aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/ABI/removed/raw1394_legacy_isochronous16
-rw-r--r--Documentation/DocBook/kernel-api.tmpl11
-rw-r--r--Documentation/block/barrier.txt16
-rw-r--r--Documentation/feature-removal-schedule.txt18
-rw-r--r--Documentation/kernel-parameters.txt43
-rw-r--r--Documentation/networking/00-INDEX3
-rw-r--r--Documentation/networking/sk98lin.txt568
-rw-r--r--Documentation/networking/spider_net.txt204
-rw-r--r--Documentation/power_supply_class.txt167
-rw-r--r--Documentation/sched-design-CFS.txt119
-rw-r--r--MAINTAINERS19
-rw-r--r--arch/i386/kernel/smpboot.c12
-rw-r--r--arch/i386/kernel/tsc.c9
-rw-r--r--arch/ia64/kernel/setup.c6
-rw-r--r--arch/mips/Kconfig198
-rw-r--r--arch/mips/Makefile84
-rw-r--r--arch/mips/au1000/common/gpio.c124
-rw-r--r--arch/mips/au1000/common/platform.c2
-rw-r--r--arch/mips/configs/atlas_defconfig4
-rw-r--r--arch/mips/configs/bigsur_defconfig4
-rw-r--r--arch/mips/configs/capcella_defconfig4
-rw-r--r--arch/mips/configs/cobalt_defconfig502
-rw-r--r--arch/mips/configs/db1000_defconfig4
-rw-r--r--arch/mips/configs/db1100_defconfig4
-rw-r--r--arch/mips/configs/db1200_defconfig4
-rw-r--r--arch/mips/configs/db1500_defconfig4
-rw-r--r--arch/mips/configs/db1550_defconfig4
-rw-r--r--arch/mips/configs/ddb5477_defconfig4
-rw-r--r--arch/mips/configs/decstation_defconfig4
-rw-r--r--arch/mips/configs/e55_defconfig4
-rw-r--r--arch/mips/configs/emma2rh_defconfig4
-rw-r--r--arch/mips/configs/ev64120_defconfig985
-rw-r--r--arch/mips/configs/excite_defconfig4
-rw-r--r--arch/mips/configs/fulong_defconfig1765
-rw-r--r--arch/mips/configs/ip22_defconfig4
-rw-r--r--arch/mips/configs/ip27_defconfig4
-rw-r--r--arch/mips/configs/ip32_defconfig4
-rw-r--r--arch/mips/configs/jazz_defconfig4
-rw-r--r--arch/mips/configs/jmr3927_defconfig4
-rw-r--r--arch/mips/configs/lasat200_defconfig1118
-rw-r--r--arch/mips/configs/malta_defconfig4
-rw-r--r--arch/mips/configs/mipssim_defconfig37
-rw-r--r--arch/mips/configs/mpc30x_defconfig4
-rw-r--r--arch/mips/configs/msp71xx_defconfig (renamed from arch/mips/configs/ocelot_3_defconfig)972
-rw-r--r--arch/mips/configs/ocelot_c_defconfig982
-rw-r--r--arch/mips/configs/ocelot_defconfig4
-rw-r--r--arch/mips/configs/pb1100_defconfig4
-rw-r--r--arch/mips/configs/pb1500_defconfig4
-rw-r--r--arch/mips/configs/pb1550_defconfig4
-rw-r--r--arch/mips/configs/pnx8550-jbs_defconfig4
-rw-r--r--arch/mips/configs/pnx8550-stb810_defconfig4
-rw-r--r--arch/mips/configs/qemu_defconfig4
-rw-r--r--arch/mips/configs/rbhma4200_defconfig4
-rw-r--r--arch/mips/configs/rbhma4500_defconfig945
-rw-r--r--arch/mips/configs/rm200_defconfig4
-rw-r--r--arch/mips/configs/sb1250-swarm_defconfig4
-rw-r--r--arch/mips/configs/sead_defconfig4
-rw-r--r--arch/mips/configs/tb0219_defconfig4
-rw-r--r--arch/mips/configs/tb0226_defconfig4
-rw-r--r--arch/mips/configs/tb0287_defconfig4
-rw-r--r--arch/mips/configs/workpad_defconfig4
-rw-r--r--arch/mips/configs/wrppmc_defconfig4
-rw-r--r--arch/mips/configs/yosemite_defconfig4
-rw-r--r--arch/mips/ddb5xxx/ddb5477/Makefile3
-rw-r--r--arch/mips/ddb5xxx/ddb5477/ddb5477-platform.c49
-rw-r--r--arch/mips/dec/prom/console.c32
-rw-r--r--arch/mips/dec/prom/init.c5
-rw-r--r--arch/mips/dec/reset.c10
-rw-r--r--arch/mips/defconfig4
-rw-r--r--arch/mips/gt64120/ev64120/Kconfig3
-rw-r--r--arch/mips/gt64120/ev64120/Makefile9
-rw-r--r--arch/mips/gt64120/ev64120/irq.c116
-rw-r--r--arch/mips/gt64120/ev64120/promcon.c48
-rw-r--r--arch/mips/gt64120/ev64120/reset.c45
-rw-r--r--arch/mips/gt64120/ev64120/serialGT.c212
-rw-r--r--arch/mips/gt64120/ev64120/setup.c99
-rw-r--r--arch/mips/gt64120/momenco_ocelot/Makefile2
-rw-r--r--arch/mips/gt64120/momenco_ocelot/ocelot-platform.c46
-rw-r--r--arch/mips/gt64120/wrppmc/setup.c4
-rw-r--r--arch/mips/jazz/Makefile2
-rw-r--r--arch/mips/jazz/jazz-platform.c60
-rw-r--r--arch/mips/kernel/8250-platform.c47
-rw-r--r--arch/mips/kernel/Makefile17
-rw-r--r--arch/mips/kernel/cpu-probe.c30
-rw-r--r--arch/mips/kernel/head.S10
-rw-r--r--arch/mips/kernel/irq-mv6434x.c111
-rw-r--r--arch/mips/kernel/mips-mt-fpaff.c176
-rw-r--r--arch/mips/kernel/mips-mt.c205
-rw-r--r--arch/mips/kernel/proc.c2
-rw-r--r--arch/mips/kernel/process.c4
-rw-r--r--arch/mips/kernel/setup.c16
-rw-r--r--arch/mips/kernel/smp.c13
-rw-r--r--arch/mips/kernel/smtc.c2
-rw-r--r--arch/mips/kernel/syscall.c5
-rw-r--r--arch/mips/kernel/traps.c77
-rw-r--r--arch/mips/kernel/unaligned.c41
-rw-r--r--arch/mips/lasat/Kconfig15
-rw-r--r--arch/mips/lasat/Makefile14
-rw-r--r--arch/mips/lasat/at93c.c148
-rw-r--r--arch/mips/lasat/at93c.h18
-rw-r--r--arch/mips/lasat/ds1603.c183
-rw-r--r--arch/mips/lasat/ds1603.h33
-rw-r--r--arch/mips/lasat/image/Makefile53
-rw-r--r--arch/mips/lasat/image/head.S31
-rw-r--r--arch/mips/lasat/image/romscript.normal23
-rw-r--r--arch/mips/lasat/interrupt.c130
-rw-r--r--arch/mips/lasat/lasat_board.c279
-rw-r--r--arch/mips/lasat/lasat_models.h63
-rw-r--r--arch/mips/lasat/picvue.c240
-rw-r--r--arch/mips/lasat/picvue.h48
-rw-r--r--arch/mips/lasat/picvue_proc.c186
-rw-r--r--arch/mips/lasat/prom.c117
-rw-r--r--arch/mips/lasat/prom.h5
-rw-r--r--arch/mips/lasat/reset.c69
-rw-r--r--arch/mips/lasat/setup.c182
-rw-r--r--arch/mips/lasat/sysctl.c441
-rw-r--r--arch/mips/lasat/sysctl.h24
-rw-r--r--arch/mips/lemote/lm2e/Makefile7
-rw-r--r--arch/mips/lemote/lm2e/bonito-irq.c74
-rw-r--r--arch/mips/lemote/lm2e/dbg_io.c146
-rw-r--r--arch/mips/lemote/lm2e/irq.c145
-rw-r--r--arch/mips/lemote/lm2e/mem.c23
-rw-r--r--arch/mips/lemote/lm2e/pci.c93
-rw-r--r--arch/mips/lemote/lm2e/prom.c104
-rw-r--r--arch/mips/lemote/lm2e/reset.c41
-rw-r--r--arch/mips/lemote/lm2e/setup.c134
-rw-r--r--arch/mips/lib-32/Makefile23
-rw-r--r--arch/mips/lib-32/dump_tlb.c242
-rw-r--r--arch/mips/lib-32/r3k_dump_tlb.c182
-rw-r--r--arch/mips/lib-32/watch.S60
-rw-r--r--arch/mips/lib-64/Makefile23
-rw-r--r--arch/mips/lib-64/dump_tlb.c216
-rw-r--r--arch/mips/lib-64/watch.S57
-rw-r--r--arch/mips/lib/Makefile19
-rw-r--r--arch/mips/lib/dump_tlb.c100
-rw-r--r--arch/mips/lib/r3k_dump_tlb.c62
-rw-r--r--arch/mips/math-emu/cp1emu.c34
-rw-r--r--arch/mips/mips-boards/malta/Makefile3
-rw-r--r--arch/mips/mips-boards/malta/malta_platform.c65
-rw-r--r--arch/mips/mipssim/Makefile (renamed from arch/mips/mips-boards/sim/Makefile)0
-rw-r--r--arch/mips/mipssim/sim_cmdline.c (renamed from arch/mips/mips-boards/sim/sim_cmdline.c)0
-rw-r--r--arch/mips/mipssim/sim_console.c (renamed from arch/mips/mips-boards/sim/sim_console.c)2
-rw-r--r--arch/mips/mipssim/sim_int.c88
-rw-r--r--arch/mips/mipssim/sim_mem.c (renamed from arch/mips/mips-boards/sim/sim_mem.c)2
-rw-r--r--arch/mips/mipssim/sim_platform.c (renamed from arch/mips/mips-boards/sim/sim_platform.c)0
-rw-r--r--arch/mips/mipssim/sim_setup.c (renamed from arch/mips/mips-boards/sim/sim_setup.c)8
-rw-r--r--arch/mips/mipssim/sim_smp.c (renamed from arch/mips/mips-boards/sim/sim_smp.c)18
-rw-r--r--arch/mips/mipssim/sim_time.c (renamed from arch/mips/mips-boards/sim/sim_time.c)30
-rw-r--r--arch/mips/mm/Makefile1
-rw-r--r--arch/mips/mm/c-r4k.c54
-rw-r--r--arch/mips/mm/c-sb1.c2
-rw-r--r--arch/mips/mm/cache.c10
-rw-r--r--arch/mips/mm/tlb-r4k.c23
-rw-r--r--arch/mips/mm/tlbex.c8
-rw-r--r--arch/mips/momentum/ocelot_3/Makefile8
-rw-r--r--arch/mips/momentum/ocelot_3/irq.c109
-rw-r--r--arch/mips/momentum/ocelot_3/platform.c208
-rw-r--r--arch/mips/momentum/ocelot_3/prom.c189
-rw-r--r--arch/mips/momentum/ocelot_3/reset.c59
-rw-r--r--arch/mips/momentum/ocelot_3/setup.c398
-rw-r--r--arch/mips/momentum/ocelot_c/Makefile8
-rw-r--r--arch/mips/momentum/ocelot_c/cpci-irq.c100
-rw-r--r--arch/mips/momentum/ocelot_c/dbg_io.c121
-rw-r--r--arch/mips/momentum/ocelot_c/irq.c107
-rw-r--r--arch/mips/momentum/ocelot_c/platform.c183
-rw-r--r--arch/mips/momentum/ocelot_c/prom.c183
-rw-r--r--arch/mips/momentum/ocelot_c/reset.c58
-rw-r--r--arch/mips/momentum/ocelot_c/setup.c362
-rw-r--r--arch/mips/momentum/ocelot_c/uart-irq.c91
-rw-r--r--arch/mips/pci/Makefile10
-rw-r--r--arch/mips/pci/fixup-atlas.c2
-rw-r--r--arch/mips/pci/fixup-au1000.c2
-rw-r--r--arch/mips/pci/fixup-capcella.c2
-rw-r--r--arch/mips/pci/fixup-cobalt.c2
-rw-r--r--arch/mips/pci/fixup-emma2rh.c2
-rw-r--r--arch/mips/pci/fixup-excite.c2
-rw-r--r--arch/mips/pci/fixup-ip32.c2
-rw-r--r--arch/mips/pci/fixup-jmr3927.c2
-rw-r--r--arch/mips/pci/fixup-lm2e.c242
-rw-r--r--arch/mips/pci/fixup-malta.c2
-rw-r--r--arch/mips/pci/fixup-mpc30x.c2
-rw-r--r--arch/mips/pci/fixup-ocelot-c.c41
-rw-r--r--arch/mips/pci/fixup-ocelot3.c41
-rw-r--r--arch/mips/pci/fixup-pmcmsp.c216
-rw-r--r--arch/mips/pci/fixup-pnx8550.c2
-rw-r--r--arch/mips/pci/fixup-rbtx4927.c2
-rw-r--r--arch/mips/pci/fixup-sni.c2
-rw-r--r--arch/mips/pci/fixup-tb0219.c2
-rw-r--r--arch/mips/pci/fixup-tb0226.c2
-rw-r--r--arch/mips/pci/fixup-tb0287.c2
-rw-r--r--arch/mips/pci/fixup-tx4938.c2
-rw-r--r--arch/mips/pci/fixup-vr4133.c2
-rw-r--r--arch/mips/pci/fixup-wrppmc.c2
-rw-r--r--arch/mips/pci/fixup-yosemite.c2
-rw-r--r--arch/mips/pci/ops-bonito64.c88
-rw-r--r--arch/mips/pci/ops-marvell.c93
-rw-r--r--arch/mips/pci/ops-nile4.c147
-rw-r--r--arch/mips/pci/ops-pmcmsp.c994
-rw-r--r--arch/mips/pci/ops-tx4938.c80
-rw-r--r--arch/mips/pci/pci-bcm1480.c3
-rw-r--r--arch/mips/pci/pci-ddb5477.c2
-rw-r--r--arch/mips/pci/pci-ev64120.c22
-rw-r--r--arch/mips/pci/pci-ip27.c2
-rw-r--r--arch/mips/pci/pci-lasat.c91
-rw-r--r--arch/mips/pci/pci-ocelot-c.c145
-rw-r--r--arch/mips/pci/pci-sb1250.c2
-rw-r--r--arch/mips/philips/pnx8550/common/platform.c2
-rw-r--r--arch/mips/philips/pnx8550/common/proc.c30
-rw-r--r--arch/mips/pmc-sierra/Kconfig46
-rw-r--r--arch/mips/pmc-sierra/msp71xx/Makefile11
-rw-r--r--arch/mips/pmc-sierra/msp71xx/msp_elb.c (renamed from arch/mips/momentum/ocelot_c/ocelot_c_fpga.h)53
-rw-r--r--arch/mips/pmc-sierra/msp71xx/msp_hwbutton.c179
-rw-r--r--arch/mips/pmc-sierra/msp71xx/msp_irq.c124
-rw-r--r--arch/mips/pmc-sierra/msp71xx/msp_irq_cic.c134
-rw-r--r--arch/mips/pmc-sierra/msp71xx/msp_irq_slp.c109
-rw-r--r--arch/mips/pmc-sierra/msp71xx/msp_pci.c (renamed from arch/mips/momentum/ocelot_3/ocelot_3_fpga.h)57
-rw-r--r--arch/mips/pmc-sierra/msp71xx/msp_prom.c566
-rw-r--r--arch/mips/pmc-sierra/msp71xx/msp_setup.c256
-rw-r--r--arch/mips/pmc-sierra/msp71xx/msp_time.c94
-rw-r--r--arch/mips/pmc-sierra/msp71xx/msp_usb.c150
-rw-r--r--arch/mips/pmc-sierra/yosemite/smp.c2
-rw-r--r--arch/mips/sgi-ip22/ip22-reset.c6
-rw-r--r--arch/mips/sgi-ip27/ip27-berr.c1
-rw-r--r--arch/mips/sgi-ip32/ip32-platform.c52
-rw-r--r--arch/mips/sgi-ip32/ip32-setup.c36
-rw-r--r--arch/mips/sibyte/cfe/setup.c6
-rw-r--r--arch/mips/sni/Makefile2
-rw-r--r--arch/mips/sni/a20r.c31
-rw-r--r--arch/mips/sni/ds1216.c81
-rw-r--r--arch/mips/sni/pcimt.c26
-rw-r--r--arch/mips/sni/pcit.c26
-rw-r--r--arch/mips/sni/rm200.c32
-rw-r--r--arch/mips/sni/sniprom.c5
-rw-r--r--arch/mips/tx4938/common/Makefile2
-rw-r--r--arch/mips/tx4938/common/rtc_rx5c348.c192
-rw-r--r--arch/mips/tx4938/toshiba_rbtx4938/Makefile2
-rw-r--r--arch/mips/tx4938/toshiba_rbtx4938/irq.c6
-rw-r--r--arch/mips/tx4938/toshiba_rbtx4938/setup.c306
-rw-r--r--arch/mips/tx4938/toshiba_rbtx4938/spi_eeprom.c261
-rw-r--r--arch/mips/tx4938/toshiba_rbtx4938/spi_txx9.c164
-rw-r--r--arch/s390/crypto/crypt_s390.h2
-rw-r--r--arch/s390/kernel/early.c45
-rw-r--r--arch/s390/kernel/entry.S7
-rw-r--r--arch/s390/kernel/entry64.S7
-rw-r--r--arch/s390/kernel/ipl.c17
-rw-r--r--arch/s390/kernel/process.c6
-rw-r--r--arch/s390/kernel/smp.c63
-rw-r--r--arch/s390/kernel/time.c4
-rw-r--r--arch/s390/kernel/vtime.c4
-rw-r--r--arch/s390/lib/Makefile4
-rw-r--r--arch/sparc/kernel/smp.c10
-rw-r--r--arch/sparc64/kernel/smp.c27
-rw-r--r--block/Kconfig4
-rw-r--r--block/cfq-iosched.c39
-rw-r--r--block/elevator.c13
-rw-r--r--block/ll_rw_blk.c13
-rw-r--r--drivers/Kconfig4
-rw-r--r--drivers/Makefile1
-rw-r--r--drivers/acorn/block/fd1772.c2
-rw-r--r--drivers/acorn/block/mfmhd.c13
-rw-r--r--drivers/ata/ahci.c159
-rw-r--r--drivers/ata/ata_generic.c4
-rw-r--r--drivers/ata/ata_piix.c35
-rw-r--r--drivers/ata/libata-acpi.c914
-rw-r--r--drivers/ata/libata-core.c105
-rw-r--r--drivers/ata/libata-eh.c11
-rw-r--r--drivers/ata/libata-scsi.c2
-rw-r--r--drivers/ata/libata.h18
-rw-r--r--drivers/ata/pata_ali.c22
-rw-r--r--drivers/ata/pata_amd.c38
-rw-r--r--drivers/ata/pata_artop.c6
-rw-r--r--drivers/ata/pata_atiixp.c3
-rw-r--r--drivers/ata/pata_cmd640.c2
-rw-r--r--drivers/ata/pata_cmd64x.c12
-rw-r--r--drivers/ata/pata_cs5520.c4
-rw-r--r--drivers/ata/pata_cs5530.c8
-rw-r--r--drivers/ata/pata_cs5535.c4
-rw-r--r--drivers/ata/pata_cypress.c2
-rw-r--r--drivers/ata/pata_efar.c2
-rw-r--r--drivers/ata/pata_hpt366.c4
-rw-r--r--drivers/ata/pata_hpt37x.c20
-rw-r--r--drivers/ata/pata_hpt3x2n.c4
-rw-r--r--drivers/ata/pata_hpt3x3.c2
-rw-r--r--drivers/ata/pata_icside.c2
-rw-r--r--drivers/ata/pata_it8213.c4
-rw-r--r--drivers/ata/pata_it821x.c6
-rw-r--r--drivers/ata/pata_ixp4xx_cf.c76
-rw-r--r--drivers/ata/pata_jmicron.c4
-rw-r--r--drivers/ata/pata_marvell.c8
-rw-r--r--drivers/ata/pata_netcell.c4
-rw-r--r--drivers/ata/pata_ns87410.c2
-rw-r--r--drivers/ata/pata_oldpiix.c2
-rw-r--r--drivers/ata/pata_opti.c2
-rw-r--r--drivers/ata/pata_optidma.c4
-rw-r--r--drivers/ata/pata_pdc202xx_old.c6
-rw-r--r--drivers/ata/pata_platform.c6
-rw-r--r--drivers/ata/pata_radisys.c2
-rw-r--r--drivers/ata/pata_rz1000.c2
-rw-r--r--drivers/ata/pata_sc1200.c6
-rw-r--r--drivers/ata/pata_serverworks.c12
-rw-r--r--drivers/ata/pata_sil680.c21
-rw-r--r--drivers/ata/pata_sis.c14
-rw-r--r--drivers/ata/pata_sl82c105.c4
-rw-r--r--drivers/ata/pata_triflex.c2
-rw-r--r--drivers/ata/pata_via.c8
-rw-r--r--drivers/ata/pdc_adma.c20
-rw-r--r--drivers/ata/sata_inic162x.c6
-rw-r--r--drivers/ata/sata_mv.c31
-rw-r--r--drivers/ata/sata_promise.c78
-rw-r--r--drivers/ata/sata_qstor.c2
-rw-r--r--drivers/ata/sata_sil.c13
-rw-r--r--drivers/ata/sata_sil24.c8
-rw-r--r--drivers/ata/sata_sis.c2
-rw-r--r--drivers/ata/sata_svw.c15
-rw-r--r--drivers/ata/sata_sx4.c168
-rw-r--r--drivers/ata/sata_uli.c2
-rw-r--r--drivers/ata/sata_via.c10
-rw-r--r--drivers/ata/sata_vsc.c2
-rw-r--r--drivers/block/Kconfig44
-rw-r--r--drivers/block/Makefile1
-rw-r--r--drivers/block/acsi.c1825
-rw-r--r--drivers/block/amiflop.c2
-rw-r--r--drivers/block/cciss.c2
-rw-r--r--drivers/block/loop.c64
-rw-r--r--drivers/block/nbd.c2
-rw-r--r--drivers/cdrom/Kconfig213
-rw-r--r--drivers/cdrom/Makefile10
-rw-r--r--drivers/cdrom/aztcd.c2492
-rw-r--r--drivers/cdrom/aztcd.h162
-rw-r--r--drivers/cdrom/cdrom.c216
-rw-r--r--drivers/cdrom/cdu31a.c3251
-rw-r--r--drivers/cdrom/cdu31a.h411
-rw-r--r--drivers/cdrom/cm206.c1594
-rw-r--r--drivers/cdrom/cm206.h171
-rw-r--r--drivers/cdrom/gscd.c1029
-rw-r--r--drivers/cdrom/gscd.h108
-rw-r--r--drivers/cdrom/isp16.c374
-rw-r--r--drivers/cdrom/isp16.h72
-rw-r--r--drivers/cdrom/mcdx.c1943
-rw-r--r--drivers/cdrom/mcdx.h185
-rw-r--r--drivers/cdrom/optcd.c2105
-rw-r--r--drivers/cdrom/optcd.h52
-rw-r--r--drivers/cdrom/sbpcd.c5966
-rw-r--r--drivers/cdrom/sbpcd.h839
-rw-r--r--drivers/cdrom/sjcd.c1815
-rw-r--r--drivers/cdrom/sjcd.h181
-rw-r--r--drivers/cdrom/sonycd535.c1689
-rw-r--r--drivers/cdrom/sonycd535.h183
-rw-r--r--drivers/char/keyboard.c4
-rw-r--r--drivers/char/mem.c9
-rw-r--r--drivers/firewire/fw-card.c7
-rw-r--r--drivers/firewire/fw-cdev.c2
-rw-r--r--drivers/firewire/fw-device.c38
-rw-r--r--drivers/firewire/fw-device.h1
-rw-r--r--drivers/firewire/fw-ohci.c6
-rw-r--r--drivers/firewire/fw-sbp2.c117
-rw-r--r--drivers/firewire/fw-topology.c66
-rw-r--r--drivers/firewire/fw-topology.h25
-rw-r--r--drivers/firewire/fw-transaction.h3
-rw-r--r--drivers/hid/Kconfig10
-rw-r--r--drivers/hid/hid-core.c93
-rw-r--r--drivers/hid/hid-debug.c15
-rw-r--r--drivers/hid/hid-input.c125
-rw-r--r--drivers/hid/usbhid/hid-core.c111
-rw-r--r--drivers/hid/usbhid/hid-lgff.c10
-rw-r--r--drivers/hid/usbhid/hid-pidff.c1
-rw-r--r--drivers/hid/usbhid/hid-quirks.c185
-rw-r--r--drivers/hid/usbhid/hid-tmff.c2
-rw-r--r--drivers/hid/usbhid/hid-zpff.c8
-rw-r--r--drivers/hid/usbhid/hiddev.c2
-rw-r--r--drivers/hid/usbhid/usbkbd.c6
-rw-r--r--drivers/ide/arm/icside.c16
-rw-r--r--drivers/ide/cris/ide-cris.c2
-rw-r--r--drivers/ide/ide-cd.c6
-rw-r--r--drivers/ide/ide-cd.h2
-rw-r--r--drivers/ide/ide-disk.c8
-rw-r--r--drivers/ide/ide-dma.c110
-rw-r--r--drivers/ide/ide-io.c4
-rw-r--r--drivers/ide/ide-iops.c8
-rw-r--r--drivers/ide/ide-probe.c10
-rw-r--r--drivers/ide/ide-proc.c34
-rw-r--r--drivers/ide/ide-timing.h56
-rw-r--r--drivers/ide/ide.c33
-rw-r--r--drivers/ide/legacy/hd.c5
-rw-r--r--drivers/ide/legacy/macide.c14
-rw-r--r--drivers/ide/mips/au1xxx-ide.c24
-rw-r--r--drivers/ide/pci/aec62xx.c119
-rw-r--r--drivers/ide/pci/alim15x3.c78
-rw-r--r--drivers/ide/pci/amd74xx.c127
-rw-r--r--drivers/ide/pci/atiixp.c5
-rw-r--r--drivers/ide/pci/cmd64x.c130
-rw-r--r--drivers/ide/pci/cs5535.c6
-rw-r--r--drivers/ide/pci/hpt366.c170
-rw-r--r--drivers/ide/pci/it8213.c8
-rw-r--r--drivers/ide/pci/it821x.c9
-rw-r--r--drivers/ide/pci/jmicron.c20
-rw-r--r--drivers/ide/pci/pdc202xx_new.c9
-rw-r--r--drivers/ide/pci/pdc202xx_old.c35
-rw-r--r--drivers/ide/pci/piix.c45
-rw-r--r--drivers/ide/pci/scc_pata.c2
-rw-r--r--drivers/ide/pci/serverworks.c103
-rw-r--r--drivers/ide/pci/sgiioc4.c20
-rw-r--r--drivers/ide/pci/siimage.c18
-rw-r--r--drivers/ide/pci/sis5513.c34
-rw-r--r--drivers/ide/pci/sl82c105.c20
-rw-r--r--drivers/ide/pci/slc90e66.c5
-rw-r--r--drivers/ide/pci/tc86c001.c4
-rw-r--r--drivers/ide/pci/via82cxxx.c175
-rw-r--r--drivers/ide/ppc/pmac.c42
-rw-r--r--drivers/ieee1394/dv1394.c8
-rw-r--r--drivers/ieee1394/eth1394.c4
-rw-r--r--drivers/ieee1394/highlevel.c45
-rw-r--r--drivers/ieee1394/highlevel.h16
-rw-r--r--drivers/ieee1394/hosts.c11
-rw-r--r--drivers/ieee1394/hosts.h10
-rw-r--r--drivers/ieee1394/ieee1394_core.c8
-rw-r--r--drivers/ieee1394/ieee1394_core.h15
-rw-r--r--drivers/ieee1394/ieee1394_transactions.c30
-rw-r--r--drivers/ieee1394/ieee1394_transactions.h2
-rw-r--r--drivers/ieee1394/nodemgr.c185
-rw-r--r--drivers/ieee1394/nodemgr.h4
-rw-r--r--drivers/ieee1394/ohci1394.c272
-rw-r--r--drivers/ieee1394/ohci1394.h14
-rw-r--r--drivers/ieee1394/pcilynx.c16
-rw-r--r--drivers/ieee1394/raw1394-private.h5
-rw-r--r--drivers/ieee1394/raw1394.c364
-rw-r--r--drivers/ieee1394/raw1394.h4
-rw-r--r--drivers/ieee1394/sbp2.c15
-rw-r--r--drivers/ieee1394/sbp2.h2
-rw-r--r--drivers/ieee1394/video1394.c10
-rw-r--r--drivers/input/evdev.c84
-rw-r--r--drivers/input/input.c136
-rw-r--r--drivers/input/joydev.c84
-rw-r--r--drivers/input/joystick/Kconfig7
-rw-r--r--drivers/input/joystick/grip_mp.c4
-rw-r--r--drivers/input/joystick/xpad.c281
-rw-r--r--drivers/input/keyboard/atkbd.c4
-rw-r--r--drivers/input/keyboard/pxa27x_keyboard.c2
-rw-r--r--drivers/input/misc/Kconfig6
-rw-r--r--drivers/input/misc/wistron_btns.c359
-rw-r--r--drivers/input/mouse/Kconfig16
-rw-r--r--drivers/input/mouse/Makefile1
-rw-r--r--drivers/input/mouse/gpio_mouse.c196
-rw-r--r--drivers/input/mouse/psmouse-base.c29
-rw-r--r--drivers/input/mouse/psmouse.h1
-rw-r--r--drivers/input/mousedev.c242
-rw-r--r--drivers/input/serio/serio_raw.c2
-rw-r--r--drivers/input/tablet/aiptek.c991
-rw-r--r--drivers/input/tablet/wacom.h8
-rw-r--r--drivers/input/tablet/wacom_sys.c6
-rw-r--r--drivers/input/tablet/wacom_wac.c47
-rw-r--r--drivers/input/tablet/wacom_wac.h1
-rw-r--r--drivers/input/touchscreen/Kconfig6
-rw-r--r--drivers/input/touchscreen/usbtouchscreen.c33
-rw-r--r--drivers/input/tsdev.c90
-rw-r--r--drivers/misc/Kconfig6
-rw-r--r--drivers/misc/Makefile1
-rw-r--r--drivers/misc/eeprom_93cx6.c241
-rw-r--r--drivers/mtd/devices/docprobe.c2
-rw-r--r--drivers/mtd/maps/Kconfig6
-rw-r--r--drivers/mtd/maps/Makefile1
-rw-r--r--drivers/mtd/maps/lasat.c103
-rw-r--r--drivers/mtd/nand/diskonchip.c2
-rw-r--r--drivers/net/3c59x.c2
-rw-r--r--drivers/net/8139cp.c11
-rw-r--r--drivers/net/8390.h11
-rw-r--r--drivers/net/Kconfig290
-rw-r--r--drivers/net/Makefile5
-rw-r--r--drivers/net/acenic.c4
-rw-r--r--drivers/net/arm/Kconfig12
-rw-r--r--drivers/net/atari_pamsnet.c62
-rw-r--r--drivers/net/atl1/atl1_main.c3
-rw-r--r--drivers/net/ax88796.c952
-rw-r--r--drivers/net/b44.c56
-rw-r--r--drivers/net/b44.h2
-rw-r--r--drivers/net/bonding/bond_main.c16
-rw-r--r--drivers/net/bonding/bonding.h2
-rw-r--r--drivers/net/cxgb3/adapter.h38
-rw-r--r--drivers/net/cxgb3/common.h28
-rw-r--r--drivers/net/cxgb3/cxgb3_main.c48
-rw-r--r--drivers/net/cxgb3/regs.h11
-rw-r--r--drivers/net/cxgb3/sge.c423
-rw-r--r--drivers/net/cxgb3/t3_hw.c128
-rw-r--r--drivers/net/cxgb3/version.h2
-rw-r--r--drivers/net/e100.c12
-rw-r--r--drivers/net/ehea/ehea.h20
-rw-r--r--drivers/net/ehea/ehea_hw.h24
-rw-r--r--drivers/net/ehea/ehea_main.c55
-rw-r--r--drivers/net/ehea/ehea_qmr.c56
-rw-r--r--drivers/net/fec_8xx/Kconfig2
-rw-r--r--drivers/net/fs_enet/Kconfig2
-rw-r--r--drivers/net/gianfar.c27
-rw-r--r--drivers/net/gianfar.h6
-rw-r--r--drivers/net/gianfar_mii.c55
-rw-r--r--drivers/net/ioc3-eth.c41
-rw-r--r--drivers/net/lasi_82596.c1460
-rw-r--r--drivers/net/lib82596.c1434
-rw-r--r--drivers/net/macmace.c2
-rw-r--r--drivers/net/mlx4/qp.c3
-rw-r--r--drivers/net/myri10ge/myri10ge.c3
-rw-r--r--drivers/net/netxen/netxen_nic.h103
-rw-r--r--drivers/net/netxen/netxen_nic_main.c97
-rw-r--r--drivers/net/netxen/netxen_nic_niu.c6
-rw-r--r--drivers/net/pasemi_mac.c2
-rw-r--r--drivers/net/pcmcia/axnet_cs.c7
-rw-r--r--drivers/net/pcmcia/fmvj18x_cs.c23
-rw-r--r--drivers/net/pcmcia/pcnet_cs.c11
-rw-r--r--drivers/net/phy/Kconfig5
-rw-r--r--drivers/net/phy/Makefile1
-rw-r--r--drivers/net/phy/icplus.c134
-rw-r--r--drivers/net/phy/marvell.c139
-rw-r--r--drivers/net/ps3_gelic_net.c1576
-rw-r--r--drivers/net/ps3_gelic_net.h239
-rwxr-xr-xdrivers/net/qla3xxx.c33
-rw-r--r--drivers/net/r8169.c944
-rw-r--r--drivers/net/rrunner.c2
-rw-r--r--drivers/net/s2io.c116
-rw-r--r--drivers/net/s2io.h6
-rw-r--r--drivers/net/sis900.c2
-rw-r--r--drivers/net/sk98lin/Makefile87
-rw-r--r--drivers/net/sk98lin/h/lm80.h179
-rw-r--r--drivers/net/sk98lin/h/skaddr.h285
-rw-r--r--drivers/net/sk98lin/h/skcsum.h213
-rw-r--r--drivers/net/sk98lin/h/skdebug.h74
-rw-r--r--drivers/net/sk98lin/h/skdrv1st.h188
-rw-r--r--drivers/net/sk98lin/h/skdrv2nd.h447
-rw-r--r--drivers/net/sk98lin/h/skerror.h55
-rw-r--r--drivers/net/sk98lin/h/skgedrv.h51
-rw-r--r--drivers/net/sk98lin/h/skgehw.h2126
-rw-r--r--drivers/net/sk98lin/h/skgehwt.h48
-rw-r--r--drivers/net/sk98lin/h/skgei2c.h210
-rw-r--r--drivers/net/sk98lin/h/skgeinit.h797
-rw-r--r--drivers/net/sk98lin/h/skgepnm2.h334
-rw-r--r--drivers/net/sk98lin/h/skgepnmi.h962
-rw-r--r--drivers/net/sk98lin/h/skgesirq.h110
-rw-r--r--drivers/net/sk98lin/h/ski2c.h174
-rw-r--r--drivers/net/sk98lin/h/skqueue.h94
-rw-r--r--drivers/net/sk98lin/h/skrlmt.h438
-rw-r--r--drivers/net/sk98lin/h/sktimer.h63
-rw-r--r--drivers/net/sk98lin/h/sktypes.h69
-rw-r--r--drivers/net/sk98lin/h/skversion.h38
-rw-r--r--drivers/net/sk98lin/h/skvpd.h248
-rw-r--r--drivers/net/sk98lin/h/xmac_ii.h1579
-rw-r--r--drivers/net/sk98lin/skaddr.c1788
-rw-r--r--drivers/net/sk98lin/skdim.c742
-rw-r--r--drivers/net/sk98lin/skethtool.c628
-rw-r--r--drivers/net/sk98lin/skge.c5211
-rw-r--r--drivers/net/sk98lin/skgehwt.c171
-rw-r--r--drivers/net/sk98lin/skgeinit.c2005
-rw-r--r--drivers/net/sk98lin/skgemib.c1075
-rw-r--r--drivers/net/sk98lin/skgepnmi.c8210
-rw-r--r--drivers/net/sk98lin/skgesirq.c2229
-rw-r--r--drivers/net/sk98lin/ski2c.c1296
-rw-r--r--drivers/net/sk98lin/sklm80.c141
-rw-r--r--drivers/net/sk98lin/skqueue.c179
-rw-r--r--drivers/net/sk98lin/skrlmt.c3257
-rw-r--r--drivers/net/sk98lin/sktimer.c250
-rw-r--r--drivers/net/sk98lin/skvpd.c1091
-rw-r--r--drivers/net/sk98lin/skxmac2.c4160
-rw-r--r--drivers/net/sky2.c665
-rw-r--r--drivers/net/sky2.h167
-rw-r--r--drivers/net/sni_82596.c185
-rw-r--r--drivers/net/spider_net.c243
-rw-r--r--drivers/net/spider_net.h21
-rw-r--r--drivers/net/sunhme.c2
-rw-r--r--drivers/net/tc35815.c50
-rw-r--r--drivers/net/tokenring/3c359.c2
-rw-r--r--drivers/net/tulip/Kconfig27
-rw-r--r--drivers/net/tulip/de2104x.c1
-rw-r--r--drivers/net/tulip/de4x5.c98
-rw-r--r--drivers/net/tulip/de4x5.h9
-rw-r--r--drivers/net/ucc_geth.c2
-rw-r--r--drivers/net/usb/usbnet.c78
-rw-r--r--drivers/net/usb/usbnet.h10
-rw-r--r--drivers/net/wireless/Kconfig12
-rw-r--r--drivers/net/wireless/Makefile3
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_phy.c2
-rw-r--r--drivers/net/wireless/hostap/hostap_ap.c34
-rw-r--r--drivers/net/wireless/hostap/hostap_config.h2
-rw-r--r--drivers/net/wireless/hostap/hostap_cs.c4
-rw-r--r--drivers/net/wireless/hostap/hostap_ioctl.c2
-rw-r--r--drivers/net/wireless/hostap/hostap_main.c1
-rw-r--r--drivers/net/wireless/hostap/hostap_pci.c5
-rw-r--r--drivers/net/wireless/hostap/hostap_plx.c5
-rw-r--r--drivers/net/wireless/rtl8187.h145
-rw-r--r--drivers/net/wireless/rtl8187_dev.c731
-rw-r--r--drivers/net/wireless/rtl8187_rtl8225.c745
-rw-r--r--drivers/net/wireless/rtl8187_rtl8225.h44
-rw-r--r--drivers/net/wireless/rtl818x.h226
-rw-r--r--drivers/net/wireless/zd1211rw/Makefile2
-rw-r--r--drivers/net/wireless/zd1211rw/zd_chip.c5
-rw-r--r--drivers/net/wireless/zd1211rw/zd_chip.h3
-rw-r--r--drivers/net/wireless/zd1211rw/zd_rf.c21
-rw-r--r--drivers/net/wireless/zd1211rw/zd_rf.h28
-rw-r--r--drivers/net/wireless/zd1211rw/zd_rf_al2230.c1
-rw-r--r--drivers/net/wireless/zd1211rw/zd_rf_al7230b.c1
-rw-r--r--drivers/net/wireless/zd1211rw/zd_rf_uw2453.c534
-rw-r--r--drivers/net/wireless/zd1211rw/zd_usb.c1
-rw-r--r--drivers/power/Kconfig51
-rw-r--r--drivers/power/Makefile22
-rw-r--r--drivers/power/apm_power.c243
-rw-r--r--drivers/power/ds2760_battery.c470
-rw-r--r--drivers/power/olpc_battery.c352
-rw-r--r--drivers/power/pda_power.c261
-rw-r--r--drivers/power/pmu_battery.c215
-rw-r--r--drivers/power/power_supply.h42
-rw-r--r--drivers/power/power_supply_core.c168
-rw-r--r--drivers/power/power_supply_leds.c176
-rw-r--r--drivers/power/power_supply_sysfs.c299
-rw-r--r--drivers/s390/block/dasd_proc.c4
-rw-r--r--drivers/s390/char/sclp.h12
-rw-r--r--drivers/s390/char/sclp_chp.c4
-rw-r--r--drivers/s390/char/sclp_info.c117
-rw-r--r--drivers/s390/char/vmcp.c13
-rw-r--r--drivers/s390/char/vmlogrdr.c4
-rw-r--r--drivers/s390/char/zcore.c2
-rw-r--r--drivers/s390/cio/device_id.c22
-rw-r--r--drivers/s390/crypto/ap_bus.c98
-rw-r--r--drivers/s390/crypto/ap_bus.h11
-rw-r--r--drivers/s390/crypto/zcrypt_cex2a.c27
-rw-r--r--drivers/s390/crypto/zcrypt_pcica.c27
-rw-r--r--drivers/s390/crypto/zcrypt_pcicc.c27
-rw-r--r--drivers/s390/crypto/zcrypt_pcixcc.c40
-rw-r--r--drivers/serial/serial_cs.c4
-rw-r--r--drivers/tc/zs.c6
-rw-r--r--drivers/w1/slaves/Kconfig13
-rw-r--r--drivers/w1/slaves/Makefile1
-rw-r--r--drivers/w1/slaves/w1_ds2760.c213
-rw-r--r--drivers/w1/slaves/w1_ds2760.h50
-rw-r--r--drivers/w1/w1_family.h1
-rw-r--r--fs/adfs/file.c2
-rw-r--r--fs/affs/file.c2
-rw-r--r--fs/afs/file.c2
-rw-r--r--fs/bad_inode.c7
-rw-r--r--fs/bfs/file.c2
-rw-r--r--fs/bio.c2
-rw-r--r--fs/block_dev.c1
-rw-r--r--fs/cifs/cifsfs.c8
-rw-r--r--fs/coda/file.c11
-rw-r--r--fs/dlm/Makefile1
-rw-r--r--fs/dlm/config.c25
-rw-r--r--fs/dlm/config.h1
-rw-r--r--fs/dlm/debug_fs.c186
-rw-r--r--fs/dlm/dlm_internal.h17
-rw-r--r--fs/dlm/lock.c470
-rw-r--r--fs/dlm/lock.h13
-rw-r--r--fs/dlm/lockspace.c86
-rw-r--r--fs/dlm/lowcomms.c23
-rw-r--r--fs/dlm/main.c11
-rw-r--r--fs/dlm/member.c11
-rw-r--r--fs/dlm/netlink.c153
-rw-r--r--fs/dlm/rcom.c13
-rw-r--r--fs/dlm/recoverd.c4
-rw-r--r--fs/dlm/user.c129
-rw-r--r--fs/ecryptfs/file.c15
-rw-r--r--fs/ext2/file.c2
-rw-r--r--fs/ext3/file.c1
-rw-r--r--fs/ext4/file.c1
-rw-r--r--fs/fat/file.c2
-rw-r--r--fs/fuse/file.c4
-rw-r--r--fs/gfs2/Makefile2
-rw-r--r--fs/gfs2/bmap.c23
-rw-r--r--fs/gfs2/daemon.c11
-rw-r--r--fs/gfs2/dir.c69
-rw-r--r--fs/gfs2/dir.h9
-rw-r--r--fs/gfs2/eattr.c14
-rw-r--r--fs/gfs2/glock.c123
-rw-r--r--fs/gfs2/glock.h1
-rw-r--r--fs/gfs2/glops.c2
-rw-r--r--fs/gfs2/incore.h81
-rw-r--r--fs/gfs2/inode.c288
-rw-r--r--fs/gfs2/inode.h30
-rw-r--r--fs/gfs2/locking/dlm/lock.c11
-rw-r--r--fs/gfs2/locking/dlm/lock_dlm.h2
-rw-r--r--fs/gfs2/locking/dlm/mount.c2
-rw-r--r--fs/gfs2/locking/dlm/plock.c8
-rw-r--r--fs/gfs2/locking/dlm/thread.c11
-rw-r--r--fs/gfs2/log.c129
-rw-r--r--fs/gfs2/lops.c49
-rw-r--r--fs/gfs2/lops.h23
-rw-r--r--fs/gfs2/meta_io.c8
-rw-r--r--fs/gfs2/meta_io.h2
-rw-r--r--fs/gfs2/mount.c25
-rw-r--r--fs/gfs2/ondisk.c251
-rw-r--r--fs/gfs2/ops_address.c69
-rw-r--r--fs/gfs2/ops_address.h2
-rw-r--r--fs/gfs2/ops_dentry.c24
-rw-r--r--fs/gfs2/ops_export.c65
-rw-r--r--fs/gfs2/ops_export.h22
-rw-r--r--fs/gfs2/ops_file.c5
-rw-r--r--fs/gfs2/ops_fstype.c33
-rw-r--r--fs/gfs2/ops_fstype.h1
-rw-r--r--fs/gfs2/ops_inode.c30
-rw-r--r--fs/gfs2/ops_super.c8
-rw-r--r--fs/gfs2/ops_vm.c2
-rw-r--r--fs/gfs2/quota.c57
-rw-r--r--fs/gfs2/recovery.c22
-rw-r--r--fs/gfs2/rgrp.c377
-rw-r--r--fs/gfs2/rgrp.h1
-rw-r--r--fs/gfs2/super.c79
-rw-r--r--fs/gfs2/super.h2
-rw-r--r--fs/gfs2/util.c6
-rw-r--r--fs/hfs/inode.c2
-rw-r--r--fs/hfsplus/inode.c2
-rw-r--r--fs/hostfs/hostfs_kern.c2
-rw-r--r--fs/hpfs/file.c2
-rw-r--r--fs/jffs2/file.c2
-rw-r--r--fs/jfs/endian24.h2
-rw-r--r--fs/jfs/file.c1
-rw-r--r--fs/jfs/jfs_debug.c28
-rw-r--r--fs/jfs/jfs_debug.h2
-rw-r--r--fs/jfs/jfs_dinode.h42
-rw-r--r--fs/jfs/jfs_dmap.c419
-rw-r--r--fs/jfs/jfs_dmap.h118
-rw-r--r--fs/jfs/jfs_dtree.c105
-rw-r--r--fs/jfs/jfs_dtree.h2
-rw-r--r--fs/jfs/jfs_extent.c102
-rw-r--r--fs/jfs/jfs_filsys.h13
-rw-r--r--fs/jfs/jfs_imap.c296
-rw-r--r--fs/jfs/jfs_imap.h98
-rw-r--r--fs/jfs/jfs_incore.h4
-rw-r--r--fs/jfs/jfs_logmgr.c90
-rw-r--r--fs/jfs/jfs_logmgr.h26
-rw-r--r--fs/jfs/jfs_metapage.c3
-rw-r--r--fs/jfs/jfs_mount.c6
-rw-r--r--fs/jfs/jfs_txnmgr.c302
-rw-r--r--fs/jfs/jfs_txnmgr.h2
-rw-r--r--fs/jfs/jfs_types.h20
-rw-r--r--fs/jfs/jfs_umount.c2
-rw-r--r--fs/jfs/jfs_xtree.c428
-rw-r--r--fs/jfs/jfs_xtree.h48
-rw-r--r--fs/jfs/namei.c26
-rw-r--r--fs/jfs/resize.c48
-rw-r--r--fs/jfs/xattr.c9
-rw-r--r--fs/minix/file.c2
-rw-r--r--fs/nfs/file.c15
-rw-r--r--fs/nfsd/vfs.c47
-rw-r--r--fs/ntfs/file.c2
-rw-r--r--fs/ocfs2/file.c18
-rw-r--r--fs/partitions/ibm.c167
-rw-r--r--fs/pipe.c70
-rw-r--r--fs/proc/array.c59
-rw-r--r--fs/proc/base.c71
-rw-r--r--fs/qnx4/file.c2
-rw-r--r--fs/ramfs/file-mmu.c2
-rw-r--r--fs/ramfs/file-nommu.c2
-rw-r--r--fs/read_write.c20
-rw-r--r--fs/reiserfs/file.c1
-rw-r--r--fs/smbfs/file.c9
-rw-r--r--fs/splice.c413
-rw-r--r--fs/sysv/file.c2
-rw-r--r--fs/udf/file.c2
-rw-r--r--fs/ufs/file.c2
-rw-r--r--fs/xfs/linux-2.6/xfs_file.c26
-rw-r--r--fs/xfs/linux-2.6/xfs_linux.h1
-rw-r--r--fs/xfs/linux-2.6/xfs_lrw.c44
-rw-r--r--fs/xfs/linux-2.6/xfs_lrw.h3
-rw-r--r--fs/xfs/linux-2.6/xfs_vnode.h6
-rw-r--r--fs/xfs/xfs_vnodeops.c3
-rw-r--r--include/asm-generic/bitops/sched.h21
-rw-r--r--include/asm-mips/addrspace.h29
-rw-r--r--include/asm-mips/bootinfo.h36
-rw-r--r--include/asm-mips/cacheops.h4
-rw-r--r--include/asm-mips/cpu-features.h4
-rw-r--r--include/asm-mips/cpu.h10
-rw-r--r--include/asm-mips/div64.h9
-rw-r--r--include/asm-mips/gpio.h6
-rw-r--r--include/asm-mips/io.h8
-rw-r--r--include/asm-mips/lasat/ds1603.h18
-rw-r--r--include/asm-mips/lasat/eeprom.h17
-rw-r--r--include/asm-mips/lasat/head.h22
-rw-r--r--include/asm-mips/lasat/lasat.h253
-rw-r--r--include/asm-mips/lasat/lasatint.h12
-rw-r--r--include/asm-mips/lasat/picvue.h15
-rw-r--r--include/asm-mips/lasat/serial.h13
-rw-r--r--include/asm-mips/mach-au1x00/au1xxx_gpio.h20
-rw-r--r--include/asm-mips/mach-au1x00/au1xxx_ide.h28
-rw-r--r--include/asm-mips/mach-au1x00/gpio.h69
-rw-r--r--include/asm-mips/mach-au1x00/ioremap.h11
-rw-r--r--include/asm-mips/mach-cobalt/cobalt.h5
-rw-r--r--include/asm-mips/mach-ev64120/mach-gt64120.h62
-rw-r--r--include/asm-mips/mach-generic/gpio.h15
-rw-r--r--include/asm-mips/mach-generic/ioremap.h11
-rw-r--r--include/asm-mips/mach-generic/spaces.h64
-rw-r--r--include/asm-mips/mach-ip22/spaces.h33
-rw-r--r--include/asm-mips/mach-ip27/spaces.h9
-rw-r--r--include/asm-mips/mach-ip32/spaces.h36
-rw-r--r--include/asm-mips/mach-jmr3927/ioremap.h38
-rw-r--r--include/asm-mips/mach-lasat/mach-gt64120.h27
-rw-r--r--include/asm-mips/mach-lemote/dma-coherence.h42
-rw-r--r--include/asm-mips/mach-lemote/mc146818rtc.h36
-rw-r--r--include/asm-mips/mach-mips/kernel-entry-init.h52
-rw-r--r--include/asm-mips/mach-mipssim/cpu-feature-overrides.h (renamed from include/asm-mips/mach-sim/cpu-feature-overrides.h)0
-rw-r--r--include/asm-mips/mach-ocelot3/cpu-feature-overrides.h48
-rw-r--r--include/asm-mips/mach-tx49xx/ioremap.h42
-rw-r--r--include/asm-mips/mips-boards/bonito64.h7
-rw-r--r--include/asm-mips/mipsregs.h39
-rw-r--r--include/asm-mips/module.h2
-rw-r--r--include/asm-mips/nile4.h310
-rw-r--r--include/asm-mips/page.h21
-rw-r--r--include/asm-mips/pci.h2
-rw-r--r--include/asm-mips/pmc-sierra/msp71xx/msp_cic_int.h151
-rw-r--r--include/asm-mips/pmc-sierra/msp71xx/msp_int.h43
-rw-r--r--include/asm-mips/pmc-sierra/msp71xx/msp_pci.h205
-rw-r--r--include/asm-mips/pmc-sierra/msp71xx/msp_prom.h176
-rw-r--r--include/asm-mips/pmc-sierra/msp71xx/msp_regops.h236
-rw-r--r--include/asm-mips/pmc-sierra/msp71xx/msp_regs.h667
-rw-r--r--include/asm-mips/pmc-sierra/msp71xx/msp_slp_int.h141
-rw-r--r--include/asm-mips/processor.h92
-rw-r--r--include/asm-mips/serial.h155
-rw-r--r--include/asm-mips/smp.h7
-rw-r--r--include/asm-mips/sni.h3
-rw-r--r--include/asm-mips/system.h14
-rw-r--r--include/asm-mips/tx4938/rbtx4938.h6
-rw-r--r--include/asm-mips/tx4938/spi.h56
-rw-r--r--include/asm-mips/war.h25
-rw-r--r--include/asm-mips/watch.h35
-rw-r--r--include/asm-s390/atomic.h4
-rw-r--r--include/asm-s390/cmb.h1
-rw-r--r--include/asm-s390/processor.h4
-rw-r--r--include/asm-s390/sclp.h47
-rw-r--r--include/asm-s390/sfp-machine.h6
-rw-r--r--include/asm-s390/sfp-util.h11
-rw-r--r--include/linux/Kbuild1
-rw-r--r--include/linux/ata.h1
-rw-r--r--include/linux/blkdev.h5
-rw-r--r--include/linux/dlm.h14
-rw-r--r--include/linux/dlm_device.h22
-rw-r--r--include/linux/dlm_netlink.h56
-rw-r--r--include/linux/eeprom_93cx6.h72
-rw-r--r--include/linux/firewire-cdev.h297
-rw-r--r--include/linux/fs.h7
-rw-r--r--include/linux/gfs2_ondisk.h142
-rw-r--r--include/linux/gpio_mouse.h61
-rw-r--r--include/linux/hardirq.h13
-rw-r--r--include/linux/hid.h56
-rw-r--r--include/linux/ide.h18
-rw-r--r--include/linux/input.h20
-rw-r--r--include/linux/ioprio.h6
-rw-r--r--include/linux/libata.h30
-rw-r--r--include/linux/mv643xx.h4
-rw-r--r--include/linux/pata_platform.h5
-rw-r--r--include/linux/pda_power.h31
-rw-r--r--include/linux/pipe_fs_i.h117
-rw-r--r--include/linux/power_supply.h180
-rw-r--r--include/linux/sched.h251
-rw-r--r--include/linux/splice.h73
-rw-r--r--include/linux/sunrpc/svc.h2
-rw-r--r--include/linux/topology.h12
-rw-r--r--include/linux/usb.h16
-rw-r--r--include/linux/wait.h16
-rw-r--r--include/net/ax88796.h27
-rw-r--r--include/pcmcia/ciscode.h2
-rw-r--r--init/Kconfig2
-rw-r--r--init/main.c5
-rw-r--r--kernel/delayacct.c10
-rw-r--r--kernel/exit.c5
-rw-r--r--kernel/fork.c4
-rw-r--r--kernel/posix-cpu-timers.c34
-rw-r--r--kernel/relay.c205
-rw-r--r--kernel/sched.c3021
-rw-r--r--kernel/sched_debug.c275
-rw-r--r--kernel/sched_fair.c1131
-rw-r--r--kernel/sched_idletask.c71
-rw-r--r--kernel/sched_rt.c255
-rw-r--r--kernel/sched_stats.h235
-rw-r--r--kernel/softirq.c1
-rw-r--r--kernel/sysctl.c80
-rw-r--r--lib/Kconfig.debug9
-rw-r--r--mm/filemap.c20
-rw-r--r--mm/filemap_xip.c22
-rw-r--r--mm/shmem.c42
-rw-r--r--net/ieee80211/softmac/ieee80211softmac_module.c32
-rw-r--r--net/ipv6/addrconf.c3
-rw-r--r--net/sunrpc/auth_gss/svcauth_gss.c2
-rw-r--r--net/sunrpc/svc.c2
-rw-r--r--sound/ppc/beep.c10
877 files changed, 37165 insertions, 95145 deletions
diff --git a/Documentation/ABI/removed/raw1394_legacy_isochronous b/Documentation/ABI/removed/raw1394_legacy_isochronous
new file mode 100644
index 000000000000..1b629622d883
--- /dev/null
+++ b/Documentation/ABI/removed/raw1394_legacy_isochronous
@@ -0,0 +1,16 @@
1What: legacy isochronous ABI of raw1394 (1st generation iso ABI)
2Date: June 2007 (scheduled), removed in kernel v2.6.23
3Contact: linux1394-devel@lists.sourceforge.net
4Description:
5 The two request types RAW1394_REQ_ISO_SEND, RAW1394_REQ_ISO_LISTEN have
6 been deprecated for quite some time. They are very inefficient as they
7 come with high interrupt load and several layers of callbacks for each
8 packet. Because of these deficiencies, the video1394 and dv1394 drivers
9 and the 3rd-generation isochronous ABI in raw1394 (rawiso) were created.
10
11Users:
12 libraw1394 users via the long deprecated API raw1394_iso_write,
13 raw1394_start_iso_write, raw1394_start_iso_rcv, raw1394_stop_iso_rcv
14
15 libdc1394, which optionally uses these old libraw1394 calls
16 alternatively to the more efficient video1394 ABI
diff --git a/Documentation/DocBook/kernel-api.tmpl b/Documentation/DocBook/kernel-api.tmpl
index 38f88b6ae405..8c5698a8c2e1 100644
--- a/Documentation/DocBook/kernel-api.tmpl
+++ b/Documentation/DocBook/kernel-api.tmpl
@@ -643,4 +643,15 @@ X!Idrivers/video/console/fonts.c
643!Edrivers/spi/spi.c 643!Edrivers/spi/spi.c
644 </chapter> 644 </chapter>
645 645
646 <chapter id="splice">
647 <title>splice API</title>
648 <para>)
649 splice is a method for moving blocks of data around inside the
650 kernel, without continually transferring it between the kernel
651 and user space.
652 </para>
653!Iinclude/linux/splice.h
654!Ffs/splice.c
655 </chapter>
656
646</book> 657</book>
diff --git a/Documentation/block/barrier.txt b/Documentation/block/barrier.txt
index a272c3db8094..7d279f2f5bb2 100644
--- a/Documentation/block/barrier.txt
+++ b/Documentation/block/barrier.txt
@@ -82,23 +82,12 @@ including draining and flushing.
82typedef void (prepare_flush_fn)(request_queue_t *q, struct request *rq); 82typedef void (prepare_flush_fn)(request_queue_t *q, struct request *rq);
83 83
84int blk_queue_ordered(request_queue_t *q, unsigned ordered, 84int blk_queue_ordered(request_queue_t *q, unsigned ordered,
85 prepare_flush_fn *prepare_flush_fn, 85 prepare_flush_fn *prepare_flush_fn);
86 unsigned gfp_mask);
87
88int blk_queue_ordered_locked(request_queue_t *q, unsigned ordered,
89 prepare_flush_fn *prepare_flush_fn,
90 unsigned gfp_mask);
91
92The only difference between the two functions is whether or not the
93caller is holding q->queue_lock on entry. The latter expects the
94caller is holding the lock.
95 86
96@q : the queue in question 87@q : the queue in question
97@ordered : the ordered mode the driver/device supports 88@ordered : the ordered mode the driver/device supports
98@prepare_flush_fn : this function should prepare @rq such that it 89@prepare_flush_fn : this function should prepare @rq such that it
99 flushes cache to physical medium when executed 90 flushes cache to physical medium when executed
100@gfp_mask : gfp_mask used when allocating data structures
101 for ordered processing
102 91
103For example, SCSI disk driver's prepare_flush_fn looks like the 92For example, SCSI disk driver's prepare_flush_fn looks like the
104following. 93following.
@@ -106,9 +95,10 @@ following.
106static void sd_prepare_flush(request_queue_t *q, struct request *rq) 95static void sd_prepare_flush(request_queue_t *q, struct request *rq)
107{ 96{
108 memset(rq->cmd, 0, sizeof(rq->cmd)); 97 memset(rq->cmd, 0, sizeof(rq->cmd));
109 rq->flags |= REQ_BLOCK_PC; 98 rq->cmd_type = REQ_TYPE_BLOCK_PC;
110 rq->timeout = SD_TIMEOUT; 99 rq->timeout = SD_TIMEOUT;
111 rq->cmd[0] = SYNCHRONIZE_CACHE; 100 rq->cmd[0] = SYNCHRONIZE_CACHE;
101 rq->cmd_len = 10;
112} 102}
113 103
114The following seven ordered modes are supported. The following table 104The following seven ordered modes are supported. The following table
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index 7d3f205b0ba5..3a159dac04f5 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -49,16 +49,6 @@ Who: Adrian Bunk <bunk@stusta.de>
49 49
50--------------------------- 50---------------------------
51 51
52What: raw1394: requests of type RAW1394_REQ_ISO_SEND, RAW1394_REQ_ISO_LISTEN
53When: June 2007
54Why: Deprecated in favour of the more efficient and robust rawiso interface.
55 Affected are applications which use the deprecated part of libraw1394
56 (raw1394_iso_write, raw1394_start_iso_write, raw1394_start_iso_rcv,
57 raw1394_stop_iso_rcv) or bypass libraw1394.
58Who: Dan Dennedy <dan@dennedy.org>, Stefan Richter <stefanr@s5r6.in-berlin.de>
59
60---------------------------
61
62What: old NCR53C9x driver 52What: old NCR53C9x driver
63When: October 2007 53When: October 2007
64Why: Replaced by the much better esp_scsi driver. Actual low-level 54Why: Replaced by the much better esp_scsi driver. Actual low-level
@@ -258,14 +248,6 @@ Who: Len Brown <len.brown@intel.com>
258 248
259--------------------------- 249---------------------------
260 250
261What: sk98lin network driver
262When: July 2007
263Why: In kernel tree version of driver is unmaintained. Sk98lin driver
264 replaced by the skge driver.
265Who: Stephen Hemminger <shemminger@osdl.org>
266
267---------------------------
268
269What: Compaq touchscreen device emulation 251What: Compaq touchscreen device emulation
270When: Oct 2007 252When: Oct 2007
271Files: drivers/input/tsdev.c 253Files: drivers/input/tsdev.c
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index af50f9bbe68e..4d880b3d1f35 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -1014,49 +1014,6 @@ and is between 256 and 4096 characters. It is defined in the file
1014 1014
1015 mga= [HW,DRM] 1015 mga= [HW,DRM]
1016 1016
1017 migration_cost=
1018 [KNL,SMP] debug: override scheduler migration costs
1019 Format: <level-1-usecs>,<level-2-usecs>,...
1020 This debugging option can be used to override the
1021 default scheduler migration cost matrix. The numbers
1022 are indexed by 'CPU domain distance'.
1023 E.g. migration_cost=1000,2000,3000 on an SMT NUMA
1024 box will set up an intra-core migration cost of
1025 1 msec, an inter-core migration cost of 2 msecs,
1026 and an inter-node migration cost of 3 msecs.
1027
1028 WARNING: using the wrong values here can break
1029 scheduler performance, so it's only for scheduler
1030 development purposes, not production environments.
1031
1032 migration_debug=
1033 [KNL,SMP] migration cost auto-detect verbosity
1034 Format=<0|1|2>
1035 If a system's migration matrix reported at bootup
1036 seems erroneous then this option can be used to
1037 increase verbosity of the detection process.
1038 We default to 0 (no extra messages), 1 will print
1039 some more information, and 2 will be really
1040 verbose (probably only useful if you also have a
1041 serial console attached to the system).
1042
1043 migration_factor=
1044 [KNL,SMP] multiply/divide migration costs by a factor
1045 Format=<percent>
1046 This debug option can be used to proportionally
1047 increase or decrease the auto-detected migration
1048 costs for all entries of the migration matrix.
1049 E.g. migration_factor=150 will increase migration
1050 costs by 50%. (and thus the scheduler will be less
1051 eager migrating cache-hot tasks)
1052 migration_factor=80 will decrease migration costs
1053 by 20%. (thus the scheduler will be more eager to
1054 migrate tasks)
1055
1056 WARNING: using the wrong values here can break
1057 scheduler performance, so it's only for scheduler
1058 development purposes, not production environments.
1059
1060 mousedev.tap_time= 1017 mousedev.tap_time=
1061 [MOUSE] Maximum time between finger touching and 1018 [MOUSE] Maximum time between finger touching and
1062 leaving touchpad surface for touch to be considered 1019 leaving touchpad surface for touch to be considered
diff --git a/Documentation/networking/00-INDEX b/Documentation/networking/00-INDEX
index 153d84d281e6..d63f480afb74 100644
--- a/Documentation/networking/00-INDEX
+++ b/Documentation/networking/00-INDEX
@@ -96,9 +96,6 @@ routing.txt
96 - the new routing mechanism 96 - the new routing mechanism
97shaper.txt 97shaper.txt
98 - info on the module that can shape/limit transmitted traffic. 98 - info on the module that can shape/limit transmitted traffic.
99sk98lin.txt
100 - Marvell Yukon Chipset / SysKonnect SK-98xx compliant Gigabit
101 Ethernet Adapter family driver info
102skfp.txt 99skfp.txt
103 - SysKonnect FDDI (SK-5xxx, Compaq Netelligent) driver info. 100 - SysKonnect FDDI (SK-5xxx, Compaq Netelligent) driver info.
104smc9.txt 101smc9.txt
diff --git a/Documentation/networking/sk98lin.txt b/Documentation/networking/sk98lin.txt
deleted file mode 100644
index 8590a954df1d..000000000000
--- a/Documentation/networking/sk98lin.txt
+++ /dev/null
@@ -1,568 +0,0 @@
1(C)Copyright 1999-2004 Marvell(R).
2All rights reserved
3===========================================================================
4
5sk98lin.txt created 13-Feb-2004
6
7Readme File for sk98lin v6.23
8Marvell Yukon/SysKonnect SK-98xx Gigabit Ethernet Adapter family driver for LINUX
9
10This file contains
11 1 Overview
12 2 Required Files
13 3 Installation
14 3.1 Driver Installation
15 3.2 Inclusion of adapter at system start
16 4 Driver Parameters
17 4.1 Per-Port Parameters
18 4.2 Adapter Parameters
19 5 Large Frame Support
20 6 VLAN and Link Aggregation Support (IEEE 802.1, 802.1q, 802.3ad)
21 7 Troubleshooting
22
23===========================================================================
24
25
261 Overview
27===========
28
29The sk98lin driver supports the Marvell Yukon and SysKonnect
30SK-98xx/SK-95xx compliant Gigabit Ethernet Adapter on Linux. It has
31been tested with Linux on Intel/x86 machines.
32***
33
34
352 Required Files
36=================
37
38The linux kernel source.
39No additional files required.
40***
41
42
433 Installation
44===============
45
46It is recommended to download the latest version of the driver from the
47SysKonnect web site www.syskonnect.com. If you have downloaded the latest
48driver, the Linux kernel has to be patched before the driver can be
49installed. For details on how to patch a Linux kernel, refer to the
50patch.txt file.
51
523.1 Driver Installation
53------------------------
54
55The following steps describe the actions that are required to install
56the driver and to start it manually. These steps should be carried
57out for the initial driver setup. Once confirmed to be ok, they can
58be included in the system start.
59
60NOTE 1: To perform the following tasks you need 'root' access.
61
62NOTE 2: In case of problems, please read the section "Troubleshooting"
63 below.
64
65The driver can either be integrated into the kernel or it can be compiled
66as a module. Select the appropriate option during the kernel
67configuration.
68
69Compile/use the driver as a module
70----------------------------------
71To compile the driver, go to the directory /usr/src/linux and
72execute the command "make menuconfig" or "make xconfig" and proceed as
73follows:
74
75To integrate the driver permanently into the kernel, proceed as follows:
76
771. Select the menu "Network device support" and then "Ethernet(1000Mbit)"
782. Mark "Marvell Yukon Chipset / SysKonnect SK-98xx family support"
79 with (*)
803. Build a new kernel when the configuration of the above options is
81 finished.
824. Install the new kernel.
835. Reboot your system.
84
85To use the driver as a module, proceed as follows:
86
871. Enable 'loadable module support' in the kernel.
882. For automatic driver start, enable the 'Kernel module loader'.
893. Select the menu "Network device support" and then "Ethernet(1000Mbit)"
904. Mark "Marvell Yukon Chipset / SysKonnect SK-98xx family support"
91 with (M)
925. Execute the command "make modules".
936. Execute the command "make modules_install".
94 The appropriate modules will be installed.
957. Reboot your system.
96
97
98Load the module manually
99------------------------
100To load the module manually, proceed as follows:
101
1021. Enter "modprobe sk98lin".
1032. If a Marvell Yukon or SysKonnect SK-98xx adapter is installed in
104 your computer and you have a /proc file system, execute the command:
105 "ls /proc/net/sk98lin/"
106 This should produce an output containing a line with the following
107 format:
108 eth0 eth1 ...
109 which indicates that your adapter has been found and initialized.
110
111 NOTE 1: If you have more than one Marvell Yukon or SysKonnect SK-98xx
112 adapter installed, the adapters will be listed as 'eth0',
113 'eth1', 'eth2', etc.
114 For each adapter, repeat steps 3 and 4 below.
115
116 NOTE 2: If you have other Ethernet adapters installed, your Marvell
117 Yukon or SysKonnect SK-98xx adapter will be mapped to the
118 next available number, e.g. 'eth1'. The mapping is executed
119 automatically.
120 The module installation message (displayed either in a system
121 log file or on the console) prints a line for each adapter
122 found containing the corresponding 'ethX'.
123
1243. Select an IP address and assign it to the respective adapter by
125 entering:
126 ifconfig eth0 <ip-address>
127 With this command, the adapter is connected to the Ethernet.
128
129 SK-98xx Gigabit Ethernet Server Adapters: The yellow LED on the adapter
130 is now active, the link status LED of the primary port is active and
131 the link status LED of the secondary port (on dual port adapters) is
132 blinking (if the ports are connected to a switch or hub).
133 SK-98xx V2.0 Gigabit Ethernet Adapters: The link status LED is active.
134 In addition, you will receive a status message on the console stating
135 "ethX: network connection up using port Y" and showing the selected
136 connection parameters (x stands for the ethernet device number
137 (0,1,2, etc), y stands for the port name (A or B)).
138
139 NOTE: If you are in doubt about IP addresses, ask your network
140 administrator for assistance.
141
1424. Your adapter should now be fully operational.
143 Use 'ping <otherstation>' to verify the connection to other computers
144 on your network.
1455. To check the adapter configuration view /proc/net/sk98lin/[devicename].
146 For example by executing:
147 "cat /proc/net/sk98lin/eth0"
148
149Unload the module
150-----------------
151To stop and unload the driver modules, proceed as follows:
152
1531. Execute the command "ifconfig eth0 down".
1542. Execute the command "rmmod sk98lin".
155
1563.2 Inclusion of adapter at system start
157-----------------------------------------
158
159Since a large number of different Linux distributions are
160available, we are unable to describe a general installation procedure
161for the driver module.
162Because the driver is now integrated in the kernel, installation should
163be easy, using the standard mechanism of your distribution.
164Refer to the distribution's manual for installation of ethernet adapters.
165
166***
167
1684 Driver Parameters
169====================
170
171Parameters can be set at the command line after the module has been
172loaded with the command 'modprobe'.
173In some distributions, the configuration tools are able to pass parameters
174to the driver module.
175
176If you use the kernel module loader, you can set driver parameters
177in the file /etc/modprobe.conf (or /etc/modules.conf in 2.4 or earlier).
178To set the driver parameters in this file, proceed as follows:
179
1801. Insert a line of the form :
181 options sk98lin ...
182 For "...", the same syntax is required as described for the command
183 line parameters of modprobe below.
1842. To activate the new parameters, either reboot your computer
185 or
186 unload and reload the driver.
187 The syntax of the driver parameters is:
188
189 modprobe sk98lin parameter=value1[,value2[,value3...]]
190
191 where value1 refers to the first adapter, value2 to the second etc.
192
193NOTE: All parameters are case sensitive. Write them exactly as shown
194 below.
195
196Example:
197Suppose you have two adapters. You want to set auto-negotiation
198on the first adapter to ON and on the second adapter to OFF.
199You also want to set DuplexCapabilities on the first adapter
200to FULL, and on the second adapter to HALF.
201Then, you must enter:
202
203 modprobe sk98lin AutoNeg_A=On,Off DupCap_A=Full,Half
204
205NOTE: The number of adapters that can be configured this way is
206 limited in the driver (file skge.c, constant SK_MAX_CARD_PARAM).
207 The current limit is 16. If you happen to install
208 more adapters, adjust this and recompile.
209
210
2114.1 Per-Port Parameters
212------------------------
213
214These settings are available for each port on the adapter.
215In the following description, '?' stands for the port for
216which you set the parameter (A or B).
217
218Speed
219-----
220Parameter: Speed_?
221Values: 10, 100, 1000, Auto
222Default: Auto
223
224This parameter is used to set the speed capabilities. It is only valid
225for the SK-98xx V2.0 copper adapters.
226Usually, the speed is negotiated between the two ports during link
227establishment. If this fails, a port can be forced to a specific setting
228with this parameter.
229
230Auto-Negotiation
231----------------
232Parameter: AutoNeg_?
233Values: On, Off, Sense
234Default: On
235
236The "Sense"-mode automatically detects whether the link partner supports
237auto-negotiation or not.
238
239Duplex Capabilities
240-------------------
241Parameter: DupCap_?
242Values: Half, Full, Both
243Default: Both
244
245This parameters is only relevant if auto-negotiation for this port is
246not set to "Sense". If auto-negotiation is set to "On", all three values
247are possible. If it is set to "Off", only "Full" and "Half" are allowed.
248This parameter is useful if your link partner does not support all
249possible combinations.
250
251Flow Control
252------------
253Parameter: FlowCtrl_?
254Values: Sym, SymOrRem, LocSend, None
255Default: SymOrRem
256
257This parameter can be used to set the flow control capabilities the
258port reports during auto-negotiation. It can be set for each port
259individually.
260Possible modes:
261 -- Sym = Symmetric: both link partners are allowed to send
262 PAUSE frames
263 -- SymOrRem = SymmetricOrRemote: both or only remote partner
264 are allowed to send PAUSE frames
265 -- LocSend = LocalSend: only local link partner is allowed
266 to send PAUSE frames
267 -- None = no link partner is allowed to send PAUSE frames
268
269NOTE: This parameter is ignored if auto-negotiation is set to "Off".
270
271Role in Master-Slave-Negotiation (1000Base-T only)
272--------------------------------------------------
273Parameter: Role_?
274Values: Auto, Master, Slave
275Default: Auto
276
277This parameter is only valid for the SK-9821 and SK-9822 adapters.
278For two 1000Base-T ports to communicate, one must take the role of the
279master (providing timing information), while the other must be the
280slave. Usually, this is negotiated between the two ports during link
281establishment. If this fails, a port can be forced to a specific setting
282with this parameter.
283
284
2854.2 Adapter Parameters
286-----------------------
287
288Connection Type (SK-98xx V2.0 copper adapters only)
289---------------
290Parameter: ConType
291Values: Auto, 100FD, 100HD, 10FD, 10HD
292Default: Auto
293
294The parameter 'ConType' is a combination of all five per-port parameters
295within one single parameter. This simplifies the configuration of both ports
296of an adapter card! The different values of this variable reflect the most
297meaningful combinations of port parameters.
298
299The following table shows the values of 'ConType' and the corresponding
300combinations of the per-port parameters:
301
302 ConType | DupCap AutoNeg FlowCtrl Role Speed
303 ----------+------------------------------------------------------
304 Auto | Both On SymOrRem Auto Auto
305 100FD | Full Off None Auto (ignored) 100
306 100HD | Half Off None Auto (ignored) 100
307 10FD | Full Off None Auto (ignored) 10
308 10HD | Half Off None Auto (ignored) 10
309
310Stating any other port parameter together with this 'ConType' variable
311will result in a merged configuration of those settings. This due to
312the fact, that the per-port parameters (e.g. Speed_? ) have a higher
313priority than the combined variable 'ConType'.
314
315NOTE: This parameter is always used on both ports of the adapter card.
316
317Interrupt Moderation
318--------------------
319Parameter: Moderation
320Values: None, Static, Dynamic
321Default: None
322
323Interrupt moderation is employed to limit the maximum number of interrupts
324the driver has to serve. That is, one or more interrupts (which indicate any
325transmit or receive packet to be processed) are queued until the driver
326processes them. When queued interrupts are to be served, is determined by the
327'IntsPerSec' parameter, which is explained later below.
328
329Possible modes:
330
331 -- None - No interrupt moderation is applied on the adapter card.
332 Therefore, each transmit or receive interrupt is served immediately
333 as soon as it appears on the interrupt line of the adapter card.
334
335 -- Static - Interrupt moderation is applied on the adapter card.
336 All transmit and receive interrupts are queued until a complete
337 moderation interval ends. If such a moderation interval ends, all
338 queued interrupts are processed in one big bunch without any delay.
339 The term 'static' reflects the fact, that interrupt moderation is
340 always enabled, regardless how much network load is currently
341 passing via a particular interface. In addition, the duration of
342 the moderation interval has a fixed length that never changes while
343 the driver is operational.
344
345 -- Dynamic - Interrupt moderation might be applied on the adapter card,
346 depending on the load of the system. If the driver detects that the
347 system load is too high, the driver tries to shield the system against
348 too much network load by enabling interrupt moderation. If - at a later
349 time - the CPU utilization decreases again (or if the network load is
350 negligible) the interrupt moderation will automatically be disabled.
351
352Interrupt moderation should be used when the driver has to handle one or more
353interfaces with a high network load, which - as a consequence - leads also to a
354high CPU utilization. When moderation is applied in such high network load
355situations, CPU load might be reduced by 20-30%.
356
357NOTE: The drawback of using interrupt moderation is an increase of the round-
358trip-time (RTT), due to the queueing and serving of interrupts at dedicated
359moderation times.
360
361Interrupts per second
362---------------------
363Parameter: IntsPerSec
364Values: 30...40000 (interrupts per second)
365Default: 2000
366
367This parameter is only used if either static or dynamic interrupt moderation
368is used on a network adapter card. Using this parameter if no moderation is
369applied will lead to no action performed.
370
371This parameter determines the length of any interrupt moderation interval.
372Assuming that static interrupt moderation is to be used, an 'IntsPerSec'
373parameter value of 2000 will lead to an interrupt moderation interval of
374500 microseconds.
375
376NOTE: The duration of the moderation interval is to be chosen with care.
377At first glance, selecting a very long duration (e.g. only 100 interrupts per
378second) seems to be meaningful, but the increase of packet-processing delay
379is tremendous. On the other hand, selecting a very short moderation time might
380compensate the use of any moderation being applied.
381
382
383Preferred Port
384--------------
385Parameter: PrefPort
386Values: A, B
387Default: A
388
389This is used to force the preferred port to A or B (on dual-port network
390adapters). The preferred port is the one that is used if both are detected
391as fully functional.
392
393RLMT Mode (Redundant Link Management Technology)
394------------------------------------------------
395Parameter: RlmtMode
396Values: CheckLinkState,CheckLocalPort, CheckSeg, DualNet
397Default: CheckLinkState
398
399RLMT monitors the status of the port. If the link of the active port
400fails, RLMT switches immediately to the standby link. The virtual link is
401maintained as long as at least one 'physical' link is up.
402
403Possible modes:
404
405 -- CheckLinkState - Check link state only: RLMT uses the link state
406 reported by the adapter hardware for each individual port to
407 determine whether a port can be used for all network traffic or
408 not.
409
410 -- CheckLocalPort - In this mode, RLMT monitors the network path
411 between the two ports of an adapter by regularly exchanging packets
412 between them. This mode requires a network configuration in which
413 the two ports are able to "see" each other (i.e. there must not be
414 any router between the ports).
415
416 -- CheckSeg - Check local port and segmentation: This mode supports the
417 same functions as the CheckLocalPort mode and additionally checks
418 network segmentation between the ports. Therefore, this mode is only
419 to be used if Gigabit Ethernet switches are installed on the network
420 that have been configured to use the Spanning Tree protocol.
421
422 -- DualNet - In this mode, ports A and B are used as separate devices.
423 If you have a dual port adapter, port A will be configured as eth0
424 and port B as eth1. Both ports can be used independently with
425 distinct IP addresses. The preferred port setting is not used.
426 RLMT is turned off.
427
428NOTE: RLMT modes CLP and CLPSS are designed to operate in configurations
429 where a network path between the ports on one adapter exists.
430 Moreover, they are not designed to work where adapters are connected
431 back-to-back.
432***
433
434
4355 Large Frame Support
436======================
437
438The driver supports large frames (also called jumbo frames). Using large
439frames can result in an improved throughput if transferring large amounts
440of data.
441To enable large frames, set the MTU (maximum transfer unit) of the
442interface to the desired value (up to 9000), execute the following
443command:
444 ifconfig eth0 mtu 9000
445This will only work if you have two adapters connected back-to-back
446or if you use a switch that supports large frames. When using a switch,
447it should be configured to allow large frames and auto-negotiation should
448be set to OFF. The setting must be configured on all adapters that can be
449reached by the large frames. If one adapter is not set to receive large
450frames, it will simply drop them.
451
452You can switch back to the standard ethernet frame size by executing the
453following command:
454 ifconfig eth0 mtu 1500
455
456To permanently configure this setting, add a script with the 'ifconfig'
457line to the system startup sequence (named something like "S99sk98lin"
458in /etc/rc.d/rc2.d).
459***
460
461
4626 VLAN and Link Aggregation Support (IEEE 802.1, 802.1q, 802.3ad)
463==================================================================
464
465The Marvell Yukon/SysKonnect Linux drivers are able to support VLAN and
466Link Aggregation according to IEEE standards 802.1, 802.1q, and 802.3ad.
467These features are only available after installation of open source
468modules available on the Internet:
469For VLAN go to: http://www.candelatech.com/~greear/vlan.html
470For Link Aggregation go to: http://www.st.rim.or.jp/~yumo
471
472NOTE: SysKonnect GmbH does not offer any support for these open source
473 modules and does not take the responsibility for any kind of
474 failures or problems arising in connection with these modules.
475
476NOTE: Configuring Link Aggregation on a SysKonnect dual link adapter may
477 cause problems when unloading the driver.
478
479
4807 Troubleshooting
481==================
482
483If any problems occur during the installation process, check the
484following list:
485
486
487Problem: The SK-98xx adapter cannot be found by the driver.
488Solution: In /proc/pci search for the following entry:
489 'Ethernet controller: SysKonnect SK-98xx ...'
490 If this entry exists, the SK-98xx or SK-98xx V2.0 adapter has
491 been found by the system and should be operational.
492 If this entry does not exist or if the file '/proc/pci' is not
493 found, there may be a hardware problem or the PCI support may
494 not be enabled in your kernel.
495 The adapter can be checked using the diagnostics program which
496 is available on the SysKonnect web site:
497 www.syskonnect.com
498
499 Some COMPAQ machines have problems dealing with PCI under Linux.
500 This problem is described in the 'PCI howto' document
501 (included in some distributions or available from the
502 web, e.g. at 'www.linux.org').
503
504
505Problem: Programs such as 'ifconfig' or 'route' cannot be found or the
506 error message 'Operation not permitted' is displayed.
507Reason: You are not logged in as user 'root'.
508Solution: Logout and login as 'root' or change to 'root' via 'su'.
509
510
511Problem: Upon use of the command 'ping <address>' the message
512 "ping: sendto: Network is unreachable" is displayed.
513Reason: Your route is not set correctly.
514Solution: If you are using RedHat, you probably forgot to set up the
515 route in the 'network configuration'.
516 Check the existing routes with the 'route' command and check
517 if an entry for 'eth0' exists, and if so, if it is set correctly.
518
519
520Problem: The driver can be started, the adapter is connected to the
521 network, but you cannot receive or transmit any packets;
522 e.g. 'ping' does not work.
523Reason: There is an incorrect route in your routing table.
524Solution: Check the routing table with the command 'route' and read the
525 manual help pages dealing with routes (enter 'man route').
526
527NOTE: Although the 2.2.x kernel versions generate the routing entry
528 automatically, problems of this kind may occur here as well. We've
529 come across a situation in which the driver started correctly at
530 system start, but after the driver has been removed and reloaded,
531 the route of the adapter's network pointed to the 'dummy0'device
532 and had to be corrected manually.
533
534
535Problem: Your computer should act as a router between multiple
536 IP subnetworks (using multiple adapters), but computers in
537 other subnetworks cannot be reached.
538Reason: Either the router's kernel is not configured for IP forwarding
539 or the routing table and gateway configuration of at least one
540 computer is not working.
541
542Problem: Upon driver start, the following error message is displayed:
543 "eth0: -- ERROR --
544 Class: internal Software error
545 Nr: 0xcc
546 Msg: SkGeInitPort() cannot init running ports"
547Reason: You are using a driver compiled for single processor machines
548 on a multiprocessor machine with SMP (Symmetric MultiProcessor)
549 kernel.
550Solution: Configure your kernel appropriately and recompile the kernel or
551 the modules.
552
553
554
555If your problem is not listed here, please contact SysKonnect's technical
556support for help (linux@syskonnect.de).
557When contacting our technical support, please ensure that the following
558information is available:
559- System Manufacturer and HW Informations (CPU, Memory... )
560- PCI-Boards in your system
561- Distribution
562- Kernel version
563- Driver version
564***
565
566
567
568***End of Readme File***
diff --git a/Documentation/networking/spider_net.txt b/Documentation/networking/spider_net.txt
new file mode 100644
index 000000000000..4b4adb8eb14f
--- /dev/null
+++ b/Documentation/networking/spider_net.txt
@@ -0,0 +1,204 @@
1
2 The Spidernet Device Driver
3 ===========================
4
5Written by Linas Vepstas <linas@austin.ibm.com>
6
7Version of 7 June 2007
8
9Abstract
10========
11This document sketches the structure of portions of the spidernet
12device driver in the Linux kernel tree. The spidernet is a gigabit
13ethernet device built into the Toshiba southbridge commonly used
14in the SONY Playstation 3 and the IBM QS20 Cell blade.
15
16The Structure of the RX Ring.
17=============================
18The receive (RX) ring is a circular linked list of RX descriptors,
19together with three pointers into the ring that are used to manage its
20contents.
21
22The elements of the ring are called "descriptors" or "descrs"; they
23describe the received data. This includes a pointer to a buffer
24containing the received data, the buffer size, and various status bits.
25
26There are three primary states that a descriptor can be in: "empty",
27"full" and "not-in-use". An "empty" or "ready" descriptor is ready
28to receive data from the hardware. A "full" descriptor has data in it,
29and is waiting to be emptied and processed by the OS. A "not-in-use"
30descriptor is neither empty or full; it is simply not ready. It may
31not even have a data buffer in it, or is otherwise unusable.
32
33During normal operation, on device startup, the OS (specifically, the
34spidernet device driver) allocates a set of RX descriptors and RX
35buffers. These are all marked "empty", ready to receive data. This
36ring is handed off to the hardware, which sequentially fills in the
37buffers, and marks them "full". The OS follows up, taking the full
38buffers, processing them, and re-marking them empty.
39
40This filling and emptying is managed by three pointers, the "head"
41and "tail" pointers, managed by the OS, and a hardware current
42descriptor pointer (GDACTDPA). The GDACTDPA points at the descr
43currently being filled. When this descr is filled, the hardware
44marks it full, and advances the GDACTDPA by one. Thus, when there is
45flowing RX traffic, every descr behind it should be marked "full",
46and everything in front of it should be "empty". If the hardware
47discovers that the current descr is not empty, it will signal an
48interrupt, and halt processing.
49
50The tail pointer tails or trails the hardware pointer. When the
51hardware is ahead, the tail pointer will be pointing at a "full"
52descr. The OS will process this descr, and then mark it "not-in-use",
53and advance the tail pointer. Thus, when there is flowing RX traffic,
54all of the descrs in front of the tail pointer should be "full", and
55all of those behind it should be "not-in-use". When RX traffic is not
56flowing, then the tail pointer can catch up to the hardware pointer.
57The OS will then note that the current tail is "empty", and halt
58processing.
59
60The head pointer (somewhat mis-named) follows after the tail pointer.
61When traffic is flowing, then the head pointer will be pointing at
62a "not-in-use" descr. The OS will perform various housekeeping duties
63on this descr. This includes allocating a new data buffer and
64dma-mapping it so as to make it visible to the hardware. The OS will
65then mark the descr as "empty", ready to receive data. Thus, when there
66is flowing RX traffic, everything in front of the head pointer should
67be "not-in-use", and everything behind it should be "empty". If no
68RX traffic is flowing, then the head pointer can catch up to the tail
69pointer, at which point the OS will notice that the head descr is
70"empty", and it will halt processing.
71
72Thus, in an idle system, the GDACTDPA, tail and head pointers will
73all be pointing at the same descr, which should be "empty". All of the
74other descrs in the ring should be "empty" as well.
75
76The show_rx_chain() routine will print out the the locations of the
77GDACTDPA, tail and head pointers. It will also summarize the contents
78of the ring, starting at the tail pointer, and listing the status
79of the descrs that follow.
80
81A typical example of the output, for a nearly idle system, might be
82
83net eth1: Total number of descrs=256
84net eth1: Chain tail located at descr=20
85net eth1: Chain head is at 20
86net eth1: HW curr desc (GDACTDPA) is at 21
87net eth1: Have 1 descrs with stat=x40800101
88net eth1: HW next desc (GDACNEXTDA) is at 22
89net eth1: Last 255 descrs with stat=xa0800000
90
91In the above, the hardware has filled in one descr, number 20. Both
92head and tail are pointing at 20, because it has not yet been emptied.
93Meanwhile, hw is pointing at 21, which is free.
94
95The "Have nnn decrs" refers to the descr starting at the tail: in this
96case, nnn=1 descr, starting at descr 20. The "Last nnn descrs" refers
97to all of the rest of the descrs, from the last status change. The "nnn"
98is a count of how many descrs have exactly the same status.
99
100The status x4... corresponds to "full" and status xa... corresponds
101to "empty". The actual value printed is RXCOMST_A.
102
103In the device driver source code, a different set of names are
104used for these same concepts, so that
105
106"empty" == SPIDER_NET_DESCR_CARDOWNED == 0xa
107"full" == SPIDER_NET_DESCR_FRAME_END == 0x4
108"not in use" == SPIDER_NET_DESCR_NOT_IN_USE == 0xf
109
110
111The RX RAM full bug/feature
112===========================
113
114As long as the OS can empty out the RX buffers at a rate faster than
115the hardware can fill them, there is no problem. If, for some reason,
116the OS fails to empty the RX ring fast enough, the hardware GDACTDPA
117pointer will catch up to the head, notice the not-empty condition,
118ad stop. However, RX packets may still continue arriving on the wire.
119The spidernet chip can save some limited number of these in local RAM.
120When this local ram fills up, the spider chip will issue an interrupt
121indicating this (GHIINT0STS will show ERRINT, and the GRMFLLINT bit
122will be set in GHIINT1STS). When the RX ram full condition occurs,
123a certain bug/feature is triggered that has to be specially handled.
124This section describes the special handling for this condition.
125
126When the OS finally has a chance to run, it will empty out the RX ring.
127In particular, it will clear the descriptor on which the hardware had
128stopped. However, once the hardware has decided that a certain
129descriptor is invalid, it will not restart at that descriptor; instead
130it will restart at the next descr. This potentially will lead to a
131deadlock condition, as the tail pointer will be pointing at this descr,
132which, from the OS point of view, is empty; the OS will be waiting for
133this descr to be filled. However, the hardware has skipped this descr,
134and is filling the next descrs. Since the OS doesn't see this, there
135is a potential deadlock, with the OS waiting for one descr to fill,
136while the hardware is waiting for a different set of descrs to become
137empty.
138
139A call to show_rx_chain() at this point indicates the nature of the
140problem. A typical print when the network is hung shows the following:
141
142net eth1: Spider RX RAM full, incoming packets might be discarded!
143net eth1: Total number of descrs=256
144net eth1: Chain tail located at descr=255
145net eth1: Chain head is at 255
146net eth1: HW curr desc (GDACTDPA) is at 0
147net eth1: Have 1 descrs with stat=xa0800000
148net eth1: HW next desc (GDACNEXTDA) is at 1
149net eth1: Have 127 descrs with stat=x40800101
150net eth1: Have 1 descrs with stat=x40800001
151net eth1: Have 126 descrs with stat=x40800101
152net eth1: Last 1 descrs with stat=xa0800000
153
154Both the tail and head pointers are pointing at descr 255, which is
155marked xa... which is "empty". Thus, from the OS point of view, there
156is nothing to be done. In particular, there is the implicit assumption
157that everything in front of the "empty" descr must surely also be empty,
158as explained in the last section. The OS is waiting for descr 255 to
159become non-empty, which, in this case, will never happen.
160
161The HW pointer is at descr 0. This descr is marked 0x4.. or "full".
162Since its already full, the hardware can do nothing more, and thus has
163halted processing. Notice that descrs 0 through 254 are all marked
164"full", while descr 254 and 255 are empty. (The "Last 1 descrs" is
165descr 254, since tail was at 255.) Thus, the system is deadlocked,
166and there can be no forward progress; the OS thinks there's nothing
167to do, and the hardware has nowhere to put incoming data.
168
169This bug/feature is worked around with the spider_net_resync_head_ptr()
170routine. When the driver receives RX interrupts, but an examination
171of the RX chain seems to show it is empty, then it is probable that
172the hardware has skipped a descr or two (sometimes dozens under heavy
173network conditions). The spider_net_resync_head_ptr() subroutine will
174search the ring for the next full descr, and the driver will resume
175operations there. Since this will leave "holes" in the ring, there
176is also a spider_net_resync_tail_ptr() that will skip over such holes.
177
178As of this writing, the spider_net_resync() strategy seems to work very
179well, even under heavy network loads.
180
181
182The TX ring
183===========
184The TX ring uses a low-watermark interrupt scheme to make sure that
185the TX queue is appropriately serviced for large packet sizes.
186
187For packet sizes greater than about 1KBytes, the kernel can fill
188the TX ring quicker than the device can drain it. Once the ring
189is full, the netdev is stopped. When there is room in the ring,
190the netdev needs to be reawakened, so that more TX packets are placed
191in the ring. The hardware can empty the ring about four times per jiffy,
192so its not appropriate to wait for the poll routine to refill, since
193the poll routine runs only once per jiffy. The low-watermark mechanism
194marks a descr about 1/4th of the way from the bottom of the queue, so
195that an interrupt is generated when the descr is processed. This
196interrupt wakes up the netdev, which can then refill the queue.
197For large packets, this mechanism generates a relatively small number
198of interrupts, about 1K/sec. For smaller packets, this will drop to zero
199interrupts, as the hardware can empty the queue faster than the kernel
200can fill it.
201
202
203 ======= END OF DOCUMENT ========
204
diff --git a/Documentation/power_supply_class.txt b/Documentation/power_supply_class.txt
new file mode 100644
index 000000000000..9758cf433c06
--- /dev/null
+++ b/Documentation/power_supply_class.txt
@@ -0,0 +1,167 @@
1Linux power supply class
2========================
3
4Synopsis
5~~~~~~~~
6Power supply class used to represent battery, UPS, AC or DC power supply
7properties to user-space.
8
9It defines core set of attributes, which should be applicable to (almost)
10every power supply out there. Attributes are available via sysfs and uevent
11interfaces.
12
13Each attribute has well defined meaning, up to unit of measure used. While
14the attributes provided are believed to be universally applicable to any
15power supply, specific monitoring hardware may not be able to provide them
16all, so any of them may be skipped.
17
18Power supply class is extensible, and allows to define drivers own attributes.
19The core attribute set is subject to the standard Linux evolution (i.e.
20if it will be found that some attribute is applicable to many power supply
21types or their drivers, it can be added to the core set).
22
23It also integrates with LED framework, for the purpose of providing
24typically expected feedback of battery charging/fully charged status and
25AC/USB power supply online status. (Note that specific details of the
26indication (including whether to use it at all) are fully controllable by
27user and/or specific machine defaults, per design principles of LED
28framework).
29
30
31Attributes/properties
32~~~~~~~~~~~~~~~~~~~~~
33Power supply class has predefined set of attributes, this eliminates code
34duplication across drivers. Power supply class insist on reusing its
35predefined attributes *and* their units.
36
37So, userspace gets predictable set of attributes and their units for any
38kind of power supply, and can process/present them to a user in consistent
39manner. Results for different power supplies and machines are also directly
40comparable.
41
42See drivers/power/ds2760_battery.c and drivers/power/pda_power.c for the
43example how to declare and handle attributes.
44
45
46Units
47~~~~~
48Quoting include/linux/power_supply.h:
49
50 All voltages, currents, charges, energies, time and temperatures in µV,
51 µA, µAh, µWh, seconds and tenths of degree Celsius unless otherwise
52 stated. It's driver's job to convert its raw values to units in which
53 this class operates.
54
55
56Attributes/properties detailed
57~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
58
59~ ~ ~ ~ ~ ~ ~ Charge/Energy/Capacity - how to not confuse ~ ~ ~ ~ ~ ~ ~
60~ ~
61~ Because both "charge" (µAh) and "energy" (µWh) represents "capacity" ~
62~ of battery, this class distinguish these terms. Don't mix them! ~
63~ ~
64~ CHARGE_* attributes represents capacity in µAh only. ~
65~ ENERGY_* attributes represents capacity in µWh only. ~
66~ CAPACITY attribute represents capacity in *percents*, from 0 to 100. ~
67~ ~
68~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
69
70Postfixes:
71_AVG - *hardware* averaged value, use it if your hardware is really able to
72report averaged values.
73_NOW - momentary/instantaneous values.
74
75STATUS - this attribute represents operating status (charging, full,
76discharging (i.e. powering a load), etc.). This corresponds to
77BATTERY_STATUS_* values, as defined in battery.h.
78
79HEALTH - represents health of the battery, values corresponds to
80POWER_SUPPLY_HEALTH_*, defined in battery.h.
81
82VOLTAGE_MAX_DESIGN, VOLTAGE_MIN_DESIGN - design values for maximal and
83minimal power supply voltages. Maximal/minimal means values of voltages
84when battery considered "full"/"empty" at normal conditions. Yes, there is
85no direct relation between voltage and battery capacity, but some dumb
86batteries use voltage for very approximated calculation of capacity.
87Battery driver also can use this attribute just to inform userspace
88about maximal and minimal voltage thresholds of a given battery.
89
90CHARGE_FULL_DESIGN, CHARGE_EMPTY_DESIGN - design charge values, when
91battery considered full/empty.
92
93ENERGY_FULL_DESIGN, ENERGY_EMPTY_DESIGN - same as above but for energy.
94
95CHARGE_FULL, CHARGE_EMPTY - These attributes means "last remembered value
96of charge when battery became full/empty". It also could mean "value of
97charge when battery considered full/empty at given conditions (temperature,
98age)". I.e. these attributes represents real thresholds, not design values.
99
100ENERGY_FULL, ENERGY_EMPTY - same as above but for energy.
101
102CAPACITY - capacity in percents.
103CAPACITY_LEVEL - capacity level. This corresponds to
104POWER_SUPPLY_CAPACITY_LEVEL_*.
105
106TEMP - temperature of the power supply.
107TEMP_AMBIENT - ambient temperature.
108
109TIME_TO_EMPTY - seconds left for battery to be considered empty (i.e.
110while battery powers a load)
111TIME_TO_FULL - seconds left for battery to be considered full (i.e.
112while battery is charging)
113
114
115Battery <-> external power supply interaction
116~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
117Often power supplies are acting as supplies and supplicants at the same
118time. Batteries are good example. So, batteries usually care if they're
119externally powered or not.
120
121For that case, power supply class implements notification mechanism for
122batteries.
123
124External power supply (AC) lists supplicants (batteries) names in
125"supplied_to" struct member, and each power_supply_changed() call
126issued by external power supply will notify supplicants via
127external_power_changed callback.
128
129
130QA
131~~
132Q: Where is POWER_SUPPLY_PROP_XYZ attribute?
133A: If you cannot find attribute suitable for your driver needs, feel free
134 to add it and send patch along with your driver.
135
136 The attributes available currently are the ones currently provided by the
137 drivers written.
138
139 Good candidates to add in future: model/part#, cycle_time, manufacturer,
140 etc.
141
142
143Q: I have some very specific attribute (e.g. battery color), should I add
144 this attribute to standard ones?
145A: Most likely, no. Such attribute can be placed in the driver itself, if
146 it is useful. Of course, if the attribute in question applicable to
147 large set of batteries, provided by many drivers, and/or comes from
148 some general battery specification/standard, it may be a candidate to
149 be added to the core attribute set.
150
151
152Q: Suppose, my battery monitoring chip/firmware does not provides capacity
153 in percents, but provides charge_{now,full,empty}. Should I calculate
154 percentage capacity manually, inside the driver, and register CAPACITY
155 attribute? The same question about time_to_empty/time_to_full.
156A: Most likely, no. This class is designed to export properties which are
157 directly measurable by the specific hardware available.
158
159 Inferring not available properties using some heuristics or mathematical
160 model is not subject of work for a battery driver. Such functionality
161 should be factored out, and in fact, apm_power, the driver to serve
162 legacy APM API on top of power supply class, uses a simple heuristic of
163 approximating remaining battery capacity based on its charge, current,
164 voltage and so on. But full-fledged battery model is likely not subject
165 for kernel at all, as it would require floating point calculation to deal
166 with things like differential equations and Kalman filters. This is
167 better be handled by batteryd/libbattery, yet to be written.
diff --git a/Documentation/sched-design-CFS.txt b/Documentation/sched-design-CFS.txt
new file mode 100644
index 000000000000..16feebb7bdc0
--- /dev/null
+++ b/Documentation/sched-design-CFS.txt
@@ -0,0 +1,119 @@
1
2This is the CFS scheduler.
3
480% of CFS's design can be summed up in a single sentence: CFS basically
5models an "ideal, precise multi-tasking CPU" on real hardware.
6
7"Ideal multi-tasking CPU" is a (non-existent :-)) CPU that has 100%
8physical power and which can run each task at precise equal speed, in
9parallel, each at 1/nr_running speed. For example: if there are 2 tasks
10running then it runs each at 50% physical power - totally in parallel.
11
12On real hardware, we can run only a single task at once, so while that
13one task runs, the other tasks that are waiting for the CPU are at a
14disadvantage - the current task gets an unfair amount of CPU time. In
15CFS this fairness imbalance is expressed and tracked via the per-task
16p->wait_runtime (nanosec-unit) value. "wait_runtime" is the amount of
17time the task should now run on the CPU for it to become completely fair
18and balanced.
19
20( small detail: on 'ideal' hardware, the p->wait_runtime value would
21 always be zero - no task would ever get 'out of balance' from the
22 'ideal' share of CPU time. )
23
24CFS's task picking logic is based on this p->wait_runtime value and it
25is thus very simple: it always tries to run the task with the largest
26p->wait_runtime value. In other words, CFS tries to run the task with
27the 'gravest need' for more CPU time. So CFS always tries to split up
28CPU time between runnable tasks as close to 'ideal multitasking
29hardware' as possible.
30
31Most of the rest of CFS's design just falls out of this really simple
32concept, with a few add-on embellishments like nice levels,
33multiprocessing and various algorithm variants to recognize sleepers.
34
35In practice it works like this: the system runs a task a bit, and when
36the task schedules (or a scheduler tick happens) the task's CPU usage is
37'accounted for': the (small) time it just spent using the physical CPU
38is deducted from p->wait_runtime. [minus the 'fair share' it would have
39gotten anyway]. Once p->wait_runtime gets low enough so that another
40task becomes the 'leftmost task' of the time-ordered rbtree it maintains
41(plus a small amount of 'granularity' distance relative to the leftmost
42task so that we do not over-schedule tasks and trash the cache) then the
43new leftmost task is picked and the current task is preempted.
44
45The rq->fair_clock value tracks the 'CPU time a runnable task would have
46fairly gotten, had it been runnable during that time'. So by using
47rq->fair_clock values we can accurately timestamp and measure the
48'expected CPU time' a task should have gotten. All runnable tasks are
49sorted in the rbtree by the "rq->fair_clock - p->wait_runtime" key, and
50CFS picks the 'leftmost' task and sticks to it. As the system progresses
51forwards, newly woken tasks are put into the tree more and more to the
52right - slowly but surely giving a chance for every task to become the
53'leftmost task' and thus get on the CPU within a deterministic amount of
54time.
55
56Some implementation details:
57
58 - the introduction of Scheduling Classes: an extensible hierarchy of
59 scheduler modules. These modules encapsulate scheduling policy
60 details and are handled by the scheduler core without the core
61 code assuming about them too much.
62
63 - sched_fair.c implements the 'CFS desktop scheduler': it is a
64 replacement for the vanilla scheduler's SCHED_OTHER interactivity
65 code.
66
67 I'd like to give credit to Con Kolivas for the general approach here:
68 he has proven via RSDL/SD that 'fair scheduling' is possible and that
69 it results in better desktop scheduling. Kudos Con!
70
71 The CFS patch uses a completely different approach and implementation
72 from RSDL/SD. My goal was to make CFS's interactivity quality exceed
73 that of RSDL/SD, which is a high standard to meet :-) Testing
74 feedback is welcome to decide this one way or another. [ and, in any
75 case, all of SD's logic could be added via a kernel/sched_sd.c module
76 as well, if Con is interested in such an approach. ]
77
78 CFS's design is quite radical: it does not use runqueues, it uses a
79 time-ordered rbtree to build a 'timeline' of future task execution,
80 and thus has no 'array switch' artifacts (by which both the vanilla
81 scheduler and RSDL/SD are affected).
82
83 CFS uses nanosecond granularity accounting and does not rely on any
84 jiffies or other HZ detail. Thus the CFS scheduler has no notion of
85 'timeslices' and has no heuristics whatsoever. There is only one
86 central tunable:
87
88 /proc/sys/kernel/sched_granularity_ns
89
90 which can be used to tune the scheduler from 'desktop' (low
91 latencies) to 'server' (good batching) workloads. It defaults to a
92 setting suitable for desktop workloads. SCHED_BATCH is handled by the
93 CFS scheduler module too.
94
95 Due to its design, the CFS scheduler is not prone to any of the
96 'attacks' that exist today against the heuristics of the stock
97 scheduler: fiftyp.c, thud.c, chew.c, ring-test.c, massive_intr.c all
98 work fine and do not impact interactivity and produce the expected
99 behavior.
100
101 the CFS scheduler has a much stronger handling of nice levels and
102 SCHED_BATCH: both types of workloads should be isolated much more
103 agressively than under the vanilla scheduler.
104
105 ( another detail: due to nanosec accounting and timeline sorting,
106 sched_yield() support is very simple under CFS, and in fact under
107 CFS sched_yield() behaves much better than under any other
108 scheduler i have tested so far. )
109
110 - sched_rt.c implements SCHED_FIFO and SCHED_RR semantics, in a simpler
111 way than the vanilla scheduler does. It uses 100 runqueues (for all
112 100 RT priority levels, instead of 140 in the vanilla scheduler)
113 and it needs no expired array.
114
115 - reworked/sanitized SMP load-balancing: the runqueue-walking
116 assumptions are gone from the load-balancing code now, and
117 iterators of the scheduling modules are used. The balancing code got
118 quite a bit simpler as a result.
119
diff --git a/MAINTAINERS b/MAINTAINERS
index df40a4ec87fb..151f4ef978a4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1856,7 +1856,7 @@ W: http://www.openib.org/
1856T: git kernel.org:/pub/scm/linux/kernel/git/roland/infiniband.git 1856T: git kernel.org:/pub/scm/linux/kernel/git/roland/infiniband.git
1857S: Supported 1857S: Supported
1858 1858
1859INPUT (KEYBOARD, MOUSE, JOYSTICK) DRIVERS 1859INPUT (KEYBOARD, MOUSE, JOYSTICK, TOUCHSCREEN) DRIVERS
1860P: Dmitry Torokhov 1860P: Dmitry Torokhov
1861M: dmitry.torokhov@gmail.com 1861M: dmitry.torokhov@gmail.com
1862M: dtor@mail.ru 1862M: dtor@mail.ru
@@ -2930,6 +2930,13 @@ M: mikpe@it.uu.se
2930L: linux-ide@vger.kernel.org 2930L: linux-ide@vger.kernel.org
2931S: Maintained 2931S: Maintained
2932 2932
2933PS3 NETWORK SUPPORT
2934P: Masakazu Mokuno
2935M: mokuno@sm.sony.co.jp
2936L: netdev@vger.kernel.org
2937L: cbe-oss-dev@ozlabs.org
2938S: Supported
2939
2933PS3 PLATFORM SUPPORT 2940PS3 PLATFORM SUPPORT
2934P: Geoff Levand 2941P: Geoff Levand
2935M: geoffrey.levand@am.sony.com 2942M: geoffrey.levand@am.sony.com
@@ -3049,6 +3056,16 @@ S: Maintained
3049RISCOM8 DRIVER 3056RISCOM8 DRIVER
3050S: Orphan 3057S: Orphan
3051 3058
3059RTL818X WIRELESS DRIVER
3060P: Michael Wu
3061M: flamingice@sourmilk.net
3062P: Andrea Merello
3063M: andreamrl@tiscali.it
3064L: linux-wireless@vger.kernel.org
3065W: http://linuxwireless.org/
3066T: git kernel.org:/pub/scm/linux/kernel/git/mwu/mac80211-drivers.git
3067S: Maintained
3068
3052S3 SAVAGE FRAMEBUFFER DRIVER 3069S3 SAVAGE FRAMEBUFFER DRIVER
3053P: Antonino Daplas 3070P: Antonino Daplas
3054M: adaplas@gmail.com 3071M: adaplas@gmail.com
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
index 88baed1e7e83..0b2954534b8e 100644
--- a/arch/i386/kernel/smpboot.c
+++ b/arch/i386/kernel/smpboot.c
@@ -941,17 +941,6 @@ exit:
941} 941}
942#endif 942#endif
943 943
944static void smp_tune_scheduling(void)
945{
946 if (cpu_khz) {
947 /* cache size in kB */
948 long cachesize = boot_cpu_data.x86_cache_size;
949
950 if (cachesize > 0)
951 max_cache_size = cachesize * 1024;
952 }
953}
954
955/* 944/*
956 * Cycle through the processors sending APIC IPIs to boot each. 945 * Cycle through the processors sending APIC IPIs to boot each.
957 */ 946 */
@@ -980,7 +969,6 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
980 x86_cpu_to_apicid[0] = boot_cpu_physical_apicid; 969 x86_cpu_to_apicid[0] = boot_cpu_physical_apicid;
981 970
982 current_thread_info()->cpu = 0; 971 current_thread_info()->cpu = 0;
983 smp_tune_scheduling();
984 972
985 set_cpu_sibling_map(0); 973 set_cpu_sibling_map(0);
986 974
diff --git a/arch/i386/kernel/tsc.c b/arch/i386/kernel/tsc.c
index f64b81f3033b..ea63a30ca3e8 100644
--- a/arch/i386/kernel/tsc.c
+++ b/arch/i386/kernel/tsc.c
@@ -4,6 +4,7 @@
4 * See comments there for proper credits. 4 * See comments there for proper credits.
5 */ 5 */
6 6
7#include <linux/sched.h>
7#include <linux/clocksource.h> 8#include <linux/clocksource.h>
8#include <linux/workqueue.h> 9#include <linux/workqueue.h>
9#include <linux/cpufreq.h> 10#include <linux/cpufreq.h>
@@ -106,8 +107,13 @@ unsigned long long sched_clock(void)
106 107
107 /* 108 /*
108 * Fall back to jiffies if there's no TSC available: 109 * Fall back to jiffies if there's no TSC available:
110 * ( But note that we still use it if the TSC is marked
111 * unstable. We do this because unlike Time Of Day,
112 * the scheduler clock tolerates small errors and it's
113 * very important for it to be as fast as the platform
114 * can achive it. )
109 */ 115 */
110 if (unlikely(!tsc_enabled)) 116 if (unlikely(!tsc_enabled && !tsc_unstable))
111 /* No locking but a rare wrong value is not a big deal: */ 117 /* No locking but a rare wrong value is not a big deal: */
112 return (jiffies_64 - INITIAL_JIFFIES) * (1000000000 / HZ); 118 return (jiffies_64 - INITIAL_JIFFIES) * (1000000000 / HZ);
113 119
@@ -277,6 +283,7 @@ static struct clocksource clocksource_tsc = {
277 283
278void mark_tsc_unstable(char *reason) 284void mark_tsc_unstable(char *reason)
279{ 285{
286 sched_clock_unstable_event();
280 if (!tsc_unstable) { 287 if (!tsc_unstable) {
281 tsc_unstable = 1; 288 tsc_unstable = 1;
282 tsc_enabled = 0; 289 tsc_enabled = 0;
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c
index eaa6a24bc0b6..188fb73c6845 100644
--- a/arch/ia64/kernel/setup.c
+++ b/arch/ia64/kernel/setup.c
@@ -805,7 +805,6 @@ static void __cpuinit
805get_max_cacheline_size (void) 805get_max_cacheline_size (void)
806{ 806{
807 unsigned long line_size, max = 1; 807 unsigned long line_size, max = 1;
808 unsigned int cache_size = 0;
809 u64 l, levels, unique_caches; 808 u64 l, levels, unique_caches;
810 pal_cache_config_info_t cci; 809 pal_cache_config_info_t cci;
811 s64 status; 810 s64 status;
@@ -835,8 +834,6 @@ get_max_cacheline_size (void)
835 line_size = 1 << cci.pcci_line_size; 834 line_size = 1 << cci.pcci_line_size;
836 if (line_size > max) 835 if (line_size > max)
837 max = line_size; 836 max = line_size;
838 if (cache_size < cci.pcci_cache_size)
839 cache_size = cci.pcci_cache_size;
840 if (!cci.pcci_unified) { 837 if (!cci.pcci_unified) {
841 status = ia64_pal_cache_config_info(l, 838 status = ia64_pal_cache_config_info(l,
842 /* cache_type (instruction)= */ 1, 839 /* cache_type (instruction)= */ 1,
@@ -853,9 +850,6 @@ get_max_cacheline_size (void)
853 ia64_i_cache_stride_shift = cci.pcci_stride; 850 ia64_i_cache_stride_shift = cci.pcci_stride;
854 } 851 }
855 out: 852 out:
856#ifdef CONFIG_SMP
857 max_cache_size = max(max_cache_size, cache_size);
858#endif
859 if (max > ia64_max_cacheline_size) 853 if (max > ia64_max_cacheline_size)
860 ia64_max_cacheline_size = max; 854 ia64_max_cacheline_size = max;
861} 855}
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 73455389257a..a00fabe2e4e0 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -15,6 +15,29 @@ choice
15 prompt "System type" 15 prompt "System type"
16 default SGI_IP22 16 default SGI_IP22
17 17
18config LEMOTE_FULONG
19 bool "Lemote Fulong mini-PC"
20 select ARCH_SPARSEMEM_ENABLE
21 select SYS_HAS_CPU_LOONGSON2
22 select DMA_NONCOHERENT
23 select BOOT_ELF32
24 select BOARD_SCACHE
25 select HAVE_STD_PC_SERIAL_PORT
26 select HW_HAS_PCI
27 select I8259
28 select ISA
29 select IRQ_CPU
30 select SYS_SUPPORTS_32BIT_KERNEL
31 select SYS_SUPPORTS_64BIT_KERNEL
32 select SYS_SUPPORTS_LITTLE_ENDIAN
33 select SYS_SUPPORTS_HIGHMEM
34 select SYS_HAS_EARLY_PRINTK
35 select GENERIC_HARDIRQS_NO__DO_IRQ
36 select CPU_HAS_WB
37 help
38 Lemote Fulong mini-PC board based on the Chinese Loongson-2E CPU and
39 an FPGA northbridge
40
18config MACH_ALCHEMY 41config MACH_ALCHEMY
19 bool "Alchemy processor based machines" 42 bool "Alchemy processor based machines"
20 43
@@ -63,7 +86,7 @@ config MACH_DECSTATION
63 bool "DECstations" 86 bool "DECstations"
64 select BOOT_ELF32 87 select BOOT_ELF32
65 select DMA_NONCOHERENT 88 select DMA_NONCOHERENT
66 select SYS_HAS_EARLY_PRINTK 89 select NO_IOPORT
67 select IRQ_CPU 90 select IRQ_CPU
68 select SYS_HAS_CPU_R3000 91 select SYS_HAS_CPU_R3000
69 select SYS_HAS_CPU_R4X00 92 select SYS_HAS_CPU_R4X00
@@ -88,24 +111,6 @@ config MACH_DECSTATION
88 111
89 otherwise choose R3000. 112 otherwise choose R3000.
90 113
91config MIPS_EV64120
92 bool "Galileo EV64120 Evaluation board (EXPERIMENTAL)"
93 depends on EXPERIMENTAL
94 select DMA_NONCOHERENT
95 select HW_HAS_PCI
96 select PCI_GT64XXX_PCI0
97 select SYS_HAS_CPU_R5000
98 select SYS_SUPPORTS_32BIT_KERNEL
99 select SYS_SUPPORTS_64BIT_KERNEL
100 select SYS_SUPPORTS_BIG_ENDIAN
101 select SYS_SUPPORTS_KGDB
102 help
103 This is an evaluation board based on the Galileo GT-64120
104 single-chip system controller that contains a MIPS R5000 compatible
105 core running at 75/100MHz. Their website is located at
106 <http://www.marvell.com/>. Say Y here if you wish to build a
107 kernel for this platform.
108
109config MACH_JAZZ 114config MACH_JAZZ
110 bool "Jazz family of machines" 115 bool "Jazz family of machines"
111 select ARC 116 select ARC
@@ -126,20 +131,6 @@ config MACH_JAZZ
126 Members include the Acer PICA, MIPS Magnum 4000, MIPS Millenium and 131 Members include the Acer PICA, MIPS Magnum 4000, MIPS Millenium and
127 Olivetti M700-10 workstations. 132 Olivetti M700-10 workstations.
128 133
129config LASAT
130 bool "LASAT Networks platforms"
131 select DMA_NONCOHERENT
132 select SYS_HAS_EARLY_PRINTK
133 select HW_HAS_PCI
134 select PCI_GT64XXX_PCI0
135 select MIPS_NILE4
136 select R5000_CPU_SCACHE
137 select SYS_HAS_CPU_R5000
138 select SYS_SUPPORTS_32BIT_KERNEL
139 select SYS_SUPPORTS_64BIT_KERNEL if BROKEN
140 select SYS_SUPPORTS_LITTLE_ENDIAN
141 select GENERIC_HARDIRQS_NO__DO_IRQ
142
143config MIPS_ATLAS 134config MIPS_ATLAS
144 bool "MIPS Atlas board" 135 bool "MIPS Atlas board"
145 select BOOT_ELF32 136 select BOOT_ELF32
@@ -173,7 +164,6 @@ config MIPS_MALTA
173 bool "MIPS Malta board" 164 bool "MIPS Malta board"
174 select ARCH_MAY_HAVE_PC_FDC 165 select ARCH_MAY_HAVE_PC_FDC
175 select BOOT_ELF32 166 select BOOT_ELF32
176 select HAVE_STD_PC_SERIAL_PORT
177 select DMA_NONCOHERENT 167 select DMA_NONCOHERENT
178 select GENERIC_ISA_DMA 168 select GENERIC_ISA_DMA
179 select IRQ_CPU 169 select IRQ_CPU
@@ -246,11 +236,13 @@ config MIPS_SIM
246 select DMA_NONCOHERENT 236 select DMA_NONCOHERENT
247 select SYS_HAS_EARLY_PRINTK 237 select SYS_HAS_EARLY_PRINTK
248 select IRQ_CPU 238 select IRQ_CPU
239 select BOOT_RAW
249 select SYS_HAS_CPU_MIPS32_R1 240 select SYS_HAS_CPU_MIPS32_R1
250 select SYS_HAS_CPU_MIPS32_R2 241 select SYS_HAS_CPU_MIPS32_R2
251 select SYS_HAS_EARLY_PRINTK 242 select SYS_HAS_EARLY_PRINTK
252 select SYS_SUPPORTS_32BIT_KERNEL 243 select SYS_SUPPORTS_32BIT_KERNEL
253 select SYS_SUPPORTS_BIG_ENDIAN 244 select SYS_SUPPORTS_BIG_ENDIAN
245 select SYS_SUPPORTS_MULTITHREADING
254 select SYS_SUPPORTS_LITTLE_ENDIAN 246 select SYS_SUPPORTS_LITTLE_ENDIAN
255 help 247 help
256 This option enables support for MIPS Technologies MIPSsim software 248 This option enables support for MIPS Technologies MIPSsim software
@@ -274,43 +266,6 @@ config MOMENCO_OCELOT
274 The Ocelot is a MIPS-based Single Board Computer (SBC) made by 266 The Ocelot is a MIPS-based Single Board Computer (SBC) made by
275 Momentum Computer <http://www.momenco.com/>. 267 Momentum Computer <http://www.momenco.com/>.
276 268
277config MOMENCO_OCELOT_3
278 bool "Momentum Ocelot-3 board"
279 select BOOT_ELF32
280 select DMA_NONCOHERENT
281 select HW_HAS_PCI
282 select IRQ_CPU
283 select IRQ_CPU_RM7K
284 select IRQ_MV64340
285 select PCI_MARVELL
286 select RM7000_CPU_SCACHE
287 select SWAP_IO_SPACE
288 select SYS_HAS_CPU_RM9000
289 select SYS_SUPPORTS_32BIT_KERNEL
290 select SYS_SUPPORTS_64BIT_KERNEL
291 select SYS_SUPPORTS_BIG_ENDIAN
292 help
293 The Ocelot-3 is based off Discovery III System Controller and
294 PMC-Sierra Rm79000 core.
295
296config MOMENCO_OCELOT_C
297 bool "Momentum Ocelot-C board"
298 select DMA_NONCOHERENT
299 select HW_HAS_PCI
300 select IRQ_CPU
301 select IRQ_MV64340
302 select PCI_MARVELL
303 select RM7000_CPU_SCACHE
304 select SWAP_IO_SPACE
305 select SYS_HAS_CPU_RM7000
306 select SYS_SUPPORTS_32BIT_KERNEL
307 select SYS_SUPPORTS_64BIT_KERNEL
308 select SYS_SUPPORTS_BIG_ENDIAN
309 select GENERIC_HARDIRQS_NO__DO_IRQ
310 help
311 The Ocelot is a MIPS-based Single Board Computer (SBC) made by
312 Momentum Computer <http://www.momenco.com/>.
313
314config PNX8550_JBS 269config PNX8550_JBS
315 bool "Philips PNX8550 based JBS board" 270 bool "Philips PNX8550 based JBS board"
316 select PNX8550 271 select PNX8550
@@ -346,6 +301,27 @@ config MACH_VR41XX
346 select SYS_HAS_CPU_VR41XX 301 select SYS_HAS_CPU_VR41XX
347 select GENERIC_HARDIRQS_NO__DO_IRQ 302 select GENERIC_HARDIRQS_NO__DO_IRQ
348 303
304config PMC_MSP
305 bool "PMC-Sierra MSP chipsets"
306 depends on EXPERIMENTAL
307 select DMA_NONCOHERENT
308 select SWAP_IO_SPACE
309 select NO_EXCEPT_FILL
310 select BOOT_RAW
311 select SYS_HAS_CPU_MIPS32_R1
312 select SYS_HAS_CPU_MIPS32_R2
313 select SYS_SUPPORTS_32BIT_KERNEL
314 select SYS_SUPPORTS_BIG_ENDIAN
315 select SYS_SUPPORTS_KGDB
316 select IRQ_CPU
317 select SERIAL_8250
318 select SERIAL_8250_CONSOLE
319 help
320 This adds support for the PMC-Sierra family of Multi-Service
321 Processor System-On-A-Chips. These parts include a number
322 of integrated peripherals, interfaces and DSPs in addition to
323 a variety of MIPS cores.
324
349config PMC_YOSEMITE 325config PMC_YOSEMITE
350 bool "PMC-Sierra Yosemite eval board" 326 bool "PMC-Sierra Yosemite eval board"
351 select DMA_COHERENT 327 select DMA_COHERENT
@@ -450,8 +426,7 @@ config SGI_IP27
450 here. 426 here.
451 427
452config SGI_IP32 428config SGI_IP32
453 bool "SGI IP32 (O2) (EXPERIMENTAL)" 429 bool "SGI IP32 (O2)"
454 depends on EXPERIMENTAL
455 select ARC 430 select ARC
456 select ARC32 431 select ARC32
457 select BOOT_ELF32 432 select BOOT_ELF32
@@ -652,6 +627,7 @@ config TOSHIBA_RBTX4938
652 select SYS_SUPPORTS_BIG_ENDIAN 627 select SYS_SUPPORTS_BIG_ENDIAN
653 select SYS_SUPPORTS_KGDB 628 select SYS_SUPPORTS_KGDB
654 select GENERIC_HARDIRQS_NO__DO_IRQ 629 select GENERIC_HARDIRQS_NO__DO_IRQ
630 select GENERIC_GPIO
655 help 631 help
656 This Toshiba board is based on the TX4938 processor. Say Y here to 632 This Toshiba board is based on the TX4938 processor. Say Y here to
657 support this machine type 633 support this machine type
@@ -660,9 +636,7 @@ endchoice
660 636
661source "arch/mips/au1000/Kconfig" 637source "arch/mips/au1000/Kconfig"
662source "arch/mips/ddb5xxx/Kconfig" 638source "arch/mips/ddb5xxx/Kconfig"
663source "arch/mips/gt64120/ev64120/Kconfig"
664source "arch/mips/jazz/Kconfig" 639source "arch/mips/jazz/Kconfig"
665source "arch/mips/lasat/Kconfig"
666source "arch/mips/pmc-sierra/Kconfig" 640source "arch/mips/pmc-sierra/Kconfig"
667source "arch/mips/sgi-ip27/Kconfig" 641source "arch/mips/sgi-ip27/Kconfig"
668source "arch/mips/sibyte/Kconfig" 642source "arch/mips/sibyte/Kconfig"
@@ -721,6 +695,9 @@ config ARC
721config ARCH_MAY_HAVE_PC_FDC 695config ARCH_MAY_HAVE_PC_FDC
722 bool 696 bool
723 697
698config BOOT_RAW
699 bool
700
724config DMA_COHERENT 701config DMA_COHERENT
725 bool 702 bool
726 703
@@ -768,16 +745,19 @@ config MIPS_BONITO64
768config MIPS_MSC 745config MIPS_MSC
769 bool 746 bool
770 747
771config MIPS_NILE4
772 bool
773
774config MIPS_DISABLE_OBSOLETE_IDE 748config MIPS_DISABLE_OBSOLETE_IDE
775 bool 749 bool
776 750
751config NO_IOPORT
752 def_bool n
753
777config GENERIC_ISA_DMA_SUPPORT_BROKEN 754config GENERIC_ISA_DMA_SUPPORT_BROKEN
778 bool 755 bool
779 select ZONE_DMA 756 select ZONE_DMA
780 757
758config GENERIC_GPIO
759 bool
760
781# 761#
782# Endianess selection. Sufficiently obscure so many users don't know what to 762# Endianess selection. Sufficiently obscure so many users don't know what to
783# answer,so we try hard to limit the available choices. Also the use of a 763# answer,so we try hard to limit the available choices. Also the use of a
@@ -821,7 +801,10 @@ config IRQ_CPU_RM7K
821config IRQ_CPU_RM9K 801config IRQ_CPU_RM9K
822 bool 802 bool
823 803
824config IRQ_MV64340 804config IRQ_MSP_SLP
805 bool
806
807config IRQ_MSP_CIC
825 bool 808 bool
826 809
827config DDB5XXX_COMMON 810config DDB5XXX_COMMON
@@ -834,6 +817,9 @@ config MIPS_BOARDS_GEN
834config PCI_GT64XXX_PCI0 817config PCI_GT64XXX_PCI0
835 bool 818 bool
836 819
820config NO_EXCEPT_FILL
821 bool
822
837config MIPS_TX3927 823config MIPS_TX3927
838 bool 824 bool
839 select HAS_TXX9_SERIAL 825 select HAS_TXX9_SERIAL
@@ -841,14 +827,6 @@ config MIPS_TX3927
841config MIPS_RM9122 827config MIPS_RM9122
842 bool 828 bool
843 select SERIAL_RM9000 829 select SERIAL_RM9000
844 select GPI_RM9000
845 select WDT_RM9000
846
847config PCI_MARVELL
848 bool
849
850config SERIAL_RM9000
851 bool
852 830
853config PNX8550 831config PNX8550
854 bool 832 bool
@@ -863,6 +841,7 @@ config SOC_PNX8550
863 select SYS_SUPPORTS_32BIT_KERNEL 841 select SYS_SUPPORTS_32BIT_KERNEL
864 select GENERIC_HARDIRQS_NO__DO_IRQ 842 select GENERIC_HARDIRQS_NO__DO_IRQ
865 select SYS_SUPPORTS_KGDB 843 select SYS_SUPPORTS_KGDB
844 select GENERIC_GPIO
866 845
867config SWAP_IO_SPACE 846config SWAP_IO_SPACE
868 bool 847 bool
@@ -875,31 +854,17 @@ config EMMA2RH
875config SERIAL_RM9000 854config SERIAL_RM9000
876 bool 855 bool
877 856
878config GPI_RM9000
879 bool
880
881config WDT_RM9000
882 bool
883
884# 857#
885# Unfortunately not all GT64120 systems run the chip at the same clock. 858# Unfortunately not all GT64120 systems run the chip at the same clock.
886# As the user for the clock rate and try to minimize the available options. 859# As the user for the clock rate and try to minimize the available options.
887# 860#
888choice 861choice
889 prompt "Galileo Chip Clock" 862 prompt "Galileo Chip Clock"
890 #default SYSCLK_83 if MIPS_EV64120 863 depends on MOMENCO_OCELOT
891 depends on MIPS_EV64120 || MOMENCO_OCELOT
892 default SYSCLK_83 if MIPS_EV64120
893 default SYSCLK_100 if MOMENCO_OCELOT 864 default SYSCLK_100 if MOMENCO_OCELOT
894 865
895config SYSCLK_75
896 bool "75" if MIPS_EV64120
897
898config SYSCLK_83
899 bool "83.3" if MIPS_EV64120
900
901config SYSCLK_100 866config SYSCLK_100
902 bool "100" if MIPS_EV64120 || MOMENCO_OCELOT 867 bool "100" if MOMENCO_OCELOT
903 868
904endchoice 869endchoice
905 870
@@ -911,8 +876,9 @@ config BOOT_ELF32
911 876
912config MIPS_L1_CACHE_SHIFT 877config MIPS_L1_CACHE_SHIFT
913 int 878 int
914 default "4" if MACH_DECSTATION || SNI_RM 879 default "4" if MACH_DECSTATION
915 default "7" if SGI_IP27 880 default "7" if SGI_IP27 || SNI_RM
881 default "4" if PMC_MSP4200_EVAL
916 default "5" 882 default "5"
917 883
918config HAVE_STD_PC_SERIAL_PORT 884config HAVE_STD_PC_SERIAL_PORT
@@ -944,6 +910,16 @@ choice
944 prompt "CPU type" 910 prompt "CPU type"
945 default CPU_R4X00 911 default CPU_R4X00
946 912
913config CPU_LOONGSON2
914 bool "Loongson 2"
915 depends on SYS_HAS_CPU_LOONGSON2
916 select CPU_SUPPORTS_32BIT_KERNEL
917 select CPU_SUPPORTS_64BIT_KERNEL
918 select CPU_SUPPORTS_HIGHMEM
919 help
920 The Loongson 2E processor implements the MIPS III instruction set
921 with many extensions.
922
947config CPU_MIPS32_R1 923config CPU_MIPS32_R1
948 bool "MIPS32 Release 1" 924 bool "MIPS32 Release 1"
949 depends on SYS_HAS_CPU_MIPS32_R1 925 depends on SYS_HAS_CPU_MIPS32_R1
@@ -1154,6 +1130,9 @@ config CPU_SB1
1154 1130
1155endchoice 1131endchoice
1156 1132
1133config SYS_HAS_CPU_LOONGSON2
1134 bool
1135
1157config SYS_HAS_CPU_MIPS32_R1 1136config SYS_HAS_CPU_MIPS32_R1
1158 bool 1137 bool
1159 1138
@@ -1488,6 +1467,15 @@ config CPU_HAS_SMARTMIPS
1488config CPU_HAS_WB 1467config CPU_HAS_WB
1489 bool 1468 bool
1490 1469
1470config 64BIT_CONTEXT
1471 bool "Save 64bit integer registers"
1472 depends on 32BIT && CPU_LOONGSON2
1473 help
1474 Loongson2 CPU is 64bit , when used in 32BIT mode, its integer
1475 registers can still be accessed as 64bit, mainly for multimedia
1476 instructions. We must have all 64bit save/restored to make sure
1477 those instructions to get correct result.
1478
1491# 1479#
1492# Vectored interrupt mode is an R2 feature 1480# Vectored interrupt mode is an R2 feature
1493# 1481#
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index f450066b6241..20d19c9b7761 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -118,6 +118,7 @@ cflags-$(CONFIG_CPU_R4300) += -march=r4300 -Wa,--trap
118cflags-$(CONFIG_CPU_VR41XX) += -march=r4100 -Wa,--trap 118cflags-$(CONFIG_CPU_VR41XX) += -march=r4100 -Wa,--trap
119cflags-$(CONFIG_CPU_R4X00) += -march=r4600 -Wa,--trap 119cflags-$(CONFIG_CPU_R4X00) += -march=r4600 -Wa,--trap
120cflags-$(CONFIG_CPU_TX49XX) += -march=r4600 -Wa,--trap 120cflags-$(CONFIG_CPU_TX49XX) += -march=r4600 -Wa,--trap
121cflags-$(CONFIG_CPU_LOONGSON2) += -march=r4600 -Wa,--trap
121cflags-$(CONFIG_CPU_MIPS32_R1) += $(call cc-option,-march=mips32,-mips32 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS32) \ 122cflags-$(CONFIG_CPU_MIPS32_R1) += $(call cc-option,-march=mips32,-mips32 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS32) \
122 -Wa,-mips32 -Wa,--trap 123 -Wa,-mips32 -Wa,--trap
123cflags-$(CONFIG_CPU_MIPS32_R2) += $(call cc-option,-march=mips32r2,-mips32r2 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS32) \ 124cflags-$(CONFIG_CPU_MIPS32_R2) += $(call cc-option,-march=mips32r2,-mips32r2 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS32) \
@@ -283,14 +284,6 @@ load-$(CONFIG_MACH_DECSTATION) += 0xffffffff80040000
283CLEAN_FILES += drivers/tc/lk201-map.c 284CLEAN_FILES += drivers/tc/lk201-map.c
284 285
285# 286#
286# Galileo EV64120 Board
287#
288core-$(CONFIG_MIPS_EV64120) += arch/mips/gt64120/ev64120/
289core-$(CONFIG_MIPS_EV64120) += arch/mips/gt64120/common/
290cflags-$(CONFIG_MIPS_EV64120) += -Iinclude/asm-mips/mach-ev64120
291load-$(CONFIG_MIPS_EV64120) += 0xffffffff80100000
292
293#
294# Wind River PPMC Board (4KC + GT64120) 287# Wind River PPMC Board (4KC + GT64120)
295# 288#
296core-$(CONFIG_WR_PPMC) += arch/mips/gt64120/wrppmc/ 289core-$(CONFIG_WR_PPMC) += arch/mips/gt64120/wrppmc/
@@ -298,6 +291,13 @@ cflags-$(CONFIG_WR_PPMC) += -Iinclude/asm-mips/mach-wrppmc
298load-$(CONFIG_WR_PPMC) += 0xffffffff80100000 291load-$(CONFIG_WR_PPMC) += 0xffffffff80100000
299 292
300# 293#
294# lemote fulong mini-PC board
295#
296core-$(CONFIG_LEMOTE_FULONG) +=arch/mips/lemote/lm2e/
297load-$(CONFIG_LEMOTE_FULONG) +=0xffffffff80100000
298cflags-$(CONFIG_LEMOTE_FULONG) += -Iinclude/asm-mips/mach-lemote
299
300#
301# For all MIPS, Inc. eval boards 301# For all MIPS, Inc. eval boards
302# 302#
303core-$(CONFIG_MIPS_BOARDS_GEN) += arch/mips/mips-boards/generic/ 303core-$(CONFIG_MIPS_BOARDS_GEN) += arch/mips/mips-boards/generic/
@@ -327,7 +327,7 @@ load-$(CONFIG_MIPS_SEAD) += 0xffffffff80100000
327# 327#
328# MIPS SIM 328# MIPS SIM
329# 329#
330core-$(CONFIG_MIPS_SIM) += arch/mips/mips-boards/sim/ 330core-$(CONFIG_MIPS_SIM) += arch/mips/mipssim/
331cflags-$(CONFIG_MIPS_SIM) += -Iinclude/asm-mips/mach-sim 331cflags-$(CONFIG_MIPS_SIM) += -Iinclude/asm-mips/mach-sim
332load-$(CONFIG_MIPS_SIM) += 0x80100000 332load-$(CONFIG_MIPS_SIM) += 0x80100000
333 333
@@ -343,12 +343,12 @@ cflags-$(CONFIG_MOMENCO_OCELOT) += -Iinclude/asm-mips/mach-ocelot
343load-$(CONFIG_MOMENCO_OCELOT) += 0xffffffff80100000 343load-$(CONFIG_MOMENCO_OCELOT) += 0xffffffff80100000
344 344
345# 345#
346# Momentum Ocelot-C and -CS boards 346# PMC-Sierra MSP SOCs
347# 347#
348# The Ocelot-C[S] setup.o must be linked early - it does the ioremap() for the 348core-$(CONFIG_PMC_MSP) += arch/mips/pmc-sierra/msp71xx/
349# mips_io_port_base. 349cflags-$(CONFIG_PMC_MSP) += -Iinclude/asm-mips/pmc-sierra/msp71xx \
350core-$(CONFIG_MOMENCO_OCELOT_C) += arch/mips/momentum/ocelot_c/ 350 -mno-branch-likely
351load-$(CONFIG_MOMENCO_OCELOT_C) += 0xffffffff80100000 351load-$(CONFIG_PMC_MSP) += 0xffffffff80100000
352 352
353# 353#
354# PMC-Sierra Yosemite 354# PMC-Sierra Yosemite
@@ -365,13 +365,6 @@ cflags-$(CONFIG_QEMU) += -Iinclude/asm-mips/mach-qemu
365load-$(CONFIG_QEMU) += 0xffffffff80010000 365load-$(CONFIG_QEMU) += 0xffffffff80010000
366 366
367# 367#
368# Momentum Ocelot-3
369#
370core-$(CONFIG_MOMENCO_OCELOT_3) += arch/mips/momentum/ocelot_3/
371cflags-$(CONFIG_MOMENCO_OCELOT_3) += -Iinclude/asm-mips/mach-ocelot3
372load-$(CONFIG_MOMENCO_OCELOT_3) += 0xffffffff80100000
373
374#
375# Basler eXcite 368# Basler eXcite
376# 369#
377core-$(CONFIG_BASLER_EXCITE) += arch/mips/basler/excite/ 370core-$(CONFIG_BASLER_EXCITE) += arch/mips/basler/excite/
@@ -389,10 +382,6 @@ core-$(CONFIG_DDB5XXX_COMMON) += arch/mips/ddb5xxx/common/
389core-$(CONFIG_DDB5477) += arch/mips/ddb5xxx/ddb5477/ 382core-$(CONFIG_DDB5477) += arch/mips/ddb5xxx/ddb5477/
390load-$(CONFIG_DDB5477) += 0xffffffff80100000 383load-$(CONFIG_DDB5477) += 0xffffffff80100000
391 384
392core-$(CONFIG_LASAT) += arch/mips/lasat/
393cflags-$(CONFIG_LASAT) += -Iinclude/asm-mips/mach-lasat
394load-$(CONFIG_LASAT) += 0xffffffff80000000
395
396# 385#
397# Common VR41xx 386# Common VR41xx
398# 387#
@@ -580,6 +569,7 @@ load-$(CONFIG_TOSHIBA_JMR3927) += 0xffffffff80050000
580# 569#
581core-$(CONFIG_TOSHIBA_RBTX4927) += arch/mips/tx4927/toshiba_rbtx4927/ 570core-$(CONFIG_TOSHIBA_RBTX4927) += arch/mips/tx4927/toshiba_rbtx4927/
582core-$(CONFIG_TOSHIBA_RBTX4927) += arch/mips/tx4927/common/ 571core-$(CONFIG_TOSHIBA_RBTX4927) += arch/mips/tx4927/common/
572cflags-$(CONFIG_TOSHIBA_RBTX4927) += -Iinclude/asm-mips/mach-tx49xx
583load-$(CONFIG_TOSHIBA_RBTX4927) += 0xffffffff80020000 573load-$(CONFIG_TOSHIBA_RBTX4927) += 0xffffffff80020000
584 574
585# 575#
@@ -587,6 +577,7 @@ load-$(CONFIG_TOSHIBA_RBTX4927) += 0xffffffff80020000
587# 577#
588core-$(CONFIG_TOSHIBA_RBTX4938) += arch/mips/tx4938/toshiba_rbtx4938/ 578core-$(CONFIG_TOSHIBA_RBTX4938) += arch/mips/tx4938/toshiba_rbtx4938/
589core-$(CONFIG_TOSHIBA_RBTX4938) += arch/mips/tx4938/common/ 579core-$(CONFIG_TOSHIBA_RBTX4938) += arch/mips/tx4938/common/
580cflags-$(CONFIG_TOSHIBA_RBTX4938) += -Iinclude/asm-mips/mach-tx49xx
590load-$(CONFIG_TOSHIBA_RBTX4938) += 0xffffffff80100000 581load-$(CONFIG_TOSHIBA_RBTX4938) += 0xffffffff80100000
591 582
592cflags-y += -Iinclude/asm-mips/mach-generic 583cflags-y += -Iinclude/asm-mips/mach-generic
@@ -603,7 +594,8 @@ JIFFIES = jiffies_64
603endif 594endif
604 595
605AFLAGS += $(cflags-y) 596AFLAGS += $(cflags-y)
606CFLAGS += $(cflags-y) 597CFLAGS += $(cflags-y) \
598 -D"VMLINUX_LOAD_ADDRESS=$(load-y)"
607 599
608LDFLAGS += -m $(ld-emul) 600LDFLAGS += -m $(ld-emul)
609 601
@@ -633,18 +625,11 @@ CPPFLAGS_vmlinux.lds := \
633head-y := arch/mips/kernel/head.o arch/mips/kernel/init_task.o 625head-y := arch/mips/kernel/head.o arch/mips/kernel/init_task.o
634 626
635libs-y += arch/mips/lib/ 627libs-y += arch/mips/lib/
636libs-$(CONFIG_32BIT) += arch/mips/lib-32/
637libs-$(CONFIG_64BIT) += arch/mips/lib-64/
638 628
639core-y += arch/mips/kernel/ arch/mips/mm/ arch/mips/math-emu/ 629core-y += arch/mips/kernel/ arch/mips/mm/ arch/mips/math-emu/
640 630
641drivers-$(CONFIG_OPROFILE) += arch/mips/oprofile/ 631drivers-$(CONFIG_OPROFILE) += arch/mips/oprofile/
642 632
643ifdef CONFIG_LASAT
644rom.bin rom.sw: vmlinux
645 $(Q)$(MAKE) $(build)=arch/mips/lasat/image $@
646endif
647
648# 633#
649# Some machines like the Indy need 32-bit ELF binaries for booting purposes. 634# Some machines like the Indy need 32-bit ELF binaries for booting purposes.
650# Other need ECOFF, so we build a 32-bit ELF binary for them which we then 635# Other need ECOFF, so we build a 32-bit ELF binary for them which we then
@@ -702,32 +687,19 @@ vmlinux.srec: $(vmlinux-32)
702CLEAN_FILES += vmlinux.ecoff \ 687CLEAN_FILES += vmlinux.ecoff \
703 vmlinux.srec 688 vmlinux.srec
704 689
690archprepare:
691ifdef CONFIG_MIPS32_N32
692 @echo ' Checking missing-syscalls for N32'
693 $(Q)$(MAKE) $(build)=. missing-syscalls EXTRA_CFLAGS="-mabi=n32"
694endif
695ifdef CONFIG_MIPS32_O32
696 @echo ' Checking missing-syscalls for O32'
697 $(Q)$(MAKE) $(build)=. missing-syscalls EXTRA_CFLAGS="-mabi=32"
698endif
699
705archclean: 700archclean:
706 @$(MAKE) $(clean)=arch/mips/boot 701 @$(MAKE) $(clean)=arch/mips/boot
707 @$(MAKE) $(clean)=arch/mips/lasat
708 702
709CLEAN_FILES += vmlinux.32 \ 703CLEAN_FILES += vmlinux.32 \
710 vmlinux.64 \ 704 vmlinux.64 \
711 vmlinux.ecoff 705 vmlinux.ecoff
712
713quiet_cmd_syscalls_n32 = CALL-N32 $<
714 cmd_syscalls_n32 = $(CONFIG_SHELL) $< $(CC) $(c_flags) -mabi=n32
715
716quiet_cmd_syscalls_o32 = CALL-O32 $<
717 cmd_syscalls_o32 = $(CONFIG_SHELL) $< $(CC) $(c_flags) -mabi=32
718
719PHONY += missing-syscalls-n32 missing-syscalls-o32
720
721missing-syscalls-n32: scripts/checksyscalls.sh FORCE
722 $(call cmd,syscalls_n32)
723
724missing-syscalls-o32: scripts/checksyscalls.sh FORCE
725 $(call cmd,syscalls_o32)
726
727archprepare:
728ifdef CONFIG_MIPS32_N32
729 $(Q)$(MAKE) $(build)=arch/mips missing-syscalls-n32
730endif
731ifdef CONFIG_MIPS32_O32
732 $(Q)$(MAKE) $(build)=arch/mips missing-syscalls-o32
733endif
diff --git a/arch/mips/au1000/common/gpio.c b/arch/mips/au1000/common/gpio.c
index ce55297dcb8c..7abe42099439 100644
--- a/arch/mips/au1000/common/gpio.c
+++ b/arch/mips/au1000/common/gpio.c
@@ -1,4 +1,7 @@
1/* 1/*
2 * Copyright (C) 2007, OpenWrt.org, Florian Fainelli <florian@openwrt.org>
3 * Architecture specific GPIO support
4 *
2 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU General Public License as published by the 6 * under the terms of the GNU General Public License as published by the
4 * Free Software Foundation; either version 2 of the License, or (at your 7 * Free Software Foundation; either version 2 of the License, or (at your
@@ -18,101 +21,136 @@
18 * You should have received a copy of the GNU General Public License along 21 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc., 22 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 675 Mass Ave, Cambridge, MA 02139, USA. 23 * 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 * Notes :
26 * au1000 SoC have only one GPIO line : GPIO1
27 * others have a second one : GPIO2
21 */ 28 */
29
30#include <linux/autoconf.h>
31#include <linux/init.h>
32#include <linux/io.h>
33#include <linux/types.h>
22#include <linux/module.h> 34#include <linux/module.h>
23#include <au1000.h> 35
24#include <au1xxx_gpio.h> 36#include <asm/addrspace.h>
37
38#include <asm/mach-au1x00/au1000.h>
39#include <asm/gpio.h>
25 40
26#define gpio1 sys 41#define gpio1 sys
27#if !defined(CONFIG_SOC_AU1000) 42#if !defined(CONFIG_SOC_AU1000)
28static AU1X00_GPIO2 * const gpio2 = (AU1X00_GPIO2 *)GPIO2_BASE;
29 43
30#define GPIO2_OUTPUT_ENABLE_MASK 0x00010000 44static struct au1x00_gpio2 *const gpio2 = (struct au1x00_gpio2 *) GPIO2_BASE;
45#define GPIO2_OUTPUT_ENABLE_MASK 0x00010000
31 46
32int au1xxx_gpio2_read(int signal) 47static int au1xxx_gpio2_read(unsigned gpio)
33{ 48{
34 signal -= 200; 49 gpio -= AU1XXX_GPIO_BASE;
35/* gpio2->dir &= ~(0x01 << signal); //Set GPIO to input */ 50 return ((gpio2->pinstate >> gpio) & 0x01);
36 return ((gpio2->pinstate >> signal) & 0x01);
37} 51}
38 52
39void au1xxx_gpio2_write(int signal, int value) 53static void au1xxx_gpio2_write(unsigned gpio, int value)
40{ 54{
41 signal -= 200; 55 gpio -= AU1XXX_GPIO_BASE;
42 56
43 gpio2->output = (GPIO2_OUTPUT_ENABLE_MASK << signal) | 57 gpio2->output = (GPIO2_OUTPUT_ENABLE_MASK << gpio) | (value << gpio);
44 (value << signal);
45} 58}
46 59
47void au1xxx_gpio2_tristate(int signal) 60static int au1xxx_gpio2_direction_input(unsigned gpio)
48{ 61{
49 signal -= 200; 62 gpio -= AU1XXX_GPIO_BASE;
50 gpio2->dir &= ~(0x01 << signal); /* Set GPIO to input */ 63 gpio2->dir &= ~(0x01 << gpio);
64 return 0;
51} 65}
52#endif
53 66
54int au1xxx_gpio1_read(int signal) 67static int au1xxx_gpio2_direction_output(unsigned gpio, int value)
68{
69 gpio -= AU1XXX_GPIO_BASE;
70 gpio2->dir = (0x01 << gpio) | (value << gpio);
71 return 0;
72}
73
74#endif /* !defined(CONFIG_SOC_AU1000) */
75
76static int au1xxx_gpio1_read(unsigned gpio)
55{ 77{
56/* gpio1->trioutclr |= (0x01 << signal); */ 78 return ((gpio1->pinstaterd >> gpio) & 0x01);
57 return ((gpio1->pinstaterd >> signal) & 0x01);
58} 79}
59 80
60void au1xxx_gpio1_write(int signal, int value) 81static void au1xxx_gpio1_write(unsigned gpio, int value)
61{ 82{
62 if(value) 83 if (value)
63 gpio1->outputset = (0x01 << signal); 84 gpio1->outputset = (0x01 << gpio);
64 else 85 else
65 gpio1->outputclr = (0x01 << signal); /* Output a Zero */ 86 /* Output a zero */
87 gpio1->outputclr = (0x01 << gpio);
66} 88}
67 89
68void au1xxx_gpio1_tristate(int signal) 90static int au1xxx_gpio1_direction_input(unsigned gpio)
69{ 91{
70 gpio1->trioutclr = (0x01 << signal); /* Tristate signal */ 92 gpio1->pininputen = (0x01 << gpio);
93 return 0;
71} 94}
72 95
96static int au1xxx_gpio1_direction_output(unsigned gpio, int value)
97{
98 gpio1->trioutclr = (0x01 & gpio);
99 return 0;
100}
73 101
74int au1xxx_gpio_read(int signal) 102int au1xxx_gpio_get_value(unsigned gpio)
75{ 103{
76 if(signal >= 200) 104 if (gpio >= AU1XXX_GPIO_BASE)
77#if defined(CONFIG_SOC_AU1000) 105#if defined(CONFIG_SOC_AU1000)
78 return 0; 106 return 0;
79#else 107#else
80 return au1xxx_gpio2_read(signal); 108 return au1xxx_gpio2_read(gpio);
81#endif 109#endif
82 else 110 else
83 return au1xxx_gpio1_read(signal); 111 return au1xxx_gpio1_read(gpio);
84} 112}
85 113
86void au1xxx_gpio_write(int signal, int value) 114EXPORT_SYMBOL(au1xxx_gpio_get_value);
115
116void au1xxx_gpio_set_value(unsigned gpio, int value)
87{ 117{
88 if(signal >= 200) 118 if (gpio >= AU1XXX_GPIO_BASE)
89#if defined(CONFIG_SOC_AU1000) 119#if defined(CONFIG_SOC_AU1000)
90 ; 120 ;
91#else 121#else
92 au1xxx_gpio2_write(signal, value); 122 au1xxx_gpio2_write(gpio, value);
93#endif 123#endif
94 else 124 else
95 au1xxx_gpio1_write(signal, value); 125 au1xxx_gpio1_write(gpio, value);
96} 126}
97 127
98void au1xxx_gpio_tristate(int signal) 128EXPORT_SYMBOL(au1xxx_gpio_set_value);
129
130int au1xxx_gpio_direction_input(unsigned gpio)
99{ 131{
100 if(signal >= 200) 132 if (gpio >= AU1XXX_GPIO_BASE)
101#if defined(CONFIG_SOC_AU1000) 133#if defined(CONFIG_SOC_AU1000)
102 ; 134 ;
103#else 135#else
104 au1xxx_gpio2_tristate(signal); 136 return au1xxx_gpio2_direction_input(gpio);
105#endif 137#endif
106 else 138 else
107 au1xxx_gpio1_tristate(signal); 139 return au1xxx_gpio1_direction_input(gpio);
108} 140}
109 141
110void au1xxx_gpio1_set_inputs(void) 142EXPORT_SYMBOL(au1xxx_gpio_direction_input);
143
144int au1xxx_gpio_direction_output(unsigned gpio, int value)
111{ 145{
112 gpio1->pininputen = 0; 146 if (gpio >= AU1XXX_GPIO_BASE)
147#if defined(CONFIG_SOC_AU1000)
148 ;
149#else
150 return au1xxx_gpio2_direction_output(gpio, value);
151#endif
152 else
153 return au1xxx_gpio1_direction_output(gpio, value);
113} 154}
114 155
115EXPORT_SYMBOL(au1xxx_gpio1_set_inputs); 156EXPORT_SYMBOL(au1xxx_gpio_direction_output);
116EXPORT_SYMBOL(au1xxx_gpio_tristate);
117EXPORT_SYMBOL(au1xxx_gpio_write);
118EXPORT_SYMBOL(au1xxx_gpio_read);
diff --git a/arch/mips/au1000/common/platform.c b/arch/mips/au1000/common/platform.c
index 8fd203d4a339..d51e18fb789b 100644
--- a/arch/mips/au1000/common/platform.c
+++ b/arch/mips/au1000/common/platform.c
@@ -289,7 +289,7 @@ static struct platform_device *au1xxx_platform_devices[] __initdata = {
289#endif 289#endif
290}; 290};
291 291
292int au1xxx_platform_init(void) 292int __init au1xxx_platform_init(void)
293{ 293{
294 return platform_add_devices(au1xxx_platform_devices, ARRAY_SIZE(au1xxx_platform_devices)); 294 return platform_add_devices(au1xxx_platform_devices, ARRAY_SIZE(au1xxx_platform_devices));
295} 295}
diff --git a/arch/mips/configs/atlas_defconfig b/arch/mips/configs/atlas_defconfig
index 39e251300c64..129e2c961fec 100644
--- a/arch/mips/configs/atlas_defconfig
+++ b/arch/mips/configs/atlas_defconfig
@@ -25,9 +25,7 @@ CONFIG_ZONE_DMA=y
25# CONFIG_BASLER_EXCITE is not set 25# CONFIG_BASLER_EXCITE is not set
26# CONFIG_MIPS_COBALT is not set 26# CONFIG_MIPS_COBALT is not set
27# CONFIG_MACH_DECSTATION is not set 27# CONFIG_MACH_DECSTATION is not set
28# CONFIG_MIPS_EV64120 is not set
29# CONFIG_MACH_JAZZ is not set 28# CONFIG_MACH_JAZZ is not set
30# CONFIG_LASAT is not set
31CONFIG_MIPS_ATLAS=y 29CONFIG_MIPS_ATLAS=y
32# CONFIG_MIPS_MALTA is not set 30# CONFIG_MIPS_MALTA is not set
33# CONFIG_MIPS_SEAD is not set 31# CONFIG_MIPS_SEAD is not set
@@ -35,8 +33,6 @@ CONFIG_MIPS_ATLAS=y
35# CONFIG_MIPS_SIM is not set 33# CONFIG_MIPS_SIM is not set
36# CONFIG_MOMENCO_JAGUAR_ATX is not set 34# CONFIG_MOMENCO_JAGUAR_ATX is not set
37# CONFIG_MOMENCO_OCELOT is not set 35# CONFIG_MOMENCO_OCELOT is not set
38# CONFIG_MOMENCO_OCELOT_3 is not set
39# CONFIG_MOMENCO_OCELOT_C is not set
40# CONFIG_MOMENCO_OCELOT_G is not set 36# CONFIG_MOMENCO_OCELOT_G is not set
41# CONFIG_MIPS_XXS1500 is not set 37# CONFIG_MIPS_XXS1500 is not set
42# CONFIG_PNX8550_JBS is not set 38# CONFIG_PNX8550_JBS is not set
diff --git a/arch/mips/configs/bigsur_defconfig b/arch/mips/configs/bigsur_defconfig
index 4713a13211ce..dc3e1bf4e42e 100644
--- a/arch/mips/configs/bigsur_defconfig
+++ b/arch/mips/configs/bigsur_defconfig
@@ -25,9 +25,7 @@ CONFIG_ZONE_DMA=y
25# CONFIG_BASLER_EXCITE is not set 25# CONFIG_BASLER_EXCITE is not set
26# CONFIG_MIPS_COBALT is not set 26# CONFIG_MIPS_COBALT is not set
27# CONFIG_MACH_DECSTATION is not set 27# CONFIG_MACH_DECSTATION is not set
28# CONFIG_MIPS_EV64120 is not set
29# CONFIG_MACH_JAZZ is not set 28# CONFIG_MACH_JAZZ is not set
30# CONFIG_LASAT is not set
31# CONFIG_MIPS_ATLAS is not set 29# CONFIG_MIPS_ATLAS is not set
32# CONFIG_MIPS_MALTA is not set 30# CONFIG_MIPS_MALTA is not set
33# CONFIG_MIPS_SEAD is not set 31# CONFIG_MIPS_SEAD is not set
@@ -35,8 +33,6 @@ CONFIG_ZONE_DMA=y
35# CONFIG_MIPS_SIM is not set 33# CONFIG_MIPS_SIM is not set
36# CONFIG_MOMENCO_JAGUAR_ATX is not set 34# CONFIG_MOMENCO_JAGUAR_ATX is not set
37# CONFIG_MOMENCO_OCELOT is not set 35# CONFIG_MOMENCO_OCELOT is not set
38# CONFIG_MOMENCO_OCELOT_3 is not set
39# CONFIG_MOMENCO_OCELOT_C is not set
40# CONFIG_MOMENCO_OCELOT_G is not set 36# CONFIG_MOMENCO_OCELOT_G is not set
41# CONFIG_MIPS_XXS1500 is not set 37# CONFIG_MIPS_XXS1500 is not set
42# CONFIG_PNX8550_JBS is not set 38# CONFIG_PNX8550_JBS is not set
diff --git a/arch/mips/configs/capcella_defconfig b/arch/mips/configs/capcella_defconfig
index 5e7ae56b1f3c..4c7031222e64 100644
--- a/arch/mips/configs/capcella_defconfig
+++ b/arch/mips/configs/capcella_defconfig
@@ -25,9 +25,7 @@ CONFIG_ZONE_DMA=y
25# CONFIG_BASLER_EXCITE is not set 25# CONFIG_BASLER_EXCITE is not set
26# CONFIG_MIPS_COBALT is not set 26# CONFIG_MIPS_COBALT is not set
27# CONFIG_MACH_DECSTATION is not set 27# CONFIG_MACH_DECSTATION is not set
28# CONFIG_MIPS_EV64120 is not set
29# CONFIG_MACH_JAZZ is not set 28# CONFIG_MACH_JAZZ is not set
30# CONFIG_LASAT is not set
31# CONFIG_MIPS_ATLAS is not set 29# CONFIG_MIPS_ATLAS is not set
32# CONFIG_MIPS_MALTA is not set 30# CONFIG_MIPS_MALTA is not set
33# CONFIG_MIPS_SEAD is not set 31# CONFIG_MIPS_SEAD is not set
@@ -35,8 +33,6 @@ CONFIG_ZONE_DMA=y
35# CONFIG_MIPS_SIM is not set 33# CONFIG_MIPS_SIM is not set
36# CONFIG_MOMENCO_JAGUAR_ATX is not set 34# CONFIG_MOMENCO_JAGUAR_ATX is not set
37# CONFIG_MOMENCO_OCELOT is not set 35# CONFIG_MOMENCO_OCELOT is not set
38# CONFIG_MOMENCO_OCELOT_3 is not set
39# CONFIG_MOMENCO_OCELOT_C is not set
40# CONFIG_MOMENCO_OCELOT_G is not set 36# CONFIG_MOMENCO_OCELOT_G is not set
41# CONFIG_MIPS_XXS1500 is not set 37# CONFIG_MIPS_XXS1500 is not set
42# CONFIG_PNX8550_JBS is not set 38# CONFIG_PNX8550_JBS is not set
diff --git a/arch/mips/configs/cobalt_defconfig b/arch/mips/configs/cobalt_defconfig
index 631b2138ad68..c8c05785a86d 100644
--- a/arch/mips/configs/cobalt_defconfig
+++ b/arch/mips/configs/cobalt_defconfig
@@ -1,44 +1,24 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.21-rc7 3# Linux kernel version: 2.6.22-rc2
4# Wed Apr 18 14:25:45 2007 4# Fri May 25 11:17:29 2007
5# 5#
6CONFIG_MIPS=y 6CONFIG_MIPS=y
7 7
8# 8#
9# Machine selection 9# Machine selection
10# 10#
11CONFIG_ZONE_DMA=y 11# CONFIG_MACH_ALCHEMY is not set
12# CONFIG_MIPS_MTX1 is not set
13# CONFIG_MIPS_BOSPORUS is not set
14# CONFIG_MIPS_PB1000 is not set
15# CONFIG_MIPS_PB1100 is not set
16# CONFIG_MIPS_PB1500 is not set
17# CONFIG_MIPS_PB1550 is not set
18# CONFIG_MIPS_PB1200 is not set
19# CONFIG_MIPS_DB1000 is not set
20# CONFIG_MIPS_DB1100 is not set
21# CONFIG_MIPS_DB1500 is not set
22# CONFIG_MIPS_DB1550 is not set
23# CONFIG_MIPS_DB1200 is not set
24# CONFIG_MIPS_MIRAGE is not set
25# CONFIG_BASLER_EXCITE is not set 12# CONFIG_BASLER_EXCITE is not set
26CONFIG_MIPS_COBALT=y 13CONFIG_MIPS_COBALT=y
27# CONFIG_MACH_DECSTATION is not set 14# CONFIG_MACH_DECSTATION is not set
28# CONFIG_MIPS_EV64120 is not set
29# CONFIG_MACH_JAZZ is not set 15# CONFIG_MACH_JAZZ is not set
30# CONFIG_LASAT is not set
31# CONFIG_MIPS_ATLAS is not set 16# CONFIG_MIPS_ATLAS is not set
32# CONFIG_MIPS_MALTA is not set 17# CONFIG_MIPS_MALTA is not set
33# CONFIG_MIPS_SEAD is not set 18# CONFIG_MIPS_SEAD is not set
34# CONFIG_WR_PPMC is not set 19# CONFIG_WR_PPMC is not set
35# CONFIG_MIPS_SIM is not set 20# CONFIG_MIPS_SIM is not set
36# CONFIG_MOMENCO_JAGUAR_ATX is not set
37# CONFIG_MOMENCO_OCELOT is not set 21# CONFIG_MOMENCO_OCELOT is not set
38# CONFIG_MOMENCO_OCELOT_3 is not set
39# CONFIG_MOMENCO_OCELOT_C is not set
40# CONFIG_MOMENCO_OCELOT_G is not set
41# CONFIG_MIPS_XXS1500 is not set
42# CONFIG_PNX8550_JBS is not set 22# CONFIG_PNX8550_JBS is not set
43# CONFIG_PNX8550_STB810 is not set 23# CONFIG_PNX8550_STB810 is not set
44# CONFIG_DDB5477 is not set 24# CONFIG_DDB5477 is not set
@@ -138,7 +118,7 @@ CONFIG_FLAT_NODE_MEM_MAP=y
138# CONFIG_SPARSEMEM_STATIC is not set 118# CONFIG_SPARSEMEM_STATIC is not set
139CONFIG_SPLIT_PTLOCK_CPUS=4 119CONFIG_SPLIT_PTLOCK_CPUS=4
140# CONFIG_RESOURCES_64BIT is not set 120# CONFIG_RESOURCES_64BIT is not set
141CONFIG_ZONE_DMA_FLAG=1 121CONFIG_ZONE_DMA_FLAG=0
142# CONFIG_HZ_48 is not set 122# CONFIG_HZ_48 is not set
143# CONFIG_HZ_100 is not set 123# CONFIG_HZ_100 is not set
144# CONFIG_HZ_128 is not set 124# CONFIG_HZ_128 is not set
@@ -178,6 +158,7 @@ CONFIG_SYSVIPC_SYSCTL=y
178# CONFIG_UTS_NS is not set 158# CONFIG_UTS_NS is not set
179# CONFIG_AUDIT is not set 159# CONFIG_AUDIT is not set
180# CONFIG_IKCONFIG is not set 160# CONFIG_IKCONFIG is not set
161CONFIG_LOG_BUF_SHIFT=14
181CONFIG_SYSFS_DEPRECATED=y 162CONFIG_SYSFS_DEPRECATED=y
182CONFIG_RELAY=y 163CONFIG_RELAY=y
183# CONFIG_BLK_DEV_INITRD is not set 164# CONFIG_BLK_DEV_INITRD is not set
@@ -193,14 +174,19 @@ CONFIG_BUG=y
193CONFIG_ELF_CORE=y 174CONFIG_ELF_CORE=y
194CONFIG_BASE_FULL=y 175CONFIG_BASE_FULL=y
195CONFIG_FUTEX=y 176CONFIG_FUTEX=y
177CONFIG_ANON_INODES=y
196CONFIG_EPOLL=y 178CONFIG_EPOLL=y
179CONFIG_SIGNALFD=y
180CONFIG_TIMERFD=y
181CONFIG_EVENTFD=y
197CONFIG_SHMEM=y 182CONFIG_SHMEM=y
198CONFIG_SLAB=y
199CONFIG_VM_EVENT_COUNTERS=y 183CONFIG_VM_EVENT_COUNTERS=y
184CONFIG_SLAB=y
185# CONFIG_SLUB is not set
186# CONFIG_SLOB is not set
200CONFIG_RT_MUTEXES=y 187CONFIG_RT_MUTEXES=y
201# CONFIG_TINY_SHMEM is not set 188# CONFIG_TINY_SHMEM is not set
202CONFIG_BASE_SMALL=0 189CONFIG_BASE_SMALL=0
203# CONFIG_SLOB is not set
204 190
205# 191#
206# Loadable module support 192# Loadable module support
@@ -233,16 +219,13 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
233# 219#
234CONFIG_HW_HAS_PCI=y 220CONFIG_HW_HAS_PCI=y
235CONFIG_PCI=y 221CONFIG_PCI=y
222# CONFIG_ARCH_SUPPORTS_MSI is not set
236CONFIG_MMU=y 223CONFIG_MMU=y
237 224
238# 225#
239# PCCARD (PCMCIA/CardBus) support 226# PCCARD (PCMCIA/CardBus) support
240# 227#
241# CONFIG_PCCARD is not set 228# CONFIG_PCCARD is not set
242
243#
244# PCI Hotplug Support
245#
246# CONFIG_HOTPLUG_PCI is not set 229# CONFIG_HOTPLUG_PCI is not set
247 230
248# 231#
@@ -268,7 +251,6 @@ CONFIG_NET=y
268# 251#
269# Networking options 252# Networking options
270# 253#
271# CONFIG_NETDEBUG is not set
272CONFIG_PACKET=y 254CONFIG_PACKET=y
273# CONFIG_PACKET_MMAP is not set 255# CONFIG_PACKET_MMAP is not set
274CONFIG_UNIX=y 256CONFIG_UNIX=y
@@ -300,11 +282,11 @@ CONFIG_INET_TCP_DIAG=y
300# CONFIG_TCP_CONG_ADVANCED is not set 282# CONFIG_TCP_CONG_ADVANCED is not set
301CONFIG_TCP_CONG_CUBIC=y 283CONFIG_TCP_CONG_CUBIC=y
302CONFIG_DEFAULT_TCP_CONG="cubic" 284CONFIG_DEFAULT_TCP_CONG="cubic"
303CONFIG_TCP_MD5SIG=y 285# CONFIG_TCP_MD5SIG is not set
304# CONFIG_IPV6 is not set 286# CONFIG_IPV6 is not set
305# CONFIG_INET6_XFRM_TUNNEL is not set 287# CONFIG_INET6_XFRM_TUNNEL is not set
306# CONFIG_INET6_TUNNEL is not set 288# CONFIG_INET6_TUNNEL is not set
307CONFIG_NETWORK_SECMARK=y 289# CONFIG_NETWORK_SECMARK is not set
308# CONFIG_NETFILTER is not set 290# CONFIG_NETFILTER is not set
309 291
310# 292#
@@ -345,13 +327,16 @@ CONFIG_NETWORK_SECMARK=y
345# CONFIG_HAMRADIO is not set 327# CONFIG_HAMRADIO is not set
346# CONFIG_IRDA is not set 328# CONFIG_IRDA is not set
347# CONFIG_BT is not set 329# CONFIG_BT is not set
348CONFIG_IEEE80211=y 330# CONFIG_AF_RXRPC is not set
349# CONFIG_IEEE80211_DEBUG is not set 331
350CONFIG_IEEE80211_CRYPT_WEP=y 332#
351CONFIG_IEEE80211_CRYPT_CCMP=y 333# Wireless
352CONFIG_IEEE80211_SOFTMAC=y 334#
353# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set 335# CONFIG_CFG80211 is not set
354CONFIG_WIRELESS_EXT=y 336# CONFIG_WIRELESS_EXT is not set
337# CONFIG_MAC80211 is not set
338# CONFIG_IEEE80211 is not set
339# CONFIG_RFKILL is not set
355 340
356# 341#
357# Device Drivers 342# Device Drivers
@@ -370,10 +355,6 @@ CONFIG_FW_LOADER=y
370# 355#
371CONFIG_CONNECTOR=y 356CONFIG_CONNECTOR=y
372CONFIG_PROC_EVENTS=y 357CONFIG_PROC_EVENTS=y
373
374#
375# Memory Technology Devices (MTD)
376#
377CONFIG_MTD=y 358CONFIG_MTD=y
378# CONFIG_MTD_DEBUG is not set 359# CONFIG_MTD_DEBUG is not set
379# CONFIG_MTD_CONCAT is not set 360# CONFIG_MTD_CONCAT is not set
@@ -418,7 +399,6 @@ CONFIG_MTD_CFI_UTIL=y
418# CONFIG_MTD_RAM is not set 399# CONFIG_MTD_RAM is not set
419# CONFIG_MTD_ROM is not set 400# CONFIG_MTD_ROM is not set
420# CONFIG_MTD_ABSENT is not set 401# CONFIG_MTD_ABSENT is not set
421# CONFIG_MTD_OBSOLETE_CHIPS is not set
422 402
423# 403#
424# Mapping drivers for chip access 404# Mapping drivers for chip access
@@ -445,16 +425,13 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=0
445# CONFIG_MTD_DOC2000 is not set 425# CONFIG_MTD_DOC2000 is not set
446# CONFIG_MTD_DOC2001 is not set 426# CONFIG_MTD_DOC2001 is not set
447# CONFIG_MTD_DOC2001PLUS is not set 427# CONFIG_MTD_DOC2001PLUS is not set
448
449#
450# NAND Flash Device Drivers
451#
452# CONFIG_MTD_NAND is not set 428# CONFIG_MTD_NAND is not set
429# CONFIG_MTD_ONENAND is not set
453 430
454# 431#
455# OneNAND Flash Device Drivers 432# UBI - Unsorted block images
456# 433#
457# CONFIG_MTD_ONENAND is not set 434# CONFIG_MTD_UBI is not set
458 435
459# 436#
460# Parallel port support 437# Parallel port support
@@ -479,87 +456,145 @@ CONFIG_BLK_DEV_LOOP=y
479# CONFIG_BLK_DEV_NBD is not set 456# CONFIG_BLK_DEV_NBD is not set
480# CONFIG_BLK_DEV_SX8 is not set 457# CONFIG_BLK_DEV_SX8 is not set
481# CONFIG_BLK_DEV_RAM is not set 458# CONFIG_BLK_DEV_RAM is not set
482CONFIG_CDROM_PKTCDVD=y 459# CONFIG_CDROM_PKTCDVD is not set
483CONFIG_CDROM_PKTCDVD_BUFFERS=8 460# CONFIG_ATA_OVER_ETH is not set
484# CONFIG_CDROM_PKTCDVD_WCACHE is not set
485CONFIG_ATA_OVER_ETH=y
486 461
487# 462#
488# Misc devices 463# Misc devices
489# 464#
490CONFIG_SGI_IOC4=y 465# CONFIG_PHANTOM is not set
466# CONFIG_SGI_IOC4 is not set
491# CONFIG_TIFM_CORE is not set 467# CONFIG_TIFM_CORE is not set
492 468# CONFIG_BLINK is not set
493# 469# CONFIG_IDE is not set
494# ATA/ATAPI/MFM/RLL support
495#
496CONFIG_IDE=y
497CONFIG_IDE_MAX_HWIFS=4
498CONFIG_BLK_DEV_IDE=y
499
500#
501# Please see Documentation/ide.txt for help/info on IDE drives
502#
503# CONFIG_BLK_DEV_IDE_SATA is not set
504CONFIG_BLK_DEV_IDEDISK=y
505# CONFIG_IDEDISK_MULTI_MODE is not set
506# CONFIG_BLK_DEV_IDECD is not set
507# CONFIG_BLK_DEV_IDETAPE is not set
508# CONFIG_BLK_DEV_IDEFLOPPY is not set
509# CONFIG_IDE_TASK_IOCTL is not set
510
511#
512# IDE chipset support/bugfixes
513#
514CONFIG_IDE_GENERIC=y
515CONFIG_BLK_DEV_IDEPCI=y
516# CONFIG_IDEPCI_SHARE_IRQ is not set
517# CONFIG_BLK_DEV_OFFBOARD is not set
518# CONFIG_BLK_DEV_GENERIC is not set
519# CONFIG_BLK_DEV_OPTI621 is not set
520CONFIG_BLK_DEV_IDEDMA_PCI=y
521# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
522# CONFIG_IDEDMA_ONLYDISK is not set
523# CONFIG_BLK_DEV_AEC62XX is not set
524# CONFIG_BLK_DEV_ALI15X3 is not set
525# CONFIG_BLK_DEV_AMD74XX is not set
526# CONFIG_BLK_DEV_CMD64X is not set
527# CONFIG_BLK_DEV_TRIFLEX is not set
528# CONFIG_BLK_DEV_CY82C693 is not set
529# CONFIG_BLK_DEV_CS5520 is not set
530# CONFIG_BLK_DEV_CS5530 is not set
531# CONFIG_BLK_DEV_HPT34X is not set
532# CONFIG_BLK_DEV_HPT366 is not set
533# CONFIG_BLK_DEV_JMICRON is not set
534# CONFIG_BLK_DEV_SC1200 is not set
535# CONFIG_BLK_DEV_PIIX is not set
536CONFIG_BLK_DEV_IT8213=y
537# CONFIG_BLK_DEV_IT821X is not set
538# CONFIG_BLK_DEV_NS87415 is not set
539# CONFIG_BLK_DEV_PDC202XX_OLD is not set
540# CONFIG_BLK_DEV_PDC202XX_NEW is not set
541# CONFIG_BLK_DEV_SVWKS is not set
542# CONFIG_BLK_DEV_SIIMAGE is not set
543# CONFIG_BLK_DEV_SLC90E66 is not set
544# CONFIG_BLK_DEV_TRM290 is not set
545CONFIG_BLK_DEV_VIA82CXXX=y
546CONFIG_BLK_DEV_TC86C001=y
547# CONFIG_IDE_ARM is not set
548CONFIG_BLK_DEV_IDEDMA=y
549# CONFIG_IDEDMA_IVB is not set
550# CONFIG_BLK_DEV_HD is not set
551 470
552# 471#
553# SCSI device support 472# SCSI device support
554# 473#
555CONFIG_RAID_ATTRS=y 474CONFIG_RAID_ATTRS=y
556# CONFIG_SCSI is not set 475CONFIG_SCSI=y
476# CONFIG_SCSI_TGT is not set
557# CONFIG_SCSI_NETLINK is not set 477# CONFIG_SCSI_NETLINK is not set
558 478CONFIG_SCSI_PROC_FS=y
559# 479
560# Serial ATA (prod) and Parallel ATA (experimental) drivers 480#
561# 481# SCSI support type (disk, tape, CD-ROM)
562# CONFIG_ATA is not set 482#
483CONFIG_BLK_DEV_SD=y
484# CONFIG_CHR_DEV_ST is not set
485# CONFIG_CHR_DEV_OSST is not set
486# CONFIG_BLK_DEV_SR is not set
487# CONFIG_CHR_DEV_SG is not set
488# CONFIG_CHR_DEV_SCH is not set
489
490#
491# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
492#
493# CONFIG_SCSI_MULTI_LUN is not set
494# CONFIG_SCSI_CONSTANTS is not set
495# CONFIG_SCSI_LOGGING is not set
496# CONFIG_SCSI_SCAN_ASYNC is not set
497
498#
499# SCSI Transports
500#
501# CONFIG_SCSI_SPI_ATTRS is not set
502# CONFIG_SCSI_FC_ATTRS is not set
503# CONFIG_SCSI_ISCSI_ATTRS is not set
504# CONFIG_SCSI_SAS_ATTRS is not set
505# CONFIG_SCSI_SAS_LIBSAS is not set
506
507#
508# SCSI low-level drivers
509#
510# CONFIG_ISCSI_TCP is not set
511# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
512# CONFIG_SCSI_3W_9XXX is not set
513# CONFIG_SCSI_ACARD is not set
514# CONFIG_SCSI_AACRAID is not set
515# CONFIG_SCSI_AIC7XXX is not set
516# CONFIG_SCSI_AIC7XXX_OLD is not set
517# CONFIG_SCSI_AIC79XX is not set
518# CONFIG_SCSI_AIC94XX is not set
519# CONFIG_SCSI_DPT_I2O is not set
520# CONFIG_SCSI_ARCMSR is not set
521# CONFIG_MEGARAID_NEWGEN is not set
522# CONFIG_MEGARAID_LEGACY is not set
523# CONFIG_MEGARAID_SAS is not set
524# CONFIG_SCSI_HPTIOP is not set
525# CONFIG_SCSI_DMX3191D is not set
526# CONFIG_SCSI_FUTURE_DOMAIN is not set
527# CONFIG_SCSI_IPS is not set
528# CONFIG_SCSI_INITIO is not set
529# CONFIG_SCSI_INIA100 is not set
530# CONFIG_SCSI_STEX is not set
531# CONFIG_SCSI_SYM53C8XX_2 is not set
532# CONFIG_SCSI_IPR is not set
533# CONFIG_SCSI_QLOGIC_1280 is not set
534# CONFIG_SCSI_QLA_FC is not set
535# CONFIG_SCSI_QLA_ISCSI is not set
536# CONFIG_SCSI_LPFC is not set
537# CONFIG_SCSI_DC395x is not set
538# CONFIG_SCSI_DC390T is not set
539# CONFIG_SCSI_NSP32 is not set
540# CONFIG_SCSI_DEBUG is not set
541# CONFIG_SCSI_ESP_CORE is not set
542# CONFIG_SCSI_SRP is not set
543CONFIG_ATA=y
544# CONFIG_ATA_NONSTANDARD is not set
545# CONFIG_SATA_AHCI is not set
546# CONFIG_SATA_SVW is not set
547# CONFIG_ATA_PIIX is not set
548# CONFIG_SATA_MV is not set
549# CONFIG_SATA_NV is not set
550# CONFIG_PDC_ADMA is not set
551# CONFIG_SATA_QSTOR is not set
552# CONFIG_SATA_PROMISE is not set
553# CONFIG_SATA_SX4 is not set
554# CONFIG_SATA_SIL is not set
555# CONFIG_SATA_SIL24 is not set
556# CONFIG_SATA_SIS is not set
557# CONFIG_SATA_ULI is not set
558# CONFIG_SATA_VIA is not set
559# CONFIG_SATA_VITESSE is not set
560# CONFIG_SATA_INIC162X is not set
561# CONFIG_PATA_ALI is not set
562# CONFIG_PATA_AMD is not set
563# CONFIG_PATA_ARTOP is not set
564# CONFIG_PATA_ATIIXP is not set
565# CONFIG_PATA_CMD640_PCI is not set
566# CONFIG_PATA_CMD64X is not set
567# CONFIG_PATA_CS5520 is not set
568# CONFIG_PATA_CS5530 is not set
569# CONFIG_PATA_CYPRESS is not set
570# CONFIG_PATA_EFAR is not set
571# CONFIG_ATA_GENERIC is not set
572# CONFIG_PATA_HPT366 is not set
573# CONFIG_PATA_HPT37X is not set
574# CONFIG_PATA_HPT3X2N is not set
575# CONFIG_PATA_HPT3X3 is not set
576# CONFIG_PATA_IT821X is not set
577# CONFIG_PATA_IT8213 is not set
578# CONFIG_PATA_JMICRON is not set
579# CONFIG_PATA_TRIFLEX is not set
580# CONFIG_PATA_MARVELL is not set
581# CONFIG_PATA_MPIIX is not set
582# CONFIG_PATA_OLDPIIX is not set
583# CONFIG_PATA_NETCELL is not set
584# CONFIG_PATA_NS87410 is not set
585# CONFIG_PATA_OPTI is not set
586# CONFIG_PATA_OPTIDMA is not set
587# CONFIG_PATA_PDC_OLD is not set
588# CONFIG_PATA_RADISYS is not set
589# CONFIG_PATA_RZ1000 is not set
590# CONFIG_PATA_SC1200 is not set
591# CONFIG_PATA_SERVERWORKS is not set
592# CONFIG_PATA_PDC2027X is not set
593# CONFIG_PATA_SIL680 is not set
594# CONFIG_PATA_SIS is not set
595CONFIG_PATA_VIA=y
596# CONFIG_PATA_WINBOND is not set
597# CONFIG_PATA_PLATFORM is not set
563 598
564# 599#
565# Multi-device support (RAID and LVM) 600# Multi-device support (RAID and LVM)
@@ -570,10 +605,14 @@ CONFIG_RAID_ATTRS=y
570# Fusion MPT device support 605# Fusion MPT device support
571# 606#
572# CONFIG_FUSION is not set 607# CONFIG_FUSION is not set
608# CONFIG_FUSION_SPI is not set
609# CONFIG_FUSION_FC is not set
610# CONFIG_FUSION_SAS is not set
573 611
574# 612#
575# IEEE 1394 (FireWire) support 613# IEEE 1394 (FireWire) support
576# 614#
615# CONFIG_FIREWIRE is not set
577# CONFIG_IEEE1394 is not set 616# CONFIG_IEEE1394 is not set
578 617
579# 618#
@@ -594,24 +633,7 @@ CONFIG_NETDEVICES=y
594# ARCnet devices 633# ARCnet devices
595# 634#
596# CONFIG_ARCNET is not set 635# CONFIG_ARCNET is not set
597 636# CONFIG_PHYLIB is not set
598#
599# PHY device support
600#
601CONFIG_PHYLIB=y
602
603#
604# MII PHY device drivers
605#
606CONFIG_MARVELL_PHY=y
607CONFIG_DAVICOM_PHY=y
608CONFIG_QSEMI_PHY=y
609CONFIG_LXT_PHY=y
610CONFIG_CICADA_PHY=y
611CONFIG_VITESSE_PHY=y
612CONFIG_SMSC_PHY=y
613# CONFIG_BROADCOM_PHY is not set
614# CONFIG_FIXED_PHY is not set
615 637
616# 638#
617# Ethernet (10 or 100Mbit) 639# Ethernet (10 or 100Mbit)
@@ -639,35 +661,8 @@ CONFIG_TULIP=y
639# CONFIG_ULI526X is not set 661# CONFIG_ULI526X is not set
640# CONFIG_HP100 is not set 662# CONFIG_HP100 is not set
641# CONFIG_NET_PCI is not set 663# CONFIG_NET_PCI is not set
642 664# CONFIG_NETDEV_1000 is not set
643# 665# CONFIG_NETDEV_10000 is not set
644# Ethernet (1000 Mbit)
645#
646# CONFIG_ACENIC is not set
647# CONFIG_DL2K is not set
648# CONFIG_E1000 is not set
649# CONFIG_NS83820 is not set
650# CONFIG_HAMACHI is not set
651# CONFIG_YELLOWFIN is not set
652# CONFIG_R8169 is not set
653# CONFIG_SIS190 is not set
654# CONFIG_SKGE is not set
655# CONFIG_SKY2 is not set
656# CONFIG_SK98LIN is not set
657# CONFIG_TIGON3 is not set
658# CONFIG_BNX2 is not set
659CONFIG_QLA3XXX=y
660# CONFIG_ATL1 is not set
661
662#
663# Ethernet (10000 Mbit)
664#
665# CONFIG_CHELSIO_T1 is not set
666CONFIG_CHELSIO_T3=y
667# CONFIG_IXGB is not set
668# CONFIG_S2IO is not set
669# CONFIG_MYRI10GE is not set
670CONFIG_NETXEN_NIC=y
671 666
672# 667#
673# Token Ring devices 668# Token Ring devices
@@ -675,18 +670,16 @@ CONFIG_NETXEN_NIC=y
675# CONFIG_TR is not set 670# CONFIG_TR is not set
676 671
677# 672#
678# Wireless LAN (non-hamradio) 673# Wireless LAN
679#
680# CONFIG_NET_RADIO is not set
681
682#
683# Wan interfaces
684# 674#
675# CONFIG_WLAN_PRE80211 is not set
676# CONFIG_WLAN_80211 is not set
685# CONFIG_WAN is not set 677# CONFIG_WAN is not set
686# CONFIG_FDDI is not set 678# CONFIG_FDDI is not set
687# CONFIG_HIPPI is not set 679# CONFIG_HIPPI is not set
688# CONFIG_PPP is not set 680# CONFIG_PPP is not set
689# CONFIG_SLIP is not set 681# CONFIG_SLIP is not set
682# CONFIG_NET_FC is not set
690# CONFIG_SHAPER is not set 683# CONFIG_SHAPER is not set
691# CONFIG_NETCONSOLE is not set 684# CONFIG_NETCONSOLE is not set
692# CONFIG_NETPOLL is not set 685# CONFIG_NETPOLL is not set
@@ -711,10 +704,7 @@ CONFIG_INPUT=y
711# 704#
712# Userland interfaces 705# Userland interfaces
713# 706#
714CONFIG_INPUT_MOUSEDEV=y 707# CONFIG_INPUT_MOUSEDEV is not set
715CONFIG_INPUT_MOUSEDEV_PSAUX=y
716CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
717CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
718# CONFIG_INPUT_JOYDEV is not set 708# CONFIG_INPUT_JOYDEV is not set
719# CONFIG_INPUT_TSDEV is not set 709# CONFIG_INPUT_TSDEV is not set
720# CONFIG_INPUT_EVDEV is not set 710# CONFIG_INPUT_EVDEV is not set
@@ -726,18 +716,23 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
726# CONFIG_INPUT_KEYBOARD is not set 716# CONFIG_INPUT_KEYBOARD is not set
727# CONFIG_INPUT_MOUSE is not set 717# CONFIG_INPUT_MOUSE is not set
728# CONFIG_INPUT_JOYSTICK is not set 718# CONFIG_INPUT_JOYSTICK is not set
719# CONFIG_INPUT_TABLET is not set
729# CONFIG_INPUT_TOUCHSCREEN is not set 720# CONFIG_INPUT_TOUCHSCREEN is not set
730# CONFIG_INPUT_MISC is not set 721CONFIG_INPUT_MISC=y
722# CONFIG_INPUT_PCSPKR is not set
723CONFIG_INPUT_COBALT_BTNS=y
724# CONFIG_INPUT_ATI_REMOTE is not set
725# CONFIG_INPUT_ATI_REMOTE2 is not set
726# CONFIG_INPUT_KEYSPAN_REMOTE is not set
727# CONFIG_INPUT_POWERMATE is not set
728# CONFIG_INPUT_YEALINK is not set
729# CONFIG_INPUT_UINPUT is not set
730CONFIG_INPUT_POLLDEV=y
731 731
732# 732#
733# Hardware I/O ports 733# Hardware I/O ports
734# 734#
735CONFIG_SERIO=y 735# CONFIG_SERIO is not set
736# CONFIG_SERIO_I8042 is not set
737CONFIG_SERIO_SERPORT=y
738# CONFIG_SERIO_PCIPS2 is not set
739# CONFIG_SERIO_LIBPS2 is not set
740CONFIG_SERIO_RAW=y
741# CONFIG_GAMEPORT is not set 736# CONFIG_GAMEPORT is not set
742 737
743# 738#
@@ -754,7 +749,7 @@ CONFIG_VT_HW_CONSOLE_BINDING=y
754# 749#
755CONFIG_SERIAL_8250=y 750CONFIG_SERIAL_8250=y
756CONFIG_SERIAL_8250_CONSOLE=y 751CONFIG_SERIAL_8250_CONSOLE=y
757CONFIG_SERIAL_8250_PCI=y 752# CONFIG_SERIAL_8250_PCI is not set
758CONFIG_SERIAL_8250_NR_UARTS=4 753CONFIG_SERIAL_8250_NR_UARTS=4
759CONFIG_SERIAL_8250_RUNTIME_UARTS=4 754CONFIG_SERIAL_8250_RUNTIME_UARTS=4
760# CONFIG_SERIAL_8250_EXTENDED is not set 755# CONFIG_SERIAL_8250_EXTENDED is not set
@@ -773,16 +768,11 @@ CONFIG_LEGACY_PTY_COUNT=256
773# IPMI 768# IPMI
774# 769#
775# CONFIG_IPMI_HANDLER is not set 770# CONFIG_IPMI_HANDLER is not set
776
777#
778# Watchdog Cards
779#
780# CONFIG_WATCHDOG is not set 771# CONFIG_WATCHDOG is not set
781# CONFIG_HW_RANDOM is not set 772# CONFIG_HW_RANDOM is not set
782# CONFIG_RTC is not set 773# CONFIG_RTC is not set
783# CONFIG_GEN_RTC is not set 774# CONFIG_GEN_RTC is not set
784CONFIG_COBALT_LCD=y 775CONFIG_COBALT_LCD=y
785# CONFIG_DTLK is not set
786# CONFIG_R3964 is not set 776# CONFIG_R3964 is not set
787# CONFIG_APPLICOM is not set 777# CONFIG_APPLICOM is not set
788# CONFIG_DRM is not set 778# CONFIG_DRM is not set
@@ -792,10 +782,7 @@ CONFIG_COBALT_LCD=y
792# TPM devices 782# TPM devices
793# 783#
794# CONFIG_TCG_TPM is not set 784# CONFIG_TCG_TPM is not set
795 785CONFIG_DEVPORT=y
796#
797# I2C support
798#
799# CONFIG_I2C is not set 786# CONFIG_I2C is not set
800 787
801# 788#
@@ -808,12 +795,7 @@ CONFIG_COBALT_LCD=y
808# Dallas's 1-wire bus 795# Dallas's 1-wire bus
809# 796#
810# CONFIG_W1 is not set 797# CONFIG_W1 is not set
811
812#
813# Hardware Monitoring support
814#
815# CONFIG_HWMON is not set 798# CONFIG_HWMON is not set
816# CONFIG_HWMON_VID is not set
817 799
818# 800#
819# Multifunction device drivers 801# Multifunction device drivers
@@ -824,16 +806,19 @@ CONFIG_COBALT_LCD=y
824# Multimedia devices 806# Multimedia devices
825# 807#
826# CONFIG_VIDEO_DEV is not set 808# CONFIG_VIDEO_DEV is not set
809# CONFIG_DVB_CORE is not set
810# CONFIG_DAB is not set
827 811
828# 812#
829# Digital Video Broadcasting Devices 813# Graphics support
830# 814#
831# CONFIG_DVB is not set 815# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
832 816
833# 817#
834# Graphics support 818# Display device support
835# 819#
836# CONFIG_BACKLIGHT_LCD_SUPPORT is not set 820# CONFIG_DISPLAY_SUPPORT is not set
821# CONFIG_VGASTATE is not set
837# CONFIG_FB is not set 822# CONFIG_FB is not set
838 823
839# 824#
@@ -868,10 +853,6 @@ CONFIG_USB_ARCH_HAS_EHCI=y
868# USB Gadget Support 853# USB Gadget Support
869# 854#
870# CONFIG_USB_GADGET is not set 855# CONFIG_USB_GADGET is not set
871
872#
873# MMC/SD Card support
874#
875# CONFIG_MMC is not set 856# CONFIG_MMC is not set
876 857
877# 858#
@@ -912,18 +893,30 @@ CONFIG_RTC_INTF_SYSFS=y
912CONFIG_RTC_INTF_PROC=y 893CONFIG_RTC_INTF_PROC=y
913CONFIG_RTC_INTF_DEV=y 894CONFIG_RTC_INTF_DEV=y
914# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set 895# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
896# CONFIG_RTC_DRV_TEST is not set
915 897
916# 898#
917# RTC drivers 899# I2C RTC drivers
900#
901
902#
903# SPI RTC drivers
904#
905
906#
907# Platform RTC drivers
918# 908#
919CONFIG_RTC_DRV_CMOS=y 909CONFIG_RTC_DRV_CMOS=y
920# CONFIG_RTC_DRV_DS1553 is not set 910# CONFIG_RTC_DRV_DS1553 is not set
921# CONFIG_RTC_DRV_DS1742 is not set 911# CONFIG_RTC_DRV_DS1742 is not set
922# CONFIG_RTC_DRV_M48T86 is not set 912# CONFIG_RTC_DRV_M48T86 is not set
923# CONFIG_RTC_DRV_TEST is not set
924# CONFIG_RTC_DRV_V3020 is not set 913# CONFIG_RTC_DRV_V3020 is not set
925 914
926# 915#
916# on-CPU RTC drivers
917#
918
919#
927# DMA Engine support 920# DMA Engine support
928# 921#
929# CONFIG_DMA_ENGINE is not set 922# CONFIG_DMA_ENGINE is not set
@@ -937,14 +930,6 @@ CONFIG_RTC_DRV_CMOS=y
937# 930#
938 931
939# 932#
940# Auxiliary Display support
941#
942
943#
944# Virtualization
945#
946
947#
948# File systems 933# File systems
949# 934#
950CONFIG_EXT2_FS=y 935CONFIG_EXT2_FS=y
@@ -952,8 +937,13 @@ CONFIG_EXT2_FS_XATTR=y
952CONFIG_EXT2_FS_POSIX_ACL=y 937CONFIG_EXT2_FS_POSIX_ACL=y
953CONFIG_EXT2_FS_SECURITY=y 938CONFIG_EXT2_FS_SECURITY=y
954# CONFIG_EXT2_FS_XIP is not set 939# CONFIG_EXT2_FS_XIP is not set
955# CONFIG_EXT3_FS is not set 940CONFIG_EXT3_FS=y
941CONFIG_EXT3_FS_XATTR=y
942CONFIG_EXT3_FS_POSIX_ACL=y
943CONFIG_EXT3_FS_SECURITY=y
956# CONFIG_EXT4DEV_FS is not set 944# CONFIG_EXT4DEV_FS is not set
945CONFIG_JBD=y
946# CONFIG_JBD_DEBUG is not set
957CONFIG_FS_MBCACHE=y 947CONFIG_FS_MBCACHE=y
958# CONFIG_REISERFS_FS is not set 948# CONFIG_REISERFS_FS is not set
959# CONFIG_JFS_FS is not set 949# CONFIG_JFS_FS is not set
@@ -969,7 +959,7 @@ CONFIG_INOTIFY_USER=y
969CONFIG_DNOTIFY=y 959CONFIG_DNOTIFY=y
970# CONFIG_AUTOFS_FS is not set 960# CONFIG_AUTOFS_FS is not set
971# CONFIG_AUTOFS4_FS is not set 961# CONFIG_AUTOFS4_FS is not set
972CONFIG_FUSE_FS=y 962# CONFIG_FUSE_FS is not set
973CONFIG_GENERIC_ACL=y 963CONFIG_GENERIC_ACL=y
974 964
975# 965#
@@ -1003,7 +993,6 @@ CONFIG_CONFIGFS_FS=y
1003# 993#
1004# CONFIG_ADFS_FS is not set 994# CONFIG_ADFS_FS is not set
1005# CONFIG_AFFS_FS is not set 995# CONFIG_AFFS_FS is not set
1006# CONFIG_ECRYPT_FS is not set
1007# CONFIG_HFS_FS is not set 996# CONFIG_HFS_FS is not set
1008# CONFIG_HFSPLUS_FS is not set 997# CONFIG_HFSPLUS_FS is not set
1009# CONFIG_BEFS_FS is not set 998# CONFIG_BEFS_FS is not set
@@ -1021,13 +1010,23 @@ CONFIG_CONFIGFS_FS=y
1021# Network File Systems 1010# Network File Systems
1022# 1011#
1023CONFIG_NFS_FS=y 1012CONFIG_NFS_FS=y
1024# CONFIG_NFS_V3 is not set 1013CONFIG_NFS_V3=y
1014CONFIG_NFS_V3_ACL=y
1025# CONFIG_NFS_V4 is not set 1015# CONFIG_NFS_V4 is not set
1026# CONFIG_NFS_DIRECTIO is not set 1016# CONFIG_NFS_DIRECTIO is not set
1027# CONFIG_NFSD is not set 1017CONFIG_NFSD=y
1018CONFIG_NFSD_V2_ACL=y
1019CONFIG_NFSD_V3=y
1020CONFIG_NFSD_V3_ACL=y
1021# CONFIG_NFSD_V4 is not set
1022CONFIG_NFSD_TCP=y
1028CONFIG_LOCKD=y 1023CONFIG_LOCKD=y
1024CONFIG_LOCKD_V4=y
1025CONFIG_EXPORTFS=y
1026CONFIG_NFS_ACL_SUPPORT=y
1029CONFIG_NFS_COMMON=y 1027CONFIG_NFS_COMMON=y
1030CONFIG_SUNRPC=y 1028CONFIG_SUNRPC=y
1029# CONFIG_SUNRPC_BIND34 is not set
1031# CONFIG_RPCSEC_GSS_KRB5 is not set 1030# CONFIG_RPCSEC_GSS_KRB5 is not set
1032# CONFIG_RPCSEC_GSS_SPKM3 is not set 1031# CONFIG_RPCSEC_GSS_SPKM3 is not set
1033# CONFIG_SMB_FS is not set 1032# CONFIG_SMB_FS is not set
@@ -1051,10 +1050,7 @@ CONFIG_MSDOS_PARTITION=y
1051# 1050#
1052# Distributed Lock Manager 1051# Distributed Lock Manager
1053# 1052#
1054CONFIG_DLM=y 1053# CONFIG_DLM is not set
1055CONFIG_DLM_TCP=y
1056# CONFIG_DLM_SCTP is not set
1057# CONFIG_DLM_DEBUG is not set
1058 1054
1059# 1055#
1060# Profiling support 1056# Profiling support
@@ -1072,72 +1068,30 @@ CONFIG_ENABLE_MUST_CHECK=y
1072# CONFIG_DEBUG_FS is not set 1068# CONFIG_DEBUG_FS is not set
1073# CONFIG_HEADERS_CHECK is not set 1069# CONFIG_HEADERS_CHECK is not set
1074# CONFIG_DEBUG_KERNEL is not set 1070# CONFIG_DEBUG_KERNEL is not set
1075CONFIG_LOG_BUF_SHIFT=14
1076CONFIG_CROSSCOMPILE=y 1071CONFIG_CROSSCOMPILE=y
1077CONFIG_CMDLINE="" 1072CONFIG_CMDLINE=""
1078 1073
1079# 1074#
1080# Security options 1075# Security options
1081# 1076#
1082CONFIG_KEYS=y 1077# CONFIG_KEYS is not set
1083CONFIG_KEYS_DEBUG_PROC_KEYS=y
1084# CONFIG_SECURITY is not set 1078# CONFIG_SECURITY is not set
1085 1079
1086# 1080#
1087# Cryptographic options 1081# Cryptographic options
1088# 1082#
1089CONFIG_CRYPTO=y 1083# CONFIG_CRYPTO is not set
1090CONFIG_CRYPTO_ALGAPI=y
1091CONFIG_CRYPTO_BLKCIPHER=y
1092CONFIG_CRYPTO_HASH=y
1093CONFIG_CRYPTO_MANAGER=y
1094CONFIG_CRYPTO_HMAC=y
1095CONFIG_CRYPTO_XCBC=y
1096CONFIG_CRYPTO_NULL=y
1097CONFIG_CRYPTO_MD4=y
1098CONFIG_CRYPTO_MD5=y
1099CONFIG_CRYPTO_SHA1=y
1100CONFIG_CRYPTO_SHA256=y
1101CONFIG_CRYPTO_SHA512=y
1102CONFIG_CRYPTO_WP512=y
1103CONFIG_CRYPTO_TGR192=y
1104CONFIG_CRYPTO_GF128MUL=y
1105CONFIG_CRYPTO_ECB=y
1106CONFIG_CRYPTO_CBC=y
1107CONFIG_CRYPTO_PCBC=y
1108CONFIG_CRYPTO_LRW=y
1109CONFIG_CRYPTO_DES=y
1110CONFIG_CRYPTO_FCRYPT=y
1111CONFIG_CRYPTO_BLOWFISH=y
1112CONFIG_CRYPTO_TWOFISH=y
1113CONFIG_CRYPTO_TWOFISH_COMMON=y
1114CONFIG_CRYPTO_SERPENT=y
1115CONFIG_CRYPTO_AES=y
1116CONFIG_CRYPTO_CAST5=y
1117CONFIG_CRYPTO_CAST6=y
1118CONFIG_CRYPTO_TEA=y
1119CONFIG_CRYPTO_ARC4=y
1120CONFIG_CRYPTO_KHAZAD=y
1121CONFIG_CRYPTO_ANUBIS=y
1122CONFIG_CRYPTO_DEFLATE=y
1123CONFIG_CRYPTO_MICHAEL_MIC=y
1124CONFIG_CRYPTO_CRC32C=y
1125CONFIG_CRYPTO_CAMELLIA=y
1126
1127#
1128# Hardware crypto devices
1129#
1130 1084
1131# 1085#
1132# Library routines 1086# Library routines
1133# 1087#
1134CONFIG_BITREVERSE=y 1088CONFIG_BITREVERSE=y
1135# CONFIG_CRC_CCITT is not set 1089# CONFIG_CRC_CCITT is not set
1136CONFIG_CRC16=y 1090# CONFIG_CRC16 is not set
1091# CONFIG_CRC_ITU_T is not set
1137CONFIG_CRC32=y 1092CONFIG_CRC32=y
1138CONFIG_LIBCRC32C=y 1093CONFIG_LIBCRC32C=y
1139CONFIG_ZLIB_INFLATE=y
1140CONFIG_ZLIB_DEFLATE=y
1141CONFIG_PLIST=y 1094CONFIG_PLIST=y
1142CONFIG_HAS_IOMEM=y 1095CONFIG_HAS_IOMEM=y
1143CONFIG_HAS_IOPORT=y 1096CONFIG_HAS_IOPORT=y
1097CONFIG_HAS_DMA=y
diff --git a/arch/mips/configs/db1000_defconfig b/arch/mips/configs/db1000_defconfig
index 10f6af43753d..ec60beb888b2 100644
--- a/arch/mips/configs/db1000_defconfig
+++ b/arch/mips/configs/db1000_defconfig
@@ -26,9 +26,7 @@ CONFIG_MIPS_DB1000=y
26# CONFIG_BASLER_EXCITE is not set 26# CONFIG_BASLER_EXCITE is not set
27# CONFIG_MIPS_COBALT is not set 27# CONFIG_MIPS_COBALT is not set
28# CONFIG_MACH_DECSTATION is not set 28# CONFIG_MACH_DECSTATION is not set
29# CONFIG_MIPS_EV64120 is not set
30# CONFIG_MACH_JAZZ is not set 29# CONFIG_MACH_JAZZ is not set
31# CONFIG_LASAT is not set
32# CONFIG_MIPS_ATLAS is not set 30# CONFIG_MIPS_ATLAS is not set
33# CONFIG_MIPS_MALTA is not set 31# CONFIG_MIPS_MALTA is not set
34# CONFIG_MIPS_SEAD is not set 32# CONFIG_MIPS_SEAD is not set
@@ -36,8 +34,6 @@ CONFIG_MIPS_DB1000=y
36# CONFIG_MIPS_SIM is not set 34# CONFIG_MIPS_SIM is not set
37# CONFIG_MOMENCO_JAGUAR_ATX is not set 35# CONFIG_MOMENCO_JAGUAR_ATX is not set
38# CONFIG_MOMENCO_OCELOT is not set 36# CONFIG_MOMENCO_OCELOT is not set
39# CONFIG_MOMENCO_OCELOT_3 is not set
40# CONFIG_MOMENCO_OCELOT_C is not set
41# CONFIG_MOMENCO_OCELOT_G is not set 37# CONFIG_MOMENCO_OCELOT_G is not set
42# CONFIG_MIPS_XXS1500 is not set 38# CONFIG_MIPS_XXS1500 is not set
43# CONFIG_PNX8550_JBS is not set 39# CONFIG_PNX8550_JBS is not set
diff --git a/arch/mips/configs/db1100_defconfig b/arch/mips/configs/db1100_defconfig
index 4b0862927748..f3c25f08bfad 100644
--- a/arch/mips/configs/db1100_defconfig
+++ b/arch/mips/configs/db1100_defconfig
@@ -26,9 +26,7 @@ CONFIG_MIPS_DB1100=y
26# CONFIG_BASLER_EXCITE is not set 26# CONFIG_BASLER_EXCITE is not set
27# CONFIG_MIPS_COBALT is not set 27# CONFIG_MIPS_COBALT is not set
28# CONFIG_MACH_DECSTATION is not set 28# CONFIG_MACH_DECSTATION is not set
29# CONFIG_MIPS_EV64120 is not set
30# CONFIG_MACH_JAZZ is not set 29# CONFIG_MACH_JAZZ is not set
31# CONFIG_LASAT is not set
32# CONFIG_MIPS_ATLAS is not set 30# CONFIG_MIPS_ATLAS is not set
33# CONFIG_MIPS_MALTA is not set 31# CONFIG_MIPS_MALTA is not set
34# CONFIG_MIPS_SEAD is not set 32# CONFIG_MIPS_SEAD is not set
@@ -36,8 +34,6 @@ CONFIG_MIPS_DB1100=y
36# CONFIG_MIPS_SIM is not set 34# CONFIG_MIPS_SIM is not set
37# CONFIG_MOMENCO_JAGUAR_ATX is not set 35# CONFIG_MOMENCO_JAGUAR_ATX is not set
38# CONFIG_MOMENCO_OCELOT is not set 36# CONFIG_MOMENCO_OCELOT is not set
39# CONFIG_MOMENCO_OCELOT_3 is not set
40# CONFIG_MOMENCO_OCELOT_C is not set
41# CONFIG_MOMENCO_OCELOT_G is not set 37# CONFIG_MOMENCO_OCELOT_G is not set
42# CONFIG_MIPS_XXS1500 is not set 38# CONFIG_MIPS_XXS1500 is not set
43# CONFIG_PNX8550_JBS is not set 39# CONFIG_PNX8550_JBS is not set
diff --git a/arch/mips/configs/db1200_defconfig b/arch/mips/configs/db1200_defconfig
index 820659e810dc..6d400befbacc 100644
--- a/arch/mips/configs/db1200_defconfig
+++ b/arch/mips/configs/db1200_defconfig
@@ -26,9 +26,7 @@ CONFIG_MIPS_DB1200=y
26# CONFIG_BASLER_EXCITE is not set 26# CONFIG_BASLER_EXCITE is not set
27# CONFIG_MIPS_COBALT is not set 27# CONFIG_MIPS_COBALT is not set
28# CONFIG_MACH_DECSTATION is not set 28# CONFIG_MACH_DECSTATION is not set
29# CONFIG_MIPS_EV64120 is not set
30# CONFIG_MACH_JAZZ is not set 29# CONFIG_MACH_JAZZ is not set
31# CONFIG_LASAT is not set
32# CONFIG_MIPS_ATLAS is not set 30# CONFIG_MIPS_ATLAS is not set
33# CONFIG_MIPS_MALTA is not set 31# CONFIG_MIPS_MALTA is not set
34# CONFIG_MIPS_SEAD is not set 32# CONFIG_MIPS_SEAD is not set
@@ -36,8 +34,6 @@ CONFIG_MIPS_DB1200=y
36# CONFIG_MIPS_SIM is not set 34# CONFIG_MIPS_SIM is not set
37# CONFIG_MOMENCO_JAGUAR_ATX is not set 35# CONFIG_MOMENCO_JAGUAR_ATX is not set
38# CONFIG_MOMENCO_OCELOT is not set 36# CONFIG_MOMENCO_OCELOT is not set
39# CONFIG_MOMENCO_OCELOT_3 is not set
40# CONFIG_MOMENCO_OCELOT_C is not set
41# CONFIG_MOMENCO_OCELOT_G is not set 37# CONFIG_MOMENCO_OCELOT_G is not set
42# CONFIG_MIPS_XXS1500 is not set 38# CONFIG_MIPS_XXS1500 is not set
43# CONFIG_PNX8550_JBS is not set 39# CONFIG_PNX8550_JBS is not set
diff --git a/arch/mips/configs/db1500_defconfig b/arch/mips/configs/db1500_defconfig
index 4050b9b91bcb..82aea6e08823 100644
--- a/arch/mips/configs/db1500_defconfig
+++ b/arch/mips/configs/db1500_defconfig
@@ -26,9 +26,7 @@ CONFIG_MIPS_DB1500=y
26# CONFIG_BASLER_EXCITE is not set 26# CONFIG_BASLER_EXCITE is not set
27# CONFIG_MIPS_COBALT is not set 27# CONFIG_MIPS_COBALT is not set
28# CONFIG_MACH_DECSTATION is not set 28# CONFIG_MACH_DECSTATION is not set
29# CONFIG_MIPS_EV64120 is not set
30# CONFIG_MACH_JAZZ is not set 29# CONFIG_MACH_JAZZ is not set
31# CONFIG_LASAT is not set
32# CONFIG_MIPS_ATLAS is not set 30# CONFIG_MIPS_ATLAS is not set
33# CONFIG_MIPS_MALTA is not set 31# CONFIG_MIPS_MALTA is not set
34# CONFIG_MIPS_SEAD is not set 32# CONFIG_MIPS_SEAD is not set
@@ -36,8 +34,6 @@ CONFIG_MIPS_DB1500=y
36# CONFIG_MIPS_SIM is not set 34# CONFIG_MIPS_SIM is not set
37# CONFIG_MOMENCO_JAGUAR_ATX is not set 35# CONFIG_MOMENCO_JAGUAR_ATX is not set
38# CONFIG_MOMENCO_OCELOT is not set 36# CONFIG_MOMENCO_OCELOT is not set
39# CONFIG_MOMENCO_OCELOT_3 is not set
40# CONFIG_MOMENCO_OCELOT_C is not set
41# CONFIG_MOMENCO_OCELOT_G is not set 37# CONFIG_MOMENCO_OCELOT_G is not set
42# CONFIG_MIPS_XXS1500 is not set 38# CONFIG_MIPS_XXS1500 is not set
43# CONFIG_PNX8550_JBS is not set 39# CONFIG_PNX8550_JBS is not set
diff --git a/arch/mips/configs/db1550_defconfig b/arch/mips/configs/db1550_defconfig
index 7b3519058ab8..82697714a9e3 100644
--- a/arch/mips/configs/db1550_defconfig
+++ b/arch/mips/configs/db1550_defconfig
@@ -26,9 +26,7 @@ CONFIG_MIPS_DB1550=y
26# CONFIG_BASLER_EXCITE is not set 26# CONFIG_BASLER_EXCITE is not set
27# CONFIG_MIPS_COBALT is not set 27# CONFIG_MIPS_COBALT is not set
28# CONFIG_MACH_DECSTATION is not set 28# CONFIG_MACH_DECSTATION is not set
29# CONFIG_MIPS_EV64120 is not set
30# CONFIG_MACH_JAZZ is not set 29# CONFIG_MACH_JAZZ is not set
31# CONFIG_LASAT is not set
32# CONFIG_MIPS_ATLAS is not set 30# CONFIG_MIPS_ATLAS is not set
33# CONFIG_MIPS_MALTA is not set 31# CONFIG_MIPS_MALTA is not set
34# CONFIG_MIPS_SEAD is not set 32# CONFIG_MIPS_SEAD is not set
@@ -36,8 +34,6 @@ CONFIG_MIPS_DB1550=y
36# CONFIG_MIPS_SIM is not set 34# CONFIG_MIPS_SIM is not set
37# CONFIG_MOMENCO_JAGUAR_ATX is not set 35# CONFIG_MOMENCO_JAGUAR_ATX is not set
38# CONFIG_MOMENCO_OCELOT is not set 36# CONFIG_MOMENCO_OCELOT is not set
39# CONFIG_MOMENCO_OCELOT_3 is not set
40# CONFIG_MOMENCO_OCELOT_C is not set
41# CONFIG_MOMENCO_OCELOT_G is not set 37# CONFIG_MOMENCO_OCELOT_G is not set
42# CONFIG_MIPS_XXS1500 is not set 38# CONFIG_MIPS_XXS1500 is not set
43# CONFIG_PNX8550_JBS is not set 39# CONFIG_PNX8550_JBS is not set
diff --git a/arch/mips/configs/ddb5477_defconfig b/arch/mips/configs/ddb5477_defconfig
index 5b502a2013fb..a42ab9ae7d4b 100644
--- a/arch/mips/configs/ddb5477_defconfig
+++ b/arch/mips/configs/ddb5477_defconfig
@@ -25,9 +25,7 @@ CONFIG_ZONE_DMA=y
25# CONFIG_BASLER_EXCITE is not set 25# CONFIG_BASLER_EXCITE is not set
26# CONFIG_MIPS_COBALT is not set 26# CONFIG_MIPS_COBALT is not set
27# CONFIG_MACH_DECSTATION is not set 27# CONFIG_MACH_DECSTATION is not set
28# CONFIG_MIPS_EV64120 is not set
29# CONFIG_MACH_JAZZ is not set 28# CONFIG_MACH_JAZZ is not set
30# CONFIG_LASAT is not set
31# CONFIG_MIPS_ATLAS is not set 29# CONFIG_MIPS_ATLAS is not set
32# CONFIG_MIPS_MALTA is not set 30# CONFIG_MIPS_MALTA is not set
33# CONFIG_MIPS_SEAD is not set 31# CONFIG_MIPS_SEAD is not set
@@ -35,8 +33,6 @@ CONFIG_ZONE_DMA=y
35# CONFIG_MIPS_SIM is not set 33# CONFIG_MIPS_SIM is not set
36# CONFIG_MOMENCO_JAGUAR_ATX is not set 34# CONFIG_MOMENCO_JAGUAR_ATX is not set
37# CONFIG_MOMENCO_OCELOT is not set 35# CONFIG_MOMENCO_OCELOT is not set
38# CONFIG_MOMENCO_OCELOT_3 is not set
39# CONFIG_MOMENCO_OCELOT_C is not set
40# CONFIG_MOMENCO_OCELOT_G is not set 36# CONFIG_MOMENCO_OCELOT_G is not set
41# CONFIG_MIPS_XXS1500 is not set 37# CONFIG_MIPS_XXS1500 is not set
42# CONFIG_PNX8550_JBS is not set 38# CONFIG_PNX8550_JBS is not set
diff --git a/arch/mips/configs/decstation_defconfig b/arch/mips/configs/decstation_defconfig
index 4bbdab078ff1..d6e3fffbc80d 100644
--- a/arch/mips/configs/decstation_defconfig
+++ b/arch/mips/configs/decstation_defconfig
@@ -25,9 +25,7 @@ CONFIG_ZONE_DMA=y
25# CONFIG_BASLER_EXCITE is not set 25# CONFIG_BASLER_EXCITE is not set
26# CONFIG_MIPS_COBALT is not set 26# CONFIG_MIPS_COBALT is not set
27CONFIG_MACH_DECSTATION=y 27CONFIG_MACH_DECSTATION=y
28# CONFIG_MIPS_EV64120 is not set
29# CONFIG_MACH_JAZZ is not set 28# CONFIG_MACH_JAZZ is not set
30# CONFIG_LASAT is not set
31# CONFIG_MIPS_ATLAS is not set 29# CONFIG_MIPS_ATLAS is not set
32# CONFIG_MIPS_MALTA is not set 30# CONFIG_MIPS_MALTA is not set
33# CONFIG_MIPS_SEAD is not set 31# CONFIG_MIPS_SEAD is not set
@@ -35,8 +33,6 @@ CONFIG_MACH_DECSTATION=y
35# CONFIG_MIPS_SIM is not set 33# CONFIG_MIPS_SIM is not set
36# CONFIG_MOMENCO_JAGUAR_ATX is not set 34# CONFIG_MOMENCO_JAGUAR_ATX is not set
37# CONFIG_MOMENCO_OCELOT is not set 35# CONFIG_MOMENCO_OCELOT is not set
38# CONFIG_MOMENCO_OCELOT_3 is not set
39# CONFIG_MOMENCO_OCELOT_C is not set
40# CONFIG_MOMENCO_OCELOT_G is not set 36# CONFIG_MOMENCO_OCELOT_G is not set
41# CONFIG_MIPS_XXS1500 is not set 37# CONFIG_MIPS_XXS1500 is not set
42# CONFIG_PNX8550_JBS is not set 38# CONFIG_PNX8550_JBS is not set
diff --git a/arch/mips/configs/e55_defconfig b/arch/mips/configs/e55_defconfig
index b5714a6a5398..78f5004fb721 100644
--- a/arch/mips/configs/e55_defconfig
+++ b/arch/mips/configs/e55_defconfig
@@ -25,9 +25,7 @@ CONFIG_ZONE_DMA=y
25# CONFIG_BASLER_EXCITE is not set 25# CONFIG_BASLER_EXCITE is not set
26# CONFIG_MIPS_COBALT is not set 26# CONFIG_MIPS_COBALT is not set
27# CONFIG_MACH_DECSTATION is not set 27# CONFIG_MACH_DECSTATION is not set
28# CONFIG_MIPS_EV64120 is not set
29# CONFIG_MACH_JAZZ is not set 28# CONFIG_MACH_JAZZ is not set
30# CONFIG_LASAT is not set
31# CONFIG_MIPS_ATLAS is not set 29# CONFIG_MIPS_ATLAS is not set
32# CONFIG_MIPS_MALTA is not set 30# CONFIG_MIPS_MALTA is not set
33# CONFIG_MIPS_SEAD is not set 31# CONFIG_MIPS_SEAD is not set
@@ -35,8 +33,6 @@ CONFIG_ZONE_DMA=y
35# CONFIG_MIPS_SIM is not set 33# CONFIG_MIPS_SIM is not set
36# CONFIG_MOMENCO_JAGUAR_ATX is not set 34# CONFIG_MOMENCO_JAGUAR_ATX is not set
37# CONFIG_MOMENCO_OCELOT is not set 35# CONFIG_MOMENCO_OCELOT is not set
38# CONFIG_MOMENCO_OCELOT_3 is not set
39# CONFIG_MOMENCO_OCELOT_C is not set
40# CONFIG_MOMENCO_OCELOT_G is not set 36# CONFIG_MOMENCO_OCELOT_G is not set
41# CONFIG_MIPS_XXS1500 is not set 37# CONFIG_MIPS_XXS1500 is not set
42# CONFIG_PNX8550_JBS is not set 38# CONFIG_PNX8550_JBS is not set
diff --git a/arch/mips/configs/emma2rh_defconfig b/arch/mips/configs/emma2rh_defconfig
index 2e3e155b4c55..b29bff0f56c3 100644
--- a/arch/mips/configs/emma2rh_defconfig
+++ b/arch/mips/configs/emma2rh_defconfig
@@ -25,9 +25,7 @@ CONFIG_ZONE_DMA=y
25# CONFIG_BASLER_EXCITE is not set 25# CONFIG_BASLER_EXCITE is not set
26# CONFIG_MIPS_COBALT is not set 26# CONFIG_MIPS_COBALT is not set
27# CONFIG_MACH_DECSTATION is not set 27# CONFIG_MACH_DECSTATION is not set
28# CONFIG_MIPS_EV64120 is not set
29# CONFIG_MACH_JAZZ is not set 28# CONFIG_MACH_JAZZ is not set
30# CONFIG_LASAT is not set
31# CONFIG_MIPS_ATLAS is not set 29# CONFIG_MIPS_ATLAS is not set
32# CONFIG_MIPS_MALTA is not set 30# CONFIG_MIPS_MALTA is not set
33# CONFIG_MIPS_SEAD is not set 31# CONFIG_MIPS_SEAD is not set
@@ -35,8 +33,6 @@ CONFIG_ZONE_DMA=y
35# CONFIG_MIPS_SIM is not set 33# CONFIG_MIPS_SIM is not set
36# CONFIG_MOMENCO_JAGUAR_ATX is not set 34# CONFIG_MOMENCO_JAGUAR_ATX is not set
37# CONFIG_MOMENCO_OCELOT is not set 35# CONFIG_MOMENCO_OCELOT is not set
38# CONFIG_MOMENCO_OCELOT_3 is not set
39# CONFIG_MOMENCO_OCELOT_C is not set
40# CONFIG_MOMENCO_OCELOT_G is not set 36# CONFIG_MOMENCO_OCELOT_G is not set
41# CONFIG_MIPS_XXS1500 is not set 37# CONFIG_MIPS_XXS1500 is not set
42# CONFIG_PNX8550_JBS is not set 38# CONFIG_PNX8550_JBS is not set
diff --git a/arch/mips/configs/ev64120_defconfig b/arch/mips/configs/ev64120_defconfig
deleted file mode 100644
index c10e4e063226..000000000000
--- a/arch/mips/configs/ev64120_defconfig
+++ /dev/null
@@ -1,985 +0,0 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.20
4# Tue Feb 20 21:47:30 2007
5#
6CONFIG_MIPS=y
7
8#
9# Machine selection
10#
11CONFIG_ZONE_DMA=y
12# CONFIG_MIPS_MTX1 is not set
13# CONFIG_MIPS_BOSPORUS is not set
14# CONFIG_MIPS_PB1000 is not set
15# CONFIG_MIPS_PB1100 is not set
16# CONFIG_MIPS_PB1500 is not set
17# CONFIG_MIPS_PB1550 is not set
18# CONFIG_MIPS_PB1200 is not set
19# CONFIG_MIPS_DB1000 is not set
20# CONFIG_MIPS_DB1100 is not set
21# CONFIG_MIPS_DB1500 is not set
22# CONFIG_MIPS_DB1550 is not set
23# CONFIG_MIPS_DB1200 is not set
24# CONFIG_MIPS_MIRAGE is not set
25# CONFIG_BASLER_EXCITE is not set
26# CONFIG_MIPS_COBALT is not set
27# CONFIG_MACH_DECSTATION is not set
28CONFIG_MIPS_EV64120=y
29# CONFIG_MACH_JAZZ is not set
30# CONFIG_LASAT is not set
31# CONFIG_MIPS_ATLAS is not set
32# CONFIG_MIPS_MALTA is not set
33# CONFIG_MIPS_SEAD is not set
34# CONFIG_WR_PPMC is not set
35# CONFIG_MIPS_SIM is not set
36# CONFIG_MOMENCO_JAGUAR_ATX is not set
37# CONFIG_MOMENCO_OCELOT is not set
38# CONFIG_MOMENCO_OCELOT_3 is not set
39# CONFIG_MOMENCO_OCELOT_C is not set
40# CONFIG_MOMENCO_OCELOT_G is not set
41# CONFIG_MIPS_XXS1500 is not set
42# CONFIG_PNX8550_JBS is not set
43# CONFIG_PNX8550_STB810 is not set
44# CONFIG_DDB5477 is not set
45# CONFIG_MACH_VR41XX is not set
46# CONFIG_PMC_YOSEMITE is not set
47# CONFIG_QEMU is not set
48# CONFIG_MARKEINS is not set
49# CONFIG_SGI_IP22 is not set
50# CONFIG_SGI_IP27 is not set
51# CONFIG_SGI_IP32 is not set
52# CONFIG_SIBYTE_BIGSUR is not set
53# CONFIG_SIBYTE_SWARM is not set
54# CONFIG_SIBYTE_SENTOSA is not set
55# CONFIG_SIBYTE_RHONE is not set
56# CONFIG_SIBYTE_CARMEL is not set
57# CONFIG_SIBYTE_PTSWARM is not set
58# CONFIG_SIBYTE_LITTLESUR is not set
59# CONFIG_SIBYTE_CRHINE is not set
60# CONFIG_SIBYTE_CRHONE is not set
61# CONFIG_SNI_RM is not set
62# CONFIG_TOSHIBA_JMR3927 is not set
63# CONFIG_TOSHIBA_RBTX4927 is not set
64# CONFIG_TOSHIBA_RBTX4938 is not set
65# CONFIG_EVB_PCI1 is not set
66CONFIG_RWSEM_GENERIC_SPINLOCK=y
67# CONFIG_ARCH_HAS_ILOG2_U32 is not set
68# CONFIG_ARCH_HAS_ILOG2_U64 is not set
69CONFIG_GENERIC_FIND_NEXT_BIT=y
70CONFIG_GENERIC_HWEIGHT=y
71CONFIG_GENERIC_CALIBRATE_DELAY=y
72CONFIG_GENERIC_TIME=y
73CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
74# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set
75CONFIG_DMA_NONCOHERENT=y
76CONFIG_DMA_NEED_PCI_MAP_STATE=y
77CONFIG_CPU_BIG_ENDIAN=y
78# CONFIG_CPU_LITTLE_ENDIAN is not set
79CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
80CONFIG_MIPS_GT64120=y
81# CONFIG_SYSCLK_75 is not set
82# CONFIG_SYSCLK_83 is not set
83CONFIG_SYSCLK_100=y
84CONFIG_MIPS_L1_CACHE_SHIFT=5
85
86#
87# CPU selection
88#
89# CONFIG_CPU_MIPS32_R1 is not set
90# CONFIG_CPU_MIPS32_R2 is not set
91# CONFIG_CPU_MIPS64_R1 is not set
92# CONFIG_CPU_MIPS64_R2 is not set
93# CONFIG_CPU_R3000 is not set
94# CONFIG_CPU_TX39XX is not set
95# CONFIG_CPU_VR41XX is not set
96# CONFIG_CPU_R4300 is not set
97# CONFIG_CPU_R4X00 is not set
98# CONFIG_CPU_TX49XX is not set
99CONFIG_CPU_R5000=y
100# CONFIG_CPU_R5432 is not set
101# CONFIG_CPU_R6000 is not set
102# CONFIG_CPU_NEVADA is not set
103# CONFIG_CPU_R8000 is not set
104# CONFIG_CPU_R10000 is not set
105# CONFIG_CPU_RM7000 is not set
106# CONFIG_CPU_RM9000 is not set
107# CONFIG_CPU_SB1 is not set
108CONFIG_SYS_HAS_CPU_R5000=y
109CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
110CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
111CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
112CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
113
114#
115# Kernel type
116#
117CONFIG_32BIT=y
118# CONFIG_64BIT is not set
119CONFIG_PAGE_SIZE_4KB=y
120# CONFIG_PAGE_SIZE_8KB is not set
121# CONFIG_PAGE_SIZE_16KB is not set
122# CONFIG_PAGE_SIZE_64KB is not set
123CONFIG_MIPS_MT_DISABLED=y
124# CONFIG_MIPS_MT_SMP is not set
125# CONFIG_MIPS_MT_SMTC is not set
126# CONFIG_MIPS_VPE_LOADER is not set
127# CONFIG_64BIT_PHYS_ADDR is not set
128CONFIG_CPU_HAS_LLSC=y
129CONFIG_CPU_HAS_SYNC=y
130CONFIG_GENERIC_HARDIRQS=y
131CONFIG_GENERIC_IRQ_PROBE=y
132CONFIG_ARCH_FLATMEM_ENABLE=y
133CONFIG_SELECT_MEMORY_MODEL=y
134CONFIG_FLATMEM_MANUAL=y
135# CONFIG_DISCONTIGMEM_MANUAL is not set
136# CONFIG_SPARSEMEM_MANUAL is not set
137CONFIG_FLATMEM=y
138CONFIG_FLAT_NODE_MEM_MAP=y
139# CONFIG_SPARSEMEM_STATIC is not set
140CONFIG_SPLIT_PTLOCK_CPUS=4
141# CONFIG_RESOURCES_64BIT is not set
142CONFIG_ZONE_DMA_FLAG=1
143# CONFIG_HZ_48 is not set
144# CONFIG_HZ_100 is not set
145# CONFIG_HZ_128 is not set
146# CONFIG_HZ_250 is not set
147# CONFIG_HZ_256 is not set
148CONFIG_HZ_1000=y
149# CONFIG_HZ_1024 is not set
150CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
151CONFIG_HZ=1000
152CONFIG_PREEMPT_NONE=y
153# CONFIG_PREEMPT_VOLUNTARY is not set
154# CONFIG_PREEMPT is not set
155# CONFIG_KEXEC is not set
156CONFIG_LOCKDEP_SUPPORT=y
157CONFIG_STACKTRACE_SUPPORT=y
158CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
159
160#
161# Code maturity level options
162#
163CONFIG_EXPERIMENTAL=y
164CONFIG_BROKEN_ON_SMP=y
165CONFIG_INIT_ENV_ARG_LIMIT=32
166
167#
168# General setup
169#
170CONFIG_LOCALVERSION=""
171CONFIG_LOCALVERSION_AUTO=y
172CONFIG_SWAP=y
173CONFIG_SYSVIPC=y
174# CONFIG_IPC_NS is not set
175CONFIG_SYSVIPC_SYSCTL=y
176# CONFIG_POSIX_MQUEUE is not set
177# CONFIG_BSD_PROCESS_ACCT is not set
178# CONFIG_TASKSTATS is not set
179# CONFIG_UTS_NS is not set
180# CONFIG_AUDIT is not set
181# CONFIG_IKCONFIG is not set
182CONFIG_SYSFS_DEPRECATED=y
183CONFIG_RELAY=y
184# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
185CONFIG_SYSCTL=y
186CONFIG_EMBEDDED=y
187CONFIG_SYSCTL_SYSCALL=y
188CONFIG_KALLSYMS=y
189# CONFIG_KALLSYMS_EXTRA_PASS is not set
190CONFIG_HOTPLUG=y
191CONFIG_PRINTK=y
192CONFIG_BUG=y
193CONFIG_ELF_CORE=y
194CONFIG_BASE_FULL=y
195CONFIG_FUTEX=y
196CONFIG_EPOLL=y
197CONFIG_SHMEM=y
198CONFIG_SLAB=y
199CONFIG_VM_EVENT_COUNTERS=y
200CONFIG_RT_MUTEXES=y
201# CONFIG_TINY_SHMEM is not set
202CONFIG_BASE_SMALL=0
203# CONFIG_SLOB is not set
204
205#
206# Loadable module support
207#
208CONFIG_MODULES=y
209CONFIG_MODULE_UNLOAD=y
210# CONFIG_MODULE_FORCE_UNLOAD is not set
211CONFIG_MODVERSIONS=y
212CONFIG_MODULE_SRCVERSION_ALL=y
213# CONFIG_KMOD is not set
214
215#
216# Block layer
217#
218CONFIG_BLOCK=y
219# CONFIG_LBD is not set
220# CONFIG_BLK_DEV_IO_TRACE is not set
221# CONFIG_LSF is not set
222
223#
224# IO Schedulers
225#
226CONFIG_IOSCHED_NOOP=y
227CONFIG_IOSCHED_AS=y
228CONFIG_IOSCHED_DEADLINE=y
229CONFIG_IOSCHED_CFQ=y
230CONFIG_DEFAULT_AS=y
231# CONFIG_DEFAULT_DEADLINE is not set
232# CONFIG_DEFAULT_CFQ is not set
233# CONFIG_DEFAULT_NOOP is not set
234CONFIG_DEFAULT_IOSCHED="anticipatory"
235
236#
237# Bus options (PCI, PCMCIA, EISA, ISA, TC)
238#
239CONFIG_HW_HAS_PCI=y
240CONFIG_PCI=y
241CONFIG_MMU=y
242
243#
244# PCCARD (PCMCIA/CardBus) support
245#
246# CONFIG_PCCARD is not set
247
248#
249# PCI Hotplug Support
250#
251# CONFIG_HOTPLUG_PCI is not set
252
253#
254# Executable file formats
255#
256CONFIG_BINFMT_ELF=y
257# CONFIG_BINFMT_MISC is not set
258CONFIG_TRAD_SIGNALS=y
259
260#
261# Power management options
262#
263CONFIG_PM=y
264# CONFIG_PM_LEGACY is not set
265# CONFIG_PM_DEBUG is not set
266# CONFIG_PM_SYSFS_DEPRECATED is not set
267
268#
269# Networking
270#
271CONFIG_NET=y
272
273#
274# Networking options
275#
276# CONFIG_NETDEBUG is not set
277# CONFIG_PACKET is not set
278CONFIG_UNIX=y
279CONFIG_XFRM=y
280CONFIG_XFRM_USER=m
281# CONFIG_XFRM_SUB_POLICY is not set
282CONFIG_XFRM_MIGRATE=y
283CONFIG_NET_KEY=y
284CONFIG_NET_KEY_MIGRATE=y
285CONFIG_INET=y
286# CONFIG_IP_MULTICAST is not set
287# CONFIG_IP_ADVANCED_ROUTER is not set
288CONFIG_IP_FIB_HASH=y
289CONFIG_IP_PNP=y
290# CONFIG_IP_PNP_DHCP is not set
291# CONFIG_IP_PNP_BOOTP is not set
292# CONFIG_IP_PNP_RARP is not set
293# CONFIG_NET_IPIP is not set
294# CONFIG_NET_IPGRE is not set
295# CONFIG_ARPD is not set
296# CONFIG_SYN_COOKIES is not set
297# CONFIG_INET_AH is not set
298# CONFIG_INET_ESP is not set
299# CONFIG_INET_IPCOMP is not set
300# CONFIG_INET_XFRM_TUNNEL is not set
301# CONFIG_INET_TUNNEL is not set
302CONFIG_INET_XFRM_MODE_TRANSPORT=m
303CONFIG_INET_XFRM_MODE_TUNNEL=m
304CONFIG_INET_XFRM_MODE_BEET=m
305CONFIG_INET_DIAG=y
306CONFIG_INET_TCP_DIAG=y
307# CONFIG_TCP_CONG_ADVANCED is not set
308CONFIG_TCP_CONG_CUBIC=y
309CONFIG_DEFAULT_TCP_CONG="cubic"
310CONFIG_TCP_MD5SIG=y
311# CONFIG_IPV6 is not set
312# CONFIG_INET6_XFRM_TUNNEL is not set
313# CONFIG_INET6_TUNNEL is not set
314CONFIG_NETWORK_SECMARK=y
315# CONFIG_NETFILTER is not set
316
317#
318# DCCP Configuration (EXPERIMENTAL)
319#
320# CONFIG_IP_DCCP is not set
321
322#
323# SCTP Configuration (EXPERIMENTAL)
324#
325# CONFIG_IP_SCTP is not set
326
327#
328# TIPC Configuration (EXPERIMENTAL)
329#
330# CONFIG_TIPC is not set
331# CONFIG_ATM is not set
332# CONFIG_BRIDGE is not set
333# CONFIG_VLAN_8021Q is not set
334# CONFIG_DECNET is not set
335# CONFIG_LLC2 is not set
336# CONFIG_IPX is not set
337# CONFIG_ATALK is not set
338# CONFIG_X25 is not set
339# CONFIG_LAPB is not set
340# CONFIG_ECONET is not set
341# CONFIG_WAN_ROUTER is not set
342
343#
344# QoS and/or fair queueing
345#
346# CONFIG_NET_SCHED is not set
347
348#
349# Network testing
350#
351# CONFIG_NET_PKTGEN is not set
352# CONFIG_HAMRADIO is not set
353# CONFIG_IRDA is not set
354# CONFIG_BT is not set
355CONFIG_IEEE80211=m
356# CONFIG_IEEE80211_DEBUG is not set
357CONFIG_IEEE80211_CRYPT_WEP=m
358CONFIG_IEEE80211_CRYPT_CCMP=m
359CONFIG_IEEE80211_SOFTMAC=m
360# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set
361CONFIG_WIRELESS_EXT=y
362
363#
364# Device Drivers
365#
366
367#
368# Generic Driver Options
369#
370CONFIG_STANDALONE=y
371CONFIG_PREVENT_FIRMWARE_BUILD=y
372CONFIG_FW_LOADER=m
373# CONFIG_SYS_HYPERVISOR is not set
374
375#
376# Connector - unified userspace <-> kernelspace linker
377#
378CONFIG_CONNECTOR=m
379
380#
381# Memory Technology Devices (MTD)
382#
383# CONFIG_MTD is not set
384
385#
386# Parallel port support
387#
388# CONFIG_PARPORT is not set
389
390#
391# Plug and Play support
392#
393# CONFIG_PNPACPI is not set
394
395#
396# Block devices
397#
398# CONFIG_BLK_CPQ_DA is not set
399# CONFIG_BLK_CPQ_CISS_DA is not set
400# CONFIG_BLK_DEV_DAC960 is not set
401# CONFIG_BLK_DEV_UMEM is not set
402# CONFIG_BLK_DEV_COW_COMMON is not set
403# CONFIG_BLK_DEV_LOOP is not set
404# CONFIG_BLK_DEV_NBD is not set
405# CONFIG_BLK_DEV_SX8 is not set
406# CONFIG_BLK_DEV_RAM is not set
407# CONFIG_BLK_DEV_INITRD is not set
408CONFIG_CDROM_PKTCDVD=m
409CONFIG_CDROM_PKTCDVD_BUFFERS=8
410# CONFIG_CDROM_PKTCDVD_WCACHE is not set
411CONFIG_ATA_OVER_ETH=m
412
413#
414# Misc devices
415#
416CONFIG_SGI_IOC4=m
417# CONFIG_TIFM_CORE is not set
418
419#
420# ATA/ATAPI/MFM/RLL support
421#
422# CONFIG_IDE is not set
423
424#
425# SCSI device support
426#
427CONFIG_RAID_ATTRS=m
428# CONFIG_SCSI is not set
429# CONFIG_SCSI_NETLINK is not set
430
431#
432# Serial ATA (prod) and Parallel ATA (experimental) drivers
433#
434# CONFIG_ATA is not set
435
436#
437# Multi-device support (RAID and LVM)
438#
439# CONFIG_MD is not set
440
441#
442# Fusion MPT device support
443#
444# CONFIG_FUSION is not set
445
446#
447# IEEE 1394 (FireWire) support
448#
449# CONFIG_IEEE1394 is not set
450
451#
452# I2O device support
453#
454# CONFIG_I2O is not set
455
456#
457# Network device support
458#
459CONFIG_NETDEVICES=y
460# CONFIG_DUMMY is not set
461# CONFIG_BONDING is not set
462# CONFIG_EQUALIZER is not set
463# CONFIG_TUN is not set
464
465#
466# ARCnet devices
467#
468# CONFIG_ARCNET is not set
469
470#
471# PHY device support
472#
473CONFIG_PHYLIB=m
474
475#
476# MII PHY device drivers
477#
478CONFIG_MARVELL_PHY=m
479CONFIG_DAVICOM_PHY=m
480CONFIG_QSEMI_PHY=m
481CONFIG_LXT_PHY=m
482CONFIG_CICADA_PHY=m
483CONFIG_VITESSE_PHY=m
484CONFIG_SMSC_PHY=m
485# CONFIG_BROADCOM_PHY is not set
486# CONFIG_FIXED_PHY is not set
487
488#
489# Ethernet (10 or 100Mbit)
490#
491CONFIG_NET_ETHERNET=y
492# CONFIG_MII is not set
493# CONFIG_HAPPYMEAL is not set
494# CONFIG_SUNGEM is not set
495# CONFIG_CASSINI is not set
496# CONFIG_NET_VENDOR_3COM is not set
497# CONFIG_DM9000 is not set
498
499#
500# Tulip family network device support
501#
502# CONFIG_NET_TULIP is not set
503# CONFIG_HP100 is not set
504# CONFIG_NET_PCI is not set
505
506#
507# Ethernet (1000 Mbit)
508#
509# CONFIG_ACENIC is not set
510# CONFIG_DL2K is not set
511# CONFIG_E1000 is not set
512# CONFIG_NS83820 is not set
513# CONFIG_HAMACHI is not set
514# CONFIG_YELLOWFIN is not set
515# CONFIG_R8169 is not set
516# CONFIG_SIS190 is not set
517# CONFIG_SKGE is not set
518# CONFIG_SKY2 is not set
519# CONFIG_SK98LIN is not set
520# CONFIG_TIGON3 is not set
521# CONFIG_BNX2 is not set
522CONFIG_QLA3XXX=m
523# CONFIG_ATL1 is not set
524
525#
526# Ethernet (10000 Mbit)
527#
528# CONFIG_CHELSIO_T1 is not set
529CONFIG_CHELSIO_T3=m
530# CONFIG_IXGB is not set
531# CONFIG_S2IO is not set
532# CONFIG_MYRI10GE is not set
533CONFIG_NETXEN_NIC=m
534
535#
536# Token Ring devices
537#
538# CONFIG_TR is not set
539
540#
541# Wireless LAN (non-hamradio)
542#
543# CONFIG_NET_RADIO is not set
544
545#
546# Wan interfaces
547#
548# CONFIG_WAN is not set
549# CONFIG_FDDI is not set
550# CONFIG_HIPPI is not set
551CONFIG_PPP=y
552# CONFIG_PPP_MULTILINK is not set
553# CONFIG_PPP_FILTER is not set
554CONFIG_PPP_ASYNC=y
555# CONFIG_PPP_SYNC_TTY is not set
556# CONFIG_PPP_DEFLATE is not set
557# CONFIG_PPP_BSDCOMP is not set
558CONFIG_PPP_MPPE=m
559# CONFIG_PPPOE is not set
560# CONFIG_SLIP is not set
561CONFIG_SLHC=y
562# CONFIG_SHAPER is not set
563# CONFIG_NETCONSOLE is not set
564# CONFIG_NETPOLL is not set
565# CONFIG_NET_POLL_CONTROLLER is not set
566
567#
568# ISDN subsystem
569#
570# CONFIG_ISDN is not set
571
572#
573# Telephony Support
574#
575# CONFIG_PHONE is not set
576
577#
578# Input device support
579#
580CONFIG_INPUT=y
581# CONFIG_INPUT_FF_MEMLESS is not set
582
583#
584# Userland interfaces
585#
586CONFIG_INPUT_MOUSEDEV=y
587CONFIG_INPUT_MOUSEDEV_PSAUX=y
588CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
589CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
590# CONFIG_INPUT_JOYDEV is not set
591# CONFIG_INPUT_TSDEV is not set
592# CONFIG_INPUT_EVDEV is not set
593# CONFIG_INPUT_EVBUG is not set
594
595#
596# Input Device Drivers
597#
598# CONFIG_INPUT_KEYBOARD is not set
599# CONFIG_INPUT_MOUSE is not set
600# CONFIG_INPUT_JOYSTICK is not set
601# CONFIG_INPUT_TOUCHSCREEN is not set
602# CONFIG_INPUT_MISC is not set
603
604#
605# Hardware I/O ports
606#
607CONFIG_SERIO=y
608# CONFIG_SERIO_I8042 is not set
609CONFIG_SERIO_SERPORT=y
610# CONFIG_SERIO_PCIPS2 is not set
611# CONFIG_SERIO_LIBPS2 is not set
612CONFIG_SERIO_RAW=m
613# CONFIG_GAMEPORT is not set
614
615#
616# Character devices
617#
618CONFIG_VT=y
619CONFIG_VT_CONSOLE=y
620CONFIG_HW_CONSOLE=y
621CONFIG_VT_HW_CONSOLE_BINDING=y
622# CONFIG_SERIAL_NONSTANDARD is not set
623
624#
625# Serial drivers
626#
627CONFIG_SERIAL_8250=y
628CONFIG_SERIAL_8250_CONSOLE=y
629CONFIG_SERIAL_8250_PCI=y
630CONFIG_SERIAL_8250_NR_UARTS=4
631CONFIG_SERIAL_8250_RUNTIME_UARTS=4
632# CONFIG_SERIAL_8250_EXTENDED is not set
633
634#
635# Non-8250 serial port support
636#
637CONFIG_SERIAL_CORE=y
638CONFIG_SERIAL_CORE_CONSOLE=y
639# CONFIG_SERIAL_JSM is not set
640CONFIG_UNIX98_PTYS=y
641CONFIG_LEGACY_PTYS=y
642CONFIG_LEGACY_PTY_COUNT=256
643
644#
645# IPMI
646#
647# CONFIG_IPMI_HANDLER is not set
648
649#
650# Watchdog Cards
651#
652# CONFIG_WATCHDOG is not set
653# CONFIG_HW_RANDOM is not set
654# CONFIG_RTC is not set
655# CONFIG_GEN_RTC is not set
656# CONFIG_DTLK is not set
657# CONFIG_R3964 is not set
658# CONFIG_APPLICOM is not set
659# CONFIG_DRM is not set
660# CONFIG_RAW_DRIVER is not set
661
662#
663# TPM devices
664#
665# CONFIG_TCG_TPM is not set
666
667#
668# I2C support
669#
670# CONFIG_I2C is not set
671
672#
673# SPI support
674#
675# CONFIG_SPI is not set
676# CONFIG_SPI_MASTER is not set
677
678#
679# Dallas's 1-wire bus
680#
681# CONFIG_W1 is not set
682
683#
684# Hardware Monitoring support
685#
686# CONFIG_HWMON is not set
687# CONFIG_HWMON_VID is not set
688
689#
690# Multimedia devices
691#
692# CONFIG_VIDEO_DEV is not set
693
694#
695# Digital Video Broadcasting Devices
696#
697# CONFIG_DVB is not set
698
699#
700# Graphics support
701#
702# CONFIG_FIRMWARE_EDID is not set
703# CONFIG_FB is not set
704
705#
706# Console display driver support
707#
708# CONFIG_VGA_CONSOLE is not set
709CONFIG_DUMMY_CONSOLE=y
710# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
711
712#
713# Sound
714#
715# CONFIG_SOUND is not set
716
717#
718# HID Devices
719#
720# CONFIG_HID is not set
721
722#
723# USB support
724#
725CONFIG_USB_ARCH_HAS_HCD=y
726CONFIG_USB_ARCH_HAS_OHCI=y
727CONFIG_USB_ARCH_HAS_EHCI=y
728# CONFIG_USB is not set
729
730#
731# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
732#
733
734#
735# USB Gadget Support
736#
737# CONFIG_USB_GADGET is not set
738
739#
740# MMC/SD Card support
741#
742# CONFIG_MMC is not set
743
744#
745# LED devices
746#
747# CONFIG_NEW_LEDS is not set
748
749#
750# LED drivers
751#
752
753#
754# LED Triggers
755#
756
757#
758# InfiniBand support
759#
760# CONFIG_INFINIBAND is not set
761
762#
763# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
764#
765
766#
767# Real Time Clock
768#
769# CONFIG_RTC_CLASS is not set
770
771#
772# DMA Engine support
773#
774# CONFIG_DMA_ENGINE is not set
775
776#
777# DMA Clients
778#
779
780#
781# DMA Devices
782#
783
784#
785# Auxiliary Display support
786#
787
788#
789# Virtualization
790#
791
792#
793# File systems
794#
795CONFIG_EXT2_FS=y
796# CONFIG_EXT2_FS_XATTR is not set
797# CONFIG_EXT2_FS_XIP is not set
798# CONFIG_EXT3_FS is not set
799# CONFIG_EXT4DEV_FS is not set
800# CONFIG_REISERFS_FS is not set
801# CONFIG_JFS_FS is not set
802# CONFIG_FS_POSIX_ACL is not set
803# CONFIG_XFS_FS is not set
804# CONFIG_GFS2_FS is not set
805# CONFIG_OCFS2_FS is not set
806# CONFIG_MINIX_FS is not set
807# CONFIG_ROMFS_FS is not set
808CONFIG_INOTIFY=y
809CONFIG_INOTIFY_USER=y
810# CONFIG_QUOTA is not set
811CONFIG_DNOTIFY=y
812# CONFIG_AUTOFS_FS is not set
813# CONFIG_AUTOFS4_FS is not set
814CONFIG_FUSE_FS=m
815
816#
817# CD-ROM/DVD Filesystems
818#
819# CONFIG_ISO9660_FS is not set
820# CONFIG_UDF_FS is not set
821
822#
823# DOS/FAT/NT Filesystems
824#
825# CONFIG_MSDOS_FS is not set
826# CONFIG_VFAT_FS is not set
827# CONFIG_NTFS_FS is not set
828
829#
830# Pseudo filesystems
831#
832CONFIG_PROC_FS=y
833CONFIG_PROC_KCORE=y
834CONFIG_PROC_SYSCTL=y
835CONFIG_SYSFS=y
836# CONFIG_TMPFS is not set
837# CONFIG_HUGETLB_PAGE is not set
838CONFIG_RAMFS=y
839CONFIG_CONFIGFS_FS=m
840
841#
842# Miscellaneous filesystems
843#
844# CONFIG_ADFS_FS is not set
845# CONFIG_AFFS_FS is not set
846# CONFIG_ECRYPT_FS is not set
847# CONFIG_HFS_FS is not set
848# CONFIG_HFSPLUS_FS is not set
849# CONFIG_BEFS_FS is not set
850# CONFIG_BFS_FS is not set
851# CONFIG_EFS_FS is not set
852# CONFIG_CRAMFS is not set
853# CONFIG_VXFS_FS is not set
854# CONFIG_HPFS_FS is not set
855# CONFIG_QNX4FS_FS is not set
856# CONFIG_SYSV_FS is not set
857# CONFIG_UFS_FS is not set
858
859#
860# Network File Systems
861#
862CONFIG_NFS_FS=y
863# CONFIG_NFS_V3 is not set
864# CONFIG_NFS_V4 is not set
865# CONFIG_NFS_DIRECTIO is not set
866# CONFIG_NFSD is not set
867CONFIG_ROOT_NFS=y
868CONFIG_LOCKD=y
869CONFIG_NFS_COMMON=y
870CONFIG_SUNRPC=y
871# CONFIG_RPCSEC_GSS_KRB5 is not set
872# CONFIG_RPCSEC_GSS_SPKM3 is not set
873# CONFIG_SMB_FS is not set
874# CONFIG_CIFS is not set
875# CONFIG_NCP_FS is not set
876# CONFIG_CODA_FS is not set
877# CONFIG_AFS_FS is not set
878# CONFIG_9P_FS is not set
879
880#
881# Partition Types
882#
883# CONFIG_PARTITION_ADVANCED is not set
884CONFIG_MSDOS_PARTITION=y
885
886#
887# Native Language Support
888#
889# CONFIG_NLS is not set
890
891#
892# Distributed Lock Manager
893#
894CONFIG_DLM=m
895CONFIG_DLM_TCP=y
896# CONFIG_DLM_SCTP is not set
897# CONFIG_DLM_DEBUG is not set
898
899#
900# Profiling support
901#
902# CONFIG_PROFILING is not set
903
904#
905# Kernel hacking
906#
907CONFIG_TRACE_IRQFLAGS_SUPPORT=y
908# CONFIG_PRINTK_TIME is not set
909CONFIG_ENABLE_MUST_CHECK=y
910# CONFIG_MAGIC_SYSRQ is not set
911# CONFIG_UNUSED_SYMBOLS is not set
912# CONFIG_DEBUG_FS is not set
913# CONFIG_HEADERS_CHECK is not set
914# CONFIG_DEBUG_KERNEL is not set
915CONFIG_LOG_BUF_SHIFT=14
916CONFIG_CROSSCOMPILE=y
917CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs rw nfsroot=192.168.1.1:/mnt/disk2/fs.gal ip=192.168.1.211:192.168.1.1:::gt::"
918CONFIG_SYS_SUPPORTS_KGDB=y
919
920#
921# Security options
922#
923CONFIG_KEYS=y
924CONFIG_KEYS_DEBUG_PROC_KEYS=y
925# CONFIG_SECURITY is not set
926
927#
928# Cryptographic options
929#
930CONFIG_CRYPTO=y
931CONFIG_CRYPTO_ALGAPI=y
932CONFIG_CRYPTO_BLKCIPHER=m
933CONFIG_CRYPTO_HASH=y
934CONFIG_CRYPTO_MANAGER=y
935CONFIG_CRYPTO_HMAC=y
936CONFIG_CRYPTO_XCBC=m
937CONFIG_CRYPTO_NULL=m
938CONFIG_CRYPTO_MD4=m
939CONFIG_CRYPTO_MD5=y
940CONFIG_CRYPTO_SHA1=m
941CONFIG_CRYPTO_SHA256=m
942CONFIG_CRYPTO_SHA512=m
943CONFIG_CRYPTO_WP512=m
944CONFIG_CRYPTO_TGR192=m
945CONFIG_CRYPTO_GF128MUL=m
946CONFIG_CRYPTO_ECB=m
947CONFIG_CRYPTO_CBC=m
948CONFIG_CRYPTO_PCBC=m
949CONFIG_CRYPTO_LRW=m
950CONFIG_CRYPTO_DES=m
951CONFIG_CRYPTO_FCRYPT=m
952CONFIG_CRYPTO_BLOWFISH=m
953CONFIG_CRYPTO_TWOFISH=m
954CONFIG_CRYPTO_TWOFISH_COMMON=m
955CONFIG_CRYPTO_SERPENT=m
956CONFIG_CRYPTO_AES=m
957CONFIG_CRYPTO_CAST5=m
958CONFIG_CRYPTO_CAST6=m
959CONFIG_CRYPTO_TEA=m
960CONFIG_CRYPTO_ARC4=m
961CONFIG_CRYPTO_KHAZAD=m
962CONFIG_CRYPTO_ANUBIS=m
963CONFIG_CRYPTO_DEFLATE=m
964CONFIG_CRYPTO_MICHAEL_MIC=m
965CONFIG_CRYPTO_CRC32C=m
966CONFIG_CRYPTO_CAMELLIA=m
967# CONFIG_CRYPTO_TEST is not set
968
969#
970# Hardware crypto devices
971#
972
973#
974# Library routines
975#
976CONFIG_BITREVERSE=m
977CONFIG_CRC_CCITT=y
978CONFIG_CRC16=m
979CONFIG_CRC32=m
980CONFIG_LIBCRC32C=m
981CONFIG_ZLIB_INFLATE=m
982CONFIG_ZLIB_DEFLATE=m
983CONFIG_PLIST=y
984CONFIG_HAS_IOMEM=y
985CONFIG_HAS_IOPORT=y
diff --git a/arch/mips/configs/excite_defconfig b/arch/mips/configs/excite_defconfig
index 460d7a26a8ba..69810592aa6b 100644
--- a/arch/mips/configs/excite_defconfig
+++ b/arch/mips/configs/excite_defconfig
@@ -26,9 +26,7 @@ CONFIG_BASLER_EXCITE=y
26# CONFIG_BASLER_EXCITE_PROTOTYPE is not set 26# CONFIG_BASLER_EXCITE_PROTOTYPE is not set
27# CONFIG_MIPS_COBALT is not set 27# CONFIG_MIPS_COBALT is not set
28# CONFIG_MACH_DECSTATION is not set 28# CONFIG_MACH_DECSTATION is not set
29# CONFIG_MIPS_EV64120 is not set
30# CONFIG_MACH_JAZZ is not set 29# CONFIG_MACH_JAZZ is not set
31# CONFIG_LASAT is not set
32# CONFIG_MIPS_ATLAS is not set 30# CONFIG_MIPS_ATLAS is not set
33# CONFIG_MIPS_MALTA is not set 31# CONFIG_MIPS_MALTA is not set
34# CONFIG_MIPS_SEAD is not set 32# CONFIG_MIPS_SEAD is not set
@@ -36,8 +34,6 @@ CONFIG_BASLER_EXCITE=y
36# CONFIG_MIPS_SIM is not set 34# CONFIG_MIPS_SIM is not set
37# CONFIG_MOMENCO_JAGUAR_ATX is not set 35# CONFIG_MOMENCO_JAGUAR_ATX is not set
38# CONFIG_MOMENCO_OCELOT is not set 36# CONFIG_MOMENCO_OCELOT is not set
39# CONFIG_MOMENCO_OCELOT_3 is not set
40# CONFIG_MOMENCO_OCELOT_C is not set
41# CONFIG_MOMENCO_OCELOT_G is not set 37# CONFIG_MOMENCO_OCELOT_G is not set
42# CONFIG_MIPS_XXS1500 is not set 38# CONFIG_MIPS_XXS1500 is not set
43# CONFIG_PNX8550_JBS is not set 39# CONFIG_PNX8550_JBS is not set
diff --git a/arch/mips/configs/fulong_defconfig b/arch/mips/configs/fulong_defconfig
new file mode 100644
index 000000000000..6ab94d8cf08b
--- /dev/null
+++ b/arch/mips/configs/fulong_defconfig
@@ -0,0 +1,1765 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.22-rc4
4# Mon Jun 11 00:23:51 2007
5#
6CONFIG_MIPS=y
7
8#
9# Machine selection
10#
11CONFIG_LEMOTE_FULONG=y
12# CONFIG_MACH_ALCHEMY is not set
13# CONFIG_BASLER_EXCITE is not set
14# CONFIG_MIPS_COBALT is not set
15# CONFIG_MACH_DECSTATION is not set
16# CONFIG_MACH_JAZZ is not set
17# CONFIG_MIPS_ATLAS is not set
18# CONFIG_MIPS_MALTA is not set
19# CONFIG_MIPS_SEAD is not set
20# CONFIG_WR_PPMC is not set
21# CONFIG_MIPS_SIM is not set
22# CONFIG_MOMENCO_OCELOT is not set
23# CONFIG_PNX8550_JBS is not set
24# CONFIG_PNX8550_STB810 is not set
25# CONFIG_DDB5477 is not set
26# CONFIG_MACH_VR41XX is not set
27# CONFIG_PMC_YOSEMITE is not set
28# CONFIG_QEMU is not set
29# CONFIG_MARKEINS is not set
30# CONFIG_SGI_IP22 is not set
31# CONFIG_SGI_IP27 is not set
32# CONFIG_SGI_IP32 is not set
33# CONFIG_SIBYTE_BIGSUR is not set
34# CONFIG_SIBYTE_SWARM is not set
35# CONFIG_SIBYTE_SENTOSA is not set
36# CONFIG_SIBYTE_RHONE is not set
37# CONFIG_SIBYTE_CARMEL is not set
38# CONFIG_SIBYTE_PTSWARM is not set
39# CONFIG_SIBYTE_LITTLESUR is not set
40# CONFIG_SIBYTE_CRHINE is not set
41# CONFIG_SIBYTE_CRHONE is not set
42# CONFIG_SNI_RM is not set
43# CONFIG_TOSHIBA_JMR3927 is not set
44# CONFIG_TOSHIBA_RBTX4927 is not set
45# CONFIG_TOSHIBA_RBTX4938 is not set
46CONFIG_RWSEM_GENERIC_SPINLOCK=y
47# CONFIG_ARCH_HAS_ILOG2_U32 is not set
48# CONFIG_ARCH_HAS_ILOG2_U64 is not set
49CONFIG_GENERIC_FIND_NEXT_BIT=y
50CONFIG_GENERIC_HWEIGHT=y
51CONFIG_GENERIC_CALIBRATE_DELAY=y
52CONFIG_GENERIC_TIME=y
53CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
54CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
55CONFIG_DMA_NONCOHERENT=y
56CONFIG_DMA_NEED_PCI_MAP_STATE=y
57CONFIG_EARLY_PRINTK=y
58CONFIG_SYS_HAS_EARLY_PRINTK=y
59CONFIG_I8259=y
60# CONFIG_NO_IOPORT is not set
61# CONFIG_CPU_BIG_ENDIAN is not set
62CONFIG_CPU_LITTLE_ENDIAN=y
63CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
64CONFIG_IRQ_CPU=y
65CONFIG_BOOT_ELF32=y
66CONFIG_MIPS_L1_CACHE_SHIFT=5
67
68#
69# CPU selection
70#
71CONFIG_CPU_LOONGSON2=y
72# CONFIG_CPU_MIPS32_R1 is not set
73# CONFIG_CPU_MIPS32_R2 is not set
74# CONFIG_CPU_MIPS64_R1 is not set
75# CONFIG_CPU_MIPS64_R2 is not set
76# CONFIG_CPU_R3000 is not set
77# CONFIG_CPU_TX39XX is not set
78# CONFIG_CPU_VR41XX is not set
79# CONFIG_CPU_R4300 is not set
80# CONFIG_CPU_R4X00 is not set
81# CONFIG_CPU_TX49XX is not set
82# CONFIG_CPU_R5000 is not set
83# CONFIG_CPU_R5432 is not set
84# CONFIG_CPU_R6000 is not set
85# CONFIG_CPU_NEVADA is not set
86# CONFIG_CPU_R8000 is not set
87# CONFIG_CPU_R10000 is not set
88# CONFIG_CPU_RM7000 is not set
89# CONFIG_CPU_RM9000 is not set
90# CONFIG_CPU_SB1 is not set
91CONFIG_SYS_HAS_CPU_LOONGSON2=y
92CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
93CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
94CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
95CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
96
97#
98# Kernel type
99#
100# CONFIG_32BIT is not set
101CONFIG_64BIT=y
102# CONFIG_PAGE_SIZE_4KB is not set
103# CONFIG_PAGE_SIZE_8KB is not set
104CONFIG_PAGE_SIZE_16KB=y
105# CONFIG_PAGE_SIZE_64KB is not set
106CONFIG_BOARD_SCACHE=y
107CONFIG_MIPS_MT_DISABLED=y
108# CONFIG_MIPS_MT_SMP is not set
109# CONFIG_MIPS_MT_SMTC is not set
110# CONFIG_MIPS_VPE_LOADER is not set
111CONFIG_CPU_HAS_WB=y
112CONFIG_CPU_HAS_SYNC=y
113CONFIG_GENERIC_HARDIRQS=y
114CONFIG_GENERIC_IRQ_PROBE=y
115CONFIG_CPU_SUPPORTS_HIGHMEM=y
116CONFIG_SYS_SUPPORTS_HIGHMEM=y
117CONFIG_ARCH_FLATMEM_ENABLE=y
118CONFIG_ARCH_SPARSEMEM_ENABLE=y
119CONFIG_SELECT_MEMORY_MODEL=y
120CONFIG_FLATMEM_MANUAL=y
121# CONFIG_DISCONTIGMEM_MANUAL is not set
122# CONFIG_SPARSEMEM_MANUAL is not set
123CONFIG_FLATMEM=y
124CONFIG_FLAT_NODE_MEM_MAP=y
125CONFIG_SPARSEMEM_STATIC=y
126CONFIG_SPLIT_PTLOCK_CPUS=4
127CONFIG_RESOURCES_64BIT=y
128CONFIG_ZONE_DMA_FLAG=0
129# CONFIG_HZ_48 is not set
130# CONFIG_HZ_100 is not set
131# CONFIG_HZ_128 is not set
132CONFIG_HZ_250=y
133# CONFIG_HZ_256 is not set
134# CONFIG_HZ_1000 is not set
135# CONFIG_HZ_1024 is not set
136CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
137CONFIG_HZ=250
138# CONFIG_PREEMPT_NONE is not set
139CONFIG_PREEMPT_VOLUNTARY=y
140# CONFIG_PREEMPT is not set
141# CONFIG_KEXEC is not set
142CONFIG_LOCKDEP_SUPPORT=y
143CONFIG_STACKTRACE_SUPPORT=y
144CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
145
146#
147# Code maturity level options
148#
149CONFIG_EXPERIMENTAL=y
150CONFIG_BROKEN_ON_SMP=y
151CONFIG_INIT_ENV_ARG_LIMIT=32
152
153#
154# General setup
155#
156CONFIG_LOCALVERSION="lm32"
157# CONFIG_LOCALVERSION_AUTO is not set
158CONFIG_SWAP=y
159CONFIG_SYSVIPC=y
160# CONFIG_IPC_NS is not set
161CONFIG_SYSVIPC_SYSCTL=y
162CONFIG_POSIX_MQUEUE=y
163CONFIG_BSD_PROCESS_ACCT=y
164# CONFIG_BSD_PROCESS_ACCT_V3 is not set
165# CONFIG_TASKSTATS is not set
166# CONFIG_UTS_NS is not set
167# CONFIG_AUDIT is not set
168CONFIG_IKCONFIG=y
169CONFIG_IKCONFIG_PROC=y
170CONFIG_LOG_BUF_SHIFT=14
171CONFIG_SYSFS_DEPRECATED=y
172# CONFIG_RELAY is not set
173# CONFIG_BLK_DEV_INITRD is not set
174# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
175CONFIG_SYSCTL=y
176CONFIG_EMBEDDED=y
177CONFIG_SYSCTL_SYSCALL=y
178CONFIG_KALLSYMS=y
179# CONFIG_KALLSYMS_EXTRA_PASS is not set
180CONFIG_HOTPLUG=y
181CONFIG_PRINTK=y
182CONFIG_BUG=y
183CONFIG_ELF_CORE=y
184CONFIG_BASE_FULL=y
185CONFIG_FUTEX=y
186CONFIG_ANON_INODES=y
187CONFIG_EPOLL=y
188CONFIG_SIGNALFD=y
189CONFIG_TIMERFD=y
190CONFIG_EVENTFD=y
191CONFIG_SHMEM=y
192CONFIG_VM_EVENT_COUNTERS=y
193CONFIG_SLAB=y
194# CONFIG_SLUB is not set
195# CONFIG_SLOB is not set
196CONFIG_RT_MUTEXES=y
197# CONFIG_TINY_SHMEM is not set
198CONFIG_BASE_SMALL=0
199
200#
201# Loadable module support
202#
203CONFIG_MODULES=y
204CONFIG_MODULE_UNLOAD=y
205CONFIG_MODULE_FORCE_UNLOAD=y
206# CONFIG_MODVERSIONS is not set
207# CONFIG_MODULE_SRCVERSION_ALL is not set
208CONFIG_KMOD=y
209
210#
211# Block layer
212#
213CONFIG_BLOCK=y
214# CONFIG_BLK_DEV_IO_TRACE is not set
215
216#
217# IO Schedulers
218#
219CONFIG_IOSCHED_NOOP=y
220CONFIG_IOSCHED_AS=y
221CONFIG_IOSCHED_DEADLINE=y
222CONFIG_IOSCHED_CFQ=y
223# CONFIG_DEFAULT_AS is not set
224# CONFIG_DEFAULT_DEADLINE is not set
225CONFIG_DEFAULT_CFQ=y
226# CONFIG_DEFAULT_NOOP is not set
227CONFIG_DEFAULT_IOSCHED="cfq"
228
229#
230# Bus options (PCI, PCMCIA, EISA, ISA, TC)
231#
232CONFIG_HW_HAS_PCI=y
233CONFIG_PCI=y
234# CONFIG_ARCH_SUPPORTS_MSI is not set
235CONFIG_ISA=y
236CONFIG_MMU=y
237
238#
239# PCCARD (PCMCIA/CardBus) support
240#
241# CONFIG_PCCARD is not set
242# CONFIG_HOTPLUG_PCI is not set
243
244#
245# Executable file formats
246#
247CONFIG_BINFMT_ELF=y
248CONFIG_BINFMT_MISC=y
249# CONFIG_BUILD_ELF64 is not set
250CONFIG_MIPS32_COMPAT=y
251CONFIG_COMPAT=y
252CONFIG_SYSVIPC_COMPAT=y
253CONFIG_MIPS32_O32=y
254CONFIG_MIPS32_N32=y
255CONFIG_BINFMT_ELF32=y
256
257#
258# Power management options
259#
260CONFIG_PM=y
261# CONFIG_PM_LEGACY is not set
262# CONFIG_PM_DEBUG is not set
263# CONFIG_PM_SYSFS_DEPRECATED is not set
264
265#
266# Networking
267#
268CONFIG_NET=y
269
270#
271# Networking options
272#
273CONFIG_PACKET=y
274CONFIG_PACKET_MMAP=y
275CONFIG_UNIX=y
276CONFIG_XFRM=y
277# CONFIG_XFRM_USER is not set
278# CONFIG_XFRM_SUB_POLICY is not set
279# CONFIG_XFRM_MIGRATE is not set
280# CONFIG_NET_KEY is not set
281CONFIG_INET=y
282CONFIG_IP_MULTICAST=y
283# CONFIG_IP_ADVANCED_ROUTER is not set
284CONFIG_IP_FIB_HASH=y
285CONFIG_IP_PNP=y
286# CONFIG_IP_PNP_DHCP is not set
287CONFIG_IP_PNP_BOOTP=y
288# CONFIG_IP_PNP_RARP is not set
289CONFIG_NET_IPIP=m
290CONFIG_NET_IPGRE=m
291CONFIG_NET_IPGRE_BROADCAST=y
292# CONFIG_IP_MROUTE is not set
293# CONFIG_ARPD is not set
294# CONFIG_SYN_COOKIES is not set
295# CONFIG_INET_AH is not set
296# CONFIG_INET_ESP is not set
297# CONFIG_INET_IPCOMP is not set
298# CONFIG_INET_XFRM_TUNNEL is not set
299CONFIG_INET_TUNNEL=m
300# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
301# CONFIG_INET_XFRM_MODE_TUNNEL is not set
302CONFIG_INET_XFRM_MODE_BEET=y
303# CONFIG_INET_DIAG is not set
304# CONFIG_TCP_CONG_ADVANCED is not set
305CONFIG_TCP_CONG_CUBIC=y
306CONFIG_DEFAULT_TCP_CONG="cubic"
307# CONFIG_TCP_MD5SIG is not set
308# CONFIG_IP_VS is not set
309# CONFIG_IPV6 is not set
310# CONFIG_INET6_XFRM_TUNNEL is not set
311# CONFIG_INET6_TUNNEL is not set
312# CONFIG_NETWORK_SECMARK is not set
313CONFIG_NETFILTER=y
314# CONFIG_NETFILTER_DEBUG is not set
315
316#
317# Core Netfilter Configuration
318#
319CONFIG_NETFILTER_NETLINK=m
320CONFIG_NETFILTER_NETLINK_QUEUE=m
321CONFIG_NETFILTER_NETLINK_LOG=m
322# CONFIG_NF_CONNTRACK_ENABLED is not set
323# CONFIG_NF_CONNTRACK is not set
324CONFIG_NETFILTER_XTABLES=m
325CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
326# CONFIG_NETFILTER_XT_TARGET_DSCP is not set
327CONFIG_NETFILTER_XT_TARGET_MARK=m
328CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
329# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set
330# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set
331CONFIG_NETFILTER_XT_MATCH_COMMENT=m
332CONFIG_NETFILTER_XT_MATCH_DCCP=m
333# CONFIG_NETFILTER_XT_MATCH_DSCP is not set
334CONFIG_NETFILTER_XT_MATCH_ESP=m
335CONFIG_NETFILTER_XT_MATCH_LENGTH=m
336CONFIG_NETFILTER_XT_MATCH_LIMIT=m
337CONFIG_NETFILTER_XT_MATCH_MAC=m
338CONFIG_NETFILTER_XT_MATCH_MARK=m
339# CONFIG_NETFILTER_XT_MATCH_POLICY is not set
340CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
341CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
342CONFIG_NETFILTER_XT_MATCH_QUOTA=m
343CONFIG_NETFILTER_XT_MATCH_REALM=m
344CONFIG_NETFILTER_XT_MATCH_SCTP=m
345CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
346CONFIG_NETFILTER_XT_MATCH_STRING=m
347CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
348# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set
349
350#
351# IP: Netfilter Configuration
352#
353CONFIG_IP_NF_QUEUE=m
354CONFIG_IP_NF_IPTABLES=m
355CONFIG_IP_NF_MATCH_IPRANGE=m
356CONFIG_IP_NF_MATCH_TOS=m
357CONFIG_IP_NF_MATCH_RECENT=m
358CONFIG_IP_NF_MATCH_ECN=m
359CONFIG_IP_NF_MATCH_AH=m
360CONFIG_IP_NF_MATCH_TTL=m
361CONFIG_IP_NF_MATCH_OWNER=m
362CONFIG_IP_NF_MATCH_ADDRTYPE=m
363CONFIG_IP_NF_FILTER=m
364CONFIG_IP_NF_TARGET_REJECT=m
365CONFIG_IP_NF_TARGET_LOG=m
366CONFIG_IP_NF_TARGET_ULOG=m
367CONFIG_IP_NF_MANGLE=m
368CONFIG_IP_NF_TARGET_TOS=m
369CONFIG_IP_NF_TARGET_ECN=m
370CONFIG_IP_NF_TARGET_TTL=m
371CONFIG_IP_NF_RAW=m
372CONFIG_IP_NF_ARPTABLES=m
373CONFIG_IP_NF_ARPFILTER=m
374CONFIG_IP_NF_ARP_MANGLE=m
375# CONFIG_IP_DCCP is not set
376# CONFIG_IP_SCTP is not set
377# CONFIG_TIPC is not set
378# CONFIG_ATM is not set
379# CONFIG_BRIDGE is not set
380# CONFIG_VLAN_8021Q is not set
381# CONFIG_DECNET is not set
382# CONFIG_LLC2 is not set
383# CONFIG_IPX is not set
384# CONFIG_ATALK is not set
385# CONFIG_X25 is not set
386# CONFIG_LAPB is not set
387# CONFIG_ECONET is not set
388# CONFIG_WAN_ROUTER is not set
389
390#
391# QoS and/or fair queueing
392#
393# CONFIG_NET_SCHED is not set
394CONFIG_NET_CLS_ROUTE=y
395
396#
397# Network testing
398#
399# CONFIG_NET_PKTGEN is not set
400# CONFIG_HAMRADIO is not set
401# CONFIG_IRDA is not set
402# CONFIG_BT is not set
403# CONFIG_AF_RXRPC is not set
404
405#
406# Wireless
407#
408# CONFIG_CFG80211 is not set
409CONFIG_WIRELESS_EXT=y
410# CONFIG_MAC80211 is not set
411CONFIG_IEEE80211=m
412# CONFIG_IEEE80211_DEBUG is not set
413CONFIG_IEEE80211_CRYPT_WEP=m
414# CONFIG_IEEE80211_CRYPT_CCMP is not set
415# CONFIG_IEEE80211_CRYPT_TKIP is not set
416# CONFIG_IEEE80211_SOFTMAC is not set
417# CONFIG_RFKILL is not set
418
419#
420# Device Drivers
421#
422
423#
424# Generic Driver Options
425#
426CONFIG_STANDALONE=y
427CONFIG_PREVENT_FIRMWARE_BUILD=y
428CONFIG_FW_LOADER=m
429# CONFIG_SYS_HYPERVISOR is not set
430
431#
432# Connector - unified userspace <-> kernelspace linker
433#
434# CONFIG_CONNECTOR is not set
435CONFIG_MTD=m
436# CONFIG_MTD_DEBUG is not set
437# CONFIG_MTD_CONCAT is not set
438# CONFIG_MTD_PARTITIONS is not set
439
440#
441# User Modules And Translation Layers
442#
443CONFIG_MTD_CHAR=m
444CONFIG_MTD_BLKDEVS=m
445CONFIG_MTD_BLOCK=m
446# CONFIG_MTD_BLOCK_RO is not set
447# CONFIG_FTL is not set
448# CONFIG_NFTL is not set
449# CONFIG_INFTL is not set
450# CONFIG_RFD_FTL is not set
451# CONFIG_SSFDC is not set
452
453#
454# RAM/ROM/Flash chip drivers
455#
456CONFIG_MTD_CFI=m
457CONFIG_MTD_JEDECPROBE=m
458CONFIG_MTD_GEN_PROBE=m
459CONFIG_MTD_CFI_ADV_OPTIONS=y
460CONFIG_MTD_CFI_NOSWAP=y
461# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
462# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
463# CONFIG_MTD_CFI_GEOMETRY is not set
464CONFIG_MTD_MAP_BANK_WIDTH_1=y
465CONFIG_MTD_MAP_BANK_WIDTH_2=y
466CONFIG_MTD_MAP_BANK_WIDTH_4=y
467# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
468# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
469# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
470CONFIG_MTD_CFI_I1=y
471CONFIG_MTD_CFI_I2=y
472# CONFIG_MTD_CFI_I4 is not set
473# CONFIG_MTD_CFI_I8 is not set
474# CONFIG_MTD_OTP is not set
475# CONFIG_MTD_CFI_INTELEXT is not set
476CONFIG_MTD_CFI_AMDSTD=m
477CONFIG_MTD_CFI_STAA=m
478CONFIG_MTD_CFI_UTIL=m
479# CONFIG_MTD_RAM is not set
480# CONFIG_MTD_ROM is not set
481# CONFIG_MTD_ABSENT is not set
482
483#
484# Mapping drivers for chip access
485#
486# CONFIG_MTD_COMPLEX_MAPPINGS is not set
487CONFIG_MTD_PHYSMAP=m
488CONFIG_MTD_PHYSMAP_START=0x1fc00000
489CONFIG_MTD_PHYSMAP_LEN=0x80000
490CONFIG_MTD_PHYSMAP_BANKWIDTH=1
491# CONFIG_MTD_PLATRAM is not set
492
493#
494# Self-contained MTD device drivers
495#
496# CONFIG_MTD_PMC551 is not set
497# CONFIG_MTD_SLRAM is not set
498# CONFIG_MTD_PHRAM is not set
499# CONFIG_MTD_MTDRAM is not set
500# CONFIG_MTD_BLOCK2MTD is not set
501
502#
503# Disk-On-Chip Device Drivers
504#
505# CONFIG_MTD_DOC2000 is not set
506# CONFIG_MTD_DOC2001 is not set
507# CONFIG_MTD_DOC2001PLUS is not set
508# CONFIG_MTD_NAND is not set
509# CONFIG_MTD_ONENAND is not set
510
511#
512# UBI - Unsorted block images
513#
514# CONFIG_MTD_UBI is not set
515
516#
517# Parallel port support
518#
519# CONFIG_PARPORT is not set
520
521#
522# Plug and Play support
523#
524# CONFIG_PNP is not set
525# CONFIG_PNPACPI is not set
526
527#
528# Block devices
529#
530# CONFIG_BLK_CPQ_DA is not set
531# CONFIG_BLK_CPQ_CISS_DA is not set
532# CONFIG_BLK_DEV_DAC960 is not set
533# CONFIG_BLK_DEV_UMEM is not set
534# CONFIG_BLK_DEV_COW_COMMON is not set
535CONFIG_BLK_DEV_LOOP=y
536CONFIG_BLK_DEV_CRYPTOLOOP=m
537# CONFIG_BLK_DEV_NBD is not set
538# CONFIG_BLK_DEV_SX8 is not set
539# CONFIG_BLK_DEV_UB is not set
540CONFIG_BLK_DEV_RAM=m
541CONFIG_BLK_DEV_RAM_COUNT=16
542CONFIG_BLK_DEV_RAM_SIZE=4096
543CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
544CONFIG_CDROM_PKTCDVD=m
545CONFIG_CDROM_PKTCDVD_BUFFERS=8
546# CONFIG_CDROM_PKTCDVD_WCACHE is not set
547CONFIG_ATA_OVER_ETH=m
548
549#
550# Misc devices
551#
552# CONFIG_PHANTOM is not set
553# CONFIG_SGI_IOC4 is not set
554# CONFIG_TIFM_CORE is not set
555# CONFIG_BLINK is not set
556CONFIG_IDE=y
557CONFIG_IDE_MAX_HWIFS=4
558CONFIG_BLK_DEV_IDE=y
559
560#
561# Please see Documentation/ide.txt for help/info on IDE drives
562#
563# CONFIG_BLK_DEV_IDE_SATA is not set
564CONFIG_BLK_DEV_IDEDISK=y
565CONFIG_IDEDISK_MULTI_MODE=y
566CONFIG_BLK_DEV_IDECD=y
567# CONFIG_BLK_DEV_IDETAPE is not set
568# CONFIG_BLK_DEV_IDEFLOPPY is not set
569CONFIG_BLK_DEV_IDESCSI=y
570CONFIG_IDE_TASK_IOCTL=y
571CONFIG_IDE_PROC_FS=y
572
573#
574# IDE chipset support/bugfixes
575#
576CONFIG_IDE_GENERIC=y
577CONFIG_BLK_DEV_IDEPCI=y
578CONFIG_IDEPCI_SHARE_IRQ=y
579CONFIG_IDEPCI_PCIBUS_ORDER=y
580# CONFIG_BLK_DEV_OFFBOARD is not set
581CONFIG_BLK_DEV_GENERIC=y
582# CONFIG_BLK_DEV_OPTI621 is not set
583CONFIG_BLK_DEV_IDEDMA_PCI=y
584# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
585# CONFIG_IDEDMA_ONLYDISK is not set
586# CONFIG_BLK_DEV_AEC62XX is not set
587# CONFIG_BLK_DEV_ALI15X3 is not set
588# CONFIG_BLK_DEV_AMD74XX is not set
589# CONFIG_BLK_DEV_CMD64X is not set
590# CONFIG_BLK_DEV_TRIFLEX is not set
591# CONFIG_BLK_DEV_CY82C693 is not set
592# CONFIG_BLK_DEV_CS5520 is not set
593# CONFIG_BLK_DEV_CS5530 is not set
594# CONFIG_BLK_DEV_HPT34X is not set
595# CONFIG_BLK_DEV_HPT366 is not set
596# CONFIG_BLK_DEV_JMICRON is not set
597# CONFIG_BLK_DEV_SC1200 is not set
598# CONFIG_BLK_DEV_PIIX is not set
599# CONFIG_BLK_DEV_IT8213 is not set
600# CONFIG_BLK_DEV_IT821X is not set
601# CONFIG_BLK_DEV_NS87415 is not set
602# CONFIG_BLK_DEV_PDC202XX_OLD is not set
603# CONFIG_BLK_DEV_PDC202XX_NEW is not set
604# CONFIG_BLK_DEV_SVWKS is not set
605# CONFIG_BLK_DEV_SIIMAGE is not set
606# CONFIG_BLK_DEV_SLC90E66 is not set
607# CONFIG_BLK_DEV_TRM290 is not set
608CONFIG_BLK_DEV_VIA82CXXX=y
609# CONFIG_BLK_DEV_TC86C001 is not set
610# CONFIG_IDE_ARM is not set
611# CONFIG_IDE_CHIPSETS is not set
612CONFIG_BLK_DEV_IDEDMA=y
613# CONFIG_IDEDMA_IVB is not set
614# CONFIG_BLK_DEV_HD is not set
615
616#
617# SCSI device support
618#
619# CONFIG_RAID_ATTRS is not set
620CONFIG_SCSI=y
621# CONFIG_SCSI_TGT is not set
622# CONFIG_SCSI_NETLINK is not set
623CONFIG_SCSI_PROC_FS=y
624
625#
626# SCSI support type (disk, tape, CD-ROM)
627#
628CONFIG_BLK_DEV_SD=y
629# CONFIG_CHR_DEV_ST is not set
630# CONFIG_CHR_DEV_OSST is not set
631CONFIG_BLK_DEV_SR=y
632CONFIG_BLK_DEV_SR_VENDOR=y
633CONFIG_CHR_DEV_SG=y
634# CONFIG_CHR_DEV_SCH is not set
635
636#
637# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
638#
639# CONFIG_SCSI_MULTI_LUN is not set
640CONFIG_SCSI_CONSTANTS=y
641# CONFIG_SCSI_LOGGING is not set
642# CONFIG_SCSI_SCAN_ASYNC is not set
643CONFIG_SCSI_WAIT_SCAN=m
644
645#
646# SCSI Transports
647#
648# CONFIG_SCSI_SPI_ATTRS is not set
649# CONFIG_SCSI_FC_ATTRS is not set
650# CONFIG_SCSI_ISCSI_ATTRS is not set
651# CONFIG_SCSI_SAS_ATTRS is not set
652# CONFIG_SCSI_SAS_LIBSAS is not set
653
654#
655# SCSI low-level drivers
656#
657# CONFIG_ISCSI_TCP is not set
658# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
659# CONFIG_SCSI_3W_9XXX is not set
660# CONFIG_SCSI_ACARD is not set
661# CONFIG_SCSI_AACRAID is not set
662# CONFIG_SCSI_AIC7XXX is not set
663# CONFIG_SCSI_AIC7XXX_OLD is not set
664# CONFIG_SCSI_AIC79XX is not set
665# CONFIG_SCSI_AIC94XX is not set
666# CONFIG_SCSI_IN2000 is not set
667# CONFIG_SCSI_ARCMSR is not set
668# CONFIG_MEGARAID_NEWGEN is not set
669# CONFIG_MEGARAID_LEGACY is not set
670# CONFIG_MEGARAID_SAS is not set
671# CONFIG_SCSI_HPTIOP is not set
672# CONFIG_SCSI_DMX3191D is not set
673# CONFIG_SCSI_DTC3280 is not set
674# CONFIG_SCSI_FUTURE_DOMAIN is not set
675# CONFIG_SCSI_GENERIC_NCR5380 is not set
676# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set
677# CONFIG_SCSI_IPS is not set
678# CONFIG_SCSI_INITIO is not set
679# CONFIG_SCSI_INIA100 is not set
680# CONFIG_SCSI_NCR53C406A is not set
681# CONFIG_SCSI_STEX is not set
682# CONFIG_SCSI_SYM53C8XX_2 is not set
683# CONFIG_SCSI_PAS16 is not set
684# CONFIG_SCSI_PSI240I is not set
685# CONFIG_SCSI_QLOGIC_FAS is not set
686# CONFIG_SCSI_QLOGIC_1280 is not set
687# CONFIG_SCSI_QLA_FC is not set
688# CONFIG_SCSI_QLA_ISCSI is not set
689# CONFIG_SCSI_LPFC is not set
690# CONFIG_SCSI_SYM53C416 is not set
691# CONFIG_SCSI_DC395x is not set
692# CONFIG_SCSI_DC390T is not set
693# CONFIG_SCSI_T128 is not set
694# CONFIG_SCSI_DEBUG is not set
695# CONFIG_SCSI_SRP is not set
696# CONFIG_ATA is not set
697
698#
699# Old CD-ROM drivers (not SCSI, not IDE)
700#
701# CONFIG_CD_NO_IDESCSI is not set
702
703#
704# Multi-device support (RAID and LVM)
705#
706# CONFIG_MD is not set
707
708#
709# Fusion MPT device support
710#
711# CONFIG_FUSION is not set
712# CONFIG_FUSION_SPI is not set
713# CONFIG_FUSION_FC is not set
714# CONFIG_FUSION_SAS is not set
715
716#
717# IEEE 1394 (FireWire) support
718#
719# CONFIG_FIREWIRE is not set
720# CONFIG_IEEE1394 is not set
721
722#
723# I2O device support
724#
725# CONFIG_I2O is not set
726
727#
728# Network device support
729#
730CONFIG_NETDEVICES=y
731# CONFIG_DUMMY is not set
732# CONFIG_BONDING is not set
733# CONFIG_EQUALIZER is not set
734# CONFIG_TUN is not set
735# CONFIG_ARCNET is not set
736CONFIG_PHYLIB=m
737
738#
739# MII PHY device drivers
740#
741CONFIG_MARVELL_PHY=m
742CONFIG_DAVICOM_PHY=m
743CONFIG_QSEMI_PHY=m
744CONFIG_LXT_PHY=m
745CONFIG_CICADA_PHY=m
746# CONFIG_VITESSE_PHY is not set
747# CONFIG_SMSC_PHY is not set
748# CONFIG_BROADCOM_PHY is not set
749# CONFIG_FIXED_PHY is not set
750
751#
752# Ethernet (10 or 100Mbit)
753#
754CONFIG_NET_ETHERNET=y
755CONFIG_MII=y
756# CONFIG_HAPPYMEAL is not set
757# CONFIG_SUNGEM is not set
758# CONFIG_CASSINI is not set
759# CONFIG_NET_VENDOR_3COM is not set
760# CONFIG_NET_VENDOR_SMC is not set
761# CONFIG_DM9000 is not set
762# CONFIG_NET_VENDOR_RACAL is not set
763
764#
765# Tulip family network device support
766#
767# CONFIG_NET_TULIP is not set
768# CONFIG_AT1700 is not set
769# CONFIG_DEPCA is not set
770# CONFIG_HP100 is not set
771# CONFIG_NET_ISA is not set
772CONFIG_NET_PCI=y
773# CONFIG_PCNET32 is not set
774# CONFIG_AMD8111_ETH is not set
775# CONFIG_ADAPTEC_STARFIRE is not set
776# CONFIG_AC3200 is not set
777# CONFIG_APRICOT is not set
778# CONFIG_B44 is not set
779# CONFIG_FORCEDETH is not set
780# CONFIG_CS89x0 is not set
781# CONFIG_TC35815 is not set
782# CONFIG_DGRS is not set
783# CONFIG_EEPRO100 is not set
784# CONFIG_E100 is not set
785# CONFIG_FEALNX is not set
786# CONFIG_NATSEMI is not set
787# CONFIG_NE2K_PCI is not set
788# CONFIG_8139CP is not set
789CONFIG_8139TOO=y
790# CONFIG_8139TOO_PIO is not set
791# CONFIG_8139TOO_TUNE_TWISTER is not set
792# CONFIG_8139TOO_8129 is not set
793# CONFIG_8139_OLD_RX_RESET is not set
794# CONFIG_SIS900 is not set
795# CONFIG_EPIC100 is not set
796# CONFIG_SUNDANCE is not set
797# CONFIG_VIA_RHINE is not set
798# CONFIG_SC92031 is not set
799CONFIG_NETDEV_1000=y
800# CONFIG_ACENIC is not set
801# CONFIG_DL2K is not set
802# CONFIG_E1000 is not set
803# CONFIG_NS83820 is not set
804# CONFIG_HAMACHI is not set
805# CONFIG_YELLOWFIN is not set
806# CONFIG_R8169 is not set
807# CONFIG_SIS190 is not set
808# CONFIG_SKGE is not set
809# CONFIG_SKY2 is not set
810# CONFIG_SK98LIN is not set
811# CONFIG_VIA_VELOCITY is not set
812# CONFIG_TIGON3 is not set
813# CONFIG_BNX2 is not set
814# CONFIG_QLA3XXX is not set
815# CONFIG_ATL1 is not set
816CONFIG_NETDEV_10000=y
817# CONFIG_CHELSIO_T1 is not set
818# CONFIG_CHELSIO_T3 is not set
819# CONFIG_IXGB is not set
820# CONFIG_S2IO is not set
821# CONFIG_MYRI10GE is not set
822# CONFIG_NETXEN_NIC is not set
823# CONFIG_MLX4_CORE is not set
824# CONFIG_TR is not set
825
826#
827# Wireless LAN
828#
829# CONFIG_WLAN_PRE80211 is not set
830# CONFIG_WLAN_80211 is not set
831
832#
833# USB Network Adapters
834#
835# CONFIG_USB_CATC is not set
836# CONFIG_USB_KAWETH is not set
837# CONFIG_USB_PEGASUS is not set
838# CONFIG_USB_RTL8150 is not set
839# CONFIG_USB_USBNET_MII is not set
840# CONFIG_USB_USBNET is not set
841# CONFIG_WAN is not set
842# CONFIG_FDDI is not set
843# CONFIG_HIPPI is not set
844CONFIG_PPP=m
845CONFIG_PPP_MULTILINK=y
846CONFIG_PPP_FILTER=y
847CONFIG_PPP_ASYNC=m
848CONFIG_PPP_SYNC_TTY=m
849CONFIG_PPP_DEFLATE=m
850CONFIG_PPP_BSDCOMP=m
851CONFIG_PPP_MPPE=m
852CONFIG_PPPOE=m
853CONFIG_SLIP=m
854CONFIG_SLIP_COMPRESSED=y
855CONFIG_SLHC=m
856CONFIG_SLIP_SMART=y
857CONFIG_SLIP_MODE_SLIP6=y
858CONFIG_NET_FC=y
859# CONFIG_SHAPER is not set
860# CONFIG_NETCONSOLE is not set
861# CONFIG_NETPOLL is not set
862# CONFIG_NET_POLL_CONTROLLER is not set
863
864#
865# ISDN subsystem
866#
867# CONFIG_ISDN is not set
868
869#
870# Telephony Support
871#
872# CONFIG_PHONE is not set
873
874#
875# Input device support
876#
877CONFIG_INPUT=y
878CONFIG_INPUT_FF_MEMLESS=y
879
880#
881# Userland interfaces
882#
883CONFIG_INPUT_MOUSEDEV=y
884CONFIG_INPUT_MOUSEDEV_PSAUX=y
885CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
886CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
887# CONFIG_INPUT_JOYDEV is not set
888# CONFIG_INPUT_TSDEV is not set
889# CONFIG_INPUT_EVDEV is not set
890# CONFIG_INPUT_EVBUG is not set
891
892#
893# Input Device Drivers
894#
895CONFIG_INPUT_KEYBOARD=y
896CONFIG_KEYBOARD_ATKBD=m
897# CONFIG_KEYBOARD_SUNKBD is not set
898# CONFIG_KEYBOARD_LKKBD is not set
899# CONFIG_KEYBOARD_XTKBD is not set
900# CONFIG_KEYBOARD_NEWTON is not set
901# CONFIG_KEYBOARD_STOWAWAY is not set
902CONFIG_INPUT_MOUSE=y
903CONFIG_MOUSE_PS2=y
904CONFIG_MOUSE_PS2_ALPS=y
905CONFIG_MOUSE_PS2_LOGIPS2PP=y
906CONFIG_MOUSE_PS2_SYNAPTICS=y
907CONFIG_MOUSE_PS2_LIFEBOOK=y
908CONFIG_MOUSE_PS2_TRACKPOINT=y
909# CONFIG_MOUSE_PS2_TOUCHKIT is not set
910CONFIG_MOUSE_SERIAL=y
911# CONFIG_MOUSE_APPLETOUCH is not set
912# CONFIG_MOUSE_INPORT is not set
913# CONFIG_MOUSE_LOGIBM is not set
914# CONFIG_MOUSE_PC110PAD is not set
915# CONFIG_MOUSE_VSXXXAA is not set
916# CONFIG_INPUT_JOYSTICK is not set
917# CONFIG_INPUT_TABLET is not set
918# CONFIG_INPUT_TOUCHSCREEN is not set
919# CONFIG_INPUT_MISC is not set
920
921#
922# Hardware I/O ports
923#
924CONFIG_SERIO=y
925CONFIG_SERIO_I8042=y
926CONFIG_SERIO_SERPORT=y
927# CONFIG_SERIO_PCIPS2 is not set
928CONFIG_SERIO_LIBPS2=y
929# CONFIG_SERIO_RAW is not set
930# CONFIG_GAMEPORT is not set
931
932#
933# Character devices
934#
935CONFIG_VT=y
936CONFIG_VT_CONSOLE=y
937CONFIG_HW_CONSOLE=y
938# CONFIG_VT_HW_CONSOLE_BINDING is not set
939# CONFIG_SERIAL_NONSTANDARD is not set
940
941#
942# Serial drivers
943#
944CONFIG_SERIAL_8250=y
945CONFIG_SERIAL_8250_CONSOLE=y
946CONFIG_SERIAL_8250_PCI=y
947CONFIG_SERIAL_8250_NR_UARTS=2
948CONFIG_SERIAL_8250_RUNTIME_UARTS=2
949# CONFIG_SERIAL_8250_EXTENDED is not set
950
951#
952# Non-8250 serial port support
953#
954CONFIG_SERIAL_CORE=y
955CONFIG_SERIAL_CORE_CONSOLE=y
956# CONFIG_SERIAL_JSM is not set
957CONFIG_UNIX98_PTYS=y
958CONFIG_LEGACY_PTYS=y
959CONFIG_LEGACY_PTY_COUNT=256
960
961#
962# IPMI
963#
964# CONFIG_IPMI_HANDLER is not set
965# CONFIG_WATCHDOG is not set
966CONFIG_HW_RANDOM=y
967CONFIG_RTC=y
968# CONFIG_DTLK is not set
969# CONFIG_R3964 is not set
970# CONFIG_APPLICOM is not set
971# CONFIG_DRM is not set
972# CONFIG_RAW_DRIVER is not set
973
974#
975# TPM devices
976#
977# CONFIG_TCG_TPM is not set
978CONFIG_DEVPORT=y
979CONFIG_I2C=m
980CONFIG_I2C_BOARDINFO=y
981CONFIG_I2C_CHARDEV=m
982
983#
984# I2C Algorithms
985#
986# CONFIG_I2C_ALGOBIT is not set
987# CONFIG_I2C_ALGOPCF is not set
988# CONFIG_I2C_ALGOPCA is not set
989
990#
991# I2C Hardware Bus support
992#
993# CONFIG_I2C_ALI1535 is not set
994# CONFIG_I2C_ALI1563 is not set
995# CONFIG_I2C_ALI15X3 is not set
996# CONFIG_I2C_AMD756 is not set
997# CONFIG_I2C_AMD8111 is not set
998# CONFIG_I2C_ELEKTOR is not set
999# CONFIG_I2C_I801 is not set
1000# CONFIG_I2C_I810 is not set
1001# CONFIG_I2C_PIIX4 is not set
1002# CONFIG_I2C_NFORCE2 is not set
1003# CONFIG_I2C_OCORES is not set
1004# CONFIG_I2C_PARPORT_LIGHT is not set
1005# CONFIG_I2C_PROSAVAGE is not set
1006# CONFIG_I2C_SAVAGE4 is not set
1007# CONFIG_I2C_SIMTEC is not set
1008# CONFIG_I2C_SIS5595 is not set
1009# CONFIG_I2C_SIS630 is not set
1010# CONFIG_I2C_SIS96X is not set
1011# CONFIG_I2C_STUB is not set
1012# CONFIG_I2C_TINY_USB is not set
1013# CONFIG_I2C_VIA is not set
1014CONFIG_I2C_VIAPRO=m
1015# CONFIG_I2C_VOODOO3 is not set
1016# CONFIG_I2C_PCA_ISA is not set
1017
1018#
1019# Miscellaneous I2C Chip support
1020#
1021# CONFIG_SENSORS_DS1337 is not set
1022# CONFIG_SENSORS_DS1374 is not set
1023# CONFIG_SENSORS_EEPROM is not set
1024# CONFIG_SENSORS_PCF8574 is not set
1025# CONFIG_SENSORS_PCA9539 is not set
1026# CONFIG_SENSORS_PCF8591 is not set
1027# CONFIG_SENSORS_MAX6875 is not set
1028# CONFIG_I2C_DEBUG_CORE is not set
1029# CONFIG_I2C_DEBUG_ALGO is not set
1030# CONFIG_I2C_DEBUG_BUS is not set
1031# CONFIG_I2C_DEBUG_CHIP is not set
1032
1033#
1034# SPI support
1035#
1036# CONFIG_SPI is not set
1037# CONFIG_SPI_MASTER is not set
1038
1039#
1040# Dallas's 1-wire bus
1041#
1042# CONFIG_W1 is not set
1043# CONFIG_HWMON is not set
1044
1045#
1046# Multifunction device drivers
1047#
1048# CONFIG_MFD_SM501 is not set
1049
1050#
1051# Multimedia devices
1052#
1053CONFIG_VIDEO_DEV=m
1054CONFIG_VIDEO_V4L1=y
1055CONFIG_VIDEO_V4L1_COMPAT=y
1056CONFIG_VIDEO_V4L2=y
1057CONFIG_VIDEO_CAPTURE_DRIVERS=y
1058# CONFIG_VIDEO_ADV_DEBUG is not set
1059CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
1060# CONFIG_VIDEO_VIVI is not set
1061# CONFIG_VIDEO_BT848 is not set
1062# CONFIG_VIDEO_PMS is not set
1063# CONFIG_VIDEO_CPIA is not set
1064# CONFIG_VIDEO_CPIA2 is not set
1065# CONFIG_VIDEO_SAA5246A is not set
1066# CONFIG_VIDEO_SAA5249 is not set
1067# CONFIG_TUNER_3036 is not set
1068# CONFIG_VIDEO_STRADIS is not set
1069# CONFIG_VIDEO_SAA7134 is not set
1070# CONFIG_VIDEO_MXB is not set
1071# CONFIG_VIDEO_DPC is not set
1072# CONFIG_VIDEO_HEXIUM_ORION is not set
1073# CONFIG_VIDEO_HEXIUM_GEMINI is not set
1074# CONFIG_VIDEO_CX88 is not set
1075# CONFIG_VIDEO_IVTV is not set
1076# CONFIG_VIDEO_CAFE_CCIC is not set
1077CONFIG_V4L_USB_DRIVERS=y
1078# CONFIG_VIDEO_PVRUSB2 is not set
1079# CONFIG_VIDEO_EM28XX is not set
1080# CONFIG_VIDEO_USBVISION is not set
1081CONFIG_VIDEO_USBVIDEO=m
1082CONFIG_USB_VICAM=m
1083CONFIG_USB_IBMCAM=m
1084CONFIG_USB_KONICAWC=m
1085CONFIG_USB_QUICKCAM_MESSENGER=m
1086CONFIG_USB_ET61X251=m
1087# CONFIG_VIDEO_OVCAMCHIP is not set
1088# CONFIG_USB_W9968CF is not set
1089CONFIG_USB_OV511=m
1090CONFIG_USB_SE401=m
1091CONFIG_USB_SN9C102=m
1092CONFIG_USB_STV680=m
1093CONFIG_USB_ZC0301=m
1094CONFIG_USB_PWC=m
1095# CONFIG_USB_PWC_DEBUG is not set
1096# CONFIG_USB_ZR364XX is not set
1097CONFIG_RADIO_ADAPTERS=y
1098# CONFIG_RADIO_CADET is not set
1099# CONFIG_RADIO_RTRACK is not set
1100# CONFIG_RADIO_RTRACK2 is not set
1101# CONFIG_RADIO_AZTECH is not set
1102# CONFIG_RADIO_GEMTEK is not set
1103# CONFIG_RADIO_GEMTEK_PCI is not set
1104# CONFIG_RADIO_MAXIRADIO is not set
1105# CONFIG_RADIO_MAESTRO is not set
1106# CONFIG_RADIO_SF16FMI is not set
1107# CONFIG_RADIO_SF16FMR2 is not set
1108# CONFIG_RADIO_TERRATEC is not set
1109# CONFIG_RADIO_TRUST is not set
1110# CONFIG_RADIO_TYPHOON is not set
1111# CONFIG_RADIO_ZOLTRIX is not set
1112# CONFIG_USB_DSBR is not set
1113# CONFIG_DVB_CORE is not set
1114CONFIG_DAB=y
1115# CONFIG_USB_DABUSB is not set
1116
1117#
1118# Graphics support
1119#
1120CONFIG_BACKLIGHT_LCD_SUPPORT=y
1121CONFIG_BACKLIGHT_CLASS_DEVICE=y
1122CONFIG_LCD_CLASS_DEVICE=m
1123
1124#
1125# Display device support
1126#
1127# CONFIG_DISPLAY_SUPPORT is not set
1128# CONFIG_VGASTATE is not set
1129CONFIG_FB=y
1130# CONFIG_FIRMWARE_EDID is not set
1131# CONFIG_FB_DDC is not set
1132CONFIG_FB_CFB_FILLRECT=y
1133CONFIG_FB_CFB_COPYAREA=y
1134CONFIG_FB_CFB_IMAGEBLIT=y
1135# CONFIG_FB_SYS_FILLRECT is not set
1136# CONFIG_FB_SYS_COPYAREA is not set
1137# CONFIG_FB_SYS_IMAGEBLIT is not set
1138# CONFIG_FB_SYS_FOPS is not set
1139CONFIG_FB_DEFERRED_IO=y
1140# CONFIG_FB_SVGALIB is not set
1141# CONFIG_FB_MACMODES is not set
1142CONFIG_FB_BACKLIGHT=y
1143CONFIG_FB_MODE_HELPERS=y
1144# CONFIG_FB_TILEBLITTING is not set
1145
1146#
1147# Frame buffer hardware drivers
1148#
1149# CONFIG_FB_CIRRUS is not set
1150# CONFIG_FB_PM2 is not set
1151# CONFIG_FB_CYBER2000 is not set
1152# CONFIG_FB_ASILIANT is not set
1153# CONFIG_FB_IMSTT is not set
1154# CONFIG_FB_S1D13XXX is not set
1155# CONFIG_FB_NVIDIA is not set
1156# CONFIG_FB_RIVA is not set
1157# CONFIG_FB_MATROX is not set
1158CONFIG_FB_RADEON=y
1159# CONFIG_FB_RADEON_I2C is not set
1160CONFIG_FB_RADEON_BACKLIGHT=y
1161# CONFIG_FB_RADEON_DEBUG is not set
1162# CONFIG_FB_ATY128 is not set
1163# CONFIG_FB_ATY is not set
1164# CONFIG_FB_S3 is not set
1165# CONFIG_FB_SAVAGE is not set
1166# CONFIG_FB_SIS is not set
1167# CONFIG_FB_NEOMAGIC is not set
1168# CONFIG_FB_KYRO is not set
1169# CONFIG_FB_3DFX is not set
1170# CONFIG_FB_VOODOO1 is not set
1171# CONFIG_FB_SMIVGX is not set
1172# CONFIG_FB_VT8623 is not set
1173# CONFIG_FB_TRIDENT is not set
1174# CONFIG_FB_ARK is not set
1175# CONFIG_FB_PM3 is not set
1176# CONFIG_FB_VIRTUAL is not set
1177
1178#
1179# Console display driver support
1180#
1181# CONFIG_VGA_CONSOLE is not set
1182# CONFIG_MDA_CONSOLE is not set
1183CONFIG_DUMMY_CONSOLE=y
1184CONFIG_FRAMEBUFFER_CONSOLE=y
1185# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
1186# CONFIG_FONTS is not set
1187CONFIG_FONT_8x8=y
1188CONFIG_FONT_8x16=y
1189# CONFIG_LOGO is not set
1190
1191#
1192# Sound
1193#
1194CONFIG_SOUND=y
1195
1196#
1197# Advanced Linux Sound Architecture
1198#
1199CONFIG_SND=m
1200CONFIG_SND_TIMER=m
1201CONFIG_SND_PCM=m
1202CONFIG_SND_RAWMIDI=m
1203CONFIG_SND_SEQUENCER=m
1204CONFIG_SND_SEQ_DUMMY=m
1205CONFIG_SND_OSSEMUL=y
1206CONFIG_SND_MIXER_OSS=m
1207CONFIG_SND_PCM_OSS=m
1208CONFIG_SND_PCM_OSS_PLUGINS=y
1209CONFIG_SND_SEQUENCER_OSS=y
1210CONFIG_SND_RTCTIMER=m
1211CONFIG_SND_SEQ_RTCTIMER_DEFAULT=y
1212# CONFIG_SND_DYNAMIC_MINORS is not set
1213CONFIG_SND_SUPPORT_OLD_API=y
1214CONFIG_SND_VERBOSE_PROCFS=y
1215# CONFIG_SND_VERBOSE_PRINTK is not set
1216# CONFIG_SND_DEBUG is not set
1217
1218#
1219# Generic devices
1220#
1221CONFIG_SND_MPU401_UART=m
1222CONFIG_SND_AC97_CODEC=m
1223# CONFIG_SND_DUMMY is not set
1224# CONFIG_SND_VIRMIDI is not set
1225# CONFIG_SND_MTPAV is not set
1226# CONFIG_SND_SERIAL_U16550 is not set
1227# CONFIG_SND_MPU401 is not set
1228
1229#
1230# PCI devices
1231#
1232# CONFIG_SND_AD1889 is not set
1233# CONFIG_SND_ALS300 is not set
1234# CONFIG_SND_ALI5451 is not set
1235# CONFIG_SND_ATIIXP is not set
1236# CONFIG_SND_ATIIXP_MODEM is not set
1237# CONFIG_SND_AU8810 is not set
1238# CONFIG_SND_AU8820 is not set
1239# CONFIG_SND_AU8830 is not set
1240# CONFIG_SND_AZT3328 is not set
1241# CONFIG_SND_BT87X is not set
1242# CONFIG_SND_CA0106 is not set
1243# CONFIG_SND_CMIPCI is not set
1244# CONFIG_SND_CS4281 is not set
1245# CONFIG_SND_CS46XX is not set
1246# CONFIG_SND_DARLA20 is not set
1247# CONFIG_SND_GINA20 is not set
1248# CONFIG_SND_LAYLA20 is not set
1249# CONFIG_SND_DARLA24 is not set
1250# CONFIG_SND_GINA24 is not set
1251# CONFIG_SND_LAYLA24 is not set
1252# CONFIG_SND_MONA is not set
1253# CONFIG_SND_MIA is not set
1254# CONFIG_SND_ECHO3G is not set
1255# CONFIG_SND_INDIGO is not set
1256# CONFIG_SND_INDIGOIO is not set
1257# CONFIG_SND_INDIGODJ is not set
1258# CONFIG_SND_EMU10K1 is not set
1259# CONFIG_SND_EMU10K1X is not set
1260# CONFIG_SND_ENS1370 is not set
1261# CONFIG_SND_ENS1371 is not set
1262# CONFIG_SND_ES1938 is not set
1263# CONFIG_SND_ES1968 is not set
1264# CONFIG_SND_FM801 is not set
1265# CONFIG_SND_HDA_INTEL is not set
1266# CONFIG_SND_HDSP is not set
1267# CONFIG_SND_HDSPM is not set
1268# CONFIG_SND_ICE1712 is not set
1269# CONFIG_SND_ICE1724 is not set
1270# CONFIG_SND_INTEL8X0 is not set
1271# CONFIG_SND_INTEL8X0M is not set
1272# CONFIG_SND_KORG1212 is not set
1273# CONFIG_SND_MAESTRO3 is not set
1274# CONFIG_SND_MIXART is not set
1275# CONFIG_SND_NM256 is not set
1276# CONFIG_SND_PCXHR is not set
1277# CONFIG_SND_RIPTIDE is not set
1278# CONFIG_SND_RME32 is not set
1279# CONFIG_SND_RME96 is not set
1280# CONFIG_SND_RME9652 is not set
1281# CONFIG_SND_SONICVIBES is not set
1282# CONFIG_SND_TRIDENT is not set
1283CONFIG_SND_VIA82XX=m
1284# CONFIG_SND_VIA82XX_MODEM is not set
1285# CONFIG_SND_VX222 is not set
1286# CONFIG_SND_YMFPCI is not set
1287# CONFIG_SND_AC97_POWER_SAVE is not set
1288
1289#
1290# ALSA MIPS devices
1291#
1292
1293#
1294# USB devices
1295#
1296# CONFIG_SND_USB_AUDIO is not set
1297# CONFIG_SND_USB_CAIAQ is not set
1298
1299#
1300# System on Chip audio support
1301#
1302# CONFIG_SND_SOC is not set
1303
1304#
1305# Open Sound System
1306#
1307# CONFIG_SOUND_PRIME is not set
1308CONFIG_AC97_BUS=m
1309
1310#
1311# HID Devices
1312#
1313CONFIG_HID=y
1314# CONFIG_HID_DEBUG is not set
1315
1316#
1317# USB Input Devices
1318#
1319CONFIG_USB_HID=m
1320# CONFIG_USB_HIDINPUT_POWERBOOK is not set
1321# CONFIG_HID_FF is not set
1322CONFIG_USB_HIDDEV=y
1323
1324#
1325# USB HID Boot Protocol drivers
1326#
1327# CONFIG_USB_KBD is not set
1328# CONFIG_USB_MOUSE is not set
1329
1330#
1331# USB support
1332#
1333CONFIG_USB_ARCH_HAS_HCD=y
1334CONFIG_USB_ARCH_HAS_OHCI=y
1335CONFIG_USB_ARCH_HAS_EHCI=y
1336CONFIG_USB=y
1337# CONFIG_USB_DEBUG is not set
1338
1339#
1340# Miscellaneous USB options
1341#
1342CONFIG_USB_DEVICEFS=y
1343# CONFIG_USB_DEVICE_CLASS is not set
1344# CONFIG_USB_DYNAMIC_MINORS is not set
1345# CONFIG_USB_SUSPEND is not set
1346# CONFIG_USB_OTG is not set
1347
1348#
1349# USB Host Controller Drivers
1350#
1351CONFIG_USB_EHCI_HCD=y
1352CONFIG_USB_EHCI_SPLIT_ISO=y
1353CONFIG_USB_EHCI_ROOT_HUB_TT=y
1354CONFIG_USB_EHCI_TT_NEWSCHED=y
1355# CONFIG_USB_EHCI_BIG_ENDIAN_MMIO is not set
1356# CONFIG_USB_ISP116X_HCD is not set
1357CONFIG_USB_OHCI_HCD=y
1358# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
1359# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
1360CONFIG_USB_OHCI_LITTLE_ENDIAN=y
1361CONFIG_USB_UHCI_HCD=m
1362# CONFIG_USB_SL811_HCD is not set
1363
1364#
1365# USB Device Class drivers
1366#
1367CONFIG_USB_ACM=y
1368CONFIG_USB_PRINTER=y
1369
1370#
1371# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
1372#
1373
1374#
1375# may also be needed; see USB_STORAGE Help for more information
1376#
1377CONFIG_USB_STORAGE=y
1378# CONFIG_USB_STORAGE_DEBUG is not set
1379# CONFIG_USB_STORAGE_DATAFAB is not set
1380# CONFIG_USB_STORAGE_FREECOM is not set
1381# CONFIG_USB_STORAGE_ISD200 is not set
1382# CONFIG_USB_STORAGE_DPCM is not set
1383# CONFIG_USB_STORAGE_USBAT is not set
1384# CONFIG_USB_STORAGE_SDDR09 is not set
1385# CONFIG_USB_STORAGE_SDDR55 is not set
1386# CONFIG_USB_STORAGE_JUMPSHOT is not set
1387# CONFIG_USB_STORAGE_ALAUDA is not set
1388# CONFIG_USB_STORAGE_KARMA is not set
1389CONFIG_USB_LIBUSUAL=y
1390
1391#
1392# USB Imaging devices
1393#
1394# CONFIG_USB_MDC800 is not set
1395# CONFIG_USB_MICROTEK is not set
1396# CONFIG_USB_MON is not set
1397
1398#
1399# USB port drivers
1400#
1401
1402#
1403# USB Serial Converter support
1404#
1405# CONFIG_USB_SERIAL is not set
1406
1407#
1408# USB Miscellaneous drivers
1409#
1410# CONFIG_USB_EMI62 is not set
1411# CONFIG_USB_EMI26 is not set
1412# CONFIG_USB_ADUTUX is not set
1413# CONFIG_USB_AUERSWALD is not set
1414# CONFIG_USB_RIO500 is not set
1415# CONFIG_USB_LEGOTOWER is not set
1416# CONFIG_USB_LCD is not set
1417# CONFIG_USB_BERRY_CHARGE is not set
1418# CONFIG_USB_LED is not set
1419# CONFIG_USB_CYPRESS_CY7C63 is not set
1420# CONFIG_USB_CYTHERM is not set
1421# CONFIG_USB_PHIDGET is not set
1422# CONFIG_USB_IDMOUSE is not set
1423# CONFIG_USB_FTDI_ELAN is not set
1424# CONFIG_USB_APPLEDISPLAY is not set
1425# CONFIG_USB_SISUSBVGA is not set
1426# CONFIG_USB_LD is not set
1427# CONFIG_USB_TRANCEVIBRATOR is not set
1428# CONFIG_USB_IOWARRIOR is not set
1429# CONFIG_USB_TEST is not set
1430
1431#
1432# USB DSL modem support
1433#
1434
1435#
1436# USB Gadget Support
1437#
1438# CONFIG_USB_GADGET is not set
1439# CONFIG_MMC is not set
1440
1441#
1442# LED devices
1443#
1444# CONFIG_NEW_LEDS is not set
1445
1446#
1447# LED drivers
1448#
1449
1450#
1451# LED Triggers
1452#
1453
1454#
1455# InfiniBand support
1456#
1457# CONFIG_INFINIBAND is not set
1458
1459#
1460# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
1461#
1462
1463#
1464# Real Time Clock
1465#
1466# CONFIG_RTC_CLASS is not set
1467
1468#
1469# DMA Engine support
1470#
1471# CONFIG_DMA_ENGINE is not set
1472
1473#
1474# DMA Clients
1475#
1476
1477#
1478# DMA Devices
1479#
1480
1481#
1482# File systems
1483#
1484CONFIG_EXT2_FS=y
1485# CONFIG_EXT2_FS_XATTR is not set
1486CONFIG_EXT2_FS_XIP=y
1487CONFIG_FS_XIP=y
1488CONFIG_EXT3_FS=y
1489# CONFIG_EXT3_FS_XATTR is not set
1490# CONFIG_EXT4DEV_FS is not set
1491CONFIG_JBD=y
1492# CONFIG_JBD_DEBUG is not set
1493CONFIG_REISERFS_FS=m
1494# CONFIG_REISERFS_CHECK is not set
1495# CONFIG_REISERFS_PROC_INFO is not set
1496# CONFIG_REISERFS_FS_XATTR is not set
1497# CONFIG_JFS_FS is not set
1498CONFIG_FS_POSIX_ACL=y
1499# CONFIG_XFS_FS is not set
1500# CONFIG_GFS2_FS is not set
1501# CONFIG_OCFS2_FS is not set
1502# CONFIG_MINIX_FS is not set
1503# CONFIG_ROMFS_FS is not set
1504CONFIG_INOTIFY=y
1505CONFIG_INOTIFY_USER=y
1506# CONFIG_QUOTA is not set
1507CONFIG_DNOTIFY=y
1508CONFIG_AUTOFS_FS=y
1509CONFIG_AUTOFS4_FS=y
1510CONFIG_FUSE_FS=y
1511
1512#
1513# CD-ROM/DVD Filesystems
1514#
1515CONFIG_ISO9660_FS=m
1516CONFIG_JOLIET=y
1517CONFIG_ZISOFS=y
1518CONFIG_UDF_FS=m
1519CONFIG_UDF_NLS=y
1520
1521#
1522# DOS/FAT/NT Filesystems
1523#
1524CONFIG_FAT_FS=m
1525CONFIG_MSDOS_FS=m
1526CONFIG_VFAT_FS=m
1527CONFIG_FAT_DEFAULT_CODEPAGE=936
1528CONFIG_FAT_DEFAULT_IOCHARSET="utf8"
1529CONFIG_NTFS_FS=m
1530# CONFIG_NTFS_DEBUG is not set
1531CONFIG_NTFS_RW=y
1532
1533#
1534# Pseudo filesystems
1535#
1536CONFIG_PROC_FS=y
1537CONFIG_PROC_KCORE=y
1538CONFIG_PROC_SYSCTL=y
1539CONFIG_SYSFS=y
1540CONFIG_TMPFS=y
1541# CONFIG_TMPFS_POSIX_ACL is not set
1542# CONFIG_HUGETLB_PAGE is not set
1543CONFIG_RAMFS=y
1544# CONFIG_CONFIGFS_FS is not set
1545
1546#
1547# Miscellaneous filesystems
1548#
1549# CONFIG_ADFS_FS is not set
1550# CONFIG_AFFS_FS is not set
1551# CONFIG_HFS_FS is not set
1552# CONFIG_HFSPLUS_FS is not set
1553# CONFIG_BEFS_FS is not set
1554# CONFIG_BFS_FS is not set
1555# CONFIG_EFS_FS is not set
1556# CONFIG_JFFS2_FS is not set
1557# CONFIG_CRAMFS is not set
1558# CONFIG_VXFS_FS is not set
1559# CONFIG_HPFS_FS is not set
1560# CONFIG_QNX4FS_FS is not set
1561# CONFIG_SYSV_FS is not set
1562# CONFIG_UFS_FS is not set
1563
1564#
1565# Network File Systems
1566#
1567CONFIG_NFS_FS=m
1568CONFIG_NFS_V3=y
1569CONFIG_NFS_V3_ACL=y
1570CONFIG_NFS_V4=y
1571CONFIG_NFS_DIRECTIO=y
1572CONFIG_NFSD=m
1573CONFIG_NFSD_V2_ACL=y
1574CONFIG_NFSD_V3=y
1575CONFIG_NFSD_V3_ACL=y
1576CONFIG_NFSD_V4=y
1577CONFIG_NFSD_TCP=y
1578CONFIG_LOCKD=m
1579CONFIG_LOCKD_V4=y
1580CONFIG_EXPORTFS=m
1581CONFIG_NFS_ACL_SUPPORT=m
1582CONFIG_NFS_COMMON=y
1583CONFIG_SUNRPC=m
1584CONFIG_SUNRPC_GSS=m
1585# CONFIG_SUNRPC_BIND34 is not set
1586CONFIG_RPCSEC_GSS_KRB5=m
1587# CONFIG_RPCSEC_GSS_SPKM3 is not set
1588CONFIG_SMB_FS=m
1589CONFIG_SMB_NLS_DEFAULT=y
1590CONFIG_SMB_NLS_REMOTE="cp936"
1591CONFIG_CIFS=m
1592CONFIG_CIFS_STATS=y
1593CONFIG_CIFS_STATS2=y
1594CONFIG_CIFS_WEAK_PW_HASH=y
1595CONFIG_CIFS_XATTR=y
1596CONFIG_CIFS_POSIX=y
1597CONFIG_CIFS_DEBUG2=y
1598CONFIG_CIFS_EXPERIMENTAL=y
1599# CONFIG_NCP_FS is not set
1600# CONFIG_CODA_FS is not set
1601# CONFIG_AFS_FS is not set
1602# CONFIG_9P_FS is not set
1603
1604#
1605# Partition Types
1606#
1607CONFIG_PARTITION_ADVANCED=y
1608# CONFIG_ACORN_PARTITION is not set
1609# CONFIG_OSF_PARTITION is not set
1610# CONFIG_AMIGA_PARTITION is not set
1611# CONFIG_ATARI_PARTITION is not set
1612# CONFIG_MAC_PARTITION is not set
1613CONFIG_MSDOS_PARTITION=y
1614# CONFIG_BSD_DISKLABEL is not set
1615# CONFIG_MINIX_SUBPARTITION is not set
1616# CONFIG_SOLARIS_X86_PARTITION is not set
1617# CONFIG_UNIXWARE_DISKLABEL is not set
1618# CONFIG_LDM_PARTITION is not set
1619# CONFIG_SGI_PARTITION is not set
1620# CONFIG_ULTRIX_PARTITION is not set
1621# CONFIG_SUN_PARTITION is not set
1622# CONFIG_KARMA_PARTITION is not set
1623# CONFIG_EFI_PARTITION is not set
1624# CONFIG_SYSV68_PARTITION is not set
1625
1626#
1627# Native Language Support
1628#
1629CONFIG_NLS=y
1630CONFIG_NLS_DEFAULT="utf8"
1631# CONFIG_NLS_CODEPAGE_437 is not set
1632# CONFIG_NLS_CODEPAGE_737 is not set
1633# CONFIG_NLS_CODEPAGE_775 is not set
1634# CONFIG_NLS_CODEPAGE_850 is not set
1635# CONFIG_NLS_CODEPAGE_852 is not set
1636# CONFIG_NLS_CODEPAGE_855 is not set
1637# CONFIG_NLS_CODEPAGE_857 is not set
1638# CONFIG_NLS_CODEPAGE_860 is not set
1639# CONFIG_NLS_CODEPAGE_861 is not set
1640# CONFIG_NLS_CODEPAGE_862 is not set
1641# CONFIG_NLS_CODEPAGE_863 is not set
1642# CONFIG_NLS_CODEPAGE_864 is not set
1643# CONFIG_NLS_CODEPAGE_865 is not set
1644# CONFIG_NLS_CODEPAGE_866 is not set
1645# CONFIG_NLS_CODEPAGE_869 is not set
1646CONFIG_NLS_CODEPAGE_936=y
1647# CONFIG_NLS_CODEPAGE_950 is not set
1648# CONFIG_NLS_CODEPAGE_932 is not set
1649# CONFIG_NLS_CODEPAGE_949 is not set
1650# CONFIG_NLS_CODEPAGE_874 is not set
1651# CONFIG_NLS_ISO8859_8 is not set
1652# CONFIG_NLS_CODEPAGE_1250 is not set
1653# CONFIG_NLS_CODEPAGE_1251 is not set
1654# CONFIG_NLS_ASCII is not set
1655CONFIG_NLS_ISO8859_1=y
1656# CONFIG_NLS_ISO8859_2 is not set
1657# CONFIG_NLS_ISO8859_3 is not set
1658# CONFIG_NLS_ISO8859_4 is not set
1659# CONFIG_NLS_ISO8859_5 is not set
1660# CONFIG_NLS_ISO8859_6 is not set
1661# CONFIG_NLS_ISO8859_7 is not set
1662# CONFIG_NLS_ISO8859_9 is not set
1663# CONFIG_NLS_ISO8859_13 is not set
1664# CONFIG_NLS_ISO8859_14 is not set
1665# CONFIG_NLS_ISO8859_15 is not set
1666# CONFIG_NLS_KOI8_R is not set
1667# CONFIG_NLS_KOI8_U is not set
1668CONFIG_NLS_UTF8=y
1669
1670#
1671# Distributed Lock Manager
1672#
1673# CONFIG_DLM is not set
1674
1675#
1676# Profiling support
1677#
1678CONFIG_PROFILING=y
1679CONFIG_OPROFILE=m
1680
1681#
1682# Kernel hacking
1683#
1684CONFIG_TRACE_IRQFLAGS_SUPPORT=y
1685# CONFIG_PRINTK_TIME is not set
1686# CONFIG_ENABLE_MUST_CHECK is not set
1687# CONFIG_MAGIC_SYSRQ is not set
1688# CONFIG_UNUSED_SYMBOLS is not set
1689# CONFIG_DEBUG_FS is not set
1690# CONFIG_HEADERS_CHECK is not set
1691# CONFIG_DEBUG_KERNEL is not set
1692CONFIG_CROSSCOMPILE=y
1693CONFIG_CMDLINE=""
1694
1695#
1696# Security options
1697#
1698# CONFIG_KEYS is not set
1699# CONFIG_SECURITY is not set
1700
1701#
1702# Cryptographic options
1703#
1704CONFIG_CRYPTO=y
1705CONFIG_CRYPTO_ALGAPI=y
1706CONFIG_CRYPTO_BLKCIPHER=m
1707CONFIG_CRYPTO_HASH=y
1708CONFIG_CRYPTO_MANAGER=y
1709CONFIG_CRYPTO_HMAC=y
1710# CONFIG_CRYPTO_XCBC is not set
1711# CONFIG_CRYPTO_NULL is not set
1712# CONFIG_CRYPTO_MD4 is not set
1713CONFIG_CRYPTO_MD5=m
1714CONFIG_CRYPTO_SHA1=m
1715# CONFIG_CRYPTO_SHA256 is not set
1716# CONFIG_CRYPTO_SHA512 is not set
1717# CONFIG_CRYPTO_WP512 is not set
1718# CONFIG_CRYPTO_TGR192 is not set
1719# CONFIG_CRYPTO_GF128MUL is not set
1720CONFIG_CRYPTO_ECB=m
1721CONFIG_CRYPTO_CBC=m
1722CONFIG_CRYPTO_PCBC=m
1723# CONFIG_CRYPTO_LRW is not set
1724# CONFIG_CRYPTO_CRYPTD is not set
1725CONFIG_CRYPTO_DES=m
1726# CONFIG_CRYPTO_FCRYPT is not set
1727# CONFIG_CRYPTO_BLOWFISH is not set
1728# CONFIG_CRYPTO_TWOFISH is not set
1729# CONFIG_CRYPTO_SERPENT is not set
1730# CONFIG_CRYPTO_AES is not set
1731# CONFIG_CRYPTO_CAST5 is not set
1732# CONFIG_CRYPTO_CAST6 is not set
1733# CONFIG_CRYPTO_TEA is not set
1734CONFIG_CRYPTO_ARC4=m
1735# CONFIG_CRYPTO_KHAZAD is not set
1736# CONFIG_CRYPTO_ANUBIS is not set
1737CONFIG_CRYPTO_DEFLATE=m
1738# CONFIG_CRYPTO_MICHAEL_MIC is not set
1739# CONFIG_CRYPTO_CRC32C is not set
1740# CONFIG_CRYPTO_CAMELLIA is not set
1741# CONFIG_CRYPTO_TEST is not set
1742
1743#
1744# Hardware crypto devices
1745#
1746
1747#
1748# Library routines
1749#
1750CONFIG_BITREVERSE=y
1751CONFIG_CRC_CCITT=y
1752# CONFIG_CRC16 is not set
1753# CONFIG_CRC_ITU_T is not set
1754CONFIG_CRC32=y
1755# CONFIG_LIBCRC32C is not set
1756CONFIG_ZLIB_INFLATE=m
1757CONFIG_ZLIB_DEFLATE=m
1758CONFIG_TEXTSEARCH=y
1759CONFIG_TEXTSEARCH_KMP=m
1760CONFIG_TEXTSEARCH_BM=m
1761CONFIG_TEXTSEARCH_FSM=m
1762CONFIG_PLIST=y
1763CONFIG_HAS_IOMEM=y
1764CONFIG_HAS_IOPORT=y
1765CONFIG_HAS_DMA=y
diff --git a/arch/mips/configs/ip22_defconfig b/arch/mips/configs/ip22_defconfig
index 7ec618f3c8b9..405c9f505a77 100644
--- a/arch/mips/configs/ip22_defconfig
+++ b/arch/mips/configs/ip22_defconfig
@@ -25,9 +25,7 @@ CONFIG_ZONE_DMA=y
25# CONFIG_BASLER_EXCITE is not set 25# CONFIG_BASLER_EXCITE is not set
26# CONFIG_MIPS_COBALT is not set 26# CONFIG_MIPS_COBALT is not set
27# CONFIG_MACH_DECSTATION is not set 27# CONFIG_MACH_DECSTATION is not set
28# CONFIG_MIPS_EV64120 is not set
29# CONFIG_MACH_JAZZ is not set 28# CONFIG_MACH_JAZZ is not set
30# CONFIG_LASAT is not set
31# CONFIG_MIPS_ATLAS is not set 29# CONFIG_MIPS_ATLAS is not set
32# CONFIG_MIPS_MALTA is not set 30# CONFIG_MIPS_MALTA is not set
33# CONFIG_MIPS_SEAD is not set 31# CONFIG_MIPS_SEAD is not set
@@ -35,8 +33,6 @@ CONFIG_ZONE_DMA=y
35# CONFIG_MIPS_SIM is not set 33# CONFIG_MIPS_SIM is not set
36# CONFIG_MOMENCO_JAGUAR_ATX is not set 34# CONFIG_MOMENCO_JAGUAR_ATX is not set
37# CONFIG_MOMENCO_OCELOT is not set 35# CONFIG_MOMENCO_OCELOT is not set
38# CONFIG_MOMENCO_OCELOT_3 is not set
39# CONFIG_MOMENCO_OCELOT_C is not set
40# CONFIG_MOMENCO_OCELOT_G is not set 36# CONFIG_MOMENCO_OCELOT_G is not set
41# CONFIG_MIPS_XXS1500 is not set 37# CONFIG_MIPS_XXS1500 is not set
42# CONFIG_PNX8550_JBS is not set 38# CONFIG_PNX8550_JBS is not set
diff --git a/arch/mips/configs/ip27_defconfig b/arch/mips/configs/ip27_defconfig
index 9ddc3eff4793..a9dcbcf563cb 100644
--- a/arch/mips/configs/ip27_defconfig
+++ b/arch/mips/configs/ip27_defconfig
@@ -25,9 +25,7 @@ CONFIG_ZONE_DMA=y
25# CONFIG_BASLER_EXCITE is not set 25# CONFIG_BASLER_EXCITE is not set
26# CONFIG_MIPS_COBALT is not set 26# CONFIG_MIPS_COBALT is not set
27# CONFIG_MACH_DECSTATION is not set 27# CONFIG_MACH_DECSTATION is not set
28# CONFIG_MIPS_EV64120 is not set
29# CONFIG_MACH_JAZZ is not set 28# CONFIG_MACH_JAZZ is not set
30# CONFIG_LASAT is not set
31# CONFIG_MIPS_ATLAS is not set 29# CONFIG_MIPS_ATLAS is not set
32# CONFIG_MIPS_MALTA is not set 30# CONFIG_MIPS_MALTA is not set
33# CONFIG_MIPS_SEAD is not set 31# CONFIG_MIPS_SEAD is not set
@@ -35,8 +33,6 @@ CONFIG_ZONE_DMA=y
35# CONFIG_MIPS_SIM is not set 33# CONFIG_MIPS_SIM is not set
36# CONFIG_MOMENCO_JAGUAR_ATX is not set 34# CONFIG_MOMENCO_JAGUAR_ATX is not set
37# CONFIG_MOMENCO_OCELOT is not set 35# CONFIG_MOMENCO_OCELOT is not set
38# CONFIG_MOMENCO_OCELOT_3 is not set
39# CONFIG_MOMENCO_OCELOT_C is not set
40# CONFIG_MOMENCO_OCELOT_G is not set 36# CONFIG_MOMENCO_OCELOT_G is not set
41# CONFIG_MIPS_XXS1500 is not set 37# CONFIG_MIPS_XXS1500 is not set
42# CONFIG_PNX8550_JBS is not set 38# CONFIG_PNX8550_JBS is not set
diff --git a/arch/mips/configs/ip32_defconfig b/arch/mips/configs/ip32_defconfig
index 8fc18809d5ff..a040459bec11 100644
--- a/arch/mips/configs/ip32_defconfig
+++ b/arch/mips/configs/ip32_defconfig
@@ -25,9 +25,7 @@ CONFIG_ZONE_DMA=y
25# CONFIG_BASLER_EXCITE is not set 25# CONFIG_BASLER_EXCITE is not set
26# CONFIG_MIPS_COBALT is not set 26# CONFIG_MIPS_COBALT is not set
27# CONFIG_MACH_DECSTATION is not set 27# CONFIG_MACH_DECSTATION is not set
28# CONFIG_MIPS_EV64120 is not set
29# CONFIG_MACH_JAZZ is not set 28# CONFIG_MACH_JAZZ is not set
30# CONFIG_LASAT is not set
31# CONFIG_MIPS_ATLAS is not set 29# CONFIG_MIPS_ATLAS is not set
32# CONFIG_MIPS_MALTA is not set 30# CONFIG_MIPS_MALTA is not set
33# CONFIG_MIPS_SEAD is not set 31# CONFIG_MIPS_SEAD is not set
@@ -35,8 +33,6 @@ CONFIG_ZONE_DMA=y
35# CONFIG_MIPS_SIM is not set 33# CONFIG_MIPS_SIM is not set
36# CONFIG_MOMENCO_JAGUAR_ATX is not set 34# CONFIG_MOMENCO_JAGUAR_ATX is not set
37# CONFIG_MOMENCO_OCELOT is not set 35# CONFIG_MOMENCO_OCELOT is not set
38# CONFIG_MOMENCO_OCELOT_3 is not set
39# CONFIG_MOMENCO_OCELOT_C is not set
40# CONFIG_MOMENCO_OCELOT_G is not set 36# CONFIG_MOMENCO_OCELOT_G is not set
41# CONFIG_MIPS_XXS1500 is not set 37# CONFIG_MIPS_XXS1500 is not set
42# CONFIG_PNX8550_JBS is not set 38# CONFIG_PNX8550_JBS is not set
diff --git a/arch/mips/configs/jazz_defconfig b/arch/mips/configs/jazz_defconfig
index 9331cb0a19b1..dd04eece9fd3 100644
--- a/arch/mips/configs/jazz_defconfig
+++ b/arch/mips/configs/jazz_defconfig
@@ -25,9 +25,7 @@ CONFIG_ZONE_DMA=y
25# CONFIG_BASLER_EXCITE is not set 25# CONFIG_BASLER_EXCITE is not set
26# CONFIG_MIPS_COBALT is not set 26# CONFIG_MIPS_COBALT is not set
27# CONFIG_MACH_DECSTATION is not set 27# CONFIG_MACH_DECSTATION is not set
28# CONFIG_MIPS_EV64120 is not set
29CONFIG_MACH_JAZZ=y 28CONFIG_MACH_JAZZ=y
30# CONFIG_LASAT is not set
31# CONFIG_MIPS_ATLAS is not set 29# CONFIG_MIPS_ATLAS is not set
32# CONFIG_MIPS_MALTA is not set 30# CONFIG_MIPS_MALTA is not set
33# CONFIG_MIPS_SEAD is not set 31# CONFIG_MIPS_SEAD is not set
@@ -35,8 +33,6 @@ CONFIG_MACH_JAZZ=y
35# CONFIG_MIPS_SIM is not set 33# CONFIG_MIPS_SIM is not set
36# CONFIG_MOMENCO_JAGUAR_ATX is not set 34# CONFIG_MOMENCO_JAGUAR_ATX is not set
37# CONFIG_MOMENCO_OCELOT is not set 35# CONFIG_MOMENCO_OCELOT is not set
38# CONFIG_MOMENCO_OCELOT_3 is not set
39# CONFIG_MOMENCO_OCELOT_C is not set
40# CONFIG_MOMENCO_OCELOT_G is not set 36# CONFIG_MOMENCO_OCELOT_G is not set
41# CONFIG_MIPS_XXS1500 is not set 37# CONFIG_MIPS_XXS1500 is not set
42# CONFIG_PNX8550_JBS is not set 38# CONFIG_PNX8550_JBS is not set
diff --git a/arch/mips/configs/jmr3927_defconfig b/arch/mips/configs/jmr3927_defconfig
index 1b364cf69140..9a25e770abd8 100644
--- a/arch/mips/configs/jmr3927_defconfig
+++ b/arch/mips/configs/jmr3927_defconfig
@@ -25,9 +25,7 @@ CONFIG_ZONE_DMA=y
25# CONFIG_BASLER_EXCITE is not set 25# CONFIG_BASLER_EXCITE is not set
26# CONFIG_MIPS_COBALT is not set 26# CONFIG_MIPS_COBALT is not set
27# CONFIG_MACH_DECSTATION is not set 27# CONFIG_MACH_DECSTATION is not set
28# CONFIG_MIPS_EV64120 is not set
29# CONFIG_MACH_JAZZ is not set 28# CONFIG_MACH_JAZZ is not set
30# CONFIG_LASAT is not set
31# CONFIG_MIPS_ATLAS is not set 29# CONFIG_MIPS_ATLAS is not set
32# CONFIG_MIPS_MALTA is not set 30# CONFIG_MIPS_MALTA is not set
33# CONFIG_MIPS_SEAD is not set 31# CONFIG_MIPS_SEAD is not set
@@ -35,8 +33,6 @@ CONFIG_ZONE_DMA=y
35# CONFIG_MIPS_SIM is not set 33# CONFIG_MIPS_SIM is not set
36# CONFIG_MOMENCO_JAGUAR_ATX is not set 34# CONFIG_MOMENCO_JAGUAR_ATX is not set
37# CONFIG_MOMENCO_OCELOT is not set 35# CONFIG_MOMENCO_OCELOT is not set
38# CONFIG_MOMENCO_OCELOT_3 is not set
39# CONFIG_MOMENCO_OCELOT_C is not set
40# CONFIG_MOMENCO_OCELOT_G is not set 36# CONFIG_MOMENCO_OCELOT_G is not set
41# CONFIG_MIPS_XXS1500 is not set 37# CONFIG_MIPS_XXS1500 is not set
42# CONFIG_PNX8550_JBS is not set 38# CONFIG_PNX8550_JBS is not set
diff --git a/arch/mips/configs/lasat200_defconfig b/arch/mips/configs/lasat200_defconfig
deleted file mode 100644
index fd4272c1458a..000000000000
--- a/arch/mips/configs/lasat200_defconfig
+++ /dev/null
@@ -1,1118 +0,0 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.20
4# Tue Feb 20 21:47:34 2007
5#
6CONFIG_MIPS=y
7
8#
9# Machine selection
10#
11CONFIG_ZONE_DMA=y
12# CONFIG_MIPS_MTX1 is not set
13# CONFIG_MIPS_BOSPORUS is not set
14# CONFIG_MIPS_PB1000 is not set
15# CONFIG_MIPS_PB1100 is not set
16# CONFIG_MIPS_PB1500 is not set
17# CONFIG_MIPS_PB1550 is not set
18# CONFIG_MIPS_PB1200 is not set
19# CONFIG_MIPS_DB1000 is not set
20# CONFIG_MIPS_DB1100 is not set
21# CONFIG_MIPS_DB1500 is not set
22# CONFIG_MIPS_DB1550 is not set
23# CONFIG_MIPS_DB1200 is not set
24# CONFIG_MIPS_MIRAGE is not set
25# CONFIG_BASLER_EXCITE is not set
26# CONFIG_MIPS_COBALT is not set
27# CONFIG_MACH_DECSTATION is not set
28# CONFIG_MIPS_EV64120 is not set
29# CONFIG_MACH_JAZZ is not set
30CONFIG_LASAT=y
31# CONFIG_MIPS_ATLAS is not set
32# CONFIG_MIPS_MALTA is not set
33# CONFIG_MIPS_SEAD is not set
34# CONFIG_WR_PPMC is not set
35# CONFIG_MIPS_SIM is not set
36# CONFIG_MOMENCO_JAGUAR_ATX is not set
37# CONFIG_MOMENCO_OCELOT is not set
38# CONFIG_MOMENCO_OCELOT_3 is not set
39# CONFIG_MOMENCO_OCELOT_C is not set
40# CONFIG_MOMENCO_OCELOT_G is not set
41# CONFIG_MIPS_XXS1500 is not set
42# CONFIG_PNX8550_JBS is not set
43# CONFIG_PNX8550_STB810 is not set
44# CONFIG_DDB5477 is not set
45# CONFIG_MACH_VR41XX is not set
46# CONFIG_PMC_YOSEMITE is not set
47# CONFIG_QEMU is not set
48# CONFIG_MARKEINS is not set
49# CONFIG_SGI_IP22 is not set
50# CONFIG_SGI_IP27 is not set
51# CONFIG_SGI_IP32 is not set
52# CONFIG_SIBYTE_BIGSUR is not set
53# CONFIG_SIBYTE_SWARM is not set
54# CONFIG_SIBYTE_SENTOSA is not set
55# CONFIG_SIBYTE_RHONE is not set
56# CONFIG_SIBYTE_CARMEL is not set
57# CONFIG_SIBYTE_PTSWARM is not set
58# CONFIG_SIBYTE_LITTLESUR is not set
59# CONFIG_SIBYTE_CRHINE is not set
60# CONFIG_SIBYTE_CRHONE is not set
61# CONFIG_SNI_RM is not set
62# CONFIG_TOSHIBA_JMR3927 is not set
63# CONFIG_TOSHIBA_RBTX4927 is not set
64# CONFIG_TOSHIBA_RBTX4938 is not set
65CONFIG_PICVUE=y
66CONFIG_PICVUE_PROC=y
67CONFIG_DS1603=y
68CONFIG_LASAT_SYSCTL=y
69CONFIG_RWSEM_GENERIC_SPINLOCK=y
70# CONFIG_ARCH_HAS_ILOG2_U32 is not set
71# CONFIG_ARCH_HAS_ILOG2_U64 is not set
72CONFIG_GENERIC_FIND_NEXT_BIT=y
73CONFIG_GENERIC_HWEIGHT=y
74CONFIG_GENERIC_CALIBRATE_DELAY=y
75CONFIG_GENERIC_TIME=y
76CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
77CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
78CONFIG_DMA_NONCOHERENT=y
79CONFIG_DMA_NEED_PCI_MAP_STATE=y
80CONFIG_MIPS_NILE4=y
81# CONFIG_CPU_BIG_ENDIAN is not set
82CONFIG_CPU_LITTLE_ENDIAN=y
83CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
84CONFIG_MIPS_GT64120=y
85CONFIG_MIPS_L1_CACHE_SHIFT=5
86
87#
88# CPU selection
89#
90# CONFIG_CPU_MIPS32_R1 is not set
91# CONFIG_CPU_MIPS32_R2 is not set
92# CONFIG_CPU_MIPS64_R1 is not set
93# CONFIG_CPU_MIPS64_R2 is not set
94# CONFIG_CPU_R3000 is not set
95# CONFIG_CPU_TX39XX is not set
96# CONFIG_CPU_VR41XX is not set
97# CONFIG_CPU_R4300 is not set
98# CONFIG_CPU_R4X00 is not set
99# CONFIG_CPU_TX49XX is not set
100CONFIG_CPU_R5000=y
101# CONFIG_CPU_R5432 is not set
102# CONFIG_CPU_R6000 is not set
103# CONFIG_CPU_NEVADA is not set
104# CONFIG_CPU_R8000 is not set
105# CONFIG_CPU_R10000 is not set
106# CONFIG_CPU_RM7000 is not set
107# CONFIG_CPU_RM9000 is not set
108# CONFIG_CPU_SB1 is not set
109CONFIG_SYS_HAS_CPU_R5000=y
110CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
111CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
112CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
113CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
114
115#
116# Kernel type
117#
118CONFIG_32BIT=y
119# CONFIG_64BIT is not set
120CONFIG_PAGE_SIZE_4KB=y
121# CONFIG_PAGE_SIZE_8KB is not set
122# CONFIG_PAGE_SIZE_16KB is not set
123# CONFIG_PAGE_SIZE_64KB is not set
124CONFIG_BOARD_SCACHE=y
125CONFIG_R5000_CPU_SCACHE=y
126CONFIG_MIPS_MT_DISABLED=y
127# CONFIG_MIPS_MT_SMP is not set
128# CONFIG_MIPS_MT_SMTC is not set
129# CONFIG_MIPS_VPE_LOADER is not set
130# CONFIG_64BIT_PHYS_ADDR is not set
131CONFIG_CPU_HAS_LLSC=y
132CONFIG_CPU_HAS_SYNC=y
133CONFIG_GENERIC_HARDIRQS=y
134CONFIG_GENERIC_IRQ_PROBE=y
135CONFIG_ARCH_FLATMEM_ENABLE=y
136CONFIG_SELECT_MEMORY_MODEL=y
137CONFIG_FLATMEM_MANUAL=y
138# CONFIG_DISCONTIGMEM_MANUAL is not set
139# CONFIG_SPARSEMEM_MANUAL is not set
140CONFIG_FLATMEM=y
141CONFIG_FLAT_NODE_MEM_MAP=y
142# CONFIG_SPARSEMEM_STATIC is not set
143CONFIG_SPLIT_PTLOCK_CPUS=4
144# CONFIG_RESOURCES_64BIT is not set
145CONFIG_ZONE_DMA_FLAG=1
146# CONFIG_HZ_48 is not set
147# CONFIG_HZ_100 is not set
148# CONFIG_HZ_128 is not set
149# CONFIG_HZ_250 is not set
150# CONFIG_HZ_256 is not set
151CONFIG_HZ_1000=y
152# CONFIG_HZ_1024 is not set
153CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
154CONFIG_HZ=1000
155CONFIG_PREEMPT_NONE=y
156# CONFIG_PREEMPT_VOLUNTARY is not set
157# CONFIG_PREEMPT is not set
158# CONFIG_KEXEC is not set
159CONFIG_LOCKDEP_SUPPORT=y
160CONFIG_STACKTRACE_SUPPORT=y
161CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
162
163#
164# Code maturity level options
165#
166CONFIG_EXPERIMENTAL=y
167CONFIG_BROKEN_ON_SMP=y
168CONFIG_INIT_ENV_ARG_LIMIT=32
169
170#
171# General setup
172#
173CONFIG_LOCALVERSION=""
174CONFIG_LOCALVERSION_AUTO=y
175CONFIG_SWAP=y
176CONFIG_SYSVIPC=y
177# CONFIG_IPC_NS is not set
178CONFIG_SYSVIPC_SYSCTL=y
179# CONFIG_POSIX_MQUEUE is not set
180# CONFIG_BSD_PROCESS_ACCT is not set
181# CONFIG_TASKSTATS is not set
182# CONFIG_UTS_NS is not set
183# CONFIG_AUDIT is not set
184# CONFIG_IKCONFIG is not set
185CONFIG_SYSFS_DEPRECATED=y
186CONFIG_RELAY=y
187# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
188CONFIG_SYSCTL=y
189CONFIG_EMBEDDED=y
190CONFIG_SYSCTL_SYSCALL=y
191CONFIG_KALLSYMS=y
192# CONFIG_KALLSYMS_EXTRA_PASS is not set
193CONFIG_HOTPLUG=y
194CONFIG_PRINTK=y
195CONFIG_BUG=y
196CONFIG_ELF_CORE=y
197CONFIG_BASE_FULL=y
198CONFIG_FUTEX=y
199CONFIG_EPOLL=y
200CONFIG_SHMEM=y
201CONFIG_SLAB=y
202CONFIG_VM_EVENT_COUNTERS=y
203CONFIG_RT_MUTEXES=y
204# CONFIG_TINY_SHMEM is not set
205CONFIG_BASE_SMALL=0
206# CONFIG_SLOB is not set
207
208#
209# Loadable module support
210#
211CONFIG_MODULES=y
212CONFIG_MODULE_UNLOAD=y
213# CONFIG_MODULE_FORCE_UNLOAD is not set
214CONFIG_MODVERSIONS=y
215CONFIG_MODULE_SRCVERSION_ALL=y
216CONFIG_KMOD=y
217
218#
219# Block layer
220#
221CONFIG_BLOCK=y
222# CONFIG_LBD is not set
223# CONFIG_BLK_DEV_IO_TRACE is not set
224# CONFIG_LSF is not set
225
226#
227# IO Schedulers
228#
229CONFIG_IOSCHED_NOOP=y
230CONFIG_IOSCHED_AS=y
231CONFIG_IOSCHED_DEADLINE=y
232CONFIG_IOSCHED_CFQ=y
233CONFIG_DEFAULT_AS=y
234# CONFIG_DEFAULT_DEADLINE is not set
235# CONFIG_DEFAULT_CFQ is not set
236# CONFIG_DEFAULT_NOOP is not set
237CONFIG_DEFAULT_IOSCHED="anticipatory"
238
239#
240# Bus options (PCI, PCMCIA, EISA, ISA, TC)
241#
242CONFIG_HW_HAS_PCI=y
243CONFIG_PCI=y
244CONFIG_MMU=y
245
246#
247# PCCARD (PCMCIA/CardBus) support
248#
249# CONFIG_PCCARD is not set
250
251#
252# PCI Hotplug Support
253#
254# CONFIG_HOTPLUG_PCI is not set
255
256#
257# Executable file formats
258#
259CONFIG_BINFMT_ELF=y
260# CONFIG_BINFMT_MISC is not set
261CONFIG_TRAD_SIGNALS=y
262
263#
264# Power management options
265#
266CONFIG_PM=y
267# CONFIG_PM_LEGACY is not set
268# CONFIG_PM_DEBUG is not set
269# CONFIG_PM_SYSFS_DEPRECATED is not set
270
271#
272# Networking
273#
274CONFIG_NET=y
275
276#
277# Networking options
278#
279# CONFIG_NETDEBUG is not set
280# CONFIG_PACKET is not set
281CONFIG_UNIX=y
282CONFIG_XFRM=y
283CONFIG_XFRM_USER=m
284# CONFIG_XFRM_SUB_POLICY is not set
285CONFIG_XFRM_MIGRATE=y
286CONFIG_NET_KEY=y
287CONFIG_NET_KEY_MIGRATE=y
288CONFIG_INET=y
289# CONFIG_IP_MULTICAST is not set
290# CONFIG_IP_ADVANCED_ROUTER is not set
291CONFIG_IP_FIB_HASH=y
292# CONFIG_IP_PNP is not set
293# CONFIG_NET_IPIP is not set
294# CONFIG_NET_IPGRE is not set
295# CONFIG_ARPD is not set
296# CONFIG_SYN_COOKIES is not set
297# CONFIG_INET_AH is not set
298# CONFIG_INET_ESP is not set
299# CONFIG_INET_IPCOMP is not set
300# CONFIG_INET_XFRM_TUNNEL is not set
301# CONFIG_INET_TUNNEL is not set
302CONFIG_INET_XFRM_MODE_TRANSPORT=m
303CONFIG_INET_XFRM_MODE_TUNNEL=m
304CONFIG_INET_XFRM_MODE_BEET=m
305CONFIG_INET_DIAG=y
306CONFIG_INET_TCP_DIAG=y
307# CONFIG_TCP_CONG_ADVANCED is not set
308CONFIG_TCP_CONG_CUBIC=y
309CONFIG_DEFAULT_TCP_CONG="cubic"
310CONFIG_TCP_MD5SIG=y
311# CONFIG_IPV6 is not set
312# CONFIG_INET6_XFRM_TUNNEL is not set
313# CONFIG_INET6_TUNNEL is not set
314CONFIG_NETWORK_SECMARK=y
315# CONFIG_NETFILTER is not set
316
317#
318# DCCP Configuration (EXPERIMENTAL)
319#
320# CONFIG_IP_DCCP is not set
321
322#
323# SCTP Configuration (EXPERIMENTAL)
324#
325# CONFIG_IP_SCTP is not set
326
327#
328# TIPC Configuration (EXPERIMENTAL)
329#
330# CONFIG_TIPC is not set
331# CONFIG_ATM is not set
332# CONFIG_BRIDGE is not set
333# CONFIG_VLAN_8021Q is not set
334# CONFIG_DECNET is not set
335# CONFIG_LLC2 is not set
336# CONFIG_IPX is not set
337# CONFIG_ATALK is not set
338# CONFIG_X25 is not set
339# CONFIG_LAPB is not set
340# CONFIG_ECONET is not set
341# CONFIG_WAN_ROUTER is not set
342
343#
344# QoS and/or fair queueing
345#
346# CONFIG_NET_SCHED is not set
347
348#
349# Network testing
350#
351# CONFIG_NET_PKTGEN is not set
352# CONFIG_HAMRADIO is not set
353# CONFIG_IRDA is not set
354# CONFIG_BT is not set
355CONFIG_IEEE80211=m
356# CONFIG_IEEE80211_DEBUG is not set
357CONFIG_IEEE80211_CRYPT_WEP=m
358CONFIG_IEEE80211_CRYPT_CCMP=m
359CONFIG_IEEE80211_SOFTMAC=m
360# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set
361CONFIG_WIRELESS_EXT=y
362
363#
364# Device Drivers
365#
366
367#
368# Generic Driver Options
369#
370CONFIG_STANDALONE=y
371CONFIG_PREVENT_FIRMWARE_BUILD=y
372CONFIG_FW_LOADER=m
373# CONFIG_SYS_HYPERVISOR is not set
374
375#
376# Connector - unified userspace <-> kernelspace linker
377#
378CONFIG_CONNECTOR=m
379
380#
381# Memory Technology Devices (MTD)
382#
383CONFIG_MTD=y
384# CONFIG_MTD_DEBUG is not set
385# CONFIG_MTD_CONCAT is not set
386CONFIG_MTD_PARTITIONS=y
387# CONFIG_MTD_REDBOOT_PARTS is not set
388# CONFIG_MTD_CMDLINE_PARTS is not set
389
390#
391# User Modules And Translation Layers
392#
393CONFIG_MTD_CHAR=y
394CONFIG_MTD_BLKDEVS=y
395CONFIG_MTD_BLOCK=y
396# CONFIG_FTL is not set
397# CONFIG_NFTL is not set
398# CONFIG_INFTL is not set
399# CONFIG_RFD_FTL is not set
400# CONFIG_SSFDC is not set
401
402#
403# RAM/ROM/Flash chip drivers
404#
405CONFIG_MTD_CFI=y
406# CONFIG_MTD_JEDECPROBE is not set
407CONFIG_MTD_GEN_PROBE=y
408# CONFIG_MTD_CFI_ADV_OPTIONS is not set
409CONFIG_MTD_MAP_BANK_WIDTH_1=y
410CONFIG_MTD_MAP_BANK_WIDTH_2=y
411CONFIG_MTD_MAP_BANK_WIDTH_4=y
412# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
413# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
414# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
415CONFIG_MTD_CFI_I1=y
416CONFIG_MTD_CFI_I2=y
417# CONFIG_MTD_CFI_I4 is not set
418# CONFIG_MTD_CFI_I8 is not set
419# CONFIG_MTD_CFI_INTELEXT is not set
420CONFIG_MTD_CFI_AMDSTD=y
421# CONFIG_MTD_CFI_STAA is not set
422CONFIG_MTD_CFI_UTIL=y
423# CONFIG_MTD_RAM is not set
424# CONFIG_MTD_ROM is not set
425# CONFIG_MTD_ABSENT is not set
426# CONFIG_MTD_OBSOLETE_CHIPS is not set
427
428#
429# Mapping drivers for chip access
430#
431# CONFIG_MTD_COMPLEX_MAPPINGS is not set
432# CONFIG_MTD_PHYSMAP is not set
433CONFIG_MTD_LASAT=y
434# CONFIG_MTD_PLATRAM is not set
435
436#
437# Self-contained MTD device drivers
438#
439# CONFIG_MTD_PMC551 is not set
440# CONFIG_MTD_SLRAM is not set
441# CONFIG_MTD_PHRAM is not set
442# CONFIG_MTD_MTDRAM is not set
443# CONFIG_MTD_BLOCK2MTD is not set
444
445#
446# Disk-On-Chip Device Drivers
447#
448# CONFIG_MTD_DOC2000 is not set
449# CONFIG_MTD_DOC2001 is not set
450# CONFIG_MTD_DOC2001PLUS is not set
451
452#
453# NAND Flash Device Drivers
454#
455# CONFIG_MTD_NAND is not set
456
457#
458# OneNAND Flash Device Drivers
459#
460# CONFIG_MTD_ONENAND is not set
461
462#
463# Parallel port support
464#
465# CONFIG_PARPORT is not set
466
467#
468# Plug and Play support
469#
470# CONFIG_PNPACPI is not set
471
472#
473# Block devices
474#
475# CONFIG_BLK_CPQ_DA is not set
476# CONFIG_BLK_CPQ_CISS_DA is not set
477# CONFIG_BLK_DEV_DAC960 is not set
478# CONFIG_BLK_DEV_UMEM is not set
479# CONFIG_BLK_DEV_COW_COMMON is not set
480# CONFIG_BLK_DEV_LOOP is not set
481# CONFIG_BLK_DEV_NBD is not set
482# CONFIG_BLK_DEV_SX8 is not set
483# CONFIG_BLK_DEV_RAM is not set
484# CONFIG_BLK_DEV_INITRD is not set
485CONFIG_CDROM_PKTCDVD=m
486CONFIG_CDROM_PKTCDVD_BUFFERS=8
487# CONFIG_CDROM_PKTCDVD_WCACHE is not set
488CONFIG_ATA_OVER_ETH=m
489
490#
491# Misc devices
492#
493CONFIG_SGI_IOC4=m
494# CONFIG_TIFM_CORE is not set
495
496#
497# ATA/ATAPI/MFM/RLL support
498#
499CONFIG_IDE=y
500CONFIG_IDE_MAX_HWIFS=4
501CONFIG_BLK_DEV_IDE=y
502
503#
504# Please see Documentation/ide.txt for help/info on IDE drives
505#
506# CONFIG_BLK_DEV_IDE_SATA is not set
507CONFIG_BLK_DEV_IDEDISK=y
508CONFIG_IDEDISK_MULTI_MODE=y
509# CONFIG_BLK_DEV_IDECD is not set
510# CONFIG_BLK_DEV_IDETAPE is not set
511# CONFIG_BLK_DEV_IDEFLOPPY is not set
512# CONFIG_IDE_TASK_IOCTL is not set
513
514#
515# IDE chipset support/bugfixes
516#
517CONFIG_IDE_GENERIC=y
518CONFIG_BLK_DEV_IDEPCI=y
519# CONFIG_IDEPCI_SHARE_IRQ is not set
520# CONFIG_BLK_DEV_OFFBOARD is not set
521CONFIG_BLK_DEV_GENERIC=y
522# CONFIG_BLK_DEV_OPTI621 is not set
523CONFIG_BLK_DEV_IDEDMA_PCI=y
524# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
525CONFIG_IDEDMA_PCI_AUTO=y
526# CONFIG_IDEDMA_ONLYDISK is not set
527# CONFIG_BLK_DEV_AEC62XX is not set
528# CONFIG_BLK_DEV_ALI15X3 is not set
529# CONFIG_BLK_DEV_AMD74XX is not set
530CONFIG_BLK_DEV_CMD64X=y
531# CONFIG_BLK_DEV_TRIFLEX is not set
532# CONFIG_BLK_DEV_CY82C693 is not set
533# CONFIG_BLK_DEV_CS5520 is not set
534# CONFIG_BLK_DEV_CS5530 is not set
535# CONFIG_BLK_DEV_HPT34X is not set
536# CONFIG_BLK_DEV_HPT366 is not set
537# CONFIG_BLK_DEV_JMICRON is not set
538# CONFIG_BLK_DEV_SC1200 is not set
539# CONFIG_BLK_DEV_PIIX is not set
540CONFIG_BLK_DEV_IT8213=m
541# CONFIG_BLK_DEV_IT821X is not set
542# CONFIG_BLK_DEV_NS87415 is not set
543# CONFIG_BLK_DEV_PDC202XX_OLD is not set
544# CONFIG_BLK_DEV_PDC202XX_NEW is not set
545# CONFIG_BLK_DEV_SVWKS is not set
546# CONFIG_BLK_DEV_SIIMAGE is not set
547# CONFIG_BLK_DEV_SLC90E66 is not set
548# CONFIG_BLK_DEV_TRM290 is not set
549# CONFIG_BLK_DEV_VIA82CXXX is not set
550CONFIG_BLK_DEV_TC86C001=m
551# CONFIG_IDE_ARM is not set
552CONFIG_BLK_DEV_IDEDMA=y
553# CONFIG_IDEDMA_IVB is not set
554CONFIG_IDEDMA_AUTO=y
555# CONFIG_BLK_DEV_HD is not set
556
557#
558# SCSI device support
559#
560CONFIG_RAID_ATTRS=m
561# CONFIG_SCSI is not set
562# CONFIG_SCSI_NETLINK is not set
563
564#
565# Serial ATA (prod) and Parallel ATA (experimental) drivers
566#
567# CONFIG_ATA is not set
568
569#
570# Multi-device support (RAID and LVM)
571#
572# CONFIG_MD is not set
573
574#
575# Fusion MPT device support
576#
577# CONFIG_FUSION is not set
578
579#
580# IEEE 1394 (FireWire) support
581#
582# CONFIG_IEEE1394 is not set
583
584#
585# I2O device support
586#
587# CONFIG_I2O is not set
588
589#
590# Network device support
591#
592CONFIG_NETDEVICES=y
593# CONFIG_DUMMY is not set
594# CONFIG_BONDING is not set
595# CONFIG_EQUALIZER is not set
596# CONFIG_TUN is not set
597
598#
599# ARCnet devices
600#
601# CONFIG_ARCNET is not set
602
603#
604# PHY device support
605#
606CONFIG_PHYLIB=m
607
608#
609# MII PHY device drivers
610#
611CONFIG_MARVELL_PHY=m
612CONFIG_DAVICOM_PHY=m
613CONFIG_QSEMI_PHY=m
614CONFIG_LXT_PHY=m
615CONFIG_CICADA_PHY=m
616CONFIG_VITESSE_PHY=m
617CONFIG_SMSC_PHY=m
618# CONFIG_BROADCOM_PHY is not set
619# CONFIG_FIXED_PHY is not set
620
621#
622# Ethernet (10 or 100Mbit)
623#
624CONFIG_NET_ETHERNET=y
625# CONFIG_MII is not set
626# CONFIG_HAPPYMEAL is not set
627# CONFIG_SUNGEM is not set
628# CONFIG_CASSINI is not set
629# CONFIG_NET_VENDOR_3COM is not set
630# CONFIG_DM9000 is not set
631
632#
633# Tulip family network device support
634#
635# CONFIG_NET_TULIP is not set
636# CONFIG_HP100 is not set
637# CONFIG_NET_PCI is not set
638
639#
640# Ethernet (1000 Mbit)
641#
642# CONFIG_ACENIC is not set
643# CONFIG_DL2K is not set
644# CONFIG_E1000 is not set
645# CONFIG_NS83820 is not set
646# CONFIG_HAMACHI is not set
647# CONFIG_YELLOWFIN is not set
648# CONFIG_R8169 is not set
649# CONFIG_SIS190 is not set
650# CONFIG_SKGE is not set
651# CONFIG_SKY2 is not set
652# CONFIG_SK98LIN is not set
653# CONFIG_TIGON3 is not set
654# CONFIG_BNX2 is not set
655CONFIG_QLA3XXX=m
656# CONFIG_ATL1 is not set
657
658#
659# Ethernet (10000 Mbit)
660#
661# CONFIG_CHELSIO_T1 is not set
662CONFIG_CHELSIO_T3=m
663# CONFIG_IXGB is not set
664# CONFIG_S2IO is not set
665# CONFIG_MYRI10GE is not set
666CONFIG_NETXEN_NIC=m
667
668#
669# Token Ring devices
670#
671# CONFIG_TR is not set
672
673#
674# Wireless LAN (non-hamradio)
675#
676# CONFIG_NET_RADIO is not set
677
678#
679# Wan interfaces
680#
681# CONFIG_WAN is not set
682# CONFIG_FDDI is not set
683# CONFIG_HIPPI is not set
684# CONFIG_PPP is not set
685# CONFIG_SLIP is not set
686# CONFIG_SHAPER is not set
687# CONFIG_NETCONSOLE is not set
688# CONFIG_NETPOLL is not set
689# CONFIG_NET_POLL_CONTROLLER is not set
690
691#
692# ISDN subsystem
693#
694# CONFIG_ISDN is not set
695
696#
697# Telephony Support
698#
699# CONFIG_PHONE is not set
700
701#
702# Input device support
703#
704CONFIG_INPUT=y
705# CONFIG_INPUT_FF_MEMLESS is not set
706
707#
708# Userland interfaces
709#
710CONFIG_INPUT_MOUSEDEV=y
711CONFIG_INPUT_MOUSEDEV_PSAUX=y
712CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
713CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
714# CONFIG_INPUT_JOYDEV is not set
715# CONFIG_INPUT_TSDEV is not set
716# CONFIG_INPUT_EVDEV is not set
717# CONFIG_INPUT_EVBUG is not set
718
719#
720# Input Device Drivers
721#
722# CONFIG_INPUT_KEYBOARD is not set
723# CONFIG_INPUT_MOUSE is not set
724# CONFIG_INPUT_JOYSTICK is not set
725# CONFIG_INPUT_TOUCHSCREEN is not set
726# CONFIG_INPUT_MISC is not set
727
728#
729# Hardware I/O ports
730#
731CONFIG_SERIO=y
732CONFIG_SERIO_I8042=y
733CONFIG_SERIO_SERPORT=y
734# CONFIG_SERIO_PCIPS2 is not set
735# CONFIG_SERIO_LIBPS2 is not set
736CONFIG_SERIO_RAW=m
737# CONFIG_GAMEPORT is not set
738
739#
740# Character devices
741#
742CONFIG_VT=y
743CONFIG_VT_CONSOLE=y
744CONFIG_HW_CONSOLE=y
745CONFIG_VT_HW_CONSOLE_BINDING=y
746# CONFIG_SERIAL_NONSTANDARD is not set
747
748#
749# Serial drivers
750#
751CONFIG_SERIAL_8250=y
752CONFIG_SERIAL_8250_CONSOLE=y
753CONFIG_SERIAL_8250_PCI=y
754CONFIG_SERIAL_8250_NR_UARTS=4
755CONFIG_SERIAL_8250_RUNTIME_UARTS=4
756# CONFIG_SERIAL_8250_EXTENDED is not set
757
758#
759# Non-8250 serial port support
760#
761CONFIG_SERIAL_CORE=y
762CONFIG_SERIAL_CORE_CONSOLE=y
763# CONFIG_SERIAL_JSM is not set
764CONFIG_UNIX98_PTYS=y
765CONFIG_LEGACY_PTYS=y
766CONFIG_LEGACY_PTY_COUNT=256
767
768#
769# IPMI
770#
771# CONFIG_IPMI_HANDLER is not set
772
773#
774# Watchdog Cards
775#
776# CONFIG_WATCHDOG is not set
777# CONFIG_HW_RANDOM is not set
778# CONFIG_RTC is not set
779# CONFIG_GEN_RTC is not set
780# CONFIG_DTLK is not set
781# CONFIG_R3964 is not set
782# CONFIG_APPLICOM is not set
783# CONFIG_DRM is not set
784# CONFIG_RAW_DRIVER is not set
785
786#
787# TPM devices
788#
789# CONFIG_TCG_TPM is not set
790
791#
792# I2C support
793#
794# CONFIG_I2C is not set
795
796#
797# SPI support
798#
799# CONFIG_SPI is not set
800# CONFIG_SPI_MASTER is not set
801
802#
803# Dallas's 1-wire bus
804#
805# CONFIG_W1 is not set
806
807#
808# Hardware Monitoring support
809#
810# CONFIG_HWMON is not set
811# CONFIG_HWMON_VID is not set
812
813#
814# Multimedia devices
815#
816# CONFIG_VIDEO_DEV is not set
817
818#
819# Digital Video Broadcasting Devices
820#
821# CONFIG_DVB is not set
822
823#
824# Graphics support
825#
826# CONFIG_FIRMWARE_EDID is not set
827# CONFIG_FB is not set
828
829#
830# Console display driver support
831#
832# CONFIG_VGA_CONSOLE is not set
833CONFIG_DUMMY_CONSOLE=y
834# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
835
836#
837# Sound
838#
839# CONFIG_SOUND is not set
840
841#
842# HID Devices
843#
844# CONFIG_HID is not set
845
846#
847# USB support
848#
849CONFIG_USB_ARCH_HAS_HCD=y
850CONFIG_USB_ARCH_HAS_OHCI=y
851CONFIG_USB_ARCH_HAS_EHCI=y
852# CONFIG_USB is not set
853
854#
855# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
856#
857
858#
859# USB Gadget Support
860#
861# CONFIG_USB_GADGET is not set
862
863#
864# MMC/SD Card support
865#
866# CONFIG_MMC is not set
867
868#
869# LED devices
870#
871# CONFIG_NEW_LEDS is not set
872
873#
874# LED drivers
875#
876
877#
878# LED Triggers
879#
880
881#
882# InfiniBand support
883#
884# CONFIG_INFINIBAND is not set
885
886#
887# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
888#
889
890#
891# Real Time Clock
892#
893# CONFIG_RTC_CLASS is not set
894
895#
896# DMA Engine support
897#
898# CONFIG_DMA_ENGINE is not set
899
900#
901# DMA Clients
902#
903
904#
905# DMA Devices
906#
907
908#
909# Auxiliary Display support
910#
911
912#
913# Virtualization
914#
915
916#
917# File systems
918#
919CONFIG_EXT2_FS=y
920# CONFIG_EXT2_FS_XATTR is not set
921# CONFIG_EXT2_FS_XIP is not set
922CONFIG_EXT3_FS=y
923CONFIG_EXT3_FS_XATTR=y
924# CONFIG_EXT3_FS_POSIX_ACL is not set
925CONFIG_EXT3_FS_SECURITY=y
926# CONFIG_EXT4DEV_FS is not set
927CONFIG_JBD=y
928# CONFIG_JBD_DEBUG is not set
929CONFIG_FS_MBCACHE=y
930# CONFIG_REISERFS_FS is not set
931# CONFIG_JFS_FS is not set
932CONFIG_FS_POSIX_ACL=y
933# CONFIG_XFS_FS is not set
934# CONFIG_GFS2_FS is not set
935# CONFIG_OCFS2_FS is not set
936# CONFIG_MINIX_FS is not set
937# CONFIG_ROMFS_FS is not set
938CONFIG_INOTIFY=y
939CONFIG_INOTIFY_USER=y
940# CONFIG_QUOTA is not set
941CONFIG_DNOTIFY=y
942# CONFIG_AUTOFS_FS is not set
943# CONFIG_AUTOFS4_FS is not set
944CONFIG_FUSE_FS=m
945CONFIG_GENERIC_ACL=y
946
947#
948# CD-ROM/DVD Filesystems
949#
950# CONFIG_ISO9660_FS is not set
951# CONFIG_UDF_FS is not set
952
953#
954# DOS/FAT/NT Filesystems
955#
956# CONFIG_MSDOS_FS is not set
957# CONFIG_VFAT_FS is not set
958# CONFIG_NTFS_FS is not set
959
960#
961# Pseudo filesystems
962#
963CONFIG_PROC_FS=y
964CONFIG_PROC_KCORE=y
965CONFIG_PROC_SYSCTL=y
966CONFIG_SYSFS=y
967CONFIG_TMPFS=y
968CONFIG_TMPFS_POSIX_ACL=y
969# CONFIG_HUGETLB_PAGE is not set
970CONFIG_RAMFS=y
971CONFIG_CONFIGFS_FS=m
972
973#
974# Miscellaneous filesystems
975#
976# CONFIG_ADFS_FS is not set
977# CONFIG_AFFS_FS is not set
978# CONFIG_ECRYPT_FS is not set
979# CONFIG_HFS_FS is not set
980# CONFIG_HFSPLUS_FS is not set
981# CONFIG_BEFS_FS is not set
982# CONFIG_BFS_FS is not set
983# CONFIG_EFS_FS is not set
984# CONFIG_JFFS2_FS is not set
985# CONFIG_CRAMFS is not set
986# CONFIG_VXFS_FS is not set
987# CONFIG_HPFS_FS is not set
988# CONFIG_QNX4FS_FS is not set
989# CONFIG_SYSV_FS is not set
990# CONFIG_UFS_FS is not set
991
992#
993# Network File Systems
994#
995CONFIG_NFS_FS=y
996CONFIG_NFS_V3=y
997# CONFIG_NFS_V3_ACL is not set
998# CONFIG_NFS_V4 is not set
999# CONFIG_NFS_DIRECTIO is not set
1000# CONFIG_NFSD is not set
1001CONFIG_LOCKD=y
1002CONFIG_LOCKD_V4=y
1003CONFIG_NFS_COMMON=y
1004CONFIG_SUNRPC=y
1005# CONFIG_RPCSEC_GSS_KRB5 is not set
1006# CONFIG_RPCSEC_GSS_SPKM3 is not set
1007# CONFIG_SMB_FS is not set
1008# CONFIG_CIFS is not set
1009# CONFIG_NCP_FS is not set
1010# CONFIG_CODA_FS is not set
1011# CONFIG_AFS_FS is not set
1012# CONFIG_9P_FS is not set
1013
1014#
1015# Partition Types
1016#
1017# CONFIG_PARTITION_ADVANCED is not set
1018CONFIG_MSDOS_PARTITION=y
1019
1020#
1021# Native Language Support
1022#
1023# CONFIG_NLS is not set
1024
1025#
1026# Distributed Lock Manager
1027#
1028CONFIG_DLM=m
1029CONFIG_DLM_TCP=y
1030# CONFIG_DLM_SCTP is not set
1031# CONFIG_DLM_DEBUG is not set
1032
1033#
1034# Profiling support
1035#
1036# CONFIG_PROFILING is not set
1037
1038#
1039# Kernel hacking
1040#
1041CONFIG_TRACE_IRQFLAGS_SUPPORT=y
1042# CONFIG_PRINTK_TIME is not set
1043CONFIG_ENABLE_MUST_CHECK=y
1044# CONFIG_MAGIC_SYSRQ is not set
1045# CONFIG_UNUSED_SYMBOLS is not set
1046# CONFIG_DEBUG_FS is not set
1047# CONFIG_HEADERS_CHECK is not set
1048# CONFIG_DEBUG_KERNEL is not set
1049CONFIG_LOG_BUF_SHIFT=14
1050CONFIG_CROSSCOMPILE=y
1051CONFIG_CMDLINE=""
1052
1053#
1054# Security options
1055#
1056CONFIG_KEYS=y
1057CONFIG_KEYS_DEBUG_PROC_KEYS=y
1058# CONFIG_SECURITY is not set
1059
1060#
1061# Cryptographic options
1062#
1063CONFIG_CRYPTO=y
1064CONFIG_CRYPTO_ALGAPI=y
1065CONFIG_CRYPTO_BLKCIPHER=m
1066CONFIG_CRYPTO_HASH=y
1067CONFIG_CRYPTO_MANAGER=y
1068CONFIG_CRYPTO_HMAC=y
1069CONFIG_CRYPTO_XCBC=m
1070CONFIG_CRYPTO_NULL=m
1071CONFIG_CRYPTO_MD4=m
1072CONFIG_CRYPTO_MD5=y
1073CONFIG_CRYPTO_SHA1=m
1074CONFIG_CRYPTO_SHA256=m
1075CONFIG_CRYPTO_SHA512=m
1076CONFIG_CRYPTO_WP512=m
1077CONFIG_CRYPTO_TGR192=m
1078CONFIG_CRYPTO_GF128MUL=m
1079CONFIG_CRYPTO_ECB=m
1080CONFIG_CRYPTO_CBC=m
1081CONFIG_CRYPTO_PCBC=m
1082CONFIG_CRYPTO_LRW=m
1083CONFIG_CRYPTO_DES=m
1084CONFIG_CRYPTO_FCRYPT=m
1085CONFIG_CRYPTO_BLOWFISH=m
1086CONFIG_CRYPTO_TWOFISH=m
1087CONFIG_CRYPTO_TWOFISH_COMMON=m
1088CONFIG_CRYPTO_SERPENT=m
1089CONFIG_CRYPTO_AES=m
1090CONFIG_CRYPTO_CAST5=m
1091CONFIG_CRYPTO_CAST6=m
1092CONFIG_CRYPTO_TEA=m
1093CONFIG_CRYPTO_ARC4=m
1094CONFIG_CRYPTO_KHAZAD=m
1095CONFIG_CRYPTO_ANUBIS=m
1096CONFIG_CRYPTO_DEFLATE=m
1097CONFIG_CRYPTO_MICHAEL_MIC=m
1098CONFIG_CRYPTO_CRC32C=m
1099CONFIG_CRYPTO_CAMELLIA=m
1100# CONFIG_CRYPTO_TEST is not set
1101
1102#
1103# Hardware crypto devices
1104#
1105
1106#
1107# Library routines
1108#
1109CONFIG_BITREVERSE=y
1110# CONFIG_CRC_CCITT is not set
1111CONFIG_CRC16=m
1112CONFIG_CRC32=y
1113CONFIG_LIBCRC32C=m
1114CONFIG_ZLIB_INFLATE=m
1115CONFIG_ZLIB_DEFLATE=m
1116CONFIG_PLIST=y
1117CONFIG_HAS_IOMEM=y
1118CONFIG_HAS_IOPORT=y
diff --git a/arch/mips/configs/malta_defconfig b/arch/mips/configs/malta_defconfig
index 1f64d7632a03..546cb243fd09 100644
--- a/arch/mips/configs/malta_defconfig
+++ b/arch/mips/configs/malta_defconfig
@@ -25,9 +25,7 @@ CONFIG_ZONE_DMA=y
25# CONFIG_BASLER_EXCITE is not set 25# CONFIG_BASLER_EXCITE is not set
26# CONFIG_MIPS_COBALT is not set 26# CONFIG_MIPS_COBALT is not set
27# CONFIG_MACH_DECSTATION is not set 27# CONFIG_MACH_DECSTATION is not set
28# CONFIG_MIPS_EV64120 is not set
29# CONFIG_MACH_JAZZ is not set 28# CONFIG_MACH_JAZZ is not set
30# CONFIG_LASAT is not set
31# CONFIG_MIPS_ATLAS is not set 29# CONFIG_MIPS_ATLAS is not set
32CONFIG_MIPS_MALTA=y 30CONFIG_MIPS_MALTA=y
33# CONFIG_MIPS_SEAD is not set 31# CONFIG_MIPS_SEAD is not set
@@ -35,8 +33,6 @@ CONFIG_MIPS_MALTA=y
35# CONFIG_MIPS_SIM is not set 33# CONFIG_MIPS_SIM is not set
36# CONFIG_MOMENCO_JAGUAR_ATX is not set 34# CONFIG_MOMENCO_JAGUAR_ATX is not set
37# CONFIG_MOMENCO_OCELOT is not set 35# CONFIG_MOMENCO_OCELOT is not set
38# CONFIG_MOMENCO_OCELOT_3 is not set
39# CONFIG_MOMENCO_OCELOT_C is not set
40# CONFIG_MOMENCO_OCELOT_G is not set 36# CONFIG_MOMENCO_OCELOT_G is not set
41# CONFIG_MIPS_XXS1500 is not set 37# CONFIG_MIPS_XXS1500 is not set
42# CONFIG_PNX8550_JBS is not set 38# CONFIG_PNX8550_JBS is not set
diff --git a/arch/mips/configs/mipssim_defconfig b/arch/mips/configs/mipssim_defconfig
index a2db5c201216..6abad6f88313 100644
--- a/arch/mips/configs/mipssim_defconfig
+++ b/arch/mips/configs/mipssim_defconfig
@@ -25,9 +25,7 @@ CONFIG_ZONE_DMA=y
25# CONFIG_BASLER_EXCITE is not set 25# CONFIG_BASLER_EXCITE is not set
26# CONFIG_MIPS_COBALT is not set 26# CONFIG_MIPS_COBALT is not set
27# CONFIG_MACH_DECSTATION is not set 27# CONFIG_MACH_DECSTATION is not set
28# CONFIG_MIPS_EV64120 is not set
29# CONFIG_MACH_JAZZ is not set 28# CONFIG_MACH_JAZZ is not set
30# CONFIG_LASAT is not set
31# CONFIG_MIPS_ATLAS is not set 29# CONFIG_MIPS_ATLAS is not set
32# CONFIG_MIPS_MALTA is not set 30# CONFIG_MIPS_MALTA is not set
33# CONFIG_MIPS_SEAD is not set 31# CONFIG_MIPS_SEAD is not set
@@ -35,8 +33,6 @@ CONFIG_ZONE_DMA=y
35CONFIG_MIPS_SIM=y 33CONFIG_MIPS_SIM=y
36# CONFIG_MOMENCO_JAGUAR_ATX is not set 34# CONFIG_MOMENCO_JAGUAR_ATX is not set
37# CONFIG_MOMENCO_OCELOT is not set 35# CONFIG_MOMENCO_OCELOT is not set
38# CONFIG_MOMENCO_OCELOT_3 is not set
39# CONFIG_MOMENCO_OCELOT_C is not set
40# CONFIG_MOMENCO_OCELOT_G is not set 36# CONFIG_MOMENCO_OCELOT_G is not set
41# CONFIG_MIPS_XXS1500 is not set 37# CONFIG_MIPS_XXS1500 is not set
42# CONFIG_PNX8550_JBS is not set 38# CONFIG_PNX8550_JBS is not set
@@ -496,36 +492,23 @@ CONFIG_NETDEVICES=y
496# CONFIG_BONDING is not set 492# CONFIG_BONDING is not set
497# CONFIG_EQUALIZER is not set 493# CONFIG_EQUALIZER is not set
498# CONFIG_TUN is not set 494# CONFIG_TUN is not set
499 495# CONFIG_PHYLIB is not set
500#
501# PHY device support
502#
503 496
504# 497#
505# Ethernet (10 or 100Mbit) 498# Ethernet (10 or 100Mbit)
506# 499#
507# CONFIG_NET_ETHERNET is not set 500CONFIG_NET_ETHERNET=y
508 501# CONFIG_MII is not set
509# 502CONFIG_MIPS_SIM_NET=y
510# Ethernet (1000 Mbit) 503# CONFIG_DM9000 is not set
511# 504# CONFIG_NETDEV_1000 is not set
512 505# CONFIG_NETDEV_10000 is not set
513#
514# Ethernet (10000 Mbit)
515#
516
517#
518# Token Ring devices
519#
520
521#
522# Wireless LAN (non-hamradio)
523#
524# CONFIG_NET_RADIO is not set
525 506
526# 507#
527# Wan interfaces 508# Wireless LAN
528# 509#
510# CONFIG_WLAN_PRE80211 is not set
511# CONFIG_WLAN_80211 is not set
529# CONFIG_WAN is not set 512# CONFIG_WAN is not set
530# CONFIG_PPP is not set 513# CONFIG_PPP is not set
531# CONFIG_SLIP is not set 514# CONFIG_SLIP is not set
diff --git a/arch/mips/configs/mpc30x_defconfig b/arch/mips/configs/mpc30x_defconfig
index ad5c0bf87b2b..4981ce425d82 100644
--- a/arch/mips/configs/mpc30x_defconfig
+++ b/arch/mips/configs/mpc30x_defconfig
@@ -25,9 +25,7 @@ CONFIG_ZONE_DMA=y
25# CONFIG_BASLER_EXCITE is not set 25# CONFIG_BASLER_EXCITE is not set
26# CONFIG_MIPS_COBALT is not set 26# CONFIG_MIPS_COBALT is not set
27# CONFIG_MACH_DECSTATION is not set 27# CONFIG_MACH_DECSTATION is not set
28# CONFIG_MIPS_EV64120 is not set
29# CONFIG_MACH_JAZZ is not set 28# CONFIG_MACH_JAZZ is not set
30# CONFIG_LASAT is not set
31# CONFIG_MIPS_ATLAS is not set 29# CONFIG_MIPS_ATLAS is not set
32# CONFIG_MIPS_MALTA is not set 30# CONFIG_MIPS_MALTA is not set
33# CONFIG_MIPS_SEAD is not set 31# CONFIG_MIPS_SEAD is not set
@@ -35,8 +33,6 @@ CONFIG_ZONE_DMA=y
35# CONFIG_MIPS_SIM is not set 33# CONFIG_MIPS_SIM is not set
36# CONFIG_MOMENCO_JAGUAR_ATX is not set 34# CONFIG_MOMENCO_JAGUAR_ATX is not set
37# CONFIG_MOMENCO_OCELOT is not set 35# CONFIG_MOMENCO_OCELOT is not set
38# CONFIG_MOMENCO_OCELOT_3 is not set
39# CONFIG_MOMENCO_OCELOT_C is not set
40# CONFIG_MOMENCO_OCELOT_G is not set 36# CONFIG_MOMENCO_OCELOT_G is not set
41# CONFIG_MIPS_XXS1500 is not set 37# CONFIG_MIPS_XXS1500 is not set
42# CONFIG_PNX8550_JBS is not set 38# CONFIG_PNX8550_JBS is not set
diff --git a/arch/mips/configs/ocelot_3_defconfig b/arch/mips/configs/msp71xx_defconfig
index 28547313ce13..adca5f7ba533 100644
--- a/arch/mips/configs/ocelot_3_defconfig
+++ b/arch/mips/configs/msp71xx_defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.20 3# Linux kernel version: 2.6.21-rc4
4# Tue Feb 20 21:47:35 2007 4# Thu Apr 26 18:11:29 2007
5# 5#
6CONFIG_MIPS=y 6CONFIG_MIPS=y
7 7
@@ -25,9 +25,7 @@ CONFIG_ZONE_DMA=y
25# CONFIG_BASLER_EXCITE is not set 25# CONFIG_BASLER_EXCITE is not set
26# CONFIG_MIPS_COBALT is not set 26# CONFIG_MIPS_COBALT is not set
27# CONFIG_MACH_DECSTATION is not set 27# CONFIG_MACH_DECSTATION is not set
28# CONFIG_MIPS_EV64120 is not set
29# CONFIG_MACH_JAZZ is not set 28# CONFIG_MACH_JAZZ is not set
30# CONFIG_LASAT is not set
31# CONFIG_MIPS_ATLAS is not set 29# CONFIG_MIPS_ATLAS is not set
32# CONFIG_MIPS_MALTA is not set 30# CONFIG_MIPS_MALTA is not set
33# CONFIG_MIPS_SEAD is not set 31# CONFIG_MIPS_SEAD is not set
@@ -35,14 +33,13 @@ CONFIG_ZONE_DMA=y
35# CONFIG_MIPS_SIM is not set 33# CONFIG_MIPS_SIM is not set
36# CONFIG_MOMENCO_JAGUAR_ATX is not set 34# CONFIG_MOMENCO_JAGUAR_ATX is not set
37# CONFIG_MOMENCO_OCELOT is not set 35# CONFIG_MOMENCO_OCELOT is not set
38CONFIG_MOMENCO_OCELOT_3=y
39# CONFIG_MOMENCO_OCELOT_C is not set
40# CONFIG_MOMENCO_OCELOT_G is not set 36# CONFIG_MOMENCO_OCELOT_G is not set
41# CONFIG_MIPS_XXS1500 is not set 37# CONFIG_MIPS_XXS1500 is not set
42# CONFIG_PNX8550_JBS is not set 38# CONFIG_PNX8550_JBS is not set
43# CONFIG_PNX8550_STB810 is not set 39# CONFIG_PNX8550_STB810 is not set
44# CONFIG_DDB5477 is not set 40# CONFIG_DDB5477 is not set
45# CONFIG_MACH_VR41XX is not set 41# CONFIG_MACH_VR41XX is not set
42CONFIG_PMC_MSP=y
46# CONFIG_PMC_YOSEMITE is not set 43# CONFIG_PMC_YOSEMITE is not set
47# CONFIG_QEMU is not set 44# CONFIG_QEMU is not set
48# CONFIG_MARKEINS is not set 45# CONFIG_MARKEINS is not set
@@ -62,6 +59,16 @@ CONFIG_MOMENCO_OCELOT_3=y
62# CONFIG_TOSHIBA_JMR3927 is not set 59# CONFIG_TOSHIBA_JMR3927 is not set
63# CONFIG_TOSHIBA_RBTX4927 is not set 60# CONFIG_TOSHIBA_RBTX4927 is not set
64# CONFIG_TOSHIBA_RBTX4938 is not set 61# CONFIG_TOSHIBA_RBTX4938 is not set
62# CONFIG_PMC_MSP4200_EVAL is not set
63# CONFIG_PMC_MSP4200_GW is not set
64# CONFIG_PMC_MSP7120_EVAL is not set
65CONFIG_PMC_MSP7120_GW=y
66# CONFIG_PMC_MSP7120_FPGA is not set
67
68#
69# Options for PMC-Sierra MSP chipsets
70#
71CONFIG_PMC_MSP_EMBEDDED_ROOTFS=y
65CONFIG_RWSEM_GENERIC_SPINLOCK=y 72CONFIG_RWSEM_GENERIC_SPINLOCK=y
66# CONFIG_ARCH_HAS_ILOG2_U32 is not set 73# CONFIG_ARCH_HAS_ILOG2_U32 is not set
67# CONFIG_ARCH_HAS_ILOG2_U64 is not set 74# CONFIG_ARCH_HAS_ILOG2_U64 is not set
@@ -71,24 +78,24 @@ CONFIG_GENERIC_CALIBRATE_DELAY=y
71CONFIG_GENERIC_TIME=y 78CONFIG_GENERIC_TIME=y
72CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y 79CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
73# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set 80# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set
81CONFIG_BOOT_RAW=y
74CONFIG_DMA_NONCOHERENT=y 82CONFIG_DMA_NONCOHERENT=y
75CONFIG_DMA_NEED_PCI_MAP_STATE=y 83CONFIG_DMA_NEED_PCI_MAP_STATE=y
84CONFIG_NO_EXCEPT_FILL=y
76CONFIG_CPU_BIG_ENDIAN=y 85CONFIG_CPU_BIG_ENDIAN=y
77# CONFIG_CPU_LITTLE_ENDIAN is not set 86# CONFIG_CPU_LITTLE_ENDIAN is not set
78CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y 87CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
79CONFIG_IRQ_CPU=y 88CONFIG_IRQ_CPU=y
80CONFIG_IRQ_CPU_RM7K=y 89CONFIG_IRQ_MSP_CIC=y
81CONFIG_IRQ_MV64340=y 90CONFIG_MSP_USB=y
82CONFIG_PCI_MARVELL=y
83CONFIG_SWAP_IO_SPACE=y 91CONFIG_SWAP_IO_SPACE=y
84CONFIG_BOOT_ELF32=y
85CONFIG_MIPS_L1_CACHE_SHIFT=5 92CONFIG_MIPS_L1_CACHE_SHIFT=5
86 93
87# 94#
88# CPU selection 95# CPU selection
89# 96#
90# CONFIG_CPU_MIPS32_R1 is not set 97# CONFIG_CPU_MIPS32_R1 is not set
91# CONFIG_CPU_MIPS32_R2 is not set 98CONFIG_CPU_MIPS32_R2=y
92# CONFIG_CPU_MIPS64_R1 is not set 99# CONFIG_CPU_MIPS64_R1 is not set
93# CONFIG_CPU_MIPS64_R2 is not set 100# CONFIG_CPU_MIPS64_R2 is not set
94# CONFIG_CPU_R3000 is not set 101# CONFIG_CPU_R3000 is not set
@@ -104,14 +111,14 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
104# CONFIG_CPU_R8000 is not set 111# CONFIG_CPU_R8000 is not set
105# CONFIG_CPU_R10000 is not set 112# CONFIG_CPU_R10000 is not set
106# CONFIG_CPU_RM7000 is not set 113# CONFIG_CPU_RM7000 is not set
107CONFIG_CPU_RM9000=y 114# CONFIG_CPU_RM9000 is not set
108# CONFIG_CPU_SB1 is not set 115# CONFIG_CPU_SB1 is not set
109CONFIG_SYS_HAS_CPU_RM9000=y 116CONFIG_SYS_HAS_CPU_MIPS32_R1=y
110CONFIG_WEAK_ORDERING=y 117CONFIG_SYS_HAS_CPU_MIPS32_R2=y
118CONFIG_CPU_MIPS32=y
119CONFIG_CPU_MIPSR2=y
111CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y 120CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
112CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
113CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y 121CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
114CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
115 122
116# 123#
117# Kernel type 124# Kernel type
@@ -122,13 +129,12 @@ CONFIG_PAGE_SIZE_4KB=y
122# CONFIG_PAGE_SIZE_8KB is not set 129# CONFIG_PAGE_SIZE_8KB is not set
123# CONFIG_PAGE_SIZE_16KB is not set 130# CONFIG_PAGE_SIZE_16KB is not set
124# CONFIG_PAGE_SIZE_64KB is not set 131# CONFIG_PAGE_SIZE_64KB is not set
125CONFIG_BOARD_SCACHE=y
126CONFIG_RM7000_CPU_SCACHE=y
127CONFIG_CPU_HAS_PREFETCH=y 132CONFIG_CPU_HAS_PREFETCH=y
128CONFIG_MIPS_MT_DISABLED=y 133CONFIG_MIPS_MT_DISABLED=y
129# CONFIG_MIPS_MT_SMP is not set 134# CONFIG_MIPS_MT_SMP is not set
130# CONFIG_MIPS_MT_SMTC is not set 135# CONFIG_MIPS_MT_SMTC is not set
131# CONFIG_MIPS_VPE_LOADER is not set 136# CONFIG_MIPS_VPE_LOADER is not set
137CONFIG_SYS_SUPPORTS_MULTITHREADING=y
132# CONFIG_64BIT_PHYS_ADDR is not set 138# CONFIG_64BIT_PHYS_ADDR is not set
133CONFIG_CPU_HAS_LLSC=y 139CONFIG_CPU_HAS_LLSC=y
134CONFIG_CPU_HAS_SYNC=y 140CONFIG_CPU_HAS_SYNC=y
@@ -149,15 +155,16 @@ CONFIG_ZONE_DMA_FLAG=1
149# CONFIG_HZ_48 is not set 155# CONFIG_HZ_48 is not set
150# CONFIG_HZ_100 is not set 156# CONFIG_HZ_100 is not set
151# CONFIG_HZ_128 is not set 157# CONFIG_HZ_128 is not set
152# CONFIG_HZ_250 is not set 158CONFIG_HZ_250=y
153# CONFIG_HZ_256 is not set 159# CONFIG_HZ_256 is not set
154CONFIG_HZ_1000=y 160# CONFIG_HZ_1000 is not set
155# CONFIG_HZ_1024 is not set 161# CONFIG_HZ_1024 is not set
156CONFIG_SYS_SUPPORTS_ARBIT_HZ=y 162CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
157CONFIG_HZ=1000 163CONFIG_HZ=250
158CONFIG_PREEMPT_NONE=y 164# CONFIG_PREEMPT_NONE is not set
159# CONFIG_PREEMPT_VOLUNTARY is not set 165# CONFIG_PREEMPT_VOLUNTARY is not set
160# CONFIG_PREEMPT is not set 166CONFIG_PREEMPT=y
167# CONFIG_PREEMPT_BKL is not set
161# CONFIG_KEXEC is not set 168# CONFIG_KEXEC is not set
162CONFIG_LOCKDEP_SUPPORT=y 169CONFIG_LOCKDEP_SUPPORT=y
163CONFIG_STACKTRACE_SUPPORT=y 170CONFIG_STACKTRACE_SUPPORT=y
@@ -168,14 +175,15 @@ CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
168# 175#
169CONFIG_EXPERIMENTAL=y 176CONFIG_EXPERIMENTAL=y
170CONFIG_BROKEN_ON_SMP=y 177CONFIG_BROKEN_ON_SMP=y
178CONFIG_LOCK_KERNEL=y
171CONFIG_INIT_ENV_ARG_LIMIT=32 179CONFIG_INIT_ENV_ARG_LIMIT=32
172 180
173# 181#
174# General setup 182# General setup
175# 183#
176CONFIG_LOCALVERSION="" 184CONFIG_LOCALVERSION="-pmc"
177CONFIG_LOCALVERSION_AUTO=y 185CONFIG_LOCALVERSION_AUTO=y
178CONFIG_SWAP=y 186# CONFIG_SWAP is not set
179CONFIG_SYSVIPC=y 187CONFIG_SYSVIPC=y
180# CONFIG_IPC_NS is not set 188# CONFIG_IPC_NS is not set
181CONFIG_SYSVIPC_SYSCTL=y 189CONFIG_SYSVIPC_SYSCTL=y
@@ -184,15 +192,16 @@ CONFIG_SYSVIPC_SYSCTL=y
184# CONFIG_TASKSTATS is not set 192# CONFIG_TASKSTATS is not set
185# CONFIG_UTS_NS is not set 193# CONFIG_UTS_NS is not set
186# CONFIG_AUDIT is not set 194# CONFIG_AUDIT is not set
187CONFIG_IKCONFIG=y 195# CONFIG_IKCONFIG is not set
188CONFIG_IKCONFIG_PROC=y
189CONFIG_SYSFS_DEPRECATED=y 196CONFIG_SYSFS_DEPRECATED=y
190CONFIG_RELAY=y 197# CONFIG_RELAY is not set
198# CONFIG_BLK_DEV_INITRD is not set
191# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set 199# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
192CONFIG_SYSCTL=y 200CONFIG_SYSCTL=y
193CONFIG_EMBEDDED=y 201CONFIG_EMBEDDED=y
194CONFIG_SYSCTL_SYSCALL=y 202CONFIG_SYSCTL_SYSCALL=y
195CONFIG_KALLSYMS=y 203CONFIG_KALLSYMS=y
204# CONFIG_KALLSYMS_ALL is not set
196# CONFIG_KALLSYMS_EXTRA_PASS is not set 205# CONFIG_KALLSYMS_EXTRA_PASS is not set
197CONFIG_HOTPLUG=y 206CONFIG_HOTPLUG=y
198CONFIG_PRINTK=y 207CONFIG_PRINTK=y
@@ -201,11 +210,11 @@ CONFIG_ELF_CORE=y
201CONFIG_BASE_FULL=y 210CONFIG_BASE_FULL=y
202CONFIG_FUTEX=y 211CONFIG_FUTEX=y
203CONFIG_EPOLL=y 212CONFIG_EPOLL=y
204CONFIG_SHMEM=y 213# CONFIG_SHMEM is not set
205CONFIG_SLAB=y 214CONFIG_SLAB=y
206CONFIG_VM_EVENT_COUNTERS=y 215CONFIG_VM_EVENT_COUNTERS=y
207CONFIG_RT_MUTEXES=y 216CONFIG_RT_MUTEXES=y
208# CONFIG_TINY_SHMEM is not set 217CONFIG_TINY_SHMEM=y
209CONFIG_BASE_SMALL=0 218CONFIG_BASE_SMALL=0
210# CONFIG_SLOB is not set 219# CONFIG_SLOB is not set
211 220
@@ -232,8 +241,8 @@ CONFIG_BLOCK=y
232# 241#
233CONFIG_IOSCHED_NOOP=y 242CONFIG_IOSCHED_NOOP=y
234CONFIG_IOSCHED_AS=y 243CONFIG_IOSCHED_AS=y
235CONFIG_IOSCHED_DEADLINE=y 244# CONFIG_IOSCHED_DEADLINE is not set
236CONFIG_IOSCHED_CFQ=y 245# CONFIG_IOSCHED_CFQ is not set
237CONFIG_DEFAULT_AS=y 246CONFIG_DEFAULT_AS=y
238# CONFIG_DEFAULT_DEADLINE is not set 247# CONFIG_DEFAULT_DEADLINE is not set
239# CONFIG_DEFAULT_CFQ is not set 248# CONFIG_DEFAULT_CFQ is not set
@@ -245,6 +254,7 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
245# 254#
246CONFIG_HW_HAS_PCI=y 255CONFIG_HW_HAS_PCI=y
247CONFIG_PCI=y 256CONFIG_PCI=y
257# CONFIG_PCI_DEBUG is not set
248CONFIG_MMU=y 258CONFIG_MMU=y
249 259
250# 260#
@@ -267,10 +277,7 @@ CONFIG_TRAD_SIGNALS=y
267# 277#
268# Power management options 278# Power management options
269# 279#
270CONFIG_PM=y 280# CONFIG_PM is not set
271# CONFIG_PM_LEGACY is not set
272# CONFIG_PM_DEBUG is not set
273# CONFIG_PM_SYSFS_DEPRECATED is not set
274 281
275# 282#
276# Networking 283# Networking
@@ -281,17 +288,16 @@ CONFIG_NET=y
281# Networking options 288# Networking options
282# 289#
283# CONFIG_NETDEBUG is not set 290# CONFIG_NETDEBUG is not set
284CONFIG_PACKET=y 291# CONFIG_PACKET is not set
285# CONFIG_PACKET_MMAP is not set
286CONFIG_UNIX=y 292CONFIG_UNIX=y
287CONFIG_XFRM=y 293CONFIG_XFRM=y
288# CONFIG_XFRM_USER is not set 294CONFIG_XFRM_USER=y
289# CONFIG_XFRM_SUB_POLICY is not set 295# CONFIG_XFRM_SUB_POLICY is not set
290CONFIG_XFRM_MIGRATE=y 296# CONFIG_XFRM_MIGRATE is not set
291CONFIG_NET_KEY=y 297CONFIG_NET_KEY=y
292CONFIG_NET_KEY_MIGRATE=y 298# CONFIG_NET_KEY_MIGRATE is not set
293CONFIG_INET=y 299CONFIG_INET=y
294# CONFIG_IP_MULTICAST is not set 300CONFIG_IP_MULTICAST=y
295# CONFIG_IP_ADVANCED_ROUTER is not set 301# CONFIG_IP_ADVANCED_ROUTER is not set
296CONFIG_IP_FIB_HASH=y 302CONFIG_IP_FIB_HASH=y
297CONFIG_IP_PNP=y 303CONFIG_IP_PNP=y
@@ -300,122 +306,92 @@ CONFIG_IP_PNP_BOOTP=y
300# CONFIG_IP_PNP_RARP is not set 306# CONFIG_IP_PNP_RARP is not set
301# CONFIG_NET_IPIP is not set 307# CONFIG_NET_IPIP is not set
302# CONFIG_NET_IPGRE is not set 308# CONFIG_NET_IPGRE is not set
309# CONFIG_IP_MROUTE is not set
303# CONFIG_ARPD is not set 310# CONFIG_ARPD is not set
304# CONFIG_SYN_COOKIES is not set 311# CONFIG_SYN_COOKIES is not set
305# CONFIG_INET_AH is not set 312CONFIG_INET_AH=y
306# CONFIG_INET_ESP is not set 313CONFIG_INET_ESP=y
307# CONFIG_INET_IPCOMP is not set 314CONFIG_INET_IPCOMP=y
308# CONFIG_INET_XFRM_TUNNEL is not set 315CONFIG_INET_XFRM_TUNNEL=y
309CONFIG_INET_TUNNEL=m 316CONFIG_INET_TUNNEL=y
310CONFIG_INET_XFRM_MODE_TRANSPORT=m 317CONFIG_INET_XFRM_MODE_TRANSPORT=y
311CONFIG_INET_XFRM_MODE_TUNNEL=m 318CONFIG_INET_XFRM_MODE_TUNNEL=y
312CONFIG_INET_XFRM_MODE_BEET=m 319CONFIG_INET_XFRM_MODE_BEET=y
313CONFIG_INET_DIAG=y 320CONFIG_INET_DIAG=y
314CONFIG_INET_TCP_DIAG=y 321CONFIG_INET_TCP_DIAG=y
315# CONFIG_TCP_CONG_ADVANCED is not set 322# CONFIG_TCP_CONG_ADVANCED is not set
316CONFIG_TCP_CONG_CUBIC=y 323CONFIG_TCP_CONG_CUBIC=y
317CONFIG_DEFAULT_TCP_CONG="cubic" 324CONFIG_DEFAULT_TCP_CONG="cubic"
318CONFIG_TCP_MD5SIG=y 325# CONFIG_TCP_MD5SIG is not set
319 326
320# 327#
321# IP: Virtual Server Configuration 328# IP: Virtual Server Configuration
322# 329#
323# CONFIG_IP_VS is not set 330# CONFIG_IP_VS is not set
324CONFIG_IPV6=m 331# CONFIG_IPV6 is not set
325# CONFIG_IPV6_PRIVACY is not set
326CONFIG_IPV6_ROUTER_PREF=y
327CONFIG_IPV6_ROUTE_INFO=y
328# CONFIG_INET6_AH is not set
329# CONFIG_INET6_ESP is not set
330# CONFIG_INET6_IPCOMP is not set
331CONFIG_IPV6_MIP6=y
332# CONFIG_INET6_XFRM_TUNNEL is not set 332# CONFIG_INET6_XFRM_TUNNEL is not set
333# CONFIG_INET6_TUNNEL is not set 333# CONFIG_INET6_TUNNEL is not set
334CONFIG_INET6_XFRM_MODE_TRANSPORT=m 334# CONFIG_NETWORK_SECMARK is not set
335CONFIG_INET6_XFRM_MODE_TUNNEL=m
336CONFIG_INET6_XFRM_MODE_BEET=m
337CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
338CONFIG_IPV6_SIT=m
339# CONFIG_IPV6_TUNNEL is not set
340CONFIG_IPV6_MULTIPLE_TABLES=y
341CONFIG_IPV6_SUBTREES=y
342CONFIG_NETWORK_SECMARK=y
343CONFIG_NETFILTER=y 335CONFIG_NETFILTER=y
344# CONFIG_NETFILTER_DEBUG is not set 336# CONFIG_NETFILTER_DEBUG is not set
337CONFIG_BRIDGE_NETFILTER=y
345 338
346# 339#
347# Core Netfilter Configuration 340# Core Netfilter Configuration
348# 341#
349CONFIG_NETFILTER_NETLINK=m 342# CONFIG_NETFILTER_NETLINK is not set
350CONFIG_NETFILTER_NETLINK_QUEUE=m 343# CONFIG_NF_CONNTRACK_ENABLED is not set
351CONFIG_NETFILTER_NETLINK_LOG=m 344CONFIG_NETFILTER_XTABLES=y
352CONFIG_NF_CONNTRACK_ENABLED=m 345# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set
353CONFIG_NF_CONNTRACK_SUPPORT=y 346# CONFIG_NETFILTER_XT_TARGET_MARK is not set
354# CONFIG_IP_NF_CONNTRACK_SUPPORT is not set 347# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set
355CONFIG_NF_CONNTRACK=m 348# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set
356CONFIG_NF_CT_ACCT=y 349# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set
357CONFIG_NF_CONNTRACK_MARK=y 350# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set
358CONFIG_NF_CONNTRACK_SECMARK=y 351# CONFIG_NETFILTER_XT_MATCH_DCCP is not set
359CONFIG_NF_CONNTRACK_EVENTS=y 352# CONFIG_NETFILTER_XT_MATCH_DSCP is not set
360CONFIG_NF_CT_PROTO_GRE=m 353# CONFIG_NETFILTER_XT_MATCH_ESP is not set
361CONFIG_NF_CT_PROTO_SCTP=m 354# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set
362CONFIG_NF_CONNTRACK_AMANDA=m 355# CONFIG_NETFILTER_XT_MATCH_LIMIT is not set
363CONFIG_NF_CONNTRACK_FTP=m 356# CONFIG_NETFILTER_XT_MATCH_MAC is not set
364CONFIG_NF_CONNTRACK_H323=m 357# CONFIG_NETFILTER_XT_MATCH_MARK is not set
365CONFIG_NF_CONNTRACK_IRC=m 358# CONFIG_NETFILTER_XT_MATCH_POLICY is not set
366# CONFIG_NF_CONNTRACK_NETBIOS_NS is not set 359# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set
367CONFIG_NF_CONNTRACK_PPTP=m 360# CONFIG_NETFILTER_XT_MATCH_PHYSDEV is not set
368CONFIG_NF_CONNTRACK_SANE=m 361# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set
369CONFIG_NF_CONNTRACK_SIP=m 362# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set
370CONFIG_NF_CONNTRACK_TFTP=m 363# CONFIG_NETFILTER_XT_MATCH_REALM is not set
371CONFIG_NF_CT_NETLINK=m 364# CONFIG_NETFILTER_XT_MATCH_SCTP is not set
372CONFIG_NETFILTER_XTABLES=m 365# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set
373CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m 366# CONFIG_NETFILTER_XT_MATCH_STRING is not set
374CONFIG_NETFILTER_XT_TARGET_MARK=m 367# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set
375CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m 368# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set
376CONFIG_NETFILTER_XT_TARGET_NFLOG=m
377CONFIG_NETFILTER_XT_TARGET_SECMARK=m
378CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
379CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
380CONFIG_NETFILTER_XT_MATCH_COMMENT=m
381CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
382CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
383CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
384CONFIG_NETFILTER_XT_MATCH_DCCP=m
385CONFIG_NETFILTER_XT_MATCH_DSCP=m
386CONFIG_NETFILTER_XT_MATCH_ESP=m
387CONFIG_NETFILTER_XT_MATCH_HELPER=m
388CONFIG_NETFILTER_XT_MATCH_LENGTH=m
389CONFIG_NETFILTER_XT_MATCH_LIMIT=m
390CONFIG_NETFILTER_XT_MATCH_MAC=m
391CONFIG_NETFILTER_XT_MATCH_MARK=m
392CONFIG_NETFILTER_XT_MATCH_POLICY=m
393CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
394CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
395CONFIG_NETFILTER_XT_MATCH_QUOTA=m
396CONFIG_NETFILTER_XT_MATCH_REALM=m
397CONFIG_NETFILTER_XT_MATCH_SCTP=m
398CONFIG_NETFILTER_XT_MATCH_STATE=m
399CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
400CONFIG_NETFILTER_XT_MATCH_STRING=m
401CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
402CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
403 369
404# 370#
405# IP: Netfilter Configuration 371# IP: Netfilter Configuration
406# 372#
407CONFIG_NF_CONNTRACK_IPV4=m
408CONFIG_NF_CONNTRACK_PROC_COMPAT=y
409# CONFIG_IP_NF_QUEUE is not set 373# CONFIG_IP_NF_QUEUE is not set
410# CONFIG_IP_NF_IPTABLES is not set 374CONFIG_IP_NF_IPTABLES=y
375# CONFIG_IP_NF_MATCH_IPRANGE is not set
376# CONFIG_IP_NF_MATCH_TOS is not set
377# CONFIG_IP_NF_MATCH_RECENT is not set
378# CONFIG_IP_NF_MATCH_ECN is not set
379# CONFIG_IP_NF_MATCH_AH is not set
380# CONFIG_IP_NF_MATCH_TTL is not set
381# CONFIG_IP_NF_MATCH_OWNER is not set
382# CONFIG_IP_NF_MATCH_ADDRTYPE is not set
383CONFIG_IP_NF_FILTER=y
384CONFIG_IP_NF_TARGET_REJECT=y
385# CONFIG_IP_NF_TARGET_LOG is not set
386# CONFIG_IP_NF_TARGET_ULOG is not set
387# CONFIG_IP_NF_MANGLE is not set
388# CONFIG_IP_NF_RAW is not set
411# CONFIG_IP_NF_ARPTABLES is not set 389# CONFIG_IP_NF_ARPTABLES is not set
412 390
413# 391#
414# IPv6: Netfilter Configuration (EXPERIMENTAL) 392# Bridge: Netfilter Configuration
415# 393#
416CONFIG_NF_CONNTRACK_IPV6=m 394# CONFIG_BRIDGE_NF_EBTABLES is not set
417# CONFIG_IP6_NF_QUEUE is not set
418# CONFIG_IP6_NF_IPTABLES is not set
419 395
420# 396#
421# DCCP Configuration (EXPERIMENTAL) 397# DCCP Configuration (EXPERIMENTAL)
@@ -432,9 +408,10 @@ CONFIG_NF_CONNTRACK_IPV6=m
432# 408#
433# CONFIG_TIPC is not set 409# CONFIG_TIPC is not set
434# CONFIG_ATM is not set 410# CONFIG_ATM is not set
435# CONFIG_BRIDGE is not set 411CONFIG_BRIDGE=y
436# CONFIG_VLAN_8021Q is not set 412# CONFIG_VLAN_8021Q is not set
437# CONFIG_DECNET is not set 413# CONFIG_DECNET is not set
414CONFIG_LLC=y
438# CONFIG_LLC2 is not set 415# CONFIG_LLC2 is not set
439# CONFIG_IPX is not set 416# CONFIG_IPX is not set
440# CONFIG_ATALK is not set 417# CONFIG_ATALK is not set
@@ -447,7 +424,6 @@ CONFIG_NF_CONNTRACK_IPV6=m
447# QoS and/or fair queueing 424# QoS and/or fair queueing
448# 425#
449# CONFIG_NET_SCHED is not set 426# CONFIG_NET_SCHED is not set
450CONFIG_NET_CLS_ROUTE=y
451 427
452# 428#
453# Network testing 429# Network testing
@@ -456,14 +432,8 @@ CONFIG_NET_CLS_ROUTE=y
456# CONFIG_HAMRADIO is not set 432# CONFIG_HAMRADIO is not set
457# CONFIG_IRDA is not set 433# CONFIG_IRDA is not set
458# CONFIG_BT is not set 434# CONFIG_BT is not set
459CONFIG_IEEE80211=m 435# CONFIG_IEEE80211 is not set
460# CONFIG_IEEE80211_DEBUG is not set
461CONFIG_IEEE80211_CRYPT_WEP=m
462CONFIG_IEEE80211_CRYPT_CCMP=m
463CONFIG_IEEE80211_SOFTMAC=m
464# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set
465CONFIG_WIRELESS_EXT=y 436CONFIG_WIRELESS_EXT=y
466CONFIG_FIB_RULES=y
467 437
468# 438#
469# Device Drivers 439# Device Drivers
@@ -473,19 +443,101 @@ CONFIG_FIB_RULES=y
473# Generic Driver Options 443# Generic Driver Options
474# 444#
475CONFIG_STANDALONE=y 445CONFIG_STANDALONE=y
476CONFIG_PREVENT_FIRMWARE_BUILD=y 446# CONFIG_PREVENT_FIRMWARE_BUILD is not set
477CONFIG_FW_LOADER=m 447# CONFIG_FW_LOADER is not set
448# CONFIG_DEBUG_DRIVER is not set
449# CONFIG_DEBUG_DEVRES is not set
478# CONFIG_SYS_HYPERVISOR is not set 450# CONFIG_SYS_HYPERVISOR is not set
479 451
480# 452#
481# Connector - unified userspace <-> kernelspace linker 453# Connector - unified userspace <-> kernelspace linker
482# 454#
483CONFIG_CONNECTOR=m 455# CONFIG_CONNECTOR is not set
484 456
485# 457#
486# Memory Technology Devices (MTD) 458# Memory Technology Devices (MTD)
487# 459#
488# CONFIG_MTD is not set 460CONFIG_MTD=y
461# CONFIG_MTD_DEBUG is not set
462# CONFIG_MTD_CONCAT is not set
463CONFIG_MTD_PARTITIONS=y
464# CONFIG_MTD_REDBOOT_PARTS is not set
465# CONFIG_MTD_CMDLINE_PARTS is not set
466
467#
468# User Modules And Translation Layers
469#
470CONFIG_MTD_CHAR=y
471CONFIG_MTD_BLKDEVS=y
472CONFIG_MTD_BLOCK=y
473# CONFIG_FTL is not set
474# CONFIG_NFTL is not set
475# CONFIG_INFTL is not set
476# CONFIG_RFD_FTL is not set
477# CONFIG_SSFDC is not set
478
479#
480# RAM/ROM/Flash chip drivers
481#
482CONFIG_MTD_CFI=y
483# CONFIG_MTD_JEDECPROBE is not set
484CONFIG_MTD_GEN_PROBE=y
485# CONFIG_MTD_CFI_ADV_OPTIONS is not set
486CONFIG_MTD_MAP_BANK_WIDTH_1=y
487CONFIG_MTD_MAP_BANK_WIDTH_2=y
488CONFIG_MTD_MAP_BANK_WIDTH_4=y
489# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
490# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
491# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
492CONFIG_MTD_CFI_I1=y
493CONFIG_MTD_CFI_I2=y
494# CONFIG_MTD_CFI_I4 is not set
495# CONFIG_MTD_CFI_I8 is not set
496# CONFIG_MTD_CFI_INTELEXT is not set
497CONFIG_MTD_CFI_AMDSTD=y
498# CONFIG_MTD_CFI_STAA is not set
499CONFIG_MTD_CFI_UTIL=y
500CONFIG_MTD_RAM=y
501# CONFIG_MTD_ROM is not set
502# CONFIG_MTD_ABSENT is not set
503# CONFIG_MTD_OBSOLETE_CHIPS is not set
504
505#
506# Mapping drivers for chip access
507#
508# CONFIG_MTD_COMPLEX_MAPPINGS is not set
509# CONFIG_MTD_PHYSMAP is not set
510CONFIG_MTD_PMC_MSP_EVM=y
511CONFIG_MSP_FLASH_MAP_LIMIT_32M=y
512CONFIG_MSP_FLASH_MAP_LIMIT=0x02000000
513CONFIG_MTD_PMC_MSP_RAMROOT=y
514# CONFIG_MTD_PLATRAM is not set
515
516#
517# Self-contained MTD device drivers
518#
519# CONFIG_MTD_PMC551 is not set
520# CONFIG_MTD_SLRAM is not set
521# CONFIG_MTD_PHRAM is not set
522# CONFIG_MTD_MTDRAM is not set
523# CONFIG_MTD_BLOCK2MTD is not set
524
525#
526# Disk-On-Chip Device Drivers
527#
528# CONFIG_MTD_DOC2000 is not set
529# CONFIG_MTD_DOC2001 is not set
530# CONFIG_MTD_DOC2001PLUS is not set
531
532#
533# NAND Flash Device Drivers
534#
535# CONFIG_MTD_NAND is not set
536
537#
538# OneNAND Flash Device Drivers
539#
540# CONFIG_MTD_ONENAND is not set
489 541
490# 542#
491# Parallel port support 543# Parallel port support
@@ -505,19 +557,21 @@ CONFIG_CONNECTOR=m
505# CONFIG_BLK_DEV_DAC960 is not set 557# CONFIG_BLK_DEV_DAC960 is not set
506# CONFIG_BLK_DEV_UMEM is not set 558# CONFIG_BLK_DEV_UMEM is not set
507# CONFIG_BLK_DEV_COW_COMMON is not set 559# CONFIG_BLK_DEV_COW_COMMON is not set
508CONFIG_BLK_DEV_LOOP=y 560# CONFIG_BLK_DEV_LOOP is not set
509# CONFIG_BLK_DEV_CRYPTOLOOP is not set
510# CONFIG_BLK_DEV_NBD is not set 561# CONFIG_BLK_DEV_NBD is not set
511# CONFIG_BLK_DEV_SX8 is not set 562# CONFIG_BLK_DEV_SX8 is not set
512# CONFIG_BLK_DEV_RAM is not set 563# CONFIG_BLK_DEV_UB is not set
513# CONFIG_BLK_DEV_INITRD is not set 564CONFIG_BLK_DEV_RAM=y
565CONFIG_BLK_DEV_RAM_COUNT=16
566CONFIG_BLK_DEV_RAM_SIZE=4096
567CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
514# CONFIG_CDROM_PKTCDVD is not set 568# CONFIG_CDROM_PKTCDVD is not set
515CONFIG_ATA_OVER_ETH=m 569# CONFIG_ATA_OVER_ETH is not set
516 570
517# 571#
518# Misc devices 572# Misc devices
519# 573#
520CONFIG_SGI_IOC4=m 574# CONFIG_SGI_IOC4 is not set
521# CONFIG_TIFM_CORE is not set 575# CONFIG_TIFM_CORE is not set
522 576
523# 577#
@@ -528,16 +582,16 @@ CONFIG_SGI_IOC4=m
528# 582#
529# SCSI device support 583# SCSI device support
530# 584#
531CONFIG_RAID_ATTRS=m 585# CONFIG_RAID_ATTRS is not set
532CONFIG_SCSI=m 586CONFIG_SCSI=y
533CONFIG_SCSI_TGT=m 587# CONFIG_SCSI_TGT is not set
534CONFIG_SCSI_NETLINK=y 588# CONFIG_SCSI_NETLINK is not set
535CONFIG_SCSI_PROC_FS=y 589CONFIG_SCSI_PROC_FS=y
536 590
537# 591#
538# SCSI support type (disk, tape, CD-ROM) 592# SCSI support type (disk, tape, CD-ROM)
539# 593#
540# CONFIG_BLK_DEV_SD is not set 594CONFIG_BLK_DEV_SD=y
541# CONFIG_CHR_DEV_ST is not set 595# CONFIG_CHR_DEV_ST is not set
542# CONFIG_CHR_DEV_OSST is not set 596# CONFIG_CHR_DEV_OSST is not set
543# CONFIG_BLK_DEV_SR is not set 597# CONFIG_BLK_DEV_SR is not set
@@ -550,22 +604,21 @@ CONFIG_SCSI_PROC_FS=y
550# CONFIG_SCSI_MULTI_LUN is not set 604# CONFIG_SCSI_MULTI_LUN is not set
551# CONFIG_SCSI_CONSTANTS is not set 605# CONFIG_SCSI_CONSTANTS is not set
552# CONFIG_SCSI_LOGGING is not set 606# CONFIG_SCSI_LOGGING is not set
553CONFIG_SCSI_SCAN_ASYNC=y 607# CONFIG_SCSI_SCAN_ASYNC is not set
554 608
555# 609#
556# SCSI Transports 610# SCSI Transports
557# 611#
558# CONFIG_SCSI_SPI_ATTRS is not set 612# CONFIG_SCSI_SPI_ATTRS is not set
559CONFIG_SCSI_FC_ATTRS=m 613# CONFIG_SCSI_FC_ATTRS is not set
560CONFIG_SCSI_ISCSI_ATTRS=m 614# CONFIG_SCSI_ISCSI_ATTRS is not set
561CONFIG_SCSI_SAS_ATTRS=m 615# CONFIG_SCSI_SAS_ATTRS is not set
562CONFIG_SCSI_SAS_LIBSAS=m 616# CONFIG_SCSI_SAS_LIBSAS is not set
563# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set
564 617
565# 618#
566# SCSI low-level drivers 619# SCSI low-level drivers
567# 620#
568CONFIG_ISCSI_TCP=m 621# CONFIG_ISCSI_TCP is not set
569# CONFIG_BLK_DEV_3W_XXXX_RAID is not set 622# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
570# CONFIG_SCSI_3W_9XXX is not set 623# CONFIG_SCSI_3W_9XXX is not set
571# CONFIG_SCSI_ACARD is not set 624# CONFIG_SCSI_ACARD is not set
@@ -573,8 +626,7 @@ CONFIG_ISCSI_TCP=m
573# CONFIG_SCSI_AIC7XXX is not set 626# CONFIG_SCSI_AIC7XXX is not set
574# CONFIG_SCSI_AIC7XXX_OLD is not set 627# CONFIG_SCSI_AIC7XXX_OLD is not set
575# CONFIG_SCSI_AIC79XX is not set 628# CONFIG_SCSI_AIC79XX is not set
576CONFIG_SCSI_AIC94XX=m 629# CONFIG_SCSI_AIC94XX is not set
577# CONFIG_AIC94XX_DEBUG is not set
578# CONFIG_SCSI_DPT_I2O is not set 630# CONFIG_SCSI_DPT_I2O is not set
579# CONFIG_SCSI_ARCMSR is not set 631# CONFIG_SCSI_ARCMSR is not set
580# CONFIG_MEGARAID_NEWGEN is not set 632# CONFIG_MEGARAID_NEWGEN is not set
@@ -630,10 +682,10 @@ CONFIG_SCSI_AIC94XX=m
630# Network device support 682# Network device support
631# 683#
632CONFIG_NETDEVICES=y 684CONFIG_NETDEVICES=y
633# CONFIG_DUMMY is not set 685CONFIG_DUMMY=y
634# CONFIG_BONDING is not set 686# CONFIG_BONDING is not set
635# CONFIG_EQUALIZER is not set 687# CONFIG_EQUALIZER is not set
636CONFIG_TUN=m 688# CONFIG_TUN is not set
637 689
638# 690#
639# ARCnet devices 691# ARCnet devices
@@ -643,26 +695,16 @@ CONFIG_TUN=m
643# 695#
644# PHY device support 696# PHY device support
645# 697#
646CONFIG_PHYLIB=m 698# CONFIG_PHYLIB is not set
647
648#
649# MII PHY device drivers
650#
651CONFIG_MARVELL_PHY=m
652CONFIG_DAVICOM_PHY=m
653CONFIG_QSEMI_PHY=m
654CONFIG_LXT_PHY=m
655CONFIG_CICADA_PHY=m
656CONFIG_VITESSE_PHY=m
657CONFIG_SMSC_PHY=m
658# CONFIG_BROADCOM_PHY is not set
659# CONFIG_FIXED_PHY is not set
660 699
661# 700#
662# Ethernet (10 or 100Mbit) 701# Ethernet (10 or 100Mbit)
663# 702#
664CONFIG_NET_ETHERNET=y 703CONFIG_NET_ETHERNET=y
665CONFIG_MII=y 704CONFIG_MII=y
705CONFIG_MSPETH=y
706CONFIG_MSPETH_NAPI=y
707# CONFIG_MSPETH_SKB_RECYCLE is not set
666# CONFIG_HAPPYMEAL is not set 708# CONFIG_HAPPYMEAL is not set
667# CONFIG_SUNGEM is not set 709# CONFIG_SUNGEM is not set
668# CONFIG_CASSINI is not set 710# CONFIG_CASSINI is not set
@@ -674,26 +716,7 @@ CONFIG_MII=y
674# 716#
675# CONFIG_NET_TULIP is not set 717# CONFIG_NET_TULIP is not set
676# CONFIG_HP100 is not set 718# CONFIG_HP100 is not set
677CONFIG_NET_PCI=y 719# CONFIG_NET_PCI is not set
678# CONFIG_PCNET32 is not set
679# CONFIG_AMD8111_ETH is not set
680# CONFIG_ADAPTEC_STARFIRE is not set
681# CONFIG_B44 is not set
682# CONFIG_FORCEDETH is not set
683# CONFIG_DGRS is not set
684# CONFIG_EEPRO100 is not set
685CONFIG_E100=y
686# CONFIG_FEALNX is not set
687# CONFIG_NATSEMI is not set
688# CONFIG_NE2K_PCI is not set
689# CONFIG_8139CP is not set
690# CONFIG_8139TOO is not set
691# CONFIG_SIS900 is not set
692# CONFIG_EPIC100 is not set
693# CONFIG_SUNDANCE is not set
694# CONFIG_TLAN is not set
695# CONFIG_VIA_RHINE is not set
696# CONFIG_SC92031 is not set
697 720
698# 721#
699# Ethernet (1000 Mbit) 722# Ethernet (1000 Mbit)
@@ -709,22 +732,20 @@ CONFIG_E100=y
709# CONFIG_SKGE is not set 732# CONFIG_SKGE is not set
710# CONFIG_SKY2 is not set 733# CONFIG_SKY2 is not set
711# CONFIG_SK98LIN is not set 734# CONFIG_SK98LIN is not set
712# CONFIG_VIA_VELOCITY is not set
713# CONFIG_TIGON3 is not set 735# CONFIG_TIGON3 is not set
714# CONFIG_BNX2 is not set 736# CONFIG_BNX2 is not set
715CONFIG_MV643XX_ETH=y 737# CONFIG_QLA3XXX is not set
716CONFIG_QLA3XXX=m
717# CONFIG_ATL1 is not set 738# CONFIG_ATL1 is not set
718 739
719# 740#
720# Ethernet (10000 Mbit) 741# Ethernet (10000 Mbit)
721# 742#
722# CONFIG_CHELSIO_T1 is not set 743# CONFIG_CHELSIO_T1 is not set
723CONFIG_CHELSIO_T3=m 744# CONFIG_CHELSIO_T3 is not set
724# CONFIG_IXGB is not set 745# CONFIG_IXGB is not set
725# CONFIG_S2IO is not set 746# CONFIG_S2IO is not set
726# CONFIG_MYRI10GE is not set 747# CONFIG_MYRI10GE is not set
727CONFIG_NETXEN_NIC=m 748# CONFIG_NETXEN_NIC is not set
728 749
729# 750#
730# Token Ring devices 751# Token Ring devices
@@ -734,7 +755,29 @@ CONFIG_NETXEN_NIC=m
734# 755#
735# Wireless LAN (non-hamradio) 756# Wireless LAN (non-hamradio)
736# 757#
737# CONFIG_NET_RADIO is not set 758CONFIG_NET_RADIO=y
759# CONFIG_NET_WIRELESS_RTNETLINK is not set
760
761#
762# Obsolete Wireless cards support (pre-802.11)
763#
764# CONFIG_STRIP is not set
765
766#
767# Wireless 802.11b ISA/PCI cards support
768#
769# CONFIG_IPW2100 is not set
770# CONFIG_IPW2200 is not set
771# CONFIG_HERMES is not set
772# CONFIG_ATMEL is not set
773
774#
775# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
776#
777# CONFIG_PRISM54 is not set
778# CONFIG_USB_ZD1201 is not set
779# CONFIG_HOSTAP is not set
780CONFIG_NET_WIRELESS=y
738 781
739# 782#
740# Wan interfaces 783# Wan interfaces
@@ -742,17 +785,17 @@ CONFIG_NETXEN_NIC=m
742# CONFIG_WAN is not set 785# CONFIG_WAN is not set
743# CONFIG_FDDI is not set 786# CONFIG_FDDI is not set
744# CONFIG_HIPPI is not set 787# CONFIG_HIPPI is not set
745CONFIG_PPP=m 788CONFIG_PPP=y
746# CONFIG_PPP_MULTILINK is not set 789# CONFIG_PPP_MULTILINK is not set
747# CONFIG_PPP_FILTER is not set 790# CONFIG_PPP_FILTER is not set
748CONFIG_PPP_ASYNC=m 791# CONFIG_PPP_ASYNC is not set
749CONFIG_PPP_SYNC_TTY=m 792# CONFIG_PPP_SYNC_TTY is not set
750CONFIG_PPP_DEFLATE=m 793# CONFIG_PPP_DEFLATE is not set
751# CONFIG_PPP_BSDCOMP is not set 794# CONFIG_PPP_BSDCOMP is not set
752CONFIG_PPP_MPPE=m 795# CONFIG_PPP_MPPE is not set
753CONFIG_PPPOE=m 796# CONFIG_PPPOE is not set
754# CONFIG_SLIP is not set 797# CONFIG_SLIP is not set
755CONFIG_SLHC=m 798CONFIG_SLHC=y
756# CONFIG_NET_FC is not set 799# CONFIG_NET_FC is not set
757# CONFIG_SHAPER is not set 800# CONFIG_SHAPER is not set
758# CONFIG_NETCONSOLE is not set 801# CONFIG_NETCONSOLE is not set
@@ -796,31 +839,24 @@ CONFIG_INPUT=y
796# 839#
797# Hardware I/O ports 840# Hardware I/O ports
798# 841#
799CONFIG_SERIO=y 842# CONFIG_SERIO is not set
800# CONFIG_SERIO_I8042 is not set
801# CONFIG_SERIO_SERPORT is not set
802# CONFIG_SERIO_PCIPS2 is not set
803# CONFIG_SERIO_LIBPS2 is not set
804# CONFIG_SERIO_RAW is not set
805# CONFIG_GAMEPORT is not set 843# CONFIG_GAMEPORT is not set
806 844
807# 845#
808# Character devices 846# Character devices
809# 847#
810CONFIG_VT=y 848# CONFIG_VT is not set
811CONFIG_VT_CONSOLE=y
812CONFIG_HW_CONSOLE=y
813CONFIG_VT_HW_CONSOLE_BINDING=y
814# CONFIG_SERIAL_NONSTANDARD is not set 849# CONFIG_SERIAL_NONSTANDARD is not set
850CONFIG_PMCMSP_GPIO=y
815 851
816# 852#
817# Serial drivers 853# Serial drivers
818# 854#
819CONFIG_SERIAL_8250=y 855CONFIG_SERIAL_8250=y
820CONFIG_SERIAL_8250_CONSOLE=y 856CONFIG_SERIAL_8250_CONSOLE=y
821CONFIG_SERIAL_8250_PCI=y 857# CONFIG_SERIAL_8250_PCI is not set
822CONFIG_SERIAL_8250_NR_UARTS=4 858CONFIG_SERIAL_8250_NR_UARTS=2
823CONFIG_SERIAL_8250_RUNTIME_UARTS=4 859CONFIG_SERIAL_8250_RUNTIME_UARTS=2
824# CONFIG_SERIAL_8250_EXTENDED is not set 860# CONFIG_SERIAL_8250_EXTENDED is not set
825 861
826# 862#
@@ -830,8 +866,7 @@ CONFIG_SERIAL_CORE=y
830CONFIG_SERIAL_CORE_CONSOLE=y 866CONFIG_SERIAL_CORE_CONSOLE=y
831# CONFIG_SERIAL_JSM is not set 867# CONFIG_SERIAL_JSM is not set
832CONFIG_UNIX98_PTYS=y 868CONFIG_UNIX98_PTYS=y
833CONFIG_LEGACY_PTYS=y 869# CONFIG_LEGACY_PTYS is not set
834CONFIG_LEGACY_PTY_COUNT=256
835 870
836# 871#
837# IPMI 872# IPMI
@@ -843,7 +878,8 @@ CONFIG_LEGACY_PTY_COUNT=256
843# 878#
844# CONFIG_WATCHDOG is not set 879# CONFIG_WATCHDOG is not set
845# CONFIG_HW_RANDOM is not set 880# CONFIG_HW_RANDOM is not set
846CONFIG_RTC=y 881# CONFIG_RTC is not set
882# CONFIG_GEN_RTC is not set
847# CONFIG_DTLK is not set 883# CONFIG_DTLK is not set
848# CONFIG_R3964 is not set 884# CONFIG_R3964 is not set
849# CONFIG_APPLICOM is not set 885# CONFIG_APPLICOM is not set
@@ -858,7 +894,58 @@ CONFIG_RTC=y
858# 894#
859# I2C support 895# I2C support
860# 896#
861# CONFIG_I2C is not set 897CONFIG_I2C=y
898CONFIG_I2C_CHARDEV=y
899
900#
901# I2C Algorithms
902#
903# CONFIG_I2C_ALGOBIT is not set
904# CONFIG_I2C_ALGOPCF is not set
905# CONFIG_I2C_ALGOPCA is not set
906
907#
908# I2C Hardware Bus support
909#
910# CONFIG_I2C_ALI1535 is not set
911# CONFIG_I2C_ALI1563 is not set
912# CONFIG_I2C_ALI15X3 is not set
913# CONFIG_I2C_AMD756 is not set
914# CONFIG_I2C_AMD8111 is not set
915# CONFIG_I2C_I801 is not set
916# CONFIG_I2C_I810 is not set
917# CONFIG_I2C_PIIX4 is not set
918# CONFIG_I2C_NFORCE2 is not set
919# CONFIG_I2C_OCORES is not set
920# CONFIG_I2C_PARPORT_LIGHT is not set
921# CONFIG_I2C_PASEMI is not set
922# CONFIG_I2C_PROSAVAGE is not set
923# CONFIG_I2C_SAVAGE4 is not set
924# CONFIG_I2C_SIS5595 is not set
925# CONFIG_I2C_SIS630 is not set
926# CONFIG_I2C_SIS96X is not set
927# CONFIG_I2C_STUB is not set
928# CONFIG_I2C_VIA is not set
929# CONFIG_I2C_VIAPRO is not set
930# CONFIG_I2C_VOODOO3 is not set
931# CONFIG_I2C_PCA_ISA is not set
932CONFIG_I2C_PMCMSP=y
933
934#
935# Miscellaneous I2C Chip support
936#
937# CONFIG_SENSORS_DS1337 is not set
938# CONFIG_SENSORS_DS1374 is not set
939# CONFIG_SENSORS_EEPROM is not set
940# CONFIG_SENSORS_PCF8574 is not set
941CONFIG_PMCTWILED=y
942# CONFIG_SENSORS_PCA9539 is not set
943# CONFIG_SENSORS_PCF8591 is not set
944# CONFIG_SENSORS_MAX6875 is not set
945# CONFIG_I2C_DEBUG_CORE is not set
946# CONFIG_I2C_DEBUG_ALGO is not set
947# CONFIG_I2C_DEBUG_BUS is not set
948# CONFIG_I2C_DEBUG_CHIP is not set
862 949
863# 950#
864# SPI support 951# SPI support
@@ -874,8 +961,57 @@ CONFIG_RTC=y
874# 961#
875# Hardware Monitoring support 962# Hardware Monitoring support
876# 963#
877# CONFIG_HWMON is not set 964CONFIG_HWMON=y
878# CONFIG_HWMON_VID is not set 965# CONFIG_HWMON_VID is not set
966# CONFIG_SENSORS_ABITUGURU is not set
967# CONFIG_SENSORS_ADM1021 is not set
968# CONFIG_SENSORS_ADM1025 is not set
969# CONFIG_SENSORS_ADM1026 is not set
970# CONFIG_SENSORS_ADM1029 is not set
971# CONFIG_SENSORS_ADM1031 is not set
972# CONFIG_SENSORS_ADM9240 is not set
973# CONFIG_SENSORS_ASB100 is not set
974# CONFIG_SENSORS_ATXP1 is not set
975# CONFIG_SENSORS_DS1621 is not set
976# CONFIG_SENSORS_F71805F is not set
977# CONFIG_SENSORS_FSCHER is not set
978# CONFIG_SENSORS_FSCPOS is not set
979# CONFIG_SENSORS_GL518SM is not set
980# CONFIG_SENSORS_GL520SM is not set
981# CONFIG_SENSORS_IT87 is not set
982# CONFIG_SENSORS_LM63 is not set
983# CONFIG_SENSORS_LM75 is not set
984# CONFIG_SENSORS_LM77 is not set
985# CONFIG_SENSORS_LM78 is not set
986# CONFIG_SENSORS_LM80 is not set
987# CONFIG_SENSORS_LM83 is not set
988# CONFIG_SENSORS_LM85 is not set
989# CONFIG_SENSORS_LM87 is not set
990# CONFIG_SENSORS_LM90 is not set
991# CONFIG_SENSORS_LM92 is not set
992# CONFIG_SENSORS_MAX1619 is not set
993# CONFIG_SENSORS_PC87360 is not set
994# CONFIG_SENSORS_PC87427 is not set
995# CONFIG_SENSORS_SIS5595 is not set
996# CONFIG_SENSORS_SMSC47M1 is not set
997# CONFIG_SENSORS_SMSC47M192 is not set
998# CONFIG_SENSORS_SMSC47B397 is not set
999# CONFIG_SENSORS_VIA686A is not set
1000# CONFIG_SENSORS_VT1211 is not set
1001# CONFIG_SENSORS_VT8231 is not set
1002# CONFIG_SENSORS_W83781D is not set
1003# CONFIG_SENSORS_W83791D is not set
1004# CONFIG_SENSORS_W83792D is not set
1005# CONFIG_SENSORS_W83793 is not set
1006# CONFIG_SENSORS_W83L785TS is not set
1007# CONFIG_SENSORS_W83627HF is not set
1008# CONFIG_SENSORS_W83627EHF is not set
1009# CONFIG_HWMON_DEBUG_CHIP is not set
1010
1011#
1012# Multifunction device drivers
1013#
1014# CONFIG_MFD_SM501 is not set
879 1015
880# 1016#
881# Multimedia devices 1017# Multimedia devices
@@ -886,62 +1022,13 @@ CONFIG_RTC=y
886# Digital Video Broadcasting Devices 1022# Digital Video Broadcasting Devices
887# 1023#
888# CONFIG_DVB is not set 1024# CONFIG_DVB is not set
1025# CONFIG_USB_DABUSB is not set
889 1026
890# 1027#
891# Graphics support 1028# Graphics support
892# 1029#
893# CONFIG_FIRMWARE_EDID is not set
894CONFIG_FB=y
895# CONFIG_FB_CFB_FILLRECT is not set
896# CONFIG_FB_CFB_COPYAREA is not set
897# CONFIG_FB_CFB_IMAGEBLIT is not set
898# CONFIG_FB_SVGALIB is not set
899# CONFIG_FB_MACMODES is not set
900# CONFIG_FB_BACKLIGHT is not set
901CONFIG_FB_MODE_HELPERS=y
902# CONFIG_FB_TILEBLITTING is not set
903# CONFIG_FB_CIRRUS is not set
904# CONFIG_FB_PM2 is not set
905# CONFIG_FB_CYBER2000 is not set
906# CONFIG_FB_ASILIANT is not set
907# CONFIG_FB_IMSTT is not set
908# CONFIG_FB_S1D13XXX is not set
909# CONFIG_FB_NVIDIA is not set
910# CONFIG_FB_RIVA is not set
911# CONFIG_FB_MATROX is not set
912# CONFIG_FB_RADEON is not set
913# CONFIG_FB_ATY128 is not set
914# CONFIG_FB_ATY is not set
915# CONFIG_FB_S3 is not set
916# CONFIG_FB_SAVAGE is not set
917# CONFIG_FB_SIS is not set
918# CONFIG_FB_NEOMAGIC is not set
919# CONFIG_FB_KYRO is not set
920# CONFIG_FB_3DFX is not set
921# CONFIG_FB_VOODOO1 is not set
922# CONFIG_FB_SMIVGX is not set
923# CONFIG_FB_TRIDENT is not set
924# CONFIG_FB_VIRTUAL is not set
925
926#
927# Console display driver support
928#
929# CONFIG_VGA_CONSOLE is not set
930CONFIG_DUMMY_CONSOLE=y
931CONFIG_FRAMEBUFFER_CONSOLE=y
932# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
933# CONFIG_FONTS is not set
934CONFIG_FONT_8x8=y
935CONFIG_FONT_8x16=y
936
937#
938# Logo configuration
939#
940CONFIG_LOGO=y
941CONFIG_LOGO_LINUX_MONO=y
942CONFIG_LOGO_LINUX_VGA16=y
943CONFIG_LOGO_LINUX_CLUT224=y
944# CONFIG_BACKLIGHT_LCD_SUPPORT is not set 1030# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
1031# CONFIG_FB is not set
945 1032
946# 1033#
947# Sound 1034# Sound
@@ -960,13 +1047,134 @@ CONFIG_HID=y
960CONFIG_USB_ARCH_HAS_HCD=y 1047CONFIG_USB_ARCH_HAS_HCD=y
961CONFIG_USB_ARCH_HAS_OHCI=y 1048CONFIG_USB_ARCH_HAS_OHCI=y
962CONFIG_USB_ARCH_HAS_EHCI=y 1049CONFIG_USB_ARCH_HAS_EHCI=y
963# CONFIG_USB is not set 1050CONFIG_USB=y
1051# CONFIG_USB_DEBUG is not set
1052
1053#
1054# Miscellaneous USB options
1055#
1056CONFIG_USB_DEVICEFS=y
1057# CONFIG_USB_DYNAMIC_MINORS is not set
1058# CONFIG_USB_OTG is not set
1059
1060#
1061# USB Host Controller Drivers
1062#
1063CONFIG_USB_EHCI_HCD=y
1064# CONFIG_USB_EHCI_SPLIT_ISO is not set
1065CONFIG_USB_EHCI_ROOT_HUB_TT=y
1066# CONFIG_USB_EHCI_TT_NEWSCHED is not set
1067# CONFIG_USB_EHCI_BIG_ENDIAN_MMIO is not set
1068# CONFIG_USB_ISP116X_HCD is not set
1069# CONFIG_USB_OHCI_HCD is not set
1070# CONFIG_USB_UHCI_HCD is not set
1071# CONFIG_USB_SL811_HCD is not set
1072
1073#
1074# USB Device Class drivers
1075#
1076# CONFIG_USB_ACM is not set
1077# CONFIG_USB_PRINTER is not set
964 1078
965# 1079#
966# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' 1080# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
967# 1081#
968 1082
969# 1083#
1084# may also be needed; see USB_STORAGE Help for more information
1085#
1086CONFIG_USB_STORAGE=y
1087# CONFIG_USB_STORAGE_DEBUG is not set
1088# CONFIG_USB_STORAGE_DATAFAB is not set
1089# CONFIG_USB_STORAGE_FREECOM is not set
1090# CONFIG_USB_STORAGE_DPCM is not set
1091# CONFIG_USB_STORAGE_USBAT is not set
1092# CONFIG_USB_STORAGE_SDDR09 is not set
1093# CONFIG_USB_STORAGE_SDDR55 is not set
1094# CONFIG_USB_STORAGE_JUMPSHOT is not set
1095# CONFIG_USB_STORAGE_ALAUDA is not set
1096# CONFIG_USB_STORAGE_KARMA is not set
1097# CONFIG_USB_LIBUSUAL is not set
1098
1099#
1100# USB Input Devices
1101#
1102# CONFIG_USB_HID is not set
1103
1104#
1105# USB HID Boot Protocol drivers
1106#
1107# CONFIG_USB_KBD is not set
1108# CONFIG_USB_MOUSE is not set
1109# CONFIG_USB_AIPTEK is not set
1110# CONFIG_USB_WACOM is not set
1111# CONFIG_USB_ACECAD is not set
1112# CONFIG_USB_KBTAB is not set
1113# CONFIG_USB_POWERMATE is not set
1114# CONFIG_USB_TOUCHSCREEN is not set
1115# CONFIG_USB_YEALINK is not set
1116# CONFIG_USB_XPAD is not set
1117# CONFIG_USB_ATI_REMOTE is not set
1118# CONFIG_USB_ATI_REMOTE2 is not set
1119# CONFIG_USB_KEYSPAN_REMOTE is not set
1120# CONFIG_USB_APPLETOUCH is not set
1121# CONFIG_USB_GTCO is not set
1122
1123#
1124# USB Imaging devices
1125#
1126# CONFIG_USB_MDC800 is not set
1127# CONFIG_USB_MICROTEK is not set
1128
1129#
1130# USB Network Adapters
1131#
1132# CONFIG_USB_CATC is not set
1133# CONFIG_USB_KAWETH is not set
1134# CONFIG_USB_PEGASUS is not set
1135# CONFIG_USB_RTL8150 is not set
1136# CONFIG_USB_USBNET_MII is not set
1137# CONFIG_USB_USBNET is not set
1138CONFIG_USB_MON=y
1139
1140#
1141# USB port drivers
1142#
1143
1144#
1145# USB Serial Converter support
1146#
1147# CONFIG_USB_SERIAL is not set
1148
1149#
1150# USB Miscellaneous drivers
1151#
1152# CONFIG_USB_EMI62 is not set
1153# CONFIG_USB_EMI26 is not set
1154# CONFIG_USB_ADUTUX is not set
1155# CONFIG_USB_AUERSWALD is not set
1156# CONFIG_USB_RIO500 is not set
1157# CONFIG_USB_LEGOTOWER is not set
1158# CONFIG_USB_LCD is not set
1159# CONFIG_USB_BERRY_CHARGE is not set
1160# CONFIG_USB_LED is not set
1161# CONFIG_USB_CYPRESS_CY7C63 is not set
1162# CONFIG_USB_CYTHERM is not set
1163# CONFIG_USB_PHIDGET is not set
1164# CONFIG_USB_IDMOUSE is not set
1165# CONFIG_USB_FTDI_ELAN is not set
1166# CONFIG_USB_APPLEDISPLAY is not set
1167# CONFIG_USB_SISUSBVGA is not set
1168# CONFIG_USB_LD is not set
1169# CONFIG_USB_TRANCEVIBRATOR is not set
1170# CONFIG_USB_IOWARRIOR is not set
1171# CONFIG_USB_TEST is not set
1172
1173#
1174# USB DSL modem support
1175#
1176
1177#
970# USB Gadget Support 1178# USB Gadget Support
971# 1179#
972# CONFIG_USB_GADGET is not set 1180# CONFIG_USB_GADGET is not set
@@ -1030,37 +1238,22 @@ CONFIG_USB_ARCH_HAS_EHCI=y
1030CONFIG_EXT2_FS=y 1238CONFIG_EXT2_FS=y
1031# CONFIG_EXT2_FS_XATTR is not set 1239# CONFIG_EXT2_FS_XATTR is not set
1032# CONFIG_EXT2_FS_XIP is not set 1240# CONFIG_EXT2_FS_XIP is not set
1033CONFIG_EXT3_FS=m 1241# CONFIG_EXT3_FS is not set
1034CONFIG_EXT3_FS_XATTR=y
1035# CONFIG_EXT3_FS_POSIX_ACL is not set
1036# CONFIG_EXT3_FS_SECURITY is not set
1037# CONFIG_EXT4DEV_FS is not set 1242# CONFIG_EXT4DEV_FS is not set
1038CONFIG_JBD=m 1243# CONFIG_REISERFS_FS is not set
1039# CONFIG_JBD_DEBUG is not set
1040CONFIG_FS_MBCACHE=y
1041CONFIG_REISERFS_FS=m
1042# CONFIG_REISERFS_CHECK is not set
1043# CONFIG_REISERFS_PROC_INFO is not set
1044# CONFIG_REISERFS_FS_XATTR is not set
1045# CONFIG_JFS_FS is not set 1244# CONFIG_JFS_FS is not set
1046CONFIG_FS_POSIX_ACL=y 1245# CONFIG_FS_POSIX_ACL is not set
1047CONFIG_XFS_FS=m 1246# CONFIG_XFS_FS is not set
1048# CONFIG_XFS_QUOTA is not set
1049# CONFIG_XFS_SECURITY is not set
1050# CONFIG_XFS_POSIX_ACL is not set
1051# CONFIG_XFS_RT is not set
1052# CONFIG_GFS2_FS is not set 1247# CONFIG_GFS2_FS is not set
1053# CONFIG_OCFS2_FS is not set 1248# CONFIG_OCFS2_FS is not set
1054# CONFIG_MINIX_FS is not set 1249# CONFIG_MINIX_FS is not set
1055# CONFIG_ROMFS_FS is not set 1250# CONFIG_ROMFS_FS is not set
1056CONFIG_INOTIFY=y 1251# CONFIG_INOTIFY is not set
1057CONFIG_INOTIFY_USER=y
1058# CONFIG_QUOTA is not set 1252# CONFIG_QUOTA is not set
1059CONFIG_DNOTIFY=y 1253# CONFIG_DNOTIFY is not set
1060CONFIG_AUTOFS_FS=y 1254# CONFIG_AUTOFS_FS is not set
1061CONFIG_AUTOFS4_FS=m 1255# CONFIG_AUTOFS4_FS is not set
1062CONFIG_FUSE_FS=m 1256# CONFIG_FUSE_FS is not set
1063CONFIG_GENERIC_ACL=y
1064 1257
1065# 1258#
1066# CD-ROM/DVD Filesystems 1259# CD-ROM/DVD Filesystems
@@ -1071,22 +1264,25 @@ CONFIG_GENERIC_ACL=y
1071# 1264#
1072# DOS/FAT/NT Filesystems 1265# DOS/FAT/NT Filesystems
1073# 1266#
1074# CONFIG_MSDOS_FS is not set 1267CONFIG_FAT_FS=y
1075# CONFIG_VFAT_FS is not set 1268CONFIG_MSDOS_FS=y
1269CONFIG_VFAT_FS=y
1270CONFIG_FAT_DEFAULT_CODEPAGE=437
1271CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
1076# CONFIG_NTFS_FS is not set 1272# CONFIG_NTFS_FS is not set
1077 1273
1078# 1274#
1079# Pseudo filesystems 1275# Pseudo filesystems
1080# 1276#
1081CONFIG_PROC_FS=y 1277CONFIG_PROC_FS=y
1082CONFIG_PROC_KCORE=y 1278# CONFIG_PROC_KCORE is not set
1083CONFIG_PROC_SYSCTL=y 1279CONFIG_PROC_SYSCTL=y
1084CONFIG_SYSFS=y 1280CONFIG_SYSFS=y
1085CONFIG_TMPFS=y 1281CONFIG_TMPFS=y
1086CONFIG_TMPFS_POSIX_ACL=y 1282# CONFIG_TMPFS_POSIX_ACL is not set
1087# CONFIG_HUGETLB_PAGE is not set 1283# CONFIG_HUGETLB_PAGE is not set
1088CONFIG_RAMFS=y 1284CONFIG_RAMFS=y
1089CONFIG_CONFIGFS_FS=m 1285# CONFIG_CONFIGFS_FS is not set
1090 1286
1091# 1287#
1092# Miscellaneous filesystems 1288# Miscellaneous filesystems
@@ -1097,8 +1293,21 @@ CONFIG_CONFIGFS_FS=m
1097# CONFIG_HFSPLUS_FS is not set 1293# CONFIG_HFSPLUS_FS is not set
1098# CONFIG_BEFS_FS is not set 1294# CONFIG_BEFS_FS is not set
1099# CONFIG_BFS_FS is not set 1295# CONFIG_BFS_FS is not set
1100CONFIG_EFS_FS=y 1296# CONFIG_EFS_FS is not set
1101CONFIG_CRAMFS=y 1297CONFIG_JFFS2_FS=y
1298CONFIG_JFFS2_FS_DEBUG=0
1299CONFIG_JFFS2_FS_WRITEBUFFER=y
1300# CONFIG_JFFS2_SUMMARY is not set
1301# CONFIG_JFFS2_FS_XATTR is not set
1302# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
1303CONFIG_JFFS2_ZLIB=y
1304CONFIG_JFFS2_RTIME=y
1305# CONFIG_JFFS2_RUBIN is not set
1306# CONFIG_CRAMFS is not set
1307CONFIG_SQUASHFS=y
1308CONFIG_SQUASHFS_EMBEDDED=y
1309CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
1310CONFIG_SQUASHFS_VMALLOC=y
1102# CONFIG_VXFS_FS is not set 1311# CONFIG_VXFS_FS is not set
1103# CONFIG_HPFS_FS is not set 1312# CONFIG_HPFS_FS is not set
1104# CONFIG_QNX4FS_FS is not set 1313# CONFIG_QNX4FS_FS is not set
@@ -1108,26 +1317,9 @@ CONFIG_CRAMFS=y
1108# 1317#
1109# Network File Systems 1318# Network File Systems
1110# 1319#
1111CONFIG_NFS_FS=y 1320# CONFIG_NFS_FS is not set
1112CONFIG_NFS_V3=y 1321# CONFIG_NFSD is not set
1113# CONFIG_NFS_V3_ACL is not set 1322# CONFIG_SMB_FS is not set
1114# CONFIG_NFS_V4 is not set
1115# CONFIG_NFS_DIRECTIO is not set
1116CONFIG_NFSD=y
1117CONFIG_NFSD_V3=y
1118# CONFIG_NFSD_V3_ACL is not set
1119# CONFIG_NFSD_V4 is not set
1120# CONFIG_NFSD_TCP is not set
1121CONFIG_ROOT_NFS=y
1122CONFIG_LOCKD=y
1123CONFIG_LOCKD_V4=y
1124CONFIG_EXPORTFS=y
1125CONFIG_NFS_COMMON=y
1126CONFIG_SUNRPC=y
1127# CONFIG_RPCSEC_GSS_KRB5 is not set
1128# CONFIG_RPCSEC_GSS_SPKM3 is not set
1129CONFIG_SMB_FS=m
1130# CONFIG_SMB_NLS_DEFAULT is not set
1131# CONFIG_CIFS is not set 1323# CONFIG_CIFS is not set
1132# CONFIG_NCP_FS is not set 1324# CONFIG_NCP_FS is not set
1133# CONFIG_CODA_FS is not set 1325# CONFIG_CODA_FS is not set
@@ -1143,9 +1335,9 @@ CONFIG_MSDOS_PARTITION=y
1143# 1335#
1144# Native Language Support 1336# Native Language Support
1145# 1337#
1146CONFIG_NLS=m 1338CONFIG_NLS=y
1147CONFIG_NLS_DEFAULT="iso8859-1" 1339CONFIG_NLS_DEFAULT="iso8859-1"
1148# CONFIG_NLS_CODEPAGE_437 is not set 1340CONFIG_NLS_CODEPAGE_437=y
1149# CONFIG_NLS_CODEPAGE_737 is not set 1341# CONFIG_NLS_CODEPAGE_737 is not set
1150# CONFIG_NLS_CODEPAGE_775 is not set 1342# CONFIG_NLS_CODEPAGE_775 is not set
1151# CONFIG_NLS_CODEPAGE_850 is not set 1343# CONFIG_NLS_CODEPAGE_850 is not set
@@ -1169,7 +1361,7 @@ CONFIG_NLS_DEFAULT="iso8859-1"
1169# CONFIG_NLS_CODEPAGE_1250 is not set 1361# CONFIG_NLS_CODEPAGE_1250 is not set
1170# CONFIG_NLS_CODEPAGE_1251 is not set 1362# CONFIG_NLS_CODEPAGE_1251 is not set
1171# CONFIG_NLS_ASCII is not set 1363# CONFIG_NLS_ASCII is not set
1172# CONFIG_NLS_ISO8859_1 is not set 1364CONFIG_NLS_ISO8859_1=y
1173# CONFIG_NLS_ISO8859_2 is not set 1365# CONFIG_NLS_ISO8859_2 is not set
1174# CONFIG_NLS_ISO8859_3 is not set 1366# CONFIG_NLS_ISO8859_3 is not set
1175# CONFIG_NLS_ISO8859_4 is not set 1367# CONFIG_NLS_ISO8859_4 is not set
@@ -1187,10 +1379,7 @@ CONFIG_NLS_DEFAULT="iso8859-1"
1187# 1379#
1188# Distributed Lock Manager 1380# Distributed Lock Manager
1189# 1381#
1190CONFIG_DLM=m 1382# CONFIG_DLM is not set
1191CONFIG_DLM_TCP=y
1192# CONFIG_DLM_SCTP is not set
1193# CONFIG_DLM_DEBUG is not set
1194 1383
1195# 1384#
1196# Profiling support 1385# Profiling support
@@ -1203,14 +1392,40 @@ CONFIG_DLM_TCP=y
1203CONFIG_TRACE_IRQFLAGS_SUPPORT=y 1392CONFIG_TRACE_IRQFLAGS_SUPPORT=y
1204# CONFIG_PRINTK_TIME is not set 1393# CONFIG_PRINTK_TIME is not set
1205CONFIG_ENABLE_MUST_CHECK=y 1394CONFIG_ENABLE_MUST_CHECK=y
1206# CONFIG_MAGIC_SYSRQ is not set 1395CONFIG_MAGIC_SYSRQ=y
1207# CONFIG_UNUSED_SYMBOLS is not set 1396# CONFIG_UNUSED_SYMBOLS is not set
1208# CONFIG_DEBUG_FS is not set 1397# CONFIG_DEBUG_FS is not set
1209# CONFIG_HEADERS_CHECK is not set 1398# CONFIG_HEADERS_CHECK is not set
1210# CONFIG_DEBUG_KERNEL is not set 1399CONFIG_DEBUG_KERNEL=y
1400# CONFIG_DEBUG_SHIRQ is not set
1211CONFIG_LOG_BUF_SHIFT=14 1401CONFIG_LOG_BUF_SHIFT=14
1402CONFIG_DETECT_SOFTLOCKUP=y
1403# CONFIG_SCHEDSTATS is not set
1404# CONFIG_TIMER_STATS is not set
1405# CONFIG_DEBUG_SLAB is not set
1406CONFIG_DEBUG_PREEMPT=y
1407# CONFIG_DEBUG_RT_MUTEXES is not set
1408# CONFIG_RT_MUTEX_TESTER is not set
1409# CONFIG_DEBUG_SPINLOCK is not set
1410# CONFIG_DEBUG_MUTEXES is not set
1411# CONFIG_DEBUG_LOCK_ALLOC is not set
1412# CONFIG_PROVE_LOCKING is not set
1413# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
1414# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
1415# CONFIG_DEBUG_KOBJECT is not set
1416# CONFIG_DEBUG_INFO is not set
1417# CONFIG_DEBUG_VM is not set
1418# CONFIG_DEBUG_LIST is not set
1419CONFIG_FORCED_INLINING=y
1420# CONFIG_RCU_TORTURE_TEST is not set
1421# CONFIG_FAULT_INJECTION is not set
1212CONFIG_CROSSCOMPILE=y 1422CONFIG_CROSSCOMPILE=y
1213CONFIG_CMDLINE="ip=any root=nfs" 1423CONFIG_CMDLINE=""
1424# CONFIG_DEBUG_STACK_USAGE is not set
1425# CONFIG_KGDB is not set
1426CONFIG_SYS_SUPPORTS_KGDB=y
1427# CONFIG_RUNTIME_DEBUG is not set
1428# CONFIG_MIPS_UNCACHED is not set
1214 1429
1215# 1430#
1216# Security options 1431# Security options
@@ -1223,41 +1438,40 @@ CONFIG_CMDLINE="ip=any root=nfs"
1223# 1438#
1224CONFIG_CRYPTO=y 1439CONFIG_CRYPTO=y
1225CONFIG_CRYPTO_ALGAPI=y 1440CONFIG_CRYPTO_ALGAPI=y
1226CONFIG_CRYPTO_BLKCIPHER=m 1441CONFIG_CRYPTO_BLKCIPHER=y
1227CONFIG_CRYPTO_HASH=y 1442CONFIG_CRYPTO_HASH=y
1228CONFIG_CRYPTO_MANAGER=y 1443CONFIG_CRYPTO_MANAGER=y
1229CONFIG_CRYPTO_HMAC=y 1444CONFIG_CRYPTO_HMAC=y
1230CONFIG_CRYPTO_XCBC=m 1445# CONFIG_CRYPTO_XCBC is not set
1231CONFIG_CRYPTO_NULL=m 1446CONFIG_CRYPTO_NULL=y
1232CONFIG_CRYPTO_MD4=m 1447# CONFIG_CRYPTO_MD4 is not set
1233CONFIG_CRYPTO_MD5=y 1448CONFIG_CRYPTO_MD5=y
1234CONFIG_CRYPTO_SHA1=m 1449CONFIG_CRYPTO_SHA1=y
1235CONFIG_CRYPTO_SHA256=m 1450# CONFIG_CRYPTO_SHA256 is not set
1236CONFIG_CRYPTO_SHA512=m 1451# CONFIG_CRYPTO_SHA512 is not set
1237CONFIG_CRYPTO_WP512=m 1452# CONFIG_CRYPTO_WP512 is not set
1238CONFIG_CRYPTO_TGR192=m 1453# CONFIG_CRYPTO_TGR192 is not set
1239CONFIG_CRYPTO_GF128MUL=m 1454# CONFIG_CRYPTO_GF128MUL is not set
1240CONFIG_CRYPTO_ECB=m 1455# CONFIG_CRYPTO_ECB is not set
1241CONFIG_CRYPTO_CBC=m 1456CONFIG_CRYPTO_CBC=y
1242CONFIG_CRYPTO_PCBC=m 1457# CONFIG_CRYPTO_PCBC is not set
1243CONFIG_CRYPTO_LRW=m 1458# CONFIG_CRYPTO_LRW is not set
1244CONFIG_CRYPTO_DES=m 1459CONFIG_CRYPTO_DES=y
1245CONFIG_CRYPTO_FCRYPT=m 1460# CONFIG_CRYPTO_FCRYPT is not set
1246CONFIG_CRYPTO_BLOWFISH=m 1461# CONFIG_CRYPTO_BLOWFISH is not set
1247CONFIG_CRYPTO_TWOFISH=m 1462# CONFIG_CRYPTO_TWOFISH is not set
1248CONFIG_CRYPTO_TWOFISH_COMMON=m 1463# CONFIG_CRYPTO_SERPENT is not set
1249CONFIG_CRYPTO_SERPENT=m 1464CONFIG_CRYPTO_AES=y
1250CONFIG_CRYPTO_AES=m 1465# CONFIG_CRYPTO_CAST5 is not set
1251CONFIG_CRYPTO_CAST5=m 1466# CONFIG_CRYPTO_CAST6 is not set
1252CONFIG_CRYPTO_CAST6=m 1467# CONFIG_CRYPTO_TEA is not set
1253CONFIG_CRYPTO_TEA=m 1468# CONFIG_CRYPTO_ARC4 is not set
1254CONFIG_CRYPTO_ARC4=m 1469# CONFIG_CRYPTO_KHAZAD is not set
1255CONFIG_CRYPTO_KHAZAD=m 1470# CONFIG_CRYPTO_ANUBIS is not set
1256CONFIG_CRYPTO_ANUBIS=m 1471CONFIG_CRYPTO_DEFLATE=y
1257CONFIG_CRYPTO_DEFLATE=m 1472# CONFIG_CRYPTO_MICHAEL_MIC is not set
1258CONFIG_CRYPTO_MICHAEL_MIC=m 1473# CONFIG_CRYPTO_CRC32C is not set
1259CONFIG_CRYPTO_CRC32C=m 1474# CONFIG_CRYPTO_CAMELLIA is not set
1260CONFIG_CRYPTO_CAMELLIA=m
1261# CONFIG_CRYPTO_TEST is not set 1475# CONFIG_CRYPTO_TEST is not set
1262 1476
1263# 1477#
@@ -1268,16 +1482,12 @@ CONFIG_CRYPTO_CAMELLIA=m
1268# Library routines 1482# Library routines
1269# 1483#
1270CONFIG_BITREVERSE=y 1484CONFIG_BITREVERSE=y
1271CONFIG_CRC_CCITT=m 1485# CONFIG_CRC_CCITT is not set
1272CONFIG_CRC16=m 1486# CONFIG_CRC16 is not set
1273CONFIG_CRC32=y 1487CONFIG_CRC32=y
1274CONFIG_LIBCRC32C=m 1488# CONFIG_LIBCRC32C is not set
1275CONFIG_ZLIB_INFLATE=y 1489CONFIG_ZLIB_INFLATE=y
1276CONFIG_ZLIB_DEFLATE=m 1490CONFIG_ZLIB_DEFLATE=y
1277CONFIG_TEXTSEARCH=y
1278CONFIG_TEXTSEARCH_KMP=m
1279CONFIG_TEXTSEARCH_BM=m
1280CONFIG_TEXTSEARCH_FSM=m
1281CONFIG_PLIST=y 1491CONFIG_PLIST=y
1282CONFIG_HAS_IOMEM=y 1492CONFIG_HAS_IOMEM=y
1283CONFIG_HAS_IOPORT=y 1493CONFIG_HAS_IOPORT=y
diff --git a/arch/mips/configs/ocelot_c_defconfig b/arch/mips/configs/ocelot_c_defconfig
deleted file mode 100644
index 82ff6fc0cd41..000000000000
--- a/arch/mips/configs/ocelot_c_defconfig
+++ /dev/null
@@ -1,982 +0,0 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.20
4# Tue Feb 20 21:47:36 2007
5#
6CONFIG_MIPS=y
7
8#
9# Machine selection
10#
11CONFIG_ZONE_DMA=y
12# CONFIG_MIPS_MTX1 is not set
13# CONFIG_MIPS_BOSPORUS is not set
14# CONFIG_MIPS_PB1000 is not set
15# CONFIG_MIPS_PB1100 is not set
16# CONFIG_MIPS_PB1500 is not set
17# CONFIG_MIPS_PB1550 is not set
18# CONFIG_MIPS_PB1200 is not set
19# CONFIG_MIPS_DB1000 is not set
20# CONFIG_MIPS_DB1100 is not set
21# CONFIG_MIPS_DB1500 is not set
22# CONFIG_MIPS_DB1550 is not set
23# CONFIG_MIPS_DB1200 is not set
24# CONFIG_MIPS_MIRAGE is not set
25# CONFIG_BASLER_EXCITE is not set
26# CONFIG_MIPS_COBALT is not set
27# CONFIG_MACH_DECSTATION is not set
28# CONFIG_MIPS_EV64120 is not set
29# CONFIG_MACH_JAZZ is not set
30# CONFIG_LASAT is not set
31# CONFIG_MIPS_ATLAS is not set
32# CONFIG_MIPS_MALTA is not set
33# CONFIG_MIPS_SEAD is not set
34# CONFIG_WR_PPMC is not set
35# CONFIG_MIPS_SIM is not set
36# CONFIG_MOMENCO_JAGUAR_ATX is not set
37# CONFIG_MOMENCO_OCELOT is not set
38# CONFIG_MOMENCO_OCELOT_3 is not set
39CONFIG_MOMENCO_OCELOT_C=y
40# CONFIG_MOMENCO_OCELOT_G is not set
41# CONFIG_MIPS_XXS1500 is not set
42# CONFIG_PNX8550_JBS is not set
43# CONFIG_PNX8550_STB810 is not set
44# CONFIG_DDB5477 is not set
45# CONFIG_MACH_VR41XX is not set
46# CONFIG_PMC_YOSEMITE is not set
47# CONFIG_QEMU is not set
48# CONFIG_MARKEINS is not set
49# CONFIG_SGI_IP22 is not set
50# CONFIG_SGI_IP27 is not set
51# CONFIG_SGI_IP32 is not set
52# CONFIG_SIBYTE_BIGSUR is not set
53# CONFIG_SIBYTE_SWARM is not set
54# CONFIG_SIBYTE_SENTOSA is not set
55# CONFIG_SIBYTE_RHONE is not set
56# CONFIG_SIBYTE_CARMEL is not set
57# CONFIG_SIBYTE_PTSWARM is not set
58# CONFIG_SIBYTE_LITTLESUR is not set
59# CONFIG_SIBYTE_CRHINE is not set
60# CONFIG_SIBYTE_CRHONE is not set
61# CONFIG_SNI_RM is not set
62# CONFIG_TOSHIBA_JMR3927 is not set
63# CONFIG_TOSHIBA_RBTX4927 is not set
64# CONFIG_TOSHIBA_RBTX4938 is not set
65CONFIG_RWSEM_GENERIC_SPINLOCK=y
66# CONFIG_ARCH_HAS_ILOG2_U32 is not set
67# CONFIG_ARCH_HAS_ILOG2_U64 is not set
68CONFIG_GENERIC_FIND_NEXT_BIT=y
69CONFIG_GENERIC_HWEIGHT=y
70CONFIG_GENERIC_CALIBRATE_DELAY=y
71CONFIG_GENERIC_TIME=y
72CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
73CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
74CONFIG_DMA_NONCOHERENT=y
75CONFIG_DMA_NEED_PCI_MAP_STATE=y
76CONFIG_CPU_BIG_ENDIAN=y
77# CONFIG_CPU_LITTLE_ENDIAN is not set
78CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
79CONFIG_IRQ_CPU=y
80CONFIG_IRQ_MV64340=y
81CONFIG_PCI_MARVELL=y
82CONFIG_SWAP_IO_SPACE=y
83CONFIG_MIPS_L1_CACHE_SHIFT=5
84
85#
86# CPU selection
87#
88# CONFIG_CPU_MIPS32_R1 is not set
89# CONFIG_CPU_MIPS32_R2 is not set
90# CONFIG_CPU_MIPS64_R1 is not set
91# CONFIG_CPU_MIPS64_R2 is not set
92# CONFIG_CPU_R3000 is not set
93# CONFIG_CPU_TX39XX is not set
94# CONFIG_CPU_VR41XX is not set
95# CONFIG_CPU_R4300 is not set
96# CONFIG_CPU_R4X00 is not set
97# CONFIG_CPU_TX49XX is not set
98# CONFIG_CPU_R5000 is not set
99# CONFIG_CPU_R5432 is not set
100# CONFIG_CPU_R6000 is not set
101# CONFIG_CPU_NEVADA is not set
102# CONFIG_CPU_R8000 is not set
103# CONFIG_CPU_R10000 is not set
104CONFIG_CPU_RM7000=y
105# CONFIG_CPU_RM9000 is not set
106# CONFIG_CPU_SB1 is not set
107CONFIG_SYS_HAS_CPU_RM7000=y
108CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
109CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
110CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
111CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
112
113#
114# Kernel type
115#
116# CONFIG_32BIT is not set
117CONFIG_64BIT=y
118CONFIG_PAGE_SIZE_4KB=y
119# CONFIG_PAGE_SIZE_8KB is not set
120# CONFIG_PAGE_SIZE_16KB is not set
121# CONFIG_PAGE_SIZE_64KB is not set
122CONFIG_BOARD_SCACHE=y
123CONFIG_RM7000_CPU_SCACHE=y
124CONFIG_CPU_HAS_PREFETCH=y
125CONFIG_MIPS_MT_DISABLED=y
126# CONFIG_MIPS_MT_SMP is not set
127# CONFIG_MIPS_MT_SMTC is not set
128# CONFIG_MIPS_VPE_LOADER is not set
129CONFIG_CPU_HAS_LLSC=y
130CONFIG_CPU_HAS_SYNC=y
131CONFIG_GENERIC_HARDIRQS=y
132CONFIG_GENERIC_IRQ_PROBE=y
133CONFIG_CPU_SUPPORTS_HIGHMEM=y
134CONFIG_ARCH_FLATMEM_ENABLE=y
135CONFIG_SELECT_MEMORY_MODEL=y
136CONFIG_FLATMEM_MANUAL=y
137# CONFIG_DISCONTIGMEM_MANUAL is not set
138# CONFIG_SPARSEMEM_MANUAL is not set
139CONFIG_FLATMEM=y
140CONFIG_FLAT_NODE_MEM_MAP=y
141# CONFIG_SPARSEMEM_STATIC is not set
142CONFIG_SPLIT_PTLOCK_CPUS=4
143CONFIG_RESOURCES_64BIT=y
144CONFIG_ZONE_DMA_FLAG=1
145# CONFIG_HZ_48 is not set
146# CONFIG_HZ_100 is not set
147# CONFIG_HZ_128 is not set
148# CONFIG_HZ_250 is not set
149# CONFIG_HZ_256 is not set
150CONFIG_HZ_1000=y
151# CONFIG_HZ_1024 is not set
152CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
153CONFIG_HZ=1000
154CONFIG_PREEMPT_NONE=y
155# CONFIG_PREEMPT_VOLUNTARY is not set
156# CONFIG_PREEMPT is not set
157# CONFIG_KEXEC is not set
158CONFIG_LOCKDEP_SUPPORT=y
159CONFIG_STACKTRACE_SUPPORT=y
160CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
161
162#
163# Code maturity level options
164#
165CONFIG_EXPERIMENTAL=y
166CONFIG_BROKEN_ON_SMP=y
167CONFIG_INIT_ENV_ARG_LIMIT=32
168
169#
170# General setup
171#
172CONFIG_LOCALVERSION=""
173CONFIG_LOCALVERSION_AUTO=y
174CONFIG_SWAP=y
175CONFIG_SYSVIPC=y
176# CONFIG_IPC_NS is not set
177CONFIG_SYSVIPC_SYSCTL=y
178# CONFIG_POSIX_MQUEUE is not set
179# CONFIG_BSD_PROCESS_ACCT is not set
180# CONFIG_TASKSTATS is not set
181# CONFIG_UTS_NS is not set
182# CONFIG_AUDIT is not set
183# CONFIG_IKCONFIG is not set
184CONFIG_SYSFS_DEPRECATED=y
185CONFIG_RELAY=y
186# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
187CONFIG_SYSCTL=y
188CONFIG_EMBEDDED=y
189CONFIG_SYSCTL_SYSCALL=y
190CONFIG_KALLSYMS=y
191# CONFIG_KALLSYMS_EXTRA_PASS is not set
192CONFIG_HOTPLUG=y
193CONFIG_PRINTK=y
194CONFIG_BUG=y
195CONFIG_ELF_CORE=y
196CONFIG_BASE_FULL=y
197CONFIG_FUTEX=y
198CONFIG_EPOLL=y
199CONFIG_SHMEM=y
200CONFIG_SLAB=y
201CONFIG_VM_EVENT_COUNTERS=y
202CONFIG_RT_MUTEXES=y
203# CONFIG_TINY_SHMEM is not set
204CONFIG_BASE_SMALL=0
205# CONFIG_SLOB is not set
206
207#
208# Loadable module support
209#
210# CONFIG_MODULES is not set
211
212#
213# Block layer
214#
215CONFIG_BLOCK=y
216# CONFIG_BLK_DEV_IO_TRACE is not set
217
218#
219# IO Schedulers
220#
221CONFIG_IOSCHED_NOOP=y
222CONFIG_IOSCHED_AS=y
223CONFIG_IOSCHED_DEADLINE=y
224CONFIG_IOSCHED_CFQ=y
225CONFIG_DEFAULT_AS=y
226# CONFIG_DEFAULT_DEADLINE is not set
227# CONFIG_DEFAULT_CFQ is not set
228# CONFIG_DEFAULT_NOOP is not set
229CONFIG_DEFAULT_IOSCHED="anticipatory"
230
231#
232# Bus options (PCI, PCMCIA, EISA, ISA, TC)
233#
234CONFIG_HW_HAS_PCI=y
235CONFIG_PCI=y
236CONFIG_MMU=y
237
238#
239# PCCARD (PCMCIA/CardBus) support
240#
241# CONFIG_PCCARD is not set
242
243#
244# PCI Hotplug Support
245#
246# CONFIG_HOTPLUG_PCI is not set
247
248#
249# Executable file formats
250#
251CONFIG_BINFMT_ELF=y
252# CONFIG_BINFMT_MISC is not set
253# CONFIG_BUILD_ELF64 is not set
254CONFIG_MIPS32_COMPAT=y
255CONFIG_COMPAT=y
256CONFIG_SYSVIPC_COMPAT=y
257CONFIG_MIPS32_O32=y
258CONFIG_MIPS32_N32=y
259CONFIG_BINFMT_ELF32=y
260
261#
262# Power management options
263#
264CONFIG_PM=y
265# CONFIG_PM_LEGACY is not set
266# CONFIG_PM_DEBUG is not set
267# CONFIG_PM_SYSFS_DEPRECATED is not set
268
269#
270# Networking
271#
272CONFIG_NET=y
273
274#
275# Networking options
276#
277# CONFIG_NETDEBUG is not set
278# CONFIG_PACKET is not set
279CONFIG_UNIX=y
280CONFIG_XFRM=y
281CONFIG_XFRM_USER=y
282# CONFIG_XFRM_SUB_POLICY is not set
283CONFIG_XFRM_MIGRATE=y
284CONFIG_NET_KEY=y
285CONFIG_NET_KEY_MIGRATE=y
286CONFIG_INET=y
287# CONFIG_IP_MULTICAST is not set
288# CONFIG_IP_ADVANCED_ROUTER is not set
289CONFIG_IP_FIB_HASH=y
290CONFIG_IP_PNP=y
291CONFIG_IP_PNP_DHCP=y
292# CONFIG_IP_PNP_BOOTP is not set
293# CONFIG_IP_PNP_RARP is not set
294# CONFIG_NET_IPIP is not set
295# CONFIG_NET_IPGRE is not set
296# CONFIG_ARPD is not set
297# CONFIG_SYN_COOKIES is not set
298# CONFIG_INET_AH is not set
299# CONFIG_INET_ESP is not set
300# CONFIG_INET_IPCOMP is not set
301# CONFIG_INET_XFRM_TUNNEL is not set
302# CONFIG_INET_TUNNEL is not set
303CONFIG_INET_XFRM_MODE_TRANSPORT=y
304CONFIG_INET_XFRM_MODE_TUNNEL=y
305CONFIG_INET_XFRM_MODE_BEET=y
306CONFIG_INET_DIAG=y
307CONFIG_INET_TCP_DIAG=y
308# CONFIG_TCP_CONG_ADVANCED is not set
309CONFIG_TCP_CONG_CUBIC=y
310CONFIG_DEFAULT_TCP_CONG="cubic"
311CONFIG_TCP_MD5SIG=y
312# CONFIG_IPV6 is not set
313# CONFIG_INET6_XFRM_TUNNEL is not set
314# CONFIG_INET6_TUNNEL is not set
315CONFIG_NETWORK_SECMARK=y
316# CONFIG_NETFILTER is not set
317
318#
319# DCCP Configuration (EXPERIMENTAL)
320#
321# CONFIG_IP_DCCP is not set
322
323#
324# SCTP Configuration (EXPERIMENTAL)
325#
326# CONFIG_IP_SCTP is not set
327
328#
329# TIPC Configuration (EXPERIMENTAL)
330#
331# CONFIG_TIPC is not set
332# CONFIG_ATM is not set
333# CONFIG_BRIDGE is not set
334# CONFIG_VLAN_8021Q is not set
335# CONFIG_DECNET is not set
336# CONFIG_LLC2 is not set
337# CONFIG_IPX is not set
338# CONFIG_ATALK is not set
339# CONFIG_X25 is not set
340# CONFIG_LAPB is not set
341# CONFIG_ECONET is not set
342# CONFIG_WAN_ROUTER is not set
343
344#
345# QoS and/or fair queueing
346#
347# CONFIG_NET_SCHED is not set
348
349#
350# Network testing
351#
352# CONFIG_NET_PKTGEN is not set
353# CONFIG_HAMRADIO is not set
354# CONFIG_IRDA is not set
355# CONFIG_BT is not set
356CONFIG_IEEE80211=y
357# CONFIG_IEEE80211_DEBUG is not set
358CONFIG_IEEE80211_CRYPT_WEP=y
359CONFIG_IEEE80211_CRYPT_CCMP=y
360CONFIG_IEEE80211_SOFTMAC=y
361# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set
362CONFIG_WIRELESS_EXT=y
363
364#
365# Device Drivers
366#
367
368#
369# Generic Driver Options
370#
371CONFIG_STANDALONE=y
372CONFIG_PREVENT_FIRMWARE_BUILD=y
373CONFIG_FW_LOADER=y
374# CONFIG_SYS_HYPERVISOR is not set
375
376#
377# Connector - unified userspace <-> kernelspace linker
378#
379CONFIG_CONNECTOR=y
380CONFIG_PROC_EVENTS=y
381
382#
383# Memory Technology Devices (MTD)
384#
385# CONFIG_MTD is not set
386
387#
388# Parallel port support
389#
390# CONFIG_PARPORT is not set
391
392#
393# Plug and Play support
394#
395# CONFIG_PNPACPI is not set
396
397#
398# Block devices
399#
400# CONFIG_BLK_CPQ_DA is not set
401# CONFIG_BLK_CPQ_CISS_DA is not set
402# CONFIG_BLK_DEV_DAC960 is not set
403# CONFIG_BLK_DEV_UMEM is not set
404# CONFIG_BLK_DEV_COW_COMMON is not set
405# CONFIG_BLK_DEV_LOOP is not set
406# CONFIG_BLK_DEV_NBD is not set
407# CONFIG_BLK_DEV_SX8 is not set
408# CONFIG_BLK_DEV_RAM is not set
409# CONFIG_BLK_DEV_INITRD is not set
410CONFIG_CDROM_PKTCDVD=y
411CONFIG_CDROM_PKTCDVD_BUFFERS=8
412# CONFIG_CDROM_PKTCDVD_WCACHE is not set
413CONFIG_ATA_OVER_ETH=y
414
415#
416# Misc devices
417#
418CONFIG_SGI_IOC4=y
419# CONFIG_TIFM_CORE is not set
420
421#
422# ATA/ATAPI/MFM/RLL support
423#
424# CONFIG_IDE is not set
425
426#
427# SCSI device support
428#
429CONFIG_RAID_ATTRS=y
430# CONFIG_SCSI is not set
431# CONFIG_SCSI_NETLINK is not set
432
433#
434# Serial ATA (prod) and Parallel ATA (experimental) drivers
435#
436# CONFIG_ATA is not set
437
438#
439# Multi-device support (RAID and LVM)
440#
441# CONFIG_MD is not set
442
443#
444# Fusion MPT device support
445#
446# CONFIG_FUSION is not set
447
448#
449# IEEE 1394 (FireWire) support
450#
451# CONFIG_IEEE1394 is not set
452
453#
454# I2O device support
455#
456# CONFIG_I2O is not set
457
458#
459# Network device support
460#
461CONFIG_NETDEVICES=y
462# CONFIG_DUMMY is not set
463# CONFIG_BONDING is not set
464# CONFIG_EQUALIZER is not set
465# CONFIG_TUN is not set
466
467#
468# ARCnet devices
469#
470# CONFIG_ARCNET is not set
471
472#
473# PHY device support
474#
475CONFIG_PHYLIB=y
476
477#
478# MII PHY device drivers
479#
480CONFIG_MARVELL_PHY=y
481CONFIG_DAVICOM_PHY=y
482CONFIG_QSEMI_PHY=y
483CONFIG_LXT_PHY=y
484CONFIG_CICADA_PHY=y
485CONFIG_VITESSE_PHY=y
486CONFIG_SMSC_PHY=y
487# CONFIG_BROADCOM_PHY is not set
488# CONFIG_FIXED_PHY is not set
489
490#
491# Ethernet (10 or 100Mbit)
492#
493CONFIG_NET_ETHERNET=y
494# CONFIG_MII is not set
495# CONFIG_HAPPYMEAL is not set
496# CONFIG_SUNGEM is not set
497# CONFIG_CASSINI is not set
498# CONFIG_NET_VENDOR_3COM is not set
499# CONFIG_DM9000 is not set
500
501#
502# Tulip family network device support
503#
504# CONFIG_NET_TULIP is not set
505# CONFIG_HP100 is not set
506# CONFIG_NET_PCI is not set
507
508#
509# Ethernet (1000 Mbit)
510#
511# CONFIG_ACENIC is not set
512# CONFIG_DL2K is not set
513# CONFIG_E1000 is not set
514# CONFIG_NS83820 is not set
515# CONFIG_HAMACHI is not set
516# CONFIG_YELLOWFIN is not set
517# CONFIG_R8169 is not set
518# CONFIG_SIS190 is not set
519# CONFIG_SKGE is not set
520# CONFIG_SKY2 is not set
521# CONFIG_SK98LIN is not set
522# CONFIG_TIGON3 is not set
523# CONFIG_BNX2 is not set
524# CONFIG_MV643XX_ETH is not set
525CONFIG_QLA3XXX=y
526# CONFIG_ATL1 is not set
527
528#
529# Ethernet (10000 Mbit)
530#
531# CONFIG_CHELSIO_T1 is not set
532CONFIG_CHELSIO_T3=y
533# CONFIG_IXGB is not set
534# CONFIG_S2IO is not set
535# CONFIG_MYRI10GE is not set
536CONFIG_NETXEN_NIC=y
537
538#
539# Token Ring devices
540#
541# CONFIG_TR is not set
542
543#
544# Wireless LAN (non-hamradio)
545#
546# CONFIG_NET_RADIO is not set
547
548#
549# Wan interfaces
550#
551# CONFIG_WAN is not set
552# CONFIG_FDDI is not set
553# CONFIG_HIPPI is not set
554# CONFIG_PPP is not set
555# CONFIG_SLIP is not set
556# CONFIG_SHAPER is not set
557# CONFIG_NETCONSOLE is not set
558# CONFIG_NETPOLL is not set
559# CONFIG_NET_POLL_CONTROLLER is not set
560
561#
562# ISDN subsystem
563#
564# CONFIG_ISDN is not set
565
566#
567# Telephony Support
568#
569# CONFIG_PHONE is not set
570
571#
572# Input device support
573#
574CONFIG_INPUT=y
575# CONFIG_INPUT_FF_MEMLESS is not set
576
577#
578# Userland interfaces
579#
580CONFIG_INPUT_MOUSEDEV=y
581CONFIG_INPUT_MOUSEDEV_PSAUX=y
582CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
583CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
584# CONFIG_INPUT_JOYDEV is not set
585# CONFIG_INPUT_TSDEV is not set
586# CONFIG_INPUT_EVDEV is not set
587# CONFIG_INPUT_EVBUG is not set
588
589#
590# Input Device Drivers
591#
592# CONFIG_INPUT_KEYBOARD is not set
593# CONFIG_INPUT_MOUSE is not set
594# CONFIG_INPUT_JOYSTICK is not set
595# CONFIG_INPUT_TOUCHSCREEN is not set
596# CONFIG_INPUT_MISC is not set
597
598#
599# Hardware I/O ports
600#
601CONFIG_SERIO=y
602# CONFIG_SERIO_I8042 is not set
603CONFIG_SERIO_SERPORT=y
604# CONFIG_SERIO_PCIPS2 is not set
605# CONFIG_SERIO_LIBPS2 is not set
606CONFIG_SERIO_RAW=y
607# CONFIG_GAMEPORT is not set
608
609#
610# Character devices
611#
612CONFIG_VT=y
613CONFIG_VT_CONSOLE=y
614CONFIG_HW_CONSOLE=y
615CONFIG_VT_HW_CONSOLE_BINDING=y
616# CONFIG_SERIAL_NONSTANDARD is not set
617
618#
619# Serial drivers
620#
621CONFIG_SERIAL_8250=y
622CONFIG_SERIAL_8250_CONSOLE=y
623CONFIG_SERIAL_8250_PCI=y
624CONFIG_SERIAL_8250_NR_UARTS=4
625CONFIG_SERIAL_8250_RUNTIME_UARTS=4
626# CONFIG_SERIAL_8250_EXTENDED is not set
627
628#
629# Non-8250 serial port support
630#
631CONFIG_SERIAL_CORE=y
632CONFIG_SERIAL_CORE_CONSOLE=y
633# CONFIG_SERIAL_JSM is not set
634CONFIG_UNIX98_PTYS=y
635CONFIG_LEGACY_PTYS=y
636CONFIG_LEGACY_PTY_COUNT=256
637
638#
639# IPMI
640#
641# CONFIG_IPMI_HANDLER is not set
642
643#
644# Watchdog Cards
645#
646# CONFIG_WATCHDOG is not set
647# CONFIG_HW_RANDOM is not set
648# CONFIG_RTC is not set
649# CONFIG_GEN_RTC is not set
650# CONFIG_DTLK is not set
651# CONFIG_R3964 is not set
652# CONFIG_APPLICOM is not set
653# CONFIG_DRM is not set
654# CONFIG_RAW_DRIVER is not set
655
656#
657# TPM devices
658#
659# CONFIG_TCG_TPM is not set
660
661#
662# I2C support
663#
664# CONFIG_I2C is not set
665
666#
667# SPI support
668#
669# CONFIG_SPI is not set
670# CONFIG_SPI_MASTER is not set
671
672#
673# Dallas's 1-wire bus
674#
675# CONFIG_W1 is not set
676
677#
678# Hardware Monitoring support
679#
680# CONFIG_HWMON is not set
681# CONFIG_HWMON_VID is not set
682
683#
684# Multimedia devices
685#
686# CONFIG_VIDEO_DEV is not set
687
688#
689# Digital Video Broadcasting Devices
690#
691# CONFIG_DVB is not set
692
693#
694# Graphics support
695#
696# CONFIG_FIRMWARE_EDID is not set
697# CONFIG_FB is not set
698
699#
700# Console display driver support
701#
702# CONFIG_VGA_CONSOLE is not set
703CONFIG_DUMMY_CONSOLE=y
704# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
705
706#
707# Sound
708#
709# CONFIG_SOUND is not set
710
711#
712# HID Devices
713#
714# CONFIG_HID is not set
715
716#
717# USB support
718#
719CONFIG_USB_ARCH_HAS_HCD=y
720CONFIG_USB_ARCH_HAS_OHCI=y
721CONFIG_USB_ARCH_HAS_EHCI=y
722# CONFIG_USB is not set
723
724#
725# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
726#
727
728#
729# USB Gadget Support
730#
731# CONFIG_USB_GADGET is not set
732
733#
734# MMC/SD Card support
735#
736# CONFIG_MMC is not set
737
738#
739# LED devices
740#
741# CONFIG_NEW_LEDS is not set
742
743#
744# LED drivers
745#
746
747#
748# LED Triggers
749#
750
751#
752# InfiniBand support
753#
754# CONFIG_INFINIBAND is not set
755
756#
757# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
758#
759
760#
761# Real Time Clock
762#
763# CONFIG_RTC_CLASS is not set
764
765#
766# DMA Engine support
767#
768# CONFIG_DMA_ENGINE is not set
769
770#
771# DMA Clients
772#
773
774#
775# DMA Devices
776#
777
778#
779# Auxiliary Display support
780#
781
782#
783# Virtualization
784#
785
786#
787# File systems
788#
789CONFIG_EXT2_FS=y
790# CONFIG_EXT2_FS_XATTR is not set
791# CONFIG_EXT2_FS_XIP is not set
792# CONFIG_EXT3_FS is not set
793# CONFIG_EXT4DEV_FS is not set
794# CONFIG_REISERFS_FS is not set
795# CONFIG_JFS_FS is not set
796CONFIG_FS_POSIX_ACL=y
797# CONFIG_XFS_FS is not set
798# CONFIG_GFS2_FS is not set
799# CONFIG_OCFS2_FS is not set
800# CONFIG_MINIX_FS is not set
801# CONFIG_ROMFS_FS is not set
802CONFIG_INOTIFY=y
803CONFIG_INOTIFY_USER=y
804# CONFIG_QUOTA is not set
805CONFIG_DNOTIFY=y
806# CONFIG_AUTOFS_FS is not set
807# CONFIG_AUTOFS4_FS is not set
808CONFIG_FUSE_FS=y
809CONFIG_GENERIC_ACL=y
810
811#
812# CD-ROM/DVD Filesystems
813#
814# CONFIG_ISO9660_FS is not set
815# CONFIG_UDF_FS is not set
816
817#
818# DOS/FAT/NT Filesystems
819#
820# CONFIG_MSDOS_FS is not set
821# CONFIG_VFAT_FS is not set
822# CONFIG_NTFS_FS is not set
823
824#
825# Pseudo filesystems
826#
827CONFIG_PROC_FS=y
828CONFIG_PROC_KCORE=y
829CONFIG_PROC_SYSCTL=y
830CONFIG_SYSFS=y
831CONFIG_TMPFS=y
832CONFIG_TMPFS_POSIX_ACL=y
833# CONFIG_HUGETLB_PAGE is not set
834CONFIG_RAMFS=y
835CONFIG_CONFIGFS_FS=y
836
837#
838# Miscellaneous filesystems
839#
840# CONFIG_ADFS_FS is not set
841# CONFIG_AFFS_FS is not set
842# CONFIG_ECRYPT_FS is not set
843# CONFIG_HFS_FS is not set
844# CONFIG_HFSPLUS_FS is not set
845# CONFIG_BEFS_FS is not set
846# CONFIG_BFS_FS is not set
847# CONFIG_EFS_FS is not set
848# CONFIG_CRAMFS is not set
849# CONFIG_VXFS_FS is not set
850# CONFIG_HPFS_FS is not set
851# CONFIG_QNX4FS_FS is not set
852# CONFIG_SYSV_FS is not set
853# CONFIG_UFS_FS is not set
854
855#
856# Network File Systems
857#
858CONFIG_NFS_FS=y
859# CONFIG_NFS_V3 is not set
860# CONFIG_NFS_V4 is not set
861# CONFIG_NFS_DIRECTIO is not set
862CONFIG_NFSD=y
863# CONFIG_NFSD_V3 is not set
864# CONFIG_NFSD_TCP is not set
865CONFIG_ROOT_NFS=y
866CONFIG_LOCKD=y
867CONFIG_EXPORTFS=y
868CONFIG_NFS_COMMON=y
869CONFIG_SUNRPC=y
870# CONFIG_RPCSEC_GSS_KRB5 is not set
871# CONFIG_RPCSEC_GSS_SPKM3 is not set
872# CONFIG_SMB_FS is not set
873# CONFIG_CIFS is not set
874# CONFIG_NCP_FS is not set
875# CONFIG_CODA_FS is not set
876# CONFIG_AFS_FS is not set
877# CONFIG_9P_FS is not set
878
879#
880# Partition Types
881#
882# CONFIG_PARTITION_ADVANCED is not set
883CONFIG_MSDOS_PARTITION=y
884
885#
886# Native Language Support
887#
888# CONFIG_NLS is not set
889
890#
891# Distributed Lock Manager
892#
893CONFIG_DLM=y
894CONFIG_DLM_TCP=y
895# CONFIG_DLM_SCTP is not set
896# CONFIG_DLM_DEBUG is not set
897
898#
899# Profiling support
900#
901# CONFIG_PROFILING is not set
902
903#
904# Kernel hacking
905#
906CONFIG_TRACE_IRQFLAGS_SUPPORT=y
907# CONFIG_PRINTK_TIME is not set
908CONFIG_ENABLE_MUST_CHECK=y
909# CONFIG_MAGIC_SYSRQ is not set
910# CONFIG_UNUSED_SYMBOLS is not set
911# CONFIG_DEBUG_FS is not set
912# CONFIG_HEADERS_CHECK is not set
913# CONFIG_DEBUG_KERNEL is not set
914CONFIG_LOG_BUF_SHIFT=14
915CONFIG_CROSSCOMPILE=y
916CONFIG_CMDLINE=""
917
918#
919# Security options
920#
921CONFIG_KEYS=y
922CONFIG_KEYS_DEBUG_PROC_KEYS=y
923# CONFIG_SECURITY is not set
924
925#
926# Cryptographic options
927#
928CONFIG_CRYPTO=y
929CONFIG_CRYPTO_ALGAPI=y
930CONFIG_CRYPTO_BLKCIPHER=y
931CONFIG_CRYPTO_HASH=y
932CONFIG_CRYPTO_MANAGER=y
933CONFIG_CRYPTO_HMAC=y
934CONFIG_CRYPTO_XCBC=y
935CONFIG_CRYPTO_NULL=y
936CONFIG_CRYPTO_MD4=y
937CONFIG_CRYPTO_MD5=y
938CONFIG_CRYPTO_SHA1=y
939CONFIG_CRYPTO_SHA256=y
940CONFIG_CRYPTO_SHA512=y
941CONFIG_CRYPTO_WP512=y
942CONFIG_CRYPTO_TGR192=y
943CONFIG_CRYPTO_GF128MUL=y
944CONFIG_CRYPTO_ECB=y
945CONFIG_CRYPTO_CBC=y
946CONFIG_CRYPTO_PCBC=y
947CONFIG_CRYPTO_LRW=y
948CONFIG_CRYPTO_DES=y
949CONFIG_CRYPTO_FCRYPT=y
950CONFIG_CRYPTO_BLOWFISH=y
951CONFIG_CRYPTO_TWOFISH=y
952CONFIG_CRYPTO_TWOFISH_COMMON=y
953CONFIG_CRYPTO_SERPENT=y
954CONFIG_CRYPTO_AES=y
955CONFIG_CRYPTO_CAST5=y
956CONFIG_CRYPTO_CAST6=y
957CONFIG_CRYPTO_TEA=y
958CONFIG_CRYPTO_ARC4=y
959CONFIG_CRYPTO_KHAZAD=y
960CONFIG_CRYPTO_ANUBIS=y
961CONFIG_CRYPTO_DEFLATE=y
962CONFIG_CRYPTO_MICHAEL_MIC=y
963CONFIG_CRYPTO_CRC32C=y
964CONFIG_CRYPTO_CAMELLIA=y
965
966#
967# Hardware crypto devices
968#
969
970#
971# Library routines
972#
973CONFIG_BITREVERSE=y
974# CONFIG_CRC_CCITT is not set
975CONFIG_CRC16=y
976CONFIG_CRC32=y
977CONFIG_LIBCRC32C=y
978CONFIG_ZLIB_INFLATE=y
979CONFIG_ZLIB_DEFLATE=y
980CONFIG_PLIST=y
981CONFIG_HAS_IOMEM=y
982CONFIG_HAS_IOPORT=y
diff --git a/arch/mips/configs/ocelot_defconfig b/arch/mips/configs/ocelot_defconfig
index 15a027e00eec..e1db1fb80cd0 100644
--- a/arch/mips/configs/ocelot_defconfig
+++ b/arch/mips/configs/ocelot_defconfig
@@ -25,9 +25,7 @@ CONFIG_ZONE_DMA=y
25# CONFIG_BASLER_EXCITE is not set 25# CONFIG_BASLER_EXCITE is not set
26# CONFIG_MIPS_COBALT is not set 26# CONFIG_MIPS_COBALT is not set
27# CONFIG_MACH_DECSTATION is not set 27# CONFIG_MACH_DECSTATION is not set
28# CONFIG_MIPS_EV64120 is not set
29# CONFIG_MACH_JAZZ is not set 28# CONFIG_MACH_JAZZ is not set
30# CONFIG_LASAT is not set
31# CONFIG_MIPS_ATLAS is not set 29# CONFIG_MIPS_ATLAS is not set
32# CONFIG_MIPS_MALTA is not set 30# CONFIG_MIPS_MALTA is not set
33# CONFIG_MIPS_SEAD is not set 31# CONFIG_MIPS_SEAD is not set
@@ -35,8 +33,6 @@ CONFIG_ZONE_DMA=y
35# CONFIG_MIPS_SIM is not set 33# CONFIG_MIPS_SIM is not set
36# CONFIG_MOMENCO_JAGUAR_ATX is not set 34# CONFIG_MOMENCO_JAGUAR_ATX is not set
37CONFIG_MOMENCO_OCELOT=y 35CONFIG_MOMENCO_OCELOT=y
38# CONFIG_MOMENCO_OCELOT_3 is not set
39# CONFIG_MOMENCO_OCELOT_C is not set
40# CONFIG_MOMENCO_OCELOT_G is not set 36# CONFIG_MOMENCO_OCELOT_G is not set
41# CONFIG_MIPS_XXS1500 is not set 37# CONFIG_MIPS_XXS1500 is not set
42# CONFIG_PNX8550_JBS is not set 38# CONFIG_PNX8550_JBS is not set
diff --git a/arch/mips/configs/pb1100_defconfig b/arch/mips/configs/pb1100_defconfig
index 37d696c64541..0028aef0af9d 100644
--- a/arch/mips/configs/pb1100_defconfig
+++ b/arch/mips/configs/pb1100_defconfig
@@ -26,9 +26,7 @@ CONFIG_MIPS_PB1100=y
26# CONFIG_BASLER_EXCITE is not set 26# CONFIG_BASLER_EXCITE is not set
27# CONFIG_MIPS_COBALT is not set 27# CONFIG_MIPS_COBALT is not set
28# CONFIG_MACH_DECSTATION is not set 28# CONFIG_MACH_DECSTATION is not set
29# CONFIG_MIPS_EV64120 is not set
30# CONFIG_MACH_JAZZ is not set 29# CONFIG_MACH_JAZZ is not set
31# CONFIG_LASAT is not set
32# CONFIG_MIPS_ATLAS is not set 30# CONFIG_MIPS_ATLAS is not set
33# CONFIG_MIPS_MALTA is not set 31# CONFIG_MIPS_MALTA is not set
34# CONFIG_MIPS_SEAD is not set 32# CONFIG_MIPS_SEAD is not set
@@ -36,8 +34,6 @@ CONFIG_MIPS_PB1100=y
36# CONFIG_MIPS_SIM is not set 34# CONFIG_MIPS_SIM is not set
37# CONFIG_MOMENCO_JAGUAR_ATX is not set 35# CONFIG_MOMENCO_JAGUAR_ATX is not set
38# CONFIG_MOMENCO_OCELOT is not set 36# CONFIG_MOMENCO_OCELOT is not set
39# CONFIG_MOMENCO_OCELOT_3 is not set
40# CONFIG_MOMENCO_OCELOT_C is not set
41# CONFIG_MOMENCO_OCELOT_G is not set 37# CONFIG_MOMENCO_OCELOT_G is not set
42# CONFIG_MIPS_XXS1500 is not set 38# CONFIG_MIPS_XXS1500 is not set
43# CONFIG_PNX8550_JBS is not set 39# CONFIG_PNX8550_JBS is not set
diff --git a/arch/mips/configs/pb1500_defconfig b/arch/mips/configs/pb1500_defconfig
index b11f0e8b6059..8a1d5888739c 100644
--- a/arch/mips/configs/pb1500_defconfig
+++ b/arch/mips/configs/pb1500_defconfig
@@ -26,9 +26,7 @@ CONFIG_MIPS_PB1500=y
26# CONFIG_BASLER_EXCITE is not set 26# CONFIG_BASLER_EXCITE is not set
27# CONFIG_MIPS_COBALT is not set 27# CONFIG_MIPS_COBALT is not set
28# CONFIG_MACH_DECSTATION is not set 28# CONFIG_MACH_DECSTATION is not set
29# CONFIG_MIPS_EV64120 is not set
30# CONFIG_MACH_JAZZ is not set 29# CONFIG_MACH_JAZZ is not set
31# CONFIG_LASAT is not set
32# CONFIG_MIPS_ATLAS is not set 30# CONFIG_MIPS_ATLAS is not set
33# CONFIG_MIPS_MALTA is not set 31# CONFIG_MIPS_MALTA is not set
34# CONFIG_MIPS_SEAD is not set 32# CONFIG_MIPS_SEAD is not set
@@ -36,8 +34,6 @@ CONFIG_MIPS_PB1500=y
36# CONFIG_MIPS_SIM is not set 34# CONFIG_MIPS_SIM is not set
37# CONFIG_MOMENCO_JAGUAR_ATX is not set 35# CONFIG_MOMENCO_JAGUAR_ATX is not set
38# CONFIG_MOMENCO_OCELOT is not set 36# CONFIG_MOMENCO_OCELOT is not set
39# CONFIG_MOMENCO_OCELOT_3 is not set
40# CONFIG_MOMENCO_OCELOT_C is not set
41# CONFIG_MOMENCO_OCELOT_G is not set 37# CONFIG_MOMENCO_OCELOT_G is not set
42# CONFIG_MIPS_XXS1500 is not set 38# CONFIG_MIPS_XXS1500 is not set
43# CONFIG_PNX8550_JBS is not set 39# CONFIG_PNX8550_JBS is not set
diff --git a/arch/mips/configs/pb1550_defconfig b/arch/mips/configs/pb1550_defconfig
index 2927f38f4907..5581ad2ca411 100644
--- a/arch/mips/configs/pb1550_defconfig
+++ b/arch/mips/configs/pb1550_defconfig
@@ -26,9 +26,7 @@ CONFIG_MIPS_PB1550=y
26# CONFIG_BASLER_EXCITE is not set 26# CONFIG_BASLER_EXCITE is not set
27# CONFIG_MIPS_COBALT is not set 27# CONFIG_MIPS_COBALT is not set
28# CONFIG_MACH_DECSTATION is not set 28# CONFIG_MACH_DECSTATION is not set
29# CONFIG_MIPS_EV64120 is not set
30# CONFIG_MACH_JAZZ is not set 29# CONFIG_MACH_JAZZ is not set
31# CONFIG_LASAT is not set
32# CONFIG_MIPS_ATLAS is not set 30# CONFIG_MIPS_ATLAS is not set
33# CONFIG_MIPS_MALTA is not set 31# CONFIG_MIPS_MALTA is not set
34# CONFIG_MIPS_SEAD is not set 32# CONFIG_MIPS_SEAD is not set
@@ -36,8 +34,6 @@ CONFIG_MIPS_PB1550=y
36# CONFIG_MIPS_SIM is not set 34# CONFIG_MIPS_SIM is not set
37# CONFIG_MOMENCO_JAGUAR_ATX is not set 35# CONFIG_MOMENCO_JAGUAR_ATX is not set
38# CONFIG_MOMENCO_OCELOT is not set 36# CONFIG_MOMENCO_OCELOT is not set
39# CONFIG_MOMENCO_OCELOT_3 is not set
40# CONFIG_MOMENCO_OCELOT_C is not set
41# CONFIG_MOMENCO_OCELOT_G is not set 37# CONFIG_MOMENCO_OCELOT_G is not set
42# CONFIG_MIPS_XXS1500 is not set 38# CONFIG_MIPS_XXS1500 is not set
43# CONFIG_PNX8550_JBS is not set 39# CONFIG_PNX8550_JBS is not set
diff --git a/arch/mips/configs/pnx8550-jbs_defconfig b/arch/mips/configs/pnx8550-jbs_defconfig
index fae16c5ec521..821c1cee5639 100644
--- a/arch/mips/configs/pnx8550-jbs_defconfig
+++ b/arch/mips/configs/pnx8550-jbs_defconfig
@@ -25,9 +25,7 @@ CONFIG_ZONE_DMA=y
25# CONFIG_BASLER_EXCITE is not set 25# CONFIG_BASLER_EXCITE is not set
26# CONFIG_MIPS_COBALT is not set 26# CONFIG_MIPS_COBALT is not set
27# CONFIG_MACH_DECSTATION is not set 27# CONFIG_MACH_DECSTATION is not set
28# CONFIG_MIPS_EV64120 is not set
29# CONFIG_MACH_JAZZ is not set 28# CONFIG_MACH_JAZZ is not set
30# CONFIG_LASAT is not set
31# CONFIG_MIPS_ATLAS is not set 29# CONFIG_MIPS_ATLAS is not set
32# CONFIG_MIPS_MALTA is not set 30# CONFIG_MIPS_MALTA is not set
33# CONFIG_MIPS_SEAD is not set 31# CONFIG_MIPS_SEAD is not set
@@ -35,8 +33,6 @@ CONFIG_ZONE_DMA=y
35# CONFIG_MIPS_SIM is not set 33# CONFIG_MIPS_SIM is not set
36# CONFIG_MOMENCO_JAGUAR_ATX is not set 34# CONFIG_MOMENCO_JAGUAR_ATX is not set
37# CONFIG_MOMENCO_OCELOT is not set 35# CONFIG_MOMENCO_OCELOT is not set
38# CONFIG_MOMENCO_OCELOT_3 is not set
39# CONFIG_MOMENCO_OCELOT_C is not set
40# CONFIG_MOMENCO_OCELOT_G is not set 36# CONFIG_MOMENCO_OCELOT_G is not set
41# CONFIG_MIPS_XXS1500 is not set 37# CONFIG_MIPS_XXS1500 is not set
42CONFIG_PNX8550_JBS=y 38CONFIG_PNX8550_JBS=y
diff --git a/arch/mips/configs/pnx8550-stb810_defconfig b/arch/mips/configs/pnx8550-stb810_defconfig
index cd821e52181d..0e8bd92b38cf 100644
--- a/arch/mips/configs/pnx8550-stb810_defconfig
+++ b/arch/mips/configs/pnx8550-stb810_defconfig
@@ -25,9 +25,7 @@ CONFIG_ZONE_DMA=y
25# CONFIG_BASLER_EXCITE is not set 25# CONFIG_BASLER_EXCITE is not set
26# CONFIG_MIPS_COBALT is not set 26# CONFIG_MIPS_COBALT is not set
27# CONFIG_MACH_DECSTATION is not set 27# CONFIG_MACH_DECSTATION is not set
28# CONFIG_MIPS_EV64120 is not set
29# CONFIG_MACH_JAZZ is not set 28# CONFIG_MACH_JAZZ is not set
30# CONFIG_LASAT is not set
31# CONFIG_MIPS_ATLAS is not set 29# CONFIG_MIPS_ATLAS is not set
32# CONFIG_MIPS_MALTA is not set 30# CONFIG_MIPS_MALTA is not set
33# CONFIG_MIPS_SEAD is not set 31# CONFIG_MIPS_SEAD is not set
@@ -35,8 +33,6 @@ CONFIG_ZONE_DMA=y
35# CONFIG_MIPS_SIM is not set 33# CONFIG_MIPS_SIM is not set
36# CONFIG_MOMENCO_JAGUAR_ATX is not set 34# CONFIG_MOMENCO_JAGUAR_ATX is not set
37# CONFIG_MOMENCO_OCELOT is not set 35# CONFIG_MOMENCO_OCELOT is not set
38# CONFIG_MOMENCO_OCELOT_3 is not set
39# CONFIG_MOMENCO_OCELOT_C is not set
40# CONFIG_MOMENCO_OCELOT_G is not set 36# CONFIG_MOMENCO_OCELOT_G is not set
41# CONFIG_MIPS_XXS1500 is not set 37# CONFIG_MIPS_XXS1500 is not set
42# CONFIG_PNX8550_JBS is not set 38# CONFIG_PNX8550_JBS is not set
diff --git a/arch/mips/configs/qemu_defconfig b/arch/mips/configs/qemu_defconfig
index 8e8d03157954..6cca105832ca 100644
--- a/arch/mips/configs/qemu_defconfig
+++ b/arch/mips/configs/qemu_defconfig
@@ -25,9 +25,7 @@ CONFIG_ZONE_DMA=y
25# CONFIG_BASLER_EXCITE is not set 25# CONFIG_BASLER_EXCITE is not set
26# CONFIG_MIPS_COBALT is not set 26# CONFIG_MIPS_COBALT is not set
27# CONFIG_MACH_DECSTATION is not set 27# CONFIG_MACH_DECSTATION is not set
28# CONFIG_MIPS_EV64120 is not set
29# CONFIG_MACH_JAZZ is not set 28# CONFIG_MACH_JAZZ is not set
30# CONFIG_LASAT is not set
31# CONFIG_MIPS_ATLAS is not set 29# CONFIG_MIPS_ATLAS is not set
32# CONFIG_MIPS_MALTA is not set 30# CONFIG_MIPS_MALTA is not set
33# CONFIG_MIPS_SEAD is not set 31# CONFIG_MIPS_SEAD is not set
@@ -35,8 +33,6 @@ CONFIG_ZONE_DMA=y
35# CONFIG_MIPS_SIM is not set 33# CONFIG_MIPS_SIM is not set
36# CONFIG_MOMENCO_JAGUAR_ATX is not set 34# CONFIG_MOMENCO_JAGUAR_ATX is not set
37# CONFIG_MOMENCO_OCELOT is not set 35# CONFIG_MOMENCO_OCELOT is not set
38# CONFIG_MOMENCO_OCELOT_3 is not set
39# CONFIG_MOMENCO_OCELOT_C is not set
40# CONFIG_MOMENCO_OCELOT_G is not set 36# CONFIG_MOMENCO_OCELOT_G is not set
41# CONFIG_MIPS_XXS1500 is not set 37# CONFIG_MIPS_XXS1500 is not set
42# CONFIG_PNX8550_JBS is not set 38# CONFIG_PNX8550_JBS is not set
diff --git a/arch/mips/configs/rbhma4200_defconfig b/arch/mips/configs/rbhma4200_defconfig
index 35d64260917e..20a38526d483 100644
--- a/arch/mips/configs/rbhma4200_defconfig
+++ b/arch/mips/configs/rbhma4200_defconfig
@@ -24,17 +24,13 @@ CONFIG_MIPS=y
24# CONFIG_BASLER_EXCITE is not set 24# CONFIG_BASLER_EXCITE is not set
25# CONFIG_MIPS_COBALT is not set 25# CONFIG_MIPS_COBALT is not set
26# CONFIG_MACH_DECSTATION is not set 26# CONFIG_MACH_DECSTATION is not set
27# CONFIG_MIPS_EV64120 is not set
28# CONFIG_MACH_JAZZ is not set 27# CONFIG_MACH_JAZZ is not set
29# CONFIG_LASAT is not set
30# CONFIG_MIPS_ATLAS is not set 28# CONFIG_MIPS_ATLAS is not set
31# CONFIG_MIPS_MALTA is not set 29# CONFIG_MIPS_MALTA is not set
32# CONFIG_MIPS_SEAD is not set 30# CONFIG_MIPS_SEAD is not set
33# CONFIG_WR_PPMC is not set 31# CONFIG_WR_PPMC is not set
34# CONFIG_MIPS_SIM is not set 32# CONFIG_MIPS_SIM is not set
35# CONFIG_MOMENCO_OCELOT is not set 33# CONFIG_MOMENCO_OCELOT is not set
36# CONFIG_MOMENCO_OCELOT_3 is not set
37# CONFIG_MOMENCO_OCELOT_C is not set
38# CONFIG_MIPS_XXS1500 is not set 34# CONFIG_MIPS_XXS1500 is not set
39# CONFIG_PNX8550_JBS is not set 35# CONFIG_PNX8550_JBS is not set
40# CONFIG_PNX8550_STB810 is not set 36# CONFIG_PNX8550_STB810 is not set
diff --git a/arch/mips/configs/rbhma4500_defconfig b/arch/mips/configs/rbhma4500_defconfig
index 41011f770a67..5dbb250f71c7 100644
--- a/arch/mips/configs/rbhma4500_defconfig
+++ b/arch/mips/configs/rbhma4500_defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.20 3# Linux kernel version: 2.6.22-rc5
4# Tue Feb 20 21:47:39 2007 4# Fri Jun 22 21:39:45 2007
5# 5#
6CONFIG_MIPS=y 6CONFIG_MIPS=y
7 7
@@ -9,40 +9,23 @@ CONFIG_MIPS=y
9# Machine selection 9# Machine selection
10# 10#
11CONFIG_ZONE_DMA=y 11CONFIG_ZONE_DMA=y
12# CONFIG_MIPS_MTX1 is not set 12# CONFIG_LEMOTE_FULONG is not set
13# CONFIG_MIPS_BOSPORUS is not set 13# CONFIG_MACH_ALCHEMY is not set
14# CONFIG_MIPS_PB1000 is not set
15# CONFIG_MIPS_PB1100 is not set
16# CONFIG_MIPS_PB1500 is not set
17# CONFIG_MIPS_PB1550 is not set
18# CONFIG_MIPS_PB1200 is not set
19# CONFIG_MIPS_DB1000 is not set
20# CONFIG_MIPS_DB1100 is not set
21# CONFIG_MIPS_DB1500 is not set
22# CONFIG_MIPS_DB1550 is not set
23# CONFIG_MIPS_DB1200 is not set
24# CONFIG_MIPS_MIRAGE is not set
25# CONFIG_BASLER_EXCITE is not set 14# CONFIG_BASLER_EXCITE is not set
26# CONFIG_MIPS_COBALT is not set 15# CONFIG_MIPS_COBALT is not set
27# CONFIG_MACH_DECSTATION is not set 16# CONFIG_MACH_DECSTATION is not set
28# CONFIG_MIPS_EV64120 is not set
29# CONFIG_MACH_JAZZ is not set 17# CONFIG_MACH_JAZZ is not set
30# CONFIG_LASAT is not set
31# CONFIG_MIPS_ATLAS is not set 18# CONFIG_MIPS_ATLAS is not set
32# CONFIG_MIPS_MALTA is not set 19# CONFIG_MIPS_MALTA is not set
33# CONFIG_MIPS_SEAD is not set 20# CONFIG_MIPS_SEAD is not set
34# CONFIG_WR_PPMC is not set 21# CONFIG_WR_PPMC is not set
35# CONFIG_MIPS_SIM is not set 22# CONFIG_MIPS_SIM is not set
36# CONFIG_MOMENCO_JAGUAR_ATX is not set
37# CONFIG_MOMENCO_OCELOT is not set 23# CONFIG_MOMENCO_OCELOT is not set
38# CONFIG_MOMENCO_OCELOT_3 is not set
39# CONFIG_MOMENCO_OCELOT_C is not set
40# CONFIG_MOMENCO_OCELOT_G is not set
41# CONFIG_MIPS_XXS1500 is not set
42# CONFIG_PNX8550_JBS is not set 24# CONFIG_PNX8550_JBS is not set
43# CONFIG_PNX8550_STB810 is not set 25# CONFIG_PNX8550_STB810 is not set
44# CONFIG_DDB5477 is not set 26# CONFIG_DDB5477 is not set
45# CONFIG_MACH_VR41XX is not set 27# CONFIG_MACH_VR41XX is not set
28# CONFIG_PMC_MSP is not set
46# CONFIG_PMC_YOSEMITE is not set 29# CONFIG_PMC_YOSEMITE is not set
47# CONFIG_QEMU is not set 30# CONFIG_QEMU is not set
48# CONFIG_MARKEINS is not set 31# CONFIG_MARKEINS is not set
@@ -82,6 +65,8 @@ CONFIG_DMA_NONCOHERENT=y
82CONFIG_DMA_NEED_PCI_MAP_STATE=y 65CONFIG_DMA_NEED_PCI_MAP_STATE=y
83CONFIG_GENERIC_ISA_DMA=y 66CONFIG_GENERIC_ISA_DMA=y
84CONFIG_I8259=y 67CONFIG_I8259=y
68# CONFIG_NO_IOPORT is not set
69CONFIG_GENERIC_GPIO=y
85# CONFIG_CPU_BIG_ENDIAN is not set 70# CONFIG_CPU_BIG_ENDIAN is not set
86CONFIG_CPU_LITTLE_ENDIAN=y 71CONFIG_CPU_LITTLE_ENDIAN=y
87CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y 72CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
@@ -93,6 +78,7 @@ CONFIG_HAVE_STD_PC_SERIAL_PORT=y
93# 78#
94# CPU selection 79# CPU selection
95# 80#
81# CONFIG_CPU_LOONGSON2 is not set
96# CONFIG_CPU_MIPS32_R1 is not set 82# CONFIG_CPU_MIPS32_R1 is not set
97# CONFIG_CPU_MIPS32_R2 is not set 83# CONFIG_CPU_MIPS32_R2 is not set
98# CONFIG_CPU_MIPS64_R1 is not set 84# CONFIG_CPU_MIPS64_R1 is not set
@@ -149,12 +135,12 @@ CONFIG_ZONE_DMA_FLAG=1
149# CONFIG_HZ_48 is not set 135# CONFIG_HZ_48 is not set
150# CONFIG_HZ_100 is not set 136# CONFIG_HZ_100 is not set
151# CONFIG_HZ_128 is not set 137# CONFIG_HZ_128 is not set
152# CONFIG_HZ_250 is not set 138CONFIG_HZ_250=y
153# CONFIG_HZ_256 is not set 139# CONFIG_HZ_256 is not set
154CONFIG_HZ_1000=y 140# CONFIG_HZ_1000 is not set
155# CONFIG_HZ_1024 is not set 141# CONFIG_HZ_1024 is not set
156CONFIG_SYS_SUPPORTS_ARBIT_HZ=y 142CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
157CONFIG_HZ=1000 143CONFIG_HZ=250
158CONFIG_PREEMPT_NONE=y 144CONFIG_PREEMPT_NONE=y
159# CONFIG_PREEMPT_VOLUNTARY is not set 145# CONFIG_PREEMPT_VOLUNTARY is not set
160# CONFIG_PREEMPT is not set 146# CONFIG_PREEMPT is not set
@@ -186,28 +172,35 @@ CONFIG_SYSVIPC_SYSCTL=y
186# CONFIG_AUDIT is not set 172# CONFIG_AUDIT is not set
187CONFIG_IKCONFIG=y 173CONFIG_IKCONFIG=y
188CONFIG_IKCONFIG_PROC=y 174CONFIG_IKCONFIG_PROC=y
175CONFIG_LOG_BUF_SHIFT=14
189CONFIG_SYSFS_DEPRECATED=y 176CONFIG_SYSFS_DEPRECATED=y
190CONFIG_RELAY=y 177# CONFIG_RELAY is not set
178CONFIG_BLK_DEV_INITRD=y
191CONFIG_INITRAMFS_SOURCE="" 179CONFIG_INITRAMFS_SOURCE=""
192# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set 180CONFIG_CC_OPTIMIZE_FOR_SIZE=y
193CONFIG_SYSCTL=y 181CONFIG_SYSCTL=y
194CONFIG_EMBEDDED=y 182CONFIG_EMBEDDED=y
195CONFIG_SYSCTL_SYSCALL=y 183CONFIG_SYSCTL_SYSCALL=y
196CONFIG_KALLSYMS=y 184CONFIG_KALLSYMS=y
197# CONFIG_KALLSYMS_EXTRA_PASS is not set 185# CONFIG_KALLSYMS_EXTRA_PASS is not set
198CONFIG_HOTPLUG=y 186# CONFIG_HOTPLUG is not set
199CONFIG_PRINTK=y 187CONFIG_PRINTK=y
200CONFIG_BUG=y 188CONFIG_BUG=y
201CONFIG_ELF_CORE=y 189CONFIG_ELF_CORE=y
202CONFIG_BASE_FULL=y 190CONFIG_BASE_FULL=y
203# CONFIG_FUTEX is not set 191# CONFIG_FUTEX is not set
192CONFIG_ANON_INODES=y
204# CONFIG_EPOLL is not set 193# CONFIG_EPOLL is not set
194CONFIG_SIGNALFD=y
195CONFIG_TIMERFD=y
196CONFIG_EVENTFD=y
205CONFIG_SHMEM=y 197CONFIG_SHMEM=y
206CONFIG_SLAB=y
207CONFIG_VM_EVENT_COUNTERS=y 198CONFIG_VM_EVENT_COUNTERS=y
199CONFIG_SLAB=y
200# CONFIG_SLUB is not set
201# CONFIG_SLOB is not set
208# CONFIG_TINY_SHMEM is not set 202# CONFIG_TINY_SHMEM is not set
209CONFIG_BASE_SMALL=0 203CONFIG_BASE_SMALL=0
210# CONFIG_SLOB is not set
211 204
212# 205#
213# Loadable module support 206# Loadable module support
@@ -244,17 +237,12 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
244# 237#
245CONFIG_HW_HAS_PCI=y 238CONFIG_HW_HAS_PCI=y
246CONFIG_PCI=y 239CONFIG_PCI=y
240# CONFIG_ARCH_SUPPORTS_MSI is not set
247CONFIG_MMU=y 241CONFIG_MMU=y
248 242
249# 243#
250# PCCARD (PCMCIA/CardBus) support 244# PCCARD (PCMCIA/CardBus) support
251# 245#
252# CONFIG_PCCARD is not set
253
254#
255# PCI Hotplug Support
256#
257# CONFIG_HOTPLUG_PCI is not set
258 246
259# 247#
260# Executable file formats 248# Executable file formats
@@ -266,10 +254,7 @@ CONFIG_TRAD_SIGNALS=y
266# 254#
267# Power management options 255# Power management options
268# 256#
269CONFIG_PM=y 257# CONFIG_PM is not set
270# CONFIG_PM_LEGACY is not set
271# CONFIG_PM_DEBUG is not set
272# CONFIG_PM_SYSFS_DEPRECATED is not set
273 258
274# 259#
275# Networking 260# Networking
@@ -279,14 +264,9 @@ CONFIG_NET=y
279# 264#
280# Networking options 265# Networking options
281# 266#
282# CONFIG_NETDEBUG is not set
283CONFIG_PACKET=y 267CONFIG_PACKET=y
284# CONFIG_PACKET_MMAP is not set 268# CONFIG_PACKET_MMAP is not set
285CONFIG_UNIX=y 269CONFIG_UNIX=y
286CONFIG_XFRM=y
287# CONFIG_XFRM_USER is not set
288# CONFIG_XFRM_SUB_POLICY is not set
289CONFIG_XFRM_MIGRATE=y
290# CONFIG_NET_KEY is not set 270# CONFIG_NET_KEY is not set
291CONFIG_INET=y 271CONFIG_INET=y
292CONFIG_IP_MULTICAST=y 272CONFIG_IP_MULTICAST=y
@@ -294,7 +274,7 @@ CONFIG_IP_MULTICAST=y
294CONFIG_IP_FIB_HASH=y 274CONFIG_IP_FIB_HASH=y
295CONFIG_IP_PNP=y 275CONFIG_IP_PNP=y
296# CONFIG_IP_PNP_DHCP is not set 276# CONFIG_IP_PNP_DHCP is not set
297CONFIG_IP_PNP_BOOTP=y 277# CONFIG_IP_PNP_BOOTP is not set
298# CONFIG_IP_PNP_RARP is not set 278# CONFIG_IP_PNP_RARP is not set
299# CONFIG_NET_IPIP is not set 279# CONFIG_NET_IPIP is not set
300# CONFIG_NET_IPGRE is not set 280# CONFIG_NET_IPGRE is not set
@@ -305,130 +285,23 @@ CONFIG_IP_PNP_BOOTP=y
305# CONFIG_INET_ESP is not set 285# CONFIG_INET_ESP is not set
306# CONFIG_INET_IPCOMP is not set 286# CONFIG_INET_IPCOMP is not set
307# CONFIG_INET_XFRM_TUNNEL is not set 287# CONFIG_INET_XFRM_TUNNEL is not set
308CONFIG_INET_TUNNEL=m 288# CONFIG_INET_TUNNEL is not set
309CONFIG_INET_XFRM_MODE_TRANSPORT=m 289# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
310CONFIG_INET_XFRM_MODE_TUNNEL=m 290# CONFIG_INET_XFRM_MODE_TUNNEL is not set
311CONFIG_INET_XFRM_MODE_BEET=m 291# CONFIG_INET_XFRM_MODE_BEET is not set
312CONFIG_INET_DIAG=y 292CONFIG_INET_DIAG=y
313CONFIG_INET_TCP_DIAG=y 293CONFIG_INET_TCP_DIAG=y
314# CONFIG_TCP_CONG_ADVANCED is not set 294# CONFIG_TCP_CONG_ADVANCED is not set
315CONFIG_TCP_CONG_CUBIC=y 295CONFIG_TCP_CONG_CUBIC=y
316CONFIG_DEFAULT_TCP_CONG="cubic" 296CONFIG_DEFAULT_TCP_CONG="cubic"
317CONFIG_TCP_MD5SIG=y 297# CONFIG_TCP_MD5SIG is not set
318 298# CONFIG_IPV6 is not set
319#
320# IP: Virtual Server Configuration
321#
322# CONFIG_IP_VS is not set
323CONFIG_IPV6=m
324# CONFIG_IPV6_PRIVACY is not set
325CONFIG_IPV6_ROUTER_PREF=y
326CONFIG_IPV6_ROUTE_INFO=y
327# CONFIG_INET6_AH is not set
328# CONFIG_INET6_ESP is not set
329# CONFIG_INET6_IPCOMP is not set
330CONFIG_IPV6_MIP6=y
331# CONFIG_INET6_XFRM_TUNNEL is not set 299# CONFIG_INET6_XFRM_TUNNEL is not set
332# CONFIG_INET6_TUNNEL is not set 300# CONFIG_INET6_TUNNEL is not set
333CONFIG_INET6_XFRM_MODE_TRANSPORT=m 301# CONFIG_NETWORK_SECMARK is not set
334CONFIG_INET6_XFRM_MODE_TUNNEL=m 302# CONFIG_NETFILTER is not set
335CONFIG_INET6_XFRM_MODE_BEET=m
336CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
337CONFIG_IPV6_SIT=m
338# CONFIG_IPV6_TUNNEL is not set
339CONFIG_IPV6_MULTIPLE_TABLES=y
340CONFIG_IPV6_SUBTREES=y
341CONFIG_NETWORK_SECMARK=y
342CONFIG_NETFILTER=y
343# CONFIG_NETFILTER_DEBUG is not set
344
345#
346# Core Netfilter Configuration
347#
348CONFIG_NETFILTER_NETLINK=m
349CONFIG_NETFILTER_NETLINK_QUEUE=m
350CONFIG_NETFILTER_NETLINK_LOG=m
351CONFIG_NF_CONNTRACK_ENABLED=m
352CONFIG_NF_CONNTRACK_SUPPORT=y
353# CONFIG_IP_NF_CONNTRACK_SUPPORT is not set
354CONFIG_NF_CONNTRACK=m
355CONFIG_NF_CT_ACCT=y
356CONFIG_NF_CONNTRACK_MARK=y
357CONFIG_NF_CONNTRACK_SECMARK=y
358CONFIG_NF_CONNTRACK_EVENTS=y
359CONFIG_NF_CT_PROTO_GRE=m
360CONFIG_NF_CT_PROTO_SCTP=m
361CONFIG_NF_CONNTRACK_AMANDA=m
362CONFIG_NF_CONNTRACK_FTP=m
363CONFIG_NF_CONNTRACK_H323=m
364CONFIG_NF_CONNTRACK_IRC=m
365# CONFIG_NF_CONNTRACK_NETBIOS_NS is not set
366CONFIG_NF_CONNTRACK_PPTP=m
367CONFIG_NF_CONNTRACK_SANE=m
368CONFIG_NF_CONNTRACK_SIP=m
369CONFIG_NF_CONNTRACK_TFTP=m
370CONFIG_NF_CT_NETLINK=m
371CONFIG_NETFILTER_XTABLES=m
372CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
373CONFIG_NETFILTER_XT_TARGET_MARK=m
374CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
375CONFIG_NETFILTER_XT_TARGET_NFLOG=m
376CONFIG_NETFILTER_XT_TARGET_SECMARK=m
377CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
378CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
379CONFIG_NETFILTER_XT_MATCH_COMMENT=m
380CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
381CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
382CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
383CONFIG_NETFILTER_XT_MATCH_DCCP=m
384CONFIG_NETFILTER_XT_MATCH_DSCP=m
385CONFIG_NETFILTER_XT_MATCH_ESP=m
386CONFIG_NETFILTER_XT_MATCH_HELPER=m
387CONFIG_NETFILTER_XT_MATCH_LENGTH=m
388CONFIG_NETFILTER_XT_MATCH_LIMIT=m
389CONFIG_NETFILTER_XT_MATCH_MAC=m
390CONFIG_NETFILTER_XT_MATCH_MARK=m
391# CONFIG_NETFILTER_XT_MATCH_POLICY is not set
392CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
393CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
394CONFIG_NETFILTER_XT_MATCH_QUOTA=m
395CONFIG_NETFILTER_XT_MATCH_REALM=m
396CONFIG_NETFILTER_XT_MATCH_SCTP=m
397CONFIG_NETFILTER_XT_MATCH_STATE=m
398CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
399CONFIG_NETFILTER_XT_MATCH_STRING=m
400CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
401CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
402
403#
404# IP: Netfilter Configuration
405#
406CONFIG_NF_CONNTRACK_IPV4=m
407CONFIG_NF_CONNTRACK_PROC_COMPAT=y
408# CONFIG_IP_NF_QUEUE is not set
409# CONFIG_IP_NF_IPTABLES is not set
410# CONFIG_IP_NF_ARPTABLES is not set
411
412#
413# IPv6: Netfilter Configuration (EXPERIMENTAL)
414#
415CONFIG_NF_CONNTRACK_IPV6=m
416# CONFIG_IP6_NF_QUEUE is not set
417# CONFIG_IP6_NF_IPTABLES is not set
418
419#
420# DCCP Configuration (EXPERIMENTAL)
421#
422# CONFIG_IP_DCCP is not set 303# CONFIG_IP_DCCP is not set
423
424#
425# SCTP Configuration (EXPERIMENTAL)
426#
427# CONFIG_IP_SCTP is not set 304# CONFIG_IP_SCTP is not set
428
429#
430# TIPC Configuration (EXPERIMENTAL)
431#
432# CONFIG_TIPC is not set 305# CONFIG_TIPC is not set
433# CONFIG_ATM is not set 306# CONFIG_ATM is not set
434# CONFIG_BRIDGE is not set 307# CONFIG_BRIDGE is not set
@@ -446,7 +319,6 @@ CONFIG_NF_CONNTRACK_IPV6=m
446# QoS and/or fair queueing 319# QoS and/or fair queueing
447# 320#
448# CONFIG_NET_SCHED is not set 321# CONFIG_NET_SCHED is not set
449CONFIG_NET_CLS_ROUTE=y
450 322
451# 323#
452# Network testing 324# Network testing
@@ -455,15 +327,16 @@ CONFIG_NET_CLS_ROUTE=y
455# CONFIG_HAMRADIO is not set 327# CONFIG_HAMRADIO is not set
456# CONFIG_IRDA is not set 328# CONFIG_IRDA is not set
457# CONFIG_BT is not set 329# CONFIG_BT is not set
458CONFIG_IEEE80211=m 330# CONFIG_AF_RXRPC is not set
459# CONFIG_IEEE80211_DEBUG is not set 331
460CONFIG_IEEE80211_CRYPT_WEP=m 332#
461CONFIG_IEEE80211_CRYPT_CCMP=m 333# Wireless
462CONFIG_IEEE80211_CRYPT_TKIP=m 334#
463CONFIG_IEEE80211_SOFTMAC=m 335# CONFIG_CFG80211 is not set
464# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set 336# CONFIG_WIRELESS_EXT is not set
465CONFIG_WIRELESS_EXT=y 337# CONFIG_MAC80211 is not set
466CONFIG_FIB_RULES=y 338# CONFIG_IEEE80211 is not set
339# CONFIG_RFKILL is not set
467 340
468# 341#
469# Device Drivers 342# Device Drivers
@@ -474,94 +347,13 @@ CONFIG_FIB_RULES=y
474# 347#
475CONFIG_STANDALONE=y 348CONFIG_STANDALONE=y
476CONFIG_PREVENT_FIRMWARE_BUILD=y 349CONFIG_PREVENT_FIRMWARE_BUILD=y
477CONFIG_FW_LOADER=m
478# CONFIG_SYS_HYPERVISOR is not set 350# CONFIG_SYS_HYPERVISOR is not set
479 351
480# 352#
481# Connector - unified userspace <-> kernelspace linker 353# Connector - unified userspace <-> kernelspace linker
482# 354#
483CONFIG_CONNECTOR=m 355# CONFIG_CONNECTOR is not set
484 356# CONFIG_MTD is not set
485#
486# Memory Technology Devices (MTD)
487#
488CONFIG_MTD=y
489# CONFIG_MTD_DEBUG is not set
490# CONFIG_MTD_CONCAT is not set
491CONFIG_MTD_PARTITIONS=y
492# CONFIG_MTD_REDBOOT_PARTS is not set
493# CONFIG_MTD_CMDLINE_PARTS is not set
494
495#
496# User Modules And Translation Layers
497#
498CONFIG_MTD_CHAR=y
499CONFIG_MTD_BLKDEVS=y
500CONFIG_MTD_BLOCK=y
501# CONFIG_FTL is not set
502# CONFIG_NFTL is not set
503# CONFIG_INFTL is not set
504# CONFIG_RFD_FTL is not set
505# CONFIG_SSFDC is not set
506
507#
508# RAM/ROM/Flash chip drivers
509#
510CONFIG_MTD_CFI=y
511# CONFIG_MTD_JEDECPROBE is not set
512CONFIG_MTD_GEN_PROBE=y
513# CONFIG_MTD_CFI_ADV_OPTIONS is not set
514CONFIG_MTD_MAP_BANK_WIDTH_1=y
515CONFIG_MTD_MAP_BANK_WIDTH_2=y
516CONFIG_MTD_MAP_BANK_WIDTH_4=y
517# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
518# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
519# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
520CONFIG_MTD_CFI_I1=y
521CONFIG_MTD_CFI_I2=y
522# CONFIG_MTD_CFI_I4 is not set
523# CONFIG_MTD_CFI_I8 is not set
524CONFIG_MTD_CFI_INTELEXT=y
525CONFIG_MTD_CFI_AMDSTD=y
526# CONFIG_MTD_CFI_STAA is not set
527CONFIG_MTD_CFI_UTIL=y
528# CONFIG_MTD_RAM is not set
529# CONFIG_MTD_ROM is not set
530# CONFIG_MTD_ABSENT is not set
531# CONFIG_MTD_OBSOLETE_CHIPS is not set
532
533#
534# Mapping drivers for chip access
535#
536# CONFIG_MTD_COMPLEX_MAPPINGS is not set
537# CONFIG_MTD_PHYSMAP is not set
538# CONFIG_MTD_PLATRAM is not set
539
540#
541# Self-contained MTD device drivers
542#
543# CONFIG_MTD_PMC551 is not set
544# CONFIG_MTD_SLRAM is not set
545# CONFIG_MTD_PHRAM is not set
546# CONFIG_MTD_MTDRAM is not set
547# CONFIG_MTD_BLOCK2MTD is not set
548
549#
550# Disk-On-Chip Device Drivers
551#
552# CONFIG_MTD_DOC2000 is not set
553# CONFIG_MTD_DOC2001 is not set
554# CONFIG_MTD_DOC2001PLUS is not set
555
556#
557# NAND Flash Device Drivers
558#
559# CONFIG_MTD_NAND is not set
560
561#
562# OneNAND Flash Device Drivers
563#
564# CONFIG_MTD_ONENAND is not set
565 357
566# 358#
567# Parallel port support 359# Parallel port support
@@ -583,93 +375,30 @@ CONFIG_MTD_CFI_UTIL=y
583# CONFIG_BLK_DEV_COW_COMMON is not set 375# CONFIG_BLK_DEV_COW_COMMON is not set
584CONFIG_BLK_DEV_LOOP=y 376CONFIG_BLK_DEV_LOOP=y
585# CONFIG_BLK_DEV_CRYPTOLOOP is not set 377# CONFIG_BLK_DEV_CRYPTOLOOP is not set
586CONFIG_BLK_DEV_NBD=m 378# CONFIG_BLK_DEV_NBD is not set
587# CONFIG_BLK_DEV_SX8 is not set 379# CONFIG_BLK_DEV_SX8 is not set
588# CONFIG_BLK_DEV_UB is not set
589CONFIG_BLK_DEV_RAM=y 380CONFIG_BLK_DEV_RAM=y
590CONFIG_BLK_DEV_RAM_COUNT=16 381CONFIG_BLK_DEV_RAM_COUNT=16
591CONFIG_BLK_DEV_RAM_SIZE=8192 382CONFIG_BLK_DEV_RAM_SIZE=8192
592CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 383CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
593CONFIG_BLK_DEV_INITRD=y
594# CONFIG_CDROM_PKTCDVD is not set 384# CONFIG_CDROM_PKTCDVD is not set
595# CONFIG_ATA_OVER_ETH is not set 385# CONFIG_ATA_OVER_ETH is not set
596 386
597# 387#
598# Misc devices 388# Misc devices
599# 389#
600CONFIG_SGI_IOC4=m 390# CONFIG_PHANTOM is not set
391# CONFIG_SGI_IOC4 is not set
601# CONFIG_TIFM_CORE is not set 392# CONFIG_TIFM_CORE is not set
602 393# CONFIG_BLINK is not set
603# 394# CONFIG_IDE is not set
604# ATA/ATAPI/MFM/RLL support
605#
606CONFIG_IDE=y
607CONFIG_IDE_MAX_HWIFS=4
608CONFIG_BLK_DEV_IDE=y
609
610#
611# Please see Documentation/ide.txt for help/info on IDE drives
612#
613# CONFIG_BLK_DEV_IDE_SATA is not set
614CONFIG_BLK_DEV_IDEDISK=y
615# CONFIG_IDEDISK_MULTI_MODE is not set
616CONFIG_BLK_DEV_IDECD=y
617# CONFIG_BLK_DEV_IDETAPE is not set
618# CONFIG_BLK_DEV_IDEFLOPPY is not set
619# CONFIG_IDE_TASK_IOCTL is not set
620
621#
622# IDE chipset support/bugfixes
623#
624CONFIG_IDE_GENERIC=y
625CONFIG_BLK_DEV_IDEPCI=y
626CONFIG_IDEPCI_SHARE_IRQ=y
627# CONFIG_BLK_DEV_OFFBOARD is not set
628# CONFIG_BLK_DEV_GENERIC is not set
629# CONFIG_BLK_DEV_OPTI621 is not set
630CONFIG_BLK_DEV_IDEDMA_PCI=y
631# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
632# CONFIG_IDEDMA_PCI_AUTO is not set
633# CONFIG_BLK_DEV_AEC62XX is not set
634# CONFIG_BLK_DEV_ALI15X3 is not set
635# CONFIG_BLK_DEV_AMD74XX is not set
636# CONFIG_BLK_DEV_CMD64X is not set
637# CONFIG_BLK_DEV_TRIFLEX is not set
638# CONFIG_BLK_DEV_CY82C693 is not set
639# CONFIG_BLK_DEV_CS5520 is not set
640# CONFIG_BLK_DEV_CS5530 is not set
641# CONFIG_BLK_DEV_HPT34X is not set
642# CONFIG_BLK_DEV_HPT366 is not set
643# CONFIG_BLK_DEV_JMICRON is not set
644# CONFIG_BLK_DEV_SC1200 is not set
645# CONFIG_BLK_DEV_PIIX is not set
646CONFIG_BLK_DEV_IT8213=m
647# CONFIG_BLK_DEV_IT821X is not set
648# CONFIG_BLK_DEV_NS87415 is not set
649# CONFIG_BLK_DEV_PDC202XX_OLD is not set
650# CONFIG_BLK_DEV_PDC202XX_NEW is not set
651# CONFIG_BLK_DEV_SVWKS is not set
652# CONFIG_BLK_DEV_SIIMAGE is not set
653# CONFIG_BLK_DEV_SLC90E66 is not set
654# CONFIG_BLK_DEV_TRM290 is not set
655# CONFIG_BLK_DEV_VIA82CXXX is not set
656CONFIG_BLK_DEV_TC86C001=m
657# CONFIG_IDE_ARM is not set
658CONFIG_BLK_DEV_IDEDMA=y
659# CONFIG_IDEDMA_IVB is not set
660# CONFIG_IDEDMA_AUTO is not set
661# CONFIG_BLK_DEV_HD is not set
662 395
663# 396#
664# SCSI device support 397# SCSI device support
665# 398#
666CONFIG_RAID_ATTRS=m 399# CONFIG_RAID_ATTRS is not set
667# CONFIG_SCSI is not set 400# CONFIG_SCSI is not set
668# CONFIG_SCSI_NETLINK is not set 401# CONFIG_SCSI_NETLINK is not set
669
670#
671# Serial ATA (prod) and Parallel ATA (experimental) drivers
672#
673# CONFIG_ATA is not set 402# CONFIG_ATA is not set
674 403
675# 404#
@@ -685,6 +414,7 @@ CONFIG_RAID_ATTRS=m
685# 414#
686# IEEE 1394 (FireWire) support 415# IEEE 1394 (FireWire) support
687# 416#
417# CONFIG_FIREWIRE is not set
688# CONFIG_IEEE1394 is not set 418# CONFIG_IEEE1394 is not set
689 419
690# 420#
@@ -699,36 +429,15 @@ CONFIG_NETDEVICES=y
699# CONFIG_DUMMY is not set 429# CONFIG_DUMMY is not set
700# CONFIG_BONDING is not set 430# CONFIG_BONDING is not set
701# CONFIG_EQUALIZER is not set 431# CONFIG_EQUALIZER is not set
702CONFIG_TUN=m 432# CONFIG_TUN is not set
703
704#
705# ARCnet devices
706#
707# CONFIG_ARCNET is not set 433# CONFIG_ARCNET is not set
708 434# CONFIG_PHYLIB is not set
709#
710# PHY device support
711#
712CONFIG_PHYLIB=m
713
714#
715# MII PHY device drivers
716#
717CONFIG_MARVELL_PHY=m
718CONFIG_DAVICOM_PHY=m
719CONFIG_QSEMI_PHY=m
720CONFIG_LXT_PHY=m
721CONFIG_CICADA_PHY=m
722CONFIG_VITESSE_PHY=m
723CONFIG_SMSC_PHY=m
724# CONFIG_BROADCOM_PHY is not set
725# CONFIG_FIXED_PHY is not set
726 435
727# 436#
728# Ethernet (10 or 100Mbit) 437# Ethernet (10 or 100Mbit)
729# 438#
730CONFIG_NET_ETHERNET=y 439CONFIG_NET_ETHERNET=y
731# CONFIG_MII is not set 440CONFIG_MII=y
732# CONFIG_HAPPYMEAL is not set 441# CONFIG_HAPPYMEAL is not set
733# CONFIG_SUNGEM is not set 442# CONFIG_SUNGEM is not set
734# CONFIG_CASSINI is not set 443# CONFIG_CASSINI is not set
@@ -747,6 +456,7 @@ CONFIG_NET_PCI=y
747# CONFIG_ADAPTEC_STARFIRE is not set 456# CONFIG_ADAPTEC_STARFIRE is not set
748# CONFIG_B44 is not set 457# CONFIG_B44 is not set
749# CONFIG_FORCEDETH is not set 458# CONFIG_FORCEDETH is not set
459CONFIG_TC35815=y
750# CONFIG_DGRS is not set 460# CONFIG_DGRS is not set
751# CONFIG_EEPRO100 is not set 461# CONFIG_EEPRO100 is not set
752# CONFIG_E100 is not set 462# CONFIG_E100 is not set
@@ -761,91 +471,20 @@ CONFIG_NET_PCI=y
761# CONFIG_TLAN is not set 471# CONFIG_TLAN is not set
762# CONFIG_VIA_RHINE is not set 472# CONFIG_VIA_RHINE is not set
763# CONFIG_SC92031 is not set 473# CONFIG_SC92031 is not set
764 474# CONFIG_NETDEV_1000 is not set
765# 475# CONFIG_NETDEV_10000 is not set
766# Ethernet (1000 Mbit)
767#
768# CONFIG_ACENIC is not set
769# CONFIG_DL2K is not set
770# CONFIG_E1000 is not set
771# CONFIG_NS83820 is not set
772# CONFIG_HAMACHI is not set
773# CONFIG_YELLOWFIN is not set
774# CONFIG_R8169 is not set
775# CONFIG_SIS190 is not set
776# CONFIG_SKGE is not set
777# CONFIG_SKY2 is not set
778# CONFIG_SK98LIN is not set
779# CONFIG_VIA_VELOCITY is not set
780# CONFIG_TIGON3 is not set
781# CONFIG_BNX2 is not set
782CONFIG_QLA3XXX=m
783# CONFIG_ATL1 is not set
784
785#
786# Ethernet (10000 Mbit)
787#
788# CONFIG_CHELSIO_T1 is not set
789CONFIG_CHELSIO_T3=m
790# CONFIG_IXGB is not set
791# CONFIG_S2IO is not set
792# CONFIG_MYRI10GE is not set
793CONFIG_NETXEN_NIC=m
794
795#
796# Token Ring devices
797#
798# CONFIG_TR is not set 476# CONFIG_TR is not set
799 477
800# 478#
801# Wireless LAN (non-hamradio) 479# Wireless LAN
802#
803CONFIG_NET_RADIO=y
804# CONFIG_NET_WIRELESS_RTNETLINK is not set
805
806#
807# Obsolete Wireless cards support (pre-802.11)
808#
809# CONFIG_STRIP is not set
810
811#
812# Wireless 802.11b ISA/PCI cards support
813#
814# CONFIG_IPW2100 is not set
815CONFIG_IPW2200=m
816# CONFIG_IPW2200_MONITOR is not set
817# CONFIG_IPW2200_QOS is not set
818# CONFIG_IPW2200_DEBUG is not set
819# CONFIG_HERMES is not set
820# CONFIG_ATMEL is not set
821
822#
823# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
824#
825# CONFIG_PRISM54 is not set
826# CONFIG_USB_ZD1201 is not set
827# CONFIG_HOSTAP is not set
828# CONFIG_BCM43XX is not set
829# CONFIG_ZD1211RW is not set
830CONFIG_NET_WIRELESS=y
831
832#
833# Wan interfaces
834# 480#
481# CONFIG_WLAN_PRE80211 is not set
482# CONFIG_WLAN_80211 is not set
835# CONFIG_WAN is not set 483# CONFIG_WAN is not set
836# CONFIG_FDDI is not set 484# CONFIG_FDDI is not set
837# CONFIG_HIPPI is not set 485# CONFIG_HIPPI is not set
838CONFIG_PPP=m 486# CONFIG_PPP is not set
839CONFIG_PPP_MULTILINK=y
840# CONFIG_PPP_FILTER is not set
841CONFIG_PPP_ASYNC=m
842CONFIG_PPP_SYNC_TTY=m
843CONFIG_PPP_DEFLATE=m
844# CONFIG_PPP_BSDCOMP is not set
845CONFIG_PPP_MPPE=m
846CONFIG_PPPOE=m
847# CONFIG_SLIP is not set 487# CONFIG_SLIP is not set
848CONFIG_SLHC=m
849# CONFIG_SHAPER is not set 488# CONFIG_SHAPER is not set
850# CONFIG_NETCONSOLE is not set 489# CONFIG_NETCONSOLE is not set
851# CONFIG_NETPOLL is not set 490# CONFIG_NETPOLL is not set
@@ -864,57 +503,18 @@ CONFIG_SLHC=m
864# 503#
865# Input device support 504# Input device support
866# 505#
867CONFIG_INPUT=y 506# CONFIG_INPUT is not set
868# CONFIG_INPUT_FF_MEMLESS is not set
869
870#
871# Userland interfaces
872#
873CONFIG_INPUT_MOUSEDEV=y
874CONFIG_INPUT_MOUSEDEV_PSAUX=y
875CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
876CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
877# CONFIG_INPUT_JOYDEV is not set
878# CONFIG_INPUT_TSDEV is not set
879CONFIG_INPUT_EVDEV=y
880# CONFIG_INPUT_EVBUG is not set
881
882#
883# Input Device Drivers
884#
885CONFIG_INPUT_KEYBOARD=y
886CONFIG_KEYBOARD_ATKBD=y
887# CONFIG_KEYBOARD_SUNKBD is not set
888# CONFIG_KEYBOARD_LKKBD is not set
889# CONFIG_KEYBOARD_XTKBD is not set
890# CONFIG_KEYBOARD_NEWTON is not set
891# CONFIG_KEYBOARD_STOWAWAY is not set
892CONFIG_INPUT_MOUSE=y
893CONFIG_MOUSE_PS2=y
894# CONFIG_MOUSE_SERIAL is not set
895# CONFIG_MOUSE_VSXXXAA is not set
896# CONFIG_INPUT_JOYSTICK is not set
897# CONFIG_INPUT_TOUCHSCREEN is not set
898# CONFIG_INPUT_MISC is not set
899 507
900# 508#
901# Hardware I/O ports 509# Hardware I/O ports
902# 510#
903CONFIG_SERIO=y 511# CONFIG_SERIO is not set
904CONFIG_SERIO_I8042=y
905CONFIG_SERIO_SERPORT=y
906# CONFIG_SERIO_PCIPS2 is not set
907CONFIG_SERIO_LIBPS2=y
908# CONFIG_SERIO_RAW is not set
909# CONFIG_GAMEPORT is not set 512# CONFIG_GAMEPORT is not set
910 513
911# 514#
912# Character devices 515# Character devices
913# 516#
914CONFIG_VT=y 517# CONFIG_VT is not set
915CONFIG_VT_CONSOLE=y
916CONFIG_HW_CONSOLE=y
917CONFIG_VT_HW_CONSOLE_BINDING=y
918# CONFIG_SERIAL_NONSTANDARD is not set 518# CONFIG_SERIAL_NONSTANDARD is not set
919 519
920# 520#
@@ -926,11 +526,12 @@ CONFIG_VT_HW_CONSOLE_BINDING=y
926# Non-8250 serial port support 526# Non-8250 serial port support
927# 527#
928CONFIG_SERIAL_CORE=y 528CONFIG_SERIAL_CORE=y
529CONFIG_SERIAL_CORE_CONSOLE=y
929CONFIG_SERIAL_TXX9=y 530CONFIG_SERIAL_TXX9=y
930CONFIG_HAS_TXX9_SERIAL=y 531CONFIG_HAS_TXX9_SERIAL=y
931CONFIG_SERIAL_TXX9_NR_UARTS=6 532CONFIG_SERIAL_TXX9_NR_UARTS=6
932# CONFIG_SERIAL_TXX9_CONSOLE is not set 533CONFIG_SERIAL_TXX9_CONSOLE=y
933# CONFIG_SERIAL_TXX9_STDSERIAL is not set 534CONFIG_SERIAL_TXX9_STDSERIAL=y
934# CONFIG_SERIAL_JSM is not set 535# CONFIG_SERIAL_JSM is not set
935CONFIG_UNIX98_PTYS=y 536CONFIG_UNIX98_PTYS=y
936CONFIG_LEGACY_PTYS=y 537CONFIG_LEGACY_PTYS=y
@@ -940,15 +541,10 @@ CONFIG_LEGACY_PTY_COUNT=256
940# IPMI 541# IPMI
941# 542#
942# CONFIG_IPMI_HANDLER is not set 543# CONFIG_IPMI_HANDLER is not set
943
944#
945# Watchdog Cards
946#
947# CONFIG_WATCHDOG is not set 544# CONFIG_WATCHDOG is not set
948# CONFIG_HW_RANDOM is not set 545# CONFIG_HW_RANDOM is not set
949# CONFIG_RTC is not set 546# CONFIG_RTC is not set
950# CONFIG_GEN_RTC is not set 547# CONFIG_GEN_RTC is not set
951# CONFIG_DTLK is not set
952# CONFIG_R3964 is not set 548# CONFIG_R3964 is not set
953# CONFIG_APPLICOM is not set 549# CONFIG_APPLICOM is not set
954# CONFIG_DRM is not set 550# CONFIG_DRM is not set
@@ -958,108 +554,61 @@ CONFIG_LEGACY_PTY_COUNT=256
958# TPM devices 554# TPM devices
959# 555#
960# CONFIG_TCG_TPM is not set 556# CONFIG_TCG_TPM is not set
557CONFIG_DEVPORT=y
558# CONFIG_I2C is not set
559
560#
561# SPI support
562#
563CONFIG_SPI=y
564CONFIG_SPI_MASTER=y
961 565
962# 566#
963# I2C support 567# SPI Master Controller Drivers
964# 568#
965# CONFIG_I2C is not set 569# CONFIG_SPI_BITBANG is not set
570CONFIG_SPI_TXX9=y
966 571
967# 572#
968# SPI support 573# SPI Protocol Masters
969# 574#
970# CONFIG_SPI is not set 575CONFIG_SPI_AT25=y
971# CONFIG_SPI_MASTER is not set 576# CONFIG_SPI_SPIDEV is not set
972 577
973# 578#
974# Dallas's 1-wire bus 579# Dallas's 1-wire bus
975# 580#
976# CONFIG_W1 is not set 581# CONFIG_W1 is not set
582# CONFIG_HWMON is not set
977 583
978# 584#
979# Hardware Monitoring support 585# Multifunction device drivers
980# 586#
981CONFIG_HWMON=y 587# CONFIG_MFD_SM501 is not set
982# CONFIG_HWMON_VID is not set
983# CONFIG_SENSORS_ABITUGURU is not set
984# CONFIG_SENSORS_F71805F is not set
985# CONFIG_SENSORS_PC87427 is not set
986# CONFIG_SENSORS_VT1211 is not set
987# CONFIG_HWMON_DEBUG_CHIP is not set
988 588
989# 589#
990# Multimedia devices 590# Multimedia devices
991# 591#
992# CONFIG_VIDEO_DEV is not set 592# CONFIG_VIDEO_DEV is not set
993 593# CONFIG_DVB_CORE is not set
994# 594# CONFIG_DAB is not set
995# Digital Video Broadcasting Devices
996#
997# CONFIG_DVB is not set
998# CONFIG_USB_DABUSB is not set
999 595
1000# 596#
1001# Graphics support 597# Graphics support
1002# 598#
1003# CONFIG_FIRMWARE_EDID is not set
1004CONFIG_FB=y
1005CONFIG_FB_CFB_FILLRECT=y
1006CONFIG_FB_CFB_COPYAREA=y
1007CONFIG_FB_CFB_IMAGEBLIT=y
1008# CONFIG_FB_SVGALIB is not set
1009# CONFIG_FB_MACMODES is not set
1010# CONFIG_FB_BACKLIGHT is not set
1011# CONFIG_FB_MODE_HELPERS is not set
1012# CONFIG_FB_TILEBLITTING is not set
1013# CONFIG_FB_CIRRUS is not set
1014# CONFIG_FB_PM2 is not set
1015# CONFIG_FB_CYBER2000 is not set
1016# CONFIG_FB_ASILIANT is not set
1017# CONFIG_FB_IMSTT is not set
1018# CONFIG_FB_S1D13XXX is not set
1019# CONFIG_FB_NVIDIA is not set
1020# CONFIG_FB_RIVA is not set
1021# CONFIG_FB_MATROX is not set
1022# CONFIG_FB_RADEON is not set
1023# CONFIG_FB_ATY128 is not set
1024CONFIG_FB_ATY=y
1025CONFIG_FB_ATY_CT=y
1026# CONFIG_FB_ATY_GENERIC_LCD is not set
1027# CONFIG_FB_ATY_GX is not set
1028# CONFIG_FB_S3 is not set
1029# CONFIG_FB_SAVAGE is not set
1030# CONFIG_FB_SIS is not set
1031# CONFIG_FB_NEOMAGIC is not set
1032# CONFIG_FB_KYRO is not set
1033# CONFIG_FB_3DFX is not set
1034# CONFIG_FB_VOODOO1 is not set
1035# CONFIG_FB_SMIVGX is not set
1036# CONFIG_FB_TRIDENT is not set
1037# CONFIG_FB_VIRTUAL is not set
1038
1039#
1040# Console display driver support
1041#
1042CONFIG_VGA_CONSOLE=y
1043# CONFIG_VGACON_SOFT_SCROLLBACK is not set
1044CONFIG_DUMMY_CONSOLE=y
1045# CONFIG_FRAMEBUFFER_CONSOLE is not set
1046
1047#
1048# Logo configuration
1049#
1050# CONFIG_LOGO is not set
1051# CONFIG_BACKLIGHT_LCD_SUPPORT is not set 599# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
1052 600
1053# 601#
1054# Sound 602# Display device support
1055# 603#
1056# CONFIG_SOUND is not set 604# CONFIG_DISPLAY_SUPPORT is not set
605# CONFIG_VGASTATE is not set
606# CONFIG_FB is not set
1057 607
1058# 608#
1059# HID Devices 609# Sound
1060# 610#
1061CONFIG_HID=y 611# CONFIG_SOUND is not set
1062# CONFIG_HID_DEBUG is not set
1063 612
1064# 613#
1065# USB support 614# USB support
@@ -1067,148 +616,80 @@ CONFIG_HID=y
1067CONFIG_USB_ARCH_HAS_HCD=y 616CONFIG_USB_ARCH_HAS_HCD=y
1068CONFIG_USB_ARCH_HAS_OHCI=y 617CONFIG_USB_ARCH_HAS_OHCI=y
1069CONFIG_USB_ARCH_HAS_EHCI=y 618CONFIG_USB_ARCH_HAS_EHCI=y
1070CONFIG_USB=y 619# CONFIG_USB is not set
1071# CONFIG_USB_DEBUG is not set
1072
1073#
1074# Miscellaneous USB options
1075#
1076# CONFIG_USB_DEVICEFS is not set
1077# CONFIG_USB_DYNAMIC_MINORS is not set
1078# CONFIG_USB_SUSPEND is not set
1079# CONFIG_USB_OTG is not set
1080
1081#
1082# USB Host Controller Drivers
1083#
1084# CONFIG_USB_EHCI_HCD is not set
1085# CONFIG_USB_ISP116X_HCD is not set
1086# CONFIG_USB_OHCI_HCD is not set
1087# CONFIG_USB_UHCI_HCD is not set
1088# CONFIG_USB_SL811_HCD is not set
1089
1090#
1091# USB Device Class drivers
1092#
1093# CONFIG_USB_ACM is not set
1094# CONFIG_USB_PRINTER is not set
1095 620
1096# 621#
1097# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' 622# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
1098# 623#
1099 624
1100# 625#
1101# may also be needed; see USB_STORAGE Help for more information 626# USB Gadget Support
1102#
1103# CONFIG_USB_LIBUSUAL is not set
1104
1105#
1106# USB Input Devices
1107#
1108CONFIG_USB_HID=y
1109# CONFIG_USB_HIDINPUT_POWERBOOK is not set
1110# CONFIG_HID_FF is not set
1111CONFIG_USB_HIDDEV=y
1112# CONFIG_USB_AIPTEK is not set
1113# CONFIG_USB_WACOM is not set
1114# CONFIG_USB_ACECAD is not set
1115# CONFIG_USB_KBTAB is not set
1116# CONFIG_USB_POWERMATE is not set
1117# CONFIG_USB_TOUCHSCREEN is not set
1118CONFIG_USB_YEALINK=m
1119# CONFIG_USB_XPAD is not set
1120# CONFIG_USB_ATI_REMOTE is not set
1121# CONFIG_USB_ATI_REMOTE2 is not set
1122# CONFIG_USB_KEYSPAN_REMOTE is not set
1123# CONFIG_USB_APPLETOUCH is not set
1124# CONFIG_USB_GTCO is not set
1125
1126#
1127# USB Imaging devices
1128#
1129# CONFIG_USB_MDC800 is not set
1130
1131#
1132# USB Network Adapters
1133#
1134# CONFIG_USB_CATC is not set
1135# CONFIG_USB_KAWETH is not set
1136# CONFIG_USB_PEGASUS is not set
1137# CONFIG_USB_RTL8150 is not set
1138# CONFIG_USB_USBNET_MII is not set
1139# CONFIG_USB_USBNET is not set
1140CONFIG_USB_MON=y
1141
1142#
1143# USB port drivers
1144# 627#
628# CONFIG_USB_GADGET is not set
629# CONFIG_MMC is not set
1145 630
1146# 631#
1147# USB Serial Converter support 632# LED devices
1148# 633#
1149# CONFIG_USB_SERIAL is not set 634# CONFIG_NEW_LEDS is not set
1150 635
1151# 636#
1152# USB Miscellaneous drivers 637# LED drivers
1153# 638#
1154# CONFIG_USB_EMI62 is not set
1155# CONFIG_USB_EMI26 is not set
1156# CONFIG_USB_ADUTUX is not set
1157# CONFIG_USB_AUERSWALD is not set
1158# CONFIG_USB_RIO500 is not set
1159# CONFIG_USB_LEGOTOWER is not set
1160# CONFIG_USB_LCD is not set
1161# CONFIG_USB_BERRY_CHARGE is not set
1162# CONFIG_USB_LED is not set
1163# CONFIG_USB_CYPRESS_CY7C63 is not set
1164# CONFIG_USB_CYTHERM is not set
1165# CONFIG_USB_PHIDGET is not set
1166# CONFIG_USB_IDMOUSE is not set
1167# CONFIG_USB_FTDI_ELAN is not set
1168# CONFIG_USB_APPLEDISPLAY is not set
1169# CONFIG_USB_LD is not set
1170# CONFIG_USB_TRANCEVIBRATOR is not set
1171 639
1172# 640#
1173# USB DSL modem support 641# LED Triggers
1174# 642#
1175 643
1176# 644#
1177# USB Gadget Support 645# InfiniBand support
1178# 646#
1179# CONFIG_USB_GADGET is not set 647# CONFIG_INFINIBAND is not set
1180 648
1181# 649#
1182# MMC/SD Card support 650# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
1183# 651#
1184# CONFIG_MMC is not set
1185 652
1186# 653#
1187# LED devices 654# Real Time Clock
1188# 655#
1189# CONFIG_NEW_LEDS is not set 656CONFIG_RTC_LIB=y
657CONFIG_RTC_CLASS=y
658CONFIG_RTC_HCTOSYS=y
659CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
660# CONFIG_RTC_DEBUG is not set
1190 661
1191# 662#
1192# LED drivers 663# RTC interfaces
1193# 664#
665CONFIG_RTC_INTF_SYSFS=y
666CONFIG_RTC_INTF_PROC=y
667CONFIG_RTC_INTF_DEV=y
668CONFIG_RTC_INTF_DEV_UIE_EMUL=y
669# CONFIG_RTC_DRV_TEST is not set
1194 670
1195# 671#
1196# LED Triggers 672# I2C RTC drivers
1197# 673#
1198 674
1199# 675#
1200# InfiniBand support 676# SPI RTC drivers
1201# 677#
1202# CONFIG_INFINIBAND is not set 678CONFIG_RTC_DRV_RS5C348=y
679# CONFIG_RTC_DRV_MAX6902 is not set
1203 680
1204# 681#
1205# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) 682# Platform RTC drivers
1206# 683#
684# CONFIG_RTC_DRV_CMOS is not set
685# CONFIG_RTC_DRV_DS1553 is not set
686# CONFIG_RTC_DRV_DS1742 is not set
687# CONFIG_RTC_DRV_M48T86 is not set
688# CONFIG_RTC_DRV_V3020 is not set
1207 689
1208# 690#
1209# Real Time Clock 691# on-CPU RTC drivers
1210# 692#
1211# CONFIG_RTC_CLASS is not set
1212 693
1213# 694#
1214# DMA Engine support 695# DMA Engine support
@@ -1224,38 +705,15 @@ CONFIG_USB_MON=y
1224# 705#
1225 706
1226# 707#
1227# Auxiliary Display support
1228#
1229
1230#
1231# Virtualization
1232#
1233
1234#
1235# File systems 708# File systems
1236# 709#
1237CONFIG_EXT2_FS=y 710# CONFIG_EXT2_FS is not set
1238# CONFIG_EXT2_FS_XATTR is not set 711# CONFIG_EXT3_FS is not set
1239# CONFIG_EXT2_FS_XIP is not set
1240CONFIG_EXT3_FS=m
1241CONFIG_EXT3_FS_XATTR=y
1242# CONFIG_EXT3_FS_POSIX_ACL is not set
1243# CONFIG_EXT3_FS_SECURITY is not set
1244# CONFIG_EXT4DEV_FS is not set 712# CONFIG_EXT4DEV_FS is not set
1245CONFIG_JBD=m 713# CONFIG_REISERFS_FS is not set
1246# CONFIG_JBD_DEBUG is not set
1247CONFIG_FS_MBCACHE=y
1248CONFIG_REISERFS_FS=m
1249# CONFIG_REISERFS_CHECK is not set
1250# CONFIG_REISERFS_PROC_INFO is not set
1251# CONFIG_REISERFS_FS_XATTR is not set
1252# CONFIG_JFS_FS is not set 714# CONFIG_JFS_FS is not set
1253CONFIG_FS_POSIX_ACL=y 715CONFIG_FS_POSIX_ACL=y
1254CONFIG_XFS_FS=m 716# CONFIG_XFS_FS is not set
1255# CONFIG_XFS_QUOTA is not set
1256# CONFIG_XFS_SECURITY is not set
1257# CONFIG_XFS_POSIX_ACL is not set
1258# CONFIG_XFS_RT is not set
1259# CONFIG_GFS2_FS is not set 717# CONFIG_GFS2_FS is not set
1260# CONFIG_OCFS2_FS is not set 718# CONFIG_OCFS2_FS is not set
1261# CONFIG_MINIX_FS is not set 719# CONFIG_MINIX_FS is not set
@@ -1265,26 +723,21 @@ CONFIG_INOTIFY_USER=y
1265# CONFIG_QUOTA is not set 723# CONFIG_QUOTA is not set
1266# CONFIG_DNOTIFY is not set 724# CONFIG_DNOTIFY is not set
1267# CONFIG_AUTOFS_FS is not set 725# CONFIG_AUTOFS_FS is not set
1268CONFIG_AUTOFS4_FS=m 726# CONFIG_AUTOFS4_FS is not set
1269CONFIG_FUSE_FS=m 727# CONFIG_FUSE_FS is not set
1270CONFIG_GENERIC_ACL=y 728CONFIG_GENERIC_ACL=y
1271 729
1272# 730#
1273# CD-ROM/DVD Filesystems 731# CD-ROM/DVD Filesystems
1274# 732#
1275CONFIG_ISO9660_FS=y 733# CONFIG_ISO9660_FS is not set
1276# CONFIG_JOLIET is not set
1277# CONFIG_ZISOFS is not set
1278# CONFIG_UDF_FS is not set 734# CONFIG_UDF_FS is not set
1279 735
1280# 736#
1281# DOS/FAT/NT Filesystems 737# DOS/FAT/NT Filesystems
1282# 738#
1283CONFIG_FAT_FS=y
1284# CONFIG_MSDOS_FS is not set 739# CONFIG_MSDOS_FS is not set
1285CONFIG_VFAT_FS=y 740# CONFIG_VFAT_FS is not set
1286CONFIG_FAT_DEFAULT_CODEPAGE=437
1287CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
1288# CONFIG_NTFS_FS is not set 741# CONFIG_NTFS_FS is not set
1289 742
1290# 743#
@@ -1298,7 +751,7 @@ CONFIG_TMPFS=y
1298CONFIG_TMPFS_POSIX_ACL=y 751CONFIG_TMPFS_POSIX_ACL=y
1299# CONFIG_HUGETLB_PAGE is not set 752# CONFIG_HUGETLB_PAGE is not set
1300CONFIG_RAMFS=y 753CONFIG_RAMFS=y
1301CONFIG_CONFIGFS_FS=m 754# CONFIG_CONFIGFS_FS is not set
1302 755
1303# 756#
1304# Miscellaneous filesystems 757# Miscellaneous filesystems
@@ -1310,16 +763,7 @@ CONFIG_CONFIGFS_FS=m
1310# CONFIG_BEFS_FS is not set 763# CONFIG_BEFS_FS is not set
1311# CONFIG_BFS_FS is not set 764# CONFIG_BFS_FS is not set
1312# CONFIG_EFS_FS is not set 765# CONFIG_EFS_FS is not set
1313CONFIG_JFFS2_FS=y 766# CONFIG_CRAMFS is not set
1314CONFIG_JFFS2_FS_DEBUG=0
1315CONFIG_JFFS2_FS_WRITEBUFFER=y
1316# CONFIG_JFFS2_SUMMARY is not set
1317# CONFIG_JFFS2_FS_XATTR is not set
1318# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
1319CONFIG_JFFS2_ZLIB=y
1320CONFIG_JFFS2_RTIME=y
1321# CONFIG_JFFS2_RUBIN is not set
1322CONFIG_CRAMFS=y
1323# CONFIG_VXFS_FS is not set 767# CONFIG_VXFS_FS is not set
1324# CONFIG_HPFS_FS is not set 768# CONFIG_HPFS_FS is not set
1325# CONFIG_QNX4FS_FS is not set 769# CONFIG_QNX4FS_FS is not set
@@ -1334,19 +778,16 @@ CONFIG_NFS_V3=y
1334# CONFIG_NFS_V3_ACL is not set 778# CONFIG_NFS_V3_ACL is not set
1335# CONFIG_NFS_V4 is not set 779# CONFIG_NFS_V4 is not set
1336# CONFIG_NFS_DIRECTIO is not set 780# CONFIG_NFS_DIRECTIO is not set
1337CONFIG_NFSD=m 781# CONFIG_NFSD is not set
1338# CONFIG_NFSD_V3 is not set
1339# CONFIG_NFSD_TCP is not set
1340CONFIG_ROOT_NFS=y 782CONFIG_ROOT_NFS=y
1341CONFIG_LOCKD=y 783CONFIG_LOCKD=y
1342CONFIG_LOCKD_V4=y 784CONFIG_LOCKD_V4=y
1343CONFIG_EXPORTFS=m
1344CONFIG_NFS_COMMON=y 785CONFIG_NFS_COMMON=y
1345CONFIG_SUNRPC=y 786CONFIG_SUNRPC=y
787# CONFIG_SUNRPC_BIND34 is not set
1346# CONFIG_RPCSEC_GSS_KRB5 is not set 788# CONFIG_RPCSEC_GSS_KRB5 is not set
1347# CONFIG_RPCSEC_GSS_SPKM3 is not set 789# CONFIG_RPCSEC_GSS_SPKM3 is not set
1348CONFIG_SMB_FS=m 790# CONFIG_SMB_FS is not set
1349# CONFIG_SMB_NLS_DEFAULT is not set
1350# CONFIG_CIFS is not set 791# CONFIG_CIFS is not set
1351# CONFIG_NCP_FS is not set 792# CONFIG_NCP_FS is not set
1352# CONFIG_CODA_FS is not set 793# CONFIG_CODA_FS is not set
@@ -1362,54 +803,12 @@ CONFIG_MSDOS_PARTITION=y
1362# 803#
1363# Native Language Support 804# Native Language Support
1364# 805#
1365CONFIG_NLS=y 806# CONFIG_NLS is not set
1366CONFIG_NLS_DEFAULT="iso8859-1"
1367# CONFIG_NLS_CODEPAGE_437 is not set
1368# CONFIG_NLS_CODEPAGE_737 is not set
1369# CONFIG_NLS_CODEPAGE_775 is not set
1370# CONFIG_NLS_CODEPAGE_850 is not set
1371# CONFIG_NLS_CODEPAGE_852 is not set
1372# CONFIG_NLS_CODEPAGE_855 is not set
1373# CONFIG_NLS_CODEPAGE_857 is not set
1374# CONFIG_NLS_CODEPAGE_860 is not set
1375# CONFIG_NLS_CODEPAGE_861 is not set
1376# CONFIG_NLS_CODEPAGE_862 is not set
1377# CONFIG_NLS_CODEPAGE_863 is not set
1378# CONFIG_NLS_CODEPAGE_864 is not set
1379# CONFIG_NLS_CODEPAGE_865 is not set
1380# CONFIG_NLS_CODEPAGE_866 is not set
1381# CONFIG_NLS_CODEPAGE_869 is not set
1382# CONFIG_NLS_CODEPAGE_936 is not set
1383# CONFIG_NLS_CODEPAGE_950 is not set
1384# CONFIG_NLS_CODEPAGE_932 is not set
1385# CONFIG_NLS_CODEPAGE_949 is not set
1386# CONFIG_NLS_CODEPAGE_874 is not set
1387# CONFIG_NLS_ISO8859_8 is not set
1388# CONFIG_NLS_CODEPAGE_1250 is not set
1389# CONFIG_NLS_CODEPAGE_1251 is not set
1390# CONFIG_NLS_ASCII is not set
1391# CONFIG_NLS_ISO8859_1 is not set
1392# CONFIG_NLS_ISO8859_2 is not set
1393# CONFIG_NLS_ISO8859_3 is not set
1394# CONFIG_NLS_ISO8859_4 is not set
1395# CONFIG_NLS_ISO8859_5 is not set
1396# CONFIG_NLS_ISO8859_6 is not set
1397# CONFIG_NLS_ISO8859_7 is not set
1398# CONFIG_NLS_ISO8859_9 is not set
1399# CONFIG_NLS_ISO8859_13 is not set
1400# CONFIG_NLS_ISO8859_14 is not set
1401# CONFIG_NLS_ISO8859_15 is not set
1402# CONFIG_NLS_KOI8_R is not set
1403# CONFIG_NLS_KOI8_U is not set
1404# CONFIG_NLS_UTF8 is not set
1405 807
1406# 808#
1407# Distributed Lock Manager 809# Distributed Lock Manager
1408# 810#
1409CONFIG_DLM=m 811# CONFIG_DLM is not set
1410CONFIG_DLM_TCP=y
1411# CONFIG_DLM_SCTP is not set
1412# CONFIG_DLM_DEBUG is not set
1413 812
1414# 813#
1415# Profiling support 814# Profiling support
@@ -1427,7 +826,6 @@ CONFIG_ENABLE_MUST_CHECK=y
1427# CONFIG_DEBUG_FS is not set 826# CONFIG_DEBUG_FS is not set
1428# CONFIG_HEADERS_CHECK is not set 827# CONFIG_HEADERS_CHECK is not set
1429# CONFIG_DEBUG_KERNEL is not set 828# CONFIG_DEBUG_KERNEL is not set
1430CONFIG_LOG_BUF_SHIFT=14
1431CONFIG_CROSSCOMPILE=y 829CONFIG_CROSSCOMPILE=y
1432CONFIG_CMDLINE="" 830CONFIG_CMDLINE=""
1433CONFIG_SYS_SUPPORTS_KGDB=y 831CONFIG_SYS_SUPPORTS_KGDB=y
@@ -1441,62 +839,17 @@ CONFIG_SYS_SUPPORTS_KGDB=y
1441# 839#
1442# Cryptographic options 840# Cryptographic options
1443# 841#
1444CONFIG_CRYPTO=y 842# CONFIG_CRYPTO is not set
1445CONFIG_CRYPTO_ALGAPI=y
1446CONFIG_CRYPTO_BLKCIPHER=m
1447CONFIG_CRYPTO_HASH=y
1448CONFIG_CRYPTO_MANAGER=y
1449CONFIG_CRYPTO_HMAC=y
1450CONFIG_CRYPTO_XCBC=m
1451CONFIG_CRYPTO_NULL=m
1452CONFIG_CRYPTO_MD4=m
1453CONFIG_CRYPTO_MD5=y
1454CONFIG_CRYPTO_SHA1=m
1455CONFIG_CRYPTO_SHA256=m
1456CONFIG_CRYPTO_SHA512=m
1457CONFIG_CRYPTO_WP512=m
1458CONFIG_CRYPTO_TGR192=m
1459CONFIG_CRYPTO_GF128MUL=m
1460CONFIG_CRYPTO_ECB=m
1461CONFIG_CRYPTO_CBC=m
1462CONFIG_CRYPTO_PCBC=m
1463CONFIG_CRYPTO_LRW=m
1464CONFIG_CRYPTO_DES=m
1465CONFIG_CRYPTO_FCRYPT=m
1466CONFIG_CRYPTO_BLOWFISH=m
1467CONFIG_CRYPTO_TWOFISH=m
1468CONFIG_CRYPTO_TWOFISH_COMMON=m
1469CONFIG_CRYPTO_SERPENT=m
1470CONFIG_CRYPTO_AES=m
1471CONFIG_CRYPTO_CAST5=m
1472CONFIG_CRYPTO_CAST6=m
1473CONFIG_CRYPTO_TEA=m
1474CONFIG_CRYPTO_ARC4=m
1475CONFIG_CRYPTO_KHAZAD=m
1476CONFIG_CRYPTO_ANUBIS=m
1477CONFIG_CRYPTO_DEFLATE=m
1478CONFIG_CRYPTO_MICHAEL_MIC=m
1479CONFIG_CRYPTO_CRC32C=m
1480CONFIG_CRYPTO_CAMELLIA=m
1481# CONFIG_CRYPTO_TEST is not set
1482
1483#
1484# Hardware crypto devices
1485#
1486 843
1487# 844#
1488# Library routines 845# Library routines
1489# 846#
1490CONFIG_BITREVERSE=y 847CONFIG_BITREVERSE=y
1491CONFIG_CRC_CCITT=m 848# CONFIG_CRC_CCITT is not set
1492CONFIG_CRC16=m 849# CONFIG_CRC16 is not set
850# CONFIG_CRC_ITU_T is not set
1493CONFIG_CRC32=y 851CONFIG_CRC32=y
1494CONFIG_LIBCRC32C=m 852# CONFIG_LIBCRC32C is not set
1495CONFIG_ZLIB_INFLATE=y
1496CONFIG_ZLIB_DEFLATE=y
1497CONFIG_TEXTSEARCH=y
1498CONFIG_TEXTSEARCH_KMP=m
1499CONFIG_TEXTSEARCH_BM=m
1500CONFIG_TEXTSEARCH_FSM=m
1501CONFIG_HAS_IOMEM=y 853CONFIG_HAS_IOMEM=y
1502CONFIG_HAS_IOPORT=y 854CONFIG_HAS_IOPORT=y
855CONFIG_HAS_DMA=y
diff --git a/arch/mips/configs/rm200_defconfig b/arch/mips/configs/rm200_defconfig
index 5593cde9f74c..1a67a85aabbb 100644
--- a/arch/mips/configs/rm200_defconfig
+++ b/arch/mips/configs/rm200_defconfig
@@ -25,9 +25,7 @@ CONFIG_ZONE_DMA=y
25# CONFIG_BASLER_EXCITE is not set 25# CONFIG_BASLER_EXCITE is not set
26# CONFIG_MIPS_COBALT is not set 26# CONFIG_MIPS_COBALT is not set
27# CONFIG_MACH_DECSTATION is not set 27# CONFIG_MACH_DECSTATION is not set
28# CONFIG_MIPS_EV64120 is not set
29# CONFIG_MACH_JAZZ is not set 28# CONFIG_MACH_JAZZ is not set
30# CONFIG_LASAT is not set
31# CONFIG_MIPS_ATLAS is not set 29# CONFIG_MIPS_ATLAS is not set
32# CONFIG_MIPS_MALTA is not set 30# CONFIG_MIPS_MALTA is not set
33# CONFIG_MIPS_SEAD is not set 31# CONFIG_MIPS_SEAD is not set
@@ -35,8 +33,6 @@ CONFIG_ZONE_DMA=y
35# CONFIG_MIPS_SIM is not set 33# CONFIG_MIPS_SIM is not set
36# CONFIG_MOMENCO_JAGUAR_ATX is not set 34# CONFIG_MOMENCO_JAGUAR_ATX is not set
37# CONFIG_MOMENCO_OCELOT is not set 35# CONFIG_MOMENCO_OCELOT is not set
38# CONFIG_MOMENCO_OCELOT_3 is not set
39# CONFIG_MOMENCO_OCELOT_C is not set
40# CONFIG_MOMENCO_OCELOT_G is not set 36# CONFIG_MOMENCO_OCELOT_G is not set
41# CONFIG_MIPS_XXS1500 is not set 37# CONFIG_MIPS_XXS1500 is not set
42# CONFIG_PNX8550_JBS is not set 38# CONFIG_PNX8550_JBS is not set
diff --git a/arch/mips/configs/sb1250-swarm_defconfig b/arch/mips/configs/sb1250-swarm_defconfig
index 6c4f09a381e2..98a914092258 100644
--- a/arch/mips/configs/sb1250-swarm_defconfig
+++ b/arch/mips/configs/sb1250-swarm_defconfig
@@ -25,9 +25,7 @@ CONFIG_ZONE_DMA=y
25# CONFIG_BASLER_EXCITE is not set 25# CONFIG_BASLER_EXCITE is not set
26# CONFIG_MIPS_COBALT is not set 26# CONFIG_MIPS_COBALT is not set
27# CONFIG_MACH_DECSTATION is not set 27# CONFIG_MACH_DECSTATION is not set
28# CONFIG_MIPS_EV64120 is not set
29# CONFIG_MACH_JAZZ is not set 28# CONFIG_MACH_JAZZ is not set
30# CONFIG_LASAT is not set
31# CONFIG_MIPS_ATLAS is not set 29# CONFIG_MIPS_ATLAS is not set
32# CONFIG_MIPS_MALTA is not set 30# CONFIG_MIPS_MALTA is not set
33# CONFIG_MIPS_SEAD is not set 31# CONFIG_MIPS_SEAD is not set
@@ -35,8 +33,6 @@ CONFIG_ZONE_DMA=y
35# CONFIG_MIPS_SIM is not set 33# CONFIG_MIPS_SIM is not set
36# CONFIG_MOMENCO_JAGUAR_ATX is not set 34# CONFIG_MOMENCO_JAGUAR_ATX is not set
37# CONFIG_MOMENCO_OCELOT is not set 35# CONFIG_MOMENCO_OCELOT is not set
38# CONFIG_MOMENCO_OCELOT_3 is not set
39# CONFIG_MOMENCO_OCELOT_C is not set
40# CONFIG_MOMENCO_OCELOT_G is not set 36# CONFIG_MOMENCO_OCELOT_G is not set
41# CONFIG_MIPS_XXS1500 is not set 37# CONFIG_MIPS_XXS1500 is not set
42# CONFIG_PNX8550_JBS is not set 38# CONFIG_PNX8550_JBS is not set
diff --git a/arch/mips/configs/sead_defconfig b/arch/mips/configs/sead_defconfig
index 988b9cdef01f..69c08b24c82a 100644
--- a/arch/mips/configs/sead_defconfig
+++ b/arch/mips/configs/sead_defconfig
@@ -25,9 +25,7 @@ CONFIG_ZONE_DMA=y
25# CONFIG_BASLER_EXCITE is not set 25# CONFIG_BASLER_EXCITE is not set
26# CONFIG_MIPS_COBALT is not set 26# CONFIG_MIPS_COBALT is not set
27# CONFIG_MACH_DECSTATION is not set 27# CONFIG_MACH_DECSTATION is not set
28# CONFIG_MIPS_EV64120 is not set
29# CONFIG_MACH_JAZZ is not set 28# CONFIG_MACH_JAZZ is not set
30# CONFIG_LASAT is not set
31# CONFIG_MIPS_ATLAS is not set 29# CONFIG_MIPS_ATLAS is not set
32# CONFIG_MIPS_MALTA is not set 30# CONFIG_MIPS_MALTA is not set
33CONFIG_MIPS_SEAD=y 31CONFIG_MIPS_SEAD=y
@@ -35,8 +33,6 @@ CONFIG_MIPS_SEAD=y
35# CONFIG_MIPS_SIM is not set 33# CONFIG_MIPS_SIM is not set
36# CONFIG_MOMENCO_JAGUAR_ATX is not set 34# CONFIG_MOMENCO_JAGUAR_ATX is not set
37# CONFIG_MOMENCO_OCELOT is not set 35# CONFIG_MOMENCO_OCELOT is not set
38# CONFIG_MOMENCO_OCELOT_3 is not set
39# CONFIG_MOMENCO_OCELOT_C is not set
40# CONFIG_MOMENCO_OCELOT_G is not set 36# CONFIG_MOMENCO_OCELOT_G is not set
41# CONFIG_MIPS_XXS1500 is not set 37# CONFIG_MIPS_XXS1500 is not set
42# CONFIG_PNX8550_JBS is not set 38# CONFIG_PNX8550_JBS is not set
diff --git a/arch/mips/configs/tb0219_defconfig b/arch/mips/configs/tb0219_defconfig
index 8b1675c07ec4..5d4fc0e4f729 100644
--- a/arch/mips/configs/tb0219_defconfig
+++ b/arch/mips/configs/tb0219_defconfig
@@ -25,9 +25,7 @@ CONFIG_ZONE_DMA=y
25# CONFIG_BASLER_EXCITE is not set 25# CONFIG_BASLER_EXCITE is not set
26# CONFIG_MIPS_COBALT is not set 26# CONFIG_MIPS_COBALT is not set
27# CONFIG_MACH_DECSTATION is not set 27# CONFIG_MACH_DECSTATION is not set
28# CONFIG_MIPS_EV64120 is not set
29# CONFIG_MACH_JAZZ is not set 28# CONFIG_MACH_JAZZ is not set
30# CONFIG_LASAT is not set
31# CONFIG_MIPS_ATLAS is not set 29# CONFIG_MIPS_ATLAS is not set
32# CONFIG_MIPS_MALTA is not set 30# CONFIG_MIPS_MALTA is not set
33# CONFIG_MIPS_SEAD is not set 31# CONFIG_MIPS_SEAD is not set
@@ -35,8 +33,6 @@ CONFIG_ZONE_DMA=y
35# CONFIG_MIPS_SIM is not set 33# CONFIG_MIPS_SIM is not set
36# CONFIG_MOMENCO_JAGUAR_ATX is not set 34# CONFIG_MOMENCO_JAGUAR_ATX is not set
37# CONFIG_MOMENCO_OCELOT is not set 35# CONFIG_MOMENCO_OCELOT is not set
38# CONFIG_MOMENCO_OCELOT_3 is not set
39# CONFIG_MOMENCO_OCELOT_C is not set
40# CONFIG_MOMENCO_OCELOT_G is not set 36# CONFIG_MOMENCO_OCELOT_G is not set
41# CONFIG_MIPS_XXS1500 is not set 37# CONFIG_MIPS_XXS1500 is not set
42# CONFIG_PNX8550_JBS is not set 38# CONFIG_PNX8550_JBS is not set
diff --git a/arch/mips/configs/tb0226_defconfig b/arch/mips/configs/tb0226_defconfig
index b5be8b74d896..1b92b48de051 100644
--- a/arch/mips/configs/tb0226_defconfig
+++ b/arch/mips/configs/tb0226_defconfig
@@ -25,9 +25,7 @@ CONFIG_ZONE_DMA=y
25# CONFIG_BASLER_EXCITE is not set 25# CONFIG_BASLER_EXCITE is not set
26# CONFIG_MIPS_COBALT is not set 26# CONFIG_MIPS_COBALT is not set
27# CONFIG_MACH_DECSTATION is not set 27# CONFIG_MACH_DECSTATION is not set
28# CONFIG_MIPS_EV64120 is not set
29# CONFIG_MACH_JAZZ is not set 28# CONFIG_MACH_JAZZ is not set
30# CONFIG_LASAT is not set
31# CONFIG_MIPS_ATLAS is not set 29# CONFIG_MIPS_ATLAS is not set
32# CONFIG_MIPS_MALTA is not set 30# CONFIG_MIPS_MALTA is not set
33# CONFIG_MIPS_SEAD is not set 31# CONFIG_MIPS_SEAD is not set
@@ -35,8 +33,6 @@ CONFIG_ZONE_DMA=y
35# CONFIG_MIPS_SIM is not set 33# CONFIG_MIPS_SIM is not set
36# CONFIG_MOMENCO_JAGUAR_ATX is not set 34# CONFIG_MOMENCO_JAGUAR_ATX is not set
37# CONFIG_MOMENCO_OCELOT is not set 35# CONFIG_MOMENCO_OCELOT is not set
38# CONFIG_MOMENCO_OCELOT_3 is not set
39# CONFIG_MOMENCO_OCELOT_C is not set
40# CONFIG_MOMENCO_OCELOT_G is not set 36# CONFIG_MOMENCO_OCELOT_G is not set
41# CONFIG_MIPS_XXS1500 is not set 37# CONFIG_MIPS_XXS1500 is not set
42# CONFIG_PNX8550_JBS is not set 38# CONFIG_PNX8550_JBS is not set
diff --git a/arch/mips/configs/tb0287_defconfig b/arch/mips/configs/tb0287_defconfig
index 8bb6be4342b6..5b77c7a5d83a 100644
--- a/arch/mips/configs/tb0287_defconfig
+++ b/arch/mips/configs/tb0287_defconfig
@@ -25,9 +25,7 @@ CONFIG_ZONE_DMA=y
25# CONFIG_BASLER_EXCITE is not set 25# CONFIG_BASLER_EXCITE is not set
26# CONFIG_MIPS_COBALT is not set 26# CONFIG_MIPS_COBALT is not set
27# CONFIG_MACH_DECSTATION is not set 27# CONFIG_MACH_DECSTATION is not set
28# CONFIG_MIPS_EV64120 is not set
29# CONFIG_MACH_JAZZ is not set 28# CONFIG_MACH_JAZZ is not set
30# CONFIG_LASAT is not set
31# CONFIG_MIPS_ATLAS is not set 29# CONFIG_MIPS_ATLAS is not set
32# CONFIG_MIPS_MALTA is not set 30# CONFIG_MIPS_MALTA is not set
33# CONFIG_MIPS_SEAD is not set 31# CONFIG_MIPS_SEAD is not set
@@ -35,8 +33,6 @@ CONFIG_ZONE_DMA=y
35# CONFIG_MIPS_SIM is not set 33# CONFIG_MIPS_SIM is not set
36# CONFIG_MOMENCO_JAGUAR_ATX is not set 34# CONFIG_MOMENCO_JAGUAR_ATX is not set
37# CONFIG_MOMENCO_OCELOT is not set 35# CONFIG_MOMENCO_OCELOT is not set
38# CONFIG_MOMENCO_OCELOT_3 is not set
39# CONFIG_MOMENCO_OCELOT_C is not set
40# CONFIG_MOMENCO_OCELOT_G is not set 36# CONFIG_MOMENCO_OCELOT_G is not set
41# CONFIG_MIPS_XXS1500 is not set 37# CONFIG_MIPS_XXS1500 is not set
42# CONFIG_PNX8550_JBS is not set 38# CONFIG_PNX8550_JBS is not set
diff --git a/arch/mips/configs/workpad_defconfig b/arch/mips/configs/workpad_defconfig
index 8f019ffcc71b..94a4f94a8b24 100644
--- a/arch/mips/configs/workpad_defconfig
+++ b/arch/mips/configs/workpad_defconfig
@@ -25,9 +25,7 @@ CONFIG_ZONE_DMA=y
25# CONFIG_BASLER_EXCITE is not set 25# CONFIG_BASLER_EXCITE is not set
26# CONFIG_MIPS_COBALT is not set 26# CONFIG_MIPS_COBALT is not set
27# CONFIG_MACH_DECSTATION is not set 27# CONFIG_MACH_DECSTATION is not set
28# CONFIG_MIPS_EV64120 is not set
29# CONFIG_MACH_JAZZ is not set 28# CONFIG_MACH_JAZZ is not set
30# CONFIG_LASAT is not set
31# CONFIG_MIPS_ATLAS is not set 29# CONFIG_MIPS_ATLAS is not set
32# CONFIG_MIPS_MALTA is not set 30# CONFIG_MIPS_MALTA is not set
33# CONFIG_MIPS_SEAD is not set 31# CONFIG_MIPS_SEAD is not set
@@ -35,8 +33,6 @@ CONFIG_ZONE_DMA=y
35# CONFIG_MIPS_SIM is not set 33# CONFIG_MIPS_SIM is not set
36# CONFIG_MOMENCO_JAGUAR_ATX is not set 34# CONFIG_MOMENCO_JAGUAR_ATX is not set
37# CONFIG_MOMENCO_OCELOT is not set 35# CONFIG_MOMENCO_OCELOT is not set
38# CONFIG_MOMENCO_OCELOT_3 is not set
39# CONFIG_MOMENCO_OCELOT_C is not set
40# CONFIG_MOMENCO_OCELOT_G is not set 36# CONFIG_MOMENCO_OCELOT_G is not set
41# CONFIG_MIPS_XXS1500 is not set 37# CONFIG_MIPS_XXS1500 is not set
42# CONFIG_PNX8550_JBS is not set 38# CONFIG_PNX8550_JBS is not set
diff --git a/arch/mips/configs/wrppmc_defconfig b/arch/mips/configs/wrppmc_defconfig
index 52b48c0715d3..e38bd9b0eadc 100644
--- a/arch/mips/configs/wrppmc_defconfig
+++ b/arch/mips/configs/wrppmc_defconfig
@@ -25,9 +25,7 @@ CONFIG_ZONE_DMA=y
25# CONFIG_BASLER_EXCITE is not set 25# CONFIG_BASLER_EXCITE is not set
26# CONFIG_MIPS_COBALT is not set 26# CONFIG_MIPS_COBALT is not set
27# CONFIG_MACH_DECSTATION is not set 27# CONFIG_MACH_DECSTATION is not set
28# CONFIG_MIPS_EV64120 is not set
29# CONFIG_MACH_JAZZ is not set 28# CONFIG_MACH_JAZZ is not set
30# CONFIG_LASAT is not set
31# CONFIG_MIPS_ATLAS is not set 29# CONFIG_MIPS_ATLAS is not set
32# CONFIG_MIPS_MALTA is not set 30# CONFIG_MIPS_MALTA is not set
33# CONFIG_MIPS_SEAD is not set 31# CONFIG_MIPS_SEAD is not set
@@ -35,8 +33,6 @@ CONFIG_WR_PPMC=y
35# CONFIG_MIPS_SIM is not set 33# CONFIG_MIPS_SIM is not set
36# CONFIG_MOMENCO_JAGUAR_ATX is not set 34# CONFIG_MOMENCO_JAGUAR_ATX is not set
37# CONFIG_MOMENCO_OCELOT is not set 35# CONFIG_MOMENCO_OCELOT is not set
38# CONFIG_MOMENCO_OCELOT_3 is not set
39# CONFIG_MOMENCO_OCELOT_C is not set
40# CONFIG_MOMENCO_OCELOT_G is not set 36# CONFIG_MOMENCO_OCELOT_G is not set
41# CONFIG_MIPS_XXS1500 is not set 37# CONFIG_MIPS_XXS1500 is not set
42# CONFIG_PNX8550_JBS is not set 38# CONFIG_PNX8550_JBS is not set
diff --git a/arch/mips/configs/yosemite_defconfig b/arch/mips/configs/yosemite_defconfig
index 6824606309e5..f1cdb12f7925 100644
--- a/arch/mips/configs/yosemite_defconfig
+++ b/arch/mips/configs/yosemite_defconfig
@@ -25,9 +25,7 @@ CONFIG_ZONE_DMA=y
25# CONFIG_BASLER_EXCITE is not set 25# CONFIG_BASLER_EXCITE is not set
26# CONFIG_MIPS_COBALT is not set 26# CONFIG_MIPS_COBALT is not set
27# CONFIG_MACH_DECSTATION is not set 27# CONFIG_MACH_DECSTATION is not set
28# CONFIG_MIPS_EV64120 is not set
29# CONFIG_MACH_JAZZ is not set 28# CONFIG_MACH_JAZZ is not set
30# CONFIG_LASAT is not set
31# CONFIG_MIPS_ATLAS is not set 29# CONFIG_MIPS_ATLAS is not set
32# CONFIG_MIPS_MALTA is not set 30# CONFIG_MIPS_MALTA is not set
33# CONFIG_MIPS_SEAD is not set 31# CONFIG_MIPS_SEAD is not set
@@ -35,8 +33,6 @@ CONFIG_ZONE_DMA=y
35# CONFIG_MIPS_SIM is not set 33# CONFIG_MIPS_SIM is not set
36# CONFIG_MOMENCO_JAGUAR_ATX is not set 34# CONFIG_MOMENCO_JAGUAR_ATX is not set
37# CONFIG_MOMENCO_OCELOT is not set 35# CONFIG_MOMENCO_OCELOT is not set
38# CONFIG_MOMENCO_OCELOT_3 is not set
39# CONFIG_MOMENCO_OCELOT_C is not set
40# CONFIG_MOMENCO_OCELOT_G is not set 36# CONFIG_MOMENCO_OCELOT_G is not set
41# CONFIG_MIPS_XXS1500 is not set 37# CONFIG_MIPS_XXS1500 is not set
42# CONFIG_PNX8550_JBS is not set 38# CONFIG_PNX8550_JBS is not set
diff --git a/arch/mips/ddb5xxx/ddb5477/Makefile b/arch/mips/ddb5xxx/ddb5477/Makefile
index 23fd3b81fe1a..4864b8a659c7 100644
--- a/arch/mips/ddb5xxx/ddb5477/Makefile
+++ b/arch/mips/ddb5xxx/ddb5477/Makefile
@@ -2,7 +2,8 @@
2# Makefile for NEC DDB-Vrc5477 board 2# Makefile for NEC DDB-Vrc5477 board
3# 3#
4 4
5obj-y += irq.o irq_5477.o setup.o lcd44780.o 5obj-y += ddb5477-platform.o irq.o irq_5477.o setup.o \
6 lcd44780.o
6 7
7obj-$(CONFIG_RUNTIME_DEBUG) += debug.o 8obj-$(CONFIG_RUNTIME_DEBUG) += debug.o
8obj-$(CONFIG_KGDB) += kgdb_io.o 9obj-$(CONFIG_KGDB) += kgdb_io.o
diff --git a/arch/mips/ddb5xxx/ddb5477/ddb5477-platform.c b/arch/mips/ddb5xxx/ddb5477/ddb5477-platform.c
new file mode 100644
index 000000000000..c16020ad54c2
--- /dev/null
+++ b/arch/mips/ddb5xxx/ddb5477/ddb5477-platform.c
@@ -0,0 +1,49 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2007 Ralf Baechle (ralf@linux-mips.org)
7 */
8#include <linux/init.h>
9#include <linux/module.h>
10#include <linux/serial_8250.h>
11
12#include <asm/ddb5xxx/ddb5477.h>
13
14#define DDB_UART_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP)
15
16#define DDB5477_PORT(base, int) \
17{ \
18 .mapbase = base, \
19 .irq = int, \
20 .uartclk = 1843200, \
21 .iotype = UPIO_MEM, \
22 .flags = DDB_UART_FLAGS, \
23 .regshift = 3, \
24}
25
26static struct plat_serial8250_port uart8250_data[] = {
27 DDB5477_PORT(0xbfa04200, VRC5477_IRQ_UART0),
28 DDB5477_PORT(0xbfa04240, VRC5477_IRQ_UART1),
29 { },
30};
31
32static struct platform_device uart8250_device = {
33 .name = "serial8250",
34 .id = PLAT8250_DEV_PLATFORM,
35 .dev = {
36 .platform_data = uart8250_data,
37 },
38};
39
40static int __init uart8250_init(void)
41{
42 return platform_device_register(&uart8250_device);
43}
44
45module_init(uart8250_init);
46
47MODULE_AUTHOR("Ralf Baechle <ralf@linux-mips.org>");
48MODULE_LICENSE("GPL");
49MODULE_DESCRIPTION("8250 UART probe driver for the NEC DDB5477");
diff --git a/arch/mips/dec/prom/console.c b/arch/mips/dec/prom/console.c
index 65419bf32441..078e1a12421d 100644
--- a/arch/mips/dec/prom/console.c
+++ b/arch/mips/dec/prom/console.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * DECstation PROM-based early console support. 4 * DECstation PROM-based early console support.
5 * 5 *
6 * Copyright (C) 2004 Maciej W. Rozycki 6 * Copyright (C) 2004, 2007 Maciej W. Rozycki
7 * 7 *
8 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License 9 * modify it under the terms of the GNU General Public License
@@ -13,15 +13,35 @@
13#include <linux/console.h> 13#include <linux/console.h>
14#include <linux/init.h> 14#include <linux/init.h>
15#include <linux/kernel.h> 15#include <linux/kernel.h>
16#include <linux/string.h>
16 17
17#include <asm/dec/prom.h> 18#include <asm/dec/prom.h>
18 19
19void prom_putchar(char c) 20static void __init prom_console_write(struct console *con, const char *s,
21 unsigned int c)
20{ 22{
21 char s[2]; 23 char buf[81];
24 unsigned int chunk = sizeof(buf) - 1;
22 25
23 s[0] = c; 26 while (c > 0) {
24 s[1] = '\0'; 27 if (chunk > c)
28 chunk = c;
29 memcpy(buf, s, chunk);
30 buf[chunk] = '\0';
31 prom_printf("%s", buf);
32 s += chunk;
33 c -= chunk;
34 }
35}
36
37static struct console promcons __initdata = {
38 .name = "prom",
39 .write = prom_console_write,
40 .flags = CON_BOOT | CON_PRINTBUFFER,
41 .index = -1,
42};
25 43
26 prom_printf( s); 44void __init register_prom_console(void)
45{
46 register_console(&promcons);
27} 47}
diff --git a/arch/mips/dec/prom/init.c b/arch/mips/dec/prom/init.c
index a217aafe59f6..808c182fd3fa 100644
--- a/arch/mips/dec/prom/init.c
+++ b/arch/mips/dec/prom/init.c
@@ -86,7 +86,7 @@ void __init which_prom(s32 magic, s32 *prom_vec)
86 86
87void __init prom_init(void) 87void __init prom_init(void)
88{ 88{
89 extern void ATTRIB_NORET dec_machine_halt(void); 89 extern void dec_machine_halt(void);
90 static char cpu_msg[] __initdata = 90 static char cpu_msg[] __initdata =
91 "Sorry, this kernel is compiled for a wrong CPU type!\n"; 91 "Sorry, this kernel is compiled for a wrong CPU type!\n";
92 s32 argc = fw_arg0; 92 s32 argc = fw_arg0;
@@ -103,6 +103,9 @@ void __init prom_init(void)
103 if (prom_is_rex(magic)) 103 if (prom_is_rex(magic))
104 rex_clear_cache(); 104 rex_clear_cache();
105 105
106 /* Register the early console. */
107 register_prom_console();
108
106 /* Were we compiled with the right CPU option? */ 109 /* Were we compiled with the right CPU option? */
107#if defined(CONFIG_CPU_R3000) 110#if defined(CONFIG_CPU_R3000)
108 if ((current_cpu_data.cputype == CPU_R4000SC) || 111 if ((current_cpu_data.cputype == CPU_R4000SC) ||
diff --git a/arch/mips/dec/reset.c b/arch/mips/dec/reset.c
index 56397227adb0..c15a879046e5 100644
--- a/arch/mips/dec/reset.c
+++ b/arch/mips/dec/reset.c
@@ -9,26 +9,26 @@
9 9
10#include <asm/addrspace.h> 10#include <asm/addrspace.h>
11 11
12typedef void ATTRIB_NORET (* noret_func_t)(void); 12typedef void __noreturn (* noret_func_t)(void);
13 13
14static inline void ATTRIB_NORET back_to_prom(void) 14static inline void __noreturn back_to_prom(void)
15{ 15{
16 noret_func_t func = (void *)CKSEG1ADDR(0x1fc00000); 16 noret_func_t func = (void *)CKSEG1ADDR(0x1fc00000);
17 17
18 func(); 18 func();
19} 19}
20 20
21void ATTRIB_NORET dec_machine_restart(char *command) 21void __noreturn dec_machine_restart(char *command)
22{ 22{
23 back_to_prom(); 23 back_to_prom();
24} 24}
25 25
26void ATTRIB_NORET dec_machine_halt(void) 26void __noreturn dec_machine_halt(void)
27{ 27{
28 back_to_prom(); 28 back_to_prom();
29} 29}
30 30
31void ATTRIB_NORET dec_machine_power_off(void) 31void __noreturn dec_machine_power_off(void)
32{ 32{
33 /* DECstations don't have a software power switch */ 33 /* DECstations don't have a software power switch */
34 back_to_prom(); 34 back_to_prom();
diff --git a/arch/mips/defconfig b/arch/mips/defconfig
index 41211f8b7738..b3b6e58058f6 100644
--- a/arch/mips/defconfig
+++ b/arch/mips/defconfig
@@ -25,9 +25,7 @@ CONFIG_ZONE_DMA=y
25# CONFIG_BASLER_EXCITE is not set 25# CONFIG_BASLER_EXCITE is not set
26# CONFIG_MIPS_COBALT is not set 26# CONFIG_MIPS_COBALT is not set
27# CONFIG_MACH_DECSTATION is not set 27# CONFIG_MACH_DECSTATION is not set
28# CONFIG_MIPS_EV64120 is not set
29# CONFIG_MACH_JAZZ is not set 28# CONFIG_MACH_JAZZ is not set
30# CONFIG_LASAT is not set
31# CONFIG_MIPS_ATLAS is not set 29# CONFIG_MIPS_ATLAS is not set
32# CONFIG_MIPS_MALTA is not set 30# CONFIG_MIPS_MALTA is not set
33# CONFIG_MIPS_SEAD is not set 31# CONFIG_MIPS_SEAD is not set
@@ -35,8 +33,6 @@ CONFIG_ZONE_DMA=y
35# CONFIG_MIPS_SIM is not set 33# CONFIG_MIPS_SIM is not set
36# CONFIG_MOMENCO_JAGUAR_ATX is not set 34# CONFIG_MOMENCO_JAGUAR_ATX is not set
37# CONFIG_MOMENCO_OCELOT is not set 35# CONFIG_MOMENCO_OCELOT is not set
38# CONFIG_MOMENCO_OCELOT_3 is not set
39# CONFIG_MOMENCO_OCELOT_C is not set
40# CONFIG_MOMENCO_OCELOT_G is not set 36# CONFIG_MOMENCO_OCELOT_G is not set
41# CONFIG_MIPS_XXS1500 is not set 37# CONFIG_MIPS_XXS1500 is not set
42# CONFIG_PNX8550_JBS is not set 38# CONFIG_PNX8550_JBS is not set
diff --git a/arch/mips/gt64120/ev64120/Kconfig b/arch/mips/gt64120/ev64120/Kconfig
deleted file mode 100644
index d691762cb0f7..000000000000
--- a/arch/mips/gt64120/ev64120/Kconfig
+++ /dev/null
@@ -1,3 +0,0 @@
1config EVB_PCI1
2 bool "Enable Second PCI (PCI1)"
3 depends on MIPS_EV64120
diff --git a/arch/mips/gt64120/ev64120/Makefile b/arch/mips/gt64120/ev64120/Makefile
deleted file mode 100644
index 323b2cebc691..000000000000
--- a/arch/mips/gt64120/ev64120/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
1#
2# Copyright 2000 RidgeRun, Inc.
3# Author: RidgeRun, Inc.
4# glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com
5#
6# Makefile for the Galileo EV64120 board.
7#
8
9obj-y += irq.o promcon.o reset.o serialGT.o setup.o
diff --git a/arch/mips/gt64120/ev64120/irq.c b/arch/mips/gt64120/ev64120/irq.c
deleted file mode 100644
index 64e4c80b6139..000000000000
--- a/arch/mips/gt64120/ev64120/irq.c
+++ /dev/null
@@ -1,116 +0,0 @@
1/*
2 * BRIEF MODULE DESCRIPTION
3 * Code to handle irqs on GT64120A boards
4 * Derived from mips/orion and Cort <cort@fsmlabs.com>
5 *
6 * Copyright (C) 2000 RidgeRun, Inc.
7 * Author: RidgeRun, Inc.
8 * glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 *
15 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
16 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
17 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
18 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
21 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
22 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 *
26 * You should have received a copy of the GNU General Public License along
27 * with this program; if not, write to the Free Software Foundation, Inc.,
28 * 675 Mass Ave, Cambridge, MA 02139, USA.
29 */
30#include <linux/errno.h>
31#include <linux/init.h>
32#include <linux/kernel_stat.h>
33#include <linux/module.h>
34#include <linux/signal.h>
35#include <linux/sched.h>
36#include <linux/types.h>
37#include <linux/interrupt.h>
38#include <linux/ioport.h>
39#include <linux/timex.h>
40#include <linux/slab.h>
41#include <linux/random.h>
42#include <linux/bitops.h>
43#include <asm/bootinfo.h>
44#include <asm/io.h>
45#include <asm/mipsregs.h>
46#include <asm/system.h>
47#include <asm/gt64120.h>
48
49asmlinkage void plat_irq_dispatch(void)
50{
51 unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM;
52
53 if (pending & STATUSF_IP4) /* int2 hardware line (timer) */
54 do_IRQ(4);
55 else if (pending & STATUSF_IP2) /* int0 hardware line */
56 do_IRQ(GT_INTA);
57 else if (pending & STATUSF_IP5) /* int3 hardware line */
58 do_IRQ(GT_INTD);
59 else if (pending & STATUSF_IP6) /* int4 hardware line */
60 do_IRQ(6);
61 else if (pending & STATUSF_IP7) /* compare int */
62 do_IRQ(7);
63 else
64 spurious_interrupt();
65}
66
67static void disable_ev64120_irq(unsigned int irq_nr)
68{
69 if (irq_nr >= 8) { // All PCI interrupts are on line 5 or 2
70 clear_c0_status(9 << 10);
71 } else {
72 clear_c0_status(1 << (irq_nr + 8));
73 }
74}
75
76static void enable_ev64120_irq(unsigned int irq_nr)
77{
78 if (irq_nr >= 8) // All PCI interrupts are on line 5 or 2
79 set_c0_status(9 << 10);
80 else
81 set_c0_status(1 << (irq_nr + 8));
82}
83
84static void end_ev64120_irq(unsigned int irq)
85{
86 if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
87 enable_ev64120_irq(irq);
88}
89
90static struct irq_chip ev64120_irq_type = {
91 .name = "EV64120",
92 .ack = disable_ev64120_irq,
93 .mask = disable_ev64120_irq,
94 .mask_ack = disable_ev64120_irq,
95 .unmask = enable_ev64120_irq,
96 .end = end_ev64120_irq,
97};
98
99void gt64120_irq_setup(void)
100{
101 /*
102 * Clear all of the interrupts while we change the able around a bit.
103 */
104 clear_c0_status(ST0_IM);
105
106 /*
107 * Enable timer. Other interrupts will be enabled as they are
108 * registered.
109 */
110 set_c0_status(IE_IRQ2);
111}
112
113void __init arch_init_irq(void)
114{
115 gt64120_irq_setup();
116}
diff --git a/arch/mips/gt64120/ev64120/promcon.c b/arch/mips/gt64120/ev64120/promcon.c
deleted file mode 100644
index 6e0ecfed9640..000000000000
--- a/arch/mips/gt64120/ev64120/promcon.c
+++ /dev/null
@@ -1,48 +0,0 @@
1/*
2 * Wrap-around code for a console using the
3 * SGI PROM io-routines.
4 *
5 * Copyright (c) 1999 Ulf Carlsson
6 *
7 * Derived from DECstation promcon.c
8 * Copyright (c) 1998 Harald Koerfgen
9 */
10#include <linux/tty.h>
11#include <linux/init.h>
12#include <linux/console.h>
13
14static void prom_console_write(struct console *co, const char *s,
15 unsigned count)
16{
17 extern int CONSOLE_CHANNEL; // The default serial port
18 unsigned i;
19
20 for (i = 0; i < count; i++) {
21 if (*s == 10)
22 serial_putc(CONSOLE_CHANNEL, 13);
23 serial_putc(CONSOLE_CHANNEL, *s++);
24 }
25}
26
27static struct console sercons = {
28 .name = "ttyS",
29 .write = prom_console_write,
30 .flags = CON_PRINTBUFFER,
31 .index = -1,
32};
33
34/*
35 * Register console.
36 */
37
38static int gal_serial_console_init(void)
39{
40 // serial_init();
41 //serial_set(115200);
42
43 register_console(&sercons);
44
45 return 0;
46}
47
48console_initcall(gal_serial_console_init);
diff --git a/arch/mips/gt64120/ev64120/reset.c b/arch/mips/gt64120/ev64120/reset.c
deleted file mode 100644
index 7b9f5e5bf21f..000000000000
--- a/arch/mips/gt64120/ev64120/reset.c
+++ /dev/null
@@ -1,45 +0,0 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 1997 Ralf Baechle
7 */
8#include <linux/sched.h>
9#include <linux/mm.h>
10#include <asm/io.h>
11#include <asm/pgtable.h>
12#include <asm/processor.h>
13#include <asm/reboot.h>
14#include <asm/system.h>
15
16void galileo_machine_restart(char *command)
17{
18 *(volatile char *) 0xbc000000 = 0x0f;
19 /*
20 * Ouch, we're still alive ... This time we take the silver bullet ...
21 * ... and find that we leave the hardware in a state in which the
22 * kernel in the flush locks up somewhen during of after the PCI
23 * detection stuff.
24 */
25 set_c0_status(ST0_BEV | ST0_ERL);
26 change_c0_config(CONF_CM_CMASK, CONF_CM_UNCACHED);
27 flush_cache_all();
28 write_c0_wired(0);
29 __asm__ __volatile__("jr\t%0"::"r"(0xbfc00000));
30}
31
32void galileo_machine_halt(void)
33{
34 printk(KERN_NOTICE "You can safely turn off the power\n");
35 while (1)
36 __asm__(".set\tmips3\n\t"
37 "wait\n\t"
38 ".set\tmips0");
39
40}
41
42void galileo_machine_power_off(void)
43{
44 galileo_machine_halt();
45}
diff --git a/arch/mips/gt64120/ev64120/serialGT.c b/arch/mips/gt64120/ev64120/serialGT.c
deleted file mode 100644
index 8f0d835491ff..000000000000
--- a/arch/mips/gt64120/ev64120/serialGT.c
+++ /dev/null
@@ -1,212 +0,0 @@
1/*
2 * serialGT.c
3 *
4 * BRIEF MODULE DESCRIPTION
5 * Low Level Serial Port control for use
6 * with the Galileo EVB64120A MIPS eval board and
7 * its on board two channel 16552 Uart.
8 *
9 * Copyright (C) 2000 RidgeRun, Inc.
10 * Author: RidgeRun, Inc.
11 * glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com
12 *
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by the
15 * Free Software Foundation; either version 2 of the License, or (at your
16 * option) any later version.
17 *
18 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
19 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
20 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
21 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
24 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
25 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 *
29 * You should have received a copy of the GNU General Public License along
30 * with this program; if not, write to the Free Software Foundation, Inc.,
31 * 675 Mass Ave, Cambridge, MA 02139, USA.
32 *
33 */
34
35// Note:
36// Serial CHANNELS - 0 is the bottom connector of evb64120A.
37// (The one that maps to the "B" channel of the
38// board's uart)
39// 1 is the top connector of evb64120A.
40// (The one that maps to the "A" channel of the
41// board's uart)
42int DEBUG_CHANNEL = 0; // See Note Above
43int CONSOLE_CHANNEL = 1; // See Note Above
44
45#define DUART 0xBD000000 /* Base address of Uart. */
46#define CHANNELOFFSET 0x20 /* DUART+CHANNELOFFSET gets you to the ChanA
47 register set of the 16552 Uart device.
48 DUART+0 gets you to the ChanB register set.
49 */
50#define DUART_DELTA 0x4
51#define FIFO_ENABLE 0x07
52#define INT_ENABLE 0x04 /* default interrupt mask */
53
54#define RBR 0x00
55#define THR 0x00
56#define DLL 0x00
57#define IER 0x01
58#define DLM 0x01
59#define IIR 0x02
60#define FCR 0x02
61#define LCR 0x03
62#define MCR 0x04
63#define LSR 0x05
64#define MSR 0x06
65#define SCR 0x07
66
67#define LCR_DLAB 0x80
68#define XTAL 1843200
69#define LSR_THRE 0x20
70#define LSR_BI 0x10
71#define LSR_DR 0x01
72#define MCR_LOOP 0x10
73#define ACCESS_DELAY 0x10000
74
75/******************************
76 Routine:
77 Description:
78 ******************************/
79int inreg(int channel, int reg)
80{
81 int val;
82 val =
83 *((volatile unsigned char *) DUART +
84 (channel * CHANNELOFFSET) + (reg * DUART_DELTA));
85 return val;
86}
87
88/******************************
89 Routine:
90 Description:
91 ******************************/
92void outreg(int channel, int reg, unsigned char val)
93{
94 *((volatile unsigned char *) DUART + (channel * CHANNELOFFSET)
95 + (reg * DUART_DELTA)) = val;
96}
97
98/******************************
99 Routine:
100 Description:
101 Initialize the device driver.
102 ******************************/
103void serial_init(int channel)
104{
105 /*
106 * Configure active port, (CHANNELOFFSET already set.)
107 *
108 * Set 8 bits, 1 stop bit, no parity.
109 *
110 * LCR<7> 0 divisor latch access bit
111 * LCR<6> 0 break control (1=send break)
112 * LCR<5> 0 stick parity (0=space, 1=mark)
113 * LCR<4> 0 parity even (0=odd, 1=even)
114 * LCR<3> 0 parity enable (1=enabled)
115 * LCR<2> 0 # stop bits (0=1, 1=1.5)
116 * LCR<1:0> 11 bits per character(00=5, 01=6, 10=7, 11=8)
117 */
118 outreg(channel, LCR, 0x3);
119
120 outreg(channel, FCR, FIFO_ENABLE); /* Enable the FIFO */
121
122 outreg(channel, IER, INT_ENABLE); /* Enable appropriate interrupts */
123}
124
125/******************************
126 Routine:
127 Description:
128 Set the baud rate.
129 ******************************/
130void serial_set(int channel, unsigned long baud)
131{
132 unsigned char sav_lcr;
133
134 /*
135 * Enable access to the divisor latches by setting DLAB in LCR.
136 *
137 */
138 sav_lcr = inreg(channel, LCR);
139
140#if 0
141 /*
142 * Set baud rate
143 */
144 outreg(channel, LCR, LCR_DLAB | sav_lcr);
145 // outreg(DLL,(XTAL/(16*2*(baud))-2));
146 outreg(channel, DLL, XTAL / (16 * baud));
147 // outreg(DLM,(XTAL/(16*2*(baud))-2)>>8);
148 outreg(channel, DLM, (XTAL / (16 * baud)) >> 8);
149#else
150 /*
151 * Note: Set baud rate, hardcoded here for rate of 115200
152 * since became unsure of above "baud rate" algorithm (??).
153 */
154 outreg(channel, LCR, 0x83);
155 outreg(channel, DLM, 0x00); // See note above
156 outreg(channel, DLL, 0x02); // See note above.
157 outreg(channel, LCR, 0x03);
158#endif
159
160 /*
161 * Restore line control register
162 */
163 outreg(channel, LCR, sav_lcr);
164}
165
166
167/******************************
168 Routine:
169 Description:
170 Transmit a character.
171 ******************************/
172void serial_putc(int channel, int c)
173{
174 while ((inreg(channel, LSR) & LSR_THRE) == 0);
175 outreg(channel, THR, c);
176}
177
178/******************************
179 Routine:
180 Description:
181 Read a received character if one is
182 available. Return -1 otherwise.
183 ******************************/
184int serial_getc(int channel)
185{
186 if (inreg(channel, LSR) & LSR_DR) {
187 return inreg(channel, RBR);
188 }
189 return -1;
190}
191
192/******************************
193 Routine:
194 Description:
195 Used by embedded gdb client. (example; gdb-stub.c)
196 ******************************/
197char getDebugChar()
198{
199 int val;
200 while ((val = serial_getc(DEBUG_CHANNEL)) == -1); // loop until we get a character in.
201 return (char) val;
202}
203
204/******************************
205 Routine:
206 Description:
207 Used by embedded gdb target. (example; gdb-stub.c)
208 ******************************/
209void putDebugChar(char c)
210{
211 serial_putc(DEBUG_CHANNEL, (int) c);
212}
diff --git a/arch/mips/gt64120/ev64120/setup.c b/arch/mips/gt64120/ev64120/setup.c
deleted file mode 100644
index 477848c22a2c..000000000000
--- a/arch/mips/gt64120/ev64120/setup.c
+++ /dev/null
@@ -1,99 +0,0 @@
1/*
2 * Copyright (C) 2000 RidgeRun, Inc.
3 * Author: RidgeRun, Inc.
4 * glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 *
11 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
12 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
14 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
15 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
16 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
17 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
18 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
19 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
20 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
21 *
22 * You should have received a copy of the GNU General Public License along
23 * with this program; if not, write to the Free Software Foundation, Inc.,
24 * 675 Mass Ave, Cambridge, MA 02139, USA.
25 *
26 */
27#include <linux/init.h>
28#include <linux/kernel.h>
29#include <linux/types.h>
30#include <linux/mm.h>
31#include <linux/swap.h>
32#include <linux/ioport.h>
33#include <linux/sched.h>
34#include <linux/interrupt.h>
35#include <linux/pci.h>
36#include <linux/timex.h>
37#include <linux/pm.h>
38
39#include <asm/bootinfo.h>
40#include <asm/page.h>
41#include <asm/io.h>
42#include <asm/irq.h>
43#include <asm/pci.h>
44#include <asm/processor.h>
45#include <asm/time.h>
46#include <asm/reboot.h>
47#include <asm/traps.h>
48#include <linux/bootmem.h>
49
50unsigned long gt64120_base = KSEG1ADDR(0x14000000);
51
52/* These functions are used for rebooting or halting the machine*/
53extern void galileo_machine_restart(char *command);
54extern void galileo_machine_halt(void);
55extern void galileo_machine_power_off(void);
56/*
57 *This structure holds pointers to the pci configuration space accesses
58 *and interrupts allocating routine for device over the PCI
59 */
60extern struct pci_ops galileo_pci_ops;
61
62void __init prom_free_prom_memory(void)
63{
64}
65
66/*
67 * Initializes basic routines and structures pointers, memory size (as
68 * given by the bios and saves the command line.
69 */
70
71void __init plat_mem_setup(void)
72{
73 _machine_restart = galileo_machine_restart;
74 _machine_halt = galileo_machine_halt;
75 pm_power_off = galileo_machine_power_off;
76
77 set_io_port_base(KSEG1);
78}
79
80const char *get_system_type(void)
81{
82 return "Galileo EV64120A";
83}
84
85/*
86 * Kernel arguments passed by the firmware
87 *
88 * $a0 - nothing
89 * $a1 - holds a pointer to the eprom parameters
90 * $a2 - nothing
91 */
92
93void __init prom_init(void)
94{
95 mips_machgroup = MACH_GROUP_GALILEO;
96 mips_machtype = MACH_EV64120A;
97
98 add_memory_region(0, 32 << 20, BOOT_MEM_RAM);
99}
diff --git a/arch/mips/gt64120/momenco_ocelot/Makefile b/arch/mips/gt64120/momenco_ocelot/Makefile
index 9f9a33fc76b9..1df5fe23c642 100644
--- a/arch/mips/gt64120/momenco_ocelot/Makefile
+++ b/arch/mips/gt64120/momenco_ocelot/Makefile
@@ -2,6 +2,6 @@
2# Makefile for Momentum's Ocelot board. 2# Makefile for Momentum's Ocelot board.
3# 3#
4 4
5obj-y += irq.o prom.o reset.o setup.o 5obj-y += irq.o ocelot-platform.o prom.o reset.o setup.o
6 6
7obj-$(CONFIG_KGDB) += dbg_io.o 7obj-$(CONFIG_KGDB) += dbg_io.o
diff --git a/arch/mips/gt64120/momenco_ocelot/ocelot-platform.c b/arch/mips/gt64120/momenco_ocelot/ocelot-platform.c
new file mode 100644
index 000000000000..81d9031a5a2a
--- /dev/null
+++ b/arch/mips/gt64120/momenco_ocelot/ocelot-platform.c
@@ -0,0 +1,46 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2007 Ralf Baechle (ralf@linux-mips.org)
7 *
8 * A NS16552 DUART with a 20MHz crystal.
9 *
10 */
11#include <linux/module.h>
12#include <linux/init.h>
13#include <linux/serial_8250.h>
14
15#define OCELOT_UART_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP)
16
17static struct plat_serial8250_port uart8250_data[] = {
18 {
19 .mapbase = 0xe0001020,
20 .irq = 4,
21 .uartclk = 20000000,
22 .iotype = UPIO_MEM,
23 .flags = OCELOT_UART_FLAGS,
24 .regshift = 2,
25 },
26 { },
27};
28
29static struct platform_device uart8250_device = {
30 .name = "serial8250",
31 .id = PLAT8250_DEV_PLATFORM,
32 .dev = {
33 .platform_data = uart8250_data,
34 },
35};
36
37static int __init uart8250_init(void)
38{
39 return platform_device_register(&uart8250_device);
40}
41
42module_init(uart8250_init);
43
44MODULE_AUTHOR("Ralf Baechle <ralf@linux-mips.org>");
45MODULE_LICENSE("GPL");
46MODULE_DESCRIPTION("8250 UART probe driver for the Momenco Ocelot");
diff --git a/arch/mips/gt64120/wrppmc/setup.c b/arch/mips/gt64120/wrppmc/setup.c
index 121188d5ec4a..ea965529e5e0 100644
--- a/arch/mips/gt64120/wrppmc/setup.c
+++ b/arch/mips/gt64120/wrppmc/setup.c
@@ -158,8 +158,8 @@ const char *get_system_type(void)
158 */ 158 */
159void __init prom_init(void) 159void __init prom_init(void)
160{ 160{
161 mips_machgroup = MACH_GROUP_GALILEO; 161 mips_machgroup = MACH_GROUP_WINDRIVER;
162 mips_machtype = MACH_EV64120A; 162 mips_machtype = MACH_WRPPMC;
163 163
164 add_memory_region(WRPPMC_SDRAM_SCS0_BASE, WRPPMC_SDRAM_SCS0_SIZE, BOOT_MEM_RAM); 164 add_memory_region(WRPPMC_SDRAM_SCS0_BASE, WRPPMC_SDRAM_SCS0_SIZE, BOOT_MEM_RAM);
165 add_memory_region(WRPPMC_BOOTROM_BASE, WRPPMC_BOOTROM_SIZE, BOOT_MEM_ROM_DATA); 165 add_memory_region(WRPPMC_BOOTROM_BASE, WRPPMC_BOOTROM_SIZE, BOOT_MEM_ROM_DATA);
diff --git a/arch/mips/jazz/Makefile b/arch/mips/jazz/Makefile
index dd9d99bfcf7a..ae4c402b5004 100644
--- a/arch/mips/jazz/Makefile
+++ b/arch/mips/jazz/Makefile
@@ -2,4 +2,4 @@
2# Makefile for the Jazz family specific parts of the kernel 2# Makefile for the Jazz family specific parts of the kernel
3# 3#
4 4
5obj-y := irq.o jazzdma.o reset.o setup.o 5obj-y := irq.o jazzdma.o jazz-platform.o reset.o setup.o
diff --git a/arch/mips/jazz/jazz-platform.c b/arch/mips/jazz/jazz-platform.c
new file mode 100644
index 000000000000..fd736703eef2
--- /dev/null
+++ b/arch/mips/jazz/jazz-platform.c
@@ -0,0 +1,60 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2007 Ralf Baechle (ralf@linux-mips.org)
7 */
8#include <linux/init.h>
9#include <linux/module.h>
10#include <linux/serial_8250.h>
11
12#include <asm/jazz.h>
13
14/*
15 * Confusion ... It seems the original Microsoft Jazz machine used to have a
16 * 4.096MHz clock for its UART while the MIPS Magnum and Millenium systems
17 * had 8MHz. The Olivetti M700-10 and the Acer PICA have 1.8432MHz like PCs.
18 */
19#ifdef CONFIG_OLIVETTI_M700
20#define JAZZ_BASE_BAUD 1843200
21#else
22#define JAZZ_BASE_BAUD 8000000 /* 3072000 */
23#endif
24
25#define JAZZ_UART_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP)
26
27#define JAZZ_PORT(base, int) \
28{ \
29 .mapbase = base, \
30 .irq = int, \
31 .uartclk = JAZZ_BASE_BAUD, \
32 .iotype = UPIO_MEM, \
33 .flags = JAZZ_UART_FLAGS, \
34 .regshift = 0, \
35}
36
37static struct plat_serial8250_port uart8250_data[] = {
38 JAZZ_PORT(JAZZ_SERIAL1_BASE, JAZZ_SERIAL1_IRQ),
39 JAZZ_PORT(JAZZ_SERIAL2_BASE, JAZZ_SERIAL2_IRQ),
40 { },
41};
42
43static struct platform_device uart8250_device = {
44 .name = "serial8250",
45 .id = PLAT8250_DEV_PLATFORM,
46 .dev = {
47 .platform_data = uart8250_data,
48 },
49};
50
51static int __init uart8250_init(void)
52{
53 return platform_device_register(&uart8250_device);
54}
55
56module_init(uart8250_init);
57
58MODULE_AUTHOR("Ralf Baechle <ralf@linux-mips.org>");
59MODULE_LICENSE("GPL");
60MODULE_DESCRIPTION("8250 UART probe driver for the Jazz family");
diff --git a/arch/mips/kernel/8250-platform.c b/arch/mips/kernel/8250-platform.c
new file mode 100644
index 000000000000..cbf3fe20ad17
--- /dev/null
+++ b/arch/mips/kernel/8250-platform.c
@@ -0,0 +1,47 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2007 Ralf Baechle (ralf@linux-mips.org)
7 */
8#include <linux/module.h>
9#include <linux/init.h>
10#include <linux/serial_8250.h>
11
12#define PORT(base, int) \
13{ \
14 .iobase = base, \
15 .irq = int, \
16 .uartclk = 1843200, \
17 .iotype = UPIO_PORT, \
18 .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, \
19 .regshift = 0, \
20}
21
22static struct plat_serial8250_port uart8250_data[] = {
23 PORT(0x3F8, 4),
24 PORT(0x2F8, 3),
25 PORT(0x3E8, 4),
26 PORT(0x2E8, 3),
27 { },
28};
29
30static struct platform_device uart8250_device = {
31 .name = "serial8250",
32 .id = PLAT8250_DEV_PLATFORM,
33 .dev = {
34 .platform_data = uart8250_data,
35 },
36};
37
38static int __init uart8250_init(void)
39{
40 return platform_device_register(&uart8250_device);
41}
42
43module_init(uart8250_init);
44
45MODULE_AUTHOR("Ralf Baechle <ralf@linux-mips.org>");
46MODULE_LICENSE("GPL");
47MODULE_DESCRIPTION("Generic 8250 UART probe driver");
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
index 49246264cc7c..961594cb5214 100644
--- a/arch/mips/kernel/Makefile
+++ b/arch/mips/kernel/Makefile
@@ -14,14 +14,15 @@ binfmt_irix-objs := irixelf.o irixinv.o irixioctl.o irixsig.o \
14obj-$(CONFIG_STACKTRACE) += stacktrace.o 14obj-$(CONFIG_STACKTRACE) += stacktrace.o
15obj-$(CONFIG_MODULES) += mips_ksyms.o module.o 15obj-$(CONFIG_MODULES) += mips_ksyms.o module.o
16 16
17obj-$(CONFIG_CPU_LOONGSON2) += r4k_fpu.o r4k_switch.o
18obj-$(CONFIG_CPU_MIPS32) += r4k_fpu.o r4k_switch.o
19obj-$(CONFIG_CPU_MIPS64) += r4k_fpu.o r4k_switch.o
17obj-$(CONFIG_CPU_R3000) += r2300_fpu.o r2300_switch.o 20obj-$(CONFIG_CPU_R3000) += r2300_fpu.o r2300_switch.o
18obj-$(CONFIG_CPU_TX39XX) += r2300_fpu.o r2300_switch.o
19obj-$(CONFIG_CPU_TX49XX) += r4k_fpu.o r4k_switch.o
20obj-$(CONFIG_CPU_R4000) += r4k_fpu.o r4k_switch.o 21obj-$(CONFIG_CPU_R4000) += r4k_fpu.o r4k_switch.o
21obj-$(CONFIG_CPU_VR41XX) += r4k_fpu.o r4k_switch.o
22obj-$(CONFIG_CPU_R4300) += r4k_fpu.o r4k_switch.o 22obj-$(CONFIG_CPU_R4300) += r4k_fpu.o r4k_switch.o
23obj-$(CONFIG_CPU_R4X00) += r4k_fpu.o r4k_switch.o 23obj-$(CONFIG_CPU_R4X00) += r4k_fpu.o r4k_switch.o
24obj-$(CONFIG_CPU_R5000) += r4k_fpu.o r4k_switch.o 24obj-$(CONFIG_CPU_R5000) += r4k_fpu.o r4k_switch.o
25obj-$(CONFIG_CPU_R6000) += r6000_fpu.o r4k_switch.o
25obj-$(CONFIG_CPU_R5432) += r4k_fpu.o r4k_switch.o 26obj-$(CONFIG_CPU_R5432) += r4k_fpu.o r4k_switch.o
26obj-$(CONFIG_CPU_R8000) += r4k_fpu.o r4k_switch.o 27obj-$(CONFIG_CPU_R8000) += r4k_fpu.o r4k_switch.o
27obj-$(CONFIG_CPU_RM7000) += r4k_fpu.o r4k_switch.o 28obj-$(CONFIG_CPU_RM7000) += r4k_fpu.o r4k_switch.o
@@ -29,13 +30,14 @@ obj-$(CONFIG_CPU_RM9000) += r4k_fpu.o r4k_switch.o
29obj-$(CONFIG_CPU_NEVADA) += r4k_fpu.o r4k_switch.o 30obj-$(CONFIG_CPU_NEVADA) += r4k_fpu.o r4k_switch.o
30obj-$(CONFIG_CPU_R10000) += r4k_fpu.o r4k_switch.o 31obj-$(CONFIG_CPU_R10000) += r4k_fpu.o r4k_switch.o
31obj-$(CONFIG_CPU_SB1) += r4k_fpu.o r4k_switch.o 32obj-$(CONFIG_CPU_SB1) += r4k_fpu.o r4k_switch.o
32obj-$(CONFIG_CPU_MIPS32) += r4k_fpu.o r4k_switch.o 33obj-$(CONFIG_CPU_TX39XX) += r2300_fpu.o r2300_switch.o
33obj-$(CONFIG_CPU_MIPS64) += r4k_fpu.o r4k_switch.o 34obj-$(CONFIG_CPU_TX49XX) += r4k_fpu.o r4k_switch.o
34obj-$(CONFIG_CPU_R6000) += r6000_fpu.o r4k_switch.o 35obj-$(CONFIG_CPU_VR41XX) += r4k_fpu.o r4k_switch.o
35 36
36obj-$(CONFIG_SMP) += smp.o 37obj-$(CONFIG_SMP) += smp.o
37 38
38obj-$(CONFIG_MIPS_MT) += mips-mt.o 39obj-$(CONFIG_MIPS_MT) += mips-mt.o
40obj-$(CONFIG_MIPS_MT_FPAFF) += mips-mt-fpaff.o
39obj-$(CONFIG_MIPS_MT_SMTC) += smtc.o smtc-asm.o smtc-proc.o 41obj-$(CONFIG_MIPS_MT_SMTC) += smtc.o smtc-asm.o smtc-proc.o
40obj-$(CONFIG_MIPS_MT_SMP) += smp-mt.o 42obj-$(CONFIG_MIPS_MT_SMP) += smp-mt.o
41 43
@@ -47,7 +49,6 @@ obj-$(CONFIG_I8259) += i8259.o
47obj-$(CONFIG_IRQ_CPU) += irq_cpu.o 49obj-$(CONFIG_IRQ_CPU) += irq_cpu.o
48obj-$(CONFIG_IRQ_CPU_RM7K) += irq-rm7000.o 50obj-$(CONFIG_IRQ_CPU_RM7K) += irq-rm7000.o
49obj-$(CONFIG_IRQ_CPU_RM9K) += irq-rm9000.o 51obj-$(CONFIG_IRQ_CPU_RM9K) += irq-rm9000.o
50obj-$(CONFIG_IRQ_MV64340) += irq-mv6434x.o
51obj-$(CONFIG_MIPS_BOARDS_GEN) += irq-msc01.o 52obj-$(CONFIG_MIPS_BOARDS_GEN) += irq-msc01.o
52 53
53obj-$(CONFIG_32BIT) += scall32-o32.o 54obj-$(CONFIG_32BIT) += scall32-o32.o
@@ -68,3 +69,5 @@ obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
68obj-$(CONFIG_EARLY_PRINTK) += early_printk.o 69obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
69 70
70CFLAGS_cpu-bugs64.o = $(shell if $(CC) $(CFLAGS) -Wa,-mdaddi -c -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-DHAVE_AS_SET_DADDI"; fi) 71CFLAGS_cpu-bugs64.o = $(shell if $(CC) $(CFLAGS) -Wa,-mdaddi -c -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-DHAVE_AS_SET_DADDI"; fi)
72
73obj-$(CONFIG_HAVE_STD_PC_SERIAL_PORT) += 8250-platform.o
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index b12eeee0e974..c6b8b074a81a 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -186,9 +186,29 @@ static inline void check_wait(void)
186 } 186 }
187} 187}
188 188
189static inline void check_errata(void)
190{
191 struct cpuinfo_mips *c = &current_cpu_data;
192
193 switch (c->cputype) {
194 case CPU_34K:
195 /*
196 * Erratum "RPS May Cause Incorrect Instruction Execution"
197 * This code only handles VPE0, any SMP/SMTC/RTOS code
198 * making use of VPE1 will be responsable for that VPE.
199 */
200 if ((c->processor_id & PRID_REV_MASK) <= PRID_REV_34K_V1_0_2)
201 write_c0_config7(read_c0_config7() | MIPS_CONF7_RPS);
202 break;
203 default:
204 break;
205 }
206}
207
189void __init check_bugs32(void) 208void __init check_bugs32(void)
190{ 209{
191 check_wait(); 210 check_wait();
211 check_errata();
192} 212}
193 213
194/* 214/*
@@ -485,6 +505,14 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c)
485 MIPS_CPU_LLSC; 505 MIPS_CPU_LLSC;
486 c->tlbsize = 64; 506 c->tlbsize = 64;
487 break; 507 break;
508 case PRID_IMP_LOONGSON2:
509 c->cputype = CPU_LOONGSON2;
510 c->isa_level = MIPS_CPU_ISA_III;
511 c->options = R4K_OPTS |
512 MIPS_CPU_FPU | MIPS_CPU_LLSC |
513 MIPS_CPU_32FPR;
514 c->tlbsize = 64;
515 break;
488 } 516 }
489} 517}
490 518
@@ -588,6 +616,8 @@ static inline unsigned int decode_config3(struct cpuinfo_mips *c)
588 c->options |= MIPS_CPU_VEIC; 616 c->options |= MIPS_CPU_VEIC;
589 if (config3 & MIPS_CONF3_MT) 617 if (config3 & MIPS_CONF3_MT)
590 c->ases |= MIPS_ASE_MIPSMT; 618 c->ases |= MIPS_ASE_MIPSMT;
619 if (config3 & MIPS_CONF3_ULRI)
620 c->options |= MIPS_CPU_ULRI;
591 621
592 return config3 & MIPS_CONF_M; 622 return config3 & MIPS_CONF_M;
593} 623}
diff --git a/arch/mips/kernel/head.S b/arch/mips/kernel/head.S
index 6f57ca44291f..f78538eceef7 100644
--- a/arch/mips/kernel/head.S
+++ b/arch/mips/kernel/head.S
@@ -16,6 +16,7 @@
16#include <linux/init.h> 16#include <linux/init.h>
17#include <linux/threads.h> 17#include <linux/threads.h>
18 18
19#include <asm/addrspace.h>
19#include <asm/asm.h> 20#include <asm/asm.h>
20#include <asm/asmmacro.h> 21#include <asm/asmmacro.h>
21#include <asm/irqflags.h> 22#include <asm/irqflags.h>
@@ -129,24 +130,25 @@
129#endif 130#endif
130 .endm 131 .endm
131 132
133#ifndef CONFIG_NO_EXCEPT_FILL
132 /* 134 /*
133 * Reserved space for exception handlers. 135 * Reserved space for exception handlers.
134 * Necessary for machines which link their kernels at KSEG0. 136 * Necessary for machines which link their kernels at KSEG0.
135 */ 137 */
136 .fill 0x400 138 .fill 0x400
139#endif
137 140
138EXPORT(stext) # used for profiling 141EXPORT(stext) # used for profiling
139EXPORT(_stext) 142EXPORT(_stext)
140 143
141#ifdef CONFIG_MIPS_SIM 144#ifdef CONFIG_BOOT_RAW
142 /* 145 /*
143 * Give us a fighting chance of running if execution beings at the 146 * Give us a fighting chance of running if execution beings at the
144 * kernel load address. This is needed because this platform does 147 * kernel load address. This is needed because this platform does
145 * not have a ELF loader yet. 148 * not have a ELF loader yet.
146 */ 149 */
147 j kernel_entry
148#endif
149 __INIT 150 __INIT
151#endif
150 152
151NESTED(kernel_entry, 16, sp) # kernel entry point 153NESTED(kernel_entry, 16, sp) # kernel entry point
152 154
@@ -197,9 +199,7 @@ NESTED(kernel_entry, 16, sp) # kernel entry point
197 j start_kernel 199 j start_kernel
198 END(kernel_entry) 200 END(kernel_entry)
199 201
200#ifdef CONFIG_QEMU
201 __INIT 202 __INIT
202#endif
203 203
204#ifdef CONFIG_SMP 204#ifdef CONFIG_SMP
205/* 205/*
diff --git a/arch/mips/kernel/irq-mv6434x.c b/arch/mips/kernel/irq-mv6434x.c
deleted file mode 100644
index 3dd561832e4c..000000000000
--- a/arch/mips/kernel/irq-mv6434x.c
+++ /dev/null
@@ -1,111 +0,0 @@
1/*
2 * Copyright 2002 Momentum Computer
3 * Author: mdharm@momenco.com
4 * Copyright (C) 2004, 06 Ralf Baechle <ralf@linux-mips.org>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 */
11#include <linux/module.h>
12#include <linux/interrupt.h>
13#include <linux/kernel.h>
14#include <linux/kernel_stat.h>
15#include <linux/mv643xx.h>
16#include <linux/sched.h>
17
18#include <asm/io.h>
19#include <asm/irq.h>
20#include <asm/marvell.h>
21
22static unsigned int irq_base;
23
24static inline int ls1bit32(unsigned int x)
25{
26 int b = 31, s;
27
28 s = 16; if (x << 16 == 0) s = 0; b -= s; x <<= s;
29 s = 8; if (x << 8 == 0) s = 0; b -= s; x <<= s;
30 s = 4; if (x << 4 == 0) s = 0; b -= s; x <<= s;
31 s = 2; if (x << 2 == 0) s = 0; b -= s; x <<= s;
32 s = 1; if (x << 1 == 0) s = 0; b -= s;
33
34 return b;
35}
36
37/* mask off an interrupt -- 1 is enable, 0 is disable */
38static inline void mask_mv64340_irq(unsigned int irq)
39{
40 uint32_t value;
41
42 if (irq < (irq_base + 32)) {
43 value = MV_READ(MV64340_INTERRUPT0_MASK_0_LOW);
44 value &= ~(1 << (irq - irq_base));
45 MV_WRITE(MV64340_INTERRUPT0_MASK_0_LOW, value);
46 } else {
47 value = MV_READ(MV64340_INTERRUPT0_MASK_0_HIGH);
48 value &= ~(1 << (irq - irq_base - 32));
49 MV_WRITE(MV64340_INTERRUPT0_MASK_0_HIGH, value);
50 }
51}
52
53/* unmask an interrupt -- 1 is enable, 0 is disable */
54static inline void unmask_mv64340_irq(unsigned int irq)
55{
56 uint32_t value;
57
58 if (irq < (irq_base + 32)) {
59 value = MV_READ(MV64340_INTERRUPT0_MASK_0_LOW);
60 value |= 1 << (irq - irq_base);
61 MV_WRITE(MV64340_INTERRUPT0_MASK_0_LOW, value);
62 } else {
63 value = MV_READ(MV64340_INTERRUPT0_MASK_0_HIGH);
64 value |= 1 << (irq - irq_base - 32);
65 MV_WRITE(MV64340_INTERRUPT0_MASK_0_HIGH, value);
66 }
67}
68
69/*
70 * Interrupt handler for interrupts coming from the Marvell chip.
71 * It could be built in ethernet ports etc...
72 */
73void ll_mv64340_irq(void)
74{
75 unsigned int irq_src_low, irq_src_high;
76 unsigned int irq_mask_low, irq_mask_high;
77
78 /* read the interrupt status registers */
79 irq_mask_low = MV_READ(MV64340_INTERRUPT0_MASK_0_LOW);
80 irq_mask_high = MV_READ(MV64340_INTERRUPT0_MASK_0_HIGH);
81 irq_src_low = MV_READ(MV64340_MAIN_INTERRUPT_CAUSE_LOW);
82 irq_src_high = MV_READ(MV64340_MAIN_INTERRUPT_CAUSE_HIGH);
83
84 /* mask for just the interrupts we want */
85 irq_src_low &= irq_mask_low;
86 irq_src_high &= irq_mask_high;
87
88 if (irq_src_low)
89 do_IRQ(ls1bit32(irq_src_low) + irq_base);
90 else
91 do_IRQ(ls1bit32(irq_src_high) + irq_base + 32);
92}
93
94struct irq_chip mv64340_irq_type = {
95 .name = "MV-64340",
96 .ack = mask_mv64340_irq,
97 .mask = mask_mv64340_irq,
98 .mask_ack = mask_mv64340_irq,
99 .unmask = unmask_mv64340_irq,
100};
101
102void __init mv64340_irq_init(unsigned int base)
103{
104 int i;
105
106 for (i = base; i < base + 64; i++)
107 set_irq_chip_and_handler(i, &mv64340_irq_type,
108 handle_level_irq);
109
110 irq_base = base;
111}
diff --git a/arch/mips/kernel/mips-mt-fpaff.c b/arch/mips/kernel/mips-mt-fpaff.c
new file mode 100644
index 000000000000..ede5d73d652e
--- /dev/null
+++ b/arch/mips/kernel/mips-mt-fpaff.c
@@ -0,0 +1,176 @@
1/*
2 * General MIPS MT support routines, usable in AP/SP, SMVP, or SMTC kernels
3 * Copyright (C) 2005 Mips Technologies, Inc
4 */
5#include <linux/cpu.h>
6#include <linux/cpumask.h>
7#include <linux/delay.h>
8#include <linux/kernel.h>
9#include <linux/init.h>
10#include <linux/sched.h>
11#include <linux/security.h>
12#include <linux/types.h>
13#include <asm/uaccess.h>
14
15/*
16 * CPU mask used to set process affinity for MT VPEs/TCs with FPUs
17 */
18cpumask_t mt_fpu_cpumask;
19
20static int fpaff_threshold = -1;
21unsigned long mt_fpemul_threshold = 0;
22
23/*
24 * Replacement functions for the sys_sched_setaffinity() and
25 * sys_sched_getaffinity() system calls, so that we can integrate
26 * FPU affinity with the user's requested processor affinity.
27 * This code is 98% identical with the sys_sched_setaffinity()
28 * and sys_sched_getaffinity() system calls, and should be
29 * updated when kernel/sched.c changes.
30 */
31
32/*
33 * find_process_by_pid - find a process with a matching PID value.
34 * used in sys_sched_set/getaffinity() in kernel/sched.c, so
35 * cloned here.
36 */
37static inline struct task_struct *find_process_by_pid(pid_t pid)
38{
39 return pid ? find_task_by_pid(pid) : current;
40}
41
42
43/*
44 * mipsmt_sys_sched_setaffinity - set the cpu affinity of a process
45 */
46asmlinkage long mipsmt_sys_sched_setaffinity(pid_t pid, unsigned int len,
47 unsigned long __user *user_mask_ptr)
48{
49 cpumask_t new_mask;
50 cpumask_t effective_mask;
51 int retval;
52 struct task_struct *p;
53
54 if (len < sizeof(new_mask))
55 return -EINVAL;
56
57 if (copy_from_user(&new_mask, user_mask_ptr, sizeof(new_mask)))
58 return -EFAULT;
59
60 lock_cpu_hotplug();
61 read_lock(&tasklist_lock);
62
63 p = find_process_by_pid(pid);
64 if (!p) {
65 read_unlock(&tasklist_lock);
66 unlock_cpu_hotplug();
67 return -ESRCH;
68 }
69
70 /*
71 * It is not safe to call set_cpus_allowed with the
72 * tasklist_lock held. We will bump the task_struct's
73 * usage count and drop tasklist_lock before invoking
74 * set_cpus_allowed.
75 */
76 get_task_struct(p);
77
78 retval = -EPERM;
79 if ((current->euid != p->euid) && (current->euid != p->uid) &&
80 !capable(CAP_SYS_NICE)) {
81 read_unlock(&tasklist_lock);
82 goto out_unlock;
83 }
84
85 retval = security_task_setscheduler(p, 0, NULL);
86 if (retval)
87 goto out_unlock;
88
89 /* Record new user-specified CPU set for future reference */
90 p->thread.user_cpus_allowed = new_mask;
91
92 /* Unlock the task list */
93 read_unlock(&tasklist_lock);
94
95 /* Compute new global allowed CPU set if necessary */
96 if ((p->thread.mflags & MF_FPUBOUND)
97 && cpus_intersects(new_mask, mt_fpu_cpumask)) {
98 cpus_and(effective_mask, new_mask, mt_fpu_cpumask);
99 retval = set_cpus_allowed(p, effective_mask);
100 } else {
101 p->thread.mflags &= ~MF_FPUBOUND;
102 retval = set_cpus_allowed(p, new_mask);
103 }
104
105
106out_unlock:
107 put_task_struct(p);
108 unlock_cpu_hotplug();
109 return retval;
110}
111
112/*
113 * mipsmt_sys_sched_getaffinity - get the cpu affinity of a process
114 */
115asmlinkage long mipsmt_sys_sched_getaffinity(pid_t pid, unsigned int len,
116 unsigned long __user *user_mask_ptr)
117{
118 unsigned int real_len;
119 cpumask_t mask;
120 int retval;
121 struct task_struct *p;
122
123 real_len = sizeof(mask);
124 if (len < real_len)
125 return -EINVAL;
126
127 lock_cpu_hotplug();
128 read_lock(&tasklist_lock);
129
130 retval = -ESRCH;
131 p = find_process_by_pid(pid);
132 if (!p)
133 goto out_unlock;
134 retval = security_task_getscheduler(p);
135 if (retval)
136 goto out_unlock;
137
138 cpus_and(mask, p->thread.user_cpus_allowed, cpu_possible_map);
139
140out_unlock:
141 read_unlock(&tasklist_lock);
142 unlock_cpu_hotplug();
143 if (retval)
144 return retval;
145 if (copy_to_user(user_mask_ptr, &mask, real_len))
146 return -EFAULT;
147 return real_len;
148}
149
150
151static int __init fpaff_thresh(char *str)
152{
153 get_option(&str, &fpaff_threshold);
154 return 1;
155}
156__setup("fpaff=", fpaff_thresh);
157
158/*
159 * FPU Use Factor empirically derived from experiments on 34K
160 */
161#define FPUSEFACTOR 333
162
163static __init int mt_fp_affinity_init(void)
164{
165 if (fpaff_threshold >= 0) {
166 mt_fpemul_threshold = fpaff_threshold;
167 } else {
168 mt_fpemul_threshold =
169 (FPUSEFACTOR * (loops_per_jiffy/(500000/HZ))) / HZ;
170 }
171 printk(KERN_DEBUG "FPU Affinity set after %ld emulations\n",
172 mt_fpemul_threshold);
173
174 return 0;
175}
176arch_initcall(mt_fp_affinity_init);
diff --git a/arch/mips/kernel/mips-mt.c b/arch/mips/kernel/mips-mt.c
index ba01800b6018..1a7d89231299 100644
--- a/arch/mips/kernel/mips-mt.c
+++ b/arch/mips/kernel/mips-mt.c
@@ -6,7 +6,6 @@
6#include <linux/device.h> 6#include <linux/device.h>
7#include <linux/kernel.h> 7#include <linux/kernel.h>
8#include <linux/sched.h> 8#include <linux/sched.h>
9#include <linux/cpumask.h>
10#include <linux/module.h> 9#include <linux/module.h>
11#include <linux/interrupt.h> 10#include <linux/interrupt.h>
12#include <linux/security.h> 11#include <linux/security.h>
@@ -23,149 +22,6 @@
23#include <asm/cacheflush.h> 22#include <asm/cacheflush.h>
24 23
25/* 24/*
26 * CPU mask used to set process affinity for MT VPEs/TCs with FPUs
27 */
28
29cpumask_t mt_fpu_cpumask;
30
31#ifdef CONFIG_MIPS_MT_FPAFF
32
33#include <linux/cpu.h>
34#include <linux/delay.h>
35#include <asm/uaccess.h>
36
37unsigned long mt_fpemul_threshold = 0;
38
39/*
40 * Replacement functions for the sys_sched_setaffinity() and
41 * sys_sched_getaffinity() system calls, so that we can integrate
42 * FPU affinity with the user's requested processor affinity.
43 * This code is 98% identical with the sys_sched_setaffinity()
44 * and sys_sched_getaffinity() system calls, and should be
45 * updated when kernel/sched.c changes.
46 */
47
48/*
49 * find_process_by_pid - find a process with a matching PID value.
50 * used in sys_sched_set/getaffinity() in kernel/sched.c, so
51 * cloned here.
52 */
53static inline struct task_struct *find_process_by_pid(pid_t pid)
54{
55 return pid ? find_task_by_pid(pid) : current;
56}
57
58
59/*
60 * mipsmt_sys_sched_setaffinity - set the cpu affinity of a process
61 */
62asmlinkage long mipsmt_sys_sched_setaffinity(pid_t pid, unsigned int len,
63 unsigned long __user *user_mask_ptr)
64{
65 cpumask_t new_mask;
66 cpumask_t effective_mask;
67 int retval;
68 struct task_struct *p;
69
70 if (len < sizeof(new_mask))
71 return -EINVAL;
72
73 if (copy_from_user(&new_mask, user_mask_ptr, sizeof(new_mask)))
74 return -EFAULT;
75
76 lock_cpu_hotplug();
77 read_lock(&tasklist_lock);
78
79 p = find_process_by_pid(pid);
80 if (!p) {
81 read_unlock(&tasklist_lock);
82 unlock_cpu_hotplug();
83 return -ESRCH;
84 }
85
86 /*
87 * It is not safe to call set_cpus_allowed with the
88 * tasklist_lock held. We will bump the task_struct's
89 * usage count and drop tasklist_lock before invoking
90 * set_cpus_allowed.
91 */
92 get_task_struct(p);
93
94 retval = -EPERM;
95 if ((current->euid != p->euid) && (current->euid != p->uid) &&
96 !capable(CAP_SYS_NICE)) {
97 read_unlock(&tasklist_lock);
98 goto out_unlock;
99 }
100
101 retval = security_task_setscheduler(p, 0, NULL);
102 if (retval)
103 goto out_unlock;
104
105 /* Record new user-specified CPU set for future reference */
106 p->thread.user_cpus_allowed = new_mask;
107
108 /* Unlock the task list */
109 read_unlock(&tasklist_lock);
110
111 /* Compute new global allowed CPU set if necessary */
112 if( (p->thread.mflags & MF_FPUBOUND)
113 && cpus_intersects(new_mask, mt_fpu_cpumask)) {
114 cpus_and(effective_mask, new_mask, mt_fpu_cpumask);
115 retval = set_cpus_allowed(p, effective_mask);
116 } else {
117 p->thread.mflags &= ~MF_FPUBOUND;
118 retval = set_cpus_allowed(p, new_mask);
119 }
120
121
122out_unlock:
123 put_task_struct(p);
124 unlock_cpu_hotplug();
125 return retval;
126}
127
128/*
129 * mipsmt_sys_sched_getaffinity - get the cpu affinity of a process
130 */
131asmlinkage long mipsmt_sys_sched_getaffinity(pid_t pid, unsigned int len,
132 unsigned long __user *user_mask_ptr)
133{
134 unsigned int real_len;
135 cpumask_t mask;
136 int retval;
137 struct task_struct *p;
138
139 real_len = sizeof(mask);
140 if (len < real_len)
141 return -EINVAL;
142
143 lock_cpu_hotplug();
144 read_lock(&tasklist_lock);
145
146 retval = -ESRCH;
147 p = find_process_by_pid(pid);
148 if (!p)
149 goto out_unlock;
150 retval = security_task_getscheduler(p);
151 if (retval)
152 goto out_unlock;
153
154 cpus_and(mask, p->thread.user_cpus_allowed, cpu_possible_map);
155
156out_unlock:
157 read_unlock(&tasklist_lock);
158 unlock_cpu_hotplug();
159 if (retval)
160 return retval;
161 if (copy_to_user(user_mask_ptr, &mask, real_len))
162 return -EFAULT;
163 return real_len;
164}
165
166#endif /* CONFIG_MIPS_MT_FPAFF */
167
168/*
169 * Dump new MIPS MT state for the core. Does not leave TCs halted. 25 * Dump new MIPS MT state for the core. Does not leave TCs halted.
170 * Takes an argument which taken to be a pre-call MVPControl value. 26 * Takes an argument which taken to be a pre-call MVPControl value.
171 */ 27 */
@@ -195,27 +51,31 @@ void mips_mt_regdump(unsigned long mvpctl)
195 nvpe = ((mvpconf0 & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT) + 1; 51 nvpe = ((mvpconf0 & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT) + 1;
196 ntc = ((mvpconf0 & MVPCONF0_PTC) >> MVPCONF0_PTC_SHIFT) + 1; 52 ntc = ((mvpconf0 & MVPCONF0_PTC) >> MVPCONF0_PTC_SHIFT) + 1;
197 printk("-- per-VPE State --\n"); 53 printk("-- per-VPE State --\n");
198 for(i = 0; i < nvpe; i++) { 54 for (i = 0; i < nvpe; i++) {
199 for(tc = 0; tc < ntc; tc++) { 55 for (tc = 0; tc < ntc; tc++) {
200 settc(tc); 56 settc(tc);
201 if((read_tc_c0_tcbind() & TCBIND_CURVPE) == i) { 57 if ((read_tc_c0_tcbind() & TCBIND_CURVPE) == i) {
202 printk(" VPE %d\n", i); 58 printk(" VPE %d\n", i);
203 printk(" VPEControl : %08lx\n", read_vpe_c0_vpecontrol()); 59 printk(" VPEControl : %08lx\n",
204 printk(" VPEConf0 : %08lx\n", read_vpe_c0_vpeconf0()); 60 read_vpe_c0_vpecontrol());
205 printk(" VPE%d.Status : %08lx\n", 61 printk(" VPEConf0 : %08lx\n",
206 i, read_vpe_c0_status()); 62 read_vpe_c0_vpeconf0());
207 printk(" VPE%d.EPC : %08lx\n", i, read_vpe_c0_epc()); 63 printk(" VPE%d.Status : %08lx\n",
208 printk(" VPE%d.Cause : %08lx\n", i, read_vpe_c0_cause()); 64 i, read_vpe_c0_status());
209 printk(" VPE%d.Config7 : %08lx\n", 65 printk(" VPE%d.EPC : %08lx\n",
210 i, read_vpe_c0_config7()); 66 i, read_vpe_c0_epc());
211 break; /* Next VPE */ 67 printk(" VPE%d.Cause : %08lx\n",
68 i, read_vpe_c0_cause());
69 printk(" VPE%d.Config7 : %08lx\n",
70 i, read_vpe_c0_config7());
71 break; /* Next VPE */
72 }
212 } 73 }
213 }
214 } 74 }
215 printk("-- per-TC State --\n"); 75 printk("-- per-TC State --\n");
216 for(tc = 0; tc < ntc; tc++) { 76 for (tc = 0; tc < ntc; tc++) {
217 settc(tc); 77 settc(tc);
218 if(read_tc_c0_tcbind() == read_c0_tcbind()) { 78 if (read_tc_c0_tcbind() == read_c0_tcbind()) {
219 /* Are we dumping ourself? */ 79 /* Are we dumping ourself? */
220 haltval = 0; /* Then we're not halted, and mustn't be */ 80 haltval = 0; /* Then we're not halted, and mustn't be */
221 tcstatval = flags; /* And pre-dump TCStatus is flags */ 81 tcstatval = flags; /* And pre-dump TCStatus is flags */
@@ -310,17 +170,6 @@ static int __init ndflush(char *s)
310 return 1; 170 return 1;
311} 171}
312__setup("ndflush=", ndflush); 172__setup("ndflush=", ndflush);
313#ifdef CONFIG_MIPS_MT_FPAFF
314static int fpaff_threshold = -1;
315
316static int __init fpaff_thresh(char *str)
317{
318 get_option(&str, &fpaff_threshold);
319 return 1;
320}
321
322__setup("fpaff=", fpaff_thresh);
323#endif /* CONFIG_MIPS_MT_FPAFF */
324 173
325static unsigned int itc_base = 0; 174static unsigned int itc_base = 0;
326 175
@@ -376,20 +225,6 @@ void mips_mt_set_cpuoptions(void)
376 if (mt_n_dflushes != 1) 225 if (mt_n_dflushes != 1)
377 printk("D-Cache Flushes Repeated %d times\n", mt_n_dflushes); 226 printk("D-Cache Flushes Repeated %d times\n", mt_n_dflushes);
378 227
379#ifdef CONFIG_MIPS_MT_FPAFF
380 /* FPU Use Factor empirically derived from experiments on 34K */
381#define FPUSEFACTOR 333
382
383 if (fpaff_threshold >= 0) {
384 mt_fpemul_threshold = fpaff_threshold;
385 } else {
386 mt_fpemul_threshold =
387 (FPUSEFACTOR * (loops_per_jiffy/(500000/HZ))) / HZ;
388 }
389 printk("FPU Affinity set after %ld emulations\n",
390 mt_fpemul_threshold);
391#endif /* CONFIG_MIPS_MT_FPAFF */
392
393 if (itc_base != 0) { 228 if (itc_base != 0) {
394 /* 229 /*
395 * Configure ITC mapping. This code is very 230 * Configure ITC mapping. This code is very
diff --git a/arch/mips/kernel/proc.c b/arch/mips/kernel/proc.c
index 5ddc2e9deecf..ec04f5a1a5ea 100644
--- a/arch/mips/kernel/proc.c
+++ b/arch/mips/kernel/proc.c
@@ -14,7 +14,6 @@
14#include <asm/cpu-features.h> 14#include <asm/cpu-features.h>
15#include <asm/mipsregs.h> 15#include <asm/mipsregs.h>
16#include <asm/processor.h> 16#include <asm/processor.h>
17#include <asm/watch.h>
18 17
19unsigned int vced_count, vcei_count; 18unsigned int vced_count, vcei_count;
20 19
@@ -84,6 +83,7 @@ static const char *cpu_name[] = {
84 [CPU_VR4181A] = "NEC VR4181A", 83 [CPU_VR4181A] = "NEC VR4181A",
85 [CPU_SR71000] = "Sandcraft SR71000", 84 [CPU_SR71000] = "Sandcraft SR71000",
86 [CPU_PR4450] = "Philips PR4450", 85 [CPU_PR4450] = "Philips PR4450",
86 [CPU_LOONGSON2] = "ICT Loongson-2",
87}; 87};
88 88
89 89
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
index 6bdfb5a9fa1a..8f4cf27c7157 100644
--- a/arch/mips/kernel/process.c
+++ b/arch/mips/kernel/process.c
@@ -46,7 +46,7 @@
46 * power and have a low exit latency (ie sit in a loop waiting for somebody to 46 * power and have a low exit latency (ie sit in a loop waiting for somebody to
47 * say that they'd like to reschedule) 47 * say that they'd like to reschedule)
48 */ 48 */
49ATTRIB_NORET void cpu_idle(void) 49void __noreturn cpu_idle(void)
50{ 50{
51 /* endless idle loop with no priority at all */ 51 /* endless idle loop with no priority at all */
52 while (1) { 52 while (1) {
@@ -213,7 +213,7 @@ int dump_task_fpu (struct task_struct *t, elf_fpregset_t *fpr)
213/* 213/*
214 * Create a kernel thread 214 * Create a kernel thread
215 */ 215 */
216static ATTRIB_NORET void kernel_thread_helper(void *arg, int (*fn)(void *)) 216static void __noreturn kernel_thread_helper(void *arg, int (*fn)(void *))
217{ 217{
218 do_exit(fn(arg)); 218 do_exit(fn(arg));
219} 219}
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index 4975da0bfb63..316685fca059 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -20,6 +20,7 @@
20#include <linux/highmem.h> 20#include <linux/highmem.h>
21#include <linux/console.h> 21#include <linux/console.h>
22#include <linux/pfn.h> 22#include <linux/pfn.h>
23#include <linux/debugfs.h>
23 24
24#include <asm/addrspace.h> 25#include <asm/addrspace.h>
25#include <asm/bootinfo.h> 26#include <asm/bootinfo.h>
@@ -574,3 +575,18 @@ __setup("nodsp", dsp_disable);
574 575
575unsigned long kernelsp[NR_CPUS]; 576unsigned long kernelsp[NR_CPUS];
576unsigned long fw_arg0, fw_arg1, fw_arg2, fw_arg3; 577unsigned long fw_arg0, fw_arg1, fw_arg2, fw_arg3;
578
579#ifdef CONFIG_DEBUG_FS
580struct dentry *mips_debugfs_dir;
581static int __init debugfs_mips(void)
582{
583 struct dentry *d;
584
585 d = debugfs_create_dir("mips", NULL);
586 if (IS_ERR(d))
587 return PTR_ERR(d);
588 mips_debugfs_dir = d;
589 return 0;
590}
591arch_initcall(debugfs_mips);
592#endif
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c
index 67edfa7ed93a..be7362bc2c9a 100644
--- a/arch/mips/kernel/smp.c
+++ b/arch/mips/kernel/smp.c
@@ -51,18 +51,8 @@ int __cpu_logical_map[NR_CPUS]; /* Map logical to physical */
51EXPORT_SYMBOL(phys_cpu_present_map); 51EXPORT_SYMBOL(phys_cpu_present_map);
52EXPORT_SYMBOL(cpu_online_map); 52EXPORT_SYMBOL(cpu_online_map);
53 53
54/* This happens early in bootup, can't really do it better */
55static void smp_tune_scheduling (void)
56{
57 struct cache_desc *cd = &current_cpu_data.scache;
58 unsigned long cachesize = cd->linesz * cd->sets * cd->ways;
59
60 if (cachesize > max_cache_size)
61 max_cache_size = cachesize;
62}
63
64extern void __init calibrate_delay(void); 54extern void __init calibrate_delay(void);
65extern ATTRIB_NORET void cpu_idle(void); 55extern void cpu_idle(void);
66 56
67/* 57/*
68 * First C code run on the secondary CPUs after being started up by 58 * First C code run on the secondary CPUs after being started up by
@@ -228,7 +218,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
228{ 218{
229 init_new_context(current, &init_mm); 219 init_new_context(current, &init_mm);
230 current_thread_info()->cpu = 0; 220 current_thread_info()->cpu = 0;
231 smp_tune_scheduling();
232 plat_prepare_cpus(max_cpus); 221 plat_prepare_cpus(max_cpus);
233#ifndef CONFIG_HOTPLUG_CPU 222#ifndef CONFIG_HOTPLUG_CPU
234 cpu_present_map = cpu_possible_map; 223 cpu_present_map = cpu_possible_map;
diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c
index 046b03b1705a..342d873b2ecc 100644
--- a/arch/mips/kernel/smtc.c
+++ b/arch/mips/kernel/smtc.c
@@ -1104,7 +1104,7 @@ void smtc_idle_loop_hook(void)
1104 mtflags = dmt(); 1104 mtflags = dmt();
1105 pdb_msg = &id_ho_db_msg[0]; 1105 pdb_msg = &id_ho_db_msg[0];
1106 im = read_c0_status(); 1106 im = read_c0_status();
1107 vpe = cpu_data[smp_processor_id()].vpe_id; 1107 vpe = current_cpu_data.vpe_id;
1108 for (bit = 0; bit < 8; bit++) { 1108 for (bit = 0; bit < 8; bit++) {
1109 /* 1109 /*
1110 * In current prototype, I/O interrupts 1110 * In current prototype, I/O interrupts
diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c
index 9dd5a2df8eac..b947c61c0cc8 100644
--- a/arch/mips/kernel/syscall.c
+++ b/arch/mips/kernel/syscall.c
@@ -272,9 +272,8 @@ asmlinkage int sys_set_thread_area(unsigned long addr)
272 struct thread_info *ti = task_thread_info(current); 272 struct thread_info *ti = task_thread_info(current);
273 273
274 ti->tp_value = addr; 274 ti->tp_value = addr;
275 275 if (cpu_has_userlocal)
276 /* If some future MIPS implementation has this register in hardware, 276 write_c0_userlocal(addr);
277 * we will need to update it here (and in context switches). */
278 277
279 return 0; 278 return 0;
280} 279}
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 3ea7863c4519..80ea4fa95bd9 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -39,7 +39,6 @@
39#include <asm/traps.h> 39#include <asm/traps.h>
40#include <asm/uaccess.h> 40#include <asm/uaccess.h>
41#include <asm/mmu_context.h> 41#include <asm/mmu_context.h>
42#include <asm/watch.h>
43#include <asm/types.h> 42#include <asm/types.h>
44#include <asm/stacktrace.h> 43#include <asm/stacktrace.h>
45 44
@@ -70,6 +69,7 @@ extern asmlinkage void handle_reserved(void);
70extern int fpu_emulator_cop1Handler(struct pt_regs *xcp, 69extern int fpu_emulator_cop1Handler(struct pt_regs *xcp,
71 struct mips_fpu_struct *ctx, int has_fpu); 70 struct mips_fpu_struct *ctx, int has_fpu);
72 71
72void (*board_watchpoint_handler)(struct pt_regs *regs);
73void (*board_be_init)(void); 73void (*board_be_init)(void);
74int (*board_be_handler)(struct pt_regs *regs, int is_fixup); 74int (*board_be_handler)(struct pt_regs *regs, int is_fixup);
75void (*board_nmi_handler_setup)(void); 75void (*board_nmi_handler_setup)(void);
@@ -311,7 +311,7 @@ void show_registers(struct pt_regs *regs)
311 311
312static DEFINE_SPINLOCK(die_lock); 312static DEFINE_SPINLOCK(die_lock);
313 313
314NORET_TYPE void ATTRIB_NORET die(const char * str, struct pt_regs * regs) 314void __noreturn die(const char * str, struct pt_regs * regs)
315{ 315{
316 static int die_counter; 316 static int die_counter;
317#ifdef CONFIG_MIPS_MT_SMTC 317#ifdef CONFIG_MIPS_MT_SMTC
@@ -753,6 +753,33 @@ asmlinkage void do_ri(struct pt_regs *regs)
753 force_sig(SIGILL, current); 753 force_sig(SIGILL, current);
754} 754}
755 755
756/*
757 * MIPS MT processors may have fewer FPU contexts than CPU threads. If we've
758 * emulated more than some threshold number of instructions, force migration to
759 * a "CPU" that has FP support.
760 */
761static void mt_ase_fp_affinity(void)
762{
763#ifdef CONFIG_MIPS_MT_FPAFF
764 if (mt_fpemul_threshold > 0 &&
765 ((current->thread.emulated_fp++ > mt_fpemul_threshold))) {
766 /*
767 * If there's no FPU present, or if the application has already
768 * restricted the allowed set to exclude any CPUs with FPUs,
769 * we'll skip the procedure.
770 */
771 if (cpus_intersects(current->cpus_allowed, mt_fpu_cpumask)) {
772 cpumask_t tmask;
773
774 cpus_and(tmask, current->thread.user_cpus_allowed,
775 mt_fpu_cpumask);
776 set_cpus_allowed(current, tmask);
777 current->thread.mflags |= MF_FPUBOUND;
778 }
779 }
780#endif /* CONFIG_MIPS_MT_FPAFF */
781}
782
756asmlinkage void do_cpu(struct pt_regs *regs) 783asmlinkage void do_cpu(struct pt_regs *regs)
757{ 784{
758 unsigned int cpid; 785 unsigned int cpid;
@@ -786,36 +813,8 @@ asmlinkage void do_cpu(struct pt_regs *regs)
786 &current->thread.fpu, 0); 813 &current->thread.fpu, 0);
787 if (sig) 814 if (sig)
788 force_sig(sig, current); 815 force_sig(sig, current);
789#ifdef CONFIG_MIPS_MT_FPAFF 816 else
790 else { 817 mt_ase_fp_affinity();
791 /*
792 * MIPS MT processors may have fewer FPU contexts
793 * than CPU threads. If we've emulated more than
794 * some threshold number of instructions, force
795 * migration to a "CPU" that has FP support.
796 */
797 if(mt_fpemul_threshold > 0
798 && ((current->thread.emulated_fp++
799 > mt_fpemul_threshold))) {
800 /*
801 * If there's no FPU present, or if the
802 * application has already restricted
803 * the allowed set to exclude any CPUs
804 * with FPUs, we'll skip the procedure.
805 */
806 if (cpus_intersects(current->cpus_allowed,
807 mt_fpu_cpumask)) {
808 cpumask_t tmask;
809
810 cpus_and(tmask,
811 current->thread.user_cpus_allowed,
812 mt_fpu_cpumask);
813 set_cpus_allowed(current, tmask);
814 current->thread.mflags |= MF_FPUBOUND;
815 }
816 }
817 }
818#endif /* CONFIG_MIPS_MT_FPAFF */
819 } 818 }
820 819
821 return; 820 return;
@@ -835,6 +834,11 @@ asmlinkage void do_mdmx(struct pt_regs *regs)
835 834
836asmlinkage void do_watch(struct pt_regs *regs) 835asmlinkage void do_watch(struct pt_regs *regs)
837{ 836{
837 if (board_watchpoint_handler) {
838 (*board_watchpoint_handler)(regs);
839 return;
840 }
841
838 /* 842 /*
839 * We use the watch exception where available to detect stack 843 * We use the watch exception where available to detect stack
840 * overflows. 844 * overflows.
@@ -1343,7 +1347,14 @@ void __init per_cpu_trap_init(void)
1343 set_c0_status(ST0_MX); 1347 set_c0_status(ST0_MX);
1344 1348
1345#ifdef CONFIG_CPU_MIPSR2 1349#ifdef CONFIG_CPU_MIPSR2
1346 write_c0_hwrena (0x0000000f); /* Allow rdhwr to all registers */ 1350 if (cpu_has_mips_r2) {
1351 unsigned int enable = 0x0000000f;
1352
1353 if (cpu_has_userlocal)
1354 enable |= (1 << 29);
1355
1356 write_c0_hwrena(enable);
1357 }
1347#endif 1358#endif
1348 1359
1349#ifdef CONFIG_MIPS_MT_SMTC 1360#ifdef CONFIG_MIPS_MT_SMTC
diff --git a/arch/mips/kernel/unaligned.c b/arch/mips/kernel/unaligned.c
index 18c4a3c45a31..8b9c34ffae18 100644
--- a/arch/mips/kernel/unaligned.c
+++ b/arch/mips/kernel/unaligned.c
@@ -77,6 +77,7 @@
77#include <linux/signal.h> 77#include <linux/signal.h>
78#include <linux/smp.h> 78#include <linux/smp.h>
79#include <linux/sched.h> 79#include <linux/sched.h>
80#include <linux/debugfs.h>
80#include <asm/asm.h> 81#include <asm/asm.h>
81#include <asm/branch.h> 82#include <asm/branch.h>
82#include <asm/byteorder.h> 83#include <asm/byteorder.h>
@@ -87,9 +88,18 @@
87#define STR(x) __STR(x) 88#define STR(x) __STR(x)
88#define __STR(x) #x 89#define __STR(x) #x
89 90
90#ifdef CONFIG_PROC_FS 91enum {
91unsigned long unaligned_instructions; 92 UNALIGNED_ACTION_QUIET,
93 UNALIGNED_ACTION_SIGNAL,
94 UNALIGNED_ACTION_SHOW,
95};
96#ifdef CONFIG_DEBUG_FS
97static u32 unaligned_instructions;
98static u32 unaligned_action;
99#else
100#define unaligned_action UNALIGNED_ACTION_QUIET
92#endif 101#endif
102extern void show_registers(struct pt_regs *regs);
93 103
94static inline int emulate_load_store_insn(struct pt_regs *regs, 104static inline int emulate_load_store_insn(struct pt_regs *regs,
95 void __user *addr, unsigned int __user *pc, 105 void __user *addr, unsigned int __user *pc,
@@ -459,7 +469,7 @@ static inline int emulate_load_store_insn(struct pt_regs *regs,
459 goto sigill; 469 goto sigill;
460 } 470 }
461 471
462#ifdef CONFIG_PROC_FS 472#ifdef CONFIG_DEBUG_FS
463 unaligned_instructions++; 473 unaligned_instructions++;
464#endif 474#endif
465 475
@@ -516,6 +526,10 @@ asmlinkage void do_ade(struct pt_regs *regs)
516 pc = (unsigned int __user *) exception_epc(regs); 526 pc = (unsigned int __user *) exception_epc(regs);
517 if (user_mode(regs) && (current->thread.mflags & MF_FIXADE) == 0) 527 if (user_mode(regs) && (current->thread.mflags & MF_FIXADE) == 0)
518 goto sigbus; 528 goto sigbus;
529 if (unaligned_action == UNALIGNED_ACTION_SIGNAL)
530 goto sigbus;
531 else if (unaligned_action == UNALIGNED_ACTION_SHOW)
532 show_registers(regs);
519 533
520 /* 534 /*
521 * Do branch emulation only if we didn't forward the exception. 535 * Do branch emulation only if we didn't forward the exception.
@@ -546,3 +560,24 @@ sigbus:
546 * XXX On return from the signal handler we should advance the epc 560 * XXX On return from the signal handler we should advance the epc
547 */ 561 */
548} 562}
563
564#ifdef CONFIG_DEBUG_FS
565extern struct dentry *mips_debugfs_dir;
566static int __init debugfs_unaligned(void)
567{
568 struct dentry *d;
569
570 if (!mips_debugfs_dir)
571 return -ENODEV;
572 d = debugfs_create_u32("unaligned_instructions", S_IRUGO,
573 mips_debugfs_dir, &unaligned_instructions);
574 if (IS_ERR(d))
575 return PTR_ERR(d);
576 d = debugfs_create_u32("unaligned_action", S_IRUGO | S_IWUSR,
577 mips_debugfs_dir, &unaligned_action);
578 if (IS_ERR(d))
579 return PTR_ERR(d);
580 return 0;
581}
582__initcall(debugfs_unaligned);
583#endif
diff --git a/arch/mips/lasat/Kconfig b/arch/mips/lasat/Kconfig
deleted file mode 100644
index 1d2ee8a9be13..000000000000
--- a/arch/mips/lasat/Kconfig
+++ /dev/null
@@ -1,15 +0,0 @@
1config PICVUE
2 tristate "PICVUE LCD display driver"
3 depends on LASAT
4
5config PICVUE_PROC
6 tristate "PICVUE LCD display driver /proc interface"
7 depends on PICVUE
8
9config DS1603
10 bool "DS1603 RTC driver"
11 depends on LASAT
12
13config LASAT_SYSCTL
14 bool "LASAT sysctl interface"
15 depends on LASAT
diff --git a/arch/mips/lasat/Makefile b/arch/mips/lasat/Makefile
deleted file mode 100644
index 99f5046fdf49..000000000000
--- a/arch/mips/lasat/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
1#
2# Makefile for the LASAT specific kernel interface routines under Linux.
3#
4
5obj-y += reset.o setup.o prom.o lasat_board.o \
6 at93c.o interrupt.o
7
8obj-$(CONFIG_LASAT_SYSCTL) += sysctl.o
9obj-$(CONFIG_DS1603) += ds1603.o
10obj-$(CONFIG_PICVUE) += picvue.o
11obj-$(CONFIG_PICVUE_PROC) += picvue_proc.o
12
13clean:
14 make -C image clean
diff --git a/arch/mips/lasat/at93c.c b/arch/mips/lasat/at93c.c
deleted file mode 100644
index ca26e554615e..000000000000
--- a/arch/mips/lasat/at93c.c
+++ /dev/null
@@ -1,148 +0,0 @@
1/*
2 * Atmel AT93C46 serial eeprom driver
3 *
4 * Brian Murphy <brian.murphy@eicon.com>
5 *
6 */
7#include <linux/kernel.h>
8#include <linux/delay.h>
9#include <asm/lasat/lasat.h>
10#include <linux/module.h>
11#include <linux/init.h>
12
13#include "at93c.h"
14
15#define AT93C_ADDR_SHIFT 7
16#define AT93C_ADDR_MAX ((1 << AT93C_ADDR_SHIFT) - 1)
17#define AT93C_RCMD (0x6 << AT93C_ADDR_SHIFT)
18#define AT93C_WCMD (0x5 << AT93C_ADDR_SHIFT)
19#define AT93C_WENCMD 0x260
20#define AT93C_WDSCMD 0x200
21
22struct at93c_defs *at93c;
23
24static void at93c_reg_write(u32 val)
25{
26 *at93c->reg = val;
27}
28
29static u32 at93c_reg_read(void)
30{
31 u32 tmp = *at93c->reg;
32 return tmp;
33}
34
35static u32 at93c_datareg_read(void)
36{
37 u32 tmp = *at93c->rdata_reg;
38 return tmp;
39}
40
41static void at93c_cycle_clk(u32 data)
42{
43 at93c_reg_write(data | at93c->clk);
44 lasat_ndelay(250);
45 at93c_reg_write(data & ~at93c->clk);
46 lasat_ndelay(250);
47}
48
49static void at93c_write_databit(u8 bit)
50{
51 u32 data = at93c_reg_read();
52 if (bit)
53 data |= 1 << at93c->wdata_shift;
54 else
55 data &= ~(1 << at93c->wdata_shift);
56
57 at93c_reg_write(data);
58 lasat_ndelay(100);
59 at93c_cycle_clk(data);
60}
61
62static unsigned int at93c_read_databit(void)
63{
64 u32 data;
65
66 at93c_cycle_clk(at93c_reg_read());
67 data = (at93c_datareg_read() >> at93c->rdata_shift) & 1;
68 return data;
69}
70
71static u8 at93c_read_byte(void)
72{
73 int i;
74 u8 data = 0;
75
76 for (i = 0; i<=7; i++) {
77 data <<= 1;
78 data |= at93c_read_databit();
79 }
80 return data;
81}
82
83static void at93c_write_bits(u32 data, int size)
84{
85 int i;
86 int shift = size - 1;
87 u32 mask = (1 << shift);
88
89 for (i = 0; i < size; i++) {
90 at93c_write_databit((data & mask) >> shift);
91 data <<= 1;
92 }
93}
94
95static void at93c_init_op(void)
96{
97 at93c_reg_write((at93c_reg_read() | at93c->cs) & ~at93c->clk & ~(1 << at93c->rdata_shift));
98 lasat_ndelay(50);
99}
100
101static void at93c_end_op(void)
102{
103 at93c_reg_write(at93c_reg_read() & ~at93c->cs);
104 lasat_ndelay(250);
105}
106
107static void at93c_wait(void)
108{
109 at93c_init_op();
110 while (!at93c_read_databit())
111 ;
112 at93c_end_op();
113};
114
115static void at93c_disable_wp(void)
116{
117 at93c_init_op();
118 at93c_write_bits(AT93C_WENCMD, 10);
119 at93c_end_op();
120}
121
122static void at93c_enable_wp(void)
123{
124 at93c_init_op();
125 at93c_write_bits(AT93C_WDSCMD, 10);
126 at93c_end_op();
127}
128
129u8 at93c_read(u8 addr)
130{
131 u8 byte;
132 at93c_init_op();
133 at93c_write_bits((addr & AT93C_ADDR_MAX)|AT93C_RCMD, 10);
134 byte = at93c_read_byte();
135 at93c_end_op();
136 return byte;
137}
138
139void at93c_write(u8 addr, u8 data)
140{
141 at93c_disable_wp();
142 at93c_init_op();
143 at93c_write_bits((addr & AT93C_ADDR_MAX)|AT93C_WCMD, 10);
144 at93c_write_bits(data, 8);
145 at93c_end_op();
146 at93c_wait();
147 at93c_enable_wp();
148}
diff --git a/arch/mips/lasat/at93c.h b/arch/mips/lasat/at93c.h
deleted file mode 100644
index cfe2f99b1d44..000000000000
--- a/arch/mips/lasat/at93c.h
+++ /dev/null
@@ -1,18 +0,0 @@
1/*
2 * Atmel AT93C46 serial eeprom driver
3 *
4 * Brian Murphy <brian.murphy@eicon.com>
5 *
6 */
7
8extern struct at93c_defs {
9 volatile u32 *reg;
10 volatile u32 *rdata_reg;
11 int rdata_shift;
12 int wdata_shift;
13 u32 cs;
14 u32 clk;
15} *at93c;
16
17u8 at93c_read(u8 addr);
18void at93c_write(u8 addr, u8 data);
diff --git a/arch/mips/lasat/ds1603.c b/arch/mips/lasat/ds1603.c
deleted file mode 100644
index 7dced67c55eb..000000000000
--- a/arch/mips/lasat/ds1603.c
+++ /dev/null
@@ -1,183 +0,0 @@
1/*
2 * Dallas Semiconductors 1603 RTC driver
3 *
4 * Brian Murphy <brian@murphy.dk>
5 *
6 */
7#include <linux/kernel.h>
8#include <asm/lasat/lasat.h>
9#include <linux/delay.h>
10#include <asm/lasat/ds1603.h>
11#include <asm/time.h>
12
13#include "ds1603.h"
14
15#define READ_TIME_CMD 0x81
16#define SET_TIME_CMD 0x80
17#define TRIMMER_SET_CMD 0xC0
18#define TRIMMER_VALUE_MASK 0x38
19#define TRIMMER_SHIFT 3
20
21struct ds_defs *ds1603 = NULL;
22
23/* HW specific register functions */
24static void rtc_reg_write(unsigned long val)
25{
26 *ds1603->reg = val;
27}
28
29static unsigned long rtc_reg_read(void)
30{
31 unsigned long tmp = *ds1603->reg;
32 return tmp;
33}
34
35static unsigned long rtc_datareg_read(void)
36{
37 unsigned long tmp = *ds1603->data_reg;
38 return tmp;
39}
40
41static void rtc_nrst_high(void)
42{
43 rtc_reg_write(rtc_reg_read() | ds1603->rst);
44}
45
46static void rtc_nrst_low(void)
47{
48 rtc_reg_write(rtc_reg_read() & ~ds1603->rst);
49}
50
51static void rtc_cycle_clock(unsigned long data)
52{
53 data |= ds1603->clk;
54 rtc_reg_write(data);
55 lasat_ndelay(250);
56 if (ds1603->data_reversed)
57 data &= ~ds1603->data;
58 else
59 data |= ds1603->data;
60 data &= ~ds1603->clk;
61 rtc_reg_write(data);
62 lasat_ndelay(250 + ds1603->huge_delay);
63}
64
65static void rtc_write_databit(unsigned int bit)
66{
67 unsigned long data = rtc_reg_read();
68 if (ds1603->data_reversed)
69 bit = !bit;
70 if (bit)
71 data |= ds1603->data;
72 else
73 data &= ~ds1603->data;
74
75 rtc_reg_write(data);
76 lasat_ndelay(50 + ds1603->huge_delay);
77 rtc_cycle_clock(data);
78}
79
80static unsigned int rtc_read_databit(void)
81{
82 unsigned int data;
83
84 data = (rtc_datareg_read() & (1 << ds1603->data_read_shift))
85 >> ds1603->data_read_shift;
86 rtc_cycle_clock(rtc_reg_read());
87 return data;
88}
89
90static void rtc_write_byte(unsigned int byte)
91{
92 int i;
93
94 for (i = 0; i<=7; i++) {
95 rtc_write_databit(byte & 1L);
96 byte >>= 1;
97 }
98}
99
100static void rtc_write_word(unsigned long word)
101{
102 int i;
103
104 for (i = 0; i<=31; i++) {
105 rtc_write_databit(word & 1L);
106 word >>= 1;
107 }
108}
109
110static unsigned long rtc_read_word(void)
111{
112 int i;
113 unsigned long word = 0;
114 unsigned long shift = 0;
115
116 for (i = 0; i<=31; i++) {
117 word |= rtc_read_databit() << shift;
118 shift++;
119 }
120 return word;
121}
122
123static void rtc_init_op(void)
124{
125 rtc_nrst_high();
126
127 rtc_reg_write(rtc_reg_read() & ~ds1603->clk);
128
129 lasat_ndelay(50);
130}
131
132static void rtc_end_op(void)
133{
134 rtc_nrst_low();
135 lasat_ndelay(1000);
136}
137
138/* interface */
139unsigned long ds1603_read(void)
140{
141 unsigned long word;
142 unsigned long flags;
143
144 spin_lock_irqsave(&rtc_lock, flags);
145 rtc_init_op();
146 rtc_write_byte(READ_TIME_CMD);
147 word = rtc_read_word();
148 rtc_end_op();
149 spin_unlock_irqrestore(&rtc_lock, flags);
150 return word;
151}
152
153int ds1603_set(unsigned long time)
154{
155 unsigned long flags;
156
157 spin_lock_irqsave(&rtc_lock, flags);
158 rtc_init_op();
159 rtc_write_byte(SET_TIME_CMD);
160 rtc_write_word(time);
161 rtc_end_op();
162 spin_unlock_irqrestore(&rtc_lock, flags);
163
164 return 0;
165}
166
167void ds1603_set_trimmer(unsigned int trimval)
168{
169 rtc_init_op();
170 rtc_write_byte(((trimval << TRIMMER_SHIFT) & TRIMMER_VALUE_MASK)
171 | (TRIMMER_SET_CMD));
172 rtc_end_op();
173}
174
175void ds1603_disable(void)
176{
177 ds1603_set_trimmer(TRIMMER_DISABLE_RTC);
178}
179
180void ds1603_enable(void)
181{
182 ds1603_set_trimmer(TRIMMER_DEFAULT);
183}
diff --git a/arch/mips/lasat/ds1603.h b/arch/mips/lasat/ds1603.h
deleted file mode 100644
index c2e5c76a379d..000000000000
--- a/arch/mips/lasat/ds1603.h
+++ /dev/null
@@ -1,33 +0,0 @@
1/*
2 * Dallas Semiconductors 1603 RTC driver
3 *
4 * Brian Murphy <brian@murphy.dk>
5 *
6 */
7#ifndef __DS1603_H
8#define __DS1603_H
9
10struct ds_defs {
11 volatile u32 *reg;
12 volatile u32 *data_reg;
13 u32 rst;
14 u32 clk;
15 u32 data;
16 u32 data_read_shift;
17 char data_reversed;
18 u32 huge_delay;
19};
20
21extern struct ds_defs *ds1603;
22
23unsigned long ds1603_read(void);
24int ds1603_set(unsigned long);
25void ds1603_set_trimmer(unsigned int);
26void ds1603_enable(void);
27void ds1603_disable(void);
28void ds1603_init(struct ds_defs *);
29
30#define TRIMMER_DEFAULT 3
31#define TRIMMER_DISABLE_RTC 0
32
33#endif
diff --git a/arch/mips/lasat/image/Makefile b/arch/mips/lasat/image/Makefile
deleted file mode 100644
index 35ecd6483ef6..000000000000
--- a/arch/mips/lasat/image/Makefile
+++ /dev/null
@@ -1,53 +0,0 @@
1#
2# MAKEFILE FOR THE MIPS LINUX BOOTLOADER AND ROM DEBUGGER
3#
4# i-data Networks
5#
6# Author: Thomas Horsten <thh@i-data.com>
7#
8
9ifndef Version
10 Version = "$(USER)-test"
11endif
12
13MKLASATIMG = mklasatimg
14MKLASATIMG_ARCH = mq2,mqpro,sp100,sp200
15KERNEL_IMAGE = $(TOPDIR)/vmlinux
16KERNEL_START = $(shell $(NM) $(KERNEL_IMAGE) | grep " _text" | cut -f1 -d\ )
17KERNEL_ENTRY = $(shell $(NM) $(KERNEL_IMAGE) | grep kernel_entry | cut -f1 -d\ )
18
19LDSCRIPT= -L$(obj) -Tromscript.normal
20
21HEAD_DEFINES := -D_kernel_start=0x$(KERNEL_START) \
22 -D_kernel_entry=0x$(KERNEL_ENTRY) \
23 -D VERSION="\"$(Version)\"" \
24 -D TIMESTAMP=$(shell date +%s)
25
26$(obj)/head.o: $(obj)/head.S $(KERNEL_IMAGE)
27 $(CC) -fno-pic $(HEAD_DEFINES) -I$(TOPDIR)/include -c -o $@ $<
28
29OBJECTS = head.o kImage.o
30
31rom.sw: $(obj)/rom.sw
32
33$(obj)/rom.sw: $(obj)/rom.bin
34 $(MKLASATIMG) -o $@ -k $^ -m $(MKLASATIMG_ARCH)
35
36$(obj)/rom.bin: $(obj)/rom
37 $(OBJCOPY) -O binary -S $^ $@
38
39# Rule to make the bootloader
40$(obj)/rom: $(addprefix $(obj)/,$(OBJECTS))
41 $(LD) $(LDFLAGS) $(LDSCRIPT) -o $@ $^
42
43$(obj)/%.o: $(obj)/%.gz
44 $(LD) -r -o $@ -b binary $<
45
46$(obj)/%.gz: $(obj)/%.bin
47 gzip -cf -9 $< > $@
48
49$(obj)/kImage.bin: $(KERNEL_IMAGE)
50 $(OBJCOPY) -O binary -S $^ $@
51
52clean:
53 rm -f rom rom.bin rom.sw kImage.bin kImage.o
diff --git a/arch/mips/lasat/image/head.S b/arch/mips/lasat/image/head.S
deleted file mode 100644
index efb95f2609c2..000000000000
--- a/arch/mips/lasat/image/head.S
+++ /dev/null
@@ -1,31 +0,0 @@
1#include <asm/lasat/head.h>
2
3 .text
4 .section .text.start, "ax"
5 .set noreorder
6 .set mips3
7
8 /* Magic words identifying a software image */
9 .word LASAT_K_MAGIC0_VAL
10 .word LASAT_K_MAGIC1_VAL
11
12 /* Image header version */
13 .word 0x00000002
14
15 /* image start and size */
16 .word _image_start
17 .word _image_size
18
19 /* start of kernel and entrypoint in uncompressed image */
20 .word _kernel_start
21 .word _kernel_entry
22
23 /* Here we have room for future flags */
24
25 .org 0x40
26reldate:
27 .word TIMESTAMP
28
29 .org 0x50
30release:
31 .string VERSION
diff --git a/arch/mips/lasat/image/romscript.normal b/arch/mips/lasat/image/romscript.normal
deleted file mode 100644
index 988f8ad189cb..000000000000
--- a/arch/mips/lasat/image/romscript.normal
+++ /dev/null
@@ -1,23 +0,0 @@
1OUTPUT_ARCH(mips)
2
3SECTIONS
4{
5 .text :
6 {
7 *(.text.start)
8 }
9
10 /* Data in ROM */
11
12 .data ALIGN(0x10) :
13 {
14 *(.data)
15 }
16 _image_start = ADDR(.data);
17 _image_size = SIZEOF(.data);
18
19 .other :
20 {
21 *(.*)
22 }
23}
diff --git a/arch/mips/lasat/interrupt.c b/arch/mips/lasat/interrupt.c
deleted file mode 100644
index 9a622b9a1051..000000000000
--- a/arch/mips/lasat/interrupt.c
+++ /dev/null
@@ -1,130 +0,0 @@
1/*
2 * Carsten Langgaard, carstenl@mips.com
3 * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
4 *
5 * This program is free software; you can distribute it and/or modify it
6 * under the terms of the GNU General Public License (Version 2) as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
17 *
18 * Routines for generic manipulation of the interrupts found on the
19 * Lasat boards.
20 */
21#include <linux/init.h>
22#include <linux/sched.h>
23#include <linux/slab.h>
24#include <linux/interrupt.h>
25#include <linux/kernel_stat.h>
26
27#include <asm/bootinfo.h>
28#include <asm/irq.h>
29#include <asm/lasat/lasatint.h>
30#include <asm/time.h>
31#include <asm/gdb-stub.h>
32
33static volatile int *lasat_int_status = NULL;
34static volatile int *lasat_int_mask = NULL;
35static volatile int lasat_int_mask_shift;
36
37void disable_lasat_irq(unsigned int irq_nr)
38{
39 *lasat_int_mask &= ~(1 << irq_nr) << lasat_int_mask_shift;
40}
41
42void enable_lasat_irq(unsigned int irq_nr)
43{
44 *lasat_int_mask |= (1 << irq_nr) << lasat_int_mask_shift;
45}
46
47static struct irq_chip lasat_irq_type = {
48 .name = "Lasat",
49 .ack = disable_lasat_irq,
50 .mask = disable_lasat_irq,
51 .mask_ack = disable_lasat_irq,
52 .unmask = enable_lasat_irq,
53};
54
55static inline int ls1bit32(unsigned int x)
56{
57 int b = 31, s;
58
59 s = 16; if (x << 16 == 0) s = 0; b -= s; x <<= s;
60 s = 8; if (x << 8 == 0) s = 0; b -= s; x <<= s;
61 s = 4; if (x << 4 == 0) s = 0; b -= s; x <<= s;
62 s = 2; if (x << 2 == 0) s = 0; b -= s; x <<= s;
63 s = 1; if (x << 1 == 0) s = 0; b -= s;
64
65 return b;
66}
67
68static unsigned long (* get_int_status)(void);
69
70static unsigned long get_int_status_100(void)
71{
72 return *lasat_int_status & *lasat_int_mask;
73}
74
75static unsigned long get_int_status_200(void)
76{
77 unsigned long int_status;
78
79 int_status = *lasat_int_status;
80 int_status &= (int_status >> LASATINT_MASK_SHIFT_200) & 0xffff;
81 return int_status;
82}
83
84asmlinkage void plat_irq_dispatch(void)
85{
86 unsigned long int_status;
87 unsigned int cause = read_c0_cause();
88 int irq;
89
90 if (cause & CAUSEF_IP7) { /* R4000 count / compare IRQ */
91 ll_timer_interrupt(7);
92 return;
93 }
94
95 int_status = get_int_status();
96
97 /* if int_status == 0, then the interrupt has already been cleared */
98 if (int_status) {
99 irq = ls1bit32(int_status);
100
101 do_IRQ(irq);
102 }
103}
104
105void __init arch_init_irq(void)
106{
107 int i;
108
109 switch (mips_machtype) {
110 case MACH_LASAT_100:
111 lasat_int_status = (void *)LASAT_INT_STATUS_REG_100;
112 lasat_int_mask = (void *)LASAT_INT_MASK_REG_100;
113 lasat_int_mask_shift = LASATINT_MASK_SHIFT_100;
114 get_int_status = get_int_status_100;
115 *lasat_int_mask = 0;
116 break;
117 case MACH_LASAT_200:
118 lasat_int_status = (void *)LASAT_INT_STATUS_REG_200;
119 lasat_int_mask = (void *)LASAT_INT_MASK_REG_200;
120 lasat_int_mask_shift = LASATINT_MASK_SHIFT_200;
121 get_int_status = get_int_status_200;
122 *lasat_int_mask &= 0xffff;
123 break;
124 default:
125 panic("arch_init_irq: mips_machtype incorrect");
126 }
127
128 for (i = 0; i <= LASATINT_END; i++)
129 set_irq_chip_and_handler(i, &lasat_irq_type, handle_level_irq);
130}
diff --git a/arch/mips/lasat/lasat_board.c b/arch/mips/lasat/lasat_board.c
deleted file mode 100644
index fbe9a87bd0ad..000000000000
--- a/arch/mips/lasat/lasat_board.c
+++ /dev/null
@@ -1,279 +0,0 @@
1/*
2 * Thomas Horsten <thh@lasat.com>
3 * Copyright (C) 2000 LASAT Networks A/S.
4 *
5 * This program is free software; you can distribute it and/or modify it
6 * under the terms of the GNU General Public License (Version 2) as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
17 *
18 * Routines specific to the LASAT boards
19 */
20#include <linux/types.h>
21#include <linux/crc32.h>
22#include <asm/lasat/lasat.h>
23#include <linux/kernel.h>
24#include <linux/string.h>
25#include <linux/ctype.h>
26#include <asm/bootinfo.h>
27#include <asm/addrspace.h>
28#include "at93c.h"
29/* New model description table */
30#include "lasat_models.h"
31
32#define EEPROM_CRC(data, len) (~0 ^ crc32(~0, data, len))
33
34struct lasat_info lasat_board_info;
35
36void update_bcastaddr(void);
37
38int EEPROMRead(unsigned int pos, unsigned char *data, int len)
39{
40 int i;
41
42 for (i=0; i<len; i++)
43 *data++ = at93c_read(pos++);
44
45 return 0;
46}
47int EEPROMWrite(unsigned int pos, unsigned char *data, int len)
48{
49 int i;
50
51 for (i=0; i<len; i++)
52 at93c_write(pos++, *data++);
53
54 return 0;
55}
56
57static void init_flash_sizes(void)
58{
59 int i;
60 unsigned long *lb = lasat_board_info.li_flashpart_base;
61 unsigned long *ls = lasat_board_info.li_flashpart_size;
62
63 ls[LASAT_MTD_BOOTLOADER] = 0x40000;
64 ls[LASAT_MTD_SERVICE] = 0xC0000;
65 ls[LASAT_MTD_NORMAL] = 0x100000;
66
67 if (mips_machtype == MACH_LASAT_100) {
68 lasat_board_info.li_flash_base = 0x1e000000;
69
70 lb[LASAT_MTD_BOOTLOADER] = 0x1e400000;
71
72 if (lasat_board_info.li_flash_size > 0x200000) {
73 ls[LASAT_MTD_CONFIG] = 0x100000;
74 ls[LASAT_MTD_FS] = 0x500000;
75 }
76 } else {
77 lasat_board_info.li_flash_base = 0x10000000;
78
79 if (lasat_board_info.li_flash_size < 0x1000000) {
80 lb[LASAT_MTD_BOOTLOADER] = 0x10000000;
81 ls[LASAT_MTD_CONFIG] = 0x100000;
82 if (lasat_board_info.li_flash_size >= 0x400000) {
83 ls[LASAT_MTD_FS] = lasat_board_info.li_flash_size - 0x300000;
84 }
85 }
86 }
87
88 for (i = 1; i < LASAT_MTD_LAST; i++)
89 lb[i] = lb[i-1] + ls[i-1];
90}
91
92int lasat_init_board_info(void)
93{
94 int c;
95 unsigned long crc;
96 unsigned long cfg0, cfg1;
97 const product_info_t *ppi;
98 int i_n_base_models = N_BASE_MODELS;
99 const char * const * i_txt_base_models = txt_base_models;
100 int i_n_prids = N_PRIDS;
101
102 memset(&lasat_board_info, 0, sizeof(lasat_board_info));
103
104 /* First read the EEPROM info */
105 EEPROMRead(0, (unsigned char *)&lasat_board_info.li_eeprom_info,
106 sizeof(struct lasat_eeprom_struct));
107
108 /* Check the CRC */
109 crc = EEPROM_CRC((unsigned char *)(&lasat_board_info.li_eeprom_info),
110 sizeof(struct lasat_eeprom_struct) - 4);
111
112 if (crc != lasat_board_info.li_eeprom_info.crc32) {
113 printk(KERN_WARNING "WARNING...\nWARNING...\nEEPROM CRC does "
114 "not match calculated, attempting to soldier on...\n");
115 }
116
117 if (lasat_board_info.li_eeprom_info.version != LASAT_EEPROM_VERSION) {
118 printk(KERN_WARNING "WARNING...\nWARNING...\nEEPROM version "
119 "%d, wanted version %d, attempting to soldier on...\n",
120 (unsigned int)lasat_board_info.li_eeprom_info.version,
121 LASAT_EEPROM_VERSION);
122 }
123
124 cfg0 = lasat_board_info.li_eeprom_info.cfg[0];
125 cfg1 = lasat_board_info.li_eeprom_info.cfg[1];
126
127 if ( LASAT_W0_DSCTYPE(cfg0) != 1) {
128 printk(KERN_WARNING "WARNING...\nWARNING...\n"
129 "Invalid configuration read from EEPROM, attempting to "
130 "soldier on...");
131 }
132 /* We have a valid configuration */
133
134 switch (LASAT_W0_SDRAMBANKSZ(cfg0)) {
135 case 0:
136 lasat_board_info.li_memsize = 0x0800000;
137 break;
138 case 1:
139 lasat_board_info.li_memsize = 0x1000000;
140 break;
141 case 2:
142 lasat_board_info.li_memsize = 0x2000000;
143 break;
144 case 3:
145 lasat_board_info.li_memsize = 0x4000000;
146 break;
147 case 4:
148 lasat_board_info.li_memsize = 0x8000000;
149 break;
150 default:
151 lasat_board_info.li_memsize = 0;
152 }
153
154 switch (LASAT_W0_SDRAMBANKS(cfg0)) {
155 case 0:
156 break;
157 case 1:
158 lasat_board_info.li_memsize *= 2;
159 break;
160 default:
161 break;
162 }
163
164 switch (LASAT_W0_BUSSPEED(cfg0)) {
165 case 0x0:
166 lasat_board_info.li_bus_hz = 60000000;
167 break;
168 case 0x1:
169 lasat_board_info.li_bus_hz = 66000000;
170 break;
171 case 0x2:
172 lasat_board_info.li_bus_hz = 66666667;
173 break;
174 case 0x3:
175 lasat_board_info.li_bus_hz = 80000000;
176 break;
177 case 0x4:
178 lasat_board_info.li_bus_hz = 83333333;
179 break;
180 case 0x5:
181 lasat_board_info.li_bus_hz = 100000000;
182 break;
183 }
184
185 switch (LASAT_W0_CPUCLK(cfg0)) {
186 case 0x0:
187 lasat_board_info.li_cpu_hz =
188 lasat_board_info.li_bus_hz;
189 break;
190 case 0x1:
191 lasat_board_info.li_cpu_hz =
192 lasat_board_info.li_bus_hz +
193 (lasat_board_info.li_bus_hz >> 1);
194 break;
195 case 0x2:
196 lasat_board_info.li_cpu_hz =
197 lasat_board_info.li_bus_hz +
198 lasat_board_info.li_bus_hz;
199 break;
200 case 0x3:
201 lasat_board_info.li_cpu_hz =
202 lasat_board_info.li_bus_hz +
203 lasat_board_info.li_bus_hz +
204 (lasat_board_info.li_bus_hz >> 1);
205 break;
206 case 0x4:
207 lasat_board_info.li_cpu_hz =
208 lasat_board_info.li_bus_hz +
209 lasat_board_info.li_bus_hz +
210 lasat_board_info.li_bus_hz;
211 break;
212 }
213
214 /* Flash size */
215 switch (LASAT_W1_FLASHSIZE(cfg1)) {
216 case 0:
217 lasat_board_info.li_flash_size = 0x200000;
218 break;
219 case 1:
220 lasat_board_info.li_flash_size = 0x400000;
221 break;
222 case 2:
223 lasat_board_info.li_flash_size = 0x800000;
224 break;
225 case 3:
226 lasat_board_info.li_flash_size = 0x1000000;
227 break;
228 case 4:
229 lasat_board_info.li_flash_size = 0x2000000;
230 break;
231 }
232
233 init_flash_sizes();
234
235 lasat_board_info.li_bmid = LASAT_W0_BMID(cfg0);
236 lasat_board_info.li_prid = lasat_board_info.li_eeprom_info.prid;
237 if (lasat_board_info.li_prid == 0xffff || lasat_board_info.li_prid == 0)
238 lasat_board_info.li_prid = lasat_board_info.li_bmid;
239
240 /* Base model stuff */
241 if (lasat_board_info.li_bmid > i_n_base_models)
242 lasat_board_info.li_bmid = i_n_base_models;
243 strcpy(lasat_board_info.li_bmstr, i_txt_base_models[lasat_board_info.li_bmid]);
244
245 /* Product ID dependent values */
246 c = lasat_board_info.li_prid;
247 if (c >= i_n_prids) {
248 strcpy(lasat_board_info.li_namestr, "Unknown Model");
249 strcpy(lasat_board_info.li_typestr, "Unknown Type");
250 } else {
251 ppi = &vendor_info_table[0].vi_product_info[c];
252 strcpy(lasat_board_info.li_namestr, ppi->pi_name);
253 if (ppi->pi_type)
254 strcpy(lasat_board_info.li_typestr, ppi->pi_type);
255 else
256 sprintf(lasat_board_info.li_typestr, "%d",10*c);
257 }
258
259#if defined(CONFIG_INET) && defined(CONFIG_SYSCTL)
260 update_bcastaddr();
261#endif
262
263 return 0;
264}
265
266void lasat_write_eeprom_info(void)
267{
268 unsigned long crc;
269
270 /* Generate the CRC */
271 crc = EEPROM_CRC((unsigned char *)(&lasat_board_info.li_eeprom_info),
272 sizeof(struct lasat_eeprom_struct) - 4);
273 lasat_board_info.li_eeprom_info.crc32 = crc;
274
275 /* Write the EEPROM info */
276 EEPROMWrite(0, (unsigned char *)&lasat_board_info.li_eeprom_info,
277 sizeof(struct lasat_eeprom_struct));
278}
279
diff --git a/arch/mips/lasat/lasat_models.h b/arch/mips/lasat/lasat_models.h
deleted file mode 100644
index ae0c5d0bd403..000000000000
--- a/arch/mips/lasat/lasat_models.h
+++ /dev/null
@@ -1,63 +0,0 @@
1/*
2 * Model description tables
3 */
4
5typedef struct product_info_t {
6 const char *pi_name;
7 const char *pi_type;
8} product_info_t;
9
10typedef struct vendor_info_t {
11 const char *vi_name;
12 const product_info_t *vi_product_info;
13} vendor_info_t;
14
15/*
16 * Base models
17 */
18static const char * const txt_base_models[] = {
19 "MQ 2", "MQ Pro", "SP 25", "SP 50", "SP 100", "SP 5000", "SP 7000", "SP 1000", "Unknown"
20};
21#define N_BASE_MODELS (sizeof(txt_base_models)/sizeof(char*)-1)
22
23/*
24 * Eicon Networks
25 */
26static const char txt_en_mq[] = "Masquerade";
27static const char txt_en_sp[] = "Safepipe";
28
29static const product_info_t product_info_eicon[] = {
30 { txt_en_mq, "II" }, /* 0 */
31 { txt_en_mq, "Pro" }, /* 1 */
32 { txt_en_sp, "25" }, /* 2 */
33 { txt_en_sp, "50" }, /* 3 */
34 { txt_en_sp, "100" }, /* 4 */
35 { txt_en_sp, "5000" }, /* 5 */
36 { txt_en_sp, "7000" }, /* 6 */
37 { txt_en_sp, "30" }, /* 7 */
38 { txt_en_sp, "5100" }, /* 8 */
39 { txt_en_sp, "7100" }, /* 9 */
40 { txt_en_sp, "1110" }, /* 10 */
41 { txt_en_sp, "3020" }, /* 11 */
42 { txt_en_sp, "3030" }, /* 12 */
43 { txt_en_sp, "5020" }, /* 13 */
44 { txt_en_sp, "5030" }, /* 14 */
45 { txt_en_sp, "1120" }, /* 15 */
46 { txt_en_sp, "1130" }, /* 16 */
47 { txt_en_sp, "6010" }, /* 17 */
48 { txt_en_sp, "6110" }, /* 18 */
49 { txt_en_sp, "6210" }, /* 19 */
50 { txt_en_sp, "1020" }, /* 20 */
51 { txt_en_sp, "1040" }, /* 21 */
52 { txt_en_sp, "1050" }, /* 22 */
53 { txt_en_sp, "1060" }, /* 23 */
54};
55#define N_PRIDS (sizeof(product_info_eicon)/sizeof(product_info_t))
56
57/*
58 * The vendor table
59 */
60static vendor_info_t const vendor_info_table[] = {
61 { "Eicon Networks", product_info_eicon },
62};
63#define N_VENDORS (sizeof(vendor_info_table)/sizeof(vendor_info_t))
diff --git a/arch/mips/lasat/picvue.c b/arch/mips/lasat/picvue.c
deleted file mode 100644
index 9ae82c3ffb07..000000000000
--- a/arch/mips/lasat/picvue.c
+++ /dev/null
@@ -1,240 +0,0 @@
1/*
2 * Picvue PVC160206 display driver
3 *
4 * Brian Murphy <brian@murphy.dk>
5 *
6 */
7#include <linux/kernel.h>
8#include <linux/delay.h>
9#include <asm/bootinfo.h>
10#include <asm/lasat/lasat.h>
11#include <linux/module.h>
12#include <linux/init.h>
13#include <linux/errno.h>
14#include <linux/string.h>
15
16#include "picvue.h"
17
18#define PVC_BUSY 0x80
19#define PVC_NLINES 2
20#define PVC_DISPMEM 80
21#define PVC_LINELEN PVC_DISPMEM / PVC_NLINES
22
23struct pvc_defs *picvue = NULL;
24
25DECLARE_MUTEX(pvc_sem);
26
27static void pvc_reg_write(u32 val)
28{
29 *picvue->reg = val;
30}
31
32static u32 pvc_reg_read(void)
33{
34 u32 tmp = *picvue->reg;
35 return tmp;
36}
37
38static void pvc_write_byte(u32 data, u8 byte)
39{
40 data |= picvue->e;
41 pvc_reg_write(data);
42 data &= ~picvue->data_mask;
43 data |= byte << picvue->data_shift;
44 pvc_reg_write(data);
45 ndelay(220);
46 pvc_reg_write(data & ~picvue->e);
47 ndelay(220);
48}
49
50static u8 pvc_read_byte(u32 data)
51{
52 u8 byte;
53
54 data |= picvue->e;
55 pvc_reg_write(data);
56 ndelay(220);
57 byte = (pvc_reg_read() & picvue->data_mask) >> picvue->data_shift;
58 data &= ~picvue->e;
59 pvc_reg_write(data);
60 ndelay(220);
61 return byte;
62}
63
64static u8 pvc_read_data(void)
65{
66 u32 data = pvc_reg_read();
67 u8 byte;
68 data |= picvue->rw;
69 data &= ~picvue->rs;
70 pvc_reg_write(data);
71 ndelay(40);
72 byte = pvc_read_byte(data);
73 data |= picvue->rs;
74 pvc_reg_write(data);
75 return byte;
76}
77
78#define TIMEOUT 1000
79static int pvc_wait(void)
80{
81 int i = TIMEOUT;
82 int err = 0;
83
84 while ((pvc_read_data() & PVC_BUSY) && i)
85 i--;
86 if (i == 0)
87 err = -ETIME;
88
89 return err;
90}
91
92#define MODE_INST 0
93#define MODE_DATA 1
94static void pvc_write(u8 byte, int mode)
95{
96 u32 data = pvc_reg_read();
97 data &= ~picvue->rw;
98 if (mode == MODE_DATA)
99 data |= picvue->rs;
100 else
101 data &= ~picvue->rs;
102 pvc_reg_write(data);
103 ndelay(40);
104 pvc_write_byte(data, byte);
105 if (mode == MODE_DATA)
106 data &= ~picvue->rs;
107 else
108 data |= picvue->rs;
109 pvc_reg_write(data);
110 pvc_wait();
111}
112
113void pvc_write_string(const unsigned char *str, u8 addr, int line)
114{
115 int i = 0;
116
117 if (line > 0 && (PVC_NLINES > 1))
118 addr += 0x40 * line;
119 pvc_write(0x80 | addr, MODE_INST);
120
121 while (*str != 0 && i < PVC_LINELEN) {
122 pvc_write(*str++, MODE_DATA);
123 i++;
124 }
125}
126
127void pvc_write_string_centered(const unsigned char *str, int line)
128{
129 int len = strlen(str);
130 u8 addr;
131
132 if (len > PVC_VISIBLE_CHARS)
133 addr = 0;
134 else
135 addr = (PVC_VISIBLE_CHARS - strlen(str))/2;
136
137 pvc_write_string(str, addr, line);
138}
139
140void pvc_dump_string(const unsigned char *str)
141{
142 int len = strlen(str);
143
144 pvc_write_string(str, 0, 0);
145 if (len > PVC_VISIBLE_CHARS)
146 pvc_write_string(&str[PVC_VISIBLE_CHARS], 0, 1);
147}
148
149#define BM_SIZE 8
150#define MAX_PROGRAMMABLE_CHARS 8
151int pvc_program_cg(int charnum, u8 bitmap[BM_SIZE])
152{
153 int i;
154 int addr;
155
156 if (charnum > MAX_PROGRAMMABLE_CHARS)
157 return -ENOENT;
158
159 addr = charnum * 8;
160 pvc_write(0x40 | addr, MODE_INST);
161
162 for (i=0; i<BM_SIZE; i++)
163 pvc_write(bitmap[i], MODE_DATA);
164 return 0;
165}
166
167#define FUNC_SET_CMD 0x20
168#define EIGHT_BYTE (1 << 4)
169#define FOUR_BYTE 0
170#define TWO_LINES (1 << 3)
171#define ONE_LINE 0
172#define LARGE_FONT (1 << 2)
173#define SMALL_FONT 0
174static void pvc_funcset(u8 cmd)
175{
176 pvc_write(FUNC_SET_CMD | (cmd & (EIGHT_BYTE|TWO_LINES|LARGE_FONT)), MODE_INST);
177}
178
179#define ENTRYMODE_CMD 0x4
180#define AUTO_INC (1 << 1)
181#define AUTO_DEC 0
182#define CURSOR_FOLLOWS_DISP (1 << 0)
183static void pvc_entrymode(u8 cmd)
184{
185 pvc_write(ENTRYMODE_CMD | (cmd & (AUTO_INC|CURSOR_FOLLOWS_DISP)), MODE_INST);
186}
187
188#define DISP_CNT_CMD 0x08
189#define DISP_OFF 0
190#define DISP_ON (1 << 2)
191#define CUR_ON (1 << 1)
192#define CUR_BLINK (1 << 0)
193void pvc_dispcnt(u8 cmd)
194{
195 pvc_write(DISP_CNT_CMD | (cmd & (DISP_ON|CUR_ON|CUR_BLINK)), MODE_INST);
196}
197
198#define MOVE_CMD 0x10
199#define DISPLAY (1 << 3)
200#define CURSOR 0
201#define RIGHT (1 << 2)
202#define LEFT 0
203void pvc_move(u8 cmd)
204{
205 pvc_write(MOVE_CMD | (cmd & (DISPLAY|RIGHT)), MODE_INST);
206}
207
208#define CLEAR_CMD 0x1
209void pvc_clear(void)
210{
211 pvc_write(CLEAR_CMD, MODE_INST);
212}
213
214#define HOME_CMD 0x2
215void pvc_home(void)
216{
217 pvc_write(HOME_CMD, MODE_INST);
218}
219
220int pvc_init(void)
221{
222 u8 cmd = EIGHT_BYTE;
223
224 if (PVC_NLINES == 2)
225 cmd |= (SMALL_FONT|TWO_LINES);
226 else
227 cmd |= (LARGE_FONT|ONE_LINE);
228 pvc_funcset(cmd);
229 pvc_dispcnt(DISP_ON);
230 pvc_entrymode(AUTO_INC);
231
232 pvc_clear();
233 pvc_write_string_centered("Display", 0);
234 pvc_write_string_centered("Initialized", 1);
235
236 return 0;
237}
238
239module_init(pvc_init);
240MODULE_LICENSE("GPL");
diff --git a/arch/mips/lasat/picvue.h b/arch/mips/lasat/picvue.h
deleted file mode 100644
index 2a96bf971897..000000000000
--- a/arch/mips/lasat/picvue.h
+++ /dev/null
@@ -1,48 +0,0 @@
1/*
2 * Picvue PVC160206 display driver
3 *
4 * Brian Murphy <brian.murphy@eicon.com>
5 *
6 */
7#include <asm/semaphore.h>
8
9struct pvc_defs {
10 volatile u32 *reg;
11 u32 data_shift;
12 u32 data_mask;
13 u32 e;
14 u32 rw;
15 u32 rs;
16};
17
18extern struct pvc_defs *picvue;
19
20#define PVC_NLINES 2
21#define PVC_DISPMEM 80
22#define PVC_LINELEN PVC_DISPMEM / PVC_NLINES
23#define PVC_VISIBLE_CHARS 16
24
25void pvc_write_string(const unsigned char *str, u8 addr, int line);
26void pvc_write_string_centered(const unsigned char *str, int line);
27void pvc_dump_string(const unsigned char *str);
28
29#define BM_SIZE 8
30#define MAX_PROGRAMMABLE_CHARS 8
31int pvc_program_cg(int charnum, u8 bitmap[BM_SIZE]);
32
33void pvc_dispcnt(u8 cmd);
34#define DISP_OFF 0
35#define DISP_ON (1 << 2)
36#define CUR_ON (1 << 1)
37#define CUR_BLINK (1 << 0)
38
39void pvc_move(u8 cmd);
40#define DISPLAY (1 << 3)
41#define CURSOR 0
42#define RIGHT (1 << 2)
43#define LEFT 0
44
45void pvc_clear(void);
46void pvc_home(void);
47
48extern struct semaphore pvc_sem;
diff --git a/arch/mips/lasat/picvue_proc.c b/arch/mips/lasat/picvue_proc.c
deleted file mode 100644
index cce7cddcdb08..000000000000
--- a/arch/mips/lasat/picvue_proc.c
+++ /dev/null
@@ -1,186 +0,0 @@
1/*
2 * Picvue PVC160206 display driver
3 *
4 * Brian Murphy <brian.murphy@eicon.com>
5 *
6 */
7#include <linux/kernel.h>
8#include <linux/module.h>
9#include <linux/init.h>
10#include <linux/errno.h>
11
12#include <linux/proc_fs.h>
13#include <linux/interrupt.h>
14
15#include <linux/timer.h>
16
17#include "picvue.h"
18
19static char pvc_lines[PVC_NLINES][PVC_LINELEN+1];
20static int pvc_linedata[PVC_NLINES];
21static struct proc_dir_entry *pvc_display_dir;
22static char *pvc_linename[PVC_NLINES] = {"line1", "line2"};
23#define DISPLAY_DIR_NAME "display"
24static int scroll_dir = 0, scroll_interval = 0;
25
26static struct timer_list timer;
27
28static void pvc_display(unsigned long data) {
29 int i;
30
31 pvc_clear();
32 for (i=0; i<PVC_NLINES; i++)
33 pvc_write_string(pvc_lines[i], 0, i);
34}
35
36static DECLARE_TASKLET(pvc_display_tasklet, &pvc_display, 0);
37
38static int pvc_proc_read_line(char *page, char **start,
39 off_t off, int count,
40 int *eof, void *data)
41{
42 char *origpage = page;
43 int lineno = *(int *)data;
44
45 if (lineno < 0 || lineno > PVC_NLINES) {
46 printk("proc_read_line: invalid lineno %d\n", lineno);
47 return 0;
48 }
49
50 down(&pvc_sem);
51 page += sprintf(page, "%s\n", pvc_lines[lineno]);
52 up(&pvc_sem);
53
54 return page - origpage;
55}
56
57static int pvc_proc_write_line(struct file *file, const char *buffer,
58 unsigned long count, void *data)
59{
60 int origcount = count;
61 int lineno = *(int *)data;
62
63 if (lineno < 0 || lineno > PVC_NLINES) {
64 printk("proc_write_line: invalid lineno %d\n", lineno);
65 return origcount;
66 }
67
68 if (count > PVC_LINELEN)
69 count = PVC_LINELEN;
70
71 if (buffer[count-1] == '\n')
72 count--;
73
74 down(&pvc_sem);
75 strncpy(pvc_lines[lineno], buffer, count);
76 pvc_lines[lineno][count] = '\0';
77 up(&pvc_sem);
78
79 tasklet_schedule(&pvc_display_tasklet);
80
81 return origcount;
82}
83
84static int pvc_proc_write_scroll(struct file *file, const char *buffer,
85 unsigned long count, void *data)
86{
87 int origcount = count;
88 int cmd = simple_strtol(buffer, NULL, 10);
89
90 down(&pvc_sem);
91 if (scroll_interval != 0)
92 del_timer(&timer);
93
94 if (cmd == 0) {
95 scroll_dir = 0;
96 scroll_interval = 0;
97 } else {
98 if (cmd < 0) {
99 scroll_dir = -1;
100 scroll_interval = -cmd;
101 } else {
102 scroll_dir = 1;
103 scroll_interval = cmd;
104 }
105 add_timer(&timer);
106 }
107 up(&pvc_sem);
108
109 return origcount;
110}
111
112static int pvc_proc_read_scroll(char *page, char **start,
113 off_t off, int count,
114 int *eof, void *data)
115{
116 char *origpage = page;
117
118 down(&pvc_sem);
119 page += sprintf(page, "%d\n", scroll_dir * scroll_interval);
120 up(&pvc_sem);
121
122 return page - origpage;
123}
124
125
126void pvc_proc_timerfunc(unsigned long data)
127{
128 if (scroll_dir < 0)
129 pvc_move(DISPLAY|RIGHT);
130 else if (scroll_dir > 0)
131 pvc_move(DISPLAY|LEFT);
132
133 timer.expires = jiffies + scroll_interval;
134 add_timer(&timer);
135}
136
137static void pvc_proc_cleanup(void)
138{
139 int i;
140 for (i=0; i<PVC_NLINES; i++)
141 remove_proc_entry(pvc_linename[i], pvc_display_dir);
142 remove_proc_entry("scroll", pvc_display_dir);
143 remove_proc_entry(DISPLAY_DIR_NAME, NULL);
144
145 del_timer(&timer);
146}
147
148static int __init pvc_proc_init(void)
149{
150 struct proc_dir_entry *proc_entry;
151 int i;
152
153 pvc_display_dir = proc_mkdir(DISPLAY_DIR_NAME, NULL);
154 if (pvc_display_dir == NULL)
155 goto error;
156
157 for (i=0; i<PVC_NLINES; i++) {
158 strcpy(pvc_lines[i], "");
159 pvc_linedata[i] = i;
160 }
161 for (i=0; i<PVC_NLINES; i++) {
162 proc_entry = create_proc_entry(pvc_linename[i], 0644, pvc_display_dir);
163 if (proc_entry == NULL)
164 goto error;
165 proc_entry->read_proc = pvc_proc_read_line;
166 proc_entry->write_proc = pvc_proc_write_line;
167 proc_entry->data = &pvc_linedata[i];
168 }
169 proc_entry = create_proc_entry("scroll", 0644, pvc_display_dir);
170 if (proc_entry == NULL)
171 goto error;
172 proc_entry->write_proc = pvc_proc_write_scroll;
173 proc_entry->read_proc = pvc_proc_read_scroll;
174
175 init_timer(&timer);
176 timer.function = pvc_proc_timerfunc;
177
178 return 0;
179error:
180 pvc_proc_cleanup();
181 return -ENOMEM;
182}
183
184module_init(pvc_proc_init);
185module_exit(pvc_proc_cleanup);
186MODULE_LICENSE("GPL");
diff --git a/arch/mips/lasat/prom.c b/arch/mips/lasat/prom.c
deleted file mode 100644
index 812c6ac366be..000000000000
--- a/arch/mips/lasat/prom.c
+++ /dev/null
@@ -1,117 +0,0 @@
1/*
2 * PROM interface routines.
3 */
4#include <linux/types.h>
5#include <linux/init.h>
6#include <linux/string.h>
7#include <linux/ctype.h>
8#include <linux/kernel.h>
9#include <linux/mm.h>
10#include <linux/bootmem.h>
11#include <linux/ioport.h>
12#include <asm/bootinfo.h>
13#include <asm/lasat/lasat.h>
14#include <asm/cpu.h>
15
16#include "at93c.h"
17#include <asm/lasat/eeprom.h>
18#include "prom.h"
19
20#define RESET_VECTOR 0xbfc00000
21#define PROM_JUMP_TABLE_ENTRY(n) (*((u32 *)(RESET_VECTOR + 0x20) + n))
22#define PROM_DISPLAY_ADDR PROM_JUMP_TABLE_ENTRY(0)
23#define PROM_PUTC_ADDR PROM_JUMP_TABLE_ENTRY(1)
24#define PROM_MONITOR_ADDR PROM_JUMP_TABLE_ENTRY(2)
25
26static void null_prom_display(const char *string, int pos, int clear)
27{
28}
29
30static void null_prom_monitor(void)
31{
32}
33
34static void null_prom_putc(char c)
35{
36}
37
38/* these are functions provided by the bootloader */
39static void (* __prom_putc)(char c) = null_prom_putc;
40
41void prom_putchar(char c)
42{
43 __prom_putc(c);
44}
45
46void (* prom_display)(const char *string, int pos, int clear) =
47 null_prom_display;
48void (* prom_monitor)(void) = null_prom_monitor;
49
50unsigned int lasat_ndelay_divider;
51
52static void setup_prom_vectors(void)
53{
54 u32 version = *(u32 *)(RESET_VECTOR + 0x90);
55
56 if (version >= 307) {
57 prom_display = (void *)PROM_DISPLAY_ADDR;
58 __prom_putc = (void *)PROM_PUTC_ADDR;
59 prom_monitor = (void *)PROM_MONITOR_ADDR;
60 }
61 printk("prom vectors set up\n");
62}
63
64static struct at93c_defs at93c_defs[N_MACHTYPES] = {
65 {(void *)AT93C_REG_100, (void *)AT93C_RDATA_REG_100, AT93C_RDATA_SHIFT_100,
66 AT93C_WDATA_SHIFT_100, AT93C_CS_M_100, AT93C_CLK_M_100},
67 {(void *)AT93C_REG_200, (void *)AT93C_RDATA_REG_200, AT93C_RDATA_SHIFT_200,
68 AT93C_WDATA_SHIFT_200, AT93C_CS_M_200, AT93C_CLK_M_200},
69};
70
71void __init prom_init(void)
72{
73 int argc = fw_arg0;
74 char **argv = (char **) fw_arg1;
75
76 setup_prom_vectors();
77
78 if (current_cpu_data.cputype == CPU_R5000) {
79 printk("LASAT 200 board\n");
80 mips_machtype = MACH_LASAT_200;
81 lasat_ndelay_divider = LASAT_200_DIVIDER;
82 } else {
83 printk("LASAT 100 board\n");
84 mips_machtype = MACH_LASAT_100;
85 lasat_ndelay_divider = LASAT_100_DIVIDER;
86 }
87
88 at93c = &at93c_defs[mips_machtype];
89
90 lasat_init_board_info(); /* Read info from EEPROM */
91
92 mips_machgroup = MACH_GROUP_LASAT;
93
94 /* Get the command line */
95 if (argc > 0) {
96 strncpy(arcs_cmdline, argv[0], CL_SIZE-1);
97 arcs_cmdline[CL_SIZE-1] = '\0';
98 }
99
100 /* Set the I/O base address */
101 set_io_port_base(KSEG1);
102
103 /* Set memory regions */
104 ioport_resource.start = 0;
105 ioport_resource.end = 0xffffffff; /* Wrong, fixme. */
106
107 add_memory_region(0, lasat_board_info.li_memsize, BOOT_MEM_RAM);
108}
109
110void __init prom_free_prom_memory(void)
111{
112}
113
114const char *get_system_type(void)
115{
116 return lasat_board_info.li_bmstr;
117}
diff --git a/arch/mips/lasat/prom.h b/arch/mips/lasat/prom.h
deleted file mode 100644
index 019d45fbd268..000000000000
--- a/arch/mips/lasat/prom.h
+++ /dev/null
@@ -1,5 +0,0 @@
1#ifndef PROM_H
2#define PROM_H
3extern void (* prom_display)(const char *string, int pos, int clear);
4extern void (* prom_monitor)(void);
5#endif
diff --git a/arch/mips/lasat/reset.c b/arch/mips/lasat/reset.c
deleted file mode 100644
index 9e22acf03083..000000000000
--- a/arch/mips/lasat/reset.c
+++ /dev/null
@@ -1,69 +0,0 @@
1/*
2 * Thomas Horsten <thh@lasat.com>
3 * Copyright (C) 2000 LASAT Networks A/S.
4 *
5 * This program is free software; you can distribute it and/or modify it
6 * under the terms of the GNU General Public License (Version 2) as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
17 *
18 * Reset the LASAT board.
19 */
20#include <linux/kernel.h>
21#include <linux/pm.h>
22
23#include <asm/reboot.h>
24#include <asm/system.h>
25#include <asm/lasat/lasat.h>
26
27#include "picvue.h"
28#include "prom.h"
29
30static void lasat_machine_restart(char *command);
31static void lasat_machine_halt(void);
32
33/* Used to set machine to boot in service mode via /proc interface */
34int lasat_boot_to_service = 0;
35
36static void lasat_machine_restart(char *command)
37{
38 local_irq_disable();
39
40 if (lasat_boot_to_service) {
41 printk("machine_restart: Rebooting to service mode\n");
42 *(volatile unsigned int *)0xa0000024 = 0xdeadbeef;
43 *(volatile unsigned int *)0xa00000fc = 0xfedeabba;
44 }
45 *lasat_misc->reset_reg = 0xbedead;
46 for (;;) ;
47}
48
49#define MESSAGE "System halted"
50static void lasat_machine_halt(void)
51{
52 local_irq_disable();
53
54 /* Disable interrupts and loop forever */
55 printk(KERN_NOTICE MESSAGE "\n");
56#ifdef CONFIG_PICVUE
57 pvc_clear();
58 pvc_write_string(MESSAGE, 0, 0);
59#endif
60 prom_monitor();
61 for (;;) ;
62}
63
64void lasat_reboot_setup(void)
65{
66 _machine_restart = lasat_machine_restart;
67 _machine_halt = lasat_machine_halt;
68 pm_power_off = lasat_machine_halt;
69}
diff --git a/arch/mips/lasat/setup.c b/arch/mips/lasat/setup.c
deleted file mode 100644
index 488007f13988..000000000000
--- a/arch/mips/lasat/setup.c
+++ /dev/null
@@ -1,182 +0,0 @@
1/*
2 * Carsten Langgaard, carstenl@mips.com
3 * Copyright (C) 1999 MIPS Technologies, Inc. All rights reserved.
4 *
5 * Thomas Horsten <thh@lasat.com>
6 * Copyright (C) 2000 LASAT Networks A/S.
7 *
8 * Brian Murphy <brian@murphy.dk>
9 *
10 * This program is free software; you can distribute it and/or modify it
11 * under the terms of the GNU General Public License (Version 2) as
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 * for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
22 *
23 * Lasat specific setup.
24 */
25#include <linux/init.h>
26#include <linux/sched.h>
27#include <linux/pci.h>
28#include <linux/interrupt.h>
29#include <linux/tty.h>
30#include <linux/serial.h>
31#include <linux/serial_core.h>
32
33#include <asm/time.h>
34#include <asm/cpu.h>
35#include <asm/bootinfo.h>
36#include <asm/irq.h>
37#include <asm/lasat/lasat.h>
38#include <asm/lasat/serial.h>
39
40#ifdef CONFIG_PICVUE
41#include <linux/notifier.h>
42#endif
43
44#include "ds1603.h"
45#include <asm/lasat/ds1603.h>
46#include <asm/lasat/picvue.h>
47#include <asm/lasat/eeprom.h>
48
49#include "prom.h"
50
51int lasat_command_line = 0;
52void lasatint_init(void);
53
54extern void lasat_reboot_setup(void);
55extern void pcisetup(void);
56extern void edhac_init(void *, void *, void *);
57extern void addrflt_init(void);
58
59struct lasat_misc lasat_misc_info[N_MACHTYPES] = {
60 {(void *)KSEG1ADDR(0x1c840000), (void *)KSEG1ADDR(0x1c800000), 2},
61 {(void *)KSEG1ADDR(0x11080000), (void *)KSEG1ADDR(0x11000000), 6}
62};
63
64struct lasat_misc *lasat_misc = NULL;
65
66#ifdef CONFIG_DS1603
67static struct ds_defs ds_defs[N_MACHTYPES] = {
68 { (void *)DS1603_REG_100, (void *)DS1603_REG_100,
69 DS1603_RST_100, DS1603_CLK_100, DS1603_DATA_100,
70 DS1603_DATA_SHIFT_100, 0, 0 },
71 { (void *)DS1603_REG_200, (void *)DS1603_DATA_REG_200,
72 DS1603_RST_200, DS1603_CLK_200, DS1603_DATA_200,
73 DS1603_DATA_READ_SHIFT_200, 1, 2000 }
74};
75#endif
76
77#ifdef CONFIG_PICVUE
78#include "picvue.h"
79static struct pvc_defs pvc_defs[N_MACHTYPES] = {
80 { (void *)PVC_REG_100, PVC_DATA_SHIFT_100, PVC_DATA_M_100,
81 PVC_E_100, PVC_RW_100, PVC_RS_100 },
82 { (void *)PVC_REG_200, PVC_DATA_SHIFT_200, PVC_DATA_M_200,
83 PVC_E_200, PVC_RW_200, PVC_RS_200 }
84};
85#endif
86
87static int lasat_panic_display(struct notifier_block *this,
88 unsigned long event, void *ptr)
89{
90#ifdef CONFIG_PICVUE
91 unsigned char *string = ptr;
92 if (string == NULL)
93 string = "Kernel Panic";
94 pvc_dump_string(string);
95#endif
96 return NOTIFY_DONE;
97}
98
99static int lasat_panic_prom_monitor(struct notifier_block *this,
100 unsigned long event, void *ptr)
101{
102 prom_monitor();
103 return NOTIFY_DONE;
104}
105
106static struct notifier_block lasat_panic_block[] =
107{
108 { lasat_panic_display, NULL, INT_MAX },
109 { lasat_panic_prom_monitor, NULL, INT_MIN }
110};
111
112static void lasat_time_init(void)
113{
114 mips_hpt_frequency = lasat_board_info.li_cpu_hz / 2;
115}
116
117void __init plat_timer_setup(struct irqaction *irq)
118{
119 change_c0_status(ST0_IM, IE_IRQ0 | IE_IRQ5);
120}
121
122#define DYNAMIC_SERIAL_INIT
123#ifdef DYNAMIC_SERIAL_INIT
124void __init serial_init(void)
125{
126#ifdef CONFIG_SERIAL_8250
127 struct uart_port s;
128
129 memset(&s, 0, sizeof(s));
130
131 s.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST;
132 s.iotype = UPIO_MEM;
133
134 if (mips_machtype == MACH_LASAT_100) {
135 s.uartclk = LASAT_BASE_BAUD_100 * 16;
136 s.irq = LASATINT_UART_100;
137 s.regshift = LASAT_UART_REGS_SHIFT_100;
138 s.membase = (char *)KSEG1ADDR(LASAT_UART_REGS_BASE_100);
139 } else {
140 s.uartclk = LASAT_BASE_BAUD_200 * 16;
141 s.irq = LASATINT_UART_200;
142 s.regshift = LASAT_UART_REGS_SHIFT_200;
143 s.membase = (char *)KSEG1ADDR(LASAT_UART_REGS_BASE_200);
144 }
145
146 if (early_serial_setup(&s) != 0)
147 printk(KERN_ERR "Serial setup failed!\n");
148#endif
149}
150#endif
151
152void __init plat_mem_setup(void)
153{
154 int i;
155 lasat_misc = &lasat_misc_info[mips_machtype];
156#ifdef CONFIG_PICVUE
157 picvue = &pvc_defs[mips_machtype];
158#endif
159
160 /* Set up panic notifier */
161 for (i = 0; i < sizeof(lasat_panic_block) / sizeof(struct notifier_block); i++)
162 atomic_notifier_chain_register(&panic_notifier_list,
163 &lasat_panic_block[i]);
164
165 lasat_reboot_setup();
166
167 board_time_init = lasat_time_init;
168
169#ifdef CONFIG_DS1603
170 ds1603 = &ds_defs[mips_machtype];
171 rtc_mips_get_time = ds1603_read;
172 rtc_mips_set_time = ds1603_set;
173#endif
174
175#ifdef DYNAMIC_SERIAL_INIT
176 serial_init();
177#endif
178 /* Switch from prom exception handler to normal mode */
179 change_c0_status(ST0_BEV,0);
180
181 pr_info("Lasat specific initialization complete\n");
182}
diff --git a/arch/mips/lasat/sysctl.c b/arch/mips/lasat/sysctl.c
deleted file mode 100644
index 699ab1886ceb..000000000000
--- a/arch/mips/lasat/sysctl.c
+++ /dev/null
@@ -1,441 +0,0 @@
1/*
2 * Thomas Horsten <thh@lasat.com>
3 * Copyright (C) 2000 LASAT Networks A/S.
4 *
5 * This program is free software; you can distribute it and/or modify it
6 * under the terms of the GNU General Public License (Version 2) as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
17 *
18 * Routines specific to the LASAT boards
19 */
20#include <linux/types.h>
21#include <asm/lasat/lasat.h>
22
23#include <linux/module.h>
24#include <linux/sysctl.h>
25#include <linux/stddef.h>
26#include <linux/init.h>
27#include <linux/fs.h>
28#include <linux/ctype.h>
29#include <linux/string.h>
30#include <linux/net.h>
31#include <linux/inet.h>
32#include <linux/mutex.h>
33#include <asm/uaccess.h>
34
35#include "sysctl.h"
36#include "ds1603.h"
37
38static DEFINE_MUTEX(lasat_info_mutex);
39
40/* Strategy function to write EEPROM after changing string entry */
41int sysctl_lasatstring(ctl_table *table, int *name, int nlen,
42 void *oldval, size_t *oldlenp,
43 void *newval, size_t newlen)
44{
45 int r;
46 mutex_lock(&lasat_info_mutex);
47 r = sysctl_string(table, name,
48 nlen, oldval, oldlenp, newval, newlen);
49 if (r < 0) {
50 mutex_unlock(&lasat_info_mutex);
51 return r;
52 }
53 if (newval && newlen) {
54 lasat_write_eeprom_info();
55 }
56 mutex_unlock(&lasat_info_mutex);
57 return 1;
58}
59
60
61/* And the same for proc */
62int proc_dolasatstring(ctl_table *table, int write, struct file *filp,
63 void *buffer, size_t *lenp, loff_t *ppos)
64{
65 int r;
66 mutex_lock(&lasat_info_mutex);
67 r = proc_dostring(table, write, filp, buffer, lenp, ppos);
68 if ( (!write) || r) {
69 mutex_unlock(&lasat_info_mutex);
70 return r;
71 }
72 lasat_write_eeprom_info();
73 mutex_unlock(&lasat_info_mutex);
74 return 0;
75}
76
77/* proc function to write EEPROM after changing int entry */
78int proc_dolasatint(ctl_table *table, int write, struct file *filp,
79 void *buffer, size_t *lenp, loff_t *ppos)
80{
81 int r;
82 mutex_lock(&lasat_info_mutex);
83 r = proc_dointvec(table, write, filp, buffer, lenp, ppos);
84 if ( (!write) || r) {
85 mutex_unlock(&lasat_info_mutex);
86 return r;
87 }
88 lasat_write_eeprom_info();
89 mutex_unlock(&lasat_info_mutex);
90 return 0;
91}
92
93static int rtctmp;
94
95#ifdef CONFIG_DS1603
96/* proc function to read/write RealTime Clock */
97int proc_dolasatrtc(ctl_table *table, int write, struct file *filp,
98 void *buffer, size_t *lenp, loff_t *ppos)
99{
100 int r;
101 mutex_lock(&lasat_info_mutex);
102 if (!write) {
103 rtctmp = ds1603_read();
104 /* check for time < 0 and set to 0 */
105 if (rtctmp < 0)
106 rtctmp = 0;
107 }
108 r = proc_dointvec(table, write, filp, buffer, lenp, ppos);
109 if ( (!write) || r) {
110 mutex_unlock(&lasat_info_mutex);
111 return r;
112 }
113 ds1603_set(rtctmp);
114 mutex_unlock(&lasat_info_mutex);
115 return 0;
116}
117#endif
118
119/* Sysctl for setting the IP addresses */
120int sysctl_lasat_intvec(ctl_table *table, int *name, int nlen,
121 void *oldval, size_t *oldlenp,
122 void *newval, size_t newlen)
123{
124 int r;
125 mutex_lock(&lasat_info_mutex);
126 r = sysctl_intvec(table, name, nlen, oldval, oldlenp, newval, newlen);
127 if (r < 0) {
128 mutex_unlock(&lasat_info_mutex);
129 return r;
130 }
131 if (newval && newlen) {
132 lasat_write_eeprom_info();
133 }
134 mutex_unlock(&lasat_info_mutex);
135 return 1;
136}
137
138#ifdef CONFIG_DS1603
139/* Same for RTC */
140int sysctl_lasat_rtc(ctl_table *table, int *name, int nlen,
141 void *oldval, size_t *oldlenp,
142 void *newval, size_t newlen)
143{
144 int r;
145 mutex_lock(&lasat_info_mutex);
146 rtctmp = ds1603_read();
147 if (rtctmp < 0)
148 rtctmp = 0;
149 r = sysctl_intvec(table, name, nlen, oldval, oldlenp, newval, newlen);
150 if (r < 0) {
151 mutex_unlock(&lasat_info_mutex);
152 return r;
153 }
154 if (newval && newlen) {
155 ds1603_set(rtctmp);
156 }
157 mutex_unlock(&lasat_info_mutex);
158 return 1;
159}
160#endif
161
162#ifdef CONFIG_INET
163static char lasat_bcastaddr[16];
164
165void update_bcastaddr(void)
166{
167 unsigned int ip;
168
169 ip = (lasat_board_info.li_eeprom_info.ipaddr &
170 lasat_board_info.li_eeprom_info.netmask) |
171 ~lasat_board_info.li_eeprom_info.netmask;
172
173 sprintf(lasat_bcastaddr, "%d.%d.%d.%d",
174 (ip ) & 0xff,
175 (ip >> 8) & 0xff,
176 (ip >> 16) & 0xff,
177 (ip >> 24) & 0xff);
178}
179
180static char proc_lasat_ipbuf[32];
181/* Parsing of IP address */
182int proc_lasat_ip(ctl_table *table, int write, struct file *filp,
183 void *buffer, size_t *lenp, loff_t *ppos)
184{
185 int len;
186 unsigned int ip;
187 char *p, c;
188
189 if (!table->data || !table->maxlen || !*lenp ||
190 (*ppos && !write)) {
191 *lenp = 0;
192 return 0;
193 }
194
195 mutex_lock(&lasat_info_mutex);
196 if (write) {
197 len = 0;
198 p = buffer;
199 while (len < *lenp) {
200 if(get_user(c, p++)) {
201 mutex_unlock(&lasat_info_mutex);
202 return -EFAULT;
203 }
204 if (c == 0 || c == '\n')
205 break;
206 len++;
207 }
208 if (len >= sizeof(proc_lasat_ipbuf)-1)
209 len = sizeof(proc_lasat_ipbuf) - 1;
210 if (copy_from_user(proc_lasat_ipbuf, buffer, len))
211 {
212 mutex_unlock(&lasat_info_mutex);
213 return -EFAULT;
214 }
215 proc_lasat_ipbuf[len] = 0;
216 *ppos += *lenp;
217 /* Now see if we can convert it to a valid IP */
218 ip = in_aton(proc_lasat_ipbuf);
219 *(unsigned int *)(table->data) = ip;
220 lasat_write_eeprom_info();
221 } else {
222 ip = *(unsigned int *)(table->data);
223 sprintf(proc_lasat_ipbuf, "%d.%d.%d.%d",
224 (ip ) & 0xff,
225 (ip >> 8) & 0xff,
226 (ip >> 16) & 0xff,
227 (ip >> 24) & 0xff);
228 len = strlen(proc_lasat_ipbuf);
229 if (len > *lenp)
230 len = *lenp;
231 if (len)
232 if(copy_to_user(buffer, proc_lasat_ipbuf, len)) {
233 mutex_unlock(&lasat_info_mutex);
234 return -EFAULT;
235 }
236 if (len < *lenp) {
237 if(put_user('\n', ((char *) buffer) + len)) {
238 mutex_unlock(&lasat_info_mutex);
239 return -EFAULT;
240 }
241 len++;
242 }
243 *lenp = len;
244 *ppos += len;
245 }
246 update_bcastaddr();
247 mutex_unlock(&lasat_info_mutex);
248 return 0;
249}
250#endif /* defined(CONFIG_INET) */
251
252static int sysctl_lasat_eeprom_value(ctl_table *table, int *name, int nlen,
253 void *oldval, size_t *oldlenp,
254 void *newval, size_t newlen)
255{
256 int r;
257
258 mutex_lock(&lasat_info_mutex);
259 r = sysctl_intvec(table, name, nlen, oldval, oldlenp, newval, newlen);
260 if (r < 0) {
261 mutex_unlock(&lasat_info_mutex);
262 return r;
263 }
264
265 if (newval && newlen)
266 {
267 if (name && *name == LASAT_PRID)
268 lasat_board_info.li_eeprom_info.prid = *(int*)newval;
269
270 lasat_write_eeprom_info();
271 lasat_init_board_info();
272 }
273 mutex_unlock(&lasat_info_mutex);
274
275 return 0;
276}
277
278int proc_lasat_eeprom_value(ctl_table *table, int write, struct file *filp,
279 void *buffer, size_t *lenp, loff_t *ppos)
280{
281 int r;
282 mutex_lock(&lasat_info_mutex);
283 r = proc_dointvec(table, write, filp, buffer, lenp, ppos);
284 if ( (!write) || r) {
285 mutex_unlock(&lasat_info_mutex);
286 return r;
287 }
288 if (filp && filp->f_path.dentry)
289 {
290 if (!strcmp(filp->f_path.dentry->d_name.name, "prid"))
291 lasat_board_info.li_eeprom_info.prid = lasat_board_info.li_prid;
292 if (!strcmp(filp->f_path.dentry->d_name.name, "debugaccess"))
293 lasat_board_info.li_eeprom_info.debugaccess = lasat_board_info.li_debugaccess;
294 }
295 lasat_write_eeprom_info();
296 mutex_unlock(&lasat_info_mutex);
297 return 0;
298}
299
300extern int lasat_boot_to_service;
301
302#ifdef CONFIG_SYSCTL
303
304static ctl_table lasat_table[] = {
305 {
306 .ctl_name = CTL_UNNUMBERED,
307 .procname = "cpu-hz",
308 .data = &lasat_board_info.li_cpu_hz,
309 .maxlen = sizeof(int),
310 .mode = 0444,
311 .proc_handler = &proc_dointvec,
312 .strategy = &sysctl_intvec
313 },
314 {
315 .ctl_name = CTL_UNNUMBERED,
316 .procname = "bus-hz",
317 .data = &lasat_board_info.li_bus_hz,
318 .maxlen = sizeof(int),
319 .mode = 0444,
320 .proc_handler = &proc_dointvec,
321 .strategy = &sysctl_intvec
322 },
323 {
324 .ctl_name = CTL_UNNUMBERED,
325 .procname = "bmid",
326 .data = &lasat_board_info.li_bmid,
327 .maxlen = sizeof(int),
328 .mode = 0444,
329 .proc_handler = &proc_dointvec,
330 .strategy = &sysctl_intvec
331 },
332 {
333 .ctl_name = CTL_UNNUMBERED,
334 .procname = "prid",
335 .data = &lasat_board_info.li_prid,
336 .maxlen = sizeof(int),
337 .mode = 0644,
338 .proc_handler = &proc_lasat_eeprom_value,
339 .strategy = &sysctl_lasat_eeprom_value
340 },
341#ifdef CONFIG_INET
342 {
343 .ctl_name = CTL_UNNUMBERED,
344 .procname = "ipaddr",
345 .data = &lasat_board_info.li_eeprom_info.ipaddr,
346 .maxlen = sizeof(int),
347 .mode = 0644,
348 .proc_handler = &proc_lasat_ip,
349 .strategy = &sysctl_lasat_intvec
350 },
351 {
352 .ctl_name = LASAT_NETMASK,
353 .procname = "netmask",
354 .data = &lasat_board_info.li_eeprom_info.netmask,
355 .maxlen = sizeof(int),
356 .mode = 0644,
357 .proc_handler = &proc_lasat_ip,
358 .strategy = &sysctl_lasat_intvec
359 },
360 {
361 .ctl_name = CTL_UNNUMBERED,
362 .procname = "bcastaddr",
363 .data = &lasat_bcastaddr,
364 .maxlen = sizeof(lasat_bcastaddr),
365 .mode = 0600,
366 .proc_handler = &proc_dostring,
367 .strategy = &sysctl_string
368 },
369#endif
370 {
371 .ctl_name = CTL_UNNUMBERED,
372 .procname = "passwd_hash",
373 .data = &lasat_board_info.li_eeprom_info.passwd_hash,
374 .maxlen = sizeof(lasat_board_info.li_eeprom_info.passwd_hash),
375 .mode = 0600,
376 .proc_handler = &proc_dolasatstring,
377 .strategy = &sysctl_lasatstring
378 },
379 {
380 .ctl_name = CTL_UNNUMBERED,
381 .procname = "boot-service",
382 .data = &lasat_boot_to_service,
383 .maxlen = sizeof(int),
384 .mode = 0644,
385 .proc_handler = &proc_dointvec,
386 .strategy = &sysctl_intvec
387 },
388#ifdef CONFIG_DS1603
389 {
390 .ctl_name = CTL_UNNUMBERED,
391 .procname = "rtc",
392 .data = &rtctmp,
393 .maxlen = sizeof(int),
394 .mode = 0644,
395 .proc_handler = &proc_dolasatrtc,
396 .strategy = &sysctl_lasat_rtc
397 },
398#endif
399 {
400 .ctl_name = CTL_UNNUMBERED,
401 .procname = "namestr",
402 .data = &lasat_board_info.li_namestr,
403 .maxlen = sizeof(lasat_board_info.li_namestr),
404 .mode = 0444,
405 .proc_handler = &proc_dostring,
406 .strategy = &sysctl_string
407 },
408 {
409 .ctl_name = CTL_UNNUMBERED,
410 .procname = "typestr",
411 .data = &lasat_board_info.li_typestr,
412 .maxlen = sizeof(lasat_board_info.li_typestr),
413 .mode = 0444,
414 .proc_handler = &proc_dostring,
415 .strategy = &sysctl_string
416 },
417 {}
418};
419
420static ctl_table lasat_root_table[] = {
421 {
422 .ctl_name = CTL_UNNUMBERED,
423 .procname = "lasat",
424 .mode = 0555,
425 .child = lasat_table
426 },
427 {}
428};
429
430static int __init lasat_register_sysctl(void)
431{
432 struct ctl_table_header *lasat_table_header;
433
434 lasat_table_header =
435 register_sysctl_table(lasat_root_table);
436
437 return 0;
438}
439
440__initcall(lasat_register_sysctl);
441#endif /* CONFIG_SYSCTL */
diff --git a/arch/mips/lasat/sysctl.h b/arch/mips/lasat/sysctl.h
deleted file mode 100644
index 4d139d2adbdf..000000000000
--- a/arch/mips/lasat/sysctl.h
+++ /dev/null
@@ -1,24 +0,0 @@
1/*
2 * LASAT sysctl values
3 */
4
5#ifndef _LASAT_SYSCTL_H
6#define _LASAT_SYSCTL_H
7
8/* /proc/sys/lasat */
9enum {
10 LASAT_CPU_HZ=1,
11 LASAT_BUS_HZ,
12 LASAT_MODEL,
13 LASAT_PRID,
14 LASAT_IPADDR,
15 LASAT_NETMASK,
16 LASAT_BCAST,
17 LASAT_PASSWORD,
18 LASAT_SBOOT,
19 LASAT_RTC,
20 LASAT_NAMESTR,
21 LASAT_TYPESTR,
22};
23
24#endif /* _LASAT_SYSCTL_H */
diff --git a/arch/mips/lemote/lm2e/Makefile b/arch/mips/lemote/lm2e/Makefile
new file mode 100644
index 000000000000..fb1b48c48cb3
--- /dev/null
+++ b/arch/mips/lemote/lm2e/Makefile
@@ -0,0 +1,7 @@
1#
2# Makefile for Lemote Fulong mini-PC board.
3#
4
5obj-y += setup.o prom.o reset.o irq.o pci.o bonito-irq.o dbg_io.o mem.o
6EXTRA_AFLAGS := $(CFLAGS)
7
diff --git a/arch/mips/lemote/lm2e/bonito-irq.c b/arch/mips/lemote/lm2e/bonito-irq.c
new file mode 100644
index 000000000000..8fc3bce7075b
--- /dev/null
+++ b/arch/mips/lemote/lm2e/bonito-irq.c
@@ -0,0 +1,74 @@
1/*
2 * Copyright 2001 MontaVista Software Inc.
3 * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
4 * Copyright (C) 2000, 2001 Ralf Baechle (ralf@gnu.org)
5 *
6 * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology
7 * Author: Fuxin Zhang, zhangfx@lemote.com
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
13 *
14 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
15 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
17 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
20 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
21 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 *
25 * You should have received a copy of the GNU General Public License along
26 * with this program; if not, write to the Free Software Foundation, Inc.,
27 * 675 Mass Ave, Cambridge, MA 02139, USA.
28 *
29 */
30#include <linux/errno.h>
31#include <linux/init.h>
32#include <linux/io.h>
33#include <linux/types.h>
34#include <linux/interrupt.h>
35#include <linux/irq.h>
36
37#include <asm/mips-boards/bonito64.h>
38
39
40static inline void bonito_irq_enable(unsigned int irq)
41{
42 BONITO_INTENSET = (1 << (irq - BONITO_IRQ_BASE));
43 mmiowb();
44}
45
46static inline void bonito_irq_disable(unsigned int irq)
47{
48 BONITO_INTENCLR = (1 << (irq - BONITO_IRQ_BASE));
49 mmiowb();
50}
51
52static struct irq_chip bonito_irq_type = {
53 .name = "bonito_irq",
54 .ack = bonito_irq_disable,
55 .mask = bonito_irq_disable,
56 .mask_ack = bonito_irq_disable,
57 .unmask = bonito_irq_enable,
58};
59
60static struct irqaction dma_timeout_irqaction = {
61 .handler = no_action,
62 .name = "dma_timeout",
63};
64
65void bonito_irq_init(void)
66{
67 u32 i;
68
69 for (i = BONITO_IRQ_BASE; i < BONITO_IRQ_BASE + 32; i++) {
70 set_irq_chip_and_handler(i, &bonito_irq_type, handle_level_irq);
71 }
72
73 setup_irq(BONITO_IRQ_BASE + 10, &dma_timeout_irqaction);
74}
diff --git a/arch/mips/lemote/lm2e/dbg_io.c b/arch/mips/lemote/lm2e/dbg_io.c
new file mode 100644
index 000000000000..6c95da3ca76f
--- /dev/null
+++ b/arch/mips/lemote/lm2e/dbg_io.c
@@ -0,0 +1,146 @@
1/*
2 * Copyright 2001 MontaVista Software Inc.
3 * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
4 * Copyright (C) 2000, 2001 Ralf Baechle (ralf@gnu.org)
5 *
6 * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology
7 * Author: Fuxin Zhang, zhangfx@lemote.com
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
13 *
14 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
15 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
17 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
20 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
21 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 *
25 * You should have received a copy of the GNU General Public License along
26 * with this program; if not, write to the Free Software Foundation, Inc.,
27 * 675 Mass Ave, Cambridge, MA 02139, USA.
28 *
29 */
30
31#include <linux/io.h>
32#include <linux/init.h>
33#include <linux/types.h>
34
35#include <asm/serial.h>
36
37#define UART16550_BAUD_2400 2400
38#define UART16550_BAUD_4800 4800
39#define UART16550_BAUD_9600 9600
40#define UART16550_BAUD_19200 19200
41#define UART16550_BAUD_38400 38400
42#define UART16550_BAUD_57600 57600
43#define UART16550_BAUD_115200 115200
44
45#define UART16550_PARITY_NONE 0
46#define UART16550_PARITY_ODD 0x08
47#define UART16550_PARITY_EVEN 0x18
48#define UART16550_PARITY_MARK 0x28
49#define UART16550_PARITY_SPACE 0x38
50
51#define UART16550_DATA_5BIT 0x0
52#define UART16550_DATA_6BIT 0x1
53#define UART16550_DATA_7BIT 0x2
54#define UART16550_DATA_8BIT 0x3
55
56#define UART16550_STOP_1BIT 0x0
57#define UART16550_STOP_2BIT 0x4
58
59/* ----------------------------------------------------- */
60
61/* === CONFIG === */
62#ifdef CONFIG_64BIT
63#define BASE (0xffffffffbfd003f8)
64#else
65#define BASE (0xbfd003f8)
66#endif
67
68#define MAX_BAUD BASE_BAUD
69/* === END OF CONFIG === */
70
71#define REG_OFFSET 1
72
73/* register offset */
74#define OFS_RCV_BUFFER 0
75#define OFS_TRANS_HOLD 0
76#define OFS_SEND_BUFFER 0
77#define OFS_INTR_ENABLE (1*REG_OFFSET)
78#define OFS_INTR_ID (2*REG_OFFSET)
79#define OFS_DATA_FORMAT (3*REG_OFFSET)
80#define OFS_LINE_CONTROL (3*REG_OFFSET)
81#define OFS_MODEM_CONTROL (4*REG_OFFSET)
82#define OFS_RS232_OUTPUT (4*REG_OFFSET)
83#define OFS_LINE_STATUS (5*REG_OFFSET)
84#define OFS_MODEM_STATUS (6*REG_OFFSET)
85#define OFS_RS232_INPUT (6*REG_OFFSET)
86#define OFS_SCRATCH_PAD (7*REG_OFFSET)
87
88#define OFS_DIVISOR_LSB (0*REG_OFFSET)
89#define OFS_DIVISOR_MSB (1*REG_OFFSET)
90
91/* memory-mapped read/write of the port */
92#define UART16550_READ(y) readb((char *)BASE + (y))
93#define UART16550_WRITE(y, z) writeb(z, (char *)BASE + (y))
94
95void debugInit(u32 baud, u8 data, u8 parity, u8 stop)
96{
97 u32 divisor;
98
99 /* disable interrupts */
100 UART16550_WRITE(OFS_INTR_ENABLE, 0);
101
102 /* set up buad rate */
103 /* set DIAB bit */
104 UART16550_WRITE(OFS_LINE_CONTROL, 0x80);
105
106 /* set divisor */
107 divisor = MAX_BAUD / baud;
108 UART16550_WRITE(OFS_DIVISOR_LSB, divisor & 0xff);
109 UART16550_WRITE(OFS_DIVISOR_MSB, (divisor & 0xff00) >> 8);
110
111 /* clear DIAB bit */
112 UART16550_WRITE(OFS_LINE_CONTROL, 0x0);
113
114 /* set data format */
115 UART16550_WRITE(OFS_DATA_FORMAT, data | parity | stop);
116}
117
118static int remoteDebugInitialized;
119
120u8 getDebugChar(void)
121{
122 if (!remoteDebugInitialized) {
123 remoteDebugInitialized = 1;
124 debugInit(UART16550_BAUD_115200,
125 UART16550_DATA_8BIT,
126 UART16550_PARITY_NONE, UART16550_STOP_1BIT);
127 }
128
129 while ((UART16550_READ(OFS_LINE_STATUS) & 0x1) == 0) ;
130 return UART16550_READ(OFS_RCV_BUFFER);
131}
132
133int putDebugChar(u8 byte)
134{
135 if (!remoteDebugInitialized) {
136 remoteDebugInitialized = 1;
137 /*
138 debugInit(UART16550_BAUD_115200,
139 UART16550_DATA_8BIT,
140 UART16550_PARITY_NONE, UART16550_STOP_1BIT); */
141 }
142
143 while ((UART16550_READ(OFS_LINE_STATUS) & 0x20) == 0) ;
144 UART16550_WRITE(OFS_SEND_BUFFER, byte);
145 return 1;
146}
diff --git a/arch/mips/lemote/lm2e/irq.c b/arch/mips/lemote/lm2e/irq.c
new file mode 100644
index 000000000000..05693bceaeaf
--- /dev/null
+++ b/arch/mips/lemote/lm2e/irq.c
@@ -0,0 +1,145 @@
1/*
2 * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology
3 * Author: Fuxin Zhang, zhangfx@lemote.com
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 *
10 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
11 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
13 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
14 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
15 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
16 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
17 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
18 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
19 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20 *
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 */
26#include <linux/delay.h>
27#include <linux/io.h>
28#include <linux/irq.h>
29#include <linux/init.h>
30#include <linux/interrupt.h>
31#include <linux/irq.h>
32
33#include <asm/irq_cpu.h>
34#include <asm/i8259.h>
35#include <asm/mipsregs.h>
36#include <asm/mips-boards/bonito64.h>
37
38
39/*
40 * the first level int-handler will jump here if it is a bonito irq
41 */
42static void bonito_irqdispatch(void)
43{
44 u32 int_status;
45 int i;
46
47 /* workaround the IO dma problem: let cpu looping to allow DMA finish */
48 int_status = BONITO_INTISR;
49 if (int_status & (1 << 10)) {
50 while (int_status & (1 << 10)) {
51 udelay(1);
52 int_status = BONITO_INTISR;
53 }
54 }
55
56 /* Get pending sources, masked by current enables */
57 int_status = BONITO_INTISR & BONITO_INTEN;
58
59 if (int_status != 0) {
60 i = __ffs(int_status);
61 int_status &= ~(1 << i);
62 do_IRQ(BONITO_IRQ_BASE + i);
63 }
64}
65
66static void i8259_irqdispatch(void)
67{
68 int irq;
69
70 irq = i8259_irq();
71 if (irq >= 0) {
72 do_IRQ(irq);
73 } else {
74 spurious_interrupt();
75 }
76
77}
78
79asmlinkage void plat_irq_dispatch(void)
80{
81 unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
82
83 if (pending & CAUSEF_IP7) {
84 do_IRQ(MIPS_CPU_IRQ_BASE + 7);
85 } else if (pending & CAUSEF_IP5) {
86 i8259_irqdispatch();
87 } else if (pending & CAUSEF_IP2) {
88 bonito_irqdispatch();
89 } else {
90 spurious_interrupt();
91 }
92}
93
94static struct irqaction cascade_irqaction = {
95 .handler = no_action,
96 .mask = CPU_MASK_NONE,
97 .name = "cascade",
98};
99
100void __init arch_init_irq(void)
101{
102 extern void bonito_irq_init(void);
103
104 /*
105 * Clear all of the interrupts while we change the able around a bit.
106 * int-handler is not on bootstrap
107 */
108 clear_c0_status(ST0_IM | ST0_BEV);
109 local_irq_disable();
110
111 /* most bonito irq should be level triggered */
112 BONITO_INTEDGE = BONITO_ICU_SYSTEMERR | BONITO_ICU_MASTERERR |
113 BONITO_ICU_RETRYERR | BONITO_ICU_MBOXES;
114 BONITO_INTSTEER = 0;
115
116 /*
117 * Mask out all interrupt by writing "1" to all bit position in
118 * the interrupt reset reg.
119 */
120 BONITO_INTENCLR = ~0;
121
122 /* init all controller
123 * 0-15 ------> i8259 interrupt
124 * 16-23 ------> mips cpu interrupt
125 * 32-63 ------> bonito irq
126 */
127
128 /* Sets the first-level interrupt dispatcher. */
129 mips_cpu_irq_init();
130 init_i8259_irqs();
131 bonito_irq_init();
132
133 /*
134 printk("GPIODATA=%x, GPIOIE=%x\n", BONITO_GPIODATA, BONITO_GPIOIE);
135 printk("INTEN=%x, INTSET=%x, INTCLR=%x, INTISR=%x\n",
136 BONITO_INTEN, BONITO_INTENSET,
137 BONITO_INTENCLR, BONITO_INTISR);
138 */
139
140 /* bonito irq at IP2 */
141 setup_irq(MIPS_CPU_IRQ_BASE + 2, &cascade_irqaction);
142 /* 8259 irq at IP5 */
143 setup_irq(MIPS_CPU_IRQ_BASE + 5, &cascade_irqaction);
144
145}
diff --git a/arch/mips/lemote/lm2e/mem.c b/arch/mips/lemote/lm2e/mem.c
new file mode 100644
index 000000000000..16cd21587d34
--- /dev/null
+++ b/arch/mips/lemote/lm2e/mem.c
@@ -0,0 +1,23 @@
1/*
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU General Public License as published by the
4 * Free Software Foundation; either version 2 of the License, or (at your
5 * option) any later version.
6 */
7#include <linux/fs.h>
8#include <linux/fcntl.h>
9#include <linux/mm.h>
10
11/* override of arch/mips/mm/cache.c: __uncached_access */
12int __uncached_access(struct file *file, unsigned long addr)
13{
14 if (file->f_flags & O_SYNC)
15 return 1;
16
17 /*
18 * On the Lemote Loongson 2e system, the peripheral registers
19 * reside between 0x1000:0000 and 0x2000:0000.
20 */
21 return addr >= __pa(high_memory) ||
22 ((addr >= 0x10000000) && (addr < 0x20000000));
23}
diff --git a/arch/mips/lemote/lm2e/pci.c b/arch/mips/lemote/lm2e/pci.c
new file mode 100644
index 000000000000..1ade1cef3899
--- /dev/null
+++ b/arch/mips/lemote/lm2e/pci.c
@@ -0,0 +1,93 @@
1/*
2 * pci.c
3 *
4 * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology
5 * Author: Fuxin Zhang, zhangfx@lemote.com
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 *
12 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
13 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
14 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
15 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
16 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
17 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
18 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
19 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
20 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
21 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22 *
23 * You should have received a copy of the GNU General Public License along
24 * with this program; if not, write to the Free Software Foundation, Inc.,
25 * 675 Mass Ave, Cambridge, MA 02139, USA.
26 *
27 */
28#include <linux/types.h>
29#include <linux/pci.h>
30#include <linux/kernel.h>
31#include <linux/init.h>
32#include <asm/mips-boards/bonito64.h>
33
34extern struct pci_ops bonito64_pci_ops;
35
36static struct resource loongson2e_pci_mem_resource = {
37 .name = "LOONGSON2E PCI MEM",
38 .start = 0x14000000UL,
39 .end = 0x1fffffffUL,
40 .flags = IORESOURCE_MEM,
41};
42
43static struct resource loongson2e_pci_io_resource = {
44 .name = "LOONGSON2E PCI IO MEM",
45 .start = 0x00004000UL,
46 .end = IO_SPACE_LIMIT,
47 .flags = IORESOURCE_IO,
48};
49
50static struct pci_controller loongson2e_pci_controller = {
51 .pci_ops = &bonito64_pci_ops,
52 .io_resource = &loongson2e_pci_io_resource,
53 .mem_resource = &loongson2e_pci_mem_resource,
54 .mem_offset = 0x00000000UL,
55 .io_offset = 0x00000000UL,
56};
57
58static void __init ict_pcimap(void)
59{
60 /*
61 * local to PCI mapping: [256M,512M] -> [256M,512M]; differ from PMON
62 *
63 * CPU address space [256M,448M] is window for accessing pci space
64 * we set pcimap_lo[0,1,2] to map it to pci space [256M,448M]
65 * pcimap: bit18,pcimap_2; bit[17-12],lo2;bit[11-6],lo1;bit[5-0],lo0
66 */
67 /* 1,00 0110 ,0001 01,00 0000 */
68 BONITO_PCIMAP = 0x46140;
69
70 /* 1, 00 0010, 0000,01, 00 0000 */
71 /* BONITO_PCIMAP = 0x42040; */
72
73 /*
74 * PCI to local mapping: [2G,2G+256M] -> [0,256M]
75 */
76 BONITO_PCIBASE0 = 0x80000000;
77 BONITO_PCIBASE1 = 0x00800000;
78 BONITO_PCIBASE2 = 0x90000000;
79
80}
81
82static int __init pcibios_init(void)
83{
84 extern int pci_probe_only;
85 pci_probe_only = 0;
86
87 ict_pcimap();
88 register_pci_controller(&loongson2e_pci_controller);
89
90 return 0;
91}
92
93arch_initcall(pcibios_init);
diff --git a/arch/mips/lemote/lm2e/prom.c b/arch/mips/lemote/lm2e/prom.c
new file mode 100644
index 000000000000..67312d7acf2a
--- /dev/null
+++ b/arch/mips/lemote/lm2e/prom.c
@@ -0,0 +1,104 @@
1/*
2 * Based on Ocelot Linux port, which is
3 * Copyright 2001 MontaVista Software Inc.
4 * Author: jsun@mvista.com or jsun@junsun.net
5 *
6 * Copyright 2003 ICT CAS
7 * Author: Michael Guo <guoyi@ict.ac.cn>
8 *
9 * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology
10 * Author: Fuxin Zhang, zhangfx@lemote.com
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version.
16 */
17#include <linux/init.h>
18#include <linux/mm.h>
19#include <linux/sched.h>
20#include <linux/bootmem.h>
21
22#include <asm/addrspace.h>
23#include <asm/bootinfo.h>
24
25extern unsigned long bus_clock;
26extern unsigned long cpu_clock;
27extern unsigned int memsize, highmemsize;
28extern int putDebugChar(unsigned char byte);
29
30static int argc;
31/* pmon passes arguments in 32bit pointers */
32static int *arg;
33static int *env;
34
35const char *get_system_type(void)
36{
37 return "lemote-fulong";
38}
39
40void __init prom_init_cmdline(void)
41{
42 int i;
43 long l;
44
45 /* arg[0] is "g", the rest is boot parameters */
46 arcs_cmdline[0] = '\0';
47 for (i = 1; i < argc; i++) {
48 l = (long)arg[i];
49 if (strlen(arcs_cmdline) + strlen(((char *)l) + 1)
50 >= sizeof(arcs_cmdline))
51 break;
52 strcat(arcs_cmdline, ((char *)l));
53 strcat(arcs_cmdline, " ");
54 }
55}
56
57void __init prom_init(void)
58{
59 long l;
60 argc = fw_arg0;
61 arg = (int *)fw_arg1;
62 env = (int *)fw_arg2;
63
64 mips_machgroup = MACH_GROUP_LEMOTE;
65 mips_machtype = MACH_LEMOTE_FULONG;
66
67 prom_init_cmdline();
68
69 if ((strstr(arcs_cmdline, "console=")) == NULL)
70 strcat(arcs_cmdline, " console=ttyS0,115200");
71 if ((strstr(arcs_cmdline, "root=")) == NULL)
72 strcat(arcs_cmdline, " root=/dev/hda1");
73
74#define parse_even_earlier(res, option, p) \
75do { \
76 if (strncmp(option, (char *)p, strlen(option)) == 0) \
77 res = simple_strtol((char *)p + strlen(option"="), \
78 NULL, 10); \
79} while (0)
80
81 l = (long)*env;
82 while (l != 0) {
83 parse_even_earlier(bus_clock, "busclock", l);
84 parse_even_earlier(cpu_clock, "cpuclock", l);
85 parse_even_earlier(memsize, "memsize", l);
86 parse_even_earlier(highmemsize, "highmemsize", l);
87 env++;
88 l = (long)*env;
89 }
90 if (memsize == 0)
91 memsize = 256;
92
93 pr_info("busclock=%ld, cpuclock=%ld,memsize=%d,highmemsize=%d\n",
94 bus_clock, cpu_clock, memsize, highmemsize);
95}
96
97void __init prom_free_prom_memory(void)
98{
99}
100
101void prom_putchar(char c)
102{
103 putDebugChar(c);
104}
diff --git a/arch/mips/lemote/lm2e/reset.c b/arch/mips/lemote/lm2e/reset.c
new file mode 100644
index 000000000000..099387a3827a
--- /dev/null
+++ b/arch/mips/lemote/lm2e/reset.c
@@ -0,0 +1,41 @@
1/*
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU General Public License as published by the
4 * Free Software Foundation; either version 2 of the License, or (at your
5 * option) any later version.
6 *
7 * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology
8 * Author: Fuxin Zhang, zhangfx@lemote.com
9 */
10#include <linux/pm.h>
11
12#include <asm/reboot.h>
13
14static void loongson2e_restart(char *command)
15{
16#ifdef CONFIG_32BIT
17 *(unsigned long *)0xbfe00104 &= ~(1 << 2);
18 *(unsigned long *)0xbfe00104 |= (1 << 2);
19#else
20 *(unsigned long *)0xffffffffbfe00104 &= ~(1 << 2);
21 *(unsigned long *)0xffffffffbfe00104 |= (1 << 2);
22#endif
23 __asm__ __volatile__("jr\t%0"::"r"(0xbfc00000));
24}
25
26static void loongson2e_halt(void)
27{
28 while (1) ;
29}
30
31static void loongson2e_power_off(void)
32{
33 loongson2e_halt();
34}
35
36void mips_reboot_setup(void)
37{
38 _machine_restart = loongson2e_restart;
39 _machine_halt = loongson2e_halt;
40 pm_power_off = loongson2e_power_off;
41}
diff --git a/arch/mips/lemote/lm2e/setup.c b/arch/mips/lemote/lm2e/setup.c
new file mode 100644
index 000000000000..0e4d1fa572b5
--- /dev/null
+++ b/arch/mips/lemote/lm2e/setup.c
@@ -0,0 +1,134 @@
1/*
2 * BRIEF MODULE DESCRIPTION
3 * setup.c - board dependent boot routines
4 *
5 * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology
6 * Author: Fuxin Zhang, zhangfx@lemote.com
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 *
13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
14 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
15 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
16 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
17 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
18 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
19 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 *
24 * You should have received a copy of the GNU General Public License along
25 * with this program; if not, write to the Free Software Foundation, Inc.,
26 * 675 Mass Ave, Cambridge, MA 02139, USA.
27 *
28 */
29#include <linux/bootmem.h>
30#include <linux/init.h>
31#include <linux/io.h>
32#include <linux/ioport.h>
33#include <linux/interrupt.h>
34#include <linux/irq.h>
35#include <linux/kernel.h>
36#include <linux/mc146818rtc.h>
37#include <linux/mm.h>
38#include <linux/module.h>
39#include <linux/pci.h>
40#include <linux/tty.h>
41#include <linux/types.h>
42
43#include <asm/bootinfo.h>
44#include <asm/mc146818-time.h>
45#include <asm/time.h>
46#include <asm/wbflush.h>
47
48#ifdef CONFIG_VT
49#include <linux/console.h>
50#include <linux/screen_info.h>
51#endif
52
53extern void mips_reboot_setup(void);
54
55#ifdef CONFIG_64BIT
56#define PTR_PAD(p) ((0xffffffff00000000)|((unsigned long long)(p)))
57#else
58#define PTR_PAD(p) (p)
59#endif
60
61unsigned long cpu_clock;
62unsigned long bus_clock;
63unsigned int memsize;
64unsigned int highmemsize = 0;
65
66void __init plat_timer_setup(struct irqaction *irq)
67{
68 setup_irq(MIPS_CPU_IRQ_BASE + 7, irq);
69}
70
71static void __init loongson2e_time_init(void)
72{
73 /* setup mips r4k timer */
74 mips_hpt_frequency = cpu_clock / 2;
75}
76
77static unsigned long __init mips_rtc_get_time(void)
78{
79 return mc146818_get_cmos_time();
80}
81
82void (*__wbflush)(void);
83EXPORT_SYMBOL(__wbflush);
84
85static void wbflush_loongson2e(void)
86{
87 asm(".set\tpush\n\t"
88 ".set\tnoreorder\n\t"
89 ".set mips3\n\t"
90 "sync\n\t"
91 "nop\n\t"
92 ".set\tpop\n\t"
93 ".set mips0\n\t");
94}
95
96void __init plat_mem_setup(void)
97{
98 set_io_port_base(PTR_PAD(0xbfd00000));
99
100 mips_reboot_setup();
101
102 board_time_init = loongson2e_time_init;
103 rtc_mips_get_time = mips_rtc_get_time;
104
105 __wbflush = wbflush_loongson2e;
106
107 add_memory_region(0x0, (memsize << 20), BOOT_MEM_RAM);
108#ifdef CONFIG_64BIT
109 if (highmemsize > 0) {
110 add_memory_region(0x20000000, highmemsize << 20, BOOT_MEM_RAM);
111 }
112#endif
113
114#ifdef CONFIG_VT
115#if defined(CONFIG_VGA_CONSOLE)
116 conswitchp = &vga_con;
117
118 screen_info = (struct screen_info) {
119 0, 25, /* orig-x, orig-y */
120 0, /* unused */
121 0, /* orig-video-page */
122 0, /* orig-video-mode */
123 80, /* orig-video-cols */
124 0, 0, 0, /* ega_ax, ega_bx, ega_cx */
125 25, /* orig-video-lines */
126 VIDEO_TYPE_VGAC, /* orig-video-isVGA */
127 16 /* orig-video-points */
128 };
129#elif defined(CONFIG_DUMMY_CONSOLE)
130 conswitchp = &dummy_con;
131#endif
132#endif
133
134}
diff --git a/arch/mips/lib-32/Makefile b/arch/mips/lib-32/Makefile
deleted file mode 100644
index 8b94d4cc5a30..000000000000
--- a/arch/mips/lib-32/Makefile
+++ /dev/null
@@ -1,23 +0,0 @@
1#
2# Makefile for MIPS-specific library files..
3#
4
5lib-y += watch.o
6
7obj-$(CONFIG_CPU_MIPS32) += dump_tlb.o
8obj-$(CONFIG_CPU_MIPS64) += dump_tlb.o
9obj-$(CONFIG_CPU_NEVADA) += dump_tlb.o
10obj-$(CONFIG_CPU_R10000) += dump_tlb.o
11obj-$(CONFIG_CPU_R3000) += r3k_dump_tlb.o
12obj-$(CONFIG_CPU_R4300) += dump_tlb.o
13obj-$(CONFIG_CPU_R4X00) += dump_tlb.o
14obj-$(CONFIG_CPU_R5000) += dump_tlb.o
15obj-$(CONFIG_CPU_R5432) += dump_tlb.o
16obj-$(CONFIG_CPU_R6000) +=
17obj-$(CONFIG_CPU_R8000) +=
18obj-$(CONFIG_CPU_RM7000) += dump_tlb.o
19obj-$(CONFIG_CPU_RM9000) += dump_tlb.o
20obj-$(CONFIG_CPU_SB1) += dump_tlb.o
21obj-$(CONFIG_CPU_TX39XX) += r3k_dump_tlb.o
22obj-$(CONFIG_CPU_TX49XX) += dump_tlb.o
23obj-$(CONFIG_CPU_VR41XX) += dump_tlb.o
diff --git a/arch/mips/lib-32/dump_tlb.c b/arch/mips/lib-32/dump_tlb.c
deleted file mode 100644
index 6a68deb51aae..000000000000
--- a/arch/mips/lib-32/dump_tlb.c
+++ /dev/null
@@ -1,242 +0,0 @@
1/*
2 * Dump R4x00 TLB for debugging purposes.
3 *
4 * Copyright (C) 1994, 1995 by Waldorf Electronics, written by Ralf Baechle.
5 * Copyright (C) 1999 by Silicon Graphics, Inc.
6 */
7#include <linux/kernel.h>
8#include <linux/mm.h>
9#include <linux/sched.h>
10#include <linux/string.h>
11
12#include <asm/bootinfo.h>
13#include <asm/cachectl.h>
14#include <asm/cpu.h>
15#include <asm/mipsregs.h>
16#include <asm/page.h>
17#include <asm/pgtable.h>
18
19static inline const char *msk2str(unsigned int mask)
20{
21 switch (mask) {
22 case PM_4K:
23 return "4kb";
24 case PM_16K:
25 return "16kb";
26 case PM_64K:
27 return "64kb";
28 case PM_256K:
29 return "256kb";
30#ifndef CONFIG_CPU_VR41XX
31 case PM_1M:
32 return "1Mb";
33 case PM_4M:
34 return "4Mb";
35 case PM_16M:
36 return "16Mb";
37 case PM_64M:
38 return "64Mb";
39 case PM_256M:
40 return "256Mb";
41#endif
42 }
43
44 return "unknown";
45}
46
47#define BARRIER() \
48 __asm__ __volatile__( \
49 ".set\tnoreorder\n\t" \
50 "nop;nop;nop;nop;nop;nop;nop\n\t" \
51 ".set\treorder");
52
53void dump_tlb(int first, int last)
54{
55 unsigned int pagemask, c0, c1, asid;
56 unsigned long long entrylo0, entrylo1;
57 unsigned long entryhi;
58 int i;
59
60 asid = read_c0_entryhi() & 0xff;
61
62 printk("\n");
63 for (i = first; i <= last; i++) {
64 write_c0_index(i);
65 BARRIER();
66 tlb_read();
67 BARRIER();
68 pagemask = read_c0_pagemask();
69 entryhi = read_c0_entryhi();
70 entrylo0 = read_c0_entrylo0();
71 entrylo1 = read_c0_entrylo1();
72
73 /* Unused entries have a virtual address in KSEG0. */
74 if ((entryhi & 0xf0000000) != 0x80000000
75 && (entryhi & 0xff) == asid) {
76 /*
77 * Only print entries in use
78 */
79 printk("Index: %2d pgmask=%s ", i, msk2str(pagemask));
80
81 c0 = (entrylo0 >> 3) & 7;
82 c1 = (entrylo1 >> 3) & 7;
83
84 printk("va=%08lx asid=%02lx\n",
85 (entryhi & 0xffffe000), (entryhi & 0xff));
86 printk("\t\t\t[pa=%08Lx c=%d d=%d v=%d g=%Ld]\n",
87 (entrylo0 << 6) & PAGE_MASK, c0,
88 (entrylo0 & 4) ? 1 : 0,
89 (entrylo0 & 2) ? 1 : 0, (entrylo0 & 1));
90 printk("\t\t\t[pa=%08Lx c=%d d=%d v=%d g=%Ld]\n",
91 (entrylo1 << 6) & PAGE_MASK, c1,
92 (entrylo1 & 4) ? 1 : 0,
93 (entrylo1 & 2) ? 1 : 0, (entrylo1 & 1));
94 printk("\n");
95 }
96 }
97
98 write_c0_entryhi(asid);
99}
100
101void dump_tlb_all(void)
102{
103 dump_tlb(0, current_cpu_data.tlbsize - 1);
104}
105
106void dump_tlb_wired(void)
107{
108 int wired;
109
110 wired = read_c0_wired();
111 printk("Wired: %d", wired);
112 dump_tlb(0, read_c0_wired());
113}
114
115void dump_tlb_addr(unsigned long addr)
116{
117 unsigned int flags, oldpid;
118 int index;
119
120 local_irq_save(flags);
121 oldpid = read_c0_entryhi() & 0xff;
122 BARRIER();
123 write_c0_entryhi((addr & PAGE_MASK) | oldpid);
124 BARRIER();
125 tlb_probe();
126 BARRIER();
127 index = read_c0_index();
128 write_c0_entryhi(oldpid);
129 local_irq_restore(flags);
130
131 if (index < 0) {
132 printk("No entry for address 0x%08lx in TLB\n", addr);
133 return;
134 }
135
136 printk("Entry %d maps address 0x%08lx\n", index, addr);
137 dump_tlb(index, index);
138}
139
140void dump_tlb_nonwired(void)
141{
142 dump_tlb(read_c0_wired(), current_cpu_data.tlbsize - 1);
143}
144
145void dump_list_process(struct task_struct *t, void *address)
146{
147 pgd_t *page_dir, *pgd;
148 pud_t *pud;
149 pmd_t *pmd;
150 pte_t *pte, page;
151 unsigned long addr, val;
152
153 addr = (unsigned long) address;
154
155 printk("Addr == %08lx\n", addr);
156 printk("task == %8p\n", t);
157 printk("task->mm == %8p\n", t->mm);
158 //printk("tasks->mm.pgd == %08x\n", (unsigned int) t->mm->pgd);
159
160 if (addr > KSEG0) {
161 page_dir = pgd_offset_k(0);
162 pgd = pgd_offset_k(addr);
163 } else if (t->mm) {
164 page_dir = pgd_offset(t->mm, 0);
165 pgd = pgd_offset(t->mm, addr);
166 } else {
167 printk("Current thread has no mm\n");
168 return;
169 }
170 printk("page_dir == %08x\n", (unsigned int) page_dir);
171 printk("pgd == %08x, ", (unsigned int) pgd);
172 pud = pud_offset(pgd, addr);
173 printk("pud == %08x, ", (unsigned int) pud);
174
175 pmd = pmd_offset(pud, addr);
176 printk("pmd == %08x, ", (unsigned int) pmd);
177
178 pte = pte_offset(pmd, addr);
179 printk("pte == %08x, ", (unsigned int) pte);
180
181 page = *pte;
182#ifdef CONFIG_64BIT_PHYS_ADDR
183 printk("page == %08Lx\n", pte_val(page));
184#else
185 printk("page == %08lx\n", pte_val(page));
186#endif
187
188 val = pte_val(page);
189 if (val & _PAGE_PRESENT)
190 printk("present ");
191 if (val & _PAGE_READ)
192 printk("read ");
193 if (val & _PAGE_WRITE)
194 printk("write ");
195 if (val & _PAGE_ACCESSED)
196 printk("accessed ");
197 if (val & _PAGE_MODIFIED)
198 printk("modified ");
199 if (val & _PAGE_R4KBUG)
200 printk("r4kbug ");
201 if (val & _PAGE_GLOBAL)
202 printk("global ");
203 if (val & _PAGE_VALID)
204 printk("valid ");
205 printk("\n");
206}
207
208void dump_list_current(void *address)
209{
210 dump_list_process(current, address);
211}
212
213unsigned int vtop(void *address)
214{
215 pgd_t *pgd;
216 pud_t *pud;
217 pmd_t *pmd;
218 pte_t *pte;
219 unsigned int addr, paddr;
220
221 addr = (unsigned long) address;
222 pgd = pgd_offset(current->mm, addr);
223 pud = pud_offset(pgd, addr);
224 pmd = pmd_offset(pud, addr);
225 pte = pte_offset(pmd, addr);
226 paddr = (KSEG1 | (unsigned int) pte_val(*pte)) & PAGE_MASK;
227 paddr |= (addr & ~PAGE_MASK);
228
229 return paddr;
230}
231
232void dump16(unsigned long *p)
233{
234 int i;
235
236 for (i = 0; i < 8; i++) {
237 printk("*%08lx == %08lx, ", (unsigned long) p, *p);
238 p++;
239 printk("*%08lx == %08lx\n", (unsigned long) p, *p);
240 p++;
241 }
242}
diff --git a/arch/mips/lib-32/r3k_dump_tlb.c b/arch/mips/lib-32/r3k_dump_tlb.c
deleted file mode 100644
index 4f2cb74f0766..000000000000
--- a/arch/mips/lib-32/r3k_dump_tlb.c
+++ /dev/null
@@ -1,182 +0,0 @@
1/*
2 * Dump R3000 TLB for debugging purposes.
3 *
4 * Copyright (C) 1994, 1995 by Waldorf Electronics, written by Ralf Baechle.
5 * Copyright (C) 1999 by Silicon Graphics, Inc.
6 * Copyright (C) 1999 by Harald Koerfgen
7 */
8#include <linux/kernel.h>
9#include <linux/mm.h>
10#include <linux/sched.h>
11#include <linux/string.h>
12
13#include <asm/bootinfo.h>
14#include <asm/cachectl.h>
15#include <asm/cpu.h>
16#include <asm/mipsregs.h>
17#include <asm/page.h>
18#include <asm/pgtable.h>
19
20extern int r3k_have_wired_reg; /* defined in tlb-r3k.c */
21
22void dump_tlb(int first, int last)
23{
24 int i;
25 unsigned int asid;
26 unsigned long entryhi, entrylo0;
27
28 asid = read_c0_entryhi() & 0xfc0;
29
30 for (i = first; i <= last; i++) {
31 write_c0_index(i<<8);
32 __asm__ __volatile__(
33 ".set\tnoreorder\n\t"
34 "tlbr\n\t"
35 "nop\n\t"
36 ".set\treorder");
37 entryhi = read_c0_entryhi();
38 entrylo0 = read_c0_entrylo0();
39
40 /* Unused entries have a virtual address of KSEG0. */
41 if ((entryhi & 0xffffe000) != 0x80000000
42 && (entryhi & 0xfc0) == asid) {
43 /*
44 * Only print entries in use
45 */
46 printk("Index: %2d ", i);
47
48 printk("va=%08lx asid=%08lx"
49 " [pa=%06lx n=%d d=%d v=%d g=%d]",
50 (entryhi & 0xffffe000),
51 entryhi & 0xfc0,
52 entrylo0 & PAGE_MASK,
53 (entrylo0 & (1 << 11)) ? 1 : 0,
54 (entrylo0 & (1 << 10)) ? 1 : 0,
55 (entrylo0 & (1 << 9)) ? 1 : 0,
56 (entrylo0 & (1 << 8)) ? 1 : 0);
57 }
58 }
59 printk("\n");
60
61 write_c0_entryhi(asid);
62}
63
64void dump_tlb_all(void)
65{
66 dump_tlb(0, current_cpu_data.tlbsize - 1);
67}
68
69void dump_tlb_wired(void)
70{
71 int wired = r3k_have_wired_reg ? read_c0_wired() : 8;
72
73 printk("Wired: %d", wired);
74 dump_tlb(0, wired - 1);
75}
76
77void dump_tlb_addr(unsigned long addr)
78{
79 unsigned long flags, oldpid;
80 int index;
81
82 local_irq_save(flags);
83 oldpid = read_c0_entryhi() & 0xff;
84 write_c0_entryhi((addr & PAGE_MASK) | oldpid);
85 tlb_probe();
86 index = read_c0_index();
87 write_c0_entryhi(oldpid);
88 local_irq_restore(flags);
89
90 if (index < 0) {
91 printk("No entry for address 0x%08lx in TLB\n", addr);
92 return;
93 }
94
95 printk("Entry %d maps address 0x%08lx\n", index, addr);
96 dump_tlb(index, index);
97}
98
99void dump_tlb_nonwired(void)
100{
101 int wired = r3k_have_wired_reg ? read_c0_wired() : 8;
102 dump_tlb(wired, current_cpu_data.tlbsize - 1);
103}
104
105void dump_list_process(struct task_struct *t, void *address)
106{
107 pgd_t *page_dir, *pgd;
108 pud_t *pud;
109 pmd_t *pmd;
110 pte_t *pte, page;
111 unsigned int addr;
112 unsigned long val;
113
114 addr = (unsigned int) address;
115
116 printk("Addr == %08x\n", addr);
117 printk("tasks->mm.pgd == %08x\n", (unsigned int) t->mm->pgd);
118
119 page_dir = pgd_offset(t->mm, 0);
120 printk("page_dir == %08x\n", (unsigned int) page_dir);
121
122 pgd = pgd_offset(t->mm, addr);
123 printk("pgd == %08x, ", (unsigned int) pgd);
124
125 pud = pud_offset(pgd, addr);
126 printk("pud == %08x, ", (unsigned int) pud);
127
128 pmd = pmd_offset(pud, addr);
129 printk("pmd == %08x, ", (unsigned int) pmd);
130
131 pte = pte_offset(pmd, addr);
132 printk("pte == %08x, ", (unsigned int) pte);
133
134 page = *pte;
135 printk("page == %08x\n", (unsigned int) pte_val(page));
136
137 val = pte_val(page);
138 if (val & _PAGE_PRESENT) printk("present ");
139 if (val & _PAGE_READ) printk("read ");
140 if (val & _PAGE_WRITE) printk("write ");
141 if (val & _PAGE_ACCESSED) printk("accessed ");
142 if (val & _PAGE_MODIFIED) printk("modified ");
143 if (val & _PAGE_GLOBAL) printk("global ");
144 if (val & _PAGE_VALID) printk("valid ");
145 printk("\n");
146}
147
148void dump_list_current(void *address)
149{
150 dump_list_process(current, address);
151}
152
153unsigned int vtop(void *address)
154{
155 pgd_t *pgd;
156 pud_t *pud;
157 pmd_t *pmd;
158 pte_t *pte;
159 unsigned int addr, paddr;
160
161 addr = (unsigned long) address;
162 pgd = pgd_offset(current->mm, addr);
163 pud = pud_offset(pgd, addr);
164 pmd = pmd_offset(pud, addr);
165 pte = pte_offset(pmd, addr);
166 paddr = (KSEG1 | (unsigned int) pte_val(*pte)) & PAGE_MASK;
167 paddr |= (addr & ~PAGE_MASK);
168
169 return paddr;
170}
171
172void dump16(unsigned long *p)
173{
174 int i;
175
176 for (i = 0; i < 8; i++) {
177 printk("*%08lx == %08lx, ", (unsigned long)p, *p);
178 p++;
179 printk("*%08lx == %08lx\n", (unsigned long)p, *p);
180 p++;
181 }
182}
diff --git a/arch/mips/lib-32/watch.S b/arch/mips/lib-32/watch.S
deleted file mode 100644
index 808b3af1a605..000000000000
--- a/arch/mips/lib-32/watch.S
+++ /dev/null
@@ -1,60 +0,0 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Kernel debug stuff to use the Watch registers.
7 * Useful to find stack overflows, dangling pointers etc.
8 *
9 * Copyright (C) 1995, 1996, 1999 by Ralf Baechle
10 */
11#include <asm/asm.h>
12#include <asm/mipsregs.h>
13#include <asm/regdef.h>
14
15 .set noreorder
16/*
17 * Parameter: a0 - logic address to watch
18 * Currently only KSEG0 addresses are allowed!
19 * a1 - set bit #1 to trap on load references
20 * bit #0 to trap on store references
21 * Results : none
22 */
23 LEAF(__watch_set)
24 li t0, 0x80000000
25 subu a0, t0
26 ori a0, 7
27 xori a0, 7
28 or a0, a1
29 mtc0 a0, CP0_WATCHLO
30 sw a0, watch_savelo
31
32 jr ra
33 mtc0 zero, CP0_WATCHHI
34 END(__watch_set)
35
36/*
37 * Parameter: none
38 * Results : none
39 */
40 LEAF(__watch_clear)
41 jr ra
42 mtc0 zero, CP0_WATCHLO
43 END(__watch_clear)
44
45/*
46 * Parameter: none
47 * Results : none
48 */
49 LEAF(__watch_reenable)
50 lw t0, watch_savelo
51 jr ra
52 mtc0 t0, CP0_WATCHLO
53 END(__watch_reenable)
54
55/*
56 * Saved value of the c0_watchlo register for watch_reenable()
57 */
58 .data
59watch_savelo: .word 0
60 .text
diff --git a/arch/mips/lib-64/Makefile b/arch/mips/lib-64/Makefile
deleted file mode 100644
index 8b94d4cc5a30..000000000000
--- a/arch/mips/lib-64/Makefile
+++ /dev/null
@@ -1,23 +0,0 @@
1#
2# Makefile for MIPS-specific library files..
3#
4
5lib-y += watch.o
6
7obj-$(CONFIG_CPU_MIPS32) += dump_tlb.o
8obj-$(CONFIG_CPU_MIPS64) += dump_tlb.o
9obj-$(CONFIG_CPU_NEVADA) += dump_tlb.o
10obj-$(CONFIG_CPU_R10000) += dump_tlb.o
11obj-$(CONFIG_CPU_R3000) += r3k_dump_tlb.o
12obj-$(CONFIG_CPU_R4300) += dump_tlb.o
13obj-$(CONFIG_CPU_R4X00) += dump_tlb.o
14obj-$(CONFIG_CPU_R5000) += dump_tlb.o
15obj-$(CONFIG_CPU_R5432) += dump_tlb.o
16obj-$(CONFIG_CPU_R6000) +=
17obj-$(CONFIG_CPU_R8000) +=
18obj-$(CONFIG_CPU_RM7000) += dump_tlb.o
19obj-$(CONFIG_CPU_RM9000) += dump_tlb.o
20obj-$(CONFIG_CPU_SB1) += dump_tlb.o
21obj-$(CONFIG_CPU_TX39XX) += r3k_dump_tlb.o
22obj-$(CONFIG_CPU_TX49XX) += dump_tlb.o
23obj-$(CONFIG_CPU_VR41XX) += dump_tlb.o
diff --git a/arch/mips/lib-64/dump_tlb.c b/arch/mips/lib-64/dump_tlb.c
deleted file mode 100644
index 594df1a05ecc..000000000000
--- a/arch/mips/lib-64/dump_tlb.c
+++ /dev/null
@@ -1,216 +0,0 @@
1/*
2 * Dump R4x00 TLB for debugging purposes.
3 *
4 * Copyright (C) 1994, 1995 by Waldorf Electronics, written by Ralf Baechle.
5 * Copyright (C) 1999 by Silicon Graphics, Inc.
6 */
7#include <linux/kernel.h>
8#include <linux/mm.h>
9#include <linux/sched.h>
10#include <linux/string.h>
11
12#include <asm/bootinfo.h>
13#include <asm/cachectl.h>
14#include <asm/cpu.h>
15#include <asm/mipsregs.h>
16#include <asm/page.h>
17#include <asm/pgtable.h>
18
19static inline const char *msk2str(unsigned int mask)
20{
21 switch (mask) {
22 case PM_4K: return "4kb";
23 case PM_16K: return "16kb";
24 case PM_64K: return "64kb";
25 case PM_256K: return "256kb";
26#ifndef CONFIG_CPU_VR41XX
27 case PM_1M: return "1Mb";
28 case PM_4M: return "4Mb";
29 case PM_16M: return "16Mb";
30 case PM_64M: return "64Mb";
31 case PM_256M: return "256Mb";
32#endif
33 }
34
35 return "unknown";
36}
37
38#define BARRIER() \
39 __asm__ __volatile__( \
40 ".set\tnoreorder\n\t" \
41 "nop;nop;nop;nop;nop;nop;nop\n\t" \
42 ".set\treorder");
43
44void dump_tlb(int first, int last)
45{
46 unsigned long s_entryhi, entryhi, entrylo0, entrylo1, asid;
47 unsigned int s_index, pagemask, c0, c1, i;
48
49 s_entryhi = read_c0_entryhi();
50 s_index = read_c0_index();
51 asid = s_entryhi & 0xff;
52
53 for (i = first; i <= last; i++) {
54 write_c0_index(i);
55 BARRIER();
56 tlb_read();
57 BARRIER();
58 pagemask = read_c0_pagemask();
59 entryhi = read_c0_entryhi();
60 entrylo0 = read_c0_entrylo0();
61 entrylo1 = read_c0_entrylo1();
62
63 /* Unused entries have a virtual address of CKSEG0. */
64 if ((entryhi & ~0x1ffffUL) != CKSEG0
65 && (entryhi & 0xff) == asid) {
66 /*
67 * Only print entries in use
68 */
69 printk("Index: %2d pgmask=%s ", i, msk2str(pagemask));
70
71 c0 = (entrylo0 >> 3) & 7;
72 c1 = (entrylo1 >> 3) & 7;
73
74 printk("va=%011lx asid=%02lx\n",
75 (entryhi & ~0x1fffUL),
76 entryhi & 0xff);
77 printk("\t[pa=%011lx c=%d d=%d v=%d g=%ld] ",
78 (entrylo0 << 6) & PAGE_MASK, c0,
79 (entrylo0 & 4) ? 1 : 0,
80 (entrylo0 & 2) ? 1 : 0,
81 (entrylo0 & 1));
82 printk("[pa=%011lx c=%d d=%d v=%d g=%ld]\n",
83 (entrylo1 << 6) & PAGE_MASK, c1,
84 (entrylo1 & 4) ? 1 : 0,
85 (entrylo1 & 2) ? 1 : 0,
86 (entrylo1 & 1));
87 }
88 }
89 printk("\n");
90
91 write_c0_entryhi(s_entryhi);
92 write_c0_index(s_index);
93}
94
95void dump_tlb_all(void)
96{
97 dump_tlb(0, current_cpu_data.tlbsize - 1);
98}
99
100void dump_tlb_wired(void)
101{
102 int wired;
103
104 wired = read_c0_wired();
105 printk("Wired: %d", wired);
106 dump_tlb(0, read_c0_wired());
107}
108
109void dump_tlb_addr(unsigned long addr)
110{
111 unsigned int flags, oldpid;
112 int index;
113
114 local_irq_save(flags);
115 oldpid = read_c0_entryhi() & 0xff;
116 BARRIER();
117 write_c0_entryhi((addr & PAGE_MASK) | oldpid);
118 BARRIER();
119 tlb_probe();
120 BARRIER();
121 index = read_c0_index();
122 write_c0_entryhi(oldpid);
123 local_irq_restore(flags);
124
125 if (index < 0) {
126 printk("No entry for address 0x%08lx in TLB\n", addr);
127 return;
128 }
129
130 printk("Entry %d maps address 0x%08lx\n", index, addr);
131 dump_tlb(index, index);
132}
133
134void dump_tlb_nonwired(void)
135{
136 dump_tlb(read_c0_wired(), current_cpu_data.tlbsize - 1);
137}
138
139void dump_list_process(struct task_struct *t, void *address)
140{
141 pgd_t *page_dir, *pgd;
142 pud_t *pud;
143 pmd_t *pmd;
144 pte_t *pte, page;
145 unsigned long addr, val;
146
147 addr = (unsigned long) address;
148
149 printk("Addr == %08lx\n", addr);
150 printk("tasks->mm.pgd == %08lx\n", (unsigned long) t->mm->pgd);
151
152 page_dir = pgd_offset(t->mm, 0UL);
153 printk("page_dir == %016lx\n", (unsigned long) page_dir);
154
155 pgd = pgd_offset(t->mm, addr);
156 printk("pgd == %016lx\n", (unsigned long) pgd);
157
158 pud = pud_offset(pgd, addr);
159 printk("pud == %016lx\n", (unsigned long) pud);
160
161 pmd = pmd_offset(pud, addr);
162 printk("pmd == %016lx\n", (unsigned long) pmd);
163
164 pte = pte_offset(pmd, addr);
165 printk("pte == %016lx\n", (unsigned long) pte);
166
167 page = *pte;
168 printk("page == %08lx\n", pte_val(page));
169
170 val = pte_val(page);
171 if (val & _PAGE_PRESENT) printk("present ");
172 if (val & _PAGE_READ) printk("read ");
173 if (val & _PAGE_WRITE) printk("write ");
174 if (val & _PAGE_ACCESSED) printk("accessed ");
175 if (val & _PAGE_MODIFIED) printk("modified ");
176 if (val & _PAGE_R4KBUG) printk("r4kbug ");
177 if (val & _PAGE_GLOBAL) printk("global ");
178 if (val & _PAGE_VALID) printk("valid ");
179 printk("\n");
180}
181
182void dump_list_current(void *address)
183{
184 dump_list_process(current, address);
185}
186
187unsigned long vtop(void *address)
188{
189 pgd_t *pgd;
190 pud_t *pud;
191 pmd_t *pmd;
192 pte_t *pte;
193 unsigned long addr, paddr;
194
195 addr = (unsigned long) address;
196 pgd = pgd_offset(current->mm, addr);
197 pud = pud_offset(pgd, addr);
198 pmd = pmd_offset(pud, addr);
199 pte = pte_offset(pmd, addr);
200 paddr = (CKSEG1 | (unsigned int) pte_val(*pte)) & PAGE_MASK;
201 paddr |= (addr & ~PAGE_MASK);
202
203 return paddr;
204}
205
206void dump16(unsigned long *p)
207{
208 int i;
209
210 for (i = 0; i < 8; i++) {
211 printk("*%08lx == %08lx, ", (unsigned long)p, *p);
212 p++;
213 printk("*%08lx == %08lx\n", (unsigned long)p, *p);
214 p++;
215 }
216}
diff --git a/arch/mips/lib-64/watch.S b/arch/mips/lib-64/watch.S
deleted file mode 100644
index f91434013695..000000000000
--- a/arch/mips/lib-64/watch.S
+++ /dev/null
@@ -1,57 +0,0 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Kernel debug stuff to use the Watch registers.
7 * Useful to find stack overflows, dangling pointers etc.
8 *
9 * Copyright (C) 1995, 1996, 1999, 2001 by Ralf Baechle
10 */
11#include <asm/asm.h>
12#include <asm/mipsregs.h>
13#include <asm/regdef.h>
14
15 .set noreorder
16/*
17 * Parameter: a0 - physical address to watch
18 * a1 - set bit #1 to trap on load references
19 * bit #0 to trap on store references
20 * Results : none
21 */
22 LEAF(__watch_set)
23 ori a0, 7
24 xori a0, 7
25 or a0, a1
26 mtc0 a0, CP0_WATCHLO
27 sd a0, watch_savelo
28 dsrl32 a0, a0, 0
29
30 jr ra
31 mtc0 zero, CP0_WATCHHI
32 END(__watch_set)
33
34/*
35 * Parameter: none
36 * Results : none
37 */
38 LEAF(__watch_clear)
39 jr ra
40 mtc0 zero, CP0_WATCHLO
41 END(__watch_clear)
42
43/*
44 * Parameter: none
45 * Results : none
46 */
47 LEAF(__watch_reenable)
48 ld t0, watch_savelo
49 jr ra
50 mtc0 t0, CP0_WATCHLO
51 END(__watch_reenable)
52
53/*
54 * Saved value of the c0_watchlo register for watch_reenable()
55 */
56 .local watch_savelo
57 .comm watch_savelo, 8, 8
diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile
index 1c1aa9f92f6c..91ed1eb33102 100644
--- a/arch/mips/lib/Makefile
+++ b/arch/mips/lib/Makefile
@@ -8,5 +8,24 @@ lib-y += csum_partial.o memcpy.o memcpy-inatomic.o memset.o strlen_user.o \
8obj-y += iomap.o 8obj-y += iomap.o
9obj-$(CONFIG_PCI) += iomap-pci.o 9obj-$(CONFIG_PCI) += iomap-pci.o
10 10
11obj-$(CONFIG_CPU_LOONGSON2) += dump_tlb.o
12obj-$(CONFIG_CPU_MIPS32) += dump_tlb.o
13obj-$(CONFIG_CPU_MIPS64) += dump_tlb.o
14obj-$(CONFIG_CPU_NEVADA) += dump_tlb.o
15obj-$(CONFIG_CPU_R10000) += dump_tlb.o
16obj-$(CONFIG_CPU_R3000) += r3k_dump_tlb.o
17obj-$(CONFIG_CPU_R4300) += dump_tlb.o
18obj-$(CONFIG_CPU_R4X00) += dump_tlb.o
19obj-$(CONFIG_CPU_R5000) += dump_tlb.o
20obj-$(CONFIG_CPU_R5432) += dump_tlb.o
21obj-$(CONFIG_CPU_R6000) +=
22obj-$(CONFIG_CPU_R8000) +=
23obj-$(CONFIG_CPU_RM7000) += dump_tlb.o
24obj-$(CONFIG_CPU_RM9000) += dump_tlb.o
25obj-$(CONFIG_CPU_SB1) += dump_tlb.o
26obj-$(CONFIG_CPU_TX39XX) += r3k_dump_tlb.o
27obj-$(CONFIG_CPU_TX49XX) += dump_tlb.o
28obj-$(CONFIG_CPU_VR41XX) += dump_tlb.o
29
11# libgcc-style stuff needed in the kernel 30# libgcc-style stuff needed in the kernel
12obj-y += ashldi3.o ashrdi3.o lshrdi3.o ucmpdi2.o 31obj-y += ashldi3.o ashrdi3.o lshrdi3.o ucmpdi2.o
diff --git a/arch/mips/lib/dump_tlb.c b/arch/mips/lib/dump_tlb.c
new file mode 100644
index 000000000000..1a4db7dc77cb
--- /dev/null
+++ b/arch/mips/lib/dump_tlb.c
@@ -0,0 +1,100 @@
1/*
2 * Dump R4x00 TLB for debugging purposes.
3 *
4 * Copyright (C) 1994, 1995 by Waldorf Electronics, written by Ralf Baechle.
5 * Copyright (C) 1999 by Silicon Graphics, Inc.
6 */
7#include <linux/kernel.h>
8#include <linux/mm.h>
9
10#include <asm/mipsregs.h>
11#include <asm/page.h>
12#include <asm/pgtable.h>
13
14static inline const char *msk2str(unsigned int mask)
15{
16 switch (mask) {
17 case PM_4K: return "4kb";
18 case PM_16K: return "16kb";
19 case PM_64K: return "64kb";
20 case PM_256K: return "256kb";
21#ifndef CONFIG_CPU_VR41XX
22 case PM_1M: return "1Mb";
23 case PM_4M: return "4Mb";
24 case PM_16M: return "16Mb";
25 case PM_64M: return "64Mb";
26 case PM_256M: return "256Mb";
27#endif
28 }
29 return "";
30}
31
32#define BARRIER() \
33 __asm__ __volatile__( \
34 ".set\tnoreorder\n\t" \
35 "nop;nop;nop;nop;nop;nop;nop\n\t" \
36 ".set\treorder");
37
38static void dump_tlb(int first, int last)
39{
40 unsigned long s_entryhi, entryhi, asid;
41 unsigned long long entrylo0, entrylo1;
42 unsigned int s_index, pagemask, c0, c1, i;
43
44 s_entryhi = read_c0_entryhi();
45 s_index = read_c0_index();
46 asid = s_entryhi & 0xff;
47
48 for (i = first; i <= last; i++) {
49 write_c0_index(i);
50 BARRIER();
51 tlb_read();
52 BARRIER();
53 pagemask = read_c0_pagemask();
54 entryhi = read_c0_entryhi();
55 entrylo0 = read_c0_entrylo0();
56 entrylo1 = read_c0_entrylo1();
57
58 /* Unused entries have a virtual address of CKSEG0. */
59 if ((entryhi & ~0x1ffffUL) != CKSEG0
60 && (entryhi & 0xff) == asid) {
61#ifdef CONFIG_32BIT
62 int width = 8;
63#else
64 int width = 11;
65#endif
66 /*
67 * Only print entries in use
68 */
69 printk("Index: %2d pgmask=%s ", i, msk2str(pagemask));
70
71 c0 = (entrylo0 >> 3) & 7;
72 c1 = (entrylo1 >> 3) & 7;
73
74 printk("va=%0*lx asid=%02lx\n",
75 width, (entryhi & ~0x1fffUL),
76 entryhi & 0xff);
77 printk("\t[pa=%0*llx c=%d d=%d v=%d g=%d] ",
78 width,
79 (entrylo0 << 6) & PAGE_MASK, c0,
80 (entrylo0 & 4) ? 1 : 0,
81 (entrylo0 & 2) ? 1 : 0,
82 (entrylo0 & 1) ? 1 : 0);
83 printk("[pa=%0*llx c=%d d=%d v=%d g=%d]\n",
84 width,
85 (entrylo1 << 6) & PAGE_MASK, c1,
86 (entrylo1 & 4) ? 1 : 0,
87 (entrylo1 & 2) ? 1 : 0,
88 (entrylo1 & 1) ? 1 : 0);
89 }
90 }
91 printk("\n");
92
93 write_c0_entryhi(s_entryhi);
94 write_c0_index(s_index);
95}
96
97void dump_tlb_all(void)
98{
99 dump_tlb(0, current_cpu_data.tlbsize - 1);
100}
diff --git a/arch/mips/lib/r3k_dump_tlb.c b/arch/mips/lib/r3k_dump_tlb.c
new file mode 100644
index 000000000000..52f87795ecc3
--- /dev/null
+++ b/arch/mips/lib/r3k_dump_tlb.c
@@ -0,0 +1,62 @@
1/*
2 * Dump R3000 TLB for debugging purposes.
3 *
4 * Copyright (C) 1994, 1995 by Waldorf Electronics, written by Ralf Baechle.
5 * Copyright (C) 1999 by Silicon Graphics, Inc.
6 * Copyright (C) 1999 by Harald Koerfgen
7 */
8#include <linux/kernel.h>
9#include <linux/mm.h>
10
11#include <asm/mipsregs.h>
12#include <asm/page.h>
13#include <asm/pgtable.h>
14
15extern int r3k_have_wired_reg; /* defined in tlb-r3k.c */
16
17static void dump_tlb(int first, int last)
18{
19 int i;
20 unsigned int asid;
21 unsigned long entryhi, entrylo0;
22
23 asid = read_c0_entryhi() & 0xfc0;
24
25 for (i = first; i <= last; i++) {
26 write_c0_index(i<<8);
27 __asm__ __volatile__(
28 ".set\tnoreorder\n\t"
29 "tlbr\n\t"
30 "nop\n\t"
31 ".set\treorder");
32 entryhi = read_c0_entryhi();
33 entrylo0 = read_c0_entrylo0();
34
35 /* Unused entries have a virtual address of KSEG0. */
36 if ((entryhi & 0xffffe000) != 0x80000000
37 && (entryhi & 0xfc0) == asid) {
38 /*
39 * Only print entries in use
40 */
41 printk("Index: %2d ", i);
42
43 printk("va=%08lx asid=%08lx"
44 " [pa=%06lx n=%d d=%d v=%d g=%d]",
45 (entryhi & 0xffffe000),
46 entryhi & 0xfc0,
47 entrylo0 & PAGE_MASK,
48 (entrylo0 & (1 << 11)) ? 1 : 0,
49 (entrylo0 & (1 << 10)) ? 1 : 0,
50 (entrylo0 & (1 << 9)) ? 1 : 0,
51 (entrylo0 & (1 << 8)) ? 1 : 0);
52 }
53 }
54 printk("\n");
55
56 write_c0_entryhi(asid);
57}
58
59void dump_tlb_all(void)
60{
61 dump_tlb(0, current_cpu_data.tlbsize - 1);
62}
diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c
index 80531b35cd61..d7f05b0abe17 100644
--- a/arch/mips/math-emu/cp1emu.c
+++ b/arch/mips/math-emu/cp1emu.c
@@ -35,6 +35,7 @@
35 * better performance by compiling with -msoft-float! 35 * better performance by compiling with -msoft-float!
36 */ 36 */
37#include <linux/sched.h> 37#include <linux/sched.h>
38#include <linux/debugfs.h>
38 39
39#include <asm/inst.h> 40#include <asm/inst.h>
40#include <asm/bootinfo.h> 41#include <asm/bootinfo.h>
@@ -1277,3 +1278,36 @@ int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
1277 1278
1278 return sig; 1279 return sig;
1279} 1280}
1281
1282#ifdef CONFIG_DEBUG_FS
1283extern struct dentry *mips_debugfs_dir;
1284static int __init debugfs_fpuemu(void)
1285{
1286 struct dentry *d, *dir;
1287 int i;
1288 static struct {
1289 const char *name;
1290 unsigned int *v;
1291 } vars[] __initdata = {
1292 { "emulated", &fpuemustats.emulated },
1293 { "loads", &fpuemustats.loads },
1294 { "stores", &fpuemustats.stores },
1295 { "cp1ops", &fpuemustats.cp1ops },
1296 { "cp1xops", &fpuemustats.cp1xops },
1297 { "errors", &fpuemustats.errors },
1298 };
1299
1300 if (!mips_debugfs_dir)
1301 return -ENODEV;
1302 dir = debugfs_create_dir("fpuemustats", mips_debugfs_dir);
1303 if (IS_ERR(dir))
1304 return PTR_ERR(dir);
1305 for (i = 0; i < ARRAY_SIZE(vars); i++) {
1306 d = debugfs_create_u32(vars[i].name, S_IRUGO, dir, vars[i].v);
1307 if (IS_ERR(d))
1308 return PTR_ERR(d);
1309 }
1310 return 0;
1311}
1312__initcall(debugfs_fpuemu);
1313#endif
diff --git a/arch/mips/mips-boards/malta/Makefile b/arch/mips/mips-boards/malta/Makefile
index 377d9e8f250a..a242b0fc377d 100644
--- a/arch/mips/mips-boards/malta/Makefile
+++ b/arch/mips/mips-boards/malta/Makefile
@@ -19,6 +19,7 @@
19# under Linux. 19# under Linux.
20# 20#
21 21
22obj-y := malta_int.o malta_setup.o 22obj-y := malta_int.o malta_platform.o malta_setup.o
23
23obj-$(CONFIG_MTD) += malta_mtd.o 24obj-$(CONFIG_MTD) += malta_mtd.o
24obj-$(CONFIG_MIPS_MT_SMTC) += malta_smtc.o 25obj-$(CONFIG_MIPS_MT_SMTC) += malta_smtc.o
diff --git a/arch/mips/mips-boards/malta/malta_platform.c b/arch/mips/mips-boards/malta/malta_platform.c
new file mode 100644
index 000000000000..83b9bab3cd3f
--- /dev/null
+++ b/arch/mips/mips-boards/malta/malta_platform.c
@@ -0,0 +1,65 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2007 MIPS Technologies, Inc.
7 * written by Ralf Baechle (ralf@linux-mips.org)
8 *
9 * Probe driver for the Malta's UART ports:
10 *
11 * o 2 ports in the SMC SuperIO
12 * o 1 port in the CBUS UART, a discrete 16550 which normally is only used
13 * for bringups.
14 *
15 * We don't use 8250_platform.c on Malta as it would result in the CBUS
16 * UART becoming ttyS0.
17 */
18#include <linux/module.h>
19#include <linux/init.h>
20#include <linux/serial_8250.h>
21
22#define SMC_PORT(base, int) \
23{ \
24 .iobase = base, \
25 .irq = int, \
26 .uartclk = 1843200, \
27 .iotype = UPIO_PORT, \
28 .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, \
29 .regshift = 0, \
30}
31
32#define CBUS_UART_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP)
33
34static struct plat_serial8250_port uart8250_data[] = {
35 SMC_PORT(0x3F8, 4),
36 SMC_PORT(0x2F8, 3),
37 {
38 .mapbase = 0x1f000900, /* The CBUS UART */
39 .irq = MIPS_CPU_IRQ_BASE + 2,
40 .uartclk = 3686400, /* Twice the usual clk! */
41 .iotype = UPIO_MEM32,
42 .flags = CBUS_UART_FLAGS,
43 .regshift = 3,
44 },
45 { },
46};
47
48static struct platform_device uart8250_device = {
49 .name = "serial8250",
50 .id = PLAT8250_DEV_PLATFORM2,
51 .dev = {
52 .platform_data = uart8250_data,
53 },
54};
55
56static int __init uart8250_init(void)
57{
58 return platform_device_register(&uart8250_device);
59}
60
61module_init(uart8250_init);
62
63MODULE_AUTHOR("Ralf Baechle <ralf@linux-mips.org>");
64MODULE_LICENSE("GPL");
65MODULE_DESCRIPTION("8250 UART probe driver for the Malta CBUS UART");
diff --git a/arch/mips/mips-boards/sim/Makefile b/arch/mips/mipssim/Makefile
index dc0bfda11427..dc0bfda11427 100644
--- a/arch/mips/mips-boards/sim/Makefile
+++ b/arch/mips/mipssim/Makefile
diff --git a/arch/mips/mips-boards/sim/sim_cmdline.c b/arch/mips/mipssim/sim_cmdline.c
index c63021a5dc6c..c63021a5dc6c 100644
--- a/arch/mips/mips-boards/sim/sim_cmdline.c
+++ b/arch/mips/mipssim/sim_cmdline.c
diff --git a/arch/mips/mips-boards/sim/sim_console.c b/arch/mips/mipssim/sim_console.c
index de595a9ccb27..a2f41672cd5d 100644
--- a/arch/mips/mips-boards/sim/sim_console.c
+++ b/arch/mips/mipssim/sim_console.c
@@ -18,8 +18,8 @@
18 * written by Ralf Baechle 18 * written by Ralf Baechle
19 */ 19 */
20#include <linux/init.h> 20#include <linux/init.h>
21#include <linux/io.h>
21#include <linux/serial_reg.h> 22#include <linux/serial_reg.h>
22#include <asm/io.h>
23 23
24static inline unsigned int serial_in(int offset) 24static inline unsigned int serial_in(int offset)
25{ 25{
diff --git a/arch/mips/mipssim/sim_int.c b/arch/mips/mipssim/sim_int.c
new file mode 100644
index 000000000000..d86b37235cf6
--- /dev/null
+++ b/arch/mips/mipssim/sim_int.c
@@ -0,0 +1,88 @@
1/*
2 * Copyright (C) 1999, 2005 MIPS Technologies, Inc. All rights reserved.
3 *
4 * This program is free software; you can distribute it and/or modify it
5 * under the terms of the GNU General Public License (Version 2) as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
11 * for more details.
12 *
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
16 *
17 */
18#include <linux/init.h>
19#include <linux/sched.h>
20#include <linux/slab.h>
21#include <linux/interrupt.h>
22#include <linux/kernel_stat.h>
23#include <asm/mips-boards/simint.h>
24#include <asm/irq_cpu.h>
25
26static inline int clz(unsigned long x)
27{
28 __asm__ (
29 " .set push \n"
30 " .set mips32 \n"
31 " clz %0, %1 \n"
32 " .set pop \n"
33 : "=r" (x)
34 : "r" (x));
35
36 return x;
37}
38
39/*
40 * Version of ffs that only looks at bits 12..15.
41 */
42static inline unsigned int irq_ffs(unsigned int pending)
43{
44#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
45 return -clz(pending) + 31 - CAUSEB_IP;
46#else
47 unsigned int a0 = 7;
48 unsigned int t0;
49
50 t0 = s0 & 0xf000;
51 t0 = t0 < 1;
52 t0 = t0 << 2;
53 a0 = a0 - t0;
54 s0 = s0 << t0;
55
56 t0 = s0 & 0xc000;
57 t0 = t0 < 1;
58 t0 = t0 << 1;
59 a0 = a0 - t0;
60 s0 = s0 << t0;
61
62 t0 = s0 & 0x8000;
63 t0 = t0 < 1;
64 /* t0 = t0 << 2; */
65 a0 = a0 - t0;
66 /* s0 = s0 << t0; */
67
68 return a0;
69#endif
70}
71
72asmlinkage void plat_irq_dispatch(void)
73{
74 unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
75 int irq;
76
77 irq = irq_ffs(pending);
78
79 if (irq > 0)
80 do_IRQ(MIPSCPU_INT_BASE + irq);
81 else
82 spurious_interrupt();
83}
84
85void __init arch_init_irq(void)
86{
87 mips_cpu_irq_init();
88}
diff --git a/arch/mips/mips-boards/sim/sim_mem.c b/arch/mips/mipssim/sim_mem.c
index e408ef0bcd6e..2312483eb838 100644
--- a/arch/mips/mips-boards/sim/sim_mem.c
+++ b/arch/mips/mipssim/sim_mem.c
@@ -95,7 +95,7 @@ void __init prom_meminit(void)
95 size = p->size; 95 size = p->size;
96 96
97 add_memory_region(base, size, type); 97 add_memory_region(base, size, type);
98 p++; 98 p++;
99 } 99 }
100} 100}
101 101
diff --git a/arch/mips/mips-boards/sim/sim_platform.c b/arch/mips/mipssim/sim_platform.c
index 53210a8c5dec..53210a8c5dec 100644
--- a/arch/mips/mips-boards/sim/sim_platform.c
+++ b/arch/mips/mipssim/sim_platform.c
diff --git a/arch/mips/mips-boards/sim/sim_setup.c b/arch/mips/mipssim/sim_setup.c
index b705f09e57c3..3643582bdade 100644
--- a/arch/mips/mips-boards/sim/sim_setup.c
+++ b/arch/mips/mipssim/sim_setup.c
@@ -19,18 +19,18 @@
19#include <linux/init.h> 19#include <linux/init.h>
20#include <linux/string.h> 20#include <linux/string.h>
21#include <linux/kernel.h> 21#include <linux/kernel.h>
22#include <linux/io.h>
23#include <linux/irq.h>
22#include <linux/ioport.h> 24#include <linux/ioport.h>
25#include <linux/serial.h>
23#include <linux/tty.h> 26#include <linux/tty.h>
24#include <linux/serial.h> 27#include <linux/serial.h>
25#include <linux/serial_core.h> 28#include <linux/serial_core.h>
26 29
27#include <asm/cpu.h> 30#include <asm/cpu.h>
28#include <asm/bootinfo.h> 31#include <asm/bootinfo.h>
29#include <asm/irq.h>
30#include <asm/mips-boards/generic.h> 32#include <asm/mips-boards/generic.h>
31#include <asm/mips-boards/prom.h> 33#include <asm/mips-boards/prom.h>
32#include <asm/serial.h>
33#include <asm/io.h>
34#include <asm/time.h> 34#include <asm/time.h>
35#include <asm/mips-boards/sim.h> 35#include <asm/mips-boards/sim.h>
36#include <asm/mips-boards/simint.h> 36#include <asm/mips-boards/simint.h>
@@ -62,7 +62,7 @@ void __init plat_mem_setup(void)
62#endif 62#endif
63} 63}
64 64
65void prom_init(void) 65void __init prom_init(void)
66{ 66{
67 set_io_port_base(0xbfd00000); 67 set_io_port_base(0xbfd00000);
68 68
diff --git a/arch/mips/mips-boards/sim/sim_smp.c b/arch/mips/mipssim/sim_smp.c
index cb47863ecf10..38fa807b99f9 100644
--- a/arch/mips/mips-boards/sim/sim_smp.c
+++ b/arch/mips/mipssim/sim_smp.c
@@ -22,13 +22,13 @@
22#include <linux/sched.h> 22#include <linux/sched.h>
23#include <linux/cpumask.h> 23#include <linux/cpumask.h>
24#include <linux/interrupt.h> 24#include <linux/interrupt.h>
25#include <linux/smp.h>
26
25#include <asm/atomic.h> 27#include <asm/atomic.h>
26#include <asm/cpu.h> 28#include <asm/cpu.h>
27#include <asm/processor.h> 29#include <asm/processor.h>
28#include <asm/system.h> 30#include <asm/system.h>
29#include <asm/hardirq.h>
30#include <asm/mmu_context.h> 31#include <asm/mmu_context.h>
31#include <asm/smp.h>
32#ifdef CONFIG_MIPS_MT_SMTC 32#ifdef CONFIG_MIPS_MT_SMTC
33#include <asm/smtc_ipi.h> 33#include <asm/smtc_ipi.h>
34#endif /* CONFIG_MIPS_MT_SMTC */ 34#endif /* CONFIG_MIPS_MT_SMTC */
@@ -73,11 +73,19 @@ void prom_init_secondary(void)
73#endif /* CONFIG_MIPS_MT_SMTC */ 73#endif /* CONFIG_MIPS_MT_SMTC */
74} 74}
75 75
76void plat_smp_setup(void)
77{
78#ifdef CONFIG_MIPS_MT_SMTC
79 if (read_c0_config3() & (1 << 2))
80 mipsmt_build_cpu_map(0);
81#endif /* CONFIG_MIPS_MT_SMTC */
82}
83
76/* 84/*
77 * Platform SMP pre-initialization 85 * Platform SMP pre-initialization
78 */ 86 */
79 87
80void prom_prepare_cpus(unsigned int max_cpus) 88void plat_prepare_cpus(unsigned int max_cpus)
81{ 89{
82#ifdef CONFIG_MIPS_MT_SMTC 90#ifdef CONFIG_MIPS_MT_SMTC
83 /* 91 /*
@@ -85,8 +93,8 @@ void prom_prepare_cpus(unsigned int max_cpus)
85 * but it may be multithreaded. 93 * but it may be multithreaded.
86 */ 94 */
87 95
88 if (read_c0_config3() & (1<<2)) { 96 if (read_c0_config3() & (1 << 2)) {
89 mipsmt_prepare_cpus(max_cpus); 97 mipsmt_prepare_cpus();
90 } 98 }
91#endif /* CONFIG_MIPS_MT_SMTC */ 99#endif /* CONFIG_MIPS_MT_SMTC */
92} 100}
diff --git a/arch/mips/mips-boards/sim/sim_time.c b/arch/mips/mipssim/sim_time.c
index 7224ffe31d36..874a18e8ac24 100644
--- a/arch/mips/mips-boards/sim/sim_time.c
+++ b/arch/mips/mipssim/sim_time.c
@@ -5,10 +5,10 @@
5#include <linux/spinlock.h> 5#include <linux/spinlock.h>
6#include <linux/interrupt.h> 6#include <linux/interrupt.h>
7#include <linux/mc146818rtc.h> 7#include <linux/mc146818rtc.h>
8#include <linux/mipsregs.h>
9#include <linux/smp.h>
8#include <linux/timex.h> 10#include <linux/timex.h>
9 11
10#include <asm/mipsregs.h>
11#include <asm/ptrace.h>
12#include <asm/hardirq.h> 12#include <asm/hardirq.h>
13#include <asm/div64.h> 13#include <asm/div64.h>
14#include <asm/cpu.h> 14#include <asm/cpu.h>
@@ -16,7 +16,6 @@
16#include <asm/irq.h> 16#include <asm/irq.h>
17#include <asm/mc146818-time.h> 17#include <asm/mc146818-time.h>
18#include <asm/msc01_ic.h> 18#include <asm/msc01_ic.h>
19#include <asm/smp.h>
20 19
21#include <asm/mips-boards/generic.h> 20#include <asm/mips-boards/generic.h>
22#include <asm/mips-boards/prom.h> 21#include <asm/mips-boards/prom.h>
@@ -37,8 +36,7 @@ irqreturn_t sim_timer_interrupt(int irq, void *dev_id)
37#ifndef CONFIG_MIPS_MT_SMTC 36#ifndef CONFIG_MIPS_MT_SMTC
38 if (cpu == 0) { 37 if (cpu == 0) {
39 timer_interrupt(irq, dev_id); 38 timer_interrupt(irq, dev_id);
40 } 39 } else {
41 else {
42 /* Everyone else needs to reset the timer int here as 40 /* Everyone else needs to reset the timer int here as
43 ll_local_timer_interrupt doesn't */ 41 ll_local_timer_interrupt doesn't */
44 /* 42 /*
@@ -76,8 +74,10 @@ irqreturn_t sim_timer_interrupt(int irq, void *dev_id)
76 irq_enable_hazard(); 74 irq_enable_hazard();
77 evpe(vpflags); 75 evpe(vpflags);
78 76
79 if(cpu_data[cpu].vpe_id == 0) timer_interrupt(irq, dev_id); 77 if (cpu_data[cpu].vpe_id == 0)
80 else write_c0_compare (read_c0_count() + ( mips_hpt_frequency/HZ)); 78 timer_interrupt(irq, dev_id);
79 else
80 write_c0_compare (read_c0_count() + ( mips_hpt_frequency/HZ));
81 smtc_timer_broadcast(cpu_data[cpu].vpe_id); 81 smtc_timer_broadcast(cpu_data[cpu].vpe_id);
82 82
83#endif /* CONFIG_MIPS_MT_SMTC */ 83#endif /* CONFIG_MIPS_MT_SMTC */
@@ -85,7 +85,8 @@ irqreturn_t sim_timer_interrupt(int irq, void *dev_id)
85 /* 85 /*
86 * every CPU should do profiling and process accounting 86 * every CPU should do profiling and process accounting
87 */ 87 */
88 local_timer_interrupt (irq, dev_id); 88 local_timer_interrupt (irq, dev_id);
89
89 return IRQ_HANDLED; 90 return IRQ_HANDLED;
90#else 91#else
91 return timer_interrupt (irq, dev_id); 92 return timer_interrupt (irq, dev_id);
@@ -152,17 +153,15 @@ void __init sim_time_init(void)
152 153
153 local_irq_save(flags); 154 local_irq_save(flags);
154 155
155 156 /* Set Data mode - binary. */
156 /* Set Data mode - binary. */
157 CMOS_WRITE(CMOS_READ(RTC_CONTROL) | RTC_DM_BINARY, RTC_CONTROL); 157 CMOS_WRITE(CMOS_READ(RTC_CONTROL) | RTC_DM_BINARY, RTC_CONTROL);
158 158
159
160 est_freq = estimate_cpu_frequency (); 159 est_freq = estimate_cpu_frequency ();
161 160
162 printk("CPU frequency %d.%02d MHz\n", est_freq/1000000, 161 printk(KERN_INFO "CPU frequency %d.%02d MHz\n", est_freq / 1000000,
163 (est_freq%1000000)*100/1000000); 162 (est_freq % 1000000) * 100 / 1000000);
164 163
165 cpu_khz = est_freq / 1000; 164 cpu_khz = est_freq / 1000;
166 165
167 local_irq_restore(flags); 166 local_irq_restore(flags);
168} 167}
@@ -180,8 +179,7 @@ void __init plat_timer_setup(struct irqaction *irq)
180 if (cpu_has_veic) { 179 if (cpu_has_veic) {
181 set_vi_handler(MSC01E_INT_CPUCTR, mips_timer_dispatch); 180 set_vi_handler(MSC01E_INT_CPUCTR, mips_timer_dispatch);
182 mips_cpu_timer_irq = MSC01E_INT_BASE + MSC01E_INT_CPUCTR; 181 mips_cpu_timer_irq = MSC01E_INT_BASE + MSC01E_INT_CPUCTR;
183 } 182 } else {
184 else {
185 if (cpu_has_vint) 183 if (cpu_has_vint)
186 set_vi_handler(cp0_compare_irq, mips_timer_dispatch); 184 set_vi_handler(cp0_compare_irq, mips_timer_dispatch);
187 mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq; 185 mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq;
diff --git a/arch/mips/mm/Makefile b/arch/mips/mm/Makefile
index 293697b15603..19a0e544c4e9 100644
--- a/arch/mips/mm/Makefile
+++ b/arch/mips/mm/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_32BIT) += ioremap.o pgtable-32.o
9obj-$(CONFIG_64BIT) += pgtable-64.o 9obj-$(CONFIG_64BIT) += pgtable-64.o
10obj-$(CONFIG_HIGHMEM) += highmem.o 10obj-$(CONFIG_HIGHMEM) += highmem.o
11 11
12obj-$(CONFIG_CPU_LOONGSON2) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o
12obj-$(CONFIG_CPU_MIPS32) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o 13obj-$(CONFIG_CPU_MIPS32) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o
13obj-$(CONFIG_CPU_MIPS64) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o 14obj-$(CONFIG_CPU_MIPS64) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o
14obj-$(CONFIG_CPU_NEVADA) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o 15obj-$(CONFIG_CPU_NEVADA) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
index df04a315d830..be96231dccb6 100644
--- a/arch/mips/mm/c-r4k.c
+++ b/arch/mips/mm/c-r4k.c
@@ -335,6 +335,10 @@ static void r4k_flush_cache_all(void)
335 335
336static inline void local_r4k___flush_cache_all(void * args) 336static inline void local_r4k___flush_cache_all(void * args)
337{ 337{
338#if defined(CONFIG_CPU_LOONGSON2)
339 r4k_blast_scache();
340 return;
341#endif
338 r4k_blast_dcache(); 342 r4k_blast_dcache();
339 r4k_blast_icache(); 343 r4k_blast_icache();
340 344
@@ -848,6 +852,24 @@ static void __init probe_pcache(void)
848 c->options |= MIPS_CPU_PREFETCH; 852 c->options |= MIPS_CPU_PREFETCH;
849 break; 853 break;
850 854
855 case CPU_LOONGSON2:
856 icache_size = 1 << (12 + ((config & CONF_IC) >> 9));
857 c->icache.linesz = 16 << ((config & CONF_IB) >> 5);
858 if (prid & 0x3)
859 c->icache.ways = 4;
860 else
861 c->icache.ways = 2;
862 c->icache.waybit = 0;
863
864 dcache_size = 1 << (12 + ((config & CONF_DC) >> 6));
865 c->dcache.linesz = 16 << ((config & CONF_DB) >> 4);
866 if (prid & 0x3)
867 c->dcache.ways = 4;
868 else
869 c->dcache.ways = 2;
870 c->dcache.waybit = 0;
871 break;
872
851 default: 873 default:
852 if (!(config & MIPS_CONF_M)) 874 if (!(config & MIPS_CONF_M))
853 panic("Don't know how to probe P-caches on this cpu."); 875 panic("Don't know how to probe P-caches on this cpu.");
@@ -963,6 +985,14 @@ static void __init probe_pcache(void)
963 break; 985 break;
964 } 986 }
965 987
988#ifdef CONFIG_CPU_LOONGSON2
989 /*
990 * LOONGSON2 has 4 way icache, but when using indexed cache op,
991 * one op will act on all 4 ways
992 */
993 c->icache.ways = 1;
994#endif
995
966 printk("Primary instruction cache %ldkB, %s, %s, linesize %d bytes.\n", 996 printk("Primary instruction cache %ldkB, %s, %s, linesize %d bytes.\n",
967 icache_size >> 10, 997 icache_size >> 10,
968 cpu_has_vtag_icache ? "virtually tagged" : "physically tagged", 998 cpu_has_vtag_icache ? "virtually tagged" : "physically tagged",
@@ -1036,6 +1066,24 @@ static int __init probe_scache(void)
1036 return 1; 1066 return 1;
1037} 1067}
1038 1068
1069#if defined(CONFIG_CPU_LOONGSON2)
1070static void __init loongson2_sc_init(void)
1071{
1072 struct cpuinfo_mips *c = &current_cpu_data;
1073
1074 scache_size = 512*1024;
1075 c->scache.linesz = 32;
1076 c->scache.ways = 4;
1077 c->scache.waybit = 0;
1078 c->scache.waysize = scache_size / (c->scache.ways);
1079 c->scache.sets = scache_size / (c->scache.linesz * c->scache.ways);
1080 pr_info("Unified secondary cache %ldkB %s, linesize %d bytes.\n",
1081 scache_size >> 10, way_string[c->scache.ways], c->scache.linesz);
1082
1083 c->options |= MIPS_CPU_INCLUSIVE_CACHES;
1084}
1085#endif
1086
1039extern int r5k_sc_init(void); 1087extern int r5k_sc_init(void);
1040extern int rm7k_sc_init(void); 1088extern int rm7k_sc_init(void);
1041extern int mips_sc_init(void); 1089extern int mips_sc_init(void);
@@ -1085,6 +1133,12 @@ static void __init setup_scache(void)
1085#endif 1133#endif
1086 return; 1134 return;
1087 1135
1136#if defined(CONFIG_CPU_LOONGSON2)
1137 case CPU_LOONGSON2:
1138 loongson2_sc_init();
1139 return;
1140#endif
1141
1088 default: 1142 default:
1089 if (c->isa_level == MIPS_CPU_ISA_M32R1 || 1143 if (c->isa_level == MIPS_CPU_ISA_M32R1 ||
1090 c->isa_level == MIPS_CPU_ISA_M32R2 || 1144 c->isa_level == MIPS_CPU_ISA_M32R2 ||
diff --git a/arch/mips/mm/c-sb1.c b/arch/mips/mm/c-sb1.c
index 9ea460b16bda..6f9bd7fbd481 100644
--- a/arch/mips/mm/c-sb1.c
+++ b/arch/mips/mm/c-sb1.c
@@ -476,7 +476,7 @@ static __init void probe_cache_sizes(void)
476 * memory management function pointers, as well as initialize 476 * memory management function pointers, as well as initialize
477 * the caches and tlbs 477 * the caches and tlbs
478 */ 478 */
479void sb1_cache_init(void) 479void __init sb1_cache_init(void)
480{ 480{
481 extern char except_vec2_sb1; 481 extern char except_vec2_sb1;
482 482
diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c
index abf99b1eba13..81f925a9a731 100644
--- a/arch/mips/mm/cache.c
+++ b/arch/mips/mm/cache.c
@@ -6,6 +6,8 @@
6 * Copyright (C) 1994 - 2003, 07 by Ralf Baechle (ralf@linux-mips.org) 6 * Copyright (C) 1994 - 2003, 07 by Ralf Baechle (ralf@linux-mips.org)
7 * Copyright (C) 2007 MIPS Technologies, Inc. 7 * Copyright (C) 2007 MIPS Technologies, Inc.
8 */ 8 */
9#include <linux/fs.h>
10#include <linux/fcntl.h>
9#include <linux/init.h> 11#include <linux/init.h>
10#include <linux/kernel.h> 12#include <linux/kernel.h>
11#include <linux/module.h> 13#include <linux/module.h>
@@ -164,3 +166,11 @@ void __init cpu_cache_init(void)
164 166
165 panic(cache_panic); 167 panic(cache_panic);
166} 168}
169
170int __weak __uncached_access(struct file *file, unsigned long addr)
171{
172 if (file->f_flags & O_SYNC)
173 return 1;
174
175 return addr >= __pa(high_memory);
176}
diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c
index 65160d4984d9..dcd6913dc1ff 100644
--- a/arch/mips/mm/tlb-r4k.c
+++ b/arch/mips/mm/tlb-r4k.c
@@ -48,6 +48,22 @@ extern void build_tlb_refill_handler(void);
48 48
49#endif /* CONFIG_MIPS_MT_SMTC */ 49#endif /* CONFIG_MIPS_MT_SMTC */
50 50
51#if defined(CONFIG_CPU_LOONGSON2)
52/*
53 * LOONGSON2 has a 4 entry itlb which is a subset of dtlb,
54 * unfortrunately, itlb is not totally transparent to software.
55 */
56#define FLUSH_ITLB write_c0_diag(4);
57
58#define FLUSH_ITLB_VM(vma) { if ((vma)->vm_flags & VM_EXEC) write_c0_diag(4); }
59
60#else
61
62#define FLUSH_ITLB
63#define FLUSH_ITLB_VM(vma)
64
65#endif
66
51void local_flush_tlb_all(void) 67void local_flush_tlb_all(void)
52{ 68{
53 unsigned long flags; 69 unsigned long flags;
@@ -73,6 +89,7 @@ void local_flush_tlb_all(void)
73 } 89 }
74 tlbw_use_hazard(); 90 tlbw_use_hazard();
75 write_c0_entryhi(old_ctx); 91 write_c0_entryhi(old_ctx);
92 FLUSH_ITLB;
76 EXIT_CRITICAL(flags); 93 EXIT_CRITICAL(flags);
77} 94}
78 95
@@ -136,6 +153,7 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
136 } else { 153 } else {
137 drop_mmu_context(mm, cpu); 154 drop_mmu_context(mm, cpu);
138 } 155 }
156 FLUSH_ITLB;
139 EXIT_CRITICAL(flags); 157 EXIT_CRITICAL(flags);
140 } 158 }
141} 159}
@@ -178,6 +196,7 @@ void local_flush_tlb_kernel_range(unsigned long start, unsigned long end)
178 } else { 196 } else {
179 local_flush_tlb_all(); 197 local_flush_tlb_all();
180 } 198 }
199 FLUSH_ITLB;
181 EXIT_CRITICAL(flags); 200 EXIT_CRITICAL(flags);
182} 201}
183 202
@@ -210,6 +229,7 @@ void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
210 229
211 finish: 230 finish:
212 write_c0_entryhi(oldpid); 231 write_c0_entryhi(oldpid);
232 FLUSH_ITLB_VM(vma);
213 EXIT_CRITICAL(flags); 233 EXIT_CRITICAL(flags);
214 } 234 }
215} 235}
@@ -241,7 +261,7 @@ void local_flush_tlb_one(unsigned long page)
241 tlbw_use_hazard(); 261 tlbw_use_hazard();
242 } 262 }
243 write_c0_entryhi(oldpid); 263 write_c0_entryhi(oldpid);
244 264 FLUSH_ITLB;
245 EXIT_CRITICAL(flags); 265 EXIT_CRITICAL(flags);
246} 266}
247 267
@@ -293,6 +313,7 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte)
293 else 313 else
294 tlb_write_indexed(); 314 tlb_write_indexed();
295 tlbw_use_hazard(); 315 tlbw_use_hazard();
316 FLUSH_ITLB_VM(vma);
296 EXIT_CRITICAL(flags); 317 EXIT_CRITICAL(flags);
297} 318}
298 319
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c
index e7149290d1cb..4ec0964b8394 100644
--- a/arch/mips/mm/tlbex.c
+++ b/arch/mips/mm/tlbex.c
@@ -893,6 +893,7 @@ static __init void build_tlb_write_entry(u32 **p, struct label **l,
893 case CPU_4KSC: 893 case CPU_4KSC:
894 case CPU_20KC: 894 case CPU_20KC:
895 case CPU_25KF: 895 case CPU_25KF:
896 case CPU_LOONGSON2:
896 tlbw(p); 897 tlbw(p);
897 break; 898 break;
898 899
@@ -1276,7 +1277,8 @@ static void __init build_r4000_tlb_refill_handler(void)
1276 * need three, with the second nop'ed and the third being 1277 * need three, with the second nop'ed and the third being
1277 * unused. 1278 * unused.
1278 */ 1279 */
1279#ifdef CONFIG_32BIT 1280 /* Loongson2 ebase is different than r4k, we have more space */
1281#if defined(CONFIG_32BIT) || defined(CONFIG_CPU_LOONGSON2)
1280 if ((p - tlb_handler) > 64) 1282 if ((p - tlb_handler) > 64)
1281 panic("TLB refill handler space exceeded"); 1283 panic("TLB refill handler space exceeded");
1282#else 1284#else
@@ -1289,7 +1291,7 @@ static void __init build_r4000_tlb_refill_handler(void)
1289 /* 1291 /*
1290 * Now fold the handler in the TLB refill handler space. 1292 * Now fold the handler in the TLB refill handler space.
1291 */ 1293 */
1292#ifdef CONFIG_32BIT 1294#if defined(CONFIG_32BIT) || defined(CONFIG_CPU_LOONGSON2)
1293 f = final_handler; 1295 f = final_handler;
1294 /* Simplest case, just copy the handler. */ 1296 /* Simplest case, just copy the handler. */
1295 copy_handler(relocs, labels, tlb_handler, p, f); 1297 copy_handler(relocs, labels, tlb_handler, p, f);
@@ -1336,7 +1338,7 @@ static void __init build_r4000_tlb_refill_handler(void)
1336 final_len); 1338 final_len);
1337 1339
1338 f = final_handler; 1340 f = final_handler;
1339#ifdef CONFIG_64BIT 1341#if defined(CONFIG_64BIT) && !defined(CONFIG_CPU_LOONGSON2)
1340 if (final_len > 32) 1342 if (final_len > 32)
1341 final_len = 64; 1343 final_len = 64;
1342 else 1344 else
diff --git a/arch/mips/momentum/ocelot_3/Makefile b/arch/mips/momentum/ocelot_3/Makefile
deleted file mode 100644
index d5a090a85a15..000000000000
--- a/arch/mips/momentum/ocelot_3/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
1#
2# Makefile for Momentum Computer's Ocelot-3 board.
3#
4# Note! Dependencies are done automagically by 'make dep', which also
5# removes any old dependencies. DON'T put your own dependencies here
6# unless it's something special (ie not a .c file).
7#
8obj-y += irq.o platform.o prom.o reset.o setup.o
diff --git a/arch/mips/momentum/ocelot_3/irq.c b/arch/mips/momentum/ocelot_3/irq.c
deleted file mode 100644
index 3862d1d1add4..000000000000
--- a/arch/mips/momentum/ocelot_3/irq.c
+++ /dev/null
@@ -1,109 +0,0 @@
1/*
2 * Copyright (C) 2000 RidgeRun, Inc.
3 * Author: RidgeRun, Inc.
4 * glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com
5 *
6 * Copyright 2001 MontaVista Software Inc.
7 * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
8 * Copyright (C) 2000, 2001 Ralf Baechle (ralf@gnu.org)
9 *
10 * Copyright 2004 PMC-Sierra
11 * Author: Manish Lachwani (lachwani@pmc-sierra.com)
12 *
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by the
15 * Free Software Foundation; either version 2 of the License, or (at your
16 * option) any later version.
17 *
18 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
19 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
20 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
21 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
24 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
25 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 *
29 * You should have received a copy of the GNU General Public License along
30 * with this program; if not, write to the Free Software Foundation, Inc.,
31 * 675 Mass Ave, Cambridge, MA 02139, USA.
32 *
33 * Copyright (C) 2004 MontaVista Software Inc.
34 * Author: Manish Lachwani, mlachwani@mvista.com
35 *
36 */
37#include <linux/errno.h>
38#include <linux/init.h>
39#include <linux/kernel_stat.h>
40#include <linux/module.h>
41#include <linux/signal.h>
42#include <linux/sched.h>
43#include <linux/types.h>
44#include <linux/interrupt.h>
45#include <linux/ioport.h>
46#include <linux/timex.h>
47#include <linux/slab.h>
48#include <linux/random.h>
49#include <asm/bitops.h>
50#include <asm/bootinfo.h>
51#include <asm/io.h>
52#include <asm/irq.h>
53#include <asm/mipsregs.h>
54#include <asm/system.h>
55
56static struct irqaction cascade_mv64340 = {
57 no_action, IRQF_DISABLED, CPU_MASK_NONE, "MV64340-Cascade", NULL, NULL
58};
59
60void __init arch_init_irq(void)
61{
62 /*
63 * Clear all of the interrupts while we change the able around a bit.
64 * int-handler is not on bootstrap
65 */
66 clear_c0_status(ST0_IM | ST0_BEV);
67
68 rm7k_cpu_irq_init();
69
70 /* set up the cascading interrupts */
71 setup_irq(8, &cascade_mv64340); /* unmask intControl IM8, IRQ 9 */
72 mv64340_irq_init(16);
73
74 set_c0_status(ST0_IM); /* IE in the status register */
75
76}
77
78asmlinkage void plat_irq_dispatch(void)
79{
80 unsigned int pending = read_c0_cause() & read_c0_status();
81
82 if (pending & STATUSF_IP0)
83 do_IRQ(0);
84 else if (pending & STATUSF_IP1)
85 do_IRQ(1);
86 else if (pending & STATUSF_IP2)
87 do_IRQ(2);
88 else if (pending & STATUSF_IP3)
89 do_IRQ(3);
90 else if (pending & STATUSF_IP4)
91 do_IRQ(4);
92 else if (pending & STATUSF_IP5)
93 do_IRQ(5);
94 else if (pending & STATUSF_IP6)
95 do_IRQ(6);
96 else if (pending & STATUSF_IP7)
97 do_IRQ(7);
98 else {
99 /*
100 * Now look at the extended interrupts
101 */
102 pending = (read_c0_cause() & (read_c0_intcontrol() << 8)) >> 16;
103
104 if (pending & STATUSF_IP8)
105 ll_mv64340_irq();
106 else
107 spurious_interrupt();
108 }
109}
diff --git a/arch/mips/momentum/ocelot_3/platform.c b/arch/mips/momentum/ocelot_3/platform.c
deleted file mode 100644
index 44e4c3fc7403..000000000000
--- a/arch/mips/momentum/ocelot_3/platform.c
+++ /dev/null
@@ -1,208 +0,0 @@
1#include <linux/delay.h>
2#include <linux/if_ether.h>
3#include <linux/ioport.h>
4#include <linux/mv643xx.h>
5#include <linux/platform_device.h>
6
7#include "ocelot_3_fpga.h"
8
9#if defined(CONFIG_MV643XX_ETH) || defined(CONFIG_MV643XX_ETH_MODULE)
10
11static struct resource mv643xx_eth_shared_resources[] = {
12 [0] = {
13 .name = "ethernet shared base",
14 .start = 0xf1000000 + MV643XX_ETH_SHARED_REGS,
15 .end = 0xf1000000 + MV643XX_ETH_SHARED_REGS +
16 MV643XX_ETH_SHARED_REGS_SIZE - 1,
17 .flags = IORESOURCE_MEM,
18 },
19};
20
21static struct platform_device mv643xx_eth_shared_device = {
22 .name = MV643XX_ETH_SHARED_NAME,
23 .id = 0,
24 .num_resources = ARRAY_SIZE(mv643xx_eth_shared_resources),
25 .resource = mv643xx_eth_shared_resources,
26};
27
28#define MV_SRAM_BASE 0xfe000000UL
29#define MV_SRAM_SIZE (256 * 1024)
30
31#define MV_SRAM_RXRING_SIZE (MV_SRAM_SIZE / 4)
32#define MV_SRAM_TXRING_SIZE (MV_SRAM_SIZE / 4)
33
34#define MV_SRAM_BASE_ETH0 MV_SRAM_BASE
35#define MV_SRAM_BASE_ETH1 (MV_SRAM_BASE + (MV_SRAM_SIZE / 2))
36
37#define MV64x60_IRQ_ETH_0 48
38#define MV64x60_IRQ_ETH_1 49
39#define MV64x60_IRQ_ETH_2 50
40
41static struct resource mv64x60_eth0_resources[] = {
42 [0] = {
43 .name = "eth0 irq",
44 .start = MV64x60_IRQ_ETH_0,
45 .end = MV64x60_IRQ_ETH_0,
46 .flags = IORESOURCE_IRQ,
47 },
48};
49
50static struct mv643xx_eth_platform_data eth0_pd = {
51 .port_number = 0,
52
53 .tx_sram_addr = MV_SRAM_BASE_ETH0,
54 .tx_sram_size = MV_SRAM_TXRING_SIZE,
55 .tx_queue_size = MV_SRAM_TXRING_SIZE / 16,
56
57 .rx_sram_addr = MV_SRAM_BASE_ETH0 + MV_SRAM_TXRING_SIZE,
58 .rx_sram_size = MV_SRAM_RXRING_SIZE,
59 .rx_queue_size = MV_SRAM_RXRING_SIZE / 16,
60};
61
62static struct platform_device eth0_device = {
63 .name = MV643XX_ETH_NAME,
64 .id = 0,
65 .num_resources = ARRAY_SIZE(mv64x60_eth0_resources),
66 .resource = mv64x60_eth0_resources,
67 .dev = {
68 .platform_data = &eth0_pd,
69 },
70};
71
72static struct resource mv64x60_eth1_resources[] = {
73 [0] = {
74 .name = "eth1 irq",
75 .start = MV64x60_IRQ_ETH_1,
76 .end = MV64x60_IRQ_ETH_1,
77 .flags = IORESOURCE_IRQ,
78 },
79};
80
81static struct mv643xx_eth_platform_data eth1_pd = {
82 .port_number = 1,
83
84 .tx_sram_addr = MV_SRAM_BASE_ETH1,
85 .tx_sram_size = MV_SRAM_TXRING_SIZE,
86 .tx_queue_size = MV_SRAM_TXRING_SIZE / 16,
87
88 .rx_sram_addr = MV_SRAM_BASE_ETH1 + MV_SRAM_TXRING_SIZE,
89 .rx_sram_size = MV_SRAM_RXRING_SIZE,
90 .rx_queue_size = MV_SRAM_RXRING_SIZE / 16,
91};
92
93static struct platform_device eth1_device = {
94 .name = MV643XX_ETH_NAME,
95 .id = 1,
96 .num_resources = ARRAY_SIZE(mv64x60_eth1_resources),
97 .resource = mv64x60_eth1_resources,
98 .dev = {
99 .platform_data = &eth1_pd,
100 },
101};
102
103static struct resource mv64x60_eth2_resources[] = {
104 [0] = {
105 .name = "eth2 irq",
106 .start = MV64x60_IRQ_ETH_2,
107 .end = MV64x60_IRQ_ETH_2,
108 .flags = IORESOURCE_IRQ,
109 },
110};
111
112static struct mv643xx_eth_platform_data eth2_pd = {
113 .port_number = 2,
114};
115
116static struct platform_device eth2_device = {
117 .name = MV643XX_ETH_NAME,
118 .id = 2,
119 .num_resources = ARRAY_SIZE(mv64x60_eth2_resources),
120 .resource = mv64x60_eth2_resources,
121 .dev = {
122 .platform_data = &eth2_pd,
123 },
124};
125
126static struct platform_device *mv643xx_eth_pd_devs[] __initdata = {
127 &mv643xx_eth_shared_device,
128 &eth0_device,
129 &eth1_device,
130 &eth2_device,
131};
132
133static u8 __init exchange_bit(u8 val, u8 cs)
134{
135 /* place the data */
136 OCELOT_FPGA_WRITE((val << 2) | cs, EEPROM_MODE);
137 udelay(1);
138
139 /* turn the clock on */
140 OCELOT_FPGA_WRITE((val << 2) | cs | 0x2, EEPROM_MODE);
141 udelay(1);
142
143 /* turn the clock off and read-strobe */
144 OCELOT_FPGA_WRITE((val << 2) | cs | 0x10, EEPROM_MODE);
145
146 /* return the data */
147 return (OCELOT_FPGA_READ(EEPROM_MODE) >> 3) & 0x1;
148}
149
150static void __init get_mac(char dest[6])
151{
152 u8 read_opcode[12] = {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
153 int i,j;
154
155 for (i = 0; i < 12; i++)
156 exchange_bit(read_opcode[i], 1);
157
158 for (j = 0; j < 6; j++) {
159 dest[j] = 0;
160 for (i = 0; i < 8; i++) {
161 dest[j] <<= 1;
162 dest[j] |= exchange_bit(0, 1);
163 }
164 }
165
166 /* turn off CS */
167 exchange_bit(0,0);
168}
169
170/*
171 * Copy and increment ethernet MAC address by a small value.
172 *
173 * This is useful for systems where the only one MAC address is stored in
174 * non-volatile memory for multiple ports.
175 */
176static inline void eth_mac_add(unsigned char *dst, unsigned char *src,
177 unsigned int add)
178{
179 int i;
180
181 BUG_ON(add >= 256);
182
183 for (i = ETH_ALEN; i >= 0; i--) {
184 dst[i] = src[i] + add;
185 add = dst[i] < src[i]; /* compute carry */
186 }
187
188 WARN_ON(add);
189}
190
191static int __init mv643xx_eth_add_pds(void)
192{
193 unsigned char mac[ETH_ALEN];
194 int ret;
195
196 get_mac(mac);
197 eth_mac_add(eth0_pd.mac_addr, mac, 0);
198 eth_mac_add(eth1_pd.mac_addr, mac, 1);
199 eth_mac_add(eth2_pd.mac_addr, mac, 2);
200 ret = platform_add_devices(mv643xx_eth_pd_devs,
201 ARRAY_SIZE(mv643xx_eth_pd_devs));
202
203 return ret;
204}
205
206device_initcall(mv643xx_eth_add_pds);
207
208#endif /* defined(CONFIG_MV643XX_ETH) || defined(CONFIG_MV643XX_ETH_MODULE) */
diff --git a/arch/mips/momentum/ocelot_3/prom.c b/arch/mips/momentum/ocelot_3/prom.c
deleted file mode 100644
index 8e02df63578a..000000000000
--- a/arch/mips/momentum/ocelot_3/prom.c
+++ /dev/null
@@ -1,189 +0,0 @@
1/*
2 * Copyright 2002 Momentum Computer Inc.
3 * Author: Matthew Dharm <mdharm@momenco.com>
4 *
5 * Louis Hamilton, Red Hat, Inc.
6 * hamilton@redhat.com [MIPS64 modifications]
7 *
8 * Copyright 2004 PMC-Sierra
9 * Author: Manish Lachwani (lachwani@pmc-sierra.com)
10 *
11 * Based on Ocelot Linux port, which is
12 * Copyright 2001 MontaVista Software Inc.
13 * Author: jsun@mvista.com or jsun@junsun.net
14 *
15 * This program is free software; you can redistribute it and/or modify it
16 * under the terms of the GNU General Public License as published by the
17 * Free Software Foundation; either version 2 of the License, or (at your
18 * option) any later version.
19 *
20 * Copyright (C) 2004 MontaVista Software Inc.
21 * Author: Manish Lachwani, mlachwani@mvista.com
22 *
23 */
24#include <linux/init.h>
25#include <linux/bootmem.h>
26#include <linux/mv643xx.h>
27
28#include <asm/addrspace.h>
29#include <asm/bootinfo.h>
30#include <asm/pmon.h>
31#include "ocelot_3_fpga.h"
32
33struct callvectors* debug_vectors;
34extern unsigned long marvell_base;
35extern unsigned long cpu_clock;
36
37const char *get_system_type(void)
38{
39 return "Momentum Ocelot-3";
40}
41
42#ifdef CONFIG_64BIT
43
44unsigned long signext(unsigned long addr)
45{
46 addr &= 0xffffffff;
47 return (unsigned long)((int)addr);
48}
49
50void *get_arg(unsigned long args, int arc)
51{
52 unsigned long ul;
53 unsigned char *puc, uc;
54
55 args += (arc * 4);
56 ul = (unsigned long)signext(args);
57 puc = (unsigned char *)ul;
58 if (puc == 0)
59 return (void *)0;
60
61#ifdef CONFIG_CPU_LITTLE_ENDIAN
62 uc = *puc++;
63 ul = (unsigned long)uc;
64 uc = *puc++;
65 ul |= (((unsigned long)uc) << 8);
66 uc = *puc++;
67 ul |= (((unsigned long)uc) << 16);
68 uc = *puc++;
69 ul |= (((unsigned long)uc) << 24);
70#else /* CONFIG_CPU_LITTLE_ENDIAN */
71 uc = *puc++;
72 ul = ((unsigned long)uc) << 24;
73 uc = *puc++;
74 ul |= (((unsigned long)uc) << 16);
75 uc = *puc++;
76 ul |= (((unsigned long)uc) << 8);
77 uc = *puc++;
78 ul |= ((unsigned long)uc);
79#endif /* CONFIG_CPU_LITTLE_ENDIAN */
80 ul = signext(ul);
81 return (void *)ul;
82}
83
84char *arg64(unsigned long addrin, int arg_index)
85{
86 unsigned long args;
87 char *p;
88
89 args = signext(addrin);
90 p = (char *)get_arg(args, arg_index);
91
92 return p;
93}
94#endif /* CONFIG_64BIT */
95
96void __init prom_init(void)
97{
98 int argc = fw_arg0;
99 char **arg = (char **) fw_arg1;
100 char **env = (char **) fw_arg2;
101 struct callvectors *cv = (struct callvectors *) fw_arg3;
102 int i;
103
104#ifdef CONFIG_64BIT
105 char *ptr;
106 printk("prom_init - MIPS64\n");
107
108 /* save the PROM vectors for debugging use */
109 debug_vectors = (struct callvectors *)signext((unsigned long)cv);
110
111 /* arg[0] is "g", the rest is boot parameters */
112 arcs_cmdline[0] = '\0';
113
114 for (i = 1; i < argc; i++) {
115 ptr = (char *)arg64((unsigned long)arg, i);
116 if ((strlen(arcs_cmdline) + strlen(ptr) + 1) >=
117 sizeof(arcs_cmdline))
118 break;
119 strcat(arcs_cmdline, ptr);
120 strcat(arcs_cmdline, " ");
121 }
122 i = 0;
123
124 while (1) {
125 ptr = (char *)arg64((unsigned long)env, i);
126 if (! ptr)
127 break;
128
129 if (strncmp("gtbase", ptr, strlen("gtbase")) == 0) {
130 marvell_base = simple_strtol(ptr + strlen("gtbase="),
131 NULL, 16);
132
133 if ((marvell_base & 0xffffffff00000000) == 0)
134 marvell_base |= 0xffffffff00000000;
135
136 printk("marvell_base set to 0x%016lx\n", marvell_base);
137 }
138 if (strncmp("cpuclock", ptr, strlen("cpuclock")) == 0) {
139 cpu_clock = simple_strtol(ptr + strlen("cpuclock="),
140 NULL, 10);
141 printk("cpu_clock set to %d\n", cpu_clock);
142 }
143 i++;
144 }
145 printk("arcs_cmdline: %s\n", arcs_cmdline);
146
147#else /* CONFIG_64BIT */
148
149 /* save the PROM vectors for debugging use */
150 debug_vectors = cv;
151
152 /* arg[0] is "g", the rest is boot parameters */
153 arcs_cmdline[0] = '\0';
154 for (i = 1; i < argc; i++) {
155 if (strlen(arcs_cmdline) + strlen(arg[i] + 1)
156 >= sizeof(arcs_cmdline))
157 break;
158 strcat(arcs_cmdline, arg[i]);
159 strcat(arcs_cmdline, " ");
160 }
161
162 while (*env) {
163 if (strncmp("gtbase", *env, strlen("gtbase")) == 0) {
164 marvell_base = simple_strtol(*env + strlen("gtbase="),
165 NULL, 16);
166 }
167 if (strncmp("cpuclock", *env, strlen("cpuclock")) == 0) {
168 cpu_clock = simple_strtol(*env + strlen("cpuclock="),
169 NULL, 10);
170 }
171 env++;
172 }
173#endif /* CONFIG_64BIT */
174
175 mips_machgroup = MACH_GROUP_MOMENCO;
176 mips_machtype = MACH_MOMENCO_OCELOT_3;
177
178#ifndef CONFIG_64BIT
179 debug_vectors->printf("Booting Linux kernel...\n");
180#endif
181}
182
183void __init prom_free_prom_memory(void)
184{
185}
186
187void __init prom_fixup_mem_map(unsigned long start, unsigned long end)
188{
189}
diff --git a/arch/mips/momentum/ocelot_3/reset.c b/arch/mips/momentum/ocelot_3/reset.c
deleted file mode 100644
index 9d86d2468376..000000000000
--- a/arch/mips/momentum/ocelot_3/reset.c
+++ /dev/null
@@ -1,59 +0,0 @@
1/*
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU General Public License as published by the
4 * Free Software Foundation; either version 2 of the License, or (at your
5 * option) any later version.
6 *
7 * Copyright (C) 1997, 01, 05 Ralf Baechle
8 * Copyright 2001 MontaVista Software Inc.
9 * Author: jsun@mvista.com or jsun@junsun.net
10 *
11 * Copyright (C) 2002 Momentum Computer Inc.
12 * Author: Matthew Dharm <mdharm@momenco.com>
13 *
14 * Louis Hamilton, Red Hat, Inc.
15 * hamilton@redhat.com [MIPS64 modifications]
16 *
17 * Copyright 2004 PMC-Sierra
18 * Author: Manish Lachwani (lachwani@pmc-sierra.com)
19 *
20 * Copyright (C) 2004 MontaVista Software Inc.
21 * Author: Manish Lachwani, mlachwani@mvista.com
22 */
23#include <linux/sched.h>
24#include <linux/mm.h>
25#include <linux/delay.h>
26#include <asm/io.h>
27#include <asm/pgtable.h>
28#include <asm/processor.h>
29#include <asm/reboot.h>
30#include <asm/system.h>
31
32void momenco_ocelot_restart(char *command)
33{
34 /* base address of timekeeper portion of part */
35 void *nvram = (void *) 0xfc807000L;
36
37 /* Ask the NVRAM/RTC/watchdog chip to assert reset in 1/16 second */
38 writeb(0x84, nvram + 0xff7);
39
40 /* wait for the watchdog to go off */
41 mdelay(100+(1000/16));
42
43 /* if the watchdog fails for some reason, let people know */
44 printk(KERN_NOTICE "Watchdog reset failed\n");
45}
46
47void momenco_ocelot_halt(void)
48{
49 printk(KERN_NOTICE "\n** You can safely turn off the power\n");
50 while (1)
51 __asm__(".set\tmips3\n\t"
52 "wait\n\t"
53 ".set\tmips0");
54}
55
56void momenco_ocelot_power_off(void)
57{
58 momenco_ocelot_halt();
59}
diff --git a/arch/mips/momentum/ocelot_3/setup.c b/arch/mips/momentum/ocelot_3/setup.c
deleted file mode 100644
index ff0829f81116..000000000000
--- a/arch/mips/momentum/ocelot_3/setup.c
+++ /dev/null
@@ -1,398 +0,0 @@
1/*
2 * setup.c
3 *
4 * BRIEF MODULE DESCRIPTION
5 * Momentum Computer Ocelot-3 board dependent boot routines
6 *
7 * Copyright (C) 1996, 1997, 01, 05 - 06 Ralf Baechle
8 * Copyright (C) 2000 RidgeRun, Inc.
9 * Copyright (C) 2001 Red Hat, Inc.
10 * Copyright (C) 2002 Momentum Computer
11 *
12 * Author: Matthew Dharm, Momentum Computer
13 * mdharm@momenco.com
14 *
15 * Louis Hamilton, Red Hat, Inc.
16 * hamilton@redhat.com [MIPS64 modifications]
17 *
18 * Author: RidgeRun, Inc.
19 * glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com
20 *
21 * Copyright 2001 MontaVista Software Inc.
22 * Author: jsun@mvista.com or jsun@junsun.net
23 *
24 * Copyright 2004 PMC-Sierra
25 * Author: Manish Lachwani (lachwani@pmc-sierra.com)
26 *
27 * Copyright (C) 2004 MontaVista Software Inc.
28 * Author: Manish Lachwani, mlachwani@mvista.com
29 *
30 * This program is free software; you can redistribute it and/or modify it
31 * under the terms of the GNU General Public License as published by the
32 * Free Software Foundation; either version 2 of the License, or (at your
33 * option) any later version.
34 *
35 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
36 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
37 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
38 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
39 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
40 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
41 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
42 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
43 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
44 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
45 *
46 * You should have received a copy of the GNU General Public License along
47 * with this program; if not, write to the Free Software Foundation, Inc.,
48 * 675 Mass Ave, Cambridge, MA 02139, USA.
49 */
50#include <linux/init.h>
51#include <linux/kernel.h>
52#include <linux/types.h>
53#include <linux/mc146818rtc.h>
54#include <linux/ioport.h>
55#include <linux/interrupt.h>
56#include <linux/pci.h>
57#include <linux/timex.h>
58#include <linux/bootmem.h>
59#include <linux/mv643xx.h>
60#include <linux/pm.h>
61#include <linux/bcd.h>
62
63#include <asm/time.h>
64#include <asm/page.h>
65#include <asm/bootinfo.h>
66#include <asm/io.h>
67#include <asm/irq.h>
68#include <asm/pci.h>
69#include <asm/processor.h>
70#include <asm/reboot.h>
71#include <asm/mc146818rtc.h>
72#include <asm/tlbflush.h>
73#include "ocelot_3_fpga.h"
74
75/* Marvell Discovery Register Base */
76unsigned long marvell_base = (signed)0xf4000000;
77
78/* CPU clock */
79unsigned long cpu_clock;
80
81/* RTC/NVRAM */
82unsigned char* rtc_base = (unsigned char*)(signed)0xfc800000;
83
84/* FPGA Base */
85unsigned long ocelot_fpga_base = (signed)0xfc000000;
86
87/* Serial base */
88unsigned long uart_base = (signed)0xfd000000;
89
90/*
91 * Marvell Discovery SRAM. This is one place where Ethernet
92 * Tx and Rx descriptors can be placed to improve performance
93 */
94extern unsigned long mv64340_sram_base;
95
96/* These functions are used for rebooting or halting the machine*/
97extern void momenco_ocelot_restart(char *command);
98extern void momenco_ocelot_halt(void);
99extern void momenco_ocelot_power_off(void);
100
101void momenco_time_init(void);
102static char reset_reason;
103
104void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
105 unsigned long entryhi, unsigned long pagemask);
106
107static inline unsigned long ENTRYLO(unsigned long paddr)
108{
109 return ((paddr & PAGE_MASK) |
110 (_PAGE_PRESENT | __READABLE | __WRITEABLE | _PAGE_GLOBAL |
111 _CACHE_UNCACHED)) >> 6;
112}
113
114void __init bus_error_init(void)
115{
116 /* nothing */
117}
118
119/*
120 * setup code for a handoff from a version 2 PMON 2000 PROM
121 */
122void setup_wired_tlb_entries(void)
123{
124 write_c0_wired(0);
125 local_flush_tlb_all();
126
127 /* marvell and extra space */
128 add_wired_entry(ENTRYLO(0xf4000000), ENTRYLO(0xf4010000), (signed)0xf4000000, PM_64K);
129
130 /* fpga, rtc, and uart */
131 add_wired_entry(ENTRYLO(0xfc000000), ENTRYLO(0xfd000000), (signed)0xfc000000, PM_16M);
132}
133
134unsigned long m48t37y_get_time(void)
135{
136 unsigned int year, month, day, hour, min, sec;
137 unsigned long flags;
138
139 spin_lock_irqsave(&rtc_lock, flags);
140 /* stop the update */
141 rtc_base[0x7ff8] = 0x40;
142
143 year = BCD2BIN(rtc_base[0x7fff]);
144 year += BCD2BIN(rtc_base[0x7ff1]) * 100;
145
146 month = BCD2BIN(rtc_base[0x7ffe]);
147
148 day = BCD2BIN(rtc_base[0x7ffd]);
149
150 hour = BCD2BIN(rtc_base[0x7ffb]);
151 min = BCD2BIN(rtc_base[0x7ffa]);
152 sec = BCD2BIN(rtc_base[0x7ff9]);
153
154 /* start the update */
155 rtc_base[0x7ff8] = 0x00;
156 spin_unlock_irqrestore(&rtc_lock, flags);
157
158 return mktime(year, month, day, hour, min, sec);
159}
160
161int m48t37y_set_time(unsigned long sec)
162{
163 struct rtc_time tm;
164 unsigned long flags;
165
166 /* convert to a more useful format -- note months count from 0 */
167 to_tm(sec, &tm);
168 tm.tm_mon += 1;
169
170 spin_lock_irqsave(&rtc_lock, flags);
171 /* enable writing */
172 rtc_base[0x7ff8] = 0x80;
173
174 /* year */
175 rtc_base[0x7fff] = BIN2BCD(tm.tm_year % 100);
176 rtc_base[0x7ff1] = BIN2BCD(tm.tm_year / 100);
177
178 /* month */
179 rtc_base[0x7ffe] = BIN2BCD(tm.tm_mon);
180
181 /* day */
182 rtc_base[0x7ffd] = BIN2BCD(tm.tm_mday);
183
184 /* hour/min/sec */
185 rtc_base[0x7ffb] = BIN2BCD(tm.tm_hour);
186 rtc_base[0x7ffa] = BIN2BCD(tm.tm_min);
187 rtc_base[0x7ff9] = BIN2BCD(tm.tm_sec);
188
189 /* day of week -- not really used, but let's keep it up-to-date */
190 rtc_base[0x7ffc] = BIN2BCD(tm.tm_wday + 1);
191
192 /* disable writing */
193 rtc_base[0x7ff8] = 0x00;
194 spin_unlock_irqrestore(&rtc_lock, flags);
195
196 return 0;
197}
198
199void __init plat_timer_setup(struct irqaction *irq)
200{
201 setup_irq(7, irq); /* Timer interrupt, unmask status IM7 */
202}
203
204void momenco_time_init(void)
205{
206 setup_wired_tlb_entries();
207
208 /*
209 * Ocelot-3 board has been built with both
210 * the Rm7900 and the Rm7065C
211 */
212 mips_hpt_frequency = cpu_clock / 2;
213
214 rtc_mips_get_time = m48t37y_get_time;
215 rtc_mips_set_time = m48t37y_set_time;
216}
217
218/*
219 * PCI Support for Ocelot-3
220 */
221
222/* Bus #0 IO and MEM space */
223#define OCELOT_3_PCI_IO_0_START 0xe0000000
224#define OCELOT_3_PCI_IO_0_SIZE 0x08000000
225#define OCELOT_3_PCI_MEM_0_START 0xc0000000
226#define OCELOT_3_PCI_MEM_0_SIZE 0x10000000
227
228/* Bus #1 IO and MEM space */
229#define OCELOT_3_PCI_IO_1_START 0xe8000000
230#define OCELOT_3_PCI_IO_1_SIZE 0x08000000
231#define OCELOT_3_PCI_MEM_1_START 0xd0000000
232#define OCELOT_3_PCI_MEM_1_SIZE 0x10000000
233
234static struct resource mv_pci_io_mem0_resource = {
235 .name = "MV64340 PCI0 IO MEM",
236 .start = OCELOT_3_PCI_IO_0_START,
237 .end = OCELOT_3_PCI_IO_0_START + OCELOT_3_PCI_IO_0_SIZE - 1,
238 .flags = IORESOURCE_IO,
239};
240
241static struct resource mv_pci_io_mem1_resource = {
242 .name = "MV64340 PCI1 IO MEM",
243 .start = OCELOT_3_PCI_IO_1_START,
244 .end = OCELOT_3_PCI_IO_1_START + OCELOT_3_PCI_IO_1_SIZE - 1,
245 .flags = IORESOURCE_IO,
246};
247
248static struct resource mv_pci_mem0_resource = {
249 .name = "MV64340 PCI0 MEM",
250 .start = OCELOT_3_PCI_MEM_0_START,
251 .end = OCELOT_3_PCI_MEM_0_START + OCELOT_3_PCI_MEM_0_SIZE - 1,
252 .flags = IORESOURCE_MEM,
253};
254
255static struct resource mv_pci_mem1_resource = {
256 .name = "MV64340 PCI1 MEM",
257 .start = OCELOT_3_PCI_MEM_1_START,
258 .end = OCELOT_3_PCI_MEM_1_START + OCELOT_3_PCI_MEM_1_SIZE - 1,
259 .flags = IORESOURCE_MEM,
260};
261
262static struct mv_pci_controller mv_bus0_controller = {
263 .pcic = {
264 .pci_ops = &mv_pci_ops,
265 .mem_resource = &mv_pci_mem0_resource,
266 .io_resource = &mv_pci_io_mem0_resource,
267 },
268 .config_addr = MV64340_PCI_0_CONFIG_ADDR,
269 .config_vreg = MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG,
270};
271
272static struct mv_pci_controller mv_bus1_controller = {
273 .pcic = {
274 .pci_ops = &mv_pci_ops,
275 .mem_resource = &mv_pci_mem1_resource,
276 .io_resource = &mv_pci_io_mem1_resource,
277 },
278 .config_addr = MV64340_PCI_1_CONFIG_ADDR,
279 .config_vreg = MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG,
280};
281
282static __init int __init ja_pci_init(void)
283{
284 uint32_t enable;
285 extern int pci_probe_only;
286
287 /* PMON will assign PCI resources */
288 pci_probe_only = 1;
289
290 enable = ~MV_READ(MV64340_BASE_ADDR_ENABLE);
291 /*
292 * We require at least one enabled I/O or PCI memory window or we
293 * will ignore this PCI bus. We ignore PCI windows 1, 2 and 3.
294 */
295 if (enable & (0x01 << 9) || enable & (0x01 << 10))
296 register_pci_controller(&mv_bus0_controller.pcic);
297
298 if (enable & (0x01 << 14) || enable & (0x01 << 15))
299 register_pci_controller(&mv_bus1_controller.pcic);
300
301 ioport_resource.end = OCELOT_3_PCI_IO_0_START + OCELOT_3_PCI_IO_0_SIZE +
302 OCELOT_3_PCI_IO_1_SIZE - 1;
303
304 iomem_resource.end = OCELOT_3_PCI_MEM_0_START + OCELOT_3_PCI_MEM_0_SIZE +
305 OCELOT_3_PCI_MEM_1_SIZE - 1;
306
307 set_io_port_base(OCELOT_3_PCI_IO_0_START); /* mips_io_port_base */
308
309 return 0;
310}
311
312arch_initcall(ja_pci_init);
313
314void __init plat_mem_setup(void)
315{
316 unsigned int tmpword;
317
318 board_time_init = momenco_time_init;
319
320 _machine_restart = momenco_ocelot_restart;
321 _machine_halt = momenco_ocelot_halt;
322 pm_power_off = momenco_ocelot_power_off;
323
324 /* Wired TLB entries */
325 setup_wired_tlb_entries();
326
327 /* shut down ethernet ports, just to be sure our memory doesn't get
328 * corrupted by random ethernet traffic.
329 */
330 MV_WRITE(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(0), 0xff << 8);
331 MV_WRITE(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(1), 0xff << 8);
332 MV_WRITE(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(0), 0xff << 8);
333 MV_WRITE(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(1), 0xff << 8);
334 do {}
335 while (MV_READ(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(0)) & 0xff);
336 do {}
337 while (MV_READ(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(1)) & 0xff);
338 do {}
339 while (MV_READ(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(0)) & 0xff);
340 do {}
341 while (MV_READ(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(1)) & 0xff);
342 MV_WRITE(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(0),
343 MV_READ(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(0)) & ~1);
344 MV_WRITE(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(1),
345 MV_READ(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(1)) & ~1);
346
347 /* Turn off the Bit-Error LED */
348 OCELOT_FPGA_WRITE(0x80, CLR);
349
350 tmpword = OCELOT_FPGA_READ(BOARDREV);
351 if (tmpword < 26)
352 printk("Momenco Ocelot-3: Board Assembly Rev. %c\n",
353 'A'+tmpword);
354 else
355 printk("Momenco Ocelot-3: Board Assembly Revision #0x%x\n",
356 tmpword);
357
358 tmpword = OCELOT_FPGA_READ(FPGA_REV);
359 printk("FPGA Rev: %d.%d\n", tmpword>>4, tmpword&15);
360 tmpword = OCELOT_FPGA_READ(RESET_STATUS);
361 printk("Reset reason: 0x%x\n", tmpword);
362 switch (tmpword) {
363 case 0x1:
364 printk(" - Power-up reset\n");
365 break;
366 case 0x2:
367 printk(" - Push-button reset\n");
368 break;
369 case 0x4:
370 printk(" - cPCI bus reset\n");
371 break;
372 case 0x8:
373 printk(" - Watchdog reset\n");
374 break;
375 case 0x10:
376 printk(" - Software reset\n");
377 break;
378 default:
379 printk(" - Unknown reset cause\n");
380 }
381 reset_reason = tmpword;
382 OCELOT_FPGA_WRITE(0xff, RESET_STATUS);
383
384 tmpword = OCELOT_FPGA_READ(CPCI_ID);
385 printk("cPCI ID register: 0x%02x\n", tmpword);
386 printk(" - Slot number: %d\n", tmpword & 0x1f);
387 printk(" - PCI bus present: %s\n", tmpword & 0x40 ? "yes" : "no");
388 printk(" - System Slot: %s\n", tmpword & 0x20 ? "yes" : "no");
389
390 tmpword = OCELOT_FPGA_READ(BOARD_STATUS);
391 printk("Board Status register: 0x%02x\n", tmpword);
392 printk(" - User jumper: %s\n", (tmpword & 0x80)?"installed":"absent");
393 printk(" - Boot flash write jumper: %s\n", (tmpword&0x40)?"installed":"absent");
394 printk(" - L3 cache size: %d MB\n", (1<<((tmpword&12) >> 2))&~1);
395
396 /* Support for 128 MB memory */
397 add_memory_region(0x0, 0x08000000, BOOT_MEM_RAM);
398}
diff --git a/arch/mips/momentum/ocelot_c/Makefile b/arch/mips/momentum/ocelot_c/Makefile
deleted file mode 100644
index d69161aa1675..000000000000
--- a/arch/mips/momentum/ocelot_c/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
1#
2# Makefile for Momentum Computer's Ocelot-C and -CS boards.
3#
4
5obj-y += cpci-irq.o irq.o platform.o prom.o reset.o \
6 setup.o uart-irq.o
7
8obj-$(CONFIG_KGDB) += dbg_io.o
diff --git a/arch/mips/momentum/ocelot_c/cpci-irq.c b/arch/mips/momentum/ocelot_c/cpci-irq.c
deleted file mode 100644
index 186a140fd2a9..000000000000
--- a/arch/mips/momentum/ocelot_c/cpci-irq.c
+++ /dev/null
@@ -1,100 +0,0 @@
1/*
2 * Copyright 2002 Momentum Computer
3 * Author: mdharm@momenco.com
4 *
5 * arch/mips/momentum/ocelot_c/cpci-irq.c
6 * Interrupt routines for cpci. Interrupt numbers are assigned from
7 * CPCI_IRQ_BASE to CPCI_IRQ_BASE+8 (8 interrupt sources).
8 *
9 * Note that the high-level software will need to be careful about using
10 * these interrupts. If this board is asserting a cPCI interrupt, it will
11 * also see the asserted interrupt. Care must be taken to avoid an
12 * interrupt flood.
13 *
14 * This program is free software; you can redistribute it and/or modify it
15 * under the terms of the GNU General Public License as published by the
16 * Free Software Foundation; either version 2 of the License, or (at your
17 * option) any later version.
18 */
19
20#include <linux/module.h>
21#include <linux/interrupt.h>
22#include <linux/irq.h>
23#include <linux/kernel.h>
24#include <linux/sched.h>
25#include <linux/kernel_stat.h>
26#include <asm/io.h>
27#include "ocelot_c_fpga.h"
28
29#define CPCI_IRQ_BASE 8
30
31static inline int ls1bit8(unsigned int x)
32{
33 int b = 7, s;
34
35 s = 4; if (((unsigned char)(x << 4)) == 0) s = 0; b -= s; x <<= s;
36 s = 2; if (((unsigned char)(x << 2)) == 0) s = 0; b -= s; x <<= s;
37 s = 1; if (((unsigned char)(x << 1)) == 0) s = 0; b -= s;
38
39 return b;
40}
41
42/* mask off an interrupt -- 0 is enable, 1 is disable */
43static inline void mask_cpci_irq(unsigned int irq)
44{
45 uint32_t value;
46
47 value = OCELOT_FPGA_READ(INTMASK);
48 value |= 1 << (irq - CPCI_IRQ_BASE);
49 OCELOT_FPGA_WRITE(value, INTMASK);
50
51 /* read the value back to assure that it's really been written */
52 value = OCELOT_FPGA_READ(INTMASK);
53}
54
55/* unmask an interrupt -- 0 is enable, 1 is disable */
56static inline void unmask_cpci_irq(unsigned int irq)
57{
58 uint32_t value;
59
60 value = OCELOT_FPGA_READ(INTMASK);
61 value &= ~(1 << (irq - CPCI_IRQ_BASE));
62 OCELOT_FPGA_WRITE(value, INTMASK);
63
64 /* read the value back to assure that it's really been written */
65 value = OCELOT_FPGA_READ(INTMASK);
66}
67
68/*
69 * Interrupt handler for interrupts coming from the FPGA chip.
70 * It could be built in ethernet ports etc...
71 */
72void ll_cpci_irq(void)
73{
74 unsigned int irq_src, irq_mask;
75
76 /* read the interrupt status registers */
77 irq_src = OCELOT_FPGA_READ(INTSTAT);
78 irq_mask = OCELOT_FPGA_READ(INTMASK);
79
80 /* mask for just the interrupts we want */
81 irq_src &= ~irq_mask;
82
83 do_IRQ(ls1bit8(irq_src) + CPCI_IRQ_BASE);
84}
85
86struct irq_chip cpci_irq_type = {
87 .name = "CPCI/FPGA",
88 .ack = mask_cpci_irq,
89 .mask = mask_cpci_irq,
90 .mask_ack = mask_cpci_irq,
91 .unmask = unmask_cpci_irq,
92};
93
94void cpci_irq_init(void)
95{
96 int i;
97
98 for (i = CPCI_IRQ_BASE; i < (CPCI_IRQ_BASE + 8); i++)
99 set_irq_chip_and_handler(i, &cpci_irq_type, handle_level_irq);
100}
diff --git a/arch/mips/momentum/ocelot_c/dbg_io.c b/arch/mips/momentum/ocelot_c/dbg_io.c
deleted file mode 100644
index 32d6fb4ee679..000000000000
--- a/arch/mips/momentum/ocelot_c/dbg_io.c
+++ /dev/null
@@ -1,121 +0,0 @@
1
2#include <asm/serial.h> /* For the serial port location and base baud */
3
4/* --- CONFIG --- */
5
6typedef unsigned char uint8;
7typedef unsigned int uint32;
8
9/* --- END OF CONFIG --- */
10
11#define UART16550_BAUD_2400 2400
12#define UART16550_BAUD_4800 4800
13#define UART16550_BAUD_9600 9600
14#define UART16550_BAUD_19200 19200
15#define UART16550_BAUD_38400 38400
16#define UART16550_BAUD_57600 57600
17#define UART16550_BAUD_115200 115200
18
19#define UART16550_PARITY_NONE 0
20#define UART16550_PARITY_ODD 0x08
21#define UART16550_PARITY_EVEN 0x18
22#define UART16550_PARITY_MARK 0x28
23#define UART16550_PARITY_SPACE 0x38
24
25#define UART16550_DATA_5BIT 0x0
26#define UART16550_DATA_6BIT 0x1
27#define UART16550_DATA_7BIT 0x2
28#define UART16550_DATA_8BIT 0x3
29
30#define UART16550_STOP_1BIT 0x0
31#define UART16550_STOP_2BIT 0x4
32
33/* ----------------------------------------------------- */
34
35/* === CONFIG === */
36
37/* [jsun] we use the second serial port for kdb */
38#define BASE OCELOT_SERIAL1_BASE
39#define MAX_BAUD OCELOT_BASE_BAUD
40
41/* === END OF CONFIG === */
42
43#define REG_OFFSET 4
44
45/* register offset */
46#define OFS_RCV_BUFFER 0
47#define OFS_TRANS_HOLD 0
48#define OFS_SEND_BUFFER 0
49#define OFS_INTR_ENABLE (1*REG_OFFSET)
50#define OFS_INTR_ID (2*REG_OFFSET)
51#define OFS_DATA_FORMAT (3*REG_OFFSET)
52#define OFS_LINE_CONTROL (3*REG_OFFSET)
53#define OFS_MODEM_CONTROL (4*REG_OFFSET)
54#define OFS_RS232_OUTPUT (4*REG_OFFSET)
55#define OFS_LINE_STATUS (5*REG_OFFSET)
56#define OFS_MODEM_STATUS (6*REG_OFFSET)
57#define OFS_RS232_INPUT (6*REG_OFFSET)
58#define OFS_SCRATCH_PAD (7*REG_OFFSET)
59
60#define OFS_DIVISOR_LSB (0*REG_OFFSET)
61#define OFS_DIVISOR_MSB (1*REG_OFFSET)
62
63
64/* memory-mapped read/write of the port */
65#define UART16550_READ(y) (*((volatile uint8*)(BASE + y)))
66#define UART16550_WRITE(y, z) ((*((volatile uint8*)(BASE + y))) = z)
67
68void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop)
69{
70 /* disable interrupts */
71 UART16550_WRITE(OFS_INTR_ENABLE, 0);
72
73 /* set up baud rate */
74 {
75 uint32 divisor;
76
77 /* set DIAB bit */
78 UART16550_WRITE(OFS_LINE_CONTROL, 0x80);
79
80 /* set divisor */
81 divisor = MAX_BAUD / baud;
82 UART16550_WRITE(OFS_DIVISOR_LSB, divisor & 0xff);
83 UART16550_WRITE(OFS_DIVISOR_MSB, (divisor & 0xff00) >> 8);
84
85 /* clear DIAB bit */
86 UART16550_WRITE(OFS_LINE_CONTROL, 0x0);
87 }
88
89 /* set data format */
90 UART16550_WRITE(OFS_DATA_FORMAT, data | parity | stop);
91}
92
93static int remoteDebugInitialized = 0;
94
95uint8 getDebugChar(void)
96{
97 if (!remoteDebugInitialized) {
98 remoteDebugInitialized = 1;
99 debugInit(UART16550_BAUD_38400,
100 UART16550_DATA_8BIT,
101 UART16550_PARITY_NONE, UART16550_STOP_1BIT);
102 }
103
104 while ((UART16550_READ(OFS_LINE_STATUS) & 0x1) == 0);
105 return UART16550_READ(OFS_RCV_BUFFER);
106}
107
108
109int putDebugChar(uint8 byte)
110{
111 if (!remoteDebugInitialized) {
112 remoteDebugInitialized = 1;
113 debugInit(UART16550_BAUD_38400,
114 UART16550_DATA_8BIT,
115 UART16550_PARITY_NONE, UART16550_STOP_1BIT);
116 }
117
118 while ((UART16550_READ(OFS_LINE_STATUS) & 0x20) == 0);
119 UART16550_WRITE(OFS_SEND_BUFFER, byte);
120 return 1;
121}
diff --git a/arch/mips/momentum/ocelot_c/irq.c b/arch/mips/momentum/ocelot_c/irq.c
deleted file mode 100644
index 844d566c9de3..000000000000
--- a/arch/mips/momentum/ocelot_c/irq.c
+++ /dev/null
@@ -1,107 +0,0 @@
1/*
2 * Copyright (C) 2000 RidgeRun, Inc.
3 * Author: RidgeRun, Inc.
4 * glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com
5 *
6 * Copyright 2001 MontaVista Software Inc.
7 * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
8 * Copyright (C) 2000, 01, 05 Ralf Baechle (ralf@linux-mips.org)
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 *
15 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
16 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
17 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
18 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
21 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
22 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 *
26 * You should have received a copy of the GNU General Public License along
27 * with this program; if not, write to the Free Software Foundation, Inc.,
28 * 675 Mass Ave, Cambridge, MA 02139, USA.
29 *
30 */
31#include <linux/errno.h>
32#include <linux/init.h>
33#include <linux/kernel_stat.h>
34#include <linux/module.h>
35#include <linux/signal.h>
36#include <linux/sched.h>
37#include <linux/types.h>
38#include <linux/interrupt.h>
39#include <linux/ioport.h>
40#include <linux/timex.h>
41#include <linux/slab.h>
42#include <linux/random.h>
43#include <linux/bitops.h>
44#include <linux/mv643xx.h>
45#include <asm/bootinfo.h>
46#include <asm/io.h>
47#include <asm/irq_cpu.h>
48#include <asm/mipsregs.h>
49#include <asm/system.h>
50
51extern void uart_irq_init(void);
52extern void cpci_irq_init(void);
53
54static struct irqaction cascade_fpga = {
55 no_action, IRQF_DISABLED, CPU_MASK_NONE, "cascade via FPGA", NULL, NULL
56};
57
58static struct irqaction cascade_mv64340 = {
59 no_action, IRQF_DISABLED, CPU_MASK_NONE, "cascade via MV64340", NULL, NULL
60};
61
62extern void ll_uart_irq(void);
63extern void ll_cpci_irq(void);
64
65asmlinkage void plat_irq_dispatch(void)
66{
67 unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
68
69 if (pending & STATUSF_IP0)
70 do_IRQ(0);
71 else if (pending & STATUSF_IP1)
72 do_IRQ(1);
73 else if (pending & STATUSF_IP2)
74 do_IRQ(2);
75 else if (pending & STATUSF_IP3)
76 ll_uart_irq();
77 else if (pending & STATUSF_IP4)
78 do_IRQ(4);
79 else if (pending & STATUSF_IP5)
80 ll_cpci_irq();
81 else if (pending & STATUSF_IP6)
82 ll_mv64340_irq();
83 else if (pending & STATUSF_IP7)
84 do_IRQ(7);
85 else
86 spurious_interrupt();
87}
88
89void __init arch_init_irq(void)
90{
91 /*
92 * Clear all of the interrupts while we change the able around a bit.
93 * int-handler is not on bootstrap
94 */
95 clear_c0_status(ST0_IM);
96
97 mips_cpu_irq_init();
98
99 /* set up the cascading interrupts */
100 setup_irq(3, &cascade_fpga);
101 setup_irq(5, &cascade_fpga);
102 setup_irq(6, &cascade_mv64340);
103
104 mv64340_irq_init(16);
105 uart_irq_init();
106 cpci_irq_init();
107}
diff --git a/arch/mips/momentum/ocelot_c/platform.c b/arch/mips/momentum/ocelot_c/platform.c
deleted file mode 100644
index 7780aa0c6555..000000000000
--- a/arch/mips/momentum/ocelot_c/platform.c
+++ /dev/null
@@ -1,183 +0,0 @@
1#include <linux/delay.h>
2#include <linux/if_ether.h>
3#include <linux/ioport.h>
4#include <linux/mv643xx.h>
5#include <linux/platform_device.h>
6
7#include "ocelot_c_fpga.h"
8
9#if defined(CONFIG_MV643XX_ETH) || defined(CONFIG_MV643XX_ETH_MODULE)
10
11static struct resource mv643xx_eth_shared_resources[] = {
12 [0] = {
13 .name = "ethernet shared base",
14 .start = 0xf1000000 + MV643XX_ETH_SHARED_REGS,
15 .end = 0xf1000000 + MV643XX_ETH_SHARED_REGS +
16 MV643XX_ETH_SHARED_REGS_SIZE - 1,
17 .flags = IORESOURCE_MEM,
18 },
19};
20
21static struct platform_device mv643xx_eth_shared_device = {
22 .name = MV643XX_ETH_SHARED_NAME,
23 .id = 0,
24 .num_resources = ARRAY_SIZE(mv643xx_eth_shared_resources),
25 .resource = mv643xx_eth_shared_resources,
26};
27
28#define MV_SRAM_BASE 0xfe000000UL
29#define MV_SRAM_SIZE (256 * 1024)
30
31#define MV_SRAM_RXRING_SIZE (MV_SRAM_SIZE / 4)
32#define MV_SRAM_TXRING_SIZE (MV_SRAM_SIZE / 4)
33
34#define MV_SRAM_BASE_ETH0 MV_SRAM_BASE
35#define MV_SRAM_BASE_ETH1 (MV_SRAM_BASE + (MV_SRAM_SIZE / 2))
36
37#define MV64x60_IRQ_ETH_0 48
38#define MV64x60_IRQ_ETH_1 49
39
40static struct resource mv64x60_eth0_resources[] = {
41 [0] = {
42 .name = "eth0 irq",
43 .start = MV64x60_IRQ_ETH_0,
44 .end = MV64x60_IRQ_ETH_0,
45 .flags = IORESOURCE_IRQ,
46 },
47};
48
49static struct mv643xx_eth_platform_data eth0_pd = {
50 .port_number = 0,
51
52 .tx_sram_addr = MV_SRAM_BASE_ETH0,
53 .tx_sram_size = MV_SRAM_TXRING_SIZE,
54 .tx_queue_size = MV_SRAM_TXRING_SIZE / 16,
55
56 .rx_sram_addr = MV_SRAM_BASE_ETH0 + MV_SRAM_TXRING_SIZE,
57 .rx_sram_size = MV_SRAM_RXRING_SIZE,
58 .rx_queue_size = MV_SRAM_RXRING_SIZE / 16,
59};
60
61static struct platform_device eth0_device = {
62 .name = MV643XX_ETH_NAME,
63 .id = 0,
64 .num_resources = ARRAY_SIZE(mv64x60_eth0_resources),
65 .resource = mv64x60_eth0_resources,
66 .dev = {
67 .platform_data = &eth0_pd,
68 },
69};
70
71static struct resource mv64x60_eth1_resources[] = {
72 [0] = {
73 .name = "eth1 irq",
74 .start = MV64x60_IRQ_ETH_1,
75 .end = MV64x60_IRQ_ETH_1,
76 .flags = IORESOURCE_IRQ,
77 },
78};
79
80static struct mv643xx_eth_platform_data eth1_pd = {
81 .port_number = 1,
82
83 .tx_sram_addr = MV_SRAM_BASE_ETH1,
84 .tx_sram_size = MV_SRAM_TXRING_SIZE,
85 .tx_queue_size = MV_SRAM_TXRING_SIZE / 16,
86
87 .rx_sram_addr = MV_SRAM_BASE_ETH1 + MV_SRAM_TXRING_SIZE,
88 .rx_sram_size = MV_SRAM_RXRING_SIZE,
89 .rx_queue_size = MV_SRAM_RXRING_SIZE / 16,
90};
91
92static struct platform_device eth1_device = {
93 .name = MV643XX_ETH_NAME,
94 .id = 1,
95 .num_resources = ARRAY_SIZE(mv64x60_eth1_resources),
96 .resource = mv64x60_eth1_resources,
97 .dev = {
98 .platform_data = &eth1_pd,
99 },
100};
101
102static struct platform_device *mv643xx_eth_pd_devs[] __initdata = {
103 &mv643xx_eth_shared_device,
104 &eth0_device,
105 &eth1_device,
106 /* The third port is not wired up on the Ocelot C */
107};
108
109static u8 __init exchange_bit(u8 val, u8 cs)
110{
111 /* place the data */
112 OCELOT_FPGA_WRITE((val << 2) | cs, EEPROM_MODE);
113 udelay(1);
114
115 /* turn the clock on */
116 OCELOT_FPGA_WRITE((val << 2) | cs | 0x2, EEPROM_MODE);
117 udelay(1);
118
119 /* turn the clock off and read-strobe */
120 OCELOT_FPGA_WRITE((val << 2) | cs | 0x10, EEPROM_MODE);
121
122 /* return the data */
123 return (OCELOT_FPGA_READ(EEPROM_MODE) >> 3) & 0x1;
124}
125
126static void __init get_mac(char dest[6])
127{
128 u8 read_opcode[12] = {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
129 int i,j;
130
131 for (i = 0; i < 12; i++)
132 exchange_bit(read_opcode[i], 1);
133
134 for (j = 0; j < 6; j++) {
135 dest[j] = 0;
136 for (i = 0; i < 8; i++) {
137 dest[j] <<= 1;
138 dest[j] |= exchange_bit(0, 1);
139 }
140 }
141
142 /* turn off CS */
143 exchange_bit(0,0);
144}
145
146/*
147 * Copy and increment ethernet MAC address by a small value.
148 *
149 * This is useful for systems where the only one MAC address is stored in
150 * non-volatile memory for multiple ports.
151 */
152static inline void eth_mac_add(unsigned char *dst, unsigned char *src,
153 unsigned int add)
154{
155 int i;
156
157 BUG_ON(add >= 256);
158
159 for (i = ETH_ALEN; i >= 0; i--) {
160 dst[i] = src[i] + add;
161 add = dst[i] < src[i]; /* compute carry */
162 }
163
164 WARN_ON(add);
165}
166
167static int __init mv643xx_eth_add_pds(void)
168{
169 unsigned char mac[ETH_ALEN];
170 int ret;
171
172 get_mac(mac);
173 eth_mac_add(eth0_pd.mac_addr, mac, 0);
174 eth_mac_add(eth1_pd.mac_addr, mac, 1);
175 ret = platform_add_devices(mv643xx_eth_pd_devs,
176 ARRAY_SIZE(mv643xx_eth_pd_devs));
177
178 return ret;
179}
180
181device_initcall(mv643xx_eth_add_pds);
182
183#endif /* defined(CONFIG_MV643XX_ETH) || defined(CONFIG_MV643XX_ETH_MODULE) */
diff --git a/arch/mips/momentum/ocelot_c/prom.c b/arch/mips/momentum/ocelot_c/prom.c
deleted file mode 100644
index b689ceea8cfb..000000000000
--- a/arch/mips/momentum/ocelot_c/prom.c
+++ /dev/null
@@ -1,183 +0,0 @@
1/*
2 * Copyright 2002 Momentum Computer Inc.
3 * Author: Matthew Dharm <mdharm@momenco.com>
4 *
5 * Louis Hamilton, Red Hat, Inc.
6 * hamilton@redhat.com [MIPS64 modifications]
7 *
8 * Based on Ocelot Linux port, which is
9 * Copyright 2001 MontaVista Software Inc.
10 * Author: jsun@mvista.com or jsun@junsun.net
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version.
16 */
17#include <linux/init.h>
18#include <linux/mm.h>
19#include <linux/sched.h>
20#include <linux/bootmem.h>
21#include <linux/mv643xx.h>
22
23#include <asm/addrspace.h>
24#include <asm/bootinfo.h>
25#include <asm/pmon.h>
26
27#include "ocelot_c_fpga.h"
28
29struct callvectors* debug_vectors;
30
31extern unsigned long marvell_base;
32extern unsigned int cpu_clock;
33
34const char *get_system_type(void)
35{
36#ifdef CONFIG_CPU_SR71000
37 return "Momentum Ocelot-CS";
38#else
39 return "Momentum Ocelot-C";
40#endif
41}
42
43#ifdef CONFIG_64BIT
44
45unsigned long signext(unsigned long addr)
46{
47 addr &= 0xffffffff;
48 return (unsigned long)((int)addr);
49}
50
51void *get_arg(unsigned long args, int arc)
52{
53 unsigned long ul;
54 unsigned char *puc, uc;
55
56 args += (arc * 4);
57 ul = (unsigned long)signext(args);
58 puc = (unsigned char *)ul;
59 if (puc == 0)
60 return (void *)0;
61
62#ifdef CONFIG_CPU_LITTLE_ENDIAN
63 uc = *puc++;
64 ul = (unsigned long)uc;
65 uc = *puc++;
66 ul |= (((unsigned long)uc) << 8);
67 uc = *puc++;
68 ul |= (((unsigned long)uc) << 16);
69 uc = *puc++;
70 ul |= (((unsigned long)uc) << 24);
71#else /* CONFIG_CPU_LITTLE_ENDIAN */
72 uc = *puc++;
73 ul = ((unsigned long)uc) << 24;
74 uc = *puc++;
75 ul |= (((unsigned long)uc) << 16);
76 uc = *puc++;
77 ul |= (((unsigned long)uc) << 8);
78 uc = *puc++;
79 ul |= ((unsigned long)uc);
80#endif /* CONFIG_CPU_LITTLE_ENDIAN */
81 ul = signext(ul);
82 return (void *)ul;
83}
84
85char *arg64(unsigned long addrin, int arg_index)
86{
87 unsigned long args;
88 char *p;
89 args = signext(addrin);
90 p = (char *)get_arg(args, arg_index);
91 return p;
92}
93#endif /* CONFIG_64BIT */
94
95
96void __init prom_init(void)
97{
98 int argc = fw_arg0;
99 char **arg = (char **) fw_arg1;
100 char **env = (char **) fw_arg2;
101 struct callvectors *cv = (struct callvectors *) fw_arg3;
102 int i;
103
104#ifdef CONFIG_64BIT
105 char *ptr;
106
107 printk("prom_init - MIPS64\n");
108 /* save the PROM vectors for debugging use */
109 debug_vectors = (struct callvectors *)signext((unsigned long)cv);
110
111 /* arg[0] is "g", the rest is boot parameters */
112 arcs_cmdline[0] = '\0';
113
114 for (i = 1; i < argc; i++) {
115 ptr = (char *)arg64((unsigned long)arg, i);
116 if ((strlen(arcs_cmdline) + strlen(ptr) + 1) >=
117 sizeof(arcs_cmdline))
118 break;
119 strcat(arcs_cmdline, ptr);
120 strcat(arcs_cmdline, " ");
121 }
122 i = 0;
123 while (1) {
124 ptr = (char *)arg64((unsigned long)env, i);
125 if (! ptr)
126 break;
127
128 if (strncmp("gtbase", ptr, strlen("gtbase")) == 0) {
129 marvell_base = simple_strtol(ptr + strlen("gtbase="),
130 NULL, 16);
131
132 if ((marvell_base & 0xffffffff00000000) == 0)
133 marvell_base |= 0xffffffff00000000;
134
135 printk("marvell_base set to 0x%016lx\n", marvell_base);
136 }
137 if (strncmp("cpuclock", ptr, strlen("cpuclock")) == 0) {
138 cpu_clock = simple_strtol(ptr + strlen("cpuclock="),
139 NULL, 10);
140 printk("cpu_clock set to %d\n", cpu_clock);
141 }
142 i++;
143 }
144 printk("arcs_cmdline: %s\n", arcs_cmdline);
145
146#else /* CONFIG_64BIT */
147 /* save the PROM vectors for debugging use */
148 debug_vectors = cv;
149
150 /* arg[0] is "g", the rest is boot parameters */
151 arcs_cmdline[0] = '\0';
152 for (i = 1; i < argc; i++) {
153 if (strlen(arcs_cmdline) + strlen(arg[i] + 1)
154 >= sizeof(arcs_cmdline))
155 break;
156 strcat(arcs_cmdline, arg[i]);
157 strcat(arcs_cmdline, " ");
158 }
159
160 while (*env) {
161 if (strncmp("gtbase", *env, strlen("gtbase")) == 0) {
162 marvell_base = simple_strtol(*env + strlen("gtbase="),
163 NULL, 16);
164 }
165 if (strncmp("cpuclock", *env, strlen("cpuclock")) == 0) {
166 cpu_clock = simple_strtol(*env + strlen("cpuclock="),
167 NULL, 10);
168 }
169 env++;
170 }
171#endif /* CONFIG_64BIT */
172
173 mips_machgroup = MACH_GROUP_MOMENCO;
174 mips_machtype = MACH_MOMENCO_OCELOT_C;
175
176#ifndef CONFIG_64BIT
177 debug_vectors->printf("Booting Linux kernel...\n");
178#endif
179}
180
181void __init prom_free_prom_memory(void)
182{
183}
diff --git a/arch/mips/momentum/ocelot_c/reset.c b/arch/mips/momentum/ocelot_c/reset.c
deleted file mode 100644
index 3fdcb64ff1e6..000000000000
--- a/arch/mips/momentum/ocelot_c/reset.c
+++ /dev/null
@@ -1,58 +0,0 @@
1/*
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU General Public License as published by the
4 * Free Software Foundation; either version 2 of the License, or (at your
5 * option) any later version.
6 *
7 * Copyright (C) 1997, 2001 Ralf Baechle
8 * Copyright 2001 MontaVista Software Inc.
9 * Author: jsun@mvista.com or jsun@junsun.net
10 *
11 * Copyright (C) 2002 Momentum Computer Inc.
12 * Author: Matthew Dharm <mdharm@momenco.com>
13 *
14 * Louis Hamilton, Red Hat, Inc.
15 * hamilton@redhat.com [MIPS64 modifications]
16 */
17#include <linux/sched.h>
18#include <linux/mm.h>
19#include <asm/io.h>
20#include <asm/pgtable.h>
21#include <asm/processor.h>
22#include <asm/reboot.h>
23#include <asm/system.h>
24#include <linux/delay.h>
25
26void momenco_ocelot_restart(char *command)
27{
28 /* base address of timekeeper portion of part */
29 void *nvram = (void *)
30#ifdef CONFIG_64BIT
31 0xfffffffffc807000;
32#else
33 0xfc807000;
34#endif
35
36 /* Ask the NVRAM/RTC/watchdog chip to assert reset in 1/16 second */
37 writeb(0x84, nvram + 0xff7);
38
39 /* wait for the watchdog to go off */
40 mdelay(100+(1000/16));
41
42 /* if the watchdog fails for some reason, let people know */
43 printk(KERN_NOTICE "Watchdog reset failed\n");
44}
45
46void momenco_ocelot_halt(void)
47{
48 printk(KERN_NOTICE "\n** You can safely turn off the power\n");
49 while (1)
50 __asm__(".set\tmips3\n\t"
51 "wait\n\t"
52 ".set\tmips0");
53}
54
55void momenco_ocelot_power_off(void)
56{
57 momenco_ocelot_halt();
58}
diff --git a/arch/mips/momentum/ocelot_c/setup.c b/arch/mips/momentum/ocelot_c/setup.c
deleted file mode 100644
index 0b6b2338cfb4..000000000000
--- a/arch/mips/momentum/ocelot_c/setup.c
+++ /dev/null
@@ -1,362 +0,0 @@
1/*
2 * BRIEF MODULE DESCRIPTION
3 * Momentum Computer Ocelot-C and -CS board dependent boot routines
4 *
5 * Copyright (C) 1996, 1997, 2001 Ralf Baechle
6 * Copyright (C) 2000 RidgeRun, Inc.
7 * Copyright (C) 2001 Red Hat, Inc.
8 * Copyright (C) 2002 Momentum Computer
9 *
10 * Author: Matthew Dharm, Momentum Computer
11 * mdharm@momenco.com
12 *
13 * Louis Hamilton, Red Hat, Inc.
14 * hamilton@redhat.com [MIPS64 modifications]
15 *
16 * Author: RidgeRun, Inc.
17 * glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com
18 *
19 * Copyright 2001 MontaVista Software Inc.
20 * Author: jsun@mvista.com or jsun@junsun.net
21 *
22 * This program is free software; you can redistribute it and/or modify it
23 * under the terms of the GNU General Public License as published by the
24 * Free Software Foundation; either version 2 of the License, or (at your
25 * option) any later version.
26 *
27 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
28 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
29 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
30 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
31 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
32 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
33 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
34 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
36 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 *
38 * You should have received a copy of the GNU General Public License along
39 * with this program; if not, write to the Free Software Foundation, Inc.,
40 * 675 Mass Ave, Cambridge, MA 02139, USA.
41 *
42 */
43#include <linux/bcd.h>
44#include <linux/init.h>
45#include <linux/kernel.h>
46#include <linux/types.h>
47#include <linux/mm.h>
48#include <linux/swap.h>
49#include <linux/ioport.h>
50#include <linux/sched.h>
51#include <linux/interrupt.h>
52#include <linux/pci.h>
53#include <linux/pm.h>
54#include <linux/timex.h>
55#include <linux/vmalloc.h>
56#include <linux/mv643xx.h>
57
58#include <asm/time.h>
59#include <asm/bootinfo.h>
60#include <asm/page.h>
61#include <asm/io.h>
62#include <asm/irq.h>
63#include <asm/pci.h>
64#include <asm/processor.h>
65#include <asm/reboot.h>
66#include <asm/marvell.h>
67#include <linux/bootmem.h>
68#include <linux/blkdev.h>
69#include "ocelot_c_fpga.h"
70
71unsigned long marvell_base;
72unsigned int cpu_clock;
73
74/* These functions are used for rebooting or halting the machine*/
75extern void momenco_ocelot_restart(char *command);
76extern void momenco_ocelot_halt(void);
77extern void momenco_ocelot_power_off(void);
78
79void momenco_time_init(void);
80
81static char reset_reason;
82
83void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, unsigned long entryhi, unsigned long pagemask);
84
85static unsigned long ENTRYLO(unsigned long paddr)
86{
87 return ((paddr & PAGE_MASK) |
88 (_PAGE_PRESENT | __READABLE | __WRITEABLE | _PAGE_GLOBAL |
89 _CACHE_UNCACHED)) >> 6;
90}
91
92/* setup code for a handoff from a version 2 PMON 2000 PROM */
93void PMON_v2_setup(void)
94{
95 /* Some wired TLB entries for the MV64340 and perhiperals. The
96 MV64340 is going to be hit on every IRQ anyway - there's
97 absolutely no point in letting it be a random TLB entry, as
98 it'll just cause needless churning of the TLB. And we use
99 the other half for the serial port, which is just a PITA
100 otherwise :)
101
102 Device Physical Virtual
103 MV64340 Internal Regs 0xf4000000 0xf4000000
104 Ocelot-C[S] PLD (CS0) 0xfc000000 0xfc000000
105 NVRAM (CS1) 0xfc800000 0xfc800000
106 UARTs (CS2) 0xfd000000 0xfd000000
107 Internal SRAM 0xfe000000 0xfe000000
108 M-Systems DOC (CS3) 0xff000000 0xff000000
109 */
110 printk("PMON_v2_setup\n");
111
112#ifdef CONFIG_64BIT
113 /* marvell and extra space */
114 add_wired_entry(ENTRYLO(0xf4000000), ENTRYLO(0xf4010000), 0xfffffffff4000000, PM_64K);
115 /* fpga, rtc, and uart */
116 add_wired_entry(ENTRYLO(0xfc000000), ENTRYLO(0xfd000000), 0xfffffffffc000000, PM_16M);
117 /* m-sys and internal SRAM */
118 add_wired_entry(ENTRYLO(0xfe000000), ENTRYLO(0xff000000), 0xfffffffffe000000, PM_16M);
119
120 marvell_base = 0xfffffffff4000000;
121#else
122 /* marvell and extra space */
123 add_wired_entry(ENTRYLO(0xf4000000), ENTRYLO(0xf4010000), 0xf4000000, PM_64K);
124 /* fpga, rtc, and uart */
125 add_wired_entry(ENTRYLO(0xfc000000), ENTRYLO(0xfd000000), 0xfc000000, PM_16M);
126 /* m-sys and internal SRAM */
127 add_wired_entry(ENTRYLO(0xfe000000), ENTRYLO(0xff000000), 0xfe000000, PM_16M);
128
129 marvell_base = 0xf4000000;
130#endif
131}
132
133unsigned long m48t37y_get_time(void)
134{
135#ifdef CONFIG_64BIT
136 unsigned char *rtc_base = (unsigned char*)0xfffffffffc800000;
137#else
138 unsigned char* rtc_base = (unsigned char*)0xfc800000;
139#endif
140 unsigned int year, month, day, hour, min, sec;
141 unsigned long flags;
142
143 spin_lock_irqsave(&rtc_lock, flags);
144 /* stop the update */
145 rtc_base[0x7ff8] = 0x40;
146
147 year = BCD2BIN(rtc_base[0x7fff]);
148 year += BCD2BIN(rtc_base[0x7ff1]) * 100;
149
150 month = BCD2BIN(rtc_base[0x7ffe]);
151
152 day = BCD2BIN(rtc_base[0x7ffd]);
153
154 hour = BCD2BIN(rtc_base[0x7ffb]);
155 min = BCD2BIN(rtc_base[0x7ffa]);
156 sec = BCD2BIN(rtc_base[0x7ff9]);
157
158 /* start the update */
159 rtc_base[0x7ff8] = 0x00;
160 spin_unlock_irqrestore(&rtc_lock, flags);
161
162 return mktime(year, month, day, hour, min, sec);
163}
164
165int m48t37y_set_time(unsigned long sec)
166{
167#ifdef CONFIG_64BIT
168 unsigned char* rtc_base = (unsigned char*)0xfffffffffc800000;
169#else
170 unsigned char* rtc_base = (unsigned char*)0xfc800000;
171#endif
172 struct rtc_time tm;
173 unsigned long flags;
174
175 /* convert to a more useful format -- note months count from 0 */
176 to_tm(sec, &tm);
177 tm.tm_mon += 1;
178
179 spin_lock_irqsave(&rtc_lock, flags);
180 /* enable writing */
181 rtc_base[0x7ff8] = 0x80;
182
183 /* year */
184 rtc_base[0x7fff] = BIN2BCD(tm.tm_year % 100);
185 rtc_base[0x7ff1] = BIN2BCD(tm.tm_year / 100);
186
187 /* month */
188 rtc_base[0x7ffe] = BIN2BCD(tm.tm_mon);
189
190 /* day */
191 rtc_base[0x7ffd] = BIN2BCD(tm.tm_mday);
192
193 /* hour/min/sec */
194 rtc_base[0x7ffb] = BIN2BCD(tm.tm_hour);
195 rtc_base[0x7ffa] = BIN2BCD(tm.tm_min);
196 rtc_base[0x7ff9] = BIN2BCD(tm.tm_sec);
197
198 /* day of week -- not really used, but let's keep it up-to-date */
199 rtc_base[0x7ffc] = BIN2BCD(tm.tm_wday + 1);
200
201 /* disable writing */
202 rtc_base[0x7ff8] = 0x00;
203 spin_unlock_irqrestore(&rtc_lock, flags);
204
205 return 0;
206}
207
208void __init plat_timer_setup(struct irqaction *irq)
209{
210 setup_irq(7, irq);
211}
212
213void momenco_time_init(void)
214{
215#ifdef CONFIG_CPU_SR71000
216 mips_hpt_frequency = cpu_clock;
217#elif defined(CONFIG_CPU_RM7000)
218 mips_hpt_frequency = cpu_clock / 2;
219#else
220#error Unknown CPU for this board
221#endif
222 printk("momenco_time_init cpu_clock=%d\n", cpu_clock);
223
224 rtc_mips_get_time = m48t37y_get_time;
225 rtc_mips_set_time = m48t37y_set_time;
226}
227
228void __init plat_mem_setup(void)
229{
230 unsigned int tmpword;
231
232 board_time_init = momenco_time_init;
233
234 _machine_restart = momenco_ocelot_restart;
235 _machine_halt = momenco_ocelot_halt;
236 pm_power_off = momenco_ocelot_power_off;
237
238 /*
239 * initrd_start = (unsigned long)ocelot_initrd_start;
240 * initrd_end = (unsigned long)ocelot_initrd_start + (ulong)ocelot_initrd_size;
241 * initrd_below_start_ok = 1;
242 */
243
244 /* do handoff reconfiguration */
245 PMON_v2_setup();
246
247 /* shut down ethernet ports, just to be sure our memory doesn't get
248 * corrupted by random ethernet traffic.
249 */
250 MV_WRITE(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(0), 0xff << 8);
251 MV_WRITE(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(1), 0xff << 8);
252 MV_WRITE(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(0), 0xff << 8);
253 MV_WRITE(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(1), 0xff << 8);
254 do {}
255 while (MV_READ(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(0)) & 0xff);
256 do {}
257 while (MV_READ(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(1)) & 0xff);
258 do {}
259 while (MV_READ(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(0)) & 0xff);
260 do {}
261 while (MV_READ(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(1)) & 0xff);
262 MV_WRITE(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(0),
263 MV_READ(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(0)) & ~1);
264 MV_WRITE(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(1),
265 MV_READ(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(1)) & ~1);
266
267 /* Turn off the Bit-Error LED */
268 OCELOT_FPGA_WRITE(0x80, CLR);
269
270 tmpword = OCELOT_FPGA_READ(BOARDREV);
271#ifdef CONFIG_CPU_SR71000
272 if (tmpword < 26)
273 printk("Momenco Ocelot-CS: Board Assembly Rev. %c\n",
274 'A'+tmpword);
275 else
276 printk("Momenco Ocelot-CS: Board Assembly Revision #0x%x\n",
277 tmpword);
278#else
279 if (tmpword < 26)
280 printk("Momenco Ocelot-C: Board Assembly Rev. %c\n",
281 'A'+tmpword);
282 else
283 printk("Momenco Ocelot-C: Board Assembly Revision #0x%x\n",
284 tmpword);
285#endif
286
287 tmpword = OCELOT_FPGA_READ(FPGA_REV);
288 printk("FPGA Rev: %d.%d\n", tmpword>>4, tmpword&15);
289 tmpword = OCELOT_FPGA_READ(RESET_STATUS);
290 printk("Reset reason: 0x%x\n", tmpword);
291 switch (tmpword) {
292 case 0x1:
293 printk(" - Power-up reset\n");
294 break;
295 case 0x2:
296 printk(" - Push-button reset\n");
297 break;
298 case 0x4:
299 printk(" - cPCI bus reset\n");
300 break;
301 case 0x8:
302 printk(" - Watchdog reset\n");
303 break;
304 case 0x10:
305 printk(" - Software reset\n");
306 break;
307 default:
308 printk(" - Unknown reset cause\n");
309 }
310 reset_reason = tmpword;
311 OCELOT_FPGA_WRITE(0xff, RESET_STATUS);
312
313 tmpword = OCELOT_FPGA_READ(CPCI_ID);
314 printk("cPCI ID register: 0x%02x\n", tmpword);
315 printk(" - Slot number: %d\n", tmpword & 0x1f);
316 printk(" - PCI bus present: %s\n", tmpword & 0x40 ? "yes" : "no");
317 printk(" - System Slot: %s\n", tmpword & 0x20 ? "yes" : "no");
318
319 tmpword = OCELOT_FPGA_READ(BOARD_STATUS);
320 printk("Board Status register: 0x%02x\n", tmpword);
321 printk(" - User jumper: %s\n", (tmpword & 0x80)?"installed":"absent");
322 printk(" - Boot flash write jumper: %s\n", (tmpword&0x40)?"installed":"absent");
323 printk(" - L3 Cache size: %d MiB\n", (1<<((tmpword&12) >> 2))&~1);
324 printk(" - SDRAM size: %d MiB\n", 1<<(6+(tmpword&3)));
325
326 switch(tmpword &3) {
327 case 3:
328 /* 512MiB */
329 add_memory_region(0x0, 0x200<<20, BOOT_MEM_RAM);
330 break;
331 case 2:
332 /* 256MiB */
333 add_memory_region(0x0, 0x100<<20, BOOT_MEM_RAM);
334 break;
335 case 1:
336 /* 128MiB */
337 add_memory_region(0x0, 0x80<<20, BOOT_MEM_RAM);
338 break;
339 case 0:
340 /* 1GiB -- needs CONFIG_HIGHMEM */
341 add_memory_region(0x0, 0x400<<20, BOOT_MEM_RAM);
342 break;
343 }
344}
345
346/*
347 * This needs to be one of the first initcalls, because no I/O port access
348 * can work before this
349 */
350static int io_base_ioremap(void)
351{
352 void __iomem * io_remap_range = ioremap(0xc0000000UL, 0x10000);
353
354 if (!io_remap_range)
355 panic("Could not ioremap I/O port range");
356
357 set_io_port_base((unsigned long) io_remap_range);
358
359 return 0;
360}
361
362module_init(io_base_ioremap);
diff --git a/arch/mips/momentum/ocelot_c/uart-irq.c b/arch/mips/momentum/ocelot_c/uart-irq.c
deleted file mode 100644
index de1a31ee52f3..000000000000
--- a/arch/mips/momentum/ocelot_c/uart-irq.c
+++ /dev/null
@@ -1,91 +0,0 @@
1/*
2 * Copyright 2002 Momentum Computer
3 * Author: mdharm@momenco.com
4 *
5 * arch/mips/momentum/ocelot_c/uart-irq.c
6 * Interrupt routines for UARTs. Interrupt numbers are assigned from
7 * 80 to 81 (2 interrupt sources).
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
13 */
14
15#include <linux/module.h>
16#include <linux/interrupt.h>
17#include <linux/irq.h>
18#include <linux/kernel.h>
19#include <linux/sched.h>
20#include <linux/kernel_stat.h>
21#include <asm/io.h>
22#include <asm/irq.h>
23#include "ocelot_c_fpga.h"
24
25static inline int ls1bit8(unsigned int x)
26{
27 int b = 7, s;
28
29 s = 4; if (((unsigned char)(x << 4)) == 0) s = 0; b -= s; x <<= s;
30 s = 2; if (((unsigned char)(x << 2)) == 0) s = 0; b -= s; x <<= s;
31 s = 1; if (((unsigned char)(x << 1)) == 0) s = 0; b -= s;
32
33 return b;
34}
35
36/* mask off an interrupt -- 0 is enable, 1 is disable */
37static inline void mask_uart_irq(unsigned int irq)
38{
39 uint8_t value;
40
41 value = OCELOT_FPGA_READ(UART_INTMASK);
42 value |= 1 << (irq - 74);
43 OCELOT_FPGA_WRITE(value, UART_INTMASK);
44
45 /* read the value back to assure that it's really been written */
46 value = OCELOT_FPGA_READ(UART_INTMASK);
47}
48
49/* unmask an interrupt -- 0 is enable, 1 is disable */
50static inline void unmask_uart_irq(unsigned int irq)
51{
52 uint8_t value;
53
54 value = OCELOT_FPGA_READ(UART_INTMASK);
55 value &= ~(1 << (irq - 74));
56 OCELOT_FPGA_WRITE(value, UART_INTMASK);
57
58 /* read the value back to assure that it's really been written */
59 value = OCELOT_FPGA_READ(UART_INTMASK);
60}
61
62/*
63 * Interrupt handler for interrupts coming from the FPGA chip.
64 */
65void ll_uart_irq(void)
66{
67 unsigned int irq_src, irq_mask;
68
69 /* read the interrupt status registers */
70 irq_src = OCELOT_FPGA_READ(UART_INTSTAT);
71 irq_mask = OCELOT_FPGA_READ(UART_INTMASK);
72
73 /* mask for just the interrupts we want */
74 irq_src &= ~irq_mask;
75
76 do_IRQ(ls1bit8(irq_src) + 74);
77}
78
79struct irq_chip uart_irq_type = {
80 .name = "UART/FPGA",
81 .ack = mask_uart_irq,
82 .mask = mask_uart_irq,
83 .mask_ack = mask_uart_irq,
84 .unmask = unmask_uart_irq,
85};
86
87void uart_irq_init(void)
88{
89 set_irq_chip_and_handler(80, &uart_irq_type, handle_level_irq);
90 set_irq_chip_and_handler(81, &uart_irq_type, handle_level_irq);
91}
diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile
index aba3dbf47eda..f26ede001a0b 100644
--- a/arch/mips/pci/Makefile
+++ b/arch/mips/pci/Makefile
@@ -9,9 +9,7 @@ obj-y += pci.o pci-dac.o
9# 9#
10obj-$(CONFIG_MIPS_BONITO64) += ops-bonito64.o 10obj-$(CONFIG_MIPS_BONITO64) += ops-bonito64.o
11obj-$(CONFIG_PCI_GT64XXX_PCI0) += ops-gt64xxx_pci0.o 11obj-$(CONFIG_PCI_GT64XXX_PCI0) += ops-gt64xxx_pci0.o
12obj-$(CONFIG_PCI_MARVELL) += ops-marvell.o
13obj-$(CONFIG_MIPS_MSC) += ops-msc.o 12obj-$(CONFIG_MIPS_MSC) += ops-msc.o
14obj-$(CONFIG_MIPS_NILE4) += ops-nile4.o
15obj-$(CONFIG_MIPS_TX3927) += ops-tx3927.o 13obj-$(CONFIG_MIPS_TX3927) += ops-tx3927.o
16obj-$(CONFIG_PCI_VR41XX) += ops-vr41xx.o pci-vr41xx.o 14obj-$(CONFIG_PCI_VR41XX) += ops-vr41xx.o pci-vr41xx.o
17obj-$(CONFIG_NEC_CMBVR4133) += fixup-vr4133.o 15obj-$(CONFIG_NEC_CMBVR4133) += fixup-vr4133.o
@@ -22,17 +20,17 @@ obj-$(CONFIG_MARKEINS) += ops-emma2rh.o pci-emma2rh.o fixup-emma2rh.o
22# 20#
23obj-$(CONFIG_BASLER_EXCITE) += ops-titan.o pci-excite.o fixup-excite.o 21obj-$(CONFIG_BASLER_EXCITE) += ops-titan.o pci-excite.o fixup-excite.o
24obj-$(CONFIG_DDB5477) += fixup-ddb5477.o pci-ddb5477.o ops-ddb5477.o 22obj-$(CONFIG_DDB5477) += fixup-ddb5477.o pci-ddb5477.o ops-ddb5477.o
25obj-$(CONFIG_LASAT) += pci-lasat.o
26obj-$(CONFIG_MIPS_ATLAS) += fixup-atlas.o 23obj-$(CONFIG_MIPS_ATLAS) += fixup-atlas.o
27obj-$(CONFIG_MIPS_COBALT) += fixup-cobalt.o 24obj-$(CONFIG_MIPS_COBALT) += fixup-cobalt.o
28obj-$(CONFIG_MIPS_EV64120) += pci-ev64120.o
29obj-$(CONFIG_SOC_AU1500) += fixup-au1000.o ops-au1000.o 25obj-$(CONFIG_SOC_AU1500) += fixup-au1000.o ops-au1000.o
30obj-$(CONFIG_SOC_AU1550) += fixup-au1000.o ops-au1000.o 26obj-$(CONFIG_SOC_AU1550) += fixup-au1000.o ops-au1000.o
31obj-$(CONFIG_SOC_PNX8550) += fixup-pnx8550.o ops-pnx8550.o 27obj-$(CONFIG_SOC_PNX8550) += fixup-pnx8550.o ops-pnx8550.o
28obj-$(CONFIG_LEMOTE_FULONG) += fixup-lm2e.o ops-bonito64.o
32obj-$(CONFIG_MIPS_MALTA) += fixup-malta.o 29obj-$(CONFIG_MIPS_MALTA) += fixup-malta.o
33obj-$(CONFIG_MOMENCO_OCELOT) += fixup-ocelot.o pci-ocelot.o 30obj-$(CONFIG_MOMENCO_OCELOT) += fixup-ocelot.o pci-ocelot.o
34obj-$(CONFIG_MOMENCO_OCELOT_3) += fixup-ocelot3.o 31obj-$(CONFIG_PMC_MSP7120_GW) += fixup-pmcmsp.o ops-pmcmsp.o
35obj-$(CONFIG_MOMENCO_OCELOT_C) += fixup-ocelot-c.o pci-ocelot-c.o 32obj-$(CONFIG_PMC_MSP7120_EVAL) += fixup-pmcmsp.o ops-pmcmsp.o
33obj-$(CONFIG_PMC_MSP7120_FPGA) += fixup-pmcmsp.o ops-pmcmsp.o
36obj-$(CONFIG_PMC_YOSEMITE) += fixup-yosemite.o ops-titan.o ops-titan-ht.o \ 34obj-$(CONFIG_PMC_YOSEMITE) += fixup-yosemite.o ops-titan.o ops-titan-ht.o \
37 pci-yosemite.o 35 pci-yosemite.o
38obj-$(CONFIG_SGI_IP27) += ops-bridge.o pci-ip27.o 36obj-$(CONFIG_SGI_IP27) += ops-bridge.o pci-ip27.o
diff --git a/arch/mips/pci/fixup-atlas.c b/arch/mips/pci/fixup-atlas.c
index c6cd6e9cdfbc..45224fd2c7ba 100644
--- a/arch/mips/pci/fixup-atlas.c
+++ b/arch/mips/pci/fixup-atlas.c
@@ -58,7 +58,7 @@ static char irq_tab[][5] __initdata = {
58 {0, 0, 0, 0, 0 } /* 21: Unused */ 58 {0, 0, 0, 0, 0 } /* 21: Unused */
59}; 59};
60 60
61int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) 61int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
62{ 62{
63 return irq_tab[slot][pin]; 63 return irq_tab[slot][pin];
64} 64}
diff --git a/arch/mips/pci/fixup-au1000.c b/arch/mips/pci/fixup-au1000.c
index c2f8304fe55b..ca0276c8070a 100644
--- a/arch/mips/pci/fixup-au1000.c
+++ b/arch/mips/pci/fixup-au1000.c
@@ -35,7 +35,7 @@
35 35
36extern char irq_tab_alchemy[][5]; 36extern char irq_tab_alchemy[][5];
37 37
38int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) 38int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
39{ 39{
40 return irq_tab_alchemy[slot][pin]; 40 return irq_tab_alchemy[slot][pin];
41} 41}
diff --git a/arch/mips/pci/fixup-capcella.c b/arch/mips/pci/fixup-capcella.c
index 1e530751936c..1416bca6d1a3 100644
--- a/arch/mips/pci/fixup-capcella.c
+++ b/arch/mips/pci/fixup-capcella.c
@@ -38,7 +38,7 @@ static char irq_tab_capcella[][5] __initdata = {
38 [14] = { -1, INTA, INTB, INTC, INTD } 38 [14] = { -1, INTA, INTB, INTC, INTD }
39}; 39};
40 40
41int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) 41int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
42{ 42{
43 return irq_tab_capcella[slot][pin]; 43 return irq_tab_capcella[slot][pin];
44} 44}
diff --git a/arch/mips/pci/fixup-cobalt.c b/arch/mips/pci/fixup-cobalt.c
index d57ffd7242ca..7fc475f7eae5 100644
--- a/arch/mips/pci/fixup-cobalt.c
+++ b/arch/mips/pci/fixup-cobalt.c
@@ -161,7 +161,7 @@ static char irq_tab_raq2[] __initdata = {
161 [COBALT_PCICONF_ETH1] = COBALT_ETH1_IRQ 161 [COBALT_PCICONF_ETH1] = COBALT_ETH1_IRQ
162}; 162};
163 163
164int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) 164int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
165{ 165{
166 if (cobalt_board_id < COBALT_BRD_ID_QUBE2) 166 if (cobalt_board_id < COBALT_BRD_ID_QUBE2)
167 return irq_tab_qube1[slot]; 167 return irq_tab_qube1[slot];
diff --git a/arch/mips/pci/fixup-emma2rh.c b/arch/mips/pci/fixup-emma2rh.c
index 7abcfd175d43..a2705895561d 100644
--- a/arch/mips/pci/fixup-emma2rh.c
+++ b/arch/mips/pci/fixup-emma2rh.c
@@ -89,7 +89,7 @@ static void __devinit emma2rh_pci_host_fixup(struct pci_dev *dev)
89DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_EMMA2RH, 89DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_EMMA2RH,
90 emma2rh_pci_host_fixup); 90 emma2rh_pci_host_fixup);
91 91
92int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) 92int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
93{ 93{
94 return irq_map[slot][pin]; 94 return irq_map[slot][pin];
95} 95}
diff --git a/arch/mips/pci/fixup-excite.c b/arch/mips/pci/fixup-excite.c
index 1da696d43f00..cd64d9f177c4 100644
--- a/arch/mips/pci/fixup-excite.c
+++ b/arch/mips/pci/fixup-excite.c
@@ -21,7 +21,7 @@
21#include <linux/pci.h> 21#include <linux/pci.h>
22#include <excite.h> 22#include <excite.h>
23 23
24int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) 24int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
25{ 25{
26 if (pin == 0) 26 if (pin == 0)
27 return -1; 27 return -1;
diff --git a/arch/mips/pci/fixup-ip32.c b/arch/mips/pci/fixup-ip32.c
index 3e66b0aa63ca..190fffd08d3e 100644
--- a/arch/mips/pci/fixup-ip32.c
+++ b/arch/mips/pci/fixup-ip32.c
@@ -39,7 +39,7 @@ static char irq_tab_mace[][5] __initdata = {
39 * irqs. I suppose a device without a pin A will thank us for doing it 39 * irqs. I suppose a device without a pin A will thank us for doing it
40 * right if there exists such a broken piece of crap. 40 * right if there exists such a broken piece of crap.
41 */ 41 */
42int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) 42int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
43{ 43{
44 return irq_tab_mace[slot][pin]; 44 return irq_tab_mace[slot][pin];
45} 45}
diff --git a/arch/mips/pci/fixup-jmr3927.c b/arch/mips/pci/fixup-jmr3927.c
index 73d18503517c..e974394be7bc 100644
--- a/arch/mips/pci/fixup-jmr3927.c
+++ b/arch/mips/pci/fixup-jmr3927.c
@@ -33,7 +33,7 @@
33 33
34#include <asm/jmr3927/jmr3927.h> 34#include <asm/jmr3927/jmr3927.h>
35 35
36int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) 36int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
37{ 37{
38 unsigned char irq = pin; 38 unsigned char irq = pin;
39 39
diff --git a/arch/mips/pci/fixup-lm2e.c b/arch/mips/pci/fixup-lm2e.c
new file mode 100644
index 000000000000..e18ae4f574c1
--- /dev/null
+++ b/arch/mips/pci/fixup-lm2e.c
@@ -0,0 +1,242 @@
1/*
2 * fixup-lm2e.c
3 *
4 * Copyright (C) 2004 ICT CAS
5 * Author: Li xiaoyu, ICT CAS
6 * lixy@ict.ac.cn
7 *
8 * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology
9 * Author: Fuxin Zhang, zhangfx@lemote.com
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your
14 * option) any later version.
15 *
16 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
19 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
22 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
23 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 * You should have received a copy of the GNU General Public License along
28 * with this program; if not, write to the Free Software Foundation, Inc.,
29 * 675 Mass Ave, Cambridge, MA 02139, USA.
30 *
31 */
32#include <linux/init.h>
33#include <linux/pci.h>
34#include <asm/mips-boards/bonito64.h>
35
36/* South bridge slot number is set by the pci probe process */
37static u8 sb_slot = 5;
38
39int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
40{
41 int irq = 0;
42
43 if (slot == sb_slot) {
44 switch (PCI_FUNC(dev->devfn)) {
45 case 2:
46 irq = 10;
47 break;
48 case 3:
49 irq = 11;
50 break;
51 case 5:
52 irq = 9;
53 break;
54 }
55 } else {
56 irq = BONITO_IRQ_BASE + 25 + pin;
57 }
58 return irq;
59
60}
61
62/* Do platform specific device initialization at pci_enable_device() time */
63int pcibios_plat_dev_init(struct pci_dev *dev)
64{
65 return 0;
66}
67
68static void __init loongson2e_nec_fixup(struct pci_dev *pdev)
69{
70 unsigned int val;
71
72 /* Configues port 1, 2, 3, 4 to be validate*/
73 pci_read_config_dword(pdev, 0xe0, &val);
74 pci_write_config_dword(pdev, 0xe0, (val & ~7) | 0x4);
75
76 /* System clock is 48-MHz Oscillator. */
77 pci_write_config_dword(pdev, 0xe4, 1 << 5);
78}
79
80static void __init loongson2e_686b_func0_fixup(struct pci_dev *pdev)
81{
82 unsigned char c;
83
84 sb_slot = PCI_SLOT(pdev->devfn);
85
86 printk(KERN_INFO "via686b fix: ISA bridge\n");
87
88 /* Enable I/O Recovery time */
89 pci_write_config_byte(pdev, 0x40, 0x08);
90
91 /* Enable ISA refresh */
92 pci_write_config_byte(pdev, 0x41, 0x01);
93
94 /* disable ISA line buffer */
95 pci_write_config_byte(pdev, 0x45, 0x00);
96
97 /* Gate INTR, and flush line buffer */
98 pci_write_config_byte(pdev, 0x46, 0xe0);
99
100 /* Disable PCI Delay Transaction, Enable EISA ports 4D0/4D1. */
101 /* pci_write_config_byte(pdev, 0x47, 0x20); */
102
103 /*
104 * enable PCI Delay Transaction, Enable EISA ports 4D0/4D1.
105 * enable time-out timer
106 */
107 pci_write_config_byte(pdev, 0x47, 0xe6);
108
109 /*
110 * enable level trigger on pci irqs: 9,10,11,13
111 * important! without this PCI interrupts won't work
112 */
113 outb(0x2e, 0x4d1);
114
115 /* 512 K PCI Decode */
116 pci_write_config_byte(pdev, 0x48, 0x01);
117
118 /* Wait for PGNT before grant to ISA Master/DMA */
119 pci_write_config_byte(pdev, 0x4a, 0x84);
120
121 /*
122 * Plug'n'Play
123 *
124 * Parallel DRQ 3, Floppy DRQ 2 (default)
125 */
126 pci_write_config_byte(pdev, 0x50, 0x0e);
127
128 /*
129 * IRQ Routing for Floppy and Parallel port
130 *
131 * IRQ 6 for floppy, IRQ 7 for parallel port
132 */
133 pci_write_config_byte(pdev, 0x51, 0x76);
134
135 /* IRQ Routing for serial ports (take IRQ 3 and 4) */
136 pci_write_config_byte(pdev, 0x52, 0x34);
137
138 /* All IRQ's level triggered. */
139 pci_write_config_byte(pdev, 0x54, 0x00);
140
141 /* route PIRQA-D irq */
142 pci_write_config_byte(pdev, 0x55, 0x90); /* bit 7-4, PIRQA */
143 pci_write_config_byte(pdev, 0x56, 0xba); /* bit 7-4, PIRQC; */
144 /* 3-0, PIRQB */
145 pci_write_config_byte(pdev, 0x57, 0xd0); /* bit 7-4, PIRQD */
146
147 /* enable function 5/6, audio/modem */
148 pci_read_config_byte(pdev, 0x85, &c);
149 c &= ~(0x3 << 2);
150 pci_write_config_byte(pdev, 0x85, c);
151
152 printk(KERN_INFO"via686b fix: ISA bridge done\n");
153}
154
155static void __init loongson2e_686b_func1_fixup(struct pci_dev *pdev)
156{
157 printk(KERN_INFO"via686b fix: IDE\n");
158
159 /* Modify IDE controller setup */
160 pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 48);
161 pci_write_config_byte(pdev, PCI_COMMAND,
162 PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
163 PCI_COMMAND_MASTER);
164 pci_write_config_byte(pdev, 0x40, 0x0b);
165 /* legacy mode */
166 pci_write_config_byte(pdev, 0x42, 0x09);
167
168#if 1/* play safe, otherwise we may see notebook's usb keyboard lockup */
169 /* disable read prefetch/write post buffers */
170 pci_write_config_byte(pdev, 0x41, 0x02);
171
172 /* use 3/4 as fifo thresh hold */
173 pci_write_config_byte(pdev, 0x43, 0x0a);
174 pci_write_config_byte(pdev, 0x44, 0x00);
175
176 pci_write_config_byte(pdev, 0x45, 0x00);
177#else
178 pci_write_config_byte(pdev, 0x41, 0xc2);
179 pci_write_config_byte(pdev, 0x43, 0x35);
180 pci_write_config_byte(pdev, 0x44, 0x1c);
181
182 pci_write_config_byte(pdev, 0x45, 0x10);
183#endif
184
185 printk(KERN_INFO"via686b fix: IDE done\n");
186}
187
188static void __init loongson2e_686b_func2_fixup(struct pci_dev *pdev)
189{
190 /* irq routing */
191 pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, 10);
192}
193
194static void __init loongson2e_686b_func3_fixup(struct pci_dev *pdev)
195{
196 /* irq routing */
197 pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, 11);
198}
199
200static void __init loongson2e_686b_func5_fixup(struct pci_dev *pdev)
201{
202 unsigned int val;
203 unsigned char c;
204
205 /* enable IO */
206 pci_write_config_byte(pdev, PCI_COMMAND,
207 PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
208 PCI_COMMAND_MASTER);
209 pci_read_config_dword(pdev, 0x4, &val);
210 pci_write_config_dword(pdev, 0x4, val | 1);
211
212 /* route ac97 IRQ */
213 pci_write_config_byte(pdev, 0x3c, 9);
214
215 pci_read_config_byte(pdev, 0x8, &c);
216
217 /* link control: enable link & SGD PCM output */
218 pci_write_config_byte(pdev, 0x41, 0xcc);
219
220 /* disable game port, FM, midi, sb, enable write to reg2c-2f */
221 pci_write_config_byte(pdev, 0x42, 0x20);
222
223 /* we are using Avance logic codec */
224 pci_write_config_word(pdev, 0x2c, 0x1005);
225 pci_write_config_word(pdev, 0x2e, 0x4710);
226 pci_read_config_dword(pdev, 0x2c, &val);
227
228 pci_write_config_byte(pdev, 0x42, 0x0);
229}
230
231DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686,
232 loongson2e_686b_func0_fixup);
233DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1,
234 loongson2e_686b_func1_fixup);
235DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_2,
236 loongson2e_686b_func2_fixup);
237DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3,
238 loongson2e_686b_func3_fixup);
239DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_5,
240 loongson2e_686b_func5_fixup);
241DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_USB,
242 loongson2e_nec_fixup);
diff --git a/arch/mips/pci/fixup-malta.c b/arch/mips/pci/fixup-malta.c
index bf2c41d1e9c5..0f48498bc231 100644
--- a/arch/mips/pci/fixup-malta.c
+++ b/arch/mips/pci/fixup-malta.c
@@ -36,7 +36,7 @@ static char irq_tab[][5] __initdata = {
36 {0, PCID, PCIA, PCIB, PCIC } /* 21: PCI Slot 4 */ 36 {0, PCID, PCIA, PCIB, PCIC } /* 21: PCI Slot 4 */
37}; 37};
38 38
39int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) 39int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
40{ 40{
41 int virq; 41 int virq;
42 virq = irq_tab[slot][pin]; 42 virq = irq_tab[slot][pin];
diff --git a/arch/mips/pci/fixup-mpc30x.c b/arch/mips/pci/fixup-mpc30x.c
index 3c9ae41f7517..591159625722 100644
--- a/arch/mips/pci/fixup-mpc30x.c
+++ b/arch/mips/pci/fixup-mpc30x.c
@@ -34,7 +34,7 @@ static const int irq_tab_mpc30x[] __initdata = {
34 [29] = MQ200_IRQ, 34 [29] = MQ200_IRQ,
35}; 35};
36 36
37int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) 37int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
38{ 38{
39 if (slot == 30) 39 if (slot == 30)
40 return internal_func_irqs[PCI_FUNC(dev->devfn)]; 40 return internal_func_irqs[PCI_FUNC(dev->devfn)];
diff --git a/arch/mips/pci/fixup-ocelot-c.c b/arch/mips/pci/fixup-ocelot-c.c
deleted file mode 100644
index d45494807a33..000000000000
--- a/arch/mips/pci/fixup-ocelot-c.c
+++ /dev/null
@@ -1,41 +0,0 @@
1/*
2 * Copyright 2002 Momentum Computer Inc.
3 * Author: Matthew Dharm <mdharm@momenco.com>
4 *
5 * Based on work for the Linux port to the Ocelot board, which is
6 * Copyright 2001 MontaVista Software Inc.
7 * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
8 *
9 * arch/mips/momentum/ocelot_g/pci.c
10 * Board-specific PCI routines for mv64340 controller.
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version.
16 */
17#include <linux/types.h>
18#include <linux/pci.h>
19#include <linux/kernel.h>
20#include <linux/init.h>
21
22int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
23{
24 int bus = dev->bus->number;
25
26 if (bus == 0 && slot == 1)
27 return 2; /* PCI-X A */
28 if (bus == 1 && slot == 1)
29 return 12; /* PCI-X B */
30 if (bus == 1 && slot == 2)
31 return 4; /* PCI B */
32
33return 0;
34 panic("Whooops in pcibios_map_irq");
35}
36
37/* Do platform specific device initialization at pci_enable_device() time */
38int pcibios_plat_dev_init(struct pci_dev *dev)
39{
40 return 0;
41}
diff --git a/arch/mips/pci/fixup-ocelot3.c b/arch/mips/pci/fixup-ocelot3.c
deleted file mode 100644
index ececc03ec620..000000000000
--- a/arch/mips/pci/fixup-ocelot3.c
+++ /dev/null
@@ -1,41 +0,0 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2004 Montavista Software Inc.
7 * Author: Manish Lachwani (mlachwani@mvista.com)
8 *
9 * Looking at the schematics for the Ocelot-3 board, there are
10 * two PCI busses and each bus has two PCI slots.
11 */
12#include <linux/kernel.h>
13#include <linux/init.h>
14#include <linux/pci.h>
15#include <asm/mipsregs.h>
16
17/*
18 * Do platform specific device initialization at
19 * pci_enable_device() time
20 */
21int pcibios_plat_dev_init(struct pci_dev *dev)
22{
23 return 0;
24}
25
26int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
27{
28 int bus = dev->bus->number;
29
30 if (bus == 0 && slot == 1)
31 return 2; /* PCI-X A */
32 if (bus == 0 && slot == 2)
33 return 3; /* PCI-X B */
34 if (bus == 1 && slot == 1)
35 return 4; /* PCI A */
36 if (bus == 1 && slot == 2)
37 return 5; /* PCI B */
38
39return 0;
40 panic("Whooops in pcibios_map_irq");
41}
diff --git a/arch/mips/pci/fixup-pmcmsp.c b/arch/mips/pci/fixup-pmcmsp.c
new file mode 100644
index 000000000000..00261211dbfa
--- /dev/null
+++ b/arch/mips/pci/fixup-pmcmsp.c
@@ -0,0 +1,216 @@
1/*
2 * PMC-Sierra MSP board specific pci fixups.
3 *
4 * Copyright 2001 MontaVista Software Inc.
5 * Copyright 2005-2007 PMC-Sierra, Inc
6 *
7 * Author: MontaVista Software, Inc.
8 * ppopov@mvista.com or source@mvista.com
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 *
15 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
16 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
17 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
18 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
21 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
22 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 *
26 * You should have received a copy of the GNU General Public License along
27 * with this program; if not, write to the Free Software Foundation, Inc.,
28 * 675 Mass Ave, Cambridge, MA 02139, USA.
29 */
30
31#ifdef CONFIG_PCI
32
33#include <linux/types.h>
34#include <linux/pci.h>
35#include <linux/kernel.h>
36#include <linux/init.h>
37
38#include <asm/byteorder.h>
39
40#include <msp_pci.h>
41#include <msp_cic_int.h>
42
43/* PCI interrupt pins */
44#define IRQ4 MSP_INT_EXT4
45#define IRQ5 MSP_INT_EXT5
46#define IRQ6 MSP_INT_EXT6
47
48#if defined(CONFIG_PMC_MSP7120_GW)
49/* Garibaldi Board IRQ wiring to PCI slots */
50static char irq_tab[][5] __initdata = {
51 /* INTA INTB INTC INTD */
52 {0, 0, 0, 0, 0 }, /* (AD[0]): Unused */
53 {0, 0, 0, 0, 0 }, /* (AD[1]): Unused */
54 {0, 0, 0, 0, 0 }, /* (AD[2]): Unused */
55 {0, 0, 0, 0, 0 }, /* (AD[3]): Unused */
56 {0, 0, 0, 0, 0 }, /* (AD[4]): Unused */
57 {0, 0, 0, 0, 0 }, /* (AD[5]): Unused */
58 {0, 0, 0, 0, 0 }, /* (AD[6]): Unused */
59 {0, 0, 0, 0, 0 }, /* (AD[7]): Unused */
60 {0, 0, 0, 0, 0 }, /* (AD[8]): Unused */
61 {0, 0, 0, 0, 0 }, /* (AD[9]): Unused */
62 {0, 0, 0, 0, 0 }, /* 0 (AD[10]): Unused */
63 {0, 0, 0, 0, 0 }, /* 1 (AD[11]): Unused */
64 {0, 0, 0, 0, 0 }, /* 2 (AD[12]): Unused */
65 {0, 0, 0, 0, 0 }, /* 3 (AD[13]): Unused */
66 {0, 0, 0, 0, 0 }, /* 4 (AD[14]): Unused */
67 {0, 0, 0, 0, 0 }, /* 5 (AD[15]): Unused */
68 {0, 0, 0, 0, 0 }, /* 6 (AD[16]): Unused */
69 {0, 0, 0, 0, 0 }, /* 7 (AD[17]): Unused */
70 {0, 0, 0, 0, 0 }, /* 8 (AD[18]): Unused */
71 {0, 0, 0, 0, 0 }, /* 9 (AD[19]): Unused */
72 {0, 0, 0, 0, 0 }, /* 10 (AD[20]): Unused */
73 {0, 0, 0, 0, 0 }, /* 11 (AD[21]): Unused */
74 {0, 0, 0, 0, 0 }, /* 12 (AD[22]): Unused */
75 {0, 0, 0, 0, 0 }, /* 13 (AD[23]): Unused */
76 {0, 0, 0, 0, 0 }, /* 14 (AD[24]): Unused */
77 {0, 0, 0, 0, 0 }, /* 15 (AD[25]): Unused */
78 {0, 0, 0, 0, 0 }, /* 16 (AD[26]): Unused */
79 {0, 0, 0, 0, 0 }, /* 17 (AD[27]): Unused */
80 {0, IRQ4, IRQ4, 0, 0 }, /* 18 (AD[28]): slot 0 */
81 {0, 0, 0, 0, 0 }, /* 19 (AD[29]): Unused */
82 {0, IRQ5, IRQ5, 0, 0 }, /* 20 (AD[30]): slot 1 */
83 {0, IRQ6, IRQ6, 0, 0 } /* 21 (AD[31]): slot 2 */
84};
85
86#elif defined(CONFIG_PMC_MSP7120_EVAL)
87
88/* MSP7120 Eval Board IRQ wiring to PCI slots */
89static char irq_tab[][5] __initdata = {
90 /* INTA INTB INTC INTD */
91 {0, 0, 0, 0, 0 }, /* (AD[0]): Unused */
92 {0, 0, 0, 0, 0 }, /* (AD[1]): Unused */
93 {0, 0, 0, 0, 0 }, /* (AD[2]): Unused */
94 {0, 0, 0, 0, 0 }, /* (AD[3]): Unused */
95 {0, 0, 0, 0, 0 }, /* (AD[4]): Unused */
96 {0, 0, 0, 0, 0 }, /* (AD[5]): Unused */
97 {0, 0, 0, 0, 0 }, /* (AD[6]): Unused */
98 {0, 0, 0, 0, 0 }, /* (AD[7]): Unused */
99 {0, 0, 0, 0, 0 }, /* (AD[8]): Unused */
100 {0, 0, 0, 0, 0 }, /* (AD[9]): Unused */
101 {0, 0, 0, 0, 0 }, /* 0 (AD[10]): Unused */
102 {0, 0, 0, 0, 0 }, /* 1 (AD[11]): Unused */
103 {0, 0, 0, 0, 0 }, /* 2 (AD[12]): Unused */
104 {0, 0, 0, 0, 0 }, /* 3 (AD[13]): Unused */
105 {0, 0, 0, 0, 0 }, /* 4 (AD[14]): Unused */
106 {0, 0, 0, 0, 0 }, /* 5 (AD[15]): Unused */
107 {0, IRQ6, IRQ6, 0, 0 }, /* 6 (AD[16]): slot 3 (mini) */
108 {0, IRQ5, IRQ5, 0, 0 }, /* 7 (AD[17]): slot 2 (mini) */
109 {0, IRQ4, IRQ4, IRQ4, IRQ4}, /* 8 (AD[18]): slot 0 (PCI) */
110 {0, IRQ5, IRQ5, IRQ5, IRQ5}, /* 9 (AD[19]): slot 1 (PCI) */
111 {0, 0, 0, 0, 0 }, /* 10 (AD[20]): Unused */
112 {0, 0, 0, 0, 0 }, /* 11 (AD[21]): Unused */
113 {0, 0, 0, 0, 0 }, /* 12 (AD[22]): Unused */
114 {0, 0, 0, 0, 0 }, /* 13 (AD[23]): Unused */
115 {0, 0, 0, 0, 0 }, /* 14 (AD[24]): Unused */
116 {0, 0, 0, 0, 0 }, /* 15 (AD[25]): Unused */
117 {0, 0, 0, 0, 0 }, /* 16 (AD[26]): Unused */
118 {0, 0, 0, 0, 0 }, /* 17 (AD[27]): Unused */
119 {0, 0, 0, 0, 0 }, /* 18 (AD[28]): Unused */
120 {0, 0, 0, 0, 0 }, /* 19 (AD[29]): Unused */
121 {0, 0, 0, 0, 0 }, /* 20 (AD[30]): Unused */
122 {0, 0, 0, 0, 0 } /* 21 (AD[31]): Unused */
123};
124
125#else
126
127/* Unknown board -- don't assign any IRQs */
128static char irq_tab[][5] __initdata = {
129 /* INTA INTB INTC INTD */
130 {0, 0, 0, 0, 0 }, /* (AD[0]): Unused */
131 {0, 0, 0, 0, 0 }, /* (AD[1]): Unused */
132 {0, 0, 0, 0, 0 }, /* (AD[2]): Unused */
133 {0, 0, 0, 0, 0 }, /* (AD[3]): Unused */
134 {0, 0, 0, 0, 0 }, /* (AD[4]): Unused */
135 {0, 0, 0, 0, 0 }, /* (AD[5]): Unused */
136 {0, 0, 0, 0, 0 }, /* (AD[6]): Unused */
137 {0, 0, 0, 0, 0 }, /* (AD[7]): Unused */
138 {0, 0, 0, 0, 0 }, /* (AD[8]): Unused */
139 {0, 0, 0, 0, 0 }, /* (AD[9]): Unused */
140 {0, 0, 0, 0, 0 }, /* 0 (AD[10]): Unused */
141 {0, 0, 0, 0, 0 }, /* 1 (AD[11]): Unused */
142 {0, 0, 0, 0, 0 }, /* 2 (AD[12]): Unused */
143 {0, 0, 0, 0, 0 }, /* 3 (AD[13]): Unused */
144 {0, 0, 0, 0, 0 }, /* 4 (AD[14]): Unused */
145 {0, 0, 0, 0, 0 }, /* 5 (AD[15]): Unused */
146 {0, 0, 0, 0, 0 }, /* 6 (AD[16]): Unused */
147 {0, 0, 0, 0, 0 }, /* 7 (AD[17]): Unused */
148 {0, 0, 0, 0, 0 }, /* 8 (AD[18]): Unused */
149 {0, 0, 0, 0, 0 }, /* 9 (AD[19]): Unused */
150 {0, 0, 0, 0, 0 }, /* 10 (AD[20]): Unused */
151 {0, 0, 0, 0, 0 }, /* 11 (AD[21]): Unused */
152 {0, 0, 0, 0, 0 }, /* 12 (AD[22]): Unused */
153 {0, 0, 0, 0, 0 }, /* 13 (AD[23]): Unused */
154 {0, 0, 0, 0, 0 }, /* 14 (AD[24]): Unused */
155 {0, 0, 0, 0, 0 }, /* 15 (AD[25]): Unused */
156 {0, 0, 0, 0, 0 }, /* 16 (AD[26]): Unused */
157 {0, 0, 0, 0, 0 }, /* 17 (AD[27]): Unused */
158 {0, 0, 0, 0, 0 }, /* 18 (AD[28]): Unused */
159 {0, 0, 0, 0, 0 }, /* 19 (AD[29]): Unused */
160 {0, 0, 0, 0, 0 }, /* 20 (AD[30]): Unused */
161 {0, 0, 0, 0, 0 } /* 21 (AD[31]): Unused */
162};
163#endif
164
165/*****************************************************************************
166 *
167 * FUNCTION: pcibios_plat_dev_init
168 * _________________________________________________________________________
169 *
170 * DESCRIPTION: Perform platform specific device initialization at
171 * pci_enable_device() time.
172 * None are needed for the MSP7120 PCI Controller.
173 *
174 * INPUTS: dev - structure describing the PCI device
175 *
176 * OUTPUTS: none
177 *
178 * RETURNS: PCIBIOS_SUCCESSFUL
179 *
180 ****************************************************************************/
181int pcibios_plat_dev_init(struct pci_dev *dev)
182{
183 return PCIBIOS_SUCCESSFUL;
184}
185
186/*****************************************************************************
187 *
188 * FUNCTION: pcibios_map_irq
189 * _________________________________________________________________________
190 *
191 * DESCRIPTION: Perform board supplied PCI IRQ mapping routine.
192 *
193 * INPUTS: dev - unused
194 * slot - PCI slot. Identified by which bit of the AD[] bus
195 * drives the IDSEL line. AD[10] is 0, AD[31] is
196 * slot 21.
197 * pin - numbered using the scheme of the PCI_INTERRUPT_PIN
198 * field of the config header.
199 *
200 * OUTPUTS: none
201 *
202 * RETURNS: IRQ number
203 *
204 ****************************************************************************/
205int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
206{
207#if !defined(CONFIG_PMC_MSP7120_GW) && !defined(CONFIG_PMC_MSP7120_EVAL)
208 printk(KERN_WARNING "PCI: unknown board, no PCI IRQs assigned.\n");
209#endif
210 printk(KERN_WARNING "PCI: irq_tab returned %d for slot=%d pin=%d\n",
211 irq_tab[slot][pin], slot, pin);
212
213 return irq_tab[slot][pin];
214}
215
216#endif /* CONFIG_PCI */
diff --git a/arch/mips/pci/fixup-pnx8550.c b/arch/mips/pci/fixup-pnx8550.c
index 50546dab6689..96857ac63bf5 100644
--- a/arch/mips/pci/fixup-pnx8550.c
+++ b/arch/mips/pci/fixup-pnx8550.c
@@ -45,7 +45,7 @@ void __init pcibios_fixup(void)
45 /* nothing to do here */ 45 /* nothing to do here */
46} 46}
47 47
48int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) 48int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
49{ 49{
50 return pnx8550_irq_tab[slot][pin]; 50 return pnx8550_irq_tab[slot][pin];
51} 51}
diff --git a/arch/mips/pci/fixup-rbtx4927.c b/arch/mips/pci/fixup-rbtx4927.c
index ceeb1860895a..3cdbecb8e714 100644
--- a/arch/mips/pci/fixup-rbtx4927.c
+++ b/arch/mips/pci/fixup-rbtx4927.c
@@ -119,7 +119,7 @@ int pci_get_irq(struct pci_dev *dev, int pin)
119 return irq; 119 return irq;
120} 120}
121 121
122int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) 122int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
123{ 123{
124 unsigned char irq; 124 unsigned char irq;
125 125
diff --git a/arch/mips/pci/fixup-sni.c b/arch/mips/pci/fixup-sni.c
index 36e5fb1b3786..a45bedd17233 100644
--- a/arch/mips/pci/fixup-sni.c
+++ b/arch/mips/pci/fixup-sni.c
@@ -120,7 +120,7 @@ static inline int is_rm300_revd(void)
120 return (csmsr & 0xa0) == 0x20; 120 return (csmsr & 0xa0) == 0x20;
121} 121}
122 122
123int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) 123int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
124{ 124{
125 switch (sni_brd_type) { 125 switch (sni_brd_type) {
126 case SNI_BRD_PCI_TOWER: 126 case SNI_BRD_PCI_TOWER:
diff --git a/arch/mips/pci/fixup-tb0219.c b/arch/mips/pci/fixup-tb0219.c
index 734f2b71e164..720a2b720c5c 100644
--- a/arch/mips/pci/fixup-tb0219.c
+++ b/arch/mips/pci/fixup-tb0219.c
@@ -23,7 +23,7 @@
23 23
24#include <asm/vr41xx/tb0219.h> 24#include <asm/vr41xx/tb0219.h>
25 25
26int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) 26int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
27{ 27{
28 int irq = -1; 28 int irq = -1;
29 29
diff --git a/arch/mips/pci/fixup-tb0226.c b/arch/mips/pci/fixup-tb0226.c
index c9e7cb4361a1..e3eedf4bf9bd 100644
--- a/arch/mips/pci/fixup-tb0226.c
+++ b/arch/mips/pci/fixup-tb0226.c
@@ -23,7 +23,7 @@
23#include <asm/vr41xx/giu.h> 23#include <asm/vr41xx/giu.h>
24#include <asm/vr41xx/tb0226.h> 24#include <asm/vr41xx/tb0226.h>
25 25
26int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) 26int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
27{ 27{
28 int irq = -1; 28 int irq = -1;
29 29
diff --git a/arch/mips/pci/fixup-tb0287.c b/arch/mips/pci/fixup-tb0287.c
index fbe6bcb28199..267ab3dc3d42 100644
--- a/arch/mips/pci/fixup-tb0287.c
+++ b/arch/mips/pci/fixup-tb0287.c
@@ -22,7 +22,7 @@
22 22
23#include <asm/vr41xx/tb0287.h> 23#include <asm/vr41xx/tb0287.h>
24 24
25int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) 25int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
26{ 26{
27 unsigned char bus; 27 unsigned char bus;
28 int irq = -1; 28 int irq = -1;
diff --git a/arch/mips/pci/fixup-tx4938.c b/arch/mips/pci/fixup-tx4938.c
index f455520ada88..2485f47dfe6f 100644
--- a/arch/mips/pci/fixup-tx4938.c
+++ b/arch/mips/pci/fixup-tx4938.c
@@ -69,7 +69,7 @@ int pci_get_irq(struct pci_dev *dev, int pin)
69 return irq; 69 return irq;
70} 70}
71 71
72int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) 72int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
73{ 73{
74 unsigned char irq = 0; 74 unsigned char irq = 0;
75 75
diff --git a/arch/mips/pci/fixup-vr4133.c b/arch/mips/pci/fixup-vr4133.c
index a8d9d22b13df..de5e5f6bbf4c 100644
--- a/arch/mips/pci/fixup-vr4133.c
+++ b/arch/mips/pci/fixup-vr4133.c
@@ -169,7 +169,7 @@ void i8259_init(void)
169} 169}
170#endif 170#endif
171 171
172int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) 172int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
173{ 173{
174 extern int pci_probe_only; 174 extern int pci_probe_only;
175 pci_probe_only = 1; 175 pci_probe_only = 1;
diff --git a/arch/mips/pci/fixup-wrppmc.c b/arch/mips/pci/fixup-wrppmc.c
index 3357c1300bb1..3d277549d5df 100644
--- a/arch/mips/pci/fixup-wrppmc.c
+++ b/arch/mips/pci/fixup-wrppmc.c
@@ -25,7 +25,7 @@ static char pci_irq_tab[PCI_SLOT_MAXNR][5] __initdata = {
25 [6] = {0, WRPPMC_PCI_INTA_IRQ, 0, 0, 0}, 25 [6] = {0, WRPPMC_PCI_INTA_IRQ, 0, 0, 0},
26}; 26};
27 27
28int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) 28int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
29{ 29{
30 return pci_irq_tab[slot][pin]; 30 return pci_irq_tab[slot][pin];
31} 31}
diff --git a/arch/mips/pci/fixup-yosemite.c b/arch/mips/pci/fixup-yosemite.c
index 81d77a587a51..fdafb13a793b 100644
--- a/arch/mips/pci/fixup-yosemite.c
+++ b/arch/mips/pci/fixup-yosemite.c
@@ -26,7 +26,7 @@
26#include <linux/init.h> 26#include <linux/init.h>
27#include <linux/pci.h> 27#include <linux/pci.h>
28 28
29int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) 29int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
30{ 30{
31 if (pin == 0) 31 if (pin == 0)
32 return -1; 32 return -1;
diff --git a/arch/mips/pci/ops-bonito64.c b/arch/mips/pci/ops-bonito64.c
index dc35270b65a2..f742c51acf0d 100644
--- a/arch/mips/pci/ops-bonito64.c
+++ b/arch/mips/pci/ops-bonito64.c
@@ -29,83 +29,60 @@
29#define PCI_ACCESS_READ 0 29#define PCI_ACCESS_READ 0
30#define PCI_ACCESS_WRITE 1 30#define PCI_ACCESS_WRITE 1
31 31
32/* 32#ifdef CONFIG_LEMOTE_FULONG
33 * PCI configuration cycle AD bus definition 33#define CFG_SPACE_REG(offset) (void *)CKSEG1ADDR(BONITO_PCICFG_BASE | (offset))
34 */ 34#define ID_SEL_BEGIN 11
35/* Type 0 */ 35#else
36#define PCI_CFG_TYPE0_REG_SHF 0 36#define CFG_SPACE_REG(offset) (void *)CKSEG1ADDR(_pcictrl_bonito_pcicfg + (offset))
37#define PCI_CFG_TYPE0_FUNC_SHF 8 37#define ID_SEL_BEGIN 10
38#endif
39#define MAX_DEV_NUM (31 - ID_SEL_BEGIN)
38 40
39/* Type 1 */
40#define PCI_CFG_TYPE1_REG_SHF 0
41#define PCI_CFG_TYPE1_FUNC_SHF 8
42#define PCI_CFG_TYPE1_DEV_SHF 11
43#define PCI_CFG_TYPE1_BUS_SHF 16
44 41
45static int bonito64_pcibios_config_access(unsigned char access_type, 42static int bonito64_pcibios_config_access(unsigned char access_type,
46 struct pci_bus *bus, 43 struct pci_bus *bus,
47 unsigned int devfn, int where, 44 unsigned int devfn, int where,
48 u32 * data) 45 u32 * data)
49{ 46{
50 unsigned char busnum = bus->number; 47 u32 busnum = bus->number;
48 u32 addr, type;
51 u32 dummy; 49 u32 dummy;
52 u64 pci_addr; 50 void *addrp;
53 51 int device = PCI_SLOT(devfn);
54 /* Algorithmics Bonito64 system controller. */ 52 int function = PCI_FUNC(devfn);
53 int reg = where & ~3;
55 54
56 if ((busnum == 0) && (PCI_SLOT(devfn) > 21)) {
57 /* We number bus 0 devices from 0..21 */
58 return -1;
59 }
60
61 /* Clear cause register bits */
62 BONITO_PCICMD |= (BONITO_PCICMD_MABORT_CLR |
63 BONITO_PCICMD_MTABORT_CLR);
64
65 /*
66 * Setup pattern to be used as PCI "address" for
67 * Type 0 cycle
68 */
69 if (busnum == 0) { 55 if (busnum == 0) {
70 /* IDSEL */ 56 /* Type 0 configuration for onboard PCI bus */
71 pci_addr = (u64) 1 << (PCI_SLOT(devfn) + 10); 57 if (device > MAX_DEV_NUM)
72 } else { 58 return -1;
73 /* Bus number */
74 pci_addr = busnum << PCI_CFG_TYPE1_BUS_SHF;
75
76 /* Device number */
77 pci_addr |=
78 PCI_SLOT(devfn) << PCI_CFG_TYPE1_DEV_SHF;
79 }
80
81 /* Function (same for Type 0/1) */
82 pci_addr |= PCI_FUNC(devfn) << PCI_CFG_TYPE0_FUNC_SHF;
83
84 /* Register number (same for Type 0/1) */
85 pci_addr |= (where & ~0x3) << PCI_CFG_TYPE0_REG_SHF;
86 59
87 if (busnum == 0) { 60 addr = (1 << (device + ID_SEL_BEGIN)) | (function << 8) | reg;
88 /* Type 0 */ 61 type = 0;
89 BONITO_PCIMAP_CFG = pci_addr >> 16;
90 } else { 62 } else {
91 /* Type 1 */ 63 /* Type 1 configuration for offboard PCI bus */
92 BONITO_PCIMAP_CFG = (pci_addr >> 16) | 0x10000; 64 addr = (busnum << 16) | (device << 11) | (function << 8) | reg;
65 type = 0x10000;
93 } 66 }
94 67
95 pci_addr &= 0xffff; 68 /* Clear aborts */
69 BONITO_PCICMD |= BONITO_PCICMD_MABORT_CLR | BONITO_PCICMD_MTABORT_CLR;
70
71 BONITO_PCIMAP_CFG = (addr >> 16) | type;
96 72
97 /* Flush Bonito register block */ 73 /* Flush Bonito register block */
98 dummy = BONITO_PCIMAP_CFG; 74 dummy = BONITO_PCIMAP_CFG;
99 iob(); /* sync */ 75 mmiowb();
100 76
101 /* Perform access */ 77 addrp = CFG_SPACE_REG(addr & 0xffff);
102 if (access_type == PCI_ACCESS_WRITE) { 78 if (access_type == PCI_ACCESS_WRITE) {
103 *(volatile u32 *) (_pcictrl_bonito_pcicfg + (u32)pci_addr) = *(u32 *) data; 79 writel(cpu_to_le32(*data), addrp);
104 80#ifndef CONFIG_LEMOTE_FULONG
105 /* Wait till done */ 81 /* Wait till done */
106 while (BONITO_PCIMSTAT & 0xF); 82 while (BONITO_PCIMSTAT & 0xF);
83#endif
107 } else { 84 } else {
108 *(u32 *) data = *(volatile u32 *) (_pcictrl_bonito_pcicfg + (u32)pci_addr); 85 *data = le32_to_cpu(readl(addrp));
109 } 86 }
110 87
111 /* Detect Master/Target abort */ 88 /* Detect Master/Target abort */
@@ -121,6 +98,7 @@ static int bonito64_pcibios_config_access(unsigned char access_type,
121 } 98 }
122 99
123 return 0; 100 return 0;
101
124} 102}
125 103
126 104
diff --git a/arch/mips/pci/ops-marvell.c b/arch/mips/pci/ops-marvell.c
deleted file mode 100644
index 1ac5c59199d1..000000000000
--- a/arch/mips/pci/ops-marvell.c
+++ /dev/null
@@ -1,93 +0,0 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2003, 2004 Ralf Baechle (ralf@linux-mips.org)
7 */
8#include <linux/kernel.h>
9#include <linux/types.h>
10#include <linux/pci.h>
11
12#include <asm/marvell.h>
13
14static int mv_read_config(struct pci_bus *bus, unsigned int devfn,
15 int where, int size, u32 * val)
16{
17 struct mv_pci_controller *mvbc = bus->sysdata;
18 unsigned long address_reg, data_reg;
19 u32 address;
20
21 address_reg = mvbc->config_addr;
22 data_reg = mvbc->config_vreg;
23
24 /* Accessing device 31 crashes those Marvells. Since years.
25 Will they ever make sane controllers ... */
26 if (PCI_SLOT(devfn) == 31)
27 return PCIBIOS_DEVICE_NOT_FOUND;
28
29 address = (bus->number << 16) | (devfn << 8) |
30 (where & 0xfc) | 0x80000000;
31
32 /* start the configuration cycle */
33 MV_WRITE(address_reg, address);
34
35 switch (size) {
36 case 1:
37 *val = MV_READ_8(data_reg + (where & 0x3));
38 break;
39
40 case 2:
41 *val = MV_READ_16(data_reg + (where & 0x3));
42 break;
43
44 case 4:
45 *val = MV_READ(data_reg);
46 break;
47 }
48
49 return PCIBIOS_SUCCESSFUL;
50}
51
52static int mv_write_config(struct pci_bus *bus, unsigned int devfn,
53 int where, int size, u32 val)
54{
55 struct mv_pci_controller *mvbc = bus->sysdata;
56 unsigned long address_reg, data_reg;
57 u32 address;
58
59 address_reg = mvbc->config_addr;
60 data_reg = mvbc->config_vreg;
61
62 /* Accessing device 31 crashes those Marvells. Since years.
63 Will they ever make sane controllers ... */
64 if (PCI_SLOT(devfn) == 31)
65 return PCIBIOS_DEVICE_NOT_FOUND;
66
67 address = (bus->number << 16) | (devfn << 8) |
68 (where & 0xfc) | 0x80000000;
69
70 /* start the configuration cycle */
71 MV_WRITE(address_reg, address);
72
73 switch (size) {
74 case 1:
75 MV_WRITE_8(data_reg + (where & 0x3), val);
76 break;
77
78 case 2:
79 MV_WRITE_16(data_reg + (where & 0x3), val);
80 break;
81
82 case 4:
83 MV_WRITE(data_reg, val);
84 break;
85 }
86
87 return PCIBIOS_SUCCESSFUL;
88}
89
90struct pci_ops mv_pci_ops = {
91 .read = mv_read_config,
92 .write = mv_write_config
93};
diff --git a/arch/mips/pci/ops-nile4.c b/arch/mips/pci/ops-nile4.c
deleted file mode 100644
index a8d38dc8c504..000000000000
--- a/arch/mips/pci/ops-nile4.c
+++ /dev/null
@@ -1,147 +0,0 @@
1#include <linux/kernel.h>
2#include <linux/init.h>
3#include <linux/pci.h>
4#include <asm/bootinfo.h>
5
6#include <asm/lasat/lasat.h>
7#include <asm/gt64120.h>
8#include <asm/nile4.h>
9
10#define PCI_ACCESS_READ 0
11#define PCI_ACCESS_WRITE 1
12
13#define LO(reg) (reg / 4)
14#define HI(reg) (reg / 4 + 1)
15
16volatile unsigned long *const vrc_pciregs = (void *) Vrc5074_BASE;
17
18static DEFINE_SPINLOCK(nile4_pci_lock);
19
20static int nile4_pcibios_config_access(unsigned char access_type,
21 struct pci_bus *bus, unsigned int devfn, int where, u32 * val)
22{
23 unsigned char busnum = bus->number;
24 u32 adr, mask, err;
25
26 if ((busnum == 0) && (PCI_SLOT(devfn) > 8))
27 /* The addressing scheme chosen leaves room for just
28 * 8 devices on the first busnum (besides the PCI
29 * controller itself) */
30 return PCIBIOS_DEVICE_NOT_FOUND;
31
32 if ((busnum == 0) && (devfn == PCI_DEVFN(0, 0))) {
33 /* Access controller registers directly */
34 if (access_type == PCI_ACCESS_WRITE) {
35 vrc_pciregs[(0x200 + where) >> 2] = *val;
36 } else {
37 *val = vrc_pciregs[(0x200 + where) >> 2];
38 }
39 return PCIBIOS_SUCCESSFUL;
40 }
41
42 /* Temporarily map PCI Window 1 to config space */
43 mask = vrc_pciregs[LO(NILE4_PCIINIT1)];
44 vrc_pciregs[LO(NILE4_PCIINIT1)] = 0x0000001a | (busnum ? 0x200 : 0);
45
46 /* Clear PCI Error register. This also clears the Error Type
47 * bits in the Control register */
48 vrc_pciregs[LO(NILE4_PCIERR)] = 0;
49 vrc_pciregs[HI(NILE4_PCIERR)] = 0;
50
51 /* Setup address */
52 if (busnum == 0)
53 adr =
54 KSEG1ADDR(PCI_WINDOW1) +
55 ((1 << (PCI_SLOT(devfn) + 15)) | (PCI_FUNC(devfn) << 8)
56 | (where & ~3));
57 else
58 adr = KSEG1ADDR(PCI_WINDOW1) | (busnum << 16) | (devfn << 8) |
59 (where & ~3);
60
61 if (access_type == PCI_ACCESS_WRITE)
62 *(u32 *) adr = *val;
63 else
64 *val = *(u32 *) adr;
65
66 /* Check for master or target abort */
67 err = (vrc_pciregs[HI(NILE4_PCICTRL)] >> 5) & 0x7;
68
69 /* Restore PCI Window 1 */
70 vrc_pciregs[LO(NILE4_PCIINIT1)] = mask;
71
72 if (err)
73 return PCIBIOS_DEVICE_NOT_FOUND;
74
75 return PCIBIOS_SUCCESSFUL;
76}
77
78static int nile4_pcibios_read(struct pci_bus *bus, unsigned int devfn,
79 int where, int size, u32 * val)
80{
81 unsigned long flags;
82 u32 data = 0;
83 int err;
84
85 if ((size == 2) && (where & 1))
86 return PCIBIOS_BAD_REGISTER_NUMBER;
87 else if ((size == 4) && (where & 3))
88 return PCIBIOS_BAD_REGISTER_NUMBER;
89
90 spin_lock_irqsave(&nile4_pci_lock, flags);
91 err = nile4_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where,
92 &data);
93 spin_unlock_irqrestore(&nile4_pci_lock, flags);
94
95 if (err)
96 return err;
97
98 if (size == 1)
99 *val = (data >> ((where & 3) << 3)) & 0xff;
100 else if (size == 2)
101 *val = (data >> ((where & 3) << 3)) & 0xffff;
102 else
103 *val = data;
104
105 return PCIBIOS_SUCCESSFUL;
106}
107
108static int nile4_pcibios_write(struct pci_bus *bus, unsigned int devfn,
109 int where, int size, u32 val)
110{
111 unsigned long flags;
112 u32 data = 0;
113 int err;
114
115 if ((size == 2) && (where & 1))
116 return PCIBIOS_BAD_REGISTER_NUMBER;
117 else if ((size == 4) && (where & 3))
118 return PCIBIOS_BAD_REGISTER_NUMBER;
119
120 spin_lock_irqsave(&nile4_pci_lock, flags);
121 err = nile4_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where,
122 &data);
123 spin_unlock_irqrestore(&nile4_pci_lock, flags);
124
125 if (err)
126 return err;
127
128 if (size == 1)
129 data = (data & ~(0xff << ((where & 3) << 3))) |
130 (val << ((where & 3) << 3));
131 else if (size == 2)
132 data = (data & ~(0xffff << ((where & 3) << 3))) |
133 (val << ((where & 3) << 3));
134 else
135 data = val;
136
137 if (nile4_pcibios_config_access
138 (PCI_ACCESS_WRITE, bus, devfn, where, &data))
139 return -1;
140
141 return PCIBIOS_SUCCESSFUL;
142}
143
144struct pci_ops nile4_pci_ops = {
145 .read = nile4_pcibios_read,
146 .write = nile4_pcibios_write,
147};
diff --git a/arch/mips/pci/ops-pmcmsp.c b/arch/mips/pci/ops-pmcmsp.c
new file mode 100644
index 000000000000..09fa007c1d1b
--- /dev/null
+++ b/arch/mips/pci/ops-pmcmsp.c
@@ -0,0 +1,994 @@
1/*
2 * PMC-Sierra MSP board specific pci_ops
3 *
4 * Copyright 2001 MontaVista Software Inc.
5 * Copyright 2005-2007 PMC-Sierra, Inc
6 *
7 * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
8 *
9 * Much of the code is derived from the original DDB5074 port by
10 * Geert Uytterhoeven <geert@sonycom.com>
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version.
16 *
17 */
18
19#define PCI_COUNTERS 1
20
21#include <linux/types.h>
22#include <linux/pci.h>
23#include <linux/interrupt.h>
24
25#if defined(CONFIG_PROC_FS) && defined(PCI_COUNTERS)
26#include <linux/proc_fs.h>
27#include <linux/seq_file.h>
28#endif /* CONFIG_PROC_FS && PCI_COUNTERS */
29
30#include <linux/kernel.h>
31#include <linux/init.h>
32
33#include <asm/byteorder.h>
34#if defined(CONFIG_PMC_MSP7120_GW) || defined(CONFIG_PMC_MSP7120_EVAL)
35#include <asm/mipsmtregs.h>
36#endif
37
38#include <msp_prom.h>
39#include <msp_cic_int.h>
40#include <msp_pci.h>
41#include <msp_regs.h>
42#include <msp_regops.h>
43
44#define PCI_ACCESS_READ 0
45#define PCI_ACCESS_WRITE 1
46
47#if defined(CONFIG_PROC_FS) && defined(PCI_COUNTERS)
48static char proc_init;
49extern struct proc_dir_entry *proc_bus_pci_dir;
50unsigned int pci_int_count[32];
51
52static void pci_proc_init(void);
53
54/*****************************************************************************
55 *
56 * FUNCTION: read_msp_pci_counts
57 * _________________________________________________________________________
58 *
59 * DESCRIPTION: Prints the count of how many times each PCI
60 * interrupt has asserted. Can be invoked by the
61 * /proc filesystem.
62 *
63 * INPUTS: page - part of STDOUT calculation
64 * off - part of STDOUT calculation
65 * count - part of STDOUT calculation
66 * data - unused
67 *
68 * OUTPUTS: start - new start location
69 * eof - end of file pointer
70 *
71 * RETURNS: len - STDOUT length
72 *
73 ****************************************************************************/
74static int read_msp_pci_counts(char *page, char **start, off_t off,
75 int count, int *eof, void *data)
76{
77 int i;
78 int len = 0;
79 unsigned int intcount, total = 0;
80
81 for (i = 0; i < 32; ++i) {
82 intcount = pci_int_count[i];
83 if (intcount != 0) {
84 len += sprintf(page + len, "[%d] = %u\n", i, intcount);
85 total += intcount;
86 }
87 }
88
89 len += sprintf(page + len, "total = %u\n", total);
90 if (len <= off+count)
91 *eof = 1;
92
93 *start = page + off;
94 len -= off;
95 if (len > count)
96 len = count;
97 if (len < 0)
98 len = 0;
99
100 return len;
101}
102
103/*****************************************************************************
104 *
105 * FUNCTION: gen_pci_cfg_wr
106 * _________________________________________________________________________
107 *
108 * DESCRIPTION: Generates a configuration write cycle for debug purposes.
109 * The IDSEL line asserted and location and data written are
110 * immaterial. Just want to be able to prove that a
111 * configuration write can be correctly generated on the
112 * PCI bus. Intent is that this function by invocable from
113 * the /proc filesystem.
114 *
115 * INPUTS: page - part of STDOUT calculation
116 * off - part of STDOUT calculation
117 * count - part of STDOUT calculation
118 * data - unused
119 *
120 * OUTPUTS: start - new start location
121 * eof - end of file pointer
122 *
123 * RETURNS: len - STDOUT length
124 *
125 ****************************************************************************/
126static int gen_pci_cfg_wr(char *page, char **start, off_t off,
127 int count, int *eof, void *data)
128{
129 unsigned char where = 0; /* Write to static Device/Vendor ID */
130 unsigned char bus_num = 0; /* Bus 0 */
131 unsigned char dev_fn = 0xF; /* Arbitrary device number */
132 u32 wr_data = 0xFF00AA00; /* Arbitrary data */
133 struct msp_pci_regs *preg = (void *)PCI_BASE_REG;
134 int len = 0;
135 unsigned long value;
136 int intr;
137
138 len += sprintf(page + len, "PMC MSP PCI: Beginning\n");
139
140 if (proc_init == 0) {
141 pci_proc_init();
142 proc_init = ~0;
143 }
144
145 len += sprintf(page + len, "PMC MSP PCI: Before Cfg Wr\n");
146
147 /*
148 * Generate PCI Configuration Write Cycle
149 */
150
151 /* Clear cause register bits */
152 preg->if_status = ~(BPCI_IFSTATUS_BC0F | BPCI_IFSTATUS_BC1F);
153
154 /* Setup address that is to appear on PCI bus */
155 preg->config_addr = BPCI_CFGADDR_ENABLE |
156 (bus_num << BPCI_CFGADDR_BUSNUM_SHF) |
157 (dev_fn << BPCI_CFGADDR_FUNCTNUM_SHF) |
158 (where & 0xFC);
159
160 value = cpu_to_le32(wr_data);
161
162 /* Launch the PCI configuration write cycle */
163 *PCI_CONFIG_SPACE_REG = value;
164
165 /*
166 * Check if the PCI configuration cycle (rd or wr) succeeded, by
167 * checking the status bits for errors like master or target abort.
168 */
169 intr = preg->if_status;
170
171 len += sprintf(page + len, "PMC MSP PCI: After Cfg Wr\n");
172
173 /* Handle STDOUT calculations */
174 if (len <= off+count)
175 *eof = 1;
176 *start = page + off;
177 len -= off;
178 if (len > count)
179 len = count;
180 if (len < 0)
181 len = 0;
182
183 return len;
184}
185
186/*****************************************************************************
187 *
188 * FUNCTION: pci_proc_init
189 * _________________________________________________________________________
190 *
191 * DESCRIPTION: Create entries in the /proc filesystem for debug access.
192 *
193 * INPUTS: none
194 *
195 * OUTPUTS: none
196 *
197 * RETURNS: none
198 *
199 ****************************************************************************/
200static void pci_proc_init(void)
201{
202 create_proc_read_entry("pmc_msp_pci_rd_cnt", 0, NULL,
203 read_msp_pci_counts, NULL);
204 create_proc_read_entry("pmc_msp_pci_cfg_wr", 0, NULL,
205 gen_pci_cfg_wr, NULL);
206}
207#endif /* CONFIG_PROC_FS && PCI_COUNTERS */
208
209spinlock_t bpci_lock = SPIN_LOCK_UNLOCKED;
210
211/*****************************************************************************
212 *
213 * STRUCT: pci_io_resource
214 * _________________________________________________________________________
215 *
216 * DESCRIPTION: Defines the address range that pciauto() will use to
217 * assign to the I/O BARs of PCI devices.
218 *
219 * Use the start and end addresses of the MSP7120 PCI Host
220 * Controller I/O space, in the form that they appear on the
221 * PCI bus AFTER MSP7120 has performed address translation.
222 *
223 * For I/O accesses, MSP7120 ignores OATRAN and maps I/O
224 * accesses into the bottom 0xFFF region of address space,
225 * so that is the range to put into the pci_io_resource
226 * struct.
227 *
228 * In MSP4200, the start address was 0x04 instead of the
229 * expected 0x00. Will just assume there was a good reason
230 * for this!
231 *
232 * NOTES: Linux, by default, will assign I/O space to the lowest
233 * region of address space. Since MSP7120 and Linux,
234 * by default, have no offset in between how they map, the
235 * io_offset element of pci_controller struct should be set
236 * to zero.
237 * ELEMENTS:
238 * name - String used for a meaningful name.
239 *
240 * start - Start address of MSP7120's I/O space, as MSP7120 presents
241 * the address on the PCI bus.
242 *
243 * end - End address of MSP7120's I/O space, as MSP7120 presents
244 * the address on the PCI bus.
245 *
246 * flags - Attributes indicating the type of resource. In this case,
247 * indicate I/O space.
248 *
249 ****************************************************************************/
250static struct resource pci_io_resource = {
251 .name = "pci IO space",
252 .start = 0x04,
253 .end = 0x0FFF,
254 .flags = IORESOURCE_IO /* I/O space */
255};
256
257/*****************************************************************************
258 *
259 * STRUCT: pci_mem_resource
260 * _________________________________________________________________________
261 *
262 * DESCRIPTION: Defines the address range that pciauto() will use to
263 * assign to the memory BARs of PCI devices.
264 *
265 * The .start and .end values are dependent upon how address
266 * translation is performed by the OATRAN regiser.
267 *
268 * The values to use for .start and .end are the values
269 * in the form they appear on the PCI bus AFTER MSP7120 has
270 * performed OATRAN address translation.
271 *
272 * ELEMENTS:
273 * name - String used for a meaningful name.
274 *
275 * start - Start address of MSP7120's memory space, as MSP7120 presents
276 * the address on the PCI bus.
277 *
278 * end - End address of MSP7120's memory space, as MSP7120 presents
279 * the address on the PCI bus.
280 *
281 * flags - Attributes indicating the type of resource. In this case,
282 * indicate memory space.
283 *
284 ****************************************************************************/
285static struct resource pci_mem_resource = {
286 .name = "pci memory space",
287 .start = MSP_PCI_SPACE_BASE,
288 .end = MSP_PCI_SPACE_END,
289 .flags = IORESOURCE_MEM /* memory space */
290};
291
292/*****************************************************************************
293 *
294 * FUNCTION: bpci_interrupt
295 * _________________________________________________________________________
296 *
297 * DESCRIPTION: PCI status interrupt handler. Updates the count of how
298 * many times each status bit has been set, then clears
299 * the status bits. If the appropriate macros are defined,
300 * these counts can be viewed via the /proc filesystem.
301 *
302 * INPUTS: irq - unused
303 * dev_id - unused
304 * pt_regs - unused
305 *
306 * OUTPUTS: none
307 *
308 * RETURNS: PCIBIOS_SUCCESSFUL - success
309 *
310 ****************************************************************************/
311static int bpci_interrupt(int irq, void *dev_id)
312{
313 struct msp_pci_regs *preg = (void *)PCI_BASE_REG;
314 unsigned int stat = preg->if_status;
315
316#if defined(CONFIG_PROC_FS) && defined(PCI_COUNTERS)
317 int i;
318 for (i = 0; i < 32; ++i) {
319 if ((1 << i) & stat)
320 ++pci_int_count[i];
321 }
322#endif /* PROC_FS && PCI_COUNTERS */
323
324 /* printk("PCI ISR: Status=%08X\n", stat); */
325
326 /* write to clear all asserted interrupts */
327 preg->if_status = stat;
328
329 return PCIBIOS_SUCCESSFUL;
330}
331
332/*****************************************************************************
333 *
334 * FUNCTION: msp_pcibios_config_access
335 * _________________________________________________________________________
336 *
337 * DESCRIPTION: Performs a PCI configuration access (rd or wr), then
338 * checks that the access succeeded by querying MSP7120's
339 * PCI status bits.
340 *
341 * INPUTS:
342 * access_type - kind of PCI configuration cycle to perform
343 * (read or write). Legal values are
344 * PCI_ACCESS_WRITE and PCI_ACCESS_READ.
345 *
346 * bus - pointer to the bus number of the device to
347 * be targetted for the configuration cycle.
348 * The only element of the pci_bus structure
349 * used is bus->number. This argument determines
350 * if the configuration access will be Type 0 or
351 * Type 1. Since MSP7120 assumes itself to be the
352 * PCI Host, any non-zero bus->number generates
353 * a Type 1 access.
354 *
355 * devfn - this is an 8-bit field. The lower three bits
356 * specify the function number of the device to
357 * be targetted for the configuration cycle, with
358 * all three-bit combinations being legal. The
359 * upper five bits specify the device number,
360 * with legal values being 10 to 31.
361 *
362 * where - address within the Configuration Header
363 * space to access.
364 *
365 * data - for write accesses, contains the data to
366 * write.
367 *
368 * OUTPUTS:
369 * data - for read accesses, contains the value read.
370 *
371 * RETURNS: PCIBIOS_SUCCESSFUL - success
372 * -1 - access failure
373 *
374 ****************************************************************************/
375int msp_pcibios_config_access(unsigned char access_type,
376 struct pci_bus *bus,
377 unsigned int devfn,
378 unsigned char where,
379 u32 *data)
380{
381 struct msp_pci_regs *preg = (void *)PCI_BASE_REG;
382 unsigned char bus_num = bus->number;
383 unsigned char dev_fn = (unsigned char)devfn;
384 unsigned long flags;
385 unsigned long intr;
386 unsigned long value;
387 static char pciirqflag;
388#if defined(CONFIG_PMC_MSP7120_GW) || defined(CONFIG_PMC_MSP7120_EVAL)
389 unsigned int vpe_status;
390#endif
391
392#if defined(CONFIG_PROC_FS) && defined(PCI_COUNTERS)
393 if (proc_init == 0) {
394 pci_proc_init();
395 proc_init = ~0;
396 }
397#endif /* CONFIG_PROC_FS && PCI_COUNTERS */
398
399 /*
400 * Just the first time this function invokes, allocate
401 * an interrupt line for PCI host status interrupts. The
402 * allocation assigns an interrupt handler to the interrupt.
403 */
404 if (pciirqflag == 0) {
405 request_irq(MSP_INT_PCI,/* Hardcoded internal MSP7120 wiring */
406 bpci_interrupt,
407 SA_SHIRQ | SA_INTERRUPT,
408 "PMC MSP PCI Host",
409 preg);
410 pciirqflag = ~0;
411 }
412
413#if defined(CONFIG_PMC_MSP7120_GW) || defined(CONFIG_PMC_MSP7120_EVAL)
414 local_irq_save(flags);
415 vpe_status = dvpe();
416#else
417 spin_lock_irqsave(&bpci_lock, flags);
418#endif
419
420 /*
421 * Clear PCI cause register bits.
422 *
423 * In Polo, the PCI Host had a dedicated DMA called the
424 * Block Copy (not to be confused with the general purpose Block
425 * Copy Engine block). There appear to have been special interrupts
426 * for this Block Copy, called Block Copy 0 Fault (BC0F) and
427 * Block Copy 1 Fault (BC1F). MSP4200 and MSP7120 don't have this
428 * dedicated Block Copy block, so these two interrupts are now
429 * marked reserved. In case the Block Copy is resurrected in a
430 * future design, maintain the code that treats these two interrupts
431 * specially.
432 *
433 * Write to clear all interrupts in the PCI status register, aside
434 * from BC0F and BC1F.
435 */
436 preg->if_status = ~(BPCI_IFSTATUS_BC0F | BPCI_IFSTATUS_BC1F);
437
438 /* Setup address that is to appear on PCI bus */
439 preg->config_addr = BPCI_CFGADDR_ENABLE |
440 (bus_num << BPCI_CFGADDR_BUSNUM_SHF) |
441 (dev_fn << BPCI_CFGADDR_FUNCTNUM_SHF) |
442 (where & 0xFC);
443
444 /* IF access is a PCI configuration write */
445 if (access_type == PCI_ACCESS_WRITE) {
446 value = cpu_to_le32(*data);
447 *PCI_CONFIG_SPACE_REG = value;
448 } else {
449 /* ELSE access is a PCI configuration read */
450 value = le32_to_cpu(*PCI_CONFIG_SPACE_REG);
451 *data = value;
452 }
453
454 /*
455 * Check if the PCI configuration cycle (rd or wr) succeeded, by
456 * checking the status bits for errors like master or target abort.
457 */
458 intr = preg->if_status;
459
460 /* Clear config access */
461 preg->config_addr = 0;
462
463 /* IF error occurred */
464 if (intr & ~(BPCI_IFSTATUS_BC0F | BPCI_IFSTATUS_BC1F)) {
465 /* Clear status bits */
466 preg->if_status = ~(BPCI_IFSTATUS_BC0F | BPCI_IFSTATUS_BC1F);
467
468#if defined(CONFIG_PMC_MSP7120_GW) || defined(CONFIG_PMC_MSP7120_EVAL)
469 evpe(vpe_status);
470 local_irq_restore(flags);
471#else
472 spin_unlock_irqrestore(&bpci_lock, flags);
473#endif
474
475 return -1;
476 }
477
478#if defined(CONFIG_PMC_MSP7120_GW) || defined(CONFIG_PMC_MSP7120_EVAL)
479 evpe(vpe_status);
480 local_irq_restore(flags);
481#else
482 spin_unlock_irqrestore(&bpci_lock, flags);
483#endif
484
485 return PCIBIOS_SUCCESSFUL;
486}
487
488/*****************************************************************************
489 *
490 * FUNCTION: msp_pcibios_read_config_byte
491 * _________________________________________________________________________
492 *
493 * DESCRIPTION: Read a byte from PCI configuration address spac
494 * Since the hardware can't address 8 bit chunks
495 * directly, read a 32-bit chunk, then mask off extraneous
496 * bits.
497 *
498 * INPUTS bus - structure containing attributes for the PCI bus
499 * that the read is destined for.
500 * devfn - device/function combination that the read is
501 * destined for.
502 * where - register within the Configuration Header space
503 * to access.
504 *
505 * OUTPUTS val - read data
506 *
507 * RETURNS: PCIBIOS_SUCCESSFUL - success
508 * -1 - read access failure
509 *
510 ****************************************************************************/
511static int
512msp_pcibios_read_config_byte(struct pci_bus *bus,
513 unsigned int devfn,
514 int where,
515 u32 *val)
516{
517 u32 data = 0;
518
519 /*
520 * If the config access did not complete normally (e.g., underwent
521 * master abort) do the PCI compliant thing, which is to supply an
522 * all ones value.
523 */
524 if (msp_pcibios_config_access(PCI_ACCESS_READ, bus, devfn,
525 where, &data)) {
526 *val = 0xFFFFFFFF;
527 return -1;
528 }
529
530 *val = (data >> ((where & 3) << 3)) & 0x0ff;
531
532 return PCIBIOS_SUCCESSFUL;
533}
534
535/*****************************************************************************
536 *
537 * FUNCTION: msp_pcibios_read_config_word
538 * _________________________________________________________________________
539 *
540 * DESCRIPTION: Read a word (16 bits) from PCI configuration address space.
541 * Since the hardware can't address 16 bit chunks
542 * directly, read a 32-bit chunk, then mask off extraneous
543 * bits.
544 *
545 * INPUTS bus - structure containing attributes for the PCI bus
546 * that the read is destined for.
547 * devfn - device/function combination that the read is
548 * destined for.
549 * where - register within the Configuration Header space
550 * to access.
551 *
552 * OUTPUTS val - read data
553 *
554 * RETURNS: PCIBIOS_SUCCESSFUL - success
555 * PCIBIOS_BAD_REGISTER_NUMBER - bad register address
556 * -1 - read access failure
557 *
558 ****************************************************************************/
559static int
560msp_pcibios_read_config_word(struct pci_bus *bus,
561 unsigned int devfn,
562 int where,
563 u32 *val)
564{
565 u32 data = 0;
566
567 /* if (where & 1) */ /* Commented out non-compliant code.
568 * Should allow word access to configuration
569 * registers, with only exception being when
570 * the word access would wrap around into
571 * the next dword.
572 */
573 if ((where & 3) == 3) {
574 *val = 0xFFFFFFFF;
575 return PCIBIOS_BAD_REGISTER_NUMBER;
576 }
577
578 /*
579 * If the config access did not complete normally (e.g., underwent
580 * master abort) do the PCI compliant thing, which is to supply an
581 * all ones value.
582 */
583 if (msp_pcibios_config_access(PCI_ACCESS_READ, bus, devfn,
584 where, &data)) {
585 *val = 0xFFFFFFFF;
586 return -1;
587 }
588
589 *val = (data >> ((where & 3) << 3)) & 0x0ffff;
590
591 return PCIBIOS_SUCCESSFUL;
592}
593
594/*****************************************************************************
595 *
596 * FUNCTION: msp_pcibios_read_config_dword
597 * _________________________________________________________________________
598 *
599 * DESCRIPTION: Read a double word (32 bits) from PCI configuration
600 * address space.
601 *
602 * INPUTS bus - structure containing attributes for the PCI bus
603 * that the read is destined for.
604 * devfn - device/function combination that the read is
605 * destined for.
606 * where - register within the Configuration Header space
607 * to access.
608 *
609 * OUTPUTS val - read data
610 *
611 * RETURNS: PCIBIOS_SUCCESSFUL - success
612 * PCIBIOS_BAD_REGISTER_NUMBER - bad register address
613 * -1 - read access failure
614 *
615 ****************************************************************************/
616static int
617msp_pcibios_read_config_dword(struct pci_bus *bus,
618 unsigned int devfn,
619 int where,
620 u32 *val)
621{
622 u32 data = 0;
623
624 /* Address must be dword aligned. */
625 if (where & 3) {
626 *val = 0xFFFFFFFF;
627 return PCIBIOS_BAD_REGISTER_NUMBER;
628 }
629
630 /*
631 * If the config access did not complete normally (e.g., underwent
632 * master abort) do the PCI compliant thing, which is to supply an
633 * all ones value.
634 */
635 if (msp_pcibios_config_access(PCI_ACCESS_READ, bus, devfn,
636 where, &data)) {
637 *val = 0xFFFFFFFF;
638 return -1;
639 }
640
641 *val = data;
642
643 return PCIBIOS_SUCCESSFUL;
644}
645
646/*****************************************************************************
647 *
648 * FUNCTION: msp_pcibios_write_config_byte
649 * _________________________________________________________________________
650 *
651 * DESCRIPTION: Write a byte to PCI configuration address space.
652 * Since the hardware can't address 8 bit chunks
653 * directly, a read-modify-write is performed.
654 *
655 * INPUTS bus - structure containing attributes for the PCI bus
656 * that the write is destined for.
657 * devfn - device/function combination that the write is
658 * destined for.
659 * where - register within the Configuration Header space
660 * to access.
661 * val - value to write
662 *
663 * OUTPUTS none
664 *
665 * RETURNS: PCIBIOS_SUCCESSFUL - success
666 * -1 - write access failure
667 *
668 ****************************************************************************/
669static int
670msp_pcibios_write_config_byte(struct pci_bus *bus,
671 unsigned int devfn,
672 int where,
673 u8 val)
674{
675 u32 data = 0;
676
677 /* read config space */
678 if (msp_pcibios_config_access(PCI_ACCESS_READ, bus, devfn,
679 where, &data))
680 return -1;
681
682 /* modify the byte within the dword */
683 data = (data & ~(0xff << ((where & 3) << 3))) |
684 (val << ((where & 3) << 3));
685
686 /* write back the full dword */
687 if (msp_pcibios_config_access(PCI_ACCESS_WRITE, bus, devfn,
688 where, &data))
689 return -1;
690
691 return PCIBIOS_SUCCESSFUL;
692}
693
694/*****************************************************************************
695 *
696 * FUNCTION: msp_pcibios_write_config_word
697 * _________________________________________________________________________
698 *
699 * DESCRIPTION: Write a word (16-bits) to PCI configuration address space.
700 * Since the hardware can't address 16 bit chunks
701 * directly, a read-modify-write is performed.
702 *
703 * INPUTS bus - structure containing attributes for the PCI bus
704 * that the write is destined for.
705 * devfn - device/function combination that the write is
706 * destined for.
707 * where - register within the Configuration Header space
708 * to access.
709 * val - value to write
710 *
711 * OUTPUTS none
712 *
713 * RETURNS: PCIBIOS_SUCCESSFUL - success
714 * PCIBIOS_BAD_REGISTER_NUMBER - bad register address
715 * -1 - write access failure
716 *
717 ****************************************************************************/
718static int
719msp_pcibios_write_config_word(struct pci_bus *bus,
720 unsigned int devfn,
721 int where,
722 u16 val)
723{
724 u32 data = 0;
725
726 /* Fixed non-compliance: if (where & 1) */
727 if ((where & 3) == 3)
728 return PCIBIOS_BAD_REGISTER_NUMBER;
729
730 /* read config space */
731 if (msp_pcibios_config_access(PCI_ACCESS_READ, bus, devfn,
732 where, &data))
733 return -1;
734
735 /* modify the word within the dword */
736 data = (data & ~(0xffff << ((where & 3) << 3))) |
737 (val << ((where & 3) << 3));
738
739 /* write back the full dword */
740 if (msp_pcibios_config_access(PCI_ACCESS_WRITE, bus, devfn,
741 where, &data))
742 return -1;
743
744 return PCIBIOS_SUCCESSFUL;
745}
746
747/*****************************************************************************
748 *
749 * FUNCTION: msp_pcibios_write_config_dword
750 * _________________________________________________________________________
751 *
752 * DESCRIPTION: Write a double word (32-bits) to PCI configuration address
753 * space.
754 *
755 * INPUTS bus - structure containing attributes for the PCI bus
756 * that the write is destined for.
757 * devfn - device/function combination that the write is
758 * destined for.
759 * where - register within the Configuration Header space
760 * to access.
761 * val - value to write
762 *
763 * OUTPUTS none
764 *
765 * RETURNS: PCIBIOS_SUCCESSFUL - success
766 * PCIBIOS_BAD_REGISTER_NUMBER - bad register address
767 * -1 - write access failure
768 *
769 ****************************************************************************/
770static int
771msp_pcibios_write_config_dword(struct pci_bus *bus,
772 unsigned int devfn,
773 int where,
774 u32 val)
775{
776 /* check that address is dword aligned */
777 if (where & 3)
778 return PCIBIOS_BAD_REGISTER_NUMBER;
779
780 /* perform write */
781 if (msp_pcibios_config_access(PCI_ACCESS_WRITE, bus, devfn,
782 where, &val))
783 return -1;
784
785 return PCIBIOS_SUCCESSFUL;
786}
787
788/*****************************************************************************
789 *
790 * FUNCTION: msp_pcibios_read_config
791 * _________________________________________________________________________
792 *
793 * DESCRIPTION: Interface the PCI configuration read request with
794 * the appropriate function, based on how many bytes
795 * the read request is.
796 *
797 * INPUTS bus - structure containing attributes for the PCI bus
798 * that the write is destined for.
799 * devfn - device/function combination that the write is
800 * destined for.
801 * where - register within the Configuration Header space
802 * to access.
803 * size - in units of bytes, should be 1, 2, or 4.
804 *
805 * OUTPUTS val - value read, with any extraneous bytes masked
806 * to zero.
807 *
808 * RETURNS: PCIBIOS_SUCCESSFUL - success
809 * -1 - failure
810 *
811 ****************************************************************************/
812int
813msp_pcibios_read_config(struct pci_bus *bus,
814 unsigned int devfn,
815 int where,
816 int size,
817 u32 *val)
818{
819 if (size == 1) {
820 if (msp_pcibios_read_config_byte(bus, devfn, where, val)) {
821 return -1;
822 }
823 } else if (size == 2) {
824 if (msp_pcibios_read_config_word(bus, devfn, where, val)) {
825 return -1;
826 }
827 } else if (size == 4) {
828 if (msp_pcibios_read_config_dword(bus, devfn, where, val)) {
829 return -1;
830 }
831 } else {
832 *val = 0xFFFFFFFF;
833 return -1;
834 }
835
836 return PCIBIOS_SUCCESSFUL;
837}
838
839/*****************************************************************************
840 *
841 * FUNCTION: msp_pcibios_write_config
842 * _________________________________________________________________________
843 *
844 * DESCRIPTION: Interface the PCI configuration write request with
845 * the appropriate function, based on how many bytes
846 * the read request is.
847 *
848 * INPUTS bus - structure containing attributes for the PCI bus
849 * that the write is destined for.
850 * devfn - device/function combination that the write is
851 * destined for.
852 * where - register within the Configuration Header space
853 * to access.
854 * size - in units of bytes, should be 1, 2, or 4.
855 * val - value to write
856 *
857 * OUTPUTS: none
858 *
859 * RETURNS: PCIBIOS_SUCCESSFUL - success
860 * -1 - failure
861 *
862 ****************************************************************************/
863int
864msp_pcibios_write_config(struct pci_bus *bus,
865 unsigned int devfn,
866 int where,
867 int size,
868 u32 val)
869{
870 if (size == 1) {
871 if (msp_pcibios_write_config_byte(bus, devfn,
872 where, (u8)(0xFF & val))) {
873 return -1;
874 }
875 } else if (size == 2) {
876 if (msp_pcibios_write_config_word(bus, devfn,
877 where, (u16)(0xFFFF & val))) {
878 return -1;
879 }
880 } else if (size == 4) {
881 if (msp_pcibios_write_config_dword(bus, devfn, where, val)) {
882 return -1;
883 }
884 } else {
885 return -1;
886 }
887
888 return PCIBIOS_SUCCESSFUL;
889}
890
891/*****************************************************************************
892 *
893 * STRUCTURE: msp_pci_ops
894 * _________________________________________________________________________
895 *
896 * DESCRIPTION: structure to abstract the hardware specific PCI
897 * configuration accesses.
898 *
899 * ELEMENTS:
900 * read - function for Linux to generate PCI Configuration reads.
901 * write - function for Linux to generate PCI Configuration writes.
902 *
903 ****************************************************************************/
904struct pci_ops msp_pci_ops = {
905 .read = msp_pcibios_read_config,
906 .write = msp_pcibios_write_config
907};
908
909/*****************************************************************************
910 *
911 * STRUCTURE: msp_pci_controller
912 * _________________________________________________________________________
913 *
914 * Describes the attributes of the MSP7120 PCI Host Controller
915 *
916 * ELEMENTS:
917 * pci_ops - abstracts the hardware specific PCI configuration
918 * accesses.
919 *
920 * mem_resource - address range pciauto() uses to assign to PCI device
921 * memory BARs.
922 *
923 * mem_offset - offset between how MSP7120 outbound PCI memory
924 * transaction addresses appear on the PCI bus and how Linux
925 * wants to configure memory BARs of the PCI devices.
926 * MSP7120 does nothing funky, so just set to zero.
927 *
928 * io_resource - address range pciauto() uses to assign to PCI device
929 * I/O BARs.
930 *
931 * io_offset - offset between how MSP7120 outbound PCI I/O
932 * transaction addresses appear on the PCI bus and how
933 * Linux defaults to configure I/O BARs of the PCI devices.
934 * MSP7120 maps outbound I/O accesses into the bottom
935 * bottom 4K of PCI address space (and ignores OATRAN).
936 * Since the Linux default is to configure I/O BARs to the
937 * bottom 4K, no special offset is needed. Just set to zero.
938 *
939 ****************************************************************************/
940static struct pci_controller msp_pci_controller = {
941 .pci_ops = &msp_pci_ops,
942 .mem_resource = &pci_mem_resource,
943 .mem_offset = 0,
944 .io_resource = &pci_io_resource,
945 .io_offset = 0
946};
947
948/*****************************************************************************
949 *
950 * FUNCTION: msp_pci_init
951 * _________________________________________________________________________
952 *
953 * DESCRIPTION: Initialize the PCI Host Controller and register it with
954 * Linux so Linux can seize control of the PCI bus.
955 *
956 ****************************************************************************/
957void __init msp_pci_init(void)
958{
959 struct msp_pci_regs *preg = (void *)PCI_BASE_REG;
960 u32 id;
961
962 /* Extract Device ID */
963 id = read_reg32(PCI_JTAG_DEVID_REG, 0xFFFF) >> 12;
964
965 /* Check if JTAG ID identifies MSP7120 */
966 if (!MSP_HAS_PCI(id)) {
967 printk(KERN_WARNING "PCI: No PCI; id reads as %x\n", id);
968 goto no_pci;
969 }
970
971 /*
972 * Enable flushing of the PCI-SDRAM queue upon a read
973 * of the SDRAM's Memory Configuration Register.
974 */
975 *(unsigned long *)QFLUSH_REG_1 = 3;
976
977 /* Configure PCI Host Controller. */
978 preg->if_status = ~0; /* Clear cause register bits */
979 preg->config_addr = 0; /* Clear config access */
980 preg->oatran = MSP_PCI_OATRAN; /* PCI outbound addr translation */
981 preg->if_mask = 0xF8BF87C0; /* Enable all PCI status interrupts */
982
983 /* configure so inb(), outb(), and family are functional */
984 set_io_port_base(MSP_PCI_IOSPACE_BASE);
985
986 /* Tell Linux the details of the MSP7120 PCI Host Controller */
987 register_pci_controller(&msp_pci_controller);
988
989 return;
990
991no_pci:
992 /* Disable PCI channel */
993 printk(KERN_WARNING "PCI: no host PCI bus detected\n");
994}
diff --git a/arch/mips/pci/ops-tx4938.c b/arch/mips/pci/ops-tx4938.c
index 445007084515..a450c4062031 100644
--- a/arch/mips/pci/ops-tx4938.c
+++ b/arch/mips/pci/ops-tx4938.c
@@ -46,50 +46,63 @@ struct resource tx4938_pcic1_pci_mem_resource = {
46 .flags = IORESOURCE_MEM 46 .flags = IORESOURCE_MEM
47}; 47};
48 48
49static int mkaddr(int bus, int dev_fn, int where, int *flagsp) 49static int mkaddr(int bus, int dev_fn, int where,
50 struct tx4938_pcic_reg *pcicptr)
50{ 51{
51 if (bus > 0) { 52 if (bus > 0) {
52 /* Type 1 configuration */ 53 /* Type 1 configuration */
53 tx4938_pcicptr->g2pcfgadrs = ((bus & 0xff) << 0x10) | 54 pcicptr->g2pcfgadrs = ((bus & 0xff) << 0x10) |
54 ((dev_fn & 0xff) << 0x08) | (where & 0xfc) | 1; 55 ((dev_fn & 0xff) << 0x08) | (where & 0xfc) | 1;
55 } else { 56 } else {
56 if (dev_fn >= PCI_DEVFN(TX4938_PCIC_MAX_DEVNU, 0)) 57 if (dev_fn >= PCI_DEVFN(TX4938_PCIC_MAX_DEVNU, 0))
57 return -1; 58 return -1;
58 59
59 /* Type 0 configuration */ 60 /* Type 0 configuration */
60 tx4938_pcicptr->g2pcfgadrs = ((bus & 0xff) << 0x10) | 61 pcicptr->g2pcfgadrs = ((bus & 0xff) << 0x10) |
61 ((dev_fn & 0xff) << 0x08) | (where & 0xfc); 62 ((dev_fn & 0xff) << 0x08) | (where & 0xfc);
62 } 63 }
63 /* clear M_ABORT and Disable M_ABORT Int. */ 64 /* clear M_ABORT and Disable M_ABORT Int. */
64 tx4938_pcicptr->pcistatus = 65 pcicptr->pcistatus =
65 (tx4938_pcicptr->pcistatus & 0x0000ffff) | 66 (pcicptr->pcistatus & 0x0000ffff) |
66 (PCI_STATUS_REC_MASTER_ABORT << 16); 67 (PCI_STATUS_REC_MASTER_ABORT << 16);
67 tx4938_pcicptr->pcimask &= ~PCI_STATUS_REC_MASTER_ABORT; 68 pcicptr->pcimask &= ~PCI_STATUS_REC_MASTER_ABORT;
68 69
69 return 0; 70 return 0;
70} 71}
71 72
72static int check_abort(int flags) 73static int check_abort(struct tx4938_pcic_reg *pcicptr)
73{ 74{
74 int code = PCIBIOS_SUCCESSFUL; 75 int code = PCIBIOS_SUCCESSFUL;
75 /* wait write cycle completion before checking error status */ 76 /* wait write cycle completion before checking error status */
76 while (tx4938_pcicptr->pcicstatus & TX4938_PCIC_PCICSTATUS_IWB) 77 while (pcicptr->pcicstatus & TX4938_PCIC_PCICSTATUS_IWB)
77 ; 78 ;
78 if (tx4938_pcicptr->pcistatus & (PCI_STATUS_REC_MASTER_ABORT << 16)) { 79 if (pcicptr->pcistatus & (PCI_STATUS_REC_MASTER_ABORT << 16)) {
79 tx4938_pcicptr->pcistatus = 80 pcicptr->pcistatus =
80 (tx4938_pcicptr-> 81 (pcicptr->
81 pcistatus & 0x0000ffff) | (PCI_STATUS_REC_MASTER_ABORT 82 pcistatus & 0x0000ffff) | (PCI_STATUS_REC_MASTER_ABORT
82 << 16); 83 << 16);
83 tx4938_pcicptr->pcimask |= PCI_STATUS_REC_MASTER_ABORT; 84 pcicptr->pcimask |= PCI_STATUS_REC_MASTER_ABORT;
84 code = PCIBIOS_DEVICE_NOT_FOUND; 85 code = PCIBIOS_DEVICE_NOT_FOUND;
85 } 86 }
86 return code; 87 return code;
87} 88}
88 89
90extern struct pci_controller tx4938_pci_controller[];
91extern struct tx4938_pcic_reg *get_tx4938_pcicptr(int ch);
92
93static struct tx4938_pcic_reg *pci_bus_to_pcicptr(struct pci_bus *bus)
94{
95 struct pci_controller *channel = bus->sysdata;
96 return get_tx4938_pcicptr(channel - &tx4938_pci_controller[0]);
97}
98
89static int tx4938_pcibios_read_config(struct pci_bus *bus, unsigned int devfn, 99static int tx4938_pcibios_read_config(struct pci_bus *bus, unsigned int devfn,
90 int where, int size, u32 * val) 100 int where, int size, u32 * val)
91{ 101{
92 int flags, retval, dev, busno, func; 102 int retval, dev, busno, func;
103 struct tx4938_pcic_reg *pcicptr = pci_bus_to_pcicptr(bus);
104 void __iomem *cfgdata =
105 (void __iomem *)(unsigned long)&pcicptr->g2pcfgdata;
93 106
94 dev = PCI_SLOT(devfn); 107 dev = PCI_SLOT(devfn);
95 func = PCI_FUNC(devfn); 108 func = PCI_FUNC(devfn);
@@ -101,32 +114,32 @@ static int tx4938_pcibios_read_config(struct pci_bus *bus, unsigned int devfn,
101 busno = 0; 114 busno = 0;
102 } 115 }
103 116
104 if (mkaddr(busno, devfn, where, &flags)) 117 if (mkaddr(busno, devfn, where, pcicptr))
105 return -1; 118 return -1;
106 119
107 switch (size) { 120 switch (size) {
108 case 1: 121 case 1:
109 *val = *(volatile u8 *) ((unsigned long) & tx4938_pcicptr->g2pcfgdata |
110#ifdef __BIG_ENDIAN 122#ifdef __BIG_ENDIAN
111 ((where & 3) ^ 3)); 123 cfgdata += (where & 3) ^ 3;
112#else 124#else
113 (where & 3)); 125 cfgdata += where & 3;
114#endif 126#endif
127 *val = __raw_readb(cfgdata);
115 break; 128 break;
116 case 2: 129 case 2:
117 *val = *(volatile u16 *) ((unsigned long) & tx4938_pcicptr->g2pcfgdata |
118#ifdef __BIG_ENDIAN 130#ifdef __BIG_ENDIAN
119 ((where & 3) ^ 2)); 131 cfgdata += (where & 2) ^ 2;
120#else 132#else
121 (where & 3)); 133 cfgdata += where & 2;
122#endif 134#endif
135 *val = __raw_readw(cfgdata);
123 break; 136 break;
124 case 4: 137 case 4:
125 *val = tx4938_pcicptr->g2pcfgdata; 138 *val = __raw_readl(cfgdata);
126 break; 139 break;
127 } 140 }
128 141
129 retval = check_abort(flags); 142 retval = check_abort(pcicptr);
130 if (retval == PCIBIOS_DEVICE_NOT_FOUND) 143 if (retval == PCIBIOS_DEVICE_NOT_FOUND)
131 *val = 0xffffffff; 144 *val = 0xffffffff;
132 145
@@ -136,7 +149,10 @@ static int tx4938_pcibios_read_config(struct pci_bus *bus, unsigned int devfn,
136static int tx4938_pcibios_write_config(struct pci_bus *bus, unsigned int devfn, int where, 149static int tx4938_pcibios_write_config(struct pci_bus *bus, unsigned int devfn, int where,
137 int size, u32 val) 150 int size, u32 val)
138{ 151{
139 int flags, dev, busno, func; 152 int dev, busno, func;
153 struct tx4938_pcic_reg *pcicptr = pci_bus_to_pcicptr(bus);
154 void __iomem *cfgdata =
155 (void __iomem *)(unsigned long)&pcicptr->g2pcfgdata;
140 156
141 busno = bus->number; 157 busno = bus->number;
142 dev = PCI_SLOT(devfn); 158 dev = PCI_SLOT(devfn);
@@ -149,32 +165,32 @@ static int tx4938_pcibios_write_config(struct pci_bus *bus, unsigned int devfn,
149 busno = 0; 165 busno = 0;
150 } 166 }
151 167
152 if (mkaddr(busno, devfn, where, &flags)) 168 if (mkaddr(busno, devfn, where, pcicptr))
153 return -1; 169 return -1;
154 170
155 switch (size) { 171 switch (size) {
156 case 1: 172 case 1:
157 *(volatile u8 *) ((unsigned long) & tx4938_pcicptr->g2pcfgdata |
158#ifdef __BIG_ENDIAN 173#ifdef __BIG_ENDIAN
159 ((where & 3) ^ 3)) = val; 174 cfgdata += (where & 3) ^ 3;
160#else 175#else
161 (where & 3)) = val; 176 cfgdata += where & 3;
162#endif 177#endif
178 __raw_writeb(val, cfgdata);
163 break; 179 break;
164 case 2: 180 case 2:
165 *(volatile u16 *) ((unsigned long) & tx4938_pcicptr->g2pcfgdata |
166#ifdef __BIG_ENDIAN 181#ifdef __BIG_ENDIAN
167 ((where & 0x3) ^ 0x2)) = val; 182 cfgdata += (where & 2) ^ 2;
168#else 183#else
169 (where & 3)) = val; 184 cfgdata += where & 2;
170#endif 185#endif
186 __raw_writew(val, cfgdata);
171 break; 187 break;
172 case 4: 188 case 4:
173 tx4938_pcicptr->g2pcfgdata = val; 189 __raw_writel(val, cfgdata);
174 break; 190 break;
175 } 191 }
176 192
177 return check_abort(flags); 193 return check_abort(pcicptr);
178} 194}
179 195
180struct pci_ops tx4938_pci_ops = { 196struct pci_ops tx4938_pci_ops = {
diff --git a/arch/mips/pci/pci-bcm1480.c b/arch/mips/pci/pci-bcm1480.c
index d7b9e1349f6d..2b4e30c7d105 100644
--- a/arch/mips/pci/pci-bcm1480.c
+++ b/arch/mips/pci/pci-bcm1480.c
@@ -74,8 +74,9 @@ static inline void WRITECFG32(u32 addr, u32 data)
74 *(u32 *)(cfg_space + (addr & ~3)) = data; 74 *(u32 *)(cfg_space + (addr & ~3)) = data;
75} 75}
76 76
77int pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) 77int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
78{ 78{
79 This is b0rked.
79 return dev->irq; 80 return dev->irq;
80} 81}
81 82
diff --git a/arch/mips/pci/pci-ddb5477.c b/arch/mips/pci/pci-ddb5477.c
index d071bc375b11..7363e1877842 100644
--- a/arch/mips/pci/pci-ddb5477.c
+++ b/arch/mips/pci/pci-ddb5477.c
@@ -131,7 +131,7 @@ static unsigned char rockhopperII_irq_map[MAX_SLOT_NUM] = {
131 /* SLOT: 20, AD:31 */ VRC5477_IRQ_IOPCI_INTA, /* vrc5477 usb host */ 131 /* SLOT: 20, AD:31 */ VRC5477_IRQ_IOPCI_INTA, /* vrc5477 usb host */
132}; 132};
133 133
134int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) 134int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
135{ 135{
136 int slot_num; 136 int slot_num;
137 unsigned char *slot_irq_map; 137 unsigned char *slot_irq_map;
diff --git a/arch/mips/pci/pci-ev64120.c b/arch/mips/pci/pci-ev64120.c
deleted file mode 100644
index a84f594b5a18..000000000000
--- a/arch/mips/pci/pci-ev64120.c
+++ /dev/null
@@ -1,22 +0,0 @@
1#include <linux/pci.h>
2#include <asm/irq.h>
3
4int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
5{
6 int irq;
7
8 if (!pin)
9 return 0;
10
11 irq = allocate_irqno();
12 if (irq < 0)
13 return 0;
14
15 return irq;
16}
17
18/* Do platform specific device initialization at pci_enable_device() time */
19int pcibios_plat_dev_init(struct pci_dev *dev)
20{
21 return 0;
22}
diff --git a/arch/mips/pci/pci-ip27.c b/arch/mips/pci/pci-ip27.c
index 405ce0152739..a322543ac34e 100644
--- a/arch/mips/pci/pci-ip27.c
+++ b/arch/mips/pci/pci-ip27.c
@@ -134,7 +134,7 @@ int __init bridge_probe(nasid_t nasid, int widget_id, int masterwid)
134 * A given PCI device, in general, should be able to intr any of the cpus 134 * A given PCI device, in general, should be able to intr any of the cpus
135 * on any one of the hubs connected to its xbow. 135 * on any one of the hubs connected to its xbow.
136 */ 136 */
137int __devinit pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) 137int __devinit pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
138{ 138{
139 struct bridge_controller *bc = BRIDGE_CONTROLLER(dev->bus); 139 struct bridge_controller *bc = BRIDGE_CONTROLLER(dev->bus);
140 int irq = bc->pci_int[slot]; 140 int irq = bc->pci_int[slot];
diff --git a/arch/mips/pci/pci-lasat.c b/arch/mips/pci/pci-lasat.c
deleted file mode 100644
index 985784a3e6f8..000000000000
--- a/arch/mips/pci/pci-lasat.c
+++ /dev/null
@@ -1,91 +0,0 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2000, 2001, 04 Keith M Wesolowski
7 */
8#include <linux/kernel.h>
9#include <linux/init.h>
10#include <linux/pci.h>
11#include <linux/types.h>
12#include <asm/bootinfo.h>
13
14extern struct pci_ops nile4_pci_ops;
15extern struct pci_ops gt64xxx_pci0_ops;
16static struct resource lasat_pci_mem_resource = {
17 .name = "LASAT PCI MEM",
18 .start = 0x18000000,
19 .end = 0x19ffffff,
20 .flags = IORESOURCE_MEM,
21};
22
23static struct resource lasat_pci_io_resource = {
24 .name = "LASAT PCI IO",
25 .start = 0x1a000000,
26 .end = 0x1bffffff,
27 .flags = IORESOURCE_IO,
28};
29
30static struct pci_controller lasat_pci_controller = {
31 .mem_resource = &lasat_pci_mem_resource,
32 .io_resource = &lasat_pci_io_resource,
33};
34
35static int __init lasat_pci_setup(void)
36{
37 printk("PCI: starting\n");
38
39 switch (mips_machtype) {
40 case MACH_LASAT_100:
41 lasat_pci_controller.pci_ops = &gt64xxx_pci0_ops;
42 break;
43 case MACH_LASAT_200:
44 lasat_pci_controller.pci_ops = &nile4_pci_ops;
45 break;
46 default:
47 panic("pcibios_init: mips_machtype incorrect");
48 }
49
50 register_pci_controller(&lasat_pci_controller);
51
52 return 0;
53}
54
55arch_initcall(lasat_pci_setup);
56
57#define LASATINT_ETH1 0
58#define LASATINT_ETH0 1
59#define LASATINT_HDC 2
60#define LASATINT_COMP 3
61#define LASATINT_HDLC 4
62#define LASATINT_PCIA 5
63#define LASATINT_PCIB 6
64#define LASATINT_PCIC 7
65#define LASATINT_PCID 8
66
67int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
68{
69 switch (slot) {
70 case 1:
71 case 2:
72 case 3:
73 return LASATINT_PCIA + (((slot-1) + (pin-1)) % 4);
74 case 4:
75 return LASATINT_ETH1; /* Ethernet 1 (LAN 2) */
76 case 5:
77 return LASATINT_ETH0; /* Ethernet 0 (LAN 1) */
78 case 6:
79 return LASATINT_HDC; /* IDE controller */
80 default:
81 return 0xff; /* Illegal */
82 }
83
84 return -1;
85}
86
87/* Do platform specific device initialization at pci_enable_device() time */
88int pcibios_plat_dev_init(struct pci_dev *dev)
89{
90 return 0;
91}
diff --git a/arch/mips/pci/pci-ocelot-c.c b/arch/mips/pci/pci-ocelot-c.c
deleted file mode 100644
index 027759f7c904..000000000000
--- a/arch/mips/pci/pci-ocelot-c.c
+++ /dev/null
@@ -1,145 +0,0 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2004, 06 by Ralf Baechle (ralf@linux-mips.org)
7 */
8
9#include <linux/types.h>
10#include <linux/pci.h>
11#include <linux/mv643xx.h>
12
13#include <linux/init.h>
14
15#include <asm/marvell.h>
16
17/*
18 * We assume the address ranges have already been setup appropriately by
19 * the firmware. PMON in case of the Ocelot C does that.
20 */
21static struct resource mv_pci_io_mem0_resource = {
22 .name = "MV64340 PCI0 IO MEM",
23 .flags = IORESOURCE_IO
24};
25
26static struct resource mv_pci_mem0_resource = {
27 .name = "MV64340 PCI0 MEM",
28 .flags = IORESOURCE_MEM
29};
30
31static struct mv_pci_controller mv_bus0_controller = {
32 .pcic = {
33 .pci_ops = &mv_pci_ops,
34 .mem_resource = &mv_pci_mem0_resource,
35 .io_resource = &mv_pci_io_mem0_resource,
36 },
37 .config_addr = MV64340_PCI_0_CONFIG_ADDR,
38 .config_vreg = MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG,
39};
40
41static uint32_t mv_io_base, mv_io_size;
42
43static void mv64340_pci0_init(void)
44{
45 uint32_t mem0_base, mem0_size;
46 uint32_t io_base, io_size;
47
48 io_base = MV_READ(MV64340_PCI_0_IO_BASE_ADDR) << 16;
49 io_size = (MV_READ(MV64340_PCI_0_IO_SIZE) + 1) << 16;
50 mem0_base = MV_READ(MV64340_PCI_0_MEMORY0_BASE_ADDR) << 16;
51 mem0_size = (MV_READ(MV64340_PCI_0_MEMORY0_SIZE) + 1) << 16;
52
53 mv_pci_io_mem0_resource.start = 0;
54 mv_pci_io_mem0_resource.end = io_size - 1;
55 mv_pci_mem0_resource.start = mem0_base;
56 mv_pci_mem0_resource.end = mem0_base + mem0_size - 1;
57 mv_bus0_controller.pcic.mem_offset = mem0_base;
58 mv_bus0_controller.pcic.io_offset = 0;
59
60 ioport_resource.end = io_size - 1;
61
62 register_pci_controller(&mv_bus0_controller.pcic);
63
64 mv_io_base = io_base;
65 mv_io_size = io_size;
66}
67
68static struct resource mv_pci_io_mem1_resource = {
69 .name = "MV64340 PCI1 IO MEM",
70 .flags = IORESOURCE_IO
71};
72
73static struct resource mv_pci_mem1_resource = {
74 .name = "MV64340 PCI1 MEM",
75 .flags = IORESOURCE_MEM
76};
77
78static struct mv_pci_controller mv_bus1_controller = {
79 .pcic = {
80 .pci_ops = &mv_pci_ops,
81 .mem_resource = &mv_pci_mem1_resource,
82 .io_resource = &mv_pci_io_mem1_resource,
83 },
84 .config_addr = MV64340_PCI_1_CONFIG_ADDR,
85 .config_vreg = MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG,
86};
87
88static __init void mv64340_pci1_init(void)
89{
90 uint32_t mem0_base, mem0_size;
91 uint32_t io_base, io_size;
92
93 io_base = MV_READ(MV64340_PCI_1_IO_BASE_ADDR) << 16;
94 io_size = (MV_READ(MV64340_PCI_1_IO_SIZE) + 1) << 16;
95 mem0_base = MV_READ(MV64340_PCI_1_MEMORY0_BASE_ADDR) << 16;
96 mem0_size = (MV_READ(MV64340_PCI_1_MEMORY0_SIZE) + 1) << 16;
97
98 /*
99 * Here we assume the I/O window of second bus to be contiguous with
100 * the first. A gap is no problem but would waste address space for
101 * remapping the port space.
102 */
103 mv_pci_io_mem1_resource.start = mv_io_size;
104 mv_pci_io_mem1_resource.end = mv_io_size + io_size - 1;
105 mv_pci_mem1_resource.start = mem0_base;
106 mv_pci_mem1_resource.end = mem0_base + mem0_size - 1;
107 mv_bus1_controller.pcic.mem_offset = mem0_base;
108 mv_bus1_controller.pcic.io_offset = 0;
109
110 ioport_resource.end = io_base + io_size -mv_io_base - 1;
111
112 register_pci_controller(&mv_bus1_controller.pcic);
113
114 mv_io_size = io_base + io_size - mv_io_base;
115}
116
117static __init int __init ocelot_c_pci_init(void)
118{
119 unsigned long io_v_base;
120 uint32_t enable;
121
122 enable = ~MV_READ(MV64340_BASE_ADDR_ENABLE);
123
124 /*
125 * We require at least one enabled I/O or PCI memory window or we
126 * will ignore this PCI bus. We ignore PCI windows 1, 2 and 3.
127 */
128 if (enable & (0x01 << 9) || enable & (0x01 << 10))
129 mv64340_pci0_init();
130
131 if (enable & (0x01 << 14) || enable & (0x01 << 15))
132 mv64340_pci1_init();
133
134 if (mv_io_size) {
135 io_v_base = (unsigned long) ioremap(mv_io_base, mv_io_size);
136 if (!io_v_base)
137 panic("Could not ioremap I/O port range");
138
139 set_io_port_base(io_v_base);
140 }
141
142 return 0;
143}
144
145arch_initcall(ocelot_c_pci_init);
diff --git a/arch/mips/pci/pci-sb1250.c b/arch/mips/pci/pci-sb1250.c
index 75c1246ced5f..c1ac6493155e 100644
--- a/arch/mips/pci/pci-sb1250.c
+++ b/arch/mips/pci/pci-sb1250.c
@@ -84,7 +84,7 @@ static inline void WRITECFG32(u32 addr, u32 data)
84 *(u32 *) (cfg_space + (addr & ~3)) = data; 84 *(u32 *) (cfg_space + (addr & ~3)) = data;
85} 85}
86 86
87int pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) 87int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
88{ 88{
89 return dev->irq; 89 return dev->irq;
90} 90}
diff --git a/arch/mips/philips/pnx8550/common/platform.c b/arch/mips/philips/pnx8550/common/platform.c
index d43f56e2cd78..c839436bd012 100644
--- a/arch/mips/philips/pnx8550/common/platform.c
+++ b/arch/mips/philips/pnx8550/common/platform.c
@@ -123,7 +123,7 @@ static struct platform_device *pnx8550_platform_devices[] __initdata = {
123 &pnx8550_uart_device, 123 &pnx8550_uart_device,
124}; 124};
125 125
126int pnx8550_platform_init(void) 126static int __init pnx8550_platform_init(void)
127{ 127{
128 return platform_add_devices(pnx8550_platform_devices, 128 return platform_add_devices(pnx8550_platform_devices,
129 ARRAY_SIZE(pnx8550_platform_devices)); 129 ARRAY_SIZE(pnx8550_platform_devices));
diff --git a/arch/mips/philips/pnx8550/common/proc.c b/arch/mips/philips/pnx8550/common/proc.c
index 3f097558ef13..92311e95b700 100644
--- a/arch/mips/philips/pnx8550/common/proc.c
+++ b/arch/mips/philips/pnx8550/common/proc.c
@@ -78,29 +78,33 @@ static int pnx8550_proc_init( void )
78{ 78{
79 79
80 // Create /proc/pnx8550 80 // Create /proc/pnx8550
81 pnx8550_dir = create_proc_entry("pnx8550", S_IFDIR|S_IRUGO, NULL); 81 pnx8550_dir = proc_mkdir("pnx8550", NULL);
82 if (!pnx8550_dir) { 82 if (!pnx8550_dir) {
83 printk(KERN_ERR "Can't create pnx8550 proc dir\n"); 83 printk(KERN_ERR "Can't create pnx8550 proc dir\n");
84 return -1; 84 return -1;
85 } 85 }
86 86
87 // Create /proc/pnx8550/timers 87 // Create /proc/pnx8550/timers
88 pnx8550_timers = create_proc_entry("timers", S_IFREG|S_IRUGO, pnx8550_dir ); 88 pnx8550_timers = create_proc_read_entry(
89 if (pnx8550_timers){ 89 "timers",
90 pnx8550_timers->read_proc = pnx8550_timers_read; 90 0,
91 } 91 pnx8550_dir,
92 else { 92 pnx8550_timers_read,
93 NULL);
94
95 if (!pnx8550_timers)
93 printk(KERN_ERR "Can't create pnx8550 timers proc file\n"); 96 printk(KERN_ERR "Can't create pnx8550 timers proc file\n");
94 }
95 97
96 // Create /proc/pnx8550/registers 98 // Create /proc/pnx8550/registers
97 pnx8550_registers = create_proc_entry("registers", S_IFREG|S_IRUGO, pnx8550_dir ); 99 pnx8550_registers = create_proc_read_entry(
98 if (pnx8550_registers){ 100 "registers",
99 pnx8550_registers->read_proc = pnx8550_registers_read; 101 0,
100 } 102 pnx8550_dir,
101 else { 103 pnx8550_registers_read,
104 NULL);
105
106 if (!pnx8550_registers)
102 printk(KERN_ERR "Can't create pnx8550 registers proc file\n"); 107 printk(KERN_ERR "Can't create pnx8550 registers proc file\n");
103 }
104 108
105 return 0; 109 return 0;
106} 110}
diff --git a/arch/mips/pmc-sierra/Kconfig b/arch/mips/pmc-sierra/Kconfig
index 24d514c9dff9..abbd0bbfabd7 100644
--- a/arch/mips/pmc-sierra/Kconfig
+++ b/arch/mips/pmc-sierra/Kconfig
@@ -1,3 +1,49 @@
1choice
2 prompt "PMC-Sierra MSP SOC type"
3 depends on PMC_MSP
4
5config PMC_MSP4200_EVAL
6 bool "PMC-Sierra MSP4200 Eval Board"
7 select IRQ_MSP_SLP
8 select HW_HAS_PCI
9
10config PMC_MSP4200_GW
11 bool "PMC-Sierra MSP4200 VoIP Gateway"
12 select IRQ_MSP_SLP
13 select HW_HAS_PCI
14
15config PMC_MSP7120_EVAL
16 bool "PMC-Sierra MSP7120 Eval Board"
17 select SYS_SUPPORTS_MULTITHREADING
18 select IRQ_MSP_CIC
19 select HW_HAS_PCI
20
21config PMC_MSP7120_GW
22 bool "PMC-Sierra MSP7120 Residential Gateway"
23 select SYS_SUPPORTS_MULTITHREADING
24 select IRQ_MSP_CIC
25 select HW_HAS_PCI
26
27config PMC_MSP7120_FPGA
28 bool "PMC-Sierra MSP7120 FPGA"
29 select SYS_SUPPORTS_MULTITHREADING
30 select IRQ_MSP_CIC
31 select HW_HAS_PCI
32
33endchoice
34
35menu "Options for PMC-Sierra MSP chipsets"
36 depends on PMC_MSP
37
38config PMC_MSP_EMBEDDED_ROOTFS
39 bool "Root filesystem embedded in kernel image"
40 select MTD
41 select MTD_BLOCK
42 select MTD_PMC_MSP_RAMROOT
43 select MTD_RAM
44
45endmenu
46
1config HYPERTRANSPORT 47config HYPERTRANSPORT
2 bool "Hypertransport Support for PMC-Sierra Yosemite" 48 bool "Hypertransport Support for PMC-Sierra Yosemite"
3 depends on PMC_YOSEMITE 49 depends on PMC_YOSEMITE
diff --git a/arch/mips/pmc-sierra/msp71xx/Makefile b/arch/mips/pmc-sierra/msp71xx/Makefile
new file mode 100644
index 000000000000..4bba79c1cc79
--- /dev/null
+++ b/arch/mips/pmc-sierra/msp71xx/Makefile
@@ -0,0 +1,11 @@
1#
2# Makefile for the PMC-Sierra MSP SOCs
3#
4obj-y += msp_prom.o msp_setup.o msp_irq.o \
5 msp_time.o msp_serial.o msp_elb.o
6obj-$(CONFIG_PMC_MSP7120_GW) += msp_hwbutton.o
7obj-$(CONFIG_IRQ_MSP_SLP) += msp_irq_slp.o
8obj-$(CONFIG_IRQ_MSP_CIC) += msp_irq_cic.o
9obj-$(CONFIG_PCI) += msp_pci.o
10obj-$(CONFIG_MSPETH) += msp_eth.o
11obj-$(CONFIG_USB_MSP71XX) += msp_usb.o
diff --git a/arch/mips/momentum/ocelot_c/ocelot_c_fpga.h b/arch/mips/pmc-sierra/msp71xx/msp_elb.c
index f0f5581dcb50..3e9641007216 100644
--- a/arch/mips/momentum/ocelot_c/ocelot_c_fpga.h
+++ b/arch/mips/pmc-sierra/msp71xx/msp_elb.c
@@ -1,7 +1,9 @@
1/* 1/*
2 * Ocelot-C Board Register Definitions 2 * Sets up the proper Chip Select configuration registers. It is assumed that
3 * PMON sets up the ADDR and MASK registers properly.
3 * 4 *
4 * (C) 2002 Momentum Computer Inc. 5 * Copyright 2005-2006 PMC-Sierra, Inc.
6 * Author: Marc St-Jean, Marc_St-Jean@pmc-sierra.com
5 * 7 *
6 * This program is free software; you can redistribute it and/or modify it 8 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the 9 * under the terms of the GNU General Public License as published by the
@@ -22,40 +24,23 @@
22 * You should have received a copy of the GNU General Public License along 24 * You should have received a copy of the GNU General Public License along
23 * with this program; if not, write to the Free Software Foundation, Inc., 25 * with this program; if not, write to the Free Software Foundation, Inc.,
24 * 675 Mass Ave, Cambridge, MA 02139, USA. 26 * 675 Mass Ave, Cambridge, MA 02139, USA.
25 *
26 * Louis Hamilton, Red Hat, Inc.
27 * hamilton@redhat.com [MIPS64 modifications]
28 */ 27 */
29 28
30#ifndef __OCELOT_C_FPGA_H__ 29#include <linux/kernel.h>
31#define __OCELOT_C_FPGA_H__ 30#include <linux/init.h>
32 31#include <msp_regs.h>
33 32
34#ifdef CONFIG_64BIT 33static int __init msp_elb_setup(void)
35#define OCELOT_C_CS0_ADDR (0xfffffffffc000000) 34{
36#else 35#if defined(CONFIG_PMC_MSP7120_GW) \
37#define OCELOT_C_CS0_ADDR (0xfc000000) 36 || defined(CONFIG_PMC_MSP7120_EVAL)
37 /*
38 * Force all CNFG to be identical and equal to CS0,
39 * according to OPS doc
40 */
41 *CS1_CNFG_REG = *CS2_CNFG_REG = *CS3_CNFG_REG = *CS0_CNFG_REG;
38#endif 42#endif
43 return 0;
44}
39 45
40#define OCELOT_C_REG_BOARDREV 0x0 46subsys_initcall(msp_elb_setup);
41#define OCELOT_C_REG_FPGA_REV 0x1
42#define OCELOT_C_REG_FPGA_TYPE 0x2
43#define OCELOT_C_REG_RESET_STATUS 0x3
44#define OCELOT_C_REG_BOARD_STATUS 0x4
45#define OCELOT_C_REG_CPCI_ID 0x5
46#define OCELOT_C_REG_SET 0x6
47#define OCELOT_C_REG_CLR 0x7
48#define OCELOT_C_REG_EEPROM_MODE 0x9
49#define OCELOT_C_REG_INTMASK 0xa
50#define OCELOT_C_REG_INTSTAT 0xb
51#define OCELOT_C_REG_UART_INTMASK 0xc
52#define OCELOT_C_REG_UART_INTSTAT 0xd
53#define OCELOT_C_REG_INTSET 0xe
54#define OCELOT_C_REG_INTCLR 0xf
55
56#define __FPGA_REG_TO_ADDR(reg) \
57 ((void *) OCELOT_C_CS0_ADDR + OCELOT_C_REG_##reg)
58#define OCELOT_FPGA_WRITE(x, reg) writeb(x, __FPGA_REG_TO_ADDR(reg))
59#define OCELOT_FPGA_READ(reg) readb(__FPGA_REG_TO_ADDR(reg))
60
61#endif
diff --git a/arch/mips/pmc-sierra/msp71xx/msp_hwbutton.c b/arch/mips/pmc-sierra/msp71xx/msp_hwbutton.c
new file mode 100644
index 000000000000..6fa85728158b
--- /dev/null
+++ b/arch/mips/pmc-sierra/msp71xx/msp_hwbutton.c
@@ -0,0 +1,179 @@
1/*
2 * Sets up interrupt handlers for various hardware switches which are
3 * connected to interrupt lines.
4 *
5 * Copyright 2005-2207 PMC-Sierra, Inc.
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 *
12 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
13 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
14 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
15 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
16 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
17 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
18 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
19 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
20 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
21 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22 *
23 * You should have received a copy of the GNU General Public License along
24 * with this program; if not, write to the Free Software Foundation, Inc.,
25 * 675 Mass Ave, Cambridge, MA 02139, USA.
26 */
27
28#include <linux/kernel.h>
29#include <linux/init.h>
30#include <linux/interrupt.h>
31
32#include <msp_int.h>
33#include <msp_regs.h>
34#include <msp_regops.h>
35#ifdef CONFIG_PMCTWILED
36#include <msp_led_macros.h>
37#endif
38
39/* For hwbutton_interrupt->initial_state */
40#define HWBUTTON_HI 0x1
41#define HWBUTTON_LO 0x2
42
43/*
44 * This struct describes a hardware button
45 */
46struct hwbutton_interrupt {
47 char *name; /* Name of button */
48 int irq; /* Actual LINUX IRQ */
49 int eirq; /* Extended IRQ number (0-7) */
50 int initial_state; /* The "normal" state of the switch */
51 void (*handle_hi)(void *); /* Handler: switch input has gone HI */
52 void (*handle_lo)(void *); /* Handler: switch input has gone LO */
53 void *data; /* Optional data to pass to handler */
54};
55
56#ifdef CONFIG_PMC_MSP7120_GW
57extern void msp_restart(char *);
58
59static void softreset_push(void *data)
60{
61 printk(KERN_WARNING "SOFTRESET switch was pushed\n");
62
63 /*
64 * In the future you could move this to the release handler,
65 * timing the difference between the 'push' and 'release', and only
66 * doing this ungraceful restart if the button has been down for
67 * a certain amount of time; otherwise doing a graceful restart.
68 */
69
70 msp_restart(NULL);
71}
72
73static void softreset_release(void *data)
74{
75 printk(KERN_WARNING "SOFTRESET switch was released\n");
76
77 /* Do nothing */
78}
79
80static void standby_on(void *data)
81{
82 printk(KERN_WARNING "STANDBY switch was set to ON (not implemented)\n");
83
84 /* TODO: Put board in standby mode */
85#ifdef CONFIG_PMCTWILED
86 msp_led_turn_off(MSP_LED_PWRSTANDBY_GREEN);
87 msp_led_turn_on(MSP_LED_PWRSTANDBY_RED);
88#endif
89}
90
91static void standby_off(void *data)
92{
93 printk(KERN_WARNING
94 "STANDBY switch was set to OFF (not implemented)\n");
95
96 /* TODO: Take out of standby mode */
97#ifdef CONFIG_PMCTWILED
98 msp_led_turn_on(MSP_LED_PWRSTANDBY_GREEN);
99 msp_led_turn_off(MSP_LED_PWRSTANDBY_RED);
100#endif
101}
102
103static struct hwbutton_interrupt softreset_sw = {
104 .name = "Softreset button",
105 .irq = MSP_INT_EXT0,
106 .eirq = 0,
107 .initial_state = HWBUTTON_HI,
108 .handle_hi = softreset_release,
109 .handle_lo = softreset_push,
110 .data = NULL,
111};
112
113static struct hwbutton_interrupt standby_sw = {
114 .name = "Standby switch",
115 .irq = MSP_INT_EXT1,
116 .eirq = 1,
117 .initial_state = HWBUTTON_HI,
118 .handle_hi = standby_off,
119 .handle_lo = standby_on,
120 .data = NULL,
121};
122#endif /* CONFIG_PMC_MSP7120_GW */
123
124static irqreturn_t hwbutton_handler(int irq, void *data)
125{
126 struct hwbutton_interrupt *hirq = data;
127 unsigned long cic_ext = *CIC_EXT_CFG_REG;
128
129 if (irq != hirq->irq)
130 return IRQ_NONE;
131
132 if (CIC_EXT_IS_ACTIVE_HI(cic_ext, hirq->eirq)) {
133 /* Interrupt: pin is now HI */
134 CIC_EXT_SET_ACTIVE_LO(cic_ext, hirq->eirq);
135 hirq->handle_hi(hirq->data);
136 } else {
137 /* Interrupt: pin is now LO */
138 CIC_EXT_SET_ACTIVE_HI(cic_ext, hirq->eirq);
139 hirq->handle_lo(hirq->data);
140 }
141
142 /*
143 * Invert the POLARITY of this level interrupt to ack the interrupt
144 * Thus next state change will invoke the opposite message
145 */
146 *CIC_EXT_CFG_REG = cic_ext;
147
148 return IRQ_HANDLED;
149}
150
151static int msp_hwbutton_register(struct hwbutton_interrupt *hirq)
152{
153 unsigned long cic_ext;
154
155 if (hirq->handle_hi == NULL || hirq->handle_lo == NULL)
156 return -EINVAL;
157
158 cic_ext = *CIC_EXT_CFG_REG;
159 CIC_EXT_SET_TRIGGER_LEVEL(cic_ext, hirq->eirq);
160 if (hirq->initial_state == HWBUTTON_HI)
161 CIC_EXT_SET_ACTIVE_LO(cic_ext, hirq->eirq);
162 else
163 CIC_EXT_SET_ACTIVE_HI(cic_ext, hirq->eirq);
164 *CIC_EXT_CFG_REG = cic_ext;
165
166 return request_irq(hirq->irq, hwbutton_handler, SA_INTERRUPT,
167 hirq->name, (void *)hirq);
168}
169
170static int __init msp_hwbutton_setup(void)
171{
172#ifdef CONFIG_PMC_MSP7120_GW
173 msp_hwbutton_register(&softreset_sw);
174 msp_hwbutton_register(&standby_sw);
175#endif
176 return 0;
177}
178
179subsys_initcall(msp_hwbutton_setup);
diff --git a/arch/mips/pmc-sierra/msp71xx/msp_irq.c b/arch/mips/pmc-sierra/msp71xx/msp_irq.c
new file mode 100644
index 000000000000..734d598a2e3a
--- /dev/null
+++ b/arch/mips/pmc-sierra/msp71xx/msp_irq.c
@@ -0,0 +1,124 @@
1/*
2 * IRQ vector handles
3 *
4 * Copyright (C) 1995, 1996, 1997, 2003 by Ralf Baechle
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 */
10
11#include <linux/kernel.h>
12#include <linux/init.h>
13#include <linux/irq.h>
14#include <linux/interrupt.h>
15#include <linux/ptrace.h>
16#include <linux/time.h>
17
18#include <asm/irq_cpu.h>
19
20#include <msp_int.h>
21
22extern void msp_int_handle(void);
23
24/* SLP bases systems */
25extern void msp_slp_irq_init(void);
26extern void msp_slp_irq_dispatch(void);
27
28/* CIC based systems */
29extern void msp_cic_irq_init(void);
30extern void msp_cic_irq_dispatch(void);
31
32/*
33 * The PMC-Sierra MSP interrupts are arranged in a 3 level cascaded
34 * hierarchical system. The first level are the direct MIPS interrupts
35 * and are assigned the interrupt range 0-7. The second level is the SLM
36 * interrupt controller and is assigned the range 8-39. The third level
37 * comprises the Peripherial block, the PCI block, the PCI MSI block and
38 * the SLP. The PCI interrupts and the SLP errors are handled by the
39 * relevant subsystems so the core interrupt code needs only concern
40 * itself with the Peripheral block. These are assigned interrupts in
41 * the range 40-71.
42 */
43
44asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
45{
46 u32 pending;
47
48 pending = read_c0_status() & read_c0_cause();
49
50 /*
51 * jump to the correct interrupt routine
52 * These are arranged in priority order and the timer
53 * comes first!
54 */
55
56#ifdef CONFIG_IRQ_MSP_CIC /* break out the CIC stuff for now */
57 if (pending & C_IRQ4) /* do the peripherals first, that's the timer */
58 msp_cic_irq_dispatch();
59
60 else if (pending & C_IRQ0)
61 do_IRQ(MSP_INT_MAC0);
62
63 else if (pending & C_IRQ1)
64 do_IRQ(MSP_INT_MAC1);
65
66 else if (pending & C_IRQ2)
67 do_IRQ(MSP_INT_USB);
68
69 else if (pending & C_IRQ3)
70 do_IRQ(MSP_INT_SAR);
71
72 else if (pending & C_IRQ5)
73 do_IRQ(MSP_INT_SEC);
74
75#else
76 if (pending & C_IRQ5)
77 do_IRQ(MSP_INT_TIMER);
78
79 else if (pending & C_IRQ0)
80 do_IRQ(MSP_INT_MAC0);
81
82 else if (pending & C_IRQ1)
83 do_IRQ(MSP_INT_MAC1);
84
85 else if (pending & C_IRQ3)
86 do_IRQ(MSP_INT_VE);
87
88 else if (pending & C_IRQ4)
89 msp_slp_irq_dispatch();
90#endif
91
92 else if (pending & C_SW0) /* do software after hardware */
93 do_IRQ(MSP_INT_SW0);
94
95 else if (pending & C_SW1)
96 do_IRQ(MSP_INT_SW1);
97}
98
99static struct irqaction cascade_msp = {
100 .handler = no_action,
101 .name = "MSP cascade"
102};
103
104
105void __init arch_init_irq(void)
106{
107 /* initialize the 1st-level CPU based interrupt controller */
108 mips_cpu_irq_init();
109
110#ifdef CONFIG_IRQ_MSP_CIC
111 msp_cic_irq_init();
112
113 /* setup the cascaded interrupts */
114 setup_irq(MSP_INT_CIC, &cascade_msp);
115 setup_irq(MSP_INT_PER, &cascade_msp);
116#else
117 /* setup the 2nd-level SLP register based interrupt controller */
118 msp_slp_irq_init();
119
120 /* setup the cascaded SLP/PER interrupts */
121 setup_irq(MSP_INT_SLP, &cascade_msp);
122 setup_irq(MSP_INT_PER, &cascade_msp);
123#endif
124}
diff --git a/arch/mips/pmc-sierra/msp71xx/msp_irq_cic.c b/arch/mips/pmc-sierra/msp71xx/msp_irq_cic.c
new file mode 100644
index 000000000000..5175357d0a25
--- /dev/null
+++ b/arch/mips/pmc-sierra/msp71xx/msp_irq_cic.c
@@ -0,0 +1,134 @@
1/*
2 * This file define the irq handler for MSP SLM subsystem interrupts.
3 *
4 * Copyright 2005-2007 PMC-Sierra, Inc, derived from irq_cpu.c
5 * Author: Andrew Hughes, Andrew_Hughes@pmc-sierra.com
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13#include <linux/init.h>
14#include <linux/interrupt.h>
15#include <linux/kernel.h>
16#include <linux/bitops.h>
17
18#include <asm/system.h>
19
20#include <msp_cic_int.h>
21#include <msp_regs.h>
22
23/*
24 * NOTE: We are only enabling support for VPE0 right now.
25 */
26
27static inline void unmask_msp_cic_irq(unsigned int irq)
28{
29
30 /* check for PER interrupt range */
31 if (irq < MSP_PER_INTBASE)
32 *CIC_VPE0_MSK_REG |= (1 << (irq - MSP_CIC_INTBASE));
33 else
34 *PER_INT_MSK_REG |= (1 << (irq - MSP_PER_INTBASE));
35}
36
37static inline void mask_msp_cic_irq(unsigned int irq)
38{
39 /* check for PER interrupt range */
40 if (irq < MSP_PER_INTBASE)
41 *CIC_VPE0_MSK_REG &= ~(1 << (irq - MSP_CIC_INTBASE));
42 else
43 *PER_INT_MSK_REG &= ~(1 << (irq - MSP_PER_INTBASE));
44}
45
46/*
47 * While we ack the interrupt interrupts are disabled and thus we don't need
48 * to deal with concurrency issues. Same for msp_cic_irq_end.
49 */
50static inline void ack_msp_cic_irq(unsigned int irq)
51{
52 mask_msp_cic_irq(irq);
53
54 /*
55 * only really necessary for 18, 16-14 and sometimes 3:0 (since
56 * these can be edge sensitive) but it doesn't hurt for the others.
57 */
58
59 /* check for PER interrupt range */
60 if (irq < MSP_PER_INTBASE)
61 *CIC_STS_REG = (1 << (irq - MSP_CIC_INTBASE));
62 else
63 *PER_INT_STS_REG = (1 << (irq - MSP_PER_INTBASE));
64}
65
66static struct irq_chip msp_cic_irq_controller = {
67 .name = "MSP_CIC",
68 .ack = ack_msp_cic_irq,
69 .mask = ack_msp_cic_irq,
70 .mask_ack = ack_msp_cic_irq,
71 .unmask = unmask_msp_cic_irq,
72};
73
74
75void __init msp_cic_irq_init(void)
76{
77 int i;
78
79 /* Mask/clear interrupts. */
80 *CIC_VPE0_MSK_REG = 0x00000000;
81 *PER_INT_MSK_REG = 0x00000000;
82 *CIC_STS_REG = 0xFFFFFFFF;
83 *PER_INT_STS_REG = 0xFFFFFFFF;
84
85#if defined(CONFIG_PMC_MSP7120_GW) || \
86 defined(CONFIG_PMC_MSP7120_EVAL)
87 /*
88 * The MSP7120 RG and EVBD boards use IRQ[6:4] for PCI.
89 * These inputs map to EXT_INT_POL[6:4] inside the CIC.
90 * They are to be active low, level sensitive.
91 */
92 *CIC_EXT_CFG_REG &= 0xFFFF8F8F;
93#endif
94
95 /* initialize all the IRQ descriptors */
96 for (i = MSP_CIC_INTBASE; i < MSP_PER_INTBASE + 32; i++)
97 set_irq_chip_and_handler(i, &msp_cic_irq_controller,
98 handle_level_irq);
99}
100
101void msp_cic_irq_dispatch(void)
102{
103 u32 pending;
104 int intbase;
105
106 intbase = MSP_CIC_INTBASE;
107 pending = *CIC_STS_REG & *CIC_VPE0_MSK_REG;
108
109 /* check for PER interrupt */
110 if (pending == (1 << (MSP_INT_PER - MSP_CIC_INTBASE))) {
111 intbase = MSP_PER_INTBASE;
112 pending = *PER_INT_STS_REG & *PER_INT_MSK_REG;
113 }
114
115 /* check for spurious interrupt */
116 if (pending == 0x00000000) {
117 printk(KERN_ERR
118 "Spurious %s interrupt? status %08x, mask %08x\n",
119 (intbase == MSP_CIC_INTBASE) ? "CIC" : "PER",
120 (intbase == MSP_CIC_INTBASE) ?
121 *CIC_STS_REG : *PER_INT_STS_REG,
122 (intbase == MSP_CIC_INTBASE) ?
123 *CIC_VPE0_MSK_REG : *PER_INT_MSK_REG);
124 return;
125 }
126
127 /* check for the timer and dispatch it first */
128 if ((intbase == MSP_CIC_INTBASE) &&
129 (pending & (1 << (MSP_INT_VPE0_TIMER - MSP_CIC_INTBASE))))
130 do_IRQ(MSP_INT_VPE0_TIMER);
131 else
132 do_IRQ(ffs(pending) + intbase - 1);
133}
134
diff --git a/arch/mips/pmc-sierra/msp71xx/msp_irq_slp.c b/arch/mips/pmc-sierra/msp71xx/msp_irq_slp.c
new file mode 100644
index 000000000000..f5f1b8d2bb9a
--- /dev/null
+++ b/arch/mips/pmc-sierra/msp71xx/msp_irq_slp.c
@@ -0,0 +1,109 @@
1/*
2 * This file define the irq handler for MSP SLM subsystem interrupts.
3 *
4 * Copyright 2005-2006 PMC-Sierra, Inc, derived from irq_cpu.c
5 * Author: Andrew Hughes, Andrew_Hughes@pmc-sierra.com
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13#include <linux/init.h>
14#include <linux/interrupt.h>
15#include <linux/kernel.h>
16#include <linux/bitops.h>
17
18#include <asm/mipsregs.h>
19#include <asm/system.h>
20
21#include <msp_slp_int.h>
22#include <msp_regs.h>
23
24static inline void unmask_msp_slp_irq(unsigned int irq)
25{
26 /* check for PER interrupt range */
27 if (irq < MSP_PER_INTBASE)
28 *SLP_INT_MSK_REG |= (1 << (irq - MSP_SLP_INTBASE));
29 else
30 *PER_INT_MSK_REG |= (1 << (irq - MSP_PER_INTBASE));
31}
32
33static inline void mask_msp_slp_irq(unsigned int irq)
34{
35 /* check for PER interrupt range */
36 if (irq < MSP_PER_INTBASE)
37 *SLP_INT_MSK_REG &= ~(1 << (irq - MSP_SLP_INTBASE));
38 else
39 *PER_INT_MSK_REG &= ~(1 << (irq - MSP_PER_INTBASE));
40}
41
42/*
43 * While we ack the interrupt interrupts are disabled and thus we don't need
44 * to deal with concurrency issues. Same for msp_slp_irq_end.
45 */
46static inline void ack_msp_slp_irq(unsigned int irq)
47{
48 mask_slp_irq(irq);
49
50 /*
51 * only really necessary for 18, 16-14 and sometimes 3:0 (since
52 * these can be edge sensitive) but it doesn't hurt for the others.
53 */
54
55 /* check for PER interrupt range */
56 if (irq < MSP_PER_INTBASE)
57 *SLP_INT_STS_REG = (1 << (irq - MSP_SLP_INTBASE));
58 else
59 *PER_INT_STS_REG = (1 << (irq - MSP_PER_INTBASE));
60}
61
62static struct irq_chip msp_slp_irq_controller = {
63 .name = "MSP_SLP",
64 .ack = ack_msp_slp_irq,
65 .mask = ack_msp_slp_irq,
66 .mask_ack = ack_msp_slp_irq,
67 .unmask = unmask_msp_slp_irq,
68};
69
70void __init msp_slp_irq_init(void)
71{
72 int i;
73
74 /* Mask/clear interrupts. */
75 *SLP_INT_MSK_REG = 0x00000000;
76 *PER_INT_MSK_REG = 0x00000000;
77 *SLP_INT_STS_REG = 0xFFFFFFFF;
78 *PER_INT_STS_REG = 0xFFFFFFFF;
79
80 /* initialize all the IRQ descriptors */
81 for (i = MSP_SLP_INTBASE; i < MSP_PER_INTBASE + 32; i++)
82 set_irq_chip_and_handler(i, &msp_slp_irq_controller
83 handle_level_irq);
84}
85
86void msp_slp_irq_dispatch(void)
87{
88 u32 pending;
89 int intbase;
90
91 intbase = MSP_SLP_INTBASE;
92 pending = *SLP_INT_STS_REG & *SLP_INT_MSK_REG;
93
94 /* check for PER interrupt */
95 if (pending == (1 << (MSP_INT_PER - MSP_SLP_INTBASE))) {
96 intbase = MSP_PER_INTBASE;
97 pending = *PER_INT_STS_REG & *PER_INT_MSK_REG;
98 }
99
100 /* check for spurious interrupt */
101 if (pending == 0x00000000) {
102 printk(KERN_ERR "Spurious %s interrupt?\n",
103 (intbase == MSP_SLP_INTBASE) ? "SLP" : "PER");
104 return;
105 }
106
107 /* dispatch the irq */
108 do_IRQ(ffs(pending) + intbase - 1);
109}
diff --git a/arch/mips/momentum/ocelot_3/ocelot_3_fpga.h b/arch/mips/pmc-sierra/msp71xx/msp_pci.c
index 5710a9029f1c..f764fe7748d6 100644
--- a/arch/mips/momentum/ocelot_3/ocelot_3_fpga.h
+++ b/arch/mips/pmc-sierra/msp71xx/msp_pci.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Ocelot-3 Board Register Definitions 2 * The setup file for PCI related hardware on PMC-Sierra MSP processors.
3 * 3 *
4 * (C) 2002 Momentum Computer Inc. 4 * Copyright 2005-2006 PMC-Sierra, Inc.
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify it 6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the 7 * under the terms of the GNU General Public License as published by the
@@ -22,38 +22,29 @@
22 * You should have received a copy of the GNU General Public License along 22 * You should have received a copy of the GNU General Public License along
23 * with this program; if not, write to the Free Software Foundation, Inc., 23 * with this program; if not, write to the Free Software Foundation, Inc.,
24 * 675 Mass Ave, Cambridge, MA 02139, USA. 24 * 675 Mass Ave, Cambridge, MA 02139, USA.
25 *
26 * Louis Hamilton, Red Hat, Inc.
27 * hamilton@redhat.com [MIPS64 modifications]
28 *
29 * Copyright (C) 2004 MontaVista Software Inc.
30 * Author: Manish Lachwani, mlachwani@mvista.com
31 */ 25 */
32 26
33#ifndef __OCELOT_3_FPGA_H__ 27#include <linux/init.h>
34#define __OCELOT_3_FPGA_H__ 28
35 29#include <msp_prom.h>
36#define OCELOT_3_REG_BOARDREV 0x0 30#include <msp_regs.h>
37#define OCELOT_3_REG_FPGA_REV 0x1 31
38#define OCELOT_3_REG_FPGA_TYPE 0x2 32extern void msp_pci_init(void);
39#define OCELOT_3_REG_RESET_STATUS 0x3
40#define OCELOT_3_REG_BOARD_STATUS 0x4
41#define OCELOT_3_REG_CPCI_ID 0x5
42#define OCELOT_3_REG_SET 0x6
43#define OCELOT_3_REG_CLR 0x7
44#define OCELOT_3_REG_EEPROM_MODE 0x9
45#define OCELOT_3_REG_INTMASK 0xa
46#define OCELOT_3_REG_INTSTAT 0xb
47#define OCELOT_3_REG_UART_INTMASK 0xc
48#define OCELOT_3_REG_UART_INTSTAT 0xd
49#define OCELOT_3_REG_INTSET 0xe
50#define OCELOT_3_REG_INTCLR 0xf
51
52extern unsigned long ocelot_fpga_base;
53
54#define __FPGA_REG_TO_ADDR(reg) \
55 ((void *) ocelot_fpga_base + OCELOT_3_REG_##reg)
56#define OCELOT_FPGA_WRITE(x, reg) writeb(x, __FPGA_REG_TO_ADDR(reg))
57#define OCELOT_FPGA_READ(reg) readb(__FPGA_REG_TO_ADDR(reg))
58 33
34static int __init msp_pci_setup(void)
35{
36#if 0 /* Linux 2.6 initialization code to be completed */
37 if (getdeviceid() & DEV_ID_SINGLE_PC) {
38 /* If single card mode */
39 slmRegs *sreg = (slmRegs *) SREG_BASE;
40
41 sreg->single_pc_enable = SINGLE_PCCARD;
42 }
59#endif 43#endif
44
45 msp_pci_init();
46
47 return 0;
48}
49
50subsys_initcall(msp_pci_setup);
diff --git a/arch/mips/pmc-sierra/msp71xx/msp_prom.c b/arch/mips/pmc-sierra/msp71xx/msp_prom.c
new file mode 100644
index 000000000000..e5bd5481d8db
--- /dev/null
+++ b/arch/mips/pmc-sierra/msp71xx/msp_prom.c
@@ -0,0 +1,566 @@
1/*
2 * BRIEF MODULE DESCRIPTION
3 * PROM library initialisation code, assuming a version of
4 * pmon is the boot code.
5 *
6 * Copyright 2000,2001 MontaVista Software Inc.
7 * Author: MontaVista Software, Inc.
8 * ppopov@mvista.com or source@mvista.com
9 *
10 * This file was derived from Carsten Langgaard's
11 * arch/mips/mips-boards/xx files.
12 *
13 * Carsten Langgaard, carstenl@mips.com
14 * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
15 *
16 * This program is free software; you can redistribute it and/or modify it
17 * under the terms of the GNU General Public License as published by the
18 * Free Software Foundation; either version 2 of the License, or (at your
19 * option) any later version.
20 *
21 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
22 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
23 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
24 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
27 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
28 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 * You should have received a copy of the GNU General Public License along
33 * with this program; if not, write to the Free Software Foundation, Inc.,
34 * 675 Mass Ave, Cambridge, MA 02139, USA.
35 */
36
37#include <linux/module.h>
38#include <linux/kernel.h>
39#include <linux/init.h>
40#include <linux/string.h>
41#include <linux/interrupt.h>
42#include <linux/mm.h>
43#ifdef CONFIG_CRAMFS
44#include <linux/cramfs_fs.h>
45#endif
46#ifdef CONFIG_SQUASHFS
47#include <linux/squashfs_fs.h>
48#endif
49
50#include <asm/addrspace.h>
51#include <asm/bootinfo.h>
52#include <asm-generic/sections.h>
53#include <asm/page.h>
54
55#include <msp_prom.h>
56#include <msp_regs.h>
57
58/* global PROM environment variables and pointers */
59int prom_argc;
60char **prom_argv, **prom_envp;
61int *prom_vec;
62
63/* debug flag */
64int init_debug = 1;
65
66/* memory blocks */
67struct prom_pmemblock mdesc[PROM_MAX_PMEMBLOCKS];
68
69/* default feature sets */
70static char msp_default_features[] =
71#if defined(CONFIG_PMC_MSP4200_EVAL) \
72 || defined(CONFIG_PMC_MSP4200_GW)
73 "ERER";
74#elif defined(CONFIG_PMC_MSP7120_EVAL) \
75 || defined(CONFIG_PMC_MSP7120_GW)
76 "EMEMSP";
77#elif defined(CONFIG_PMC_MSP7120_FPGA)
78 "EMEM";
79#endif
80
81/* conversion functions */
82static inline unsigned char str2hexnum(unsigned char c)
83{
84 if (c >= '0' && c <= '9')
85 return c - '0';
86 if (c >= 'a' && c <= 'f')
87 return c - 'a' + 10;
88 return 0; /* foo */
89}
90
91static inline int str2eaddr(unsigned char *ea, unsigned char *str)
92{
93 int index = 0;
94 unsigned char num = 0;
95
96 while (*str != '\0') {
97 if ((*str == '.') || (*str == ':')) {
98 ea[index++] = num;
99 num = 0;
100 str++;
101 } else {
102 num = num << 4;
103 num |= str2hexnum(*str++);
104 }
105 }
106
107 if (index == 5) {
108 ea[index++] = num;
109 return 0;
110 } else
111 return -1;
112}
113EXPORT_SYMBOL(str2eaddr);
114
115static inline unsigned long str2hex(unsigned char *str)
116{
117 int value = 0;
118
119 while (*str) {
120 value = value << 4;
121 value |= str2hexnum(*str++);
122 }
123
124 return value;
125}
126
127/* function to query the system information */
128const char *get_system_type(void)
129{
130#if defined(CONFIG_PMC_MSP4200_EVAL)
131 return "PMC-Sierra MSP4200 Eval Board";
132#elif defined(CONFIG_PMC_MSP4200_GW)
133 return "PMC-Sierra MSP4200 VoIP Gateway";
134#elif defined(CONFIG_PMC_MSP7120_EVAL)
135 return "PMC-Sierra MSP7120 Eval Board";
136#elif defined(CONFIG_PMC_MSP7120_GW)
137 return "PMC-Sierra MSP7120 Residential Gateway";
138#elif defined(CONFIG_PMC_MSP7120_FPGA)
139 return "PMC-Sierra MSP7120 FPGA";
140#else
141 #error "What is the type of *your* MSP?"
142#endif
143}
144
145int get_ethernet_addr(char *ethaddr_name, char *ethernet_addr)
146{
147 char *ethaddr_str;
148
149 ethaddr_str = prom_getenv(ethaddr_name);
150 if (!ethaddr_str) {
151 printk(KERN_WARNING "%s not set in boot prom\n", ethaddr_name);
152 return -1;
153 }
154
155 if (str2eaddr(ethernet_addr, ethaddr_str) == -1) {
156 printk(KERN_WARNING "%s badly formatted-<%s>\n",
157 ethaddr_name, ethaddr_str);
158 return -1;
159 }
160
161 if (init_debug > 1) {
162 int i;
163 printk(KERN_DEBUG "get_ethernet_addr: for %s ", ethaddr_name);
164 for (i = 0; i < 5; i++)
165 printk(KERN_DEBUG "%02x:",
166 (unsigned char)*(ethernet_addr+i));
167 printk(KERN_DEBUG "%02x\n", *(ethernet_addr+i));
168 }
169
170 return 0;
171}
172EXPORT_SYMBOL(get_ethernet_addr);
173
174static char *get_features(void)
175{
176 char *feature = prom_getenv(FEATURES);
177
178 if (feature == NULL) {
179 /* default features based on MACHINE_TYPE */
180 feature = msp_default_features;
181 }
182
183 return feature;
184}
185
186static char test_feature(char c)
187{
188 char *feature = get_features();
189
190 while (*feature) {
191 if (*feature++ == c)
192 return *feature;
193 feature++;
194 }
195
196 return FEATURE_NOEXIST;
197}
198
199unsigned long get_deviceid(void)
200{
201 char *deviceid = prom_getenv(DEVICEID);
202
203 if (deviceid == NULL)
204 return *DEV_ID_REG;
205 else
206 return str2hex(deviceid);
207}
208
209char identify_pci(void)
210{
211 return test_feature(PCI_KEY);
212}
213EXPORT_SYMBOL(identify_pci);
214
215char identify_pcimux(void)
216{
217 return test_feature(PCIMUX_KEY);
218}
219
220char identify_sec(void)
221{
222 return test_feature(SEC_KEY);
223}
224EXPORT_SYMBOL(identify_sec);
225
226char identify_spad(void)
227{
228 return test_feature(SPAD_KEY);
229}
230EXPORT_SYMBOL(identify_spad);
231
232char identify_tdm(void)
233{
234 return test_feature(TDM_KEY);
235}
236EXPORT_SYMBOL(identify_tdm);
237
238char identify_zsp(void)
239{
240 return test_feature(ZSP_KEY);
241}
242EXPORT_SYMBOL(identify_zsp);
243
244static char identify_enetfeature(char key, unsigned long interface_num)
245{
246 char *feature = get_features();
247
248 while (*feature) {
249 if (*feature++ == key && interface_num-- == 0)
250 return *feature;
251 feature++;
252 }
253
254 return FEATURE_NOEXIST;
255}
256
257char identify_enet(unsigned long interface_num)
258{
259 return identify_enetfeature(ENET_KEY, interface_num);
260}
261EXPORT_SYMBOL(identify_enet);
262
263char identify_enetTxD(unsigned long interface_num)
264{
265 return identify_enetfeature(ENETTXD_KEY, interface_num);
266}
267EXPORT_SYMBOL(identify_enetTxD);
268
269unsigned long identify_family(void)
270{
271 unsigned long deviceid;
272
273 deviceid = get_deviceid();
274
275 return deviceid & CPU_DEVID_FAMILY;
276}
277EXPORT_SYMBOL(identify_family);
278
279unsigned long identify_revision(void)
280{
281 unsigned long deviceid;
282
283 deviceid = get_deviceid();
284
285 return deviceid & CPU_DEVID_REVISION;
286}
287EXPORT_SYMBOL(identify_revision);
288
289/* PROM environment functions */
290char *prom_getenv(char *env_name)
291{
292 /*
293 * Return a pointer to the given environment variable. prom_envp
294 * points to a null terminated array of pointers to variables.
295 * Environment variables are stored in the form of "memsize=64"
296 */
297
298 char **var = prom_envp;
299 int i = strlen(env_name);
300
301 while (*var) {
302 if (strncmp(env_name, *var, i) == 0) {
303 return (*var + strlen(env_name) + 1);
304 }
305 var++;
306 }
307
308 return NULL;
309}
310
311/* PROM commandline functions */
312char *prom_getcmdline(void)
313{
314 return &(arcs_cmdline[0]);
315}
316EXPORT_SYMBOL(prom_getcmdline);
317
318void __init prom_init_cmdline(void)
319{
320 char *cp;
321 int actr;
322
323 actr = 1; /* Always ignore argv[0] */
324
325 cp = &(arcs_cmdline[0]);
326 while (actr < prom_argc) {
327 strcpy(cp, prom_argv[actr]);
328 cp += strlen(prom_argv[actr]);
329 *cp++ = ' ';
330 actr++;
331 }
332 if (cp != &(arcs_cmdline[0])) /* get rid of trailing space */
333 --cp;
334 *cp = '\0';
335}
336
337/* memory allocation functions */
338static int __init prom_memtype_classify(unsigned int type)
339{
340 switch (type) {
341 case yamon_free:
342 return BOOT_MEM_RAM;
343 case yamon_prom:
344 return BOOT_MEM_ROM_DATA;
345 default:
346 return BOOT_MEM_RESERVED;
347 }
348}
349
350void __init prom_meminit(void)
351{
352 struct prom_pmemblock *p;
353
354 p = prom_getmdesc();
355
356 while (p->size) {
357 long type;
358 unsigned long base, size;
359
360 type = prom_memtype_classify(p->type);
361 base = p->base;
362 size = p->size;
363
364 add_memory_region(base, size, type);
365 p++;
366 }
367}
368
369void __init prom_free_prom_memory(void)
370{
371 int argc;
372 char **argv;
373 char **envp;
374 char *ptr;
375 int len = 0;
376 int i;
377 unsigned long addr;
378
379 /*
380 * preserve environment variables and command line from pmon/bbload
381 * first preserve the command line
382 */
383 for (argc = 0; argc < prom_argc; argc++) {
384 len += sizeof(char *); /* length of pointer */
385 len += strlen(prom_argv[argc]) + 1; /* length of string */
386 }
387 len += sizeof(char *); /* plus length of null pointer */
388
389 argv = kmalloc(len, GFP_KERNEL);
390 ptr = (char *) &argv[prom_argc + 1]; /* strings follow array */
391
392 for (argc = 0; argc < prom_argc; argc++) {
393 argv[argc] = ptr;
394 strcpy(ptr, prom_argv[argc]);
395 ptr += strlen(prom_argv[argc]) + 1;
396 }
397 argv[prom_argc] = NULL; /* end array with null pointer */
398 prom_argv = argv;
399
400 /* next preserve the environment variables */
401 len = 0;
402 i = 0;
403 for (envp = prom_envp; *envp != NULL; envp++) {
404 i++; /* count number of environment variables */
405 len += sizeof(char *); /* length of pointer */
406 len += strlen(*envp) + 1; /* length of string */
407 }
408 len += sizeof(char *); /* plus length of null pointer */
409
410 envp = kmalloc(len, GFP_KERNEL);
411 ptr = (char *) &envp[i+1];
412
413 for (argc = 0; argc < i; argc++) {
414 envp[argc] = ptr;
415 strcpy(ptr, prom_envp[argc]);
416 ptr += strlen(prom_envp[argc]) + 1;
417 }
418 envp[i] = NULL; /* end array with null pointer */
419 prom_envp = envp;
420
421 for (i = 0; i < boot_mem_map.nr_map; i++) {
422 if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA)
423 continue;
424
425 addr = boot_mem_map.map[i].addr;
426 free_init_pages("prom memory",
427 addr, addr + boot_mem_map.map[i].size);
428 }
429}
430
431struct prom_pmemblock *__init prom_getmdesc(void)
432{
433 static char memsz_env[] __initdata = "memsize";
434 static char heaptop_env[] __initdata = "heaptop";
435 char *str;
436 unsigned int memsize;
437 unsigned int heaptop;
438#ifdef CONFIG_MTD_PMC_MSP_RAMROOT
439 void *ramroot_start;
440 unsigned long ramroot_size;
441#endif
442 int i;
443
444 str = prom_getenv(memsz_env);
445 if (!str) {
446 ppfinit("memsize not set in boot prom, "
447 "set to default (32Mb)\n");
448 memsize = 0x02000000;
449 } else {
450 memsize = simple_strtol(str, NULL, 0);
451
452 if (memsize == 0) {
453 /* if memsize is a bad size, use reasonable default */
454 memsize = 0x02000000;
455 }
456
457 /* convert to physical address (removing caching bits, etc) */
458 memsize = CPHYSADDR(memsize);
459 }
460
461 str = prom_getenv(heaptop_env);
462 if (!str) {
463 heaptop = CPHYSADDR((u32)&_text);
464 ppfinit("heaptop not set in boot prom, "
465 "set to default 0x%08x\n", heaptop);
466 } else {
467 heaptop = simple_strtol(str, NULL, 16);
468 if (heaptop == 0) {
469 /* heaptop conversion bad, might have 0xValue */
470 heaptop = simple_strtol(str, NULL, 0);
471
472 if (heaptop == 0) {
473 /* heaptop still bad, use reasonable default */
474 heaptop = CPHYSADDR((u32)&_text);
475 }
476 }
477
478 /* convert to physical address (removing caching bits, etc) */
479 heaptop = CPHYSADDR((u32)heaptop);
480 }
481
482 /* the base region */
483 i = 0;
484 mdesc[i].type = BOOT_MEM_RESERVED;
485 mdesc[i].base = 0x00000000;
486 mdesc[i].size = PAGE_ALIGN(0x300 + 0x80);
487 /* jtag interrupt vector + sizeof vector */
488
489 /* PMON data */
490 if (heaptop > mdesc[i].base + mdesc[i].size) {
491 i++; /* 1 */
492 mdesc[i].type = BOOT_MEM_ROM_DATA;
493 mdesc[i].base = mdesc[i-1].base + mdesc[i-1].size;
494 mdesc[i].size = heaptop - mdesc[i].base;
495 }
496
497 /* end of PMON data to start of kernel -- probably zero .. */
498 if (heaptop != CPHYSADDR((u32)_text)) {
499 i++; /* 2 */
500 mdesc[i].type = BOOT_MEM_RAM;
501 mdesc[i].base = heaptop;
502 mdesc[i].size = CPHYSADDR((u32)_text) - mdesc[i].base;
503 }
504
505 /* kernel proper */
506 i++; /* 3 */
507 mdesc[i].type = BOOT_MEM_RESERVED;
508 mdesc[i].base = CPHYSADDR((u32)_text);
509#ifdef CONFIG_MTD_PMC_MSP_RAMROOT
510 if (get_ramroot(&ramroot_start, &ramroot_size)) {
511 /*
512 * Rootfs in RAM -- follows kernel
513 * Combine rootfs image with kernel block so a
514 * page (4k) isn't wasted between memory blocks
515 */
516 mdesc[i].size = CPHYSADDR(PAGE_ALIGN(
517 (u32)ramroot_start + ramroot_size)) - mdesc[i].base;
518 } else
519#endif
520 mdesc[i].size = CPHYSADDR(PAGE_ALIGN(
521 (u32)_end)) - mdesc[i].base;
522
523 /* Remainder of RAM -- under memsize */
524 i++; /* 5 */
525 mdesc[i].type = yamon_free;
526 mdesc[i].base = mdesc[i-1].base + mdesc[i-1].size;
527 mdesc[i].size = memsize - mdesc[i].base;
528
529 return &mdesc[0];
530}
531
532/* rootfs functions */
533#ifdef CONFIG_MTD_PMC_MSP_RAMROOT
534bool get_ramroot(void **start, unsigned long *size)
535{
536 extern char _end[];
537
538 /* Check for start following the end of the kernel */
539 void *check_start = (void *)_end;
540
541 /* Check for supported rootfs types */
542#ifdef CONFIG_CRAMFS
543 if (*(__u32 *)check_start == CRAMFS_MAGIC) {
544 /* Get CRAMFS size */
545 *start = check_start;
546 *size = PAGE_ALIGN(((struct cramfs_super *)
547 check_start)->size);
548
549 return true;
550 }
551#endif
552#ifdef CONFIG_SQUASHFS
553 if (*((unsigned int *)check_start) == SQUASHFS_MAGIC) {
554 /* Get SQUASHFS size */
555 *start = check_start;
556 *size = PAGE_ALIGN(((struct squashfs_super_block *)
557 check_start)->bytes_used);
558
559 return true;
560 }
561#endif
562
563 return false;
564}
565EXPORT_SYMBOL(get_ramroot);
566#endif
diff --git a/arch/mips/pmc-sierra/msp71xx/msp_setup.c b/arch/mips/pmc-sierra/msp71xx/msp_setup.c
new file mode 100644
index 000000000000..8f69b789be90
--- /dev/null
+++ b/arch/mips/pmc-sierra/msp71xx/msp_setup.c
@@ -0,0 +1,256 @@
1/*
2 * The generic setup file for PMC-Sierra MSP processors
3 *
4 * Copyright 2005-2007 PMC-Sierra, Inc,
5 * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13#include <asm/bootinfo.h>
14#include <asm/cacheflush.h>
15#include <asm/r4kcache.h>
16#include <asm/reboot.h>
17#include <asm/time.h>
18
19#include <msp_prom.h>
20#include <msp_regs.h>
21
22#if defined(CONFIG_PMC_MSP7120_GW)
23#include <msp_regops.h>
24#include <msp_gpio.h>
25#define MSP_BOARD_RESET_GPIO 9
26#endif
27
28extern void msp_timer_init(void);
29extern void msp_serial_setup(void);
30extern void pmctwiled_setup(void);
31
32#if defined(CONFIG_PMC_MSP7120_EVAL) || \
33 defined(CONFIG_PMC_MSP7120_GW) || \
34 defined(CONFIG_PMC_MSP7120_FPGA)
35/*
36 * Performs the reset for MSP7120-based boards
37 */
38void msp7120_reset(void)
39{
40 void *start, *end, *iptr;
41 register int i;
42
43 /* Diasble all interrupts */
44 local_irq_disable();
45#ifdef CONFIG_SYS_SUPPORTS_MULTITHREADING
46 dvpe();
47#endif
48
49 /* Cache the reset code of this function */
50 __asm__ __volatile__ (
51 " .set push \n"
52 " .set mips3 \n"
53 " la %0,startpoint \n"
54 " la %1,endpoint \n"
55 " .set pop \n"
56 : "=r" (start), "=r" (end)
57 :
58 );
59
60 for (iptr = (void *)((unsigned int)start & ~(L1_CACHE_BYTES - 1));
61 iptr < end; iptr += L1_CACHE_BYTES)
62 cache_op(Fill, iptr);
63
64 __asm__ __volatile__ (
65 "startpoint: \n"
66 );
67
68 /* Put the DDRC into self-refresh mode */
69 DDRC_INDIRECT_WRITE(DDRC_CTL(10), 0xb, 1 << 16);
70
71 /*
72 * IMPORTANT!
73 * DO NOT do anything from here on out that might even
74 * think about fetching from RAM - i.e., don't call any
75 * non-inlined functions, and be VERY sure that any inline
76 * functions you do call do NOT access any sort of RAM
77 * anywhere!
78 */
79
80 /* Wait a bit for the DDRC to settle */
81 for (i = 0; i < 100000000; i++);
82
83#if defined(CONFIG_PMC_MSP7120_GW)
84 /*
85 * Set GPIO 9 HI, (tied to board reset logic)
86 * GPIO 9 is the 4th GPIO of register 3
87 *
88 * NOTE: We cannot use the higher-level msp_gpio_mode()/out()
89 * as GPIO char driver may not be enabled and it would look up
90 * data inRAM!
91 */
92 set_value_reg32(GPIO_CFG3_REG,
93 basic_mode_mask(MSP_BOARD_RESET_GPIO),
94 basic_mode(MSP_GPIO_OUTPUT, MSP_BOARD_RESET_GPIO));
95 set_reg32(GPIO_DATA3_REG,
96 basic_data_mask(MSP_BOARD_RESET_GPIO));
97
98 /*
99 * In case GPIO9 doesn't reset the board (jumper configurable!)
100 * fallback to device reset below.
101 */
102#endif
103 /* Set bit 1 of the MSP7120 reset register */
104 *RST_SET_REG = 0x00000001;
105
106 __asm__ __volatile__ (
107 "endpoint: \n"
108 );
109}
110#endif
111
112void msp_restart(char *command)
113{
114 printk(KERN_WARNING "Now rebooting .......\n");
115
116#if defined(CONFIG_PMC_MSP7120_EVAL) || \
117 defined(CONFIG_PMC_MSP7120_GW) || \
118 defined(CONFIG_PMC_MSP7120_FPGA)
119 msp7120_reset();
120#else
121 /* No chip-specific reset code, just jump to the ROM reset vector */
122 set_c0_status(ST0_BEV | ST0_ERL);
123 change_c0_config(CONF_CM_CMASK, CONF_CM_UNCACHED);
124 flush_cache_all();
125 write_c0_wired(0);
126
127 __asm__ __volatile__("jr\t%0"::"r"(0xbfc00000));
128#endif
129}
130
131void msp_halt(void)
132{
133 printk(KERN_WARNING "\n** You can safely turn off the power\n");
134 while (1)
135 /* If possible call official function to get CPU WARs */
136 if (cpu_wait)
137 (*cpu_wait)();
138 else
139 __asm__(".set\tmips3\n\t" "wait\n\t" ".set\tmips0");
140}
141
142void msp_power_off(void)
143{
144 msp_halt();
145}
146
147void __init plat_mem_setup(void)
148{
149 _machine_restart = msp_restart;
150 _machine_halt = msp_halt;
151 pm_power_off = msp_power_off;
152
153 board_time_init = msp_timer_init;
154}
155
156void __init prom_init(void)
157{
158 unsigned long family;
159 unsigned long revision;
160
161 prom_argc = fw_arg0;
162 prom_argv = (char **)fw_arg1;
163 prom_envp = (char **)fw_arg2;
164
165 /*
166 * Someday we can use this with PMON2000 to get a
167 * platform call prom routines for output etc. without
168 * having to use grody hacks. For now it's unused.
169 *
170 * struct callvectors *cv = (struct callvectors *) fw_arg3;
171 */
172 family = identify_family();
173 revision = identify_revision();
174
175 switch (family) {
176 case FAMILY_FPGA:
177 if (FPGA_IS_MSP4200(revision)) {
178 /* Old-style revision ID */
179 mips_machgroup = MACH_GROUP_MSP;
180 mips_machtype = MACH_MSP4200_FPGA;
181 } else {
182 mips_machgroup = MACH_GROUP_MSP;
183 mips_machtype = MACH_MSP_OTHER;
184 }
185 break;
186
187 case FAMILY_MSP4200:
188 mips_machgroup = MACH_GROUP_MSP;
189#if defined(CONFIG_PMC_MSP4200_EVAL)
190 mips_machtype = MACH_MSP4200_EVAL;
191#elif defined(CONFIG_PMC_MSP4200_GW)
192 mips_machtype = MACH_MSP4200_GW;
193#else
194 mips_machtype = MACH_MSP_OTHER;
195#endif
196 break;
197
198 case FAMILY_MSP4200_FPGA:
199 mips_machgroup = MACH_GROUP_MSP;
200 mips_machtype = MACH_MSP4200_FPGA;
201 break;
202
203 case FAMILY_MSP7100:
204 mips_machgroup = MACH_GROUP_MSP;
205#if defined(CONFIG_PMC_MSP7120_EVAL)
206 mips_machtype = MACH_MSP7120_EVAL;
207#elif defined(CONFIG_PMC_MSP7120_GW)
208 mips_machtype = MACH_MSP7120_GW;
209#else
210 mips_machtype = MACH_MSP_OTHER;
211#endif
212 break;
213
214 case FAMILY_MSP7100_FPGA:
215 mips_machgroup = MACH_GROUP_MSP;
216 mips_machtype = MACH_MSP7120_FPGA;
217 break;
218
219 default:
220 /* we don't recognize the machine */
221 mips_machgroup = MACH_GROUP_UNKNOWN;
222 mips_machtype = MACH_UNKNOWN;
223 break;
224 }
225
226 /* make sure we have the right initialization routine - sanity */
227 if (mips_machgroup != MACH_GROUP_MSP) {
228 ppfinit("Unknown machine group in a "
229 "MSP initialization routine\n");
230 panic("***Bogosity factor five***, exiting\n");
231 }
232
233 prom_init_cmdline();
234
235 prom_meminit();
236
237 /*
238 * Sub-system setup follows.
239 * Setup functions can either be called here or using the
240 * subsys_initcall mechanism (i.e. see msp_pci_setup). The
241 * order in which they are called can be changed by using the
242 * link order in arch/mips/pmc-sierra/msp71xx/Makefile.
243 *
244 * NOTE: Please keep sub-system specific initialization code
245 * in separate specific files.
246 */
247 msp_serial_setup();
248
249#ifdef CONFIG_PMCTWILED
250 /*
251 * Setup LED states before the subsys_initcall loads other
252 * dependant drivers/modules.
253 */
254 pmctwiled_setup();
255#endif
256}
diff --git a/arch/mips/pmc-sierra/msp71xx/msp_time.c b/arch/mips/pmc-sierra/msp71xx/msp_time.c
new file mode 100644
index 000000000000..2a2beac5a4f8
--- /dev/null
+++ b/arch/mips/pmc-sierra/msp71xx/msp_time.c
@@ -0,0 +1,94 @@
1/*
2 * Setting up the clock on MSP SOCs. No RTC typically.
3 *
4 * Carsten Langgaard, carstenl@mips.com
5 * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
6 *
7 * ########################################################################
8 *
9 * This program is free software; you can distribute it and/or modify it
10 * under the terms of the GNU General Public License (Version 2) as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 * for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
21 *
22 * ########################################################################
23 */
24
25#include <linux/init.h>
26#include <linux/kernel_stat.h>
27#include <linux/sched.h>
28#include <linux/spinlock.h>
29#include <linux/module.h>
30#include <linux/ptrace.h>
31
32#include <asm/mipsregs.h>
33#include <asm/time.h>
34
35#include <msp_prom.h>
36#include <msp_int.h>
37#include <msp_regs.h>
38
39void __init msp_timer_init(void)
40{
41 char *endp, *s;
42 unsigned long cpu_rate = 0;
43
44 if (cpu_rate == 0) {
45 s = prom_getenv("clkfreqhz");
46 cpu_rate = simple_strtoul(s, &endp, 10);
47 if (endp != NULL && *endp != 0) {
48 printk(KERN_ERR
49 "Clock rate in Hz parse error: %s\n", s);
50 cpu_rate = 0;
51 }
52 }
53
54 if (cpu_rate == 0) {
55 s = prom_getenv("clkfreq");
56 cpu_rate = 1000 * simple_strtoul(s, &endp, 10);
57 if (endp != NULL && *endp != 0) {
58 printk(KERN_ERR
59 "Clock rate in MHz parse error: %s\n", s);
60 cpu_rate = 0;
61 }
62 }
63
64 if (cpu_rate == 0) {
65#if defined(CONFIG_PMC_MSP7120_EVAL) \
66 || defined(CONFIG_PMC_MSP7120_GW)
67 cpu_rate = 400000000;
68#elif defined(CONFIG_PMC_MSP7120_FPGA)
69 cpu_rate = 25000000;
70#else
71 cpu_rate = 150000000;
72#endif
73 printk(KERN_ERR
74 "Failed to determine CPU clock rate, "
75 "assuming %ld hz ...\n", cpu_rate);
76 }
77
78 printk(KERN_WARNING "Clock rate set to %ld\n", cpu_rate);
79
80 /* timer frequency is 1/2 clock rate */
81 mips_hpt_frequency = cpu_rate/2;
82}
83
84
85void __init plat_timer_setup(struct irqaction *irq)
86{
87#ifdef CONFIG_IRQ_MSP_CIC
88 /* we are using the vpe0 counter for timer interrupts */
89 setup_irq(MSP_INT_VPE0_TIMER, irq);
90#else
91 /* we are using the mips counter for timer interrupts */
92 setup_irq(MSP_INT_TIMER, irq);
93#endif
94}
diff --git a/arch/mips/pmc-sierra/msp71xx/msp_usb.c b/arch/mips/pmc-sierra/msp71xx/msp_usb.c
new file mode 100644
index 000000000000..21f9c70b6923
--- /dev/null
+++ b/arch/mips/pmc-sierra/msp71xx/msp_usb.c
@@ -0,0 +1,150 @@
1/*
2 * The setup file for USB related hardware on PMC-Sierra MSP processors.
3 *
4 * Copyright 2006-2007 PMC-Sierra, Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 *
11 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
12 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
14 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
15 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
16 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
17 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
18 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
19 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
20 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
21 *
22 * You should have received a copy of the GNU General Public License along
23 * with this program; if not, write to the Free Software Foundation, Inc.,
24 * 675 Mass Ave, Cambridge, MA 02139, USA.
25 */
26
27#include <linux/dma-mapping.h>
28#include <linux/init.h>
29#include <linux/ioport.h>
30#include <linux/platform_device.h>
31
32#include <asm/mipsregs.h>
33
34#include <msp_regs.h>
35#include <msp_int.h>
36#include <msp_prom.h>
37
38#if defined(CONFIG_USB_EHCI_HCD)
39static struct resource msp_usbhost_resources [] = {
40 [0] = {
41 .start = MSP_USB_BASE_START,
42 .end = MSP_USB_BASE_END,
43 .flags = IORESOURCE_MEM,
44 },
45 [1] = {
46 .start = MSP_INT_USB,
47 .end = MSP_INT_USB,
48 .flags = IORESOURCE_IRQ,
49 },
50};
51
52static u64 msp_usbhost_dma_mask = DMA_32BIT_MASK;
53
54static struct platform_device msp_usbhost_device = {
55 .name = "pmcmsp-ehci",
56 .id = 0,
57 .dev = {
58 .dma_mask = &msp_usbhost_dma_mask,
59 .coherent_dma_mask = DMA_32BIT_MASK,
60 },
61 .num_resources = ARRAY_SIZE (msp_usbhost_resources),
62 .resource = msp_usbhost_resources,
63};
64#endif /* CONFIG_USB_EHCI_HCD */
65
66#if defined(CONFIG_USB_GADGET)
67static struct resource msp_usbdev_resources [] = {
68 [0] = {
69 .start = MSP_USB_BASE,
70 .end = MSP_USB_BASE_END,
71 .flags = IORESOURCE_MEM,
72 },
73 [1] = {
74 .start = MSP_INT_USB,
75 .end = MSP_INT_USB,
76 .flags = IORESOURCE_IRQ,
77 },
78};
79
80static u64 msp_usbdev_dma_mask = DMA_32BIT_MASK;
81
82static struct platform_device msp_usbdev_device = {
83 .name = "msp71xx_udc",
84 .id = 0,
85 .dev = {
86 .dma_mask = &msp_usbdev_dma_mask,
87 .coherent_dma_mask = DMA_32BIT_MASK,
88 },
89 .num_resources = ARRAY_SIZE (msp_usbdev_resources),
90 .resource = msp_usbdev_resources,
91};
92#endif /* CONFIG_USB_GADGET */
93
94#if defined(CONFIG_USB_EHCI_HCD) || defined(CONFIG_USB_GADGET)
95static struct platform_device *msp_devs[1];
96#endif
97
98
99static int __init msp_usb_setup(void)
100{
101#if defined(CONFIG_USB_EHCI_HCD) || defined(CONFIG_USB_GADGET)
102 char *strp;
103 char envstr[32];
104 unsigned int val = 0;
105 int result = 0;
106
107 /*
108 * construct environment name usbmode
109 * set usbmode <host/device> as pmon environment var
110 */
111 snprintf((char *)&envstr[0], sizeof(envstr), "usbmode");
112
113#if defined(CONFIG_USB_EHCI_HCD)
114 /* default to host mode */
115 val = 1;
116#endif
117
118 /* get environment string */
119 strp = prom_getenv((char *)&envstr[0]);
120 if (strp) {
121 if (!strcmp(strp, "device"))
122 val = 0;
123 }
124
125 if (val) {
126#if defined(CONFIG_USB_EHCI_HCD)
127 /* get host mode device */
128 msp_devs[0] = &msp_usbhost_device;
129 ppfinit("platform add USB HOST done %s.\n",
130 msp_devs[0]->name);
131
132 result = platform_add_devices(msp_devs, ARRAY_SIZE (msp_devs));
133#endif /* CONFIG_USB_EHCI_HCD */
134 }
135#if defined(CONFIG_USB_GADGET)
136 else {
137 /* get device mode structure */
138 msp_devs[0] = &msp_usbdev_device;
139 ppfinit("platform add USB DEVICE done %s.\n",
140 msp_devs[0]->name);
141
142 result = platform_add_devices(msp_devs, ARRAY_SIZE (msp_devs));
143 }
144#endif /* CONFIG_USB_GADGET */
145#endif /* CONFIG_USB_EHCI_HCD || CONFIG_USB_GADGET */
146
147 return result;
148}
149
150subsys_initcall(msp_usb_setup);
diff --git a/arch/mips/pmc-sierra/yosemite/smp.c b/arch/mips/pmc-sierra/yosemite/smp.c
index 305491e74dbe..d83c4ada14f3 100644
--- a/arch/mips/pmc-sierra/yosemite/smp.c
+++ b/arch/mips/pmc-sierra/yosemite/smp.c
@@ -77,7 +77,7 @@ void __init plat_prepare_cpus(unsigned int max_cpus)
77 * stack so the first thing we do is throw away that stuff and load useful 77 * stack so the first thing we do is throw away that stuff and load useful
78 * values into the registers ... 78 * values into the registers ...
79 */ 79 */
80void prom_boot_secondary(int cpu, struct task_struct *idle) 80void __init prom_boot_secondary(int cpu, struct task_struct *idle)
81{ 81{
82 unsigned long gp = (unsigned long) task_thread_info(idle); 82 unsigned long gp = (unsigned long) task_thread_info(idle);
83 unsigned long sp = __KSTK_TOS(idle); 83 unsigned long sp = __KSTK_TOS(idle);
diff --git a/arch/mips/sgi-ip22/ip22-reset.c b/arch/mips/sgi-ip22/ip22-reset.c
index 66df5ac8f089..63afd7e44428 100644
--- a/arch/mips/sgi-ip22/ip22-reset.c
+++ b/arch/mips/sgi-ip22/ip22-reset.c
@@ -46,7 +46,7 @@ static struct timer_list power_timer, blink_timer, debounce_timer, volume_timer;
46 46
47static int machine_state; 47static int machine_state;
48 48
49static void ATTRIB_NORET sgi_machine_power_off(void) 49static void __noreturn sgi_machine_power_off(void)
50{ 50{
51 unsigned int tmp; 51 unsigned int tmp;
52 52
@@ -68,7 +68,7 @@ static void ATTRIB_NORET sgi_machine_power_off(void)
68 } 68 }
69} 69}
70 70
71static void ATTRIB_NORET sgi_machine_restart(char *command) 71static void __noreturn sgi_machine_restart(char *command)
72{ 72{
73 if (machine_state & MACHINE_SHUTTING_DOWN) 73 if (machine_state & MACHINE_SHUTTING_DOWN)
74 sgi_machine_power_off(); 74 sgi_machine_power_off();
@@ -76,7 +76,7 @@ static void ATTRIB_NORET sgi_machine_restart(char *command)
76 while (1); 76 while (1);
77} 77}
78 78
79static void ATTRIB_NORET sgi_machine_halt(void) 79static void __noreturn sgi_machine_halt(void)
80{ 80{
81 if (machine_state & MACHINE_SHUTTING_DOWN) 81 if (machine_state & MACHINE_SHUTTING_DOWN)
82 sgi_machine_power_off(); 82 sgi_machine_power_off();
diff --git a/arch/mips/sgi-ip27/ip27-berr.c b/arch/mips/sgi-ip27/ip27-berr.c
index ce907eda221b..123141ab21a2 100644
--- a/arch/mips/sgi-ip27/ip27-berr.c
+++ b/arch/mips/sgi-ip27/ip27-berr.c
@@ -21,7 +21,6 @@
21#include <asm/traps.h> 21#include <asm/traps.h>
22#include <asm/uaccess.h> 22#include <asm/uaccess.h>
23 23
24extern void dump_tlb_addr(unsigned long addr);
25extern void dump_tlb_all(void); 24extern void dump_tlb_all(void);
26 25
27static void dump_hub_information(unsigned long errst0, unsigned long errst1) 26static void dump_hub_information(unsigned long errst0, unsigned long errst1)
diff --git a/arch/mips/sgi-ip32/ip32-platform.c b/arch/mips/sgi-ip32/ip32-platform.c
index 120b15932caf..ba3697ee7ff6 100644
--- a/arch/mips/sgi-ip32/ip32-platform.c
+++ b/arch/mips/sgi-ip32/ip32-platform.c
@@ -1,5 +1,53 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2007 Ralf Baechle (ralf@linux-mips.org)
7 */
8#include <linux/module.h>
1#include <linux/init.h> 9#include <linux/init.h>
2#include <linux/platform_device.h> 10#include <linux/platform_device.h>
11#include <linux/serial_8250.h>
12
13#include <asm/ip32/mace.h>
14#include <asm/ip32/ip32_ints.h>
15
16/*
17 * .iobase isn't a constant (in the sense of C) so we fill it in at runtime.
18 */
19#define MACE_PORT(int) \
20{ \
21 .irq = int, \
22 .uartclk = 1843200, \
23 .iotype = UPIO_MEM, \
24 .flags = UPF_SKIP_TEST, \
25 .regshift = 8, \
26}
27
28static struct plat_serial8250_port uart8250_data[] = {
29 MACE_PORT(MACEISA_SERIAL1_IRQ),
30 MACE_PORT(MACEISA_SERIAL2_IRQ),
31 { },
32};
33
34static struct platform_device uart8250_device = {
35 .name = "serial8250",
36 .id = PLAT8250_DEV_PLATFORM,
37 .dev = {
38 .platform_data = uart8250_data,
39 },
40};
41
42static int __init uart8250_init(void)
43{
44 uart8250_data[0].iobase = (unsigned long) &mace->isa.serial1;
45 uart8250_data[1].iobase = (unsigned long) &mace->isa.serial1;
46
47 return platform_device_register(&uart8250_device);
48}
49
50device_initcall(uart8250_init);
3 51
4static __init int meth_devinit(void) 52static __init int meth_devinit(void)
5{ 53{
@@ -18,3 +66,7 @@ static __init int meth_devinit(void)
18} 66}
19 67
20device_initcall(meth_devinit); 68device_initcall(meth_devinit);
69
70MODULE_AUTHOR("Ralf Baechle <ralf@linux-mips.org>");
71MODULE_LICENSE("GPL");
72MODULE_DESCRIPTION("8250 UART probe driver for SGI IP32 aka O2");
diff --git a/arch/mips/sgi-ip32/ip32-setup.c b/arch/mips/sgi-ip32/ip32-setup.c
index 57708fe28bd7..bbba066cb405 100644
--- a/arch/mips/sgi-ip32/ip32-setup.c
+++ b/arch/mips/sgi-ip32/ip32-setup.c
@@ -62,12 +62,6 @@ static inline void str2eaddr(unsigned char *ea, unsigned char *str)
62} 62}
63#endif 63#endif
64 64
65#ifdef CONFIG_SERIAL_8250
66#include <linux/tty.h>
67#include <linux/serial.h>
68#include <linux/serial_core.h>
69#endif /* CONFIG_SERIAL_8250 */
70
71/* An arbitrary time; this can be decreased if reliability looks good */ 65/* An arbitrary time; this can be decreased if reliability looks good */
72#define WAIT_MS 10 66#define WAIT_MS 10
73 67
@@ -96,36 +90,6 @@ void __init plat_mem_setup(void)
96 90
97 board_time_init = ip32_time_init; 91 board_time_init = ip32_time_init;
98 92
99#ifdef CONFIG_SERIAL_8250
100 {
101 static struct uart_port o2_serial[2];
102
103 memset(o2_serial, 0, sizeof(o2_serial));
104 o2_serial[0].type = PORT_16550A;
105 o2_serial[0].line = 0;
106 o2_serial[0].irq = MACEISA_SERIAL1_IRQ;
107 o2_serial[0].flags = UPF_SKIP_TEST;
108 o2_serial[0].uartclk = 1843200;
109 o2_serial[0].iotype = UPIO_MEM;
110 o2_serial[0].membase = (char *)&mace->isa.serial1;
111 o2_serial[0].fifosize = 14;
112 /* How much to shift register offset by. Each UART register
113 * is replicated over 256 byte space */
114 o2_serial[0].regshift = 8;
115 o2_serial[1].type = PORT_16550A;
116 o2_serial[1].line = 1;
117 o2_serial[1].irq = MACEISA_SERIAL2_IRQ;
118 o2_serial[1].flags = UPF_SKIP_TEST;
119 o2_serial[1].uartclk = 1843200;
120 o2_serial[1].iotype = UPIO_MEM;
121 o2_serial[1].membase = (char *)&mace->isa.serial2;
122 o2_serial[1].fifosize = 14;
123 o2_serial[1].regshift = 8;
124
125 early_serial_setup(&o2_serial[0]);
126 early_serial_setup(&o2_serial[1]);
127 }
128#endif
129#ifdef CONFIG_SGI_O2MACE_ETH 93#ifdef CONFIG_SGI_O2MACE_ETH
130 { 94 {
131 char *mac = ArcGetEnvironmentVariable("eaddr"); 95 char *mac = ArcGetEnvironmentVariable("eaddr");
diff --git a/arch/mips/sibyte/cfe/setup.c b/arch/mips/sibyte/cfe/setup.c
index ae4a92c3e529..51898dd1304a 100644
--- a/arch/mips/sibyte/cfe/setup.c
+++ b/arch/mips/sibyte/cfe/setup.c
@@ -62,7 +62,7 @@ extern unsigned long initrd_start, initrd_end;
62extern int kgdb_port; 62extern int kgdb_port;
63#endif 63#endif
64 64
65static void ATTRIB_NORET cfe_linux_exit(void *arg) 65static void __noreturn cfe_linux_exit(void *arg)
66{ 66{
67 int warm = *(int *)arg; 67 int warm = *(int *)arg;
68 68
@@ -83,14 +83,14 @@ static void ATTRIB_NORET cfe_linux_exit(void *arg)
83 while (1); 83 while (1);
84} 84}
85 85
86static void ATTRIB_NORET cfe_linux_restart(char *command) 86static void __noreturn cfe_linux_restart(char *command)
87{ 87{
88 static const int zero; 88 static const int zero;
89 89
90 cfe_linux_exit((void *)&zero); 90 cfe_linux_exit((void *)&zero);
91} 91}
92 92
93static void ATTRIB_NORET cfe_linux_halt(void) 93static void __noreturn cfe_linux_halt(void)
94{ 94{
95 static const int one = 1; 95 static const int one = 1;
96 96
diff --git a/arch/mips/sni/Makefile b/arch/mips/sni/Makefile
index e5777b7e2bc9..471418e4f446 100644
--- a/arch/mips/sni/Makefile
+++ b/arch/mips/sni/Makefile
@@ -2,5 +2,5 @@
2# Makefile for the SNI specific part of the kernel 2# Makefile for the SNI specific part of the kernel
3# 3#
4 4
5obj-y += irq.o reset.o setup.o ds1216.o a20r.o rm200.o pcimt.o pcit.o time.o 5obj-y += irq.o reset.o setup.o a20r.o rm200.o pcimt.o pcit.o time.o
6obj-$(CONFIG_CPU_BIG_ENDIAN) += sniprom.o 6obj-$(CONFIG_CPU_BIG_ENDIAN) += sniprom.o
diff --git a/arch/mips/sni/a20r.c b/arch/mips/sni/a20r.c
index 31ab80f1befa..6850a29defcd 100644
--- a/arch/mips/sni/a20r.c
+++ b/arch/mips/sni/a20r.c
@@ -15,7 +15,6 @@
15 15
16#include <asm/sni.h> 16#include <asm/sni.h>
17#include <asm/time.h> 17#include <asm/time.h>
18#include <asm/ds1216.h>
19 18
20#define PORT(_base,_irq) \ 19#define PORT(_base,_irq) \
21 { \ 20 { \
@@ -40,20 +39,34 @@ static struct platform_device a20r_serial8250_device = {
40 }, 39 },
41}; 40};
42 41
42static struct resource a20r_ds1216_rsrc[] = {
43 {
44 .start = 0x1c081ffc,
45 .end = 0x1c081fff,
46 .flags = IORESOURCE_MEM
47 }
48};
49
50static struct platform_device a20r_ds1216_device = {
51 .name = "rtc-ds1216",
52 .num_resources = ARRAY_SIZE(a20r_ds1216_rsrc),
53 .resource = a20r_ds1216_rsrc
54};
55
43static struct resource snirm_82596_rsrc[] = { 56static struct resource snirm_82596_rsrc[] = {
44 { 57 {
45 .start = 0xb8000000, 58 .start = 0x18000000,
46 .end = 0xb8000004, 59 .end = 0x18000004,
47 .flags = IORESOURCE_MEM 60 .flags = IORESOURCE_MEM
48 }, 61 },
49 { 62 {
50 .start = 0xb8010000, 63 .start = 0x18010000,
51 .end = 0xb8010004, 64 .end = 0x18010004,
52 .flags = IORESOURCE_MEM 65 .flags = IORESOURCE_MEM
53 }, 66 },
54 { 67 {
55 .start = 0xbff00000, 68 .start = 0x1ff00000,
56 .end = 0xbff00020, 69 .end = 0x1ff00020,
57 .flags = IORESOURCE_MEM 70 .flags = IORESOURCE_MEM
58 }, 71 },
59 { 72 {
@@ -205,8 +218,7 @@ void __init sni_a20r_irq_init(void)
205 218
206void sni_a20r_init(void) 219void sni_a20r_init(void)
207{ 220{
208 ds1216_base = (volatile unsigned char *) SNI_DS1216_A20R_BASE; 221 /* FIXME, remove if not needed */
209 rtc_mips_get_time = ds1216_get_cmos_time;
210} 222}
211 223
212static int __init snirm_a20r_setup_devinit(void) 224static int __init snirm_a20r_setup_devinit(void)
@@ -218,6 +230,7 @@ static int __init snirm_a20r_setup_devinit(void)
218 platform_device_register(&snirm_53c710_pdev); 230 platform_device_register(&snirm_53c710_pdev);
219 platform_device_register(&sc26xx_pdev); 231 platform_device_register(&sc26xx_pdev);
220 platform_device_register(&a20r_serial8250_device); 232 platform_device_register(&a20r_serial8250_device);
233 platform_device_register(&a20r_ds1216_device);
221 break; 234 break;
222 } 235 }
223 236
diff --git a/arch/mips/sni/ds1216.c b/arch/mips/sni/ds1216.c
deleted file mode 100644
index 1d92732c14f1..000000000000
--- a/arch/mips/sni/ds1216.c
+++ /dev/null
@@ -1,81 +0,0 @@
1
2#include <linux/bcd.h>
3#include <linux/time.h>
4
5#include <asm/ds1216.h>
6
7volatile unsigned char *ds1216_base;
8
9/*
10 * Read the 64 bit we'd like to have - It a series
11 * of 64 bits showing up in the LSB of the base register.
12 *
13 */
14static unsigned char *ds1216_read(void)
15{
16 static unsigned char rdbuf[8];
17 unsigned char c;
18 int i, j;
19
20 for (i = 0; i < 8; i++) {
21 c = 0x0;
22 for (j = 0; j < 8; j++) {
23 c |= (*ds1216_base & 0x1) << j;
24 }
25 rdbuf[i] = c;
26 }
27
28 return rdbuf;
29}
30
31static void ds1216_switch_ds_to_clock(void)
32{
33 unsigned char magic[] = {
34 0xc5, 0x3a, 0xa3, 0x5c, 0xc5, 0x3a, 0xa3, 0x5c
35 };
36 int i,j,c;
37
38 /* Reset magic pointer */
39 c = *ds1216_base;
40
41 /* Write 64 bit magic to DS1216 */
42 for (i = 0; i < 8; i++) {
43 c = magic[i];
44 for (j = 0; j < 8; j++) {
45 *ds1216_base = c;
46 c = c >> 1;
47 }
48 }
49}
50
51unsigned long ds1216_get_cmos_time(void)
52{
53 unsigned char *rdbuf;
54 unsigned int year, month, date, hour, min, sec;
55
56 ds1216_switch_ds_to_clock();
57 rdbuf = ds1216_read();
58
59 sec = BCD2BIN(DS1216_SEC(rdbuf));
60 min = BCD2BIN(DS1216_MIN(rdbuf));
61 hour = BCD2BIN(DS1216_HOUR(rdbuf));
62 date = BCD2BIN(DS1216_DATE(rdbuf));
63 month = BCD2BIN(DS1216_MONTH(rdbuf));
64 year = BCD2BIN(DS1216_YEAR(rdbuf));
65
66 if (DS1216_1224(rdbuf) && DS1216_AMPM(rdbuf))
67 hour+=12;
68
69 if (year < 70)
70 year += 2000;
71 else
72 year += 1900;
73
74 return mktime(year, month, date, hour, min, sec);
75}
76
77int ds1216_set_rtc_mmss(unsigned long nowtime)
78{
79 printk("ds1216_set_rtc_mmss called but not implemented\n");
80 return -1;
81}
diff --git a/arch/mips/sni/pcimt.c b/arch/mips/sni/pcimt.c
index 97b234361b4d..44b1ae62aa4a 100644
--- a/arch/mips/sni/pcimt.c
+++ b/arch/mips/sni/pcimt.c
@@ -14,7 +14,6 @@
14#include <linux/pci.h> 14#include <linux/pci.h>
15#include <linux/serial_8250.h> 15#include <linux/serial_8250.h>
16 16
17#include <asm/mc146818-time.h>
18#include <asm/sni.h> 17#include <asm/sni.h>
19#include <asm/time.h> 18#include <asm/time.h>
20#include <asm/i8259.h> 19#include <asm/i8259.h>
@@ -90,6 +89,26 @@ static struct platform_device pcimt_serial8250_device = {
90 }, 89 },
91}; 90};
92 91
92static struct resource pcimt_cmos_rsrc[] = {
93 {
94 .start = 0x70,
95 .end = 0x71,
96 .flags = IORESOURCE_IO
97 },
98 {
99 .start = 8,
100 .end = 8,
101 .flags = IORESOURCE_IRQ
102 }
103};
104
105static struct platform_device pcimt_cmos_device = {
106 .name = "rtc_cmos",
107 .num_resources = ARRAY_SIZE(pcimt_cmos_rsrc),
108 .resource = pcimt_cmos_rsrc
109};
110
111
93static struct resource sni_io_resource = { 112static struct resource sni_io_resource = {
94 .start = 0x00000000UL, 113 .start = 0x00000000UL,
95 .end = 0x03bfffffUL, 114 .end = 0x03bfffffUL,
@@ -290,12 +309,10 @@ void __init sni_pcimt_irq_init(void)
290 change_c0_status(ST0_IM, IE_IRQ1|IE_IRQ3); 309 change_c0_status(ST0_IM, IE_IRQ1|IE_IRQ3);
291} 310}
292 311
293void sni_pcimt_init(void) 312void __init sni_pcimt_init(void)
294{ 313{
295 sni_pcimt_detect(); 314 sni_pcimt_detect();
296 sni_pcimt_sc_init(); 315 sni_pcimt_sc_init();
297 rtc_mips_get_time = mc146818_get_cmos_time;
298 rtc_mips_set_time = mc146818_set_rtc_mmss;
299 board_time_init = sni_cpu_time_init; 316 board_time_init = sni_cpu_time_init;
300 ioport_resource.end = sni_io_resource.end; 317 ioport_resource.end = sni_io_resource.end;
301#ifdef CONFIG_PCI 318#ifdef CONFIG_PCI
@@ -312,6 +329,7 @@ static int __init snirm_pcimt_setup_devinit(void)
312 case SNI_BRD_PCI_DESKTOP: 329 case SNI_BRD_PCI_DESKTOP:
313 case SNI_BRD_PCI_MTOWER_CPLUS: 330 case SNI_BRD_PCI_MTOWER_CPLUS:
314 platform_device_register(&pcimt_serial8250_device); 331 platform_device_register(&pcimt_serial8250_device);
332 platform_device_register(&pcimt_cmos_device);
315 break; 333 break;
316 } 334 }
317 335
diff --git a/arch/mips/sni/pcit.c b/arch/mips/sni/pcit.c
index 00d151f4d121..2480c478dcbd 100644
--- a/arch/mips/sni/pcit.c
+++ b/arch/mips/sni/pcit.c
@@ -13,7 +13,6 @@
13#include <linux/pci.h> 13#include <linux/pci.h>
14#include <linux/serial_8250.h> 14#include <linux/serial_8250.h>
15 15
16#include <asm/mc146818-time.h>
17#include <asm/sni.h> 16#include <asm/sni.h>
18#include <asm/time.h> 17#include <asm/time.h>
19#include <asm/irq_cpu.h> 18#include <asm/irq_cpu.h>
@@ -58,6 +57,25 @@ static struct platform_device pcit_cplus_serial8250_device = {
58 }, 57 },
59}; 58};
60 59
60static struct resource pcit_cmos_rsrc[] = {
61 {
62 .start = 0x70,
63 .end = 0x71,
64 .flags = IORESOURCE_IO
65 },
66 {
67 .start = 8,
68 .end = 8,
69 .flags = IORESOURCE_IRQ
70 }
71};
72
73static struct platform_device pcit_cmos_device = {
74 .name = "rtc_cmos",
75 .num_resources = ARRAY_SIZE(pcit_cmos_rsrc),
76 .resource = pcit_cmos_rsrc
77};
78
61static struct resource sni_io_resource = { 79static struct resource sni_io_resource = {
62 .start = 0x00000000UL, 80 .start = 0x00000000UL,
63 .end = 0x03bfffffUL, 81 .end = 0x03bfffffUL,
@@ -243,10 +261,8 @@ void __init sni_pcit_cplus_irq_init(void)
243 setup_irq (MIPS_CPU_IRQ_BASE + 3, &sni_isa_irq); 261 setup_irq (MIPS_CPU_IRQ_BASE + 3, &sni_isa_irq);
244} 262}
245 263
246void sni_pcit_init(void) 264void __init sni_pcit_init(void)
247{ 265{
248 rtc_mips_get_time = mc146818_get_cmos_time;
249 rtc_mips_set_time = mc146818_set_rtc_mmss;
250 board_time_init = sni_cpu_time_init; 266 board_time_init = sni_cpu_time_init;
251 ioport_resource.end = sni_io_resource.end; 267 ioport_resource.end = sni_io_resource.end;
252#ifdef CONFIG_PCI 268#ifdef CONFIG_PCI
@@ -261,10 +277,12 @@ static int __init snirm_pcit_setup_devinit(void)
261 switch (sni_brd_type) { 277 switch (sni_brd_type) {
262 case SNI_BRD_PCI_TOWER: 278 case SNI_BRD_PCI_TOWER:
263 platform_device_register(&pcit_serial8250_device); 279 platform_device_register(&pcit_serial8250_device);
280 platform_device_register(&pcit_cmos_device);
264 break; 281 break;
265 282
266 case SNI_BRD_PCI_TOWER_CPLUS: 283 case SNI_BRD_PCI_TOWER_CPLUS:
267 platform_device_register(&pcit_cplus_serial8250_device); 284 platform_device_register(&pcit_cplus_serial8250_device);
285 platform_device_register(&pcit_cmos_device);
268 break; 286 break;
269 } 287 }
270 return 0; 288 return 0;
diff --git a/arch/mips/sni/rm200.c b/arch/mips/sni/rm200.c
index b82ff129f5ea..4bfda020fdc7 100644
--- a/arch/mips/sni/rm200.c
+++ b/arch/mips/sni/rm200.c
@@ -15,7 +15,6 @@
15 15
16#include <asm/sni.h> 16#include <asm/sni.h>
17#include <asm/time.h> 17#include <asm/time.h>
18#include <asm/ds1216.h>
19#include <asm/irq_cpu.h> 18#include <asm/irq_cpu.h>
20 19
21#define PORT(_base,_irq) \ 20#define PORT(_base,_irq) \
@@ -41,20 +40,34 @@ static struct platform_device rm200_serial8250_device = {
41 }, 40 },
42}; 41};
43 42
43static struct resource rm200_ds1216_rsrc[] = {
44 {
45 .start = 0x1cd41ffc,
46 .end = 0x1cd41fff,
47 .flags = IORESOURCE_MEM
48 }
49};
50
51static struct platform_device rm200_ds1216_device = {
52 .name = "rtc-ds1216",
53 .num_resources = ARRAY_SIZE(rm200_ds1216_rsrc),
54 .resource = rm200_ds1216_rsrc
55};
56
44static struct resource snirm_82596_rm200_rsrc[] = { 57static struct resource snirm_82596_rm200_rsrc[] = {
45 { 58 {
46 .start = 0xb8000000, 59 .start = 0x18000000,
47 .end = 0xb80fffff, 60 .end = 0x180fffff,
48 .flags = IORESOURCE_MEM 61 .flags = IORESOURCE_MEM
49 }, 62 },
50 { 63 {
51 .start = 0xbb000000, 64 .start = 0x1b000000,
52 .end = 0xbb000004, 65 .end = 0x1b000004,
53 .flags = IORESOURCE_MEM 66 .flags = IORESOURCE_MEM
54 }, 67 },
55 { 68 {
56 .start = 0xbff00000, 69 .start = 0x1ff00000,
57 .end = 0xbff00020, 70 .end = 0x1ff00020,
58 .flags = IORESOURCE_MEM 71 .flags = IORESOURCE_MEM
59 }, 72 },
60 { 73 {
@@ -96,6 +109,7 @@ static int __init snirm_setup_devinit(void)
96{ 109{
97 if (sni_brd_type == SNI_BRD_RM200) { 110 if (sni_brd_type == SNI_BRD_RM200) {
98 platform_device_register(&rm200_serial8250_device); 111 platform_device_register(&rm200_serial8250_device);
112 platform_device_register(&rm200_ds1216_device);
99 platform_device_register(&snirm_82596_rm200_pdev); 113 platform_device_register(&snirm_82596_rm200_pdev);
100 platform_device_register(&snirm_53c710_rm200_pdev); 114 platform_device_register(&snirm_53c710_rm200_pdev);
101 } 115 }
@@ -176,11 +190,9 @@ void __init sni_rm200_irq_init(void)
176 setup_irq (SNI_RM200_INT_START + 0, &sni_isa_irq); 190 setup_irq (SNI_RM200_INT_START + 0, &sni_isa_irq);
177} 191}
178 192
179void sni_rm200_init(void) 193void __init sni_rm200_init(void)
180{ 194{
181 set_io_port_base(SNI_PORT_BASE + 0x02000000); 195 set_io_port_base(SNI_PORT_BASE + 0x02000000);
182 ioport_resource.end += 0x02000000; 196 ioport_resource.end += 0x02000000;
183 ds1216_base = (volatile unsigned char *) SNI_DS1216_RM200_BASE;
184 rtc_mips_get_time = ds1216_get_cmos_time;
185 board_time_init = sni_cpu_time_init; 197 board_time_init = sni_cpu_time_init;
186} 198}
diff --git a/arch/mips/sni/sniprom.c b/arch/mips/sni/sniprom.c
index 643366eb854a..00a03a6e8f58 100644
--- a/arch/mips/sni/sniprom.c
+++ b/arch/mips/sni/sniprom.c
@@ -146,7 +146,10 @@ static void __init sni_console_setup(void)
146 } 146 }
147 if (baud) 147 if (baud)
148 strcpy(options, baud); 148 strcpy(options, baud);
149 add_preferred_console("ttyS", port, baud ? options : NULL); 149 if (strncmp (cdev, "tty552", 6) == 0)
150 add_preferred_console("ttyS", port, baud ? options : NULL);
151 else
152 add_preferred_console("ttySC", port, baud ? options : NULL);
150 } 153 }
151} 154}
152 155
diff --git a/arch/mips/tx4938/common/Makefile b/arch/mips/tx4938/common/Makefile
index 2033ae77f632..83cda518f204 100644
--- a/arch/mips/tx4938/common/Makefile
+++ b/arch/mips/tx4938/common/Makefile
@@ -6,6 +6,6 @@
6# unless it's something special (ie not a .c file). 6# unless it's something special (ie not a .c file).
7# 7#
8 8
9obj-y += prom.o setup.o irq.o rtc_rx5c348.o 9obj-y += prom.o setup.o irq.o
10obj-$(CONFIG_KGDB) += dbgio.o 10obj-$(CONFIG_KGDB) += dbgio.o
11 11
diff --git a/arch/mips/tx4938/common/rtc_rx5c348.c b/arch/mips/tx4938/common/rtc_rx5c348.c
deleted file mode 100644
index 07f782fc0725..000000000000
--- a/arch/mips/tx4938/common/rtc_rx5c348.c
+++ /dev/null
@@ -1,192 +0,0 @@
1/*
2 * RTC routines for RICOH Rx5C348 SPI chip.
3 * Copyright (C) 2000-2001 Toshiba Corporation
4 *
5 * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
6 * terms of the GNU General Public License version 2. This program is
7 * licensed "as is" without any warranty of any kind, whether express
8 * or implied.
9 *
10 * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
11 */
12#include <linux/init.h>
13#include <linux/kernel.h>
14#include <linux/string.h>
15#include <linux/rtc.h>
16#include <linux/time.h>
17#include <linux/bcd.h>
18#include <asm/time.h>
19#include <asm/tx4938/spi.h>
20
21#define EPOCH 2000
22
23/* registers */
24#define Rx5C348_REG_SECOND 0
25#define Rx5C348_REG_MINUTE 1
26#define Rx5C348_REG_HOUR 2
27#define Rx5C348_REG_WEEK 3
28#define Rx5C348_REG_DAY 4
29#define Rx5C348_REG_MONTH 5
30#define Rx5C348_REG_YEAR 6
31#define Rx5C348_REG_ADJUST 7
32#define Rx5C348_REG_ALARM_W_MIN 8
33#define Rx5C348_REG_ALARM_W_HOUR 9
34#define Rx5C348_REG_ALARM_W_WEEK 10
35#define Rx5C348_REG_ALARM_D_MIN 11
36#define Rx5C348_REG_ALARM_D_HOUR 12
37#define Rx5C348_REG_CTL1 14
38#define Rx5C348_REG_CTL2 15
39
40/* register bits */
41#define Rx5C348_BIT_PM 0x20 /* REG_HOUR */
42#define Rx5C348_BIT_Y2K 0x80 /* REG_MONTH */
43#define Rx5C348_BIT_24H 0x20 /* REG_CTL1 */
44#define Rx5C348_BIT_XSTP 0x10 /* REG_CTL2 */
45
46/* commands */
47#define Rx5C348_CMD_W(addr) (((addr) << 4) | 0x08) /* single write */
48#define Rx5C348_CMD_R(addr) (((addr) << 4) | 0x0c) /* single read */
49#define Rx5C348_CMD_MW(addr) (((addr) << 4) | 0x00) /* burst write */
50#define Rx5C348_CMD_MR(addr) (((addr) << 4) | 0x04) /* burst read */
51
52static struct spi_dev_desc srtc_dev_desc = {
53 .baud = 1000000, /* 1.0Mbps @ Vdd 2.0V */
54 .tcss = 31,
55 .tcsh = 1,
56 .tcsr = 62,
57 /* 31us for Tcss (62us for Tcsr) is required for carry operation) */
58 .byteorder = 1, /* MSB-First */
59 .polarity = 0, /* High-Active */
60 .phase = 1, /* Shift-Then-Sample */
61
62};
63static int srtc_chipid;
64static int srtc_24h;
65
66static inline int
67spi_rtc_io(unsigned char *inbuf, unsigned char *outbuf, unsigned int count)
68{
69 unsigned char *inbufs[1], *outbufs[1];
70 unsigned int incounts[2], outcounts[2];
71 inbufs[0] = inbuf;
72 incounts[0] = count;
73 incounts[1] = 0;
74 outbufs[0] = outbuf;
75 outcounts[0] = count;
76 outcounts[1] = 0;
77 return txx9_spi_io(srtc_chipid, &srtc_dev_desc,
78 inbufs, incounts, outbufs, outcounts, 0);
79}
80
81/* RTC-dependent code for time.c */
82
83static int
84rtc_rx5c348_set_time(unsigned long t)
85{
86 unsigned char inbuf[8];
87 struct rtc_time tm;
88 u8 year, month, day, hour, minute, second, century;
89
90 /* convert */
91 to_tm(t, &tm);
92
93 year = tm.tm_year % 100;
94 month = tm.tm_mon+1; /* tm_mon starts from 0 to 11 */
95 day = tm.tm_mday;
96 hour = tm.tm_hour;
97 minute = tm.tm_min;
98 second = tm.tm_sec;
99 century = tm.tm_year / 100;
100
101 inbuf[0] = Rx5C348_CMD_MW(Rx5C348_REG_SECOND);
102 BIN_TO_BCD(second);
103 inbuf[1] = second;
104 BIN_TO_BCD(minute);
105 inbuf[2] = minute;
106
107 if (srtc_24h) {
108 BIN_TO_BCD(hour);
109 inbuf[3] = hour;
110 } else {
111 /* hour 0 is AM12, noon is PM12 */
112 inbuf[3] = 0;
113 if (hour >= 12)
114 inbuf[3] = Rx5C348_BIT_PM;
115 hour = (hour + 11) % 12 + 1;
116 BIN_TO_BCD(hour);
117 inbuf[3] |= hour;
118 }
119 inbuf[4] = 0; /* ignore week */
120 BIN_TO_BCD(day);
121 inbuf[5] = day;
122 BIN_TO_BCD(month);
123 inbuf[6] = month;
124 if (century >= 20)
125 inbuf[6] |= Rx5C348_BIT_Y2K;
126 BIN_TO_BCD(year);
127 inbuf[7] = year;
128 /* write in one transfer to avoid data inconsistency */
129 return spi_rtc_io(inbuf, NULL, 8);
130}
131
132static unsigned long
133rtc_rx5c348_get_time(void)
134{
135 unsigned char inbuf[8], outbuf[8];
136 unsigned int year, month, day, hour, minute, second;
137
138 inbuf[0] = Rx5C348_CMD_MR(Rx5C348_REG_SECOND);
139 memset(inbuf + 1, 0, 7);
140 /* read in one transfer to avoid data inconsistency */
141 if (spi_rtc_io(inbuf, outbuf, 8))
142 return 0;
143 second = outbuf[1];
144 BCD_TO_BIN(second);
145 minute = outbuf[2];
146 BCD_TO_BIN(minute);
147 if (srtc_24h) {
148 hour = outbuf[3];
149 BCD_TO_BIN(hour);
150 } else {
151 hour = outbuf[3] & ~Rx5C348_BIT_PM;
152 BCD_TO_BIN(hour);
153 hour %= 12;
154 if (outbuf[3] & Rx5C348_BIT_PM)
155 hour += 12;
156 }
157 day = outbuf[5];
158 BCD_TO_BIN(day);
159 month = outbuf[6] & ~Rx5C348_BIT_Y2K;
160 BCD_TO_BIN(month);
161 year = outbuf[7];
162 BCD_TO_BIN(year);
163 year += EPOCH;
164
165 return mktime(year, month, day, hour, minute, second);
166}
167
168void __init
169rtc_rx5c348_init(int chipid)
170{
171 unsigned char inbuf[2], outbuf[2];
172 srtc_chipid = chipid;
173 /* turn on RTC if it is not on */
174 inbuf[0] = Rx5C348_CMD_R(Rx5C348_REG_CTL2);
175 inbuf[1] = 0;
176 spi_rtc_io(inbuf, outbuf, 2);
177 if (outbuf[1] & Rx5C348_BIT_XSTP) {
178 inbuf[0] = Rx5C348_CMD_W(Rx5C348_REG_CTL2);
179 inbuf[1] = 0;
180 spi_rtc_io(inbuf, NULL, 2);
181 }
182
183 inbuf[0] = Rx5C348_CMD_R(Rx5C348_REG_CTL1);
184 inbuf[1] = 0;
185 spi_rtc_io(inbuf, outbuf, 2);
186 if (outbuf[1] & Rx5C348_BIT_24H)
187 srtc_24h = 1;
188
189 /* set the function pointers */
190 rtc_mips_get_time = rtc_rx5c348_get_time;
191 rtc_mips_set_time = rtc_rx5c348_set_time;
192}
diff --git a/arch/mips/tx4938/toshiba_rbtx4938/Makefile b/arch/mips/tx4938/toshiba_rbtx4938/Makefile
index 226941279d75..10c94e62bf5b 100644
--- a/arch/mips/tx4938/toshiba_rbtx4938/Makefile
+++ b/arch/mips/tx4938/toshiba_rbtx4938/Makefile
@@ -6,4 +6,4 @@
6# unless it's something special (ie not a .c file). 6# unless it's something special (ie not a .c file).
7# 7#
8 8
9obj-y += prom.o setup.o irq.o spi_eeprom.o spi_txx9.o 9obj-y += prom.o setup.o irq.o spi_eeprom.o
diff --git a/arch/mips/tx4938/toshiba_rbtx4938/irq.c b/arch/mips/tx4938/toshiba_rbtx4938/irq.c
index 2e96dbb248b1..91aea7aff515 100644
--- a/arch/mips/tx4938/toshiba_rbtx4938/irq.c
+++ b/arch/mips/tx4938/toshiba_rbtx4938/irq.c
@@ -165,8 +165,6 @@ toshiba_rbtx4938_irq_ioc_disable(unsigned int irq)
165 TX4938_RD08(TOSHIBA_RBTX4938_IOC_INTR_ENAB); 165 TX4938_RD08(TOSHIBA_RBTX4938_IOC_INTR_ENAB);
166} 166}
167 167
168extern void __init txx9_spi_irqinit(int irc_irq);
169
170void __init arch_init_irq(void) 168void __init arch_init_irq(void)
171{ 169{
172 extern void tx4938_irq_init(void); 170 extern void tx4938_irq_init(void);
@@ -185,9 +183,5 @@ void __init arch_init_irq(void)
185 /* Onboard 10M Ether: High Active */ 183 /* Onboard 10M Ether: High Active */
186 TX4938_WR(TX4938_MKA(TX4938_IRC_IRDM0), 0x00000040); 184 TX4938_WR(TX4938_MKA(TX4938_IRC_IRDM0), 0x00000040);
187 185
188 if (tx4938_ccfgptr->pcfg & TX4938_PCFG_SPI_SEL) {
189 txx9_spi_irqinit(RBTX4938_IRQ_IRC_SPI);
190 }
191
192 wbflush(); 186 wbflush();
193} 187}
diff --git a/arch/mips/tx4938/toshiba_rbtx4938/setup.c b/arch/mips/tx4938/toshiba_rbtx4938/setup.c
index f5d1ce739fcc..6ed39a5aea72 100644
--- a/arch/mips/tx4938/toshiba_rbtx4938/setup.c
+++ b/arch/mips/tx4938/toshiba_rbtx4938/setup.c
@@ -14,13 +14,13 @@
14#include <linux/init.h> 14#include <linux/init.h>
15#include <linux/types.h> 15#include <linux/types.h>
16#include <linux/ioport.h> 16#include <linux/ioport.h>
17#include <linux/proc_fs.h>
18#include <linux/delay.h> 17#include <linux/delay.h>
19#include <linux/interrupt.h> 18#include <linux/interrupt.h>
20#include <linux/console.h> 19#include <linux/console.h>
21#include <linux/pci.h> 20#include <linux/pci.h>
22#include <linux/pm.h> 21#include <linux/pm.h>
23#include <linux/platform_device.h> 22#include <linux/platform_device.h>
23#include <linux/clk.h>
24 24
25#include <asm/wbflush.h> 25#include <asm/wbflush.h>
26#include <asm/reboot.h> 26#include <asm/reboot.h>
@@ -35,6 +35,9 @@
35#include <linux/serial.h> 35#include <linux/serial.h>
36#include <linux/serial_core.h> 36#include <linux/serial_core.h>
37#endif 37#endif
38#include <linux/spi/spi.h>
39#include <asm/tx4938/spi.h>
40#include <asm/gpio.h>
38 41
39extern void rbtx4938_time_init(void) __init; 42extern void rbtx4938_time_init(void) __init;
40extern char * __init prom_getcmdline(void); 43extern char * __init prom_getcmdline(void);
@@ -349,7 +352,7 @@ static struct pci_dev *fake_pci_dev(struct pci_controller *hose,
349 static struct pci_dev dev; 352 static struct pci_dev dev;
350 static struct pci_bus bus; 353 static struct pci_bus bus;
351 354
352 dev.sysdata = (void *)hose; 355 dev.sysdata = bus.sysdata = hose;
353 dev.devfn = devfn; 356 dev.devfn = devfn;
354 bus.number = busnr; 357 bus.number = busnr;
355 bus.ops = hose->pci_ops; 358 bus.ops = hose->pci_ops;
@@ -382,8 +385,10 @@ int txboard_pci66_check(struct pci_controller *hose, int top_bus, int current_bu
382 printk("PCI: Checking 66MHz capabilities...\n"); 385 printk("PCI: Checking 66MHz capabilities...\n");
383 386
384 for (pci_devfn=devfn_start; pci_devfn<devfn_stop; pci_devfn++) { 387 for (pci_devfn=devfn_start; pci_devfn<devfn_stop; pci_devfn++) {
385 early_read_config_word(hose, top_bus, current_bus, pci_devfn, 388 if (early_read_config_word(hose, top_bus, current_bus,
386 PCI_VENDOR_ID, &vid); 389 pci_devfn, PCI_VENDOR_ID,
390 &vid) != PCIBIOS_SUCCESSFUL)
391 continue;
387 392
388 if (vid == 0xffff) continue; 393 if (vid == 0xffff) continue;
389 394
@@ -460,7 +465,6 @@ static int __init tx4938_pcibios_init(void)
460 int extarb = !(tx4938_ccfgptr->ccfg & TX4938_CCFG_PCIXARB); 465 int extarb = !(tx4938_ccfgptr->ccfg & TX4938_CCFG_PCIXARB);
461 466
462 PCIBIOS_MIN_IO = 0x00001000UL; 467 PCIBIOS_MIN_IO = 0x00001000UL;
463 PCIBIOS_MIN_MEM = 0x01000000UL;
464 468
465 mem_base[0] = txboard_request_phys_region_shrink(&mem_size[0]); 469 mem_base[0] = txboard_request_phys_region_shrink(&mem_size[0]);
466 io_base[0] = txboard_request_phys_region_shrink(&io_size[0]); 470 io_base[0] = txboard_request_phys_region_shrink(&io_size[0]);
@@ -574,82 +578,43 @@ arch_initcall(tx4938_pcibios_init);
574#define SEEPROM3_CS 1 /* IOC */ 578#define SEEPROM3_CS 1 /* IOC */
575#define SRTC_CS 2 /* IOC */ 579#define SRTC_CS 2 /* IOC */
576 580
577static int rbtx4938_spi_cs_func(int chipid, int on)
578{
579 unsigned char bit;
580 switch (chipid) {
581 case RBTX4938_SEEPROM1_CHIPID:
582 if (on)
583 tx4938_pioptr->dout &= ~(1 << SEEPROM1_CS);
584 else
585 tx4938_pioptr->dout |= (1 << SEEPROM1_CS);
586 return 0;
587 break;
588 case RBTX4938_SEEPROM2_CHIPID:
589 bit = (1 << SEEPROM2_CS);
590 break;
591 case RBTX4938_SEEPROM3_CHIPID:
592 bit = (1 << SEEPROM3_CS);
593 break;
594 case RBTX4938_SRTC_CHIPID:
595 bit = (1 << SRTC_CS);
596 break;
597 default:
598 return -ENODEV;
599 }
600 /* bit1,2,4 are low active, bit3 is high active */
601 *rbtx4938_spics_ptr =
602 (*rbtx4938_spics_ptr & ~bit) |
603 ((on ? (bit ^ 0x0b) : ~(bit ^ 0x0b)) & bit);
604 return 0;
605}
606
607#ifdef CONFIG_PCI 581#ifdef CONFIG_PCI
608extern int spi_eeprom_read(int chipid, int address, unsigned char *buf, int len); 582static int __init rbtx4938_ethaddr_init(void)
609
610int rbtx4938_get_tx4938_ethaddr(struct pci_dev *dev, unsigned char *addr)
611{ 583{
612 struct pci_controller *channel = (struct pci_controller *)dev->bus->sysdata; 584 unsigned char dat[17];
613 static unsigned char dat[17]; 585 unsigned char sum;
614 static int read_dat = 0; 586 int i;
615 int ch = 0;
616 587
617 if (channel != &tx4938_pci_controller[1]) 588 /* 0-3: "MAC\0", 4-9:eth0, 10-15:eth1, 16:sum */
618 return -ENODEV; 589 if (spi_eeprom_read(SEEPROM1_CS, 0, dat, sizeof(dat))) {
619 /* TX4938 PCIC1 */ 590 printk(KERN_ERR "seeprom: read error.\n");
620 switch (PCI_SLOT(dev->devfn)) {
621 case TX4938_PCIC_IDSEL_AD_TO_SLOT(31):
622 ch = 0;
623 break;
624 case TX4938_PCIC_IDSEL_AD_TO_SLOT(30):
625 ch = 1;
626 break;
627 default:
628 return -ENODEV; 591 return -ENODEV;
592 } else {
593 if (strcmp(dat, "MAC") != 0)
594 printk(KERN_WARNING "seeprom: bad signature.\n");
595 for (i = 0, sum = 0; i < sizeof(dat); i++)
596 sum += dat[i];
597 if (sum)
598 printk(KERN_WARNING "seeprom: bad checksum.\n");
629 } 599 }
630 if (!read_dat) { 600 for (i = 0; i < 2; i++) {
631 unsigned char sum; 601 unsigned int slot = TX4938_PCIC_IDSEL_AD_TO_SLOT(31 - i);
632 int i; 602 unsigned int id = (1 << 8) | PCI_DEVFN(slot, 0); /* bus 1 */
633 read_dat = 1; 603 struct platform_device *pdev;
634 /* 0-3: "MAC\0", 4-9:eth0, 10-15:eth1, 16:sum */ 604 if (!(tx4938_ccfgptr->pcfg &
635 if (spi_eeprom_read(RBTX4938_SEEPROM1_CHIPID, 605 (i ? TX4938_PCFG_ETH1_SEL : TX4938_PCFG_ETH0_SEL)))
636 0, dat, sizeof(dat))) { 606 continue;
637 printk(KERN_ERR "seeprom: read error.\n"); 607 pdev = platform_device_alloc("tc35815-mac", id);
638 } else { 608 if (!pdev ||
639 if (strcmp(dat, "MAC") != 0) 609 platform_device_add_data(pdev, &dat[4 + 6 * i], 6) ||
640 printk(KERN_WARNING "seeprom: bad signature.\n"); 610 platform_device_add(pdev))
641 for (i = 0, sum = 0; i < sizeof(dat); i++) 611 platform_device_put(pdev);
642 sum += dat[i];
643 if (sum)
644 printk(KERN_WARNING "seeprom: bad checksum.\n");
645 }
646 } 612 }
647 memcpy(addr, &dat[4 + 6 * ch], 6);
648 return 0; 613 return 0;
649} 614}
615device_initcall(rbtx4938_ethaddr_init);
650#endif /* CONFIG_PCI */ 616#endif /* CONFIG_PCI */
651 617
652extern void __init txx9_spi_init(unsigned long base, int (*cs_func)(int chipid, int on));
653static void __init rbtx4938_spi_setup(void) 618static void __init rbtx4938_spi_setup(void)
654{ 619{
655 /* set SPI_SEL */ 620 /* set SPI_SEL */
@@ -657,7 +622,6 @@ static void __init rbtx4938_spi_setup(void)
657 /* chip selects for SPI devices */ 622 /* chip selects for SPI devices */
658 tx4938_pioptr->dout |= (1 << SEEPROM1_CS); 623 tx4938_pioptr->dout |= (1 << SEEPROM1_CS);
659 tx4938_pioptr->dir |= (1 << SEEPROM1_CS); 624 tx4938_pioptr->dir |= (1 << SEEPROM1_CS);
660 txx9_spi_init(TX4938_SPI_REG, rbtx4938_spi_cs_func);
661} 625}
662 626
663static struct resource rbtx4938_fpga_resource; 627static struct resource rbtx4938_fpga_resource;
@@ -896,10 +860,8 @@ void tx4938_report_pcic_status(void)
896/* We use onchip r4k counter or TMR timer as our system wide timer 860/* We use onchip r4k counter or TMR timer as our system wide timer
897 * interrupt running at 100HZ. */ 861 * interrupt running at 100HZ. */
898 862
899extern void __init rtc_rx5c348_init(int chipid);
900void __init rbtx4938_time_init(void) 863void __init rbtx4938_time_init(void)
901{ 864{
902 rtc_rx5c348_init(RBTX4938_SRTC_CHIPID);
903 mips_hpt_frequency = txx9_cpu_clock / 2; 865 mips_hpt_frequency = txx9_cpu_clock / 2;
904} 866}
905 867
@@ -1016,29 +978,6 @@ void __init toshiba_rbtx4938_setup(void)
1016 *rbtx4938_dipsw_ptr, *rbtx4938_bdipsw_ptr); 978 *rbtx4938_dipsw_ptr, *rbtx4938_bdipsw_ptr);
1017} 979}
1018 980
1019#ifdef CONFIG_PROC_FS
1020extern void spi_eeprom_proc_create(struct proc_dir_entry *dir, int chipid);
1021static int __init tx4938_spi_proc_setup(void)
1022{
1023 struct proc_dir_entry *tx4938_spi_eeprom_dir;
1024
1025 tx4938_spi_eeprom_dir = proc_mkdir("spi_eeprom", 0);
1026
1027 if (!tx4938_spi_eeprom_dir)
1028 return -ENOMEM;
1029
1030 /* don't allow user access to RBTX4938_SEEPROM1_CHIPID
1031 * as it contains eth0 and eth1 MAC addresses
1032 */
1033 spi_eeprom_proc_create(tx4938_spi_eeprom_dir, RBTX4938_SEEPROM2_CHIPID);
1034 spi_eeprom_proc_create(tx4938_spi_eeprom_dir, RBTX4938_SEEPROM3_CHIPID);
1035
1036 return 0;
1037}
1038
1039__initcall(tx4938_spi_proc_setup);
1040#endif
1041
1042static int __init rbtx4938_ne_init(void) 981static int __init rbtx4938_ne_init(void)
1043{ 982{
1044 struct resource res[] = { 983 struct resource res[] = {
@@ -1057,3 +996,176 @@ static int __init rbtx4938_ne_init(void)
1057 return IS_ERR(dev) ? PTR_ERR(dev) : 0; 996 return IS_ERR(dev) ? PTR_ERR(dev) : 0;
1058} 997}
1059device_initcall(rbtx4938_ne_init); 998device_initcall(rbtx4938_ne_init);
999
1000/* GPIO support */
1001
1002static DEFINE_SPINLOCK(rbtx4938_spi_gpio_lock);
1003
1004static void rbtx4938_spi_gpio_set(unsigned gpio, int value)
1005{
1006 u8 val;
1007 unsigned long flags;
1008 gpio -= 16;
1009 spin_lock_irqsave(&rbtx4938_spi_gpio_lock, flags);
1010 val = *rbtx4938_spics_ptr;
1011 if (value)
1012 val |= 1 << gpio;
1013 else
1014 val &= ~(1 << gpio);
1015 *rbtx4938_spics_ptr = val;
1016 mmiowb();
1017 spin_unlock_irqrestore(&rbtx4938_spi_gpio_lock, flags);
1018}
1019
1020static int rbtx4938_spi_gpio_dir_out(unsigned gpio, int value)
1021{
1022 rbtx4938_spi_gpio_set(gpio, value);
1023 return 0;
1024}
1025
1026static DEFINE_SPINLOCK(tx4938_gpio_lock);
1027
1028static int tx4938_gpio_get(unsigned gpio)
1029{
1030 return tx4938_pioptr->din & (1 << gpio);
1031}
1032
1033static void tx4938_gpio_set_raw(unsigned gpio, int value)
1034{
1035 u32 val;
1036 val = tx4938_pioptr->dout;
1037 if (value)
1038 val |= 1 << gpio;
1039 else
1040 val &= ~(1 << gpio);
1041 tx4938_pioptr->dout = val;
1042}
1043
1044static void tx4938_gpio_set(unsigned gpio, int value)
1045{
1046 unsigned long flags;
1047 spin_lock_irqsave(&tx4938_gpio_lock, flags);
1048 tx4938_gpio_set_raw(gpio, value);
1049 mmiowb();
1050 spin_unlock_irqrestore(&tx4938_gpio_lock, flags);
1051}
1052
1053static int tx4938_gpio_dir_in(unsigned gpio)
1054{
1055 spin_lock_irq(&tx4938_gpio_lock);
1056 tx4938_pioptr->dir &= ~(1 << gpio);
1057 mmiowb();
1058 spin_unlock_irq(&tx4938_gpio_lock);
1059 return 0;
1060}
1061
1062static int tx4938_gpio_dir_out(unsigned int gpio, int value)
1063{
1064 spin_lock_irq(&tx4938_gpio_lock);
1065 tx4938_gpio_set_raw(gpio, value);
1066 tx4938_pioptr->dir |= 1 << gpio;
1067 mmiowb();
1068 spin_unlock_irq(&tx4938_gpio_lock);
1069 return 0;
1070}
1071
1072int gpio_direction_input(unsigned gpio)
1073{
1074 if (gpio < 16)
1075 return tx4938_gpio_dir_in(gpio);
1076 return -EINVAL;
1077}
1078
1079int gpio_direction_output(unsigned gpio, int value)
1080{
1081 if (gpio < 16)
1082 return tx4938_gpio_dir_out(gpio, value);
1083 if (gpio < 16 + 3)
1084 return rbtx4938_spi_gpio_dir_out(gpio, value);
1085 return -EINVAL;
1086}
1087
1088int gpio_get_value(unsigned gpio)
1089{
1090 if (gpio < 16)
1091 return tx4938_gpio_get(gpio);
1092 return 0;
1093}
1094
1095void gpio_set_value(unsigned gpio, int value)
1096{
1097 if (gpio < 16)
1098 tx4938_gpio_set(gpio, value);
1099 else
1100 rbtx4938_spi_gpio_set(gpio, value);
1101}
1102
1103/* SPI support */
1104
1105static void __init txx9_spi_init(unsigned long base, int irq)
1106{
1107 struct resource res[] = {
1108 {
1109 .start = base,
1110 .end = base + 0x20 - 1,
1111 .flags = IORESOURCE_MEM,
1112 .parent = &tx4938_reg_resource,
1113 }, {
1114 .start = irq,
1115 .flags = IORESOURCE_IRQ,
1116 },
1117 };
1118 platform_device_register_simple("txx9spi", 0,
1119 res, ARRAY_SIZE(res));
1120}
1121
1122static int __init rbtx4938_spi_init(void)
1123{
1124 struct spi_board_info srtc_info = {
1125 .modalias = "rs5c348",
1126 .max_speed_hz = 1000000, /* 1.0Mbps @ Vdd 2.0V */
1127 .bus_num = 0,
1128 .chip_select = 16 + SRTC_CS,
1129 /* Mode 1 (High-Active, Shift-Then-Sample), High Avtive CS */
1130 .mode = SPI_MODE_1 | SPI_CS_HIGH,
1131 };
1132 spi_register_board_info(&srtc_info, 1);
1133 spi_eeprom_register(SEEPROM1_CS);
1134 spi_eeprom_register(16 + SEEPROM2_CS);
1135 spi_eeprom_register(16 + SEEPROM3_CS);
1136 txx9_spi_init(TX4938_SPI_REG & 0xfffffffffULL, RBTX4938_IRQ_IRC_SPI);
1137 return 0;
1138}
1139arch_initcall(rbtx4938_spi_init);
1140
1141/* Minimum CLK support */
1142
1143struct clk *clk_get(struct device *dev, const char *id)
1144{
1145 if (!strcmp(id, "spi-baseclk"))
1146 return (struct clk *)(txx9_gbus_clock / 2 / 4);
1147 return ERR_PTR(-ENOENT);
1148}
1149EXPORT_SYMBOL(clk_get);
1150
1151int clk_enable(struct clk *clk)
1152{
1153 return 0;
1154}
1155EXPORT_SYMBOL(clk_enable);
1156
1157void clk_disable(struct clk *clk)
1158{
1159}
1160EXPORT_SYMBOL(clk_disable);
1161
1162unsigned long clk_get_rate(struct clk *clk)
1163{
1164 return (unsigned long)clk;
1165}
1166EXPORT_SYMBOL(clk_get_rate);
1167
1168void clk_put(struct clk *clk)
1169{
1170}
1171EXPORT_SYMBOL(clk_put);
diff --git a/arch/mips/tx4938/toshiba_rbtx4938/spi_eeprom.c b/arch/mips/tx4938/toshiba_rbtx4938/spi_eeprom.c
index 89596e62f909..4d6b4ade5e8c 100644
--- a/arch/mips/tx4938/toshiba_rbtx4938/spi_eeprom.c
+++ b/arch/mips/tx4938/toshiba_rbtx4938/spi_eeprom.c
@@ -10,209 +10,90 @@
10 * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com) 10 * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
11 */ 11 */
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/delay.h> 13#include <linux/device.h>
14#include <linux/proc_fs.h> 14#include <linux/spi/spi.h>
15#include <linux/spinlock.h> 15#include <linux/spi/eeprom.h>
16#include <asm/tx4938/spi.h> 16#include <asm/tx4938/spi.h>
17#include <asm/tx4938/tx4938.h>
18 17
19/* ATMEL 250x0 instructions */ 18#define AT250X0_PAGE_SIZE 8
20#define ATMEL_WREN 0x06
21#define ATMEL_WRDI 0x04
22#define ATMEL_RDSR 0x05
23#define ATMEL_WRSR 0x01
24#define ATMEL_READ 0x03
25#define ATMEL_WRITE 0x02
26 19
27#define ATMEL_SR_BSY 0x01 20/* register board information for at25 driver */
28#define ATMEL_SR_WEN 0x02 21int __init spi_eeprom_register(int chipid)
29#define ATMEL_SR_BP0 0x04
30#define ATMEL_SR_BP1 0x08
31
32DEFINE_SPINLOCK(spi_eeprom_lock);
33
34static struct spi_dev_desc seeprom_dev_desc = {
35 .baud = 1500000, /* 1.5Mbps */
36 .tcss = 1,
37 .tcsh = 1,
38 .tcsr = 1,
39 .byteorder = 1, /* MSB-First */
40 .polarity = 0, /* High-Active */
41 .phase = 0, /* Sample-Then-Shift */
42
43};
44static inline int
45spi_eeprom_io(int chipid,
46 unsigned char **inbufs, unsigned int *incounts,
47 unsigned char **outbufs, unsigned int *outcounts)
48{
49 return txx9_spi_io(chipid, &seeprom_dev_desc,
50 inbufs, incounts, outbufs, outcounts, 0);
51}
52
53int spi_eeprom_write_enable(int chipid, int enable)
54{ 22{
55 unsigned char inbuf[1]; 23 static struct spi_eeprom eeprom = {
56 unsigned char *inbufs[1]; 24 .name = "at250x0",
57 unsigned int incounts[2]; 25 .byte_len = 128,
58 unsigned long flags; 26 .page_size = AT250X0_PAGE_SIZE,
59 int stat; 27 .flags = EE_ADDR1,
60 inbuf[0] = enable ? ATMEL_WREN : ATMEL_WRDI; 28 };
61 inbufs[0] = inbuf; 29 struct spi_board_info info = {
62 incounts[0] = sizeof(inbuf); 30 .modalias = "at25",
63 incounts[1] = 0; 31 .max_speed_hz = 1500000, /* 1.5Mbps */
64 spin_lock_irqsave(&spi_eeprom_lock, flags); 32 .bus_num = 0,
65 stat = spi_eeprom_io(chipid, inbufs, incounts, NULL, NULL); 33 .chip_select = chipid,
66 spin_unlock_irqrestore(&spi_eeprom_lock, flags); 34 .platform_data = &eeprom,
67 return stat; 35 /* Mode 0: High-Active, Sample-Then-Shift */
68} 36 };
69 37
70static int spi_eeprom_read_status_nolock(int chipid) 38 return spi_register_board_info(&info, 1);
71{
72 unsigned char inbuf[2], outbuf[2];
73 unsigned char *inbufs[1], *outbufs[1];
74 unsigned int incounts[2], outcounts[2];
75 int stat;
76 inbuf[0] = ATMEL_RDSR;
77 inbuf[1] = 0;
78 inbufs[0] = inbuf;
79 incounts[0] = sizeof(inbuf);
80 incounts[1] = 0;
81 outbufs[0] = outbuf;
82 outcounts[0] = sizeof(outbuf);
83 outcounts[1] = 0;
84 stat = spi_eeprom_io(chipid, inbufs, incounts, outbufs, outcounts);
85 if (stat < 0)
86 return stat;
87 return outbuf[1];
88} 39}
89 40
90int spi_eeprom_read_status(int chipid) 41/* simple temporary spi driver to provide early access to seeprom. */
91{
92 unsigned long flags;
93 int stat;
94 spin_lock_irqsave(&spi_eeprom_lock, flags);
95 stat = spi_eeprom_read_status_nolock(chipid);
96 spin_unlock_irqrestore(&spi_eeprom_lock, flags);
97 return stat;
98}
99 42
100int spi_eeprom_read(int chipid, int address, unsigned char *buf, int len) 43static struct read_param {
101{ 44 int chipid;
102 unsigned char inbuf[2]; 45 int address;
103 unsigned char *inbufs[2], *outbufs[2]; 46 unsigned char *buf;
104 unsigned int incounts[2], outcounts[3]; 47 int len;
105 unsigned long flags; 48} *read_param;
106 int stat;
107 inbuf[0] = ATMEL_READ;
108 inbuf[1] = address;
109 inbufs[0] = inbuf;
110 inbufs[1] = NULL;
111 incounts[0] = sizeof(inbuf);
112 incounts[1] = 0;
113 outbufs[0] = NULL;
114 outbufs[1] = buf;
115 outcounts[0] = 2;
116 outcounts[1] = len;
117 outcounts[2] = 0;
118 spin_lock_irqsave(&spi_eeprom_lock, flags);
119 stat = spi_eeprom_io(chipid, inbufs, incounts, outbufs, outcounts);
120 spin_unlock_irqrestore(&spi_eeprom_lock, flags);
121 return stat;
122}
123 49
124int spi_eeprom_write(int chipid, int address, unsigned char *buf, int len) 50static int __init early_seeprom_probe(struct spi_device *spi)
125{ 51{
126 unsigned char inbuf[2]; 52 int stat = 0;
127 unsigned char *inbufs[2]; 53 u8 cmd[2];
128 unsigned int incounts[3]; 54 int len = read_param->len;
129 unsigned long flags; 55 char *buf = read_param->buf;
130 int i, stat; 56 int address = read_param->address;
131 57
132 if (address / 8 != (address + len - 1) / 8) 58 dev_info(&spi->dev, "spiclk %u KHz.\n",
133 return -EINVAL; 59 (spi->max_speed_hz + 500) / 1000);
134 stat = spi_eeprom_write_enable(chipid, 1); 60 if (read_param->chipid != spi->chip_select)
135 if (stat < 0) 61 return -ENODEV;
136 return stat; 62 while (len > 0) {
137 stat = spi_eeprom_read_status(chipid); 63 /* spi_write_then_read can only work with small chunk */
138 if (stat < 0) 64 int c = len < AT250X0_PAGE_SIZE ? len : AT250X0_PAGE_SIZE;
139 return stat; 65 cmd[0] = 0x03; /* AT25_READ */
140 if (!(stat & ATMEL_SR_WEN)) 66 cmd[1] = address;
141 return -EPERM; 67 stat = spi_write_then_read(spi, cmd, sizeof(cmd), buf, c);
142 68 buf += c;
143 inbuf[0] = ATMEL_WRITE; 69 len -= c;
144 inbuf[1] = address; 70 address += c;
145 inbufs[0] = inbuf;
146 inbufs[1] = buf;
147 incounts[0] = sizeof(inbuf);
148 incounts[1] = len;
149 incounts[2] = 0;
150 spin_lock_irqsave(&spi_eeprom_lock, flags);
151 stat = spi_eeprom_io(chipid, inbufs, incounts, NULL, NULL);
152 if (stat < 0)
153 goto unlock_return;
154
155 /* write start. max 10ms */
156 for (i = 10; i > 0; i--) {
157 int stat = spi_eeprom_read_status_nolock(chipid);
158 if (stat < 0)
159 goto unlock_return;
160 if (!(stat & ATMEL_SR_BSY))
161 break;
162 mdelay(1);
163 } 71 }
164 spin_unlock_irqrestore(&spi_eeprom_lock, flags);
165 if (i == 0)
166 return -EIO;
167 return len;
168 unlock_return:
169 spin_unlock_irqrestore(&spi_eeprom_lock, flags);
170 return stat; 72 return stat;
171} 73}
172 74
173#ifdef CONFIG_PROC_FS 75static struct spi_driver early_seeprom_driver __initdata = {
174#define MAX_SIZE 0x80 /* for ATMEL 25010 */ 76 .driver = {
175static int spi_eeprom_read_proc(char *page, char **start, off_t off, 77 .name = "at25",
176 int count, int *eof, void *data) 78 .owner = THIS_MODULE,
177{ 79 },
178 unsigned int size = MAX_SIZE; 80 .probe = early_seeprom_probe,
179 if (spi_eeprom_read((int)data, 0, (unsigned char *)page, size) < 0) 81};
180 size = 0;
181 return size;
182}
183
184static int spi_eeprom_write_proc(struct file *file, const char *buffer,
185 unsigned long count, void *data)
186{
187 unsigned int size = MAX_SIZE;
188 int i;
189 if (file->f_pos >= size)
190 return -EIO;
191 if (file->f_pos + count > size)
192 count = size - file->f_pos;
193 for (i = 0; i < count; i += 8) {
194 int len = count - i < 8 ? count - i : 8;
195 if (spi_eeprom_write((int)data, file->f_pos,
196 (unsigned char *)buffer, len) < 0) {
197 count = -EIO;
198 break;
199 }
200 buffer += len;
201 file->f_pos += len;
202 }
203 return count;
204}
205 82
206__init void spi_eeprom_proc_create(struct proc_dir_entry *dir, int chipid) 83int __init spi_eeprom_read(int chipid, int address,
84 unsigned char *buf, int len)
207{ 85{
208 struct proc_dir_entry *entry; 86 int ret;
209 char name[128]; 87 struct read_param param = {
210 sprintf(name, "seeprom-%d", chipid); 88 .chipid = chipid,
211 entry = create_proc_entry(name, 0600, dir); 89 .address = address,
212 if (entry) { 90 .buf = buf,
213 entry->read_proc = spi_eeprom_read_proc; 91 .len = len
214 entry->write_proc = spi_eeprom_write_proc; 92 };
215 entry->data = (void *)chipid; 93
216 } 94 read_param = &param;
95 ret = spi_register_driver(&early_seeprom_driver);
96 if (!ret)
97 spi_unregister_driver(&early_seeprom_driver);
98 return ret;
217} 99}
218#endif /* CONFIG_PROC_FS */
diff --git a/arch/mips/tx4938/toshiba_rbtx4938/spi_txx9.c b/arch/mips/tx4938/toshiba_rbtx4938/spi_txx9.c
deleted file mode 100644
index 08b20cdfd7b3..000000000000
--- a/arch/mips/tx4938/toshiba_rbtx4938/spi_txx9.c
+++ /dev/null
@@ -1,164 +0,0 @@
1/*
2 * linux/arch/mips/tx4938/toshiba_rbtx4938/spi_txx9.c
3 * Copyright (C) 2000-2001 Toshiba Corporation
4 *
5 * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
6 * terms of the GNU General Public License version 2. This program is
7 * licensed "as is" without any warranty of any kind, whether express
8 * or implied.
9 *
10 * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
11 */
12#include <linux/init.h>
13#include <linux/delay.h>
14#include <linux/errno.h>
15#include <linux/interrupt.h>
16#include <linux/module.h>
17#include <linux/sched.h>
18#include <linux/spinlock.h>
19#include <linux/wait.h>
20#include <asm/tx4938/spi.h>
21#include <asm/tx4938/tx4938.h>
22
23static int (*txx9_spi_cs_func)(int chipid, int on);
24static DEFINE_SPINLOCK(txx9_spi_lock);
25
26extern unsigned int txx9_gbus_clock;
27
28#define SPI_FIFO_SIZE 4
29
30void __init txx9_spi_init(unsigned long base, int (*cs_func)(int chipid, int on))
31{
32 txx9_spi_cs_func = cs_func;
33 /* enter config mode */
34 tx4938_spiptr->mcr = TXx9_SPMCR_CONFIG | TXx9_SPMCR_BCLR;
35}
36
37static DECLARE_WAIT_QUEUE_HEAD(txx9_spi_wait);
38
39static irqreturn_t txx9_spi_interrupt(int irq, void *dev_id)
40{
41 /* disable rx intr */
42 tx4938_spiptr->cr0 &= ~TXx9_SPCR0_RBSIE;
43 wake_up(&txx9_spi_wait);
44
45 return IRQ_HANDLED;
46}
47
48static struct irqaction txx9_spi_action = {
49 .handler = txx9_spi_interrupt,
50 .name = "spi",
51};
52
53void __init txx9_spi_irqinit(int irc_irq)
54{
55 setup_irq(irc_irq, &txx9_spi_action);
56}
57
58int txx9_spi_io(int chipid, struct spi_dev_desc *desc,
59 unsigned char **inbufs, unsigned int *incounts,
60 unsigned char **outbufs, unsigned int *outcounts,
61 int cansleep)
62{
63 unsigned int incount, outcount;
64 unsigned char *inp, *outp;
65 int ret;
66 unsigned long flags;
67
68 spin_lock_irqsave(&txx9_spi_lock, flags);
69 if ((tx4938_spiptr->mcr & TXx9_SPMCR_OPMODE) == TXx9_SPMCR_ACTIVE) {
70 spin_unlock_irqrestore(&txx9_spi_lock, flags);
71 return -EBUSY;
72 }
73 /* enter config mode */
74 tx4938_spiptr->mcr = TXx9_SPMCR_CONFIG | TXx9_SPMCR_BCLR;
75 tx4938_spiptr->cr0 =
76 (desc->byteorder ? TXx9_SPCR0_SBOS : 0) |
77 (desc->polarity ? TXx9_SPCR0_SPOL : 0) |
78 (desc->phase ? TXx9_SPCR0_SPHA : 0) |
79 0x08;
80 tx4938_spiptr->cr1 =
81 (((TXX9_IMCLK + desc->baud) / (2 * desc->baud) - 1) << 8) |
82 0x08 /* 8 bit only */;
83 /* enter active mode */
84 tx4938_spiptr->mcr = TXx9_SPMCR_ACTIVE;
85 spin_unlock_irqrestore(&txx9_spi_lock, flags);
86
87 /* CS ON */
88 if ((ret = txx9_spi_cs_func(chipid, 1)) < 0) {
89 spin_unlock_irqrestore(&txx9_spi_lock, flags);
90 return ret;
91 }
92 udelay(desc->tcss);
93
94 /* do scatter IO */
95 inp = inbufs ? *inbufs : NULL;
96 outp = outbufs ? *outbufs : NULL;
97 incount = 0;
98 outcount = 0;
99 while (1) {
100 unsigned char data;
101 unsigned int count;
102 int i;
103 if (!incount) {
104 incount = incounts ? *incounts++ : 0;
105 inp = (incount && inbufs) ? *inbufs++ : NULL;
106 }
107 if (!outcount) {
108 outcount = outcounts ? *outcounts++ : 0;
109 outp = (outcount && outbufs) ? *outbufs++ : NULL;
110 }
111 if (!inp && !outp)
112 break;
113 count = SPI_FIFO_SIZE;
114 if (incount)
115 count = min(count, incount);
116 if (outcount)
117 count = min(count, outcount);
118
119 /* now tx must be idle... */
120 while (!(tx4938_spiptr->sr & TXx9_SPSR_SIDLE))
121 ;
122
123 tx4938_spiptr->cr0 =
124 (tx4938_spiptr->cr0 & ~TXx9_SPCR0_RXIFL_MASK) |
125 ((count - 1) << 12);
126 if (cansleep) {
127 /* enable rx intr */
128 tx4938_spiptr->cr0 |= TXx9_SPCR0_RBSIE;
129 }
130 /* send */
131 for (i = 0; i < count; i++)
132 tx4938_spiptr->dr = inp ? *inp++ : 0;
133 /* wait all rx data */
134 if (cansleep) {
135 wait_event(txx9_spi_wait,
136 tx4938_spiptr->sr & TXx9_SPSR_SRRDY);
137 } else {
138 while (!(tx4938_spiptr->sr & TXx9_SPSR_RBSI))
139 ;
140 }
141 /* receive */
142 for (i = 0; i < count; i++) {
143 data = tx4938_spiptr->dr;
144 if (outp)
145 *outp++ = data;
146 }
147 if (incount)
148 incount -= count;
149 if (outcount)
150 outcount -= count;
151 }
152
153 /* CS OFF */
154 udelay(desc->tcsh);
155 txx9_spi_cs_func(chipid, 0);
156 udelay(desc->tcsr);
157
158 spin_lock_irqsave(&txx9_spi_lock, flags);
159 /* enter config mode */
160 tx4938_spiptr->mcr = TXx9_SPMCR_CONFIG | TXx9_SPMCR_BCLR;
161 spin_unlock_irqrestore(&txx9_spi_lock, flags);
162
163 return 0;
164}
diff --git a/arch/s390/crypto/crypt_s390.h b/arch/s390/crypto/crypt_s390.h
index 2775d2618332..95f5160df27f 100644
--- a/arch/s390/crypto/crypt_s390.h
+++ b/arch/s390/crypto/crypt_s390.h
@@ -24,7 +24,7 @@
24#define CRYPT_S390_PRIORITY 300 24#define CRYPT_S390_PRIORITY 300
25#define CRYPT_S390_COMPOSITE_PRIORITY 400 25#define CRYPT_S390_COMPOSITE_PRIORITY 400
26 26
27/* s930 cryptographic operations */ 27/* s390 cryptographic operations */
28enum crypt_s390_operations { 28enum crypt_s390_operations {
29 CRYPT_S390_KM = 0x0100, 29 CRYPT_S390_KM = 0x0100,
30 CRYPT_S390_KMC = 0x0200, 30 CRYPT_S390_KMC = 0x0200,
diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c
index 50538e545618..e6289ee74ecd 100644
--- a/arch/s390/kernel/early.c
+++ b/arch/s390/kernel/early.c
@@ -171,37 +171,6 @@ static inline int memory_fast_detect(void)
171} 171}
172#endif 172#endif
173 173
174#define ADDR2G (1UL << 31)
175
176static noinline __init unsigned long sclp_memory_detect(void)
177{
178 struct sclp_readinfo_sccb *sccb;
179 unsigned long long memsize;
180
181 sccb = &s390_readinfo_sccb;
182
183 if (sccb->header.response_code != 0x10)
184 return 0;
185
186 if (sccb->rnsize)
187 memsize = sccb->rnsize << 20;
188 else
189 memsize = sccb->rnsize2 << 20;
190 if (sccb->rnmax)
191 memsize *= sccb->rnmax;
192 else
193 memsize *= sccb->rnmax2;
194#ifndef CONFIG_64BIT
195 /*
196 * Can't deal with more than 2G in 31 bit addressing mode, so
197 * limit the value in order to avoid strange side effects.
198 */
199 if (memsize > ADDR2G)
200 memsize = ADDR2G;
201#endif
202 return (unsigned long) memsize;
203}
204
205static inline __init unsigned long __tprot(unsigned long addr) 174static inline __init unsigned long __tprot(unsigned long addr)
206{ 175{
207 int cc = -1; 176 int cc = -1;
@@ -218,6 +187,7 @@ static inline __init unsigned long __tprot(unsigned long addr)
218 187
219/* Checking memory in 128KB increments. */ 188/* Checking memory in 128KB increments. */
220#define CHUNK_INCR (1UL << 17) 189#define CHUNK_INCR (1UL << 17)
190#define ADDR2G (1UL << 31)
221 191
222static noinline __init void find_memory_chunks(unsigned long memsize) 192static noinline __init void find_memory_chunks(unsigned long memsize)
223{ 193{
@@ -293,7 +263,7 @@ static noinline __init void setup_lowcore_early(void)
293 */ 263 */
294void __init startup_init(void) 264void __init startup_init(void)
295{ 265{
296 unsigned long memsize; 266 unsigned long long memsize;
297 267
298 ipl_save_parameters(); 268 ipl_save_parameters();
299 clear_bss_section(); 269 clear_bss_section();
@@ -305,8 +275,17 @@ void __init startup_init(void)
305 sort_main_extable(); 275 sort_main_extable();
306 setup_lowcore_early(); 276 setup_lowcore_early();
307 sclp_readinfo_early(); 277 sclp_readinfo_early();
278 sclp_facilities_detect();
308 memsize = sclp_memory_detect(); 279 memsize = sclp_memory_detect();
280#ifndef CONFIG_64BIT
281 /*
282 * Can't deal with more than 2G in 31 bit addressing mode, so
283 * limit the value in order to avoid strange side effects.
284 */
285 if (memsize > ADDR2G)
286 memsize = ADDR2G;
287#endif
309 if (memory_fast_detect() < 0) 288 if (memory_fast_detect() < 0)
310 find_memory_chunks(memsize); 289 find_memory_chunks((unsigned long) memsize);
311 lockdep_on(); 290 lockdep_on();
312} 291}
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
index 6234c6978a1f..bc7ff3658c3d 100644
--- a/arch/s390/kernel/entry.S
+++ b/arch/s390/kernel/entry.S
@@ -107,6 +107,11 @@ STACK_SIZE = 1 << STACK_SHIFT
107 l %r13,__LC_SVC_NEW_PSW+4 # load &system_call to %r13 107 l %r13,__LC_SVC_NEW_PSW+4 # load &system_call to %r13
108 .endm 108 .endm
109 109
110 .macro SAVE_ALL_SVC psworg,savearea
111 la %r12,\psworg
112 l %r15,__LC_KERNEL_STACK # problem state -> load ksp
113 .endm
114
110 .macro SAVE_ALL_SYNC psworg,savearea 115 .macro SAVE_ALL_SYNC psworg,savearea
111 la %r12,\psworg 116 la %r12,\psworg
112 tm \psworg+1,0x01 # test problem state bit 117 tm \psworg+1,0x01 # test problem state bit
@@ -218,7 +223,7 @@ system_call:
218 STORE_TIMER __LC_SYNC_ENTER_TIMER 223 STORE_TIMER __LC_SYNC_ENTER_TIMER
219sysc_saveall: 224sysc_saveall:
220 SAVE_ALL_BASE __LC_SAVE_AREA 225 SAVE_ALL_BASE __LC_SAVE_AREA
221 SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA 226 SAVE_ALL_SVC __LC_SVC_OLD_PSW,__LC_SAVE_AREA
222 CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA 227 CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA
223 lh %r7,0x8a # get svc number from lowcore 228 lh %r7,0x8a # get svc number from lowcore
224#ifdef CONFIG_VIRT_CPU_ACCOUNTING 229#ifdef CONFIG_VIRT_CPU_ACCOUNTING
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S
index 685f11faa4bc..2a7b1304418b 100644
--- a/arch/s390/kernel/entry64.S
+++ b/arch/s390/kernel/entry64.S
@@ -99,6 +99,11 @@ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | _TIF_NEED_RESCHED | \
99 larl %r13,system_call 99 larl %r13,system_call
100 .endm 100 .endm
101 101
102 .macro SAVE_ALL_SVC psworg,savearea
103 la %r12,\psworg
104 lg %r15,__LC_KERNEL_STACK # problem state -> load ksp
105 .endm
106
102 .macro SAVE_ALL_SYNC psworg,savearea 107 .macro SAVE_ALL_SYNC psworg,savearea
103 la %r12,\psworg 108 la %r12,\psworg
104 tm \psworg+1,0x01 # test problem state bit 109 tm \psworg+1,0x01 # test problem state bit
@@ -207,7 +212,7 @@ system_call:
207 STORE_TIMER __LC_SYNC_ENTER_TIMER 212 STORE_TIMER __LC_SYNC_ENTER_TIMER
208sysc_saveall: 213sysc_saveall:
209 SAVE_ALL_BASE __LC_SAVE_AREA 214 SAVE_ALL_BASE __LC_SAVE_AREA
210 SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA 215 SAVE_ALL_SVC __LC_SVC_OLD_PSW,__LC_SAVE_AREA
211 CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA 216 CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA
212 llgh %r7,__LC_SVC_INT_CODE # get svc number from lowcore 217 llgh %r7,__LC_SVC_INT_CODE # get svc number from lowcore
213#ifdef CONFIG_VIRT_CPU_ACCOUNTING 218#ifdef CONFIG_VIRT_CPU_ACCOUNTING
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c
index 367caf92ea78..82b131ddd7ff 100644
--- a/arch/s390/kernel/ipl.c
+++ b/arch/s390/kernel/ipl.c
@@ -25,10 +25,6 @@
25 25
26#define IPL_PARM_BLOCK_VERSION 0 26#define IPL_PARM_BLOCK_VERSION 0
27 27
28#define SCCB_VALID (s390_readinfo_sccb.header.response_code == 0x10)
29#define SCCB_LOADPARM (&s390_readinfo_sccb.loadparm)
30#define SCCB_FLAG (s390_readinfo_sccb.flags)
31
32#define IPL_UNKNOWN_STR "unknown" 28#define IPL_UNKNOWN_STR "unknown"
33#define IPL_CCW_STR "ccw" 29#define IPL_CCW_STR "ccw"
34#define IPL_FCP_STR "fcp" 30#define IPL_FCP_STR "fcp"
@@ -146,6 +142,8 @@ static struct ipl_parameter_block *dump_block_ccw;
146 142
147static enum shutdown_action on_panic_action = SHUTDOWN_STOP; 143static enum shutdown_action on_panic_action = SHUTDOWN_STOP;
148 144
145static struct sclp_ipl_info sclp_ipl_info;
146
149int diag308(unsigned long subcode, void *addr) 147int diag308(unsigned long subcode, void *addr)
150{ 148{
151 register unsigned long _addr asm("0") = (unsigned long) addr; 149 register unsigned long _addr asm("0") = (unsigned long) addr;
@@ -375,9 +373,9 @@ static ssize_t ipl_ccw_loadparm_show(struct kset *kset, char *page)
375{ 373{
376 char loadparm[LOADPARM_LEN + 1] = {}; 374 char loadparm[LOADPARM_LEN + 1] = {};
377 375
378 if (!SCCB_VALID) 376 if (!sclp_ipl_info.is_valid)
379 return sprintf(page, "#unknown#\n"); 377 return sprintf(page, "#unknown#\n");
380 memcpy(loadparm, SCCB_LOADPARM, LOADPARM_LEN); 378 memcpy(loadparm, &sclp_ipl_info.loadparm, LOADPARM_LEN);
381 EBCASC(loadparm, LOADPARM_LEN); 379 EBCASC(loadparm, LOADPARM_LEN);
382 strstrip(loadparm); 380 strstrip(loadparm);
383 return sprintf(page, "%s\n", loadparm); 381 return sprintf(page, "%s\n", loadparm);
@@ -910,9 +908,9 @@ static int __init reipl_ccw_init(void)
910 reipl_block_ccw->hdr.blk0_len = IPL_PARM_BLK0_CCW_LEN; 908 reipl_block_ccw->hdr.blk0_len = IPL_PARM_BLK0_CCW_LEN;
911 reipl_block_ccw->hdr.pbt = DIAG308_IPL_TYPE_CCW; 909 reipl_block_ccw->hdr.pbt = DIAG308_IPL_TYPE_CCW;
912 /* check if read scp info worked and set loadparm */ 910 /* check if read scp info worked and set loadparm */
913 if (SCCB_VALID) 911 if (sclp_ipl_info.is_valid)
914 memcpy(reipl_block_ccw->ipl_info.ccw.load_param, 912 memcpy(reipl_block_ccw->ipl_info.ccw.load_param,
915 SCCB_LOADPARM, LOADPARM_LEN); 913 &sclp_ipl_info.loadparm, LOADPARM_LEN);
916 else 914 else
917 /* read scp info failed: set empty loadparm (EBCDIC blanks) */ 915 /* read scp info failed: set empty loadparm (EBCDIC blanks) */
918 memset(reipl_block_ccw->ipl_info.ccw.load_param, 0x40, 916 memset(reipl_block_ccw->ipl_info.ccw.load_param, 0x40,
@@ -1007,7 +1005,7 @@ static int __init dump_fcp_init(void)
1007{ 1005{
1008 int rc; 1006 int rc;
1009 1007
1010 if(!(SCCB_FLAG & 0x2) || !SCCB_VALID) 1008 if (!sclp_ipl_info.has_dump)
1011 return 0; /* LDIPL DUMP is not installed */ 1009 return 0; /* LDIPL DUMP is not installed */
1012 if (!diag308_set_works) 1010 if (!diag308_set_works)
1013 return 0; 1011 return 0;
@@ -1088,6 +1086,7 @@ static int __init s390_ipl_init(void)
1088{ 1086{
1089 int rc; 1087 int rc;
1090 1088
1089 sclp_get_ipl_info(&sclp_ipl_info);
1091 reipl_probe(); 1090 reipl_probe();
1092 rc = ipl_init(); 1091 rc = ipl_init();
1093 if (rc) 1092 if (rc)
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c
index eb43c3b31269..441975b796fb 100644
--- a/arch/s390/kernel/process.c
+++ b/arch/s390/kernel/process.c
@@ -93,8 +93,8 @@ void do_monitor_call(struct pt_regs *regs, long interruption_code)
93 /* disable monitor call class 0 */ 93 /* disable monitor call class 0 */
94 __ctl_clear_bit(8, 15); 94 __ctl_clear_bit(8, 15);
95 95
96 atomic_notifier_call_chain(&idle_chain, CPU_NOT_IDLE, 96 atomic_notifier_call_chain(&idle_chain, S390_CPU_NOT_IDLE,
97 (void *)(long) smp_processor_id()); 97 (void *)(long) smp_processor_id());
98} 98}
99 99
100extern void s390_handle_mcck(void); 100extern void s390_handle_mcck(void);
@@ -115,7 +115,7 @@ static void default_idle(void)
115 } 115 }
116 116
117 rc = atomic_notifier_call_chain(&idle_chain, 117 rc = atomic_notifier_call_chain(&idle_chain,
118 CPU_IDLE, (void *)(long) cpu); 118 S390_CPU_IDLE, (void *)(long) cpu);
119 if (rc != NOTIFY_OK && rc != NOTIFY_DONE) 119 if (rc != NOTIFY_OK && rc != NOTIFY_DONE)
120 BUG(); 120 BUG();
121 if (rc != NOTIFY_OK) { 121 if (rc != NOTIFY_OK) {
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index 8ff2feaf9b00..182c085ae4dd 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -410,58 +410,40 @@ EXPORT_SYMBOL(smp_ctl_clear_bit);
410unsigned int zfcpdump_prefix_array[NR_CPUS + 1] \ 410unsigned int zfcpdump_prefix_array[NR_CPUS + 1] \
411 __attribute__((__section__(".data"))); 411 __attribute__((__section__(".data")));
412 412
413static void __init smp_get_save_areas(void) 413static void __init smp_get_save_area(unsigned int cpu, unsigned int phy_cpu)
414{ 414{
415 unsigned int cpu, cpu_num, rc;
416 __u16 boot_cpu_addr;
417
418 if (ipl_info.type != IPL_TYPE_FCP_DUMP) 415 if (ipl_info.type != IPL_TYPE_FCP_DUMP)
419 return; 416 return;
420 boot_cpu_addr = S390_lowcore.cpu_data.cpu_addr; 417 if (cpu >= NR_CPUS) {
421 cpu_num = 1; 418 printk(KERN_WARNING "Registers for cpu %i not saved since dump "
422 for (cpu = 0; cpu <= 65535; cpu++) { 419 "kernel was compiled with NR_CPUS=%i\n", cpu, NR_CPUS);
423 if ((u16) cpu == boot_cpu_addr) 420 return;
424 continue;
425 __cpu_logical_map[1] = (__u16) cpu;
426 if (signal_processor(1, sigp_sense) == sigp_not_operational)
427 continue;
428 if (cpu_num >= NR_CPUS) {
429 printk("WARNING: Registers for cpu %i are not "
430 "saved, since dump kernel was compiled with"
431 "NR_CPUS=%i!\n", cpu_num, NR_CPUS);
432 continue;
433 }
434 zfcpdump_save_areas[cpu_num] =
435 alloc_bootmem(sizeof(union save_area));
436 while (1) {
437 rc = signal_processor(1, sigp_stop_and_store_status);
438 if (rc != sigp_busy)
439 break;
440 cpu_relax();
441 }
442 memcpy(zfcpdump_save_areas[cpu_num],
443 (void *)(unsigned long) store_prefix() +
444 SAVE_AREA_BASE, SAVE_AREA_SIZE);
445#ifdef __s390x__
446 /* copy original prefix register */
447 zfcpdump_save_areas[cpu_num]->s390x.pref_reg =
448 zfcpdump_prefix_array[cpu_num];
449#endif
450 cpu_num++;
451 } 421 }
422 zfcpdump_save_areas[cpu] = alloc_bootmem(sizeof(union save_area));
423 __cpu_logical_map[1] = (__u16) phy_cpu;
424 while (signal_processor(1, sigp_stop_and_store_status) == sigp_busy)
425 cpu_relax();
426 memcpy(zfcpdump_save_areas[cpu],
427 (void *)(unsigned long) store_prefix() + SAVE_AREA_BASE,
428 SAVE_AREA_SIZE);
429#ifdef CONFIG_64BIT
430 /* copy original prefix register */
431 zfcpdump_save_areas[cpu]->s390x.pref_reg = zfcpdump_prefix_array[cpu];
432#endif
452} 433}
453 434
454union save_area *zfcpdump_save_areas[NR_CPUS + 1]; 435union save_area *zfcpdump_save_areas[NR_CPUS + 1];
455EXPORT_SYMBOL_GPL(zfcpdump_save_areas); 436EXPORT_SYMBOL_GPL(zfcpdump_save_areas);
456 437
457#else 438#else
458#define smp_get_save_areas() do { } while (0) 439
459#endif 440static inline void smp_get_save_area(unsigned int cpu, unsigned int phy_cpu) { }
441
442#endif /* CONFIG_ZFCPDUMP || CONFIG_ZFCPDUMP_MODULE */
460 443
461/* 444/*
462 * Lets check how many CPUs we have. 445 * Lets check how many CPUs we have.
463 */ 446 */
464
465static unsigned int __init smp_count_cpus(void) 447static unsigned int __init smp_count_cpus(void)
466{ 448{
467 unsigned int cpu, num_cpus; 449 unsigned int cpu, num_cpus;
@@ -470,7 +452,6 @@ static unsigned int __init smp_count_cpus(void)
470 /* 452 /*
471 * cpu 0 is the boot cpu. See smp_prepare_boot_cpu. 453 * cpu 0 is the boot cpu. See smp_prepare_boot_cpu.
472 */ 454 */
473
474 boot_cpu_addr = S390_lowcore.cpu_data.cpu_addr; 455 boot_cpu_addr = S390_lowcore.cpu_data.cpu_addr;
475 current_thread_info()->cpu = 0; 456 current_thread_info()->cpu = 0;
476 num_cpus = 1; 457 num_cpus = 1;
@@ -480,12 +461,11 @@ static unsigned int __init smp_count_cpus(void)
480 __cpu_logical_map[1] = (__u16) cpu; 461 __cpu_logical_map[1] = (__u16) cpu;
481 if (signal_processor(1, sigp_sense) == sigp_not_operational) 462 if (signal_processor(1, sigp_sense) == sigp_not_operational)
482 continue; 463 continue;
464 smp_get_save_area(num_cpus, cpu);
483 num_cpus++; 465 num_cpus++;
484 } 466 }
485
486 printk("Detected %d CPU's\n", (int) num_cpus); 467 printk("Detected %d CPU's\n", (int) num_cpus);
487 printk("Boot cpu address %2X\n", boot_cpu_addr); 468 printk("Boot cpu address %2X\n", boot_cpu_addr);
488
489 return num_cpus; 469 return num_cpus;
490} 470}
491 471
@@ -606,7 +586,6 @@ void __init smp_setup_cpu_possible_map(void)
606{ 586{
607 unsigned int phy_cpus, pos_cpus, cpu; 587 unsigned int phy_cpus, pos_cpus, cpu;
608 588
609 smp_get_save_areas();
610 phy_cpus = smp_count_cpus(); 589 phy_cpus = smp_count_cpus();
611 pos_cpus = min(phy_cpus + additional_cpus, (unsigned int) NR_CPUS); 590 pos_cpus = min(phy_cpus + additional_cpus, (unsigned int) NR_CPUS);
612 591
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
index 9c2872a7cca7..48dae49bc1ec 100644
--- a/arch/s390/kernel/time.c
+++ b/arch/s390/kernel/time.c
@@ -226,10 +226,10 @@ static int nohz_idle_notify(struct notifier_block *self,
226 unsigned long action, void *hcpu) 226 unsigned long action, void *hcpu)
227{ 227{
228 switch (action) { 228 switch (action) {
229 case CPU_IDLE: 229 case S390_CPU_IDLE:
230 stop_hz_timer(); 230 stop_hz_timer();
231 break; 231 break;
232 case CPU_NOT_IDLE: 232 case S390_CPU_NOT_IDLE:
233 start_hz_timer(); 233 start_hz_timer();
234 break; 234 break;
235 } 235 }
diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c
index 1e1a6ee2cac1..b6ed143e8597 100644
--- a/arch/s390/kernel/vtime.c
+++ b/arch/s390/kernel/vtime.c
@@ -545,10 +545,10 @@ static int vtimer_idle_notify(struct notifier_block *self,
545 unsigned long action, void *hcpu) 545 unsigned long action, void *hcpu)
546{ 546{
547 switch (action) { 547 switch (action) {
548 case CPU_IDLE: 548 case S390_CPU_IDLE:
549 stop_cpu_timer(); 549 stop_cpu_timer();
550 break; 550 break;
551 case CPU_NOT_IDLE: 551 case S390_CPU_NOT_IDLE:
552 start_cpu_timer(); 552 start_cpu_timer();
553 break; 553 break;
554 } 554 }
diff --git a/arch/s390/lib/Makefile b/arch/s390/lib/Makefile
index 59aea65ce99f..52084436ab69 100644
--- a/arch/s390/lib/Makefile
+++ b/arch/s390/lib/Makefile
@@ -4,7 +4,7 @@
4 4
5EXTRA_AFLAGS := -traditional 5EXTRA_AFLAGS := -traditional
6 6
7lib-y += delay.o string.o uaccess_std.o uaccess_pt.o qrnnd.o 7lib-y += delay.o string.o uaccess_std.o uaccess_pt.o
8obj-$(CONFIG_32BIT) += div64.o 8obj-$(CONFIG_32BIT) += div64.o qrnnd.o
9lib-$(CONFIG_64BIT) += uaccess_mvcos.o 9lib-$(CONFIG_64BIT) += uaccess_mvcos.o
10lib-$(CONFIG_SMP) += spinlock.o 10lib-$(CONFIG_SMP) += spinlock.o
diff --git a/arch/sparc/kernel/smp.c b/arch/sparc/kernel/smp.c
index 4d9ad59031bb..4fea3ac7bff0 100644
--- a/arch/sparc/kernel/smp.c
+++ b/arch/sparc/kernel/smp.c
@@ -68,16 +68,6 @@ void __cpuinit smp_store_cpu_info(int id)
68 cpu_data(id).prom_node = cpu_node; 68 cpu_data(id).prom_node = cpu_node;
69 cpu_data(id).mid = cpu_get_hwmid(cpu_node); 69 cpu_data(id).mid = cpu_get_hwmid(cpu_node);
70 70
71 /* this is required to tune the scheduler correctly */
72 /* is it possible to have CPUs with different cache sizes? */
73 if (id == boot_cpu_id) {
74 int cache_line,cache_nlines;
75 cache_line = 0x20;
76 cache_line = prom_getintdefault(cpu_node, "ecache-line-size", cache_line);
77 cache_nlines = 0x8000;
78 cache_nlines = prom_getintdefault(cpu_node, "ecache-nlines", cache_nlines);
79 max_cache_size = cache_line * cache_nlines;
80 }
81 if (cpu_data(id).mid < 0) 71 if (cpu_data(id).mid < 0)
82 panic("No MID found for CPU%d at node 0x%08d", id, cpu_node); 72 panic("No MID found for CPU%d at node 0x%08d", id, cpu_node);
83} 73}
diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c
index 4dcd7d0b60f2..40e40f968d61 100644
--- a/arch/sparc64/kernel/smp.c
+++ b/arch/sparc64/kernel/smp.c
@@ -1163,32 +1163,6 @@ int setup_profiling_timer(unsigned int multiplier)
1163 return -EINVAL; 1163 return -EINVAL;
1164} 1164}
1165 1165
1166static void __init smp_tune_scheduling(void)
1167{
1168 unsigned int smallest = ~0U;
1169 int i;
1170
1171 for (i = 0; i < NR_CPUS; i++) {
1172 unsigned int val = cpu_data(i).ecache_size;
1173
1174 if (val && val < smallest)
1175 smallest = val;
1176 }
1177
1178 /* Any value less than 256K is nonsense. */
1179 if (smallest < (256U * 1024U))
1180 smallest = 256 * 1024;
1181
1182 max_cache_size = smallest;
1183
1184 if (smallest < 1U * 1024U * 1024U)
1185 printk(KERN_INFO "Using max_cache_size of %uKB\n",
1186 smallest / 1024U);
1187 else
1188 printk(KERN_INFO "Using max_cache_size of %uMB\n",
1189 smallest / 1024U / 1024U);
1190}
1191
1192/* Constrain the number of cpus to max_cpus. */ 1166/* Constrain the number of cpus to max_cpus. */
1193void __init smp_prepare_cpus(unsigned int max_cpus) 1167void __init smp_prepare_cpus(unsigned int max_cpus)
1194{ 1168{
@@ -1206,7 +1180,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
1206 } 1180 }
1207 1181
1208 cpu_data(boot_cpu_id).udelay_val = loops_per_jiffy; 1182 cpu_data(boot_cpu_id).udelay_val = loops_per_jiffy;
1209 smp_tune_scheduling();
1210} 1183}
1211 1184
1212void __devinit smp_prepare_boot_cpu(void) 1185void __devinit smp_prepare_boot_cpu(void)
diff --git a/block/Kconfig b/block/Kconfig
index a50f48111647..285935134bcd 100644
--- a/block/Kconfig
+++ b/block/Kconfig
@@ -1,7 +1,7 @@
1# 1#
2# Block layer core configuration 2# Block layer core configuration
3# 3#
4config BLOCK 4menuconfig BLOCK
5 bool "Enable the block layer" if EMBEDDED 5 bool "Enable the block layer" if EMBEDDED
6 default y 6 default y
7 help 7 help
@@ -49,6 +49,6 @@ config LSF
49 49
50 If unsure, say Y. 50 If unsure, say Y.
51 51
52endif 52endif # BLOCK
53 53
54source block/Kconfig.iosched 54source block/Kconfig.iosched
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index baef5fc7cff8..e0aa4dad6742 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -92,6 +92,8 @@ struct cfq_data {
92 struct cfq_queue *active_queue; 92 struct cfq_queue *active_queue;
93 struct cfq_io_context *active_cic; 93 struct cfq_io_context *active_cic;
94 94
95 struct cfq_queue *async_cfqq[IOPRIO_BE_NR];
96
95 struct timer_list idle_class_timer; 97 struct timer_list idle_class_timer;
96 98
97 sector_t last_position; 99 sector_t last_position;
@@ -1351,8 +1353,8 @@ static void cfq_ioc_set_ioprio(struct io_context *ioc)
1351} 1353}
1352 1354
1353static struct cfq_queue * 1355static struct cfq_queue *
1354cfq_get_queue(struct cfq_data *cfqd, int is_sync, struct task_struct *tsk, 1356cfq_find_alloc_queue(struct cfq_data *cfqd, int is_sync,
1355 gfp_t gfp_mask) 1357 struct task_struct *tsk, gfp_t gfp_mask)
1356{ 1358{
1357 struct cfq_queue *cfqq, *new_cfqq = NULL; 1359 struct cfq_queue *cfqq, *new_cfqq = NULL;
1358 struct cfq_io_context *cic; 1360 struct cfq_io_context *cic;
@@ -1405,12 +1407,35 @@ retry:
1405 if (new_cfqq) 1407 if (new_cfqq)
1406 kmem_cache_free(cfq_pool, new_cfqq); 1408 kmem_cache_free(cfq_pool, new_cfqq);
1407 1409
1408 atomic_inc(&cfqq->ref);
1409out: 1410out:
1410 WARN_ON((gfp_mask & __GFP_WAIT) && !cfqq); 1411 WARN_ON((gfp_mask & __GFP_WAIT) && !cfqq);
1411 return cfqq; 1412 return cfqq;
1412} 1413}
1413 1414
1415static struct cfq_queue *
1416cfq_get_queue(struct cfq_data *cfqd, int is_sync, struct task_struct *tsk,
1417 gfp_t gfp_mask)
1418{
1419 const int ioprio = task_ioprio(tsk);
1420 struct cfq_queue *cfqq = NULL;
1421
1422 if (!is_sync)
1423 cfqq = cfqd->async_cfqq[ioprio];
1424 if (!cfqq)
1425 cfqq = cfq_find_alloc_queue(cfqd, is_sync, tsk, gfp_mask);
1426
1427 /*
1428 * pin the queue now that it's allocated, scheduler exit will prune it
1429 */
1430 if (!is_sync && !cfqd->async_cfqq[ioprio]) {
1431 atomic_inc(&cfqq->ref);
1432 cfqd->async_cfqq[ioprio] = cfqq;
1433 }
1434
1435 atomic_inc(&cfqq->ref);
1436 return cfqq;
1437}
1438
1414/* 1439/*
1415 * We drop cfq io contexts lazily, so we may find a dead one. 1440 * We drop cfq io contexts lazily, so we may find a dead one.
1416 */ 1441 */
@@ -2019,6 +2044,7 @@ static void cfq_exit_queue(elevator_t *e)
2019{ 2044{
2020 struct cfq_data *cfqd = e->elevator_data; 2045 struct cfq_data *cfqd = e->elevator_data;
2021 request_queue_t *q = cfqd->queue; 2046 request_queue_t *q = cfqd->queue;
2047 int i;
2022 2048
2023 cfq_shutdown_timer_wq(cfqd); 2049 cfq_shutdown_timer_wq(cfqd);
2024 2050
@@ -2035,6 +2061,13 @@ static void cfq_exit_queue(elevator_t *e)
2035 __cfq_exit_single_io_context(cfqd, cic); 2061 __cfq_exit_single_io_context(cfqd, cic);
2036 } 2062 }
2037 2063
2064 /*
2065 * Put the async queues
2066 */
2067 for (i = 0; i < IOPRIO_BE_NR; i++)
2068 if (cfqd->async_cfqq[i])
2069 cfq_put_queue(cfqd->async_cfqq[i]);
2070
2038 spin_unlock_irq(q->queue_lock); 2071 spin_unlock_irq(q->queue_lock);
2039 2072
2040 cfq_shutdown_timer_wq(cfqd); 2073 cfq_shutdown_timer_wq(cfqd);
diff --git a/block/elevator.c b/block/elevator.c
index ce866eb75f6a..4769a25d7037 100644
--- a/block/elevator.c
+++ b/block/elevator.c
@@ -112,12 +112,8 @@ static inline int elv_try_merge(struct request *__rq, struct bio *bio)
112static struct elevator_type *elevator_find(const char *name) 112static struct elevator_type *elevator_find(const char *name)
113{ 113{
114 struct elevator_type *e; 114 struct elevator_type *e;
115 struct list_head *entry;
116
117 list_for_each(entry, &elv_list) {
118
119 e = list_entry(entry, struct elevator_type, list);
120 115
116 list_for_each_entry(e, &elv_list, list) {
121 if (!strcmp(e->elevator_name, name)) 117 if (!strcmp(e->elevator_name, name))
122 return e; 118 return e;
123 } 119 }
@@ -1116,14 +1112,11 @@ ssize_t elv_iosched_show(request_queue_t *q, char *name)
1116{ 1112{
1117 elevator_t *e = q->elevator; 1113 elevator_t *e = q->elevator;
1118 struct elevator_type *elv = e->elevator_type; 1114 struct elevator_type *elv = e->elevator_type;
1119 struct list_head *entry; 1115 struct elevator_type *__e;
1120 int len = 0; 1116 int len = 0;
1121 1117
1122 spin_lock(&elv_list_lock); 1118 spin_lock(&elv_list_lock);
1123 list_for_each(entry, &elv_list) { 1119 list_for_each_entry(__e, &elv_list, list) {
1124 struct elevator_type *__e;
1125
1126 __e = list_entry(entry, struct elevator_type, list);
1127 if (!strcmp(elv->elevator_name, __e->elevator_name)) 1120 if (!strcmp(elv->elevator_name, __e->elevator_name))
1128 len += sprintf(name+len, "[%s] ", elv->elevator_name); 1121 len += sprintf(name+len, "[%s] ", elv->elevator_name);
1129 else 1122 else
diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c
index c99b46354859..ef42bb2b12b6 100644
--- a/block/ll_rw_blk.c
+++ b/block/ll_rw_blk.c
@@ -527,8 +527,6 @@ int blk_do_ordered(request_queue_t *q, struct request **rqp)
527static int flush_dry_bio_endio(struct bio *bio, unsigned int bytes, int error) 527static int flush_dry_bio_endio(struct bio *bio, unsigned int bytes, int error)
528{ 528{
529 request_queue_t *q = bio->bi_private; 529 request_queue_t *q = bio->bi_private;
530 struct bio_vec *bvec;
531 int i;
532 530
533 /* 531 /*
534 * This is dry run, restore bio_sector and size. We'll finish 532 * This is dry run, restore bio_sector and size. We'll finish
@@ -540,13 +538,6 @@ static int flush_dry_bio_endio(struct bio *bio, unsigned int bytes, int error)
540 if (bio->bi_size) 538 if (bio->bi_size)
541 return 1; 539 return 1;
542 540
543 /* Rewind bvec's */
544 bio->bi_idx = 0;
545 bio_for_each_segment(bvec, bio, i) {
546 bvec->bv_len += bvec->bv_offset;
547 bvec->bv_offset = 0;
548 }
549
550 /* Reset bio */ 541 /* Reset bio */
551 set_bit(BIO_UPTODATE, &bio->bi_flags); 542 set_bit(BIO_UPTODATE, &bio->bi_flags);
552 bio->bi_size = q->bi_size; 543 bio->bi_size = q->bi_size;
@@ -1304,9 +1295,9 @@ static int blk_hw_contig_segment(request_queue_t *q, struct bio *bio,
1304 if (unlikely(!bio_flagged(nxt, BIO_SEG_VALID))) 1295 if (unlikely(!bio_flagged(nxt, BIO_SEG_VALID)))
1305 blk_recount_segments(q, nxt); 1296 blk_recount_segments(q, nxt);
1306 if (!BIOVEC_VIRT_MERGEABLE(__BVEC_END(bio), __BVEC_START(nxt)) || 1297 if (!BIOVEC_VIRT_MERGEABLE(__BVEC_END(bio), __BVEC_START(nxt)) ||
1307 BIOVEC_VIRT_OVERSIZE(bio->bi_hw_front_size + bio->bi_hw_back_size)) 1298 BIOVEC_VIRT_OVERSIZE(bio->bi_hw_back_size + nxt->bi_hw_front_size))
1308 return 0; 1299 return 0;
1309 if (bio->bi_size + nxt->bi_size > q->max_segment_size) 1300 if (bio->bi_hw_back_size + nxt->bi_hw_front_size > q->max_segment_size)
1310 return 0; 1301 return 0;
1311 1302
1312 return 1; 1303 return 1;
diff --git a/drivers/Kconfig b/drivers/Kconfig
index 050323fd79e9..7916f4b86d23 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -24,8 +24,6 @@ source "drivers/scsi/Kconfig"
24 24
25source "drivers/ata/Kconfig" 25source "drivers/ata/Kconfig"
26 26
27source "drivers/cdrom/Kconfig"
28
29source "drivers/md/Kconfig" 27source "drivers/md/Kconfig"
30 28
31source "drivers/message/fusion/Kconfig" 29source "drivers/message/fusion/Kconfig"
@@ -54,6 +52,8 @@ source "drivers/spi/Kconfig"
54 52
55source "drivers/w1/Kconfig" 53source "drivers/w1/Kconfig"
56 54
55source "drivers/power/Kconfig"
56
57source "drivers/hwmon/Kconfig" 57source "drivers/hwmon/Kconfig"
58 58
59source "drivers/mfd/Kconfig" 59source "drivers/mfd/Kconfig"
diff --git a/drivers/Makefile b/drivers/Makefile
index adad2f3d438a..503d82569449 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -61,6 +61,7 @@ obj-$(CONFIG_I2O) += message/
61obj-$(CONFIG_RTC_LIB) += rtc/ 61obj-$(CONFIG_RTC_LIB) += rtc/
62obj-y += i2c/ 62obj-y += i2c/
63obj-$(CONFIG_W1) += w1/ 63obj-$(CONFIG_W1) += w1/
64obj-$(CONFIG_POWER_SUPPLY) += power/
64obj-$(CONFIG_HWMON) += hwmon/ 65obj-$(CONFIG_HWMON) += hwmon/
65obj-$(CONFIG_PHONE) += telephony/ 66obj-$(CONFIG_PHONE) += telephony/
66obj-$(CONFIG_MD) += md/ 67obj-$(CONFIG_MD) += md/
diff --git a/drivers/acorn/block/fd1772.c b/drivers/acorn/block/fd1772.c
index 674bf81c6e66..423ed08fb6f7 100644
--- a/drivers/acorn/block/fd1772.c
+++ b/drivers/acorn/block/fd1772.c
@@ -1246,7 +1246,7 @@ repeat:
1246 del_timer(&motor_off_timer); 1246 del_timer(&motor_off_timer);
1247 1247
1248 ReqCnt = 0; 1248 ReqCnt = 0;
1249 ReqCmd = CURRENT->cmd; 1249 ReqCmd = rq_data_dir(CURRENT);
1250 ReqBlock = CURRENT->sector; 1250 ReqBlock = CURRENT->sector;
1251 ReqBuffer = CURRENT->buffer; 1251 ReqBuffer = CURRENT->buffer;
1252 setup_req_params(drive); 1252 setup_req_params(drive);
diff --git a/drivers/acorn/block/mfmhd.c b/drivers/acorn/block/mfmhd.c
index 689a4c3542ba..d85520f78e68 100644
--- a/drivers/acorn/block/mfmhd.c
+++ b/drivers/acorn/block/mfmhd.c
@@ -439,7 +439,7 @@ static void mfm_rw_intr(void)
439 a choice of command end or some data which is ready to be collected */ 439 a choice of command end or some data which is ready to be collected */
440 /* I think we have to transfer data while the interrupt line is on and its 440 /* I think we have to transfer data while the interrupt line is on and its
441 not any other type of interrupt */ 441 not any other type of interrupt */
442 if (CURRENT->cmd == WRITE) { 442 if (rq_data_dir(CURRENT) == WRITE) {
443 extern void hdc63463_writedma(void); 443 extern void hdc63463_writedma(void);
444 if ((hdc63463_dataleft <= 0) && (!(mfm_status & STAT_CED))) { 444 if ((hdc63463_dataleft <= 0) && (!(mfm_status & STAT_CED))) {
445 printk("mfm_rw_intr: Apparent DMA write request when no more to DMA\n"); 445 printk("mfm_rw_intr: Apparent DMA write request when no more to DMA\n");
@@ -799,7 +799,7 @@ static void issue_request(unsigned int block, unsigned int nsect,
799 raw_cmd.head = start_head; 799 raw_cmd.head = start_head;
800 raw_cmd.cylinder = track / p->heads; 800 raw_cmd.cylinder = track / p->heads;
801 raw_cmd.cmdtype = CURRENT->cmd; 801 raw_cmd.cmdtype = CURRENT->cmd;
802 raw_cmd.cmdcode = CURRENT->cmd == WRITE ? CMD_WD : CMD_RD; 802 raw_cmd.cmdcode = rq_data_dir(CURRENT) == WRITE ? CMD_WD : CMD_RD;
803 raw_cmd.cmddata[0] = dev + 1; /* DAG: +1 to get US */ 803 raw_cmd.cmddata[0] = dev + 1; /* DAG: +1 to get US */
804 raw_cmd.cmddata[1] = raw_cmd.head; 804 raw_cmd.cmddata[1] = raw_cmd.head;
805 raw_cmd.cmddata[2] = raw_cmd.cylinder >> 8; 805 raw_cmd.cmddata[2] = raw_cmd.cylinder >> 8;
@@ -830,7 +830,7 @@ static void issue_request(unsigned int block, unsigned int nsect,
830 hdc63463_dataleft = nsect * 256; /* Better way? */ 830 hdc63463_dataleft = nsect * 256; /* Better way? */
831 831
832 DBG("mfm%c: %sing: CHS=%d/%d/%d, sectors=%d, buffer=0x%08lx (%p)\n", 832 DBG("mfm%c: %sing: CHS=%d/%d/%d, sectors=%d, buffer=0x%08lx (%p)\n",
833 raw_cmd.dev + 'a', (CURRENT->cmd == READ) ? "read" : "writ", 833 raw_cmd.dev + 'a', rq_data_dir(CURRENT) == READ ? "read" : "writ",
834 raw_cmd.cylinder, 834 raw_cmd.cylinder,
835 raw_cmd.head, 835 raw_cmd.head,
836 raw_cmd.sector, nsect, (unsigned long) Copy_buffer, CURRENT); 836 raw_cmd.sector, nsect, (unsigned long) Copy_buffer, CURRENT);
@@ -917,13 +917,6 @@ static void mfm_request(void)
917 917
918 DBG("mfm_request: block after offset=%d\n", block); 918 DBG("mfm_request: block after offset=%d\n", block);
919 919
920 if (CURRENT->cmd != READ && CURRENT->cmd != WRITE) {
921 printk("unknown mfm-command %d\n", CURRENT->cmd);
922 end_request(CURRENT, 0);
923 Busy = 0;
924 printk("mfm: continue 4\n");
925 continue;
926 }
927 issue_request(block, nsect, CURRENT); 920 issue_request(block, nsect, CURRENT);
928 921
929 break; 922 break;
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index ca5229d24d8e..11e4eb9f304e 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -46,7 +46,7 @@
46#include <linux/libata.h> 46#include <linux/libata.h>
47 47
48#define DRV_NAME "ahci" 48#define DRV_NAME "ahci"
49#define DRV_VERSION "2.2" 49#define DRV_VERSION "2.3"
50 50
51 51
52enum { 52enum {
@@ -54,7 +54,7 @@ enum {
54 AHCI_MAX_PORTS = 32, 54 AHCI_MAX_PORTS = 32,
55 AHCI_MAX_SG = 168, /* hardware max is 64K */ 55 AHCI_MAX_SG = 168, /* hardware max is 64K */
56 AHCI_DMA_BOUNDARY = 0xffffffff, 56 AHCI_DMA_BOUNDARY = 0xffffffff,
57 AHCI_USE_CLUSTERING = 0, 57 AHCI_USE_CLUSTERING = 1,
58 AHCI_MAX_CMDS = 32, 58 AHCI_MAX_CMDS = 32,
59 AHCI_CMD_SZ = 32, 59 AHCI_CMD_SZ = 32,
60 AHCI_CMD_SLOT_SZ = AHCI_MAX_CMDS * AHCI_CMD_SZ, 60 AHCI_CMD_SLOT_SZ = AHCI_MAX_CMDS * AHCI_CMD_SZ,
@@ -81,6 +81,7 @@ enum {
81 board_ahci_vt8251 = 2, 81 board_ahci_vt8251 = 2,
82 board_ahci_ign_iferr = 3, 82 board_ahci_ign_iferr = 3,
83 board_ahci_sb600 = 4, 83 board_ahci_sb600 = 4,
84 board_ahci_mv = 5,
84 85
85 /* global controller registers */ 86 /* global controller registers */
86 HOST_CAP = 0x00, /* host capabilities */ 87 HOST_CAP = 0x00, /* host capabilities */
@@ -171,6 +172,8 @@ enum {
171 AHCI_FLAG_HONOR_PI = (1 << 26), /* honor PORTS_IMPL */ 172 AHCI_FLAG_HONOR_PI = (1 << 26), /* honor PORTS_IMPL */
172 AHCI_FLAG_IGN_SERR_INTERNAL = (1 << 27), /* ignore SERR_INTERNAL */ 173 AHCI_FLAG_IGN_SERR_INTERNAL = (1 << 27), /* ignore SERR_INTERNAL */
173 AHCI_FLAG_32BIT_ONLY = (1 << 28), /* force 32bit */ 174 AHCI_FLAG_32BIT_ONLY = (1 << 28), /* force 32bit */
175 AHCI_FLAG_MV_PATA = (1 << 29), /* PATA port */
176 AHCI_FLAG_NO_MSI = (1 << 30), /* no PCI MSI */
174 177
175 AHCI_FLAG_COMMON = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | 178 AHCI_FLAG_COMMON = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
176 ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA | 179 ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
@@ -228,9 +231,12 @@ static void ahci_thaw(struct ata_port *ap);
228static void ahci_error_handler(struct ata_port *ap); 231static void ahci_error_handler(struct ata_port *ap);
229static void ahci_vt8251_error_handler(struct ata_port *ap); 232static void ahci_vt8251_error_handler(struct ata_port *ap);
230static void ahci_post_internal_cmd(struct ata_queued_cmd *qc); 233static void ahci_post_internal_cmd(struct ata_queued_cmd *qc);
234static int ahci_port_resume(struct ata_port *ap);
235static unsigned int ahci_fill_sg(struct ata_queued_cmd *qc, void *cmd_tbl);
236static void ahci_fill_cmd_slot(struct ahci_port_priv *pp, unsigned int tag,
237 u32 opts);
231#ifdef CONFIG_PM 238#ifdef CONFIG_PM
232static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg); 239static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg);
233static int ahci_port_resume(struct ata_port *ap);
234static int ahci_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg); 240static int ahci_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg);
235static int ahci_pci_device_resume(struct pci_dev *pdev); 241static int ahci_pci_device_resume(struct pci_dev *pdev);
236#endif 242#endif
@@ -327,14 +333,14 @@ static const struct ata_port_info ahci_port_info[] = {
327 { 333 {
328 .flags = AHCI_FLAG_COMMON, 334 .flags = AHCI_FLAG_COMMON,
329 .pio_mask = 0x1f, /* pio0-4 */ 335 .pio_mask = 0x1f, /* pio0-4 */
330 .udma_mask = 0x7f, /* udma0-6 ; FIXME */ 336 .udma_mask = ATA_UDMA6,
331 .port_ops = &ahci_ops, 337 .port_ops = &ahci_ops,
332 }, 338 },
333 /* board_ahci_pi */ 339 /* board_ahci_pi */
334 { 340 {
335 .flags = AHCI_FLAG_COMMON | AHCI_FLAG_HONOR_PI, 341 .flags = AHCI_FLAG_COMMON | AHCI_FLAG_HONOR_PI,
336 .pio_mask = 0x1f, /* pio0-4 */ 342 .pio_mask = 0x1f, /* pio0-4 */
337 .udma_mask = 0x7f, /* udma0-6 ; FIXME */ 343 .udma_mask = ATA_UDMA6,
338 .port_ops = &ahci_ops, 344 .port_ops = &ahci_ops,
339 }, 345 },
340 /* board_ahci_vt8251 */ 346 /* board_ahci_vt8251 */
@@ -342,14 +348,14 @@ static const struct ata_port_info ahci_port_info[] = {
342 .flags = AHCI_FLAG_COMMON | ATA_FLAG_HRST_TO_RESUME | 348 .flags = AHCI_FLAG_COMMON | ATA_FLAG_HRST_TO_RESUME |
343 AHCI_FLAG_NO_NCQ, 349 AHCI_FLAG_NO_NCQ,
344 .pio_mask = 0x1f, /* pio0-4 */ 350 .pio_mask = 0x1f, /* pio0-4 */
345 .udma_mask = 0x7f, /* udma0-6 ; FIXME */ 351 .udma_mask = ATA_UDMA6,
346 .port_ops = &ahci_vt8251_ops, 352 .port_ops = &ahci_vt8251_ops,
347 }, 353 },
348 /* board_ahci_ign_iferr */ 354 /* board_ahci_ign_iferr */
349 { 355 {
350 .flags = AHCI_FLAG_COMMON | AHCI_FLAG_IGN_IRQ_IF_ERR, 356 .flags = AHCI_FLAG_COMMON | AHCI_FLAG_IGN_IRQ_IF_ERR,
351 .pio_mask = 0x1f, /* pio0-4 */ 357 .pio_mask = 0x1f, /* pio0-4 */
352 .udma_mask = 0x7f, /* udma0-6 ; FIXME */ 358 .udma_mask = ATA_UDMA6,
353 .port_ops = &ahci_ops, 359 .port_ops = &ahci_ops,
354 }, 360 },
355 /* board_ahci_sb600 */ 361 /* board_ahci_sb600 */
@@ -358,7 +364,19 @@ static const struct ata_port_info ahci_port_info[] = {
358 AHCI_FLAG_IGN_SERR_INTERNAL | 364 AHCI_FLAG_IGN_SERR_INTERNAL |
359 AHCI_FLAG_32BIT_ONLY, 365 AHCI_FLAG_32BIT_ONLY,
360 .pio_mask = 0x1f, /* pio0-4 */ 366 .pio_mask = 0x1f, /* pio0-4 */
361 .udma_mask = 0x7f, /* udma0-6 ; FIXME */ 367 .udma_mask = ATA_UDMA6,
368 .port_ops = &ahci_ops,
369 },
370 /* board_ahci_mv */
371 {
372 .sht = &ahci_sht,
373 .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
374 ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
375 ATA_FLAG_SKIP_D2H_BSY | AHCI_FLAG_HONOR_PI |
376 AHCI_FLAG_NO_NCQ | AHCI_FLAG_NO_MSI |
377 AHCI_FLAG_MV_PATA,
378 .pio_mask = 0x1f, /* pio0-4 */
379 .udma_mask = ATA_UDMA6,
362 .port_ops = &ahci_ops, 380 .port_ops = &ahci_ops,
363 }, 381 },
364}; 382};
@@ -456,6 +474,9 @@ static const struct pci_device_id ahci_pci_tbl[] = {
456 { PCI_VDEVICE(SI, 0x1185), board_ahci }, /* SiS 966 */ 474 { PCI_VDEVICE(SI, 0x1185), board_ahci }, /* SiS 966 */
457 { PCI_VDEVICE(SI, 0x0186), board_ahci }, /* SiS 968 */ 475 { PCI_VDEVICE(SI, 0x0186), board_ahci }, /* SiS 968 */
458 476
477 /* Marvell */
478 { PCI_VDEVICE(MARVELL, 0x6145), board_ahci_mv }, /* 6145 */
479
459 /* Generic, PCI class code for AHCI */ 480 /* Generic, PCI class code for AHCI */
460 { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 481 { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
461 PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, board_ahci }, 482 PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, board_ahci },
@@ -481,11 +502,17 @@ static inline int ahci_nr_ports(u32 cap)
481 return (cap & 0x1f) + 1; 502 return (cap & 0x1f) + 1;
482} 503}
483 504
484static inline void __iomem *ahci_port_base(struct ata_port *ap) 505static inline void __iomem *__ahci_port_base(struct ata_host *host,
506 unsigned int port_no)
485{ 507{
486 void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR]; 508 void __iomem *mmio = host->iomap[AHCI_PCI_BAR];
509
510 return mmio + 0x100 + (port_no * 0x80);
511}
487 512
488 return mmio + 0x100 + (ap->port_no * 0x80); 513static inline void __iomem *ahci_port_base(struct ata_port *ap)
514{
515 return __ahci_port_base(ap->host, ap->port_no);
489} 516}
490 517
491/** 518/**
@@ -535,6 +562,20 @@ static void ahci_save_initial_config(struct pci_dev *pdev,
535 hpriv->saved_port_map = port_map; 562 hpriv->saved_port_map = port_map;
536 } 563 }
537 564
565 /*
566 * Temporary Marvell 6145 hack: PATA port presence
567 * is asserted through the standard AHCI port
568 * presence register, as bit 4 (counting from 0)
569 */
570 if (pi->flags & AHCI_FLAG_MV_PATA) {
571 dev_printk(KERN_ERR, &pdev->dev,
572 "MV_AHCI HACK: port_map %x -> %x\n",
573 hpriv->port_map,
574 hpriv->port_map & 0xf);
575
576 port_map &= 0xf;
577 }
578
538 /* cross check port_map and cap.n_ports */ 579 /* cross check port_map and cap.n_ports */
539 if (pi->flags & AHCI_FLAG_HONOR_PI) { 580 if (pi->flags & AHCI_FLAG_HONOR_PI) {
540 u32 tmp_port_map = port_map; 581 u32 tmp_port_map = port_map;
@@ -740,7 +781,7 @@ static void ahci_power_down(struct ata_port *ap)
740} 781}
741#endif 782#endif
742 783
743static void ahci_init_port(struct ata_port *ap) 784static void ahci_start_port(struct ata_port *ap)
744{ 785{
745 /* enable FIS reception */ 786 /* enable FIS reception */
746 ahci_start_fis_rx(ap); 787 ahci_start_fis_rx(ap);
@@ -814,39 +855,62 @@ static int ahci_reset_controller(struct ata_host *host)
814 return 0; 855 return 0;
815} 856}
816 857
858static void ahci_port_init(struct pci_dev *pdev, struct ata_port *ap,
859 int port_no, void __iomem *mmio,
860 void __iomem *port_mmio)
861{
862 const char *emsg = NULL;
863 int rc;
864 u32 tmp;
865
866 /* make sure port is not active */
867 rc = ahci_deinit_port(ap, &emsg);
868 if (rc)
869 dev_printk(KERN_WARNING, &pdev->dev,
870 "%s (%d)\n", emsg, rc);
871
872 /* clear SError */
873 tmp = readl(port_mmio + PORT_SCR_ERR);
874 VPRINTK("PORT_SCR_ERR 0x%x\n", tmp);
875 writel(tmp, port_mmio + PORT_SCR_ERR);
876
877 /* clear port IRQ */
878 tmp = readl(port_mmio + PORT_IRQ_STAT);
879 VPRINTK("PORT_IRQ_STAT 0x%x\n", tmp);
880 if (tmp)
881 writel(tmp, port_mmio + PORT_IRQ_STAT);
882
883 writel(1 << port_no, mmio + HOST_IRQ_STAT);
884}
885
817static void ahci_init_controller(struct ata_host *host) 886static void ahci_init_controller(struct ata_host *host)
818{ 887{
819 struct pci_dev *pdev = to_pci_dev(host->dev); 888 struct pci_dev *pdev = to_pci_dev(host->dev);
820 void __iomem *mmio = host->iomap[AHCI_PCI_BAR]; 889 void __iomem *mmio = host->iomap[AHCI_PCI_BAR];
821 int i, rc; 890 int i;
891 void __iomem *port_mmio;
822 u32 tmp; 892 u32 tmp;
823 893
824 for (i = 0; i < host->n_ports; i++) { 894 if (host->ports[0]->flags & AHCI_FLAG_MV_PATA) {
825 struct ata_port *ap = host->ports[i]; 895 port_mmio = __ahci_port_base(host, 4);
826 void __iomem *port_mmio = ahci_port_base(ap);
827 const char *emsg = NULL;
828
829 if (ata_port_is_dummy(ap))
830 continue;
831
832 /* make sure port is not active */
833 rc = ahci_deinit_port(ap, &emsg);
834 if (rc)
835 dev_printk(KERN_WARNING, &pdev->dev,
836 "%s (%d)\n", emsg, rc);
837 896
838 /* clear SError */ 897 writel(0, port_mmio + PORT_IRQ_MASK);
839 tmp = readl(port_mmio + PORT_SCR_ERR);
840 VPRINTK("PORT_SCR_ERR 0x%x\n", tmp);
841 writel(tmp, port_mmio + PORT_SCR_ERR);
842 898
843 /* clear port IRQ */ 899 /* clear port IRQ */
844 tmp = readl(port_mmio + PORT_IRQ_STAT); 900 tmp = readl(port_mmio + PORT_IRQ_STAT);
845 VPRINTK("PORT_IRQ_STAT 0x%x\n", tmp); 901 VPRINTK("PORT_IRQ_STAT 0x%x\n", tmp);
846 if (tmp) 902 if (tmp)
847 writel(tmp, port_mmio + PORT_IRQ_STAT); 903 writel(tmp, port_mmio + PORT_IRQ_STAT);
904 }
848 905
849 writel(1 << i, mmio + HOST_IRQ_STAT); 906 for (i = 0; i < host->n_ports; i++) {
907 struct ata_port *ap = host->ports[i];
908
909 port_mmio = ahci_port_base(ap);
910 if (ata_port_is_dummy(ap))
911 continue;
912
913 ahci_port_init(pdev, ap, i, mmio, port_mmio);
850 } 914 }
851 915
852 tmp = readl(mmio + HOST_CTL); 916 tmp = readl(mmio + HOST_CTL);
@@ -1232,7 +1296,7 @@ static void ahci_error_intr(struct ata_port *ap, u32 irq_stat)
1232 ata_port_abort(ap); 1296 ata_port_abort(ap);
1233} 1297}
1234 1298
1235static void ahci_host_intr(struct ata_port *ap) 1299static void ahci_port_intr(struct ata_port *ap)
1236{ 1300{
1237 void __iomem *port_mmio = ap->ioaddr.cmd_addr; 1301 void __iomem *port_mmio = ap->ioaddr.cmd_addr;
1238 struct ata_eh_info *ehi = &ap->eh_info; 1302 struct ata_eh_info *ehi = &ap->eh_info;
@@ -1358,7 +1422,7 @@ static irqreturn_t ahci_interrupt(int irq, void *dev_instance)
1358 1422
1359 ap = host->ports[i]; 1423 ap = host->ports[i];
1360 if (ap) { 1424 if (ap) {
1361 ahci_host_intr(ap); 1425 ahci_port_intr(ap);
1362 VPRINTK("port %u\n", i); 1426 VPRINTK("port %u\n", i);
1363 } else { 1427 } else {
1364 VPRINTK("port %u (no irq)\n", i); 1428 VPRINTK("port %u (no irq)\n", i);
@@ -1466,7 +1530,7 @@ static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg)
1466 ahci_power_down(ap); 1530 ahci_power_down(ap);
1467 else { 1531 else {
1468 ata_port_printk(ap, KERN_ERR, "%s (%d)\n", emsg, rc); 1532 ata_port_printk(ap, KERN_ERR, "%s (%d)\n", emsg, rc);
1469 ahci_init_port(ap); 1533 ahci_start_port(ap);
1470 } 1534 }
1471 1535
1472 return rc; 1536 return rc;
@@ -1475,7 +1539,7 @@ static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg)
1475static int ahci_port_resume(struct ata_port *ap) 1539static int ahci_port_resume(struct ata_port *ap)
1476{ 1540{
1477 ahci_power_up(ap); 1541 ahci_power_up(ap);
1478 ahci_init_port(ap); 1542 ahci_start_port(ap);
1479 1543
1480 return 0; 1544 return 0;
1481} 1545}
@@ -1573,13 +1637,8 @@ static int ahci_port_start(struct ata_port *ap)
1573 1637
1574 ap->private_data = pp; 1638 ap->private_data = pp;
1575 1639
1576 /* power up port */ 1640 /* engage engines, captain */
1577 ahci_power_up(ap); 1641 return ahci_port_resume(ap);
1578
1579 /* initialize port */
1580 ahci_init_port(ap);
1581
1582 return 0;
1583} 1642}
1584 1643
1585static void ahci_port_stop(struct ata_port *ap) 1644static void ahci_port_stop(struct ata_port *ap)
@@ -1724,7 +1783,7 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
1724 if (rc) 1783 if (rc)
1725 return rc; 1784 return rc;
1726 1785
1727 if (pci_enable_msi(pdev)) 1786 if ((pi.flags & AHCI_FLAG_NO_MSI) || pci_enable_msi(pdev))
1728 pci_intx(pdev, 1); 1787 pci_intx(pdev, 1);
1729 1788
1730 hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL); 1789 hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL);
@@ -1745,14 +1804,18 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
1745 host->private_data = hpriv; 1804 host->private_data = hpriv;
1746 1805
1747 for (i = 0; i < host->n_ports; i++) { 1806 for (i = 0; i < host->n_ports; i++) {
1748 if (hpriv->port_map & (1 << i)) { 1807 struct ata_port *ap = host->ports[i];
1749 struct ata_port *ap = host->ports[i]; 1808 void __iomem *port_mmio = ahci_port_base(ap);
1750 void __iomem *port_mmio = ahci_port_base(ap);
1751 1809
1810 /* standard SATA port setup */
1811 if (hpriv->port_map & (1 << i)) {
1752 ap->ioaddr.cmd_addr = port_mmio; 1812 ap->ioaddr.cmd_addr = port_mmio;
1753 ap->ioaddr.scr_addr = port_mmio + PORT_SCR; 1813 ap->ioaddr.scr_addr = port_mmio + PORT_SCR;
1754 } else 1814 }
1755 host->ports[i]->ops = &ata_dummy_port_ops; 1815
1816 /* disabled/not-implemented port */
1817 else
1818 ap->ops = &ata_dummy_port_ops;
1756 } 1819 }
1757 1820
1758 /* initialize adapter */ 1821 /* initialize adapter */
diff --git a/drivers/ata/ata_generic.c b/drivers/ata/ata_generic.c
index 4c6e95c95e4a..430fcf4f9ef3 100644
--- a/drivers/ata/ata_generic.c
+++ b/drivers/ata/ata_generic.c
@@ -143,10 +143,10 @@ static int ata_generic_init_one(struct pci_dev *dev, const struct pci_device_id
143 u16 command; 143 u16 command;
144 static const struct ata_port_info info = { 144 static const struct ata_port_info info = {
145 .sht = &generic_sht, 145 .sht = &generic_sht,
146 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 146 .flags = ATA_FLAG_SLAVE_POSS,
147 .pio_mask = 0x1f, 147 .pio_mask = 0x1f,
148 .mwdma_mask = 0x07, 148 .mwdma_mask = 0x07,
149 .udma_mask = 0x3f, 149 .udma_mask = ATA_UDMA5,
150 .port_ops = &generic_port_ops 150 .port_ops = &generic_port_ops
151 }; 151 };
152 const struct ata_port_info *ppi[] = { &info, NULL }; 152 const struct ata_port_info *ppi[] = { &info, NULL };
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c
index 9c07b88631be..6a3bfef58e13 100644
--- a/drivers/ata/ata_piix.c
+++ b/drivers/ata/ata_piix.c
@@ -200,6 +200,8 @@ static const struct pci_device_id piix_pci_tbl[] = {
200 /* ICH7/7-R (i945, i975) UDMA 100*/ 200 /* ICH7/7-R (i945, i975) UDMA 100*/
201 { 0x8086, 0x27DF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_133 }, 201 { 0x8086, 0x27DF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_133 },
202 { 0x8086, 0x269E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 }, 202 { 0x8086, 0x269E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 },
203 /* ICH8 Mobile PATA Controller */
204 { 0x8086, 0x2850, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 },
203 205
204 /* NOTE: The following PCI ids must be kept in sync with the 206 /* NOTE: The following PCI ids must be kept in sync with the
205 * list in drivers/pci/quirks.c. 207 * list in drivers/pci/quirks.c.
@@ -495,7 +497,7 @@ static struct ata_port_info piix_port_info[] = {
495 .flags = PIIX_SATA_FLAGS, 497 .flags = PIIX_SATA_FLAGS,
496 .pio_mask = 0x1f, /* pio0-4 */ 498 .pio_mask = 0x1f, /* pio0-4 */
497 .mwdma_mask = 0x07, /* mwdma0-2 */ 499 .mwdma_mask = 0x07, /* mwdma0-2 */
498 .udma_mask = 0x7f, /* udma0-6 */ 500 .udma_mask = ATA_UDMA6,
499 .port_ops = &piix_sata_ops, 501 .port_ops = &piix_sata_ops,
500 }, 502 },
501 503
@@ -505,7 +507,7 @@ static struct ata_port_info piix_port_info[] = {
505 .flags = PIIX_SATA_FLAGS | PIIX_FLAG_SCR, 507 .flags = PIIX_SATA_FLAGS | PIIX_FLAG_SCR,
506 .pio_mask = 0x1f, /* pio0-4 */ 508 .pio_mask = 0x1f, /* pio0-4 */
507 .mwdma_mask = 0x07, /* mwdma0-2 */ 509 .mwdma_mask = 0x07, /* mwdma0-2 */
508 .udma_mask = 0x7f, /* udma0-6 */ 510 .udma_mask = ATA_UDMA6,
509 .port_ops = &piix_sata_ops, 511 .port_ops = &piix_sata_ops,
510 }, 512 },
511 513
@@ -516,7 +518,7 @@ static struct ata_port_info piix_port_info[] = {
516 PIIX_FLAG_AHCI, 518 PIIX_FLAG_AHCI,
517 .pio_mask = 0x1f, /* pio0-4 */ 519 .pio_mask = 0x1f, /* pio0-4 */
518 .mwdma_mask = 0x07, /* mwdma0-2 */ 520 .mwdma_mask = 0x07, /* mwdma0-2 */
519 .udma_mask = 0x7f, /* udma0-6 */ 521 .udma_mask = ATA_UDMA6,
520 .port_ops = &piix_sata_ops, 522 .port_ops = &piix_sata_ops,
521 }, 523 },
522 524
@@ -527,7 +529,7 @@ static struct ata_port_info piix_port_info[] = {
527 PIIX_FLAG_AHCI, 529 PIIX_FLAG_AHCI,
528 .pio_mask = 0x1f, /* pio0-4 */ 530 .pio_mask = 0x1f, /* pio0-4 */
529 .mwdma_mask = 0x07, /* mwdma0-2 */ 531 .mwdma_mask = 0x07, /* mwdma0-2 */
530 .udma_mask = 0x7f, /* udma0-6 */ 532 .udma_mask = ATA_UDMA6,
531 .port_ops = &piix_sata_ops, 533 .port_ops = &piix_sata_ops,
532 }, 534 },
533 535
@@ -538,7 +540,7 @@ static struct ata_port_info piix_port_info[] = {
538 PIIX_FLAG_AHCI, 540 PIIX_FLAG_AHCI,
539 .pio_mask = 0x1f, /* pio0-4 */ 541 .pio_mask = 0x1f, /* pio0-4 */
540 .mwdma_mask = 0x07, /* mwdma0-2 */ 542 .mwdma_mask = 0x07, /* mwdma0-2 */
541 .udma_mask = 0x7f, /* udma0-6 */ 543 .udma_mask = ATA_UDMA6,
542 .port_ops = &piix_sata_ops, 544 .port_ops = &piix_sata_ops,
543 }, 545 },
544 546
@@ -685,8 +687,14 @@ static void piix_set_piomode (struct ata_port *ap, struct ata_device *adev)
685 if (adev->class == ATA_DEV_ATA) 687 if (adev->class == ATA_DEV_ATA)
686 control |= 4; /* PPE enable */ 688 control |= 4; /* PPE enable */
687 689
690 /* PIO configuration clears DTE unconditionally. It will be
691 * programmed in set_dmamode which is guaranteed to be called
692 * after set_piomode if any DMA mode is available.
693 */
688 pci_read_config_word(dev, master_port, &master_data); 694 pci_read_config_word(dev, master_port, &master_data);
689 if (is_slave) { 695 if (is_slave) {
696 /* clear TIME1|IE1|PPE1|DTE1 */
697 master_data &= 0xff0f;
690 /* Enable SITRE (seperate slave timing register) */ 698 /* Enable SITRE (seperate slave timing register) */
691 master_data |= 0x4000; 699 master_data |= 0x4000;
692 /* enable PPE1, IE1 and TIME1 as needed */ 700 /* enable PPE1, IE1 and TIME1 as needed */
@@ -694,12 +702,14 @@ static void piix_set_piomode (struct ata_port *ap, struct ata_device *adev)
694 pci_read_config_byte(dev, slave_port, &slave_data); 702 pci_read_config_byte(dev, slave_port, &slave_data);
695 slave_data &= (ap->port_no ? 0x0f : 0xf0); 703 slave_data &= (ap->port_no ? 0x0f : 0xf0);
696 /* Load the timing nibble for this slave */ 704 /* Load the timing nibble for this slave */
697 slave_data |= ((timings[pio][0] << 2) | timings[pio][1]) << (ap->port_no ? 4 : 0); 705 slave_data |= ((timings[pio][0] << 2) | timings[pio][1])
706 << (ap->port_no ? 4 : 0);
698 } else { 707 } else {
699 /* Master keeps the bits in a different format */ 708 /* clear ISP|RCT|TIME0|IE0|PPE0|DTE0 */
700 master_data &= 0xccf8; 709 master_data &= 0xccf0;
701 /* Enable PPE, IE and TIME as appropriate */ 710 /* Enable PPE, IE and TIME as appropriate */
702 master_data |= control; 711 master_data |= control;
712 /* load ISP and RCT */
703 master_data |= 713 master_data |=
704 (timings[pio][0] << 12) | 714 (timings[pio][0] << 12) |
705 (timings[pio][1] << 8); 715 (timings[pio][1] << 8);
@@ -816,7 +826,7 @@ static void do_pata_set_dmamode (struct ata_port *ap, struct ata_device *adev, i
816 master_data &= 0xFF4F; /* Mask out IORDY|TIME1|DMAONLY */ 826 master_data &= 0xFF4F; /* Mask out IORDY|TIME1|DMAONLY */
817 master_data |= control << 4; 827 master_data |= control << 4;
818 pci_read_config_byte(dev, 0x44, &slave_data); 828 pci_read_config_byte(dev, 0x44, &slave_data);
819 slave_data &= (0x0F + 0xE1 * ap->port_no); 829 slave_data &= (ap->port_no ? 0x0f : 0xf0);
820 /* Load the matching timing */ 830 /* Load the matching timing */
821 slave_data |= ((timings[pio][0] << 2) | timings[pio][1]) << (ap->port_no ? 4 : 0); 831 slave_data |= ((timings[pio][0] << 2) | timings[pio][1]) << (ap->port_no ? 4 : 0);
822 pci_write_config_byte(dev, 0x44, slave_data); 832 pci_write_config_byte(dev, 0x44, slave_data);
@@ -828,8 +838,11 @@ static void do_pata_set_dmamode (struct ata_port *ap, struct ata_device *adev, i
828 (timings[pio][0] << 12) | 838 (timings[pio][0] << 12) |
829 (timings[pio][1] << 8); 839 (timings[pio][1] << 8);
830 } 840 }
831 udma_enable &= ~(1 << devid); 841
832 pci_write_config_word(dev, master_port, master_data); 842 if (ap->udma_mask) {
843 udma_enable &= ~(1 << devid);
844 pci_write_config_word(dev, master_port, master_data);
845 }
833 } 846 }
834 /* Don't scribble on 0x48 if the controller does not support UDMA */ 847 /* Don't scribble on 0x48 if the controller does not support UDMA */
835 if (ap->udma_mask) 848 if (ap->udma_mask)
diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c
index 02236739b40f..c059f78ad944 100644
--- a/drivers/ata/libata-acpi.c
+++ b/drivers/ata/libata-acpi.c
@@ -24,15 +24,13 @@
24#include <acpi/acmacros.h> 24#include <acpi/acmacros.h>
25#include <acpi/actypes.h> 25#include <acpi/actypes.h>
26 26
27#define SATA_ROOT_PORT(x) (((x) >> 16) & 0xffff)
28#define SATA_PORT_NUMBER(x) ((x) & 0xffff) /* or NO_PORT_MULT */
29#define NO_PORT_MULT 0xffff 27#define NO_PORT_MULT 0xffff
30#define SATA_ADR_RSVD 0xffffffff 28#define SATA_ADR(root,pmp) (((root) << 16) | (pmp))
31 29
32#define REGS_PER_GTF 7 30#define REGS_PER_GTF 7
33struct taskfile_array { 31struct ata_acpi_gtf {
34 u8 tfa[REGS_PER_GTF]; /* regs. 0x1f1 - 0x1f7 */ 32 u8 tf[REGS_PER_GTF]; /* regs. 0x1f1 - 0x1f7 */
35}; 33} __packed;
36 34
37/* 35/*
38 * Helper - belongs in the PCI layer somewhere eventually 36 * Helper - belongs in the PCI layer somewhere eventually
@@ -42,237 +40,173 @@ static int is_pci_dev(struct device *dev)
42 return (dev->bus == &pci_bus_type); 40 return (dev->bus == &pci_bus_type);
43} 41}
44 42
43static void ata_acpi_associate_sata_port(struct ata_port *ap)
44{
45 acpi_integer adr = SATA_ADR(ap->port_no, NO_PORT_MULT);
46
47 ap->device->acpi_handle = acpi_get_child(ap->host->acpi_handle, adr);
48}
49
50static void ata_acpi_associate_ide_port(struct ata_port *ap)
51{
52 int max_devices, i;
53
54 ap->acpi_handle = acpi_get_child(ap->host->acpi_handle, ap->port_no);
55 if (!ap->acpi_handle)
56 return;
57
58 max_devices = 1;
59 if (ap->flags & ATA_FLAG_SLAVE_POSS)
60 max_devices++;
61
62 for (i = 0; i < max_devices; i++) {
63 struct ata_device *dev = &ap->device[i];
64
65 dev->acpi_handle = acpi_get_child(ap->acpi_handle, i);
66 }
67}
68
45/** 69/**
46 * sata_get_dev_handle - finds acpi_handle and PCI device.function 70 * ata_acpi_associate - associate ATA host with ACPI objects
47 * @dev: device to locate 71 * @host: target ATA host
48 * @handle: returned acpi_handle for @dev 72 *
49 * @pcidevfn: return PCI device.func for @dev 73 * Look up ACPI objects associated with @host and initialize
74 * acpi_handle fields of @host, its ports and devices accordingly.
50 * 75 *
51 * This function is somewhat SATA-specific. Or at least the 76 * LOCKING:
52 * PATA & SATA versions of this function are different, 77 * EH context.
53 * so it's not entirely generic code.
54 * 78 *
55 * Returns 0 on success, <0 on error. 79 * RETURNS:
80 * 0 on success, -errno on failure.
56 */ 81 */
57static int sata_get_dev_handle(struct device *dev, acpi_handle *handle, 82void ata_acpi_associate(struct ata_host *host)
58 acpi_integer *pcidevfn)
59{ 83{
60 struct pci_dev *pci_dev; 84 int i;
61 acpi_integer addr; 85
62 86 if (!is_pci_dev(host->dev) || libata_noacpi)
63 if (!is_pci_dev(dev)) 87 return;
64 return -ENODEV; 88
65 89 host->acpi_handle = DEVICE_ACPI_HANDLE(host->dev);
66 pci_dev = to_pci_dev(dev); /* NOTE: PCI-specific */ 90 if (!host->acpi_handle)
67 /* Please refer to the ACPI spec for the syntax of _ADR. */ 91 return;
68 addr = (PCI_SLOT(pci_dev->devfn) << 16) | PCI_FUNC(pci_dev->devfn); 92
69 *pcidevfn = addr; 93 for (i = 0; i < host->n_ports; i++) {
70 *handle = acpi_get_child(DEVICE_ACPI_HANDLE(dev->parent), addr); 94 struct ata_port *ap = host->ports[i];
71 if (!*handle) 95
72 return -ENODEV; 96 if (host->ports[0]->flags & ATA_FLAG_ACPI_SATA)
73 return 0; 97 ata_acpi_associate_sata_port(ap);
98 else
99 ata_acpi_associate_ide_port(ap);
100 }
74} 101}
75 102
76/** 103/**
77 * pata_get_dev_handle - finds acpi_handle and PCI device.function 104 * ata_acpi_gtm - execute _GTM
78 * @dev: device to locate 105 * @ap: target ATA port
79 * @handle: returned acpi_handle for @dev 106 * @gtm: out parameter for _GTM result
80 * @pcidevfn: return PCI device.func for @dev 107 *
108 * Evaluate _GTM and store the result in @gtm.
81 * 109 *
82 * The PATA and SATA versions of this function are different. 110 * LOCKING:
111 * EH context.
83 * 112 *
84 * Returns 0 on success, <0 on error. 113 * RETURNS:
114 * 0 on success, -ENOENT if _GTM doesn't exist, -errno on failure.
85 */ 115 */
86static int pata_get_dev_handle(struct device *dev, acpi_handle *handle, 116static int ata_acpi_gtm(const struct ata_port *ap, struct ata_acpi_gtm *gtm)
87 acpi_integer *pcidevfn)
88{ 117{
89 unsigned int bus, devnum, func; 118 struct acpi_buffer output = { .length = ACPI_ALLOCATE_BUFFER };
90 acpi_integer addr; 119 union acpi_object *out_obj;
91 acpi_handle dev_handle, parent_handle;
92 struct acpi_buffer buffer = {.length = ACPI_ALLOCATE_BUFFER,
93 .pointer = NULL};
94 acpi_status status; 120 acpi_status status;
95 struct acpi_device_info *dinfo = NULL; 121 int rc = 0;
96 int ret = -ENODEV; 122
97 struct pci_dev *pdev; 123 status = acpi_evaluate_object(ap->acpi_handle, "_GTM", NULL, &output);
98 124
99 if (!is_pci_dev(dev)) 125 rc = -ENOENT;
100 return -ENODEV; 126 if (status == AE_NOT_FOUND)
101 127 goto out_free;
102 pdev = to_pci_dev(dev); 128
103 129 rc = -EINVAL;
104 bus = pdev->bus->number; 130 if (ACPI_FAILURE(status)) {
105 devnum = PCI_SLOT(pdev->devfn); 131 ata_port_printk(ap, KERN_ERR,
106 func = PCI_FUNC(pdev->devfn); 132 "ACPI get timing mode failed (AE 0x%x)\n",
107 133 status);
108 dev_handle = DEVICE_ACPI_HANDLE(dev); 134 goto out_free;
109 parent_handle = DEVICE_ACPI_HANDLE(dev->parent);
110
111 status = acpi_get_object_info(parent_handle, &buffer);
112 if (ACPI_FAILURE(status))
113 goto err;
114
115 dinfo = buffer.pointer;
116 if (dinfo && (dinfo->valid & ACPI_VALID_ADR) &&
117 dinfo->address == bus) {
118 /* ACPI spec for _ADR for PCI bus: */
119 addr = (acpi_integer)(devnum << 16 | func);
120 *pcidevfn = addr;
121 *handle = dev_handle;
122 } else {
123 goto err;
124 } 135 }
125 136
126 if (!*handle) 137 out_obj = output.pointer;
127 goto err; 138 if (out_obj->type != ACPI_TYPE_BUFFER) {
128 ret = 0; 139 ata_port_printk(ap, KERN_WARNING,
129err: 140 "_GTM returned unexpected object type 0x%x\n",
130 kfree(dinfo); 141 out_obj->type);
131 return ret;
132}
133 142
134struct walk_info { /* can be trimmed some */ 143 goto out_free;
135 struct device *dev;
136 struct acpi_device *adev;
137 acpi_handle handle;
138 acpi_integer pcidevfn;
139 unsigned int drivenum;
140 acpi_handle obj_handle;
141 struct ata_port *ataport;
142 struct ata_device *atadev;
143 u32 sata_adr;
144 int status;
145 char basepath[ACPI_PATHNAME_MAX];
146 int basepath_len;
147};
148
149static acpi_status get_devices(acpi_handle handle,
150 u32 level, void *context, void **return_value)
151{
152 acpi_status status;
153 struct walk_info *winfo = context;
154 struct acpi_buffer namebuf = {ACPI_ALLOCATE_BUFFER, NULL};
155 char *pathname;
156 struct acpi_buffer buffer;
157 struct acpi_device_info *dinfo;
158
159 status = acpi_get_name(handle, ACPI_FULL_PATHNAME, &namebuf);
160 if (status)
161 goto ret;
162 pathname = namebuf.pointer;
163
164 buffer.length = ACPI_ALLOCATE_BUFFER;
165 buffer.pointer = NULL;
166 status = acpi_get_object_info(handle, &buffer);
167 if (ACPI_FAILURE(status))
168 goto out2;
169
170 dinfo = buffer.pointer;
171
172 /* find full device path name for pcidevfn */
173 if (dinfo && (dinfo->valid & ACPI_VALID_ADR) &&
174 dinfo->address == winfo->pcidevfn) {
175 if (ata_msg_probe(winfo->ataport))
176 ata_dev_printk(winfo->atadev, KERN_DEBUG,
177 ":%s: matches pcidevfn (0x%llx)\n",
178 pathname, winfo->pcidevfn);
179 strlcpy(winfo->basepath, pathname,
180 sizeof(winfo->basepath));
181 winfo->basepath_len = strlen(pathname);
182 goto out;
183 } 144 }
184 145
185 /* if basepath is not yet known, ignore this object */ 146 if (out_obj->buffer.length != sizeof(struct ata_acpi_gtm)) {
186 if (!winfo->basepath_len) 147 ata_port_printk(ap, KERN_ERR,
187 goto out; 148 "_GTM returned invalid length %d\n",
188 149 out_obj->buffer.length);
189 /* if this object is in scope of basepath, maybe use it */ 150 goto out_free;
190 if (strncmp(pathname, winfo->basepath,
191 winfo->basepath_len) == 0) {
192 if (!(dinfo->valid & ACPI_VALID_ADR))
193 goto out;
194 if (ata_msg_probe(winfo->ataport))
195 ata_dev_printk(winfo->atadev, KERN_DEBUG,
196 "GOT ONE: (%s) root_port = 0x%llx,"
197 " port_num = 0x%llx\n", pathname,
198 SATA_ROOT_PORT(dinfo->address),
199 SATA_PORT_NUMBER(dinfo->address));
200 /* heuristics: */
201 if (SATA_PORT_NUMBER(dinfo->address) != NO_PORT_MULT)
202 if (ata_msg_probe(winfo->ataport))
203 ata_dev_printk(winfo->atadev,
204 KERN_DEBUG, "warning: don't"
205 " know how to handle SATA port"
206 " multiplier\n");
207 if (SATA_ROOT_PORT(dinfo->address) ==
208 winfo->ataport->port_no &&
209 SATA_PORT_NUMBER(dinfo->address) == NO_PORT_MULT) {
210 if (ata_msg_probe(winfo->ataport))
211 ata_dev_printk(winfo->atadev,
212 KERN_DEBUG,
213 "THIS ^^^^^ is the requested"
214 " SATA drive (handle = 0x%p)\n",
215 handle);
216 winfo->sata_adr = dinfo->address;
217 winfo->obj_handle = handle;
218 }
219 } 151 }
220out:
221 kfree(dinfo);
222out2:
223 kfree(pathname);
224 152
225ret: 153 memcpy(gtm, out_obj->buffer.pointer, sizeof(struct ata_acpi_gtm));
226 return status; 154 rc = 0;
155 out_free:
156 kfree(output.pointer);
157 return rc;
227} 158}
228 159
229/* Get the SATA drive _ADR object. */ 160/**
230static int get_sata_adr(struct device *dev, acpi_handle handle, 161 * ata_acpi_stm - execute _STM
231 acpi_integer pcidevfn, unsigned int drive, 162 * @ap: target ATA port
232 struct ata_port *ap, 163 * @stm: timing parameter to _STM
233 struct ata_device *atadev, u32 *dev_adr) 164 *
165 * Evaluate _STM with timing parameter @stm.
166 *
167 * LOCKING:
168 * EH context.
169 *
170 * RETURNS:
171 * 0 on success, -ENOENT if _STM doesn't exist, -errno on failure.
172 */
173static int ata_acpi_stm(const struct ata_port *ap, struct ata_acpi_gtm *stm)
234{ 174{
235 acpi_status status; 175 acpi_status status;
236 struct walk_info *winfo; 176 struct acpi_object_list input;
237 int err = -ENOMEM; 177 union acpi_object in_params[3];
238
239 winfo = kzalloc(sizeof(struct walk_info), GFP_KERNEL);
240 if (!winfo)
241 goto out;
242
243 winfo->dev = dev;
244 winfo->atadev = atadev;
245 winfo->ataport = ap;
246 if (acpi_bus_get_device(handle, &winfo->adev) < 0)
247 if (ata_msg_probe(ap))
248 ata_dev_printk(winfo->atadev, KERN_DEBUG,
249 "acpi_bus_get_device failed\n");
250 winfo->handle = handle;
251 winfo->pcidevfn = pcidevfn;
252 winfo->drivenum = drive;
253 178
254 status = acpi_get_devices(NULL, get_devices, winfo, NULL); 179 in_params[0].type = ACPI_TYPE_BUFFER;
180 in_params[0].buffer.length = sizeof(struct ata_acpi_gtm);
181 in_params[0].buffer.pointer = (u8 *)stm;
182 /* Buffers for id may need byteswapping ? */
183 in_params[1].type = ACPI_TYPE_BUFFER;
184 in_params[1].buffer.length = 512;
185 in_params[1].buffer.pointer = (u8 *)ap->device[0].id;
186 in_params[2].type = ACPI_TYPE_BUFFER;
187 in_params[2].buffer.length = 512;
188 in_params[2].buffer.pointer = (u8 *)ap->device[1].id;
189
190 input.count = 3;
191 input.pointer = in_params;
192
193 status = acpi_evaluate_object(ap->acpi_handle, "_STM", &input, NULL);
194
195 if (status == AE_NOT_FOUND)
196 return -ENOENT;
255 if (ACPI_FAILURE(status)) { 197 if (ACPI_FAILURE(status)) {
256 if (ata_msg_probe(ap)) 198 ata_port_printk(ap, KERN_ERR,
257 ata_dev_printk(winfo->atadev, KERN_DEBUG, 199 "ACPI set timing mode failed (status=0x%x)\n", status);
258 "%s: acpi_get_devices failed\n", 200 return -EINVAL;
259 __FUNCTION__);
260 err = -ENODEV;
261 } else {
262 *dev_adr = winfo->sata_adr;
263 atadev->obj_handle = winfo->obj_handle;
264 err = 0;
265 } 201 }
266 kfree(winfo); 202 return 0;
267out:
268 return err;
269} 203}
270 204
271/** 205/**
272 * do_drive_get_GTF - get the drive bootup default taskfile settings 206 * ata_dev_get_GTF - get the drive bootup default taskfile settings
273 * @dev: target ATA device 207 * @dev: target ATA device
274 * @gtf_length: number of bytes of _GTF data returned at @gtf_address 208 * @gtf: output parameter for buffer containing _GTF taskfile arrays
275 * @gtf_address: buffer containing _GTF taskfile arrays 209 * @ptr_to_free: pointer which should be freed
276 * 210 *
277 * This applies to both PATA and SATA drives. 211 * This applies to both PATA and SATA drives.
278 * 212 *
@@ -282,121 +216,41 @@ out:
282 * The <variable number> is not known in advance, so have ACPI-CA 216 * The <variable number> is not known in advance, so have ACPI-CA
283 * allocate the buffer as needed and return it, then free it later. 217 * allocate the buffer as needed and return it, then free it later.
284 * 218 *
285 * The returned @gtf_length and @gtf_address are only valid if the 219 * LOCKING:
286 * function return value is 0. 220 * EH context.
221 *
222 * RETURNS:
223 * Number of taskfiles on success, 0 if _GTF doesn't exist or doesn't
224 * contain valid data. -errno on other errors.
287 */ 225 */
288static int do_drive_get_GTF(struct ata_device *dev, unsigned int *gtf_length, 226static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf,
289 unsigned long *gtf_address, unsigned long *obj_loc) 227 void **ptr_to_free)
290{ 228{
291 struct ata_port *ap = dev->ap; 229 struct ata_port *ap = dev->ap;
292 acpi_status status; 230 acpi_status status;
293 acpi_handle dev_handle = NULL;
294 acpi_handle chan_handle, drive_handle;
295 acpi_integer pcidevfn = 0;
296 u32 dev_adr;
297 struct acpi_buffer output; 231 struct acpi_buffer output;
298 union acpi_object *out_obj; 232 union acpi_object *out_obj;
299 struct device *gdev = ap->host->dev; 233 int rc = 0;
300 int err = -ENODEV;
301 234
302 *gtf_length = 0; 235 /* set up output buffer */
303 *gtf_address = 0UL; 236 output.length = ACPI_ALLOCATE_BUFFER;
304 *obj_loc = 0UL; 237 output.pointer = NULL; /* ACPI-CA sets this; save/free it later */
305
306 if (libata_noacpi)
307 return 0;
308 238
309 if (ata_msg_probe(ap)) 239 if (ata_msg_probe(ap))
310 ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER: port#: %d\n", 240 ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER: port#: %d\n",
311 __FUNCTION__, ap->port_no); 241 __FUNCTION__, ap->port_no);
312 242
313 if (!ata_dev_enabled(dev) || (ap->flags & ATA_FLAG_DISABLED)) {
314 if (ata_msg_probe(ap))
315 ata_dev_printk(dev, KERN_DEBUG, "%s: ERR: "
316 "ata_dev_present: %d, PORT_DISABLED: %lu\n",
317 __FUNCTION__, ata_dev_enabled(dev),
318 ap->flags & ATA_FLAG_DISABLED);
319 goto out;
320 }
321
322 /* Don't continue if device has no _ADR method.
323 * _GTF is intended for known motherboard devices. */
324 if (!(ap->flags & ATA_FLAG_ACPI_SATA)) {
325 err = pata_get_dev_handle(gdev, &dev_handle, &pcidevfn);
326 if (err < 0) {
327 if (ata_msg_probe(ap))
328 ata_dev_printk(dev, KERN_DEBUG,
329 "%s: pata_get_dev_handle failed (%d)\n",
330 __FUNCTION__, err);
331 goto out;
332 }
333 } else {
334 err = sata_get_dev_handle(gdev, &dev_handle, &pcidevfn);
335 if (err < 0) {
336 if (ata_msg_probe(ap))
337 ata_dev_printk(dev, KERN_DEBUG,
338 "%s: sata_get_dev_handle failed (%d\n",
339 __FUNCTION__, err);
340 goto out;
341 }
342 }
343
344 /* Get this drive's _ADR info. if not already known. */
345 if (!dev->obj_handle) {
346 if (!(ap->flags & ATA_FLAG_ACPI_SATA)) {
347 /* get child objects of dev_handle == channel objects,
348 * + _their_ children == drive objects */
349 /* channel is ap->port_no */
350 chan_handle = acpi_get_child(dev_handle,
351 ap->port_no);
352 if (ata_msg_probe(ap))
353 ata_dev_printk(dev, KERN_DEBUG,
354 "%s: chan adr=%d: chan_handle=0x%p\n",
355 __FUNCTION__, ap->port_no,
356 chan_handle);
357 if (!chan_handle) {
358 err = -ENODEV;
359 goto out;
360 }
361 /* TBD: could also check ACPI object VALID bits */
362 drive_handle = acpi_get_child(chan_handle, dev->devno);
363 if (!drive_handle) {
364 err = -ENODEV;
365 goto out;
366 }
367 dev_adr = dev->devno;
368 dev->obj_handle = drive_handle;
369 } else { /* for SATA mode */
370 dev_adr = SATA_ADR_RSVD;
371 err = get_sata_adr(gdev, dev_handle, pcidevfn, 0,
372 ap, dev, &dev_adr);
373 }
374 if (err < 0 || dev_adr == SATA_ADR_RSVD ||
375 !dev->obj_handle) {
376 if (ata_msg_probe(ap))
377 ata_dev_printk(dev, KERN_DEBUG,
378 "%s: get_sata/pata_adr failed: "
379 "err=%d, dev_adr=%u, obj_handle=0x%p\n",
380 __FUNCTION__, err, dev_adr,
381 dev->obj_handle);
382 goto out;
383 }
384 }
385
386 /* Setting up output buffer */
387 output.length = ACPI_ALLOCATE_BUFFER;
388 output.pointer = NULL; /* ACPI-CA sets this; save/free it later */
389
390 /* _GTF has no input parameters */ 243 /* _GTF has no input parameters */
391 err = -EIO; 244 status = acpi_evaluate_object(dev->acpi_handle, "_GTF", NULL, &output);
392 status = acpi_evaluate_object(dev->obj_handle, "_GTF", 245
393 NULL, &output);
394 if (ACPI_FAILURE(status)) { 246 if (ACPI_FAILURE(status)) {
395 if (ata_msg_probe(ap)) 247 if (status != AE_NOT_FOUND) {
396 ata_dev_printk(dev, KERN_DEBUG, 248 ata_dev_printk(dev, KERN_WARNING,
397 "%s: Run _GTF error: status = 0x%x\n", 249 "_GTF evaluation failed (AE 0x%x)\n",
398 __FUNCTION__, status); 250 status);
399 goto out; 251 rc = -EIO;
252 }
253 goto out_free;
400 } 254 }
401 255
402 if (!output.length || !output.pointer) { 256 if (!output.length || !output.pointer) {
@@ -406,43 +260,39 @@ static int do_drive_get_GTF(struct ata_device *dev, unsigned int *gtf_length,
406 __FUNCTION__, 260 __FUNCTION__,
407 (unsigned long long)output.length, 261 (unsigned long long)output.length,
408 output.pointer); 262 output.pointer);
409 kfree(output.pointer); 263 goto out_free;
410 goto out;
411 } 264 }
412 265
413 out_obj = output.pointer; 266 out_obj = output.pointer;
414 if (out_obj->type != ACPI_TYPE_BUFFER) { 267 if (out_obj->type != ACPI_TYPE_BUFFER) {
415 kfree(output.pointer); 268 ata_dev_printk(dev, KERN_WARNING,
416 if (ata_msg_probe(ap)) 269 "_GTF unexpected object type 0x%x\n",
417 ata_dev_printk(dev, KERN_DEBUG, "%s: Run _GTF: " 270 out_obj->type);
418 "error: expected object type of " 271 rc = -EINVAL;
419 " ACPI_TYPE_BUFFER, got 0x%x\n", 272 goto out_free;
420 __FUNCTION__, out_obj->type);
421 err = -ENOENT;
422 goto out;
423 } 273 }
424 274
425 if (!out_obj->buffer.length || !out_obj->buffer.pointer || 275 if (out_obj->buffer.length % REGS_PER_GTF) {
426 out_obj->buffer.length % REGS_PER_GTF) { 276 ata_dev_printk(dev, KERN_WARNING,
427 if (ata_msg_drv(ap)) 277 "unexpected _GTF length (%d)\n",
428 ata_dev_printk(dev, KERN_ERR, 278 out_obj->buffer.length);
429 "%s: unexpected GTF length (%d) or addr (0x%p)\n", 279 rc = -EINVAL;
430 __FUNCTION__, out_obj->buffer.length, 280 goto out_free;
431 out_obj->buffer.pointer);
432 err = -ENOENT;
433 goto out;
434 } 281 }
435 282
436 *gtf_length = out_obj->buffer.length; 283 *ptr_to_free = out_obj;
437 *gtf_address = (unsigned long)out_obj->buffer.pointer; 284 *gtf = (void *)out_obj->buffer.pointer;
438 *obj_loc = (unsigned long)out_obj; 285 rc = out_obj->buffer.length / REGS_PER_GTF;
286
439 if (ata_msg_probe(ap)) 287 if (ata_msg_probe(ap))
440 ata_dev_printk(dev, KERN_DEBUG, "%s: returning " 288 ata_dev_printk(dev, KERN_DEBUG, "%s: returning "
441 "gtf_length=%d, gtf_address=0x%lx, obj_loc=0x%lx\n", 289 "gtf=%p, gtf_count=%d, ptr_to_free=%p\n",
442 __FUNCTION__, *gtf_length, *gtf_address, *obj_loc); 290 __FUNCTION__, *gtf, rc, *ptr_to_free);
443 err = 0; 291 return rc;
444out: 292
445 return err; 293 out_free:
294 kfree(output.pointer);
295 return rc;
446} 296}
447 297
448/** 298/**
@@ -461,154 +311,99 @@ out:
461 * function also waits for idle after writing control and before 311 * function also waits for idle after writing control and before
462 * writing the remaining registers. 312 * writing the remaining registers.
463 * 313 *
464 * LOCKING: TBD: 314 * LOCKING:
465 * Inherited from caller. 315 * EH context.
316 *
317 * RETURNS:
318 * 0 on success, -errno on failure.
466 */ 319 */
467static void taskfile_load_raw(struct ata_device *dev, 320static int taskfile_load_raw(struct ata_device *dev,
468 const struct taskfile_array *gtf) 321 const struct ata_acpi_gtf *gtf)
469{ 322{
470 struct ata_port *ap = dev->ap; 323 struct ata_port *ap = dev->ap;
471 struct ata_taskfile tf; 324 struct ata_taskfile tf, rtf;
472 unsigned int err; 325 unsigned int err_mask;
473 326
474 if (ata_msg_probe(ap)) 327 if ((gtf->tf[0] == 0) && (gtf->tf[1] == 0) && (gtf->tf[2] == 0)
475 ata_dev_printk(dev, KERN_DEBUG, "%s: (0x1f1-1f7): hex: " 328 && (gtf->tf[3] == 0) && (gtf->tf[4] == 0) && (gtf->tf[5] == 0)
476 "%02x %02x %02x %02x %02x %02x %02x\n", 329 && (gtf->tf[6] == 0))
477 __FUNCTION__, 330 return 0;
478 gtf->tfa[0], gtf->tfa[1], gtf->tfa[2],
479 gtf->tfa[3], gtf->tfa[4], gtf->tfa[5], gtf->tfa[6]);
480
481 if ((gtf->tfa[0] == 0) && (gtf->tfa[1] == 0) && (gtf->tfa[2] == 0)
482 && (gtf->tfa[3] == 0) && (gtf->tfa[4] == 0) && (gtf->tfa[5] == 0)
483 && (gtf->tfa[6] == 0))
484 return;
485 331
486 ata_tf_init(dev, &tf); 332 ata_tf_init(dev, &tf);
487 333
488 /* convert gtf to tf */ 334 /* convert gtf to tf */
489 tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; /* TBD */ 335 tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; /* TBD */
490 tf.protocol = ATA_PROT_NODATA; 336 tf.protocol = ATA_PROT_NODATA;
491 tf.feature = gtf->tfa[0]; /* 0x1f1 */ 337 tf.feature = gtf->tf[0]; /* 0x1f1 */
492 tf.nsect = gtf->tfa[1]; /* 0x1f2 */ 338 tf.nsect = gtf->tf[1]; /* 0x1f2 */
493 tf.lbal = gtf->tfa[2]; /* 0x1f3 */ 339 tf.lbal = gtf->tf[2]; /* 0x1f3 */
494 tf.lbam = gtf->tfa[3]; /* 0x1f4 */ 340 tf.lbam = gtf->tf[3]; /* 0x1f4 */
495 tf.lbah = gtf->tfa[4]; /* 0x1f5 */ 341 tf.lbah = gtf->tf[4]; /* 0x1f5 */
496 tf.device = gtf->tfa[5]; /* 0x1f6 */ 342 tf.device = gtf->tf[5]; /* 0x1f6 */
497 tf.command = gtf->tfa[6]; /* 0x1f7 */ 343 tf.command = gtf->tf[6]; /* 0x1f7 */
498
499 err = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0);
500 if (err && ata_msg_probe(ap))
501 ata_dev_printk(dev, KERN_ERR,
502 "%s: ata_exec_internal failed: %u\n",
503 __FUNCTION__, err);
504}
505
506/**
507 * do_drive_set_taskfiles - write the drive taskfile settings from _GTF
508 * @dev: target ATA device
509 * @gtf_length: total number of bytes of _GTF taskfiles
510 * @gtf_address: location of _GTF taskfile arrays
511 *
512 * This applies to both PATA and SATA drives.
513 *
514 * Write {gtf_address, length gtf_length} in groups of
515 * REGS_PER_GTF bytes.
516 */
517static int do_drive_set_taskfiles(struct ata_device *dev,
518 unsigned int gtf_length,
519 unsigned long gtf_address)
520{
521 struct ata_port *ap = dev->ap;
522 int err = -ENODEV;
523 int gtf_count = gtf_length / REGS_PER_GTF;
524 int ix;
525 struct taskfile_array *gtf;
526 344
527 if (ata_msg_probe(ap)) 345 if (ata_msg_probe(ap))
528 ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER: port#: %d\n", 346 ata_dev_printk(dev, KERN_DEBUG, "executing ACPI cmd "
529 __FUNCTION__, ap->port_no); 347 "%02x/%02x:%02x:%02x:%02x:%02x:%02x\n",
530 348 tf.command, tf.feature, tf.nsect,
531 if (libata_noacpi || !(ap->flags & ATA_FLAG_ACPI_SATA)) 349 tf.lbal, tf.lbam, tf.lbah, tf.device);
532 return 0; 350
533 351 rtf = tf;
534 if (!ata_dev_enabled(dev) || (ap->flags & ATA_FLAG_DISABLED)) 352 err_mask = ata_exec_internal(dev, &rtf, NULL, DMA_NONE, NULL, 0);
535 goto out; 353 if (err_mask) {
536 if (!gtf_count) /* shouldn't be here */ 354 ata_dev_printk(dev, KERN_ERR,
537 goto out; 355 "ACPI cmd %02x/%02x:%02x:%02x:%02x:%02x:%02x failed "
538 356 "(Emask=0x%x Stat=0x%02x Err=0x%02x)\n",
539 if (gtf_length % REGS_PER_GTF) { 357 tf.command, tf.feature, tf.nsect, tf.lbal, tf.lbam,
540 if (ata_msg_drv(ap)) 358 tf.lbah, tf.device, err_mask, rtf.command, rtf.feature);
541 ata_dev_printk(dev, KERN_ERR, 359 return -EIO;
542 "%s: unexpected GTF length (%d)\n",
543 __FUNCTION__, gtf_length);
544 goto out;
545 }
546
547 for (ix = 0; ix < gtf_count; ix++) {
548 gtf = (struct taskfile_array *)
549 (gtf_address + ix * REGS_PER_GTF);
550
551 /* send all TaskFile registers (0x1f1-0x1f7) *in*that*order* */
552 taskfile_load_raw(dev, gtf);
553 } 360 }
554 361
555 err = 0; 362 return 0;
556out:
557 return err;
558} 363}
559 364
560/** 365/**
561 * ata_acpi_exec_tfs - get then write drive taskfile settings 366 * ata_acpi_exec_tfs - get then write drive taskfile settings
562 * @ap: the ata_port for the drive 367 * @dev: target ATA device
563 * 368 *
564 * This applies to both PATA and SATA drives. 369 * Evaluate _GTF and excute returned taskfiles.
370 *
371 * LOCKING:
372 * EH context.
373 *
374 * RETURNS:
375 * Number of executed taskfiles on success, 0 if _GTF doesn't exist or
376 * doesn't contain valid data. -errno on other errors.
565 */ 377 */
566int ata_acpi_exec_tfs(struct ata_port *ap) 378static int ata_acpi_exec_tfs(struct ata_device *dev)
567{ 379{
568 int ix; 380 struct ata_acpi_gtf *gtf = NULL;
569 int ret = 0; 381 void *ptr_to_free = NULL;
570 unsigned int gtf_length; 382 int gtf_count, i, rc;
571 unsigned long gtf_address; 383
572 unsigned long obj_loc; 384 /* get taskfiles */
573 385 rc = ata_dev_get_GTF(dev, &gtf, &ptr_to_free);
574 if (libata_noacpi) 386 if (rc < 0)
575 return 0; 387 return rc;
576 /* 388 gtf_count = rc;
577 * TBD - implement PATA support. For now, 389
578 * we should not run GTF on PATA devices since some 390 /* execute them */
579 * PATA require execution of GTM/STM before GTF. 391 for (i = 0, rc = 0; i < gtf_count; i++) {
580 */ 392 int tmp;
581 if (!(ap->flags & ATA_FLAG_ACPI_SATA)) 393
582 return 0; 394 /* ACPI errors are eventually ignored. Run till the
583 395 * end even after errors.
584 for (ix = 0; ix < ATA_MAX_DEVICES; ix++) { 396 */
585 struct ata_device *dev = &ap->device[ix]; 397 tmp = taskfile_load_raw(dev, gtf++);
586 398 if (!rc)
587 if (!ata_dev_enabled(dev)) 399 rc = tmp;
588 continue;
589
590 ret = do_drive_get_GTF(dev, &gtf_length, &gtf_address,
591 &obj_loc);
592 if (ret < 0) {
593 if (ata_msg_probe(ap))
594 ata_port_printk(ap, KERN_DEBUG,
595 "%s: get_GTF error (%d)\n",
596 __FUNCTION__, ret);
597 break;
598 }
599
600 ret = do_drive_set_taskfiles(dev, gtf_length, gtf_address);
601 kfree((void *)obj_loc);
602 if (ret < 0) {
603 if (ata_msg_probe(ap))
604 ata_port_printk(ap, KERN_DEBUG,
605 "%s: set_taskfiles error (%d)\n",
606 __FUNCTION__, ret);
607 break;
608 }
609 } 400 }
610 401
611 return ret; 402 kfree(ptr_to_free);
403
404 if (rc == 0)
405 return gtf_count;
406 return rc;
612} 407}
613 408
614/** 409/**
@@ -620,62 +415,25 @@ int ata_acpi_exec_tfs(struct ata_port *ap)
620 * ATM this function never returns a failure. It is an optional 415 * ATM this function never returns a failure. It is an optional
621 * method and if it fails for whatever reason, we should still 416 * method and if it fails for whatever reason, we should still
622 * just keep going. 417 * just keep going.
418 *
419 * LOCKING:
420 * EH context.
421 *
422 * RETURNS:
423 * 0 on success, -errno on failure.
623 */ 424 */
624int ata_acpi_push_id(struct ata_device *dev) 425static int ata_acpi_push_id(struct ata_device *dev)
625{ 426{
626 struct ata_port *ap = dev->ap; 427 struct ata_port *ap = dev->ap;
627 acpi_handle handle;
628 acpi_integer pcidevfn;
629 int err; 428 int err;
630 struct device *gdev = ap->host->dev;
631 u32 dev_adr;
632 acpi_status status; 429 acpi_status status;
633 struct acpi_object_list input; 430 struct acpi_object_list input;
634 union acpi_object in_params[1]; 431 union acpi_object in_params[1];
635 432
636 if (libata_noacpi)
637 return 0;
638
639 if (ata_msg_probe(ap)) 433 if (ata_msg_probe(ap))
640 ata_dev_printk(dev, KERN_DEBUG, "%s: ix = %d, port#: %d\n", 434 ata_dev_printk(dev, KERN_DEBUG, "%s: ix = %d, port#: %d\n",
641 __FUNCTION__, dev->devno, ap->port_no); 435 __FUNCTION__, dev->devno, ap->port_no);
642 436
643 /* Don't continue if not a SATA device. */
644 if (!(ap->flags & ATA_FLAG_ACPI_SATA)) {
645 if (ata_msg_probe(ap))
646 ata_dev_printk(dev, KERN_DEBUG,
647 "%s: Not a SATA device\n", __FUNCTION__);
648 goto out;
649 }
650
651 /* Don't continue if device has no _ADR method.
652 * _SDD is intended for known motherboard devices. */
653 err = sata_get_dev_handle(gdev, &handle, &pcidevfn);
654 if (err < 0) {
655 if (ata_msg_probe(ap))
656 ata_dev_printk(dev, KERN_DEBUG,
657 "%s: sata_get_dev_handle failed (%d\n",
658 __FUNCTION__, err);
659 goto out;
660 }
661
662 /* Get this drive's _ADR info, if not already known */
663 if (!dev->obj_handle) {
664 dev_adr = SATA_ADR_RSVD;
665 err = get_sata_adr(gdev, handle, pcidevfn, dev->devno, ap, dev,
666 &dev_adr);
667 if (err < 0 || dev_adr == SATA_ADR_RSVD ||
668 !dev->obj_handle) {
669 if (ata_msg_probe(ap))
670 ata_dev_printk(dev, KERN_DEBUG,
671 "%s: get_sata_adr failed: "
672 "err=%d, dev_adr=%u, obj_handle=0x%p\n",
673 __FUNCTION__, err, dev_adr,
674 dev->obj_handle);
675 goto out;
676 }
677 }
678
679 /* Give the drive Identify data to the drive via the _SDD method */ 437 /* Give the drive Identify data to the drive via the _SDD method */
680 /* _SDD: set up input parameters */ 438 /* _SDD: set up input parameters */
681 input.count = 1; 439 input.count = 1;
@@ -687,20 +445,150 @@ int ata_acpi_push_id(struct ata_device *dev)
687 445
688 /* It's OK for _SDD to be missing too. */ 446 /* It's OK for _SDD to be missing too. */
689 swap_buf_le16(dev->id, ATA_ID_WORDS); 447 swap_buf_le16(dev->id, ATA_ID_WORDS);
690 status = acpi_evaluate_object(dev->obj_handle, "_SDD", &input, NULL); 448 status = acpi_evaluate_object(dev->acpi_handle, "_SDD", &input, NULL);
691 swap_buf_le16(dev->id, ATA_ID_WORDS); 449 swap_buf_le16(dev->id, ATA_ID_WORDS);
692 450
693 err = ACPI_FAILURE(status) ? -EIO : 0; 451 err = ACPI_FAILURE(status) ? -EIO : 0;
694 if (err < 0) { 452 if (err < 0)
695 if (ata_msg_probe(ap)) 453 ata_dev_printk(dev, KERN_WARNING,
696 ata_dev_printk(dev, KERN_DEBUG, 454 "ACPI _SDD failed (AE 0x%x)\n", status);
697 "%s _SDD error: status = 0x%x\n", 455
698 __FUNCTION__, status); 456 return err;
457}
458
459/**
460 * ata_acpi_on_suspend - ATA ACPI hook called on suspend
461 * @ap: target ATA port
462 *
463 * This function is called when @ap is about to be suspended. All
464 * devices are already put to sleep but the port_suspend() callback
465 * hasn't been executed yet. Error return from this function aborts
466 * suspend.
467 *
468 * LOCKING:
469 * EH context.
470 *
471 * RETURNS:
472 * 0 on success, -errno on failure.
473 */
474int ata_acpi_on_suspend(struct ata_port *ap)
475{
476 unsigned long flags;
477 int rc;
478
479 /* proceed iff per-port acpi_handle is valid */
480 if (!ap->acpi_handle)
481 return 0;
482 BUG_ON(ap->flags & ATA_FLAG_ACPI_SATA);
483
484 /* store timing parameters */
485 rc = ata_acpi_gtm(ap, &ap->acpi_gtm);
486
487 spin_lock_irqsave(ap->lock, flags);
488 if (rc == 0)
489 ap->pflags |= ATA_PFLAG_GTM_VALID;
490 else
491 ap->pflags &= ~ATA_PFLAG_GTM_VALID;
492 spin_unlock_irqrestore(ap->lock, flags);
493
494 if (rc == -ENOENT)
495 rc = 0;
496 return rc;
497}
498
499/**
500 * ata_acpi_on_resume - ATA ACPI hook called on resume
501 * @ap: target ATA port
502 *
503 * This function is called when @ap is resumed - right after port
504 * itself is resumed but before any EH action is taken.
505 *
506 * LOCKING:
507 * EH context.
508 */
509void ata_acpi_on_resume(struct ata_port *ap)
510{
511 int i;
512
513 if (ap->acpi_handle && (ap->pflags & ATA_PFLAG_GTM_VALID)) {
514 BUG_ON(ap->flags & ATA_FLAG_ACPI_SATA);
515
516 /* restore timing parameters */
517 ata_acpi_stm(ap, &ap->acpi_gtm);
699 } 518 }
700 519
701 /* always return success */ 520 /* schedule _GTF */
702out: 521 for (i = 0; i < ATA_MAX_DEVICES; i++)
703 return 0; 522 ap->device[i].flags |= ATA_DFLAG_ACPI_PENDING;
704} 523}
705 524
525/**
526 * ata_acpi_on_devcfg - ATA ACPI hook called on device donfiguration
527 * @dev: target ATA device
528 *
529 * This function is called when @dev is about to be configured.
530 * IDENTIFY data might have been modified after this hook is run.
531 *
532 * LOCKING:
533 * EH context.
534 *
535 * RETURNS:
536 * Positive number if IDENTIFY data needs to be refreshed, 0 if not,
537 * -errno on failure.
538 */
539int ata_acpi_on_devcfg(struct ata_device *dev)
540{
541 struct ata_port *ap = dev->ap;
542 struct ata_eh_context *ehc = &ap->eh_context;
543 int acpi_sata = ap->flags & ATA_FLAG_ACPI_SATA;
544 int rc;
545
546 if (!dev->acpi_handle)
547 return 0;
548
549 /* do we need to do _GTF? */
550 if (!(dev->flags & ATA_DFLAG_ACPI_PENDING) &&
551 !(acpi_sata && (ehc->i.flags & ATA_EHI_DID_HARDRESET)))
552 return 0;
553
554 /* do _SDD if SATA */
555 if (acpi_sata) {
556 rc = ata_acpi_push_id(dev);
557 if (rc)
558 goto acpi_err;
559 }
560
561 /* do _GTF */
562 rc = ata_acpi_exec_tfs(dev);
563 if (rc < 0)
564 goto acpi_err;
565
566 dev->flags &= ~ATA_DFLAG_ACPI_PENDING;
567
568 /* refresh IDENTIFY page if any _GTF command has been executed */
569 if (rc > 0) {
570 rc = ata_dev_reread_id(dev, 0);
571 if (rc < 0) {
572 ata_dev_printk(dev, KERN_ERR, "failed to IDENTIFY "
573 "after ACPI commands\n");
574 return rc;
575 }
576 }
706 577
578 return 0;
579
580 acpi_err:
581 /* let EH retry on the first failure, disable ACPI on the second */
582 if (dev->flags & ATA_DFLAG_ACPI_FAILED) {
583 ata_dev_printk(dev, KERN_WARNING, "ACPI on devcfg failed the "
584 "second time, disabling (errno=%d)\n", rc);
585
586 dev->acpi_handle = NULL;
587
588 /* if port is working, request IDENTIFY reload and continue */
589 if (!(ap->pflags & ATA_PFLAG_FROZEN))
590 rc = 1;
591 }
592 dev->flags |= ATA_DFLAG_ACPI_FAILED;
593 return rc;
594}
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 981b397cb46b..5b25311ba885 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -1845,7 +1845,8 @@ static void ata_dev_config_ncq(struct ata_device *dev,
1845int ata_dev_configure(struct ata_device *dev) 1845int ata_dev_configure(struct ata_device *dev)
1846{ 1846{
1847 struct ata_port *ap = dev->ap; 1847 struct ata_port *ap = dev->ap;
1848 int print_info = ap->eh_context.i.flags & ATA_EHI_PRINTINFO; 1848 struct ata_eh_context *ehc = &ap->eh_context;
1849 int print_info = ehc->i.flags & ATA_EHI_PRINTINFO;
1849 const u16 *id = dev->id; 1850 const u16 *id = dev->id;
1850 unsigned int xfer_mask; 1851 unsigned int xfer_mask;
1851 char revbuf[7]; /* XYZ-99\0 */ 1852 char revbuf[7]; /* XYZ-99\0 */
@@ -1862,15 +1863,10 @@ int ata_dev_configure(struct ata_device *dev)
1862 if (ata_msg_probe(ap)) 1863 if (ata_msg_probe(ap))
1863 ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER\n", __FUNCTION__); 1864 ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER\n", __FUNCTION__);
1864 1865
1865 /* set _SDD */ 1866 /* let ACPI work its magic */
1866 rc = ata_acpi_push_id(dev); 1867 rc = ata_acpi_on_devcfg(dev);
1867 if (rc) { 1868 if (rc)
1868 ata_dev_printk(dev, KERN_WARNING, "failed to set _SDD(%d)\n", 1869 return rc;
1869 rc);
1870 }
1871
1872 /* retrieve and execute the ATA task file of _GTF */
1873 ata_acpi_exec_tfs(ap);
1874 1870
1875 /* print device capabilities */ 1871 /* print device capabilities */
1876 if (ata_msg_probe(ap)) 1872 if (ata_msg_probe(ap))
@@ -3359,7 +3355,7 @@ int ata_std_prereset(struct ata_port *ap, unsigned long deadline)
3359 return 0; 3355 return 0;
3360 3356
3361 /* if SATA, resume phy */ 3357 /* if SATA, resume phy */
3362 if (ap->cbl == ATA_CBL_SATA) { 3358 if (ap->flags & ATA_FLAG_SATA) {
3363 rc = sata_phy_resume(ap, timing, deadline); 3359 rc = sata_phy_resume(ap, timing, deadline);
3364 /* whine about phy resume failure but proceed */ 3360 /* whine about phy resume failure but proceed */
3365 if (rc && rc != -EOPNOTSUPP) 3361 if (rc && rc != -EOPNOTSUPP)
@@ -4107,6 +4103,68 @@ static void ata_fill_sg(struct ata_queued_cmd *qc)
4107} 4103}
4108 4104
4109/** 4105/**
4106 * ata_fill_sg_dumb - Fill PCI IDE PRD table
4107 * @qc: Metadata associated with taskfile to be transferred
4108 *
4109 * Fill PCI IDE PRD (scatter-gather) table with segments
4110 * associated with the current disk command. Perform the fill
4111 * so that we avoid writing any length 64K records for
4112 * controllers that don't follow the spec.
4113 *
4114 * LOCKING:
4115 * spin_lock_irqsave(host lock)
4116 *
4117 */
4118static void ata_fill_sg_dumb(struct ata_queued_cmd *qc)
4119{
4120 struct ata_port *ap = qc->ap;
4121 struct scatterlist *sg;
4122 unsigned int idx;
4123
4124 WARN_ON(qc->__sg == NULL);
4125 WARN_ON(qc->n_elem == 0 && qc->pad_len == 0);
4126
4127 idx = 0;
4128 ata_for_each_sg(sg, qc) {
4129 u32 addr, offset;
4130 u32 sg_len, len, blen;
4131
4132 /* determine if physical DMA addr spans 64K boundary.
4133 * Note h/w doesn't support 64-bit, so we unconditionally
4134 * truncate dma_addr_t to u32.
4135 */
4136 addr = (u32) sg_dma_address(sg);
4137 sg_len = sg_dma_len(sg);
4138
4139 while (sg_len) {
4140 offset = addr & 0xffff;
4141 len = sg_len;
4142 if ((offset + sg_len) > 0x10000)
4143 len = 0x10000 - offset;
4144
4145 blen = len & 0xffff;
4146 ap->prd[idx].addr = cpu_to_le32(addr);
4147 if (blen == 0) {
4148 /* Some PATA chipsets like the CS5530 can't
4149 cope with 0x0000 meaning 64K as the spec says */
4150 ap->prd[idx].flags_len = cpu_to_le32(0x8000);
4151 blen = 0x8000;
4152 ap->prd[++idx].addr = cpu_to_le32(addr + 0x8000);
4153 }
4154 ap->prd[idx].flags_len = cpu_to_le32(blen);
4155 VPRINTK("PRD[%u] = (0x%X, 0x%X)\n", idx, addr, len);
4156
4157 idx++;
4158 sg_len -= len;
4159 addr += len;
4160 }
4161 }
4162
4163 if (idx)
4164 ap->prd[idx - 1].flags_len |= cpu_to_le32(ATA_PRD_EOT);
4165}
4166
4167/**
4110 * ata_check_atapi_dma - Check whether ATAPI DMA can be supported 4168 * ata_check_atapi_dma - Check whether ATAPI DMA can be supported
4111 * @qc: Metadata associated with taskfile to check 4169 * @qc: Metadata associated with taskfile to check
4112 * 4170 *
@@ -4153,6 +4211,23 @@ void ata_qc_prep(struct ata_queued_cmd *qc)
4153 ata_fill_sg(qc); 4211 ata_fill_sg(qc);
4154} 4212}
4155 4213
4214/**
4215 * ata_dumb_qc_prep - Prepare taskfile for submission
4216 * @qc: Metadata associated with taskfile to be prepared
4217 *
4218 * Prepare ATA taskfile for submission.
4219 *
4220 * LOCKING:
4221 * spin_lock_irqsave(host lock)
4222 */
4223void ata_dumb_qc_prep(struct ata_queued_cmd *qc)
4224{
4225 if (!(qc->flags & ATA_QCFLAG_DMAMAP))
4226 return;
4227
4228 ata_fill_sg_dumb(qc);
4229}
4230
4156void ata_noop_qc_prep(struct ata_queued_cmd *qc) { } 4231void ata_noop_qc_prep(struct ata_queued_cmd *qc) { }
4157 4232
4158/** 4233/**
@@ -5660,7 +5735,7 @@ irqreturn_t ata_interrupt (int irq, void *dev_instance)
5660 */ 5735 */
5661int sata_scr_valid(struct ata_port *ap) 5736int sata_scr_valid(struct ata_port *ap)
5662{ 5737{
5663 return ap->cbl == ATA_CBL_SATA && ap->ops->scr_read; 5738 return (ap->flags & ATA_FLAG_SATA) && ap->ops->scr_read;
5664} 5739}
5665 5740
5666/** 5741/**
@@ -6293,6 +6368,9 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
6293 if (rc) 6368 if (rc)
6294 return rc; 6369 return rc;
6295 6370
6371 /* associate with ACPI nodes */
6372 ata_acpi_associate(host);
6373
6296 /* set cable, sata_spd_limit and report */ 6374 /* set cable, sata_spd_limit and report */
6297 for (i = 0; i < host->n_ports; i++) { 6375 for (i = 0; i < host->n_ports; i++) {
6298 struct ata_port *ap = host->ports[i]; 6376 struct ata_port *ap = host->ports[i];
@@ -6324,7 +6402,7 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
6324 if (!ata_port_is_dummy(ap)) 6402 if (!ata_port_is_dummy(ap))
6325 ata_port_printk(ap, KERN_INFO, "%cATA max %s cmd 0x%p " 6403 ata_port_printk(ap, KERN_INFO, "%cATA max %s cmd 0x%p "
6326 "ctl 0x%p bmdma 0x%p irq %d\n", 6404 "ctl 0x%p bmdma 0x%p irq %d\n",
6327 ap->cbl == ATA_CBL_SATA ? 'S' : 'P', 6405 (ap->flags & ATA_FLAG_SATA) ? 'S' : 'P',
6328 ata_mode_string(xfer_mask), 6406 ata_mode_string(xfer_mask),
6329 ap->ioaddr.cmd_addr, 6407 ap->ioaddr.cmd_addr,
6330 ap->ioaddr.ctl_addr, 6408 ap->ioaddr.ctl_addr,
@@ -6822,6 +6900,7 @@ EXPORT_SYMBOL_GPL(ata_do_set_mode);
6822EXPORT_SYMBOL_GPL(ata_data_xfer); 6900EXPORT_SYMBOL_GPL(ata_data_xfer);
6823EXPORT_SYMBOL_GPL(ata_data_xfer_noirq); 6901EXPORT_SYMBOL_GPL(ata_data_xfer_noirq);
6824EXPORT_SYMBOL_GPL(ata_qc_prep); 6902EXPORT_SYMBOL_GPL(ata_qc_prep);
6903EXPORT_SYMBOL_GPL(ata_dumb_qc_prep);
6825EXPORT_SYMBOL_GPL(ata_noop_qc_prep); 6904EXPORT_SYMBOL_GPL(ata_noop_qc_prep);
6826EXPORT_SYMBOL_GPL(ata_bmdma_setup); 6905EXPORT_SYMBOL_GPL(ata_bmdma_setup);
6827EXPORT_SYMBOL_GPL(ata_bmdma_start); 6906EXPORT_SYMBOL_GPL(ata_bmdma_start);
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index f7582c9c320e..9ee0a8c08d96 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -2154,19 +2154,25 @@ static void ata_eh_handle_port_suspend(struct ata_port *ap)
2154 2154
2155 WARN_ON(ap->pflags & ATA_PFLAG_SUSPENDED); 2155 WARN_ON(ap->pflags & ATA_PFLAG_SUSPENDED);
2156 2156
2157 /* tell ACPI we're suspending */
2158 rc = ata_acpi_on_suspend(ap);
2159 if (rc)
2160 goto out;
2161
2157 /* suspend */ 2162 /* suspend */
2158 ata_eh_freeze_port(ap); 2163 ata_eh_freeze_port(ap);
2159 2164
2160 if (ap->ops->port_suspend) 2165 if (ap->ops->port_suspend)
2161 rc = ap->ops->port_suspend(ap, ap->pm_mesg); 2166 rc = ap->ops->port_suspend(ap, ap->pm_mesg);
2162 2167
2168 out:
2163 /* report result */ 2169 /* report result */
2164 spin_lock_irqsave(ap->lock, flags); 2170 spin_lock_irqsave(ap->lock, flags);
2165 2171
2166 ap->pflags &= ~ATA_PFLAG_PM_PENDING; 2172 ap->pflags &= ~ATA_PFLAG_PM_PENDING;
2167 if (rc == 0) 2173 if (rc == 0)
2168 ap->pflags |= ATA_PFLAG_SUSPENDED; 2174 ap->pflags |= ATA_PFLAG_SUSPENDED;
2169 else 2175 else if (ap->pflags & ATA_PFLAG_FROZEN)
2170 ata_port_schedule_eh(ap); 2176 ata_port_schedule_eh(ap);
2171 2177
2172 if (ap->pm_result) { 2178 if (ap->pm_result) {
@@ -2207,6 +2213,9 @@ static void ata_eh_handle_port_resume(struct ata_port *ap)
2207 if (ap->ops->port_resume) 2213 if (ap->ops->port_resume)
2208 rc = ap->ops->port_resume(ap); 2214 rc = ap->ops->port_resume(ap);
2209 2215
2216 /* tell ACPI that we're resuming */
2217 ata_acpi_on_resume(ap);
2218
2210 /* report result */ 2219 /* report result */
2211 spin_lock_irqsave(ap->lock, flags); 2220 spin_lock_irqsave(ap->lock, flags);
2212 ap->pflags &= ~(ATA_PFLAG_PM_PENDING | ATA_PFLAG_SUSPENDED); 2221 ap->pflags &= ~(ATA_PFLAG_PM_PENDING | ATA_PFLAG_SUSPENDED);
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 4ddf00c8c5f5..cfde22da07ac 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -2620,7 +2620,7 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc)
2620 ata_dev_printk(dev, KERN_WARNING, 2620 ata_dev_printk(dev, KERN_WARNING,
2621 "invalid multi_count %u ignored\n", 2621 "invalid multi_count %u ignored\n",
2622 multi_count); 2622 multi_count);
2623 } 2623 }
2624 2624
2625 /* READ/WRITE LONG use a non-standard sect_size */ 2625 /* READ/WRITE LONG use a non-standard sect_size */
2626 qc->sect_size = ATA_SECT_SIZE; 2626 qc->sect_size = ATA_SECT_SIZE;
diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h
index 5e2466658420..ba17fc5f2e99 100644
--- a/drivers/ata/libata.h
+++ b/drivers/ata/libata.h
@@ -98,17 +98,15 @@ extern struct ata_port *ata_port_alloc(struct ata_host *host);
98 98
99/* libata-acpi.c */ 99/* libata-acpi.c */
100#ifdef CONFIG_ATA_ACPI 100#ifdef CONFIG_ATA_ACPI
101extern int ata_acpi_exec_tfs(struct ata_port *ap); 101extern void ata_acpi_associate(struct ata_host *host);
102extern int ata_acpi_push_id(struct ata_device *dev); 102extern int ata_acpi_on_suspend(struct ata_port *ap);
103extern void ata_acpi_on_resume(struct ata_port *ap);
104extern int ata_acpi_on_devcfg(struct ata_device *adev);
103#else 105#else
104static inline int ata_acpi_exec_tfs(struct ata_port *ap) 106static inline void ata_acpi_associate(struct ata_host *host) { }
105{ 107static inline int ata_acpi_on_suspend(struct ata_port *ap) { return 0; }
106 return 0; 108static inline void ata_acpi_on_resume(struct ata_port *ap) { }
107} 109static inline int ata_acpi_on_devcfg(struct ata_device *adev) { return 0; }
108static inline int ata_acpi_push_id(struct ata_device *dev)
109{
110 return 0;
111}
112#endif 110#endif
113 111
114/* libata-scsi.c */ 112/* libata-scsi.c */
diff --git a/drivers/ata/pata_ali.c b/drivers/ata/pata_ali.c
index 75e95bdbe02f..30c4276ec882 100644
--- a/drivers/ata/pata_ali.c
+++ b/drivers/ata/pata_ali.c
@@ -520,14 +520,14 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
520{ 520{
521 static const struct ata_port_info info_early = { 521 static const struct ata_port_info info_early = {
522 .sht = &ali_sht, 522 .sht = &ali_sht,
523 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 523 .flags = ATA_FLAG_SLAVE_POSS,
524 .pio_mask = 0x1f, 524 .pio_mask = 0x1f,
525 .port_ops = &ali_early_port_ops 525 .port_ops = &ali_early_port_ops
526 }; 526 };
527 /* Revision 0x20 added DMA */ 527 /* Revision 0x20 added DMA */
528 static const struct ata_port_info info_20 = { 528 static const struct ata_port_info info_20 = {
529 .sht = &ali_sht, 529 .sht = &ali_sht,
530 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST | ATA_FLAG_PIO_LBA48, 530 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48,
531 .pio_mask = 0x1f, 531 .pio_mask = 0x1f,
532 .mwdma_mask = 0x07, 532 .mwdma_mask = 0x07,
533 .port_ops = &ali_20_port_ops 533 .port_ops = &ali_20_port_ops
@@ -535,7 +535,7 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
535 /* Revision 0x20 with support logic added UDMA */ 535 /* Revision 0x20 with support logic added UDMA */
536 static const struct ata_port_info info_20_udma = { 536 static const struct ata_port_info info_20_udma = {
537 .sht = &ali_sht, 537 .sht = &ali_sht,
538 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST | ATA_FLAG_PIO_LBA48, 538 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48,
539 .pio_mask = 0x1f, 539 .pio_mask = 0x1f,
540 .mwdma_mask = 0x07, 540 .mwdma_mask = 0x07,
541 .udma_mask = 0x07, /* UDMA33 */ 541 .udma_mask = 0x07, /* UDMA33 */
@@ -544,37 +544,37 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
544 /* Revision 0xC2 adds UDMA66 */ 544 /* Revision 0xC2 adds UDMA66 */
545 static const struct ata_port_info info_c2 = { 545 static const struct ata_port_info info_c2 = {
546 .sht = &ali_sht, 546 .sht = &ali_sht,
547 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST | ATA_FLAG_PIO_LBA48, 547 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48,
548 .pio_mask = 0x1f, 548 .pio_mask = 0x1f,
549 .mwdma_mask = 0x07, 549 .mwdma_mask = 0x07,
550 .udma_mask = 0x1f, 550 .udma_mask = ATA_UDMA4,
551 .port_ops = &ali_c2_port_ops 551 .port_ops = &ali_c2_port_ops
552 }; 552 };
553 /* Revision 0xC3 is UDMA66 for now */ 553 /* Revision 0xC3 is UDMA66 for now */
554 static const struct ata_port_info info_c3 = { 554 static const struct ata_port_info info_c3 = {
555 .sht = &ali_sht, 555 .sht = &ali_sht,
556 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST | ATA_FLAG_PIO_LBA48, 556 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48,
557 .pio_mask = 0x1f, 557 .pio_mask = 0x1f,
558 .mwdma_mask = 0x07, 558 .mwdma_mask = 0x07,
559 .udma_mask = 0x1f, 559 .udma_mask = ATA_UDMA4,
560 .port_ops = &ali_c2_port_ops 560 .port_ops = &ali_c2_port_ops
561 }; 561 };
562 /* Revision 0xC4 is UDMA100 */ 562 /* Revision 0xC4 is UDMA100 */
563 static const struct ata_port_info info_c4 = { 563 static const struct ata_port_info info_c4 = {
564 .sht = &ali_sht, 564 .sht = &ali_sht,
565 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST | ATA_FLAG_PIO_LBA48, 565 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48,
566 .pio_mask = 0x1f, 566 .pio_mask = 0x1f,
567 .mwdma_mask = 0x07, 567 .mwdma_mask = 0x07,
568 .udma_mask = 0x3f, 568 .udma_mask = ATA_UDMA5,
569 .port_ops = &ali_c2_port_ops 569 .port_ops = &ali_c2_port_ops
570 }; 570 };
571 /* Revision 0xC5 is UDMA133 with LBA48 DMA */ 571 /* Revision 0xC5 is UDMA133 with LBA48 DMA */
572 static const struct ata_port_info info_c5 = { 572 static const struct ata_port_info info_c5 = {
573 .sht = &ali_sht, 573 .sht = &ali_sht,
574 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 574 .flags = ATA_FLAG_SLAVE_POSS,
575 .pio_mask = 0x1f, 575 .pio_mask = 0x1f,
576 .mwdma_mask = 0x07, 576 .mwdma_mask = 0x07,
577 .udma_mask = 0x7f, 577 .udma_mask = ATA_UDMA6,
578 .port_ops = &ali_c5_port_ops 578 .port_ops = &ali_c5_port_ops
579 }; 579 };
580 580
diff --git a/drivers/ata/pata_amd.c b/drivers/ata/pata_amd.c
index a16f629b7b38..b9c44c575ce3 100644
--- a/drivers/ata/pata_amd.c
+++ b/drivers/ata/pata_amd.c
@@ -541,7 +541,7 @@ static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
541 static const struct ata_port_info info[10] = { 541 static const struct ata_port_info info[10] = {
542 { /* 0: AMD 7401 */ 542 { /* 0: AMD 7401 */
543 .sht = &amd_sht, 543 .sht = &amd_sht,
544 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 544 .flags = ATA_FLAG_SLAVE_POSS,
545 .pio_mask = 0x1f, 545 .pio_mask = 0x1f,
546 .mwdma_mask = 0x07, /* No SWDMA */ 546 .mwdma_mask = 0x07, /* No SWDMA */
547 .udma_mask = 0x07, /* UDMA 33 */ 547 .udma_mask = 0x07, /* UDMA 33 */
@@ -549,74 +549,74 @@ static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
549 }, 549 },
550 { /* 1: Early AMD7409 - no swdma */ 550 { /* 1: Early AMD7409 - no swdma */
551 .sht = &amd_sht, 551 .sht = &amd_sht,
552 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 552 .flags = ATA_FLAG_SLAVE_POSS,
553 .pio_mask = 0x1f, 553 .pio_mask = 0x1f,
554 .mwdma_mask = 0x07, 554 .mwdma_mask = 0x07,
555 .udma_mask = 0x1f, /* UDMA 66 */ 555 .udma_mask = ATA_UDMA4, /* UDMA 66 */
556 .port_ops = &amd66_port_ops 556 .port_ops = &amd66_port_ops
557 }, 557 },
558 { /* 2: AMD 7409, no swdma errata */ 558 { /* 2: AMD 7409, no swdma errata */
559 .sht = &amd_sht, 559 .sht = &amd_sht,
560 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 560 .flags = ATA_FLAG_SLAVE_POSS,
561 .pio_mask = 0x1f, 561 .pio_mask = 0x1f,
562 .mwdma_mask = 0x07, 562 .mwdma_mask = 0x07,
563 .udma_mask = 0x1f, /* UDMA 66 */ 563 .udma_mask = ATA_UDMA4, /* UDMA 66 */
564 .port_ops = &amd66_port_ops 564 .port_ops = &amd66_port_ops
565 }, 565 },
566 { /* 3: AMD 7411 */ 566 { /* 3: AMD 7411 */
567 .sht = &amd_sht, 567 .sht = &amd_sht,
568 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 568 .flags = ATA_FLAG_SLAVE_POSS,
569 .pio_mask = 0x1f, 569 .pio_mask = 0x1f,
570 .mwdma_mask = 0x07, 570 .mwdma_mask = 0x07,
571 .udma_mask = 0x3f, /* UDMA 100 */ 571 .udma_mask = ATA_UDMA5, /* UDMA 100 */
572 .port_ops = &amd100_port_ops 572 .port_ops = &amd100_port_ops
573 }, 573 },
574 { /* 4: AMD 7441 */ 574 { /* 4: AMD 7441 */
575 .sht = &amd_sht, 575 .sht = &amd_sht,
576 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 576 .flags = ATA_FLAG_SLAVE_POSS,
577 .pio_mask = 0x1f, 577 .pio_mask = 0x1f,
578 .mwdma_mask = 0x07, 578 .mwdma_mask = 0x07,
579 .udma_mask = 0x3f, /* UDMA 100 */ 579 .udma_mask = ATA_UDMA5, /* UDMA 100 */
580 .port_ops = &amd100_port_ops 580 .port_ops = &amd100_port_ops
581 }, 581 },
582 { /* 5: AMD 8111*/ 582 { /* 5: AMD 8111*/
583 .sht = &amd_sht, 583 .sht = &amd_sht,
584 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 584 .flags = ATA_FLAG_SLAVE_POSS,
585 .pio_mask = 0x1f, 585 .pio_mask = 0x1f,
586 .mwdma_mask = 0x07, 586 .mwdma_mask = 0x07,
587 .udma_mask = 0x7f, /* UDMA 133, no swdma */ 587 .udma_mask = ATA_UDMA6, /* UDMA 133, no swdma */
588 .port_ops = &amd133_port_ops 588 .port_ops = &amd133_port_ops
589 }, 589 },
590 { /* 6: AMD 8111 UDMA 100 (Serenade) */ 590 { /* 6: AMD 8111 UDMA 100 (Serenade) */
591 .sht = &amd_sht, 591 .sht = &amd_sht,
592 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 592 .flags = ATA_FLAG_SLAVE_POSS,
593 .pio_mask = 0x1f, 593 .pio_mask = 0x1f,
594 .mwdma_mask = 0x07, 594 .mwdma_mask = 0x07,
595 .udma_mask = 0x3f, /* UDMA 100, no swdma */ 595 .udma_mask = ATA_UDMA5, /* UDMA 100, no swdma */
596 .port_ops = &amd133_port_ops 596 .port_ops = &amd133_port_ops
597 }, 597 },
598 { /* 7: Nvidia Nforce */ 598 { /* 7: Nvidia Nforce */
599 .sht = &amd_sht, 599 .sht = &amd_sht,
600 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 600 .flags = ATA_FLAG_SLAVE_POSS,
601 .pio_mask = 0x1f, 601 .pio_mask = 0x1f,
602 .mwdma_mask = 0x07, 602 .mwdma_mask = 0x07,
603 .udma_mask = 0x3f, /* UDMA 100 */ 603 .udma_mask = ATA_UDMA5, /* UDMA 100 */
604 .port_ops = &nv100_port_ops 604 .port_ops = &nv100_port_ops
605 }, 605 },
606 { /* 8: Nvidia Nforce2 and later */ 606 { /* 8: Nvidia Nforce2 and later */
607 .sht = &amd_sht, 607 .sht = &amd_sht,
608 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 608 .flags = ATA_FLAG_SLAVE_POSS,
609 .pio_mask = 0x1f, 609 .pio_mask = 0x1f,
610 .mwdma_mask = 0x07, 610 .mwdma_mask = 0x07,
611 .udma_mask = 0x7f, /* UDMA 133, no swdma */ 611 .udma_mask = ATA_UDMA6, /* UDMA 133, no swdma */
612 .port_ops = &nv133_port_ops 612 .port_ops = &nv133_port_ops
613 }, 613 },
614 { /* 9: AMD CS5536 (Geode companion) */ 614 { /* 9: AMD CS5536 (Geode companion) */
615 .sht = &amd_sht, 615 .sht = &amd_sht,
616 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 616 .flags = ATA_FLAG_SLAVE_POSS,
617 .pio_mask = 0x1f, 617 .pio_mask = 0x1f,
618 .mwdma_mask = 0x07, 618 .mwdma_mask = 0x07,
619 .udma_mask = 0x3f, /* UDMA 100 */ 619 .udma_mask = ATA_UDMA5, /* UDMA 100 */
620 .port_ops = &amd100_port_ops 620 .port_ops = &amd100_port_ops
621 } 621 }
622 }; 622 };
diff --git a/drivers/ata/pata_artop.c b/drivers/ata/pata_artop.c
index 03b6ddd2abd2..ce589d96ca42 100644
--- a/drivers/ata/pata_artop.c
+++ b/drivers/ata/pata_artop.c
@@ -416,7 +416,7 @@ static int artop_init_one (struct pci_dev *pdev, const struct pci_device_id *id)
416 static int printed_version; 416 static int printed_version;
417 static const struct ata_port_info info_6210 = { 417 static const struct ata_port_info info_6210 = {
418 .sht = &artop_sht, 418 .sht = &artop_sht,
419 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 419 .flags = ATA_FLAG_SLAVE_POSS,
420 .pio_mask = 0x1f, /* pio0-4 */ 420 .pio_mask = 0x1f, /* pio0-4 */
421 .mwdma_mask = 0x07, /* mwdma0-2 */ 421 .mwdma_mask = 0x07, /* mwdma0-2 */
422 .udma_mask = ATA_UDMA2, 422 .udma_mask = ATA_UDMA2,
@@ -424,7 +424,7 @@ static int artop_init_one (struct pci_dev *pdev, const struct pci_device_id *id)
424 }; 424 };
425 static const struct ata_port_info info_626x = { 425 static const struct ata_port_info info_626x = {
426 .sht = &artop_sht, 426 .sht = &artop_sht,
427 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 427 .flags = ATA_FLAG_SLAVE_POSS,
428 .pio_mask = 0x1f, /* pio0-4 */ 428 .pio_mask = 0x1f, /* pio0-4 */
429 .mwdma_mask = 0x07, /* mwdma0-2 */ 429 .mwdma_mask = 0x07, /* mwdma0-2 */
430 .udma_mask = ATA_UDMA4, 430 .udma_mask = ATA_UDMA4,
@@ -432,7 +432,7 @@ static int artop_init_one (struct pci_dev *pdev, const struct pci_device_id *id)
432 }; 432 };
433 static const struct ata_port_info info_626x_fast = { 433 static const struct ata_port_info info_626x_fast = {
434 .sht = &artop_sht, 434 .sht = &artop_sht,
435 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 435 .flags = ATA_FLAG_SLAVE_POSS,
436 .pio_mask = 0x1f, /* pio0-4 */ 436 .pio_mask = 0x1f, /* pio0-4 */
437 .mwdma_mask = 0x07, /* mwdma0-2 */ 437 .mwdma_mask = 0x07, /* mwdma0-2 */
438 .udma_mask = ATA_UDMA5, 438 .udma_mask = ATA_UDMA5,
diff --git a/drivers/ata/pata_atiixp.c b/drivers/ata/pata_atiixp.c
index 844914681a2a..80509be49e7a 100644
--- a/drivers/ata/pata_atiixp.c
+++ b/drivers/ata/pata_atiixp.c
@@ -270,7 +270,7 @@ static int atiixp_init_one(struct pci_dev *dev, const struct pci_device_id *id)
270{ 270{
271 static const struct ata_port_info info = { 271 static const struct ata_port_info info = {
272 .sht = &atiixp_sht, 272 .sht = &atiixp_sht,
273 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 273 .flags = ATA_FLAG_SLAVE_POSS,
274 .pio_mask = 0x1f, 274 .pio_mask = 0x1f,
275 .mwdma_mask = 0x06, /* No MWDMA0 support */ 275 .mwdma_mask = 0x06, /* No MWDMA0 support */
276 .udma_mask = 0x3F, 276 .udma_mask = 0x3F,
@@ -285,6 +285,7 @@ static const struct pci_device_id atiixp[] = {
285 { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP300_IDE), }, 285 { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP300_IDE), },
286 { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP400_IDE), }, 286 { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP400_IDE), },
287 { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP600_IDE), }, 287 { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP600_IDE), },
288 { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP700_IDE), },
288 289
289 { }, 290 { },
290}; 291};
diff --git a/drivers/ata/pata_cmd640.c b/drivers/ata/pata_cmd640.c
index 31cbf8daa299..0feb5ae8c486 100644
--- a/drivers/ata/pata_cmd640.c
+++ b/drivers/ata/pata_cmd640.c
@@ -251,7 +251,7 @@ static int cmd640_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
251{ 251{
252 static const struct ata_port_info info = { 252 static const struct ata_port_info info = {
253 .sht = &cmd640_sht, 253 .sht = &cmd640_sht,
254 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 254 .flags = ATA_FLAG_SLAVE_POSS,
255 .pio_mask = 0x1f, 255 .pio_mask = 0x1f,
256 .port_ops = &cmd640_port_ops 256 .port_ops = &cmd640_port_ops
257 }; 257 };
diff --git a/drivers/ata/pata_cmd64x.c b/drivers/ata/pata_cmd64x.c
index 320a5b10aa98..dc443e7dc37c 100644
--- a/drivers/ata/pata_cmd64x.c
+++ b/drivers/ata/pata_cmd64x.c
@@ -380,21 +380,21 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
380 static const struct ata_port_info cmd_info[6] = { 380 static const struct ata_port_info cmd_info[6] = {
381 { /* CMD 643 - no UDMA */ 381 { /* CMD 643 - no UDMA */
382 .sht = &cmd64x_sht, 382 .sht = &cmd64x_sht,
383 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 383 .flags = ATA_FLAG_SLAVE_POSS,
384 .pio_mask = 0x1f, 384 .pio_mask = 0x1f,
385 .mwdma_mask = 0x07, 385 .mwdma_mask = 0x07,
386 .port_ops = &cmd64x_port_ops 386 .port_ops = &cmd64x_port_ops
387 }, 387 },
388 { /* CMD 646 with broken UDMA */ 388 { /* CMD 646 with broken UDMA */
389 .sht = &cmd64x_sht, 389 .sht = &cmd64x_sht,
390 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 390 .flags = ATA_FLAG_SLAVE_POSS,
391 .pio_mask = 0x1f, 391 .pio_mask = 0x1f,
392 .mwdma_mask = 0x07, 392 .mwdma_mask = 0x07,
393 .port_ops = &cmd64x_port_ops 393 .port_ops = &cmd64x_port_ops
394 }, 394 },
395 { /* CMD 646 with working UDMA */ 395 { /* CMD 646 with working UDMA */
396 .sht = &cmd64x_sht, 396 .sht = &cmd64x_sht,
397 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 397 .flags = ATA_FLAG_SLAVE_POSS,
398 .pio_mask = 0x1f, 398 .pio_mask = 0x1f,
399 .mwdma_mask = 0x07, 399 .mwdma_mask = 0x07,
400 .udma_mask = ATA_UDMA1, 400 .udma_mask = ATA_UDMA1,
@@ -402,14 +402,14 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
402 }, 402 },
403 { /* CMD 646 rev 1 */ 403 { /* CMD 646 rev 1 */
404 .sht = &cmd64x_sht, 404 .sht = &cmd64x_sht,
405 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 405 .flags = ATA_FLAG_SLAVE_POSS,
406 .pio_mask = 0x1f, 406 .pio_mask = 0x1f,
407 .mwdma_mask = 0x07, 407 .mwdma_mask = 0x07,
408 .port_ops = &cmd646r1_port_ops 408 .port_ops = &cmd646r1_port_ops
409 }, 409 },
410 { /* CMD 648 */ 410 { /* CMD 648 */
411 .sht = &cmd64x_sht, 411 .sht = &cmd64x_sht,
412 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 412 .flags = ATA_FLAG_SLAVE_POSS,
413 .pio_mask = 0x1f, 413 .pio_mask = 0x1f,
414 .mwdma_mask = 0x07, 414 .mwdma_mask = 0x07,
415 .udma_mask = ATA_UDMA2, 415 .udma_mask = ATA_UDMA2,
@@ -417,7 +417,7 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
417 }, 417 },
418 { /* CMD 649 */ 418 { /* CMD 649 */
419 .sht = &cmd64x_sht, 419 .sht = &cmd64x_sht,
420 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 420 .flags = ATA_FLAG_SLAVE_POSS,
421 .pio_mask = 0x1f, 421 .pio_mask = 0x1f,
422 .mwdma_mask = 0x07, 422 .mwdma_mask = 0x07,
423 .udma_mask = ATA_UDMA3, 423 .udma_mask = ATA_UDMA3,
diff --git a/drivers/ata/pata_cs5520.c b/drivers/ata/pata_cs5520.c
index 00cf0134079c..6bf037d82b5a 100644
--- a/drivers/ata/pata_cs5520.c
+++ b/drivers/ata/pata_cs5520.c
@@ -146,7 +146,7 @@ static struct scsi_host_template cs5520_sht = {
146 .queuecommand = ata_scsi_queuecmd, 146 .queuecommand = ata_scsi_queuecmd,
147 .can_queue = ATA_DEF_QUEUE, 147 .can_queue = ATA_DEF_QUEUE,
148 .this_id = ATA_SHT_THIS_ID, 148 .this_id = ATA_SHT_THIS_ID,
149 .sg_tablesize = LIBATA_MAX_PRD, 149 .sg_tablesize = LIBATA_DUMB_MAX_PRD,
150 .cmd_per_lun = ATA_SHT_CMD_PER_LUN, 150 .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
151 .emulated = ATA_SHT_EMULATED, 151 .emulated = ATA_SHT_EMULATED,
152 .use_clustering = ATA_SHT_USE_CLUSTERING, 152 .use_clustering = ATA_SHT_USE_CLUSTERING,
@@ -178,7 +178,7 @@ static struct ata_port_operations cs5520_port_ops = {
178 .bmdma_start = ata_bmdma_start, 178 .bmdma_start = ata_bmdma_start,
179 .bmdma_stop = ata_bmdma_stop, 179 .bmdma_stop = ata_bmdma_stop,
180 .bmdma_status = ata_bmdma_status, 180 .bmdma_status = ata_bmdma_status,
181 .qc_prep = ata_qc_prep, 181 .qc_prep = ata_dumb_qc_prep,
182 .qc_issue = ata_qc_issue_prot, 182 .qc_issue = ata_qc_issue_prot,
183 .data_xfer = ata_data_xfer, 183 .data_xfer = ata_data_xfer,
184 184
diff --git a/drivers/ata/pata_cs5530.c b/drivers/ata/pata_cs5530.c
index 848f0309bf03..3fca5898642b 100644
--- a/drivers/ata/pata_cs5530.c
+++ b/drivers/ata/pata_cs5530.c
@@ -167,7 +167,7 @@ static struct scsi_host_template cs5530_sht = {
167 .queuecommand = ata_scsi_queuecmd, 167 .queuecommand = ata_scsi_queuecmd,
168 .can_queue = ATA_DEF_QUEUE, 168 .can_queue = ATA_DEF_QUEUE,
169 .this_id = ATA_SHT_THIS_ID, 169 .this_id = ATA_SHT_THIS_ID,
170 .sg_tablesize = LIBATA_MAX_PRD, 170 .sg_tablesize = LIBATA_DUMB_MAX_PRD,
171 .cmd_per_lun = ATA_SHT_CMD_PER_LUN, 171 .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
172 .emulated = ATA_SHT_EMULATED, 172 .emulated = ATA_SHT_EMULATED,
173 .use_clustering = ATA_SHT_USE_CLUSTERING, 173 .use_clustering = ATA_SHT_USE_CLUSTERING,
@@ -201,7 +201,7 @@ static struct ata_port_operations cs5530_port_ops = {
201 .post_internal_cmd = ata_bmdma_post_internal_cmd, 201 .post_internal_cmd = ata_bmdma_post_internal_cmd,
202 .cable_detect = ata_cable_40wire, 202 .cable_detect = ata_cable_40wire,
203 203
204 .qc_prep = ata_qc_prep, 204 .qc_prep = ata_dumb_qc_prep,
205 .qc_issue = cs5530_qc_issue_prot, 205 .qc_issue = cs5530_qc_issue_prot,
206 206
207 .data_xfer = ata_data_xfer, 207 .data_xfer = ata_data_xfer,
@@ -337,7 +337,7 @@ static int cs5530_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
337{ 337{
338 static const struct ata_port_info info = { 338 static const struct ata_port_info info = {
339 .sht = &cs5530_sht, 339 .sht = &cs5530_sht,
340 .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST, 340 .flags = ATA_FLAG_SLAVE_POSS,
341 .pio_mask = 0x1f, 341 .pio_mask = 0x1f,
342 .mwdma_mask = 0x07, 342 .mwdma_mask = 0x07,
343 .udma_mask = 0x07, 343 .udma_mask = 0x07,
@@ -346,7 +346,7 @@ static int cs5530_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
346 /* The docking connector doesn't do UDMA, and it seems not MWDMA */ 346 /* The docking connector doesn't do UDMA, and it seems not MWDMA */
347 static const struct ata_port_info info_palmax_secondary = { 347 static const struct ata_port_info info_palmax_secondary = {
348 .sht = &cs5530_sht, 348 .sht = &cs5530_sht,
349 .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST, 349 .flags = ATA_FLAG_SLAVE_POSS,
350 .pio_mask = 0x1f, 350 .pio_mask = 0x1f,
351 .port_ops = &cs5530_port_ops 351 .port_ops = &cs5530_port_ops
352 }; 352 };
diff --git a/drivers/ata/pata_cs5535.c b/drivers/ata/pata_cs5535.c
index aa3256fb9f7a..360b6f32e17e 100644
--- a/drivers/ata/pata_cs5535.c
+++ b/drivers/ata/pata_cs5535.c
@@ -225,10 +225,10 @@ static int cs5535_init_one(struct pci_dev *dev, const struct pci_device_id *id)
225{ 225{
226 static const struct ata_port_info info = { 226 static const struct ata_port_info info = {
227 .sht = &cs5535_sht, 227 .sht = &cs5535_sht,
228 .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST, 228 .flags = ATA_FLAG_SLAVE_POSS,
229 .pio_mask = 0x1f, 229 .pio_mask = 0x1f,
230 .mwdma_mask = 0x07, 230 .mwdma_mask = 0x07,
231 .udma_mask = 0x1f, 231 .udma_mask = ATA_UDMA4,
232 .port_ops = &cs5535_port_ops 232 .port_ops = &cs5535_port_ops
233 }; 233 };
234 const struct ata_port_info *ppi[] = { &info, &ata_dummy_port_info }; 234 const struct ata_port_info *ppi[] = { &info, &ata_dummy_port_info };
diff --git a/drivers/ata/pata_cypress.c b/drivers/ata/pata_cypress.c
index d41a7691dd8e..6cbc8778bf4f 100644
--- a/drivers/ata/pata_cypress.c
+++ b/drivers/ata/pata_cypress.c
@@ -167,7 +167,7 @@ static int cy82c693_init_one(struct pci_dev *pdev, const struct pci_device_id *i
167{ 167{
168 static const struct ata_port_info info = { 168 static const struct ata_port_info info = {
169 .sht = &cy82c693_sht, 169 .sht = &cy82c693_sht,
170 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 170 .flags = ATA_FLAG_SLAVE_POSS,
171 .pio_mask = 0x1f, 171 .pio_mask = 0x1f,
172 .mwdma_mask = 0x07, 172 .mwdma_mask = 0x07,
173 .port_ops = &cy82c693_port_ops 173 .port_ops = &cy82c693_port_ops
diff --git a/drivers/ata/pata_efar.c b/drivers/ata/pata_efar.c
index 079248a9b460..c8ba59c56114 100644
--- a/drivers/ata/pata_efar.c
+++ b/drivers/ata/pata_efar.c
@@ -303,7 +303,7 @@ static int efar_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
303 static int printed_version; 303 static int printed_version;
304 static const struct ata_port_info info = { 304 static const struct ata_port_info info = {
305 .sht = &efar_sht, 305 .sht = &efar_sht,
306 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 306 .flags = ATA_FLAG_SLAVE_POSS,
307 .pio_mask = 0x1f, /* pio0-4 */ 307 .pio_mask = 0x1f, /* pio0-4 */
308 .mwdma_mask = 0x07, /* mwdma1-2 */ 308 .mwdma_mask = 0x07, /* mwdma1-2 */
309 .udma_mask = 0x0f, /* UDMA 66 */ 309 .udma_mask = 0x0f, /* UDMA 66 */
diff --git a/drivers/ata/pata_hpt366.c b/drivers/ata/pata_hpt366.c
index 0c9cb6090711..6f7d34ad19ef 100644
--- a/drivers/ata/pata_hpt366.c
+++ b/drivers/ata/pata_hpt366.c
@@ -393,10 +393,10 @@ static int hpt36x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
393{ 393{
394 static const struct ata_port_info info_hpt366 = { 394 static const struct ata_port_info info_hpt366 = {
395 .sht = &hpt36x_sht, 395 .sht = &hpt36x_sht,
396 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 396 .flags = ATA_FLAG_SLAVE_POSS,
397 .pio_mask = 0x1f, 397 .pio_mask = 0x1f,
398 .mwdma_mask = 0x07, 398 .mwdma_mask = 0x07,
399 .udma_mask = 0x1f, 399 .udma_mask = ATA_UDMA4,
400 .port_ops = &hpt366_port_ops 400 .port_ops = &hpt366_port_ops
401 }; 401 };
402 struct ata_port_info info = info_hpt366; 402 struct ata_port_info info = info_hpt366;
diff --git a/drivers/ata/pata_hpt37x.c b/drivers/ata/pata_hpt37x.c
index a8c0cbeca399..b0af65aadde3 100644
--- a/drivers/ata/pata_hpt37x.c
+++ b/drivers/ata/pata_hpt37x.c
@@ -889,25 +889,25 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
889 /* HPT370 - UDMA100 */ 889 /* HPT370 - UDMA100 */
890 static const struct ata_port_info info_hpt370 = { 890 static const struct ata_port_info info_hpt370 = {
891 .sht = &hpt37x_sht, 891 .sht = &hpt37x_sht,
892 .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST, 892 .flags = ATA_FLAG_SLAVE_POSS,
893 .pio_mask = 0x1f, 893 .pio_mask = 0x1f,
894 .mwdma_mask = 0x07, 894 .mwdma_mask = 0x07,
895 .udma_mask = 0x3f, 895 .udma_mask = ATA_UDMA5,
896 .port_ops = &hpt370_port_ops 896 .port_ops = &hpt370_port_ops
897 }; 897 };
898 /* HPT370A - UDMA100 */ 898 /* HPT370A - UDMA100 */
899 static const struct ata_port_info info_hpt370a = { 899 static const struct ata_port_info info_hpt370a = {
900 .sht = &hpt37x_sht, 900 .sht = &hpt37x_sht,
901 .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST, 901 .flags = ATA_FLAG_SLAVE_POSS,
902 .pio_mask = 0x1f, 902 .pio_mask = 0x1f,
903 .mwdma_mask = 0x07, 903 .mwdma_mask = 0x07,
904 .udma_mask = 0x3f, 904 .udma_mask = ATA_UDMA5,
905 .port_ops = &hpt370a_port_ops 905 .port_ops = &hpt370a_port_ops
906 }; 906 };
907 /* HPT370 - UDMA100 */ 907 /* HPT370 - UDMA100 */
908 static const struct ata_port_info info_hpt370_33 = { 908 static const struct ata_port_info info_hpt370_33 = {
909 .sht = &hpt37x_sht, 909 .sht = &hpt37x_sht,
910 .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST, 910 .flags = ATA_FLAG_SLAVE_POSS,
911 .pio_mask = 0x1f, 911 .pio_mask = 0x1f,
912 .mwdma_mask = 0x07, 912 .mwdma_mask = 0x07,
913 .udma_mask = 0x0f, 913 .udma_mask = 0x0f,
@@ -916,7 +916,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
916 /* HPT370A - UDMA100 */ 916 /* HPT370A - UDMA100 */
917 static const struct ata_port_info info_hpt370a_33 = { 917 static const struct ata_port_info info_hpt370a_33 = {
918 .sht = &hpt37x_sht, 918 .sht = &hpt37x_sht,
919 .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST, 919 .flags = ATA_FLAG_SLAVE_POSS,
920 .pio_mask = 0x1f, 920 .pio_mask = 0x1f,
921 .mwdma_mask = 0x07, 921 .mwdma_mask = 0x07,
922 .udma_mask = 0x0f, 922 .udma_mask = 0x0f,
@@ -925,19 +925,19 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
925 /* HPT371, 372 and friends - UDMA133 */ 925 /* HPT371, 372 and friends - UDMA133 */
926 static const struct ata_port_info info_hpt372 = { 926 static const struct ata_port_info info_hpt372 = {
927 .sht = &hpt37x_sht, 927 .sht = &hpt37x_sht,
928 .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST, 928 .flags = ATA_FLAG_SLAVE_POSS,
929 .pio_mask = 0x1f, 929 .pio_mask = 0x1f,
930 .mwdma_mask = 0x07, 930 .mwdma_mask = 0x07,
931 .udma_mask = 0x7f, 931 .udma_mask = ATA_UDMA6,
932 .port_ops = &hpt372_port_ops 932 .port_ops = &hpt372_port_ops
933 }; 933 };
934 /* HPT374 - UDMA100 */ 934 /* HPT374 - UDMA100 */
935 static const struct ata_port_info info_hpt374 = { 935 static const struct ata_port_info info_hpt374 = {
936 .sht = &hpt37x_sht, 936 .sht = &hpt37x_sht,
937 .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST, 937 .flags = ATA_FLAG_SLAVE_POSS,
938 .pio_mask = 0x1f, 938 .pio_mask = 0x1f,
939 .mwdma_mask = 0x07, 939 .mwdma_mask = 0x07,
940 .udma_mask = 0x3f, 940 .udma_mask = ATA_UDMA5,
941 .port_ops = &hpt374_port_ops 941 .port_ops = &hpt374_port_ops
942 }; 942 };
943 943
diff --git a/drivers/ata/pata_hpt3x2n.c b/drivers/ata/pata_hpt3x2n.c
index e947433cb37d..aa29cde09f8b 100644
--- a/drivers/ata/pata_hpt3x2n.c
+++ b/drivers/ata/pata_hpt3x2n.c
@@ -490,10 +490,10 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id)
490 /* HPT372N and friends - UDMA133 */ 490 /* HPT372N and friends - UDMA133 */
491 static const struct ata_port_info info = { 491 static const struct ata_port_info info = {
492 .sht = &hpt3x2n_sht, 492 .sht = &hpt3x2n_sht,
493 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 493 .flags = ATA_FLAG_SLAVE_POSS,
494 .pio_mask = 0x1f, 494 .pio_mask = 0x1f,
495 .mwdma_mask = 0x07, 495 .mwdma_mask = 0x07,
496 .udma_mask = 0x7f, 496 .udma_mask = ATA_UDMA6,
497 .port_ops = &hpt3x2n_port_ops 497 .port_ops = &hpt3x2n_port_ops
498 }; 498 };
499 struct ata_port_info port = info; 499 struct ata_port_info port = info;
diff --git a/drivers/ata/pata_hpt3x3.c b/drivers/ata/pata_hpt3x3.c
index 8ce5e23a5f75..d928c9105034 100644
--- a/drivers/ata/pata_hpt3x3.c
+++ b/drivers/ata/pata_hpt3x3.c
@@ -173,7 +173,7 @@ static int hpt3x3_init_one(struct pci_dev *dev, const struct pci_device_id *id)
173{ 173{
174 static const struct ata_port_info info = { 174 static const struct ata_port_info info = {
175 .sht = &hpt3x3_sht, 175 .sht = &hpt3x3_sht,
176 .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST, 176 .flags = ATA_FLAG_SLAVE_POSS,
177 .pio_mask = 0x1f, 177 .pio_mask = 0x1f,
178 .mwdma_mask = 0x07, 178 .mwdma_mask = 0x07,
179 .udma_mask = 0x07, 179 .udma_mask = 0x07,
diff --git a/drivers/ata/pata_icside.c b/drivers/ata/pata_icside.c
index c791a46df461..321d98b0bed2 100644
--- a/drivers/ata/pata_icside.c
+++ b/drivers/ata/pata_icside.c
@@ -530,7 +530,7 @@ static int __devinit pata_icside_add_ports(struct pata_icside_info *info)
530 530
531 ap->pio_mask = 0x1f; 531 ap->pio_mask = 0x1f;
532 ap->mwdma_mask = info->mwdma_mask; 532 ap->mwdma_mask = info->mwdma_mask;
533 ap->flags |= ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST; 533 ap->flags |= ATA_FLAG_SLAVE_POSS;
534 ap->ops = &pata_icside_port_ops; 534 ap->ops = &pata_icside_port_ops;
535 535
536 pata_icside_setup_ioaddr(&ap->ioaddr, info->base, info->port[i]); 536 pata_icside_setup_ioaddr(&ap->ioaddr, info->base, info->port[i]);
diff --git a/drivers/ata/pata_it8213.c b/drivers/ata/pata_it8213.c
index 95b0bb61788b..b8af55e89156 100644
--- a/drivers/ata/pata_it8213.c
+++ b/drivers/ata/pata_it8213.c
@@ -313,10 +313,10 @@ static int it8213_init_one (struct pci_dev *pdev, const struct pci_device_id *en
313 static int printed_version; 313 static int printed_version;
314 static const struct ata_port_info info = { 314 static const struct ata_port_info info = {
315 .sht = &it8213_sht, 315 .sht = &it8213_sht,
316 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 316 .flags = ATA_FLAG_SLAVE_POSS,
317 .pio_mask = 0x1f, /* pio0-4 */ 317 .pio_mask = 0x1f, /* pio0-4 */
318 .mwdma_mask = 0x07, /* mwdma0-2 */ 318 .mwdma_mask = 0x07, /* mwdma0-2 */
319 .udma_mask = 0x1f, /* UDMA 100 */ 319 .udma_mask = ATA_UDMA4, /* FIXME: want UDMA 100? */
320 .port_ops = &it8213_ops, 320 .port_ops = &it8213_ops,
321 }; 321 };
322 /* Current IT8213 stuff is single port */ 322 /* Current IT8213 stuff is single port */
diff --git a/drivers/ata/pata_it821x.c b/drivers/ata/pata_it821x.c
index 12c6e08cc4d1..b67bbf6516ba 100644
--- a/drivers/ata/pata_it821x.c
+++ b/drivers/ata/pata_it821x.c
@@ -714,17 +714,17 @@ static int it821x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
714 714
715 static const struct ata_port_info info_smart = { 715 static const struct ata_port_info info_smart = {
716 .sht = &it821x_sht, 716 .sht = &it821x_sht,
717 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 717 .flags = ATA_FLAG_SLAVE_POSS,
718 .pio_mask = 0x1f, 718 .pio_mask = 0x1f,
719 .mwdma_mask = 0x07, 719 .mwdma_mask = 0x07,
720 .port_ops = &it821x_smart_port_ops 720 .port_ops = &it821x_smart_port_ops
721 }; 721 };
722 static const struct ata_port_info info_passthru = { 722 static const struct ata_port_info info_passthru = {
723 .sht = &it821x_sht, 723 .sht = &it821x_sht,
724 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 724 .flags = ATA_FLAG_SLAVE_POSS,
725 .pio_mask = 0x1f, 725 .pio_mask = 0x1f,
726 .mwdma_mask = 0x07, 726 .mwdma_mask = 0x07,
727 .udma_mask = 0x7f, 727 .udma_mask = ATA_UDMA6,
728 .port_ops = &it821x_passthru_port_ops 728 .port_ops = &it821x_passthru_port_ops
729 }; 729 };
730 730
diff --git a/drivers/ata/pata_ixp4xx_cf.c b/drivers/ata/pata_ixp4xx_cf.c
index 8d2bc1e9e871..4ca7fd6118d5 100644
--- a/drivers/ata/pata_ixp4xx_cf.c
+++ b/drivers/ata/pata_ixp4xx_cf.c
@@ -1,13 +1,14 @@
1/* 1/*
2 * ixp4xx PATA/Compact Flash driver 2 * ixp4xx PATA/Compact Flash driver
3 * Copyright (c) 2006 Tower Technologies 3 * Copyright (C) 2006-07 Tower Technologies
4 * Author: Alessandro Zummo <a.zummo@towertech.it> 4 * Author: Alessandro Zummo <a.zummo@towertech.it>
5 * 5 *
6 * An ATA driver to handle a Compact Flash connected 6 * An ATA driver to handle a Compact Flash connected
7 * to the ixp4xx expansion bus in TrueIDE mode. The CF 7 * to the ixp4xx expansion bus in TrueIDE mode. The CF
8 * must have it chip selects connected to two CS lines 8 * must have it chip selects connected to two CS lines
9 * on the ixp4xx. The interrupt line is optional, if not 9 * on the ixp4xx. In the irq is not available, you might
10 * specified the driver will run in polling mode. 10 * want to modify both this driver and libata to run in
11 * polling mode.
11 * 12 *
12 * This program is free software; you can redistribute it and/or modify 13 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as 14 * it under the terms of the GNU General Public License version 2 as
@@ -23,7 +24,7 @@
23#include <scsi/scsi_host.h> 24#include <scsi/scsi_host.h>
24 25
25#define DRV_NAME "pata_ixp4xx_cf" 26#define DRV_NAME "pata_ixp4xx_cf"
26#define DRV_VERSION "0.1.3" 27#define DRV_VERSION "0.2"
27 28
28static int ixp4xx_set_mode(struct ata_port *ap, struct ata_device **error) 29static int ixp4xx_set_mode(struct ata_port *ap, struct ata_device **error)
29{ 30{
@@ -42,13 +43,6 @@ static int ixp4xx_set_mode(struct ata_port *ap, struct ata_device **error)
42 return 0; 43 return 0;
43} 44}
44 45
45static void ixp4xx_phy_reset(struct ata_port *ap)
46{
47 ap->cbl = ATA_CBL_PATA40;
48 ata_port_probe(ap);
49 ata_bus_reset(ap);
50}
51
52static void ixp4xx_mmio_data_xfer(struct ata_device *adev, unsigned char *buf, 46static void ixp4xx_mmio_data_xfer(struct ata_device *adev, unsigned char *buf,
53 unsigned int buflen, int write_data) 47 unsigned int buflen, int write_data)
54{ 48{
@@ -56,7 +50,7 @@ static void ixp4xx_mmio_data_xfer(struct ata_device *adev, unsigned char *buf,
56 unsigned int words = buflen >> 1; 50 unsigned int words = buflen >> 1;
57 u16 *buf16 = (u16 *) buf; 51 u16 *buf16 = (u16 *) buf;
58 struct ata_port *ap = adev->ap; 52 struct ata_port *ap = adev->ap;
59 void __iomem *mmio = (void __iomem *)ap->ioaddr.data_addr; 53 void __iomem *mmio = ap->ioaddr.data_addr;
60 struct ixp4xx_pata_data *data = ap->host->dev->platform_data; 54 struct ixp4xx_pata_data *data = ap->host->dev->platform_data;
61 55
62 /* set the expansion bus in 16bit mode and restore 56 /* set the expansion bus in 16bit mode and restore
@@ -92,10 +86,6 @@ static void ixp4xx_mmio_data_xfer(struct ata_device *adev, unsigned char *buf,
92 *data->cs0_cfg |= 0x01; 86 *data->cs0_cfg |= 0x01;
93} 87}
94 88
95static void ixp4xx_irq_clear(struct ata_port *ap)
96{
97}
98
99static struct scsi_host_template ixp4xx_sht = { 89static struct scsi_host_template ixp4xx_sht = {
100 .module = THIS_MODULE, 90 .module = THIS_MODULE,
101 .name = DRV_NAME, 91 .name = DRV_NAME,
@@ -115,29 +105,32 @@ static struct scsi_host_template ixp4xx_sht = {
115}; 105};
116 106
117static struct ata_port_operations ixp4xx_port_ops = { 107static struct ata_port_operations ixp4xx_port_ops = {
118 .set_mode = ixp4xx_set_mode, 108 .set_mode = ixp4xx_set_mode,
119 .mode_filter = ata_pci_default_filter, 109 .mode_filter = ata_pci_default_filter,
120 110
121 .port_disable = ata_port_disable, 111 .port_disable = ata_port_disable,
122 .tf_load = ata_tf_load, 112 .tf_load = ata_tf_load,
123 .tf_read = ata_tf_read, 113 .tf_read = ata_tf_read,
124 .check_status = ata_check_status, 114 .exec_command = ata_exec_command,
125 .exec_command = ata_exec_command, 115 .check_status = ata_check_status,
126 .dev_select = ata_std_dev_select, 116 .dev_select = ata_std_dev_select,
127 117
128 .qc_prep = ata_qc_prep, 118 .freeze = ata_bmdma_freeze,
129 .qc_issue = ata_qc_issue_prot, 119 .thaw = ata_bmdma_thaw,
130 .eng_timeout = ata_eng_timeout, 120 .error_handler = ata_bmdma_error_handler,
131 .data_xfer = ixp4xx_mmio_data_xfer, 121 .post_internal_cmd = ata_bmdma_post_internal_cmd,
132 .cable_detect = ata_cable_40wire, 122
133 123 .qc_prep = ata_qc_prep,
134 .irq_clear = ixp4xx_irq_clear, 124 .qc_issue = ata_qc_issue_prot,
135 .irq_on = ata_irq_on, 125 .data_xfer = ixp4xx_mmio_data_xfer,
136 .irq_ack = ata_irq_ack, 126 .cable_detect = ata_cable_40wire,
137 127
138 .port_start = ata_port_start, 128 .irq_handler = ata_interrupt,
139 129 .irq_clear = ata_bmdma_irq_clear,
140 .phy_reset = ixp4xx_phy_reset, 130 .irq_on = ata_irq_on,
131 .irq_ack = ata_dummy_irq_ack,
132
133 .port_start = ata_port_start,
141}; 134};
142 135
143static void ixp4xx_setup_port(struct ata_ioports *ioaddr, 136static void ixp4xx_setup_port(struct ata_ioports *ioaddr,
@@ -178,7 +171,6 @@ static __devinit int ixp4xx_pata_probe(struct platform_device *pdev)
178 struct ata_host *host; 171 struct ata_host *host;
179 struct ata_port *ap; 172 struct ata_port *ap;
180 struct ixp4xx_pata_data *data = pdev->dev.platform_data; 173 struct ixp4xx_pata_data *data = pdev->dev.platform_data;
181 int rc;
182 174
183 cs0 = platform_get_resource(pdev, IORESOURCE_MEM, 0); 175 cs0 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
184 cs1 = platform_get_resource(pdev, IORESOURCE_MEM, 1); 176 cs1 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
@@ -211,10 +203,6 @@ static __devinit int ixp4xx_pata_probe(struct platform_device *pdev)
211 ap->pio_mask = 0x1f; /* PIO4 */ 203 ap->pio_mask = 0x1f; /* PIO4 */
212 ap->flags |= ATA_FLAG_MMIO | ATA_FLAG_NO_LEGACY | ATA_FLAG_NO_ATAPI; 204 ap->flags |= ATA_FLAG_MMIO | ATA_FLAG_NO_LEGACY | ATA_FLAG_NO_ATAPI;
213 205
214 /* run in polling mode if no irq has been assigned */
215 if (!irq)
216 ap->flags |= ATA_FLAG_PIO_POLLING;
217
218 ixp4xx_setup_port(&ap->ioaddr, data); 206 ixp4xx_setup_port(&ap->ioaddr, data);
219 207
220 dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n"); 208 dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n");
diff --git a/drivers/ata/pata_jmicron.c b/drivers/ata/pata_jmicron.c
index 2af7ff8256ca..4d67f238eee2 100644
--- a/drivers/ata/pata_jmicron.c
+++ b/drivers/ata/pata_jmicron.c
@@ -193,11 +193,11 @@ static int jmicron_init_one (struct pci_dev *pdev, const struct pci_device_id *i
193{ 193{
194 static const struct ata_port_info info = { 194 static const struct ata_port_info info = {
195 .sht = &jmicron_sht, 195 .sht = &jmicron_sht,
196 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 196 .flags = ATA_FLAG_SLAVE_POSS,
197 197
198 .pio_mask = 0x1f, 198 .pio_mask = 0x1f,
199 .mwdma_mask = 0x07, 199 .mwdma_mask = 0x07,
200 .udma_mask = 0x3f, 200 .udma_mask = ATA_UDMA5,
201 201
202 .port_ops = &jmicron_ops, 202 .port_ops = &jmicron_ops,
203 }; 203 };
diff --git a/drivers/ata/pata_marvell.c b/drivers/ata/pata_marvell.c
index edbfe0dbbf78..87594c04d3a3 100644
--- a/drivers/ata/pata_marvell.c
+++ b/drivers/ata/pata_marvell.c
@@ -163,22 +163,22 @@ static int marvell_init_one (struct pci_dev *pdev, const struct pci_device_id *i
163{ 163{
164 static const struct ata_port_info info = { 164 static const struct ata_port_info info = {
165 .sht = &marvell_sht, 165 .sht = &marvell_sht,
166 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 166 .flags = ATA_FLAG_SLAVE_POSS,
167 167
168 .pio_mask = 0x1f, 168 .pio_mask = 0x1f,
169 .mwdma_mask = 0x07, 169 .mwdma_mask = 0x07,
170 .udma_mask = 0x3f, 170 .udma_mask = ATA_UDMA5,
171 171
172 .port_ops = &marvell_ops, 172 .port_ops = &marvell_ops,
173 }; 173 };
174 static const struct ata_port_info info_sata = { 174 static const struct ata_port_info info_sata = {
175 .sht = &marvell_sht, 175 .sht = &marvell_sht,
176 /* Slave possible as its magically mapped not real */ 176 /* Slave possible as its magically mapped not real */
177 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 177 .flags = ATA_FLAG_SLAVE_POSS,
178 178
179 .pio_mask = 0x1f, 179 .pio_mask = 0x1f,
180 .mwdma_mask = 0x07, 180 .mwdma_mask = 0x07,
181 .udma_mask = 0x7f, 181 .udma_mask = ATA_UDMA6,
182 182
183 .port_ops = &marvell_ops, 183 .port_ops = &marvell_ops,
184 }; 184 };
diff --git a/drivers/ata/pata_netcell.c b/drivers/ata/pata_netcell.c
index 81f563458666..40eb574828bf 100644
--- a/drivers/ata/pata_netcell.c
+++ b/drivers/ata/pata_netcell.c
@@ -94,12 +94,12 @@ static int netcell_init_one (struct pci_dev *pdev, const struct pci_device_id *e
94 static int printed_version; 94 static int printed_version;
95 static const struct ata_port_info info = { 95 static const struct ata_port_info info = {
96 .sht = &netcell_sht, 96 .sht = &netcell_sht,
97 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 97 .flags = ATA_FLAG_SLAVE_POSS,
98 /* Actually we don't really care about these as the 98 /* Actually we don't really care about these as the
99 firmware deals with it */ 99 firmware deals with it */
100 .pio_mask = 0x1f, /* pio0-4 */ 100 .pio_mask = 0x1f, /* pio0-4 */
101 .mwdma_mask = 0x07, /* mwdma0-2 */ 101 .mwdma_mask = 0x07, /* mwdma0-2 */
102 .udma_mask = 0x3f, /* UDMA 133 */ 102 .udma_mask = ATA_UDMA5, /* UDMA 133 */
103 .port_ops = &netcell_ops, 103 .port_ops = &netcell_ops,
104 }; 104 };
105 const struct ata_port_info *port_info[] = { &info, NULL }; 105 const struct ata_port_info *port_info[] = { &info, NULL };
diff --git a/drivers/ata/pata_ns87410.c b/drivers/ata/pata_ns87410.c
index ea70ec744879..2f5d714ebfc4 100644
--- a/drivers/ata/pata_ns87410.c
+++ b/drivers/ata/pata_ns87410.c
@@ -193,7 +193,7 @@ static int ns87410_init_one(struct pci_dev *dev, const struct pci_device_id *id)
193{ 193{
194 static const struct ata_port_info info = { 194 static const struct ata_port_info info = {
195 .sht = &ns87410_sht, 195 .sht = &ns87410_sht,
196 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 196 .flags = ATA_FLAG_SLAVE_POSS,
197 .pio_mask = 0x0F, 197 .pio_mask = 0x0F,
198 .port_ops = &ns87410_port_ops 198 .port_ops = &ns87410_port_ops
199 }; 199 };
diff --git a/drivers/ata/pata_oldpiix.c b/drivers/ata/pata_oldpiix.c
index 29c23ddd6550..091a70a0ef1c 100644
--- a/drivers/ata/pata_oldpiix.c
+++ b/drivers/ata/pata_oldpiix.c
@@ -291,7 +291,7 @@ static int oldpiix_init_one (struct pci_dev *pdev, const struct pci_device_id *e
291 static int printed_version; 291 static int printed_version;
292 static const struct ata_port_info info = { 292 static const struct ata_port_info info = {
293 .sht = &oldpiix_sht, 293 .sht = &oldpiix_sht,
294 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 294 .flags = ATA_FLAG_SLAVE_POSS,
295 .pio_mask = 0x1f, /* pio0-4 */ 295 .pio_mask = 0x1f, /* pio0-4 */
296 .mwdma_mask = 0x07, /* mwdma1-2 */ 296 .mwdma_mask = 0x07, /* mwdma1-2 */
297 .port_ops = &oldpiix_pata_ops, 297 .port_ops = &oldpiix_pata_ops,
diff --git a/drivers/ata/pata_opti.c b/drivers/ata/pata_opti.c
index 1c44653e1e06..458bf67f766f 100644
--- a/drivers/ata/pata_opti.c
+++ b/drivers/ata/pata_opti.c
@@ -218,7 +218,7 @@ static int opti_init_one(struct pci_dev *dev, const struct pci_device_id *id)
218{ 218{
219 static const struct ata_port_info info = { 219 static const struct ata_port_info info = {
220 .sht = &opti_sht, 220 .sht = &opti_sht,
221 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 221 .flags = ATA_FLAG_SLAVE_POSS,
222 .pio_mask = 0x1f, 222 .pio_mask = 0x1f,
223 .port_ops = &opti_port_ops 223 .port_ops = &opti_port_ops
224 }; 224 };
diff --git a/drivers/ata/pata_optidma.c b/drivers/ata/pata_optidma.c
index 3093b02286ce..f89bdfde16d0 100644
--- a/drivers/ata/pata_optidma.c
+++ b/drivers/ata/pata_optidma.c
@@ -484,14 +484,14 @@ static int optidma_init_one(struct pci_dev *dev, const struct pci_device_id *id)
484{ 484{
485 static const struct ata_port_info info_82c700 = { 485 static const struct ata_port_info info_82c700 = {
486 .sht = &optidma_sht, 486 .sht = &optidma_sht,
487 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 487 .flags = ATA_FLAG_SLAVE_POSS,
488 .pio_mask = 0x1f, 488 .pio_mask = 0x1f,
489 .mwdma_mask = 0x07, 489 .mwdma_mask = 0x07,
490 .port_ops = &optidma_port_ops 490 .port_ops = &optidma_port_ops
491 }; 491 };
492 static const struct ata_port_info info_82c700_udma = { 492 static const struct ata_port_info info_82c700_udma = {
493 .sht = &optidma_sht, 493 .sht = &optidma_sht,
494 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 494 .flags = ATA_FLAG_SLAVE_POSS,
495 .pio_mask = 0x1f, 495 .pio_mask = 0x1f,
496 .mwdma_mask = 0x07, 496 .mwdma_mask = 0x07,
497 .udma_mask = 0x07, 497 .udma_mask = 0x07,
diff --git a/drivers/ata/pata_pdc202xx_old.c b/drivers/ata/pata_pdc202xx_old.c
index d277246b7337..92447bed5e77 100644
--- a/drivers/ata/pata_pdc202xx_old.c
+++ b/drivers/ata/pata_pdc202xx_old.c
@@ -320,7 +320,7 @@ static int pdc202xx_init_one(struct pci_dev *dev, const struct pci_device_id *id
320 static const struct ata_port_info info[3] = { 320 static const struct ata_port_info info[3] = {
321 { 321 {
322 .sht = &pdc202xx_sht, 322 .sht = &pdc202xx_sht,
323 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 323 .flags = ATA_FLAG_SLAVE_POSS,
324 .pio_mask = 0x1f, 324 .pio_mask = 0x1f,
325 .mwdma_mask = 0x07, 325 .mwdma_mask = 0x07,
326 .udma_mask = ATA_UDMA2, 326 .udma_mask = ATA_UDMA2,
@@ -328,7 +328,7 @@ static int pdc202xx_init_one(struct pci_dev *dev, const struct pci_device_id *id
328 }, 328 },
329 { 329 {
330 .sht = &pdc202xx_sht, 330 .sht = &pdc202xx_sht,
331 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 331 .flags = ATA_FLAG_SLAVE_POSS,
332 .pio_mask = 0x1f, 332 .pio_mask = 0x1f,
333 .mwdma_mask = 0x07, 333 .mwdma_mask = 0x07,
334 .udma_mask = ATA_UDMA4, 334 .udma_mask = ATA_UDMA4,
@@ -336,7 +336,7 @@ static int pdc202xx_init_one(struct pci_dev *dev, const struct pci_device_id *id
336 }, 336 },
337 { 337 {
338 .sht = &pdc202xx_sht, 338 .sht = &pdc202xx_sht,
339 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 339 .flags = ATA_FLAG_SLAVE_POSS,
340 .pio_mask = 0x1f, 340 .pio_mask = 0x1f,
341 .mwdma_mask = 0x07, 341 .mwdma_mask = 0x07,
342 .udma_mask = ATA_UDMA5, 342 .udma_mask = ATA_UDMA5,
diff --git a/drivers/ata/pata_platform.c b/drivers/ata/pata_platform.c
index cbb7866940d6..79f841bca593 100644
--- a/drivers/ata/pata_platform.c
+++ b/drivers/ata/pata_platform.c
@@ -139,6 +139,7 @@ static int __devinit pata_platform_probe(struct platform_device *pdev)
139 struct resource *io_res, *ctl_res; 139 struct resource *io_res, *ctl_res;
140 struct ata_host *host; 140 struct ata_host *host;
141 struct ata_port *ap; 141 struct ata_port *ap;
142 struct pata_platform_info *pp_info;
142 unsigned int mmio; 143 unsigned int mmio;
143 144
144 /* 145 /*
@@ -208,11 +209,12 @@ static int __devinit pata_platform_probe(struct platform_device *pdev)
208 209
209 ap->ioaddr.altstatus_addr = ap->ioaddr.ctl_addr; 210 ap->ioaddr.altstatus_addr = ap->ioaddr.ctl_addr;
210 211
211 pata_platform_setup_port(&ap->ioaddr, pdev->dev.platform_data); 212 pp_info = (struct pata_platform_info *)(pdev->dev.platform_data);
213 pata_platform_setup_port(&ap->ioaddr, pp_info);
212 214
213 /* activate */ 215 /* activate */
214 return ata_host_activate(host, platform_get_irq(pdev, 0), ata_interrupt, 216 return ata_host_activate(host, platform_get_irq(pdev, 0), ata_interrupt,
215 0, &pata_platform_sht); 217 pp_info->irq_flags, &pata_platform_sht);
216} 218}
217 219
218/** 220/**
diff --git a/drivers/ata/pata_radisys.c b/drivers/ata/pata_radisys.c
index ba96b54f5b87..7d1aabed422d 100644
--- a/drivers/ata/pata_radisys.c
+++ b/drivers/ata/pata_radisys.c
@@ -257,7 +257,7 @@ static int radisys_init_one (struct pci_dev *pdev, const struct pci_device_id *e
257 static int printed_version; 257 static int printed_version;
258 static const struct ata_port_info info = { 258 static const struct ata_port_info info = {
259 .sht = &radisys_sht, 259 .sht = &radisys_sht,
260 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 260 .flags = ATA_FLAG_SLAVE_POSS,
261 .pio_mask = 0x1f, /* pio0-4 */ 261 .pio_mask = 0x1f, /* pio0-4 */
262 .mwdma_mask = 0x07, /* mwdma1-2 */ 262 .mwdma_mask = 0x07, /* mwdma1-2 */
263 .udma_mask = 0x14, /* UDMA33/66 only */ 263 .udma_mask = 0x14, /* UDMA33/66 only */
diff --git a/drivers/ata/pata_rz1000.c b/drivers/ata/pata_rz1000.c
index a3488b41ad26..7632fcb070ca 100644
--- a/drivers/ata/pata_rz1000.c
+++ b/drivers/ata/pata_rz1000.c
@@ -133,7 +133,7 @@ static int rz1000_init_one (struct pci_dev *pdev, const struct pci_device_id *en
133 static int printed_version; 133 static int printed_version;
134 static const struct ata_port_info info = { 134 static const struct ata_port_info info = {
135 .sht = &rz1000_sht, 135 .sht = &rz1000_sht,
136 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 136 .flags = ATA_FLAG_SLAVE_POSS,
137 .pio_mask = 0x1f, 137 .pio_mask = 0x1f,
138 .port_ops = &rz1000_port_ops 138 .port_ops = &rz1000_port_ops
139 }; 139 };
diff --git a/drivers/ata/pata_sc1200.c b/drivers/ata/pata_sc1200.c
index 1233063ab9a8..b8b2d11e4180 100644
--- a/drivers/ata/pata_sc1200.c
+++ b/drivers/ata/pata_sc1200.c
@@ -185,7 +185,7 @@ static struct scsi_host_template sc1200_sht = {
185 .queuecommand = ata_scsi_queuecmd, 185 .queuecommand = ata_scsi_queuecmd,
186 .can_queue = ATA_DEF_QUEUE, 186 .can_queue = ATA_DEF_QUEUE,
187 .this_id = ATA_SHT_THIS_ID, 187 .this_id = ATA_SHT_THIS_ID,
188 .sg_tablesize = LIBATA_MAX_PRD, 188 .sg_tablesize = LIBATA_DUMB_MAX_PRD,
189 .cmd_per_lun = ATA_SHT_CMD_PER_LUN, 189 .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
190 .emulated = ATA_SHT_EMULATED, 190 .emulated = ATA_SHT_EMULATED,
191 .use_clustering = ATA_SHT_USE_CLUSTERING, 191 .use_clustering = ATA_SHT_USE_CLUSTERING,
@@ -219,7 +219,7 @@ static struct ata_port_operations sc1200_port_ops = {
219 .bmdma_stop = ata_bmdma_stop, 219 .bmdma_stop = ata_bmdma_stop,
220 .bmdma_status = ata_bmdma_status, 220 .bmdma_status = ata_bmdma_status,
221 221
222 .qc_prep = ata_qc_prep, 222 .qc_prep = ata_dumb_qc_prep,
223 .qc_issue = sc1200_qc_issue_prot, 223 .qc_issue = sc1200_qc_issue_prot,
224 224
225 .data_xfer = ata_data_xfer, 225 .data_xfer = ata_data_xfer,
@@ -245,7 +245,7 @@ static int sc1200_init_one(struct pci_dev *dev, const struct pci_device_id *id)
245{ 245{
246 static const struct ata_port_info info = { 246 static const struct ata_port_info info = {
247 .sht = &sc1200_sht, 247 .sht = &sc1200_sht,
248 .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST, 248 .flags = ATA_FLAG_SLAVE_POSS,
249 .pio_mask = 0x1f, 249 .pio_mask = 0x1f,
250 .mwdma_mask = 0x07, 250 .mwdma_mask = 0x07,
251 .udma_mask = 0x07, 251 .udma_mask = 0x07,
diff --git a/drivers/ata/pata_serverworks.c b/drivers/ata/pata_serverworks.c
index 1e8f421963c7..0231aba51ca4 100644
--- a/drivers/ata/pata_serverworks.c
+++ b/drivers/ata/pata_serverworks.c
@@ -478,31 +478,31 @@ static int serverworks_init_one(struct pci_dev *pdev, const struct pci_device_id
478 static const struct ata_port_info info[4] = { 478 static const struct ata_port_info info[4] = {
479 { /* OSB4 */ 479 { /* OSB4 */
480 .sht = &serverworks_sht, 480 .sht = &serverworks_sht,
481 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 481 .flags = ATA_FLAG_SLAVE_POSS,
482 .pio_mask = 0x1f, 482 .pio_mask = 0x1f,
483 .mwdma_mask = 0x07, 483 .mwdma_mask = 0x07,
484 .udma_mask = 0x07, 484 .udma_mask = 0x07,
485 .port_ops = &serverworks_osb4_port_ops 485 .port_ops = &serverworks_osb4_port_ops
486 }, { /* OSB4 no UDMA */ 486 }, { /* OSB4 no UDMA */
487 .sht = &serverworks_sht, 487 .sht = &serverworks_sht,
488 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 488 .flags = ATA_FLAG_SLAVE_POSS,
489 .pio_mask = 0x1f, 489 .pio_mask = 0x1f,
490 .mwdma_mask = 0x07, 490 .mwdma_mask = 0x07,
491 .udma_mask = 0x00, 491 .udma_mask = 0x00,
492 .port_ops = &serverworks_osb4_port_ops 492 .port_ops = &serverworks_osb4_port_ops
493 }, { /* CSB5 */ 493 }, { /* CSB5 */
494 .sht = &serverworks_sht, 494 .sht = &serverworks_sht,
495 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 495 .flags = ATA_FLAG_SLAVE_POSS,
496 .pio_mask = 0x1f, 496 .pio_mask = 0x1f,
497 .mwdma_mask = 0x07, 497 .mwdma_mask = 0x07,
498 .udma_mask = 0x1f, 498 .udma_mask = ATA_UDMA4,
499 .port_ops = &serverworks_csb_port_ops 499 .port_ops = &serverworks_csb_port_ops
500 }, { /* CSB5 - later revisions*/ 500 }, { /* CSB5 - later revisions*/
501 .sht = &serverworks_sht, 501 .sht = &serverworks_sht,
502 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 502 .flags = ATA_FLAG_SLAVE_POSS,
503 .pio_mask = 0x1f, 503 .pio_mask = 0x1f,
504 .mwdma_mask = 0x07, 504 .mwdma_mask = 0x07,
505 .udma_mask = 0x3f, 505 .udma_mask = ATA_UDMA5,
506 .port_ops = &serverworks_csb_port_ops 506 .port_ops = &serverworks_csb_port_ops
507 } 507 }
508 }; 508 };
diff --git a/drivers/ata/pata_sil680.c b/drivers/ata/pata_sil680.c
index 440e2cb6ee75..b0cd52d6e3fb 100644
--- a/drivers/ata/pata_sil680.c
+++ b/drivers/ata/pata_sil680.c
@@ -35,6 +35,8 @@
35#define DRV_NAME "pata_sil680" 35#define DRV_NAME "pata_sil680"
36#define DRV_VERSION "0.4.6" 36#define DRV_VERSION "0.4.6"
37 37
38#define SIL680_MMIO_BAR 5
39
38/** 40/**
39 * sil680_selreg - return register base 41 * sil680_selreg - return register base
40 * @hwif: interface 42 * @hwif: interface
@@ -293,8 +295,8 @@ static u8 sil680_init_chip(struct pci_dev *pdev)
293 295
294 pci_read_config_byte(pdev, 0x8A, &tmpbyte); 296 pci_read_config_byte(pdev, 0x8A, &tmpbyte);
295 297
296 printk(KERN_INFO "sil680: BA5_EN = %d clock = %02X\n", 298 dev_dbg(&pdev->dev, "sil680: BA5_EN = %d clock = %02X\n",
297 tmpbyte & 1, tmpbyte & 0x30); 299 tmpbyte & 1, tmpbyte & 0x30);
298 300
299 switch(tmpbyte & 0x30) { 301 switch(tmpbyte & 0x30) {
300 case 0x00: 302 case 0x00:
@@ -315,8 +317,8 @@ static u8 sil680_init_chip(struct pci_dev *pdev)
315 } 317 }
316 318
317 pci_read_config_byte(pdev, 0x8A, &tmpbyte); 319 pci_read_config_byte(pdev, 0x8A, &tmpbyte);
318 printk(KERN_INFO "sil680: BA5_EN = %d clock = %02X\n", 320 dev_dbg(&pdev->dev, "sil680: BA5_EN = %d clock = %02X\n",
319 tmpbyte & 1, tmpbyte & 0x30); 321 tmpbyte & 1, tmpbyte & 0x30);
320 322
321 pci_write_config_byte(pdev, 0xA1, 0x72); 323 pci_write_config_byte(pdev, 0xA1, 0x72);
322 pci_write_config_word(pdev, 0xA2, 0x328A); 324 pci_write_config_word(pdev, 0xA2, 0x328A);
@@ -339,22 +341,23 @@ static u8 sil680_init_chip(struct pci_dev *pdev)
339 return tmpbyte & 0x30; 341 return tmpbyte & 0x30;
340} 342}
341 343
342static int sil680_init_one(struct pci_dev *pdev, const struct pci_device_id *id) 344static int __devinit sil680_init_one(struct pci_dev *pdev,
345 const struct pci_device_id *id)
343{ 346{
344 static const struct ata_port_info info = { 347 static const struct ata_port_info info = {
345 .sht = &sil680_sht, 348 .sht = &sil680_sht,
346 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 349 .flags = ATA_FLAG_SLAVE_POSS,
347 .pio_mask = 0x1f, 350 .pio_mask = 0x1f,
348 .mwdma_mask = 0x07, 351 .mwdma_mask = 0x07,
349 .udma_mask = 0x7f, 352 .udma_mask = ATA_UDMA6,
350 .port_ops = &sil680_port_ops 353 .port_ops = &sil680_port_ops
351 }; 354 };
352 static const struct ata_port_info info_slow = { 355 static const struct ata_port_info info_slow = {
353 .sht = &sil680_sht, 356 .sht = &sil680_sht,
354 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 357 .flags = ATA_FLAG_SLAVE_POSS,
355 .pio_mask = 0x1f, 358 .pio_mask = 0x1f,
356 .mwdma_mask = 0x07, 359 .mwdma_mask = 0x07,
357 .udma_mask = 0x3f, 360 .udma_mask = ATA_UDMA5,
358 .port_ops = &sil680_port_ops 361 .port_ops = &sil680_port_ops
359 }; 362 };
360 const struct ata_port_info *ppi[] = { &info, NULL }; 363 const struct ata_port_info *ppi[] = { &info, NULL };
diff --git a/drivers/ata/pata_sis.c b/drivers/ata/pata_sis.c
index cfe4ec6eb3d5..2b4508206a6c 100644
--- a/drivers/ata/pata_sis.c
+++ b/drivers/ata/pata_sis.c
@@ -732,7 +732,7 @@ static const struct ata_port_operations sis_old_ops = {
732 732
733static const struct ata_port_info sis_info = { 733static const struct ata_port_info sis_info = {
734 .sht = &sis_sht, 734 .sht = &sis_sht,
735 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 735 .flags = ATA_FLAG_SLAVE_POSS,
736 .pio_mask = 0x1f, /* pio0-4 */ 736 .pio_mask = 0x1f, /* pio0-4 */
737 .mwdma_mask = 0x07, 737 .mwdma_mask = 0x07,
738 .udma_mask = 0, 738 .udma_mask = 0,
@@ -740,7 +740,7 @@ static const struct ata_port_info sis_info = {
740}; 740};
741static const struct ata_port_info sis_info33 = { 741static const struct ata_port_info sis_info33 = {
742 .sht = &sis_sht, 742 .sht = &sis_sht,
743 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 743 .flags = ATA_FLAG_SLAVE_POSS,
744 .pio_mask = 0x1f, /* pio0-4 */ 744 .pio_mask = 0x1f, /* pio0-4 */
745 .mwdma_mask = 0x07, 745 .mwdma_mask = 0x07,
746 .udma_mask = ATA_UDMA2, /* UDMA 33 */ 746 .udma_mask = ATA_UDMA2, /* UDMA 33 */
@@ -748,28 +748,28 @@ static const struct ata_port_info sis_info33 = {
748}; 748};
749static const struct ata_port_info sis_info66 = { 749static const struct ata_port_info sis_info66 = {
750 .sht = &sis_sht, 750 .sht = &sis_sht,
751 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 751 .flags = ATA_FLAG_SLAVE_POSS,
752 .pio_mask = 0x1f, /* pio0-4 */ 752 .pio_mask = 0x1f, /* pio0-4 */
753 .udma_mask = ATA_UDMA4, /* UDMA 66 */ 753 .udma_mask = ATA_UDMA4, /* UDMA 66 */
754 .port_ops = &sis_66_ops, 754 .port_ops = &sis_66_ops,
755}; 755};
756static const struct ata_port_info sis_info100 = { 756static const struct ata_port_info sis_info100 = {
757 .sht = &sis_sht, 757 .sht = &sis_sht,
758 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 758 .flags = ATA_FLAG_SLAVE_POSS,
759 .pio_mask = 0x1f, /* pio0-4 */ 759 .pio_mask = 0x1f, /* pio0-4 */
760 .udma_mask = ATA_UDMA5, 760 .udma_mask = ATA_UDMA5,
761 .port_ops = &sis_100_ops, 761 .port_ops = &sis_100_ops,
762}; 762};
763static const struct ata_port_info sis_info100_early = { 763static const struct ata_port_info sis_info100_early = {
764 .sht = &sis_sht, 764 .sht = &sis_sht,
765 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 765 .flags = ATA_FLAG_SLAVE_POSS,
766 .udma_mask = ATA_UDMA5, 766 .udma_mask = ATA_UDMA5,
767 .pio_mask = 0x1f, /* pio0-4 */ 767 .pio_mask = 0x1f, /* pio0-4 */
768 .port_ops = &sis_66_ops, 768 .port_ops = &sis_66_ops,
769}; 769};
770static const struct ata_port_info sis_info133 = { 770static const struct ata_port_info sis_info133 = {
771 .sht = &sis_sht, 771 .sht = &sis_sht,
772 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 772 .flags = ATA_FLAG_SLAVE_POSS,
773 .pio_mask = 0x1f, /* pio0-4 */ 773 .pio_mask = 0x1f, /* pio0-4 */
774 .udma_mask = ATA_UDMA6, 774 .udma_mask = ATA_UDMA6,
775 .port_ops = &sis_133_ops, 775 .port_ops = &sis_133_ops,
@@ -783,7 +783,7 @@ const struct ata_port_info sis_info133_for_sata = {
783}; 783};
784static const struct ata_port_info sis_info133_early = { 784static const struct ata_port_info sis_info133_early = {
785 .sht = &sis_sht, 785 .sht = &sis_sht,
786 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 786 .flags = ATA_FLAG_SLAVE_POSS,
787 .pio_mask = 0x1f, /* pio0-4 */ 787 .pio_mask = 0x1f, /* pio0-4 */
788 .udma_mask = ATA_UDMA6, 788 .udma_mask = ATA_UDMA6,
789 .port_ops = &sis_133_early_ops, 789 .port_ops = &sis_133_early_ops,
diff --git a/drivers/ata/pata_sl82c105.c b/drivers/ata/pata_sl82c105.c
index e5aaec43694d..bde734189623 100644
--- a/drivers/ata/pata_sl82c105.c
+++ b/drivers/ata/pata_sl82c105.c
@@ -303,14 +303,14 @@ static int sl82c105_init_one(struct pci_dev *dev, const struct pci_device_id *id
303{ 303{
304 static const struct ata_port_info info_dma = { 304 static const struct ata_port_info info_dma = {
305 .sht = &sl82c105_sht, 305 .sht = &sl82c105_sht,
306 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 306 .flags = ATA_FLAG_SLAVE_POSS,
307 .pio_mask = 0x1f, 307 .pio_mask = 0x1f,
308 .mwdma_mask = 0x07, 308 .mwdma_mask = 0x07,
309 .port_ops = &sl82c105_port_ops 309 .port_ops = &sl82c105_port_ops
310 }; 310 };
311 static const struct ata_port_info info_early = { 311 static const struct ata_port_info info_early = {
312 .sht = &sl82c105_sht, 312 .sht = &sl82c105_sht,
313 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 313 .flags = ATA_FLAG_SLAVE_POSS,
314 .pio_mask = 0x1f, 314 .pio_mask = 0x1f,
315 .port_ops = &sl82c105_port_ops 315 .port_ops = &sl82c105_port_ops
316 }; 316 };
diff --git a/drivers/ata/pata_triflex.c b/drivers/ata/pata_triflex.c
index b1d3076dfe51..af21f443db6e 100644
--- a/drivers/ata/pata_triflex.c
+++ b/drivers/ata/pata_triflex.c
@@ -235,7 +235,7 @@ static int triflex_init_one(struct pci_dev *dev, const struct pci_device_id *id)
235{ 235{
236 static const struct ata_port_info info = { 236 static const struct ata_port_info info = {
237 .sht = &triflex_sht, 237 .sht = &triflex_sht,
238 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 238 .flags = ATA_FLAG_SLAVE_POSS,
239 .pio_mask = 0x1f, 239 .pio_mask = 0x1f,
240 .mwdma_mask = 0x07, 240 .mwdma_mask = 0x07,
241 .port_ops = &triflex_port_ops 241 .port_ops = &triflex_port_ops
diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c
index 63eca299c62b..f0cadbe6aa11 100644
--- a/drivers/ata/pata_via.c
+++ b/drivers/ata/pata_via.c
@@ -471,7 +471,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
471 .flags = ATA_FLAG_SLAVE_POSS, 471 .flags = ATA_FLAG_SLAVE_POSS,
472 .pio_mask = 0x1f, 472 .pio_mask = 0x1f,
473 .mwdma_mask = 0x07, 473 .mwdma_mask = 0x07,
474 .udma_mask = 0x7, 474 .udma_mask = ATA_UDMA2,
475 .port_ops = &via_port_ops 475 .port_ops = &via_port_ops
476 }; 476 };
477 /* VIA UDMA 66 devices */ 477 /* VIA UDMA 66 devices */
@@ -480,7 +480,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
480 .flags = ATA_FLAG_SLAVE_POSS, 480 .flags = ATA_FLAG_SLAVE_POSS,
481 .pio_mask = 0x1f, 481 .pio_mask = 0x1f,
482 .mwdma_mask = 0x07, 482 .mwdma_mask = 0x07,
483 .udma_mask = 0x1f, 483 .udma_mask = ATA_UDMA4,
484 .port_ops = &via_port_ops 484 .port_ops = &via_port_ops
485 }; 485 };
486 /* VIA UDMA 100 devices */ 486 /* VIA UDMA 100 devices */
@@ -489,7 +489,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
489 .flags = ATA_FLAG_SLAVE_POSS, 489 .flags = ATA_FLAG_SLAVE_POSS,
490 .pio_mask = 0x1f, 490 .pio_mask = 0x1f,
491 .mwdma_mask = 0x07, 491 .mwdma_mask = 0x07,
492 .udma_mask = 0x3f, 492 .udma_mask = ATA_UDMA5,
493 .port_ops = &via_port_ops 493 .port_ops = &via_port_ops
494 }; 494 };
495 /* UDMA133 with bad AST (All current 133) */ 495 /* UDMA133 with bad AST (All current 133) */
@@ -498,7 +498,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
498 .flags = ATA_FLAG_SLAVE_POSS, 498 .flags = ATA_FLAG_SLAVE_POSS,
499 .pio_mask = 0x1f, 499 .pio_mask = 0x1f,
500 .mwdma_mask = 0x07, 500 .mwdma_mask = 0x07,
501 .udma_mask = 0x7f, /* FIXME: should check north bridge */ 501 .udma_mask = ATA_UDMA6, /* FIXME: should check north bridge */
502 .port_ops = &via_port_ops 502 .port_ops = &via_port_ops
503 }; 503 };
504 struct ata_port_info type; 504 struct ata_port_info type;
diff --git a/drivers/ata/pdc_adma.c b/drivers/ata/pdc_adma.c
index f12c2b6ac08e..bec1de594de8 100644
--- a/drivers/ata/pdc_adma.c
+++ b/drivers/ata/pdc_adma.c
@@ -145,32 +145,32 @@ static struct scsi_host_template adma_ata_sht = {
145 .name = DRV_NAME, 145 .name = DRV_NAME,
146 .ioctl = ata_scsi_ioctl, 146 .ioctl = ata_scsi_ioctl,
147 .queuecommand = ata_scsi_queuecmd, 147 .queuecommand = ata_scsi_queuecmd,
148 .slave_configure = ata_scsi_slave_config,
149 .slave_destroy = ata_scsi_slave_destroy,
150 .bios_param = ata_std_bios_param,
151 .proc_name = DRV_NAME,
148 .can_queue = ATA_DEF_QUEUE, 152 .can_queue = ATA_DEF_QUEUE,
149 .this_id = ATA_SHT_THIS_ID, 153 .this_id = ATA_SHT_THIS_ID,
150 .sg_tablesize = LIBATA_MAX_PRD, 154 .sg_tablesize = LIBATA_MAX_PRD,
155 .dma_boundary = ADMA_DMA_BOUNDARY,
151 .cmd_per_lun = ATA_SHT_CMD_PER_LUN, 156 .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
152 .emulated = ATA_SHT_EMULATED,
153 .use_clustering = ENABLE_CLUSTERING, 157 .use_clustering = ENABLE_CLUSTERING,
154 .proc_name = DRV_NAME, 158 .emulated = ATA_SHT_EMULATED,
155 .dma_boundary = ADMA_DMA_BOUNDARY,
156 .slave_configure = ata_scsi_slave_config,
157 .slave_destroy = ata_scsi_slave_destroy,
158 .bios_param = ata_std_bios_param,
159}; 159};
160 160
161static const struct ata_port_operations adma_ata_ops = { 161static const struct ata_port_operations adma_ata_ops = {
162 .port_disable = ata_port_disable, 162 .port_disable = ata_port_disable,
163 .tf_load = ata_tf_load, 163 .tf_load = ata_tf_load,
164 .tf_read = ata_tf_read, 164 .tf_read = ata_tf_read,
165 .check_status = ata_check_status,
166 .check_atapi_dma = adma_check_atapi_dma,
167 .exec_command = ata_exec_command, 165 .exec_command = ata_exec_command,
166 .check_status = ata_check_status,
168 .dev_select = ata_std_dev_select, 167 .dev_select = ata_std_dev_select,
169 .phy_reset = adma_phy_reset, 168 .phy_reset = adma_phy_reset,
169 .check_atapi_dma = adma_check_atapi_dma,
170 .data_xfer = ata_data_xfer,
170 .qc_prep = adma_qc_prep, 171 .qc_prep = adma_qc_prep,
171 .qc_issue = adma_qc_issue, 172 .qc_issue = adma_qc_issue,
172 .eng_timeout = adma_eng_timeout, 173 .eng_timeout = adma_eng_timeout,
173 .data_xfer = ata_data_xfer,
174 .irq_clear = adma_irq_clear, 174 .irq_clear = adma_irq_clear,
175 .irq_on = ata_irq_on, 175 .irq_on = ata_irq_on,
176 .irq_ack = ata_irq_ack, 176 .irq_ack = ata_irq_ack,
@@ -188,7 +188,7 @@ static struct ata_port_info adma_port_info[] = {
188 ATA_FLAG_NO_LEGACY | ATA_FLAG_MMIO | 188 ATA_FLAG_NO_LEGACY | ATA_FLAG_MMIO |
189 ATA_FLAG_PIO_POLLING, 189 ATA_FLAG_PIO_POLLING,
190 .pio_mask = 0x10, /* pio4 */ 190 .pio_mask = 0x10, /* pio4 */
191 .udma_mask = 0x1f, /* udma0-4 */ 191 .udma_mask = ATA_UDMA4,
192 .port_ops = &adma_ata_ops, 192 .port_ops = &adma_ata_ops,
193 }, 193 },
194}; 194};
diff --git a/drivers/ata/sata_inic162x.c b/drivers/ata/sata_inic162x.c
index dc3bbce04676..3de183461c3c 100644
--- a/drivers/ata/sata_inic162x.c
+++ b/drivers/ata/sata_inic162x.c
@@ -192,7 +192,7 @@ static void inic_reset_port(void __iomem *port_base)
192 192
193static u32 inic_scr_read(struct ata_port *ap, unsigned sc_reg) 193static u32 inic_scr_read(struct ata_port *ap, unsigned sc_reg)
194{ 194{
195 void __iomem *scr_addr = (void __iomem *)ap->ioaddr.scr_addr; 195 void __iomem *scr_addr = ap->ioaddr.scr_addr;
196 void __iomem *addr; 196 void __iomem *addr;
197 u32 val; 197 u32 val;
198 198
@@ -210,7 +210,7 @@ static u32 inic_scr_read(struct ata_port *ap, unsigned sc_reg)
210 210
211static void inic_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val) 211static void inic_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val)
212{ 212{
213 void __iomem *scr_addr = (void __iomem *)ap->ioaddr.scr_addr; 213 void __iomem *scr_addr = ap->ioaddr.scr_addr;
214 void __iomem *addr; 214 void __iomem *addr;
215 215
216 if (unlikely(sc_reg >= ARRAY_SIZE(scr_map))) 216 if (unlikely(sc_reg >= ARRAY_SIZE(scr_map)))
@@ -594,7 +594,7 @@ static struct ata_port_info inic_port_info = {
594 .flags = ATA_FLAG_SATA | ATA_FLAG_PIO_DMA, 594 .flags = ATA_FLAG_SATA | ATA_FLAG_PIO_DMA,
595 .pio_mask = 0x1f, /* pio0-4 */ 595 .pio_mask = 0x1f, /* pio0-4 */
596 .mwdma_mask = 0x07, /* mwdma0-2 */ 596 .mwdma_mask = 0x07, /* mwdma0-2 */
597 .udma_mask = 0x7f, /* udma0-6 */ 597 .udma_mask = ATA_UDMA6,
598 .port_ops = &inic_port_ops 598 .port_ops = &inic_port_ops
599}; 599};
600 600
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index 590f2f92b4e0..3873b29c80d6 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -526,44 +526,44 @@ static const struct ata_port_info mv_port_info[] = {
526 { /* chip_504x */ 526 { /* chip_504x */
527 .flags = MV_COMMON_FLAGS, 527 .flags = MV_COMMON_FLAGS,
528 .pio_mask = 0x1f, /* pio0-4 */ 528 .pio_mask = 0x1f, /* pio0-4 */
529 .udma_mask = 0x7f, /* udma0-6 */ 529 .udma_mask = ATA_UDMA6,
530 .port_ops = &mv5_ops, 530 .port_ops = &mv5_ops,
531 }, 531 },
532 { /* chip_508x */ 532 { /* chip_508x */
533 .flags = (MV_COMMON_FLAGS | MV_FLAG_DUAL_HC), 533 .flags = (MV_COMMON_FLAGS | MV_FLAG_DUAL_HC),
534 .pio_mask = 0x1f, /* pio0-4 */ 534 .pio_mask = 0x1f, /* pio0-4 */
535 .udma_mask = 0x7f, /* udma0-6 */ 535 .udma_mask = ATA_UDMA6,
536 .port_ops = &mv5_ops, 536 .port_ops = &mv5_ops,
537 }, 537 },
538 { /* chip_5080 */ 538 { /* chip_5080 */
539 .flags = (MV_COMMON_FLAGS | MV_FLAG_DUAL_HC), 539 .flags = (MV_COMMON_FLAGS | MV_FLAG_DUAL_HC),
540 .pio_mask = 0x1f, /* pio0-4 */ 540 .pio_mask = 0x1f, /* pio0-4 */
541 .udma_mask = 0x7f, /* udma0-6 */ 541 .udma_mask = ATA_UDMA6,
542 .port_ops = &mv5_ops, 542 .port_ops = &mv5_ops,
543 }, 543 },
544 { /* chip_604x */ 544 { /* chip_604x */
545 .flags = (MV_COMMON_FLAGS | MV_6XXX_FLAGS), 545 .flags = (MV_COMMON_FLAGS | MV_6XXX_FLAGS),
546 .pio_mask = 0x1f, /* pio0-4 */ 546 .pio_mask = 0x1f, /* pio0-4 */
547 .udma_mask = 0x7f, /* udma0-6 */ 547 .udma_mask = ATA_UDMA6,
548 .port_ops = &mv6_ops, 548 .port_ops = &mv6_ops,
549 }, 549 },
550 { /* chip_608x */ 550 { /* chip_608x */
551 .flags = (MV_COMMON_FLAGS | MV_6XXX_FLAGS | 551 .flags = (MV_COMMON_FLAGS | MV_6XXX_FLAGS |
552 MV_FLAG_DUAL_HC), 552 MV_FLAG_DUAL_HC),
553 .pio_mask = 0x1f, /* pio0-4 */ 553 .pio_mask = 0x1f, /* pio0-4 */
554 .udma_mask = 0x7f, /* udma0-6 */ 554 .udma_mask = ATA_UDMA6,
555 .port_ops = &mv6_ops, 555 .port_ops = &mv6_ops,
556 }, 556 },
557 { /* chip_6042 */ 557 { /* chip_6042 */
558 .flags = (MV_COMMON_FLAGS | MV_6XXX_FLAGS), 558 .flags = (MV_COMMON_FLAGS | MV_6XXX_FLAGS),
559 .pio_mask = 0x1f, /* pio0-4 */ 559 .pio_mask = 0x1f, /* pio0-4 */
560 .udma_mask = 0x7f, /* udma0-6 */ 560 .udma_mask = ATA_UDMA6,
561 .port_ops = &mv_iie_ops, 561 .port_ops = &mv_iie_ops,
562 }, 562 },
563 { /* chip_7042 */ 563 { /* chip_7042 */
564 .flags = (MV_COMMON_FLAGS | MV_6XXX_FLAGS), 564 .flags = (MV_COMMON_FLAGS | MV_6XXX_FLAGS),
565 .pio_mask = 0x1f, /* pio0-4 */ 565 .pio_mask = 0x1f, /* pio0-4 */
566 .udma_mask = 0x7f, /* udma0-6 */ 566 .udma_mask = ATA_UDMA6,
567 .port_ops = &mv_iie_ops, 567 .port_ops = &mv_iie_ops,
568 }, 568 },
569}; 569};
@@ -2338,7 +2338,7 @@ static void mv_print_info(struct ata_host *host)
2338 struct pci_dev *pdev = to_pci_dev(host->dev); 2338 struct pci_dev *pdev = to_pci_dev(host->dev);
2339 struct mv_host_priv *hpriv = host->private_data; 2339 struct mv_host_priv *hpriv = host->private_data;
2340 u8 rev_id, scc; 2340 u8 rev_id, scc;
2341 const char *scc_s; 2341 const char *scc_s, *gen;
2342 2342
2343 /* Use this to determine the HW stepping of the chip so we know 2343 /* Use this to determine the HW stepping of the chip so we know
2344 * what errata to workaround 2344 * what errata to workaround
@@ -2351,11 +2351,20 @@ static void mv_print_info(struct ata_host *host)
2351 else if (scc == 0x01) 2351 else if (scc == 0x01)
2352 scc_s = "RAID"; 2352 scc_s = "RAID";
2353 else 2353 else
2354 scc_s = "unknown"; 2354 scc_s = "?";
2355
2356 if (IS_GEN_I(hpriv))
2357 gen = "I";
2358 else if (IS_GEN_II(hpriv))
2359 gen = "II";
2360 else if (IS_GEN_IIE(hpriv))
2361 gen = "IIE";
2362 else
2363 gen = "?";
2355 2364
2356 dev_printk(KERN_INFO, &pdev->dev, 2365 dev_printk(KERN_INFO, &pdev->dev,
2357 "%u slots %u ports %s mode IRQ via %s\n", 2366 "Gen-%s %u slots %u ports %s mode IRQ via %s\n",
2358 (unsigned)MV_MAX_Q_DEPTH, host->n_ports, 2367 gen, (unsigned)MV_MAX_Q_DEPTH, host->n_ports,
2359 scc_s, (MV_HP_FLAG_MSI & hpriv->hp_flags) ? "MSI" : "INTx"); 2368 scc_s, (MV_HP_FLAG_MSI & hpriv->hp_flags) ? "MSI" : "INTx");
2360} 2369}
2361 2370
diff --git a/drivers/ata/sata_promise.c b/drivers/ata/sata_promise.c
index 6dc0b011a6b7..2ad5872fe90c 100644
--- a/drivers/ata/sata_promise.c
+++ b/drivers/ata/sata_promise.c
@@ -45,8 +45,7 @@
45#include "sata_promise.h" 45#include "sata_promise.h"
46 46
47#define DRV_NAME "sata_promise" 47#define DRV_NAME "sata_promise"
48#define DRV_VERSION "2.07" 48#define DRV_VERSION "2.08"
49
50 49
51enum { 50enum {
52 PDC_MAX_PORTS = 4, 51 PDC_MAX_PORTS = 4,
@@ -94,7 +93,7 @@ enum {
94 board_20319 = 2, /* FastTrak S150 TX4 */ 93 board_20319 = 2, /* FastTrak S150 TX4 */
95 board_20619 = 3, /* FastTrak TX4000 */ 94 board_20619 = 3, /* FastTrak TX4000 */
96 board_2057x = 4, /* SATAII150 Tx2plus */ 95 board_2057x = 4, /* SATAII150 Tx2plus */
97 board_2057x_pata = 5, /* SATAII150 Tx2plus */ 96 board_2057x_pata = 5, /* SATAII150 Tx2plus PATA port */
98 board_40518 = 6, /* SATAII150 Tx4 */ 97 board_40518 = 6, /* SATAII150 Tx4 */
99 98
100 PDC_HAS_PATA = (1 << 1), /* PDC20375/20575 has PATA */ 99 PDC_HAS_PATA = (1 << 1), /* PDC20375/20575 has PATA */
@@ -124,7 +123,6 @@ enum {
124 PDC_FLAG_4_PORTS = (1 << 26), /* 4 ports */ 123 PDC_FLAG_4_PORTS = (1 << 26), /* 4 ports */
125}; 124};
126 125
127
128struct pdc_port_priv { 126struct pdc_port_priv {
129 u8 *pkt; 127 u8 *pkt;
130 dma_addr_t pkt_dma; 128 dma_addr_t pkt_dma;
@@ -252,7 +250,7 @@ static const struct ata_port_info pdc_port_info[] = {
252 PDC_FLAG_SATA_PATA, 250 PDC_FLAG_SATA_PATA,
253 .pio_mask = 0x1f, /* pio0-4 */ 251 .pio_mask = 0x1f, /* pio0-4 */
254 .mwdma_mask = 0x07, /* mwdma0-2 */ 252 .mwdma_mask = 0x07, /* mwdma0-2 */
255 .udma_mask = 0x7f, /* udma0-6 ; FIXME */ 253 .udma_mask = ATA_UDMA6,
256 .port_ops = &pdc_old_sata_ops, 254 .port_ops = &pdc_old_sata_ops,
257 }, 255 },
258 256
@@ -261,7 +259,7 @@ static const struct ata_port_info pdc_port_info[] = {
261 .flags = PDC_COMMON_FLAGS | ATA_FLAG_SLAVE_POSS, 259 .flags = PDC_COMMON_FLAGS | ATA_FLAG_SLAVE_POSS,
262 .pio_mask = 0x1f, /* pio0-4 */ 260 .pio_mask = 0x1f, /* pio0-4 */
263 .mwdma_mask = 0x07, /* mwdma0-2 */ 261 .mwdma_mask = 0x07, /* mwdma0-2 */
264 .udma_mask = 0x7f, /* udma0-6 ; FIXME */ 262 .udma_mask = ATA_UDMA6,
265 .port_ops = &pdc_pata_ops, 263 .port_ops = &pdc_pata_ops,
266 }, 264 },
267 265
@@ -271,7 +269,7 @@ static const struct ata_port_info pdc_port_info[] = {
271 PDC_FLAG_4_PORTS, 269 PDC_FLAG_4_PORTS,
272 .pio_mask = 0x1f, /* pio0-4 */ 270 .pio_mask = 0x1f, /* pio0-4 */
273 .mwdma_mask = 0x07, /* mwdma0-2 */ 271 .mwdma_mask = 0x07, /* mwdma0-2 */
274 .udma_mask = 0x7f, /* udma0-6 ; FIXME */ 272 .udma_mask = ATA_UDMA6,
275 .port_ops = &pdc_old_sata_ops, 273 .port_ops = &pdc_old_sata_ops,
276 }, 274 },
277 275
@@ -281,7 +279,7 @@ static const struct ata_port_info pdc_port_info[] = {
281 PDC_FLAG_4_PORTS, 279 PDC_FLAG_4_PORTS,
282 .pio_mask = 0x1f, /* pio0-4 */ 280 .pio_mask = 0x1f, /* pio0-4 */
283 .mwdma_mask = 0x07, /* mwdma0-2 */ 281 .mwdma_mask = 0x07, /* mwdma0-2 */
284 .udma_mask = 0x7f, /* udma0-6 ; FIXME */ 282 .udma_mask = ATA_UDMA6,
285 .port_ops = &pdc_pata_ops, 283 .port_ops = &pdc_pata_ops,
286 }, 284 },
287 285
@@ -291,7 +289,7 @@ static const struct ata_port_info pdc_port_info[] = {
291 PDC_FLAG_GEN_II | PDC_FLAG_SATA_PATA, 289 PDC_FLAG_GEN_II | PDC_FLAG_SATA_PATA,
292 .pio_mask = 0x1f, /* pio0-4 */ 290 .pio_mask = 0x1f, /* pio0-4 */
293 .mwdma_mask = 0x07, /* mwdma0-2 */ 291 .mwdma_mask = 0x07, /* mwdma0-2 */
294 .udma_mask = 0x7f, /* udma0-6 ; FIXME */ 292 .udma_mask = ATA_UDMA6,
295 .port_ops = &pdc_sata_ops, 293 .port_ops = &pdc_sata_ops,
296 }, 294 },
297 295
@@ -301,7 +299,7 @@ static const struct ata_port_info pdc_port_info[] = {
301 PDC_FLAG_GEN_II, 299 PDC_FLAG_GEN_II,
302 .pio_mask = 0x1f, /* pio0-4 */ 300 .pio_mask = 0x1f, /* pio0-4 */
303 .mwdma_mask = 0x07, /* mwdma0-2 */ 301 .mwdma_mask = 0x07, /* mwdma0-2 */
304 .udma_mask = 0x7f, /* udma0-6 ; FIXME */ 302 .udma_mask = ATA_UDMA6,
305 .port_ops = &pdc_pata_ops, 303 .port_ops = &pdc_pata_ops,
306 }, 304 },
307 305
@@ -311,7 +309,7 @@ static const struct ata_port_info pdc_port_info[] = {
311 PDC_FLAG_GEN_II | PDC_FLAG_4_PORTS, 309 PDC_FLAG_GEN_II | PDC_FLAG_4_PORTS,
312 .pio_mask = 0x1f, /* pio0-4 */ 310 .pio_mask = 0x1f, /* pio0-4 */
313 .mwdma_mask = 0x07, /* mwdma0-2 */ 311 .mwdma_mask = 0x07, /* mwdma0-2 */
314 .udma_mask = 0x7f, /* udma0-6 ; FIXME */ 312 .udma_mask = ATA_UDMA6,
315 .port_ops = &pdc_sata_ops, 313 .port_ops = &pdc_sata_ops,
316 }, 314 },
317}; 315};
@@ -340,7 +338,6 @@ static const struct pci_device_id pdc_ata_pci_tbl[] = {
340 { } /* terminate list */ 338 { } /* terminate list */
341}; 339};
342 340
343
344static struct pci_driver pdc_ata_pci_driver = { 341static struct pci_driver pdc_ata_pci_driver = {
345 .name = DRV_NAME, 342 .name = DRV_NAME,
346 .id_table = pdc_ata_pci_tbl, 343 .id_table = pdc_ata_pci_tbl,
@@ -348,7 +345,6 @@ static struct pci_driver pdc_ata_pci_driver = {
348 .remove = ata_pci_remove_one, 345 .remove = ata_pci_remove_one,
349}; 346};
350 347
351
352static int pdc_common_port_start(struct ata_port *ap) 348static int pdc_common_port_start(struct ata_port *ap)
353{ 349{
354 struct device *dev = ap->host->dev; 350 struct device *dev = ap->host->dev;
@@ -382,7 +378,7 @@ static int pdc_sata_port_start(struct ata_port *ap)
382 378
383 /* fix up PHYMODE4 align timing */ 379 /* fix up PHYMODE4 align timing */
384 if (ap->flags & PDC_FLAG_GEN_II) { 380 if (ap->flags & PDC_FLAG_GEN_II) {
385 void __iomem *mmio = (void __iomem *) ap->ioaddr.scr_addr; 381 void __iomem *mmio = ap->ioaddr.scr_addr;
386 unsigned int tmp; 382 unsigned int tmp;
387 383
388 tmp = readl(mmio + 0x014); 384 tmp = readl(mmio + 0x014);
@@ -418,7 +414,7 @@ static void pdc_reset_port(struct ata_port *ap)
418static int pdc_pata_cable_detect(struct ata_port *ap) 414static int pdc_pata_cable_detect(struct ata_port *ap)
419{ 415{
420 u8 tmp; 416 u8 tmp;
421 void __iomem *mmio = (void __iomem *) ap->ioaddr.cmd_addr + PDC_CTLSTAT + 0x03; 417 void __iomem *mmio = ap->ioaddr.cmd_addr + PDC_CTLSTAT + 0x03;
422 418
423 tmp = readb(mmio); 419 tmp = readb(mmio);
424 if (tmp & 0x01) 420 if (tmp & 0x01)
@@ -438,7 +434,6 @@ static u32 pdc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg)
438 return readl(ap->ioaddr.scr_addr + (sc_reg * 4)); 434 return readl(ap->ioaddr.scr_addr + (sc_reg * 4));
439} 435}
440 436
441
442static void pdc_sata_scr_write (struct ata_port *ap, unsigned int sc_reg, 437static void pdc_sata_scr_write (struct ata_port *ap, unsigned int sc_reg,
443 u32 val) 438 u32 val)
444{ 439{
@@ -573,7 +568,7 @@ static void pdc_qc_prep(struct ata_queued_cmd *qc)
573 568
574static void pdc_freeze(struct ata_port *ap) 569static void pdc_freeze(struct ata_port *ap)
575{ 570{
576 void __iomem *mmio = (void __iomem *) ap->ioaddr.cmd_addr; 571 void __iomem *mmio = ap->ioaddr.cmd_addr;
577 u32 tmp; 572 u32 tmp;
578 573
579 tmp = readl(mmio + PDC_CTLSTAT); 574 tmp = readl(mmio + PDC_CTLSTAT);
@@ -585,7 +580,7 @@ static void pdc_freeze(struct ata_port *ap)
585 580
586static void pdc_thaw(struct ata_port *ap) 581static void pdc_thaw(struct ata_port *ap)
587{ 582{
588 void __iomem *mmio = (void __iomem *) ap->ioaddr.cmd_addr; 583 void __iomem *mmio = ap->ioaddr.cmd_addr;
589 u32 tmp; 584 u32 tmp;
590 585
591 /* clear IRQ */ 586 /* clear IRQ */
@@ -657,8 +652,8 @@ static void pdc_error_intr(struct ata_port *ap, struct ata_queued_cmd *qc,
657 ata_port_abort(ap); 652 ata_port_abort(ap);
658} 653}
659 654
660static inline unsigned int pdc_host_intr( struct ata_port *ap, 655static inline unsigned int pdc_host_intr(struct ata_port *ap,
661 struct ata_queued_cmd *qc) 656 struct ata_queued_cmd *qc)
662{ 657{
663 unsigned int handled = 0; 658 unsigned int handled = 0;
664 void __iomem *port_mmio = ap->ioaddr.cmd_addr; 659 void __iomem *port_mmio = ap->ioaddr.cmd_addr;
@@ -685,10 +680,10 @@ static inline unsigned int pdc_host_intr( struct ata_port *ap,
685 handled = 1; 680 handled = 1;
686 break; 681 break;
687 682
688 default: 683 default:
689 ap->stats.idle_irq++; 684 ap->stats.idle_irq++;
690 break; 685 break;
691 } 686 }
692 687
693 return handled; 688 return handled;
694} 689}
@@ -701,6 +696,18 @@ static void pdc_irq_clear(struct ata_port *ap)
701 readl(mmio + PDC_INT_SEQMASK); 696 readl(mmio + PDC_INT_SEQMASK);
702} 697}
703 698
699static inline int pdc_is_sataii_tx4(unsigned long flags)
700{
701 const unsigned long mask = PDC_FLAG_GEN_II | PDC_FLAG_4_PORTS;
702 return (flags & mask) == mask;
703}
704
705static inline unsigned int pdc_port_no_to_ata_no(unsigned int port_no, int is_sataii_tx4)
706{
707 static const unsigned char sataii_tx4_port_remap[4] = { 3, 1, 0, 2};
708 return is_sataii_tx4 ? sataii_tx4_port_remap[port_no] : port_no;
709}
710
704static irqreturn_t pdc_interrupt (int irq, void *dev_instance) 711static irqreturn_t pdc_interrupt (int irq, void *dev_instance)
705{ 712{
706 struct ata_host *host = dev_instance; 713 struct ata_host *host = dev_instance;
@@ -807,7 +814,6 @@ static void pdc_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf)
807 ata_tf_load(ap, tf); 814 ata_tf_load(ap, tf);
808} 815}
809 816
810
811static void pdc_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile *tf) 817static void pdc_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile *tf)
812{ 818{
813 WARN_ON (tf->protocol == ATA_PROT_DMA || 819 WARN_ON (tf->protocol == ATA_PROT_DMA ||
@@ -867,7 +873,6 @@ static void pdc_ata_setup_port(struct ata_port *ap,
867 ap->ioaddr.scr_addr = scr_addr; 873 ap->ioaddr.scr_addr = scr_addr;
868} 874}
869 875
870
871static void pdc_host_init(struct ata_host *host) 876static void pdc_host_init(struct ata_host *host)
872{ 877{
873 void __iomem *mmio = host->iomap[PDC_MMIO_BAR]; 878 void __iomem *mmio = host->iomap[PDC_MMIO_BAR];
@@ -955,10 +960,8 @@ static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
955 960
956 if (pi->flags & PDC_FLAG_SATA_PATA) { 961 if (pi->flags & PDC_FLAG_SATA_PATA) {
957 u8 tmp = readb(base + PDC_FLASH_CTL+1); 962 u8 tmp = readb(base + PDC_FLASH_CTL+1);
958 if (!(tmp & 0x80)) { 963 if (!(tmp & 0x80))
959 ppi[n_ports++] = pi + 1; 964 ppi[n_ports++] = pi + 1;
960 dev_printk(KERN_INFO, &pdev->dev, "PATA port found\n");
961 }
962 } 965 }
963 966
964 host = ata_host_alloc_pinfo(&pdev->dev, ppi, n_ports); 967 host = ata_host_alloc_pinfo(&pdev->dev, ppi, n_ports);
@@ -968,22 +971,12 @@ static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
968 } 971 }
969 host->iomap = pcim_iomap_table(pdev); 972 host->iomap = pcim_iomap_table(pdev);
970 973
971 is_sataii_tx4 = 0; 974 is_sataii_tx4 = pdc_is_sataii_tx4(pi->flags);
972 if ((pi->flags & (PDC_FLAG_GEN_II|PDC_FLAG_4_PORTS)) == (PDC_FLAG_GEN_II|PDC_FLAG_4_PORTS)) {
973 is_sataii_tx4 = 1;
974 dev_printk(KERN_INFO, &pdev->dev, "applying SATAII TX4 port numbering workaround\n");
975 }
976 for (i = 0; i < host->n_ports; i++) { 975 for (i = 0; i < host->n_ports; i++) {
977 static const unsigned char sataii_tx4_port_remap[4] = { 3, 1, 0, 2}; 976 unsigned int ata_no = pdc_port_no_to_ata_no(i, is_sataii_tx4);
978 int ata_nr;
979
980 ata_nr = i;
981 if (is_sataii_tx4)
982 ata_nr = sataii_tx4_port_remap[i];
983
984 pdc_ata_setup_port(host->ports[i], 977 pdc_ata_setup_port(host->ports[i],
985 base + 0x200 + ata_nr * 0x80, 978 base + 0x200 + ata_no * 0x80,
986 base + 0x400 + ata_nr * 0x100); 979 base + 0x400 + ata_no * 0x100);
987 } 980 }
988 981
989 /* initialize adapter */ 982 /* initialize adapter */
@@ -1002,19 +995,16 @@ static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
1002 &pdc_ata_sht); 995 &pdc_ata_sht);
1003} 996}
1004 997
1005
1006static int __init pdc_ata_init(void) 998static int __init pdc_ata_init(void)
1007{ 999{
1008 return pci_register_driver(&pdc_ata_pci_driver); 1000 return pci_register_driver(&pdc_ata_pci_driver);
1009} 1001}
1010 1002
1011
1012static void __exit pdc_ata_exit(void) 1003static void __exit pdc_ata_exit(void)
1013{ 1004{
1014 pci_unregister_driver(&pdc_ata_pci_driver); 1005 pci_unregister_driver(&pdc_ata_pci_driver);
1015} 1006}
1016 1007
1017
1018MODULE_AUTHOR("Jeff Garzik"); 1008MODULE_AUTHOR("Jeff Garzik");
1019MODULE_DESCRIPTION("Promise ATA TX2/TX4/TX4000 low-level driver"); 1009MODULE_DESCRIPTION("Promise ATA TX2/TX4/TX4000 low-level driver");
1020MODULE_LICENSE("GPL"); 1010MODULE_LICENSE("GPL");
diff --git a/drivers/ata/sata_qstor.c b/drivers/ata/sata_qstor.c
index 6688ccb66320..9ab554da89bf 100644
--- a/drivers/ata/sata_qstor.c
+++ b/drivers/ata/sata_qstor.c
@@ -176,7 +176,7 @@ static const struct ata_port_info qs_port_info[] = {
176 //FIXME ATA_FLAG_SRST | 176 //FIXME ATA_FLAG_SRST |
177 ATA_FLAG_MMIO | ATA_FLAG_PIO_POLLING, 177 ATA_FLAG_MMIO | ATA_FLAG_PIO_POLLING,
178 .pio_mask = 0x10, /* pio4 */ 178 .pio_mask = 0x10, /* pio4 */
179 .udma_mask = 0x7f, /* udma0-6 */ 179 .udma_mask = ATA_UDMA6,
180 .port_ops = &qs_ata_ops, 180 .port_ops = &qs_ata_ops,
181 }, 181 },
182}; 182};
diff --git a/drivers/ata/sata_sil.c b/drivers/ata/sata_sil.c
index a3b339bcf3cf..2a86dc4598d0 100644
--- a/drivers/ata/sata_sil.c
+++ b/drivers/ata/sata_sil.c
@@ -218,7 +218,7 @@ static const struct ata_port_info sil_port_info[] = {
218 .flags = SIL_DFL_PORT_FLAGS | SIL_FLAG_MOD15WRITE, 218 .flags = SIL_DFL_PORT_FLAGS | SIL_FLAG_MOD15WRITE,
219 .pio_mask = 0x1f, /* pio0-4 */ 219 .pio_mask = 0x1f, /* pio0-4 */
220 .mwdma_mask = 0x07, /* mwdma0-2 */ 220 .mwdma_mask = 0x07, /* mwdma0-2 */
221 .udma_mask = 0x3f, /* udma0-5 */ 221 .udma_mask = ATA_UDMA5,
222 .port_ops = &sil_ops, 222 .port_ops = &sil_ops,
223 }, 223 },
224 /* sil_3112_no_sata_irq */ 224 /* sil_3112_no_sata_irq */
@@ -227,7 +227,7 @@ static const struct ata_port_info sil_port_info[] = {
227 SIL_FLAG_NO_SATA_IRQ, 227 SIL_FLAG_NO_SATA_IRQ,
228 .pio_mask = 0x1f, /* pio0-4 */ 228 .pio_mask = 0x1f, /* pio0-4 */
229 .mwdma_mask = 0x07, /* mwdma0-2 */ 229 .mwdma_mask = 0x07, /* mwdma0-2 */
230 .udma_mask = 0x3f, /* udma0-5 */ 230 .udma_mask = ATA_UDMA5,
231 .port_ops = &sil_ops, 231 .port_ops = &sil_ops,
232 }, 232 },
233 /* sil_3512 */ 233 /* sil_3512 */
@@ -235,7 +235,7 @@ static const struct ata_port_info sil_port_info[] = {
235 .flags = SIL_DFL_PORT_FLAGS | SIL_FLAG_RERR_ON_DMA_ACT, 235 .flags = SIL_DFL_PORT_FLAGS | SIL_FLAG_RERR_ON_DMA_ACT,
236 .pio_mask = 0x1f, /* pio0-4 */ 236 .pio_mask = 0x1f, /* pio0-4 */
237 .mwdma_mask = 0x07, /* mwdma0-2 */ 237 .mwdma_mask = 0x07, /* mwdma0-2 */
238 .udma_mask = 0x3f, /* udma0-5 */ 238 .udma_mask = ATA_UDMA5,
239 .port_ops = &sil_ops, 239 .port_ops = &sil_ops,
240 }, 240 },
241 /* sil_3114 */ 241 /* sil_3114 */
@@ -243,7 +243,7 @@ static const struct ata_port_info sil_port_info[] = {
243 .flags = SIL_DFL_PORT_FLAGS | SIL_FLAG_RERR_ON_DMA_ACT, 243 .flags = SIL_DFL_PORT_FLAGS | SIL_FLAG_RERR_ON_DMA_ACT,
244 .pio_mask = 0x1f, /* pio0-4 */ 244 .pio_mask = 0x1f, /* pio0-4 */
245 .mwdma_mask = 0x07, /* mwdma0-2 */ 245 .mwdma_mask = 0x07, /* mwdma0-2 */
246 .udma_mask = 0x3f, /* udma0-5 */ 246 .udma_mask = ATA_UDMA5,
247 .port_ops = &sil_ops, 247 .port_ops = &sil_ops,
248 }, 248 },
249}; 249};
@@ -262,8 +262,9 @@ static const struct {
262 unsigned long sfis_cfg; /* SATA FIS reception config register */ 262 unsigned long sfis_cfg; /* SATA FIS reception config register */
263} sil_port[] = { 263} sil_port[] = {
264 /* port 0 ... */ 264 /* port 0 ... */
265 { 0x80, 0x8A, 0x00, 0x10, 0x40, 0x100, 0x148, 0xb4, 0x14c }, 265 /* tf ctl bmdma bmdma2 fifo scr sien mode sfis */
266 { 0xC0, 0xCA, 0x08, 0x18, 0x44, 0x180, 0x1c8, 0xf4, 0x1cc }, 266 { 0x80, 0x8A, 0x0, 0x10, 0x40, 0x100, 0x148, 0xb4, 0x14c },
267 { 0xC0, 0xCA, 0x8, 0x18, 0x44, 0x180, 0x1c8, 0xf4, 0x1cc },
267 { 0x280, 0x28A, 0x200, 0x210, 0x240, 0x300, 0x348, 0x2b4, 0x34c }, 268 { 0x280, 0x28A, 0x200, 0x210, 0x240, 0x300, 0x348, 0x2b4, 0x34c },
268 { 0x2C0, 0x2CA, 0x208, 0x218, 0x244, 0x380, 0x3c8, 0x2f4, 0x3cc }, 269 { 0x2C0, 0x2CA, 0x208, 0x218, 0x244, 0x380, 0x3c8, 0x2f4, 0x3cc },
269 /* ... port 3 */ 270 /* ... port 3 */
diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c
index 0ddfae9911cd..ac43a30ebe29 100644
--- a/drivers/ata/sata_sil24.c
+++ b/drivers/ata/sata_sil24.c
@@ -426,7 +426,7 @@ static const struct ata_port_info sil24_port_info[] = {
426 SIL24_FLAG_PCIX_IRQ_WOC, 426 SIL24_FLAG_PCIX_IRQ_WOC,
427 .pio_mask = 0x1f, /* pio0-4 */ 427 .pio_mask = 0x1f, /* pio0-4 */
428 .mwdma_mask = 0x07, /* mwdma0-2 */ 428 .mwdma_mask = 0x07, /* mwdma0-2 */
429 .udma_mask = 0x3f, /* udma0-5 */ 429 .udma_mask = ATA_UDMA5, /* udma0-5 */
430 .port_ops = &sil24_ops, 430 .port_ops = &sil24_ops,
431 }, 431 },
432 /* sil_3132 */ 432 /* sil_3132 */
@@ -434,7 +434,7 @@ static const struct ata_port_info sil24_port_info[] = {
434 .flags = SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(2), 434 .flags = SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(2),
435 .pio_mask = 0x1f, /* pio0-4 */ 435 .pio_mask = 0x1f, /* pio0-4 */
436 .mwdma_mask = 0x07, /* mwdma0-2 */ 436 .mwdma_mask = 0x07, /* mwdma0-2 */
437 .udma_mask = 0x3f, /* udma0-5 */ 437 .udma_mask = ATA_UDMA5, /* udma0-5 */
438 .port_ops = &sil24_ops, 438 .port_ops = &sil24_ops,
439 }, 439 },
440 /* sil_3131/sil_3531 */ 440 /* sil_3131/sil_3531 */
@@ -442,7 +442,7 @@ static const struct ata_port_info sil24_port_info[] = {
442 .flags = SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(1), 442 .flags = SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(1),
443 .pio_mask = 0x1f, /* pio0-4 */ 443 .pio_mask = 0x1f, /* pio0-4 */
444 .mwdma_mask = 0x07, /* mwdma0-2 */ 444 .mwdma_mask = 0x07, /* mwdma0-2 */
445 .udma_mask = 0x3f, /* udma0-5 */ 445 .udma_mask = ATA_UDMA5, /* udma0-5 */
446 .port_ops = &sil24_ops, 446 .port_ops = &sil24_ops,
447 }, 447 },
448}; 448};
@@ -888,7 +888,7 @@ static irqreturn_t sil24_interrupt(int irq, void *dev_instance)
888 if (status & (1 << i)) { 888 if (status & (1 << i)) {
889 struct ata_port *ap = host->ports[i]; 889 struct ata_port *ap = host->ports[i];
890 if (ap && !(ap->flags & ATA_FLAG_DISABLED)) { 890 if (ap && !(ap->flags & ATA_FLAG_DISABLED)) {
891 sil24_host_intr(host->ports[i]); 891 sil24_host_intr(ap);
892 handled++; 892 handled++;
893 } else 893 } else
894 printk(KERN_ERR DRV_NAME 894 printk(KERN_ERR DRV_NAME
diff --git a/drivers/ata/sata_sis.c b/drivers/ata/sata_sis.c
index f111c984a359..fd80bcf1b236 100644
--- a/drivers/ata/sata_sis.c
+++ b/drivers/ata/sata_sis.c
@@ -133,7 +133,7 @@ static const struct ata_port_info sis_port_info = {
133 .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY, 133 .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY,
134 .pio_mask = 0x1f, 134 .pio_mask = 0x1f,
135 .mwdma_mask = 0x7, 135 .mwdma_mask = 0x7,
136 .udma_mask = 0x7f, 136 .udma_mask = ATA_UDMA6,
137 .port_ops = &sis_ops, 137 .port_ops = &sis_ops,
138}; 138};
139 139
diff --git a/drivers/ata/sata_svw.c b/drivers/ata/sata_svw.c
index bcb2cd8b063d..63fe99afd59f 100644
--- a/drivers/ata/sata_svw.c
+++ b/drivers/ata/sata_svw.c
@@ -107,7 +107,7 @@ static u32 k2_sata_scr_read (struct ata_port *ap, unsigned int sc_reg)
107{ 107{
108 if (sc_reg > SCR_CONTROL) 108 if (sc_reg > SCR_CONTROL)
109 return 0xffffffffU; 109 return 0xffffffffU;
110 return readl((void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4)); 110 return readl(ap->ioaddr.scr_addr + (sc_reg * 4));
111} 111}
112 112
113 113
@@ -116,7 +116,7 @@ static void k2_sata_scr_write (struct ata_port *ap, unsigned int sc_reg,
116{ 116{
117 if (sc_reg > SCR_CONTROL) 117 if (sc_reg > SCR_CONTROL)
118 return; 118 return;
119 writel(val, (void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4)); 119 writel(val, ap->ioaddr.scr_addr + (sc_reg * 4));
120} 120}
121 121
122 122
@@ -197,7 +197,8 @@ static void k2_bmdma_setup_mmio (struct ata_queued_cmd *qc)
197 struct ata_port *ap = qc->ap; 197 struct ata_port *ap = qc->ap;
198 unsigned int rw = (qc->tf.flags & ATA_TFLAG_WRITE); 198 unsigned int rw = (qc->tf.flags & ATA_TFLAG_WRITE);
199 u8 dmactl; 199 u8 dmactl;
200 void __iomem *mmio = (void __iomem *) ap->ioaddr.bmdma_addr; 200 void __iomem *mmio = ap->ioaddr.bmdma_addr;
201
201 /* load PRD table addr. */ 202 /* load PRD table addr. */
202 mb(); /* make sure PRD table writes are visible to controller */ 203 mb(); /* make sure PRD table writes are visible to controller */
203 writel(ap->prd_dma, mmio + ATA_DMA_TABLE_OFS); 204 writel(ap->prd_dma, mmio + ATA_DMA_TABLE_OFS);
@@ -225,7 +226,7 @@ static void k2_bmdma_setup_mmio (struct ata_queued_cmd *qc)
225static void k2_bmdma_start_mmio (struct ata_queued_cmd *qc) 226static void k2_bmdma_start_mmio (struct ata_queued_cmd *qc)
226{ 227{
227 struct ata_port *ap = qc->ap; 228 struct ata_port *ap = qc->ap;
228 void __iomem *mmio = (void __iomem *) ap->ioaddr.bmdma_addr; 229 void __iomem *mmio = ap->ioaddr.bmdma_addr;
229 u8 dmactl; 230 u8 dmactl;
230 231
231 /* start host DMA transaction */ 232 /* start host DMA transaction */
@@ -253,7 +254,7 @@ static void k2_bmdma_start_mmio (struct ata_queued_cmd *qc)
253 254
254static u8 k2_stat_check_status(struct ata_port *ap) 255static u8 k2_stat_check_status(struct ata_port *ap)
255{ 256{
256 return readl((void __iomem *) ap->ioaddr.status_addr); 257 return readl(ap->ioaddr.status_addr);
257} 258}
258 259
259#ifdef CONFIG_PPC_OF 260#ifdef CONFIG_PPC_OF
@@ -360,7 +361,7 @@ static const struct ata_port_info k2_port_info[] = {
360 ATA_FLAG_MMIO | K2_FLAG_NO_ATAPI_DMA, 361 ATA_FLAG_MMIO | K2_FLAG_NO_ATAPI_DMA,
361 .pio_mask = 0x1f, 362 .pio_mask = 0x1f,
362 .mwdma_mask = 0x07, 363 .mwdma_mask = 0x07,
363 .udma_mask = 0x7f, 364 .udma_mask = ATA_UDMA6,
364 .port_ops = &k2_sata_ops, 365 .port_ops = &k2_sata_ops,
365 }, 366 },
366 /* board_svw8 */ 367 /* board_svw8 */
@@ -370,7 +371,7 @@ static const struct ata_port_info k2_port_info[] = {
370 K2_FLAG_SATA_8_PORTS, 371 K2_FLAG_SATA_8_PORTS,
371 .pio_mask = 0x1f, 372 .pio_mask = 0x1f,
372 .mwdma_mask = 0x07, 373 .mwdma_mask = 0x07,
373 .udma_mask = 0x7f, 374 .udma_mask = ATA_UDMA6,
374 .port_ops = &k2_sata_ops, 375 .port_ops = &k2_sata_ops,
375 }, 376 },
376}; 377};
diff --git a/drivers/ata/sata_sx4.c b/drivers/ata/sata_sx4.c
index 2d14f3d56d92..5193bd8647ba 100644
--- a/drivers/ata/sata_sx4.c
+++ b/drivers/ata/sata_sx4.c
@@ -30,6 +30,54 @@
30 * 30 *
31 */ 31 */
32 32
33/*
34 Theory of operation
35 -------------------
36
37 The SX4 (PDC20621) chip features a single Host DMA (HDMA) copy
38 engine, DIMM memory, and four ATA engines (one per SATA port).
39 Data is copied to/from DIMM memory by the HDMA engine, before
40 handing off to one (or more) of the ATA engines. The ATA
41 engines operate solely on DIMM memory.
42
43 The SX4 behaves like a PATA chip, with no SATA controls or
44 knowledge whatsoever, leading to the presumption that
45 PATA<->SATA bridges exist on SX4 boards, external to the
46 PDC20621 chip itself.
47
48 The chip is quite capable, supporting an XOR engine and linked
49 hardware commands (permits a string to transactions to be
50 submitted and waited-on as a single unit), and an optional
51 microprocessor.
52
53 The limiting factor is largely software. This Linux driver was
54 written to multiplex the single HDMA engine to copy disk
55 transactions into a fixed DIMM memory space, from where an ATA
56 engine takes over. As a result, each WRITE looks like this:
57
58 submit HDMA packet to hardware
59 hardware copies data from system memory to DIMM
60 hardware raises interrupt
61
62 submit ATA packet to hardware
63 hardware executes ATA WRITE command, w/ data in DIMM
64 hardware raises interrupt
65
66 and each READ looks like this:
67
68 submit ATA packet to hardware
69 hardware executes ATA READ command, w/ data in DIMM
70 hardware raises interrupt
71
72 submit HDMA packet to hardware
73 hardware copies data from DIMM to system memory
74 hardware raises interrupt
75
76 This is a very slow, lock-step way of doing things that can
77 certainly be improved by motivated kernel hackers.
78
79 */
80
33#include <linux/kernel.h> 81#include <linux/kernel.h>
34#include <linux/module.h> 82#include <linux/module.h>
35#include <linux/pci.h> 83#include <linux/pci.h>
@@ -58,6 +106,8 @@ enum {
58 PDC_INT_SEQMASK = 0x40, /* Mask of asserted SEQ INTs */ 106 PDC_INT_SEQMASK = 0x40, /* Mask of asserted SEQ INTs */
59 PDC_HDMA_CTLSTAT = 0x12C, /* Host DMA control / status */ 107 PDC_HDMA_CTLSTAT = 0x12C, /* Host DMA control / status */
60 108
109 PDC_CTLSTAT = 0x60, /* IDEn control / status */
110
61 PDC_20621_SEQCTL = 0x400, 111 PDC_20621_SEQCTL = 0x400,
62 PDC_20621_SEQMASK = 0x480, 112 PDC_20621_SEQMASK = 0x480,
63 PDC_20621_GENERAL_CTL = 0x484, 113 PDC_20621_GENERAL_CTL = 0x484,
@@ -87,48 +137,60 @@ enum {
87 137
88 board_20621 = 0, /* FastTrak S150 SX4 */ 138 board_20621 = 0, /* FastTrak S150 SX4 */
89 139
90 PDC_RESET = (1 << 11), /* HDMA reset */ 140 PDC_MASK_INT = (1 << 10), /* HDMA/ATA mask int */
141 PDC_RESET = (1 << 11), /* HDMA/ATA reset */
142 PDC_DMA_ENABLE = (1 << 7), /* DMA start/stop */
91 143
92 PDC_MAX_HDMA = 32, 144 PDC_MAX_HDMA = 32,
93 PDC_HDMA_Q_MASK = (PDC_MAX_HDMA - 1), 145 PDC_HDMA_Q_MASK = (PDC_MAX_HDMA - 1),
94 146
95 PDC_DIMM0_SPD_DEV_ADDRESS = 0x50, 147 PDC_DIMM0_SPD_DEV_ADDRESS = 0x50,
96 PDC_DIMM1_SPD_DEV_ADDRESS = 0x51, 148 PDC_DIMM1_SPD_DEV_ADDRESS = 0x51,
97 PDC_MAX_DIMM_MODULE = 0x02, 149 PDC_I2C_CONTROL = 0x48,
98 PDC_I2C_CONTROL_OFFSET = 0x48, 150 PDC_I2C_ADDR_DATA = 0x4C,
99 PDC_I2C_ADDR_DATA_OFFSET = 0x4C, 151 PDC_DIMM0_CONTROL = 0x80,
100 PDC_DIMM0_CONTROL_OFFSET = 0x80, 152 PDC_DIMM1_CONTROL = 0x84,
101 PDC_DIMM1_CONTROL_OFFSET = 0x84, 153 PDC_SDRAM_CONTROL = 0x88,
102 PDC_SDRAM_CONTROL_OFFSET = 0x88, 154 PDC_I2C_WRITE = 0, /* master -> slave */
103 PDC_I2C_WRITE = 0x00000000, 155 PDC_I2C_READ = (1 << 6), /* master <- slave */
104 PDC_I2C_READ = 0x00000040, 156 PDC_I2C_START = (1 << 7), /* start I2C proto */
105 PDC_I2C_START = 0x00000080, 157 PDC_I2C_MASK_INT = (1 << 5), /* mask I2C interrupt */
106 PDC_I2C_MASK_INT = 0x00000020, 158 PDC_I2C_COMPLETE = (1 << 16), /* I2C normal compl. */
107 PDC_I2C_COMPLETE = 0x00010000, 159 PDC_I2C_NO_ACK = (1 << 20), /* slave no-ack addr */
108 PDC_I2C_NO_ACK = 0x00100000, 160 PDC_DIMM_SPD_SUBADDRESS_START = 0x00,
109 PDC_DIMM_SPD_SUBADDRESS_START = 0x00, 161 PDC_DIMM_SPD_SUBADDRESS_END = 0x7F,
110 PDC_DIMM_SPD_SUBADDRESS_END = 0x7F, 162 PDC_DIMM_SPD_ROW_NUM = 3,
111 PDC_DIMM_SPD_ROW_NUM = 3, 163 PDC_DIMM_SPD_COLUMN_NUM = 4,
112 PDC_DIMM_SPD_COLUMN_NUM = 4, 164 PDC_DIMM_SPD_MODULE_ROW = 5,
113 PDC_DIMM_SPD_MODULE_ROW = 5, 165 PDC_DIMM_SPD_TYPE = 11,
114 PDC_DIMM_SPD_TYPE = 11, 166 PDC_DIMM_SPD_FRESH_RATE = 12,
115 PDC_DIMM_SPD_FRESH_RATE = 12, 167 PDC_DIMM_SPD_BANK_NUM = 17,
116 PDC_DIMM_SPD_BANK_NUM = 17, 168 PDC_DIMM_SPD_CAS_LATENCY = 18,
117 PDC_DIMM_SPD_CAS_LATENCY = 18, 169 PDC_DIMM_SPD_ATTRIBUTE = 21,
118 PDC_DIMM_SPD_ATTRIBUTE = 21, 170 PDC_DIMM_SPD_ROW_PRE_CHARGE = 27,
119 PDC_DIMM_SPD_ROW_PRE_CHARGE = 27, 171 PDC_DIMM_SPD_ROW_ACTIVE_DELAY = 28,
120 PDC_DIMM_SPD_ROW_ACTIVE_DELAY = 28, 172 PDC_DIMM_SPD_RAS_CAS_DELAY = 29,
121 PDC_DIMM_SPD_RAS_CAS_DELAY = 29, 173 PDC_DIMM_SPD_ACTIVE_PRECHARGE = 30,
122 PDC_DIMM_SPD_ACTIVE_PRECHARGE = 30, 174 PDC_DIMM_SPD_SYSTEM_FREQ = 126,
123 PDC_DIMM_SPD_SYSTEM_FREQ = 126, 175 PDC_CTL_STATUS = 0x08,
124 PDC_CTL_STATUS = 0x08, 176 PDC_DIMM_WINDOW_CTLR = 0x0C,
125 PDC_DIMM_WINDOW_CTLR = 0x0C, 177 PDC_TIME_CONTROL = 0x3C,
126 PDC_TIME_CONTROL = 0x3C, 178 PDC_TIME_PERIOD = 0x40,
127 PDC_TIME_PERIOD = 0x40, 179 PDC_TIME_COUNTER = 0x44,
128 PDC_TIME_COUNTER = 0x44, 180 PDC_GENERAL_CTLR = 0x484,
129 PDC_GENERAL_CTLR = 0x484, 181 PCI_PLL_INIT = 0x8A531824,
130 PCI_PLL_INIT = 0x8A531824, 182 PCI_X_TCOUNT = 0xEE1E5CFF,
131 PCI_X_TCOUNT = 0xEE1E5CFF 183
184 /* PDC_TIME_CONTROL bits */
185 PDC_TIMER_BUZZER = (1 << 10),
186 PDC_TIMER_MODE_PERIODIC = 0, /* bits 9:8 == 00 */
187 PDC_TIMER_MODE_ONCE = (1 << 8), /* bits 9:8 == 01 */
188 PDC_TIMER_ENABLE = (1 << 7),
189 PDC_TIMER_MASK_INT = (1 << 5),
190 PDC_TIMER_SEQ_MASK = 0x1f, /* SEQ ID for timer */
191 PDC_TIMER_DEFAULT = PDC_TIMER_MODE_ONCE |
192 PDC_TIMER_ENABLE |
193 PDC_TIMER_MASK_INT,
132}; 194};
133 195
134 196
@@ -217,7 +279,7 @@ static const struct ata_port_info pdc_port_info[] = {
217 ATA_FLAG_NO_ATAPI | ATA_FLAG_PIO_POLLING, 279 ATA_FLAG_NO_ATAPI | ATA_FLAG_PIO_POLLING,
218 .pio_mask = 0x1f, /* pio0-4 */ 280 .pio_mask = 0x1f, /* pio0-4 */
219 .mwdma_mask = 0x07, /* mwdma0-2 */ 281 .mwdma_mask = 0x07, /* mwdma0-2 */
220 .udma_mask = 0x7f, /* udma0-6 ; FIXME */ 282 .udma_mask = ATA_UDMA6,
221 .port_ops = &pdc_20621_ops, 283 .port_ops = &pdc_20621_ops,
222 }, 284 },
223 285
@@ -999,17 +1061,17 @@ static unsigned int pdc20621_i2c_read(struct ata_host *host, u32 device,
999 i2creg |= subaddr << 16; 1061 i2creg |= subaddr << 16;
1000 1062
1001 /* Set the device and subaddress */ 1063 /* Set the device and subaddress */
1002 writel(i2creg, mmio + PDC_I2C_ADDR_DATA_OFFSET); 1064 writel(i2creg, mmio + PDC_I2C_ADDR_DATA);
1003 readl(mmio + PDC_I2C_ADDR_DATA_OFFSET); 1065 readl(mmio + PDC_I2C_ADDR_DATA);
1004 1066
1005 /* Write Control to perform read operation, mask int */ 1067 /* Write Control to perform read operation, mask int */
1006 writel(PDC_I2C_READ | PDC_I2C_START | PDC_I2C_MASK_INT, 1068 writel(PDC_I2C_READ | PDC_I2C_START | PDC_I2C_MASK_INT,
1007 mmio + PDC_I2C_CONTROL_OFFSET); 1069 mmio + PDC_I2C_CONTROL);
1008 1070
1009 for (count = 0; count <= 1000; count ++) { 1071 for (count = 0; count <= 1000; count ++) {
1010 status = readl(mmio + PDC_I2C_CONTROL_OFFSET); 1072 status = readl(mmio + PDC_I2C_CONTROL);
1011 if (status & PDC_I2C_COMPLETE) { 1073 if (status & PDC_I2C_COMPLETE) {
1012 status = readl(mmio + PDC_I2C_ADDR_DATA_OFFSET); 1074 status = readl(mmio + PDC_I2C_ADDR_DATA);
1013 break; 1075 break;
1014 } else if (count == 1000) 1076 } else if (count == 1000)
1015 return 0; 1077 return 0;
@@ -1099,8 +1161,8 @@ static int pdc20621_prog_dimm0(struct ata_host *host)
1099 data |= (((size / 16) - 1) << 16); 1161 data |= (((size / 16) - 1) << 16);
1100 data |= (0 << 23); 1162 data |= (0 << 23);
1101 data |= 8; 1163 data |= 8;
1102 writel(data, mmio + PDC_DIMM0_CONTROL_OFFSET); 1164 writel(data, mmio + PDC_DIMM0_CONTROL);
1103 readl(mmio + PDC_DIMM0_CONTROL_OFFSET); 1165 readl(mmio + PDC_DIMM0_CONTROL);
1104 return size; 1166 return size;
1105} 1167}
1106 1168
@@ -1122,27 +1184,27 @@ static unsigned int pdc20621_prog_dimm_global(struct ata_host *host)
1122 */ 1184 */
1123 1185
1124 data = 0x022259F1; 1186 data = 0x022259F1;
1125 writel(data, mmio + PDC_SDRAM_CONTROL_OFFSET); 1187 writel(data, mmio + PDC_SDRAM_CONTROL);
1126 readl(mmio + PDC_SDRAM_CONTROL_OFFSET); 1188 readl(mmio + PDC_SDRAM_CONTROL);
1127 1189
1128 /* Turn on for ECC */ 1190 /* Turn on for ECC */
1129 pdc20621_i2c_read(host, PDC_DIMM0_SPD_DEV_ADDRESS, 1191 pdc20621_i2c_read(host, PDC_DIMM0_SPD_DEV_ADDRESS,
1130 PDC_DIMM_SPD_TYPE, &spd0); 1192 PDC_DIMM_SPD_TYPE, &spd0);
1131 if (spd0 == 0x02) { 1193 if (spd0 == 0x02) {
1132 data |= (0x01 << 16); 1194 data |= (0x01 << 16);
1133 writel(data, mmio + PDC_SDRAM_CONTROL_OFFSET); 1195 writel(data, mmio + PDC_SDRAM_CONTROL);
1134 readl(mmio + PDC_SDRAM_CONTROL_OFFSET); 1196 readl(mmio + PDC_SDRAM_CONTROL);
1135 printk(KERN_ERR "Local DIMM ECC Enabled\n"); 1197 printk(KERN_ERR "Local DIMM ECC Enabled\n");
1136 } 1198 }
1137 1199
1138 /* DIMM Initialization Select/Enable (bit 18/19) */ 1200 /* DIMM Initialization Select/Enable (bit 18/19) */
1139 data &= (~(1<<18)); 1201 data &= (~(1<<18));
1140 data |= (1<<19); 1202 data |= (1<<19);
1141 writel(data, mmio + PDC_SDRAM_CONTROL_OFFSET); 1203 writel(data, mmio + PDC_SDRAM_CONTROL);
1142 1204
1143 error = 1; 1205 error = 1;
1144 for (i = 1; i <= 10; i++) { /* polling ~5 secs */ 1206 for (i = 1; i <= 10; i++) { /* polling ~5 secs */
1145 data = readl(mmio + PDC_SDRAM_CONTROL_OFFSET); 1207 data = readl(mmio + PDC_SDRAM_CONTROL);
1146 if (!(data & (1<<19))) { 1208 if (!(data & (1<<19))) {
1147 error = 0; 1209 error = 0;
1148 break; 1210 break;
@@ -1176,7 +1238,7 @@ static unsigned int pdc20621_dimm_init(struct ata_host *host)
1176 VPRINTK("Time Period Register (0x40): 0x%x\n", time_period); 1238 VPRINTK("Time Period Register (0x40): 0x%x\n", time_period);
1177 1239
1178 /* Enable timer */ 1240 /* Enable timer */
1179 writel(0x00001a0, mmio + PDC_TIME_CONTROL); 1241 writel(PDC_TIMER_DEFAULT, mmio + PDC_TIME_CONTROL);
1180 readl(mmio + PDC_TIME_CONTROL); 1242 readl(mmio + PDC_TIME_CONTROL);
1181 1243
1182 /* Wait 3 seconds */ 1244 /* Wait 3 seconds */
diff --git a/drivers/ata/sata_uli.c b/drivers/ata/sata_uli.c
index 6815de7cca79..aca71819f6e8 100644
--- a/drivers/ata/sata_uli.c
+++ b/drivers/ata/sata_uli.c
@@ -129,7 +129,7 @@ static const struct ata_port_info uli_port_info = {
129 .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | 129 .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
130 ATA_FLAG_IGN_SIMPLEX, 130 ATA_FLAG_IGN_SIMPLEX,
131 .pio_mask = 0x1f, /* pio0-4 */ 131 .pio_mask = 0x1f, /* pio0-4 */
132 .udma_mask = 0x7f, /* udma0-6 */ 132 .udma_mask = ATA_UDMA6,
133 .port_ops = &uli_ops, 133 .port_ops = &uli_ops,
134}; 134};
135 135
diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c
index e8b90e7b42dd..a4c0832033d8 100644
--- a/drivers/ata/sata_via.c
+++ b/drivers/ata/sata_via.c
@@ -223,7 +223,7 @@ static const struct ata_port_info vt6420_port_info = {
223 .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY, 223 .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY,
224 .pio_mask = 0x1f, 224 .pio_mask = 0x1f,
225 .mwdma_mask = 0x07, 225 .mwdma_mask = 0x07,
226 .udma_mask = 0x7f, 226 .udma_mask = ATA_UDMA6,
227 .port_ops = &vt6420_sata_ops, 227 .port_ops = &vt6420_sata_ops,
228}; 228};
229 229
@@ -231,7 +231,7 @@ static struct ata_port_info vt6421_sport_info = {
231 .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY, 231 .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY,
232 .pio_mask = 0x1f, 232 .pio_mask = 0x1f,
233 .mwdma_mask = 0x07, 233 .mwdma_mask = 0x07,
234 .udma_mask = 0x7f, 234 .udma_mask = ATA_UDMA6,
235 .port_ops = &vt6421_sata_ops, 235 .port_ops = &vt6421_sata_ops,
236}; 236};
237 237
@@ -239,7 +239,7 @@ static struct ata_port_info vt6421_pport_info = {
239 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_NO_LEGACY, 239 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_NO_LEGACY,
240 .pio_mask = 0x1f, 240 .pio_mask = 0x1f,
241 .mwdma_mask = 0, 241 .mwdma_mask = 0,
242 .udma_mask = 0x7f, 242 .udma_mask = ATA_UDMA6,
243 .port_ops = &vt6421_pata_ops, 243 .port_ops = &vt6421_pata_ops,
244}; 244};
245 245
@@ -303,9 +303,7 @@ static int vt6420_prereset(struct ata_port *ap, unsigned long deadline)
303 if (!(ap->pflags & ATA_PFLAG_LOADING)) 303 if (!(ap->pflags & ATA_PFLAG_LOADING))
304 goto skip_scr; 304 goto skip_scr;
305 305
306 /* Resume phy. This is the old resume sequence from 306 /* Resume phy. This is the old SATA resume sequence */
307 * __sata_phy_reset().
308 */
309 svia_scr_write(ap, SCR_CONTROL, 0x300); 307 svia_scr_write(ap, SCR_CONTROL, 0x300);
310 svia_scr_read(ap, SCR_CONTROL); /* flush */ 308 svia_scr_read(ap, SCR_CONTROL); /* flush */
311 309
diff --git a/drivers/ata/sata_vsc.c b/drivers/ata/sata_vsc.c
index 81330175fc89..1b5d81faa102 100644
--- a/drivers/ata/sata_vsc.c
+++ b/drivers/ata/sata_vsc.c
@@ -371,7 +371,7 @@ static int __devinit vsc_sata_init_one (struct pci_dev *pdev, const struct pci_d
371 ATA_FLAG_MMIO, 371 ATA_FLAG_MMIO,
372 .pio_mask = 0x1f, 372 .pio_mask = 0x1f,
373 .mwdma_mask = 0x07, 373 .mwdma_mask = 0x07,
374 .udma_mask = 0x7f, 374 .udma_mask = ATA_UDMA6,
375 .port_ops = &vsc_sata_ops, 375 .port_ops = &vsc_sata_ops,
376 }; 376 };
377 const struct ata_port_info *ppi[] = { &pi, NULL }; 377 const struct ata_port_info *ppi[] = { &pi, NULL };
diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig
index b4c8319138b2..6e23af1ecbdb 100644
--- a/drivers/block/Kconfig
+++ b/drivers/block/Kconfig
@@ -2,9 +2,12 @@
2# Block device driver configuration 2# Block device driver configuration
3# 3#
4 4
5if BLOCK 5menuconfig BLK_DEV
6 bool "Block devices"
7 depends on BLOCK
8 default y
6 9
7menu "Block devices" 10if BLK_DEV
8 11
9config BLK_DEV_FD 12config BLK_DEV_FD
10 tristate "Normal floppy disk support" 13 tristate "Normal floppy disk support"
@@ -56,40 +59,9 @@ config AMIGA_Z2RAM
56 To compile this driver as a module, choose M here: the 59 To compile this driver as a module, choose M here: the
57 module will be called z2ram. 60 module will be called z2ram.
58 61
59config ATARI_ACSI
60 tristate "Atari ACSI support"
61 depends on ATARI && BROKEN
62 ---help---
63 This enables support for the Atari ACSI interface. The driver
64 supports hard disks and CD-ROMs, which have 512-byte sectors, or can
65 be switched to that mode. Due to the ACSI command format, only disks
66 up to 1 GB are supported. Special support for certain ACSI to SCSI
67 adapters, which could relax that, isn't included yet. The ACSI
68 driver is also the basis for certain other drivers for devices
69 attached to the ACSI bus: Atari SLM laser printer, BioNet-100
70 Ethernet, and PAMsNet Ethernet. If you want to use one of these
71 devices, you need ACSI support, too.
72
73 To compile this driver as a module, choose M here: the
74 module will be called acsi.
75
76comment "Some devices (e.g. CD jukebox) support multiple LUNs"
77 depends on ATARI && ATARI_ACSI
78
79config ACSI_MULTI_LUN
80 bool "Probe all LUNs on each ACSI device"
81 depends on ATARI_ACSI
82 help
83 If you have a ACSI device that supports more than one LUN (Logical
84 Unit Number), e.g. a CD jukebox, you should say Y here so that all
85 will be found by the ACSI driver. An ACSI device with multiple LUNs
86 acts logically like multiple ACSI devices. The vast majority of ACSI
87 devices have only one LUN, and so most people can say N here and
88 should in fact do so, because it is safer.
89
90config ATARI_SLM 62config ATARI_SLM
91 tristate "Atari SLM laser printer support" 63 tristate "Atari SLM laser printer support"
92 depends on ATARI && ATARI_ACSI!=n 64 depends on ATARI
93 help 65 help
94 If you have an Atari SLM laser printer, say Y to include support for 66 If you have an Atari SLM laser printer, say Y to include support for
95 it in the kernel. Otherwise, say N. This driver is also available as 67 it in the kernel. Otherwise, say N. This driver is also available as
@@ -453,6 +425,4 @@ config ATA_OVER_ETH
453 425
454source "drivers/s390/block/Kconfig" 426source "drivers/s390/block/Kconfig"
455 427
456endmenu 428endif # BLK_DEV
457
458endif
diff --git a/drivers/block/Makefile b/drivers/block/Makefile
index dd88e33c1eb1..e5f98acc5d52 100644
--- a/drivers/block/Makefile
+++ b/drivers/block/Makefile
@@ -9,7 +9,6 @@ obj-$(CONFIG_MAC_FLOPPY) += swim3.o
9obj-$(CONFIG_BLK_DEV_FD) += floppy.o 9obj-$(CONFIG_BLK_DEV_FD) += floppy.o
10obj-$(CONFIG_AMIGA_FLOPPY) += amiflop.o 10obj-$(CONFIG_AMIGA_FLOPPY) += amiflop.o
11obj-$(CONFIG_ATARI_FLOPPY) += ataflop.o 11obj-$(CONFIG_ATARI_FLOPPY) += ataflop.o
12obj-$(CONFIG_ATARI_ACSI) += acsi.o
13obj-$(CONFIG_ATARI_SLM) += acsi_slm.o 12obj-$(CONFIG_ATARI_SLM) += acsi_slm.o
14obj-$(CONFIG_AMIGA_Z2RAM) += z2ram.o 13obj-$(CONFIG_AMIGA_Z2RAM) += z2ram.o
15obj-$(CONFIG_BLK_DEV_RAM) += rd.o 14obj-$(CONFIG_BLK_DEV_RAM) += rd.o
diff --git a/drivers/block/acsi.c b/drivers/block/acsi.c
deleted file mode 100644
index e3d9152e231a..000000000000
--- a/drivers/block/acsi.c
+++ /dev/null
@@ -1,1825 +0,0 @@
1/*
2 * acsi.c -- Device driver for Atari ACSI hard disks
3 *
4 * Copyright 1994 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de>
5 *
6 * Some parts are based on hd.c by Linus Torvalds
7 *
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file COPYING in the main directory of this archive for
10 * more details.
11 *
12 */
13
14/*
15 * Still to in this file:
16 * - If a command ends with an error status (!= 0), the following
17 * REQUEST SENSE commands (4 to fill the ST-DMA FIFO) are done by
18 * polling the _IRQ signal (not interrupt-driven). This should be
19 * avoided in future because it takes up a non-neglectible time in
20 * the interrupt service routine while interrupts are disabled.
21 * Maybe a timer interrupt will get lost :-(
22 */
23
24/*
25 * General notes:
26 *
27 * - All ACSI devices (disks, CD-ROMs, ...) use major number 28.
28 * Minors are organized like it is with SCSI: The upper 4 bits
29 * identify the device, the lower 4 bits the partition.
30 * The device numbers (the upper 4 bits) are given in the same
31 * order as the devices are found on the bus.
32 * - Up to 8 LUNs are supported for each target (if CONFIG_ACSI_MULTI_LUN
33 * is defined), but only a total of 16 devices (due to minor
34 * numbers...). Note that Atari allows only a maximum of 4 targets
35 * (i.e. controllers, not devices) on the ACSI bus!
36 * - A optimizing scheme similar to SCSI scatter-gather is implemented.
37 * - Removable media are supported. After a medium change to device
38 * is reinitialized (partition check etc.). Also, if the device
39 * knows the PREVENT/ALLOW MEDIUM REMOVAL command, the door should
40 * be locked and unlocked when mounting the first or unmounting the
41 * last filesystem on the device. The code is untested, because I
42 * don't have a removable hard disk.
43 *
44 */
45
46#include <linux/module.h>
47#include <linux/errno.h>
48#include <linux/signal.h>
49#include <linux/timer.h>
50#include <linux/fs.h>
51#include <linux/kernel.h>
52#include <linux/genhd.h>
53#include <linux/delay.h>
54#include <linux/mm.h>
55#include <linux/major.h>
56#include <linux/slab.h>
57#include <linux/interrupt.h>
58#include <scsi/scsi.h> /* for SCSI_IOCTL_GET_IDLUN */
59#include <scsi/scsi_ioctl.h>
60#include <linux/hdreg.h> /* for HDIO_GETGEO */
61#include <linux/blkpg.h>
62#include <linux/buffer_head.h>
63#include <linux/blkdev.h>
64
65#include <asm/setup.h>
66#include <asm/pgtable.h>
67#include <asm/system.h>
68#include <asm/uaccess.h>
69#include <asm/atarihw.h>
70#include <asm/atariints.h>
71#include <asm/atari_acsi.h>
72#include <asm/atari_stdma.h>
73#include <asm/atari_stram.h>
74
75static void (*do_acsi)(void) = NULL;
76static struct request_queue *acsi_queue;
77#define QUEUE (acsi_queue)
78#define CURRENT elv_next_request(acsi_queue)
79
80#define DEBUG
81#undef DEBUG_DETECT
82#undef NO_WRITE
83
84#define MAX_ERRORS 8 /* Max read/write errors/sector */
85#define MAX_LUN 8 /* Max LUNs per target */
86#define MAX_DEV 16
87
88#define ACSI_BUFFER_SIZE (16*1024) /* "normal" ACSI buffer size */
89#define ACSI_BUFFER_MINSIZE (2048) /* min. buf size if ext. DMA */
90#define ACSI_BUFFER_SIZE_ORDER 2 /* order size for above */
91#define ACSI_BUFFER_MINSIZE_ORDER 0 /* order size for above */
92#define ACSI_BUFFER_SECTORS (ACSI_BUFFER_SIZE/512)
93
94#define ACSI_BUFFER_ORDER \
95 (ATARIHW_PRESENT(EXTD_DMA) ? \
96 ACSI_BUFFER_MINSIZE_ORDER : \
97 ACSI_BUFFER_SIZE_ORDER)
98
99#define ACSI_TIMEOUT (4*HZ)
100
101/* minimum delay between two commands */
102
103#define COMMAND_DELAY 500
104
105typedef enum {
106 NONE, HARDDISK, CDROM
107} ACSI_TYPE;
108
109struct acsi_info_struct {
110 ACSI_TYPE type; /* type of device */
111 unsigned target; /* target number */
112 unsigned lun; /* LUN in target controller */
113 unsigned removable : 1; /* Flag for removable media */
114 unsigned read_only : 1; /* Flag for read only devices */
115 unsigned old_atari_disk : 1; /* Is an old Atari disk */
116 unsigned changed : 1; /* Medium has been changed */
117 unsigned long size; /* #blocks */
118 int access_count;
119} acsi_info[MAX_DEV];
120
121/*
122 * SENSE KEYS
123 */
124
125#define NO_SENSE 0x00
126#define RECOVERED_ERROR 0x01
127#define NOT_READY 0x02
128#define MEDIUM_ERROR 0x03
129#define HARDWARE_ERROR 0x04
130#define ILLEGAL_REQUEST 0x05
131#define UNIT_ATTENTION 0x06
132#define DATA_PROTECT 0x07
133#define BLANK_CHECK 0x08
134#define COPY_ABORTED 0x0a
135#define ABORTED_COMMAND 0x0b
136#define VOLUME_OVERFLOW 0x0d
137#define MISCOMPARE 0x0e
138
139
140/*
141 * DEVICE TYPES
142 */
143
144#define TYPE_DISK 0x00
145#define TYPE_TAPE 0x01
146#define TYPE_WORM 0x04
147#define TYPE_ROM 0x05
148#define TYPE_MOD 0x07
149#define TYPE_NO_LUN 0x7f
150
151/* The data returned by MODE SENSE differ between the old Atari
152 * hard disks and SCSI disks connected to ACSI. In the following, both
153 * formats are defined and some macros to operate on them potably.
154 */
155
156typedef struct {
157 unsigned long dummy[2];
158 unsigned long sector_size;
159 unsigned char format_code;
160#define ATARI_SENSE_FORMAT_FIX 1
161#define ATARI_SENSE_FORMAT_CHNG 2
162 unsigned char cylinders_h;
163 unsigned char cylinders_l;
164 unsigned char heads;
165 unsigned char reduced_h;
166 unsigned char reduced_l;
167 unsigned char precomp_h;
168 unsigned char precomp_l;
169 unsigned char landing_zone;
170 unsigned char steprate;
171 unsigned char type;
172#define ATARI_SENSE_TYPE_FIXCHNG_MASK 4
173#define ATARI_SENSE_TYPE_SOFTHARD_MASK 8
174#define ATARI_SENSE_TYPE_FIX 4
175#define ATARI_SENSE_TYPE_CHNG 0
176#define ATARI_SENSE_TYPE_SOFT 0
177#define ATARI_SENSE_TYPE_HARD 8
178 unsigned char sectors;
179} ATARI_SENSE_DATA;
180
181#define ATARI_CAPACITY(sd) \
182 (((int)((sd).cylinders_h<<8)|(sd).cylinders_l) * \
183 (sd).heads * (sd).sectors)
184
185
186typedef struct {
187 unsigned char dummy1;
188 unsigned char medium_type;
189 unsigned char dummy2;
190 unsigned char descriptor_size;
191 unsigned long block_count;
192 unsigned long sector_size;
193 /* Page 0 data */
194 unsigned char page_code;
195 unsigned char page_size;
196 unsigned char page_flags;
197 unsigned char qualifier;
198} SCSI_SENSE_DATA;
199
200#define SCSI_CAPACITY(sd) ((sd).block_count & 0xffffff)
201
202
203typedef union {
204 ATARI_SENSE_DATA atari;
205 SCSI_SENSE_DATA scsi;
206} SENSE_DATA;
207
208#define SENSE_TYPE_UNKNOWN 0
209#define SENSE_TYPE_ATARI 1
210#define SENSE_TYPE_SCSI 2
211
212#define SENSE_TYPE(sd) \
213 (((sd).atari.dummy[0] == 8 && \
214 ((sd).atari.format_code == 1 || \
215 (sd).atari.format_code == 2)) ? SENSE_TYPE_ATARI : \
216 ((sd).scsi.dummy1 >= 11) ? SENSE_TYPE_SCSI : \
217 SENSE_TYPE_UNKNOWN)
218
219#define CAPACITY(sd) \
220 (SENSE_TYPE(sd) == SENSE_TYPE_ATARI ? \
221 ATARI_CAPACITY((sd).atari) : \
222 SCSI_CAPACITY((sd).scsi))
223
224#define SECTOR_SIZE(sd) \
225 (SENSE_TYPE(sd) == SENSE_TYPE_ATARI ? \
226 (sd).atari.sector_size : \
227 (sd).scsi.sector_size & 0xffffff)
228
229/* Default size if capacity cannot be determined (1 GByte) */
230#define DEFAULT_SIZE 0x1fffff
231
232#define CARTRCH_STAT(aip,buf) \
233 (aip->old_atari_disk ? \
234 (((buf)[0] & 0x7f) == 0x28) : \
235 ((((buf)[0] & 0x70) == 0x70) ? \
236 (((buf)[2] & 0x0f) == 0x06) : \
237 (((buf)[0] & 0x0f) == 0x06))) \
238
239/* These two are also exported to other drivers that work on the ACSI bus and
240 * need an ST-RAM buffer. */
241char *acsi_buffer;
242unsigned long phys_acsi_buffer;
243
244static int NDevices;
245
246static int CurrentNReq;
247static int CurrentNSect;
248static char *CurrentBuffer;
249
250static DEFINE_SPINLOCK(acsi_lock);
251
252
253#define SET_TIMER() mod_timer(&acsi_timer, jiffies + ACSI_TIMEOUT)
254#define CLEAR_TIMER() del_timer(&acsi_timer)
255
256static unsigned long STramMask;
257#define STRAM_ADDR(a) (((a) & STramMask) == 0)
258
259
260
261/* ACSI commands */
262
263static char tur_cmd[6] = { 0x00, 0, 0, 0, 0, 0 };
264static char modesense_cmd[6] = { 0x1a, 0, 0, 0, 24, 0 };
265static char modeselect_cmd[6] = { 0x15, 0, 0, 0, 12, 0 };
266static char inquiry_cmd[6] = { 0x12, 0, 0, 0,255, 0 };
267static char reqsense_cmd[6] = { 0x03, 0, 0, 0, 4, 0 };
268static char read_cmd[6] = { 0x08, 0, 0, 0, 0, 0 };
269static char write_cmd[6] = { 0x0a, 0, 0, 0, 0, 0 };
270static char pa_med_rem_cmd[6] = { 0x1e, 0, 0, 0, 0, 0 };
271
272#define CMDSET_TARG_LUN(cmd,targ,lun) \
273 do { \
274 cmd[0] = (cmd[0] & ~0xe0) | (targ)<<5; \
275 cmd[1] = (cmd[1] & ~0xe0) | (lun)<<5; \
276 } while(0)
277
278#define CMDSET_BLOCK(cmd,blk) \
279 do { \
280 unsigned long __blk = (blk); \
281 cmd[3] = __blk; __blk >>= 8; \
282 cmd[2] = __blk; __blk >>= 8; \
283 cmd[1] = (cmd[1] & 0xe0) | (__blk & 0x1f); \
284 } while(0)
285
286#define CMDSET_LEN(cmd,len) \
287 do { \
288 cmd[4] = (len); \
289 } while(0)
290
291/* ACSI errors (from REQUEST SENSE); There are two tables, one for the
292 * old Atari disks and one for SCSI on ACSI disks.
293 */
294
295struct acsi_error {
296 unsigned char code;
297 const char *text;
298} atari_acsi_errors[] = {
299 { 0x00, "No error (??)" },
300 { 0x01, "No index pulses" },
301 { 0x02, "Seek not complete" },
302 { 0x03, "Write fault" },
303 { 0x04, "Drive not ready" },
304 { 0x06, "No Track 00 signal" },
305 { 0x10, "ECC error in ID field" },
306 { 0x11, "Uncorrectable data error" },
307 { 0x12, "ID field address mark not found" },
308 { 0x13, "Data field address mark not found" },
309 { 0x14, "Record not found" },
310 { 0x15, "Seek error" },
311 { 0x18, "Data check in no retry mode" },
312 { 0x19, "ECC error during verify" },
313 { 0x1a, "Access to bad block" },
314 { 0x1c, "Unformatted or bad format" },
315 { 0x20, "Invalid command" },
316 { 0x21, "Invalid block address" },
317 { 0x23, "Volume overflow" },
318 { 0x24, "Invalid argument" },
319 { 0x25, "Invalid drive number" },
320 { 0x26, "Byte zero parity check" },
321 { 0x28, "Cartride changed" },
322 { 0x2c, "Error count overflow" },
323 { 0x30, "Controller selftest failed" }
324},
325
326 scsi_acsi_errors[] = {
327 { 0x00, "No error (??)" },
328 { 0x01, "Recovered error" },
329 { 0x02, "Drive not ready" },
330 { 0x03, "Uncorrectable medium error" },
331 { 0x04, "Hardware error" },
332 { 0x05, "Illegal request" },
333 { 0x06, "Unit attention (Reset or cartridge changed)" },
334 { 0x07, "Data protection" },
335 { 0x08, "Blank check" },
336 { 0x0b, "Aborted Command" },
337 { 0x0d, "Volume overflow" }
338};
339
340
341
342/***************************** Prototypes *****************************/
343
344static int acsicmd_dma( const char *cmd, char *buffer, int blocks, int
345 rwflag, int enable);
346static int acsi_reqsense( char *buffer, int targ, int lun);
347static void acsi_print_error(const unsigned char *errblk, struct acsi_info_struct *aip);
348static irqreturn_t acsi_interrupt (int irq, void *data);
349static void unexpected_acsi_interrupt( void );
350static void bad_rw_intr( void );
351static void read_intr( void );
352static void write_intr( void);
353static void acsi_times_out( unsigned long dummy );
354static void copy_to_acsibuffer( void );
355static void copy_from_acsibuffer( void );
356static void do_end_requests( void );
357static void do_acsi_request( request_queue_t * );
358static void redo_acsi_request( void );
359static int acsi_ioctl( struct inode *inode, struct file *file, unsigned int
360 cmd, unsigned long arg );
361static int acsi_open( struct inode * inode, struct file * filp );
362static int acsi_release( struct inode * inode, struct file * file );
363static void acsi_prevent_removal(struct acsi_info_struct *aip, int flag );
364static int acsi_change_blk_size( int target, int lun);
365static int acsi_mode_sense( int target, int lun, SENSE_DATA *sd );
366static int acsi_revalidate (struct gendisk *disk);
367
368/************************* End of Prototypes **************************/
369
370
371DEFINE_TIMER(acsi_timer, acsi_times_out, 0, 0);
372
373
374#ifdef CONFIG_ATARI_SLM
375
376extern int attach_slm( int target, int lun );
377extern int slm_init( void );
378
379#endif
380
381
382
383/***********************************************************************
384 *
385 * ACSI primitives
386 *
387 **********************************************************************/
388
389
390/*
391 * The following two functions wait for _IRQ to become Low or High,
392 * resp., with a timeout. The 'timeout' parameter is in jiffies
393 * (10ms).
394 * If the functions are called with timer interrupts on (int level <
395 * 6), the timeout is based on the 'jiffies' variable to provide exact
396 * timeouts for device probing etc.
397 * If interrupts are disabled, the number of tries is based on the
398 * 'loops_per_jiffy' variable. A rough estimation is sufficient here...
399 */
400
401#define INT_LEVEL \
402 ({ unsigned __sr; \
403 __asm__ __volatile__ ( "movew %/sr,%0" : "=dm" (__sr) ); \
404 (__sr >> 8) & 7; \
405 })
406
407int acsi_wait_for_IRQ( unsigned timeout )
408
409{
410 if (INT_LEVEL < 6) {
411 unsigned long maxjif = jiffies + timeout;
412 while (time_before(jiffies, maxjif))
413 if (!(mfp.par_dt_reg & 0x20)) return( 1 );
414 }
415 else {
416 long tries = loops_per_jiffy / 8 * timeout;
417 while( --tries >= 0 )
418 if (!(mfp.par_dt_reg & 0x20)) return( 1 );
419 }
420 return( 0 ); /* timeout! */
421}
422
423
424int acsi_wait_for_noIRQ( unsigned timeout )
425
426{
427 if (INT_LEVEL < 6) {
428 unsigned long maxjif = jiffies + timeout;
429 while (time_before(jiffies, maxjif))
430 if (mfp.par_dt_reg & 0x20) return( 1 );
431 }
432 else {
433 long tries = loops_per_jiffy * timeout / 8;
434 while( tries-- >= 0 )
435 if (mfp.par_dt_reg & 0x20) return( 1 );
436 }
437 return( 0 ); /* timeout! */
438}
439
440static struct timeval start_time;
441
442void
443acsi_delay_start(void)
444{
445 do_gettimeofday(&start_time);
446}
447
448/* wait from acsi_delay_start to now usec (<1E6) usec */
449
450void
451acsi_delay_end(long usec)
452{
453 struct timeval end_time;
454 long deltau,deltas;
455 do_gettimeofday(&end_time);
456 deltau=end_time.tv_usec - start_time.tv_usec;
457 deltas=end_time.tv_sec - start_time.tv_sec;
458 if (deltas > 1 || deltas < 0)
459 return;
460 if (deltas > 0)
461 deltau += 1000*1000;
462 if (deltau >= usec)
463 return;
464 udelay(usec-deltau);
465}
466
467/* acsicmd_dma() sends an ACSI command and sets up the DMA to transfer
468 * 'blocks' blocks of 512 bytes from/to 'buffer'.
469 * Because the _IRQ signal is used for handshaking the command bytes,
470 * the ACSI interrupt has to be disabled in this function. If the end
471 * of the operation should be signalled by a real interrupt, it has to be
472 * reenabled afterwards.
473 */
474
475static int acsicmd_dma( const char *cmd, char *buffer, int blocks, int rwflag, int enable)
476
477{ unsigned long flags, paddr;
478 int i;
479
480#ifdef NO_WRITE
481 if (rwflag || *cmd == 0x0a) {
482 printk( "ACSI: Write commands disabled!\n" );
483 return( 0 );
484 }
485#endif
486
487 rwflag = rwflag ? 0x100 : 0;
488 paddr = virt_to_phys( buffer );
489
490 acsi_delay_end(COMMAND_DELAY);
491 DISABLE_IRQ();
492
493 local_irq_save(flags);
494 /* Low on A1 */
495 dma_wd.dma_mode_status = 0x88 | rwflag;
496 MFPDELAY();
497
498 /* set DMA address */
499 dma_wd.dma_lo = (unsigned char)paddr;
500 paddr >>= 8;
501 MFPDELAY();
502 dma_wd.dma_md = (unsigned char)paddr;
503 paddr >>= 8;
504 MFPDELAY();
505 if (ATARIHW_PRESENT(EXTD_DMA))
506 st_dma_ext_dmahi = (unsigned short)paddr;
507 else
508 dma_wd.dma_hi = (unsigned char)paddr;
509 MFPDELAY();
510 local_irq_restore(flags);
511
512 /* send the command bytes except the last */
513 for( i = 0; i < 5; ++i ) {
514 DMA_LONG_WRITE( *cmd++, 0x8a | rwflag );
515 udelay(20);
516 if (!acsi_wait_for_IRQ( HZ/2 )) return( 0 ); /* timeout */
517 }
518
519 /* Clear FIFO and switch DMA to correct direction */
520 dma_wd.dma_mode_status = 0x92 | (rwflag ^ 0x100);
521 MFPDELAY();
522 dma_wd.dma_mode_status = 0x92 | rwflag;
523 MFPDELAY();
524
525 /* How many sectors for DMA */
526 dma_wd.fdc_acces_seccount = blocks;
527 MFPDELAY();
528
529 /* send last command byte */
530 dma_wd.dma_mode_status = 0x8a | rwflag;
531 MFPDELAY();
532 DMA_LONG_WRITE( *cmd++, 0x0a | rwflag );
533 if (enable)
534 ENABLE_IRQ();
535 udelay(80);
536
537 return( 1 );
538}
539
540
541/*
542 * acsicmd_nodma() sends an ACSI command that requires no DMA.
543 */
544
545int acsicmd_nodma( const char *cmd, int enable)
546
547{ int i;
548
549 acsi_delay_end(COMMAND_DELAY);
550 DISABLE_IRQ();
551
552 /* send first command byte */
553 dma_wd.dma_mode_status = 0x88;
554 MFPDELAY();
555 DMA_LONG_WRITE( *cmd++, 0x8a );
556 udelay(20);
557 if (!acsi_wait_for_IRQ( HZ/2 )) return( 0 ); /* timeout */
558
559 /* send the intermediate command bytes */
560 for( i = 0; i < 4; ++i ) {
561 DMA_LONG_WRITE( *cmd++, 0x8a );
562 udelay(20);
563 if (!acsi_wait_for_IRQ( HZ/2 )) return( 0 ); /* timeout */
564 }
565
566 /* send last command byte */
567 DMA_LONG_WRITE( *cmd++, 0x0a );
568 if (enable)
569 ENABLE_IRQ();
570 udelay(80);
571
572 return( 1 );
573 /* Note that the ACSI interrupt is still disabled after this
574 * function. If you want to get the IRQ delivered, enable it manually!
575 */
576}
577
578
579static int acsi_reqsense( char *buffer, int targ, int lun)
580
581{
582 CMDSET_TARG_LUN( reqsense_cmd, targ, lun);
583 if (!acsicmd_dma( reqsense_cmd, buffer, 1, 0, 0 )) return( 0 );
584 if (!acsi_wait_for_IRQ( 10 )) return( 0 );
585 acsi_getstatus();
586 if (!acsicmd_nodma( reqsense_cmd, 0 )) return( 0 );
587 if (!acsi_wait_for_IRQ( 10 )) return( 0 );
588 acsi_getstatus();
589 if (!acsicmd_nodma( reqsense_cmd, 0 )) return( 0 );
590 if (!acsi_wait_for_IRQ( 10 )) return( 0 );
591 acsi_getstatus();
592 if (!acsicmd_nodma( reqsense_cmd, 0 )) return( 0 );
593 if (!acsi_wait_for_IRQ( 10 )) return( 0 );
594 acsi_getstatus();
595 dma_cache_maintenance( virt_to_phys(buffer), 16, 0 );
596
597 return( 1 );
598}
599
600
601/*
602 * ACSI status phase: get the status byte from the bus
603 *
604 * I've seen several times that a 0xff status is read, propably due to
605 * a timing error. In this case, the procedure is repeated after the
606 * next _IRQ edge.
607 */
608
609int acsi_getstatus( void )
610
611{ int status;
612
613 DISABLE_IRQ();
614 for(;;) {
615 if (!acsi_wait_for_IRQ( 100 )) {
616 acsi_delay_start();
617 return( -1 );
618 }
619 dma_wd.dma_mode_status = 0x8a;
620 MFPDELAY();
621 status = dma_wd.fdc_acces_seccount;
622 if (status != 0xff) break;
623#ifdef DEBUG
624 printk("ACSI: skipping 0xff status byte\n" );
625#endif
626 udelay(40);
627 acsi_wait_for_noIRQ( 20 );
628 }
629 dma_wd.dma_mode_status = 0x80;
630 udelay(40);
631 acsi_wait_for_noIRQ( 20 );
632
633 acsi_delay_start();
634 return( status & 0x1f ); /* mask of the device# */
635}
636
637
638#if (defined(CONFIG_ATARI_SLM) || defined(CONFIG_ATARI_SLM_MODULE))
639
640/* Receive data in an extended status phase. Needed by SLM printer. */
641
642int acsi_extstatus( char *buffer, int cnt )
643
644{ int status;
645
646 DISABLE_IRQ();
647 udelay(80);
648 while( cnt-- > 0 ) {
649 if (!acsi_wait_for_IRQ( 40 )) return( 0 );
650 dma_wd.dma_mode_status = 0x8a;
651 MFPDELAY();
652 status = dma_wd.fdc_acces_seccount;
653 MFPDELAY();
654 *buffer++ = status & 0xff;
655 udelay(40);
656 }
657 return( 1 );
658}
659
660
661/* Finish an extended status phase */
662
663void acsi_end_extstatus( void )
664
665{
666 dma_wd.dma_mode_status = 0x80;
667 udelay(40);
668 acsi_wait_for_noIRQ( 20 );
669 acsi_delay_start();
670}
671
672
673/* Send data in an extended command phase */
674
675int acsi_extcmd( unsigned char *buffer, int cnt )
676
677{
678 while( cnt-- > 0 ) {
679 DMA_LONG_WRITE( *buffer++, 0x8a );
680 udelay(20);
681 if (!acsi_wait_for_IRQ( HZ/2 )) return( 0 ); /* timeout */
682 }
683 return( 1 );
684}
685
686#endif
687
688
689static void acsi_print_error(const unsigned char *errblk, struct acsi_info_struct *aip)
690
691{ int atari_err, i, errcode;
692 struct acsi_error *arr;
693
694 atari_err = aip->old_atari_disk;
695 if (atari_err)
696 errcode = errblk[0] & 0x7f;
697 else
698 if ((errblk[0] & 0x70) == 0x70)
699 errcode = errblk[2] & 0x0f;
700 else
701 errcode = errblk[0] & 0x0f;
702
703 printk( KERN_ERR "ACSI error 0x%02x", errcode );
704
705 if (errblk[0] & 0x80)
706 printk( " for sector %d",
707 ((errblk[1] & 0x1f) << 16) |
708 (errblk[2] << 8) | errblk[0] );
709
710 arr = atari_err ? atari_acsi_errors : scsi_acsi_errors;
711 i = atari_err ? sizeof(atari_acsi_errors)/sizeof(*atari_acsi_errors) :
712 sizeof(scsi_acsi_errors)/sizeof(*scsi_acsi_errors);
713
714 for( --i; i >= 0; --i )
715 if (arr[i].code == errcode) break;
716 if (i >= 0)
717 printk( ": %s\n", arr[i].text );
718}
719
720/*******************************************************************
721 *
722 * ACSI interrupt routine
723 * Test, if this is a ACSI interrupt and call the irq handler
724 * Otherwise ignore this interrupt.
725 *
726 *******************************************************************/
727
728static irqreturn_t acsi_interrupt(int irq, void *data )
729
730{ void (*acsi_irq_handler)(void) = do_acsi;
731
732 do_acsi = NULL;
733 CLEAR_TIMER();
734
735 if (!acsi_irq_handler)
736 acsi_irq_handler = unexpected_acsi_interrupt;
737 acsi_irq_handler();
738 return IRQ_HANDLED;
739}
740
741
742/******************************************************************
743 *
744 * The Interrupt handlers
745 *
746 *******************************************************************/
747
748
749static void unexpected_acsi_interrupt( void )
750
751{
752 printk( KERN_WARNING "Unexpected ACSI interrupt\n" );
753}
754
755
756/* This function is called in case of errors. Because we cannot reset
757 * the ACSI bus or a single device, there is no other choice than
758 * retrying several times :-(
759 */
760
761static void bad_rw_intr( void )
762
763{
764 if (!CURRENT)
765 return;
766
767 if (++CURRENT->errors >= MAX_ERRORS)
768 end_request(CURRENT, 0);
769 /* Otherwise just retry */
770}
771
772
773static void read_intr( void )
774
775{ int status;
776
777 status = acsi_getstatus();
778 if (status != 0) {
779 struct gendisk *disk = CURRENT->rq_disk;
780 struct acsi_info_struct *aip = disk->private_data;
781 printk(KERN_ERR "%s: ", disk->disk_name);
782 if (!acsi_reqsense(acsi_buffer, aip->target, aip->lun))
783 printk( "ACSI error and REQUEST SENSE failed (status=0x%02x)\n", status );
784 else {
785 acsi_print_error(acsi_buffer, aip);
786 if (CARTRCH_STAT(aip, acsi_buffer))
787 aip->changed = 1;
788 }
789 ENABLE_IRQ();
790 bad_rw_intr();
791 redo_acsi_request();
792 return;
793 }
794
795 dma_cache_maintenance( virt_to_phys(CurrentBuffer), CurrentNSect*512, 0 );
796 if (CurrentBuffer == acsi_buffer)
797 copy_from_acsibuffer();
798
799 do_end_requests();
800 redo_acsi_request();
801}
802
803
804static void write_intr(void)
805
806{ int status;
807
808 status = acsi_getstatus();
809 if (status != 0) {
810 struct gendisk *disk = CURRENT->rq_disk;
811 struct acsi_info_struct *aip = disk->private_data;
812 printk( KERN_ERR "%s: ", disk->disk_name);
813 if (!acsi_reqsense( acsi_buffer, aip->target, aip->lun))
814 printk( "ACSI error and REQUEST SENSE failed (status=0x%02x)\n", status );
815 else {
816 acsi_print_error(acsi_buffer, aip);
817 if (CARTRCH_STAT(aip, acsi_buffer))
818 aip->changed = 1;
819 }
820 bad_rw_intr();
821 redo_acsi_request();
822 return;
823 }
824
825 do_end_requests();
826 redo_acsi_request();
827}
828
829
830static void acsi_times_out( unsigned long dummy )
831
832{
833 DISABLE_IRQ();
834 if (!do_acsi) return;
835
836 do_acsi = NULL;
837 printk( KERN_ERR "ACSI timeout\n" );
838 if (!CURRENT)
839 return;
840 if (++CURRENT->errors >= MAX_ERRORS) {
841#ifdef DEBUG
842 printk( KERN_ERR "ACSI: too many errors.\n" );
843#endif
844 end_request(CURRENT, 0);
845 }
846
847 redo_acsi_request();
848}
849
850
851
852/***********************************************************************
853 *
854 * Scatter-gather utility functions
855 *
856 ***********************************************************************/
857
858
859static void copy_to_acsibuffer( void )
860
861{ int i;
862 char *src, *dst;
863 struct buffer_head *bh;
864
865 src = CURRENT->buffer;
866 dst = acsi_buffer;
867 bh = CURRENT->bh;
868
869 if (!bh)
870 memcpy( dst, src, CurrentNSect*512 );
871 else
872 for( i = 0; i < CurrentNReq; ++i ) {
873 memcpy( dst, src, bh->b_size );
874 dst += bh->b_size;
875 if ((bh = bh->b_reqnext))
876 src = bh->b_data;
877 }
878}
879
880
881static void copy_from_acsibuffer( void )
882
883{ int i;
884 char *src, *dst;
885 struct buffer_head *bh;
886
887 dst = CURRENT->buffer;
888 src = acsi_buffer;
889 bh = CURRENT->bh;
890
891 if (!bh)
892 memcpy( dst, src, CurrentNSect*512 );
893 else
894 for( i = 0; i < CurrentNReq; ++i ) {
895 memcpy( dst, src, bh->b_size );
896 src += bh->b_size;
897 if ((bh = bh->b_reqnext))
898 dst = bh->b_data;
899 }
900}
901
902
903static void do_end_requests( void )
904
905{ int i, n;
906
907 if (!CURRENT->bh) {
908 CURRENT->nr_sectors -= CurrentNSect;
909 CURRENT->current_nr_sectors -= CurrentNSect;
910 CURRENT->sector += CurrentNSect;
911 if (CURRENT->nr_sectors == 0)
912 end_request(CURRENT, 1);
913 }
914 else {
915 for( i = 0; i < CurrentNReq; ++i ) {
916 n = CURRENT->bh->b_size >> 9;
917 CURRENT->nr_sectors -= n;
918 CURRENT->current_nr_sectors -= n;
919 CURRENT->sector += n;
920 end_request(CURRENT, 1);
921 }
922 }
923}
924
925
926
927
928/***********************************************************************
929 *
930 * do_acsi_request and friends
931 *
932 ***********************************************************************/
933
934static void do_acsi_request( request_queue_t * q )
935
936{
937 stdma_lock( acsi_interrupt, NULL );
938 redo_acsi_request();
939}
940
941
942static void redo_acsi_request( void )
943{
944 unsigned block, target, lun, nsect;
945 char *buffer;
946 unsigned long pbuffer;
947 struct buffer_head *bh;
948 struct gendisk *disk;
949 struct acsi_info_struct *aip;
950
951 repeat:
952 CLEAR_TIMER();
953
954 if (do_acsi)
955 return;
956
957 if (!CURRENT) {
958 do_acsi = NULL;
959 ENABLE_IRQ();
960 stdma_release();
961 return;
962 }
963
964 disk = CURRENT->rq_disk;
965 aip = disk->private_data;
966 if (CURRENT->bh) {
967 if (!CURRENT->bh && !buffer_locked(CURRENT->bh))
968 panic("ACSI: block not locked");
969 }
970
971 block = CURRENT->sector;
972 if (block+CURRENT->nr_sectors >= get_capacity(disk)) {
973#ifdef DEBUG
974 printk( "%s: attempted access for blocks %d...%ld past end of device at block %ld.\n",
975 disk->disk_name,
976 block, block + CURRENT->nr_sectors - 1,
977 get_capacity(disk));
978#endif
979 end_request(CURRENT, 0);
980 goto repeat;
981 }
982 if (aip->changed) {
983 printk( KERN_NOTICE "%s: request denied because cartridge has "
984 "been changed.\n", disk->disk_name);
985 end_request(CURRENT, 0);
986 goto repeat;
987 }
988
989 target = aip->target;
990 lun = aip->lun;
991
992 /* Find out how many sectors should be transferred from/to
993 * consecutive buffers and thus can be done with a single command.
994 */
995 buffer = CURRENT->buffer;
996 pbuffer = virt_to_phys(buffer);
997 nsect = CURRENT->current_nr_sectors;
998 CurrentNReq = 1;
999
1000 if ((bh = CURRENT->bh) && bh != CURRENT->bhtail) {
1001 if (!STRAM_ADDR(pbuffer)) {
1002 /* If transfer is done via the ACSI buffer anyway, we can
1003 * assemble as much bh's as fit in the buffer.
1004 */
1005 while( (bh = bh->b_reqnext) ) {
1006 if (nsect + (bh->b_size>>9) > ACSI_BUFFER_SECTORS) break;
1007 nsect += bh->b_size >> 9;
1008 ++CurrentNReq;
1009 if (bh == CURRENT->bhtail) break;
1010 }
1011 buffer = acsi_buffer;
1012 pbuffer = phys_acsi_buffer;
1013 }
1014 else {
1015 unsigned long pendadr, pnewadr;
1016 pendadr = pbuffer + nsect*512;
1017 while( (bh = bh->b_reqnext) ) {
1018 pnewadr = virt_to_phys(bh->b_data);
1019 if (!STRAM_ADDR(pnewadr) || pendadr != pnewadr) break;
1020 nsect += bh->b_size >> 9;
1021 pendadr = pnewadr + bh->b_size;
1022 ++CurrentNReq;
1023 if (bh == CURRENT->bhtail) break;
1024 }
1025 }
1026 }
1027 else {
1028 if (!STRAM_ADDR(pbuffer)) {
1029 buffer = acsi_buffer;
1030 pbuffer = phys_acsi_buffer;
1031 if (nsect > ACSI_BUFFER_SECTORS)
1032 nsect = ACSI_BUFFER_SECTORS;
1033 }
1034 }
1035 CurrentBuffer = buffer;
1036 CurrentNSect = nsect;
1037
1038 if (rq_data_dir(CURRENT) == WRITE) {
1039 CMDSET_TARG_LUN( write_cmd, target, lun );
1040 CMDSET_BLOCK( write_cmd, block );
1041 CMDSET_LEN( write_cmd, nsect );
1042 if (buffer == acsi_buffer)
1043 copy_to_acsibuffer();
1044 dma_cache_maintenance( pbuffer, nsect*512, 1 );
1045 do_acsi = write_intr;
1046 if (!acsicmd_dma( write_cmd, buffer, nsect, 1, 1)) {
1047 do_acsi = NULL;
1048 printk( KERN_ERR "ACSI (write): Timeout in command block\n" );
1049 bad_rw_intr();
1050 goto repeat;
1051 }
1052 SET_TIMER();
1053 return;
1054 }
1055 if (rq_data_dir(CURRENT) == READ) {
1056 CMDSET_TARG_LUN( read_cmd, target, lun );
1057 CMDSET_BLOCK( read_cmd, block );
1058 CMDSET_LEN( read_cmd, nsect );
1059 do_acsi = read_intr;
1060 if (!acsicmd_dma( read_cmd, buffer, nsect, 0, 1)) {
1061 do_acsi = NULL;
1062 printk( KERN_ERR "ACSI (read): Timeout in command block\n" );
1063 bad_rw_intr();
1064 goto repeat;
1065 }
1066 SET_TIMER();
1067 return;
1068 }
1069 panic("unknown ACSI command");
1070}
1071
1072
1073
1074/***********************************************************************
1075 *
1076 * Misc functions: ioctl, open, release, check_change, ...
1077 *
1078 ***********************************************************************/
1079
1080static int acsi_getgeo(struct block_device *bdev, struct hd_geometry *geo)
1081{
1082 struct acsi_info_struct *aip = bdev->bd_disk->private_data;
1083
1084 /*
1085 * Just fake some geometry here, it's nonsense anyway
1086 * To make it easy, use Adaptec's usual 64/32 mapping
1087 */
1088 geo->heads = 64;
1089 geo->sectors = 32;
1090 geo->cylinders = aip->size >> 11;
1091 return 0;
1092}
1093
1094static int acsi_ioctl( struct inode *inode, struct file *file,
1095 unsigned int cmd, unsigned long arg )
1096{
1097 struct gendisk *disk = inode->i_bdev->bd_disk;
1098 struct acsi_info_struct *aip = disk->private_data;
1099 switch (cmd) {
1100 case SCSI_IOCTL_GET_IDLUN:
1101 /* SCSI compatible GET_IDLUN call to get target's ID and LUN number */
1102 put_user( aip->target | (aip->lun << 8),
1103 &((Scsi_Idlun *) arg)->dev_id );
1104 put_user( 0, &((Scsi_Idlun *) arg)->host_unique_id );
1105 return 0;
1106 default:
1107 return -EINVAL;
1108 }
1109}
1110
1111
1112/*
1113 * Open a device, check for read-only and lock the medium if it is
1114 * removable.
1115 *
1116 * Changes by Martin Rogge, 9th Aug 1995:
1117 * Check whether check_disk_change (and therefore revalidate_acsidisk)
1118 * was successful. They fail when there is no medium in the drive.
1119 *
1120 * The problem of media being changed during an operation can be
1121 * ignored because of the prevent_removal code.
1122 *
1123 * Added check for the validity of the device number.
1124 *
1125 */
1126
1127static int acsi_open( struct inode * inode, struct file * filp )
1128{
1129 struct gendisk *disk = inode->i_bdev->bd_disk;
1130 struct acsi_info_struct *aip = disk->private_data;
1131
1132 if (aip->access_count == 0 && aip->removable) {
1133#if 0
1134 aip->changed = 1; /* safety first */
1135#endif
1136 check_disk_change( inode->i_bdev );
1137 if (aip->changed) /* revalidate was not successful (no medium) */
1138 return -ENXIO;
1139 acsi_prevent_removal(aip, 1);
1140 }
1141 aip->access_count++;
1142
1143 if (filp && filp->f_mode) {
1144 check_disk_change( inode->i_bdev );
1145 if (filp->f_mode & 2) {
1146 if (aip->read_only) {
1147 acsi_release( inode, filp );
1148 return -EROFS;
1149 }
1150 }
1151 }
1152
1153 return 0;
1154}
1155
1156/*
1157 * Releasing a block device means we sync() it, so that it can safely
1158 * be forgotten about...
1159 */
1160
1161static int acsi_release( struct inode * inode, struct file * file )
1162{
1163 struct gendisk *disk = inode->i_bdev->bd_disk;
1164 struct acsi_info_struct *aip = disk->private_data;
1165 if (--aip->access_count == 0 && aip->removable)
1166 acsi_prevent_removal(aip, 0);
1167 return( 0 );
1168}
1169
1170/*
1171 * Prevent or allow a media change for removable devices.
1172 */
1173
1174static void acsi_prevent_removal(struct acsi_info_struct *aip, int flag)
1175{
1176 stdma_lock( NULL, NULL );
1177
1178 CMDSET_TARG_LUN(pa_med_rem_cmd, aip->target, aip->lun);
1179 CMDSET_LEN( pa_med_rem_cmd, flag );
1180
1181 if (acsicmd_nodma(pa_med_rem_cmd, 0) && acsi_wait_for_IRQ(3*HZ))
1182 acsi_getstatus();
1183 /* Do not report errors -- some devices may not know this command. */
1184
1185 ENABLE_IRQ();
1186 stdma_release();
1187}
1188
1189static int acsi_media_change(struct gendisk *disk)
1190{
1191 struct acsi_info_struct *aip = disk->private_data;
1192
1193 if (!aip->removable)
1194 return 0;
1195
1196 if (aip->changed)
1197 /* We can be sure that the medium has been changed -- REQUEST
1198 * SENSE has reported this earlier.
1199 */
1200 return 1;
1201
1202 /* If the flag isn't set, make a test by reading block 0.
1203 * If errors happen, it seems to be better to say "changed"...
1204 */
1205 stdma_lock( NULL, NULL );
1206 CMDSET_TARG_LUN(read_cmd, aip->target, aip->lun);
1207 CMDSET_BLOCK( read_cmd, 0 );
1208 CMDSET_LEN( read_cmd, 1 );
1209 if (acsicmd_dma(read_cmd, acsi_buffer, 1, 0, 0) &&
1210 acsi_wait_for_IRQ(3*HZ)) {
1211 if (acsi_getstatus()) {
1212 if (acsi_reqsense(acsi_buffer, aip->target, aip->lun)) {
1213 if (CARTRCH_STAT(aip, acsi_buffer))
1214 aip->changed = 1;
1215 }
1216 else {
1217 printk( KERN_ERR "%s: REQUEST SENSE failed in test for "
1218 "medium change; assuming a change\n", disk->disk_name );
1219 aip->changed = 1;
1220 }
1221 }
1222 }
1223 else {
1224 printk( KERN_ERR "%s: Test for medium changed timed out; "
1225 "assuming a change\n", disk->disk_name);
1226 aip->changed = 1;
1227 }
1228 ENABLE_IRQ();
1229 stdma_release();
1230
1231 /* Now, after reading a block, the changed status is surely valid. */
1232 return aip->changed;
1233}
1234
1235
1236static int acsi_change_blk_size( int target, int lun)
1237
1238{ int i;
1239
1240 for (i=0; i<12; i++)
1241 acsi_buffer[i] = 0;
1242
1243 acsi_buffer[3] = 8;
1244 acsi_buffer[10] = 2;
1245 CMDSET_TARG_LUN( modeselect_cmd, target, lun);
1246
1247 if (!acsicmd_dma( modeselect_cmd, acsi_buffer, 1,1,0) ||
1248 !acsi_wait_for_IRQ( 3*HZ ) ||
1249 acsi_getstatus() != 0 ) {
1250 return(0);
1251 }
1252 return(1);
1253}
1254
1255
1256static int acsi_mode_sense( int target, int lun, SENSE_DATA *sd )
1257
1258{
1259 int page;
1260
1261 CMDSET_TARG_LUN( modesense_cmd, target, lun );
1262 for (page=0; page<4; page++) {
1263 modesense_cmd[2] = page;
1264 if (!acsicmd_dma( modesense_cmd, acsi_buffer, 1, 0, 0 ) ||
1265 !acsi_wait_for_IRQ( 3*HZ ) ||
1266 acsi_getstatus())
1267 continue;
1268
1269 /* read twice to jump over the second 16-byte border! */
1270 udelay(300);
1271 if (acsi_wait_for_noIRQ( 20 ) &&
1272 acsicmd_nodma( modesense_cmd, 0 ) &&
1273 acsi_wait_for_IRQ( 3*HZ ) &&
1274 acsi_getstatus() == 0)
1275 break;
1276 }
1277 if (page == 4) {
1278 return(0);
1279 }
1280
1281 dma_cache_maintenance( phys_acsi_buffer, sizeof(SENSE_DATA), 0 );
1282 *sd = *(SENSE_DATA *)acsi_buffer;
1283
1284 /* Validity check, depending on type of data */
1285
1286 switch( SENSE_TYPE(*sd) ) {
1287
1288 case SENSE_TYPE_ATARI:
1289 if (CAPACITY(*sd) == 0)
1290 goto invalid_sense;
1291 break;
1292
1293 case SENSE_TYPE_SCSI:
1294 if (sd->scsi.descriptor_size != 8)
1295 goto invalid_sense;
1296 break;
1297
1298 case SENSE_TYPE_UNKNOWN:
1299
1300 printk( KERN_ERR "ACSI target %d, lun %d: Cannot interpret "
1301 "sense data\n", target, lun );
1302
1303 invalid_sense:
1304
1305#ifdef DEBUG
1306 { int i;
1307 printk( "Mode sense data for ACSI target %d, lun %d seem not valid:",
1308 target, lun );
1309 for( i = 0; i < sizeof(SENSE_DATA); ++i )
1310 printk( "%02x ", (unsigned char)acsi_buffer[i] );
1311 printk( "\n" );
1312 }
1313#endif
1314 return( 0 );
1315 }
1316
1317 return( 1 );
1318}
1319
1320
1321
1322/*******************************************************************
1323 *
1324 * Initialization
1325 *
1326 ********************************************************************/
1327
1328
1329extern struct block_device_operations acsi_fops;
1330
1331static struct gendisk *acsi_gendisk[MAX_DEV];
1332
1333#define MAX_SCSI_DEVICE_CODE 10
1334
1335static const char *const scsi_device_types[MAX_SCSI_DEVICE_CODE] =
1336{
1337 "Direct-Access ",
1338 "Sequential-Access",
1339 "Printer ",
1340 "Processor ",
1341 "WORM ",
1342 "CD-ROM ",
1343 "Scanner ",
1344 "Optical Device ",
1345 "Medium Changer ",
1346 "Communications "
1347};
1348
1349static void print_inquiry(unsigned char *data)
1350{
1351 int i;
1352
1353 printk(KERN_INFO " Vendor: ");
1354 for (i = 8; i < 16; i++)
1355 {
1356 if (data[i] >= 0x20 && i < data[4] + 5)
1357 printk("%c", data[i]);
1358 else
1359 printk(" ");
1360 }
1361
1362 printk(" Model: ");
1363 for (i = 16; i < 32; i++)
1364 {
1365 if (data[i] >= 0x20 && i < data[4] + 5)
1366 printk("%c", data[i]);
1367 else
1368 printk(" ");
1369 }
1370
1371 printk(" Rev: ");
1372 for (i = 32; i < 36; i++)
1373 {
1374 if (data[i] >= 0x20 && i < data[4] + 5)
1375 printk("%c", data[i]);
1376 else
1377 printk(" ");
1378 }
1379
1380 printk("\n");
1381
1382 i = data[0] & 0x1f;
1383
1384 printk(KERN_INFO " Type: %s ", (i < MAX_SCSI_DEVICE_CODE
1385 ? scsi_device_types[i]
1386 : "Unknown "));
1387 printk(" ANSI SCSI revision: %02x", data[2] & 0x07);
1388 if ((data[2] & 0x07) == 1 && (data[3] & 0x0f) == 1)
1389 printk(" CCS\n");
1390 else
1391 printk("\n");
1392}
1393
1394
1395/*
1396 * Changes by Martin Rogge, 9th Aug 1995:
1397 * acsi_devinit has been taken out of acsi_geninit, because it needs
1398 * to be called from revalidate_acsidisk. The result of request sense
1399 * is now checked for DRIVE NOT READY.
1400 *
1401 * The structure *aip is only valid when acsi_devinit returns
1402 * DEV_SUPPORTED.
1403 *
1404 */
1405
1406#define DEV_NONE 0
1407#define DEV_UNKNOWN 1
1408#define DEV_SUPPORTED 2
1409#define DEV_SLM 3
1410
1411static int acsi_devinit(struct acsi_info_struct *aip)
1412{
1413 int status, got_inquiry;
1414 SENSE_DATA sense;
1415 unsigned char reqsense, extsense;
1416
1417 /*****************************************************************/
1418 /* Do a TEST UNIT READY command to test the presence of a device */
1419 /*****************************************************************/
1420
1421 CMDSET_TARG_LUN(tur_cmd, aip->target, aip->lun);
1422 if (!acsicmd_nodma(tur_cmd, 0)) {
1423 /* timed out -> no device here */
1424#ifdef DEBUG_DETECT
1425 printk("target %d lun %d: timeout\n", aip->target, aip->lun);
1426#endif
1427 return DEV_NONE;
1428 }
1429
1430 /*************************/
1431 /* Read the ACSI status. */
1432 /*************************/
1433
1434 status = acsi_getstatus();
1435 if (status) {
1436 if (status == 0x12) {
1437 /* The SLM printer should be the only device that
1438 * responds with the error code in the status byte. In
1439 * correct status bytes, bit 4 is never set.
1440 */
1441 printk( KERN_INFO "Detected SLM printer at id %d lun %d\n",
1442 aip->target, aip->lun);
1443 return DEV_SLM;
1444 }
1445 /* ignore CHECK CONDITION, since some devices send a
1446 UNIT ATTENTION */
1447 if ((status & 0x1e) != 0x2) {
1448#ifdef DEBUG_DETECT
1449 printk("target %d lun %d: status %d\n",
1450 aip->target, aip->lun, status);
1451#endif
1452 return DEV_UNKNOWN;
1453 }
1454 }
1455
1456 /*******************************/
1457 /* Do a REQUEST SENSE command. */
1458 /*******************************/
1459
1460 if (!acsi_reqsense(acsi_buffer, aip->target, aip->lun)) {
1461 printk( KERN_WARNING "acsi_reqsense failed\n");
1462 acsi_buffer[0] = 0;
1463 acsi_buffer[2] = UNIT_ATTENTION;
1464 }
1465 reqsense = acsi_buffer[0];
1466 extsense = acsi_buffer[2] & 0xf;
1467 if (status) {
1468 if ((reqsense & 0x70) == 0x70) { /* extended sense */
1469 if (extsense != UNIT_ATTENTION &&
1470 extsense != NOT_READY) {
1471#ifdef DEBUG_DETECT
1472 printk("target %d lun %d: extended sense %d\n",
1473 aip->target, aip->lun, extsense);
1474#endif
1475 return DEV_UNKNOWN;
1476 }
1477 }
1478 else {
1479 if (reqsense & 0x7f) {
1480#ifdef DEBUG_DETECT
1481 printk("target %d lun %d: sense %d\n",
1482 aip->target, aip->lun, reqsense);
1483#endif
1484 return DEV_UNKNOWN;
1485 }
1486 }
1487 }
1488 else
1489 if (reqsense == 0x4) { /* SH204 Bug workaround */
1490#ifdef DEBUG_DETECT
1491 printk("target %d lun %d status=0 sense=4\n",
1492 aip->target, aip->lun);
1493#endif
1494 return DEV_UNKNOWN;
1495 }
1496
1497 /***********************************************************/
1498 /* Do an INQUIRY command to get more infos on this device. */
1499 /***********************************************************/
1500
1501 /* Assume default values */
1502 aip->removable = 1;
1503 aip->read_only = 0;
1504 aip->old_atari_disk = 0;
1505 aip->changed = (extsense == NOT_READY); /* medium inserted? */
1506 aip->size = DEFAULT_SIZE;
1507 got_inquiry = 0;
1508 /* Fake inquiry result for old atari disks */
1509 memcpy(acsi_buffer, "\000\000\001\000 Adaptec 40xx"
1510 " ", 40);
1511 CMDSET_TARG_LUN(inquiry_cmd, aip->target, aip->lun);
1512 if (acsicmd_dma(inquiry_cmd, acsi_buffer, 1, 0, 0) &&
1513 acsi_getstatus() == 0) {
1514 acsicmd_nodma(inquiry_cmd, 0);
1515 acsi_getstatus();
1516 dma_cache_maintenance( phys_acsi_buffer, 256, 0 );
1517 got_inquiry = 1;
1518 aip->removable = !!(acsi_buffer[1] & 0x80);
1519 }
1520 if (aip->type == NONE) /* only at boot time */
1521 print_inquiry(acsi_buffer);
1522 switch(acsi_buffer[0]) {
1523 case TYPE_DISK:
1524 aip->type = HARDDISK;
1525 break;
1526 case TYPE_ROM:
1527 aip->type = CDROM;
1528 aip->read_only = 1;
1529 break;
1530 default:
1531 return DEV_UNKNOWN;
1532 }
1533 /****************************/
1534 /* Do a MODE SENSE command. */
1535 /****************************/
1536
1537 if (!acsi_mode_sense(aip->target, aip->lun, &sense)) {
1538 printk( KERN_WARNING "No mode sense data.\n" );
1539 return DEV_UNKNOWN;
1540 }
1541 if ((SECTOR_SIZE(sense) != 512) &&
1542 ((aip->type != CDROM) ||
1543 !acsi_change_blk_size(aip->target, aip->lun) ||
1544 !acsi_mode_sense(aip->target, aip->lun, &sense) ||
1545 (SECTOR_SIZE(sense) != 512))) {
1546 printk( KERN_WARNING "Sector size != 512 not supported.\n" );
1547 return DEV_UNKNOWN;
1548 }
1549 /* There are disks out there that claim to have 0 sectors... */
1550 if (CAPACITY(sense))
1551 aip->size = CAPACITY(sense); /* else keep DEFAULT_SIZE */
1552 if (!got_inquiry && SENSE_TYPE(sense) == SENSE_TYPE_ATARI) {
1553 /* If INQUIRY failed and the sense data suggest an old
1554 * Atari disk (SH20x, Megafile), the disk is not removable
1555 */
1556 aip->removable = 0;
1557 aip->old_atari_disk = 1;
1558 }
1559
1560 /******************/
1561 /* We've done it. */
1562 /******************/
1563
1564 return DEV_SUPPORTED;
1565}
1566
1567EXPORT_SYMBOL(acsi_delay_start);
1568EXPORT_SYMBOL(acsi_delay_end);
1569EXPORT_SYMBOL(acsi_wait_for_IRQ);
1570EXPORT_SYMBOL(acsi_wait_for_noIRQ);
1571EXPORT_SYMBOL(acsicmd_nodma);
1572EXPORT_SYMBOL(acsi_getstatus);
1573EXPORT_SYMBOL(acsi_buffer);
1574EXPORT_SYMBOL(phys_acsi_buffer);
1575
1576#ifdef CONFIG_ATARI_SLM_MODULE
1577void acsi_attach_SLMs( int (*attach_func)( int, int ) );
1578
1579EXPORT_SYMBOL(acsi_extstatus);
1580EXPORT_SYMBOL(acsi_end_extstatus);
1581EXPORT_SYMBOL(acsi_extcmd);
1582EXPORT_SYMBOL(acsi_attach_SLMs);
1583
1584/* to remember IDs of SLM devices, SLM module is loaded later
1585 * (index is target#, contents is lun#, -1 means "no SLM") */
1586int SLM_devices[8];
1587#endif
1588
1589static struct block_device_operations acsi_fops = {
1590 .owner = THIS_MODULE,
1591 .open = acsi_open,
1592 .release = acsi_release,
1593 .ioctl = acsi_ioctl,
1594 .getgeo = acsi_getgeo,
1595 .media_changed = acsi_media_change,
1596 .revalidate_disk= acsi_revalidate,
1597};
1598
1599#ifdef CONFIG_ATARI_SLM_MODULE
1600/* call attach_slm() for each device that is a printer; needed for init of SLM
1601 * driver as a module, since it's not yet present if acsi.c is inited and thus
1602 * the bus gets scanned. */
1603void acsi_attach_SLMs( int (*attach_func)( int, int ) )
1604{
1605 int i, n = 0;
1606
1607 for( i = 0; i < 8; ++i )
1608 if (SLM_devices[i] >= 0)
1609 n += (*attach_func)( i, SLM_devices[i] );
1610 printk( KERN_INFO "Found %d SLM printer(s) total.\n", n );
1611}
1612#endif /* CONFIG_ATARI_SLM_MODULE */
1613
1614
1615int acsi_init( void )
1616{
1617 int err = 0;
1618 int i, target, lun;
1619 struct acsi_info_struct *aip;
1620#ifdef CONFIG_ATARI_SLM
1621 int n_slm = 0;
1622#endif
1623 if (!MACH_IS_ATARI || !ATARIHW_PRESENT(ACSI))
1624 return 0;
1625 if (register_blkdev(ACSI_MAJOR, "ad")) {
1626 err = -EBUSY;
1627 goto out1;
1628 }
1629 if (!(acsi_buffer =
1630 (char *)atari_stram_alloc(ACSI_BUFFER_SIZE, "acsi"))) {
1631 err = -ENOMEM;
1632 printk( KERN_ERR "Unable to get ACSI ST-Ram buffer.\n" );
1633 goto out2;
1634 }
1635 phys_acsi_buffer = virt_to_phys( acsi_buffer );
1636 STramMask = ATARIHW_PRESENT(EXTD_DMA) ? 0x00000000 : 0xff000000;
1637
1638 acsi_queue = blk_init_queue(do_acsi_request, &acsi_lock);
1639 if (!acsi_queue) {
1640 err = -ENOMEM;
1641 goto out2a;
1642 }
1643#ifdef CONFIG_ATARI_SLM
1644 err = slm_init();
1645#endif
1646 if (err)
1647 goto out3;
1648
1649 printk( KERN_INFO "Probing ACSI devices:\n" );
1650 NDevices = 0;
1651#ifdef CONFIG_ATARI_SLM_MODULE
1652 for( i = 0; i < 8; ++i )
1653 SLM_devices[i] = -1;
1654#endif
1655 stdma_lock(NULL, NULL);
1656
1657 for (target = 0; target < 8 && NDevices < MAX_DEV; ++target) {
1658 lun = 0;
1659 do {
1660 aip = &acsi_info[NDevices];
1661 aip->type = NONE;
1662 aip->target = target;
1663 aip->lun = lun;
1664 i = acsi_devinit(aip);
1665 switch (i) {
1666 case DEV_SUPPORTED:
1667 printk( KERN_INFO "Detected ");
1668 switch (aip->type) {
1669 case HARDDISK:
1670 printk("disk");
1671 break;
1672 case CDROM:
1673 printk("cdrom");
1674 break;
1675 default:
1676 }
1677 printk(" ad%c at id %d lun %d ",
1678 'a' + NDevices, target, lun);
1679 if (aip->removable)
1680 printk("(removable) ");
1681 if (aip->read_only)
1682 printk("(read-only) ");
1683 if (aip->size == DEFAULT_SIZE)
1684 printk(" unkown size, using default ");
1685 printk("%ld MByte\n",
1686 (aip->size*512+1024*1024/2)/(1024*1024));
1687 NDevices++;
1688 break;
1689 case DEV_SLM:
1690#ifdef CONFIG_ATARI_SLM
1691 n_slm += attach_slm( target, lun );
1692 break;
1693#endif
1694#ifdef CONFIG_ATARI_SLM_MODULE
1695 SLM_devices[target] = lun;
1696 break;
1697#endif
1698 /* neither of the above: fall through to unknown device */
1699 case DEV_UNKNOWN:
1700 printk( KERN_INFO "Detected unsupported device at "
1701 "id %d lun %d\n", target, lun);
1702 break;
1703 }
1704 }
1705#ifdef CONFIG_ACSI_MULTI_LUN
1706 while (i != DEV_NONE && ++lun < MAX_LUN);
1707#else
1708 while (0);
1709#endif
1710 }
1711
1712 /* reenable interrupt */
1713 ENABLE_IRQ();
1714 stdma_release();
1715
1716#ifndef CONFIG_ATARI_SLM
1717 printk( KERN_INFO "Found %d ACSI device(s) total.\n", NDevices );
1718#else
1719 printk( KERN_INFO "Found %d ACSI device(s) and %d SLM printer(s) total.\n",
1720 NDevices, n_slm );
1721#endif
1722 err = -ENOMEM;
1723 for( i = 0; i < NDevices; ++i ) {
1724 acsi_gendisk[i] = alloc_disk(16);
1725 if (!acsi_gendisk[i])
1726 goto out4;
1727 }
1728
1729 for( i = 0; i < NDevices; ++i ) {
1730 struct gendisk *disk = acsi_gendisk[i];
1731 sprintf(disk->disk_name, "ad%c", 'a'+i);
1732 aip = &acsi_info[NDevices];
1733 disk->major = ACSI_MAJOR;
1734 disk->first_minor = i << 4;
1735 if (acsi_info[i].type != HARDDISK)
1736 disk->minors = 1;
1737 disk->fops = &acsi_fops;
1738 disk->private_data = &acsi_info[i];
1739 set_capacity(disk, acsi_info[i].size);
1740 disk->queue = acsi_queue;
1741 add_disk(disk);
1742 }
1743 return 0;
1744out4:
1745 while (i--)
1746 put_disk(acsi_gendisk[i]);
1747out3:
1748 blk_cleanup_queue(acsi_queue);
1749out2a:
1750 atari_stram_free( acsi_buffer );
1751out2:
1752 unregister_blkdev( ACSI_MAJOR, "ad" );
1753out1:
1754 return err;
1755}
1756
1757
1758#ifdef MODULE
1759
1760MODULE_LICENSE("GPL");
1761
1762int init_module(void)
1763{
1764 int err;
1765
1766 if ((err = acsi_init()))
1767 return( err );
1768 printk( KERN_INFO "ACSI driver loaded as module.\n");
1769 return( 0 );
1770}
1771
1772void cleanup_module(void)
1773{
1774 int i;
1775 del_timer( &acsi_timer );
1776 blk_cleanup_queue(acsi_queue);
1777 atari_stram_free( acsi_buffer );
1778
1779 if (unregister_blkdev( ACSI_MAJOR, "ad" ) != 0)
1780 printk( KERN_ERR "acsi: cleanup_module failed\n");
1781
1782 for (i = 0; i < NDevices; i++) {
1783 del_gendisk(acsi_gendisk[i]);
1784 put_disk(acsi_gendisk[i]);
1785 }
1786}
1787#endif
1788
1789/*
1790 * This routine is called to flush all partitions and partition tables
1791 * for a changed scsi disk, and then re-read the new partition table.
1792 * If we are revalidating a disk because of a media change, then we
1793 * enter with usage == 0. If we are using an ioctl, we automatically have
1794 * usage == 1 (we need an open channel to use an ioctl :-), so this
1795 * is our limit.
1796 *
1797 * Changes by Martin Rogge, 9th Aug 1995:
1798 * got cd-roms to work by calling acsi_devinit. There are only two problems:
1799 * First, if there is no medium inserted, the status will remain "changed".
1800 * That is no problem at all, but our design of three-valued logic (medium
1801 * changed, medium not changed, no medium inserted).
1802 * Secondly the check could fail completely and the drive could deliver
1803 * nonsensical data, which could mess up the acsi_info[] structure. In
1804 * that case we try to make the entry safe.
1805 *
1806 */
1807
1808static int acsi_revalidate(struct gendisk *disk)
1809{
1810 struct acsi_info_struct *aip = disk->private_data;
1811 stdma_lock( NULL, NULL );
1812 if (acsi_devinit(aip) != DEV_SUPPORTED) {
1813 printk( KERN_ERR "ACSI: revalidate failed for target %d lun %d\n",
1814 aip->target, aip->lun);
1815 aip->size = 0;
1816 aip->read_only = 1;
1817 aip->removable = 1;
1818 aip->changed = 1; /* next acsi_open will try again... */
1819 }
1820
1821 ENABLE_IRQ();
1822 stdma_release();
1823 set_capacity(disk, aip->size);
1824 return 0;
1825}
diff --git a/drivers/block/amiflop.c b/drivers/block/amiflop.c
index 27a139025ced..6ce8b897e262 100644
--- a/drivers/block/amiflop.c
+++ b/drivers/block/amiflop.c
@@ -1363,7 +1363,7 @@ static void redo_fd_request(void)
1363#ifdef DEBUG 1363#ifdef DEBUG
1364 printk("fd: sector %ld + %d requested for %s\n", 1364 printk("fd: sector %ld + %d requested for %s\n",
1365 CURRENT->sector,cnt, 1365 CURRENT->sector,cnt,
1366 (CURRENT->cmd==READ)?"read":"write"); 1366 (rq_data_dir(CURRENT) == READ) ? "read" : "write");
1367#endif 1367#endif
1368 block = CURRENT->sector + cnt; 1368 block = CURRENT->sector + cnt;
1369 if ((int)block > floppy->blocks) { 1369 if ((int)block > floppy->blocks) {
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index 5acc6c44aead..0fcad430474e 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -87,6 +87,7 @@ static const struct pci_device_id cciss_pci_device_id[] = {
87 {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSD, 0x103C, 0x3214}, 87 {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSD, 0x103C, 0x3214},
88 {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSD, 0x103C, 0x3215}, 88 {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSD, 0x103C, 0x3215},
89 {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSC, 0x103C, 0x3237}, 89 {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSC, 0x103C, 0x3237},
90 {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSC, 0x103C, 0x323D},
90 {PCI_VENDOR_ID_HP, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 91 {PCI_VENDOR_ID_HP, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
91 PCI_CLASS_STORAGE_RAID << 8, 0xffff << 8, 0}, 92 PCI_CLASS_STORAGE_RAID << 8, 0xffff << 8, 0},
92 {0,} 93 {0,}
@@ -119,6 +120,7 @@ static struct board_type products[] = {
119 {0x3214103C, "Smart Array E200i", &SA5_access, 120}, 120 {0x3214103C, "Smart Array E200i", &SA5_access, 120},
120 {0x3215103C, "Smart Array E200i", &SA5_access, 120}, 121 {0x3215103C, "Smart Array E200i", &SA5_access, 120},
121 {0x3237103C, "Smart Array E500", &SA5_access, 512}, 122 {0x3237103C, "Smart Array E500", &SA5_access, 512},
123 {0x323D103C, "Smart Array P700m", &SA5_access, 512},
122 {0xFFFF103C, "Unknown Smart Array", &SA5_access, 120}, 124 {0xFFFF103C, "Unknown Smart Array", &SA5_access, 120},
123}; 125};
124 126
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index 0ed5470d2533..4503290da407 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -74,6 +74,7 @@
74#include <linux/highmem.h> 74#include <linux/highmem.h>
75#include <linux/gfp.h> 75#include <linux/gfp.h>
76#include <linux/kthread.h> 76#include <linux/kthread.h>
77#include <linux/splice.h>
77 78
78#include <asm/uaccess.h> 79#include <asm/uaccess.h>
79 80
@@ -401,50 +402,73 @@ struct lo_read_data {
401}; 402};
402 403
403static int 404static int
404lo_read_actor(read_descriptor_t *desc, struct page *page, 405lo_splice_actor(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
405 unsigned long offset, unsigned long size) 406 struct splice_desc *sd)
406{ 407{
407 unsigned long count = desc->count; 408 struct lo_read_data *p = sd->u.data;
408 struct lo_read_data *p = desc->arg.data;
409 struct loop_device *lo = p->lo; 409 struct loop_device *lo = p->lo;
410 struct page *page = buf->page;
410 sector_t IV; 411 sector_t IV;
412 size_t size;
413 int ret;
411 414
412 IV = ((sector_t) page->index << (PAGE_CACHE_SHIFT - 9))+(offset >> 9); 415 ret = buf->ops->confirm(pipe, buf);
416 if (unlikely(ret))
417 return ret;
413 418
414 if (size > count) 419 IV = ((sector_t) page->index << (PAGE_CACHE_SHIFT - 9)) +
415 size = count; 420 (buf->offset >> 9);
421 size = sd->len;
422 if (size > p->bsize)
423 size = p->bsize;
416 424
417 if (lo_do_transfer(lo, READ, page, offset, p->page, p->offset, size, IV)) { 425 if (lo_do_transfer(lo, READ, page, buf->offset, p->page, p->offset, size, IV)) {
418 size = 0;
419 printk(KERN_ERR "loop: transfer error block %ld\n", 426 printk(KERN_ERR "loop: transfer error block %ld\n",
420 page->index); 427 page->index);
421 desc->error = -EINVAL; 428 size = -EINVAL;
422 } 429 }
423 430
424 flush_dcache_page(p->page); 431 flush_dcache_page(p->page);
425 432
426 desc->count = count - size; 433 if (size > 0)
427 desc->written += size; 434 p->offset += size;
428 p->offset += size; 435
429 return size; 436 return size;
430} 437}
431 438
432static int 439static int
440lo_direct_splice_actor(struct pipe_inode_info *pipe, struct splice_desc *sd)
441{
442 return __splice_from_pipe(pipe, sd, lo_splice_actor);
443}
444
445static int
433do_lo_receive(struct loop_device *lo, 446do_lo_receive(struct loop_device *lo,
434 struct bio_vec *bvec, int bsize, loff_t pos) 447 struct bio_vec *bvec, int bsize, loff_t pos)
435{ 448{
436 struct lo_read_data cookie; 449 struct lo_read_data cookie;
450 struct splice_desc sd;
437 struct file *file; 451 struct file *file;
438 int retval; 452 long retval;
439 453
440 cookie.lo = lo; 454 cookie.lo = lo;
441 cookie.page = bvec->bv_page; 455 cookie.page = bvec->bv_page;
442 cookie.offset = bvec->bv_offset; 456 cookie.offset = bvec->bv_offset;
443 cookie.bsize = bsize; 457 cookie.bsize = bsize;
458
459 sd.len = 0;
460 sd.total_len = bvec->bv_len;
461 sd.flags = 0;
462 sd.pos = pos;
463 sd.u.data = &cookie;
464
444 file = lo->lo_backing_file; 465 file = lo->lo_backing_file;
445 retval = file->f_op->sendfile(file, &pos, bvec->bv_len, 466 retval = splice_direct_to_actor(file, &sd, lo_direct_splice_actor);
446 lo_read_actor, &cookie); 467
447 return (retval < 0)? retval: 0; 468 if (retval < 0)
469 return retval;
470
471 return 0;
448} 472}
449 473
450static int 474static int
@@ -679,8 +703,8 @@ static int loop_change_fd(struct loop_device *lo, struct file *lo_file,
679 if (!S_ISREG(inode->i_mode) && !S_ISBLK(inode->i_mode)) 703 if (!S_ISREG(inode->i_mode) && !S_ISBLK(inode->i_mode))
680 goto out_putf; 704 goto out_putf;
681 705
682 /* new backing store needs to support loop (eg sendfile) */ 706 /* new backing store needs to support loop (eg splice_read) */
683 if (!inode->i_fop->sendfile) 707 if (!inode->i_fop->splice_read)
684 goto out_putf; 708 goto out_putf;
685 709
686 /* size of the new backing store needs to be the same */ 710 /* size of the new backing store needs to be the same */
@@ -760,7 +784,7 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file,
760 * If we can't read - sorry. If we only can't write - well, 784 * If we can't read - sorry. If we only can't write - well,
761 * it's going to be read-only. 785 * it's going to be read-only.
762 */ 786 */
763 if (!file->f_op->sendfile) 787 if (!file->f_op->splice_read)
764 goto out_putf; 788 goto out_putf;
765 if (aops->prepare_write && aops->commit_write) 789 if (aops->prepare_write && aops->commit_write)
766 lo_flags |= LO_FLAGS_USE_AOPS; 790 lo_flags |= LO_FLAGS_USE_AOPS;
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index 069ae39a9cd9..c575fb1d585f 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -416,7 +416,7 @@ static void nbd_clear_que(struct nbd_device *lo)
416/* 416/*
417 * We always wait for result of write, for now. It would be nice to make it optional 417 * We always wait for result of write, for now. It would be nice to make it optional
418 * in future 418 * in future
419 * if ((req->cmd == WRITE) && (lo->flags & NBD_WRITE_NOCHK)) 419 * if ((rq_data_dir(req) == WRITE) && (lo->flags & NBD_WRITE_NOCHK))
420 * { printk( "Warning: Ignoring result!\n"); nbd_end_request( req ); } 420 * { printk( "Warning: Ignoring result!\n"); nbd_end_request( req ); }
421 */ 421 */
422 422
diff --git a/drivers/cdrom/Kconfig b/drivers/cdrom/Kconfig
deleted file mode 100644
index 4b12e9031fb3..000000000000
--- a/drivers/cdrom/Kconfig
+++ /dev/null
@@ -1,213 +0,0 @@
1#
2# CDROM driver configuration
3#
4
5menu "Old CD-ROM drivers (not SCSI, not IDE)"
6 depends on ISA && BLOCK
7
8config CD_NO_IDESCSI
9 bool "Support non-SCSI/IDE/ATAPI CDROM drives"
10 ---help---
11 If you have a CD-ROM drive that is neither SCSI nor IDE/ATAPI, say Y
12 here, otherwise N. Read the CD-ROM-HOWTO, available from
13 <http://www.tldp.org/docs.html#howto>.
14
15 Note that the answer to this question doesn't directly affect the
16 kernel: saying N will just cause the configurator to skip all
17 the questions about these CD-ROM drives. If you are unsure what you
18 have, say Y and find out whether you have one of the following
19 drives.
20
21 For each of these drivers, a <file:Documentation/cdrom/{driver_name}>
22 exists. Especially in cases where you do not know exactly which kind
23 of drive you have you should read there. Most of these drivers use a
24 file drivers/cdrom/{driver_name}.h where you can define your
25 interface parameters and switch some internal goodies.
26
27 To compile these CD-ROM drivers as a module, choose M instead of Y.
28
29 If you want to use any of these CD-ROM drivers, you also have to
30 answer Y or M to "ISO 9660 CD-ROM file system support" below (this
31 answer will get "defaulted" for you if you enable any of the Linux
32 CD-ROM drivers).
33
34config AZTCD
35 tristate "Aztech/Orchid/Okano/Wearnes/TXC/CyDROM CDROM support"
36 depends on CD_NO_IDESCSI
37 ---help---
38 This is your driver if you have an Aztech CDA268-01A, Orchid
39 CD-3110, Okano or Wearnes CDD110, Conrad TXC, or CyCD-ROM CR520 or
40 CR540 CD-ROM drive. This driver -- just like all these CD-ROM
41 drivers -- is NOT for CD-ROM drives with IDE/ATAPI interfaces, such
42 as Aztech CDA269-031SE. Please read the file
43 <file:Documentation/cdrom/aztcd>.
44
45 If you say Y here, you should also say Y or M to "ISO 9660 CD-ROM
46 file system support" below, because that's the file system used on
47 CD-ROMs.
48
49 To compile this driver as a module, choose M here: the
50 module will be called aztcd.
51
52config GSCD
53 tristate "Goldstar R420 CDROM support"
54 depends on CD_NO_IDESCSI
55 ---help---
56 If this is your CD-ROM drive, say Y here. As described in the file
57 <file:Documentation/cdrom/gscd>, you might have to change a setting
58 in the file <file:drivers/cdrom/gscd.h> before compiling the
59 kernel. Please read the file <file:Documentation/cdrom/gscd>.
60
61 If you say Y here, you should also say Y or M to "ISO 9660 CD-ROM
62 file system support" below, because that's the file system used on
63 CD-ROMs.
64
65 To compile this driver as a module, choose M here: the
66 module will be called gscd.
67
68config SBPCD
69 tristate "Matsushita/Panasonic/Creative, Longshine, TEAC CDROM support"
70 depends on CD_NO_IDESCSI && BROKEN_ON_SMP
71 ---help---
72 This driver supports most of the drives which use the Panasonic or
73 Sound Blaster interface. Please read the file
74 <file:Documentation/cdrom/sbpcd>.
75
76 The Matsushita CR-521, CR-522, CR-523, CR-562, CR-563 drives
77 (sometimes labeled "Creative"), the Creative Labs CD200, the
78 Longshine LCS-7260, the "IBM External ISA CD-ROM" (in fact a CR-56x
79 model), the TEAC CD-55A fall under this category. Some other
80 "electrically compatible" drives (Vertos, Genoa, some Funai models)
81 are currently not supported; for the Sanyo H94A drive currently a
82 separate driver (asked later) is responsible. Most drives have a
83 uniquely shaped faceplate, with a caddyless motorized drawer, but
84 without external brand markings. The older CR-52x drives have a
85 caddy and manual loading/eject, but still no external markings. The
86 driver is able to do an extended auto-probing for interface
87 addresses and drive types; this can help to find facts in cases you
88 are not sure, but can consume some time during the boot process if
89 none of the supported drives gets found. Once your drive got found,
90 you should enter the reported parameters into
91 <file:drivers/cdrom/sbpcd.h> and set "DISTRIBUTION 0" there.
92
93 This driver can support up to four CD-ROM controller cards, and each
94 card can support up to four CD-ROM drives; if you say Y here, you
95 will be asked how many controller cards you have. If compiled as a
96 module, only one controller card (but with up to four drives) is
97 usable.
98
99 If you say Y here, you should also say Y or M to "ISO 9660 CD-ROM
100 file system support" below, because that's the file system used on
101 CD-ROMs.
102
103 To compile this driver as a module, choose M here: the
104 module will be called sbpcd.
105
106config MCDX
107 tristate "Mitsumi CDROM support"
108 depends on CD_NO_IDESCSI
109 ---help---
110 Use this driver if you want to be able to use your Mitsumi LU-005,
111 FX-001 or FX-001D CD-ROM drive.
112
113 Please read the file <file:Documentation/cdrom/mcdx>.
114
115 If you say Y here, you should also say Y or M to "ISO 9660 CD-ROM
116 file system support" below, because that's the file system used on
117 CD-ROMs.
118
119 To compile this driver as a module, choose M here: the
120 module will be called mcdx.
121
122config OPTCD
123 tristate "Optics Storage DOLPHIN 8000AT CDROM support"
124 depends on CD_NO_IDESCSI
125 ---help---
126 This is the driver for the 'DOLPHIN' drive with a 34-pin Sony
127 compatible interface. It also works with the Lasermate CR328A. If
128 you have one of those, say Y. This driver does not work for the
129 Optics Storage 8001 drive; use the IDE-ATAPI CD-ROM driver for that
130 one. Please read the file <file:Documentation/cdrom/optcd>.
131
132 If you say Y here, you should also say Y or M to "ISO 9660 CD-ROM
133 file system support" below, because that's the file system used on
134 CD-ROMs.
135
136 To compile this driver as a module, choose M here: the
137 module will be called optcd.
138
139config CM206
140 tristate "Philips/LMS CM206 CDROM support"
141 depends on CD_NO_IDESCSI && BROKEN_ON_SMP
142 ---help---
143 If you have a Philips/LMS CD-ROM drive cm206 in combination with a
144 cm260 host adapter card, say Y here. Please also read the file
145 <file:Documentation/cdrom/cm206>.
146
147 If you say Y here, you should also say Y or M to "ISO 9660 CD-ROM
148 file system support" below, because that's the file system used on
149 CD-ROMs.
150
151 To compile this driver as a module, choose M here: the
152 module will be called cm206.
153
154config SJCD
155 tristate "Sanyo CDR-H94A CDROM support"
156 depends on CD_NO_IDESCSI
157 help
158 If this is your CD-ROM drive, say Y here and read the file
159 <file:Documentation/cdrom/sjcd>. You should then also say Y or M to
160 "ISO 9660 CD-ROM file system support" below, because that's the
161 file system used on CD-ROMs.
162
163 To compile this driver as a module, choose M here: the
164 module will be called sjcd.
165
166config ISP16_CDI
167 tristate "ISP16/MAD16/Mozart soft configurable cdrom interface support"
168 depends on CD_NO_IDESCSI
169 ---help---
170 These are sound cards with built-in cdrom interfaces using the OPTi
171 82C928 or 82C929 chips. Say Y here to have them detected and
172 possibly configured at boot time. In addition, You'll have to say Y
173 to a driver for the particular cdrom drive you have attached to the
174 card. Read <file:Documentation/cdrom/isp16> for details.
175
176 To compile this driver as a module, choose M here: the
177 module will be called isp16.
178
179config CDU31A
180 tristate "Sony CDU31A/CDU33A CDROM support"
181 depends on CD_NO_IDESCSI && BROKEN_ON_SMP
182 ---help---
183 These CD-ROM drives have a spring-pop-out caddyless drawer, and a
184 rectangular green LED centered beneath it. NOTE: these CD-ROM
185 drives will not be auto detected by the kernel at boot time; you
186 have to provide the interface address as an option to the kernel at
187 boot time as described in <file:Documentation/cdrom/cdu31a> or fill
188 in your parameters into <file:drivers/cdrom/cdu31a.c>. Try "man
189 bootparam" or see the documentation of your boot loader (lilo or
190 loadlin) about how to pass options to the kernel.
191
192 If you say Y here, you should also say Y or M to "ISO 9660 CD-ROM
193 file system support" below, because that's the file system used on
194 CD-ROMs.
195
196 To compile this driver as a module, choose M here: the
197 module will be called cdu31a.
198
199config CDU535
200 tristate "Sony CDU535 CDROM support"
201 depends on CD_NO_IDESCSI
202 ---help---
203 This is the driver for the older Sony CDU-535 and CDU-531 CD-ROM
204 drives. Please read the file <file:Documentation/cdrom/sonycd535>.
205
206 If you say Y here, you should also say Y or M to "ISO 9660 CD-ROM
207 file system support" below, because that's the file system used on
208 CD-ROMs.
209
210 To compile this driver as a module, choose M here: the
211 module will be called sonycd535.
212
213endmenu
diff --git a/drivers/cdrom/Makefile b/drivers/cdrom/Makefile
index d1d1e5a4be73..774c180a4e11 100644
--- a/drivers/cdrom/Makefile
+++ b/drivers/cdrom/Makefile
@@ -10,14 +10,4 @@ obj-$(CONFIG_BLK_DEV_SR) += cdrom.o
10obj-$(CONFIG_PARIDE_PCD) += cdrom.o 10obj-$(CONFIG_PARIDE_PCD) += cdrom.o
11obj-$(CONFIG_CDROM_PKTCDVD) += cdrom.o 11obj-$(CONFIG_CDROM_PKTCDVD) += cdrom.o
12 12
13obj-$(CONFIG_AZTCD) += aztcd.o
14obj-$(CONFIG_CDU31A) += cdu31a.o cdrom.o
15obj-$(CONFIG_CM206) += cm206.o cdrom.o
16obj-$(CONFIG_GSCD) += gscd.o
17obj-$(CONFIG_ISP16_CDI) += isp16.o
18obj-$(CONFIG_MCDX) += mcdx.o cdrom.o
19obj-$(CONFIG_OPTCD) += optcd.o
20obj-$(CONFIG_SBPCD) += sbpcd.o cdrom.o
21obj-$(CONFIG_SJCD) += sjcd.o
22obj-$(CONFIG_CDU535) += sonycd535.o
23obj-$(CONFIG_VIOCD) += viocd.o cdrom.o 13obj-$(CONFIG_VIOCD) += viocd.o cdrom.o
diff --git a/drivers/cdrom/aztcd.c b/drivers/cdrom/aztcd.c
deleted file mode 100644
index 1f9fb7a96703..000000000000
--- a/drivers/cdrom/aztcd.c
+++ /dev/null
@@ -1,2492 +0,0 @@
1#define AZT_VERSION "2.60"
2
3/* $Id: aztcd.c,v 2.60 1997/11/29 09:51:19 root Exp root $
4 linux/drivers/block/aztcd.c - Aztech CD268 CDROM driver
5
6 Copyright (C) 1994-98 Werner Zimmermann(Werner.Zimmermann@fht-esslingen.de)
7
8 based on Mitsumi CDROM driver by Martin Hariss and preworks by
9 Eberhard Moenkeberg; contains contributions by Joe Nardone and Robby
10 Schirmer.
11
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2, or (at your option)
15 any later version.
16
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25
26 HISTORY
27 V0.0 Adaption to Aztech CD268-01A Version 1.3
28 Version is PRE_ALPHA, unresolved points:
29 1. I use busy wait instead of timer wait in STEN_LOW,DTEN_LOW
30 thus driver causes CPU overhead and is very slow
31 2. could not find a way to stop the drive, when it is
32 in data read mode, therefore I had to set
33 msf.end.min/sec/frame to 0:0:1 (in azt_poll); so only one
34 frame can be read in sequence, this is also the reason for
35 3. getting 'timeout in state 4' messages, but nevertheless
36 it works
37 W.Zimmermann, Oct. 31, 1994
38 V0.1 Version is ALPHA, problems #2 and #3 resolved.
39 W.Zimmermann, Nov. 3, 1994
40 V0.2 Modification to some comments, debugging aids for partial test
41 with Borland C under DOS eliminated. Timer interrupt wait
42 STEN_LOW_WAIT additionally to busy wait for STEN_LOW implemented;
43 use it only for the 'slow' commands (ACMD_GET_Q_CHANNEL, ACMD_
44 SEEK_TO_LEAD_IN), all other commands are so 'fast', that busy
45 waiting seems better to me than interrupt rescheduling.
46 Besides that, when used in the wrong place, STEN_LOW_WAIT causes
47 kernel panic.
48 In function aztPlay command ACMD_PLAY_AUDIO added, should make
49 audio functions work. The Aztech drive needs different commands
50 to read data tracks and play audio tracks.
51 W.Zimmermann, Nov. 8, 1994
52 V0.3 Recognition of missing drive during boot up improved (speeded up).
53 W.Zimmermann, Nov. 13, 1994
54 V0.35 Rewrote the control mechanism in azt_poll (formerly mcd_poll)
55 including removal of all 'goto' commands. :-);
56 J. Nardone, Nov. 14, 1994
57 V0.4 Renamed variables and constants to 'azt' instead of 'mcd'; had
58 to make some "compatibility" defines in azt.h; please note,
59 that the source file was renamed to azt.c, the include file to
60 azt.h
61 Speeded up drive recognition during init (will be a little bit
62 slower than before if no drive is installed!); suggested by
63 Robby Schirmer.
64 read_count declared volatile and set to AZT_BUF_SIZ to make
65 drive faster (now 300kB/sec, was 60kB/sec before, measured
66 by 'time dd if=/dev/cdrom of=/dev/null bs=2048 count=4096';
67 different AZT_BUF_SIZes were test, above 16 no further im-
68 provement seems to be possible; suggested by E.Moenkeberg.
69 W.Zimmermann, Nov. 18, 1994
70 V0.42 Included getAztStatus command in GetQChannelInfo() to allow
71 reading Q-channel info on audio disks, if drive is stopped,
72 and some other bug fixes in the audio stuff, suggested by
73 Robby Schirmer.
74 Added more ioctls (reading data in mode 1 and mode 2).
75 Completely removed the old azt_poll() routine.
76 Detection of ORCHID CDS-3110 in aztcd_init implemented.
77 Additional debugging aids (see the readme file).
78 W.Zimmermann, Dec. 9, 1994
79 V0.50 Autodetection of drives implemented.
80 W.Zimmermann, Dec. 12, 1994
81 V0.52 Prepared for including in the standard kernel, renamed most
82 variables to contain 'azt', included autoconf.h
83 W.Zimmermann, Dec. 16, 1994
84 V0.6 Version for being included in the standard Linux kernel.
85 Renamed source and header file to aztcd.c and aztcd.h
86 W.Zimmermann, Dec. 24, 1994
87 V0.7 Changed VERIFY_READ to VERIFY_WRITE in aztcd_ioctl, case
88 CDROMREADMODE1 and CDROMREADMODE2; bug fix in the ioctl,
89 which causes kernel crashes when playing audio, changed
90 include-files (config.h instead of autoconf.h, removed
91 delay.h)
92 W.Zimmermann, Jan. 8, 1995
93 V0.72 Some more modifications for adaption to the standard kernel.
94 W.Zimmermann, Jan. 16, 1995
95 V0.80 aztcd is now part of the standard kernel since version 1.1.83.
96 Modified the SET_TIMER and CLEAR_TIMER macros to comply with
97 the new timer scheme.
98 W.Zimmermann, Jan. 21, 1995
99 V0.90 Included CDROMVOLCTRL, but with my Aztech drive I can only turn
100 the channels on and off. If it works better with your drive,
101 please mail me. Also implemented ACMD_CLOSE for CDROMSTART.
102 W.Zimmermann, Jan. 24, 1995
103 V1.00 Implemented close and lock tray commands. Patches supplied by
104 Frank Racis
105 Added support for loadable MODULEs, so aztcd can now also be
106 loaded by insmod and removed by rmmod during run time
107 Werner Zimmermann, Mar. 24, 95
108 V1.10 Implemented soundcard configuration for Orchid CDS-3110 drives
109 connected to Soundwave32 cards. Release for LST 2.1.
110 (still experimental)
111 Werner Zimmermann, May 8, 95
112 V1.20 Implemented limited support for DOSEMU0.60's cdrom.c. Now it works, but
113 sometimes DOSEMU may hang for 30 seconds or so. A fully functional ver-
114 sion needs an update of Dosemu0.60's cdrom.c, which will come with the
115 next revision of Dosemu.
116 Also Soundwave32 support now works.
117 Werner Zimmermann, May 22, 95
118 V1.30 Auto-eject feature. Inspired by Franc Racis (racis@psu.edu)
119 Werner Zimmermann, July 4, 95
120 V1.40 Started multisession support. Implementation copied from mcdx.c
121 by Heiko Schlittermann. Not tested yet.
122 Werner Zimmermann, July 15, 95
123 V1.50 Implementation of ioctl CDROMRESET, continued multisession, began
124 XA, but still untested. Heavy modifications to drive status de-
125 tection.
126 Werner Zimmermann, July 25, 95
127 V1.60 XA support now should work. Speeded up drive recognition in cases,
128 where no drive is installed.
129 Werner Zimmermann, August 8, 1995
130 V1.70 Multisession support now is completed, but there is still not
131 enough testing done. If you can test it, please contact me. For
132 details please read Documentation/cdrom/aztcd
133 Werner Zimmermann, August 19, 1995
134 V1.80 Modification to suit the new kernel boot procedure introduced
135 with kernel 1.3.33. Will definitely not work with older kernels.
136 Programming done by Linus himself.
137 Werner Zimmermann, October 11, 1995
138 V1.90 Support for Conrad TXC drives, thank's to Jochen Kunz and Olaf Kaluza.
139 Werner Zimmermann, October 21, 1995
140 V2.00 Changed #include "blk.h" to <linux/blk.h> as the directory
141 structure was changed. README.aztcd is now /usr/src/docu-
142 mentation/cdrom/aztcd
143 Werner Zimmermann, November 10, 95
144 V2.10 Started to modify azt_poll to prevent reading beyond end of
145 tracks.
146 Werner Zimmermann, December 3, 95
147 V2.20 Changed some comments
148 Werner Zimmermann, April 1, 96
149 V2.30 Implemented support for CyCDROM CR520, CR940, Code for CR520
150 delivered by H.Berger with preworks by E.Moenkeberg.
151 Werner Zimmermann, April 29, 96
152 V2.40 Reorganized the placement of functions in the source code file
153 to reflect the layered approach; did not actually change code
154 Werner Zimmermann, May 1, 96
155 V2.50 Heiko Eissfeldt suggested to remove some VERIFY_READs in
156 aztcd_ioctl; check_aztcd_media_change modified
157 Werner Zimmermann, May 16, 96
158 V2.60 Implemented Auto-Probing; made changes for kernel's 2.1.xx blocksize
159 Adaption to linux kernel > 2.1.0
160 Werner Zimmermann, Nov 29, 97
161
162 November 1999 -- Make kernel-parameter implementation work with 2.3.x
163 Removed init_module & cleanup_module in favor of
164 module_init & module_exit.
165 Torben Mathiasen <tmm@image.dk>
166*/
167
168#include <linux/blkdev.h>
169#include "aztcd.h"
170
171#include <linux/module.h>
172#include <linux/errno.h>
173#include <linux/mm.h>
174#include <linux/timer.h>
175#include <linux/fs.h>
176#include <linux/kernel.h>
177#include <linux/cdrom.h>
178#include <linux/ioport.h>
179#include <linux/string.h>
180#include <linux/major.h>
181
182#include <linux/init.h>
183
184#include <asm/system.h>
185#include <asm/io.h>
186
187#include <asm/uaccess.h>
188
189/*###########################################################################
190 Defines
191 ###########################################################################
192*/
193
194#define MAJOR_NR AZTECH_CDROM_MAJOR
195#define QUEUE (azt_queue)
196#define CURRENT elv_next_request(azt_queue)
197#define SET_TIMER(func, jifs) delay_timer.expires = jiffies + (jifs); \
198 delay_timer.function = (void *) (func); \
199 add_timer(&delay_timer);
200
201#define CLEAR_TIMER del_timer(&delay_timer);
202
203#define RETURNM(message,value) {printk("aztcd: Warning: %s failed\n",message);\
204 return value;}
205#define RETURN(message) {printk("aztcd: Warning: %s failed\n",message);\
206 return;}
207
208/* Macros to switch the IDE-interface to the slave device and back to the master*/
209#define SWITCH_IDE_SLAVE outb_p(0xa0,azt_port+6); \
210 outb_p(0x10,azt_port+6); \
211 outb_p(0x00,azt_port+7); \
212 outb_p(0x10,azt_port+6);
213#define SWITCH_IDE_MASTER outb_p(0xa0,azt_port+6);
214
215
216#if 0
217#define AZT_TEST
218#define AZT_TEST1 /* <int-..> */
219#define AZT_TEST2 /* do_aztcd_request */
220#define AZT_TEST3 /* AZT_S_state */
221#define AZT_TEST4 /* QUICK_LOOP-counter */
222#define AZT_TEST5 /* port(1) state */
223#define AZT_DEBUG
224#define AZT_DEBUG_MULTISESSION
225#endif
226
227static struct request_queue *azt_queue;
228
229static int current_valid(void)
230{
231 return CURRENT &&
232 CURRENT->cmd == READ &&
233 CURRENT->sector != -1;
234}
235
236#define AFL_STATUSorDATA (AFL_STATUS | AFL_DATA)
237#define AZT_BUF_SIZ 16
238
239#define READ_TIMEOUT 3000
240
241#define azt_port aztcd /*needed for the modutils */
242
243/*##########################################################################
244 Type Definitions
245 ##########################################################################
246*/
247enum azt_state_e { AZT_S_IDLE, /* 0 */
248 AZT_S_START, /* 1 */
249 AZT_S_MODE, /* 2 */
250 AZT_S_READ, /* 3 */
251 AZT_S_DATA, /* 4 */
252 AZT_S_STOP, /* 5 */
253 AZT_S_STOPPING /* 6 */
254};
255enum azt_read_modes { AZT_MODE_0, /*read mode for audio disks, not supported by Aztech firmware */
256 AZT_MODE_1, /*read mode for normal CD-ROMs */
257 AZT_MODE_2 /*read mode for XA CD-ROMs */
258};
259
260/*##########################################################################
261 Global Variables
262 ##########################################################################
263*/
264static int aztPresent = 0;
265
266static volatile int azt_transfer_is_active = 0;
267
268static char azt_buf[CD_FRAMESIZE_RAW * AZT_BUF_SIZ]; /*buffer for block size conversion */
269#if AZT_PRIVATE_IOCTLS
270static char buf[CD_FRAMESIZE_RAW]; /*separate buffer for the ioctls */
271#endif
272
273static volatile int azt_buf_bn[AZT_BUF_SIZ], azt_next_bn;
274static volatile int azt_buf_in, azt_buf_out = -1;
275static volatile int azt_error = 0;
276static int azt_open_count = 0;
277static volatile enum azt_state_e azt_state = AZT_S_IDLE;
278#ifdef AZT_TEST3
279static volatile enum azt_state_e azt_state_old = AZT_S_STOP;
280static volatile int azt_st_old = 0;
281#endif
282static volatile enum azt_read_modes azt_read_mode = AZT_MODE_1;
283
284static int azt_mode = -1;
285static volatile int azt_read_count = 1;
286
287static int azt_port = AZT_BASE_ADDR;
288
289module_param(azt_port, int, 0);
290
291static int azt_port_auto[16] = AZT_BASE_AUTO;
292
293static char azt_cont = 0;
294static char azt_init_end = 0;
295static char azt_auto_eject = AZT_AUTO_EJECT;
296
297static int AztTimeout, AztTries;
298static DECLARE_WAIT_QUEUE_HEAD(azt_waitq);
299static DEFINE_TIMER(delay_timer, NULL, 0, 0);
300
301static struct azt_DiskInfo DiskInfo;
302static struct azt_Toc Toc[MAX_TRACKS];
303static struct azt_Play_msf azt_Play;
304
305static int aztAudioStatus = CDROM_AUDIO_NO_STATUS;
306static char aztDiskChanged = 1;
307static char aztTocUpToDate = 0;
308
309static unsigned char aztIndatum;
310static unsigned long aztTimeOutCount;
311static int aztCmd = 0;
312
313static DEFINE_SPINLOCK(aztSpin);
314
315/*###########################################################################
316 Function Prototypes
317 ###########################################################################
318*/
319/* CDROM Drive Low Level I/O Functions */
320static void aztStatTimer(void);
321
322/* CDROM Drive Command Functions */
323static int aztGetDiskInfo(void);
324#if AZT_MULTISESSION
325static int aztGetMultiDiskInfo(void);
326#endif
327static int aztGetToc(int multi);
328
329/* Kernel Interface Functions */
330static int check_aztcd_media_change(struct gendisk *disk);
331static int aztcd_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
332 unsigned long arg);
333static int aztcd_open(struct inode *ip, struct file *fp);
334static int aztcd_release(struct inode *inode, struct file *file);
335
336static struct block_device_operations azt_fops = {
337 .owner = THIS_MODULE,
338 .open = aztcd_open,
339 .release = aztcd_release,
340 .ioctl = aztcd_ioctl,
341 .media_changed = check_aztcd_media_change,
342};
343
344/* Aztcd State Machine: Controls Drive Operating State */
345static void azt_poll(void);
346
347/* Miscellaneous support functions */
348static void azt_hsg2msf(long hsg, struct msf *msf);
349static long azt_msf2hsg(struct msf *mp);
350static void azt_bin2bcd(unsigned char *p);
351static int azt_bcd2bin(unsigned char bcd);
352
353/*##########################################################################
354 CDROM Drive Low Level I/O Functions
355 ##########################################################################
356*/
357/* Macros for the drive hardware interface handshake, these macros use
358 busy waiting */
359/* Wait for OP_OK = drive answers with AFL_OP_OK after receiving a command*/
360# define OP_OK op_ok()
361static void op_ok(void)
362{
363 aztTimeOutCount = 0;
364 do {
365 aztIndatum = inb(DATA_PORT);
366 aztTimeOutCount++;
367 if (aztTimeOutCount >= AZT_TIMEOUT) {
368 printk("aztcd: Error Wait OP_OK\n");
369 break;
370 }
371 } while (aztIndatum != AFL_OP_OK);
372}
373
374/* Wait for PA_OK = drive answers with AFL_PA_OK after receiving parameters*/
375#if 0
376# define PA_OK pa_ok()
377static void pa_ok(void)
378{
379 aztTimeOutCount = 0;
380 do {
381 aztIndatum = inb(DATA_PORT);
382 aztTimeOutCount++;
383 if (aztTimeOutCount >= AZT_TIMEOUT) {
384 printk("aztcd: Error Wait PA_OK\n");
385 break;
386 }
387 } while (aztIndatum != AFL_PA_OK);
388}
389#endif
390
391/* Wait for STEN=Low = handshake signal 'AFL_.._OK available or command executed*/
392# define STEN_LOW sten_low()
393static void sten_low(void)
394{
395 aztTimeOutCount = 0;
396 do {
397 aztIndatum = inb(STATUS_PORT);
398 aztTimeOutCount++;
399 if (aztTimeOutCount >= AZT_TIMEOUT) {
400 if (azt_init_end)
401 printk
402 ("aztcd: Error Wait STEN_LOW commands:%x\n",
403 aztCmd);
404 break;
405 }
406 } while (aztIndatum & AFL_STATUS);
407}
408
409/* Wait for DTEN=Low = handshake signal 'Data available'*/
410# define DTEN_LOW dten_low()
411static void dten_low(void)
412{
413 aztTimeOutCount = 0;
414 do {
415 aztIndatum = inb(STATUS_PORT);
416 aztTimeOutCount++;
417 if (aztTimeOutCount >= AZT_TIMEOUT) {
418 printk("aztcd: Error Wait DTEN_OK\n");
419 break;
420 }
421 } while (aztIndatum & AFL_DATA);
422}
423
424/*
425 * Macro for timer wait on STEN=Low, should only be used for 'slow' commands;
426 * may cause kernel panic when used in the wrong place
427*/
428#define STEN_LOW_WAIT statusAzt()
429static void statusAzt(void)
430{
431 AztTimeout = AZT_STATUS_DELAY;
432 SET_TIMER(aztStatTimer, HZ / 100);
433 sleep_on(&azt_waitq);
434 if (AztTimeout <= 0)
435 printk("aztcd: Error Wait STEN_LOW_WAIT command:%x\n",
436 aztCmd);
437 return;
438}
439
440static void aztStatTimer(void)
441{
442 if (!(inb(STATUS_PORT) & AFL_STATUS)) {
443 wake_up(&azt_waitq);
444 return;
445 }
446 AztTimeout--;
447 if (AztTimeout <= 0) {
448 wake_up(&azt_waitq);
449 printk("aztcd: Error aztStatTimer: Timeout\n");
450 return;
451 }
452 SET_TIMER(aztStatTimer, HZ / 100);
453}
454
455/*##########################################################################
456 CDROM Drive Command Functions
457 ##########################################################################
458*/
459/*
460 * Send a single command, return -1 on error, else 0
461*/
462static int aztSendCmd(int cmd)
463{
464 unsigned char data;
465 int retry;
466
467#ifdef AZT_DEBUG
468 printk("aztcd: Executing command %x\n", cmd);
469#endif
470
471 if ((azt_port == 0x1f0) || (azt_port == 0x170))
472 SWITCH_IDE_SLAVE; /*switch IDE interface to slave configuration */
473
474 aztCmd = cmd;
475 outb(POLLED, MODE_PORT);
476 do {
477 if (inb(STATUS_PORT) & AFL_STATUS)
478 break;
479 inb(DATA_PORT); /* if status left from last command, read and */
480 } while (1); /* discard it */
481 do {
482 if (inb(STATUS_PORT) & AFL_DATA)
483 break;
484 inb(DATA_PORT); /* if data left from last command, read and */
485 } while (1); /* discard it */
486 for (retry = 0; retry < AZT_RETRY_ATTEMPTS; retry++) {
487 outb((unsigned char) cmd, CMD_PORT);
488 STEN_LOW;
489 data = inb(DATA_PORT);
490 if (data == AFL_OP_OK) {
491 return 0;
492 } /*OP_OK? */
493 if (data == AFL_OP_ERR) {
494 STEN_LOW;
495 data = inb(DATA_PORT);
496 printk
497 ("### Error 1 aztcd: aztSendCmd %x Error Code %x\n",
498 cmd, data);
499 }
500 }
501 if (retry >= AZT_RETRY_ATTEMPTS) {
502 printk("### Error 2 aztcd: aztSendCmd %x \n", cmd);
503 azt_error = 0xA5;
504 }
505 RETURNM("aztSendCmd", -1);
506}
507
508/*
509 * Send a play or read command to the drive, return -1 on error, else 0
510*/
511static int sendAztCmd(int cmd, struct azt_Play_msf *params)
512{
513 unsigned char data;
514 int retry;
515
516#ifdef AZT_DEBUG
517 printk("aztcd: play start=%02x:%02x:%02x end=%02x:%02x:%02x\n",
518 params->start.min, params->start.sec, params->start.frame,
519 params->end.min, params->end.sec, params->end.frame);
520#endif
521 for (retry = 0; retry < AZT_RETRY_ATTEMPTS; retry++) {
522 aztSendCmd(cmd);
523 outb(params->start.min, CMD_PORT);
524 outb(params->start.sec, CMD_PORT);
525 outb(params->start.frame, CMD_PORT);
526 outb(params->end.min, CMD_PORT);
527 outb(params->end.sec, CMD_PORT);
528 outb(params->end.frame, CMD_PORT);
529 STEN_LOW;
530 data = inb(DATA_PORT);
531 if (data == AFL_PA_OK) {
532 return 0;
533 } /*PA_OK ? */
534 if (data == AFL_PA_ERR) {
535 STEN_LOW;
536 data = inb(DATA_PORT);
537 printk
538 ("### Error 1 aztcd: sendAztCmd %x Error Code %x\n",
539 cmd, data);
540 }
541 }
542 if (retry >= AZT_RETRY_ATTEMPTS) {
543 printk("### Error 2 aztcd: sendAztCmd %x\n ", cmd);
544 azt_error = 0xA5;
545 }
546 RETURNM("sendAztCmd", -1);
547}
548
549/*
550 * Send a seek command to the drive, return -1 on error, else 0
551*/
552static int aztSeek(struct azt_Play_msf *params)
553{
554 unsigned char data;
555 int retry;
556
557#ifdef AZT_DEBUG
558 printk("aztcd: aztSeek %02x:%02x:%02x\n",
559 params->start.min, params->start.sec, params->start.frame);
560#endif
561 for (retry = 0; retry < AZT_RETRY_ATTEMPTS; retry++) {
562 aztSendCmd(ACMD_SEEK);
563 outb(params->start.min, CMD_PORT);
564 outb(params->start.sec, CMD_PORT);
565 outb(params->start.frame, CMD_PORT);
566 STEN_LOW;
567 data = inb(DATA_PORT);
568 if (data == AFL_PA_OK) {
569 return 0;
570 } /*PA_OK ? */
571 if (data == AFL_PA_ERR) {
572 STEN_LOW;
573 data = inb(DATA_PORT);
574 printk("### Error 1 aztcd: aztSeek\n");
575 }
576 }
577 if (retry >= AZT_RETRY_ATTEMPTS) {
578 printk("### Error 2 aztcd: aztSeek\n ");
579 azt_error = 0xA5;
580 }
581 RETURNM("aztSeek", -1);
582}
583
584/* Send a Set Disk Type command
585 does not seem to work with Aztech drives, behavior is completely indepen-
586 dent on which mode is set ???
587*/
588static int aztSetDiskType(int type)
589{
590 unsigned char data;
591 int retry;
592
593#ifdef AZT_DEBUG
594 printk("aztcd: set disk type command: type= %i\n", type);
595#endif
596 for (retry = 0; retry < AZT_RETRY_ATTEMPTS; retry++) {
597 aztSendCmd(ACMD_SET_DISK_TYPE);
598 outb(type, CMD_PORT);
599 STEN_LOW;
600 data = inb(DATA_PORT);
601 if (data == AFL_PA_OK) { /*PA_OK ? */
602 azt_read_mode = type;
603 return 0;
604 }
605 if (data == AFL_PA_ERR) {
606 STEN_LOW;
607 data = inb(DATA_PORT);
608 printk
609 ("### Error 1 aztcd: aztSetDiskType %x Error Code %x\n",
610 type, data);
611 }
612 }
613 if (retry >= AZT_RETRY_ATTEMPTS) {
614 printk("### Error 2 aztcd: aztSetDiskType %x\n ", type);
615 azt_error = 0xA5;
616 }
617 RETURNM("aztSetDiskType", -1);
618}
619
620
621/* used in azt_poll to poll the status, expects another program to issue a
622 * ACMD_GET_STATUS directly before
623 */
624static int aztStatus(void)
625{
626 int st;
627/* int i;
628
629 i = inb(STATUS_PORT) & AFL_STATUS; is STEN=0? ???
630 if (!i)
631*/ STEN_LOW;
632 if (aztTimeOutCount < AZT_TIMEOUT) {
633 st = inb(DATA_PORT) & 0xFF;
634 return st;
635 } else
636 RETURNM("aztStatus", -1);
637}
638
639/*
640 * Get the drive status
641 */
642static int getAztStatus(void)
643{
644 int st;
645
646 if (aztSendCmd(ACMD_GET_STATUS))
647 RETURNM("getAztStatus 1", -1);
648 STEN_LOW;
649 st = inb(DATA_PORT) & 0xFF;
650#ifdef AZT_DEBUG
651 printk("aztcd: Status = %x\n", st);
652#endif
653 if ((st == 0xFF) || (st & AST_CMD_CHECK)) {
654 printk
655 ("aztcd: AST_CMD_CHECK error or no status available\n");
656 return -1;
657 }
658
659 if (((st & AST_MODE_BITS) != AST_BUSY)
660 && (aztAudioStatus == CDROM_AUDIO_PLAY))
661 /* XXX might be an error? look at q-channel? */
662 aztAudioStatus = CDROM_AUDIO_COMPLETED;
663
664 if ((st & AST_DSK_CHG) || (st & AST_NOT_READY)) {
665 aztDiskChanged = 1;
666 aztTocUpToDate = 0;
667 aztAudioStatus = CDROM_AUDIO_NO_STATUS;
668 }
669 return st;
670}
671
672
673/*
674 * Send a 'Play' command and get the status. Use only from the top half.
675 */
676static int aztPlay(struct azt_Play_msf *arg)
677{
678 if (sendAztCmd(ACMD_PLAY_AUDIO, arg) < 0)
679 RETURNM("aztPlay", -1);
680 return 0;
681}
682
683/*
684 * Subroutines to automatically close the door (tray) and
685 * lock it closed when the cd is mounted. Leave the tray
686 * locking as an option
687 */
688static void aztCloseDoor(void)
689{
690 aztSendCmd(ACMD_CLOSE);
691 STEN_LOW;
692 return;
693}
694
695static void aztLockDoor(void)
696{
697#if AZT_ALLOW_TRAY_LOCK
698 aztSendCmd(ACMD_LOCK);
699 STEN_LOW;
700#endif
701 return;
702}
703
704static void aztUnlockDoor(void)
705{
706#if AZT_ALLOW_TRAY_LOCK
707 aztSendCmd(ACMD_UNLOCK);
708 STEN_LOW;
709#endif
710 return;
711}
712
713/*
714 * Read a value from the drive. Should return quickly, so a busy wait
715 * is used to avoid excessive rescheduling. The read command itself must
716 * be issued with aztSendCmd() directly before
717 */
718static int aztGetValue(unsigned char *result)
719{
720 int s;
721
722 STEN_LOW;
723 if (aztTimeOutCount >= AZT_TIMEOUT) {
724 printk("aztcd: aztGetValue timeout\n");
725 return -1;
726 }
727 s = inb(DATA_PORT) & 0xFF;
728 *result = (unsigned char) s;
729 return 0;
730}
731
732/*
733 * Read the current Q-channel info. Also used for reading the
734 * table of contents.
735 */
736static int aztGetQChannelInfo(struct azt_Toc *qp)
737{
738 unsigned char notUsed;
739 int st;
740
741#ifdef AZT_DEBUG
742 printk("aztcd: starting aztGetQChannelInfo Time:%li\n", jiffies);
743#endif
744 if ((st = getAztStatus()) == -1)
745 RETURNM("aztGetQChannelInfo 1", -1);
746 if (aztSendCmd(ACMD_GET_Q_CHANNEL))
747 RETURNM("aztGetQChannelInfo 2", -1);
748 /*STEN_LOW_WAIT; ??? Dosemu0.60's cdrom.c does not like STEN_LOW_WAIT here */
749 if (aztGetValue(&notUsed))
750 RETURNM("aztGetQChannelInfo 3", -1); /*??? Nullbyte einlesen */
751 if ((st & AST_MODE_BITS) == AST_INITIAL) {
752 qp->ctrl_addr = 0; /* when audio stop ACMD_GET_Q_CHANNEL returns */
753 qp->track = 0; /* only one byte with Aztech drives */
754 qp->pointIndex = 0;
755 qp->trackTime.min = 0;
756 qp->trackTime.sec = 0;
757 qp->trackTime.frame = 0;
758 qp->diskTime.min = 0;
759 qp->diskTime.sec = 0;
760 qp->diskTime.frame = 0;
761 return 0;
762 } else {
763 if (aztGetValue(&qp->ctrl_addr) < 0)
764 RETURNM("aztGetQChannelInfo 4", -1);
765 if (aztGetValue(&qp->track) < 0)
766 RETURNM("aztGetQChannelInfo 4", -1);
767 if (aztGetValue(&qp->pointIndex) < 0)
768 RETURNM("aztGetQChannelInfo 4", -1);
769 if (aztGetValue(&qp->trackTime.min) < 0)
770 RETURNM("aztGetQChannelInfo 4", -1);
771 if (aztGetValue(&qp->trackTime.sec) < 0)
772 RETURNM("aztGetQChannelInfo 4", -1);
773 if (aztGetValue(&qp->trackTime.frame) < 0)
774 RETURNM("aztGetQChannelInfo 4", -1);
775 if (aztGetValue(&notUsed) < 0)
776 RETURNM("aztGetQChannelInfo 4", -1);
777 if (aztGetValue(&qp->diskTime.min) < 0)
778 RETURNM("aztGetQChannelInfo 4", -1);
779 if (aztGetValue(&qp->diskTime.sec) < 0)
780 RETURNM("aztGetQChannelInfo 4", -1);
781 if (aztGetValue(&qp->diskTime.frame) < 0)
782 RETURNM("aztGetQChannelInfo 4", -1);
783 }
784#ifdef AZT_DEBUG
785 printk("aztcd: exiting aztGetQChannelInfo Time:%li\n", jiffies);
786#endif
787 return 0;
788}
789
790/*
791 * Read the table of contents (TOC) and TOC header if necessary
792 */
793static int aztUpdateToc(void)
794{
795 int st;
796
797#ifdef AZT_DEBUG
798 printk("aztcd: starting aztUpdateToc Time:%li\n", jiffies);
799#endif
800 if (aztTocUpToDate)
801 return 0;
802
803 if (aztGetDiskInfo() < 0)
804 return -EIO;
805
806 if (aztGetToc(0) < 0)
807 return -EIO;
808
809 /*audio disk detection
810 with my Aztech drive there is no audio status bit, so I use the copy
811 protection bit of the first track. If this track is copy protected
812 (copy bit = 0), I assume, it's an audio disk. Strange, but works ??? */
813 if (!(Toc[DiskInfo.first].ctrl_addr & 0x40))
814 DiskInfo.audio = 1;
815 else
816 DiskInfo.audio = 0;
817
818 /* XA detection */
819 if (!DiskInfo.audio) {
820 azt_Play.start.min = 0; /*XA detection only seems to work */
821 azt_Play.start.sec = 2; /*when we play a track */
822 azt_Play.start.frame = 0;
823 azt_Play.end.min = 0;
824 azt_Play.end.sec = 0;
825 azt_Play.end.frame = 1;
826 if (sendAztCmd(ACMD_PLAY_READ, &azt_Play))
827 return -1;
828 DTEN_LOW;
829 for (st = 0; st < CD_FRAMESIZE; st++)
830 inb(DATA_PORT);
831 }
832 DiskInfo.xa = getAztStatus() & AST_MODE;
833 if (DiskInfo.xa) {
834 printk
835 ("aztcd: XA support experimental - mail results to Werner.Zimmermann@fht-esslingen.de\n");
836 }
837
838 /*multisession detection
839 support for multisession CDs is done automatically with Aztech drives,
840 we don't have to take care about TOC redirection; if we want the isofs
841 to take care about redirection, we have to set AZT_MULTISESSION to 1 */
842 DiskInfo.multi = 0;
843#if AZT_MULTISESSION
844 if (DiskInfo.xa) {
845 aztGetMultiDiskInfo(); /*here Disk.Info.multi is set */
846 }
847#endif
848 if (DiskInfo.multi) {
849 DiskInfo.lastSession.min = Toc[DiskInfo.next].diskTime.min;
850 DiskInfo.lastSession.sec = Toc[DiskInfo.next].diskTime.sec;
851 DiskInfo.lastSession.frame =
852 Toc[DiskInfo.next].diskTime.frame;
853 printk("aztcd: Multisession support experimental\n");
854 } else {
855 DiskInfo.lastSession.min =
856 Toc[DiskInfo.first].diskTime.min;
857 DiskInfo.lastSession.sec =
858 Toc[DiskInfo.first].diskTime.sec;
859 DiskInfo.lastSession.frame =
860 Toc[DiskInfo.first].diskTime.frame;
861 }
862
863 aztTocUpToDate = 1;
864#ifdef AZT_DEBUG
865 printk("aztcd: exiting aztUpdateToc Time:%li\n", jiffies);
866#endif
867 return 0;
868}
869
870
871/* Read the table of contents header, i.e. no. of tracks and start of first
872 * track
873 */
874static int aztGetDiskInfo(void)
875{
876 int limit;
877 unsigned char test;
878 struct azt_Toc qInfo;
879
880#ifdef AZT_DEBUG
881 printk("aztcd: starting aztGetDiskInfo Time:%li\n", jiffies);
882#endif
883 if (aztSendCmd(ACMD_SEEK_TO_LEADIN))
884 RETURNM("aztGetDiskInfo 1", -1);
885 STEN_LOW_WAIT;
886 test = 0;
887 for (limit = 300; limit > 0; limit--) {
888 if (aztGetQChannelInfo(&qInfo) < 0)
889 RETURNM("aztGetDiskInfo 2", -1);
890 if (qInfo.pointIndex == 0xA0) { /*Number of FirstTrack */
891 DiskInfo.first = qInfo.diskTime.min;
892 DiskInfo.first = azt_bcd2bin(DiskInfo.first);
893 test = test | 0x01;
894 }
895 if (qInfo.pointIndex == 0xA1) { /*Number of LastTrack */
896 DiskInfo.last = qInfo.diskTime.min;
897 DiskInfo.last = azt_bcd2bin(DiskInfo.last);
898 test = test | 0x02;
899 }
900 if (qInfo.pointIndex == 0xA2) { /*DiskLength */
901 DiskInfo.diskLength.min = qInfo.diskTime.min;
902 DiskInfo.diskLength.sec = qInfo.diskTime.sec;
903 DiskInfo.diskLength.frame = qInfo.diskTime.frame;
904 test = test | 0x04;
905 }
906 if ((qInfo.pointIndex == DiskInfo.first) && (test & 0x01)) { /*StartTime of First Track */
907 DiskInfo.firstTrack.min = qInfo.diskTime.min;
908 DiskInfo.firstTrack.sec = qInfo.diskTime.sec;
909 DiskInfo.firstTrack.frame = qInfo.diskTime.frame;
910 test = test | 0x08;
911 }
912 if (test == 0x0F)
913 break;
914 }
915#ifdef AZT_DEBUG
916 printk("aztcd: exiting aztGetDiskInfo Time:%li\n", jiffies);
917 printk
918 ("Disk Info: first %d last %d length %02X:%02X.%02X dez first %02X:%02X.%02X dez\n",
919 DiskInfo.first, DiskInfo.last, DiskInfo.diskLength.min,
920 DiskInfo.diskLength.sec, DiskInfo.diskLength.frame,
921 DiskInfo.firstTrack.min, DiskInfo.firstTrack.sec,
922 DiskInfo.firstTrack.frame);
923#endif
924 if (test != 0x0F)
925 return -1;
926 return 0;
927}
928
929#if AZT_MULTISESSION
930/*
931 * Get Multisession Disk Info
932 */
933static int aztGetMultiDiskInfo(void)
934{
935 int limit, k = 5;
936 unsigned char test;
937 struct azt_Toc qInfo;
938
939#ifdef AZT_DEBUG
940 printk("aztcd: starting aztGetMultiDiskInfo\n");
941#endif
942
943 do {
944 azt_Play.start.min = Toc[DiskInfo.last + 1].diskTime.min;
945 azt_Play.start.sec = Toc[DiskInfo.last + 1].diskTime.sec;
946 azt_Play.start.frame =
947 Toc[DiskInfo.last + 1].diskTime.frame;
948 test = 0;
949
950 for (limit = 30; limit > 0; limit--) { /*Seek for LeadIn of next session */
951 if (aztSeek(&azt_Play))
952 RETURNM("aztGetMultiDiskInfo 1", -1);
953 if (aztGetQChannelInfo(&qInfo) < 0)
954 RETURNM("aztGetMultiDiskInfo 2", -1);
955 if ((qInfo.track == 0) && (qInfo.pointIndex))
956 break; /*LeadIn found */
957 if ((azt_Play.start.sec += 10) > 59) {
958 azt_Play.start.sec = 0;
959 azt_Play.start.min++;
960 }
961 }
962 if (!limit)
963 break; /*Check, if a leadin track was found, if not we're
964 at the end of the disk */
965#ifdef AZT_DEBUG_MULTISESSION
966 printk("leadin found track %d pointIndex %x limit %d\n",
967 qInfo.track, qInfo.pointIndex, limit);
968#endif
969 for (limit = 300; limit > 0; limit--) {
970 if (++azt_Play.start.frame > 74) {
971 azt_Play.start.frame = 0;
972 if (azt_Play.start.sec > 59) {
973 azt_Play.start.sec = 0;
974 azt_Play.start.min++;
975 }
976 }
977 if (aztSeek(&azt_Play))
978 RETURNM("aztGetMultiDiskInfo 3", -1);
979 if (aztGetQChannelInfo(&qInfo) < 0)
980 RETURNM("aztGetMultiDiskInfo 4", -1);
981 if (qInfo.pointIndex == 0xA0) { /*Number of NextTrack */
982 DiskInfo.next = qInfo.diskTime.min;
983 DiskInfo.next = azt_bcd2bin(DiskInfo.next);
984 test = test | 0x01;
985 }
986 if (qInfo.pointIndex == 0xA1) { /*Number of LastTrack */
987 DiskInfo.last = qInfo.diskTime.min;
988 DiskInfo.last = azt_bcd2bin(DiskInfo.last);
989 test = test | 0x02;
990 }
991 if (qInfo.pointIndex == 0xA2) { /*DiskLength */
992 DiskInfo.diskLength.min =
993 qInfo.diskTime.min;
994 DiskInfo.diskLength.sec =
995 qInfo.diskTime.sec;
996 DiskInfo.diskLength.frame =
997 qInfo.diskTime.frame;
998 test = test | 0x04;
999 }
1000 if ((qInfo.pointIndex == DiskInfo.next) && (test & 0x01)) { /*StartTime of Next Track */
1001 DiskInfo.nextSession.min =
1002 qInfo.diskTime.min;
1003 DiskInfo.nextSession.sec =
1004 qInfo.diskTime.sec;
1005 DiskInfo.nextSession.frame =
1006 qInfo.diskTime.frame;
1007 test = test | 0x08;
1008 }
1009 if (test == 0x0F)
1010 break;
1011 }
1012#ifdef AZT_DEBUG_MULTISESSION
1013 printk
1014 ("MultiDisk Info: first %d next %d last %d length %02x:%02x.%02x dez first %02x:%02x.%02x dez next %02x:%02x.%02x dez\n",
1015 DiskInfo.first, DiskInfo.next, DiskInfo.last,
1016 DiskInfo.diskLength.min, DiskInfo.diskLength.sec,
1017 DiskInfo.diskLength.frame, DiskInfo.firstTrack.min,
1018 DiskInfo.firstTrack.sec, DiskInfo.firstTrack.frame,
1019 DiskInfo.nextSession.min, DiskInfo.nextSession.sec,
1020 DiskInfo.nextSession.frame);
1021#endif
1022 if (test != 0x0F)
1023 break;
1024 else
1025 DiskInfo.multi = 1; /*found TOC of more than one session */
1026 aztGetToc(1);
1027 } while (--k);
1028
1029#ifdef AZT_DEBUG
1030 printk("aztcd: exiting aztGetMultiDiskInfo Time:%li\n", jiffies);
1031#endif
1032 return 0;
1033}
1034#endif
1035
1036/*
1037 * Read the table of contents (TOC)
1038 */
1039static int aztGetToc(int multi)
1040{
1041 int i, px;
1042 int limit;
1043 struct azt_Toc qInfo;
1044
1045#ifdef AZT_DEBUG
1046 printk("aztcd: starting aztGetToc Time:%li\n", jiffies);
1047#endif
1048 if (!multi) {
1049 for (i = 0; i < MAX_TRACKS; i++)
1050 Toc[i].pointIndex = 0;
1051 i = DiskInfo.last + 3;
1052 } else {
1053 for (i = DiskInfo.next; i < MAX_TRACKS; i++)
1054 Toc[i].pointIndex = 0;
1055 i = DiskInfo.last + 4 - DiskInfo.next;
1056 }
1057
1058/*Is there a good reason to stop motor before TOC read?
1059 if (aztSendCmd(ACMD_STOP)) RETURNM("aztGetToc 1",-1);
1060 STEN_LOW_WAIT;
1061*/
1062
1063 if (!multi) {
1064 azt_mode = 0x05;
1065 if (aztSendCmd(ACMD_SEEK_TO_LEADIN))
1066 RETURNM("aztGetToc 2", -1);
1067 STEN_LOW_WAIT;
1068 }
1069 for (limit = 300; limit > 0; limit--) {
1070 if (multi) {
1071 if (++azt_Play.start.sec > 59) {
1072 azt_Play.start.sec = 0;
1073 azt_Play.start.min++;
1074 }
1075 if (aztSeek(&azt_Play))
1076 RETURNM("aztGetToc 3", -1);
1077 }
1078 if (aztGetQChannelInfo(&qInfo) < 0)
1079 break;
1080
1081 px = azt_bcd2bin(qInfo.pointIndex);
1082
1083 if (px > 0 && px < MAX_TRACKS && qInfo.track == 0)
1084 if (Toc[px].pointIndex == 0) {
1085 Toc[px] = qInfo;
1086 i--;
1087 }
1088
1089 if (i <= 0)
1090 break;
1091 }
1092
1093 Toc[DiskInfo.last + 1].diskTime = DiskInfo.diskLength;
1094 Toc[DiskInfo.last].trackTime = DiskInfo.diskLength;
1095
1096#ifdef AZT_DEBUG_MULTISESSION
1097 printk("aztcd: exiting aztGetToc\n");
1098 for (i = 1; i <= DiskInfo.last + 1; i++)
1099 printk
1100 ("i = %2d ctl-adr = %02X track %2d px %02X %02X:%02X.%02X dez %02X:%02X.%02X dez\n",
1101 i, Toc[i].ctrl_addr, Toc[i].track, Toc[i].pointIndex,
1102 Toc[i].trackTime.min, Toc[i].trackTime.sec,
1103 Toc[i].trackTime.frame, Toc[i].diskTime.min,
1104 Toc[i].diskTime.sec, Toc[i].diskTime.frame);
1105 for (i = 100; i < 103; i++)
1106 printk
1107 ("i = %2d ctl-adr = %02X track %2d px %02X %02X:%02X.%02X dez %02X:%02X.%02X dez\n",
1108 i, Toc[i].ctrl_addr, Toc[i].track, Toc[i].pointIndex,
1109 Toc[i].trackTime.min, Toc[i].trackTime.sec,
1110 Toc[i].trackTime.frame, Toc[i].diskTime.min,
1111 Toc[i].diskTime.sec, Toc[i].diskTime.frame);
1112#endif
1113
1114 return limit > 0 ? 0 : -1;
1115}
1116
1117
1118/*##########################################################################
1119 Kernel Interface Functions
1120 ##########################################################################
1121*/
1122
1123#ifndef MODULE
1124static int __init aztcd_setup(char *str)
1125{
1126 int ints[4];
1127
1128 (void) get_options(str, ARRAY_SIZE(ints), ints);
1129
1130 if (ints[0] > 0)
1131 azt_port = ints[1];
1132 if (ints[1] > 1)
1133 azt_cont = ints[2];
1134 return 1;
1135}
1136
1137__setup("aztcd=", aztcd_setup);
1138
1139#endif /* !MODULE */
1140
1141/*
1142 * Checking if the media has been changed
1143*/
1144static int check_aztcd_media_change(struct gendisk *disk)
1145{
1146 if (aztDiskChanged) { /* disk changed */
1147 aztDiskChanged = 0;
1148 return 1;
1149 } else
1150 return 0; /* no change */
1151}
1152
1153/*
1154 * Kernel IO-controls
1155*/
1156static int aztcd_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
1157 unsigned long arg)
1158{
1159 int i;
1160 struct azt_Toc qInfo;
1161 struct cdrom_ti ti;
1162 struct cdrom_tochdr tocHdr;
1163 struct cdrom_msf msf;
1164 struct cdrom_tocentry entry;
1165 struct azt_Toc *tocPtr;
1166 struct cdrom_subchnl subchnl;
1167 struct cdrom_volctrl volctrl;
1168 void __user *argp = (void __user *)arg;
1169
1170#ifdef AZT_DEBUG
1171 printk("aztcd: starting aztcd_ioctl - Command:%x Time: %li\n",
1172 cmd, jiffies);
1173 printk("aztcd Status %x\n", getAztStatus());
1174#endif
1175 if (!ip)
1176 RETURNM("aztcd_ioctl 1", -EINVAL);
1177 if (getAztStatus() < 0)
1178 RETURNM("aztcd_ioctl 2", -EIO);
1179 if ((!aztTocUpToDate) || (aztDiskChanged)) {
1180 if ((i = aztUpdateToc()) < 0)
1181 RETURNM("aztcd_ioctl 3", i); /* error reading TOC */
1182 }
1183
1184 switch (cmd) {
1185 case CDROMSTART: /* Spin up the drive. Don't know, what to do,
1186 at least close the tray */
1187#if AZT_PRIVATE_IOCTLS
1188 if (aztSendCmd(ACMD_CLOSE))
1189 RETURNM("aztcd_ioctl 4", -1);
1190 STEN_LOW_WAIT;
1191#endif
1192 break;
1193 case CDROMSTOP: /* Spin down the drive */
1194 if (aztSendCmd(ACMD_STOP))
1195 RETURNM("aztcd_ioctl 5", -1);
1196 STEN_LOW_WAIT;
1197 /* should we do anything if it fails? */
1198 aztAudioStatus = CDROM_AUDIO_NO_STATUS;
1199 break;
1200 case CDROMPAUSE: /* Pause the drive */
1201 if (aztAudioStatus != CDROM_AUDIO_PLAY)
1202 return -EINVAL;
1203
1204 if (aztGetQChannelInfo(&qInfo) < 0) { /* didn't get q channel info */
1205 aztAudioStatus = CDROM_AUDIO_NO_STATUS;
1206 RETURNM("aztcd_ioctl 7", 0);
1207 }
1208 azt_Play.start = qInfo.diskTime; /* remember restart point */
1209
1210 if (aztSendCmd(ACMD_PAUSE))
1211 RETURNM("aztcd_ioctl 8", -1);
1212 STEN_LOW_WAIT;
1213 aztAudioStatus = CDROM_AUDIO_PAUSED;
1214 break;
1215 case CDROMRESUME: /* Play it again, Sam */
1216 if (aztAudioStatus != CDROM_AUDIO_PAUSED)
1217 return -EINVAL;
1218 /* restart the drive at the saved position. */
1219 i = aztPlay(&azt_Play);
1220 if (i < 0) {
1221 aztAudioStatus = CDROM_AUDIO_ERROR;
1222 return -EIO;
1223 }
1224 aztAudioStatus = CDROM_AUDIO_PLAY;
1225 break;
1226 case CDROMMULTISESSION: /*multisession support -- experimental */
1227 {
1228 struct cdrom_multisession ms;
1229#ifdef AZT_DEBUG
1230 printk("aztcd ioctl MULTISESSION\n");
1231#endif
1232 if (copy_from_user(&ms, argp,
1233 sizeof(struct cdrom_multisession)))
1234 return -EFAULT;
1235 if (ms.addr_format == CDROM_MSF) {
1236 ms.addr.msf.minute =
1237 azt_bcd2bin(DiskInfo.lastSession.min);
1238 ms.addr.msf.second =
1239 azt_bcd2bin(DiskInfo.lastSession.sec);
1240 ms.addr.msf.frame =
1241 azt_bcd2bin(DiskInfo.lastSession.
1242 frame);
1243 } else if (ms.addr_format == CDROM_LBA)
1244 ms.addr.lba =
1245 azt_msf2hsg(&DiskInfo.lastSession);
1246 else
1247 return -EINVAL;
1248 ms.xa_flag = DiskInfo.xa;
1249 if (copy_to_user(argp, &ms,
1250 sizeof(struct cdrom_multisession)))
1251 return -EFAULT;
1252#ifdef AZT_DEBUG
1253 if (ms.addr_format == CDROM_MSF)
1254 printk
1255 ("aztcd multisession xa:%d, msf:%02x:%02x.%02x [%02x:%02x.%02x])\n",
1256 ms.xa_flag, ms.addr.msf.minute,
1257 ms.addr.msf.second, ms.addr.msf.frame,
1258 DiskInfo.lastSession.min,
1259 DiskInfo.lastSession.sec,
1260 DiskInfo.lastSession.frame);
1261 else
1262 printk
1263 ("aztcd multisession %d, lba:0x%08x [%02x:%02x.%02x])\n",
1264 ms.xa_flag, ms.addr.lba,
1265 DiskInfo.lastSession.min,
1266 DiskInfo.lastSession.sec,
1267 DiskInfo.lastSession.frame);
1268#endif
1269 return 0;
1270 }
1271 case CDROMPLAYTRKIND: /* Play a track. This currently ignores index. */
1272 if (copy_from_user(&ti, argp, sizeof ti))
1273 return -EFAULT;
1274 if (ti.cdti_trk0 < DiskInfo.first
1275 || ti.cdti_trk0 > DiskInfo.last
1276 || ti.cdti_trk1 < ti.cdti_trk0) {
1277 return -EINVAL;
1278 }
1279 if (ti.cdti_trk1 > DiskInfo.last)
1280 ti.cdti_trk1 = DiskInfo.last;
1281 azt_Play.start = Toc[ti.cdti_trk0].diskTime;
1282 azt_Play.end = Toc[ti.cdti_trk1 + 1].diskTime;
1283#ifdef AZT_DEBUG
1284 printk("aztcd play: %02x:%02x.%02x to %02x:%02x.%02x\n",
1285 azt_Play.start.min, azt_Play.start.sec,
1286 azt_Play.start.frame, azt_Play.end.min,
1287 azt_Play.end.sec, azt_Play.end.frame);
1288#endif
1289 i = aztPlay(&azt_Play);
1290 if (i < 0) {
1291 aztAudioStatus = CDROM_AUDIO_ERROR;
1292 return -EIO;
1293 }
1294 aztAudioStatus = CDROM_AUDIO_PLAY;
1295 break;
1296 case CDROMPLAYMSF: /* Play starting at the given MSF address. */
1297/* if (aztAudioStatus == CDROM_AUDIO_PLAY)
1298 { if (aztSendCmd(ACMD_STOP)) RETURNM("aztcd_ioctl 9",-1);
1299 STEN_LOW;
1300 aztAudioStatus = CDROM_AUDIO_NO_STATUS;
1301 }
1302*/
1303 if (copy_from_user(&msf, argp, sizeof msf))
1304 return -EFAULT;
1305 /* convert to bcd */
1306 azt_bin2bcd(&msf.cdmsf_min0);
1307 azt_bin2bcd(&msf.cdmsf_sec0);
1308 azt_bin2bcd(&msf.cdmsf_frame0);
1309 azt_bin2bcd(&msf.cdmsf_min1);
1310 azt_bin2bcd(&msf.cdmsf_sec1);
1311 azt_bin2bcd(&msf.cdmsf_frame1);
1312 azt_Play.start.min = msf.cdmsf_min0;
1313 azt_Play.start.sec = msf.cdmsf_sec0;
1314 azt_Play.start.frame = msf.cdmsf_frame0;
1315 azt_Play.end.min = msf.cdmsf_min1;
1316 azt_Play.end.sec = msf.cdmsf_sec1;
1317 azt_Play.end.frame = msf.cdmsf_frame1;
1318#ifdef AZT_DEBUG
1319 printk("aztcd play: %02x:%02x.%02x to %02x:%02x.%02x\n",
1320 azt_Play.start.min, azt_Play.start.sec,
1321 azt_Play.start.frame, azt_Play.end.min,
1322 azt_Play.end.sec, azt_Play.end.frame);
1323#endif
1324 i = aztPlay(&azt_Play);
1325 if (i < 0) {
1326 aztAudioStatus = CDROM_AUDIO_ERROR;
1327 return -EIO;
1328 }
1329 aztAudioStatus = CDROM_AUDIO_PLAY;
1330 break;
1331
1332 case CDROMREADTOCHDR: /* Read the table of contents header */
1333 tocHdr.cdth_trk0 = DiskInfo.first;
1334 tocHdr.cdth_trk1 = DiskInfo.last;
1335 if (copy_to_user(argp, &tocHdr, sizeof tocHdr))
1336 return -EFAULT;
1337 break;
1338 case CDROMREADTOCENTRY: /* Read an entry in the table of contents */
1339 if (copy_from_user(&entry, argp, sizeof entry))
1340 return -EFAULT;
1341 if ((!aztTocUpToDate) || aztDiskChanged)
1342 aztUpdateToc();
1343 if (entry.cdte_track == CDROM_LEADOUT)
1344 tocPtr = &Toc[DiskInfo.last + 1];
1345 else if (entry.cdte_track > DiskInfo.last
1346 || entry.cdte_track < DiskInfo.first) {
1347 return -EINVAL;
1348 } else
1349 tocPtr = &Toc[entry.cdte_track];
1350 entry.cdte_adr = tocPtr->ctrl_addr;
1351 entry.cdte_ctrl = tocPtr->ctrl_addr >> 4;
1352 if (entry.cdte_format == CDROM_LBA)
1353 entry.cdte_addr.lba =
1354 azt_msf2hsg(&tocPtr->diskTime);
1355 else if (entry.cdte_format == CDROM_MSF) {
1356 entry.cdte_addr.msf.minute =
1357 azt_bcd2bin(tocPtr->diskTime.min);
1358 entry.cdte_addr.msf.second =
1359 azt_bcd2bin(tocPtr->diskTime.sec);
1360 entry.cdte_addr.msf.frame =
1361 azt_bcd2bin(tocPtr->diskTime.frame);
1362 } else {
1363 return -EINVAL;
1364 }
1365 if (copy_to_user(argp, &entry, sizeof entry))
1366 return -EFAULT;
1367 break;
1368 case CDROMSUBCHNL: /* Get subchannel info */
1369 if (copy_from_user
1370 (&subchnl, argp, sizeof(struct cdrom_subchnl)))
1371 return -EFAULT;
1372 if (aztGetQChannelInfo(&qInfo) < 0) {
1373#ifdef AZT_DEBUG
1374 printk
1375 ("aztcd: exiting aztcd_ioctl - Error 3 - Command:%x\n",
1376 cmd);
1377#endif
1378 return -EIO;
1379 }
1380 subchnl.cdsc_audiostatus = aztAudioStatus;
1381 subchnl.cdsc_adr = qInfo.ctrl_addr;
1382 subchnl.cdsc_ctrl = qInfo.ctrl_addr >> 4;
1383 subchnl.cdsc_trk = azt_bcd2bin(qInfo.track);
1384 subchnl.cdsc_ind = azt_bcd2bin(qInfo.pointIndex);
1385 if (subchnl.cdsc_format == CDROM_LBA) {
1386 subchnl.cdsc_absaddr.lba =
1387 azt_msf2hsg(&qInfo.diskTime);
1388 subchnl.cdsc_reladdr.lba =
1389 azt_msf2hsg(&qInfo.trackTime);
1390 } else { /*default */
1391 subchnl.cdsc_format = CDROM_MSF;
1392 subchnl.cdsc_absaddr.msf.minute =
1393 azt_bcd2bin(qInfo.diskTime.min);
1394 subchnl.cdsc_absaddr.msf.second =
1395 azt_bcd2bin(qInfo.diskTime.sec);
1396 subchnl.cdsc_absaddr.msf.frame =
1397 azt_bcd2bin(qInfo.diskTime.frame);
1398 subchnl.cdsc_reladdr.msf.minute =
1399 azt_bcd2bin(qInfo.trackTime.min);
1400 subchnl.cdsc_reladdr.msf.second =
1401 azt_bcd2bin(qInfo.trackTime.sec);
1402 subchnl.cdsc_reladdr.msf.frame =
1403 azt_bcd2bin(qInfo.trackTime.frame);
1404 }
1405 if (copy_to_user(argp, &subchnl, sizeof(struct cdrom_subchnl)))
1406 return -EFAULT;
1407 break;
1408 case CDROMVOLCTRL: /* Volume control
1409 * With my Aztech CD268-01A volume control does not work, I can only
1410 turn the channels on (any value !=0) or off (value==0). Maybe it
1411 works better with your drive */
1412 if (copy_from_user(&volctrl, argp, sizeof(volctrl)))
1413 return -EFAULT;
1414 azt_Play.start.min = 0x21;
1415 azt_Play.start.sec = 0x84;
1416 azt_Play.start.frame = volctrl.channel0;
1417 azt_Play.end.min = volctrl.channel1;
1418 azt_Play.end.sec = volctrl.channel2;
1419 azt_Play.end.frame = volctrl.channel3;
1420 sendAztCmd(ACMD_SET_VOLUME, &azt_Play);
1421 STEN_LOW_WAIT;
1422 break;
1423 case CDROMEJECT:
1424 aztUnlockDoor(); /* Assume user knows what they're doing */
1425 /* all drives can at least stop! */
1426 if (aztAudioStatus == CDROM_AUDIO_PLAY) {
1427 if (aztSendCmd(ACMD_STOP))
1428 RETURNM("azt_ioctl 10", -1);
1429 STEN_LOW_WAIT;
1430 }
1431 if (aztSendCmd(ACMD_EJECT))
1432 RETURNM("azt_ioctl 11", -1);
1433 STEN_LOW_WAIT;
1434 aztAudioStatus = CDROM_AUDIO_NO_STATUS;
1435 break;
1436 case CDROMEJECT_SW:
1437 azt_auto_eject = (char) arg;
1438 break;
1439 case CDROMRESET:
1440 outb(ACMD_SOFT_RESET, CMD_PORT); /*send reset */
1441 STEN_LOW;
1442 if (inb(DATA_PORT) != AFL_OP_OK) { /*OP_OK? */
1443 printk
1444 ("aztcd: AZTECH CD-ROM drive does not respond\n");
1445 }
1446 break;
1447/*Take care, the following code is not compatible with other CD-ROM drivers,
1448 use it at your own risk with cdplay.c. Set AZT_PRIVATE_IOCTLS to 0 in aztcd.h,
1449 if you do not want to use it!
1450*/
1451#if AZT_PRIVATE_IOCTLS
1452 case CDROMREADCOOKED: /*read data in mode 1 (2048 Bytes) */
1453 case CDROMREADRAW: /*read data in mode 2 (2336 Bytes) */
1454 {
1455 if (copy_from_user(&msf, argp, sizeof msf))
1456 return -EFAULT;
1457 /* convert to bcd */
1458 azt_bin2bcd(&msf.cdmsf_min0);
1459 azt_bin2bcd(&msf.cdmsf_sec0);
1460 azt_bin2bcd(&msf.cdmsf_frame0);
1461 msf.cdmsf_min1 = 0;
1462 msf.cdmsf_sec1 = 0;
1463 msf.cdmsf_frame1 = 1; /*read only one frame */
1464 azt_Play.start.min = msf.cdmsf_min0;
1465 azt_Play.start.sec = msf.cdmsf_sec0;
1466 azt_Play.start.frame = msf.cdmsf_frame0;
1467 azt_Play.end.min = msf.cdmsf_min1;
1468 azt_Play.end.sec = msf.cdmsf_sec1;
1469 azt_Play.end.frame = msf.cdmsf_frame1;
1470 if (cmd == CDROMREADRAW) {
1471 if (DiskInfo.xa) {
1472 return -1; /*XA Disks can't be read raw */
1473 } else {
1474 if (sendAztCmd(ACMD_PLAY_READ_RAW, &azt_Play))
1475 return -1;
1476 DTEN_LOW;
1477 insb(DATA_PORT, buf, CD_FRAMESIZE_RAW);
1478 if (copy_to_user(argp, &buf, CD_FRAMESIZE_RAW))
1479 return -EFAULT;
1480 }
1481 } else
1482 /*CDROMREADCOOKED*/ {
1483 if (sendAztCmd(ACMD_PLAY_READ, &azt_Play))
1484 return -1;
1485 DTEN_LOW;
1486 insb(DATA_PORT, buf, CD_FRAMESIZE);
1487 if (copy_to_user(argp, &buf, CD_FRAMESIZE))
1488 return -EFAULT;
1489 }
1490 }
1491 break;
1492 case CDROMSEEK: /*seek msf address */
1493 if (copy_from_user(&msf, argp, sizeof msf))
1494 return -EFAULT;
1495 /* convert to bcd */
1496 azt_bin2bcd(&msf.cdmsf_min0);
1497 azt_bin2bcd(&msf.cdmsf_sec0);
1498 azt_bin2bcd(&msf.cdmsf_frame0);
1499 azt_Play.start.min = msf.cdmsf_min0;
1500 azt_Play.start.sec = msf.cdmsf_sec0;
1501 azt_Play.start.frame = msf.cdmsf_frame0;
1502 if (aztSeek(&azt_Play))
1503 return -1;
1504 break;
1505#endif /*end of incompatible code */
1506 case CDROMREADMODE1: /*set read data in mode 1 */
1507 return aztSetDiskType(AZT_MODE_1);
1508 case CDROMREADMODE2: /*set read data in mode 2 */
1509 return aztSetDiskType(AZT_MODE_2);
1510 default:
1511 return -EINVAL;
1512 }
1513#ifdef AZT_DEBUG
1514 printk("aztcd: exiting aztcd_ioctl Command:%x Time:%li\n", cmd,
1515 jiffies);
1516#endif
1517 return 0;
1518}
1519
1520/*
1521 * Take care of the different block sizes between cdrom and Linux.
1522 * When Linux gets variable block sizes this will probably go away.
1523 */
1524static void azt_transfer(void)
1525{
1526#ifdef AZT_TEST
1527 printk("aztcd: executing azt_transfer Time:%li\n", jiffies);
1528#endif
1529 if (!current_valid())
1530 return;
1531
1532 while (CURRENT->nr_sectors) {
1533 int bn = CURRENT->sector / 4;
1534 int i;
1535 for (i = 0; i < AZT_BUF_SIZ && azt_buf_bn[i] != bn; ++i);
1536 if (i < AZT_BUF_SIZ) {
1537 int offs = (i * 4 + (CURRENT->sector & 3)) * 512;
1538 int nr_sectors = 4 - (CURRENT->sector & 3);
1539 if (azt_buf_out != i) {
1540 azt_buf_out = i;
1541 if (azt_buf_bn[i] != bn) {
1542 azt_buf_out = -1;
1543 continue;
1544 }
1545 }
1546 if (nr_sectors > CURRENT->nr_sectors)
1547 nr_sectors = CURRENT->nr_sectors;
1548 memcpy(CURRENT->buffer, azt_buf + offs,
1549 nr_sectors * 512);
1550 CURRENT->nr_sectors -= nr_sectors;
1551 CURRENT->sector += nr_sectors;
1552 CURRENT->buffer += nr_sectors * 512;
1553 } else {
1554 azt_buf_out = -1;
1555 break;
1556 }
1557 }
1558}
1559
1560static void do_aztcd_request(request_queue_t * q)
1561{
1562#ifdef AZT_TEST
1563 printk(" do_aztcd_request(%ld+%ld) Time:%li\n", CURRENT->sector,
1564 CURRENT->nr_sectors, jiffies);
1565#endif
1566 if (DiskInfo.audio) {
1567 printk("aztcd: Error, tried to mount an Audio CD\n");
1568 end_request(CURRENT, 0);
1569 return;
1570 }
1571 azt_transfer_is_active = 1;
1572 while (current_valid()) {
1573 azt_transfer();
1574 if (CURRENT->nr_sectors == 0) {
1575 end_request(CURRENT, 1);
1576 } else {
1577 azt_buf_out = -1; /* Want to read a block not in buffer */
1578 if (azt_state == AZT_S_IDLE) {
1579 if ((!aztTocUpToDate) || aztDiskChanged) {
1580 if (aztUpdateToc() < 0) {
1581 while (current_valid())
1582 end_request(CURRENT, 0);
1583 break;
1584 }
1585 }
1586 azt_state = AZT_S_START;
1587 AztTries = 5;
1588 SET_TIMER(azt_poll, HZ / 100);
1589 }
1590 break;
1591 }
1592 }
1593 azt_transfer_is_active = 0;
1594#ifdef AZT_TEST2
1595 printk
1596 ("azt_next_bn:%x azt_buf_in:%x azt_buf_out:%x azt_buf_bn:%x\n",
1597 azt_next_bn, azt_buf_in, azt_buf_out, azt_buf_bn[azt_buf_in]);
1598 printk(" do_aztcd_request ends Time:%li\n", jiffies);
1599#endif
1600}
1601
1602
1603static void azt_invalidate_buffers(void)
1604{
1605 int i;
1606
1607#ifdef AZT_DEBUG
1608 printk("aztcd: executing azt_invalidate_buffers\n");
1609#endif
1610 for (i = 0; i < AZT_BUF_SIZ; ++i)
1611 azt_buf_bn[i] = -1;
1612 azt_buf_out = -1;
1613}
1614
1615/*
1616 * Open the device special file. Check that a disk is in.
1617 */
1618static int aztcd_open(struct inode *ip, struct file *fp)
1619{
1620 int st;
1621
1622#ifdef AZT_DEBUG
1623 printk("aztcd: starting aztcd_open\n");
1624#endif
1625
1626 if (aztPresent == 0)
1627 return -ENXIO; /* no hardware */
1628
1629 if (!azt_open_count && azt_state == AZT_S_IDLE) {
1630 azt_invalidate_buffers();
1631
1632 st = getAztStatus(); /* check drive status */
1633 if (st == -1)
1634 goto err_out; /* drive doesn't respond */
1635
1636 if (st & AST_DOOR_OPEN) { /* close door, then get the status again. */
1637 printk("aztcd: Door Open?\n");
1638 aztCloseDoor();
1639 st = getAztStatus();
1640 }
1641
1642 if ((st & AST_NOT_READY) || (st & AST_DSK_CHG)) { /*no disk in drive or changed */
1643 printk
1644 ("aztcd: Disk Changed or No Disk in Drive?\n");
1645 aztTocUpToDate = 0;
1646 }
1647 if (aztUpdateToc())
1648 goto err_out;
1649
1650 }
1651 ++azt_open_count;
1652 aztLockDoor();
1653
1654#ifdef AZT_DEBUG
1655 printk("aztcd: exiting aztcd_open\n");
1656#endif
1657 return 0;
1658
1659 err_out:
1660 return -EIO;
1661}
1662
1663
1664/*
1665 * On close, we flush all azt blocks from the buffer cache.
1666 */
1667static int aztcd_release(struct inode *inode, struct file *file)
1668{
1669#ifdef AZT_DEBUG
1670 printk("aztcd: executing aztcd_release\n");
1671 printk("inode: %p, device: %s file: %p\n", inode,
1672 inode->i_bdev->bd_disk->disk_name, file);
1673#endif
1674 if (!--azt_open_count) {
1675 azt_invalidate_buffers();
1676 aztUnlockDoor();
1677 if (azt_auto_eject)
1678 aztSendCmd(ACMD_EJECT);
1679 CLEAR_TIMER;
1680 }
1681 return 0;
1682}
1683
1684static struct gendisk *azt_disk;
1685
1686/*
1687 * Test for presence of drive and initialize it. Called at boot time.
1688 */
1689
1690static int __init aztcd_init(void)
1691{
1692 long int count, max_count;
1693 unsigned char result[50];
1694 int st;
1695 void* status = NULL;
1696 int i = 0;
1697 int ret = 0;
1698
1699 if (azt_port == 0) {
1700 printk(KERN_INFO "aztcd: no Aztech CD-ROM Initialization");
1701 return -EIO;
1702 }
1703
1704 printk(KERN_INFO "aztcd: AZTECH, ORCHID, OKANO, WEARNES, TXC, CyDROM "
1705 "CD-ROM Driver\n");
1706 printk(KERN_INFO "aztcd: (C) 1994-98 W.Zimmermann\n");
1707 if (azt_port == -1) {
1708 printk
1709 ("aztcd: DriverVersion=%s For IDE/ATAPI-drives use ide-cd.c\n",
1710 AZT_VERSION);
1711 } else
1712 printk
1713 ("aztcd: DriverVersion=%s BaseAddress=0x%x For IDE/ATAPI-drives use ide-cd.c\n",
1714 AZT_VERSION, azt_port);
1715 printk(KERN_INFO "aztcd: If you have problems, read /usr/src/linux/"
1716 "Documentation/cdrom/aztcd\n");
1717
1718
1719#ifdef AZT_SW32 /*CDROM connected to Soundwave32 card */
1720 if ((0xFF00 & inw(AZT_SW32_ID_REG)) != 0x4500) {
1721 printk
1722 ("aztcd: no Soundwave32 card detected at base:%x init:%x config:%x id:%x\n",
1723 AZT_SW32_BASE_ADDR, AZT_SW32_INIT,
1724 AZT_SW32_CONFIG_REG, AZT_SW32_ID_REG);
1725 return -EIO;
1726 } else {
1727 printk(KERN_INFO
1728 "aztcd: Soundwave32 card detected at %x Version %x\n",
1729 AZT_SW32_BASE_ADDR, inw(AZT_SW32_ID_REG));
1730 outw(AZT_SW32_INIT, AZT_SW32_CONFIG_REG);
1731 for (count = 0; count < 10000; count++); /*delay a bit */
1732 }
1733#endif
1734
1735 /* check for presence of drive */
1736
1737 if (azt_port == -1) { /* autoprobing for proprietary interface */
1738 for (i = 0; (azt_port_auto[i] != 0) && (i < 16); i++) {
1739 azt_port = azt_port_auto[i];
1740 printk(KERN_INFO "aztcd: Autoprobing BaseAddress=0x%x"
1741 "\n", azt_port);
1742 /*proprietary interfaces need 4 bytes */
1743 if (!request_region(azt_port, 4, "aztcd")) {
1744 continue;
1745 }
1746 outb(POLLED, MODE_PORT);
1747 inb(CMD_PORT);
1748 inb(CMD_PORT);
1749 outb(ACMD_GET_VERSION, CMD_PORT); /*Try to get version info */
1750
1751 aztTimeOutCount = 0;
1752 do {
1753 aztIndatum = inb(STATUS_PORT);
1754 aztTimeOutCount++;
1755 if (aztTimeOutCount >= AZT_FAST_TIMEOUT)
1756 break;
1757 } while (aztIndatum & AFL_STATUS);
1758 if (inb(DATA_PORT) == AFL_OP_OK) { /* OK drive found */
1759 break;
1760 }
1761 else { /* Drive not found on this port - try next one */
1762 release_region(azt_port, 4);
1763 }
1764 }
1765 if ((i == 16) || (azt_port_auto[i] == 0)) {
1766 printk(KERN_INFO "aztcd: no AZTECH CD-ROM drive found\n");
1767 return -EIO;
1768 }
1769 } else { /* no autoprobing */
1770 if ((azt_port == 0x1f0) || (azt_port == 0x170))
1771 status = request_region(azt_port, 8, "aztcd"); /*IDE-interfaces need 8 bytes */
1772 else
1773 status = request_region(azt_port, 4, "aztcd"); /*proprietary interfaces need 4 bytes */
1774 if (!status) {
1775 printk(KERN_WARNING "aztcd: conflict, I/O port (%X) "
1776 "already used\n", azt_port);
1777 return -EIO;
1778 }
1779
1780 if ((azt_port == 0x1f0) || (azt_port == 0x170))
1781 SWITCH_IDE_SLAVE; /*switch IDE interface to slave configuration */
1782
1783 outb(POLLED, MODE_PORT);
1784 inb(CMD_PORT);
1785 inb(CMD_PORT);
1786 outb(ACMD_GET_VERSION, CMD_PORT); /*Try to get version info */
1787
1788 aztTimeOutCount = 0;
1789 do {
1790 aztIndatum = inb(STATUS_PORT);
1791 aztTimeOutCount++;
1792 if (aztTimeOutCount >= AZT_FAST_TIMEOUT)
1793 break;
1794 } while (aztIndatum & AFL_STATUS);
1795
1796 if (inb(DATA_PORT) != AFL_OP_OK) { /*OP_OK? If not, reset and try again */
1797#ifndef MODULE
1798 if (azt_cont != 0x79) {
1799 printk(KERN_WARNING "aztcd: no AZTECH CD-ROM "
1800 "drive found-Try boot parameter aztcd="
1801 "<BaseAddress>,0x79\n");
1802 ret = -EIO;
1803 goto err_out;
1804 }
1805#else
1806 if (0) {
1807 }
1808#endif
1809 else {
1810 printk(KERN_INFO "aztcd: drive reset - "
1811 "please wait\n");
1812 for (count = 0; count < 50; count++) {
1813 inb(STATUS_PORT); /*removing all data from earlier tries */
1814 inb(DATA_PORT);
1815 }
1816 outb(POLLED, MODE_PORT);
1817 inb(CMD_PORT);
1818 inb(CMD_PORT);
1819 getAztStatus(); /*trap errors */
1820 outb(ACMD_SOFT_RESET, CMD_PORT); /*send reset */
1821 STEN_LOW;
1822 if (inb(DATA_PORT) != AFL_OP_OK) { /*OP_OK? */
1823 printk(KERN_WARNING "aztcd: no AZTECH "
1824 "CD-ROM drive found\n");
1825 ret = -EIO;
1826 goto err_out;
1827 }
1828
1829 for (count = 0; count < AZT_TIMEOUT;
1830 count++)
1831 barrier(); /* Stop gcc 2.96 being smart */
1832 /* use udelay(), damnit -- AV */
1833
1834 if ((st = getAztStatus()) == -1) {
1835 printk(KERN_WARNING "aztcd: Drive Status"
1836 " Error Status=%x\n", st);
1837 ret = -EIO;
1838 goto err_out;
1839 }
1840#ifdef AZT_DEBUG
1841 printk(KERN_DEBUG "aztcd: Status = %x\n", st);
1842#endif
1843 outb(POLLED, MODE_PORT);
1844 inb(CMD_PORT);
1845 inb(CMD_PORT);
1846 outb(ACMD_GET_VERSION, CMD_PORT); /*GetVersion */
1847 STEN_LOW;
1848 OP_OK;
1849 }
1850 }
1851 }
1852
1853 azt_init_end = 1;
1854 STEN_LOW;
1855 result[0] = inb(DATA_PORT); /*reading in a null byte??? */
1856 for (count = 1; count < 50; count++) { /*Reading version string */
1857 aztTimeOutCount = 0; /*here we must implement STEN_LOW differently */
1858 do {
1859 aztIndatum = inb(STATUS_PORT); /*because we want to exit by timeout */
1860 aztTimeOutCount++;
1861 if (aztTimeOutCount >= AZT_FAST_TIMEOUT)
1862 break;
1863 } while (aztIndatum & AFL_STATUS);
1864 if (aztTimeOutCount >= AZT_FAST_TIMEOUT)
1865 break; /*all chars read? */
1866 result[count] = inb(DATA_PORT);
1867 }
1868 if (count > 30)
1869 max_count = 30; /*print max.30 chars of the version string */
1870 else
1871 max_count = count;
1872 printk(KERN_INFO "aztcd: FirmwareVersion=");
1873 for (count = 1; count < max_count; count++)
1874 printk("%c", result[count]);
1875 printk("<<>> ");
1876
1877 if ((result[1] == 'A') && (result[2] == 'Z') && (result[3] == 'T')) {
1878 printk("AZTECH drive detected\n");
1879 /*AZTECH*/}
1880 else if ((result[2] == 'C') && (result[3] == 'D')
1881 && (result[4] == 'D')) {
1882 printk("ORCHID or WEARNES drive detected\n"); /*ORCHID or WEARNES */
1883 } else if ((result[1] == 0x03) && (result[2] == '5')) {
1884 printk("TXC or CyCDROM drive detected\n"); /*Conrad TXC, CyCDROM */
1885 } else { /*OTHERS or none */
1886 printk("\nunknown drive or firmware version detected\n");
1887 printk
1888 ("aztcd may not run stable, if you want to try anyhow,\n");
1889 printk("boot with: aztcd=<BaseAddress>,0x79\n");
1890 if ((azt_cont != 0x79)) {
1891 printk("aztcd: FirmwareVersion=");
1892 for (count = 1; count < 5; count++)
1893 printk("%c", result[count]);
1894 printk("<<>> ");
1895 printk("Aborted\n");
1896 ret = -EIO;
1897 goto err_out;
1898 }
1899 }
1900 azt_disk = alloc_disk(1);
1901 if (!azt_disk)
1902 goto err_out;
1903
1904 if (register_blkdev(MAJOR_NR, "aztcd")) {
1905 ret = -EIO;
1906 goto err_out2;
1907 }
1908
1909 azt_queue = blk_init_queue(do_aztcd_request, &aztSpin);
1910 if (!azt_queue) {
1911 ret = -ENOMEM;
1912 goto err_out3;
1913 }
1914
1915 blk_queue_hardsect_size(azt_queue, 2048);
1916 azt_disk->major = MAJOR_NR;
1917 azt_disk->first_minor = 0;
1918 azt_disk->fops = &azt_fops;
1919 sprintf(azt_disk->disk_name, "aztcd");
1920 azt_disk->queue = azt_queue;
1921 add_disk(azt_disk);
1922 azt_invalidate_buffers();
1923 aztPresent = 1;
1924 aztCloseDoor();
1925 return 0;
1926err_out3:
1927 unregister_blkdev(MAJOR_NR, "aztcd");
1928err_out2:
1929 put_disk(azt_disk);
1930err_out:
1931 if ((azt_port == 0x1f0) || (azt_port == 0x170)) {
1932 SWITCH_IDE_MASTER;
1933 release_region(azt_port, 8); /*IDE-interface */
1934 } else
1935 release_region(azt_port, 4); /*proprietary interface */
1936 return ret;
1937
1938}
1939
1940static void __exit aztcd_exit(void)
1941{
1942 del_gendisk(azt_disk);
1943 put_disk(azt_disk);
1944 if ((unregister_blkdev(MAJOR_NR, "aztcd") == -EINVAL)) {
1945 printk("What's that: can't unregister aztcd\n");
1946 return;
1947 }
1948 blk_cleanup_queue(azt_queue);
1949 if ((azt_port == 0x1f0) || (azt_port == 0x170)) {
1950 SWITCH_IDE_MASTER;
1951 release_region(azt_port, 8); /*IDE-interface */
1952 } else
1953 release_region(azt_port, 4); /*proprietary interface */
1954 printk(KERN_INFO "aztcd module released.\n");
1955}
1956
1957module_init(aztcd_init);
1958module_exit(aztcd_exit);
1959
1960/*##########################################################################
1961 Aztcd State Machine: Controls Drive Operating State
1962 ##########################################################################
1963*/
1964static void azt_poll(void)
1965{
1966 int st = 0;
1967 int loop_ctl = 1;
1968 int skip = 0;
1969
1970 if (azt_error) {
1971 if (aztSendCmd(ACMD_GET_ERROR))
1972 RETURN("azt_poll 1");
1973 STEN_LOW;
1974 azt_error = inb(DATA_PORT) & 0xFF;
1975 printk("aztcd: I/O error 0x%02x\n", azt_error);
1976 azt_invalidate_buffers();
1977#ifdef WARN_IF_READ_FAILURE
1978 if (AztTries == 5)
1979 printk
1980 ("aztcd: Read of Block %d Failed - Maybe Audio Disk?\n",
1981 azt_next_bn);
1982#endif
1983 if (!AztTries--) {
1984 printk
1985 ("aztcd: Read of Block %d Failed, Maybe Audio Disk? Giving up\n",
1986 azt_next_bn);
1987 if (azt_transfer_is_active) {
1988 AztTries = 0;
1989 loop_ctl = 0;
1990 }
1991 if (current_valid())
1992 end_request(CURRENT, 0);
1993 AztTries = 5;
1994 }
1995 azt_error = 0;
1996 azt_state = AZT_S_STOP;
1997 }
1998
1999 while (loop_ctl) {
2000 loop_ctl = 0; /* each case must flip this back to 1 if we want
2001 to come back up here */
2002 switch (azt_state) {
2003
2004 case AZT_S_IDLE:
2005#ifdef AZT_TEST3
2006 if (azt_state != azt_state_old) {
2007 azt_state_old = azt_state;
2008 printk("AZT_S_IDLE\n");
2009 }
2010#endif
2011 return;
2012
2013 case AZT_S_START:
2014#ifdef AZT_TEST3
2015 if (azt_state != azt_state_old) {
2016 azt_state_old = azt_state;
2017 printk("AZT_S_START\n");
2018 }
2019#endif
2020 if (aztSendCmd(ACMD_GET_STATUS))
2021 RETURN("azt_poll 2"); /*result will be checked by aztStatus() */
2022 azt_state =
2023 azt_mode == 1 ? AZT_S_READ : AZT_S_MODE;
2024 AztTimeout = 3000;
2025 break;
2026
2027 case AZT_S_MODE:
2028#ifdef AZT_TEST3
2029 if (azt_state != azt_state_old) {
2030 azt_state_old = azt_state;
2031 printk("AZT_S_MODE\n");
2032 }
2033#endif
2034 if (!skip) {
2035 if ((st = aztStatus()) != -1) {
2036 if ((st & AST_DSK_CHG)
2037 || (st & AST_NOT_READY)) {
2038 aztDiskChanged = 1;
2039 aztTocUpToDate = 0;
2040 azt_invalidate_buffers();
2041 end_request(CURRENT, 0);
2042 printk
2043 ("aztcd: Disk Changed or Not Ready 1 - Unmount Disk!\n");
2044 }
2045 } else
2046 break;
2047 }
2048 skip = 0;
2049
2050 if ((st & AST_DOOR_OPEN) || (st & AST_NOT_READY)) {
2051 aztDiskChanged = 1;
2052 aztTocUpToDate = 0;
2053 printk
2054 ("aztcd: Disk Changed or Not Ready 2 - Unmount Disk!\n");
2055 end_request(CURRENT, 0);
2056 printk((st & AST_DOOR_OPEN) ?
2057 "aztcd: door open\n" :
2058 "aztcd: disk removed\n");
2059 if (azt_transfer_is_active) {
2060 azt_state = AZT_S_START;
2061 loop_ctl = 1; /* goto immediately */
2062 break;
2063 }
2064 azt_state = AZT_S_IDLE;
2065 while (current_valid())
2066 end_request(CURRENT, 0);
2067 return;
2068 }
2069
2070/* if (aztSendCmd(ACMD_SET_MODE)) RETURN("azt_poll 3");
2071 outb(0x01, DATA_PORT);
2072 PA_OK;
2073 STEN_LOW;
2074*/
2075 if (aztSendCmd(ACMD_GET_STATUS))
2076 RETURN("azt_poll 4");
2077 STEN_LOW;
2078 azt_mode = 1;
2079 azt_state = AZT_S_READ;
2080 AztTimeout = 3000;
2081
2082 break;
2083
2084
2085 case AZT_S_READ:
2086#ifdef AZT_TEST3
2087 if (azt_state != azt_state_old) {
2088 azt_state_old = azt_state;
2089 printk("AZT_S_READ\n");
2090 }
2091#endif
2092 if (!skip) {
2093 if ((st = aztStatus()) != -1) {
2094 if ((st & AST_DSK_CHG)
2095 || (st & AST_NOT_READY)) {
2096 aztDiskChanged = 1;
2097 aztTocUpToDate = 0;
2098 azt_invalidate_buffers();
2099 printk
2100 ("aztcd: Disk Changed or Not Ready 3 - Unmount Disk!\n");
2101 end_request(CURRENT, 0);
2102 }
2103 } else
2104 break;
2105 }
2106
2107 skip = 0;
2108 if ((st & AST_DOOR_OPEN) || (st & AST_NOT_READY)) {
2109 aztDiskChanged = 1;
2110 aztTocUpToDate = 0;
2111 printk((st & AST_DOOR_OPEN) ?
2112 "aztcd: door open\n" :
2113 "aztcd: disk removed\n");
2114 if (azt_transfer_is_active) {
2115 azt_state = AZT_S_START;
2116 loop_ctl = 1;
2117 break;
2118 }
2119 azt_state = AZT_S_IDLE;
2120 while (current_valid())
2121 end_request(CURRENT, 0);
2122 return;
2123 }
2124
2125 if (current_valid()) {
2126 struct azt_Play_msf msf;
2127 int i;
2128 azt_next_bn = CURRENT->sector / 4;
2129 azt_hsg2msf(azt_next_bn, &msf.start);
2130 i = 0;
2131 /* find out in which track we are */
2132 while (azt_msf2hsg(&msf.start) >
2133 azt_msf2hsg(&Toc[++i].trackTime)) {
2134 };
2135 if (azt_msf2hsg(&msf.start) <
2136 azt_msf2hsg(&Toc[i].trackTime) -
2137 AZT_BUF_SIZ) {
2138 azt_read_count = AZT_BUF_SIZ; /*fast, because we read ahead */
2139 /*azt_read_count=CURRENT->nr_sectors; slow, no read ahead */
2140 } else /* don't read beyond end of track */
2141#if AZT_MULTISESSION
2142 {
2143 azt_read_count =
2144 (azt_msf2hsg(&Toc[i].trackTime)
2145 / 4) * 4 -
2146 azt_msf2hsg(&msf.start);
2147 if (azt_read_count < 0)
2148 azt_read_count = 0;
2149 if (azt_read_count > AZT_BUF_SIZ)
2150 azt_read_count =
2151 AZT_BUF_SIZ;
2152 printk
2153 ("aztcd: warning - trying to read beyond end of track\n");
2154/* printk("%i %i %li %li\n",i,azt_read_count,azt_msf2hsg(&msf.start),azt_msf2hsg(&Toc[i].trackTime));
2155*/ }
2156#else
2157 {
2158 azt_read_count = AZT_BUF_SIZ;
2159 }
2160#endif
2161 msf.end.min = 0;
2162 msf.end.sec = 0;
2163 msf.end.frame = azt_read_count; /*Mitsumi here reads 0xffffff sectors */
2164#ifdef AZT_TEST3
2165 printk
2166 ("---reading msf-address %x:%x:%x %x:%x:%x\n",
2167 msf.start.min, msf.start.sec,
2168 msf.start.frame, msf.end.min,
2169 msf.end.sec, msf.end.frame);
2170 printk
2171 ("azt_next_bn:%x azt_buf_in:%x azt_buf_out:%x azt_buf_bn:%x\n",
2172 azt_next_bn, azt_buf_in, azt_buf_out,
2173 azt_buf_bn[azt_buf_in]);
2174#endif
2175 if (azt_read_mode == AZT_MODE_2) {
2176 sendAztCmd(ACMD_PLAY_READ_RAW, &msf); /*XA disks in raw mode */
2177 } else {
2178 sendAztCmd(ACMD_PLAY_READ, &msf); /*others in cooked mode */
2179 }
2180 azt_state = AZT_S_DATA;
2181 AztTimeout = READ_TIMEOUT;
2182 } else {
2183 azt_state = AZT_S_STOP;
2184 loop_ctl = 1;
2185 break;
2186 }
2187
2188 break;
2189
2190
2191 case AZT_S_DATA:
2192#ifdef AZT_TEST3
2193 if (azt_state != azt_state_old) {
2194 azt_state_old = azt_state;
2195 printk("AZT_S_DATA\n");
2196 }
2197#endif
2198
2199 st = inb(STATUS_PORT) & AFL_STATUSorDATA;
2200
2201 switch (st) {
2202
2203 case AFL_DATA:
2204#ifdef AZT_TEST3
2205 if (st != azt_st_old) {
2206 azt_st_old = st;
2207 printk("---AFL_DATA st:%x\n", st);
2208 }
2209#endif
2210 if (!AztTries--) {
2211 printk
2212 ("aztcd: Read of Block %d Failed, Maybe Audio Disk ? Giving up\n",
2213 azt_next_bn);
2214 if (azt_transfer_is_active) {
2215 AztTries = 0;
2216 break;
2217 }
2218 if (current_valid())
2219 end_request(CURRENT, 0);
2220 AztTries = 5;
2221 }
2222 azt_state = AZT_S_START;
2223 AztTimeout = READ_TIMEOUT;
2224 loop_ctl = 1;
2225 break;
2226
2227 case AFL_STATUSorDATA:
2228#ifdef AZT_TEST3
2229 if (st != azt_st_old) {
2230 azt_st_old = st;
2231 printk
2232 ("---AFL_STATUSorDATA st:%x\n",
2233 st);
2234 }
2235#endif
2236 break;
2237
2238 default:
2239#ifdef AZT_TEST3
2240 if (st != azt_st_old) {
2241 azt_st_old = st;
2242 printk("---default: st:%x\n", st);
2243 }
2244#endif
2245 AztTries = 5;
2246 if (!current_valid() && azt_buf_in == azt_buf_out) {
2247 azt_state = AZT_S_STOP;
2248 loop_ctl = 1;
2249 break;
2250 }
2251 if (azt_read_count <= 0)
2252 printk
2253 ("aztcd: warning - try to read 0 frames\n");
2254 while (azt_read_count) { /*??? fast read ahead loop */
2255 azt_buf_bn[azt_buf_in] = -1;
2256 DTEN_LOW; /*??? unsolved problem, very
2257 seldom we get timeouts
2258 here, don't now the real
2259 reason. With my drive this
2260 sometimes also happens with
2261 Aztech's original driver under
2262 DOS. Is it a hardware bug?
2263 I tried to recover from such
2264 situations here. Zimmermann */
2265 if (aztTimeOutCount >= AZT_TIMEOUT) {
2266 printk
2267 ("read_count:%d CURRENT->nr_sectors:%ld azt_buf_in:%d\n",
2268 azt_read_count,
2269 CURRENT->nr_sectors,
2270 azt_buf_in);
2271 printk
2272 ("azt_transfer_is_active:%x\n",
2273 azt_transfer_is_active);
2274 azt_read_count = 0;
2275 azt_state = AZT_S_STOP;
2276 loop_ctl = 1;
2277 end_request(CURRENT, 1); /*should we have here (1) or (0)? */
2278 } else {
2279 if (azt_read_mode ==
2280 AZT_MODE_2) {
2281 insb(DATA_PORT,
2282 azt_buf +
2283 CD_FRAMESIZE_RAW
2284 * azt_buf_in,
2285 CD_FRAMESIZE_RAW);
2286 } else {
2287 insb(DATA_PORT,
2288 azt_buf +
2289 CD_FRAMESIZE *
2290 azt_buf_in,
2291 CD_FRAMESIZE);
2292 }
2293 azt_read_count--;
2294#ifdef AZT_TEST3
2295 printk
2296 ("AZT_S_DATA; ---I've read data- read_count: %d\n",
2297 azt_read_count);
2298 printk
2299 ("azt_next_bn:%d azt_buf_in:%d azt_buf_out:%d azt_buf_bn:%d\n",
2300 azt_next_bn,
2301 azt_buf_in,
2302 azt_buf_out,
2303 azt_buf_bn
2304 [azt_buf_in]);
2305#endif
2306 azt_buf_bn[azt_buf_in] =
2307 azt_next_bn++;
2308 if (azt_buf_out == -1)
2309 azt_buf_out =
2310 azt_buf_in;
2311 azt_buf_in =
2312 azt_buf_in + 1 ==
2313 AZT_BUF_SIZ ? 0 :
2314 azt_buf_in + 1;
2315 }
2316 }
2317 if (!azt_transfer_is_active) {
2318 while (current_valid()) {
2319 azt_transfer();
2320 if (CURRENT->nr_sectors ==
2321 0)
2322 end_request(CURRENT, 1);
2323 else
2324 break;
2325 }
2326 }
2327
2328 if (current_valid()
2329 && (CURRENT->sector / 4 < azt_next_bn
2330 || CURRENT->sector / 4 >
2331 azt_next_bn + AZT_BUF_SIZ)) {
2332 azt_state = AZT_S_STOP;
2333 loop_ctl = 1;
2334 break;
2335 }
2336 AztTimeout = READ_TIMEOUT;
2337 if (azt_read_count == 0) {
2338 azt_state = AZT_S_STOP;
2339 loop_ctl = 1;
2340 break;
2341 }
2342 break;
2343 }
2344 break;
2345
2346
2347 case AZT_S_STOP:
2348#ifdef AZT_TEST3
2349 if (azt_state != azt_state_old) {
2350 azt_state_old = azt_state;
2351 printk("AZT_S_STOP\n");
2352 }
2353#endif
2354 if (azt_read_count != 0)
2355 printk("aztcd: discard data=%x frames\n",
2356 azt_read_count);
2357 while (azt_read_count != 0) {
2358 int i;
2359 if (!(inb(STATUS_PORT) & AFL_DATA)) {
2360 if (azt_read_mode == AZT_MODE_2)
2361 for (i = 0;
2362 i < CD_FRAMESIZE_RAW;
2363 i++)
2364 inb(DATA_PORT);
2365 else
2366 for (i = 0;
2367 i < CD_FRAMESIZE; i++)
2368 inb(DATA_PORT);
2369 }
2370 azt_read_count--;
2371 }
2372 if (aztSendCmd(ACMD_GET_STATUS))
2373 RETURN("azt_poll 5");
2374 azt_state = AZT_S_STOPPING;
2375 AztTimeout = 1000;
2376 break;
2377
2378 case AZT_S_STOPPING:
2379#ifdef AZT_TEST3
2380 if (azt_state != azt_state_old) {
2381 azt_state_old = azt_state;
2382 printk("AZT_S_STOPPING\n");
2383 }
2384#endif
2385
2386 if ((st = aztStatus()) == -1 && AztTimeout)
2387 break;
2388
2389 if ((st != -1)
2390 && ((st & AST_DSK_CHG)
2391 || (st & AST_NOT_READY))) {
2392 aztDiskChanged = 1;
2393 aztTocUpToDate = 0;
2394 azt_invalidate_buffers();
2395 printk
2396 ("aztcd: Disk Changed or Not Ready 4 - Unmount Disk!\n");
2397 end_request(CURRENT, 0);
2398 }
2399
2400#ifdef AZT_TEST3
2401 printk("CURRENT_VALID %d azt_mode %d\n",
2402 current_valid(), azt_mode);
2403#endif
2404
2405 if (current_valid()) {
2406 if (st != -1) {
2407 if (azt_mode == 1) {
2408 azt_state = AZT_S_READ;
2409 loop_ctl = 1;
2410 skip = 1;
2411 break;
2412 } else {
2413 azt_state = AZT_S_MODE;
2414 loop_ctl = 1;
2415 skip = 1;
2416 break;
2417 }
2418 } else {
2419 azt_state = AZT_S_START;
2420 AztTimeout = 1;
2421 }
2422 } else {
2423 azt_state = AZT_S_IDLE;
2424 return;
2425 }
2426 break;
2427
2428 default:
2429 printk("aztcd: invalid state %d\n", azt_state);
2430 return;
2431 } /* case */
2432 } /* while */
2433
2434
2435 if (!AztTimeout--) {
2436 printk("aztcd: timeout in state %d\n", azt_state);
2437 azt_state = AZT_S_STOP;
2438 if (aztSendCmd(ACMD_STOP))
2439 RETURN("azt_poll 6");
2440 STEN_LOW_WAIT;
2441 };
2442
2443 SET_TIMER(azt_poll, HZ / 100);
2444}
2445
2446
2447/*###########################################################################
2448 * Miscellaneous support functions
2449 ###########################################################################
2450*/
2451static void azt_hsg2msf(long hsg, struct msf *msf)
2452{
2453 hsg += 150;
2454 msf->min = hsg / 4500;
2455 hsg %= 4500;
2456 msf->sec = hsg / 75;
2457 msf->frame = hsg % 75;
2458#ifdef AZT_DEBUG
2459 if (msf->min >= 70)
2460 printk("aztcd: Error hsg2msf address Minutes\n");
2461 if (msf->sec >= 60)
2462 printk("aztcd: Error hsg2msf address Seconds\n");
2463 if (msf->frame >= 75)
2464 printk("aztcd: Error hsg2msf address Frames\n");
2465#endif
2466 azt_bin2bcd(&msf->min); /* convert to BCD */
2467 azt_bin2bcd(&msf->sec);
2468 azt_bin2bcd(&msf->frame);
2469}
2470
2471static long azt_msf2hsg(struct msf *mp)
2472{
2473 return azt_bcd2bin(mp->frame) + azt_bcd2bin(mp->sec) * 75
2474 + azt_bcd2bin(mp->min) * 4500 - CD_MSF_OFFSET;
2475}
2476
2477static void azt_bin2bcd(unsigned char *p)
2478{
2479 int u, t;
2480
2481 u = *p % 10;
2482 t = *p / 10;
2483 *p = u | (t << 4);
2484}
2485
2486static int azt_bcd2bin(unsigned char bcd)
2487{
2488 return (bcd >> 4) * 10 + (bcd & 0xF);
2489}
2490
2491MODULE_LICENSE("GPL");
2492MODULE_ALIAS_BLOCKDEV_MAJOR(AZTECH_CDROM_MAJOR);
diff --git a/drivers/cdrom/aztcd.h b/drivers/cdrom/aztcd.h
deleted file mode 100644
index 057501e31628..000000000000
--- a/drivers/cdrom/aztcd.h
+++ /dev/null
@@ -1,162 +0,0 @@
1/* $Id: aztcd.h,v 2.60 1997/11/29 09:51:22 root Exp root $
2 *
3 * Definitions for a AztechCD268 CD-ROM interface
4 * Copyright (C) 1994-98 Werner Zimmermann
5 *
6 * based on Mitsumi CDROM driver by Martin Harriss
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22 * History: W.Zimmermann adaption to Aztech CD268-01A Version 1.3
23 * October 1994 Email: Werner.Zimmermann@fht-esslingen.de
24 */
25
26/* *** change this to set the I/O port address of your CD-ROM drive,
27 set to '-1', if you want autoprobing */
28#define AZT_BASE_ADDR -1
29
30/* list of autoprobing addresses (not more than 15), last value must be 0x000
31 Note: Autoprobing is only enabled, if AZT_BASE_ADDR is set to '-1' ! */
32#define AZT_BASE_AUTO { 0x320, 0x300, 0x310, 0x330, 0x000 }
33
34/* Uncomment this, if your CDROM is connected to a Soundwave32-soundcard
35 and configure AZT_BASE_ADDR and AZT_SW32_BASE_ADDR */
36/*#define AZT_SW32 1
37*/
38
39#ifdef AZT_SW32
40#define AZT_SW32_BASE_ADDR 0x220 /*I/O port base address of your soundcard*/
41#endif
42
43/* Set this to 1, if you want your tray to be locked, set to 0 to prevent tray
44 from locking */
45#define AZT_ALLOW_TRAY_LOCK 1
46
47/*Set this to 1 to allow auto-eject when unmounting a disk, set to 0, if you
48 don't want the auto-eject feature*/
49#define AZT_AUTO_EJECT 0
50
51/*Set this to 1, if you want to use incompatible ioctls for reading in raw and
52 cooked mode */
53#define AZT_PRIVATE_IOCTLS 1
54
55/*Set this to 1, if you want multisession support by the ISO fs. Even if you set
56 this value to '0' you can use multisession CDs. In that case the drive's firm-
57 ware will do the appropriate redirection automatically. The CD will then look
58 like a single session CD (but nevertheless all data may be read). Please read
59 chapter '5.1 Multisession support' in README.aztcd for details. Normally it's
60 uncritical to leave this setting untouched */
61#define AZT_MULTISESSION 1
62
63/*Uncomment this, if you are using a linux kernel version prior to 2.1.0 */
64/*#define AZT_KERNEL_PRIOR_2_1 */
65
66/*---------------------------------------------------------------------------*/
67/*-----nothing to be configured for normal applications below this line------*/
68
69
70/* Increase this if you get lots of timeouts; if you get kernel panic, replace
71 STEN_LOW_WAIT by STEN_LOW in the source code */
72#define AZT_STATUS_DELAY 400 /*for timer wait, STEN_LOW_WAIT*/
73#define AZT_TIMEOUT 8000000 /*for busy wait STEN_LOW, DTEN_LOW*/
74#define AZT_FAST_TIMEOUT 10000 /*for reading the version string*/
75
76/* number of times to retry a command before giving up */
77#define AZT_RETRY_ATTEMPTS 3
78
79/* port access macros */
80#define CMD_PORT azt_port
81#define DATA_PORT azt_port
82#define STATUS_PORT azt_port+1
83#define MODE_PORT azt_port+2
84#ifdef AZT_SW32
85 #define AZT_SW32_INIT (unsigned int) (0xFF00 & (AZT_BASE_ADDR*16))
86 #define AZT_SW32_CONFIG_REG AZT_SW32_BASE_ADDR+0x16 /*Soundwave32 Config. Register*/
87 #define AZT_SW32_ID_REG AZT_SW32_BASE_ADDR+0x04 /*Soundwave32 ID Version Register*/
88#endif
89
90/* status bits */
91#define AST_CMD_CHECK 0x80 /* 1 = command error */
92#define AST_DOOR_OPEN 0x40 /* 1 = door is open */
93#define AST_NOT_READY 0x20 /* 1 = no disk in the drive */
94#define AST_DSK_CHG 0x02 /* 1 = disk removed or changed */
95#define AST_MODE 0x01 /* 0=MODE1, 1=MODE2 */
96#define AST_MODE_BITS 0x1C /* Mode Bits */
97#define AST_INITIAL 0x0C /* initial, only valid ... */
98#define AST_BUSY 0x04 /* now playing, only valid
99 in combination with mode
100 bits */
101/* flag bits */
102#define AFL_DATA 0x02 /* data available if low */
103#define AFL_STATUS 0x04 /* status available if low */
104#define AFL_OP_OK 0x01 /* OP_OK command correct*/
105#define AFL_PA_OK 0x02 /* PA_OK parameter correct*/
106#define AFL_OP_ERR 0x05 /* error in command*/
107#define AFL_PA_ERR 0x06 /* error in parameters*/
108#define POLLED 0x04 /* polled mode */
109
110/* commands */
111#define ACMD_SOFT_RESET 0x10 /* reset drive */
112#define ACMD_PLAY_READ 0x20 /* read data track in cooked mode */
113#define ACMD_PLAY_READ_RAW 0x21 /* reading in raw mode*/
114#define ACMD_SEEK 0x30 /* seek msf address*/
115#define ACMD_SEEK_TO_LEADIN 0x31 /* seek to leadin track*/
116#define ACMD_GET_ERROR 0x40 /* get error code */
117#define ACMD_GET_STATUS 0x41 /* get status */
118#define ACMD_GET_Q_CHANNEL 0x50 /* read info from q channel */
119#define ACMD_EJECT 0x60 /* eject/open tray */
120#define ACMD_CLOSE 0x61 /* close tray */
121#define ACMD_LOCK 0x71 /* lock tray closed */
122#define ACMD_UNLOCK 0x72 /* unlock tray */
123#define ACMD_PAUSE 0x80 /* pause */
124#define ACMD_STOP 0x81 /* stop play */
125#define ACMD_PLAY_AUDIO 0x90 /* play audio track */
126#define ACMD_SET_VOLUME 0x93 /* set audio level */
127#define ACMD_GET_VERSION 0xA0 /* get firmware version */
128#define ACMD_SET_DISK_TYPE 0xA1 /* set disk data mode */
129
130#define MAX_TRACKS 104
131
132struct msf {
133 unsigned char min;
134 unsigned char sec;
135 unsigned char frame;
136};
137
138struct azt_Play_msf {
139 struct msf start;
140 struct msf end;
141};
142
143struct azt_DiskInfo {
144 unsigned char first;
145 unsigned char next;
146 unsigned char last;
147 struct msf diskLength;
148 struct msf firstTrack;
149 unsigned char multi;
150 struct msf nextSession;
151 struct msf lastSession;
152 unsigned char xa;
153 unsigned char audio;
154};
155
156struct azt_Toc {
157 unsigned char ctrl_addr;
158 unsigned char track;
159 unsigned char pointIndex;
160 struct msf trackTime;
161 struct msf diskTime;
162};
diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c
index 3625a05bc3d3..aa5468f487ba 100644
--- a/drivers/cdrom/cdrom.c
+++ b/drivers/cdrom/cdrom.c
@@ -302,7 +302,7 @@ module_param(lockdoor, bool, 0);
302module_param(check_media_type, bool, 0); 302module_param(check_media_type, bool, 0);
303module_param(mrw_format_restart, bool, 0); 303module_param(mrw_format_restart, bool, 0);
304 304
305static DEFINE_SPINLOCK(cdrom_lock); 305static DEFINE_MUTEX(cdrom_mutex);
306 306
307static const char *mrw_format_status[] = { 307static const char *mrw_format_status[] = {
308 "not mrw", 308 "not mrw",
@@ -438,10 +438,10 @@ int register_cdrom(struct cdrom_device_info *cdi)
438 cdo->generic_packet = cdrom_dummy_generic_packet; 438 cdo->generic_packet = cdrom_dummy_generic_packet;
439 439
440 cdinfo(CD_REG_UNREG, "drive \"/dev/%s\" registered\n", cdi->name); 440 cdinfo(CD_REG_UNREG, "drive \"/dev/%s\" registered\n", cdi->name);
441 spin_lock(&cdrom_lock); 441 mutex_lock(&cdrom_mutex);
442 cdi->next = topCdromPtr; 442 cdi->next = topCdromPtr;
443 topCdromPtr = cdi; 443 topCdromPtr = cdi;
444 spin_unlock(&cdrom_lock); 444 mutex_unlock(&cdrom_mutex);
445 return 0; 445 return 0;
446} 446}
447#undef ENSURE 447#undef ENSURE
@@ -452,7 +452,7 @@ int unregister_cdrom(struct cdrom_device_info *unreg)
452 cdinfo(CD_OPEN, "entering unregister_cdrom\n"); 452 cdinfo(CD_OPEN, "entering unregister_cdrom\n");
453 453
454 prev = NULL; 454 prev = NULL;
455 spin_lock(&cdrom_lock); 455 mutex_lock(&cdrom_mutex);
456 cdi = topCdromPtr; 456 cdi = topCdromPtr;
457 while (cdi && cdi != unreg) { 457 while (cdi && cdi != unreg) {
458 prev = cdi; 458 prev = cdi;
@@ -460,7 +460,7 @@ int unregister_cdrom(struct cdrom_device_info *unreg)
460 } 460 }
461 461
462 if (cdi == NULL) { 462 if (cdi == NULL) {
463 spin_unlock(&cdrom_lock); 463 mutex_unlock(&cdrom_mutex);
464 return -2; 464 return -2;
465 } 465 }
466 if (prev) 466 if (prev)
@@ -468,7 +468,7 @@ int unregister_cdrom(struct cdrom_device_info *unreg)
468 else 468 else
469 topCdromPtr = cdi->next; 469 topCdromPtr = cdi->next;
470 470
471 spin_unlock(&cdrom_lock); 471 mutex_unlock(&cdrom_mutex);
472 472
473 if (cdi->exit) 473 if (cdi->exit)
474 cdi->exit(cdi); 474 cdi->exit(cdi);
@@ -3289,103 +3289,137 @@ static struct cdrom_sysctl_settings {
3289 int check; /* check media type */ 3289 int check; /* check media type */
3290} cdrom_sysctl_settings; 3290} cdrom_sysctl_settings;
3291 3291
3292enum cdrom_print_option {
3293 CTL_NAME,
3294 CTL_SPEED,
3295 CTL_SLOTS,
3296 CTL_CAPABILITY
3297};
3298
3299static int cdrom_print_info(const char *header, int val, char *info,
3300 int *pos, enum cdrom_print_option option)
3301{
3302 const int max_size = sizeof(cdrom_sysctl_settings.info);
3303 struct cdrom_device_info *cdi;
3304 int ret;
3305
3306 ret = scnprintf(info + *pos, max_size - *pos, header);
3307 if (!ret)
3308 return 1;
3309
3310 *pos += ret;
3311
3312 for (cdi = topCdromPtr; cdi; cdi = cdi->next) {
3313 switch (option) {
3314 case CTL_NAME:
3315 ret = scnprintf(info + *pos, max_size - *pos,
3316 "\t%s", cdi->name);
3317 break;
3318 case CTL_SPEED:
3319 ret = scnprintf(info + *pos, max_size - *pos,
3320 "\t%d", cdi->speed);
3321 break;
3322 case CTL_SLOTS:
3323 ret = scnprintf(info + *pos, max_size - *pos,
3324 "\t%d", cdi->capacity);
3325 break;
3326 case CTL_CAPABILITY:
3327 ret = scnprintf(info + *pos, max_size - *pos,
3328 "\t%d", CDROM_CAN(val) != 0);
3329 break;
3330 default:
3331 printk(KERN_INFO "cdrom: invalid option%d\n", option);
3332 return 1;
3333 }
3334 if (!ret)
3335 return 1;
3336 *pos += ret;
3337 }
3338
3339 return 0;
3340}
3341
3292static int cdrom_sysctl_info(ctl_table *ctl, int write, struct file * filp, 3342static int cdrom_sysctl_info(ctl_table *ctl, int write, struct file * filp,
3293 void __user *buffer, size_t *lenp, loff_t *ppos) 3343 void __user *buffer, size_t *lenp, loff_t *ppos)
3294{ 3344{
3295 int pos; 3345 int pos;
3296 struct cdrom_device_info *cdi;
3297 char *info = cdrom_sysctl_settings.info; 3346 char *info = cdrom_sysctl_settings.info;
3347 const int max_size = sizeof(cdrom_sysctl_settings.info);
3298 3348
3299 if (!*lenp || (*ppos && !write)) { 3349 if (!*lenp || (*ppos && !write)) {
3300 *lenp = 0; 3350 *lenp = 0;
3301 return 0; 3351 return 0;
3302 } 3352 }
3303 3353
3354 mutex_lock(&cdrom_mutex);
3355
3304 pos = sprintf(info, "CD-ROM information, " VERSION "\n"); 3356 pos = sprintf(info, "CD-ROM information, " VERSION "\n");
3305 3357
3306 pos += sprintf(info+pos, "\ndrive name:\t"); 3358 if (cdrom_print_info("\ndrive name:\t", 0, info, &pos, CTL_NAME))
3307 for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next) 3359 goto done;
3308 pos += sprintf(info+pos, "\t%s", cdi->name); 3360 if (cdrom_print_info("\ndrive speed:\t", 0, info, &pos, CTL_SPEED))
3309 3361 goto done;
3310 pos += sprintf(info+pos, "\ndrive speed:\t"); 3362 if (cdrom_print_info("\ndrive # of slots:", 0, info, &pos, CTL_SLOTS))
3311 for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next) 3363 goto done;
3312 pos += sprintf(info+pos, "\t%d", cdi->speed); 3364 if (cdrom_print_info("\nCan close tray:\t",
3313 3365 CDC_CLOSE_TRAY, info, &pos, CTL_CAPABILITY))
3314 pos += sprintf(info+pos, "\ndrive # of slots:"); 3366 goto done;
3315 for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next) 3367 if (cdrom_print_info("\nCan open tray:\t",
3316 pos += sprintf(info+pos, "\t%d", cdi->capacity); 3368 CDC_OPEN_TRAY, info, &pos, CTL_CAPABILITY))
3317 3369 goto done;
3318 pos += sprintf(info+pos, "\nCan close tray:\t"); 3370 if (cdrom_print_info("\nCan lock tray:\t",
3319 for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next) 3371 CDC_LOCK, info, &pos, CTL_CAPABILITY))
3320 pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_CLOSE_TRAY) != 0); 3372 goto done;
3321 3373 if (cdrom_print_info("\nCan change speed:",
3322 pos += sprintf(info+pos, "\nCan open tray:\t"); 3374 CDC_SELECT_SPEED, info, &pos, CTL_CAPABILITY))
3323 for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next) 3375 goto done;
3324 pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_OPEN_TRAY) != 0); 3376 if (cdrom_print_info("\nCan select disk:",
3325 3377 CDC_SELECT_DISC, info, &pos, CTL_CAPABILITY))
3326 pos += sprintf(info+pos, "\nCan lock tray:\t"); 3378 goto done;
3327 for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next) 3379 if (cdrom_print_info("\nCan read multisession:",
3328 pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_LOCK) != 0); 3380 CDC_MULTI_SESSION, info, &pos, CTL_CAPABILITY))
3329 3381 goto done;
3330 pos += sprintf(info+pos, "\nCan change speed:"); 3382 if (cdrom_print_info("\nCan read MCN:\t",
3331 for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next) 3383 CDC_MCN, info, &pos, CTL_CAPABILITY))
3332 pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_SELECT_SPEED) != 0); 3384 goto done;
3333 3385 if (cdrom_print_info("\nReports media changed:",
3334 pos += sprintf(info+pos, "\nCan select disk:"); 3386 CDC_MEDIA_CHANGED, info, &pos, CTL_CAPABILITY))
3335 for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next) 3387 goto done;
3336 pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_SELECT_DISC) != 0); 3388 if (cdrom_print_info("\nCan play audio:\t",
3337 3389 CDC_PLAY_AUDIO, info, &pos, CTL_CAPABILITY))
3338 pos += sprintf(info+pos, "\nCan read multisession:"); 3390 goto done;
3339 for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next) 3391 if (cdrom_print_info("\nCan write CD-R:\t",
3340 pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_MULTI_SESSION) != 0); 3392 CDC_CD_R, info, &pos, CTL_CAPABILITY))
3341 3393 goto done;
3342 pos += sprintf(info+pos, "\nCan read MCN:\t"); 3394 if (cdrom_print_info("\nCan write CD-RW:",
3343 for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next) 3395 CDC_CD_RW, info, &pos, CTL_CAPABILITY))
3344 pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_MCN) != 0); 3396 goto done;
3345 3397 if (cdrom_print_info("\nCan read DVD:\t",
3346 pos += sprintf(info+pos, "\nReports media changed:"); 3398 CDC_DVD, info, &pos, CTL_CAPABILITY))
3347 for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next) 3399 goto done;
3348 pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_MEDIA_CHANGED) != 0); 3400 if (cdrom_print_info("\nCan write DVD-R:",
3349 3401 CDC_DVD_R, info, &pos, CTL_CAPABILITY))
3350 pos += sprintf(info+pos, "\nCan play audio:\t"); 3402 goto done;
3351 for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next) 3403 if (cdrom_print_info("\nCan write DVD-RAM:",
3352 pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_PLAY_AUDIO) != 0); 3404 CDC_DVD_RAM, info, &pos, CTL_CAPABILITY))
3353 3405 goto done;
3354 pos += sprintf(info+pos, "\nCan write CD-R:\t"); 3406 if (cdrom_print_info("\nCan read MRW:\t",
3355 for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next) 3407 CDC_MRW, info, &pos, CTL_CAPABILITY))
3356 pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_CD_R) != 0); 3408 goto done;
3357 3409 if (cdrom_print_info("\nCan write MRW:\t",
3358 pos += sprintf(info+pos, "\nCan write CD-RW:"); 3410 CDC_MRW_W, info, &pos, CTL_CAPABILITY))
3359 for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next) 3411 goto done;
3360 pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_CD_RW) != 0); 3412 if (cdrom_print_info("\nCan write RAM:\t",
3361 3413 CDC_RAM, info, &pos, CTL_CAPABILITY))
3362 pos += sprintf(info+pos, "\nCan read DVD:\t"); 3414 goto done;
3363 for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next) 3415 if (!scnprintf(info + pos, max_size - pos, "\n\n"))
3364 pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_DVD) != 0); 3416 goto done;
3365 3417doit:
3366 pos += sprintf(info+pos, "\nCan write DVD-R:"); 3418 mutex_unlock(&cdrom_mutex);
3367 for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next) 3419 return proc_dostring(ctl, write, filp, buffer, lenp, ppos);
3368 pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_DVD_R) != 0); 3420done:
3369 3421 printk(KERN_INFO "cdrom: info buffer too small\n");
3370 pos += sprintf(info+pos, "\nCan write DVD-RAM:"); 3422 goto doit;
3371 for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
3372 pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_DVD_RAM) != 0);
3373
3374 pos += sprintf(info+pos, "\nCan read MRW:\t");
3375 for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
3376 pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_MRW) != 0);
3377
3378 pos += sprintf(info+pos, "\nCan write MRW:\t");
3379 for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
3380 pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_MRW_W) != 0);
3381
3382 pos += sprintf(info+pos, "\nCan write RAM:\t");
3383 for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
3384 pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_RAM) != 0);
3385
3386 strcpy(info+pos,"\n\n");
3387
3388 return proc_dostring(ctl, write, filp, buffer, lenp, ppos);
3389} 3423}
3390 3424
3391/* Unfortunately, per device settings are not implemented through 3425/* Unfortunately, per device settings are not implemented through
diff --git a/drivers/cdrom/cdu31a.c b/drivers/cdrom/cdu31a.c
deleted file mode 100644
index 2157c58755e0..000000000000
--- a/drivers/cdrom/cdu31a.c
+++ /dev/null
@@ -1,3251 +0,0 @@
1/*
2* Sony CDU-31A CDROM interface device driver.
3*
4* Corey Minyard (minyard@wf-rch.cirr.com)
5*
6* Colossians 3:17
7*
8* See Documentation/cdrom/cdu31a for additional details about this driver.
9*
10* The Sony interface device driver handles Sony interface CDROM
11* drives and provides a complete block-level interface as well as an
12* ioctl() interface compatible with the Sun (as specified in
13* include/linux/cdrom.h). With this interface, CDROMs can be
14* accessed and standard audio CDs can be played back normally.
15*
16* WARNING - All autoprobes have been removed from the driver.
17* You MUST configure the CDU31A via a LILO config
18* at boot time or in lilo.conf. I have the
19* following in my lilo.conf:
20*
21* append="cdu31a=0x1f88,0,PAS"
22*
23* The first number is the I/O base address of the
24* card. The second is the interrupt (0 means none).
25 * The third should be "PAS" if on a Pro-Audio
26 * spectrum, or nothing if on something else.
27 *
28 * This interface is (unfortunately) a polled interface. This is
29 * because most Sony interfaces are set up with DMA and interrupts
30 * disables. Some (like mine) do not even have the capability to
31 * handle interrupts or DMA. For this reason you will see a lot of
32 * the following:
33 *
34 * retry_count = jiffies+ SONY_JIFFIES_TIMEOUT;
35 * while (time_before(jiffies, retry_count) && (! <some condition to wait for))
36 * {
37 * while (handle_sony_cd_attention())
38 * ;
39 *
40 * sony_sleep();
41 * }
42 * if (the condition not met)
43 * {
44 * return an error;
45 * }
46 *
47 * This ugly hack waits for something to happen, sleeping a little
48 * between every try. it also handles attentions, which are
49 * asynchronous events from the drive informing the driver that a disk
50 * has been inserted, removed, etc.
51 *
52 * NEWS FLASH - The driver now supports interrupts but they are
53 * turned off by default. Use of interrupts is highly encouraged, it
54 * cuts CPU usage down to a reasonable level. I had DMA in for a while
55 * but PC DMA is just too slow. Better to just insb() it.
56 *
57 * One thing about these drives: They talk in MSF (Minute Second Frame) format.
58 * There are 75 frames a second, 60 seconds a minute, and up to 75 minutes on a
59 * disk. The funny thing is that these are sent to the drive in BCD, but the
60 * interface wants to see them in decimal. A lot of conversion goes on.
61 *
62 * DRIVER SPECIAL FEATURES
63 * -----------------------
64 *
65 * This section describes features beyond the normal audio and CD-ROM
66 * functions of the drive.
67 *
68 * XA compatibility
69 *
70 * The driver should support XA disks for both the CDU31A and CDU33A.
71 * It does this transparently, the using program doesn't need to set it.
72 *
73 * Multi-Session
74 *
75 * A multi-session disk looks just like a normal disk to the user.
76 * Just mount one normally, and all the data should be there.
77 * A special thanks to Koen for help with this!
78 *
79 * Raw sector I/O
80 *
81 * Using the CDROMREADAUDIO it is possible to read raw audio and data
82 * tracks. Both operations return 2352 bytes per sector. On the data
83 * tracks, the first 12 bytes is not returned by the drive and the value
84 * of that data is indeterminate.
85 *
86 *
87 * Copyright (C) 1993 Corey Minyard
88 *
89 * This program is free software; you can redistribute it and/or modify
90 * it under the terms of the GNU General Public License as published by
91 * the Free Software Foundation; either version 2 of the License, or
92 * (at your option) any later version.
93 *
94 * This program is distributed in the hope that it will be useful,
95 * but WITHOUT ANY WARRANTY; without even the implied warranty of
96 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
97 * GNU General Public License for more details.
98 *
99 * You should have received a copy of the GNU General Public License
100 * along with this program; if not, write to the Free Software
101 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
102 *
103 * TODO:
104 * CDs with form1 and form2 sectors cause problems
105 * with current read-ahead strategy.
106 *
107 * Credits:
108 * Heiko Eissfeldt <heiko@colossus.escape.de>
109 * For finding abug in the return of the track numbers.
110 * TOC processing redone for proper multisession support.
111 *
112 *
113 * It probably a little late to be adding a history, but I guess I
114 * will start.
115 *
116 * 10/24/95 - Added support for disabling the eject button when the
117 * drive is open. Note that there is a small problem
118 * still here, if the eject button is pushed while the
119 * drive light is flashing, the drive will return a bad
120 * status and be reset. It recovers, though.
121 *
122 * 03/07/97 - Fixed a problem with timers.
123 *
124 *
125 * 18 Spetember 1997 -- Ported to Uniform CD-ROM driver by
126 * Heiko Eissfeldt <heiko@colossus.escape.de> with additional
127 * changes by Erik Andersen <andersee@debian.org>
128 *
129 * 24 January 1998 -- Removed the scd_disc_status() function, which was now
130 * just dead code left over from the port.
131 * Erik Andersen <andersee@debian.org>
132 *
133 * 16 July 1998 -- Drive donated to Erik Andersen by John Kodis
134 * <kodis@jagunet.com>. Work begun on fixing driver to
135 * work under 2.1.X. Added temporary extra printks
136 * which seem to slow it down enough to work.
137 *
138 * 9 November 1999 -- Make kernel-parameter implementation work with 2.3.x
139 * Removed init_module & cleanup_module in favor of
140 * module_init & module_exit.
141 * Torben Mathiasen <tmm@image.dk>
142 *
143 * 22 October 2004 -- Make the driver work in 2.6.X
144 * Added workaround to fix hard lockups on eject
145 * Fixed door locking problem after mounting empty drive
146 * Set double-speed drives to double speed by default
147 * Removed all readahead things - not needed anymore
148 * Ondrej Zary <rainbow@rainbow-software.org>
149*/
150
151#define DEBUG 1
152
153#include <linux/major.h>
154#include <linux/module.h>
155#include <linux/errno.h>
156#include <linux/signal.h>
157#include <linux/sched.h>
158#include <linux/timer.h>
159#include <linux/fs.h>
160#include <linux/kernel.h>
161#include <linux/hdreg.h>
162#include <linux/genhd.h>
163#include <linux/ioport.h>
164#include <linux/string.h>
165#include <linux/slab.h>
166#include <linux/init.h>
167#include <linux/interrupt.h>
168#include <linux/cdrom.h>
169
170#include <asm/system.h>
171#include <asm/io.h>
172#include <asm/uaccess.h>
173#include <asm/dma.h>
174
175#include "cdu31a.h"
176
177#define MAJOR_NR CDU31A_CDROM_MAJOR
178#include <linux/blkdev.h>
179
180#define CDU31A_MAX_CONSECUTIVE_ATTENTIONS 10
181
182#define PFX "CDU31A: "
183
184/*
185** Edit the following data to change interrupts, DMA channels, etc.
186** Default is polled and no DMA. DMA is not recommended for double-speed
187** drives.
188*/
189static struct {
190 unsigned short base; /* I/O Base Address */
191 short int_num; /* Interrupt Number (-1 means scan for it,
192 0 means don't use) */
193} cdu31a_addresses[] __initdata = {
194 {0}
195};
196
197static int handle_sony_cd_attention(void);
198static int read_subcode(void);
199static void sony_get_toc(void);
200static int scd_spinup(void);
201/*static int scd_open(struct inode *inode, struct file *filp);*/
202static int scd_open(struct cdrom_device_info *, int);
203static void do_sony_cd_cmd(unsigned char cmd,
204 unsigned char *params,
205 unsigned int num_params,
206 unsigned char *result_buffer,
207 unsigned int *result_size);
208static void size_to_buf(unsigned int size, unsigned char *buf);
209
210/* Parameters for the read-ahead. */
211static unsigned int sony_next_block; /* Next 512 byte block offset */
212static unsigned int sony_blocks_left = 0; /* Number of 512 byte blocks left
213 in the current read command. */
214
215
216/* The base I/O address of the Sony Interface. This is a variable (not a
217 #define) so it can be easily changed via some future ioctl() */
218static unsigned int cdu31a_port = 0;
219module_param(cdu31a_port, uint, 0);
220
221/*
222 * The following are I/O addresses of the various registers for the drive. The
223 * comment for the base address also applies here.
224 */
225static volatile unsigned short sony_cd_cmd_reg;
226static volatile unsigned short sony_cd_param_reg;
227static volatile unsigned short sony_cd_write_reg;
228static volatile unsigned short sony_cd_control_reg;
229static volatile unsigned short sony_cd_status_reg;
230static volatile unsigned short sony_cd_result_reg;
231static volatile unsigned short sony_cd_read_reg;
232static volatile unsigned short sony_cd_fifost_reg;
233
234static struct request_queue *cdu31a_queue;
235static DEFINE_SPINLOCK(cdu31a_lock); /* queue lock */
236
237static int sony_spun_up = 0; /* Has the drive been spun up? */
238
239static int sony_speed = 0; /* Last wanted speed */
240
241static int sony_xa_mode = 0; /* Is an XA disk in the drive
242 and the drive a CDU31A? */
243
244static int sony_raw_data_mode = 1; /* 1 if data tracks, 0 if audio.
245 For raw data reads. */
246
247static unsigned int sony_usage = 0; /* How many processes have the
248 drive open. */
249
250static int sony_pas_init = 0; /* Initialize the Pro-Audio
251 Spectrum card? */
252
253static struct s_sony_session_toc single_toc; /* Holds the
254 table of
255 contents. */
256
257static struct s_all_sessions_toc sony_toc; /* entries gathered from all
258 sessions */
259
260static int sony_toc_read = 0; /* Has the TOC been read for
261 the drive? */
262
263static struct s_sony_subcode last_sony_subcode; /* Points to the last
264 subcode address read */
265
266static DECLARE_MUTEX(sony_sem); /* Semaphore for drive hardware access */
267
268static int is_double_speed = 0; /* does the drive support double speed ? */
269
270static int is_auto_eject = 1; /* Door has been locked? 1=No/0=Yes */
271
272/*
273 * The audio status uses the values from read subchannel data as specified
274 * in include/linux/cdrom.h.
275 */
276static volatile int sony_audio_status = CDROM_AUDIO_NO_STATUS;
277
278/*
279 * The following are a hack for pausing and resuming audio play. The drive
280 * does not work as I would expect it, if you stop it then start it again,
281 * the drive seeks back to the beginning and starts over. This holds the
282 * position during a pause so a resume can restart it. It uses the
283 * audio status variable above to tell if it is paused.
284 */
285static unsigned volatile char cur_pos_msf[3] = { 0, 0, 0 };
286static unsigned volatile char final_pos_msf[3] = { 0, 0, 0 };
287
288/* What IRQ is the drive using? 0 if none. */
289static int cdu31a_irq = 0;
290module_param(cdu31a_irq, int, 0);
291
292/* The interrupt handler will wake this queue up when it gets an
293 interrupts. */
294static DECLARE_WAIT_QUEUE_HEAD(cdu31a_irq_wait);
295static int irq_flag = 0;
296
297static int curr_control_reg = 0; /* Current value of the control register */
298
299/* A disk changed variable. When a disk change is detected, it will
300 all be set to TRUE. As the upper layers ask for disk_changed status
301 it will be cleared. */
302static char disk_changed;
303
304/* This was readahead_buffer once... Now it's used only for audio reads */
305static char audio_buffer[CD_FRAMESIZE_RAW];
306
307/* Used to time a short period to abort an operation after the
308 drive has been idle for a while. This keeps the light on
309 the drive from flashing for very long. */
310static struct timer_list cdu31a_abort_timer;
311
312/* Marks if the timeout has started an abort read. This is used
313 on entry to the drive to tell the code to read out the status
314 from the abort read. */
315static int abort_read_started = 0;
316
317/*
318 * Uniform cdrom interface function
319 * report back, if disc has changed from time of last request.
320 */
321static int scd_media_changed(struct cdrom_device_info *cdi, int disc_nr)
322{
323 int retval;
324
325 retval = disk_changed;
326 disk_changed = 0;
327
328 return retval;
329}
330
331/*
332 * Uniform cdrom interface function
333 * report back, if drive is ready
334 */
335static int scd_drive_status(struct cdrom_device_info *cdi, int slot_nr)
336{
337 if (CDSL_CURRENT != slot_nr)
338 /* we have no changer support */
339 return -EINVAL;
340 if (sony_spun_up)
341 return CDS_DISC_OK;
342 if (down_interruptible(&sony_sem))
343 return -ERESTARTSYS;
344 if (scd_spinup() == 0)
345 sony_spun_up = 1;
346 up(&sony_sem);
347 return sony_spun_up ? CDS_DISC_OK : CDS_DRIVE_NOT_READY;
348}
349
350static inline void enable_interrupts(void)
351{
352 curr_control_reg |= (SONY_ATTN_INT_EN_BIT
353 | SONY_RES_RDY_INT_EN_BIT
354 | SONY_DATA_RDY_INT_EN_BIT);
355 outb(curr_control_reg, sony_cd_control_reg);
356}
357
358static inline void disable_interrupts(void)
359{
360 curr_control_reg &= ~(SONY_ATTN_INT_EN_BIT
361 | SONY_RES_RDY_INT_EN_BIT
362 | SONY_DATA_RDY_INT_EN_BIT);
363 outb(curr_control_reg, sony_cd_control_reg);
364}
365
366/*
367 * Wait a little while (used for polling the drive). If in initialization,
368 * setting a timeout doesn't work, so just loop for a while.
369 */
370static inline void sony_sleep(void)
371{
372 if (cdu31a_irq <= 0) {
373 yield();
374 } else { /* Interrupt driven */
375 DEFINE_WAIT(w);
376 int first = 1;
377
378 while (1) {
379 prepare_to_wait(&cdu31a_irq_wait, &w,
380 TASK_INTERRUPTIBLE);
381 if (first) {
382 enable_interrupts();
383 first = 0;
384 }
385
386 if (irq_flag != 0)
387 break;
388 if (!signal_pending(current)) {
389 schedule();
390 continue;
391 } else
392 disable_interrupts();
393 break;
394 }
395 finish_wait(&cdu31a_irq_wait, &w);
396 irq_flag = 0;
397 }
398}
399
400
401/*
402 * The following are convenience routine to read various status and set
403 * various conditions in the drive.
404 */
405static inline int is_attention(void)
406{
407 return (inb(sony_cd_status_reg) & SONY_ATTN_BIT) != 0;
408}
409
410static inline int is_busy(void)
411{
412 return (inb(sony_cd_status_reg) & SONY_BUSY_BIT) != 0;
413}
414
415static inline int is_data_ready(void)
416{
417 return (inb(sony_cd_status_reg) & SONY_DATA_RDY_BIT) != 0;
418}
419
420static inline int is_data_requested(void)
421{
422 return (inb(sony_cd_status_reg) & SONY_DATA_REQUEST_BIT) != 0;
423}
424
425static inline int is_result_ready(void)
426{
427 return (inb(sony_cd_status_reg) & SONY_RES_RDY_BIT) != 0;
428}
429
430static inline int is_param_write_rdy(void)
431{
432 return (inb(sony_cd_fifost_reg) & SONY_PARAM_WRITE_RDY_BIT) != 0;
433}
434
435static inline int is_result_reg_not_empty(void)
436{
437 return (inb(sony_cd_fifost_reg) & SONY_RES_REG_NOT_EMP_BIT) != 0;
438}
439
440static inline void reset_drive(void)
441{
442 curr_control_reg = 0;
443 sony_toc_read = 0;
444 outb(SONY_DRIVE_RESET_BIT, sony_cd_control_reg);
445}
446
447/*
448 * Uniform cdrom interface function
449 * reset drive and return when it is ready
450 */
451static int scd_reset(struct cdrom_device_info *cdi)
452{
453 unsigned long retry_count;
454
455 if (down_interruptible(&sony_sem))
456 return -ERESTARTSYS;
457 reset_drive();
458
459 retry_count = jiffies + SONY_RESET_TIMEOUT;
460 while (time_before(jiffies, retry_count) && (!is_attention())) {
461 sony_sleep();
462 }
463
464 up(&sony_sem);
465 return 0;
466}
467
468static inline void clear_attention(void)
469{
470 outb(curr_control_reg | SONY_ATTN_CLR_BIT, sony_cd_control_reg);
471}
472
473static inline void clear_result_ready(void)
474{
475 outb(curr_control_reg | SONY_RES_RDY_CLR_BIT, sony_cd_control_reg);
476}
477
478static inline void clear_data_ready(void)
479{
480 outb(curr_control_reg | SONY_DATA_RDY_CLR_BIT,
481 sony_cd_control_reg);
482}
483
484static inline void clear_param_reg(void)
485{
486 outb(curr_control_reg | SONY_PARAM_CLR_BIT, sony_cd_control_reg);
487}
488
489static inline unsigned char read_status_register(void)
490{
491 return inb(sony_cd_status_reg);
492}
493
494static inline unsigned char read_result_register(void)
495{
496 return inb(sony_cd_result_reg);
497}
498
499static inline unsigned char read_data_register(void)
500{
501 return inb(sony_cd_read_reg);
502}
503
504static inline void write_param(unsigned char param)
505{
506 outb(param, sony_cd_param_reg);
507}
508
509static inline void write_cmd(unsigned char cmd)
510{
511 outb(curr_control_reg | SONY_RES_RDY_INT_EN_BIT,
512 sony_cd_control_reg);
513 outb(cmd, sony_cd_cmd_reg);
514}
515
516static irqreturn_t cdu31a_interrupt(int irq, void *dev_id)
517{
518 unsigned char val;
519
520 if (abort_read_started) {
521 /* We might be waiting for an abort to finish. Don't
522 disable interrupts yet, though, because we handle
523 this one here. */
524 /* Clear out the result registers. */
525 while (is_result_reg_not_empty()) {
526 val = read_result_register();
527 }
528 clear_data_ready();
529 clear_result_ready();
530
531 /* Clear out the data */
532 while (is_data_requested()) {
533 val = read_data_register();
534 }
535 abort_read_started = 0;
536
537 /* If something was waiting, wake it up now. */
538 if (waitqueue_active(&cdu31a_irq_wait)) {
539 disable_interrupts();
540 irq_flag = 1;
541 wake_up_interruptible(&cdu31a_irq_wait);
542 }
543 } else if (waitqueue_active(&cdu31a_irq_wait)) {
544 disable_interrupts();
545 irq_flag = 1;
546 wake_up_interruptible(&cdu31a_irq_wait);
547 } else {
548 disable_interrupts();
549 printk(KERN_NOTICE PFX
550 "Got an interrupt but nothing was waiting\n");
551 }
552 return IRQ_HANDLED;
553}
554
555/*
556 * give more verbose error messages
557 */
558static unsigned char *translate_error(unsigned char err_code)
559{
560 static unsigned char errbuf[80];
561
562 switch (err_code) {
563 case 0x10: return "illegal command ";
564 case 0x11: return "illegal parameter ";
565
566 case 0x20: return "not loaded ";
567 case 0x21: return "no disc ";
568 case 0x22: return "not spinning ";
569 case 0x23: return "spinning ";
570 case 0x25: return "spindle servo ";
571 case 0x26: return "focus servo ";
572 case 0x29: return "eject mechanism ";
573 case 0x2a: return "audio playing ";
574 case 0x2c: return "emergency eject ";
575
576 case 0x30: return "focus ";
577 case 0x31: return "frame sync ";
578 case 0x32: return "subcode address ";
579 case 0x33: return "block sync ";
580 case 0x34: return "header address ";
581
582 case 0x40: return "illegal track read ";
583 case 0x41: return "mode 0 read ";
584 case 0x42: return "illegal mode read ";
585 case 0x43: return "illegal block size read ";
586 case 0x44: return "mode read ";
587 case 0x45: return "form read ";
588 case 0x46: return "leadout read ";
589 case 0x47: return "buffer overrun ";
590
591 case 0x53: return "unrecoverable CIRC ";
592 case 0x57: return "unrecoverable LECC ";
593
594 case 0x60: return "no TOC ";
595 case 0x61: return "invalid subcode data ";
596 case 0x63: return "focus on TOC read ";
597 case 0x64: return "frame sync on TOC read ";
598 case 0x65: return "TOC data ";
599
600 case 0x70: return "hardware failure ";
601 case 0x91: return "leadin ";
602 case 0x92: return "leadout ";
603 case 0x93: return "data track ";
604 }
605 sprintf(errbuf, "unknown 0x%02x ", err_code);
606 return errbuf;
607}
608
609/*
610 * Set the drive parameters so the drive will auto-spin-up when a
611 * disk is inserted.
612 */
613static void set_drive_params(int want_doublespeed)
614{
615 unsigned char res_reg[12];
616 unsigned int res_size;
617 unsigned char params[3];
618
619
620 params[0] = SONY_SD_AUTO_SPIN_DOWN_TIME;
621 params[1] = 0x00; /* Never spin down the drive. */
622 do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
623 params, 2, res_reg, &res_size);
624 if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20)) {
625 printk(KERN_NOTICE PFX
626 "Unable to set spin-down time: 0x%2.2x\n", res_reg[1]);
627 }
628
629 params[0] = SONY_SD_MECH_CONTROL;
630 params[1] = SONY_AUTO_SPIN_UP_BIT; /* Set auto spin up */
631
632 if (is_auto_eject)
633 params[1] |= SONY_AUTO_EJECT_BIT;
634
635 if (is_double_speed && want_doublespeed) {
636 params[1] |= SONY_DOUBLE_SPEED_BIT; /* Set the drive to double speed if
637 possible */
638 }
639 do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
640 params, 2, res_reg, &res_size);
641 if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20)) {
642 printk(KERN_NOTICE PFX "Unable to set mechanical "
643 "parameters: 0x%2.2x\n", res_reg[1]);
644 }
645}
646
647/*
648 * Uniform cdrom interface function
649 * select reading speed for data access
650 */
651static int scd_select_speed(struct cdrom_device_info *cdi, int speed)
652{
653 if (speed == 0)
654 sony_speed = 1;
655 else
656 sony_speed = speed - 1;
657
658 if (down_interruptible(&sony_sem))
659 return -ERESTARTSYS;
660 set_drive_params(sony_speed);
661 up(&sony_sem);
662 return 0;
663}
664
665/*
666 * Uniform cdrom interface function
667 * lock or unlock eject button
668 */
669static int scd_lock_door(struct cdrom_device_info *cdi, int lock)
670{
671 if (lock == 0) {
672 is_auto_eject = 1;
673 } else {
674 is_auto_eject = 0;
675 }
676 if (down_interruptible(&sony_sem))
677 return -ERESTARTSYS;
678 set_drive_params(sony_speed);
679 up(&sony_sem);
680 return 0;
681}
682
683/*
684 * This code will reset the drive and attempt to restore sane parameters.
685 */
686static void restart_on_error(void)
687{
688 unsigned char res_reg[12];
689 unsigned int res_size;
690 unsigned long retry_count;
691
692
693 printk(KERN_NOTICE PFX "Resetting drive on error\n");
694 reset_drive();
695 retry_count = jiffies + SONY_RESET_TIMEOUT;
696 while (time_before(jiffies, retry_count) && (!is_attention())) {
697 sony_sleep();
698 }
699 set_drive_params(sony_speed);
700 do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg, &res_size);
701 if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20)) {
702 printk(KERN_NOTICE PFX "Unable to spin up drive: 0x%2.2x\n",
703 res_reg[1]);
704 }
705
706 msleep(2000);
707
708 sony_get_toc();
709}
710
711/*
712 * This routine writes data to the parameter register. Since this should
713 * happen fairly fast, it is polled with no OS waits between.
714 */
715static int write_params(unsigned char *params, int num_params)
716{
717 unsigned int retry_count;
718
719
720 retry_count = SONY_READY_RETRIES;
721 while ((retry_count > 0) && (!is_param_write_rdy())) {
722 retry_count--;
723 }
724 if (!is_param_write_rdy()) {
725 return -EIO;
726 }
727
728 while (num_params > 0) {
729 write_param(*params);
730 params++;
731 num_params--;
732 }
733
734 return 0;
735}
736
737
738/*
739 * The following reads data from the command result register. It is a
740 * fairly complex routine, all status info flows back through this
741 * interface. The algorithm is stolen directly from the flowcharts in
742 * the drive manual.
743 */
744static void
745get_result(unsigned char *result_buffer, unsigned int *result_size)
746{
747 unsigned char a, b;
748 int i;
749 unsigned long retry_count;
750
751
752 while (handle_sony_cd_attention());
753 /* Wait for the result data to be ready */
754 retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
755 while (time_before(jiffies, retry_count)
756 && (is_busy() || (!(is_result_ready())))) {
757 sony_sleep();
758
759 while (handle_sony_cd_attention());
760 }
761 if (is_busy() || (!(is_result_ready()))) {
762 pr_debug(PFX "timeout out %d\n", __LINE__);
763 result_buffer[0] = 0x20;
764 result_buffer[1] = SONY_TIMEOUT_OP_ERR;
765 *result_size = 2;
766 return;
767 }
768
769 /*
770 * Get the first two bytes. This determines what else needs
771 * to be done.
772 */
773 clear_result_ready();
774 a = read_result_register();
775 *result_buffer = a;
776 result_buffer++;
777
778 /* Check for block error status result. */
779 if ((a & 0xf0) == 0x50) {
780 *result_size = 1;
781 return;
782 }
783
784 b = read_result_register();
785 *result_buffer = b;
786 result_buffer++;
787 *result_size = 2;
788
789 /*
790 * 0x20 means an error occurred. Byte 2 will have the error code.
791 * Otherwise, the command succeeded, byte 2 will have the count of
792 * how many more status bytes are coming.
793 *
794 * The result register can be read 10 bytes at a time, a wait for
795 * result ready to be asserted must be done between every 10 bytes.
796 */
797 if ((a & 0xf0) != 0x20) {
798 if (b > 8) {
799 for (i = 0; i < 8; i++) {
800 *result_buffer = read_result_register();
801 result_buffer++;
802 (*result_size)++;
803 }
804 b = b - 8;
805
806 while (b > 10) {
807 retry_count = SONY_READY_RETRIES;
808 while ((retry_count > 0)
809 && (!is_result_ready())) {
810 retry_count--;
811 }
812 if (!is_result_ready()) {
813 pr_debug(PFX "timeout out %d\n",
814 __LINE__);
815 result_buffer[0] = 0x20;
816 result_buffer[1] =
817 SONY_TIMEOUT_OP_ERR;
818 *result_size = 2;
819 return;
820 }
821
822 clear_result_ready();
823
824 for (i = 0; i < 10; i++) {
825 *result_buffer =
826 read_result_register();
827 result_buffer++;
828 (*result_size)++;
829 }
830 b = b - 10;
831 }
832
833 if (b > 0) {
834 retry_count = SONY_READY_RETRIES;
835 while ((retry_count > 0)
836 && (!is_result_ready())) {
837 retry_count--;
838 }
839 if (!is_result_ready()) {
840 pr_debug(PFX "timeout out %d\n",
841 __LINE__);
842 result_buffer[0] = 0x20;
843 result_buffer[1] =
844 SONY_TIMEOUT_OP_ERR;
845 *result_size = 2;
846 return;
847 }
848 }
849 }
850
851 while (b > 0) {
852 *result_buffer = read_result_register();
853 result_buffer++;
854 (*result_size)++;
855 b--;
856 }
857 }
858}
859
860/*
861 * Do a command that does not involve data transfer. This routine must
862 * be re-entrant from the same task to support being called from the
863 * data operation code when an error occurs.
864 */
865static void
866do_sony_cd_cmd(unsigned char cmd,
867 unsigned char *params,
868 unsigned int num_params,
869 unsigned char *result_buffer, unsigned int *result_size)
870{
871 unsigned long retry_count;
872 int num_retries = 0;
873
874retry_cd_operation:
875
876 while (handle_sony_cd_attention());
877
878 retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
879 while (time_before(jiffies, retry_count) && (is_busy())) {
880 sony_sleep();
881
882 while (handle_sony_cd_attention());
883 }
884 if (is_busy()) {
885 pr_debug(PFX "timeout out %d\n", __LINE__);
886 result_buffer[0] = 0x20;
887 result_buffer[1] = SONY_TIMEOUT_OP_ERR;
888 *result_size = 2;
889 } else {
890 clear_result_ready();
891 clear_param_reg();
892
893 write_params(params, num_params);
894 write_cmd(cmd);
895
896 get_result(result_buffer, result_size);
897 }
898
899 if (((result_buffer[0] & 0xf0) == 0x20)
900 && (num_retries < MAX_CDU31A_RETRIES)) {
901 num_retries++;
902 msleep(100);
903 goto retry_cd_operation;
904 }
905}
906
907
908/*
909 * Handle an attention from the drive. This will return 1 if it found one
910 * or 0 if not (if one is found, the caller might want to call again).
911 *
912 * This routine counts the number of consecutive times it is called
913 * (since this is always called from a while loop until it returns
914 * a 0), and returns a 0 if it happens too many times. This will help
915 * prevent a lockup.
916 */
917static int handle_sony_cd_attention(void)
918{
919 unsigned char atten_code;
920 static int num_consecutive_attentions = 0;
921 volatile int val;
922
923
924#if 0
925 pr_debug(PFX "Entering %s\n", __FUNCTION__);
926#endif
927 if (is_attention()) {
928 if (num_consecutive_attentions >
929 CDU31A_MAX_CONSECUTIVE_ATTENTIONS) {
930 printk(KERN_NOTICE PFX "Too many consecutive "
931 "attentions: %d\n", num_consecutive_attentions);
932 num_consecutive_attentions = 0;
933 pr_debug(PFX "Leaving %s at %d\n", __FUNCTION__,
934 __LINE__);
935 return 0;
936 }
937
938 clear_attention();
939 atten_code = read_result_register();
940
941 switch (atten_code) {
942 /* Someone changed the CD. Mark it as changed */
943 case SONY_MECH_LOADED_ATTN:
944 disk_changed = 1;
945 sony_toc_read = 0;
946 sony_audio_status = CDROM_AUDIO_NO_STATUS;
947 sony_blocks_left = 0;
948 break;
949
950 case SONY_SPIN_DOWN_COMPLETE_ATTN:
951 /* Mark the disk as spun down. */
952 sony_spun_up = 0;
953 break;
954
955 case SONY_AUDIO_PLAY_DONE_ATTN:
956 sony_audio_status = CDROM_AUDIO_COMPLETED;
957 read_subcode();
958 break;
959
960 case SONY_EJECT_PUSHED_ATTN:
961 if (is_auto_eject) {
962 sony_audio_status = CDROM_AUDIO_INVALID;
963 }
964 break;
965
966 case SONY_LEAD_IN_ERR_ATTN:
967 case SONY_LEAD_OUT_ERR_ATTN:
968 case SONY_DATA_TRACK_ERR_ATTN:
969 case SONY_AUDIO_PLAYBACK_ERR_ATTN:
970 sony_audio_status = CDROM_AUDIO_ERROR;
971 break;
972 }
973
974 num_consecutive_attentions++;
975 pr_debug(PFX "Leaving %s at %d\n", __FUNCTION__, __LINE__);
976 return 1;
977 } else if (abort_read_started) {
978 while (is_result_reg_not_empty()) {
979 val = read_result_register();
980 }
981 clear_data_ready();
982 clear_result_ready();
983 /* Clear out the data */
984 while (is_data_requested()) {
985 val = read_data_register();
986 }
987 abort_read_started = 0;
988 pr_debug(PFX "Leaving %s at %d\n", __FUNCTION__, __LINE__);
989 return 1;
990 }
991
992 num_consecutive_attentions = 0;
993#if 0
994 pr_debug(PFX "Leaving %s at %d\n", __FUNCTION__, __LINE__);
995#endif
996 return 0;
997}
998
999
1000/* Convert from an integer 0-99 to BCD */
1001static inline unsigned int int_to_bcd(unsigned int val)
1002{
1003 int retval;
1004
1005
1006 retval = (val / 10) << 4;
1007 retval = retval | val % 10;
1008 return retval;
1009}
1010
1011
1012/* Convert from BCD to an integer from 0-99 */
1013static unsigned int bcd_to_int(unsigned int bcd)
1014{
1015 return (((bcd >> 4) & 0x0f) * 10) + (bcd & 0x0f);
1016}
1017
1018
1019/*
1020 * Convert a logical sector value (like the OS would want to use for
1021 * a block device) to an MSF format.
1022 */
1023static void log_to_msf(unsigned int log, unsigned char *msf)
1024{
1025 log = log + LOG_START_OFFSET;
1026 msf[0] = int_to_bcd(log / 4500);
1027 log = log % 4500;
1028 msf[1] = int_to_bcd(log / 75);
1029 msf[2] = int_to_bcd(log % 75);
1030}
1031
1032
1033/*
1034 * Convert an MSF format to a logical sector.
1035 */
1036static unsigned int msf_to_log(unsigned char *msf)
1037{
1038 unsigned int log;
1039
1040
1041 log = msf[2];
1042 log += msf[1] * 75;
1043 log += msf[0] * 4500;
1044 log = log - LOG_START_OFFSET;
1045
1046 return log;
1047}
1048
1049
1050/*
1051 * Take in integer size value and put it into a buffer like
1052 * the drive would want to see a number-of-sector value.
1053 */
1054static void size_to_buf(unsigned int size, unsigned char *buf)
1055{
1056 buf[0] = size / 65536;
1057 size = size % 65536;
1058 buf[1] = size / 256;
1059 buf[2] = size % 256;
1060}
1061
1062/* Starts a read operation. Returns 0 on success and 1 on failure.
1063 The read operation used here allows multiple sequential sectors
1064 to be read and status returned for each sector. The driver will
1065 read the output one at a time as the requests come and abort the
1066 operation if the requested sector is not the next one from the
1067 drive. */
1068static int
1069start_request(unsigned int sector, unsigned int nsect)
1070{
1071 unsigned char params[6];
1072 unsigned long retry_count;
1073
1074
1075 pr_debug(PFX "Entering %s\n", __FUNCTION__);
1076 log_to_msf(sector, params);
1077 size_to_buf(nsect, &params[3]);
1078
1079 /*
1080 * Clear any outstanding attentions and wait for the drive to
1081 * complete any pending operations.
1082 */
1083 while (handle_sony_cd_attention());
1084
1085 retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
1086 while (time_before(jiffies, retry_count) && (is_busy())) {
1087 sony_sleep();
1088
1089 while (handle_sony_cd_attention());
1090 }
1091
1092 if (is_busy()) {
1093 printk(KERN_NOTICE PFX "Timeout while waiting "
1094 "to issue command\n");
1095 pr_debug(PFX "Leaving %s at %d\n", __FUNCTION__, __LINE__);
1096 return 1;
1097 } else {
1098 /* Issue the command */
1099 clear_result_ready();
1100 clear_param_reg();
1101
1102 write_params(params, 6);
1103 write_cmd(SONY_READ_BLKERR_STAT_CMD);
1104
1105 sony_blocks_left = nsect * 4;
1106 sony_next_block = sector * 4;
1107 pr_debug(PFX "Leaving %s at %d\n", __FUNCTION__, __LINE__);
1108 return 0;
1109 }
1110 pr_debug(PFX "Leaving %s at %d\n", __FUNCTION__, __LINE__);
1111}
1112
1113/* Abort a pending read operation. Clear all the drive status variables. */
1114static void abort_read(void)
1115{
1116 unsigned char result_reg[2];
1117 int result_size;
1118 volatile int val;
1119
1120
1121 do_sony_cd_cmd(SONY_ABORT_CMD, NULL, 0, result_reg, &result_size);
1122 if ((result_reg[0] & 0xf0) == 0x20) {
1123 printk(KERN_ERR PFX "Aborting read, %s error\n",
1124 translate_error(result_reg[1]));
1125 }
1126
1127 while (is_result_reg_not_empty()) {
1128 val = read_result_register();
1129 }
1130 clear_data_ready();
1131 clear_result_ready();
1132 /* Clear out the data */
1133 while (is_data_requested()) {
1134 val = read_data_register();
1135 }
1136
1137 sony_blocks_left = 0;
1138}
1139
1140/* Called when the timer times out. This will abort the
1141 pending read operation. */
1142static void handle_abort_timeout(unsigned long data)
1143{
1144 pr_debug(PFX "Entering %s\n", __FUNCTION__);
1145 /* If it is in use, ignore it. */
1146 if (down_trylock(&sony_sem) == 0) {
1147 /* We can't use abort_read(), because it will sleep
1148 or schedule in the timer interrupt. Just start
1149 the operation, finish it on the next access to
1150 the drive. */
1151 clear_result_ready();
1152 clear_param_reg();
1153 write_cmd(SONY_ABORT_CMD);
1154
1155 sony_blocks_left = 0;
1156 abort_read_started = 1;
1157 up(&sony_sem);
1158 }
1159 pr_debug(PFX "Leaving %s\n", __FUNCTION__);
1160}
1161
1162/* Actually get one sector of data from the drive. */
1163static void
1164input_data_sector(char *buffer)
1165{
1166 pr_debug(PFX "Entering %s\n", __FUNCTION__);
1167
1168 /* If an XA disk on a CDU31A, skip the first 12 bytes of data from
1169 the disk. The real data is after that. We can use audio_buffer. */
1170 if (sony_xa_mode)
1171 insb(sony_cd_read_reg, audio_buffer, CD_XA_HEAD);
1172
1173 clear_data_ready();
1174
1175 insb(sony_cd_read_reg, buffer, 2048);
1176
1177 /* If an XA disk, we have to clear out the rest of the unused
1178 error correction data. We can use audio_buffer for that. */
1179 if (sony_xa_mode)
1180 insb(sony_cd_read_reg, audio_buffer, CD_XA_TAIL);
1181
1182 pr_debug(PFX "Leaving %s\n", __FUNCTION__);
1183}
1184
1185/* read data from the drive. Note the nsect must be <= 4. */
1186static void
1187read_data_block(char *buffer,
1188 unsigned int block,
1189 unsigned int nblocks,
1190 unsigned char res_reg[], int *res_size)
1191{
1192 unsigned long retry_count;
1193
1194 pr_debug(PFX "Entering %s\n", __FUNCTION__);
1195
1196 res_reg[0] = 0;
1197 res_reg[1] = 0;
1198 *res_size = 0;
1199
1200 /* Wait for the drive to tell us we have something */
1201 retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
1202 while (time_before(jiffies, retry_count) && !(is_data_ready())) {
1203 while (handle_sony_cd_attention());
1204
1205 sony_sleep();
1206 }
1207 if (!(is_data_ready())) {
1208 if (is_result_ready()) {
1209 get_result(res_reg, res_size);
1210 if ((res_reg[0] & 0xf0) != 0x20) {
1211 printk(KERN_NOTICE PFX "Got result that should"
1212 " have been error: %d\n", res_reg[0]);
1213 res_reg[0] = 0x20;
1214 res_reg[1] = SONY_BAD_DATA_ERR;
1215 *res_size = 2;
1216 }
1217 abort_read();
1218 } else {
1219 pr_debug(PFX "timeout out %d\n", __LINE__);
1220 res_reg[0] = 0x20;
1221 res_reg[1] = SONY_TIMEOUT_OP_ERR;
1222 *res_size = 2;
1223 abort_read();
1224 }
1225 } else {
1226 input_data_sector(buffer);
1227 sony_blocks_left -= nblocks;
1228 sony_next_block += nblocks;
1229
1230 /* Wait for the status from the drive. */
1231 retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
1232 while (time_before(jiffies, retry_count)
1233 && !(is_result_ready())) {
1234 while (handle_sony_cd_attention());
1235
1236 sony_sleep();
1237 }
1238
1239 if (!is_result_ready()) {
1240 pr_debug(PFX "timeout out %d\n", __LINE__);
1241 res_reg[0] = 0x20;
1242 res_reg[1] = SONY_TIMEOUT_OP_ERR;
1243 *res_size = 2;
1244 abort_read();
1245 } else {
1246 get_result(res_reg, res_size);
1247
1248 /* If we got a buffer status, handle that. */
1249 if ((res_reg[0] & 0xf0) == 0x50) {
1250
1251 if ((res_reg[0] ==
1252 SONY_NO_CIRC_ERR_BLK_STAT)
1253 || (res_reg[0] ==
1254 SONY_NO_LECC_ERR_BLK_STAT)
1255 || (res_reg[0] ==
1256 SONY_RECOV_LECC_ERR_BLK_STAT)) {
1257 /* nothing here */
1258 } else {
1259 printk(KERN_ERR PFX "Data block "
1260 "error: 0x%x\n", res_reg[0]);
1261 res_reg[0] = 0x20;
1262 res_reg[1] = SONY_BAD_DATA_ERR;
1263 *res_size = 2;
1264 }
1265
1266 /* Final transfer is done for read command, get final result. */
1267 if (sony_blocks_left == 0) {
1268 get_result(res_reg, res_size);
1269 }
1270 } else if ((res_reg[0] & 0xf0) != 0x20) {
1271 /* The drive gave me bad status, I don't know what to do.
1272 Reset the driver and return an error. */
1273 printk(KERN_ERR PFX "Invalid block "
1274 "status: 0x%x\n", res_reg[0]);
1275 restart_on_error();
1276 res_reg[0] = 0x20;
1277 res_reg[1] = SONY_BAD_DATA_ERR;
1278 *res_size = 2;
1279 }
1280 }
1281 }
1282 pr_debug(PFX "Leaving %s at %d\n", __FUNCTION__, __LINE__);
1283}
1284
1285
1286/*
1287 * The OS calls this to perform a read or write operation to the drive.
1288 * Write obviously fail. Reads to a read ahead of sony_buffer_size
1289 * bytes to help speed operations. This especially helps since the OS
1290 * uses 1024 byte blocks and the drive uses 2048 byte blocks. Since most
1291 * data access on a CD is done sequentially, this saves a lot of operations.
1292 */
1293static void do_cdu31a_request(request_queue_t * q)
1294{
1295 struct request *req;
1296 int block, nblock, num_retries;
1297 unsigned char res_reg[12];
1298 unsigned int res_size;
1299
1300 pr_debug(PFX "Entering %s\n", __FUNCTION__);
1301
1302 spin_unlock_irq(q->queue_lock);
1303 if (down_interruptible(&sony_sem)) {
1304 spin_lock_irq(q->queue_lock);
1305 return;
1306 }
1307
1308 /* Get drive status before doing anything. */
1309 while (handle_sony_cd_attention());
1310
1311 /* Make sure we have a valid TOC. */
1312 sony_get_toc();
1313
1314
1315 /* Make sure the timer is cancelled. */
1316 del_timer(&cdu31a_abort_timer);
1317
1318 while (1) {
1319 /*
1320 * The beginning here is stolen from the hard disk driver. I hope
1321 * it's right.
1322 */
1323 req = elv_next_request(q);
1324 if (!req)
1325 goto end_do_cdu31a_request;
1326
1327 if (!sony_spun_up)
1328 scd_spinup();
1329
1330 block = req->sector;
1331 nblock = req->nr_sectors;
1332 pr_debug(PFX "request at block %d, length %d blocks\n",
1333 block, nblock);
1334 if (!sony_toc_read) {
1335 printk(KERN_NOTICE PFX "TOC not read\n");
1336 end_request(req, 0);
1337 continue;
1338 }
1339
1340 /* WTF??? */
1341 if (!blk_fs_request(req)) {
1342 end_request(req, 0);
1343 continue;
1344 }
1345 if (rq_data_dir(req) == WRITE) {
1346 end_request(req, 0);
1347 continue;
1348 }
1349
1350 /*
1351 * If the block address is invalid or the request goes beyond the end of
1352 * the media, return an error.
1353 */
1354 if (((block + nblock) / 4) >= sony_toc.lead_out_start_lba) {
1355 printk(KERN_NOTICE PFX "Request past end of media\n");
1356 end_request(req, 0);
1357 continue;
1358 }
1359
1360 if (nblock > 4)
1361 nblock = 4;
1362 num_retries = 0;
1363
1364 try_read_again:
1365 while (handle_sony_cd_attention());
1366
1367 if (!sony_toc_read) {
1368 printk(KERN_NOTICE PFX "TOC not read\n");
1369 end_request(req, 0);
1370 continue;
1371 }
1372
1373 /* If no data is left to be read from the drive, start the
1374 next request. */
1375 if (sony_blocks_left == 0) {
1376 if (start_request(block / 4, nblock / 4)) {
1377 end_request(req, 0);
1378 continue;
1379 }
1380 }
1381 /* If the requested block is not the next one waiting in
1382 the driver, abort the current operation and start a
1383 new one. */
1384 else if (block != sony_next_block) {
1385 pr_debug(PFX "Read for block %d, expected %d\n",
1386 block, sony_next_block);
1387 abort_read();
1388 if (!sony_toc_read) {
1389 printk(KERN_NOTICE PFX "TOC not read\n");
1390 end_request(req, 0);
1391 continue;
1392 }
1393 if (start_request(block / 4, nblock / 4)) {
1394 printk(KERN_NOTICE PFX "start request failed\n");
1395 end_request(req, 0);
1396 continue;
1397 }
1398 }
1399
1400 read_data_block(req->buffer, block, nblock, res_reg, &res_size);
1401
1402 if (res_reg[0] != 0x20) {
1403 if (!end_that_request_first(req, 1, nblock)) {
1404 spin_lock_irq(q->queue_lock);
1405 blkdev_dequeue_request(req);
1406 end_that_request_last(req, 1);
1407 spin_unlock_irq(q->queue_lock);
1408 }
1409 continue;
1410 }
1411
1412 if (num_retries > MAX_CDU31A_RETRIES) {
1413 end_request(req, 0);
1414 continue;
1415 }
1416
1417 num_retries++;
1418 if (res_reg[1] == SONY_NOT_SPIN_ERR) {
1419 do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg,
1420 &res_size);
1421 } else {
1422 printk(KERN_NOTICE PFX "%s error for block %d, nblock %d\n",
1423 translate_error(res_reg[1]), block, nblock);
1424 }
1425 goto try_read_again;
1426 }
1427 end_do_cdu31a_request:
1428#if 0
1429 /* After finished, cancel any pending operations. */
1430 abort_read();
1431#else
1432 /* Start a timer to time out after a while to disable
1433 the read. */
1434 cdu31a_abort_timer.expires = jiffies + 2 * HZ; /* Wait 2 seconds */
1435 add_timer(&cdu31a_abort_timer);
1436#endif
1437
1438 up(&sony_sem);
1439 spin_lock_irq(q->queue_lock);
1440 pr_debug(PFX "Leaving %s at %d\n", __FUNCTION__, __LINE__);
1441}
1442
1443
1444/*
1445 * Read the table of contents from the drive and set up TOC if
1446 * successful.
1447 */
1448static void sony_get_toc(void)
1449{
1450 unsigned char res_reg[2];
1451 unsigned int res_size;
1452 unsigned char parms[1];
1453 int session;
1454 int num_spin_ups;
1455 int totaltracks = 0;
1456 int mint = 99;
1457 int maxt = 0;
1458
1459 pr_debug(PFX "Entering %s\n", __FUNCTION__);
1460
1461 num_spin_ups = 0;
1462 if (!sony_toc_read) {
1463 respinup_on_gettoc:
1464 /* Ignore the result, since it might error if spinning already. */
1465 do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg,
1466 &res_size);
1467
1468 do_sony_cd_cmd(SONY_READ_TOC_CMD, NULL, 0, res_reg,
1469 &res_size);
1470
1471 /* The drive sometimes returns error 0. I don't know why, but ignore
1472 it. It seems to mean the drive has already done the operation. */
1473 if ((res_size < 2)
1474 || ((res_reg[0] != 0) && (res_reg[1] != 0))) {
1475 /* If the drive is already playing, it's ok. */
1476 if ((res_reg[1] == SONY_AUDIO_PLAYING_ERR)
1477 || (res_reg[1] == 0)) {
1478 goto gettoc_drive_spinning;
1479 }
1480
1481 /* If the drive says it is not spun up (even though we just did it!)
1482 then retry the operation at least a few times. */
1483 if ((res_reg[1] == SONY_NOT_SPIN_ERR)
1484 && (num_spin_ups < MAX_CDU31A_RETRIES)) {
1485 num_spin_ups++;
1486 goto respinup_on_gettoc;
1487 }
1488
1489 printk("cdu31a: Error reading TOC: %x %s\n",
1490 res_reg[0], translate_error(res_reg[1]));
1491 return;
1492 }
1493
1494 gettoc_drive_spinning:
1495
1496 /* The idea here is we keep asking for sessions until the command
1497 fails. Then we know what the last valid session on the disk is.
1498 No need to check session 0, since session 0 is the same as session
1499 1; the command returns different information if you give it 0.
1500 */
1501#if DEBUG
1502 memset(&sony_toc, 0x0e, sizeof(sony_toc));
1503 memset(&single_toc, 0x0f, sizeof(single_toc));
1504#endif
1505 session = 1;
1506 while (1) {
1507/* This seems to slow things down enough to make it work. This
1508 * appears to be a problem in do_sony_cd_cmd. This printk seems
1509 * to address the symptoms... -Erik */
1510 pr_debug(PFX "Trying session %d\n", session);
1511 parms[0] = session;
1512 do_sony_cd_cmd(SONY_READ_TOC_SPEC_CMD,
1513 parms, 1, res_reg, &res_size);
1514
1515 pr_debug(PFX "%2.2x %2.2x\n", res_reg[0], res_reg[1]);
1516
1517 if ((res_size < 2)
1518 || ((res_reg[0] & 0xf0) == 0x20)) {
1519 /* An error reading the TOC, this must be past the last session. */
1520 if (session == 1)
1521 printk
1522 ("Yikes! Couldn't read any sessions!");
1523 break;
1524 }
1525 pr_debug(PFX "Reading session %d\n", session);
1526
1527 parms[0] = session;
1528 do_sony_cd_cmd(SONY_REQ_TOC_DATA_SPEC_CMD,
1529 parms,
1530 1,
1531 (unsigned char *) &single_toc,
1532 &res_size);
1533 if ((res_size < 2)
1534 || ((single_toc.exec_status[0] & 0xf0) ==
1535 0x20)) {
1536 printk(KERN_ERR PFX "Error reading "
1537 "session %d: %x %s\n",
1538 session, single_toc.exec_status[0],
1539 translate_error(single_toc.
1540 exec_status[1]));
1541 /* An error reading the TOC. Return without sony_toc_read
1542 set. */
1543 return;
1544 }
1545 pr_debug(PFX "add0 %01x, con0 %01x, poi0 %02x, "
1546 "1st trk %d, dsktyp %x, dum0 %x\n",
1547 single_toc.address0, single_toc.control0,
1548 single_toc.point0,
1549 bcd_to_int(single_toc.first_track_num),
1550 single_toc.disk_type, single_toc.dummy0);
1551 pr_debug(PFX "add1 %01x, con1 %01x, poi1 %02x, "
1552 "lst trk %d, dummy1 %x, dum2 %x\n",
1553 single_toc.address1, single_toc.control1,
1554 single_toc.point1,
1555 bcd_to_int(single_toc.last_track_num),
1556 single_toc.dummy1, single_toc.dummy2);
1557 pr_debug(PFX "add2 %01x, con2 %01x, poi2 %02x "
1558 "leadout start min %d, sec %d, frame %d\n",
1559 single_toc.address2, single_toc.control2,
1560 single_toc.point2,
1561 bcd_to_int(single_toc.lead_out_start_msf[0]),
1562 bcd_to_int(single_toc.lead_out_start_msf[1]),
1563 bcd_to_int(single_toc.lead_out_start_msf[2]));
1564 if (res_size > 18 && single_toc.pointb0 > 0xaf)
1565 pr_debug(PFX "addb0 %01x, conb0 %01x, poib0 %02x, nextsession min %d, sec %d, frame %d\n"
1566 "#mode5_ptrs %02d, max_start_outer_leadout_msf min %d, sec %d, frame %d\n",
1567 single_toc.addressb0,
1568 single_toc.controlb0,
1569 single_toc.pointb0,
1570 bcd_to_int(single_toc.
1571 next_poss_prog_area_msf
1572 [0]),
1573 bcd_to_int(single_toc.
1574 next_poss_prog_area_msf
1575 [1]),
1576 bcd_to_int(single_toc.
1577 next_poss_prog_area_msf
1578 [2]),
1579 single_toc.num_mode_5_pointers,
1580 bcd_to_int(single_toc.
1581 max_start_outer_leadout_msf
1582 [0]),
1583 bcd_to_int(single_toc.
1584 max_start_outer_leadout_msf
1585 [1]),
1586 bcd_to_int(single_toc.
1587 max_start_outer_leadout_msf
1588 [2]));
1589 if (res_size > 27 && single_toc.pointb1 > 0xaf)
1590 pr_debug(PFX "addb1 %01x, conb1 %01x, poib1 %02x, %x %x %x %x #skipint_ptrs %d, #skiptrkassign %d %x\n",
1591 single_toc.addressb1,
1592 single_toc.controlb1,
1593 single_toc.pointb1,
1594 single_toc.dummyb0_1[0],
1595 single_toc.dummyb0_1[1],
1596 single_toc.dummyb0_1[2],
1597 single_toc.dummyb0_1[3],
1598 single_toc.num_skip_interval_pointers,
1599 single_toc.num_skip_track_assignments,
1600 single_toc.dummyb0_2);
1601 if (res_size > 36 && single_toc.pointb2 > 0xaf)
1602 pr_debug(PFX "addb2 %01x, conb2 %01x, poib2 %02x, %02x %02x %02x %02x %02x %02x %02x\n",
1603 single_toc.addressb2,
1604 single_toc.controlb2,
1605 single_toc.pointb2,
1606 single_toc.tracksb2[0],
1607 single_toc.tracksb2[1],
1608 single_toc.tracksb2[2],
1609 single_toc.tracksb2[3],
1610 single_toc.tracksb2[4],
1611 single_toc.tracksb2[5],
1612 single_toc.tracksb2[6]);
1613 if (res_size > 45 && single_toc.pointb3 > 0xaf)
1614 pr_debug(PFX "addb3 %01x, conb3 %01x, poib3 %02x, %02x %02x %02x %02x %02x %02x %02x\n",
1615 single_toc.addressb3,
1616 single_toc.controlb3,
1617 single_toc.pointb3,
1618 single_toc.tracksb3[0],
1619 single_toc.tracksb3[1],
1620 single_toc.tracksb3[2],
1621 single_toc.tracksb3[3],
1622 single_toc.tracksb3[4],
1623 single_toc.tracksb3[5],
1624 single_toc.tracksb3[6]);
1625 if (res_size > 54 && single_toc.pointb4 > 0xaf)
1626 pr_debug(PFX "addb4 %01x, conb4 %01x, poib4 %02x, %02x %02x %02x %02x %02x %02x %02x\n",
1627 single_toc.addressb4,
1628 single_toc.controlb4,
1629 single_toc.pointb4,
1630 single_toc.tracksb4[0],
1631 single_toc.tracksb4[1],
1632 single_toc.tracksb4[2],
1633 single_toc.tracksb4[3],
1634 single_toc.tracksb4[4],
1635 single_toc.tracksb4[5],
1636 single_toc.tracksb4[6]);
1637 if (res_size > 63 && single_toc.pointc0 > 0xaf)
1638 pr_debug(PFX "addc0 %01x, conc0 %01x, poic0 %02x, %02x %02x %02x %02x %02x %02x %02x\n",
1639 single_toc.addressc0,
1640 single_toc.controlc0,
1641 single_toc.pointc0,
1642 single_toc.dummyc0[0],
1643 single_toc.dummyc0[1],
1644 single_toc.dummyc0[2],
1645 single_toc.dummyc0[3],
1646 single_toc.dummyc0[4],
1647 single_toc.dummyc0[5],
1648 single_toc.dummyc0[6]);
1649#undef DEBUG
1650#define DEBUG 0
1651
1652 sony_toc.lead_out_start_msf[0] =
1653 bcd_to_int(single_toc.lead_out_start_msf[0]);
1654 sony_toc.lead_out_start_msf[1] =
1655 bcd_to_int(single_toc.lead_out_start_msf[1]);
1656 sony_toc.lead_out_start_msf[2] =
1657 bcd_to_int(single_toc.lead_out_start_msf[2]);
1658 sony_toc.lead_out_start_lba =
1659 single_toc.lead_out_start_lba =
1660 msf_to_log(sony_toc.lead_out_start_msf);
1661
1662 /* For points that do not exist, move the data over them
1663 to the right location. */
1664 if (single_toc.pointb0 != 0xb0) {
1665 memmove(((char *) &single_toc) + 27,
1666 ((char *) &single_toc) + 18,
1667 res_size - 18);
1668 res_size += 9;
1669 } else if (res_size > 18) {
1670 sony_toc.lead_out_start_msf[0] =
1671 bcd_to_int(single_toc.
1672 max_start_outer_leadout_msf
1673 [0]);
1674 sony_toc.lead_out_start_msf[1] =
1675 bcd_to_int(single_toc.
1676 max_start_outer_leadout_msf
1677 [1]);
1678 sony_toc.lead_out_start_msf[2] =
1679 bcd_to_int(single_toc.
1680 max_start_outer_leadout_msf
1681 [2]);
1682 sony_toc.lead_out_start_lba =
1683 msf_to_log(sony_toc.
1684 lead_out_start_msf);
1685 }
1686 if (single_toc.pointb1 != 0xb1) {
1687 memmove(((char *) &single_toc) + 36,
1688 ((char *) &single_toc) + 27,
1689 res_size - 27);
1690 res_size += 9;
1691 }
1692 if (single_toc.pointb2 != 0xb2) {
1693 memmove(((char *) &single_toc) + 45,
1694 ((char *) &single_toc) + 36,
1695 res_size - 36);
1696 res_size += 9;
1697 }
1698 if (single_toc.pointb3 != 0xb3) {
1699 memmove(((char *) &single_toc) + 54,
1700 ((char *) &single_toc) + 45,
1701 res_size - 45);
1702 res_size += 9;
1703 }
1704 if (single_toc.pointb4 != 0xb4) {
1705 memmove(((char *) &single_toc) + 63,
1706 ((char *) &single_toc) + 54,
1707 res_size - 54);
1708 res_size += 9;
1709 }
1710 if (single_toc.pointc0 != 0xc0) {
1711 memmove(((char *) &single_toc) + 72,
1712 ((char *) &single_toc) + 63,
1713 res_size - 63);
1714 res_size += 9;
1715 }
1716#if DEBUG
1717 printk(PRINT_INFO PFX "start track lba %u, "
1718 "leadout start lba %u\n",
1719 single_toc.start_track_lba,
1720 single_toc.lead_out_start_lba);
1721 {
1722 int i;
1723 for (i = 0;
1724 i <
1725 1 +
1726 bcd_to_int(single_toc.last_track_num)
1727 -
1728 bcd_to_int(single_toc.
1729 first_track_num); i++) {
1730 printk(KERN_INFO PFX "trk %02d: add 0x%01x, con 0x%01x, track %02d, start min %02d, sec %02d, frame %02d\n",
1731 i,
1732 single_toc.tracks[i].address,
1733 single_toc.tracks[i].control,
1734 bcd_to_int(single_toc.
1735 tracks[i].track),
1736 bcd_to_int(single_toc.
1737 tracks[i].
1738 track_start_msf
1739 [0]),
1740 bcd_to_int(single_toc.
1741 tracks[i].
1742 track_start_msf
1743 [1]),
1744 bcd_to_int(single_toc.
1745 tracks[i].
1746 track_start_msf
1747 [2]));
1748 if (mint >
1749 bcd_to_int(single_toc.
1750 tracks[i].track))
1751 mint =
1752 bcd_to_int(single_toc.
1753 tracks[i].
1754 track);
1755 if (maxt <
1756 bcd_to_int(single_toc.
1757 tracks[i].track))
1758 maxt =
1759 bcd_to_int(single_toc.
1760 tracks[i].
1761 track);
1762 }
1763 printk(KERN_INFO PFX "min track number %d, "
1764 "max track number %d\n",
1765 mint, maxt);
1766 }
1767#endif
1768
1769 /* prepare a special table of contents for a CD-I disc. They don't have one. */
1770 if (single_toc.disk_type == 0x10 &&
1771 single_toc.first_track_num == 2 &&
1772 single_toc.last_track_num == 2 /* CD-I */ ) {
1773 sony_toc.tracks[totaltracks].address = 1;
1774 sony_toc.tracks[totaltracks].control = 4; /* force data tracks */
1775 sony_toc.tracks[totaltracks].track = 1;
1776 sony_toc.tracks[totaltracks].
1777 track_start_msf[0] = 0;
1778 sony_toc.tracks[totaltracks].
1779 track_start_msf[1] = 2;
1780 sony_toc.tracks[totaltracks].
1781 track_start_msf[2] = 0;
1782 mint = maxt = 1;
1783 totaltracks++;
1784 } else
1785 /* gather track entries from this session */
1786 {
1787 int i;
1788 for (i = 0;
1789 i <
1790 1 +
1791 bcd_to_int(single_toc.last_track_num)
1792 -
1793 bcd_to_int(single_toc.
1794 first_track_num);
1795 i++, totaltracks++) {
1796 sony_toc.tracks[totaltracks].
1797 address =
1798 single_toc.tracks[i].address;
1799 sony_toc.tracks[totaltracks].
1800 control =
1801 single_toc.tracks[i].control;
1802 sony_toc.tracks[totaltracks].
1803 track =
1804 bcd_to_int(single_toc.
1805 tracks[i].track);
1806 sony_toc.tracks[totaltracks].
1807 track_start_msf[0] =
1808 bcd_to_int(single_toc.
1809 tracks[i].
1810 track_start_msf[0]);
1811 sony_toc.tracks[totaltracks].
1812 track_start_msf[1] =
1813 bcd_to_int(single_toc.
1814 tracks[i].
1815 track_start_msf[1]);
1816 sony_toc.tracks[totaltracks].
1817 track_start_msf[2] =
1818 bcd_to_int(single_toc.
1819 tracks[i].
1820 track_start_msf[2]);
1821 if (i == 0)
1822 single_toc.
1823 start_track_lba =
1824 msf_to_log(sony_toc.
1825 tracks
1826 [totaltracks].
1827 track_start_msf);
1828 if (mint >
1829 sony_toc.tracks[totaltracks].
1830 track)
1831 mint =
1832 sony_toc.
1833 tracks[totaltracks].
1834 track;
1835 if (maxt <
1836 sony_toc.tracks[totaltracks].
1837 track)
1838 maxt =
1839 sony_toc.
1840 tracks[totaltracks].
1841 track;
1842 }
1843 }
1844 sony_toc.first_track_num = mint;
1845 sony_toc.last_track_num = maxt;
1846 /* Disk type of last session wins. For example:
1847 CD-Extra has disk type 0 for the first session, so
1848 a dumb HiFi CD player thinks it is a plain audio CD.
1849 We are interested in the disk type of the last session,
1850 which is 0x20 (XA) for CD-Extra, so we can access the
1851 data track ... */
1852 sony_toc.disk_type = single_toc.disk_type;
1853 sony_toc.sessions = session;
1854
1855 /* don't believe everything :-) */
1856 if (session == 1)
1857 single_toc.start_track_lba = 0;
1858 sony_toc.start_track_lba =
1859 single_toc.start_track_lba;
1860
1861 if (session > 1 && single_toc.pointb0 == 0xb0 &&
1862 sony_toc.lead_out_start_lba ==
1863 single_toc.lead_out_start_lba) {
1864 break;
1865 }
1866
1867 /* Let's not get carried away... */
1868 if (session > 40) {
1869 printk(KERN_NOTICE PFX "too many sessions: "
1870 "%d\n", session);
1871 break;
1872 }
1873 session++;
1874 }
1875 sony_toc.track_entries = totaltracks;
1876 /* add one entry for the LAST track with track number CDROM_LEADOUT */
1877 sony_toc.tracks[totaltracks].address = single_toc.address2;
1878 sony_toc.tracks[totaltracks].control = single_toc.control2;
1879 sony_toc.tracks[totaltracks].track = CDROM_LEADOUT;
1880 sony_toc.tracks[totaltracks].track_start_msf[0] =
1881 sony_toc.lead_out_start_msf[0];
1882 sony_toc.tracks[totaltracks].track_start_msf[1] =
1883 sony_toc.lead_out_start_msf[1];
1884 sony_toc.tracks[totaltracks].track_start_msf[2] =
1885 sony_toc.lead_out_start_msf[2];
1886
1887 sony_toc_read = 1;
1888
1889 pr_debug(PFX "Disk session %d, start track: %d, "
1890 "stop track: %d\n",
1891 session, single_toc.start_track_lba,
1892 single_toc.lead_out_start_lba);
1893 }
1894 pr_debug(PFX "Leaving %s\n", __FUNCTION__);
1895}
1896
1897
1898/*
1899 * Uniform cdrom interface function
1900 * return multisession offset and sector information
1901 */
1902static int scd_get_last_session(struct cdrom_device_info *cdi,
1903 struct cdrom_multisession *ms_info)
1904{
1905 if (ms_info == NULL)
1906 return 1;
1907
1908 if (!sony_toc_read) {
1909 if (down_interruptible(&sony_sem))
1910 return -ERESTARTSYS;
1911 sony_get_toc();
1912 up(&sony_sem);
1913 }
1914
1915 ms_info->addr_format = CDROM_LBA;
1916 ms_info->addr.lba = sony_toc.start_track_lba;
1917 ms_info->xa_flag = sony_toc.disk_type == SONY_XA_DISK_TYPE ||
1918 sony_toc.disk_type == 0x10 /* CDI */ ;
1919
1920 return 0;
1921}
1922
1923/*
1924 * Search for a specific track in the table of contents.
1925 */
1926static int find_track(int track)
1927{
1928 int i;
1929
1930 for (i = 0; i <= sony_toc.track_entries; i++) {
1931 if (sony_toc.tracks[i].track == track) {
1932 return i;
1933 }
1934 }
1935
1936 return -1;
1937}
1938
1939
1940/*
1941 * Read the subcode and put it in last_sony_subcode for future use.
1942 */
1943static int read_subcode(void)
1944{
1945 unsigned int res_size;
1946
1947
1948 do_sony_cd_cmd(SONY_REQ_SUBCODE_ADDRESS_CMD,
1949 NULL,
1950 0, (unsigned char *) &last_sony_subcode, &res_size);
1951 if ((res_size < 2)
1952 || ((last_sony_subcode.exec_status[0] & 0xf0) == 0x20)) {
1953 printk(KERN_ERR PFX "Sony CDROM error %s (read_subcode)\n",
1954 translate_error(last_sony_subcode.exec_status[1]));
1955 return -EIO;
1956 }
1957
1958 last_sony_subcode.track_num =
1959 bcd_to_int(last_sony_subcode.track_num);
1960 last_sony_subcode.index_num =
1961 bcd_to_int(last_sony_subcode.index_num);
1962 last_sony_subcode.abs_msf[0] =
1963 bcd_to_int(last_sony_subcode.abs_msf[0]);
1964 last_sony_subcode.abs_msf[1] =
1965 bcd_to_int(last_sony_subcode.abs_msf[1]);
1966 last_sony_subcode.abs_msf[2] =
1967 bcd_to_int(last_sony_subcode.abs_msf[2]);
1968
1969 last_sony_subcode.rel_msf[0] =
1970 bcd_to_int(last_sony_subcode.rel_msf[0]);
1971 last_sony_subcode.rel_msf[1] =
1972 bcd_to_int(last_sony_subcode.rel_msf[1]);
1973 last_sony_subcode.rel_msf[2] =
1974 bcd_to_int(last_sony_subcode.rel_msf[2]);
1975 return 0;
1976}
1977
1978/*
1979 * Uniform cdrom interface function
1980 * return the media catalog number found on some older audio cds
1981 */
1982static int
1983scd_get_mcn(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn)
1984{
1985 unsigned char resbuffer[2 + 14];
1986 unsigned char *mcnp = mcn->medium_catalog_number;
1987 unsigned char *resp = resbuffer + 3;
1988 unsigned int res_size;
1989
1990 memset(mcn->medium_catalog_number, 0, 14);
1991 if (down_interruptible(&sony_sem))
1992 return -ERESTARTSYS;
1993 do_sony_cd_cmd(SONY_REQ_UPC_EAN_CMD,
1994 NULL, 0, resbuffer, &res_size);
1995 up(&sony_sem);
1996 if ((res_size < 2) || ((resbuffer[0] & 0xf0) == 0x20));
1997 else {
1998 /* packed bcd to single ASCII digits */
1999 *mcnp++ = (*resp >> 4) + '0';
2000 *mcnp++ = (*resp++ & 0x0f) + '0';
2001 *mcnp++ = (*resp >> 4) + '0';
2002 *mcnp++ = (*resp++ & 0x0f) + '0';
2003 *mcnp++ = (*resp >> 4) + '0';
2004 *mcnp++ = (*resp++ & 0x0f) + '0';
2005 *mcnp++ = (*resp >> 4) + '0';
2006 *mcnp++ = (*resp++ & 0x0f) + '0';
2007 *mcnp++ = (*resp >> 4) + '0';
2008 *mcnp++ = (*resp++ & 0x0f) + '0';
2009 *mcnp++ = (*resp >> 4) + '0';
2010 *mcnp++ = (*resp++ & 0x0f) + '0';
2011 *mcnp++ = (*resp >> 4) + '0';
2012 }
2013 *mcnp = '\0';
2014 return 0;
2015}
2016
2017
2018/*
2019 * Get the subchannel info like the CDROMSUBCHNL command wants to see it. If
2020 * the drive is playing, the subchannel needs to be read (since it would be
2021 * changing). If the drive is paused or completed, the subcode information has
2022 * already been stored, just use that. The ioctl call wants things in decimal
2023 * (not BCD), so all the conversions are done.
2024 */
2025static int sony_get_subchnl_info(struct cdrom_subchnl *schi)
2026{
2027 /* Get attention stuff */
2028 while (handle_sony_cd_attention());
2029
2030 sony_get_toc();
2031 if (!sony_toc_read) {
2032 return -EIO;
2033 }
2034
2035 switch (sony_audio_status) {
2036 case CDROM_AUDIO_NO_STATUS:
2037 case CDROM_AUDIO_PLAY:
2038 if (read_subcode() < 0) {
2039 return -EIO;
2040 }
2041 break;
2042
2043 case CDROM_AUDIO_PAUSED:
2044 case CDROM_AUDIO_COMPLETED:
2045 break;
2046
2047#if 0
2048 case CDROM_AUDIO_NO_STATUS:
2049 schi->cdsc_audiostatus = sony_audio_status;
2050 return 0;
2051 break;
2052#endif
2053 case CDROM_AUDIO_INVALID:
2054 case CDROM_AUDIO_ERROR:
2055 default:
2056 return -EIO;
2057 }
2058
2059 schi->cdsc_audiostatus = sony_audio_status;
2060 schi->cdsc_adr = last_sony_subcode.address;
2061 schi->cdsc_ctrl = last_sony_subcode.control;
2062 schi->cdsc_trk = last_sony_subcode.track_num;
2063 schi->cdsc_ind = last_sony_subcode.index_num;
2064 if (schi->cdsc_format == CDROM_MSF) {
2065 schi->cdsc_absaddr.msf.minute =
2066 last_sony_subcode.abs_msf[0];
2067 schi->cdsc_absaddr.msf.second =
2068 last_sony_subcode.abs_msf[1];
2069 schi->cdsc_absaddr.msf.frame =
2070 last_sony_subcode.abs_msf[2];
2071
2072 schi->cdsc_reladdr.msf.minute =
2073 last_sony_subcode.rel_msf[0];
2074 schi->cdsc_reladdr.msf.second =
2075 last_sony_subcode.rel_msf[1];
2076 schi->cdsc_reladdr.msf.frame =
2077 last_sony_subcode.rel_msf[2];
2078 } else if (schi->cdsc_format == CDROM_LBA) {
2079 schi->cdsc_absaddr.lba =
2080 msf_to_log(last_sony_subcode.abs_msf);
2081 schi->cdsc_reladdr.lba =
2082 msf_to_log(last_sony_subcode.rel_msf);
2083 }
2084
2085 return 0;
2086}
2087
2088/* Get audio data from the drive. This is fairly complex because I
2089 am looking for status and data at the same time, but if I get status
2090 then I just look for data. I need to get the status immediately so
2091 the switch from audio to data tracks will happen quickly. */
2092static void
2093read_audio_data(char *buffer, unsigned char res_reg[], int *res_size)
2094{
2095 unsigned long retry_count;
2096 int result_read;
2097
2098
2099 res_reg[0] = 0;
2100 res_reg[1] = 0;
2101 *res_size = 0;
2102 result_read = 0;
2103
2104 /* Wait for the drive to tell us we have something */
2105 retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
2106 continue_read_audio_wait:
2107 while (time_before(jiffies, retry_count) && !(is_data_ready())
2108 && !(is_result_ready() || result_read)) {
2109 while (handle_sony_cd_attention());
2110
2111 sony_sleep();
2112 }
2113 if (!(is_data_ready())) {
2114 if (is_result_ready() && !result_read) {
2115 get_result(res_reg, res_size);
2116
2117 /* Read block status and continue waiting for data. */
2118 if ((res_reg[0] & 0xf0) == 0x50) {
2119 result_read = 1;
2120 goto continue_read_audio_wait;
2121 }
2122 /* Invalid data from the drive. Shut down the operation. */
2123 else if ((res_reg[0] & 0xf0) != 0x20) {
2124 printk(KERN_WARNING PFX "Got result that "
2125 "should have been error: %d\n",
2126 res_reg[0]);
2127 res_reg[0] = 0x20;
2128 res_reg[1] = SONY_BAD_DATA_ERR;
2129 *res_size = 2;
2130 }
2131 abort_read();
2132 } else {
2133 pr_debug(PFX "timeout out %d\n", __LINE__);
2134 res_reg[0] = 0x20;
2135 res_reg[1] = SONY_TIMEOUT_OP_ERR;
2136 *res_size = 2;
2137 abort_read();
2138 }
2139 } else {
2140 clear_data_ready();
2141
2142 /* If data block, then get 2340 bytes offset by 12. */
2143 if (sony_raw_data_mode) {
2144 insb(sony_cd_read_reg, buffer + CD_XA_HEAD,
2145 CD_FRAMESIZE_RAW1);
2146 } else {
2147 /* Audio gets the whole 2352 bytes. */
2148 insb(sony_cd_read_reg, buffer, CD_FRAMESIZE_RAW);
2149 }
2150
2151 /* If I haven't already gotten the result, get it now. */
2152 if (!result_read) {
2153 /* Wait for the drive to tell us we have something */
2154 retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
2155 while (time_before(jiffies, retry_count)
2156 && !(is_result_ready())) {
2157 while (handle_sony_cd_attention());
2158
2159 sony_sleep();
2160 }
2161
2162 if (!is_result_ready()) {
2163 pr_debug(PFX "timeout out %d\n", __LINE__);
2164 res_reg[0] = 0x20;
2165 res_reg[1] = SONY_TIMEOUT_OP_ERR;
2166 *res_size = 2;
2167 abort_read();
2168 return;
2169 } else {
2170 get_result(res_reg, res_size);
2171 }
2172 }
2173
2174 if ((res_reg[0] & 0xf0) == 0x50) {
2175 if ((res_reg[0] == SONY_NO_CIRC_ERR_BLK_STAT)
2176 || (res_reg[0] == SONY_NO_LECC_ERR_BLK_STAT)
2177 || (res_reg[0] == SONY_RECOV_LECC_ERR_BLK_STAT)
2178 || (res_reg[0] == SONY_NO_ERR_DETECTION_STAT)) {
2179 /* Ok, nothing to do. */
2180 } else {
2181 printk(KERN_ERR PFX "Data block error: 0x%x\n",
2182 res_reg[0]);
2183 res_reg[0] = 0x20;
2184 res_reg[1] = SONY_BAD_DATA_ERR;
2185 *res_size = 2;
2186 }
2187 } else if ((res_reg[0] & 0xf0) != 0x20) {
2188 /* The drive gave me bad status, I don't know what to do.
2189 Reset the driver and return an error. */
2190 printk(KERN_NOTICE PFX "Invalid block status: 0x%x\n",
2191 res_reg[0]);
2192 restart_on_error();
2193 res_reg[0] = 0x20;
2194 res_reg[1] = SONY_BAD_DATA_ERR;
2195 *res_size = 2;
2196 }
2197 }
2198}
2199
2200/* Perform a raw data read. This will automatically detect the
2201 track type and read the proper data (audio or data). */
2202static int read_audio(struct cdrom_read_audio *ra)
2203{
2204 int retval;
2205 unsigned char params[2];
2206 unsigned char res_reg[12];
2207 unsigned int res_size;
2208 unsigned int cframe;
2209
2210 if (down_interruptible(&sony_sem))
2211 return -ERESTARTSYS;
2212 if (!sony_spun_up)
2213 scd_spinup();
2214
2215 /* Set the drive to do raw operations. */
2216 params[0] = SONY_SD_DECODE_PARAM;
2217 params[1] = 0x06 | sony_raw_data_mode;
2218 do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
2219 params, 2, res_reg, &res_size);
2220 if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20)) {
2221 printk(KERN_ERR PFX "Unable to set decode params: 0x%2.2x\n",
2222 res_reg[1]);
2223 retval = -EIO;
2224 goto out_up;
2225 }
2226
2227 /* From here down, we have to goto exit_read_audio instead of returning
2228 because the drive parameters have to be set back to data before
2229 return. */
2230
2231 retval = 0;
2232 if (start_request(ra->addr.lba, ra->nframes)) {
2233 retval = -EIO;
2234 goto exit_read_audio;
2235 }
2236
2237 /* For every requested frame. */
2238 cframe = 0;
2239 while (cframe < ra->nframes) {
2240 read_audio_data(audio_buffer, res_reg, &res_size);
2241 if ((res_reg[0] & 0xf0) == 0x20) {
2242 if (res_reg[1] == SONY_BAD_DATA_ERR) {
2243 printk(KERN_ERR PFX "Data error on audio "
2244 "sector %d\n",
2245 ra->addr.lba + cframe);
2246 } else if (res_reg[1] == SONY_ILL_TRACK_R_ERR) {
2247 /* Illegal track type, change track types and start over. */
2248 sony_raw_data_mode =
2249 (sony_raw_data_mode) ? 0 : 1;
2250
2251 /* Set the drive mode. */
2252 params[0] = SONY_SD_DECODE_PARAM;
2253 params[1] = 0x06 | sony_raw_data_mode;
2254 do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
2255 params,
2256 2, res_reg, &res_size);
2257 if ((res_size < 2)
2258 || ((res_reg[0] & 0xf0) == 0x20)) {
2259 printk(KERN_ERR PFX "Unable to set "
2260 "decode params: 0x%2.2x\n",
2261 res_reg[1]);
2262 retval = -EIO;
2263 goto exit_read_audio;
2264 }
2265
2266 /* Restart the request on the current frame. */
2267 if (start_request
2268 (ra->addr.lba + cframe,
2269 ra->nframes - cframe)) {
2270 retval = -EIO;
2271 goto exit_read_audio;
2272 }
2273
2274 /* Don't go back to the top because don't want to get into
2275 and infinite loop. A lot of code gets duplicated, but
2276 that's no big deal, I don't guess. */
2277 read_audio_data(audio_buffer, res_reg,
2278 &res_size);
2279 if ((res_reg[0] & 0xf0) == 0x20) {
2280 if (res_reg[1] ==
2281 SONY_BAD_DATA_ERR) {
2282 printk(KERN_ERR PFX "Data error"
2283 " on audio sector %d\n",
2284 ra->addr.lba +
2285 cframe);
2286 } else {
2287 printk(KERN_ERR PFX "Error reading audio data on sector %d: %s\n",
2288 ra->addr.lba + cframe,
2289 translate_error
2290 (res_reg[1]));
2291 retval = -EIO;
2292 goto exit_read_audio;
2293 }
2294 } else if (copy_to_user(ra->buf +
2295 (CD_FRAMESIZE_RAW
2296 * cframe),
2297 audio_buffer,
2298 CD_FRAMESIZE_RAW)) {
2299 retval = -EFAULT;
2300 goto exit_read_audio;
2301 }
2302 } else {
2303 printk(KERN_ERR PFX "Error reading audio "
2304 "data on sector %d: %s\n",
2305 ra->addr.lba + cframe,
2306 translate_error(res_reg[1]));
2307 retval = -EIO;
2308 goto exit_read_audio;
2309 }
2310 } else if (copy_to_user(ra->buf + (CD_FRAMESIZE_RAW * cframe),
2311 (char *)audio_buffer,
2312 CD_FRAMESIZE_RAW)) {
2313 retval = -EFAULT;
2314 goto exit_read_audio;
2315 }
2316
2317 cframe++;
2318 }
2319
2320 get_result(res_reg, &res_size);
2321 if ((res_reg[0] & 0xf0) == 0x20) {
2322 printk(KERN_ERR PFX "Error return from audio read: %s\n",
2323 translate_error(res_reg[1]));
2324 retval = -EIO;
2325 goto exit_read_audio;
2326 }
2327
2328 exit_read_audio:
2329
2330 /* Set the drive mode back to the proper one for the disk. */
2331 params[0] = SONY_SD_DECODE_PARAM;
2332 if (!sony_xa_mode) {
2333 params[1] = 0x0f;
2334 } else {
2335 params[1] = 0x07;
2336 }
2337 do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
2338 params, 2, res_reg, &res_size);
2339 if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20)) {
2340 printk(KERN_ERR PFX "Unable to reset decode params: 0x%2.2x\n",
2341 res_reg[1]);
2342 retval = -EIO;
2343 }
2344
2345 out_up:
2346 up(&sony_sem);
2347
2348 return retval;
2349}
2350
2351static int
2352do_sony_cd_cmd_chk(const char *name,
2353 unsigned char cmd,
2354 unsigned char *params,
2355 unsigned int num_params,
2356 unsigned char *result_buffer, unsigned int *result_size)
2357{
2358 do_sony_cd_cmd(cmd, params, num_params, result_buffer,
2359 result_size);
2360 if ((*result_size < 2) || ((result_buffer[0] & 0xf0) == 0x20)) {
2361 printk(KERN_ERR PFX "Error %s (CDROM%s)\n",
2362 translate_error(result_buffer[1]), name);
2363 return -EIO;
2364 }
2365 return 0;
2366}
2367
2368/*
2369 * Uniform cdrom interface function
2370 * open the tray
2371 */
2372static int scd_tray_move(struct cdrom_device_info *cdi, int position)
2373{
2374 int retval;
2375
2376 if (down_interruptible(&sony_sem))
2377 return -ERESTARTSYS;
2378 if (position == 1 /* open tray */ ) {
2379 unsigned char res_reg[12];
2380 unsigned int res_size;
2381
2382 do_sony_cd_cmd(SONY_AUDIO_STOP_CMD, NULL, 0, res_reg,
2383 &res_size);
2384 do_sony_cd_cmd(SONY_SPIN_DOWN_CMD, NULL, 0, res_reg,
2385 &res_size);
2386
2387 sony_audio_status = CDROM_AUDIO_INVALID;
2388 retval = do_sony_cd_cmd_chk("EJECT", SONY_EJECT_CMD, NULL, 0,
2389 res_reg, &res_size);
2390 } else {
2391 if (0 == scd_spinup())
2392 sony_spun_up = 1;
2393 retval = 0;
2394 }
2395 up(&sony_sem);
2396 return retval;
2397}
2398
2399/*
2400 * The big ugly ioctl handler.
2401 */
2402static int scd_audio_ioctl(struct cdrom_device_info *cdi,
2403 unsigned int cmd, void *arg)
2404{
2405 unsigned char res_reg[12];
2406 unsigned int res_size;
2407 unsigned char params[7];
2408 int i, retval;
2409
2410 if (down_interruptible(&sony_sem))
2411 return -ERESTARTSYS;
2412 switch (cmd) {
2413 case CDROMSTART: /* Spin up the drive */
2414 retval = do_sony_cd_cmd_chk("START", SONY_SPIN_UP_CMD, NULL,
2415 0, res_reg, &res_size);
2416 break;
2417
2418 case CDROMSTOP: /* Spin down the drive */
2419 do_sony_cd_cmd(SONY_AUDIO_STOP_CMD, NULL, 0, res_reg,
2420 &res_size);
2421
2422 /*
2423 * Spin the drive down, ignoring the error if the disk was
2424 * already not spinning.
2425 */
2426 sony_audio_status = CDROM_AUDIO_NO_STATUS;
2427 retval = do_sony_cd_cmd_chk("STOP", SONY_SPIN_DOWN_CMD, NULL,
2428 0, res_reg, &res_size);
2429 break;
2430
2431 case CDROMPAUSE: /* Pause the drive */
2432 if (do_sony_cd_cmd_chk
2433 ("PAUSE", SONY_AUDIO_STOP_CMD, NULL, 0, res_reg,
2434 &res_size)) {
2435 retval = -EIO;
2436 break;
2437 }
2438 /* Get the current position and save it for resuming */
2439 if (read_subcode() < 0) {
2440 retval = -EIO;
2441 break;
2442 }
2443 cur_pos_msf[0] = last_sony_subcode.abs_msf[0];
2444 cur_pos_msf[1] = last_sony_subcode.abs_msf[1];
2445 cur_pos_msf[2] = last_sony_subcode.abs_msf[2];
2446 sony_audio_status = CDROM_AUDIO_PAUSED;
2447 retval = 0;
2448 break;
2449
2450 case CDROMRESUME: /* Start the drive after being paused */
2451 if (sony_audio_status != CDROM_AUDIO_PAUSED) {
2452 retval = -EINVAL;
2453 break;
2454 }
2455
2456 do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg,
2457 &res_size);
2458
2459 /* Start the drive at the saved position. */
2460 params[1] = int_to_bcd(cur_pos_msf[0]);
2461 params[2] = int_to_bcd(cur_pos_msf[1]);
2462 params[3] = int_to_bcd(cur_pos_msf[2]);
2463 params[4] = int_to_bcd(final_pos_msf[0]);
2464 params[5] = int_to_bcd(final_pos_msf[1]);
2465 params[6] = int_to_bcd(final_pos_msf[2]);
2466 params[0] = 0x03;
2467 if (do_sony_cd_cmd_chk
2468 ("RESUME", SONY_AUDIO_PLAYBACK_CMD, params, 7, res_reg,
2469 &res_size) < 0) {
2470 retval = -EIO;
2471 break;
2472 }
2473 sony_audio_status = CDROM_AUDIO_PLAY;
2474 retval = 0;
2475 break;
2476
2477 case CDROMPLAYMSF: /* Play starting at the given MSF address. */
2478 do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg,
2479 &res_size);
2480
2481 /* The parameters are given in int, must be converted */
2482 for (i = 1; i < 7; i++) {
2483 params[i] =
2484 int_to_bcd(((unsigned char *) arg)[i - 1]);
2485 }
2486 params[0] = 0x03;
2487 if (do_sony_cd_cmd_chk
2488 ("PLAYMSF", SONY_AUDIO_PLAYBACK_CMD, params, 7,
2489 res_reg, &res_size) < 0) {
2490 retval = -EIO;
2491 break;
2492 }
2493
2494 /* Save the final position for pauses and resumes */
2495 final_pos_msf[0] = bcd_to_int(params[4]);
2496 final_pos_msf[1] = bcd_to_int(params[5]);
2497 final_pos_msf[2] = bcd_to_int(params[6]);
2498 sony_audio_status = CDROM_AUDIO_PLAY;
2499 retval = 0;
2500 break;
2501
2502 case CDROMREADTOCHDR: /* Read the table of contents header */
2503 {
2504 struct cdrom_tochdr *hdr;
2505
2506 sony_get_toc();
2507 if (!sony_toc_read) {
2508 retval = -EIO;
2509 break;
2510 }
2511
2512 hdr = (struct cdrom_tochdr *) arg;
2513 hdr->cdth_trk0 = sony_toc.first_track_num;
2514 hdr->cdth_trk1 = sony_toc.last_track_num;
2515 }
2516 retval = 0;
2517 break;
2518
2519 case CDROMREADTOCENTRY: /* Read a given table of contents entry */
2520 {
2521 struct cdrom_tocentry *entry;
2522 int track_idx;
2523 unsigned char *msf_val = NULL;
2524
2525 sony_get_toc();
2526 if (!sony_toc_read) {
2527 retval = -EIO;
2528 break;
2529 }
2530
2531 entry = (struct cdrom_tocentry *) arg;
2532
2533 track_idx = find_track(entry->cdte_track);
2534 if (track_idx < 0) {
2535 retval = -EINVAL;
2536 break;
2537 }
2538
2539 entry->cdte_adr =
2540 sony_toc.tracks[track_idx].address;
2541 entry->cdte_ctrl =
2542 sony_toc.tracks[track_idx].control;
2543 msf_val =
2544 sony_toc.tracks[track_idx].track_start_msf;
2545
2546 /* Logical buffer address or MSF format requested? */
2547 if (entry->cdte_format == CDROM_LBA) {
2548 entry->cdte_addr.lba = msf_to_log(msf_val);
2549 } else if (entry->cdte_format == CDROM_MSF) {
2550 entry->cdte_addr.msf.minute = *msf_val;
2551 entry->cdte_addr.msf.second =
2552 *(msf_val + 1);
2553 entry->cdte_addr.msf.frame =
2554 *(msf_val + 2);
2555 }
2556 }
2557 retval = 0;
2558 break;
2559
2560 case CDROMPLAYTRKIND: /* Play a track. This currently ignores index. */
2561 {
2562 struct cdrom_ti *ti = (struct cdrom_ti *) arg;
2563 int track_idx;
2564
2565 sony_get_toc();
2566 if (!sony_toc_read) {
2567 retval = -EIO;
2568 break;
2569 }
2570
2571 if ((ti->cdti_trk0 < sony_toc.first_track_num)
2572 || (ti->cdti_trk0 > sony_toc.last_track_num)
2573 || (ti->cdti_trk1 < ti->cdti_trk0)) {
2574 retval = -EINVAL;
2575 break;
2576 }
2577
2578 track_idx = find_track(ti->cdti_trk0);
2579 if (track_idx < 0) {
2580 retval = -EINVAL;
2581 break;
2582 }
2583 params[1] =
2584 int_to_bcd(sony_toc.tracks[track_idx].
2585 track_start_msf[0]);
2586 params[2] =
2587 int_to_bcd(sony_toc.tracks[track_idx].
2588 track_start_msf[1]);
2589 params[3] =
2590 int_to_bcd(sony_toc.tracks[track_idx].
2591 track_start_msf[2]);
2592
2593 /*
2594 * If we want to stop after the last track, use the lead-out
2595 * MSF to do that.
2596 */
2597 if (ti->cdti_trk1 >= sony_toc.last_track_num) {
2598 track_idx = find_track(CDROM_LEADOUT);
2599 } else {
2600 track_idx = find_track(ti->cdti_trk1 + 1);
2601 }
2602 if (track_idx < 0) {
2603 retval = -EINVAL;
2604 break;
2605 }
2606 params[4] =
2607 int_to_bcd(sony_toc.tracks[track_idx].
2608 track_start_msf[0]);
2609 params[5] =
2610 int_to_bcd(sony_toc.tracks[track_idx].
2611 track_start_msf[1]);
2612 params[6] =
2613 int_to_bcd(sony_toc.tracks[track_idx].
2614 track_start_msf[2]);
2615 params[0] = 0x03;
2616
2617 do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg,
2618 &res_size);
2619
2620 do_sony_cd_cmd(SONY_AUDIO_PLAYBACK_CMD, params, 7,
2621 res_reg, &res_size);
2622
2623 if ((res_size < 2)
2624 || ((res_reg[0] & 0xf0) == 0x20)) {
2625 printk(KERN_ERR PFX
2626 "Params: %x %x %x %x %x %x %x\n",
2627 params[0], params[1], params[2],
2628 params[3], params[4], params[5],
2629 params[6]);
2630 printk(KERN_ERR PFX
2631 "Error %s (CDROMPLAYTRKIND)\n",
2632 translate_error(res_reg[1]));
2633 retval = -EIO;
2634 break;
2635 }
2636
2637 /* Save the final position for pauses and resumes */
2638 final_pos_msf[0] = bcd_to_int(params[4]);
2639 final_pos_msf[1] = bcd_to_int(params[5]);
2640 final_pos_msf[2] = bcd_to_int(params[6]);
2641 sony_audio_status = CDROM_AUDIO_PLAY;
2642 retval = 0;
2643 break;
2644 }
2645
2646 case CDROMVOLCTRL: /* Volume control. What volume does this change, anyway? */
2647 {
2648 struct cdrom_volctrl *volctrl =
2649 (struct cdrom_volctrl *) arg;
2650
2651 params[0] = SONY_SD_AUDIO_VOLUME;
2652 params[1] = volctrl->channel0;
2653 params[2] = volctrl->channel1;
2654 retval = do_sony_cd_cmd_chk("VOLCTRL",
2655 SONY_SET_DRIVE_PARAM_CMD,
2656 params, 3, res_reg,
2657 &res_size);
2658 break;
2659 }
2660 case CDROMSUBCHNL: /* Get subchannel info */
2661 retval = sony_get_subchnl_info((struct cdrom_subchnl *) arg);
2662 break;
2663
2664 default:
2665 retval = -EINVAL;
2666 break;
2667 }
2668 up(&sony_sem);
2669 return retval;
2670}
2671
2672static int scd_read_audio(struct cdrom_device_info *cdi,
2673 unsigned int cmd, unsigned long arg)
2674{
2675 void __user *argp = (void __user *)arg;
2676 int retval;
2677
2678 if (down_interruptible(&sony_sem))
2679 return -ERESTARTSYS;
2680 switch (cmd) {
2681 case CDROMREADAUDIO: /* Read 2352 byte audio tracks and 2340 byte
2682 raw data tracks. */
2683 {
2684 struct cdrom_read_audio ra;
2685
2686
2687 sony_get_toc();
2688 if (!sony_toc_read) {
2689 retval = -EIO;
2690 break;
2691 }
2692
2693 if (copy_from_user(&ra, argp, sizeof(ra))) {
2694 retval = -EFAULT;
2695 break;
2696 }
2697
2698 if (ra.nframes == 0) {
2699 retval = 0;
2700 break;
2701 }
2702
2703 if (!access_ok(VERIFY_WRITE, ra.buf,
2704 CD_FRAMESIZE_RAW * ra.nframes))
2705 return -EFAULT;
2706
2707 if (ra.addr_format == CDROM_LBA) {
2708 if ((ra.addr.lba >=
2709 sony_toc.lead_out_start_lba)
2710 || (ra.addr.lba + ra.nframes >=
2711 sony_toc.lead_out_start_lba)) {
2712 retval = -EINVAL;
2713 break;
2714 }
2715 } else if (ra.addr_format == CDROM_MSF) {
2716 if ((ra.addr.msf.minute >= 75)
2717 || (ra.addr.msf.second >= 60)
2718 || (ra.addr.msf.frame >= 75)) {
2719 retval = -EINVAL;
2720 break;
2721 }
2722
2723 ra.addr.lba = ((ra.addr.msf.minute * 4500)
2724 + (ra.addr.msf.second * 75)
2725 + ra.addr.msf.frame);
2726 if ((ra.addr.lba >=
2727 sony_toc.lead_out_start_lba)
2728 || (ra.addr.lba + ra.nframes >=
2729 sony_toc.lead_out_start_lba)) {
2730 retval = -EINVAL;
2731 break;
2732 }
2733
2734 /* I know, this can go negative on an unsigned. However,
2735 the first thing done to the data is to add this value,
2736 so this should compensate and allow direct msf access. */
2737 ra.addr.lba -= LOG_START_OFFSET;
2738 } else {
2739 retval = -EINVAL;
2740 break;
2741 }
2742
2743 retval = read_audio(&ra);
2744 break;
2745 }
2746 retval = 0;
2747 break;
2748
2749 default:
2750 retval = -EINVAL;
2751 }
2752 up(&sony_sem);
2753 return retval;
2754}
2755
2756static int scd_spinup(void)
2757{
2758 unsigned char res_reg[12];
2759 unsigned int res_size;
2760 int num_spin_ups;
2761
2762 num_spin_ups = 0;
2763
2764 respinup_on_open:
2765 do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg, &res_size);
2766
2767 /* The drive sometimes returns error 0. I don't know why, but ignore
2768 it. It seems to mean the drive has already done the operation. */
2769 if ((res_size < 2) || ((res_reg[0] != 0) && (res_reg[1] != 0))) {
2770 printk(KERN_ERR PFX "%s error (scd_open, spin up)\n",
2771 translate_error(res_reg[1]));
2772 return 1;
2773 }
2774
2775 do_sony_cd_cmd(SONY_READ_TOC_CMD, NULL, 0, res_reg, &res_size);
2776
2777 /* The drive sometimes returns error 0. I don't know why, but ignore
2778 it. It seems to mean the drive has already done the operation. */
2779 if ((res_size < 2) || ((res_reg[0] != 0) && (res_reg[1] != 0))) {
2780 /* If the drive is already playing, it's ok. */
2781 if ((res_reg[1] == SONY_AUDIO_PLAYING_ERR)
2782 || (res_reg[1] == 0)) {
2783 return 0;
2784 }
2785
2786 /* If the drive says it is not spun up (even though we just did it!)
2787 then retry the operation at least a few times. */
2788 if ((res_reg[1] == SONY_NOT_SPIN_ERR)
2789 && (num_spin_ups < MAX_CDU31A_RETRIES)) {
2790 num_spin_ups++;
2791 goto respinup_on_open;
2792 }
2793
2794 printk(KERN_ERR PFX "Error %s (scd_open, read toc)\n",
2795 translate_error(res_reg[1]));
2796 do_sony_cd_cmd(SONY_SPIN_DOWN_CMD, NULL, 0, res_reg,
2797 &res_size);
2798 return 1;
2799 }
2800 return 0;
2801}
2802
2803/*
2804 * Open the drive for operations. Spin the drive up and read the table of
2805 * contents if these have not already been done.
2806 */
2807static int scd_open(struct cdrom_device_info *cdi, int purpose)
2808{
2809 unsigned char res_reg[12];
2810 unsigned int res_size;
2811 unsigned char params[2];
2812
2813 if (purpose == 1) {
2814 /* Open for IOCTLs only - no media check */
2815 sony_usage++;
2816 return 0;
2817 }
2818
2819 if (sony_usage == 0) {
2820 if (scd_spinup() != 0)
2821 return -EIO;
2822 sony_get_toc();
2823 if (!sony_toc_read) {
2824 do_sony_cd_cmd(SONY_SPIN_DOWN_CMD, NULL, 0,
2825 res_reg, &res_size);
2826 return -EIO;
2827 }
2828
2829 /* For XA on the CDU31A only, we have to do special reads.
2830 The CDU33A handles XA automagically. */
2831 /* if ( (sony_toc.disk_type == SONY_XA_DISK_TYPE) */
2832 if ((sony_toc.disk_type != 0x00)
2833 && (!is_double_speed)) {
2834 params[0] = SONY_SD_DECODE_PARAM;
2835 params[1] = 0x07;
2836 do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
2837 params, 2, res_reg, &res_size);
2838 if ((res_size < 2)
2839 || ((res_reg[0] & 0xf0) == 0x20)) {
2840 printk(KERN_WARNING PFX "Unable to set "
2841 "XA params: 0x%2.2x\n", res_reg[1]);
2842 }
2843 sony_xa_mode = 1;
2844 }
2845 /* A non-XA disk. Set the parms back if necessary. */
2846 else if (sony_xa_mode) {
2847 params[0] = SONY_SD_DECODE_PARAM;
2848 params[1] = 0x0f;
2849 do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
2850 params, 2, res_reg, &res_size);
2851 if ((res_size < 2)
2852 || ((res_reg[0] & 0xf0) == 0x20)) {
2853 printk(KERN_WARNING PFX "Unable to reset "
2854 "XA params: 0x%2.2x\n", res_reg[1]);
2855 }
2856 sony_xa_mode = 0;
2857 }
2858
2859 sony_spun_up = 1;
2860 }
2861
2862 sony_usage++;
2863
2864 return 0;
2865}
2866
2867
2868/*
2869 * Close the drive. Spin it down if no task is using it. The spin
2870 * down will fail if playing audio, so audio play is OK.
2871 */
2872static void scd_release(struct cdrom_device_info *cdi)
2873{
2874 if (sony_usage == 1) {
2875 unsigned char res_reg[12];
2876 unsigned int res_size;
2877
2878 do_sony_cd_cmd(SONY_SPIN_DOWN_CMD, NULL, 0, res_reg,
2879 &res_size);
2880
2881 sony_spun_up = 0;
2882 }
2883 sony_usage--;
2884}
2885
2886static struct cdrom_device_ops scd_dops = {
2887 .open = scd_open,
2888 .release = scd_release,
2889 .drive_status = scd_drive_status,
2890 .media_changed = scd_media_changed,
2891 .tray_move = scd_tray_move,
2892 .lock_door = scd_lock_door,
2893 .select_speed = scd_select_speed,
2894 .get_last_session = scd_get_last_session,
2895 .get_mcn = scd_get_mcn,
2896 .reset = scd_reset,
2897 .audio_ioctl = scd_audio_ioctl,
2898 .capability = CDC_OPEN_TRAY | CDC_CLOSE_TRAY | CDC_LOCK |
2899 CDC_SELECT_SPEED | CDC_MULTI_SESSION |
2900 CDC_MCN | CDC_MEDIA_CHANGED | CDC_PLAY_AUDIO |
2901 CDC_RESET | CDC_DRIVE_STATUS,
2902 .n_minors = 1,
2903};
2904
2905static struct cdrom_device_info scd_info = {
2906 .ops = &scd_dops,
2907 .speed = 2,
2908 .capacity = 1,
2909 .name = "cdu31a"
2910};
2911
2912static int scd_block_open(struct inode *inode, struct file *file)
2913{
2914 return cdrom_open(&scd_info, inode, file);
2915}
2916
2917static int scd_block_release(struct inode *inode, struct file *file)
2918{
2919 return cdrom_release(&scd_info, file);
2920}
2921
2922static int scd_block_ioctl(struct inode *inode, struct file *file,
2923 unsigned cmd, unsigned long arg)
2924{
2925 int retval;
2926
2927 /* The eject and close commands should be handled by Uniform CD-ROM
2928 * driver - but I always got hard lockup instead of eject
2929 * until I put this here.
2930 */
2931 switch (cmd) {
2932 case CDROMEJECT:
2933 scd_lock_door(&scd_info, 0);
2934 retval = scd_tray_move(&scd_info, 1);
2935 break;
2936 case CDROMCLOSETRAY:
2937 retval = scd_tray_move(&scd_info, 0);
2938 break;
2939 case CDROMREADAUDIO:
2940 retval = scd_read_audio(&scd_info, CDROMREADAUDIO, arg);
2941 break;
2942 default:
2943 retval = cdrom_ioctl(file, &scd_info, inode, cmd, arg);
2944 }
2945 return retval;
2946}
2947
2948static int scd_block_media_changed(struct gendisk *disk)
2949{
2950 return cdrom_media_changed(&scd_info);
2951}
2952
2953static struct block_device_operations scd_bdops =
2954{
2955 .owner = THIS_MODULE,
2956 .open = scd_block_open,
2957 .release = scd_block_release,
2958 .ioctl = scd_block_ioctl,
2959 .media_changed = scd_block_media_changed,
2960};
2961
2962static struct gendisk *scd_gendisk;
2963
2964/* The different types of disc loading mechanisms supported */
2965static char *load_mech[] __initdata =
2966 { "caddy", "tray", "pop-up", "unknown" };
2967
2968static int __init
2969get_drive_configuration(unsigned short base_io,
2970 unsigned char res_reg[], unsigned int *res_size)
2971{
2972 unsigned long retry_count;
2973
2974
2975 if (!request_region(base_io, 4, "cdu31a"))
2976 return 0;
2977
2978 /* Set the base address */
2979 cdu31a_port = base_io;
2980
2981 /* Set up all the register locations */
2982 sony_cd_cmd_reg = cdu31a_port + SONY_CMD_REG_OFFSET;
2983 sony_cd_param_reg = cdu31a_port + SONY_PARAM_REG_OFFSET;
2984 sony_cd_write_reg = cdu31a_port + SONY_WRITE_REG_OFFSET;
2985 sony_cd_control_reg = cdu31a_port + SONY_CONTROL_REG_OFFSET;
2986 sony_cd_status_reg = cdu31a_port + SONY_STATUS_REG_OFFSET;
2987 sony_cd_result_reg = cdu31a_port + SONY_RESULT_REG_OFFSET;
2988 sony_cd_read_reg = cdu31a_port + SONY_READ_REG_OFFSET;
2989 sony_cd_fifost_reg = cdu31a_port + SONY_FIFOST_REG_OFFSET;
2990
2991 /*
2992 * Check to see if anything exists at the status register location.
2993 * I don't know if this is a good way to check, but it seems to work
2994 * ok for me.
2995 */
2996 if (read_status_register() != 0xff) {
2997 /*
2998 * Reset the drive and wait for attention from it (to say it's reset).
2999 * If you don't wait, the next operation will probably fail.
3000 */
3001 reset_drive();
3002 retry_count = jiffies + SONY_RESET_TIMEOUT;
3003 while (time_before(jiffies, retry_count)
3004 && (!is_attention())) {
3005 sony_sleep();
3006 }
3007
3008#if 0
3009 /* If attention is never seen probably not a CDU31a present */
3010 if (!is_attention()) {
3011 res_reg[0] = 0x20;
3012 goto out_err;
3013 }
3014#endif
3015
3016 /*
3017 * Get the drive configuration.
3018 */
3019 do_sony_cd_cmd(SONY_REQ_DRIVE_CONFIG_CMD,
3020 NULL,
3021 0, (unsigned char *) res_reg, res_size);
3022 if (*res_size <= 2 || (res_reg[0] & 0xf0) != 0)
3023 goto out_err;
3024 return 1;
3025 }
3026
3027 /* Return an error */
3028 res_reg[0] = 0x20;
3029out_err:
3030 release_region(cdu31a_port, 4);
3031 cdu31a_port = 0;
3032 return 0;
3033}
3034
3035#ifndef MODULE
3036/*
3037 * Set up base I/O and interrupts, called from main.c.
3038 */
3039
3040static int __init cdu31a_setup(char *strings)
3041{
3042 int ints[4];
3043
3044 (void) get_options(strings, ARRAY_SIZE(ints), ints);
3045
3046 if (ints[0] > 0) {
3047 cdu31a_port = ints[1];
3048 }
3049 if (ints[0] > 1) {
3050 cdu31a_irq = ints[2];
3051 }
3052 if ((strings != NULL) && (*strings != '\0')) {
3053 if (strcmp(strings, "PAS") == 0) {
3054 sony_pas_init = 1;
3055 } else {
3056 printk(KERN_NOTICE PFX "Unknown interface type: %s\n",
3057 strings);
3058 }
3059 }
3060
3061 return 1;
3062}
3063
3064__setup("cdu31a=", cdu31a_setup);
3065
3066#endif
3067
3068/*
3069 * Initialize the driver.
3070 */
3071int __init cdu31a_init(void)
3072{
3073 struct s_sony_drive_config drive_config;
3074 struct gendisk *disk;
3075 int deficiency = 0;
3076 unsigned int res_size;
3077 char msg[255];
3078 char buf[40];
3079 int i;
3080 int tmp_irq;
3081
3082 /*
3083 * According to Alex Freed (freed@europa.orion.adobe.com), this is
3084 * required for the Fusion CD-16 package. If the sound driver is
3085 * loaded, it should work fine, but just in case...
3086 *
3087 * The following turn on the CD-ROM interface for a Fusion CD-16.
3088 */
3089 if (sony_pas_init) {
3090 outb(0xbc, 0x9a01);
3091 outb(0xe2, 0x9a01);
3092 }
3093
3094 /* Setting the base I/O address to 0xffff will disable it. */
3095 if (cdu31a_port == 0xffff)
3096 goto errout3;
3097
3098 if (cdu31a_port != 0) {
3099 /* Need IRQ 0 because we can't sleep here. */
3100 tmp_irq = cdu31a_irq;
3101 cdu31a_irq = 0;
3102 if (!get_drive_configuration(cdu31a_port,
3103 drive_config.exec_status,
3104 &res_size))
3105 goto errout3;
3106 cdu31a_irq = tmp_irq;
3107 } else {
3108 cdu31a_irq = 0;
3109 for (i = 0; cdu31a_addresses[i].base; i++) {
3110 if (get_drive_configuration(cdu31a_addresses[i].base,
3111 drive_config.exec_status,
3112 &res_size)) {
3113 cdu31a_irq = cdu31a_addresses[i].int_num;
3114 break;
3115 }
3116 }
3117 if (!cdu31a_port)
3118 goto errout3;
3119 }
3120
3121 if (register_blkdev(MAJOR_NR, "cdu31a"))
3122 goto errout2;
3123
3124 disk = alloc_disk(1);
3125 if (!disk)
3126 goto errout1;
3127 disk->major = MAJOR_NR;
3128 disk->first_minor = 0;
3129 sprintf(disk->disk_name, "cdu31a");
3130 disk->fops = &scd_bdops;
3131 disk->flags = GENHD_FL_CD;
3132
3133 if (SONY_HWC_DOUBLE_SPEED(drive_config))
3134 is_double_speed = 1;
3135
3136 tmp_irq = cdu31a_irq; /* Need IRQ 0 because we can't sleep here. */
3137 cdu31a_irq = 0;
3138
3139 sony_speed = is_double_speed; /* Set 2X drives to 2X by default */
3140 set_drive_params(sony_speed);
3141
3142 cdu31a_irq = tmp_irq;
3143
3144 if (cdu31a_irq > 0) {
3145 if (request_irq
3146 (cdu31a_irq, cdu31a_interrupt, IRQF_DISABLED,
3147 "cdu31a", NULL)) {
3148 printk(KERN_WARNING PFX "Unable to grab IRQ%d for "
3149 "the CDU31A driver\n", cdu31a_irq);
3150 cdu31a_irq = 0;
3151 }
3152 }
3153
3154 sprintf(msg, "Sony I/F CDROM : %8.8s %16.16s %8.8s\n",
3155 drive_config.vendor_id,
3156 drive_config.product_id,
3157 drive_config.product_rev_level);
3158 sprintf(buf, " Capabilities: %s",
3159 load_mech[SONY_HWC_GET_LOAD_MECH(drive_config)]);
3160 strcat(msg, buf);
3161 if (SONY_HWC_AUDIO_PLAYBACK(drive_config))
3162 strcat(msg, ", audio");
3163 else
3164 deficiency |= CDC_PLAY_AUDIO;
3165 if (SONY_HWC_EJECT(drive_config))
3166 strcat(msg, ", eject");
3167 else
3168 deficiency |= CDC_OPEN_TRAY;
3169 if (SONY_HWC_LED_SUPPORT(drive_config))
3170 strcat(msg, ", LED");
3171 if (SONY_HWC_ELECTRIC_VOLUME(drive_config))
3172 strcat(msg, ", elec. Vol");
3173 if (SONY_HWC_ELECTRIC_VOLUME_CTL(drive_config))
3174 strcat(msg, ", sep. Vol");
3175 if (is_double_speed)
3176 strcat(msg, ", double speed");
3177 else
3178 deficiency |= CDC_SELECT_SPEED;
3179 if (cdu31a_irq > 0) {
3180 sprintf(buf, ", irq %d", cdu31a_irq);
3181 strcat(msg, buf);
3182 }
3183 strcat(msg, "\n");
3184 printk(KERN_INFO PFX "%s",msg);
3185
3186 cdu31a_queue = blk_init_queue(do_cdu31a_request, &cdu31a_lock);
3187 if (!cdu31a_queue)
3188 goto errout0;
3189 blk_queue_hardsect_size(cdu31a_queue, 2048);
3190
3191 init_timer(&cdu31a_abort_timer);
3192 cdu31a_abort_timer.function = handle_abort_timeout;
3193
3194 scd_info.mask = deficiency;
3195 scd_gendisk = disk;
3196 if (register_cdrom(&scd_info))
3197 goto err;
3198 disk->queue = cdu31a_queue;
3199 add_disk(disk);
3200
3201 disk_changed = 1;
3202 return 0;
3203
3204err:
3205 blk_cleanup_queue(cdu31a_queue);
3206errout0:
3207 if (cdu31a_irq)
3208 free_irq(cdu31a_irq, NULL);
3209 printk(KERN_ERR PFX "Unable to register with Uniform cdrom driver\n");
3210 put_disk(disk);
3211errout1:
3212 if (unregister_blkdev(MAJOR_NR, "cdu31a")) {
3213 printk(KERN_WARNING PFX "Can't unregister block device\n");
3214 }
3215errout2:
3216 release_region(cdu31a_port, 4);
3217errout3:
3218 return -EIO;
3219}
3220
3221
3222static void __exit cdu31a_exit(void)
3223{
3224 del_gendisk(scd_gendisk);
3225 put_disk(scd_gendisk);
3226 if (unregister_cdrom(&scd_info)) {
3227 printk(KERN_WARNING PFX "Can't unregister from Uniform "
3228 "cdrom driver\n");
3229 return;
3230 }
3231 if ((unregister_blkdev(MAJOR_NR, "cdu31a") == -EINVAL)) {
3232 printk(KERN_WARNING PFX "Can't unregister\n");
3233 return;
3234 }
3235
3236 blk_cleanup_queue(cdu31a_queue);
3237
3238 if (cdu31a_irq > 0)
3239 free_irq(cdu31a_irq, NULL);
3240
3241 release_region(cdu31a_port, 4);
3242 printk(KERN_INFO PFX "module released.\n");
3243}
3244
3245#ifdef MODULE
3246module_init(cdu31a_init);
3247#endif
3248module_exit(cdu31a_exit);
3249
3250MODULE_LICENSE("GPL");
3251MODULE_ALIAS_BLOCKDEV_MAJOR(CDU31A_CDROM_MAJOR);
diff --git a/drivers/cdrom/cdu31a.h b/drivers/cdrom/cdu31a.h
deleted file mode 100644
index 61d4768c412e..000000000000
--- a/drivers/cdrom/cdu31a.h
+++ /dev/null
@@ -1,411 +0,0 @@
1/*
2 * Definitions for a Sony interface CDROM drive.
3 *
4 * Corey Minyard (minyard@wf-rch.cirr.com)
5 *
6 * Copyright (C) 1993 Corey Minyard
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22 */
23
24/*
25 * General defines.
26 */
27#define SONY_XA_DISK_TYPE 0x20
28
29/*
30 * Offsets (from the base address) and bits for the various write registers
31 * of the drive.
32 */
33#define SONY_CMD_REG_OFFSET 0
34#define SONY_PARAM_REG_OFFSET 1
35#define SONY_WRITE_REG_OFFSET 2
36#define SONY_CONTROL_REG_OFFSET 3
37# define SONY_ATTN_CLR_BIT 0x01
38# define SONY_RES_RDY_CLR_BIT 0x02
39# define SONY_DATA_RDY_CLR_BIT 0x04
40# define SONY_ATTN_INT_EN_BIT 0x08
41# define SONY_RES_RDY_INT_EN_BIT 0x10
42# define SONY_DATA_RDY_INT_EN_BIT 0x20
43# define SONY_PARAM_CLR_BIT 0x40
44# define SONY_DRIVE_RESET_BIT 0x80
45
46/*
47 * Offsets (from the base address) and bits for the various read registers
48 * of the drive.
49 */
50#define SONY_STATUS_REG_OFFSET 0
51# define SONY_ATTN_BIT 0x01
52# define SONY_RES_RDY_BIT 0x02
53# define SONY_DATA_RDY_BIT 0x04
54# define SONY_ATTN_INT_ST_BIT 0x08
55# define SONY_RES_RDY_INT_ST_BIT 0x10
56# define SONY_DATA_RDY_INT_ST_BIT 0x20
57# define SONY_DATA_REQUEST_BIT 0x40
58# define SONY_BUSY_BIT 0x80
59#define SONY_RESULT_REG_OFFSET 1
60#define SONY_READ_REG_OFFSET 2
61#define SONY_FIFOST_REG_OFFSET 3
62# define SONY_PARAM_WRITE_RDY_BIT 0x01
63# define SONY_PARAM_REG_EMPTY_BIT 0x02
64# define SONY_RES_REG_NOT_EMP_BIT 0x04
65# define SONY_RES_REG_FULL_BIT 0x08
66
67#define LOG_START_OFFSET 150 /* Offset of first logical sector */
68
69#define SONY_DETECT_TIMEOUT (8*HZ/10) /* Maximum amount of time
70 that drive detection code
71 will wait for response
72 from drive (in 1/100th's
73 of seconds). */
74
75#define SONY_JIFFIES_TIMEOUT (10*HZ) /* Maximum number of times the
76 drive will wait/try for an
77 operation */
78#define SONY_RESET_TIMEOUT HZ /* Maximum number of times the
79 drive will wait/try a reset
80 operation */
81#define SONY_READY_RETRIES 20000 /* How many times to retry a
82 spin waiting for a register
83 to come ready */
84
85#define MAX_CDU31A_RETRIES 3 /* How many times to retry an
86 operation */
87
88/* Commands to request or set drive control parameters and disc information */
89#define SONY_REQ_DRIVE_CONFIG_CMD 0x00 /* Returns s_sony_drive_config */
90#define SONY_REQ_DRIVE_MODE_CMD 0x01
91#define SONY_REQ_DRIVE_PARAM_CMD 0x02
92#define SONY_REQ_MECH_STATUS_CMD 0x03
93#define SONY_REQ_AUDIO_STATUS_CMD 0x04
94#define SONY_SET_DRIVE_PARAM_CMD 0x10
95#define SONY_REQ_TOC_DATA_CMD 0x20 /* Returns s_sony_toc */
96#define SONY_REQ_SUBCODE_ADDRESS_CMD 0x21 /* Returns s_sony_subcode */
97#define SONY_REQ_UPC_EAN_CMD 0x22
98#define SONY_REQ_ISRC_CMD 0x23
99#define SONY_REQ_TOC_DATA_SPEC_CMD 0x24 /* Returns s_sony_session_toc */
100
101/* Commands to request information from the drive */
102#define SONY_READ_TOC_CMD 0x30 /* let the drive firmware grab the TOC */
103#define SONY_SEEK_CMD 0x31
104#define SONY_READ_CMD 0x32
105#define SONY_READ_BLKERR_STAT_CMD 0x34
106#define SONY_ABORT_CMD 0x35
107#define SONY_READ_TOC_SPEC_CMD 0x36
108
109/* Commands to control audio */
110#define SONY_AUDIO_PLAYBACK_CMD 0x40
111#define SONY_AUDIO_STOP_CMD 0x41
112#define SONY_AUDIO_SCAN_CMD 0x42
113
114/* Miscellaneous control commands */
115#define SONY_EJECT_CMD 0x50
116#define SONY_SPIN_UP_CMD 0x51
117#define SONY_SPIN_DOWN_CMD 0x52
118
119/* Diagnostic commands */
120#define SONY_WRITE_BUFFER_CMD 0x60
121#define SONY_READ_BUFFER_CMD 0x61
122#define SONY_DIAGNOSTICS_CMD 0x62
123
124
125/*
126 * The following are command parameters for the set drive parameter command
127 */
128#define SONY_SD_DECODE_PARAM 0x00
129#define SONY_SD_INTERFACE_PARAM 0x01
130#define SONY_SD_BUFFERING_PARAM 0x02
131#define SONY_SD_AUDIO_PARAM 0x03
132#define SONY_SD_AUDIO_VOLUME 0x04
133#define SONY_SD_MECH_CONTROL 0x05
134#define SONY_SD_AUTO_SPIN_DOWN_TIME 0x06
135
136/*
137 * The following are parameter bits for the mechanical control command
138 */
139#define SONY_AUTO_SPIN_UP_BIT 0x01
140#define SONY_AUTO_EJECT_BIT 0x02
141#define SONY_DOUBLE_SPEED_BIT 0x04
142
143/*
144 * The following extract information from the drive configuration about
145 * the drive itself.
146 */
147#define SONY_HWC_GET_LOAD_MECH(c) (c.hw_config[0] & 0x03)
148#define SONY_HWC_EJECT(c) (c.hw_config[0] & 0x04)
149#define SONY_HWC_LED_SUPPORT(c) (c.hw_config[0] & 0x08)
150#define SONY_HWC_DOUBLE_SPEED(c) (c.hw_config[0] & 0x10)
151#define SONY_HWC_GET_BUF_MEM_SIZE(c) ((c.hw_config[0] & 0xc0) >> 6)
152#define SONY_HWC_AUDIO_PLAYBACK(c) (c.hw_config[1] & 0x01)
153#define SONY_HWC_ELECTRIC_VOLUME(c) (c.hw_config[1] & 0x02)
154#define SONY_HWC_ELECTRIC_VOLUME_CTL(c) (c.hw_config[1] & 0x04)
155
156#define SONY_HWC_CADDY_LOAD_MECH 0x00
157#define SONY_HWC_TRAY_LOAD_MECH 0x01
158#define SONY_HWC_POPUP_LOAD_MECH 0x02
159#define SONY_HWC_UNKWN_LOAD_MECH 0x03
160
161#define SONY_HWC_8KB_BUFFER 0x00
162#define SONY_HWC_32KB_BUFFER 0x01
163#define SONY_HWC_64KB_BUFFER 0x02
164#define SONY_HWC_UNKWN_BUFFER 0x03
165
166/*
167 * This is the complete status returned from the drive configuration request
168 * command.
169 */
170struct s_sony_drive_config
171{
172 unsigned char exec_status[2];
173 char vendor_id[8];
174 char product_id[16];
175 char product_rev_level[8];
176 unsigned char hw_config[2];
177};
178
179/* The following is returned from the request subcode address command */
180struct s_sony_subcode
181{
182 unsigned char exec_status[2];
183 unsigned char address :4;
184 unsigned char control :4;
185 unsigned char track_num;
186 unsigned char index_num;
187 unsigned char rel_msf[3];
188 unsigned char reserved1;
189 unsigned char abs_msf[3];
190};
191
192#define MAX_TRACKS 100 /* The maximum tracks a disk may have. */
193/*
194 * The following is returned from the request TOC (Table Of Contents) command.
195 * (last_track_num-first_track_num+1) values are valid in tracks.
196 */
197struct s_sony_toc
198{
199 unsigned char exec_status[2];
200 unsigned char address0 :4;
201 unsigned char control0 :4;
202 unsigned char point0;
203 unsigned char first_track_num;
204 unsigned char disk_type;
205 unsigned char dummy0;
206 unsigned char address1 :4;
207 unsigned char control1 :4;
208 unsigned char point1;
209 unsigned char last_track_num;
210 unsigned char dummy1;
211 unsigned char dummy2;
212 unsigned char address2 :4;
213 unsigned char control2 :4;
214 unsigned char point2;
215 unsigned char lead_out_start_msf[3];
216 struct
217 {
218 unsigned char address :4;
219 unsigned char control :4;
220 unsigned char track;
221 unsigned char track_start_msf[3];
222 } tracks[MAX_TRACKS];
223
224 unsigned int lead_out_start_lba;
225};
226
227struct s_sony_session_toc
228{
229 unsigned char exec_status[2];
230 unsigned char session_number;
231 unsigned char address0 :4;
232 unsigned char control0 :4;
233 unsigned char point0;
234 unsigned char first_track_num;
235 unsigned char disk_type;
236 unsigned char dummy0;
237 unsigned char address1 :4;
238 unsigned char control1 :4;
239 unsigned char point1;
240 unsigned char last_track_num;
241 unsigned char dummy1;
242 unsigned char dummy2;
243 unsigned char address2 :4;
244 unsigned char control2 :4;
245 unsigned char point2;
246 unsigned char lead_out_start_msf[3];
247 unsigned char addressb0 :4;
248 unsigned char controlb0 :4;
249 unsigned char pointb0;
250 unsigned char next_poss_prog_area_msf[3];
251 unsigned char num_mode_5_pointers;
252 unsigned char max_start_outer_leadout_msf[3];
253 unsigned char addressb1 :4;
254 unsigned char controlb1 :4;
255 unsigned char pointb1;
256 unsigned char dummyb0_1[4];
257 unsigned char num_skip_interval_pointers;
258 unsigned char num_skip_track_assignments;
259 unsigned char dummyb0_2;
260 unsigned char addressb2 :4;
261 unsigned char controlb2 :4;
262 unsigned char pointb2;
263 unsigned char tracksb2[7];
264 unsigned char addressb3 :4;
265 unsigned char controlb3 :4;
266 unsigned char pointb3;
267 unsigned char tracksb3[7];
268 unsigned char addressb4 :4;
269 unsigned char controlb4 :4;
270 unsigned char pointb4;
271 unsigned char tracksb4[7];
272 unsigned char addressc0 :4;
273 unsigned char controlc0 :4;
274 unsigned char pointc0;
275 unsigned char dummyc0[7];
276 struct
277 {
278 unsigned char address :4;
279 unsigned char control :4;
280 unsigned char track;
281 unsigned char track_start_msf[3];
282 } tracks[MAX_TRACKS];
283
284 unsigned int start_track_lba;
285 unsigned int lead_out_start_lba;
286 unsigned int mint;
287 unsigned int maxt;
288};
289
290struct s_all_sessions_toc
291{
292 unsigned char sessions;
293 unsigned int track_entries;
294 unsigned char first_track_num;
295 unsigned char last_track_num;
296 unsigned char disk_type;
297 unsigned char lead_out_start_msf[3];
298 struct
299 {
300 unsigned char address :4;
301 unsigned char control :4;
302 unsigned char track;
303 unsigned char track_start_msf[3];
304 } tracks[MAX_TRACKS];
305
306 unsigned int start_track_lba;
307 unsigned int lead_out_start_lba;
308};
309
310
311/*
312 * The following are errors returned from the drive.
313 */
314
315/* Command error group */
316#define SONY_ILL_CMD_ERR 0x10
317#define SONY_ILL_PARAM_ERR 0x11
318
319/* Mechanism group */
320#define SONY_NOT_LOAD_ERR 0x20
321#define SONY_NO_DISK_ERR 0x21
322#define SONY_NOT_SPIN_ERR 0x22
323#define SONY_SPIN_ERR 0x23
324#define SONY_SPINDLE_SERVO_ERR 0x25
325#define SONY_FOCUS_SERVO_ERR 0x26
326#define SONY_EJECT_MECH_ERR 0x29
327#define SONY_AUDIO_PLAYING_ERR 0x2a
328#define SONY_EMERGENCY_EJECT_ERR 0x2c
329
330/* Seek error group */
331#define SONY_FOCUS_ERR 0x30
332#define SONY_FRAME_SYNC_ERR 0x31
333#define SONY_SUBCODE_ADDR_ERR 0x32
334#define SONY_BLOCK_SYNC_ERR 0x33
335#define SONY_HEADER_ADDR_ERR 0x34
336
337/* Read error group */
338#define SONY_ILL_TRACK_R_ERR 0x40
339#define SONY_MODE_0_R_ERR 0x41
340#define SONY_ILL_MODE_R_ERR 0x42
341#define SONY_ILL_BLOCK_SIZE_R_ERR 0x43
342#define SONY_MODE_R_ERR 0x44
343#define SONY_FORM_R_ERR 0x45
344#define SONY_LEAD_OUT_R_ERR 0x46
345#define SONY_BUFFER_OVERRUN_R_ERR 0x47
346
347/* Data error group */
348#define SONY_UNREC_CIRC_ERR 0x53
349#define SONY_UNREC_LECC_ERR 0x57
350
351/* Subcode error group */
352#define SONY_NO_TOC_ERR 0x60
353#define SONY_SUBCODE_DATA_NVAL_ERR 0x61
354#define SONY_FOCUS_ON_TOC_READ_ERR 0x63
355#define SONY_FRAME_SYNC_ON_TOC_READ_ERR 0x64
356#define SONY_TOC_DATA_ERR 0x65
357
358/* Hardware failure group */
359#define SONY_HW_FAILURE_ERR 0x70
360#define SONY_LEAD_IN_A_ERR 0x91
361#define SONY_LEAD_OUT_A_ERR 0x92
362#define SONY_DATA_TRACK_A_ERR 0x93
363
364/*
365 * The following are returned from the Read With Block Error Status command.
366 * They are not errors but information (Errors from the 0x5x group above may
367 * also be returned
368 */
369#define SONY_NO_CIRC_ERR_BLK_STAT 0x50
370#define SONY_NO_LECC_ERR_BLK_STAT 0x54
371#define SONY_RECOV_LECC_ERR_BLK_STAT 0x55
372#define SONY_NO_ERR_DETECTION_STAT 0x59
373
374/*
375 * The following is not an error returned by the drive, but by the code
376 * that talks to the drive. It is returned because of a timeout.
377 */
378#define SONY_TIMEOUT_OP_ERR 0x01
379#define SONY_SIGNAL_OP_ERR 0x02
380#define SONY_BAD_DATA_ERR 0x03
381
382
383/*
384 * The following are attention code for asynchronous events from the drive.
385 */
386
387/* Standard attention group */
388#define SONY_EMER_EJECT_ATTN 0x2c
389#define SONY_HW_FAILURE_ATTN 0x70
390#define SONY_MECH_LOADED_ATTN 0x80
391#define SONY_EJECT_PUSHED_ATTN 0x81
392
393/* Audio attention group */
394#define SONY_AUDIO_PLAY_DONE_ATTN 0x90
395#define SONY_LEAD_IN_ERR_ATTN 0x91
396#define SONY_LEAD_OUT_ERR_ATTN 0x92
397#define SONY_DATA_TRACK_ERR_ATTN 0x93
398#define SONY_AUDIO_PLAYBACK_ERR_ATTN 0x94
399
400/* Auto spin up group */
401#define SONY_SPIN_UP_COMPLETE_ATTN 0x24
402#define SONY_SPINDLE_SERVO_ERR_ATTN 0x25
403#define SONY_FOCUS_SERVO_ERR_ATTN 0x26
404#define SONY_TOC_READ_DONE_ATTN 0x62
405#define SONY_FOCUS_ON_TOC_READ_ERR_ATTN 0x63
406#define SONY_SYNC_ON_TOC_READ_ERR_ATTN 0x65
407
408/* Auto eject group */
409#define SONY_SPIN_DOWN_COMPLETE_ATTN 0x27
410#define SONY_EJECT_COMPLETE_ATTN 0x28
411#define SONY_EJECT_MECH_ERR_ATTN 0x29
diff --git a/drivers/cdrom/cm206.c b/drivers/cdrom/cm206.c
deleted file mode 100644
index 230131163240..000000000000
--- a/drivers/cdrom/cm206.c
+++ /dev/null
@@ -1,1594 +0,0 @@
1/* cm206.c. A linux-driver for the cm206 cdrom player with cm260 adapter card.
2 Copyright (c) 1995--1997 David A. van Leeuwen.
3 $Id: cm206.c,v 1.5 1997/12/26 11:02:51 david Exp $
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18
19History:
20 Started 25 jan 1994. Waiting for documentation...
21 22 feb 1995: 0.1a first reasonably safe polling driver.
22 Two major bugs, one in read_sector and one in
23 do_cm206_request, happened to cancel!
24 25 feb 1995: 0.2a first reasonable interrupt driven version of above.
25 uart writes are still done in polling mode.
26 25 feb 1995: 0.21a writes also in interrupt mode, still some
27 small bugs to be found... Larger buffer.
28 2 mrt 1995: 0.22 Bug found (cd-> nowhere, interrupt was called in
29 initialization), read_ahead of 16. Timeouts implemented.
30 unclear if they do something...
31 7 mrt 1995: 0.23 Start of background read-ahead.
32 18 mrt 1995: 0.24 Working background read-ahead. (still problems)
33 26 mrt 1995: 0.25 Multi-session ioctl added (kernel v1.2).
34 Statistics implemented, though separate stats206.h.
35 Accessible through ioctl 0x1000 (just a number).
36 Hard to choose between v1.2 development and 1.1.75.
37 Bottom-half doesn't work with 1.2...
38 0.25a: fixed... typo. Still problems...
39 1 apr 1995: 0.26 Module support added. Most bugs found. Use kernel 1.2.n.
40 5 apr 1995: 0.27 Auto-probe for the adapter card base address.
41 Auto-probe for the adaptor card irq line.
42 7 apr 1995: 0.28 Added lilo setup support for base address and irq.
43 Use major number 32 (not in this source), officially
44 assigned to this driver.
45 9 apr 1995: 0.29 Added very limited audio support. Toc_header, stop, pause,
46 resume, eject. Play_track ignores track info, because we can't
47 read a table-of-contents entry. Toc_entry is implemented
48 as a `placebo' function: always returns start of disc.
49 3 may 1995: 0.30 Audio support completed. The get_toc_entry function
50 is implemented as a binary search.
51 15 may 1995: 0.31 More work on audio stuff. Workman is not easy to
52 satisfy; changed binary search into linear search.
53 Auto-probe for base address somewhat relaxed.
54 1 jun 1995: 0.32 Removed probe_irq_on/off for module version.
55 10 jun 1995: 0.33 Workman still behaves funny, but you should be
56 able to eject and substitute another disc.
57
58 An adaptation of 0.33 is included in linux-1.3.7 by Eberhard Moenkeberg
59
60 18 jul 1995: 0.34 Patch by Heiko Eissfeldt included, mainly considering
61 verify_area's in the ioctls. Some bugs introduced by
62 EM considering the base port and irq fixed.
63
64 18 dec 1995: 0.35 Add some code for error checking... no luck...
65
66 We jump to reach our goal: version 1.0 in the next stable linux kernel.
67
68 19 mar 1996: 0.95 Different implementation of CDROM_GET_UPC, on
69 request of Thomas Quinot.
70 25 mar 1996: 0.96 Interpretation of opening with O_WRONLY or O_RDWR:
71 open only for ioctl operation, e.g., for operation of
72 tray etc.
73 4 apr 1996: 0.97 First implementation of layer between VFS and cdrom
74 driver, a generic interface. Much of the functionality
75 of cm206_open() and cm206_ioctl() is transferred to a
76 new file cdrom.c and its header ucdrom.h.
77
78 Upgrade to Linux kernel 1.3.78.
79
80 11 apr 1996 0.98 Upgrade to Linux kernel 1.3.85
81 More code moved to cdrom.c
82
83 0.99 Some more small changes to decrease number
84 of oopses at module load;
85
86 27 jul 1996 0.100 Many hours of debugging, kernel change from 1.2.13
87 to 2.0.7 seems to have introduced some weird behavior
88 in (interruptible_)sleep_on(&cd->data): the process
89 seems to be woken without any explicit wake_up in my own
90 code. Patch to try 100x in case such untriggered wake_up's
91 occur.
92
93 28 jul 1996 0.101 Rewriting of the code that receives the command echo,
94 using a fifo to store echoed bytes.
95
96 Branch from 0.99:
97
98 0.99.1.0 Update to kernel release 2.0.10 dev_t -> kdev_t
99 (emoenke) various typos found by others. extra
100 module-load oops protection.
101
102 0.99.1.1 Initialization constant cdrom_dops.speed
103 changed from float (2.0) to int (2); Cli()-sti() pair
104 around cm260_reset() in module initialization code.
105
106 0.99.1.2 Changes literally as proposed by Scott Snyder
107 <snyder@d0sgif.fnal.gov> for the 2.1 kernel line, which
108 have to do mainly with the poor minor support i had. The
109 major new concept is to change a cdrom driver's
110 operations struct from the capabilities struct. This
111 reflects the fact that there is one major for a driver,
112 whilst there can be many minors whith completely
113 different capabilities.
114
115 0.99.1.3 More changes for operations/info separation.
116
117 0.99.1.4 Added speed selection (someone had to do this
118 first).
119
120 23 jan 1997 0.99.1.5 MODULE_PARMS call added.
121
122 23 jan 1997 0.100.1.2--0.100.1.5 following similar lines as
123 0.99.1.1--0.99.1.5. I get too many complaints about the
124 drive making read errors. What't wrong with the 2.0+
125 kernel line? Why get i (and othe cm206 owners) weird
126 results? Why were things good in the good old 1.1--1.2
127 era? Why don't i throw away the drive?
128
129 2 feb 1997 0.102 Added `volatile' to values in cm206_struct. Seems to
130 reduce many of the problems. Rewrote polling routines
131 to use fixed delays between polls.
132 0.103 Changed printk behavior.
133 0.104 Added a 0.100 -> 0.100.1.1 change
134
13511 feb 1997 0.105 Allow auto_probe during module load, disable
136 with module option "auto_probe=0". Moved some debugging
137 statements to lower priority. Implemented select_speed()
138 function.
139
14013 feb 1997 1.0 Final version for 2.0 kernel line.
141
142 All following changes will be for the 2.1 kernel line.
143
14415 feb 1997 1.1 Keep up with kernel 2.1.26, merge in changes from
145 cdrom.c 0.100.1.1--1.0. Add some more MODULE_PARMS.
146
14714 sep 1997 1.2 Upgrade to Linux 2.1.55. Added blksize_size[], patch
148 sent by James Bottomley <James.Bottomley@columbiasc.ncr.com>.
149
15021 dec 1997 1.4 Upgrade to Linux 2.1.72.
151
15224 jan 1998 Removed the cm206_disc_status() function, as it was now dead
153 code. The Uniform CDROM driver now provides this functionality.
154
1559 Nov. 1999 Make kernel-parameter implementation work with 2.3.x
156 Removed init_module & cleanup_module in favor of
157 module_init & module_exit.
158 Torben Mathiasen <tmm@image.dk>
159 *
160 * Parts of the code are based upon lmscd.c written by Kai Petzke,
161 * sbpcd.c written by Eberhard Moenkeberg, and mcd.c by Martin
162 * Harriss, but any off-the-shelf dynamic programming algorithm won't
163 * be able to find them.
164 *
165 * The cm206 drive interface and the cm260 adapter card seem to be
166 * sufficiently different from their cm205/cm250 counterparts
167 * in order to write a complete new driver.
168 *
169 * I call all routines connected to the Linux kernel something
170 * with `cm206' in it, as this stuff is too series-dependent.
171 *
172 * Currently, my limited knowledge is based on:
173 * - The Linux Kernel Hacker's guide, v. 0.5, by Michael K. Johnson
174 * - Linux Kernel Programmierung, by Michael Beck and others
175 * - Philips/LMS cm206 and cm226 product specification
176 * - Philips/LMS cm260 product specification
177 *
178 * David van Leeuwen, david@tm.tno.nl. */
179#define REVISION "$Revision: 1.5 $"
180
181#include <linux/module.h>
182
183#include <linux/errno.h> /* These include what we really need */
184#include <linux/delay.h>
185#include <linux/string.h>
186#include <linux/interrupt.h>
187#include <linux/timer.h>
188#include <linux/cdrom.h>
189#include <linux/ioport.h>
190#include <linux/mm.h>
191#include <linux/slab.h>
192#include <linux/init.h>
193
194/* #include <linux/ucdrom.h> */
195
196#include <asm/io.h>
197
198#define MAJOR_NR CM206_CDROM_MAJOR
199
200#include <linux/blkdev.h>
201
202#undef DEBUG
203#define STATISTICS /* record times and frequencies of events */
204#define AUTO_PROBE_MODULE
205#define USE_INSW
206
207#include "cm206.h"
208
209/* This variable defines whether or not to probe for adapter base port
210 address and interrupt request. It can be overridden by the boot
211 parameter `auto'.
212*/
213static int auto_probe = 1; /* Yes, why not? */
214
215static int cm206_base = CM206_BASE;
216static int cm206_irq = CM206_IRQ;
217#ifdef MODULE
218static int cm206[2] = { 0, 0 }; /* for compatible `insmod' parameter passing */
219module_param_array(cm206, int, NULL, 0); /* base,irq or irq,base */
220#endif
221
222module_param(cm206_base, int, 0); /* base */
223module_param(cm206_irq, int, 0); /* irq */
224module_param(auto_probe, bool, 0); /* auto probe base and irq */
225MODULE_LICENSE("GPL");
226
227#define POLLOOP 100 /* milliseconds */
228#define READ_AHEAD 1 /* defines private buffer, waste! */
229#define BACK_AHEAD 1 /* defines adapter-read ahead */
230#define DATA_TIMEOUT (3*HZ) /* measured in jiffies (10 ms) */
231#define UART_TIMEOUT (5*HZ/100)
232#define DSB_TIMEOUT (7*HZ) /* time for the slowest command to finish */
233#define UR_SIZE 4 /* uart receive buffer fifo size */
234
235#define LINUX_BLOCK_SIZE 512 /* WHERE is this defined? */
236#define RAW_SECTOR_SIZE 2352 /* ok, is also defined in cdrom.h */
237#define ISO_SECTOR_SIZE 2048
238#define BLOCKS_ISO (ISO_SECTOR_SIZE/LINUX_BLOCK_SIZE) /* 4 */
239#define CD_SYNC_HEAD 16 /* CD_SYNC + CD_HEAD */
240
241#ifdef STATISTICS /* keep track of errors in counters */
242#define stats(i) { ++cd->stats[st_ ## i]; \
243 cd->last_stat[st_ ## i] = cd->stat_counter++; \
244 }
245#else
246#define stats(i) (void) 0;
247#endif
248
249#define Debug(a) {printk (KERN_DEBUG); printk a;}
250#ifdef DEBUG
251#define debug(a) Debug(a)
252#else
253#define debug(a) (void) 0;
254#endif
255
256typedef unsigned char uch; /* 8-bits */
257typedef unsigned short ush; /* 16-bits */
258
259struct toc_struct { /* private copy of Table of Contents */
260 uch track, fsm[3], q0;
261};
262
263struct cm206_struct {
264 volatile ush intr_ds; /* data status read on last interrupt */
265 volatile ush intr_ls; /* uart line status read on last interrupt */
266 volatile uch ur[UR_SIZE]; /* uart receive buffer fifo */
267 volatile uch ur_w, ur_r; /* write/read buffer index */
268 volatile uch dsb, cc; /* drive status byte and condition (error) code */
269 int command; /* command to be written to the uart */
270 int openfiles;
271 ush sector[READ_AHEAD * RAW_SECTOR_SIZE / 2]; /* buffered cd-sector */
272 int sector_first, sector_last; /* range of these sectors */
273 wait_queue_head_t uart; /* wait queues for interrupt */
274 wait_queue_head_t data;
275 struct timer_list timer; /* time-out */
276 char timed_out;
277 signed char max_sectors; /* number of sectors that fit in adapter mem */
278 char wait_back; /* we're waiting for a background-read */
279 char background; /* is a read going on in the background? */
280 int adapter_first; /* if so, that's the starting sector */
281 int adapter_last;
282 char fifo_overflowed;
283 uch disc_status[7]; /* result of get_disc_status command */
284#ifdef STATISTICS
285 int stats[NR_STATS];
286 int last_stat[NR_STATS]; /* `time' at which stat was stat */
287 int stat_counter;
288#endif
289 struct toc_struct toc[101]; /* The whole table of contents + lead-out */
290 uch q[10]; /* Last read q-channel info */
291 uch audio_status[5]; /* last read position on pause */
292 uch media_changed; /* record if media changed */
293};
294
295#define DISC_STATUS cd->disc_status[0]
296#define FIRST_TRACK cd->disc_status[1]
297#define LAST_TRACK cd->disc_status[2]
298#define PAUSED cd->audio_status[0] /* misuse this memory byte! */
299#define PLAY_TO cd->toc[0] /* toc[0] records end-time in play */
300
301static struct cm206_struct *cd; /* the main memory structure */
302static struct request_queue *cm206_queue;
303static DEFINE_SPINLOCK(cm206_lock);
304
305/* First, we define some polling functions. These are actually
306 only being used in the initialization. */
307
308static void send_command_polled(int command)
309{
310 int loop = POLLOOP;
311 while (!(inw(r_line_status) & ls_transmitter_buffer_empty)
312 && loop > 0) {
313 mdelay(1); /* one millisec delay */
314 --loop;
315 }
316 outw(command, r_uart_transmit);
317}
318
319static uch receive_echo_polled(void)
320{
321 int loop = POLLOOP;
322 while (!(inw(r_line_status) & ls_receive_buffer_full) && loop > 0) {
323 mdelay(1);
324 --loop;
325 }
326 return ((uch) inw(r_uart_receive));
327}
328
329static uch send_receive_polled(int command)
330{
331 send_command_polled(command);
332 return receive_echo_polled();
333}
334
335static inline void clear_ur(void)
336{
337 if (cd->ur_r != cd->ur_w) {
338 debug(("Deleting bytes from fifo:"));
339 for (; cd->ur_r != cd->ur_w;
340 cd->ur_r++, cd->ur_r %= UR_SIZE)
341 debug((" 0x%x", cd->ur[cd->ur_r]));
342 debug(("\n"));
343 }
344}
345
346static struct tasklet_struct cm206_tasklet;
347
348/* The interrupt handler. When the cm260 generates an interrupt, very
349 much care has to be taken in reading out the registers in the right
350 order; in case of a receive_buffer_full interrupt, first the
351 uart_receive must be read, and then the line status again to
352 de-assert the interrupt line. It took me a couple of hours to find
353 this out:-(
354
355 The function reset_cm206 appears to cause an interrupt, because
356 pulling up the INIT line clears both the uart-write-buffer /and/
357 the uart-write-buffer-empty mask. We call this a `lost interrupt,'
358 as there seems so reason for this to happen.
359*/
360
361static irqreturn_t cm206_interrupt(int sig, void *dev_id)
362{
363 volatile ush fool;
364 cd->intr_ds = inw(r_data_status); /* resets data_ready, data_error,
365 crc_error, sync_error, toc_ready
366 interrupts */
367 cd->intr_ls = inw(r_line_status); /* resets overrun bit */
368 debug(("Intr, 0x%x 0x%x, %d\n", cd->intr_ds, cd->intr_ls,
369 cd->background));
370 if (cd->intr_ls & ls_attention)
371 stats(attention);
372 /* receive buffer full? */
373 if (cd->intr_ls & ls_receive_buffer_full) {
374 cd->ur[cd->ur_w] = inb(r_uart_receive); /* get order right! */
375 cd->intr_ls = inw(r_line_status); /* resets rbf interrupt */
376 debug(("receiving #%d: 0x%x\n", cd->ur_w,
377 cd->ur[cd->ur_w]));
378 cd->ur_w++;
379 cd->ur_w %= UR_SIZE;
380 if (cd->ur_w == cd->ur_r)
381 debug(("cd->ur overflow!\n"));
382 if (waitqueue_active(&cd->uart) && cd->background < 2) {
383 del_timer(&cd->timer);
384 wake_up_interruptible(&cd->uart);
385 }
386 }
387 /* data ready in fifo? */
388 else if (cd->intr_ds & ds_data_ready) {
389 if (cd->background)
390 ++cd->adapter_last;
391 if (waitqueue_active(&cd->data)
392 && (cd->wait_back || !cd->background)) {
393 del_timer(&cd->timer);
394 wake_up_interruptible(&cd->data);
395 }
396 stats(data_ready);
397 }
398 /* ready to issue a write command? */
399 else if (cd->command && cd->intr_ls & ls_transmitter_buffer_empty) {
400 outw(dc_normal | (inw(r_data_status) & 0x7f),
401 r_data_control);
402 outw(cd->command, r_uart_transmit);
403 cd->command = 0;
404 if (!cd->background)
405 wake_up_interruptible(&cd->uart);
406 }
407 /* now treat errors (at least, identify them for debugging) */
408 else if (cd->intr_ds & ds_fifo_overflow) {
409 debug(("Fifo overflow at sectors 0x%x\n",
410 cd->sector_first));
411 fool = inw(r_fifo_output_buffer); /* de-assert the interrupt */
412 cd->fifo_overflowed = 1; /* signal one word less should be read */
413 stats(fifo_overflow);
414 } else if (cd->intr_ds & ds_data_error) {
415 debug(("Data error at sector 0x%x\n", cd->sector_first));
416 stats(data_error);
417 } else if (cd->intr_ds & ds_crc_error) {
418 debug(("CRC error at sector 0x%x\n", cd->sector_first));
419 stats(crc_error);
420 } else if (cd->intr_ds & ds_sync_error) {
421 debug(("Sync at sector 0x%x\n", cd->sector_first));
422 stats(sync_error);
423 } else if (cd->intr_ds & ds_toc_ready) {
424 /* do something appropriate */
425 }
426 /* couldn't see why this interrupt, maybe due to init */
427 else {
428 outw(dc_normal | READ_AHEAD, r_data_control);
429 stats(lost_intr);
430 }
431 if (cd->background
432 && (cd->adapter_last - cd->adapter_first == cd->max_sectors
433 || cd->fifo_overflowed))
434 tasklet_schedule(&cm206_tasklet); /* issue a stop read command */
435 stats(interrupt);
436 return IRQ_HANDLED;
437}
438
439/* we have put the address of the wait queue in who */
440static void cm206_timeout(unsigned long who)
441{
442 cd->timed_out = 1;
443 debug(("Timing out\n"));
444 wake_up_interruptible((wait_queue_head_t *) who);
445}
446
447/* This function returns 1 if a timeout occurred, 0 if an interrupt
448 happened */
449static int sleep_or_timeout(wait_queue_head_t * wait, int timeout)
450{
451 cd->timed_out = 0;
452 init_timer(&cd->timer);
453 cd->timer.data = (unsigned long) wait;
454 cd->timer.expires = jiffies + timeout;
455 add_timer(&cd->timer);
456 debug(("going to sleep\n"));
457 interruptible_sleep_on(wait);
458 del_timer(&cd->timer);
459 if (cd->timed_out) {
460 cd->timed_out = 0;
461 return 1;
462 } else
463 return 0;
464}
465
466static void send_command(int command)
467{
468 debug(("Sending 0x%x\n", command));
469 if (!(inw(r_line_status) & ls_transmitter_buffer_empty)) {
470 cd->command = command;
471 cli(); /* don't interrupt before sleep */
472 outw(dc_mask_sync_error | dc_no_stop_on_error |
473 (inw(r_data_status) & 0x7f), r_data_control);
474 /* interrupt routine sends command */
475 if (sleep_or_timeout(&cd->uart, UART_TIMEOUT)) {
476 debug(("Time out on write-buffer\n"));
477 stats(write_timeout);
478 outw(command, r_uart_transmit);
479 }
480 debug(("Write commmand delayed\n"));
481 } else
482 outw(command, r_uart_transmit);
483}
484
485static uch receive_byte(int timeout)
486{
487 uch ret;
488 cli();
489 debug(("cli\n"));
490 ret = cd->ur[cd->ur_r];
491 if (cd->ur_r != cd->ur_w) {
492 sti();
493 debug(("returning #%d: 0x%x\n", cd->ur_r,
494 cd->ur[cd->ur_r]));
495 cd->ur_r++;
496 cd->ur_r %= UR_SIZE;
497 return ret;
498 } else if (sleep_or_timeout(&cd->uart, timeout)) { /* does sti() */
499 debug(("Time out on receive-buffer\n"));
500#ifdef STATISTICS
501 if (timeout == UART_TIMEOUT)
502 stats(receive_timeout) /* no `;'! */
503 else
504 stats(dsb_timeout);
505#endif
506 return 0xda;
507 }
508 ret = cd->ur[cd->ur_r];
509 debug(("slept; returning #%d: 0x%x\n", cd->ur_r,
510 cd->ur[cd->ur_r]));
511 cd->ur_r++;
512 cd->ur_r %= UR_SIZE;
513 return ret;
514}
515
516static inline uch receive_echo(void)
517{
518 return receive_byte(UART_TIMEOUT);
519}
520
521static inline uch send_receive(int command)
522{
523 send_command(command);
524 return receive_echo();
525}
526
527static inline uch wait_dsb(void)
528{
529 return receive_byte(DSB_TIMEOUT);
530}
531
532static int type_0_command(int command, int expect_dsb)
533{
534 int e;
535 clear_ur();
536 if (command != (e = send_receive(command))) {
537 debug(("command 0x%x echoed as 0x%x\n", command, e));
538 stats(echo);
539 return -1;
540 }
541 if (expect_dsb) {
542 cd->dsb = wait_dsb(); /* wait for command to finish */
543 }
544 return 0;
545}
546
547static int type_1_command(int command, int bytes, uch * status)
548{ /* returns info */
549 int i;
550 if (type_0_command(command, 0))
551 return -1;
552 for (i = 0; i < bytes; i++)
553 status[i] = send_receive(c_gimme);
554 return 0;
555}
556
557/* This function resets the adapter card. We'd better not do this too
558 * often, because it tends to generate `lost interrupts.' */
559static void reset_cm260(void)
560{
561 outw(dc_normal | dc_initialize | READ_AHEAD, r_data_control);
562 udelay(10); /* 3.3 mu sec minimum */
563 outw(dc_normal | READ_AHEAD, r_data_control);
564}
565
566/* fsm: frame-sec-min from linear address; one of many */
567static void fsm(int lba, uch * fsm)
568{
569 fsm[0] = lba % 75;
570 lba /= 75;
571 lba += 2;
572 fsm[1] = lba % 60;
573 fsm[2] = lba / 60;
574}
575
576static inline int fsm2lba(uch * fsm)
577{
578 return fsm[0] + 75 * (fsm[1] - 2 + 60 * fsm[2]);
579}
580
581static inline int f_s_m2lba(uch f, uch s, uch m)
582{
583 return f + 75 * (s - 2 + 60 * m);
584}
585
586static int start_read(int start)
587{
588 uch read_sector[4] = { c_read_data, };
589 int i, e;
590
591 fsm(start, &read_sector[1]);
592 clear_ur();
593 for (i = 0; i < 4; i++)
594 if (read_sector[i] != (e = send_receive(read_sector[i]))) {
595 debug(("read_sector: %x echoes %x\n",
596 read_sector[i], e));
597 stats(echo);
598 if (e == 0xff) { /* this seems to happen often */
599 e = receive_echo();
600 debug(("Second try %x\n", e));
601 if (e != read_sector[i])
602 return -1;
603 }
604 }
605 return 0;
606}
607
608static int stop_read(void)
609{
610 int e;
611 type_0_command(c_stop, 0);
612 if ((e = receive_echo()) != 0xff) {
613 debug(("c_stop didn't send 0xff, but 0x%x\n", e));
614 stats(stop_0xff);
615 return -1;
616 }
617 return 0;
618}
619
620/* This function starts to read sectors in adapter memory, the
621 interrupt routine should stop the read. In fact, the bottom_half
622 routine takes care of this. Set a flag `background' in the cd
623 struct to indicate the process. */
624
625static int read_background(int start, int reading)
626{
627 if (cd->background)
628 return -1; /* can't do twice */
629 outw(dc_normal | BACK_AHEAD, r_data_control);
630 if (!reading && start_read(start))
631 return -2;
632 cd->adapter_first = cd->adapter_last = start;
633 cd->background = 1; /* flag a read is going on */
634 return 0;
635}
636
637#ifdef USE_INSW
638#define transport_data insw
639#else
640/* this routine implements insw(,,). There was a time i had the
641 impression that there would be any difference in error-behaviour. */
642void transport_data(int port, ush * dest, int count)
643{
644 int i;
645 ush *d;
646 for (i = 0, d = dest; i < count; i++, d++)
647 *d = inw(port);
648}
649#endif
650
651
652#define MAX_TRIES 100
653static int read_sector(int start)
654{
655 int tries = 0;
656 if (cd->background) {
657 cd->background = 0;
658 cd->adapter_last = -1; /* invalidate adapter memory */
659 stop_read();
660 }
661 cd->fifo_overflowed = 0;
662 reset_cm260(); /* empty fifo etc. */
663 if (start_read(start))
664 return -1;
665 do {
666 if (sleep_or_timeout(&cd->data, DATA_TIMEOUT)) {
667 debug(("Read timed out sector 0x%x\n", start));
668 stats(read_timeout);
669 stop_read();
670 return -3;
671 }
672 tries++;
673 } while (cd->intr_ds & ds_fifo_empty && tries < MAX_TRIES);
674 if (tries > 1)
675 debug(("Took me some tries\n"))
676 else
677 if (tries == MAX_TRIES)
678 debug(("MAX_TRIES tries for read sector\n"));
679 transport_data(r_fifo_output_buffer, cd->sector,
680 READ_AHEAD * RAW_SECTOR_SIZE / 2);
681 if (read_background(start + READ_AHEAD, 1))
682 stats(read_background);
683 cd->sector_first = start;
684 cd->sector_last = start + READ_AHEAD;
685 stats(read_restarted);
686 return 0;
687}
688
689/* The function of bottom-half is to send a stop command to the drive
690 This isn't easy because the routine is not `owned' by any process;
691 we can't go to sleep! The variable cd->background gives the status:
692 0 no read pending
693 1 a read is pending
694 2 c_stop waits for write_buffer_empty
695 3 c_stop waits for receive_buffer_full: echo
696 4 c_stop waits for receive_buffer_full: 0xff
697*/
698
699static void cm206_tasklet_func(unsigned long ignore)
700{
701 debug(("bh: %d\n", cd->background));
702 switch (cd->background) {
703 case 1:
704 stats(bh);
705 if (!(cd->intr_ls & ls_transmitter_buffer_empty)) {
706 cd->command = c_stop;
707 outw(dc_mask_sync_error | dc_no_stop_on_error |
708 (inw(r_data_status) & 0x7f), r_data_control);
709 cd->background = 2;
710 break; /* we'd better not time-out here! */
711 } else
712 outw(c_stop, r_uart_transmit);
713 /* fall into case 2: */
714 case 2:
715 /* the write has been satisfied by interrupt routine */
716 cd->background = 3;
717 break;
718 case 3:
719 if (cd->ur_r != cd->ur_w) {
720 if (cd->ur[cd->ur_r] != c_stop) {
721 debug(("cm206_bh: c_stop echoed 0x%x\n",
722 cd->ur[cd->ur_r]));
723 stats(echo);
724 }
725 cd->ur_r++;
726 cd->ur_r %= UR_SIZE;
727 }
728 cd->background++;
729 break;
730 case 4:
731 if (cd->ur_r != cd->ur_w) {
732 if (cd->ur[cd->ur_r] != 0xff) {
733 debug(("cm206_bh: c_stop reacted with 0x%x\n", cd->ur[cd->ur_r]));
734 stats(stop_0xff);
735 }
736 cd->ur_r++;
737 cd->ur_r %= UR_SIZE;
738 }
739 cd->background = 0;
740 }
741}
742
743static DECLARE_TASKLET(cm206_tasklet, cm206_tasklet_func, 0);
744
745/* This command clears the dsb_possible_media_change flag, so we must
746 * retain it.
747 */
748static void get_drive_status(void)
749{
750 uch status[2];
751 type_1_command(c_drive_status, 2, status); /* this might be done faster */
752 cd->dsb = status[0];
753 cd->cc = status[1];
754 cd->media_changed |=
755 !!(cd->dsb & (dsb_possible_media_change |
756 dsb_drive_not_ready | dsb_tray_not_closed));
757}
758
759static void get_disc_status(void)
760{
761 if (type_1_command(c_disc_status, 7, cd->disc_status)) {
762 debug(("get_disc_status: error\n"));
763 }
764}
765
766/* The new open. The real opening strategy is defined in cdrom.c. */
767
768static int cm206_open(struct cdrom_device_info *cdi, int purpose)
769{
770 if (!cd->openfiles) { /* reset only first time */
771 cd->background = 0;
772 reset_cm260();
773 cd->adapter_last = -1; /* invalidate adapter memory */
774 cd->sector_last = -1;
775 }
776 ++cd->openfiles;
777 stats(open);
778 return 0;
779}
780
781static void cm206_release(struct cdrom_device_info *cdi)
782{
783 if (cd->openfiles == 1) {
784 if (cd->background) {
785 cd->background = 0;
786 stop_read();
787 }
788 cd->sector_last = -1; /* Make our internal buffer invalid */
789 FIRST_TRACK = 0; /* No valid disc status */
790 }
791 --cd->openfiles;
792}
793
794/* Empty buffer empties $sectors$ sectors of the adapter card buffer,
795 * and then reads a sector in kernel memory. */
796static void empty_buffer(int sectors)
797{
798 while (sectors >= 0) {
799 transport_data(r_fifo_output_buffer,
800 cd->sector + cd->fifo_overflowed,
801 RAW_SECTOR_SIZE / 2 - cd->fifo_overflowed);
802 --sectors;
803 ++cd->adapter_first; /* update the current adapter sector */
804 cd->fifo_overflowed = 0; /* reset overflow bit */
805 stats(sector_transferred);
806 }
807 cd->sector_first = cd->adapter_first - 1;
808 cd->sector_last = cd->adapter_first; /* update the buffer sector */
809}
810
811/* try_adapter. This function determines if the requested sector is
812 in adapter memory, or will appear there soon. Returns 0 upon
813 success */
814static int try_adapter(int sector)
815{
816 if (cd->adapter_first <= sector && sector < cd->adapter_last) {
817 /* sector is in adapter memory */
818 empty_buffer(sector - cd->adapter_first);
819 return 0;
820 } else if (cd->background == 1 && cd->adapter_first <= sector
821 && sector < cd->adapter_first + cd->max_sectors) {
822 /* a read is going on, we can wait for it */
823 cd->wait_back = 1;
824 while (sector >= cd->adapter_last) {
825 if (sleep_or_timeout(&cd->data, DATA_TIMEOUT)) {
826 debug(("Timed out during background wait: %d %d %d %d\n", sector, cd->adapter_last, cd->adapter_first, cd->background));
827 stats(back_read_timeout);
828 cd->wait_back = 0;
829 return -1;
830 }
831 }
832 cd->wait_back = 0;
833 empty_buffer(sector - cd->adapter_first);
834 return 0;
835 } else
836 return -2;
837}
838
839/* This is not a very smart implementation. We could optimize for
840 consecutive block numbers. I'm not convinced this would really
841 bring down the processor load. */
842static void do_cm206_request(request_queue_t * q)
843{
844 long int i, cd_sec_no;
845 int quarter, error;
846 uch *source, *dest;
847 struct request *req;
848
849 while (1) { /* repeat until all requests have been satisfied */
850 req = elv_next_request(q);
851 if (!req)
852 return;
853
854 if (req->cmd != READ) {
855 debug(("Non-read command %d on cdrom\n", req->cmd));
856 end_request(req, 0);
857 continue;
858 }
859 spin_unlock_irq(q->queue_lock);
860 error = 0;
861 for (i = 0; i < req->nr_sectors; i++) {
862 int e1, e2;
863 cd_sec_no = (req->sector + i) / BLOCKS_ISO; /* 4 times 512 bytes */
864 quarter = (req->sector + i) % BLOCKS_ISO;
865 dest = req->buffer + i * LINUX_BLOCK_SIZE;
866 /* is already in buffer memory? */
867 if (cd->sector_first <= cd_sec_no
868 && cd_sec_no < cd->sector_last) {
869 source =
870 ((uch *) cd->sector) + 16 +
871 quarter * LINUX_BLOCK_SIZE +
872 (cd_sec_no -
873 cd->sector_first) * RAW_SECTOR_SIZE;
874 memcpy(dest, source, LINUX_BLOCK_SIZE);
875 } else if (!(e1 = try_adapter(cd_sec_no)) ||
876 !(e2 = read_sector(cd_sec_no))) {
877 source =
878 ((uch *) cd->sector) + 16 +
879 quarter * LINUX_BLOCK_SIZE;
880 memcpy(dest, source, LINUX_BLOCK_SIZE);
881 } else {
882 error = 1;
883 debug(("cm206_request: %d %d\n", e1, e2));
884 }
885 }
886 spin_lock_irq(q->queue_lock);
887 end_request(req, !error);
888 }
889}
890
891/* Audio support. I've tried very hard, but the cm206 drive doesn't
892 seem to have a get_toc (table-of-contents) function, while i'm
893 pretty sure it must read the toc upon disc insertion. Therefore
894 this function has been implemented through a binary search
895 strategy. All track starts that happen to be found are stored in
896 cd->toc[], for future use.
897
898 I've spent a whole day on a bug that only shows under Workman---
899 I don't get it. Tried everything, nothing works. If workman asks
900 for track# 0xaa, it'll get the wrong time back. Any other program
901 receives the correct value. I'm stymied.
902*/
903
904/* seek seeks to address lba. It does wait to arrive there. */
905static void seek(int lba)
906{
907 int i;
908 uch seek_command[4] = { c_seek, };
909
910 fsm(lba, &seek_command[1]);
911 for (i = 0; i < 4; i++)
912 type_0_command(seek_command[i], 0);
913 cd->dsb = wait_dsb();
914}
915
916static uch bcdbin(unsigned char bcd)
917{ /* stolen from mcd.c! */
918 return (bcd >> 4) * 10 + (bcd & 0xf);
919}
920
921static inline uch normalize_track(uch track)
922{
923 if (track < 1)
924 return 1;
925 if (track > LAST_TRACK)
926 return LAST_TRACK + 1;
927 return track;
928}
929
930/* This function does a binary search for track start. It records all
931 * tracks seen in the process. Input $track$ must be between 1 and
932 * #-of-tracks+1. Note that the start of the disc must be in toc[1].fsm.
933 */
934static int get_toc_lba(uch track)
935{
936 int max = 74 * 60 * 75 - 150, min = fsm2lba(cd->toc[1].fsm);
937 int i, lba, l, old_lba = 0;
938 uch *q = cd->q;
939 uch ct; /* current track */
940 int binary = 0;
941 const int skip = 3 * 60 * 75; /* 3 minutes */
942
943 for (i = track; i > 0; i--)
944 if (cd->toc[i].track) {
945 min = fsm2lba(cd->toc[i].fsm);
946 break;
947 }
948 lba = min + skip;
949 do {
950 seek(lba);
951 type_1_command(c_read_current_q, 10, q);
952 ct = normalize_track(q[1]);
953 if (!cd->toc[ct].track) {
954 l = q[9] - bcdbin(q[5]) + 75 * (q[8] -
955 bcdbin(q[4]) - 2 +
956 60 * (q[7] -
957 bcdbin(q
958 [3])));
959 cd->toc[ct].track = q[1]; /* lead out still 0xaa */
960 fsm(l, cd->toc[ct].fsm);
961 cd->toc[ct].q0 = q[0]; /* contains adr and ctrl info */
962 if (ct == track)
963 return l;
964 }
965 old_lba = lba;
966 if (binary) {
967 if (ct < track)
968 min = lba;
969 else
970 max = lba;
971 lba = (min + max) / 2;
972 } else {
973 if (ct < track)
974 lba += skip;
975 else {
976 binary = 1;
977 max = lba;
978 min = lba - skip;
979 lba = (min + max) / 2;
980 }
981 }
982 } while (lba != old_lba);
983 return lba;
984}
985
986static void update_toc_entry(uch track)
987{
988 track = normalize_track(track);
989 if (!cd->toc[track].track)
990 get_toc_lba(track);
991}
992
993/* return 0 upon success */
994static int read_toc_header(struct cdrom_tochdr *hp)
995{
996 if (!FIRST_TRACK)
997 get_disc_status();
998 if (hp) {
999 int i;
1000 hp->cdth_trk0 = FIRST_TRACK;
1001 hp->cdth_trk1 = LAST_TRACK;
1002 /* fill in first track position */
1003 for (i = 0; i < 3; i++)
1004 cd->toc[1].fsm[i] = cd->disc_status[3 + i];
1005 update_toc_entry(LAST_TRACK + 1); /* find most entries */
1006 return 0;
1007 }
1008 return -1;
1009}
1010
1011static void play_from_to_msf(struct cdrom_msf *msfp)
1012{
1013 uch play_command[] = { c_play,
1014 msfp->cdmsf_frame0, msfp->cdmsf_sec0, msfp->cdmsf_min0,
1015 msfp->cdmsf_frame1, msfp->cdmsf_sec1, msfp->cdmsf_min1, 2,
1016 2
1017 };
1018 int i;
1019 for (i = 0; i < 9; i++)
1020 type_0_command(play_command[i], 0);
1021 for (i = 0; i < 3; i++)
1022 PLAY_TO.fsm[i] = play_command[i + 4];
1023 PLAY_TO.track = 0; /* say no track end */
1024 cd->dsb = wait_dsb();
1025}
1026
1027static void play_from_to_track(int from, int to)
1028{
1029 uch play_command[8] = { c_play, };
1030 int i;
1031
1032 if (from == 0) { /* continue paused play */
1033 for (i = 0; i < 3; i++) {
1034 play_command[i + 1] = cd->audio_status[i + 2];
1035 play_command[i + 4] = PLAY_TO.fsm[i];
1036 }
1037 } else {
1038 update_toc_entry(from);
1039 update_toc_entry(to + 1);
1040 for (i = 0; i < 3; i++) {
1041 play_command[i + 1] = cd->toc[from].fsm[i];
1042 PLAY_TO.fsm[i] = play_command[i + 4] =
1043 cd->toc[to + 1].fsm[i];
1044 }
1045 PLAY_TO.track = to;
1046 }
1047 for (i = 0; i < 7; i++)
1048 type_0_command(play_command[i], 0);
1049 for (i = 0; i < 2; i++)
1050 type_0_command(0x2, 0); /* volume */
1051 cd->dsb = wait_dsb();
1052}
1053
1054static int get_current_q(struct cdrom_subchnl *qp)
1055{
1056 int i;
1057 uch *q = cd->q;
1058 if (type_1_command(c_read_current_q, 10, q))
1059 return 0;
1060/* q[0] = bcdbin(q[0]); Don't think so! */
1061 for (i = 2; i < 6; i++)
1062 q[i] = bcdbin(q[i]);
1063 qp->cdsc_adr = q[0] & 0xf;
1064 qp->cdsc_ctrl = q[0] >> 4; /* from mcd.c */
1065 qp->cdsc_trk = q[1];
1066 qp->cdsc_ind = q[2];
1067 if (qp->cdsc_format == CDROM_MSF) {
1068 qp->cdsc_reladdr.msf.minute = q[3];
1069 qp->cdsc_reladdr.msf.second = q[4];
1070 qp->cdsc_reladdr.msf.frame = q[5];
1071 qp->cdsc_absaddr.msf.minute = q[7];
1072 qp->cdsc_absaddr.msf.second = q[8];
1073 qp->cdsc_absaddr.msf.frame = q[9];
1074 } else {
1075 qp->cdsc_reladdr.lba = f_s_m2lba(q[5], q[4], q[3]);
1076 qp->cdsc_absaddr.lba = f_s_m2lba(q[9], q[8], q[7]);
1077 }
1078 get_drive_status();
1079 if (cd->dsb & dsb_play_in_progress)
1080 qp->cdsc_audiostatus = CDROM_AUDIO_PLAY;
1081 else if (PAUSED)
1082 qp->cdsc_audiostatus = CDROM_AUDIO_PAUSED;
1083 else
1084 qp->cdsc_audiostatus = CDROM_AUDIO_NO_STATUS;
1085 return 0;
1086}
1087
1088static void invalidate_toc(void)
1089{
1090 memset(cd->toc, 0, sizeof(cd->toc));
1091 memset(cd->disc_status, 0, sizeof(cd->disc_status));
1092}
1093
1094/* cdrom.c guarantees that cdte_format == CDROM_MSF */
1095static void get_toc_entry(struct cdrom_tocentry *ep)
1096{
1097 uch track = normalize_track(ep->cdte_track);
1098 update_toc_entry(track);
1099 ep->cdte_addr.msf.frame = cd->toc[track].fsm[0];
1100 ep->cdte_addr.msf.second = cd->toc[track].fsm[1];
1101 ep->cdte_addr.msf.minute = cd->toc[track].fsm[2];
1102 ep->cdte_adr = cd->toc[track].q0 & 0xf;
1103 ep->cdte_ctrl = cd->toc[track].q0 >> 4;
1104 ep->cdte_datamode = 0;
1105}
1106
1107/* Audio ioctl. Ioctl commands connected to audio are in such an
1108 * idiosyncratic i/o format, that we leave these untouched. Return 0
1109 * upon success. Memory checking has been done by cdrom_ioctl(), the
1110 * calling function, as well as LBA/MSF sanitization.
1111*/
1112static int cm206_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
1113 void *arg)
1114{
1115 switch (cmd) {
1116 case CDROMREADTOCHDR:
1117 return read_toc_header((struct cdrom_tochdr *) arg);
1118 case CDROMREADTOCENTRY:
1119 get_toc_entry((struct cdrom_tocentry *) arg);
1120 return 0;
1121 case CDROMPLAYMSF:
1122 play_from_to_msf((struct cdrom_msf *) arg);
1123 return 0;
1124 case CDROMPLAYTRKIND: /* admittedly, not particularly beautiful */
1125 play_from_to_track(((struct cdrom_ti *) arg)->cdti_trk0,
1126 ((struct cdrom_ti *) arg)->cdti_trk1);
1127 return 0;
1128 case CDROMSTOP:
1129 PAUSED = 0;
1130 if (cd->dsb & dsb_play_in_progress)
1131 return type_0_command(c_stop, 1);
1132 else
1133 return 0;
1134 case CDROMPAUSE:
1135 get_drive_status();
1136 if (cd->dsb & dsb_play_in_progress) {
1137 type_0_command(c_stop, 1);
1138 type_1_command(c_audio_status, 5,
1139 cd->audio_status);
1140 PAUSED = 1; /* say we're paused */
1141 }
1142 return 0;
1143 case CDROMRESUME:
1144 if (PAUSED)
1145 play_from_to_track(0, 0);
1146 PAUSED = 0;
1147 return 0;
1148 case CDROMSTART:
1149 case CDROMVOLCTRL:
1150 return 0;
1151 case CDROMSUBCHNL:
1152 return get_current_q((struct cdrom_subchnl *) arg);
1153 default:
1154 return -EINVAL;
1155 }
1156}
1157
1158static int cm206_media_changed(struct cdrom_device_info *cdi, int disc_nr)
1159{
1160 if (cd != NULL) {
1161 int r;
1162 get_drive_status(); /* ensure cd->media_changed OK */
1163 r = cd->media_changed;
1164 cd->media_changed = 0; /* clear bit */
1165 return r;
1166 } else
1167 return -EIO;
1168}
1169
1170/* The new generic cdrom support. Routines should be concise, most of
1171 the logic should be in cdrom.c */
1172
1173
1174/* controls tray movement */
1175static int cm206_tray_move(struct cdrom_device_info *cdi, int position)
1176{
1177 if (position) { /* 1: eject */
1178 type_0_command(c_open_tray, 1);
1179 invalidate_toc();
1180 } else
1181 type_0_command(c_close_tray, 1); /* 0: close */
1182 return 0;
1183}
1184
1185/* gives current state of the drive */
1186static int cm206_drive_status(struct cdrom_device_info *cdi, int slot_nr)
1187{
1188 get_drive_status();
1189 if (cd->dsb & dsb_tray_not_closed)
1190 return CDS_TRAY_OPEN;
1191 if (!(cd->dsb & dsb_disc_present))
1192 return CDS_NO_DISC;
1193 if (cd->dsb & dsb_drive_not_ready)
1194 return CDS_DRIVE_NOT_READY;
1195 return CDS_DISC_OK;
1196}
1197
1198/* locks or unlocks door lock==1: lock; return 0 upon success */
1199static int cm206_lock_door(struct cdrom_device_info *cdi, int lock)
1200{
1201 uch command = (lock) ? c_lock_tray : c_unlock_tray;
1202 type_0_command(command, 1); /* wait and get dsb */
1203 /* the logic calculates the success, 0 means successful */
1204 return lock ^ ((cd->dsb & dsb_tray_locked) != 0);
1205}
1206
1207/* Although a session start should be in LBA format, we return it in
1208 MSF format because it is slightly easier, and the new generic ioctl
1209 will take care of the necessary conversion. */
1210static int cm206_get_last_session(struct cdrom_device_info *cdi,
1211 struct cdrom_multisession *mssp)
1212{
1213 if (!FIRST_TRACK)
1214 get_disc_status();
1215 if (mssp != NULL) {
1216 if (DISC_STATUS & cds_multi_session) { /* multi-session */
1217 mssp->addr.msf.frame = cd->disc_status[3];
1218 mssp->addr.msf.second = cd->disc_status[4];
1219 mssp->addr.msf.minute = cd->disc_status[5];
1220 mssp->addr_format = CDROM_MSF;
1221 mssp->xa_flag = 1;
1222 } else {
1223 mssp->xa_flag = 0;
1224 }
1225 return 1;
1226 }
1227 return 0;
1228}
1229
1230static int cm206_get_upc(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn)
1231{
1232 uch upc[10];
1233 char *ret = mcn->medium_catalog_number;
1234 int i;
1235
1236 if (type_1_command(c_read_upc, 10, upc))
1237 return -EIO;
1238 for (i = 0; i < 13; i++) {
1239 int w = i / 2 + 1, r = i % 2;
1240 if (r)
1241 ret[i] = 0x30 | (upc[w] & 0x0f);
1242 else
1243 ret[i] = 0x30 | ((upc[w] >> 4) & 0x0f);
1244 }
1245 ret[13] = '\0';
1246 return 0;
1247}
1248
1249static int cm206_reset(struct cdrom_device_info *cdi)
1250{
1251 stop_read();
1252 reset_cm260();
1253 outw(dc_normal | dc_break | READ_AHEAD, r_data_control);
1254 mdelay(1); /* 750 musec minimum */
1255 outw(dc_normal | READ_AHEAD, r_data_control);
1256 cd->sector_last = -1; /* flag no data buffered */
1257 cd->adapter_last = -1;
1258 invalidate_toc();
1259 return 0;
1260}
1261
1262static int cm206_select_speed(struct cdrom_device_info *cdi, int speed)
1263{
1264 int r;
1265 switch (speed) {
1266 case 0:
1267 r = type_0_command(c_auto_mode, 1);
1268 break;
1269 case 1:
1270 r = type_0_command(c_force_1x, 1);
1271 break;
1272 case 2:
1273 r = type_0_command(c_force_2x, 1);
1274 break;
1275 default:
1276 return -1;
1277 }
1278 if (r < 0)
1279 return r;
1280 else
1281 return 1;
1282}
1283
1284static struct cdrom_device_ops cm206_dops = {
1285 .open = cm206_open,
1286 .release = cm206_release,
1287 .drive_status = cm206_drive_status,
1288 .media_changed = cm206_media_changed,
1289 .tray_move = cm206_tray_move,
1290 .lock_door = cm206_lock_door,
1291 .select_speed = cm206_select_speed,
1292 .get_last_session = cm206_get_last_session,
1293 .get_mcn = cm206_get_upc,
1294 .reset = cm206_reset,
1295 .audio_ioctl = cm206_audio_ioctl,
1296 .capability = CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK |
1297 CDC_MULTI_SESSION | CDC_MEDIA_CHANGED |
1298 CDC_MCN | CDC_PLAY_AUDIO | CDC_SELECT_SPEED |
1299 CDC_DRIVE_STATUS,
1300 .n_minors = 1,
1301};
1302
1303
1304static struct cdrom_device_info cm206_info = {
1305 .ops = &cm206_dops,
1306 .speed = 2,
1307 .capacity = 1,
1308 .name = "cm206",
1309};
1310
1311static int cm206_block_open(struct inode *inode, struct file *file)
1312{
1313 return cdrom_open(&cm206_info, inode, file);
1314}
1315
1316static int cm206_block_release(struct inode *inode, struct file *file)
1317{
1318 return cdrom_release(&cm206_info, file);
1319}
1320
1321static int cm206_block_ioctl(struct inode *inode, struct file *file,
1322 unsigned cmd, unsigned long arg)
1323{
1324 switch (cmd) {
1325#ifdef STATISTICS
1326 case CM206CTL_GET_STAT:
1327 if (arg >= NR_STATS)
1328 return -EINVAL;
1329 return cd->stats[arg];
1330 case CM206CTL_GET_LAST_STAT:
1331 if (arg >= NR_STATS)
1332 return -EINVAL;
1333 return cd->last_stat[arg];
1334#endif
1335 default:
1336 break;
1337 }
1338
1339 return cdrom_ioctl(file, &cm206_info, inode, cmd, arg);
1340}
1341
1342static int cm206_block_media_changed(struct gendisk *disk)
1343{
1344 return cdrom_media_changed(&cm206_info);
1345}
1346
1347static struct block_device_operations cm206_bdops =
1348{
1349 .owner = THIS_MODULE,
1350 .open = cm206_block_open,
1351 .release = cm206_block_release,
1352 .ioctl = cm206_block_ioctl,
1353 .media_changed = cm206_block_media_changed,
1354};
1355
1356static struct gendisk *cm206_gendisk;
1357
1358/* This function probes for the adapter card. It returns the base
1359 address if it has found the adapter card. One can specify a base
1360 port to probe specifically, or 0 which means span all possible
1361 bases.
1362
1363 Linus says it is too dangerous to use writes for probing, so we
1364 stick with pure reads for a while. Hope that 8 possible ranges,
1365 request_region, 15 bits of one port and 6 of another make things
1366 likely enough to accept the region on the first hit...
1367 */
1368static int __init probe_base_port(int base)
1369{
1370 int b = 0x300, e = 0x370; /* this is the range of start addresses */
1371 volatile int fool, i;
1372
1373 if (base)
1374 b = e = base;
1375 for (base = b; base <= e; base += 0x10) {
1376 if (!request_region(base, 0x10,"cm206"))
1377 continue;
1378 for (i = 0; i < 3; i++)
1379 fool = inw(base + 2); /* empty possibly uart_receive_buffer */
1380 if ((inw(base + 6) & 0xffef) != 0x0001 || /* line_status */
1381 (inw(base) & 0xad00) != 0) { /* data status */
1382 release_region(base,0x10);
1383 continue;
1384 }
1385 return (base);
1386 }
1387 return 0;
1388}
1389
1390#if !defined(MODULE) || defined(AUTO_PROBE_MODULE)
1391/* Probe for irq# nr. If nr==0, probe for all possible irq's. */
1392static int __init probe_irq(int nr)
1393{
1394 int irqs, irq;
1395 outw(dc_normal | READ_AHEAD, r_data_control); /* disable irq-generation */
1396 sti();
1397 irqs = probe_irq_on();
1398 reset_cm260(); /* causes interrupt */
1399 udelay(100); /* wait for it */
1400 irq = probe_irq_off(irqs);
1401 outw(dc_normal | READ_AHEAD, r_data_control); /* services interrupt */
1402 if (nr && irq != nr && irq > 0)
1403 return 0; /* wrong interrupt happened */
1404 else
1405 return irq;
1406}
1407#endif
1408
1409int __init cm206_init(void)
1410{
1411 uch e = 0;
1412 long int size = sizeof(struct cm206_struct);
1413 struct gendisk *disk;
1414
1415 printk(KERN_INFO "cm206 cdrom driver " REVISION);
1416 cm206_base = probe_base_port(auto_probe ? 0 : cm206_base);
1417 if (!cm206_base) {
1418 printk(" can't find adapter!\n");
1419 return -EIO;
1420 }
1421 printk(" adapter at 0x%x", cm206_base);
1422 cd = kmalloc(size, GFP_KERNEL);
1423 if (!cd)
1424 goto out_base;
1425 /* Now we have found the adaptor card, try to reset it. As we have
1426 * found out earlier, this process generates an interrupt as well,
1427 * so we might just exploit that fact for irq probing! */
1428#if !defined(MODULE) || defined(AUTO_PROBE_MODULE)
1429 cm206_irq = probe_irq(auto_probe ? 0 : cm206_irq);
1430 if (cm206_irq <= 0) {
1431 printk("can't find IRQ!\n");
1432 goto out_probe;
1433 } else
1434 printk(" IRQ %d found\n", cm206_irq);
1435#else
1436 cli();
1437 reset_cm260();
1438 /* Now, the problem here is that reset_cm260 can generate an
1439 interrupt. It seems that this can cause a kernel oops some time
1440 later. So we wait a while and `service' this interrupt. */
1441 mdelay(1);
1442 outw(dc_normal | READ_AHEAD, r_data_control);
1443 sti();
1444 printk(" using IRQ %d\n", cm206_irq);
1445#endif
1446 if (send_receive_polled(c_drive_configuration) !=
1447 c_drive_configuration) {
1448 printk(KERN_INFO " drive not there\n");
1449 goto out_probe;
1450 }
1451 e = send_receive_polled(c_gimme);
1452 printk(KERN_INFO "Firmware revision %d", e & dcf_revision_code);
1453 if (e & dcf_transfer_rate)
1454 printk(" double");
1455 else
1456 printk(" single");
1457 printk(" speed drive");
1458 if (e & dcf_motorized_tray)
1459 printk(", motorized tray");
1460 if (request_irq(cm206_irq, cm206_interrupt, 0, "cm206", NULL)) {
1461 printk("\nUnable to reserve IRQ---aborted\n");
1462 goto out_probe;
1463 }
1464 printk(".\n");
1465
1466 if (register_blkdev(MAJOR_NR, "cm206"))
1467 goto out_blkdev;
1468
1469 disk = alloc_disk(1);
1470 if (!disk)
1471 goto out_disk;
1472 disk->major = MAJOR_NR;
1473 disk->first_minor = 0;
1474 sprintf(disk->disk_name, "cm206cd");
1475 disk->fops = &cm206_bdops;
1476 disk->flags = GENHD_FL_CD;
1477 cm206_gendisk = disk;
1478 if (register_cdrom(&cm206_info) != 0) {
1479 printk(KERN_INFO "Cannot register for cdrom %d!\n", MAJOR_NR);
1480 goto out_cdrom;
1481 }
1482 cm206_queue = blk_init_queue(do_cm206_request, &cm206_lock);
1483 if (!cm206_queue)
1484 goto out_queue;
1485
1486 blk_queue_hardsect_size(cm206_queue, 2048);
1487 disk->queue = cm206_queue;
1488 add_disk(disk);
1489
1490 memset(cd, 0, sizeof(*cd)); /* give'm some reasonable value */
1491 cd->sector_last = -1; /* flag no data buffered */
1492 cd->adapter_last = -1;
1493 init_timer(&cd->timer);
1494 cd->timer.function = cm206_timeout;
1495 cd->max_sectors = (inw(r_data_status) & ds_ram_size) ? 24 : 97;
1496 printk(KERN_INFO "%d kB adapter memory available, "
1497 " %ld bytes kernel memory used.\n", cd->max_sectors * 2,
1498 size);
1499 return 0;
1500
1501out_queue:
1502 unregister_cdrom(&cm206_info);
1503out_cdrom:
1504 put_disk(disk);
1505out_disk:
1506 unregister_blkdev(MAJOR_NR, "cm206");
1507out_blkdev:
1508 free_irq(cm206_irq, NULL);
1509out_probe:
1510 kfree(cd);
1511out_base:
1512 release_region(cm206_base, 16);
1513 return -EIO;
1514}
1515
1516#ifdef MODULE
1517
1518
1519static void __init parse_options(void)
1520{
1521 int i;
1522 for (i = 0; i < 2; i++) {
1523 if (0x300 <= cm206[i] && i <= 0x370
1524 && cm206[i] % 0x10 == 0) {
1525 cm206_base = cm206[i];
1526 auto_probe = 0;
1527 } else if (3 <= cm206[i] && cm206[i] <= 15) {
1528 cm206_irq = cm206[i];
1529 auto_probe = 0;
1530 }
1531 }
1532}
1533
1534static int __init __cm206_init(void)
1535{
1536 parse_options();
1537#if !defined(AUTO_PROBE_MODULE)
1538 auto_probe = 0;
1539#endif
1540 return cm206_init();
1541}
1542
1543static void __exit cm206_exit(void)
1544{
1545 del_gendisk(cm206_gendisk);
1546 put_disk(cm206_gendisk);
1547 if (unregister_cdrom(&cm206_info)) {
1548 printk("Can't unregister cdrom cm206\n");
1549 return;
1550 }
1551 if (unregister_blkdev(MAJOR_NR, "cm206")) {
1552 printk("Can't unregister major cm206\n");
1553 return;
1554 }
1555 blk_cleanup_queue(cm206_queue);
1556 free_irq(cm206_irq, NULL);
1557 kfree(cd);
1558 release_region(cm206_base, 16);
1559 printk(KERN_INFO "cm206 removed\n");
1560}
1561
1562module_init(__cm206_init);
1563module_exit(cm206_exit);
1564
1565#else /* !MODULE */
1566
1567/* This setup function accepts either `auto' or numbers in the range
1568 * 3--11 (for irq) or 0x300--0x370 (for base port) or both. */
1569
1570static int __init cm206_setup(char *s)
1571{
1572 int i, p[4];
1573
1574 (void) get_options(s, ARRAY_SIZE(p), p);
1575
1576 if (!strcmp(s, "auto"))
1577 auto_probe = 1;
1578 for (i = 1; i <= p[0]; i++) {
1579 if (0x300 <= p[i] && i <= 0x370 && p[i] % 0x10 == 0) {
1580 cm206_base = p[i];
1581 auto_probe = 0;
1582 } else if (3 <= p[i] && p[i] <= 15) {
1583 cm206_irq = p[i];
1584 auto_probe = 0;
1585 }
1586 }
1587 return 1;
1588}
1589
1590__setup("cm206=", cm206_setup);
1591
1592#endif /* !MODULE */
1593MODULE_ALIAS_BLOCKDEV_MAJOR(CM206_CDROM_MAJOR);
1594
diff --git a/drivers/cdrom/cm206.h b/drivers/cdrom/cm206.h
deleted file mode 100644
index 0ae51c1a0dac..000000000000
--- a/drivers/cdrom/cm206.h
+++ /dev/null
@@ -1,171 +0,0 @@
1/* cm206.h Header file for cm206.c.
2 Copyright (c) 1995 David van Leeuwen
3*/
4
5#ifndef LINUX_CM206_H
6#define LINUX_CM206_H
7
8#include <linux/ioctl.h>
9
10/* First, the cm260 stuff */
11/* The ports and irq used. Although CM206_BASE and CM206_IRQ are defined
12 below, the values are not used unless autoprobing is turned off and
13 no LILO boot options or module command line options are given. Change
14 these values to your own as last resort if autoprobing and options
15 don't work. */
16
17#define CM206_BASE 0x340
18#define CM206_IRQ 11
19
20#define r_data_status (cm206_base)
21#define r_uart_receive (cm206_base+0x2)
22#define r_fifo_output_buffer (cm206_base+0x4)
23#define r_line_status (cm206_base+0x6)
24#define r_data_control (cm206_base+0x8)
25#define r_uart_transmit (cm206_base+0xa)
26#define r_test_clock (cm206_base+0xc)
27#define r_test_control (cm206_base+0xe)
28
29/* the data_status flags */
30#define ds_ram_size 0x4000
31#define ds_toc_ready 0x2000
32#define ds_fifo_empty 0x1000
33#define ds_sync_error 0x800
34#define ds_crc_error 0x400
35#define ds_data_error 0x200
36#define ds_fifo_overflow 0x100
37#define ds_data_ready 0x80
38
39/* the line_status flags */
40#define ls_attention 0x10
41#define ls_parity_error 0x8
42#define ls_overrun 0x4
43#define ls_receive_buffer_full 0x2
44#define ls_transmitter_buffer_empty 0x1
45
46/* the data control register flags */
47#define dc_read_q_channel 0x4000
48#define dc_mask_sync_error 0x2000
49#define dc_toc_enable 0x1000
50#define dc_no_stop_on_error 0x800
51#define dc_break 0x400
52#define dc_initialize 0x200
53#define dc_mask_transmit_ready 0x100
54#define dc_flag_enable 0x80
55
56/* Define the default data control register flags here */
57#define dc_normal (dc_mask_sync_error | dc_no_stop_on_error | \
58 dc_mask_transmit_ready)
59
60/* now some constants related to the cm206 */
61/* another drive status byte, echoed by the cm206 on most commands */
62
63#define dsb_error_condition 0x1
64#define dsb_play_in_progress 0x4
65#define dsb_possible_media_change 0x8
66#define dsb_disc_present 0x10
67#define dsb_drive_not_ready 0x20
68#define dsb_tray_locked 0x40
69#define dsb_tray_not_closed 0x80
70
71#define dsb_not_useful (dsb_drive_not_ready | dsb_tray_not_closed)
72
73/* the cm206 command set */
74
75#define c_close_tray 0
76#define c_lock_tray 0x01
77#define c_unlock_tray 0x04
78#define c_open_tray 0x05
79#define c_seek 0x10
80#define c_read_data 0x20
81#define c_force_1x 0x21
82#define c_force_2x 0x22
83#define c_auto_mode 0x23
84#define c_play 0x30
85#define c_set_audio_mode 0x31
86#define c_read_current_q 0x41
87#define c_stream_q 0x42
88#define c_drive_status 0x50
89#define c_disc_status 0x51
90#define c_audio_status 0x52
91#define c_drive_configuration 0x53
92#define c_read_upc 0x60
93#define c_stop 0x70
94#define c_calc_checksum 0xe5
95
96#define c_gimme 0xf8
97
98/* finally, the (error) condition that the drive can be in *
99 * OK, this is not always an error, but let's prefix it with e_ */
100
101#define e_none 0
102#define e_illegal_command 0x01
103#define e_sync 0x02
104#define e_seek 0x03
105#define e_parity 0x04
106#define e_focus 0x05
107#define e_header_sync 0x06
108#define e_code_incompatibility 0x07
109#define e_reset_done 0x08
110#define e_bad_parameter 0x09
111#define e_radial 0x0a
112#define e_sub_code 0x0b
113#define e_no_data_track 0x0c
114#define e_scan 0x0d
115#define e_tray_open 0x0f
116#define e_no_disc 0x10
117#define e_tray stalled 0x11
118
119/* drive configuration masks */
120
121#define dcf_revision_code 0x7
122#define dcf_transfer_rate 0x60
123#define dcf_motorized_tray 0x80
124
125/* disc status byte */
126
127#define cds_multi_session 0x2
128#define cds_all_audio 0x8
129#define cds_xa_mode 0xf0
130
131/* finally some ioctls for the driver */
132
133#define CM206CTL_GET_STAT _IO( 0x20, 0 )
134#define CM206CTL_GET_LAST_STAT _IO( 0x20, 1 )
135
136#ifdef STATISTICS
137
138/* This is an ugly way to guarantee that the names of the statistics
139 * are the same in the code and in the diagnostics program. */
140
141#ifdef __KERNEL__
142#define x(a) st_ ## a
143#define y enum
144#else
145#define x(a) #a
146#define y char * stats_name[] =
147#endif
148
149y {x(interrupt), x(data_ready), x(fifo_overflow), x(data_error),
150 x(crc_error), x(sync_error), x(lost_intr), x(echo),
151 x(write_timeout), x(receive_timeout), x(read_timeout),
152 x(dsb_timeout), x(stop_0xff), x(back_read_timeout),
153 x(sector_transferred), x(read_restarted), x(read_background),
154 x(bh), x(open), x(ioctl_multisession), x(attention)
155#ifdef __KERNEL__
156 , x(last_entry)
157#endif
158 };
159
160#ifdef __KERNEL__
161#define NR_STATS st_last_entry
162#else
163#define NR_STATS (sizeof(stats_name)/sizeof(char*))
164#endif
165
166#undef y
167#undef x
168
169#endif /* STATISTICS */
170
171#endif /* LINUX_CM206_H */
diff --git a/drivers/cdrom/gscd.c b/drivers/cdrom/gscd.c
deleted file mode 100644
index b3ab6e9b8df1..000000000000
--- a/drivers/cdrom/gscd.c
+++ /dev/null
@@ -1,1029 +0,0 @@
1#define GSCD_VERSION "0.4a Oliver Raupach <raupach@nwfs1.rz.fh-hannover.de>"
2
3/*
4 linux/drivers/block/gscd.c - GoldStar R420 CDROM driver
5
6 Copyright (C) 1995 Oliver Raupach <raupach@nwfs1.rz.fh-hannover.de>
7 based upon pre-works by Eberhard Moenkeberg <emoenke@gwdg.de>
8
9
10 For all kind of other information about the GoldStar CDROM
11 and this Linux device driver I installed a WWW-URL:
12 http://linux.rz.fh-hannover.de/~raupach
13
14
15 If you are the editor of a Linux CD, you should
16 enable gscd.c within your boot floppy kernel and
17 send me one of your CDs for free.
18
19
20 --------------------------------------------------------------------
21 This program is free software; you can redistribute it and/or modify
22 it under the terms of the GNU General Public License as published by
23 the Free Software Foundation; either version 2, or (at your option)
24 any later version.
25
26 This program is distributed in the hope that it will be useful,
27 but WITHOUT ANY WARRANTY; without even the implied warranty of
28 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29 GNU General Public License for more details.
30
31 You should have received a copy of the GNU General Public License
32 along with this program; if not, write to the Free Software
33 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
34
35 --------------------------------------------------------------------
36
37 9 November 1999 -- Make kernel-parameter implementation work with 2.3.x
38 Removed init_module & cleanup_module in favor of
39 module_init & module_exit.
40 Torben Mathiasen <tmm@image.dk>
41
42*/
43
44/* These settings are for various debug-level. Leave they untouched ... */
45#define NO_GSCD_DEBUG
46#define NO_IOCTL_DEBUG
47#define NO_MODULE_DEBUG
48#define NO_FUTURE_WORK
49/*------------------------*/
50
51#include <linux/module.h>
52
53#include <linux/slab.h>
54#include <linux/errno.h>
55#include <linux/signal.h>
56#include <linux/timer.h>
57#include <linux/fs.h>
58#include <linux/mm.h>
59#include <linux/kernel.h>
60#include <linux/cdrom.h>
61#include <linux/ioport.h>
62#include <linux/major.h>
63#include <linux/string.h>
64#include <linux/init.h>
65
66#include <asm/system.h>
67#include <asm/io.h>
68#include <asm/uaccess.h>
69
70#define MAJOR_NR GOLDSTAR_CDROM_MAJOR
71#include <linux/blkdev.h>
72#include "gscd.h"
73
74static int gscdPresent = 0;
75
76static unsigned char gscd_buf[2048]; /* buffer for block size conversion */
77static int gscd_bn = -1;
78static short gscd_port = GSCD_BASE_ADDR;
79module_param_named(gscd, gscd_port, short, 0);
80
81/* Kommt spaeter vielleicht noch mal dran ...
82 * static DECLARE_WAIT_QUEUE_HEAD(gscd_waitq);
83 */
84
85static void gscd_read_cmd(struct request *req);
86static void gscd_hsg2msf(long hsg, struct msf *msf);
87static void gscd_bin2bcd(unsigned char *p);
88
89/* Schnittstellen zum Kern/FS */
90
91static void __do_gscd_request(unsigned long dummy);
92static int gscd_ioctl(struct inode *, struct file *, unsigned int,
93 unsigned long);
94static int gscd_open(struct inode *, struct file *);
95static int gscd_release(struct inode *, struct file *);
96static int check_gscd_med_chg(struct gendisk *disk);
97
98/* GoldStar Funktionen */
99
100static void cmd_out(int, char *, char *, int);
101static void cmd_status(void);
102static void init_cd_drive(int);
103
104static int get_status(void);
105static void clear_Audio(void);
106static void cc_invalidate(void);
107
108/* some things for the next version */
109#ifdef FUTURE_WORK
110static void update_state(void);
111static long gscd_msf2hsg(struct msf *mp);
112static int gscd_bcd2bin(unsigned char bcd);
113#endif
114
115
116/* lo-level cmd-Funktionen */
117
118static void cmd_info_in(char *, int);
119static void cmd_end(void);
120static void cmd_read_b(char *, int, int);
121static void cmd_read_w(char *, int, int);
122static int cmd_unit_alive(void);
123static void cmd_write_cmd(char *);
124
125
126/* GoldStar Variablen */
127
128static int curr_drv_state;
129static int drv_states[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
130static int drv_mode;
131static int disk_state;
132static int speed;
133static int ndrives;
134
135static unsigned char drv_num_read;
136static unsigned char f_dsk_valid;
137static unsigned char current_drive;
138static unsigned char f_drv_ok;
139
140
141static char f_AudioPlay;
142static char f_AudioPause;
143static int AudioStart_m;
144static int AudioStart_f;
145static int AudioEnd_m;
146static int AudioEnd_f;
147
148static DEFINE_TIMER(gscd_timer, NULL, 0, 0);
149static DEFINE_SPINLOCK(gscd_lock);
150static struct request_queue *gscd_queue;
151
152static struct block_device_operations gscd_fops = {
153 .owner = THIS_MODULE,
154 .open = gscd_open,
155 .release = gscd_release,
156 .ioctl = gscd_ioctl,
157 .media_changed = check_gscd_med_chg,
158};
159
160/*
161 * Checking if the media has been changed
162 * (not yet implemented)
163 */
164static int check_gscd_med_chg(struct gendisk *disk)
165{
166#ifdef GSCD_DEBUG
167 printk("gscd: check_med_change\n");
168#endif
169 return 0;
170}
171
172
173#ifndef MODULE
174/* Using new interface for kernel-parameters */
175
176static int __init gscd_setup(char *str)
177{
178 int ints[2];
179 (void) get_options(str, ARRAY_SIZE(ints), ints);
180
181 if (ints[0] > 0) {
182 gscd_port = ints[1];
183 }
184 return 1;
185}
186
187__setup("gscd=", gscd_setup);
188
189#endif
190
191static int gscd_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
192 unsigned long arg)
193{
194 unsigned char to_do[10];
195 unsigned char dummy;
196
197
198 switch (cmd) {
199 case CDROMSTART: /* Spin up the drive */
200 /* Don't think we can do this. Even if we could,
201 * I think the drive times out and stops after a while
202 * anyway. For now, ignore it.
203 */
204 return 0;
205
206 case CDROMRESUME: /* keine Ahnung was das ist */
207 return 0;
208
209
210 case CDROMEJECT:
211 cmd_status();
212 to_do[0] = CMD_TRAY_CTL;
213 cmd_out(TYPE_INFO, (char *) &to_do, (char *) &dummy, 0);
214
215 return 0;
216
217 default:
218 return -EINVAL;
219 }
220
221}
222
223
224/*
225 * Take care of the different block sizes between cdrom and Linux.
226 * When Linux gets variable block sizes this will probably go away.
227 */
228
229static void gscd_transfer(struct request *req)
230{
231 while (req->nr_sectors > 0 && gscd_bn == req->sector / 4) {
232 long offs = (req->sector & 3) * 512;
233 memcpy(req->buffer, gscd_buf + offs, 512);
234 req->nr_sectors--;
235 req->sector++;
236 req->buffer += 512;
237 }
238}
239
240
241/*
242 * I/O request routine called from Linux kernel.
243 */
244
245static void do_gscd_request(request_queue_t * q)
246{
247 __do_gscd_request(0);
248}
249
250static void __do_gscd_request(unsigned long dummy)
251{
252 struct request *req;
253 unsigned int block;
254 unsigned int nsect;
255
256repeat:
257 req = elv_next_request(gscd_queue);
258 if (!req)
259 return;
260
261 block = req->sector;
262 nsect = req->nr_sectors;
263
264 if (req->sector == -1)
265 goto out;
266
267 if (req->cmd != READ) {
268 printk("GSCD: bad cmd %u\n", rq_data_dir(req));
269 end_request(req, 0);
270 goto repeat;
271 }
272
273 gscd_transfer(req);
274
275 /* if we satisfied the request from the buffer, we're done. */
276
277 if (req->nr_sectors == 0) {
278 end_request(req, 1);
279 goto repeat;
280 }
281#ifdef GSCD_DEBUG
282 printk("GSCD: block %d, nsect %d\n", block, nsect);
283#endif
284 gscd_read_cmd(req);
285out:
286 return;
287}
288
289
290
291/*
292 * Check the result of the set-mode command. On success, send the
293 * read-data command.
294 */
295
296static void gscd_read_cmd(struct request *req)
297{
298 long block;
299 struct gscd_Play_msf gscdcmd;
300 char cmd[] = { CMD_READ, 0x80, 0, 0, 0, 0, 1 }; /* cmd mode M-S-F secth sectl */
301
302 cmd_status();
303 if (disk_state & (ST_NO_DISK | ST_DOOR_OPEN)) {
304 printk("GSCD: no disk or door open\n");
305 end_request(req, 0);
306 } else {
307 if (disk_state & ST_INVALID) {
308 printk("GSCD: disk invalid\n");
309 end_request(req, 0);
310 } else {
311 gscd_bn = -1; /* purge our buffer */
312 block = req->sector / 4;
313 gscd_hsg2msf(block, &gscdcmd.start); /* cvt to msf format */
314
315 cmd[2] = gscdcmd.start.min;
316 cmd[3] = gscdcmd.start.sec;
317 cmd[4] = gscdcmd.start.frame;
318
319#ifdef GSCD_DEBUG
320 printk("GSCD: read msf %d:%d:%d\n", cmd[2], cmd[3],
321 cmd[4]);
322#endif
323 cmd_out(TYPE_DATA, (char *) &cmd,
324 (char *) &gscd_buf[0], 1);
325
326 gscd_bn = req->sector / 4;
327 gscd_transfer(req);
328 end_request(req, 1);
329 }
330 }
331 SET_TIMER(__do_gscd_request, 1);
332}
333
334
335/*
336 * Open the device special file. Check that a disk is in.
337 */
338
339static int gscd_open(struct inode *ip, struct file *fp)
340{
341 int st;
342
343#ifdef GSCD_DEBUG
344 printk("GSCD: open\n");
345#endif
346
347 if (gscdPresent == 0)
348 return -ENXIO; /* no hardware */
349
350 get_status();
351 st = disk_state & (ST_NO_DISK | ST_DOOR_OPEN);
352 if (st) {
353 printk("GSCD: no disk or door open\n");
354 return -ENXIO;
355 }
356
357/* if (updateToc() < 0)
358 return -EIO;
359*/
360
361 return 0;
362}
363
364
365/*
366 * On close, we flush all gscd blocks from the buffer cache.
367 */
368
369static int gscd_release(struct inode *inode, struct file *file)
370{
371
372#ifdef GSCD_DEBUG
373 printk("GSCD: release\n");
374#endif
375
376 gscd_bn = -1;
377
378 return 0;
379}
380
381
382static int get_status(void)
383{
384 int status;
385
386 cmd_status();
387 status = disk_state & (ST_x08 | ST_x04 | ST_INVALID | ST_x01);
388
389 if (status == (ST_x08 | ST_x04 | ST_INVALID | ST_x01)) {
390 cc_invalidate();
391 return 1;
392 } else {
393 return 0;
394 }
395}
396
397
398static void cc_invalidate(void)
399{
400 drv_num_read = 0xFF;
401 f_dsk_valid = 0xFF;
402 current_drive = 0xFF;
403 f_drv_ok = 0xFF;
404
405 clear_Audio();
406
407}
408
409static void clear_Audio(void)
410{
411
412 f_AudioPlay = 0;
413 f_AudioPause = 0;
414 AudioStart_m = 0;
415 AudioStart_f = 0;
416 AudioEnd_m = 0;
417 AudioEnd_f = 0;
418
419}
420
421/*
422 * waiting ?
423 */
424
425static int wait_drv_ready(void)
426{
427 int found, read;
428
429 do {
430 found = inb(GSCDPORT(0));
431 found &= 0x0f;
432 read = inb(GSCDPORT(0));
433 read &= 0x0f;
434 } while (read != found);
435
436#ifdef GSCD_DEBUG
437 printk("Wait for: %d\n", read);
438#endif
439
440 return read;
441}
442
443static void cc_Ident(char *respons)
444{
445 char to_do[] = { CMD_IDENT, 0, 0 };
446
447 cmd_out(TYPE_INFO, (char *) &to_do, (char *) respons, (int) 0x1E);
448
449}
450
451static void cc_SetSpeed(void)
452{
453 char to_do[] = { CMD_SETSPEED, 0, 0 };
454 char dummy;
455
456 if (speed > 0) {
457 to_do[1] = speed & 0x0F;
458 cmd_out(TYPE_INFO, (char *) &to_do, (char *) &dummy, 0);
459 }
460}
461
462static void cc_Reset(void)
463{
464 char to_do[] = { CMD_RESET, 0 };
465 char dummy;
466
467 cmd_out(TYPE_INFO, (char *) &to_do, (char *) &dummy, 0);
468}
469
470static void cmd_status(void)
471{
472 char to_do[] = { CMD_STATUS, 0 };
473 char dummy;
474
475 cmd_out(TYPE_INFO, (char *) &to_do, (char *) &dummy, 0);
476
477#ifdef GSCD_DEBUG
478 printk("GSCD: Status: %d\n", disk_state);
479#endif
480
481}
482
483static void cmd_out(int cmd_type, char *cmd, char *respo_buf, int respo_count)
484{
485 int result;
486
487
488 result = wait_drv_ready();
489 if (result != drv_mode) {
490 unsigned long test_loops = 0xFFFF;
491 int i, dummy;
492
493 outb(curr_drv_state, GSCDPORT(0));
494
495 /* LOCLOOP_170 */
496 do {
497 result = wait_drv_ready();
498 test_loops--;
499 } while ((result != drv_mode) && (test_loops > 0));
500
501 if (result != drv_mode) {
502 disk_state = ST_x08 | ST_x04 | ST_INVALID;
503 return;
504 }
505
506 /* ...and waiting */
507 for (i = 1, dummy = 1; i < 0xFFFF; i++) {
508 dummy *= i;
509 }
510 }
511
512 /* LOC_172 */
513 /* check the unit */
514 /* and wake it up */
515 if (cmd_unit_alive() != 0x08) {
516 /* LOC_174 */
517 /* game over for this unit */
518 disk_state = ST_x08 | ST_x04 | ST_INVALID;
519 return;
520 }
521
522 /* LOC_176 */
523#ifdef GSCD_DEBUG
524 printk("LOC_176 ");
525#endif
526 if (drv_mode == 0x09) {
527 /* magic... */
528 printk("GSCD: magic ...\n");
529 outb(result, GSCDPORT(2));
530 }
531
532 /* write the command to the drive */
533 cmd_write_cmd(cmd);
534
535 /* LOC_178 */
536 for (;;) {
537 result = wait_drv_ready();
538 if (result != drv_mode) {
539 /* LOC_179 */
540 if (result == 0x04) { /* Mode 4 */
541 /* LOC_205 */
542#ifdef GSCD_DEBUG
543 printk("LOC_205 ");
544#endif
545 disk_state = inb(GSCDPORT(2));
546
547 do {
548 result = wait_drv_ready();
549 } while (result != drv_mode);
550 return;
551
552 } else {
553 if (result == 0x06) { /* Mode 6 */
554 /* LOC_181 */
555#ifdef GSCD_DEBUG
556 printk("LOC_181 ");
557#endif
558
559 if (cmd_type == TYPE_DATA) {
560 /* read data */
561 /* LOC_184 */
562 if (drv_mode == 9) {
563 /* read the data to the buffer (word) */
564
565 /* (*(cmd+1))?(CD_FRAMESIZE/2):(CD_FRAMESIZE_RAW/2) */
566 cmd_read_w
567 (respo_buf,
568 respo_count,
569 CD_FRAMESIZE /
570 2);
571 return;
572 } else {
573 /* read the data to the buffer (byte) */
574
575 /* (*(cmd+1))?(CD_FRAMESIZE):(CD_FRAMESIZE_RAW) */
576 cmd_read_b
577 (respo_buf,
578 respo_count,
579 CD_FRAMESIZE);
580 return;
581 }
582 } else {
583 /* read the info to the buffer */
584 cmd_info_in(respo_buf,
585 respo_count);
586 return;
587 }
588
589 return;
590 }
591 }
592
593 } else {
594 disk_state = ST_x08 | ST_x04 | ST_INVALID;
595 return;
596 }
597 } /* for (;;) */
598
599
600#ifdef GSCD_DEBUG
601 printk("\n");
602#endif
603}
604
605
606static void cmd_write_cmd(char *pstr)
607{
608 int i, j;
609
610 /* LOC_177 */
611#ifdef GSCD_DEBUG
612 printk("LOC_177 ");
613#endif
614
615 /* calculate the number of parameter */
616 j = *pstr & 0x0F;
617
618 /* shift it out */
619 for (i = 0; i < j; i++) {
620 outb(*pstr, GSCDPORT(2));
621 pstr++;
622 }
623}
624
625
626static int cmd_unit_alive(void)
627{
628 int result;
629 unsigned long max_test_loops;
630
631
632 /* LOC_172 */
633#ifdef GSCD_DEBUG
634 printk("LOC_172 ");
635#endif
636
637 outb(curr_drv_state, GSCDPORT(0));
638 max_test_loops = 0xFFFF;
639
640 do {
641 result = wait_drv_ready();
642 max_test_loops--;
643 } while ((result != 0x08) && (max_test_loops > 0));
644
645 return result;
646}
647
648
649static void cmd_info_in(char *pb, int count)
650{
651 int result;
652 char read;
653
654
655 /* read info */
656 /* LOC_182 */
657#ifdef GSCD_DEBUG
658 printk("LOC_182 ");
659#endif
660
661 do {
662 read = inb(GSCDPORT(2));
663 if (count > 0) {
664 *pb = read;
665 pb++;
666 count--;
667 }
668
669 /* LOC_183 */
670 do {
671 result = wait_drv_ready();
672 } while (result == 0x0E);
673 } while (result == 6);
674
675 cmd_end();
676 return;
677}
678
679
680static void cmd_read_b(char *pb, int count, int size)
681{
682 int result;
683 int i;
684
685
686 /* LOC_188 */
687 /* LOC_189 */
688#ifdef GSCD_DEBUG
689 printk("LOC_189 ");
690#endif
691
692 do {
693 do {
694 result = wait_drv_ready();
695 } while (result != 6 || result == 0x0E);
696
697 if (result != 6) {
698 cmd_end();
699 return;
700 }
701#ifdef GSCD_DEBUG
702 printk("LOC_191 ");
703#endif
704
705 for (i = 0; i < size; i++) {
706 *pb = inb(GSCDPORT(2));
707 pb++;
708 }
709 count--;
710 } while (count > 0);
711
712 cmd_end();
713 return;
714}
715
716
717static void cmd_end(void)
718{
719 int result;
720
721
722 /* LOC_204 */
723#ifdef GSCD_DEBUG
724 printk("LOC_204 ");
725#endif
726
727 do {
728 result = wait_drv_ready();
729 if (result == drv_mode) {
730 return;
731 }
732 } while (result != 4);
733
734 /* LOC_205 */
735#ifdef GSCD_DEBUG
736 printk("LOC_205 ");
737#endif
738
739 disk_state = inb(GSCDPORT(2));
740
741 do {
742 result = wait_drv_ready();
743 } while (result != drv_mode);
744 return;
745
746}
747
748
749static void cmd_read_w(char *pb, int count, int size)
750{
751 int result;
752 int i;
753
754
755#ifdef GSCD_DEBUG
756 printk("LOC_185 ");
757#endif
758
759 do {
760 /* LOC_185 */
761 do {
762 result = wait_drv_ready();
763 } while (result != 6 || result == 0x0E);
764
765 if (result != 6) {
766 cmd_end();
767 return;
768 }
769
770 for (i = 0; i < size; i++) {
771 /* na, hier muss ich noch mal drueber nachdenken */
772 *pb = inw(GSCDPORT(2));
773 pb++;
774 }
775 count--;
776 } while (count > 0);
777
778 cmd_end();
779 return;
780}
781
782static int __init find_drives(void)
783{
784 int *pdrv;
785 int drvnum;
786 int subdrv;
787 int i;
788
789 speed = 0;
790 pdrv = (int *) &drv_states;
791 curr_drv_state = 0xFE;
792 subdrv = 0;
793 drvnum = 0;
794
795 for (i = 0; i < 8; i++) {
796 subdrv++;
797 cmd_status();
798 disk_state &= ST_x08 | ST_x04 | ST_INVALID | ST_x01;
799 if (disk_state != (ST_x08 | ST_x04 | ST_INVALID)) {
800 /* LOC_240 */
801 *pdrv = curr_drv_state;
802 init_cd_drive(drvnum);
803 pdrv++;
804 drvnum++;
805 } else {
806 if (subdrv < 2) {
807 continue;
808 } else {
809 subdrv = 0;
810 }
811 }
812
813/* curr_drv_state<<1; <-- das geht irgendwie nicht */
814/* muss heissen: curr_drv_state <<= 1; (ist ja Wert-Zuweisung) */
815 curr_drv_state *= 2;
816 curr_drv_state |= 1;
817#ifdef GSCD_DEBUG
818 printk("DriveState: %d\n", curr_drv_state);
819#endif
820 }
821
822 ndrives = drvnum;
823 return drvnum;
824}
825
826static void __init init_cd_drive(int num)
827{
828 char resp[50];
829 int i;
830
831 printk("GSCD: init unit %d\n", num);
832 cc_Ident((char *) &resp);
833
834 printk("GSCD: identification: ");
835 for (i = 0; i < 0x1E; i++) {
836 printk("%c", resp[i]);
837 }
838 printk("\n");
839
840 cc_SetSpeed();
841
842}
843
844#ifdef FUTURE_WORK
845/* return_done */
846static void update_state(void)
847{
848 unsigned int AX;
849
850
851 if ((disk_state & (ST_x08 | ST_x04 | ST_INVALID | ST_x01)) == 0) {
852 if (disk_state == (ST_x08 | ST_x04 | ST_INVALID)) {
853 AX = ST_INVALID;
854 }
855
856 if ((disk_state & (ST_x08 | ST_x04 | ST_INVALID | ST_x01))
857 == 0) {
858 invalidate();
859 f_drv_ok = 0;
860 }
861
862 AX |= 0x8000;
863 }
864
865 if (disk_state & ST_PLAYING) {
866 AX |= 0x200;
867 }
868
869 AX |= 0x100;
870 /* pkt_esbx = AX; */
871
872 disk_state = 0;
873
874}
875#endif
876
877static struct gendisk *gscd_disk;
878
879static void __exit gscd_exit(void)
880{
881 CLEAR_TIMER;
882
883 del_gendisk(gscd_disk);
884 put_disk(gscd_disk);
885 if ((unregister_blkdev(MAJOR_NR, "gscd") == -EINVAL)) {
886 printk("What's that: can't unregister GoldStar-module\n");
887 return;
888 }
889 blk_cleanup_queue(gscd_queue);
890 release_region(gscd_port, GSCD_IO_EXTENT);
891 printk(KERN_INFO "GoldStar-module released.\n");
892}
893
894/* This is the common initialisation for the GoldStar drive. */
895/* It is called at boot time AND for module init. */
896static int __init gscd_init(void)
897{
898 int i;
899 int result;
900 int ret=0;
901
902 printk(KERN_INFO "GSCD: version %s\n", GSCD_VERSION);
903 printk(KERN_INFO
904 "GSCD: Trying to detect a Goldstar R420 CD-ROM drive at 0x%X.\n",
905 gscd_port);
906
907 if (!request_region(gscd_port, GSCD_IO_EXTENT, "gscd")) {
908 printk(KERN_WARNING "GSCD: Init failed, I/O port (%X) already"
909 " in use.\n", gscd_port);
910 return -EIO;
911 }
912
913
914 /* check for card */
915 result = wait_drv_ready();
916 if (result == 0x09) {
917 printk(KERN_WARNING "GSCD: DMA kann ich noch nicht!\n");
918 ret = -EIO;
919 goto err_out1;
920 }
921
922 if (result == 0x0b) {
923 drv_mode = result;
924 i = find_drives();
925 if (i == 0) {
926 printk(KERN_WARNING "GSCD: GoldStar CD-ROM Drive is"
927 " not found.\n");
928 ret = -EIO;
929 goto err_out1;
930 }
931 }
932
933 if ((result != 0x0b) && (result != 0x09)) {
934 printk(KERN_WARNING "GSCD: GoldStar Interface Adapter does not "
935 "exist or H/W error\n");
936 ret = -EIO;
937 goto err_out1;
938 }
939
940 /* reset all drives */
941 i = 0;
942 while (drv_states[i] != 0) {
943 curr_drv_state = drv_states[i];
944 printk(KERN_INFO "GSCD: Reset unit %d ... ", i);
945 cc_Reset();
946 printk("done\n");
947 i++;
948 }
949
950 gscd_disk = alloc_disk(1);
951 if (!gscd_disk)
952 goto err_out1;
953 gscd_disk->major = MAJOR_NR;
954 gscd_disk->first_minor = 0;
955 gscd_disk->fops = &gscd_fops;
956 sprintf(gscd_disk->disk_name, "gscd");
957
958 if (register_blkdev(MAJOR_NR, "gscd")) {
959 ret = -EIO;
960 goto err_out2;
961 }
962
963 gscd_queue = blk_init_queue(do_gscd_request, &gscd_lock);
964 if (!gscd_queue) {
965 ret = -ENOMEM;
966 goto err_out3;
967 }
968
969 disk_state = 0;
970 gscdPresent = 1;
971
972 gscd_disk->queue = gscd_queue;
973 add_disk(gscd_disk);
974
975 printk(KERN_INFO "GSCD: GoldStar CD-ROM Drive found.\n");
976 return 0;
977
978err_out3:
979 unregister_blkdev(MAJOR_NR, "gscd");
980err_out2:
981 put_disk(gscd_disk);
982err_out1:
983 release_region(gscd_port, GSCD_IO_EXTENT);
984 return ret;
985}
986
987static void gscd_hsg2msf(long hsg, struct msf *msf)
988{
989 hsg += CD_MSF_OFFSET;
990 msf->min = hsg / (CD_FRAMES * CD_SECS);
991 hsg %= CD_FRAMES * CD_SECS;
992 msf->sec = hsg / CD_FRAMES;
993 msf->frame = hsg % CD_FRAMES;
994
995 gscd_bin2bcd(&msf->min); /* convert to BCD */
996 gscd_bin2bcd(&msf->sec);
997 gscd_bin2bcd(&msf->frame);
998}
999
1000
1001static void gscd_bin2bcd(unsigned char *p)
1002{
1003 int u, t;
1004
1005 u = *p % 10;
1006 t = *p / 10;
1007 *p = u | (t << 4);
1008}
1009
1010
1011#ifdef FUTURE_WORK
1012static long gscd_msf2hsg(struct msf *mp)
1013{
1014 return gscd_bcd2bin(mp->frame)
1015 + gscd_bcd2bin(mp->sec) * CD_FRAMES
1016 + gscd_bcd2bin(mp->min) * CD_FRAMES * CD_SECS - CD_MSF_OFFSET;
1017}
1018
1019static int gscd_bcd2bin(unsigned char bcd)
1020{
1021 return (bcd >> 4) * 10 + (bcd & 0xF);
1022}
1023#endif
1024
1025MODULE_AUTHOR("Oliver Raupach <raupach@nwfs1.rz.fh-hannover.de>");
1026MODULE_LICENSE("GPL");
1027module_init(gscd_init);
1028module_exit(gscd_exit);
1029MODULE_ALIAS_BLOCKDEV_MAJOR(GOLDSTAR_CDROM_MAJOR);
diff --git a/drivers/cdrom/gscd.h b/drivers/cdrom/gscd.h
deleted file mode 100644
index a41e64bfc061..000000000000
--- a/drivers/cdrom/gscd.h
+++ /dev/null
@@ -1,108 +0,0 @@
1/*
2 * Definitions for a GoldStar R420 CD-ROM interface
3 *
4 * Copyright (C) 1995 Oliver Raupach <raupach@nwfs1.rz.fh-hannover.de>
5 * Eberhard Moenkeberg <emoenke@gwdg.de>
6 *
7 * Published under the GPL.
8 *
9 */
10
11
12/* The Interface Card default address is 0x340. This will work for most
13 applications. Address selection is accomplished by jumpers PN801-1 to
14 PN801-4 on the GoldStar Interface Card.
15 Appropriate settings are: 0x300, 0x310, 0x320, 0x330, 0x340, 0x350, 0x360
16 0x370, 0x380, 0x390, 0x3A0, 0x3B0, 0x3C0, 0x3D0, 0x3E0, 0x3F0 */
17
18/* insert here the I/O port address and extent */
19#define GSCD_BASE_ADDR 0x340
20#define GSCD_IO_EXTENT 4
21
22
23/************** nothing to set up below here *********************/
24
25/* port access macro */
26#define GSCDPORT(x) (gscd_port + (x))
27
28/*
29 * commands
30 * the lower nibble holds the command length
31 */
32#define CMD_STATUS 0x01
33#define CMD_READSUBQ 0x02 /* 1: ?, 2: UPC, 5: ? */
34#define CMD_SEEK 0x05 /* read_mode M-S-F */
35#define CMD_READ 0x07 /* read_mode M-S-F nsec_h nsec_l */
36#define CMD_RESET 0x11
37#define CMD_SETMODE 0x15
38#define CMD_PLAY 0x17 /* M-S-F M-S-F */
39#define CMD_LOCK_CTL 0x22 /* 0: unlock, 1: lock */
40#define CMD_IDENT 0x31
41#define CMD_SETSPEED 0x32 /* 0: auto */ /* ??? */
42#define CMD_GETMODE 0x41
43#define CMD_PAUSE 0x51
44#define CMD_READTOC 0x61
45#define CMD_DISKINFO 0x71
46#define CMD_TRAY_CTL 0x81
47
48/*
49 * disk_state:
50 */
51#define ST_PLAYING 0x80
52#define ST_UNLOCKED 0x40
53#define ST_NO_DISK 0x20
54#define ST_DOOR_OPEN 0x10
55#define ST_x08 0x08
56#define ST_x04 0x04
57#define ST_INVALID 0x02
58#define ST_x01 0x01
59
60/*
61 * cmd_type:
62 */
63#define TYPE_INFO 0x01
64#define TYPE_DATA 0x02
65
66/*
67 * read_mode:
68 */
69#define MOD_POLLED 0x80
70#define MOD_x08 0x08
71#define MOD_RAW 0x04
72
73#define READ_DATA(port, buf, nr) insb(port, buf, nr)
74
75#define SET_TIMER(func, jifs) \
76 ((mod_timer(&gscd_timer, jiffies + jifs)), \
77 (gscd_timer.function = func))
78
79#define CLEAR_TIMER del_timer_sync(&gscd_timer)
80
81#define MAX_TRACKS 104
82
83struct msf {
84 unsigned char min;
85 unsigned char sec;
86 unsigned char frame;
87};
88
89struct gscd_Play_msf {
90 struct msf start;
91 struct msf end;
92};
93
94struct gscd_DiskInfo {
95 unsigned char first;
96 unsigned char last;
97 struct msf diskLength;
98 struct msf firstTrack;
99};
100
101struct gscd_Toc {
102 unsigned char ctrl_addr;
103 unsigned char track;
104 unsigned char pointIndex;
105 struct msf trackTime;
106 struct msf diskTime;
107};
108
diff --git a/drivers/cdrom/isp16.c b/drivers/cdrom/isp16.c
deleted file mode 100644
index db0fd9a240e3..000000000000
--- a/drivers/cdrom/isp16.c
+++ /dev/null
@@ -1,374 +0,0 @@
1/* -- ISP16 cdrom detection and configuration
2 *
3 * Copyright (c) 1995,1996 Eric van der Maarel <H.T.M.v.d.Maarel@marin.nl>
4 *
5 * Version 0.6
6 *
7 * History:
8 * 0.5 First release.
9 * Was included in the sjcd and optcd cdrom drivers.
10 * 0.6 First "stand-alone" version.
11 * Removed sound configuration.
12 * Added "module" support.
13 *
14 * 9 November 1999 -- Make kernel-parameter implementation work with 2.3.x
15 * Removed init_module & cleanup_module in favor of
16 * module_init & module_exit.
17 * Torben Mathiasen <tmm@image.dk>
18 *
19 * 19 June 2004 -- check_region() converted to request_region()
20 * and return statement cleanups.
21 * - Jesper Juhl
22 *
23 * Detect cdrom interface on ISP16 sound card.
24 * Configure cdrom interface.
25 *
26 * Algorithm for the card with OPTi 82C928 taken
27 * from the CDSETUP.SYS driver for MSDOS,
28 * by OPTi Computers, version 2.03.
29 * Algorithm for the card with OPTi 82C929 as communicated
30 * to me by Vadim Model and Leo Spiekman.
31 *
32 * This program is free software; you can redistribute it and/or modify
33 * it under the terms of the GNU General Public License as published by
34 * the Free Software Foundation; either version 2 of the License, or
35 * (at your option) any later version.
36 *
37 * This program is distributed in the hope that it will be useful,
38 * but WITHOUT ANY WARRANTY; without even the implied warranty of
39 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
40 * GNU General Public License for more details.
41 *
42 * You should have received a copy of the GNU General Public License
43 * along with this program; if not, write to the Free Software
44 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
45 *
46 */
47
48#define ISP16_VERSION_MAJOR 0
49#define ISP16_VERSION_MINOR 6
50
51#include <linux/module.h>
52
53#include <linux/fs.h>
54#include <linux/kernel.h>
55#include <linux/string.h>
56#include <linux/ioport.h>
57#include <linux/init.h>
58#include <asm/io.h>
59#include "isp16.h"
60
61static short isp16_detect(void);
62static short isp16_c928__detect(void);
63static short isp16_c929__detect(void);
64static short isp16_cdi_config(int base, u_char drive_type, int irq,
65 int dma);
66static short isp16_type; /* dependent on type of interface card */
67static u_char isp16_ctrl;
68static u_short isp16_enable_port;
69
70static int isp16_cdrom_base = ISP16_CDROM_IO_BASE;
71static int isp16_cdrom_irq = ISP16_CDROM_IRQ;
72static int isp16_cdrom_dma = ISP16_CDROM_DMA;
73static char *isp16_cdrom_type = ISP16_CDROM_TYPE;
74
75module_param(isp16_cdrom_base, int, 0);
76module_param(isp16_cdrom_irq, int, 0);
77module_param(isp16_cdrom_dma, int, 0);
78module_param(isp16_cdrom_type, charp, 0);
79
80#define ISP16_IN(p) (outb(isp16_ctrl,ISP16_CTRL_PORT), inb(p))
81#define ISP16_OUT(p,b) (outb(isp16_ctrl,ISP16_CTRL_PORT), outb(b,p))
82
83#ifndef MODULE
84
85static int
86__init isp16_setup(char *str)
87{
88 int ints[4];
89
90 (void) get_options(str, ARRAY_SIZE(ints), ints);
91 if (ints[0] > 0)
92 isp16_cdrom_base = ints[1];
93 if (ints[0] > 1)
94 isp16_cdrom_irq = ints[2];
95 if (ints[0] > 2)
96 isp16_cdrom_dma = ints[3];
97 if (str)
98 isp16_cdrom_type = str;
99
100 return 1;
101}
102
103__setup("isp16=", isp16_setup);
104
105#endif /* MODULE */
106
107/*
108 * ISP16 initialisation.
109 *
110 */
111static int __init isp16_init(void)
112{
113 u_char expected_drive;
114
115 printk(KERN_INFO
116 "ISP16: configuration cdrom interface, version %d.%d.\n",
117 ISP16_VERSION_MAJOR, ISP16_VERSION_MINOR);
118
119 if (!strcmp(isp16_cdrom_type, "noisp16")) {
120 printk("ISP16: no cdrom interface configured.\n");
121 return 0;
122 }
123
124 if (!request_region(ISP16_IO_BASE, ISP16_IO_SIZE, "isp16")) {
125 printk("ISP16: i/o ports already in use.\n");
126 goto out;
127 }
128
129 if ((isp16_type = isp16_detect()) < 0) {
130 printk("ISP16: no cdrom interface found.\n");
131 goto cleanup_out;
132 }
133
134 printk(KERN_INFO
135 "ISP16: cdrom interface (with OPTi 82C92%d chip) detected.\n",
136 (isp16_type == 2) ? 9 : 8);
137
138 if (!strcmp(isp16_cdrom_type, "Sanyo"))
139 expected_drive =
140 (isp16_type ? ISP16_SANYO1 : ISP16_SANYO0);
141 else if (!strcmp(isp16_cdrom_type, "Sony"))
142 expected_drive = ISP16_SONY;
143 else if (!strcmp(isp16_cdrom_type, "Panasonic"))
144 expected_drive =
145 (isp16_type ? ISP16_PANASONIC1 : ISP16_PANASONIC0);
146 else if (!strcmp(isp16_cdrom_type, "Mitsumi"))
147 expected_drive = ISP16_MITSUMI;
148 else {
149 printk("ISP16: %s not supported by cdrom interface.\n",
150 isp16_cdrom_type);
151 goto cleanup_out;
152 }
153
154 if (isp16_cdi_config(isp16_cdrom_base, expected_drive,
155 isp16_cdrom_irq, isp16_cdrom_dma) < 0) {
156 printk
157 ("ISP16: cdrom interface has not been properly configured.\n");
158 goto cleanup_out;
159 }
160 printk(KERN_INFO
161 "ISP16: cdrom interface set up with io base 0x%03X, irq %d, dma %d,"
162 " type %s.\n", isp16_cdrom_base, isp16_cdrom_irq,
163 isp16_cdrom_dma, isp16_cdrom_type);
164 return 0;
165
166cleanup_out:
167 release_region(ISP16_IO_BASE, ISP16_IO_SIZE);
168out:
169 return -EIO;
170}
171
172static short __init isp16_detect(void)
173{
174
175 if (isp16_c929__detect() >= 0)
176 return 2;
177 else
178 return (isp16_c928__detect());
179}
180
181static short __init isp16_c928__detect(void)
182{
183 u_char ctrl;
184 u_char enable_cdrom;
185 u_char io;
186 short i = -1;
187
188 isp16_ctrl = ISP16_C928__CTRL;
189 isp16_enable_port = ISP16_C928__ENABLE_PORT;
190
191 /* read' and write' are a special read and write, respectively */
192
193 /* read' ISP16_CTRL_PORT, clear last two bits and write' back the result */
194 ctrl = ISP16_IN(ISP16_CTRL_PORT) & 0xFC;
195 ISP16_OUT(ISP16_CTRL_PORT, ctrl);
196
197 /* read' 3,4 and 5-bit from the cdrom enable port */
198 enable_cdrom = ISP16_IN(ISP16_C928__ENABLE_PORT) & 0x38;
199
200 if (!(enable_cdrom & 0x20)) { /* 5-bit not set */
201 /* read' last 2 bits of ISP16_IO_SET_PORT */
202 io = ISP16_IN(ISP16_IO_SET_PORT) & 0x03;
203 if (((io & 0x01) << 1) == (io & 0x02)) { /* bits are the same */
204 if (io == 0) { /* ...the same and 0 */
205 i = 0;
206 enable_cdrom |= 0x20;
207 } else { /* ...the same and 1 *//* my card, first time 'round */
208 i = 1;
209 enable_cdrom |= 0x28;
210 }
211 ISP16_OUT(ISP16_C928__ENABLE_PORT, enable_cdrom);
212 } else { /* bits are not the same */
213 ISP16_OUT(ISP16_CTRL_PORT, ctrl);
214 return i; /* -> not detected: possibly incorrect conclusion */
215 }
216 } else if (enable_cdrom == 0x20)
217 i = 0;
218 else if (enable_cdrom == 0x28) /* my card, already initialised */
219 i = 1;
220
221 ISP16_OUT(ISP16_CTRL_PORT, ctrl);
222
223 return i;
224}
225
226static short __init isp16_c929__detect(void)
227{
228 u_char ctrl;
229 u_char tmp;
230
231 isp16_ctrl = ISP16_C929__CTRL;
232 isp16_enable_port = ISP16_C929__ENABLE_PORT;
233
234 /* read' and write' are a special read and write, respectively */
235
236 /* read' ISP16_CTRL_PORT and save */
237 ctrl = ISP16_IN(ISP16_CTRL_PORT);
238
239 /* write' zero to the ctrl port and get response */
240 ISP16_OUT(ISP16_CTRL_PORT, 0);
241 tmp = ISP16_IN(ISP16_CTRL_PORT);
242
243 if (tmp != 2) /* isp16 with 82C929 not detected */
244 return -1;
245
246 /* restore ctrl port value */
247 ISP16_OUT(ISP16_CTRL_PORT, ctrl);
248
249 return 2;
250}
251
252static short __init
253isp16_cdi_config(int base, u_char drive_type, int irq, int dma)
254{
255 u_char base_code;
256 u_char irq_code;
257 u_char dma_code;
258 u_char i;
259
260 if ((drive_type == ISP16_MITSUMI) && (dma != 0))
261 printk("ISP16: Mitsumi cdrom drive has no dma support.\n");
262
263 switch (base) {
264 case 0x340:
265 base_code = ISP16_BASE_340;
266 break;
267 case 0x330:
268 base_code = ISP16_BASE_330;
269 break;
270 case 0x360:
271 base_code = ISP16_BASE_360;
272 break;
273 case 0x320:
274 base_code = ISP16_BASE_320;
275 break;
276 default:
277 printk
278 ("ISP16: base address 0x%03X not supported by cdrom interface.\n",
279 base);
280 return -1;
281 }
282 switch (irq) {
283 case 0:
284 irq_code = ISP16_IRQ_X;
285 break; /* disable irq */
286 case 5:
287 irq_code = ISP16_IRQ_5;
288 printk("ISP16: irq 5 shouldn't be used by cdrom interface,"
289 " due to possible conflicts with the sound card.\n");
290 break;
291 case 7:
292 irq_code = ISP16_IRQ_7;
293 printk("ISP16: irq 7 shouldn't be used by cdrom interface,"
294 " due to possible conflicts with the sound card.\n");
295 break;
296 case 3:
297 irq_code = ISP16_IRQ_3;
298 break;
299 case 9:
300 irq_code = ISP16_IRQ_9;
301 break;
302 case 10:
303 irq_code = ISP16_IRQ_10;
304 break;
305 case 11:
306 irq_code = ISP16_IRQ_11;
307 break;
308 default:
309 printk("ISP16: irq %d not supported by cdrom interface.\n",
310 irq);
311 return -1;
312 }
313 switch (dma) {
314 case 0:
315 dma_code = ISP16_DMA_X;
316 break; /* disable dma */
317 case 1:
318 printk("ISP16: dma 1 cannot be used by cdrom interface,"
319 " due to conflict with the sound card.\n");
320 return -1;
321 break;
322 case 3:
323 dma_code = ISP16_DMA_3;
324 break;
325 case 5:
326 dma_code = ISP16_DMA_5;
327 break;
328 case 6:
329 dma_code = ISP16_DMA_6;
330 break;
331 case 7:
332 dma_code = ISP16_DMA_7;
333 break;
334 default:
335 printk("ISP16: dma %d not supported by cdrom interface.\n",
336 dma);
337 return -1;
338 }
339
340 if (drive_type != ISP16_SONY && drive_type != ISP16_PANASONIC0 &&
341 drive_type != ISP16_PANASONIC1 && drive_type != ISP16_SANYO0 &&
342 drive_type != ISP16_SANYO1 && drive_type != ISP16_MITSUMI &&
343 drive_type != ISP16_DRIVE_X) {
344 printk
345 ("ISP16: drive type (code 0x%02X) not supported by cdrom"
346 " interface.\n", drive_type);
347 return -1;
348 }
349
350 /* set type of interface */
351 i = ISP16_IN(ISP16_DRIVE_SET_PORT) & ISP16_DRIVE_SET_MASK; /* clear some bits */
352 ISP16_OUT(ISP16_DRIVE_SET_PORT, i | drive_type);
353
354 /* enable cdrom on interface with 82C929 chip */
355 if (isp16_type > 1)
356 ISP16_OUT(isp16_enable_port, ISP16_ENABLE_CDROM);
357
358 /* set base address, irq and dma */
359 i = ISP16_IN(ISP16_IO_SET_PORT) & ISP16_IO_SET_MASK; /* keep some bits */
360 ISP16_OUT(ISP16_IO_SET_PORT, i | base_code | irq_code | dma_code);
361
362 return 0;
363}
364
365static void __exit isp16_exit(void)
366{
367 release_region(ISP16_IO_BASE, ISP16_IO_SIZE);
368 printk(KERN_INFO "ISP16: module released.\n");
369}
370
371module_init(isp16_init);
372module_exit(isp16_exit);
373
374MODULE_LICENSE("GPL");
diff --git a/drivers/cdrom/isp16.h b/drivers/cdrom/isp16.h
deleted file mode 100644
index 5bd22c8f7a96..000000000000
--- a/drivers/cdrom/isp16.h
+++ /dev/null
@@ -1,72 +0,0 @@
1/* -- isp16.h
2 *
3 * Header for detection and initialisation of cdrom interface (only) on
4 * ISP16 (MAD16, Mozart) sound card.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 *
20 */
21
22/* These are the default values */
23#define ISP16_CDROM_TYPE "Sanyo"
24#define ISP16_CDROM_IO_BASE 0x340
25#define ISP16_CDROM_IRQ 0
26#define ISP16_CDROM_DMA 0
27
28/* Some (Media)Magic */
29/* define types of drive the interface on an ISP16 card may be looking at */
30#define ISP16_DRIVE_X 0x00
31#define ISP16_SONY 0x02
32#define ISP16_PANASONIC0 0x02
33#define ISP16_SANYO0 0x02
34#define ISP16_MITSUMI 0x04
35#define ISP16_PANASONIC1 0x06
36#define ISP16_SANYO1 0x06
37#define ISP16_DRIVE_NOT_USED 0x08 /* not used */
38#define ISP16_DRIVE_SET_MASK 0xF1 /* don't change 0-bit or 4-7-bits*/
39/* ...for port */
40#define ISP16_DRIVE_SET_PORT 0xF8D
41/* set io parameters */
42#define ISP16_BASE_340 0x00
43#define ISP16_BASE_330 0x40
44#define ISP16_BASE_360 0x80
45#define ISP16_BASE_320 0xC0
46#define ISP16_IRQ_X 0x00
47#define ISP16_IRQ_5 0x04 /* shouldn't be used to avoid sound card conflicts */
48#define ISP16_IRQ_7 0x08 /* shouldn't be used to avoid sound card conflicts */
49#define ISP16_IRQ_3 0x0C
50#define ISP16_IRQ_9 0x10
51#define ISP16_IRQ_10 0x14
52#define ISP16_IRQ_11 0x18
53#define ISP16_DMA_X 0x03
54#define ISP16_DMA_3 0x00
55#define ISP16_DMA_5 0x00
56#define ISP16_DMA_6 0x01
57#define ISP16_DMA_7 0x02
58#define ISP16_IO_SET_MASK 0x20 /* don't change 5-bit */
59/* ...for port */
60#define ISP16_IO_SET_PORT 0xF8E
61/* enable the card */
62#define ISP16_C928__ENABLE_PORT 0xF90 /* ISP16 with OPTi 82C928 chip */
63#define ISP16_C929__ENABLE_PORT 0xF91 /* ISP16 with OPTi 82C929 chip */
64#define ISP16_ENABLE_CDROM 0x80 /* seven bit */
65
66/* the magic stuff */
67#define ISP16_CTRL_PORT 0xF8F
68#define ISP16_C928__CTRL 0xE2 /* ISP16 with OPTi 82C928 chip */
69#define ISP16_C929__CTRL 0xE3 /* ISP16 with OPTi 82C929 chip */
70
71#define ISP16_IO_BASE 0xF8D
72#define ISP16_IO_SIZE 5 /* ports used from 0xF8D up to 0xF91 */
diff --git a/drivers/cdrom/mcdx.c b/drivers/cdrom/mcdx.c
deleted file mode 100644
index 4310cc84dfed..000000000000
--- a/drivers/cdrom/mcdx.c
+++ /dev/null
@@ -1,1943 +0,0 @@
1/*
2 * The Mitsumi CDROM interface
3 * Copyright (C) 1995 1996 Heiko Schlittermann <heiko@lotte.sax.de>
4 * VERSION: 2.14(hs)
5 *
6 * ... anyway, I'm back again, thanks to Marcin, he adopted
7 * large portions of my code (at least the parts containing
8 * my main thoughts ...)
9 *
10 ****************** H E L P *********************************
11 * If you ever plan to update your CD ROM drive and perhaps
12 * want to sell or simply give away your Mitsumi FX-001[DS]
13 * -- Please --
14 * mail me (heiko@lotte.sax.de). When my last drive goes
15 * ballistic no more driver support will be available from me!
16 *************************************************************
17 *
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by
20 * the Free Software Foundation; either version 2, or (at your option)
21 * any later version.
22 *
23 * This program is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
27 *
28 * You should have received a copy of the GNU General Public License
29 * along with this program; see the file COPYING. If not, write to
30 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
31 *
32 * Thanks to
33 * The Linux Community at all and ...
34 * Martin Harriss (he wrote the first Mitsumi Driver)
35 * Eberhard Moenkeberg (he gave me much support and the initial kick)
36 * Bernd Huebner, Ruediger Helsch (Unifix-Software GmbH, they
37 * improved the original driver)
38 * Jon Tombs, Bjorn Ekwall (module support)
39 * Daniel v. Mosnenck (he sent me the Technical and Programming Reference)
40 * Gerd Knorr (he lent me his PhotoCD)
41 * Nils Faerber and Roger E. Wolff (extensively tested the LU portion)
42 * Andreas Kies (testing the mysterious hang-ups)
43 * Heiko Eissfeldt (VERIFY_READ/WRITE)
44 * Marcin Dalecki (improved performance, shortened code)
45 * ... somebody forgotten?
46 *
47 * 9 November 1999 -- Make kernel-parameter implementation work with 2.3.x
48 * Removed init_module & cleanup_module in favor of
49 * module_init & module_exit.
50 * Torben Mathiasen <tmm@image.dk>
51 */
52
53
54#ifdef RCS
55static const char *mcdx_c_version
56 = "$Id: mcdx.c,v 1.21 1997/01/26 07:12:59 davem Exp $";
57#endif
58
59#include <linux/module.h>
60
61#include <linux/errno.h>
62#include <linux/interrupt.h>
63#include <linux/fs.h>
64#include <linux/kernel.h>
65#include <linux/cdrom.h>
66#include <linux/ioport.h>
67#include <linux/mm.h>
68#include <linux/slab.h>
69#include <linux/init.h>
70#include <asm/io.h>
71#include <asm/current.h>
72#include <asm/uaccess.h>
73
74#include <linux/major.h>
75#define MAJOR_NR MITSUMI_X_CDROM_MAJOR
76#include <linux/blkdev.h>
77
78#include "mcdx.h"
79
80#ifndef HZ
81#error HZ not defined
82#endif
83
84#define xwarn(fmt, args...) printk(KERN_WARNING MCDX " " fmt, ## args)
85
86#if !MCDX_QUIET
87#define xinfo(fmt, args...) printk(KERN_INFO MCDX " " fmt, ## args)
88#else
89#define xinfo(fmt, args...) { ; }
90#endif
91
92#if MCDX_DEBUG
93#define xtrace(lvl, fmt, args...) \
94 { if (lvl > 0) \
95 { printk(KERN_DEBUG MCDX ":: " fmt, ## args); } }
96#define xdebug(fmt, args...) printk(KERN_DEBUG MCDX ":: " fmt, ## args)
97#else
98#define xtrace(lvl, fmt, args...) { ; }
99#define xdebug(fmt, args...) { ; }
100#endif
101
102/* CONSTANTS *******************************************************/
103
104/* Following are the number of sectors we _request_ from the drive
105 every time an access outside the already requested range is done.
106 The _direct_ size is the number of sectors we're allowed to skip
107 directly (performing a read instead of requesting the new sector
108 needed */
109static const int REQUEST_SIZE = 800; /* should be less then 255 * 4 */
110static const int DIRECT_SIZE = 400; /* should be less then REQUEST_SIZE */
111
112enum drivemodes { TOC, DATA, RAW, COOKED };
113enum datamodes { MODE0, MODE1, MODE2 };
114enum resetmodes { SOFT, HARD };
115
116static const int SINGLE = 0x01; /* single speed drive (FX001S, LU) */
117static const int DOUBLE = 0x02; /* double speed drive (FX001D, ..? */
118static const int DOOR = 0x04; /* door locking capability */
119static const int MULTI = 0x08; /* multi session capability */
120
121static const unsigned char READ1X = 0xc0;
122static const unsigned char READ2X = 0xc1;
123
124
125/* DECLARATIONS ****************************************************/
126struct s_subqcode {
127 unsigned char control;
128 unsigned char tno;
129 unsigned char index;
130 struct cdrom_msf0 tt;
131 struct cdrom_msf0 dt;
132};
133
134struct s_diskinfo {
135 unsigned int n_first;
136 unsigned int n_last;
137 struct cdrom_msf0 msf_leadout;
138 struct cdrom_msf0 msf_first;
139};
140
141struct s_multi {
142 unsigned char multi;
143 struct cdrom_msf0 msf_last;
144};
145
146struct s_version {
147 unsigned char code;
148 unsigned char ver;
149};
150
151/* Per drive/controller stuff **************************************/
152
153struct s_drive_stuff {
154 /* waitqueues */
155 wait_queue_head_t busyq;
156 wait_queue_head_t lockq;
157 wait_queue_head_t sleepq;
158
159 /* flags */
160 volatile int introk; /* status of last irq operation */
161 volatile int busy; /* drive performs an operation */
162 volatile int lock; /* exclusive usage */
163
164 /* cd infos */
165 struct s_diskinfo di;
166 struct s_multi multi;
167 struct s_subqcode *toc; /* first entry of the toc array */
168 struct s_subqcode start;
169 struct s_subqcode stop;
170 int xa; /* 1 if xa disk */
171 int audio; /* 1 if audio disk */
172 int audiostatus;
173
174 /* `buffer' control */
175 volatile int valid; /* pending, ..., values are valid */
176 volatile int pending; /* next sector to be read */
177 volatile int low_border; /* first sector not to be skipped direct */
178 volatile int high_border; /* first sector `out of area' */
179#ifdef AK2
180 volatile int int_err;
181#endif /* AK2 */
182
183 /* adds and odds */
184 unsigned wreg_data; /* w data */
185 unsigned wreg_reset; /* w hardware reset */
186 unsigned wreg_hcon; /* w hardware conf */
187 unsigned wreg_chn; /* w channel */
188 unsigned rreg_data; /* r data */
189 unsigned rreg_status; /* r status */
190
191 int irq; /* irq used by this drive */
192 int present; /* drive present and its capabilities */
193 unsigned char readcmd; /* read cmd depends on single/double speed */
194 unsigned char playcmd; /* play should always be single speed */
195 unsigned int xxx; /* set if changed, reset while open */
196 unsigned int yyy; /* set if changed, reset by media_changed */
197 int users; /* keeps track of open/close */
198 int lastsector; /* last block accessible */
199 int status; /* last operation's error / status */
200 int readerrs; /* # of blocks read w/o error */
201 struct cdrom_device_info info;
202 struct gendisk *disk;
203};
204
205
206/* Prototypes ******************************************************/
207
208/* The following prototypes are already declared elsewhere. They are
209 repeated here to show what's going on. And to sense, if they're
210 changed elsewhere. */
211
212static int mcdx_init(void);
213
214static int mcdx_block_open(struct inode *inode, struct file *file)
215{
216 struct s_drive_stuff *p = inode->i_bdev->bd_disk->private_data;
217 return cdrom_open(&p->info, inode, file);
218}
219
220static int mcdx_block_release(struct inode *inode, struct file *file)
221{
222 struct s_drive_stuff *p = inode->i_bdev->bd_disk->private_data;
223 return cdrom_release(&p->info, file);
224}
225
226static int mcdx_block_ioctl(struct inode *inode, struct file *file,
227 unsigned cmd, unsigned long arg)
228{
229 struct s_drive_stuff *p = inode->i_bdev->bd_disk->private_data;
230 return cdrom_ioctl(file, &p->info, inode, cmd, arg);
231}
232
233static int mcdx_block_media_changed(struct gendisk *disk)
234{
235 struct s_drive_stuff *p = disk->private_data;
236 return cdrom_media_changed(&p->info);
237}
238
239static struct block_device_operations mcdx_bdops =
240{
241 .owner = THIS_MODULE,
242 .open = mcdx_block_open,
243 .release = mcdx_block_release,
244 .ioctl = mcdx_block_ioctl,
245 .media_changed = mcdx_block_media_changed,
246};
247
248
249/* Indirect exported functions. These functions are exported by their
250 addresses, such as mcdx_open and mcdx_close in the
251 structure mcdx_dops. */
252
253/* exported by file_ops */
254static int mcdx_open(struct cdrom_device_info *cdi, int purpose);
255static void mcdx_close(struct cdrom_device_info *cdi);
256static int mcdx_media_changed(struct cdrom_device_info *cdi, int disc_nr);
257static int mcdx_tray_move(struct cdrom_device_info *cdi, int position);
258static int mcdx_lockdoor(struct cdrom_device_info *cdi, int lock);
259static int mcdx_audio_ioctl(struct cdrom_device_info *cdi,
260 unsigned int cmd, void *arg);
261
262/* misc internal support functions */
263static void log2msf(unsigned int, struct cdrom_msf0 *);
264static unsigned int msf2log(const struct cdrom_msf0 *);
265static unsigned int uint2bcd(unsigned int);
266static unsigned int bcd2uint(unsigned char);
267static unsigned port(int *);
268static int irq(int *);
269static void mcdx_delay(struct s_drive_stuff *, long jifs);
270static int mcdx_transfer(struct s_drive_stuff *, char *buf, int sector,
271 int nr_sectors);
272static int mcdx_xfer(struct s_drive_stuff *, char *buf, int sector,
273 int nr_sectors);
274
275static int mcdx_config(struct s_drive_stuff *, int);
276static int mcdx_requestversion(struct s_drive_stuff *, struct s_version *,
277 int);
278static int mcdx_stop(struct s_drive_stuff *, int);
279static int mcdx_hold(struct s_drive_stuff *, int);
280static int mcdx_reset(struct s_drive_stuff *, enum resetmodes, int);
281static int mcdx_setdrivemode(struct s_drive_stuff *, enum drivemodes, int);
282static int mcdx_setdatamode(struct s_drive_stuff *, enum datamodes, int);
283static int mcdx_requestsubqcode(struct s_drive_stuff *,
284 struct s_subqcode *, int);
285static int mcdx_requestmultidiskinfo(struct s_drive_stuff *,
286 struct s_multi *, int);
287static int mcdx_requesttocdata(struct s_drive_stuff *, struct s_diskinfo *,
288 int);
289static int mcdx_getstatus(struct s_drive_stuff *, int);
290static int mcdx_getval(struct s_drive_stuff *, int to, int delay, char *);
291static int mcdx_talk(struct s_drive_stuff *,
292 const unsigned char *cmd, size_t,
293 void *buffer, size_t size, unsigned int timeout, int);
294static int mcdx_readtoc(struct s_drive_stuff *);
295static int mcdx_playtrk(struct s_drive_stuff *, const struct cdrom_ti *);
296static int mcdx_playmsf(struct s_drive_stuff *, const struct cdrom_msf *);
297static int mcdx_setattentuator(struct s_drive_stuff *,
298 struct cdrom_volctrl *, int);
299
300/* static variables ************************************************/
301
302static int mcdx_drive_map[][2] = MCDX_DRIVEMAP;
303static struct s_drive_stuff *mcdx_stuffp[MCDX_NDRIVES];
304static DEFINE_SPINLOCK(mcdx_lock);
305static struct request_queue *mcdx_queue;
306
307/* You can only set the first two pairs, from old MODULE_PARM code. */
308static int mcdx_set(const char *val, struct kernel_param *kp)
309{
310 get_options((char *)val, 4, (int *)mcdx_drive_map);
311 return 0;
312}
313module_param_call(mcdx, mcdx_set, NULL, NULL, 0);
314
315static struct cdrom_device_ops mcdx_dops = {
316 .open = mcdx_open,
317 .release = mcdx_close,
318 .media_changed = mcdx_media_changed,
319 .tray_move = mcdx_tray_move,
320 .lock_door = mcdx_lockdoor,
321 .audio_ioctl = mcdx_audio_ioctl,
322 .capability = CDC_OPEN_TRAY | CDC_LOCK | CDC_MEDIA_CHANGED |
323 CDC_PLAY_AUDIO | CDC_DRIVE_STATUS,
324};
325
326/* KERNEL INTERFACE FUNCTIONS **************************************/
327
328
329static int mcdx_audio_ioctl(struct cdrom_device_info *cdi,
330 unsigned int cmd, void *arg)
331{
332 struct s_drive_stuff *stuffp = cdi->handle;
333
334 if (!stuffp->present)
335 return -ENXIO;
336
337 if (stuffp->xxx) {
338 if (-1 == mcdx_requesttocdata(stuffp, &stuffp->di, 1)) {
339 stuffp->lastsector = -1;
340 } else {
341 stuffp->lastsector = (CD_FRAMESIZE / 512)
342 * msf2log(&stuffp->di.msf_leadout) - 1;
343 }
344
345 if (stuffp->toc) {
346 kfree(stuffp->toc);
347 stuffp->toc = NULL;
348 if (-1 == mcdx_readtoc(stuffp))
349 return -1;
350 }
351
352 stuffp->xxx = 0;
353 }
354
355 switch (cmd) {
356 case CDROMSTART:{
357 xtrace(IOCTL, "ioctl() START\n");
358 /* Spin up the drive. Don't think we can do this.
359 * For now, ignore it.
360 */
361 return 0;
362 }
363
364 case CDROMSTOP:{
365 xtrace(IOCTL, "ioctl() STOP\n");
366 stuffp->audiostatus = CDROM_AUDIO_INVALID;
367 if (-1 == mcdx_stop(stuffp, 1))
368 return -EIO;
369 return 0;
370 }
371
372 case CDROMPLAYTRKIND:{
373 struct cdrom_ti *ti = (struct cdrom_ti *) arg;
374
375 xtrace(IOCTL, "ioctl() PLAYTRKIND\n");
376 if ((ti->cdti_trk0 < stuffp->di.n_first)
377 || (ti->cdti_trk0 > stuffp->di.n_last)
378 || (ti->cdti_trk1 < stuffp->di.n_first))
379 return -EINVAL;
380 if (ti->cdti_trk1 > stuffp->di.n_last)
381 ti->cdti_trk1 = stuffp->di.n_last;
382 xtrace(PLAYTRK, "ioctl() track %d to %d\n",
383 ti->cdti_trk0, ti->cdti_trk1);
384 return mcdx_playtrk(stuffp, ti);
385 }
386
387 case CDROMPLAYMSF:{
388 struct cdrom_msf *msf = (struct cdrom_msf *) arg;
389
390 xtrace(IOCTL, "ioctl() PLAYMSF\n");
391
392 if ((stuffp->audiostatus == CDROM_AUDIO_PLAY)
393 && (-1 == mcdx_hold(stuffp, 1)))
394 return -EIO;
395
396 msf->cdmsf_min0 = uint2bcd(msf->cdmsf_min0);
397 msf->cdmsf_sec0 = uint2bcd(msf->cdmsf_sec0);
398 msf->cdmsf_frame0 = uint2bcd(msf->cdmsf_frame0);
399
400 msf->cdmsf_min1 = uint2bcd(msf->cdmsf_min1);
401 msf->cdmsf_sec1 = uint2bcd(msf->cdmsf_sec1);
402 msf->cdmsf_frame1 = uint2bcd(msf->cdmsf_frame1);
403
404 stuffp->stop.dt.minute = msf->cdmsf_min1;
405 stuffp->stop.dt.second = msf->cdmsf_sec1;
406 stuffp->stop.dt.frame = msf->cdmsf_frame1;
407
408 return mcdx_playmsf(stuffp, msf);
409 }
410
411 case CDROMRESUME:{
412 xtrace(IOCTL, "ioctl() RESUME\n");
413 return mcdx_playtrk(stuffp, NULL);
414 }
415
416 case CDROMREADTOCENTRY:{
417 struct cdrom_tocentry *entry =
418 (struct cdrom_tocentry *) arg;
419 struct s_subqcode *tp = NULL;
420 xtrace(IOCTL, "ioctl() READTOCENTRY\n");
421
422 if (-1 == mcdx_readtoc(stuffp))
423 return -1;
424 if (entry->cdte_track == CDROM_LEADOUT)
425 tp = &stuffp->toc[stuffp->di.n_last -
426 stuffp->di.n_first + 1];
427 else if (entry->cdte_track > stuffp->di.n_last
428 || entry->cdte_track < stuffp->di.n_first)
429 return -EINVAL;
430 else
431 tp = &stuffp->toc[entry->cdte_track -
432 stuffp->di.n_first];
433
434 if (NULL == tp)
435 return -EIO;
436 entry->cdte_adr = tp->control;
437 entry->cdte_ctrl = tp->control >> 4;
438 /* Always return stuff in MSF, and let the Uniform cdrom driver
439 worry about what the user actually wants */
440 entry->cdte_addr.msf.minute =
441 bcd2uint(tp->dt.minute);
442 entry->cdte_addr.msf.second =
443 bcd2uint(tp->dt.second);
444 entry->cdte_addr.msf.frame =
445 bcd2uint(tp->dt.frame);
446 return 0;
447 }
448
449 case CDROMSUBCHNL:{
450 struct cdrom_subchnl *sub =
451 (struct cdrom_subchnl *) arg;
452 struct s_subqcode q;
453
454 xtrace(IOCTL, "ioctl() SUBCHNL\n");
455
456 if (-1 == mcdx_requestsubqcode(stuffp, &q, 2))
457 return -EIO;
458
459 xtrace(SUBCHNL, "audiostatus: %x\n",
460 stuffp->audiostatus);
461 sub->cdsc_audiostatus = stuffp->audiostatus;
462 sub->cdsc_adr = q.control;
463 sub->cdsc_ctrl = q.control >> 4;
464 sub->cdsc_trk = bcd2uint(q.tno);
465 sub->cdsc_ind = bcd2uint(q.index);
466
467 xtrace(SUBCHNL, "trk %d, ind %d\n",
468 sub->cdsc_trk, sub->cdsc_ind);
469 /* Always return stuff in MSF, and let the Uniform cdrom driver
470 worry about what the user actually wants */
471 sub->cdsc_absaddr.msf.minute =
472 bcd2uint(q.dt.minute);
473 sub->cdsc_absaddr.msf.second =
474 bcd2uint(q.dt.second);
475 sub->cdsc_absaddr.msf.frame = bcd2uint(q.dt.frame);
476 sub->cdsc_reladdr.msf.minute =
477 bcd2uint(q.tt.minute);
478 sub->cdsc_reladdr.msf.second =
479 bcd2uint(q.tt.second);
480 sub->cdsc_reladdr.msf.frame = bcd2uint(q.tt.frame);
481 xtrace(SUBCHNL,
482 "msf: abs %02d:%02d:%02d, rel %02d:%02d:%02d\n",
483 sub->cdsc_absaddr.msf.minute,
484 sub->cdsc_absaddr.msf.second,
485 sub->cdsc_absaddr.msf.frame,
486 sub->cdsc_reladdr.msf.minute,
487 sub->cdsc_reladdr.msf.second,
488 sub->cdsc_reladdr.msf.frame);
489
490 return 0;
491 }
492
493 case CDROMREADTOCHDR:{
494 struct cdrom_tochdr *toc =
495 (struct cdrom_tochdr *) arg;
496
497 xtrace(IOCTL, "ioctl() READTOCHDR\n");
498 toc->cdth_trk0 = stuffp->di.n_first;
499 toc->cdth_trk1 = stuffp->di.n_last;
500 xtrace(TOCHDR,
501 "ioctl() track0 = %d, track1 = %d\n",
502 stuffp->di.n_first, stuffp->di.n_last);
503 return 0;
504 }
505
506 case CDROMPAUSE:{
507 xtrace(IOCTL, "ioctl() PAUSE\n");
508 if (stuffp->audiostatus != CDROM_AUDIO_PLAY)
509 return -EINVAL;
510 if (-1 == mcdx_stop(stuffp, 1))
511 return -EIO;
512 stuffp->audiostatus = CDROM_AUDIO_PAUSED;
513 if (-1 ==
514 mcdx_requestsubqcode(stuffp, &stuffp->start,
515 1))
516 return -EIO;
517 return 0;
518 }
519
520 case CDROMMULTISESSION:{
521 struct cdrom_multisession *ms =
522 (struct cdrom_multisession *) arg;
523 xtrace(IOCTL, "ioctl() MULTISESSION\n");
524 /* Always return stuff in LBA, and let the Uniform cdrom driver
525 worry about what the user actually wants */
526 ms->addr.lba = msf2log(&stuffp->multi.msf_last);
527 ms->xa_flag = !!stuffp->multi.multi;
528 xtrace(MS,
529 "ioctl() (%d, 0x%08x [%02x:%02x.%02x])\n",
530 ms->xa_flag, ms->addr.lba,
531 stuffp->multi.msf_last.minute,
532 stuffp->multi.msf_last.second,
533 stuffp->multi.msf_last.frame);
534
535 return 0;
536 }
537
538 case CDROMEJECT:{
539 xtrace(IOCTL, "ioctl() EJECT\n");
540 if (stuffp->users > 1)
541 return -EBUSY;
542 return (mcdx_tray_move(cdi, 1));
543 }
544
545 case CDROMCLOSETRAY:{
546 xtrace(IOCTL, "ioctl() CDROMCLOSETRAY\n");
547 return (mcdx_tray_move(cdi, 0));
548 }
549
550 case CDROMVOLCTRL:{
551 struct cdrom_volctrl *volctrl =
552 (struct cdrom_volctrl *) arg;
553 xtrace(IOCTL, "ioctl() VOLCTRL\n");
554
555#if 0 /* not tested! */
556 /* adjust for the weirdness of workman (md) */
557 /* can't test it (hs) */
558 volctrl.channel2 = volctrl.channel1;
559 volctrl.channel1 = volctrl.channel3 = 0x00;
560#endif
561 return mcdx_setattentuator(stuffp, volctrl, 2);
562 }
563
564 default:
565 return -EINVAL;
566 }
567}
568
569static void do_mcdx_request(request_queue_t * q)
570{
571 struct s_drive_stuff *stuffp;
572 struct request *req;
573
574 again:
575
576 req = elv_next_request(q);
577 if (!req)
578 return;
579
580 stuffp = req->rq_disk->private_data;
581
582 if (!stuffp->present) {
583 xwarn("do_request(): bad device: %s\n",req->rq_disk->disk_name);
584 xtrace(REQUEST, "end_request(0): bad device\n");
585 end_request(req, 0);
586 return;
587 }
588
589 if (stuffp->audio) {
590 xwarn("do_request() attempt to read from audio cd\n");
591 xtrace(REQUEST, "end_request(0): read from audio\n");
592 end_request(req, 0);
593 return;
594 }
595
596 xtrace(REQUEST, "do_request() (%lu + %lu)\n",
597 req->sector, req->nr_sectors);
598
599 if (req->cmd != READ) {
600 xwarn("do_request(): non-read command to cd!!\n");
601 xtrace(REQUEST, "end_request(0): write\n");
602 end_request(req, 0);
603 return;
604 }
605 else {
606 stuffp->status = 0;
607 while (req->nr_sectors) {
608 int i;
609
610 i = mcdx_transfer(stuffp,
611 req->buffer,
612 req->sector,
613 req->nr_sectors);
614
615 if (i == -1) {
616 end_request(req, 0);
617 goto again;
618 }
619 req->sector += i;
620 req->nr_sectors -= i;
621 req->buffer += (i * 512);
622 }
623 end_request(req, 1);
624 goto again;
625
626 xtrace(REQUEST, "end_request(1)\n");
627 end_request(req, 1);
628 }
629
630 goto again;
631}
632
633static int mcdx_open(struct cdrom_device_info *cdi, int purpose)
634{
635 struct s_drive_stuff *stuffp;
636 xtrace(OPENCLOSE, "open()\n");
637 stuffp = cdi->handle;
638 if (!stuffp->present)
639 return -ENXIO;
640
641 /* Make the modules looking used ... (thanx bjorn).
642 * But we shouldn't forget to decrement the module counter
643 * on error return */
644
645 /* this is only done to test if the drive talks with us */
646 if (-1 == mcdx_getstatus(stuffp, 1))
647 return -EIO;
648
649 if (stuffp->xxx) {
650
651 xtrace(OPENCLOSE, "open() media changed\n");
652 stuffp->audiostatus = CDROM_AUDIO_INVALID;
653 stuffp->readcmd = 0;
654 xtrace(OPENCLOSE, "open() Request multisession info\n");
655 if (-1 ==
656 mcdx_requestmultidiskinfo(stuffp, &stuffp->multi, 6))
657 xinfo("No multidiskinfo\n");
658 } else {
659 /* multisession ? */
660 if (!stuffp->multi.multi)
661 stuffp->multi.msf_last.second = 2;
662
663 xtrace(OPENCLOSE, "open() MS: %d, last @ %02x:%02x.%02x\n",
664 stuffp->multi.multi,
665 stuffp->multi.msf_last.minute,
666 stuffp->multi.msf_last.second,
667 stuffp->multi.msf_last.frame);
668
669 {;
670 } /* got multisession information */
671 /* request the disks table of contents (aka diskinfo) */
672 if (-1 == mcdx_requesttocdata(stuffp, &stuffp->di, 1)) {
673
674 stuffp->lastsector = -1;
675
676 } else {
677
678 stuffp->lastsector = (CD_FRAMESIZE / 512)
679 * msf2log(&stuffp->di.msf_leadout) - 1;
680
681 xtrace(OPENCLOSE,
682 "open() start %d (%02x:%02x.%02x) %d\n",
683 stuffp->di.n_first,
684 stuffp->di.msf_first.minute,
685 stuffp->di.msf_first.second,
686 stuffp->di.msf_first.frame,
687 msf2log(&stuffp->di.msf_first));
688 xtrace(OPENCLOSE,
689 "open() last %d (%02x:%02x.%02x) %d\n",
690 stuffp->di.n_last,
691 stuffp->di.msf_leadout.minute,
692 stuffp->di.msf_leadout.second,
693 stuffp->di.msf_leadout.frame,
694 msf2log(&stuffp->di.msf_leadout));
695 }
696
697 if (stuffp->toc) {
698 xtrace(MALLOC, "open() free old toc @ %p\n",
699 stuffp->toc);
700 kfree(stuffp->toc);
701
702 stuffp->toc = NULL;
703 }
704
705 xtrace(OPENCLOSE, "open() init irq generation\n");
706 if (-1 == mcdx_config(stuffp, 1))
707 return -EIO;
708#ifdef FALLBACK
709 /* Set the read speed */
710 xwarn("AAA %x AAA\n", stuffp->readcmd);
711 if (stuffp->readerrs)
712 stuffp->readcmd = READ1X;
713 else
714 stuffp->readcmd =
715 stuffp->present | SINGLE ? READ1X : READ2X;
716 xwarn("XXX %x XXX\n", stuffp->readcmd);
717#else
718 stuffp->readcmd =
719 stuffp->present | SINGLE ? READ1X : READ2X;
720#endif
721
722 /* try to get the first sector, iff any ... */
723 if (stuffp->lastsector >= 0) {
724 char buf[512];
725 int ans;
726 int tries;
727
728 stuffp->xa = 0;
729 stuffp->audio = 0;
730
731 for (tries = 6; tries; tries--) {
732
733 stuffp->introk = 1;
734
735 xtrace(OPENCLOSE, "open() try as %s\n",
736 stuffp->xa ? "XA" : "normal");
737 /* set data mode */
738 if (-1 == (ans = mcdx_setdatamode(stuffp,
739 stuffp->
740 xa ?
741 MODE2 :
742 MODE1,
743 1))) {
744 /* return -EIO; */
745 stuffp->xa = 0;
746 break;
747 }
748
749 if ((stuffp->audio = e_audio(ans)))
750 break;
751
752 while (0 ==
753 (ans =
754 mcdx_transfer(stuffp, buf, 0, 1)));
755
756 if (ans == 1)
757 break;
758 stuffp->xa = !stuffp->xa;
759 }
760 }
761 /* xa disks will be read in raw mode, others not */
762 if (-1 == mcdx_setdrivemode(stuffp,
763 stuffp->xa ? RAW : COOKED,
764 1))
765 return -EIO;
766 if (stuffp->audio) {
767 xinfo("open() audio disk found\n");
768 } else if (stuffp->lastsector >= 0) {
769 xinfo("open() %s%s disk found\n",
770 stuffp->xa ? "XA / " : "",
771 stuffp->multi.
772 multi ? "Multi Session" : "Single Session");
773 }
774 }
775 stuffp->xxx = 0;
776 stuffp->users++;
777 return 0;
778}
779
780static void mcdx_close(struct cdrom_device_info *cdi)
781{
782 struct s_drive_stuff *stuffp;
783
784 xtrace(OPENCLOSE, "close()\n");
785
786 stuffp = cdi->handle;
787
788 --stuffp->users;
789}
790
791static int mcdx_media_changed(struct cdrom_device_info *cdi, int disc_nr)
792/* Return: 1 if media changed since last call to this function
793 0 otherwise */
794{
795 struct s_drive_stuff *stuffp;
796
797 xinfo("mcdx_media_changed called for device %s\n", cdi->name);
798
799 stuffp = cdi->handle;
800 mcdx_getstatus(stuffp, 1);
801
802 if (stuffp->yyy == 0)
803 return 0;
804
805 stuffp->yyy = 0;
806 return 1;
807}
808
809#ifndef MODULE
810static int __init mcdx_setup(char *str)
811{
812 int pi[4];
813 (void) get_options(str, ARRAY_SIZE(pi), pi);
814
815 if (pi[0] > 0)
816 mcdx_drive_map[0][0] = pi[1];
817 if (pi[0] > 1)
818 mcdx_drive_map[0][1] = pi[2];
819 return 1;
820}
821
822__setup("mcdx=", mcdx_setup);
823
824#endif
825
826/* DIRTY PART ******************************************************/
827
828static void mcdx_delay(struct s_drive_stuff *stuff, long jifs)
829/* This routine is used for sleeping.
830 * A jifs value <0 means NO sleeping,
831 * =0 means minimal sleeping (let the kernel
832 * run for other processes)
833 * >0 means at least sleep for that amount.
834 * May be we could use a simple count loop w/ jumps to itself, but
835 * I wanna make this independent of cpu speed. [1 jiffy is 1/HZ] sec */
836{
837 if (jifs < 0)
838 return;
839
840 xtrace(SLEEP, "*** delay: sleepq\n");
841 interruptible_sleep_on_timeout(&stuff->sleepq, jifs);
842 xtrace(SLEEP, "delay awoken\n");
843 if (signal_pending(current)) {
844 xtrace(SLEEP, "got signal\n");
845 }
846}
847
848static irqreturn_t mcdx_intr(int irq, void *dev_id)
849{
850 struct s_drive_stuff *stuffp = dev_id;
851 unsigned char b;
852
853#ifdef AK2
854 if (!stuffp->busy && stuffp->pending)
855 stuffp->int_err = 1;
856
857#endif /* AK2 */
858 /* get the interrupt status */
859 b = inb(stuffp->rreg_status);
860 stuffp->introk = ~b & MCDX_RBIT_DTEN;
861
862 /* NOTE: We only should get interrupts if the data we
863 * requested are ready to transfer.
864 * But the drive seems to generate ``asynchronous'' interrupts
865 * on several error conditions too. (Despite the err int enable
866 * setting during initialisation) */
867
868 /* if not ok, read the next byte as the drives status */
869 if (!stuffp->introk) {
870 xtrace(IRQ, "intr() irq %d hw status 0x%02x\n", irq, b);
871 if (~b & MCDX_RBIT_STEN) {
872 xinfo("intr() irq %d status 0x%02x\n",
873 irq, inb(stuffp->rreg_data));
874 } else {
875 xinfo("intr() irq %d ambiguous hw status\n", irq);
876 }
877 } else {
878 xtrace(IRQ, "irq() irq %d ok, status %02x\n", irq, b);
879 }
880
881 stuffp->busy = 0;
882 wake_up_interruptible(&stuffp->busyq);
883 return IRQ_HANDLED;
884}
885
886
887static int mcdx_talk(struct s_drive_stuff *stuffp,
888 const unsigned char *cmd, size_t cmdlen,
889 void *buffer, size_t size, unsigned int timeout, int tries)
890/* Send a command to the drive, wait for the result.
891 * returns -1 on timeout, drive status otherwise
892 * If buffer is not zero, the result (length size) is stored there.
893 * If buffer is zero the size should be the number of bytes to read
894 * from the drive. These bytes are discarded.
895 */
896{
897 int st;
898 char c;
899 int discard;
900
901 /* Somebody wants the data read? */
902 if ((discard = (buffer == NULL)))
903 buffer = &c;
904
905 while (stuffp->lock) {
906 xtrace(SLEEP, "*** talk: lockq\n");
907 interruptible_sleep_on(&stuffp->lockq);
908 xtrace(SLEEP, "talk: awoken\n");
909 }
910
911 stuffp->lock = 1;
912
913 /* An operation other then reading data destroys the
914 * data already requested and remembered in stuffp->request, ... */
915 stuffp->valid = 0;
916
917#if MCDX_DEBUG & TALK
918 {
919 unsigned char i;
920 xtrace(TALK,
921 "talk() %d / %d tries, res.size %d, command 0x%02x",
922 tries, timeout, size, (unsigned char) cmd[0]);
923 for (i = 1; i < cmdlen; i++)
924 xtrace(TALK, " 0x%02x", cmd[i]);
925 xtrace(TALK, "\n");
926 }
927#endif
928
929 /* give up if all tries are done (bad) or if the status
930 * st != -1 (good) */
931 for (st = -1; st == -1 && tries; tries--) {
932
933 char *bp = (char *) buffer;
934 size_t sz = size;
935
936 outsb(stuffp->wreg_data, cmd, cmdlen);
937 xtrace(TALK, "talk() command sent\n");
938
939 /* get the status byte */
940 if (-1 == mcdx_getval(stuffp, timeout, 0, bp)) {
941 xinfo("talk() %02x timed out (status), %d tr%s left\n",
942 cmd[0], tries - 1, tries == 2 ? "y" : "ies");
943 continue;
944 }
945 st = *bp;
946 sz--;
947 if (!discard)
948 bp++;
949
950 xtrace(TALK, "talk() got status 0x%02x\n", st);
951
952 /* command error? */
953 if (e_cmderr(st)) {
954 xwarn("command error cmd = %02x %s \n",
955 cmd[0], cmdlen > 1 ? "..." : "");
956 st = -1;
957 continue;
958 }
959
960 /* audio status? */
961 if (stuffp->audiostatus == CDROM_AUDIO_INVALID)
962 stuffp->audiostatus =
963 e_audiobusy(st) ? CDROM_AUDIO_PLAY :
964 CDROM_AUDIO_NO_STATUS;
965 else if (stuffp->audiostatus == CDROM_AUDIO_PLAY
966 && e_audiobusy(st) == 0)
967 stuffp->audiostatus = CDROM_AUDIO_COMPLETED;
968
969 /* media change? */
970 if (e_changed(st)) {
971 xinfo("talk() media changed\n");
972 stuffp->xxx = stuffp->yyy = 1;
973 }
974
975 /* now actually get the data */
976 while (sz--) {
977 if (-1 == mcdx_getval(stuffp, timeout, 0, bp)) {
978 xinfo("talk() %02x timed out (data), %d tr%s left\n",
979 cmd[0], tries - 1,
980 tries == 2 ? "y" : "ies");
981 st = -1;
982 break;
983 }
984 if (!discard)
985 bp++;
986 xtrace(TALK, "talk() got 0x%02x\n", *(bp - 1));
987 }
988 }
989
990#if !MCDX_QUIET
991 if (!tries && st == -1)
992 xinfo("talk() giving up\n");
993#endif
994
995 stuffp->lock = 0;
996 wake_up_interruptible(&stuffp->lockq);
997
998 xtrace(TALK, "talk() done with 0x%02x\n", st);
999 return st;
1000}
1001
1002/* MODULE STUFF ***********************************************************/
1003
1004static int __init __mcdx_init(void)
1005{
1006 int i;
1007 int drives = 0;
1008
1009 mcdx_init();
1010 for (i = 0; i < MCDX_NDRIVES; i++) {
1011 if (mcdx_stuffp[i]) {
1012 xtrace(INIT, "init_module() drive %d stuff @ %p\n",
1013 i, mcdx_stuffp[i]);
1014 drives++;
1015 }
1016 }
1017
1018 if (!drives)
1019 return -EIO;
1020
1021 return 0;
1022}
1023
1024static void __exit mcdx_exit(void)
1025{
1026 int i;
1027
1028 xinfo("cleanup_module called\n");
1029
1030 for (i = 0; i < MCDX_NDRIVES; i++) {
1031 struct s_drive_stuff *stuffp = mcdx_stuffp[i];
1032 if (!stuffp)
1033 continue;
1034 del_gendisk(stuffp->disk);
1035 if (unregister_cdrom(&stuffp->info)) {
1036 printk(KERN_WARNING "Can't unregister cdrom mcdx\n");
1037 continue;
1038 }
1039 put_disk(stuffp->disk);
1040 release_region(stuffp->wreg_data, MCDX_IO_SIZE);
1041 free_irq(stuffp->irq, NULL);
1042 if (stuffp->toc) {
1043 xtrace(MALLOC, "cleanup_module() free toc @ %p\n",
1044 stuffp->toc);
1045 kfree(stuffp->toc);
1046 }
1047 xtrace(MALLOC, "cleanup_module() free stuffp @ %p\n",
1048 stuffp);
1049 mcdx_stuffp[i] = NULL;
1050 kfree(stuffp);
1051 }
1052
1053 if (unregister_blkdev(MAJOR_NR, "mcdx") != 0) {
1054 xwarn("cleanup() unregister_blkdev() failed\n");
1055 }
1056#if !MCDX_QUIET
1057 else
1058 xinfo("cleanup() succeeded\n");
1059#endif
1060 blk_cleanup_queue(mcdx_queue);
1061}
1062
1063#ifdef MODULE
1064module_init(__mcdx_init);
1065#endif
1066module_exit(mcdx_exit);
1067
1068
1069/* Support functions ************************************************/
1070
1071static int __init mcdx_init_drive(int drive)
1072{
1073 struct s_version version;
1074 struct gendisk *disk;
1075 struct s_drive_stuff *stuffp;
1076 int size = sizeof(*stuffp);
1077 char msg[80];
1078
1079 xtrace(INIT, "init() try drive %d\n", drive);
1080
1081 xtrace(INIT, "kmalloc space for stuffpt's\n");
1082 xtrace(MALLOC, "init() malloc %d bytes\n", size);
1083 if (!(stuffp = kzalloc(size, GFP_KERNEL))) {
1084 xwarn("init() malloc failed\n");
1085 return 1;
1086 }
1087
1088 disk = alloc_disk(1);
1089 if (!disk) {
1090 xwarn("init() malloc failed\n");
1091 kfree(stuffp);
1092 return 1;
1093 }
1094
1095 xtrace(INIT, "init() got %d bytes for drive stuff @ %p\n",
1096 sizeof(*stuffp), stuffp);
1097
1098 /* set default values */
1099 stuffp->present = 0; /* this should be 0 already */
1100 stuffp->toc = NULL; /* this should be NULL already */
1101
1102 /* setup our irq and i/o addresses */
1103 stuffp->irq = irq(mcdx_drive_map[drive]);
1104 stuffp->wreg_data = stuffp->rreg_data = port(mcdx_drive_map[drive]);
1105 stuffp->wreg_reset = stuffp->rreg_status = stuffp->wreg_data + 1;
1106 stuffp->wreg_hcon = stuffp->wreg_reset + 1;
1107 stuffp->wreg_chn = stuffp->wreg_hcon + 1;
1108
1109 init_waitqueue_head(&stuffp->busyq);
1110 init_waitqueue_head(&stuffp->lockq);
1111 init_waitqueue_head(&stuffp->sleepq);
1112
1113 /* check if i/o addresses are available */
1114 if (!request_region(stuffp->wreg_data, MCDX_IO_SIZE, "mcdx")) {
1115 xwarn("0x%03x,%d: Init failed. "
1116 "I/O ports (0x%03x..0x%03x) already in use.\n",
1117 stuffp->wreg_data, stuffp->irq,
1118 stuffp->wreg_data,
1119 stuffp->wreg_data + MCDX_IO_SIZE - 1);
1120 xtrace(MALLOC, "init() free stuffp @ %p\n", stuffp);
1121 kfree(stuffp);
1122 put_disk(disk);
1123 xtrace(INIT, "init() continue at next drive\n");
1124 return 0; /* next drive */
1125 }
1126
1127 xtrace(INIT, "init() i/o port is available at 0x%03x\n"
1128 stuffp->wreg_data);
1129 xtrace(INIT, "init() hardware reset\n");
1130 mcdx_reset(stuffp, HARD, 1);
1131
1132 xtrace(INIT, "init() get version\n");
1133 if (-1 == mcdx_requestversion(stuffp, &version, 4)) {
1134 /* failed, next drive */
1135 release_region(stuffp->wreg_data, MCDX_IO_SIZE);
1136 xwarn("%s=0x%03x,%d: Init failed. Can't get version.\n",
1137 MCDX, stuffp->wreg_data, stuffp->irq);
1138 xtrace(MALLOC, "init() free stuffp @ %p\n", stuffp);
1139 kfree(stuffp);
1140 put_disk(disk);
1141 xtrace(INIT, "init() continue at next drive\n");
1142 return 0;
1143 }
1144
1145 switch (version.code) {
1146 case 'D':
1147 stuffp->readcmd = READ2X;
1148 stuffp->present = DOUBLE | DOOR | MULTI;
1149 break;
1150 case 'F':
1151 stuffp->readcmd = READ1X;
1152 stuffp->present = SINGLE | DOOR | MULTI;
1153 break;
1154 case 'M':
1155 stuffp->readcmd = READ1X;
1156 stuffp->present = SINGLE;
1157 break;
1158 default:
1159 stuffp->present = 0;
1160 break;
1161 }
1162
1163 stuffp->playcmd = READ1X;
1164
1165 if (!stuffp->present) {
1166 release_region(stuffp->wreg_data, MCDX_IO_SIZE);
1167 xwarn("%s=0x%03x,%d: Init failed. No Mitsumi CD-ROM?.\n",
1168 MCDX, stuffp->wreg_data, stuffp->irq);
1169 kfree(stuffp);
1170 put_disk(disk);
1171 return 0; /* next drive */
1172 }
1173
1174 xtrace(INIT, "init() register blkdev\n");
1175 if (register_blkdev(MAJOR_NR, "mcdx")) {
1176 release_region(stuffp->wreg_data, MCDX_IO_SIZE);
1177 kfree(stuffp);
1178 put_disk(disk);
1179 return 1;
1180 }
1181
1182 mcdx_queue = blk_init_queue(do_mcdx_request, &mcdx_lock);
1183 if (!mcdx_queue) {
1184 unregister_blkdev(MAJOR_NR, "mcdx");
1185 release_region(stuffp->wreg_data, MCDX_IO_SIZE);
1186 kfree(stuffp);
1187 put_disk(disk);
1188 return 1;
1189 }
1190
1191 xtrace(INIT, "init() subscribe irq and i/o\n");
1192 if (request_irq(stuffp->irq, mcdx_intr, IRQF_DISABLED, "mcdx", stuffp)) {
1193 release_region(stuffp->wreg_data, MCDX_IO_SIZE);
1194 xwarn("%s=0x%03x,%d: Init failed. Can't get irq (%d).\n",
1195 MCDX, stuffp->wreg_data, stuffp->irq, stuffp->irq);
1196 stuffp->irq = 0;
1197 blk_cleanup_queue(mcdx_queue);
1198 kfree(stuffp);
1199 put_disk(disk);
1200 return 0;
1201 }
1202
1203 xtrace(INIT, "init() get garbage\n");
1204 {
1205 int i;
1206 mcdx_delay(stuffp, HZ / 2);
1207 for (i = 100; i; i--)
1208 (void) inb(stuffp->rreg_status);
1209 }
1210
1211
1212#ifdef WE_KNOW_WHY
1213 /* irq 11 -> channel register */
1214 outb(0x50, stuffp->wreg_chn);
1215#endif
1216
1217 xtrace(INIT, "init() set non dma but irq mode\n");
1218 mcdx_config(stuffp, 1);
1219
1220 stuffp->info.ops = &mcdx_dops;
1221 stuffp->info.speed = 2;
1222 stuffp->info.capacity = 1;
1223 stuffp->info.handle = stuffp;
1224 sprintf(stuffp->info.name, "mcdx%d", drive);
1225 disk->major = MAJOR_NR;
1226 disk->first_minor = drive;
1227 strcpy(disk->disk_name, stuffp->info.name);
1228 disk->fops = &mcdx_bdops;
1229 disk->flags = GENHD_FL_CD;
1230 stuffp->disk = disk;
1231
1232 sprintf(msg, " mcdx: Mitsumi CD-ROM installed at 0x%03x, irq %d."
1233 " (Firmware version %c %x)\n",
1234 stuffp->wreg_data, stuffp->irq, version.code, version.ver);
1235 mcdx_stuffp[drive] = stuffp;
1236 xtrace(INIT, "init() mcdx_stuffp[%d] = %p\n", drive, stuffp);
1237 if (register_cdrom(&stuffp->info) != 0) {
1238 printk("Cannot register Mitsumi CD-ROM!\n");
1239 free_irq(stuffp->irq, NULL);
1240 release_region(stuffp->wreg_data, MCDX_IO_SIZE);
1241 kfree(stuffp);
1242 put_disk(disk);
1243 if (unregister_blkdev(MAJOR_NR, "mcdx") != 0)
1244 xwarn("cleanup() unregister_blkdev() failed\n");
1245 blk_cleanup_queue(mcdx_queue);
1246 return 2;
1247 }
1248 disk->private_data = stuffp;
1249 disk->queue = mcdx_queue;
1250 add_disk(disk);
1251 printk(msg);
1252 return 0;
1253}
1254
1255static int __init mcdx_init(void)
1256{
1257 int drive;
1258 xwarn("Version 2.14(hs) \n");
1259
1260 xwarn("$Id: mcdx.c,v 1.21 1997/01/26 07:12:59 davem Exp $\n");
1261
1262 /* zero the pointer array */
1263 for (drive = 0; drive < MCDX_NDRIVES; drive++)
1264 mcdx_stuffp[drive] = NULL;
1265
1266 /* do the initialisation */
1267 for (drive = 0; drive < MCDX_NDRIVES; drive++) {
1268 switch (mcdx_init_drive(drive)) {
1269 case 2:
1270 return -EIO;
1271 case 1:
1272 break;
1273 }
1274 }
1275 return 0;
1276}
1277
1278static int mcdx_transfer(struct s_drive_stuff *stuffp,
1279 char *p, int sector, int nr_sectors)
1280/* This seems to do the actually transfer. But it does more. It
1281 keeps track of errors occurred and will (if possible) fall back
1282 to single speed on error.
1283 Return: -1 on timeout or other error
1284 else status byte (as in stuff->st) */
1285{
1286 int ans;
1287
1288 ans = mcdx_xfer(stuffp, p, sector, nr_sectors);
1289 return ans;
1290#ifdef FALLBACK
1291 if (-1 == ans)
1292 stuffp->readerrs++;
1293 else
1294 return ans;
1295
1296 if (stuffp->readerrs && stuffp->readcmd == READ1X) {
1297 xwarn("XXX Already reading 1x -- no chance\n");
1298 return -1;
1299 }
1300
1301 xwarn("XXX Fallback to 1x\n");
1302
1303 stuffp->readcmd = READ1X;
1304 return mcdx_transfer(stuffp, p, sector, nr_sectors);
1305#endif
1306
1307}
1308
1309
1310static int mcdx_xfer(struct s_drive_stuff *stuffp,
1311 char *p, int sector, int nr_sectors)
1312/* This does actually the transfer from the drive.
1313 Return: -1 on timeout or other error
1314 else status byte (as in stuff->st) */
1315{
1316 int border;
1317 int done = 0;
1318 long timeout;
1319
1320 if (stuffp->audio) {
1321 xwarn("Attempt to read from audio CD.\n");
1322 return -1;
1323 }
1324
1325 if (!stuffp->readcmd) {
1326 xinfo("Can't transfer from missing disk.\n");
1327 return -1;
1328 }
1329
1330 while (stuffp->lock) {
1331 interruptible_sleep_on(&stuffp->lockq);
1332 }
1333
1334 if (stuffp->valid && (sector >= stuffp->pending)
1335 && (sector < stuffp->low_border)) {
1336
1337 /* All (or at least a part of the sectors requested) seems
1338 * to be already requested, so we don't need to bother the
1339 * drive with new requests ...
1340 * Wait for the drive become idle, but first
1341 * check for possible occurred errors --- the drive
1342 * seems to report them asynchronously */
1343
1344
1345 border = stuffp->high_border < (border =
1346 sector + nr_sectors)
1347 ? stuffp->high_border : border;
1348
1349 stuffp->lock = current->pid;
1350
1351 do {
1352
1353 while (stuffp->busy) {
1354
1355 timeout =
1356 interruptible_sleep_on_timeout
1357 (&stuffp->busyq, 5 * HZ);
1358
1359 if (!stuffp->introk) {
1360 xtrace(XFER,
1361 "error via interrupt\n");
1362 } else if (!timeout) {
1363 xtrace(XFER, "timeout\n");
1364 } else if (signal_pending(current)) {
1365 xtrace(XFER, "signal\n");
1366 } else
1367 continue;
1368
1369 stuffp->lock = 0;
1370 stuffp->busy = 0;
1371 stuffp->valid = 0;
1372
1373 wake_up_interruptible(&stuffp->lockq);
1374 xtrace(XFER, "transfer() done (-1)\n");
1375 return -1;
1376 }
1377
1378 /* check if we need to set the busy flag (as we
1379 * expect an interrupt */
1380 stuffp->busy = (3 == (stuffp->pending & 3));
1381
1382 /* Test if it's the first sector of a block,
1383 * there we have to skip some bytes as we read raw data */
1384 if (stuffp->xa && (0 == (stuffp->pending & 3))) {
1385 const int HEAD =
1386 CD_FRAMESIZE_RAW - CD_XA_TAIL -
1387 CD_FRAMESIZE;
1388 insb(stuffp->rreg_data, p, HEAD);
1389 }
1390
1391 /* now actually read the data */
1392 insb(stuffp->rreg_data, p, 512);
1393
1394 /* test if it's the last sector of a block,
1395 * if so, we have to handle XA special */
1396 if ((3 == (stuffp->pending & 3)) && stuffp->xa) {
1397 char dummy[CD_XA_TAIL];
1398 insb(stuffp->rreg_data, &dummy[0], CD_XA_TAIL);
1399 }
1400
1401 if (stuffp->pending == sector) {
1402 p += 512;
1403 done++;
1404 sector++;
1405 }
1406 } while (++(stuffp->pending) < border);
1407
1408 stuffp->lock = 0;
1409 wake_up_interruptible(&stuffp->lockq);
1410
1411 } else {
1412
1413 /* The requested sector(s) is/are out of the
1414 * already requested range, so we have to bother the drive
1415 * with a new request. */
1416
1417 static unsigned char cmd[] = {
1418 0,
1419 0, 0, 0,
1420 0, 0, 0
1421 };
1422
1423 cmd[0] = stuffp->readcmd;
1424
1425 /* The numbers held in ->pending, ..., should be valid */
1426 stuffp->valid = 1;
1427 stuffp->pending = sector & ~3;
1428
1429 /* do some sanity checks */
1430 if (stuffp->pending > stuffp->lastsector) {
1431 xwarn
1432 ("transfer() sector %d from nirvana requested.\n",
1433 stuffp->pending);
1434 stuffp->status = MCDX_ST_EOM;
1435 stuffp->valid = 0;
1436 xtrace(XFER, "transfer() done (-1)\n");
1437 return -1;
1438 }
1439
1440 if ((stuffp->low_border = stuffp->pending + DIRECT_SIZE)
1441 > stuffp->lastsector + 1) {
1442 xtrace(XFER, "cut low_border\n");
1443 stuffp->low_border = stuffp->lastsector + 1;
1444 }
1445 if ((stuffp->high_border = stuffp->pending + REQUEST_SIZE)
1446 > stuffp->lastsector + 1) {
1447 xtrace(XFER, "cut high_border\n");
1448 stuffp->high_border = stuffp->lastsector + 1;
1449 }
1450
1451 { /* Convert the sector to be requested to MSF format */
1452 struct cdrom_msf0 pending;
1453 log2msf(stuffp->pending / 4, &pending);
1454 cmd[1] = pending.minute;
1455 cmd[2] = pending.second;
1456 cmd[3] = pending.frame;
1457 }
1458
1459 cmd[6] =
1460 (unsigned
1461 char) ((stuffp->high_border - stuffp->pending) / 4);
1462 xtrace(XFER, "[%2d]\n", cmd[6]);
1463
1464 stuffp->busy = 1;
1465 /* Now really issue the request command */
1466 outsb(stuffp->wreg_data, cmd, sizeof cmd);
1467
1468 }
1469#ifdef AK2
1470 if (stuffp->int_err) {
1471 stuffp->valid = 0;
1472 stuffp->int_err = 0;
1473 return -1;
1474 }
1475#endif /* AK2 */
1476
1477 stuffp->low_border = (stuffp->low_border +=
1478 done) <
1479 stuffp->high_border ? stuffp->low_border : stuffp->high_border;
1480
1481 return done;
1482}
1483
1484
1485/* Access to elements of the mcdx_drive_map members */
1486
1487static unsigned port(int *ip)
1488{
1489 return ip[0];
1490}
1491static int irq(int *ip)
1492{
1493 return ip[1];
1494}
1495
1496/* Misc number converters */
1497
1498static unsigned int bcd2uint(unsigned char c)
1499{
1500 return (c >> 4) * 10 + (c & 0x0f);
1501}
1502
1503static unsigned int uint2bcd(unsigned int ival)
1504{
1505 return ((ival / 10) << 4) | (ival % 10);
1506}
1507
1508static void log2msf(unsigned int l, struct cdrom_msf0 *pmsf)
1509{
1510 l += CD_MSF_OFFSET;
1511 pmsf->minute = uint2bcd(l / 4500), l %= 4500;
1512 pmsf->second = uint2bcd(l / 75);
1513 pmsf->frame = uint2bcd(l % 75);
1514}
1515
1516static unsigned int msf2log(const struct cdrom_msf0 *pmsf)
1517{
1518 return bcd2uint(pmsf->frame)
1519 + bcd2uint(pmsf->second) * 75
1520 + bcd2uint(pmsf->minute) * 4500 - CD_MSF_OFFSET;
1521}
1522
1523int mcdx_readtoc(struct s_drive_stuff *stuffp)
1524/* Read the toc entries from the CD,
1525 * Return: -1 on failure, else 0 */
1526{
1527
1528 if (stuffp->toc) {
1529 xtrace(READTOC, "ioctl() toc already read\n");
1530 return 0;
1531 }
1532
1533 xtrace(READTOC, "ioctl() readtoc for %d tracks\n",
1534 stuffp->di.n_last - stuffp->di.n_first + 1);
1535
1536 if (-1 == mcdx_hold(stuffp, 1))
1537 return -1;
1538
1539 xtrace(READTOC, "ioctl() tocmode\n");
1540 if (-1 == mcdx_setdrivemode(stuffp, TOC, 1))
1541 return -EIO;
1542
1543 /* all seems to be ok so far ... malloc */
1544 {
1545 int size;
1546 size =
1547 sizeof(struct s_subqcode) * (stuffp->di.n_last -
1548 stuffp->di.n_first + 2);
1549
1550 xtrace(MALLOC, "ioctl() malloc %d bytes\n", size);
1551 stuffp->toc = kmalloc(size, GFP_KERNEL);
1552 if (!stuffp->toc) {
1553 xwarn("Cannot malloc %d bytes for toc\n", size);
1554 mcdx_setdrivemode(stuffp, DATA, 1);
1555 return -EIO;
1556 }
1557 }
1558
1559 /* now read actually the index */
1560 {
1561 int trk;
1562 int retries;
1563
1564 for (trk = 0;
1565 trk < (stuffp->di.n_last - stuffp->di.n_first + 1);
1566 trk++)
1567 stuffp->toc[trk].index = 0;
1568
1569 for (retries = 300; retries; retries--) { /* why 300? */
1570 struct s_subqcode q;
1571 unsigned int idx;
1572
1573 if (-1 == mcdx_requestsubqcode(stuffp, &q, 1)) {
1574 mcdx_setdrivemode(stuffp, DATA, 1);
1575 return -EIO;
1576 }
1577
1578 idx = bcd2uint(q.index);
1579
1580 if ((idx > 0)
1581 && (idx <= stuffp->di.n_last)
1582 && (q.tno == 0)
1583 && (stuffp->toc[idx - stuffp->di.n_first].
1584 index == 0)) {
1585 stuffp->toc[idx - stuffp->di.n_first] = q;
1586 xtrace(READTOC,
1587 "ioctl() toc idx %d (trk %d)\n",
1588 idx, trk);
1589 trk--;
1590 }
1591 if (trk == 0)
1592 break;
1593 }
1594 memset(&stuffp->
1595 toc[stuffp->di.n_last - stuffp->di.n_first + 1], 0,
1596 sizeof(stuffp->toc[0]));
1597 stuffp->toc[stuffp->di.n_last - stuffp->di.n_first +
1598 1].dt = stuffp->di.msf_leadout;
1599 }
1600
1601 /* unset toc mode */
1602 xtrace(READTOC, "ioctl() undo toc mode\n");
1603 if (-1 == mcdx_setdrivemode(stuffp, DATA, 2))
1604 return -EIO;
1605
1606#if MCDX_DEBUG && READTOC
1607 {
1608 int trk;
1609 for (trk = 0;
1610 trk < (stuffp->di.n_last - stuffp->di.n_first + 2);
1611 trk++)
1612 xtrace(READTOC, "ioctl() %d readtoc %02x %02x %02x"
1613 " %02x:%02x.%02x %02x:%02x.%02x\n",
1614 trk + stuffp->di.n_first,
1615 stuffp->toc[trk].control,
1616 stuffp->toc[trk].tno,
1617 stuffp->toc[trk].index,
1618 stuffp->toc[trk].tt.minute,
1619 stuffp->toc[trk].tt.second,
1620 stuffp->toc[trk].tt.frame,
1621 stuffp->toc[trk].dt.minute,
1622 stuffp->toc[trk].dt.second,
1623 stuffp->toc[trk].dt.frame);
1624 }
1625#endif
1626
1627 return 0;
1628}
1629
1630static int
1631mcdx_playmsf(struct s_drive_stuff *stuffp, const struct cdrom_msf *msf)
1632{
1633 unsigned char cmd[7] = {
1634 0, 0, 0, 0, 0, 0, 0
1635 };
1636
1637 if (!stuffp->readcmd) {
1638 xinfo("Can't play from missing disk.\n");
1639 return -1;
1640 }
1641
1642 cmd[0] = stuffp->playcmd;
1643
1644 cmd[1] = msf->cdmsf_min0;
1645 cmd[2] = msf->cdmsf_sec0;
1646 cmd[3] = msf->cdmsf_frame0;
1647 cmd[4] = msf->cdmsf_min1;
1648 cmd[5] = msf->cdmsf_sec1;
1649 cmd[6] = msf->cdmsf_frame1;
1650
1651 xtrace(PLAYMSF, "ioctl(): play %x "
1652 "%02x:%02x:%02x -- %02x:%02x:%02x\n",
1653 cmd[0], cmd[1], cmd[2], cmd[3], cmd[4], cmd[5], cmd[6]);
1654
1655 outsb(stuffp->wreg_data, cmd, sizeof cmd);
1656
1657 if (-1 == mcdx_getval(stuffp, 3 * HZ, 0, NULL)) {
1658 xwarn("playmsf() timeout\n");
1659 return -1;
1660 }
1661
1662 stuffp->audiostatus = CDROM_AUDIO_PLAY;
1663 return 0;
1664}
1665
1666static int
1667mcdx_playtrk(struct s_drive_stuff *stuffp, const struct cdrom_ti *ti)
1668{
1669 struct s_subqcode *p;
1670 struct cdrom_msf msf;
1671
1672 if (-1 == mcdx_readtoc(stuffp))
1673 return -1;
1674
1675 if (ti)
1676 p = &stuffp->toc[ti->cdti_trk0 - stuffp->di.n_first];
1677 else
1678 p = &stuffp->start;
1679
1680 msf.cdmsf_min0 = p->dt.minute;
1681 msf.cdmsf_sec0 = p->dt.second;
1682 msf.cdmsf_frame0 = p->dt.frame;
1683
1684 if (ti) {
1685 p = &stuffp->toc[ti->cdti_trk1 - stuffp->di.n_first + 1];
1686 stuffp->stop = *p;
1687 } else
1688 p = &stuffp->stop;
1689
1690 msf.cdmsf_min1 = p->dt.minute;
1691 msf.cdmsf_sec1 = p->dt.second;
1692 msf.cdmsf_frame1 = p->dt.frame;
1693
1694 return mcdx_playmsf(stuffp, &msf);
1695}
1696
1697
1698/* Drive functions ************************************************/
1699
1700static int mcdx_tray_move(struct cdrom_device_info *cdi, int position)
1701{
1702 struct s_drive_stuff *stuffp = cdi->handle;
1703
1704 if (!stuffp->present)
1705 return -ENXIO;
1706 if (!(stuffp->present & DOOR))
1707 return -ENOSYS;
1708
1709 if (position) /* 1: eject */
1710 return mcdx_talk(stuffp, "\xf6", 1, NULL, 1, 5 * HZ, 3);
1711 else /* 0: close */
1712 return mcdx_talk(stuffp, "\xf8", 1, NULL, 1, 5 * HZ, 3);
1713 return 1;
1714}
1715
1716static int mcdx_stop(struct s_drive_stuff *stuffp, int tries)
1717{
1718 return mcdx_talk(stuffp, "\xf0", 1, NULL, 1, 2 * HZ, tries);
1719}
1720
1721static int mcdx_hold(struct s_drive_stuff *stuffp, int tries)
1722{
1723 return mcdx_talk(stuffp, "\x70", 1, NULL, 1, 2 * HZ, tries);
1724}
1725
1726static int mcdx_requestsubqcode(struct s_drive_stuff *stuffp,
1727 struct s_subqcode *sub, int tries)
1728{
1729 char buf[11];
1730 int ans;
1731
1732 if (-1 == (ans = mcdx_talk(stuffp, "\x20", 1, buf, sizeof(buf),
1733 2 * HZ, tries)))
1734 return -1;
1735 sub->control = buf[1];
1736 sub->tno = buf[2];
1737 sub->index = buf[3];
1738 sub->tt.minute = buf[4];
1739 sub->tt.second = buf[5];
1740 sub->tt.frame = buf[6];
1741 sub->dt.minute = buf[8];
1742 sub->dt.second = buf[9];
1743 sub->dt.frame = buf[10];
1744
1745 return ans;
1746}
1747
1748static int mcdx_requestmultidiskinfo(struct s_drive_stuff *stuffp,
1749 struct s_multi *multi, int tries)
1750{
1751 char buf[5];
1752 int ans;
1753
1754 if (stuffp->present & MULTI) {
1755 ans =
1756 mcdx_talk(stuffp, "\x11", 1, buf, sizeof(buf), 2 * HZ,
1757 tries);
1758 multi->multi = buf[1];
1759 multi->msf_last.minute = buf[2];
1760 multi->msf_last.second = buf[3];
1761 multi->msf_last.frame = buf[4];
1762 return ans;
1763 } else {
1764 multi->multi = 0;
1765 return 0;
1766 }
1767}
1768
1769static int mcdx_requesttocdata(struct s_drive_stuff *stuffp, struct s_diskinfo *info,
1770 int tries)
1771{
1772 char buf[9];
1773 int ans;
1774 ans =
1775 mcdx_talk(stuffp, "\x10", 1, buf, sizeof(buf), 2 * HZ, tries);
1776 if (ans == -1) {
1777 info->n_first = 0;
1778 info->n_last = 0;
1779 } else {
1780 info->n_first = bcd2uint(buf[1]);
1781 info->n_last = bcd2uint(buf[2]);
1782 info->msf_leadout.minute = buf[3];
1783 info->msf_leadout.second = buf[4];
1784 info->msf_leadout.frame = buf[5];
1785 info->msf_first.minute = buf[6];
1786 info->msf_first.second = buf[7];
1787 info->msf_first.frame = buf[8];
1788 }
1789 return ans;
1790}
1791
1792static int mcdx_setdrivemode(struct s_drive_stuff *stuffp, enum drivemodes mode,
1793 int tries)
1794{
1795 char cmd[2];
1796 int ans;
1797
1798 xtrace(HW, "setdrivemode() %d\n", mode);
1799
1800 if (-1 == (ans = mcdx_talk(stuffp, "\xc2", 1, cmd, sizeof(cmd), 5 * HZ, tries)))
1801 return -1;
1802
1803 switch (mode) {
1804 case TOC:
1805 cmd[1] |= 0x04;
1806 break;
1807 case DATA:
1808 cmd[1] &= ~0x04;
1809 break;
1810 case RAW:
1811 cmd[1] |= 0x40;
1812 break;
1813 case COOKED:
1814 cmd[1] &= ~0x40;
1815 break;
1816 default:
1817 break;
1818 }
1819 cmd[0] = 0x50;
1820 return mcdx_talk(stuffp, cmd, 2, NULL, 1, 5 * HZ, tries);
1821}
1822
1823static int mcdx_setdatamode(struct s_drive_stuff *stuffp, enum datamodes mode,
1824 int tries)
1825{
1826 unsigned char cmd[2] = { 0xa0 };
1827 xtrace(HW, "setdatamode() %d\n", mode);
1828 switch (mode) {
1829 case MODE0:
1830 cmd[1] = 0x00;
1831 break;
1832 case MODE1:
1833 cmd[1] = 0x01;
1834 break;
1835 case MODE2:
1836 cmd[1] = 0x02;
1837 break;
1838 default:
1839 return -EINVAL;
1840 }
1841 return mcdx_talk(stuffp, cmd, 2, NULL, 1, 5 * HZ, tries);
1842}
1843
1844static int mcdx_config(struct s_drive_stuff *stuffp, int tries)
1845{
1846 char cmd[4];
1847
1848 xtrace(HW, "config()\n");
1849
1850 cmd[0] = 0x90;
1851
1852 cmd[1] = 0x10; /* irq enable */
1853 cmd[2] = 0x05; /* pre, err irq enable */
1854
1855 if (-1 == mcdx_talk(stuffp, cmd, 3, NULL, 1, 1 * HZ, tries))
1856 return -1;
1857
1858 cmd[1] = 0x02; /* dma select */
1859 cmd[2] = 0x00; /* no dma */
1860
1861 return mcdx_talk(stuffp, cmd, 3, NULL, 1, 1 * HZ, tries);
1862}
1863
1864static int mcdx_requestversion(struct s_drive_stuff *stuffp, struct s_version *ver,
1865 int tries)
1866{
1867 char buf[3];
1868 int ans;
1869
1870 if (-1 == (ans = mcdx_talk(stuffp, "\xdc",
1871 1, buf, sizeof(buf), 2 * HZ, tries)))
1872 return ans;
1873
1874 ver->code = buf[1];
1875 ver->ver = buf[2];
1876
1877 return ans;
1878}
1879
1880static int mcdx_reset(struct s_drive_stuff *stuffp, enum resetmodes mode, int tries)
1881{
1882 if (mode == HARD) {
1883 outb(0, stuffp->wreg_chn); /* no dma, no irq -> hardware */
1884 outb(0, stuffp->wreg_reset); /* hw reset */
1885 return 0;
1886 } else
1887 return mcdx_talk(stuffp, "\x60", 1, NULL, 1, 5 * HZ, tries);
1888}
1889
1890static int mcdx_lockdoor(struct cdrom_device_info *cdi, int lock)
1891{
1892 struct s_drive_stuff *stuffp = cdi->handle;
1893 char cmd[2] = { 0xfe };
1894
1895 if (!(stuffp->present & DOOR))
1896 return -ENOSYS;
1897 if (stuffp->present & DOOR) {
1898 cmd[1] = lock ? 0x01 : 0x00;
1899 return mcdx_talk(stuffp, cmd, sizeof(cmd), NULL, 1, 5 * HZ, 3);
1900 } else
1901 return 0;
1902}
1903
1904static int mcdx_getstatus(struct s_drive_stuff *stuffp, int tries)
1905{
1906 return mcdx_talk(stuffp, "\x40", 1, NULL, 1, 5 * HZ, tries);
1907}
1908
1909static int
1910mcdx_getval(struct s_drive_stuff *stuffp, int to, int delay, char *buf)
1911{
1912 unsigned long timeout = to + jiffies;
1913 char c;
1914
1915 if (!buf)
1916 buf = &c;
1917
1918 while (inb(stuffp->rreg_status) & MCDX_RBIT_STEN) {
1919 if (time_after(jiffies, timeout))
1920 return -1;
1921 mcdx_delay(stuffp, delay);
1922 }
1923
1924 *buf = (unsigned char) inb(stuffp->rreg_data) & 0xff;
1925
1926 return 0;
1927}
1928
1929static int mcdx_setattentuator(struct s_drive_stuff *stuffp,
1930 struct cdrom_volctrl *vol, int tries)
1931{
1932 char cmd[5];
1933 cmd[0] = 0xae;
1934 cmd[1] = vol->channel0;
1935 cmd[2] = 0;
1936 cmd[3] = vol->channel1;
1937 cmd[4] = 0;
1938
1939 return mcdx_talk(stuffp, cmd, sizeof(cmd), NULL, 5, 200, tries);
1940}
1941
1942MODULE_LICENSE("GPL");
1943MODULE_ALIAS_BLOCKDEV_MAJOR(MITSUMI_X_CDROM_MAJOR);
diff --git a/drivers/cdrom/mcdx.h b/drivers/cdrom/mcdx.h
deleted file mode 100644
index 83c364a74dc4..000000000000
--- a/drivers/cdrom/mcdx.h
+++ /dev/null
@@ -1,185 +0,0 @@
1/*
2 * Definitions for the Mitsumi CDROM interface
3 * Copyright (C) 1995 1996 Heiko Schlittermann <heiko@lotte.sax.de>
4 * VERSION: @VERSION@
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; see the file COPYING. If not, write to
18 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
19 *
20 * Thanks to
21 * The Linux Community at all and ...
22 * Martin Harris (he wrote the first Mitsumi Driver)
23 * Eberhard Moenkeberg (he gave me much support and the initial kick)
24 * Bernd Huebner, Ruediger Helsch (Unifix-Software Gmbh, they
25 * improved the original driver)
26 * Jon Tombs, Bjorn Ekwall (module support)
27 * Daniel v. Mosnenck (he sent me the Technical and Programming Reference)
28 * Gerd Knorr (he lent me his PhotoCD)
29 * Nils Faerber and Roger E. Wolff (extensively tested the LU portion)
30 * Andreas Kies (testing the mysterious hang up's)
31 * ... somebody forgotten?
32 * Marcin Dalecki
33 *
34 */
35
36/*
37 * The following lines are for user configuration
38 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
39 *
40 * {0|1} -- 1 if you want the driver detect your drive, may crash and
41 * needs a long time to seek. The higher the address the longer the
42 * seek.
43 *
44 * WARNING: AUTOPROBE doesn't work.
45 */
46#define MCDX_AUTOPROBE 0
47
48/*
49 * Drive specific settings according to the jumpers on the controller
50 * board(s).
51 * o MCDX_NDRIVES : number of used entries of the following table
52 * o MCDX_DRIVEMAP : table of {i/o base, irq} per controller
53 *
54 * NOTE: I didn't get a drive at irq 9(2) working. Not even alone.
55 */
56#if MCDX_AUTOPROBE == 0
57 #define MCDX_NDRIVES 1
58 #define MCDX_DRIVEMAP { \
59 {0x300, 11}, \
60 {0x304, 05}, \
61 {0x000, 00}, \
62 {0x000, 00}, \
63 {0x000, 00}, \
64 }
65#else
66 #error Autoprobing is not implemented yet.
67#endif
68
69#ifndef MCDX_QUIET
70#define MCDX_QUIET 1
71#endif
72
73#ifndef MCDX_DEBUG
74#define MCDX_DEBUG 0
75#endif
76
77/* *** make the following line uncommented, if you're sure,
78 * *** all configuration is done */
79/* #define I_WAS_HERE */
80
81/* The name of the device */
82#define MCDX "mcdx"
83
84/* Flags for DEBUGGING */
85#define INIT 0
86#define MALLOC 0
87#define IOCTL 0
88#define PLAYTRK 0
89#define SUBCHNL 0
90#define TOCHDR 0
91#define MS 0
92#define PLAYMSF 0
93#define READTOC 0
94#define OPENCLOSE 0
95#define HW 0
96#define TALK 0
97#define IRQ 0
98#define XFER 0
99#define REQUEST 0
100#define SLEEP 0
101
102/* The following addresses are taken from the Mitsumi Reference
103 * and describe the possible i/o range for the controller.
104 */
105#define MCDX_IO_BEGIN ((char*) 0x300) /* first base of i/o addr */
106#define MCDX_IO_END ((char*) 0x3fc) /* last base of i/o addr */
107
108/* Per controller 4 bytes i/o are needed. */
109#define MCDX_IO_SIZE 4
110
111/*
112 * Bits
113 */
114
115/* The status byte, returned from every command, set if
116 * the description is true */
117#define MCDX_RBIT_OPEN 0x80 /* door is open */
118#define MCDX_RBIT_DISKSET 0x40 /* disk set (recognised) */
119#define MCDX_RBIT_CHANGED 0x20 /* disk was changed */
120#define MCDX_RBIT_CHECK 0x10 /* disk rotates, servo is on */
121#define MCDX_RBIT_AUDIOTR 0x08 /* current track is audio */
122#define MCDX_RBIT_RDERR 0x04 /* read error, refer SENSE KEY */
123#define MCDX_RBIT_AUDIOBS 0x02 /* currently playing audio */
124#define MCDX_RBIT_CMDERR 0x01 /* command, param or format error */
125
126/* The I/O Register holding the h/w status of the drive,
127 * can be read at i/o base + 1 */
128#define MCDX_RBIT_DOOR 0x10 /* door is open */
129#define MCDX_RBIT_STEN 0x04 /* if 0, i/o base contains drive status */
130#define MCDX_RBIT_DTEN 0x02 /* if 0, i/o base contains data */
131
132/*
133 * The commands.
134 */
135
136#define OPCODE 1 /* offset of opcode */
137#define MCDX_CMD_REQUEST_TOC 1, 0x10
138#define MCDX_CMD_REQUEST_STATUS 1, 0x40
139#define MCDX_CMD_RESET 1, 0x60
140#define MCDX_CMD_REQUEST_DRIVE_MODE 1, 0xc2
141#define MCDX_CMD_SET_INTERLEAVE 2, 0xc8, 0
142#define MCDX_CMD_DATAMODE_SET 2, 0xa0, 0
143 #define MCDX_DATAMODE1 0x01
144 #define MCDX_DATAMODE2 0x02
145#define MCDX_CMD_LOCK_DOOR 2, 0xfe, 0
146
147#define READ_AHEAD 4 /* 8 Sectors (4K) */
148
149/* Useful macros */
150#define e_door(x) ((x) & MCDX_RBIT_OPEN)
151#define e_check(x) (~(x) & MCDX_RBIT_CHECK)
152#define e_notset(x) (~(x) & MCDX_RBIT_DISKSET)
153#define e_changed(x) ((x) & MCDX_RBIT_CHANGED)
154#define e_audio(x) ((x) & MCDX_RBIT_AUDIOTR)
155#define e_audiobusy(x) ((x) & MCDX_RBIT_AUDIOBS)
156#define e_cmderr(x) ((x) & MCDX_RBIT_CMDERR)
157#define e_readerr(x) ((x) & MCDX_RBIT_RDERR)
158
159/** no drive specific */
160#define MCDX_CDBLK 2048 /* 2048 cooked data each blk */
161
162#define MCDX_DATA_TIMEOUT (HZ/10) /* 0.1 second */
163
164/*
165 * Access to the msf array
166 */
167#define MSF_MIN 0 /* minute */
168#define MSF_SEC 1 /* second */
169#define MSF_FRM 2 /* frame */
170
171/*
172 * Errors
173 */
174#define MCDX_E 1 /* unspec error */
175#define MCDX_ST_EOM 0x0100 /* end of media */
176#define MCDX_ST_DRV 0x00ff /* mask to query the drive status */
177
178#ifndef I_WAS_HERE
179#ifndef MODULE
180#warning You have not edited mcdx.h
181#warning Perhaps irq and i/o settings are wrong.
182#endif
183#endif
184
185/* ex:set ts=4 sw=4: */
diff --git a/drivers/cdrom/optcd.c b/drivers/cdrom/optcd.c
deleted file mode 100644
index 3541690a77d4..000000000000
--- a/drivers/cdrom/optcd.c
+++ /dev/null
@@ -1,2105 +0,0 @@
1/* linux/drivers/cdrom/optcd.c - Optics Storage 8000 AT CDROM driver
2 $Id: optcd.c,v 1.11 1997/01/26 07:13:00 davem Exp $
3
4 Copyright (C) 1995 Leo Spiekman (spiekman@dutette.et.tudelft.nl)
5
6
7 Based on Aztech CD268 CDROM driver by Werner Zimmermann and preworks
8 by Eberhard Moenkeberg (emoenke@gwdg.de).
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2, or (at your option)
13 any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23*/
24
25/* Revision history
26
27
28 14-5-95 v0.0 Plays sound tracks. No reading of data CDs yet.
29 Detection of disk change doesn't work.
30 21-5-95 v0.1 First ALPHA version. CD can be mounted. The
31 device major nr is borrowed from the Aztech
32 driver. Speed is around 240 kb/s, as measured
33 with "time dd if=/dev/cdrom of=/dev/null \
34 bs=2048 count=4096".
35 24-6-95 v0.2 Reworked the #defines for the command codes
36 and the like, as well as the structure of
37 the hardware communication protocol, to
38 reflect the "official" documentation, kindly
39 supplied by C.K. Tan, Optics Storage Pte. Ltd.
40 Also tidied up the state machine somewhat.
41 28-6-95 v0.3 Removed the ISP-16 interface code, as this
42 should go into its own driver. The driver now
43 has its own major nr.
44 Disk change detection now seems to work, too.
45 This version became part of the standard
46 kernel as of version 1.3.7
47 24-9-95 v0.4 Re-inserted ISP-16 interface code which I
48 copied from sjcd.c, with a few changes.
49 Updated README.optcd. Submitted for
50 inclusion in 1.3.21
51 29-9-95 v0.4a Fixed bug that prevented compilation as module
52 25-10-95 v0.5 Started multisession code. Implementation
53 copied from Werner Zimmermann, who copied it
54 from Heiko Schlittermann's mcdx.
55 17-1-96 v0.6 Multisession works; some cleanup too.
56 18-4-96 v0.7 Increased some timing constants;
57 thanks to Luke McFarlane. Also tidied up some
58 printk behaviour. ISP16 initialization
59 is now handled by a separate driver.
60
61 09-11-99 Make kernel-parameter implementation work with 2.3.x
62 Removed init_module & cleanup_module in favor of
63 module_init & module_exit.
64 Torben Mathiasen <tmm@image.dk>
65*/
66
67/* Includes */
68
69
70#include <linux/module.h>
71#include <linux/mm.h>
72#include <linux/ioport.h>
73#include <linux/init.h>
74
75#include <asm/io.h>
76#include <linux/blkdev.h>
77
78#include <linux/cdrom.h>
79#include "optcd.h"
80
81#include <asm/uaccess.h>
82
83#define MAJOR_NR OPTICS_CDROM_MAJOR
84#define QUEUE (opt_queue)
85#define CURRENT elv_next_request(opt_queue)
86
87
88/* Debug support */
89
90
91/* Don't forget to add new debug flags here. */
92#if DEBUG_DRIVE_IF | DEBUG_VFS | DEBUG_CONV | DEBUG_TOC | \
93 DEBUG_BUFFERS | DEBUG_REQUEST | DEBUG_STATE | DEBUG_MULTIS
94#define DEBUG(x) debug x
95static void debug(int debug_this, const char* fmt, ...)
96{
97 char s[1024];
98 va_list args;
99
100 if (!debug_this)
101 return;
102
103 va_start(args, fmt);
104 vsnprintf(s, sizeof(s), fmt, args);
105 printk(KERN_DEBUG "optcd: %s\n", s);
106 va_end(args);
107}
108#else
109#define DEBUG(x)
110#endif
111
112
113/* Drive hardware/firmware characteristics
114 Identifiers in accordance with Optics Storage documentation */
115
116
117#define optcd_port optcd /* Needed for the modutils. */
118static short optcd_port = OPTCD_PORTBASE; /* I/O base of drive. */
119module_param(optcd_port, short, 0);
120/* Drive registers, read */
121#define DATA_PORT optcd_port /* Read data/status */
122#define STATUS_PORT optcd_port+1 /* Indicate data/status availability */
123
124/* Drive registers, write */
125#define COMIN_PORT optcd_port /* For passing command/parameter */
126#define RESET_PORT optcd_port+1 /* Write anything and wait 0.5 sec */
127#define HCON_PORT optcd_port+2 /* Host Xfer Configuration */
128
129
130/* Command completion/status read from DATA register */
131#define ST_DRVERR 0x80
132#define ST_DOOR_OPEN 0x40
133#define ST_MIXEDMODE_DISK 0x20
134#define ST_MODE_BITS 0x1c
135#define ST_M_STOP 0x00
136#define ST_M_READ 0x04
137#define ST_M_AUDIO 0x04
138#define ST_M_PAUSE 0x08
139#define ST_M_INITIAL 0x0c
140#define ST_M_ERROR 0x10
141#define ST_M_OTHERS 0x14
142#define ST_MODE2TRACK 0x02
143#define ST_DSK_CHG 0x01
144#define ST_L_LOCK 0x01
145#define ST_CMD_OK 0x00
146#define ST_OP_OK 0x01
147#define ST_PA_OK 0x02
148#define ST_OP_ERROR 0x05
149#define ST_PA_ERROR 0x06
150
151
152/* Error codes (appear as command completion code from DATA register) */
153/* Player related errors */
154#define ERR_ILLCMD 0x11 /* Illegal command to player module */
155#define ERR_ILLPARM 0x12 /* Illegal parameter to player module */
156#define ERR_SLEDGE 0x13
157#define ERR_FOCUS 0x14
158#define ERR_MOTOR 0x15
159#define ERR_RADIAL 0x16
160#define ERR_PLL 0x17 /* PLL lock error */
161#define ERR_SUB_TIM 0x18 /* Subcode timeout error */
162#define ERR_SUB_NF 0x19 /* Subcode not found error */
163#define ERR_TRAY 0x1a
164#define ERR_TOC 0x1b /* Table of Contents read error */
165#define ERR_JUMP 0x1c
166/* Data errors */
167#define ERR_MODE 0x21
168#define ERR_FORM 0x22
169#define ERR_HEADADDR 0x23 /* Header Address not found */
170#define ERR_CRC 0x24
171#define ERR_ECC 0x25 /* Uncorrectable ECC error */
172#define ERR_CRC_UNC 0x26 /* CRC error and uncorrectable error */
173#define ERR_ILLBSYNC 0x27 /* Illegal block sync error */
174#define ERR_VDST 0x28 /* VDST not found */
175/* Timeout errors */
176#define ERR_READ_TIM 0x31 /* Read timeout error */
177#define ERR_DEC_STP 0x32 /* Decoder stopped */
178#define ERR_DEC_TIM 0x33 /* Decoder interrupt timeout error */
179/* Function abort codes */
180#define ERR_KEY 0x41 /* Key -Detected abort */
181#define ERR_READ_FINISH 0x42 /* Read Finish */
182/* Second Byte diagnostic codes */
183#define ERR_NOBSYNC 0x01 /* No block sync */
184#define ERR_SHORTB 0x02 /* Short block */
185#define ERR_LONGB 0x03 /* Long block */
186#define ERR_SHORTDSP 0x04 /* Short DSP word */
187#define ERR_LONGDSP 0x05 /* Long DSP word */
188
189
190/* Status availability flags read from STATUS register */
191#define FL_EJECT 0x20
192#define FL_WAIT 0x10 /* active low */
193#define FL_EOP 0x08 /* active low */
194#define FL_STEN 0x04 /* Status available when low */
195#define FL_DTEN 0x02 /* Data available when low */
196#define FL_DRQ 0x01 /* active low */
197#define FL_RESET 0xde /* These bits are high after a reset */
198#define FL_STDT (FL_STEN|FL_DTEN)
199
200
201/* Transfer mode, written to HCON register */
202#define HCON_DTS 0x08
203#define HCON_SDRQB 0x04
204#define HCON_LOHI 0x02
205#define HCON_DMA16 0x01
206
207
208/* Drive command set, written to COMIN register */
209/* Quick response commands */
210#define COMDRVST 0x20 /* Drive Status Read */
211#define COMERRST 0x21 /* Error Status Read */
212#define COMIOCTLISTAT 0x22 /* Status Read; reset disk changed bit */
213#define COMINITSINGLE 0x28 /* Initialize Single Speed */
214#define COMINITDOUBLE 0x29 /* Initialize Double Speed */
215#define COMUNLOCK 0x30 /* Unlock */
216#define COMLOCK 0x31 /* Lock */
217#define COMLOCKST 0x32 /* Lock/Unlock Status */
218#define COMVERSION 0x40 /* Get Firmware Revision */
219#define COMVOIDREADMODE 0x50 /* Void Data Read Mode */
220/* Read commands */
221#define COMFETCH 0x60 /* Prefetch Data */
222#define COMREAD 0x61 /* Read */
223#define COMREADRAW 0x62 /* Read Raw Data */
224#define COMREADALL 0x63 /* Read All 2646 Bytes */
225/* Player control commands */
226#define COMLEADIN 0x70 /* Seek To Lead-in */
227#define COMSEEK 0x71 /* Seek */
228#define COMPAUSEON 0x80 /* Pause On */
229#define COMPAUSEOFF 0x81 /* Pause Off */
230#define COMSTOP 0x82 /* Stop */
231#define COMOPEN 0x90 /* Open Tray Door */
232#define COMCLOSE 0x91 /* Close Tray Door */
233#define COMPLAY 0xa0 /* Audio Play */
234#define COMPLAY_TNO 0xa2 /* Audio Play By Track Number */
235#define COMSUBQ 0xb0 /* Read Sub-q Code */
236#define COMLOCATION 0xb1 /* Read Head Position */
237/* Audio control commands */
238#define COMCHCTRL 0xc0 /* Audio Channel Control */
239/* Miscellaneous (test) commands */
240#define COMDRVTEST 0xd0 /* Write Test Bytes */
241#define COMTEST 0xd1 /* Diagnostic Test */
242
243/* Low level drive interface. Only here we do actual I/O
244 Waiting for status / data available */
245
246
247/* Busy wait until FLAG goes low. Return 0 on timeout. */
248static inline int flag_low(int flag, unsigned long timeout)
249{
250 int flag_high;
251 unsigned long count = 0;
252
253 while ((flag_high = (inb(STATUS_PORT) & flag)))
254 if (++count >= timeout)
255 break;
256
257 DEBUG((DEBUG_DRIVE_IF, "flag_low 0x%x count %ld%s",
258 flag, count, flag_high ? " timeout" : ""));
259 return !flag_high;
260}
261
262
263/* Timed waiting for status or data */
264static int sleep_timeout; /* max # of ticks to sleep */
265static DECLARE_WAIT_QUEUE_HEAD(waitq);
266static void sleep_timer(unsigned long data);
267static DEFINE_TIMER(delay_timer, sleep_timer, 0, 0);
268static DEFINE_SPINLOCK(optcd_lock);
269static struct request_queue *opt_queue;
270
271/* Timer routine: wake up when desired flag goes low,
272 or when timeout expires. */
273static void sleep_timer(unsigned long data)
274{
275 int flags = inb(STATUS_PORT) & FL_STDT;
276
277 if (flags == FL_STDT && --sleep_timeout > 0) {
278 mod_timer(&delay_timer, jiffies + HZ/100); /* multi-statement macro */
279 } else
280 wake_up(&waitq);
281}
282
283
284/* Sleep until FLAG goes low. Return 0 on timeout or wrong flag low. */
285static int sleep_flag_low(int flag, unsigned long timeout)
286{
287 int flag_high;
288
289 DEBUG((DEBUG_DRIVE_IF, "sleep_flag_low"));
290
291 sleep_timeout = timeout;
292 flag_high = inb(STATUS_PORT) & flag;
293 if (flag_high && sleep_timeout > 0) {
294 mod_timer(&delay_timer, jiffies + HZ/100);
295 sleep_on(&waitq);
296 flag_high = inb(STATUS_PORT) & flag;
297 }
298
299 DEBUG((DEBUG_DRIVE_IF, "flag 0x%x count %ld%s",
300 flag, timeout, flag_high ? " timeout" : ""));
301 return !flag_high;
302}
303
304/* Low level drive interface. Only here we do actual I/O
305 Sending commands and parameters */
306
307
308/* Errors in the command protocol */
309#define ERR_IF_CMD_TIMEOUT 0x100
310#define ERR_IF_ERR_TIMEOUT 0x101
311#define ERR_IF_RESP_TIMEOUT 0x102
312#define ERR_IF_DATA_TIMEOUT 0x103
313#define ERR_IF_NOSTAT 0x104
314
315
316/* Send command code. Return <0 indicates error */
317static int send_cmd(int cmd)
318{
319 unsigned char ack;
320
321 DEBUG((DEBUG_DRIVE_IF, "sending command 0x%02x\n", cmd));
322
323 outb(HCON_DTS, HCON_PORT); /* Enable Suspend Data Transfer */
324 outb(cmd, COMIN_PORT); /* Send command code */
325 if (!flag_low(FL_STEN, BUSY_TIMEOUT)) /* Wait for status */
326 return -ERR_IF_CMD_TIMEOUT;
327 ack = inb(DATA_PORT); /* read command acknowledge */
328 outb(HCON_SDRQB, HCON_PORT); /* Disable Suspend Data Transfer */
329 return ack==ST_OP_OK ? 0 : -ack;
330}
331
332
333/* Send command parameters. Return <0 indicates error */
334static int send_params(struct cdrom_msf *params)
335{
336 unsigned char ack;
337
338 DEBUG((DEBUG_DRIVE_IF, "sending parameters"
339 " %02x:%02x:%02x"
340 " %02x:%02x:%02x",
341 params->cdmsf_min0,
342 params->cdmsf_sec0,
343 params->cdmsf_frame0,
344 params->cdmsf_min1,
345 params->cdmsf_sec1,
346 params->cdmsf_frame1));
347
348 outb(params->cdmsf_min0, COMIN_PORT);
349 outb(params->cdmsf_sec0, COMIN_PORT);
350 outb(params->cdmsf_frame0, COMIN_PORT);
351 outb(params->cdmsf_min1, COMIN_PORT);
352 outb(params->cdmsf_sec1, COMIN_PORT);
353 outb(params->cdmsf_frame1, COMIN_PORT);
354 if (!flag_low(FL_STEN, BUSY_TIMEOUT)) /* Wait for status */
355 return -ERR_IF_CMD_TIMEOUT;
356 ack = inb(DATA_PORT); /* read command acknowledge */
357 return ack==ST_PA_OK ? 0 : -ack;
358}
359
360
361/* Send parameters for SEEK command. Return <0 indicates error */
362static int send_seek_params(struct cdrom_msf *params)
363{
364 unsigned char ack;
365
366 DEBUG((DEBUG_DRIVE_IF, "sending seek parameters"
367 " %02x:%02x:%02x",
368 params->cdmsf_min0,
369 params->cdmsf_sec0,
370 params->cdmsf_frame0));
371
372 outb(params->cdmsf_min0, COMIN_PORT);
373 outb(params->cdmsf_sec0, COMIN_PORT);
374 outb(params->cdmsf_frame0, COMIN_PORT);
375 if (!flag_low(FL_STEN, BUSY_TIMEOUT)) /* Wait for status */
376 return -ERR_IF_CMD_TIMEOUT;
377 ack = inb(DATA_PORT); /* read command acknowledge */
378 return ack==ST_PA_OK ? 0 : -ack;
379}
380
381
382/* Wait for command execution status. Choice between busy waiting
383 and sleeping. Return value <0 indicates timeout. */
384static inline int get_exec_status(int busy_waiting)
385{
386 unsigned char exec_status;
387
388 if (busy_waiting
389 ? !flag_low(FL_STEN, BUSY_TIMEOUT)
390 : !sleep_flag_low(FL_STEN, SLEEP_TIMEOUT))
391 return -ERR_IF_CMD_TIMEOUT;
392
393 exec_status = inb(DATA_PORT);
394 DEBUG((DEBUG_DRIVE_IF, "returned exec status 0x%02x", exec_status));
395 return exec_status;
396}
397
398
399/* Wait busy for extra byte of data that a command returns.
400 Return value <0 indicates timeout. */
401static inline int get_data(int short_timeout)
402{
403 unsigned char data;
404
405 if (!flag_low(FL_STEN, short_timeout ? FAST_TIMEOUT : BUSY_TIMEOUT))
406 return -ERR_IF_DATA_TIMEOUT;
407
408 data = inb(DATA_PORT);
409 DEBUG((DEBUG_DRIVE_IF, "returned data 0x%02x", data));
410 return data;
411}
412
413
414/* Returns 0 if failed */
415static int reset_drive(void)
416{
417 unsigned long count = 0;
418 int flags;
419
420 DEBUG((DEBUG_DRIVE_IF, "reset drive"));
421
422 outb(0, RESET_PORT);
423 while (++count < RESET_WAIT)
424 inb(DATA_PORT);
425
426 count = 0;
427 while ((flags = (inb(STATUS_PORT) & FL_RESET)) != FL_RESET)
428 if (++count >= BUSY_TIMEOUT)
429 break;
430
431 DEBUG((DEBUG_DRIVE_IF, "reset %s",
432 flags == FL_RESET ? "succeeded" : "failed"));
433
434 if (flags != FL_RESET)
435 return 0; /* Reset failed */
436 outb(HCON_SDRQB, HCON_PORT); /* Disable Suspend Data Transfer */
437 return 1; /* Reset succeeded */
438}
439
440
441/* Facilities for asynchronous operation */
442
443/* Read status/data availability flags FL_STEN and FL_DTEN */
444static inline int stdt_flags(void)
445{
446 return inb(STATUS_PORT) & FL_STDT;
447}
448
449
450/* Fetch status that has previously been waited for. <0 means not available */
451static inline int fetch_status(void)
452{
453 unsigned char status;
454
455 if (inb(STATUS_PORT) & FL_STEN)
456 return -ERR_IF_NOSTAT;
457
458 status = inb(DATA_PORT);
459 DEBUG((DEBUG_DRIVE_IF, "fetched exec status 0x%02x", status));
460 return status;
461}
462
463
464/* Fetch data that has previously been waited for. */
465static inline void fetch_data(char *buf, int n)
466{
467 insb(DATA_PORT, buf, n);
468 DEBUG((DEBUG_DRIVE_IF, "fetched 0x%x bytes", n));
469}
470
471
472/* Flush status and data fifos */
473static inline void flush_data(void)
474{
475 while ((inb(STATUS_PORT) & FL_STDT) != FL_STDT)
476 inb(DATA_PORT);
477 DEBUG((DEBUG_DRIVE_IF, "flushed fifos"));
478}
479
480/* Command protocol */
481
482
483/* Send a simple command and wait for response. Command codes < COMFETCH
484 are quick response commands */
485static inline int exec_cmd(int cmd)
486{
487 int ack = send_cmd(cmd);
488 if (ack < 0)
489 return ack;
490 return get_exec_status(cmd < COMFETCH);
491}
492
493
494/* Send a command with parameters. Don't wait for the response,
495 * which consists of data blocks read from the CD. */
496static inline int exec_read_cmd(int cmd, struct cdrom_msf *params)
497{
498 int ack = send_cmd(cmd);
499 if (ack < 0)
500 return ack;
501 return send_params(params);
502}
503
504
505/* Send a seek command with parameters and wait for response */
506static inline int exec_seek_cmd(int cmd, struct cdrom_msf *params)
507{
508 int ack = send_cmd(cmd);
509 if (ack < 0)
510 return ack;
511 ack = send_seek_params(params);
512 if (ack < 0)
513 return ack;
514 return 0;
515}
516
517
518/* Send a command with parameters and wait for response */
519static inline int exec_long_cmd(int cmd, struct cdrom_msf *params)
520{
521 int ack = exec_read_cmd(cmd, params);
522 if (ack < 0)
523 return ack;
524 return get_exec_status(0);
525}
526
527/* Address conversion routines */
528
529
530/* Binary to BCD (2 digits) */
531static inline void single_bin2bcd(u_char *p)
532{
533 DEBUG((DEBUG_CONV, "bin2bcd %02d", *p));
534 *p = (*p % 10) | ((*p / 10) << 4);
535}
536
537
538/* Convert entire msf struct */
539static void bin2bcd(struct cdrom_msf *msf)
540{
541 single_bin2bcd(&msf->cdmsf_min0);
542 single_bin2bcd(&msf->cdmsf_sec0);
543 single_bin2bcd(&msf->cdmsf_frame0);
544 single_bin2bcd(&msf->cdmsf_min1);
545 single_bin2bcd(&msf->cdmsf_sec1);
546 single_bin2bcd(&msf->cdmsf_frame1);
547}
548
549
550/* Linear block address to minute, second, frame form */
551#define CD_FPM (CD_SECS * CD_FRAMES) /* frames per minute */
552
553static void lba2msf(int lba, struct cdrom_msf *msf)
554{
555 DEBUG((DEBUG_CONV, "lba2msf %d", lba));
556 lba += CD_MSF_OFFSET;
557 msf->cdmsf_min0 = lba / CD_FPM; lba %= CD_FPM;
558 msf->cdmsf_sec0 = lba / CD_FRAMES;
559 msf->cdmsf_frame0 = lba % CD_FRAMES;
560 msf->cdmsf_min1 = 0;
561 msf->cdmsf_sec1 = 0;
562 msf->cdmsf_frame1 = 0;
563 bin2bcd(msf);
564}
565
566
567/* Two BCD digits to binary */
568static inline u_char bcd2bin(u_char bcd)
569{
570 DEBUG((DEBUG_CONV, "bcd2bin %x%02x", bcd));
571 return (bcd >> 4) * 10 + (bcd & 0x0f);
572}
573
574
575static void msf2lba(union cdrom_addr *addr)
576{
577 addr->lba = addr->msf.minute * CD_FPM
578 + addr->msf.second * CD_FRAMES
579 + addr->msf.frame - CD_MSF_OFFSET;
580}
581
582
583/* Minute, second, frame address BCD to binary or to linear address,
584 depending on MODE */
585static void msf_bcd2bin(union cdrom_addr *addr)
586{
587 addr->msf.minute = bcd2bin(addr->msf.minute);
588 addr->msf.second = bcd2bin(addr->msf.second);
589 addr->msf.frame = bcd2bin(addr->msf.frame);
590}
591
592/* High level drive commands */
593
594
595static int audio_status = CDROM_AUDIO_NO_STATUS;
596static char toc_uptodate = 0;
597static char disk_changed = 1;
598
599/* Get drive status, flagging completion of audio play and disk changes. */
600static int drive_status(void)
601{
602 int status;
603
604 status = exec_cmd(COMIOCTLISTAT);
605 DEBUG((DEBUG_DRIVE_IF, "IOCTLISTAT: %03x", status));
606 if (status < 0)
607 return status;
608 if (status == 0xff) /* No status available */
609 return -ERR_IF_NOSTAT;
610
611 if (((status & ST_MODE_BITS) != ST_M_AUDIO) &&
612 (audio_status == CDROM_AUDIO_PLAY)) {
613 audio_status = CDROM_AUDIO_COMPLETED;
614 }
615
616 if (status & ST_DSK_CHG) {
617 toc_uptodate = 0;
618 disk_changed = 1;
619 audio_status = CDROM_AUDIO_NO_STATUS;
620 }
621
622 return status;
623}
624
625
626/* Read the current Q-channel info. Also used for reading the
627 table of contents. qp->cdsc_format must be set on entry to
628 indicate the desired address format */
629static int get_q_channel(struct cdrom_subchnl *qp)
630{
631 int status, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10;
632
633 status = drive_status();
634 if (status < 0)
635 return status;
636 qp->cdsc_audiostatus = audio_status;
637
638 status = exec_cmd(COMSUBQ);
639 if (status < 0)
640 return status;
641
642 d1 = get_data(0);
643 if (d1 < 0)
644 return d1;
645 qp->cdsc_adr = d1;
646 qp->cdsc_ctrl = d1 >> 4;
647
648 d2 = get_data(0);
649 if (d2 < 0)
650 return d2;
651 qp->cdsc_trk = bcd2bin(d2);
652
653 d3 = get_data(0);
654 if (d3 < 0)
655 return d3;
656 qp->cdsc_ind = bcd2bin(d3);
657
658 d4 = get_data(0);
659 if (d4 < 0)
660 return d4;
661 qp->cdsc_reladdr.msf.minute = d4;
662
663 d5 = get_data(0);
664 if (d5 < 0)
665 return d5;
666 qp->cdsc_reladdr.msf.second = d5;
667
668 d6 = get_data(0);
669 if (d6 < 0)
670 return d6;
671 qp->cdsc_reladdr.msf.frame = d6;
672
673 d7 = get_data(0);
674 if (d7 < 0)
675 return d7;
676 /* byte not used */
677
678 d8 = get_data(0);
679 if (d8 < 0)
680 return d8;
681 qp->cdsc_absaddr.msf.minute = d8;
682
683 d9 = get_data(0);
684 if (d9 < 0)
685 return d9;
686 qp->cdsc_absaddr.msf.second = d9;
687
688 d10 = get_data(0);
689 if (d10 < 0)
690 return d10;
691 qp->cdsc_absaddr.msf.frame = d10;
692
693 DEBUG((DEBUG_TOC, "%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
694 d1, d2, d3, d4, d5, d6, d7, d8, d9, d10));
695
696 msf_bcd2bin(&qp->cdsc_absaddr);
697 msf_bcd2bin(&qp->cdsc_reladdr);
698 if (qp->cdsc_format == CDROM_LBA) {
699 msf2lba(&qp->cdsc_absaddr);
700 msf2lba(&qp->cdsc_reladdr);
701 }
702
703 return 0;
704}
705
706/* Table of contents handling */
707
708
709/* Errors in table of contents */
710#define ERR_TOC_MISSINGINFO 0x120
711#define ERR_TOC_MISSINGENTRY 0x121
712
713
714struct cdrom_disk_info {
715 unsigned char first;
716 unsigned char last;
717 struct cdrom_msf0 disk_length;
718 struct cdrom_msf0 first_track;
719 /* Multisession info: */
720 unsigned char next;
721 struct cdrom_msf0 next_session;
722 struct cdrom_msf0 last_session;
723 unsigned char multi;
724 unsigned char xa;
725 unsigned char audio;
726};
727static struct cdrom_disk_info disk_info;
728
729#define MAX_TRACKS 111
730static struct cdrom_subchnl toc[MAX_TRACKS];
731
732#define QINFO_FIRSTTRACK 100 /* bcd2bin(0xa0) */
733#define QINFO_LASTTRACK 101 /* bcd2bin(0xa1) */
734#define QINFO_DISKLENGTH 102 /* bcd2bin(0xa2) */
735#define QINFO_NEXTSESSION 110 /* bcd2bin(0xb0) */
736
737#define I_FIRSTTRACK 0x01
738#define I_LASTTRACK 0x02
739#define I_DISKLENGTH 0x04
740#define I_NEXTSESSION 0x08
741#define I_ALL (I_FIRSTTRACK | I_LASTTRACK | I_DISKLENGTH)
742
743
744#if DEBUG_TOC
745static void toc_debug_info(int i)
746{
747 printk(KERN_DEBUG "#%3d ctl %1x, adr %1x, track %2d index %3d"
748 " %2d:%02d.%02d %2d:%02d.%02d\n",
749 i, toc[i].cdsc_ctrl, toc[i].cdsc_adr,
750 toc[i].cdsc_trk, toc[i].cdsc_ind,
751 toc[i].cdsc_reladdr.msf.minute,
752 toc[i].cdsc_reladdr.msf.second,
753 toc[i].cdsc_reladdr.msf.frame,
754 toc[i].cdsc_absaddr.msf.minute,
755 toc[i].cdsc_absaddr.msf.second,
756 toc[i].cdsc_absaddr.msf.frame);
757}
758#endif
759
760
761static int read_toc(void)
762{
763 int status, limit, count;
764 unsigned char got_info = 0;
765 struct cdrom_subchnl q_info;
766#if DEBUG_TOC
767 int i;
768#endif
769
770 DEBUG((DEBUG_TOC, "starting read_toc"));
771
772 count = 0;
773 for (limit = 60; limit > 0; limit--) {
774 int index;
775
776 q_info.cdsc_format = CDROM_MSF;
777 status = get_q_channel(&q_info);
778 if (status < 0)
779 return status;
780
781 index = q_info.cdsc_ind;
782 if (index > 0 && index < MAX_TRACKS
783 && q_info.cdsc_trk == 0 && toc[index].cdsc_ind == 0) {
784 toc[index] = q_info;
785 DEBUG((DEBUG_TOC, "got %d", index));
786 if (index < 100)
787 count++;
788
789 switch (q_info.cdsc_ind) {
790 case QINFO_FIRSTTRACK:
791 got_info |= I_FIRSTTRACK;
792 break;
793 case QINFO_LASTTRACK:
794 got_info |= I_LASTTRACK;
795 break;
796 case QINFO_DISKLENGTH:
797 got_info |= I_DISKLENGTH;
798 break;
799 case QINFO_NEXTSESSION:
800 got_info |= I_NEXTSESSION;
801 break;
802 }
803 }
804
805 if ((got_info & I_ALL) == I_ALL
806 && toc[QINFO_FIRSTTRACK].cdsc_absaddr.msf.minute + count
807 >= toc[QINFO_LASTTRACK].cdsc_absaddr.msf.minute + 1)
808 break;
809 }
810
811 /* Construct disk_info from TOC */
812 if (disk_info.first == 0) {
813 disk_info.first = toc[QINFO_FIRSTTRACK].cdsc_absaddr.msf.minute;
814 disk_info.first_track.minute =
815 toc[disk_info.first].cdsc_absaddr.msf.minute;
816 disk_info.first_track.second =
817 toc[disk_info.first].cdsc_absaddr.msf.second;
818 disk_info.first_track.frame =
819 toc[disk_info.first].cdsc_absaddr.msf.frame;
820 }
821 disk_info.last = toc[QINFO_LASTTRACK].cdsc_absaddr.msf.minute;
822 disk_info.disk_length.minute =
823 toc[QINFO_DISKLENGTH].cdsc_absaddr.msf.minute;
824 disk_info.disk_length.second =
825 toc[QINFO_DISKLENGTH].cdsc_absaddr.msf.second-2;
826 disk_info.disk_length.frame =
827 toc[QINFO_DISKLENGTH].cdsc_absaddr.msf.frame;
828 disk_info.next_session.minute =
829 toc[QINFO_NEXTSESSION].cdsc_reladdr.msf.minute;
830 disk_info.next_session.second =
831 toc[QINFO_NEXTSESSION].cdsc_reladdr.msf.second;
832 disk_info.next_session.frame =
833 toc[QINFO_NEXTSESSION].cdsc_reladdr.msf.frame;
834 disk_info.next = toc[QINFO_FIRSTTRACK].cdsc_absaddr.msf.minute;
835 disk_info.last_session.minute =
836 toc[disk_info.next].cdsc_absaddr.msf.minute;
837 disk_info.last_session.second =
838 toc[disk_info.next].cdsc_absaddr.msf.second;
839 disk_info.last_session.frame =
840 toc[disk_info.next].cdsc_absaddr.msf.frame;
841 toc[disk_info.last + 1].cdsc_absaddr.msf.minute =
842 disk_info.disk_length.minute;
843 toc[disk_info.last + 1].cdsc_absaddr.msf.second =
844 disk_info.disk_length.second;
845 toc[disk_info.last + 1].cdsc_absaddr.msf.frame =
846 disk_info.disk_length.frame;
847#if DEBUG_TOC
848 for (i = 1; i <= disk_info.last + 1; i++)
849 toc_debug_info(i);
850 toc_debug_info(QINFO_FIRSTTRACK);
851 toc_debug_info(QINFO_LASTTRACK);
852 toc_debug_info(QINFO_DISKLENGTH);
853 toc_debug_info(QINFO_NEXTSESSION);
854#endif
855
856 DEBUG((DEBUG_TOC, "exiting read_toc, got_info %x, count %d",
857 got_info, count));
858 if ((got_info & I_ALL) != I_ALL
859 || toc[QINFO_FIRSTTRACK].cdsc_absaddr.msf.minute + count
860 < toc[QINFO_LASTTRACK].cdsc_absaddr.msf.minute + 1)
861 return -ERR_TOC_MISSINGINFO;
862 return 0;
863}
864
865
866#ifdef MULTISESSION
867static int get_multi_disk_info(void)
868{
869 int sessions, status;
870 struct cdrom_msf multi_index;
871
872
873 for (sessions = 2; sessions < 10 /* %%for now */; sessions++) {
874 int count;
875
876 for (count = 100; count < MAX_TRACKS; count++)
877 toc[count].cdsc_ind = 0;
878
879 multi_index.cdmsf_min0 = disk_info.next_session.minute;
880 multi_index.cdmsf_sec0 = disk_info.next_session.second;
881 multi_index.cdmsf_frame0 = disk_info.next_session.frame;
882 if (multi_index.cdmsf_sec0 >= 20)
883 multi_index.cdmsf_sec0 -= 20;
884 else {
885 multi_index.cdmsf_sec0 += 40;
886 multi_index.cdmsf_min0--;
887 }
888 DEBUG((DEBUG_MULTIS, "Try %d: %2d:%02d.%02d", sessions,
889 multi_index.cdmsf_min0,
890 multi_index.cdmsf_sec0,
891 multi_index.cdmsf_frame0));
892 bin2bcd(&multi_index);
893 multi_index.cdmsf_min1 = 0;
894 multi_index.cdmsf_sec1 = 0;
895 multi_index.cdmsf_frame1 = 1;
896
897 status = exec_read_cmd(COMREAD, &multi_index);
898 if (status < 0) {
899 DEBUG((DEBUG_TOC, "exec_read_cmd COMREAD: %02x",
900 -status));
901 break;
902 }
903 status = sleep_flag_low(FL_DTEN, MULTI_SEEK_TIMEOUT) ?
904 0 : -ERR_TOC_MISSINGINFO;
905 flush_data();
906 if (status < 0) {
907 DEBUG((DEBUG_TOC, "sleep_flag_low: %02x", -status));
908 break;
909 }
910
911 status = read_toc();
912 if (status < 0) {
913 DEBUG((DEBUG_TOC, "read_toc: %02x", -status));
914 break;
915 }
916
917 disk_info.multi = 1;
918 }
919
920 exec_cmd(COMSTOP);
921
922 if (status < 0)
923 return -EIO;
924 return 0;
925}
926#endif /* MULTISESSION */
927
928
929static int update_toc(void)
930{
931 int status, count;
932
933 if (toc_uptodate)
934 return 0;
935
936 DEBUG((DEBUG_TOC, "starting update_toc"));
937
938 disk_info.first = 0;
939 for (count = 0; count < MAX_TRACKS; count++)
940 toc[count].cdsc_ind = 0;
941
942 status = exec_cmd(COMLEADIN);
943 if (status < 0)
944 return -EIO;
945
946 status = read_toc();
947 if (status < 0) {
948 DEBUG((DEBUG_TOC, "read_toc: %02x", -status));
949 return -EIO;
950 }
951
952 /* Audio disk detection. Look at first track. */
953 disk_info.audio =
954 (toc[disk_info.first].cdsc_ctrl & CDROM_DATA_TRACK) ? 0 : 1;
955
956 /* XA detection */
957 disk_info.xa = drive_status() & ST_MODE2TRACK;
958
959 /* Multisession detection: if we want this, define MULTISESSION */
960 disk_info.multi = 0;
961#ifdef MULTISESSION
962 if (disk_info.xa)
963 get_multi_disk_info(); /* Here disk_info.multi is set */
964#endif /* MULTISESSION */
965 if (disk_info.multi)
966 printk(KERN_WARNING "optcd: Multisession support experimental, "
967 "see Documentation/cdrom/optcd\n");
968
969 DEBUG((DEBUG_TOC, "exiting update_toc"));
970
971 toc_uptodate = 1;
972 return 0;
973}
974
975/* Request handling */
976
977static int current_valid(void)
978{
979 return CURRENT &&
980 CURRENT->cmd == READ &&
981 CURRENT->sector != -1;
982}
983
984/* Buffers for block size conversion. */
985#define NOBUF -1
986
987static char buf[CD_FRAMESIZE * N_BUFS];
988static volatile int buf_bn[N_BUFS], next_bn;
989static volatile int buf_in = 0, buf_out = NOBUF;
990
991static inline void opt_invalidate_buffers(void)
992{
993 int i;
994
995 DEBUG((DEBUG_BUFFERS, "executing opt_invalidate_buffers"));
996
997 for (i = 0; i < N_BUFS; i++)
998 buf_bn[i] = NOBUF;
999 buf_out = NOBUF;
1000}
1001
1002
1003/* Take care of the different block sizes between cdrom and Linux.
1004 When Linux gets variable block sizes this will probably go away. */
1005static void transfer(void)
1006{
1007#if DEBUG_BUFFERS | DEBUG_REQUEST
1008 printk(KERN_DEBUG "optcd: executing transfer\n");
1009#endif
1010
1011 if (!current_valid())
1012 return;
1013 while (CURRENT -> nr_sectors) {
1014 int bn = CURRENT -> sector / 4;
1015 int i, offs, nr_sectors;
1016 for (i = 0; i < N_BUFS && buf_bn[i] != bn; ++i);
1017
1018 DEBUG((DEBUG_REQUEST, "found %d", i));
1019
1020 if (i >= N_BUFS) {
1021 buf_out = NOBUF;
1022 break;
1023 }
1024
1025 offs = (i * 4 + (CURRENT -> sector & 3)) * 512;
1026 nr_sectors = 4 - (CURRENT -> sector & 3);
1027
1028 if (buf_out != i) {
1029 buf_out = i;
1030 if (buf_bn[i] != bn) {
1031 buf_out = NOBUF;
1032 continue;
1033 }
1034 }
1035
1036 if (nr_sectors > CURRENT -> nr_sectors)
1037 nr_sectors = CURRENT -> nr_sectors;
1038 memcpy(CURRENT -> buffer, buf + offs, nr_sectors * 512);
1039 CURRENT -> nr_sectors -= nr_sectors;
1040 CURRENT -> sector += nr_sectors;
1041 CURRENT -> buffer += nr_sectors * 512;
1042 }
1043}
1044
1045
1046/* State machine for reading disk blocks */
1047
1048enum state_e {
1049 S_IDLE, /* 0 */
1050 S_START, /* 1 */
1051 S_READ, /* 2 */
1052 S_DATA, /* 3 */
1053 S_STOP, /* 4 */
1054 S_STOPPING /* 5 */
1055};
1056
1057static volatile enum state_e state = S_IDLE;
1058#if DEBUG_STATE
1059static volatile enum state_e state_old = S_STOP;
1060static volatile int flags_old = 0;
1061static volatile long state_n = 0;
1062#endif
1063
1064
1065/* Used as mutex to keep do_optcd_request (and other processes calling
1066 ioctl) out while some process is inside a VFS call.
1067 Reverse is accomplished by checking if state = S_IDLE upon entry
1068 of opt_ioctl and opt_media_change. */
1069static int in_vfs = 0;
1070
1071
1072static volatile int transfer_is_active = 0;
1073static volatile int error = 0; /* %% do something with this?? */
1074static int tries; /* ibid?? */
1075static int timeout = 0;
1076
1077static void poll(unsigned long data);
1078static struct timer_list req_timer = {.function = poll};
1079
1080
1081static void poll(unsigned long data)
1082{
1083 static volatile int read_count = 1;
1084 int flags;
1085 int loop_again = 1;
1086 int status = 0;
1087 int skip = 0;
1088
1089 if (error) {
1090 printk(KERN_ERR "optcd: I/O error 0x%02x\n", error);
1091 opt_invalidate_buffers();
1092 if (!tries--) {
1093 printk(KERN_ERR "optcd: read block %d failed;"
1094 " Giving up\n", next_bn);
1095 if (transfer_is_active)
1096 loop_again = 0;
1097 if (current_valid())
1098 end_request(CURRENT, 0);
1099 tries = 5;
1100 }
1101 error = 0;
1102 state = S_STOP;
1103 }
1104
1105 while (loop_again)
1106 {
1107 loop_again = 0; /* each case must flip this back to 1 if we want
1108 to come back up here */
1109
1110#if DEBUG_STATE
1111 if (state == state_old)
1112 state_n++;
1113 else {
1114 state_old = state;
1115 if (++state_n > 1)
1116 printk(KERN_DEBUG "optcd: %ld times "
1117 "in previous state\n", state_n);
1118 printk(KERN_DEBUG "optcd: state %d\n", state);
1119 state_n = 0;
1120 }
1121#endif
1122
1123 switch (state) {
1124 case S_IDLE:
1125 return;
1126 case S_START:
1127 if (in_vfs)
1128 break;
1129 if (send_cmd(COMDRVST)) {
1130 state = S_IDLE;
1131 while (current_valid())
1132 end_request(CURRENT, 0);
1133 return;
1134 }
1135 state = S_READ;
1136 timeout = READ_TIMEOUT;
1137 break;
1138 case S_READ: {
1139 struct cdrom_msf msf;
1140 if (!skip) {
1141 status = fetch_status();
1142 if (status < 0)
1143 break;
1144 if (status & ST_DSK_CHG) {
1145 toc_uptodate = 0;
1146 opt_invalidate_buffers();
1147 }
1148 }
1149 skip = 0;
1150 if ((status & ST_DOOR_OPEN) || (status & ST_DRVERR)) {
1151 toc_uptodate = 0;
1152 opt_invalidate_buffers();
1153 printk(KERN_WARNING "optcd: %s\n",
1154 (status & ST_DOOR_OPEN)
1155 ? "door open"
1156 : "disk removed");
1157 state = S_IDLE;
1158 while (current_valid())
1159 end_request(CURRENT, 0);
1160 return;
1161 }
1162 if (!current_valid()) {
1163 state = S_STOP;
1164 loop_again = 1;
1165 break;
1166 }
1167 next_bn = CURRENT -> sector / 4;
1168 lba2msf(next_bn, &msf);
1169 read_count = N_BUFS;
1170 msf.cdmsf_frame1 = read_count; /* Not BCD! */
1171
1172 DEBUG((DEBUG_REQUEST, "reading %x:%x.%x %x:%x.%x",
1173 msf.cdmsf_min0,
1174 msf.cdmsf_sec0,
1175 msf.cdmsf_frame0,
1176 msf.cdmsf_min1,
1177 msf.cdmsf_sec1,
1178 msf.cdmsf_frame1));
1179 DEBUG((DEBUG_REQUEST, "next_bn:%d buf_in:%d"
1180 " buf_out:%d buf_bn:%d",
1181 next_bn,
1182 buf_in,
1183 buf_out,
1184 buf_bn[buf_in]));
1185
1186 exec_read_cmd(COMREAD, &msf);
1187 state = S_DATA;
1188 timeout = READ_TIMEOUT;
1189 break;
1190 }
1191 case S_DATA:
1192 flags = stdt_flags() & (FL_STEN|FL_DTEN);
1193
1194#if DEBUG_STATE
1195 if (flags != flags_old) {
1196 flags_old = flags;
1197 printk(KERN_DEBUG "optcd: flags:%x\n", flags);
1198 }
1199 if (flags == FL_STEN)
1200 printk(KERN_DEBUG "timeout cnt: %d\n", timeout);
1201#endif
1202
1203 switch (flags) {
1204 case FL_DTEN: /* only STEN low */
1205 if (!tries--) {
1206 printk(KERN_ERR
1207 "optcd: read block %d failed; "
1208 "Giving up\n", next_bn);
1209 if (transfer_is_active) {
1210 tries = 0;
1211 break;
1212 }
1213 if (current_valid())
1214 end_request(CURRENT, 0);
1215 tries = 5;
1216 }
1217 state = S_START;
1218 timeout = READ_TIMEOUT;
1219 loop_again = 1;
1220 case (FL_STEN|FL_DTEN): /* both high */
1221 break;
1222 default: /* DTEN low */
1223 tries = 5;
1224 if (!current_valid() && buf_in == buf_out) {
1225 state = S_STOP;
1226 loop_again = 1;
1227 break;
1228 }
1229 if (read_count<=0)
1230 printk(KERN_WARNING
1231 "optcd: warning - try to read"
1232 " 0 frames\n");
1233 while (read_count) {
1234 buf_bn[buf_in] = NOBUF;
1235 if (!flag_low(FL_DTEN, BUSY_TIMEOUT)) {
1236 /* should be no waiting here!?? */
1237 printk(KERN_ERR
1238 "read_count:%d "
1239 "CURRENT->nr_sectors:%ld "
1240 "buf_in:%d\n",
1241 read_count,
1242 CURRENT->nr_sectors,
1243 buf_in);
1244 printk(KERN_ERR
1245 "transfer active: %x\n",
1246 transfer_is_active);
1247 read_count = 0;
1248 state = S_STOP;
1249 loop_again = 1;
1250 end_request(CURRENT, 0);
1251 break;
1252 }
1253 fetch_data(buf+
1254 CD_FRAMESIZE*buf_in,
1255 CD_FRAMESIZE);
1256 read_count--;
1257
1258 DEBUG((DEBUG_REQUEST,
1259 "S_DATA; ---I've read data- "
1260 "read_count: %d",
1261 read_count));
1262 DEBUG((DEBUG_REQUEST,
1263 "next_bn:%d buf_in:%d "
1264 "buf_out:%d buf_bn:%d",
1265 next_bn,
1266 buf_in,
1267 buf_out,
1268 buf_bn[buf_in]));
1269
1270 buf_bn[buf_in] = next_bn++;
1271 if (buf_out == NOBUF)
1272 buf_out = buf_in;
1273 buf_in = buf_in + 1 ==
1274 N_BUFS ? 0 : buf_in + 1;
1275 }
1276 if (!transfer_is_active) {
1277 while (current_valid()) {
1278 transfer();
1279 if (CURRENT -> nr_sectors == 0)
1280 end_request(CURRENT, 1);
1281 else
1282 break;
1283 }
1284 }
1285
1286 if (current_valid()
1287 && (CURRENT -> sector / 4 < next_bn ||
1288 CURRENT -> sector / 4 >
1289 next_bn + N_BUFS)) {
1290 state = S_STOP;
1291 loop_again = 1;
1292 break;
1293 }
1294 timeout = READ_TIMEOUT;
1295 if (read_count == 0) {
1296 state = S_STOP;
1297 loop_again = 1;
1298 break;
1299 }
1300 }
1301 break;
1302 case S_STOP:
1303 if (read_count != 0)
1304 printk(KERN_ERR
1305 "optcd: discard data=%x frames\n",
1306 read_count);
1307 flush_data();
1308 if (send_cmd(COMDRVST)) {
1309 state = S_IDLE;
1310 while (current_valid())
1311 end_request(CURRENT, 0);
1312 return;
1313 }
1314 state = S_STOPPING;
1315 timeout = STOP_TIMEOUT;
1316 break;
1317 case S_STOPPING:
1318 status = fetch_status();
1319 if (status < 0 && timeout)
1320 break;
1321 if ((status >= 0) && (status & ST_DSK_CHG)) {
1322 toc_uptodate = 0;
1323 opt_invalidate_buffers();
1324 }
1325 if (current_valid()) {
1326 if (status >= 0) {
1327 state = S_READ;
1328 loop_again = 1;
1329 skip = 1;
1330 break;
1331 } else {
1332 state = S_START;
1333 timeout = 1;
1334 }
1335 } else {
1336 state = S_IDLE;
1337 return;
1338 }
1339 break;
1340 default:
1341 printk(KERN_ERR "optcd: invalid state %d\n", state);
1342 return;
1343 } /* case */
1344 } /* while */
1345
1346 if (!timeout--) {
1347 printk(KERN_ERR "optcd: timeout in state %d\n", state);
1348 state = S_STOP;
1349 if (exec_cmd(COMSTOP) < 0) {
1350 state = S_IDLE;
1351 while (current_valid())
1352 end_request(CURRENT, 0);
1353 return;
1354 }
1355 }
1356
1357 mod_timer(&req_timer, jiffies + HZ/100);
1358}
1359
1360
1361static void do_optcd_request(request_queue_t * q)
1362{
1363 DEBUG((DEBUG_REQUEST, "do_optcd_request(%ld+%ld)",
1364 CURRENT -> sector, CURRENT -> nr_sectors));
1365
1366 if (disk_info.audio) {
1367 printk(KERN_WARNING "optcd: tried to mount an Audio CD\n");
1368 end_request(CURRENT, 0);
1369 return;
1370 }
1371
1372 transfer_is_active = 1;
1373 while (current_valid()) {
1374 transfer(); /* First try to transfer block from buffers */
1375 if (CURRENT -> nr_sectors == 0) {
1376 end_request(CURRENT, 1);
1377 } else { /* Want to read a block not in buffer */
1378 buf_out = NOBUF;
1379 if (state == S_IDLE) {
1380 /* %% Should this block the request queue?? */
1381 if (update_toc() < 0) {
1382 while (current_valid())
1383 end_request(CURRENT, 0);
1384 break;
1385 }
1386 /* Start state machine */
1387 state = S_START;
1388 timeout = READ_TIMEOUT;
1389 tries = 5;
1390 /* %% why not start right away?? */
1391 mod_timer(&req_timer, jiffies + HZ/100);
1392 }
1393 break;
1394 }
1395 }
1396 transfer_is_active = 0;
1397
1398 DEBUG((DEBUG_REQUEST, "next_bn:%d buf_in:%d buf_out:%d buf_bn:%d",
1399 next_bn, buf_in, buf_out, buf_bn[buf_in]));
1400 DEBUG((DEBUG_REQUEST, "do_optcd_request ends"));
1401}
1402
1403/* IOCTLs */
1404
1405
1406static char auto_eject = 0;
1407
1408static int cdrompause(void)
1409{
1410 int status;
1411
1412 if (audio_status != CDROM_AUDIO_PLAY)
1413 return -EINVAL;
1414
1415 status = exec_cmd(COMPAUSEON);
1416 if (status < 0) {
1417 DEBUG((DEBUG_VFS, "exec_cmd COMPAUSEON: %02x", -status));
1418 return -EIO;
1419 }
1420 audio_status = CDROM_AUDIO_PAUSED;
1421 return 0;
1422}
1423
1424
1425static int cdromresume(void)
1426{
1427 int status;
1428
1429 if (audio_status != CDROM_AUDIO_PAUSED)
1430 return -EINVAL;
1431
1432 status = exec_cmd(COMPAUSEOFF);
1433 if (status < 0) {
1434 DEBUG((DEBUG_VFS, "exec_cmd COMPAUSEOFF: %02x", -status));
1435 audio_status = CDROM_AUDIO_ERROR;
1436 return -EIO;
1437 }
1438 audio_status = CDROM_AUDIO_PLAY;
1439 return 0;
1440}
1441
1442
1443static int cdromplaymsf(void __user *arg)
1444{
1445 int status;
1446 struct cdrom_msf msf;
1447
1448 if (copy_from_user(&msf, arg, sizeof msf))
1449 return -EFAULT;
1450
1451 bin2bcd(&msf);
1452 status = exec_long_cmd(COMPLAY, &msf);
1453 if (status < 0) {
1454 DEBUG((DEBUG_VFS, "exec_long_cmd COMPLAY: %02x", -status));
1455 audio_status = CDROM_AUDIO_ERROR;
1456 return -EIO;
1457 }
1458
1459 audio_status = CDROM_AUDIO_PLAY;
1460 return 0;
1461}
1462
1463
1464static int cdromplaytrkind(void __user *arg)
1465{
1466 int status;
1467 struct cdrom_ti ti;
1468 struct cdrom_msf msf;
1469
1470 if (copy_from_user(&ti, arg, sizeof ti))
1471 return -EFAULT;
1472
1473 if (ti.cdti_trk0 < disk_info.first
1474 || ti.cdti_trk0 > disk_info.last
1475 || ti.cdti_trk1 < ti.cdti_trk0)
1476 return -EINVAL;
1477 if (ti.cdti_trk1 > disk_info.last)
1478 ti.cdti_trk1 = disk_info.last;
1479
1480 msf.cdmsf_min0 = toc[ti.cdti_trk0].cdsc_absaddr.msf.minute;
1481 msf.cdmsf_sec0 = toc[ti.cdti_trk0].cdsc_absaddr.msf.second;
1482 msf.cdmsf_frame0 = toc[ti.cdti_trk0].cdsc_absaddr.msf.frame;
1483 msf.cdmsf_min1 = toc[ti.cdti_trk1 + 1].cdsc_absaddr.msf.minute;
1484 msf.cdmsf_sec1 = toc[ti.cdti_trk1 + 1].cdsc_absaddr.msf.second;
1485 msf.cdmsf_frame1 = toc[ti.cdti_trk1 + 1].cdsc_absaddr.msf.frame;
1486
1487 DEBUG((DEBUG_VFS, "play %02d:%02d.%02d to %02d:%02d.%02d",
1488 msf.cdmsf_min0,
1489 msf.cdmsf_sec0,
1490 msf.cdmsf_frame0,
1491 msf.cdmsf_min1,
1492 msf.cdmsf_sec1,
1493 msf.cdmsf_frame1));
1494
1495 bin2bcd(&msf);
1496 status = exec_long_cmd(COMPLAY, &msf);
1497 if (status < 0) {
1498 DEBUG((DEBUG_VFS, "exec_long_cmd COMPLAY: %02x", -status));
1499 audio_status = CDROM_AUDIO_ERROR;
1500 return -EIO;
1501 }
1502
1503 audio_status = CDROM_AUDIO_PLAY;
1504 return 0;
1505}
1506
1507
1508static int cdromreadtochdr(void __user *arg)
1509{
1510 struct cdrom_tochdr tochdr;
1511
1512 tochdr.cdth_trk0 = disk_info.first;
1513 tochdr.cdth_trk1 = disk_info.last;
1514
1515 return copy_to_user(arg, &tochdr, sizeof tochdr) ? -EFAULT : 0;
1516}
1517
1518
1519static int cdromreadtocentry(void __user *arg)
1520{
1521 struct cdrom_tocentry entry;
1522 struct cdrom_subchnl *tocptr;
1523
1524 if (copy_from_user(&entry, arg, sizeof entry))
1525 return -EFAULT;
1526
1527 if (entry.cdte_track == CDROM_LEADOUT)
1528 tocptr = &toc[disk_info.last + 1];
1529 else if (entry.cdte_track > disk_info.last
1530 || entry.cdte_track < disk_info.first)
1531 return -EINVAL;
1532 else
1533 tocptr = &toc[entry.cdte_track];
1534
1535 entry.cdte_adr = tocptr->cdsc_adr;
1536 entry.cdte_ctrl = tocptr->cdsc_ctrl;
1537 entry.cdte_addr.msf.minute = tocptr->cdsc_absaddr.msf.minute;
1538 entry.cdte_addr.msf.second = tocptr->cdsc_absaddr.msf.second;
1539 entry.cdte_addr.msf.frame = tocptr->cdsc_absaddr.msf.frame;
1540 /* %% What should go into entry.cdte_datamode? */
1541
1542 if (entry.cdte_format == CDROM_LBA)
1543 msf2lba(&entry.cdte_addr);
1544 else if (entry.cdte_format != CDROM_MSF)
1545 return -EINVAL;
1546
1547 return copy_to_user(arg, &entry, sizeof entry) ? -EFAULT : 0;
1548}
1549
1550
1551static int cdromvolctrl(void __user *arg)
1552{
1553 int status;
1554 struct cdrom_volctrl volctrl;
1555 struct cdrom_msf msf;
1556
1557 if (copy_from_user(&volctrl, arg, sizeof volctrl))
1558 return -EFAULT;
1559
1560 msf.cdmsf_min0 = 0x10;
1561 msf.cdmsf_sec0 = 0x32;
1562 msf.cdmsf_frame0 = volctrl.channel0;
1563 msf.cdmsf_min1 = volctrl.channel1;
1564 msf.cdmsf_sec1 = volctrl.channel2;
1565 msf.cdmsf_frame1 = volctrl.channel3;
1566
1567 status = exec_long_cmd(COMCHCTRL, &msf);
1568 if (status < 0) {
1569 DEBUG((DEBUG_VFS, "exec_long_cmd COMCHCTRL: %02x", -status));
1570 return -EIO;
1571 }
1572 return 0;
1573}
1574
1575
1576static int cdromsubchnl(void __user *arg)
1577{
1578 int status;
1579 struct cdrom_subchnl subchnl;
1580
1581 if (copy_from_user(&subchnl, arg, sizeof subchnl))
1582 return -EFAULT;
1583
1584 if (subchnl.cdsc_format != CDROM_LBA
1585 && subchnl.cdsc_format != CDROM_MSF)
1586 return -EINVAL;
1587
1588 status = get_q_channel(&subchnl);
1589 if (status < 0) {
1590 DEBUG((DEBUG_VFS, "get_q_channel: %02x", -status));
1591 return -EIO;
1592 }
1593
1594 if (copy_to_user(arg, &subchnl, sizeof subchnl))
1595 return -EFAULT;
1596 return 0;
1597}
1598
1599
1600static struct gendisk *optcd_disk;
1601
1602
1603static int cdromread(void __user *arg, int blocksize, int cmd)
1604{
1605 int status;
1606 struct cdrom_msf msf;
1607
1608 if (copy_from_user(&msf, arg, sizeof msf))
1609 return -EFAULT;
1610
1611 bin2bcd(&msf);
1612 msf.cdmsf_min1 = 0;
1613 msf.cdmsf_sec1 = 0;
1614 msf.cdmsf_frame1 = 1; /* read only one frame */
1615 status = exec_read_cmd(cmd, &msf);
1616
1617 DEBUG((DEBUG_VFS, "read cmd status 0x%x", status));
1618
1619 if (!sleep_flag_low(FL_DTEN, SLEEP_TIMEOUT))
1620 return -EIO;
1621
1622 fetch_data(optcd_disk->private_data, blocksize);
1623
1624 if (copy_to_user(arg, optcd_disk->private_data, blocksize))
1625 return -EFAULT;
1626
1627 return 0;
1628}
1629
1630
1631static int cdromseek(void __user *arg)
1632{
1633 int status;
1634 struct cdrom_msf msf;
1635
1636 if (copy_from_user(&msf, arg, sizeof msf))
1637 return -EFAULT;
1638
1639 bin2bcd(&msf);
1640 status = exec_seek_cmd(COMSEEK, &msf);
1641
1642 DEBUG((DEBUG_VFS, "COMSEEK status 0x%x", status));
1643
1644 if (status < 0)
1645 return -EIO;
1646 return 0;
1647}
1648
1649
1650#ifdef MULTISESSION
1651static int cdrommultisession(void __user *arg)
1652{
1653 struct cdrom_multisession ms;
1654
1655 if (copy_from_user(&ms, arg, sizeof ms))
1656 return -EFAULT;
1657
1658 ms.addr.msf.minute = disk_info.last_session.minute;
1659 ms.addr.msf.second = disk_info.last_session.second;
1660 ms.addr.msf.frame = disk_info.last_session.frame;
1661
1662 if (ms.addr_format != CDROM_LBA
1663 && ms.addr_format != CDROM_MSF)
1664 return -EINVAL;
1665 if (ms.addr_format == CDROM_LBA)
1666 msf2lba(&ms.addr);
1667
1668 ms.xa_flag = disk_info.xa;
1669
1670 if (copy_to_user(arg, &ms, sizeof(struct cdrom_multisession)))
1671 return -EFAULT;
1672
1673#if DEBUG_MULTIS
1674 if (ms.addr_format == CDROM_MSF)
1675 printk(KERN_DEBUG
1676 "optcd: multisession xa:%d, msf:%02d:%02d.%02d\n",
1677 ms.xa_flag,
1678 ms.addr.msf.minute,
1679 ms.addr.msf.second,
1680 ms.addr.msf.frame);
1681 else
1682 printk(KERN_DEBUG
1683 "optcd: multisession %d, lba:0x%08x [%02d:%02d.%02d])\n",
1684 ms.xa_flag,
1685 ms.addr.lba,
1686 disk_info.last_session.minute,
1687 disk_info.last_session.second,
1688 disk_info.last_session.frame);
1689#endif /* DEBUG_MULTIS */
1690
1691 return 0;
1692}
1693#endif /* MULTISESSION */
1694
1695
1696static int cdromreset(void)
1697{
1698 if (state != S_IDLE) {
1699 error = 1;
1700 tries = 0;
1701 }
1702
1703 toc_uptodate = 0;
1704 disk_changed = 1;
1705 opt_invalidate_buffers();
1706 audio_status = CDROM_AUDIO_NO_STATUS;
1707
1708 if (!reset_drive())
1709 return -EIO;
1710 return 0;
1711}
1712
1713/* VFS calls */
1714
1715
1716static int opt_ioctl(struct inode *ip, struct file *fp,
1717 unsigned int cmd, unsigned long arg)
1718{
1719 int status, err, retval = 0;
1720 void __user *argp = (void __user *)arg;
1721
1722 DEBUG((DEBUG_VFS, "starting opt_ioctl"));
1723
1724 if (!ip)
1725 return -EINVAL;
1726
1727 if (cmd == CDROMRESET)
1728 return cdromreset();
1729
1730 /* is do_optcd_request or another ioctl busy? */
1731 if (state != S_IDLE || in_vfs)
1732 return -EBUSY;
1733
1734 in_vfs = 1;
1735
1736 status = drive_status();
1737 if (status < 0) {
1738 DEBUG((DEBUG_VFS, "drive_status: %02x", -status));
1739 in_vfs = 0;
1740 return -EIO;
1741 }
1742
1743 if (status & ST_DOOR_OPEN)
1744 switch (cmd) { /* Actions that can be taken with door open */
1745 case CDROMCLOSETRAY:
1746 /* We do this before trying to read the toc. */
1747 err = exec_cmd(COMCLOSE);
1748 if (err < 0) {
1749 DEBUG((DEBUG_VFS,
1750 "exec_cmd COMCLOSE: %02x", -err));
1751 in_vfs = 0;
1752 return -EIO;
1753 }
1754 break;
1755 default: in_vfs = 0;
1756 return -EBUSY;
1757 }
1758
1759 err = update_toc();
1760 if (err < 0) {
1761 DEBUG((DEBUG_VFS, "update_toc: %02x", -err));
1762 in_vfs = 0;
1763 return -EIO;
1764 }
1765
1766 DEBUG((DEBUG_VFS, "ioctl cmd 0x%x", cmd));
1767
1768 switch (cmd) {
1769 case CDROMPAUSE: retval = cdrompause(); break;
1770 case CDROMRESUME: retval = cdromresume(); break;
1771 case CDROMPLAYMSF: retval = cdromplaymsf(argp); break;
1772 case CDROMPLAYTRKIND: retval = cdromplaytrkind(argp); break;
1773 case CDROMREADTOCHDR: retval = cdromreadtochdr(argp); break;
1774 case CDROMREADTOCENTRY: retval = cdromreadtocentry(argp); break;
1775
1776 case CDROMSTOP: err = exec_cmd(COMSTOP);
1777 if (err < 0) {
1778 DEBUG((DEBUG_VFS,
1779 "exec_cmd COMSTOP: %02x",
1780 -err));
1781 retval = -EIO;
1782 } else
1783 audio_status = CDROM_AUDIO_NO_STATUS;
1784 break;
1785 case CDROMSTART: break; /* This is a no-op */
1786 case CDROMEJECT: err = exec_cmd(COMUNLOCK);
1787 if (err < 0) {
1788 DEBUG((DEBUG_VFS,
1789 "exec_cmd COMUNLOCK: %02x",
1790 -err));
1791 retval = -EIO;
1792 break;
1793 }
1794 err = exec_cmd(COMOPEN);
1795 if (err < 0) {
1796 DEBUG((DEBUG_VFS,
1797 "exec_cmd COMOPEN: %02x",
1798 -err));
1799 retval = -EIO;
1800 }
1801 break;
1802
1803 case CDROMVOLCTRL: retval = cdromvolctrl(argp); break;
1804 case CDROMSUBCHNL: retval = cdromsubchnl(argp); break;
1805
1806 /* The drive detects the mode and automatically delivers the
1807 correct 2048 bytes, so we don't need these IOCTLs */
1808 case CDROMREADMODE2: retval = -EINVAL; break;
1809 case CDROMREADMODE1: retval = -EINVAL; break;
1810
1811 /* Drive doesn't support reading audio */
1812 case CDROMREADAUDIO: retval = -EINVAL; break;
1813
1814 case CDROMEJECT_SW: auto_eject = (char) arg;
1815 break;
1816
1817#ifdef MULTISESSION
1818 case CDROMMULTISESSION: retval = cdrommultisession(argp); break;
1819#endif
1820
1821 case CDROM_GET_MCN: retval = -EINVAL; break; /* not implemented */
1822 case CDROMVOLREAD: retval = -EINVAL; break; /* not implemented */
1823
1824 case CDROMREADRAW:
1825 /* this drive delivers 2340 bytes in raw mode */
1826 retval = cdromread(argp, CD_FRAMESIZE_RAW1, COMREADRAW);
1827 break;
1828 case CDROMREADCOOKED:
1829 retval = cdromread(argp, CD_FRAMESIZE, COMREAD);
1830 break;
1831 case CDROMREADALL:
1832 retval = cdromread(argp, CD_FRAMESIZE_RAWER, COMREADALL);
1833 break;
1834
1835 case CDROMSEEK: retval = cdromseek(argp); break;
1836 case CDROMPLAYBLK: retval = -EINVAL; break; /* not implemented */
1837 case CDROMCLOSETRAY: break; /* The action was taken earlier */
1838 default: retval = -EINVAL;
1839 }
1840 in_vfs = 0;
1841 return retval;
1842}
1843
1844
1845static int open_count = 0;
1846
1847/* Open device special file; check that a disk is in. */
1848static int opt_open(struct inode *ip, struct file *fp)
1849{
1850 DEBUG((DEBUG_VFS, "starting opt_open"));
1851
1852 if (!open_count && state == S_IDLE) {
1853 int status;
1854 char *buf;
1855
1856 buf = kmalloc(CD_FRAMESIZE_RAWER, GFP_KERNEL);
1857 if (!buf) {
1858 printk(KERN_INFO "optcd: cannot allocate read buffer\n");
1859 return -ENOMEM;
1860 }
1861 optcd_disk->private_data = buf; /* save read buffer */
1862
1863 toc_uptodate = 0;
1864 opt_invalidate_buffers();
1865
1866 status = exec_cmd(COMCLOSE); /* close door */
1867 if (status < 0) {
1868 DEBUG((DEBUG_VFS, "exec_cmd COMCLOSE: %02x", -status));
1869 }
1870
1871 status = drive_status();
1872 if (status < 0) {
1873 DEBUG((DEBUG_VFS, "drive_status: %02x", -status));
1874 goto err_out;
1875 }
1876 DEBUG((DEBUG_VFS, "status: %02x", status));
1877 if ((status & ST_DOOR_OPEN) || (status & ST_DRVERR)) {
1878 printk(KERN_INFO "optcd: no disk or door open\n");
1879 goto err_out;
1880 }
1881 status = exec_cmd(COMLOCK); /* Lock door */
1882 if (status < 0) {
1883 DEBUG((DEBUG_VFS, "exec_cmd COMLOCK: %02x", -status));
1884 }
1885 status = update_toc(); /* Read table of contents */
1886 if (status < 0) {
1887 DEBUG((DEBUG_VFS, "update_toc: %02x", -status));
1888 status = exec_cmd(COMUNLOCK); /* Unlock door */
1889 if (status < 0) {
1890 DEBUG((DEBUG_VFS,
1891 "exec_cmd COMUNLOCK: %02x", -status));
1892 }
1893 goto err_out;
1894 }
1895 open_count++;
1896 }
1897
1898 DEBUG((DEBUG_VFS, "exiting opt_open"));
1899
1900 return 0;
1901
1902err_out:
1903 return -EIO;
1904}
1905
1906
1907/* Release device special file; flush all blocks from the buffer cache */
1908static int opt_release(struct inode *ip, struct file *fp)
1909{
1910 int status;
1911
1912 DEBUG((DEBUG_VFS, "executing opt_release"));
1913 DEBUG((DEBUG_VFS, "inode: %p, device: %s, file: %p\n",
1914 ip, ip->i_bdev->bd_disk->disk_name, fp));
1915
1916 if (!--open_count) {
1917 toc_uptodate = 0;
1918 opt_invalidate_buffers();
1919 status = exec_cmd(COMUNLOCK); /* Unlock door */
1920 if (status < 0) {
1921 DEBUG((DEBUG_VFS, "exec_cmd COMUNLOCK: %02x", -status));
1922 }
1923 if (auto_eject) {
1924 status = exec_cmd(COMOPEN);
1925 DEBUG((DEBUG_VFS, "exec_cmd COMOPEN: %02x", -status));
1926 }
1927 kfree(optcd_disk->private_data);
1928 del_timer(&delay_timer);
1929 del_timer(&req_timer);
1930 }
1931 return 0;
1932}
1933
1934
1935/* Check if disk has been changed */
1936static int opt_media_change(struct gendisk *disk)
1937{
1938 DEBUG((DEBUG_VFS, "executing opt_media_change"));
1939 DEBUG((DEBUG_VFS, "dev: %s; disk_changed = %d\n",
1940 disk->disk_name, disk_changed));
1941
1942 if (disk_changed) {
1943 disk_changed = 0;
1944 return 1;
1945 }
1946 return 0;
1947}
1948
1949/* Driver initialisation */
1950
1951
1952/* Returns 1 if a drive is detected with a version string
1953 starting with "DOLPHIN". Otherwise 0. */
1954static int __init version_ok(void)
1955{
1956 char devname[100];
1957 int count, i, ch, status;
1958
1959 status = exec_cmd(COMVERSION);
1960 if (status < 0) {
1961 DEBUG((DEBUG_VFS, "exec_cmd COMVERSION: %02x", -status));
1962 return 0;
1963 }
1964 if ((count = get_data(1)) < 0) {
1965 DEBUG((DEBUG_VFS, "get_data(1): %02x", -count));
1966 return 0;
1967 }
1968 for (i = 0, ch = -1; count > 0; count--) {
1969 if ((ch = get_data(1)) < 0) {
1970 DEBUG((DEBUG_VFS, "get_data(1): %02x", -ch));
1971 break;
1972 }
1973 if (i < 99)
1974 devname[i++] = ch;
1975 }
1976 devname[i] = '\0';
1977 if (ch < 0)
1978 return 0;
1979
1980 printk(KERN_INFO "optcd: Device %s detected\n", devname);
1981 return ((devname[0] == 'D')
1982 && (devname[1] == 'O')
1983 && (devname[2] == 'L')
1984 && (devname[3] == 'P')
1985 && (devname[4] == 'H')
1986 && (devname[5] == 'I')
1987 && (devname[6] == 'N'));
1988}
1989
1990
1991static struct block_device_operations opt_fops = {
1992 .owner = THIS_MODULE,
1993 .open = opt_open,
1994 .release = opt_release,
1995 .ioctl = opt_ioctl,
1996 .media_changed = opt_media_change,
1997};
1998
1999#ifndef MODULE
2000/* Get kernel parameter when used as a kernel driver */
2001static int optcd_setup(char *str)
2002{
2003 int ints[4];
2004 (void)get_options(str, ARRAY_SIZE(ints), ints);
2005
2006 if (ints[0] > 0)
2007 optcd_port = ints[1];
2008
2009 return 1;
2010}
2011
2012__setup("optcd=", optcd_setup);
2013
2014#endif /* MODULE */
2015
2016/* Test for presence of drive and initialize it. Called at boot time
2017 or during module initialisation. */
2018static int __init optcd_init(void)
2019{
2020 int status;
2021
2022 if (optcd_port <= 0) {
2023 printk(KERN_INFO
2024 "optcd: no Optics Storage CDROM Initialization\n");
2025 return -EIO;
2026 }
2027 optcd_disk = alloc_disk(1);
2028 if (!optcd_disk) {
2029 printk(KERN_ERR "optcd: can't allocate disk\n");
2030 return -ENOMEM;
2031 }
2032 optcd_disk->major = MAJOR_NR;
2033 optcd_disk->first_minor = 0;
2034 optcd_disk->fops = &opt_fops;
2035 sprintf(optcd_disk->disk_name, "optcd");
2036
2037 if (!request_region(optcd_port, 4, "optcd")) {
2038 printk(KERN_ERR "optcd: conflict, I/O port 0x%x already used\n",
2039 optcd_port);
2040 put_disk(optcd_disk);
2041 return -EIO;
2042 }
2043
2044 if (!reset_drive()) {
2045 printk(KERN_ERR "optcd: drive at 0x%x not ready\n", optcd_port);
2046 release_region(optcd_port, 4);
2047 put_disk(optcd_disk);
2048 return -EIO;
2049 }
2050 if (!version_ok()) {
2051 printk(KERN_ERR "optcd: unknown drive detected; aborting\n");
2052 release_region(optcd_port, 4);
2053 put_disk(optcd_disk);
2054 return -EIO;
2055 }
2056 status = exec_cmd(COMINITDOUBLE);
2057 if (status < 0) {
2058 printk(KERN_ERR "optcd: cannot init double speed mode\n");
2059 release_region(optcd_port, 4);
2060 DEBUG((DEBUG_VFS, "exec_cmd COMINITDOUBLE: %02x", -status));
2061 put_disk(optcd_disk);
2062 return -EIO;
2063 }
2064 if (register_blkdev(MAJOR_NR, "optcd")) {
2065 release_region(optcd_port, 4);
2066 put_disk(optcd_disk);
2067 return -EIO;
2068 }
2069
2070
2071 opt_queue = blk_init_queue(do_optcd_request, &optcd_lock);
2072 if (!opt_queue) {
2073 unregister_blkdev(MAJOR_NR, "optcd");
2074 release_region(optcd_port, 4);
2075 put_disk(optcd_disk);
2076 return -ENOMEM;
2077 }
2078
2079 blk_queue_hardsect_size(opt_queue, 2048);
2080 optcd_disk->queue = opt_queue;
2081 add_disk(optcd_disk);
2082
2083 printk(KERN_INFO "optcd: DOLPHIN 8000 AT CDROM at 0x%x\n", optcd_port);
2084 return 0;
2085}
2086
2087
2088static void __exit optcd_exit(void)
2089{
2090 del_gendisk(optcd_disk);
2091 put_disk(optcd_disk);
2092 if (unregister_blkdev(MAJOR_NR, "optcd") == -EINVAL) {
2093 printk(KERN_ERR "optcd: what's that: can't unregister\n");
2094 return;
2095 }
2096 blk_cleanup_queue(opt_queue);
2097 release_region(optcd_port, 4);
2098 printk(KERN_INFO "optcd: module released.\n");
2099}
2100
2101module_init(optcd_init);
2102module_exit(optcd_exit);
2103
2104MODULE_LICENSE("GPL");
2105MODULE_ALIAS_BLOCKDEV_MAJOR(OPTICS_CDROM_MAJOR);
diff --git a/drivers/cdrom/optcd.h b/drivers/cdrom/optcd.h
deleted file mode 100644
index 1911bb92ee28..000000000000
--- a/drivers/cdrom/optcd.h
+++ /dev/null
@@ -1,52 +0,0 @@
1/* linux/include/linux/optcd.h - Optics Storage 8000 AT CDROM driver
2 $Id: optcd.h,v 1.2 1996/01/15 18:43:44 root Exp root $
3
4 Copyright (C) 1995 Leo Spiekman (spiekman@dutette.et.tudelft.nl)
5
6
7 Configuration file for linux/drivers/cdrom/optcd.c
8*/
9
10#ifndef _LINUX_OPTCD_H
11#define _LINUX_OPTCD_H
12
13
14/* I/O base of drive. Drive uses base to base+2.
15 This setting can be overridden with the kernel or insmod command
16 line option 'optcd=<portbase>'. Use address of 0 to disable driver. */
17#define OPTCD_PORTBASE 0x340
18
19
20/* enable / disable parts of driver by define / undef */
21#define MULTISESSION /* multisession support (ALPHA) */
22
23
24/* Change 0 to 1 to debug various parts of the driver */
25#define DEBUG_DRIVE_IF 0 /* Low level drive interface */
26#define DEBUG_CONV 0 /* Address conversions */
27#define DEBUG_BUFFERS 0 /* Buffering and block size conversion */
28#define DEBUG_REQUEST 0 /* Request mechanism */
29#define DEBUG_STATE 0 /* State machine */
30#define DEBUG_TOC 0 /* Q-channel and Table of Contents */
31#define DEBUG_MULTIS 0 /* Multisession code */
32#define DEBUG_VFS 0 /* VFS interface */
33
34
35/* Don't touch these unless you know what you're doing. */
36
37/* Various timeout loop repetition counts. */
38#define BUSY_TIMEOUT 10000000 /* for busy wait */
39#define FAST_TIMEOUT 100000 /* ibid. for probing */
40#define SLEEP_TIMEOUT 6000 /* for timer wait */
41#define MULTI_SEEK_TIMEOUT 1000 /* for timer wait */
42#define READ_TIMEOUT 6000 /* for poll wait */
43#define STOP_TIMEOUT 2000 /* for poll wait */
44#define RESET_WAIT 5000 /* busy wait at drive reset */
45
46/* # of buffers for block size conversion. 6 is optimal for my setup (P75),
47 giving 280 kb/s, with 0.4% CPU usage. Experiment to find your optimal
48 setting */
49#define N_BUFS 6
50
51
52#endif /* _LINUX_OPTCD_H */
diff --git a/drivers/cdrom/sbpcd.c b/drivers/cdrom/sbpcd.c
deleted file mode 100644
index a1283b1ef989..000000000000
--- a/drivers/cdrom/sbpcd.c
+++ /dev/null
@@ -1,5966 +0,0 @@
1/*
2 * sbpcd.c CD-ROM device driver for the whole family of traditional,
3 * non-ATAPI IDE-style Matsushita/Panasonic CR-5xx drives.
4 * Works with SoundBlaster compatible cards and with "no-sound"
5 * interface cards like Lasermate, Panasonic CI-101P, Teac, ...
6 * Also for the Longshine LCS-7260 drive.
7 * Also for the IBM "External ISA CD-Rom" drive.
8 * Also for the CreativeLabs CD200 drive.
9 * Also for the TEAC CD-55A drive.
10 * Also for the ECS-AT "Vertos 100" drive.
11 * Not for Sanyo drives (but for the H94A, sjcd is there...).
12 * Not for any other Funai drives than the CD200 types (sometimes
13 * labelled E2550UA or MK4015 or 2800F).
14 */
15
16#define VERSION "v4.63 Andrew J. Kroll <ag784@freenet.buffalo.edu> Wed Jul 26 04:24:10 EDT 2000"
17
18/* Copyright (C) 1993, 1994, 1995 Eberhard Moenkeberg <emoenke@gwdg.de>
19 *
20 * This program is free software; you can redistribute it and/or modify
21 * it under the terms of the GNU General Public License as published by
22 * the Free Software Foundation; either version 2, or (at your option)
23 * any later version.
24 *
25 * You should have received a copy of the GNU General Public License
26 * (for example /usr/src/linux/COPYING); if not, write to the Free
27 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 *
29 * If you change this software, you should mail a .diff file with some
30 * description lines to emoenke@gwdg.de. I want to know about it.
31 *
32 * If you are the editor of a Linux CD, you should enable sbpcd.c within
33 * your boot floppy kernel and send me one of your CDs for free.
34 *
35 * If you would like to port the driver to an other operating system (f.e.
36 * FreeBSD or NetBSD) or use it as an information source, you shall not be
37 * restricted by the GPL under the following conditions:
38 * a) the source code of your work is freely available
39 * b) my part of the work gets mentioned at all places where your
40 * authorship gets mentioned
41 * c) I receive a copy of your code together with a full installation
42 * package of your operating system for free.
43 *
44 *
45 * VERSION HISTORY
46 *
47 * 0.1 initial release, April/May 93, after mcd.c (Martin Harriss)
48 *
49 * 0.2 thek "repeat:"-loop in do_sbpcd_request did not check for
50 * end-of-request_queue (resulting in kernel panic).
51 * Flow control seems stable, but throughput is not better.
52 *
53 * 0.3 interrupt locking totally eliminated (maybe "inb" and "outb"
54 * are still locking) - 0.2 made keyboard-type-ahead losses.
55 * check_sbpcd_media_change added (to use by isofs/inode.c)
56 * - but it detects almost nothing.
57 *
58 * 0.4 use MAJOR 25 definitely.
59 * Almost total re-design to support double-speed drives and
60 * "naked" (no sound) interface cards ("LaserMate" interface type).
61 * Flow control should be exact now.
62 * Don't occupy the SbPro IRQ line (not needed either); will
63 * live together with Hannu Savolainen's sndkit now.
64 * Speeded up data transfer to 150 kB/sec, with help from Kai
65 * Makisara, the "provider" of the "mt" tape utility.
66 * Give "SpinUp" command if necessary.
67 * First steps to support up to 4 drives (but currently only one).
68 * Implemented audio capabilities - workman should work, xcdplayer
69 * gives some problems.
70 * This version is still consuming too much CPU time, and
71 * sleeping still has to be worked on.
72 * During "long" implied seeks, it seems possible that a
73 * ReadStatus command gets ignored. That gives the message
74 * "ResponseStatus timed out" (happens about 6 times here during
75 * a "ls -alR" of the YGGDRASIL LGX-Beta CD). Such a case is
76 * handled without data error, but it should get done better.
77 *
78 * 0.5 Free CPU during waits (again with help from Kai Makisara).
79 * Made it work together with the LILO/kernel setup standard.
80 * Included auto-probing code, as suggested by YGGDRASIL.
81 * Formal redesign to add DDI debugging.
82 * There are still flaws in IOCTL (workman with double speed drive).
83 *
84 * 1.0 Added support for all drive IDs (0...3, no longer only 0)
85 * and up to 4 drives on one controller.
86 * Added "#define MANY_SESSION" for "old" multi session CDs.
87 *
88 * 1.1 Do SpinUp for new drives, too.
89 * Revised for clean compile under "old" kernels (0.99pl9).
90 *
91 * 1.2 Found the "workman with double-speed drive" bug: use the driver's
92 * audio_state, not what the drive is reporting with ReadSubQ.
93 *
94 * 1.3 Minor cleanups.
95 * Refinements regarding Workman.
96 *
97 * 1.4 Read XA disks (PhotoCDs) with "old" drives, too (but only the first
98 * session - no chance to fully access a "multi-session" CD).
99 * This currently still is too slow (50 kB/sec) - but possibly
100 * the old drives won't do it faster.
101 * Implemented "door (un)lock" for new drives (still does not work
102 * as wanted - no lock possible after an unlock).
103 * Added some debugging printout for the UPC/EAN code - but my drives
104 * return only zeroes. Is there no UPC/EAN code written?
105 *
106 * 1.5 Laborate with UPC/EAN code (not better yet).
107 * Adapt to kernel 1.1.8 change (have to explicitly include
108 * <linux/string.h> now).
109 *
110 * 1.6 Trying to read audio frames as data. Impossible with the current
111 * drive firmware levels, as it seems. Awaiting any hint. ;-)
112 * Changed "door unlock": repeat it until success.
113 * Changed CDROMSTOP routine (stop somewhat "softer" so that Workman
114 * won't get confused).
115 * Added a third interface type: Sequoia S-1000, as used with the SPEA
116 * Media FX sound card. This interface (usable for Sony and Mitsumi
117 * drives, too) needs a special configuration setup and behaves like a
118 * LaserMate type after that. Still experimental - I do not have such
119 * an interface.
120 * Use the "variable BLOCK_SIZE" feature (2048). But it does only work
121 * if you give the mount option "block=2048".
122 * The media_check routine is currently disabled; now that it gets
123 * called as it should I fear it must get synchronized for not to
124 * disturb the normal driver's activity.
125 *
126 * 2.0 Version number bumped - two reasons:
127 * - reading audio tracks as data works now with CR-562 and CR-563. We
128 * currently do it by an IOCTL (yet has to get standardized), one frame
129 * at a time; that is pretty slow. But it works.
130 * - we are maintaining now up to 4 interfaces (each up to 4 drives):
131 * did it the easy way - a different MAJOR (25, 26, ...) and a different
132 * copy of the driver (sbpcd.c, sbpcd2.c, sbpcd3.c, sbpcd4.c - only
133 * distinguished by the value of SBPCD_ISSUE and the driver's name),
134 * and a common sbpcd.h file.
135 * Bettered the "ReadCapacity error" problem with old CR-52x drives (the
136 * drives sometimes need a manual "eject/insert" before work): just
137 * reset the drive and do again. Needs lots of resets here and sometimes
138 * that does not cure, so this can't be the solution.
139 *
140 * 2.1 Found bug with multisession CDs (accessing frame 16).
141 * "read audio" works now with address type CDROM_MSF, too.
142 * Bigger audio frame buffer: allows reading max. 4 frames at time; this
143 * gives a significant speedup, but reading more than one frame at once
144 * gives missing chunks at each single frame boundary.
145 *
146 * 2.2 Kernel interface cleanups: timers, init, setup, media check.
147 *
148 * 2.3 Let "door lock" and "eject" live together.
149 * Implemented "close tray" (done automatically during open).
150 *
151 * 2.4 Use different names for device registering.
152 *
153 * 2.5 Added "#if EJECT" code (default: enabled) to automatically eject
154 * the tray during last call to "sbpcd_release".
155 * Added "#if JUKEBOX" code (default: disabled) to automatically eject
156 * the tray during call to "sbpcd_open" if no disk is in.
157 * Turn on the CD volume of "compatible" sound cards, too; just define
158 * SOUND_BASE (in sbpcd.h) accordingly (default: disabled).
159 *
160 * 2.6 Nothing new.
161 *
162 * 2.7 Added CDROMEJECT_SW ioctl to set the "EJECT" behavior on the fly:
163 * 0 disables, 1 enables auto-ejecting. Useful to keep the tray in
164 * during shutdown.
165 *
166 * 2.8 Added first support (still BETA, I need feedback or a drive) for
167 * the Longshine LCS-7260 drives. They appear as double-speed drives
168 * using the "old" command scheme, extended by tray control and door
169 * lock functions.
170 * Found (and fixed preliminary) a flaw with some multisession CDs: we
171 * have to re-direct not only the accesses to frame 16 (the isofs
172 * routines drive it up to max. 100), but also those to the continuation
173 * (repetition) frames (as far as they exist - currently set fix as
174 * 16..20).
175 * Changed default of the "JUKEBOX" define. If you use this default,
176 * your tray will eject if you try to mount without a disk in. Next
177 * mount command will insert the tray - so, just fill in a disk. ;-)
178 *
179 * 2.9 Fulfilled the Longshine LCS-7260 support; with great help and
180 * experiments by Serge Robyns.
181 * First attempts to support the TEAC CD-55A drives; but still not
182 * usable yet.
183 * Implemented the CDROMMULTISESSION ioctl; this is an attempt to handle
184 * multi session CDs more "transparent" (redirection handling has to be
185 * done within the isofs routines, and only for the special purpose of
186 * obtaining the "right" volume descriptor; accesses to the raw device
187 * should not get redirected).
188 *
189 * 3.0 Just a "normal" increment, with some provisions to do it better. ;-)
190 * Introduced "#define READ_AUDIO" to specify the maximum number of
191 * audio frames to grab with one request. This defines a buffer size
192 * within kernel space; a value of 0 will reserve no such space and
193 * disable the CDROMREADAUDIO ioctl. A value of 75 enables the reading
194 * of a whole second with one command, but will use a buffer of more
195 * than 172 kB.
196 * Started CD200 support. Drive detection should work, but nothing
197 * more.
198 *
199 * 3.1 Working to support the CD200 and the Teac CD-55A drives.
200 * AT-BUS style device numbering no longer used: use SCSI style now.
201 * So, the first "found" device has MINOR 0, regardless of the
202 * jumpered drive ID. This implies modifications to the /dev/sbpcd*
203 * entries for some people, but will help the DAU (german TLA, english:
204 * "newbie", maybe ;-) to install his "first" system from a CD.
205 *
206 * 3.2 Still testing with CD200 and CD-55A drives.
207 *
208 * 3.3 Working with CD200 support.
209 *
210 * 3.4 Auto-probing stops if an address of 0 is seen (to be entered with
211 * the kernel command line).
212 * Made the driver "loadable". If used as a module, "audio copy" is
213 * disabled, and the internal read ahead data buffer has a reduced size
214 * of 4 kB; so, throughput may be reduced a little bit with slow CPUs.
215 *
216 * 3.5 Provisions to handle weird photoCDs which have an interrupted
217 * "formatting" immediately after the last frames of some files: simply
218 * never "read ahead" with MultiSession CDs. By this, CPU usage may be
219 * increased with those CDs, and there may be a loss in speed.
220 * Re-structured the messaging system.
221 * The "loadable" version no longer has a limited READ_AUDIO buffer
222 * size.
223 * Removed "MANY_SESSION" handling for "old" multi session CDs.
224 * Added "private" IOCTLs CDROMRESET and CDROMVOLREAD.
225 * Started again to support the TEAC CD-55A drives, now that I found
226 * the money for "my own" drive. ;-)
227 * The TEAC CD-55A support is fairly working now.
228 * I have measured that the drive "delivers" at 600 kB/sec (even with
229 * bigger requests than the drive's 64 kB buffer can satisfy), but
230 * the "real" rate does not exceed 520 kB/sec at the moment.
231 * Caused by the various changes to build in TEAC support, the timed
232 * loops are de-optimized at the moment (less throughput with CR-52x
233 * drives, and the TEAC will give speed only with SBP_BUFFER_FRAMES 64).
234 *
235 * 3.6 Fixed TEAC data read problems with SbPro interfaces.
236 * Initial size of the READ_AUDIO buffer is 0. Can get set to any size
237 * during runtime.
238 *
239 * 3.7 Introduced MAX_DRIVES for some poor interface cards (seen with TEAC
240 * drives) which allow only one drive (ID 0); this avoids repetitive
241 * detection under IDs 1..3.
242 * Elongated cmd_out_T response waiting; necessary for photo CDs with
243 * a lot of sessions.
244 * Bettered the sbpcd_open() behavior with TEAC drives.
245 *
246 * 3.8 Elongated max_latency for CR-56x drives.
247 *
248 * 3.9 Finally fixed the long-known SoundScape/SPEA/Sequoia S-1000 interface
249 * configuration bug.
250 * Now Corey, Heiko, Ken, Leo, Vadim/Eric & Werner are invited to copy
251 * the config_spea() routine into their drivers. ;-)
252 *
253 * 4.0 No "big step" - normal version increment.
254 * Adapted the benefits from 1.3.33.
255 * Fiddled with CDROMREADAUDIO flaws.
256 * Avoid ReadCapacity command with CD200 drives (the MKE 1.01 version
257 * seems not to support it).
258 * Fulfilled "read audio" for CD200 drives, with help of Pete Heist
259 * (heistp@rpi.edu).
260 *
261 * 4.1 Use loglevel KERN_INFO with printk().
262 * Added support for "Vertos 100" drive ("ECS-AT") - it is very similar
263 * to the Longshine LCS-7260. Give feedback if you can - I never saw
264 * such a drive, and I have no specs.
265 *
266 * 4.2 Support for Teac 16-bit interface cards. Can't get auto-detected,
267 * so you have to jumper your card to 0x2C0. Still not 100% - come
268 * in contact if you can give qualified feedback.
269 * Use loglevel KERN_NOTICE with printk(). If you get annoyed by a
270 * flood of unwanted messages and the accompanied delay, try to read
271 * my documentation. Especially the Linux CDROM drivers have to do an
272 * important job for the newcomers, so the "distributed" version has
273 * to fit some special needs. Since generations, the flood of messages
274 * is user-configurable (even at runtime), but to get aware of this, one
275 * needs a special mental quality: the ability to read.
276 *
277 * 4.3 CD200F does not like to receive a command while the drive is
278 * reading the ToC; still trying to solve it.
279 * Removed some redundant verify_area calls (yes, Heiko Eissfeldt
280 * is visiting all the Linux CDROM drivers ;-).
281 *
282 * 4.4 Adapted one idea from tiensivu@pilot.msu.edu's "stripping-down"
283 * experiments: "KLOGD_PAUSE".
284 * Inhibited "play audio" attempts with data CDs. Provisions for a
285 * "data-safe" handling of "mixed" (data plus audio) Cds.
286 *
287 * 4.5 Meanwhile Gonzalo Tornaria <tornaria@cmat.edu.uy> (GTL) built a
288 * special end_request routine: we seem to have to take care for not
289 * to have two processes working at the request list. My understanding
290 * was and is that ll_rw_blk should not call do_sbpcd_request as long
291 * as there is still one call active (the first call will care for all
292 * outstanding I/Os, and if a second call happens, that is a bug in
293 * ll_rw_blk.c).
294 * "Check media change" without touching any drive.
295 *
296 * 4.6 Use a semaphore to synchronize multi-activity; elaborated by Rob
297 * Riggs <rriggs@tesser.com>. At the moment, we simply block "read"
298 * against "ioctl" and vice versa. This could be refined further, but
299 * I guess with almost no performance increase.
300 * Experiments to speed up the CD-55A; again with help of Rob Riggs
301 * (to be true, he gave both, idea & code. ;-)
302 *
303 * 4.61 Ported to Uniform CD-ROM driver by
304 * Heiko Eissfeldt <heiko@colossus.escape.de> with additional
305 * changes by Erik Andersen <andersee@debian.org>
306 *
307 * 4.62 Fix a bug where playing audio left the drive in an unusable state.
308 * Heiko Eissfeldt <heiko@colossus.escape.de>
309 *
310 * November 1999 -- Make kernel-parameter implementation work with 2.3.x
311 * Removed init_module & cleanup_module in favor of
312 * module_init & module_exit.
313 * Torben Mathiasen <tmm@image.dk>
314 *
315 * 4.63 Bug fixes for audio annoyances, new legacy CDROM maintainer.
316 * Annoying things fixed:
317 * TOC reread on automated disk changes
318 * TOC reread on manual cd changes
319 * Play IOCTL tries to play CD before it's actually ready... sometimes.
320 * CD_AUDIO_COMPLETED state so workman (and other playes) can repeat play.
321 * Andrew J. Kroll <ag784@freenet.buffalo.edu> Wed Jul 26 04:24:10 EDT 2000
322 *
323 * 4.64 Fix module parameters - were being completely ignored.
324 * Can also specify max_drives=N as a setup int to get rid of
325 * "ghost" drives on crap hardware (aren't they all?) Paul Gortmaker
326 *
327 * TODO
328 * implement "read all subchannel data" (96 bytes per frame)
329 * remove alot of the virtual status bits and deal with hardware status
330 * move the change of cd for audio to a better place
331 * add debug levels to insmod parameters (trivial)
332 *
333 * special thanks to Kai Makisara (kai.makisara@vtt.fi) for his fine
334 * elaborated speed-up experiments (and the fabulous results!), for
335 * the "push" towards load-free wait loops, and for the extensive mail
336 * thread which brought additional hints and bug fixes.
337 *
338 */
339
340/*
341 * Trying to merge requests breaks this driver horribly (as in it goes
342 * boom and apparently has done so since 2.3.41). As it is a legacy
343 * driver for a horribly slow double speed CD on a hideous interface
344 * designed for polled operation, I won't lose any sleep in simply
345 * disallowing merging. Paul G. 02/2001
346 *
347 * Thu May 30 14:14:47 CEST 2002:
348 *
349 * I have presumably found the reson for the above - there was a bogous
350 * end_request substitute, which was manipulating the request queues
351 * incorrectly. If someone has access to the actual hardware, and it's
352 * still operations - well please free to test it.
353 *
354 * Marcin Dalecki
355 */
356
357/*
358 * Add bio/kdev_t changes for 2.5.x required to make it work again.
359 * Still room for improvement in the request handling here if anyone
360 * actually cares. Bring your own chainsaw. Paul G. 02/2002
361 */
362
363
364#include <linux/module.h>
365
366#include <linux/errno.h>
367#include <linux/sched.h>
368#include <linux/mm.h>
369#include <linux/timer.h>
370#include <linux/fs.h>
371#include <linux/kernel.h>
372#include <linux/cdrom.h>
373#include <linux/ioport.h>
374#include <linux/major.h>
375#include <linux/string.h>
376#include <linux/vmalloc.h>
377#include <linux/init.h>
378#include <linux/interrupt.h>
379
380#include <asm/system.h>
381#include <asm/io.h>
382#include <asm/uaccess.h>
383#include <stdarg.h>
384#include "sbpcd.h"
385
386#define MAJOR_NR MATSUSHITA_CDROM_MAJOR
387#include <linux/blkdev.h>
388
389/*==========================================================================*/
390#if SBPCD_DIS_IRQ
391# define SBPCD_CLI cli()
392# define SBPCD_STI sti()
393#else
394# define SBPCD_CLI
395# define SBPCD_STI
396#endif
397
398/*==========================================================================*/
399/*
400 * auto-probing address list
401 * inspired by Adam J. Richter from Yggdrasil
402 *
403 * still not good enough - can cause a hang.
404 * example: a NE 2000 ethernet card at 300 will cause a hang probing 310.
405 * if that happens, reboot and use the LILO (kernel) command line.
406 * The possibly conflicting ethernet card addresses get NOT probed
407 * by default - to minimize the hang possibilities.
408 *
409 * The SB Pro addresses get "mirrored" at 0x6xx and some more locations - to
410 * avoid a type error, the 0x2xx-addresses must get checked before 0x6xx.
411 *
412 * send mail to emoenke@gwdg.de if your interface card is not FULLY
413 * represented here.
414 */
415static int sbpcd[] =
416{
417 CDROM_PORT, SBPRO, /* probe with user's setup first */
418#if DISTRIBUTION
419 0x230, 1, /* Soundblaster Pro and 16 (default) */
420#if 0
421 0x300, 0, /* CI-101P (default), WDH-7001C (default),
422 Galaxy (default), Reveal (one default) */
423 0x250, 1, /* OmniCD default, Soundblaster Pro and 16 */
424 0x2C0, 3, /* Teac 16-bit cards */
425 0x260, 1, /* OmniCD */
426 0x320, 0, /* Lasermate, CI-101P, WDH-7001C, Galaxy, Reveal (other default),
427 Longshine LCS-6853 (default) */
428 0x338, 0, /* Reveal Sound Wave 32 card model #SC600 */
429 0x340, 0, /* Mozart sound card (default), Lasermate, CI-101P */
430 0x360, 0, /* Lasermate, CI-101P */
431 0x270, 1, /* Soundblaster 16 */
432 0x670, 0, /* "sound card #9" */
433 0x690, 0, /* "sound card #9" */
434 0x338, 2, /* SPEA Media FX, Ensonic SoundScape (default) */
435 0x328, 2, /* SPEA Media FX */
436 0x348, 2, /* SPEA Media FX */
437 0x634, 0, /* some newer sound cards */
438 0x638, 0, /* some newer sound cards */
439 0x230, 1, /* some newer sound cards */
440 /* due to incomplete address decoding of the SbPro card, these must be last */
441 0x630, 0, /* "sound card #9" (default) */
442 0x650, 0, /* "sound card #9" */
443#ifdef MODULE
444 /*
445 * some "hazardous" locations (no harm with the loadable version)
446 * (will stop the bus if a NE2000 ethernet card resides at offset -0x10)
447 */
448 0x330, 0, /* Lasermate, CI-101P, WDH-7001C */
449 0x350, 0, /* Lasermate, CI-101P */
450 0x358, 2, /* SPEA Media FX */
451 0x370, 0, /* Lasermate, CI-101P */
452 0x290, 1, /* Soundblaster 16 */
453 0x310, 0, /* Lasermate, CI-101P, WDH-7001C */
454#endif /* MODULE */
455#endif
456#endif /* DISTRIBUTION */
457};
458
459/*
460 * Protects access to global structures etc.
461 */
462static __cacheline_aligned DEFINE_SPINLOCK(sbpcd_lock);
463static struct request_queue *sbpcd_queue;
464
465/* You can only set the first pair, from old MODULE_PARM code. */
466static int sbpcd_set(const char *val, struct kernel_param *kp)
467{
468 get_options((char *)val, 2, (int *)sbpcd);
469 return 0;
470}
471module_param_call(sbpcd, sbpcd_set, NULL, NULL, 0);
472
473#define NUM_PROBE (sizeof(sbpcd) / sizeof(int))
474
475/*==========================================================================*/
476
477#define INLINE inline
478
479/*==========================================================================*/
480/*
481 * the forward references:
482 */
483static void sbp_sleep(u_int);
484static void mark_timeout_delay(u_long);
485static void mark_timeout_data(u_long);
486#if 0
487static void mark_timeout_audio(u_long);
488#endif
489static void sbp_read_cmd(struct request *req);
490static int sbp_data(struct request *req);
491static int cmd_out(void);
492static int DiskInfo(void);
493
494/*==========================================================================*/
495
496/*
497 * pattern for printk selection:
498 *
499 * (1<<DBG_INF) necessary information
500 * (1<<DBG_BSZ) BLOCK_SIZE trace
501 * (1<<DBG_REA) "read" status trace
502 * (1<<DBG_CHK) "media check" trace
503 * (1<<DBG_TIM) datarate timer test
504 * (1<<DBG_INI) initialization trace
505 * (1<<DBG_TOC) tell TocEntry values
506 * (1<<DBG_IOC) ioctl trace
507 * (1<<DBG_STA) "ResponseStatus" trace
508 * (1<<DBG_ERR) "cc_ReadError" trace
509 * (1<<DBG_CMD) "cmd_out" trace
510 * (1<<DBG_WRN) give explanation before auto-probing
511 * (1<<DBG_MUL) multi session code test
512 * (1<<DBG_IDX) "drive_id != 0" test code
513 * (1<<DBG_IOX) some special information
514 * (1<<DBG_DID) drive ID test
515 * (1<<DBG_RES) drive reset info
516 * (1<<DBG_SPI) SpinUp test info
517 * (1<<DBG_IOS) ioctl trace: "subchannel"
518 * (1<<DBG_IO2) ioctl trace: general
519 * (1<<DBG_UPC) show UPC info
520 * (1<<DBG_XA1) XA mode debugging
521 * (1<<DBG_LCK) door (un)lock info
522 * (1<<DBG_SQ1) dump SubQ frame
523 * (1<<DBG_AUD) "read audio" debugging
524 * (1<<DBG_SEQ) Sequoia interface configuration trace
525 * (1<<DBG_LCS) Longshine LCS-7260 debugging trace
526 * (1<<DBG_CD2) MKE/Funai CD200 debugging trace
527 * (1<<DBG_TEA) TEAC CD-55A debugging trace
528 * (1<<DBG_ECS) ECS-AT (Vertos-100) debugging trace
529 * (1<<DBG_000) unnecessary information
530 */
531#if DISTRIBUTION
532static int sbpcd_debug = (1<<DBG_INF);
533#else
534static int sbpcd_debug = 0 & ((1<<DBG_INF) |
535 (1<<DBG_TOC) |
536 (1<<DBG_MUL) |
537 (1<<DBG_UPC));
538#endif /* DISTRIBUTION */
539
540static int sbpcd_ioaddr = CDROM_PORT; /* default I/O base address */
541static int sbpro_type = SBPRO;
542static unsigned char f_16bit;
543static unsigned char do_16bit;
544static int CDo_command, CDo_reset;
545static int CDo_sel_i_d, CDo_enable;
546static int CDi_info, CDi_status, CDi_data;
547static struct cdrom_msf msf;
548static struct cdrom_ti ti;
549static struct cdrom_tochdr tochdr;
550static struct cdrom_tocentry tocentry;
551static struct cdrom_subchnl SC;
552static struct cdrom_volctrl volctrl;
553static struct cdrom_read_audio read_audio;
554
555static unsigned char msgnum;
556static char msgbuf[80];
557
558static int max_drives = MAX_DRIVES;
559module_param(max_drives, int, 0);
560#ifndef MODULE
561static unsigned char setup_done;
562static const char *str_sb_l = "soundblaster";
563static const char *str_sp_l = "spea";
564static const char *str_ss_l = "soundscape";
565static const char *str_t16_l = "teac16bit";
566static const char *str_ss = "SoundScape";
567#endif
568static const char *str_sb = "SoundBlaster";
569static const char *str_lm = "LaserMate";
570static const char *str_sp = "SPEA";
571static const char *str_t16 = "Teac16bit";
572static const char *type;
573static const char *major_name="sbpcd";
574
575/*==========================================================================*/
576
577#ifdef FUTURE
578static DECLARE_WAIT_QUEUE_HEAD(sbp_waitq);
579#endif /* FUTURE */
580
581static int teac=SBP_TEAC_SPEED;
582static int buffers=SBP_BUFFER_FRAMES;
583
584static u_char family0[]="MATSHITA"; /* MKE CR-521, CR-522, CR-523 */
585static u_char family1[]="CR-56"; /* MKE CR-562, CR-563 */
586static u_char family2[]="CD200"; /* MKE CD200, Funai CD200F */
587static u_char familyL[]="LCS-7260"; /* Longshine LCS-7260 */
588static u_char familyT[]="CD-55"; /* TEAC CD-55A */
589static u_char familyV[]="ECS-AT"; /* ECS Vertos 100 */
590
591static u_int recursion; /* internal testing only */
592static u_int fatal_err; /* internal testing only */
593static u_int response_count;
594static u_int flags_cmd_out;
595static u_char cmd_type;
596static u_char drvcmd[10];
597static u_char infobuf[20];
598static u_char xa_head_buf[CD_XA_HEAD];
599static u_char xa_tail_buf[CD_XA_TAIL];
600
601#if OLD_BUSY
602static volatile u_char busy_data;
603static volatile u_char busy_audio; /* true semaphores would be safer */
604#endif /* OLD_BUSY */
605static DECLARE_MUTEX(ioctl_read_sem);
606static u_long timeout;
607static volatile u_char timed_out_delay;
608static volatile u_char timed_out_data;
609#if 0
610static volatile u_char timed_out_audio;
611#endif
612static u_int datarate= 1000000;
613static u_int maxtim16=16000000;
614static u_int maxtim04= 4000000;
615static u_int maxtim02= 2000000;
616static u_int maxtim_8= 30000;
617#if LONG_TIMING
618static u_int maxtim_data= 9000;
619#else
620static u_int maxtim_data= 3000;
621#endif /* LONG_TIMING */
622#if DISTRIBUTION
623static int n_retries=6;
624#else
625static int n_retries=6;
626#endif
627/*==========================================================================*/
628
629static int ndrives;
630static u_char drv_pattern[NR_SBPCD]={speed_auto,speed_auto,speed_auto,speed_auto};
631
632/*==========================================================================*/
633/*
634 * drive space begins here (needed separate for each unit)
635 */
636static struct sbpcd_drive {
637 char drv_id; /* "jumpered" drive ID or -1 */
638 char drv_sel; /* drive select lines bits */
639
640 char drive_model[9];
641 u_char firmware_version[4];
642 char f_eject; /* auto-eject flag: 0 or 1 */
643 u_char *sbp_buf; /* Pointer to internal data buffer,
644 space allocated during sbpcd_init() */
645 u_int sbp_bufsiz; /* size of sbp_buf (# of frames) */
646 int sbp_first_frame; /* First frame in buffer */
647 int sbp_last_frame; /* Last frame in buffer */
648 int sbp_read_frames; /* Number of frames being read to buffer */
649 int sbp_current; /* Frame being currently read */
650
651 u_char mode; /* read_mode: READ_M1, READ_M2, READ_SC, READ_AU */
652 u_char *aud_buf; /* Pointer to audio data buffer,
653 space allocated during sbpcd_init() */
654 u_int sbp_audsiz; /* size of aud_buf (# of raw frames) */
655 u_int drv_type;
656 u_char drv_options;
657 int status_bits;
658 u_char diskstate_flags;
659 u_char sense_byte;
660
661 u_char CD_changed;
662 char open_count;
663 u_char error_byte;
664
665 u_char f_multisession;
666 u_int lba_multi;
667 int first_session;
668 int last_session;
669 int track_of_last_session;
670
671 u_char audio_state;
672 u_int pos_audio_start;
673 u_int pos_audio_end;
674 char vol_chan0;
675 u_char vol_ctrl0;
676 char vol_chan1;
677 u_char vol_ctrl1;
678#if 000 /* no supported drive has it */
679 char vol_chan2;
680 u_char vol_ctrl2;
681 char vol_chan3;
682 u_char vol_ctrl3;
683#endif /*000 */
684 u_char volume_control; /* TEAC on/off bits */
685
686 u_char SubQ_ctl_adr;
687 u_char SubQ_trk;
688 u_char SubQ_pnt_idx;
689 u_int SubQ_run_tot;
690 u_int SubQ_run_trk;
691 u_char SubQ_whatisthis;
692
693 u_char UPC_ctl_adr;
694 u_char UPC_buf[7];
695
696 int frame_size;
697 int CDsize_frm;
698
699 u_char xa_byte; /* 0x20: XA capabilities */
700 u_char n_first_track; /* binary */
701 u_char n_last_track; /* binary (not bcd), 0x01...0x63 */
702 u_int size_msf; /* time of whole CD, position of LeadOut track */
703 u_int size_blk;
704
705 u_char TocEnt_nixbyte; /* em */
706 u_char TocEnt_ctl_adr;
707 u_char TocEnt_number;
708 u_char TocEnt_format; /* em */
709 u_int TocEnt_address;
710#ifdef SAFE_MIXED
711 char has_data;
712#endif /* SAFE_MIXED */
713 u_char ored_ctl_adr; /* to detect if CDROM contains data tracks */
714
715 struct {
716 u_char nixbyte; /* em */
717 u_char ctl_adr; /* 0x4x: data, 0x0x: audio */
718 u_char number;
719 u_char format; /* em */ /* 0x00: lba, 0x01: msf */
720 u_int address;
721 } TocBuffer[MAX_TRACKS+1]; /* last entry faked */
722
723 int in_SpinUp; /* CR-52x test flag */
724 int n_bytes; /* TEAC awaited response count */
725 u_char error_state, b3, b4; /* TEAC command error state */
726 u_char f_drv_error; /* TEAC command error flag */
727 u_char speed_byte;
728 int frmsiz;
729 u_char f_XA; /* 1: XA */
730 u_char type_byte; /* 0, 1, 3 */
731 u_char mode_xb_6;
732 u_char mode_yb_7;
733 u_char mode_xb_8;
734 u_char delay;
735 struct cdrom_device_info *sbpcd_infop;
736 struct gendisk *disk;
737} D_S[NR_SBPCD];
738
739static struct sbpcd_drive *current_drive = D_S;
740
741/*
742 * drive space ends here (needed separate for each unit)
743 */
744/*==========================================================================*/
745#if 0
746unsigned long cli_sti; /* for saving the processor flags */
747#endif
748/*==========================================================================*/
749static DEFINE_TIMER(delay_timer, mark_timeout_delay, 0, 0);
750static DEFINE_TIMER(data_timer, mark_timeout_data, 0, 0);
751#if 0
752static DEFINE_TIMER(audio_timer, mark_timeout_audio, 0, 0);
753#endif
754/*==========================================================================*/
755/*
756 * DDI interface
757 */
758static void msg(int level, const char *fmt, ...)
759{
760#if DISTRIBUTION
761#define MSG_LEVEL KERN_NOTICE
762#else
763#define MSG_LEVEL KERN_INFO
764#endif /* DISTRIBUTION */
765
766 char buf[256];
767 va_list args;
768
769 if (!(sbpcd_debug&(1<<level))) return;
770
771 msgnum++;
772 if (msgnum>99) msgnum=0;
773 va_start(args, fmt);
774 vsnprintf(buf, sizeof(buf), fmt, args);
775 va_end(args);
776 printk(MSG_LEVEL "%s-%d [%02d]: %s", major_name, current_drive - D_S, msgnum, buf);
777#if KLOGD_PAUSE
778 sbp_sleep(KLOGD_PAUSE); /* else messages get lost */
779#endif /* KLOGD_PAUSE */
780 return;
781}
782/*==========================================================================*/
783/*
784 * DDI interface: runtime trace bit pattern maintenance
785 */
786static int sbpcd_dbg_ioctl(unsigned long arg, int level)
787{
788 switch(arg)
789 {
790 case 0: /* OFF */
791 sbpcd_debug = DBG_INF;
792 break;
793
794 default:
795 if (arg>=128) sbpcd_debug &= ~(1<<(arg-128));
796 else sbpcd_debug |= (1<<arg);
797 }
798 return (arg);
799}
800/*==========================================================================*/
801static void mark_timeout_delay(u_long i)
802{
803 timed_out_delay=1;
804#if 0
805 msg(DBG_TIM,"delay timer expired.\n");
806#endif
807}
808/*==========================================================================*/
809static void mark_timeout_data(u_long i)
810{
811 timed_out_data=1;
812#if 0
813 msg(DBG_TIM,"data timer expired.\n");
814#endif
815}
816/*==========================================================================*/
817#if 0
818static void mark_timeout_audio(u_long i)
819{
820 timed_out_audio=1;
821#if 0
822 msg(DBG_TIM,"audio timer expired.\n");
823#endif
824}
825#endif
826/*==========================================================================*/
827/*
828 * Wait a little while (used for polling the drive).
829 */
830static void sbp_sleep(u_int time)
831{
832 sti();
833 schedule_timeout_interruptible(time);
834 sti();
835}
836/*==========================================================================*/
837#define RETURN_UP(rc) {up(&ioctl_read_sem); return(rc);}
838/*==========================================================================*/
839/*
840 * convert logical_block_address to m-s-f_number (3 bytes only)
841 */
842static INLINE void lba2msf(int lba, u_char *msf)
843{
844 lba += CD_MSF_OFFSET;
845 msf[0] = lba / (CD_SECS*CD_FRAMES);
846 lba %= CD_SECS*CD_FRAMES;
847 msf[1] = lba / CD_FRAMES;
848 msf[2] = lba % CD_FRAMES;
849}
850/*==========================================================================*/
851/*==========================================================================*/
852/*
853 * convert msf-bin to msf-bcd
854 */
855static INLINE void bin2bcdx(u_char *p) /* must work only up to 75 or 99 */
856{
857 *p=((*p/10)<<4)|(*p%10);
858}
859/*==========================================================================*/
860static INLINE u_int blk2msf(u_int blk)
861{
862 MSF msf;
863 u_int mm;
864
865 msf.c[3] = 0;
866 msf.c[2] = (blk + CD_MSF_OFFSET) / (CD_SECS * CD_FRAMES);
867 mm = (blk + CD_MSF_OFFSET) % (CD_SECS * CD_FRAMES);
868 msf.c[1] = mm / CD_FRAMES;
869 msf.c[0] = mm % CD_FRAMES;
870 return (msf.n);
871}
872/*==========================================================================*/
873static INLINE u_int make16(u_char rh, u_char rl)
874{
875 return ((rh<<8)|rl);
876}
877/*==========================================================================*/
878static INLINE u_int make32(u_int rh, u_int rl)
879{
880 return ((rh<<16)|rl);
881}
882/*==========================================================================*/
883static INLINE u_char swap_nibbles(u_char i)
884{
885 return ((i<<4)|(i>>4));
886}
887/*==========================================================================*/
888static INLINE u_char byt2bcd(u_char i)
889{
890 return (((i/10)<<4)+i%10);
891}
892/*==========================================================================*/
893static INLINE u_char bcd2bin(u_char bcd)
894{
895 return ((bcd>>4)*10+(bcd&0x0F));
896}
897/*==========================================================================*/
898static INLINE int msf2blk(int msfx)
899{
900 MSF msf;
901 int i;
902
903 msf.n=msfx;
904 i=(msf.c[2] * CD_SECS + msf.c[1]) * CD_FRAMES + msf.c[0] - CD_MSF_OFFSET;
905 if (i<0) return (0);
906 return (i);
907}
908/*==========================================================================*/
909/*
910 * convert m-s-f_number (3 bytes only) to logical_block_address
911 */
912static INLINE int msf2lba(u_char *msf)
913{
914 int i;
915
916 i=(msf[0] * CD_SECS + msf[1]) * CD_FRAMES + msf[2] - CD_MSF_OFFSET;
917 if (i<0) return (0);
918 return (i);
919}
920/*==========================================================================*/
921/* evaluate cc_ReadError code */
922static int sta2err(int sta)
923{
924 if (famT_drive)
925 {
926 if (sta==0x00) return (0);
927 if (sta==0x01) return (-604); /* CRC error */
928 if (sta==0x02) return (-602); /* drive not ready */
929 if (sta==0x03) return (-607); /* unknown media */
930 if (sta==0x04) return (-612); /* general failure */
931 if (sta==0x05) return (0);
932 if (sta==0x06) return (-ERR_DISKCHANGE); /* disk change */
933 if (sta==0x0b) return (-612); /* general failure */
934 if (sta==0xff) return (-612); /* general failure */
935 return (0);
936 }
937 else
938 {
939 if (sta<=2) return (sta);
940 if (sta==0x05) return (-604); /* CRC error */
941 if (sta==0x06) return (-606); /* seek error */
942 if (sta==0x0d) return (-606); /* seek error */
943 if (sta==0x0e) return (-603); /* unknown command */
944 if (sta==0x14) return (-603); /* unknown command */
945 if (sta==0x0c) return (-611); /* read fault */
946 if (sta==0x0f) return (-611); /* read fault */
947 if (sta==0x10) return (-611); /* read fault */
948 if (sta>=0x16) return (-612); /* general failure */
949 if (sta==0x11) return (-ERR_DISKCHANGE); /* disk change (LCS: removed) */
950 if (famL_drive)
951 if (sta==0x12) return (-ERR_DISKCHANGE); /* disk change (inserted) */
952 return (-602); /* drive not ready */
953 }
954}
955/*==========================================================================*/
956static INLINE void clr_cmdbuf(void)
957{
958 int i;
959
960 for (i=0;i<10;i++) drvcmd[i]=0;
961 cmd_type=0;
962}
963/*==========================================================================*/
964static void flush_status(void)
965{
966 int i;
967
968 sbp_sleep(15*HZ/10);
969 for (i=maxtim_data;i!=0;i--) inb(CDi_status);
970}
971/*====================================================================*/
972/*
973 * CDi status loop for Teac CD-55A (Rob Riggs)
974 *
975 * This is needed because for some strange reason
976 * the CD-55A can take a real long time to give a
977 * status response. This seems to happen after we
978 * issue a READ command where a long seek is involved.
979 *
980 * I tried to ensure that we get max throughput with
981 * minimal busy waiting. We busy wait at first, then
982 * "switch gears" and start sleeping. We sleep for
983 * longer periods of time the longer we wait.
984 *
985 */
986static int CDi_stat_loop_T(void)
987{
988 int i, gear=1;
989 u_long timeout_1, timeout_2, timeout_3, timeout_4;
990
991 timeout_1 = jiffies + HZ / 50; /* sbp_sleep(0) for a short period */
992 timeout_2 = jiffies + HZ / 5; /* nap for no more than 200ms */
993 timeout_3 = jiffies + 5 * HZ; /* sleep for up to 5s */
994 timeout_4 = jiffies + 45 * HZ; /* long sleep for up to 45s. */
995 do
996 {
997 i = inb(CDi_status);
998 if (!(i&s_not_data_ready)) return (i);
999 if (!(i&s_not_result_ready)) return (i);
1000 switch(gear)
1001 {
1002 case 4:
1003 sbp_sleep(HZ);
1004 if (time_after(jiffies, timeout_4)) gear++;
1005 msg(DBG_TEA, "CDi_stat_loop_T: long sleep active.\n");
1006 break;
1007 case 3:
1008 sbp_sleep(HZ/10);
1009 if (time_after(jiffies, timeout_3)) gear++;
1010 break;
1011 case 2:
1012 sbp_sleep(HZ/100);
1013 if (time_after(jiffies, timeout_2)) gear++;
1014 break;
1015 case 1:
1016 sbp_sleep(0);
1017 if (time_after(jiffies, timeout_1)) gear++;
1018 }
1019 } while (gear < 5);
1020 return -1;
1021}
1022/*==========================================================================*/
1023static int CDi_stat_loop(void)
1024{
1025 int i,j;
1026
1027 for(timeout = jiffies + 10*HZ, i=maxtim_data; time_before(jiffies, timeout); )
1028 {
1029 for ( ;i!=0;i--)
1030 {
1031 j=inb(CDi_status);
1032 if (!(j&s_not_data_ready)) return (j);
1033 if (!(j&s_not_result_ready)) return (j);
1034 if (fam0L_drive) if (j&s_attention) return (j);
1035 }
1036 sbp_sleep(1);
1037 i = 1;
1038 }
1039 msg(DBG_LCS,"CDi_stat_loop failed in line %d\n", __LINE__);
1040 return (-1);
1041}
1042/*==========================================================================*/
1043#if 00000
1044/*==========================================================================*/
1045static int tst_DataReady(void)
1046{
1047 int i;
1048
1049 i=inb(CDi_status);
1050 if (i&s_not_data_ready) return (0);
1051 return (1);
1052}
1053/*==========================================================================*/
1054static int tst_ResultReady(void)
1055{
1056 int i;
1057
1058 i=inb(CDi_status);
1059 if (i&s_not_result_ready) return (0);
1060 return (1);
1061}
1062/*==========================================================================*/
1063static int tst_Attention(void)
1064{
1065 int i;
1066
1067 i=inb(CDi_status);
1068 if (i&s_attention) return (1);
1069 return (0);
1070}
1071/*==========================================================================*/
1072#endif
1073/*==========================================================================*/
1074static int ResponseInfo(void)
1075{
1076 int i,j,st=0;
1077 u_long timeout;
1078
1079 for (i=0,timeout=jiffies+HZ;i<response_count;i++)
1080 {
1081 for (j=maxtim_data; ; )
1082 {
1083 for ( ;j!=0;j-- )
1084 {
1085 st=inb(CDi_status);
1086 if (!(st&s_not_result_ready)) break;
1087 }
1088 if ((j!=0)||time_after_eq(jiffies, timeout)) break;
1089 sbp_sleep(1);
1090 j = 1;
1091 }
1092 if (time_after_eq(jiffies, timeout)) break;
1093 infobuf[i]=inb(CDi_info);
1094 }
1095#if 000
1096 while (!(inb(CDi_status)&s_not_result_ready))
1097 {
1098 infobuf[i++]=inb(CDi_info);
1099 }
1100 j=i-response_count;
1101 if (j>0) msg(DBG_INF,"ResponseInfo: got %d trailing bytes.\n",j);
1102#endif /* 000 */
1103 for (j=0;j<i;j++)
1104 sprintf(&msgbuf[j*3]," %02X",infobuf[j]);
1105 msgbuf[j*3]=0;
1106 msg(DBG_CMD,"ResponseInfo:%s (%d,%d)\n",msgbuf,response_count,i);
1107 j=response_count-i;
1108 if (j>0) return (-j);
1109 else return (i);
1110}
1111/*==========================================================================*/
1112static void EvaluateStatus(int st)
1113{
1114 current_drive->status_bits=0;
1115 if (fam1_drive) current_drive->status_bits=st|p_success;
1116 else if (fam0_drive)
1117 {
1118 if (st&p_caddin_old) current_drive->status_bits |= p_door_closed|p_caddy_in;
1119 if (st&p_spinning) current_drive->status_bits |= p_spinning;
1120 if (st&p_check) current_drive->status_bits |= p_check;
1121 if (st&p_success_old) current_drive->status_bits |= p_success;
1122 if (st&p_busy_old) current_drive->status_bits |= p_busy_new;
1123 if (st&p_disk_ok) current_drive->status_bits |= p_disk_ok;
1124 }
1125 else if (famLV_drive)
1126 {
1127 current_drive->status_bits |= p_success;
1128 if (st&p_caddin_old) current_drive->status_bits |= p_disk_ok|p_caddy_in;
1129 if (st&p_spinning) current_drive->status_bits |= p_spinning;
1130 if (st&p_check) current_drive->status_bits |= p_check;
1131 if (st&p_busy_old) current_drive->status_bits |= p_busy_new;
1132 if (st&p_lcs_door_closed) current_drive->status_bits |= p_door_closed;
1133 if (st&p_lcs_door_locked) current_drive->status_bits |= p_door_locked;
1134 }
1135 else if (fam2_drive)
1136 {
1137 current_drive->status_bits |= p_success;
1138 if (st&p2_check) current_drive->status_bits |= p1_check;
1139 if (st&p2_door_closed) current_drive->status_bits |= p1_door_closed;
1140 if (st&p2_disk_in) current_drive->status_bits |= p1_disk_in;
1141 if (st&p2_busy1) current_drive->status_bits |= p1_busy;
1142 if (st&p2_busy2) current_drive->status_bits |= p1_busy;
1143 if (st&p2_spinning) current_drive->status_bits |= p1_spinning;
1144 if (st&p2_door_locked) current_drive->status_bits |= p1_door_locked;
1145 if (st&p2_disk_ok) current_drive->status_bits |= p1_disk_ok;
1146 }
1147 else if (famT_drive)
1148 {
1149 return; /* still needs to get coded */
1150 current_drive->status_bits |= p_success;
1151 if (st&p2_check) current_drive->status_bits |= p1_check;
1152 if (st&p2_door_closed) current_drive->status_bits |= p1_door_closed;
1153 if (st&p2_disk_in) current_drive->status_bits |= p1_disk_in;
1154 if (st&p2_busy1) current_drive->status_bits |= p1_busy;
1155 if (st&p2_busy2) current_drive->status_bits |= p1_busy;
1156 if (st&p2_spinning) current_drive->status_bits |= p1_spinning;
1157 if (st&p2_door_locked) current_drive->status_bits |= p1_door_locked;
1158 if (st&p2_disk_ok) current_drive->status_bits |= p1_disk_ok;
1159 }
1160 return;
1161}
1162/*==========================================================================*/
1163static int cmd_out_T(void);
1164
1165static int get_state_T(void)
1166{
1167 int i;
1168
1169 clr_cmdbuf();
1170 current_drive->n_bytes=1;
1171 drvcmd[0]=CMDT_STATUS;
1172 i=cmd_out_T();
1173 if (i>=0) i=infobuf[0];
1174 else
1175 {
1176 msg(DBG_TEA,"get_state_T error %d\n", i);
1177 return (i);
1178 }
1179 if (i>=0)
1180 /* 2: closed, disk in */
1181 current_drive->status_bits=p1_door_closed|p1_disk_in|p1_spinning|p1_disk_ok;
1182 else if (current_drive->error_state==6)
1183 {
1184 /* 3: closed, disk in, changed ("06 xx xx") */
1185 current_drive->status_bits=p1_door_closed|p1_disk_in;
1186 current_drive->CD_changed=0xFF;
1187 current_drive->diskstate_flags &= ~toc_bit;
1188 }
1189 else if ((current_drive->error_state!=2)||(current_drive->b3!=0x3A)||(current_drive->b4==0x00))
1190 {
1191 /* 1: closed, no disk ("xx yy zz"or "02 3A 00") */
1192 current_drive->status_bits=p1_door_closed;
1193 current_drive->open_count=0;
1194 }
1195 else if (current_drive->b4==0x01)
1196 {
1197 /* 0: open ("02 3A 01") */
1198 current_drive->status_bits=0;
1199 current_drive->open_count=0;
1200 }
1201 else
1202 {
1203 /* 1: closed, no disk ("02 3A xx") */
1204 current_drive->status_bits=p1_door_closed;
1205 current_drive->open_count=0;
1206 }
1207 return (current_drive->status_bits);
1208}
1209/*==========================================================================*/
1210static int ResponseStatus(void)
1211{
1212 int i,j;
1213 u_long timeout;
1214
1215 msg(DBG_STA,"doing ResponseStatus...\n");
1216 if (famT_drive) return (get_state_T());
1217 if (flags_cmd_out & f_respo3) timeout = jiffies;
1218 else if (flags_cmd_out & f_respo2) timeout = jiffies + 16*HZ;
1219 else timeout = jiffies + 4*HZ;
1220 j=maxtim_8;
1221 do
1222 {
1223 for ( ;j!=0;j--)
1224 {
1225 i=inb(CDi_status);
1226 if (!(i&s_not_result_ready)) break;
1227 }
1228 if ((j!=0)||time_after(jiffies, timeout)) break;
1229 sbp_sleep(1);
1230 j = 1;
1231 }
1232 while (1);
1233 if (j==0)
1234 {
1235 if ((flags_cmd_out & f_respo3) == 0)
1236 msg(DBG_STA,"ResponseStatus: timeout.\n");
1237 current_drive->status_bits=0;
1238 return (-401);
1239 }
1240 i=inb(CDi_info);
1241 msg(DBG_STA,"ResponseStatus: response %02X.\n", i);
1242 EvaluateStatus(i);
1243 msg(DBG_STA,"status_bits=%02X, i=%02X\n",current_drive->status_bits,i);
1244 return (current_drive->status_bits);
1245}
1246/*==========================================================================*/
1247static void cc_ReadStatus(void)
1248{
1249 int i;
1250
1251 msg(DBG_STA,"giving cc_ReadStatus command\n");
1252 if (famT_drive) return;
1253 SBPCD_CLI;
1254 if (fam0LV_drive) OUT(CDo_command,CMD0_STATUS);
1255 else if (fam1_drive) OUT(CDo_command,CMD1_STATUS);
1256 else if (fam2_drive) OUT(CDo_command,CMD2_STATUS);
1257 if (!fam0LV_drive) for (i=0;i<6;i++) OUT(CDo_command,0);
1258 SBPCD_STI;
1259}
1260/*==========================================================================*/
1261static int cc_ReadError(void)
1262{
1263 int i;
1264
1265 clr_cmdbuf();
1266 msg(DBG_ERR,"giving cc_ReadError command.\n");
1267 if (fam1_drive)
1268 {
1269 drvcmd[0]=CMD1_READ_ERR;
1270 response_count=8;
1271 flags_cmd_out=f_putcmd|f_ResponseStatus;
1272 }
1273 else if (fam0LV_drive)
1274 {
1275 drvcmd[0]=CMD0_READ_ERR;
1276 response_count=6;
1277 if (famLV_drive)
1278 flags_cmd_out=f_putcmd;
1279 else
1280 flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus;
1281 }
1282 else if (fam2_drive)
1283 {
1284 drvcmd[0]=CMD2_READ_ERR;
1285 response_count=6;
1286 flags_cmd_out=f_putcmd;
1287 }
1288 else if (famT_drive)
1289 {
1290 response_count=5;
1291 drvcmd[0]=CMDT_READ_ERR;
1292 }
1293 i=cmd_out();
1294 current_drive->error_byte=0;
1295 msg(DBG_ERR,"cc_ReadError: cmd_out(CMDx_READ_ERR) returns %d (%02X)\n",i,i);
1296 if (i<0) return (i);
1297 if (fam0V_drive) i=1;
1298 else i=2;
1299 current_drive->error_byte=infobuf[i];
1300 msg(DBG_ERR,"cc_ReadError: infobuf[%d] is %d (%02X)\n",i,current_drive->error_byte,current_drive->error_byte);
1301 i=sta2err(infobuf[i]);
1302 if (i==-ERR_DISKCHANGE)
1303 {
1304 current_drive->CD_changed=0xFF;
1305 current_drive->diskstate_flags &= ~toc_bit;
1306 }
1307 return (i);
1308}
1309/*==========================================================================*/
1310static int cc_DriveReset(void);
1311
1312static int cmd_out_T(void)
1313{
1314#undef CMDT_TRIES
1315#define CMDT_TRIES 1000
1316#define TEST_FALSE_FF 1
1317
1318 int i, j, l=0, m, ntries;
1319 unsigned long flags;
1320
1321 current_drive->error_state=0;
1322 current_drive->b3=0;
1323 current_drive->b4=0;
1324 current_drive->f_drv_error=0;
1325 for (i=0;i<10;i++) sprintf(&msgbuf[i*3]," %02X",drvcmd[i]);
1326 msgbuf[i*3]=0;
1327 msg(DBG_CMD,"cmd_out_T:%s\n",msgbuf);
1328
1329 OUT(CDo_sel_i_d,0);
1330 OUT(CDo_enable,current_drive->drv_sel);
1331 i=inb(CDi_status);
1332 do_16bit=0;
1333 if ((f_16bit)&&(!(i&0x80)))
1334 {
1335 do_16bit=1;
1336 msg(DBG_TEA,"cmd_out_T: do_16bit set.\n");
1337 }
1338 if (!(i&s_not_result_ready))
1339 do
1340 {
1341 j=inb(CDi_info);
1342 i=inb(CDi_status);
1343 sbp_sleep(0);
1344 msg(DBG_TEA,"cmd_out_T: spurious !s_not_result_ready. (%02X)\n", j);
1345 }
1346 while (!(i&s_not_result_ready));
1347 save_flags(flags); cli();
1348 for (i=0;i<10;i++) OUT(CDo_command,drvcmd[i]);
1349 restore_flags(flags);
1350 for (ntries=CMDT_TRIES;ntries>0;ntries--)
1351 {
1352 if (drvcmd[0]==CMDT_READ_VER) sbp_sleep(HZ); /* fixme */
1353#if 01
1354 OUT(CDo_sel_i_d,1);
1355#endif /* 01 */
1356 if (teac==2)
1357 {
1358 if ((i=CDi_stat_loop_T()) == -1) break;
1359 }
1360 else
1361 {
1362#if 0
1363 OUT(CDo_sel_i_d,1);
1364#endif /* 0 */
1365 i=inb(CDi_status);
1366 }
1367 if (!(i&s_not_data_ready)) /* f.e. CMDT_DISKINFO */
1368 {
1369 OUT(CDo_sel_i_d,1);
1370 if (drvcmd[0]==CMDT_READ) return (0); /* handled elsewhere */
1371 if (drvcmd[0]==CMDT_DISKINFO)
1372 {
1373 l=0;
1374 do
1375 {
1376 if (do_16bit)
1377 {
1378 i=inw(CDi_data);
1379 infobuf[l++]=i&0x0ff;
1380 infobuf[l++]=i>>8;
1381#if TEST_FALSE_FF
1382 if ((l==2)&&(infobuf[0]==0x0ff))
1383 {
1384 infobuf[0]=infobuf[1];
1385 l=1;
1386 msg(DBG_TEA,"cmd_out_T: do_16bit: false first byte!\n");
1387 }
1388#endif /* TEST_FALSE_FF */
1389 }
1390 else infobuf[l++]=inb(CDi_data);
1391 i=inb(CDi_status);
1392 }
1393 while (!(i&s_not_data_ready));
1394 for (j=0;j<l;j++) sprintf(&msgbuf[j*3]," %02X",infobuf[j]);
1395 msgbuf[j*3]=0;
1396 msg(DBG_CMD,"cmd_out_T data response:%s\n", msgbuf);
1397 }
1398 else
1399 {
1400 msg(DBG_TEA,"cmd_out_T: data response with cmd_%02X!\n",
1401 drvcmd[0]);
1402 j=0;
1403 do
1404 {
1405 if (do_16bit) i=inw(CDi_data);
1406 else i=inb(CDi_data);
1407 j++;
1408 i=inb(CDi_status);
1409 }
1410 while (!(i&s_not_data_ready));
1411 msg(DBG_TEA,"cmd_out_T: data response: discarded %d bytes/words.\n", j);
1412 fatal_err++;
1413 }
1414 }
1415 i=inb(CDi_status);
1416 if (!(i&s_not_result_ready))
1417 {
1418 OUT(CDo_sel_i_d,0);
1419 if (drvcmd[0]==CMDT_DISKINFO) m=l;
1420 else m=0;
1421 do
1422 {
1423 infobuf[m++]=inb(CDi_info);
1424 i=inb(CDi_status);
1425 }
1426 while (!(i&s_not_result_ready));
1427 for (j=0;j<m;j++) sprintf(&msgbuf[j*3]," %02X",infobuf[j]);
1428 msgbuf[j*3]=0;
1429 msg(DBG_CMD,"cmd_out_T info response:%s\n", msgbuf);
1430 if (drvcmd[0]==CMDT_DISKINFO)
1431 {
1432 infobuf[0]=infobuf[l];
1433 if (infobuf[0]!=0x02) return (l); /* data length */
1434 }
1435 else if (infobuf[0]!=0x02) return (m); /* info length */
1436 do
1437 {
1438 ++recursion;
1439 if (recursion>1) msg(DBG_TEA,"cmd_out_T READ_ERR recursion (%02X): %d !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n", drvcmd[0], recursion);
1440 clr_cmdbuf();
1441 drvcmd[0]=CMDT_READ_ERR;
1442 j=cmd_out_T(); /* !!! recursive here !!! */
1443 --recursion;
1444 sbp_sleep(1);
1445 }
1446 while (j<0);
1447 current_drive->error_state=infobuf[2];
1448 current_drive->b3=infobuf[3];
1449 current_drive->b4=infobuf[4];
1450 if (current_drive->f_drv_error)
1451 {
1452 current_drive->f_drv_error=0;
1453 cc_DriveReset();
1454 current_drive->error_state=2;
1455 }
1456 return (-current_drive->error_state-400);
1457 }
1458 if (drvcmd[0]==CMDT_READ) return (0); /* handled elsewhere */
1459 if ((teac==0)||(ntries<(CMDT_TRIES-5))) sbp_sleep(HZ/10);
1460 else sbp_sleep(HZ/100);
1461 if (ntries>(CMDT_TRIES-50)) continue;
1462 msg(DBG_TEA,"cmd_out_T: next CMDT_TRIES (%02X): %d.\n", drvcmd[0], ntries-1);
1463 }
1464 current_drive->f_drv_error=1;
1465 cc_DriveReset();
1466 current_drive->error_state=2;
1467 return (-99);
1468}
1469/*==========================================================================*/
1470static int cmd_out(void)
1471{
1472 int i=0;
1473
1474 if (famT_drive) return(cmd_out_T());
1475
1476 if (flags_cmd_out&f_putcmd)
1477 {
1478 unsigned long flags;
1479 for (i=0;i<7;i++)
1480 sprintf(&msgbuf[i*3], " %02X", drvcmd[i]);
1481 msgbuf[i*3]=0;
1482 msg(DBG_CMD,"cmd_out:%s\n", msgbuf);
1483 save_flags(flags); cli();
1484 for (i=0;i<7;i++) OUT(CDo_command,drvcmd[i]);
1485 restore_flags(flags);
1486 }
1487 if (response_count!=0)
1488 {
1489 if (cmd_type!=0)
1490 {
1491 if (sbpro_type==1) OUT(CDo_sel_i_d,1);
1492 msg(DBG_INF,"misleaded to try ResponseData.\n");
1493 if (sbpro_type==1) OUT(CDo_sel_i_d,0);
1494 return (-22);
1495 }
1496 else i=ResponseInfo();
1497 if (i<0) return (i);
1498 }
1499 if (current_drive->in_SpinUp) msg(DBG_SPI,"in_SpinUp: to CDi_stat_loop.\n");
1500 if (flags_cmd_out&f_lopsta)
1501 {
1502 i=CDi_stat_loop();
1503 if ((i<0)||!(i&s_attention)) return (-8);
1504 }
1505 if (!(flags_cmd_out&f_getsta)) goto LOC_229;
1506
1507 LOC_228:
1508 if (current_drive->in_SpinUp) msg(DBG_SPI,"in_SpinUp: to cc_ReadStatus.\n");
1509 cc_ReadStatus();
1510
1511 LOC_229:
1512 if (flags_cmd_out&f_ResponseStatus)
1513 {
1514 if (current_drive->in_SpinUp) msg(DBG_SPI,"in_SpinUp: to ResponseStatus.\n");
1515 i=ResponseStatus();
1516 /* builds status_bits, returns orig. status or p_busy_new */
1517 if (i<0) return (i);
1518 if (flags_cmd_out&(f_bit1|f_wait_if_busy))
1519 {
1520 if (!st_check)
1521 {
1522 if ((flags_cmd_out&f_bit1)&&(i&p_success)) goto LOC_232;
1523 if ((!(flags_cmd_out&f_wait_if_busy))||(!st_busy)) goto LOC_228;
1524 }
1525 }
1526 }
1527 LOC_232:
1528 if (!(flags_cmd_out&f_obey_p_check)) return (0);
1529 if (!st_check) return (0);
1530 if (current_drive->in_SpinUp) msg(DBG_SPI,"in_SpinUp: to cc_ReadError.\n");
1531 i=cc_ReadError();
1532 if (current_drive->in_SpinUp) msg(DBG_SPI,"in_SpinUp: to cmd_out OK.\n");
1533 msg(DBG_000,"cmd_out: cc_ReadError=%d\n", i);
1534 return (i);
1535}
1536/*==========================================================================*/
1537static int cc_Seek(u_int pos, char f_blk_msf)
1538{
1539 int i;
1540
1541 clr_cmdbuf();
1542 if (f_blk_msf>1) return (-3);
1543 if (fam0V_drive)
1544 {
1545 drvcmd[0]=CMD0_SEEK;
1546 if (f_blk_msf==1) pos=msf2blk(pos);
1547 drvcmd[2]=(pos>>16)&0x00FF;
1548 drvcmd[3]=(pos>>8)&0x00FF;
1549 drvcmd[4]=pos&0x00FF;
1550 if (fam0_drive)
1551 flags_cmd_out = f_putcmd | f_respo2 | f_lopsta | f_getsta |
1552 f_ResponseStatus | f_obey_p_check | f_bit1;
1553 else
1554 flags_cmd_out = f_putcmd;
1555 }
1556 else if (fam1L_drive)
1557 {
1558 drvcmd[0]=CMD1_SEEK; /* same as CMD1_ and CMDL_ */
1559 if (f_blk_msf==0) pos=blk2msf(pos);
1560 drvcmd[1]=(pos>>16)&0x00FF;
1561 drvcmd[2]=(pos>>8)&0x00FF;
1562 drvcmd[3]=pos&0x00FF;
1563 if (famL_drive)
1564 flags_cmd_out=f_putcmd|f_respo2|f_lopsta|f_getsta|f_ResponseStatus|f_obey_p_check|f_bit1;
1565 else
1566 flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check;
1567 }
1568 else if (fam2_drive)
1569 {
1570 drvcmd[0]=CMD2_SEEK;
1571 if (f_blk_msf==0) pos=blk2msf(pos);
1572 drvcmd[2]=(pos>>24)&0x00FF;
1573 drvcmd[3]=(pos>>16)&0x00FF;
1574 drvcmd[4]=(pos>>8)&0x00FF;
1575 drvcmd[5]=pos&0x00FF;
1576 flags_cmd_out=f_putcmd|f_ResponseStatus;
1577 }
1578 else if (famT_drive)
1579 {
1580 drvcmd[0]=CMDT_SEEK;
1581 if (f_blk_msf==1) pos=msf2blk(pos);
1582 drvcmd[2]=(pos>>24)&0x00FF;
1583 drvcmd[3]=(pos>>16)&0x00FF;
1584 drvcmd[4]=(pos>>8)&0x00FF;
1585 drvcmd[5]=pos&0x00FF;
1586 current_drive->n_bytes=1;
1587 }
1588 response_count=0;
1589 i=cmd_out();
1590 return (i);
1591}
1592/*==========================================================================*/
1593static int cc_SpinUp(void)
1594{
1595 int i;
1596
1597 msg(DBG_SPI,"SpinUp.\n");
1598 current_drive->in_SpinUp = 1;
1599 clr_cmdbuf();
1600 if (fam0LV_drive)
1601 {
1602 drvcmd[0]=CMD0_SPINUP;
1603 if (fam0L_drive)
1604 flags_cmd_out=f_putcmd|f_respo2|f_lopsta|f_getsta|
1605 f_ResponseStatus|f_obey_p_check|f_bit1;
1606 else
1607 flags_cmd_out=f_putcmd;
1608 }
1609 else if (fam1_drive)
1610 {
1611 drvcmd[0]=CMD1_SPINUP;
1612 flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check;
1613 }
1614 else if (fam2_drive)
1615 {
1616 drvcmd[0]=CMD2_TRAY_CTL;
1617 drvcmd[4]=0x01; /* "spinup" */
1618 flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check;
1619 }
1620 else if (famT_drive)
1621 {
1622 drvcmd[0]=CMDT_TRAY_CTL;
1623 drvcmd[4]=0x03; /* "insert", it hopefully spins the drive up */
1624 }
1625 response_count=0;
1626 i=cmd_out();
1627 current_drive->in_SpinUp = 0;
1628 return (i);
1629}
1630/*==========================================================================*/
1631static int cc_SpinDown(void)
1632{
1633 int i;
1634
1635 if (fam0_drive) return (0);
1636 clr_cmdbuf();
1637 response_count=0;
1638 if (fam1_drive)
1639 {
1640 drvcmd[0]=CMD1_SPINDOWN;
1641 flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check;
1642 }
1643 else if (fam2_drive)
1644 {
1645 drvcmd[0]=CMD2_TRAY_CTL;
1646 drvcmd[4]=0x02; /* "eject" */
1647 flags_cmd_out=f_putcmd|f_ResponseStatus;
1648 }
1649 else if (famL_drive)
1650 {
1651 drvcmd[0]=CMDL_SPINDOWN;
1652 drvcmd[1]=1;
1653 flags_cmd_out=f_putcmd|f_respo2|f_lopsta|f_getsta|f_ResponseStatus|f_obey_p_check|f_bit1;
1654 }
1655 else if (famV_drive)
1656 {
1657 drvcmd[0]=CMDV_SPINDOWN;
1658 flags_cmd_out=f_putcmd;
1659 }
1660 else if (famT_drive)
1661 {
1662 drvcmd[0]=CMDT_TRAY_CTL;
1663 drvcmd[4]=0x02; /* "eject" */
1664 }
1665 i=cmd_out();
1666 return (i);
1667}
1668/*==========================================================================*/
1669static int cc_get_mode_T(void)
1670{
1671 int i;
1672
1673 clr_cmdbuf();
1674 response_count=10;
1675 drvcmd[0]=CMDT_GETMODE;
1676 drvcmd[4]=response_count;
1677 i=cmd_out_T();
1678 return (i);
1679}
1680/*==========================================================================*/
1681static int cc_set_mode_T(void)
1682{
1683 int i;
1684
1685 clr_cmdbuf();
1686 response_count=1;
1687 drvcmd[0]=CMDT_SETMODE;
1688 drvcmd[1]=current_drive->speed_byte;
1689 drvcmd[2]=current_drive->frmsiz>>8;
1690 drvcmd[3]=current_drive->frmsiz&0x0FF;
1691 drvcmd[4]=current_drive->f_XA; /* 1: XA */
1692 drvcmd[5]=current_drive->type_byte; /* 0, 1, 3 */
1693 drvcmd[6]=current_drive->mode_xb_6;
1694 drvcmd[7]=current_drive->mode_yb_7|current_drive->volume_control;
1695 drvcmd[8]=current_drive->mode_xb_8;
1696 drvcmd[9]=current_drive->delay;
1697 i=cmd_out_T();
1698 return (i);
1699}
1700/*==========================================================================*/
1701static int cc_prep_mode_T(void)
1702{
1703 int i, j;
1704
1705 i=cc_get_mode_T();
1706 if (i<0) return (i);
1707 for (i=0;i<10;i++)
1708 sprintf(&msgbuf[i*3], " %02X", infobuf[i]);
1709 msgbuf[i*3]=0;
1710 msg(DBG_TEA,"CMDT_GETMODE:%s\n", msgbuf);
1711 current_drive->speed_byte=0x02; /* 0x02: auto quad, 0x82: quad, 0x81: double, 0x80: single */
1712 current_drive->frmsiz=make16(infobuf[2],infobuf[3]);
1713 current_drive->f_XA=infobuf[4];
1714 if (current_drive->f_XA==0) current_drive->type_byte=0;
1715 else current_drive->type_byte=1;
1716 current_drive->mode_xb_6=infobuf[6];
1717 current_drive->mode_yb_7=1;
1718 current_drive->mode_xb_8=infobuf[8];
1719 current_drive->delay=0; /* 0, 1, 2, 3 */
1720 j=cc_set_mode_T();
1721 i=cc_get_mode_T();
1722 for (i=0;i<10;i++)
1723 sprintf(&msgbuf[i*3], " %02X", infobuf[i]);
1724 msgbuf[i*3]=0;
1725 msg(DBG_TEA,"CMDT_GETMODE:%s\n", msgbuf);
1726 return (j);
1727}
1728/*==========================================================================*/
1729static int cc_SetSpeed(u_char speed, u_char x1, u_char x2)
1730{
1731 int i;
1732
1733 if (fam0LV_drive) return (0);
1734 clr_cmdbuf();
1735 response_count=0;
1736 if (fam1_drive)
1737 {
1738 drvcmd[0]=CMD1_SETMODE;
1739 drvcmd[1]=0x03;
1740 drvcmd[2]=speed;
1741 drvcmd[3]=x1;
1742 drvcmd[4]=x2;
1743 flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
1744 }
1745 else if (fam2_drive)
1746 {
1747 drvcmd[0]=CMD2_SETSPEED;
1748 if (speed&speed_auto)
1749 {
1750 drvcmd[2]=0xFF;
1751 drvcmd[3]=0xFF;
1752 }
1753 else
1754 {
1755 drvcmd[2]=0;
1756 drvcmd[3]=150;
1757 }
1758 flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
1759 }
1760 else if (famT_drive)
1761 {
1762 return (0);
1763 }
1764 i=cmd_out();
1765 return (i);
1766}
1767/*==========================================================================*/
1768static int cc_SetVolume(void)
1769{
1770 int i;
1771 u_char channel0,channel1,volume0,volume1;
1772 u_char control0,value0,control1,value1;
1773
1774 current_drive->diskstate_flags &= ~volume_bit;
1775 clr_cmdbuf();
1776 channel0=current_drive->vol_chan0;
1777 volume0=current_drive->vol_ctrl0;
1778 channel1=control1=current_drive->vol_chan1;
1779 volume1=value1=current_drive->vol_ctrl1;
1780 control0=value0=0;
1781
1782 if (famV_drive) return (0);
1783
1784 if (((current_drive->drv_options&audio_mono)!=0)&&(current_drive->drv_type>=drv_211))
1785 {
1786 if ((volume0!=0)&&(volume1==0))
1787 {
1788 volume1=volume0;
1789 channel1=channel0;
1790 }
1791 else if ((volume0==0)&&(volume1!=0))
1792 {
1793 volume0=volume1;
1794 channel0=channel1;
1795 }
1796 }
1797 if (channel0>1)
1798 {
1799 channel0=0;
1800 volume0=0;
1801 }
1802 if (channel1>1)
1803 {
1804 channel1=1;
1805 volume1=0;
1806 }
1807
1808 if (fam1_drive)
1809 {
1810 control0=channel0+1;
1811 control1=channel1+1;
1812 value0=(volume0>volume1)?volume0:volume1;
1813 value1=value0;
1814 if (volume0==0) control0=0;
1815 if (volume1==0) control1=0;
1816 drvcmd[0]=CMD1_SETMODE;
1817 drvcmd[1]=0x05;
1818 drvcmd[3]=control0;
1819 drvcmd[4]=value0;
1820 drvcmd[5]=control1;
1821 drvcmd[6]=value1;
1822 flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
1823 }
1824 else if (fam2_drive)
1825 {
1826 control0=channel0+1;
1827 control1=channel1+1;
1828 value0=(volume0>volume1)?volume0:volume1;
1829 value1=value0;
1830 if (volume0==0) control0=0;
1831 if (volume1==0) control1=0;
1832 drvcmd[0]=CMD2_SETMODE;
1833 drvcmd[1]=0x0E;
1834 drvcmd[3]=control0;
1835 drvcmd[4]=value0;
1836 drvcmd[5]=control1;
1837 drvcmd[6]=value1;
1838 flags_cmd_out=f_putcmd|f_ResponseStatus;
1839 }
1840 else if (famL_drive)
1841 {
1842 if ((volume0==0)||(channel0!=0)) control0 |= 0x80;
1843 if ((volume1==0)||(channel1!=1)) control0 |= 0x40;
1844 if (volume0|volume1) value0=0x80;
1845 drvcmd[0]=CMDL_SETMODE;
1846 drvcmd[1]=0x03;
1847 drvcmd[4]=control0;
1848 drvcmd[5]=value0;
1849 flags_cmd_out=f_putcmd|f_lopsta|f_getsta|f_ResponseStatus|f_obey_p_check|f_bit1;
1850 }
1851 else if (fam0_drive) /* different firmware levels */
1852 {
1853 if (current_drive->drv_type>=drv_300)
1854 {
1855 control0=volume0&0xFC;
1856 value0=volume1&0xFC;
1857 if ((volume0!=0)&&(volume0<4)) control0 |= 0x04;
1858 if ((volume1!=0)&&(volume1<4)) value0 |= 0x04;
1859 if (channel0!=0) control0 |= 0x01;
1860 if (channel1==1) value0 |= 0x01;
1861 }
1862 else
1863 {
1864 value0=(volume0>volume1)?volume0:volume1;
1865 if (current_drive->drv_type<drv_211)
1866 {
1867 if (channel0!=0)
1868 {
1869 i=channel1;
1870 channel1=channel0;
1871 channel0=i;
1872 i=volume1;
1873 volume1=volume0;
1874 volume0=i;
1875 }
1876 if (channel0==channel1)
1877 {
1878 if (channel0==0)
1879 {
1880 channel1=1;
1881 volume1=0;
1882 volume0=value0;
1883 }
1884 else
1885 {
1886 channel0=0;
1887 volume0=0;
1888 volume1=value0;
1889 }
1890 }
1891 }
1892
1893 if ((volume0!=0)&&(volume1!=0))
1894 {
1895 if (volume0==0xFF) volume1=0xFF;
1896 else if (volume1==0xFF) volume0=0xFF;
1897 }
1898 else if (current_drive->drv_type<drv_201) volume0=volume1=value0;
1899
1900 if (current_drive->drv_type>=drv_201)
1901 {
1902 if (volume0==0) control0 |= 0x80;
1903 if (volume1==0) control0 |= 0x40;
1904 }
1905 if (current_drive->drv_type>=drv_211)
1906 {
1907 if (channel0!=0) control0 |= 0x20;
1908 if (channel1!=1) control0 |= 0x10;
1909 }
1910 }
1911 drvcmd[0]=CMD0_SETMODE;
1912 drvcmd[1]=0x83;
1913 drvcmd[4]=control0;
1914 drvcmd[5]=value0;
1915 flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
1916 }
1917 else if (famT_drive)
1918 {
1919 current_drive->volume_control=0;
1920 if (!volume0) current_drive->volume_control|=0x10;
1921 if (!volume1) current_drive->volume_control|=0x20;
1922 i=cc_prep_mode_T();
1923 if (i<0) return (i);
1924 }
1925 if (!famT_drive)
1926 {
1927 response_count=0;
1928 i=cmd_out();
1929 if (i<0) return (i);
1930 }
1931 current_drive->diskstate_flags |= volume_bit;
1932 return (0);
1933}
1934/*==========================================================================*/
1935static int GetStatus(void)
1936{
1937 int i;
1938
1939 if (famT_drive) return (0);
1940 flags_cmd_out=f_getsta|f_ResponseStatus|f_obey_p_check;
1941 response_count=0;
1942 cmd_type=0;
1943 i=cmd_out();
1944 return (i);
1945}
1946/*==========================================================================*/
1947static int cc_DriveReset(void)
1948{
1949 int i;
1950
1951 msg(DBG_RES,"cc_DriveReset called.\n");
1952 clr_cmdbuf();
1953 response_count=0;
1954 if (fam0LV_drive) OUT(CDo_reset,0x00);
1955 else if (fam1_drive)
1956 {
1957 drvcmd[0]=CMD1_RESET;
1958 flags_cmd_out=f_putcmd;
1959 i=cmd_out();
1960 }
1961 else if (fam2_drive)
1962 {
1963 drvcmd[0]=CMD2_RESET;
1964 flags_cmd_out=f_putcmd;
1965 i=cmd_out();
1966 OUT(CDo_reset,0x00);
1967 }
1968 else if (famT_drive)
1969 {
1970 OUT(CDo_sel_i_d,0);
1971 OUT(CDo_enable,current_drive->drv_sel);
1972 OUT(CDo_command,CMDT_RESET);
1973 for (i=1;i<10;i++) OUT(CDo_command,0);
1974 }
1975 if (fam0LV_drive) sbp_sleep(5*HZ); /* wait 5 seconds */
1976 else sbp_sleep(1*HZ); /* wait a second */
1977#if 1
1978 if (famT_drive)
1979 {
1980 msg(DBG_TEA, "================CMDT_RESET given=================.\n");
1981 sbp_sleep(3*HZ);
1982 }
1983#endif /* 1 */
1984 flush_status();
1985 i=GetStatus();
1986 if (i<0) return i;
1987 if (!famT_drive)
1988 if (current_drive->error_byte!=aud_12) return -501;
1989 return (0);
1990}
1991
1992/*==========================================================================*/
1993static int SetSpeed(void)
1994{
1995 int i, speed;
1996
1997 if (!(current_drive->drv_options&(speed_auto|speed_300|speed_150))) return (0);
1998 speed=speed_auto;
1999 if (!(current_drive->drv_options&speed_auto))
2000 {
2001 speed |= speed_300;
2002 if (!(current_drive->drv_options&speed_300)) speed=0;
2003 }
2004 i=cc_SetSpeed(speed,0,0);
2005 return (i);
2006}
2007
2008static void switch_drive(struct sbpcd_drive *);
2009
2010static int sbpcd_select_speed(struct cdrom_device_info *cdi, int speed)
2011{
2012 struct sbpcd_drive *p = cdi->handle;
2013 if (p != current_drive)
2014 switch_drive(p);
2015
2016 return cc_SetSpeed(speed == 2 ? speed_300 : speed_150, 0, 0);
2017}
2018
2019/*==========================================================================*/
2020static int DriveReset(void)
2021{
2022 int i;
2023
2024 i=cc_DriveReset();
2025 if (i<0) return (-22);
2026 do
2027 {
2028 i=GetStatus();
2029 if ((i<0)&&(i!=-ERR_DISKCHANGE)) {
2030 return (-2); /* from sta2err */
2031 }
2032 if (!st_caddy_in) break;
2033 sbp_sleep(1);
2034 }
2035 while (!st_diskok);
2036#if 000
2037 current_drive->CD_changed=1;
2038#endif
2039 if ((st_door_closed) && (st_caddy_in))
2040 {
2041 i=DiskInfo();
2042 if (i<0) return (-23);
2043 }
2044 return (0);
2045}
2046
2047static int sbpcd_reset(struct cdrom_device_info *cdi)
2048{
2049 struct sbpcd_drive *p = cdi->handle;
2050 if (p != current_drive)
2051 switch_drive(p);
2052 return DriveReset();
2053}
2054
2055/*==========================================================================*/
2056static int cc_PlayAudio(int pos_audio_start,int pos_audio_end)
2057{
2058 int i, j, n;
2059
2060 if (current_drive->audio_state==audio_playing) return (-EINVAL);
2061 clr_cmdbuf();
2062 response_count=0;
2063 if (famLV_drive)
2064 {
2065 drvcmd[0]=CMDL_PLAY;
2066 i=msf2blk(pos_audio_start);
2067 n=msf2blk(pos_audio_end)+1-i;
2068 drvcmd[1]=(i>>16)&0x00FF;
2069 drvcmd[2]=(i>>8)&0x00FF;
2070 drvcmd[3]=i&0x00FF;
2071 drvcmd[4]=(n>>16)&0x00FF;
2072 drvcmd[5]=(n>>8)&0x00FF;
2073 drvcmd[6]=n&0x00FF;
2074 if (famL_drive)
2075 flags_cmd_out = f_putcmd | f_respo2 | f_lopsta | f_getsta |
2076 f_ResponseStatus | f_obey_p_check | f_wait_if_busy;
2077 else
2078 flags_cmd_out = f_putcmd;
2079 }
2080 else
2081 {
2082 j=1;
2083 if (fam1_drive)
2084 {
2085 drvcmd[0]=CMD1_PLAY_MSF;
2086 flags_cmd_out = f_putcmd | f_respo2 | f_ResponseStatus |
2087 f_obey_p_check | f_wait_if_busy;
2088 }
2089 else if (fam2_drive)
2090 {
2091 drvcmd[0]=CMD2_PLAY_MSF;
2092 flags_cmd_out = f_putcmd | f_ResponseStatus | f_obey_p_check;
2093 }
2094 else if (famT_drive)
2095 {
2096 drvcmd[0]=CMDT_PLAY_MSF;
2097 j=3;
2098 response_count=1;
2099 }
2100 else if (fam0_drive)
2101 {
2102 drvcmd[0]=CMD0_PLAY_MSF;
2103 flags_cmd_out = f_putcmd | f_respo2 | f_lopsta | f_getsta |
2104 f_ResponseStatus | f_obey_p_check | f_wait_if_busy;
2105 }
2106 drvcmd[j]=(pos_audio_start>>16)&0x00FF;
2107 drvcmd[j+1]=(pos_audio_start>>8)&0x00FF;
2108 drvcmd[j+2]=pos_audio_start&0x00FF;
2109 drvcmd[j+3]=(pos_audio_end>>16)&0x00FF;
2110 drvcmd[j+4]=(pos_audio_end>>8)&0x00FF;
2111 drvcmd[j+5]=pos_audio_end&0x00FF;
2112 }
2113 i=cmd_out();
2114 return (i);
2115}
2116/*==========================================================================*/
2117static int cc_Pause_Resume(int pau_res)
2118{
2119 int i;
2120
2121 clr_cmdbuf();
2122 response_count=0;
2123 if (fam1_drive)
2124 {
2125 drvcmd[0]=CMD1_PAU_RES;
2126 if (pau_res!=1) drvcmd[1]=0x80;
2127 flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check;
2128 }
2129 else if (fam2_drive)
2130 {
2131 drvcmd[0]=CMD2_PAU_RES;
2132 if (pau_res!=1) drvcmd[2]=0x01;
2133 flags_cmd_out=f_putcmd|f_ResponseStatus;
2134 }
2135 else if (fam0LV_drive)
2136 {
2137 drvcmd[0]=CMD0_PAU_RES;
2138 if (pau_res!=1) drvcmd[1]=0x80;
2139 if (famL_drive)
2140 flags_cmd_out=f_putcmd|f_respo2|f_lopsta|f_getsta|f_ResponseStatus|
2141 f_obey_p_check|f_bit1;
2142 else if (famV_drive)
2143 flags_cmd_out=f_putcmd;
2144 else
2145 flags_cmd_out=f_putcmd|f_respo2|f_lopsta|f_getsta|f_ResponseStatus|
2146 f_obey_p_check;
2147 }
2148 else if (famT_drive)
2149 {
2150 if (pau_res==3) return (cc_PlayAudio(current_drive->pos_audio_start,current_drive->pos_audio_end));
2151 else if (pau_res==1) drvcmd[0]=CMDT_PAUSE;
2152 else return (-56);
2153 }
2154 i=cmd_out();
2155 return (i);
2156}
2157/*==========================================================================*/
2158static int cc_LockDoor(char lock)
2159{
2160 int i;
2161
2162 if (fam0_drive) return (0);
2163 msg(DBG_LCK,"cc_LockDoor: %d (drive %d)\n", lock, current_drive - D_S);
2164 msg(DBG_LCS,"p_door_locked bit %d before\n", st_door_locked);
2165 clr_cmdbuf();
2166 response_count=0;
2167 if (fam1_drive)
2168 {
2169 drvcmd[0]=CMD1_LOCK_CTL;
2170 if (lock==1) drvcmd[1]=0x01;
2171 flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
2172 }
2173 else if (fam2_drive)
2174 {
2175 drvcmd[0]=CMD2_LOCK_CTL;
2176 if (lock==1) drvcmd[4]=0x01;
2177 flags_cmd_out=f_putcmd|f_ResponseStatus;
2178 }
2179 else if (famLV_drive)
2180 {
2181 drvcmd[0]=CMDL_LOCK_CTL;
2182 if (lock==1) drvcmd[1]=0x01;
2183 if (famL_drive)
2184 flags_cmd_out=f_putcmd|f_respo2|f_lopsta|f_getsta|f_ResponseStatus|f_obey_p_check|f_bit1;
2185 else
2186 flags_cmd_out=f_putcmd;
2187 }
2188 else if (famT_drive)
2189 {
2190 drvcmd[0]=CMDT_LOCK_CTL;
2191 if (lock==1) drvcmd[4]=0x01;
2192 }
2193 i=cmd_out();
2194 msg(DBG_LCS,"p_door_locked bit %d after\n", st_door_locked);
2195 return (i);
2196}
2197/*==========================================================================*/
2198/*==========================================================================*/
2199static int UnLockDoor(void)
2200{
2201 int i,j;
2202
2203 j=20;
2204 do
2205 {
2206 i=cc_LockDoor(0);
2207 --j;
2208 sbp_sleep(1);
2209 }
2210 while ((i<0)&&(j));
2211 if (i<0)
2212 {
2213 cc_DriveReset();
2214 return -84;
2215 }
2216 return (0);
2217}
2218/*==========================================================================*/
2219static int LockDoor(void)
2220{
2221 int i,j;
2222
2223 j=20;
2224 do
2225 {
2226 i=cc_LockDoor(1);
2227 --j;
2228 sbp_sleep(1);
2229 }
2230 while ((i<0)&&(j));
2231 if (j==0)
2232 {
2233 cc_DriveReset();
2234 j=20;
2235 do
2236 {
2237 i=cc_LockDoor(1);
2238 --j;
2239 sbp_sleep(1);
2240 }
2241 while ((i<0)&&(j));
2242 }
2243 return (i);
2244}
2245
2246static int sbpcd_lock_door(struct cdrom_device_info *cdi, int lock)
2247{
2248 return lock ? LockDoor() : UnLockDoor();
2249}
2250
2251/*==========================================================================*/
2252static int cc_CloseTray(void)
2253{
2254 int i;
2255
2256 if (fam0_drive) return (0);
2257 msg(DBG_LCK,"cc_CloseTray (drive %d)\n", current_drive - D_S);
2258 msg(DBG_LCS,"p_door_closed bit %d before\n", st_door_closed);
2259
2260 clr_cmdbuf();
2261 response_count=0;
2262 if (fam1_drive)
2263 {
2264 drvcmd[0]=CMD1_TRAY_CTL;
2265 flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check;
2266 }
2267 else if (fam2_drive)
2268 {
2269 drvcmd[0]=CMD2_TRAY_CTL;
2270 drvcmd[1]=0x01;
2271 drvcmd[4]=0x03; /* "insert" */
2272 flags_cmd_out=f_putcmd|f_ResponseStatus;
2273 }
2274 else if (famLV_drive)
2275 {
2276 drvcmd[0]=CMDL_TRAY_CTL;
2277 if (famLV_drive)
2278 flags_cmd_out=f_putcmd|f_respo2|f_lopsta|f_getsta|
2279 f_ResponseStatus|f_obey_p_check|f_bit1;
2280 else
2281 flags_cmd_out=f_putcmd;
2282 }
2283 else if (famT_drive)
2284 {
2285 drvcmd[0]=CMDT_TRAY_CTL;
2286 drvcmd[4]=0x03; /* "insert" */
2287 }
2288 i=cmd_out();
2289 msg(DBG_LCS,"p_door_closed bit %d after\n", st_door_closed);
2290
2291 i=cc_ReadError();
2292 flags_cmd_out |= f_respo2;
2293 cc_ReadStatus(); /* command: give 1-byte status */
2294 i=ResponseStatus();
2295 if (famT_drive&&(i<0))
2296 {
2297 cc_DriveReset();
2298 i=ResponseStatus();
2299#if 0
2300 sbp_sleep(HZ);
2301#endif /* 0 */
2302 i=ResponseStatus();
2303 }
2304 if (i<0)
2305 {
2306 msg(DBG_INF,"sbpcd cc_CloseTray: ResponseStatus timed out (%d).\n",i);
2307 }
2308 if (!(famT_drive))
2309 {
2310 if (!st_spinning)
2311 {
2312 cc_SpinUp();
2313 if (st_check) i=cc_ReadError();
2314 flags_cmd_out |= f_respo2;
2315 cc_ReadStatus();
2316 i=ResponseStatus();
2317 } else {
2318 }
2319 }
2320 i=DiskInfo();
2321 return (i);
2322}
2323
2324static int sbpcd_tray_move(struct cdrom_device_info *cdi, int position)
2325{
2326 int retval=0;
2327 switch_drive(cdi->handle);
2328 /* DUH! --AJK */
2329 if(current_drive->CD_changed != 0xFF) {
2330 current_drive->CD_changed=0xFF;
2331 current_drive->diskstate_flags &= ~cd_size_bit;
2332 }
2333 if (position == 1) {
2334 cc_SpinDown();
2335 } else {
2336 retval=cc_CloseTray();
2337 }
2338 return retval;
2339}
2340
2341/*==========================================================================*/
2342static int cc_ReadSubQ(void)
2343{
2344 int i,j;
2345
2346 current_drive->diskstate_flags &= ~subq_bit;
2347 for (j=255;j>0;j--)
2348 {
2349 clr_cmdbuf();
2350 if (fam1_drive)
2351 {
2352 drvcmd[0]=CMD1_READSUBQ;
2353 flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
2354 response_count=11;
2355 }
2356 else if (fam2_drive)
2357 {
2358 drvcmd[0]=CMD2_READSUBQ;
2359 drvcmd[1]=0x02;
2360 drvcmd[3]=0x01;
2361 flags_cmd_out=f_putcmd;
2362 response_count=10;
2363 }
2364 else if (fam0LV_drive)
2365 {
2366 drvcmd[0]=CMD0_READSUBQ;
2367 drvcmd[1]=0x02;
2368 if (famLV_drive)
2369 flags_cmd_out=f_putcmd;
2370 else
2371 flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
2372 response_count=13;
2373 }
2374 else if (famT_drive)
2375 {
2376 response_count=12;
2377 drvcmd[0]=CMDT_READSUBQ;
2378 drvcmd[1]=0x02;
2379 drvcmd[2]=0x40;
2380 drvcmd[3]=0x01;
2381 drvcmd[8]=response_count;
2382 }
2383 i=cmd_out();
2384 if (i<0) return (i);
2385 for (i=0;i<response_count;i++)
2386 {
2387 sprintf(&msgbuf[i*3], " %02X", infobuf[i]);
2388 msgbuf[i*3]=0;
2389 msg(DBG_SQ1,"cc_ReadSubQ:%s\n", msgbuf);
2390 }
2391 if (famT_drive) break;
2392 if (infobuf[0]!=0) break;
2393 if ((!st_spinning) || (j==1))
2394 {
2395 current_drive->SubQ_ctl_adr=current_drive->SubQ_trk=current_drive->SubQ_pnt_idx=current_drive->SubQ_whatisthis=0;
2396 current_drive->SubQ_run_tot=current_drive->SubQ_run_trk=0;
2397 return (0);
2398 }
2399 }
2400 if (famT_drive) current_drive->SubQ_ctl_adr=infobuf[1];
2401 else current_drive->SubQ_ctl_adr=swap_nibbles(infobuf[1]);
2402 current_drive->SubQ_trk=byt2bcd(infobuf[2]);
2403 current_drive->SubQ_pnt_idx=byt2bcd(infobuf[3]);
2404 if (fam0LV_drive) i=5;
2405 else if (fam12_drive) i=4;
2406 else if (famT_drive) i=8;
2407 current_drive->SubQ_run_tot=make32(make16(0,infobuf[i]),make16(infobuf[i+1],infobuf[i+2])); /* msf-bin */
2408 i=7;
2409 if (fam0LV_drive) i=9;
2410 else if (fam12_drive) i=7;
2411 else if (famT_drive) i=4;
2412 current_drive->SubQ_run_trk=make32(make16(0,infobuf[i]),make16(infobuf[i+1],infobuf[i+2])); /* msf-bin */
2413 current_drive->SubQ_whatisthis=infobuf[i+3];
2414 current_drive->diskstate_flags |= subq_bit;
2415 return (0);
2416}
2417/*==========================================================================*/
2418static int cc_ModeSense(void)
2419{
2420 int i;
2421
2422 if (fam2_drive) return (0);
2423 if (famV_drive) return (0);
2424 current_drive->diskstate_flags &= ~frame_size_bit;
2425 clr_cmdbuf();
2426 if (fam1_drive)
2427 {
2428 response_count=5;
2429 drvcmd[0]=CMD1_GETMODE;
2430 flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
2431 }
2432 else if (fam0L_drive)
2433 {
2434 response_count=2;
2435 drvcmd[0]=CMD0_GETMODE;
2436 if (famL_drive) flags_cmd_out=f_putcmd;
2437 else flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
2438 }
2439 else if (famT_drive)
2440 {
2441 response_count=10;
2442 drvcmd[0]=CMDT_GETMODE;
2443 drvcmd[4]=response_count;
2444 }
2445 i=cmd_out();
2446 if (i<0) return (i);
2447 i=0;
2448 current_drive->sense_byte=0;
2449 if (fam1_drive) current_drive->sense_byte=infobuf[i++];
2450 else if (famT_drive)
2451 {
2452 if (infobuf[4]==0x01) current_drive->xa_byte=0x20;
2453 else current_drive->xa_byte=0;
2454 i=2;
2455 }
2456 current_drive->frame_size=make16(infobuf[i],infobuf[i+1]);
2457 for (i=0;i<response_count;i++)
2458 sprintf(&msgbuf[i*3], " %02X", infobuf[i]);
2459 msgbuf[i*3]=0;
2460 msg(DBG_XA1,"cc_ModeSense:%s\n", msgbuf);
2461
2462 current_drive->diskstate_flags |= frame_size_bit;
2463 return (0);
2464}
2465/*==========================================================================*/
2466/*==========================================================================*/
2467static int cc_ModeSelect(int framesize)
2468{
2469 int i;
2470
2471 if (fam2_drive) return (0);
2472 if (famV_drive) return (0);
2473 current_drive->diskstate_flags &= ~frame_size_bit;
2474 clr_cmdbuf();
2475 current_drive->frame_size=framesize;
2476 if (framesize==CD_FRAMESIZE_RAW) current_drive->sense_byte=0x82;
2477 else current_drive->sense_byte=0x00;
2478
2479 msg(DBG_XA1,"cc_ModeSelect: %02X %04X\n",
2480 current_drive->sense_byte, current_drive->frame_size);
2481
2482 if (fam1_drive)
2483 {
2484 drvcmd[0]=CMD1_SETMODE;
2485 drvcmd[1]=0x00;
2486 drvcmd[2]=current_drive->sense_byte;
2487 drvcmd[3]=(current_drive->frame_size>>8)&0xFF;
2488 drvcmd[4]=current_drive->frame_size&0xFF;
2489 flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
2490 }
2491 else if (fam0L_drive)
2492 {
2493 drvcmd[0]=CMD0_SETMODE;
2494 drvcmd[1]=0x00;
2495 drvcmd[2]=(current_drive->frame_size>>8)&0xFF;
2496 drvcmd[3]=current_drive->frame_size&0xFF;
2497 drvcmd[4]=0x00;
2498 if(famL_drive)
2499 flags_cmd_out=f_putcmd|f_lopsta|f_getsta|f_ResponseStatus|f_obey_p_check;
2500 else
2501 flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
2502 }
2503 else if (famT_drive)
2504 {
2505 return (-1);
2506 }
2507 response_count=0;
2508 i=cmd_out();
2509 if (i<0) return (i);
2510 current_drive->diskstate_flags |= frame_size_bit;
2511 return (0);
2512}
2513/*==========================================================================*/
2514static int cc_GetVolume(void)
2515{
2516 int i;
2517 u_char switches;
2518 u_char chan0=0;
2519 u_char vol0=0;
2520 u_char chan1=1;
2521 u_char vol1=0;
2522
2523 if (famV_drive) return (0);
2524 current_drive->diskstate_flags &= ~volume_bit;
2525 clr_cmdbuf();
2526 if (fam1_drive)
2527 {
2528 drvcmd[0]=CMD1_GETMODE;
2529 drvcmd[1]=0x05;
2530 response_count=5;
2531 flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
2532 }
2533 else if (fam2_drive)
2534 {
2535 drvcmd[0]=CMD2_GETMODE;
2536 drvcmd[1]=0x0E;
2537 response_count=5;
2538 flags_cmd_out=f_putcmd;
2539 }
2540 else if (fam0L_drive)
2541 {
2542 drvcmd[0]=CMD0_GETMODE;
2543 drvcmd[1]=0x03;
2544 response_count=2;
2545 if(famL_drive)
2546 flags_cmd_out=f_putcmd;
2547 else
2548 flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
2549 }
2550 else if (famT_drive)
2551 {
2552 i=cc_get_mode_T();
2553 if (i<0) return (i);
2554 }
2555 if (!famT_drive)
2556 {
2557 i=cmd_out();
2558 if (i<0) return (i);
2559 }
2560 if (fam1_drive)
2561 {
2562 chan0=infobuf[1]&0x0F;
2563 vol0=infobuf[2];
2564 chan1=infobuf[3]&0x0F;
2565 vol1=infobuf[4];
2566 if (chan0==0)
2567 {
2568 chan0=1;
2569 vol0=0;
2570 }
2571 if (chan1==0)
2572 {
2573 chan1=2;
2574 vol1=0;
2575 }
2576 chan0 >>= 1;
2577 chan1 >>= 1;
2578 }
2579 else if (fam2_drive)
2580 {
2581 chan0=infobuf[1];
2582 vol0=infobuf[2];
2583 chan1=infobuf[3];
2584 vol1=infobuf[4];
2585 }
2586 else if (famL_drive)
2587 {
2588 chan0=0;
2589 chan1=1;
2590 vol0=vol1=infobuf[1];
2591 switches=infobuf[0];
2592 if ((switches&0x80)!=0) chan0=1;
2593 if ((switches&0x40)!=0) chan1=0;
2594 }
2595 else if (fam0_drive) /* different firmware levels */
2596 {
2597 chan0=0;
2598 chan1=1;
2599 vol0=vol1=infobuf[1];
2600 if (current_drive->drv_type>=drv_201)
2601 {
2602 if (current_drive->drv_type<drv_300)
2603 {
2604 switches=infobuf[0];
2605 if ((switches&0x80)!=0) vol0=0;
2606 if ((switches&0x40)!=0) vol1=0;
2607 if (current_drive->drv_type>=drv_211)
2608 {
2609 if ((switches&0x20)!=0) chan0=1;
2610 if ((switches&0x10)!=0) chan1=0;
2611 }
2612 }
2613 else
2614 {
2615 vol0=infobuf[0];
2616 if ((vol0&0x01)!=0) chan0=1;
2617 if ((vol1&0x01)==0) chan1=0;
2618 vol0 &= 0xFC;
2619 vol1 &= 0xFC;
2620 if (vol0!=0) vol0 += 3;
2621 if (vol1!=0) vol1 += 3;
2622 }
2623 }
2624 }
2625 else if (famT_drive)
2626 {
2627 current_drive->volume_control=infobuf[7];
2628 chan0=0;
2629 chan1=1;
2630 if (current_drive->volume_control&0x10) vol0=0;
2631 else vol0=0xff;
2632 if (current_drive->volume_control&0x20) vol1=0;
2633 else vol1=0xff;
2634 }
2635 current_drive->vol_chan0=chan0;
2636 current_drive->vol_ctrl0=vol0;
2637 current_drive->vol_chan1=chan1;
2638 current_drive->vol_ctrl1=vol1;
2639#if 000
2640 current_drive->vol_chan2=2;
2641 current_drive->vol_ctrl2=0xFF;
2642 current_drive->vol_chan3=3;
2643 current_drive->vol_ctrl3=0xFF;
2644#endif /* 000 */
2645 current_drive->diskstate_flags |= volume_bit;
2646 return (0);
2647}
2648/*==========================================================================*/
2649static int cc_ReadCapacity(void)
2650{
2651 int i, j;
2652
2653 if (fam2_drive) return (0); /* some firmware lacks this command */
2654 if (famLV_drive) return (0); /* some firmware lacks this command */
2655 if (famT_drive) return (0); /* done with cc_ReadTocDescr() */
2656 current_drive->diskstate_flags &= ~cd_size_bit;
2657 for (j=3;j>0;j--)
2658 {
2659 clr_cmdbuf();
2660 if (fam1_drive)
2661 {
2662 drvcmd[0]=CMD1_CAPACITY;
2663 response_count=5;
2664 flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
2665 }
2666#if 00
2667 else if (fam2_drive)
2668 {
2669 drvcmd[0]=CMD2_CAPACITY;
2670 response_count=8;
2671 flags_cmd_out=f_putcmd;
2672 }
2673#endif
2674 else if (fam0_drive)
2675 {
2676 drvcmd[0]=CMD0_CAPACITY;
2677 response_count=5;
2678 flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
2679 }
2680 i=cmd_out();
2681 if (i>=0) break;
2682 msg(DBG_000,"cc_ReadCapacity: cmd_out: err %d\n", i);
2683 cc_ReadError();
2684 }
2685 if (j==0) return (i);
2686 if (fam1_drive) current_drive->CDsize_frm=msf2blk(make32(make16(0,infobuf[0]),make16(infobuf[1],infobuf[2])))+CD_MSF_OFFSET;
2687 else if (fam0_drive) current_drive->CDsize_frm=make32(make16(0,infobuf[0]),make16(infobuf[1],infobuf[2]));
2688#if 00
2689 else if (fam2_drive) current_drive->CDsize_frm=make32(make16(infobuf[0],infobuf[1]),make16(infobuf[2],infobuf[3]));
2690#endif
2691 current_drive->diskstate_flags |= cd_size_bit;
2692 msg(DBG_000,"cc_ReadCapacity: %d frames.\n", current_drive->CDsize_frm);
2693 return (0);
2694}
2695/*==========================================================================*/
2696static int cc_ReadTocDescr(void)
2697{
2698 int i;
2699
2700 current_drive->diskstate_flags &= ~toc_bit;
2701 clr_cmdbuf();
2702 if (fam1_drive)
2703 {
2704 drvcmd[0]=CMD1_DISKINFO;
2705 response_count=6;
2706 flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
2707 }
2708 else if (fam0LV_drive)
2709 {
2710 drvcmd[0]=CMD0_DISKINFO;
2711 response_count=6;
2712 if(famLV_drive)
2713 flags_cmd_out=f_putcmd;
2714 else
2715 flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
2716 }
2717 else if (fam2_drive)
2718 {
2719 /* possibly longer timeout periods necessary */
2720 current_drive->f_multisession=0;
2721 drvcmd[0]=CMD2_DISKINFO;
2722 drvcmd[1]=0x02;
2723 drvcmd[2]=0xAB;
2724 drvcmd[3]=0xFF; /* session */
2725 response_count=8;
2726 flags_cmd_out=f_putcmd;
2727 }
2728 else if (famT_drive)
2729 {
2730 current_drive->f_multisession=0;
2731 response_count=12;
2732 drvcmd[0]=CMDT_DISKINFO;
2733 drvcmd[1]=0x02;
2734 drvcmd[6]=CDROM_LEADOUT;
2735 drvcmd[8]=response_count;
2736 drvcmd[9]=0x00;
2737 }
2738 i=cmd_out();
2739 if (i<0) return (i);
2740 if ((famT_drive)&&(i<response_count)) return (-100-i);
2741 if ((fam1_drive)||(fam2_drive)||(fam0LV_drive))
2742 current_drive->xa_byte=infobuf[0];
2743 if (fam2_drive)
2744 {
2745 current_drive->first_session=infobuf[1];
2746 current_drive->last_session=infobuf[2];
2747 current_drive->n_first_track=infobuf[3];
2748 current_drive->n_last_track=infobuf[4];
2749 if (current_drive->first_session!=current_drive->last_session)
2750 {
2751 current_drive->f_multisession=1;
2752 current_drive->lba_multi=msf2blk(make32(make16(0,infobuf[5]),make16(infobuf[6],infobuf[7])));
2753 }
2754#if 0
2755 if (current_drive->first_session!=current_drive->last_session)
2756 {
2757 if (current_drive->last_session<=20)
2758 zwanzig=current_drive->last_session+1;
2759 else zwanzig=20;
2760 for (count=current_drive->first_session;count<zwanzig;count++)
2761 {
2762 drvcmd[0]=CMD2_DISKINFO;
2763 drvcmd[1]=0x02;
2764 drvcmd[2]=0xAB;
2765 drvcmd[3]=count;
2766 response_count=8;
2767 flags_cmd_out=f_putcmd;
2768 i=cmd_out();
2769 if (i<0) return (i);
2770 current_drive->msf_multi_n[count]=make32(make16(0,infobuf[5]),make16(infobuf[6],infobuf[7]));
2771 }
2772 current_drive->diskstate_flags |= multisession_bit;
2773 }
2774#endif
2775 drvcmd[0]=CMD2_DISKINFO;
2776 drvcmd[1]=0x02;
2777 drvcmd[2]=0xAA;
2778 drvcmd[3]=0xFF;
2779 response_count=5;
2780 flags_cmd_out=f_putcmd;
2781 i=cmd_out();
2782 if (i<0) return (i);
2783 current_drive->size_msf=make32(make16(0,infobuf[2]),make16(infobuf[3],infobuf[4]));
2784 current_drive->size_blk=msf2blk(current_drive->size_msf);
2785 current_drive->CDsize_frm=current_drive->size_blk+1;
2786 }
2787 else if (famT_drive)
2788 {
2789 current_drive->size_msf=make32(make16(infobuf[8],infobuf[9]),make16(infobuf[10],infobuf[11]));
2790 current_drive->size_blk=msf2blk(current_drive->size_msf);
2791 current_drive->CDsize_frm=current_drive->size_blk+1;
2792 current_drive->n_first_track=infobuf[2];
2793 current_drive->n_last_track=infobuf[3];
2794 }
2795 else
2796 {
2797 current_drive->n_first_track=infobuf[1];
2798 current_drive->n_last_track=infobuf[2];
2799 current_drive->size_msf=make32(make16(0,infobuf[3]),make16(infobuf[4],infobuf[5]));
2800 current_drive->size_blk=msf2blk(current_drive->size_msf);
2801 if (famLV_drive) current_drive->CDsize_frm=current_drive->size_blk+1;
2802 }
2803 current_drive->diskstate_flags |= toc_bit;
2804 msg(DBG_TOC,"TocDesc: xa %02X firstt %02X lastt %02X size %08X firstses %02X lastsess %02X\n",
2805 current_drive->xa_byte,
2806 current_drive->n_first_track,
2807 current_drive->n_last_track,
2808 current_drive->size_msf,
2809 current_drive->first_session,
2810 current_drive->last_session);
2811 return (0);
2812}
2813/*==========================================================================*/
2814static int cc_ReadTocEntry(int num)
2815{
2816 int i;
2817
2818 clr_cmdbuf();
2819 if (fam1_drive)
2820 {
2821 drvcmd[0]=CMD1_READTOC;
2822 drvcmd[2]=num;
2823 response_count=8;
2824 flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
2825 }
2826 else if (fam2_drive)
2827 {
2828 /* possibly longer timeout periods necessary */
2829 drvcmd[0]=CMD2_DISKINFO;
2830 drvcmd[1]=0x02;
2831 drvcmd[2]=num;
2832 response_count=5;
2833 flags_cmd_out=f_putcmd;
2834 }
2835 else if (fam0LV_drive)
2836 {
2837 drvcmd[0]=CMD0_READTOC;
2838 drvcmd[1]=0x02;
2839 drvcmd[2]=num;
2840 response_count=8;
2841 if (famLV_drive)
2842 flags_cmd_out=f_putcmd;
2843 else
2844 flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
2845 }
2846 else if (famT_drive)
2847 {
2848 response_count=12;
2849 drvcmd[0]=CMDT_DISKINFO;
2850 drvcmd[1]=0x02;
2851 drvcmd[6]=num;
2852 drvcmd[8]=response_count;
2853 drvcmd[9]=0x00;
2854 }
2855 i=cmd_out();
2856 if (i<0) return (i);
2857 if ((famT_drive)&&(i<response_count)) return (-100-i);
2858 if ((fam1_drive)||(fam0LV_drive))
2859 {
2860 current_drive->TocEnt_nixbyte=infobuf[0];
2861 i=1;
2862 }
2863 else if (fam2_drive) i=0;
2864 else if (famT_drive) i=5;
2865 current_drive->TocEnt_ctl_adr=swap_nibbles(infobuf[i++]);
2866 if ((fam1_drive)||(fam0L_drive))
2867 {
2868 current_drive->TocEnt_number=infobuf[i++];
2869 current_drive->TocEnt_format=infobuf[i];
2870 }
2871 else
2872 {
2873 current_drive->TocEnt_number=num;
2874 current_drive->TocEnt_format=0;
2875 }
2876 if (fam1_drive) i=4;
2877 else if (fam0LV_drive) i=5;
2878 else if (fam2_drive) i=2;
2879 else if (famT_drive) i=9;
2880 current_drive->TocEnt_address=make32(make16(0,infobuf[i]),
2881 make16(infobuf[i+1],infobuf[i+2]));
2882 for (i=0;i<response_count;i++)
2883 sprintf(&msgbuf[i*3], " %02X", infobuf[i]);
2884 msgbuf[i*3]=0;
2885 msg(DBG_ECS,"TocEntry:%s\n", msgbuf);
2886 msg(DBG_TOC,"TocEntry: %02X %02X %02X %02X %08X\n",
2887 current_drive->TocEnt_nixbyte, current_drive->TocEnt_ctl_adr,
2888 current_drive->TocEnt_number, current_drive->TocEnt_format,
2889 current_drive->TocEnt_address);
2890 return (0);
2891}
2892/*==========================================================================*/
2893static int cc_ReadPacket(void)
2894{
2895 int i;
2896
2897 clr_cmdbuf();
2898 drvcmd[0]=CMD0_PACKET;
2899 drvcmd[1]=response_count;
2900 if(famL_drive) flags_cmd_out=f_putcmd;
2901 else if (fam01_drive)
2902 flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
2903 else if (fam2_drive) return (-1); /* not implemented yet */
2904 else if (famT_drive)
2905 {
2906 return (-1);
2907 }
2908 i=cmd_out();
2909 return (i);
2910}
2911/*==========================================================================*/
2912static int convert_UPC(u_char *p)
2913{
2914 int i;
2915
2916 p++;
2917 if (fam0L_drive) p[13]=0;
2918 for (i=0;i<7;i++)
2919 {
2920 if (fam1_drive) current_drive->UPC_buf[i]=swap_nibbles(*p++);
2921 else if (fam0L_drive)
2922 {
2923 current_drive->UPC_buf[i]=((*p++)<<4)&0xFF;
2924 current_drive->UPC_buf[i] |= *p++;
2925 }
2926 else if (famT_drive)
2927 {
2928 return (-1);
2929 }
2930 else /* CD200 */
2931 {
2932 return (-1);
2933 }
2934 }
2935 current_drive->UPC_buf[6] &= 0xF0;
2936 return (0);
2937}
2938/*==========================================================================*/
2939static int cc_ReadUPC(void)
2940{
2941 int i;
2942#if TEST_UPC
2943 int block, checksum;
2944#endif /* TEST_UPC */
2945
2946 if (fam2_drive) return (0); /* not implemented yet */
2947 if (famT_drive) return (0); /* not implemented yet */
2948 if (famV_drive) return (0); /* not implemented yet */
2949#if 1
2950 if (fam0_drive) return (0); /* but it should work */
2951#endif
2952
2953 current_drive->diskstate_flags &= ~upc_bit;
2954#if TEST_UPC
2955 for (block=CD_MSF_OFFSET+1;block<CD_MSF_OFFSET+200;block++)
2956 {
2957#endif /* TEST_UPC */
2958 clr_cmdbuf();
2959 if (fam1_drive)
2960 {
2961 drvcmd[0]=CMD1_READ_UPC;
2962#if TEST_UPC
2963 drvcmd[1]=(block>>16)&0xFF;
2964 drvcmd[2]=(block>>8)&0xFF;
2965 drvcmd[3]=block&0xFF;
2966#endif /* TEST_UPC */
2967 response_count=8;
2968 flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
2969 }
2970 else if (fam0L_drive)
2971 {
2972 drvcmd[0]=CMD0_READ_UPC;
2973#if TEST_UPC
2974 drvcmd[2]=(block>>16)&0xFF;
2975 drvcmd[3]=(block>>8)&0xFF;
2976 drvcmd[4]=block&0xFF;
2977#endif /* TEST_UPC */
2978 response_count=0;
2979 flags_cmd_out=f_putcmd|f_lopsta|f_getsta|f_ResponseStatus|f_obey_p_check|f_bit1;
2980 }
2981 else if (fam2_drive)
2982 {
2983 return (-1);
2984 }
2985 else if (famT_drive)
2986 {
2987 return (-1);
2988 }
2989 i=cmd_out();
2990 if (i<0)
2991 {
2992 msg(DBG_000,"cc_ReadUPC cmd_out: err %d\n", i);
2993 return (i);
2994 }
2995 if (fam0L_drive)
2996 {
2997 response_count=16;
2998 if (famL_drive) flags_cmd_out=f_putcmd;
2999 i=cc_ReadPacket();
3000 if (i<0)
3001 {
3002 msg(DBG_000,"cc_ReadUPC ReadPacket: err %d\n", i);
3003 return (i);
3004 }
3005 }
3006#if TEST_UPC
3007 checksum=0;
3008#endif /* TEST_UPC */
3009 for (i=0;i<(fam1_drive?8:16);i++)
3010 {
3011#if TEST_UPC
3012 checksum |= infobuf[i];
3013#endif /* TEST_UPC */
3014 sprintf(&msgbuf[i*3], " %02X", infobuf[i]);
3015 }
3016 msgbuf[i*3]=0;
3017 msg(DBG_UPC,"UPC info:%s\n", msgbuf);
3018#if TEST_UPC
3019 if ((checksum&0x7F)!=0) break;
3020 }
3021#endif /* TEST_UPC */
3022 current_drive->UPC_ctl_adr=0;
3023 if (fam1_drive) i=0;
3024 else i=2;
3025 if ((infobuf[i]&0x80)!=0)
3026 {
3027 convert_UPC(&infobuf[i]);
3028 current_drive->UPC_ctl_adr = (current_drive->TocEnt_ctl_adr & 0xF0) | 0x02;
3029 }
3030 for (i=0;i<7;i++)
3031 sprintf(&msgbuf[i*3], " %02X", current_drive->UPC_buf[i]);
3032 sprintf(&msgbuf[i*3], " (%02X)", current_drive->UPC_ctl_adr);
3033 msgbuf[i*3+5]=0;
3034 msg(DBG_UPC,"UPC code:%s\n", msgbuf);
3035 current_drive->diskstate_flags |= upc_bit;
3036 return (0);
3037}
3038
3039static int sbpcd_get_mcn(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn)
3040{
3041 int i;
3042 unsigned char *mcnp = mcn->medium_catalog_number;
3043 unsigned char *resp;
3044
3045 current_drive->diskstate_flags &= ~upc_bit;
3046 clr_cmdbuf();
3047 if (fam1_drive)
3048 {
3049 drvcmd[0]=CMD1_READ_UPC;
3050 response_count=8;
3051 flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
3052 }
3053 else if (fam0L_drive)
3054 {
3055 drvcmd[0]=CMD0_READ_UPC;
3056 response_count=0;
3057 flags_cmd_out=f_putcmd|f_lopsta|f_getsta|f_ResponseStatus|f_obey_p_check|f_bit1;
3058 }
3059 else if (fam2_drive)
3060 {
3061 return (-1);
3062 }
3063 else if (famT_drive)
3064 {
3065 return (-1);
3066 }
3067 i=cmd_out();
3068 if (i<0)
3069 {
3070 msg(DBG_000,"cc_ReadUPC cmd_out: err %d\n", i);
3071 return (i);
3072 }
3073 if (fam0L_drive)
3074 {
3075 response_count=16;
3076 if (famL_drive) flags_cmd_out=f_putcmd;
3077 i=cc_ReadPacket();
3078 if (i<0)
3079 {
3080 msg(DBG_000,"cc_ReadUPC ReadPacket: err %d\n", i);
3081 return (i);
3082 }
3083 }
3084 current_drive->UPC_ctl_adr=0;
3085 if (fam1_drive) i=0;
3086 else i=2;
3087
3088 resp = infobuf + i;
3089 if (*resp++ == 0x80) {
3090 /* packed bcd to single ASCII digits */
3091 *mcnp++ = (*resp >> 4) + '0';
3092 *mcnp++ = (*resp++ & 0x0f) + '0';
3093 *mcnp++ = (*resp >> 4) + '0';
3094 *mcnp++ = (*resp++ & 0x0f) + '0';
3095 *mcnp++ = (*resp >> 4) + '0';
3096 *mcnp++ = (*resp++ & 0x0f) + '0';
3097 *mcnp++ = (*resp >> 4) + '0';
3098 *mcnp++ = (*resp++ & 0x0f) + '0';
3099 *mcnp++ = (*resp >> 4) + '0';
3100 *mcnp++ = (*resp++ & 0x0f) + '0';
3101 *mcnp++ = (*resp >> 4) + '0';
3102 *mcnp++ = (*resp++ & 0x0f) + '0';
3103 *mcnp++ = (*resp >> 4) + '0';
3104 }
3105 *mcnp = '\0';
3106
3107 current_drive->diskstate_flags |= upc_bit;
3108 return (0);
3109}
3110
3111/*==========================================================================*/
3112static int cc_CheckMultiSession(void)
3113{
3114 int i;
3115
3116 if (fam2_drive) return (0);
3117 current_drive->f_multisession=0;
3118 current_drive->lba_multi=0;
3119 if (fam0_drive) return (0);
3120 clr_cmdbuf();
3121 if (fam1_drive)
3122 {
3123 drvcmd[0]=CMD1_MULTISESS;
3124 response_count=6;
3125 flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
3126 i=cmd_out();
3127 if (i<0) return (i);
3128 if ((infobuf[0]&0x80)!=0)
3129 {
3130 current_drive->f_multisession=1;
3131 current_drive->lba_multi=msf2blk(make32(make16(0,infobuf[1]),
3132 make16(infobuf[2],infobuf[3])));
3133 }
3134 }
3135 else if (famLV_drive)
3136 {
3137 drvcmd[0]=CMDL_MULTISESS;
3138 drvcmd[1]=3;
3139 drvcmd[2]=1;
3140 response_count=8;
3141 flags_cmd_out=f_putcmd;
3142 i=cmd_out();
3143 if (i<0) return (i);
3144 current_drive->lba_multi=msf2blk(make32(make16(0,infobuf[5]),
3145 make16(infobuf[6],infobuf[7])));
3146 }
3147 else if (famT_drive)
3148 {
3149 response_count=12;
3150 drvcmd[0]=CMDT_DISKINFO;
3151 drvcmd[1]=0x02;
3152 drvcmd[6]=0;
3153 drvcmd[8]=response_count;
3154 drvcmd[9]=0x40;
3155 i=cmd_out();
3156 if (i<0) return (i);
3157 if (i<response_count) return (-100-i);
3158 current_drive->first_session=infobuf[2];
3159 current_drive->last_session=infobuf[3];
3160 current_drive->track_of_last_session=infobuf[6];
3161 if (current_drive->first_session!=current_drive->last_session)
3162 {
3163 current_drive->f_multisession=1;
3164 current_drive->lba_multi=msf2blk(make32(make16(0,infobuf[9]),make16(infobuf[10],infobuf[11])));
3165 }
3166 }
3167 for (i=0;i<response_count;i++)
3168 sprintf(&msgbuf[i*3], " %02X", infobuf[i]);
3169 msgbuf[i*3]=0;
3170 msg(DBG_MUL,"MultiSession Info:%s (%d)\n", msgbuf, current_drive->lba_multi);
3171 if (current_drive->lba_multi>200)
3172 {
3173 current_drive->f_multisession=1;
3174 msg(DBG_MUL,"MultiSession base: %06X\n", current_drive->lba_multi);
3175 }
3176 return (0);
3177}
3178/*==========================================================================*/
3179#ifdef FUTURE
3180static int cc_SubChanInfo(int frame, int count, u_char *buffer)
3181 /* "frame" is a RED BOOK (msf-bin) address */
3182{
3183 int i;
3184
3185 if (fam0LV_drive) return (-ENOSYS); /* drive firmware lacks it */
3186 if (famT_drive)
3187 {
3188 return (-1);
3189 }
3190#if 0
3191 if (current_drive->audio_state!=audio_playing) return (-ENODATA);
3192#endif
3193 clr_cmdbuf();
3194 drvcmd[0]=CMD1_SUBCHANINF;
3195 drvcmd[1]=(frame>>16)&0xFF;
3196 drvcmd[2]=(frame>>8)&0xFF;
3197 drvcmd[3]=frame&0xFF;
3198 drvcmd[5]=(count>>8)&0xFF;
3199 drvcmd[6]=count&0xFF;
3200 flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check;
3201 cmd_type=READ_SC;
3202 current_drive->frame_size=CD_FRAMESIZE_SUB;
3203 i=cmd_out(); /* which buffer to use? */
3204 return (i);
3205}
3206#endif /* FUTURE */
3207/*==========================================================================*/
3208static void __init check_datarate(void)
3209{
3210 int i=0;
3211
3212 msg(DBG_IOX,"check_datarate entered.\n");
3213 datarate=0;
3214#if TEST_STI
3215 for (i=0;i<=1000;i++) printk(".");
3216#endif
3217 /* set a timer to make (timed_out_delay!=0) after 1.1 seconds */
3218#if 1
3219 del_timer(&delay_timer);
3220#endif
3221 delay_timer.expires=jiffies+11*HZ/10;
3222 timed_out_delay=0;
3223 add_timer(&delay_timer);
3224#if 0
3225 msg(DBG_TIM,"delay timer started (11*HZ/10).\n");
3226#endif
3227 do
3228 {
3229 i=inb(CDi_status);
3230 datarate++;
3231#if 1
3232 if (datarate>0x6FFFFFFF) break;
3233#endif
3234 }
3235 while (!timed_out_delay);
3236 del_timer(&delay_timer);
3237#if 0
3238 msg(DBG_TIM,"datarate: %04X\n", datarate);
3239#endif
3240 if (datarate<65536) datarate=65536;
3241 maxtim16=datarate*16;
3242 maxtim04=datarate*4;
3243 maxtim02=datarate*2;
3244 maxtim_8=datarate/32;
3245#if LONG_TIMING
3246 maxtim_data=datarate/100;
3247#else
3248 maxtim_data=datarate/300;
3249#endif /* LONG_TIMING */
3250#if 0
3251 msg(DBG_TIM,"maxtim_8 %d, maxtim_data %d.\n", maxtim_8, maxtim_data);
3252#endif
3253}
3254/*==========================================================================*/
3255#if 0
3256static int c2_ReadError(int fam)
3257{
3258 int i;
3259
3260 clr_cmdbuf();
3261 response_count=9;
3262 clr_respo_buf(9);
3263 if (fam==1)
3264 {
3265 drvcmd[0]=CMD0_READ_ERR; /* same as CMD1_ and CMDL_ */
3266 i=do_cmd(f_putcmd|f_lopsta|f_getsta|f_ResponseStatus);
3267 }
3268 else if (fam==2)
3269 {
3270 drvcmd[0]=CMD2_READ_ERR;
3271 i=do_cmd(f_putcmd);
3272 }
3273 else return (-1);
3274 return (i);
3275}
3276#endif
3277/*==========================================================================*/
3278static void __init ask_mail(void)
3279{
3280 int i;
3281
3282 msg(DBG_INF, "please mail the following lines to emoenke@gwdg.de\n");
3283 msg(DBG_INF, "(don't mail if you are not using the actual kernel):\n");
3284 msg(DBG_INF, "%s\n", VERSION);
3285 msg(DBG_INF, "address %03X, type %s, drive %s (ID %d)\n",
3286 CDo_command, type, current_drive->drive_model, current_drive->drv_id);
3287 for (i=0;i<12;i++)
3288 sprintf(&msgbuf[i*3], " %02X", infobuf[i]);
3289 msgbuf[i*3]=0;
3290 msg(DBG_INF,"infobuf =%s\n", msgbuf);
3291 for (i=0;i<12;i++)
3292 sprintf(&msgbuf[i*3], " %c ", infobuf[i]);
3293 msgbuf[i*3]=0;
3294 msg(DBG_INF,"infobuf =%s\n", msgbuf);
3295}
3296/*==========================================================================*/
3297static int __init check_version(void)
3298{
3299 int i, j, l;
3300 int teac_possible=0;
3301
3302 msg(DBG_INI,"check_version: id=%d, d=%d.\n", current_drive->drv_id, current_drive - D_S);
3303 current_drive->drv_type=0;
3304
3305 /* check for CR-52x, CR-56x, LCS-7260 and ECS-AT */
3306 /* clear any pending error state */
3307 clr_cmdbuf();
3308 drvcmd[0]=CMD0_READ_ERR; /* same as CMD1_ and CMDL_ */
3309 response_count=9;
3310 flags_cmd_out=f_putcmd;
3311 i=cmd_out();
3312 if (i<0) msg(DBG_INI,"CMD0_READ_ERR returns %d (ok anyway).\n",i);
3313 /* read drive version */
3314 clr_cmdbuf();
3315 for (i=0;i<12;i++) infobuf[i]=0;
3316 drvcmd[0]=CMD0_READ_VER; /* same as CMD1_ and CMDL_ */
3317 response_count=12; /* fam1: only 11 */
3318 flags_cmd_out=f_putcmd;
3319 i=cmd_out();
3320 if (i<-1) msg(DBG_INI,"CMD0_READ_VER returns %d\n",i);
3321 if (i==-11) teac_possible++;
3322 j=0;
3323 for (i=0;i<12;i++) j+=infobuf[i];
3324 if (j)
3325 {
3326 for (i=0;i<12;i++)
3327 sprintf(&msgbuf[i*3], " %02X", infobuf[i]);
3328 msgbuf[i*3]=0;
3329 msg(DBG_ECS,"infobuf =%s\n", msgbuf);
3330 for (i=0;i<12;i++)
3331 sprintf(&msgbuf[i*3], " %c ", infobuf[i]);
3332 msgbuf[i*3]=0;
3333 msg(DBG_ECS,"infobuf =%s\n", msgbuf);
3334 }
3335 for (i=0;i<4;i++) if (infobuf[i]!=family1[i]) break;
3336 if (i==4)
3337 {
3338 current_drive->drive_model[0]='C';
3339 current_drive->drive_model[1]='R';
3340 current_drive->drive_model[2]='-';
3341 current_drive->drive_model[3]='5';
3342 current_drive->drive_model[4]=infobuf[i++];
3343 current_drive->drive_model[5]=infobuf[i++];
3344 current_drive->drive_model[6]=0;
3345 current_drive->drv_type=drv_fam1;
3346 }
3347 if (!current_drive->drv_type)
3348 {
3349 for (i=0;i<8;i++) if (infobuf[i]!=family0[i]) break;
3350 if (i==8)
3351 {
3352 current_drive->drive_model[0]='C';
3353 current_drive->drive_model[1]='R';
3354 current_drive->drive_model[2]='-';
3355 current_drive->drive_model[3]='5';
3356 current_drive->drive_model[4]='2';
3357 current_drive->drive_model[5]='x';
3358 current_drive->drive_model[6]=0;
3359 current_drive->drv_type=drv_fam0;
3360 }
3361 }
3362 if (!current_drive->drv_type)
3363 {
3364 for (i=0;i<8;i++) if (infobuf[i]!=familyL[i]) break;
3365 if (i==8)
3366 {
3367 for (j=0;j<8;j++)
3368 current_drive->drive_model[j]=infobuf[j];
3369 current_drive->drive_model[8]=0;
3370 current_drive->drv_type=drv_famL;
3371 }
3372 }
3373 if (!current_drive->drv_type)
3374 {
3375 for (i=0;i<6;i++) if (infobuf[i]!=familyV[i]) break;
3376 if (i==6)
3377 {
3378 for (j=0;j<6;j++)
3379 current_drive->drive_model[j]=infobuf[j];
3380 current_drive->drive_model[6]=0;
3381 current_drive->drv_type=drv_famV;
3382 i+=2; /* 2 blanks before version */
3383 }
3384 }
3385 if (!current_drive->drv_type)
3386 {
3387 /* check for CD200 */
3388 clr_cmdbuf();
3389 drvcmd[0]=CMD2_READ_ERR;
3390 response_count=9;
3391 flags_cmd_out=f_putcmd;
3392 i=cmd_out();
3393 if (i<0) msg(DBG_INI,"CMD2_READERR returns %d (ok anyway).\n",i);
3394 if (i<0) msg(DBG_000,"CMD2_READERR returns %d (ok anyway).\n",i);
3395 /* read drive version */
3396 clr_cmdbuf();
3397 for (i=0;i<12;i++) infobuf[i]=0;
3398 if (sbpro_type==1) OUT(CDo_sel_i_d,0);
3399#if 0
3400 OUT(CDo_reset,0);
3401 sbp_sleep(6*HZ);
3402 OUT(CDo_enable,current_drive->drv_sel);
3403#endif
3404 drvcmd[0]=CMD2_READ_VER;
3405 response_count=12;
3406 flags_cmd_out=f_putcmd;
3407 i=cmd_out();
3408 if (i<0) msg(DBG_INI,"CMD2_READ_VER returns %d\n",i);
3409 if (i==-7) teac_possible++;
3410 j=0;
3411 for (i=0;i<12;i++) j+=infobuf[i];
3412 if (j)
3413 {
3414 for (i=0;i<12;i++)
3415 sprintf(&msgbuf[i*3], " %02X", infobuf[i]);
3416 msgbuf[i*3]=0;
3417 msg(DBG_IDX,"infobuf =%s\n", msgbuf);
3418 for (i=0;i<12;i++)
3419 sprintf(&msgbuf[i*3], " %c ", infobuf[i]);
3420 msgbuf[i*3]=0;
3421 msg(DBG_IDX,"infobuf =%s\n", msgbuf);
3422 }
3423 if (i>=0)
3424 {
3425 for (i=0;i<5;i++) if (infobuf[i]!=family2[i]) break;
3426 if (i==5)
3427 {
3428 current_drive->drive_model[0]='C';
3429 current_drive->drive_model[1]='D';
3430 current_drive->drive_model[2]='2';
3431 current_drive->drive_model[3]='0';
3432 current_drive->drive_model[4]='0';
3433 current_drive->drive_model[5]=infobuf[i++];
3434 current_drive->drive_model[6]=infobuf[i++];
3435 current_drive->drive_model[7]=0;
3436 current_drive->drv_type=drv_fam2;
3437 }
3438 }
3439 }
3440 if (!current_drive->drv_type)
3441 {
3442 /* check for TEAC CD-55A */
3443 msg(DBG_TEA,"teac_possible: %d\n",teac_possible);
3444 for (j=1;j<=((current_drive->drv_id==0)?3:1);j++)
3445 {
3446 for (l=1;l<=((current_drive->drv_id==0)?10:1);l++)
3447 {
3448 msg(DBG_TEA,"TEAC reset #%d-%d.\n", j, l);
3449 if (sbpro_type==1) OUT(CDo_reset,0);
3450 else
3451 {
3452 OUT(CDo_enable,current_drive->drv_sel);
3453 OUT(CDo_sel_i_d,0);
3454 OUT(CDo_command,CMDT_RESET);
3455 for (i=0;i<9;i++) OUT(CDo_command,0);
3456 }
3457 sbp_sleep(5*HZ/10);
3458 OUT(CDo_enable,current_drive->drv_sel);
3459 OUT(CDo_sel_i_d,0);
3460 i=inb(CDi_status);
3461 msg(DBG_TEA,"TEAC CDi_status: %02X.\n",i);
3462#if 0
3463 if (i&s_not_result_ready) continue; /* drive not present or ready */
3464#endif
3465 i=inb(CDi_info);
3466 msg(DBG_TEA,"TEAC CDi_info: %02X.\n",i);
3467 if (i==0x55) break; /* drive found */
3468 }
3469 if (i==0x55) break; /* drive found */
3470 }
3471 if (i==0x55) /* drive found */
3472 {
3473 msg(DBG_TEA,"TEAC drive found.\n");
3474 clr_cmdbuf();
3475 flags_cmd_out=f_putcmd;
3476 response_count=12;
3477 drvcmd[0]=CMDT_READ_VER;
3478 drvcmd[4]=response_count;
3479 for (i=0;i<12;i++) infobuf[i]=0;
3480 i=cmd_out_T();
3481 if (i!=0) msg(DBG_TEA,"cmd_out_T(CMDT_READ_VER) returns %d.\n",i);
3482 for (i=1;i<6;i++) if (infobuf[i]!=familyT[i-1]) break;
3483 if (i==6)
3484 {
3485 current_drive->drive_model[0]='C';
3486 current_drive->drive_model[1]='D';
3487 current_drive->drive_model[2]='-';
3488 current_drive->drive_model[3]='5';
3489 current_drive->drive_model[4]='5';
3490 current_drive->drive_model[5]=0;
3491 current_drive->drv_type=drv_famT;
3492 }
3493 }
3494 }
3495 if (!current_drive->drv_type)
3496 {
3497 msg(DBG_TEA,"no drive found at address %03X under ID %d.\n",CDo_command,current_drive->drv_id);
3498 return (-522);
3499 }
3500 for (j=0;j<4;j++) current_drive->firmware_version[j]=infobuf[i+j];
3501 if (famL_drive)
3502 {
3503 u_char lcs_firm_e1[]="A E1";
3504 u_char lcs_firm_f4[]="A4F4";
3505
3506 for (j=0;j<4;j++)
3507 if (current_drive->firmware_version[j]!=lcs_firm_e1[j]) break;
3508 if (j==4) current_drive->drv_type=drv_e1;
3509
3510 for (j=0;j<4;j++)
3511 if (current_drive->firmware_version[j]!=lcs_firm_f4[j]) break;
3512 if (j==4) current_drive->drv_type=drv_f4;
3513
3514 if (current_drive->drv_type==drv_famL) ask_mail();
3515 }
3516 else if (famT_drive)
3517 {
3518 j=infobuf[4]; /* one-byte version??? - here: 0x15 */
3519 if (j=='5')
3520 {
3521 current_drive->firmware_version[0]=infobuf[7];
3522 current_drive->firmware_version[1]=infobuf[8];
3523 current_drive->firmware_version[2]=infobuf[10];
3524 current_drive->firmware_version[3]=infobuf[11];
3525 }
3526 else
3527 {
3528 if (j!=0x15) ask_mail();
3529 current_drive->firmware_version[0]='0';
3530 current_drive->firmware_version[1]='.';
3531 current_drive->firmware_version[2]='0'+(j>>4);
3532 current_drive->firmware_version[3]='0'+(j&0x0f);
3533 }
3534 }
3535 else /* CR-52x, CR-56x, CD200, ECS-AT */
3536 {
3537 j = (current_drive->firmware_version[0] & 0x0F) * 100 +
3538 (current_drive->firmware_version[2] & 0x0F) *10 +
3539 (current_drive->firmware_version[3] & 0x0F);
3540 if (fam0_drive)
3541 {
3542 if (j<200) current_drive->drv_type=drv_199;
3543 else if (j<201) current_drive->drv_type=drv_200;
3544 else if (j<210) current_drive->drv_type=drv_201;
3545 else if (j<211) current_drive->drv_type=drv_210;
3546 else if (j<300) current_drive->drv_type=drv_211;
3547 else if (j>=300) current_drive->drv_type=drv_300;
3548 }
3549 else if (fam1_drive)
3550 {
3551 if (j<100) current_drive->drv_type=drv_099;
3552 else
3553 {
3554 current_drive->drv_type=drv_100;
3555 if ((j!=500)&&(j!=102)) ask_mail();
3556 }
3557 }
3558 else if (fam2_drive)
3559 {
3560 if (current_drive->drive_model[5]=='F')
3561 {
3562 if ((j!=1)&&(j!=35)&&(j!=200)&&(j!=210))
3563 ask_mail(); /* unknown version at time */
3564 }
3565 else
3566 {
3567 msg(DBG_INF,"this CD200 drive is not fully supported yet - only audio will work.\n");
3568 if ((j!=101)&&(j!=35))
3569 ask_mail(); /* unknown version at time */
3570 }
3571 }
3572 else if (famV_drive)
3573 {
3574 if ((j==100)||(j==150)) current_drive->drv_type=drv_at;
3575 ask_mail(); /* hopefully we get some feedback by this */
3576 }
3577 }
3578 msg(DBG_LCS,"drive type %02X\n",current_drive->drv_type);
3579 msg(DBG_INI,"check_version done.\n");
3580 return (0);
3581}
3582/*==========================================================================*/
3583static void switch_drive(struct sbpcd_drive *p)
3584{
3585 current_drive = p;
3586 OUT(CDo_enable,current_drive->drv_sel);
3587 msg(DBG_DID,"drive %d (ID=%d) activated.\n",
3588 current_drive - D_S, current_drive->drv_id);
3589 return;
3590}
3591/*==========================================================================*/
3592#ifdef PATH_CHECK
3593/*
3594 * probe for the presence of an interface card
3595 */
3596static int __init check_card(int port)
3597{
3598#undef N_RESPO
3599#define N_RESPO 20
3600 int i, j, k;
3601 u_char response[N_RESPO];
3602 u_char save_port0;
3603 u_char save_port3;
3604
3605 msg(DBG_INI,"check_card entered.\n");
3606 save_port0=inb(port+0);
3607 save_port3=inb(port+3);
3608
3609 for (j=0;j<NR_SBPCD;j++)
3610 {
3611 OUT(port+3,j) ; /* enable drive #j */
3612 OUT(port+0,CMD0_PATH_CHECK);
3613 for (i=10;i>0;i--) OUT(port+0,0);
3614 for (k=0;k<N_RESPO;k++) response[k]=0;
3615 for (k=0;k<N_RESPO;k++)
3616 {
3617 for (i=10000;i>0;i--)
3618 {
3619 if (inb(port+1)&s_not_result_ready) continue;
3620 response[k]=inb(port+0);
3621 break;
3622 }
3623 }
3624 for (i=0;i<N_RESPO;i++)
3625 sprintf(&msgbuf[i*3], " %02X", response[i]);
3626 msgbuf[i*3]=0;
3627 msg(DBG_TEA,"path check 00 (%d): %s\n", j, msgbuf);
3628 OUT(port+0,CMD0_PATH_CHECK);
3629 for (i=10;i>0;i--) OUT(port+0,0);
3630 for (k=0;k<N_RESPO;k++) response[k]=0xFF;
3631 for (k=0;k<N_RESPO;k++)
3632 {
3633 for (i=10000;i>0;i--)
3634 {
3635 if (inb(port+1)&s_not_result_ready) continue;
3636 response[k]=inb(port+0);
3637 break;
3638 }
3639 }
3640 for (i=0;i<N_RESPO;i++)
3641 sprintf(&msgbuf[i*3], " %02X", response[i]);
3642 msgbuf[i*3]=0;
3643 msg(DBG_TEA,"path check 00 (%d): %s\n", j, msgbuf);
3644
3645 if (response[0]==0xAA)
3646 if (response[1]==0x55)
3647 return (0);
3648 }
3649 for (j=0;j<NR_SBPCD;j++)
3650 {
3651 OUT(port+3,j) ; /* enable drive #j */
3652 OUT(port+0,CMD2_READ_VER);
3653 for (i=10;i>0;i--) OUT(port+0,0);
3654 for (k=0;k<N_RESPO;k++) response[k]=0;
3655 for (k=0;k<N_RESPO;k++)
3656 {
3657 for (i=1000000;i>0;i--)
3658 {
3659 if (inb(port+1)&s_not_result_ready) continue;
3660 response[k]=inb(port+0);
3661 break;
3662 }
3663 }
3664 for (i=0;i<N_RESPO;i++)
3665 sprintf(&msgbuf[i*3], " %02X", response[i]);
3666 msgbuf[i*3]=0;
3667 msg(DBG_TEA,"path check 12 (%d): %s\n", j, msgbuf);
3668
3669 OUT(port+0,CMD2_READ_VER);
3670 for (i=10;i>0;i--) OUT(port+0,0);
3671 for (k=0;k<N_RESPO;k++) response[k]=0xFF;
3672 for (k=0;k<N_RESPO;k++)
3673 {
3674 for (i=1000000;i>0;i--)
3675 {
3676 if (inb(port+1)&s_not_result_ready) continue;
3677 response[k]=inb(port+0);
3678 break;
3679 }
3680 }
3681 for (i=0;i<N_RESPO;i++)
3682 sprintf(&msgbuf[i*3], " %02X", response[i]);
3683 msgbuf[i*3]=0;
3684 msg(DBG_TEA,"path check 12 (%d): %s\n", j, msgbuf);
3685
3686 if (response[0]==0xAA)
3687 if (response[1]==0x55)
3688 return (0);
3689 }
3690 OUT(port+0,save_port0);
3691 OUT(port+3,save_port3);
3692 return (0); /* in any case - no real "function" at time */
3693}
3694#endif /* PATH_CHECK */
3695/*==========================================================================*/
3696/*==========================================================================*/
3697/*
3698 * probe for the presence of drives on the selected controller
3699 */
3700static int __init check_drives(void)
3701{
3702 int i, j;
3703
3704 msg(DBG_INI,"check_drives entered.\n");
3705 ndrives=0;
3706 for (j=0;j<max_drives;j++)
3707 {
3708 struct sbpcd_drive *p = D_S + ndrives;
3709 p->drv_id=j;
3710 if (sbpro_type==1) p->drv_sel=(j&0x01)<<1|(j&0x02)>>1;
3711 else p->drv_sel=j;
3712 switch_drive(p);
3713 msg(DBG_INI,"check_drives: drive %d (ID=%d) activated.\n",ndrives,j);
3714 msg(DBG_000,"check_drives: drive %d (ID=%d) activated.\n",ndrives,j);
3715 i=check_version();
3716 if (i<0) msg(DBG_INI,"check_version returns %d.\n",i);
3717 else
3718 {
3719 current_drive->drv_options=drv_pattern[j];
3720 if (fam0L_drive) current_drive->drv_options&=~(speed_auto|speed_300|speed_150);
3721 msg(DBG_INF, "Drive %d (ID=%d): %.9s (%.4s) at 0x%03X (type %d)\n",
3722 current_drive - D_S,
3723 current_drive->drv_id,
3724 current_drive->drive_model,
3725 current_drive->firmware_version,
3726 CDo_command,
3727 sbpro_type);
3728 ndrives++;
3729 }
3730 }
3731 for (j=ndrives;j<NR_SBPCD;j++) D_S[j].drv_id=-1;
3732 if (ndrives==0) return (-1);
3733 return (0);
3734}
3735/*==========================================================================*/
3736#ifdef FUTURE
3737/*
3738 * obtain if requested service disturbs current audio state
3739 */
3740static int obey_audio_state(u_char audio_state, u_char func,u_char subfunc)
3741{
3742 switch (audio_state) /* audio status from controller */
3743 {
3744 case aud_11: /* "audio play in progress" */
3745 case audx11:
3746 switch (func) /* DOS command code */
3747 {
3748 case cmd_07: /* input flush */
3749 case cmd_0d: /* open device */
3750 case cmd_0e: /* close device */
3751 case cmd_0c: /* ioctl output */
3752 return (1);
3753 case cmd_03: /* ioctl input */
3754 switch (subfunc)
3755 /* DOS ioctl input subfunction */
3756 {
3757 case cxi_00:
3758 case cxi_06:
3759 case cxi_09:
3760 return (1);
3761 default:
3762 return (ERROR15);
3763 }
3764 return (1);
3765 default:
3766 return (ERROR15);
3767 }
3768 return (1);
3769 case aud_12: /* "audio play paused" */
3770 case audx12:
3771 return (1);
3772 default:
3773 return (2);
3774 }
3775}
3776/*==========================================================================*/
3777/* allowed is only
3778 * ioctl_o, flush_input, open_device, close_device,
3779 * tell_address, tell_volume, tell_capabiliti,
3780 * tell_framesize, tell_CD_changed, tell_audio_posi
3781 */
3782static int check_allowed1(u_char func1, u_char func2)
3783{
3784#if 000
3785 if (func1==ioctl_o) return (0);
3786 if (func1==read_long) return (-1);
3787 if (func1==read_long_prefetch) return (-1);
3788 if (func1==seek) return (-1);
3789 if (func1==audio_play) return (-1);
3790 if (func1==audio_pause) return (-1);
3791 if (func1==audio_resume) return (-1);
3792 if (func1!=ioctl_i) return (0);
3793 if (func2==tell_SubQ_run_tot) return (-1);
3794 if (func2==tell_cdsize) return (-1);
3795 if (func2==tell_TocDescrip) return (-1);
3796 if (func2==tell_TocEntry) return (-1);
3797 if (func2==tell_subQ_info) return (-1);
3798 if (fam1_drive) if (func2==tell_SubChanInfo) return (-1);
3799 if (func2==tell_UPC) return (-1);
3800#else
3801 return (0);
3802#endif
3803}
3804/*==========================================================================*/
3805static int check_allowed2(u_char func1, u_char func2)
3806{
3807#if 000
3808 if (func1==read_long) return (-1);
3809 if (func1==read_long_prefetch) return (-1);
3810 if (func1==seek) return (-1);
3811 if (func1==audio_play) return (-1);
3812 if (func1!=ioctl_o) return (0);
3813 if (fam1_drive)
3814 {
3815 if (func2==EjectDisk) return (-1);
3816 if (func2==CloseTray) return (-1);
3817 }
3818#else
3819 return (0);
3820#endif
3821}
3822/*==========================================================================*/
3823static int check_allowed3(u_char func1, u_char func2)
3824{
3825#if 000
3826 if (func1==ioctl_i)
3827 {
3828 if (func2==tell_address) return (0);
3829 if (func2==tell_capabiliti) return (0);
3830 if (func2==tell_CD_changed) return (0);
3831 if (fam0L_drive) if (func2==tell_SubChanInfo) return (0);
3832 return (-1);
3833 }
3834 if (func1==ioctl_o)
3835 {
3836 if (func2==DriveReset) return (0);
3837 if (fam0L_drive)
3838 {
3839 if (func2==EjectDisk) return (0);
3840 if (func2==LockDoor) return (0);
3841 if (func2==CloseTray) return (0);
3842 }
3843 return (-1);
3844 }
3845 if (func1==flush_input) return (-1);
3846 if (func1==read_long) return (-1);
3847 if (func1==read_long_prefetch) return (-1);
3848 if (func1==seek) return (-1);
3849 if (func1==audio_play) return (-1);
3850 if (func1==audio_pause) return (-1);
3851 if (func1==audio_resume) return (-1);
3852#else
3853 return (0);
3854#endif
3855}
3856/*==========================================================================*/
3857static int seek_pos_audio_end(void)
3858{
3859 int i;
3860
3861 i=msf2blk(current_drive->pos_audio_end)-1;
3862 if (i<0) return (-1);
3863 i=cc_Seek(i,0);
3864 return (i);
3865}
3866#endif /* FUTURE */
3867/*==========================================================================*/
3868static int ReadToC(void)
3869{
3870 int i, j;
3871 current_drive->diskstate_flags &= ~toc_bit;
3872 current_drive->ored_ctl_adr=0;
3873 /* special handling of CD-I HE */
3874 if ((current_drive->n_first_track == 2 && current_drive->n_last_track == 2) ||
3875 current_drive->xa_byte == 0x10)
3876 {
3877 current_drive->TocBuffer[1].nixbyte=0;
3878 current_drive->TocBuffer[1].ctl_adr=0x40;
3879 current_drive->TocBuffer[1].number=1;
3880 current_drive->TocBuffer[1].format=0;
3881 current_drive->TocBuffer[1].address=blk2msf(0);
3882 current_drive->ored_ctl_adr |= 0x40;
3883 current_drive->n_first_track = 1;
3884 current_drive->n_last_track = 1;
3885 current_drive->xa_byte = 0x10;
3886 j = 2;
3887 } else
3888 for (j=current_drive->n_first_track;j<=current_drive->n_last_track;j++)
3889 {
3890 i=cc_ReadTocEntry(j);
3891 if (i<0)
3892 {
3893 msg(DBG_INF,"cc_ReadTocEntry(%d) returns %d.\n",j,i);
3894 return (i);
3895 }
3896 current_drive->TocBuffer[j].nixbyte=current_drive->TocEnt_nixbyte;
3897 current_drive->TocBuffer[j].ctl_adr=current_drive->TocEnt_ctl_adr;
3898 current_drive->TocBuffer[j].number=current_drive->TocEnt_number;
3899 current_drive->TocBuffer[j].format=current_drive->TocEnt_format;
3900 current_drive->TocBuffer[j].address=current_drive->TocEnt_address;
3901 current_drive->ored_ctl_adr |= current_drive->TocEnt_ctl_adr;
3902 }
3903 /* fake entry for LeadOut Track */
3904 current_drive->TocBuffer[j].nixbyte=0;
3905 current_drive->TocBuffer[j].ctl_adr=0;
3906 current_drive->TocBuffer[j].number=CDROM_LEADOUT;
3907 current_drive->TocBuffer[j].format=0;
3908 current_drive->TocBuffer[j].address=current_drive->size_msf;
3909
3910 current_drive->diskstate_flags |= toc_bit;
3911 return (0);
3912}
3913/*==========================================================================*/
3914static int DiskInfo(void)
3915{
3916 int i, j;
3917
3918 current_drive->mode=READ_M1;
3919
3920#undef LOOP_COUNT
3921#define LOOP_COUNT 10 /* needed for some "old" drives */
3922
3923 msg(DBG_000,"DiskInfo entered.\n");
3924 for (j=1;j<LOOP_COUNT;j++)
3925 {
3926#if 0
3927 i=SetSpeed();
3928 if (i<0)
3929 {
3930 msg(DBG_INF,"DiskInfo: SetSpeed returns %d\n", i);
3931 continue;
3932 }
3933 i=cc_ModeSense();
3934 if (i<0)
3935 {
3936 msg(DBG_INF,"DiskInfo: cc_ModeSense returns %d\n", i);
3937 continue;
3938 }
3939#endif
3940 i=cc_ReadCapacity();
3941 if (i>=0) break;
3942 msg(DBG_INF,"DiskInfo: ReadCapacity #%d returns %d\n", j, i);
3943#if 0
3944 i=cc_DriveReset();
3945#endif
3946 if (!fam0_drive && j == 2) break;
3947 }
3948 if (j==LOOP_COUNT) return (-33); /* give up */
3949
3950 i=cc_ReadTocDescr();
3951 if (i<0)
3952 {
3953 msg(DBG_INF,"DiskInfo: ReadTocDescr returns %d\n", i);
3954 return (i);
3955 }
3956 i=ReadToC();
3957 if (i<0)
3958 {
3959 msg(DBG_INF,"DiskInfo: ReadToC returns %d\n", i);
3960 return (i);
3961 }
3962 i=cc_CheckMultiSession();
3963 if (i<0)
3964 {
3965 msg(DBG_INF,"DiskInfo: cc_CheckMultiSession returns %d\n", i);
3966 return (i);
3967 }
3968 if (current_drive->f_multisession) current_drive->sbp_bufsiz=1; /* possibly a weird PhotoCD */
3969 else current_drive->sbp_bufsiz=buffers;
3970 i=cc_ReadTocEntry(current_drive->n_first_track);
3971 if (i<0)
3972 {
3973 msg(DBG_INF,"DiskInfo: cc_ReadTocEntry(1) returns %d\n", i);
3974 return (i);
3975 }
3976 i=cc_ReadUPC();
3977 if (i<0) msg(DBG_INF,"DiskInfo: cc_ReadUPC returns %d\n", i);
3978 if ((fam0L_drive) && (current_drive->xa_byte==0x20 || current_drive->xa_byte == 0x10))
3979 {
3980 /* XA disk with old drive */
3981 cc_ModeSelect(CD_FRAMESIZE_RAW1);
3982 cc_ModeSense();
3983 }
3984 if (famT_drive) cc_prep_mode_T();
3985 msg(DBG_000,"DiskInfo done.\n");
3986 return (0);
3987}
3988
3989static int sbpcd_drive_status(struct cdrom_device_info *cdi, int slot_nr)
3990{
3991 struct sbpcd_drive *p = cdi->handle;
3992 int st;
3993
3994 if (CDSL_CURRENT != slot_nr) {
3995 /* we have no changer support */
3996 return -EINVAL;
3997 }
3998
3999 cc_ReadStatus();
4000 st=ResponseStatus();
4001 if (st<0)
4002 {
4003 msg(DBG_INF,"sbpcd_drive_status: timeout.\n");
4004 return (0);
4005 }
4006 msg(DBG_000,"Drive Status: door_locked =%d.\n", st_door_locked);
4007 msg(DBG_000,"Drive Status: door_closed =%d.\n", st_door_closed);
4008 msg(DBG_000,"Drive Status: caddy_in =%d.\n", st_caddy_in);
4009 msg(DBG_000,"Drive Status: disk_ok =%d.\n", st_diskok);
4010 msg(DBG_000,"Drive Status: spinning =%d.\n", st_spinning);
4011 msg(DBG_000,"Drive Status: busy =%d.\n", st_busy);
4012
4013#if 0
4014 if (!(p->status_bits & p_door_closed)) return CDS_TRAY_OPEN;
4015 if (p->status_bits & p_disk_ok) return CDS_DISC_OK;
4016 if (p->status_bits & p_disk_in) return CDS_DRIVE_NOT_READY;
4017
4018 return CDS_NO_DISC;
4019#else
4020 if (p->status_bits & p_spinning) return CDS_DISC_OK;
4021/* return CDS_TRAY_OPEN; */
4022 return CDS_NO_DISC;
4023
4024#endif
4025
4026}
4027
4028
4029/*==========================================================================*/
4030#ifdef FUTURE
4031/*
4032 * called always if driver gets entered
4033 * returns 0 or ERROR2 or ERROR15
4034 */
4035static int prepare(u_char func, u_char subfunc)
4036{
4037 int i;
4038
4039 if (fam0L_drive)
4040 {
4041 i=inb(CDi_status);
4042 if (i&s_attention) GetStatus();
4043 }
4044 else if (fam1_drive) GetStatus();
4045 else if (fam2_drive) GetStatus();
4046 else if (famT_drive) GetStatus();
4047 if (current_drive->CD_changed==0xFF)
4048 {
4049 current_drive->diskstate_flags=0;
4050 current_drive->audio_state=0;
4051 if (!st_diskok)
4052 {
4053 i=check_allowed1(func,subfunc);
4054 if (i<0) return (-2);
4055 }
4056 else
4057 {
4058 i=check_allowed3(func,subfunc);
4059 if (i<0)
4060 {
4061 current_drive->CD_changed=1;
4062 return (-15);
4063 }
4064 }
4065 }
4066 else
4067 {
4068 if (!st_diskok)
4069 {
4070 current_drive->diskstate_flags=0;
4071 current_drive->audio_state=0;
4072 i=check_allowed1(func,subfunc);
4073 if (i<0) return (-2);
4074 }
4075 else
4076 {
4077 if (st_busy)
4078 {
4079 if (current_drive->audio_state!=audio_pausing)
4080 {
4081 i=check_allowed2(func,subfunc);
4082 if (i<0) return (-2);
4083 }
4084 }
4085 else
4086 {
4087 if (current_drive->audio_state==audio_playing) seek_pos_audio_end();
4088 current_drive->audio_state=0;
4089 }
4090 if (!frame_size_valid)
4091 {
4092 i=DiskInfo();
4093 if (i<0)
4094 {
4095 current_drive->diskstate_flags=0;
4096 current_drive->audio_state=0;
4097 i=check_allowed1(func,subfunc);
4098 if (i<0) return (-2);
4099 }
4100 }
4101 }
4102 }
4103 return (0);
4104}
4105#endif /* FUTURE */
4106/*==========================================================================*/
4107/*==========================================================================*/
4108/*
4109 * Check the results of the "get status" command.
4110 */
4111static int sbp_status(void)
4112{
4113 int st;
4114
4115 st=ResponseStatus();
4116 if (st<0)
4117 {
4118 msg(DBG_INF,"sbp_status: timeout.\n");
4119 return (0);
4120 }
4121
4122 if (!st_spinning) msg(DBG_SPI,"motor got off - ignoring.\n");
4123
4124 if (st_check)
4125 {
4126 msg(DBG_INF,"st_check detected - retrying.\n");
4127 return (0);
4128 }
4129 if (!st_door_closed)
4130 {
4131 msg(DBG_INF,"door is open - retrying.\n");
4132 return (0);
4133 }
4134 if (!st_caddy_in)
4135 {
4136 msg(DBG_INF,"disk removed - retrying.\n");
4137 return (0);
4138 }
4139 if (!st_diskok)
4140 {
4141 msg(DBG_INF,"!st_diskok detected - retrying.\n");
4142 return (0);
4143 }
4144 if (st_busy)
4145 {
4146 msg(DBG_INF,"st_busy detected - retrying.\n");
4147 return (0);
4148 }
4149 return (1);
4150}
4151/*==========================================================================*/
4152
4153static int sbpcd_get_last_session(struct cdrom_device_info *cdi, struct cdrom_multisession *ms_infp)
4154{
4155 struct sbpcd_drive *p = cdi->handle;
4156 ms_infp->addr_format = CDROM_LBA;
4157 ms_infp->addr.lba = p->lba_multi;
4158 if (p->f_multisession)
4159 ms_infp->xa_flag=1; /* valid redirection address */
4160 else
4161 ms_infp->xa_flag=0; /* invalid redirection address */
4162
4163 return 0;
4164}
4165
4166static int sbpcd_audio_ioctl(struct cdrom_device_info *cdi, u_int cmd,
4167 void * arg)
4168{
4169 struct sbpcd_drive *p = cdi->handle;
4170 int i, st, j;
4171
4172 msg(DBG_IO2,"ioctl(%s, 0x%08lX, 0x%08p)\n", cdi->name, cmd, arg);
4173 if (p->drv_id==-1) {
4174 msg(DBG_INF, "ioctl: bad device: %s\n", cdi->name);
4175 return (-ENXIO); /* no such drive */
4176 }
4177 down(&ioctl_read_sem);
4178 if (p != current_drive)
4179 switch_drive(p);
4180
4181 msg(DBG_IO2,"ioctl: device %s, request %04X\n",cdi->name,cmd);
4182 switch (cmd) /* Sun-compatible */
4183 {
4184
4185 case CDROMPAUSE: /* Pause the drive */
4186 msg(DBG_IOC,"ioctl: CDROMPAUSE entered.\n");
4187 /* pause the drive unit when it is currently in PLAY mode, */
4188 /* or reset the starting and ending locations when in PAUSED mode. */
4189 /* If applicable, at the next stopping point it reaches */
4190 /* the drive will discontinue playing. */
4191 switch (current_drive->audio_state)
4192 {
4193 case audio_playing:
4194 if (famL_drive) i=cc_ReadSubQ();
4195 else i=cc_Pause_Resume(1);
4196 if (i<0) RETURN_UP(-EIO);
4197 if (famL_drive) i=cc_Pause_Resume(1);
4198 else i=cc_ReadSubQ();
4199 if (i<0) RETURN_UP(-EIO);
4200 current_drive->pos_audio_start=current_drive->SubQ_run_tot;
4201 current_drive->audio_state=audio_pausing;
4202 RETURN_UP(0);
4203 case audio_pausing:
4204 i=cc_Seek(current_drive->pos_audio_start,1);
4205 if (i<0) RETURN_UP(-EIO);
4206 RETURN_UP(0);
4207 default:
4208 RETURN_UP(-EINVAL);
4209 }
4210
4211 case CDROMRESUME: /* resume paused audio play */
4212 msg(DBG_IOC,"ioctl: CDROMRESUME entered.\n");
4213 /* resume playing audio tracks when a previous PLAY AUDIO call has */
4214 /* been paused with a PAUSE command. */
4215 /* It will resume playing from the location saved in SubQ_run_tot. */
4216 if (current_drive->audio_state!=audio_pausing) RETURN_UP(-EINVAL);
4217 if (famL_drive)
4218 i=cc_PlayAudio(current_drive->pos_audio_start,
4219 current_drive->pos_audio_end);
4220 else i=cc_Pause_Resume(3);
4221 if (i<0) RETURN_UP(-EIO);
4222 current_drive->audio_state=audio_playing;
4223 RETURN_UP(0);
4224
4225 case CDROMPLAYMSF:
4226 msg(DBG_IOC,"ioctl: CDROMPLAYMSF entered.\n");
4227#ifdef SAFE_MIXED
4228 if (current_drive->has_data>1) RETURN_UP(-EBUSY);
4229#endif /* SAFE_MIXED */
4230 if (current_drive->audio_state==audio_playing)
4231 {
4232 i=cc_Pause_Resume(1);
4233 if (i<0) RETURN_UP(-EIO);
4234 i=cc_ReadSubQ();
4235 if (i<0) RETURN_UP(-EIO);
4236 current_drive->pos_audio_start=current_drive->SubQ_run_tot;
4237 i=cc_Seek(current_drive->pos_audio_start,1);
4238 }
4239 memcpy(&msf, (void *) arg, sizeof(struct cdrom_msf));
4240 /* values come as msf-bin */
4241 current_drive->pos_audio_start = (msf.cdmsf_min0<<16) |
4242 (msf.cdmsf_sec0<<8) |
4243 msf.cdmsf_frame0;
4244 current_drive->pos_audio_end = (msf.cdmsf_min1<<16) |
4245 (msf.cdmsf_sec1<<8) |
4246 msf.cdmsf_frame1;
4247 msg(DBG_IOX,"ioctl: CDROMPLAYMSF %08X %08X\n",
4248 current_drive->pos_audio_start,current_drive->pos_audio_end);
4249 i=cc_PlayAudio(current_drive->pos_audio_start,current_drive->pos_audio_end);
4250 if (i<0)
4251 {
4252 msg(DBG_INF,"ioctl: cc_PlayAudio returns %d\n",i);
4253 DriveReset();
4254 current_drive->audio_state=0;
4255 RETURN_UP(-EIO);
4256 }
4257 current_drive->audio_state=audio_playing;
4258 RETURN_UP(0);
4259
4260 case CDROMPLAYTRKIND: /* Play a track. This currently ignores index. */
4261 msg(DBG_IOC,"ioctl: CDROMPLAYTRKIND entered.\n");
4262#ifdef SAFE_MIXED
4263 if (current_drive->has_data>1) RETURN_UP(-EBUSY);
4264#endif /* SAFE_MIXED */
4265 if (current_drive->audio_state==audio_playing)
4266 {
4267 msg(DBG_IOX,"CDROMPLAYTRKIND: already audio_playing.\n");
4268#if 1
4269 RETURN_UP(0); /* just let us play on */
4270#else
4271 RETURN_UP(-EINVAL); /* play on, but say "error" */
4272#endif
4273 }
4274 memcpy(&ti,(void *) arg,sizeof(struct cdrom_ti));
4275 msg(DBG_IOX,"ioctl: trk0: %d, ind0: %d, trk1:%d, ind1:%d\n",
4276 ti.cdti_trk0,ti.cdti_ind0,ti.cdti_trk1,ti.cdti_ind1);
4277 if (ti.cdti_trk0<current_drive->n_first_track) RETURN_UP(-EINVAL);
4278 if (ti.cdti_trk0>current_drive->n_last_track) RETURN_UP(-EINVAL);
4279 if (ti.cdti_trk1<ti.cdti_trk0) ti.cdti_trk1=ti.cdti_trk0;
4280 if (ti.cdti_trk1>current_drive->n_last_track) ti.cdti_trk1=current_drive->n_last_track;
4281 current_drive->pos_audio_start=current_drive->TocBuffer[ti.cdti_trk0].address;
4282 current_drive->pos_audio_end=current_drive->TocBuffer[ti.cdti_trk1+1].address;
4283 i=cc_PlayAudio(current_drive->pos_audio_start,current_drive->pos_audio_end);
4284 if (i<0)
4285 {
4286 msg(DBG_INF,"ioctl: cc_PlayAudio returns %d\n",i);
4287 DriveReset();
4288 current_drive->audio_state=0;
4289 RETURN_UP(-EIO);
4290 }
4291 current_drive->audio_state=audio_playing;
4292 RETURN_UP(0);
4293
4294 case CDROMREADTOCHDR: /* Read the table of contents header */
4295 msg(DBG_IOC,"ioctl: CDROMREADTOCHDR entered.\n");
4296 tochdr.cdth_trk0=current_drive->n_first_track;
4297 tochdr.cdth_trk1=current_drive->n_last_track;
4298 memcpy((void *) arg, &tochdr, sizeof(struct cdrom_tochdr));
4299 RETURN_UP(0);
4300
4301 case CDROMREADTOCENTRY: /* Read an entry in the table of contents */
4302 msg(DBG_IOC,"ioctl: CDROMREADTOCENTRY entered.\n");
4303 memcpy(&tocentry, (void *) arg, sizeof(struct cdrom_tocentry));
4304 i=tocentry.cdte_track;
4305 if (i==CDROM_LEADOUT) i=current_drive->n_last_track+1;
4306 else if (i<current_drive->n_first_track||i>current_drive->n_last_track)
4307 RETURN_UP(-EINVAL);
4308 tocentry.cdte_adr=current_drive->TocBuffer[i].ctl_adr&0x0F;
4309 tocentry.cdte_ctrl=(current_drive->TocBuffer[i].ctl_adr>>4)&0x0F;
4310 tocentry.cdte_datamode=current_drive->TocBuffer[i].format;
4311 if (tocentry.cdte_format==CDROM_MSF) /* MSF-bin required */
4312 {
4313 tocentry.cdte_addr.msf.minute=(current_drive->TocBuffer[i].address>>16)&0x00FF;
4314 tocentry.cdte_addr.msf.second=(current_drive->TocBuffer[i].address>>8)&0x00FF;
4315 tocentry.cdte_addr.msf.frame=current_drive->TocBuffer[i].address&0x00FF;
4316 }
4317 else if (tocentry.cdte_format==CDROM_LBA) /* blk required */
4318 tocentry.cdte_addr.lba=msf2blk(current_drive->TocBuffer[i].address);
4319 else RETURN_UP(-EINVAL);
4320 memcpy((void *) arg, &tocentry, sizeof(struct cdrom_tocentry));
4321 RETURN_UP(0);
4322
4323 case CDROMSTOP: /* Spin down the drive */
4324 msg(DBG_IOC,"ioctl: CDROMSTOP entered.\n");
4325#ifdef SAFE_MIXED
4326 if (current_drive->has_data>1) RETURN_UP(-EBUSY);
4327#endif /* SAFE_MIXED */
4328 i=cc_Pause_Resume(1);
4329 current_drive->audio_state=0;
4330#if 0
4331 cc_DriveReset();
4332#endif
4333 RETURN_UP(i);
4334
4335 case CDROMSTART: /* Spin up the drive */
4336 msg(DBG_IOC,"ioctl: CDROMSTART entered.\n");
4337 cc_SpinUp();
4338 current_drive->audio_state=0;
4339 RETURN_UP(0);
4340
4341 case CDROMVOLCTRL: /* Volume control */
4342 msg(DBG_IOC,"ioctl: CDROMVOLCTRL entered.\n");
4343 memcpy(&volctrl,(char *) arg,sizeof(volctrl));
4344 current_drive->vol_chan0=0;
4345 current_drive->vol_ctrl0=volctrl.channel0;
4346 current_drive->vol_chan1=1;
4347 current_drive->vol_ctrl1=volctrl.channel1;
4348 i=cc_SetVolume();
4349 RETURN_UP(0);
4350
4351 case CDROMVOLREAD: /* read Volume settings from drive */
4352 msg(DBG_IOC,"ioctl: CDROMVOLREAD entered.\n");
4353 st=cc_GetVolume();
4354 if (st<0) RETURN_UP(st);
4355 volctrl.channel0=current_drive->vol_ctrl0;
4356 volctrl.channel1=current_drive->vol_ctrl1;
4357 volctrl.channel2=0;
4358 volctrl.channel2=0;
4359 memcpy((void *)arg,&volctrl,sizeof(volctrl));
4360 RETURN_UP(0);
4361
4362 case CDROMSUBCHNL: /* Get subchannel info */
4363 msg(DBG_IOS,"ioctl: CDROMSUBCHNL entered.\n");
4364 /* Bogus, I can do better than this! --AJK
4365 if ((st_spinning)||(!subq_valid)) {
4366 i=cc_ReadSubQ();
4367 if (i<0) RETURN_UP(-EIO);
4368 }
4369 */
4370 i=cc_ReadSubQ();
4371 if (i<0) {
4372 j=cc_ReadError(); /* clear out error status from drive */
4373 current_drive->audio_state=CDROM_AUDIO_NO_STATUS;
4374 /* get and set the disk state here,
4375 probably not the right place, but who cares!
4376 It makes it work properly! --AJK */
4377 if (current_drive->CD_changed==0xFF) {
4378 msg(DBG_000,"Disk changed detect\n");
4379 current_drive->diskstate_flags &= ~cd_size_bit;
4380 }
4381 RETURN_UP(-EIO);
4382 }
4383 if (current_drive->CD_changed==0xFF) {
4384 /* reread the TOC because the disk has changed! --AJK */
4385 msg(DBG_000,"Disk changed STILL detected, rereading TOC!\n");
4386 i=DiskInfo();
4387 if(i==0) {
4388 current_drive->CD_changed=0x00; /* cd has changed, procede, */
4389 RETURN_UP(-EIO); /* and get TOC, etc on next try! --AJK */
4390 } else {
4391 RETURN_UP(-EIO); /* we weren't ready yet! --AJK */
4392 }
4393 }
4394 memcpy(&SC, (void *) arg, sizeof(struct cdrom_subchnl));
4395 /*
4396 This virtual crap is very bogus!
4397 It doesn't detect when the cd is done playing audio!
4398 Lets do this right with proper hardware register reading!
4399 */
4400 cc_ReadStatus();
4401 i=ResponseStatus();
4402 msg(DBG_000,"Drive Status: door_locked =%d.\n", st_door_locked);
4403 msg(DBG_000,"Drive Status: door_closed =%d.\n", st_door_closed);
4404 msg(DBG_000,"Drive Status: caddy_in =%d.\n", st_caddy_in);
4405 msg(DBG_000,"Drive Status: disk_ok =%d.\n", st_diskok);
4406 msg(DBG_000,"Drive Status: spinning =%d.\n", st_spinning);
4407 msg(DBG_000,"Drive Status: busy =%d.\n", st_busy);
4408 /* st_busy indicates if it's _ACTUALLY_ playing audio */
4409 switch (current_drive->audio_state)
4410 {
4411 case audio_playing:
4412 if(st_busy==0) {
4413 /* CD has stopped playing audio --AJK */
4414 current_drive->audio_state=audio_completed;
4415 SC.cdsc_audiostatus=CDROM_AUDIO_COMPLETED;
4416 } else {
4417 SC.cdsc_audiostatus=CDROM_AUDIO_PLAY;
4418 }
4419 break;
4420 case audio_pausing:
4421 SC.cdsc_audiostatus=CDROM_AUDIO_PAUSED;
4422 break;
4423 case audio_completed:
4424 SC.cdsc_audiostatus=CDROM_AUDIO_COMPLETED;
4425 break;
4426 default:
4427 SC.cdsc_audiostatus=CDROM_AUDIO_NO_STATUS;
4428 break;
4429 }
4430 SC.cdsc_adr=current_drive->SubQ_ctl_adr;
4431 SC.cdsc_ctrl=current_drive->SubQ_ctl_adr>>4;
4432 SC.cdsc_trk=bcd2bin(current_drive->SubQ_trk);
4433 SC.cdsc_ind=bcd2bin(current_drive->SubQ_pnt_idx);
4434 if (SC.cdsc_format==CDROM_LBA)
4435 {
4436 SC.cdsc_absaddr.lba=msf2blk(current_drive->SubQ_run_tot);
4437 SC.cdsc_reladdr.lba=msf2blk(current_drive->SubQ_run_trk);
4438 }
4439 else /* not only if (SC.cdsc_format==CDROM_MSF) */
4440 {
4441 SC.cdsc_absaddr.msf.minute=(current_drive->SubQ_run_tot>>16)&0x00FF;
4442 SC.cdsc_absaddr.msf.second=(current_drive->SubQ_run_tot>>8)&0x00FF;
4443 SC.cdsc_absaddr.msf.frame=current_drive->SubQ_run_tot&0x00FF;
4444 SC.cdsc_reladdr.msf.minute=(current_drive->SubQ_run_trk>>16)&0x00FF;
4445 SC.cdsc_reladdr.msf.second=(current_drive->SubQ_run_trk>>8)&0x00FF;
4446 SC.cdsc_reladdr.msf.frame=current_drive->SubQ_run_trk&0x00FF;
4447 }
4448 memcpy((void *) arg, &SC, sizeof(struct cdrom_subchnl));
4449 msg(DBG_IOS,"CDROMSUBCHNL: %1X %02X %08X %08X %02X %02X %06X %06X\n",
4450 SC.cdsc_format,SC.cdsc_audiostatus,
4451 SC.cdsc_adr,SC.cdsc_ctrl,
4452 SC.cdsc_trk,SC.cdsc_ind,
4453 SC.cdsc_absaddr,SC.cdsc_reladdr);
4454 RETURN_UP(0);
4455
4456 default:
4457 msg(DBG_IOC,"ioctl: unknown function request %04X\n", cmd);
4458 RETURN_UP(-EINVAL);
4459 } /* end switch(cmd) */
4460}
4461/*==========================================================================*/
4462/*
4463 * Take care of the different block sizes between cdrom and Linux.
4464 */
4465static void sbp_transfer(struct request *req)
4466{
4467 long offs;
4468
4469 while ( (req->nr_sectors > 0) &&
4470 (req->sector/4 >= current_drive->sbp_first_frame) &&
4471 (req->sector/4 <= current_drive->sbp_last_frame) )
4472 {
4473 offs = (req->sector - current_drive->sbp_first_frame * 4) * 512;
4474 memcpy(req->buffer, current_drive->sbp_buf + offs, 512);
4475 req->nr_sectors--;
4476 req->sector++;
4477 req->buffer += 512;
4478 }
4479}
4480/*==========================================================================*/
4481/*
4482 * special end_request for sbpcd to solve CURRENT==NULL bug. (GTL)
4483 * GTL = Gonzalo Tornaria <tornaria@cmat.edu.uy>
4484 *
4485 * This is a kludge so we don't need to modify end_request.
4486 * We put the req we take out after INIT_REQUEST in the requests list,
4487 * so that end_request will discard it.
4488 *
4489 * The bug could be present in other block devices, perhaps we
4490 * should modify INIT_REQUEST and end_request instead, and
4491 * change every block device..
4492 *
4493 * Could be a race here?? Could e.g. a timer interrupt schedule() us?
4494 * If so, we should copy end_request here, and do it right.. (or
4495 * modify end_request and the block devices).
4496 *
4497 * In any case, the race here would be much small than it was, and
4498 * I couldn't reproduce..
4499 *
4500 * The race could be: suppose CURRENT==NULL. We put our req in the list,
4501 * and we are scheduled. Other process takes over, and gets into
4502 * do_sbpcd_request. It sees CURRENT!=NULL (it is == to our req), so
4503 * proceeds. It ends, so CURRENT is now NULL.. Now we awake somewhere in
4504 * end_request, but now CURRENT==NULL... oops!
4505 *
4506 */
4507#undef DEBUG_GTL
4508
4509/*==========================================================================*/
4510/*
4511 * I/O request routine, called from Linux kernel.
4512 */
4513static void do_sbpcd_request(request_queue_t * q)
4514{
4515 u_int block;
4516 u_int nsect;
4517 int status_tries, data_tries;
4518 struct request *req;
4519 struct sbpcd_drive *p;
4520#ifdef DEBUG_GTL
4521 static int xx_nr=0;
4522 int xnr;
4523#endif
4524
4525 request_loop:
4526#ifdef DEBUG_GTL
4527 xnr=++xx_nr;
4528
4529 req = elv_next_request(q);
4530
4531 if (!req)
4532 {
4533 printk( "do_sbpcd_request[%di](NULL), Pid:%d, Time:%li\n",
4534 xnr, current->pid, jiffies);
4535 printk( "do_sbpcd_request[%do](NULL) end 0 (null), Time:%li\n",
4536 xnr, jiffies);
4537 return;
4538 }
4539
4540 printk(" do_sbpcd_request[%di](%p:%ld+%ld), Pid:%d, Time:%li\n",
4541 xnr, req, req->sector, req->nr_sectors, current->pid, jiffies);
4542#endif
4543
4544 req = elv_next_request(q); /* take out our request so no other */
4545 if (!req)
4546 return;
4547
4548 if (req -> sector == -1)
4549 end_request(req, 0);
4550 spin_unlock_irq(q->queue_lock);
4551
4552 down(&ioctl_read_sem);
4553 if (rq_data_dir(elv_next_request(q)) != READ)
4554 {
4555 msg(DBG_INF, "bad cmd %d\n", req->cmd[0]);
4556 goto err_done;
4557 }
4558 p = req->rq_disk->private_data;
4559#if OLD_BUSY
4560 while (busy_audio) sbp_sleep(HZ); /* wait a bit */
4561 busy_data=1;
4562#endif /* OLD_BUSY */
4563
4564 if (p->audio_state==audio_playing) goto err_done;
4565 if (p != current_drive)
4566 switch_drive(p);
4567
4568 block = req->sector; /* always numbered as 512-byte-pieces */
4569 nsect = req->nr_sectors; /* always counted as 512-byte-pieces */
4570
4571 msg(DBG_BSZ,"read sector %d (%d sectors)\n", block, nsect);
4572#if 0
4573 msg(DBG_MUL,"read LBA %d\n", block/4);
4574#endif
4575
4576 sbp_transfer(req);
4577 /* if we satisfied the request from the buffer, we're done. */
4578 if (req->nr_sectors == 0)
4579 {
4580#ifdef DEBUG_GTL
4581 printk(" do_sbpcd_request[%do](%p:%ld+%ld) end 2, Time:%li\n",
4582 xnr, req, req->sector, req->nr_sectors, jiffies);
4583#endif
4584 up(&ioctl_read_sem);
4585 spin_lock_irq(q->queue_lock);
4586 end_request(req, 1);
4587 goto request_loop;
4588 }
4589
4590#ifdef FUTURE
4591 i=prepare(0,0); /* at moment not really a hassle check, but ... */
4592 if (i!=0)
4593 msg(DBG_INF,"\"prepare\" tells error %d -- ignored\n", i);
4594#endif /* FUTURE */
4595
4596 if (!st_spinning) cc_SpinUp();
4597
4598 for (data_tries=n_retries; data_tries > 0; data_tries--)
4599 {
4600 for (status_tries=3; status_tries > 0; status_tries--)
4601 {
4602 flags_cmd_out |= f_respo3;
4603 cc_ReadStatus();
4604 if (sbp_status() != 0) break;
4605 if (st_check) cc_ReadError();
4606 sbp_sleep(1); /* wait a bit, try again */
4607 }
4608 if (status_tries == 0)
4609 {
4610 msg(DBG_INF,"sbp_status: failed after 3 tries in line %d\n", __LINE__);
4611 break;
4612 }
4613
4614 sbp_read_cmd(req);
4615 sbp_sleep(0);
4616 if (sbp_data(req) != 0)
4617 {
4618#ifdef SAFE_MIXED
4619 current_drive->has_data=2; /* is really a data disk */
4620#endif /* SAFE_MIXED */
4621#ifdef DEBUG_GTL
4622 printk(" do_sbpcd_request[%do](%p:%ld+%ld) end 3, Time:%li\n",
4623 xnr, req, req->sector, req->nr_sectors, jiffies);
4624#endif
4625 up(&ioctl_read_sem);
4626 spin_lock_irq(q->queue_lock);
4627 end_request(req, 1);
4628 goto request_loop;
4629 }
4630 }
4631
4632 err_done:
4633#if OLD_BUSY
4634 busy_data=0;
4635#endif /* OLD_BUSY */
4636#ifdef DEBUG_GTL
4637 printk(" do_sbpcd_request[%do](%p:%ld+%ld) end 4 (error), Time:%li\n",
4638 xnr, req, req->sector, req->nr_sectors, jiffies);
4639#endif
4640 up(&ioctl_read_sem);
4641 sbp_sleep(0); /* wait a bit, try again */
4642 spin_lock_irq(q->queue_lock);
4643 end_request(req, 0);
4644 goto request_loop;
4645}
4646/*==========================================================================*/
4647/*
4648 * build and send the READ command.
4649 */
4650static void sbp_read_cmd(struct request *req)
4651{
4652#undef OLD
4653
4654 int i;
4655 int block;
4656
4657 current_drive->sbp_first_frame=current_drive->sbp_last_frame=-1; /* purge buffer */
4658 current_drive->sbp_current = 0;
4659 block=req->sector/4;
4660 if (block+current_drive->sbp_bufsiz <= current_drive->CDsize_frm)
4661 current_drive->sbp_read_frames = current_drive->sbp_bufsiz;
4662 else
4663 {
4664 current_drive->sbp_read_frames=current_drive->CDsize_frm-block;
4665 /* avoid reading past end of data */
4666 if (current_drive->sbp_read_frames < 1)
4667 {
4668 msg(DBG_INF,"requested frame %d, CD size %d ???\n",
4669 block, current_drive->CDsize_frm);
4670 current_drive->sbp_read_frames=1;
4671 }
4672 }
4673
4674 flags_cmd_out = f_putcmd | f_respo2 | f_ResponseStatus | f_obey_p_check;
4675 clr_cmdbuf();
4676 if (famV_drive)
4677 {
4678 drvcmd[0]=CMDV_READ;
4679 lba2msf(block,&drvcmd[1]); /* msf-bcd format required */
4680 bin2bcdx(&drvcmd[1]);
4681 bin2bcdx(&drvcmd[2]);
4682 bin2bcdx(&drvcmd[3]);
4683 drvcmd[4]=current_drive->sbp_read_frames>>8;
4684 drvcmd[5]=current_drive->sbp_read_frames&0xff;
4685 drvcmd[6]=0x02; /* flag "msf-bcd" */
4686 }
4687 else if (fam0L_drive)
4688 {
4689 flags_cmd_out |= f_lopsta | f_getsta | f_bit1;
4690 if (current_drive->xa_byte==0x20)
4691 {
4692 cmd_type=READ_M2;
4693 drvcmd[0]=CMD0_READ_XA; /* "read XA frames", old drives */
4694 drvcmd[1]=(block>>16)&0x0ff;
4695 drvcmd[2]=(block>>8)&0x0ff;
4696 drvcmd[3]=block&0x0ff;
4697 drvcmd[4]=(current_drive->sbp_read_frames>>8)&0x0ff;
4698 drvcmd[5]=current_drive->sbp_read_frames&0x0ff;
4699 }
4700 else
4701 {
4702 drvcmd[0]=CMD0_READ; /* "read frames", old drives */
4703 if (current_drive->drv_type>=drv_201)
4704 {
4705 lba2msf(block,&drvcmd[1]); /* msf-bcd format required */
4706 bin2bcdx(&drvcmd[1]);
4707 bin2bcdx(&drvcmd[2]);
4708 bin2bcdx(&drvcmd[3]);
4709 }
4710 else
4711 {
4712 drvcmd[1]=(block>>16)&0x0ff;
4713 drvcmd[2]=(block>>8)&0x0ff;
4714 drvcmd[3]=block&0x0ff;
4715 }
4716 drvcmd[4]=(current_drive->sbp_read_frames>>8)&0x0ff;
4717 drvcmd[5]=current_drive->sbp_read_frames&0x0ff;
4718 drvcmd[6]=(current_drive->drv_type<drv_201)?0:2; /* flag "lba or msf-bcd format" */
4719 }
4720 }
4721 else if (fam1_drive)
4722 {
4723 drvcmd[0]=CMD1_READ;
4724 lba2msf(block,&drvcmd[1]); /* msf-bin format required */
4725 drvcmd[5]=(current_drive->sbp_read_frames>>8)&0x0ff;
4726 drvcmd[6]=current_drive->sbp_read_frames&0x0ff;
4727 }
4728 else if (fam2_drive)
4729 {
4730 drvcmd[0]=CMD2_READ;
4731 lba2msf(block,&drvcmd[1]); /* msf-bin format required */
4732 drvcmd[4]=(current_drive->sbp_read_frames>>8)&0x0ff;
4733 drvcmd[5]=current_drive->sbp_read_frames&0x0ff;
4734 drvcmd[6]=0x02;
4735 }
4736 else if (famT_drive)
4737 {
4738 drvcmd[0]=CMDT_READ;
4739 drvcmd[2]=(block>>24)&0x0ff;
4740 drvcmd[3]=(block>>16)&0x0ff;
4741 drvcmd[4]=(block>>8)&0x0ff;
4742 drvcmd[5]=block&0x0ff;
4743 drvcmd[7]=(current_drive->sbp_read_frames>>8)&0x0ff;
4744 drvcmd[8]=current_drive->sbp_read_frames&0x0ff;
4745 }
4746 flags_cmd_out=f_putcmd;
4747 response_count=0;
4748 i=cmd_out();
4749 if (i<0) msg(DBG_INF,"error giving READ command: %0d\n", i);
4750 return;
4751}
4752/*==========================================================================*/
4753/*
4754 * Check the completion of the read-data command. On success, read
4755 * the current_drive->sbp_bufsiz * 2048 bytes of data from the disk into buffer.
4756 */
4757static int sbp_data(struct request *req)
4758{
4759 int i=0, j=0, l, frame;
4760 u_int try=0;
4761 u_long timeout;
4762 u_char *p;
4763 u_int data_tries = 0;
4764 u_int data_waits = 0;
4765 u_int data_retrying = 0;
4766 int error_flag;
4767 int xa_count;
4768 int max_latency;
4769 int success;
4770 int wait;
4771 int duration;
4772
4773 error_flag=0;
4774 success=0;
4775#if LONG_TIMING
4776 max_latency=9*HZ;
4777#else
4778 if (current_drive->f_multisession) max_latency=15*HZ;
4779 else max_latency=5*HZ;
4780#endif
4781 duration=jiffies;
4782 for (frame=0;frame<current_drive->sbp_read_frames&&!error_flag; frame++)
4783 {
4784 SBPCD_CLI;
4785
4786 del_timer(&data_timer);
4787 data_timer.expires=jiffies+max_latency;
4788 timed_out_data=0;
4789 add_timer(&data_timer);
4790 while (!timed_out_data)
4791 {
4792 if (current_drive->f_multisession) try=maxtim_data*4;
4793 else try=maxtim_data;
4794 msg(DBG_000,"sbp_data: CDi_status loop: try=%d.\n",try);
4795 for ( ; try!=0;try--)
4796 {
4797 j=inb(CDi_status);
4798 if (!(j&s_not_data_ready)) break;
4799 if (!(j&s_not_result_ready)) break;
4800 if (fam0LV_drive) if (j&s_attention) break;
4801 }
4802 if (!(j&s_not_data_ready)) goto data_ready;
4803 if (try==0)
4804 {
4805 if (data_retrying == 0) data_waits++;
4806 data_retrying = 1;
4807 msg(DBG_000,"sbp_data: CDi_status loop: sleeping.\n");
4808 sbp_sleep(1);
4809 try = 1;
4810 }
4811 }
4812 msg(DBG_INF,"sbp_data: CDi_status loop expired.\n");
4813 data_ready:
4814 del_timer(&data_timer);
4815
4816 if (timed_out_data)
4817 {
4818 msg(DBG_INF,"sbp_data: CDi_status timeout (timed_out_data) (%02X).\n", j);
4819 error_flag++;
4820 }
4821 if (try==0)
4822 {
4823 msg(DBG_INF,"sbp_data: CDi_status timeout (try=0) (%02X).\n", j);
4824 error_flag++;
4825 }
4826 if (!(j&s_not_result_ready))
4827 {
4828 msg(DBG_INF, "sbp_data: RESULT_READY where DATA_READY awaited (%02X).\n", j);
4829 response_count=20;
4830 j=ResponseInfo();
4831 j=inb(CDi_status);
4832 }
4833 if (j&s_not_data_ready)
4834 {
4835 if ((current_drive->ored_ctl_adr&0x40)==0)
4836 msg(DBG_INF, "CD contains no data tracks.\n");
4837 else msg(DBG_INF, "sbp_data: DATA_READY timeout (%02X).\n", j);
4838 error_flag++;
4839 }
4840 SBPCD_STI;
4841 if (error_flag) break;
4842
4843 msg(DBG_000, "sbp_data: beginning to read.\n");
4844 p = current_drive->sbp_buf + frame * CD_FRAMESIZE;
4845 if (sbpro_type==1) OUT(CDo_sel_i_d,1);
4846 if (cmd_type==READ_M2) {
4847 if (do_16bit) insw(CDi_data, xa_head_buf, CD_XA_HEAD>>1);
4848 else insb(CDi_data, xa_head_buf, CD_XA_HEAD);
4849 }
4850 if (do_16bit) insw(CDi_data, p, CD_FRAMESIZE>>1);
4851 else insb(CDi_data, p, CD_FRAMESIZE);
4852 if (cmd_type==READ_M2) {
4853 if (do_16bit) insw(CDi_data, xa_tail_buf, CD_XA_TAIL>>1);
4854 else insb(CDi_data, xa_tail_buf, CD_XA_TAIL);
4855 }
4856 current_drive->sbp_current++;
4857 if (sbpro_type==1) OUT(CDo_sel_i_d,0);
4858 if (cmd_type==READ_M2)
4859 {
4860 for (xa_count=0;xa_count<CD_XA_HEAD;xa_count++)
4861 sprintf(&msgbuf[xa_count*3], " %02X", xa_head_buf[xa_count]);
4862 msgbuf[xa_count*3]=0;
4863 msg(DBG_XA1,"xa head:%s\n", msgbuf);
4864 }
4865 data_retrying = 0;
4866 data_tries++;
4867 if (data_tries >= 1000)
4868 {
4869 msg(DBG_INF,"sbp_data() statistics: %d waits in %d frames.\n", data_waits, data_tries);
4870 data_waits = data_tries = 0;
4871 }
4872 }
4873 duration=jiffies-duration;
4874 msg(DBG_TEA,"time to read %d frames: %d jiffies .\n",frame,duration);
4875 if (famT_drive)
4876 {
4877 wait=8;
4878 do
4879 {
4880 if (teac==2)
4881 {
4882 if ((i=CDi_stat_loop_T()) == -1) break;
4883 }
4884 else
4885 {
4886 sbp_sleep(1);
4887 OUT(CDo_sel_i_d,0);
4888 i=inb(CDi_status);
4889 }
4890 if (!(i&s_not_data_ready))
4891 {
4892 OUT(CDo_sel_i_d,1);
4893 j=0;
4894 do
4895 {
4896 if (do_16bit) i=inw(CDi_data);
4897 else i=inb(CDi_data);
4898 j++;
4899 i=inb(CDi_status);
4900 }
4901 while (!(i&s_not_data_ready));
4902 msg(DBG_TEA, "==========too much data (%d bytes/words)==============.\n", j);
4903 }
4904 if (!(i&s_not_result_ready))
4905 {
4906 OUT(CDo_sel_i_d,0);
4907 l=0;
4908 do
4909 {
4910 infobuf[l++]=inb(CDi_info);
4911 i=inb(CDi_status);
4912 }
4913 while (!(i&s_not_result_ready));
4914 if (infobuf[0]==0x00) success=1;
4915#if 1
4916 for (j=0;j<l;j++) sprintf(&msgbuf[j*3], " %02X", infobuf[j]);
4917 msgbuf[j*3]=0;
4918 msg(DBG_TEA,"sbp_data info response:%s\n", msgbuf);
4919#endif
4920 if (infobuf[0]==0x02)
4921 {
4922 error_flag++;
4923 do
4924 {
4925 ++recursion;
4926 if (recursion>1) msg(DBG_TEA,"cmd_out_T READ_ERR recursion (sbp_data): %d !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n",recursion);
4927 else msg(DBG_TEA,"sbp_data: CMDT_READ_ERR necessary.\n");
4928 clr_cmdbuf();
4929 drvcmd[0]=CMDT_READ_ERR;
4930 j=cmd_out_T(); /* !!! recursive here !!! */
4931 --recursion;
4932 sbp_sleep(1);
4933 }
4934 while (j<0);
4935 current_drive->error_state=infobuf[2];
4936 current_drive->b3=infobuf[3];
4937 current_drive->b4=infobuf[4];
4938 }
4939 break;
4940 }
4941 else
4942 {
4943#if 0
4944 msg(DBG_TEA, "============= waiting for result=================.\n");
4945 sbp_sleep(1);
4946#endif
4947 }
4948 }
4949 while (wait--);
4950 }
4951
4952 if (error_flag) /* must have been spurious D_RDY or (ATTN&&!D_RDY) */
4953 {
4954 msg(DBG_TEA, "================error flag: %d=================.\n", error_flag);
4955 msg(DBG_INF,"sbp_data: read aborted by drive.\n");
4956#if 1
4957 i=cc_DriveReset(); /* ugly fix to prevent a hang */
4958#else
4959 i=cc_ReadError();
4960#endif
4961 return (0);
4962 }
4963
4964 if (fam0LV_drive)
4965 {
4966 SBPCD_CLI;
4967 i=maxtim_data;
4968 for (timeout=jiffies+HZ; time_before(jiffies, timeout); timeout--)
4969 {
4970 for ( ;i!=0;i--)
4971 {
4972 j=inb(CDi_status);
4973 if (!(j&s_not_data_ready)) break;
4974 if (!(j&s_not_result_ready)) break;
4975 if (j&s_attention) break;
4976 }
4977 if (i != 0 || time_after_eq(jiffies, timeout)) break;
4978 sbp_sleep(0);
4979 i = 1;
4980 }
4981 if (i==0) msg(DBG_INF,"status timeout after READ.\n");
4982 if (!(j&s_attention))
4983 {
4984 msg(DBG_INF,"sbp_data: timeout waiting DRV_ATTN - retrying.\n");
4985 i=cc_DriveReset(); /* ugly fix to prevent a hang */
4986 SBPCD_STI;
4987 return (0);
4988 }
4989 SBPCD_STI;
4990 }
4991
4992#if 0
4993 if (!success)
4994#endif
4995 do
4996 {
4997 if (fam0LV_drive) cc_ReadStatus();
4998#if 1
4999 if (famT_drive) msg(DBG_TEA, "================before ResponseStatus=================.\n", i);
5000#endif
5001 i=ResponseStatus(); /* builds status_bits, returns orig. status (old) or faked p_success (new) */
5002#if 1
5003 if (famT_drive) msg(DBG_TEA, "================ResponseStatus: %d=================.\n", i);
5004#endif
5005 if (i<0)
5006 {
5007 msg(DBG_INF,"bad cc_ReadStatus after read: %02X\n", current_drive->status_bits);
5008 return (0);
5009 }
5010 }
5011 while ((fam0LV_drive)&&(!st_check)&&(!(i&p_success)));
5012 if (st_check)
5013 {
5014 i=cc_ReadError();
5015 msg(DBG_INF,"cc_ReadError was necessary after read: %d\n",i);
5016 return (0);
5017 }
5018 if (fatal_err)
5019 {
5020 fatal_err=0;
5021 current_drive->sbp_first_frame=current_drive->sbp_last_frame=-1; /* purge buffer */
5022 current_drive->sbp_current = 0;
5023 msg(DBG_INF,"sbp_data: fatal_err - retrying.\n");
5024 return (0);
5025 }
5026
5027 current_drive->sbp_first_frame = req -> sector / 4;
5028 current_drive->sbp_last_frame = current_drive->sbp_first_frame + current_drive->sbp_read_frames - 1;
5029 sbp_transfer(req);
5030 return (1);
5031}
5032/*==========================================================================*/
5033
5034static int sbpcd_block_open(struct inode *inode, struct file *file)
5035{
5036 struct sbpcd_drive *p = inode->i_bdev->bd_disk->private_data;
5037 return cdrom_open(p->sbpcd_infop, inode, file);
5038}
5039
5040static int sbpcd_block_release(struct inode *inode, struct file *file)
5041{
5042 struct sbpcd_drive *p = inode->i_bdev->bd_disk->private_data;
5043 return cdrom_release(p->sbpcd_infop, file);
5044}
5045
5046static int sbpcd_block_ioctl(struct inode *inode, struct file *file,
5047 unsigned cmd, unsigned long arg)
5048{
5049 struct sbpcd_drive *p = inode->i_bdev->bd_disk->private_data;
5050 struct cdrom_device_info *cdi = p->sbpcd_infop;
5051 int ret, i;
5052
5053 ret = cdrom_ioctl(file, p->sbpcd_infop, inode, cmd, arg);
5054 if (ret != -ENOSYS)
5055 return ret;
5056
5057 msg(DBG_IO2,"ioctl(%s, 0x%08lX, 0x%08lX)\n", cdi->name, cmd, arg);
5058 if (p->drv_id==-1) {
5059 msg(DBG_INF, "ioctl: bad device: %s\n", cdi->name);
5060 return (-ENXIO); /* no such drive */
5061 }
5062 down(&ioctl_read_sem);
5063 if (p != current_drive)
5064 switch_drive(p);
5065
5066 msg(DBG_IO2,"ioctl: device %s, request %04X\n",cdi->name,cmd);
5067 switch (cmd) /* Sun-compatible */
5068 {
5069 case DDIOCSDBG: /* DDI Debug */
5070 if (!capable(CAP_SYS_ADMIN)) RETURN_UP(-EPERM);
5071 i=sbpcd_dbg_ioctl(arg,1);
5072 RETURN_UP(i);
5073 case CDROMRESET: /* hard reset the drive */
5074 msg(DBG_IOC,"ioctl: CDROMRESET entered.\n");
5075 i=DriveReset();
5076 current_drive->audio_state=0;
5077 RETURN_UP(i);
5078
5079 case CDROMREADMODE1:
5080 msg(DBG_IOC,"ioctl: CDROMREADMODE1 requested.\n");
5081#ifdef SAFE_MIXED
5082 if (current_drive->has_data>1) RETURN_UP(-EBUSY);
5083#endif /* SAFE_MIXED */
5084 cc_ModeSelect(CD_FRAMESIZE);
5085 cc_ModeSense();
5086 current_drive->mode=READ_M1;
5087 RETURN_UP(0);
5088
5089 case CDROMREADMODE2: /* not usable at the moment */
5090 msg(DBG_IOC,"ioctl: CDROMREADMODE2 requested.\n");
5091#ifdef SAFE_MIXED
5092 if (current_drive->has_data>1) RETURN_UP(-EBUSY);
5093#endif /* SAFE_MIXED */
5094 cc_ModeSelect(CD_FRAMESIZE_RAW1);
5095 cc_ModeSense();
5096 current_drive->mode=READ_M2;
5097 RETURN_UP(0);
5098
5099 case CDROMAUDIOBUFSIZ: /* configure the audio buffer size */
5100 msg(DBG_IOC,"ioctl: CDROMAUDIOBUFSIZ entered.\n");
5101 if (current_drive->sbp_audsiz>0)
5102 vfree(current_drive->aud_buf);
5103 current_drive->aud_buf=NULL;
5104 current_drive->sbp_audsiz=arg;
5105
5106 if (current_drive->sbp_audsiz>16)
5107 {
5108 current_drive->sbp_audsiz = 0;
5109 RETURN_UP(current_drive->sbp_audsiz);
5110 }
5111
5112 if (current_drive->sbp_audsiz>0)
5113 {
5114 current_drive->aud_buf=(u_char *) vmalloc(current_drive->sbp_audsiz*CD_FRAMESIZE_RAW);
5115 if (current_drive->aud_buf==NULL)
5116 {
5117 msg(DBG_INF,"audio buffer (%d frames) not available.\n",current_drive->sbp_audsiz);
5118 current_drive->sbp_audsiz=0;
5119 }
5120 else msg(DBG_INF,"audio buffer size: %d frames.\n",current_drive->sbp_audsiz);
5121 }
5122 RETURN_UP(current_drive->sbp_audsiz);
5123
5124 case CDROMREADAUDIO:
5125 { /* start of CDROMREADAUDIO */
5126 int i=0, j=0, frame, block=0;
5127 u_int try=0;
5128 u_long timeout;
5129 u_char *p;
5130 u_int data_tries = 0;
5131 u_int data_waits = 0;
5132 u_int data_retrying = 0;
5133 int status_tries;
5134 int error_flag;
5135
5136 msg(DBG_IOC,"ioctl: CDROMREADAUDIO entered.\n");
5137 if (fam0_drive) RETURN_UP(-EINVAL);
5138 if (famL_drive) RETURN_UP(-EINVAL);
5139 if (famV_drive) RETURN_UP(-EINVAL);
5140 if (famT_drive) RETURN_UP(-EINVAL);
5141#ifdef SAFE_MIXED
5142 if (current_drive->has_data>1) RETURN_UP(-EBUSY);
5143#endif /* SAFE_MIXED */
5144 if (current_drive->aud_buf==NULL) RETURN_UP(-EINVAL);
5145 if (copy_from_user(&read_audio, (void __user *)arg,
5146 sizeof(struct cdrom_read_audio)))
5147 RETURN_UP(-EFAULT);
5148 if (read_audio.nframes < 0 || read_audio.nframes>current_drive->sbp_audsiz) RETURN_UP(-EINVAL);
5149 if (!access_ok(VERIFY_WRITE, read_audio.buf,
5150 read_audio.nframes*CD_FRAMESIZE_RAW))
5151 RETURN_UP(-EFAULT);
5152
5153 if (read_audio.addr_format==CDROM_MSF) /* MSF-bin specification of where to start */
5154 block=msf2lba(&read_audio.addr.msf.minute);
5155 else if (read_audio.addr_format==CDROM_LBA) /* lba specification of where to start */
5156 block=read_audio.addr.lba;
5157 else RETURN_UP(-EINVAL);
5158#if 000
5159 i=cc_SetSpeed(speed_150,0,0);
5160 if (i) msg(DBG_AUD,"read_audio: SetSpeed error %d\n", i);
5161#endif
5162 msg(DBG_AUD,"read_audio: lba: %d, msf: %06X\n",
5163 block, blk2msf(block));
5164 msg(DBG_AUD,"read_audio: before cc_ReadStatus.\n");
5165#if OLD_BUSY
5166 while (busy_data) sbp_sleep(HZ/10); /* wait a bit */
5167 busy_audio=1;
5168#endif /* OLD_BUSY */
5169 error_flag=0;
5170 for (data_tries=5; data_tries>0; data_tries--)
5171 {
5172 msg(DBG_AUD,"data_tries=%d ...\n", data_tries);
5173 current_drive->mode=READ_AU;
5174 cc_ModeSelect(CD_FRAMESIZE_RAW);
5175 cc_ModeSense();
5176 for (status_tries=3; status_tries > 0; status_tries--)
5177 {
5178 flags_cmd_out |= f_respo3;
5179 cc_ReadStatus();
5180 if (sbp_status() != 0) break;
5181 if (st_check) cc_ReadError();
5182 sbp_sleep(1); /* wait a bit, try again */
5183 }
5184 if (status_tries == 0)
5185 {
5186 msg(DBG_AUD,"read_audio: sbp_status: failed after 3 tries in line %d.\n", __LINE__);
5187 continue;
5188 }
5189 msg(DBG_AUD,"read_audio: sbp_status: ok.\n");
5190
5191 flags_cmd_out = f_putcmd | f_respo2 | f_ResponseStatus | f_obey_p_check;
5192 if (fam0L_drive)
5193 {
5194 flags_cmd_out |= f_lopsta | f_getsta | f_bit1;
5195 cmd_type=READ_M2;
5196 drvcmd[0]=CMD0_READ_XA; /* "read XA frames", old drives */
5197 drvcmd[1]=(block>>16)&0x000000ff;
5198 drvcmd[2]=(block>>8)&0x000000ff;
5199 drvcmd[3]=block&0x000000ff;
5200 drvcmd[4]=0;
5201 drvcmd[5]=read_audio.nframes; /* # of frames */
5202 drvcmd[6]=0;
5203 }
5204 else if (fam1_drive)
5205 {
5206 drvcmd[0]=CMD1_READ; /* "read frames", new drives */
5207 lba2msf(block,&drvcmd[1]); /* msf-bin format required */
5208 drvcmd[4]=0;
5209 drvcmd[5]=0;
5210 drvcmd[6]=read_audio.nframes; /* # of frames */
5211 }
5212 else if (fam2_drive)
5213 {
5214 drvcmd[0]=CMD2_READ_XA2;
5215 lba2msf(block,&drvcmd[1]); /* msf-bin format required */
5216 drvcmd[4]=0;
5217 drvcmd[5]=read_audio.nframes; /* # of frames */
5218 drvcmd[6]=0x11; /* raw mode */
5219 }
5220 else if (famT_drive) /* CD-55A: not tested yet */
5221 {
5222 }
5223 msg(DBG_AUD,"read_audio: before giving \"read\" command.\n");
5224 flags_cmd_out=f_putcmd;
5225 response_count=0;
5226 i=cmd_out();
5227 if (i<0) msg(DBG_INF,"error giving READ AUDIO command: %0d\n", i);
5228 sbp_sleep(0);
5229 msg(DBG_AUD,"read_audio: after giving \"read\" command.\n");
5230 for (frame=1;frame<2 && !error_flag; frame++)
5231 {
5232 try=maxtim_data;
5233 for (timeout=jiffies+9*HZ; ; )
5234 {
5235 for ( ; try!=0;try--)
5236 {
5237 j=inb(CDi_status);
5238 if (!(j&s_not_data_ready)) break;
5239 if (!(j&s_not_result_ready)) break;
5240 if (fam0L_drive) if (j&s_attention) break;
5241 }
5242 if (try != 0 || time_after_eq(jiffies, timeout)) break;
5243 if (data_retrying == 0) data_waits++;
5244 data_retrying = 1;
5245 sbp_sleep(1);
5246 try = 1;
5247 }
5248 if (try==0)
5249 {
5250 msg(DBG_INF,"read_audio: sbp_data: CDi_status timeout.\n");
5251 error_flag++;
5252 break;
5253 }
5254 msg(DBG_AUD,"read_audio: sbp_data: CDi_status ok.\n");
5255 if (j&s_not_data_ready)
5256 {
5257 msg(DBG_INF, "read_audio: sbp_data: DATA_READY timeout.\n");
5258 error_flag++;
5259 break;
5260 }
5261 msg(DBG_AUD,"read_audio: before reading data.\n");
5262 error_flag=0;
5263 p = current_drive->aud_buf;
5264 if (sbpro_type==1) OUT(CDo_sel_i_d,1);
5265 if (do_16bit)
5266 {
5267 u_short *p2 = (u_short *) p;
5268
5269 for (; (u_char *) p2 < current_drive->aud_buf + read_audio.nframes*CD_FRAMESIZE_RAW;)
5270 {
5271 if ((inb_p(CDi_status)&s_not_data_ready)) continue;
5272
5273 /* get one sample */
5274 *p2++ = inw_p(CDi_data);
5275 *p2++ = inw_p(CDi_data);
5276 }
5277 } else {
5278 for (; p < current_drive->aud_buf + read_audio.nframes*CD_FRAMESIZE_RAW;)
5279 {
5280 if ((inb_p(CDi_status)&s_not_data_ready)) continue;
5281
5282 /* get one sample */
5283 *p++ = inb_p(CDi_data);
5284 *p++ = inb_p(CDi_data);
5285 *p++ = inb_p(CDi_data);
5286 *p++ = inb_p(CDi_data);
5287 }
5288 }
5289 if (sbpro_type==1) OUT(CDo_sel_i_d,0);
5290 data_retrying = 0;
5291 }
5292 msg(DBG_AUD,"read_audio: after reading data.\n");
5293 if (error_flag) /* must have been spurious D_RDY or (ATTN&&!D_RDY) */
5294 {
5295 msg(DBG_AUD,"read_audio: read aborted by drive\n");
5296#if 0000
5297 i=cc_DriveReset(); /* ugly fix to prevent a hang */
5298#else
5299 i=cc_ReadError();
5300#endif
5301 continue;
5302 }
5303 if (fam0L_drive)
5304 {
5305 i=maxtim_data;
5306 for (timeout=jiffies+9*HZ; time_before(jiffies, timeout); timeout--)
5307 {
5308 for ( ;i!=0;i--)
5309 {
5310 j=inb(CDi_status);
5311 if (!(j&s_not_data_ready)) break;
5312 if (!(j&s_not_result_ready)) break;
5313 if (j&s_attention) break;
5314 }
5315 if (i != 0 || time_after_eq(jiffies, timeout)) break;
5316 sbp_sleep(0);
5317 i = 1;
5318 }
5319 if (i==0) msg(DBG_AUD,"read_audio: STATUS TIMEOUT AFTER READ");
5320 if (!(j&s_attention))
5321 {
5322 msg(DBG_AUD,"read_audio: sbp_data: timeout waiting DRV_ATTN - retrying\n");
5323 i=cc_DriveReset(); /* ugly fix to prevent a hang */
5324 continue;
5325 }
5326 }
5327 do
5328 {
5329 if (fam0L_drive) cc_ReadStatus();
5330 i=ResponseStatus(); /* builds status_bits, returns orig. status (old) or faked p_success (new) */
5331 if (i<0) { msg(DBG_AUD,
5332 "read_audio: cc_ReadStatus error after read: %02X\n",
5333 current_drive->status_bits);
5334 continue; /* FIXME */
5335 }
5336 }
5337 while ((fam0L_drive)&&(!st_check)&&(!(i&p_success)));
5338 if (st_check)
5339 {
5340 i=cc_ReadError();
5341 msg(DBG_AUD,"read_audio: cc_ReadError was necessary after read: %02X\n",i);
5342 continue;
5343 }
5344 if (copy_to_user(read_audio.buf,
5345 current_drive->aud_buf,
5346 read_audio.nframes * CD_FRAMESIZE_RAW))
5347 RETURN_UP(-EFAULT);
5348 msg(DBG_AUD,"read_audio: copy_to_user done.\n");
5349 break;
5350 }
5351 cc_ModeSelect(CD_FRAMESIZE);
5352 cc_ModeSense();
5353 current_drive->mode=READ_M1;
5354#if OLD_BUSY
5355 busy_audio=0;
5356#endif /* OLD_BUSY */
5357 if (data_tries == 0)
5358 {
5359 msg(DBG_AUD,"read_audio: failed after 5 tries in line %d.\n", __LINE__);
5360 RETURN_UP(-EIO);
5361 }
5362 msg(DBG_AUD,"read_audio: successful return.\n");
5363 RETURN_UP(0);
5364 } /* end of CDROMREADAUDIO */
5365
5366 default:
5367 msg(DBG_IOC,"ioctl: unknown function request %04X\n", cmd);
5368 RETURN_UP(-EINVAL);
5369 } /* end switch(cmd) */
5370}
5371
5372static int sbpcd_block_media_changed(struct gendisk *disk)
5373{
5374 struct sbpcd_drive *p = disk->private_data;
5375 return cdrom_media_changed(p->sbpcd_infop);
5376}
5377
5378static struct block_device_operations sbpcd_bdops =
5379{
5380 .owner = THIS_MODULE,
5381 .open = sbpcd_block_open,
5382 .release = sbpcd_block_release,
5383 .ioctl = sbpcd_block_ioctl,
5384 .media_changed = sbpcd_block_media_changed,
5385};
5386/*==========================================================================*/
5387/*
5388 * Open the device special file. Check that a disk is in. Read TOC.
5389 */
5390static int sbpcd_open(struct cdrom_device_info *cdi, int purpose)
5391{
5392 struct sbpcd_drive *p = cdi->handle;
5393
5394 down(&ioctl_read_sem);
5395 switch_drive(p);
5396
5397 /*
5398 * try to keep an "open" counter here and lock the door if 0->1.
5399 */
5400 msg(DBG_LCK,"open_count: %d -> %d\n",
5401 current_drive->open_count,current_drive->open_count+1);
5402 if (++current_drive->open_count<=1)
5403 {
5404 int i;
5405 i=LockDoor();
5406 current_drive->open_count=1;
5407 if (famT_drive) msg(DBG_TEA,"sbpcd_open: before i=DiskInfo();.\n");
5408 i=DiskInfo();
5409 if (famT_drive) msg(DBG_TEA,"sbpcd_open: after i=DiskInfo();.\n");
5410 if ((current_drive->ored_ctl_adr&0x40)==0)
5411 {
5412 msg(DBG_INF,"CD contains no data tracks.\n");
5413#ifdef SAFE_MIXED
5414 current_drive->has_data=0;
5415#endif /* SAFE_MIXED */
5416 }
5417#ifdef SAFE_MIXED
5418 else if (current_drive->has_data<1) current_drive->has_data=1;
5419#endif /* SAFE_MIXED */
5420 }
5421 if (!st_spinning) cc_SpinUp();
5422 RETURN_UP(0);
5423}
5424/*==========================================================================*/
5425/*
5426 * On close, we flush all sbp blocks from the buffer cache.
5427 */
5428static void sbpcd_release(struct cdrom_device_info * cdi)
5429{
5430 struct sbpcd_drive *p = cdi->handle;
5431
5432 if (p->drv_id==-1) {
5433 msg(DBG_INF, "release: bad device: %s\n", cdi->name);
5434 return;
5435 }
5436 down(&ioctl_read_sem);
5437 switch_drive(p);
5438 /*
5439 * try to keep an "open" counter here and unlock the door if 1->0.
5440 */
5441 msg(DBG_LCK,"open_count: %d -> %d\n",
5442 p->open_count,p->open_count-1);
5443 if (p->open_count>-2) /* CDROMEJECT may have been done */
5444 {
5445 if (--p->open_count<=0)
5446 {
5447 p->sbp_first_frame=p->sbp_last_frame=-1;
5448 if (p->audio_state!=audio_playing)
5449 if (p->f_eject) cc_SpinDown();
5450 p->diskstate_flags &= ~cd_size_bit;
5451 p->open_count=0;
5452#ifdef SAFE_MIXED
5453 p->has_data=0;
5454#endif /* SAFE_MIXED */
5455 }
5456 }
5457 up(&ioctl_read_sem);
5458 return ;
5459}
5460/*==========================================================================*/
5461/*
5462 *
5463 */
5464static int sbpcd_media_changed( struct cdrom_device_info *cdi, int disc_nr);
5465static struct cdrom_device_ops sbpcd_dops = {
5466 .open = sbpcd_open,
5467 .release = sbpcd_release,
5468 .drive_status = sbpcd_drive_status,
5469 .media_changed = sbpcd_media_changed,
5470 .tray_move = sbpcd_tray_move,
5471 .lock_door = sbpcd_lock_door,
5472 .select_speed = sbpcd_select_speed,
5473 .get_last_session = sbpcd_get_last_session,
5474 .get_mcn = sbpcd_get_mcn,
5475 .reset = sbpcd_reset,
5476 .audio_ioctl = sbpcd_audio_ioctl,
5477 .capability = CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK |
5478 CDC_MULTI_SESSION | CDC_MEDIA_CHANGED |
5479 CDC_MCN | CDC_PLAY_AUDIO,
5480 .n_minors = 1,
5481};
5482
5483/*==========================================================================*/
5484/*
5485 * accept "kernel command line" parameters
5486 * (suggested by Peter MacDonald with SLS 1.03)
5487 *
5488 * This is only implemented for the first controller. Should be enough to
5489 * allow installing with a "strange" distribution kernel.
5490 *
5491 * use: tell LILO:
5492 * sbpcd=0x230,SoundBlaster
5493 * or
5494 * sbpcd=0x300,LaserMate
5495 * or
5496 * sbpcd=0x338,SoundScape
5497 * or
5498 * sbpcd=0x2C0,Teac16bit
5499 *
5500 * (upper/lower case sensitive here - but all-lowercase is ok!!!).
5501 *
5502 * the address value has to be the CDROM PORT ADDRESS -
5503 * not the soundcard base address.
5504 * For the SPEA/SoundScape setup, DO NOT specify the "configuration port"
5505 * address, but the address which is really used for the CDROM (usually 8
5506 * bytes above).
5507 *
5508 */
5509
5510int sbpcd_setup(char *s)
5511{
5512#ifndef MODULE
5513 int p[4];
5514 (void)get_options(s, ARRAY_SIZE(p), p);
5515 setup_done++;
5516 msg(DBG_INI,"sbpcd_setup called with %04X,%s\n",p[1], s);
5517 sbpro_type=0; /* default: "LaserMate" */
5518 if (p[0]>1) sbpro_type=p[2];
5519 else if (!strcmp(s,str_sb)) sbpro_type=1;
5520 else if (!strcmp(s,str_sb_l)) sbpro_type=1;
5521 else if (!strcmp(s,str_sp)) sbpro_type=2;
5522 else if (!strcmp(s,str_sp_l)) sbpro_type=2;
5523 else if (!strcmp(s,str_ss)) sbpro_type=2;
5524 else if (!strcmp(s,str_ss_l)) sbpro_type=2;
5525 else if (!strcmp(s,str_t16)) sbpro_type=3;
5526 else if (!strcmp(s,str_t16_l)) sbpro_type=3;
5527 if (p[0]>0) sbpcd_ioaddr=p[1];
5528 if (p[0]>2) max_drives=p[3];
5529#else
5530 sbpcd_ioaddr = sbpcd[0];
5531 sbpro_type = sbpcd[1];
5532#endif
5533
5534 CDo_command=sbpcd_ioaddr;
5535 CDi_info=sbpcd_ioaddr;
5536 CDi_status=sbpcd_ioaddr+1;
5537 CDo_sel_i_d=sbpcd_ioaddr+1;
5538 CDo_reset=sbpcd_ioaddr+2;
5539 CDo_enable=sbpcd_ioaddr+3;
5540 f_16bit=0;
5541 if ((sbpro_type==1)||(sbpro_type==3))
5542 {
5543 CDi_data=sbpcd_ioaddr;
5544 if (sbpro_type==3)
5545 {
5546 f_16bit=1;
5547 sbpro_type=1;
5548 }
5549 }
5550 else CDi_data=sbpcd_ioaddr+2;
5551
5552 return 1;
5553}
5554
5555__setup("sbpcd=", sbpcd_setup);
5556
5557
5558/*==========================================================================*/
5559/*
5560 * Sequoia S-1000 CD-ROM Interface Configuration
5561 * as used within SPEA Media FX, Ensonic SoundScape and some Reveal cards
5562 * The soundcard has to get jumpered for the interface type "Panasonic"
5563 * (not Sony or Mitsumi) and to get soft-configured for
5564 * -> configuration port address
5565 * -> CDROM port offset (num_ports): has to be 8 here. Possibly this
5566 * offset value determines the interface type (none, Panasonic,
5567 * Mitsumi, Sony).
5568 * The interface uses a configuration port (0x320, 0x330, 0x340, 0x350)
5569 * some bytes below the real CDROM address.
5570 *
5571 * For the Panasonic style (LaserMate) interface and the configuration
5572 * port 0x330, we have to use an offset of 8; so, the real CDROM port
5573 * address is 0x338.
5574 */
5575static int __init config_spea(void)
5576{
5577 /*
5578 * base address offset between configuration port and CDROM port,
5579 * this probably defines the interface type
5580 * 2 (type=??): 0x00
5581 * 8 (type=LaserMate):0x10
5582 * 16 (type=??):0x20
5583 * 32 (type=??):0x30
5584 */
5585 int n_ports=0x10;
5586
5587 int irq_number=0; /* off:0x00, 2/9:0x01, 7:0x03, 12:0x05, 15:0x07 */
5588 int dma_channel=0; /* off: 0x00, 0:0x08, 1:0x18, 3:0x38, 5:0x58, 6:0x68 */
5589 int dack_polarity=0; /* L:0x00, H:0x80 */
5590 int drq_polarity=0x40; /* L:0x00, H:0x40 */
5591 int i;
5592
5593#define SPEA_REG_1 sbpcd_ioaddr-0x08+4
5594#define SPEA_REG_2 sbpcd_ioaddr-0x08+5
5595
5596 OUT(SPEA_REG_1,0xFF);
5597 i=inb(SPEA_REG_1);
5598 if (i!=0x0F)
5599 {
5600 msg(DBG_SEQ,"no SPEA interface at %04X present.\n", sbpcd_ioaddr);
5601 return (-1); /* no interface found */
5602 }
5603 OUT(SPEA_REG_1,0x04);
5604 OUT(SPEA_REG_2,0xC0);
5605
5606 OUT(SPEA_REG_1,0x05);
5607 OUT(SPEA_REG_2,0x10|drq_polarity|dack_polarity);
5608
5609#if 1
5610#define SPEA_PATTERN 0x80
5611#else
5612#define SPEA_PATTERN 0x00
5613#endif
5614 OUT(SPEA_REG_1,0x06);
5615 OUT(SPEA_REG_2,dma_channel|irq_number|SPEA_PATTERN);
5616 OUT(SPEA_REG_2,dma_channel|irq_number|SPEA_PATTERN);
5617
5618 OUT(SPEA_REG_1,0x09);
5619 i=(inb(SPEA_REG_2)&0xCF)|n_ports;
5620 OUT(SPEA_REG_2,i);
5621
5622 sbpro_type = 0; /* acts like a LaserMate interface now */
5623 msg(DBG_SEQ,"found SoundScape interface at %04X.\n", sbpcd_ioaddr);
5624 return (0);
5625}
5626
5627/*==========================================================================*/
5628/*
5629 * Test for presence of drive and initialize it.
5630 * Called once at boot or load time.
5631 */
5632
5633/* FIXME: cleanups after failed allocations are too ugly for words */
5634#ifdef MODULE
5635int __init __sbpcd_init(void)
5636#else
5637int __init sbpcd_init(void)
5638#endif
5639{
5640 int i=0, j=0;
5641 int addr[2]={1, CDROM_PORT};
5642 int port_index;
5643
5644 sti();
5645
5646 msg(DBG_INF,"sbpcd.c %s\n", VERSION);
5647#ifndef MODULE
5648#if DISTRIBUTION
5649 if (!setup_done)
5650 {
5651 msg(DBG_INF,"Looking for Matsushita/Panasonic, CreativeLabs, Longshine, TEAC CD-ROM drives\n");
5652 msg(DBG_INF,"= = = = = = = = = = W A R N I N G = = = = = = = = = =\n");
5653 msg(DBG_INF,"Auto-Probing can cause a hang (f.e. touching an NE2000 card).\n");
5654 msg(DBG_INF,"If that happens, you have to reboot and use the\n");
5655 msg(DBG_INF,"LILO (kernel) command line feature like:\n");
5656 msg(DBG_INF," LILO boot: ... sbpcd=0x230,SoundBlaster\n");
5657 msg(DBG_INF,"or like:\n");
5658 msg(DBG_INF," LILO boot: ... sbpcd=0x300,LaserMate\n");
5659 msg(DBG_INF,"or like:\n");
5660 msg(DBG_INF," LILO boot: ... sbpcd=0x338,SoundScape\n");
5661 msg(DBG_INF,"with your REAL address.\n");
5662 msg(DBG_INF,"= = = = = = = = = = END of WARNING = = = = = == = = =\n");
5663 }
5664#endif /* DISTRIBUTION */
5665 sbpcd[0]=sbpcd_ioaddr; /* possibly changed by kernel command line */
5666 sbpcd[1]=sbpro_type; /* possibly changed by kernel command line */
5667#endif /* MODULE */
5668
5669 for (port_index=0;port_index<NUM_PROBE;port_index+=2)
5670 {
5671 addr[1]=sbpcd[port_index];
5672 if (addr[1]==0) break;
5673 if (check_region(addr[1],4))
5674 {
5675 msg(DBG_INF,"check_region: %03X is not free.\n",addr[1]);
5676 continue;
5677 }
5678 if (sbpcd[port_index+1]==2) type=str_sp;
5679 else if (sbpcd[port_index+1]==1) type=str_sb;
5680 else if (sbpcd[port_index+1]==3) type=str_t16;
5681 else type=str_lm;
5682 sbpcd_setup((char *)type);
5683#if DISTRIBUTION
5684 msg(DBG_INF,"Scanning 0x%X (%s)...\n", CDo_command, type);
5685#endif /* DISTRIBUTION */
5686 if (sbpcd[port_index+1]==2)
5687 {
5688 i=config_spea();
5689 if (i<0) continue;
5690 }
5691#ifdef PATH_CHECK
5692 if (check_card(addr[1])) continue;
5693#endif /* PATH_CHECK */
5694 i=check_drives();
5695 msg(DBG_INI,"check_drives done.\n");
5696 if (i>=0) break; /* drive found */
5697 } /* end of cycling through the set of possible I/O port addresses */
5698
5699 if (ndrives==0)
5700 {
5701 msg(DBG_INF, "No drive found.\n");
5702#ifdef MODULE
5703 return -EIO;
5704#else
5705 goto init_done;
5706#endif /* MODULE */
5707 }
5708
5709 if (port_index>0)
5710 {
5711 msg(DBG_INF, "You should read Documentation/cdrom/sbpcd\n");
5712 msg(DBG_INF, "and then configure sbpcd.h for your hardware.\n");
5713 }
5714 check_datarate();
5715 msg(DBG_INI,"check_datarate done.\n");
5716
5717 for (j=0;j<NR_SBPCD;j++)
5718 {
5719 struct sbpcd_drive *p = D_S + j;
5720 if (p->drv_id==-1)
5721 continue;
5722 switch_drive(p);
5723#if 1
5724 if (!famL_drive) cc_DriveReset();
5725#endif
5726 if (!st_spinning) cc_SpinUp();
5727 p->sbp_first_frame = -1; /* First frame in buffer */
5728 p->sbp_last_frame = -1; /* Last frame in buffer */
5729 p->sbp_read_frames = 0; /* Number of frames being read to buffer */
5730 p->sbp_current = 0; /* Frame being currently read */
5731 p->CD_changed=1;
5732 p->frame_size=CD_FRAMESIZE;
5733 p->f_eject=0;
5734#if EJECT
5735 if (!fam0_drive) p->f_eject=1;
5736#endif /* EJECT */
5737 cc_ReadStatus();
5738 i=ResponseStatus(); /* returns orig. status or p_busy_new */
5739 if (famT_drive) i=ResponseStatus(); /* returns orig. status or p_busy_new */
5740 if (i<0)
5741 {
5742 if (i!=-402)
5743 msg(DBG_INF,"init: ResponseStatus returns %d.\n",i);
5744 }
5745 else
5746 {
5747 if (st_check)
5748 {
5749 i=cc_ReadError();
5750 msg(DBG_INI,"init: cc_ReadError returns %d\n",i);
5751 }
5752 }
5753 msg(DBG_INI,"init: first GetStatus: %d\n",i);
5754 msg(DBG_LCS,"init: first GetStatus: error_byte=%d\n",
5755 p->error_byte);
5756 if (p->error_byte==aud_12)
5757 {
5758 timeout=jiffies+2*HZ;
5759 do
5760 {
5761 i=GetStatus();
5762 msg(DBG_INI,"init: second GetStatus: %02X\n",i);
5763 msg(DBG_LCS,
5764 "init: second GetStatus: error_byte=%d\n",
5765 p->error_byte);
5766 if (i<0) break;
5767 if (!st_caddy_in) break;
5768 }
5769 while ((!st_diskok)||time_after(jiffies, timeout));
5770 }
5771 i=SetSpeed();
5772 if (i>=0) p->CD_changed=1;
5773 }
5774
5775 if (!request_region(CDo_command,4,major_name))
5776 {
5777 printk(KERN_WARNING "sbpcd: Unable to request region 0x%x\n", CDo_command);
5778 return -EIO;
5779 }
5780
5781 /*
5782 * Turn on the CD audio channels.
5783 * The addresses are obtained from SOUND_BASE (see sbpcd.h).
5784 */
5785#if SOUND_BASE
5786 OUT(MIXER_addr,MIXER_CD_Volume); /* select SB Pro mixer register */
5787 OUT(MIXER_data,0xCC); /* one nibble per channel, max. value: 0xFF */
5788#endif /* SOUND_BASE */
5789
5790 if (register_blkdev(MAJOR_NR, major_name)) {
5791#ifdef MODULE
5792 return -EIO;
5793#else
5794 goto init_done;
5795#endif /* MODULE */
5796 }
5797
5798 /*
5799 * init error handling is broken beyond belief in this driver...
5800 */
5801 sbpcd_queue = blk_init_queue(do_sbpcd_request, &sbpcd_lock);
5802 if (!sbpcd_queue) {
5803 release_region(CDo_command,4);
5804 unregister_blkdev(MAJOR_NR, major_name);
5805 return -ENOMEM;
5806 }
5807
5808 for (j=0;j<NR_SBPCD;j++)
5809 {
5810 struct cdrom_device_info * sbpcd_infop;
5811 struct gendisk *disk;
5812 struct sbpcd_drive *p = D_S + j;
5813
5814 if (p->drv_id==-1) continue;
5815 switch_drive(p);
5816#ifdef SAFE_MIXED
5817 p->has_data=0;
5818#endif /* SAFE_MIXED */
5819 /*
5820 * allocate memory for the frame buffers
5821 */
5822 p->aud_buf=NULL;
5823 p->sbp_audsiz=0;
5824 p->sbp_bufsiz=buffers;
5825 if (p->drv_type&drv_fam1)
5826 if (READ_AUDIO>0)
5827 p->sbp_audsiz = READ_AUDIO;
5828 p->sbp_buf=(u_char *) vmalloc(buffers*CD_FRAMESIZE);
5829 if (!p->sbp_buf) {
5830 msg(DBG_INF,"data buffer (%d frames) not available.\n",
5831 buffers);
5832 if ((unregister_blkdev(MAJOR_NR, major_name) == -EINVAL))
5833 {
5834 printk("Can't unregister %s\n", major_name);
5835 }
5836 release_region(CDo_command,4);
5837 blk_cleanup_queue(sbpcd_queue);
5838 return -EIO;
5839 }
5840#ifdef MODULE
5841 msg(DBG_INF,"data buffer size: %d frames.\n",buffers);
5842#endif /* MODULE */
5843 if (p->sbp_audsiz>0)
5844 {
5845 p->aud_buf=(u_char *) vmalloc(p->sbp_audsiz*CD_FRAMESIZE_RAW);
5846 if (p->aud_buf==NULL) msg(DBG_INF,"audio buffer (%d frames) not available.\n",p->sbp_audsiz);
5847 else msg(DBG_INF,"audio buffer size: %d frames.\n",p->sbp_audsiz);
5848 }
5849 sbpcd_infop = vmalloc(sizeof (struct cdrom_device_info));
5850 if (sbpcd_infop == NULL)
5851 {
5852 release_region(CDo_command,4);
5853 blk_cleanup_queue(sbpcd_queue);
5854 return -ENOMEM;
5855 }
5856 memset(sbpcd_infop, 0, sizeof(struct cdrom_device_info));
5857 sbpcd_infop->ops = &sbpcd_dops;
5858 sbpcd_infop->speed = 2;
5859 sbpcd_infop->capacity = 1;
5860 sprintf(sbpcd_infop->name, "sbpcd%d", j);
5861 sbpcd_infop->handle = p;
5862 p->sbpcd_infop = sbpcd_infop;
5863 disk = alloc_disk(1);
5864 disk->major = MAJOR_NR;
5865 disk->first_minor = j;
5866 disk->fops = &sbpcd_bdops;
5867 strcpy(disk->disk_name, sbpcd_infop->name);
5868 disk->flags = GENHD_FL_CD;
5869 p->disk = disk;
5870 if (register_cdrom(sbpcd_infop))
5871 {
5872 printk(" sbpcd: Unable to register with Uniform CD-ROm driver\n");
5873 }
5874 disk->private_data = p;
5875 disk->queue = sbpcd_queue;
5876 add_disk(disk);
5877 }
5878 blk_queue_hardsect_size(sbpcd_queue, CD_FRAMESIZE);
5879
5880#ifndef MODULE
5881 init_done:
5882#endif
5883 return 0;
5884}
5885/*==========================================================================*/
5886#ifdef MODULE
5887static void sbpcd_exit(void)
5888{
5889 int j;
5890
5891 if ((unregister_blkdev(MAJOR_NR, major_name) == -EINVAL))
5892 {
5893 msg(DBG_INF, "What's that: can't unregister %s.\n", major_name);
5894 return;
5895 }
5896 release_region(CDo_command,4);
5897 blk_cleanup_queue(sbpcd_queue);
5898 for (j=0;j<NR_SBPCD;j++)
5899 {
5900 if (D_S[j].drv_id==-1) continue;
5901 del_gendisk(D_S[j].disk);
5902 put_disk(D_S[j].disk);
5903 vfree(D_S[j].sbp_buf);
5904 if (D_S[j].sbp_audsiz>0)
5905 vfree(D_S[j].aud_buf);
5906 if ((unregister_cdrom(D_S[j].sbpcd_infop) == -EINVAL))
5907 {
5908 msg(DBG_INF, "What's that: can't unregister info %s.\n", major_name);
5909 return;
5910 }
5911 vfree(D_S[j].sbpcd_infop);
5912 }
5913 msg(DBG_INF, "%s module released.\n", major_name);
5914}
5915
5916
5917module_init(__sbpcd_init) /*HACK!*/;
5918module_exit(sbpcd_exit);
5919
5920
5921#endif /* MODULE */
5922static int sbpcd_media_changed(struct cdrom_device_info *cdi, int disc_nr)
5923{
5924 struct sbpcd_drive *p = cdi->handle;
5925 msg(DBG_CHK,"media_check (%s) called\n", cdi->name);
5926
5927 if (p->CD_changed==0xFF)
5928 {
5929 p->CD_changed=0;
5930 msg(DBG_CHK,"medium changed (drive %s)\n", cdi->name);
5931 current_drive->diskstate_flags &= ~toc_bit;
5932 /* we *don't* need invalidate here, it's done by caller */
5933 current_drive->diskstate_flags &= ~cd_size_bit;
5934#ifdef SAFE_MIXED
5935 current_drive->has_data=0;
5936#endif /* SAFE_MIXED */
5937
5938 return (1);
5939 }
5940 else
5941 return (0);
5942}
5943
5944MODULE_LICENSE("GPL");
5945/* FIXME: Old modules.conf claims MATSUSHITA_CDROM2_MAJOR and CDROM3, but
5946 AFAICT this doesn't support those majors, so why? --RR 30 Jul 2003 */
5947MODULE_ALIAS_BLOCKDEV_MAJOR(MATSUSHITA_CDROM_MAJOR);
5948
5949/*==========================================================================*/
5950/*
5951 * Overrides for Emacs so that we follow Linus's tabbing style.
5952 * Emacs will notice this stuff at the end of the file and automatically
5953 * adjust the settings for this buffer only. This must remain at the end
5954 * of the file.
5955 * ---------------------------------------------------------------------------
5956 * Local variables:
5957 * c-indent-level: 8
5958 * c-brace-imaginary-offset: 0
5959 * c-brace-offset: -8
5960 * c-argdecl-indent: 8
5961 * c-label-offset: -8
5962 * c-continued-statement-offset: 8
5963 * c-continued-brace-offset: 0
5964 * End:
5965 */
5966
diff --git a/drivers/cdrom/sbpcd.h b/drivers/cdrom/sbpcd.h
deleted file mode 100644
index 2f2225f13c6f..000000000000
--- a/drivers/cdrom/sbpcd.h
+++ /dev/null
@@ -1,839 +0,0 @@
1/*
2 * sbpcd.h Specify interface address and interface type here.
3 */
4
5/*
6 * Attention! This file contains user-serviceable parts!
7 * I recommend to make use of it...
8 * If you feel helpless, look into Documentation/cdrom/sbpcd
9 * (good idea anyway, at least before mailing me).
10 *
11 * The definitions for the first controller can get overridden by
12 * the kernel command line ("lilo boot option").
13 * Examples:
14 * sbpcd=0x300,LaserMate
15 * or
16 * sbpcd=0x230,SoundBlaster
17 * or
18 * sbpcd=0x338,SoundScape
19 * or
20 * sbpcd=0x2C0,Teac16bit
21 *
22 * If sbpcd gets used as a module, you can load it with
23 * insmod sbpcd.o sbpcd=0x300,0
24 * or
25 * insmod sbpcd.o sbpcd=0x230,1
26 * or
27 * insmod sbpcd.o sbpcd=0x338,2
28 * or
29 * insmod sbpcd.o sbpcd=0x2C0,3
30 * respective to override the configured address and type.
31 */
32
33/*
34 * define your CDROM port base address as CDROM_PORT
35 * and specify the type of your interface card as SBPRO.
36 *
37 * address:
38 * ========
39 * SBPRO type addresses typically are 0x0230 (=0x220+0x10), 0x0250, ...
40 * LASERMATE type (CI-101P, WDH-7001C) addresses typically are 0x0300, ...
41 * SOUNDSCAPE addresses are from the LASERMATE type and range. You have to
42 * specify the REAL address here, not the configuration port address. Look
43 * at the CDROM driver's invoking line within your DOS CONFIG.SYS, or let
44 * sbpcd auto-probe, if you are not firm with the address.
45 * There are some soundcards on the market with 0x0630, 0x0650, ...; their
46 * type is not obvious (both types are possible).
47 *
48 * example: if your SBPRO audio address is 0x220, specify 0x230 and SBPRO 1.
49 * if your soundcard has its CDROM port above 0x300, specify
50 * that address and try SBPRO 0 first.
51 * if your SoundScape configuration port is at 0x330, specify
52 * 0x338 and SBPRO 2.
53 *
54 * interface type:
55 * ===============
56 * set SBPRO to 1 for "true" SoundBlaster card
57 * set SBPRO to 0 for "compatible" soundcards and
58 * for "poor" (no sound) interface cards.
59 * set SBPRO to 2 for Ensonic SoundScape or SPEA Media FX cards
60 * set SBPRO to 3 for Teac 16bit interface cards
61 *
62 * Almost all "compatible" sound boards need to set SBPRO to 0.
63 * If SBPRO is set wrong, the drives will get found - but any
64 * data access will give errors (audio access will work).
65 * The "OmniCD" no-sound interface card from CreativeLabs and most Teac
66 * interface cards need SBPRO 1.
67 *
68 * sound base:
69 * ===========
70 * The SOUND_BASE definition tells if we should try to turn the CD sound
71 * channels on. It will only be of use regarding soundcards with a SbPro
72 * compatible mixer.
73 *
74 * Example: #define SOUND_BASE 0x220 enables the sound card's CD channels
75 * #define SOUND_BASE 0 leaves the soundcard untouched
76 */
77#define CDROM_PORT 0x340 /* <-----------<< port address */
78#define SBPRO 0 /* <-----------<< interface type */
79#define MAX_DRIVES 4 /* set to 1 if the card does not use "drive select" */
80#define SOUND_BASE 0x220 /* <-----------<< sound address of this card or 0 */
81
82/*
83 * some more or less user dependent definitions - service them!
84 */
85
86/* Set this to 0 once you have configured your interface definitions right. */
87#define DISTRIBUTION 1
88
89/*
90 * Time to wait after giving a message.
91 * This gets important if you enable non-standard DBG_xxx flags.
92 * You will see what happens if you omit the pause or make it
93 * too short. Be warned!
94 */
95#define KLOGD_PAUSE 1
96
97/* tray control: eject tray if no disk is in */
98#if DISTRIBUTION
99#define JUKEBOX 0
100#else
101#define JUKEBOX 1
102#endif /* DISTRIBUTION */
103
104/* tray control: eject tray after last use */
105#if DISTRIBUTION
106#define EJECT 0
107#else
108#define EJECT 1
109#endif /* DISTRIBUTION */
110
111/* max. number of audio frames to read with one */
112/* request (allocates n* 2352 bytes kernel memory!) */
113/* may be freely adjusted, f.e. 75 (= 1 sec.), at */
114/* runtime by use of the CDROMAUDIOBUFSIZ ioctl. */
115#define READ_AUDIO 0
116
117/* Optimizations for the Teac CD-55A drive read performance.
118 * SBP_TEAC_SPEED can be changed here, or one can set the
119 * variable "teac" when loading as a module.
120 * Valid settings are:
121 * 0 - very slow - the recommended "DISTRIBUTION 1" setup.
122 * 1 - 2x performance with little overhead. No busy waiting.
123 * 2 - 4x performance with 5ms overhead per read. Busy wait.
124 *
125 * Setting SBP_TEAC_SPEED or the variable 'teac' to anything
126 * other than 0 may cause problems. If you run into them, first
127 * change SBP_TEAC_SPEED back to 0 and see if your drive responds
128 * normally. If yes, you are "allowed" to report your case - to help
129 * me with the driver, not to solve your hassle. Don´t mail if you
130 * simply are stuck into your own "tuning" experiments, you know?
131 */
132#define SBP_TEAC_SPEED 1
133
134/*==========================================================================*/
135/*==========================================================================*/
136/*
137 * nothing to change below here if you are not fully aware what you're doing
138 */
139#ifndef _LINUX_SBPCD_H
140
141#define _LINUX_SBPCD_H
142/*==========================================================================*/
143/*==========================================================================*/
144/*
145 * driver's own read_ahead, data mode
146 */
147#define SBP_BUFFER_FRAMES 8
148
149#define LONG_TIMING 0 /* test against timeouts with "gold" CDs on CR-521 */
150#undef FUTURE
151#undef SAFE_MIXED
152
153#define TEST_UPC 0
154#define SPEA_TEST 0
155#define TEST_STI 0
156#define OLD_BUSY 0
157#undef PATH_CHECK
158#ifndef SOUND_BASE
159#define SOUND_BASE 0
160#endif
161#if DISTRIBUTION
162#undef SBP_TEAC_SPEED
163#define SBP_TEAC_SPEED 0
164#endif
165/*==========================================================================*/
166/*
167 * DDI interface definitions
168 * "invented" by Fred N. van Kempen..
169 */
170#define DDIOCSDBG 0x9000
171
172/*==========================================================================*/
173/*
174 * "private" IOCTL functions
175 */
176#define CDROMAUDIOBUFSIZ 0x5382 /* set the audio buffer size */
177
178/*==========================================================================*/
179/*
180 * Debug output levels
181 */
182#define DBG_INF 1 /* necessary information */
183#define DBG_BSZ 2 /* BLOCK_SIZE trace */
184#define DBG_REA 3 /* READ status trace */
185#define DBG_CHK 4 /* MEDIA CHECK trace */
186#define DBG_TIM 5 /* datarate timer test */
187#define DBG_INI 6 /* initialization trace */
188#define DBG_TOC 7 /* tell TocEntry values */
189#define DBG_IOC 8 /* ioctl trace */
190#define DBG_STA 9 /* ResponseStatus() trace */
191#define DBG_ERR 10 /* cc_ReadError() trace */
192#define DBG_CMD 11 /* cmd_out() trace */
193#define DBG_WRN 12 /* give explanation before auto-probing */
194#define DBG_MUL 13 /* multi session code test */
195#define DBG_IDX 14 /* test code for drive_id !=0 */
196#define DBG_IOX 15 /* some special information */
197#define DBG_DID 16 /* drive ID test */
198#define DBG_RES 17 /* drive reset info */
199#define DBG_SPI 18 /* SpinUp test */
200#define DBG_IOS 19 /* ioctl trace: subchannel functions */
201#define DBG_IO2 20 /* ioctl trace: general */
202#define DBG_UPC 21 /* show UPC information */
203#define DBG_XA1 22 /* XA mode debugging */
204#define DBG_LCK 23 /* door (un)lock info */
205#define DBG_SQ1 24 /* dump SubQ frame */
206#define DBG_AUD 25 /* READ AUDIO debugging */
207#define DBG_SEQ 26 /* Sequoia interface configuration trace */
208#define DBG_LCS 27 /* Longshine LCS-7260 debugging trace */
209#define DBG_CD2 28 /* MKE/Funai CD200 debugging trace */
210#define DBG_TEA 29 /* TEAC CD-55A debugging trace */
211#define DBG_ECS 30 /* ECS-AT (Vertos 100) debugging trace */
212#define DBG_000 31 /* unnecessary information */
213
214/*==========================================================================*/
215/*==========================================================================*/
216
217/*
218 * bits of flags_cmd_out:
219 */
220#define f_respo3 0x100
221#define f_putcmd 0x80
222#define f_respo2 0x40
223#define f_lopsta 0x20
224#define f_getsta 0x10
225#define f_ResponseStatus 0x08
226#define f_obey_p_check 0x04
227#define f_bit1 0x02
228#define f_wait_if_busy 0x01
229
230/*
231 * diskstate_flags:
232 */
233#define x80_bit 0x80
234#define upc_bit 0x40
235#define volume_bit 0x20
236#define toc_bit 0x10
237#define multisession_bit 0x08
238#define cd_size_bit 0x04
239#define subq_bit 0x02
240#define frame_size_bit 0x01
241
242/*
243 * disk states (bits of diskstate_flags):
244 */
245#define upc_valid (current_drive->diskstate_flags&upc_bit)
246#define volume_valid (current_drive->diskstate_flags&volume_bit)
247#define toc_valid (current_drive->diskstate_flags&toc_bit)
248#define cd_size_valid (current_drive->diskstate_flags&cd_size_bit)
249#define subq_valid (current_drive->diskstate_flags&subq_bit)
250#define frame_size_valid (current_drive->diskstate_flags&frame_size_bit)
251
252/*
253 * the status_bits variable
254 */
255#define p_success 0x100
256#define p_door_closed 0x80
257#define p_caddy_in 0x40
258#define p_spinning 0x20
259#define p_check 0x10
260#define p_busy_new 0x08
261#define p_door_locked 0x04
262#define p_disk_ok 0x01
263
264/*
265 * LCS-7260 special status result bits:
266 */
267#define p_lcs_door_locked 0x02
268#define p_lcs_door_closed 0x01 /* probably disk_in */
269
270/*
271 * CR-52x special status result bits:
272 */
273#define p_caddin_old 0x40
274#define p_success_old 0x08
275#define p_busy_old 0x04
276#define p_bit_1 0x02 /* hopefully unused now */
277
278/*
279 * "generation specific" defs of the status result bits:
280 */
281#define p0_door_closed 0x80
282#define p0_caddy_in 0x40
283#define p0_spinning 0x20
284#define p0_check 0x10
285#define p0_success 0x08 /* unused */
286#define p0_busy 0x04
287#define p0_bit_1 0x02 /* unused */
288#define p0_disk_ok 0x01
289
290#define pL_disk_in 0x40
291#define pL_spinning 0x20
292#define pL_check 0x10
293#define pL_success 0x08 /* unused ?? */
294#define pL_busy 0x04
295#define pL_door_locked 0x02
296#define pL_door_closed 0x01
297
298#define pV_door_closed 0x40
299#define pV_spinning 0x20
300#define pV_check 0x10
301#define pV_success 0x08
302#define pV_busy 0x04
303#define pV_door_locked 0x02
304#define pV_disk_ok 0x01
305
306#define p1_door_closed 0x80
307#define p1_disk_in 0x40
308#define p1_spinning 0x20
309#define p1_check 0x10
310#define p1_busy 0x08
311#define p1_door_locked 0x04
312#define p1_bit_1 0x02 /* unused */
313#define p1_disk_ok 0x01
314
315#define p2_disk_ok 0x80
316#define p2_door_locked 0x40
317#define p2_spinning 0x20
318#define p2_busy2 0x10
319#define p2_busy1 0x08
320#define p2_door_closed 0x04
321#define p2_disk_in 0x02
322#define p2_check 0x01
323
324/*
325 * used drive states:
326 */
327#define st_door_closed (current_drive->status_bits&p_door_closed)
328#define st_caddy_in (current_drive->status_bits&p_caddy_in)
329#define st_spinning (current_drive->status_bits&p_spinning)
330#define st_check (current_drive->status_bits&p_check)
331#define st_busy (current_drive->status_bits&p_busy_new)
332#define st_door_locked (current_drive->status_bits&p_door_locked)
333#define st_diskok (current_drive->status_bits&p_disk_ok)
334
335/*
336 * bits of the CDi_status register:
337 */
338#define s_not_result_ready 0x04 /* 0: "result ready" */
339#define s_not_data_ready 0x02 /* 0: "data ready" */
340#define s_attention 0x01 /* 1: "attention required" */
341/*
342 * usable as:
343 */
344#define DRV_ATTN ((inb(CDi_status)&s_attention)!=0)
345#define DATA_READY ((inb(CDi_status)&s_not_data_ready)==0)
346#define RESULT_READY ((inb(CDi_status)&s_not_result_ready)==0)
347
348/*
349 * drive families and types (firmware versions):
350 */
351#define drv_fam0 0x0100 /* CR-52x family */
352#define drv_199 (drv_fam0+0x01) /* <200 */
353#define drv_200 (drv_fam0+0x02) /* <201 */
354#define drv_201 (drv_fam0+0x03) /* <210 */
355#define drv_210 (drv_fam0+0x04) /* <211 */
356#define drv_211 (drv_fam0+0x05) /* <300 */
357#define drv_300 (drv_fam0+0x06) /* >=300 */
358
359#define drv_fam1 0x0200 /* CR-56x family */
360#define drv_099 (drv_fam1+0x01) /* <100 */
361#define drv_100 (drv_fam1+0x02) /* >=100, only 1.02 and 5.00 known */
362
363#define drv_fam2 0x0400 /* CD200 family */
364
365#define drv_famT 0x0800 /* TEAC CD-55A */
366
367#define drv_famL 0x1000 /* Longshine family */
368#define drv_260 (drv_famL+0x01) /* LCS-7260 */
369#define drv_e1 (drv_famL+0x01) /* LCS-7260, firmware "A E1" */
370#define drv_f4 (drv_famL+0x02) /* LCS-7260, firmware "A4F4" */
371
372#define drv_famV 0x2000 /* ECS-AT (vertos-100) family */
373#define drv_at (drv_famV+0x01) /* ECS-AT, firmware "1.00" */
374
375#define fam0_drive (current_drive->drv_type&drv_fam0)
376#define famL_drive (current_drive->drv_type&drv_famL)
377#define famV_drive (current_drive->drv_type&drv_famV)
378#define fam1_drive (current_drive->drv_type&drv_fam1)
379#define fam2_drive (current_drive->drv_type&drv_fam2)
380#define famT_drive (current_drive->drv_type&drv_famT)
381#define fam0L_drive (current_drive->drv_type&(drv_fam0|drv_famL))
382#define fam0V_drive (current_drive->drv_type&(drv_fam0|drv_famV))
383#define famLV_drive (current_drive->drv_type&(drv_famL|drv_famV))
384#define fam0LV_drive (current_drive->drv_type&(drv_fam0|drv_famL|drv_famV))
385#define fam1L_drive (current_drive->drv_type&(drv_fam1|drv_famL))
386#define fam1V_drive (current_drive->drv_type&(drv_fam1|drv_famV))
387#define fam1LV_drive (current_drive->drv_type&(drv_fam1|drv_famL|drv_famV))
388#define fam01_drive (current_drive->drv_type&(drv_fam0|drv_fam1))
389#define fam12_drive (current_drive->drv_type&(drv_fam1|drv_fam2))
390#define fam2T_drive (current_drive->drv_type&(drv_fam2|drv_famT))
391
392/*
393 * audio states:
394 */
395#define audio_completed 3 /* Forgot this one! --AJK */
396#define audio_playing 2
397#define audio_pausing 1
398
399/*
400 * drv_pattern, drv_options:
401 */
402#define speed_auto 0x80
403#define speed_300 0x40
404#define speed_150 0x20
405#define audio_mono 0x04
406
407/*
408 * values of cmd_type (0 else):
409 */
410#define READ_M1 0x01 /* "data mode 1": 2048 bytes per frame */
411#define READ_M2 0x02 /* "data mode 2": 12+2048+280 bytes per frame */
412#define READ_SC 0x04 /* "subchannel info": 96 bytes per frame */
413#define READ_AU 0x08 /* "audio frame": 2352 bytes per frame */
414
415/*
416 * sense_byte:
417 *
418 * values: 00
419 * 01
420 * 81
421 * 82 "raw audio" mode
422 * xx from infobuf[0] after 85 00 00 00 00 00 00
423 */
424
425/* audio status (bin) */
426#define aud_00 0x00 /* Audio status byte not supported or not valid */
427#define audx11 0x0b /* Audio play operation in progress */
428#define audx12 0x0c /* Audio play operation paused */
429#define audx13 0x0d /* Audio play operation successfully completed */
430#define audx14 0x0e /* Audio play operation stopped due to error */
431#define audx15 0x0f /* No current audio status to return */
432/* audio status (bcd) */
433#define aud_11 0x11 /* Audio play operation in progress */
434#define aud_12 0x12 /* Audio play operation paused */
435#define aud_13 0x13 /* Audio play operation successfully completed */
436#define aud_14 0x14 /* Audio play operation stopped due to error */
437#define aud_15 0x15 /* No current audio status to return */
438
439/*
440 * highest allowed drive number (MINOR+1)
441 */
442#define NR_SBPCD 4
443
444/*
445 * we try to never disable interrupts - seems to work
446 */
447#define SBPCD_DIS_IRQ 0
448
449/*
450 * "write byte to port"
451 */
452#define OUT(x,y) outb(y,x)
453
454/*==========================================================================*/
455
456#define MIXER_addr SOUND_BASE+4 /* sound card's address register */
457#define MIXER_data SOUND_BASE+5 /* sound card's data register */
458#define MIXER_CD_Volume 0x28 /* internal SB Pro register address */
459
460/*==========================================================================*/
461
462#define MAX_TRACKS 99
463
464#define ERR_DISKCHANGE 615
465
466/*==========================================================================*/
467/*
468 * To make conversions easier (machine dependent!)
469 */
470typedef union _msf
471{
472 u_int n;
473 u_char c[4];
474} MSF;
475
476typedef union _blk
477{
478 u_int n;
479 u_char c[4];
480} BLK;
481
482/*==========================================================================*/
483
484/*============================================================================
485==============================================================================
486
487COMMAND SET of "old" drives like CR-521, CR-522
488 (the CR-562 family is different):
489
490No. Command Code
491--------------------------------------------
492
493Drive Commands:
494 1 Seek 01
495 2 Read Data 02
496 3 Read XA-Data 03
497 4 Read Header 04
498 5 Spin Up 05
499 6 Spin Down 06
500 7 Diagnostic 07
501 8 Read UPC 08
502 9 Read ISRC 09
50310 Play Audio 0A
50411 Play Audio MSF 0B
50512 Play Audio Track/Index 0C
506
507Status Commands:
50813 Read Status 81
50914 Read Error 82
51015 Read Drive Version 83
51116 Mode Select 84
51217 Mode Sense 85
51318 Set XA Parameter 86
51419 Read XA Parameter 87
51520 Read Capacity 88
51621 Read SUB_Q 89
51722 Read Disc Code 8A
51823 Read Disc Information 8B
51924 Read TOC 8C
52025 Pause/Resume 8D
52126 Read Packet 8E
52227 Read Path Check 00
523
524
525all numbers (lba, msf-bin, msf-bcd, counts) to transfer high byte first
526
527mnemo 7-byte command #bytes response (r0...rn)
528________ ____________________ ____
529
530Read Status:
531status: 81. (1) one-byte command, gives the main
532 status byte
533Read Error:
534check1: 82 00 00 00 00 00 00. (6) r1: audio status
535
536Read Packet:
537check2: 8e xx 00 00 00 00 00. (xx) gets xx bytes response, relating
538 to commands 01 04 05 07 08 09
539
540Play Audio:
541play: 0a ll-bb-aa nn-nn-nn. (0) play audio, ll-bb-aa: starting block (lba),
542 nn-nn-nn: #blocks
543Play Audio MSF:
544 0b mm-ss-ff mm-ss-ff (0) play audio from/to
545
546Play Audio Track/Index:
547 0c ...
548
549Pause/Resume:
550pause: 8d pr 00 00 00 00 00. (0) pause (pr=00)
551 resume (pr=80) audio playing
552
553Mode Select:
554 84 00 nn-nn ??.?? 00 (0) nn-nn: 2048 or 2340
555 possibly defines transfer size
556
557set_vol: 84 83 00 00 sw le 00. (0) sw(itch): lrxxxxxx (off=1)
558 le(vel): min=0, max=FF, else half
559 (firmware 2.11)
560
561Mode Sense:
562get_vol: 85 03 00 00 00 00 00. (2) tell current audio volume setting
563
564Read Disc Information:
565tocdesc: 8b 00 00 00 00 00 00. (6) read the toc descriptor ("msf-bin"-format)
566
567Read TOC:
568tocent: 8c fl nn 00 00 00 00. (8) read toc entry #nn
569 (fl=0:"lba"-, =2:"msf-bin"-format)
570
571Read Capacity:
572capacit: 88 00 00 00 00 00 00. (5) "read CD-ROM capacity"
573
574
575Read Path Check:
576ping: 00 00 00 00 00 00 00. (2) r0=AA, r1=55
577 ("ping" if the drive is connected)
578
579Read Drive Version:
580ident: 83 00 00 00 00 00 00. (12) gives "MATSHITAn.nn"
581 (n.nn = 2.01, 2.11., 3.00, ...)
582
583Seek:
584seek: 01 00 ll-bb-aa 00 00. (0)
585seek: 01 02 mm-ss-ff 00 00. (0)
586
587Read Data:
588read: 02 xx-xx-xx nn-nn fl. (?) read nn-nn blocks of 2048 bytes,
589 starting at block xx-xx-xx
590 fl=0: "lba"-, =2:"msf-bcd"-coded xx-xx-xx
591
592Read XA-Data:
593read: 03 xx-xx-xx nn-nn fl. (?) read nn-nn blocks of 2340 bytes,
594 starting at block xx-xx-xx
595 fl=0: "lba"-, =2:"msf-bcd"-coded xx-xx-xx
596
597Read SUB_Q:
598 89 fl 00 00 00 00 00. (13) r0: audio status, r4-r7: lba/msf,
599 fl=0: "lba", fl=2: "msf"
600
601Read Disc Code:
602 8a 00 00 00 00 00 00. (14) possibly extended "check condition"-info
603
604Read Header:
605 04 00 ll-bb-aa 00 00. (0) 4 bytes response with "check2"
606 04 02 mm-ss-ff 00 00. (0) 4 bytes response with "check2"
607
608Spin Up:
609 05 00 ll-bb-aa 00 00. (0) possibly implies a "seek"
610
611Spin Down:
612 06 ...
613
614Diagnostic:
615 07 00 ll-bb-aa 00 00. (2) 2 bytes response with "check2"
616 07 02 mm-ss-ff 00 00. (2) 2 bytes response with "check2"
617
618Read UPC:
619 08 00 ll-bb-aa 00 00. (16)
620 08 02 mm-ss-ff 00 00. (16)
621
622Read ISRC:
623 09 00 ll-bb-aa 00 00. (15) 15 bytes response with "check2"
624 09 02 mm-ss-ff 00 00. (15) 15 bytes response with "check2"
625
626Set XA Parameter:
627 86 ...
628
629Read XA Parameter:
630 87 ...
631
632==============================================================================
633============================================================================*/
634
635/*
636 * commands
637 *
638 * CR-52x: CMD0_
639 * CR-56x: CMD1_
640 * CD200: CMD2_
641 * LCS-7260: CMDL_
642 * TEAC CD-55A: CMDT_
643 * ECS-AT: CMDV_
644 */
645#define CMD1_RESET 0x0a
646#define CMD2_RESET 0x01
647#define CMDT_RESET 0xc0
648
649#define CMD1_LOCK_CTL 0x0c
650#define CMD2_LOCK_CTL 0x1e
651#define CMDT_LOCK_CTL CMD2_LOCK_CTL
652#define CMDL_LOCK_CTL 0x0e
653#define CMDV_LOCK_CTL CMDL_LOCK_CTL
654
655#define CMD1_TRAY_CTL 0x07
656#define CMD2_TRAY_CTL 0x1b
657#define CMDT_TRAY_CTL CMD2_TRAY_CTL
658#define CMDL_TRAY_CTL 0x0d
659#define CMDV_TRAY_CTL CMDL_TRAY_CTL
660
661#define CMD1_MULTISESS 0x8d
662#define CMDL_MULTISESS 0x8c
663#define CMDV_MULTISESS CMDL_MULTISESS
664
665#define CMD1_SUBCHANINF 0x11
666#define CMD2_SUBCHANINF 0x??
667
668#define CMD1_ABORT 0x08
669#define CMD2_ABORT 0x08
670#define CMDT_ABORT 0x08
671
672#define CMD2_x02 0x02
673
674#define CMD2_SETSPEED 0xda
675
676#define CMD0_PATH_CHECK 0x00
677#define CMD1_PATH_CHECK 0x???
678#define CMD2_PATH_CHECK 0x???
679#define CMDT_PATH_CHECK 0x???
680#define CMDL_PATH_CHECK CMD0_PATH_CHECK
681#define CMDV_PATH_CHECK CMD0_PATH_CHECK
682
683#define CMD0_SEEK 0x01
684#define CMD1_SEEK CMD0_SEEK
685#define CMD2_SEEK 0x2b
686#define CMDT_SEEK CMD2_SEEK
687#define CMDL_SEEK CMD0_SEEK
688#define CMDV_SEEK CMD0_SEEK
689
690#define CMD0_READ 0x02
691#define CMD1_READ 0x10
692#define CMD2_READ 0x28
693#define CMDT_READ CMD2_READ
694#define CMDL_READ CMD0_READ
695#define CMDV_READ CMD0_READ
696
697#define CMD0_READ_XA 0x03
698#define CMD2_READ_XA 0xd4
699#define CMD2_READ_XA2 0xd5
700#define CMDL_READ_XA CMD0_READ_XA /* really ?? */
701#define CMDV_READ_XA CMD0_READ_XA
702
703#define CMD0_READ_HEAD 0x04
704
705#define CMD0_SPINUP 0x05
706#define CMD1_SPINUP 0x02
707#define CMD2_SPINUP CMD2_TRAY_CTL
708#define CMDL_SPINUP CMD0_SPINUP
709#define CMDV_SPINUP CMD0_SPINUP
710
711#define CMD0_SPINDOWN 0x06 /* really??? */
712#define CMD1_SPINDOWN 0x06
713#define CMD2_SPINDOWN CMD2_TRAY_CTL
714#define CMDL_SPINDOWN 0x0d
715#define CMDV_SPINDOWN CMD0_SPINDOWN
716
717#define CMD0_DIAG 0x07
718
719#define CMD0_READ_UPC 0x08
720#define CMD1_READ_UPC 0x88
721#define CMD2_READ_UPC 0x???
722#define CMDL_READ_UPC CMD0_READ_UPC
723#define CMDV_READ_UPC 0x8f
724
725#define CMD0_READ_ISRC 0x09
726
727#define CMD0_PLAY 0x0a
728#define CMD1_PLAY 0x???
729#define CMD2_PLAY 0x???
730#define CMDL_PLAY CMD0_PLAY
731#define CMDV_PLAY CMD0_PLAY
732
733#define CMD0_PLAY_MSF 0x0b
734#define CMD1_PLAY_MSF 0x0e
735#define CMD2_PLAY_MSF 0x47
736#define CMDT_PLAY_MSF CMD2_PLAY_MSF
737#define CMDL_PLAY_MSF 0x???
738
739#define CMD0_PLAY_TI 0x0c
740#define CMD1_PLAY_TI 0x0f
741
742#define CMD0_STATUS 0x81
743#define CMD1_STATUS 0x05
744#define CMD2_STATUS 0x00
745#define CMDT_STATUS CMD2_STATUS
746#define CMDL_STATUS CMD0_STATUS
747#define CMDV_STATUS CMD0_STATUS
748#define CMD2_SEEK_LEADIN 0x00
749
750#define CMD0_READ_ERR 0x82
751#define CMD1_READ_ERR CMD0_READ_ERR
752#define CMD2_READ_ERR 0x03
753#define CMDT_READ_ERR CMD2_READ_ERR /* get audio status */
754#define CMDL_READ_ERR CMD0_READ_ERR
755#define CMDV_READ_ERR CMD0_READ_ERR
756
757#define CMD0_READ_VER 0x83
758#define CMD1_READ_VER CMD0_READ_VER
759#define CMD2_READ_VER 0x12
760#define CMDT_READ_VER CMD2_READ_VER /* really ?? */
761#define CMDL_READ_VER CMD0_READ_VER
762#define CMDV_READ_VER CMD0_READ_VER
763
764#define CMD0_SETMODE 0x84
765#define CMD1_SETMODE 0x09
766#define CMD2_SETMODE 0x55
767#define CMDT_SETMODE CMD2_SETMODE
768#define CMDL_SETMODE CMD0_SETMODE
769
770#define CMD0_GETMODE 0x85
771#define CMD1_GETMODE 0x84
772#define CMD2_GETMODE 0x5a
773#define CMDT_GETMODE CMD2_GETMODE
774#define CMDL_GETMODE CMD0_GETMODE
775
776#define CMD0_SET_XA 0x86
777
778#define CMD0_GET_XA 0x87
779
780#define CMD0_CAPACITY 0x88
781#define CMD1_CAPACITY 0x85
782#define CMD2_CAPACITY 0x25
783#define CMDL_CAPACITY CMD0_CAPACITY /* missing in some firmware versions */
784
785#define CMD0_READSUBQ 0x89
786#define CMD1_READSUBQ 0x87
787#define CMD2_READSUBQ 0x42
788#define CMDT_READSUBQ CMD2_READSUBQ
789#define CMDL_READSUBQ CMD0_READSUBQ
790#define CMDV_READSUBQ CMD0_READSUBQ
791
792#define CMD0_DISKCODE 0x8a
793
794#define CMD0_DISKINFO 0x8b
795#define CMD1_DISKINFO CMD0_DISKINFO
796#define CMD2_DISKINFO 0x43
797#define CMDT_DISKINFO CMD2_DISKINFO
798#define CMDL_DISKINFO CMD0_DISKINFO
799#define CMDV_DISKINFO CMD0_DISKINFO
800
801#define CMD0_READTOC 0x8c
802#define CMD1_READTOC CMD0_READTOC
803#define CMD2_READTOC 0x???
804#define CMDL_READTOC CMD0_READTOC
805#define CMDV_READTOC CMD0_READTOC
806
807#define CMD0_PAU_RES 0x8d
808#define CMD1_PAU_RES 0x0d
809#define CMD2_PAU_RES 0x4b
810#define CMDT_PAUSE CMD2_PAU_RES
811#define CMDL_PAU_RES CMD0_PAU_RES
812#define CMDV_PAUSE CMD0_PAU_RES
813
814#define CMD0_PACKET 0x8e
815#define CMD1_PACKET CMD0_PACKET
816#define CMD2_PACKET 0x???
817#define CMDL_PACKET CMD0_PACKET
818#define CMDV_PACKET 0x???
819
820/*==========================================================================*/
821/*==========================================================================*/
822#endif /* _LINUX_SBPCD_H */
823/*==========================================================================*/
824/*
825 * Overrides for Emacs so that we follow Linus's tabbing style.
826 * Emacs will notice this stuff at the end of the file and automatically
827 * adjust the settings for this buffer only. This must remain at the end
828 * of the file.
829 * ---------------------------------------------------------------------------
830 * Local variables:
831 * c-indent-level: 8
832 * c-brace-imaginary-offset: 0
833 * c-brace-offset: -8
834 * c-argdecl-indent: 8
835 * c-label-offset: -8
836 * c-continued-statement-offset: 8
837 * c-continued-brace-offset: 0
838 * End:
839 */
diff --git a/drivers/cdrom/sjcd.c b/drivers/cdrom/sjcd.c
deleted file mode 100644
index 5409fca5bbfc..000000000000
--- a/drivers/cdrom/sjcd.c
+++ /dev/null
@@ -1,1815 +0,0 @@
1/* -- sjcd.c
2 *
3 * Sanyo CD-ROM device driver implementation, Version 1.6
4 * Copyright (C) 1995 Vadim V. Model
5 *
6 * model@cecmow.enet.dec.com
7 * vadim@rbrf.ru
8 * vadim@ipsun.ras.ru
9 *
10 *
11 * This driver is based on pre-works by Eberhard Moenkeberg (emoenke@gwdg.de);
12 * it was developed under use of mcd.c from Martin Harriss, with help of
13 * Eric van der Maarel (H.T.M.v.d.Maarel@marin.nl).
14 *
15 * It is planned to include these routines into sbpcd.c later - to make
16 * a "mixed use" on one cable possible for all kinds of drives which use
17 * the SoundBlaster/Panasonic style CDROM interface. But today, the
18 * ability to install directly from CDROM is more important than flexibility.
19 *
20 * This program is free software; you can redistribute it and/or modify
21 * it under the terms of the GNU General Public License as published by
22 * the Free Software Foundation; either version 2 of the License, or
23 * (at your option) any later version.
24 *
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
29 *
30 * You should have received a copy of the GNU General Public License
31 * along with this program; if not, write to the Free Software
32 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
33 *
34 * History:
35 * 1.1 First public release with kernel version 1.3.7.
36 * Written by Vadim Model.
37 * 1.2 Added detection and configuration of cdrom interface
38 * on ISP16 soundcard.
39 * Allow for command line options: sjcd=<io_base>,<irq>,<dma>
40 * 1.3 Some minor changes to README.sjcd.
41 * 1.4 MSS Sound support!! Listen to a CD through the speakers.
42 * 1.5 Module support and bugfixes.
43 * Tray locking.
44 * 1.6 Removed ISP16 code from this driver.
45 * Allow only to set io base address on command line: sjcd=<io_base>
46 * Changes to Documentation/cdrom/sjcd
47 * Added cleanup after any error in the initialisation.
48 * 1.7 Added code to set the sector size tables to prevent the bug present in
49 * the previous version of this driver. Coded added by Anthony Barbachan
50 * from bugfix tip originally suggested by Alan Cox.
51 *
52 * November 1999 -- Make kernel-parameter implementation work with 2.3.x
53 * Removed init_module & cleanup_module in favor of
54 * module_init & module_exit.
55 * Torben Mathiasen <tmm@image.dk>
56 */
57
58#define SJCD_VERSION_MAJOR 1
59#define SJCD_VERSION_MINOR 7
60
61#include <linux/module.h>
62#include <linux/errno.h>
63#include <linux/mm.h>
64#include <linux/timer.h>
65#include <linux/fs.h>
66#include <linux/kernel.h>
67#include <linux/cdrom.h>
68#include <linux/ioport.h>
69#include <linux/string.h>
70#include <linux/major.h>
71#include <linux/init.h>
72
73#include <asm/system.h>
74#include <asm/io.h>
75#include <asm/uaccess.h>
76#include <linux/blkdev.h>
77#include "sjcd.h"
78
79static int sjcd_present = 0;
80static struct request_queue *sjcd_queue;
81
82#define MAJOR_NR SANYO_CDROM_MAJOR
83#define QUEUE (sjcd_queue)
84#define CURRENT elv_next_request(sjcd_queue)
85
86#define SJCD_BUF_SIZ 32 /* cdr-h94a has internal 64K buffer */
87
88/*
89 * buffer for block size conversion
90 */
91static char sjcd_buf[2048 * SJCD_BUF_SIZ];
92static volatile int sjcd_buf_bn[SJCD_BUF_SIZ], sjcd_next_bn;
93static volatile int sjcd_buf_in, sjcd_buf_out = -1;
94
95/*
96 * Status.
97 */
98static unsigned short sjcd_status_valid = 0;
99static unsigned short sjcd_door_closed;
100static unsigned short sjcd_door_was_open;
101static unsigned short sjcd_media_is_available;
102static unsigned short sjcd_media_is_changed;
103static unsigned short sjcd_toc_uptodate = 0;
104static unsigned short sjcd_command_failed;
105static volatile unsigned char sjcd_completion_status = 0;
106static volatile unsigned char sjcd_completion_error = 0;
107static unsigned short sjcd_command_is_in_progress = 0;
108static unsigned short sjcd_error_reported = 0;
109static DEFINE_SPINLOCK(sjcd_lock);
110
111static int sjcd_open_count;
112
113static int sjcd_audio_status;
114static struct sjcd_play_msf sjcd_playing;
115
116static int sjcd_base = SJCD_BASE_ADDR;
117
118module_param(sjcd_base, int, 0);
119
120static DECLARE_WAIT_QUEUE_HEAD(sjcd_waitq);
121
122/*
123 * Data transfer.
124 */
125static volatile unsigned short sjcd_transfer_is_active = 0;
126
127enum sjcd_transfer_state {
128 SJCD_S_IDLE = 0,
129 SJCD_S_START = 1,
130 SJCD_S_MODE = 2,
131 SJCD_S_READ = 3,
132 SJCD_S_DATA = 4,
133 SJCD_S_STOP = 5,
134 SJCD_S_STOPPING = 6
135};
136static enum sjcd_transfer_state sjcd_transfer_state = SJCD_S_IDLE;
137static long sjcd_transfer_timeout = 0;
138static int sjcd_read_count = 0;
139static unsigned char sjcd_mode = 0;
140
141#define SJCD_READ_TIMEOUT 5000
142
143#if defined( SJCD_GATHER_STAT )
144/*
145 * Statistic.
146 */
147static struct sjcd_stat statistic;
148#endif
149
150/*
151 * Timer.
152 */
153static DEFINE_TIMER(sjcd_delay_timer, NULL, 0, 0);
154
155#define SJCD_SET_TIMER( func, tmout ) \
156 ( sjcd_delay_timer.expires = jiffies+tmout, \
157 sjcd_delay_timer.function = ( void * )func, \
158 add_timer( &sjcd_delay_timer ) )
159
160#define CLEAR_TIMER del_timer( &sjcd_delay_timer )
161
162/*
163 * Set up device, i.e., use command line data to set
164 * base address.
165 */
166#ifndef MODULE
167static int __init sjcd_setup(char *str)
168{
169 int ints[2];
170 (void) get_options(str, ARRAY_SIZE(ints), ints);
171 if (ints[0] > 0)
172 sjcd_base = ints[1];
173
174 return 1;
175}
176
177__setup("sjcd=", sjcd_setup);
178
179#endif
180
181/*
182 * Special converters.
183 */
184static unsigned char bin2bcd(int bin)
185{
186 int u, v;
187
188 u = bin % 10;
189 v = bin / 10;
190 return (u | (v << 4));
191}
192
193static int bcd2bin(unsigned char bcd)
194{
195 return ((bcd >> 4) * 10 + (bcd & 0x0F));
196}
197
198static long msf2hsg(struct msf *mp)
199{
200 return (bcd2bin(mp->frame) + bcd2bin(mp->sec) * 75
201 + bcd2bin(mp->min) * 4500 - 150);
202}
203
204static void hsg2msf(long hsg, struct msf *msf)
205{
206 hsg += 150;
207 msf->min = hsg / 4500;
208 hsg %= 4500;
209 msf->sec = hsg / 75;
210 msf->frame = hsg % 75;
211 msf->min = bin2bcd(msf->min); /* convert to BCD */
212 msf->sec = bin2bcd(msf->sec);
213 msf->frame = bin2bcd(msf->frame);
214}
215
216/*
217 * Send a command to cdrom. Invalidate status.
218 */
219static void sjcd_send_cmd(unsigned char cmd)
220{
221#if defined( SJCD_TRACE )
222 printk("SJCD: send_cmd( 0x%x )\n", cmd);
223#endif
224 outb(cmd, SJCDPORT(0));
225 sjcd_command_is_in_progress = 1;
226 sjcd_status_valid = 0;
227 sjcd_command_failed = 0;
228}
229
230/*
231 * Send a command with one arg to cdrom. Invalidate status.
232 */
233static void sjcd_send_1_cmd(unsigned char cmd, unsigned char a)
234{
235#if defined( SJCD_TRACE )
236 printk("SJCD: send_1_cmd( 0x%x, 0x%x )\n", cmd, a);
237#endif
238 outb(cmd, SJCDPORT(0));
239 outb(a, SJCDPORT(0));
240 sjcd_command_is_in_progress = 1;
241 sjcd_status_valid = 0;
242 sjcd_command_failed = 0;
243}
244
245/*
246 * Send a command with four args to cdrom. Invalidate status.
247 */
248static void sjcd_send_4_cmd(unsigned char cmd, unsigned char a,
249 unsigned char b, unsigned char c,
250 unsigned char d)
251{
252#if defined( SJCD_TRACE )
253 printk("SJCD: send_4_cmd( 0x%x )\n", cmd);
254#endif
255 outb(cmd, SJCDPORT(0));
256 outb(a, SJCDPORT(0));
257 outb(b, SJCDPORT(0));
258 outb(c, SJCDPORT(0));
259 outb(d, SJCDPORT(0));
260 sjcd_command_is_in_progress = 1;
261 sjcd_status_valid = 0;
262 sjcd_command_failed = 0;
263}
264
265/*
266 * Send a play or read command to cdrom. Invalidate Status.
267 */
268static void sjcd_send_6_cmd(unsigned char cmd, struct sjcd_play_msf *pms)
269{
270#if defined( SJCD_TRACE )
271 printk("SJCD: send_long_cmd( 0x%x )\n", cmd);
272#endif
273 outb(cmd, SJCDPORT(0));
274 outb(pms->start.min, SJCDPORT(0));
275 outb(pms->start.sec, SJCDPORT(0));
276 outb(pms->start.frame, SJCDPORT(0));
277 outb(pms->end.min, SJCDPORT(0));
278 outb(pms->end.sec, SJCDPORT(0));
279 outb(pms->end.frame, SJCDPORT(0));
280 sjcd_command_is_in_progress = 1;
281 sjcd_status_valid = 0;
282 sjcd_command_failed = 0;
283}
284
285/*
286 * Get a value from the data port. Should not block, so we use a little
287 * wait for a while. Returns 0 if OK.
288 */
289static int sjcd_load_response(void *buf, int len)
290{
291 unsigned char *resp = (unsigned char *) buf;
292
293 for (; len; --len) {
294 int i;
295 for (i = 200;
296 i-- && !SJCD_STATUS_AVAILABLE(inb(SJCDPORT(1))););
297 if (i > 0)
298 *resp++ = (unsigned char) inb(SJCDPORT(0));
299 else
300 break;
301 }
302 return (len);
303}
304
305/*
306 * Load and parse command completion status (drive info byte and maybe error).
307 * Sorry, no error classification yet.
308 */
309static void sjcd_load_status(void)
310{
311 sjcd_media_is_changed = 0;
312 sjcd_completion_error = 0;
313 sjcd_completion_status = inb(SJCDPORT(0));
314 if (sjcd_completion_status & SST_DOOR_OPENED) {
315 sjcd_door_closed = sjcd_media_is_available = 0;
316 } else {
317 sjcd_door_closed = 1;
318 if (sjcd_completion_status & SST_MEDIA_CHANGED)
319 sjcd_media_is_available = sjcd_media_is_changed =
320 1;
321 else if (sjcd_completion_status & 0x0F) {
322 /*
323 * OK, we seem to catch an error ...
324 */
325 while (!SJCD_STATUS_AVAILABLE(inb(SJCDPORT(1))));
326 sjcd_completion_error = inb(SJCDPORT(0));
327 if ((sjcd_completion_status & 0x08) &&
328 (sjcd_completion_error & 0x40))
329 sjcd_media_is_available = 0;
330 else
331 sjcd_command_failed = 1;
332 } else
333 sjcd_media_is_available = 1;
334 }
335 /*
336 * Ok, status loaded successfully.
337 */
338 sjcd_status_valid = 1, sjcd_error_reported = 0;
339 sjcd_command_is_in_progress = 0;
340
341 /*
342 * If the disk is changed, the TOC is not valid.
343 */
344 if (sjcd_media_is_changed)
345 sjcd_toc_uptodate = 0;
346#if defined( SJCD_TRACE )
347 printk("SJCD: status %02x.%02x loaded.\n",
348 (int) sjcd_completion_status, (int) sjcd_completion_error);
349#endif
350}
351
352/*
353 * Read status from cdrom. Check to see if the status is available.
354 */
355static int sjcd_check_status(void)
356{
357 /*
358 * Try to load the response from cdrom into buffer.
359 */
360 if (SJCD_STATUS_AVAILABLE(inb(SJCDPORT(1)))) {
361 sjcd_load_status();
362 return (1);
363 } else {
364 /*
365 * No status is available.
366 */
367 return (0);
368 }
369}
370
371/*
372 * This is just timeout counter, and nothing more. Surprised ? :-)
373 */
374static volatile long sjcd_status_timeout;
375
376/*
377 * We need about 10 seconds to wait. The longest command takes about 5 seconds
378 * to probe the disk (usually after tray closed or drive reset). Other values
379 * should be thought of for other commands.
380 */
381#define SJCD_WAIT_FOR_STATUS_TIMEOUT 1000
382
383static void sjcd_status_timer(void)
384{
385 if (sjcd_check_status()) {
386 /*
387 * The command completed and status is loaded, stop waiting.
388 */
389 wake_up(&sjcd_waitq);
390 } else if (--sjcd_status_timeout <= 0) {
391 /*
392 * We are timed out.
393 */
394 wake_up(&sjcd_waitq);
395 } else {
396 /*
397 * We have still some time to wait. Try again.
398 */
399 SJCD_SET_TIMER(sjcd_status_timer, 1);
400 }
401}
402
403/*
404 * Wait for status for 10 sec approx. Returns non-positive when timed out.
405 * Should not be used while reading data CDs.
406 */
407static int sjcd_wait_for_status(void)
408{
409 sjcd_status_timeout = SJCD_WAIT_FOR_STATUS_TIMEOUT;
410 SJCD_SET_TIMER(sjcd_status_timer, 1);
411 sleep_on(&sjcd_waitq);
412#if defined( SJCD_DIAGNOSTIC ) || defined ( SJCD_TRACE )
413 if (sjcd_status_timeout <= 0)
414 printk("SJCD: Error Wait For Status.\n");
415#endif
416 return (sjcd_status_timeout);
417}
418
419static int sjcd_receive_status(void)
420{
421 int i;
422#if defined( SJCD_TRACE )
423 printk("SJCD: receive_status\n");
424#endif
425 /*
426 * Wait a bit for status available.
427 */
428 for (i = 200; i-- && (sjcd_check_status() == 0););
429 if (i < 0) {
430#if defined( SJCD_TRACE )
431 printk("SJCD: long wait for status\n");
432#endif
433 if (sjcd_wait_for_status() <= 0)
434 printk("SJCD: Timeout when read status.\n");
435 else
436 i = 0;
437 }
438 return (i);
439}
440
441/*
442 * Load the status. Issue get status command and wait for status available.
443 */
444static void sjcd_get_status(void)
445{
446#if defined( SJCD_TRACE )
447 printk("SJCD: get_status\n");
448#endif
449 sjcd_send_cmd(SCMD_GET_STATUS);
450 sjcd_receive_status();
451}
452
453/*
454 * Check the drive if the disk is changed. Should be revised.
455 */
456static int sjcd_disk_change(struct gendisk *disk)
457{
458#if 0
459 printk("SJCD: sjcd_disk_change(%s)\n", disk->disk_name);
460#endif
461 if (!sjcd_command_is_in_progress)
462 sjcd_get_status();
463 return (sjcd_status_valid ? sjcd_media_is_changed : 0);
464}
465
466/*
467 * Read the table of contents (TOC) and TOC header if necessary.
468 * We assume that the drive contains no more than 99 toc entries.
469 */
470static struct sjcd_hw_disk_info sjcd_table_of_contents[SJCD_MAX_TRACKS];
471static unsigned char sjcd_first_track_no, sjcd_last_track_no;
472#define sjcd_disk_length sjcd_table_of_contents[0].un.track_msf
473
474static int sjcd_update_toc(void)
475{
476 struct sjcd_hw_disk_info info;
477 int i;
478#if defined( SJCD_TRACE )
479 printk("SJCD: update toc:\n");
480#endif
481 /*
482 * check to see if we need to do anything
483 */
484 if (sjcd_toc_uptodate)
485 return (0);
486
487 /*
488 * Get the TOC start information.
489 */
490 sjcd_send_1_cmd(SCMD_GET_DISK_INFO, SCMD_GET_1_TRACK);
491 sjcd_receive_status();
492
493 if (!sjcd_status_valid) {
494 printk("SJCD: cannot load status.\n");
495 return (-1);
496 }
497
498 if (!sjcd_media_is_available) {
499 printk("SJCD: no disk in drive\n");
500 return (-1);
501 }
502
503 if (!sjcd_command_failed) {
504 if (sjcd_load_response(&info, sizeof(info)) != 0) {
505 printk
506 ("SJCD: cannot load response about TOC start.\n");
507 return (-1);
508 }
509 sjcd_first_track_no = bcd2bin(info.un.track_no);
510 } else {
511 printk("SJCD: get first failed\n");
512 return (-1);
513 }
514#if defined( SJCD_TRACE )
515 printk("SJCD: TOC start 0x%02x ", sjcd_first_track_no);
516#endif
517 /*
518 * Get the TOC finish information.
519 */
520 sjcd_send_1_cmd(SCMD_GET_DISK_INFO, SCMD_GET_L_TRACK);
521 sjcd_receive_status();
522
523 if (!sjcd_status_valid) {
524 printk("SJCD: cannot load status.\n");
525 return (-1);
526 }
527
528 if (!sjcd_media_is_available) {
529 printk("SJCD: no disk in drive\n");
530 return (-1);
531 }
532
533 if (!sjcd_command_failed) {
534 if (sjcd_load_response(&info, sizeof(info)) != 0) {
535 printk
536 ("SJCD: cannot load response about TOC finish.\n");
537 return (-1);
538 }
539 sjcd_last_track_no = bcd2bin(info.un.track_no);
540 } else {
541 printk("SJCD: get last failed\n");
542 return (-1);
543 }
544#if defined( SJCD_TRACE )
545 printk("SJCD: TOC finish 0x%02x ", sjcd_last_track_no);
546#endif
547 for (i = sjcd_first_track_no; i <= sjcd_last_track_no; i++) {
548 /*
549 * Get the first track information.
550 */
551 sjcd_send_1_cmd(SCMD_GET_DISK_INFO, bin2bcd(i));
552 sjcd_receive_status();
553
554 if (!sjcd_status_valid) {
555 printk("SJCD: cannot load status.\n");
556 return (-1);
557 }
558
559 if (!sjcd_media_is_available) {
560 printk("SJCD: no disk in drive\n");
561 return (-1);
562 }
563
564 if (!sjcd_command_failed) {
565 if (sjcd_load_response(&sjcd_table_of_contents[i],
566 sizeof(struct
567 sjcd_hw_disk_info))
568 != 0) {
569 printk
570 ("SJCD: cannot load info for %d track\n",
571 i);
572 return (-1);
573 }
574 } else {
575 printk("SJCD: get info %d failed\n", i);
576 return (-1);
577 }
578 }
579
580 /*
581 * Get the disk length info.
582 */
583 sjcd_send_1_cmd(SCMD_GET_DISK_INFO, SCMD_GET_D_SIZE);
584 sjcd_receive_status();
585
586 if (!sjcd_status_valid) {
587 printk("SJCD: cannot load status.\n");
588 return (-1);
589 }
590
591 if (!sjcd_media_is_available) {
592 printk("SJCD: no disk in drive\n");
593 return (-1);
594 }
595
596 if (!sjcd_command_failed) {
597 if (sjcd_load_response(&info, sizeof(info)) != 0) {
598 printk
599 ("SJCD: cannot load response about disk size.\n");
600 return (-1);
601 }
602 sjcd_disk_length.min = info.un.track_msf.min;
603 sjcd_disk_length.sec = info.un.track_msf.sec;
604 sjcd_disk_length.frame = info.un.track_msf.frame;
605 } else {
606 printk("SJCD: get size failed\n");
607 return (1);
608 }
609#if defined( SJCD_TRACE )
610 printk("SJCD: (%02x:%02x.%02x)\n", sjcd_disk_length.min,
611 sjcd_disk_length.sec, sjcd_disk_length.frame);
612#endif
613 return (0);
614}
615
616/*
617 * Load subchannel information.
618 */
619static int sjcd_get_q_info(struct sjcd_hw_qinfo *qp)
620{
621 int s;
622#if defined( SJCD_TRACE )
623 printk("SJCD: load sub q\n");
624#endif
625 sjcd_send_cmd(SCMD_GET_QINFO);
626 s = sjcd_receive_status();
627 if (s < 0 || sjcd_command_failed || !sjcd_status_valid) {
628 sjcd_send_cmd(0xF2);
629 s = sjcd_receive_status();
630 if (s < 0 || sjcd_command_failed || !sjcd_status_valid)
631 return (-1);
632 sjcd_send_cmd(SCMD_GET_QINFO);
633 s = sjcd_receive_status();
634 if (s < 0 || sjcd_command_failed || !sjcd_status_valid)
635 return (-1);
636 }
637 if (sjcd_media_is_available)
638 if (sjcd_load_response(qp, sizeof(*qp)) == 0)
639 return (0);
640 return (-1);
641}
642
643/*
644 * Start playing from the specified position.
645 */
646static int sjcd_play(struct sjcd_play_msf *mp)
647{
648 struct sjcd_play_msf msf;
649
650 /*
651 * Turn the device to play mode.
652 */
653 sjcd_send_1_cmd(SCMD_SET_MODE, SCMD_MODE_PLAY);
654 if (sjcd_receive_status() < 0)
655 return (-1);
656
657 /*
658 * Seek to the starting point.
659 */
660 msf.start = mp->start;
661 msf.end.min = msf.end.sec = msf.end.frame = 0x00;
662 sjcd_send_6_cmd(SCMD_SEEK, &msf);
663 if (sjcd_receive_status() < 0)
664 return (-1);
665
666 /*
667 * Start playing.
668 */
669 sjcd_send_6_cmd(SCMD_PLAY, mp);
670 return (sjcd_receive_status());
671}
672
673/*
674 * Tray control functions.
675 */
676static int sjcd_tray_close(void)
677{
678#if defined( SJCD_TRACE )
679 printk("SJCD: tray_close\n");
680#endif
681 sjcd_send_cmd(SCMD_CLOSE_TRAY);
682 return (sjcd_receive_status());
683}
684
685static int sjcd_tray_lock(void)
686{
687#if defined( SJCD_TRACE )
688 printk("SJCD: tray_lock\n");
689#endif
690 sjcd_send_cmd(SCMD_LOCK_TRAY);
691 return (sjcd_receive_status());
692}
693
694static int sjcd_tray_unlock(void)
695{
696#if defined( SJCD_TRACE )
697 printk("SJCD: tray_unlock\n");
698#endif
699 sjcd_send_cmd(SCMD_UNLOCK_TRAY);
700 return (sjcd_receive_status());
701}
702
703static int sjcd_tray_open(void)
704{
705#if defined( SJCD_TRACE )
706 printk("SJCD: tray_open\n");
707#endif
708 sjcd_send_cmd(SCMD_EJECT_TRAY);
709 return (sjcd_receive_status());
710}
711
712/*
713 * Do some user commands.
714 */
715static int sjcd_ioctl(struct inode *ip, struct file *fp,
716 unsigned int cmd, unsigned long arg)
717{
718 void __user *argp = (void __user *)arg;
719#if defined( SJCD_TRACE )
720 printk("SJCD:ioctl\n");
721#endif
722
723 sjcd_get_status();
724 if (!sjcd_status_valid)
725 return (-EIO);
726 if (sjcd_update_toc() < 0)
727 return (-EIO);
728
729 switch (cmd) {
730 case CDROMSTART:{
731#if defined( SJCD_TRACE )
732 printk("SJCD: ioctl: start\n");
733#endif
734 return (0);
735 }
736
737 case CDROMSTOP:{
738#if defined( SJCD_TRACE )
739 printk("SJCD: ioctl: stop\n");
740#endif
741 sjcd_send_cmd(SCMD_PAUSE);
742 (void) sjcd_receive_status();
743 sjcd_audio_status = CDROM_AUDIO_NO_STATUS;
744 return (0);
745 }
746
747 case CDROMPAUSE:{
748 struct sjcd_hw_qinfo q_info;
749#if defined( SJCD_TRACE )
750 printk("SJCD: ioctl: pause\n");
751#endif
752 if (sjcd_audio_status == CDROM_AUDIO_PLAY) {
753 sjcd_send_cmd(SCMD_PAUSE);
754 (void) sjcd_receive_status();
755 if (sjcd_get_q_info(&q_info) < 0) {
756 sjcd_audio_status =
757 CDROM_AUDIO_NO_STATUS;
758 } else {
759 sjcd_audio_status =
760 CDROM_AUDIO_PAUSED;
761 sjcd_playing.start = q_info.abs;
762 }
763 return (0);
764 } else
765 return (-EINVAL);
766 }
767
768 case CDROMRESUME:{
769#if defined( SJCD_TRACE )
770 printk("SJCD: ioctl: resume\n");
771#endif
772 if (sjcd_audio_status == CDROM_AUDIO_PAUSED) {
773 /*
774 * continue play starting at saved location
775 */
776 if (sjcd_play(&sjcd_playing) < 0) {
777 sjcd_audio_status =
778 CDROM_AUDIO_ERROR;
779 return (-EIO);
780 } else {
781 sjcd_audio_status =
782 CDROM_AUDIO_PLAY;
783 return (0);
784 }
785 } else
786 return (-EINVAL);
787 }
788
789 case CDROMPLAYTRKIND:{
790 struct cdrom_ti ti;
791 int s = -EFAULT;
792#if defined( SJCD_TRACE )
793 printk("SJCD: ioctl: playtrkind\n");
794#endif
795 if (!copy_from_user(&ti, argp, sizeof(ti))) {
796 s = 0;
797 if (ti.cdti_trk0 < sjcd_first_track_no)
798 return (-EINVAL);
799 if (ti.cdti_trk1 > sjcd_last_track_no)
800 ti.cdti_trk1 = sjcd_last_track_no;
801 if (ti.cdti_trk0 > ti.cdti_trk1)
802 return (-EINVAL);
803
804 sjcd_playing.start =
805 sjcd_table_of_contents[ti.cdti_trk0].
806 un.track_msf;
807 sjcd_playing.end =
808 (ti.cdti_trk1 <
809 sjcd_last_track_no) ?
810 sjcd_table_of_contents[ti.cdti_trk1 +
811 1].un.
812 track_msf : sjcd_table_of_contents[0].
813 un.track_msf;
814
815 if (sjcd_play(&sjcd_playing) < 0) {
816 sjcd_audio_status =
817 CDROM_AUDIO_ERROR;
818 return (-EIO);
819 } else
820 sjcd_audio_status =
821 CDROM_AUDIO_PLAY;
822 }
823 return (s);
824 }
825
826 case CDROMPLAYMSF:{
827 struct cdrom_msf sjcd_msf;
828 int s;
829#if defined( SJCD_TRACE )
830 printk("SJCD: ioctl: playmsf\n");
831#endif
832 if ((s =
833 access_ok(VERIFY_READ, argp, sizeof(sjcd_msf))
834 ? 0 : -EFAULT) == 0) {
835 if (sjcd_audio_status == CDROM_AUDIO_PLAY) {
836 sjcd_send_cmd(SCMD_PAUSE);
837 (void) sjcd_receive_status();
838 sjcd_audio_status =
839 CDROM_AUDIO_NO_STATUS;
840 }
841
842 if (copy_from_user(&sjcd_msf, argp,
843 sizeof(sjcd_msf)))
844 return (-EFAULT);
845
846 sjcd_playing.start.min =
847 bin2bcd(sjcd_msf.cdmsf_min0);
848 sjcd_playing.start.sec =
849 bin2bcd(sjcd_msf.cdmsf_sec0);
850 sjcd_playing.start.frame =
851 bin2bcd(sjcd_msf.cdmsf_frame0);
852 sjcd_playing.end.min =
853 bin2bcd(sjcd_msf.cdmsf_min1);
854 sjcd_playing.end.sec =
855 bin2bcd(sjcd_msf.cdmsf_sec1);
856 sjcd_playing.end.frame =
857 bin2bcd(sjcd_msf.cdmsf_frame1);
858
859 if (sjcd_play(&sjcd_playing) < 0) {
860 sjcd_audio_status =
861 CDROM_AUDIO_ERROR;
862 return (-EIO);
863 } else
864 sjcd_audio_status =
865 CDROM_AUDIO_PLAY;
866 }
867 return (s);
868 }
869
870 case CDROMREADTOCHDR:{
871 struct cdrom_tochdr toc_header;
872#if defined (SJCD_TRACE )
873 printk("SJCD: ioctl: readtocheader\n");
874#endif
875 toc_header.cdth_trk0 = sjcd_first_track_no;
876 toc_header.cdth_trk1 = sjcd_last_track_no;
877 if (copy_to_user(argp, &toc_header,
878 sizeof(toc_header)))
879 return -EFAULT;
880 return 0;
881 }
882
883 case CDROMREADTOCENTRY:{
884 struct cdrom_tocentry toc_entry;
885 int s;
886#if defined( SJCD_TRACE )
887 printk("SJCD: ioctl: readtocentry\n");
888#endif
889 if ((s =
890 access_ok(VERIFY_WRITE, argp, sizeof(toc_entry))
891 ? 0 : -EFAULT) == 0) {
892 struct sjcd_hw_disk_info *tp;
893
894 if (copy_from_user(&toc_entry, argp,
895 sizeof(toc_entry)))
896 return (-EFAULT);
897 if (toc_entry.cdte_track == CDROM_LEADOUT)
898 tp = &sjcd_table_of_contents[0];
899 else if (toc_entry.cdte_track <
900 sjcd_first_track_no)
901 return (-EINVAL);
902 else if (toc_entry.cdte_track >
903 sjcd_last_track_no)
904 return (-EINVAL);
905 else
906 tp = &sjcd_table_of_contents
907 [toc_entry.cdte_track];
908
909 toc_entry.cdte_adr =
910 tp->track_control & 0x0F;
911 toc_entry.cdte_ctrl =
912 tp->track_control >> 4;
913
914 switch (toc_entry.cdte_format) {
915 case CDROM_LBA:
916 toc_entry.cdte_addr.lba =
917 msf2hsg(&(tp->un.track_msf));
918 break;
919 case CDROM_MSF:
920 toc_entry.cdte_addr.msf.minute =
921 bcd2bin(tp->un.track_msf.min);
922 toc_entry.cdte_addr.msf.second =
923 bcd2bin(tp->un.track_msf.sec);
924 toc_entry.cdte_addr.msf.frame =
925 bcd2bin(tp->un.track_msf.
926 frame);
927 break;
928 default:
929 return (-EINVAL);
930 }
931 if (copy_to_user(argp, &toc_entry,
932 sizeof(toc_entry)))
933 s = -EFAULT;
934 }
935 return (s);
936 }
937
938 case CDROMSUBCHNL:{
939 struct cdrom_subchnl subchnl;
940 int s;
941#if defined( SJCD_TRACE )
942 printk("SJCD: ioctl: subchnl\n");
943#endif
944 if ((s =
945 access_ok(VERIFY_WRITE, argp, sizeof(subchnl))
946 ? 0 : -EFAULT) == 0) {
947 struct sjcd_hw_qinfo q_info;
948
949 if (copy_from_user(&subchnl, argp,
950 sizeof(subchnl)))
951 return (-EFAULT);
952
953 if (sjcd_get_q_info(&q_info) < 0)
954 return (-EIO);
955
956 subchnl.cdsc_audiostatus =
957 sjcd_audio_status;
958 subchnl.cdsc_adr =
959 q_info.track_control & 0x0F;
960 subchnl.cdsc_ctrl =
961 q_info.track_control >> 4;
962 subchnl.cdsc_trk =
963 bcd2bin(q_info.track_no);
964 subchnl.cdsc_ind = bcd2bin(q_info.x);
965
966 switch (subchnl.cdsc_format) {
967 case CDROM_LBA:
968 subchnl.cdsc_absaddr.lba =
969 msf2hsg(&(q_info.abs));
970 subchnl.cdsc_reladdr.lba =
971 msf2hsg(&(q_info.rel));
972 break;
973 case CDROM_MSF:
974 subchnl.cdsc_absaddr.msf.minute =
975 bcd2bin(q_info.abs.min);
976 subchnl.cdsc_absaddr.msf.second =
977 bcd2bin(q_info.abs.sec);
978 subchnl.cdsc_absaddr.msf.frame =
979 bcd2bin(q_info.abs.frame);
980 subchnl.cdsc_reladdr.msf.minute =
981 bcd2bin(q_info.rel.min);
982 subchnl.cdsc_reladdr.msf.second =
983 bcd2bin(q_info.rel.sec);
984 subchnl.cdsc_reladdr.msf.frame =
985 bcd2bin(q_info.rel.frame);
986 break;
987 default:
988 return (-EINVAL);
989 }
990 if (copy_to_user(argp, &subchnl,
991 sizeof(subchnl)))
992 s = -EFAULT;
993 }
994 return (s);
995 }
996
997 case CDROMVOLCTRL:{
998 struct cdrom_volctrl vol_ctrl;
999 int s;
1000#if defined( SJCD_TRACE )
1001 printk("SJCD: ioctl: volctrl\n");
1002#endif
1003 if ((s =
1004 access_ok(VERIFY_READ, argp, sizeof(vol_ctrl))
1005 ? 0 : -EFAULT) == 0) {
1006 unsigned char dummy[4];
1007
1008 if (copy_from_user(&vol_ctrl, argp,
1009 sizeof(vol_ctrl)))
1010 return (-EFAULT);
1011 sjcd_send_4_cmd(SCMD_SET_VOLUME,
1012 vol_ctrl.channel0, 0xFF,
1013 vol_ctrl.channel1, 0xFF);
1014 if (sjcd_receive_status() < 0)
1015 return (-EIO);
1016 (void) sjcd_load_response(dummy, 4);
1017 }
1018 return (s);
1019 }
1020
1021 case CDROMEJECT:{
1022#if defined( SJCD_TRACE )
1023 printk("SJCD: ioctl: eject\n");
1024#endif
1025 if (!sjcd_command_is_in_progress) {
1026 sjcd_tray_unlock();
1027 sjcd_send_cmd(SCMD_EJECT_TRAY);
1028 (void) sjcd_receive_status();
1029 }
1030 return (0);
1031 }
1032
1033#if defined( SJCD_GATHER_STAT )
1034 case 0xABCD:{
1035#if defined( SJCD_TRACE )
1036 printk("SJCD: ioctl: statistic\n");
1037#endif
1038 if (copy_to_user(argp, &statistic, sizeof(statistic)))
1039 return -EFAULT;
1040 return 0;
1041 }
1042#endif
1043
1044 default:
1045 return (-EINVAL);
1046 }
1047}
1048
1049/*
1050 * Invalidate internal buffers of the driver.
1051 */
1052static void sjcd_invalidate_buffers(void)
1053{
1054 int i;
1055 for (i = 0; i < SJCD_BUF_SIZ; sjcd_buf_bn[i++] = -1);
1056 sjcd_buf_out = -1;
1057}
1058
1059/*
1060 * Take care of the different block sizes between cdrom and Linux.
1061 * When Linux gets variable block sizes this will probably go away.
1062 */
1063
1064static int current_valid(void)
1065{
1066 return CURRENT &&
1067 CURRENT->cmd == READ &&
1068 CURRENT->sector != -1;
1069}
1070
1071static void sjcd_transfer(void)
1072{
1073#if defined( SJCD_TRACE )
1074 printk("SJCD: transfer:\n");
1075#endif
1076 if (current_valid()) {
1077 while (CURRENT->nr_sectors) {
1078 int i, bn = CURRENT->sector / 4;
1079 for (i = 0;
1080 i < SJCD_BUF_SIZ && sjcd_buf_bn[i] != bn;
1081 i++);
1082 if (i < SJCD_BUF_SIZ) {
1083 int offs =
1084 (i * 4 + (CURRENT->sector & 3)) * 512;
1085 int nr_sectors = 4 - (CURRENT->sector & 3);
1086 if (sjcd_buf_out != i) {
1087 sjcd_buf_out = i;
1088 if (sjcd_buf_bn[i] != bn) {
1089 sjcd_buf_out = -1;
1090 continue;
1091 }
1092 }
1093 if (nr_sectors > CURRENT->nr_sectors)
1094 nr_sectors = CURRENT->nr_sectors;
1095#if defined( SJCD_TRACE )
1096 printk("SJCD: copy out\n");
1097#endif
1098 memcpy(CURRENT->buffer, sjcd_buf + offs,
1099 nr_sectors * 512);
1100 CURRENT->nr_sectors -= nr_sectors;
1101 CURRENT->sector += nr_sectors;
1102 CURRENT->buffer += nr_sectors * 512;
1103 } else {
1104 sjcd_buf_out = -1;
1105 break;
1106 }
1107 }
1108 }
1109#if defined( SJCD_TRACE )
1110 printk("SJCD: transfer: done\n");
1111#endif
1112}
1113
1114static void sjcd_poll(void)
1115{
1116#if defined( SJCD_GATHER_STAT )
1117 /*
1118 * Update total number of ticks.
1119 */
1120 statistic.ticks++;
1121 statistic.tticks[sjcd_transfer_state]++;
1122#endif
1123
1124 ReSwitch:switch (sjcd_transfer_state) {
1125
1126 case SJCD_S_IDLE:{
1127#if defined( SJCD_GATHER_STAT )
1128 statistic.idle_ticks++;
1129#endif
1130#if defined( SJCD_TRACE )
1131 printk("SJCD_S_IDLE\n");
1132#endif
1133 return;
1134 }
1135
1136 case SJCD_S_START:{
1137#if defined( SJCD_GATHER_STAT )
1138 statistic.start_ticks++;
1139#endif
1140 sjcd_send_cmd(SCMD_GET_STATUS);
1141 sjcd_transfer_state =
1142 sjcd_mode ==
1143 SCMD_MODE_COOKED ? SJCD_S_READ : SJCD_S_MODE;
1144 sjcd_transfer_timeout = 500;
1145#if defined( SJCD_TRACE )
1146 printk("SJCD_S_START: goto SJCD_S_%s mode\n",
1147 sjcd_transfer_state ==
1148 SJCD_S_READ ? "READ" : "MODE");
1149#endif
1150 break;
1151 }
1152
1153 case SJCD_S_MODE:{
1154 if (sjcd_check_status()) {
1155 /*
1156 * Previous command is completed.
1157 */
1158 if (!sjcd_status_valid
1159 || sjcd_command_failed) {
1160#if defined( SJCD_TRACE )
1161 printk
1162 ("SJCD_S_MODE: pre-cmd failed: goto to SJCD_S_STOP mode\n");
1163#endif
1164 sjcd_transfer_state = SJCD_S_STOP;
1165 goto ReSwitch;
1166 }
1167
1168 sjcd_mode = 0; /* unknown mode; should not be valid when failed */
1169 sjcd_send_1_cmd(SCMD_SET_MODE,
1170 SCMD_MODE_COOKED);
1171 sjcd_transfer_state = SJCD_S_READ;
1172 sjcd_transfer_timeout = 1000;
1173#if defined( SJCD_TRACE )
1174 printk
1175 ("SJCD_S_MODE: goto SJCD_S_READ mode\n");
1176#endif
1177 }
1178#if defined( SJCD_GATHER_STAT )
1179 else
1180 statistic.mode_ticks++;
1181#endif
1182 break;
1183 }
1184
1185 case SJCD_S_READ:{
1186 if (sjcd_status_valid ? 1 : sjcd_check_status()) {
1187 /*
1188 * Previous command is completed.
1189 */
1190 if (!sjcd_status_valid
1191 || sjcd_command_failed) {
1192#if defined( SJCD_TRACE )
1193 printk
1194 ("SJCD_S_READ: pre-cmd failed: goto to SJCD_S_STOP mode\n");
1195#endif
1196 sjcd_transfer_state = SJCD_S_STOP;
1197 goto ReSwitch;
1198 }
1199 if (!sjcd_media_is_available) {
1200#if defined( SJCD_TRACE )
1201 printk
1202 ("SJCD_S_READ: no disk: goto to SJCD_S_STOP mode\n");
1203#endif
1204 sjcd_transfer_state = SJCD_S_STOP;
1205 goto ReSwitch;
1206 }
1207 if (sjcd_mode != SCMD_MODE_COOKED) {
1208 /*
1209 * We seem to come from set mode. So discard one byte of result.
1210 */
1211 if (sjcd_load_response
1212 (&sjcd_mode, 1) != 0) {
1213#if defined( SJCD_TRACE )
1214 printk
1215 ("SJCD_S_READ: load failed: goto to SJCD_S_STOP mode\n");
1216#endif
1217 sjcd_transfer_state =
1218 SJCD_S_STOP;
1219 goto ReSwitch;
1220 }
1221 if (sjcd_mode != SCMD_MODE_COOKED) {
1222#if defined( SJCD_TRACE )
1223 printk
1224 ("SJCD_S_READ: mode failed: goto to SJCD_S_STOP mode\n");
1225#endif
1226 sjcd_transfer_state =
1227 SJCD_S_STOP;
1228 goto ReSwitch;
1229 }
1230 }
1231
1232 if (current_valid()) {
1233 struct sjcd_play_msf msf;
1234
1235 sjcd_next_bn = CURRENT->sector / 4;
1236 hsg2msf(sjcd_next_bn, &msf.start);
1237 msf.end.min = 0;
1238 msf.end.sec = 0;
1239 msf.end.frame = sjcd_read_count =
1240 SJCD_BUF_SIZ;
1241#if defined( SJCD_TRACE )
1242 printk
1243 ("SJCD: ---reading msf-address %x:%x:%x %x:%x:%x\n",
1244 msf.start.min, msf.start.sec,
1245 msf.start.frame, msf.end.min,
1246 msf.end.sec, msf.end.frame);
1247 printk
1248 ("sjcd_next_bn:%x buf_in:%x buf_out:%x buf_bn:%x\n",
1249 sjcd_next_bn, sjcd_buf_in,
1250 sjcd_buf_out,
1251 sjcd_buf_bn[sjcd_buf_in]);
1252#endif
1253 sjcd_send_6_cmd(SCMD_DATA_READ,
1254 &msf);
1255 sjcd_transfer_state = SJCD_S_DATA;
1256 sjcd_transfer_timeout = 500;
1257#if defined( SJCD_TRACE )
1258 printk
1259 ("SJCD_S_READ: go to SJCD_S_DATA mode\n");
1260#endif
1261 } else {
1262#if defined( SJCD_TRACE )
1263 printk
1264 ("SJCD_S_READ: nothing to read: go to SJCD_S_STOP mode\n");
1265#endif
1266 sjcd_transfer_state = SJCD_S_STOP;
1267 goto ReSwitch;
1268 }
1269 }
1270#if defined( SJCD_GATHER_STAT )
1271 else
1272 statistic.read_ticks++;
1273#endif
1274 break;
1275 }
1276
1277 case SJCD_S_DATA:{
1278 unsigned char stat;
1279
1280 sjcd_s_data:stat =
1281 inb(SJCDPORT
1282 (1));
1283#if defined( SJCD_TRACE )
1284 printk("SJCD_S_DATA: status = 0x%02x\n", stat);
1285#endif
1286 if (SJCD_STATUS_AVAILABLE(stat)) {
1287 /*
1288 * No data is waiting for us in the drive buffer. Status of operation
1289 * completion is available. Read and parse it.
1290 */
1291 sjcd_load_status();
1292
1293 if (!sjcd_status_valid
1294 || sjcd_command_failed) {
1295#if defined( SJCD_TRACE )
1296 printk
1297 ("SJCD: read block %d failed, maybe audio disk? Giving up\n",
1298 sjcd_next_bn);
1299#endif
1300 if (current_valid())
1301 end_request(CURRENT, 0);
1302#if defined( SJCD_TRACE )
1303 printk
1304 ("SJCD_S_DATA: pre-cmd failed: go to SJCD_S_STOP mode\n");
1305#endif
1306 sjcd_transfer_state = SJCD_S_STOP;
1307 goto ReSwitch;
1308 }
1309
1310 if (!sjcd_media_is_available) {
1311 printk
1312 ("SJCD_S_DATA: no disk: go to SJCD_S_STOP mode\n");
1313 sjcd_transfer_state = SJCD_S_STOP;
1314 goto ReSwitch;
1315 }
1316
1317 sjcd_transfer_state = SJCD_S_READ;
1318 goto ReSwitch;
1319 } else if (SJCD_DATA_AVAILABLE(stat)) {
1320 /*
1321 * One frame is read into device buffer. We must copy it to our memory.
1322 * Otherwise cdrom hangs up. Check to see if we have something to copy
1323 * to.
1324 */
1325 if (!current_valid()
1326 && sjcd_buf_in == sjcd_buf_out) {
1327#if defined( SJCD_TRACE )
1328 printk
1329 ("SJCD_S_DATA: nothing to read: go to SJCD_S_STOP mode\n");
1330 printk
1331 (" ... all the date would be discarded\n");
1332#endif
1333 sjcd_transfer_state = SJCD_S_STOP;
1334 goto ReSwitch;
1335 }
1336
1337 /*
1338 * Everything seems to be OK. Just read the frame and recalculate
1339 * indices.
1340 */
1341 sjcd_buf_bn[sjcd_buf_in] = -1; /* ??? */
1342 insb(SJCDPORT(2),
1343 sjcd_buf + 2048 * sjcd_buf_in, 2048);
1344#if defined( SJCD_TRACE )
1345 printk
1346 ("SJCD_S_DATA: next_bn=%d, buf_in=%d, buf_out=%d, buf_bn=%d\n",
1347 sjcd_next_bn, sjcd_buf_in,
1348 sjcd_buf_out,
1349 sjcd_buf_bn[sjcd_buf_in]);
1350#endif
1351 sjcd_buf_bn[sjcd_buf_in] = sjcd_next_bn++;
1352 if (sjcd_buf_out == -1)
1353 sjcd_buf_out = sjcd_buf_in;
1354 if (++sjcd_buf_in == SJCD_BUF_SIZ)
1355 sjcd_buf_in = 0;
1356
1357 /*
1358 * Only one frame is ready at time. So we should turn over to wait for
1359 * another frame. If we need that, of course.
1360 */
1361 if (--sjcd_read_count == 0) {
1362 /*
1363 * OK, request seems to be precessed. Continue transferring...
1364 */
1365 if (!sjcd_transfer_is_active) {
1366 while (current_valid()) {
1367 /*
1368 * Continue transferring.
1369 */
1370 sjcd_transfer();
1371 if (CURRENT->
1372 nr_sectors ==
1373 0)
1374 end_request
1375 (CURRENT, 1);
1376 else
1377 break;
1378 }
1379 }
1380 if (current_valid() &&
1381 (CURRENT->sector / 4 <
1382 sjcd_next_bn
1383 || CURRENT->sector / 4 >
1384 sjcd_next_bn +
1385 SJCD_BUF_SIZ)) {
1386#if defined( SJCD_TRACE )
1387 printk
1388 ("SJCD_S_DATA: can't read: go to SJCD_S_STOP mode\n");
1389#endif
1390 sjcd_transfer_state =
1391 SJCD_S_STOP;
1392 goto ReSwitch;
1393 }
1394 }
1395 /*
1396 * Now we should turn around rather than wait for while.
1397 */
1398 goto sjcd_s_data;
1399 }
1400#if defined( SJCD_GATHER_STAT )
1401 else
1402 statistic.data_ticks++;
1403#endif
1404 break;
1405 }
1406
1407 case SJCD_S_STOP:{
1408 sjcd_read_count = 0;
1409 sjcd_send_cmd(SCMD_STOP);
1410 sjcd_transfer_state = SJCD_S_STOPPING;
1411 sjcd_transfer_timeout = 500;
1412#if defined( SJCD_GATHER_STAT )
1413 statistic.stop_ticks++;
1414#endif
1415 break;
1416 }
1417
1418 case SJCD_S_STOPPING:{
1419 unsigned char stat;
1420
1421 stat = inb(SJCDPORT(1));
1422#if defined( SJCD_TRACE )
1423 printk("SJCD_S_STOP: status = 0x%02x\n", stat);
1424#endif
1425 if (SJCD_DATA_AVAILABLE(stat)) {
1426 int i;
1427#if defined( SJCD_TRACE )
1428 printk("SJCD_S_STOP: discard data\n");
1429#endif
1430 /*
1431 * Discard all the data from the pipe. Foolish method.
1432 */
1433 for (i = 2048; i--;
1434 (void) inb(SJCDPORT(2)));
1435 sjcd_transfer_timeout = 500;
1436 } else if (SJCD_STATUS_AVAILABLE(stat)) {
1437 sjcd_load_status();
1438 if (sjcd_status_valid
1439 && sjcd_media_is_changed) {
1440 sjcd_toc_uptodate = 0;
1441 sjcd_invalidate_buffers();
1442 }
1443 if (current_valid()) {
1444 if (sjcd_status_valid)
1445 sjcd_transfer_state =
1446 SJCD_S_READ;
1447 else
1448 sjcd_transfer_state =
1449 SJCD_S_START;
1450 } else
1451 sjcd_transfer_state = SJCD_S_IDLE;
1452 goto ReSwitch;
1453 }
1454#if defined( SJCD_GATHER_STAT )
1455 else
1456 statistic.stopping_ticks++;
1457#endif
1458 break;
1459 }
1460
1461 default:
1462 printk("SJCD: poll: invalid state %d\n",
1463 sjcd_transfer_state);
1464 return;
1465 }
1466
1467 if (--sjcd_transfer_timeout == 0) {
1468 printk("SJCD: timeout in state %d\n", sjcd_transfer_state);
1469 while (current_valid())
1470 end_request(CURRENT, 0);
1471 sjcd_send_cmd(SCMD_STOP);
1472 sjcd_transfer_state = SJCD_S_IDLE;
1473 goto ReSwitch;
1474 }
1475
1476 /*
1477 * Get back in some time. 1 should be replaced with count variable to
1478 * avoid unnecessary testings.
1479 */
1480 SJCD_SET_TIMER(sjcd_poll, 1);
1481}
1482
1483static void do_sjcd_request(request_queue_t * q)
1484{
1485#if defined( SJCD_TRACE )
1486 printk("SJCD: do_sjcd_request(%ld+%ld)\n",
1487 CURRENT->sector, CURRENT->nr_sectors);
1488#endif
1489 sjcd_transfer_is_active = 1;
1490 while (current_valid()) {
1491 sjcd_transfer();
1492 if (CURRENT->nr_sectors == 0)
1493 end_request(CURRENT, 1);
1494 else {
1495 sjcd_buf_out = -1; /* Want to read a block not in buffer */
1496 if (sjcd_transfer_state == SJCD_S_IDLE) {
1497 if (!sjcd_toc_uptodate) {
1498 if (sjcd_update_toc() < 0) {
1499 printk
1500 ("SJCD: transfer: discard\n");
1501 while (current_valid())
1502 end_request(CURRENT, 0);
1503 break;
1504 }
1505 }
1506 sjcd_transfer_state = SJCD_S_START;
1507 SJCD_SET_TIMER(sjcd_poll, HZ / 100);
1508 }
1509 break;
1510 }
1511 }
1512 sjcd_transfer_is_active = 0;
1513#if defined( SJCD_TRACE )
1514 printk
1515 ("sjcd_next_bn:%x sjcd_buf_in:%x sjcd_buf_out:%x sjcd_buf_bn:%x\n",
1516 sjcd_next_bn, sjcd_buf_in, sjcd_buf_out,
1517 sjcd_buf_bn[sjcd_buf_in]);
1518 printk("do_sjcd_request ends\n");
1519#endif
1520}
1521
1522/*
1523 * Open the device special file. Check disk is in.
1524 */
1525static int sjcd_open(struct inode *ip, struct file *fp)
1526{
1527 /*
1528 * Check the presence of device.
1529 */
1530 if (!sjcd_present)
1531 return (-ENXIO);
1532
1533 /*
1534 * Only read operations are allowed. Really? (:-)
1535 */
1536 if (fp->f_mode & 2)
1537 return (-EROFS);
1538
1539 if (sjcd_open_count == 0) {
1540 int s, sjcd_open_tries;
1541/* We don't know that, do we? */
1542/*
1543 sjcd_audio_status = CDROM_AUDIO_NO_STATUS;
1544*/
1545 sjcd_mode = 0;
1546 sjcd_door_was_open = 0;
1547 sjcd_transfer_state = SJCD_S_IDLE;
1548 sjcd_invalidate_buffers();
1549 sjcd_status_valid = 0;
1550
1551 /*
1552 * Strict status checking.
1553 */
1554 for (sjcd_open_tries = 4; --sjcd_open_tries;) {
1555 if (!sjcd_status_valid)
1556 sjcd_get_status();
1557 if (!sjcd_status_valid) {
1558#if defined( SJCD_DIAGNOSTIC )
1559 printk
1560 ("SJCD: open: timed out when check status.\n");
1561#endif
1562 goto err_out;
1563 } else if (!sjcd_media_is_available) {
1564#if defined( SJCD_DIAGNOSTIC )
1565 printk("SJCD: open: no disk in drive\n");
1566#endif
1567 if (!sjcd_door_closed) {
1568 sjcd_door_was_open = 1;
1569#if defined( SJCD_TRACE )
1570 printk
1571 ("SJCD: open: close the tray\n");
1572#endif
1573 s = sjcd_tray_close();
1574 if (s < 0 || !sjcd_status_valid
1575 || sjcd_command_failed) {
1576#if defined( SJCD_DIAGNOSTIC )
1577 printk
1578 ("SJCD: open: tray close attempt failed\n");
1579#endif
1580 goto err_out;
1581 }
1582 continue;
1583 } else
1584 goto err_out;
1585 }
1586 break;
1587 }
1588 s = sjcd_tray_lock();
1589 if (s < 0 || !sjcd_status_valid || sjcd_command_failed) {
1590#if defined( SJCD_DIAGNOSTIC )
1591 printk("SJCD: open: tray lock attempt failed\n");
1592#endif
1593 goto err_out;
1594 }
1595#if defined( SJCD_TRACE )
1596 printk("SJCD: open: done\n");
1597#endif
1598 }
1599
1600 ++sjcd_open_count;
1601 return (0);
1602
1603 err_out:
1604 return (-EIO);
1605}
1606
1607/*
1608 * On close, we flush all sjcd blocks from the buffer cache.
1609 */
1610static int sjcd_release(struct inode *inode, struct file *file)
1611{
1612 int s;
1613
1614#if defined( SJCD_TRACE )
1615 printk("SJCD: release\n");
1616#endif
1617 if (--sjcd_open_count == 0) {
1618 sjcd_invalidate_buffers();
1619 s = sjcd_tray_unlock();
1620 if (s < 0 || !sjcd_status_valid || sjcd_command_failed) {
1621#if defined( SJCD_DIAGNOSTIC )
1622 printk
1623 ("SJCD: release: tray unlock attempt failed.\n");
1624#endif
1625 }
1626 if (sjcd_door_was_open) {
1627 s = sjcd_tray_open();
1628 if (s < 0 || !sjcd_status_valid
1629 || sjcd_command_failed) {
1630#if defined( SJCD_DIAGNOSTIC )
1631 printk
1632 ("SJCD: release: tray unload attempt failed.\n");
1633#endif
1634 }
1635 }
1636 }
1637 return 0;
1638}
1639
1640/*
1641 * A list of file operations allowed for this cdrom.
1642 */
1643static struct block_device_operations sjcd_fops = {
1644 .owner = THIS_MODULE,
1645 .open = sjcd_open,
1646 .release = sjcd_release,
1647 .ioctl = sjcd_ioctl,
1648 .media_changed = sjcd_disk_change,
1649};
1650
1651/*
1652 * Following stuff is intended for initialization of the cdrom. It
1653 * first looks for presence of device. If the device is present, it
1654 * will be reset. Then read the version of the drive and load status.
1655 * The version is two BCD-coded bytes.
1656 */
1657static struct {
1658 unsigned char major, minor;
1659} sjcd_version;
1660
1661static struct gendisk *sjcd_disk;
1662
1663/*
1664 * Test for presence of drive and initialize it. Called at boot time.
1665 * Probe cdrom, find out version and status.
1666 */
1667static int __init sjcd_init(void)
1668{
1669 int i;
1670
1671 printk(KERN_INFO
1672 "SJCD: Sanyo CDR-H94A cdrom driver version %d.%d.\n",
1673 SJCD_VERSION_MAJOR, SJCD_VERSION_MINOR);
1674
1675#if defined( SJCD_TRACE )
1676 printk("SJCD: sjcd=0x%x: ", sjcd_base);
1677#endif
1678
1679 if (register_blkdev(MAJOR_NR, "sjcd"))
1680 return -EIO;
1681
1682 sjcd_queue = blk_init_queue(do_sjcd_request, &sjcd_lock);
1683 if (!sjcd_queue)
1684 goto out0;
1685
1686 blk_queue_hardsect_size(sjcd_queue, 2048);
1687
1688 sjcd_disk = alloc_disk(1);
1689 if (!sjcd_disk) {
1690 printk(KERN_ERR "SJCD: can't allocate disk");
1691 goto out1;
1692 }
1693 sjcd_disk->major = MAJOR_NR,
1694 sjcd_disk->first_minor = 0,
1695 sjcd_disk->fops = &sjcd_fops,
1696 sprintf(sjcd_disk->disk_name, "sjcd");
1697
1698 if (!request_region(sjcd_base, 4,"sjcd")) {
1699 printk
1700 ("SJCD: Init failed, I/O port (%X) is already in use\n",
1701 sjcd_base);
1702 goto out2;
1703 }
1704
1705 /*
1706 * Check for card. Since we are booting now, we can't use standard
1707 * wait algorithm.
1708 */
1709 printk(KERN_INFO "SJCD: Resetting: ");
1710 sjcd_send_cmd(SCMD_RESET);
1711 for (i = 1000; i > 0 && !sjcd_status_valid; --i) {
1712 unsigned long timer;
1713
1714 /*
1715 * Wait 10ms approx.
1716 */
1717 for (timer = jiffies; time_before_eq(jiffies, timer););
1718 if ((i % 100) == 0)
1719 printk(".");
1720 (void) sjcd_check_status();
1721 }
1722 if (i == 0 || sjcd_command_failed) {
1723 printk(" reset failed, no drive found.\n");
1724 goto out3;
1725 } else
1726 printk("\n");
1727
1728 /*
1729 * Get and print out cdrom version.
1730 */
1731 printk(KERN_INFO "SJCD: Getting version: ");
1732 sjcd_send_cmd(SCMD_GET_VERSION);
1733 for (i = 1000; i > 0 && !sjcd_status_valid; --i) {
1734 unsigned long timer;
1735
1736 /*
1737 * Wait 10ms approx.
1738 */
1739 for (timer = jiffies; time_before_eq(jiffies, timer););
1740 if ((i % 100) == 0)
1741 printk(".");
1742 (void) sjcd_check_status();
1743 }
1744 if (i == 0 || sjcd_command_failed) {
1745 printk(" get version failed, no drive found.\n");
1746 goto out3;
1747 }
1748
1749 if (sjcd_load_response(&sjcd_version, sizeof(sjcd_version)) == 0) {
1750 printk(" %1x.%02x\n", (int) sjcd_version.major,
1751 (int) sjcd_version.minor);
1752 } else {
1753 printk(" read version failed, no drive found.\n");
1754 goto out3;
1755 }
1756
1757 /*
1758 * Check and print out the tray state. (if it is needed?).
1759 */
1760 if (!sjcd_status_valid) {
1761 printk(KERN_INFO "SJCD: Getting status: ");
1762 sjcd_send_cmd(SCMD_GET_STATUS);
1763 for (i = 1000; i > 0 && !sjcd_status_valid; --i) {
1764 unsigned long timer;
1765
1766 /*
1767 * Wait 10ms approx.
1768 */
1769 for (timer = jiffies;
1770 time_before_eq(jiffies, timer););
1771 if ((i % 100) == 0)
1772 printk(".");
1773 (void) sjcd_check_status();
1774 }
1775 if (i == 0 || sjcd_command_failed) {
1776 printk(" get status failed, no drive found.\n");
1777 goto out3;
1778 } else
1779 printk("\n");
1780 }
1781
1782 printk(KERN_INFO "SJCD: Status: port=0x%x.\n", sjcd_base);
1783 sjcd_disk->queue = sjcd_queue;
1784 add_disk(sjcd_disk);
1785
1786 sjcd_present++;
1787 return (0);
1788out3:
1789 release_region(sjcd_base, 4);
1790out2:
1791 put_disk(sjcd_disk);
1792out1:
1793 blk_cleanup_queue(sjcd_queue);
1794out0:
1795 if ((unregister_blkdev(MAJOR_NR, "sjcd") == -EINVAL))
1796 printk("SJCD: cannot unregister device.\n");
1797 return (-EIO);
1798}
1799
1800static void __exit sjcd_exit(void)
1801{
1802 del_gendisk(sjcd_disk);
1803 put_disk(sjcd_disk);
1804 release_region(sjcd_base, 4);
1805 blk_cleanup_queue(sjcd_queue);
1806 if ((unregister_blkdev(MAJOR_NR, "sjcd") == -EINVAL))
1807 printk("SJCD: cannot unregister device.\n");
1808 printk(KERN_INFO "SJCD: module: removed.\n");
1809}
1810
1811module_init(sjcd_init);
1812module_exit(sjcd_exit);
1813
1814MODULE_LICENSE("GPL");
1815MODULE_ALIAS_BLOCKDEV_MAJOR(SANYO_CDROM_MAJOR);
diff --git a/drivers/cdrom/sjcd.h b/drivers/cdrom/sjcd.h
deleted file mode 100644
index 0aa5e714659d..000000000000
--- a/drivers/cdrom/sjcd.h
+++ /dev/null
@@ -1,181 +0,0 @@
1/*
2 * Definitions for a Sanyo CD-ROM interface.
3 *
4 * Copyright (C) 1995 Vadim V. Model
5 * model@cecmow.enet.dec.com
6 * vadim@rbrf.msk.su
7 * vadim@ipsun.ras.ru
8 * Eric van der Maarel
9 * H.T.M.v.d.Maarel@marin.nl
10 *
11 * This information is based on mcd.c from M. Harriss and sjcd102.lst from
12 * E. Moenkeberg.
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 */
28
29#ifndef __SJCD_H__
30#define __SJCD_H__
31
32/*
33 * Change this to set the I/O port address as default. More flexibility
34 * come with setup implementation.
35 */
36#define SJCD_BASE_ADDR 0x340
37
38/*
39 * Change this to set the irq as default. Really SANYO do not use interrupts
40 * at all.
41 */
42#define SJCD_INTR_NR 0
43
44/*
45 * Change this to set the dma as default value. really SANYO does not use
46 * direct memory access at all.
47 */
48#define SJCD_DMA_NR 0
49
50/*
51 * Macros which allow us to find out the status of the drive.
52 */
53#define SJCD_STATUS_AVAILABLE( x ) (((x)&0x02)==0)
54#define SJCD_DATA_AVAILABLE( x ) (((x)&0x01)==0)
55
56/*
57 * Port access macro. Three ports are available: S-data port (command port),
58 * status port (read only) and D-data port (read only).
59 */
60#define SJCDPORT( x ) ( sjcd_base + ( x ) )
61#define SJCD_STATUS_PORT SJCDPORT( 1 )
62#define SJCD_S_DATA_PORT SJCDPORT( 0 )
63#define SJCD_COMMAND_PORT SJCDPORT( 0 )
64#define SJCD_D_DATA_PORT SJCDPORT( 2 )
65
66/*
67 * Drive info bits. Drive info available as first (mandatory) byte of
68 * command completion status.
69 */
70#define SST_NOT_READY 0x10 /* no disk in the drive (???) */
71#define SST_MEDIA_CHANGED 0x20 /* disk is changed */
72#define SST_DOOR_OPENED 0x40 /* door is open */
73
74/* commands */
75
76#define SCMD_EJECT_TRAY 0xD0 /* eject tray if not locked */
77#define SCMD_LOCK_TRAY 0xD2 /* lock tray when in */
78#define SCMD_UNLOCK_TRAY 0xD4 /* unlock tray when in */
79#define SCMD_CLOSE_TRAY 0xD6 /* load tray in */
80
81#define SCMD_RESET 0xFA /* soft reset */
82#define SCMD_GET_STATUS 0x80
83#define SCMD_GET_VERSION 0xCC
84
85#define SCMD_DATA_READ 0xA0 /* are the same, depend on mode&args */
86#define SCMD_SEEK 0xA0
87#define SCMD_PLAY 0xA0
88
89#define SCMD_GET_QINFO 0xA8
90
91#define SCMD_SET_MODE 0xC4
92#define SCMD_MODE_PLAY 0xE0
93#define SCMD_MODE_COOKED (0xF8 & ~0x20)
94#define SCMD_MODE_RAW 0xF9
95#define SCMD_MODE_x20_BIT 0x20 /* What is it for ? */
96
97#define SCMD_SET_VOLUME 0xAE
98#define SCMD_PAUSE 0xE0
99#define SCMD_STOP 0xE0
100
101#define SCMD_GET_DISK_INFO 0xAA
102
103/*
104 * Some standard arguments for SCMD_GET_DISK_INFO.
105 */
106#define SCMD_GET_1_TRACK 0xA0 /* get the first track information */
107#define SCMD_GET_L_TRACK 0xA1 /* get the last track information */
108#define SCMD_GET_D_SIZE 0xA2 /* get the whole disk information */
109
110/*
111 * Borrowed from hd.c. Allows to optimize multiple port read commands.
112 */
113#define S_READ_DATA( port, buf, nr ) insb( port, buf, nr )
114
115/*
116 * We assume that there are no audio disks with TOC length more than this
117 * number (I personally have never seen disks with more than 20 fragments).
118 */
119#define SJCD_MAX_TRACKS 100
120
121struct msf {
122 unsigned char min;
123 unsigned char sec;
124 unsigned char frame;
125};
126
127struct sjcd_hw_disk_info {
128 unsigned char track_control;
129 unsigned char track_no;
130 unsigned char x, y, z;
131 union {
132 unsigned char track_no;
133 struct msf track_msf;
134 } un;
135};
136
137struct sjcd_hw_qinfo {
138 unsigned char track_control;
139 unsigned char track_no;
140 unsigned char x;
141 struct msf rel;
142 struct msf abs;
143};
144
145struct sjcd_play_msf {
146 struct msf start;
147 struct msf end;
148};
149
150struct sjcd_disk_info {
151 unsigned char first;
152 unsigned char last;
153 struct msf disk_length;
154 struct msf first_track;
155};
156
157struct sjcd_toc {
158 unsigned char ctrl_addr;
159 unsigned char track;
160 unsigned char point_index;
161 struct msf track_time;
162 struct msf disk_time;
163};
164
165#if defined( SJCD_GATHER_STAT )
166
167struct sjcd_stat {
168 int ticks;
169 int tticks[ 8 ];
170 int idle_ticks;
171 int start_ticks;
172 int mode_ticks;
173 int read_ticks;
174 int data_ticks;
175 int stop_ticks;
176 int stopping_ticks;
177};
178
179#endif
180
181#endif
diff --git a/drivers/cdrom/sonycd535.c b/drivers/cdrom/sonycd535.c
deleted file mode 100644
index f77ada933ea0..000000000000
--- a/drivers/cdrom/sonycd535.c
+++ /dev/null
@@ -1,1689 +0,0 @@
1/*
2 * Sony CDU-535 interface device driver
3 *
4 * This is a modified version of the CDU-31A device driver (see below).
5 * Changes were made using documentation for the CDU-531 (which Sony
6 * assures me is very similar to the 535) and partial disassembly of the
7 * DOS driver. I used Minyard's driver and replaced the CDU-31A
8 * commands with the CDU-531 commands. This was complicated by a different
9 * interface protocol with the drive. The driver is still polled.
10 *
11 * Data transfer rate is about 110 Kb/sec, theoretical maximum is 150 Kb/sec.
12 * I tried polling without the sony_sleep during the data transfers but
13 * it did not speed things up any.
14 *
15 * 1993-05-23 (rgj) changed the major number to 21 to get rid of conflict
16 * with CDU-31A driver. This is the also the number from the Linux
17 * Device Driver Registry for the Sony Drive. Hope nobody else is using it.
18 *
19 * 1993-08-29 (rgj) remove the configuring of the interface board address
20 * from the top level configuration, you have to modify it in this file.
21 *
22 * 1995-01-26 Made module-capable (Joel Katz <Stimpson@Panix.COM>)
23 *
24 * 1995-05-20
25 * Modified to support CDU-510/515 series
26 * (Claudio Porfiri<C.Porfiri@nisms.tei.ericsson.se>)
27 * Fixed to report verify_area() failures
28 * (Heiko Eissfeldt <heiko@colossus.escape.de>)
29 *
30 * 1995-06-01
31 * More changes to support CDU-510/515 series
32 * (Claudio Porfiri<C.Porfiri@nisms.tei.ericsson.se>)
33 *
34 * November 1999 -- Make kernel-parameter implementation work with 2.3.x
35 * Removed init_module & cleanup_module in favor of
36 * module_init & module_exit.
37 * Torben Mathiasen <tmm@image.dk>
38 *
39 * September 2003 - Fix SMP support by removing cli/sti calls.
40 * Using spinlocks with a wait_queue instead.
41 * Felipe Damasio <felipewd@terra.com.br>
42 *
43 * Things to do:
44 * - handle errors and status better, put everything into a single word
45 * - use interrupts (code mostly there, but a big hole still missing)
46 * - handle multi-session CDs?
47 * - use DMA?
48 *
49 * Known Bugs:
50 * -
51 *
52 * Ken Pizzini (ken@halcyon.com)
53 *
54 * Original by:
55 * Ron Jeppesen (ronj.an@site007.saic.com)
56 *
57 *
58 *------------------------------------------------------------------------
59 * Sony CDROM interface device driver.
60 *
61 * Corey Minyard (minyard@wf-rch.cirr.com) (CDU-535 complaints to Ken above)
62 *
63 * Colossians 3:17
64 *
65 * The Sony interface device driver handles Sony interface CDROM
66 * drives and provides a complete block-level interface as well as an
67 * ioctl() interface compatible with the Sun (as specified in
68 * include/linux/cdrom.h). With this interface, CDROMs can be
69 * accessed and standard audio CDs can be played back normally.
70 *
71 * This interface is (unfortunately) a polled interface. This is
72 * because most Sony interfaces are set up with DMA and interrupts
73 * disables. Some (like mine) do not even have the capability to
74 * handle interrupts or DMA. For this reason you will see a bit of
75 * the following:
76 *
77 * snap = jiffies;
78 * while (jiffies-snap < SONY_JIFFIES_TIMEOUT)
79 * {
80 * if (some_condition())
81 * break;
82 * sony_sleep();
83 * }
84 * if (some_condition not met)
85 * {
86 * return an_error;
87 * }
88 *
89 * This ugly hack waits for something to happen, sleeping a little
90 * between every try. (The conditional is written so that jiffies
91 * wrap-around is handled properly.)
92 *
93 * One thing about these drives: They talk in MSF (Minute Second Frame) format.
94 * There are 75 frames a second, 60 seconds a minute, and up to 75 minutes on a
95 * disk. The funny thing is that these are sent to the drive in BCD, but the
96 * interface wants to see them in decimal. A lot of conversion goes on.
97 *
98 * Copyright (C) 1993 Corey Minyard
99 *
100 * This program is free software; you can redistribute it and/or modify
101 * it under the terms of the GNU General Public License as published by
102 * the Free Software Foundation; either version 2 of the License, or
103 * (at your option) any later version.
104 *
105 * This program is distributed in the hope that it will be useful,
106 * but WITHOUT ANY WARRANTY; without even the implied warranty of
107 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
108 * GNU General Public License for more details.
109 *
110 * You should have received a copy of the GNU General Public License
111 * along with this program; if not, write to the Free Software
112 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
113 *
114 */
115
116
117# include <linux/module.h>
118
119#include <linux/errno.h>
120#include <linux/signal.h>
121#include <linux/sched.h>
122#include <linux/timer.h>
123#include <linux/fs.h>
124#include <linux/kernel.h>
125#include <linux/interrupt.h>
126#include <linux/ioport.h>
127#include <linux/hdreg.h>
128#include <linux/genhd.h>
129#include <linux/mm.h>
130#include <linux/slab.h>
131#include <linux/init.h>
132
133#define REALLY_SLOW_IO
134#include <asm/system.h>
135#include <asm/io.h>
136#include <asm/uaccess.h>
137
138#include <linux/cdrom.h>
139
140#define MAJOR_NR CDU535_CDROM_MAJOR
141#include <linux/blkdev.h>
142
143#define sony535_cd_base_io sonycd535 /* for compatible parameter passing with "insmod" */
144#include "sonycd535.h"
145
146/*
147 * this is the base address of the interface card for the Sony CDU-535
148 * CDROM drive. If your jumpers are set for an address other than
149 * this one (the default), change the following line to the
150 * proper address.
151 */
152#ifndef CDU535_ADDRESS
153# define CDU535_ADDRESS 0x340
154#endif
155#ifndef CDU535_INTERRUPT
156# define CDU535_INTERRUPT 0
157#endif
158#ifndef CDU535_HANDLE
159# define CDU535_HANDLE "cdu535"
160#endif
161#ifndef CDU535_MESSAGE_NAME
162# define CDU535_MESSAGE_NAME "Sony CDU-535"
163#endif
164
165#define CDU535_BLOCK_SIZE 2048
166
167#ifndef MAX_SPINUP_RETRY
168# define MAX_SPINUP_RETRY 3 /* 1 is sufficient for most drives... */
169#endif
170#ifndef RETRY_FOR_BAD_STATUS
171# define RETRY_FOR_BAD_STATUS 100 /* in 10th of second */
172#endif
173
174#ifndef DEBUG
175# define DEBUG 1
176#endif
177
178/*
179 * SONY535_BUFFER_SIZE determines the size of internal buffer used
180 * by the drive. It must be at least 2K and the larger the buffer
181 * the better the transfer rate. It does however take system memory.
182 * On my system I get the following transfer rates using dd to read
183 * 10 Mb off /dev/cdrom.
184 *
185 * 8K buffer 43 Kb/sec
186 * 16K buffer 66 Kb/sec
187 * 32K buffer 91 Kb/sec
188 * 64K buffer 111 Kb/sec
189 * 128K buffer 123 Kb/sec
190 * 512K buffer 123 Kb/sec
191 */
192#define SONY535_BUFFER_SIZE (64*1024)
193
194/*
195 * if LOCK_DOORS is defined then the eject button is disabled while
196 * the device is open.
197 */
198#ifndef NO_LOCK_DOORS
199# define LOCK_DOORS
200#endif
201
202static int read_subcode(void);
203static void sony_get_toc(void);
204static int cdu_open(struct inode *inode, struct file *filp);
205static inline unsigned int int_to_bcd(unsigned int val);
206static unsigned int bcd_to_int(unsigned int bcd);
207static int do_sony_cmd(Byte * cmd, int nCmd, Byte status[2],
208 Byte * response, int n_response, int ignoreStatusBit7);
209
210/* The base I/O address of the Sony Interface. This is a variable (not a
211 #define) so it can be easily changed via some future ioctl() */
212static unsigned int sony535_cd_base_io = CDU535_ADDRESS;
213module_param(sony535_cd_base_io, int, 0);
214
215/*
216 * The following are I/O addresses of the various registers for the drive. The
217 * comment for the base address also applies here.
218 */
219static unsigned short select_unit_reg;
220static unsigned short result_reg;
221static unsigned short command_reg;
222static unsigned short read_status_reg;
223static unsigned short data_reg;
224
225static DEFINE_SPINLOCK(sonycd535_lock); /* queue lock */
226static struct request_queue *sonycd535_queue;
227
228static int initialized; /* Has the drive been initialized? */
229static int sony_disc_changed = 1; /* Has the disk been changed
230 since the last check? */
231static int sony_toc_read; /* Has the table of contents been
232 read? */
233static unsigned int sony_buffer_size; /* Size in bytes of the read-ahead
234 buffer. */
235static unsigned int sony_buffer_sectors; /* Size (in 2048 byte records) of
236 the read-ahead buffer. */
237static unsigned int sony_usage; /* How many processes have the
238 drive open. */
239
240static int sony_first_block = -1; /* First OS block (512 byte) in
241 the read-ahead buffer */
242static int sony_last_block = -1; /* Last OS block (512 byte) in
243 the read-ahead buffer */
244
245static struct s535_sony_toc *sony_toc; /* Points to the table of
246 contents. */
247
248static struct s535_sony_subcode *last_sony_subcode; /* Points to the last
249 subcode address read */
250static Byte **sony_buffer; /* Points to the pointers
251 to the sector buffers */
252
253static int sony_inuse; /* is the drive in use? Only one
254 open at a time allowed */
255
256/*
257 * The audio status uses the values from read subchannel data as specified
258 * in include/linux/cdrom.h.
259 */
260static int sony_audio_status = CDROM_AUDIO_NO_STATUS;
261
262/*
263 * The following are a hack for pausing and resuming audio play. The drive
264 * does not work as I would expect it, if you stop it then start it again,
265 * the drive seeks back to the beginning and starts over. This holds the
266 * position during a pause so a resume can restart it. It uses the
267 * audio status variable above to tell if it is paused.
268 * I just kept the CDU-31A driver behavior rather than using the PAUSE
269 * command on the CDU-535.
270 */
271static Byte cur_pos_msf[3];
272static Byte final_pos_msf[3];
273
274/* What IRQ is the drive using? 0 if none. */
275static int sony535_irq_used = CDU535_INTERRUPT;
276
277/* The interrupt handler will wake this queue up when it gets an interrupt. */
278static DECLARE_WAIT_QUEUE_HEAD(cdu535_irq_wait);
279
280
281/*
282 * This routine returns 1 if the disk has been changed since the last
283 * check or 0 if it hasn't. Setting flag to 0 resets the changed flag.
284 */
285static int
286cdu535_check_media_change(struct gendisk *disk)
287{
288 /* if driver is not initialized, always return 0 */
289 int retval = initialized ? sony_disc_changed : 0;
290 sony_disc_changed = 0;
291 return retval;
292}
293
294static inline void
295enable_interrupts(void)
296{
297#ifdef USE_IRQ
298 /*
299 * This code was taken from cdu31a.c; it will not
300 * directly work for the cdu535 as written...
301 */
302 curr_control_reg |= ( SONY_ATTN_INT_EN_BIT
303 | SONY_RES_RDY_INT_EN_BIT
304 | SONY_DATA_RDY_INT_EN_BIT);
305 outb(curr_control_reg, sony_cd_control_reg);
306#endif
307}
308
309static inline void
310disable_interrupts(void)
311{
312#ifdef USE_IRQ
313 /*
314 * This code was taken from cdu31a.c; it will not
315 * directly work for the cdu535 as written...
316 */
317 curr_control_reg &= ~(SONY_ATTN_INT_EN_BIT
318 | SONY_RES_RDY_INT_EN_BIT
319 | SONY_DATA_RDY_INT_EN_BIT);
320 outb(curr_control_reg, sony_cd_control_reg);
321#endif
322}
323
324static irqreturn_t
325cdu535_interrupt(int irq, void *dev_id)
326{
327 disable_interrupts();
328 if (waitqueue_active(&cdu535_irq_wait)) {
329 wake_up(&cdu535_irq_wait);
330 return IRQ_HANDLED;
331 }
332 printk(CDU535_MESSAGE_NAME
333 ": Got an interrupt but nothing was waiting\n");
334 return IRQ_NONE;
335}
336
337
338/*
339 * Wait a little while.
340 */
341static inline void
342sony_sleep(void)
343{
344 if (sony535_irq_used <= 0) { /* poll */
345 yield();
346 } else { /* Interrupt driven */
347 DEFINE_WAIT(wait);
348
349 spin_lock_irq(&sonycd535_lock);
350 enable_interrupts();
351 prepare_to_wait(&cdu535_irq_wait, &wait, TASK_INTERRUPTIBLE);
352 spin_unlock_irq(&sonycd535_lock);
353 schedule();
354 finish_wait(&cdu535_irq_wait, &wait);
355 }
356}
357
358/*------------------start of SONY CDU535 very specific ---------------------*/
359
360/****************************************************************************
361 * void select_unit( int unit_no )
362 *
363 * Select the specified unit (0-3) so that subsequent commands reference it
364 ****************************************************************************/
365static void
366select_unit(int unit_no)
367{
368 unsigned int select_mask = ~(1 << unit_no);
369 outb(select_mask, select_unit_reg);
370}
371
372/***************************************************************************
373 * int read_result_reg( Byte *data_ptr )
374 *
375 * Read a result byte from the Sony CDU controller, store in location pointed
376 * to by data_ptr. Return zero on success, TIME_OUT if we did not receive
377 * data.
378 ***************************************************************************/
379static int
380read_result_reg(Byte *data_ptr)
381{
382 unsigned long snap;
383 int read_status;
384
385 snap = jiffies;
386 while (jiffies-snap < SONY_JIFFIES_TIMEOUT) {
387 read_status = inb(read_status_reg);
388 if ((read_status & SONY535_RESULT_NOT_READY_BIT) == 0) {
389#if DEBUG > 1
390 printk(CDU535_MESSAGE_NAME
391 ": read_result_reg(): readStatReg = 0x%x\n", read_status);
392#endif
393 *data_ptr = inb(result_reg);
394 return 0;
395 } else {
396 sony_sleep();
397 }
398 }
399 printk(CDU535_MESSAGE_NAME " read_result_reg: TIME OUT!\n");
400 return TIME_OUT;
401}
402
403/****************************************************************************
404 * int read_exec_status( Byte status[2] )
405 *
406 * Read the execution status of the last command and put into status.
407 * Handles reading second status word if available. Returns 0 on success,
408 * TIME_OUT on failure.
409 ****************************************************************************/
410static int
411read_exec_status(Byte status[2])
412{
413 status[1] = 0;
414 if (read_result_reg(&(status[0])) != 0)
415 return TIME_OUT;
416 if ((status[0] & 0x80) != 0) { /* byte two follows */
417 if (read_result_reg(&(status[1])) != 0)
418 return TIME_OUT;
419 }
420#if DEBUG > 1
421 printk(CDU535_MESSAGE_NAME ": read_exec_status: read 0x%x 0x%x\n",
422 status[0], status[1]);
423#endif
424 return 0;
425}
426
427/****************************************************************************
428 * int check_drive_status( void )
429 *
430 * Check the current drive status. Using this before executing a command
431 * takes care of the problem of unsolicited drive status-2 messages.
432 * Add a check of the audio status if we think the disk is playing.
433 ****************************************************************************/
434static int
435check_drive_status(void)
436{
437 Byte status, e_status[2];
438 int CDD, ATN;
439 Byte cmd;
440
441 select_unit(0);
442 if (sony_audio_status == CDROM_AUDIO_PLAY) { /* check status */
443 outb(SONY535_REQUEST_AUDIO_STATUS, command_reg);
444 if (read_result_reg(&status) == 0) {
445 switch (status) {
446 case 0x0:
447 break; /* play in progress */
448 case 0x1:
449 break; /* paused */
450 case 0x3: /* audio play completed */
451 case 0x5: /* play not requested */
452 sony_audio_status = CDROM_AUDIO_COMPLETED;
453 read_subcode();
454 break;
455 case 0x4: /* error during play */
456 sony_audio_status = CDROM_AUDIO_ERROR;
457 break;
458 }
459 }
460 }
461 /* now check drive status */
462 outb(SONY535_REQUEST_DRIVE_STATUS_2, command_reg);
463 if (read_result_reg(&status) != 0)
464 return TIME_OUT;
465
466#if DEBUG > 1
467 printk(CDU535_MESSAGE_NAME ": check_drive_status() got 0x%x\n", status);
468#endif
469
470 if (status == 0)
471 return 0;
472
473 ATN = status & 0xf;
474 CDD = (status >> 4) & 0xf;
475
476 switch (ATN) {
477 case 0x0:
478 break; /* go on to CDD stuff */
479 case SONY535_ATN_BUSY:
480 if (initialized)
481 printk(CDU535_MESSAGE_NAME " error: drive busy\n");
482 return CD_BUSY;
483 case SONY535_ATN_EJECT_IN_PROGRESS:
484 printk(CDU535_MESSAGE_NAME " error: eject in progress\n");
485 sony_audio_status = CDROM_AUDIO_INVALID;
486 return CD_BUSY;
487 case SONY535_ATN_RESET_OCCURRED:
488 case SONY535_ATN_DISC_CHANGED:
489 case SONY535_ATN_RESET_AND_DISC_CHANGED:
490#if DEBUG > 0
491 printk(CDU535_MESSAGE_NAME " notice: reset occurred or disc changed\n");
492#endif
493 sony_disc_changed = 1;
494 sony_toc_read = 0;
495 sony_audio_status = CDROM_AUDIO_NO_STATUS;
496 sony_first_block = -1;
497 sony_last_block = -1;
498 if (initialized) {
499 cmd = SONY535_SPIN_UP;
500 do_sony_cmd(&cmd, 1, e_status, NULL, 0, 0);
501 sony_get_toc();
502 }
503 return 0;
504 default:
505 printk(CDU535_MESSAGE_NAME " error: drive busy (ATN=0x%x)\n", ATN);
506 return CD_BUSY;
507 }
508 switch (CDD) { /* the 531 docs are not helpful in decoding this */
509 case 0x0: /* just use the values from the DOS driver */
510 case 0x2:
511 case 0xa:
512 break; /* no error */
513 case 0xc:
514 printk(CDU535_MESSAGE_NAME
515 ": check_drive_status(): CDD = 0xc! Not properly handled!\n");
516 return CD_BUSY; /* ? */
517 default:
518 return CD_BUSY;
519 }
520 return 0;
521} /* check_drive_status() */
522
523/*****************************************************************************
524 * int do_sony_cmd( Byte *cmd, int n_cmd, Byte status[2],
525 * Byte *response, int n_response, int ignore_status_bit7 )
526 *
527 * Generic routine for executing commands. The command and its parameters
528 * should be placed in the cmd[] array, number of bytes in the command is
529 * stored in nCmd. The response from the command will be stored in the
530 * response array. The number of bytes you expect back (excluding status)
531 * should be passed in n_response. Finally, some
532 * commands set bit 7 of the return status even when there is no second
533 * status byte, on these commands set ignoreStatusBit7 TRUE.
534 * If the command was sent and data received back, then we return 0,
535 * else we return TIME_OUT. You still have to check the status yourself.
536 * You should call check_drive_status() before calling this routine
537 * so that you do not lose notifications of disk changes, etc.
538 ****************************************************************************/
539static int
540do_sony_cmd(Byte * cmd, int n_cmd, Byte status[2],
541 Byte * response, int n_response, int ignore_status_bit7)
542{
543 int i;
544
545 /* write out the command */
546 for (i = 0; i < n_cmd; i++)
547 outb(cmd[i], command_reg);
548
549 /* read back the status */
550 if (read_result_reg(status) != 0)
551 return TIME_OUT;
552 if (!ignore_status_bit7 && ((status[0] & 0x80) != 0)) {
553 /* get second status byte */
554 if (read_result_reg(status + 1) != 0)
555 return TIME_OUT;
556 } else {
557 status[1] = 0;
558 }
559#if DEBUG > 2
560 printk(CDU535_MESSAGE_NAME ": do_sony_cmd %x: %x %x\n",
561 *cmd, status[0], status[1]);
562#endif
563
564 /* do not know about when I should read set of data and when not to */
565 if ((status[0] & ((ignore_status_bit7 ? 0x7f : 0xff) & 0x8f)) != 0)
566 return 0;
567
568 /* else, read in rest of data */
569 for (i = 0; 0 < n_response; n_response--, i++)
570 if (read_result_reg(response + i) != 0)
571 return TIME_OUT;
572 return 0;
573} /* do_sony_cmd() */
574
575/**************************************************************************
576 * int set_drive_mode( int mode, Byte status[2] )
577 *
578 * Set the drive mode to the specified value (mode=0 is audio, mode=e0
579 * is mode-1 CDROM
580 **************************************************************************/
581static int
582set_drive_mode(int mode, Byte status[2])
583{
584 Byte cmd_buff[2];
585 Byte ret_buff[1];
586
587 cmd_buff[0] = SONY535_SET_DRIVE_MODE;
588 cmd_buff[1] = mode;
589 return do_sony_cmd(cmd_buff, 2, status, ret_buff, 1, 1);
590}
591
592/***************************************************************************
593 * int seek_and_read_N_blocks( Byte params[], int n_blocks, Byte status[2],
594 * Byte *data_buff, int buff_size )
595 *
596 * Read n_blocks of data from the CDROM starting at position params[0:2],
597 * number of blocks in stored in params[3:5] -- both these are already
598 * int bcd format.
599 * Transfer the data into the buffer pointed at by data_buff. buff_size
600 * gives the number of bytes available in the buffer.
601 * The routine returns number of bytes read in if successful, otherwise
602 * it returns one of the standard error returns.
603 ***************************************************************************/
604static int
605seek_and_read_N_blocks(Byte params[], int n_blocks, Byte status[2],
606 Byte **buff, int buf_size)
607{
608 Byte cmd_buff[7];
609 int i;
610 int read_status;
611 unsigned long snap;
612 Byte *data_buff;
613 int sector_count = 0;
614
615 if (buf_size < CDU535_BLOCK_SIZE * n_blocks)
616 return NO_ROOM;
617
618 set_drive_mode(SONY535_CDROM_DRIVE_MODE, status);
619
620 /* send command to read the data */
621 cmd_buff[0] = SONY535_SEEK_AND_READ_N_BLOCKS_1;
622 for (i = 0; i < 6; i++)
623 cmd_buff[i + 1] = params[i];
624 for (i = 0; i < 7; i++)
625 outb(cmd_buff[i], command_reg);
626
627 /* read back the data one block at a time */
628 while (0 < n_blocks--) {
629 /* wait for data to be ready */
630 int data_valid = 0;
631 snap = jiffies;
632 while (jiffies-snap < SONY_JIFFIES_TIMEOUT) {
633 read_status = inb(read_status_reg);
634 if ((read_status & SONY535_RESULT_NOT_READY_BIT) == 0) {
635 read_exec_status(status);
636 return BAD_STATUS;
637 }
638 if ((read_status & SONY535_DATA_NOT_READY_BIT) == 0) {
639 /* data is ready, read it */
640 data_buff = buff[sector_count++];
641 for (i = 0; i < CDU535_BLOCK_SIZE; i++)
642 *data_buff++ = inb(data_reg); /* unrolling this loop does not seem to help */
643 data_valid = 1;
644 break; /* exit the timeout loop */
645 }
646 sony_sleep(); /* data not ready, sleep a while */
647 }
648 if (!data_valid)
649 return TIME_OUT; /* if we reach this stage */
650 }
651
652 /* read all the data, now read the status */
653 if ((i = read_exec_status(status)) != 0)
654 return i;
655 return CDU535_BLOCK_SIZE * sector_count;
656} /* seek_and_read_N_blocks() */
657
658/****************************************************************************
659 * int request_toc_data( Byte status[2], struct s535_sony_toc *toc )
660 *
661 * Read in the table of contents data. Converts all the bcd data
662 * into integers in the toc structure.
663 ****************************************************************************/
664static int
665request_toc_data(Byte status[2], struct s535_sony_toc *toc)
666{
667 int to_status;
668 int i, j, n_tracks, track_no;
669 int first_track_num, last_track_num;
670 Byte cmd_no = 0xb2;
671 Byte track_address_buffer[5];
672
673 /* read the fixed portion of the table of contents */
674 if ((to_status = do_sony_cmd(&cmd_no, 1, status, (Byte *) toc, 15, 1)) != 0)
675 return to_status;
676
677 /* convert the data into integers so we can use them */
678 first_track_num = bcd_to_int(toc->first_track_num);
679 last_track_num = bcd_to_int(toc->last_track_num);
680 n_tracks = last_track_num - first_track_num + 1;
681
682 /* read each of the track address descriptors */
683 for (i = 0; i < n_tracks; i++) {
684 /* read the descriptor into a temporary buffer */
685 for (j = 0; j < 5; j++) {
686 if (read_result_reg(track_address_buffer + j) != 0)
687 return TIME_OUT;
688 if (j == 1) /* need to convert from bcd */
689 track_no = bcd_to_int(track_address_buffer[j]);
690 }
691 /* copy the descriptor to proper location - sonycd.c just fills */
692 memcpy(toc->tracks + i, track_address_buffer, 5);
693 }
694 return 0;
695} /* request_toc_data() */
696
697/***************************************************************************
698 * int spin_up_drive( Byte status[2] )
699 *
700 * Spin up the drive (unless it is already spinning).
701 ***************************************************************************/
702static int
703spin_up_drive(Byte status[2])
704{
705 Byte cmd;
706
707 /* first see if the drive is already spinning */
708 cmd = SONY535_REQUEST_DRIVE_STATUS_1;
709 if (do_sony_cmd(&cmd, 1, status, NULL, 0, 0) != 0)
710 return TIME_OUT;
711 if ((status[0] & SONY535_STATUS1_NOT_SPINNING) == 0)
712 return 0; /* it's already spinning */
713
714 /* otherwise, give the spin-up command */
715 cmd = SONY535_SPIN_UP;
716 return do_sony_cmd(&cmd, 1, status, NULL, 0, 0);
717}
718
719/*--------------------end of SONY CDU535 very specific ---------------------*/
720
721/* Convert from an integer 0-99 to BCD */
722static inline unsigned int
723int_to_bcd(unsigned int val)
724{
725 int retval;
726
727 retval = (val / 10) << 4;
728 retval = retval | val % 10;
729 return retval;
730}
731
732
733/* Convert from BCD to an integer from 0-99 */
734static unsigned int
735bcd_to_int(unsigned int bcd)
736{
737 return (((bcd >> 4) & 0x0f) * 10) + (bcd & 0x0f);
738}
739
740
741/*
742 * Convert a logical sector value (like the OS would want to use for
743 * a block device) to an MSF format.
744 */
745static void
746log_to_msf(unsigned int log, Byte *msf)
747{
748 log = log + LOG_START_OFFSET;
749 msf[0] = int_to_bcd(log / 4500);
750 log = log % 4500;
751 msf[1] = int_to_bcd(log / 75);
752 msf[2] = int_to_bcd(log % 75);
753}
754
755
756/*
757 * Convert an MSF format to a logical sector.
758 */
759static unsigned int
760msf_to_log(Byte *msf)
761{
762 unsigned int log;
763
764
765 log = bcd_to_int(msf[2]);
766 log += bcd_to_int(msf[1]) * 75;
767 log += bcd_to_int(msf[0]) * 4500;
768 log = log - LOG_START_OFFSET;
769
770 return log;
771}
772
773
774/*
775 * Take in integer size value and put it into a buffer like
776 * the drive would want to see a number-of-sector value.
777 */
778static void
779size_to_buf(unsigned int size, Byte *buf)
780{
781 buf[0] = size / 65536;
782 size = size % 65536;
783 buf[1] = size / 256;
784 buf[2] = size % 256;
785}
786
787
788/*
789 * The OS calls this to perform a read or write operation to the drive.
790 * Write obviously fail. Reads to a read ahead of sony_buffer_size
791 * bytes to help speed operations. This especially helps since the OS
792 * may use 1024 byte blocks and the drive uses 2048 byte blocks. Since most
793 * data access on a CD is done sequentially, this saves a lot of operations.
794 */
795static void
796do_cdu535_request(request_queue_t * q)
797{
798 struct request *req;
799 unsigned int read_size;
800 int block;
801 int nsect;
802 int copyoff;
803 int spin_up_retry;
804 Byte params[10];
805 Byte status[2];
806 Byte cmd[2];
807
808 while (1) {
809 req = elv_next_request(q);
810 if (!req)
811 return;
812
813 block = req->sector;
814 nsect = req->nr_sectors;
815 if (!blk_fs_request(req)) {
816 end_request(req, 0);
817 continue;
818 }
819 if (rq_data_dir(req) == WRITE) {
820 end_request(req, 0);
821 continue;
822 }
823 /*
824 * If the block address is invalid or the request goes beyond
825 * the end of the media, return an error.
826 */
827 if (sony_toc->lead_out_start_lba <= (block/4)) {
828 end_request(req, 0);
829 return;
830 }
831 if (sony_toc->lead_out_start_lba <= ((block + nsect) / 4)) {
832 end_request(req, 0);
833 return;
834 }
835 while (0 < nsect) {
836 /*
837 * If the requested sector is not currently in
838 * the read-ahead buffer, it must be read in.
839 */
840 if ((block < sony_first_block) || (sony_last_block < block)) {
841 sony_first_block = (block / 4) * 4;
842 log_to_msf(block / 4, params);
843
844 /*
845 * If the full read-ahead would go beyond the end of the media, trim
846 * it back to read just till the end of the media.
847 */
848 if (sony_toc->lead_out_start_lba <= ((block / 4) + sony_buffer_sectors)) {
849 sony_last_block = (sony_toc->lead_out_start_lba * 4) - 1;
850 read_size = sony_toc->lead_out_start_lba - (block / 4);
851 } else {
852 sony_last_block = sony_first_block + (sony_buffer_sectors * 4) - 1;
853 read_size = sony_buffer_sectors;
854 }
855 size_to_buf(read_size, &params[3]);
856
857 /*
858 * Read the data. If the drive was not spinning,
859 * spin it up and try some more.
860 */
861 for (spin_up_retry=0 ;; ++spin_up_retry) {
862 /* This loop has been modified to support the Sony
863 * CDU-510/515 series, thanks to Claudio Porfiri
864 * <C.Porfiri@nisms.tei.ericsson.se>.
865 */
866 /*
867 * This part is to deal with very slow hardware. We
868 * try at most MAX_SPINUP_RETRY times to read the same
869 * block. A check for seek_and_read_N_blocks' result is
870 * performed; if the result is wrong, the CDROM's engine
871 * is restarted and the operation is tried again.
872 */
873 /*
874 * 1995-06-01: The system got problems when downloading
875 * from Slackware CDROM, the problem seems to be:
876 * seek_and_read_N_blocks returns BAD_STATUS and we
877 * should wait for a while before retrying, so a new
878 * part was added to discriminate the return value from
879 * seek_and_read_N_blocks for the various cases.
880 */
881 int readStatus = seek_and_read_N_blocks(params, read_size,
882 status, sony_buffer, (read_size * CDU535_BLOCK_SIZE));
883 if (0 <= readStatus) /* Good data; common case, placed first */
884 break;
885 if (readStatus == NO_ROOM || spin_up_retry == MAX_SPINUP_RETRY) {
886 /* give up */
887 if (readStatus == NO_ROOM)
888 printk(CDU535_MESSAGE_NAME " No room to read from CD\n");
889 else
890 printk(CDU535_MESSAGE_NAME " Read error: 0x%.2x\n",
891 status[0]);
892 sony_first_block = -1;
893 sony_last_block = -1;
894 end_request(req, 0);
895 return;
896 }
897 if (readStatus == BAD_STATUS) {
898 /* Sleep for a while, then retry */
899 set_current_state(TASK_INTERRUPTIBLE);
900 spin_unlock_irq(&sonycd535_lock);
901 schedule_timeout(RETRY_FOR_BAD_STATUS*HZ/10);
902 spin_lock_irq(&sonycd535_lock);
903 }
904#if DEBUG > 0
905 printk(CDU535_MESSAGE_NAME
906 " debug: calling spin up when reading data!\n");
907#endif
908 cmd[0] = SONY535_SPIN_UP;
909 do_sony_cmd(cmd, 1, status, NULL, 0, 0);
910 }
911 }
912 /*
913 * The data is in memory now, copy it to the buffer and advance to the
914 * next block to read.
915 */
916 copyoff = block - sony_first_block;
917 memcpy(req->buffer,
918 sony_buffer[copyoff / 4] + 512 * (copyoff % 4), 512);
919
920 block += 1;
921 nsect -= 1;
922 req->buffer += 512;
923 }
924
925 end_request(req, 1);
926 }
927}
928
929/*
930 * Read the table of contents from the drive and set sony_toc_read if
931 * successful.
932 */
933static void
934sony_get_toc(void)
935{
936 Byte status[2];
937 if (!sony_toc_read) {
938 /* do not call check_drive_status() from here since it can call this routine */
939 if (request_toc_data(status, sony_toc) < 0)
940 return;
941 sony_toc->lead_out_start_lba = msf_to_log(sony_toc->lead_out_start_msf);
942 sony_toc_read = 1;
943 }
944}
945
946
947/*
948 * Search for a specific track in the table of contents. track is
949 * passed in bcd format
950 */
951static int
952find_track(int track)
953{
954 int i;
955 int num_tracks;
956
957
958 num_tracks = bcd_to_int(sony_toc->last_track_num) -
959 bcd_to_int(sony_toc->first_track_num) + 1;
960 for (i = 0; i < num_tracks; i++) {
961 if (sony_toc->tracks[i].track == track) {
962 return i;
963 }
964 }
965
966 return -1;
967}
968
969/*
970 * Read the subcode and put it int last_sony_subcode for future use.
971 */
972static int
973read_subcode(void)
974{
975 Byte cmd = SONY535_REQUEST_SUB_Q_DATA;
976 Byte status[2];
977 int dsc_status;
978
979 if (check_drive_status() != 0)
980 return -EIO;
981
982 if ((dsc_status = do_sony_cmd(&cmd, 1, status, (Byte *) last_sony_subcode,
983 sizeof(struct s535_sony_subcode), 1)) != 0) {
984 printk(CDU535_MESSAGE_NAME " error 0x%.2x, %d (read_subcode)\n",
985 status[0], dsc_status);
986 return -EIO;
987 }
988 return 0;
989}
990
991
992/*
993 * Get the subchannel info like the CDROMSUBCHNL command wants to see it. If
994 * the drive is playing, the subchannel needs to be read (since it would be
995 * changing). If the drive is paused or completed, the subcode information has
996 * already been stored, just use that. The ioctl call wants things in decimal
997 * (not BCD), so all the conversions are done.
998 */
999static int
1000sony_get_subchnl_info(void __user *arg)
1001{
1002 struct cdrom_subchnl schi;
1003
1004 /* Get attention stuff */
1005 if (check_drive_status() != 0)
1006 return -EIO;
1007
1008 sony_get_toc();
1009 if (!sony_toc_read) {
1010 return -EIO;
1011 }
1012 if (copy_from_user(&schi, arg, sizeof schi))
1013 return -EFAULT;
1014
1015 switch (sony_audio_status) {
1016 case CDROM_AUDIO_PLAY:
1017 if (read_subcode() < 0) {
1018 return -EIO;
1019 }
1020 break;
1021
1022 case CDROM_AUDIO_PAUSED:
1023 case CDROM_AUDIO_COMPLETED:
1024 break;
1025
1026 case CDROM_AUDIO_NO_STATUS:
1027 schi.cdsc_audiostatus = sony_audio_status;
1028 if (copy_to_user(arg, &schi, sizeof schi))
1029 return -EFAULT;
1030 return 0;
1031 break;
1032
1033 case CDROM_AUDIO_INVALID:
1034 case CDROM_AUDIO_ERROR:
1035 default:
1036 return -EIO;
1037 }
1038
1039 schi.cdsc_audiostatus = sony_audio_status;
1040 schi.cdsc_adr = last_sony_subcode->address;
1041 schi.cdsc_ctrl = last_sony_subcode->control;
1042 schi.cdsc_trk = bcd_to_int(last_sony_subcode->track_num);
1043 schi.cdsc_ind = bcd_to_int(last_sony_subcode->index_num);
1044 if (schi.cdsc_format == CDROM_MSF) {
1045 schi.cdsc_absaddr.msf.minute = bcd_to_int(last_sony_subcode->abs_msf[0]);
1046 schi.cdsc_absaddr.msf.second = bcd_to_int(last_sony_subcode->abs_msf[1]);
1047 schi.cdsc_absaddr.msf.frame = bcd_to_int(last_sony_subcode->abs_msf[2]);
1048
1049 schi.cdsc_reladdr.msf.minute = bcd_to_int(last_sony_subcode->rel_msf[0]);
1050 schi.cdsc_reladdr.msf.second = bcd_to_int(last_sony_subcode->rel_msf[1]);
1051 schi.cdsc_reladdr.msf.frame = bcd_to_int(last_sony_subcode->rel_msf[2]);
1052 } else if (schi.cdsc_format == CDROM_LBA) {
1053 schi.cdsc_absaddr.lba = msf_to_log(last_sony_subcode->abs_msf);
1054 schi.cdsc_reladdr.lba = msf_to_log(last_sony_subcode->rel_msf);
1055 }
1056 return copy_to_user(arg, &schi, sizeof schi) ? -EFAULT : 0;
1057}
1058
1059
1060/*
1061 * The big ugly ioctl handler.
1062 */
1063static int
1064cdu_ioctl(struct inode *inode,
1065 struct file *file,
1066 unsigned int cmd,
1067 unsigned long arg)
1068{
1069 Byte status[2];
1070 Byte cmd_buff[10], params[10];
1071 int i;
1072 int dsc_status;
1073 void __user *argp = (void __user *)arg;
1074
1075 if (check_drive_status() != 0)
1076 return -EIO;
1077
1078 switch (cmd) {
1079 case CDROMSTART: /* Spin up the drive */
1080 if (spin_up_drive(status) < 0) {
1081 printk(CDU535_MESSAGE_NAME " error 0x%.2x (CDROMSTART)\n",
1082 status[0]);
1083 return -EIO;
1084 }
1085 return 0;
1086 break;
1087
1088 case CDROMSTOP: /* Spin down the drive */
1089 cmd_buff[0] = SONY535_HOLD;
1090 do_sony_cmd(cmd_buff, 1, status, NULL, 0, 0);
1091
1092 /*
1093 * Spin the drive down, ignoring the error if the disk was
1094 * already not spinning.
1095 */
1096 sony_audio_status = CDROM_AUDIO_NO_STATUS;
1097 cmd_buff[0] = SONY535_SPIN_DOWN;
1098 dsc_status = do_sony_cmd(cmd_buff, 1, status, NULL, 0, 0);
1099 if (((dsc_status < 0) && (dsc_status != BAD_STATUS)) ||
1100 ((status[0] & ~(SONY535_STATUS1_NOT_SPINNING)) != 0)) {
1101 printk(CDU535_MESSAGE_NAME " error 0x%.2x (CDROMSTOP)\n",
1102 status[0]);
1103 return -EIO;
1104 }
1105 return 0;
1106 break;
1107
1108 case CDROMPAUSE: /* Pause the drive */
1109 cmd_buff[0] = SONY535_HOLD; /* CDU-31 driver uses AUDIO_STOP, not pause */
1110 if (do_sony_cmd(cmd_buff, 1, status, NULL, 0, 0) != 0) {
1111 printk(CDU535_MESSAGE_NAME " error 0x%.2x (CDROMPAUSE)\n",
1112 status[0]);
1113 return -EIO;
1114 }
1115 /* Get the current position and save it for resuming */
1116 if (read_subcode() < 0) {
1117 return -EIO;
1118 }
1119 cur_pos_msf[0] = last_sony_subcode->abs_msf[0];
1120 cur_pos_msf[1] = last_sony_subcode->abs_msf[1];
1121 cur_pos_msf[2] = last_sony_subcode->abs_msf[2];
1122 sony_audio_status = CDROM_AUDIO_PAUSED;
1123 return 0;
1124 break;
1125
1126 case CDROMRESUME: /* Start the drive after being paused */
1127 set_drive_mode(SONY535_AUDIO_DRIVE_MODE, status);
1128
1129 if (sony_audio_status != CDROM_AUDIO_PAUSED) {
1130 return -EINVAL;
1131 }
1132 spin_up_drive(status);
1133
1134 /* Start the drive at the saved position. */
1135 cmd_buff[0] = SONY535_PLAY_AUDIO;
1136 cmd_buff[1] = 0; /* play back starting at this address */
1137 cmd_buff[2] = cur_pos_msf[0];
1138 cmd_buff[3] = cur_pos_msf[1];
1139 cmd_buff[4] = cur_pos_msf[2];
1140 cmd_buff[5] = SONY535_PLAY_AUDIO;
1141 cmd_buff[6] = 2; /* set ending address */
1142 cmd_buff[7] = final_pos_msf[0];
1143 cmd_buff[8] = final_pos_msf[1];
1144 cmd_buff[9] = final_pos_msf[2];
1145 if ((do_sony_cmd(cmd_buff, 5, status, NULL, 0, 0) != 0) ||
1146 (do_sony_cmd(cmd_buff + 5, 5, status, NULL, 0, 0) != 0)) {
1147 printk(CDU535_MESSAGE_NAME " error 0x%.2x (CDROMRESUME)\n",
1148 status[0]);
1149 return -EIO;
1150 }
1151 sony_audio_status = CDROM_AUDIO_PLAY;
1152 return 0;
1153 break;
1154
1155 case CDROMPLAYMSF: /* Play starting at the given MSF address. */
1156 if (copy_from_user(params, argp, 6))
1157 return -EFAULT;
1158 spin_up_drive(status);
1159 set_drive_mode(SONY535_AUDIO_DRIVE_MODE, status);
1160
1161 /* The parameters are given in int, must be converted */
1162 for (i = 0; i < 3; i++) {
1163 cmd_buff[2 + i] = int_to_bcd(params[i]);
1164 cmd_buff[7 + i] = int_to_bcd(params[i + 3]);
1165 }
1166 cmd_buff[0] = SONY535_PLAY_AUDIO;
1167 cmd_buff[1] = 0; /* play back starting at this address */
1168 /* cmd_buff[2-4] are filled in for loop above */
1169 cmd_buff[5] = SONY535_PLAY_AUDIO;
1170 cmd_buff[6] = 2; /* set ending address */
1171 /* cmd_buff[7-9] are filled in for loop above */
1172 if ((do_sony_cmd(cmd_buff, 5, status, NULL, 0, 0) != 0) ||
1173 (do_sony_cmd(cmd_buff + 5, 5, status, NULL, 0, 0) != 0)) {
1174 printk(CDU535_MESSAGE_NAME " error 0x%.2x (CDROMPLAYMSF)\n",
1175 status[0]);
1176 return -EIO;
1177 }
1178 /* Save the final position for pauses and resumes */
1179 final_pos_msf[0] = cmd_buff[7];
1180 final_pos_msf[1] = cmd_buff[8];
1181 final_pos_msf[2] = cmd_buff[9];
1182 sony_audio_status = CDROM_AUDIO_PLAY;
1183 return 0;
1184 break;
1185
1186 case CDROMREADTOCHDR: /* Read the table of contents header */
1187 {
1188 struct cdrom_tochdr __user *hdr = argp;
1189 struct cdrom_tochdr loc_hdr;
1190
1191 sony_get_toc();
1192 if (!sony_toc_read)
1193 return -EIO;
1194 loc_hdr.cdth_trk0 = bcd_to_int(sony_toc->first_track_num);
1195 loc_hdr.cdth_trk1 = bcd_to_int(sony_toc->last_track_num);
1196 if (copy_to_user(hdr, &loc_hdr, sizeof *hdr))
1197 return -EFAULT;
1198 }
1199 return 0;
1200 break;
1201
1202 case CDROMREADTOCENTRY: /* Read a given table of contents entry */
1203 {
1204 struct cdrom_tocentry __user *entry = argp;
1205 struct cdrom_tocentry loc_entry;
1206 int track_idx;
1207 Byte *msf_val = NULL;
1208
1209 sony_get_toc();
1210 if (!sony_toc_read) {
1211 return -EIO;
1212 }
1213
1214 if (copy_from_user(&loc_entry, entry, sizeof loc_entry))
1215 return -EFAULT;
1216
1217 /* Lead out is handled separately since it is special. */
1218 if (loc_entry.cdte_track == CDROM_LEADOUT) {
1219 loc_entry.cdte_adr = 0 /*sony_toc->address2 */ ;
1220 loc_entry.cdte_ctrl = sony_toc->control2;
1221 msf_val = sony_toc->lead_out_start_msf;
1222 } else {
1223 track_idx = find_track(int_to_bcd(loc_entry.cdte_track));
1224 if (track_idx < 0)
1225 return -EINVAL;
1226 loc_entry.cdte_adr = 0 /*sony_toc->tracks[track_idx].address */ ;
1227 loc_entry.cdte_ctrl = sony_toc->tracks[track_idx].control;
1228 msf_val = sony_toc->tracks[track_idx].track_start_msf;
1229 }
1230
1231 /* Logical buffer address or MSF format requested? */
1232 if (loc_entry.cdte_format == CDROM_LBA) {
1233 loc_entry.cdte_addr.lba = msf_to_log(msf_val);
1234 } else if (loc_entry.cdte_format == CDROM_MSF) {
1235 loc_entry.cdte_addr.msf.minute = bcd_to_int(*msf_val);
1236 loc_entry.cdte_addr.msf.second = bcd_to_int(*(msf_val + 1));
1237 loc_entry.cdte_addr.msf.frame = bcd_to_int(*(msf_val + 2));
1238 }
1239 if (copy_to_user(entry, &loc_entry, sizeof *entry))
1240 return -EFAULT;
1241 }
1242 return 0;
1243 break;
1244
1245 case CDROMPLAYTRKIND: /* Play a track. This currently ignores index. */
1246 {
1247 struct cdrom_ti ti;
1248 int track_idx;
1249
1250 sony_get_toc();
1251 if (!sony_toc_read)
1252 return -EIO;
1253
1254 if (copy_from_user(&ti, argp, sizeof ti))
1255 return -EFAULT;
1256 if ((ti.cdti_trk0 < sony_toc->first_track_num)
1257 || (sony_toc->last_track_num < ti.cdti_trk0)
1258 || (ti.cdti_trk1 < ti.cdti_trk0)) {
1259 return -EINVAL;
1260 }
1261 track_idx = find_track(int_to_bcd(ti.cdti_trk0));
1262 if (track_idx < 0)
1263 return -EINVAL;
1264 params[1] = sony_toc->tracks[track_idx].track_start_msf[0];
1265 params[2] = sony_toc->tracks[track_idx].track_start_msf[1];
1266 params[3] = sony_toc->tracks[track_idx].track_start_msf[2];
1267 /*
1268 * If we want to stop after the last track, use the lead-out
1269 * MSF to do that.
1270 */
1271 if (bcd_to_int(sony_toc->last_track_num) <= ti.cdti_trk1) {
1272 log_to_msf(msf_to_log(sony_toc->lead_out_start_msf) - 1,
1273 &(params[4]));
1274 } else {
1275 track_idx = find_track(int_to_bcd(ti.cdti_trk1 + 1));
1276 if (track_idx < 0)
1277 return -EINVAL;
1278 log_to_msf(msf_to_log(sony_toc->tracks[track_idx].track_start_msf) - 1,
1279 &(params[4]));
1280 }
1281 params[0] = 0x03;
1282
1283 spin_up_drive(status);
1284
1285 set_drive_mode(SONY535_AUDIO_DRIVE_MODE, status);
1286
1287 /* Start the drive at the saved position. */
1288 cmd_buff[0] = SONY535_PLAY_AUDIO;
1289 cmd_buff[1] = 0; /* play back starting at this address */
1290 cmd_buff[2] = params[1];
1291 cmd_buff[3] = params[2];
1292 cmd_buff[4] = params[3];
1293 cmd_buff[5] = SONY535_PLAY_AUDIO;
1294 cmd_buff[6] = 2; /* set ending address */
1295 cmd_buff[7] = params[4];
1296 cmd_buff[8] = params[5];
1297 cmd_buff[9] = params[6];
1298 if ((do_sony_cmd(cmd_buff, 5, status, NULL, 0, 0) != 0) ||
1299 (do_sony_cmd(cmd_buff + 5, 5, status, NULL, 0, 0) != 0)) {
1300 printk(CDU535_MESSAGE_NAME " error 0x%.2x (CDROMPLAYTRKIND)\n",
1301 status[0]);
1302 printk("... Params: %x %x %x %x %x %x %x\n",
1303 params[0], params[1], params[2],
1304 params[3], params[4], params[5], params[6]);
1305 return -EIO;
1306 }
1307 /* Save the final position for pauses and resumes */
1308 final_pos_msf[0] = params[4];
1309 final_pos_msf[1] = params[5];
1310 final_pos_msf[2] = params[6];
1311 sony_audio_status = CDROM_AUDIO_PLAY;
1312 return 0;
1313 }
1314
1315 case CDROMSUBCHNL: /* Get subchannel info */
1316 return sony_get_subchnl_info(argp);
1317
1318 case CDROMVOLCTRL: /* Volume control. What volume does this change, anyway? */
1319 {
1320 struct cdrom_volctrl volctrl;
1321
1322 if (copy_from_user(&volctrl, argp, sizeof volctrl))
1323 return -EFAULT;
1324 cmd_buff[0] = SONY535_SET_VOLUME;
1325 cmd_buff[1] = volctrl.channel0;
1326 cmd_buff[2] = volctrl.channel1;
1327 if (do_sony_cmd(cmd_buff, 3, status, NULL, 0, 0) != 0) {
1328 printk(CDU535_MESSAGE_NAME " error 0x%.2x (CDROMVOLCTRL)\n",
1329 status[0]);
1330 return -EIO;
1331 }
1332 }
1333 return 0;
1334
1335 case CDROMEJECT: /* Eject the drive */
1336 cmd_buff[0] = SONY535_STOP;
1337 do_sony_cmd(cmd_buff, 1, status, NULL, 0, 0);
1338 cmd_buff[0] = SONY535_SPIN_DOWN;
1339 do_sony_cmd(cmd_buff, 1, status, NULL, 0, 0);
1340
1341 sony_audio_status = CDROM_AUDIO_INVALID;
1342 cmd_buff[0] = SONY535_EJECT_CADDY;
1343 if (do_sony_cmd(cmd_buff, 1, status, NULL, 0, 0) != 0) {
1344 printk(CDU535_MESSAGE_NAME " error 0x%.2x (CDROMEJECT)\n",
1345 status[0]);
1346 return -EIO;
1347 }
1348 return 0;
1349 break;
1350
1351 default:
1352 return -EINVAL;
1353 }
1354}
1355
1356
1357/*
1358 * Open the drive for operations. Spin the drive up and read the table of
1359 * contents if these have not already been done.
1360 */
1361static int
1362cdu_open(struct inode *inode,
1363 struct file *filp)
1364{
1365 Byte status[2], cmd_buff[2];
1366
1367 if (sony_inuse)
1368 return -EBUSY;
1369 if (check_drive_status() != 0)
1370 return -EIO;
1371 sony_inuse = 1;
1372
1373 if (spin_up_drive(status) != 0) {
1374 printk(CDU535_MESSAGE_NAME " error 0x%.2x (cdu_open, spin up)\n",
1375 status[0]);
1376 sony_inuse = 0;
1377 return -EIO;
1378 }
1379 sony_get_toc();
1380 if (!sony_toc_read) {
1381 cmd_buff[0] = SONY535_SPIN_DOWN;
1382 do_sony_cmd(cmd_buff, 1, status, NULL, 0, 0);
1383 sony_inuse = 0;
1384 return -EIO;
1385 }
1386 check_disk_change(inode->i_bdev);
1387 sony_usage++;
1388
1389#ifdef LOCK_DOORS
1390 /* disable the eject button while mounted */
1391 cmd_buff[0] = SONY535_DISABLE_EJECT_BUTTON;
1392 do_sony_cmd(cmd_buff, 1, status, NULL, 0, 0);
1393#endif
1394
1395 return 0;
1396}
1397
1398
1399/*
1400 * Close the drive. Spin it down if no task is using it. The spin
1401 * down will fail if playing audio, so audio play is OK.
1402 */
1403static int
1404cdu_release(struct inode *inode,
1405 struct file *filp)
1406{
1407 Byte status[2], cmd_no;
1408
1409 sony_inuse = 0;
1410
1411 if (0 < sony_usage) {
1412 sony_usage--;
1413 }
1414 if (sony_usage == 0) {
1415 check_drive_status();
1416
1417 if (sony_audio_status != CDROM_AUDIO_PLAY) {
1418 cmd_no = SONY535_SPIN_DOWN;
1419 do_sony_cmd(&cmd_no, 1, status, NULL, 0, 0);
1420 }
1421#ifdef LOCK_DOORS
1422 /* enable the eject button after umount */
1423 cmd_no = SONY535_ENABLE_EJECT_BUTTON;
1424 do_sony_cmd(&cmd_no, 1, status, NULL, 0, 0);
1425#endif
1426 }
1427 return 0;
1428}
1429
1430static struct block_device_operations cdu_fops =
1431{
1432 .owner = THIS_MODULE,
1433 .open = cdu_open,
1434 .release = cdu_release,
1435 .ioctl = cdu_ioctl,
1436 .media_changed = cdu535_check_media_change,
1437};
1438
1439static struct gendisk *cdu_disk;
1440
1441/*
1442 * Initialize the driver.
1443 */
1444static int __init sony535_init(void)
1445{
1446 struct s535_sony_drive_config drive_config;
1447 Byte cmd_buff[3];
1448 Byte ret_buff[2];
1449 Byte status[2];
1450 unsigned long snap;
1451 int got_result = 0;
1452 int tmp_irq;
1453 int i;
1454 int err;
1455
1456 /* Setting the base I/O address to 0 will disable it. */
1457 if ((sony535_cd_base_io == 0xffff)||(sony535_cd_base_io == 0))
1458 return 0;
1459
1460 /* Set up all the register locations */
1461 result_reg = sony535_cd_base_io;
1462 command_reg = sony535_cd_base_io;
1463 data_reg = sony535_cd_base_io + 1;
1464 read_status_reg = sony535_cd_base_io + 2;
1465 select_unit_reg = sony535_cd_base_io + 3;
1466
1467#ifndef USE_IRQ
1468 sony535_irq_used = 0; /* polling only until this is ready... */
1469#endif
1470 /* we need to poll until things get initialized */
1471 tmp_irq = sony535_irq_used;
1472 sony535_irq_used = 0;
1473
1474#if DEBUG > 0
1475 printk(KERN_INFO CDU535_MESSAGE_NAME ": probing base address %03X\n",
1476 sony535_cd_base_io);
1477#endif
1478 /* look for the CD-ROM, follows the procedure in the DOS driver */
1479 inb(select_unit_reg);
1480 /* wait for 40 18 Hz ticks (reverse-engineered from DOS driver) */
1481 schedule_timeout_interruptible((HZ+17)*40/18);
1482 inb(result_reg);
1483
1484 outb(0, read_status_reg); /* does a reset? */
1485 snap = jiffies;
1486 while (jiffies-snap < SONY_JIFFIES_TIMEOUT) {
1487 select_unit(0);
1488 if (inb(result_reg) != 0xff) {
1489 got_result = 1;
1490 break;
1491 }
1492 sony_sleep();
1493 }
1494
1495 if (!got_result || check_drive_status() == TIME_OUT)
1496 goto Enodev;
1497
1498 /* CD-ROM drive responded -- get the drive configuration */
1499 cmd_buff[0] = SONY535_INQUIRY;
1500 if (do_sony_cmd(cmd_buff, 1, status, (Byte *)&drive_config, 28, 1) != 0)
1501 goto Enodev;
1502
1503 /* was able to get the configuration,
1504 * set drive mode as rest of init
1505 */
1506#if DEBUG > 0
1507 /* 0x50 == CADDY_NOT_INSERTED | NOT_SPINNING */
1508 if ( (status[0] & 0x7f) != 0 && (status[0] & 0x7f) != 0x50 )
1509 printk(CDU535_MESSAGE_NAME
1510 "Inquiry command returned status = 0x%x\n", status[0]);
1511#endif
1512 /* now ready to use interrupts, if available */
1513 sony535_irq_used = tmp_irq;
1514
1515 /* A negative sony535_irq_used will attempt an autoirq. */
1516 if (sony535_irq_used < 0) {
1517 unsigned long irq_mask, delay;
1518
1519 irq_mask = probe_irq_on();
1520 enable_interrupts();
1521 outb(0, read_status_reg); /* does a reset? */
1522 delay = jiffies + HZ/10;
1523 while (time_before(jiffies, delay)) ;
1524
1525 sony535_irq_used = probe_irq_off(irq_mask);
1526 disable_interrupts();
1527 }
1528 if (sony535_irq_used > 0) {
1529 if (request_irq(sony535_irq_used, cdu535_interrupt,
1530 IRQF_DISABLED, CDU535_HANDLE, NULL)) {
1531 printk("Unable to grab IRQ%d for the " CDU535_MESSAGE_NAME
1532 " driver; polling instead.\n", sony535_irq_used);
1533 sony535_irq_used = 0;
1534 }
1535 }
1536 cmd_buff[0] = SONY535_SET_DRIVE_MODE;
1537 cmd_buff[1] = 0x0; /* default audio */
1538 if (do_sony_cmd(cmd_buff, 2, status, ret_buff, 1, 1) != 0)
1539 goto Enodev_irq;
1540
1541 /* set the drive mode successful, we are set! */
1542 sony_buffer_size = SONY535_BUFFER_SIZE;
1543 sony_buffer_sectors = sony_buffer_size / CDU535_BLOCK_SIZE;
1544
1545 printk(KERN_INFO CDU535_MESSAGE_NAME " I/F CDROM : %8.8s %16.16s %4.4s",
1546 drive_config.vendor_id,
1547 drive_config.product_id,
1548 drive_config.product_rev_level);
1549 printk(" base address %03X, ", sony535_cd_base_io);
1550 if (tmp_irq > 0)
1551 printk("IRQ%d, ", tmp_irq);
1552 printk("using %d byte buffer\n", sony_buffer_size);
1553
1554 if (register_blkdev(MAJOR_NR, CDU535_HANDLE)) {
1555 err = -EIO;
1556 goto out1;
1557 }
1558 sonycd535_queue = blk_init_queue(do_cdu535_request, &sonycd535_lock);
1559 if (!sonycd535_queue) {
1560 err = -ENOMEM;
1561 goto out1a;
1562 }
1563
1564 blk_queue_hardsect_size(sonycd535_queue, CDU535_BLOCK_SIZE);
1565 sony_toc = kmalloc(sizeof(struct s535_sony_toc), GFP_KERNEL);
1566 err = -ENOMEM;
1567 if (!sony_toc)
1568 goto out2;
1569 last_sony_subcode = kmalloc(sizeof(struct s535_sony_subcode), GFP_KERNEL);
1570 if (!last_sony_subcode)
1571 goto out3;
1572 sony_buffer = kmalloc(sizeof(Byte *) * sony_buffer_sectors, GFP_KERNEL);
1573 if (!sony_buffer)
1574 goto out4;
1575 for (i = 0; i < sony_buffer_sectors; i++) {
1576 sony_buffer[i] = kmalloc(CDU535_BLOCK_SIZE, GFP_KERNEL);
1577 if (!sony_buffer[i]) {
1578 while (--i>=0)
1579 kfree(sony_buffer[i]);
1580 goto out5;
1581 }
1582 }
1583 initialized = 1;
1584
1585 cdu_disk = alloc_disk(1);
1586 if (!cdu_disk)
1587 goto out6;
1588 cdu_disk->major = MAJOR_NR;
1589 cdu_disk->first_minor = 0;
1590 cdu_disk->fops = &cdu_fops;
1591 sprintf(cdu_disk->disk_name, "cdu");
1592
1593 if (!request_region(sony535_cd_base_io, 4, CDU535_HANDLE)) {
1594 printk(KERN_WARNING"sonycd535: Unable to request region 0x%x\n",
1595 sony535_cd_base_io);
1596 goto out7;
1597 }
1598 cdu_disk->queue = sonycd535_queue;
1599 add_disk(cdu_disk);
1600 return 0;
1601
1602out7:
1603 put_disk(cdu_disk);
1604out6:
1605 for (i = 0; i < sony_buffer_sectors; i++)
1606 kfree(sony_buffer[i]);
1607out5:
1608 kfree(sony_buffer);
1609out4:
1610 kfree(last_sony_subcode);
1611out3:
1612 kfree(sony_toc);
1613out2:
1614 blk_cleanup_queue(sonycd535_queue);
1615out1a:
1616 unregister_blkdev(MAJOR_NR, CDU535_HANDLE);
1617out1:
1618 if (sony535_irq_used)
1619 free_irq(sony535_irq_used, NULL);
1620 return err;
1621Enodev_irq:
1622 if (sony535_irq_used)
1623 free_irq(sony535_irq_used, NULL);
1624Enodev:
1625 printk("Did not find a " CDU535_MESSAGE_NAME " drive\n");
1626 return -EIO;
1627}
1628
1629#ifndef MODULE
1630
1631/*
1632 * accept "kernel command line" parameters
1633 * (added by emoenke@gwdg.de)
1634 *
1635 * use: tell LILO:
1636 * sonycd535=0x320
1637 *
1638 * the address value has to be the existing CDROM port address.
1639 */
1640static int __init
1641sonycd535_setup(char *strings)
1642{
1643 int ints[3];
1644 (void)get_options(strings, ARRAY_SIZE(ints), ints);
1645 /* if IRQ change and default io base desired,
1646 * then call with io base of 0
1647 */
1648 if (ints[0] > 0)
1649 if (ints[1] != 0)
1650 sony535_cd_base_io = ints[1];
1651 if (ints[0] > 1)
1652 sony535_irq_used = ints[2];
1653 if ((strings != NULL) && (*strings != '\0'))
1654 printk(CDU535_MESSAGE_NAME
1655 ": Warning: Unknown interface type: %s\n", strings);
1656
1657 return 1;
1658}
1659
1660__setup("sonycd535=", sonycd535_setup);
1661
1662#endif /* MODULE */
1663
1664static void __exit
1665sony535_exit(void)
1666{
1667 int i;
1668
1669 release_region(sony535_cd_base_io, 4);
1670 for (i = 0; i < sony_buffer_sectors; i++)
1671 kfree(sony_buffer[i]);
1672 kfree(sony_buffer);
1673 kfree(last_sony_subcode);
1674 kfree(sony_toc);
1675 del_gendisk(cdu_disk);
1676 put_disk(cdu_disk);
1677 blk_cleanup_queue(sonycd535_queue);
1678 if (unregister_blkdev(MAJOR_NR, CDU535_HANDLE) == -EINVAL)
1679 printk("Uh oh, couldn't unregister " CDU535_HANDLE "\n");
1680 else
1681 printk(KERN_INFO CDU535_HANDLE " module released\n");
1682}
1683
1684module_init(sony535_init);
1685module_exit(sony535_exit);
1686
1687
1688MODULE_LICENSE("GPL");
1689MODULE_ALIAS_BLOCKDEV_MAJOR(CDU535_CDROM_MAJOR);
diff --git a/drivers/cdrom/sonycd535.h b/drivers/cdrom/sonycd535.h
deleted file mode 100644
index 5dea1ef168d6..000000000000
--- a/drivers/cdrom/sonycd535.h
+++ /dev/null
@@ -1,183 +0,0 @@
1#ifndef SONYCD535_H
2#define SONYCD535_H
3
4/*
5 * define all the commands recognized by the CDU-531/5
6 */
7#define SONY535_REQUEST_DRIVE_STATUS_1 (0x80)
8#define SONY535_REQUEST_SENSE (0x82)
9#define SONY535_REQUEST_DRIVE_STATUS_2 (0x84)
10#define SONY535_REQUEST_ERROR_STATUS (0x86)
11#define SONY535_REQUEST_AUDIO_STATUS (0x88)
12#define SONY535_INQUIRY (0x8a)
13
14#define SONY535_SET_INACTIVITY_TIME (0x90)
15
16#define SONY535_SEEK_AND_READ_N_BLOCKS_1 (0xa0)
17#define SONY535_SEEK_AND_READ_N_BLOCKS_2 (0xa4)
18#define SONY535_PLAY_AUDIO (0xa6)
19
20#define SONY535_REQUEST_DISC_CAPACITY (0xb0)
21#define SONY535_REQUEST_TOC_DATA (0xb2)
22#define SONY535_REQUEST_SUB_Q_DATA (0xb4)
23#define SONY535_REQUEST_ISRC (0xb6)
24#define SONY535_REQUEST_UPC_EAN (0xb8)
25
26#define SONY535_SET_DRIVE_MODE (0xc0)
27#define SONY535_REQUEST_DRIVE_MODE (0xc2)
28#define SONY535_SET_RETRY_COUNT (0xc4)
29
30#define SONY535_DIAGNOSTIC_1 (0xc6)
31#define SONY535_DIAGNOSTIC_4 (0xcc)
32#define SONY535_DIAGNOSTIC_5 (0xce)
33
34#define SONY535_EJECT_CADDY (0xd0)
35#define SONY535_DISABLE_EJECT_BUTTON (0xd2)
36#define SONY535_ENABLE_EJECT_BUTTON (0xd4)
37
38#define SONY535_HOLD (0xe0)
39#define SONY535_AUDIO_PAUSE_ON_OFF (0xe2)
40#define SONY535_SET_VOLUME (0xe8)
41
42#define SONY535_STOP (0xf0)
43#define SONY535_SPIN_UP (0xf2)
44#define SONY535_SPIN_DOWN (0xf4)
45
46#define SONY535_CLEAR_PARAMETERS (0xf6)
47#define SONY535_CLEAR_ENDING_ADDRESS (0xf8)
48
49/*
50 * define some masks
51 */
52#define SONY535_DATA_NOT_READY_BIT (0x1)
53#define SONY535_RESULT_NOT_READY_BIT (0x2)
54
55/*
56 * drive status 1
57 */
58#define SONY535_STATUS1_COMMAND_ERROR (0x1)
59#define SONY535_STATUS1_DATA_ERROR (0x2)
60#define SONY535_STATUS1_SEEK_ERROR (0x4)
61#define SONY535_STATUS1_DISC_TYPE_ERROR (0x8)
62#define SONY535_STATUS1_NOT_SPINNING (0x10)
63#define SONY535_STATUS1_EJECT_BUTTON_PRESSED (0x20)
64#define SONY535_STATUS1_CADDY_NOT_INSERTED (0x40)
65#define SONY535_STATUS1_BYTE_TWO_FOLLOWS (0x80)
66
67/*
68 * drive status 2
69 */
70#define SONY535_CDD_LOADING_ERROR (0x7)
71#define SONY535_CDD_NO_DISC (0x8)
72#define SONY535_CDD_UNLOADING_ERROR (0x9)
73#define SONY535_CDD_CADDY_NOT_INSERTED (0xd)
74#define SONY535_ATN_RESET_OCCURRED (0x2)
75#define SONY535_ATN_DISC_CHANGED (0x4)
76#define SONY535_ATN_RESET_AND_DISC_CHANGED (0x6)
77#define SONY535_ATN_EJECT_IN_PROGRESS (0xe)
78#define SONY535_ATN_BUSY (0xf)
79
80/*
81 * define some parameters
82 */
83#define SONY535_AUDIO_DRIVE_MODE (0)
84#define SONY535_CDROM_DRIVE_MODE (0xe0)
85
86#define SONY535_PLAY_OP_PLAYBACK (0)
87#define SONY535_PLAY_OP_ENTER_HOLD (1)
88#define SONY535_PLAY_OP_SET_AUDIO_ENDING_ADDR (2)
89#define SONY535_PLAY_OP_SCAN_FORWARD (3)
90#define SONY535_PLAY_OP_SCAN_BACKWARD (4)
91
92/*
93 * convert from msf format to block number
94 */
95#define SONY_BLOCK_NUMBER(m,s,f) (((m)*60L+(s))*75L+(f))
96#define SONY_BLOCK_NUMBER_MSF(x) (((x)[0]*60L+(x)[1])*75L+(x)[2])
97
98/*
99 * error return values from the doSonyCmd() routines
100 */
101#define TIME_OUT (-1)
102#define NO_CDROM (-2)
103#define BAD_STATUS (-3)
104#define CD_BUSY (-4)
105#define NOT_DATA_CD (-5)
106#define NO_ROOM (-6)
107
108#define LOG_START_OFFSET 150 /* Offset of first logical sector */
109
110#define SONY_JIFFIES_TIMEOUT (5*HZ) /* Maximum time
111 the drive will wait/try for an
112 operation */
113#define SONY_READY_RETRIES (50000) /* How many times to retry a
114 spin waiting for a register
115 to come ready */
116#define SONY535_FAST_POLLS (10000) /* how many times recheck
117 status waiting for a data
118 to become ready */
119
120typedef unsigned char Byte;
121
122/*
123 * This is the complete status returned from the drive configuration request
124 * command.
125 */
126struct s535_sony_drive_config
127{
128 char vendor_id[8];
129 char product_id[16];
130 char product_rev_level[4];
131};
132
133/* The following is returned from the request sub-q data command */
134struct s535_sony_subcode
135{
136 unsigned char address :4;
137 unsigned char control :4;
138 unsigned char track_num;
139 unsigned char index_num;
140 unsigned char rel_msf[3];
141 unsigned char abs_msf[3];
142};
143
144struct s535_sony_disc_capacity
145{
146 Byte mFirstTrack, sFirstTrack, fFirstTrack;
147 Byte mLeadOut, sLeadOut, fLeadOut;
148};
149
150/*
151 * The following is returned from the request TOC (Table Of Contents) command.
152 * (last_track_num-first_track_num+1) values are valid in tracks.
153 */
154struct s535_sony_toc
155{
156 unsigned char reserved0 :4;
157 unsigned char control0 :4;
158 unsigned char point0;
159 unsigned char first_track_num;
160 unsigned char reserved0a;
161 unsigned char reserved0b;
162 unsigned char reserved1 :4;
163 unsigned char control1 :4;
164 unsigned char point1;
165 unsigned char last_track_num;
166 unsigned char dummy1;
167 unsigned char dummy2;
168 unsigned char reserved2 :4;
169 unsigned char control2 :4;
170 unsigned char point2;
171 unsigned char lead_out_start_msf[3];
172 struct
173 {
174 unsigned char reserved :4;
175 unsigned char control :4;
176 unsigned char track;
177 unsigned char track_start_msf[3];
178 } tracks[100];
179
180 unsigned int lead_out_start_lba;
181};
182
183#endif /* SONYCD535_H */
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c
index 1b094509b1d2..90965b4def5c 100644
--- a/drivers/char/keyboard.c
+++ b/drivers/char/keyboard.c
@@ -1005,8 +1005,8 @@ static const unsigned short x86_keycodes[256] =
1005 284,285,309, 0,312, 91,327,328,329,331,333,335,336,337,338,339, 1005 284,285,309, 0,312, 91,327,328,329,331,333,335,336,337,338,339,
1006 367,288,302,304,350, 89,334,326,267,126,268,269,125,347,348,349, 1006 367,288,302,304,350, 89,334,326,267,126,268,269,125,347,348,349,
1007 360,261,262,263,268,376,100,101,321,316,373,286,289,102,351,355, 1007 360,261,262,263,268,376,100,101,321,316,373,286,289,102,351,355,
1008 103,104,105,275,287,279,306,106,274,107,294,364,358,363,362,361, 1008 103,104,105,275,287,279,258,106,274,107,294,364,358,363,362,361,
1009 291,108,381,281,290,272,292,305,280, 99,112,257,258,359,113,114, 1009 291,108,381,281,290,272,292,305,280, 99,112,257,306,359,113,114,
1010 264,117,271,374,379,265,266, 93, 94, 95, 85,259,375,260, 90,116, 1010 264,117,271,374,379,265,266, 93, 94, 95, 85,259,375,260, 90,116,
1011 377,109,111,277,278,282,283,295,296,297,299,300,301,293,303,307, 1011 377,109,111,277,278,282,283,295,296,297,299,300,301,293,303,307,
1012 308,310,313,314,315,317,318,319,320,357,322,323,324,325,276,330, 1012 308,310,313,314,315,317,318,319,320,357,322,323,324,325,276,330,
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index cc9a9d0df979..bbee97ff355f 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -24,7 +24,7 @@
24#include <linux/crash_dump.h> 24#include <linux/crash_dump.h>
25#include <linux/backing-dev.h> 25#include <linux/backing-dev.h>
26#include <linux/bootmem.h> 26#include <linux/bootmem.h>
27#include <linux/pipe_fs_i.h> 27#include <linux/splice.h>
28#include <linux/pfn.h> 28#include <linux/pfn.h>
29 29
30#include <asm/uaccess.h> 30#include <asm/uaccess.h>
@@ -75,6 +75,13 @@ static inline int uncached_access(struct file *file, unsigned long addr)
75 * On ia64, we ignore O_SYNC because we cannot tolerate memory attribute aliases. 75 * On ia64, we ignore O_SYNC because we cannot tolerate memory attribute aliases.
76 */ 76 */
77 return !(efi_mem_attributes(addr) & EFI_MEMORY_WB); 77 return !(efi_mem_attributes(addr) & EFI_MEMORY_WB);
78#elif defined(CONFIG_MIPS)
79 {
80 extern int __uncached_access(struct file *file,
81 unsigned long addr);
82
83 return __uncached_access(file, addr);
84 }
78#else 85#else
79 /* 86 /*
80 * Accessing memory above the top the kernel knows about or through a file pointer 87 * Accessing memory above the top the kernel knows about or through a file pointer
diff --git a/drivers/firewire/fw-card.c b/drivers/firewire/fw-card.c
index 9eb1edacd825..0aeab3218bb6 100644
--- a/drivers/firewire/fw-card.c
+++ b/drivers/firewire/fw-card.c
@@ -336,8 +336,11 @@ fw_card_bm_work(struct work_struct *work)
336 } 336 }
337 337
338 pick_me: 338 pick_me:
339 /* Now figure out what gap count to set. */ 339 /*
340 if (card->topology_type == FW_TOPOLOGY_A && 340 * Pick a gap count from 1394a table E-1. The table doesn't cover
341 * the typically much larger 1394b beta repeater delays though.
342 */
343 if (!card->beta_repeaters_present &&
341 card->root_node->max_hops < ARRAY_SIZE(gap_count_table)) 344 card->root_node->max_hops < ARRAY_SIZE(gap_count_table))
342 gap_count = gap_count_table[card->root_node->max_hops]; 345 gap_count = gap_count_table[card->root_node->max_hops];
343 else 346 else
diff --git a/drivers/firewire/fw-cdev.c b/drivers/firewire/fw-cdev.c
index dbb76427d529..75388641a7d3 100644
--- a/drivers/firewire/fw-cdev.c
+++ b/drivers/firewire/fw-cdev.c
@@ -397,7 +397,7 @@ static int ioctl_send_request(struct client *client, void *buffer)
397 request->tcode & 0x1f, 397 request->tcode & 0x1f,
398 device->node->node_id, 398 device->node->node_id,
399 request->generation, 399 request->generation,
400 device->node->max_speed, 400 device->max_speed,
401 request->offset, 401 request->offset,
402 response->response.data, request->length, 402 response->response.data, request->length,
403 complete_transaction, response); 403 complete_transaction, response);
diff --git a/drivers/firewire/fw-device.c b/drivers/firewire/fw-device.c
index c1ce465d9710..2b6586341635 100644
--- a/drivers/firewire/fw-device.c
+++ b/drivers/firewire/fw-device.c
@@ -401,8 +401,7 @@ static int read_rom(struct fw_device *device, int index, u32 * data)
401 401
402 offset = 0xfffff0000400ULL + index * 4; 402 offset = 0xfffff0000400ULL + index * 4;
403 fw_send_request(device->card, &t, TCODE_READ_QUADLET_REQUEST, 403 fw_send_request(device->card, &t, TCODE_READ_QUADLET_REQUEST,
404 device->node_id, 404 device->node_id, device->generation, device->max_speed,
405 device->generation, SCODE_100,
406 offset, NULL, 4, complete_transaction, &callback_data); 405 offset, NULL, 4, complete_transaction, &callback_data);
407 406
408 wait_for_completion(&callback_data.done); 407 wait_for_completion(&callback_data.done);
@@ -418,6 +417,8 @@ static int read_bus_info_block(struct fw_device *device)
418 u32 stack[16], sp, key; 417 u32 stack[16], sp, key;
419 int i, end, length; 418 int i, end, length;
420 419
420 device->max_speed = SCODE_100;
421
421 /* First read the bus info block. */ 422 /* First read the bus info block. */
422 for (i = 0; i < 5; i++) { 423 for (i = 0; i < 5; i++) {
423 if (read_rom(device, i, &rom[i]) != RCODE_COMPLETE) 424 if (read_rom(device, i, &rom[i]) != RCODE_COMPLETE)
@@ -434,6 +435,33 @@ static int read_bus_info_block(struct fw_device *device)
434 return -1; 435 return -1;
435 } 436 }
436 437
438 device->max_speed = device->node->max_speed;
439
440 /*
441 * Determine the speed of
442 * - devices with link speed less than PHY speed,
443 * - devices with 1394b PHY (unless only connected to 1394a PHYs),
444 * - all devices if there are 1394b repeaters.
445 * Note, we cannot use the bus info block's link_spd as starting point
446 * because some buggy firmwares set it lower than necessary and because
447 * 1394-1995 nodes do not have the field.
448 */
449 if ((rom[2] & 0x7) < device->max_speed ||
450 device->max_speed == SCODE_BETA ||
451 device->card->beta_repeaters_present) {
452 u32 dummy;
453
454 /* for S1600 and S3200 */
455 if (device->max_speed == SCODE_BETA)
456 device->max_speed = device->card->link_speed;
457
458 while (device->max_speed > SCODE_100) {
459 if (read_rom(device, 0, &dummy) == RCODE_COMPLETE)
460 break;
461 device->max_speed--;
462 }
463 }
464
437 /* 465 /*
438 * Now parse the config rom. The config rom is a recursive 466 * Now parse the config rom. The config rom is a recursive
439 * directory structure so we parse it using a stack of 467 * directory structure so we parse it using a stack of
@@ -680,8 +708,10 @@ static void fw_device_init(struct work_struct *work)
680 FW_DEVICE_RUNNING) == FW_DEVICE_SHUTDOWN) 708 FW_DEVICE_RUNNING) == FW_DEVICE_SHUTDOWN)
681 fw_device_shutdown(&device->work.work); 709 fw_device_shutdown(&device->work.work);
682 else 710 else
683 fw_notify("created new fw device %s (%d config rom retries)\n", 711 fw_notify("created new fw device %s "
684 device->device.bus_id, device->config_rom_retries); 712 "(%d config rom retries, S%d00)\n",
713 device->device.bus_id, device->config_rom_retries,
714 1 << device->max_speed);
685 715
686 /* 716 /*
687 * Reschedule the IRM work if we just finished reading the 717 * Reschedule the IRM work if we just finished reading the
diff --git a/drivers/firewire/fw-device.h b/drivers/firewire/fw-device.h
index af1723eae4ba..d13e6a69707f 100644
--- a/drivers/firewire/fw-device.h
+++ b/drivers/firewire/fw-device.h
@@ -40,6 +40,7 @@ struct fw_device {
40 struct fw_node *node; 40 struct fw_node *node;
41 int node_id; 41 int node_id;
42 int generation; 42 int generation;
43 unsigned max_speed;
43 struct fw_card *card; 44 struct fw_card *card;
44 struct device device; 45 struct device device;
45 struct list_head link; 46 struct list_head link;
diff --git a/drivers/firewire/fw-ohci.c b/drivers/firewire/fw-ohci.c
index 96c8ac5b86cc..41476abc0693 100644
--- a/drivers/firewire/fw-ohci.c
+++ b/drivers/firewire/fw-ohci.c
@@ -1934,12 +1934,12 @@ static int pci_suspend(struct pci_dev *pdev, pm_message_t state)
1934 free_irq(pdev->irq, ohci); 1934 free_irq(pdev->irq, ohci);
1935 err = pci_save_state(pdev); 1935 err = pci_save_state(pdev);
1936 if (err) { 1936 if (err) {
1937 fw_error("pci_save_state failed with %d", err); 1937 fw_error("pci_save_state failed\n");
1938 return err; 1938 return err;
1939 } 1939 }
1940 err = pci_set_power_state(pdev, pci_choose_state(pdev, state)); 1940 err = pci_set_power_state(pdev, pci_choose_state(pdev, state));
1941 if (err) { 1941 if (err) {
1942 fw_error("pci_set_power_state failed with %d", err); 1942 fw_error("pci_set_power_state failed\n");
1943 return err; 1943 return err;
1944 } 1944 }
1945 1945
@@ -1955,7 +1955,7 @@ static int pci_resume(struct pci_dev *pdev)
1955 pci_restore_state(pdev); 1955 pci_restore_state(pdev);
1956 err = pci_enable_device(pdev); 1956 err = pci_enable_device(pdev);
1957 if (err) { 1957 if (err) {
1958 fw_error("pci_enable_device failed with %d", err); 1958 fw_error("pci_enable_device failed\n");
1959 return err; 1959 return err;
1960 } 1960 }
1961 1961
diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c
index a98d3915e26f..7c53be0387fb 100644
--- a/drivers/firewire/fw-sbp2.c
+++ b/drivers/firewire/fw-sbp2.c
@@ -30,10 +30,13 @@
30 30
31#include <linux/kernel.h> 31#include <linux/kernel.h>
32#include <linux/module.h> 32#include <linux/module.h>
33#include <linux/moduleparam.h>
33#include <linux/mod_devicetable.h> 34#include <linux/mod_devicetable.h>
34#include <linux/device.h> 35#include <linux/device.h>
35#include <linux/scatterlist.h> 36#include <linux/scatterlist.h>
36#include <linux/dma-mapping.h> 37#include <linux/dma-mapping.h>
38#include <linux/blkdev.h>
39#include <linux/string.h>
37#include <linux/timer.h> 40#include <linux/timer.h>
38 41
39#include <scsi/scsi.h> 42#include <scsi/scsi.h>
@@ -46,6 +49,18 @@
46#include "fw-topology.h" 49#include "fw-topology.h"
47#include "fw-device.h" 50#include "fw-device.h"
48 51
52/*
53 * So far only bridges from Oxford Semiconductor are known to support
54 * concurrent logins. Depending on firmware, four or two concurrent logins
55 * are possible on OXFW911 and newer Oxsemi bridges.
56 *
57 * Concurrent logins are useful together with cluster filesystems.
58 */
59static int sbp2_param_exclusive_login = 1;
60module_param_named(exclusive_login, sbp2_param_exclusive_login, bool, 0644);
61MODULE_PARM_DESC(exclusive_login, "Exclusive login to sbp2 device "
62 "(default = Y, use N for concurrent initiators)");
63
49/* I don't know why the SCSI stack doesn't define something like this... */ 64/* I don't know why the SCSI stack doesn't define something like this... */
50typedef void (*scsi_done_fn_t)(struct scsi_cmnd *); 65typedef void (*scsi_done_fn_t)(struct scsi_cmnd *);
51 66
@@ -154,7 +169,7 @@ struct sbp2_orb {
154#define MANAGEMENT_ORB_LUN(v) ((v)) 169#define MANAGEMENT_ORB_LUN(v) ((v))
155#define MANAGEMENT_ORB_FUNCTION(v) ((v) << 16) 170#define MANAGEMENT_ORB_FUNCTION(v) ((v) << 16)
156#define MANAGEMENT_ORB_RECONNECT(v) ((v) << 20) 171#define MANAGEMENT_ORB_RECONNECT(v) ((v) << 20)
157#define MANAGEMENT_ORB_EXCLUSIVE ((1) << 28) 172#define MANAGEMENT_ORB_EXCLUSIVE(v) ((v) ? 1 << 28 : 0)
158#define MANAGEMENT_ORB_REQUEST_FORMAT(v) ((v) << 29) 173#define MANAGEMENT_ORB_REQUEST_FORMAT(v) ((v) << 29)
159#define MANAGEMENT_ORB_NOTIFY ((1) << 31) 174#define MANAGEMENT_ORB_NOTIFY ((1) << 31)
160 175
@@ -205,9 +220,8 @@ struct sbp2_command_orb {
205 scsi_done_fn_t done; 220 scsi_done_fn_t done;
206 struct fw_unit *unit; 221 struct fw_unit *unit;
207 222
208 struct sbp2_pointer page_table[SG_ALL]; 223 struct sbp2_pointer page_table[SG_ALL] __attribute__((aligned(8)));
209 dma_addr_t page_table_bus; 224 dma_addr_t page_table_bus;
210 dma_addr_t request_buffer_bus;
211}; 225};
212 226
213/* 227/*
@@ -347,8 +361,7 @@ sbp2_send_orb(struct sbp2_orb *orb, struct fw_unit *unit,
347 spin_unlock_irqrestore(&device->card->lock, flags); 361 spin_unlock_irqrestore(&device->card->lock, flags);
348 362
349 fw_send_request(device->card, &orb->t, TCODE_WRITE_BLOCK_REQUEST, 363 fw_send_request(device->card, &orb->t, TCODE_WRITE_BLOCK_REQUEST,
350 node_id, generation, 364 node_id, generation, device->max_speed, offset,
351 device->node->max_speed, offset,
352 &orb->pointer, sizeof(orb->pointer), 365 &orb->pointer, sizeof(orb->pointer),
353 complete_transaction, orb); 366 complete_transaction, orb);
354} 367}
@@ -383,7 +396,7 @@ static void
383complete_management_orb(struct sbp2_orb *base_orb, struct sbp2_status *status) 396complete_management_orb(struct sbp2_orb *base_orb, struct sbp2_status *status)
384{ 397{
385 struct sbp2_management_orb *orb = 398 struct sbp2_management_orb *orb =
386 (struct sbp2_management_orb *)base_orb; 399 container_of(base_orb, struct sbp2_management_orb, base);
387 400
388 if (status) 401 if (status)
389 memcpy(&orb->status, status, sizeof(*status)); 402 memcpy(&orb->status, status, sizeof(*status));
@@ -403,21 +416,11 @@ sbp2_send_management_orb(struct fw_unit *unit, int node_id, int generation,
403 if (orb == NULL) 416 if (orb == NULL)
404 return -ENOMEM; 417 return -ENOMEM;
405 418
406 /*
407 * The sbp2 device is going to send a block read request to
408 * read out the request from host memory, so map it for dma.
409 */
410 orb->base.request_bus =
411 dma_map_single(device->card->device, &orb->request,
412 sizeof(orb->request), DMA_TO_DEVICE);
413 if (dma_mapping_error(orb->base.request_bus))
414 goto out;
415
416 orb->response_bus = 419 orb->response_bus =
417 dma_map_single(device->card->device, &orb->response, 420 dma_map_single(device->card->device, &orb->response,
418 sizeof(orb->response), DMA_FROM_DEVICE); 421 sizeof(orb->response), DMA_FROM_DEVICE);
419 if (dma_mapping_error(orb->response_bus)) 422 if (dma_mapping_error(orb->response_bus))
420 goto out; 423 goto fail_mapping_response;
421 424
422 orb->request.response.high = 0; 425 orb->request.response.high = 0;
423 orb->request.response.low = orb->response_bus; 426 orb->request.response.low = orb->response_bus;
@@ -432,14 +435,9 @@ sbp2_send_management_orb(struct fw_unit *unit, int node_id, int generation,
432 orb->request.status_fifo.high = sd->address_handler.offset >> 32; 435 orb->request.status_fifo.high = sd->address_handler.offset >> 32;
433 orb->request.status_fifo.low = sd->address_handler.offset; 436 orb->request.status_fifo.low = sd->address_handler.offset;
434 437
435 /*
436 * FIXME: Yeah, ok this isn't elegant, we hardwire exclusive
437 * login and 1 second reconnect time. The reconnect setting
438 * is probably fine, but the exclusive login should be an option.
439 */
440 if (function == SBP2_LOGIN_REQUEST) { 438 if (function == SBP2_LOGIN_REQUEST) {
441 orb->request.misc |= 439 orb->request.misc |=
442 MANAGEMENT_ORB_EXCLUSIVE | 440 MANAGEMENT_ORB_EXCLUSIVE(sbp2_param_exclusive_login) |
443 MANAGEMENT_ORB_RECONNECT(0); 441 MANAGEMENT_ORB_RECONNECT(0);
444 } 442 }
445 443
@@ -448,6 +446,12 @@ sbp2_send_management_orb(struct fw_unit *unit, int node_id, int generation,
448 init_completion(&orb->done); 446 init_completion(&orb->done);
449 orb->base.callback = complete_management_orb; 447 orb->base.callback = complete_management_orb;
450 448
449 orb->base.request_bus =
450 dma_map_single(device->card->device, &orb->request,
451 sizeof(orb->request), DMA_TO_DEVICE);
452 if (dma_mapping_error(orb->base.request_bus))
453 goto fail_mapping_request;
454
451 sbp2_send_orb(&orb->base, unit, 455 sbp2_send_orb(&orb->base, unit,
452 node_id, generation, sd->management_agent_address); 456 node_id, generation, sd->management_agent_address);
453 457
@@ -479,9 +483,10 @@ sbp2_send_management_orb(struct fw_unit *unit, int node_id, int generation,
479 out: 483 out:
480 dma_unmap_single(device->card->device, orb->base.request_bus, 484 dma_unmap_single(device->card->device, orb->base.request_bus,
481 sizeof(orb->request), DMA_TO_DEVICE); 485 sizeof(orb->request), DMA_TO_DEVICE);
486 fail_mapping_request:
482 dma_unmap_single(device->card->device, orb->response_bus, 487 dma_unmap_single(device->card->device, orb->response_bus,
483 sizeof(orb->response), DMA_FROM_DEVICE); 488 sizeof(orb->response), DMA_FROM_DEVICE);
484 489 fail_mapping_response:
485 if (response) 490 if (response)
486 fw_memcpy_from_be32(response, 491 fw_memcpy_from_be32(response,
487 orb->response, sizeof(orb->response)); 492 orb->response, sizeof(orb->response));
@@ -511,7 +516,7 @@ static int sbp2_agent_reset(struct fw_unit *unit)
511 return -ENOMEM; 516 return -ENOMEM;
512 517
513 fw_send_request(device->card, t, TCODE_WRITE_QUADLET_REQUEST, 518 fw_send_request(device->card, t, TCODE_WRITE_QUADLET_REQUEST,
514 sd->node_id, sd->generation, SCODE_400, 519 sd->node_id, sd->generation, device->max_speed,
515 sd->command_block_agent_address + SBP2_AGENT_RESET, 520 sd->command_block_agent_address + SBP2_AGENT_RESET,
516 &zero, sizeof(zero), complete_agent_reset_write, t); 521 &zero, sizeof(zero), complete_agent_reset_write, t);
517 522
@@ -521,17 +526,15 @@ static int sbp2_agent_reset(struct fw_unit *unit)
521static void sbp2_reconnect(struct work_struct *work); 526static void sbp2_reconnect(struct work_struct *work);
522static struct scsi_host_template scsi_driver_template; 527static struct scsi_host_template scsi_driver_template;
523 528
524static void 529static void release_sbp2_device(struct kref *kref)
525release_sbp2_device(struct kref *kref)
526{ 530{
527 struct sbp2_device *sd = container_of(kref, struct sbp2_device, kref); 531 struct sbp2_device *sd = container_of(kref, struct sbp2_device, kref);
528 struct Scsi_Host *host = 532 struct Scsi_Host *host =
529 container_of((void *)sd, struct Scsi_Host, hostdata[0]); 533 container_of((void *)sd, struct Scsi_Host, hostdata[0]);
530 534
535 scsi_remove_host(host);
531 sbp2_send_management_orb(sd->unit, sd->node_id, sd->generation, 536 sbp2_send_management_orb(sd->unit, sd->node_id, sd->generation,
532 SBP2_LOGOUT_REQUEST, sd->login_id, NULL); 537 SBP2_LOGOUT_REQUEST, sd->login_id, NULL);
533
534 scsi_remove_host(host);
535 fw_core_remove_address_handler(&sd->address_handler); 538 fw_core_remove_address_handler(&sd->address_handler);
536 fw_notify("removed sbp2 unit %s\n", sd->unit->device.bus_id); 539 fw_notify("removed sbp2 unit %s\n", sd->unit->device.bus_id);
537 put_device(&sd->unit->device); 540 put_device(&sd->unit->device);
@@ -833,7 +836,8 @@ sbp2_status_to_sense_data(u8 *sbp2_status, u8 *sense_data)
833static void 836static void
834complete_command_orb(struct sbp2_orb *base_orb, struct sbp2_status *status) 837complete_command_orb(struct sbp2_orb *base_orb, struct sbp2_status *status)
835{ 838{
836 struct sbp2_command_orb *orb = (struct sbp2_command_orb *)base_orb; 839 struct sbp2_command_orb *orb =
840 container_of(base_orb, struct sbp2_command_orb, base);
837 struct fw_unit *unit = orb->unit; 841 struct fw_unit *unit = orb->unit;
838 struct fw_device *device = fw_device(unit->device.parent); 842 struct fw_device *device = fw_device(unit->device.parent);
839 struct scatterlist *sg; 843 struct scatterlist *sg;
@@ -880,12 +884,7 @@ complete_command_orb(struct sbp2_orb *base_orb, struct sbp2_status *status)
880 884
881 if (orb->page_table_bus != 0) 885 if (orb->page_table_bus != 0)
882 dma_unmap_single(device->card->device, orb->page_table_bus, 886 dma_unmap_single(device->card->device, orb->page_table_bus,
883 sizeof(orb->page_table_bus), DMA_TO_DEVICE); 887 sizeof(orb->page_table), DMA_TO_DEVICE);
884
885 if (orb->request_buffer_bus != 0)
886 dma_unmap_single(device->card->device, orb->request_buffer_bus,
887 sizeof(orb->request_buffer_bus),
888 DMA_FROM_DEVICE);
889 888
890 orb->cmd->result = result; 889 orb->cmd->result = result;
891 orb->done(orb->cmd); 890 orb->done(orb->cmd);
@@ -900,7 +899,6 @@ static int sbp2_command_orb_map_scatterlist(struct sbp2_command_orb *orb)
900 struct fw_device *device = fw_device(unit->device.parent); 899 struct fw_device *device = fw_device(unit->device.parent);
901 struct scatterlist *sg; 900 struct scatterlist *sg;
902 int sg_len, l, i, j, count; 901 int sg_len, l, i, j, count;
903 size_t size;
904 dma_addr_t sg_addr; 902 dma_addr_t sg_addr;
905 903
906 sg = (struct scatterlist *)orb->cmd->request_buffer; 904 sg = (struct scatterlist *)orb->cmd->request_buffer;
@@ -935,6 +933,11 @@ static int sbp2_command_orb_map_scatterlist(struct sbp2_command_orb *orb)
935 sg_len = sg_dma_len(sg + i); 933 sg_len = sg_dma_len(sg + i);
936 sg_addr = sg_dma_address(sg + i); 934 sg_addr = sg_dma_address(sg + i);
937 while (sg_len) { 935 while (sg_len) {
936 /* FIXME: This won't get us out of the pinch. */
937 if (unlikely(j >= ARRAY_SIZE(orb->page_table))) {
938 fw_error("page table overflow\n");
939 goto fail_page_table;
940 }
938 l = min(sg_len, SBP2_MAX_SG_ELEMENT_LENGTH); 941 l = min(sg_len, SBP2_MAX_SG_ELEMENT_LENGTH);
939 orb->page_table[j].low = sg_addr; 942 orb->page_table[j].low = sg_addr;
940 orb->page_table[j].high = (l << 16); 943 orb->page_table[j].high = (l << 16);
@@ -944,7 +947,13 @@ static int sbp2_command_orb_map_scatterlist(struct sbp2_command_orb *orb)
944 } 947 }
945 } 948 }
946 949
947 size = sizeof(orb->page_table[0]) * j; 950 fw_memcpy_to_be32(orb->page_table, orb->page_table,
951 sizeof(orb->page_table[0]) * j);
952 orb->page_table_bus =
953 dma_map_single(device->card->device, orb->page_table,
954 sizeof(orb->page_table), DMA_TO_DEVICE);
955 if (dma_mapping_error(orb->page_table_bus))
956 goto fail_page_table;
948 957
949 /* 958 /*
950 * The data_descriptor pointer is the one case where we need 959 * The data_descriptor pointer is the one case where we need
@@ -953,20 +962,12 @@ static int sbp2_command_orb_map_scatterlist(struct sbp2_command_orb *orb)
953 * initiator (i.e. us), but data_descriptor can refer to data 962 * initiator (i.e. us), but data_descriptor can refer to data
954 * on other nodes so we need to put our ID in descriptor.high. 963 * on other nodes so we need to put our ID in descriptor.high.
955 */ 964 */
956
957 orb->page_table_bus =
958 dma_map_single(device->card->device, orb->page_table,
959 size, DMA_TO_DEVICE);
960 if (dma_mapping_error(orb->page_table_bus))
961 goto fail_page_table;
962 orb->request.data_descriptor.high = sd->address_high; 965 orb->request.data_descriptor.high = sd->address_high;
963 orb->request.data_descriptor.low = orb->page_table_bus; 966 orb->request.data_descriptor.low = orb->page_table_bus;
964 orb->request.misc |= 967 orb->request.misc |=
965 COMMAND_ORB_PAGE_TABLE_PRESENT | 968 COMMAND_ORB_PAGE_TABLE_PRESENT |
966 COMMAND_ORB_DATA_SIZE(j); 969 COMMAND_ORB_DATA_SIZE(j);
967 970
968 fw_memcpy_to_be32(orb->page_table, orb->page_table, size);
969
970 return 0; 971 return 0;
971 972
972 fail_page_table: 973 fail_page_table:
@@ -991,7 +992,7 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done)
991 * transfer direction not handled. 992 * transfer direction not handled.
992 */ 993 */
993 if (cmd->sc_data_direction == DMA_BIDIRECTIONAL) { 994 if (cmd->sc_data_direction == DMA_BIDIRECTIONAL) {
994 fw_error("Cannot handle DMA_BIDIRECTIONAL - rejecting command"); 995 fw_error("Can't handle DMA_BIDIRECTIONAL, rejecting command\n");
995 cmd->result = DID_ERROR << 16; 996 cmd->result = DID_ERROR << 16;
996 done(cmd); 997 done(cmd);
997 return 0; 998 return 0;
@@ -1005,11 +1006,6 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done)
1005 1006
1006 /* Initialize rcode to something not RCODE_COMPLETE. */ 1007 /* Initialize rcode to something not RCODE_COMPLETE. */
1007 orb->base.rcode = -1; 1008 orb->base.rcode = -1;
1008 orb->base.request_bus =
1009 dma_map_single(device->card->device, &orb->request,
1010 sizeof(orb->request), DMA_TO_DEVICE);
1011 if (dma_mapping_error(orb->base.request_bus))
1012 goto fail_mapping;
1013 1009
1014 orb->unit = unit; 1010 orb->unit = unit;
1015 orb->done = done; 1011 orb->done = done;
@@ -1024,8 +1020,8 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done)
1024 * if we set this to max_speed + 7, we get the right value. 1020 * if we set this to max_speed + 7, we get the right value.
1025 */ 1021 */
1026 orb->request.misc = 1022 orb->request.misc =
1027 COMMAND_ORB_MAX_PAYLOAD(device->node->max_speed + 7) | 1023 COMMAND_ORB_MAX_PAYLOAD(device->max_speed + 7) |
1028 COMMAND_ORB_SPEED(device->node->max_speed) | 1024 COMMAND_ORB_SPEED(device->max_speed) |
1029 COMMAND_ORB_NOTIFY; 1025 COMMAND_ORB_NOTIFY;
1030 1026
1031 if (cmd->sc_data_direction == DMA_FROM_DEVICE) 1027 if (cmd->sc_data_direction == DMA_FROM_DEVICE)
@@ -1036,7 +1032,7 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done)
1036 COMMAND_ORB_DIRECTION(SBP2_DIRECTION_TO_MEDIA); 1032 COMMAND_ORB_DIRECTION(SBP2_DIRECTION_TO_MEDIA);
1037 1033
1038 if (cmd->use_sg && sbp2_command_orb_map_scatterlist(orb) < 0) 1034 if (cmd->use_sg && sbp2_command_orb_map_scatterlist(orb) < 0)
1039 goto fail_map_payload; 1035 goto fail_mapping;
1040 1036
1041 fw_memcpy_to_be32(&orb->request, &orb->request, sizeof(orb->request)); 1037 fw_memcpy_to_be32(&orb->request, &orb->request, sizeof(orb->request));
1042 1038
@@ -1045,15 +1041,17 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done)
1045 memcpy(orb->request.command_block, cmd->cmnd, COMMAND_SIZE(*cmd->cmnd)); 1041 memcpy(orb->request.command_block, cmd->cmnd, COMMAND_SIZE(*cmd->cmnd));
1046 1042
1047 orb->base.callback = complete_command_orb; 1043 orb->base.callback = complete_command_orb;
1044 orb->base.request_bus =
1045 dma_map_single(device->card->device, &orb->request,
1046 sizeof(orb->request), DMA_TO_DEVICE);
1047 if (dma_mapping_error(orb->base.request_bus))
1048 goto fail_mapping;
1048 1049
1049 sbp2_send_orb(&orb->base, unit, sd->node_id, sd->generation, 1050 sbp2_send_orb(&orb->base, unit, sd->node_id, sd->generation,
1050 sd->command_block_agent_address + SBP2_ORB_POINTER); 1051 sd->command_block_agent_address + SBP2_ORB_POINTER);
1051 1052
1052 return 0; 1053 return 0;
1053 1054
1054 fail_map_payload:
1055 dma_unmap_single(device->card->device, orb->base.request_bus,
1056 sizeof(orb->request), DMA_TO_DEVICE);
1057 fail_mapping: 1055 fail_mapping:
1058 kfree(orb); 1056 kfree(orb);
1059 fail_alloc: 1057 fail_alloc:
@@ -1087,7 +1085,8 @@ static int sbp2_scsi_slave_configure(struct scsi_device *sdev)
1087 fw_notify("setting fix_capacity for %s\n", unit->device.bus_id); 1085 fw_notify("setting fix_capacity for %s\n", unit->device.bus_id);
1088 sdev->fix_capacity = 1; 1086 sdev->fix_capacity = 1;
1089 } 1087 }
1090 1088 if (sd->workarounds & SBP2_WORKAROUND_128K_MAX_TRANS)
1089 blk_queue_max_sectors(sdev->request_queue, 128 * 1024 / 512);
1091 return 0; 1090 return 0;
1092} 1091}
1093 1092
diff --git a/drivers/firewire/fw-topology.c b/drivers/firewire/fw-topology.c
index 7aebb8ae0efa..39e5cd12aa52 100644
--- a/drivers/firewire/fw-topology.c
+++ b/drivers/firewire/fw-topology.c
@@ -135,17 +135,17 @@ static void update_hop_count(struct fw_node *node)
135 int i; 135 int i;
136 136
137 for (i = 0; i < node->port_count; i++) { 137 for (i = 0; i < node->port_count; i++) {
138 if (node->ports[i].node == NULL) 138 if (node->ports[i] == NULL)
139 continue; 139 continue;
140 140
141 if (node->ports[i].node->max_hops > max_child_hops) 141 if (node->ports[i]->max_hops > max_child_hops)
142 max_child_hops = node->ports[i].node->max_hops; 142 max_child_hops = node->ports[i]->max_hops;
143 143
144 if (node->ports[i].node->max_depth > depths[0]) { 144 if (node->ports[i]->max_depth > depths[0]) {
145 depths[1] = depths[0]; 145 depths[1] = depths[0];
146 depths[0] = node->ports[i].node->max_depth; 146 depths[0] = node->ports[i]->max_depth;
147 } else if (node->ports[i].node->max_depth > depths[1]) 147 } else if (node->ports[i]->max_depth > depths[1])
148 depths[1] = node->ports[i].node->max_depth; 148 depths[1] = node->ports[i]->max_depth;
149 } 149 }
150 150
151 node->max_depth = depths[0] + 1; 151 node->max_depth = depths[0] + 1;
@@ -172,7 +172,8 @@ static struct fw_node *build_tree(struct fw_card *card,
172 struct list_head stack, *h; 172 struct list_head stack, *h;
173 u32 *next_sid, *end, q; 173 u32 *next_sid, *end, q;
174 int i, port_count, child_port_count, phy_id, parent_count, stack_depth; 174 int i, port_count, child_port_count, phy_id, parent_count, stack_depth;
175 int gap_count, topology_type; 175 int gap_count;
176 bool beta_repeaters_present;
176 177
177 local_node = NULL; 178 local_node = NULL;
178 node = NULL; 179 node = NULL;
@@ -182,7 +183,7 @@ static struct fw_node *build_tree(struct fw_card *card,
182 phy_id = 0; 183 phy_id = 0;
183 irm_node = NULL; 184 irm_node = NULL;
184 gap_count = SELF_ID_GAP_COUNT(*sid); 185 gap_count = SELF_ID_GAP_COUNT(*sid);
185 topology_type = 0; 186 beta_repeaters_present = false;
186 187
187 while (sid < end) { 188 while (sid < end) {
188 next_sid = count_ports(sid, &port_count, &child_port_count); 189 next_sid = count_ports(sid, &port_count, &child_port_count);
@@ -214,7 +215,7 @@ static struct fw_node *build_tree(struct fw_card *card,
214 215
215 node = fw_node_create(q, port_count, card->color); 216 node = fw_node_create(q, port_count, card->color);
216 if (node == NULL) { 217 if (node == NULL) {
217 fw_error("Out of memory while building topology."); 218 fw_error("Out of memory while building topology.\n");
218 return NULL; 219 return NULL;
219 } 220 }
220 221
@@ -224,11 +225,6 @@ static struct fw_node *build_tree(struct fw_card *card,
224 if (SELF_ID_CONTENDER(q)) 225 if (SELF_ID_CONTENDER(q))
225 irm_node = node; 226 irm_node = node;
226 227
227 if (node->phy_speed == SCODE_BETA)
228 topology_type |= FW_TOPOLOGY_B;
229 else
230 topology_type |= FW_TOPOLOGY_A;
231
232 parent_count = 0; 228 parent_count = 0;
233 229
234 for (i = 0; i < port_count; i++) { 230 for (i = 0; i < port_count; i++) {
@@ -249,12 +245,12 @@ static struct fw_node *build_tree(struct fw_card *card,
249 break; 245 break;
250 246
251 case SELFID_PORT_CHILD: 247 case SELFID_PORT_CHILD:
252 node->ports[i].node = child; 248 node->ports[i] = child;
253 /* 249 /*
254 * Fix up parent reference for this 250 * Fix up parent reference for this
255 * child node. 251 * child node.
256 */ 252 */
257 child->ports[child->color].node = node; 253 child->ports[child->color] = node;
258 child->color = card->color; 254 child->color = card->color;
259 child = fw_node(child->link.next); 255 child = fw_node(child->link.next);
260 break; 256 break;
@@ -278,6 +274,10 @@ static struct fw_node *build_tree(struct fw_card *card,
278 list_add_tail(&node->link, &stack); 274 list_add_tail(&node->link, &stack);
279 stack_depth += 1 - child_port_count; 275 stack_depth += 1 - child_port_count;
280 276
277 if (node->phy_speed == SCODE_BETA &&
278 parent_count + child_port_count > 1)
279 beta_repeaters_present = true;
280
281 /* 281 /*
282 * If all PHYs does not report the same gap count 282 * If all PHYs does not report the same gap count
283 * setting, we fall back to 63 which will force a gap 283 * setting, we fall back to 63 which will force a gap
@@ -295,7 +295,7 @@ static struct fw_node *build_tree(struct fw_card *card,
295 card->root_node = node; 295 card->root_node = node;
296 card->irm_node = irm_node; 296 card->irm_node = irm_node;
297 card->gap_count = gap_count; 297 card->gap_count = gap_count;
298 card->topology_type = topology_type; 298 card->beta_repeaters_present = beta_repeaters_present;
299 299
300 return local_node; 300 return local_node;
301} 301}
@@ -321,7 +321,7 @@ for_each_fw_node(struct fw_card *card, struct fw_node *root,
321 node->color = card->color; 321 node->color = card->color;
322 322
323 for (i = 0; i < node->port_count; i++) { 323 for (i = 0; i < node->port_count; i++) {
324 child = node->ports[i].node; 324 child = node->ports[i];
325 if (!child) 325 if (!child)
326 continue; 326 continue;
327 if (child->color == card->color) 327 if (child->color == card->color)
@@ -382,11 +382,11 @@ static void move_tree(struct fw_node *node0, struct fw_node *node1, int port)
382 struct fw_node *tree; 382 struct fw_node *tree;
383 int i; 383 int i;
384 384
385 tree = node1->ports[port].node; 385 tree = node1->ports[port];
386 node0->ports[port].node = tree; 386 node0->ports[port] = tree;
387 for (i = 0; i < tree->port_count; i++) { 387 for (i = 0; i < tree->port_count; i++) {
388 if (tree->ports[i].node == node1) { 388 if (tree->ports[i] == node1) {
389 tree->ports[i].node = node0; 389 tree->ports[i] = node0;
390 break; 390 break;
391 } 391 }
392 } 392 }
@@ -437,19 +437,17 @@ update_tree(struct fw_card *card, struct fw_node *root)
437 card->irm_node = node0; 437 card->irm_node = node0;
438 438
439 for (i = 0; i < node0->port_count; i++) { 439 for (i = 0; i < node0->port_count; i++) {
440 if (node0->ports[i].node && node1->ports[i].node) { 440 if (node0->ports[i] && node1->ports[i]) {
441 /* 441 /*
442 * This port didn't change, queue the 442 * This port didn't change, queue the
443 * connected node for further 443 * connected node for further
444 * investigation. 444 * investigation.
445 */ 445 */
446 if (node0->ports[i].node->color == card->color) 446 if (node0->ports[i]->color == card->color)
447 continue; 447 continue;
448 list_add_tail(&node0->ports[i].node->link, 448 list_add_tail(&node0->ports[i]->link, &list0);
449 &list0); 449 list_add_tail(&node1->ports[i]->link, &list1);
450 list_add_tail(&node1->ports[i].node->link, 450 } else if (node0->ports[i]) {
451 &list1);
452 } else if (node0->ports[i].node) {
453 /* 451 /*
454 * The nodes connected here were 452 * The nodes connected here were
455 * unplugged; unref the lost nodes and 453 * unplugged; unref the lost nodes and
@@ -457,10 +455,10 @@ update_tree(struct fw_card *card, struct fw_node *root)
457 * them. 455 * them.
458 */ 456 */
459 457
460 for_each_fw_node(card, node0->ports[i].node, 458 for_each_fw_node(card, node0->ports[i],
461 report_lost_node); 459 report_lost_node);
462 node0->ports[i].node = NULL; 460 node0->ports[i] = NULL;
463 } else if (node1->ports[i].node) { 461 } else if (node1->ports[i]) {
464 /* 462 /*
465 * One or more node were connected to 463 * One or more node were connected to
466 * this port. Move the new nodes into 464 * this port. Move the new nodes into
@@ -468,7 +466,7 @@ update_tree(struct fw_card *card, struct fw_node *root)
468 * callbacks for them. 466 * callbacks for them.
469 */ 467 */
470 move_tree(node0, node1, i); 468 move_tree(node0, node1, i);
471 for_each_fw_node(card, node0->ports[i].node, 469 for_each_fw_node(card, node0->ports[i],
472 report_found_node); 470 report_found_node);
473 } 471 }
474 } 472 }
diff --git a/drivers/firewire/fw-topology.h b/drivers/firewire/fw-topology.h
index 363b6cbcd0b3..1b56b4ac7fb2 100644
--- a/drivers/firewire/fw-topology.h
+++ b/drivers/firewire/fw-topology.h
@@ -20,12 +20,6 @@
20#define __fw_topology_h 20#define __fw_topology_h
21 21
22enum { 22enum {
23 FW_TOPOLOGY_A = 0x01,
24 FW_TOPOLOGY_B = 0x02,
25 FW_TOPOLOGY_MIXED = 0x03,
26};
27
28enum {
29 FW_NODE_CREATED = 0x00, 23 FW_NODE_CREATED = 0x00,
30 FW_NODE_UPDATED = 0x01, 24 FW_NODE_UPDATED = 0x01,
31 FW_NODE_DESTROYED = 0x02, 25 FW_NODE_DESTROYED = 0x02,
@@ -33,21 +27,16 @@ enum {
33 FW_NODE_LINK_OFF = 0x04, 27 FW_NODE_LINK_OFF = 0x04,
34}; 28};
35 29
36struct fw_port {
37 struct fw_node *node;
38 unsigned speed : 3; /* S100, S200, ... S3200 */
39};
40
41struct fw_node { 30struct fw_node {
42 u16 node_id; 31 u16 node_id;
43 u8 color; 32 u8 color;
44 u8 port_count; 33 u8 port_count;
45 unsigned link_on : 1; 34 u8 link_on : 1;
46 unsigned initiated_reset : 1; 35 u8 initiated_reset : 1;
47 unsigned b_path : 1; 36 u8 b_path : 1;
48 u8 phy_speed : 3; /* As in the self ID packet. */ 37 u8 phy_speed : 2; /* As in the self ID packet. */
49 u8 max_speed : 5; /* Minimum of all phy-speeds and port speeds on 38 u8 max_speed : 2; /* Minimum of all phy-speeds on the path from the
50 * the path from the local node to this node. */ 39 * local node to this node. */
51 u8 max_depth : 4; /* Maximum depth to any leaf node */ 40 u8 max_depth : 4; /* Maximum depth to any leaf node */
52 u8 max_hops : 4; /* Max hops in this sub tree */ 41 u8 max_hops : 4; /* Max hops in this sub tree */
53 atomic_t ref_count; 42 atomic_t ref_count;
@@ -58,7 +47,7 @@ struct fw_node {
58 /* Upper layer specific data. */ 47 /* Upper layer specific data. */
59 void *data; 48 void *data;
60 49
61 struct fw_port ports[0]; 50 struct fw_node *ports[0];
62}; 51};
63 52
64static inline struct fw_node * 53static inline struct fw_node *
diff --git a/drivers/firewire/fw-transaction.h b/drivers/firewire/fw-transaction.h
index acdc3be38c61..5abed193f4a6 100644
--- a/drivers/firewire/fw-transaction.h
+++ b/drivers/firewire/fw-transaction.h
@@ -81,7 +81,6 @@
81 81
82#define fw_notify(s, args...) printk(KERN_NOTICE KBUILD_MODNAME ": " s, ## args) 82#define fw_notify(s, args...) printk(KERN_NOTICE KBUILD_MODNAME ": " s, ## args)
83#define fw_error(s, args...) printk(KERN_ERR KBUILD_MODNAME ": " s, ## args) 83#define fw_error(s, args...) printk(KERN_ERR KBUILD_MODNAME ": " s, ## args)
84#define fw_debug(s, args...) printk(KERN_DEBUG KBUILD_MODNAME ": " s, ## args)
85 84
86static inline void 85static inline void
87fw_memcpy_from_be32(void *_dst, void *_src, size_t size) 86fw_memcpy_from_be32(void *_dst, void *_src, size_t size)
@@ -246,7 +245,7 @@ struct fw_card {
246 struct fw_node *irm_node; 245 struct fw_node *irm_node;
247 int color; 246 int color;
248 int gap_count; 247 int gap_count;
249 int topology_type; 248 bool beta_repeaters_present;
250 249
251 int index; 250 int index;
252 251
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index 8fbe9fdac128..3b63b0b78122 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -1,8 +1,12 @@
1# 1#
2# HID driver configuration 2# HID driver configuration
3# 3#
4menu "HID Devices" 4menuconfig HID_SUPPORT
5 bool "HID Devices"
5 depends on INPUT 6 depends on INPUT
7 default y
8
9if HID_SUPPORT
6 10
7config HID 11config HID
8 tristate "Generic HID support" 12 tristate "Generic HID support"
@@ -24,6 +28,7 @@ config HID
24 28
25config HID_DEBUG 29config HID_DEBUG
26 bool "HID debugging support" 30 bool "HID debugging support"
31 default y if !EMBEDDED
27 depends on HID 32 depends on HID
28 ---help--- 33 ---help---
29 This option lets the HID layer output diagnostics about its internal 34 This option lets the HID layer output diagnostics about its internal
@@ -38,5 +43,4 @@ config HID_DEBUG
38 43
39source "drivers/hid/usbhid/Kconfig" 44source "drivers/hid/usbhid/Kconfig"
40 45
41endmenu 46endif # HID_SUPPORT
42
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 6ec04e79f685..317cf8a7b63c 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -40,6 +40,13 @@
40#define DRIVER_DESC "HID core driver" 40#define DRIVER_DESC "HID core driver"
41#define DRIVER_LICENSE "GPL" 41#define DRIVER_LICENSE "GPL"
42 42
43#ifdef CONFIG_HID_DEBUG
44int hid_debug = 0;
45module_param_named(debug, hid_debug, bool, 0600);
46MODULE_PARM_DESC(debug, "Turn HID debugging mode on and off");
47EXPORT_SYMBOL_GPL(hid_debug);
48#endif
49
43/* 50/*
44 * Register a new report for a device. 51 * Register a new report for a device.
45 */ 52 */
@@ -78,7 +85,7 @@ static struct hid_field *hid_register_field(struct hid_report *report, unsigned
78 struct hid_field *field; 85 struct hid_field *field;
79 86
80 if (report->maxfield == HID_MAX_FIELDS) { 87 if (report->maxfield == HID_MAX_FIELDS) {
81 dbg("too many fields in report"); 88 dbg_hid("too many fields in report\n");
82 return NULL; 89 return NULL;
83 } 90 }
84 91
@@ -106,7 +113,7 @@ static int open_collection(struct hid_parser *parser, unsigned type)
106 usage = parser->local.usage[0]; 113 usage = parser->local.usage[0];
107 114
108 if (parser->collection_stack_ptr == HID_COLLECTION_STACK_SIZE) { 115 if (parser->collection_stack_ptr == HID_COLLECTION_STACK_SIZE) {
109 dbg("collection stack overflow"); 116 dbg_hid("collection stack overflow\n");
110 return -1; 117 return -1;
111 } 118 }
112 119
@@ -114,7 +121,7 @@ static int open_collection(struct hid_parser *parser, unsigned type)
114 collection = kmalloc(sizeof(struct hid_collection) * 121 collection = kmalloc(sizeof(struct hid_collection) *
115 parser->device->collection_size * 2, GFP_KERNEL); 122 parser->device->collection_size * 2, GFP_KERNEL);
116 if (collection == NULL) { 123 if (collection == NULL) {
117 dbg("failed to reallocate collection array"); 124 dbg_hid("failed to reallocate collection array\n");
118 return -1; 125 return -1;
119 } 126 }
120 memcpy(collection, parser->device->collection, 127 memcpy(collection, parser->device->collection,
@@ -150,7 +157,7 @@ static int open_collection(struct hid_parser *parser, unsigned type)
150static int close_collection(struct hid_parser *parser) 157static int close_collection(struct hid_parser *parser)
151{ 158{
152 if (!parser->collection_stack_ptr) { 159 if (!parser->collection_stack_ptr) {
153 dbg("collection stack underflow"); 160 dbg_hid("collection stack underflow\n");
154 return -1; 161 return -1;
155 } 162 }
156 parser->collection_stack_ptr--; 163 parser->collection_stack_ptr--;
@@ -178,7 +185,7 @@ static unsigned hid_lookup_collection(struct hid_parser *parser, unsigned type)
178static int hid_add_usage(struct hid_parser *parser, unsigned usage) 185static int hid_add_usage(struct hid_parser *parser, unsigned usage)
179{ 186{
180 if (parser->local.usage_index >= HID_MAX_USAGES) { 187 if (parser->local.usage_index >= HID_MAX_USAGES) {
181 dbg("usage index exceeded"); 188 dbg_hid("usage index exceeded\n");
182 return -1; 189 return -1;
183 } 190 }
184 parser->local.usage[parser->local.usage_index] = usage; 191 parser->local.usage[parser->local.usage_index] = usage;
@@ -202,12 +209,12 @@ static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsign
202 int i; 209 int i;
203 210
204 if (!(report = hid_register_report(parser->device, report_type, parser->global.report_id))) { 211 if (!(report = hid_register_report(parser->device, report_type, parser->global.report_id))) {
205 dbg("hid_register_report failed"); 212 dbg_hid("hid_register_report failed\n");
206 return -1; 213 return -1;
207 } 214 }
208 215
209 if (parser->global.logical_maximum < parser->global.logical_minimum) { 216 if (parser->global.logical_maximum < parser->global.logical_minimum) {
210 dbg("logical range invalid %d %d", parser->global.logical_minimum, parser->global.logical_maximum); 217 dbg_hid("logical range invalid %d %d\n", parser->global.logical_minimum, parser->global.logical_maximum);
211 return -1; 218 return -1;
212 } 219 }
213 220
@@ -287,7 +294,7 @@ static int hid_parser_global(struct hid_parser *parser, struct hid_item *item)
287 case HID_GLOBAL_ITEM_TAG_PUSH: 294 case HID_GLOBAL_ITEM_TAG_PUSH:
288 295
289 if (parser->global_stack_ptr == HID_GLOBAL_STACK_SIZE) { 296 if (parser->global_stack_ptr == HID_GLOBAL_STACK_SIZE) {
290 dbg("global enviroment stack overflow"); 297 dbg_hid("global enviroment stack overflow\n");
291 return -1; 298 return -1;
292 } 299 }
293 300
@@ -298,7 +305,7 @@ static int hid_parser_global(struct hid_parser *parser, struct hid_item *item)
298 case HID_GLOBAL_ITEM_TAG_POP: 305 case HID_GLOBAL_ITEM_TAG_POP:
299 306
300 if (!parser->global_stack_ptr) { 307 if (!parser->global_stack_ptr) {
301 dbg("global enviroment stack underflow"); 308 dbg_hid("global enviroment stack underflow\n");
302 return -1; 309 return -1;
303 } 310 }
304 311
@@ -342,27 +349,27 @@ static int hid_parser_global(struct hid_parser *parser, struct hid_item *item)
342 349
343 case HID_GLOBAL_ITEM_TAG_REPORT_SIZE: 350 case HID_GLOBAL_ITEM_TAG_REPORT_SIZE:
344 if ((parser->global.report_size = item_udata(item)) > 32) { 351 if ((parser->global.report_size = item_udata(item)) > 32) {
345 dbg("invalid report_size %d", parser->global.report_size); 352 dbg_hid("invalid report_size %d\n", parser->global.report_size);
346 return -1; 353 return -1;
347 } 354 }
348 return 0; 355 return 0;
349 356
350 case HID_GLOBAL_ITEM_TAG_REPORT_COUNT: 357 case HID_GLOBAL_ITEM_TAG_REPORT_COUNT:
351 if ((parser->global.report_count = item_udata(item)) > HID_MAX_USAGES) { 358 if ((parser->global.report_count = item_udata(item)) > HID_MAX_USAGES) {
352 dbg("invalid report_count %d", parser->global.report_count); 359 dbg_hid("invalid report_count %d\n", parser->global.report_count);
353 return -1; 360 return -1;
354 } 361 }
355 return 0; 362 return 0;
356 363
357 case HID_GLOBAL_ITEM_TAG_REPORT_ID: 364 case HID_GLOBAL_ITEM_TAG_REPORT_ID:
358 if ((parser->global.report_id = item_udata(item)) == 0) { 365 if ((parser->global.report_id = item_udata(item)) == 0) {
359 dbg("report_id 0 is invalid"); 366 dbg_hid("report_id 0 is invalid\n");
360 return -1; 367 return -1;
361 } 368 }
362 return 0; 369 return 0;
363 370
364 default: 371 default:
365 dbg("unknown global tag 0x%x", item->tag); 372 dbg_hid("unknown global tag 0x%x\n", item->tag);
366 return -1; 373 return -1;
367 } 374 }
368} 375}
@@ -377,7 +384,7 @@ static int hid_parser_local(struct hid_parser *parser, struct hid_item *item)
377 unsigned n; 384 unsigned n;
378 385
379 if (item->size == 0) { 386 if (item->size == 0) {
380 dbg("item data expected for local item"); 387 dbg_hid("item data expected for local item\n");
381 return -1; 388 return -1;
382 } 389 }
383 390
@@ -395,14 +402,14 @@ static int hid_parser_local(struct hid_parser *parser, struct hid_item *item)
395 * items and the first delimiter set. 402 * items and the first delimiter set.
396 */ 403 */
397 if (parser->local.delimiter_depth != 0) { 404 if (parser->local.delimiter_depth != 0) {
398 dbg("nested delimiters"); 405 dbg_hid("nested delimiters\n");
399 return -1; 406 return -1;
400 } 407 }
401 parser->local.delimiter_depth++; 408 parser->local.delimiter_depth++;
402 parser->local.delimiter_branch++; 409 parser->local.delimiter_branch++;
403 } else { 410 } else {
404 if (parser->local.delimiter_depth < 1) { 411 if (parser->local.delimiter_depth < 1) {
405 dbg("bogus close delimiter"); 412 dbg_hid("bogus close delimiter\n");
406 return -1; 413 return -1;
407 } 414 }
408 parser->local.delimiter_depth--; 415 parser->local.delimiter_depth--;
@@ -412,7 +419,7 @@ static int hid_parser_local(struct hid_parser *parser, struct hid_item *item)
412 case HID_LOCAL_ITEM_TAG_USAGE: 419 case HID_LOCAL_ITEM_TAG_USAGE:
413 420
414 if (parser->local.delimiter_branch > 1) { 421 if (parser->local.delimiter_branch > 1) {
415 dbg("alternative usage ignored"); 422 dbg_hid("alternative usage ignored\n");
416 return 0; 423 return 0;
417 } 424 }
418 425
@@ -424,7 +431,7 @@ static int hid_parser_local(struct hid_parser *parser, struct hid_item *item)
424 case HID_LOCAL_ITEM_TAG_USAGE_MINIMUM: 431 case HID_LOCAL_ITEM_TAG_USAGE_MINIMUM:
425 432
426 if (parser->local.delimiter_branch > 1) { 433 if (parser->local.delimiter_branch > 1) {
427 dbg("alternative usage ignored"); 434 dbg_hid("alternative usage ignored\n");
428 return 0; 435 return 0;
429 } 436 }
430 437
@@ -437,7 +444,7 @@ static int hid_parser_local(struct hid_parser *parser, struct hid_item *item)
437 case HID_LOCAL_ITEM_TAG_USAGE_MAXIMUM: 444 case HID_LOCAL_ITEM_TAG_USAGE_MAXIMUM:
438 445
439 if (parser->local.delimiter_branch > 1) { 446 if (parser->local.delimiter_branch > 1) {
440 dbg("alternative usage ignored"); 447 dbg_hid("alternative usage ignored\n");
441 return 0; 448 return 0;
442 } 449 }
443 450
@@ -446,14 +453,14 @@ static int hid_parser_local(struct hid_parser *parser, struct hid_item *item)
446 453
447 for (n = parser->local.usage_minimum; n <= data; n++) 454 for (n = parser->local.usage_minimum; n <= data; n++)
448 if (hid_add_usage(parser, n)) { 455 if (hid_add_usage(parser, n)) {
449 dbg("hid_add_usage failed\n"); 456 dbg_hid("hid_add_usage failed\n");
450 return -1; 457 return -1;
451 } 458 }
452 return 0; 459 return 0;
453 460
454 default: 461 default:
455 462
456 dbg("unknown local item tag 0x%x", item->tag); 463 dbg_hid("unknown local item tag 0x%x\n", item->tag);
457 return 0; 464 return 0;
458 } 465 }
459 return 0; 466 return 0;
@@ -487,7 +494,7 @@ static int hid_parser_main(struct hid_parser *parser, struct hid_item *item)
487 ret = hid_add_field(parser, HID_FEATURE_REPORT, data); 494 ret = hid_add_field(parser, HID_FEATURE_REPORT, data);
488 break; 495 break;
489 default: 496 default:
490 dbg("unknown main item tag 0x%x", item->tag); 497 dbg_hid("unknown main item tag 0x%x\n", item->tag);
491 ret = 0; 498 ret = 0;
492 } 499 }
493 500
@@ -502,7 +509,7 @@ static int hid_parser_main(struct hid_parser *parser, struct hid_item *item)
502 509
503static int hid_parser_reserved(struct hid_parser *parser, struct hid_item *item) 510static int hid_parser_reserved(struct hid_parser *parser, struct hid_item *item)
504{ 511{
505 dbg("reserved item type, tag 0x%x", item->tag); 512 dbg_hid("reserved item type, tag 0x%x\n", item->tag);
506 return 0; 513 return 0;
507} 514}
508 515
@@ -667,14 +674,14 @@ struct hid_device *hid_parse_report(__u8 *start, unsigned size)
667 while ((start = fetch_item(start, end, &item)) != NULL) { 674 while ((start = fetch_item(start, end, &item)) != NULL) {
668 675
669 if (item.format != HID_ITEM_FORMAT_SHORT) { 676 if (item.format != HID_ITEM_FORMAT_SHORT) {
670 dbg("unexpected long global item"); 677 dbg_hid("unexpected long global item\n");
671 hid_free_device(device); 678 hid_free_device(device);
672 vfree(parser); 679 vfree(parser);
673 return NULL; 680 return NULL;
674 } 681 }
675 682
676 if (dispatch_type[item.type](parser, &item)) { 683 if (dispatch_type[item.type](parser, &item)) {
677 dbg("item %u %u %u %u parsing failed\n", 684 dbg_hid("item %u %u %u %u parsing failed\n",
678 item.format, (unsigned)item.size, (unsigned)item.type, (unsigned)item.tag); 685 item.format, (unsigned)item.size, (unsigned)item.type, (unsigned)item.tag);
679 hid_free_device(device); 686 hid_free_device(device);
680 vfree(parser); 687 vfree(parser);
@@ -683,13 +690,13 @@ struct hid_device *hid_parse_report(__u8 *start, unsigned size)
683 690
684 if (start == end) { 691 if (start == end) {
685 if (parser->collection_stack_ptr) { 692 if (parser->collection_stack_ptr) {
686 dbg("unbalanced collection at end of report description"); 693 dbg_hid("unbalanced collection at end of report description\n");
687 hid_free_device(device); 694 hid_free_device(device);
688 vfree(parser); 695 vfree(parser);
689 return NULL; 696 return NULL;
690 } 697 }
691 if (parser->local.delimiter_depth) { 698 if (parser->local.delimiter_depth) {
692 dbg("unbalanced delimiter at end of report description"); 699 dbg_hid("unbalanced delimiter at end of report description\n");
693 hid_free_device(device); 700 hid_free_device(device);
694 vfree(parser); 701 vfree(parser);
695 return NULL; 702 return NULL;
@@ -699,7 +706,7 @@ struct hid_device *hid_parse_report(__u8 *start, unsigned size)
699 } 706 }
700 } 707 }
701 708
702 dbg("item fetching failed at offset %d\n", (int)(end - start)); 709 dbg_hid("item fetching failed at offset %d\n", (int)(end - start));
703 hid_free_device(device); 710 hid_free_device(device);
704 vfree(parser); 711 vfree(parser);
705 return NULL; 712 return NULL;
@@ -915,13 +922,13 @@ int hid_set_field(struct hid_field *field, unsigned offset, __s32 value)
915 hid_dump_input(field->usage + offset, value); 922 hid_dump_input(field->usage + offset, value);
916 923
917 if (offset >= field->report_count) { 924 if (offset >= field->report_count) {
918 dbg("offset (%d) exceeds report_count (%d)", offset, field->report_count); 925 dbg_hid("offset (%d) exceeds report_count (%d)\n", offset, field->report_count);
919 hid_dump_field(field, 8); 926 hid_dump_field(field, 8);
920 return -1; 927 return -1;
921 } 928 }
922 if (field->logical_minimum < 0) { 929 if (field->logical_minimum < 0) {
923 if (value != snto32(s32ton(value, size), size)) { 930 if (value != snto32(s32ton(value, size), size)) {
924 dbg("value %d is out of range", value); 931 dbg_hid("value %d is out of range\n", value);
925 return -1; 932 return -1;
926 } 933 }
927 } 934 }
@@ -934,19 +941,17 @@ int hid_input_report(struct hid_device *hid, int type, u8 *data, int size, int i
934{ 941{
935 struct hid_report_enum *report_enum = hid->report_enum + type; 942 struct hid_report_enum *report_enum = hid->report_enum + type;
936 struct hid_report *report; 943 struct hid_report *report;
937 int n, rsize; 944 int n, rsize, i;
938 945
939 if (!hid) 946 if (!hid)
940 return -ENODEV; 947 return -ENODEV;
941 948
942 if (!size) { 949 if (!size) {
943 dbg("empty report"); 950 dbg_hid("empty report\n");
944 return -1; 951 return -1;
945 } 952 }
946 953
947#ifdef CONFIG_HID_DEBUG 954 dbg_hid("report (size %u) (%snumbered)\n", size, report_enum->numbered ? "" : "un");
948 printk(KERN_DEBUG __FILE__ ": report (size %u) (%snumbered)\n", size, report_enum->numbered ? "" : "un");
949#endif
950 955
951 n = 0; /* Normally report number is 0 */ 956 n = 0; /* Normally report number is 0 */
952 if (report_enum->numbered) { /* Device uses numbered reports, data[0] is report number */ 957 if (report_enum->numbered) { /* Device uses numbered reports, data[0] is report number */
@@ -954,25 +959,21 @@ int hid_input_report(struct hid_device *hid, int type, u8 *data, int size, int i
954 size--; 959 size--;
955 } 960 }
956 961
957#ifdef CONFIG_HID_DEBUG 962 /* dump the report descriptor */
958 { 963 dbg_hid("report %d (size %u) = ", n, size);
959 int i; 964 for (i = 0; i < size; i++)
960 printk(KERN_DEBUG __FILE__ ": report %d (size %u) = ", n, size); 965 dbg_hid_line(" %02x", data[i]);
961 for (i = 0; i < size; i++) 966 dbg_hid_line("\n");
962 printk(" %02x", data[i]);
963 printk("\n");
964 }
965#endif
966 967
967 if (!(report = report_enum->report_id_hash[n])) { 968 if (!(report = report_enum->report_id_hash[n])) {
968 dbg("undefined report_id %d received", n); 969 dbg_hid("undefined report_id %d received\n", n);
969 return -1; 970 return -1;
970 } 971 }
971 972
972 rsize = ((report->size - 1) >> 3) + 1; 973 rsize = ((report->size - 1) >> 3) + 1;
973 974
974 if (size < rsize) { 975 if (size < rsize) {
975 dbg("report %d is too short, (%d < %d)", report->id, size, rsize); 976 dbg_hid("report %d is too short, (%d < %d)\n", report->id, size, rsize);
976 memset(data + size, 0, rsize - size); 977 memset(data + size, 0, rsize - size);
977 } 978 }
978 979
diff --git a/drivers/hid/hid-debug.c b/drivers/hid/hid-debug.c
index 83c4126b37c3..a13757b78980 100644
--- a/drivers/hid/hid-debug.c
+++ b/drivers/hid/hid-debug.c
@@ -347,6 +347,9 @@ static void resolv_usage_page(unsigned page) {
347void hid_resolv_usage(unsigned usage) { 347void hid_resolv_usage(unsigned usage) {
348 const struct hid_usage_entry *p; 348 const struct hid_usage_entry *p;
349 349
350 if (!hid_debug)
351 return;
352
350 resolv_usage_page(usage >> 16); 353 resolv_usage_page(usage >> 16);
351 printk("."); 354 printk(".");
352 for (p = hid_usage_table; p->description; p++) 355 for (p = hid_usage_table; p->description; p++)
@@ -369,6 +372,9 @@ __inline__ static void tab(int n) {
369void hid_dump_field(struct hid_field *field, int n) { 372void hid_dump_field(struct hid_field *field, int n) {
370 int j; 373 int j;
371 374
375 if (!hid_debug)
376 return;
377
372 if (field->physical) { 378 if (field->physical) {
373 tab(n); 379 tab(n);
374 printk("Physical("); 380 printk("Physical(");
@@ -466,6 +472,9 @@ void hid_dump_device(struct hid_device *device) {
466 unsigned i,k; 472 unsigned i,k;
467 static char *table[] = {"INPUT", "OUTPUT", "FEATURE"}; 473 static char *table[] = {"INPUT", "OUTPUT", "FEATURE"};
468 474
475 if (!hid_debug)
476 return;
477
469 for (i = 0; i < HID_REPORT_TYPES; i++) { 478 for (i = 0; i < HID_REPORT_TYPES; i++) {
470 report_enum = device->report_enum + i; 479 report_enum = device->report_enum + i;
471 list = report_enum->report_list.next; 480 list = report_enum->report_list.next;
@@ -489,6 +498,9 @@ void hid_dump_device(struct hid_device *device) {
489EXPORT_SYMBOL_GPL(hid_dump_device); 498EXPORT_SYMBOL_GPL(hid_dump_device);
490 499
491void hid_dump_input(struct hid_usage *usage, __s32 value) { 500void hid_dump_input(struct hid_usage *usage, __s32 value) {
501 if (!hid_debug)
502 return;
503
492 printk("hid-debug: input "); 504 printk("hid-debug: input ");
493 hid_resolv_usage(usage->hid); 505 hid_resolv_usage(usage->hid);
494 printk(" = %d\n", value); 506 printk(" = %d\n", value);
@@ -758,6 +770,9 @@ static char **names[EV_MAX + 1] = {
758 770
759void hid_resolv_event(__u8 type, __u16 code) { 771void hid_resolv_event(__u8 type, __u16 code) {
760 772
773 if (!hid_debug)
774 return;
775
761 printk("%s.%s", events[type] ? events[type] : "?", 776 printk("%s.%s", events[type] ? events[type] : "?",
762 names[type] ? (names[type][code] ? names[type][code] : "?") : "?"); 777 names[type] ? (names[type][code] ? names[type][code] : "?") : "?");
763} 778}
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index 7f817897b178..8edbd30cf795 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -60,6 +60,19 @@ static const unsigned char hid_keyboard[256] = {
60 150,158,159,128,136,177,178,176,142,152,173,140,unk,unk,unk,unk 60 150,158,159,128,136,177,178,176,142,152,173,140,unk,unk,unk,unk
61}; 61};
62 62
63/* extended mapping for certain Logitech hardware (Logitech cordless desktop LX500) */
64#define LOGITECH_EXPANDED_KEYMAP_SIZE 80
65static int logitech_expanded_keymap[LOGITECH_EXPANDED_KEYMAP_SIZE] = {
66 0,216, 0,213,175,156, 0, 0, 0, 0,
67 144, 0, 0, 0, 0, 0, 0, 0, 0,212,
68 174,167,152,161,112, 0, 0, 0,154, 0,
69 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
70 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
71 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
72 0, 0, 0, 0, 0,183,184,185,186,187,
73 188,189,190,191,192,193,194, 0, 0, 0
74};
75
63static const struct { 76static const struct {
64 __s32 x; 77 __s32 x;
65 __s32 y; 78 __s32 y;
@@ -308,9 +321,7 @@ static int hidinput_setkeycode(struct input_dev *dev, int scancode,
308 321
309 clear_bit(old_keycode, dev->keybit); 322 clear_bit(old_keycode, dev->keybit);
310 set_bit(usage->code, dev->keybit); 323 set_bit(usage->code, dev->keybit);
311#ifdef CONFIG_HID_DEBUG 324 dbg_hid(KERN_DEBUG "Assigned keycode %d to HID usage code %x\n", keycode, scancode);
312 printk (KERN_DEBUG "Assigned keycode %d to HID usage code %x\n", keycode, scancode);
313#endif
314 /* Set the keybit for the old keycode if the old keycode is used 325 /* Set the keybit for the old keycode if the old keycode is used
315 * by another key */ 326 * by another key */
316 if (hidinput_find_key (hid, 0, old_keycode)) 327 if (hidinput_find_key (hid, 0, old_keycode))
@@ -333,11 +344,9 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
333 344
334 field->hidinput = hidinput; 345 field->hidinput = hidinput;
335 346
336#ifdef CONFIG_HID_DEBUG 347 dbg_hid("Mapping: ");
337 printk(KERN_DEBUG "Mapping: ");
338 hid_resolv_usage(usage->hid); 348 hid_resolv_usage(usage->hid);
339 printk(" ---> "); 349 dbg_hid_line(" ---> ");
340#endif
341 350
342 if (field->flags & HID_MAIN_ITEM_CONSTANT) 351 if (field->flags & HID_MAIN_ITEM_CONSTANT)
343 goto ignore; 352 goto ignore;
@@ -378,6 +387,21 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
378 } 387 }
379 } 388 }
380 389
390 /* Special handling for Logitech Cordless Desktop */
391 if (field->application != HID_GD_MOUSE) {
392 if (device->quirks & HID_QUIRK_LOGITECH_EXPANDED_KEYMAP) {
393 int hid = usage->hid & HID_USAGE;
394 if (hid < LOGITECH_EXPANDED_KEYMAP_SIZE && logitech_expanded_keymap[hid] != 0)
395 code = logitech_expanded_keymap[hid];
396 }
397 } else {
398 if (device->quirks & HID_QUIRK_LOGITECH_IGNORE_DOUBLED_WHEEL) {
399 int hid = usage->hid & HID_USAGE;
400 if (hid == 7 || hid == 8)
401 goto ignore;
402 }
403 }
404
381 map_key(code); 405 map_key(code);
382 break; 406 break;
383 407
@@ -566,6 +590,11 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
566 case 0x0e5: map_key_clear(KEY_BASSBOOST); break; 590 case 0x0e5: map_key_clear(KEY_BASSBOOST); break;
567 case 0x0e9: map_key_clear(KEY_VOLUMEUP); break; 591 case 0x0e9: map_key_clear(KEY_VOLUMEUP); break;
568 case 0x0ea: map_key_clear(KEY_VOLUMEDOWN); break; 592 case 0x0ea: map_key_clear(KEY_VOLUMEDOWN); break;
593
594 /* reserved in HUT 1.12. Reported on Petalynx remote */
595 case 0x0f6: map_key_clear(KEY_NEXT); break;
596 case 0x0fa: map_key_clear(KEY_BACK); break;
597
569 case 0x183: map_key_clear(KEY_CONFIG); break; 598 case 0x183: map_key_clear(KEY_CONFIG); break;
570 case 0x184: map_key_clear(KEY_WORDPROCESSOR); break; 599 case 0x184: map_key_clear(KEY_WORDPROCESSOR); break;
571 case 0x185: map_key_clear(KEY_EDITOR); break; 600 case 0x185: map_key_clear(KEY_EDITOR); break;
@@ -598,7 +627,9 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
598 case 0x21b: map_key_clear(KEY_COPY); break; 627 case 0x21b: map_key_clear(KEY_COPY); break;
599 case 0x21c: map_key_clear(KEY_CUT); break; 628 case 0x21c: map_key_clear(KEY_CUT); break;
600 case 0x21d: map_key_clear(KEY_PASTE); break; 629 case 0x21d: map_key_clear(KEY_PASTE); break;
601 case 0x221: map_key_clear(KEY_FIND); break; 630 case 0x21f: map_key_clear(KEY_FIND); break;
631 case 0x221: map_key_clear(KEY_SEARCH); break;
632 case 0x222: map_key_clear(KEY_GOTO); break;
602 case 0x223: map_key_clear(KEY_HOMEPAGE); break; 633 case 0x223: map_key_clear(KEY_HOMEPAGE); break;
603 case 0x224: map_key_clear(KEY_BACK); break; 634 case 0x224: map_key_clear(KEY_BACK); break;
604 case 0x225: map_key_clear(KEY_FORWARD); break; 635 case 0x225: map_key_clear(KEY_FORWARD); break;
@@ -688,7 +719,28 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
688 break; 719 break;
689 720
690 case HID_UP_MSVENDOR: 721 case HID_UP_MSVENDOR:
691 goto ignore; 722
723 /* special case - Chicony Chicony KU-0418 tactical pad */
724 if (device->vendor == 0x04f2 && device->product == 0x0418) {
725 set_bit(EV_REP, input->evbit);
726 switch(usage->hid & HID_USAGE) {
727 case 0xff01: map_key_clear(BTN_1); break;
728 case 0xff02: map_key_clear(BTN_2); break;
729 case 0xff03: map_key_clear(BTN_3); break;
730 case 0xff04: map_key_clear(BTN_4); break;
731 case 0xff05: map_key_clear(BTN_5); break;
732 case 0xff06: map_key_clear(BTN_6); break;
733 case 0xff07: map_key_clear(BTN_7); break;
734 case 0xff08: map_key_clear(BTN_8); break;
735 case 0xff09: map_key_clear(BTN_9); break;
736 case 0xff0a: map_key_clear(BTN_A); break;
737 case 0xff0b: map_key_clear(BTN_B); break;
738 default: goto ignore;
739 }
740 } else {
741 goto ignore;
742 }
743 break;
692 744
693 case HID_UP_CUSTOM: /* Reported on Logitech and Powerbook USB keyboards */ 745 case HID_UP_CUSTOM: /* Reported on Logitech and Powerbook USB keyboards */
694 746
@@ -704,10 +756,10 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
704 } 756 }
705 break; 757 break;
706 758
707 case HID_UP_LOGIVENDOR: /* Reported on Logitech Ultra X Media Remote */ 759 case HID_UP_LOGIVENDOR:
708
709 set_bit(EV_REP, input->evbit); 760 set_bit(EV_REP, input->evbit);
710 switch(usage->hid & HID_USAGE) { 761 switch(usage->hid & HID_USAGE) {
762 /* Reported on Logitech Ultra X Media Remote */
711 case 0x004: map_key_clear(KEY_AGAIN); break; 763 case 0x004: map_key_clear(KEY_AGAIN); break;
712 case 0x00d: map_key_clear(KEY_HOME); break; 764 case 0x00d: map_key_clear(KEY_HOME); break;
713 case 0x024: map_key_clear(KEY_SHUFFLE); break; 765 case 0x024: map_key_clear(KEY_SHUFFLE); break;
@@ -725,6 +777,14 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
725 case 0x04d: map_key_clear(KEY_SUBTITLE); break; 777 case 0x04d: map_key_clear(KEY_SUBTITLE); break;
726 case 0x051: map_key_clear(KEY_RED); break; 778 case 0x051: map_key_clear(KEY_RED); break;
727 case 0x052: map_key_clear(KEY_CLOSE); break; 779 case 0x052: map_key_clear(KEY_CLOSE); break;
780
781 /* Reported on Petalynx Maxter remote */
782 case 0x05a: map_key_clear(KEY_TEXT); break;
783 case 0x05b: map_key_clear(KEY_RED); break;
784 case 0x05c: map_key_clear(KEY_GREEN); break;
785 case 0x05d: map_key_clear(KEY_YELLOW); break;
786 case 0x05e: map_key_clear(KEY_BLUE); break;
787
728 default: goto ignore; 788 default: goto ignore;
729 } 789 }
730 break; 790 break;
@@ -818,16 +878,24 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
818 field->dpad = usage->code; 878 field->dpad = usage->code;
819 } 879 }
820 880
881 /* for those devices which produce Consumer volume usage as relative,
882 * we emulate pressing volumeup/volumedown appropriate number of times
883 * in hidinput_hid_event()
884 */
885 if ((usage->type == EV_ABS) && (field->flags & HID_MAIN_ITEM_RELATIVE) &&
886 (usage->code == ABS_VOLUME)) {
887 set_bit(KEY_VOLUMEUP, input->keybit);
888 set_bit(KEY_VOLUMEDOWN, input->keybit);
889 }
890
821 hid_resolv_event(usage->type, usage->code); 891 hid_resolv_event(usage->type, usage->code);
822#ifdef CONFIG_HID_DEBUG 892
823 printk("\n"); 893 dbg_hid_line("\n");
824#endif 894
825 return; 895 return;
826 896
827ignore: 897ignore:
828#ifdef CONFIG_HID_DEBUG 898 dbg_hid_line("IGNORED\n");
829 printk("IGNORED\n");
830#endif
831 return; 899 return;
832} 900}
833 901
@@ -896,18 +964,33 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct
896 } 964 }
897 965
898 if (usage->hid == (HID_UP_PID | 0x83UL)) { /* Simultaneous Effects Max */ 966 if (usage->hid == (HID_UP_PID | 0x83UL)) { /* Simultaneous Effects Max */
899 dbg("Maximum Effects - %d",value); 967 dbg_hid("Maximum Effects - %d\n",value);
900 return; 968 return;
901 } 969 }
902 970
903 if (usage->hid == (HID_UP_PID | 0x7fUL)) { 971 if (usage->hid == (HID_UP_PID | 0x7fUL)) {
904 dbg("PID Pool Report\n"); 972 dbg_hid("PID Pool Report\n");
905 return; 973 return;
906 } 974 }
907 975
908 if ((usage->type == EV_KEY) && (usage->code == 0)) /* Key 0 is "unassigned", not KEY_UNKNOWN */ 976 if ((usage->type == EV_KEY) && (usage->code == 0)) /* Key 0 is "unassigned", not KEY_UNKNOWN */
909 return; 977 return;
910 978
979 if ((usage->type == EV_ABS) && (field->flags & HID_MAIN_ITEM_RELATIVE) &&
980 (usage->code == ABS_VOLUME)) {
981 int count = abs(value);
982 int direction = value > 0 ? KEY_VOLUMEUP : KEY_VOLUMEDOWN;
983 int i;
984
985 for (i = 0; i < count; i++) {
986 input_event(input, EV_KEY, direction, 1);
987 input_sync(input);
988 input_event(input, EV_KEY, direction, 0);
989 input_sync(input);
990 }
991 return;
992 }
993
911 input_event(input, usage->type, usage->code, value); 994 input_event(input, usage->type, usage->code, value);
912 995
913 if ((field->flags & HID_MAIN_ITEM_RELATIVE) && (usage->type == EV_KEY)) 996 if ((field->flags & HID_MAIN_ITEM_RELATIVE) && (usage->type == EV_KEY))
@@ -976,7 +1059,7 @@ int hidinput_connect(struct hid_device *hid)
976 if (IS_INPUT_APPLICATION(hid->collection[i].usage)) 1059 if (IS_INPUT_APPLICATION(hid->collection[i].usage))
977 break; 1060 break;
978 1061
979 if (i == hid->maxcollection) 1062 if (i == hid->maxcollection && (hid->quirks & HID_QUIRK_HIDINPUT) == 0)
980 return -1; 1063 return -1;
981 1064
982 if (hid->quirks & HID_QUIRK_SKIP_OUTPUT_REPORTS) 1065 if (hid->quirks & HID_QUIRK_SKIP_OUTPUT_REPORTS)
@@ -994,7 +1077,7 @@ int hidinput_connect(struct hid_device *hid)
994 if (!hidinput || !input_dev) { 1077 if (!hidinput || !input_dev) {
995 kfree(hidinput); 1078 kfree(hidinput);
996 input_free_device(input_dev); 1079 input_free_device(input_dev);
997 err("Out of memory during hid input probe"); 1080 err_hid("Out of memory during hid input probe");
998 return -1; 1081 return -1;
999 } 1082 }
1000 1083
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index d91b9dac6dff..3afa4a5035b7 100644
--- a/drivers/hid/usbhid/hid-core.c
+++ b/drivers/hid/usbhid/hid-core.c
@@ -60,6 +60,12 @@ MODULE_PARM_DESC(quirks, "Add/modify USB HID quirks by specifying "
60 " quirks=vendorID:productID:quirks" 60 " quirks=vendorID:productID:quirks"
61 " where vendorID, productID, and quirks are all in" 61 " where vendorID, productID, and quirks are all in"
62 " 0x-prefixed hex"); 62 " 0x-prefixed hex");
63static char *rdesc_quirks_param[MAX_USBHID_BOOT_QUIRKS] = { [ 0 ... (MAX_USBHID_BOOT_QUIRKS - 1) ] = NULL };
64module_param_array_named(rdesc_quirks, rdesc_quirks_param, charp, NULL, 0444);
65MODULE_PARM_DESC(rdesc_quirks, "Add/modify report descriptor quirks by specifying "
66 " rdesc_quirks=vendorID:productID:rdesc_quirks"
67 " where vendorID, productID, and rdesc_quirks are all in"
68 " 0x-prefixed hex");
63/* 69/*
64 * Input submission and I/O error handler. 70 * Input submission and I/O error handler.
65 */ 71 */
@@ -127,7 +133,7 @@ static void hid_reset(struct work_struct *work)
127 hid_io_error(hid); 133 hid_io_error(hid);
128 break; 134 break;
129 default: 135 default:
130 err("can't reset device, %s-%s/input%d, status %d", 136 err_hid("can't reset device, %s-%s/input%d, status %d",
131 hid_to_usb_dev(hid)->bus->bus_name, 137 hid_to_usb_dev(hid)->bus->bus_name,
132 hid_to_usb_dev(hid)->devpath, 138 hid_to_usb_dev(hid)->devpath,
133 usbhid->ifnum, rc); 139 usbhid->ifnum, rc);
@@ -220,7 +226,7 @@ static void hid_irq_in(struct urb *urb)
220 if (status) { 226 if (status) {
221 clear_bit(HID_IN_RUNNING, &usbhid->iofl); 227 clear_bit(HID_IN_RUNNING, &usbhid->iofl);
222 if (status != -EPERM) { 228 if (status != -EPERM) {
223 err("can't resubmit intr, %s-%s/input%d, status %d", 229 err_hid("can't resubmit intr, %s-%s/input%d, status %d",
224 hid_to_usb_dev(hid)->bus->bus_name, 230 hid_to_usb_dev(hid)->bus->bus_name,
225 hid_to_usb_dev(hid)->devpath, 231 hid_to_usb_dev(hid)->devpath,
226 usbhid->ifnum, status); 232 usbhid->ifnum, status);
@@ -240,10 +246,10 @@ static int hid_submit_out(struct hid_device *hid)
240 usbhid->urbout->transfer_buffer_length = ((report->size - 1) >> 3) + 1 + (report->id > 0); 246 usbhid->urbout->transfer_buffer_length = ((report->size - 1) >> 3) + 1 + (report->id > 0);
241 usbhid->urbout->dev = hid_to_usb_dev(hid); 247 usbhid->urbout->dev = hid_to_usb_dev(hid);
242 248
243 dbg("submitting out urb"); 249 dbg_hid("submitting out urb\n");
244 250
245 if (usb_submit_urb(usbhid->urbout, GFP_ATOMIC)) { 251 if (usb_submit_urb(usbhid->urbout, GFP_ATOMIC)) {
246 err("usb_submit_urb(out) failed"); 252 err_hid("usb_submit_urb(out) failed");
247 return -1; 253 return -1;
248 } 254 }
249 255
@@ -287,12 +293,12 @@ static int hid_submit_ctrl(struct hid_device *hid)
287 usbhid->cr->wIndex = cpu_to_le16(usbhid->ifnum); 293 usbhid->cr->wIndex = cpu_to_le16(usbhid->ifnum);
288 usbhid->cr->wLength = cpu_to_le16(len); 294 usbhid->cr->wLength = cpu_to_le16(len);
289 295
290 dbg("submitting ctrl urb: %s wValue=0x%04x wIndex=0x%04x wLength=%u", 296 dbg_hid("submitting ctrl urb: %s wValue=0x%04x wIndex=0x%04x wLength=%u\n",
291 usbhid->cr->bRequest == HID_REQ_SET_REPORT ? "Set_Report" : "Get_Report", 297 usbhid->cr->bRequest == HID_REQ_SET_REPORT ? "Set_Report" : "Get_Report",
292 usbhid->cr->wValue, usbhid->cr->wIndex, usbhid->cr->wLength); 298 usbhid->cr->wValue, usbhid->cr->wIndex, usbhid->cr->wLength);
293 299
294 if (usb_submit_urb(usbhid->urbctrl, GFP_ATOMIC)) { 300 if (usb_submit_urb(usbhid->urbctrl, GFP_ATOMIC)) {
295 err("usb_submit_urb(ctrl) failed"); 301 err_hid("usb_submit_urb(ctrl) failed");
296 return -1; 302 return -1;
297 } 303 }
298 304
@@ -474,7 +480,7 @@ int usbhid_wait_io(struct hid_device *hid)
474 if (!wait_event_timeout(hid->wait, (!test_bit(HID_CTRL_RUNNING, &usbhid->iofl) && 480 if (!wait_event_timeout(hid->wait, (!test_bit(HID_CTRL_RUNNING, &usbhid->iofl) &&
475 !test_bit(HID_OUT_RUNNING, &usbhid->iofl)), 481 !test_bit(HID_OUT_RUNNING, &usbhid->iofl)),
476 10*HZ)) { 482 10*HZ)) {
477 dbg("timeout waiting for ctrl or out queue to clear"); 483 dbg_hid("timeout waiting for ctrl or out queue to clear\n");
478 return -1; 484 return -1;
479 } 485 }
480 486
@@ -633,20 +639,6 @@ static void hid_free_buffers(struct usb_device *dev, struct hid_device *hid)
633} 639}
634 640
635/* 641/*
636 * Cherry Cymotion keyboard have an invalid HID report descriptor,
637 * that needs fixing before we can parse it.
638 */
639
640static void hid_fixup_cymotion_descriptor(char *rdesc, int rsize)
641{
642 if (rsize >= 17 && rdesc[11] == 0x3c && rdesc[12] == 0x02) {
643 info("Fixing up Cherry Cymotion report descriptor");
644 rdesc[11] = rdesc[16] = 0xff;
645 rdesc[12] = rdesc[17] = 0x03;
646 }
647}
648
649/*
650 * Sending HID_REQ_GET_REPORT changes the operation mode of the ps3 controller 642 * Sending HID_REQ_GET_REPORT changes the operation mode of the ps3 controller
651 * to "operational". Without this, the ps3 controller will not report any 643 * to "operational". Without this, the ps3 controller will not report any
652 * events. 644 * events.
@@ -667,51 +659,11 @@ static void hid_fixup_sony_ps3_controller(struct usb_device *dev, int ifnum)
667 USB_CTRL_GET_TIMEOUT); 659 USB_CTRL_GET_TIMEOUT);
668 660
669 if (result < 0) 661 if (result < 0)
670 err("%s failed: %d\n", __func__, result); 662 err_hid("%s failed: %d\n", __func__, result);
671 663
672 kfree(buf); 664 kfree(buf);
673} 665}
674 666
675/*
676 * Certain Logitech keyboards send in report #3 keys which are far
677 * above the logical maximum described in descriptor. This extends
678 * the original value of 0x28c of logical maximum to 0x104d
679 */
680static void hid_fixup_logitech_descriptor(unsigned char *rdesc, int rsize)
681{
682 if (rsize >= 90 && rdesc[83] == 0x26
683 && rdesc[84] == 0x8c
684 && rdesc[85] == 0x02) {
685 info("Fixing up Logitech keyboard report descriptor");
686 rdesc[84] = rdesc[89] = 0x4d;
687 rdesc[85] = rdesc[90] = 0x10;
688 }
689}
690
691/*
692 * Some USB barcode readers from cypress have usage min and usage max in
693 * the wrong order
694 */
695static void hid_fixup_cypress_descriptor(unsigned char *rdesc, int rsize)
696{
697 short fixed = 0;
698 int i;
699
700 for (i = 0; i < rsize - 4; i++) {
701 if (rdesc[i] == 0x29 && rdesc [i+2] == 0x19) {
702 unsigned char tmp;
703
704 rdesc[i] = 0x19; rdesc[i+2] = 0x29;
705 tmp = rdesc[i+3];
706 rdesc[i+3] = rdesc[i+1];
707 rdesc[i+1] = tmp;
708 }
709 }
710
711 if (fixed)
712 info("Fixing up Cypress report descriptor");
713}
714
715static struct hid_device *usb_hid_configure(struct usb_interface *intf) 667static struct hid_device *usb_hid_configure(struct usb_interface *intf)
716{ 668{
717 struct usb_host_interface *interface = intf->cur_altsetting; 669 struct usb_host_interface *interface = intf->cur_altsetting;
@@ -746,7 +698,7 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
746 if (usb_get_extra_descriptor(interface, HID_DT_HID, &hdesc) && 698 if (usb_get_extra_descriptor(interface, HID_DT_HID, &hdesc) &&
747 (!interface->desc.bNumEndpoints || 699 (!interface->desc.bNumEndpoints ||
748 usb_get_extra_descriptor(&interface->endpoint[0], HID_DT_HID, &hdesc))) { 700 usb_get_extra_descriptor(&interface->endpoint[0], HID_DT_HID, &hdesc))) {
749 dbg("class descriptor not present\n"); 701 dbg_hid("class descriptor not present\n");
750 return NULL; 702 return NULL;
751 } 703 }
752 704
@@ -755,41 +707,34 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
755 rsize = le16_to_cpu(hdesc->desc[n].wDescriptorLength); 707 rsize = le16_to_cpu(hdesc->desc[n].wDescriptorLength);
756 708
757 if (!rsize || rsize > HID_MAX_DESCRIPTOR_SIZE) { 709 if (!rsize || rsize > HID_MAX_DESCRIPTOR_SIZE) {
758 dbg("weird size of report descriptor (%u)", rsize); 710 dbg_hid("weird size of report descriptor (%u)\n", rsize);
759 return NULL; 711 return NULL;
760 } 712 }
761 713
762 if (!(rdesc = kmalloc(rsize, GFP_KERNEL))) { 714 if (!(rdesc = kmalloc(rsize, GFP_KERNEL))) {
763 dbg("couldn't allocate rdesc memory"); 715 dbg_hid("couldn't allocate rdesc memory\n");
764 return NULL; 716 return NULL;
765 } 717 }
766 718
767 hid_set_idle(dev, interface->desc.bInterfaceNumber, 0, 0); 719 hid_set_idle(dev, interface->desc.bInterfaceNumber, 0, 0);
768 720
769 if ((n = hid_get_class_descriptor(dev, interface->desc.bInterfaceNumber, HID_DT_REPORT, rdesc, rsize)) < 0) { 721 if ((n = hid_get_class_descriptor(dev, interface->desc.bInterfaceNumber, HID_DT_REPORT, rdesc, rsize)) < 0) {
770 dbg("reading report descriptor failed"); 722 dbg_hid("reading report descriptor failed\n");
771 kfree(rdesc); 723 kfree(rdesc);
772 return NULL; 724 return NULL;
773 } 725 }
774 726
775 if ((quirks & HID_QUIRK_CYMOTION)) 727 usbhid_fixup_report_descriptor(le16_to_cpu(dev->descriptor.idVendor),
776 hid_fixup_cymotion_descriptor(rdesc, rsize); 728 le16_to_cpu(dev->descriptor.idProduct), rdesc,
729 rsize, rdesc_quirks_param);
777 730
778 if (quirks & HID_QUIRK_LOGITECH_DESCRIPTOR) 731 dbg_hid("report descriptor (size %u, read %d) = ", rsize, n);
779 hid_fixup_logitech_descriptor(rdesc, rsize);
780
781 if (quirks & HID_QUIRK_SWAPPED_MIN_MAX)
782 hid_fixup_cypress_descriptor(rdesc, rsize);
783
784#ifdef CONFIG_HID_DEBUG
785 printk(KERN_DEBUG __FILE__ ": report descriptor (size %u, read %d) = ", rsize, n);
786 for (n = 0; n < rsize; n++) 732 for (n = 0; n < rsize; n++)
787 printk(" %02x", (unsigned char) rdesc[n]); 733 dbg_hid_line(" %02x", (unsigned char) rdesc[n]);
788 printk("\n"); 734 dbg_hid_line("\n");
789#endif
790 735
791 if (!(hid = hid_parse_report(rdesc, n))) { 736 if (!(hid = hid_parse_report(rdesc, n))) {
792 dbg("parsing report descriptor failed"); 737 dbg_hid("parsing report descriptor failed\n");
793 kfree(rdesc); 738 kfree(rdesc);
794 return NULL; 739 return NULL;
795 } 740 }
@@ -861,7 +806,7 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
861 } 806 }
862 807
863 if (!usbhid->urbin) { 808 if (!usbhid->urbin) {
864 err("couldn't find an input interrupt endpoint"); 809 err_hid("couldn't find an input interrupt endpoint");
865 goto fail; 810 goto fail;
866 } 811 }
867 812
@@ -956,7 +901,7 @@ static void hid_disconnect(struct usb_interface *intf)
956 usb_kill_urb(usbhid->urbctrl); 901 usb_kill_urb(usbhid->urbctrl);
957 902
958 del_timer_sync(&usbhid->io_retry); 903 del_timer_sync(&usbhid->io_retry);
959 flush_scheduled_work(); 904 cancel_work_sync(&usbhid->reset_work);
960 905
961 if (hid->claimed & HID_CLAIMED_INPUT) 906 if (hid->claimed & HID_CLAIMED_INPUT)
962 hidinput_disconnect(hid); 907 hidinput_disconnect(hid);
@@ -978,7 +923,7 @@ static int hid_probe(struct usb_interface *intf, const struct usb_device_id *id)
978 int i; 923 int i;
979 char *c; 924 char *c;
980 925
981 dbg("HID probe called for ifnum %d", 926 dbg_hid("HID probe called for ifnum %d\n",
982 intf->altsetting->desc.bInterfaceNumber); 927 intf->altsetting->desc.bInterfaceNumber);
983 928
984 if (!(hid = usb_hid_configure(intf))) 929 if (!(hid = usb_hid_configure(intf)))
diff --git a/drivers/hid/usbhid/hid-lgff.c b/drivers/hid/usbhid/hid-lgff.c
index c5cd4107d6af..4b7ab6a46d93 100644
--- a/drivers/hid/usbhid/hid-lgff.c
+++ b/drivers/hid/usbhid/hid-lgff.c
@@ -78,7 +78,7 @@ static int hid_lgff_play(struct input_dev *dev, void *data, struct ff_effect *ef
78 report->field[0]->value[1] = 0x08; 78 report->field[0]->value[1] = 0x08;
79 report->field[0]->value[2] = x; 79 report->field[0]->value[2] = x;
80 report->field[0]->value[3] = y; 80 report->field[0]->value[3] = y;
81 dbg("(x, y)=(%04x, %04x)", x, y); 81 dbg_hid("(x, y)=(%04x, %04x)\n", x, y);
82 usbhid_submit_report(hid, report, USB_DIR_OUT); 82 usbhid_submit_report(hid, report, USB_DIR_OUT);
83 break; 83 break;
84 84
@@ -93,7 +93,7 @@ static int hid_lgff_play(struct input_dev *dev, void *data, struct ff_effect *ef
93 report->field[0]->value[1] = 0x00; 93 report->field[0]->value[1] = 0x00;
94 report->field[0]->value[2] = left; 94 report->field[0]->value[2] = left;
95 report->field[0]->value[3] = right; 95 report->field[0]->value[3] = right;
96 dbg("(left, right)=(%04x, %04x)", left, right); 96 dbg_hid("(left, right)=(%04x, %04x)\n", left, right);
97 usbhid_submit_report(hid, report, USB_DIR_OUT); 97 usbhid_submit_report(hid, report, USB_DIR_OUT);
98 break; 98 break;
99 } 99 }
@@ -113,20 +113,20 @@ int hid_lgff_init(struct hid_device* hid)
113 113
114 /* Find the report to use */ 114 /* Find the report to use */
115 if (list_empty(report_list)) { 115 if (list_empty(report_list)) {
116 err("No output report found"); 116 err_hid("No output report found");
117 return -1; 117 return -1;
118 } 118 }
119 119
120 /* Check that the report looks ok */ 120 /* Check that the report looks ok */
121 report = list_entry(report_list->next, struct hid_report, list); 121 report = list_entry(report_list->next, struct hid_report, list);
122 if (!report) { 122 if (!report) {
123 err("NULL output report"); 123 err_hid("NULL output report");
124 return -1; 124 return -1;
125 } 125 }
126 126
127 field = report->field[0]; 127 field = report->field[0];
128 if (!field) { 128 if (!field) {
129 err("NULL field"); 129 err_hid("NULL field");
130 return -1; 130 return -1;
131 } 131 }
132 132
diff --git a/drivers/hid/usbhid/hid-pidff.c b/drivers/hid/usbhid/hid-pidff.c
index f5a90e950e6b..011326178c06 100644
--- a/drivers/hid/usbhid/hid-pidff.c
+++ b/drivers/hid/usbhid/hid-pidff.c
@@ -738,6 +738,7 @@ static void pidff_autocenter(struct pidff_device *pidff, u16 magnitude)
738 pidff->set_effect[PID_TRIGGER_BUTTON].value[0] = 0; 738 pidff->set_effect[PID_TRIGGER_BUTTON].value[0] = 0;
739 pidff->set_effect[PID_TRIGGER_REPEAT_INT].value[0] = 0; 739 pidff->set_effect[PID_TRIGGER_REPEAT_INT].value[0] = 0;
740 pidff_set(&pidff->set_effect[PID_GAIN], magnitude); 740 pidff_set(&pidff->set_effect[PID_GAIN], magnitude);
741 pidff->set_effect[PID_DIRECTION_ENABLE].value[0] = 1;
741 pidff->set_effect[PID_START_DELAY].value[0] = 0; 742 pidff->set_effect[PID_START_DELAY].value[0] = 0;
742 743
743 usbhid_submit_report(pidff->hid, pidff->reports[PID_SET_EFFECT], 744 usbhid_submit_report(pidff->hid, pidff->reports[PID_SET_EFFECT],
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c
index f6c4145dc202..775b9f3b8ce3 100644
--- a/drivers/hid/usbhid/hid-quirks.c
+++ b/drivers/hid/usbhid/hid-quirks.c
@@ -105,6 +105,9 @@
105#define USB_VENDOR_ID_ESSENTIAL_REALITY 0x0d7f 105#define USB_VENDOR_ID_ESSENTIAL_REALITY 0x0d7f
106#define USB_DEVICE_ID_ESSENTIAL_REALITY_P5 0x0100 106#define USB_DEVICE_ID_ESSENTIAL_REALITY_P5 0x0100
107 107
108#define USB_VENDOR_ID_GAMERON 0x0810
109#define USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR 0x0001
110
108#define USB_VENDOR_ID_GLAB 0x06c2 111#define USB_VENDOR_ID_GLAB 0x06c2
109#define USB_DEVICE_ID_4_PHIDGETSERVO_30 0x0038 112#define USB_DEVICE_ID_4_PHIDGETSERVO_30 0x0038
110#define USB_DEVICE_ID_1_PHIDGETSERVO_30 0x0039 113#define USB_DEVICE_ID_1_PHIDGETSERVO_30 0x0039
@@ -196,8 +199,10 @@
196#define USB_VENDOR_ID_LOGITECH 0x046d 199#define USB_VENDOR_ID_LOGITECH 0x046d
197#define USB_DEVICE_ID_LOGITECH_RECEIVER 0xc101 200#define USB_DEVICE_ID_LOGITECH_RECEIVER 0xc101
198#define USB_DEVICE_ID_LOGITECH_WHEEL 0xc294 201#define USB_DEVICE_ID_LOGITECH_WHEEL 0xc294
202#define USB_DEVICE_ID_LOGITECH_KBD 0xc311
199#define USB_DEVICE_ID_S510_RECEIVER 0xc50c 203#define USB_DEVICE_ID_S510_RECEIVER 0xc50c
200#define USB_DEVICE_ID_S510_RECEIVER_2 0xc517 204#define USB_DEVICE_ID_S510_RECEIVER_2 0xc517
205#define USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500 0xc512
201#define USB_DEVICE_ID_MX3000_RECEIVER 0xc513 206#define USB_DEVICE_ID_MX3000_RECEIVER 0xc513
202#define USB_DEVICE_ID_DINOVO_EDGE 0xc714 207#define USB_DEVICE_ID_DINOVO_EDGE 0xc714
203 208
@@ -209,6 +214,13 @@
209#define USB_DEVICE_ID_MGE_UPS 0xffff 214#define USB_DEVICE_ID_MGE_UPS 0xffff
210#define USB_DEVICE_ID_MGE_UPS1 0x0001 215#define USB_DEVICE_ID_MGE_UPS1 0x0001
211 216
217#define USB_VENDOR_ID_MICROSOFT 0x045e
218#define USB_DEVICE_ID_SIDEWINDER_GV 0x003b
219
220#define USB_VENDOR_ID_NCR 0x0404
221#define USB_DEVICE_ID_NCR_FIRST 0x0300
222#define USB_DEVICE_ID_NCR_LAST 0x03ff
223
212#define USB_VENDOR_ID_NEC 0x073e 224#define USB_VENDOR_ID_NEC 0x073e
213#define USB_DEVICE_ID_NEC_USB_GAME_PAD 0x0301 225#define USB_DEVICE_ID_NEC_USB_GAME_PAD 0x0301
214 226
@@ -220,6 +232,9 @@
220#define USB_VENDOR_ID_PANTHERLORD 0x0810 232#define USB_VENDOR_ID_PANTHERLORD 0x0810
221#define USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK 0x0001 233#define USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK 0x0001
222 234
235#define USB_VENDOR_ID_PETALYNX 0x18b1
236#define USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE 0x0037
237
223#define USB_VENDOR_ID_PLAYDOTCOM 0x0b43 238#define USB_VENDOR_ID_PLAYDOTCOM 0x0b43
224#define USB_DEVICE_ID_PLAYDOTCOM_EMS_USBII 0x0003 239#define USB_DEVICE_ID_PLAYDOTCOM_EMS_USBII 0x0003
225 240
@@ -278,6 +293,7 @@ static const struct hid_blacklist {
278 { USB_VENDOR_ID_AASHIMA, USB_DEVICE_ID_AASHIMA_PREDATOR, HID_QUIRK_BADPAD }, 293 { USB_VENDOR_ID_AASHIMA, USB_DEVICE_ID_AASHIMA_PREDATOR, HID_QUIRK_BADPAD },
279 { USB_VENDOR_ID_ALPS, USB_DEVICE_ID_IBM_GAMEPAD, HID_QUIRK_BADPAD }, 294 { USB_VENDOR_ID_ALPS, USB_DEVICE_ID_IBM_GAMEPAD, HID_QUIRK_BADPAD },
280 { USB_VENDOR_ID_CHIC, USB_DEVICE_ID_CHIC_GAMEPAD, HID_QUIRK_BADPAD }, 295 { USB_VENDOR_ID_CHIC, USB_DEVICE_ID_CHIC_GAMEPAD, HID_QUIRK_BADPAD },
296 { USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR, HID_QUIRK_MULTI_INPUT },
281 { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_DRIVING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, 297 { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_DRIVING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT },
282 { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FLYING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, 298 { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FLYING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT },
283 { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FIGHTING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, 299 { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FIGHTING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT },
@@ -285,11 +301,10 @@ static const struct hid_blacklist {
285 { USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RUMBLEPAD, HID_QUIRK_BADPAD }, 301 { USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RUMBLEPAD, HID_QUIRK_BADPAD },
286 { USB_VENDOR_ID_TOPMAX, USB_DEVICE_ID_TOPMAX_COBRAPAD, HID_QUIRK_BADPAD }, 302 { USB_VENDOR_ID_TOPMAX, USB_DEVICE_ID_TOPMAX_COBRAPAD, HID_QUIRK_BADPAD },
287 303
288 { USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION, HID_QUIRK_CYMOTION },
289
290 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_EDGE, HID_QUIRK_DUPLICATE_USAGES }, 304 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_EDGE, HID_QUIRK_DUPLICATE_USAGES },
291 305
292 { USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM, HID_QUIRK_HIDDEV }, 306 { USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM, HID_QUIRK_HIDDEV },
307 { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV, HID_QUIRK_HIDINPUT },
293 308
294 { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_01, HID_QUIRK_IGNORE }, 309 { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_01, HID_QUIRK_IGNORE },
295 { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_10, HID_QUIRK_IGNORE }, 310 { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_10, HID_QUIRK_IGNORE },
@@ -409,9 +424,7 @@ static const struct hid_blacklist {
409 { USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_FLAIR, HID_QUIRK_IGNORE }, 424 { USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_FLAIR, HID_QUIRK_IGNORE },
410 { USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_302, HID_QUIRK_IGNORE }, 425 { USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_302, HID_QUIRK_IGNORE },
411 426
412 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER, HID_QUIRK_LOGITECH_DESCRIPTOR }, 427 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500, HID_QUIRK_LOGITECH_IGNORE_DOUBLED_WHEEL | HID_QUIRK_LOGITECH_EXPANDED_KEYMAP },
413 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER, HID_QUIRK_LOGITECH_DESCRIPTOR },
414 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER_2, HID_QUIRK_LOGITECH_DESCRIPTOR },
415 428
416 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE, HID_QUIRK_MIGHTYMOUSE | HID_QUIRK_INVERT_HWHEEL }, 429 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE, HID_QUIRK_MIGHTYMOUSE | HID_QUIRK_INVERT_HWHEEL },
417 430
@@ -426,6 +439,7 @@ static const struct hid_blacklist {
426 { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVM, HID_QUIRK_NOGET }, 439 { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVM, HID_QUIRK_NOGET },
427 { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC, HID_QUIRK_NOGET }, 440 { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC, HID_QUIRK_NOGET },
428 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WHEEL, HID_QUIRK_NOGET }, 441 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WHEEL, HID_QUIRK_NOGET },
442 { USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE, HID_QUIRK_NOGET },
429 { USB_VENDOR_ID_SUN, USB_DEVICE_ID_RARITAN_KVM_DONGLE, HID_QUIRK_NOGET }, 443 { USB_VENDOR_ID_SUN, USB_DEVICE_ID_RARITAN_KVM_DONGLE, HID_QUIRK_NOGET },
430 { USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_KEYBOARD, HID_QUIRK_NOGET }, 444 { USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_KEYBOARD, HID_QUIRK_NOGET },
431 { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, 445 { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT },
@@ -448,9 +462,28 @@ static const struct hid_blacklist {
448 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, 462 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
449 463
450 { USB_VENDOR_ID_DELL, USB_DEVICE_ID_DELL_W7658, HID_QUIRK_RESET_LEDS }, 464 { USB_VENDOR_ID_DELL, USB_DEVICE_ID_DELL_W7658, HID_QUIRK_RESET_LEDS },
465 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_KBD, HID_QUIRK_RESET_LEDS },
451 466
452 { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1, HID_QUIRK_SWAPPED_MIN_MAX }, 467 { 0, 0 }
453 { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2, HID_QUIRK_SWAPPED_MIN_MAX }, 468};
469
470/* Quirks for devices which require report descriptor fixup go here */
471static const struct hid_rdesc_blacklist {
472 __u16 idVendor;
473 __u16 idProduct;
474 __u32 quirks;
475} hid_rdesc_blacklist[] = {
476
477 { USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION, HID_QUIRK_RDESC_CYMOTION },
478
479 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER, HID_QUIRK_RDESC_LOGITECH },
480 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER, HID_QUIRK_RDESC_LOGITECH },
481 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER_2, HID_QUIRK_RDESC_LOGITECH },
482
483 { USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE, HID_QUIRK_RDESC_PETALYNX },
484
485 { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1, HID_QUIRK_RDESC_SWAPPED_MIN_MAX },
486 { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2, HID_QUIRK_RDESC_SWAPPED_MIN_MAX },
454 487
455 { 0, 0 } 488 { 0, 0 }
456}; 489};
@@ -493,7 +526,7 @@ static struct hid_blacklist *usbhid_exists_dquirk(const u16 idVendor,
493 } 526 }
494 527
495 if (bl_entry != NULL) 528 if (bl_entry != NULL)
496 dbg("Found dynamic quirk 0x%x for USB HID vendor 0x%hx prod 0x%hx\n", 529 dbg_hid("Found dynamic quirk 0x%x for USB HID vendor 0x%hx prod 0x%hx\n",
497 bl_entry->quirks, bl_entry->idVendor, 530 bl_entry->quirks, bl_entry->idVendor,
498 bl_entry->idProduct); 531 bl_entry->idProduct);
499 532
@@ -521,13 +554,13 @@ int usbhid_modify_dquirk(const u16 idVendor, const u16 idProduct,
521 int list_edited = 0; 554 int list_edited = 0;
522 555
523 if (!idVendor) { 556 if (!idVendor) {
524 dbg("Cannot add a quirk with idVendor = 0"); 557 dbg_hid("Cannot add a quirk with idVendor = 0\n");
525 return -EINVAL; 558 return -EINVAL;
526 } 559 }
527 560
528 q_new = kmalloc(sizeof(struct quirks_list_struct), GFP_KERNEL); 561 q_new = kmalloc(sizeof(struct quirks_list_struct), GFP_KERNEL);
529 if (!q_new) { 562 if (!q_new) {
530 dbg("Could not allocate quirks_list_struct"); 563 dbg_hid("Could not allocate quirks_list_struct\n");
531 return -ENOMEM; 564 return -ENOMEM;
532 } 565 }
533 566
@@ -559,7 +592,6 @@ int usbhid_modify_dquirk(const u16 idVendor, const u16 idProduct,
559 return 0; 592 return 0;
560} 593}
561 594
562
563/** 595/**
564 * usbhid_remove_all_dquirks: remove all runtime HID quirks from memory 596 * usbhid_remove_all_dquirks: remove all runtime HID quirks from memory
565 * 597 *
@@ -643,7 +675,7 @@ static const struct hid_blacklist *usbhid_exists_squirk(const u16 idVendor,
643 bl_entry = &hid_blacklist[n]; 675 bl_entry = &hid_blacklist[n];
644 676
645 if (bl_entry != NULL) 677 if (bl_entry != NULL)
646 dbg("Found squirk 0x%x for USB HID vendor 0x%hx prod 0x%hx\n", 678 dbg_hid("Found squirk 0x%x for USB HID vendor 0x%hx prod 0x%hx\n",
647 bl_entry->quirks, bl_entry->idVendor, 679 bl_entry->quirks, bl_entry->idVendor,
648 bl_entry->idProduct); 680 bl_entry->idProduct);
649 return bl_entry; 681 return bl_entry;
@@ -675,6 +707,12 @@ u32 usbhid_lookup_quirk(const u16 idVendor, const u16 idProduct)
675 idProduct <= USB_DEVICE_ID_CODEMERCS_IOW_LAST) 707 idProduct <= USB_DEVICE_ID_CODEMERCS_IOW_LAST)
676 return HID_QUIRK_IGNORE; 708 return HID_QUIRK_IGNORE;
677 709
710 /* NCR devices must not be queried for reports */
711 if (idVendor == USB_VENDOR_ID_NCR &&
712 idProduct >= USB_DEVICE_ID_NCR_FIRST &&
713 idProduct <= USB_DEVICE_ID_NCR_LAST)
714 return HID_QUIRK_NOGET;
715
678 down_read(&dquirks_rwsem); 716 down_read(&dquirks_rwsem);
679 bl_entry = usbhid_exists_dquirk(idVendor, idProduct); 717 bl_entry = usbhid_exists_dquirk(idVendor, idProduct);
680 if (!bl_entry) 718 if (!bl_entry)
@@ -686,3 +724,126 @@ u32 usbhid_lookup_quirk(const u16 idVendor, const u16 idProduct)
686 return quirks; 724 return quirks;
687} 725}
688 726
727/*
728 * Cherry Cymotion keyboard have an invalid HID report descriptor,
729 * that needs fixing before we can parse it.
730 */
731static void usbhid_fixup_cymotion_descriptor(char *rdesc, int rsize)
732{
733 if (rsize >= 17 && rdesc[11] == 0x3c && rdesc[12] == 0x02) {
734 printk(KERN_INFO "Fixing up Cherry Cymotion report descriptor\n");
735 rdesc[11] = rdesc[16] = 0xff;
736 rdesc[12] = rdesc[17] = 0x03;
737 }
738}
739
740
741/*
742 * Certain Logitech keyboards send in report #3 keys which are far
743 * above the logical maximum described in descriptor. This extends
744 * the original value of 0x28c of logical maximum to 0x104d
745 */
746static void usbhid_fixup_logitech_descriptor(unsigned char *rdesc, int rsize)
747{
748 if (rsize >= 90 && rdesc[83] == 0x26
749 && rdesc[84] == 0x8c
750 && rdesc[85] == 0x02) {
751 printk(KERN_INFO "Fixing up Logitech keyboard report descriptor\n");
752 rdesc[84] = rdesc[89] = 0x4d;
753 rdesc[85] = rdesc[90] = 0x10;
754 }
755}
756
757/* Petalynx Maxter Remote has maximum for consumer page set too low */
758static void usbhid_fixup_petalynx_descriptor(unsigned char *rdesc, int rsize)
759{
760 if (rsize >= 60 && rdesc[39] == 0x2a
761 && rdesc[40] == 0xf5
762 && rdesc[41] == 0x00
763 && rdesc[59] == 0x26
764 && rdesc[60] == 0xf9
765 && rdesc[61] == 0x00) {
766 printk(KERN_INFO "Fixing up Petalynx Maxter Remote report descriptor\n");
767 rdesc[60] = 0xfa;
768 rdesc[40] = 0xfa;
769 }
770}
771
772/*
773 * Some USB barcode readers from cypress have usage min and usage max in
774 * the wrong order
775 */
776static void usbhid_fixup_cypress_descriptor(unsigned char *rdesc, int rsize)
777{
778 short fixed = 0;
779 int i;
780
781 for (i = 0; i < rsize - 4; i++) {
782 if (rdesc[i] == 0x29 && rdesc [i+2] == 0x19) {
783 unsigned char tmp;
784
785 rdesc[i] = 0x19; rdesc[i+2] = 0x29;
786 tmp = rdesc[i+3];
787 rdesc[i+3] = rdesc[i+1];
788 rdesc[i+1] = tmp;
789 }
790 }
791
792 if (fixed)
793 printk(KERN_INFO "Fixing up Cypress report descriptor\n");
794}
795
796
797static void __usbhid_fixup_report_descriptor(__u32 quirks, char *rdesc, unsigned rsize)
798{
799 if ((quirks & HID_QUIRK_RDESC_CYMOTION))
800 usbhid_fixup_cymotion_descriptor(rdesc, rsize);
801
802 if (quirks & HID_QUIRK_RDESC_LOGITECH)
803 usbhid_fixup_logitech_descriptor(rdesc, rsize);
804
805 if (quirks & HID_QUIRK_RDESC_SWAPPED_MIN_MAX)
806 usbhid_fixup_cypress_descriptor(rdesc, rsize);
807
808 if (quirks & HID_QUIRK_RDESC_PETALYNX)
809 usbhid_fixup_petalynx_descriptor(rdesc, rsize);
810}
811
812/**
813 * usbhid_fixup_report_descriptor: check if report descriptor needs fixup
814 *
815 * Description:
816 * Walks the hid_rdesc_blacklist[] array and checks whether the device
817 * is known to have broken report descriptor that needs to be fixed up
818 * prior to entering the HID parser
819 *
820 * Returns: nothing
821 */
822void usbhid_fixup_report_descriptor(const u16 idVendor, const u16 idProduct,
823 char *rdesc, unsigned rsize, char **quirks_param)
824{
825 int n, m;
826 u16 paramVendor, paramProduct;
827 u32 quirks;
828
829 /* static rdesc quirk entries */
830 for (n = 0; hid_rdesc_blacklist[n].idVendor; n++)
831 if (hid_rdesc_blacklist[n].idVendor == idVendor &&
832 hid_rdesc_blacklist[n].idProduct == idProduct)
833 __usbhid_fixup_report_descriptor(hid_rdesc_blacklist[n].quirks,
834 rdesc, rsize);
835
836 /* runtime rdesc quirk entries handling */
837 for (n = 0; quirks_param[n] && n < MAX_USBHID_BOOT_QUIRKS; n++) {
838 m = sscanf(quirks_param[n], "0x%hx:0x%hx:0x%x",
839 &paramVendor, &paramProduct, &quirks);
840
841 if (m != 3)
842 printk(KERN_WARNING
843 "Could not parse HID quirk module param %s\n",
844 quirks_param[n]);
845 else if (paramVendor == idVendor && paramProduct == idProduct)
846 __usbhid_fixup_report_descriptor(quirks, rdesc, rsize);
847 }
848
849}
diff --git a/drivers/hid/usbhid/hid-tmff.c b/drivers/hid/usbhid/hid-tmff.c
index ab5ba6ef891c..555bb48b4295 100644
--- a/drivers/hid/usbhid/hid-tmff.c
+++ b/drivers/hid/usbhid/hid-tmff.c
@@ -70,7 +70,7 @@ static int hid_tmff_play(struct input_dev *dev, void *data, struct ff_effect *ef
70 70
71 tmff->rumble->value[0] = left; 71 tmff->rumble->value[0] = left;
72 tmff->rumble->value[1] = right; 72 tmff->rumble->value[1] = right;
73 dbg("(left,right)=(%08x, %08x)", left, right); 73 dbg_hid("(left,right)=(%08x, %08x)\n", left, right);
74 usbhid_submit_report(hid, tmff->report, USB_DIR_OUT); 74 usbhid_submit_report(hid, tmff->report, USB_DIR_OUT);
75 75
76 return 0; 76 return 0;
diff --git a/drivers/hid/usbhid/hid-zpff.c b/drivers/hid/usbhid/hid-zpff.c
index a7fbffcdaf36..5a688274f6a3 100644
--- a/drivers/hid/usbhid/hid-zpff.c
+++ b/drivers/hid/usbhid/hid-zpff.c
@@ -21,10 +21,6 @@
21 */ 21 */
22 22
23 23
24/* #define DEBUG */
25
26#define debug(format, arg...) pr_debug("hid-zpff: " format "\n" , ## arg)
27
28#include <linux/input.h> 24#include <linux/input.h>
29#include <linux/usb.h> 25#include <linux/usb.h>
30#include <linux/hid.h> 26#include <linux/hid.h>
@@ -49,14 +45,14 @@ static int hid_zpff_play(struct input_dev *dev, void *data,
49 45
50 left = effect->u.rumble.strong_magnitude; 46 left = effect->u.rumble.strong_magnitude;
51 right = effect->u.rumble.weak_magnitude; 47 right = effect->u.rumble.weak_magnitude;
52 debug("called with 0x%04x 0x%04x", left, right); 48 dbg_hid("called with 0x%04x 0x%04x\n", left, right);
53 49
54 left = left * 0x7f / 0xffff; 50 left = left * 0x7f / 0xffff;
55 right = right * 0x7f / 0xffff; 51 right = right * 0x7f / 0xffff;
56 52
57 zpff->report->field[2]->value[0] = left; 53 zpff->report->field[2]->value[0] = left;
58 zpff->report->field[3]->value[0] = right; 54 zpff->report->field[3]->value[0] = right;
59 debug("running with 0x%02x 0x%02x", left, right); 55 dbg_hid("running with 0x%02x 0x%02x\n", left, right);
60 usbhid_submit_report(hid, zpff->report, USB_DIR_OUT); 56 usbhid_submit_report(hid, zpff->report, USB_DIR_OUT);
61 57
62 return 0; 58 return 0;
diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c
index 488d61bdbf2c..e793127f971e 100644
--- a/drivers/hid/usbhid/hiddev.c
+++ b/drivers/hid/usbhid/hiddev.c
@@ -779,7 +779,7 @@ int hiddev_connect(struct hid_device *hid)
779 779
780 retval = usb_register_dev(usbhid->intf, &hiddev_class); 780 retval = usb_register_dev(usbhid->intf, &hiddev_class);
781 if (retval) { 781 if (retval) {
782 err("Not able to get a minor for this device."); 782 err_hid("Not able to get a minor for this device.");
783 kfree(hiddev); 783 kfree(hiddev);
784 return -1; 784 return -1;
785 } 785 }
diff --git a/drivers/hid/usbhid/usbkbd.c b/drivers/hid/usbhid/usbkbd.c
index 130978780713..b76b02f7b52d 100644
--- a/drivers/hid/usbhid/usbkbd.c
+++ b/drivers/hid/usbhid/usbkbd.c
@@ -125,7 +125,7 @@ static void usb_kbd_irq(struct urb *urb)
125resubmit: 125resubmit:
126 i = usb_submit_urb (urb, GFP_ATOMIC); 126 i = usb_submit_urb (urb, GFP_ATOMIC);
127 if (i) 127 if (i)
128 err ("can't resubmit intr, %s-%s/input0, status %d", 128 err_hid ("can't resubmit intr, %s-%s/input0, status %d",
129 kbd->usbdev->bus->bus_name, 129 kbd->usbdev->bus->bus_name,
130 kbd->usbdev->devpath, i); 130 kbd->usbdev->devpath, i);
131} 131}
@@ -151,7 +151,7 @@ static int usb_kbd_event(struct input_dev *dev, unsigned int type,
151 *(kbd->leds) = kbd->newleds; 151 *(kbd->leds) = kbd->newleds;
152 kbd->led->dev = kbd->usbdev; 152 kbd->led->dev = kbd->usbdev;
153 if (usb_submit_urb(kbd->led, GFP_ATOMIC)) 153 if (usb_submit_urb(kbd->led, GFP_ATOMIC))
154 err("usb_submit_urb(leds) failed"); 154 err_hid("usb_submit_urb(leds) failed");
155 155
156 return 0; 156 return 0;
157} 157}
@@ -169,7 +169,7 @@ static void usb_kbd_led(struct urb *urb)
169 *(kbd->leds) = kbd->newleds; 169 *(kbd->leds) = kbd->newleds;
170 kbd->led->dev = kbd->usbdev; 170 kbd->led->dev = kbd->usbdev;
171 if (usb_submit_urb(kbd->led, GFP_ATOMIC)) 171 if (usb_submit_urb(kbd->led, GFP_ATOMIC))
172 err("usb_submit_urb(leds) failed"); 172 err_hid("usb_submit_urb(leds) failed");
173} 173}
174 174
175static int usb_kbd_open(struct input_dev *dev) 175static int usb_kbd_open(struct input_dev *dev)
diff --git a/drivers/ide/arm/icside.c b/drivers/ide/arm/icside.c
index 66f826252aee..444a0b84f5bd 100644
--- a/drivers/ide/arm/icside.c
+++ b/drivers/ide/arm/icside.c
@@ -448,23 +448,21 @@ static int icside_dma_test_irq(ide_drive_t *drive)
448 ICS_ARCIN_V6_INTRSTAT_1)) & 1; 448 ICS_ARCIN_V6_INTRSTAT_1)) & 1;
449} 449}
450 450
451static int icside_dma_timeout(ide_drive_t *drive) 451static void icside_dma_timeout(ide_drive_t *drive)
452{ 452{
453 printk(KERN_ERR "%s: DMA timeout occurred: ", drive->name); 453 printk(KERN_ERR "%s: DMA timeout occurred: ", drive->name);
454 454
455 if (icside_dma_test_irq(drive)) 455 if (icside_dma_test_irq(drive))
456 return 0; 456 return;
457 457
458 ide_dump_status(drive, "DMA timeout", 458 ide_dump_status(drive, "DMA timeout", HWIF(drive)->INB(IDE_STATUS_REG));
459 HWIF(drive)->INB(IDE_STATUS_REG));
460 459
461 return icside_dma_end(drive); 460 icside_dma_end(drive);
462} 461}
463 462
464static int icside_dma_lostirq(ide_drive_t *drive) 463static void icside_dma_lost_irq(ide_drive_t *drive)
465{ 464{
466 printk(KERN_ERR "%s: IRQ lost\n", drive->name); 465 printk(KERN_ERR "%s: IRQ lost\n", drive->name);
467 return 1;
468} 466}
469 467
470static void icside_dma_init(ide_hwif_t *hwif) 468static void icside_dma_init(ide_hwif_t *hwif)
@@ -490,8 +488,8 @@ static void icside_dma_init(ide_hwif_t *hwif)
490 hwif->dma_start = icside_dma_start; 488 hwif->dma_start = icside_dma_start;
491 hwif->ide_dma_end = icside_dma_end; 489 hwif->ide_dma_end = icside_dma_end;
492 hwif->ide_dma_test_irq = icside_dma_test_irq; 490 hwif->ide_dma_test_irq = icside_dma_test_irq;
493 hwif->ide_dma_timeout = icside_dma_timeout; 491 hwif->dma_timeout = icside_dma_timeout;
494 hwif->ide_dma_lostirq = icside_dma_lostirq; 492 hwif->dma_lost_irq = icside_dma_lost_irq;
495 493
496 hwif->drives[0].autodma = hwif->autodma; 494 hwif->drives[0].autodma = hwif->autodma;
497 hwif->drives[1].autodma = hwif->autodma; 495 hwif->drives[1].autodma = hwif->autodma;
diff --git a/drivers/ide/cris/ide-cris.c b/drivers/ide/cris/ide-cris.c
index ca0341c05e55..886091bc7db0 100644
--- a/drivers/ide/cris/ide-cris.c
+++ b/drivers/ide/cris/ide-cris.c
@@ -819,7 +819,7 @@ init_e100_ide (void)
819 hwif->dma_host_off = &cris_dma_off; 819 hwif->dma_host_off = &cris_dma_off;
820 hwif->dma_host_on = &cris_dma_on; 820 hwif->dma_host_on = &cris_dma_on;
821 hwif->dma_off_quietly = &cris_dma_off; 821 hwif->dma_off_quietly = &cris_dma_off;
822 hwif->udma_four = 0; 822 hwif->cbl = ATA_CBL_PATA40;
823 hwif->ultra_mask = cris_ultra_mask; 823 hwif->ultra_mask = cris_ultra_mask;
824 hwif->mwdma_mask = 0x07; /* Multiword DMA 0-2 */ 824 hwif->mwdma_mask = 0x07; /* Multiword DMA 0-2 */
825 hwif->autodma = 1; 825 hwif->autodma = 1;
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index 252ab8295edf..1486eb212ccc 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -481,7 +481,7 @@ void cdrom_analyze_sense_data(ide_drive_t *drive,
481 else 481 else
482 printk(" Unknown Error Type: "); 482 printk(" Unknown Error Type: ");
483 483
484 if (sense->sense_key < ARY_LEN(sense_key_texts)) 484 if (sense->sense_key < ARRAY_SIZE(sense_key_texts))
485 s = sense_key_texts[sense->sense_key]; 485 s = sense_key_texts[sense->sense_key];
486 486
487 printk("%s -- (Sense key=0x%02x)\n", s, sense->sense_key); 487 printk("%s -- (Sense key=0x%02x)\n", s, sense->sense_key);
@@ -491,7 +491,7 @@ void cdrom_analyze_sense_data(ide_drive_t *drive,
491 sense->ascq); 491 sense->ascq);
492 s = buf; 492 s = buf;
493 } else { 493 } else {
494 int lo = 0, mid, hi = ARY_LEN(sense_data_texts); 494 int lo = 0, mid, hi = ARRAY_SIZE(sense_data_texts);
495 unsigned long key = (sense->sense_key << 16); 495 unsigned long key = (sense->sense_key << 16);
496 key |= (sense->asc << 8); 496 key |= (sense->asc << 8);
497 if (!(sense->ascq >= 0x80 && sense->ascq <= 0xdd)) 497 if (!(sense->ascq >= 0x80 && sense->ascq <= 0xdd))
@@ -524,7 +524,7 @@ void cdrom_analyze_sense_data(ide_drive_t *drive,
524 524
525 if (failed_command != NULL) { 525 if (failed_command != NULL) {
526 526
527 int lo=0, mid, hi= ARY_LEN (packet_command_texts); 527 int lo=0, mid, hi= ARRAY_SIZE(packet_command_texts);
528 s = NULL; 528 s = NULL;
529 529
530 while (hi > lo) { 530 while (hi > lo) {
diff --git a/drivers/ide/ide-cd.h b/drivers/ide/ide-cd.h
index ad1f2ed14a37..228b29c5d2e4 100644
--- a/drivers/ide/ide-cd.h
+++ b/drivers/ide/ide-cd.h
@@ -498,8 +498,6 @@ struct cdrom_info {
498 * Descriptions of ATAPI error codes. 498 * Descriptions of ATAPI error codes.
499 */ 499 */
500 500
501#define ARY_LEN(a) ((sizeof(a) / sizeof(a[0])))
502
503/* This stuff should be in cdrom.h, since it is now generic... */ 501/* This stuff should be in cdrom.h, since it is now generic... */
504 502
505/* ATAPI sense keys (from table 140 of ATAPI 2.6) */ 503/* ATAPI sense keys (from table 140 of ATAPI 2.6) */
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index dc2175c81f5e..b1304a7f3e0a 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -1190,11 +1190,11 @@ static int idedisk_ioctl(struct inode *inode, struct file *file,
1190 return generic_ide_ioctl(drive, file, bdev, cmd, arg); 1190 return generic_ide_ioctl(drive, file, bdev, cmd, arg);
1191 1191
1192read_val: 1192read_val:
1193 down(&ide_setting_sem); 1193 mutex_lock(&ide_setting_mtx);
1194 spin_lock_irqsave(&ide_lock, flags); 1194 spin_lock_irqsave(&ide_lock, flags);
1195 err = *val; 1195 err = *val;
1196 spin_unlock_irqrestore(&ide_lock, flags); 1196 spin_unlock_irqrestore(&ide_lock, flags);
1197 up(&ide_setting_sem); 1197 mutex_unlock(&ide_setting_mtx);
1198 return err >= 0 ? put_user(err, (long __user *)arg) : err; 1198 return err >= 0 ? put_user(err, (long __user *)arg) : err;
1199 1199
1200set_val: 1200set_val:
@@ -1204,9 +1204,9 @@ set_val:
1204 if (!capable(CAP_SYS_ADMIN)) 1204 if (!capable(CAP_SYS_ADMIN))
1205 err = -EACCES; 1205 err = -EACCES;
1206 else { 1206 else {
1207 down(&ide_setting_sem); 1207 mutex_lock(&ide_setting_mtx);
1208 err = setfunc(drive, arg); 1208 err = setfunc(drive, arg);
1209 up(&ide_setting_sem); 1209 mutex_unlock(&ide_setting_mtx);
1210 } 1210 }
1211 } 1211 }
1212 return err; 1212 return err;
diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c
index ead141e2db9e..5fe1d72ab451 100644
--- a/drivers/ide/ide-dma.c
+++ b/drivers/ide/ide-dma.c
@@ -91,45 +91,45 @@
91 91
92static const struct drive_list_entry drive_whitelist [] = { 92static const struct drive_list_entry drive_whitelist [] = {
93 93
94 { "Micropolis 2112A" , "ALL" }, 94 { "Micropolis 2112A" , NULL },
95 { "CONNER CTMA 4000" , "ALL" }, 95 { "CONNER CTMA 4000" , NULL },
96 { "CONNER CTT8000-A" , "ALL" }, 96 { "CONNER CTT8000-A" , NULL },
97 { "ST34342A" , "ALL" }, 97 { "ST34342A" , NULL },
98 { NULL , NULL } 98 { NULL , NULL }
99}; 99};
100 100
101static const struct drive_list_entry drive_blacklist [] = { 101static const struct drive_list_entry drive_blacklist [] = {
102 102
103 { "WDC AC11000H" , "ALL" }, 103 { "WDC AC11000H" , NULL },
104 { "WDC AC22100H" , "ALL" }, 104 { "WDC AC22100H" , NULL },
105 { "WDC AC32500H" , "ALL" }, 105 { "WDC AC32500H" , NULL },
106 { "WDC AC33100H" , "ALL" }, 106 { "WDC AC33100H" , NULL },
107 { "WDC AC31600H" , "ALL" }, 107 { "WDC AC31600H" , NULL },
108 { "WDC AC32100H" , "24.09P07" }, 108 { "WDC AC32100H" , "24.09P07" },
109 { "WDC AC23200L" , "21.10N21" }, 109 { "WDC AC23200L" , "21.10N21" },
110 { "Compaq CRD-8241B" , "ALL" }, 110 { "Compaq CRD-8241B" , NULL },
111 { "CRD-8400B" , "ALL" }, 111 { "CRD-8400B" , NULL },
112 { "CRD-8480B", "ALL" }, 112 { "CRD-8480B", NULL },
113 { "CRD-8482B", "ALL" }, 113 { "CRD-8482B", NULL },
114 { "CRD-84" , "ALL" }, 114 { "CRD-84" , NULL },
115 { "SanDisk SDP3B" , "ALL" }, 115 { "SanDisk SDP3B" , NULL },
116 { "SanDisk SDP3B-64" , "ALL" }, 116 { "SanDisk SDP3B-64" , NULL },
117 { "SANYO CD-ROM CRD" , "ALL" }, 117 { "SANYO CD-ROM CRD" , NULL },
118 { "HITACHI CDR-8" , "ALL" }, 118 { "HITACHI CDR-8" , NULL },
119 { "HITACHI CDR-8335" , "ALL" }, 119 { "HITACHI CDR-8335" , NULL },
120 { "HITACHI CDR-8435" , "ALL" }, 120 { "HITACHI CDR-8435" , NULL },
121 { "Toshiba CD-ROM XM-6202B" , "ALL" }, 121 { "Toshiba CD-ROM XM-6202B" , NULL },
122 { "TOSHIBA CD-ROM XM-1702BC", "ALL" }, 122 { "TOSHIBA CD-ROM XM-1702BC", NULL },
123 { "CD-532E-A" , "ALL" }, 123 { "CD-532E-A" , NULL },
124 { "E-IDE CD-ROM CR-840", "ALL" }, 124 { "E-IDE CD-ROM CR-840", NULL },
125 { "CD-ROM Drive/F5A", "ALL" }, 125 { "CD-ROM Drive/F5A", NULL },
126 { "WPI CDD-820", "ALL" }, 126 { "WPI CDD-820", NULL },
127 { "SAMSUNG CD-ROM SC-148C", "ALL" }, 127 { "SAMSUNG CD-ROM SC-148C", NULL },
128 { "SAMSUNG CD-ROM SC", "ALL" }, 128 { "SAMSUNG CD-ROM SC", NULL },
129 { "ATAPI CD-ROM DRIVE 40X MAXIMUM", "ALL" }, 129 { "ATAPI CD-ROM DRIVE 40X MAXIMUM", NULL },
130 { "_NEC DV5800A", "ALL" }, 130 { "_NEC DV5800A", NULL },
131 { "SAMSUNG CD-ROM SN-124", "N001" }, 131 { "SAMSUNG CD-ROM SN-124", "N001" },
132 { "Seagate STT20000A", "ALL" }, 132 { "Seagate STT20000A", NULL },
133 { NULL , NULL } 133 { NULL , NULL }
134 134
135}; 135};
@@ -147,8 +147,8 @@ int ide_in_drive_list(struct hd_driveid *id, const struct drive_list_entry *driv
147{ 147{
148 for ( ; drive_table->id_model ; drive_table++) 148 for ( ; drive_table->id_model ; drive_table++)
149 if ((!strcmp(drive_table->id_model, id->model)) && 149 if ((!strcmp(drive_table->id_model, id->model)) &&
150 ((strstr(id->fw_rev, drive_table->id_firmware)) || 150 (!drive_table->id_firmware ||
151 (!strcmp(drive_table->id_firmware, "ALL")))) 151 strstr(id->fw_rev, drive_table->id_firmware)))
152 return 1; 152 return 1;
153 return 0; 153 return 0;
154} 154}
@@ -702,8 +702,22 @@ static unsigned int ide_get_mode_mask(ide_drive_t *drive, u8 base)
702 mask = id->dma_mword & hwif->mwdma_mask; 702 mask = id->dma_mword & hwif->mwdma_mask;
703 break; 703 break;
704 case XFER_SW_DMA_0: 704 case XFER_SW_DMA_0:
705 if (id->field_valid & 2) 705 if (id->field_valid & 2) {
706 mask = id->dma_1word & hwif->swdma_mask; 706 mask = id->dma_1word & hwif->swdma_mask;
707 } else if (id->tDMA) {
708 /*
709 * ide_fix_driveid() doesn't convert ->tDMA to the
710 * CPU endianness so we need to do it here
711 */
712 u8 mode = le16_to_cpu(id->tDMA);
713
714 /*
715 * if the mode is valid convert it to the mask
716 * (the maximum allowed mode is XFER_SW_DMA_2)
717 */
718 if (mode <= 2)
719 mask = ((2 << mode) - 1) & hwif->swdma_mask;
720 }
707 break; 721 break;
708 default: 722 default:
709 BUG(); 723 BUG();
@@ -847,27 +861,27 @@ int ide_set_dma(ide_drive_t *drive)
847 return rc; 861 return rc;
848} 862}
849 863
850EXPORT_SYMBOL_GPL(ide_set_dma);
851
852#ifdef CONFIG_BLK_DEV_IDEDMA_PCI 864#ifdef CONFIG_BLK_DEV_IDEDMA_PCI
853int __ide_dma_lostirq (ide_drive_t *drive) 865void ide_dma_lost_irq (ide_drive_t *drive)
854{ 866{
855 printk("%s: DMA interrupt recovery\n", drive->name); 867 printk("%s: DMA interrupt recovery\n", drive->name);
856 return 1;
857} 868}
858 869
859EXPORT_SYMBOL(__ide_dma_lostirq); 870EXPORT_SYMBOL(ide_dma_lost_irq);
860 871
861int __ide_dma_timeout (ide_drive_t *drive) 872void ide_dma_timeout (ide_drive_t *drive)
862{ 873{
874 ide_hwif_t *hwif = HWIF(drive);
875
863 printk(KERN_ERR "%s: timeout waiting for DMA\n", drive->name); 876 printk(KERN_ERR "%s: timeout waiting for DMA\n", drive->name);
864 if (HWIF(drive)->ide_dma_test_irq(drive))
865 return 0;
866 877
867 return HWIF(drive)->ide_dma_end(drive); 878 if (hwif->ide_dma_test_irq(drive))
879 return;
880
881 hwif->ide_dma_end(drive);
868} 882}
869 883
870EXPORT_SYMBOL(__ide_dma_timeout); 884EXPORT_SYMBOL(ide_dma_timeout);
871 885
872/* 886/*
873 * Needed for allowing full modular support of ide-driver 887 * Needed for allowing full modular support of ide-driver
@@ -1018,10 +1032,10 @@ void ide_setup_dma (ide_hwif_t *hwif, unsigned long dma_base, unsigned int num_p
1018 hwif->ide_dma_end = &__ide_dma_end; 1032 hwif->ide_dma_end = &__ide_dma_end;
1019 if (!hwif->ide_dma_test_irq) 1033 if (!hwif->ide_dma_test_irq)
1020 hwif->ide_dma_test_irq = &__ide_dma_test_irq; 1034 hwif->ide_dma_test_irq = &__ide_dma_test_irq;
1021 if (!hwif->ide_dma_timeout) 1035 if (!hwif->dma_timeout)
1022 hwif->ide_dma_timeout = &__ide_dma_timeout; 1036 hwif->dma_timeout = &ide_dma_timeout;
1023 if (!hwif->ide_dma_lostirq) 1037 if (!hwif->dma_lost_irq)
1024 hwif->ide_dma_lostirq = &__ide_dma_lostirq; 1038 hwif->dma_lost_irq = &ide_dma_lost_irq;
1025 1039
1026 if (hwif->chipset != ide_trm290) { 1040 if (hwif->chipset != ide_trm290) {
1027 u8 dma_stat = hwif->INB(hwif->dma_status); 1041 u8 dma_stat = hwif->INB(hwif->dma_status);
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
index bfe8f1b712ba..c5b5011da56e 100644
--- a/drivers/ide/ide-io.c
+++ b/drivers/ide/ide-io.c
@@ -1350,7 +1350,7 @@ static ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error)
1350 hwif->INB(IDE_STATUS_REG)); 1350 hwif->INB(IDE_STATUS_REG));
1351 } else { 1351 } else {
1352 printk(KERN_WARNING "%s: DMA timeout retry\n", drive->name); 1352 printk(KERN_WARNING "%s: DMA timeout retry\n", drive->name);
1353 (void) hwif->ide_dma_timeout(drive); 1353 hwif->dma_timeout(drive);
1354 } 1354 }
1355 1355
1356 /* 1356 /*
@@ -1466,7 +1466,7 @@ void ide_timer_expiry (unsigned long data)
1466 startstop = handler(drive); 1466 startstop = handler(drive);
1467 } else if (drive_is_ready(drive)) { 1467 } else if (drive_is_ready(drive)) {
1468 if (drive->waiting_for_dma) 1468 if (drive->waiting_for_dma)
1469 (void) hwgroup->hwif->ide_dma_lostirq(drive); 1469 hwgroup->hwif->dma_lost_irq(drive);
1470 (void)ide_ack_intr(hwif); 1470 (void)ide_ack_intr(hwif);
1471 printk(KERN_WARNING "%s: lost interrupt\n", drive->name); 1471 printk(KERN_WARNING "%s: lost interrupt\n", drive->name);
1472 startstop = handler(drive); 1472 startstop = handler(drive);
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c
index f0be5f665a0e..92578b6832e9 100644
--- a/drivers/ide/ide-iops.c
+++ b/drivers/ide/ide-iops.c
@@ -574,7 +574,10 @@ u8 eighty_ninty_three (ide_drive_t *drive)
574 ide_hwif_t *hwif = drive->hwif; 574 ide_hwif_t *hwif = drive->hwif;
575 struct hd_driveid *id = drive->id; 575 struct hd_driveid *id = drive->id;
576 576
577 if (hwif->udma_four == 0) 577 if (hwif->cbl == ATA_CBL_PATA40_SHORT)
578 return 1;
579
580 if (hwif->cbl != ATA_CBL_PATA80)
578 goto no_80w; 581 goto no_80w;
579 582
580 /* Check for SATA but only if we are ATA5 or higher */ 583 /* Check for SATA but only if we are ATA5 or higher */
@@ -600,7 +603,8 @@ no_80w:
600 603
601 printk(KERN_WARNING "%s: %s side 80-wire cable detection failed, " 604 printk(KERN_WARNING "%s: %s side 80-wire cable detection failed, "
602 "limiting max speed to UDMA33\n", 605 "limiting max speed to UDMA33\n",
603 drive->name, hwif->udma_four ? "drive" : "host"); 606 drive->name,
607 hwif->cbl == ATA_CBL_PATA80 ? "drive" : "host");
604 608
605 drive->udma33_warned = 1; 609 drive->udma33_warned = 1;
606 610
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index f5ce22c38f82..cc5801399467 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -144,7 +144,7 @@ static inline void do_identify (ide_drive_t *drive, u8 cmd)
144 local_irq_enable(); 144 local_irq_enable();
145 ide_fix_driveid(id); 145 ide_fix_driveid(id);
146 146
147#if defined (CONFIG_SCSI_EATA_DMA) || defined (CONFIG_SCSI_EATA_PIO) || defined (CONFIG_SCSI_EATA) 147#if defined (CONFIG_SCSI_EATA_PIO) || defined (CONFIG_SCSI_EATA)
148 /* 148 /*
149 * EATA SCSI controllers do a hardware ATA emulation: 149 * EATA SCSI controllers do a hardware ATA emulation:
150 * Ignore them if there is a driver for them available. 150 * Ignore them if there is a driver for them available.
@@ -154,7 +154,7 @@ static inline void do_identify (ide_drive_t *drive, u8 cmd)
154 printk("%s: EATA SCSI HBA %.10s\n", drive->name, id->model); 154 printk("%s: EATA SCSI HBA %.10s\n", drive->name, id->model);
155 goto err_misc; 155 goto err_misc;
156 } 156 }
157#endif /* CONFIG_SCSI_EATA_DMA || CONFIG_SCSI_EATA_PIO */ 157#endif /* CONFIG_SCSI_EATA || CONFIG_SCSI_EATA_PIO */
158 158
159 /* 159 /*
160 * WIN_IDENTIFY returns little-endian info, 160 * WIN_IDENTIFY returns little-endian info,
@@ -1025,7 +1025,7 @@ static int init_irq (ide_hwif_t *hwif)
1025 BUG_ON(irqs_disabled()); 1025 BUG_ON(irqs_disabled());
1026 BUG_ON(hwif == NULL); 1026 BUG_ON(hwif == NULL);
1027 1027
1028 down(&ide_cfg_sem); 1028 mutex_lock(&ide_cfg_mtx);
1029 hwif->hwgroup = NULL; 1029 hwif->hwgroup = NULL;
1030#if MAX_HWIFS > 1 1030#if MAX_HWIFS > 1
1031 /* 1031 /*
@@ -1154,7 +1154,7 @@ static int init_irq (ide_hwif_t *hwif)
1154 printk(" (%sed with %s)", 1154 printk(" (%sed with %s)",
1155 hwif->sharing_irq ? "shar" : "serializ", match->name); 1155 hwif->sharing_irq ? "shar" : "serializ", match->name);
1156 printk("\n"); 1156 printk("\n");
1157 up(&ide_cfg_sem); 1157 mutex_unlock(&ide_cfg_mtx);
1158 return 0; 1158 return 0;
1159out_unlink: 1159out_unlink:
1160 spin_lock_irq(&ide_lock); 1160 spin_lock_irq(&ide_lock);
@@ -1177,7 +1177,7 @@ out_unlink:
1177 } 1177 }
1178 spin_unlock_irq(&ide_lock); 1178 spin_unlock_irq(&ide_lock);
1179out_up: 1179out_up:
1180 up(&ide_cfg_sem); 1180 mutex_unlock(&ide_cfg_mtx);
1181 return 1; 1181 return 1;
1182} 1182}
1183 1183
diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c
index ea94c9aa1220..fc1d8ae6a803 100644
--- a/drivers/ide/ide-proc.c
+++ b/drivers/ide/ide-proc.c
@@ -156,7 +156,7 @@ static int __ide_add_setting(ide_drive_t *drive, const char *name, int rw, int d
156{ 156{
157 ide_settings_t **p = (ide_settings_t **) &drive->settings, *setting = NULL; 157 ide_settings_t **p = (ide_settings_t **) &drive->settings, *setting = NULL;
158 158
159 down(&ide_setting_sem); 159 mutex_lock(&ide_setting_mtx);
160 while ((*p) && strcmp((*p)->name, name) < 0) 160 while ((*p) && strcmp((*p)->name, name) < 0)
161 p = &((*p)->next); 161 p = &((*p)->next);
162 if ((setting = kzalloc(sizeof(*setting), GFP_KERNEL)) == NULL) 162 if ((setting = kzalloc(sizeof(*setting), GFP_KERNEL)) == NULL)
@@ -177,10 +177,10 @@ static int __ide_add_setting(ide_drive_t *drive, const char *name, int rw, int d
177 if (auto_remove) 177 if (auto_remove)
178 setting->auto_remove = 1; 178 setting->auto_remove = 1;
179 *p = setting; 179 *p = setting;
180 up(&ide_setting_sem); 180 mutex_unlock(&ide_setting_mtx);
181 return 0; 181 return 0;
182abort: 182abort:
183 up(&ide_setting_sem); 183 mutex_unlock(&ide_setting_mtx);
184 kfree(setting); 184 kfree(setting);
185 return -1; 185 return -1;
186} 186}
@@ -224,7 +224,7 @@ static void __ide_remove_setting (ide_drive_t *drive, char *name)
224 * 224 *
225 * Automatically remove all the driver specific settings for this 225 * Automatically remove all the driver specific settings for this
226 * drive. This function may not be called from IRQ context. The 226 * drive. This function may not be called from IRQ context. The
227 * caller must hold ide_setting_sem. 227 * caller must hold ide_setting_mtx.
228 */ 228 */
229 229
230static void auto_remove_settings (ide_drive_t *drive) 230static void auto_remove_settings (ide_drive_t *drive)
@@ -269,7 +269,7 @@ static ide_settings_t *ide_find_setting_by_name(ide_drive_t *drive, char *name)
269 * @setting: drive setting 269 * @setting: drive setting
270 * 270 *
271 * Read a drive setting and return the value. The caller 271 * Read a drive setting and return the value. The caller
272 * must hold the ide_setting_sem when making this call. 272 * must hold the ide_setting_mtx when making this call.
273 * 273 *
274 * BUGS: the data return and error are the same return value 274 * BUGS: the data return and error are the same return value
275 * so an error -EINVAL and true return of the same value cannot 275 * so an error -EINVAL and true return of the same value cannot
@@ -306,7 +306,7 @@ static int ide_read_setting(ide_drive_t *drive, ide_settings_t *setting)
306 * @val: value 306 * @val: value
307 * 307 *
308 * Write a drive setting if it is possible. The caller 308 * Write a drive setting if it is possible. The caller
309 * must hold the ide_setting_sem when making this call. 309 * must hold the ide_setting_mtx when making this call.
310 * 310 *
311 * BUGS: the data return and error are the same return value 311 * BUGS: the data return and error are the same return value
312 * so an error -EINVAL and true return of the same value cannot 312 * so an error -EINVAL and true return of the same value cannot
@@ -367,7 +367,7 @@ static int set_xfer_rate (ide_drive_t *drive, int arg)
367 * @drive: drive being configured 367 * @drive: drive being configured
368 * 368 *
369 * Add the generic parts of the system settings to the /proc files. 369 * Add the generic parts of the system settings to the /proc files.
370 * The caller must not be holding the ide_setting_sem. 370 * The caller must not be holding the ide_setting_mtx.
371 */ 371 */
372 372
373void ide_add_generic_settings (ide_drive_t *drive) 373void ide_add_generic_settings (ide_drive_t *drive)
@@ -408,7 +408,7 @@ static int proc_ide_read_settings
408 408
409 proc_ide_settings_warn(); 409 proc_ide_settings_warn();
410 410
411 down(&ide_setting_sem); 411 mutex_lock(&ide_setting_mtx);
412 out += sprintf(out, "name\t\t\tvalue\t\tmin\t\tmax\t\tmode\n"); 412 out += sprintf(out, "name\t\t\tvalue\t\tmin\t\tmax\t\tmode\n");
413 out += sprintf(out, "----\t\t\t-----\t\t---\t\t---\t\t----\n"); 413 out += sprintf(out, "----\t\t\t-----\t\t---\t\t---\t\t----\n");
414 while(setting) { 414 while(setting) {
@@ -428,7 +428,7 @@ static int proc_ide_read_settings
428 setting = setting->next; 428 setting = setting->next;
429 } 429 }
430 len = out - page; 430 len = out - page;
431 up(&ide_setting_sem); 431 mutex_unlock(&ide_setting_mtx);
432 PROC_IDE_READ_RETURN(page,start,off,count,eof,len); 432 PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
433} 433}
434 434
@@ -508,16 +508,16 @@ static int proc_ide_write_settings(struct file *file, const char __user *buffer,
508 ++p; 508 ++p;
509 } 509 }
510 510
511 down(&ide_setting_sem); 511 mutex_lock(&ide_setting_mtx);
512 setting = ide_find_setting_by_name(drive, name); 512 setting = ide_find_setting_by_name(drive, name);
513 if (!setting) 513 if (!setting)
514 { 514 {
515 up(&ide_setting_sem); 515 mutex_unlock(&ide_setting_mtx);
516 goto parse_error; 516 goto parse_error;
517 } 517 }
518 if (for_real) 518 if (for_real)
519 ide_write_setting(drive, setting, val * setting->div_factor / setting->mul_factor); 519 ide_write_setting(drive, setting, val * setting->div_factor / setting->mul_factor);
520 up(&ide_setting_sem); 520 mutex_unlock(&ide_setting_mtx);
521 } 521 }
522 } while (!for_real++); 522 } while (!for_real++);
523 free_page((unsigned long)buf); 523 free_page((unsigned long)buf);
@@ -705,7 +705,7 @@ EXPORT_SYMBOL(ide_proc_register_driver);
705 * Clean up the driver specific /proc files and IDE settings 705 * Clean up the driver specific /proc files and IDE settings
706 * for a given drive. 706 * for a given drive.
707 * 707 *
708 * Takes ide_setting_sem and ide_lock. 708 * Takes ide_setting_mtx and ide_lock.
709 * Caller must hold none of the locks. 709 * Caller must hold none of the locks.
710 */ 710 */
711 711
@@ -715,10 +715,10 @@ void ide_proc_unregister_driver(ide_drive_t *drive, ide_driver_t *driver)
715 715
716 ide_remove_proc_entries(drive->proc, driver->proc); 716 ide_remove_proc_entries(drive->proc, driver->proc);
717 717
718 down(&ide_setting_sem); 718 mutex_lock(&ide_setting_mtx);
719 spin_lock_irqsave(&ide_lock, flags); 719 spin_lock_irqsave(&ide_lock, flags);
720 /* 720 /*
721 * ide_setting_sem protects the settings list 721 * ide_setting_mtx protects the settings list
722 * ide_lock protects the use of settings 722 * ide_lock protects the use of settings
723 * 723 *
724 * so we need to hold both, ide_settings_sem because we want to 724 * so we need to hold both, ide_settings_sem because we want to
@@ -726,11 +726,11 @@ void ide_proc_unregister_driver(ide_drive_t *drive, ide_driver_t *driver)
726 * a setting out that is being used. 726 * a setting out that is being used.
727 * 727 *
728 * OTOH both ide_{read,write}_setting are only ever used under 728 * OTOH both ide_{read,write}_setting are only ever used under
729 * ide_setting_sem. 729 * ide_setting_mtx.
730 */ 730 */
731 auto_remove_settings(drive); 731 auto_remove_settings(drive);
732 spin_unlock_irqrestore(&ide_lock, flags); 732 spin_unlock_irqrestore(&ide_lock, flags);
733 up(&ide_setting_sem); 733 mutex_unlock(&ide_setting_mtx);
734} 734}
735 735
736EXPORT_SYMBOL(ide_proc_unregister_driver); 736EXPORT_SYMBOL(ide_proc_unregister_driver);
diff --git a/drivers/ide/ide-timing.h b/drivers/ide/ide-timing.h
index c0864b1e9228..e6cb8593b5ba 100644
--- a/drivers/ide/ide-timing.h
+++ b/drivers/ide/ide-timing.h
@@ -102,66 +102,16 @@ static struct ide_timing ide_timing[] = {
102#define EZ(v,unit) ((v)?ENOUGH(v,unit):0) 102#define EZ(v,unit) ((v)?ENOUGH(v,unit):0)
103 103
104#define XFER_MODE 0xf0 104#define XFER_MODE 0xf0
105#define XFER_UDMA_133 0x48
106#define XFER_UDMA_100 0x44
107#define XFER_UDMA_66 0x42
108#define XFER_UDMA 0x40
109#define XFER_MWDMA 0x20 105#define XFER_MWDMA 0x20
110#define XFER_SWDMA 0x10
111#define XFER_EPIO 0x01 106#define XFER_EPIO 0x01
112#define XFER_PIO 0x00 107#define XFER_PIO 0x00
113 108
114static short ide_find_best_mode(ide_drive_t *drive, int map) 109static short ide_find_best_pio_mode(ide_drive_t *drive)
115{ 110{
116 struct hd_driveid *id = drive->id; 111 struct hd_driveid *id = drive->id;
117 short best = 0; 112 short best = 0;
118 113
119 if (!id) 114 if (id->field_valid & 2) { /* EIDE PIO modes */
120 return XFER_PIO_SLOW;
121
122 if ((map & XFER_UDMA) && (id->field_valid & 4)) { /* Want UDMA and UDMA bitmap valid */
123
124 if ((map & XFER_UDMA_133) == XFER_UDMA_133)
125 if ((best = (id->dma_ultra & 0x0040) ? XFER_UDMA_6 : 0)) return best;
126
127 if ((map & XFER_UDMA_100) == XFER_UDMA_100)
128 if ((best = (id->dma_ultra & 0x0020) ? XFER_UDMA_5 : 0)) return best;
129
130 if ((map & XFER_UDMA_66) == XFER_UDMA_66)
131 if ((best = (id->dma_ultra & 0x0010) ? XFER_UDMA_4 :
132 (id->dma_ultra & 0x0008) ? XFER_UDMA_3 : 0)) return best;
133
134 if ((best = (id->dma_ultra & 0x0004) ? XFER_UDMA_2 :
135 (id->dma_ultra & 0x0002) ? XFER_UDMA_1 :
136 (id->dma_ultra & 0x0001) ? XFER_UDMA_0 : 0)) return best;
137 }
138
139 if ((map & XFER_MWDMA) && (id->field_valid & 2)) { /* Want MWDMA and drive has EIDE fields */
140
141 if ((best = (id->dma_mword & 0x0004) ? XFER_MW_DMA_2 :
142 (id->dma_mword & 0x0002) ? XFER_MW_DMA_1 :
143 (id->dma_mword & 0x0001) ? XFER_MW_DMA_0 : 0)) return best;
144 }
145
146 if (map & XFER_SWDMA) { /* Want SWDMA */
147
148 if (id->field_valid & 2) { /* EIDE SWDMA */
149
150 if ((best = (id->dma_1word & 0x0004) ? XFER_SW_DMA_2 :
151 (id->dma_1word & 0x0002) ? XFER_SW_DMA_1 :
152 (id->dma_1word & 0x0001) ? XFER_SW_DMA_0 : 0)) return best;
153 }
154
155 if (id->capability & 1) { /* Pre-EIDE style SWDMA */
156
157 if ((best = (id->tDMA == 2) ? XFER_SW_DMA_2 :
158 (id->tDMA == 1) ? XFER_SW_DMA_1 :
159 (id->tDMA == 0) ? XFER_SW_DMA_0 : 0)) return best;
160 }
161 }
162
163
164 if ((map & XFER_EPIO) && (id->field_valid & 2)) { /* EIDE PIO modes */
165 115
166 if ((best = (drive->id->eide_pio_modes & 4) ? XFER_PIO_5 : 116 if ((best = (drive->id->eide_pio_modes & 4) ? XFER_PIO_5 :
167 (drive->id->eide_pio_modes & 2) ? XFER_PIO_4 : 117 (drive->id->eide_pio_modes & 2) ? XFER_PIO_4 :
@@ -262,7 +212,7 @@ static int ide_timing_compute(ide_drive_t *drive, short speed, struct ide_timing
262 */ 212 */
263 213
264 if ((speed & XFER_MODE) != XFER_PIO) { 214 if ((speed & XFER_MODE) != XFER_PIO) {
265 ide_timing_compute(drive, ide_find_best_mode(drive, XFER_PIO | XFER_EPIO), &p, T, UT); 215 ide_timing_compute(drive, ide_find_best_pio_mode(drive), &p, T, UT);
266 ide_timing_merge(&p, t, t, IDE_TIMING_ALL); 216 ide_timing_merge(&p, t, t, IDE_TIMING_ALL);
267 } 217 }
268 218
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c
index 0cd76bf66833..c948a5c17a5d 100644
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -169,7 +169,7 @@ static const u8 ide_hwif_to_major[] = { IDE0_MAJOR, IDE1_MAJOR,
169static int idebus_parameter; /* holds the "idebus=" parameter */ 169static int idebus_parameter; /* holds the "idebus=" parameter */
170static int system_bus_speed; /* holds what we think is VESA/PCI bus speed */ 170static int system_bus_speed; /* holds what we think is VESA/PCI bus speed */
171 171
172DECLARE_MUTEX(ide_cfg_sem); 172DEFINE_MUTEX(ide_cfg_mtx);
173 __cacheline_aligned_in_smp DEFINE_SPINLOCK(ide_lock); 173 __cacheline_aligned_in_smp DEFINE_SPINLOCK(ide_lock);
174 174
175#ifdef CONFIG_IDEPCI_PCIBUS_ORDER 175#ifdef CONFIG_IDEPCI_PCIBUS_ORDER
@@ -460,6 +460,8 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif)
460 hwif->mwdma_mask = tmp_hwif->mwdma_mask; 460 hwif->mwdma_mask = tmp_hwif->mwdma_mask;
461 hwif->swdma_mask = tmp_hwif->swdma_mask; 461 hwif->swdma_mask = tmp_hwif->swdma_mask;
462 462
463 hwif->cbl = tmp_hwif->cbl;
464
463 hwif->chipset = tmp_hwif->chipset; 465 hwif->chipset = tmp_hwif->chipset;
464 hwif->hold = tmp_hwif->hold; 466 hwif->hold = tmp_hwif->hold;
465 467
@@ -496,8 +498,8 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif)
496 hwif->ide_dma_clear_irq = tmp_hwif->ide_dma_clear_irq; 498 hwif->ide_dma_clear_irq = tmp_hwif->ide_dma_clear_irq;
497 hwif->dma_host_on = tmp_hwif->dma_host_on; 499 hwif->dma_host_on = tmp_hwif->dma_host_on;
498 hwif->dma_host_off = tmp_hwif->dma_host_off; 500 hwif->dma_host_off = tmp_hwif->dma_host_off;
499 hwif->ide_dma_lostirq = tmp_hwif->ide_dma_lostirq; 501 hwif->dma_lost_irq = tmp_hwif->dma_lost_irq;
500 hwif->ide_dma_timeout = tmp_hwif->ide_dma_timeout; 502 hwif->dma_timeout = tmp_hwif->dma_timeout;
501 503
502 hwif->OUTB = tmp_hwif->OUTB; 504 hwif->OUTB = tmp_hwif->OUTB;
503 hwif->OUTBSYNC = tmp_hwif->OUTBSYNC; 505 hwif->OUTBSYNC = tmp_hwif->OUTBSYNC;
@@ -533,7 +535,6 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif)
533 hwif->extra_base = tmp_hwif->extra_base; 535 hwif->extra_base = tmp_hwif->extra_base;
534 hwif->extra_ports = tmp_hwif->extra_ports; 536 hwif->extra_ports = tmp_hwif->extra_ports;
535 hwif->autodma = tmp_hwif->autodma; 537 hwif->autodma = tmp_hwif->autodma;
536 hwif->udma_four = tmp_hwif->udma_four;
537 538
538 hwif->hwif_data = tmp_hwif->hwif_data; 539 hwif->hwif_data = tmp_hwif->hwif_data;
539} 540}
@@ -564,7 +565,7 @@ void ide_unregister(unsigned int index)
564{ 565{
565 ide_drive_t *drive; 566 ide_drive_t *drive;
566 ide_hwif_t *hwif, *g; 567 ide_hwif_t *hwif, *g;
567 static ide_hwif_t tmp_hwif; /* protected by ide_cfg_sem */ 568 static ide_hwif_t tmp_hwif; /* protected by ide_cfg_mtx */
568 ide_hwgroup_t *hwgroup; 569 ide_hwgroup_t *hwgroup;
569 int irq_count = 0, unit; 570 int irq_count = 0, unit;
570 571
@@ -572,7 +573,7 @@ void ide_unregister(unsigned int index)
572 573
573 BUG_ON(in_interrupt()); 574 BUG_ON(in_interrupt());
574 BUG_ON(irqs_disabled()); 575 BUG_ON(irqs_disabled());
575 down(&ide_cfg_sem); 576 mutex_lock(&ide_cfg_mtx);
576 spin_lock_irq(&ide_lock); 577 spin_lock_irq(&ide_lock);
577 hwif = &ide_hwifs[index]; 578 hwif = &ide_hwifs[index];
578 if (!hwif->present) 579 if (!hwif->present)
@@ -679,7 +680,7 @@ void ide_unregister(unsigned int index)
679 680
680abort: 681abort:
681 spin_unlock_irq(&ide_lock); 682 spin_unlock_irq(&ide_lock);
682 up(&ide_cfg_sem); 683 mutex_unlock(&ide_cfg_mtx);
683} 684}
684 685
685EXPORT_SYMBOL(ide_unregister); 686EXPORT_SYMBOL(ide_unregister);
@@ -817,9 +818,9 @@ EXPORT_SYMBOL(ide_register_hw);
817 * Locks for IDE setting functionality 818 * Locks for IDE setting functionality
818 */ 819 */
819 820
820DECLARE_MUTEX(ide_setting_sem); 821DEFINE_MUTEX(ide_setting_mtx);
821 822
822EXPORT_SYMBOL_GPL(ide_setting_sem); 823EXPORT_SYMBOL_GPL(ide_setting_mtx);
823 824
824/** 825/**
825 * ide_spin_wait_hwgroup - wait for group 826 * ide_spin_wait_hwgroup - wait for group
@@ -1192,11 +1193,11 @@ int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device
1192 } 1193 }
1193 1194
1194read_val: 1195read_val:
1195 down(&ide_setting_sem); 1196 mutex_lock(&ide_setting_mtx);
1196 spin_lock_irqsave(&ide_lock, flags); 1197 spin_lock_irqsave(&ide_lock, flags);
1197 err = *val; 1198 err = *val;
1198 spin_unlock_irqrestore(&ide_lock, flags); 1199 spin_unlock_irqrestore(&ide_lock, flags);
1199 up(&ide_setting_sem); 1200 mutex_unlock(&ide_setting_mtx);
1200 return err >= 0 ? put_user(err, (long __user *)arg) : err; 1201 return err >= 0 ? put_user(err, (long __user *)arg) : err;
1201 1202
1202set_val: 1203set_val:
@@ -1206,9 +1207,9 @@ set_val:
1206 if (!capable(CAP_SYS_ADMIN)) 1207 if (!capable(CAP_SYS_ADMIN))
1207 err = -EACCES; 1208 err = -EACCES;
1208 else { 1209 else {
1209 down(&ide_setting_sem); 1210 mutex_lock(&ide_setting_mtx);
1210 err = setfunc(drive, arg); 1211 err = setfunc(drive, arg);
1211 up(&ide_setting_sem); 1212 mutex_unlock(&ide_setting_mtx);
1212 } 1213 }
1213 } 1214 }
1214 return err; 1215 return err;
@@ -1548,7 +1549,11 @@ static int __init ide_setup(char *s)
1548 goto bad_option; 1549 goto bad_option;
1549 case -7: /* ata66 */ 1550 case -7: /* ata66 */
1550#ifdef CONFIG_BLK_DEV_IDEPCI 1551#ifdef CONFIG_BLK_DEV_IDEPCI
1551 hwif->udma_four = 1; 1552 /*
1553 * Use ATA_CBL_PATA40_SHORT so drive side
1554 * cable detection is also overriden.
1555 */
1556 hwif->cbl = ATA_CBL_PATA40_SHORT;
1552 goto obsolete_option; 1557 goto obsolete_option;
1553#else 1558#else
1554 goto bad_hwif; 1559 goto bad_hwif;
diff --git a/drivers/ide/legacy/hd.c b/drivers/ide/legacy/hd.c
index 45ed03591cd8..7f4c0a5050a1 100644
--- a/drivers/ide/legacy/hd.c
+++ b/drivers/ide/legacy/hd.c
@@ -130,7 +130,7 @@ struct hd_i_struct {
130 130
131#ifdef HD_TYPE 131#ifdef HD_TYPE
132static struct hd_i_struct hd_info[] = { HD_TYPE }; 132static struct hd_i_struct hd_info[] = { HD_TYPE };
133static int NR_HD = ((sizeof (hd_info))/(sizeof (struct hd_i_struct))); 133static int NR_HD = ARRAY_SIZE(hd_info);
134#else 134#else
135static struct hd_i_struct hd_info[MAX_HD]; 135static struct hd_i_struct hd_info[MAX_HD];
136static int NR_HD; 136static int NR_HD;
@@ -623,7 +623,8 @@ repeat:
623 cyl = track / disk->head; 623 cyl = track / disk->head;
624#ifdef DEBUG 624#ifdef DEBUG
625 printk("%s: %sing: CHS=%d/%d/%d, sectors=%d, buffer=%p\n", 625 printk("%s: %sing: CHS=%d/%d/%d, sectors=%d, buffer=%p\n",
626 req->rq_disk->disk_name, (req->cmd == READ)?"read":"writ", 626 req->rq_disk->disk_name,
627 req_data_dir(req) == READ ? "read" : "writ",
627 cyl, head, sec, nsect, req->buffer); 628 cyl, head, sec, nsect, req->buffer);
628#endif 629#endif
629 if (blk_fs_request(req)) { 630 if (blk_fs_request(req)) {
diff --git a/drivers/ide/legacy/macide.c b/drivers/ide/legacy/macide.c
index c211fc78345d..b557c45a5a9d 100644
--- a/drivers/ide/legacy/macide.c
+++ b/drivers/ide/legacy/macide.c
@@ -77,15 +77,6 @@ int macide_ack_intr(ide_hwif_t* hwif)
77 return 0; 77 return 0;
78} 78}
79 79
80#ifdef CONFIG_BLK_DEV_MAC_MEDIABAY
81static void macide_mediabay_interrupt(int irq, void *dev_id)
82{
83 int state = baboon->mb_status & 0x04;
84
85 printk(KERN_INFO "macide: media bay %s detected\n", state? "removal":"insertion");
86}
87#endif
88
89/* 80/*
90 * Probe for a Macintosh IDE interface 81 * Probe for a Macintosh IDE interface
91 */ 82 */
@@ -128,11 +119,6 @@ void macide_init(void)
128 ide_drive_t *drive = &ide_hwifs[index].drives[0]; 119 ide_drive_t *drive = &ide_hwifs[index].drives[0];
129 drive->capacity64 = drive->cyl*drive->head*drive->sect; 120 drive->capacity64 = drive->cyl*drive->head*drive->sect;
130 121
131#ifdef CONFIG_BLK_DEV_MAC_MEDIABAY
132 request_irq(IRQ_BABOON_2, macide_mediabay_interrupt,
133 IRQ_FLG_FAST, "mediabay",
134 macide_mediabay_interrupt);
135#endif
136 } 122 }
137 break; 123 break;
138 124
diff --git a/drivers/ide/mips/au1xxx-ide.c b/drivers/ide/mips/au1xxx-ide.c
index ca95e990862e..2e7013a2a7f6 100644
--- a/drivers/ide/mips/au1xxx-ide.c
+++ b/drivers/ide/mips/au1xxx-ide.c
@@ -381,9 +381,7 @@ static int auide_dma_setup(ide_drive_t *drive)
381 381
382static int auide_dma_check(ide_drive_t *drive) 382static int auide_dma_check(ide_drive_t *drive)
383{ 383{
384 u8 speed; 384 u8 speed = ide_max_dma_mode(drive);
385
386#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
387 385
388 if( dbdma_init_done == 0 ){ 386 if( dbdma_init_done == 0 ){
389 auide_hwif.white_list = ide_in_drive_list(drive->id, 387 auide_hwif.white_list = ide_in_drive_list(drive->id,
@@ -394,7 +392,6 @@ static int auide_dma_check(ide_drive_t *drive)
394 auide_ddma_init(&auide_hwif); 392 auide_ddma_init(&auide_hwif);
395 dbdma_init_done = 1; 393 dbdma_init_done = 1;
396 } 394 }
397#endif
398 395
399 /* Is the drive in our DMA black list? */ 396 /* Is the drive in our DMA black list? */
400 397
@@ -409,8 +406,6 @@ static int auide_dma_check(ide_drive_t *drive)
409 else 406 else
410 drive->using_dma = 1; 407 drive->using_dma = 1;
411 408
412 speed = ide_find_best_mode(drive, XFER_PIO | XFER_MWDMA);
413
414 if (drive->autodma && (speed & XFER_MODE) != XFER_PIO) 409 if (drive->autodma && (speed & XFER_MODE) != XFER_PIO)
415 return 0; 410 return 0;
416 411
@@ -456,10 +451,9 @@ static void auide_dma_off_quietly(ide_drive_t *drive)
456 drive->using_dma = 0; 451 drive->using_dma = 0;
457} 452}
458 453
459static int auide_dma_lostirq(ide_drive_t *drive) 454static void auide_dma_lost_irq(ide_drive_t *drive)
460{ 455{
461 printk(KERN_ERR "%s: IRQ lost\n", drive->name); 456 printk(KERN_ERR "%s: IRQ lost\n", drive->name);
462 return 0;
463} 457}
464 458
465static void auide_ddma_tx_callback(int irq, void *param) 459static void auide_ddma_tx_callback(int irq, void *param)
@@ -489,16 +483,16 @@ static void auide_init_dbdma_dev(dbdev_tab_t *dev, u32 dev_id, u32 tsize, u32 de
489 483
490#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA) 484#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA)
491 485
492static int auide_dma_timeout(ide_drive_t *drive) 486static void auide_dma_timeout(ide_drive_t *drive)
493{ 487{
494// printk("%s\n", __FUNCTION__); 488 ide_hwif_t *hwif = HWIF(drive);
495 489
496 printk(KERN_ERR "%s: DMA timeout occurred: ", drive->name); 490 printk(KERN_ERR "%s: DMA timeout occurred: ", drive->name);
497 491
498 if (HWIF(drive)->ide_dma_test_irq(drive)) 492 if (hwif->ide_dma_test_irq(drive))
499 return 0; 493 return;
500 494
501 return HWIF(drive)->ide_dma_end(drive); 495 hwif->ide_dma_end(drive);
502} 496}
503 497
504 498
@@ -721,7 +715,7 @@ static int au_ide_probe(struct device *dev)
721 715
722#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA 716#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
723 hwif->dma_off_quietly = &auide_dma_off_quietly; 717 hwif->dma_off_quietly = &auide_dma_off_quietly;
724 hwif->ide_dma_timeout = &auide_dma_timeout; 718 hwif->dma_timeout = &auide_dma_timeout;
725 719
726 hwif->ide_dma_check = &auide_dma_check; 720 hwif->ide_dma_check = &auide_dma_check;
727 hwif->dma_exec_cmd = &auide_dma_exec_cmd; 721 hwif->dma_exec_cmd = &auide_dma_exec_cmd;
@@ -731,7 +725,7 @@ static int au_ide_probe(struct device *dev)
731 hwif->ide_dma_test_irq = &auide_dma_test_irq; 725 hwif->ide_dma_test_irq = &auide_dma_test_irq;
732 hwif->dma_host_off = &auide_dma_host_off; 726 hwif->dma_host_off = &auide_dma_host_off;
733 hwif->dma_host_on = &auide_dma_host_on; 727 hwif->dma_host_on = &auide_dma_host_on;
734 hwif->ide_dma_lostirq = &auide_dma_lostirq; 728 hwif->dma_lost_irq = &auide_dma_lost_irq;
735 hwif->ide_dma_on = &auide_dma_on; 729 hwif->ide_dma_on = &auide_dma_on;
736 730
737 hwif->autodma = 1; 731 hwif->autodma = 1;
diff --git a/drivers/ide/pci/aec62xx.c b/drivers/ide/pci/aec62xx.c
index b173bc66ce1e..e5d09367627e 100644
--- a/drivers/ide/pci/aec62xx.c
+++ b/drivers/ide/pci/aec62xx.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * linux/drivers/ide/pci/aec62xx.c Version 0.21 Apr 21, 2007 2 * linux/drivers/ide/pci/aec62xx.c Version 0.24 May 24, 2007
3 * 3 *
4 * Copyright (C) 1999-2002 Andre Hedrick <andre@linux-ide.org> 4 * Copyright (C) 1999-2002 Andre Hedrick <andre@linux-ide.org>
5 * Copyright (C) 2007 MontaVista Software, Inc. <source@mvista.com> 5 * Copyright (C) 2007 MontaVista Software, Inc. <source@mvista.com>
@@ -140,25 +140,10 @@ static int aec6260_tune_chipset (ide_drive_t *drive, u8 xferspeed)
140 return(ide_config_drive_speed(drive, speed)); 140 return(ide_config_drive_speed(drive, speed));
141} 141}
142 142
143static int aec62xx_tune_chipset (ide_drive_t *drive, u8 speed)
144{
145 switch (HWIF(drive)->pci_dev->device) {
146 case PCI_DEVICE_ID_ARTOP_ATP865:
147 case PCI_DEVICE_ID_ARTOP_ATP865R:
148 case PCI_DEVICE_ID_ARTOP_ATP860:
149 case PCI_DEVICE_ID_ARTOP_ATP860R:
150 return ((int) aec6260_tune_chipset(drive, speed));
151 case PCI_DEVICE_ID_ARTOP_ATP850UF:
152 return ((int) aec6210_tune_chipset(drive, speed));
153 default:
154 return -1;
155 }
156}
157
158static void aec62xx_tune_drive (ide_drive_t *drive, u8 pio) 143static void aec62xx_tune_drive (ide_drive_t *drive, u8 pio)
159{ 144{
160 pio = ide_get_best_pio_mode(drive, pio, 4, NULL); 145 pio = ide_get_best_pio_mode(drive, pio, 4, NULL);
161 (void) aec62xx_tune_chipset(drive, pio + XFER_PIO_0); 146 (void) HWIF(drive)->speedproc(drive, pio + XFER_PIO_0);
162} 147}
163 148
164static int aec62xx_config_drive_xfer_rate (ide_drive_t *drive) 149static int aec62xx_config_drive_xfer_rate (ide_drive_t *drive)
@@ -172,12 +157,9 @@ static int aec62xx_config_drive_xfer_rate (ide_drive_t *drive)
172 return -1; 157 return -1;
173} 158}
174 159
175static int aec62xx_irq_timeout (ide_drive_t *drive) 160static void aec62xx_dma_lost_irq (ide_drive_t *drive)
176{ 161{
177 ide_hwif_t *hwif = HWIF(drive); 162 switch (HWIF(drive)->pci_dev->device) {
178 struct pci_dev *dev = hwif->pci_dev;
179
180 switch(dev->device) {
181 case PCI_DEVICE_ID_ARTOP_ATP860: 163 case PCI_DEVICE_ID_ARTOP_ATP860:
182 case PCI_DEVICE_ID_ARTOP_ATP860R: 164 case PCI_DEVICE_ID_ARTOP_ATP860R:
183 case PCI_DEVICE_ID_ARTOP_ATP865: 165 case PCI_DEVICE_ID_ARTOP_ATP865:
@@ -186,7 +168,6 @@ static int aec62xx_irq_timeout (ide_drive_t *drive)
186 default: 168 default:
187 break; 169 break;
188 } 170 }
189 return 0;
190} 171}
191 172
192static unsigned int __devinit init_chipset_aec62xx(struct pci_dev *dev, const char *name) 173static unsigned int __devinit init_chipset_aec62xx(struct pci_dev *dev, const char *name)
@@ -224,64 +205,46 @@ static unsigned int __devinit init_chipset_aec62xx(struct pci_dev *dev, const ch
224 205
225static void __devinit init_hwif_aec62xx(ide_hwif_t *hwif) 206static void __devinit init_hwif_aec62xx(ide_hwif_t *hwif)
226{ 207{
227 struct pci_dev *dev = hwif->pci_dev; 208 struct pci_dev *dev = hwif->pci_dev;
209 u8 reg54 = 0, mask = hwif->channel ? 0xf0 : 0x0f;
210 unsigned long flags;
228 211
229 hwif->autodma = 0;
230 hwif->tuneproc = &aec62xx_tune_drive; 212 hwif->tuneproc = &aec62xx_tune_drive;
231 hwif->speedproc = &aec62xx_tune_chipset;
232 213
233 if (dev->device == PCI_DEVICE_ID_ARTOP_ATP850UF) 214 if (dev->device == PCI_DEVICE_ID_ARTOP_ATP850UF) {
234 hwif->serialized = hwif->channel; 215 if(hwif->mate)
235 216 hwif->mate->serialized = hwif->serialized = 1;
236 if (hwif->mate) 217 hwif->speedproc = &aec6210_tune_chipset;
237 hwif->mate->serialized = hwif->serialized; 218 } else
219 hwif->speedproc = &aec6260_tune_chipset;
238 220
239 if (!hwif->dma_base) { 221 if (!hwif->dma_base) {
240 hwif->drives[0].autotune = 1; 222 hwif->drives[0].autotune = hwif->drives[1].autotune = 1;
241 hwif->drives[1].autotune = 1;
242 return; 223 return;
243 } 224 }
244 225
245 hwif->ultra_mask = hwif->cds->udma_mask; 226 hwif->ultra_mask = hwif->cds->udma_mask;
246
247 /* atp865 and atp865r */
248 if (hwif->ultra_mask == 0x3f) {
249 /* check bit 0x10 of DMA status register */
250 if (inb(pci_resource_start(dev, 4) + 2) & 0x10)
251 hwif->ultra_mask = 0x7f; /* udma0-6 */
252 }
253
254 hwif->mwdma_mask = 0x07; 227 hwif->mwdma_mask = 0x07;
255 228
256 hwif->ide_dma_check = &aec62xx_config_drive_xfer_rate; 229 hwif->ide_dma_check = &aec62xx_config_drive_xfer_rate;
257 hwif->ide_dma_lostirq = &aec62xx_irq_timeout; 230 hwif->dma_lost_irq = &aec62xx_dma_lost_irq;
258
259 if (!noautodma)
260 hwif->autodma = 1;
261 hwif->drives[0].autodma = hwif->autodma;
262 hwif->drives[1].autodma = hwif->autodma;
263}
264
265static void __devinit init_dma_aec62xx(ide_hwif_t *hwif, unsigned long dmabase)
266{
267 struct pci_dev *dev = hwif->pci_dev;
268 231
269 if (dev->device == PCI_DEVICE_ID_ARTOP_ATP850UF) { 232 if (dev->device == PCI_DEVICE_ID_ARTOP_ATP850UF) {
270 u8 reg54h = 0;
271 unsigned long flags;
272
273 spin_lock_irqsave(&ide_lock, flags); 233 spin_lock_irqsave(&ide_lock, flags);
274 pci_read_config_byte(dev, 0x54, &reg54h); 234 pci_read_config_byte (dev, 0x54, &reg54);
275 pci_write_config_byte(dev, 0x54, reg54h & ~(hwif->channel ? 0xF0 : 0x0F)); 235 pci_write_config_byte(dev, 0x54, (reg54 & ~mask));
276 spin_unlock_irqrestore(&ide_lock, flags); 236 spin_unlock_irqrestore(&ide_lock, flags);
277 } else { 237 } else if (hwif->cbl != ATA_CBL_PATA40_SHORT) {
278 u8 ata66 = 0; 238 u8 ata66 = 0, mask = hwif->channel ? 0x02 : 0x01;
239
279 pci_read_config_byte(hwif->pci_dev, 0x49, &ata66); 240 pci_read_config_byte(hwif->pci_dev, 0x49, &ata66);
280 if (!(hwif->udma_four)) 241
281 hwif->udma_four = (ata66&(hwif->channel?0x02:0x01))?0:1; 242 hwif->cbl = (ata66 & mask) ? ATA_CBL_PATA40 : ATA_CBL_PATA80;
282 } 243 }
283 244
284 ide_setup_dma(hwif, dmabase, 8); 245 if (!noautodma)
246 hwif->autodma = 1;
247 hwif->drives[0].autodma = hwif->drives[1].autodma = hwif->autodma;
285} 248}
286 249
287static int __devinit init_setup_aec62xx(struct pci_dev *dev, ide_pci_device_t *d) 250static int __devinit init_setup_aec62xx(struct pci_dev *dev, ide_pci_device_t *d)
@@ -291,16 +254,12 @@ static int __devinit init_setup_aec62xx(struct pci_dev *dev, ide_pci_device_t *d
291 254
292static int __devinit init_setup_aec6x80(struct pci_dev *dev, ide_pci_device_t *d) 255static int __devinit init_setup_aec6x80(struct pci_dev *dev, ide_pci_device_t *d)
293{ 256{
294 unsigned long bar4reg = pci_resource_start(dev, 4); 257 unsigned long dma_base = pci_resource_start(dev, 4);
295 258
296 if (inb(bar4reg+2) & 0x10) { 259 if (inb(dma_base + 2) & 0x10) {
297 strcpy(d->name, "AEC6880"); 260 d->name = (dev->device == PCI_DEVICE_ID_ARTOP_ATP865R) ?
298 if (dev->device == PCI_DEVICE_ID_ARTOP_ATP865R) 261 "AEC6880R" : "AEC6880";
299 strcpy(d->name, "AEC6880R"); 262 d->udma_mask = 0x7f; /* udma0-6 */
300 } else {
301 strcpy(d->name, "AEC6280");
302 if (dev->device == PCI_DEVICE_ID_ARTOP_ATP865R)
303 strcpy(d->name, "AEC6280R");
304 } 263 }
305 264
306 return ide_setup_pci_device(dev, d); 265 return ide_setup_pci_device(dev, d);
@@ -312,7 +271,6 @@ static ide_pci_device_t aec62xx_chipsets[] __devinitdata = {
312 .init_setup = init_setup_aec62xx, 271 .init_setup = init_setup_aec62xx,
313 .init_chipset = init_chipset_aec62xx, 272 .init_chipset = init_chipset_aec62xx,
314 .init_hwif = init_hwif_aec62xx, 273 .init_hwif = init_hwif_aec62xx,
315 .init_dma = init_dma_aec62xx,
316 .channels = 2, 274 .channels = 2,
317 .autodma = AUTODMA, 275 .autodma = AUTODMA,
318 .enablebits = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}}, 276 .enablebits = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}},
@@ -323,7 +281,6 @@ static ide_pci_device_t aec62xx_chipsets[] __devinitdata = {
323 .init_setup = init_setup_aec62xx, 281 .init_setup = init_setup_aec62xx,
324 .init_chipset = init_chipset_aec62xx, 282 .init_chipset = init_chipset_aec62xx,
325 .init_hwif = init_hwif_aec62xx, 283 .init_hwif = init_hwif_aec62xx,
326 .init_dma = init_dma_aec62xx,
327 .channels = 2, 284 .channels = 2,
328 .autodma = NOAUTODMA, 285 .autodma = NOAUTODMA,
329 .bootable = OFF_BOARD, 286 .bootable = OFF_BOARD,
@@ -333,28 +290,25 @@ static ide_pci_device_t aec62xx_chipsets[] __devinitdata = {
333 .init_setup = init_setup_aec62xx, 290 .init_setup = init_setup_aec62xx,
334 .init_chipset = init_chipset_aec62xx, 291 .init_chipset = init_chipset_aec62xx,
335 .init_hwif = init_hwif_aec62xx, 292 .init_hwif = init_hwif_aec62xx,
336 .init_dma = init_dma_aec62xx,
337 .channels = 2, 293 .channels = 2,
338 .autodma = AUTODMA, 294 .autodma = AUTODMA,
339 .enablebits = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}}, 295 .enablebits = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}},
340 .bootable = NEVER_BOARD, 296 .bootable = NEVER_BOARD,
341 .udma_mask = 0x1f, /* udma0-4 */ 297 .udma_mask = 0x1f, /* udma0-4 */
342 },{ /* 3 */ 298 },{ /* 3 */
343 .name = "AEC6X80", 299 .name = "AEC6280",
344 .init_setup = init_setup_aec6x80, 300 .init_setup = init_setup_aec6x80,
345 .init_chipset = init_chipset_aec62xx, 301 .init_chipset = init_chipset_aec62xx,
346 .init_hwif = init_hwif_aec62xx, 302 .init_hwif = init_hwif_aec62xx,
347 .init_dma = init_dma_aec62xx,
348 .channels = 2, 303 .channels = 2,
349 .autodma = AUTODMA, 304 .autodma = AUTODMA,
350 .bootable = OFF_BOARD, 305 .bootable = OFF_BOARD,
351 .udma_mask = 0x3f, /* udma0-5 */ 306 .udma_mask = 0x3f, /* udma0-5 */
352 },{ /* 4 */ 307 },{ /* 4 */
353 .name = "AEC6X80R", 308 .name = "AEC6280R",
354 .init_setup = init_setup_aec6x80, 309 .init_setup = init_setup_aec6x80,
355 .init_chipset = init_chipset_aec62xx, 310 .init_chipset = init_chipset_aec62xx,
356 .init_hwif = init_hwif_aec62xx, 311 .init_hwif = init_hwif_aec62xx,
357 .init_dma = init_dma_aec62xx,
358 .channels = 2, 312 .channels = 2,
359 .autodma = AUTODMA, 313 .autodma = AUTODMA,
360 .enablebits = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}}, 314 .enablebits = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}},
@@ -370,13 +324,16 @@ static ide_pci_device_t aec62xx_chipsets[] __devinitdata = {
370 * 324 *
371 * Called when the PCI registration layer (or the IDE initialization) 325 * Called when the PCI registration layer (or the IDE initialization)
372 * finds a device matching our IDE device tables. 326 * finds a device matching our IDE device tables.
327 *
328 * NOTE: since we're going to modify the 'name' field for AEC-6[26]80[R]
329 * chips, pass a local copy of 'struct pci_device_id' down the call chain.
373 */ 330 */
374 331
375static int __devinit aec62xx_init_one(struct pci_dev *dev, const struct pci_device_id *id) 332static int __devinit aec62xx_init_one(struct pci_dev *dev, const struct pci_device_id *id)
376{ 333{
377 ide_pci_device_t *d = &aec62xx_chipsets[id->driver_data]; 334 ide_pci_device_t d = aec62xx_chipsets[id->driver_data];
378 335
379 return d->init_setup(dev, d); 336 return d.init_setup(dev, &d);
380} 337}
381 338
382static struct pci_device_id aec62xx_pci_tbl[] = { 339static struct pci_device_id aec62xx_pci_tbl[] = {
diff --git a/drivers/ide/pci/alim15x3.c b/drivers/ide/pci/alim15x3.c
index 27525ec2e19a..8a6b27b3bcc3 100644
--- a/drivers/ide/pci/alim15x3.c
+++ b/drivers/ide/pci/alim15x3.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * linux/drivers/ide/pci/alim15x3.c Version 0.21 2007/02/03 2 * linux/drivers/ide/pci/alim15x3.c Version 0.25 Jun 9 2007
3 * 3 *
4 * Copyright (C) 1998-2000 Michel Aubry, Maintainer 4 * Copyright (C) 1998-2000 Michel Aubry, Maintainer
5 * Copyright (C) 1998-2000 Andrzej Krzysztofowicz, Maintainer 5 * Copyright (C) 1998-2000 Andrzej Krzysztofowicz, Maintainer
@@ -10,6 +10,7 @@
10 * Copyright (C) 2002 Alan Cox <alan@redhat.com> 10 * Copyright (C) 2002 Alan Cox <alan@redhat.com>
11 * ALi (now ULi M5228) support by Clear Zhang <Clear.Zhang@ali.com.tw> 11 * ALi (now ULi M5228) support by Clear Zhang <Clear.Zhang@ali.com.tw>
12 * Copyright (C) 2007 MontaVista Software, Inc. <source@mvista.com> 12 * Copyright (C) 2007 MontaVista Software, Inc. <source@mvista.com>
13 * Copyright (C) 2007 Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
13 * 14 *
14 * (U)DMA capable version of ali 1533/1543(C), 1535(D) 15 * (U)DMA capable version of ali 1533/1543(C), 1535(D)
15 * 16 *
@@ -36,6 +37,7 @@
36#include <linux/hdreg.h> 37#include <linux/hdreg.h>
37#include <linux/ide.h> 38#include <linux/ide.h>
38#include <linux/init.h> 39#include <linux/init.h>
40#include <linux/dmi.h>
39 41
40#include <asm/io.h> 42#include <asm/io.h>
41 43
@@ -583,6 +585,35 @@ out:
583 return 0; 585 return 0;
584} 586}
585 587
588/*
589 * Cable special cases
590 */
591
592static struct dmi_system_id cable_dmi_table[] = {
593 {
594 .ident = "HP Pavilion N5430",
595 .matches = {
596 DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
597 DMI_MATCH(DMI_BOARD_NAME, "OmniBook N32N-736"),
598 },
599 },
600 { }
601};
602
603static int ali_cable_override(struct pci_dev *pdev)
604{
605 /* Fujitsu P2000 */
606 if (pdev->subsystem_vendor == 0x10CF &&
607 pdev->subsystem_device == 0x10AF)
608 return 1;
609
610 /* Systems by DMI */
611 if (dmi_check_system(cable_dmi_table))
612 return 1;
613
614 return 0;
615}
616
586/** 617/**
587 * ata66_ali15x3 - check for UDMA 66 support 618 * ata66_ali15x3 - check for UDMA 66 support
588 * @hwif: IDE interface 619 * @hwif: IDE interface
@@ -594,37 +625,31 @@ out:
594 * FIXME: frobs bits that are not defined on newer ALi devicea 625 * FIXME: frobs bits that are not defined on newer ALi devicea
595 */ 626 */
596 627
597static unsigned int __devinit ata66_ali15x3 (ide_hwif_t *hwif) 628static u8 __devinit ata66_ali15x3(ide_hwif_t *hwif)
598{ 629{
599 struct pci_dev *dev = hwif->pci_dev; 630 struct pci_dev *dev = hwif->pci_dev;
600 unsigned int ata66 = 0;
601 u8 cable_80_pin[2] = { 0, 0 };
602
603 unsigned long flags; 631 unsigned long flags;
604 u8 tmpbyte; 632 u8 cbl = ATA_CBL_PATA40, tmpbyte;
605 633
606 local_irq_save(flags); 634 local_irq_save(flags);
607 635
608 if (m5229_revision >= 0xC2) { 636 if (m5229_revision >= 0xC2) {
609 /* 637 /*
610 * Ultra66 cable detection (from Host View) 638 * m5229 80-pin cable detection (from Host View)
611 * m5229, 0x4a, bit0: primary, bit1: secondary 80 pin 639 *
612 */ 640 * 0x4a bit0 is 0 => primary channel has 80-pin
613 pci_read_config_byte(dev, 0x4a, &tmpbyte); 641 * 0x4a bit1 is 0 => secondary channel has 80-pin
614 /* 642 *
615 * 0x4a, bit0 is 0 => primary channel 643 * Certain laptops use short but suitable cables
616 * has 80-pin (from host view) 644 * and don't implement the detect logic.
617 */
618 if (!(tmpbyte & 0x01)) cable_80_pin[0] = 1;
619 /*
620 * 0x4a, bit1 is 0 => secondary channel
621 * has 80-pin (from host view)
622 */
623 if (!(tmpbyte & 0x02)) cable_80_pin[1] = 1;
624 /*
625 * Allow ata66 if cable of current channel has 80 pins
626 */ 645 */
627 ata66 = (hwif->channel)?cable_80_pin[1]:cable_80_pin[0]; 646 if (ali_cable_override(dev))
647 cbl = ATA_CBL_PATA40_SHORT;
648 else {
649 pci_read_config_byte(dev, 0x4a, &tmpbyte);
650 if ((tmpbyte & (1 << hwif->channel)) == 0)
651 cbl = ATA_CBL_PATA80;
652 }
628 } else { 653 } else {
629 /* 654 /*
630 * check m1533, 0x5e, bit 1~4 == 1001 => & 00011110 = 00010010 655 * check m1533, 0x5e, bit 1~4 == 1001 => & 00011110 = 00010010
@@ -657,7 +682,7 @@ static unsigned int __devinit ata66_ali15x3 (ide_hwif_t *hwif)
657 682
658 local_irq_restore(flags); 683 local_irq_restore(flags);
659 684
660 return(ata66); 685 return cbl;
661} 686}
662 687
663/** 688/**
@@ -708,8 +733,9 @@ static void __devinit init_hwif_common_ali15x3 (ide_hwif_t *hwif)
708 hwif->dma_setup = &ali15x3_dma_setup; 733 hwif->dma_setup = &ali15x3_dma_setup;
709 if (!noautodma) 734 if (!noautodma)
710 hwif->autodma = 1; 735 hwif->autodma = 1;
711 if (!(hwif->udma_four)) 736
712 hwif->udma_four = ata66_ali15x3(hwif); 737 if (hwif->cbl != ATA_CBL_PATA40_SHORT)
738 hwif->cbl = ata66_ali15x3(hwif);
713 } 739 }
714 hwif->drives[0].autodma = hwif->autodma; 740 hwif->drives[0].autodma = hwif->autodma;
715 hwif->drives[1].autodma = hwif->autodma; 741 hwif->drives[1].autodma = hwif->autodma;
diff --git a/drivers/ide/pci/amd74xx.c b/drivers/ide/pci/amd74xx.c
index a2be65fcf89c..84ed30cdb324 100644
--- a/drivers/ide/pci/amd74xx.c
+++ b/drivers/ide/pci/amd74xx.c
@@ -1,10 +1,11 @@
1/* 1/*
2 * Version 2.16 2 * Version 2.20
3 * 3 *
4 * AMD 755/756/766/8111 and nVidia nForce/2/2s/3/3s/CK804/MCP04 4 * AMD 755/756/766/8111 and nVidia nForce/2/2s/3/3s/CK804/MCP04
5 * IDE driver for Linux. 5 * IDE driver for Linux.
6 * 6 *
7 * Copyright (c) 2000-2002 Vojtech Pavlik 7 * Copyright (c) 2000-2002 Vojtech Pavlik
8 * Copyright (c) 2007 Bartlomiej Zolnierkiewicz
8 * 9 *
9 * Based on the work of: 10 * Based on the work of:
10 * Andre Hedrick 11 * Andre Hedrick
@@ -37,11 +38,6 @@
37#define AMD_ADDRESS_SETUP (0x0c + amd_config->base) 38#define AMD_ADDRESS_SETUP (0x0c + amd_config->base)
38#define AMD_UDMA_TIMING (0x10 + amd_config->base) 39#define AMD_UDMA_TIMING (0x10 + amd_config->base)
39 40
40#define AMD_UDMA 0x07
41#define AMD_UDMA_33 0x01
42#define AMD_UDMA_66 0x02
43#define AMD_UDMA_100 0x03
44#define AMD_UDMA_133 0x04
45#define AMD_CHECK_SWDMA 0x08 41#define AMD_CHECK_SWDMA 0x08
46#define AMD_BAD_SWDMA 0x10 42#define AMD_BAD_SWDMA 0x10
47#define AMD_BAD_FIFO 0x20 43#define AMD_BAD_FIFO 0x20
@@ -53,32 +49,33 @@
53 49
54static struct amd_ide_chip { 50static struct amd_ide_chip {
55 unsigned short id; 51 unsigned short id;
56 unsigned long base; 52 u8 base;
57 unsigned char flags; 53 u8 udma_mask;
54 u8 flags;
58} amd_ide_chips[] = { 55} amd_ide_chips[] = {
59 { PCI_DEVICE_ID_AMD_COBRA_7401, 0x40, AMD_UDMA_33 | AMD_BAD_SWDMA }, 56 { PCI_DEVICE_ID_AMD_COBRA_7401, 0x40, ATA_UDMA2, AMD_BAD_SWDMA },
60 { PCI_DEVICE_ID_AMD_VIPER_7409, 0x40, AMD_UDMA_66 | AMD_CHECK_SWDMA }, 57 { PCI_DEVICE_ID_AMD_VIPER_7409, 0x40, ATA_UDMA4, AMD_CHECK_SWDMA },
61 { PCI_DEVICE_ID_AMD_VIPER_7411, 0x40, AMD_UDMA_100 | AMD_BAD_FIFO }, 58 { PCI_DEVICE_ID_AMD_VIPER_7411, 0x40, ATA_UDMA5, AMD_BAD_FIFO },
62 { PCI_DEVICE_ID_AMD_OPUS_7441, 0x40, AMD_UDMA_100 }, 59 { PCI_DEVICE_ID_AMD_OPUS_7441, 0x40, ATA_UDMA5, },
63 { PCI_DEVICE_ID_AMD_8111_IDE, 0x40, AMD_UDMA_133 | AMD_CHECK_SERENADE }, 60 { PCI_DEVICE_ID_AMD_8111_IDE, 0x40, ATA_UDMA6, AMD_CHECK_SERENADE },
64 { PCI_DEVICE_ID_NVIDIA_NFORCE_IDE, 0x50, AMD_UDMA_100 }, 61 { PCI_DEVICE_ID_NVIDIA_NFORCE_IDE, 0x50, ATA_UDMA5, },
65 { PCI_DEVICE_ID_NVIDIA_NFORCE2_IDE, 0x50, AMD_UDMA_133 }, 62 { PCI_DEVICE_ID_NVIDIA_NFORCE2_IDE, 0x50, ATA_UDMA6, },
66 { PCI_DEVICE_ID_NVIDIA_NFORCE2S_IDE, 0x50, AMD_UDMA_133 }, 63 { PCI_DEVICE_ID_NVIDIA_NFORCE2S_IDE, 0x50, ATA_UDMA6, },
67 { PCI_DEVICE_ID_NVIDIA_NFORCE2S_SATA, 0x50, AMD_UDMA_133 }, 64 { PCI_DEVICE_ID_NVIDIA_NFORCE2S_SATA, 0x50, ATA_UDMA6, },
68 { PCI_DEVICE_ID_NVIDIA_NFORCE3_IDE, 0x50, AMD_UDMA_133 }, 65 { PCI_DEVICE_ID_NVIDIA_NFORCE3_IDE, 0x50, ATA_UDMA6, },
69 { PCI_DEVICE_ID_NVIDIA_NFORCE3S_IDE, 0x50, AMD_UDMA_133 }, 66 { PCI_DEVICE_ID_NVIDIA_NFORCE3S_IDE, 0x50, ATA_UDMA6, },
70 { PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA, 0x50, AMD_UDMA_133 }, 67 { PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA, 0x50, ATA_UDMA6, },
71 { PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA2, 0x50, AMD_UDMA_133 }, 68 { PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA2, 0x50, ATA_UDMA6, },
72 { PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_IDE, 0x50, AMD_UDMA_133 }, 69 { PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_IDE, 0x50, ATA_UDMA6, },
73 { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE, 0x50, AMD_UDMA_133 }, 70 { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE, 0x50, ATA_UDMA6, },
74 { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE, 0x50, AMD_UDMA_133 }, 71 { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE, 0x50, ATA_UDMA6, },
75 { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE, 0x50, AMD_UDMA_133 }, 72 { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE, 0x50, ATA_UDMA6, },
76 { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_IDE, 0x50, AMD_UDMA_133 }, 73 { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_IDE, 0x50, ATA_UDMA6, },
77 { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_IDE, 0x50, AMD_UDMA_133 }, 74 { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_IDE, 0x50, ATA_UDMA6, },
78 { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP67_IDE, 0x50, AMD_UDMA_133 }, 75 { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP67_IDE, 0x50, ATA_UDMA6, },
79 { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP73_IDE, 0x50, AMD_UDMA_133 }, 76 { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP73_IDE, 0x50, ATA_UDMA6, },
80 { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP77_IDE, 0x50, AMD_UDMA_133 }, 77 { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP77_IDE, 0x50, ATA_UDMA6, },
81 { PCI_DEVICE_ID_AMD_CS5536_IDE, 0x40, AMD_UDMA_100 }, 78 { PCI_DEVICE_ID_AMD_CS5536_IDE, 0x40, ATA_UDMA5, },
82 { 0 } 79 { 0 }
83}; 80};
84 81
@@ -87,7 +84,7 @@ static ide_pci_device_t *amd_chipset;
87static unsigned int amd_80w; 84static unsigned int amd_80w;
88static unsigned int amd_clock; 85static unsigned int amd_clock;
89 86
90static char *amd_dma[] = { "MWDMA16", "UDMA33", "UDMA66", "UDMA100", "UDMA133" }; 87static char *amd_dma[] = { "16", "25", "33", "44", "66", "100", "133" };
91static unsigned char amd_cyc2udma[] = { 6, 6, 5, 4, 0, 1, 1, 2, 2, 3, 3, 3, 3, 3, 3, 7 }; 88static unsigned char amd_cyc2udma[] = { 6, 6, 5, 4, 0, 1, 1, 2, 2, 3, 3, 3, 3, 3, 3, 7 };
92 89
93/* 90/*
@@ -128,7 +125,7 @@ static int amd74xx_get_info(char *buffer, char **addr, off_t offset, int count)
128 125
129 pci_read_config_byte(dev, PCI_REVISION_ID, &t); 126 pci_read_config_byte(dev, PCI_REVISION_ID, &t);
130 amd_print("Revision: IDE %#x", t); 127 amd_print("Revision: IDE %#x", t);
131 amd_print("Highest DMA rate: %s", amd_dma[amd_config->flags & AMD_UDMA]); 128 amd_print("Highest DMA rate: UDMA%s", amd_dma[fls(amd_config->udma_mask) - 1]);
132 129
133 amd_print("BM-DMA base: %#lx", amd_base); 130 amd_print("BM-DMA base: %#lx", amd_base);
134 amd_print("PCI clock: %d.%dMHz", amd_clock / 1000, amd_clock / 100 % 10); 131 amd_print("PCI clock: %d.%dMHz", amd_clock / 1000, amd_clock / 100 % 10);
@@ -221,12 +218,12 @@ static void amd_set_speed(struct pci_dev *dev, unsigned char dn, struct ide_timi
221 pci_write_config_byte(dev, AMD_DRIVE_TIMING + (3 - dn), 218 pci_write_config_byte(dev, AMD_DRIVE_TIMING + (3 - dn),
222 ((FIT(timing->active, 1, 16) - 1) << 4) | (FIT(timing->recover, 1, 16) - 1)); 219 ((FIT(timing->active, 1, 16) - 1) << 4) | (FIT(timing->recover, 1, 16) - 1));
223 220
224 switch (amd_config->flags & AMD_UDMA) { 221 switch (amd_config->udma_mask) {
225 case AMD_UDMA_33: t = timing->udma ? (0xc0 | (FIT(timing->udma, 2, 5) - 2)) : 0x03; break; 222 case ATA_UDMA2: t = timing->udma ? (0xc0 | (FIT(timing->udma, 2, 5) - 2)) : 0x03; break;
226 case AMD_UDMA_66: t = timing->udma ? (0xc0 | amd_cyc2udma[FIT(timing->udma, 2, 10)]) : 0x03; break; 223 case ATA_UDMA4: t = timing->udma ? (0xc0 | amd_cyc2udma[FIT(timing->udma, 2, 10)]) : 0x03; break;
227 case AMD_UDMA_100: t = timing->udma ? (0xc0 | amd_cyc2udma[FIT(timing->udma, 1, 10)]) : 0x03; break; 224 case ATA_UDMA5: t = timing->udma ? (0xc0 | amd_cyc2udma[FIT(timing->udma, 1, 10)]) : 0x03; break;
228 case AMD_UDMA_133: t = timing->udma ? (0xc0 | amd_cyc2udma[FIT(timing->udma, 1, 15)]) : 0x03; break; 225 case ATA_UDMA6: t = timing->udma ? (0xc0 | amd_cyc2udma[FIT(timing->udma, 1, 15)]) : 0x03; break;
229 default: return; 226 default: return;
230 } 227 }
231 228
232 pci_write_config_byte(dev, AMD_UDMA_TIMING + (3 - dn), t); 229 pci_write_config_byte(dev, AMD_UDMA_TIMING + (3 - dn), t);
@@ -248,7 +245,7 @@ static int amd_set_drive(ide_drive_t *drive, u8 speed)
248 ide_config_drive_speed(drive, speed); 245 ide_config_drive_speed(drive, speed);
249 246
250 T = 1000000000 / amd_clock; 247 T = 1000000000 / amd_clock;
251 UT = T / min_t(int, max_t(int, amd_config->flags & AMD_UDMA, 1), 2); 248 UT = (amd_config->udma_mask == ATA_UDMA2) ? T : (T / 2);
252 249
253 ide_timing_compute(drive, speed, &t, T, UT); 250 ide_timing_compute(drive, speed, &t, T, UT);
254 251
@@ -277,29 +274,19 @@ static int amd_set_drive(ide_drive_t *drive, u8 speed)
277static void amd74xx_tune_drive(ide_drive_t *drive, u8 pio) 274static void amd74xx_tune_drive(ide_drive_t *drive, u8 pio)
278{ 275{
279 if (pio == 255) { 276 if (pio == 255) {
280 amd_set_drive(drive, ide_find_best_mode(drive, XFER_PIO | XFER_EPIO)); 277 amd_set_drive(drive, ide_find_best_pio_mode(drive));
281 return; 278 return;
282 } 279 }
283 280
284 amd_set_drive(drive, XFER_PIO_0 + min_t(byte, pio, 5)); 281 amd_set_drive(drive, XFER_PIO_0 + min_t(byte, pio, 5));
285} 282}
286 283
287/*
288 * amd74xx_dmaproc() is a callback from upper layers that can do
289 * a lot, but we use it for DMA/PIO tuning only, delegating everything
290 * else to the default ide_dmaproc().
291 */
292
293static int amd74xx_ide_dma_check(ide_drive_t *drive) 284static int amd74xx_ide_dma_check(ide_drive_t *drive)
294{ 285{
295 int w80 = HWIF(drive)->udma_four; 286 u8 speed = ide_max_dma_mode(drive);
296 287
297 u8 speed = ide_find_best_mode(drive, 288 if (speed == 0)
298 XFER_PIO | XFER_EPIO | XFER_MWDMA | XFER_UDMA | 289 speed = ide_find_best_pio_mode(drive);
299 ((amd_config->flags & AMD_BAD_SWDMA) ? 0 : XFER_SWDMA) |
300 (w80 && (amd_config->flags & AMD_UDMA) >= AMD_UDMA_66 ? XFER_UDMA_66 : 0) |
301 (w80 && (amd_config->flags & AMD_UDMA) >= AMD_UDMA_100 ? XFER_UDMA_100 : 0) |
302 (w80 && (amd_config->flags & AMD_UDMA) >= AMD_UDMA_133 ? XFER_UDMA_133 : 0));
303 290
304 amd_set_drive(drive, speed); 291 amd_set_drive(drive, speed);
305 292
@@ -334,10 +321,10 @@ static unsigned int __devinit init_chipset_amd74xx(struct pci_dev *dev, const ch
334 * Check 80-wire cable presence. 321 * Check 80-wire cable presence.
335 */ 322 */
336 323
337 switch (amd_config->flags & AMD_UDMA) { 324 switch (amd_config->udma_mask) {
338 325
339 case AMD_UDMA_133: 326 case ATA_UDMA6:
340 case AMD_UDMA_100: 327 case ATA_UDMA5:
341 pci_read_config_byte(dev, AMD_CABLE_DETECT, &t); 328 pci_read_config_byte(dev, AMD_CABLE_DETECT, &t);
342 pci_read_config_dword(dev, AMD_UDMA_TIMING, &u); 329 pci_read_config_dword(dev, AMD_UDMA_TIMING, &u);
343 amd_80w = ((t & 0x3) ? 1 : 0) | ((t & 0xc) ? 2 : 0); 330 amd_80w = ((t & 0x3) ? 1 : 0) | ((t & 0xc) ? 2 : 0);
@@ -349,7 +336,7 @@ static unsigned int __devinit init_chipset_amd74xx(struct pci_dev *dev, const ch
349 } 336 }
350 break; 337 break;
351 338
352 case AMD_UDMA_66: 339 case ATA_UDMA4:
353 /* no host side cable detection */ 340 /* no host side cable detection */
354 amd_80w = 0x03; 341 amd_80w = 0x03;
355 break; 342 break;
@@ -370,7 +357,7 @@ static unsigned int __devinit init_chipset_amd74xx(struct pci_dev *dev, const ch
370 if ((amd_config->flags & AMD_CHECK_SERENADE) && 357 if ((amd_config->flags & AMD_CHECK_SERENADE) &&
371 dev->subsystem_vendor == PCI_VENDOR_ID_AMD && 358 dev->subsystem_vendor == PCI_VENDOR_ID_AMD &&
372 dev->subsystem_device == PCI_DEVICE_ID_AMD_SERENADE) 359 dev->subsystem_device == PCI_DEVICE_ID_AMD_SERENADE)
373 amd_config->flags = AMD_UDMA_100; 360 amd_config->udma_mask = ATA_UDMA5;
374 361
375/* 362/*
376 * Determine the system bus clock. 363 * Determine the system bus clock.
@@ -395,8 +382,9 @@ static unsigned int __devinit init_chipset_amd74xx(struct pci_dev *dev, const ch
395 */ 382 */
396 383
397 pci_read_config_byte(dev, PCI_REVISION_ID, &t); 384 pci_read_config_byte(dev, PCI_REVISION_ID, &t);
398 printk(KERN_INFO "%s: %s (rev %02x) %s controller\n", 385 printk(KERN_INFO "%s: %s (rev %02x) UDMA%s controller\n",
399 amd_chipset->name, pci_name(dev), t, amd_dma[amd_config->flags & AMD_UDMA]); 386 amd_chipset->name, pci_name(dev), t,
387 amd_dma[fls(amd_config->udma_mask) - 1]);
400 388
401/* 389/*
402 * Register /proc/ide/amd74xx entry 390 * Register /proc/ide/amd74xx entry
@@ -437,12 +425,19 @@ static void __devinit init_hwif_amd74xx(ide_hwif_t *hwif)
437 return; 425 return;
438 426
439 hwif->atapi_dma = 1; 427 hwif->atapi_dma = 1;
440 hwif->ultra_mask = 0x7f;
441 hwif->mwdma_mask = 0x07;
442 hwif->swdma_mask = 0x07;
443 428
444 if (!hwif->udma_four) 429 hwif->ultra_mask = amd_config->udma_mask;
445 hwif->udma_four = (amd_80w >> hwif->channel) & 1; 430 hwif->mwdma_mask = 0x07;
431 if ((amd_config->flags & AMD_BAD_SWDMA) == 0)
432 hwif->swdma_mask = 0x07;
433
434 if (hwif->cbl != ATA_CBL_PATA40_SHORT) {
435 if ((amd_80w >> hwif->channel) & 1)
436 hwif->cbl = ATA_CBL_PATA80;
437 else
438 hwif->cbl = ATA_CBL_PATA40;
439 }
440
446 hwif->ide_dma_check = &amd74xx_ide_dma_check; 441 hwif->ide_dma_check = &amd74xx_ide_dma_check;
447 if (!noautodma) 442 if (!noautodma)
448 hwif->autodma = 1; 443 hwif->autodma = 1;
diff --git a/drivers/ide/pci/atiixp.c b/drivers/ide/pci/atiixp.c
index 8ab33faf6f76..2761510309b3 100644
--- a/drivers/ide/pci/atiixp.c
+++ b/drivers/ide/pci/atiixp.c
@@ -264,10 +264,11 @@ static void __devinit init_hwif_atiixp(ide_hwif_t *hwif)
264 hwif->swdma_mask = 0x04; 264 hwif->swdma_mask = 0x04;
265 265
266 pci_read_config_byte(pdev, ATIIXP_IDE_UDMA_MODE + ch, &udma_mode); 266 pci_read_config_byte(pdev, ATIIXP_IDE_UDMA_MODE + ch, &udma_mode);
267
267 if ((udma_mode & 0x07) >= 0x04 || (udma_mode & 0x70) >= 0x40) 268 if ((udma_mode & 0x07) >= 0x04 || (udma_mode & 0x70) >= 0x40)
268 hwif->udma_four = 1; 269 hwif->cbl = ATA_CBL_PATA80;
269 else 270 else
270 hwif->udma_four = 0; 271 hwif->cbl = ATA_CBL_PATA40;
271 272
272 hwif->dma_host_on = &atiixp_dma_host_on; 273 hwif->dma_host_on = &atiixp_dma_host_on;
273 hwif->dma_host_off = &atiixp_dma_host_off; 274 hwif->dma_host_off = &atiixp_dma_host_off;
diff --git a/drivers/ide/pci/cmd64x.c b/drivers/ide/pci/cmd64x.c
index 7c57dc696f52..8631b6c8aa15 100644
--- a/drivers/ide/pci/cmd64x.c
+++ b/drivers/ide/pci/cmd64x.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * linux/drivers/ide/pci/cmd64x.c Version 1.47 Mar 19, 2007 2 * linux/drivers/ide/pci/cmd64x.c Version 1.50 May 10, 2007
3 * 3 *
4 * cmd64x.c: Enable interrupts at initialization time on Ultra/PCI machines. 4 * cmd64x.c: Enable interrupts at initialization time on Ultra/PCI machines.
5 * Due to massive hardware bugs, UltraDMA is only supported 5 * Due to massive hardware bugs, UltraDMA is only supported
@@ -52,9 +52,6 @@
52#define ARTTIM23_DIS_RA2 0x04 52#define ARTTIM23_DIS_RA2 0x04
53#define ARTTIM23_DIS_RA3 0x08 53#define ARTTIM23_DIS_RA3 0x08
54#define ARTTIM23_INTR_CH1 0x10 54#define ARTTIM23_INTR_CH1 0x10
55#define ARTTIM2 0x57
56#define ARTTIM3 0x57
57#define DRWTIM23 0x58
58#define DRWTIM2 0x58 55#define DRWTIM2 0x58
59#define BRST 0x59 56#define BRST 0x59
60#define DRWTIM3 0x5b 57#define DRWTIM3 0x5b
@@ -469,71 +466,43 @@ static int cmd646_1_ide_dma_end (ide_drive_t *drive)
469 466
470static unsigned int __devinit init_chipset_cmd64x(struct pci_dev *dev, const char *name) 467static unsigned int __devinit init_chipset_cmd64x(struct pci_dev *dev, const char *name)
471{ 468{
472 u32 class_rev = 0;
473 u8 mrdmode = 0; 469 u8 mrdmode = 0;
474 470
475 pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); 471 if (dev->device == PCI_DEVICE_ID_CMD_646) {
476 class_rev &= 0xff; 472 u8 rev = 0;
477 473
478 switch(dev->device) { 474 pci_read_config_byte(dev, PCI_REVISION_ID, &rev);
479 case PCI_DEVICE_ID_CMD_643: 475
480 break; 476 switch (rev) {
481 case PCI_DEVICE_ID_CMD_646: 477 case 0x07:
482 printk(KERN_INFO "%s: chipset revision 0x%02X, ", name, class_rev); 478 case 0x05:
483 switch(class_rev) { 479 printk("%s: UltraDMA capable", name);
484 case 0x07:
485 case 0x05:
486 printk("UltraDMA Capable");
487 break;
488 case 0x03:
489 printk("MultiWord DMA Force Limited");
490 break;
491 case 0x01:
492 default:
493 printk("MultiWord DMA Limited, IRQ workaround enabled");
494 break;
495 }
496 printk("\n");
497 break;
498 case PCI_DEVICE_ID_CMD_648:
499 case PCI_DEVICE_ID_CMD_649:
500 break; 480 break;
481 case 0x03:
501 default: 482 default:
483 printk("%s: MultiWord DMA force limited", name);
484 break;
485 case 0x01:
486 printk("%s: MultiWord DMA limited, "
487 "IRQ workaround enabled\n", name);
502 break; 488 break;
489 }
503 } 490 }
504 491
505 /* Set a good latency timer and cache line size value. */ 492 /* Set a good latency timer and cache line size value. */
506 (void) pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64); 493 (void) pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64);
507 /* FIXME: pci_set_master() to ensure a good latency timer value */ 494 /* FIXME: pci_set_master() to ensure a good latency timer value */
508 495
509 /* Setup interrupts. */ 496 /*
510 (void) pci_read_config_byte(dev, MRDMODE, &mrdmode); 497 * Enable interrupts, select MEMORY READ LINE for reads.
511 mrdmode &= ~(0x30); 498 *
512 (void) pci_write_config_byte(dev, MRDMODE, mrdmode); 499 * NOTE: although not mentioned in the PCI0646U specs,
513 500 * bits 0-1 are write only and won't be read back as
514 /* Use MEMORY READ LINE for reads. 501 * set or not -- PCI0646U2 specs clarify this point.
515 * NOTE: Although not mentioned in the PCI0646U specs,
516 * these bits are write only and won't be read
517 * back as set or not. The PCI0646U2 specs clarify
518 * this point.
519 */ 502 */
520 (void) pci_write_config_byte(dev, MRDMODE, mrdmode | 0x02); 503 (void) pci_read_config_byte (dev, MRDMODE, &mrdmode);
521 504 mrdmode &= ~0x30;
522 /* Set reasonable active/recovery/address-setup values. */ 505 (void) pci_write_config_byte(dev, MRDMODE, (mrdmode | 0x02));
523 (void) pci_write_config_byte(dev, ARTTIM0, 0x40);
524 (void) pci_write_config_byte(dev, DRWTIM0, 0x3f);
525 (void) pci_write_config_byte(dev, ARTTIM1, 0x40);
526 (void) pci_write_config_byte(dev, DRWTIM1, 0x3f);
527#ifdef __i386__
528 (void) pci_write_config_byte(dev, ARTTIM23, 0x1c);
529#else
530 (void) pci_write_config_byte(dev, ARTTIM23, 0x5c);
531#endif
532 (void) pci_write_config_byte(dev, DRWTIM23, 0x3f);
533 (void) pci_write_config_byte(dev, DRWTIM3, 0x3f);
534#ifdef CONFIG_PPC
535 (void) pci_write_config_byte(dev, UDIDETCR0, 0xf0);
536#endif /* CONFIG_PPC */
537 506
538#if defined(DISPLAY_CMD64X_TIMINGS) && defined(CONFIG_IDE_PROC_FS) 507#if defined(DISPLAY_CMD64X_TIMINGS) && defined(CONFIG_IDE_PROC_FS)
539 508
@@ -548,29 +517,27 @@ static unsigned int __devinit init_chipset_cmd64x(struct pci_dev *dev, const cha
548 return 0; 517 return 0;
549} 518}
550 519
551static unsigned int __devinit ata66_cmd64x(ide_hwif_t *hwif) 520static u8 __devinit ata66_cmd64x(ide_hwif_t *hwif)
552{ 521{
553 u8 ata66 = 0, mask = (hwif->channel) ? 0x02 : 0x01; 522 struct pci_dev *dev = hwif->pci_dev;
523 u8 bmidecsr = 0, mask = hwif->channel ? 0x02 : 0x01;
554 524
555 switch(hwif->pci_dev->device) { 525 switch (dev->device) {
556 case PCI_DEVICE_ID_CMD_643: 526 case PCI_DEVICE_ID_CMD_648:
557 case PCI_DEVICE_ID_CMD_646: 527 case PCI_DEVICE_ID_CMD_649:
558 return ata66; 528 pci_read_config_byte(dev, BMIDECSR, &bmidecsr);
559 default: 529 return (bmidecsr & mask) ? ATA_CBL_PATA80 : ATA_CBL_PATA40;
560 break; 530 default:
531 return ATA_CBL_PATA40;
561 } 532 }
562 pci_read_config_byte(hwif->pci_dev, BMIDECSR, &ata66);
563 return (ata66 & mask) ? 1 : 0;
564} 533}
565 534
566static void __devinit init_hwif_cmd64x(ide_hwif_t *hwif) 535static void __devinit init_hwif_cmd64x(ide_hwif_t *hwif)
567{ 536{
568 struct pci_dev *dev = hwif->pci_dev; 537 struct pci_dev *dev = hwif->pci_dev;
569 unsigned int class_rev; 538 u8 rev = 0;
570 539
571 hwif->autodma = 0; 540 pci_read_config_byte(dev, PCI_REVISION_ID, &rev);
572 pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
573 class_rev &= 0xff;
574 541
575 hwif->tuneproc = &cmd64x_tune_drive; 542 hwif->tuneproc = &cmd64x_tune_drive;
576 hwif->speedproc = &cmd64x_tune_chipset; 543 hwif->speedproc = &cmd64x_tune_chipset;
@@ -580,8 +547,8 @@ static void __devinit init_hwif_cmd64x(ide_hwif_t *hwif)
580 if (!hwif->dma_base) 547 if (!hwif->dma_base)
581 return; 548 return;
582 549
583 hwif->atapi_dma = 1; 550 hwif->atapi_dma = 1;
584 551 hwif->mwdma_mask = 0x07;
585 hwif->ultra_mask = hwif->cds->udma_mask; 552 hwif->ultra_mask = hwif->cds->udma_mask;
586 553
587 /* 554 /*
@@ -596,16 +563,15 @@ static void __devinit init_hwif_cmd64x(ide_hwif_t *hwif)
596 * 563 *
597 * So we only do UltraDMA on revision 0x05 and 0x07 chipsets. 564 * So we only do UltraDMA on revision 0x05 and 0x07 chipsets.
598 */ 565 */
599 if (dev->device == PCI_DEVICE_ID_CMD_646 && class_rev < 5) 566 if (dev->device == PCI_DEVICE_ID_CMD_646 && rev < 5)
600 hwif->ultra_mask = 0x00; 567 hwif->ultra_mask = 0x00;
601 568
602 hwif->mwdma_mask = 0x07;
603
604 hwif->ide_dma_check = &cmd64x_config_drive_for_dma; 569 hwif->ide_dma_check = &cmd64x_config_drive_for_dma;
605 if (!(hwif->udma_four))
606 hwif->udma_four = ata66_cmd64x(hwif);
607 570
608 switch(dev->device) { 571 if (hwif->cbl != ATA_CBL_PATA40_SHORT)
572 hwif->cbl = ata66_cmd64x(hwif);
573
574 switch (dev->device) {
609 case PCI_DEVICE_ID_CMD_648: 575 case PCI_DEVICE_ID_CMD_648:
610 case PCI_DEVICE_ID_CMD_649: 576 case PCI_DEVICE_ID_CMD_649:
611 alt_irq_bits: 577 alt_irq_bits:
@@ -614,10 +580,10 @@ static void __devinit init_hwif_cmd64x(ide_hwif_t *hwif)
614 break; 580 break;
615 case PCI_DEVICE_ID_CMD_646: 581 case PCI_DEVICE_ID_CMD_646:
616 hwif->chipset = ide_cmd646; 582 hwif->chipset = ide_cmd646;
617 if (class_rev == 0x01) { 583 if (rev == 0x01) {
618 hwif->ide_dma_end = &cmd646_1_ide_dma_end; 584 hwif->ide_dma_end = &cmd646_1_ide_dma_end;
619 break; 585 break;
620 } else if (class_rev >= 0x03) 586 } else if (rev >= 0x03)
621 goto alt_irq_bits; 587 goto alt_irq_bits;
622 /* fall thru */ 588 /* fall thru */
623 default: 589 default:
@@ -626,11 +592,9 @@ static void __devinit init_hwif_cmd64x(ide_hwif_t *hwif)
626 break; 592 break;
627 } 593 }
628 594
629
630 if (!noautodma) 595 if (!noautodma)
631 hwif->autodma = 1; 596 hwif->autodma = 1;
632 hwif->drives[0].autodma = hwif->autodma; 597 hwif->drives[0].autodma = hwif->drives[1].autodma = hwif->autodma;
633 hwif->drives[1].autodma = hwif->autodma;
634} 598}
635 599
636static int __devinit init_setup_cmd64x(struct pci_dev *dev, ide_pci_device_t *d) 600static int __devinit init_setup_cmd64x(struct pci_dev *dev, ide_pci_device_t *d)
diff --git a/drivers/ide/pci/cs5535.c b/drivers/ide/pci/cs5535.c
index 41925c47ef05..10f61f38243c 100644
--- a/drivers/ide/pci/cs5535.c
+++ b/drivers/ide/pci/cs5535.c
@@ -187,7 +187,8 @@ static u8 __devinit cs5535_cable_detect(struct pci_dev *dev)
187 187
188 /* if a 80 wire cable was detected */ 188 /* if a 80 wire cable was detected */
189 pci_read_config_byte(dev, CS5535_CABLE_DETECT, &bit); 189 pci_read_config_byte(dev, CS5535_CABLE_DETECT, &bit);
190 return (bit & 1); 190
191 return (bit & 1) ? ATA_CBL_PATA80 : ATA_CBL_PATA40;
191} 192}
192 193
193/**** 194/****
@@ -212,8 +213,7 @@ static void __devinit init_hwif_cs5535(ide_hwif_t *hwif)
212 hwif->ultra_mask = 0x1F; 213 hwif->ultra_mask = 0x1F;
213 hwif->mwdma_mask = 0x07; 214 hwif->mwdma_mask = 0x07;
214 215
215 216 hwif->cbl = cs5535_cable_detect(hwif->pci_dev);
216 hwif->udma_four = cs5535_cable_detect(hwif->pci_dev);
217 217
218 if (!noautodma) 218 if (!noautodma)
219 hwif->autodma = 1; 219 hwif->autodma = 1;
diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c
index c33d0b0f11c9..4b6bae8eee82 100644
--- a/drivers/ide/pci/hpt366.c
+++ b/drivers/ide/pci/hpt366.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * linux/drivers/ide/pci/hpt366.c Version 1.06 Jun 27, 2007 2 * linux/drivers/ide/pci/hpt366.c Version 1.10 Jun 29, 2007
3 * 3 *
4 * Copyright (C) 1999-2003 Andre Hedrick <andre@linux-ide.org> 4 * Copyright (C) 1999-2003 Andre Hedrick <andre@linux-ide.org>
5 * Portions Copyright (C) 2001 Sun Microsystems, Inc. 5 * Portions Copyright (C) 2001 Sun Microsystems, Inc.
@@ -77,7 +77,7 @@
77 * since they may tamper with its fields 77 * since they may tamper with its fields
78 * - prefix the driver startup messages with the real chip name 78 * - prefix the driver startup messages with the real chip name
79 * - claim the extra 240 bytes of I/O space for all chips 79 * - claim the extra 240 bytes of I/O space for all chips
80 * - optimize the rate masking/filtering and the drive list lookup code 80 * - optimize the UltraDMA filtering and the drive list lookup code
81 * - use pci_get_slot() to get to the function 1 of HPT36x/374 81 * - use pci_get_slot() to get to the function 1 of HPT36x/374
82 * - cache offset of the channel's misc. control registers (MCRs) being used 82 * - cache offset of the channel's misc. control registers (MCRs) being used
83 * throughout the driver 83 * throughout the driver
@@ -99,9 +99,9 @@
99 * stop duplicating it for each channel by storing the pointer in the pci_dev 99 * stop duplicating it for each channel by storing the pointer in the pci_dev
100 * structure: first, at the init_setup stage, point it to a static "template" 100 * structure: first, at the init_setup stage, point it to a static "template"
101 * with only the chip type and its specific base DPLL frequency, the highest 101 * with only the chip type and its specific base DPLL frequency, the highest
102 * supported DMA mode, and the chip settings table pointer filled, then, at 102 * UltraDMA mode, and the chip settings table pointer filled, then, at the
103 * the init_chipset stage, allocate per-chip instance and fill it with the 103 * init_chipset stage, allocate per-chip instance and fill it with the rest
104 * rest of the necessary information 104 * of the necessary information
105 * - get rid of the constant thresholds in the HPT37x PCI clock detection code, 105 * - get rid of the constant thresholds in the HPT37x PCI clock detection code,
106 * switch to calculating PCI clock frequency based on the chip's base DPLL 106 * switch to calculating PCI clock frequency based on the chip's base DPLL
107 * frequency 107 * frequency
@@ -112,6 +112,7 @@
112 * also fixing the interchanged 25/40 MHz PCI clock cases for HPT36x chips; 112 * also fixing the interchanged 25/40 MHz PCI clock cases for HPT36x chips;
113 * unify HPT36x/37x timing setup code and the speedproc handlers by joining 113 * unify HPT36x/37x timing setup code and the speedproc handlers by joining
114 * the register setting lists into the table indexed by the clock selected 114 * the register setting lists into the table indexed by the clock selected
115 * - set the correct hwif->ultra_mask for each individual chip
115 * Sergei Shtylyov, <sshtylyov@ru.mvista.com> or <source@mvista.com> 116 * Sergei Shtylyov, <sshtylyov@ru.mvista.com> or <source@mvista.com>
116 */ 117 */
117 118
@@ -391,7 +392,7 @@ enum ata_clock {
391 392
392struct hpt_info { 393struct hpt_info {
393 u8 chip_type; /* Chip type */ 394 u8 chip_type; /* Chip type */
394 u8 max_mode; /* Speeds allowed */ 395 u8 max_ultra; /* Max. UltraDMA mode allowed */
395 u8 dpll_clk; /* DPLL clock in MHz */ 396 u8 dpll_clk; /* DPLL clock in MHz */
396 u8 pci_clk; /* PCI clock in MHz */ 397 u8 pci_clk; /* PCI clock in MHz */
397 u32 **settings; /* Chipset settings table */ 398 u32 **settings; /* Chipset settings table */
@@ -430,77 +431,77 @@ static u32 *hpt37x_settings[NUM_ATA_CLOCKS] = {
430 431
431static struct hpt_info hpt36x __devinitdata = { 432static struct hpt_info hpt36x __devinitdata = {
432 .chip_type = HPT36x, 433 .chip_type = HPT36x,
433 .max_mode = (HPT366_ALLOW_ATA66_4 || HPT366_ALLOW_ATA66_3) ? 2 : 1, 434 .max_ultra = HPT366_ALLOW_ATA66_3 ? (HPT366_ALLOW_ATA66_4 ? 4 : 3) : 2,
434 .dpll_clk = 0, /* no DPLL */ 435 .dpll_clk = 0, /* no DPLL */
435 .settings = hpt36x_settings 436 .settings = hpt36x_settings
436}; 437};
437 438
438static struct hpt_info hpt370 __devinitdata = { 439static struct hpt_info hpt370 __devinitdata = {
439 .chip_type = HPT370, 440 .chip_type = HPT370,
440 .max_mode = HPT370_ALLOW_ATA100_5 ? 3 : 2, 441 .max_ultra = HPT370_ALLOW_ATA100_5 ? 5 : 4,
441 .dpll_clk = 48, 442 .dpll_clk = 48,
442 .settings = hpt37x_settings 443 .settings = hpt37x_settings
443}; 444};
444 445
445static struct hpt_info hpt370a __devinitdata = { 446static struct hpt_info hpt370a __devinitdata = {
446 .chip_type = HPT370A, 447 .chip_type = HPT370A,
447 .max_mode = HPT370_ALLOW_ATA100_5 ? 3 : 2, 448 .max_ultra = HPT370_ALLOW_ATA100_5 ? 5 : 4,
448 .dpll_clk = 48, 449 .dpll_clk = 48,
449 .settings = hpt37x_settings 450 .settings = hpt37x_settings
450}; 451};
451 452
452static struct hpt_info hpt374 __devinitdata = { 453static struct hpt_info hpt374 __devinitdata = {
453 .chip_type = HPT374, 454 .chip_type = HPT374,
454 .max_mode = 3, 455 .max_ultra = 5,
455 .dpll_clk = 48, 456 .dpll_clk = 48,
456 .settings = hpt37x_settings 457 .settings = hpt37x_settings
457}; 458};
458 459
459static struct hpt_info hpt372 __devinitdata = { 460static struct hpt_info hpt372 __devinitdata = {
460 .chip_type = HPT372, 461 .chip_type = HPT372,
461 .max_mode = HPT372_ALLOW_ATA133_6 ? 4 : 3, 462 .max_ultra = HPT372_ALLOW_ATA133_6 ? 6 : 5,
462 .dpll_clk = 55, 463 .dpll_clk = 55,
463 .settings = hpt37x_settings 464 .settings = hpt37x_settings
464}; 465};
465 466
466static struct hpt_info hpt372a __devinitdata = { 467static struct hpt_info hpt372a __devinitdata = {
467 .chip_type = HPT372A, 468 .chip_type = HPT372A,
468 .max_mode = HPT372_ALLOW_ATA133_6 ? 4 : 3, 469 .max_ultra = HPT372_ALLOW_ATA133_6 ? 6 : 5,
469 .dpll_clk = 66, 470 .dpll_clk = 66,
470 .settings = hpt37x_settings 471 .settings = hpt37x_settings
471}; 472};
472 473
473static struct hpt_info hpt302 __devinitdata = { 474static struct hpt_info hpt302 __devinitdata = {
474 .chip_type = HPT302, 475 .chip_type = HPT302,
475 .max_mode = HPT302_ALLOW_ATA133_6 ? 4 : 3, 476 .max_ultra = HPT372_ALLOW_ATA133_6 ? 6 : 5,
476 .dpll_clk = 66, 477 .dpll_clk = 66,
477 .settings = hpt37x_settings 478 .settings = hpt37x_settings
478}; 479};
479 480
480static struct hpt_info hpt371 __devinitdata = { 481static struct hpt_info hpt371 __devinitdata = {
481 .chip_type = HPT371, 482 .chip_type = HPT371,
482 .max_mode = HPT371_ALLOW_ATA133_6 ? 4 : 3, 483 .max_ultra = HPT371_ALLOW_ATA133_6 ? 6 : 5,
483 .dpll_clk = 66, 484 .dpll_clk = 66,
484 .settings = hpt37x_settings 485 .settings = hpt37x_settings
485}; 486};
486 487
487static struct hpt_info hpt372n __devinitdata = { 488static struct hpt_info hpt372n __devinitdata = {
488 .chip_type = HPT372N, 489 .chip_type = HPT372N,
489 .max_mode = HPT372_ALLOW_ATA133_6 ? 4 : 3, 490 .max_ultra = HPT372_ALLOW_ATA133_6 ? 6 : 5,
490 .dpll_clk = 77, 491 .dpll_clk = 77,
491 .settings = hpt37x_settings 492 .settings = hpt37x_settings
492}; 493};
493 494
494static struct hpt_info hpt302n __devinitdata = { 495static struct hpt_info hpt302n __devinitdata = {
495 .chip_type = HPT302N, 496 .chip_type = HPT302N,
496 .max_mode = HPT302_ALLOW_ATA133_6 ? 4 : 3, 497 .max_ultra = HPT302_ALLOW_ATA133_6 ? 6 : 5,
497 .dpll_clk = 77, 498 .dpll_clk = 77,
498 .settings = hpt37x_settings 499 .settings = hpt37x_settings
499}; 500};
500 501
501static struct hpt_info hpt371n __devinitdata = { 502static struct hpt_info hpt371n __devinitdata = {
502 .chip_type = HPT371N, 503 .chip_type = HPT371N,
503 .max_mode = HPT371_ALLOW_ATA133_6 ? 4 : 3, 504 .max_ultra = HPT371_ALLOW_ATA133_6 ? 6 : 5,
504 .dpll_clk = 77, 505 .dpll_clk = 77,
505 .settings = hpt37x_settings 506 .settings = hpt37x_settings
506}; 507};
@@ -523,53 +524,38 @@ static int check_in_drive_list(ide_drive_t *drive, const char **list)
523static u8 hpt3xx_udma_filter(ide_drive_t *drive) 524static u8 hpt3xx_udma_filter(ide_drive_t *drive)
524{ 525{
525 struct hpt_info *info = pci_get_drvdata(HWIF(drive)->pci_dev); 526 struct hpt_info *info = pci_get_drvdata(HWIF(drive)->pci_dev);
526 u8 chip_type = info->chip_type;
527 u8 mode = info->max_mode;
528 u8 mask; 527 u8 mask;
529 528
530 switch (mode) { 529 switch (info->chip_type) {
531 case 0x04: 530 case HPT370A:
532 mask = 0x7f; 531 if (!HPT370_ALLOW_ATA100_5 ||
533 break; 532 check_in_drive_list(drive, bad_ata100_5))
534 case 0x03: 533 return 0x1f;
534 else
535 return 0x3f;
536 case HPT370:
537 if (!HPT370_ALLOW_ATA100_5 ||
538 check_in_drive_list(drive, bad_ata100_5))
539 mask = 0x1f;
540 else
535 mask = 0x3f; 541 mask = 0x3f;
536 if (chip_type >= HPT374) 542 break;
537 break; 543 case HPT36x:
538 if (!check_in_drive_list(drive, bad_ata100_5)) 544 if (!HPT366_ALLOW_ATA66_4 ||
539 goto check_bad_ata33; 545 check_in_drive_list(drive, bad_ata66_4))
540 /* fall thru */ 546 mask = 0x0f;
541 case 0x02: 547 else
542 mask = 0x1f; 548 mask = 0x1f;
543 549
544 /* 550 if (!HPT366_ALLOW_ATA66_3 ||
545 * CHECK ME, Does this need to be changed to HPT374 ?? 551 check_in_drive_list(drive, bad_ata66_3))
546 */
547 if (chip_type >= HPT370)
548 goto check_bad_ata33;
549 if (HPT366_ALLOW_ATA66_4 &&
550 !check_in_drive_list(drive, bad_ata66_4))
551 goto check_bad_ata33;
552
553 mask = 0x0f;
554 if (HPT366_ALLOW_ATA66_3 &&
555 !check_in_drive_list(drive, bad_ata66_3))
556 goto check_bad_ata33;
557 /* fall thru */
558 case 0x01:
559 mask = 0x07; 552 mask = 0x07;
560 553 break;
561 check_bad_ata33: 554 default:
562 if (chip_type >= HPT370A) 555 return 0x7f;
563 break;
564 if (!check_in_drive_list(drive, bad_ata33))
565 break;
566 /* fall thru */
567 case 0x00:
568 default:
569 mask = 0x00;
570 break;
571 } 556 }
572 return mask; 557
558 return check_in_drive_list(drive, bad_ata33) ? 0x00 : mask;
573} 559}
574 560
575static u32 get_speed_setting(u8 speed, struct hpt_info *info) 561static u32 get_speed_setting(u8 speed, struct hpt_info *info)
@@ -737,7 +723,7 @@ static int hpt366_config_drive_xfer_rate(ide_drive_t *drive)
737 * This is specific to the HPT366 UDMA chipset 723 * This is specific to the HPT366 UDMA chipset
738 * by HighPoint|Triones Technologies, Inc. 724 * by HighPoint|Triones Technologies, Inc.
739 */ 725 */
740static int hpt366_ide_dma_lostirq(ide_drive_t *drive) 726static void hpt366_dma_lost_irq(ide_drive_t *drive)
741{ 727{
742 struct pci_dev *dev = HWIF(drive)->pci_dev; 728 struct pci_dev *dev = HWIF(drive)->pci_dev;
743 u8 mcr1 = 0, mcr3 = 0, scr1 = 0; 729 u8 mcr1 = 0, mcr3 = 0, scr1 = 0;
@@ -749,7 +735,7 @@ static int hpt366_ide_dma_lostirq(ide_drive_t *drive)
749 drive->name, __FUNCTION__, mcr1, mcr3, scr1); 735 drive->name, __FUNCTION__, mcr1, mcr3, scr1);
750 if (scr1 & 0x10) 736 if (scr1 & 0x10)
751 pci_write_config_byte(dev, 0x5a, scr1 & ~0x10); 737 pci_write_config_byte(dev, 0x5a, scr1 & ~0x10);
752 return __ide_dma_lostirq(drive); 738 ide_dma_lost_irq(drive);
753} 739}
754 740
755static void hpt370_clear_engine(ide_drive_t *drive) 741static void hpt370_clear_engine(ide_drive_t *drive)
@@ -799,10 +785,10 @@ static int hpt370_ide_dma_end(ide_drive_t *drive)
799 return __ide_dma_end(drive); 785 return __ide_dma_end(drive);
800} 786}
801 787
802static int hpt370_ide_dma_timeout(ide_drive_t *drive) 788static void hpt370_dma_timeout(ide_drive_t *drive)
803{ 789{
804 hpt370_irq_timeout(drive); 790 hpt370_irq_timeout(drive);
805 return __ide_dma_timeout(drive); 791 ide_dma_timeout(drive);
806} 792}
807 793
808/* returns 1 if DMA IRQ issued, 0 otherwise */ 794/* returns 1 if DMA IRQ issued, 0 otherwise */
@@ -1150,7 +1136,7 @@ static unsigned int __devinit init_chipset_hpt366(struct pci_dev *dev, const cha
1150 * Select 66 MHz DPLL clock only if UltraATA/133 mode is 1136 * Select 66 MHz DPLL clock only if UltraATA/133 mode is
1151 * supported/enabled, use 50 MHz DPLL clock otherwise... 1137 * supported/enabled, use 50 MHz DPLL clock otherwise...
1152 */ 1138 */
1153 if (info->max_mode == 0x04) { 1139 if (info->max_ultra == 6) {
1154 dpll_clk = 66; 1140 dpll_clk = 66;
1155 clock = ATA_CLOCK_66MHZ; 1141 clock = ATA_CLOCK_66MHZ;
1156 } else if (dpll_clk) { /* HPT36x chips don't have DPLL */ 1142 } else if (dpll_clk) { /* HPT36x chips don't have DPLL */
@@ -1243,7 +1229,7 @@ static void __devinit init_hwif_hpt366(ide_hwif_t *hwif)
1243 struct pci_dev *dev = hwif->pci_dev; 1229 struct pci_dev *dev = hwif->pci_dev;
1244 struct hpt_info *info = pci_get_drvdata(dev); 1230 struct hpt_info *info = pci_get_drvdata(dev);
1245 int serialize = HPT_SERIALIZE_IO; 1231 int serialize = HPT_SERIALIZE_IO;
1246 u8 scr1 = 0, ata66 = (hwif->channel) ? 0x01 : 0x02; 1232 u8 scr1 = 0, ata66 = hwif->channel ? 0x01 : 0x02;
1247 u8 chip_type = info->chip_type; 1233 u8 chip_type = info->chip_type;
1248 u8 new_mcr, old_mcr = 0; 1234 u8 new_mcr, old_mcr = 0;
1249 1235
@@ -1256,7 +1242,9 @@ static void __devinit init_hwif_hpt366(ide_hwif_t *hwif)
1256 hwif->intrproc = &hpt3xx_intrproc; 1242 hwif->intrproc = &hpt3xx_intrproc;
1257 hwif->maskproc = &hpt3xx_maskproc; 1243 hwif->maskproc = &hpt3xx_maskproc;
1258 hwif->busproc = &hpt3xx_busproc; 1244 hwif->busproc = &hpt3xx_busproc;
1259 hwif->udma_filter = &hpt3xx_udma_filter; 1245
1246 if (chip_type <= HPT370A)
1247 hwif->udma_filter = &hpt3xx_udma_filter;
1260 1248
1261 /* 1249 /*
1262 * HPT3xxN chips have some complications: 1250 * HPT3xxN chips have some complications:
@@ -1305,7 +1293,7 @@ static void __devinit init_hwif_hpt366(ide_hwif_t *hwif)
1305 return; 1293 return;
1306 } 1294 }
1307 1295
1308 hwif->ultra_mask = 0x7f; 1296 hwif->ultra_mask = hwif->cds->udma_mask;
1309 hwif->mwdma_mask = 0x07; 1297 hwif->mwdma_mask = 0x07;
1310 1298
1311 /* 1299 /*
@@ -1342,8 +1330,8 @@ static void __devinit init_hwif_hpt366(ide_hwif_t *hwif)
1342 } else 1330 } else
1343 pci_read_config_byte (dev, 0x5a, &scr1); 1331 pci_read_config_byte (dev, 0x5a, &scr1);
1344 1332
1345 if (!hwif->udma_four) 1333 if (hwif->cbl != ATA_CBL_PATA40_SHORT)
1346 hwif->udma_four = (scr1 & ata66) ? 0 : 1; 1334 hwif->cbl = (scr1 & ata66) ? ATA_CBL_PATA40 : ATA_CBL_PATA80;
1347 1335
1348 hwif->ide_dma_check = &hpt366_config_drive_xfer_rate; 1336 hwif->ide_dma_check = &hpt366_config_drive_xfer_rate;
1349 1337
@@ -1353,9 +1341,9 @@ static void __devinit init_hwif_hpt366(ide_hwif_t *hwif)
1353 } else if (chip_type >= HPT370) { 1341 } else if (chip_type >= HPT370) {
1354 hwif->dma_start = &hpt370_ide_dma_start; 1342 hwif->dma_start = &hpt370_ide_dma_start;
1355 hwif->ide_dma_end = &hpt370_ide_dma_end; 1343 hwif->ide_dma_end = &hpt370_ide_dma_end;
1356 hwif->ide_dma_timeout = &hpt370_ide_dma_timeout; 1344 hwif->dma_timeout = &hpt370_dma_timeout;
1357 } else 1345 } else
1358 hwif->ide_dma_lostirq = &hpt366_ide_dma_lostirq; 1346 hwif->dma_lost_irq = &hpt366_dma_lost_irq;
1359 1347
1360 if (!noautodma) 1348 if (!noautodma)
1361 hwif->autodma = 1; 1349 hwif->autodma = 1;
@@ -1503,9 +1491,35 @@ static int __devinit init_setup_hpt366(struct pci_dev *dev, ide_pci_device_t *d)
1503 1491
1504 pci_read_config_byte(dev, PCI_REVISION_ID, &rev); 1492 pci_read_config_byte(dev, PCI_REVISION_ID, &rev);
1505 1493
1506 if (rev > 6) 1494 switch (rev) {
1495 case 0:
1496 case 1:
1497 case 2:
1498 /*
1499 * HPT36x chips have one channel per function and have
1500 * both channel enable bits located differently and visible
1501 * to both functions -- really stupid design decision... :-(
1502 * Bit 4 is for the primary channel, bit 5 for the secondary.
1503 */
1504 d->channels = 1;
1505 d->enablebits[0].mask = d->enablebits[0].val = 0x10;
1506
1507 d->udma_mask = HPT366_ALLOW_ATA66_3 ?
1508 (HPT366_ALLOW_ATA66_4 ? 0x1f : 0x0f) : 0x07;
1509 break;
1510 case 3:
1511 case 4:
1512 d->udma_mask = HPT370_ALLOW_ATA100_5 ? 0x3f : 0x1f;
1513 break;
1514 default:
1507 rev = 6; 1515 rev = 6;
1508 1516 /* fall thru */
1517 case 5:
1518 case 6:
1519 d->udma_mask = HPT372_ALLOW_ATA133_6 ? 0x7f : 0x3f;
1520 break;
1521 }
1522
1509 d->name = chipset_names[rev]; 1523 d->name = chipset_names[rev];
1510 1524
1511 pci_set_drvdata(dev, info[rev]); 1525 pci_set_drvdata(dev, info[rev]);
@@ -1513,15 +1527,6 @@ static int __devinit init_setup_hpt366(struct pci_dev *dev, ide_pci_device_t *d)
1513 if (rev > 2) 1527 if (rev > 2)
1514 goto init_single; 1528 goto init_single;
1515 1529
1516 /*
1517 * HPT36x chips have one channel per function and have
1518 * both channel enable bits located differently and visible
1519 * to both functions -- really stupid design decision... :-(
1520 * Bit 4 is for the primary channel, bit 5 for the secondary.
1521 */
1522 d->channels = 1;
1523 d->enablebits[0].mask = d->enablebits[0].val = 0x10;
1524
1525 if ((dev2 = pci_get_slot(dev->bus, dev->devfn + 1)) != NULL) { 1530 if ((dev2 = pci_get_slot(dev->bus, dev->devfn + 1)) != NULL) {
1526 u8 mcr1 = 0, pin1 = 0, pin2 = 0; 1531 u8 mcr1 = 0, pin1 = 0, pin2 = 0;
1527 int ret; 1532 int ret;
@@ -1573,6 +1578,7 @@ static ide_pci_device_t hpt366_chipsets[] __devinitdata = {
1573 .channels = 2, 1578 .channels = 2,
1574 .autodma = AUTODMA, 1579 .autodma = AUTODMA,
1575 .enablebits = {{0x50,0x04,0x04}, {0x54,0x04,0x04}}, 1580 .enablebits = {{0x50,0x04,0x04}, {0x54,0x04,0x04}},
1581 .udma_mask = HPT372_ALLOW_ATA133_6 ? 0x7f : 0x3f,
1576 .bootable = OFF_BOARD, 1582 .bootable = OFF_BOARD,
1577 .extra = 240 1583 .extra = 240
1578 },{ /* 2 */ 1584 },{ /* 2 */
@@ -1584,6 +1590,7 @@ static ide_pci_device_t hpt366_chipsets[] __devinitdata = {
1584 .channels = 2, 1590 .channels = 2,
1585 .autodma = AUTODMA, 1591 .autodma = AUTODMA,
1586 .enablebits = {{0x50,0x04,0x04}, {0x54,0x04,0x04}}, 1592 .enablebits = {{0x50,0x04,0x04}, {0x54,0x04,0x04}},
1593 .udma_mask = HPT302_ALLOW_ATA133_6 ? 0x7f : 0x3f,
1587 .bootable = OFF_BOARD, 1594 .bootable = OFF_BOARD,
1588 .extra = 240 1595 .extra = 240
1589 },{ /* 3 */ 1596 },{ /* 3 */
@@ -1595,6 +1602,7 @@ static ide_pci_device_t hpt366_chipsets[] __devinitdata = {
1595 .channels = 2, 1602 .channels = 2,
1596 .autodma = AUTODMA, 1603 .autodma = AUTODMA,
1597 .enablebits = {{0x50,0x04,0x04}, {0x54,0x04,0x04}}, 1604 .enablebits = {{0x50,0x04,0x04}, {0x54,0x04,0x04}},
1605 .udma_mask = HPT371_ALLOW_ATA133_6 ? 0x7f : 0x3f,
1598 .bootable = OFF_BOARD, 1606 .bootable = OFF_BOARD,
1599 .extra = 240 1607 .extra = 240
1600 },{ /* 4 */ 1608 },{ /* 4 */
@@ -1606,6 +1614,7 @@ static ide_pci_device_t hpt366_chipsets[] __devinitdata = {
1606 .channels = 2, /* 4 */ 1614 .channels = 2, /* 4 */
1607 .autodma = AUTODMA, 1615 .autodma = AUTODMA,
1608 .enablebits = {{0x50,0x04,0x04}, {0x54,0x04,0x04}}, 1616 .enablebits = {{0x50,0x04,0x04}, {0x54,0x04,0x04}},
1617 .udma_mask = 0x3f,
1609 .bootable = OFF_BOARD, 1618 .bootable = OFF_BOARD,
1610 .extra = 240 1619 .extra = 240
1611 },{ /* 5 */ 1620 },{ /* 5 */
@@ -1617,6 +1626,7 @@ static ide_pci_device_t hpt366_chipsets[] __devinitdata = {
1617 .channels = 2, /* 4 */ 1626 .channels = 2, /* 4 */
1618 .autodma = AUTODMA, 1627 .autodma = AUTODMA,
1619 .enablebits = {{0x50,0x04,0x04}, {0x54,0x04,0x04}}, 1628 .enablebits = {{0x50,0x04,0x04}, {0x54,0x04,0x04}},
1629 .udma_mask = HPT372_ALLOW_ATA133_6 ? 0x7f : 0x3f,
1620 .bootable = OFF_BOARD, 1630 .bootable = OFF_BOARD,
1621 .extra = 240 1631 .extra = 240
1622 } 1632 }
diff --git a/drivers/ide/pci/it8213.c b/drivers/ide/pci/it8213.c
index c04a02687b95..ff48c23e571e 100644
--- a/drivers/ide/pci/it8213.c
+++ b/drivers/ide/pci/it8213.c
@@ -231,7 +231,7 @@ static int it8213_config_drive_for_dma (ide_drive_t *drive)
231 231
232static void __devinit init_hwif_it8213(ide_hwif_t *hwif) 232static void __devinit init_hwif_it8213(ide_hwif_t *hwif)
233{ 233{
234 u8 reg42h = 0, ata66 = 0; 234 u8 reg42h = 0;
235 235
236 hwif->speedproc = &it8213_tune_chipset; 236 hwif->speedproc = &it8213_tune_chipset;
237 hwif->tuneproc = &it8213_tuneproc; 237 hwif->tuneproc = &it8213_tuneproc;
@@ -250,11 +250,11 @@ static void __devinit init_hwif_it8213(ide_hwif_t *hwif)
250 hwif->swdma_mask = 0x04; 250 hwif->swdma_mask = 0x04;
251 251
252 pci_read_config_byte(hwif->pci_dev, 0x42, &reg42h); 252 pci_read_config_byte(hwif->pci_dev, 0x42, &reg42h);
253 ata66 = (reg42h & 0x02) ? 0 : 1;
254 253
255 hwif->ide_dma_check = &it8213_config_drive_for_dma; 254 hwif->ide_dma_check = &it8213_config_drive_for_dma;
256 if (!(hwif->udma_four)) 255
257 hwif->udma_four = ata66; 256 if (hwif->cbl != ATA_CBL_PATA40_SHORT)
257 hwif->cbl = (reg42h & 0x02) ? ATA_CBL_PATA40 : ATA_CBL_PATA80;
258 258
259 /* 259 /*
260 * The BIOS often doesn't set up DMA on this controller 260 * The BIOS often doesn't set up DMA on this controller
diff --git a/drivers/ide/pci/it821x.c b/drivers/ide/pci/it821x.c
index 3aeb7f1b7916..8197b653ba1e 100644
--- a/drivers/ide/pci/it821x.c
+++ b/drivers/ide/pci/it821x.c
@@ -491,10 +491,10 @@ static int it821x_config_drive_for_dma (ide_drive_t *drive)
491 * the needed logic onboard. 491 * the needed logic onboard.
492 */ 492 */
493 493
494static unsigned int __devinit ata66_it821x(ide_hwif_t *hwif) 494static u8 __devinit ata66_it821x(ide_hwif_t *hwif)
495{ 495{
496 /* The reference driver also only does disk side */ 496 /* The reference driver also only does disk side */
497 return 1; 497 return ATA_CBL_PATA80;
498} 498}
499 499
500/** 500/**
@@ -662,8 +662,9 @@ static void __devinit init_hwif_it821x(ide_hwif_t *hwif)
662 hwif->mwdma_mask = 0x07; 662 hwif->mwdma_mask = 0x07;
663 663
664 hwif->ide_dma_check = &it821x_config_drive_for_dma; 664 hwif->ide_dma_check = &it821x_config_drive_for_dma;
665 if (!(hwif->udma_four)) 665
666 hwif->udma_four = ata66_it821x(hwif); 666 if (hwif->cbl != ATA_CBL_PATA40_SHORT)
667 hwif->cbl = ata66_it821x(hwif);
667 668
668 /* 669 /*
669 * The BIOS often doesn't set up DMA on this controller 670 * The BIOS often doesn't set up DMA on this controller
diff --git a/drivers/ide/pci/jmicron.c b/drivers/ide/pci/jmicron.c
index 76ed25147229..a6008f63e71e 100644
--- a/drivers/ide/pci/jmicron.c
+++ b/drivers/ide/pci/jmicron.c
@@ -25,10 +25,10 @@ typedef enum {
25 * ata66_jmicron - Cable check 25 * ata66_jmicron - Cable check
26 * @hwif: IDE port 26 * @hwif: IDE port
27 * 27 *
28 * Return 1 if the cable is 80pin 28 * Returns the cable type.
29 */ 29 */
30 30
31static int __devinit ata66_jmicron(ide_hwif_t *hwif) 31static u8 __devinit ata66_jmicron(ide_hwif_t *hwif)
32{ 32{
33 struct pci_dev *pdev = hwif->pci_dev; 33 struct pci_dev *pdev = hwif->pci_dev;
34 34
@@ -70,16 +70,17 @@ static int __devinit ata66_jmicron(ide_hwif_t *hwif)
70 { 70 {
71 case PORT_PATA0: 71 case PORT_PATA0:
72 if (control & (1 << 3)) /* 40/80 pin primary */ 72 if (control & (1 << 3)) /* 40/80 pin primary */
73 return 0; 73 return ATA_CBL_PATA40;
74 return 1; 74 return ATA_CBL_PATA80;
75 case PORT_PATA1: 75 case PORT_PATA1:
76 if (control5 & (1 << 19)) /* 40/80 pin secondary */ 76 if (control5 & (1 << 19)) /* 40/80 pin secondary */
77 return 0; 77 return ATA_CBL_PATA40;
78 return 1; 78 return ATA_CBL_PATA80;
79 case PORT_SATA: 79 case PORT_SATA:
80 break; 80 break;
81 } 81 }
82 return 1; /* Avoid bogus "control reaches end of non-void function" */ 82 /* Avoid bogus "control reaches end of non-void function" */
83 return ATA_CBL_PATA80;
83} 84}
84 85
85static void jmicron_tuneproc (ide_drive_t *drive, byte mode_wanted) 86static void jmicron_tuneproc (ide_drive_t *drive, byte mode_wanted)
@@ -159,8 +160,9 @@ static void __devinit init_hwif_jmicron(ide_hwif_t *hwif)
159 hwif->mwdma_mask = 0x07; 160 hwif->mwdma_mask = 0x07;
160 161
161 hwif->ide_dma_check = &jmicron_config_drive_for_dma; 162 hwif->ide_dma_check = &jmicron_config_drive_for_dma;
162 if (!(hwif->udma_four)) 163
163 hwif->udma_four = ata66_jmicron(hwif); 164 if (hwif->cbl != ATA_CBL_PATA40_SHORT)
165 hwif->cbl = ata66_jmicron(hwif);
164 166
165 hwif->autodma = 1; 167 hwif->autodma = 1;
166 hwif->drives[0].autodma = hwif->autodma; 168 hwif->drives[0].autodma = hwif->autodma;
diff --git a/drivers/ide/pci/pdc202xx_new.c b/drivers/ide/pci/pdc202xx_new.c
index 0765dce6948e..ee5020df005d 100644
--- a/drivers/ide/pci/pdc202xx_new.c
+++ b/drivers/ide/pci/pdc202xx_new.c
@@ -225,7 +225,10 @@ static void pdcnew_tune_drive(ide_drive_t *drive, u8 pio)
225 225
226static u8 pdcnew_cable_detect(ide_hwif_t *hwif) 226static u8 pdcnew_cable_detect(ide_hwif_t *hwif)
227{ 227{
228 return get_indexed_reg(hwif, 0x0b) & 0x04; 228 if (get_indexed_reg(hwif, 0x0b) & 0x04)
229 return ATA_CBL_PATA40;
230 else
231 return ATA_CBL_PATA80;
229} 232}
230 233
231static int pdcnew_config_drive_xfer_rate(ide_drive_t *drive) 234static int pdcnew_config_drive_xfer_rate(ide_drive_t *drive)
@@ -509,8 +512,8 @@ static void __devinit init_hwif_pdc202new(ide_hwif_t *hwif)
509 512
510 hwif->ide_dma_check = &pdcnew_config_drive_xfer_rate; 513 hwif->ide_dma_check = &pdcnew_config_drive_xfer_rate;
511 514
512 if (!hwif->udma_four) 515 if (hwif->cbl != ATA_CBL_PATA40_SHORT)
513 hwif->udma_four = pdcnew_cable_detect(hwif) ? 0 : 1; 516 hwif->cbl = pdcnew_cable_detect(hwif);
514 517
515 if (!noautodma) 518 if (!noautodma)
516 hwif->autodma = 1; 519 hwif->autodma = 1;
diff --git a/drivers/ide/pci/pdc202xx_old.c b/drivers/ide/pci/pdc202xx_old.c
index 23844687deea..41ac4a94959f 100644
--- a/drivers/ide/pci/pdc202xx_old.c
+++ b/drivers/ide/pci/pdc202xx_old.c
@@ -152,8 +152,10 @@ static void pdc202xx_tune_drive(ide_drive_t *drive, u8 pio)
152static u8 pdc202xx_old_cable_detect (ide_hwif_t *hwif) 152static u8 pdc202xx_old_cable_detect (ide_hwif_t *hwif)
153{ 153{
154 u16 CIS = 0, mask = (hwif->channel) ? (1<<11) : (1<<10); 154 u16 CIS = 0, mask = (hwif->channel) ? (1<<11) : (1<<10);
155
155 pci_read_config_word(hwif->pci_dev, 0x50, &CIS); 156 pci_read_config_word(hwif->pci_dev, 0x50, &CIS);
156 return (CIS & mask) ? 1 : 0; 157
158 return (CIS & mask) ? ATA_CBL_PATA40 : ATA_CBL_PATA80;
157} 159}
158 160
159/* 161/*
@@ -267,18 +269,24 @@ somebody_else:
267 return (dma_stat & 4) == 4; /* return 1 if INTR asserted */ 269 return (dma_stat & 4) == 4; /* return 1 if INTR asserted */
268} 270}
269 271
270static int pdc202xx_ide_dma_lostirq(ide_drive_t *drive) 272static void pdc202xx_dma_lost_irq(ide_drive_t *drive)
271{ 273{
272 if (HWIF(drive)->resetproc != NULL) 274 ide_hwif_t *hwif = HWIF(drive);
273 HWIF(drive)->resetproc(drive); 275
274 return __ide_dma_lostirq(drive); 276 if (hwif->resetproc != NULL)
277 hwif->resetproc(drive);
278
279 ide_dma_lost_irq(drive);
275} 280}
276 281
277static int pdc202xx_ide_dma_timeout(ide_drive_t *drive) 282static void pdc202xx_dma_timeout(ide_drive_t *drive)
278{ 283{
279 if (HWIF(drive)->resetproc != NULL) 284 ide_hwif_t *hwif = HWIF(drive);
280 HWIF(drive)->resetproc(drive); 285
281 return __ide_dma_timeout(drive); 286 if (hwif->resetproc != NULL)
287 hwif->resetproc(drive);
288
289 ide_dma_timeout(drive);
282} 290}
283 291
284static void pdc202xx_reset_host (ide_hwif_t *hwif) 292static void pdc202xx_reset_host (ide_hwif_t *hwif)
@@ -347,12 +355,13 @@ static void __devinit init_hwif_pdc202xx(ide_hwif_t *hwif)
347 hwif->err_stops_fifo = 1; 355 hwif->err_stops_fifo = 1;
348 356
349 hwif->ide_dma_check = &pdc202xx_config_drive_xfer_rate; 357 hwif->ide_dma_check = &pdc202xx_config_drive_xfer_rate;
350 hwif->ide_dma_lostirq = &pdc202xx_ide_dma_lostirq; 358 hwif->dma_lost_irq = &pdc202xx_dma_lost_irq;
351 hwif->ide_dma_timeout = &pdc202xx_ide_dma_timeout; 359 hwif->dma_timeout = &pdc202xx_dma_timeout;
352 360
353 if (hwif->pci_dev->device != PCI_DEVICE_ID_PROMISE_20246) { 361 if (hwif->pci_dev->device != PCI_DEVICE_ID_PROMISE_20246) {
354 if (!(hwif->udma_four)) 362 if (hwif->cbl != ATA_CBL_PATA40_SHORT)
355 hwif->udma_four = (pdc202xx_old_cable_detect(hwif)) ? 0 : 1; 363 hwif->cbl = pdc202xx_old_cable_detect(hwif);
364
356 hwif->dma_start = &pdc202xx_old_ide_dma_start; 365 hwif->dma_start = &pdc202xx_old_ide_dma_start;
357 hwif->ide_dma_end = &pdc202xx_old_ide_dma_end; 366 hwif->ide_dma_end = &pdc202xx_old_ide_dma_end;
358 } 367 }
diff --git a/drivers/ide/pci/piix.c b/drivers/ide/pci/piix.c
index 8b219dd63024..2e0b29ef596a 100644
--- a/drivers/ide/pci/piix.c
+++ b/drivers/ide/pci/piix.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * linux/drivers/ide/pci/piix.c Version 0.47 February 8, 2007 2 * linux/drivers/ide/pci/piix.c Version 0.50 Jun 10, 2007
3 * 3 *
4 * Copyright (C) 1998-1999 Andrzej Krzysztofowicz, Author and Maintainer 4 * Copyright (C) 1998-1999 Andrzej Krzysztofowicz, Author and Maintainer
5 * Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org> 5 * Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org>
@@ -394,14 +394,45 @@ static void piix_dma_clear_irq(ide_drive_t *drive)
394 hwif->OUTB(dma_stat, hwif->dma_status); 394 hwif->OUTB(dma_stat, hwif->dma_status);
395} 395}
396 396
397static int __devinit piix_cable_detect(ide_hwif_t *hwif) 397struct ich_laptop {
398 u16 device;
399 u16 subvendor;
400 u16 subdevice;
401};
402
403/*
404 * List of laptops that use short cables rather than 80 wire
405 */
406
407static const struct ich_laptop ich_laptop[] = {
408 /* devid, subvendor, subdev */
409 { 0x27DF, 0x0005, 0x0280 }, /* ICH7 on Acer 5602WLMi */
410 { 0x27DF, 0x1025, 0x0110 }, /* ICH7 on Acer 3682WLMi */
411 { 0x27DF, 0x1043, 0x1267 }, /* ICH7 on Asus W5F */
412 { 0x24CA, 0x1025, 0x0061 }, /* ICH4 on Acer Aspire 2023WLMi */
413 /* end marker */
414 { 0, }
415};
416
417static u8 __devinit piix_cable_detect(ide_hwif_t *hwif)
398{ 418{
399 struct pci_dev *dev = hwif->pci_dev; 419 struct pci_dev *pdev = hwif->pci_dev;
420 const struct ich_laptop *lap = &ich_laptop[0];
400 u8 reg54h = 0, mask = hwif->channel ? 0xc0 : 0x30; 421 u8 reg54h = 0, mask = hwif->channel ? 0xc0 : 0x30;
401 422
402 pci_read_config_byte(dev, 0x54, &reg54h); 423 /* check for specials */
424 while (lap->device) {
425 if (lap->device == pdev->device &&
426 lap->subvendor == pdev->subsystem_vendor &&
427 lap->subdevice == pdev->subsystem_device) {
428 return ATA_CBL_PATA40_SHORT;
429 }
430 lap++;
431 }
432
433 pci_read_config_byte(pdev, 0x54, &reg54h);
403 434
404 return (reg54h & mask) ? 1 : 0; 435 return (reg54h & mask) ? ATA_CBL_PATA80 : ATA_CBL_PATA40;
405} 436}
406 437
407/** 438/**
@@ -444,8 +475,8 @@ static void __devinit init_hwif_piix(ide_hwif_t *hwif)
444 hwif->swdma_mask = 0x04; 475 hwif->swdma_mask = 0x04;
445 476
446 if (hwif->ultra_mask & 0x78) { 477 if (hwif->ultra_mask & 0x78) {
447 if (!hwif->udma_four) 478 if (hwif->cbl != ATA_CBL_PATA40_SHORT)
448 hwif->udma_four = piix_cable_detect(hwif); 479 hwif->cbl = piix_cable_detect(hwif);
449 } 480 }
450 481
451 if (no_piix_dma) 482 if (no_piix_dma)
diff --git a/drivers/ide/pci/scc_pata.c b/drivers/ide/pci/scc_pata.c
index 55bc0a32e34f..7b87488e3daa 100644
--- a/drivers/ide/pci/scc_pata.c
+++ b/drivers/ide/pci/scc_pata.c
@@ -716,7 +716,7 @@ static void __devinit init_hwif_scc(ide_hwif_t *hwif)
716 hwif->atapi_dma = 1; 716 hwif->atapi_dma = 1;
717 717
718 /* we support 80c cable only. */ 718 /* we support 80c cable only. */
719 hwif->udma_four = 1; 719 hwif->cbl = ATA_CBL_PATA80;
720 720
721 hwif->autodma = 0; 721 hwif->autodma = 0;
722 if (!noautodma) 722 if (!noautodma)
diff --git a/drivers/ide/pci/serverworks.c b/drivers/ide/pci/serverworks.c
index d9c4fd1ae996..1371b5bf6bf0 100644
--- a/drivers/ide/pci/serverworks.c
+++ b/drivers/ide/pci/serverworks.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * linux/drivers/ide/pci/serverworks.c Version 0.11 Jun 2 2007 2 * linux/drivers/ide/pci/serverworks.c Version 0.20 Jun 3 2007
3 * 3 *
4 * Copyright (C) 1998-2000 Michel Aubry 4 * Copyright (C) 1998-2000 Michel Aubry
5 * Copyright (C) 1998-2000 Andrzej Krzysztofowicz 5 * Copyright (C) 1998-2000 Andrzej Krzysztofowicz
@@ -151,84 +151,11 @@ static int svwks_tune_chipset (ide_drive_t *drive, u8 xferspeed)
151 if(dev->device == PCI_DEVICE_ID_SERVERWORKS_OSB4 && 151 if(dev->device == PCI_DEVICE_ID_SERVERWORKS_OSB4 &&
152 drive->media == ide_disk && speed >= XFER_UDMA_0) 152 drive->media == ide_disk && speed >= XFER_UDMA_0)
153 BUG(); 153 BUG();
154 154
155 pci_read_config_byte(dev, drive_pci[drive->dn], &pio_timing);
156 pci_read_config_byte(dev, drive_pci2[drive->dn], &dma_timing);
157 pci_read_config_byte(dev, (0x56|hwif->channel), &ultra_timing); 155 pci_read_config_byte(dev, (0x56|hwif->channel), &ultra_timing);
158 pci_read_config_word(dev, 0x4A, &csb5_pio); 156 pci_read_config_word(dev, 0x4A, &csb5_pio);
159 pci_read_config_byte(dev, 0x54, &ultra_enable); 157 pci_read_config_byte(dev, 0x54, &ultra_enable);
160 158
161 /* If we are in RAID mode (eg AMI MegaIDE) then we can't it
162 turns out trust the firmware configuration */
163
164 if ((dev->class >> 8) != PCI_CLASS_STORAGE_IDE)
165 goto oem_setup_failed;
166
167 /* Per Specified Design by OEM, and ASIC Architect */
168 if ((dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE) ||
169 (dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2)) {
170 if (!drive->init_speed) {
171 u8 dma_stat = inb(hwif->dma_status);
172
173 if (((ultra_enable << (7-drive->dn) & 0x80) == 0x80) &&
174 ((dma_stat & (1<<(5+unit))) == (1<<(5+unit)))) {
175 drive->current_speed = drive->init_speed = XFER_UDMA_0 + udma_modes[(ultra_timing >> (4*unit)) & ~(0xF0)];
176 return 0;
177 } else if ((dma_timing) &&
178 ((dma_stat&(1<<(5+unit)))==(1<<(5+unit)))) {
179 u8 dmaspeed;
180
181 switch (dma_timing & 0x77) {
182 case 0x20:
183 dmaspeed = XFER_MW_DMA_2;
184 break;
185 case 0x21:
186 dmaspeed = XFER_MW_DMA_1;
187 break;
188 case 0x77:
189 dmaspeed = XFER_MW_DMA_0;
190 break;
191 default:
192 goto dma_pio;
193 }
194
195 drive->current_speed = drive->init_speed = dmaspeed;
196 return 0;
197 }
198dma_pio:
199 if (pio_timing) {
200 u8 piospeed;
201
202 switch (pio_timing & 0x7f) {
203 case 0x20:
204 piospeed = XFER_PIO_4;
205 break;
206 case 0x22:
207 piospeed = XFER_PIO_3;
208 break;
209 case 0x34:
210 piospeed = XFER_PIO_2;
211 break;
212 case 0x47:
213 piospeed = XFER_PIO_1;
214 break;
215 case 0x5d:
216 piospeed = XFER_PIO_0;
217 break;
218 default:
219 goto oem_setup_failed;
220 }
221
222 drive->current_speed = drive->init_speed = piospeed;
223 return 0;
224 }
225 }
226 }
227
228oem_setup_failed:
229
230 pio_timing = 0;
231 dma_timing = 0;
232 ultra_timing &= ~(0x0F << (4*unit)); 159 ultra_timing &= ~(0x0F << (4*unit));
233 ultra_enable &= ~(0x01 << drive->dn); 160 ultra_enable &= ~(0x01 << drive->dn);
234 csb5_pio &= ~(0x0F << (4*drive->dn)); 161 csb5_pio &= ~(0x0F << (4*drive->dn));
@@ -402,9 +329,9 @@ static unsigned int __devinit init_chipset_svwks (struct pci_dev *dev, const cha
402 return dev->irq; 329 return dev->irq;
403} 330}
404 331
405static unsigned int __devinit ata66_svwks_svwks (ide_hwif_t *hwif) 332static u8 __devinit ata66_svwks_svwks(ide_hwif_t *hwif)
406{ 333{
407 return 1; 334 return ATA_CBL_PATA80;
408} 335}
409 336
410/* On Dell PowerEdge servers with a CSB5/CSB6, the top two bits 337/* On Dell PowerEdge servers with a CSB5/CSB6, the top two bits
@@ -414,7 +341,7 @@ static unsigned int __devinit ata66_svwks_svwks (ide_hwif_t *hwif)
414 * Bit 14 clear = primary IDE channel does not have 80-pin cable. 341 * Bit 14 clear = primary IDE channel does not have 80-pin cable.
415 * Bit 14 set = primary IDE channel has 80-pin cable. 342 * Bit 14 set = primary IDE channel has 80-pin cable.
416 */ 343 */
417static unsigned int __devinit ata66_svwks_dell (ide_hwif_t *hwif) 344static u8 __devinit ata66_svwks_dell(ide_hwif_t *hwif)
418{ 345{
419 struct pci_dev *dev = hwif->pci_dev; 346 struct pci_dev *dev = hwif->pci_dev;
420 if (dev->subsystem_vendor == PCI_VENDOR_ID_DELL && 347 if (dev->subsystem_vendor == PCI_VENDOR_ID_DELL &&
@@ -422,8 +349,8 @@ static unsigned int __devinit ata66_svwks_dell (ide_hwif_t *hwif)
422 (dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5IDE || 349 (dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5IDE ||
423 dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE)) 350 dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE))
424 return ((1 << (hwif->channel + 14)) & 351 return ((1 << (hwif->channel + 14)) &
425 dev->subsystem_device) ? 1 : 0; 352 dev->subsystem_device) ? ATA_CBL_PATA80 : ATA_CBL_PATA40;
426 return 0; 353 return ATA_CBL_PATA40;
427} 354}
428 355
429/* Sun Cobalt Alpine hardware avoids the 80-pin cable 356/* Sun Cobalt Alpine hardware avoids the 80-pin cable
@@ -432,18 +359,18 @@ static unsigned int __devinit ata66_svwks_dell (ide_hwif_t *hwif)
432 * 359 *
433 * WARNING: this only works on Alpine hardware! 360 * WARNING: this only works on Alpine hardware!
434 */ 361 */
435static unsigned int __devinit ata66_svwks_cobalt (ide_hwif_t *hwif) 362static u8 __devinit ata66_svwks_cobalt(ide_hwif_t *hwif)
436{ 363{
437 struct pci_dev *dev = hwif->pci_dev; 364 struct pci_dev *dev = hwif->pci_dev;
438 if (dev->subsystem_vendor == PCI_VENDOR_ID_SUN && 365 if (dev->subsystem_vendor == PCI_VENDOR_ID_SUN &&
439 dev->vendor == PCI_VENDOR_ID_SERVERWORKS && 366 dev->vendor == PCI_VENDOR_ID_SERVERWORKS &&
440 dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5IDE) 367 dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5IDE)
441 return ((1 << (hwif->channel + 14)) & 368 return ((1 << (hwif->channel + 14)) &
442 dev->subsystem_device) ? 1 : 0; 369 dev->subsystem_device) ? ATA_CBL_PATA80 : ATA_CBL_PATA40;
443 return 0; 370 return ATA_CBL_PATA40;
444} 371}
445 372
446static unsigned int __devinit ata66_svwks (ide_hwif_t *hwif) 373static u8 __devinit ata66_svwks(ide_hwif_t *hwif)
447{ 374{
448 struct pci_dev *dev = hwif->pci_dev; 375 struct pci_dev *dev = hwif->pci_dev;
449 376
@@ -462,9 +389,9 @@ static unsigned int __devinit ata66_svwks (ide_hwif_t *hwif)
462 /* Per Specified Design by OEM, and ASIC Architect */ 389 /* Per Specified Design by OEM, and ASIC Architect */
463 if ((dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE) || 390 if ((dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE) ||
464 (dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2)) 391 (dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2))
465 return 1; 392 return ATA_CBL_PATA80;
466 393
467 return 0; 394 return ATA_CBL_PATA40;
468} 395}
469 396
470static void __devinit init_hwif_svwks (ide_hwif_t *hwif) 397static void __devinit init_hwif_svwks (ide_hwif_t *hwif)
@@ -495,8 +422,8 @@ static void __devinit init_hwif_svwks (ide_hwif_t *hwif)
495 422
496 hwif->ide_dma_check = &svwks_config_drive_xfer_rate; 423 hwif->ide_dma_check = &svwks_config_drive_xfer_rate;
497 if (hwif->pci_dev->device != PCI_DEVICE_ID_SERVERWORKS_OSB4IDE) { 424 if (hwif->pci_dev->device != PCI_DEVICE_ID_SERVERWORKS_OSB4IDE) {
498 if (!hwif->udma_four) 425 if (hwif->cbl != ATA_CBL_PATA40_SHORT)
499 hwif->udma_four = ata66_svwks(hwif); 426 hwif->cbl = ata66_svwks(hwif);
500 } 427 }
501 if (!noautodma) 428 if (!noautodma)
502 hwif->autodma = 1; 429 hwif->autodma = 1;
diff --git a/drivers/ide/pci/sgiioc4.c b/drivers/ide/pci/sgiioc4.c
index d3185e29a38e..d396b2929ed8 100644
--- a/drivers/ide/pci/sgiioc4.c
+++ b/drivers/ide/pci/sgiioc4.c
@@ -316,14 +316,6 @@ static void sgiioc4_dma_host_off(ide_drive_t * drive)
316 sgiioc4_clearirq(drive); 316 sgiioc4_clearirq(drive);
317} 317}
318 318
319static int
320sgiioc4_ide_dma_lostirq(ide_drive_t * drive)
321{
322 HWIF(drive)->resetproc(drive);
323
324 return __ide_dma_lostirq(drive);
325}
326
327static void 319static void
328sgiioc4_resetproc(ide_drive_t * drive) 320sgiioc4_resetproc(ide_drive_t * drive)
329{ 321{
@@ -331,6 +323,14 @@ sgiioc4_resetproc(ide_drive_t * drive)
331 sgiioc4_clearirq(drive); 323 sgiioc4_clearirq(drive);
332} 324}
333 325
326static void
327sgiioc4_dma_lost_irq(ide_drive_t * drive)
328{
329 sgiioc4_resetproc(drive);
330
331 ide_dma_lost_irq(drive);
332}
333
334static u8 334static u8
335sgiioc4_INB(unsigned long port) 335sgiioc4_INB(unsigned long port)
336{ 336{
@@ -607,8 +607,8 @@ ide_init_sgiioc4(ide_hwif_t * hwif)
607 hwif->ide_dma_test_irq = &sgiioc4_ide_dma_test_irq; 607 hwif->ide_dma_test_irq = &sgiioc4_ide_dma_test_irq;
608 hwif->dma_host_on = &sgiioc4_dma_host_on; 608 hwif->dma_host_on = &sgiioc4_dma_host_on;
609 hwif->dma_host_off = &sgiioc4_dma_host_off; 609 hwif->dma_host_off = &sgiioc4_dma_host_off;
610 hwif->ide_dma_lostirq = &sgiioc4_ide_dma_lostirq; 610 hwif->dma_lost_irq = &sgiioc4_dma_lost_irq;
611 hwif->ide_dma_timeout = &__ide_dma_timeout; 611 hwif->dma_timeout = &ide_dma_timeout;
612 612
613 hwif->INB = &sgiioc4_INB; 613 hwif->INB = &sgiioc4_INB;
614} 614}
diff --git a/drivers/ide/pci/siimage.c b/drivers/ide/pci/siimage.c
index 1a4444e7226a..1c3e35487893 100644
--- a/drivers/ide/pci/siimage.c
+++ b/drivers/ide/pci/siimage.c
@@ -933,16 +933,17 @@ static void __devinit init_iops_siimage(ide_hwif_t *hwif)
933 * interface. 933 * interface.
934 */ 934 */
935 935
936static unsigned int __devinit ata66_siimage(ide_hwif_t *hwif) 936static u8 __devinit ata66_siimage(ide_hwif_t *hwif)
937{ 937{
938 unsigned long addr = siimage_selreg(hwif, 0); 938 unsigned long addr = siimage_selreg(hwif, 0);
939 if (pci_get_drvdata(hwif->pci_dev) == NULL) { 939 u8 ata66 = 0;
940 u8 ata66 = 0; 940
941 if (pci_get_drvdata(hwif->pci_dev) == NULL)
941 pci_read_config_byte(hwif->pci_dev, addr, &ata66); 942 pci_read_config_byte(hwif->pci_dev, addr, &ata66);
942 return (ata66 & 0x01) ? 1 : 0; 943 else
943 } 944 ata66 = hwif->INB(addr);
944 945
945 return (hwif->INB(addr) & 0x01) ? 1 : 0; 946 return (ata66 & 0x01) ? ATA_CBL_PATA80 : ATA_CBL_PATA40;
946} 947}
947 948
948/** 949/**
@@ -988,8 +989,9 @@ static void __devinit init_hwif_siimage(ide_hwif_t *hwif)
988 hwif->atapi_dma = 1; 989 hwif->atapi_dma = 1;
989 990
990 hwif->ide_dma_check = &siimage_config_drive_for_dma; 991 hwif->ide_dma_check = &siimage_config_drive_for_dma;
991 if (!(hwif->udma_four)) 992
992 hwif->udma_four = ata66_siimage(hwif); 993 if (hwif->cbl != ATA_CBL_PATA40_SHORT)
994 hwif->cbl = ata66_siimage(hwif);
993 995
994 if (hwif->mmio) { 996 if (hwif->mmio) {
995 hwif->ide_dma_test_irq = &siimage_mmio_ide_dma_test_irq; 997 hwif->ide_dma_test_irq = &siimage_mmio_ide_dma_test_irq;
diff --git a/drivers/ide/pci/sis5513.c b/drivers/ide/pci/sis5513.c
index ec0adad9ef61..f875183ac8d9 100644
--- a/drivers/ide/pci/sis5513.c
+++ b/drivers/ide/pci/sis5513.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * linux/drivers/ide/pci/sis5513.c Version 0.20 Mar 4, 2007 2 * linux/drivers/ide/pci/sis5513.c Version 0.25 Jun 10, 2007
3 * 3 *
4 * Copyright (C) 1999-2000 Andre Hedrick <andre@linux-ide.org> 4 * Copyright (C) 1999-2000 Andre Hedrick <andre@linux-ide.org>
5 * Copyright (C) 2002 Lionel Bouton <Lionel.Bouton@inet6.fr>, Maintainer 5 * Copyright (C) 2002 Lionel Bouton <Lionel.Bouton@inet6.fr>, Maintainer
@@ -796,10 +796,33 @@ static unsigned int __devinit init_chipset_sis5513 (struct pci_dev *dev, const c
796 return 0; 796 return 0;
797} 797}
798 798
799static unsigned int __devinit ata66_sis5513 (ide_hwif_t *hwif) 799struct sis_laptop {
800 u16 device;
801 u16 subvendor;
802 u16 subdevice;
803};
804
805static const struct sis_laptop sis_laptop[] = {
806 /* devid, subvendor, subdev */
807 { 0x5513, 0x1043, 0x1107 }, /* ASUS A6K */
808 /* end marker */
809 { 0, }
810};
811
812static u8 __devinit ata66_sis5513(ide_hwif_t *hwif)
800{ 813{
814 struct pci_dev *pdev = hwif->pci_dev;
815 const struct sis_laptop *lap = &sis_laptop[0];
801 u8 ata66 = 0; 816 u8 ata66 = 0;
802 817
818 while (lap->device) {
819 if (lap->device == pdev->device &&
820 lap->subvendor == pdev->subsystem_vendor &&
821 lap->subdevice == pdev->subsystem_device)
822 return ATA_CBL_PATA40_SHORT;
823 lap++;
824 }
825
803 if (chipset_family >= ATA_133) { 826 if (chipset_family >= ATA_133) {
804 u16 regw = 0; 827 u16 regw = 0;
805 u16 reg_addr = hwif->channel ? 0x52: 0x50; 828 u16 reg_addr = hwif->channel ? 0x52: 0x50;
@@ -811,7 +834,8 @@ static unsigned int __devinit ata66_sis5513 (ide_hwif_t *hwif)
811 pci_read_config_byte(hwif->pci_dev, 0x48, &reg48h); 834 pci_read_config_byte(hwif->pci_dev, 0x48, &reg48h);
812 ata66 = (reg48h & mask) ? 0 : 1; 835 ata66 = (reg48h & mask) ? 0 : 1;
813 } 836 }
814 return ata66; 837
838 return ata66 ? ATA_CBL_PATA80 : ATA_CBL_PATA40;
815} 839}
816 840
817static void __devinit init_hwif_sis5513 (ide_hwif_t *hwif) 841static void __devinit init_hwif_sis5513 (ide_hwif_t *hwif)
@@ -841,8 +865,8 @@ static void __devinit init_hwif_sis5513 (ide_hwif_t *hwif)
841 if (!chipset_family) 865 if (!chipset_family)
842 return; 866 return;
843 867
844 if (!(hwif->udma_four)) 868 if (hwif->cbl != ATA_CBL_PATA40_SHORT)
845 hwif->udma_four = ata66_sis5513(hwif); 869 hwif->cbl = ata66_sis5513(hwif);
846 870
847 if (chipset_family > ATA_16) { 871 if (chipset_family > ATA_16) {
848 hwif->ide_dma_check = &sis5513_config_xfer_rate; 872 hwif->ide_dma_check = &sis5513_config_xfer_rate;
diff --git a/drivers/ide/pci/sl82c105.c b/drivers/ide/pci/sl82c105.c
index 7c383d9cc472..487879842af4 100644
--- a/drivers/ide/pci/sl82c105.c
+++ b/drivers/ide/pci/sl82c105.c
@@ -195,7 +195,7 @@ static inline void sl82c105_reset_host(struct pci_dev *dev)
195 * This function is called when the IDE timer expires, the drive 195 * This function is called when the IDE timer expires, the drive
196 * indicates that it is READY, and we were waiting for DMA to complete. 196 * indicates that it is READY, and we were waiting for DMA to complete.
197 */ 197 */
198static int sl82c105_ide_dma_lostirq(ide_drive_t *drive) 198static void sl82c105_dma_lost_irq(ide_drive_t *drive)
199{ 199{
200 ide_hwif_t *hwif = HWIF(drive); 200 ide_hwif_t *hwif = HWIF(drive);
201 struct pci_dev *dev = hwif->pci_dev; 201 struct pci_dev *dev = hwif->pci_dev;
@@ -222,9 +222,6 @@ static int sl82c105_ide_dma_lostirq(ide_drive_t *drive)
222 } 222 }
223 223
224 sl82c105_reset_host(dev); 224 sl82c105_reset_host(dev);
225
226 /* __ide_dma_lostirq would return 1, so we do as well */
227 return 1;
228} 225}
229 226
230/* 227/*
@@ -244,15 +241,12 @@ static void sl82c105_dma_start(ide_drive_t *drive)
244 ide_dma_start(drive); 241 ide_dma_start(drive);
245} 242}
246 243
247static int sl82c105_ide_dma_timeout(ide_drive_t *drive) 244static void sl82c105_dma_timeout(ide_drive_t *drive)
248{ 245{
249 ide_hwif_t *hwif = HWIF(drive); 246 DBG(("sl82c105_dma_timeout(drive:%s)\n", drive->name));
250 struct pci_dev *dev = hwif->pci_dev;
251 247
252 DBG(("sl82c105_ide_dma_timeout(drive:%s)\n", drive->name)); 248 sl82c105_reset_host(HWIF(drive)->pci_dev);
253 249 ide_dma_timeout(drive);
254 sl82c105_reset_host(dev);
255 return __ide_dma_timeout(drive);
256} 250}
257 251
258static int sl82c105_ide_dma_on(ide_drive_t *drive) 252static int sl82c105_ide_dma_on(ide_drive_t *drive)
@@ -441,9 +435,9 @@ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif)
441 hwif->ide_dma_check = &sl82c105_ide_dma_check; 435 hwif->ide_dma_check = &sl82c105_ide_dma_check;
442 hwif->ide_dma_on = &sl82c105_ide_dma_on; 436 hwif->ide_dma_on = &sl82c105_ide_dma_on;
443 hwif->dma_off_quietly = &sl82c105_dma_off_quietly; 437 hwif->dma_off_quietly = &sl82c105_dma_off_quietly;
444 hwif->ide_dma_lostirq = &sl82c105_ide_dma_lostirq; 438 hwif->dma_lost_irq = &sl82c105_dma_lost_irq;
445 hwif->dma_start = &sl82c105_dma_start; 439 hwif->dma_start = &sl82c105_dma_start;
446 hwif->ide_dma_timeout = &sl82c105_ide_dma_timeout; 440 hwif->dma_timeout = &sl82c105_dma_timeout;
447 441
448 if (!noautodma) 442 if (!noautodma)
449 hwif->autodma = 1; 443 hwif->autodma = 1;
diff --git a/drivers/ide/pci/slc90e66.c b/drivers/ide/pci/slc90e66.c
index c40f291f91e0..575dbbd8b482 100644
--- a/drivers/ide/pci/slc90e66.c
+++ b/drivers/ide/pci/slc90e66.c
@@ -199,10 +199,9 @@ static void __devinit init_hwif_slc90e66 (ide_hwif_t *hwif)
199 hwif->mwdma_mask = 0x06; 199 hwif->mwdma_mask = 0x06;
200 hwif->swdma_mask = 0x04; 200 hwif->swdma_mask = 0x04;
201 201
202 if (!hwif->udma_four) { 202 if (hwif->cbl != ATA_CBL_PATA40_SHORT)
203 /* bit[0(1)]: 0:80, 1:40 */ 203 /* bit[0(1)]: 0:80, 1:40 */
204 hwif->udma_four = (reg47 & mask) ? 0 : 1; 204 hwif->cbl = (reg47 & mask) ? ATA_CBL_PATA40 : ATA_CBL_PATA80;
205 }
206 205
207 hwif->ide_dma_check = &slc90e66_config_drive_xfer_rate; 206 hwif->ide_dma_check = &slc90e66_config_drive_xfer_rate;
208 207
diff --git a/drivers/ide/pci/tc86c001.c b/drivers/ide/pci/tc86c001.c
index cee619bb2eaf..8de1f8e22494 100644
--- a/drivers/ide/pci/tc86c001.c
+++ b/drivers/ide/pci/tc86c001.c
@@ -220,13 +220,13 @@ static void __devinit init_hwif_tc86c001(ide_hwif_t *hwif)
220 hwif->ide_dma_check = &tc86c001_config_drive_xfer_rate; 220 hwif->ide_dma_check = &tc86c001_config_drive_xfer_rate;
221 hwif->dma_start = &tc86c001_dma_start; 221 hwif->dma_start = &tc86c001_dma_start;
222 222
223 if (!hwif->udma_four) { 223 if (hwif->cbl != ATA_CBL_PATA40_SHORT) {
224 /* 224 /*
225 * System Control 1 Register bit 13 (PDIAGN): 225 * System Control 1 Register bit 13 (PDIAGN):
226 * 0=80-pin cable, 1=40-pin cable 226 * 0=80-pin cable, 1=40-pin cable
227 */ 227 */
228 scr1 = hwif->INW(sc_base + 0x00); 228 scr1 = hwif->INW(sc_base + 0x00);
229 hwif->udma_four = (scr1 & 0x2000) ? 0 : 1; 229 hwif->cbl = (scr1 & 0x2000) ? ATA_CBL_PATA40 : ATA_CBL_PATA80;
230 } 230 }
231 231
232 if (!noautodma) 232 if (!noautodma)
diff --git a/drivers/ide/pci/via82cxxx.c b/drivers/ide/pci/via82cxxx.c
index a508550c4095..d21dd2e7eeb3 100644
--- a/drivers/ide/pci/via82cxxx.c
+++ b/drivers/ide/pci/via82cxxx.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * 2 *
3 * Version 3.38 3 * Version 3.45
4 * 4 *
5 * VIA IDE driver for Linux. Supported southbridges: 5 * VIA IDE driver for Linux. Supported southbridges:
6 * 6 *
@@ -9,6 +9,7 @@
9 * vt8235, vt8237, vt8237a 9 * vt8235, vt8237, vt8237a
10 * 10 *
11 * Copyright (c) 2000-2002 Vojtech Pavlik 11 * Copyright (c) 2000-2002 Vojtech Pavlik
12 * Copyright (c) 2007 Bartlomiej Zolnierkiewicz
12 * 13 *
13 * Based on the work of: 14 * Based on the work of:
14 * Michel Aubry 15 * Michel Aubry
@@ -33,6 +34,8 @@
33#include <linux/pci.h> 34#include <linux/pci.h>
34#include <linux/init.h> 35#include <linux/init.h>
35#include <linux/ide.h> 36#include <linux/ide.h>
37#include <linux/dmi.h>
38
36#include <asm/io.h> 39#include <asm/io.h>
37 40
38#ifdef CONFIG_PPC_CHRP 41#ifdef CONFIG_PPC_CHRP
@@ -41,8 +44,6 @@
41 44
42#include "ide-timing.h" 45#include "ide-timing.h"
43 46
44#define DISPLAY_VIA_TIMINGS
45
46#define VIA_IDE_ENABLE 0x40 47#define VIA_IDE_ENABLE 0x40
47#define VIA_IDE_CONFIG 0x41 48#define VIA_IDE_CONFIG 0x41
48#define VIA_FIFO_CONFIG 0x43 49#define VIA_FIFO_CONFIG 0x43
@@ -54,18 +55,12 @@
54#define VIA_ADDRESS_SETUP 0x4c 55#define VIA_ADDRESS_SETUP 0x4c
55#define VIA_UDMA_TIMING 0x50 56#define VIA_UDMA_TIMING 0x50
56 57
57#define VIA_UDMA 0x007 58#define VIA_BAD_PREQ 0x01 /* Crashes if PREQ# till DDACK# set */
58#define VIA_UDMA_NONE 0x000 59#define VIA_BAD_CLK66 0x02 /* 66 MHz clock doesn't work correctly */
59#define VIA_UDMA_33 0x001 60#define VIA_SET_FIFO 0x04 /* Needs to have FIFO split set */
60#define VIA_UDMA_66 0x002 61#define VIA_NO_UNMASK 0x08 /* Doesn't work with IRQ unmasking on */
61#define VIA_UDMA_100 0x003 62#define VIA_BAD_ID 0x10 /* Has wrong vendor ID (0x1107) */
62#define VIA_UDMA_133 0x004 63#define VIA_BAD_AST 0x20 /* Don't touch Address Setup Timing */
63#define VIA_BAD_PREQ 0x010 /* Crashes if PREQ# till DDACK# set */
64#define VIA_BAD_CLK66 0x020 /* 66 MHz clock doesn't work correctly */
65#define VIA_SET_FIFO 0x040 /* Needs to have FIFO split set */
66#define VIA_NO_UNMASK 0x080 /* Doesn't work with IRQ unmasking on */
67#define VIA_BAD_ID 0x100 /* Has wrong vendor ID (0x1107) */
68#define VIA_BAD_AST 0x200 /* Don't touch Address Setup Timing */
69 64
70/* 65/*
71 * VIA SouthBridge chips. 66 * VIA SouthBridge chips.
@@ -76,36 +71,37 @@ static struct via_isa_bridge {
76 u16 id; 71 u16 id;
77 u8 rev_min; 72 u8 rev_min;
78 u8 rev_max; 73 u8 rev_max;
79 u16 flags; 74 u8 udma_mask;
75 u8 flags;
80} via_isa_bridges[] = { 76} via_isa_bridges[] = {
81 { "cx700", PCI_DEVICE_ID_VIA_CX700, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, 77 { "cx700", PCI_DEVICE_ID_VIA_CX700, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
82 { "vt8237s", PCI_DEVICE_ID_VIA_8237S, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, 78 { "vt8237s", PCI_DEVICE_ID_VIA_8237S, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
83 { "vt6410", PCI_DEVICE_ID_VIA_6410, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, 79 { "vt6410", PCI_DEVICE_ID_VIA_6410, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
84 { "vt8251", PCI_DEVICE_ID_VIA_8251, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, 80 { "vt8251", PCI_DEVICE_ID_VIA_8251, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
85 { "vt8237", PCI_DEVICE_ID_VIA_8237, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, 81 { "vt8237", PCI_DEVICE_ID_VIA_8237, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
86 { "vt8237a", PCI_DEVICE_ID_VIA_8237A, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, 82 { "vt8237a", PCI_DEVICE_ID_VIA_8237A, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
87 { "vt8235", PCI_DEVICE_ID_VIA_8235, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, 83 { "vt8235", PCI_DEVICE_ID_VIA_8235, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
88 { "vt8233a", PCI_DEVICE_ID_VIA_8233A, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, 84 { "vt8233a", PCI_DEVICE_ID_VIA_8233A, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
89 { "vt8233c", PCI_DEVICE_ID_VIA_8233C_0, 0x00, 0x2f, VIA_UDMA_100 }, 85 { "vt8233c", PCI_DEVICE_ID_VIA_8233C_0, 0x00, 0x2f, ATA_UDMA5, },
90 { "vt8233", PCI_DEVICE_ID_VIA_8233_0, 0x00, 0x2f, VIA_UDMA_100 }, 86 { "vt8233", PCI_DEVICE_ID_VIA_8233_0, 0x00, 0x2f, ATA_UDMA5, },
91 { "vt8231", PCI_DEVICE_ID_VIA_8231, 0x00, 0x2f, VIA_UDMA_100 }, 87 { "vt8231", PCI_DEVICE_ID_VIA_8231, 0x00, 0x2f, ATA_UDMA5, },
92 { "vt82c686b", PCI_DEVICE_ID_VIA_82C686, 0x40, 0x4f, VIA_UDMA_100 }, 88 { "vt82c686b", PCI_DEVICE_ID_VIA_82C686, 0x40, 0x4f, ATA_UDMA5, },
93 { "vt82c686a", PCI_DEVICE_ID_VIA_82C686, 0x10, 0x2f, VIA_UDMA_66 }, 89 { "vt82c686a", PCI_DEVICE_ID_VIA_82C686, 0x10, 0x2f, ATA_UDMA4, },
94 { "vt82c686", PCI_DEVICE_ID_VIA_82C686, 0x00, 0x0f, VIA_UDMA_33 | VIA_BAD_CLK66 }, 90 { "vt82c686", PCI_DEVICE_ID_VIA_82C686, 0x00, 0x0f, ATA_UDMA2, VIA_BAD_CLK66 },
95 { "vt82c596b", PCI_DEVICE_ID_VIA_82C596, 0x10, 0x2f, VIA_UDMA_66 }, 91 { "vt82c596b", PCI_DEVICE_ID_VIA_82C596, 0x10, 0x2f, ATA_UDMA4, },
96 { "vt82c596a", PCI_DEVICE_ID_VIA_82C596, 0x00, 0x0f, VIA_UDMA_33 | VIA_BAD_CLK66 }, 92 { "vt82c596a", PCI_DEVICE_ID_VIA_82C596, 0x00, 0x0f, ATA_UDMA2, VIA_BAD_CLK66 },
97 { "vt82c586b", PCI_DEVICE_ID_VIA_82C586_0, 0x47, 0x4f, VIA_UDMA_33 | VIA_SET_FIFO }, 93 { "vt82c586b", PCI_DEVICE_ID_VIA_82C586_0, 0x47, 0x4f, ATA_UDMA2, VIA_SET_FIFO },
98 { "vt82c586b", PCI_DEVICE_ID_VIA_82C586_0, 0x40, 0x46, VIA_UDMA_33 | VIA_SET_FIFO | VIA_BAD_PREQ }, 94 { "vt82c586b", PCI_DEVICE_ID_VIA_82C586_0, 0x40, 0x46, ATA_UDMA2, VIA_SET_FIFO | VIA_BAD_PREQ },
99 { "vt82c586b", PCI_DEVICE_ID_VIA_82C586_0, 0x30, 0x3f, VIA_UDMA_33 | VIA_SET_FIFO }, 95 { "vt82c586b", PCI_DEVICE_ID_VIA_82C586_0, 0x30, 0x3f, ATA_UDMA2, VIA_SET_FIFO },
100 { "vt82c586a", PCI_DEVICE_ID_VIA_82C586_0, 0x20, 0x2f, VIA_UDMA_33 | VIA_SET_FIFO }, 96 { "vt82c586a", PCI_DEVICE_ID_VIA_82C586_0, 0x20, 0x2f, ATA_UDMA2, VIA_SET_FIFO },
101 { "vt82c586", PCI_DEVICE_ID_VIA_82C586_0, 0x00, 0x0f, VIA_UDMA_NONE | VIA_SET_FIFO }, 97 { "vt82c586", PCI_DEVICE_ID_VIA_82C586_0, 0x00, 0x0f, 0x00, VIA_SET_FIFO },
102 { "vt82c576", PCI_DEVICE_ID_VIA_82C576, 0x00, 0x2f, VIA_UDMA_NONE | VIA_SET_FIFO | VIA_NO_UNMASK }, 98 { "vt82c576", PCI_DEVICE_ID_VIA_82C576, 0x00, 0x2f, 0x00, VIA_SET_FIFO | VIA_NO_UNMASK },
103 { "vt82c576", PCI_DEVICE_ID_VIA_82C576, 0x00, 0x2f, VIA_UDMA_NONE | VIA_SET_FIFO | VIA_NO_UNMASK | VIA_BAD_ID }, 99 { "vt82c576", PCI_DEVICE_ID_VIA_82C576, 0x00, 0x2f, 0x00, VIA_SET_FIFO | VIA_NO_UNMASK | VIA_BAD_ID },
104 { NULL } 100 { NULL }
105}; 101};
106 102
107static unsigned int via_clock; 103static unsigned int via_clock;
108static char *via_dma[] = { "MWDMA16", "UDMA33", "UDMA66", "UDMA100", "UDMA133" }; 104static char *via_dma[] = { "16", "25", "33", "44", "66", "100", "133" };
109 105
110struct via82cxxx_dev 106struct via82cxxx_dev
111{ 107{
@@ -140,12 +136,12 @@ static void via_set_speed(ide_hwif_t *hwif, u8 dn, struct ide_timing *timing)
140 pci_write_config_byte(dev, VIA_DRIVE_TIMING + (3 - dn), 136 pci_write_config_byte(dev, VIA_DRIVE_TIMING + (3 - dn),
141 ((FIT(timing->active, 1, 16) - 1) << 4) | (FIT(timing->recover, 1, 16) - 1)); 137 ((FIT(timing->active, 1, 16) - 1) << 4) | (FIT(timing->recover, 1, 16) - 1));
142 138
143 switch (vdev->via_config->flags & VIA_UDMA) { 139 switch (vdev->via_config->udma_mask) {
144 case VIA_UDMA_33: t = timing->udma ? (0xe0 | (FIT(timing->udma, 2, 5) - 2)) : 0x03; break; 140 case ATA_UDMA2: t = timing->udma ? (0xe0 | (FIT(timing->udma, 2, 5) - 2)) : 0x03; break;
145 case VIA_UDMA_66: t = timing->udma ? (0xe8 | (FIT(timing->udma, 2, 9) - 2)) : 0x0f; break; 141 case ATA_UDMA4: t = timing->udma ? (0xe8 | (FIT(timing->udma, 2, 9) - 2)) : 0x0f; break;
146 case VIA_UDMA_100: t = timing->udma ? (0xe0 | (FIT(timing->udma, 2, 9) - 2)) : 0x07; break; 142 case ATA_UDMA5: t = timing->udma ? (0xe0 | (FIT(timing->udma, 2, 9) - 2)) : 0x07; break;
147 case VIA_UDMA_133: t = timing->udma ? (0xe0 | (FIT(timing->udma, 2, 9) - 2)) : 0x07; break; 143 case ATA_UDMA6: t = timing->udma ? (0xe0 | (FIT(timing->udma, 2, 9) - 2)) : 0x07; break;
148 default: return; 144 default: return;
149 } 145 }
150 146
151 pci_write_config_byte(dev, VIA_UDMA_TIMING + (3 - dn), t); 147 pci_write_config_byte(dev, VIA_UDMA_TIMING + (3 - dn), t);
@@ -173,12 +169,12 @@ static int via_set_drive(ide_drive_t *drive, u8 speed)
173 169
174 T = 1000000000 / via_clock; 170 T = 1000000000 / via_clock;
175 171
176 switch (vdev->via_config->flags & VIA_UDMA) { 172 switch (vdev->via_config->udma_mask) {
177 case VIA_UDMA_33: UT = T; break; 173 case ATA_UDMA2: UT = T; break;
178 case VIA_UDMA_66: UT = T/2; break; 174 case ATA_UDMA4: UT = T/2; break;
179 case VIA_UDMA_100: UT = T/3; break; 175 case ATA_UDMA5: UT = T/3; break;
180 case VIA_UDMA_133: UT = T/4; break; 176 case ATA_UDMA6: UT = T/4; break;
181 default: UT = T; 177 default: UT = T;
182 } 178 }
183 179
184 ide_timing_compute(drive, speed, &t, T, UT); 180 ide_timing_compute(drive, speed, &t, T, UT);
@@ -208,8 +204,7 @@ static int via_set_drive(ide_drive_t *drive, u8 speed)
208static void via82cxxx_tune_drive(ide_drive_t *drive, u8 pio) 204static void via82cxxx_tune_drive(ide_drive_t *drive, u8 pio)
209{ 205{
210 if (pio == 255) { 206 if (pio == 255) {
211 via_set_drive(drive, 207 via_set_drive(drive, ide_find_best_pio_mode(drive));
212 ide_find_best_mode(drive, XFER_PIO | XFER_EPIO));
213 return; 208 return;
214 } 209 }
215 210
@@ -226,16 +221,10 @@ static void via82cxxx_tune_drive(ide_drive_t *drive, u8 pio)
226 221
227static int via82cxxx_ide_dma_check (ide_drive_t *drive) 222static int via82cxxx_ide_dma_check (ide_drive_t *drive)
228{ 223{
229 ide_hwif_t *hwif = HWIF(drive); 224 u8 speed = ide_max_dma_mode(drive);
230 struct via82cxxx_dev *vdev = pci_get_drvdata(hwif->pci_dev);
231 u16 w80 = hwif->udma_four;
232 225
233 u16 speed = ide_find_best_mode(drive, 226 if (speed == 0)
234 XFER_PIO | XFER_EPIO | XFER_SWDMA | XFER_MWDMA | 227 speed = ide_find_best_pio_mode(drive);
235 (vdev->via_config->flags & VIA_UDMA ? XFER_UDMA : 0) |
236 (w80 && (vdev->via_config->flags & VIA_UDMA) >= VIA_UDMA_66 ? XFER_UDMA_66 : 0) |
237 (w80 && (vdev->via_config->flags & VIA_UDMA) >= VIA_UDMA_100 ? XFER_UDMA_100 : 0) |
238 (w80 && (vdev->via_config->flags & VIA_UDMA) >= VIA_UDMA_133 ? XFER_UDMA_133 : 0));
239 228
240 via_set_drive(drive, speed); 229 via_set_drive(drive, speed);
241 230
@@ -272,8 +261,8 @@ static void __devinit via_cable_detect(struct via82cxxx_dev *vdev, u32 u)
272{ 261{
273 int i; 262 int i;
274 263
275 switch (vdev->via_config->flags & VIA_UDMA) { 264 switch (vdev->via_config->udma_mask) {
276 case VIA_UDMA_66: 265 case ATA_UDMA4:
277 for (i = 24; i >= 0; i -= 8) 266 for (i = 24; i >= 0; i -= 8)
278 if (((u >> (i & 16)) & 8) && 267 if (((u >> (i & 16)) & 8) &&
279 ((u >> i) & 0x20) && 268 ((u >> i) & 0x20) &&
@@ -286,7 +275,7 @@ static void __devinit via_cable_detect(struct via82cxxx_dev *vdev, u32 u)
286 } 275 }
287 break; 276 break;
288 277
289 case VIA_UDMA_100: 278 case ATA_UDMA5:
290 for (i = 24; i >= 0; i -= 8) 279 for (i = 24; i >= 0; i -= 8)
291 if (((u >> i) & 0x10) || 280 if (((u >> i) & 0x10) ||
292 (((u >> i) & 0x20) && 281 (((u >> i) & 0x20) &&
@@ -298,7 +287,7 @@ static void __devinit via_cable_detect(struct via82cxxx_dev *vdev, u32 u)
298 } 287 }
299 break; 288 break;
300 289
301 case VIA_UDMA_133: 290 case ATA_UDMA6:
302 for (i = 24; i >= 0; i -= 8) 291 for (i = 24; i >= 0; i -= 8)
303 if (((u >> i) & 0x10) || 292 if (((u >> i) & 0x10) ||
304 (((u >> i) & 0x20) && 293 (((u >> i) & 0x20) &&
@@ -353,7 +342,7 @@ static unsigned int __devinit init_chipset_via82cxxx(struct pci_dev *dev, const
353 342
354 via_cable_detect(vdev, u); 343 via_cable_detect(vdev, u);
355 344
356 if ((via_config->flags & VIA_UDMA) == VIA_UDMA_66) { 345 if (via_config->udma_mask == ATA_UDMA4) {
357 /* Enable Clk66 */ 346 /* Enable Clk66 */
358 pci_write_config_dword(dev, VIA_UDMA_TIMING, u|0x80008); 347 pci_write_config_dword(dev, VIA_UDMA_TIMING, u|0x80008);
359 } else if (via_config->flags & VIA_BAD_CLK66) { 348 } else if (via_config->flags & VIA_BAD_CLK66) {
@@ -416,16 +405,54 @@ static unsigned int __devinit init_chipset_via82cxxx(struct pci_dev *dev, const
416 */ 405 */
417 406
418 pci_read_config_byte(isa, PCI_REVISION_ID, &t); 407 pci_read_config_byte(isa, PCI_REVISION_ID, &t);
419 printk(KERN_INFO "VP_IDE: VIA %s (rev %02x) IDE %s " 408 printk(KERN_INFO "VP_IDE: VIA %s (rev %02x) IDE %sDMA%s "
420 "controller on pci%s\n", 409 "controller on pci%s\n",
421 via_config->name, t, 410 via_config->name, t,
422 via_dma[via_config->flags & VIA_UDMA], 411 via_config->udma_mask ? "U" : "MW",
412 via_dma[via_config->udma_mask ?
413 (fls(via_config->udma_mask) - 1) : 0],
423 pci_name(dev)); 414 pci_name(dev));
424 415
425 pci_dev_put(isa); 416 pci_dev_put(isa);
426 return 0; 417 return 0;
427} 418}
428 419
420/*
421 * Cable special cases
422 */
423
424static struct dmi_system_id cable_dmi_table[] = {
425 {
426 .ident = "Acer Ferrari 3400",
427 .matches = {
428 DMI_MATCH(DMI_BOARD_VENDOR, "Acer,Inc."),
429 DMI_MATCH(DMI_BOARD_NAME, "Ferrari 3400"),
430 },
431 },
432 { }
433};
434
435static int via_cable_override(void)
436{
437 /* Systems by DMI */
438 if (dmi_check_system(cable_dmi_table))
439 return 1;
440 return 0;
441}
442
443static u8 __devinit via82cxxx_cable_detect(ide_hwif_t *hwif)
444{
445 struct via82cxxx_dev *vdev = pci_get_drvdata(hwif->pci_dev);
446
447 if (via_cable_override())
448 return ATA_CBL_PATA40_SHORT;
449
450 if ((vdev->via_80w >> hwif->channel) & 1)
451 return ATA_CBL_PATA80;
452 else
453 return ATA_CBL_PATA40;
454}
455
429static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif) 456static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif)
430{ 457{
431 struct via82cxxx_dev *vdev = pci_get_drvdata(hwif->pci_dev); 458 struct via82cxxx_dev *vdev = pci_get_drvdata(hwif->pci_dev);
@@ -454,12 +481,14 @@ static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif)
454 return; 481 return;
455 482
456 hwif->atapi_dma = 1; 483 hwif->atapi_dma = 1;
457 hwif->ultra_mask = 0x7f; 484
485 hwif->ultra_mask = vdev->via_config->udma_mask;
458 hwif->mwdma_mask = 0x07; 486 hwif->mwdma_mask = 0x07;
459 hwif->swdma_mask = 0x07; 487 hwif->swdma_mask = 0x07;
460 488
461 if (!hwif->udma_four) 489 if (hwif->cbl != ATA_CBL_PATA40_SHORT)
462 hwif->udma_four = (vdev->via_80w >> hwif->channel) & 1; 490 hwif->cbl = via82cxxx_cable_detect(hwif);
491
463 hwif->ide_dma_check = &via82cxxx_ide_dma_check; 492 hwif->ide_dma_check = &via82cxxx_ide_dma_check;
464 if (!noautodma) 493 if (!noautodma)
465 hwif->autodma = 1; 494 hwif->autodma = 1;
diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c
index 45fc36f0f219..e46f47206542 100644
--- a/drivers/ide/ppc/pmac.c
+++ b/drivers/ide/ppc/pmac.c
@@ -942,8 +942,8 @@ pmac_ide_tune_chipset (ide_drive_t *drive, byte speed)
942 return 1; 942 return 1;
943 case XFER_UDMA_4: 943 case XFER_UDMA_4:
944 case XFER_UDMA_3: 944 case XFER_UDMA_3:
945 if (HWIF(drive)->udma_four == 0) 945 if (drive->hwif->cbl != ATA_CBL_PATA80)
946 return 1; 946 return 1;
947 case XFER_UDMA_2: 947 case XFER_UDMA_2:
948 case XFER_UDMA_1: 948 case XFER_UDMA_1:
949 case XFER_UDMA_0: 949 case XFER_UDMA_0:
@@ -1244,7 +1244,7 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
1244 hwif->chipset = ide_pmac; 1244 hwif->chipset = ide_pmac;
1245 hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET] || pmif->mediabay; 1245 hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET] || pmif->mediabay;
1246 hwif->hold = pmif->mediabay; 1246 hwif->hold = pmif->mediabay;
1247 hwif->udma_four = pmif->cable_80; 1247 hwif->cbl = pmif->cable_80 ? ATA_CBL_PATA80 : ATA_CBL_PATA40;
1248 hwif->drives[0].unmask = 1; 1248 hwif->drives[0].unmask = 1;
1249 hwif->drives[1].unmask = 1; 1249 hwif->drives[1].unmask = 1;
1250 hwif->tuneproc = pmac_ide_tuneproc; 1250 hwif->tuneproc = pmac_ide_tuneproc;
@@ -1821,28 +1821,11 @@ pmac_ide_dma_check(ide_drive_t *drive)
1821 enable = 0; 1821 enable = 0;
1822 1822
1823 if (enable) { 1823 if (enable) {
1824 short mode; 1824 u8 mode = ide_max_dma_mode(drive);
1825 1825
1826 map = XFER_MWDMA; 1826 if (mode >= XFER_UDMA_0)
1827 if (pmif->kind == controller_kl_ata4
1828 || pmif->kind == controller_un_ata6
1829 || pmif->kind == controller_k2_ata6
1830 || pmif->kind == controller_sh_ata6) {
1831 map |= XFER_UDMA;
1832 if (pmif->cable_80) {
1833 map |= XFER_UDMA_66;
1834 if (pmif->kind == controller_un_ata6 ||
1835 pmif->kind == controller_k2_ata6 ||
1836 pmif->kind == controller_sh_ata6)
1837 map |= XFER_UDMA_100;
1838 if (pmif->kind == controller_sh_ata6)
1839 map |= XFER_UDMA_133;
1840 }
1841 }
1842 mode = ide_find_best_mode(drive, map);
1843 if (mode & XFER_UDMA)
1844 drive->using_dma = pmac_ide_udma_enable(drive, mode); 1827 drive->using_dma = pmac_ide_udma_enable(drive, mode);
1845 else if (mode & XFER_MWDMA) 1828 else if (mode >= XFER_MW_DMA_0)
1846 drive->using_dma = pmac_ide_mdma_enable(drive, mode); 1829 drive->using_dma = pmac_ide_mdma_enable(drive, mode);
1847 hwif->OUTB(0, IDE_CONTROL_REG); 1830 hwif->OUTB(0, IDE_CONTROL_REG);
1848 /* Apply settings to controller */ 1831 /* Apply settings to controller */
@@ -2004,20 +1987,19 @@ static void pmac_ide_dma_host_on(ide_drive_t *drive)
2004{ 1987{
2005} 1988}
2006 1989
2007static int 1990static void
2008pmac_ide_dma_lostirq (ide_drive_t *drive) 1991pmac_ide_dma_lost_irq (ide_drive_t *drive)
2009{ 1992{
2010 pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data; 1993 pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data;
2011 volatile struct dbdma_regs __iomem *dma; 1994 volatile struct dbdma_regs __iomem *dma;
2012 unsigned long status; 1995 unsigned long status;
2013 1996
2014 if (pmif == NULL) 1997 if (pmif == NULL)
2015 return 0; 1998 return;
2016 dma = pmif->dma_regs; 1999 dma = pmif->dma_regs;
2017 2000
2018 status = readl(&dma->status); 2001 status = readl(&dma->status);
2019 printk(KERN_ERR "ide-pmac lost interrupt, dma status: %lx\n", status); 2002 printk(KERN_ERR "ide-pmac lost interrupt, dma status: %lx\n", status);
2020 return 0;
2021} 2003}
2022 2004
2023/* 2005/*
@@ -2057,8 +2039,8 @@ pmac_ide_setup_dma(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
2057 hwif->ide_dma_test_irq = &pmac_ide_dma_test_irq; 2039 hwif->ide_dma_test_irq = &pmac_ide_dma_test_irq;
2058 hwif->dma_host_off = &pmac_ide_dma_host_off; 2040 hwif->dma_host_off = &pmac_ide_dma_host_off;
2059 hwif->dma_host_on = &pmac_ide_dma_host_on; 2041 hwif->dma_host_on = &pmac_ide_dma_host_on;
2060 hwif->ide_dma_timeout = &__ide_dma_timeout; 2042 hwif->dma_timeout = &ide_dma_timeout;
2061 hwif->ide_dma_lostirq = &pmac_ide_dma_lostirq; 2043 hwif->dma_lost_irq = &pmac_ide_dma_lost_irq;
2062 2044
2063 hwif->atapi_dma = 1; 2045 hwif->atapi_dma = 1;
2064 switch(pmif->kind) { 2046 switch(pmif->kind) {
diff --git a/drivers/ieee1394/dv1394.c b/drivers/ieee1394/dv1394.c
index 208141377612..65722117ab6e 100644
--- a/drivers/ieee1394/dv1394.c
+++ b/drivers/ieee1394/dv1394.c
@@ -2280,7 +2280,7 @@ static void dv1394_remove_host(struct hpsb_host *host)
2280 } while (video); 2280 } while (video);
2281 2281
2282 if (found_ohci_card) 2282 if (found_ohci_card)
2283 class_device_destroy(hpsb_protocol_class, MKDEV(IEEE1394_MAJOR, 2283 device_destroy(hpsb_protocol_class, MKDEV(IEEE1394_MAJOR,
2284 IEEE1394_MINOR_BLOCK_DV1394 * 16 + (host->id << 2))); 2284 IEEE1394_MINOR_BLOCK_DV1394 * 16 + (host->id << 2)));
2285} 2285}
2286 2286
@@ -2295,9 +2295,9 @@ static void dv1394_add_host(struct hpsb_host *host)
2295 2295
2296 ohci = (struct ti_ohci *)host->hostdata; 2296 ohci = (struct ti_ohci *)host->hostdata;
2297 2297
2298 class_device_create(hpsb_protocol_class, NULL, MKDEV( 2298 device_create(hpsb_protocol_class, NULL, MKDEV(
2299 IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_DV1394 * 16 + (id<<2)), 2299 IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_DV1394 * 16 + (id<<2)),
2300 NULL, "dv1394-%d", id); 2300 "dv1394-%d", id);
2301 2301
2302 dv1394_init(ohci, DV1394_NTSC, MODE_RECEIVE); 2302 dv1394_init(ohci, DV1394_NTSC, MODE_RECEIVE);
2303 dv1394_init(ohci, DV1394_NTSC, MODE_TRANSMIT); 2303 dv1394_init(ohci, DV1394_NTSC, MODE_TRANSMIT);
diff --git a/drivers/ieee1394/eth1394.c b/drivers/ieee1394/eth1394.c
index 7c13fb3c167b..93362eed94ed 100644
--- a/drivers/ieee1394/eth1394.c
+++ b/drivers/ieee1394/eth1394.c
@@ -599,9 +599,7 @@ static void ether1394_add_host(struct hpsb_host *host)
599 } 599 }
600 600
601 SET_MODULE_OWNER(dev); 601 SET_MODULE_OWNER(dev);
602 602 SET_NETDEV_DEV(dev, &host->device);
603 /* This used to be &host->device in Linux 2.6.20 and before. */
604 SET_NETDEV_DEV(dev, host->device.parent);
605 603
606 priv = netdev_priv(dev); 604 priv = netdev_priv(dev);
607 INIT_LIST_HEAD(&priv->ip_node_list); 605 INIT_LIST_HEAD(&priv->ip_node_list);
diff --git a/drivers/ieee1394/highlevel.c b/drivers/ieee1394/highlevel.c
index 83a493312751..b6425469b6ee 100644
--- a/drivers/ieee1394/highlevel.c
+++ b/drivers/ieee1394/highlevel.c
@@ -483,37 +483,6 @@ int hpsb_unregister_addrspace(struct hpsb_highlevel *hl, struct hpsb_host *host,
483 return retval; 483 return retval;
484} 484}
485 485
486/**
487 * hpsb_listen_channel - enable receving a certain isochronous channel
488 *
489 * Reception is handled through the @hl's iso_receive op.
490 */
491int hpsb_listen_channel(struct hpsb_highlevel *hl, struct hpsb_host *host,
492 unsigned int channel)
493{
494 if (channel > 63) {
495 HPSB_ERR("%s called with invalid channel", __FUNCTION__);
496 return -EINVAL;
497 }
498 if (host->iso_listen_count[channel]++ == 0)
499 return host->driver->devctl(host, ISO_LISTEN_CHANNEL, channel);
500 return 0;
501}
502
503/**
504 * hpsb_unlisten_channel - disable receving a certain isochronous channel
505 */
506void hpsb_unlisten_channel(struct hpsb_highlevel *hl, struct hpsb_host *host,
507 unsigned int channel)
508{
509 if (channel > 63) {
510 HPSB_ERR("%s called with invalid channel", __FUNCTION__);
511 return;
512 }
513 if (--host->iso_listen_count[channel] == 0)
514 host->driver->devctl(host, ISO_UNLISTEN_CHANNEL, channel);
515}
516
517static void init_hpsb_highlevel(struct hpsb_host *host) 486static void init_hpsb_highlevel(struct hpsb_host *host)
518{ 487{
519 INIT_LIST_HEAD(&dummy_zero_addr.host_list); 488 INIT_LIST_HEAD(&dummy_zero_addr.host_list);
@@ -570,20 +539,6 @@ void highlevel_host_reset(struct hpsb_host *host)
570 read_unlock_irqrestore(&hl_irqs_lock, flags); 539 read_unlock_irqrestore(&hl_irqs_lock, flags);
571} 540}
572 541
573void highlevel_iso_receive(struct hpsb_host *host, void *data, size_t length)
574{
575 unsigned long flags;
576 struct hpsb_highlevel *hl;
577 int channel = (((quadlet_t *)data)[0] >> 8) & 0x3f;
578
579 read_lock_irqsave(&hl_irqs_lock, flags);
580 list_for_each_entry(hl, &hl_irqs, irq_list) {
581 if (hl->iso_receive)
582 hl->iso_receive(host, channel, data, length);
583 }
584 read_unlock_irqrestore(&hl_irqs_lock, flags);
585}
586
587void highlevel_fcp_request(struct hpsb_host *host, int nodeid, int direction, 542void highlevel_fcp_request(struct hpsb_host *host, int nodeid, int direction,
588 void *data, size_t length) 543 void *data, size_t length)
589{ 544{
diff --git a/drivers/ieee1394/highlevel.h b/drivers/ieee1394/highlevel.h
index 63474f7ee69d..eb9fe321e09a 100644
--- a/drivers/ieee1394/highlevel.h
+++ b/drivers/ieee1394/highlevel.h
@@ -26,9 +26,7 @@ struct hpsb_address_serve {
26struct hpsb_highlevel { 26struct hpsb_highlevel {
27 const char *name; 27 const char *name;
28 28
29 /* Any of the following pointers can legally be NULL, except for 29 /* Any of the following pointers can legally be NULL. */
30 * iso_receive which can only be NULL when you don't request
31 * channels. */
32 30
33 /* New host initialized. Will also be called during 31 /* New host initialized. Will also be called during
34 * hpsb_register_highlevel for all hosts already installed. */ 32 * hpsb_register_highlevel for all hosts already installed. */
@@ -43,13 +41,6 @@ struct hpsb_highlevel {
43 * You can not expect to be able to do stock hpsb_reads. */ 41 * You can not expect to be able to do stock hpsb_reads. */
44 void (*host_reset)(struct hpsb_host *host); 42 void (*host_reset)(struct hpsb_host *host);
45 43
46 /* An isochronous packet was received. Channel contains the channel
47 * number for your convenience, it is also contained in the included
48 * packet header (first quadlet, CRCs are missing). You may get called
49 * for channel/host combinations you did not request. */
50 void (*iso_receive)(struct hpsb_host *host, int channel,
51 quadlet_t *data, size_t length);
52
53 /* A write request was received on either the FCP_COMMAND (direction = 44 /* A write request was received on either the FCP_COMMAND (direction =
54 * 0) or the FCP_RESPONSE (direction = 1) register. The cts arg 45 * 0) or the FCP_RESPONSE (direction = 1) register. The cts arg
55 * contains the cts field (first byte of data). */ 46 * contains the cts field (first byte of data). */
@@ -109,7 +100,6 @@ int highlevel_lock(struct hpsb_host *host, int nodeid, quadlet_t *store,
109int highlevel_lock64(struct hpsb_host *host, int nodeid, octlet_t *store, 100int highlevel_lock64(struct hpsb_host *host, int nodeid, octlet_t *store,
110 u64 addr, octlet_t data, octlet_t arg, int ext_tcode, 101 u64 addr, octlet_t data, octlet_t arg, int ext_tcode,
111 u16 flags); 102 u16 flags);
112void highlevel_iso_receive(struct hpsb_host *host, void *data, size_t length);
113void highlevel_fcp_request(struct hpsb_host *host, int nodeid, int direction, 103void highlevel_fcp_request(struct hpsb_host *host, int nodeid, int direction,
114 void *data, size_t length); 104 void *data, size_t length);
115 105
@@ -125,10 +115,6 @@ int hpsb_register_addrspace(struct hpsb_highlevel *hl, struct hpsb_host *host,
125 struct hpsb_address_ops *ops, u64 start, u64 end); 115 struct hpsb_address_ops *ops, u64 start, u64 end);
126int hpsb_unregister_addrspace(struct hpsb_highlevel *hl, struct hpsb_host *host, 116int hpsb_unregister_addrspace(struct hpsb_highlevel *hl, struct hpsb_host *host,
127 u64 start); 117 u64 start);
128int hpsb_listen_channel(struct hpsb_highlevel *hl, struct hpsb_host *host,
129 unsigned int channel);
130void hpsb_unlisten_channel(struct hpsb_highlevel *hl, struct hpsb_host *host,
131 unsigned int channel);
132 118
133void *hpsb_get_hostinfo(struct hpsb_highlevel *hl, struct hpsb_host *host); 119void *hpsb_get_hostinfo(struct hpsb_highlevel *hl, struct hpsb_host *host);
134void *hpsb_create_hostinfo(struct hpsb_highlevel *hl, struct hpsb_host *host, 120void *hpsb_create_hostinfo(struct hpsb_highlevel *hl, struct hpsb_host *host,
diff --git a/drivers/ieee1394/hosts.c b/drivers/ieee1394/hosts.c
index bd0755c789c5..8dd09d850419 100644
--- a/drivers/ieee1394/hosts.c
+++ b/drivers/ieee1394/hosts.c
@@ -154,15 +154,16 @@ struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra,
154 154
155 memcpy(&h->device, &nodemgr_dev_template_host, sizeof(h->device)); 155 memcpy(&h->device, &nodemgr_dev_template_host, sizeof(h->device));
156 h->device.parent = dev; 156 h->device.parent = dev;
157 set_dev_node(&h->device, dev_to_node(dev));
157 snprintf(h->device.bus_id, BUS_ID_SIZE, "fw-host%d", h->id); 158 snprintf(h->device.bus_id, BUS_ID_SIZE, "fw-host%d", h->id);
158 159
159 h->class_dev.dev = &h->device; 160 h->host_dev.parent = &h->device;
160 h->class_dev.class = &hpsb_host_class; 161 h->host_dev.class = &hpsb_host_class;
161 snprintf(h->class_dev.class_id, BUS_ID_SIZE, "fw-host%d", h->id); 162 snprintf(h->host_dev.bus_id, BUS_ID_SIZE, "fw-host%d", h->id);
162 163
163 if (device_register(&h->device)) 164 if (device_register(&h->device))
164 goto fail; 165 goto fail;
165 if (class_device_register(&h->class_dev)) { 166 if (device_register(&h->host_dev)) {
166 device_unregister(&h->device); 167 device_unregister(&h->device);
167 goto fail; 168 goto fail;
168 } 169 }
@@ -202,7 +203,7 @@ void hpsb_remove_host(struct hpsb_host *host)
202 host->driver = &dummy_driver; 203 host->driver = &dummy_driver;
203 highlevel_remove_host(host); 204 highlevel_remove_host(host);
204 205
205 class_device_unregister(&host->class_dev); 206 device_unregister(&host->host_dev);
206 device_unregister(&host->device); 207 device_unregister(&host->device);
207} 208}
208 209
diff --git a/drivers/ieee1394/hosts.h b/drivers/ieee1394/hosts.h
index feb55d032294..e4e8aeb4d778 100644
--- a/drivers/ieee1394/hosts.h
+++ b/drivers/ieee1394/hosts.h
@@ -28,8 +28,6 @@ struct hpsb_host {
28 struct timer_list timeout; 28 struct timer_list timeout;
29 unsigned long timeout_interval; 29 unsigned long timeout_interval;
30 30
31 unsigned char iso_listen_count[64];
32
33 int node_count; /* number of identified nodes on this bus */ 31 int node_count; /* number of identified nodes on this bus */
34 int selfid_count; /* total number of SelfIDs received */ 32 int selfid_count; /* total number of SelfIDs received */
35 int nodes_active; /* number of nodes with active link layer */ 33 int nodes_active; /* number of nodes with active link layer */
@@ -57,7 +55,7 @@ struct hpsb_host {
57 struct hpsb_host_driver *driver; 55 struct hpsb_host_driver *driver;
58 struct pci_dev *pdev; 56 struct pci_dev *pdev;
59 struct device device; 57 struct device device;
60 struct class_device class_dev; 58 struct device host_dev;
61 59
62 struct delayed_work delayed_reset; 60 struct delayed_work delayed_reset;
63 unsigned config_roms:31; 61 unsigned config_roms:31;
@@ -99,12 +97,6 @@ enum devctl_cmd {
99 /* Cancel all outstanding async requests without resetting the bus. 97 /* Cancel all outstanding async requests without resetting the bus.
100 * Return void. */ 98 * Return void. */
101 CANCEL_REQUESTS, 99 CANCEL_REQUESTS,
102
103 /* Start or stop receiving isochronous channel in arg. Return void.
104 * This acts as an optimization hint, hosts are not required not to
105 * listen on unrequested channels. */
106 ISO_LISTEN_CHANNEL,
107 ISO_UNLISTEN_CHANNEL
108}; 100};
109 101
110enum isoctl_cmd { 102enum isoctl_cmd {
diff --git a/drivers/ieee1394/ieee1394_core.c b/drivers/ieee1394/ieee1394_core.c
index 8f71b6a06aa0..0fc8c6e559e4 100644
--- a/drivers/ieee1394/ieee1394_core.c
+++ b/drivers/ieee1394/ieee1394_core.c
@@ -1028,11 +1028,6 @@ void hpsb_packet_received(struct hpsb_host *host, quadlet_t *data, size_t size,
1028 handle_incoming_packet(host, tcode, data, size, write_acked); 1028 handle_incoming_packet(host, tcode, data, size, write_acked);
1029 break; 1029 break;
1030 1030
1031
1032 case TCODE_ISO_DATA:
1033 highlevel_iso_receive(host, data, size);
1034 break;
1035
1036 case TCODE_CYCLE_START: 1031 case TCODE_CYCLE_START:
1037 /* simply ignore this packet if it is passed on */ 1032 /* simply ignore this packet if it is passed on */
1038 break; 1033 break;
@@ -1316,7 +1311,6 @@ EXPORT_SYMBOL(hpsb_make_streampacket);
1316EXPORT_SYMBOL(hpsb_make_lockpacket); 1311EXPORT_SYMBOL(hpsb_make_lockpacket);
1317EXPORT_SYMBOL(hpsb_make_lock64packet); 1312EXPORT_SYMBOL(hpsb_make_lock64packet);
1318EXPORT_SYMBOL(hpsb_make_phypacket); 1313EXPORT_SYMBOL(hpsb_make_phypacket);
1319EXPORT_SYMBOL(hpsb_make_isopacket);
1320EXPORT_SYMBOL(hpsb_read); 1314EXPORT_SYMBOL(hpsb_read);
1321EXPORT_SYMBOL(hpsb_write); 1315EXPORT_SYMBOL(hpsb_write);
1322EXPORT_SYMBOL(hpsb_packet_success); 1316EXPORT_SYMBOL(hpsb_packet_success);
@@ -1327,8 +1321,6 @@ EXPORT_SYMBOL(hpsb_unregister_highlevel);
1327EXPORT_SYMBOL(hpsb_register_addrspace); 1321EXPORT_SYMBOL(hpsb_register_addrspace);
1328EXPORT_SYMBOL(hpsb_unregister_addrspace); 1322EXPORT_SYMBOL(hpsb_unregister_addrspace);
1329EXPORT_SYMBOL(hpsb_allocate_and_register_addrspace); 1323EXPORT_SYMBOL(hpsb_allocate_and_register_addrspace);
1330EXPORT_SYMBOL(hpsb_listen_channel);
1331EXPORT_SYMBOL(hpsb_unlisten_channel);
1332EXPORT_SYMBOL(hpsb_get_hostinfo); 1324EXPORT_SYMBOL(hpsb_get_hostinfo);
1333EXPORT_SYMBOL(hpsb_create_hostinfo); 1325EXPORT_SYMBOL(hpsb_create_hostinfo);
1334EXPORT_SYMBOL(hpsb_destroy_hostinfo); 1326EXPORT_SYMBOL(hpsb_destroy_hostinfo);
diff --git a/drivers/ieee1394/ieee1394_core.h b/drivers/ieee1394/ieee1394_core.h
index ad526523d0ef..21d50f73a210 100644
--- a/drivers/ieee1394/ieee1394_core.h
+++ b/drivers/ieee1394/ieee1394_core.h
@@ -24,9 +24,8 @@ struct hpsb_packet {
24 24
25 nodeid_t node_id; 25 nodeid_t node_id;
26 26
27 /* Async and Iso types should be clear, raw means send-as-is, do not 27 /* hpsb_raw = send as-is, do not CRC (but still byte-swap it) */
28 * CRC! Byte swapping shall still be done in this case. */ 28 enum { hpsb_async, hpsb_raw } __attribute__((packed)) type;
29 enum { hpsb_async, hpsb_iso, hpsb_raw } __attribute__((packed)) type;
30 29
31 /* Okay, this is core internal and a no care for hosts. 30 /* Okay, this is core internal and a no care for hosts.
32 * queued = queued for sending 31 * queued = queued for sending
@@ -37,7 +36,7 @@ struct hpsb_packet {
37 hpsb_unused, hpsb_queued, hpsb_pending, hpsb_complete 36 hpsb_unused, hpsb_queued, hpsb_pending, hpsb_complete
38 } __attribute__((packed)) state; 37 } __attribute__((packed)) state;
39 38
40 /* These are core internal. */ 39 /* These are core-internal. */
41 signed char tlabel; 40 signed char tlabel;
42 signed char ack_code; 41 signed char ack_code;
43 unsigned char tcode; 42 unsigned char tcode;
@@ -62,11 +61,15 @@ struct hpsb_packet {
62 /* Store jiffies for implementing bus timeouts. */ 61 /* Store jiffies for implementing bus timeouts. */
63 unsigned long sendtime; 62 unsigned long sendtime;
64 63
65 /* Sizes are in bytes. *data can be DMA-mapped. */ 64 /* Core-internal. */
66 size_t allocated_data_size; /* as allocated */ 65 size_t allocated_data_size; /* as allocated */
66
67 /* Sizes are in bytes. To be set by caller of hpsb_alloc_packet. */
67 size_t data_size; /* as filled in */ 68 size_t data_size; /* as filled in */
68 size_t header_size; /* as filled in, not counting the CRC */ 69 size_t header_size; /* as filled in, not counting the CRC */
69 quadlet_t *data; 70
71 /* Buffers */
72 quadlet_t *data; /* can be DMA-mapped */
70 quadlet_t header[5]; 73 quadlet_t header[5];
71 quadlet_t embedded_data[0]; /* keep as last member */ 74 quadlet_t embedded_data[0]; /* keep as last member */
72}; 75};
diff --git a/drivers/ieee1394/ieee1394_transactions.c b/drivers/ieee1394/ieee1394_transactions.c
index 40078ce930c8..c39c70a8aa9f 100644
--- a/drivers/ieee1394/ieee1394_transactions.c
+++ b/drivers/ieee1394/ieee1394_transactions.c
@@ -89,18 +89,6 @@ static void fill_async_lock(struct hpsb_packet *packet, u64 addr, int extcode,
89 packet->expect_response = 1; 89 packet->expect_response = 1;
90} 90}
91 91
92static void fill_iso_packet(struct hpsb_packet *packet, int length, int channel,
93 int tag, int sync)
94{
95 packet->header[0] = (length << 16) | (tag << 14) | (channel << 8)
96 | (TCODE_ISO_DATA << 4) | sync;
97
98 packet->header_size = 4;
99 packet->data_size = length;
100 packet->type = hpsb_iso;
101 packet->tcode = TCODE_ISO_DATA;
102}
103
104static void fill_phy_packet(struct hpsb_packet *packet, quadlet_t data) 92static void fill_phy_packet(struct hpsb_packet *packet, quadlet_t data)
105{ 93{
106 packet->header[0] = data; 94 packet->header[0] = data;
@@ -491,24 +479,6 @@ struct hpsb_packet *hpsb_make_phypacket(struct hpsb_host *host, quadlet_t data)
491 return p; 479 return p;
492} 480}
493 481
494struct hpsb_packet *hpsb_make_isopacket(struct hpsb_host *host,
495 int length, int channel,
496 int tag, int sync)
497{
498 struct hpsb_packet *p;
499
500 p = hpsb_alloc_packet(length);
501 if (!p)
502 return NULL;
503
504 p->host = host;
505 fill_iso_packet(p, length, channel, tag, sync);
506
507 p->generation = get_hpsb_generation(host);
508
509 return p;
510}
511
512/* 482/*
513 * FIXME - these functions should probably read from / write to user space to 483 * FIXME - these functions should probably read from / write to user space to
514 * avoid in kernel buffers for user space callers 484 * avoid in kernel buffers for user space callers
diff --git a/drivers/ieee1394/ieee1394_transactions.h b/drivers/ieee1394/ieee1394_transactions.h
index 86b8ee692ea7..d2d5bc3546d7 100644
--- a/drivers/ieee1394/ieee1394_transactions.h
+++ b/drivers/ieee1394/ieee1394_transactions.h
@@ -19,8 +19,6 @@ struct hpsb_packet *hpsb_make_lock64packet(struct hpsb_host *host,
19 nodeid_t node, u64 addr, int extcode, 19 nodeid_t node, u64 addr, int extcode,
20 octlet_t *data, octlet_t arg); 20 octlet_t *data, octlet_t arg);
21struct hpsb_packet *hpsb_make_phypacket(struct hpsb_host *host, quadlet_t data); 21struct hpsb_packet *hpsb_make_phypacket(struct hpsb_host *host, quadlet_t data);
22struct hpsb_packet *hpsb_make_isopacket(struct hpsb_host *host, int length,
23 int channel, int tag, int sync);
24struct hpsb_packet *hpsb_make_writepacket(struct hpsb_host *host, 22struct hpsb_packet *hpsb_make_writepacket(struct hpsb_host *host,
25 nodeid_t node, u64 addr, 23 nodeid_t node, u64 addr,
26 quadlet_t *buffer, size_t length); 24 quadlet_t *buffer, size_t length);
diff --git a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c
index 81b3864d2ba7..c4d3d4131f01 100644
--- a/drivers/ieee1394/nodemgr.c
+++ b/drivers/ieee1394/nodemgr.c
@@ -19,6 +19,7 @@
19#include <linux/mutex.h> 19#include <linux/mutex.h>
20#include <linux/freezer.h> 20#include <linux/freezer.h>
21#include <asm/atomic.h> 21#include <asm/atomic.h>
22#include <asm/semaphore.h>
22 23
23#include "csr.h" 24#include "csr.h"
24#include "highlevel.h" 25#include "highlevel.h"
@@ -145,8 +146,6 @@ static struct csr1212_bus_ops nodemgr_csr_ops = {
145 * but now we are much simpler because of the LDM. 146 * but now we are much simpler because of the LDM.
146 */ 147 */
147 148
148static DEFINE_MUTEX(nodemgr_serialize);
149
150struct host_info { 149struct host_info {
151 struct hpsb_host *host; 150 struct hpsb_host *host;
152 struct list_head list; 151 struct list_head list;
@@ -154,7 +153,7 @@ struct host_info {
154}; 153};
155 154
156static int nodemgr_bus_match(struct device * dev, struct device_driver * drv); 155static int nodemgr_bus_match(struct device * dev, struct device_driver * drv);
157static int nodemgr_uevent(struct class_device *cdev, char **envp, int num_envp, 156static int nodemgr_uevent(struct device *dev, char **envp, int num_envp,
158 char *buffer, int buffer_size); 157 char *buffer, int buffer_size);
159static void nodemgr_resume_ne(struct node_entry *ne); 158static void nodemgr_resume_ne(struct node_entry *ne);
160static void nodemgr_remove_ne(struct node_entry *ne); 159static void nodemgr_remove_ne(struct node_entry *ne);
@@ -165,37 +164,38 @@ struct bus_type ieee1394_bus_type = {
165 .match = nodemgr_bus_match, 164 .match = nodemgr_bus_match,
166}; 165};
167 166
168static void host_cls_release(struct class_device *class_dev) 167static void host_cls_release(struct device *dev)
169{ 168{
170 put_device(&container_of((class_dev), struct hpsb_host, class_dev)->device); 169 put_device(&container_of((dev), struct hpsb_host, host_dev)->device);
171} 170}
172 171
173struct class hpsb_host_class = { 172struct class hpsb_host_class = {
174 .name = "ieee1394_host", 173 .name = "ieee1394_host",
175 .release = host_cls_release, 174 .dev_release = host_cls_release,
176}; 175};
177 176
178static void ne_cls_release(struct class_device *class_dev) 177static void ne_cls_release(struct device *dev)
179{ 178{
180 put_device(&container_of((class_dev), struct node_entry, class_dev)->device); 179 put_device(&container_of((dev), struct node_entry, node_dev)->device);
181} 180}
182 181
183static struct class nodemgr_ne_class = { 182static struct class nodemgr_ne_class = {
184 .name = "ieee1394_node", 183 .name = "ieee1394_node",
185 .release = ne_cls_release, 184 .dev_release = ne_cls_release,
186}; 185};
187 186
188static void ud_cls_release(struct class_device *class_dev) 187static void ud_cls_release(struct device *dev)
189{ 188{
190 put_device(&container_of((class_dev), struct unit_directory, class_dev)->device); 189 put_device(&container_of((dev), struct unit_directory, unit_dev)->device);
191} 190}
192 191
193/* The name here is only so that unit directory hotplug works with old 192/* The name here is only so that unit directory hotplug works with old
194 * style hotplug, which only ever did unit directories anyway. */ 193 * style hotplug, which only ever did unit directories anyway.
194 */
195static struct class nodemgr_ud_class = { 195static struct class nodemgr_ud_class = {
196 .name = "ieee1394", 196 .name = "ieee1394",
197 .release = ud_cls_release, 197 .dev_release = ud_cls_release,
198 .uevent = nodemgr_uevent, 198 .dev_uevent = nodemgr_uevent,
199}; 199};
200 200
201static struct hpsb_highlevel nodemgr_highlevel; 201static struct hpsb_highlevel nodemgr_highlevel;
@@ -730,11 +730,11 @@ static DEFINE_MUTEX(nodemgr_serialize_remove_uds);
730 730
731static void nodemgr_remove_uds(struct node_entry *ne) 731static void nodemgr_remove_uds(struct node_entry *ne)
732{ 732{
733 struct class_device *cdev; 733 struct device *dev;
734 struct unit_directory *tmp, *ud; 734 struct unit_directory *tmp, *ud;
735 735
736 /* Iteration over nodemgr_ud_class.children has to be protected by 736 /* Iteration over nodemgr_ud_class.devices has to be protected by
737 * nodemgr_ud_class.sem, but class_device_unregister() will eventually 737 * nodemgr_ud_class.sem, but device_unregister() will eventually
738 * take nodemgr_ud_class.sem too. Therefore pick out one ud at a time, 738 * take nodemgr_ud_class.sem too. Therefore pick out one ud at a time,
739 * release the semaphore, and then unregister the ud. Since this code 739 * release the semaphore, and then unregister the ud. Since this code
740 * may be called from other contexts besides the knodemgrds, protect the 740 * may be called from other contexts besides the knodemgrds, protect the
@@ -744,9 +744,9 @@ static void nodemgr_remove_uds(struct node_entry *ne)
744 for (;;) { 744 for (;;) {
745 ud = NULL; 745 ud = NULL;
746 down(&nodemgr_ud_class.sem); 746 down(&nodemgr_ud_class.sem);
747 list_for_each_entry(cdev, &nodemgr_ud_class.children, node) { 747 list_for_each_entry(dev, &nodemgr_ud_class.devices, node) {
748 tmp = container_of(cdev, struct unit_directory, 748 tmp = container_of(dev, struct unit_directory,
749 class_dev); 749 unit_dev);
750 if (tmp->ne == ne) { 750 if (tmp->ne == ne) {
751 ud = tmp; 751 ud = tmp;
752 break; 752 break;
@@ -755,7 +755,7 @@ static void nodemgr_remove_uds(struct node_entry *ne)
755 up(&nodemgr_ud_class.sem); 755 up(&nodemgr_ud_class.sem);
756 if (ud == NULL) 756 if (ud == NULL)
757 break; 757 break;
758 class_device_unregister(&ud->class_dev); 758 device_unregister(&ud->unit_dev);
759 device_unregister(&ud->device); 759 device_unregister(&ud->device);
760 } 760 }
761 mutex_unlock(&nodemgr_serialize_remove_uds); 761 mutex_unlock(&nodemgr_serialize_remove_uds);
@@ -772,10 +772,9 @@ static void nodemgr_remove_ne(struct node_entry *ne)
772 772
773 HPSB_DEBUG("Node removed: ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]", 773 HPSB_DEBUG("Node removed: ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]",
774 NODE_BUS_ARGS(ne->host, ne->nodeid), (unsigned long long)ne->guid); 774 NODE_BUS_ARGS(ne->host, ne->nodeid), (unsigned long long)ne->guid);
775
776 nodemgr_remove_uds(ne); 775 nodemgr_remove_uds(ne);
777 776
778 class_device_unregister(&ne->class_dev); 777 device_unregister(&ne->node_dev);
779 device_unregister(dev); 778 device_unregister(dev);
780 779
781 put_device(dev); 780 put_device(dev);
@@ -783,7 +782,9 @@ static void nodemgr_remove_ne(struct node_entry *ne)
783 782
784static int __nodemgr_remove_host_dev(struct device *dev, void *data) 783static int __nodemgr_remove_host_dev(struct device *dev, void *data)
785{ 784{
786 nodemgr_remove_ne(container_of(dev, struct node_entry, device)); 785 if (dev->bus == &ieee1394_bus_type)
786 nodemgr_remove_ne(container_of(dev, struct node_entry,
787 device));
787 return 0; 788 return 0;
788} 789}
789 790
@@ -850,14 +851,14 @@ static struct node_entry *nodemgr_create_node(octlet_t guid, struct csr1212_csr
850 snprintf(ne->device.bus_id, BUS_ID_SIZE, "%016Lx", 851 snprintf(ne->device.bus_id, BUS_ID_SIZE, "%016Lx",
851 (unsigned long long)(ne->guid)); 852 (unsigned long long)(ne->guid));
852 853
853 ne->class_dev.dev = &ne->device; 854 ne->node_dev.parent = &ne->device;
854 ne->class_dev.class = &nodemgr_ne_class; 855 ne->node_dev.class = &nodemgr_ne_class;
855 snprintf(ne->class_dev.class_id, BUS_ID_SIZE, "%016Lx", 856 snprintf(ne->node_dev.bus_id, BUS_ID_SIZE, "%016Lx",
856 (unsigned long long)(ne->guid)); 857 (unsigned long long)(ne->guid));
857 858
858 if (device_register(&ne->device)) 859 if (device_register(&ne->device))
859 goto fail_devreg; 860 goto fail_devreg;
860 if (class_device_register(&ne->class_dev)) 861 if (device_register(&ne->node_dev))
861 goto fail_classdevreg; 862 goto fail_classdevreg;
862 get_device(&ne->device); 863 get_device(&ne->device);
863 864
@@ -885,12 +886,12 @@ fail_alloc:
885 886
886static struct node_entry *find_entry_by_guid(u64 guid) 887static struct node_entry *find_entry_by_guid(u64 guid)
887{ 888{
888 struct class_device *cdev; 889 struct device *dev;
889 struct node_entry *ne, *ret_ne = NULL; 890 struct node_entry *ne, *ret_ne = NULL;
890 891
891 down(&nodemgr_ne_class.sem); 892 down(&nodemgr_ne_class.sem);
892 list_for_each_entry(cdev, &nodemgr_ne_class.children, node) { 893 list_for_each_entry(dev, &nodemgr_ne_class.devices, node) {
893 ne = container_of(cdev, struct node_entry, class_dev); 894 ne = container_of(dev, struct node_entry, node_dev);
894 895
895 if (ne->guid == guid) { 896 if (ne->guid == guid) {
896 ret_ne = ne; 897 ret_ne = ne;
@@ -906,12 +907,12 @@ static struct node_entry *find_entry_by_guid(u64 guid)
906static struct node_entry *find_entry_by_nodeid(struct hpsb_host *host, 907static struct node_entry *find_entry_by_nodeid(struct hpsb_host *host,
907 nodeid_t nodeid) 908 nodeid_t nodeid)
908{ 909{
909 struct class_device *cdev; 910 struct device *dev;
910 struct node_entry *ne, *ret_ne = NULL; 911 struct node_entry *ne, *ret_ne = NULL;
911 912
912 down(&nodemgr_ne_class.sem); 913 down(&nodemgr_ne_class.sem);
913 list_for_each_entry(cdev, &nodemgr_ne_class.children, node) { 914 list_for_each_entry(dev, &nodemgr_ne_class.devices, node) {
914 ne = container_of(cdev, struct node_entry, class_dev); 915 ne = container_of(dev, struct node_entry, node_dev);
915 916
916 if (ne->host == host && ne->nodeid == nodeid) { 917 if (ne->host == host && ne->nodeid == nodeid) {
917 ret_ne = ne; 918 ret_ne = ne;
@@ -935,14 +936,14 @@ static void nodemgr_register_device(struct node_entry *ne,
935 snprintf(ud->device.bus_id, BUS_ID_SIZE, "%s-%u", 936 snprintf(ud->device.bus_id, BUS_ID_SIZE, "%s-%u",
936 ne->device.bus_id, ud->id); 937 ne->device.bus_id, ud->id);
937 938
938 ud->class_dev.dev = &ud->device; 939 ud->unit_dev.parent = &ud->device;
939 ud->class_dev.class = &nodemgr_ud_class; 940 ud->unit_dev.class = &nodemgr_ud_class;
940 snprintf(ud->class_dev.class_id, BUS_ID_SIZE, "%s-%u", 941 snprintf(ud->unit_dev.bus_id, BUS_ID_SIZE, "%s-%u",
941 ne->device.bus_id, ud->id); 942 ne->device.bus_id, ud->id);
942 943
943 if (device_register(&ud->device)) 944 if (device_register(&ud->device))
944 goto fail_devreg; 945 goto fail_devreg;
945 if (class_device_register(&ud->class_dev)) 946 if (device_register(&ud->unit_dev))
946 goto fail_classdevreg; 947 goto fail_classdevreg;
947 get_device(&ud->device); 948 get_device(&ud->device);
948 949
@@ -1159,7 +1160,7 @@ static void nodemgr_process_root_directory(struct host_info *hi, struct node_ent
1159 1160
1160#ifdef CONFIG_HOTPLUG 1161#ifdef CONFIG_HOTPLUG
1161 1162
1162static int nodemgr_uevent(struct class_device *cdev, char **envp, int num_envp, 1163static int nodemgr_uevent(struct device *dev, char **envp, int num_envp,
1163 char *buffer, int buffer_size) 1164 char *buffer, int buffer_size)
1164{ 1165{
1165 struct unit_directory *ud; 1166 struct unit_directory *ud;
@@ -1169,10 +1170,10 @@ static int nodemgr_uevent(struct class_device *cdev, char **envp, int num_envp,
1169 /* ieee1394:venNmoNspNverN */ 1170 /* ieee1394:venNmoNspNverN */
1170 char buf[8 + 1 + 3 + 8 + 2 + 8 + 2 + 8 + 3 + 8 + 1]; 1171 char buf[8 + 1 + 3 + 8 + 2 + 8 + 2 + 8 + 3 + 8 + 1];
1171 1172
1172 if (!cdev) 1173 if (!dev)
1173 return -ENODEV; 1174 return -ENODEV;
1174 1175
1175 ud = container_of(cdev, struct unit_directory, class_dev); 1176 ud = container_of(dev, struct unit_directory, unit_dev);
1176 1177
1177 if (ud->ne->in_limbo || ud->ignore_driver) 1178 if (ud->ne->in_limbo || ud->ignore_driver)
1178 return -ENODEV; 1179 return -ENODEV;
@@ -1207,7 +1208,7 @@ do { \
1207 1208
1208#else 1209#else
1209 1210
1210static int nodemgr_uevent(struct class_device *cdev, char **envp, int num_envp, 1211static int nodemgr_uevent(struct device *dev, char **envp, int num_envp,
1211 char *buffer, int buffer_size) 1212 char *buffer, int buffer_size)
1212{ 1213{
1213 return -ENODEV; 1214 return -ENODEV;
@@ -1378,8 +1379,10 @@ static void nodemgr_node_scan(struct host_info *hi, int generation)
1378 1379
1379static void nodemgr_suspend_ne(struct node_entry *ne) 1380static void nodemgr_suspend_ne(struct node_entry *ne)
1380{ 1381{
1381 struct class_device *cdev; 1382 struct device *dev;
1382 struct unit_directory *ud; 1383 struct unit_directory *ud;
1384 struct device_driver *drv;
1385 int error;
1383 1386
1384 HPSB_DEBUG("Node suspended: ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]", 1387 HPSB_DEBUG("Node suspended: ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]",
1385 NODE_BUS_ARGS(ne->host, ne->nodeid), (unsigned long long)ne->guid); 1388 NODE_BUS_ARGS(ne->host, ne->nodeid), (unsigned long long)ne->guid);
@@ -1388,15 +1391,24 @@ static void nodemgr_suspend_ne(struct node_entry *ne)
1388 WARN_ON(device_create_file(&ne->device, &dev_attr_ne_in_limbo)); 1391 WARN_ON(device_create_file(&ne->device, &dev_attr_ne_in_limbo));
1389 1392
1390 down(&nodemgr_ud_class.sem); 1393 down(&nodemgr_ud_class.sem);
1391 list_for_each_entry(cdev, &nodemgr_ud_class.children, node) { 1394 list_for_each_entry(dev, &nodemgr_ud_class.devices, node) {
1392 ud = container_of(cdev, struct unit_directory, class_dev); 1395 ud = container_of(dev, struct unit_directory, unit_dev);
1393 if (ud->ne != ne) 1396 if (ud->ne != ne)
1394 continue; 1397 continue;
1395 1398
1396 if (ud->device.driver && 1399 drv = get_driver(ud->device.driver);
1397 (!ud->device.driver->suspend || 1400 if (!drv)
1398 ud->device.driver->suspend(&ud->device, PMSG_SUSPEND))) 1401 continue;
1402
1403 error = 1; /* release if suspend is not implemented */
1404 if (drv->suspend) {
1405 down(&ud->device.sem);
1406 error = drv->suspend(&ud->device, PMSG_SUSPEND);
1407 up(&ud->device.sem);
1408 }
1409 if (error)
1399 device_release_driver(&ud->device); 1410 device_release_driver(&ud->device);
1411 put_driver(drv);
1400 } 1412 }
1401 up(&nodemgr_ud_class.sem); 1413 up(&nodemgr_ud_class.sem);
1402} 1414}
@@ -1404,20 +1416,29 @@ static void nodemgr_suspend_ne(struct node_entry *ne)
1404 1416
1405static void nodemgr_resume_ne(struct node_entry *ne) 1417static void nodemgr_resume_ne(struct node_entry *ne)
1406{ 1418{
1407 struct class_device *cdev; 1419 struct device *dev;
1408 struct unit_directory *ud; 1420 struct unit_directory *ud;
1421 struct device_driver *drv;
1409 1422
1410 ne->in_limbo = 0; 1423 ne->in_limbo = 0;
1411 device_remove_file(&ne->device, &dev_attr_ne_in_limbo); 1424 device_remove_file(&ne->device, &dev_attr_ne_in_limbo);
1412 1425
1413 down(&nodemgr_ud_class.sem); 1426 down(&nodemgr_ud_class.sem);
1414 list_for_each_entry(cdev, &nodemgr_ud_class.children, node) { 1427 list_for_each_entry(dev, &nodemgr_ud_class.devices, node) {
1415 ud = container_of(cdev, struct unit_directory, class_dev); 1428 ud = container_of(dev, struct unit_directory, unit_dev);
1416 if (ud->ne != ne) 1429 if (ud->ne != ne)
1417 continue; 1430 continue;
1418 1431
1419 if (ud->device.driver && ud->device.driver->resume) 1432 drv = get_driver(ud->device.driver);
1420 ud->device.driver->resume(&ud->device); 1433 if (!drv)
1434 continue;
1435
1436 if (drv->resume) {
1437 down(&ud->device.sem);
1438 drv->resume(&ud->device);
1439 up(&ud->device.sem);
1440 }
1441 put_driver(drv);
1421 } 1442 }
1422 up(&nodemgr_ud_class.sem); 1443 up(&nodemgr_ud_class.sem);
1423 1444
@@ -1428,23 +1449,32 @@ static void nodemgr_resume_ne(struct node_entry *ne)
1428 1449
1429static void nodemgr_update_pdrv(struct node_entry *ne) 1450static void nodemgr_update_pdrv(struct node_entry *ne)
1430{ 1451{
1452 struct device *dev;
1431 struct unit_directory *ud; 1453 struct unit_directory *ud;
1454 struct device_driver *drv;
1432 struct hpsb_protocol_driver *pdrv; 1455 struct hpsb_protocol_driver *pdrv;
1433 struct class_device *cdev; 1456 int error;
1434 1457
1435 down(&nodemgr_ud_class.sem); 1458 down(&nodemgr_ud_class.sem);
1436 list_for_each_entry(cdev, &nodemgr_ud_class.children, node) { 1459 list_for_each_entry(dev, &nodemgr_ud_class.devices, node) {
1437 ud = container_of(cdev, struct unit_directory, class_dev); 1460 ud = container_of(dev, struct unit_directory, unit_dev);
1438 if (ud->ne != ne) 1461 if (ud->ne != ne)
1439 continue; 1462 continue;
1440 1463
1441 if (ud->device.driver) { 1464 drv = get_driver(ud->device.driver);
1442 pdrv = container_of(ud->device.driver, 1465 if (!drv)
1443 struct hpsb_protocol_driver, 1466 continue;
1444 driver); 1467
1445 if (pdrv->update && pdrv->update(ud)) 1468 error = 0;
1446 device_release_driver(&ud->device); 1469 pdrv = container_of(drv, struct hpsb_protocol_driver, driver);
1470 if (pdrv->update) {
1471 down(&ud->device.sem);
1472 error = pdrv->update(ud);
1473 up(&ud->device.sem);
1447 } 1474 }
1475 if (error)
1476 device_release_driver(&ud->device);
1477 put_driver(drv);
1448 } 1478 }
1449 up(&nodemgr_ud_class.sem); 1479 up(&nodemgr_ud_class.sem);
1450} 1480}
@@ -1509,7 +1539,7 @@ static void nodemgr_probe_ne(struct host_info *hi, struct node_entry *ne, int ge
1509static void nodemgr_node_probe(struct host_info *hi, int generation) 1539static void nodemgr_node_probe(struct host_info *hi, int generation)
1510{ 1540{
1511 struct hpsb_host *host = hi->host; 1541 struct hpsb_host *host = hi->host;
1512 struct class_device *cdev; 1542 struct device *dev;
1513 struct node_entry *ne; 1543 struct node_entry *ne;
1514 1544
1515 /* Do some processing of the nodes we've probed. This pulls them 1545 /* Do some processing of the nodes we've probed. This pulls them
@@ -1522,13 +1552,13 @@ static void nodemgr_node_probe(struct host_info *hi, int generation)
1522 * improvement...) */ 1552 * improvement...) */
1523 1553
1524 down(&nodemgr_ne_class.sem); 1554 down(&nodemgr_ne_class.sem);
1525 list_for_each_entry(cdev, &nodemgr_ne_class.children, node) { 1555 list_for_each_entry(dev, &nodemgr_ne_class.devices, node) {
1526 ne = container_of(cdev, struct node_entry, class_dev); 1556 ne = container_of(dev, struct node_entry, node_dev);
1527 if (!ne->needs_probe) 1557 if (!ne->needs_probe)
1528 nodemgr_probe_ne(hi, ne, generation); 1558 nodemgr_probe_ne(hi, ne, generation);
1529 } 1559 }
1530 list_for_each_entry(cdev, &nodemgr_ne_class.children, node) { 1560 list_for_each_entry(dev, &nodemgr_ne_class.devices, node) {
1531 ne = container_of(cdev, struct node_entry, class_dev); 1561 ne = container_of(dev, struct node_entry, node_dev);
1532 if (ne->needs_probe) 1562 if (ne->needs_probe)
1533 nodemgr_probe_ne(hi, ne, generation); 1563 nodemgr_probe_ne(hi, ne, generation);
1534 } 1564 }
@@ -1686,18 +1716,12 @@ static int nodemgr_host_thread(void *__hi)
1686 if (kthread_should_stop()) 1716 if (kthread_should_stop())
1687 goto exit; 1717 goto exit;
1688 1718
1689 if (mutex_lock_interruptible(&nodemgr_serialize)) {
1690 if (try_to_freeze())
1691 continue;
1692 goto exit;
1693 }
1694
1695 /* Pause for 1/4 second in 1/16 second intervals, 1719 /* Pause for 1/4 second in 1/16 second intervals,
1696 * to make sure things settle down. */ 1720 * to make sure things settle down. */
1697 g = get_hpsb_generation(host); 1721 g = get_hpsb_generation(host);
1698 for (i = 0; i < 4 ; i++) { 1722 for (i = 0; i < 4 ; i++) {
1699 if (msleep_interruptible(63) || kthread_should_stop()) 1723 if (msleep_interruptible(63) || kthread_should_stop())
1700 goto unlock_exit; 1724 goto exit;
1701 1725
1702 /* Now get the generation in which the node ID's we collect 1726 /* Now get the generation in which the node ID's we collect
1703 * are valid. During the bus scan we will use this generation 1727 * are valid. During the bus scan we will use this generation
@@ -1715,7 +1739,6 @@ static int nodemgr_host_thread(void *__hi)
1715 if (!nodemgr_check_irm_capability(host, reset_cycles) || 1739 if (!nodemgr_check_irm_capability(host, reset_cycles) ||
1716 !nodemgr_do_irm_duties(host, reset_cycles)) { 1740 !nodemgr_do_irm_duties(host, reset_cycles)) {
1717 reset_cycles++; 1741 reset_cycles++;
1718 mutex_unlock(&nodemgr_serialize);
1719 continue; 1742 continue;
1720 } 1743 }
1721 reset_cycles = 0; 1744 reset_cycles = 0;
@@ -1732,11 +1755,7 @@ static int nodemgr_host_thread(void *__hi)
1732 1755
1733 /* Update some of our sysfs symlinks */ 1756 /* Update some of our sysfs symlinks */
1734 nodemgr_update_host_dev_links(host); 1757 nodemgr_update_host_dev_links(host);
1735
1736 mutex_unlock(&nodemgr_serialize);
1737 } 1758 }
1738unlock_exit:
1739 mutex_unlock(&nodemgr_serialize);
1740exit: 1759exit:
1741 HPSB_VERBOSE("NodeMgr: Exiting thread"); 1760 HPSB_VERBOSE("NodeMgr: Exiting thread");
1742 return 0; 1761 return 0;
@@ -1756,13 +1775,13 @@ exit:
1756 */ 1775 */
1757int nodemgr_for_each_host(void *data, int (*cb)(struct hpsb_host *, void *)) 1776int nodemgr_for_each_host(void *data, int (*cb)(struct hpsb_host *, void *))
1758{ 1777{
1759 struct class_device *cdev; 1778 struct device *dev;
1760 struct hpsb_host *host; 1779 struct hpsb_host *host;
1761 int error = 0; 1780 int error = 0;
1762 1781
1763 down(&hpsb_host_class.sem); 1782 down(&hpsb_host_class.sem);
1764 list_for_each_entry(cdev, &hpsb_host_class.children, node) { 1783 list_for_each_entry(dev, &hpsb_host_class.devices, node) {
1765 host = container_of(cdev, struct hpsb_host, class_dev); 1784 host = container_of(dev, struct hpsb_host, host_dev);
1766 1785
1767 if ((error = cb(host, data))) 1786 if ((error = cb(host, data)))
1768 break; 1787 break;
diff --git a/drivers/ieee1394/nodemgr.h b/drivers/ieee1394/nodemgr.h
index 4530b29d941c..919e92e2a955 100644
--- a/drivers/ieee1394/nodemgr.h
+++ b/drivers/ieee1394/nodemgr.h
@@ -84,7 +84,7 @@ struct unit_directory {
84 int length; /* Number of quadlets */ 84 int length; /* Number of quadlets */
85 85
86 struct device device; 86 struct device device;
87 struct class_device class_dev; 87 struct device unit_dev;
88 88
89 struct csr1212_keyval *ud_kv; 89 struct csr1212_keyval *ud_kv;
90 u32 lun; /* logical unit number immediate value */ 90 u32 lun; /* logical unit number immediate value */
@@ -107,7 +107,7 @@ struct node_entry {
107 u32 capabilities; 107 u32 capabilities;
108 108
109 struct device device; 109 struct device device;
110 struct class_device class_dev; 110 struct device node_dev;
111 111
112 /* Means this node is not attached anymore */ 112 /* Means this node is not attached anymore */
113 int in_limbo; 113 int in_limbo;
diff --git a/drivers/ieee1394/ohci1394.c b/drivers/ieee1394/ohci1394.c
index 5dadfd296f79..5667c8102efc 100644
--- a/drivers/ieee1394/ohci1394.c
+++ b/drivers/ieee1394/ohci1394.c
@@ -138,19 +138,6 @@ printk(KERN_INFO "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, ohci->host->
138#define DBGMSG(fmt, args...) do {} while (0) 138#define DBGMSG(fmt, args...) do {} while (0)
139#endif 139#endif
140 140
141#ifdef CONFIG_IEEE1394_OHCI_DMA_DEBUG
142#define OHCI_DMA_ALLOC(fmt, args...) \
143 HPSB_ERR("%s(%s)alloc(%d): "fmt, OHCI1394_DRIVER_NAME, __FUNCTION__, \
144 ++global_outstanding_dmas, ## args)
145#define OHCI_DMA_FREE(fmt, args...) \
146 HPSB_ERR("%s(%s)free(%d): "fmt, OHCI1394_DRIVER_NAME, __FUNCTION__, \
147 --global_outstanding_dmas, ## args)
148static int global_outstanding_dmas = 0;
149#else
150#define OHCI_DMA_ALLOC(fmt, args...) do {} while (0)
151#define OHCI_DMA_FREE(fmt, args...) do {} while (0)
152#endif
153
154/* print general (card independent) information */ 141/* print general (card independent) information */
155#define PRINT_G(level, fmt, args...) \ 142#define PRINT_G(level, fmt, args...) \
156printk(level "%s: " fmt "\n" , OHCI1394_DRIVER_NAME , ## args) 143printk(level "%s: " fmt "\n" , OHCI1394_DRIVER_NAME , ## args)
@@ -170,7 +157,6 @@ static void dma_trm_reset(struct dma_trm_ctx *d);
170static int alloc_dma_rcv_ctx(struct ti_ohci *ohci, struct dma_rcv_ctx *d, 157static int alloc_dma_rcv_ctx(struct ti_ohci *ohci, struct dma_rcv_ctx *d,
171 enum context_type type, int ctx, int num_desc, 158 enum context_type type, int ctx, int num_desc,
172 int buf_size, int split_buf_size, int context_base); 159 int buf_size, int split_buf_size, int context_base);
173static void stop_dma_rcv_ctx(struct dma_rcv_ctx *d);
174static void free_dma_rcv_ctx(struct dma_rcv_ctx *d); 160static void free_dma_rcv_ctx(struct dma_rcv_ctx *d);
175 161
176static int alloc_dma_trm_ctx(struct ti_ohci *ohci, struct dma_trm_ctx *d, 162static int alloc_dma_trm_ctx(struct ti_ohci *ohci, struct dma_trm_ctx *d,
@@ -533,9 +519,6 @@ static void ohci_initialize(struct ti_ohci *ohci)
533 initialize_dma_trm_ctx(&ohci->at_req_context); 519 initialize_dma_trm_ctx(&ohci->at_req_context);
534 initialize_dma_trm_ctx(&ohci->at_resp_context); 520 initialize_dma_trm_ctx(&ohci->at_resp_context);
535 521
536 /* Initialize IR Legacy DMA channel mask */
537 ohci->ir_legacy_channels = 0;
538
539 /* Accept AR requests from all nodes */ 522 /* Accept AR requests from all nodes */
540 reg_write(ohci, OHCI1394_AsReqFilterHiSet, 0x80000000); 523 reg_write(ohci, OHCI1394_AsReqFilterHiSet, 0x80000000);
541 524
@@ -733,7 +716,6 @@ static void insert_packet(struct ti_ohci *ohci,
733 pci_map_single(ohci->dev, packet->data, 716 pci_map_single(ohci->dev, packet->data,
734 packet->data_size, 717 packet->data_size,
735 PCI_DMA_TODEVICE)); 718 PCI_DMA_TODEVICE));
736 OHCI_DMA_ALLOC("single, block transmit packet");
737 719
738 d->prg_cpu[idx]->end.branchAddress = 0; 720 d->prg_cpu[idx]->end.branchAddress = 0;
739 d->prg_cpu[idx]->end.status = 0; 721 d->prg_cpu[idx]->end.status = 0;
@@ -783,7 +765,6 @@ static void insert_packet(struct ti_ohci *ohci,
783 d->prg_cpu[idx]->end.address = cpu_to_le32( 765 d->prg_cpu[idx]->end.address = cpu_to_le32(
784 pci_map_single(ohci->dev, packet->data, 766 pci_map_single(ohci->dev, packet->data,
785 packet->data_size, PCI_DMA_TODEVICE)); 767 packet->data_size, PCI_DMA_TODEVICE));
786 OHCI_DMA_ALLOC("single, iso transmit packet");
787 768
788 d->prg_cpu[idx]->end.branchAddress = 0; 769 d->prg_cpu[idx]->end.branchAddress = 0;
789 d->prg_cpu[idx]->end.status = 0; 770 d->prg_cpu[idx]->end.status = 0;
@@ -884,36 +865,9 @@ static int ohci_transmit(struct hpsb_host *host, struct hpsb_packet *packet)
884 return -EOVERFLOW; 865 return -EOVERFLOW;
885 } 866 }
886 867
887 /* Decide whether we have an iso, a request, or a response packet */
888 if (packet->type == hpsb_raw) 868 if (packet->type == hpsb_raw)
889 d = &ohci->at_req_context; 869 d = &ohci->at_req_context;
890 else if ((packet->tcode == TCODE_ISO_DATA) && (packet->type == hpsb_iso)) { 870 else if ((packet->tcode & 0x02) && (packet->tcode != TCODE_ISO_DATA))
891 /* The legacy IT DMA context is initialized on first
892 * use. However, the alloc cannot be run from
893 * interrupt context, so we bail out if that is the
894 * case. I don't see anyone sending ISO packets from
895 * interrupt context anyway... */
896
897 if (ohci->it_legacy_context.ohci == NULL) {
898 if (in_interrupt()) {
899 PRINT(KERN_ERR,
900 "legacy IT context cannot be initialized during interrupt");
901 return -EINVAL;
902 }
903
904 if (alloc_dma_trm_ctx(ohci, &ohci->it_legacy_context,
905 DMA_CTX_ISO, 0, IT_NUM_DESC,
906 OHCI1394_IsoXmitContextBase) < 0) {
907 PRINT(KERN_ERR,
908 "error initializing legacy IT context");
909 return -ENOMEM;
910 }
911
912 initialize_dma_trm_ctx(&ohci->it_legacy_context);
913 }
914
915 d = &ohci->it_legacy_context;
916 } else if ((packet->tcode & 0x02) && (packet->tcode != TCODE_ISO_DATA))
917 d = &ohci->at_resp_context; 871 d = &ohci->at_resp_context;
918 else 872 else
919 d = &ohci->at_req_context; 873 d = &ohci->at_req_context;
@@ -932,9 +886,7 @@ static int ohci_transmit(struct hpsb_host *host, struct hpsb_packet *packet)
932static int ohci_devctl(struct hpsb_host *host, enum devctl_cmd cmd, int arg) 886static int ohci_devctl(struct hpsb_host *host, enum devctl_cmd cmd, int arg)
933{ 887{
934 struct ti_ohci *ohci = host->hostdata; 888 struct ti_ohci *ohci = host->hostdata;
935 int retval = 0; 889 int retval = 0, phy_reg;
936 unsigned long flags;
937 int phy_reg;
938 890
939 switch (cmd) { 891 switch (cmd) {
940 case RESET_BUS: 892 case RESET_BUS:
@@ -1027,117 +979,6 @@ static int ohci_devctl(struct hpsb_host *host, enum devctl_cmd cmd, int arg)
1027 dma_trm_reset(&ohci->at_resp_context); 979 dma_trm_reset(&ohci->at_resp_context);
1028 break; 980 break;
1029 981
1030 case ISO_LISTEN_CHANNEL:
1031 {
1032 u64 mask;
1033 struct dma_rcv_ctx *d = &ohci->ir_legacy_context;
1034 int ir_legacy_active;
1035
1036 if (arg<0 || arg>63) {
1037 PRINT(KERN_ERR,
1038 "%s: IS0 listen channel %d is out of range",
1039 __FUNCTION__, arg);
1040 return -EFAULT;
1041 }
1042
1043 mask = (u64)0x1<<arg;
1044
1045 spin_lock_irqsave(&ohci->IR_channel_lock, flags);
1046
1047 if (ohci->ISO_channel_usage & mask) {
1048 PRINT(KERN_ERR,
1049 "%s: IS0 listen channel %d is already used",
1050 __FUNCTION__, arg);
1051 spin_unlock_irqrestore(&ohci->IR_channel_lock, flags);
1052 return -EFAULT;
1053 }
1054
1055 ir_legacy_active = ohci->ir_legacy_channels;
1056
1057 ohci->ISO_channel_usage |= mask;
1058 ohci->ir_legacy_channels |= mask;
1059
1060 spin_unlock_irqrestore(&ohci->IR_channel_lock, flags);
1061
1062 if (!ir_legacy_active) {
1063 if (ohci1394_register_iso_tasklet(ohci,
1064 &ohci->ir_legacy_tasklet) < 0) {
1065 PRINT(KERN_ERR, "No IR DMA context available");
1066 return -EBUSY;
1067 }
1068
1069 /* the IR context can be assigned to any DMA context
1070 * by ohci1394_register_iso_tasklet */
1071 d->ctx = ohci->ir_legacy_tasklet.context;
1072 d->ctrlSet = OHCI1394_IsoRcvContextControlSet +
1073 32*d->ctx;
1074 d->ctrlClear = OHCI1394_IsoRcvContextControlClear +
1075 32*d->ctx;
1076 d->cmdPtr = OHCI1394_IsoRcvCommandPtr + 32*d->ctx;
1077 d->ctxtMatch = OHCI1394_IsoRcvContextMatch + 32*d->ctx;
1078
1079 initialize_dma_rcv_ctx(&ohci->ir_legacy_context, 1);
1080
1081 if (printk_ratelimit())
1082 DBGMSG("IR legacy activated");
1083 }
1084
1085 spin_lock_irqsave(&ohci->IR_channel_lock, flags);
1086
1087 if (arg>31)
1088 reg_write(ohci, OHCI1394_IRMultiChanMaskHiSet,
1089 1<<(arg-32));
1090 else
1091 reg_write(ohci, OHCI1394_IRMultiChanMaskLoSet,
1092 1<<arg);
1093
1094 spin_unlock_irqrestore(&ohci->IR_channel_lock, flags);
1095 DBGMSG("Listening enabled on channel %d", arg);
1096 break;
1097 }
1098 case ISO_UNLISTEN_CHANNEL:
1099 {
1100 u64 mask;
1101
1102 if (arg<0 || arg>63) {
1103 PRINT(KERN_ERR,
1104 "%s: IS0 unlisten channel %d is out of range",
1105 __FUNCTION__, arg);
1106 return -EFAULT;
1107 }
1108
1109 mask = (u64)0x1<<arg;
1110
1111 spin_lock_irqsave(&ohci->IR_channel_lock, flags);
1112
1113 if (!(ohci->ISO_channel_usage & mask)) {
1114 PRINT(KERN_ERR,
1115 "%s: IS0 unlisten channel %d is not used",
1116 __FUNCTION__, arg);
1117 spin_unlock_irqrestore(&ohci->IR_channel_lock, flags);
1118 return -EFAULT;
1119 }
1120
1121 ohci->ISO_channel_usage &= ~mask;
1122 ohci->ir_legacy_channels &= ~mask;
1123
1124 if (arg>31)
1125 reg_write(ohci, OHCI1394_IRMultiChanMaskHiClear,
1126 1<<(arg-32));
1127 else
1128 reg_write(ohci, OHCI1394_IRMultiChanMaskLoClear,
1129 1<<arg);
1130
1131 spin_unlock_irqrestore(&ohci->IR_channel_lock, flags);
1132 DBGMSG("Listening disabled on channel %d", arg);
1133
1134 if (ohci->ir_legacy_channels == 0) {
1135 stop_dma_rcv_ctx(&ohci->ir_legacy_context);
1136 DBGMSG("ISO legacy receive context stopped");
1137 }
1138
1139 break;
1140 }
1141 default: 982 default:
1142 PRINT_G(KERN_ERR, "ohci_devctl cmd %d not implemented yet", 983 PRINT_G(KERN_ERR, "ohci_devctl cmd %d not implemented yet",
1143 cmd); 984 cmd);
@@ -2869,12 +2710,10 @@ static void dma_trm_tasklet (unsigned long data)
2869 list_del_init(&packet->driver_list); 2710 list_del_init(&packet->driver_list);
2870 hpsb_packet_sent(ohci->host, packet, ack); 2711 hpsb_packet_sent(ohci->host, packet, ack);
2871 2712
2872 if (datasize) { 2713 if (datasize)
2873 pci_unmap_single(ohci->dev, 2714 pci_unmap_single(ohci->dev,
2874 cpu_to_le32(d->prg_cpu[d->sent_ind]->end.address), 2715 cpu_to_le32(d->prg_cpu[d->sent_ind]->end.address),
2875 datasize, PCI_DMA_TODEVICE); 2716 datasize, PCI_DMA_TODEVICE);
2876 OHCI_DMA_FREE("single Xmit data packet");
2877 }
2878 2717
2879 d->sent_ind = (d->sent_ind+1)%d->num_desc; 2718 d->sent_ind = (d->sent_ind+1)%d->num_desc;
2880 d->free_prgs++; 2719 d->free_prgs++;
@@ -2885,22 +2724,6 @@ static void dma_trm_tasklet (unsigned long data)
2885 spin_unlock_irqrestore(&d->lock, flags); 2724 spin_unlock_irqrestore(&d->lock, flags);
2886} 2725}
2887 2726
2888static void stop_dma_rcv_ctx(struct dma_rcv_ctx *d)
2889{
2890 if (d->ctrlClear) {
2891 ohci1394_stop_context(d->ohci, d->ctrlClear, NULL);
2892
2893 if (d->type == DMA_CTX_ISO) {
2894 /* disable interrupts */
2895 reg_write(d->ohci, OHCI1394_IsoRecvIntMaskClear, 1 << d->ctx);
2896 ohci1394_unregister_iso_tasklet(d->ohci, &d->ohci->ir_legacy_tasklet);
2897 } else {
2898 tasklet_kill(&d->task);
2899 }
2900 }
2901}
2902
2903
2904static void free_dma_rcv_ctx(struct dma_rcv_ctx *d) 2727static void free_dma_rcv_ctx(struct dma_rcv_ctx *d)
2905{ 2728{
2906 int i; 2729 int i;
@@ -2913,23 +2736,19 @@ static void free_dma_rcv_ctx(struct dma_rcv_ctx *d)
2913 2736
2914 if (d->buf_cpu) { 2737 if (d->buf_cpu) {
2915 for (i=0; i<d->num_desc; i++) 2738 for (i=0; i<d->num_desc; i++)
2916 if (d->buf_cpu[i] && d->buf_bus[i]) { 2739 if (d->buf_cpu[i] && d->buf_bus[i])
2917 pci_free_consistent( 2740 pci_free_consistent(
2918 ohci->dev, d->buf_size, 2741 ohci->dev, d->buf_size,
2919 d->buf_cpu[i], d->buf_bus[i]); 2742 d->buf_cpu[i], d->buf_bus[i]);
2920 OHCI_DMA_FREE("consistent dma_rcv buf[%d]", i);
2921 }
2922 kfree(d->buf_cpu); 2743 kfree(d->buf_cpu);
2923 kfree(d->buf_bus); 2744 kfree(d->buf_bus);
2924 } 2745 }
2925 if (d->prg_cpu) { 2746 if (d->prg_cpu) {
2926 for (i=0; i<d->num_desc; i++) 2747 for (i=0; i<d->num_desc; i++)
2927 if (d->prg_cpu[i] && d->prg_bus[i]) { 2748 if (d->prg_cpu[i] && d->prg_bus[i])
2928 pci_pool_free(d->prg_pool, d->prg_cpu[i], d->prg_bus[i]); 2749 pci_pool_free(d->prg_pool, d->prg_cpu[i],
2929 OHCI_DMA_FREE("consistent dma_rcv prg[%d]", i); 2750 d->prg_bus[i]);
2930 }
2931 pci_pool_destroy(d->prg_pool); 2751 pci_pool_destroy(d->prg_pool);
2932 OHCI_DMA_FREE("dma_rcv prg pool");
2933 kfree(d->prg_cpu); 2752 kfree(d->prg_cpu);
2934 kfree(d->prg_bus); 2753 kfree(d->prg_bus);
2935 } 2754 }
@@ -2998,13 +2817,10 @@ alloc_dma_rcv_ctx(struct ti_ohci *ohci, struct dma_rcv_ctx *d,
2998 } 2817 }
2999 num_allocs++; 2818 num_allocs++;
3000 2819
3001 OHCI_DMA_ALLOC("dma_rcv prg pool");
3002
3003 for (i=0; i<d->num_desc; i++) { 2820 for (i=0; i<d->num_desc; i++) {
3004 d->buf_cpu[i] = pci_alloc_consistent(ohci->dev, 2821 d->buf_cpu[i] = pci_alloc_consistent(ohci->dev,
3005 d->buf_size, 2822 d->buf_size,
3006 d->buf_bus+i); 2823 d->buf_bus+i);
3007 OHCI_DMA_ALLOC("consistent dma_rcv buf[%d]", i);
3008 2824
3009 if (d->buf_cpu[i] != NULL) { 2825 if (d->buf_cpu[i] != NULL) {
3010 memset(d->buf_cpu[i], 0, d->buf_size); 2826 memset(d->buf_cpu[i], 0, d->buf_size);
@@ -3016,7 +2832,6 @@ alloc_dma_rcv_ctx(struct ti_ohci *ohci, struct dma_rcv_ctx *d,
3016 } 2832 }
3017 2833
3018 d->prg_cpu[i] = pci_pool_alloc(d->prg_pool, GFP_KERNEL, d->prg_bus+i); 2834 d->prg_cpu[i] = pci_pool_alloc(d->prg_pool, GFP_KERNEL, d->prg_bus+i);
3019 OHCI_DMA_ALLOC("pool dma_rcv prg[%d]", i);
3020 2835
3021 if (d->prg_cpu[i] != NULL) { 2836 if (d->prg_cpu[i] != NULL) {
3022 memset(d->prg_cpu[i], 0, sizeof(struct dma_cmd)); 2837 memset(d->prg_cpu[i], 0, sizeof(struct dma_cmd));
@@ -3030,18 +2845,11 @@ alloc_dma_rcv_ctx(struct ti_ohci *ohci, struct dma_rcv_ctx *d,
3030 2845
3031 spin_lock_init(&d->lock); 2846 spin_lock_init(&d->lock);
3032 2847
3033 if (type == DMA_CTX_ISO) { 2848 d->ctrlSet = context_base + OHCI1394_ContextControlSet;
3034 ohci1394_init_iso_tasklet(&ohci->ir_legacy_tasklet, 2849 d->ctrlClear = context_base + OHCI1394_ContextControlClear;
3035 OHCI_ISO_MULTICHANNEL_RECEIVE, 2850 d->cmdPtr = context_base + OHCI1394_ContextCommandPtr;
3036 dma_rcv_tasklet, (unsigned long) d);
3037 } else {
3038 d->ctrlSet = context_base + OHCI1394_ContextControlSet;
3039 d->ctrlClear = context_base + OHCI1394_ContextControlClear;
3040 d->cmdPtr = context_base + OHCI1394_ContextCommandPtr;
3041
3042 tasklet_init (&d->task, dma_rcv_tasklet, (unsigned long) d);
3043 }
3044 2851
2852 tasklet_init(&d->task, dma_rcv_tasklet, (unsigned long) d);
3045 return 0; 2853 return 0;
3046} 2854}
3047 2855
@@ -3057,12 +2865,10 @@ static void free_dma_trm_ctx(struct dma_trm_ctx *d)
3057 2865
3058 if (d->prg_cpu) { 2866 if (d->prg_cpu) {
3059 for (i=0; i<d->num_desc; i++) 2867 for (i=0; i<d->num_desc; i++)
3060 if (d->prg_cpu[i] && d->prg_bus[i]) { 2868 if (d->prg_cpu[i] && d->prg_bus[i])
3061 pci_pool_free(d->prg_pool, d->prg_cpu[i], d->prg_bus[i]); 2869 pci_pool_free(d->prg_pool, d->prg_cpu[i],
3062 OHCI_DMA_FREE("pool dma_trm prg[%d]", i); 2870 d->prg_bus[i]);
3063 }
3064 pci_pool_destroy(d->prg_pool); 2871 pci_pool_destroy(d->prg_pool);
3065 OHCI_DMA_FREE("dma_trm prg pool");
3066 kfree(d->prg_cpu); 2872 kfree(d->prg_cpu);
3067 kfree(d->prg_bus); 2873 kfree(d->prg_bus);
3068 } 2874 }
@@ -3108,11 +2914,8 @@ alloc_dma_trm_ctx(struct ti_ohci *ohci, struct dma_trm_ctx *d,
3108 } 2914 }
3109 num_allocs++; 2915 num_allocs++;
3110 2916
3111 OHCI_DMA_ALLOC("dma_rcv prg pool");
3112
3113 for (i = 0; i < d->num_desc; i++) { 2917 for (i = 0; i < d->num_desc; i++) {
3114 d->prg_cpu[i] = pci_pool_alloc(d->prg_pool, GFP_KERNEL, d->prg_bus+i); 2918 d->prg_cpu[i] = pci_pool_alloc(d->prg_pool, GFP_KERNEL, d->prg_bus+i);
3115 OHCI_DMA_ALLOC("pool dma_trm prg[%d]", i);
3116 2919
3117 if (d->prg_cpu[i] != NULL) { 2920 if (d->prg_cpu[i] != NULL) {
3118 memset(d->prg_cpu[i], 0, sizeof(struct at_dma_prg)); 2921 memset(d->prg_cpu[i], 0, sizeof(struct at_dma_prg));
@@ -3127,28 +2930,10 @@ alloc_dma_trm_ctx(struct ti_ohci *ohci, struct dma_trm_ctx *d,
3127 spin_lock_init(&d->lock); 2930 spin_lock_init(&d->lock);
3128 2931
3129 /* initialize tasklet */ 2932 /* initialize tasklet */
3130 if (type == DMA_CTX_ISO) { 2933 d->ctrlSet = context_base + OHCI1394_ContextControlSet;
3131 ohci1394_init_iso_tasklet(&ohci->it_legacy_tasklet, OHCI_ISO_TRANSMIT, 2934 d->ctrlClear = context_base + OHCI1394_ContextControlClear;
3132 dma_trm_tasklet, (unsigned long) d); 2935 d->cmdPtr = context_base + OHCI1394_ContextCommandPtr;
3133 if (ohci1394_register_iso_tasklet(ohci, 2936 tasklet_init(&d->task, dma_trm_tasklet, (unsigned long)d);
3134 &ohci->it_legacy_tasklet) < 0) {
3135 PRINT(KERN_ERR, "No IT DMA context available");
3136 free_dma_trm_ctx(d);
3137 return -EBUSY;
3138 }
3139
3140 /* IT can be assigned to any context by register_iso_tasklet */
3141 d->ctx = ohci->it_legacy_tasklet.context;
3142 d->ctrlSet = OHCI1394_IsoXmitContextControlSet + 16 * d->ctx;
3143 d->ctrlClear = OHCI1394_IsoXmitContextControlClear + 16 * d->ctx;
3144 d->cmdPtr = OHCI1394_IsoXmitCommandPtr + 16 * d->ctx;
3145 } else {
3146 d->ctrlSet = context_base + OHCI1394_ContextControlSet;
3147 d->ctrlClear = context_base + OHCI1394_ContextControlClear;
3148 d->cmdPtr = context_base + OHCI1394_ContextCommandPtr;
3149 tasklet_init (&d->task, dma_trm_tasklet, (unsigned long)d);
3150 }
3151
3152 return 0; 2937 return 0;
3153} 2938}
3154 2939
@@ -3294,7 +3079,6 @@ static int __devinit ohci1394_pci_probe(struct pci_dev *dev,
3294 ohci->csr_config_rom_cpu = 3079 ohci->csr_config_rom_cpu =
3295 pci_alloc_consistent(ohci->dev, OHCI_CONFIG_ROM_LEN, 3080 pci_alloc_consistent(ohci->dev, OHCI_CONFIG_ROM_LEN,
3296 &ohci->csr_config_rom_bus); 3081 &ohci->csr_config_rom_bus);
3297 OHCI_DMA_ALLOC("consistent csr_config_rom");
3298 if (ohci->csr_config_rom_cpu == NULL) 3082 if (ohci->csr_config_rom_cpu == NULL)
3299 FAIL(-ENOMEM, "Failed to allocate buffer config rom"); 3083 FAIL(-ENOMEM, "Failed to allocate buffer config rom");
3300 ohci->init_state = OHCI_INIT_HAVE_CONFIG_ROM_BUFFER; 3084 ohci->init_state = OHCI_INIT_HAVE_CONFIG_ROM_BUFFER;
@@ -3303,8 +3087,6 @@ static int __devinit ohci1394_pci_probe(struct pci_dev *dev,
3303 ohci->selfid_buf_cpu = 3087 ohci->selfid_buf_cpu =
3304 pci_alloc_consistent(ohci->dev, OHCI1394_SI_DMA_BUF_SIZE, 3088 pci_alloc_consistent(ohci->dev, OHCI1394_SI_DMA_BUF_SIZE,
3305 &ohci->selfid_buf_bus); 3089 &ohci->selfid_buf_bus);
3306 OHCI_DMA_ALLOC("consistent selfid_buf");
3307
3308 if (ohci->selfid_buf_cpu == NULL) 3090 if (ohci->selfid_buf_cpu == NULL)
3309 FAIL(-ENOMEM, "Failed to allocate DMA buffer for self-id packets"); 3091 FAIL(-ENOMEM, "Failed to allocate DMA buffer for self-id packets");
3310 ohci->init_state = OHCI_INIT_HAVE_SELFID_BUFFER; 3092 ohci->init_state = OHCI_INIT_HAVE_SELFID_BUFFER;
@@ -3377,20 +3159,6 @@ static int __devinit ohci1394_pci_probe(struct pci_dev *dev,
3377 ohci->ISO_channel_usage = 0; 3159 ohci->ISO_channel_usage = 0;
3378 spin_lock_init(&ohci->IR_channel_lock); 3160 spin_lock_init(&ohci->IR_channel_lock);
3379 3161
3380 /* Allocate the IR DMA context right here so we don't have
3381 * to do it in interrupt path - note that this doesn't
3382 * waste much memory and avoids the jugglery required to
3383 * allocate it in IRQ path. */
3384 if (alloc_dma_rcv_ctx(ohci, &ohci->ir_legacy_context,
3385 DMA_CTX_ISO, 0, IR_NUM_DESC,
3386 IR_BUF_SIZE, IR_SPLIT_BUF_SIZE,
3387 OHCI1394_IsoRcvContextBase) < 0) {
3388 FAIL(-ENOMEM, "Cannot allocate IR Legacy DMA context");
3389 }
3390
3391 /* We hopefully don't have to pre-allocate IT DMA like we did
3392 * for IR DMA above. Allocate it on-demand and mark inactive. */
3393 ohci->it_legacy_context.ohci = NULL;
3394 spin_lock_init(&ohci->event_lock); 3162 spin_lock_init(&ohci->event_lock);
3395 3163
3396 /* 3164 /*
@@ -3483,20 +3251,16 @@ static void ohci1394_pci_remove(struct pci_dev *pdev)
3483 free_dma_rcv_ctx(&ohci->ar_resp_context); 3251 free_dma_rcv_ctx(&ohci->ar_resp_context);
3484 free_dma_trm_ctx(&ohci->at_req_context); 3252 free_dma_trm_ctx(&ohci->at_req_context);
3485 free_dma_trm_ctx(&ohci->at_resp_context); 3253 free_dma_trm_ctx(&ohci->at_resp_context);
3486 free_dma_rcv_ctx(&ohci->ir_legacy_context);
3487 free_dma_trm_ctx(&ohci->it_legacy_context);
3488 3254
3489 case OHCI_INIT_HAVE_SELFID_BUFFER: 3255 case OHCI_INIT_HAVE_SELFID_BUFFER:
3490 pci_free_consistent(ohci->dev, OHCI1394_SI_DMA_BUF_SIZE, 3256 pci_free_consistent(ohci->dev, OHCI1394_SI_DMA_BUF_SIZE,
3491 ohci->selfid_buf_cpu, 3257 ohci->selfid_buf_cpu,
3492 ohci->selfid_buf_bus); 3258 ohci->selfid_buf_bus);
3493 OHCI_DMA_FREE("consistent selfid_buf");
3494 3259
3495 case OHCI_INIT_HAVE_CONFIG_ROM_BUFFER: 3260 case OHCI_INIT_HAVE_CONFIG_ROM_BUFFER:
3496 pci_free_consistent(ohci->dev, OHCI_CONFIG_ROM_LEN, 3261 pci_free_consistent(ohci->dev, OHCI_CONFIG_ROM_LEN,
3497 ohci->csr_config_rom_cpu, 3262 ohci->csr_config_rom_cpu,
3498 ohci->csr_config_rom_bus); 3263 ohci->csr_config_rom_bus);
3499 OHCI_DMA_FREE("consistent csr_config_rom");
3500 3264
3501 case OHCI_INIT_HAVE_IOMAPPING: 3265 case OHCI_INIT_HAVE_IOMAPPING:
3502 iounmap(ohci->registers); 3266 iounmap(ohci->registers);
diff --git a/drivers/ieee1394/ohci1394.h b/drivers/ieee1394/ohci1394.h
index f1ad539e7c1b..4320bf010495 100644
--- a/drivers/ieee1394/ohci1394.h
+++ b/drivers/ieee1394/ohci1394.h
@@ -190,23 +190,10 @@ struct ti_ohci {
190 unsigned long ir_multichannel_used; /* ditto */ 190 unsigned long ir_multichannel_used; /* ditto */
191 spinlock_t IR_channel_lock; 191 spinlock_t IR_channel_lock;
192 192
193 /* iso receive (legacy API) */
194 u64 ir_legacy_channels; /* note: this differs from ISO_channel_usage;
195 it only accounts for channels listened to
196 by the legacy API, so that we can know when
197 it is safe to free the legacy API context */
198
199 struct dma_rcv_ctx ir_legacy_context;
200 struct ohci1394_iso_tasklet ir_legacy_tasklet;
201
202 /* iso transmit */ 193 /* iso transmit */
203 int nb_iso_xmit_ctx; 194 int nb_iso_xmit_ctx;
204 unsigned long it_ctx_usage; /* use test_and_set_bit() for atomicity */ 195 unsigned long it_ctx_usage; /* use test_and_set_bit() for atomicity */
205 196
206 /* iso transmit (legacy API) */
207 struct dma_trm_ctx it_legacy_context;
208 struct ohci1394_iso_tasklet it_legacy_tasklet;
209
210 u64 ISO_channel_usage; 197 u64 ISO_channel_usage;
211 198
212 /* IEEE-1394 part follows */ 199 /* IEEE-1394 part follows */
@@ -221,7 +208,6 @@ struct ti_ohci {
221 208
222 /* Tasklets for iso receive and transmit, used by video1394 209 /* Tasklets for iso receive and transmit, used by video1394
223 * and dv1394 */ 210 * and dv1394 */
224
225 struct list_head iso_tasklet_list; 211 struct list_head iso_tasklet_list;
226 spinlock_t iso_tasklet_list_lock; 212 spinlock_t iso_tasklet_list_lock;
227 213
diff --git a/drivers/ieee1394/pcilynx.c b/drivers/ieee1394/pcilynx.c
index 0742befe9227..d1a5bcdb5e0b 100644
--- a/drivers/ieee1394/pcilynx.c
+++ b/drivers/ieee1394/pcilynx.c
@@ -477,7 +477,11 @@ static void send_next(struct ti_lynx *lynx, int what)
477 struct lynx_send_data *d; 477 struct lynx_send_data *d;
478 struct hpsb_packet *packet; 478 struct hpsb_packet *packet;
479 479
480#if 0 /* has been removed from ieee1394 core */
480 d = (what == hpsb_iso ? &lynx->iso_send : &lynx->async); 481 d = (what == hpsb_iso ? &lynx->iso_send : &lynx->async);
482#else
483 d = &lynx->async;
484#endif
481 if (!list_empty(&d->pcl_queue)) { 485 if (!list_empty(&d->pcl_queue)) {
482 PRINT(KERN_ERR, lynx->id, "trying to queue a new packet in nonempty fifo"); 486 PRINT(KERN_ERR, lynx->id, "trying to queue a new packet in nonempty fifo");
483 BUG(); 487 BUG();
@@ -511,9 +515,11 @@ static void send_next(struct ti_lynx *lynx, int what)
511 case hpsb_async: 515 case hpsb_async:
512 pcl.buffer[0].control |= PCL_CMD_XMT; 516 pcl.buffer[0].control |= PCL_CMD_XMT;
513 break; 517 break;
518#if 0 /* has been removed from ieee1394 core */
514 case hpsb_iso: 519 case hpsb_iso:
515 pcl.buffer[0].control |= PCL_CMD_XMT | PCL_ISOMODE; 520 pcl.buffer[0].control |= PCL_CMD_XMT | PCL_ISOMODE;
516 break; 521 break;
522#endif
517 case hpsb_raw: 523 case hpsb_raw:
518 pcl.buffer[0].control |= PCL_CMD_UNFXMT; 524 pcl.buffer[0].control |= PCL_CMD_UNFXMT;
519 break; 525 break;
@@ -542,9 +548,11 @@ static int lynx_transmit(struct hpsb_host *host, struct hpsb_packet *packet)
542 case hpsb_raw: 548 case hpsb_raw:
543 d = &lynx->async; 549 d = &lynx->async;
544 break; 550 break;
551#if 0 /* has been removed from ieee1394 core */
545 case hpsb_iso: 552 case hpsb_iso:
546 d = &lynx->iso_send; 553 d = &lynx->iso_send;
547 break; 554 break;
555#endif
548 default: 556 default:
549 PRINT(KERN_ERR, lynx->id, "invalid packet type %d", 557 PRINT(KERN_ERR, lynx->id, "invalid packet type %d",
550 packet->type); 558 packet->type);
@@ -797,7 +805,7 @@ static int lynx_devctl(struct hpsb_host *host, enum devctl_cmd cmd, int arg)
797 } 805 }
798 806
799 break; 807 break;
800 808#if 0 /* has been removed from ieee1394 core */
801 case ISO_LISTEN_CHANNEL: 809 case ISO_LISTEN_CHANNEL:
802 spin_lock_irqsave(&lynx->iso_rcv.lock, flags); 810 spin_lock_irqsave(&lynx->iso_rcv.lock, flags);
803 811
@@ -819,7 +827,7 @@ static int lynx_devctl(struct hpsb_host *host, enum devctl_cmd cmd, int arg)
819 827
820 spin_unlock_irqrestore(&lynx->iso_rcv.lock, flags); 828 spin_unlock_irqrestore(&lynx->iso_rcv.lock, flags);
821 break; 829 break;
822 830#endif
823 default: 831 default:
824 PRINT(KERN_ERR, lynx->id, "unknown devctl command %d", cmd); 832 PRINT(KERN_ERR, lynx->id, "unknown devctl command %d", cmd);
825 retval = -1; 833 retval = -1;
@@ -1009,11 +1017,11 @@ static irqreturn_t lynx_irq_handler(int irq, void *dev_id)
1009 pci_unmap_single(lynx->dev, lynx->iso_send.data_dma, 1017 pci_unmap_single(lynx->dev, lynx->iso_send.data_dma,
1010 packet->data_size, PCI_DMA_TODEVICE); 1018 packet->data_size, PCI_DMA_TODEVICE);
1011 } 1019 }
1012 1020#if 0 /* has been removed from ieee1394 core */
1013 if (!list_empty(&lynx->iso_send.queue)) { 1021 if (!list_empty(&lynx->iso_send.queue)) {
1014 send_next(lynx, hpsb_iso); 1022 send_next(lynx, hpsb_iso);
1015 } 1023 }
1016 1024#endif
1017 spin_unlock(&lynx->iso_send.queue_lock); 1025 spin_unlock(&lynx->iso_send.queue_lock);
1018 1026
1019 if (pcl.pcl_status & DMA_CHAN_STAT_PKTCMPL) { 1027 if (pcl.pcl_status & DMA_CHAN_STAT_PKTCMPL) {
diff --git a/drivers/ieee1394/raw1394-private.h b/drivers/ieee1394/raw1394-private.h
index 50daabf6e5fa..a06aaad5b448 100644
--- a/drivers/ieee1394/raw1394-private.h
+++ b/drivers/ieee1394/raw1394-private.h
@@ -36,11 +36,6 @@ struct file_info {
36 36
37 u8 __user *fcp_buffer; 37 u8 __user *fcp_buffer;
38 38
39 /* old ISO API */
40 u64 listen_channels;
41 quadlet_t __user *iso_buffer;
42 size_t iso_buffer_length;
43
44 u8 notification; /* (busreset-notification) RAW1394_NOTIFY_OFF/ON */ 39 u8 notification; /* (busreset-notification) RAW1394_NOTIFY_OFF/ON */
45 40
46 /* new rawiso API */ 41 /* new rawiso API */
diff --git a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c
index f1d05eeb9f51..336e5ff4cfcf 100644
--- a/drivers/ieee1394/raw1394.c
+++ b/drivers/ieee1394/raw1394.c
@@ -98,21 +98,6 @@ static struct hpsb_address_ops arm_ops = {
98 98
99static void queue_complete_cb(struct pending_request *req); 99static void queue_complete_cb(struct pending_request *req);
100 100
101#include <asm/current.h>
102static void print_old_iso_deprecation(void)
103{
104 static pid_t p;
105
106 if (p == current->pid)
107 return;
108 p = current->pid;
109 printk(KERN_WARNING "raw1394: WARNING - Program \"%s\" uses unsupported"
110 " isochronous request types which will be removed in a next"
111 " kernel release\n", current->comm);
112 printk(KERN_WARNING "raw1394: Update your software to use libraw1394's"
113 " newer interface\n");
114}
115
116static struct pending_request *__alloc_pending_request(gfp_t flags) 101static struct pending_request *__alloc_pending_request(gfp_t flags)
117{ 102{
118 struct pending_request *req; 103 struct pending_request *req;
@@ -297,67 +282,6 @@ static void host_reset(struct hpsb_host *host)
297 spin_unlock_irqrestore(&host_info_lock, flags); 282 spin_unlock_irqrestore(&host_info_lock, flags);
298} 283}
299 284
300static void iso_receive(struct hpsb_host *host, int channel, quadlet_t * data,
301 size_t length)
302{
303 unsigned long flags;
304 struct host_info *hi;
305 struct file_info *fi;
306 struct pending_request *req, *req_next;
307 struct iso_block_store *ibs = NULL;
308 LIST_HEAD(reqs);
309
310 if ((atomic_read(&iso_buffer_size) + length) > iso_buffer_max) {
311 HPSB_INFO("dropped iso packet");
312 return;
313 }
314
315 spin_lock_irqsave(&host_info_lock, flags);
316 hi = find_host_info(host);
317
318 if (hi != NULL) {
319 list_for_each_entry(fi, &hi->file_info_list, list) {
320 if (!(fi->listen_channels & (1ULL << channel)))
321 continue;
322
323 req = __alloc_pending_request(GFP_ATOMIC);
324 if (!req)
325 break;
326
327 if (!ibs) {
328 ibs = kmalloc(sizeof(*ibs) + length,
329 GFP_ATOMIC);
330 if (!ibs) {
331 kfree(req);
332 break;
333 }
334
335 atomic_add(length, &iso_buffer_size);
336 atomic_set(&ibs->refcount, 0);
337 ibs->data_size = length;
338 memcpy(ibs->data, data, length);
339 }
340
341 atomic_inc(&ibs->refcount);
342
343 req->file_info = fi;
344 req->ibs = ibs;
345 req->data = ibs->data;
346 req->req.type = RAW1394_REQ_ISO_RECEIVE;
347 req->req.generation = get_hpsb_generation(host);
348 req->req.misc = 0;
349 req->req.recvb = ptr2int(fi->iso_buffer);
350 req->req.length = min(length, fi->iso_buffer_length);
351
352 list_add_tail(&req->list, &reqs);
353 }
354 }
355 spin_unlock_irqrestore(&host_info_lock, flags);
356
357 list_for_each_entry_safe(req, req_next, &reqs, list)
358 queue_complete_req(req);
359}
360
361static void fcp_request(struct hpsb_host *host, int nodeid, int direction, 285static void fcp_request(struct hpsb_host *host, int nodeid, int direction,
362 int cts, u8 * data, size_t length) 286 int cts, u8 * data, size_t length)
363{ 287{
@@ -434,7 +358,11 @@ struct compat_raw1394_req {
434 358
435 __u64 sendb; 359 __u64 sendb;
436 __u64 recvb; 360 __u64 recvb;
437} __attribute__((packed)); 361}
362#if defined(CONFIG_X86_64) || defined(CONFIG_IA64)
363__attribute__((packed))
364#endif
365;
438 366
439static const char __user *raw1394_compat_write(const char __user *buf) 367static const char __user *raw1394_compat_write(const char __user *buf)
440{ 368{
@@ -459,7 +387,7 @@ static const char __user *raw1394_compat_write(const char __user *buf)
459static int 387static int
460raw1394_compat_read(const char __user *buf, struct raw1394_request *r) 388raw1394_compat_read(const char __user *buf, struct raw1394_request *r)
461{ 389{
462 struct compat_raw1394_req __user *cr = (typeof(cr)) r; 390 struct compat_raw1394_req __user *cr = (typeof(cr)) buf;
463 if (!access_ok(VERIFY_WRITE, cr, sizeof(struct compat_raw1394_req)) || 391 if (!access_ok(VERIFY_WRITE, cr, sizeof(struct compat_raw1394_req)) ||
464 P(type) || 392 P(type) ||
465 P(error) || 393 P(error) ||
@@ -587,7 +515,7 @@ static int state_opened(struct file_info *fi, struct pending_request *req)
587 515
588 req->req.length = 0; 516 req->req.length = 0;
589 queue_complete_req(req); 517 queue_complete_req(req);
590 return sizeof(struct raw1394_request); 518 return 0;
591} 519}
592 520
593static int state_initialized(struct file_info *fi, struct pending_request *req) 521static int state_initialized(struct file_info *fi, struct pending_request *req)
@@ -601,7 +529,7 @@ static int state_initialized(struct file_info *fi, struct pending_request *req)
601 req->req.generation = atomic_read(&internal_generation); 529 req->req.generation = atomic_read(&internal_generation);
602 req->req.length = 0; 530 req->req.length = 0;
603 queue_complete_req(req); 531 queue_complete_req(req);
604 return sizeof(struct raw1394_request); 532 return 0;
605 } 533 }
606 534
607 switch (req->req.type) { 535 switch (req->req.type) {
@@ -673,44 +601,7 @@ out_set_card:
673 } 601 }
674 602
675 queue_complete_req(req); 603 queue_complete_req(req);
676 return sizeof(struct raw1394_request); 604 return 0;
677}
678
679static void handle_iso_listen(struct file_info *fi, struct pending_request *req)
680{
681 int channel = req->req.misc;
682
683 if ((channel > 63) || (channel < -64)) {
684 req->req.error = RAW1394_ERROR_INVALID_ARG;
685 } else if (channel >= 0) {
686 /* allocate channel req.misc */
687 if (fi->listen_channels & (1ULL << channel)) {
688 req->req.error = RAW1394_ERROR_ALREADY;
689 } else {
690 if (hpsb_listen_channel
691 (&raw1394_highlevel, fi->host, channel)) {
692 req->req.error = RAW1394_ERROR_ALREADY;
693 } else {
694 fi->listen_channels |= 1ULL << channel;
695 fi->iso_buffer = int2ptr(req->req.recvb);
696 fi->iso_buffer_length = req->req.length;
697 }
698 }
699 } else {
700 /* deallocate channel (one's complement neg) req.misc */
701 channel = ~channel;
702
703 if (fi->listen_channels & (1ULL << channel)) {
704 hpsb_unlisten_channel(&raw1394_highlevel, fi->host,
705 channel);
706 fi->listen_channels &= ~(1ULL << channel);
707 } else {
708 req->req.error = RAW1394_ERROR_INVALID_ARG;
709 }
710 }
711
712 req->req.length = 0;
713 queue_complete_req(req);
714} 605}
715 606
716static void handle_fcp_listen(struct file_info *fi, struct pending_request *req) 607static void handle_fcp_listen(struct file_info *fi, struct pending_request *req)
@@ -865,7 +756,7 @@ static int handle_async_request(struct file_info *fi,
865 if (req->req.error) { 756 if (req->req.error) {
866 req->req.length = 0; 757 req->req.length = 0;
867 queue_complete_req(req); 758 queue_complete_req(req);
868 return sizeof(struct raw1394_request); 759 return 0;
869 } 760 }
870 761
871 hpsb_set_packet_complete_task(packet, 762 hpsb_set_packet_complete_task(packet,
@@ -883,51 +774,7 @@ static int handle_async_request(struct file_info *fi,
883 hpsb_free_tlabel(packet); 774 hpsb_free_tlabel(packet);
884 queue_complete_req(req); 775 queue_complete_req(req);
885 } 776 }
886 return sizeof(struct raw1394_request); 777 return 0;
887}
888
889static int handle_iso_send(struct file_info *fi, struct pending_request *req,
890 int channel)
891{
892 unsigned long flags;
893 struct hpsb_packet *packet;
894
895 packet = hpsb_make_isopacket(fi->host, req->req.length, channel & 0x3f,
896 (req->req.misc >> 16) & 0x3,
897 req->req.misc & 0xf);
898 if (!packet)
899 return -ENOMEM;
900
901 packet->speed_code = req->req.address & 0x3;
902
903 req->packet = packet;
904
905 if (copy_from_user(packet->data, int2ptr(req->req.sendb),
906 req->req.length)) {
907 req->req.error = RAW1394_ERROR_MEMFAULT;
908 req->req.length = 0;
909 queue_complete_req(req);
910 return sizeof(struct raw1394_request);
911 }
912
913 req->req.length = 0;
914 hpsb_set_packet_complete_task(packet,
915 (void (*)(void *))queue_complete_req,
916 req);
917
918 spin_lock_irqsave(&fi->reqlists_lock, flags);
919 list_add_tail(&req->list, &fi->req_pending);
920 spin_unlock_irqrestore(&fi->reqlists_lock, flags);
921
922 /* Update the generation of the packet just before sending. */
923 packet->generation = req->req.generation;
924
925 if (hpsb_send_packet(packet) < 0) {
926 req->req.error = RAW1394_ERROR_SEND_ERROR;
927 queue_complete_req(req);
928 }
929
930 return sizeof(struct raw1394_request);
931} 778}
932 779
933static int handle_async_send(struct file_info *fi, struct pending_request *req) 780static int handle_async_send(struct file_info *fi, struct pending_request *req)
@@ -943,7 +790,7 @@ static int handle_async_send(struct file_info *fi, struct pending_request *req)
943 req->req.error = RAW1394_ERROR_INVALID_ARG; 790 req->req.error = RAW1394_ERROR_INVALID_ARG;
944 req->req.length = 0; 791 req->req.length = 0;
945 queue_complete_req(req); 792 queue_complete_req(req);
946 return sizeof(struct raw1394_request); 793 return 0;
947 } 794 }
948 795
949 data_size = req->req.length - header_length; 796 data_size = req->req.length - header_length;
@@ -957,7 +804,7 @@ static int handle_async_send(struct file_info *fi, struct pending_request *req)
957 req->req.error = RAW1394_ERROR_MEMFAULT; 804 req->req.error = RAW1394_ERROR_MEMFAULT;
958 req->req.length = 0; 805 req->req.length = 0;
959 queue_complete_req(req); 806 queue_complete_req(req);
960 return sizeof(struct raw1394_request); 807 return 0;
961 } 808 }
962 809
963 if (copy_from_user 810 if (copy_from_user
@@ -966,7 +813,7 @@ static int handle_async_send(struct file_info *fi, struct pending_request *req)
966 req->req.error = RAW1394_ERROR_MEMFAULT; 813 req->req.error = RAW1394_ERROR_MEMFAULT;
967 req->req.length = 0; 814 req->req.length = 0;
968 queue_complete_req(req); 815 queue_complete_req(req);
969 return sizeof(struct raw1394_request); 816 return 0;
970 } 817 }
971 818
972 packet->type = hpsb_async; 819 packet->type = hpsb_async;
@@ -994,7 +841,7 @@ static int handle_async_send(struct file_info *fi, struct pending_request *req)
994 queue_complete_req(req); 841 queue_complete_req(req);
995 } 842 }
996 843
997 return sizeof(struct raw1394_request); 844 return 0;
998} 845}
999 846
1000static int arm_read(struct hpsb_host *host, int nodeid, quadlet_t * buffer, 847static int arm_read(struct hpsb_host *host, int nodeid, quadlet_t * buffer,
@@ -1869,7 +1716,7 @@ static int arm_register(struct file_info *fi, struct pending_request *req)
1869 spin_lock_irqsave(&host_info_lock, flags); 1716 spin_lock_irqsave(&host_info_lock, flags);
1870 list_add_tail(&addr->addr_list, &fi->addr_list); 1717 list_add_tail(&addr->addr_list, &fi->addr_list);
1871 spin_unlock_irqrestore(&host_info_lock, flags); 1718 spin_unlock_irqrestore(&host_info_lock, flags);
1872 return sizeof(struct raw1394_request); 1719 return 0;
1873 } 1720 }
1874 retval = 1721 retval =
1875 hpsb_register_addrspace(&raw1394_highlevel, fi->host, &arm_ops, 1722 hpsb_register_addrspace(&raw1394_highlevel, fi->host, &arm_ops,
@@ -1887,7 +1734,7 @@ static int arm_register(struct file_info *fi, struct pending_request *req)
1887 return (-EALREADY); 1734 return (-EALREADY);
1888 } 1735 }
1889 free_pending_request(req); /* immediate success or fail */ 1736 free_pending_request(req); /* immediate success or fail */
1890 return sizeof(struct raw1394_request); 1737 return 0;
1891} 1738}
1892 1739
1893static int arm_unregister(struct file_info *fi, struct pending_request *req) 1740static int arm_unregister(struct file_info *fi, struct pending_request *req)
@@ -1955,7 +1802,7 @@ static int arm_unregister(struct file_info *fi, struct pending_request *req)
1955 vfree(addr->addr_space_buffer); 1802 vfree(addr->addr_space_buffer);
1956 kfree(addr); 1803 kfree(addr);
1957 free_pending_request(req); /* immediate success or fail */ 1804 free_pending_request(req); /* immediate success or fail */
1958 return sizeof(struct raw1394_request); 1805 return 0;
1959 } 1806 }
1960 retval = 1807 retval =
1961 hpsb_unregister_addrspace(&raw1394_highlevel, fi->host, 1808 hpsb_unregister_addrspace(&raw1394_highlevel, fi->host,
@@ -1971,7 +1818,7 @@ static int arm_unregister(struct file_info *fi, struct pending_request *req)
1971 vfree(addr->addr_space_buffer); 1818 vfree(addr->addr_space_buffer);
1972 kfree(addr); 1819 kfree(addr);
1973 free_pending_request(req); /* immediate success or fail */ 1820 free_pending_request(req); /* immediate success or fail */
1974 return sizeof(struct raw1394_request); 1821 return 0;
1975} 1822}
1976 1823
1977/* Copy data from ARM buffer(s) to user buffer. */ 1824/* Copy data from ARM buffer(s) to user buffer. */
@@ -2013,7 +1860,7 @@ static int arm_get_buf(struct file_info *fi, struct pending_request *req)
2013 * queue no response, and therefore nobody 1860 * queue no response, and therefore nobody
2014 * will free it. */ 1861 * will free it. */
2015 free_pending_request(req); 1862 free_pending_request(req);
2016 return sizeof(struct raw1394_request); 1863 return 0;
2017 } else { 1864 } else {
2018 DBGMSG("arm_get_buf request exceeded mapping"); 1865 DBGMSG("arm_get_buf request exceeded mapping");
2019 spin_unlock_irqrestore(&host_info_lock, flags); 1866 spin_unlock_irqrestore(&host_info_lock, flags);
@@ -2065,7 +1912,7 @@ static int arm_set_buf(struct file_info *fi, struct pending_request *req)
2065 * queue no response, and therefore nobody 1912 * queue no response, and therefore nobody
2066 * will free it. */ 1913 * will free it. */
2067 free_pending_request(req); 1914 free_pending_request(req);
2068 return sizeof(struct raw1394_request); 1915 return 0;
2069 } else { 1916 } else {
2070 DBGMSG("arm_set_buf request exceeded mapping"); 1917 DBGMSG("arm_set_buf request exceeded mapping");
2071 spin_unlock_irqrestore(&host_info_lock, flags); 1918 spin_unlock_irqrestore(&host_info_lock, flags);
@@ -2086,7 +1933,7 @@ static int reset_notification(struct file_info *fi, struct pending_request *req)
2086 (req->req.misc == RAW1394_NOTIFY_ON)) { 1933 (req->req.misc == RAW1394_NOTIFY_ON)) {
2087 fi->notification = (u8) req->req.misc; 1934 fi->notification = (u8) req->req.misc;
2088 free_pending_request(req); /* we have to free the request, because we queue no response, and therefore nobody will free it */ 1935 free_pending_request(req); /* we have to free the request, because we queue no response, and therefore nobody will free it */
2089 return sizeof(struct raw1394_request); 1936 return 0;
2090 } 1937 }
2091 /* error EINVAL (22) invalid argument */ 1938 /* error EINVAL (22) invalid argument */
2092 return (-EINVAL); 1939 return (-EINVAL);
@@ -2119,12 +1966,12 @@ static int write_phypacket(struct file_info *fi, struct pending_request *req)
2119 req->req.length = 0; 1966 req->req.length = 0;
2120 queue_complete_req(req); 1967 queue_complete_req(req);
2121 } 1968 }
2122 return sizeof(struct raw1394_request); 1969 return 0;
2123} 1970}
2124 1971
2125static int get_config_rom(struct file_info *fi, struct pending_request *req) 1972static int get_config_rom(struct file_info *fi, struct pending_request *req)
2126{ 1973{
2127 int ret = sizeof(struct raw1394_request); 1974 int ret = 0;
2128 quadlet_t *data = kmalloc(req->req.length, GFP_KERNEL); 1975 quadlet_t *data = kmalloc(req->req.length, GFP_KERNEL);
2129 int status; 1976 int status;
2130 1977
@@ -2154,7 +2001,7 @@ static int get_config_rom(struct file_info *fi, struct pending_request *req)
2154 2001
2155static int update_config_rom(struct file_info *fi, struct pending_request *req) 2002static int update_config_rom(struct file_info *fi, struct pending_request *req)
2156{ 2003{
2157 int ret = sizeof(struct raw1394_request); 2004 int ret = 0;
2158 quadlet_t *data = kmalloc(req->req.length, GFP_KERNEL); 2005 quadlet_t *data = kmalloc(req->req.length, GFP_KERNEL);
2159 if (!data) 2006 if (!data)
2160 return -ENOMEM; 2007 return -ENOMEM;
@@ -2221,7 +2068,7 @@ static int modify_config_rom(struct file_info *fi, struct pending_request *req)
2221 2068
2222 hpsb_update_config_rom_image(fi->host); 2069 hpsb_update_config_rom_image(fi->host);
2223 free_pending_request(req); 2070 free_pending_request(req);
2224 return sizeof(struct raw1394_request); 2071 return 0;
2225 } 2072 }
2226 } 2073 }
2227 2074
@@ -2286,7 +2133,7 @@ static int modify_config_rom(struct file_info *fi, struct pending_request *req)
2286 /* we have to free the request, because we queue no response, 2133 /* we have to free the request, because we queue no response,
2287 * and therefore nobody will free it */ 2134 * and therefore nobody will free it */
2288 free_pending_request(req); 2135 free_pending_request(req);
2289 return sizeof(struct raw1394_request); 2136 return 0;
2290 } else { 2137 } else {
2291 for (dentry = 2138 for (dentry =
2292 fi->csr1212_dirs[dr]->value.directory.dentries_head; 2139 fi->csr1212_dirs[dr]->value.directory.dentries_head;
@@ -2311,11 +2158,7 @@ static int state_connected(struct file_info *fi, struct pending_request *req)
2311 2158
2312 case RAW1394_REQ_ECHO: 2159 case RAW1394_REQ_ECHO:
2313 queue_complete_req(req); 2160 queue_complete_req(req);
2314 return sizeof(struct raw1394_request); 2161 return 0;
2315
2316 case RAW1394_REQ_ISO_SEND:
2317 print_old_iso_deprecation();
2318 return handle_iso_send(fi, req, node);
2319 2162
2320 case RAW1394_REQ_ARM_REGISTER: 2163 case RAW1394_REQ_ARM_REGISTER:
2321 return arm_register(fi, req); 2164 return arm_register(fi, req);
@@ -2332,27 +2175,30 @@ static int state_connected(struct file_info *fi, struct pending_request *req)
2332 case RAW1394_REQ_RESET_NOTIFY: 2175 case RAW1394_REQ_RESET_NOTIFY:
2333 return reset_notification(fi, req); 2176 return reset_notification(fi, req);
2334 2177
2178 case RAW1394_REQ_ISO_SEND:
2335 case RAW1394_REQ_ISO_LISTEN: 2179 case RAW1394_REQ_ISO_LISTEN:
2336 print_old_iso_deprecation(); 2180 printk(KERN_DEBUG "raw1394: old iso ABI has been removed\n");
2337 handle_iso_listen(fi, req); 2181 req->req.error = RAW1394_ERROR_COMPAT;
2338 return sizeof(struct raw1394_request); 2182 req->req.misc = RAW1394_KERNELAPI_VERSION;
2183 queue_complete_req(req);
2184 return 0;
2339 2185
2340 case RAW1394_REQ_FCP_LISTEN: 2186 case RAW1394_REQ_FCP_LISTEN:
2341 handle_fcp_listen(fi, req); 2187 handle_fcp_listen(fi, req);
2342 return sizeof(struct raw1394_request); 2188 return 0;
2343 2189
2344 case RAW1394_REQ_RESET_BUS: 2190 case RAW1394_REQ_RESET_BUS:
2345 if (req->req.misc == RAW1394_LONG_RESET) { 2191 if (req->req.misc == RAW1394_LONG_RESET) {
2346 DBGMSG("busreset called (type: LONG)"); 2192 DBGMSG("busreset called (type: LONG)");
2347 hpsb_reset_bus(fi->host, LONG_RESET); 2193 hpsb_reset_bus(fi->host, LONG_RESET);
2348 free_pending_request(req); /* we have to free the request, because we queue no response, and therefore nobody will free it */ 2194 free_pending_request(req); /* we have to free the request, because we queue no response, and therefore nobody will free it */
2349 return sizeof(struct raw1394_request); 2195 return 0;
2350 } 2196 }
2351 if (req->req.misc == RAW1394_SHORT_RESET) { 2197 if (req->req.misc == RAW1394_SHORT_RESET) {
2352 DBGMSG("busreset called (type: SHORT)"); 2198 DBGMSG("busreset called (type: SHORT)");
2353 hpsb_reset_bus(fi->host, SHORT_RESET); 2199 hpsb_reset_bus(fi->host, SHORT_RESET);
2354 free_pending_request(req); /* we have to free the request, because we queue no response, and therefore nobody will free it */ 2200 free_pending_request(req); /* we have to free the request, because we queue no response, and therefore nobody will free it */
2355 return sizeof(struct raw1394_request); 2201 return 0;
2356 } 2202 }
2357 /* error EINVAL (22) invalid argument */ 2203 /* error EINVAL (22) invalid argument */
2358 return (-EINVAL); 2204 return (-EINVAL);
@@ -2371,7 +2217,7 @@ static int state_connected(struct file_info *fi, struct pending_request *req)
2371 req->req.generation = get_hpsb_generation(fi->host); 2217 req->req.generation = get_hpsb_generation(fi->host);
2372 req->req.length = 0; 2218 req->req.length = 0;
2373 queue_complete_req(req); 2219 queue_complete_req(req);
2374 return sizeof(struct raw1394_request); 2220 return 0;
2375 } 2221 }
2376 2222
2377 switch (req->req.type) { 2223 switch (req->req.type) {
@@ -2384,7 +2230,7 @@ static int state_connected(struct file_info *fi, struct pending_request *req)
2384 if (req->req.length == 0) { 2230 if (req->req.length == 0) {
2385 req->req.error = RAW1394_ERROR_INVALID_ARG; 2231 req->req.error = RAW1394_ERROR_INVALID_ARG;
2386 queue_complete_req(req); 2232 queue_complete_req(req);
2387 return sizeof(struct raw1394_request); 2233 return 0;
2388 } 2234 }
2389 2235
2390 return handle_async_request(fi, req, node); 2236 return handle_async_request(fi, req, node);
@@ -2395,7 +2241,7 @@ static ssize_t raw1394_write(struct file *file, const char __user * buffer,
2395{ 2241{
2396 struct file_info *fi = (struct file_info *)file->private_data; 2242 struct file_info *fi = (struct file_info *)file->private_data;
2397 struct pending_request *req; 2243 struct pending_request *req;
2398 ssize_t retval = 0; 2244 ssize_t retval = -EBADFD;
2399 2245
2400#ifdef CONFIG_COMPAT 2246#ifdef CONFIG_COMPAT
2401 if (count == sizeof(struct compat_raw1394_req) && 2247 if (count == sizeof(struct compat_raw1394_req) &&
@@ -2437,6 +2283,9 @@ static ssize_t raw1394_write(struct file *file, const char __user * buffer,
2437 2283
2438 if (retval < 0) { 2284 if (retval < 0) {
2439 free_pending_request(req); 2285 free_pending_request(req);
2286 } else {
2287 BUG_ON(retval);
2288 retval = count;
2440 } 2289 }
2441 2290
2442 return retval; 2291 return retval;
@@ -2802,6 +2651,103 @@ static int raw1394_ioctl(struct inode *inode, struct file *file,
2802 return -EINVAL; 2651 return -EINVAL;
2803} 2652}
2804 2653
2654#ifdef CONFIG_COMPAT
2655struct raw1394_iso_packets32 {
2656 __u32 n_packets;
2657 compat_uptr_t infos;
2658} __attribute__((packed));
2659
2660struct raw1394_cycle_timer32 {
2661 __u32 cycle_timer;
2662 __u64 local_time;
2663}
2664#if defined(CONFIG_X86_64) || defined(CONFIG_IA64)
2665__attribute__((packed))
2666#endif
2667;
2668
2669#define RAW1394_IOC_ISO_RECV_PACKETS32 \
2670 _IOW ('#', 0x25, struct raw1394_iso_packets32)
2671#define RAW1394_IOC_ISO_XMIT_PACKETS32 \
2672 _IOW ('#', 0x27, struct raw1394_iso_packets32)
2673#define RAW1394_IOC_GET_CYCLE_TIMER32 \
2674 _IOR ('#', 0x30, struct raw1394_cycle_timer32)
2675
2676static long raw1394_iso_xmit_recv_packets32(struct file *file, unsigned int cmd,
2677 struct raw1394_iso_packets32 __user *arg)
2678{
2679 compat_uptr_t infos32;
2680 void *infos;
2681 long err = -EFAULT;
2682 struct raw1394_iso_packets __user *dst = compat_alloc_user_space(sizeof(struct raw1394_iso_packets));
2683
2684 if (!copy_in_user(&dst->n_packets, &arg->n_packets, sizeof arg->n_packets) &&
2685 !copy_from_user(&infos32, &arg->infos, sizeof infos32)) {
2686 infos = compat_ptr(infos32);
2687 if (!copy_to_user(&dst->infos, &infos, sizeof infos))
2688 err = raw1394_ioctl(NULL, file, cmd, (unsigned long)dst);
2689 }
2690 return err;
2691}
2692
2693static long raw1394_read_cycle_timer32(struct file_info *fi, void __user * uaddr)
2694{
2695 struct raw1394_cycle_timer32 ct;
2696 int err;
2697
2698 err = hpsb_read_cycle_timer(fi->host, &ct.cycle_timer, &ct.local_time);
2699 if (!err)
2700 if (copy_to_user(uaddr, &ct, sizeof(ct)))
2701 err = -EFAULT;
2702 return err;
2703}
2704
2705static long raw1394_compat_ioctl(struct file *file,
2706 unsigned int cmd, unsigned long arg)
2707{
2708 struct file_info *fi = file->private_data;
2709 void __user *argp = (void __user *)arg;
2710 long err;
2711
2712 lock_kernel();
2713 switch (cmd) {
2714 /* These requests have same format as long as 'int' has same size. */
2715 case RAW1394_IOC_ISO_RECV_INIT:
2716 case RAW1394_IOC_ISO_RECV_START:
2717 case RAW1394_IOC_ISO_RECV_LISTEN_CHANNEL:
2718 case RAW1394_IOC_ISO_RECV_UNLISTEN_CHANNEL:
2719 case RAW1394_IOC_ISO_RECV_SET_CHANNEL_MASK:
2720 case RAW1394_IOC_ISO_RECV_RELEASE_PACKETS:
2721 case RAW1394_IOC_ISO_RECV_FLUSH:
2722 case RAW1394_IOC_ISO_XMIT_RECV_STOP:
2723 case RAW1394_IOC_ISO_XMIT_INIT:
2724 case RAW1394_IOC_ISO_XMIT_START:
2725 case RAW1394_IOC_ISO_XMIT_SYNC:
2726 case RAW1394_IOC_ISO_GET_STATUS:
2727 case RAW1394_IOC_ISO_SHUTDOWN:
2728 case RAW1394_IOC_ISO_QUEUE_ACTIVITY:
2729 err = raw1394_ioctl(NULL, file, cmd, arg);
2730 break;
2731 /* These request have different format. */
2732 case RAW1394_IOC_ISO_RECV_PACKETS32:
2733 err = raw1394_iso_xmit_recv_packets32(file, RAW1394_IOC_ISO_RECV_PACKETS, argp);
2734 break;
2735 case RAW1394_IOC_ISO_XMIT_PACKETS32:
2736 err = raw1394_iso_xmit_recv_packets32(file, RAW1394_IOC_ISO_XMIT_PACKETS, argp);
2737 break;
2738 case RAW1394_IOC_GET_CYCLE_TIMER32:
2739 err = raw1394_read_cycle_timer32(fi, argp);
2740 break;
2741 default:
2742 err = -EINVAL;
2743 break;
2744 }
2745 unlock_kernel();
2746
2747 return err;
2748}
2749#endif
2750
2805static unsigned int raw1394_poll(struct file *file, poll_table * pt) 2751static unsigned int raw1394_poll(struct file *file, poll_table * pt)
2806{ 2752{
2807 struct file_info *fi = file->private_data; 2753 struct file_info *fi = file->private_data;
@@ -2861,14 +2807,7 @@ static int raw1394_release(struct inode *inode, struct file *file)
2861 if (fi->iso_state != RAW1394_ISO_INACTIVE) 2807 if (fi->iso_state != RAW1394_ISO_INACTIVE)
2862 raw1394_iso_shutdown(fi); 2808 raw1394_iso_shutdown(fi);
2863 2809
2864 for (i = 0; i < 64; i++) {
2865 if (fi->listen_channels & (1ULL << i)) {
2866 hpsb_unlisten_channel(&raw1394_highlevel, fi->host, i);
2867 }
2868 }
2869
2870 spin_lock_irqsave(&host_info_lock, flags); 2810 spin_lock_irqsave(&host_info_lock, flags);
2871 fi->listen_channels = 0;
2872 2811
2873 fail = 0; 2812 fail = 0;
2874 /* set address-entries invalid */ 2813 /* set address-entries invalid */
@@ -3030,7 +2969,6 @@ static struct hpsb_highlevel raw1394_highlevel = {
3030 .add_host = add_host, 2969 .add_host = add_host,
3031 .remove_host = remove_host, 2970 .remove_host = remove_host,
3032 .host_reset = host_reset, 2971 .host_reset = host_reset,
3033 .iso_receive = iso_receive,
3034 .fcp_request = fcp_request, 2972 .fcp_request = fcp_request,
3035}; 2973};
3036 2974
@@ -3041,7 +2979,9 @@ static const struct file_operations raw1394_fops = {
3041 .write = raw1394_write, 2979 .write = raw1394_write,
3042 .mmap = raw1394_mmap, 2980 .mmap = raw1394_mmap,
3043 .ioctl = raw1394_ioctl, 2981 .ioctl = raw1394_ioctl,
3044 // .compat_ioctl = ... someone needs to do this 2982#ifdef CONFIG_COMPAT
2983 .compat_ioctl = raw1394_compat_ioctl,
2984#endif
3045 .poll = raw1394_poll, 2985 .poll = raw1394_poll,
3046 .open = raw1394_open, 2986 .open = raw1394_open,
3047 .release = raw1394_release, 2987 .release = raw1394_release,
@@ -3054,9 +2994,9 @@ static int __init init_raw1394(void)
3054 hpsb_register_highlevel(&raw1394_highlevel); 2994 hpsb_register_highlevel(&raw1394_highlevel);
3055 2995
3056 if (IS_ERR 2996 if (IS_ERR
3057 (class_device_create 2997 (device_create(
3058 (hpsb_protocol_class, NULL, 2998 hpsb_protocol_class, NULL,
3059 MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16), NULL, 2999 MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16),
3060 RAW1394_DEVICE_NAME))) { 3000 RAW1394_DEVICE_NAME))) {
3061 ret = -EFAULT; 3001 ret = -EFAULT;
3062 goto out_unreg; 3002 goto out_unreg;
@@ -3083,9 +3023,9 @@ static int __init init_raw1394(void)
3083 goto out; 3023 goto out;
3084 3024
3085 out_dev: 3025 out_dev:
3086 class_device_destroy(hpsb_protocol_class, 3026 device_destroy(hpsb_protocol_class,
3087 MKDEV(IEEE1394_MAJOR, 3027 MKDEV(IEEE1394_MAJOR,
3088 IEEE1394_MINOR_BLOCK_RAW1394 * 16)); 3028 IEEE1394_MINOR_BLOCK_RAW1394 * 16));
3089 out_unreg: 3029 out_unreg:
3090 hpsb_unregister_highlevel(&raw1394_highlevel); 3030 hpsb_unregister_highlevel(&raw1394_highlevel);
3091 out: 3031 out:
@@ -3094,9 +3034,9 @@ static int __init init_raw1394(void)
3094 3034
3095static void __exit cleanup_raw1394(void) 3035static void __exit cleanup_raw1394(void)
3096{ 3036{
3097 class_device_destroy(hpsb_protocol_class, 3037 device_destroy(hpsb_protocol_class,
3098 MKDEV(IEEE1394_MAJOR, 3038 MKDEV(IEEE1394_MAJOR,
3099 IEEE1394_MINOR_BLOCK_RAW1394 * 16)); 3039 IEEE1394_MINOR_BLOCK_RAW1394 * 16));
3100 cdev_del(&raw1394_cdev); 3040 cdev_del(&raw1394_cdev);
3101 hpsb_unregister_highlevel(&raw1394_highlevel); 3041 hpsb_unregister_highlevel(&raw1394_highlevel);
3102 hpsb_unregister_protocol(&raw1394_driver); 3042 hpsb_unregister_protocol(&raw1394_driver);
diff --git a/drivers/ieee1394/raw1394.h b/drivers/ieee1394/raw1394.h
index 7bd22ee1afbb..963ac20373d2 100644
--- a/drivers/ieee1394/raw1394.h
+++ b/drivers/ieee1394/raw1394.h
@@ -17,11 +17,11 @@
17#define RAW1394_REQ_ASYNC_WRITE 101 17#define RAW1394_REQ_ASYNC_WRITE 101
18#define RAW1394_REQ_LOCK 102 18#define RAW1394_REQ_LOCK 102
19#define RAW1394_REQ_LOCK64 103 19#define RAW1394_REQ_LOCK64 103
20#define RAW1394_REQ_ISO_SEND 104 20#define RAW1394_REQ_ISO_SEND 104 /* removed ABI, now a no-op */
21#define RAW1394_REQ_ASYNC_SEND 105 21#define RAW1394_REQ_ASYNC_SEND 105
22#define RAW1394_REQ_ASYNC_STREAM 106 22#define RAW1394_REQ_ASYNC_STREAM 106
23 23
24#define RAW1394_REQ_ISO_LISTEN 200 24#define RAW1394_REQ_ISO_LISTEN 200 /* removed ABI, now a no-op */
25#define RAW1394_REQ_FCP_LISTEN 201 25#define RAW1394_REQ_FCP_LISTEN 201
26#define RAW1394_REQ_RESET_BUS 202 26#define RAW1394_REQ_RESET_BUS 202
27#define RAW1394_REQ_GET_ROM 203 27#define RAW1394_REQ_GET_ROM 203
diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c
index 3f873cc7e247..e0c385a3b450 100644
--- a/drivers/ieee1394/sbp2.c
+++ b/drivers/ieee1394/sbp2.c
@@ -118,14 +118,13 @@ MODULE_PARM_DESC(max_speed, "Force max speed "
118 "(3 = 800Mb/s, 2 = 400Mb/s, 1 = 200Mb/s, 0 = 100Mb/s)"); 118 "(3 = 800Mb/s, 2 = 400Mb/s, 1 = 200Mb/s, 0 = 100Mb/s)");
119 119
120/* 120/*
121 * Set serialize_io to 1 if you'd like only one scsi command sent 121 * Set serialize_io to 0 or N to use dynamically appended lists of command ORBs.
122 * down to us at a time (debugging). This might be necessary for very 122 * This is and always has been buggy in multiple subtle ways. See above TODOs.
123 * badly behaved sbp2 devices.
124 */ 123 */
125static int sbp2_serialize_io = 1; 124static int sbp2_serialize_io = 1;
126module_param_named(serialize_io, sbp2_serialize_io, int, 0444); 125module_param_named(serialize_io, sbp2_serialize_io, bool, 0444);
127MODULE_PARM_DESC(serialize_io, "Serialize I/O coming from scsi drivers " 126MODULE_PARM_DESC(serialize_io, "Serialize requests coming from SCSI drivers "
128 "(default = 1, faster = 0)"); 127 "(default = Y, faster but buggy = N)");
129 128
130/* 129/*
131 * Bump up max_sectors if you'd like to support very large sized 130 * Bump up max_sectors if you'd like to support very large sized
@@ -154,9 +153,9 @@ MODULE_PARM_DESC(max_sectors, "Change max sectors per I/O supported "
154 * are possible on OXFW911 and newer Oxsemi bridges. 153 * are possible on OXFW911 and newer Oxsemi bridges.
155 */ 154 */
156static int sbp2_exclusive_login = 1; 155static int sbp2_exclusive_login = 1;
157module_param_named(exclusive_login, sbp2_exclusive_login, int, 0644); 156module_param_named(exclusive_login, sbp2_exclusive_login, bool, 0644);
158MODULE_PARM_DESC(exclusive_login, "Exclusive login to sbp2 device " 157MODULE_PARM_DESC(exclusive_login, "Exclusive login to sbp2 device "
159 "(default = 1)"); 158 "(default = Y, use N for concurrent initiators)");
160 159
161/* 160/*
162 * If any of the following workarounds is required for your device to work, 161 * If any of the following workarounds is required for your device to work,
diff --git a/drivers/ieee1394/sbp2.h b/drivers/ieee1394/sbp2.h
index 44402b9d82a8..333a4bb76743 100644
--- a/drivers/ieee1394/sbp2.h
+++ b/drivers/ieee1394/sbp2.h
@@ -67,7 +67,7 @@ struct sbp2_command_orb {
67#define ORB_SET_LUN(v) ((v) & 0xffff) 67#define ORB_SET_LUN(v) ((v) & 0xffff)
68#define ORB_SET_FUNCTION(v) (((v) & 0xf) << 16) 68#define ORB_SET_FUNCTION(v) (((v) & 0xf) << 16)
69#define ORB_SET_RECONNECT(v) (((v) & 0xf) << 20) 69#define ORB_SET_RECONNECT(v) (((v) & 0xf) << 20)
70#define ORB_SET_EXCLUSIVE(v) (((v) & 0x1) << 28) 70#define ORB_SET_EXCLUSIVE(v) ((v) ? 1 << 28 : 0)
71#define ORB_SET_LOGIN_RESP_LENGTH(v) ((v) & 0xffff) 71#define ORB_SET_LOGIN_RESP_LENGTH(v) ((v) & 0xffff)
72#define ORB_SET_PASSWD_LENGTH(v) (((v) & 0xffff) << 16) 72#define ORB_SET_PASSWD_LENGTH(v) (((v) & 0xffff) << 16)
73 73
diff --git a/drivers/ieee1394/video1394.c b/drivers/ieee1394/video1394.c
index 87ebd0846c34..bd28adfd7afc 100644
--- a/drivers/ieee1394/video1394.c
+++ b/drivers/ieee1394/video1394.c
@@ -1340,9 +1340,9 @@ static void video1394_add_host (struct hpsb_host *host)
1340 hpsb_set_hostinfo_key(&video1394_highlevel, host, ohci->host->id); 1340 hpsb_set_hostinfo_key(&video1394_highlevel, host, ohci->host->id);
1341 1341
1342 minor = IEEE1394_MINOR_BLOCK_VIDEO1394 * 16 + ohci->host->id; 1342 minor = IEEE1394_MINOR_BLOCK_VIDEO1394 * 16 + ohci->host->id;
1343 class_device_create(hpsb_protocol_class, NULL, MKDEV( 1343 device_create(hpsb_protocol_class, NULL,
1344 IEEE1394_MAJOR, minor), 1344 MKDEV(IEEE1394_MAJOR, minor),
1345 NULL, "%s-%d", VIDEO1394_DRIVER_NAME, ohci->host->id); 1345 "%s-%d", VIDEO1394_DRIVER_NAME, ohci->host->id);
1346} 1346}
1347 1347
1348 1348
@@ -1351,8 +1351,8 @@ static void video1394_remove_host (struct hpsb_host *host)
1351 struct ti_ohci *ohci = hpsb_get_hostinfo(&video1394_highlevel, host); 1351 struct ti_ohci *ohci = hpsb_get_hostinfo(&video1394_highlevel, host);
1352 1352
1353 if (ohci) 1353 if (ohci)
1354 class_device_destroy(hpsb_protocol_class, MKDEV(IEEE1394_MAJOR, 1354 device_destroy(hpsb_protocol_class, MKDEV(IEEE1394_MAJOR,
1355 IEEE1394_MINOR_BLOCK_VIDEO1394 * 16 + ohci->host->id)); 1355 IEEE1394_MINOR_BLOCK_VIDEO1394 * 16 + ohci->host->id));
1356 return; 1356 return;
1357} 1357}
1358 1358
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index be6b93c20f60..ab4b2d9b5327 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -30,6 +30,7 @@ struct evdev {
30 wait_queue_head_t wait; 30 wait_queue_head_t wait;
31 struct evdev_client *grab; 31 struct evdev_client *grab;
32 struct list_head client_list; 32 struct list_head client_list;
33 struct device dev;
33}; 34};
34 35
35struct evdev_client { 36struct evdev_client {
@@ -94,8 +95,10 @@ static int evdev_flush(struct file *file, fl_owner_t id)
94 return input_flush_device(&evdev->handle, file); 95 return input_flush_device(&evdev->handle, file);
95} 96}
96 97
97static void evdev_free(struct evdev *evdev) 98static void evdev_free(struct device *dev)
98{ 99{
100 struct evdev *evdev = container_of(dev, struct evdev, dev);
101
99 evdev_table[evdev->minor] = NULL; 102 evdev_table[evdev->minor] = NULL;
100 kfree(evdev); 103 kfree(evdev);
101} 104}
@@ -114,12 +117,10 @@ static int evdev_release(struct inode *inode, struct file *file)
114 list_del(&client->node); 117 list_del(&client->node);
115 kfree(client); 118 kfree(client);
116 119
117 if (!--evdev->open) { 120 if (!--evdev->open && evdev->exist)
118 if (evdev->exist) 121 input_close_device(&evdev->handle);
119 input_close_device(&evdev->handle); 122
120 else 123 put_device(&evdev->dev);
121 evdev_free(evdev);
122 }
123 124
124 return 0; 125 return 0;
125} 126}
@@ -139,24 +140,32 @@ static int evdev_open(struct inode *inode, struct file *file)
139 if (!evdev || !evdev->exist) 140 if (!evdev || !evdev->exist)
140 return -ENODEV; 141 return -ENODEV;
141 142
143 get_device(&evdev->dev);
144
142 client = kzalloc(sizeof(struct evdev_client), GFP_KERNEL); 145 client = kzalloc(sizeof(struct evdev_client), GFP_KERNEL);
143 if (!client) 146 if (!client) {
144 return -ENOMEM; 147 error = -ENOMEM;
148 goto err_put_evdev;
149 }
145 150
146 client->evdev = evdev; 151 client->evdev = evdev;
147 list_add_tail(&client->node, &evdev->client_list); 152 list_add_tail(&client->node, &evdev->client_list);
148 153
149 if (!evdev->open++ && evdev->exist) { 154 if (!evdev->open++ && evdev->exist) {
150 error = input_open_device(&evdev->handle); 155 error = input_open_device(&evdev->handle);
151 if (error) { 156 if (error)
152 list_del(&client->node); 157 goto err_free_client;
153 kfree(client);
154 return error;
155 }
156 } 158 }
157 159
158 file->private_data = client; 160 file->private_data = client;
159 return 0; 161 return 0;
162
163 err_free_client:
164 list_del(&client->node);
165 kfree(client);
166 err_put_evdev:
167 put_device(&evdev->dev);
168 return error;
160} 169}
161 170
162#ifdef CONFIG_COMPAT 171#ifdef CONFIG_COMPAT
@@ -625,8 +634,6 @@ static int evdev_connect(struct input_handler *handler, struct input_dev *dev,
625 const struct input_device_id *id) 634 const struct input_device_id *id)
626{ 635{
627 struct evdev *evdev; 636 struct evdev *evdev;
628 struct class_device *cdev;
629 dev_t devt;
630 int minor; 637 int minor;
631 int error; 638 int error;
632 639
@@ -649,38 +656,32 @@ static int evdev_connect(struct input_handler *handler, struct input_dev *dev,
649 evdev->handle.name = evdev->name; 656 evdev->handle.name = evdev->name;
650 evdev->handle.handler = handler; 657 evdev->handle.handler = handler;
651 evdev->handle.private = evdev; 658 evdev->handle.private = evdev;
652 sprintf(evdev->name, "event%d", minor); 659 snprintf(evdev->name, sizeof(evdev->name), "event%d", minor);
653
654 evdev_table[minor] = evdev;
655 660
656 devt = MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor), 661 snprintf(evdev->dev.bus_id, sizeof(evdev->dev.bus_id),
662 "event%d", minor);
663 evdev->dev.class = &input_class;
664 evdev->dev.parent = &dev->dev;
665 evdev->dev.devt = MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor);
666 evdev->dev.release = evdev_free;
667 device_initialize(&evdev->dev);
657 668
658 cdev = class_device_create(&input_class, &dev->cdev, devt, 669 evdev_table[minor] = evdev;
659 dev->cdev.dev, evdev->name);
660 if (IS_ERR(cdev)) {
661 error = PTR_ERR(cdev);
662 goto err_free_evdev;
663 }
664 670
665 /* temporary symlink to keep userspace happy */ 671 error = device_add(&evdev->dev);
666 error = sysfs_create_link(&input_class.subsys.kobj,
667 &cdev->kobj, evdev->name);
668 if (error) 672 if (error)
669 goto err_cdev_destroy; 673 goto err_free_evdev;
670 674
671 error = input_register_handle(&evdev->handle); 675 error = input_register_handle(&evdev->handle);
672 if (error) 676 if (error)
673 goto err_remove_link; 677 goto err_delete_evdev;
674 678
675 return 0; 679 return 0;
676 680
677 err_remove_link: 681 err_delete_evdev:
678 sysfs_remove_link(&input_class.subsys.kobj, evdev->name); 682 device_del(&evdev->dev);
679 err_cdev_destroy:
680 class_device_destroy(&input_class, devt);
681 err_free_evdev: 683 err_free_evdev:
682 kfree(evdev); 684 put_device(&evdev->dev);
683 evdev_table[minor] = NULL;
684 return error; 685 return error;
685} 686}
686 687
@@ -690,10 +691,8 @@ static void evdev_disconnect(struct input_handle *handle)
690 struct evdev_client *client; 691 struct evdev_client *client;
691 692
692 input_unregister_handle(handle); 693 input_unregister_handle(handle);
694 device_del(&evdev->dev);
693 695
694 sysfs_remove_link(&input_class.subsys.kobj, evdev->name);
695 class_device_destroy(&input_class,
696 MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + evdev->minor));
697 evdev->exist = 0; 696 evdev->exist = 0;
698 697
699 if (evdev->open) { 698 if (evdev->open) {
@@ -702,8 +701,9 @@ static void evdev_disconnect(struct input_handle *handle)
702 list_for_each_entry(client, &evdev->client_list, node) 701 list_for_each_entry(client, &evdev->client_list, node)
703 kill_fasync(&client->fasync, SIGIO, POLL_HUP); 702 kill_fasync(&client->fasync, SIGIO, POLL_HUP);
704 wake_up_interruptible(&evdev->wait); 703 wake_up_interruptible(&evdev->wait);
705 } else 704 }
706 evdev_free(evdev); 705
706 put_device(&evdev->dev);
707} 707}
708 708
709static const struct input_device_id evdev_ids[] = { 709static const struct input_device_id evdev_ids[] = {
diff --git a/drivers/input/input.c b/drivers/input/input.c
index ccd8abafcb70..75b4d2a83dd9 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -442,7 +442,7 @@ static int input_attach_handler(struct input_dev *dev, struct input_handler *han
442 printk(KERN_ERR 442 printk(KERN_ERR
443 "input: failed to attach handler %s to device %s, " 443 "input: failed to attach handler %s to device %s, "
444 "error: %d\n", 444 "error: %d\n",
445 handler->name, kobject_name(&dev->cdev.kobj), error); 445 handler->name, kobject_name(&dev->dev.kobj), error);
446 446
447 return error; 447 return error;
448} 448}
@@ -527,7 +527,7 @@ static void input_seq_print_bitmap(struct seq_file *seq, const char *name,
527static int input_devices_seq_show(struct seq_file *seq, void *v) 527static int input_devices_seq_show(struct seq_file *seq, void *v)
528{ 528{
529 struct input_dev *dev = container_of(v, struct input_dev, node); 529 struct input_dev *dev = container_of(v, struct input_dev, node);
530 const char *path = kobject_get_path(&dev->cdev.kobj, GFP_KERNEL); 530 const char *path = kobject_get_path(&dev->dev.kobj, GFP_KERNEL);
531 struct input_handle *handle; 531 struct input_handle *handle;
532 532
533 seq_printf(seq, "I: Bus=%04x Vendor=%04x Product=%04x Version=%04x\n", 533 seq_printf(seq, "I: Bus=%04x Vendor=%04x Product=%04x Version=%04x\n",
@@ -682,15 +682,17 @@ static inline int input_proc_init(void) { return 0; }
682static inline void input_proc_exit(void) { } 682static inline void input_proc_exit(void) { }
683#endif 683#endif
684 684
685#define INPUT_DEV_STRING_ATTR_SHOW(name) \ 685#define INPUT_DEV_STRING_ATTR_SHOW(name) \
686static ssize_t input_dev_show_##name(struct class_device *dev, char *buf) \ 686static ssize_t input_dev_show_##name(struct device *dev, \
687{ \ 687 struct device_attribute *attr, \
688 struct input_dev *input_dev = to_input_dev(dev); \ 688 char *buf) \
689 \ 689{ \
690 return scnprintf(buf, PAGE_SIZE, "%s\n", \ 690 struct input_dev *input_dev = to_input_dev(dev); \
691 input_dev->name ? input_dev->name : ""); \ 691 \
692} \ 692 return scnprintf(buf, PAGE_SIZE, "%s\n", \
693static CLASS_DEVICE_ATTR(name, S_IRUGO, input_dev_show_##name, NULL); 693 input_dev->name ? input_dev->name : ""); \
694} \
695static DEVICE_ATTR(name, S_IRUGO, input_dev_show_##name, NULL)
694 696
695INPUT_DEV_STRING_ATTR_SHOW(name); 697INPUT_DEV_STRING_ATTR_SHOW(name);
696INPUT_DEV_STRING_ATTR_SHOW(phys); 698INPUT_DEV_STRING_ATTR_SHOW(phys);
@@ -744,7 +746,9 @@ static int input_print_modalias(char *buf, int size, struct input_dev *id,
744 return len; 746 return len;
745} 747}
746 748
747static ssize_t input_dev_show_modalias(struct class_device *dev, char *buf) 749static ssize_t input_dev_show_modalias(struct device *dev,
750 struct device_attribute *attr,
751 char *buf)
748{ 752{
749 struct input_dev *id = to_input_dev(dev); 753 struct input_dev *id = to_input_dev(dev);
750 ssize_t len; 754 ssize_t len;
@@ -753,13 +757,13 @@ static ssize_t input_dev_show_modalias(struct class_device *dev, char *buf)
753 757
754 return min_t(int, len, PAGE_SIZE); 758 return min_t(int, len, PAGE_SIZE);
755} 759}
756static CLASS_DEVICE_ATTR(modalias, S_IRUGO, input_dev_show_modalias, NULL); 760static DEVICE_ATTR(modalias, S_IRUGO, input_dev_show_modalias, NULL);
757 761
758static struct attribute *input_dev_attrs[] = { 762static struct attribute *input_dev_attrs[] = {
759 &class_device_attr_name.attr, 763 &dev_attr_name.attr,
760 &class_device_attr_phys.attr, 764 &dev_attr_phys.attr,
761 &class_device_attr_uniq.attr, 765 &dev_attr_uniq.attr,
762 &class_device_attr_modalias.attr, 766 &dev_attr_modalias.attr,
763 NULL 767 NULL
764}; 768};
765 769
@@ -767,13 +771,15 @@ static struct attribute_group input_dev_attr_group = {
767 .attrs = input_dev_attrs, 771 .attrs = input_dev_attrs,
768}; 772};
769 773
770#define INPUT_DEV_ID_ATTR(name) \ 774#define INPUT_DEV_ID_ATTR(name) \
771static ssize_t input_dev_show_id_##name(struct class_device *dev, char *buf) \ 775static ssize_t input_dev_show_id_##name(struct device *dev, \
772{ \ 776 struct device_attribute *attr, \
773 struct input_dev *input_dev = to_input_dev(dev); \ 777 char *buf) \
774 return scnprintf(buf, PAGE_SIZE, "%04x\n", input_dev->id.name); \ 778{ \
775} \ 779 struct input_dev *input_dev = to_input_dev(dev); \
776static CLASS_DEVICE_ATTR(name, S_IRUGO, input_dev_show_id_##name, NULL); 780 return scnprintf(buf, PAGE_SIZE, "%04x\n", input_dev->id.name); \
781} \
782static DEVICE_ATTR(name, S_IRUGO, input_dev_show_id_##name, NULL)
777 783
778INPUT_DEV_ID_ATTR(bustype); 784INPUT_DEV_ID_ATTR(bustype);
779INPUT_DEV_ID_ATTR(vendor); 785INPUT_DEV_ID_ATTR(vendor);
@@ -781,10 +787,10 @@ INPUT_DEV_ID_ATTR(product);
781INPUT_DEV_ID_ATTR(version); 787INPUT_DEV_ID_ATTR(version);
782 788
783static struct attribute *input_dev_id_attrs[] = { 789static struct attribute *input_dev_id_attrs[] = {
784 &class_device_attr_bustype.attr, 790 &dev_attr_bustype.attr,
785 &class_device_attr_vendor.attr, 791 &dev_attr_vendor.attr,
786 &class_device_attr_product.attr, 792 &dev_attr_product.attr,
787 &class_device_attr_version.attr, 793 &dev_attr_version.attr,
788 NULL 794 NULL
789}; 795};
790 796
@@ -813,15 +819,17 @@ static int input_print_bitmap(char *buf, int buf_size, unsigned long *bitmap,
813 return len; 819 return len;
814} 820}
815 821
816#define INPUT_DEV_CAP_ATTR(ev, bm) \ 822#define INPUT_DEV_CAP_ATTR(ev, bm) \
817static ssize_t input_dev_show_cap_##bm(struct class_device *dev, char *buf) \ 823static ssize_t input_dev_show_cap_##bm(struct device *dev, \
818{ \ 824 struct device_attribute *attr, \
819 struct input_dev *input_dev = to_input_dev(dev); \ 825 char *buf) \
820 int len = input_print_bitmap(buf, PAGE_SIZE, \ 826{ \
821 input_dev->bm##bit, ev##_MAX, 1); \ 827 struct input_dev *input_dev = to_input_dev(dev); \
822 return min_t(int, len, PAGE_SIZE); \ 828 int len = input_print_bitmap(buf, PAGE_SIZE, \
823} \ 829 input_dev->bm##bit, ev##_MAX, 1); \
824static CLASS_DEVICE_ATTR(bm, S_IRUGO, input_dev_show_cap_##bm, NULL); 830 return min_t(int, len, PAGE_SIZE); \
831} \
832static DEVICE_ATTR(bm, S_IRUGO, input_dev_show_cap_##bm, NULL)
825 833
826INPUT_DEV_CAP_ATTR(EV, ev); 834INPUT_DEV_CAP_ATTR(EV, ev);
827INPUT_DEV_CAP_ATTR(KEY, key); 835INPUT_DEV_CAP_ATTR(KEY, key);
@@ -834,15 +842,15 @@ INPUT_DEV_CAP_ATTR(FF, ff);
834INPUT_DEV_CAP_ATTR(SW, sw); 842INPUT_DEV_CAP_ATTR(SW, sw);
835 843
836static struct attribute *input_dev_caps_attrs[] = { 844static struct attribute *input_dev_caps_attrs[] = {
837 &class_device_attr_ev.attr, 845 &dev_attr_ev.attr,
838 &class_device_attr_key.attr, 846 &dev_attr_key.attr,
839 &class_device_attr_rel.attr, 847 &dev_attr_rel.attr,
840 &class_device_attr_abs.attr, 848 &dev_attr_abs.attr,
841 &class_device_attr_msc.attr, 849 &dev_attr_msc.attr,
842 &class_device_attr_led.attr, 850 &dev_attr_led.attr,
843 &class_device_attr_snd.attr, 851 &dev_attr_snd.attr,
844 &class_device_attr_ff.attr, 852 &dev_attr_ff.attr,
845 &class_device_attr_sw.attr, 853 &dev_attr_sw.attr,
846 NULL 854 NULL
847}; 855};
848 856
@@ -858,9 +866,9 @@ static struct attribute_group *input_dev_attr_groups[] = {
858 NULL 866 NULL
859}; 867};
860 868
861static void input_dev_release(struct class_device *class_dev) 869static void input_dev_release(struct device *device)
862{ 870{
863 struct input_dev *dev = to_input_dev(class_dev); 871 struct input_dev *dev = to_input_dev(device);
864 872
865 input_ff_destroy(dev); 873 input_ff_destroy(dev);
866 kfree(dev); 874 kfree(dev);
@@ -947,10 +955,10 @@ static int input_add_uevent_modalias_var(char **envp, int num_envp, int *cur_ind
947 return err; \ 955 return err; \
948 } while (0) 956 } while (0)
949 957
950static int input_dev_uevent(struct class_device *cdev, char **envp, 958static int input_dev_uevent(struct device *device, char **envp,
951 int num_envp, char *buffer, int buffer_size) 959 int num_envp, char *buffer, int buffer_size)
952{ 960{
953 struct input_dev *dev = to_input_dev(cdev); 961 struct input_dev *dev = to_input_dev(device);
954 int i = 0; 962 int i = 0;
955 int len = 0; 963 int len = 0;
956 964
@@ -988,10 +996,14 @@ static int input_dev_uevent(struct class_device *cdev, char **envp,
988 return 0; 996 return 0;
989} 997}
990 998
999static struct device_type input_dev_type = {
1000 .groups = input_dev_attr_groups,
1001 .release = input_dev_release,
1002 .uevent = input_dev_uevent,
1003};
1004
991struct class input_class = { 1005struct class input_class = {
992 .name = "input", 1006 .name = "input",
993 .release = input_dev_release,
994 .uevent = input_dev_uevent,
995}; 1007};
996EXPORT_SYMBOL_GPL(input_class); 1008EXPORT_SYMBOL_GPL(input_class);
997 1009
@@ -1010,9 +1022,9 @@ struct input_dev *input_allocate_device(void)
1010 1022
1011 dev = kzalloc(sizeof(struct input_dev), GFP_KERNEL); 1023 dev = kzalloc(sizeof(struct input_dev), GFP_KERNEL);
1012 if (dev) { 1024 if (dev) {
1013 dev->cdev.class = &input_class; 1025 dev->dev.type = &input_dev_type;
1014 dev->cdev.groups = input_dev_attr_groups; 1026 dev->dev.class = &input_class;
1015 class_device_initialize(&dev->cdev); 1027 device_initialize(&dev->dev);
1016 mutex_init(&dev->mutex); 1028 mutex_init(&dev->mutex);
1017 INIT_LIST_HEAD(&dev->h_list); 1029 INIT_LIST_HEAD(&dev->h_list);
1018 INIT_LIST_HEAD(&dev->node); 1030 INIT_LIST_HEAD(&dev->node);
@@ -1131,17 +1143,17 @@ int input_register_device(struct input_dev *dev)
1131 1143
1132 list_add_tail(&dev->node, &input_dev_list); 1144 list_add_tail(&dev->node, &input_dev_list);
1133 1145
1134 snprintf(dev->cdev.class_id, sizeof(dev->cdev.class_id), 1146 snprintf(dev->dev.bus_id, sizeof(dev->dev.bus_id),
1135 "input%ld", (unsigned long) atomic_inc_return(&input_no) - 1); 1147 "input%ld", (unsigned long) atomic_inc_return(&input_no) - 1);
1136 1148
1137 if (!dev->cdev.dev) 1149 if (dev->cdev.dev)
1138 dev->cdev.dev = dev->dev.parent; 1150 dev->dev.parent = dev->cdev.dev;
1139 1151
1140 error = class_device_add(&dev->cdev); 1152 error = device_add(&dev->dev);
1141 if (error) 1153 if (error)
1142 return error; 1154 return error;
1143 1155
1144 path = kobject_get_path(&dev->cdev.kobj, GFP_KERNEL); 1156 path = kobject_get_path(&dev->dev.kobj, GFP_KERNEL);
1145 printk(KERN_INFO "input: %s as %s\n", 1157 printk(KERN_INFO "input: %s as %s\n",
1146 dev->name ? dev->name : "Unspecified device", path ? path : "N/A"); 1158 dev->name ? dev->name : "Unspecified device", path ? path : "N/A");
1147 kfree(path); 1159 kfree(path);
@@ -1173,7 +1185,7 @@ void input_unregister_device(struct input_dev *dev)
1173 1185
1174 list_del_init(&dev->node); 1186 list_del_init(&dev->node);
1175 1187
1176 class_device_unregister(&dev->cdev); 1188 device_unregister(&dev->dev);
1177 1189
1178 input_wakeup_procfs_readers(); 1190 input_wakeup_procfs_readers();
1179} 1191}
diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c
index 10e3b7bc925f..a9a0180bfd46 100644
--- a/drivers/input/joydev.c
+++ b/drivers/input/joydev.c
@@ -43,6 +43,8 @@ struct joydev {
43 struct input_handle handle; 43 struct input_handle handle;
44 wait_queue_head_t wait; 44 wait_queue_head_t wait;
45 struct list_head client_list; 45 struct list_head client_list;
46 struct device dev;
47
46 struct js_corr corr[ABS_MAX + 1]; 48 struct js_corr corr[ABS_MAX + 1];
47 struct JS_DATA_SAVE_TYPE glue; 49 struct JS_DATA_SAVE_TYPE glue;
48 int nabs; 50 int nabs;
@@ -138,8 +140,10 @@ static int joydev_fasync(int fd, struct file *file, int on)
138 return retval < 0 ? retval : 0; 140 return retval < 0 ? retval : 0;
139} 141}
140 142
141static void joydev_free(struct joydev *joydev) 143static void joydev_free(struct device *dev)
142{ 144{
145 struct joydev *joydev = container_of(dev, struct joydev, dev);
146
143 joydev_table[joydev->minor] = NULL; 147 joydev_table[joydev->minor] = NULL;
144 kfree(joydev); 148 kfree(joydev);
145} 149}
@@ -154,12 +158,10 @@ static int joydev_release(struct inode *inode, struct file *file)
154 list_del(&client->node); 158 list_del(&client->node);
155 kfree(client); 159 kfree(client);
156 160
157 if (!--joydev->open) { 161 if (!--joydev->open && joydev->exist)
158 if (joydev->exist) 162 input_close_device(&joydev->handle);
159 input_close_device(&joydev->handle); 163
160 else 164 put_device(&joydev->dev);
161 joydev_free(joydev);
162 }
163 165
164 return 0; 166 return 0;
165} 167}
@@ -178,24 +180,32 @@ static int joydev_open(struct inode *inode, struct file *file)
178 if (!joydev || !joydev->exist) 180 if (!joydev || !joydev->exist)
179 return -ENODEV; 181 return -ENODEV;
180 182
183 get_device(&joydev->dev);
184
181 client = kzalloc(sizeof(struct joydev_client), GFP_KERNEL); 185 client = kzalloc(sizeof(struct joydev_client), GFP_KERNEL);
182 if (!client) 186 if (!client) {
183 return -ENOMEM; 187 error = -ENOMEM;
188 goto err_put_joydev;
189 }
184 190
185 client->joydev = joydev; 191 client->joydev = joydev;
186 list_add_tail(&client->node, &joydev->client_list); 192 list_add_tail(&client->node, &joydev->client_list);
187 193
188 if (!joydev->open++ && joydev->exist) { 194 if (!joydev->open++ && joydev->exist) {
189 error = input_open_device(&joydev->handle); 195 error = input_open_device(&joydev->handle);
190 if (error) { 196 if (error)
191 list_del(&client->node); 197 goto err_free_client;
192 kfree(client);
193 return error;
194 }
195 } 198 }
196 199
197 file->private_data = client; 200 file->private_data = client;
198 return 0; 201 return 0;
202
203 err_free_client:
204 list_del(&client->node);
205 kfree(client);
206 err_put_joydev:
207 put_device(&joydev->dev);
208 return error;
199} 209}
200 210
201static ssize_t joydev_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) 211static ssize_t joydev_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
@@ -481,8 +491,6 @@ static int joydev_connect(struct input_handler *handler, struct input_dev *dev,
481 const struct input_device_id *id) 491 const struct input_device_id *id)
482{ 492{
483 struct joydev *joydev; 493 struct joydev *joydev;
484 struct class_device *cdev;
485 dev_t devt;
486 int i, j, t, minor; 494 int i, j, t, minor;
487 int error; 495 int error;
488 496
@@ -505,7 +513,7 @@ static int joydev_connect(struct input_handler *handler, struct input_dev *dev,
505 joydev->handle.name = joydev->name; 513 joydev->handle.name = joydev->name;
506 joydev->handle.handler = handler; 514 joydev->handle.handler = handler;
507 joydev->handle.private = joydev; 515 joydev->handle.private = joydev;
508 sprintf(joydev->name, "js%d", minor); 516 snprintf(joydev->name, sizeof(joydev->name), "js%d", minor);
509 517
510 for (i = 0; i < ABS_MAX + 1; i++) 518 for (i = 0; i < ABS_MAX + 1; i++)
511 if (test_bit(i, dev->absbit)) { 519 if (test_bit(i, dev->absbit)) {
@@ -547,36 +555,30 @@ static int joydev_connect(struct input_handler *handler, struct input_dev *dev,
547 joydev->abs[i] = joydev_correct(dev->abs[j], joydev->corr + i); 555 joydev->abs[i] = joydev_correct(dev->abs[j], joydev->corr + i);
548 } 556 }
549 557
550 joydev_table[minor] = joydev; 558 snprintf(joydev->dev.bus_id, sizeof(joydev->dev.bus_id),
551 559 "js%d", minor);
552 devt = MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + minor), 560 joydev->dev.class = &input_class;
561 joydev->dev.parent = &dev->dev;
562 joydev->dev.devt = MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + minor);
563 joydev->dev.release = joydev_free;
564 device_initialize(&joydev->dev);
553 565
554 cdev = class_device_create(&input_class, &dev->cdev, devt, 566 joydev_table[minor] = joydev;
555 dev->cdev.dev, joydev->name);
556 if (IS_ERR(cdev)) {
557 error = PTR_ERR(cdev);
558 goto err_free_joydev;
559 }
560 567
561 /* temporary symlink to keep userspace happy */ 568 error = device_add(&joydev->dev);
562 error = sysfs_create_link(&input_class.subsys.kobj,
563 &cdev->kobj, joydev->name);
564 if (error) 569 if (error)
565 goto err_cdev_destroy; 570 goto err_free_joydev;
566 571
567 error = input_register_handle(&joydev->handle); 572 error = input_register_handle(&joydev->handle);
568 if (error) 573 if (error)
569 goto err_remove_link; 574 goto err_delete_joydev;
570 575
571 return 0; 576 return 0;
572 577
573 err_remove_link: 578 err_delete_joydev:
574 sysfs_remove_link(&input_class.subsys.kobj, joydev->name); 579 device_del(&joydev->dev);
575 err_cdev_destroy:
576 class_device_destroy(&input_class, devt);
577 err_free_joydev: 580 err_free_joydev:
578 joydev_table[minor] = NULL; 581 put_device(&joydev->dev);
579 kfree(joydev);
580 return error; 582 return error;
581} 583}
582 584
@@ -587,9 +589,8 @@ static void joydev_disconnect(struct input_handle *handle)
587 struct joydev_client *client; 589 struct joydev_client *client;
588 590
589 input_unregister_handle(handle); 591 input_unregister_handle(handle);
592 device_del(&joydev->dev);
590 593
591 sysfs_remove_link(&input_class.subsys.kobj, joydev->name);
592 class_device_destroy(&input_class, MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + joydev->minor));
593 joydev->exist = 0; 594 joydev->exist = 0;
594 595
595 if (joydev->open) { 596 if (joydev->open) {
@@ -597,8 +598,9 @@ static void joydev_disconnect(struct input_handle *handle)
597 list_for_each_entry(client, &joydev->client_list, node) 598 list_for_each_entry(client, &joydev->client_list, node)
598 kill_fasync(&client->fasync, SIGIO, POLL_HUP); 599 kill_fasync(&client->fasync, SIGIO, POLL_HUP);
599 wake_up_interruptible(&joydev->wait); 600 wake_up_interruptible(&joydev->wait);
600 } else 601 }
601 joydev_free(joydev); 602
603 put_device(&joydev->dev);
602} 604}
603 605
604static const struct input_device_id joydev_blacklist[] = { 606static const struct input_device_id joydev_blacklist[] = {
diff --git a/drivers/input/joystick/Kconfig b/drivers/input/joystick/Kconfig
index b0023452ec90..12db72d83ea0 100644
--- a/drivers/input/joystick/Kconfig
+++ b/drivers/input/joystick/Kconfig
@@ -268,4 +268,11 @@ config JOYSTICK_XPAD
268 To compile this driver as a module, choose M here: the 268 To compile this driver as a module, choose M here: the
269 module will be called xpad. 269 module will be called xpad.
270 270
271config JOYSTICK_XPAD_FF
272 bool "X-Box gamepad rumble support"
273 depends on JOYSTICK_XPAD && INPUT
274 select INPUT_FF_MEMLESS
275 ---help---
276 Say Y here if you want to take advantage of xbox 360 rumble features.
277
271endif 278endif
diff --git a/drivers/input/joystick/grip_mp.c b/drivers/input/joystick/grip_mp.c
index 555319e6378c..4ed3a3eadf19 100644
--- a/drivers/input/joystick/grip_mp.c
+++ b/drivers/input/joystick/grip_mp.c
@@ -320,10 +320,10 @@ static int multiport_io(struct gameport* gameport, int sendflags, int sendcode,
320 320
321static int dig_mode_start(struct gameport *gameport, u32 *packet) 321static int dig_mode_start(struct gameport *gameport, u32 *packet)
322{ 322{
323 int i, seq_len = sizeof(init_seq)/sizeof(int); 323 int i;
324 int flags, tries = 0, bads = 0; 324 int flags, tries = 0, bads = 0;
325 325
326 for (i = 0; i < seq_len; i++) { /* Send magic sequence */ 326 for (i = 0; i < ARRAY_SIZE(init_seq); i++) { /* Send magic sequence */
327 if (init_seq[i]) 327 if (init_seq[i])
328 gameport_trigger(gameport); 328 gameport_trigger(gameport);
329 udelay(GRIP_INIT_DELAY); 329 udelay(GRIP_INIT_DELAY);
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
index 8c8cd95a6989..244089c52650 100644
--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -8,6 +8,7 @@
8 * Ivan Hawkes <blackhawk@ivanhawkes.com> 8 * Ivan Hawkes <blackhawk@ivanhawkes.com>
9 * 2005 Dominic Cerquetti <binary1230@yahoo.com> 9 * 2005 Dominic Cerquetti <binary1230@yahoo.com>
10 * 2006 Adam Buchbinder <adam.buchbinder@gmail.com> 10 * 2006 Adam Buchbinder <adam.buchbinder@gmail.com>
11 * 2007 Jan Kratochvil <honza@jikos.cz>
11 * 12 *
12 * This program is free software; you can redistribute it and/or 13 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License as 14 * modify it under the terms of the GNU General Public License as
@@ -28,6 +29,7 @@
28 * - information from http://euc.jp/periphs/xbox-controller.ja.html 29 * - information from http://euc.jp/periphs/xbox-controller.ja.html
29 * - the iForce driver drivers/char/joystick/iforce.c 30 * - the iForce driver drivers/char/joystick/iforce.c
30 * - the skeleton-driver drivers/usb/usb-skeleton.c 31 * - the skeleton-driver drivers/usb/usb-skeleton.c
32 * - Xbox 360 information http://www.free60.org/wiki/Gamepad
31 * 33 *
32 * Thanks to: 34 * Thanks to:
33 * - ITO Takayuki for providing essential xpad information on his website 35 * - ITO Takayuki for providing essential xpad information on his website
@@ -88,6 +90,9 @@
88#define MAP_DPAD_TO_AXES 1 90#define MAP_DPAD_TO_AXES 1
89#define MAP_DPAD_UNKNOWN -1 91#define MAP_DPAD_UNKNOWN -1
90 92
93#define XTYPE_XBOX 0
94#define XTYPE_XBOX360 1
95
91static int dpad_to_buttons; 96static int dpad_to_buttons;
92module_param(dpad_to_buttons, bool, S_IRUGO); 97module_param(dpad_to_buttons, bool, S_IRUGO);
93MODULE_PARM_DESC(dpad_to_buttons, "Map D-PAD to buttons rather than axes for unknown pads"); 98MODULE_PARM_DESC(dpad_to_buttons, "Map D-PAD to buttons rather than axes for unknown pads");
@@ -97,40 +102,42 @@ static const struct xpad_device {
97 u16 idProduct; 102 u16 idProduct;
98 char *name; 103 char *name;
99 u8 dpad_mapping; 104 u8 dpad_mapping;
105 u8 xtype;
100} xpad_device[] = { 106} xpad_device[] = {
101 { 0x045e, 0x0202, "Microsoft X-Box pad v1 (US)", MAP_DPAD_TO_AXES }, 107 { 0x045e, 0x0202, "Microsoft X-Box pad v1 (US)", MAP_DPAD_TO_AXES, XTYPE_XBOX },
102 { 0x045e, 0x0289, "Microsoft X-Box pad v2 (US)", MAP_DPAD_TO_AXES }, 108 { 0x045e, 0x0289, "Microsoft X-Box pad v2 (US)", MAP_DPAD_TO_AXES, XTYPE_XBOX },
103 { 0x045e, 0x0285, "Microsoft X-Box pad (Japan)", MAP_DPAD_TO_AXES }, 109 { 0x045e, 0x0285, "Microsoft X-Box pad (Japan)", MAP_DPAD_TO_AXES, XTYPE_XBOX },
104 { 0x045e, 0x0287, "Microsoft Xbox Controller S", MAP_DPAD_TO_AXES }, 110 { 0x045e, 0x0287, "Microsoft Xbox Controller S", MAP_DPAD_TO_AXES, XTYPE_XBOX },
105 { 0x0c12, 0x8809, "RedOctane Xbox Dance Pad", MAP_DPAD_TO_BUTTONS }, 111 { 0x0c12, 0x8809, "RedOctane Xbox Dance Pad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX },
106 { 0x044f, 0x0f07, "Thrustmaster, Inc. Controller", MAP_DPAD_TO_AXES }, 112 { 0x044f, 0x0f07, "Thrustmaster, Inc. Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX },
107 { 0x046d, 0xca84, "Logitech Xbox Cordless Controller", MAP_DPAD_TO_AXES }, 113 { 0x046d, 0xca84, "Logitech Xbox Cordless Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX },
108 { 0x046d, 0xca88, "Logitech Compact Controller for Xbox", MAP_DPAD_TO_AXES }, 114 { 0x046d, 0xca88, "Logitech Compact Controller for Xbox", MAP_DPAD_TO_AXES, XTYPE_XBOX },
109 { 0x05fd, 0x1007, "Mad Catz Controller (unverified)", MAP_DPAD_TO_AXES }, 115 { 0x05fd, 0x1007, "Mad Catz Controller (unverified)", MAP_DPAD_TO_AXES, XTYPE_XBOX },
110 { 0x05fd, 0x107a, "InterAct 'PowerPad Pro' X-Box pad (Germany)", MAP_DPAD_TO_AXES }, 116 { 0x05fd, 0x107a, "InterAct 'PowerPad Pro' X-Box pad (Germany)", MAP_DPAD_TO_AXES, XTYPE_XBOX },
111 { 0x0738, 0x4516, "Mad Catz Control Pad", MAP_DPAD_TO_AXES }, 117 { 0x0738, 0x4516, "Mad Catz Control Pad", MAP_DPAD_TO_AXES, XTYPE_XBOX },
112 { 0x0738, 0x4522, "Mad Catz LumiCON", MAP_DPAD_TO_AXES }, 118 { 0x0738, 0x4522, "Mad Catz LumiCON", MAP_DPAD_TO_AXES, XTYPE_XBOX },
113 { 0x0738, 0x4526, "Mad Catz Control Pad Pro", MAP_DPAD_TO_AXES }, 119 { 0x0738, 0x4526, "Mad Catz Control Pad Pro", MAP_DPAD_TO_AXES, XTYPE_XBOX },
114 { 0x0738, 0x4536, "Mad Catz MicroCON", MAP_DPAD_TO_AXES }, 120 { 0x0738, 0x4536, "Mad Catz MicroCON", MAP_DPAD_TO_AXES, XTYPE_XBOX },
115 { 0x0738, 0x4540, "Mad Catz Beat Pad", MAP_DPAD_TO_BUTTONS }, 121 { 0x0738, 0x4540, "Mad Catz Beat Pad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX },
116 { 0x0738, 0x4556, "Mad Catz Lynx Wireless Controller", MAP_DPAD_TO_AXES }, 122 { 0x0738, 0x4556, "Mad Catz Lynx Wireless Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX },
117 { 0x0738, 0x6040, "Mad Catz Beat Pad Pro", MAP_DPAD_TO_BUTTONS }, 123 { 0x0738, 0x6040, "Mad Catz Beat Pad Pro", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX },
118 { 0x0c12, 0x8802, "Zeroplus Xbox Controller", MAP_DPAD_TO_AXES }, 124 { 0x0c12, 0x8802, "Zeroplus Xbox Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX },
119 { 0x0c12, 0x8810, "Zeroplus Xbox Controller", MAP_DPAD_TO_AXES }, 125 { 0x0c12, 0x8810, "Zeroplus Xbox Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX },
120 { 0x0c12, 0x9902, "HAMA VibraX - *FAULTY HARDWARE*", MAP_DPAD_TO_AXES }, 126 { 0x0c12, 0x9902, "HAMA VibraX - *FAULTY HARDWARE*", MAP_DPAD_TO_AXES, XTYPE_XBOX },
121 { 0x0e4c, 0x1097, "Radica Gamester Controller", MAP_DPAD_TO_AXES }, 127 { 0x0e4c, 0x1097, "Radica Gamester Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX },
122 { 0x0e4c, 0x2390, "Radica Games Jtech Controller", MAP_DPAD_TO_AXES}, 128 { 0x0e4c, 0x2390, "Radica Games Jtech Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX },
123 { 0x0e6f, 0x0003, "Logic3 Freebird wireless Controller", MAP_DPAD_TO_AXES }, 129 { 0x0e6f, 0x0003, "Logic3 Freebird wireless Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX },
124 { 0x0e6f, 0x0005, "Eclipse wireless Controller", MAP_DPAD_TO_AXES }, 130 { 0x0e6f, 0x0005, "Eclipse wireless Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX },
125 { 0x0e6f, 0x0006, "Edge wireless Controller", MAP_DPAD_TO_AXES }, 131 { 0x0e6f, 0x0006, "Edge wireless Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX },
126 { 0x0e8f, 0x0201, "SmartJoy Frag Xpad/PS2 adaptor", MAP_DPAD_TO_AXES }, 132 { 0x0e8f, 0x0201, "SmartJoy Frag Xpad/PS2 adaptor", MAP_DPAD_TO_AXES, XTYPE_XBOX },
127 { 0x0f30, 0x0202, "Joytech Advanced Controller", MAP_DPAD_TO_AXES }, 133 { 0x0f30, 0x0202, "Joytech Advanced Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX },
128 { 0x0f30, 0x8888, "BigBen XBMiniPad Controller", MAP_DPAD_TO_AXES }, 134 { 0x0f30, 0x8888, "BigBen XBMiniPad Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX },
129 { 0x102c, 0xff0c, "Joytech Wireless Advanced Controller", MAP_DPAD_TO_AXES }, 135 { 0x102c, 0xff0c, "Joytech Wireless Advanced Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX },
130 { 0x12ab, 0x8809, "Xbox DDR dancepad", MAP_DPAD_TO_BUTTONS }, 136 { 0x12ab, 0x8809, "Xbox DDR dancepad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX },
131 { 0x1430, 0x8888, "TX6500+ Dance Pad (first generation)", MAP_DPAD_TO_BUTTONS }, 137 { 0x1430, 0x8888, "TX6500+ Dance Pad (first generation)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX },
132 { 0xffff, 0xffff, "Chinese-made Xbox Controller", MAP_DPAD_TO_AXES }, 138 { 0x045e, 0x028e, "Microsoft X-Box 360 pad", MAP_DPAD_TO_AXES, XTYPE_XBOX360 },
133 { 0x0000, 0x0000, "Generic X-Box pad", MAP_DPAD_UNKNOWN } 139 { 0xffff, 0xffff, "Chinese-made Xbox Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX },
140 { 0x0000, 0x0000, "Generic X-Box pad", MAP_DPAD_UNKNOWN, XTYPE_XBOX }
134}; 141};
135 142
136static const signed short xpad_btn[] = { 143static const signed short xpad_btn[] = {
@@ -146,6 +153,12 @@ static const signed short xpad_btn_pad[] = {
146 -1 /* terminating entry */ 153 -1 /* terminating entry */
147}; 154};
148 155
156static const signed short xpad360_btn[] = { /* buttons for x360 controller */
157 BTN_TL, BTN_TR, /* Button LB/RB */
158 BTN_MODE, /* The big X button */
159 -1
160};
161
149static const signed short xpad_abs[] = { 162static const signed short xpad_abs[] = {
150 ABS_X, ABS_Y, /* left stick */ 163 ABS_X, ABS_Y, /* left stick */
151 ABS_RX, ABS_RY, /* right stick */ 164 ABS_RX, ABS_RY, /* right stick */
@@ -159,8 +172,12 @@ static const signed short xpad_abs_pad[] = {
159 -1 /* terminating entry */ 172 -1 /* terminating entry */
160}; 173};
161 174
175/* Xbox 360 has a vendor-specific (sub)class, so we cannot match it with only
176 * USB_INTERFACE_INFO, more to that this device has 4 InterfaceProtocols,
177 * but we need only one of them. */
162static struct usb_device_id xpad_table [] = { 178static struct usb_device_id xpad_table [] = {
163 { USB_INTERFACE_INFO('X', 'B', 0) }, /* X-Box USB-IF not approved class */ 179 { USB_INTERFACE_INFO('X', 'B', 0) }, /* X-Box USB-IF not approved class */
180 { USB_DEVICE_INTERFACE_PROTOCOL(0x045e, 0x028e, 1) }, /* X-Box 360 controller */
164 { } 181 { }
165}; 182};
166 183
@@ -174,9 +191,16 @@ struct usb_xpad {
174 unsigned char *idata; /* input data */ 191 unsigned char *idata; /* input data */
175 dma_addr_t idata_dma; 192 dma_addr_t idata_dma;
176 193
194#ifdef CONFIG_JOYSTICK_XPAD_FF
195 struct urb *irq_out; /* urb for interrupt out report */
196 unsigned char *odata; /* output data */
197 dma_addr_t odata_dma;
198#endif
199
177 char phys[65]; /* physical device path */ 200 char phys[65]; /* physical device path */
178 201
179 int dpad_mapping; /* map d-pad to buttons or to axes */ 202 int dpad_mapping; /* map d-pad to buttons or to axes */
203 int xtype; /* type of xbox device */
180}; 204};
181 205
182/* 206/*
@@ -212,8 +236,8 @@ static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *d
212 } else /* xpad->dpad_mapping == MAP_DPAD_TO_BUTTONS */ { 236 } else /* xpad->dpad_mapping == MAP_DPAD_TO_BUTTONS */ {
213 input_report_key(dev, BTN_LEFT, data[2] & 0x04); 237 input_report_key(dev, BTN_LEFT, data[2] & 0x04);
214 input_report_key(dev, BTN_RIGHT, data[2] & 0x08); 238 input_report_key(dev, BTN_RIGHT, data[2] & 0x08);
215 input_report_key(dev, BTN_0, data[2] & 0x01); // up 239 input_report_key(dev, BTN_0, data[2] & 0x01); /* up */
216 input_report_key(dev, BTN_1, data[2] & 0x02); // down 240 input_report_key(dev, BTN_1, data[2] & 0x02); /* down */
217 } 241 }
218 242
219 /* start/back buttons and stick press left/right */ 243 /* start/back buttons and stick press left/right */
@@ -235,6 +259,64 @@ static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *d
235 input_sync(dev); 259 input_sync(dev);
236} 260}
237 261
262/*
263 * xpad360_process_packet
264 *
265 * Completes a request by converting the data into events for the
266 * input subsystem. It is version for xbox 360 controller
267 *
268 * The used report descriptor was taken from:
269 * http://www.free60.org/wiki/Gamepad
270 */
271
272static void xpad360_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *data)
273{
274 struct input_dev *dev = xpad->dev;
275
276 /* digital pad */
277 if (xpad->dpad_mapping == MAP_DPAD_TO_AXES) {
278 input_report_abs(dev, ABS_HAT0X, !!(data[2] & 0x08) - !!(data[2] & 0x04));
279 input_report_abs(dev, ABS_HAT0Y, !!(data[2] & 0x02) - !!(data[2] & 0x01));
280 } else if (xpad->dpad_mapping == MAP_DPAD_TO_BUTTONS) {
281 /* dpad as buttons (right, left, down, up) */
282 input_report_key(dev, BTN_LEFT, data[2] & 0x04);
283 input_report_key(dev, BTN_RIGHT, data[2] & 0x08);
284 input_report_key(dev, BTN_0, data[2] & 0x01); /* up */
285 input_report_key(dev, BTN_1, data[2] & 0x02); /* down */
286 }
287
288 /* start/back buttons */
289 input_report_key(dev, BTN_START, data[2] & 0x10);
290 input_report_key(dev, BTN_BACK, data[2] & 0x20);
291
292 /* stick press left/right */
293 input_report_key(dev, BTN_THUMBL, data[2] & 0x40);
294 input_report_key(dev, BTN_THUMBR, data[2] & 0x80);
295
296 /* buttons A,B,X,Y,TL,TR and MODE */
297 input_report_key(dev, BTN_A, data[3] & 0x10);
298 input_report_key(dev, BTN_B, data[3] & 0x20);
299 input_report_key(dev, BTN_X, data[3] & 0x40);
300 input_report_key(dev, BTN_Y, data[3] & 0x80);
301 input_report_key(dev, BTN_TL, data[3] & 0x01);
302 input_report_key(dev, BTN_TR, data[3] & 0x02);
303 input_report_key(dev, BTN_MODE, data[3] & 0x04);
304
305 /* left stick */
306 input_report_abs(dev, ABS_X, (__s16) (((__s16)data[7] << 8) | (__s16)data[6]));
307 input_report_abs(dev, ABS_Y, (__s16) (((__s16)data[9] << 8) | (__s16)data[8]));
308
309 /* right stick */
310 input_report_abs(dev, ABS_RX, (__s16) (((__s16)data[11] << 8) | (__s16)data[10]));
311 input_report_abs(dev, ABS_RY, (__s16) (((__s16)data[13] << 8) | (__s16)data[12]));
312
313 /* triggers left/right */
314 input_report_abs(dev, ABS_Z, data[4]);
315 input_report_abs(dev, ABS_RZ, data[5]);
316
317 input_sync(dev);
318}
319
238static void xpad_irq_in(struct urb *urb) 320static void xpad_irq_in(struct urb *urb)
239{ 321{
240 struct usb_xpad *xpad = urb->context; 322 struct usb_xpad *xpad = urb->context;
@@ -255,7 +337,10 @@ static void xpad_irq_in(struct urb *urb)
255 goto exit; 337 goto exit;
256 } 338 }
257 339
258 xpad_process_packet(xpad, 0, xpad->idata); 340 if (xpad->xtype == XTYPE_XBOX360)
341 xpad360_process_packet(xpad, 0, xpad->idata);
342 else
343 xpad_process_packet(xpad, 0, xpad->idata);
259 344
260exit: 345exit:
261 retval = usb_submit_urb (urb, GFP_ATOMIC); 346 retval = usb_submit_urb (urb, GFP_ATOMIC);
@@ -264,7 +349,114 @@ exit:
264 __FUNCTION__, retval); 349 __FUNCTION__, retval);
265} 350}
266 351
267static int xpad_open (struct input_dev *dev) 352#ifdef CONFIG_JOYSTICK_XPAD_FF
353static void xpad_irq_out(struct urb *urb)
354{
355 int retval;
356
357 switch (urb->status) {
358 case 0:
359 /* success */
360 break;
361 case -ECONNRESET:
362 case -ENOENT:
363 case -ESHUTDOWN:
364 /* this urb is terminated, clean up */
365 dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status);
366 return;
367 default:
368 dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status);
369 goto exit;
370 }
371
372exit:
373 retval = usb_submit_urb(urb, GFP_ATOMIC);
374 if (retval)
375 err("%s - usb_submit_urb failed with result %d",
376 __FUNCTION__, retval);
377}
378
379static int xpad_play_effect(struct input_dev *dev, void *data,
380 struct ff_effect *effect)
381{
382 struct usb_xpad *xpad = input_get_drvdata(dev);
383
384 if (effect->type == FF_RUMBLE) {
385 __u16 strong = effect->u.rumble.strong_magnitude;
386 __u16 weak = effect->u.rumble.weak_magnitude;
387 xpad->odata[0] = 0x00;
388 xpad->odata[1] = 0x08;
389 xpad->odata[2] = 0x00;
390 xpad->odata[3] = strong / 256;
391 xpad->odata[4] = weak / 256;
392 xpad->odata[5] = 0x00;
393 xpad->odata[6] = 0x00;
394 xpad->odata[7] = 0x00;
395 usb_submit_urb(xpad->irq_out, GFP_KERNEL);
396 }
397
398 return 0;
399}
400
401static int xpad_init_ff(struct usb_interface *intf, struct usb_xpad *xpad)
402{
403 struct usb_endpoint_descriptor *ep_irq_out;
404 int error = -ENOMEM;
405
406 if (xpad->xtype != XTYPE_XBOX360)
407 return 0;
408
409 xpad->odata = usb_buffer_alloc(xpad->udev, XPAD_PKT_LEN,
410 GFP_ATOMIC, &xpad->odata_dma );
411 if (!xpad->odata)
412 goto fail1;
413
414 xpad->irq_out = usb_alloc_urb(0, GFP_KERNEL);
415 if (!xpad->irq_out)
416 goto fail2;
417
418 ep_irq_out = &intf->cur_altsetting->endpoint[1].desc;
419 usb_fill_int_urb(xpad->irq_out, xpad->udev,
420 usb_sndintpipe(xpad->udev, ep_irq_out->bEndpointAddress),
421 xpad->odata, XPAD_PKT_LEN,
422 xpad_irq_out, xpad, ep_irq_out->bInterval);
423 xpad->irq_out->transfer_dma = xpad->odata_dma;
424 xpad->irq_out->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
425
426 input_set_capability(xpad->dev, EV_FF, FF_RUMBLE);
427
428 error = input_ff_create_memless(xpad->dev, NULL, xpad_play_effect);
429 if (error)
430 goto fail2;
431
432 return 0;
433
434 fail2: usb_buffer_free(xpad->udev, XPAD_PKT_LEN, xpad->odata, xpad->odata_dma);
435 fail1: return error;
436}
437
438static void xpad_stop_ff(struct usb_xpad *xpad)
439{
440 if (xpad->xtype == XTYPE_XBOX360)
441 usb_kill_urb(xpad->irq_out);
442}
443
444static void xpad_deinit_ff(struct usb_xpad *xpad)
445{
446 if (xpad->xtype == XTYPE_XBOX360) {
447 usb_free_urb(xpad->irq_out);
448 usb_buffer_free(xpad->udev, XPAD_PKT_LEN,
449 xpad->odata, xpad->odata_dma);
450 }
451}
452
453#else
454static int xpad_init_ff(struct usb_interface *intf, struct usb_xpad *xpad) { return 0; }
455static void xpad_stop_ff(struct usb_xpad *xpad) { }
456static void xpad_deinit_ff(struct usb_xpad *xpad) { }
457#endif
458
459static int xpad_open(struct input_dev *dev)
268{ 460{
269 struct usb_xpad *xpad = input_get_drvdata(dev); 461 struct usb_xpad *xpad = input_get_drvdata(dev);
270 462
@@ -275,11 +467,12 @@ static int xpad_open (struct input_dev *dev)
275 return 0; 467 return 0;
276} 468}
277 469
278static void xpad_close (struct input_dev *dev) 470static void xpad_close(struct input_dev *dev)
279{ 471{
280 struct usb_xpad *xpad = input_get_drvdata(dev); 472 struct usb_xpad *xpad = input_get_drvdata(dev);
281 473
282 usb_kill_urb(xpad->irq_in); 474 usb_kill_urb(xpad->irq_in);
475 xpad_stop_ff(xpad);
283} 476}
284 477
285static void xpad_set_up_abs(struct input_dev *input_dev, signed short abs) 478static void xpad_set_up_abs(struct input_dev *input_dev, signed short abs)
@@ -335,6 +528,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
335 528
336 xpad->udev = udev; 529 xpad->udev = udev;
337 xpad->dpad_mapping = xpad_device[i].dpad_mapping; 530 xpad->dpad_mapping = xpad_device[i].dpad_mapping;
531 xpad->xtype = xpad_device[i].xtype;
338 if (xpad->dpad_mapping == MAP_DPAD_UNKNOWN) 532 if (xpad->dpad_mapping == MAP_DPAD_UNKNOWN)
339 xpad->dpad_mapping = dpad_to_buttons; 533 xpad->dpad_mapping = dpad_to_buttons;
340 xpad->dev = input_dev; 534 xpad->dev = input_dev;
@@ -356,6 +550,9 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
356 /* set up buttons */ 550 /* set up buttons */
357 for (i = 0; xpad_btn[i] >= 0; i++) 551 for (i = 0; xpad_btn[i] >= 0; i++)
358 set_bit(xpad_btn[i], input_dev->keybit); 552 set_bit(xpad_btn[i], input_dev->keybit);
553 if (xpad->xtype == XTYPE_XBOX360)
554 for (i = 0; xpad360_btn[i] >= 0; i++)
555 set_bit(xpad360_btn[i], input_dev->keybit);
359 if (xpad->dpad_mapping == MAP_DPAD_TO_BUTTONS) 556 if (xpad->dpad_mapping == MAP_DPAD_TO_BUTTONS)
360 for (i = 0; xpad_btn_pad[i] >= 0; i++) 557 for (i = 0; xpad_btn_pad[i] >= 0; i++)
361 set_bit(xpad_btn_pad[i], input_dev->keybit); 558 set_bit(xpad_btn_pad[i], input_dev->keybit);
@@ -367,6 +564,10 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
367 for (i = 0; xpad_abs_pad[i] >= 0; i++) 564 for (i = 0; xpad_abs_pad[i] >= 0; i++)
368 xpad_set_up_abs(input_dev, xpad_abs_pad[i]); 565 xpad_set_up_abs(input_dev, xpad_abs_pad[i]);
369 566
567 error = xpad_init_ff(intf, xpad);
568 if (error)
569 goto fail2;
570
370 ep_irq_in = &intf->cur_altsetting->endpoint[0].desc; 571 ep_irq_in = &intf->cur_altsetting->endpoint[0].desc;
371 usb_fill_int_urb(xpad->irq_in, udev, 572 usb_fill_int_urb(xpad->irq_in, udev,
372 usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress), 573 usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress),
@@ -396,10 +597,10 @@ static void xpad_disconnect(struct usb_interface *intf)
396 597
397 usb_set_intfdata(intf, NULL); 598 usb_set_intfdata(intf, NULL);
398 if (xpad) { 599 if (xpad) {
399 usb_kill_urb(xpad->irq_in);
400 input_unregister_device(xpad->dev); 600 input_unregister_device(xpad->dev);
601 xpad_deinit_ff(xpad);
401 usb_free_urb(xpad->irq_in); 602 usb_free_urb(xpad->irq_in);
402 usb_buffer_free(interface_to_usbdev(intf), XPAD_PKT_LEN, 603 usb_buffer_free(xpad->udev, XPAD_PKT_LEN,
403 xpad->idata, xpad->idata_dma); 604 xpad->idata, xpad->idata_dma);
404 kfree(xpad); 605 kfree(xpad);
405 } 606 }
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
index 9950fcb33650..41fc3d03b6eb 100644
--- a/drivers/input/keyboard/atkbd.c
+++ b/drivers/input/keyboard/atkbd.c
@@ -89,7 +89,7 @@ static unsigned char atkbd_set2_keycode[512] = {
89 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 89 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
90 217,100,255, 0, 97,165, 0, 0,156, 0, 0, 0, 0, 0, 0,125, 90 217,100,255, 0, 97,165, 0, 0,156, 0, 0, 0, 0, 0, 0,125,
91 173,114, 0,113, 0, 0, 0,126,128, 0, 0,140, 0, 0, 0,127, 91 173,114, 0,113, 0, 0, 0,126,128, 0, 0,140, 0, 0, 0,127,
92 159, 0,115, 0,164, 0, 0,116,158, 0,150,166, 0, 0, 0,142, 92 159, 0,115, 0,164, 0, 0,116,158, 0,172,166, 0, 0, 0,142,
93 157, 0, 0, 0, 0, 0, 0, 0,155, 0, 98, 0, 0,163, 0, 0, 93 157, 0, 0, 0, 0, 0, 0, 0,155, 0, 98, 0, 0,163, 0, 0,
94 226, 0, 0, 0, 0, 0, 0, 0, 0,255, 96, 0, 0, 0,143, 0, 94 226, 0, 0, 0, 0, 0, 0, 0, 0,255, 96, 0, 0, 0,143, 0,
95 0, 0, 0, 0, 0, 0, 0, 0, 0,107, 0,105,102, 0, 0,112, 95 0, 0, 0, 0, 0, 0, 0, 0, 0,107, 0,105,102, 0, 0,112,
@@ -111,7 +111,7 @@ static unsigned char atkbd_set3_keycode[512] = {
111 82, 83, 80, 76, 77, 72, 69, 98, 0, 96, 81, 0, 78, 73, 55,183, 111 82, 83, 80, 76, 77, 72, 69, 98, 0, 96, 81, 0, 78, 73, 55,183,
112 112
113 184,185,186,187, 74, 94, 92, 93, 0, 0, 0,125,126,127,112, 0, 113 184,185,186,187, 74, 94, 92, 93, 0, 0, 0,125,126,127,112, 0,
114 0,139,150,163,165,115,152,150,166,140,160,154,113,114,167,168, 114 0,139,172,163,165,115,152,172,166,140,160,154,113,114,167,168,
115 148,149,147,140 115 148,149,147,140
116}; 116};
117 117
diff --git a/drivers/input/keyboard/pxa27x_keyboard.c b/drivers/input/keyboard/pxa27x_keyboard.c
index f9e82c9ca421..ebe5eacf2990 100644
--- a/drivers/input/keyboard/pxa27x_keyboard.c
+++ b/drivers/input/keyboard/pxa27x_keyboard.c
@@ -140,7 +140,7 @@ static int pxakbd_resume(struct platform_device *pdev)
140 KPREC = pdata->reg_kprec; 140 KPREC = pdata->reg_kprec;
141 141
142 /* Enable unit clock */ 142 /* Enable unit clock */
143 pxa_set_cken(CKEN19_KEYPAD, 1); 143 pxa_set_cken(CKEN_KEYPAD, 1);
144 } 144 }
145 145
146 mutex_unlock(&input_dev->mutex); 146 mutex_unlock(&input_dev->mutex);
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index 88e29074ac90..9b26574f1466 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -65,9 +65,13 @@ config INPUT_COBALT_BTNS
65config INPUT_WISTRON_BTNS 65config INPUT_WISTRON_BTNS
66 tristate "x86 Wistron laptop button interface" 66 tristate "x86 Wistron laptop button interface"
67 depends on X86 && !X86_64 67 depends on X86 && !X86_64
68 select INPUT_POLLDEV
69 select NEW_LEDS
70 select LEDS_CLASS
68 help 71 help
69 Say Y here for support of Winstron laptop button interface, used on 72 Say Y here for support of Winstron laptop button interface, used on
70 laptops of various brands, including Acer and Fujitsu-Siemens. 73 laptops of various brands, including Acer and Fujitsu-Siemens. If
74 available, mail and wifi leds will be controlable via /sys/class/leds.
71 75
72 To compile this driver as a module, choose M here: the module will 76 To compile this driver as a module, choose M here: the module will
73 be called wistron_btns. 77 be called wistron_btns.
diff --git a/drivers/input/misc/wistron_btns.c b/drivers/input/misc/wistron_btns.c
index 961aad7a0476..60121f10f8d9 100644
--- a/drivers/input/misc/wistron_btns.c
+++ b/drivers/input/misc/wistron_btns.c
@@ -20,37 +20,31 @@
20#include <linux/io.h> 20#include <linux/io.h>
21#include <linux/dmi.h> 21#include <linux/dmi.h>
22#include <linux/init.h> 22#include <linux/init.h>
23#include <linux/input.h> 23#include <linux/input-polldev.h>
24#include <linux/interrupt.h> 24#include <linux/interrupt.h>
25#include <linux/jiffies.h>
25#include <linux/kernel.h> 26#include <linux/kernel.h>
26#include <linux/mc146818rtc.h> 27#include <linux/mc146818rtc.h>
27#include <linux/module.h> 28#include <linux/module.h>
28#include <linux/preempt.h> 29#include <linux/preempt.h>
29#include <linux/string.h> 30#include <linux/string.h>
30#include <linux/timer.h>
31#include <linux/types.h> 31#include <linux/types.h>
32#include <linux/platform_device.h> 32#include <linux/platform_device.h>
33#include <linux/leds.h>
33 34
34/* 35/* How often we poll keys - msecs */
35 * Number of attempts to read data from queue per poll; 36#define POLL_INTERVAL_DEFAULT 500 /* when idle */
36 * the queue can hold up to 31 entries 37#define POLL_INTERVAL_BURST 100 /* when a key was recently pressed */
37 */
38#define MAX_POLL_ITERATIONS 64
39
40#define POLL_FREQUENCY 10 /* Number of polls per second */
41
42#if POLL_FREQUENCY > HZ
43#error "POLL_FREQUENCY too high"
44#endif
45 38
46/* BIOS subsystem IDs */ 39/* BIOS subsystem IDs */
47#define WIFI 0x35 40#define WIFI 0x35
48#define BLUETOOTH 0x34 41#define BLUETOOTH 0x34
42#define MAIL_LED 0x31
49 43
50MODULE_AUTHOR("Miloslav Trmac <mitr@volny.cz>"); 44MODULE_AUTHOR("Miloslav Trmac <mitr@volny.cz>");
51MODULE_DESCRIPTION("Wistron laptop button driver"); 45MODULE_DESCRIPTION("Wistron laptop button driver");
52MODULE_LICENSE("GPL v2"); 46MODULE_LICENSE("GPL v2");
53MODULE_VERSION("0.2"); 47MODULE_VERSION("0.3");
54 48
55static int force; /* = 0; */ 49static int force; /* = 0; */
56module_param(force, bool, 0); 50module_param(force, bool, 0);
@@ -248,9 +242,10 @@ enum { KE_END, KE_KEY, KE_SW, KE_WIFI, KE_BLUETOOTH };
248#define FE_WIFI_LED 0x02 242#define FE_WIFI_LED 0x02
249#define FE_UNTESTED 0x80 243#define FE_UNTESTED 0x80
250 244
251static const struct key_entry *keymap; /* = NULL; Current key map */ 245static struct key_entry *keymap; /* = NULL; Current key map */
252static int have_wifi; 246static int have_wifi;
253static int have_bluetooth; 247static int have_bluetooth;
248static int have_leds;
254 249
255static int __init dmi_matched(struct dmi_system_id *dmi) 250static int __init dmi_matched(struct dmi_system_id *dmi)
256{ 251{
@@ -263,6 +258,8 @@ static int __init dmi_matched(struct dmi_system_id *dmi)
263 else if (key->type == KE_BLUETOOTH) 258 else if (key->type == KE_BLUETOOTH)
264 have_bluetooth = 1; 259 have_bluetooth = 1;
265 } 260 }
261 have_leds = key->code & (FE_MAIL_LED | FE_WIFI_LED);
262
266 return 1; 263 return 1;
267} 264}
268 265
@@ -966,118 +963,163 @@ static int __init select_keymap(void)
966 963
967 /* Input layer interface */ 964 /* Input layer interface */
968 965
969static struct input_dev *input_dev; 966static struct input_polled_dev *wistron_idev;
967static unsigned long jiffies_last_press;
968static int wifi_enabled;
969static int bluetooth_enabled;
970 970
971static int __devinit setup_input_dev(void) 971static void report_key(struct input_dev *dev, unsigned int keycode)
972{ 972{
973 const struct key_entry *key; 973 input_report_key(dev, keycode, 1);
974 int error; 974 input_sync(dev);
975 input_report_key(dev, keycode, 0);
976 input_sync(dev);
977}
975 978
976 input_dev = input_allocate_device(); 979static void report_switch(struct input_dev *dev, unsigned int code, int value)
977 if (!input_dev) 980{
978 return -ENOMEM; 981 input_report_switch(dev, code, value);
982 input_sync(dev);
983}
979 984
980 input_dev->name = "Wistron laptop buttons";
981 input_dev->phys = "wistron/input0";
982 input_dev->id.bustype = BUS_HOST;
983 input_dev->cdev.dev = &wistron_device->dev;
984 985
985 for (key = keymap; key->type != KE_END; key++) { 986 /* led management */
986 switch (key->type) { 987static void wistron_mail_led_set(struct led_classdev *led_cdev,
987 case KE_KEY: 988 enum led_brightness value)
988 set_bit(EV_KEY, input_dev->evbit); 989{
989 set_bit(key->keycode, input_dev->keybit); 990 bios_set_state(MAIL_LED, (value != LED_OFF) ? 1 : 0);
990 break; 991}
991 992
992 case KE_SW: 993/* same as setting up wifi card, but for laptops on which the led is managed */
993 set_bit(EV_SW, input_dev->evbit); 994static void wistron_wifi_led_set(struct led_classdev *led_cdev,
994 set_bit(key->sw.code, input_dev->swbit); 995 enum led_brightness value)
995 break; 996{
997 bios_set_state(WIFI, (value != LED_OFF) ? 1 : 0);
998}
996 999
997 default: 1000static struct led_classdev wistron_mail_led = {
998 ; 1001 .name = "mail:green",
999 } 1002 .brightness_set = wistron_mail_led_set,
1000 } 1003};
1001 1004
1002 /* reads information flags on KE_END */ 1005static struct led_classdev wistron_wifi_led = {
1003 if (key->code & FE_UNTESTED) 1006 .name = "wifi:red",
1004 printk(KERN_WARNING "Untested laptop multimedia keys, " 1007 .brightness_set = wistron_wifi_led_set,
1005 "please report success or failure to eric.piel" 1008};
1006 "@tremplin-utc.net\n");
1007 1009
1008 error = input_register_device(input_dev); 1010static void __devinit wistron_led_init(struct device *parent)
1009 if (error) { 1011{
1010 input_free_device(input_dev); 1012 if (have_leds & FE_WIFI_LED) {
1011 return error; 1013 u16 wifi = bios_get_default_setting(WIFI);
1014 if (wifi & 1) {
1015 wistron_wifi_led.brightness = (wifi & 2) ? LED_FULL : LED_OFF;
1016 if (led_classdev_register(parent, &wistron_wifi_led))
1017 have_leds &= ~FE_WIFI_LED;
1018 else
1019 bios_set_state(WIFI, wistron_wifi_led.brightness);
1020
1021 } else
1022 have_leds &= ~FE_WIFI_LED;
1012 } 1023 }
1013 1024
1014 return 0; 1025 if (have_leds & FE_MAIL_LED) {
1026 /* bios_get_default_setting(MAIL) always retuns 0, so just turn the led off */
1027 wistron_mail_led.brightness = LED_OFF;
1028 if (led_classdev_register(parent, &wistron_mail_led))
1029 have_leds &= ~FE_MAIL_LED;
1030 else
1031 bios_set_state(MAIL_LED, wistron_mail_led.brightness);
1032 }
1015} 1033}
1016 1034
1017static void report_key(unsigned keycode) 1035static void __devexit wistron_led_remove(void)
1018{ 1036{
1019 input_report_key(input_dev, keycode, 1); 1037 if (have_leds & FE_MAIL_LED)
1020 input_sync(input_dev); 1038 led_classdev_unregister(&wistron_mail_led);
1021 input_report_key(input_dev, keycode, 0); 1039
1022 input_sync(input_dev); 1040 if (have_leds & FE_WIFI_LED)
1041 led_classdev_unregister(&wistron_wifi_led);
1023} 1042}
1024 1043
1025static void report_switch(unsigned code, int value) 1044static inline void wistron_led_suspend(void)
1026{ 1045{
1027 input_report_switch(input_dev, code, value); 1046 if (have_leds & FE_MAIL_LED)
1028 input_sync(input_dev); 1047 led_classdev_suspend(&wistron_mail_led);
1048
1049 if (have_leds & FE_WIFI_LED)
1050 led_classdev_suspend(&wistron_wifi_led);
1029} 1051}
1030 1052
1031 /* Driver core */ 1053static inline void wistron_led_resume(void)
1054{
1055 if (have_leds & FE_MAIL_LED)
1056 led_classdev_resume(&wistron_mail_led);
1032 1057
1033static int wifi_enabled; 1058 if (have_leds & FE_WIFI_LED)
1034static int bluetooth_enabled; 1059 led_classdev_resume(&wistron_wifi_led);
1060}
1061
1062static struct key_entry *wistron_get_entry_by_scancode(int code)
1063{
1064 struct key_entry *key;
1035 1065
1036static void poll_bios(unsigned long); 1066 for (key = keymap; key->type != KE_END; key++)
1067 if (code == key->code)
1068 return key;
1037 1069
1038static struct timer_list poll_timer = TIMER_INITIALIZER(poll_bios, 0, 0); 1070 return NULL;
1071}
1039 1072
1040static void handle_key(u8 code) 1073static struct key_entry *wistron_get_entry_by_keycode(int keycode)
1041{ 1074{
1042 const struct key_entry *key; 1075 struct key_entry *key;
1043 1076
1044 for (key = keymap; key->type != KE_END; key++) { 1077 for (key = keymap; key->type != KE_END; key++)
1045 if (code == key->code) { 1078 if (key->type == KE_KEY && keycode == key->keycode)
1046 switch (key->type) { 1079 return key;
1047 case KE_KEY:
1048 report_key(key->keycode);
1049 break;
1050 1080
1051 case KE_SW: 1081 return NULL;
1052 report_switch(key->sw.code, key->sw.value); 1082}
1053 break;
1054 1083
1055 case KE_WIFI: 1084static void handle_key(u8 code)
1056 if (have_wifi) { 1085{
1057 wifi_enabled = !wifi_enabled; 1086 const struct key_entry *key = wistron_get_entry_by_scancode(code);
1058 bios_set_state(WIFI, wifi_enabled);
1059 }
1060 break;
1061 1087
1062 case KE_BLUETOOTH: 1088 if (key) {
1063 if (have_bluetooth) { 1089 switch (key->type) {
1064 bluetooth_enabled = !bluetooth_enabled; 1090 case KE_KEY:
1065 bios_set_state(BLUETOOTH, bluetooth_enabled); 1091 report_key(wistron_idev->input, key->keycode);
1066 } 1092 break;
1067 break;
1068 1093
1069 case KE_END: 1094 case KE_SW:
1070 break; 1095 report_switch(wistron_idev->input,
1071 default: 1096 key->sw.code, key->sw.value);
1072 BUG(); 1097 break;
1098
1099 case KE_WIFI:
1100 if (have_wifi) {
1101 wifi_enabled = !wifi_enabled;
1102 bios_set_state(WIFI, wifi_enabled);
1103 }
1104 break;
1105
1106 case KE_BLUETOOTH:
1107 if (have_bluetooth) {
1108 bluetooth_enabled = !bluetooth_enabled;
1109 bios_set_state(BLUETOOTH, bluetooth_enabled);
1073 } 1110 }
1074 return; 1111 break;
1112
1113 default:
1114 BUG();
1075 } 1115 }
1076 } 1116 jiffies_last_press = jiffies;
1077 printk(KERN_NOTICE "wistron_btns: Unknown key code %02X\n", code); 1117 } else
1118 printk(KERN_NOTICE
1119 "wistron_btns: Unknown key code %02X\n", code);
1078} 1120}
1079 1121
1080static void poll_bios(unsigned long discard) 1122static void poll_bios(bool discard)
1081{ 1123{
1082 u8 qlen; 1124 u8 qlen;
1083 u16 val; 1125 u16 val;
@@ -1090,15 +1132,118 @@ static void poll_bios(unsigned long discard)
1090 if (val != 0 && !discard) 1132 if (val != 0 && !discard)
1091 handle_key((u8)val); 1133 handle_key((u8)val);
1092 } 1134 }
1135}
1136
1137static void wistron_flush(struct input_polled_dev *dev)
1138{
1139 /* Flush stale event queue */
1140 poll_bios(true);
1141}
1142
1143static void wistron_poll(struct input_polled_dev *dev)
1144{
1145 poll_bios(false);
1146
1147 /* Increase poll frequency if user is currently pressing keys (< 2s ago) */
1148 if (time_before(jiffies, jiffies_last_press + 2 * HZ))
1149 dev->poll_interval = POLL_INTERVAL_BURST;
1150 else
1151 dev->poll_interval = POLL_INTERVAL_DEFAULT;
1152}
1153
1154static int wistron_getkeycode(struct input_dev *dev, int scancode, int *keycode)
1155{
1156 const struct key_entry *key = wistron_get_entry_by_scancode(scancode);
1157
1158 if (key && key->type == KE_KEY) {
1159 *keycode = key->keycode;
1160 return 0;
1161 }
1162
1163 return -EINVAL;
1164}
1165
1166static int wistron_setkeycode(struct input_dev *dev, int scancode, int keycode)
1167{
1168 struct key_entry *key;
1169 int old_keycode;
1170
1171 if (keycode < 0 || keycode > KEY_MAX)
1172 return -EINVAL;
1173
1174 key = wistron_get_entry_by_scancode(scancode);
1175 if (key && key->type == KE_KEY) {
1176 old_keycode = key->keycode;
1177 key->keycode = keycode;
1178 set_bit(keycode, dev->keybit);
1179 if (!wistron_get_entry_by_keycode(old_keycode))
1180 clear_bit(old_keycode, dev->keybit);
1181 return 0;
1182 }
1093 1183
1094 mod_timer(&poll_timer, jiffies + HZ / POLL_FREQUENCY); 1184 return -EINVAL;
1095} 1185}
1096 1186
1187static int __devinit setup_input_dev(void)
1188{
1189 const struct key_entry *key;
1190 struct input_dev *input_dev;
1191 int error;
1192
1193 wistron_idev = input_allocate_polled_device();
1194 if (!wistron_idev)
1195 return -ENOMEM;
1196
1197 wistron_idev->flush = wistron_flush;
1198 wistron_idev->poll = wistron_poll;
1199 wistron_idev->poll_interval = POLL_INTERVAL_DEFAULT;
1200
1201 input_dev = wistron_idev->input;
1202 input_dev->name = "Wistron laptop buttons";
1203 input_dev->phys = "wistron/input0";
1204 input_dev->id.bustype = BUS_HOST;
1205 input_dev->dev.parent = &wistron_device->dev;
1206
1207 input_dev->getkeycode = wistron_getkeycode;
1208 input_dev->setkeycode = wistron_setkeycode;
1209
1210 for (key = keymap; key->type != KE_END; key++) {
1211 switch (key->type) {
1212 case KE_KEY:
1213 set_bit(EV_KEY, input_dev->evbit);
1214 set_bit(key->keycode, input_dev->keybit);
1215 break;
1216
1217 case KE_SW:
1218 set_bit(EV_SW, input_dev->evbit);
1219 set_bit(key->sw.code, input_dev->swbit);
1220 break;
1221
1222 default:
1223 break;
1224 }
1225 }
1226
1227 /* reads information flags on KE_END */
1228 if (key->code & FE_UNTESTED)
1229 printk(KERN_WARNING "Untested laptop multimedia keys, "
1230 "please report success or failure to eric.piel"
1231 "@tremplin-utc.net\n");
1232
1233 error = input_register_polled_device(wistron_idev);
1234 if (error) {
1235 input_free_polled_device(wistron_idev);
1236 return error;
1237 }
1238
1239 return 0;
1240}
1241
1242/* Driver core */
1243
1097static int __devinit wistron_probe(struct platform_device *dev) 1244static int __devinit wistron_probe(struct platform_device *dev)
1098{ 1245{
1099 int err = setup_input_dev(); 1246 int err;
1100 if (err)
1101 return err;
1102 1247
1103 bios_attach(); 1248 bios_attach();
1104 cmos_address = bios_get_cmos_address(); 1249 cmos_address = bios_get_cmos_address();
@@ -1125,15 +1270,21 @@ static int __devinit wistron_probe(struct platform_device *dev)
1125 bios_set_state(BLUETOOTH, bluetooth_enabled); 1270 bios_set_state(BLUETOOTH, bluetooth_enabled);
1126 } 1271 }
1127 1272
1128 poll_bios(1); /* Flush stale event queue and arm timer */ 1273 wistron_led_init(&dev->dev);
1274 err = setup_input_dev();
1275 if (err) {
1276 bios_detach();
1277 return err;
1278 }
1129 1279
1130 return 0; 1280 return 0;
1131} 1281}
1132 1282
1133static int __devexit wistron_remove(struct platform_device *dev) 1283static int __devexit wistron_remove(struct platform_device *dev)
1134{ 1284{
1135 del_timer_sync(&poll_timer); 1285 wistron_led_remove();
1136 input_unregister_device(input_dev); 1286 input_unregister_polled_device(wistron_idev);
1287 input_free_polled_device(wistron_idev);
1137 bios_detach(); 1288 bios_detach();
1138 1289
1139 return 0; 1290 return 0;
@@ -1142,14 +1293,13 @@ static int __devexit wistron_remove(struct platform_device *dev)
1142#ifdef CONFIG_PM 1293#ifdef CONFIG_PM
1143static int wistron_suspend(struct platform_device *dev, pm_message_t state) 1294static int wistron_suspend(struct platform_device *dev, pm_message_t state)
1144{ 1295{
1145 del_timer_sync(&poll_timer);
1146
1147 if (have_wifi) 1296 if (have_wifi)
1148 bios_set_state(WIFI, 0); 1297 bios_set_state(WIFI, 0);
1149 1298
1150 if (have_bluetooth) 1299 if (have_bluetooth)
1151 bios_set_state(BLUETOOTH, 0); 1300 bios_set_state(BLUETOOTH, 0);
1152 1301
1302 wistron_led_suspend();
1153 return 0; 1303 return 0;
1154} 1304}
1155 1305
@@ -1161,7 +1311,8 @@ static int wistron_resume(struct platform_device *dev)
1161 if (have_bluetooth) 1311 if (have_bluetooth)
1162 bios_set_state(BLUETOOTH, bluetooth_enabled); 1312 bios_set_state(BLUETOOTH, bluetooth_enabled);
1163 1313
1164 poll_bios(1); 1314 wistron_led_resume();
1315 poll_bios(true);
1165 1316
1166 return 0; 1317 return 0;
1167} 1318}
diff --git a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig
index 50e06e8dd05d..7bbea097cda2 100644
--- a/drivers/input/mouse/Kconfig
+++ b/drivers/input/mouse/Kconfig
@@ -216,4 +216,20 @@ config MOUSE_HIL
216 help 216 help
217 Say Y here to support HIL pointers. 217 Say Y here to support HIL pointers.
218 218
219config MOUSE_GPIO
220 tristate "GPIO mouse"
221 depends on GENERIC_GPIO
222 select INPUT_POLLDEV
223 help
224 This driver simulates a mouse on GPIO lines of various CPUs (and some
225 other chips).
226
227 Say Y here if your device has buttons or a simple joystick connected
228 directly to GPIO lines. Your board-specific setup logic must also
229 provide a platform device and platform data saying which GPIOs are
230 used.
231
232 To compile this driver as a module, choose M here: the
233 module will be called gpio_mouse.
234
219endif 235endif
diff --git a/drivers/input/mouse/Makefile b/drivers/input/mouse/Makefile
index aa4ba878533f..9e6e36330820 100644
--- a/drivers/input/mouse/Makefile
+++ b/drivers/input/mouse/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_MOUSE_PS2) += psmouse.o
15obj-$(CONFIG_MOUSE_SERIAL) += sermouse.o 15obj-$(CONFIG_MOUSE_SERIAL) += sermouse.o
16obj-$(CONFIG_MOUSE_HIL) += hil_ptr.o 16obj-$(CONFIG_MOUSE_HIL) += hil_ptr.o
17obj-$(CONFIG_MOUSE_VSXXXAA) += vsxxxaa.o 17obj-$(CONFIG_MOUSE_VSXXXAA) += vsxxxaa.o
18obj-$(CONFIG_MOUSE_GPIO) += gpio_mouse.o
18 19
19psmouse-objs := psmouse-base.o synaptics.o 20psmouse-objs := psmouse-base.o synaptics.o
20 21
diff --git a/drivers/input/mouse/gpio_mouse.c b/drivers/input/mouse/gpio_mouse.c
new file mode 100644
index 000000000000..0936d6ba015c
--- /dev/null
+++ b/drivers/input/mouse/gpio_mouse.c
@@ -0,0 +1,196 @@
1/*
2 * Driver for simulating a mouse on GPIO lines.
3 *
4 * Copyright (C) 2007 Atmel Corporation
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/init.h>
12#include <linux/version.h>
13#include <linux/module.h>
14#include <linux/platform_device.h>
15#include <linux/input-polldev.h>
16#include <linux/gpio_mouse.h>
17
18#include <asm/gpio.h>
19
20/*
21 * Timer function which is run every scan_ms ms when the device is opened.
22 * The dev input varaible is set to the the input_dev pointer.
23 */
24static void gpio_mouse_scan(struct input_polled_dev *dev)
25{
26 struct gpio_mouse_platform_data *gpio = dev->private;
27 struct input_dev *input = dev->input;
28 int x, y;
29
30 if (gpio->bleft >= 0)
31 input_report_key(input, BTN_LEFT,
32 gpio_get_value(gpio->bleft) ^ gpio->polarity);
33 if (gpio->bmiddle >= 0)
34 input_report_key(input, BTN_MIDDLE,
35 gpio_get_value(gpio->bmiddle) ^ gpio->polarity);
36 if (gpio->bright >= 0)
37 input_report_key(input, BTN_RIGHT,
38 gpio_get_value(gpio->bright) ^ gpio->polarity);
39
40 x = (gpio_get_value(gpio->right) ^ gpio->polarity)
41 - (gpio_get_value(gpio->left) ^ gpio->polarity);
42 y = (gpio_get_value(gpio->down) ^ gpio->polarity)
43 - (gpio_get_value(gpio->up) ^ gpio->polarity);
44
45 input_report_rel(input, REL_X, x);
46 input_report_rel(input, REL_Y, y);
47 input_sync(input);
48}
49
50static int __init gpio_mouse_probe(struct platform_device *pdev)
51{
52 struct gpio_mouse_platform_data *pdata = pdev->dev.platform_data;
53 struct input_polled_dev *input_poll;
54 struct input_dev *input;
55 int pin, i;
56 int error;
57
58 if (!pdata) {
59 dev_err(&pdev->dev, "no platform data\n");
60 error = -ENXIO;
61 goto out;
62 }
63
64 if (pdata->scan_ms < 0) {
65 dev_err(&pdev->dev, "invalid scan time\n");
66 error = -EINVAL;
67 goto out;
68 }
69
70 for (i = 0; i < GPIO_MOUSE_PIN_MAX; i++) {
71 pin = pdata->pins[i];
72
73 if (pin < 0) {
74
75 if (i <= GPIO_MOUSE_PIN_RIGHT) {
76 /* Mouse direction is required. */
77 dev_err(&pdev->dev,
78 "missing GPIO for directions\n");
79 error = -EINVAL;
80 goto out_free_gpios;
81 }
82
83 if (i == GPIO_MOUSE_PIN_BLEFT)
84 dev_dbg(&pdev->dev, "no left button defined\n");
85
86 } else {
87 error = gpio_request(pin, "gpio_mouse");
88 if (error) {
89 dev_err(&pdev->dev, "fail %d pin (%d idx)\n",
90 pin, i);
91 goto out_free_gpios;
92 }
93
94 gpio_direction_input(pin);
95 }
96 }
97
98 input_poll = input_allocate_polled_device();
99 if (!input_poll) {
100 dev_err(&pdev->dev, "not enough memory for input device\n");
101 error = -ENOMEM;
102 goto out_free_gpios;
103 }
104
105 platform_set_drvdata(pdev, input_poll);
106
107 /* set input-polldev handlers */
108 input_poll->private = pdata;
109 input_poll->poll = gpio_mouse_scan;
110 input_poll->poll_interval = pdata->scan_ms;
111
112 input = input_poll->input;
113 input->name = pdev->name;
114 input->id.bustype = BUS_HOST;
115 input->dev.parent = &pdev->dev;
116
117 input_set_capability(input, EV_REL, REL_X);
118 input_set_capability(input, EV_REL, REL_Y);
119 if (pdata->bleft >= 0)
120 input_set_capability(input, EV_KEY, BTN_LEFT);
121 if (pdata->bmiddle >= 0)
122 input_set_capability(input, EV_KEY, BTN_MIDDLE);
123 if (pdata->bright >= 0)
124 input_set_capability(input, EV_KEY, BTN_RIGHT);
125
126 error = input_register_polled_device(input_poll);
127 if (error) {
128 dev_err(&pdev->dev, "could not register input device\n");
129 goto out_free_polldev;
130 }
131
132 dev_dbg(&pdev->dev, "%d ms scan time, buttons: %s%s%s\n",
133 pdata->scan_ms,
134 pdata->bleft < 0 ? "" : "left ",
135 pdata->bmiddle < 0 ? "" : "middle ",
136 pdata->bright < 0 ? "" : "right");
137
138 return 0;
139
140 out_free_polldev:
141 input_free_polled_device(input_poll);
142 platform_set_drvdata(pdev, NULL);
143
144 out_free_gpios:
145 while (--i >= 0) {
146 pin = pdata->pins[i];
147 if (pin)
148 gpio_free(pin);
149 }
150 out:
151 return error;
152}
153
154static int __devexit gpio_mouse_remove(struct platform_device *pdev)
155{
156 struct input_polled_dev *input = platform_get_drvdata(pdev);
157 struct gpio_mouse_platform_data *pdata = input->private;
158 int pin, i;
159
160 input_unregister_polled_device(input);
161 input_free_polled_device(input);
162
163 for (i = 0; i < GPIO_MOUSE_PIN_MAX; i++) {
164 pin = pdata->pins[i];
165 if (pin >= 0)
166 gpio_free(pin);
167 }
168
169 platform_set_drvdata(pdev, NULL);
170
171 return 0;
172}
173
174struct platform_driver gpio_mouse_device_driver = {
175 .remove = __devexit_p(gpio_mouse_remove),
176 .driver = {
177 .name = "gpio_mouse",
178 }
179};
180
181static int __init gpio_mouse_init(void)
182{
183 return platform_driver_probe(&gpio_mouse_device_driver,
184 gpio_mouse_probe);
185}
186module_init(gpio_mouse_init);
187
188static void __exit gpio_mouse_exit(void)
189{
190 platform_driver_unregister(&gpio_mouse_device_driver);
191}
192module_exit(gpio_mouse_exit);
193
194MODULE_AUTHOR("Hans-Christian Egtvedt <hcegtvedt@atmel.com>");
195MODULE_DESCRIPTION("GPIO mouse driver");
196MODULE_LICENSE("GPL");
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
index f15f695777f8..b9f0fb2530e2 100644
--- a/drivers/input/mouse/psmouse-base.c
+++ b/drivers/input/mouse/psmouse-base.c
@@ -178,6 +178,15 @@ static psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse)
178 } 178 }
179 179
180/* 180/*
181 * Cortron PS2 Trackball reports SIDE button on the 4th bit of the first
182 * byte.
183 */
184 if (psmouse->type == PSMOUSE_CORTRON) {
185 input_report_key(dev, BTN_SIDE, (packet[0] >> 3) & 1);
186 packet[0] |= 0x08;
187 }
188
189/*
181 * Generic PS/2 Mouse 190 * Generic PS/2 Mouse
182 */ 191 */
183 192
@@ -539,6 +548,20 @@ static int ps2bare_detect(struct psmouse *psmouse, int set_properties)
539 return 0; 548 return 0;
540} 549}
541 550
551/*
552 * Cortron PS/2 protocol detection. There's no special way to detect it, so it
553 * must be forced by sysfs protocol writing.
554 */
555static int cortron_detect(struct psmouse *psmouse, int set_properties)
556{
557 if (set_properties) {
558 psmouse->vendor = "Cortron";
559 psmouse->name = "PS/2 Trackball";
560 set_bit(BTN_SIDE, psmouse->dev->keybit);
561 }
562
563 return 0;
564}
542 565
543/* 566/*
544 * psmouse_extensions() probes for any extensions to the basic PS/2 protocol 567 * psmouse_extensions() probes for any extensions to the basic PS/2 protocol
@@ -740,6 +763,12 @@ static const struct psmouse_protocol psmouse_protocols[] = {
740 }, 763 },
741#endif 764#endif
742 { 765 {
766 .type = PSMOUSE_CORTRON,
767 .name = "CortronPS/2",
768 .alias = "cortps",
769 .detect = cortron_detect,
770 },
771 {
743 .type = PSMOUSE_AUTO, 772 .type = PSMOUSE_AUTO,
744 .name = "auto", 773 .name = "auto",
745 .alias = "any", 774 .alias = "any",
diff --git a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h
index 3964e8acbc54..27a68835b5ba 100644
--- a/drivers/input/mouse/psmouse.h
+++ b/drivers/input/mouse/psmouse.h
@@ -88,6 +88,7 @@ enum psmouse_type {
88 PSMOUSE_LIFEBOOK, 88 PSMOUSE_LIFEBOOK,
89 PSMOUSE_TRACKPOINT, 89 PSMOUSE_TRACKPOINT,
90 PSMOUSE_TOUCHKIT_PS2, 90 PSMOUSE_TOUCHKIT_PS2,
91 PSMOUSE_CORTRON,
91 PSMOUSE_AUTO /* This one should always be last */ 92 PSMOUSE_AUTO /* This one should always be last */
92}; 93};
93 94
diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c
index 3f4866d8d18c..9173916b8be5 100644
--- a/drivers/input/mousedev.c
+++ b/drivers/input/mousedev.c
@@ -64,6 +64,7 @@ struct mousedev {
64 wait_queue_head_t wait; 64 wait_queue_head_t wait;
65 struct list_head client_list; 65 struct list_head client_list;
66 struct input_handle handle; 66 struct input_handle handle;
67 struct device dev;
67 68
68 struct list_head mixdev_node; 69 struct list_head mixdev_node;
69 int mixdev_open; 70 int mixdev_open;
@@ -112,7 +113,7 @@ static unsigned char mousedev_imex_seq[] = { 0xf3, 200, 0xf3, 200, 0xf3, 80 };
112static struct input_handler mousedev_handler; 113static struct input_handler mousedev_handler;
113 114
114static struct mousedev *mousedev_table[MOUSEDEV_MINORS]; 115static struct mousedev *mousedev_table[MOUSEDEV_MINORS];
115static struct mousedev mousedev_mix; 116static struct mousedev *mousedev_mix;
116static LIST_HEAD(mousedev_mix_list); 117static LIST_HEAD(mousedev_mix_list);
117 118
118#define fx(i) (mousedev->old_x[(mousedev->pkt_count - (i)) & 03]) 119#define fx(i) (mousedev->old_x[(mousedev->pkt_count - (i)) & 03])
@@ -218,10 +219,10 @@ static void mousedev_key_event(struct mousedev *mousedev, unsigned int code, int
218 219
219 if (value) { 220 if (value) {
220 set_bit(index, &mousedev->packet.buttons); 221 set_bit(index, &mousedev->packet.buttons);
221 set_bit(index, &mousedev_mix.packet.buttons); 222 set_bit(index, &mousedev_mix->packet.buttons);
222 } else { 223 } else {
223 clear_bit(index, &mousedev->packet.buttons); 224 clear_bit(index, &mousedev->packet.buttons);
224 clear_bit(index, &mousedev_mix.packet.buttons); 225 clear_bit(index, &mousedev_mix->packet.buttons);
225 } 226 }
226} 227}
227 228
@@ -287,11 +288,11 @@ static void mousedev_touchpad_touch(struct mousedev *mousedev, int value)
287 * motion packet so we won't mess current position. 288 * motion packet so we won't mess current position.
288 */ 289 */
289 set_bit(0, &mousedev->packet.buttons); 290 set_bit(0, &mousedev->packet.buttons);
290 set_bit(0, &mousedev_mix.packet.buttons); 291 set_bit(0, &mousedev_mix->packet.buttons);
291 mousedev_notify_readers(mousedev, &mousedev_mix.packet); 292 mousedev_notify_readers(mousedev, &mousedev_mix->packet);
292 mousedev_notify_readers(&mousedev_mix, &mousedev_mix.packet); 293 mousedev_notify_readers(mousedev_mix, &mousedev_mix->packet);
293 clear_bit(0, &mousedev->packet.buttons); 294 clear_bit(0, &mousedev->packet.buttons);
294 clear_bit(0, &mousedev_mix.packet.buttons); 295 clear_bit(0, &mousedev_mix->packet.buttons);
295 } 296 }
296 mousedev->touch = mousedev->pkt_count = 0; 297 mousedev->touch = mousedev->pkt_count = 0;
297 mousedev->frac_dx = 0; 298 mousedev->frac_dx = 0;
@@ -343,7 +344,7 @@ static void mousedev_event(struct input_handle *handle, unsigned int type, unsig
343 } 344 }
344 345
345 mousedev_notify_readers(mousedev, &mousedev->packet); 346 mousedev_notify_readers(mousedev, &mousedev->packet);
346 mousedev_notify_readers(&mousedev_mix, &mousedev->packet); 347 mousedev_notify_readers(mousedev_mix, &mousedev->packet);
347 348
348 mousedev->packet.dx = mousedev->packet.dy = mousedev->packet.dz = 0; 349 mousedev->packet.dx = mousedev->packet.dy = mousedev->packet.dz = 0;
349 mousedev->packet.abs_event = 0; 350 mousedev->packet.abs_event = 0;
@@ -362,8 +363,10 @@ static int mousedev_fasync(int fd, struct file *file, int on)
362 return retval < 0 ? retval : 0; 363 return retval < 0 ? retval : 0;
363} 364}
364 365
365static void mousedev_free(struct mousedev *mousedev) 366static void mousedev_free(struct device *dev)
366{ 367{
368 struct mousedev *mousedev = container_of(dev, struct mousedev, dev);
369
367 mousedev_table[mousedev->minor] = NULL; 370 mousedev_table[mousedev->minor] = NULL;
368 kfree(mousedev); 371 kfree(mousedev);
369} 372}
@@ -372,15 +375,16 @@ static int mixdev_add_device(struct mousedev *mousedev)
372{ 375{
373 int error; 376 int error;
374 377
375 if (mousedev_mix.open) { 378 if (mousedev_mix->open) {
376 error = input_open_device(&mousedev->handle); 379 error = input_open_device(&mousedev->handle);
377 if (error) 380 if (error)
378 return error; 381 return error;
379 382
380 mousedev->open++; 383 mousedev->open++;
381 mousedev->mixdev_open++; 384 mousedev->mixdev_open = 1;
382 } 385 }
383 386
387 get_device(&mousedev->dev);
384 list_add_tail(&mousedev->mixdev_node, &mousedev_mix_list); 388 list_add_tail(&mousedev->mixdev_node, &mousedev_mix_list);
385 389
386 return 0; 390 return 0;
@@ -395,36 +399,40 @@ static void mixdev_remove_device(struct mousedev *mousedev)
395 } 399 }
396 400
397 list_del_init(&mousedev->mixdev_node); 401 list_del_init(&mousedev->mixdev_node);
402 put_device(&mousedev->dev);
398} 403}
399 404
400static void mixdev_open_devices(void) 405static void mixdev_open_devices(void)
401{ 406{
402 struct mousedev *mousedev; 407 struct mousedev *mousedev;
403 408
409 if (mousedev_mix->open++)
410 return;
411
404 list_for_each_entry(mousedev, &mousedev_mix_list, mixdev_node) { 412 list_for_each_entry(mousedev, &mousedev_mix_list, mixdev_node) {
405 if (mousedev->exist && !mousedev->open) { 413 if (!mousedev->mixdev_open) {
406 if (input_open_device(&mousedev->handle)) 414 if (!mousedev->open && mousedev->exist)
407 continue; 415 if (input_open_device(&mousedev->handle))
416 continue;
408 417
409 mousedev->open++; 418 mousedev->open++;
410 mousedev->mixdev_open++; 419 mousedev->mixdev_open = 1;
411 } 420 }
412 } 421 }
413} 422}
414 423
415static void mixdev_close_devices(void) 424static void mixdev_close_devices(void)
416{ 425{
417 struct mousedev *mousedev, *next; 426 struct mousedev *mousedev;
418 427
419 list_for_each_entry_safe(mousedev, next, &mousedev_mix_list, mixdev_node) { 428 if (--mousedev_mix->open)
429 return;
430
431 list_for_each_entry(mousedev, &mousedev_mix_list, mixdev_node) {
420 if (mousedev->mixdev_open) { 432 if (mousedev->mixdev_open) {
421 mousedev->mixdev_open = 0; 433 mousedev->mixdev_open = 0;
422 if (!--mousedev->open) { 434 if (!--mousedev->open && mousedev->exist)
423 if (mousedev->exist) 435 input_close_device(&mousedev->handle);
424 input_close_device(&mousedev->handle);
425 else
426 mousedev_free(mousedev);
427 }
428 } 436 }
429 } 437 }
430} 438}
@@ -439,14 +447,12 @@ static int mousedev_release(struct inode *inode, struct file *file)
439 list_del(&client->node); 447 list_del(&client->node);
440 kfree(client); 448 kfree(client);
441 449
442 if (!--mousedev->open) { 450 if (mousedev->minor == MOUSEDEV_MIX)
443 if (mousedev->minor == MOUSEDEV_MIX) 451 mixdev_close_devices();
444 mixdev_close_devices(); 452 else if (!--mousedev->open && mousedev->exist)
445 else if (mousedev->exist) 453 input_close_device(&mousedev->handle);
446 input_close_device(&mousedev->handle); 454
447 else 455 put_device(&mousedev->dev);
448 mousedev_free(mousedev);
449 }
450 456
451 return 0; 457 return 0;
452} 458}
@@ -473,9 +479,13 @@ static int mousedev_open(struct inode *inode, struct file *file)
473 if (!mousedev) 479 if (!mousedev)
474 return -ENODEV; 480 return -ENODEV;
475 481
482 get_device(&mousedev->dev);
483
476 client = kzalloc(sizeof(struct mousedev_client), GFP_KERNEL); 484 client = kzalloc(sizeof(struct mousedev_client), GFP_KERNEL);
477 if (!client) 485 if (!client) {
478 return -ENOMEM; 486 error = -ENOMEM;
487 goto err_put_mousedev;
488 }
479 489
480 spin_lock_init(&client->packet_lock); 490 spin_lock_init(&client->packet_lock);
481 client->pos_x = xres / 2; 491 client->pos_x = xres / 2;
@@ -483,21 +493,23 @@ static int mousedev_open(struct inode *inode, struct file *file)
483 client->mousedev = mousedev; 493 client->mousedev = mousedev;
484 list_add_tail(&client->node, &mousedev->client_list); 494 list_add_tail(&client->node, &mousedev->client_list);
485 495
486 if (!mousedev->open++) { 496 if (mousedev->minor == MOUSEDEV_MIX)
487 if (mousedev->minor == MOUSEDEV_MIX) 497 mixdev_open_devices();
488 mixdev_open_devices(); 498 else if (!mousedev->open++ && mousedev->exist) {
489 else if (mousedev->exist) { 499 error = input_open_device(&mousedev->handle);
490 error = input_open_device(&mousedev->handle); 500 if (error)
491 if (error) { 501 goto err_free_client;
492 list_del(&client->node);
493 kfree(client);
494 return error;
495 }
496 }
497 } 502 }
498 503
499 file->private_data = client; 504 file->private_data = client;
500 return 0; 505 return 0;
506
507 err_free_client:
508 list_del(&client->node);
509 kfree(client);
510 err_put_mousedev:
511 put_device(&mousedev->dev);
512 return error;
501} 513}
502 514
503static inline int mousedev_limit_delta(int delta, int limit) 515static inline int mousedev_limit_delta(int delta, int limit)
@@ -680,57 +692,96 @@ static const struct file_operations mousedev_fops = {
680 .fasync = mousedev_fasync, 692 .fasync = mousedev_fasync,
681}; 693};
682 694
683static int mousedev_connect(struct input_handler *handler, struct input_dev *dev, 695static struct mousedev *mousedev_create(struct input_dev *dev,
684 const struct input_device_id *id) 696 struct input_handler *handler,
697 int minor)
685{ 698{
686 struct mousedev *mousedev; 699 struct mousedev *mousedev;
687 struct class_device *cdev;
688 dev_t devt;
689 int minor;
690 int error; 700 int error;
691 701
692 for (minor = 0; minor < MOUSEDEV_MINORS && mousedev_table[minor]; minor++);
693 if (minor == MOUSEDEV_MINORS) {
694 printk(KERN_ERR "mousedev: no more free mousedev devices\n");
695 return -ENFILE;
696 }
697
698 mousedev = kzalloc(sizeof(struct mousedev), GFP_KERNEL); 702 mousedev = kzalloc(sizeof(struct mousedev), GFP_KERNEL);
699 if (!mousedev) 703 if (!mousedev) {
700 return -ENOMEM; 704 error = -ENOMEM;
705 goto err_out;
706 }
701 707
702 INIT_LIST_HEAD(&mousedev->client_list); 708 INIT_LIST_HEAD(&mousedev->client_list);
703 INIT_LIST_HEAD(&mousedev->mixdev_node); 709 INIT_LIST_HEAD(&mousedev->mixdev_node);
704 init_waitqueue_head(&mousedev->wait); 710 init_waitqueue_head(&mousedev->wait);
705 711
712 if (minor == MOUSEDEV_MIX)
713 strlcpy(mousedev->name, "mice", sizeof(mousedev->name));
714 else
715 snprintf(mousedev->name, sizeof(mousedev->name),
716 "mouse%d", minor);
717
706 mousedev->minor = minor; 718 mousedev->minor = minor;
707 mousedev->exist = 1; 719 mousedev->exist = 1;
708 mousedev->handle.dev = dev; 720 mousedev->handle.dev = dev;
709 mousedev->handle.name = mousedev->name; 721 mousedev->handle.name = mousedev->name;
710 mousedev->handle.handler = handler; 722 mousedev->handle.handler = handler;
711 mousedev->handle.private = mousedev; 723 mousedev->handle.private = mousedev;
712 sprintf(mousedev->name, "mouse%d", minor);
713 724
714 mousedev_table[minor] = mousedev; 725 strlcpy(mousedev->dev.bus_id, mousedev->name,
726 sizeof(mousedev->dev.bus_id));
727 mousedev->dev.class = &input_class;
728 if (dev)
729 mousedev->dev.parent = &dev->dev;
730 mousedev->dev.devt = MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + minor);
731 mousedev->dev.release = mousedev_free;
732 device_initialize(&mousedev->dev);
715 733
716 devt = MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + minor), 734 mousedev_table[minor] = mousedev;
717 735
718 cdev = class_device_create(&input_class, &dev->cdev, devt, 736 error = device_add(&mousedev->dev);
719 dev->cdev.dev, mousedev->name); 737 if (error)
720 if (IS_ERR(cdev)) {
721 error = PTR_ERR(cdev);
722 goto err_free_mousedev; 738 goto err_free_mousedev;
739
740 return mousedev;
741
742 err_free_mousedev:
743 put_device(&mousedev->dev);
744 err_out:
745 return ERR_PTR(error);
746}
747
748static void mousedev_destroy(struct mousedev *mousedev)
749{
750 struct mousedev_client *client;
751
752 device_del(&mousedev->dev);
753 mousedev->exist = 0;
754
755 if (mousedev->open) {
756 input_close_device(&mousedev->handle);
757 list_for_each_entry(client, &mousedev->client_list, node)
758 kill_fasync(&client->fasync, SIGIO, POLL_HUP);
759 wake_up_interruptible(&mousedev->wait);
723 } 760 }
724 761
725 /* temporary symlink to keep userspace happy */ 762 put_device(&mousedev->dev);
726 error = sysfs_create_link(&input_class.subsys.kobj, 763}
727 &cdev->kobj, mousedev->name); 764
728 if (error) 765static int mousedev_connect(struct input_handler *handler, struct input_dev *dev,
729 goto err_cdev_destroy; 766 const struct input_device_id *id)
767{
768 struct mousedev *mousedev;
769 int minor;
770 int error;
771
772 for (minor = 0; minor < MOUSEDEV_MINORS && mousedev_table[minor]; minor++);
773 if (minor == MOUSEDEV_MINORS) {
774 printk(KERN_ERR "mousedev: no more free mousedev devices\n");
775 return -ENFILE;
776 }
777
778 mousedev = mousedev_create(dev, handler, minor);
779 if (IS_ERR(mousedev))
780 return PTR_ERR(mousedev);
730 781
731 error = input_register_handle(&mousedev->handle); 782 error = input_register_handle(&mousedev->handle);
732 if (error) 783 if (error)
733 goto err_remove_link; 784 goto err_delete_mousedev;
734 785
735 error = mixdev_add_device(mousedev); 786 error = mixdev_add_device(mousedev);
736 if (error) 787 if (error)
@@ -740,37 +791,18 @@ static int mousedev_connect(struct input_handler *handler, struct input_dev *dev
740 791
741 err_unregister_handle: 792 err_unregister_handle:
742 input_unregister_handle(&mousedev->handle); 793 input_unregister_handle(&mousedev->handle);
743 err_remove_link: 794 err_delete_mousedev:
744 sysfs_remove_link(&input_class.subsys.kobj, mousedev->name); 795 device_unregister(&mousedev->dev);
745 err_cdev_destroy:
746 class_device_destroy(&input_class, devt);
747 err_free_mousedev:
748 mousedev_table[minor] = NULL;
749 kfree(mousedev);
750 return error; 796 return error;
751} 797}
752 798
753static void mousedev_disconnect(struct input_handle *handle) 799static void mousedev_disconnect(struct input_handle *handle)
754{ 800{
755 struct mousedev *mousedev = handle->private; 801 struct mousedev *mousedev = handle->private;
756 struct mousedev_client *client;
757
758 input_unregister_handle(handle);
759
760 sysfs_remove_link(&input_class.subsys.kobj, mousedev->name);
761 class_device_destroy(&input_class,
762 MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + mousedev->minor));
763 mousedev->exist = 0;
764 802
765 mixdev_remove_device(mousedev); 803 mixdev_remove_device(mousedev);
766 804 input_unregister_handle(handle);
767 if (mousedev->open) { 805 mousedev_destroy(mousedev);
768 input_close_device(handle);
769 list_for_each_entry(client, &mousedev->client_list, node)
770 kill_fasync(&client->fasync, SIGIO, POLL_HUP);
771 wake_up_interruptible(&mousedev->wait);
772 } else
773 mousedev_free(mousedev);
774} 806}
775 807
776static const struct input_device_id mousedev_ids[] = { 808static const struct input_device_id mousedev_ids[] = {
@@ -822,25 +854,16 @@ static int psaux_registered;
822 854
823static int __init mousedev_init(void) 855static int __init mousedev_init(void)
824{ 856{
825 struct class_device *cdev;
826 int error; 857 int error;
827 858
859 mousedev_mix = mousedev_create(NULL, &mousedev_handler, MOUSEDEV_MIX);
860 if (IS_ERR(mousedev_mix))
861 return PTR_ERR(mousedev_mix);
862
828 error = input_register_handler(&mousedev_handler); 863 error = input_register_handler(&mousedev_handler);
829 if (error) 864 if (error) {
865 mousedev_destroy(mousedev_mix);
830 return error; 866 return error;
831
832 memset(&mousedev_mix, 0, sizeof(struct mousedev));
833 INIT_LIST_HEAD(&mousedev_mix.client_list);
834 init_waitqueue_head(&mousedev_mix.wait);
835 mousedev_table[MOUSEDEV_MIX] = &mousedev_mix;
836 mousedev_mix.exist = 1;
837 mousedev_mix.minor = MOUSEDEV_MIX;
838
839 cdev = class_device_create(&input_class, NULL,
840 MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + MOUSEDEV_MIX), NULL, "mice");
841 if (IS_ERR(cdev)) {
842 input_unregister_handler(&mousedev_handler);
843 return PTR_ERR(cdev);
844 } 867 }
845 868
846#ifdef CONFIG_INPUT_MOUSEDEV_PSAUX 869#ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
@@ -863,9 +886,8 @@ static void __exit mousedev_exit(void)
863 if (psaux_registered) 886 if (psaux_registered)
864 misc_deregister(&psaux_mouse); 887 misc_deregister(&psaux_mouse);
865#endif 888#endif
866 class_device_destroy(&input_class,
867 MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + MOUSEDEV_MIX));
868 input_unregister_handler(&mousedev_handler); 889 input_unregister_handler(&mousedev_handler);
890 mousedev_destroy(mousedev_mix);
869} 891}
870 892
871module_init(mousedev_init); 893module_init(mousedev_init);
diff --git a/drivers/input/serio/serio_raw.c b/drivers/input/serio/serio_raw.c
index 887357666c68..0403622ae267 100644
--- a/drivers/input/serio/serio_raw.c
+++ b/drivers/input/serio/serio_raw.c
@@ -160,7 +160,7 @@ static ssize_t serio_raw_read(struct file *file, char __user *buffer, size_t cou
160{ 160{
161 struct serio_raw_list *list = file->private_data; 161 struct serio_raw_list *list = file->private_data;
162 struct serio_raw *serio_raw = list->serio_raw; 162 struct serio_raw *serio_raw = list->serio_raw;
163 char c; 163 char uninitialized_var(c);
164 ssize_t retval = 0; 164 ssize_t retval = 0;
165 165
166 if (!serio_raw->serio) 166 if (!serio_raw->serio)
diff --git a/drivers/input/tablet/aiptek.c b/drivers/input/tablet/aiptek.c
index cc0a498763d8..94683f58c9e1 100644
--- a/drivers/input/tablet/aiptek.c
+++ b/drivers/input/tablet/aiptek.c
@@ -82,8 +82,8 @@
82/* 82/*
83 * Version Information 83 * Version Information
84 */ 84 */
85#define DRIVER_VERSION "v1.5 (May-15-2004)" 85#define DRIVER_VERSION "v2.3 (May 2, 2007)"
86#define DRIVER_AUTHOR "Bryan W. Headley/Chris Atenasio" 86#define DRIVER_AUTHOR "Bryan W. Headley/Chris Atenasio/Cedric Brun/Rene van Paassen"
87#define DRIVER_DESC "Aiptek HyperPen USB Tablet Driver (Linux 2.6.x)" 87#define DRIVER_DESC "Aiptek HyperPen USB Tablet Driver (Linux 2.6.x)"
88 88
89/* 89/*
@@ -112,7 +112,7 @@
112 * (returned as Report 3 - absolute coordinates from the mouse) 112 * (returned as Report 3 - absolute coordinates from the mouse)
113 * 113 *
114 * bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 114 * bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
115 * byte0 0 0 0 0 0 0 1 0 115 * byte0 0 0 0 0 0 0 1 1
116 * byte1 X7 X6 X5 X4 X3 X2 X1 X0 116 * byte1 X7 X6 X5 X4 X3 X2 X1 X0
117 * byte2 X15 X14 X13 X12 X11 X10 X9 X8 117 * byte2 X15 X14 X13 X12 X11 X10 X9 X8
118 * byte3 Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 118 * byte3 Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0
@@ -134,7 +134,7 @@
134 * (returned as Report 5 - macrokeys from the mouse) 134 * (returned as Report 5 - macrokeys from the mouse)
135 * 135 *
136 * bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 136 * bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
137 * byte0 0 0 0 0 0 1 0 0 137 * byte0 0 0 0 0 0 1 0 1
138 * byte1 0 0 0 BS2 BS Tip IR DV 138 * byte1 0 0 0 BS2 BS Tip IR DV
139 * byte2 0 0 0 0 0 0 1 0 139 * byte2 0 0 0 0 0 0 1 0
140 * byte3 0 0 0 K4 K3 K2 K1 K0 140 * byte3 0 0 0 K4 K3 K2 K1 K0
@@ -218,15 +218,9 @@
218#define AIPTEK_WHEEL_DISABLE (-10101) 218#define AIPTEK_WHEEL_DISABLE (-10101)
219 219
220 /* ToolCode values, which BTW are 0x140 .. 0x14f 220 /* ToolCode values, which BTW are 0x140 .. 0x14f
221 * We have things set up such that if TOOL_BUTTON_FIRED_BIT is 221 * We have things set up such that if the tool button has changed,
222 * not set, we'll send one instance of AIPTEK_TOOL_BUTTON_xxx. 222 * the tools get reset.
223 *
224 * Whenever the user resets the value, TOOL_BUTTON_FIRED_BIT will
225 * get reset.
226 */ 223 */
227#define TOOL_BUTTON(x) ((x) & 0x14f)
228#define TOOL_BUTTON_FIRED(x) ((x) & 0x200)
229#define TOOL_BUTTON_FIRED_BIT 0x200
230 /* toolMode codes 224 /* toolMode codes
231 */ 225 */
232#define AIPTEK_TOOL_BUTTON_PEN_MODE BTN_TOOL_PEN 226#define AIPTEK_TOOL_BUTTON_PEN_MODE BTN_TOOL_PEN
@@ -264,9 +258,9 @@
264 258
265 /* Mouse button programming 259 /* Mouse button programming
266 */ 260 */
267#define AIPTEK_MOUSE_LEFT_BUTTON 0x01 261#define AIPTEK_MOUSE_LEFT_BUTTON 0x04
268#define AIPTEK_MOUSE_RIGHT_BUTTON 0x02 262#define AIPTEK_MOUSE_RIGHT_BUTTON 0x08
269#define AIPTEK_MOUSE_MIDDLE_BUTTON 0x04 263#define AIPTEK_MOUSE_MIDDLE_BUTTON 0x10
270 264
271 /* Stylus button programming 265 /* Stylus button programming
272 */ 266 */
@@ -294,7 +288,6 @@ struct aiptek_features {
294 int modelCode; /* Tablet model code (not unique) */ 288 int modelCode; /* Tablet model code (not unique) */
295 int firmwareCode; /* prom/eeprom version */ 289 int firmwareCode; /* prom/eeprom version */
296 char usbPath[64 + 1]; /* device's physical usb path */ 290 char usbPath[64 + 1]; /* device's physical usb path */
297 char inputPath[64 + 1]; /* input device path */
298}; 291};
299 292
300struct aiptek_settings { 293struct aiptek_settings {
@@ -327,9 +320,32 @@ struct aiptek {
327 int inDelay; /* jitter: in jitter delay? */ 320 int inDelay; /* jitter: in jitter delay? */
328 unsigned long endDelay; /* jitter: time when delay ends */ 321 unsigned long endDelay; /* jitter: time when delay ends */
329 int previousJitterable; /* jitterable prev value */ 322 int previousJitterable; /* jitterable prev value */
323
324 int lastMacro; /* macro key to reset */
325 int previousToolMode; /* pen, pencil, brush, etc. tool */
330 unsigned char *data; /* incoming packet data */ 326 unsigned char *data; /* incoming packet data */
331}; 327};
332 328
329static const int eventTypes[] = {
330 EV_KEY, EV_ABS, EV_REL, EV_MSC,
331};
332
333static const int absEvents[] = {
334 ABS_X, ABS_Y, ABS_PRESSURE, ABS_TILT_X, ABS_TILT_Y,
335 ABS_WHEEL, ABS_MISC,
336};
337
338static const int relEvents[] = {
339 REL_X, REL_Y, REL_WHEEL,
340};
341
342static const int buttonEvents[] = {
343 BTN_LEFT, BTN_RIGHT, BTN_MIDDLE,
344 BTN_TOOL_PEN, BTN_TOOL_RUBBER, BTN_TOOL_PENCIL, BTN_TOOL_AIRBRUSH,
345 BTN_TOOL_BRUSH, BTN_TOOL_MOUSE, BTN_TOOL_LENS, BTN_TOUCH,
346 BTN_STYLUS, BTN_STYLUS2,
347};
348
333/* 349/*
334 * Permit easy lookup of keyboard events to send, versus 350 * Permit easy lookup of keyboard events to send, versus
335 * the bitmap which comes from the tablet. This hides the 351 * the bitmap which comes from the tablet. This hides the
@@ -345,23 +361,39 @@ static const int macroKeyEvents[] = {
345}; 361};
346 362
347/*********************************************************************** 363/***********************************************************************
348 * Relative reports deliver values in 2's complement format to 364 * Map values to strings and back. Every map shoudl have the following
349 * deal with negative offsets. 365 * as its last element: { NULL, AIPTEK_INVALID_VALUE }.
350 */ 366 */
351static int aiptek_convert_from_2s_complement(unsigned char c) 367#define AIPTEK_INVALID_VALUE -1
368
369struct aiptek_map {
370 const char *string;
371 int value;
372};
373
374static int map_str_to_val(const struct aiptek_map *map, const char *str, size_t count)
352{ 375{
353 int ret; 376 const struct aiptek_map *p;
354 unsigned char b = c;
355 int negate = 0;
356 377
357 if ((b & 0x80) != 0) { 378 if (str[count - 1] == '\n')
358 b = ~b; 379 count--;
359 b--; 380
360 negate = 1; 381 for (p = map; p->string; p++)
361 } 382 if (!strncmp(str, p->string, count))
362 ret = b; 383 return p->value;
363 ret = (negate == 1) ? -ret : ret; 384
364 return ret; 385 return AIPTEK_INVALID_VALUE;
386}
387
388static const char *map_val_to_str(const struct aiptek_map *map, int val)
389{
390 const struct aiptek_map *p;
391
392 for (p = map; p->value != AIPTEK_INVALID_VALUE; p++)
393 if (val == p->value)
394 return p->string;
395
396 return "unknown";
365} 397}
366 398
367/*********************************************************************** 399/***********************************************************************
@@ -385,6 +417,9 @@ static int aiptek_convert_from_2s_complement(unsigned char c)
385 * Proximity. Why two events? I thought it interesting to know if the 417 * Proximity. Why two events? I thought it interesting to know if the
386 * Proximity event occurred while the tablet was in absolute or relative 418 * Proximity event occurred while the tablet was in absolute or relative
387 * mode. 419 * mode.
420 * Update: REL_MISC proved not to be such a good idea. With REL_MISC you
421 * get an event transmitted each time. ABS_MISC works better, since it
422 * can be set and re-set. Thus, only using ABS_MISC from now on.
388 * 423 *
389 * Other tablets use the notion of a certain minimum stylus pressure 424 * Other tablets use the notion of a certain minimum stylus pressure
390 * to infer proximity. While that could have been done, that is yet 425 * to infer proximity. While that could have been done, that is yet
@@ -441,8 +476,8 @@ static void aiptek_irq(struct urb *urb)
441 aiptek->diagnostic = 476 aiptek->diagnostic =
442 AIPTEK_DIAGNOSTIC_SENDING_RELATIVE_IN_ABSOLUTE; 477 AIPTEK_DIAGNOSTIC_SENDING_RELATIVE_IN_ABSOLUTE;
443 } else { 478 } else {
444 x = aiptek_convert_from_2s_complement(data[2]); 479 x = (signed char) data[2];
445 y = aiptek_convert_from_2s_complement(data[3]); 480 y = (signed char) data[3];
446 481
447 /* jitterable keeps track of whether any button has been pressed. 482 /* jitterable keeps track of whether any button has been pressed.
448 * We're also using it to remap the physical mouse button mask 483 * We're also using it to remap the physical mouse button mask
@@ -451,18 +486,20 @@ static void aiptek_irq(struct urb *urb)
451 * that a non-zero value indicates that one or more 486 * that a non-zero value indicates that one or more
452 * mouse button was pressed.) 487 * mouse button was pressed.)
453 */ 488 */
454 jitterable = data[5] & 0x07; 489 jitterable = data[1] & 0x07;
455 490
456 left = (data[5] & aiptek->curSetting.mouseButtonLeft) != 0 ? 1 : 0; 491 left = (data[1] & aiptek->curSetting.mouseButtonLeft >> 2) != 0 ? 1 : 0;
457 right = (data[5] & aiptek->curSetting.mouseButtonRight) != 0 ? 1 : 0; 492 right = (data[1] & aiptek->curSetting.mouseButtonRight >> 2) != 0 ? 1 : 0;
458 middle = (data[5] & aiptek->curSetting.mouseButtonMiddle) != 0 ? 1 : 0; 493 middle = (data[1] & aiptek->curSetting.mouseButtonMiddle >> 2) != 0 ? 1 : 0;
459 494
460 input_report_key(inputdev, BTN_LEFT, left); 495 input_report_key(inputdev, BTN_LEFT, left);
461 input_report_key(inputdev, BTN_MIDDLE, middle); 496 input_report_key(inputdev, BTN_MIDDLE, middle);
462 input_report_key(inputdev, BTN_RIGHT, right); 497 input_report_key(inputdev, BTN_RIGHT, right);
498
499 input_report_abs(inputdev, ABS_MISC,
500 1 | AIPTEK_REPORT_TOOL_UNKNOWN);
463 input_report_rel(inputdev, REL_X, x); 501 input_report_rel(inputdev, REL_X, x);
464 input_report_rel(inputdev, REL_Y, y); 502 input_report_rel(inputdev, REL_Y, y);
465 input_report_rel(inputdev, REL_MISC, 1 | AIPTEK_REPORT_TOOL_UNKNOWN);
466 503
467 /* Wheel support is in the form of a single-event 504 /* Wheel support is in the form of a single-event
468 * firing. 505 * firing.
@@ -472,6 +509,11 @@ static void aiptek_irq(struct urb *urb)
472 aiptek->curSetting.wheel); 509 aiptek->curSetting.wheel);
473 aiptek->curSetting.wheel = AIPTEK_WHEEL_DISABLE; 510 aiptek->curSetting.wheel = AIPTEK_WHEEL_DISABLE;
474 } 511 }
512 if (aiptek->lastMacro != -1) {
513 input_report_key(inputdev,
514 macroKeyEvents[aiptek->lastMacro], 0);
515 aiptek->lastMacro = -1;
516 }
475 input_sync(inputdev); 517 input_sync(inputdev);
476 } 518 }
477 } 519 }
@@ -489,8 +531,8 @@ static void aiptek_irq(struct urb *urb)
489 y = le16_to_cpu(get_unaligned((__le16 *) (data + 3))); 531 y = le16_to_cpu(get_unaligned((__le16 *) (data + 3)));
490 z = le16_to_cpu(get_unaligned((__le16 *) (data + 6))); 532 z = le16_to_cpu(get_unaligned((__le16 *) (data + 6)));
491 533
492 p = (data[5] & 0x01) != 0 ? 1 : 0; 534 dv = (data[5] & 0x01) != 0 ? 1 : 0;
493 dv = (data[5] & 0x02) != 0 ? 1 : 0; 535 p = (data[5] & 0x02) != 0 ? 1 : 0;
494 tip = (data[5] & 0x04) != 0 ? 1 : 0; 536 tip = (data[5] & 0x04) != 0 ? 1 : 0;
495 537
496 /* Use jitterable to re-arrange button masks 538 /* Use jitterable to re-arrange button masks
@@ -505,16 +547,18 @@ static void aiptek_irq(struct urb *urb)
505 * all 'bad' reports... 547 * all 'bad' reports...
506 */ 548 */
507 if (dv != 0) { 549 if (dv != 0) {
508 /* If we've not already sent a tool_button_?? code, do 550 /* If the selected tool changed, reset the old
509 * so now. Then set FIRED_BIT so it won't be resent unless 551 * tool key, and set the new one.
510 * the user forces FIRED_BIT off.
511 */ 552 */
512 if (TOOL_BUTTON_FIRED 553 if (aiptek->previousToolMode !=
513 (aiptek->curSetting.toolMode) == 0) { 554 aiptek->curSetting.toolMode) {
555 input_report_key(inputdev,
556 aiptek->previousToolMode, 0);
514 input_report_key(inputdev, 557 input_report_key(inputdev,
515 TOOL_BUTTON(aiptek->curSetting.toolMode), 558 aiptek->curSetting.toolMode,
516 1); 559 1);
517 aiptek->curSetting.toolMode |= TOOL_BUTTON_FIRED_BIT; 560 aiptek->previousToolMode =
561 aiptek->curSetting.toolMode;
518 } 562 }
519 563
520 if (p != 0) { 564 if (p != 0) {
@@ -550,6 +594,11 @@ static void aiptek_irq(struct urb *urb)
550 } 594 }
551 } 595 }
552 input_report_abs(inputdev, ABS_MISC, p | AIPTEK_REPORT_TOOL_STYLUS); 596 input_report_abs(inputdev, ABS_MISC, p | AIPTEK_REPORT_TOOL_STYLUS);
597 if (aiptek->lastMacro != -1) {
598 input_report_key(inputdev,
599 macroKeyEvents[aiptek->lastMacro], 0);
600 aiptek->lastMacro = -1;
601 }
553 input_sync(inputdev); 602 input_sync(inputdev);
554 } 603 }
555 } 604 }
@@ -568,23 +617,25 @@ static void aiptek_irq(struct urb *urb)
568 617
569 jitterable = data[5] & 0x1c; 618 jitterable = data[5] & 0x1c;
570 619
571 p = (data[5] & 0x01) != 0 ? 1 : 0; 620 dv = (data[5] & 0x01) != 0 ? 1 : 0;
572 dv = (data[5] & 0x02) != 0 ? 1 : 0; 621 p = (data[5] & 0x02) != 0 ? 1 : 0;
573 left = (data[5] & aiptek->curSetting.mouseButtonLeft) != 0 ? 1 : 0; 622 left = (data[5] & aiptek->curSetting.mouseButtonLeft) != 0 ? 1 : 0;
574 right = (data[5] & aiptek->curSetting.mouseButtonRight) != 0 ? 1 : 0; 623 right = (data[5] & aiptek->curSetting.mouseButtonRight) != 0 ? 1 : 0;
575 middle = (data[5] & aiptek->curSetting.mouseButtonMiddle) != 0 ? 1 : 0; 624 middle = (data[5] & aiptek->curSetting.mouseButtonMiddle) != 0 ? 1 : 0;
576 625
577 if (dv != 0) { 626 if (dv != 0) {
578 /* If we've not already sent a tool_button_?? code, do 627 /* If the selected tool changed, reset the old
579 * so now. Then set FIRED_BIT so it won't be resent unless 628 * tool key, and set the new one.
580 * the user forces FIRED_BIT off.
581 */ 629 */
582 if (TOOL_BUTTON_FIRED 630 if (aiptek->previousToolMode !=
583 (aiptek->curSetting.toolMode) == 0) { 631 aiptek->curSetting.toolMode) {
632 input_report_key(inputdev,
633 aiptek->previousToolMode, 0);
584 input_report_key(inputdev, 634 input_report_key(inputdev,
585 TOOL_BUTTON(aiptek->curSetting.toolMode), 635 aiptek->curSetting.toolMode,
586 1); 636 1);
587 aiptek->curSetting.toolMode |= TOOL_BUTTON_FIRED_BIT; 637 aiptek->previousToolMode =
638 aiptek->curSetting.toolMode;
588 } 639 }
589 640
590 if (p != 0) { 641 if (p != 0) {
@@ -605,7 +656,12 @@ static void aiptek_irq(struct urb *urb)
605 aiptek->curSetting.wheel = AIPTEK_WHEEL_DISABLE; 656 aiptek->curSetting.wheel = AIPTEK_WHEEL_DISABLE;
606 } 657 }
607 } 658 }
608 input_report_rel(inputdev, REL_MISC, p | AIPTEK_REPORT_TOOL_MOUSE); 659 input_report_abs(inputdev, ABS_MISC, p | AIPTEK_REPORT_TOOL_MOUSE);
660 if (aiptek->lastMacro != -1) {
661 input_report_key(inputdev,
662 macroKeyEvents[aiptek->lastMacro], 0);
663 aiptek->lastMacro = -1;
664 }
609 input_sync(inputdev); 665 input_sync(inputdev);
610 } 666 }
611 } 667 }
@@ -615,98 +671,83 @@ static void aiptek_irq(struct urb *urb)
615 else if (data[0] == 4) { 671 else if (data[0] == 4) {
616 jitterable = data[1] & 0x18; 672 jitterable = data[1] & 0x18;
617 673
618 p = (data[1] & 0x01) != 0 ? 1 : 0; 674 dv = (data[1] & 0x01) != 0 ? 1 : 0;
619 dv = (data[1] & 0x02) != 0 ? 1 : 0; 675 p = (data[1] & 0x02) != 0 ? 1 : 0;
620 tip = (data[1] & 0x04) != 0 ? 1 : 0; 676 tip = (data[1] & 0x04) != 0 ? 1 : 0;
621 bs = (data[1] & aiptek->curSetting.stylusButtonLower) != 0 ? 1 : 0; 677 bs = (data[1] & aiptek->curSetting.stylusButtonLower) != 0 ? 1 : 0;
622 pck = (data[1] & aiptek->curSetting.stylusButtonUpper) != 0 ? 1 : 0; 678 pck = (data[1] & aiptek->curSetting.stylusButtonUpper) != 0 ? 1 : 0;
623 679
624 macro = data[3]; 680 macro = dv && p && tip && !(data[3] & 1) ? (data[3] >> 1) : -1;
625 z = le16_to_cpu(get_unaligned((__le16 *) (data + 4))); 681 z = le16_to_cpu(get_unaligned((__le16 *) (data + 4)));
626 682
627 if (dv != 0) { 683 if (dv) {
628 /* If we've not already sent a tool_button_?? code, do 684 /* If the selected tool changed, reset the old
629 * so now. Then set FIRED_BIT so it won't be resent unless 685 * tool key, and set the new one.
630 * the user forces FIRED_BIT off.
631 */ 686 */
632 if (TOOL_BUTTON_FIRED(aiptek->curSetting.toolMode) == 0) { 687 if (aiptek->previousToolMode !=
688 aiptek->curSetting.toolMode) {
689 input_report_key(inputdev,
690 aiptek->previousToolMode, 0);
633 input_report_key(inputdev, 691 input_report_key(inputdev,
634 TOOL_BUTTON(aiptek->curSetting.toolMode), 692 aiptek->curSetting.toolMode,
635 1); 693 1);
636 aiptek->curSetting.toolMode |= TOOL_BUTTON_FIRED_BIT; 694 aiptek->previousToolMode =
695 aiptek->curSetting.toolMode;
637 } 696 }
697 }
638 698
639 if (p != 0) { 699 if (aiptek->lastMacro != -1 && aiptek->lastMacro != macro) {
640 input_report_key(inputdev, BTN_TOUCH, tip); 700 input_report_key(inputdev, macroKeyEvents[aiptek->lastMacro], 0);
641 input_report_key(inputdev, BTN_STYLUS, bs); 701 aiptek->lastMacro = -1;
642 input_report_key(inputdev, BTN_STYLUS2, pck); 702 }
643 input_report_abs(inputdev, ABS_PRESSURE, z);
644 }
645 703
646 /* For safety, we're sending key 'break' codes for the 704 if (macro != -1 && macro != aiptek->lastMacro) {
647 * neighboring macro keys. 705 input_report_key(inputdev, macroKeyEvents[macro], 1);
648 */ 706 aiptek->lastMacro = macro;
649 if (macro > 0) {
650 input_report_key(inputdev,
651 macroKeyEvents[macro - 1], 0);
652 }
653 if (macro < 25) {
654 input_report_key(inputdev,
655 macroKeyEvents[macro + 1], 0);
656 }
657 input_report_key(inputdev, macroKeyEvents[macro], p);
658 input_report_abs(inputdev, ABS_MISC,
659 p | AIPTEK_REPORT_TOOL_STYLUS);
660 input_sync(inputdev);
661 } 707 }
708 input_report_abs(inputdev, ABS_MISC,
709 p | AIPTEK_REPORT_TOOL_STYLUS);
710 input_sync(inputdev);
662 } 711 }
663 /* Report 5s come from the macro keys when pressed by mouse 712 /* Report 5s come from the macro keys when pressed by mouse
664 */ 713 */
665 else if (data[0] == 5) { 714 else if (data[0] == 5) {
666 jitterable = data[1] & 0x1c; 715 jitterable = data[1] & 0x1c;
667 716
668 p = (data[1] & 0x01) != 0 ? 1 : 0; 717 dv = (data[1] & 0x01) != 0 ? 1 : 0;
669 dv = (data[1] & 0x02) != 0 ? 1 : 0; 718 p = (data[1] & 0x02) != 0 ? 1 : 0;
670 left = (data[1]& aiptek->curSetting.mouseButtonLeft) != 0 ? 1 : 0; 719 left = (data[1]& aiptek->curSetting.mouseButtonLeft) != 0 ? 1 : 0;
671 right = (data[1] & aiptek->curSetting.mouseButtonRight) != 0 ? 1 : 0; 720 right = (data[1] & aiptek->curSetting.mouseButtonRight) != 0 ? 1 : 0;
672 middle = (data[1] & aiptek->curSetting.mouseButtonMiddle) != 0 ? 1 : 0; 721 middle = (data[1] & aiptek->curSetting.mouseButtonMiddle) != 0 ? 1 : 0;
673 macro = data[3]; 722 macro = dv && p && left && !(data[3] & 1) ? (data[3] >> 1) : 0;
674 723
675 if (dv != 0) { 724 if (dv) {
676 /* If we've not already sent a tool_button_?? code, do 725 /* If the selected tool changed, reset the old
677 * so now. Then set FIRED_BIT so it won't be resent unless 726 * tool key, and set the new one.
678 * the user forces FIRED_BIT off.
679 */ 727 */
680 if (TOOL_BUTTON_FIRED(aiptek->curSetting.toolMode) == 0) { 728 if (aiptek->previousToolMode !=
681 input_report_key(inputdev, 729 aiptek->curSetting.toolMode) {
682 TOOL_BUTTON(aiptek->curSetting.toolMode), 730 input_report_key(inputdev,
683 1); 731 aiptek->previousToolMode, 0);
684 aiptek->curSetting.toolMode |= TOOL_BUTTON_FIRED_BIT; 732 input_report_key(inputdev,
685 } 733 aiptek->curSetting.toolMode, 1);
686 734 aiptek->previousToolMode = aiptek->curSetting.toolMode;
687 if (p != 0) {
688 input_report_key(inputdev, BTN_LEFT, left);
689 input_report_key(inputdev, BTN_MIDDLE, middle);
690 input_report_key(inputdev, BTN_RIGHT, right);
691 } 735 }
736 }
692 737
693 /* For safety, we're sending key 'break' codes for the 738 if (aiptek->lastMacro != -1 && aiptek->lastMacro != macro) {
694 * neighboring macro keys. 739 input_report_key(inputdev, macroKeyEvents[aiptek->lastMacro], 0);
695 */ 740 aiptek->lastMacro = -1;
696 if (macro > 0) { 741 }
697 input_report_key(inputdev,
698 macroKeyEvents[macro - 1], 0);
699 }
700 if (macro < 25) {
701 input_report_key(inputdev,
702 macroKeyEvents[macro + 1], 0);
703 }
704 742
743 if (macro != -1 && macro != aiptek->lastMacro) {
705 input_report_key(inputdev, macroKeyEvents[macro], 1); 744 input_report_key(inputdev, macroKeyEvents[macro], 1);
706 input_report_rel(inputdev, ABS_MISC, 745 aiptek->lastMacro = macro;
707 p | AIPTEK_REPORT_TOOL_MOUSE);
708 input_sync(inputdev);
709 } 746 }
747
748 input_report_abs(inputdev, ABS_MISC,
749 p | AIPTEK_REPORT_TOOL_MOUSE);
750 input_sync(inputdev);
710 } 751 }
711 /* We have no idea which tool can generate a report 6. Theoretically, 752 /* We have no idea which tool can generate a report 6. Theoretically,
712 * neither need to, having been given reports 4 & 5 for such use. 753 * neither need to, having been given reports 4 & 5 for such use.
@@ -725,15 +766,18 @@ static void aiptek_irq(struct urb *urb)
725 0); 766 0);
726 } 767 }
727 768
728 /* If we've not already sent a tool_button_?? code, do 769 /* If the selected tool changed, reset the old
729 * so now. Then set FIRED_BIT so it won't be resent unless 770 tool key, and set the new one.
730 * the user forces FIRED_BIT off. 771 */
731 */ 772 if (aiptek->previousToolMode !=
732 if (TOOL_BUTTON_FIRED(aiptek->curSetting.toolMode) == 0) { 773 aiptek->curSetting.toolMode) {
774 input_report_key(inputdev,
775 aiptek->previousToolMode, 0);
733 input_report_key(inputdev, 776 input_report_key(inputdev,
734 TOOL_BUTTON(aiptek->curSetting. 777 aiptek->curSetting.toolMode,
735 toolMode), 1); 778 1);
736 aiptek->curSetting.toolMode |= TOOL_BUTTON_FIRED_BIT; 779 aiptek->previousToolMode =
780 aiptek->curSetting.toolMode;
737 } 781 }
738 782
739 input_report_key(inputdev, macroKeyEvents[macro], 1); 783 input_report_key(inputdev, macroKeyEvents[macro], 1);
@@ -1007,9 +1051,6 @@ static ssize_t show_tabletSize(struct device *dev, struct device_attribute *attr
1007{ 1051{
1008 struct aiptek *aiptek = dev_get_drvdata(dev); 1052 struct aiptek *aiptek = dev_get_drvdata(dev);
1009 1053
1010 if (aiptek == NULL)
1011 return 0;
1012
1013 return snprintf(buf, PAGE_SIZE, "%dx%d\n", 1054 return snprintf(buf, PAGE_SIZE, "%dx%d\n",
1014 aiptek->inputdev->absmax[ABS_X] + 1, 1055 aiptek->inputdev->absmax[ABS_X] + 1,
1015 aiptek->inputdev->absmax[ABS_Y] + 1); 1056 aiptek->inputdev->absmax[ABS_Y] + 1);
@@ -1024,117 +1065,35 @@ static ssize_t show_tabletSize(struct device *dev, struct device_attribute *attr
1024static DEVICE_ATTR(size, S_IRUGO, show_tabletSize, NULL); 1065static DEVICE_ATTR(size, S_IRUGO, show_tabletSize, NULL);
1025 1066
1026/*********************************************************************** 1067/***********************************************************************
1027 * support routines for the 'product_id' file
1028 */
1029static ssize_t show_tabletProductId(struct device *dev, struct device_attribute *attr, char *buf)
1030{
1031 struct aiptek *aiptek = dev_get_drvdata(dev);
1032
1033 if (aiptek == NULL)
1034 return 0;
1035
1036 return snprintf(buf, PAGE_SIZE, "0x%04x\n",
1037 aiptek->inputdev->id.product);
1038}
1039
1040static DEVICE_ATTR(product_id, S_IRUGO, show_tabletProductId, NULL);
1041
1042/***********************************************************************
1043 * support routines for the 'vendor_id' file
1044 */
1045static ssize_t show_tabletVendorId(struct device *dev, struct device_attribute *attr, char *buf)
1046{
1047 struct aiptek *aiptek = dev_get_drvdata(dev);
1048
1049 if (aiptek == NULL)
1050 return 0;
1051
1052 return snprintf(buf, PAGE_SIZE, "0x%04x\n", aiptek->inputdev->id.vendor);
1053}
1054
1055static DEVICE_ATTR(vendor_id, S_IRUGO, show_tabletVendorId, NULL);
1056
1057/***********************************************************************
1058 * support routines for the 'vendor' file
1059 */
1060static ssize_t show_tabletManufacturer(struct device *dev, struct device_attribute *attr, char *buf)
1061{
1062 struct aiptek *aiptek = dev_get_drvdata(dev);
1063 int retval;
1064
1065 if (aiptek == NULL)
1066 return 0;
1067
1068 retval = snprintf(buf, PAGE_SIZE, "%s\n", aiptek->usbdev->manufacturer);
1069 return retval;
1070}
1071
1072static DEVICE_ATTR(vendor, S_IRUGO, show_tabletManufacturer, NULL);
1073
1074/***********************************************************************
1075 * support routines for the 'product' file
1076 */
1077static ssize_t show_tabletProduct(struct device *dev, struct device_attribute *attr, char *buf)
1078{
1079 struct aiptek *aiptek = dev_get_drvdata(dev);
1080 int retval;
1081
1082 if (aiptek == NULL)
1083 return 0;
1084
1085 retval = snprintf(buf, PAGE_SIZE, "%s\n", aiptek->usbdev->product);
1086 return retval;
1087}
1088
1089static DEVICE_ATTR(product, S_IRUGO, show_tabletProduct, NULL);
1090
1091/***********************************************************************
1092 * support routines for the 'pointer_mode' file. Note that this file 1068 * support routines for the 'pointer_mode' file. Note that this file
1093 * both displays current setting and allows reprogramming. 1069 * both displays current setting and allows reprogramming.
1094 */ 1070 */
1071static struct aiptek_map pointer_mode_map[] = {
1072 { "stylus", AIPTEK_POINTER_ONLY_STYLUS_MODE },
1073 { "mouse", AIPTEK_POINTER_ONLY_MOUSE_MODE },
1074 { "either", AIPTEK_POINTER_EITHER_MODE },
1075 { NULL, AIPTEK_INVALID_VALUE }
1076};
1077
1095static ssize_t show_tabletPointerMode(struct device *dev, struct device_attribute *attr, char *buf) 1078static ssize_t show_tabletPointerMode(struct device *dev, struct device_attribute *attr, char *buf)
1096{ 1079{
1097 struct aiptek *aiptek = dev_get_drvdata(dev); 1080 struct aiptek *aiptek = dev_get_drvdata(dev);
1098 char *s;
1099
1100 if (aiptek == NULL)
1101 return 0;
1102
1103 switch (aiptek->curSetting.pointerMode) {
1104 case AIPTEK_POINTER_ONLY_STYLUS_MODE:
1105 s = "stylus";
1106 break;
1107
1108 case AIPTEK_POINTER_ONLY_MOUSE_MODE:
1109 s = "mouse";
1110 break;
1111
1112 case AIPTEK_POINTER_EITHER_MODE:
1113 s = "either";
1114 break;
1115 1081
1116 default: 1082 return snprintf(buf, PAGE_SIZE, "%s\n",
1117 s = "unknown"; 1083 map_val_to_str(pointer_mode_map,
1118 break; 1084 aiptek->curSetting.pointerMode));
1119 }
1120 return snprintf(buf, PAGE_SIZE, "%s\n", s);
1121} 1085}
1122 1086
1123static ssize_t 1087static ssize_t
1124store_tabletPointerMode(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) 1088store_tabletPointerMode(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
1125{ 1089{
1126 struct aiptek *aiptek = dev_get_drvdata(dev); 1090 struct aiptek *aiptek = dev_get_drvdata(dev);
1127 if (aiptek == NULL) 1091 int new_mode = map_str_to_val(pointer_mode_map, buf, count);
1128 return 0;
1129 1092
1130 if (strcmp(buf, "stylus") == 0) { 1093 if (new_mode == AIPTEK_INVALID_VALUE)
1131 aiptek->newSetting.pointerMode = 1094 return -EINVAL;
1132 AIPTEK_POINTER_ONLY_STYLUS_MODE; 1095
1133 } else if (strcmp(buf, "mouse") == 0) { 1096 aiptek->newSetting.pointerMode = new_mode;
1134 aiptek->newSetting.pointerMode = AIPTEK_POINTER_ONLY_MOUSE_MODE;
1135 } else if (strcmp(buf, "either") == 0) {
1136 aiptek->newSetting.pointerMode = AIPTEK_POINTER_EITHER_MODE;
1137 }
1138 return count; 1097 return count;
1139} 1098}
1140 1099
@@ -1146,44 +1105,32 @@ static DEVICE_ATTR(pointer_mode,
1146 * support routines for the 'coordinate_mode' file. Note that this file 1105 * support routines for the 'coordinate_mode' file. Note that this file
1147 * both displays current setting and allows reprogramming. 1106 * both displays current setting and allows reprogramming.
1148 */ 1107 */
1108
1109static struct aiptek_map coordinate_mode_map[] = {
1110 { "absolute", AIPTEK_COORDINATE_ABSOLUTE_MODE },
1111 { "relative", AIPTEK_COORDINATE_RELATIVE_MODE },
1112 { NULL, AIPTEK_INVALID_VALUE }
1113};
1114
1149static ssize_t show_tabletCoordinateMode(struct device *dev, struct device_attribute *attr, char *buf) 1115static ssize_t show_tabletCoordinateMode(struct device *dev, struct device_attribute *attr, char *buf)
1150{ 1116{
1151 struct aiptek *aiptek = dev_get_drvdata(dev); 1117 struct aiptek *aiptek = dev_get_drvdata(dev);
1152 char *s;
1153 1118
1154 if (aiptek == NULL) 1119 return snprintf(buf, PAGE_SIZE, "%s\n",
1155 return 0; 1120 map_val_to_str(coordinate_mode_map,
1156 1121 aiptek->curSetting.coordinateMode));
1157 switch (aiptek->curSetting.coordinateMode) {
1158 case AIPTEK_COORDINATE_ABSOLUTE_MODE:
1159 s = "absolute";
1160 break;
1161
1162 case AIPTEK_COORDINATE_RELATIVE_MODE:
1163 s = "relative";
1164 break;
1165
1166 default:
1167 s = "unknown";
1168 break;
1169 }
1170 return snprintf(buf, PAGE_SIZE, "%s\n", s);
1171} 1122}
1172 1123
1173static ssize_t 1124static ssize_t
1174store_tabletCoordinateMode(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) 1125store_tabletCoordinateMode(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
1175{ 1126{
1176 struct aiptek *aiptek = dev_get_drvdata(dev); 1127 struct aiptek *aiptek = dev_get_drvdata(dev);
1177 if (aiptek == NULL) 1128 int new_mode = map_str_to_val(coordinate_mode_map, buf, count);
1178 return 0;
1179 1129
1180 if (strcmp(buf, "absolute") == 0) { 1130 if (new_mode == AIPTEK_INVALID_VALUE)
1181 aiptek->newSetting.pointerMode = 1131 return -EINVAL;
1182 AIPTEK_COORDINATE_ABSOLUTE_MODE; 1132
1183 } else if (strcmp(buf, "relative") == 0) { 1133 aiptek->newSetting.coordinateMode = new_mode;
1184 aiptek->newSetting.pointerMode =
1185 AIPTEK_COORDINATE_RELATIVE_MODE;
1186 }
1187 return count; 1134 return count;
1188} 1135}
1189 1136
@@ -1195,73 +1142,37 @@ static DEVICE_ATTR(coordinate_mode,
1195 * support routines for the 'tool_mode' file. Note that this file 1142 * support routines for the 'tool_mode' file. Note that this file
1196 * both displays current setting and allows reprogramming. 1143 * both displays current setting and allows reprogramming.
1197 */ 1144 */
1145
1146static struct aiptek_map tool_mode_map[] = {
1147 { "mouse", AIPTEK_TOOL_BUTTON_MOUSE_MODE },
1148 { "eraser", AIPTEK_TOOL_BUTTON_ERASER_MODE },
1149 { "pencil", AIPTEK_TOOL_BUTTON_PENCIL_MODE },
1150 { "pen", AIPTEK_TOOL_BUTTON_PEN_MODE },
1151 { "brush", AIPTEK_TOOL_BUTTON_BRUSH_MODE },
1152 { "airbrush", AIPTEK_TOOL_BUTTON_AIRBRUSH_MODE },
1153 { "lens", AIPTEK_TOOL_BUTTON_LENS_MODE },
1154 { NULL, AIPTEK_INVALID_VALUE }
1155};
1156
1198static ssize_t show_tabletToolMode(struct device *dev, struct device_attribute *attr, char *buf) 1157static ssize_t show_tabletToolMode(struct device *dev, struct device_attribute *attr, char *buf)
1199{ 1158{
1200 struct aiptek *aiptek = dev_get_drvdata(dev); 1159 struct aiptek *aiptek = dev_get_drvdata(dev);
1201 char *s;
1202
1203 if (aiptek == NULL)
1204 return 0;
1205
1206 switch (TOOL_BUTTON(aiptek->curSetting.toolMode)) {
1207 case AIPTEK_TOOL_BUTTON_MOUSE_MODE:
1208 s = "mouse";
1209 break;
1210
1211 case AIPTEK_TOOL_BUTTON_ERASER_MODE:
1212 s = "eraser";
1213 break;
1214
1215 case AIPTEK_TOOL_BUTTON_PENCIL_MODE:
1216 s = "pencil";
1217 break;
1218
1219 case AIPTEK_TOOL_BUTTON_PEN_MODE:
1220 s = "pen";
1221 break;
1222
1223 case AIPTEK_TOOL_BUTTON_BRUSH_MODE:
1224 s = "brush";
1225 break;
1226
1227 case AIPTEK_TOOL_BUTTON_AIRBRUSH_MODE:
1228 s = "airbrush";
1229 break;
1230
1231 case AIPTEK_TOOL_BUTTON_LENS_MODE:
1232 s = "lens";
1233 break;
1234 1160
1235 default: 1161 return snprintf(buf, PAGE_SIZE, "%s\n",
1236 s = "unknown"; 1162 map_val_to_str(tool_mode_map,
1237 break; 1163 aiptek->curSetting.toolMode));
1238 }
1239 return snprintf(buf, PAGE_SIZE, "%s\n", s);
1240} 1164}
1241 1165
1242static ssize_t 1166static ssize_t
1243store_tabletToolMode(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) 1167store_tabletToolMode(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
1244{ 1168{
1245 struct aiptek *aiptek = dev_get_drvdata(dev); 1169 struct aiptek *aiptek = dev_get_drvdata(dev);
1246 if (aiptek == NULL) 1170 int new_mode = map_str_to_val(tool_mode_map, buf, count);
1247 return 0;
1248 1171
1249 if (strcmp(buf, "mouse") == 0) { 1172 if (new_mode == AIPTEK_INVALID_VALUE)
1250 aiptek->newSetting.toolMode = AIPTEK_TOOL_BUTTON_MOUSE_MODE; 1173 return -EINVAL;
1251 } else if (strcmp(buf, "eraser") == 0) {
1252 aiptek->newSetting.toolMode = AIPTEK_TOOL_BUTTON_ERASER_MODE;
1253 } else if (strcmp(buf, "pencil") == 0) {
1254 aiptek->newSetting.toolMode = AIPTEK_TOOL_BUTTON_PENCIL_MODE;
1255 } else if (strcmp(buf, "pen") == 0) {
1256 aiptek->newSetting.toolMode = AIPTEK_TOOL_BUTTON_PEN_MODE;
1257 } else if (strcmp(buf, "brush") == 0) {
1258 aiptek->newSetting.toolMode = AIPTEK_TOOL_BUTTON_BRUSH_MODE;
1259 } else if (strcmp(buf, "airbrush") == 0) {
1260 aiptek->newSetting.toolMode = AIPTEK_TOOL_BUTTON_AIRBRUSH_MODE;
1261 } else if (strcmp(buf, "lens") == 0) {
1262 aiptek->newSetting.toolMode = AIPTEK_TOOL_BUTTON_LENS_MODE;
1263 }
1264 1174
1175 aiptek->newSetting.toolMode = new_mode;
1265 return count; 1176 return count;
1266} 1177}
1267 1178
@@ -1277,9 +1188,6 @@ static ssize_t show_tabletXtilt(struct device *dev, struct device_attribute *att
1277{ 1188{
1278 struct aiptek *aiptek = dev_get_drvdata(dev); 1189 struct aiptek *aiptek = dev_get_drvdata(dev);
1279 1190
1280 if (aiptek == NULL)
1281 return 0;
1282
1283 if (aiptek->curSetting.xTilt == AIPTEK_TILT_DISABLE) { 1191 if (aiptek->curSetting.xTilt == AIPTEK_TILT_DISABLE) {
1284 return snprintf(buf, PAGE_SIZE, "disable\n"); 1192 return snprintf(buf, PAGE_SIZE, "disable\n");
1285 } else { 1193 } else {
@@ -1294,9 +1202,6 @@ store_tabletXtilt(struct device *dev, struct device_attribute *attr, const char
1294 struct aiptek *aiptek = dev_get_drvdata(dev); 1202 struct aiptek *aiptek = dev_get_drvdata(dev);
1295 int x; 1203 int x;
1296 1204
1297 if (aiptek == NULL)
1298 return 0;
1299
1300 if (strcmp(buf, "disable") == 0) { 1205 if (strcmp(buf, "disable") == 0) {
1301 aiptek->newSetting.xTilt = AIPTEK_TILT_DISABLE; 1206 aiptek->newSetting.xTilt = AIPTEK_TILT_DISABLE;
1302 } else { 1207 } else {
@@ -1319,9 +1224,6 @@ static ssize_t show_tabletYtilt(struct device *dev, struct device_attribute *att
1319{ 1224{
1320 struct aiptek *aiptek = dev_get_drvdata(dev); 1225 struct aiptek *aiptek = dev_get_drvdata(dev);
1321 1226
1322 if (aiptek == NULL)
1323 return 0;
1324
1325 if (aiptek->curSetting.yTilt == AIPTEK_TILT_DISABLE) { 1227 if (aiptek->curSetting.yTilt == AIPTEK_TILT_DISABLE) {
1326 return snprintf(buf, PAGE_SIZE, "disable\n"); 1228 return snprintf(buf, PAGE_SIZE, "disable\n");
1327 } else { 1229 } else {
@@ -1336,9 +1238,6 @@ store_tabletYtilt(struct device *dev, struct device_attribute *attr, const char
1336 struct aiptek *aiptek = dev_get_drvdata(dev); 1238 struct aiptek *aiptek = dev_get_drvdata(dev);
1337 int y; 1239 int y;
1338 1240
1339 if (aiptek == NULL)
1340 return 0;
1341
1342 if (strcmp(buf, "disable") == 0) { 1241 if (strcmp(buf, "disable") == 0) {
1343 aiptek->newSetting.yTilt = AIPTEK_TILT_DISABLE; 1242 aiptek->newSetting.yTilt = AIPTEK_TILT_DISABLE;
1344 } else { 1243 } else {
@@ -1361,9 +1260,6 @@ static ssize_t show_tabletJitterDelay(struct device *dev, struct device_attribut
1361{ 1260{
1362 struct aiptek *aiptek = dev_get_drvdata(dev); 1261 struct aiptek *aiptek = dev_get_drvdata(dev);
1363 1262
1364 if (aiptek == NULL)
1365 return 0;
1366
1367 return snprintf(buf, PAGE_SIZE, "%d\n", aiptek->curSetting.jitterDelay); 1263 return snprintf(buf, PAGE_SIZE, "%d\n", aiptek->curSetting.jitterDelay);
1368} 1264}
1369 1265
@@ -1372,9 +1268,6 @@ store_tabletJitterDelay(struct device *dev, struct device_attribute *attr, const
1372{ 1268{
1373 struct aiptek *aiptek = dev_get_drvdata(dev); 1269 struct aiptek *aiptek = dev_get_drvdata(dev);
1374 1270
1375 if (aiptek == NULL)
1376 return 0;
1377
1378 aiptek->newSetting.jitterDelay = (int)simple_strtol(buf, NULL, 10); 1271 aiptek->newSetting.jitterDelay = (int)simple_strtol(buf, NULL, 10);
1379 return count; 1272 return count;
1380} 1273}
@@ -1391,9 +1284,6 @@ static ssize_t show_tabletProgrammableDelay(struct device *dev, struct device_at
1391{ 1284{
1392 struct aiptek *aiptek = dev_get_drvdata(dev); 1285 struct aiptek *aiptek = dev_get_drvdata(dev);
1393 1286
1394 if (aiptek == NULL)
1395 return 0;
1396
1397 return snprintf(buf, PAGE_SIZE, "%d\n", 1287 return snprintf(buf, PAGE_SIZE, "%d\n",
1398 aiptek->curSetting.programmableDelay); 1288 aiptek->curSetting.programmableDelay);
1399} 1289}
@@ -1403,9 +1293,6 @@ store_tabletProgrammableDelay(struct device *dev, struct device_attribute *attr,
1403{ 1293{
1404 struct aiptek *aiptek = dev_get_drvdata(dev); 1294 struct aiptek *aiptek = dev_get_drvdata(dev);
1405 1295
1406 if (aiptek == NULL)
1407 return 0;
1408
1409 aiptek->newSetting.programmableDelay = (int)simple_strtol(buf, NULL, 10); 1296 aiptek->newSetting.programmableDelay = (int)simple_strtol(buf, NULL, 10);
1410 return count; 1297 return count;
1411} 1298}
@@ -1415,23 +1302,6 @@ static DEVICE_ATTR(delay,
1415 show_tabletProgrammableDelay, store_tabletProgrammableDelay); 1302 show_tabletProgrammableDelay, store_tabletProgrammableDelay);
1416 1303
1417/*********************************************************************** 1304/***********************************************************************
1418 * support routines for the 'input_path' file. Note that this file
1419 * only displays current setting.
1420 */
1421static ssize_t show_tabletInputDevice(struct device *dev, struct device_attribute *attr, char *buf)
1422{
1423 struct aiptek *aiptek = dev_get_drvdata(dev);
1424
1425 if (aiptek == NULL)
1426 return 0;
1427
1428 return snprintf(buf, PAGE_SIZE, "/dev/input/%s\n",
1429 aiptek->features.inputPath);
1430}
1431
1432static DEVICE_ATTR(input_path, S_IRUGO, show_tabletInputDevice, NULL);
1433
1434/***********************************************************************
1435 * support routines for the 'event_count' file. Note that this file 1305 * support routines for the 'event_count' file. Note that this file
1436 * only displays current setting. 1306 * only displays current setting.
1437 */ 1307 */
@@ -1439,9 +1309,6 @@ static ssize_t show_tabletEventsReceived(struct device *dev, struct device_attri
1439{ 1309{
1440 struct aiptek *aiptek = dev_get_drvdata(dev); 1310 struct aiptek *aiptek = dev_get_drvdata(dev);
1441 1311
1442 if (aiptek == NULL)
1443 return 0;
1444
1445 return snprintf(buf, PAGE_SIZE, "%ld\n", aiptek->eventCount); 1312 return snprintf(buf, PAGE_SIZE, "%ld\n", aiptek->eventCount);
1446} 1313}
1447 1314
@@ -1456,9 +1323,6 @@ static ssize_t show_tabletDiagnosticMessage(struct device *dev, struct device_at
1456 struct aiptek *aiptek = dev_get_drvdata(dev); 1323 struct aiptek *aiptek = dev_get_drvdata(dev);
1457 char *retMsg; 1324 char *retMsg;
1458 1325
1459 if (aiptek == NULL)
1460 return 0;
1461
1462 switch (aiptek->diagnostic) { 1326 switch (aiptek->diagnostic) {
1463 case AIPTEK_DIAGNOSTIC_NA: 1327 case AIPTEK_DIAGNOSTIC_NA:
1464 retMsg = "no errors\n"; 1328 retMsg = "no errors\n";
@@ -1493,45 +1357,32 @@ static DEVICE_ATTR(diagnostic, S_IRUGO, show_tabletDiagnosticMessage, NULL);
1493 * support routines for the 'stylus_upper' file. Note that this file 1357 * support routines for the 'stylus_upper' file. Note that this file
1494 * both displays current setting and allows for setting changing. 1358 * both displays current setting and allows for setting changing.
1495 */ 1359 */
1360
1361static struct aiptek_map stylus_button_map[] = {
1362 { "upper", AIPTEK_STYLUS_UPPER_BUTTON },
1363 { "lower", AIPTEK_STYLUS_LOWER_BUTTON },
1364 { NULL, AIPTEK_INVALID_VALUE }
1365};
1366
1496static ssize_t show_tabletStylusUpper(struct device *dev, struct device_attribute *attr, char *buf) 1367static ssize_t show_tabletStylusUpper(struct device *dev, struct device_attribute *attr, char *buf)
1497{ 1368{
1498 struct aiptek *aiptek = dev_get_drvdata(dev); 1369 struct aiptek *aiptek = dev_get_drvdata(dev);
1499 char *s;
1500
1501 if (aiptek == NULL)
1502 return 0;
1503
1504 switch (aiptek->curSetting.stylusButtonUpper) {
1505 case AIPTEK_STYLUS_UPPER_BUTTON:
1506 s = "upper";
1507 break;
1508
1509 case AIPTEK_STYLUS_LOWER_BUTTON:
1510 s = "lower";
1511 break;
1512 1370
1513 default: 1371 return snprintf(buf, PAGE_SIZE, "%s\n",
1514 s = "unknown"; 1372 map_val_to_str(stylus_button_map,
1515 break; 1373 aiptek->curSetting.stylusButtonUpper));
1516 }
1517 return snprintf(buf, PAGE_SIZE, "%s\n", s);
1518} 1374}
1519 1375
1520static ssize_t 1376static ssize_t
1521store_tabletStylusUpper(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) 1377store_tabletStylusUpper(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
1522{ 1378{
1523 struct aiptek *aiptek = dev_get_drvdata(dev); 1379 struct aiptek *aiptek = dev_get_drvdata(dev);
1380 int new_button = map_str_to_val(stylus_button_map, buf, count);
1524 1381
1525 if (aiptek == NULL) 1382 if (new_button == AIPTEK_INVALID_VALUE)
1526 return 0; 1383 return -EINVAL;
1527 1384
1528 if (strcmp(buf, "upper") == 0) { 1385 aiptek->newSetting.stylusButtonUpper = new_button;
1529 aiptek->newSetting.stylusButtonUpper =
1530 AIPTEK_STYLUS_UPPER_BUTTON;
1531 } else if (strcmp(buf, "lower") == 0) {
1532 aiptek->newSetting.stylusButtonUpper =
1533 AIPTEK_STYLUS_LOWER_BUTTON;
1534 }
1535 return count; 1386 return count;
1536} 1387}
1537 1388
@@ -1543,45 +1394,26 @@ static DEVICE_ATTR(stylus_upper,
1543 * support routines for the 'stylus_lower' file. Note that this file 1394 * support routines for the 'stylus_lower' file. Note that this file
1544 * both displays current setting and allows for setting changing. 1395 * both displays current setting and allows for setting changing.
1545 */ 1396 */
1397
1546static ssize_t show_tabletStylusLower(struct device *dev, struct device_attribute *attr, char *buf) 1398static ssize_t show_tabletStylusLower(struct device *dev, struct device_attribute *attr, char *buf)
1547{ 1399{
1548 struct aiptek *aiptek = dev_get_drvdata(dev); 1400 struct aiptek *aiptek = dev_get_drvdata(dev);
1549 char *s;
1550
1551 if (aiptek == NULL)
1552 return 0;
1553
1554 switch (aiptek->curSetting.stylusButtonLower) {
1555 case AIPTEK_STYLUS_UPPER_BUTTON:
1556 s = "upper";
1557 break;
1558
1559 case AIPTEK_STYLUS_LOWER_BUTTON:
1560 s = "lower";
1561 break;
1562 1401
1563 default: 1402 return snprintf(buf, PAGE_SIZE, "%s\n",
1564 s = "unknown"; 1403 map_val_to_str(stylus_button_map,
1565 break; 1404 aiptek->curSetting.stylusButtonLower));
1566 }
1567 return snprintf(buf, PAGE_SIZE, "%s\n", s);
1568} 1405}
1569 1406
1570static ssize_t 1407static ssize_t
1571store_tabletStylusLower(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) 1408store_tabletStylusLower(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
1572{ 1409{
1573 struct aiptek *aiptek = dev_get_drvdata(dev); 1410 struct aiptek *aiptek = dev_get_drvdata(dev);
1411 int new_button = map_str_to_val(stylus_button_map, buf, count);
1574 1412
1575 if (aiptek == NULL) 1413 if (new_button == AIPTEK_INVALID_VALUE)
1576 return 0; 1414 return -EINVAL;
1577 1415
1578 if (strcmp(buf, "upper") == 0) { 1416 aiptek->newSetting.stylusButtonLower = new_button;
1579 aiptek->newSetting.stylusButtonLower =
1580 AIPTEK_STYLUS_UPPER_BUTTON;
1581 } else if (strcmp(buf, "lower") == 0) {
1582 aiptek->newSetting.stylusButtonLower =
1583 AIPTEK_STYLUS_LOWER_BUTTON;
1584 }
1585 return count; 1417 return count;
1586} 1418}
1587 1419
@@ -1593,49 +1425,33 @@ static DEVICE_ATTR(stylus_lower,
1593 * support routines for the 'mouse_left' file. Note that this file 1425 * support routines for the 'mouse_left' file. Note that this file
1594 * both displays current setting and allows for setting changing. 1426 * both displays current setting and allows for setting changing.
1595 */ 1427 */
1428
1429static struct aiptek_map mouse_button_map[] = {
1430 { "left", AIPTEK_MOUSE_LEFT_BUTTON },
1431 { "middle", AIPTEK_MOUSE_MIDDLE_BUTTON },
1432 { "right", AIPTEK_MOUSE_RIGHT_BUTTON },
1433 { NULL, AIPTEK_INVALID_VALUE }
1434};
1435
1596static ssize_t show_tabletMouseLeft(struct device *dev, struct device_attribute *attr, char *buf) 1436static ssize_t show_tabletMouseLeft(struct device *dev, struct device_attribute *attr, char *buf)
1597{ 1437{
1598 struct aiptek *aiptek = dev_get_drvdata(dev); 1438 struct aiptek *aiptek = dev_get_drvdata(dev);
1599 char *s;
1600
1601 if (aiptek == NULL)
1602 return 0;
1603
1604 switch (aiptek->curSetting.mouseButtonLeft) {
1605 case AIPTEK_MOUSE_LEFT_BUTTON:
1606 s = "left";
1607 break;
1608
1609 case AIPTEK_MOUSE_MIDDLE_BUTTON:
1610 s = "middle";
1611 break;
1612
1613 case AIPTEK_MOUSE_RIGHT_BUTTON:
1614 s = "right";
1615 break;
1616 1439
1617 default: 1440 return snprintf(buf, PAGE_SIZE, "%s\n",
1618 s = "unknown"; 1441 map_val_to_str(mouse_button_map,
1619 break; 1442 aiptek->curSetting.mouseButtonLeft));
1620 }
1621 return snprintf(buf, PAGE_SIZE, "%s\n", s);
1622} 1443}
1623 1444
1624static ssize_t 1445static ssize_t
1625store_tabletMouseLeft(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) 1446store_tabletMouseLeft(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
1626{ 1447{
1627 struct aiptek *aiptek = dev_get_drvdata(dev); 1448 struct aiptek *aiptek = dev_get_drvdata(dev);
1449 int new_button = map_str_to_val(mouse_button_map, buf, count);
1628 1450
1629 if (aiptek == NULL) 1451 if (new_button == AIPTEK_INVALID_VALUE)
1630 return 0; 1452 return -EINVAL;
1631 1453
1632 if (strcmp(buf, "left") == 0) { 1454 aiptek->newSetting.mouseButtonLeft = new_button;
1633 aiptek->newSetting.mouseButtonLeft = AIPTEK_MOUSE_LEFT_BUTTON;
1634 } else if (strcmp(buf, "middle") == 0) {
1635 aiptek->newSetting.mouseButtonLeft = AIPTEK_MOUSE_MIDDLE_BUTTON;
1636 } else if (strcmp(buf, "right") == 0) {
1637 aiptek->newSetting.mouseButtonLeft = AIPTEK_MOUSE_RIGHT_BUTTON;
1638 }
1639 return count; 1455 return count;
1640} 1456}
1641 1457
@@ -1650,48 +1466,22 @@ static DEVICE_ATTR(mouse_left,
1650static ssize_t show_tabletMouseMiddle(struct device *dev, struct device_attribute *attr, char *buf) 1466static ssize_t show_tabletMouseMiddle(struct device *dev, struct device_attribute *attr, char *buf)
1651{ 1467{
1652 struct aiptek *aiptek = dev_get_drvdata(dev); 1468 struct aiptek *aiptek = dev_get_drvdata(dev);
1653 char *s;
1654 1469
1655 if (aiptek == NULL) 1470 return snprintf(buf, PAGE_SIZE, "%s\n",
1656 return 0; 1471 map_val_to_str(mouse_button_map,
1657 1472 aiptek->curSetting.mouseButtonMiddle));
1658 switch (aiptek->curSetting.mouseButtonMiddle) {
1659 case AIPTEK_MOUSE_LEFT_BUTTON:
1660 s = "left";
1661 break;
1662
1663 case AIPTEK_MOUSE_MIDDLE_BUTTON:
1664 s = "middle";
1665 break;
1666
1667 case AIPTEK_MOUSE_RIGHT_BUTTON:
1668 s = "right";
1669 break;
1670
1671 default:
1672 s = "unknown";
1673 break;
1674 }
1675 return snprintf(buf, PAGE_SIZE, "%s\n", s);
1676} 1473}
1677 1474
1678static ssize_t 1475static ssize_t
1679store_tabletMouseMiddle(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) 1476store_tabletMouseMiddle(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
1680{ 1477{
1681 struct aiptek *aiptek = dev_get_drvdata(dev); 1478 struct aiptek *aiptek = dev_get_drvdata(dev);
1479 int new_button = map_str_to_val(mouse_button_map, buf, count);
1682 1480
1683 if (aiptek == NULL) 1481 if (new_button == AIPTEK_INVALID_VALUE)
1684 return 0; 1482 return -EINVAL;
1685 1483
1686 if (strcmp(buf, "left") == 0) { 1484 aiptek->newSetting.mouseButtonMiddle = new_button;
1687 aiptek->newSetting.mouseButtonMiddle = AIPTEK_MOUSE_LEFT_BUTTON;
1688 } else if (strcmp(buf, "middle") == 0) {
1689 aiptek->newSetting.mouseButtonMiddle =
1690 AIPTEK_MOUSE_MIDDLE_BUTTON;
1691 } else if (strcmp(buf, "right") == 0) {
1692 aiptek->newSetting.mouseButtonMiddle =
1693 AIPTEK_MOUSE_RIGHT_BUTTON;
1694 }
1695 return count; 1485 return count;
1696} 1486}
1697 1487
@@ -1706,47 +1496,22 @@ static DEVICE_ATTR(mouse_middle,
1706static ssize_t show_tabletMouseRight(struct device *dev, struct device_attribute *attr, char *buf) 1496static ssize_t show_tabletMouseRight(struct device *dev, struct device_attribute *attr, char *buf)
1707{ 1497{
1708 struct aiptek *aiptek = dev_get_drvdata(dev); 1498 struct aiptek *aiptek = dev_get_drvdata(dev);
1709 char *s;
1710
1711 if (aiptek == NULL)
1712 return 0;
1713
1714 switch (aiptek->curSetting.mouseButtonRight) {
1715 case AIPTEK_MOUSE_LEFT_BUTTON:
1716 s = "left";
1717 break;
1718
1719 case AIPTEK_MOUSE_MIDDLE_BUTTON:
1720 s = "middle";
1721 break;
1722 1499
1723 case AIPTEK_MOUSE_RIGHT_BUTTON: 1500 return snprintf(buf, PAGE_SIZE, "%s\n",
1724 s = "right"; 1501 map_val_to_str(mouse_button_map,
1725 break; 1502 aiptek->curSetting.mouseButtonRight));
1726
1727 default:
1728 s = "unknown";
1729 break;
1730 }
1731 return snprintf(buf, PAGE_SIZE, "%s\n", s);
1732} 1503}
1733 1504
1734static ssize_t 1505static ssize_t
1735store_tabletMouseRight(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) 1506store_tabletMouseRight(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
1736{ 1507{
1737 struct aiptek *aiptek = dev_get_drvdata(dev); 1508 struct aiptek *aiptek = dev_get_drvdata(dev);
1509 int new_button = map_str_to_val(mouse_button_map, buf, count);
1738 1510
1739 if (aiptek == NULL) 1511 if (new_button == AIPTEK_INVALID_VALUE)
1740 return 0; 1512 return -EINVAL;
1741 1513
1742 if (strcmp(buf, "left") == 0) { 1514 aiptek->newSetting.mouseButtonRight = new_button;
1743 aiptek->newSetting.mouseButtonRight = AIPTEK_MOUSE_LEFT_BUTTON;
1744 } else if (strcmp(buf, "middle") == 0) {
1745 aiptek->newSetting.mouseButtonRight =
1746 AIPTEK_MOUSE_MIDDLE_BUTTON;
1747 } else if (strcmp(buf, "right") == 0) {
1748 aiptek->newSetting.mouseButtonRight = AIPTEK_MOUSE_RIGHT_BUTTON;
1749 }
1750 return count; 1515 return count;
1751} 1516}
1752 1517
@@ -1762,9 +1527,6 @@ static ssize_t show_tabletWheel(struct device *dev, struct device_attribute *att
1762{ 1527{
1763 struct aiptek *aiptek = dev_get_drvdata(dev); 1528 struct aiptek *aiptek = dev_get_drvdata(dev);
1764 1529
1765 if (aiptek == NULL)
1766 return 0;
1767
1768 if (aiptek->curSetting.wheel == AIPTEK_WHEEL_DISABLE) { 1530 if (aiptek->curSetting.wheel == AIPTEK_WHEEL_DISABLE) {
1769 return snprintf(buf, PAGE_SIZE, "disable\n"); 1531 return snprintf(buf, PAGE_SIZE, "disable\n");
1770 } else { 1532 } else {
@@ -1778,9 +1540,6 @@ store_tabletWheel(struct device *dev, struct device_attribute *attr, const char
1778{ 1540{
1779 struct aiptek *aiptek = dev_get_drvdata(dev); 1541 struct aiptek *aiptek = dev_get_drvdata(dev);
1780 1542
1781 if (aiptek == NULL)
1782 return 0;
1783
1784 aiptek->newSetting.wheel = (int)simple_strtol(buf, NULL, 10); 1543 aiptek->newSetting.wheel = (int)simple_strtol(buf, NULL, 10);
1785 return count; 1544 return count;
1786} 1545}
@@ -1794,11 +1553,6 @@ static DEVICE_ATTR(wheel,
1794 */ 1553 */
1795static ssize_t show_tabletExecute(struct device *dev, struct device_attribute *attr, char *buf) 1554static ssize_t show_tabletExecute(struct device *dev, struct device_attribute *attr, char *buf)
1796{ 1555{
1797 struct aiptek *aiptek = dev_get_drvdata(dev);
1798
1799 if (aiptek == NULL)
1800 return 0;
1801
1802 /* There is nothing useful to display, so a one-line manual 1556 /* There is nothing useful to display, so a one-line manual
1803 * is in order... 1557 * is in order...
1804 */ 1558 */
@@ -1811,9 +1565,6 @@ store_tabletExecute(struct device *dev, struct device_attribute *attr, const cha
1811{ 1565{
1812 struct aiptek *aiptek = dev_get_drvdata(dev); 1566 struct aiptek *aiptek = dev_get_drvdata(dev);
1813 1567
1814 if (aiptek == NULL)
1815 return 0;
1816
1817 /* We do not care what you write to this file. Merely the action 1568 /* We do not care what you write to this file. Merely the action
1818 * of writing to this file triggers a tablet reprogramming. 1569 * of writing to this file triggers a tablet reprogramming.
1819 */ 1570 */
@@ -1837,9 +1588,6 @@ static ssize_t show_tabletODMCode(struct device *dev, struct device_attribute *a
1837{ 1588{
1838 struct aiptek *aiptek = dev_get_drvdata(dev); 1589 struct aiptek *aiptek = dev_get_drvdata(dev);
1839 1590
1840 if (aiptek == NULL)
1841 return 0;
1842
1843 return snprintf(buf, PAGE_SIZE, "0x%04x\n", aiptek->features.odmCode); 1591 return snprintf(buf, PAGE_SIZE, "0x%04x\n", aiptek->features.odmCode);
1844} 1592}
1845 1593
@@ -1853,9 +1601,6 @@ static ssize_t show_tabletModelCode(struct device *dev, struct device_attribute
1853{ 1601{
1854 struct aiptek *aiptek = dev_get_drvdata(dev); 1602 struct aiptek *aiptek = dev_get_drvdata(dev);
1855 1603
1856 if (aiptek == NULL)
1857 return 0;
1858
1859 return snprintf(buf, PAGE_SIZE, "0x%04x\n", aiptek->features.modelCode); 1604 return snprintf(buf, PAGE_SIZE, "0x%04x\n", aiptek->features.modelCode);
1860} 1605}
1861 1606
@@ -1869,86 +1614,39 @@ static ssize_t show_firmwareCode(struct device *dev, struct device_attribute *at
1869{ 1614{
1870 struct aiptek *aiptek = dev_get_drvdata(dev); 1615 struct aiptek *aiptek = dev_get_drvdata(dev);
1871 1616
1872 if (aiptek == NULL)
1873 return 0;
1874
1875 return snprintf(buf, PAGE_SIZE, "%04x\n", 1617 return snprintf(buf, PAGE_SIZE, "%04x\n",
1876 aiptek->features.firmwareCode); 1618 aiptek->features.firmwareCode);
1877} 1619}
1878 1620
1879static DEVICE_ATTR(firmware_code, S_IRUGO, show_firmwareCode, NULL); 1621static DEVICE_ATTR(firmware_code, S_IRUGO, show_firmwareCode, NULL);
1880 1622
1881/*********************************************************************** 1623static struct attribute *aiptek_attributes[] = {
1882 * This routine removes all existing sysfs files managed by this device 1624 &dev_attr_size.attr,
1883 * driver. 1625 &dev_attr_pointer_mode.attr,
1884 */ 1626 &dev_attr_coordinate_mode.attr,
1885static void aiptek_delete_files(struct device *dev) 1627 &dev_attr_tool_mode.attr,
1886{ 1628 &dev_attr_xtilt.attr,
1887 device_remove_file(dev, &dev_attr_size); 1629 &dev_attr_ytilt.attr,
1888 device_remove_file(dev, &dev_attr_product_id); 1630 &dev_attr_jitter.attr,
1889 device_remove_file(dev, &dev_attr_vendor_id); 1631 &dev_attr_delay.attr,
1890 device_remove_file(dev, &dev_attr_vendor); 1632 &dev_attr_event_count.attr,
1891 device_remove_file(dev, &dev_attr_product); 1633 &dev_attr_diagnostic.attr,
1892 device_remove_file(dev, &dev_attr_pointer_mode); 1634 &dev_attr_odm_code.attr,
1893 device_remove_file(dev, &dev_attr_coordinate_mode); 1635 &dev_attr_model_code.attr,
1894 device_remove_file(dev, &dev_attr_tool_mode); 1636 &dev_attr_firmware_code.attr,
1895 device_remove_file(dev, &dev_attr_xtilt); 1637 &dev_attr_stylus_lower.attr,
1896 device_remove_file(dev, &dev_attr_ytilt); 1638 &dev_attr_stylus_upper.attr,
1897 device_remove_file(dev, &dev_attr_jitter); 1639 &dev_attr_mouse_left.attr,
1898 device_remove_file(dev, &dev_attr_delay); 1640 &dev_attr_mouse_middle.attr,
1899 device_remove_file(dev, &dev_attr_input_path); 1641 &dev_attr_mouse_right.attr,
1900 device_remove_file(dev, &dev_attr_event_count); 1642 &dev_attr_wheel.attr,
1901 device_remove_file(dev, &dev_attr_diagnostic); 1643 &dev_attr_execute.attr,
1902 device_remove_file(dev, &dev_attr_odm_code); 1644 NULL
1903 device_remove_file(dev, &dev_attr_model_code); 1645};
1904 device_remove_file(dev, &dev_attr_firmware_code);
1905 device_remove_file(dev, &dev_attr_stylus_lower);
1906 device_remove_file(dev, &dev_attr_stylus_upper);
1907 device_remove_file(dev, &dev_attr_mouse_left);
1908 device_remove_file(dev, &dev_attr_mouse_middle);
1909 device_remove_file(dev, &dev_attr_mouse_right);
1910 device_remove_file(dev, &dev_attr_wheel);
1911 device_remove_file(dev, &dev_attr_execute);
1912}
1913
1914/***********************************************************************
1915 * This routine creates the sysfs files managed by this device
1916 * driver.
1917 */
1918static int aiptek_add_files(struct device *dev)
1919{
1920 int ret;
1921 1646
1922 if ((ret = device_create_file(dev, &dev_attr_size)) || 1647static struct attribute_group aiptek_attribute_group = {
1923 (ret = device_create_file(dev, &dev_attr_product_id)) || 1648 .attrs = aiptek_attributes,
1924 (ret = device_create_file(dev, &dev_attr_vendor_id)) || 1649};
1925 (ret = device_create_file(dev, &dev_attr_vendor)) ||
1926 (ret = device_create_file(dev, &dev_attr_product)) ||
1927 (ret = device_create_file(dev, &dev_attr_pointer_mode)) ||
1928 (ret = device_create_file(dev, &dev_attr_coordinate_mode)) ||
1929 (ret = device_create_file(dev, &dev_attr_tool_mode)) ||
1930 (ret = device_create_file(dev, &dev_attr_xtilt)) ||
1931 (ret = device_create_file(dev, &dev_attr_ytilt)) ||
1932 (ret = device_create_file(dev, &dev_attr_jitter)) ||
1933 (ret = device_create_file(dev, &dev_attr_delay)) ||
1934 (ret = device_create_file(dev, &dev_attr_input_path)) ||
1935 (ret = device_create_file(dev, &dev_attr_event_count)) ||
1936 (ret = device_create_file(dev, &dev_attr_diagnostic)) ||
1937 (ret = device_create_file(dev, &dev_attr_odm_code)) ||
1938 (ret = device_create_file(dev, &dev_attr_model_code)) ||
1939 (ret = device_create_file(dev, &dev_attr_firmware_code)) ||
1940 (ret = device_create_file(dev, &dev_attr_stylus_lower)) ||
1941 (ret = device_create_file(dev, &dev_attr_stylus_upper)) ||
1942 (ret = device_create_file(dev, &dev_attr_mouse_left)) ||
1943 (ret = device_create_file(dev, &dev_attr_mouse_middle)) ||
1944 (ret = device_create_file(dev, &dev_attr_mouse_right)) ||
1945 (ret = device_create_file(dev, &dev_attr_wheel)) ||
1946 (ret = device_create_file(dev, &dev_attr_execute))) {
1947 err("aiptek: killing own sysfs device files\n");
1948 aiptek_delete_files(dev);
1949 }
1950 return ret;
1951}
1952 1650
1953/*********************************************************************** 1651/***********************************************************************
1954 * This routine is called when a tablet has been identified. It basically 1652 * This routine is called when a tablet has been identified. It basically
@@ -1961,8 +1659,6 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
1961 struct usb_endpoint_descriptor *endpoint; 1659 struct usb_endpoint_descriptor *endpoint;
1962 struct aiptek *aiptek; 1660 struct aiptek *aiptek;
1963 struct input_dev *inputdev; 1661 struct input_dev *inputdev;
1964 struct input_handle *inputhandle;
1965 struct list_head *node, *next;
1966 int i; 1662 int i;
1967 int speeds[] = { 0, 1663 int speeds[] = { 0,
1968 AIPTEK_PROGRAMMABLE_DELAY_50, 1664 AIPTEK_PROGRAMMABLE_DELAY_50,
@@ -1984,17 +1680,23 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
1984 1680
1985 aiptek = kzalloc(sizeof(struct aiptek), GFP_KERNEL); 1681 aiptek = kzalloc(sizeof(struct aiptek), GFP_KERNEL);
1986 inputdev = input_allocate_device(); 1682 inputdev = input_allocate_device();
1987 if (!aiptek || !inputdev) 1683 if (!aiptek || !inputdev) {
1684 warn("aiptek: cannot allocate memory or input device");
1988 goto fail1; 1685 goto fail1;
1686 }
1989 1687
1990 aiptek->data = usb_buffer_alloc(usbdev, AIPTEK_PACKET_LENGTH, 1688 aiptek->data = usb_buffer_alloc(usbdev, AIPTEK_PACKET_LENGTH,
1991 GFP_ATOMIC, &aiptek->data_dma); 1689 GFP_ATOMIC, &aiptek->data_dma);
1992 if (!aiptek->data) 1690 if (!aiptek->data) {
1691 warn("aiptek: cannot allocate usb buffer");
1993 goto fail1; 1692 goto fail1;
1693 }
1994 1694
1995 aiptek->urb = usb_alloc_urb(0, GFP_KERNEL); 1695 aiptek->urb = usb_alloc_urb(0, GFP_KERNEL);
1996 if (!aiptek->urb) 1696 if (!aiptek->urb) {
1697 warn("aiptek: cannot allocate urb");
1997 goto fail2; 1698 goto fail2;
1699 }
1998 1700
1999 aiptek->inputdev = inputdev; 1701 aiptek->inputdev = inputdev;
2000 aiptek->usbdev = usbdev; 1702 aiptek->usbdev = usbdev;
@@ -2002,6 +1704,7 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
2002 aiptek->inDelay = 0; 1704 aiptek->inDelay = 0;
2003 aiptek->endDelay = 0; 1705 aiptek->endDelay = 0;
2004 aiptek->previousJitterable = 0; 1706 aiptek->previousJitterable = 0;
1707 aiptek->lastMacro = -1;
2005 1708
2006 /* Set up the curSettings struct. Said struct contains the current 1709 /* Set up the curSettings struct. Said struct contains the current
2007 * programmable parameters. The newSetting struct contains changes 1710 * programmable parameters. The newSetting struct contains changes
@@ -2054,36 +1757,23 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
2054 /* Now program the capacities of the tablet, in terms of being 1757 /* Now program the capacities of the tablet, in terms of being
2055 * an input device. 1758 * an input device.
2056 */ 1759 */
2057 inputdev->evbit[0] |= BIT(EV_KEY) 1760 for (i = 0; i < ARRAY_SIZE(eventTypes); ++i)
2058 | BIT(EV_ABS) 1761 __set_bit(eventTypes[i], inputdev->evbit);
2059 | BIT(EV_REL)
2060 | BIT(EV_MSC);
2061
2062 inputdev->absbit[0] |= BIT(ABS_MISC);
2063 1762
2064 inputdev->relbit[0] |= 1763 for (i = 0; i < ARRAY_SIZE(absEvents); ++i)
2065 (BIT(REL_X) | BIT(REL_Y) | BIT(REL_WHEEL) | BIT(REL_MISC)); 1764 __set_bit(absEvents[i], inputdev->absbit);
2066 1765
2067 inputdev->keybit[LONG(BTN_LEFT)] |= 1766 for (i = 0; i < ARRAY_SIZE(relEvents); ++i)
2068 (BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE)); 1767 __set_bit(relEvents[i], inputdev->relbit);
2069 1768
2070 inputdev->keybit[LONG(BTN_DIGI)] |= 1769 __set_bit(MSC_SERIAL, inputdev->mscbit);
2071 (BIT(BTN_TOOL_PEN) |
2072 BIT(BTN_TOOL_RUBBER) |
2073 BIT(BTN_TOOL_PENCIL) |
2074 BIT(BTN_TOOL_AIRBRUSH) |
2075 BIT(BTN_TOOL_BRUSH) |
2076 BIT(BTN_TOOL_MOUSE) |
2077 BIT(BTN_TOOL_LENS) |
2078 BIT(BTN_TOUCH) | BIT(BTN_STYLUS) | BIT(BTN_STYLUS2));
2079 1770
2080 inputdev->mscbit[0] = BIT(MSC_SERIAL); 1771 /* Set up key and button codes */
1772 for (i = 0; i < ARRAY_SIZE(buttonEvents); ++i)
1773 __set_bit(buttonEvents[i], inputdev->keybit);
2081 1774
2082 /* Programming the tablet macro keys needs to be done with a for loop
2083 * as the keycodes are discontiguous.
2084 */
2085 for (i = 0; i < ARRAY_SIZE(macroKeyEvents); ++i) 1775 for (i = 0; i < ARRAY_SIZE(macroKeyEvents); ++i)
2086 set_bit(macroKeyEvents[i], inputdev->keybit); 1776 __set_bit(macroKeyEvents[i], inputdev->keybit);
2087 1777
2088 /* 1778 /*
2089 * Program the input device coordinate capacities. We do not yet 1779 * Program the input device coordinate capacities. We do not yet
@@ -2134,25 +1824,11 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
2134 } 1824 }
2135 } 1825 }
2136 1826
2137 /* Register the tablet as an Input Device 1827 /* Murphy says that some day someone will have a tablet that fails the
2138 */ 1828 above test. That's you, Frederic Rodrigo */
2139 err = input_register_device(aiptek->inputdev); 1829 if (i == ARRAY_SIZE(speeds)) {
2140 if (err) 1830 info("input: Aiptek tried all speeds, no sane response");
2141 goto fail2; 1831 goto fail2;
2142
2143 /* We now will look for the evdev device which is mapped to
2144 * the tablet. The partial name is kept in the link list of
2145 * input_handles associated with this input device.
2146 * What identifies an evdev input_handler is that it begins
2147 * with 'event', continues with a digit, and that in turn
2148 * is mapped to input/eventN.
2149 */
2150 list_for_each_safe(node, next, &inputdev->h_list) {
2151 inputhandle = to_handle(node);
2152 if (strncmp(inputhandle->name, "event", 5) == 0) {
2153 strcpy(aiptek->features.inputPath, inputhandle->name);
2154 break;
2155 }
2156 } 1832 }
2157 1833
2158 /* Associate this driver's struct with the usb interface. 1834 /* Associate this driver's struct with the usb interface.
@@ -2161,18 +1837,27 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
2161 1837
2162 /* Set up the sysfs files 1838 /* Set up the sysfs files
2163 */ 1839 */
2164 aiptek_add_files(&intf->dev); 1840 err = sysfs_create_group(&intf->dev.kobj, &aiptek_attribute_group);
1841 if (err) {
1842 warn("aiptek: cannot create sysfs group err: %d", err);
1843 goto fail3;
1844 }
2165 1845
2166 /* Make sure the evdev module is loaded. Assuming evdev IS a module :-) 1846 /* Register the tablet as an Input Device
2167 */ 1847 */
2168 if (request_module("evdev") != 0) 1848 err = input_register_device(aiptek->inputdev);
2169 info("aiptek: error loading 'evdev' module"); 1849 if (err) {
2170 1850 warn("aiptek: input_register_device returned err: %d", err);
1851 goto fail4;
1852 }
2171 return 0; 1853 return 0;
2172 1854
1855 fail4: sysfs_remove_group(&intf->dev.kobj, &aiptek_attribute_group);
1856 fail3: usb_free_urb(aiptek->urb);
2173 fail2: usb_buffer_free(usbdev, AIPTEK_PACKET_LENGTH, aiptek->data, 1857 fail2: usb_buffer_free(usbdev, AIPTEK_PACKET_LENGTH, aiptek->data,
2174 aiptek->data_dma); 1858 aiptek->data_dma);
2175 fail1: input_free_device(inputdev); 1859 fail1: usb_set_intfdata(intf, NULL);
1860 input_free_device(inputdev);
2176 kfree(aiptek); 1861 kfree(aiptek);
2177 return err; 1862 return err;
2178} 1863}
@@ -2192,7 +1877,7 @@ static void aiptek_disconnect(struct usb_interface *intf)
2192 */ 1877 */
2193 usb_kill_urb(aiptek->urb); 1878 usb_kill_urb(aiptek->urb);
2194 input_unregister_device(aiptek->inputdev); 1879 input_unregister_device(aiptek->inputdev);
2195 aiptek_delete_files(&intf->dev); 1880 sysfs_remove_group(&intf->dev.kobj, &aiptek_attribute_group);
2196 usb_free_urb(aiptek->urb); 1881 usb_free_urb(aiptek->urb);
2197 usb_buffer_free(interface_to_usbdev(intf), 1882 usb_buffer_free(interface_to_usbdev(intf),
2198 AIPTEK_PACKET_LENGTH, 1883 AIPTEK_PACKET_LENGTH,
diff --git a/drivers/input/tablet/wacom.h b/drivers/input/tablet/wacom.h
index ef01a807ec0f..6542edb6f76e 100644
--- a/drivers/input/tablet/wacom.h
+++ b/drivers/input/tablet/wacom.h
@@ -11,7 +11,7 @@
11 * Copyright (c) 2000 Daniel Egger <egger@suse.de> 11 * Copyright (c) 2000 Daniel Egger <egger@suse.de>
12 * Copyright (c) 2001 Frederic Lepied <flepied@mandrakesoft.com> 12 * Copyright (c) 2001 Frederic Lepied <flepied@mandrakesoft.com>
13 * Copyright (c) 2004 Panagiotis Issaris <panagiotis.issaris@mech.kuleuven.ac.be> 13 * Copyright (c) 2004 Panagiotis Issaris <panagiotis.issaris@mech.kuleuven.ac.be>
14 * Copyright (c) 2002-2006 Ping Cheng <pingc@wacom.com> 14 * Copyright (c) 2002-2007 Ping Cheng <pingc@wacom.com>
15 * 15 *
16 * ChangeLog: 16 * ChangeLog:
17 * v0.1 (vp) - Initial release 17 * v0.1 (vp) - Initial release
@@ -62,8 +62,9 @@
62 * - Minor data report fix 62 * - Minor data report fix
63 * v1.46 (pc) - Split wacom.c into wacom_sys.c and wacom_wac.c, 63 * v1.46 (pc) - Split wacom.c into wacom_sys.c and wacom_wac.c,
64 * - where wacom_sys.c deals with system specific code, 64 * - where wacom_sys.c deals with system specific code,
65 * - and wacom_wac.c deals with Wacom specific code 65 * - and wacom_wac.c deals with Wacom specific code
66 * - Support Intuos3 4x6 66 * - Support Intuos3 4x6
67 * v1.47 (pc) - Added support for Bamboo
67 */ 68 */
68 69
69/* 70/*
@@ -84,7 +85,7 @@
84/* 85/*
85 * Version Information 86 * Version Information
86 */ 87 */
87#define DRIVER_VERSION "v1.46" 88#define DRIVER_VERSION "v1.47"
88#define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>" 89#define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>"
89#define DRIVER_DESC "USB Wacom Graphire and Wacom Intuos tablet driver" 90#define DRIVER_DESC "USB Wacom Graphire and Wacom Intuos tablet driver"
90#define DRIVER_LICENSE "GPL" 91#define DRIVER_LICENSE "GPL"
@@ -123,6 +124,7 @@ extern void input_dev_i3(struct input_dev *input_dev, struct wacom_wac *wacom_wa
123extern void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac); 124extern void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac);
124extern void input_dev_pl(struct input_dev *input_dev, struct wacom_wac *wacom_wac); 125extern void input_dev_pl(struct input_dev *input_dev, struct wacom_wac *wacom_wac);
125extern void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac); 126extern void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac);
127extern void input_dev_mo(struct input_dev *input_dev, struct wacom_wac *wacom_wac);
126extern __u16 wacom_le16_to_cpu(unsigned char *data); 128extern __u16 wacom_le16_to_cpu(unsigned char *data);
127extern __u16 wacom_be16_to_cpu(unsigned char *data); 129extern __u16 wacom_be16_to_cpu(unsigned char *data);
128extern struct wacom_features * get_wacom_feature(const struct usb_device_id *id); 130extern struct wacom_features * get_wacom_feature(const struct usb_device_id *id);
diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c
index 83bddef66067..064e123c9b76 100644
--- a/drivers/input/tablet/wacom_sys.c
+++ b/drivers/input/tablet/wacom_sys.c
@@ -138,6 +138,12 @@ static void wacom_close(struct input_dev *dev)
138 usb_kill_urb(wacom->irq); 138 usb_kill_urb(wacom->irq);
139} 139}
140 140
141void input_dev_mo(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
142{
143 input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_1) | BIT(BTN_5);
144 input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0);
145}
146
141void input_dev_g4(struct input_dev *input_dev, struct wacom_wac *wacom_wac) 147void input_dev_g4(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
142{ 148{
143 input_dev->evbit[0] |= BIT(EV_MSC); 149 input_dev->evbit[0] |= BIT(EV_MSC);
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c
index 7661f03a2db2..fc03ba256f4c 100644
--- a/drivers/input/tablet/wacom_wac.c
+++ b/drivers/input/tablet/wacom_wac.c
@@ -178,7 +178,8 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
178 178
179 case 2: /* Mouse with wheel */ 179 case 2: /* Mouse with wheel */
180 wacom_report_key(wcombo, BTN_MIDDLE, data[1] & 0x04); 180 wacom_report_key(wcombo, BTN_MIDDLE, data[1] & 0x04);
181 if (wacom->features->type == WACOM_G4) { 181 if (wacom->features->type == WACOM_G4 ||
182 wacom->features->type == WACOM_MO) {
182 rw = data[7] & 0x04 ? (data[7] & 0x03)-4 : (data[7] & 0x03); 183 rw = data[7] & 0x04 ? (data[7] & 0x03)-4 : (data[7] & 0x03);
183 wacom_report_rel(wcombo, REL_WHEEL, -rw); 184 wacom_report_rel(wcombo, REL_WHEEL, -rw);
184 } else 185 } else
@@ -190,7 +191,8 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
190 id = CURSOR_DEVICE_ID; 191 id = CURSOR_DEVICE_ID;
191 wacom_report_key(wcombo, BTN_LEFT, data[1] & 0x01); 192 wacom_report_key(wcombo, BTN_LEFT, data[1] & 0x01);
192 wacom_report_key(wcombo, BTN_RIGHT, data[1] & 0x02); 193 wacom_report_key(wcombo, BTN_RIGHT, data[1] & 0x02);
193 if (wacom->features->type == WACOM_G4) 194 if (wacom->features->type == WACOM_G4 ||
195 wacom->features->type == WACOM_MO)
194 wacom_report_abs(wcombo, ABS_DISTANCE, data[6] & 0x3f); 196 wacom_report_abs(wcombo, ABS_DISTANCE, data[6] & 0x3f);
195 else 197 else
196 wacom_report_abs(wcombo, ABS_DISTANCE, data[7] & 0x3f); 198 wacom_report_abs(wcombo, ABS_DISTANCE, data[7] & 0x3f);
@@ -226,7 +228,8 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
226 } 228 }
227 229
228 /* send pad data */ 230 /* send pad data */
229 if (wacom->features->type == WACOM_G4) { 231 switch (wacom->features->type) {
232 case WACOM_G4:
230 if (data[7] & 0xf8) { 233 if (data[7] & 0xf8) {
231 wacom_input_sync(wcombo); /* sync last event */ 234 wacom_input_sync(wcombo); /* sync last event */
232 wacom->id[1] = 1; 235 wacom->id[1] = 1;
@@ -247,6 +250,33 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
247 wacom_report_abs(wcombo, ABS_MISC, 0); 250 wacom_report_abs(wcombo, ABS_MISC, 0);
248 wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); 251 wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0);
249 } 252 }
253 break;
254 case WACOM_MO:
255 if ((data[7] & 0xf8) || (data[8] & 0x80)) {
256 wacom_input_sync(wcombo); /* sync last event */
257 wacom->id[1] = 1;
258 wacom->serial[1] = (data[7] & 0xf8);
259 wacom_report_key(wcombo, BTN_0, (data[7] & 0x08));
260 wacom_report_key(wcombo, BTN_1, (data[7] & 0x20));
261 wacom_report_key(wcombo, BTN_4, (data[7] & 0x10));
262 wacom_report_key(wcombo, BTN_5, (data[7] & 0x40));
263 wacom_report_abs(wcombo, ABS_WHEEL, (data[8] & 0x7f));
264 wacom_report_key(wcombo, BTN_TOOL_FINGER, 0xf0);
265 wacom_report_abs(wcombo, ABS_MISC, PAD_DEVICE_ID);
266 wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0);
267 } else if (wacom->id[1]) {
268 wacom_input_sync(wcombo); /* sync last event */
269 wacom->id[1] = 0;
270 wacom_report_key(wcombo, BTN_0, (data[7] & 0x08));
271 wacom_report_key(wcombo, BTN_1, (data[7] & 0x20));
272 wacom_report_key(wcombo, BTN_4, (data[7] & 0x10));
273 wacom_report_key(wcombo, BTN_5, (data[7] & 0x40));
274 wacom_report_abs(wcombo, ABS_WHEEL, (data[8] & 0x7f));
275 wacom_report_key(wcombo, BTN_TOOL_FINGER, 0);
276 wacom_report_abs(wcombo, ABS_MISC, 0);
277 wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0);
278 }
279 break;
250 } 280 }
251 return 1; 281 return 1;
252} 282}
@@ -331,7 +361,7 @@ static int wacom_intuos_inout(struct wacom_wac *wacom, void *wcombo)
331 wacom_report_key(wcombo, BTN_EXTRA, 0); 361 wacom_report_key(wcombo, BTN_EXTRA, 0);
332 wacom_report_abs(wcombo, ABS_THROTTLE, 0); 362 wacom_report_abs(wcombo, ABS_THROTTLE, 0);
333 wacom_report_abs(wcombo, ABS_RZ, 0); 363 wacom_report_abs(wcombo, ABS_RZ, 0);
334 } else { 364 } else {
335 wacom_report_abs(wcombo, ABS_PRESSURE, 0); 365 wacom_report_abs(wcombo, ABS_PRESSURE, 0);
336 wacom_report_abs(wcombo, ABS_TILT_X, 0); 366 wacom_report_abs(wcombo, ABS_TILT_X, 0);
337 wacom_report_abs(wcombo, ABS_TILT_Y, 0); 367 wacom_report_abs(wcombo, ABS_TILT_Y, 0);
@@ -423,9 +453,9 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo)
423 return result-1; 453 return result-1;
424 454
425 /* Only large I3 and I1 & I2 support Lense Cursor */ 455 /* Only large I3 and I1 & I2 support Lense Cursor */
426 if((wacom->tool[idx] == BTN_TOOL_LENS) 456 if ((wacom->tool[idx] == BTN_TOOL_LENS)
427 && ((wacom->features->type == INTUOS3) 457 && ((wacom->features->type == INTUOS3)
428 || (wacom->features->type == INTUOS3S))) 458 || (wacom->features->type == INTUOS3S)))
429 return 0; 459 return 0;
430 460
431 /* Cintiq doesn't send data when RDY bit isn't set */ 461 /* Cintiq doesn't send data when RDY bit isn't set */
@@ -517,6 +547,7 @@ int wacom_wac_irq(struct wacom_wac *wacom_wac, void *wcombo)
517 break; 547 break;
518 case WACOM_G4: 548 case WACOM_G4:
519 case GRAPHIRE: 549 case GRAPHIRE:
550 case WACOM_MO:
520 return (wacom_graphire_irq(wacom_wac, wcombo)); 551 return (wacom_graphire_irq(wacom_wac, wcombo));
521 break; 552 break;
522 case PTU: 553 case PTU:
@@ -538,6 +569,8 @@ int wacom_wac_irq(struct wacom_wac *wacom_wac, void *wcombo)
538void wacom_init_input_dev(struct input_dev *input_dev, struct wacom_wac *wacom_wac) 569void wacom_init_input_dev(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
539{ 570{
540 switch (wacom_wac->features->type) { 571 switch (wacom_wac->features->type) {
572 case WACOM_MO:
573 input_dev_mo(input_dev, wacom_wac);
541 case WACOM_G4: 574 case WACOM_G4:
542 input_dev_g4(input_dev, wacom_wac); 575 input_dev_g4(input_dev, wacom_wac);
543 /* fall through */ 576 /* fall through */
@@ -579,6 +612,7 @@ static struct wacom_features wacom_features[] = {
579 { "Wacom Volito2 4x5", 8, 5104, 3712, 511, 63, GRAPHIRE }, 612 { "Wacom Volito2 4x5", 8, 5104, 3712, 511, 63, GRAPHIRE },
580 { "Wacom Volito2 2x3", 8, 3248, 2320, 511, 63, GRAPHIRE }, 613 { "Wacom Volito2 2x3", 8, 3248, 2320, 511, 63, GRAPHIRE },
581 { "Wacom PenPartner2", 8, 3250, 2320, 255, 63, GRAPHIRE }, 614 { "Wacom PenPartner2", 8, 3250, 2320, 255, 63, GRAPHIRE },
615 { "Wacom Bamboo", 9, 14760, 9225, 511, 63, WACOM_MO },
582 { "Wacom Intuos 4x5", 10, 12700, 10600, 1023, 31, INTUOS }, 616 { "Wacom Intuos 4x5", 10, 12700, 10600, 1023, 31, INTUOS },
583 { "Wacom Intuos 6x8", 10, 20320, 16240, 1023, 31, INTUOS }, 617 { "Wacom Intuos 6x8", 10, 20320, 16240, 1023, 31, INTUOS },
584 { "Wacom Intuos 9x12", 10, 30480, 24060, 1023, 31, INTUOS }, 618 { "Wacom Intuos 9x12", 10, 30480, 24060, 1023, 31, INTUOS },
@@ -627,6 +661,7 @@ static struct usb_device_id wacom_ids[] = {
627 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x62) }, 661 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x62) },
628 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x63) }, 662 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x63) },
629 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x64) }, 663 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x64) },
664 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x65) },
630 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x20) }, 665 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x20) },
631 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x21) }, 666 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x21) },
632 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x22) }, 667 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x22) },
diff --git a/drivers/input/tablet/wacom_wac.h b/drivers/input/tablet/wacom_wac.h
index a5e12e8756de..a302e229bb8a 100644
--- a/drivers/input/tablet/wacom_wac.h
+++ b/drivers/input/tablet/wacom_wac.h
@@ -25,6 +25,7 @@ enum {
25 INTUOS3, 25 INTUOS3,
26 INTUOS3L, 26 INTUOS3L,
27 CINTIQ, 27 CINTIQ,
28 WACOM_MO,
28 MAX_TYPE 29 MAX_TYPE
29}; 30};
30 31
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index e5cca9bd0406..69371779806a 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -177,6 +177,7 @@ config TOUCHSCREEN_USB_COMPOSITE
177 - some other eTurboTouch 177 - some other eTurboTouch
178 - Gunze AHL61 178 - Gunze AHL61
179 - DMC TSC-10/25 179 - DMC TSC-10/25
180 - IRTOUCHSYSTEMS/UNITOP
180 181
181 Have a look at <http://linux.chapter7.ch/touchkit/> for 182 Have a look at <http://linux.chapter7.ch/touchkit/> for
182 a usage description and the required user-space stuff. 183 a usage description and the required user-space stuff.
@@ -219,4 +220,9 @@ config TOUCHSCREEN_USB_DMC_TSC10
219 bool "DMC TSC-10/25 device support" if EMBEDDED 220 bool "DMC TSC-10/25 device support" if EMBEDDED
220 depends on TOUCHSCREEN_USB_COMPOSITE 221 depends on TOUCHSCREEN_USB_COMPOSITE
221 222
223config TOUCHSCREEN_USB_IRTOUCH
224 default y
225 bool "IRTOUCHSYSTEMS/UNITOP device support" if EMBEDDED
226 depends on TOUCHSCREEN_USB_COMPOSITE
227
222endif 228endif
diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c
index e3f22852bd09..b407028ffc59 100644
--- a/drivers/input/touchscreen/usbtouchscreen.c
+++ b/drivers/input/touchscreen/usbtouchscreen.c
@@ -9,6 +9,7 @@
9 * - eTurboTouch 9 * - eTurboTouch
10 * - Gunze AHL61 10 * - Gunze AHL61
11 * - DMC TSC-10/25 11 * - DMC TSC-10/25
12 * - IRTOUCHSYSTEMS/UNITOP
12 * 13 *
13 * Copyright (C) 2004-2006 by Daniel Ritz <daniel.ritz@gmx.ch> 14 * Copyright (C) 2004-2006 by Daniel Ritz <daniel.ritz@gmx.ch>
14 * Copyright (C) by Todd E. Johnson (mtouchusb.c) 15 * Copyright (C) by Todd E. Johnson (mtouchusb.c)
@@ -110,6 +111,7 @@ enum {
110 DEVTYPE_ETURBO, 111 DEVTYPE_ETURBO,
111 DEVTYPE_GUNZE, 112 DEVTYPE_GUNZE,
112 DEVTYPE_DMC_TSC10, 113 DEVTYPE_DMC_TSC10,
114 DEVTYPE_IRTOUCH,
113}; 115};
114 116
115static struct usb_device_id usbtouch_devices[] = { 117static struct usb_device_id usbtouch_devices[] = {
@@ -150,6 +152,11 @@ static struct usb_device_id usbtouch_devices[] = {
150 {USB_DEVICE(0x0afa, 0x03e8), .driver_info = DEVTYPE_DMC_TSC10}, 152 {USB_DEVICE(0x0afa, 0x03e8), .driver_info = DEVTYPE_DMC_TSC10},
151#endif 153#endif
152 154
155#ifdef CONFIG_TOUCHSCREEN_USB_IRTOUCH
156 {USB_DEVICE(0x595a, 0x0001), .driver_info = DEVTYPE_IRTOUCH},
157 {USB_DEVICE(0x6615, 0x0001), .driver_info = DEVTYPE_IRTOUCH},
158#endif
159
153 {} 160 {}
154}; 161};
155 162
@@ -416,6 +423,21 @@ static int dmc_tsc10_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
416 423
417 424
418/***************************************************************************** 425/*****************************************************************************
426 * IRTOUCH Part
427 */
428#ifdef CONFIG_TOUCHSCREEN_USB_IRTOUCH
429static int irtouch_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
430{
431 dev->x = (pkt[3] << 8) | pkt[2];
432 dev->y = (pkt[5] << 8) | pkt[4];
433 dev->touch = (pkt[1] & 0x03) ? 1 : 0;
434
435 return 1;
436}
437#endif
438
439
440/*****************************************************************************
419 * the different device descriptors 441 * the different device descriptors
420 */ 442 */
421static struct usbtouch_device_info usbtouch_dev_info[] = { 443static struct usbtouch_device_info usbtouch_dev_info[] = {
@@ -504,6 +526,17 @@ static struct usbtouch_device_info usbtouch_dev_info[] = {
504 .read_data = dmc_tsc10_read_data, 526 .read_data = dmc_tsc10_read_data,
505 }, 527 },
506#endif 528#endif
529
530#ifdef CONFIG_TOUCHSCREEN_USB_IRTOUCH
531 [DEVTYPE_IRTOUCH] = {
532 .min_xc = 0x0,
533 .max_xc = 0x0fff,
534 .min_yc = 0x0,
535 .max_yc = 0x0fff,
536 .rept_size = 8,
537 .read_data = irtouch_read_data,
538 },
539#endif
507}; 540};
508 541
509 542
diff --git a/drivers/input/tsdev.c b/drivers/input/tsdev.c
index 2db364898e15..d2f882e98e5e 100644
--- a/drivers/input/tsdev.c
+++ b/drivers/input/tsdev.c
@@ -109,9 +109,11 @@ struct tsdev {
109 int open; 109 int open;
110 int minor; 110 int minor;
111 char name[8]; 111 char name[8];
112 struct input_handle handle;
112 wait_queue_head_t wait; 113 wait_queue_head_t wait;
113 struct list_head client_list; 114 struct list_head client_list;
114 struct input_handle handle; 115 struct device dev;
116
115 int x, y, pressure; 117 int x, y, pressure;
116 struct ts_calibration cal; 118 struct ts_calibration cal;
117}; 119};
@@ -163,9 +165,13 @@ static int tsdev_open(struct inode *inode, struct file *file)
163 if (!tsdev || !tsdev->exist) 165 if (!tsdev || !tsdev->exist)
164 return -ENODEV; 166 return -ENODEV;
165 167
168 get_device(&tsdev->dev);
169
166 client = kzalloc(sizeof(struct tsdev_client), GFP_KERNEL); 170 client = kzalloc(sizeof(struct tsdev_client), GFP_KERNEL);
167 if (!client) 171 if (!client) {
168 return -ENOMEM; 172 error = -ENOMEM;
173 goto err_put_tsdev;
174 }
169 175
170 client->tsdev = tsdev; 176 client->tsdev = tsdev;
171 client->raw = (i >= TSDEV_MINORS / 2) ? 1 : 0; 177 client->raw = (i >= TSDEV_MINORS / 2) ? 1 : 0;
@@ -173,19 +179,25 @@ static int tsdev_open(struct inode *inode, struct file *file)
173 179
174 if (!tsdev->open++ && tsdev->exist) { 180 if (!tsdev->open++ && tsdev->exist) {
175 error = input_open_device(&tsdev->handle); 181 error = input_open_device(&tsdev->handle);
176 if (error) { 182 if (error)
177 list_del(&client->node); 183 goto err_free_client;
178 kfree(client);
179 return error;
180 }
181 } 184 }
182 185
183 file->private_data = client; 186 file->private_data = client;
184 return 0; 187 return 0;
188
189 err_free_client:
190 list_del(&client->node);
191 kfree(client);
192 err_put_tsdev:
193 put_device(&tsdev->dev);
194 return error;
185} 195}
186 196
187static void tsdev_free(struct tsdev *tsdev) 197static void tsdev_free(struct device *dev)
188{ 198{
199 struct tsdev *tsdev = container_of(dev, struct tsdev, dev);
200
189 tsdev_table[tsdev->minor] = NULL; 201 tsdev_table[tsdev->minor] = NULL;
190 kfree(tsdev); 202 kfree(tsdev);
191} 203}
@@ -200,12 +212,10 @@ static int tsdev_release(struct inode *inode, struct file *file)
200 list_del(&client->node); 212 list_del(&client->node);
201 kfree(client); 213 kfree(client);
202 214
203 if (!--tsdev->open) { 215 if (!--tsdev->open && tsdev->exist)
204 if (tsdev->exist) 216 input_close_device(&tsdev->handle);
205 input_close_device(&tsdev->handle); 217
206 else 218 put_device(&tsdev->dev);
207 tsdev_free(tsdev);
208 }
209 219
210 return 0; 220 return 0;
211} 221}
@@ -361,7 +371,7 @@ static void tsdev_event(struct input_handle *handle, unsigned int type,
361 int x, y, tmp; 371 int x, y, tmp;
362 372
363 do_gettimeofday(&time); 373 do_gettimeofday(&time);
364 client->event[client->head].millisecs = time.tv_usec / 100; 374 client->event[client->head].millisecs = time.tv_usec / 1000;
365 client->event[client->head].pressure = tsdev->pressure; 375 client->event[client->head].pressure = tsdev->pressure;
366 376
367 x = tsdev->x; 377 x = tsdev->x;
@@ -388,8 +398,6 @@ static int tsdev_connect(struct input_handler *handler, struct input_dev *dev,
388 const struct input_device_id *id) 398 const struct input_device_id *id)
389{ 399{
390 struct tsdev *tsdev; 400 struct tsdev *tsdev;
391 struct class_device *cdev;
392 dev_t devt;
393 int minor, delta; 401 int minor, delta;
394 int error; 402 int error;
395 403
@@ -407,14 +415,13 @@ static int tsdev_connect(struct input_handler *handler, struct input_dev *dev,
407 INIT_LIST_HEAD(&tsdev->client_list); 415 INIT_LIST_HEAD(&tsdev->client_list);
408 init_waitqueue_head(&tsdev->wait); 416 init_waitqueue_head(&tsdev->wait);
409 417
410 sprintf(tsdev->name, "ts%d", minor);
411
412 tsdev->exist = 1; 418 tsdev->exist = 1;
413 tsdev->minor = minor; 419 tsdev->minor = minor;
414 tsdev->handle.dev = dev; 420 tsdev->handle.dev = dev;
415 tsdev->handle.name = tsdev->name; 421 tsdev->handle.name = tsdev->name;
416 tsdev->handle.handler = handler; 422 tsdev->handle.handler = handler;
417 tsdev->handle.private = tsdev; 423 tsdev->handle.private = tsdev;
424 snprintf(tsdev->name, sizeof(tsdev->name), "ts%d", minor);
418 425
419 /* Precompute the rough calibration matrix */ 426 /* Precompute the rough calibration matrix */
420 delta = dev->absmax [ABS_X] - dev->absmin [ABS_X] + 1; 427 delta = dev->absmax [ABS_X] - dev->absmin [ABS_X] + 1;
@@ -429,36 +436,30 @@ static int tsdev_connect(struct input_handler *handler, struct input_dev *dev,
429 tsdev->cal.yscale = (yres << 8) / delta; 436 tsdev->cal.yscale = (yres << 8) / delta;
430 tsdev->cal.ytrans = - ((dev->absmin [ABS_Y] * tsdev->cal.yscale) >> 8); 437 tsdev->cal.ytrans = - ((dev->absmin [ABS_Y] * tsdev->cal.yscale) >> 8);
431 438
432 tsdev_table[minor] = tsdev; 439 snprintf(tsdev->dev.bus_id, sizeof(tsdev->dev.bus_id),
433 440 "ts%d", minor);
434 devt = MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + minor), 441 tsdev->dev.class = &input_class;
442 tsdev->dev.parent = &dev->dev;
443 tsdev->dev.devt = MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + minor);
444 tsdev->dev.release = tsdev_free;
445 device_initialize(&tsdev->dev);
435 446
436 cdev = class_device_create(&input_class, &dev->cdev, devt, 447 tsdev_table[minor] = tsdev;
437 dev->cdev.dev, tsdev->name);
438 if (IS_ERR(cdev)) {
439 error = PTR_ERR(cdev);
440 goto err_free_tsdev;
441 }
442 448
443 /* temporary symlink to keep userspace happy */ 449 error = device_add(&tsdev->dev);
444 error = sysfs_create_link(&input_class.subsys.kobj,
445 &cdev->kobj, tsdev->name);
446 if (error) 450 if (error)
447 goto err_cdev_destroy; 451 goto err_free_tsdev;
448 452
449 error = input_register_handle(&tsdev->handle); 453 error = input_register_handle(&tsdev->handle);
450 if (error) 454 if (error)
451 goto err_remove_link; 455 goto err_delete_tsdev;
452 456
453 return 0; 457 return 0;
454 458
455 err_remove_link: 459 err_delete_tsdev:
456 sysfs_remove_link(&input_class.subsys.kobj, tsdev->name); 460 device_del(&tsdev->dev);
457 err_cdev_destroy:
458 class_device_destroy(&input_class, devt);
459 err_free_tsdev: 461 err_free_tsdev:
460 tsdev_table[minor] = NULL; 462 put_device(&tsdev->dev);
461 kfree(tsdev);
462 return error; 463 return error;
463} 464}
464 465
@@ -468,10 +469,8 @@ static void tsdev_disconnect(struct input_handle *handle)
468 struct tsdev_client *client; 469 struct tsdev_client *client;
469 470
470 input_unregister_handle(handle); 471 input_unregister_handle(handle);
472 device_del(&tsdev->dev);
471 473
472 sysfs_remove_link(&input_class.subsys.kobj, tsdev->name);
473 class_device_destroy(&input_class,
474 MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + tsdev->minor));
475 tsdev->exist = 0; 474 tsdev->exist = 0;
476 475
477 if (tsdev->open) { 476 if (tsdev->open) {
@@ -479,8 +478,9 @@ static void tsdev_disconnect(struct input_handle *handle)
479 list_for_each_entry(client, &tsdev->client_list, node) 478 list_for_each_entry(client, &tsdev->client_list, node)
480 kill_fasync(&client->fasync, SIGIO, POLL_HUP); 479 kill_fasync(&client->fasync, SIGIO, POLL_HUP);
481 wake_up_interruptible(&tsdev->wait); 480 wake_up_interruptible(&tsdev->wait);
482 } else 481 }
483 tsdev_free(tsdev); 482
483 put_device(&tsdev->dev);
484} 484}
485 485
486static const struct input_device_id tsdev_ids[] = { 486static const struct input_device_id tsdev_ids[] = {
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 616eee9c04f1..bd601efa7bd1 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -34,6 +34,11 @@ config PHANTOM
34 If you choose to build module, its name will be phantom. If unsure, 34 If you choose to build module, its name will be phantom. If unsure,
35 say N here. 35 say N here.
36 36
37config EEPROM_93CX6
38 tristate "EEPROM 93CX6 support"
39 ---help---
40 This is a driver for the EEPROM chipsets 93c46 and 93c66.
41 The driver supports both read as well as write commands.
37 42
38 If unsure, say N. 43 If unsure, say N.
39 44
@@ -187,5 +192,4 @@ config THINKPAD_ACPI_BAY
187 192
188 If you are not sure, say Y here. 193 If you are not sure, say Y here.
189 194
190
191endmenu 195endmenu
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 8abbf2f07a65..b5ce0e3dba86 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -14,3 +14,4 @@ obj-$(CONFIG_PHANTOM) += phantom.o
14obj-$(CONFIG_SGI_IOC4) += ioc4.o 14obj-$(CONFIG_SGI_IOC4) += ioc4.o
15obj-$(CONFIG_SONY_LAPTOP) += sony-laptop.o 15obj-$(CONFIG_SONY_LAPTOP) += sony-laptop.o
16obj-$(CONFIG_THINKPAD_ACPI) += thinkpad_acpi.o 16obj-$(CONFIG_THINKPAD_ACPI) += thinkpad_acpi.o
17obj-$(CONFIG_EEPROM_93CX6) += eeprom_93cx6.o
diff --git a/drivers/misc/eeprom_93cx6.c b/drivers/misc/eeprom_93cx6.c
new file mode 100644
index 000000000000..ea55654e5948
--- /dev/null
+++ b/drivers/misc/eeprom_93cx6.c
@@ -0,0 +1,241 @@
1/*
2 Copyright (C) 2004 - 2006 rt2x00 SourceForge Project
3 <http://rt2x00.serialmonkey.com>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the
17 Free Software Foundation, Inc.,
18 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20
21/*
22 Module: eeprom_93cx6
23 Abstract: EEPROM reader routines for 93cx6 chipsets.
24 Supported chipsets: 93c46 & 93c66.
25 */
26
27#include <linux/kernel.h>
28#include <linux/module.h>
29#include <linux/version.h>
30#include <linux/delay.h>
31#include <linux/eeprom_93cx6.h>
32
33MODULE_AUTHOR("http://rt2x00.serialmonkey.com");
34MODULE_VERSION("1.0");
35MODULE_DESCRIPTION("EEPROM 93cx6 chip driver");
36MODULE_LICENSE("GPL");
37
38static inline void eeprom_93cx6_pulse_high(struct eeprom_93cx6 *eeprom)
39{
40 eeprom->reg_data_clock = 1;
41 eeprom->register_write(eeprom);
42
43 /*
44 * Add a short delay for the pulse to work.
45 * According to the specifications the "maximum minimum"
46 * time should be 450ns.
47 */
48 ndelay(450);
49}
50
51static inline void eeprom_93cx6_pulse_low(struct eeprom_93cx6 *eeprom)
52{
53 eeprom->reg_data_clock = 0;
54 eeprom->register_write(eeprom);
55
56 /*
57 * Add a short delay for the pulse to work.
58 * According to the specifications the "maximum minimum"
59 * time should be 450ns.
60 */
61 ndelay(450);
62}
63
64static void eeprom_93cx6_startup(struct eeprom_93cx6 *eeprom)
65{
66 /*
67 * Clear all flags, and enable chip select.
68 */
69 eeprom->register_read(eeprom);
70 eeprom->reg_data_in = 0;
71 eeprom->reg_data_out = 0;
72 eeprom->reg_data_clock = 0;
73 eeprom->reg_chip_select = 1;
74 eeprom->register_write(eeprom);
75
76 /*
77 * kick a pulse.
78 */
79 eeprom_93cx6_pulse_high(eeprom);
80 eeprom_93cx6_pulse_low(eeprom);
81}
82
83static void eeprom_93cx6_cleanup(struct eeprom_93cx6 *eeprom)
84{
85 /*
86 * Clear chip_select and data_in flags.
87 */
88 eeprom->register_read(eeprom);
89 eeprom->reg_data_in = 0;
90 eeprom->reg_chip_select = 0;
91 eeprom->register_write(eeprom);
92
93 /*
94 * kick a pulse.
95 */
96 eeprom_93cx6_pulse_high(eeprom);
97 eeprom_93cx6_pulse_low(eeprom);
98}
99
100static void eeprom_93cx6_write_bits(struct eeprom_93cx6 *eeprom,
101 const u16 data, const u16 count)
102{
103 unsigned int i;
104
105 eeprom->register_read(eeprom);
106
107 /*
108 * Clear data flags.
109 */
110 eeprom->reg_data_in = 0;
111 eeprom->reg_data_out = 0;
112
113 /*
114 * Start writing all bits.
115 */
116 for (i = count; i > 0; i--) {
117 /*
118 * Check if this bit needs to be set.
119 */
120 eeprom->reg_data_in = !!(data & (1 << (i - 1)));
121
122 /*
123 * Write the bit to the eeprom register.
124 */
125 eeprom->register_write(eeprom);
126
127 /*
128 * Kick a pulse.
129 */
130 eeprom_93cx6_pulse_high(eeprom);
131 eeprom_93cx6_pulse_low(eeprom);
132 }
133
134 eeprom->reg_data_in = 0;
135 eeprom->register_write(eeprom);
136}
137
138static void eeprom_93cx6_read_bits(struct eeprom_93cx6 *eeprom,
139 u16 *data, const u16 count)
140{
141 unsigned int i;
142 u16 buf = 0;
143
144 eeprom->register_read(eeprom);
145
146 /*
147 * Clear data flags.
148 */
149 eeprom->reg_data_in = 0;
150 eeprom->reg_data_out = 0;
151
152 /*
153 * Start reading all bits.
154 */
155 for (i = count; i > 0; i--) {
156 eeprom_93cx6_pulse_high(eeprom);
157
158 eeprom->register_read(eeprom);
159
160 /*
161 * Clear data_in flag.
162 */
163 eeprom->reg_data_in = 0;
164
165 /*
166 * Read if the bit has been set.
167 */
168 if (eeprom->reg_data_out)
169 buf |= (1 << (i - 1));
170
171 eeprom_93cx6_pulse_low(eeprom);
172 }
173
174 *data = buf;
175}
176
177/**
178 * eeprom_93cx6_read - Read multiple words from eeprom
179 * @eeprom: Pointer to eeprom structure
180 * @word: Word index from where we should start reading
181 * @data: target pointer where the information will have to be stored
182 *
183 * This function will read the eeprom data as host-endian word
184 * into the given data pointer.
185 */
186void eeprom_93cx6_read(struct eeprom_93cx6 *eeprom, const u8 word,
187 u16 *data)
188{
189 u16 command;
190
191 /*
192 * Initialize the eeprom register
193 */
194 eeprom_93cx6_startup(eeprom);
195
196 /*
197 * Select the read opcode and the word to be read.
198 */
199 command = (PCI_EEPROM_READ_OPCODE << eeprom->width) | word;
200 eeprom_93cx6_write_bits(eeprom, command,
201 PCI_EEPROM_WIDTH_OPCODE + eeprom->width);
202
203 /*
204 * Read the requested 16 bits.
205 */
206 eeprom_93cx6_read_bits(eeprom, data, 16);
207
208 /*
209 * Cleanup eeprom register.
210 */
211 eeprom_93cx6_cleanup(eeprom);
212}
213EXPORT_SYMBOL_GPL(eeprom_93cx6_read);
214
215/**
216 * eeprom_93cx6_multiread - Read multiple words from eeprom
217 * @eeprom: Pointer to eeprom structure
218 * @word: Word index from where we should start reading
219 * @data: target pointer where the information will have to be stored
220 * @words: Number of words that should be read.
221 *
222 * This function will read all requested words from the eeprom,
223 * this is done by calling eeprom_93cx6_read() multiple times.
224 * But with the additional change that while the eeprom_93cx6_read
225 * will return host ordered bytes, this method will return little
226 * endian words.
227 */
228void eeprom_93cx6_multiread(struct eeprom_93cx6 *eeprom, const u8 word,
229 __le16 *data, const u16 words)
230{
231 unsigned int i;
232 u16 tmp;
233
234 for (i = 0; i < words; i++) {
235 tmp = 0;
236 eeprom_93cx6_read(eeprom, word + i, &tmp);
237 data[i] = cpu_to_le16(tmp);
238 }
239}
240EXPORT_SYMBOL_GPL(eeprom_93cx6_multiread);
241
diff --git a/drivers/mtd/devices/docprobe.c b/drivers/mtd/devices/docprobe.c
index 78872c3f3760..b96ac8e119dc 100644
--- a/drivers/mtd/devices/docprobe.c
+++ b/drivers/mtd/devices/docprobe.c
@@ -84,7 +84,7 @@ static unsigned long __initdata doc_locations[] = {
84#elif defined(CONFIG_MOMENCO_OCELOT) 84#elif defined(CONFIG_MOMENCO_OCELOT)
85 0x2f000000, 85 0x2f000000,
86 0xff000000, 86 0xff000000,
87#elif defined(CONFIG_MOMENCO_OCELOT_G) || defined (CONFIG_MOMENCO_OCELOT_C) 87#elif defined(CONFIG_MOMENCO_OCELOT_G)
88 0xff000000, 88 0xff000000,
89##else 89##else
90#warning Unknown architecture for DiskOnChip. No default probe locations defined 90#warning Unknown architecture for DiskOnChip. No default probe locations defined
diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig
index b665e4ac2208..f88ebc5b685e 100644
--- a/drivers/mtd/maps/Kconfig
+++ b/drivers/mtd/maps/Kconfig
@@ -258,12 +258,6 @@ config MTD_TSUNAMI
258 help 258 help
259 Support for the flash chip on Tsunami TIG bus. 259 Support for the flash chip on Tsunami TIG bus.
260 260
261config MTD_LASAT
262 tristate "LASAT flash device"
263 depends on LASAT && MTD_CFI
264 help
265 Support for the flash chips on the Lasat 100 and 200 boards.
266
267config MTD_NETtel 261config MTD_NETtel
268 tristate "CFI flash device on SnapGear/SecureEdge" 262 tristate "CFI flash device on SnapGear/SecureEdge"
269 depends on X86 && MTD_PARTITIONS && MTD_JEDECPROBE 263 depends on X86 && MTD_PARTITIONS && MTD_JEDECPROBE
diff --git a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile
index 3acbb5d01ca4..970b189271a2 100644
--- a/drivers/mtd/maps/Makefile
+++ b/drivers/mtd/maps/Makefile
@@ -47,7 +47,6 @@ obj-$(CONFIG_MTD_OCELOT) += ocelot.o
47obj-$(CONFIG_MTD_SOLUTIONENGINE)+= solutionengine.o 47obj-$(CONFIG_MTD_SOLUTIONENGINE)+= solutionengine.o
48obj-$(CONFIG_MTD_PCI) += pci.o 48obj-$(CONFIG_MTD_PCI) += pci.o
49obj-$(CONFIG_MTD_ALCHEMY) += alchemy-flash.o 49obj-$(CONFIG_MTD_ALCHEMY) += alchemy-flash.o
50obj-$(CONFIG_MTD_LASAT) += lasat.o
51obj-$(CONFIG_MTD_AUTCPU12) += autcpu12-nvram.o 50obj-$(CONFIG_MTD_AUTCPU12) += autcpu12-nvram.o
52obj-$(CONFIG_MTD_EDB7312) += edb7312.o 51obj-$(CONFIG_MTD_EDB7312) += edb7312.o
53obj-$(CONFIG_MTD_IMPA7) += impa7.o 52obj-$(CONFIG_MTD_IMPA7) += impa7.o
diff --git a/drivers/mtd/maps/lasat.c b/drivers/mtd/maps/lasat.c
deleted file mode 100644
index e34376321050..000000000000
--- a/drivers/mtd/maps/lasat.c
+++ /dev/null
@@ -1,103 +0,0 @@
1/*
2 * Flash device on Lasat 100 and 200 boards
3 *
4 * (C) 2002 Brian Murphy <brian@murphy.dk>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License version
8 * 2 as published by the Free Software Foundation.
9 *
10 * $Id: lasat.c,v 1.9 2004/11/04 13:24:15 gleixner Exp $
11 *
12 */
13
14#include <linux/module.h>
15#include <linux/types.h>
16#include <linux/kernel.h>
17#include <linux/init.h>
18#include <asm/io.h>
19#include <linux/mtd/mtd.h>
20#include <linux/mtd/map.h>
21#include <linux/mtd/partitions.h>
22#include <asm/lasat/lasat.h>
23
24static struct mtd_info *lasat_mtd;
25
26static struct mtd_partition partition_info[LASAT_MTD_LAST];
27static char *lasat_mtd_partnames[] = {"Bootloader", "Service", "Normal", "Filesystem", "Config"};
28
29static void lasat_set_vpp(struct map_info *map, int vpp)
30{
31 if (vpp)
32 *lasat_misc->flash_wp_reg |= 1 << lasat_misc->flash_wp_bit;
33 else
34 *lasat_misc->flash_wp_reg &= ~(1 << lasat_misc->flash_wp_bit);
35}
36
37static struct map_info lasat_map = {
38 .name = "LASAT flash",
39 .bankwidth = 4,
40 .set_vpp = lasat_set_vpp
41};
42
43static int __init init_lasat(void)
44{
45 int i;
46 /* since we use AMD chips and set_vpp is not implimented
47 * for these (yet) we still have to permanently enable flash write */
48 printk(KERN_NOTICE "Unprotecting flash\n");
49 ENABLE_VPP((&lasat_map));
50
51 lasat_map.phys = lasat_flash_partition_start(LASAT_MTD_BOOTLOADER);
52 lasat_map.virt = ioremap_nocache(
53 lasat_map.phys, lasat_board_info.li_flash_size);
54 lasat_map.size = lasat_board_info.li_flash_size;
55
56 simple_map_init(&lasat_map);
57
58 for (i=0; i < LASAT_MTD_LAST; i++)
59 partition_info[i].name = lasat_mtd_partnames[i];
60
61 lasat_mtd = do_map_probe("cfi_probe", &lasat_map);
62
63 if (!lasat_mtd)
64 lasat_mtd = do_map_probe("jedec_probe", &lasat_map);
65
66 if (lasat_mtd) {
67 u32 size, offset = 0;
68
69 lasat_mtd->owner = THIS_MODULE;
70
71 for (i=0; i < LASAT_MTD_LAST; i++) {
72 size = lasat_flash_partition_size(i);
73 partition_info[i].size = size;
74 partition_info[i].offset = offset;
75 offset += size;
76 }
77
78 add_mtd_partitions( lasat_mtd, partition_info, LASAT_MTD_LAST );
79 return 0;
80 }
81
82 iounmap(lasat_map.virt);
83 return -ENXIO;
84}
85
86static void __exit cleanup_lasat(void)
87{
88 if (lasat_mtd) {
89 del_mtd_partitions(lasat_mtd);
90 map_destroy(lasat_mtd);
91 }
92 if (lasat_map.virt) {
93 iounmap(lasat_map.virt);
94 lasat_map.virt = 0;
95 }
96}
97
98module_init(init_lasat);
99module_exit(cleanup_lasat);
100
101MODULE_LICENSE("GPL");
102MODULE_AUTHOR("Brian Murphy <brian@murphy.dk>");
103MODULE_DESCRIPTION("Lasat Safepipe/Masquerade MTD map driver");
diff --git a/drivers/mtd/nand/diskonchip.c b/drivers/mtd/nand/diskonchip.c
index 595208f965a5..17c868034aad 100644
--- a/drivers/mtd/nand/diskonchip.c
+++ b/drivers/mtd/nand/diskonchip.c
@@ -59,7 +59,7 @@ static unsigned long __initdata doc_locations[] = {
59#elif defined(CONFIG_MOMENCO_OCELOT) 59#elif defined(CONFIG_MOMENCO_OCELOT)
60 0x2f000000, 60 0x2f000000,
61 0xff000000, 61 0xff000000,
62#elif defined(CONFIG_MOMENCO_OCELOT_G) || defined (CONFIG_MOMENCO_OCELOT_C) 62#elif defined(CONFIG_MOMENCO_OCELOT_G)
63 0xff000000, 63 0xff000000,
64#else 64#else
65#warning Unknown architecture for DiskOnChip. No default probe locations defined 65#warning Unknown architecture for DiskOnChip. No default probe locations defined
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c
index f26ca331615e..6deb20fc7a08 100644
--- a/drivers/net/3c59x.c
+++ b/drivers/net/3c59x.c
@@ -324,7 +324,7 @@ static struct vortex_chip_info {
324 {"3c980C Python-T", 324 {"3c980C Python-T",
325 PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM, 128, }, 325 PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM, 128, },
326 {"3cSOHO100-TX Hurricane", 326 {"3cSOHO100-TX Hurricane",
327 PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM, 128, }, 327 PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM|EXTRA_PREAMBLE, 128, },
328 {"3c555 Laptop Hurricane", 328 {"3c555 Laptop Hurricane",
329 PCI_USES_MASTER, IS_CYCLONE|EEPROM_8BIT|HAS_HWCKSM, 128, }, 329 PCI_USES_MASTER, IS_CYCLONE|EEPROM_8BIT|HAS_HWCKSM, 128, },
330 {"3c556 Laptop Tornado", 330 {"3c556 Laptop Tornado",
diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c
index a804965e6542..58bbc3e6d0de 100644
--- a/drivers/net/8139cp.c
+++ b/drivers/net/8139cp.c
@@ -107,11 +107,6 @@ MODULE_PARM_DESC (multicast_filter_limit, "8139cp: maximum number of filtered mu
107 107
108#define PFX DRV_NAME ": " 108#define PFX DRV_NAME ": "
109 109
110#ifndef TRUE
111#define FALSE 0
112#define TRUE (!FALSE)
113#endif
114
115#define CP_DEF_MSG_ENABLE (NETIF_MSG_DRV | \ 110#define CP_DEF_MSG_ENABLE (NETIF_MSG_DRV | \
116 NETIF_MSG_PROBE | \ 111 NETIF_MSG_PROBE | \
117 NETIF_MSG_LINK) 112 NETIF_MSG_LINK)
@@ -661,7 +656,7 @@ static irqreturn_t cp_interrupt (int irq, void *dev_instance)
661 if (status & (TxOK | TxErr | TxEmpty | SWInt)) 656 if (status & (TxOK | TxErr | TxEmpty | SWInt))
662 cp_tx(cp); 657 cp_tx(cp);
663 if (status & LinkChg) 658 if (status & LinkChg)
664 mii_check_media(&cp->mii_if, netif_msg_link(cp), FALSE); 659 mii_check_media(&cp->mii_if, netif_msg_link(cp), false);
665 660
666 spin_unlock(&cp->lock); 661 spin_unlock(&cp->lock);
667 662
@@ -1188,7 +1183,7 @@ static int cp_open (struct net_device *dev)
1188 goto err_out_hw; 1183 goto err_out_hw;
1189 1184
1190 netif_carrier_off(dev); 1185 netif_carrier_off(dev);
1191 mii_check_media(&cp->mii_if, netif_msg_link(cp), TRUE); 1186 mii_check_media(&cp->mii_if, netif_msg_link(cp), true);
1192 netif_start_queue(dev); 1187 netif_start_queue(dev);
1193 1188
1194 return 0; 1189 return 0;
@@ -2050,7 +2045,7 @@ static int cp_resume (struct pci_dev *pdev)
2050 2045
2051 spin_lock_irqsave (&cp->lock, flags); 2046 spin_lock_irqsave (&cp->lock, flags);
2052 2047
2053 mii_check_media(&cp->mii_if, netif_msg_link(cp), FALSE); 2048 mii_check_media(&cp->mii_if, netif_msg_link(cp), false);
2054 2049
2055 spin_unlock_irqrestore (&cp->lock, flags); 2050 spin_unlock_irqrestore (&cp->lock, flags);
2056 2051
diff --git a/drivers/net/8390.h b/drivers/net/8390.h
index 414de5bd228f..04ddec0f4c61 100644
--- a/drivers/net/8390.h
+++ b/drivers/net/8390.h
@@ -73,6 +73,9 @@ struct ei_device {
73 u32 *reg_offset; /* Register mapping table */ 73 u32 *reg_offset; /* Register mapping table */
74 spinlock_t page_lock; /* Page register locks */ 74 spinlock_t page_lock; /* Page register locks */
75 unsigned long priv; /* Private field to store bus IDs etc. */ 75 unsigned long priv; /* Private field to store bus IDs etc. */
76#ifdef AX88796_PLATFORM
77 unsigned char rxcr_base; /* default value for RXCR */
78#endif
76}; 79};
77 80
78/* The maximum number of 8390 interrupt service routines called per IRQ. */ 81/* The maximum number of 8390 interrupt service routines called per IRQ. */
@@ -86,11 +89,19 @@ struct ei_device {
86/* Some generic ethernet register configurations. */ 89/* Some generic ethernet register configurations. */
87#define E8390_TX_IRQ_MASK 0xa /* For register EN0_ISR */ 90#define E8390_TX_IRQ_MASK 0xa /* For register EN0_ISR */
88#define E8390_RX_IRQ_MASK 0x5 91#define E8390_RX_IRQ_MASK 0x5
92
93#ifdef AX88796_PLATFORM
94#define E8390_RXCONFIG (ei_status.rxcr_base | 0x04)
95#define E8390_RXOFF (ei_status.rxcr_base | 0x20)
96#else
89#define E8390_RXCONFIG 0x4 /* EN0_RXCR: broadcasts, no multicast,errors */ 97#define E8390_RXCONFIG 0x4 /* EN0_RXCR: broadcasts, no multicast,errors */
90#define E8390_RXOFF 0x20 /* EN0_RXCR: Accept no packets */ 98#define E8390_RXOFF 0x20 /* EN0_RXCR: Accept no packets */
99#endif
100
91#define E8390_TXCONFIG 0x00 /* EN0_TXCR: Normal transmit mode */ 101#define E8390_TXCONFIG 0x00 /* EN0_TXCR: Normal transmit mode */
92#define E8390_TXOFF 0x02 /* EN0_TXCR: Transmitter off */ 102#define E8390_TXOFF 0x02 /* EN0_TXCR: Transmitter off */
93 103
104
94/* Register accessed at EN_CMD, the 8390 base addr. */ 105/* Register accessed at EN_CMD, the 8390 base addr. */
95#define E8390_STOP 0x01 /* Stop and reset the chip */ 106#define E8390_STOP 0x01 /* Stop and reset the chip */
96#define E8390_START 0x02 /* Start the chip, clear reset */ 107#define E8390_START 0x02 /* Start the chip, clear reset */
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index b49375abb5f4..b941c74a06c4 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -3,10 +3,7 @@
3# Network device configuration 3# Network device configuration
4# 4#
5 5
6menu "Network device support" 6menuconfig NETDEVICES
7 depends on NET
8
9config NETDEVICES
10 default y if UML 7 default y if UML
11 bool "Network device support" 8 bool "Network device support"
12 ---help--- 9 ---help---
@@ -151,11 +148,9 @@ source "drivers/net/phy/Kconfig"
151# Ethernet 148# Ethernet
152# 149#
153 150
154menu "Ethernet (10 or 100Mbit)" 151menuconfig NET_ETHERNET
155 depends on !UML
156
157config NET_ETHERNET
158 bool "Ethernet (10 or 100Mbit)" 152 bool "Ethernet (10 or 100Mbit)"
153 depends on !UML
159 ---help--- 154 ---help---
160 Ethernet (also called IEEE 802.3 or ISO 8802-2) is the most common 155 Ethernet (also called IEEE 802.3 or ISO 8802-2) is the most common
161 type of Local Area Network (LAN) in universities and companies. 156 type of Local Area Network (LAN) in universities and companies.
@@ -180,9 +175,10 @@ config NET_ETHERNET
180 kernel: saying N will just cause the configurator to skip all 175 kernel: saying N will just cause the configurator to skip all
181 the questions about Ethernet network cards. If unsure, say N. 176 the questions about Ethernet network cards. If unsure, say N.
182 177
178if NET_ETHERNET
179
183config MII 180config MII
184 tristate "Generic Media Independent Interface device support" 181 tristate "Generic Media Independent Interface device support"
185 depends on NET_ETHERNET
186 help 182 help
187 Most ethernet controllers have MII transceiver either as an external 183 Most ethernet controllers have MII transceiver either as an external
188 or internal device. It is safe to say Y or M here even if your 184 or internal device. It is safe to say Y or M here even if your
@@ -190,7 +186,7 @@ config MII
190 186
191config MACB 187config MACB
192 tristate "Atmel MACB support" 188 tristate "Atmel MACB support"
193 depends on NET_ETHERNET && (AVR32 || ARCH_AT91SAM9260 || ARCH_AT91SAM9263) 189 depends on AVR32 || ARCH_AT91SAM9260 || ARCH_AT91SAM9263
194 select MII 190 select MII
195 help 191 help
196 The Atmel MACB ethernet interface is found on many AT32 and AT91 192 The Atmel MACB ethernet interface is found on many AT32 and AT91
@@ -201,9 +197,18 @@ config MACB
201 197
202source "drivers/net/arm/Kconfig" 198source "drivers/net/arm/Kconfig"
203 199
200config AX88796
201 tristate "ASIX AX88796 NE2000 clone support"
202 depends on ARM || MIPS
203 select CRC32
204 select MII
205 help
206 AX88796 driver, using platform bus to provide
207 chip detection and resources
208
204config MACE 209config MACE
205 tristate "MACE (Power Mac ethernet) support" 210 tristate "MACE (Power Mac ethernet) support"
206 depends on NET_ETHERNET && PPC_PMAC && PPC32 211 depends on PPC_PMAC && PPC32
207 select CRC32 212 select CRC32
208 help 213 help
209 Power Macintoshes and clones with Ethernet built-in on the 214 Power Macintoshes and clones with Ethernet built-in on the
@@ -226,7 +231,7 @@ config MACE_AAUI_PORT
226 231
227config BMAC 232config BMAC
228 tristate "BMAC (G3 ethernet) support" 233 tristate "BMAC (G3 ethernet) support"
229 depends on NET_ETHERNET && PPC_PMAC && PPC32 234 depends on PPC_PMAC && PPC32
230 select CRC32 235 select CRC32
231 help 236 help
232 Say Y for support of BMAC Ethernet interfaces. These are used on G3 237 Say Y for support of BMAC Ethernet interfaces. These are used on G3
@@ -237,7 +242,7 @@ config BMAC
237 242
238config ARIADNE 243config ARIADNE
239 tristate "Ariadne support" 244 tristate "Ariadne support"
240 depends on NET_ETHERNET && ZORRO 245 depends on ZORRO
241 help 246 help
242 If you have a Village Tronic Ariadne Ethernet adapter, say Y. 247 If you have a Village Tronic Ariadne Ethernet adapter, say Y.
243 Otherwise, say N. 248 Otherwise, say N.
@@ -247,7 +252,7 @@ config ARIADNE
247 252
248config A2065 253config A2065
249 tristate "A2065 support" 254 tristate "A2065 support"
250 depends on NET_ETHERNET && ZORRO 255 depends on ZORRO
251 select CRC32 256 select CRC32
252 help 257 help
253 If you have a Commodore A2065 Ethernet adapter, say Y. Otherwise, 258 If you have a Commodore A2065 Ethernet adapter, say Y. Otherwise,
@@ -258,7 +263,7 @@ config A2065
258 263
259config HYDRA 264config HYDRA
260 tristate "Hydra support" 265 tristate "Hydra support"
261 depends on NET_ETHERNET && ZORRO 266 depends on ZORRO
262 select CRC32 267 select CRC32
263 help 268 help
264 If you have a Hydra Ethernet adapter, say Y. Otherwise, say N. 269 If you have a Hydra Ethernet adapter, say Y. Otherwise, say N.
@@ -268,7 +273,7 @@ config HYDRA
268 273
269config ZORRO8390 274config ZORRO8390
270 tristate "Zorro NS8390-based Ethernet support" 275 tristate "Zorro NS8390-based Ethernet support"
271 depends on NET_ETHERNET && ZORRO 276 depends on ZORRO
272 select CRC32 277 select CRC32
273 help 278 help
274 This driver is for Zorro Ethernet cards using an NS8390-compatible 279 This driver is for Zorro Ethernet cards using an NS8390-compatible
@@ -281,7 +286,7 @@ config ZORRO8390
281 286
282config APNE 287config APNE
283 tristate "PCMCIA NE2000 support" 288 tristate "PCMCIA NE2000 support"
284 depends on NET_ETHERNET && AMIGA_PCMCIA 289 depends on AMIGA_PCMCIA
285 select CRC32 290 select CRC32
286 help 291 help
287 If you have a PCMCIA NE2000 compatible adapter, say Y. Otherwise, 292 If you have a PCMCIA NE2000 compatible adapter, say Y. Otherwise,
@@ -292,7 +297,7 @@ config APNE
292 297
293config APOLLO_ELPLUS 298config APOLLO_ELPLUS
294 tristate "Apollo 3c505 support" 299 tristate "Apollo 3c505 support"
295 depends on NET_ETHERNET && APOLLO 300 depends on APOLLO
296 help 301 help
297 Say Y or M here if your Apollo has a 3Com 3c505 ISA Ethernet card. 302 Say Y or M here if your Apollo has a 3Com 3c505 ISA Ethernet card.
298 If you don't have one made for Apollos, you can use one from a PC, 303 If you don't have one made for Apollos, you can use one from a PC,
@@ -301,7 +306,7 @@ config APOLLO_ELPLUS
301 306
302config MAC8390 307config MAC8390
303 bool "Macintosh NS 8390 based ethernet cards" 308 bool "Macintosh NS 8390 based ethernet cards"
304 depends on NET_ETHERNET && MAC 309 depends on MAC
305 select CRC32 310 select CRC32
306 help 311 help
307 If you want to include a driver to support Nubus or LC-PDS 312 If you want to include a driver to support Nubus or LC-PDS
@@ -311,7 +316,7 @@ config MAC8390
311 316
312config MAC89x0 317config MAC89x0
313 tristate "Macintosh CS89x0 based ethernet cards" 318 tristate "Macintosh CS89x0 based ethernet cards"
314 depends on NET_ETHERNET && MAC 319 depends on MAC
315 ---help--- 320 ---help---
316 Support for CS89x0 chipset based Ethernet cards. If you have a 321 Support for CS89x0 chipset based Ethernet cards. If you have a
317 Nubus or LC-PDS network (Ethernet) card of this type, say Y and 322 Nubus or LC-PDS network (Ethernet) card of this type, say Y and
@@ -324,7 +329,7 @@ config MAC89x0
324 329
325config MACSONIC 330config MACSONIC
326 tristate "Macintosh SONIC based ethernet (onboard, NuBus, LC, CS)" 331 tristate "Macintosh SONIC based ethernet (onboard, NuBus, LC, CS)"
327 depends on NET_ETHERNET && MAC 332 depends on MAC
328 ---help--- 333 ---help---
329 Support for NatSemi SONIC based Ethernet devices. This includes 334 Support for NatSemi SONIC based Ethernet devices. This includes
330 the onboard Ethernet in many Quadras as well as some LC-PDS, 335 the onboard Ethernet in many Quadras as well as some LC-PDS,
@@ -338,7 +343,7 @@ config MACSONIC
338 343
339config MACMACE 344config MACMACE
340 bool "Macintosh (AV) onboard MACE ethernet" 345 bool "Macintosh (AV) onboard MACE ethernet"
341 depends on NET_ETHERNET && MAC 346 depends on MAC
342 select CRC32 347 select CRC32
343 help 348 help
344 Support for the onboard AMD 79C940 MACE Ethernet controller used in 349 Support for the onboard AMD 79C940 MACE Ethernet controller used in
@@ -348,7 +353,7 @@ config MACMACE
348 353
349config MVME147_NET 354config MVME147_NET
350 tristate "MVME147 (Lance) Ethernet support" 355 tristate "MVME147 (Lance) Ethernet support"
351 depends on NET_ETHERNET && MVME147 356 depends on MVME147
352 select CRC32 357 select CRC32
353 help 358 help
354 Support for the on-board Ethernet interface on the Motorola MVME147 359 Support for the on-board Ethernet interface on the Motorola MVME147
@@ -358,7 +363,7 @@ config MVME147_NET
358 363
359config MVME16x_NET 364config MVME16x_NET
360 tristate "MVME16x Ethernet support" 365 tristate "MVME16x Ethernet support"
361 depends on NET_ETHERNET && MVME16x 366 depends on MVME16x
362 help 367 help
363 This is the driver for the Ethernet interface on the Motorola 368 This is the driver for the Ethernet interface on the Motorola
364 MVME162, 166, 167, 172 and 177 boards. Say Y here to include the 369 MVME162, 166, 167, 172 and 177 boards. Say Y here to include the
@@ -367,7 +372,7 @@ config MVME16x_NET
367 372
368config BVME6000_NET 373config BVME6000_NET
369 tristate "BVME6000 Ethernet support" 374 tristate "BVME6000 Ethernet support"
370 depends on NET_ETHERNET && BVME6000 375 depends on BVME6000
371 help 376 help
372 This is the driver for the Ethernet interface on BVME4000 and 377 This is the driver for the Ethernet interface on BVME4000 and
373 BVME6000 VME boards. Say Y here to include the driver for this chip 378 BVME6000 VME boards. Say Y here to include the driver for this chip
@@ -376,7 +381,7 @@ config BVME6000_NET
376 381
377config ATARILANCE 382config ATARILANCE
378 tristate "Atari Lance support" 383 tristate "Atari Lance support"
379 depends on NET_ETHERNET && ATARI 384 depends on ATARI
380 help 385 help
381 Say Y to include support for several Atari Ethernet adapters based 386 Say Y to include support for several Atari Ethernet adapters based
382 on the AMD Lance chipset: RieblCard (with or without battery), or 387 on the AMD Lance chipset: RieblCard (with or without battery), or
@@ -384,7 +389,7 @@ config ATARILANCE
384 389
385config ATARI_BIONET 390config ATARI_BIONET
386 tristate "BioNet-100 support" 391 tristate "BioNet-100 support"
387 depends on NET_ETHERNET && ATARI && ATARI_ACSI && BROKEN 392 depends on ATARI && ATARI_ACSI && BROKEN
388 help 393 help
389 Say Y to include support for BioData's BioNet-100 Ethernet adapter 394 Say Y to include support for BioData's BioNet-100 Ethernet adapter
390 for the ACSI port. The driver works (has to work...) with a polled 395 for the ACSI port. The driver works (has to work...) with a polled
@@ -392,7 +397,7 @@ config ATARI_BIONET
392 397
393config ATARI_PAMSNET 398config ATARI_PAMSNET
394 tristate "PAMsNet support" 399 tristate "PAMsNet support"
395 depends on NET_ETHERNET && ATARI && ATARI_ACSI && BROKEN 400 depends on ATARI && ATARI_ACSI && BROKEN
396 help 401 help
397 Say Y to include support for the PAMsNet Ethernet adapter for the 402 Say Y to include support for the PAMsNet Ethernet adapter for the
398 ACSI port ("ACSI node"). The driver works (has to work...) with a 403 ACSI port ("ACSI node"). The driver works (has to work...) with a
@@ -400,7 +405,7 @@ config ATARI_PAMSNET
400 405
401config SUN3LANCE 406config SUN3LANCE
402 tristate "Sun3/Sun3x on-board LANCE support" 407 tristate "Sun3/Sun3x on-board LANCE support"
403 depends on NET_ETHERNET && (SUN3 || SUN3X) 408 depends on SUN3 || SUN3X
404 help 409 help
405 Most Sun3 and Sun3x motherboards (including the 3/50, 3/60 and 3/80) 410 Most Sun3 and Sun3x motherboards (including the 3/50, 3/60 and 3/80)
406 featured an AMD Lance 10Mbit Ethernet controller on board; say Y 411 featured an AMD Lance 10Mbit Ethernet controller on board; say Y
@@ -413,7 +418,7 @@ config SUN3LANCE
413 418
414config SUN3_82586 419config SUN3_82586
415 bool "Sun3 on-board Intel 82586 support" 420 bool "Sun3 on-board Intel 82586 support"
416 depends on NET_ETHERNET && SUN3 421 depends on SUN3
417 help 422 help
418 This driver enables support for the on-board Intel 82586 based 423 This driver enables support for the on-board Intel 82586 based
419 Ethernet adapter found on Sun 3/1xx and 3/2xx motherboards. Note 424 Ethernet adapter found on Sun 3/1xx and 3/2xx motherboards. Note
@@ -422,7 +427,7 @@ config SUN3_82586
422 427
423config HPLANCE 428config HPLANCE
424 bool "HP on-board LANCE support" 429 bool "HP on-board LANCE support"
425 depends on NET_ETHERNET && DIO 430 depends on DIO
426 select CRC32 431 select CRC32
427 help 432 help
428 If you want to use the builtin "LANCE" Ethernet controller on an 433 If you want to use the builtin "LANCE" Ethernet controller on an
@@ -430,21 +435,28 @@ config HPLANCE
430 435
431config LASI_82596 436config LASI_82596
432 tristate "Lasi ethernet" 437 tristate "Lasi ethernet"
433 depends on NET_ETHERNET && GSC 438 depends on GSC
434 help 439 help
435 Say Y here to support the builtin Intel 82596 ethernet controller 440 Say Y here to support the builtin Intel 82596 ethernet controller
436 found in Hewlett-Packard PA-RISC machines with 10Mbit ethernet. 441 found in Hewlett-Packard PA-RISC machines with 10Mbit ethernet.
437 442
443config SNI_82596
444 tristate "SNI RM ethernet"
445 depends on NET_ETHERNET && SNI_RM
446 help
447 Say Y here to support the on-board Intel 82596 ethernet controller
448 built into SNI RM machines.
449
438config MIPS_JAZZ_SONIC 450config MIPS_JAZZ_SONIC
439 tristate "MIPS JAZZ onboard SONIC Ethernet support" 451 tristate "MIPS JAZZ onboard SONIC Ethernet support"
440 depends on NET_ETHERNET && MACH_JAZZ 452 depends on MACH_JAZZ
441 help 453 help
442 This is the driver for the onboard card of MIPS Magnum 4000, 454 This is the driver for the onboard card of MIPS Magnum 4000,
443 Acer PICA, Olivetti M700-10 and a few other identical OEM systems. 455 Acer PICA, Olivetti M700-10 and a few other identical OEM systems.
444 456
445config MIPS_AU1X00_ENET 457config MIPS_AU1X00_ENET
446 bool "MIPS AU1000 Ethernet support" 458 bool "MIPS AU1000 Ethernet support"
447 depends on NET_ETHERNET && SOC_AU1X00 459 depends on SOC_AU1X00
448 select PHYLIB 460 select PHYLIB
449 select CRC32 461 select CRC32
450 help 462 help
@@ -453,11 +465,11 @@ config MIPS_AU1X00_ENET
453 465
454config NET_SB1250_MAC 466config NET_SB1250_MAC
455 tristate "SB1250 Ethernet support" 467 tristate "SB1250 Ethernet support"
456 depends on NET_ETHERNET && SIBYTE_SB1xxx_SOC 468 depends on SIBYTE_SB1xxx_SOC
457 469
458config SGI_IOC3_ETH 470config SGI_IOC3_ETH
459 bool "SGI IOC3 Ethernet" 471 bool "SGI IOC3 Ethernet"
460 depends on NET_ETHERNET && PCI && SGI_IP27 472 depends on PCI && SGI_IP27
461 select CRC32 473 select CRC32
462 select MII 474 select MII
463 help 475 help
@@ -487,7 +499,7 @@ config SGI_IOC3_ETH_HW_TX_CSUM
487 499
488config MIPS_SIM_NET 500config MIPS_SIM_NET
489 tristate "MIPS simulator Network device" 501 tristate "MIPS simulator Network device"
490 depends on NET_ETHERNET && MIPS_SIM 502 depends on MIPS_SIM
491 help 503 help
492 The MIPSNET device is a simple Ethernet network device which is 504 The MIPSNET device is a simple Ethernet network device which is
493 emulated by the MIPS Simulator. 505 emulated by the MIPS Simulator.
@@ -495,11 +507,11 @@ config MIPS_SIM_NET
495 507
496config SGI_O2MACE_ETH 508config SGI_O2MACE_ETH
497 tristate "SGI O2 MACE Fast Ethernet support" 509 tristate "SGI O2 MACE Fast Ethernet support"
498 depends on NET_ETHERNET && SGI_IP32=y 510 depends on SGI_IP32=y
499 511
500config STNIC 512config STNIC
501 tristate "National DP83902AV support" 513 tristate "National DP83902AV support"
502 depends on NET_ETHERNET && SUPERH 514 depends on SUPERH
503 select CRC32 515 select CRC32
504 help 516 help
505 Support for cards based on the National Semiconductor DP83902AV 517 Support for cards based on the National Semiconductor DP83902AV
@@ -511,7 +523,7 @@ config STNIC
511 523
512config SUNLANCE 524config SUNLANCE
513 tristate "Sun LANCE support" 525 tristate "Sun LANCE support"
514 depends on NET_ETHERNET && SBUS 526 depends on SBUS
515 select CRC32 527 select CRC32
516 help 528 help
517 This driver supports the "le" interface present on all 32-bit Sparc 529 This driver supports the "le" interface present on all 32-bit Sparc
@@ -524,7 +536,7 @@ config SUNLANCE
524 536
525config HAPPYMEAL 537config HAPPYMEAL
526 tristate "Sun Happy Meal 10/100baseT support" 538 tristate "Sun Happy Meal 10/100baseT support"
527 depends on NET_ETHERNET && (SBUS || PCI) 539 depends on SBUS || PCI
528 select CRC32 540 select CRC32
529 help 541 help
530 This driver supports the "hme" interface present on most Ultra 542 This driver supports the "hme" interface present on most Ultra
@@ -537,7 +549,7 @@ config HAPPYMEAL
537 549
538config SUNBMAC 550config SUNBMAC
539 tristate "Sun BigMAC 10/100baseT support (EXPERIMENTAL)" 551 tristate "Sun BigMAC 10/100baseT support (EXPERIMENTAL)"
540 depends on NET_ETHERNET && SBUS && EXPERIMENTAL 552 depends on SBUS && EXPERIMENTAL
541 select CRC32 553 select CRC32
542 help 554 help
543 This driver supports the "be" interface available as an Sbus option. 555 This driver supports the "be" interface available as an Sbus option.
@@ -548,7 +560,7 @@ config SUNBMAC
548 560
549config SUNQE 561config SUNQE
550 tristate "Sun QuadEthernet support" 562 tristate "Sun QuadEthernet support"
551 depends on NET_ETHERNET && SBUS 563 depends on SBUS
552 select CRC32 564 select CRC32
553 help 565 help
554 This driver supports the "qe" 10baseT Ethernet device, available as 566 This driver supports the "qe" 10baseT Ethernet device, available as
@@ -560,7 +572,7 @@ config SUNQE
560 572
561config SUNGEM 573config SUNGEM
562 tristate "Sun GEM support" 574 tristate "Sun GEM support"
563 depends on NET_ETHERNET && PCI 575 depends on PCI
564 select CRC32 576 select CRC32
565 help 577 help
566 Support for the Sun GEM chip, aka Sun GigabitEthernet/P 2.0. See also 578 Support for the Sun GEM chip, aka Sun GigabitEthernet/P 2.0. See also
@@ -568,7 +580,7 @@ config SUNGEM
568 580
569config CASSINI 581config CASSINI
570 tristate "Sun Cassini support" 582 tristate "Sun Cassini support"
571 depends on NET_ETHERNET && PCI 583 depends on PCI
572 select CRC32 584 select CRC32
573 help 585 help
574 Support for the Sun Cassini chip, aka Sun GigaSwift Ethernet. See also 586 Support for the Sun Cassini chip, aka Sun GigaSwift Ethernet. See also
@@ -576,7 +588,7 @@ config CASSINI
576 588
577config NET_VENDOR_3COM 589config NET_VENDOR_3COM
578 bool "3COM cards" 590 bool "3COM cards"
579 depends on NET_ETHERNET && (ISA || EISA || MCA || PCI) 591 depends on ISA || EISA || MCA || PCI
580 help 592 help
581 If you have a network (Ethernet) card belonging to this class, say Y 593 If you have a network (Ethernet) card belonging to this class, say Y
582 and read the Ethernet-HOWTO, available from 594 and read the Ethernet-HOWTO, available from
@@ -736,7 +748,7 @@ config TYPHOON
736 748
737config LANCE 749config LANCE
738 tristate "AMD LANCE and PCnet (AT1500 and NE2100) support" 750 tristate "AMD LANCE and PCnet (AT1500 and NE2100) support"
739 depends on NET_ETHERNET && ISA && ISA_DMA_API 751 depends on ISA && ISA_DMA_API
740 help 752 help
741 If you have a network (Ethernet) card of this type, say Y and read 753 If you have a network (Ethernet) card of this type, say Y and read
742 the Ethernet-HOWTO, available from 754 the Ethernet-HOWTO, available from
@@ -748,7 +760,7 @@ config LANCE
748 760
749config NET_VENDOR_SMC 761config NET_VENDOR_SMC
750 bool "Western Digital/SMC cards" 762 bool "Western Digital/SMC cards"
751 depends on NET_ETHERNET && (ISA || MCA || EISA || MAC) 763 depends on ISA || MCA || EISA || MAC
752 help 764 help
753 If you have a network (Ethernet) card belonging to this class, say Y 765 If you have a network (Ethernet) card belonging to this class, say Y
754 and read the Ethernet-HOWTO, available from 766 and read the Ethernet-HOWTO, available from
@@ -818,11 +830,27 @@ config ULTRA32
818 <file:Documentation/networking/net-modules.txt>. The module 830 <file:Documentation/networking/net-modules.txt>. The module
819 will be called smc-ultra32. 831 will be called smc-ultra32.
820 832
833config SMC9194
834 tristate "SMC 9194 support"
835 depends on NET_VENDOR_SMC && (ISA || MAC && BROKEN)
836 select CRC32
837 ---help---
838 This is support for the SMC9xxx based Ethernet cards. Choose this
839 option if you have a DELL laptop with the docking station, or
840 another SMC9192/9194 based chipset. Say Y if you want it compiled
841 into the kernel, and read the file
842 <file:Documentation/networking/smc9.txt> and the Ethernet-HOWTO,
843 available from <http://www.tldp.org/docs.html#howto>.
844
845 To compile this driver as a module, choose M here and read
846 <file:Documentation/networking/net-modules.txt>. The module
847 will be called smc9194.
848
821config SMC91X 849config SMC91X
822 tristate "SMC 91C9x/91C1xxx support" 850 tristate "SMC 91C9x/91C1xxx support"
823 select CRC32 851 select CRC32
824 select MII 852 select MII
825 depends on NET_ETHERNET && (ARM || REDWOOD_5 || REDWOOD_6 || M32R || SUPERH || SOC_AU1X00 || BFIN) 853 depends on ARM || REDWOOD_5 || REDWOOD_6 || M32R || SUPERH || SOC_AU1X00 || BFIN
826 help 854 help
827 This is a driver for SMC's 91x series of Ethernet chipsets, 855 This is a driver for SMC's 91x series of Ethernet chipsets,
828 including the SMC91C94 and the SMC91C111. Say Y if you want it 856 including the SMC91C94 and the SMC91C111. Say Y if you want it
@@ -836,26 +864,10 @@ config SMC91X
836 module, say M here and read <file:Documentation/kbuild/modules.txt> 864 module, say M here and read <file:Documentation/kbuild/modules.txt>
837 as well as <file:Documentation/networking/net-modules.txt>. 865 as well as <file:Documentation/networking/net-modules.txt>.
838 866
839config SMC9194
840 tristate "SMC 9194 support"
841 depends on NET_VENDOR_SMC && (ISA || MAC && BROKEN)
842 select CRC32
843 ---help---
844 This is support for the SMC9xxx based Ethernet cards. Choose this
845 option if you have a DELL laptop with the docking station, or
846 another SMC9192/9194 based chipset. Say Y if you want it compiled
847 into the kernel, and read the file
848 <file:Documentation/networking/smc9.txt> and the Ethernet-HOWTO,
849 available from <http://www.tldp.org/docs.html#howto>.
850
851 To compile this driver as a module, choose M here and read
852 <file:Documentation/networking/net-modules.txt>. The module
853 will be called smc9194.
854
855config NET_NETX 867config NET_NETX
856 tristate "NetX Ethernet support" 868 tristate "NetX Ethernet support"
857 select MII 869 select MII
858 depends on NET_ETHERNET && ARCH_NETX 870 depends on ARCH_NETX
859 help 871 help
860 This is support for the Hilscher netX builtin Ethernet ports 872 This is support for the Hilscher netX builtin Ethernet ports
861 873
@@ -865,7 +877,7 @@ config NET_NETX
865 877
866config DM9000 878config DM9000
867 tristate "DM9000 support" 879 tristate "DM9000 support"
868 depends on (ARM || MIPS) && NET_ETHERNET 880 depends on ARM || MIPS
869 select CRC32 881 select CRC32
870 select MII 882 select MII
871 ---help--- 883 ---help---
@@ -879,7 +891,7 @@ config SMC911X
879 tristate "SMSC LAN911[5678] support" 891 tristate "SMSC LAN911[5678] support"
880 select CRC32 892 select CRC32
881 select MII 893 select MII
882 depends on NET_ETHERNET && ARCH_PXA 894 depends on ARCH_PXA
883 help 895 help
884 This is a driver for SMSC's LAN911x series of Ethernet chipsets 896 This is a driver for SMSC's LAN911x series of Ethernet chipsets
885 including the new LAN9115, LAN9116, LAN9117, and LAN9118. 897 including the new LAN9115, LAN9116, LAN9117, and LAN9118.
@@ -893,7 +905,7 @@ config SMC911X
893 905
894config NET_VENDOR_RACAL 906config NET_VENDOR_RACAL
895 bool "Racal-Interlan (Micom) NI cards" 907 bool "Racal-Interlan (Micom) NI cards"
896 depends on NET_ETHERNET && ISA 908 depends on ISA
897 help 909 help
898 If you have a network (Ethernet) card belonging to this class, such 910 If you have a network (Ethernet) card belonging to this class, such
899 as the NI5010, NI5210 or NI6210, say Y and read the Ethernet-HOWTO, 911 as the NI5010, NI5210 or NI6210, say Y and read the Ethernet-HOWTO,
@@ -945,7 +957,7 @@ source "drivers/net/tulip/Kconfig"
945 957
946config AT1700 958config AT1700
947 tristate "AT1700/1720 support (EXPERIMENTAL)" 959 tristate "AT1700/1720 support (EXPERIMENTAL)"
948 depends on NET_ETHERNET && (ISA || MCA_LEGACY) && EXPERIMENTAL 960 depends on (ISA || MCA_LEGACY) && EXPERIMENTAL
949 select CRC32 961 select CRC32
950 ---help--- 962 ---help---
951 If you have a network (Ethernet) card of this type, say Y and read 963 If you have a network (Ethernet) card of this type, say Y and read
@@ -958,7 +970,7 @@ config AT1700
958 970
959config DEPCA 971config DEPCA
960 tristate "DEPCA, DE10x, DE200, DE201, DE202, DE422 support" 972 tristate "DEPCA, DE10x, DE200, DE201, DE202, DE422 support"
961 depends on NET_ETHERNET && (ISA || EISA || MCA) 973 depends on ISA || EISA || MCA
962 select CRC32 974 select CRC32
963 ---help--- 975 ---help---
964 If you have a network (Ethernet) card of this type, say Y and read 976 If you have a network (Ethernet) card of this type, say Y and read
@@ -972,7 +984,7 @@ config DEPCA
972 984
973config HP100 985config HP100
974 tristate "HP 10/100VG PCLAN (ISA, EISA, PCI) support" 986 tristate "HP 10/100VG PCLAN (ISA, EISA, PCI) support"
975 depends on NET_ETHERNET && (ISA || EISA || PCI) 987 depends on ISA || EISA || PCI
976 help 988 help
977 If you have a network (Ethernet) card of this type, say Y and read 989 If you have a network (Ethernet) card of this type, say Y and read
978 the Ethernet-HOWTO, available from 990 the Ethernet-HOWTO, available from
@@ -984,7 +996,7 @@ config HP100
984 996
985config NET_ISA 997config NET_ISA
986 bool "Other ISA cards" 998 bool "Other ISA cards"
987 depends on NET_ETHERNET && ISA 999 depends on ISA
988 ---help--- 1000 ---help---
989 If your network (Ethernet) card hasn't been mentioned yet and its 1001 If your network (Ethernet) card hasn't been mentioned yet and its
990 bus system (that's the way the cards talks to the other components 1002 bus system (that's the way the cards talks to the other components
@@ -1147,7 +1159,7 @@ config SEEQ8005
1147 1159
1148config NE2_MCA 1160config NE2_MCA
1149 tristate "NE/2 (ne2000 MCA version) support" 1161 tristate "NE/2 (ne2000 MCA version) support"
1150 depends on NET_ETHERNET && MCA_LEGACY 1162 depends on MCA_LEGACY
1151 select CRC32 1163 select CRC32
1152 help 1164 help
1153 If you have a network (Ethernet) card of this type, say Y and read 1165 If you have a network (Ethernet) card of this type, say Y and read
@@ -1160,7 +1172,7 @@ config NE2_MCA
1160 1172
1161config IBMLANA 1173config IBMLANA
1162 tristate "IBM LAN Adapter/A support" 1174 tristate "IBM LAN Adapter/A support"
1163 depends on NET_ETHERNET && MCA && MCA_LEGACY 1175 depends on MCA && MCA_LEGACY
1164 ---help--- 1176 ---help---
1165 This is a Micro Channel Ethernet adapter. You need to set 1177 This is a Micro Channel Ethernet adapter. You need to set
1166 CONFIG_MCA to use this driver. It is both available as an in-kernel 1178 CONFIG_MCA to use this driver. It is both available as an in-kernel
@@ -1176,7 +1188,7 @@ config IBMLANA
1176 1188
1177config IBMVETH 1189config IBMVETH
1178 tristate "IBM LAN Virtual Ethernet support" 1190 tristate "IBM LAN Virtual Ethernet support"
1179 depends on NET_ETHERNET && PPC_PSERIES 1191 depends on PPC_PSERIES
1180 ---help--- 1192 ---help---
1181 This driver supports virtual ethernet adapters on newer IBM iSeries 1193 This driver supports virtual ethernet adapters on newer IBM iSeries
1182 and pSeries systems. 1194 and pSeries systems.
@@ -1257,7 +1269,7 @@ config IBM_EMAC_TAH
1257 1269
1258config NET_PCI 1270config NET_PCI
1259 bool "EISA, VLB, PCI and on board controllers" 1271 bool "EISA, VLB, PCI and on board controllers"
1260 depends on NET_ETHERNET && (ISA || EISA || PCI) 1272 depends on ISA || EISA || PCI
1261 help 1273 help
1262 This is another class of network cards which attach directly to the 1274 This is another class of network cards which attach directly to the
1263 bus. If you have one of those, say Y and read the Ethernet-HOWTO, 1275 bus. If you have one of those, say Y and read the Ethernet-HOWTO,
@@ -1313,6 +1325,7 @@ config AMD8111_ETH
1313 To compile this driver as a module, choose M here and read 1325 To compile this driver as a module, choose M here and read
1314 <file:Documentation/networking/net-modules.txt>. The module 1326 <file:Documentation/networking/net-modules.txt>. The module
1315 will be called amd8111e. 1327 will be called amd8111e.
1328
1316config AMD8111E_NAPI 1329config AMD8111E_NAPI
1317 bool "Enable NAPI support" 1330 bool "Enable NAPI support"
1318 depends on AMD8111_ETH 1331 depends on AMD8111_ETH
@@ -1778,7 +1791,7 @@ config SC92031
1778 1791
1779config NET_POCKET 1792config NET_POCKET
1780 bool "Pocket and portable adapters" 1793 bool "Pocket and portable adapters"
1781 depends on NET_ETHERNET && PARPORT 1794 depends on PARPORT
1782 ---help--- 1795 ---help---
1783 Cute little network (Ethernet) devices which attach to the parallel 1796 Cute little network (Ethernet) devices which attach to the parallel
1784 port ("pocket adapters"), commonly used with laptops. If you have 1797 port ("pocket adapters"), commonly used with laptops. If you have
@@ -1847,14 +1860,14 @@ config DE620
1847 1860
1848config SGISEEQ 1861config SGISEEQ
1849 tristate "SGI Seeq ethernet controller support" 1862 tristate "SGI Seeq ethernet controller support"
1850 depends on NET_ETHERNET && SGI_IP22 1863 depends on SGI_IP22
1851 help 1864 help
1852 Say Y here if you have an Seeq based Ethernet network card. This is 1865 Say Y here if you have an Seeq based Ethernet network card. This is
1853 used in many Silicon Graphics machines. 1866 used in many Silicon Graphics machines.
1854 1867
1855config DECLANCE 1868config DECLANCE
1856 tristate "DEC LANCE ethernet controller support" 1869 tristate "DEC LANCE ethernet controller support"
1857 depends on NET_ETHERNET && MACH_DECSTATION 1870 depends on MACH_DECSTATION
1858 select CRC32 1871 select CRC32
1859 help 1872 help
1860 This driver is for the series of Ethernet controllers produced by 1873 This driver is for the series of Ethernet controllers produced by
@@ -1884,7 +1897,7 @@ config FEC2
1884 1897
1885config NE_H8300 1898config NE_H8300
1886 tristate "NE2000 compatible support for H8/300" 1899 tristate "NE2000 compatible support for H8/300"
1887 depends on H8300 && NET_ETHERNET 1900 depends on H8300
1888 help 1901 help
1889 Say Y here if you want to use the NE2000 compatible 1902 Say Y here if you want to use the NE2000 compatible
1890 controller on the Renesas H8/300 processor. 1903 controller on the Renesas H8/300 processor.
@@ -1892,7 +1905,7 @@ config NE_H8300
1892source "drivers/net/fec_8xx/Kconfig" 1905source "drivers/net/fec_8xx/Kconfig"
1893source "drivers/net/fs_enet/Kconfig" 1906source "drivers/net/fs_enet/Kconfig"
1894 1907
1895endmenu 1908endif # NET_ETHERNET
1896 1909
1897# 1910#
1898# Gigabit Ethernet 1911# Gigabit Ethernet
@@ -2101,7 +2114,7 @@ config SKGE
2101 with better performance and more complete ethtool support. 2114 with better performance and more complete ethtool support.
2102 2115
2103 It does not support the link failover and network management 2116 It does not support the link failover and network management
2104 features that "portable" vendor supplied sk98lin driver does. 2117 features available in the hardware.
2105 2118
2106 This driver supports adapters based on the original Yukon chipset: 2119 This driver supports adapters based on the original Yukon chipset:
2107 Marvell 88E8001, Belkin F5D5005, CNet GigaCard, DLink DGE-530T, 2120 Marvell 88E8001, Belkin F5D5005, CNet GigaCard, DLink DGE-530T,
@@ -2114,7 +2127,7 @@ config SKGE
2114 will be called skge. This is recommended. 2127 will be called skge. This is recommended.
2115 2128
2116config SKY2 2129config SKY2
2117 tristate "SysKonnect Yukon2 support (EXPERIMENTAL)" 2130 tristate "SysKonnect Yukon2 support"
2118 depends on PCI 2131 depends on PCI
2119 select CRC32 2132 select CRC32
2120 ---help--- 2133 ---help---
@@ -2129,92 +2142,15 @@ config SKY2
2129 To compile this driver as a module, choose M here: the module 2142 To compile this driver as a module, choose M here: the module
2130 will be called sky2. This is recommended. 2143 will be called sky2. This is recommended.
2131 2144
2132config SK98LIN 2145config SKY2_DEBUG
2133 tristate "Marvell Yukon Chipset / SysKonnect SK-98xx Support (DEPRECATED)" 2146 bool "Debugging interface"
2134 depends on PCI 2147 depends on SKY2 && DEBUG_FS
2135 ---help--- 2148 help
2136 Say Y here if you have a Marvell Yukon or SysKonnect SK-98xx/SK-95xx 2149 This option adds the ability to dump driver state for debugging.
2137 compliant Gigabit Ethernet Adapter. 2150 The file debugfs/sky2/ethX displays the state of the internal
2138 2151 transmit and receive rings.
2139 This driver supports the original Yukon chipset. This driver is
2140 deprecated and will be removed from the kernel in the near future,
2141 it has been replaced by the skge driver. skge is cleaner and
2142 seems to work better.
2143 2152
2144 This driver does not support the newer Yukon2 chipset. A separate 2153 If unsure, say N.
2145 driver, sky2, is provided to support Yukon2-based adapters.
2146
2147 The following adapters are supported by this driver:
2148 - 3Com 3C940 Gigabit LOM Ethernet Adapter
2149 - 3Com 3C941 Gigabit LOM Ethernet Adapter
2150 - Allied Telesyn AT-2970LX Gigabit Ethernet Adapter
2151 - Allied Telesyn AT-2970LX/2SC Gigabit Ethernet Adapter
2152 - Allied Telesyn AT-2970SX Gigabit Ethernet Adapter
2153 - Allied Telesyn AT-2970SX/2SC Gigabit Ethernet Adapter
2154 - Allied Telesyn AT-2970TX Gigabit Ethernet Adapter
2155 - Allied Telesyn AT-2970TX/2TX Gigabit Ethernet Adapter
2156 - Allied Telesyn AT-2971SX Gigabit Ethernet Adapter
2157 - Allied Telesyn AT-2971T Gigabit Ethernet Adapter
2158 - Belkin Gigabit Desktop Card 10/100/1000Base-T Adapter, Copper RJ-45
2159 - EG1032 v2 Instant Gigabit Network Adapter
2160 - EG1064 v2 Instant Gigabit Network Adapter
2161 - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Abit)
2162 - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Albatron)
2163 - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Asus)
2164 - Marvell 88E8001 Gigabit LOM Ethernet Adapter (ECS)
2165 - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Epox)
2166 - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Foxconn)
2167 - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Gigabyte)
2168 - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Iwill)
2169 - Marvell 88E8050 Gigabit LOM Ethernet Adapter (Intel)
2170 - Marvell RDK-8001 Adapter
2171 - Marvell RDK-8002 Adapter
2172 - Marvell RDK-8003 Adapter
2173 - Marvell RDK-8004 Adapter
2174 - Marvell RDK-8006 Adapter
2175 - Marvell RDK-8007 Adapter
2176 - Marvell RDK-8008 Adapter
2177 - Marvell RDK-8009 Adapter
2178 - Marvell RDK-8010 Adapter
2179 - Marvell RDK-8011 Adapter
2180 - Marvell RDK-8012 Adapter
2181 - Marvell RDK-8052 Adapter
2182 - Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Adapter (32 bit)
2183 - Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Adapter (64 bit)
2184 - N-Way PCI-Bus Giga-Card 1000/100/10Mbps(L)
2185 - SK-9521 10/100/1000Base-T Adapter
2186 - SK-9521 V2.0 10/100/1000Base-T Adapter
2187 - SK-9821 Gigabit Ethernet Server Adapter (SK-NET GE-T)
2188 - SK-9821 V2.0 Gigabit Ethernet 10/100/1000Base-T Adapter
2189 - SK-9822 Gigabit Ethernet Server Adapter (SK-NET GE-T dual link)
2190 - SK-9841 Gigabit Ethernet Server Adapter (SK-NET GE-LX)
2191 - SK-9841 V2.0 Gigabit Ethernet 1000Base-LX Adapter
2192 - SK-9842 Gigabit Ethernet Server Adapter (SK-NET GE-LX dual link)
2193 - SK-9843 Gigabit Ethernet Server Adapter (SK-NET GE-SX)
2194 - SK-9843 V2.0 Gigabit Ethernet 1000Base-SX Adapter
2195 - SK-9844 Gigabit Ethernet Server Adapter (SK-NET GE-SX dual link)
2196 - SK-9851 V2.0 Gigabit Ethernet 1000Base-SX Adapter
2197 - SK-9861 Gigabit Ethernet Server Adapter (SK-NET GE-SX Volition)
2198 - SK-9861 V2.0 Gigabit Ethernet 1000Base-SX Adapter
2199 - SK-9862 Gigabit Ethernet Server Adapter (SK-NET GE-SX Volition dual link)
2200 - SK-9871 Gigabit Ethernet Server Adapter (SK-NET GE-ZX)
2201 - SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter
2202 - SK-9872 Gigabit Ethernet Server Adapter (SK-NET GE-ZX dual link)
2203 - SMC EZ Card 1000 (SMC9452TXV.2)
2204
2205 The adapters support Jumbo Frames.
2206 The dual link adapters support link-failover and dual port features.
2207 Both Marvell Yukon and SysKonnect SK-98xx/SK-95xx adapters support
2208 the scatter-gather functionality with sendfile(). Please refer to
2209 <file:Documentation/networking/sk98lin.txt> for more information about
2210 optional driver parameters.
2211 Questions concerning this driver may be addressed to:
2212 <linux@syskonnect.de>
2213
2214 If you want to compile this driver as a module ( = code which can be
2215 inserted in and removed from the running kernel whenever you want),
2216 say M here and read <file:Documentation/kbuild/modules.txt>. The module will
2217 be called sk98lin. This is recommended.
2218 2154
2219config VIA_VELOCITY 2155config VIA_VELOCITY
2220 tristate "VIA Velocity support" 2156 tristate "VIA Velocity support"
@@ -2264,6 +2200,16 @@ config TSI108_ETH
2264 To compile this driver as a module, choose M here: the module 2200 To compile this driver as a module, choose M here: the module
2265 will be called tsi108_eth. 2201 will be called tsi108_eth.
2266 2202
2203config GELIC_NET
2204 tristate "PS3 Gigabit Ethernet driver"
2205 depends on PPC_PS3
2206 help
2207 This driver supports the network device on the PS3 game
2208 console. This driver has built-in support for Ethernet.
2209
2210 To compile this driver as a module, choose M here: the
2211 module will be called ps3_gelic.
2212
2267config GIANFAR 2213config GIANFAR
2268 tristate "Gianfar Ethernet" 2214 tristate "Gianfar Ethernet"
2269 depends on 85xx || 83xx || PPC_86xx 2215 depends on 85xx || 83xx || PPC_86xx
@@ -2303,7 +2249,7 @@ config UGETH_TX_ON_DEMAND
2303 2249
2304config MV643XX_ETH 2250config MV643XX_ETH
2305 tristate "MV-643XX Ethernet support" 2251 tristate "MV-643XX Ethernet support"
2306 depends on MOMENCO_OCELOT_C || MOMENCO_JAGUAR_ATX || MV64360 || MV64X60 || MOMENCO_OCELOT_3 || (PPC_MULTIPLATFORM && PPC32) 2252 depends on MV64360 || MV64X60 || (PPC_MULTIPLATFORM && PPC32)
2307 select MII 2253 select MII
2308 help 2254 help
2309 This driver supports the gigabit Ethernet on the Marvell MV643XX 2255 This driver supports the gigabit Ethernet on the Marvell MV643XX
@@ -2948,8 +2894,6 @@ config NETCONSOLE
2948 If you want to log kernel messages over the network, enable this. 2894 If you want to log kernel messages over the network, enable this.
2949 See <file:Documentation/networking/netconsole.txt> for details. 2895 See <file:Documentation/networking/netconsole.txt> for details.
2950 2896
2951endif #NETDEVICES
2952
2953config NETPOLL 2897config NETPOLL
2954 def_bool NETCONSOLE 2898 def_bool NETCONSOLE
2955 2899
@@ -2961,4 +2905,4 @@ config NETPOLL_TRAP
2961config NET_POLL_CONTROLLER 2905config NET_POLL_CONTROLLER
2962 def_bool NETPOLL 2906 def_bool NETPOLL
2963 2907
2964endmenu 2908endif # NETDEVICES
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index a77affa4f6e6..1bbcbedad04a 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -60,10 +60,11 @@ obj-$(CONFIG_TIGON3) += tg3.o
60obj-$(CONFIG_BNX2) += bnx2.o 60obj-$(CONFIG_BNX2) += bnx2.o
61spidernet-y += spider_net.o spider_net_ethtool.o 61spidernet-y += spider_net.o spider_net_ethtool.o
62obj-$(CONFIG_SPIDER_NET) += spidernet.o sungem_phy.o 62obj-$(CONFIG_SPIDER_NET) += spidernet.o sungem_phy.o
63obj-$(CONFIG_GELIC_NET) += ps3_gelic.o
64ps3_gelic-objs += ps3_gelic_net.o
63obj-$(CONFIG_TC35815) += tc35815.o 65obj-$(CONFIG_TC35815) += tc35815.o
64obj-$(CONFIG_SKGE) += skge.o 66obj-$(CONFIG_SKGE) += skge.o
65obj-$(CONFIG_SKY2) += sky2.o 67obj-$(CONFIG_SKY2) += sky2.o
66obj-$(CONFIG_SK98LIN) += sk98lin/
67obj-$(CONFIG_SKFP) += skfp/ 68obj-$(CONFIG_SKFP) += skfp/
68obj-$(CONFIG_VIA_RHINE) += via-rhine.o 69obj-$(CONFIG_VIA_RHINE) += via-rhine.o
69obj-$(CONFIG_VIA_VELOCITY) += via-velocity.o 70obj-$(CONFIG_VIA_VELOCITY) += via-velocity.o
@@ -107,6 +108,7 @@ obj-$(CONFIG_NET_SB1250_MAC) += sb1250-mac.o
107obj-$(CONFIG_B44) += b44.o 108obj-$(CONFIG_B44) += b44.o
108obj-$(CONFIG_FORCEDETH) += forcedeth.o 109obj-$(CONFIG_FORCEDETH) += forcedeth.o
109obj-$(CONFIG_NE_H8300) += ne-h8300.o 110obj-$(CONFIG_NE_H8300) += ne-h8300.o
111obj-$(CONFIG_AX88796) += ax88796.o
110 112
111obj-$(CONFIG_TSI108_ETH) += tsi108_eth.o 113obj-$(CONFIG_TSI108_ETH) += tsi108_eth.o
112obj-$(CONFIG_MV643XX_ETH) += mv643xx_eth.o 114obj-$(CONFIG_MV643XX_ETH) += mv643xx_eth.o
@@ -157,6 +159,7 @@ obj-$(CONFIG_ELPLUS) += 3c505.o
157obj-$(CONFIG_AC3200) += ac3200.o 8390.o 159obj-$(CONFIG_AC3200) += ac3200.o 8390.o
158obj-$(CONFIG_APRICOT) += 82596.o 160obj-$(CONFIG_APRICOT) += 82596.o
159obj-$(CONFIG_LASI_82596) += lasi_82596.o 161obj-$(CONFIG_LASI_82596) += lasi_82596.o
162obj-$(CONFIG_SNI_82596) += sni_82596.o
160obj-$(CONFIG_MVME16x_NET) += 82596.o 163obj-$(CONFIG_MVME16x_NET) += 82596.o
161obj-$(CONFIG_BVME6000_NET) += 82596.o 164obj-$(CONFIG_BVME6000_NET) += 82596.o
162obj-$(CONFIG_SC92031) += sc92031.o 165obj-$(CONFIG_SC92031) += sc92031.o
diff --git a/drivers/net/acenic.c b/drivers/net/acenic.c
index 04382f979c99..b78a4e5ceeb2 100644
--- a/drivers/net/acenic.c
+++ b/drivers/net/acenic.c
@@ -159,10 +159,6 @@ static struct pci_device_id acenic_pci_tbl[] = {
159}; 159};
160MODULE_DEVICE_TABLE(pci, acenic_pci_tbl); 160MODULE_DEVICE_TABLE(pci, acenic_pci_tbl);
161 161
162#ifndef SET_NETDEV_DEV
163#define SET_NETDEV_DEV(net, pdev) do{} while(0)
164#endif
165
166#define ace_sync_irq(irq) synchronize_irq(irq) 162#define ace_sync_irq(irq) synchronize_irq(irq)
167 163
168#ifndef offset_in_page 164#ifndef offset_in_page
diff --git a/drivers/net/arm/Kconfig b/drivers/net/arm/Kconfig
index 678e4f48d36b..5bf2d33887ac 100644
--- a/drivers/net/arm/Kconfig
+++ b/drivers/net/arm/Kconfig
@@ -4,7 +4,7 @@
4# 4#
5config ARM_AM79C961A 5config ARM_AM79C961A
6 bool "ARM EBSA110 AM79C961A support" 6 bool "ARM EBSA110 AM79C961A support"
7 depends on NET_ETHERNET && ARM && ARCH_EBSA110 7 depends on ARM && ARCH_EBSA110
8 select CRC32 8 select CRC32
9 help 9 help
10 If you wish to compile a kernel for the EBSA-110, then you should 10 If you wish to compile a kernel for the EBSA-110, then you should
@@ -12,21 +12,21 @@ config ARM_AM79C961A
12 12
13config ARM_ETHER1 13config ARM_ETHER1
14 tristate "Acorn Ether1 support" 14 tristate "Acorn Ether1 support"
15 depends on NET_ETHERNET && ARM && ARCH_ACORN 15 depends on ARM && ARCH_ACORN
16 help 16 help
17 If you have an Acorn system with one of these (AKA25) network cards, 17 If you have an Acorn system with one of these (AKA25) network cards,
18 you should say Y to this option if you wish to use it with Linux. 18 you should say Y to this option if you wish to use it with Linux.
19 19
20config ARM_ETHER3 20config ARM_ETHER3
21 tristate "Acorn/ANT Ether3 support" 21 tristate "Acorn/ANT Ether3 support"
22 depends on NET_ETHERNET && ARM && ARCH_ACORN 22 depends on ARM && ARCH_ACORN
23 help 23 help
24 If you have an Acorn system with one of these network cards, you 24 If you have an Acorn system with one of these network cards, you
25 should say Y to this option if you wish to use it with Linux. 25 should say Y to this option if you wish to use it with Linux.
26 26
27config ARM_ETHERH 27config ARM_ETHERH
28 tristate "I-cubed EtherH/ANT EtherM support" 28 tristate "I-cubed EtherH/ANT EtherM support"
29 depends on NET_ETHERNET && ARM && ARCH_ACORN 29 depends on ARM && ARCH_ACORN
30 select CRC32 30 select CRC32
31 help 31 help
32 If you have an Acorn system with one of these network cards, you 32 If you have an Acorn system with one of these network cards, you
@@ -34,7 +34,7 @@ config ARM_ETHERH
34 34
35config ARM_AT91_ETHER 35config ARM_AT91_ETHER
36 tristate "AT91RM9200 Ethernet support" 36 tristate "AT91RM9200 Ethernet support"
37 depends on NET_ETHERNET && ARM && ARCH_AT91RM9200 37 depends on ARM && ARCH_AT91RM9200
38 select MII 38 select MII
39 help 39 help
40 If you wish to compile a kernel for the AT91RM9200 and enable 40 If you wish to compile a kernel for the AT91RM9200 and enable
@@ -42,7 +42,7 @@ config ARM_AT91_ETHER
42 42
43config EP93XX_ETH 43config EP93XX_ETH
44 tristate "EP93xx Ethernet support" 44 tristate "EP93xx Ethernet support"
45 depends on NET_ETHERNET && ARM && ARCH_EP93XX 45 depends on ARM && ARCH_EP93XX
46 help 46 help
47 This is a driver for the ethernet hardware included in EP93xx CPUs. 47 This is a driver for the ethernet hardware included in EP93xx CPUs.
48 Say Y if you are building a kernel for EP93xx based devices. 48 Say Y if you are building a kernel for EP93xx based devices.
diff --git a/drivers/net/atari_pamsnet.c b/drivers/net/atari_pamsnet.c
index 54714409a09b..f7356374a2e7 100644
--- a/drivers/net/atari_pamsnet.c
+++ b/drivers/net/atari_pamsnet.c
@@ -295,10 +295,7 @@ int if_up = 0;
295/* Setup the DMA counter */ 295/* Setup the DMA counter */
296 296
297static void 297static void
298setup_dma (address, rw_flag, num_blocks) 298setup_dma (void *address, unsigned rw_flag, int num_blocks)
299 void *address;
300 unsigned rw_flag;
301 int num_blocks;
302{ 299{
303 WRITEMODE((unsigned) rw_flag | DMA_FDC | SEC_COUNT | REG_ACSI | 300 WRITEMODE((unsigned) rw_flag | DMA_FDC | SEC_COUNT | REG_ACSI |
304 A1); 301 A1);
@@ -317,9 +314,7 @@ setup_dma (address, rw_flag, num_blocks)
317/* Send the first byte of an command block */ 314/* Send the first byte of an command block */
318 315
319static int 316static int
320send_first (target, byte) 317send_first (int target, unsigned char byte)
321 int target;
322 unsigned char byte;
323{ 318{
324 rw = READ; 319 rw = READ;
325 acsi_delay_end(COMMAND_DELAY); 320 acsi_delay_end(COMMAND_DELAY);
@@ -338,10 +333,7 @@ send_first (target, byte)
338/* Send the rest of an command block */ 333/* Send the rest of an command block */
339 334
340static int 335static int
341send_1_5 (lun, command, dma) 336send_1_5 (int lun, unsigned char *command, int dma)
342 int lun;
343 unsigned char *command;
344 int dma;
345{ 337{
346 int i, j; 338 int i, j;
347 339
@@ -371,8 +363,7 @@ get_status (void)
371/* Calculate the number of received bytes */ 363/* Calculate the number of received bytes */
372 364
373static int 365static int
374calc_received (start_address) 366calc_received (void *start_address)
375 void *start_address;
376{ 367{
377 return (int)( 368 return (int)(
378 (((unsigned long)DMAHIGH << 16) | ((unsigned)DMAMID << 8) | DMALOW) 369 (((unsigned long)DMAHIGH << 16) | ((unsigned)DMAMID << 8) | DMALOW)
@@ -384,8 +375,7 @@ calc_received (start_address)
384/* start() starts the PAM's DMA adaptor */ 375/* start() starts the PAM's DMA adaptor */
385 376
386static void 377static void
387start (target) 378start (int target)
388 int target;
389{ 379{
390 send_first(target, START); 380 send_first(target, START);
391} 381}
@@ -393,8 +383,7 @@ start (target)
393/* stop() stops the PAM's DMA adaptor and returns a value of zero in case of success */ 383/* stop() stops the PAM's DMA adaptor and returns a value of zero in case of success */
394 384
395static int 385static int
396stop (target) 386stop (int target)
397 int target;
398{ 387{
399 int ret = -1; 388 int ret = -1;
400 unsigned char cmd_buffer[5]; 389 unsigned char cmd_buffer[5];
@@ -415,8 +404,7 @@ bad:
415/* testpkt() returns the number of received packets waiting in the queue */ 404/* testpkt() returns the number of received packets waiting in the queue */
416 405
417static int 406static int
418testpkt(target) 407testpkt(int target)
419 int target;
420{ 408{
421 int ret = -1; 409 int ret = -1;
422 410
@@ -431,9 +419,7 @@ bad:
431/* Please note: The buffer is for internal use only but must be defined! */ 419/* Please note: The buffer is for internal use only but must be defined! */
432 420
433static int 421static int
434inquiry (target, buffer) 422inquiry (int target, unsigned char *buffer)
435 int target;
436 unsigned char *buffer;
437{ 423{
438 int ret = -1; 424 int ret = -1;
439 unsigned char *vbuffer = phys_to_virt((unsigned long)buffer); 425 unsigned char *vbuffer = phys_to_virt((unsigned long)buffer);
@@ -468,9 +454,7 @@ bad:
468 */ 454 */
469 455
470static HADDR 456static HADDR
471*read_hw_addr(target, buffer) 457*read_hw_addr(int target, unsigned char *buffer)
472 int target;
473 unsigned char *buffer;
474{ 458{
475 HADDR *ret = 0; 459 HADDR *ret = 0;
476 unsigned char cmd_buffer[5]; 460 unsigned char cmd_buffer[5];
@@ -491,9 +475,7 @@ bad:
491} 475}
492 476
493static irqreturn_t 477static irqreturn_t
494pamsnet_intr(irq, data, fp) 478pamsnet_intr(int irq, void *data)
495 int irq;
496 void *data;
497{ 479{
498 return IRQ_HANDLED; 480 return IRQ_HANDLED;
499} 481}
@@ -501,9 +483,7 @@ pamsnet_intr(irq, data, fp)
501/* receivepkt() loads a packet to a given buffer and returns its length */ 483/* receivepkt() loads a packet to a given buffer and returns its length */
502 484
503static int 485static int
504receivepkt (target, buffer) 486receivepkt (int target, unsigned char *buffer)
505 int target;
506 unsigned char *buffer;
507{ 487{
508 int ret = -1; 488 int ret = -1;
509 unsigned char cmd_buffer[5]; 489 unsigned char cmd_buffer[5];
@@ -526,10 +506,7 @@ bad:
526 successfully */ 506 successfully */
527 507
528static int 508static int
529sendpkt (target, buffer, length) 509sendpkt (int target, unsigned char *buffer, int length)
530 int target;
531 unsigned char *buffer;
532 int length;
533{ 510{
534 int ret = -1; 511 int ret = -1;
535 unsigned char cmd_buffer[5]; 512 unsigned char cmd_buffer[5];
@@ -665,7 +642,8 @@ struct net_device * __init pamsnet_probe (int unit)
665 there is non-reboot way to recover if something goes wrong. 642 there is non-reboot way to recover if something goes wrong.
666 */ 643 */
667static int 644static int
668pamsnet_open(struct net_device *dev) { 645pamsnet_open(struct net_device *dev)
646{
669 struct net_local *lp = netdev_priv(dev); 647 struct net_local *lp = netdev_priv(dev);
670 648
671 if (pamsnet_debug > 0) 649 if (pamsnet_debug > 0)
@@ -694,7 +672,8 @@ pamsnet_open(struct net_device *dev) {
694} 672}
695 673
696static int 674static int
697pamsnet_send_packet(struct sk_buff *skb, struct net_device *dev) { 675pamsnet_send_packet(struct sk_buff *skb, struct net_device *dev)
676{
698 struct net_local *lp = netdev_priv(dev); 677 struct net_local *lp = netdev_priv(dev);
699 unsigned long flags; 678 unsigned long flags;
700 679
@@ -741,7 +720,8 @@ pamsnet_send_packet(struct sk_buff *skb, struct net_device *dev) {
741/* We have a good packet(s), get it/them out of the buffers. 720/* We have a good packet(s), get it/them out of the buffers.
742 */ 721 */
743static void 722static void
744pamsnet_poll_rx(struct net_device *dev) { 723pamsnet_poll_rx(struct net_device *dev)
724{
745 struct net_local *lp = netdev_priv(dev); 725 struct net_local *lp = netdev_priv(dev);
746 int boguscount; 726 int boguscount;
747 int pkt_len; 727 int pkt_len;
@@ -816,7 +796,8 @@ pamsnet_poll_rx(struct net_device *dev) {
816 * passes them to the higher layers and restarts the timer. 796 * passes them to the higher layers and restarts the timer.
817 */ 797 */
818static void 798static void
819pamsnet_tick(unsigned long data) { 799pamsnet_tick(unsigned long data)
800{
820 struct net_device *dev = (struct net_device *)data; 801 struct net_device *dev = (struct net_device *)data;
821 struct net_local *lp = netdev_priv(dev); 802 struct net_local *lp = netdev_priv(dev);
822 803
@@ -832,7 +813,8 @@ pamsnet_tick(unsigned long data) {
832/* The inverse routine to pamsnet_open(). 813/* The inverse routine to pamsnet_open().
833 */ 814 */
834static int 815static int
835pamsnet_close(struct net_device *dev) { 816pamsnet_close(struct net_device *dev)
817{
836 struct net_local *lp = netdev_priv(dev); 818 struct net_local *lp = netdev_priv(dev);
837 819
838 if (pamsnet_debug > 0) 820 if (pamsnet_debug > 0)
diff --git a/drivers/net/atl1/atl1_main.c b/drivers/net/atl1/atl1_main.c
index 6862c11ff864..3bb40dd4a410 100644
--- a/drivers/net/atl1/atl1_main.c
+++ b/drivers/net/atl1/atl1_main.c
@@ -634,14 +634,13 @@ static void atl1_intr_tx(struct atl1_adapter *adapter)
634 struct atl1_buffer *buffer_info; 634 struct atl1_buffer *buffer_info;
635 u16 sw_tpd_next_to_clean; 635 u16 sw_tpd_next_to_clean;
636 u16 cmb_tpd_next_to_clean; 636 u16 cmb_tpd_next_to_clean;
637 u8 update = 0;
638 637
639 sw_tpd_next_to_clean = atomic_read(&tpd_ring->next_to_clean); 638 sw_tpd_next_to_clean = atomic_read(&tpd_ring->next_to_clean);
640 cmb_tpd_next_to_clean = le16_to_cpu(adapter->cmb.cmb->tpd_cons_idx); 639 cmb_tpd_next_to_clean = le16_to_cpu(adapter->cmb.cmb->tpd_cons_idx);
641 640
642 while (cmb_tpd_next_to_clean != sw_tpd_next_to_clean) { 641 while (cmb_tpd_next_to_clean != sw_tpd_next_to_clean) {
643 struct tx_packet_desc *tpd; 642 struct tx_packet_desc *tpd;
644 update = 1; 643
645 tpd = ATL1_TPD_DESC(tpd_ring, sw_tpd_next_to_clean); 644 tpd = ATL1_TPD_DESC(tpd_ring, sw_tpd_next_to_clean);
646 buffer_info = &tpd_ring->buffer_info[sw_tpd_next_to_clean]; 645 buffer_info = &tpd_ring->buffer_info[sw_tpd_next_to_clean];
647 if (buffer_info->dma) { 646 if (buffer_info->dma) {
diff --git a/drivers/net/ax88796.c b/drivers/net/ax88796.c
new file mode 100644
index 000000000000..d19874bf0706
--- /dev/null
+++ b/drivers/net/ax88796.c
@@ -0,0 +1,952 @@
1/* drivers/net/ax88796.c
2 *
3 * Copyright 2005,2007 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * Asix AX88796 10/100 Ethernet controller support
7 * Based on ne.c, by Donald Becker, et-al.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12*/
13
14#include <linux/module.h>
15#include <linux/kernel.h>
16#include <linux/errno.h>
17#include <linux/isapnp.h>
18#include <linux/init.h>
19#include <linux/interrupt.h>
20#include <linux/platform_device.h>
21#include <linux/delay.h>
22#include <linux/timer.h>
23#include <linux/netdevice.h>
24#include <linux/etherdevice.h>
25#include <linux/ethtool.h>
26#include <linux/mii.h>
27
28#include <net/ax88796.h>
29
30#include <asm/system.h>
31#include <asm/io.h>
32
33static int phy_debug = 0;
34
35/* Rename the lib8390.c functions to show that they are in this driver */
36#define __ei_open ax_ei_open
37#define __ei_close ax_ei_close
38#define __ei_poll ax_ei_poll
39#define __ei_tx_timeout ax_ei_tx_timeout
40#define __ei_interrupt ax_ei_interrupt
41#define ____alloc_ei_netdev ax__alloc_ei_netdev
42#define __NS8390_init ax_NS8390_init
43
44/* force unsigned long back to 'void __iomem *' */
45#define ax_convert_addr(_a) ((void __force __iomem *)(_a))
46
47#define ei_inb(_a) readb(ax_convert_addr(_a))
48#define ei_outb(_v, _a) writeb(_v, ax_convert_addr(_a))
49
50#define ei_inb_p(_a) ei_inb(_a)
51#define ei_outb_p(_v, _a) ei_outb(_v, _a)
52
53/* define EI_SHIFT() to take into account our register offsets */
54#define EI_SHIFT(x) (ei_local->reg_offset[(x)])
55
56/* Ensure we have our RCR base value */
57#define AX88796_PLATFORM
58
59static unsigned char version[] = "ax88796.c: Copyright 2005,2007 Simtec Electronics\n";
60
61#include "lib8390.c"
62
63#define DRV_NAME "ax88796"
64#define DRV_VERSION "1.00"
65
66/* from ne.c */
67#define NE_CMD EI_SHIFT(0x00)
68#define NE_RESET EI_SHIFT(0x1f)
69#define NE_DATAPORT EI_SHIFT(0x10)
70
71#define NE1SM_START_PG 0x20 /* First page of TX buffer */
72#define NE1SM_STOP_PG 0x40 /* Last page +1 of RX ring */
73#define NESM_START_PG 0x40 /* First page of TX buffer */
74#define NESM_STOP_PG 0x80 /* Last page +1 of RX ring */
75
76/* device private data */
77
78struct ax_device {
79 struct timer_list mii_timer;
80 spinlock_t mii_lock;
81 struct mii_if_info mii;
82
83 u32 msg_enable;
84 void __iomem *map2;
85 struct platform_device *dev;
86 struct resource *mem;
87 struct resource *mem2;
88 struct ax_plat_data *plat;
89
90 unsigned char running;
91 unsigned char resume_open;
92
93 u32 reg_offsets[0x20];
94};
95
96static inline struct ax_device *to_ax_dev(struct net_device *dev)
97{
98 struct ei_device *ei_local = netdev_priv(dev);
99 return (struct ax_device *)(ei_local+1);
100}
101
102/* ax_initial_check
103 *
104 * do an initial probe for the card to check wether it exists
105 * and is functional
106 */
107
108static int ax_initial_check(struct net_device *dev)
109{
110 struct ei_device *ei_local = netdev_priv(dev);
111 void __iomem *ioaddr = ei_local->mem;
112 int reg0;
113 int regd;
114
115 reg0 = ei_inb(ioaddr);
116 if (reg0 == 0xFF)
117 return -ENODEV;
118
119 ei_outb(E8390_NODMA+E8390_PAGE1+E8390_STOP, ioaddr + E8390_CMD);
120 regd = ei_inb(ioaddr + 0x0d);
121 ei_outb(0xff, ioaddr + 0x0d);
122 ei_outb(E8390_NODMA+E8390_PAGE0, ioaddr + E8390_CMD);
123 ei_inb(ioaddr + EN0_COUNTER0); /* Clear the counter by reading. */
124 if (ei_inb(ioaddr + EN0_COUNTER0) != 0) {
125 ei_outb(reg0, ioaddr);
126 ei_outb(regd, ioaddr + 0x0d); /* Restore the old values. */
127 return -ENODEV;
128 }
129
130 return 0;
131}
132
133/* Hard reset the card. This used to pause for the same period that a
134 8390 reset command required, but that shouldn't be necessary. */
135
136static void ax_reset_8390(struct net_device *dev)
137{
138 struct ei_device *ei_local = netdev_priv(dev);
139 unsigned long reset_start_time = jiffies;
140 void __iomem *addr = (void __iomem *)dev->base_addr;
141
142 if (ei_debug > 1)
143 printk(KERN_DEBUG "resetting the 8390 t=%ld...", jiffies);
144
145 ei_outb(ei_inb(addr + NE_RESET), addr + NE_RESET);
146
147 ei_status.txing = 0;
148 ei_status.dmaing = 0;
149
150 /* This check _should_not_ be necessary, omit eventually. */
151 while ((ei_inb(addr + EN0_ISR) & ENISR_RESET) == 0) {
152 if (jiffies - reset_start_time > 2*HZ/100) {
153 printk(KERN_WARNING "%s: %s did not complete.\n",
154 __FUNCTION__, dev->name);
155 break;
156 }
157 }
158
159 ei_outb(ENISR_RESET, addr + EN0_ISR); /* Ack intr. */
160}
161
162
163static void ax_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,
164 int ring_page)
165{
166 struct ei_device *ei_local = netdev_priv(dev);
167 void __iomem *nic_base = ei_local->mem;
168
169 /* This *shouldn't* happen. If it does, it's the last thing you'll see */
170 if (ei_status.dmaing) {
171 printk(KERN_EMERG "%s: DMAing conflict in %s [DMAstat:%d][irqlock:%d].\n",
172 dev->name, __FUNCTION__,
173 ei_status.dmaing, ei_status.irqlock);
174 return;
175 }
176
177 ei_status.dmaing |= 0x01;
178 ei_outb(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD);
179 ei_outb(sizeof(struct e8390_pkt_hdr), nic_base + EN0_RCNTLO);
180 ei_outb(0, nic_base + EN0_RCNTHI);
181 ei_outb(0, nic_base + EN0_RSARLO); /* On page boundary */
182 ei_outb(ring_page, nic_base + EN0_RSARHI);
183 ei_outb(E8390_RREAD+E8390_START, nic_base + NE_CMD);
184
185 if (ei_status.word16)
186 readsw(nic_base + NE_DATAPORT, hdr, sizeof(struct e8390_pkt_hdr)>>1);
187 else
188 readsb(nic_base + NE_DATAPORT, hdr, sizeof(struct e8390_pkt_hdr));
189
190 ei_outb(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */
191 ei_status.dmaing &= ~0x01;
192
193 le16_to_cpus(&hdr->count);
194}
195
196
197/* Block input and output, similar to the Crynwr packet driver. If you
198 are porting to a new ethercard, look at the packet driver source for hints.
199 The NEx000 doesn't share the on-board packet memory -- you have to put
200 the packet out through the "remote DMA" dataport using ei_outb. */
201
202static void ax_block_input(struct net_device *dev, int count,
203 struct sk_buff *skb, int ring_offset)
204{
205 struct ei_device *ei_local = netdev_priv(dev);
206 void __iomem *nic_base = ei_local->mem;
207 char *buf = skb->data;
208
209 if (ei_status.dmaing) {
210 printk(KERN_EMERG "%s: DMAing conflict in ax_block_input "
211 "[DMAstat:%d][irqlock:%d].\n",
212 dev->name, ei_status.dmaing, ei_status.irqlock);
213 return;
214 }
215
216 ei_status.dmaing |= 0x01;
217
218 ei_outb(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD);
219 ei_outb(count & 0xff, nic_base + EN0_RCNTLO);
220 ei_outb(count >> 8, nic_base + EN0_RCNTHI);
221 ei_outb(ring_offset & 0xff, nic_base + EN0_RSARLO);
222 ei_outb(ring_offset >> 8, nic_base + EN0_RSARHI);
223 ei_outb(E8390_RREAD+E8390_START, nic_base + NE_CMD);
224
225 if (ei_status.word16) {
226 readsw(nic_base + NE_DATAPORT, buf, count >> 1);
227 if (count & 0x01)
228 buf[count-1] = ei_inb(nic_base + NE_DATAPORT);
229
230 } else {
231 readsb(nic_base + NE_DATAPORT, buf, count);
232 }
233
234 ei_status.dmaing &= ~1;
235}
236
237static void ax_block_output(struct net_device *dev, int count,
238 const unsigned char *buf, const int start_page)
239{
240 struct ei_device *ei_local = netdev_priv(dev);
241 void __iomem *nic_base = ei_local->mem;
242 unsigned long dma_start;
243
244 /* Round the count up for word writes. Do we need to do this?
245 What effect will an odd byte count have on the 8390?
246 I should check someday. */
247
248 if (ei_status.word16 && (count & 0x01))
249 count++;
250
251 /* This *shouldn't* happen. If it does, it's the last thing you'll see */
252 if (ei_status.dmaing) {
253 printk(KERN_EMERG "%s: DMAing conflict in %s."
254 "[DMAstat:%d][irqlock:%d]\n",
255 dev->name, __FUNCTION__,
256 ei_status.dmaing, ei_status.irqlock);
257 return;
258 }
259
260 ei_status.dmaing |= 0x01;
261 /* We should already be in page 0, but to be safe... */
262 ei_outb(E8390_PAGE0+E8390_START+E8390_NODMA, nic_base + NE_CMD);
263
264 ei_outb(ENISR_RDC, nic_base + EN0_ISR);
265
266 /* Now the normal output. */
267 ei_outb(count & 0xff, nic_base + EN0_RCNTLO);
268 ei_outb(count >> 8, nic_base + EN0_RCNTHI);
269 ei_outb(0x00, nic_base + EN0_RSARLO);
270 ei_outb(start_page, nic_base + EN0_RSARHI);
271
272 ei_outb(E8390_RWRITE+E8390_START, nic_base + NE_CMD);
273 if (ei_status.word16) {
274 writesw(nic_base + NE_DATAPORT, buf, count>>1);
275 } else {
276 writesb(nic_base + NE_DATAPORT, buf, count);
277 }
278
279 dma_start = jiffies;
280
281 while ((ei_inb(nic_base + EN0_ISR) & ENISR_RDC) == 0) {
282 if (jiffies - dma_start > 2*HZ/100) { /* 20ms */
283 printk(KERN_WARNING "%s: timeout waiting for Tx RDC.\n", dev->name);
284 ax_reset_8390(dev);
285 ax_NS8390_init(dev,1);
286 break;
287 }
288 }
289
290 ei_outb(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */
291 ei_status.dmaing &= ~0x01;
292 return;
293}
294
295/* definitions for accessing MII/EEPROM interface */
296
297#define AX_MEMR EI_SHIFT(0x14)
298#define AX_MEMR_MDC (1<<0)
299#define AX_MEMR_MDIR (1<<1)
300#define AX_MEMR_MDI (1<<2)
301#define AX_MEMR_MDO (1<<3)
302#define AX_MEMR_EECS (1<<4)
303#define AX_MEMR_EEI (1<<5)
304#define AX_MEMR_EEO (1<<6)
305#define AX_MEMR_EECLK (1<<7)
306
307/* ax_mii_ei_outbits
308 *
309 * write the specified set of bits to the phy
310*/
311
312static void
313ax_mii_ei_outbits(struct net_device *dev, unsigned int bits, int len)
314{
315 struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
316 void __iomem *memr_addr = (void __iomem *)dev->base_addr + AX_MEMR;
317 unsigned int memr;
318
319 /* clock low, data to output mode */
320 memr = ei_inb(memr_addr);
321 memr &= ~(AX_MEMR_MDC | AX_MEMR_MDIR);
322 ei_outb(memr, memr_addr);
323
324 for (len--; len >= 0; len--) {
325 if (bits & (1 << len))
326 memr |= AX_MEMR_MDO;
327 else
328 memr &= ~AX_MEMR_MDO;
329
330 ei_outb(memr, memr_addr);
331
332 /* clock high */
333
334 ei_outb(memr | AX_MEMR_MDC, memr_addr);
335 udelay(1);
336
337 /* clock low */
338 ei_outb(memr, memr_addr);
339 }
340
341 /* leaves the clock line low, mdir input */
342 memr |= AX_MEMR_MDIR;
343 ei_outb(memr, (void __iomem *)dev->base_addr + AX_MEMR);
344}
345
346/* ax_phy_ei_inbits
347 *
348 * read a specified number of bits from the phy
349*/
350
351static unsigned int
352ax_phy_ei_inbits(struct net_device *dev, int no)
353{
354 struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
355 void __iomem *memr_addr = (void __iomem *)dev->base_addr + AX_MEMR;
356 unsigned int memr;
357 unsigned int result = 0;
358
359 /* clock low, data to input mode */
360 memr = ei_inb(memr_addr);
361 memr &= ~AX_MEMR_MDC;
362 memr |= AX_MEMR_MDIR;
363 ei_outb(memr, memr_addr);
364
365 for (no--; no >= 0; no--) {
366 ei_outb(memr | AX_MEMR_MDC, memr_addr);
367
368 udelay(1);
369
370 if (ei_inb(memr_addr) & AX_MEMR_MDI)
371 result |= (1<<no);
372
373 ei_outb(memr, memr_addr);
374 }
375
376 return result;
377}
378
379/* ax_phy_issueaddr
380 *
381 * use the low level bit shifting routines to send the address
382 * and command to the specified phy
383*/
384
385static void
386ax_phy_issueaddr(struct net_device *dev, int phy_addr, int reg, int opc)
387{
388 if (phy_debug)
389 pr_debug("%s: dev %p, %04x, %04x, %d\n",
390 __FUNCTION__, dev, phy_addr, reg, opc);
391
392 ax_mii_ei_outbits(dev, 0x3f, 6); /* pre-amble */
393 ax_mii_ei_outbits(dev, 1, 2); /* frame-start */
394 ax_mii_ei_outbits(dev, opc, 2); /* op code */
395 ax_mii_ei_outbits(dev, phy_addr, 5); /* phy address */
396 ax_mii_ei_outbits(dev, reg, 5); /* reg address */
397}
398
399static int
400ax_phy_read(struct net_device *dev, int phy_addr, int reg)
401{
402 struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
403 unsigned long flags;
404 unsigned int result;
405
406 spin_lock_irqsave(&ei_local->page_lock, flags);
407
408 ax_phy_issueaddr(dev, phy_addr, reg, 2);
409
410 result = ax_phy_ei_inbits(dev, 17);
411 result &= ~(3<<16);
412
413 spin_unlock_irqrestore(&ei_local->page_lock, flags);
414
415 if (phy_debug)
416 pr_debug("%s: %04x.%04x => read %04x\n", __FUNCTION__,
417 phy_addr, reg, result);
418
419 return result;
420}
421
422static void
423ax_phy_write(struct net_device *dev, int phy_addr, int reg, int value)
424{
425 struct ei_device *ei = (struct ei_device *) netdev_priv(dev);
426 unsigned long flags;
427
428 printk(KERN_DEBUG "%s: %p, %04x, %04x %04x\n",
429 __FUNCTION__, dev, phy_addr, reg, value);
430
431 spin_lock_irqsave(&ei->page_lock, flags);
432
433 ax_phy_issueaddr(dev, phy_addr, reg, 1);
434 ax_mii_ei_outbits(dev, 2, 2); /* send TA */
435 ax_mii_ei_outbits(dev, value, 16);
436
437 spin_unlock_irqrestore(&ei->page_lock, flags);
438}
439
440static void ax_mii_expiry(unsigned long data)
441{
442 struct net_device *dev = (struct net_device *)data;
443 struct ax_device *ax = to_ax_dev(dev);
444 unsigned long flags;
445
446 spin_lock_irqsave(&ax->mii_lock, flags);
447 mii_check_media(&ax->mii, netif_msg_link(ax), 0);
448 spin_unlock_irqrestore(&ax->mii_lock, flags);
449
450 if (ax->running) {
451 ax->mii_timer.expires = jiffies + HZ*2;
452 add_timer(&ax->mii_timer);
453 }
454}
455
456static int ax_open(struct net_device *dev)
457{
458 struct ax_device *ax = to_ax_dev(dev);
459 struct ei_device *ei_local = netdev_priv(dev);
460 int ret;
461
462 dev_dbg(ax->dev, "%s: open\n", dev->name);
463
464 ret = request_irq(dev->irq, ax_ei_interrupt, 0, dev->name, dev);
465 if (ret)
466 return ret;
467
468 ret = ax_ei_open(dev);
469 if (ret)
470 return ret;
471
472 /* turn the phy on (if turned off) */
473
474 ei_outb(ax->plat->gpoc_val, ei_local->mem + EI_SHIFT(0x17));
475 ax->running = 1;
476
477 /* start the MII timer */
478
479 init_timer(&ax->mii_timer);
480
481 ax->mii_timer.expires = jiffies+1;
482 ax->mii_timer.data = (unsigned long) dev;
483 ax->mii_timer.function = ax_mii_expiry;
484
485 add_timer(&ax->mii_timer);
486
487 return 0;
488}
489
490static int ax_close(struct net_device *dev)
491{
492 struct ax_device *ax = to_ax_dev(dev);
493 struct ei_device *ei_local = netdev_priv(dev);
494
495 dev_dbg(ax->dev, "%s: close\n", dev->name);
496
497 /* turn the phy off */
498
499 ei_outb(ax->plat->gpoc_val | (1<<6),
500 ei_local->mem + EI_SHIFT(0x17));
501
502 ax->running = 0;
503 wmb();
504
505 del_timer_sync(&ax->mii_timer);
506 ax_ei_close(dev);
507
508 free_irq(dev->irq, dev);
509 return 0;
510}
511
512static int ax_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
513{
514 struct ax_device *ax = to_ax_dev(dev);
515 unsigned long flags;
516 int rc;
517
518 if (!netif_running(dev))
519 return -EINVAL;
520
521 spin_lock_irqsave(&ax->mii_lock, flags);
522 rc = generic_mii_ioctl(&ax->mii, if_mii(req), cmd, NULL);
523 spin_unlock_irqrestore(&ax->mii_lock, flags);
524
525 return rc;
526}
527
528/* ethtool ops */
529
530static void ax_get_drvinfo(struct net_device *dev,
531 struct ethtool_drvinfo *info)
532{
533 struct ax_device *ax = to_ax_dev(dev);
534
535 strcpy(info->driver, DRV_NAME);
536 strcpy(info->version, DRV_VERSION);
537 strcpy(info->bus_info, ax->dev->name);
538}
539
540static int ax_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
541{
542 struct ax_device *ax = to_ax_dev(dev);
543 unsigned long flags;
544
545 spin_lock_irqsave(&ax->mii_lock, flags);
546 mii_ethtool_gset(&ax->mii, cmd);
547 spin_lock_irqsave(&ax->mii_lock, flags);
548
549 return 0;
550}
551
552static int ax_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
553{
554 struct ax_device *ax = to_ax_dev(dev);
555 unsigned long flags;
556 int rc;
557
558 spin_lock_irqsave(&ax->mii_lock, flags);
559 rc = mii_ethtool_sset(&ax->mii, cmd);
560 spin_lock_irqsave(&ax->mii_lock, flags);
561
562 return rc;
563}
564
565static int ax_nway_reset(struct net_device *dev)
566{
567 struct ax_device *ax = to_ax_dev(dev);
568 return mii_nway_restart(&ax->mii);
569}
570
571static u32 ax_get_link(struct net_device *dev)
572{
573 struct ax_device *ax = to_ax_dev(dev);
574 return mii_link_ok(&ax->mii);
575}
576
577static const struct ethtool_ops ax_ethtool_ops = {
578 .get_drvinfo = ax_get_drvinfo,
579 .get_settings = ax_get_settings,
580 .set_settings = ax_set_settings,
581 .nway_reset = ax_nway_reset,
582 .get_link = ax_get_link,
583 .get_perm_addr = ethtool_op_get_perm_addr,
584};
585
586/* setup code */
587
588static void ax_initial_setup(struct net_device *dev, struct ei_device *ei_local)
589{
590 void __iomem *ioaddr = ei_local->mem;
591 struct ax_device *ax = to_ax_dev(dev);
592
593 /* Select page 0*/
594 ei_outb(E8390_NODMA+E8390_PAGE0+E8390_STOP, ioaddr + E8390_CMD);
595
596 /* set to byte access */
597 ei_outb(ax->plat->dcr_val & ~1, ioaddr + EN0_DCFG);
598 ei_outb(ax->plat->gpoc_val, ioaddr + EI_SHIFT(0x17));
599}
600
601/* ax_init_dev
602 *
603 * initialise the specified device, taking care to note the MAC
604 * address it may already have (if configured), ensure
605 * the device is ready to be used by lib8390.c and registerd with
606 * the network layer.
607 */
608
609static int ax_init_dev(struct net_device *dev, int first_init)
610{
611 struct ei_device *ei_local = netdev_priv(dev);
612 struct ax_device *ax = to_ax_dev(dev);
613 void __iomem *ioaddr = ei_local->mem;
614 unsigned int start_page;
615 unsigned int stop_page;
616 int ret;
617 int i;
618
619 ret = ax_initial_check(dev);
620 if (ret)
621 goto err_out;
622
623 /* setup goes here */
624
625 ax_initial_setup(dev, ei_local);
626
627 /* read the mac from the card prom if we need it */
628
629 if (first_init && ax->plat->flags & AXFLG_HAS_EEPROM) {
630 unsigned char SA_prom[32];
631
632 for(i = 0; i < sizeof(SA_prom); i+=2) {
633 SA_prom[i] = ei_inb(ioaddr + NE_DATAPORT);
634 SA_prom[i+1] = ei_inb(ioaddr + NE_DATAPORT);
635 }
636
637 if (ax->plat->wordlength == 2)
638 for (i = 0; i < 16; i++)
639 SA_prom[i] = SA_prom[i+i];
640
641 memcpy(dev->dev_addr, SA_prom, 6);
642 }
643
644 if (ax->plat->wordlength == 2) {
645 /* We must set the 8390 for word mode. */
646 ei_outb(ax->plat->dcr_val, ei_local->mem + EN0_DCFG);
647 start_page = NESM_START_PG;
648 stop_page = NESM_STOP_PG;
649 } else {
650 start_page = NE1SM_START_PG;
651 stop_page = NE1SM_STOP_PG;
652 }
653
654 /* load the mac-address from the device if this is the
655 * first time we've initialised */
656
657 if (first_init && ax->plat->flags & AXFLG_MAC_FROMDEV) {
658 ei_outb(E8390_NODMA + E8390_PAGE1 + E8390_STOP,
659 ei_local->mem + E8390_CMD); /* 0x61 */
660
661 for (i = 0 ; i < ETHER_ADDR_LEN ; i++)
662 dev->dev_addr[i] = ei_inb(ioaddr + EN1_PHYS_SHIFT(i));
663 }
664
665 ax_reset_8390(dev);
666
667 ei_status.name = "AX88796";
668 ei_status.tx_start_page = start_page;
669 ei_status.stop_page = stop_page;
670 ei_status.word16 = (ax->plat->wordlength == 2);
671 ei_status.rx_start_page = start_page + TX_PAGES;
672
673#ifdef PACKETBUF_MEMSIZE
674 /* Allow the packet buffer size to be overridden by know-it-alls. */
675 ei_status.stop_page = ei_status.tx_start_page + PACKETBUF_MEMSIZE;
676#endif
677
678 ei_status.reset_8390 = &ax_reset_8390;
679 ei_status.block_input = &ax_block_input;
680 ei_status.block_output = &ax_block_output;
681 ei_status.get_8390_hdr = &ax_get_8390_hdr;
682 ei_status.priv = 0;
683
684 dev->open = ax_open;
685 dev->stop = ax_close;
686 dev->do_ioctl = ax_ioctl;
687 dev->ethtool_ops = &ax_ethtool_ops;
688
689 ax->msg_enable = NETIF_MSG_LINK;
690 ax->mii.phy_id_mask = 0x1f;
691 ax->mii.reg_num_mask = 0x1f;
692 ax->mii.phy_id = 0x10; /* onboard phy */
693 ax->mii.force_media = 0;
694 ax->mii.full_duplex = 0;
695 ax->mii.mdio_read = ax_phy_read;
696 ax->mii.mdio_write = ax_phy_write;
697 ax->mii.dev = dev;
698
699#ifdef CONFIG_NET_POLL_CONTROLLER
700 dev->poll_controller = ax_ei_poll;
701#endif
702 ax_NS8390_init(dev, 0);
703
704 if (first_init) {
705 printk("AX88796: %dbit, irq %d, %lx, MAC: ",
706 ei_status.word16 ? 16:8, dev->irq, dev->base_addr);
707
708 for (i = 0; i < ETHER_ADDR_LEN; i++)
709 printk("%2.2x%c", dev->dev_addr[i],
710 (i < (ETHER_ADDR_LEN-1) ? ':' : ' '));
711
712 printk("\n");
713 }
714
715 ret = register_netdev(dev);
716 if (ret)
717 goto out_irq;
718
719 return 0;
720
721 out_irq:
722 /* cleanup irq */
723 free_irq(dev->irq, dev);
724 err_out:
725 return ret;
726}
727
728static int ax_remove(struct platform_device *_dev)
729{
730 struct net_device *dev = platform_get_drvdata(_dev);
731 struct ax_device *ax;
732
733 ax = to_ax_dev(dev);
734
735 unregister_netdev(dev);
736 free_irq(dev->irq, dev);
737
738 iounmap(ei_status.mem);
739 release_resource(ax->mem);
740 kfree(ax->mem);
741
742 if (ax->map2) {
743 iounmap(ax->map2);
744 release_resource(ax->mem2);
745 kfree(ax->mem2);
746 }
747
748 free_netdev(dev);
749
750 return 0;
751}
752
753/* ax_probe
754 *
755 * This is the entry point when the platform device system uses to
756 * notify us of a new device to attach to. Allocate memory, find
757 * the resources and information passed, and map the necessary registers.
758*/
759
760static int ax_probe(struct platform_device *pdev)
761{
762 struct net_device *dev;
763 struct ax_device *ax;
764 struct resource *res;
765 size_t size;
766 int ret;
767
768 dev = ax__alloc_ei_netdev(sizeof(struct ax_device));
769 if (dev == NULL)
770 return -ENOMEM;
771
772 /* ok, let's setup our device */
773 ax = to_ax_dev(dev);
774
775 memset(ax, 0, sizeof(struct ax_device));
776
777 spin_lock_init(&ax->mii_lock);
778
779 ax->dev = pdev;
780 ax->plat = pdev->dev.platform_data;
781 platform_set_drvdata(pdev, dev);
782
783 ei_status.rxcr_base = ax->plat->rcr_val;
784
785 /* find the platform resources */
786
787 dev->irq = platform_get_irq(pdev, 0);
788 if (dev->irq < 0) {
789 dev_err(&pdev->dev, "no IRQ specified\n");
790 ret = -ENXIO;
791 goto exit_mem;
792 }
793
794 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
795 if (res == NULL) {
796 dev_err(&pdev->dev, "no MEM specified\n");
797 ret = -ENXIO;
798 goto exit_mem;
799 }
800
801 size = (res->end - res->start) + 1;
802
803 /* setup the register offsets from either the platform data
804 * or by using the size of the resource provided */
805
806 if (ax->plat->reg_offsets)
807 ei_status.reg_offset = ax->plat->reg_offsets;
808 else {
809 ei_status.reg_offset = ax->reg_offsets;
810 for (ret = 0; ret < 0x18; ret++)
811 ax->reg_offsets[ret] = (size / 0x18) * ret;
812 }
813
814 ax->mem = request_mem_region(res->start, size, pdev->name);
815 if (ax->mem == NULL) {
816 dev_err(&pdev->dev, "cannot reserve registers\n");
817 ret = -ENXIO;
818 goto exit_mem;
819 }
820
821 ei_status.mem = ioremap(res->start, size);
822 dev->base_addr = (long)ei_status.mem;
823
824 if (ei_status.mem == NULL) {
825 dev_err(&pdev->dev, "Cannot ioremap area (%08zx,%08zx)\n",
826 res->start, res->end);
827
828 ret = -ENXIO;
829 goto exit_req;
830 }
831
832 /* look for reset area */
833
834 res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
835 if (res == NULL) {
836 if (!ax->plat->reg_offsets) {
837 for (ret = 0; ret < 0x20; ret++)
838 ax->reg_offsets[ret] = (size / 0x20) * ret;
839 }
840
841 ax->map2 = NULL;
842 } else {
843 size = (res->end - res->start) + 1;
844
845 ax->mem2 = request_mem_region(res->start, size, pdev->name);
846 if (ax->mem == NULL) {
847 dev_err(&pdev->dev, "cannot reserve registers\n");
848 ret = -ENXIO;
849 goto exit_mem1;
850 }
851
852 ax->map2 = ioremap(res->start, size);
853 if (ax->map2 == NULL) {
854 dev_err(&pdev->dev, "cannot map reset register");
855 ret = -ENXIO;
856 goto exit_mem2;
857 }
858
859 ei_status.reg_offset[0x1f] = ax->map2 - ei_status.mem;
860 }
861
862 /* got resources, now initialise and register device */
863
864 ret = ax_init_dev(dev, 1);
865 if (!ret)
866 return 0;
867
868 if (ax->map2 == NULL)
869 goto exit_mem1;
870
871 iounmap(ax->map2);
872
873 exit_mem2:
874 release_resource(ax->mem2);
875 kfree(ax->mem2);
876
877 exit_mem1:
878 iounmap(ei_status.mem);
879
880 exit_req:
881 release_resource(ax->mem);
882 kfree(ax->mem);
883
884 exit_mem:
885 free_netdev(dev);
886
887 return ret;
888}
889
890/* suspend and resume */
891
892#ifdef CONFIG_PM
893static int ax_suspend(struct platform_device *dev, pm_message_t state)
894{
895 struct net_device *ndev = platform_get_drvdata(dev);
896 struct ax_device *ax = to_ax_dev(ndev);
897
898 ax->resume_open = ax->running;
899
900 netif_device_detach(ndev);
901 ax_close(ndev);
902
903 return 0;
904}
905
906static int ax_resume(struct platform_device *pdev)
907{
908 struct net_device *ndev = platform_get_drvdata(pdev);
909 struct ax_device *ax = to_ax_dev(ndev);
910
911 ax_initial_setup(ndev, netdev_priv(ndev));
912 ax_NS8390_init(ndev, ax->resume_open);
913 netif_device_attach(ndev);
914
915 if (ax->resume_open)
916 ax_open(ndev);
917
918 return 0;
919}
920
921#else
922#define ax_suspend NULL
923#define ax_resume NULL
924#endif
925
926static struct platform_driver axdrv = {
927 .driver = {
928 .name = "ax88796",
929 .owner = THIS_MODULE,
930 },
931 .probe = ax_probe,
932 .remove = ax_remove,
933 .suspend = ax_suspend,
934 .resume = ax_resume,
935};
936
937static int __init axdrv_init(void)
938{
939 return platform_driver_register(&axdrv);
940}
941
942static void __exit axdrv_exit(void)
943{
944 platform_driver_unregister(&axdrv);
945}
946
947module_init(axdrv_init);
948module_exit(axdrv_exit);
949
950MODULE_DESCRIPTION("AX88796 10/100 Ethernet platform driver");
951MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
952MODULE_LICENSE("GPL v2");
diff --git a/drivers/net/b44.c b/drivers/net/b44.c
index 879a2fff474e..96fb0ec905a7 100644
--- a/drivers/net/b44.c
+++ b/drivers/net/b44.c
@@ -15,6 +15,7 @@
15#include <linux/ethtool.h> 15#include <linux/ethtool.h>
16#include <linux/mii.h> 16#include <linux/mii.h>
17#include <linux/if_ether.h> 17#include <linux/if_ether.h>
18#include <linux/if_vlan.h>
18#include <linux/etherdevice.h> 19#include <linux/etherdevice.h>
19#include <linux/pci.h> 20#include <linux/pci.h>
20#include <linux/delay.h> 21#include <linux/delay.h>
@@ -68,8 +69,8 @@
68 (BP)->tx_cons - (BP)->tx_prod - TX_RING_GAP(BP)) 69 (BP)->tx_cons - (BP)->tx_prod - TX_RING_GAP(BP))
69#define NEXT_TX(N) (((N) + 1) & (B44_TX_RING_SIZE - 1)) 70#define NEXT_TX(N) (((N) + 1) & (B44_TX_RING_SIZE - 1))
70 71
71#define RX_PKT_BUF_SZ (1536 + bp->rx_offset + 64) 72#define RX_PKT_OFFSET 30
72#define TX_PKT_BUF_SZ (B44_MAX_MTU + ETH_HLEN + 8) 73#define RX_PKT_BUF_SZ (1536 + RX_PKT_OFFSET + 64)
73 74
74/* minimum number of free TX descriptors required to wake up TX process */ 75/* minimum number of free TX descriptors required to wake up TX process */
75#define B44_TX_WAKEUP_THRESH (B44_TX_RING_SIZE / 4) 76#define B44_TX_WAKEUP_THRESH (B44_TX_RING_SIZE / 4)
@@ -599,8 +600,7 @@ static void b44_timer(unsigned long __opaque)
599 600
600 spin_unlock_irq(&bp->lock); 601 spin_unlock_irq(&bp->lock);
601 602
602 bp->timer.expires = jiffies + HZ; 603 mod_timer(&bp->timer, round_jiffies(jiffies + HZ));
603 add_timer(&bp->timer);
604} 604}
605 605
606static void b44_tx(struct b44 *bp) 606static void b44_tx(struct b44 *bp)
@@ -653,7 +653,7 @@ static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked)
653 src_map = &bp->rx_buffers[src_idx]; 653 src_map = &bp->rx_buffers[src_idx];
654 dest_idx = dest_idx_unmasked & (B44_RX_RING_SIZE - 1); 654 dest_idx = dest_idx_unmasked & (B44_RX_RING_SIZE - 1);
655 map = &bp->rx_buffers[dest_idx]; 655 map = &bp->rx_buffers[dest_idx];
656 skb = dev_alloc_skb(RX_PKT_BUF_SZ); 656 skb = netdev_alloc_skb(bp->dev, RX_PKT_BUF_SZ);
657 if (skb == NULL) 657 if (skb == NULL)
658 return -ENOMEM; 658 return -ENOMEM;
659 659
@@ -669,7 +669,7 @@ static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked)
669 if (!dma_mapping_error(mapping)) 669 if (!dma_mapping_error(mapping))
670 pci_unmap_single(bp->pdev, mapping, RX_PKT_BUF_SZ,PCI_DMA_FROMDEVICE); 670 pci_unmap_single(bp->pdev, mapping, RX_PKT_BUF_SZ,PCI_DMA_FROMDEVICE);
671 dev_kfree_skb_any(skb); 671 dev_kfree_skb_any(skb);
672 skb = __dev_alloc_skb(RX_PKT_BUF_SZ,GFP_DMA); 672 skb = __netdev_alloc_skb(bp->dev, RX_PKT_BUF_SZ, GFP_ATOMIC|GFP_DMA);
673 if (skb == NULL) 673 if (skb == NULL)
674 return -ENOMEM; 674 return -ENOMEM;
675 mapping = pci_map_single(bp->pdev, skb->data, 675 mapping = pci_map_single(bp->pdev, skb->data,
@@ -684,11 +684,9 @@ static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked)
684 } 684 }
685 } 685 }
686 686
687 skb->dev = bp->dev; 687 rh = (struct rx_header *) skb->data;
688 skb_reserve(skb, bp->rx_offset); 688 skb_reserve(skb, RX_PKT_OFFSET);
689 689
690 rh = (struct rx_header *)
691 (skb->data - bp->rx_offset);
692 rh->len = 0; 690 rh->len = 0;
693 rh->flags = 0; 691 rh->flags = 0;
694 692
@@ -698,13 +696,13 @@ static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked)
698 if (src_map != NULL) 696 if (src_map != NULL)
699 src_map->skb = NULL; 697 src_map->skb = NULL;
700 698
701 ctrl = (DESC_CTRL_LEN & (RX_PKT_BUF_SZ - bp->rx_offset)); 699 ctrl = (DESC_CTRL_LEN & (RX_PKT_BUF_SZ - RX_PKT_OFFSET));
702 if (dest_idx == (B44_RX_RING_SIZE - 1)) 700 if (dest_idx == (B44_RX_RING_SIZE - 1))
703 ctrl |= DESC_CTRL_EOT; 701 ctrl |= DESC_CTRL_EOT;
704 702
705 dp = &bp->rx_ring[dest_idx]; 703 dp = &bp->rx_ring[dest_idx];
706 dp->ctrl = cpu_to_le32(ctrl); 704 dp->ctrl = cpu_to_le32(ctrl);
707 dp->addr = cpu_to_le32((u32) mapping + bp->rx_offset + bp->dma_offset); 705 dp->addr = cpu_to_le32((u32) mapping + RX_PKT_OFFSET + bp->dma_offset);
708 706
709 if (bp->flags & B44_FLAG_RX_RING_HACK) 707 if (bp->flags & B44_FLAG_RX_RING_HACK)
710 b44_sync_dma_desc_for_device(bp->pdev, bp->rx_ring_dma, 708 b44_sync_dma_desc_for_device(bp->pdev, bp->rx_ring_dma,
@@ -783,7 +781,7 @@ static int b44_rx(struct b44 *bp, int budget)
783 PCI_DMA_FROMDEVICE); 781 PCI_DMA_FROMDEVICE);
784 rh = (struct rx_header *) skb->data; 782 rh = (struct rx_header *) skb->data;
785 len = le16_to_cpu(rh->len); 783 len = le16_to_cpu(rh->len);
786 if ((len > (RX_PKT_BUF_SZ - bp->rx_offset)) || 784 if ((len > (RX_PKT_BUF_SZ - RX_PKT_OFFSET)) ||
787 (rh->flags & cpu_to_le16(RX_FLAG_ERRORS))) { 785 (rh->flags & cpu_to_le16(RX_FLAG_ERRORS))) {
788 drop_it: 786 drop_it:
789 b44_recycle_rx(bp, cons, bp->rx_prod); 787 b44_recycle_rx(bp, cons, bp->rx_prod);
@@ -815,8 +813,8 @@ static int b44_rx(struct b44 *bp, int budget)
815 pci_unmap_single(bp->pdev, map, 813 pci_unmap_single(bp->pdev, map,
816 skb_size, PCI_DMA_FROMDEVICE); 814 skb_size, PCI_DMA_FROMDEVICE);
817 /* Leave out rx_header */ 815 /* Leave out rx_header */
818 skb_put(skb, len+bp->rx_offset); 816 skb_put(skb, len + RX_PKT_OFFSET);
819 skb_pull(skb,bp->rx_offset); 817 skb_pull(skb, RX_PKT_OFFSET);
820 } else { 818 } else {
821 struct sk_buff *copy_skb; 819 struct sk_buff *copy_skb;
822 820
@@ -828,7 +826,7 @@ static int b44_rx(struct b44 *bp, int budget)
828 skb_reserve(copy_skb, 2); 826 skb_reserve(copy_skb, 2);
829 skb_put(copy_skb, len); 827 skb_put(copy_skb, len);
830 /* DMA sync done above, copy just the actual packet */ 828 /* DMA sync done above, copy just the actual packet */
831 skb_copy_from_linear_data_offset(skb, bp->rx_offset, 829 skb_copy_from_linear_data_offset(skb, RX_PKT_OFFSET,
832 copy_skb->data, len); 830 copy_skb->data, len);
833 skb = copy_skb; 831 skb = copy_skb;
834 } 832 }
@@ -969,7 +967,6 @@ static void b44_tx_timeout(struct net_device *dev)
969static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev) 967static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev)
970{ 968{
971 struct b44 *bp = netdev_priv(dev); 969 struct b44 *bp = netdev_priv(dev);
972 struct sk_buff *bounce_skb;
973 int rc = NETDEV_TX_OK; 970 int rc = NETDEV_TX_OK;
974 dma_addr_t mapping; 971 dma_addr_t mapping;
975 u32 len, entry, ctrl; 972 u32 len, entry, ctrl;
@@ -987,12 +984,13 @@ static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev)
987 984
988 mapping = pci_map_single(bp->pdev, skb->data, len, PCI_DMA_TODEVICE); 985 mapping = pci_map_single(bp->pdev, skb->data, len, PCI_DMA_TODEVICE);
989 if (dma_mapping_error(mapping) || mapping + len > DMA_30BIT_MASK) { 986 if (dma_mapping_error(mapping) || mapping + len > DMA_30BIT_MASK) {
987 struct sk_buff *bounce_skb;
988
990 /* Chip can't handle DMA to/from >1GB, use bounce buffer */ 989 /* Chip can't handle DMA to/from >1GB, use bounce buffer */
991 if (!dma_mapping_error(mapping)) 990 if (!dma_mapping_error(mapping))
992 pci_unmap_single(bp->pdev, mapping, len, PCI_DMA_TODEVICE); 991 pci_unmap_single(bp->pdev, mapping, len, PCI_DMA_TODEVICE);
993 992
994 bounce_skb = __dev_alloc_skb(TX_PKT_BUF_SZ, 993 bounce_skb = __dev_alloc_skb(len, GFP_ATOMIC | GFP_DMA);
995 GFP_ATOMIC|GFP_DMA);
996 if (!bounce_skb) 994 if (!bounce_skb)
997 goto err_out; 995 goto err_out;
998 996
@@ -1001,13 +999,12 @@ static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev)
1001 if (dma_mapping_error(mapping) || mapping + len > DMA_30BIT_MASK) { 999 if (dma_mapping_error(mapping) || mapping + len > DMA_30BIT_MASK) {
1002 if (!dma_mapping_error(mapping)) 1000 if (!dma_mapping_error(mapping))
1003 pci_unmap_single(bp->pdev, mapping, 1001 pci_unmap_single(bp->pdev, mapping,
1004 len, PCI_DMA_TODEVICE); 1002 len, PCI_DMA_TODEVICE);
1005 dev_kfree_skb_any(bounce_skb); 1003 dev_kfree_skb_any(bounce_skb);
1006 goto err_out; 1004 goto err_out;
1007 } 1005 }
1008 1006
1009 skb_copy_from_linear_data(skb, skb_put(bounce_skb, len), 1007 skb_copy_from_linear_data(skb, skb_put(bounce_skb, len), len);
1010 skb->len);
1011 dev_kfree_skb_any(skb); 1008 dev_kfree_skb_any(skb);
1012 skb = bounce_skb; 1009 skb = bounce_skb;
1013 } 1010 }
@@ -1396,12 +1393,12 @@ static void b44_init_hw(struct b44 *bp, int reset_kind)
1396 bw32(bp, B44_TX_WMARK, 56); /* XXX magic */ 1393 bw32(bp, B44_TX_WMARK, 56); /* XXX magic */
1397 if (reset_kind == B44_PARTIAL_RESET) { 1394 if (reset_kind == B44_PARTIAL_RESET) {
1398 bw32(bp, B44_DMARX_CTRL, (DMARX_CTRL_ENABLE | 1395 bw32(bp, B44_DMARX_CTRL, (DMARX_CTRL_ENABLE |
1399 (bp->rx_offset << DMARX_CTRL_ROSHIFT))); 1396 (RX_PKT_OFFSET << DMARX_CTRL_ROSHIFT)));
1400 } else { 1397 } else {
1401 bw32(bp, B44_DMATX_CTRL, DMATX_CTRL_ENABLE); 1398 bw32(bp, B44_DMATX_CTRL, DMATX_CTRL_ENABLE);
1402 bw32(bp, B44_DMATX_ADDR, bp->tx_ring_dma + bp->dma_offset); 1399 bw32(bp, B44_DMATX_ADDR, bp->tx_ring_dma + bp->dma_offset);
1403 bw32(bp, B44_DMARX_CTRL, (DMARX_CTRL_ENABLE | 1400 bw32(bp, B44_DMARX_CTRL, (DMARX_CTRL_ENABLE |
1404 (bp->rx_offset << DMARX_CTRL_ROSHIFT))); 1401 (RX_PKT_OFFSET << DMARX_CTRL_ROSHIFT)));
1405 bw32(bp, B44_DMARX_ADDR, bp->rx_ring_dma + bp->dma_offset); 1402 bw32(bp, B44_DMARX_ADDR, bp->rx_ring_dma + bp->dma_offset);
1406 1403
1407 bw32(bp, B44_DMARX_PTR, bp->rx_pending); 1404 bw32(bp, B44_DMARX_PTR, bp->rx_pending);
@@ -2093,11 +2090,6 @@ static int __devinit b44_get_invariants(struct b44 *bp)
2093 2090
2094 bp->phy_addr = eeprom[90] & 0x1f; 2091 bp->phy_addr = eeprom[90] & 0x1f;
2095 2092
2096 /* With this, plus the rx_header prepended to the data by the
2097 * hardware, we'll land the ethernet header on a 2-byte boundary.
2098 */
2099 bp->rx_offset = 30;
2100
2101 bp->imask = IMASK_DEF; 2093 bp->imask = IMASK_DEF;
2102 2094
2103 bp->core_unit = ssb_core_unit(bp); 2095 bp->core_unit = ssb_core_unit(bp);
@@ -2348,11 +2340,11 @@ static int b44_resume(struct pci_dev *pdev)
2348 netif_device_attach(bp->dev); 2340 netif_device_attach(bp->dev);
2349 spin_unlock_irq(&bp->lock); 2341 spin_unlock_irq(&bp->lock);
2350 2342
2351 bp->timer.expires = jiffies + HZ;
2352 add_timer(&bp->timer);
2353
2354 b44_enable_ints(bp); 2343 b44_enable_ints(bp);
2355 netif_wake_queue(dev); 2344 netif_wake_queue(dev);
2345
2346 mod_timer(&bp->timer, jiffies + 1);
2347
2356 return 0; 2348 return 0;
2357} 2349}
2358 2350
diff --git a/drivers/net/b44.h b/drivers/net/b44.h
index 18fc13336628..e537e63f292e 100644
--- a/drivers/net/b44.h
+++ b/drivers/net/b44.h
@@ -443,8 +443,6 @@ struct b44 {
443#define B44_FLAG_TX_RING_HACK 0x40000000 443#define B44_FLAG_TX_RING_HACK 0x40000000
444#define B44_FLAG_WOL_ENABLE 0x80000000 444#define B44_FLAG_WOL_ENABLE 0x80000000
445 445
446 u32 rx_offset;
447
448 u32 msg_enable; 446 u32 msg_enable;
449 447
450 struct timer_list timer; 448 struct timer_list timer;
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 6287ffbda7f7..cb9cb3013f42 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -187,7 +187,7 @@ static void bond_send_gratuitous_arp(struct bonding *bond);
187 187
188/*---------------------------- General routines -----------------------------*/ 188/*---------------------------- General routines -----------------------------*/
189 189
190const char *bond_mode_name(int mode) 190static const char *bond_mode_name(int mode)
191{ 191{
192 switch (mode) { 192 switch (mode) {
193 case BOND_MODE_ROUNDROBIN : 193 case BOND_MODE_ROUNDROBIN :
@@ -1224,7 +1224,8 @@ static void bond_detach_slave(struct bonding *bond, struct slave *slave)
1224 1224
1225/*---------------------------------- IOCTL ----------------------------------*/ 1225/*---------------------------------- IOCTL ----------------------------------*/
1226 1226
1227int bond_sethwaddr(struct net_device *bond_dev, struct net_device *slave_dev) 1227static int bond_sethwaddr(struct net_device *bond_dev,
1228 struct net_device *slave_dev)
1228{ 1229{
1229 dprintk("bond_dev=%p\n", bond_dev); 1230 dprintk("bond_dev=%p\n", bond_dev);
1230 dprintk("slave_dev=%p\n", slave_dev); 1231 dprintk("slave_dev=%p\n", slave_dev);
@@ -1390,6 +1391,11 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
1390 goto err_free; 1391 goto err_free;
1391 } 1392 }
1392 1393
1394 res = netdev_set_master(slave_dev, bond_dev);
1395 if (res) {
1396 dprintk("Error %d calling netdev_set_master\n", res);
1397 goto err_close;
1398 }
1393 /* open the slave since the application closed it */ 1399 /* open the slave since the application closed it */
1394 res = dev_open(slave_dev); 1400 res = dev_open(slave_dev);
1395 if (res) { 1401 if (res) {
@@ -1397,12 +1403,6 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
1397 goto err_restore_mac; 1403 goto err_restore_mac;
1398 } 1404 }
1399 1405
1400 res = netdev_set_master(slave_dev, bond_dev);
1401 if (res) {
1402 dprintk("Error %d calling netdev_set_master\n", res);
1403 goto err_close;
1404 }
1405
1406 new_slave->dev = slave_dev; 1406 new_slave->dev = slave_dev;
1407 slave_dev->priv_flags |= IFF_BONDING; 1407 slave_dev->priv_flags |= IFF_BONDING;
1408 1408
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index a89102116ccb..6dcbd25e3ef0 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -301,13 +301,11 @@ int bond_create_slave_symlinks(struct net_device *master, struct net_device *sla
301void bond_destroy_slave_symlinks(struct net_device *master, struct net_device *slave); 301void bond_destroy_slave_symlinks(struct net_device *master, struct net_device *slave);
302int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev); 302int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev);
303int bond_release(struct net_device *bond_dev, struct net_device *slave_dev); 303int bond_release(struct net_device *bond_dev, struct net_device *slave_dev);
304int bond_sethwaddr(struct net_device *bond_dev, struct net_device *slave_dev);
305void bond_mii_monitor(struct net_device *bond_dev); 304void bond_mii_monitor(struct net_device *bond_dev);
306void bond_loadbalance_arp_mon(struct net_device *bond_dev); 305void bond_loadbalance_arp_mon(struct net_device *bond_dev);
307void bond_activebackup_arp_mon(struct net_device *bond_dev); 306void bond_activebackup_arp_mon(struct net_device *bond_dev);
308void bond_set_mode_ops(struct bonding *bond, int mode); 307void bond_set_mode_ops(struct bonding *bond, int mode);
309int bond_parse_parm(char *mode_arg, struct bond_parm_tbl *tbl); 308int bond_parse_parm(char *mode_arg, struct bond_parm_tbl *tbl);
310const char *bond_mode_name(int mode);
311void bond_select_active_slave(struct bonding *bond); 309void bond_select_active_slave(struct bonding *bond);
312void bond_change_active_slave(struct bonding *bond, struct slave *new_active); 310void bond_change_active_slave(struct bonding *bond, struct slave *new_active);
313void bond_register_arp(struct bonding *); 311void bond_register_arp(struct bonding *);
diff --git a/drivers/net/cxgb3/adapter.h b/drivers/net/cxgb3/adapter.h
index 80c3d8f268a7..ab72563b81ee 100644
--- a/drivers/net/cxgb3/adapter.h
+++ b/drivers/net/cxgb3/adapter.h
@@ -71,27 +71,29 @@ enum { /* adapter flags */
71 QUEUES_BOUND = (1 << 3), 71 QUEUES_BOUND = (1 << 3),
72}; 72};
73 73
74struct fl_pg_chunk {
75 struct page *page;
76 void *va;
77 unsigned int offset;
78};
79
74struct rx_desc; 80struct rx_desc;
75struct rx_sw_desc; 81struct rx_sw_desc;
76 82
77struct sge_fl_page { 83struct sge_fl { /* SGE per free-buffer list state */
78 struct skb_frag_struct frag; 84 unsigned int buf_size; /* size of each Rx buffer */
79 unsigned char *va; 85 unsigned int credits; /* # of available Rx buffers */
80}; 86 unsigned int size; /* capacity of free list */
81 87 unsigned int cidx; /* consumer index */
82struct sge_fl { /* SGE per free-buffer list state */ 88 unsigned int pidx; /* producer index */
83 unsigned int buf_size; /* size of each Rx buffer */ 89 unsigned int gen; /* free list generation */
84 unsigned int credits; /* # of available Rx buffers */ 90 struct fl_pg_chunk pg_chunk;/* page chunk cache */
85 unsigned int size; /* capacity of free list */ 91 unsigned int use_pages; /* whether FL uses pages or sk_buffs */
86 unsigned int cidx; /* consumer index */ 92 struct rx_desc *desc; /* address of HW Rx descriptor ring */
87 unsigned int pidx; /* producer index */ 93 struct rx_sw_desc *sdesc; /* address of SW Rx descriptor ring */
88 unsigned int gen; /* free list generation */ 94 dma_addr_t phys_addr; /* physical address of HW ring start */
89 unsigned int cntxt_id; /* SGE context id for the free list */ 95 unsigned int cntxt_id; /* SGE context id for the free list */
90 struct sge_fl_page page; 96 unsigned long empty; /* # of times queue ran out of buffers */
91 struct rx_desc *desc; /* address of HW Rx descriptor ring */
92 struct rx_sw_desc *sdesc; /* address of SW Rx descriptor ring */
93 dma_addr_t phys_addr; /* physical address of HW ring start */
94 unsigned long empty; /* # of times queue ran out of buffers */
95 unsigned long alloc_failed; /* # of times buffer allocation failed */ 97 unsigned long alloc_failed; /* # of times buffer allocation failed */
96}; 98};
97 99
diff --git a/drivers/net/cxgb3/common.h b/drivers/net/cxgb3/common.h
index 8d1379633698..16378004507a 100644
--- a/drivers/net/cxgb3/common.h
+++ b/drivers/net/cxgb3/common.h
@@ -101,6 +101,7 @@ enum {
101 TCB_SIZE = 128, /* TCB size */ 101 TCB_SIZE = 128, /* TCB size */
102 NMTUS = 16, /* size of MTU table */ 102 NMTUS = 16, /* size of MTU table */
103 NCCTRL_WIN = 32, /* # of congestion control windows */ 103 NCCTRL_WIN = 32, /* # of congestion control windows */
104 PROTO_SRAM_LINES = 128, /* size of TP sram */
104}; 105};
105 106
106#define MAX_RX_COALESCING_LEN 16224U 107#define MAX_RX_COALESCING_LEN 16224U
@@ -124,6 +125,30 @@ enum { /* adapter interrupt-maintained statistics */
124}; 125};
125 126
126enum { 127enum {
128 TP_VERSION_MAJOR = 1,
129 TP_VERSION_MINOR = 0,
130 TP_VERSION_MICRO = 44
131};
132
133#define S_TP_VERSION_MAJOR 16
134#define M_TP_VERSION_MAJOR 0xFF
135#define V_TP_VERSION_MAJOR(x) ((x) << S_TP_VERSION_MAJOR)
136#define G_TP_VERSION_MAJOR(x) \
137 (((x) >> S_TP_VERSION_MAJOR) & M_TP_VERSION_MAJOR)
138
139#define S_TP_VERSION_MINOR 8
140#define M_TP_VERSION_MINOR 0xFF
141#define V_TP_VERSION_MINOR(x) ((x) << S_TP_VERSION_MINOR)
142#define G_TP_VERSION_MINOR(x) \
143 (((x) >> S_TP_VERSION_MINOR) & M_TP_VERSION_MINOR)
144
145#define S_TP_VERSION_MICRO 0
146#define M_TP_VERSION_MICRO 0xFF
147#define V_TP_VERSION_MICRO(x) ((x) << S_TP_VERSION_MICRO)
148#define G_TP_VERSION_MICRO(x) \
149 (((x) >> S_TP_VERSION_MICRO) & M_TP_VERSION_MICRO)
150
151enum {
127 SGE_QSETS = 8, /* # of SGE Tx/Rx/RspQ sets */ 152 SGE_QSETS = 8, /* # of SGE Tx/Rx/RspQ sets */
128 SGE_RXQ_PER_SET = 2, /* # of Rx queues per set */ 153 SGE_RXQ_PER_SET = 2, /* # of Rx queues per set */
129 SGE_TXQ_PER_SET = 3 /* # of Tx queues per set */ 154 SGE_TXQ_PER_SET = 3 /* # of Tx queues per set */
@@ -654,6 +679,9 @@ const struct adapter_info *t3_get_adapter_info(unsigned int board_id);
654int t3_seeprom_read(struct adapter *adapter, u32 addr, u32 *data); 679int t3_seeprom_read(struct adapter *adapter, u32 addr, u32 *data);
655int t3_seeprom_write(struct adapter *adapter, u32 addr, u32 data); 680int t3_seeprom_write(struct adapter *adapter, u32 addr, u32 data);
656int t3_seeprom_wp(struct adapter *adapter, int enable); 681int t3_seeprom_wp(struct adapter *adapter, int enable);
682int t3_check_tpsram_version(struct adapter *adapter);
683int t3_check_tpsram(struct adapter *adapter, u8 *tp_ram, unsigned int size);
684int t3_set_proto_sram(struct adapter *adap, u8 *data);
657int t3_read_flash(struct adapter *adapter, unsigned int addr, 685int t3_read_flash(struct adapter *adapter, unsigned int addr,
658 unsigned int nwords, u32 *data, int byte_oriented); 686 unsigned int nwords, u32 *data, int byte_oriented);
659int t3_load_fw(struct adapter *adapter, const u8 * fw_data, unsigned int size); 687int t3_load_fw(struct adapter *adapter, const u8 * fw_data, unsigned int size);
diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c
index d8a1f5452c51..6fd1e5241833 100644
--- a/drivers/net/cxgb3/cxgb3_main.c
+++ b/drivers/net/cxgb3/cxgb3_main.c
@@ -43,6 +43,7 @@
43#include <linux/proc_fs.h> 43#include <linux/proc_fs.h>
44#include <linux/rtnetlink.h> 44#include <linux/rtnetlink.h>
45#include <linux/firmware.h> 45#include <linux/firmware.h>
46#include <linux/log2.h>
46#include <asm/uaccess.h> 47#include <asm/uaccess.h>
47 48
48#include "common.h" 49#include "common.h"
@@ -1818,8 +1819,8 @@ static int cxgb_extension_ioctl(struct net_device *dev, void __user *useraddr)
1818 return -EBUSY; 1819 return -EBUSY;
1819 if (copy_from_user(&m, useraddr, sizeof(m))) 1820 if (copy_from_user(&m, useraddr, sizeof(m)))
1820 return -EFAULT; 1821 return -EFAULT;
1821 if (!m.rx_pg_sz || (m.rx_pg_sz & (m.rx_pg_sz - 1)) || 1822 if (!is_power_of_2(m.rx_pg_sz) ||
1822 !m.tx_pg_sz || (m.tx_pg_sz & (m.tx_pg_sz - 1))) 1823 !is_power_of_2(m.tx_pg_sz))
1823 return -EINVAL; /* not power of 2 */ 1824 return -EINVAL; /* not power of 2 */
1824 if (!(m.rx_pg_sz & 0x14000)) 1825 if (!(m.rx_pg_sz & 0x14000))
1825 return -EINVAL; /* not 16KB or 64KB */ 1826 return -EINVAL; /* not 16KB or 64KB */
@@ -2088,6 +2089,42 @@ static void cxgb_netpoll(struct net_device *dev)
2088} 2089}
2089#endif 2090#endif
2090 2091
2092#define TPSRAM_NAME "t3%c_protocol_sram-%d.%d.%d.bin"
2093int update_tpsram(struct adapter *adap)
2094{
2095 const struct firmware *tpsram;
2096 char buf[64];
2097 struct device *dev = &adap->pdev->dev;
2098 int ret;
2099 char rev;
2100
2101 rev = adap->params.rev == T3_REV_B2 ? 'b' : 'a';
2102
2103 snprintf(buf, sizeof(buf), TPSRAM_NAME, rev,
2104 TP_VERSION_MAJOR, TP_VERSION_MINOR, TP_VERSION_MICRO);
2105
2106 ret = request_firmware(&tpsram, buf, dev);
2107 if (ret < 0) {
2108 dev_err(dev, "could not load TP SRAM: unable to load %s\n",
2109 buf);
2110 return ret;
2111 }
2112
2113 ret = t3_check_tpsram(adap, tpsram->data, tpsram->size);
2114 if (ret)
2115 goto release_tpsram;
2116
2117 ret = t3_set_proto_sram(adap, tpsram->data);
2118 if (ret)
2119 dev_err(dev, "loading protocol SRAM failed\n");
2120
2121release_tpsram:
2122 release_firmware(tpsram);
2123
2124 return ret;
2125}
2126
2127
2091/* 2128/*
2092 * Periodic accumulation of MAC statistics. 2129 * Periodic accumulation of MAC statistics.
2093 */ 2130 */
@@ -2437,6 +2474,13 @@ static int __devinit init_one(struct pci_dev *pdev,
2437 goto out_free_dev; 2474 goto out_free_dev;
2438 } 2475 }
2439 2476
2477 err = t3_check_tpsram_version(adapter);
2478 if (err == -EINVAL)
2479 err = update_tpsram(adapter);
2480
2481 if (err)
2482 goto out_free_dev;
2483
2440 /* 2484 /*
2441 * The card is now ready to go. If any errors occur during device 2485 * The card is now ready to go. If any errors occur during device
2442 * registration we do not fail the whole card but rather proceed only 2486 * registration we do not fail the whole card but rather proceed only
diff --git a/drivers/net/cxgb3/regs.h b/drivers/net/cxgb3/regs.h
index 020859c855d7..aa80313c922e 100644
--- a/drivers/net/cxgb3/regs.h
+++ b/drivers/net/cxgb3/regs.h
@@ -1160,6 +1160,8 @@
1160 1160
1161#define A_TP_MOD_CHANNEL_WEIGHT 0x434 1161#define A_TP_MOD_CHANNEL_WEIGHT 0x434
1162 1162
1163#define A_TP_MOD_RATE_LIMIT 0x438
1164
1163#define A_TP_PIO_ADDR 0x440 1165#define A_TP_PIO_ADDR 0x440
1164 1166
1165#define A_TP_PIO_DATA 0x444 1167#define A_TP_PIO_DATA 0x444
@@ -1214,6 +1216,15 @@
1214#define G_TXDROPCNTCH0RCVD(x) (((x) >> S_TXDROPCNTCH0RCVD) & \ 1216#define G_TXDROPCNTCH0RCVD(x) (((x) >> S_TXDROPCNTCH0RCVD) & \
1215 M_TXDROPCNTCH0RCVD) 1217 M_TXDROPCNTCH0RCVD)
1216 1218
1219#define A_TP_PROXY_FLOW_CNTL 0x4b0
1220
1221#define A_TP_EMBED_OP_FIELD0 0x4e8
1222#define A_TP_EMBED_OP_FIELD1 0x4ec
1223#define A_TP_EMBED_OP_FIELD2 0x4f0
1224#define A_TP_EMBED_OP_FIELD3 0x4f4
1225#define A_TP_EMBED_OP_FIELD4 0x4f8
1226#define A_TP_EMBED_OP_FIELD5 0x4fc
1227
1217#define A_ULPRX_CTL 0x500 1228#define A_ULPRX_CTL 0x500
1218 1229
1219#define S_ROUND_ROBIN 4 1230#define S_ROUND_ROBIN 4
diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c
index a60ec4d4707c..a2cfd68ac757 100644
--- a/drivers/net/cxgb3/sge.c
+++ b/drivers/net/cxgb3/sge.c
@@ -46,23 +46,16 @@
46 46
47#define SGE_RX_SM_BUF_SIZE 1536 47#define SGE_RX_SM_BUF_SIZE 1536
48 48
49/*
50 * If USE_RX_PAGE is defined, the small freelist populated with (partial)
51 * pages instead of skbs. Pages are carved up into RX_PAGE_SIZE chunks (must
52 * be a multiple of the host page size).
53 */
54#define USE_RX_PAGE
55#define RX_PAGE_SIZE 2048
56
57/*
58 * skb freelist packets are copied into a new skb (and the freelist one is
59 * reused) if their len is <=
60 */
61#define SGE_RX_COPY_THRES 256 49#define SGE_RX_COPY_THRES 256
50#define SGE_RX_PULL_LEN 128
62 51
63/* 52/*
64 * Minimum number of freelist entries before we start dropping TUNNEL frames. 53 * Page chunk size for FL0 buffers if FL0 is to be populated with page chunks.
54 * It must be a divisor of PAGE_SIZE. If set to 0 FL0 will use sk_buffs
55 * directly.
65 */ 56 */
57#define FL0_PG_CHUNK_SIZE 2048
58
66#define SGE_RX_DROP_THRES 16 59#define SGE_RX_DROP_THRES 16
67 60
68/* 61/*
@@ -100,12 +93,12 @@ struct tx_sw_desc { /* SW state per Tx descriptor */
100 struct sk_buff *skb; 93 struct sk_buff *skb;
101}; 94};
102 95
103struct rx_sw_desc { /* SW state per Rx descriptor */ 96struct rx_sw_desc { /* SW state per Rx descriptor */
104 union { 97 union {
105 struct sk_buff *skb; 98 struct sk_buff *skb;
106 struct sge_fl_page page; 99 struct fl_pg_chunk pg_chunk;
107 } t; 100 };
108 DECLARE_PCI_UNMAP_ADDR(dma_addr); 101 DECLARE_PCI_UNMAP_ADDR(dma_addr);
109}; 102};
110 103
111struct rsp_desc { /* response queue descriptor */ 104struct rsp_desc { /* response queue descriptor */
@@ -351,27 +344,26 @@ static void free_rx_bufs(struct pci_dev *pdev, struct sge_fl *q)
351 344
352 pci_unmap_single(pdev, pci_unmap_addr(d, dma_addr), 345 pci_unmap_single(pdev, pci_unmap_addr(d, dma_addr),
353 q->buf_size, PCI_DMA_FROMDEVICE); 346 q->buf_size, PCI_DMA_FROMDEVICE);
354 347 if (q->use_pages) {
355 if (q->buf_size != RX_PAGE_SIZE) { 348 put_page(d->pg_chunk.page);
356 kfree_skb(d->t.skb); 349 d->pg_chunk.page = NULL;
357 d->t.skb = NULL;
358 } else { 350 } else {
359 if (d->t.page.frag.page) 351 kfree_skb(d->skb);
360 put_page(d->t.page.frag.page); 352 d->skb = NULL;
361 d->t.page.frag.page = NULL;
362 } 353 }
363 if (++cidx == q->size) 354 if (++cidx == q->size)
364 cidx = 0; 355 cidx = 0;
365 } 356 }
366 357
367 if (q->page.frag.page) 358 if (q->pg_chunk.page) {
368 put_page(q->page.frag.page); 359 __free_page(q->pg_chunk.page);
369 q->page.frag.page = NULL; 360 q->pg_chunk.page = NULL;
361 }
370} 362}
371 363
372/** 364/**
373 * add_one_rx_buf - add a packet buffer to a free-buffer list 365 * add_one_rx_buf - add a packet buffer to a free-buffer list
374 * @va: va of the buffer to add 366 * @va: buffer start VA
375 * @len: the buffer length 367 * @len: the buffer length
376 * @d: the HW Rx descriptor to write 368 * @d: the HW Rx descriptor to write
377 * @sd: the SW Rx descriptor to write 369 * @sd: the SW Rx descriptor to write
@@ -381,7 +373,7 @@ static void free_rx_bufs(struct pci_dev *pdev, struct sge_fl *q)
381 * Add a buffer of the given length to the supplied HW and SW Rx 373 * Add a buffer of the given length to the supplied HW and SW Rx
382 * descriptors. 374 * descriptors.
383 */ 375 */
384static inline void add_one_rx_buf(unsigned char *va, unsigned int len, 376static inline void add_one_rx_buf(void *va, unsigned int len,
385 struct rx_desc *d, struct rx_sw_desc *sd, 377 struct rx_desc *d, struct rx_sw_desc *sd,
386 unsigned int gen, struct pci_dev *pdev) 378 unsigned int gen, struct pci_dev *pdev)
387{ 379{
@@ -397,6 +389,27 @@ static inline void add_one_rx_buf(unsigned char *va, unsigned int len,
397 d->gen2 = cpu_to_be32(V_FLD_GEN2(gen)); 389 d->gen2 = cpu_to_be32(V_FLD_GEN2(gen));
398} 390}
399 391
392static int alloc_pg_chunk(struct sge_fl *q, struct rx_sw_desc *sd, gfp_t gfp)
393{
394 if (!q->pg_chunk.page) {
395 q->pg_chunk.page = alloc_page(gfp);
396 if (unlikely(!q->pg_chunk.page))
397 return -ENOMEM;
398 q->pg_chunk.va = page_address(q->pg_chunk.page);
399 q->pg_chunk.offset = 0;
400 }
401 sd->pg_chunk = q->pg_chunk;
402
403 q->pg_chunk.offset += q->buf_size;
404 if (q->pg_chunk.offset == PAGE_SIZE)
405 q->pg_chunk.page = NULL;
406 else {
407 q->pg_chunk.va += q->buf_size;
408 get_page(q->pg_chunk.page);
409 }
410 return 0;
411}
412
400/** 413/**
401 * refill_fl - refill an SGE free-buffer list 414 * refill_fl - refill an SGE free-buffer list
402 * @adapter: the adapter 415 * @adapter: the adapter
@@ -410,49 +423,29 @@ static inline void add_one_rx_buf(unsigned char *va, unsigned int len,
410 */ 423 */
411static void refill_fl(struct adapter *adap, struct sge_fl *q, int n, gfp_t gfp) 424static void refill_fl(struct adapter *adap, struct sge_fl *q, int n, gfp_t gfp)
412{ 425{
426 void *buf_start;
413 struct rx_sw_desc *sd = &q->sdesc[q->pidx]; 427 struct rx_sw_desc *sd = &q->sdesc[q->pidx];
414 struct rx_desc *d = &q->desc[q->pidx]; 428 struct rx_desc *d = &q->desc[q->pidx];
415 struct sge_fl_page *p = &q->page;
416 429
417 while (n--) { 430 while (n--) {
418 unsigned char *va; 431 if (q->use_pages) {
419 432 if (unlikely(alloc_pg_chunk(q, sd, gfp))) {
420 if (unlikely(q->buf_size != RX_PAGE_SIZE)) { 433nomem: q->alloc_failed++;
421 struct sk_buff *skb = alloc_skb(q->buf_size, gfp);
422
423 if (!skb) {
424 q->alloc_failed++;
425 break; 434 break;
426 } 435 }
427 va = skb->data; 436 buf_start = sd->pg_chunk.va;
428 sd->t.skb = skb;
429 } else { 437 } else {
430 if (!p->frag.page) { 438 struct sk_buff *skb = alloc_skb(q->buf_size, gfp);
431 p->frag.page = alloc_pages(gfp, 0);
432 if (unlikely(!p->frag.page)) {
433 q->alloc_failed++;
434 break;
435 } else {
436 p->frag.size = RX_PAGE_SIZE;
437 p->frag.page_offset = 0;
438 p->va = page_address(p->frag.page);
439 }
440 }
441 439
442 memcpy(&sd->t, p, sizeof(*p)); 440 if (!skb)
443 va = p->va; 441 goto nomem;
444 442
445 p->frag.page_offset += RX_PAGE_SIZE; 443 sd->skb = skb;
446 BUG_ON(p->frag.page_offset > PAGE_SIZE); 444 buf_start = skb->data;
447 p->va += RX_PAGE_SIZE;
448 if (p->frag.page_offset == PAGE_SIZE)
449 p->frag.page = NULL;
450 else
451 get_page(p->frag.page);
452 } 445 }
453 446
454 add_one_rx_buf(va, q->buf_size, d, sd, q->gen, adap->pdev); 447 add_one_rx_buf(buf_start, q->buf_size, d, sd, q->gen,
455 448 adap->pdev);
456 d++; 449 d++;
457 sd++; 450 sd++;
458 if (++q->pidx == q->size) { 451 if (++q->pidx == q->size) {
@@ -487,7 +480,7 @@ static void recycle_rx_buf(struct adapter *adap, struct sge_fl *q,
487 struct rx_desc *from = &q->desc[idx]; 480 struct rx_desc *from = &q->desc[idx];
488 struct rx_desc *to = &q->desc[q->pidx]; 481 struct rx_desc *to = &q->desc[q->pidx];
489 482
490 memcpy(&q->sdesc[q->pidx], &q->sdesc[idx], sizeof(struct rx_sw_desc)); 483 q->sdesc[q->pidx] = q->sdesc[idx];
491 to->addr_lo = from->addr_lo; /* already big endian */ 484 to->addr_lo = from->addr_lo; /* already big endian */
492 to->addr_hi = from->addr_hi; /* likewise */ 485 to->addr_hi = from->addr_hi; /* likewise */
493 wmb(); 486 wmb();
@@ -650,6 +643,132 @@ static inline unsigned int flits_to_desc(unsigned int n)
650} 643}
651 644
652/** 645/**
646 * get_packet - return the next ingress packet buffer from a free list
647 * @adap: the adapter that received the packet
648 * @fl: the SGE free list holding the packet
649 * @len: the packet length including any SGE padding
650 * @drop_thres: # of remaining buffers before we start dropping packets
651 *
652 * Get the next packet from a free list and complete setup of the
653 * sk_buff. If the packet is small we make a copy and recycle the
654 * original buffer, otherwise we use the original buffer itself. If a
655 * positive drop threshold is supplied packets are dropped and their
656 * buffers recycled if (a) the number of remaining buffers is under the
657 * threshold and the packet is too big to copy, or (b) the packet should
658 * be copied but there is no memory for the copy.
659 */
660static struct sk_buff *get_packet(struct adapter *adap, struct sge_fl *fl,
661 unsigned int len, unsigned int drop_thres)
662{
663 struct sk_buff *skb = NULL;
664 struct rx_sw_desc *sd = &fl->sdesc[fl->cidx];
665
666 prefetch(sd->skb->data);
667 fl->credits--;
668
669 if (len <= SGE_RX_COPY_THRES) {
670 skb = alloc_skb(len, GFP_ATOMIC);
671 if (likely(skb != NULL)) {
672 __skb_put(skb, len);
673 pci_dma_sync_single_for_cpu(adap->pdev,
674 pci_unmap_addr(sd, dma_addr), len,
675 PCI_DMA_FROMDEVICE);
676 memcpy(skb->data, sd->skb->data, len);
677 pci_dma_sync_single_for_device(adap->pdev,
678 pci_unmap_addr(sd, dma_addr), len,
679 PCI_DMA_FROMDEVICE);
680 } else if (!drop_thres)
681 goto use_orig_buf;
682recycle:
683 recycle_rx_buf(adap, fl, fl->cidx);
684 return skb;
685 }
686
687 if (unlikely(fl->credits < drop_thres))
688 goto recycle;
689
690use_orig_buf:
691 pci_unmap_single(adap->pdev, pci_unmap_addr(sd, dma_addr),
692 fl->buf_size, PCI_DMA_FROMDEVICE);
693 skb = sd->skb;
694 skb_put(skb, len);
695 __refill_fl(adap, fl);
696 return skb;
697}
698
699/**
700 * get_packet_pg - return the next ingress packet buffer from a free list
701 * @adap: the adapter that received the packet
702 * @fl: the SGE free list holding the packet
703 * @len: the packet length including any SGE padding
704 * @drop_thres: # of remaining buffers before we start dropping packets
705 *
706 * Get the next packet from a free list populated with page chunks.
707 * If the packet is small we make a copy and recycle the original buffer,
708 * otherwise we attach the original buffer as a page fragment to a fresh
709 * sk_buff. If a positive drop threshold is supplied packets are dropped
710 * and their buffers recycled if (a) the number of remaining buffers is
711 * under the threshold and the packet is too big to copy, or (b) there's
712 * no system memory.
713 *
714 * Note: this function is similar to @get_packet but deals with Rx buffers
715 * that are page chunks rather than sk_buffs.
716 */
717static struct sk_buff *get_packet_pg(struct adapter *adap, struct sge_fl *fl,
718 unsigned int len, unsigned int drop_thres)
719{
720 struct sk_buff *skb = NULL;
721 struct rx_sw_desc *sd = &fl->sdesc[fl->cidx];
722
723 if (len <= SGE_RX_COPY_THRES) {
724 skb = alloc_skb(len, GFP_ATOMIC);
725 if (likely(skb != NULL)) {
726 __skb_put(skb, len);
727 pci_dma_sync_single_for_cpu(adap->pdev,
728 pci_unmap_addr(sd, dma_addr), len,
729 PCI_DMA_FROMDEVICE);
730 memcpy(skb->data, sd->pg_chunk.va, len);
731 pci_dma_sync_single_for_device(adap->pdev,
732 pci_unmap_addr(sd, dma_addr), len,
733 PCI_DMA_FROMDEVICE);
734 } else if (!drop_thres)
735 return NULL;
736recycle:
737 fl->credits--;
738 recycle_rx_buf(adap, fl, fl->cidx);
739 return skb;
740 }
741
742 if (unlikely(fl->credits <= drop_thres))
743 goto recycle;
744
745 skb = alloc_skb(SGE_RX_PULL_LEN, GFP_ATOMIC);
746 if (unlikely(!skb)) {
747 if (!drop_thres)
748 return NULL;
749 goto recycle;
750 }
751
752 pci_unmap_single(adap->pdev, pci_unmap_addr(sd, dma_addr),
753 fl->buf_size, PCI_DMA_FROMDEVICE);
754 __skb_put(skb, SGE_RX_PULL_LEN);
755 memcpy(skb->data, sd->pg_chunk.va, SGE_RX_PULL_LEN);
756 skb_fill_page_desc(skb, 0, sd->pg_chunk.page,
757 sd->pg_chunk.offset + SGE_RX_PULL_LEN,
758 len - SGE_RX_PULL_LEN);
759 skb->len = len;
760 skb->data_len = len - SGE_RX_PULL_LEN;
761 skb->truesize += skb->data_len;
762
763 fl->credits--;
764 /*
765 * We do not refill FLs here, we let the caller do it to overlap a
766 * prefetch.
767 */
768 return skb;
769}
770
771/**
653 * get_imm_packet - return the next ingress packet buffer from a response 772 * get_imm_packet - return the next ingress packet buffer from a response
654 * @resp: the response descriptor containing the packet data 773 * @resp: the response descriptor containing the packet data
655 * 774 *
@@ -1715,85 +1834,6 @@ static void rx_eth(struct adapter *adap, struct sge_rspq *rq,
1715 netif_rx(skb); 1834 netif_rx(skb);
1716} 1835}
1717 1836
1718#define SKB_DATA_SIZE 128
1719
1720static void skb_data_init(struct sk_buff *skb, struct sge_fl_page *p,
1721 unsigned int len)
1722{
1723 skb->len = len;
1724 if (len <= SKB_DATA_SIZE) {
1725 skb_copy_to_linear_data(skb, p->va, len);
1726 skb->tail += len;
1727 put_page(p->frag.page);
1728 } else {
1729 skb_copy_to_linear_data(skb, p->va, SKB_DATA_SIZE);
1730 skb_shinfo(skb)->frags[0].page = p->frag.page;
1731 skb_shinfo(skb)->frags[0].page_offset =
1732 p->frag.page_offset + SKB_DATA_SIZE;
1733 skb_shinfo(skb)->frags[0].size = len - SKB_DATA_SIZE;
1734 skb_shinfo(skb)->nr_frags = 1;
1735 skb->data_len = len - SKB_DATA_SIZE;
1736 skb->tail += SKB_DATA_SIZE;
1737 skb->truesize += skb->data_len;
1738 }
1739}
1740
1741/**
1742* get_packet - return the next ingress packet buffer from a free list
1743* @adap: the adapter that received the packet
1744* @fl: the SGE free list holding the packet
1745* @len: the packet length including any SGE padding
1746* @drop_thres: # of remaining buffers before we start dropping packets
1747*
1748* Get the next packet from a free list and complete setup of the
1749* sk_buff. If the packet is small we make a copy and recycle the
1750* original buffer, otherwise we use the original buffer itself. If a
1751* positive drop threshold is supplied packets are dropped and their
1752* buffers recycled if (a) the number of remaining buffers is under the
1753* threshold and the packet is too big to copy, or (b) the packet should
1754* be copied but there is no memory for the copy.
1755*/
1756static struct sk_buff *get_packet(struct adapter *adap, struct sge_fl *fl,
1757 unsigned int len, unsigned int drop_thres)
1758{
1759 struct sk_buff *skb = NULL;
1760 struct rx_sw_desc *sd = &fl->sdesc[fl->cidx];
1761
1762 prefetch(sd->t.skb->data);
1763
1764 if (len <= SGE_RX_COPY_THRES) {
1765 skb = alloc_skb(len, GFP_ATOMIC);
1766 if (likely(skb != NULL)) {
1767 struct rx_desc *d = &fl->desc[fl->cidx];
1768 dma_addr_t mapping =
1769 (dma_addr_t)((u64) be32_to_cpu(d->addr_hi) << 32 |
1770 be32_to_cpu(d->addr_lo));
1771
1772 __skb_put(skb, len);
1773 pci_dma_sync_single_for_cpu(adap->pdev, mapping, len,
1774 PCI_DMA_FROMDEVICE);
1775 skb_copy_from_linear_data(sd->t.skb, skb->data, len);
1776 pci_dma_sync_single_for_device(adap->pdev, mapping, len,
1777 PCI_DMA_FROMDEVICE);
1778 } else if (!drop_thres)
1779 goto use_orig_buf;
1780recycle:
1781 recycle_rx_buf(adap, fl, fl->cidx);
1782 return skb;
1783 }
1784
1785 if (unlikely(fl->credits < drop_thres))
1786 goto recycle;
1787
1788use_orig_buf:
1789 pci_unmap_single(adap->pdev, pci_unmap_addr(sd, dma_addr),
1790 fl->buf_size, PCI_DMA_FROMDEVICE);
1791 skb = sd->t.skb;
1792 skb_put(skb, len);
1793 __refill_fl(adap, fl);
1794 return skb;
1795}
1796
1797/** 1837/**
1798 * handle_rsp_cntrl_info - handles control information in a response 1838 * handle_rsp_cntrl_info - handles control information in a response
1799 * @qs: the queue set corresponding to the response 1839 * @qs: the queue set corresponding to the response
@@ -1935,7 +1975,7 @@ static int process_responses(struct adapter *adap, struct sge_qset *qs,
1935 } else if (flags & F_RSPD_IMM_DATA_VALID) { 1975 } else if (flags & F_RSPD_IMM_DATA_VALID) {
1936 skb = get_imm_packet(r); 1976 skb = get_imm_packet(r);
1937 if (unlikely(!skb)) { 1977 if (unlikely(!skb)) {
1938 no_mem: 1978no_mem:
1939 q->next_holdoff = NOMEM_INTR_DELAY; 1979 q->next_holdoff = NOMEM_INTR_DELAY;
1940 q->nomem++; 1980 q->nomem++;
1941 /* consume one credit since we tried */ 1981 /* consume one credit since we tried */
@@ -1945,53 +1985,29 @@ static int process_responses(struct adapter *adap, struct sge_qset *qs,
1945 q->imm_data++; 1985 q->imm_data++;
1946 ethpad = 0; 1986 ethpad = 0;
1947 } else if ((len = ntohl(r->len_cq)) != 0) { 1987 } else if ((len = ntohl(r->len_cq)) != 0) {
1948 struct sge_fl *fl = 1988 struct sge_fl *fl;
1949 (len & F_RSPD_FLQ) ? &qs->fl[1] : &qs->fl[0];
1950 1989
1951 if (fl->buf_size == RX_PAGE_SIZE) { 1990 fl = (len & F_RSPD_FLQ) ? &qs->fl[1] : &qs->fl[0];
1952 struct rx_sw_desc *sd = &fl->sdesc[fl->cidx]; 1991 if (fl->use_pages) {
1953 struct sge_fl_page *p = &sd->t.page; 1992 void *addr = fl->sdesc[fl->cidx].pg_chunk.va;
1954
1955 prefetch(p->va);
1956 prefetch(p->va + L1_CACHE_BYTES);
1957 1993
1994 prefetch(addr);
1995#if L1_CACHE_BYTES < 128
1996 prefetch(addr + L1_CACHE_BYTES);
1997#endif
1958 __refill_fl(adap, fl); 1998 __refill_fl(adap, fl);
1959 1999
1960 pci_unmap_single(adap->pdev, 2000 skb = get_packet_pg(adap, fl, G_RSPD_LEN(len),
1961 pci_unmap_addr(sd, dma_addr), 2001 eth ? SGE_RX_DROP_THRES : 0);
1962 fl->buf_size, 2002 } else
1963 PCI_DMA_FROMDEVICE);
1964
1965 if (eth) {
1966 if (unlikely(fl->credits <
1967 SGE_RX_DROP_THRES))
1968 goto eth_recycle;
1969
1970 skb = alloc_skb(SKB_DATA_SIZE,
1971 GFP_ATOMIC);
1972 if (unlikely(!skb)) {
1973eth_recycle:
1974 q->rx_drops++;
1975 recycle_rx_buf(adap, fl,
1976 fl->cidx);
1977 goto eth_done;
1978 }
1979 } else {
1980 skb = alloc_skb(SKB_DATA_SIZE,
1981 GFP_ATOMIC);
1982 if (unlikely(!skb))
1983 goto no_mem;
1984 }
1985
1986 skb_data_init(skb, p, G_RSPD_LEN(len));
1987eth_done:
1988 fl->credits--;
1989 q->eth_pkts++;
1990 } else {
1991 fl->credits--;
1992 skb = get_packet(adap, fl, G_RSPD_LEN(len), 2003 skb = get_packet(adap, fl, G_RSPD_LEN(len),
1993 eth ? SGE_RX_DROP_THRES : 0); 2004 eth ? SGE_RX_DROP_THRES : 0);
1994 } 2005 if (unlikely(!skb)) {
2006 if (!eth)
2007 goto no_mem;
2008 q->rx_drops++;
2009 } else if (unlikely(r->rss_hdr.opcode == CPL_TRACE_PKT))
2010 __skb_pull(skb, 2);
1995 2011
1996 if (++fl->cidx == fl->size) 2012 if (++fl->cidx == fl->size)
1997 fl->cidx = 0; 2013 fl->cidx = 0;
@@ -2016,20 +2032,15 @@ eth_done:
2016 q->credits = 0; 2032 q->credits = 0;
2017 } 2033 }
2018 2034
2019 if (skb) { 2035 if (likely(skb != NULL)) {
2020 /* Preserve the RSS info in csum & priority */
2021 skb->csum = rss_hi;
2022 skb->priority = rss_lo;
2023
2024 if (eth) 2036 if (eth)
2025 rx_eth(adap, q, skb, ethpad); 2037 rx_eth(adap, q, skb, ethpad);
2026 else { 2038 else {
2027 if (unlikely(r->rss_hdr.opcode == 2039 /* Preserve the RSS info in csum & priority */
2028 CPL_TRACE_PKT)) 2040 skb->csum = rss_hi;
2029 __skb_pull(skb, ethpad); 2041 skb->priority = rss_lo;
2030 2042 ngathered = rx_offload(&adap->tdev, q, skb,
2031 ngathered = rx_offload(&adap->tdev, q, 2043 offload_skbs,
2032 skb, offload_skbs,
2033 ngathered); 2044 ngathered);
2034 } 2045 }
2035 } 2046 }
@@ -2635,25 +2646,15 @@ int t3_sge_alloc_qset(struct adapter *adapter, unsigned int id, int nports,
2635 q->txq[TXQ_ETH].stop_thres = nports * 2646 q->txq[TXQ_ETH].stop_thres = nports *
2636 flits_to_desc(sgl_len(MAX_SKB_FRAGS + 1) + 3); 2647 flits_to_desc(sgl_len(MAX_SKB_FRAGS + 1) + 3);
2637 2648
2638 if (!is_offload(adapter)) { 2649#if FL0_PG_CHUNK_SIZE > 0
2639#ifdef USE_RX_PAGE 2650 q->fl[0].buf_size = FL0_PG_CHUNK_SIZE;
2640 q->fl[0].buf_size = RX_PAGE_SIZE;
2641#else 2651#else
2642 q->fl[0].buf_size = SGE_RX_SM_BUF_SIZE + 2 + 2652 q->fl[0].buf_size = SGE_RX_SM_BUF_SIZE + sizeof(struct cpl_rx_data);
2643 sizeof(struct cpl_rx_pkt);
2644#endif 2653#endif
2645 q->fl[1].buf_size = MAX_FRAME_SIZE + 2 + 2654 q->fl[0].use_pages = FL0_PG_CHUNK_SIZE > 0;
2646 sizeof(struct cpl_rx_pkt); 2655 q->fl[1].buf_size = is_offload(adapter) ?
2647 } else { 2656 (16 * 1024) - SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) :
2648#ifdef USE_RX_PAGE 2657 MAX_FRAME_SIZE + 2 + sizeof(struct cpl_rx_pkt);
2649 q->fl[0].buf_size = RX_PAGE_SIZE;
2650#else
2651 q->fl[0].buf_size = SGE_RX_SM_BUF_SIZE +
2652 sizeof(struct cpl_rx_data);
2653#endif
2654 q->fl[1].buf_size = (16 * 1024) -
2655 SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
2656 }
2657 2658
2658 spin_lock(&adapter->sge.reg_lock); 2659 spin_lock(&adapter->sge.reg_lock);
2659 2660
diff --git a/drivers/net/cxgb3/t3_hw.c b/drivers/net/cxgb3/t3_hw.c
index fb485d0a43d8..dd3149d94ba8 100644
--- a/drivers/net/cxgb3/t3_hw.c
+++ b/drivers/net/cxgb3/t3_hw.c
@@ -847,6 +847,64 @@ static int t3_write_flash(struct adapter *adapter, unsigned int addr,
847 return 0; 847 return 0;
848} 848}
849 849
850/**
851 * t3_check_tpsram_version - read the tp sram version
852 * @adapter: the adapter
853 *
854 * Reads the protocol sram version from serial eeprom.
855 */
856int t3_check_tpsram_version(struct adapter *adapter)
857{
858 int ret;
859 u32 vers;
860 unsigned int major, minor;
861
862 /* Get version loaded in SRAM */
863 t3_write_reg(adapter, A_TP_EMBED_OP_FIELD0, 0);
864 ret = t3_wait_op_done(adapter, A_TP_EMBED_OP_FIELD0,
865 1, 1, 5, 1);
866 if (ret)
867 return ret;
868
869 vers = t3_read_reg(adapter, A_TP_EMBED_OP_FIELD1);
870
871 major = G_TP_VERSION_MAJOR(vers);
872 minor = G_TP_VERSION_MINOR(vers);
873
874 if (major == TP_VERSION_MAJOR && minor == TP_VERSION_MINOR)
875 return 0;
876
877 return -EINVAL;
878}
879
880/**
881 * t3_check_tpsram - check if provided protocol SRAM
882 * is compatible with this driver
883 * @adapter: the adapter
884 * @tp_sram: the firmware image to write
885 * @size: image size
886 *
887 * Checks if an adapter's tp sram is compatible with the driver.
888 * Returns 0 if the versions are compatible, a negative error otherwise.
889 */
890int t3_check_tpsram(struct adapter *adapter, u8 *tp_sram, unsigned int size)
891{
892 u32 csum;
893 unsigned int i;
894 const u32 *p = (const u32 *)tp_sram;
895
896 /* Verify checksum */
897 for (csum = 0, i = 0; i < size / sizeof(csum); i++)
898 csum += ntohl(p[i]);
899 if (csum != 0xffffffff) {
900 CH_ERR(adapter, "corrupted protocol SRAM image, checksum %u\n",
901 csum);
902 return -EINVAL;
903 }
904
905 return 0;
906}
907
850enum fw_version_type { 908enum fw_version_type {
851 FW_VERSION_N3, 909 FW_VERSION_N3,
852 FW_VERSION_T3 910 FW_VERSION_T3
@@ -921,7 +979,7 @@ static int t3_flash_erase_sectors(struct adapter *adapter, int start, int end)
921/* 979/*
922 * t3_load_fw - download firmware 980 * t3_load_fw - download firmware
923 * @adapter: the adapter 981 * @adapter: the adapter
924 * @fw_data: the firrware image to write 982 * @fw_data: the firmware image to write
925 * @size: image size 983 * @size: image size
926 * 984 *
927 * Write the supplied firmware image to the card's serial flash. 985 * Write the supplied firmware image to the card's serial flash.
@@ -2362,7 +2420,7 @@ static void tp_config(struct adapter *adap, const struct tp_params *p)
2362 F_TCPCHECKSUMOFFLOAD | V_IPTTL(64)); 2420 F_TCPCHECKSUMOFFLOAD | V_IPTTL(64));
2363 t3_write_reg(adap, A_TP_TCP_OPTIONS, V_MTUDEFAULT(576) | 2421 t3_write_reg(adap, A_TP_TCP_OPTIONS, V_MTUDEFAULT(576) |
2364 F_MTUENABLE | V_WINDOWSCALEMODE(1) | 2422 F_MTUENABLE | V_WINDOWSCALEMODE(1) |
2365 V_TIMESTAMPSMODE(1) | V_SACKMODE(1) | V_SACKRX(1)); 2423 V_TIMESTAMPSMODE(0) | V_SACKMODE(1) | V_SACKRX(1));
2366 t3_write_reg(adap, A_TP_DACK_CONFIG, V_AUTOSTATE3(1) | 2424 t3_write_reg(adap, A_TP_DACK_CONFIG, V_AUTOSTATE3(1) |
2367 V_AUTOSTATE2(1) | V_AUTOSTATE1(0) | 2425 V_AUTOSTATE2(1) | V_AUTOSTATE1(0) |
2368 V_BYTETHRESHOLD(16384) | V_MSSTHRESHOLD(2) | 2426 V_BYTETHRESHOLD(16384) | V_MSSTHRESHOLD(2) |
@@ -2371,16 +2429,18 @@ static void tp_config(struct adapter *adap, const struct tp_params *p)
2371 F_IPV6ENABLE | F_NICMODE); 2429 F_IPV6ENABLE | F_NICMODE);
2372 t3_write_reg(adap, A_TP_TX_RESOURCE_LIMIT, 0x18141814); 2430 t3_write_reg(adap, A_TP_TX_RESOURCE_LIMIT, 0x18141814);
2373 t3_write_reg(adap, A_TP_PARA_REG4, 0x5050105); 2431 t3_write_reg(adap, A_TP_PARA_REG4, 0x5050105);
2374 t3_set_reg_field(adap, A_TP_PARA_REG6, 2432 t3_set_reg_field(adap, A_TP_PARA_REG6, 0,
2375 adap->params.rev > 0 ? F_ENABLEESND : F_T3A_ENABLEESND, 2433 adap->params.rev > 0 ? F_ENABLEESND :
2376 0); 2434 F_T3A_ENABLEESND);
2377 2435
2378 t3_set_reg_field(adap, A_TP_PC_CONFIG, 2436 t3_set_reg_field(adap, A_TP_PC_CONFIG,
2379 F_ENABLEEPCMDAFULL | F_ENABLEOCSPIFULL, 2437 F_ENABLEEPCMDAFULL,
2380 F_TXDEFERENABLE | F_HEARBEATDACK | F_TXCONGESTIONMODE | 2438 F_ENABLEOCSPIFULL |F_TXDEFERENABLE | F_HEARBEATDACK |
2381 F_RXCONGESTIONMODE); 2439 F_TXCONGESTIONMODE | F_RXCONGESTIONMODE);
2382 t3_set_reg_field(adap, A_TP_PC_CONFIG2, F_CHDRAFULL, 0); 2440 t3_set_reg_field(adap, A_TP_PC_CONFIG2, F_CHDRAFULL, 0);
2383 2441 t3_write_reg(adap, A_TP_PROXY_FLOW_CNTL, 1080);
2442 t3_write_reg(adap, A_TP_PROXY_FLOW_CNTL, 1000);
2443
2384 if (adap->params.rev > 0) { 2444 if (adap->params.rev > 0) {
2385 tp_wr_indirect(adap, A_TP_EGRESS_CONFIG, F_REWRITEFORCETOSIZE); 2445 tp_wr_indirect(adap, A_TP_EGRESS_CONFIG, F_REWRITEFORCETOSIZE);
2386 t3_set_reg_field(adap, A_TP_PARA_REG3, F_TXPACEAUTO, 2446 t3_set_reg_field(adap, A_TP_PARA_REG3, F_TXPACEAUTO,
@@ -2390,9 +2450,10 @@ static void tp_config(struct adapter *adap, const struct tp_params *p)
2390 } else 2450 } else
2391 t3_set_reg_field(adap, A_TP_PARA_REG3, 0, F_TXPACEFIXED); 2451 t3_set_reg_field(adap, A_TP_PARA_REG3, 0, F_TXPACEFIXED);
2392 2452
2393 t3_write_reg(adap, A_TP_TX_MOD_QUEUE_WEIGHT1, 0x12121212); 2453 t3_write_reg(adap, A_TP_TX_MOD_QUEUE_WEIGHT1, 0);
2394 t3_write_reg(adap, A_TP_TX_MOD_QUEUE_WEIGHT0, 0x12121212); 2454 t3_write_reg(adap, A_TP_TX_MOD_QUEUE_WEIGHT0, 0);
2395 t3_write_reg(adap, A_TP_MOD_CHANNEL_WEIGHT, 0x1212); 2455 t3_write_reg(adap, A_TP_MOD_CHANNEL_WEIGHT, 0);
2456 t3_write_reg(adap, A_TP_MOD_RATE_LIMIT, 0xf2200000);
2396} 2457}
2397 2458
2398/* Desired TP timer resolution in usec */ 2459/* Desired TP timer resolution in usec */
@@ -2468,6 +2529,7 @@ int t3_tp_set_coalescing_size(struct adapter *adap, unsigned int size, int psh)
2468 val |= F_RXCOALESCEENABLE; 2529 val |= F_RXCOALESCEENABLE;
2469 if (psh) 2530 if (psh)
2470 val |= F_RXCOALESCEPSHEN; 2531 val |= F_RXCOALESCEPSHEN;
2532 size = min(MAX_RX_COALESCING_LEN, size);
2471 t3_write_reg(adap, A_TP_PARA_REG2, V_RXCOALESCESIZE(size) | 2533 t3_write_reg(adap, A_TP_PARA_REG2, V_RXCOALESCESIZE(size) |
2472 V_MAXRXDATA(MAX_RX_COALESCING_LEN)); 2534 V_MAXRXDATA(MAX_RX_COALESCING_LEN));
2473 } 2535 }
@@ -2496,11 +2558,11 @@ static void __devinit init_mtus(unsigned short mtus[])
2496 * it can accomodate max size TCP/IP headers when SACK and timestamps 2558 * it can accomodate max size TCP/IP headers when SACK and timestamps
2497 * are enabled and still have at least 8 bytes of payload. 2559 * are enabled and still have at least 8 bytes of payload.
2498 */ 2560 */
2499 mtus[0] = 88; 2561 mtus[1] = 88;
2500 mtus[1] = 256; 2562 mtus[1] = 88;
2501 mtus[2] = 512; 2563 mtus[2] = 256;
2502 mtus[3] = 576; 2564 mtus[3] = 512;
2503 mtus[4] = 808; 2565 mtus[4] = 576;
2504 mtus[5] = 1024; 2566 mtus[5] = 1024;
2505 mtus[6] = 1280; 2567 mtus[6] = 1280;
2506 mtus[7] = 1492; 2568 mtus[7] = 1492;
@@ -2682,6 +2744,34 @@ static void ulp_config(struct adapter *adap, const struct tp_params *p)
2682 t3_write_reg(adap, A_ULPRX_TDDP_TAGMASK, 0xffffffff); 2744 t3_write_reg(adap, A_ULPRX_TDDP_TAGMASK, 0xffffffff);
2683} 2745}
2684 2746
2747/**
2748 * t3_set_proto_sram - set the contents of the protocol sram
2749 * @adapter: the adapter
2750 * @data: the protocol image
2751 *
2752 * Write the contents of the protocol SRAM.
2753 */
2754int t3_set_proto_sram(struct adapter *adap, u8 *data)
2755{
2756 int i;
2757 u32 *buf = (u32 *)data;
2758
2759 for (i = 0; i < PROTO_SRAM_LINES; i++) {
2760 t3_write_reg(adap, A_TP_EMBED_OP_FIELD5, cpu_to_be32(*buf++));
2761 t3_write_reg(adap, A_TP_EMBED_OP_FIELD4, cpu_to_be32(*buf++));
2762 t3_write_reg(adap, A_TP_EMBED_OP_FIELD3, cpu_to_be32(*buf++));
2763 t3_write_reg(adap, A_TP_EMBED_OP_FIELD2, cpu_to_be32(*buf++));
2764 t3_write_reg(adap, A_TP_EMBED_OP_FIELD1, cpu_to_be32(*buf++));
2765
2766 t3_write_reg(adap, A_TP_EMBED_OP_FIELD0, i << 1 | 1 << 31);
2767 if (t3_wait_op_done(adap, A_TP_EMBED_OP_FIELD0, 1, 1, 5, 1))
2768 return -EIO;
2769 }
2770 t3_write_reg(adap, A_TP_EMBED_OP_FIELD0, 0);
2771
2772 return 0;
2773}
2774
2685void t3_config_trace_filter(struct adapter *adapter, 2775void t3_config_trace_filter(struct adapter *adapter,
2686 const struct trace_params *tp, int filter_index, 2776 const struct trace_params *tp, int filter_index,
2687 int invert, int enable) 2777 int invert, int enable)
@@ -2802,7 +2892,7 @@ static void init_hw_for_avail_ports(struct adapter *adap, int nports)
2802 t3_set_reg_field(adap, A_ULPTX_CONFIG, F_CFG_RR_ARB, 0); 2892 t3_set_reg_field(adap, A_ULPTX_CONFIG, F_CFG_RR_ARB, 0);
2803 t3_write_reg(adap, A_MPS_CFG, F_TPRXPORTEN | F_TPTXPORT0EN | 2893 t3_write_reg(adap, A_MPS_CFG, F_TPRXPORTEN | F_TPTXPORT0EN |
2804 F_PORT0ACTIVE | F_ENFORCEPKT); 2894 F_PORT0ACTIVE | F_ENFORCEPKT);
2805 t3_write_reg(adap, A_PM1_TX_CFG, 0xc000c000); 2895 t3_write_reg(adap, A_PM1_TX_CFG, 0xffffffff);
2806 } else { 2896 } else {
2807 t3_set_reg_field(adap, A_ULPRX_CTL, 0, F_ROUND_ROBIN); 2897 t3_set_reg_field(adap, A_ULPRX_CTL, 0, F_ROUND_ROBIN);
2808 t3_set_reg_field(adap, A_ULPTX_CONFIG, 0, F_CFG_RR_ARB); 2898 t3_set_reg_field(adap, A_ULPTX_CONFIG, 0, F_CFG_RR_ARB);
@@ -3097,7 +3187,7 @@ int t3_init_hw(struct adapter *adapter, u32 fw_params)
3097 else 3187 else
3098 t3_set_reg_field(adapter, A_PCIX_CFG, 0, F_CLIDECEN); 3188 t3_set_reg_field(adapter, A_PCIX_CFG, 0, F_CLIDECEN);
3099 3189
3100 t3_write_reg(adapter, A_PM1_RX_CFG, 0xf000f000); 3190 t3_write_reg(adapter, A_PM1_RX_CFG, 0xffffffff);
3101 init_hw_for_avail_ports(adapter, adapter->params.nports); 3191 init_hw_for_avail_ports(adapter, adapter->params.nports);
3102 t3_sge_init(adapter, &adapter->params.sge); 3192 t3_sge_init(adapter, &adapter->params.sge);
3103 3193
diff --git a/drivers/net/cxgb3/version.h b/drivers/net/cxgb3/version.h
index b112317f033e..8eddd23a3a51 100644
--- a/drivers/net/cxgb3/version.h
+++ b/drivers/net/cxgb3/version.h
@@ -39,6 +39,6 @@
39 39
40/* Firmware version */ 40/* Firmware version */
41#define FW_VERSION_MAJOR 4 41#define FW_VERSION_MAJOR 4
42#define FW_VERSION_MINOR 0 42#define FW_VERSION_MINOR 1
43#define FW_VERSION_MICRO 0 43#define FW_VERSION_MICRO 0
44#endif /* __CHELSIO_VERSION_H */ 44#endif /* __CHELSIO_VERSION_H */
diff --git a/drivers/net/e100.c b/drivers/net/e100.c
index 763810c7f33a..74ea6373c7cd 100644
--- a/drivers/net/e100.c
+++ b/drivers/net/e100.c
@@ -159,7 +159,7 @@
159 159
160#define DRV_NAME "e100" 160#define DRV_NAME "e100"
161#define DRV_EXT "-NAPI" 161#define DRV_EXT "-NAPI"
162#define DRV_VERSION "3.5.17-k4"DRV_EXT 162#define DRV_VERSION "3.5.23-k4"DRV_EXT
163#define DRV_DESCRIPTION "Intel(R) PRO/100 Network Driver" 163#define DRV_DESCRIPTION "Intel(R) PRO/100 Network Driver"
164#define DRV_COPYRIGHT "Copyright(c) 1999-2006 Intel Corporation" 164#define DRV_COPYRIGHT "Copyright(c) 1999-2006 Intel Corporation"
165#define PFX DRV_NAME ": " 165#define PFX DRV_NAME ": "
@@ -1024,10 +1024,16 @@ static void e100_configure(struct nic *nic, struct cb *cb, struct sk_buff *skb)
1024 config->mwi_enable = 0x1; /* 1=enable, 0=disable */ 1024 config->mwi_enable = 0x1; /* 1=enable, 0=disable */
1025 config->standard_tcb = 0x0; /* 1=standard, 0=extended */ 1025 config->standard_tcb = 0x0; /* 1=standard, 0=extended */
1026 config->rx_long_ok = 0x1; /* 1=VLANs ok, 0=standard */ 1026 config->rx_long_ok = 0x1; /* 1=VLANs ok, 0=standard */
1027 if(nic->mac >= mac_82559_D101M) 1027 if (nic->mac >= mac_82559_D101M) {
1028 config->tno_intr = 0x1; /* TCO stats enable */ 1028 config->tno_intr = 0x1; /* TCO stats enable */
1029 else 1029 /* Enable TCO in extended config */
1030 if (nic->mac >= mac_82551_10) {
1031 config->byte_count = 0x20; /* extended bytes */
1032 config->rx_d102_mode = 0x1; /* GMRC for TCO */
1033 }
1034 } else {
1030 config->standard_stat_counter = 0x0; 1035 config->standard_stat_counter = 0x0;
1036 }
1031 } 1037 }
1032 1038
1033 DPRINTK(HW, DEBUG, "[00-07]=%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n", 1039 DPRINTK(HW, DEBUG, "[00-07]=%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h
index c0f81b5a30fb..f03f070451de 100644
--- a/drivers/net/ehea/ehea.h
+++ b/drivers/net/ehea/ehea.h
@@ -39,7 +39,13 @@
39#include <asm/io.h> 39#include <asm/io.h>
40 40
41#define DRV_NAME "ehea" 41#define DRV_NAME "ehea"
42#define DRV_VERSION "EHEA_0064" 42#define DRV_VERSION "EHEA_0067"
43
44/* EHEA capability flags */
45#define DLPAR_PORT_ADD_REM 1
46#define DLPAR_MEM_ADD 2
47#define DLPAR_MEM_REM 4
48#define EHEA_CAPABILITIES (DLPAR_PORT_ADD_REM)
43 49
44#define EHEA_MSG_DEFAULT (NETIF_MSG_LINK | NETIF_MSG_TIMER \ 50#define EHEA_MSG_DEFAULT (NETIF_MSG_LINK | NETIF_MSG_TIMER \
45 | NETIF_MSG_RX_ERR | NETIF_MSG_TX_ERR) 51 | NETIF_MSG_RX_ERR | NETIF_MSG_TX_ERR)
@@ -136,10 +142,10 @@ void ehea_dump(void *adr, int len, char *msg);
136 (0xffffffffffffffffULL >> ((64 - (mask)) & 0xffff)) 142 (0xffffffffffffffffULL >> ((64 - (mask)) & 0xffff))
137 143
138#define EHEA_BMASK_SET(mask, value) \ 144#define EHEA_BMASK_SET(mask, value) \
139 ((EHEA_BMASK_MASK(mask) & ((u64)(value))) << EHEA_BMASK_SHIFTPOS(mask)) 145 ((EHEA_BMASK_MASK(mask) & ((u64)(value))) << EHEA_BMASK_SHIFTPOS(mask))
140 146
141#define EHEA_BMASK_GET(mask, value) \ 147#define EHEA_BMASK_GET(mask, value) \
142 (EHEA_BMASK_MASK(mask) & (((u64)(value)) >> EHEA_BMASK_SHIFTPOS(mask))) 148 (EHEA_BMASK_MASK(mask) & (((u64)(value)) >> EHEA_BMASK_SHIFTPOS(mask)))
143 149
144/* 150/*
145 * Generic ehea page 151 * Generic ehea page
@@ -190,7 +196,7 @@ struct ehea_av;
190 * Queue attributes passed to ehea_create_qp() 196 * Queue attributes passed to ehea_create_qp()
191 */ 197 */
192struct ehea_qp_init_attr { 198struct ehea_qp_init_attr {
193 /* input parameter */ 199 /* input parameter */
194 u32 qp_token; /* queue token */ 200 u32 qp_token; /* queue token */
195 u8 low_lat_rq1; 201 u8 low_lat_rq1;
196 u8 signalingtype; /* cqe generation flag */ 202 u8 signalingtype; /* cqe generation flag */
@@ -212,7 +218,7 @@ struct ehea_qp_init_attr {
212 u64 recv_cq_handle; 218 u64 recv_cq_handle;
213 u64 aff_eq_handle; 219 u64 aff_eq_handle;
214 220
215 /* output parameter */ 221 /* output parameter */
216 u32 qp_nr; 222 u32 qp_nr;
217 u16 act_nr_send_wqes; 223 u16 act_nr_send_wqes;
218 u16 act_nr_rwqes_rq1; 224 u16 act_nr_rwqes_rq1;
@@ -279,12 +285,12 @@ struct ehea_qp {
279 * Completion Queue attributes 285 * Completion Queue attributes
280 */ 286 */
281struct ehea_cq_attr { 287struct ehea_cq_attr {
282 /* input parameter */ 288 /* input parameter */
283 u32 max_nr_of_cqes; 289 u32 max_nr_of_cqes;
284 u32 cq_token; 290 u32 cq_token;
285 u64 eq_handle; 291 u64 eq_handle;
286 292
287 /* output parameter */ 293 /* output parameter */
288 u32 act_nr_of_cqes; 294 u32 act_nr_of_cqes;
289 u32 nr_pages; 295 u32 nr_pages;
290}; 296};
diff --git a/drivers/net/ehea/ehea_hw.h b/drivers/net/ehea/ehea_hw.h
index 1246757f2c22..1af7ca499ec5 100644
--- a/drivers/net/ehea/ehea_hw.h
+++ b/drivers/net/ehea/ehea_hw.h
@@ -211,34 +211,34 @@ static inline void epa_store_acc(struct h_epa epa, u32 offset, u64 value)
211} 211}
212 212
213#define epa_store_eq(epa, offset, value)\ 213#define epa_store_eq(epa, offset, value)\
214 epa_store(epa, EQTEMM_OFFSET(offset), value) 214 epa_store(epa, EQTEMM_OFFSET(offset), value)
215#define epa_load_eq(epa, offset)\ 215#define epa_load_eq(epa, offset)\
216 epa_load(epa, EQTEMM_OFFSET(offset)) 216 epa_load(epa, EQTEMM_OFFSET(offset))
217 217
218#define epa_store_cq(epa, offset, value)\ 218#define epa_store_cq(epa, offset, value)\
219 epa_store(epa, CQTEMM_OFFSET(offset), value) 219 epa_store(epa, CQTEMM_OFFSET(offset), value)
220#define epa_load_cq(epa, offset)\ 220#define epa_load_cq(epa, offset)\
221 epa_load(epa, CQTEMM_OFFSET(offset)) 221 epa_load(epa, CQTEMM_OFFSET(offset))
222 222
223#define epa_store_qp(epa, offset, value)\ 223#define epa_store_qp(epa, offset, value)\
224 epa_store(epa, QPTEMM_OFFSET(offset), value) 224 epa_store(epa, QPTEMM_OFFSET(offset), value)
225#define epa_load_qp(epa, offset)\ 225#define epa_load_qp(epa, offset)\
226 epa_load(epa, QPTEMM_OFFSET(offset)) 226 epa_load(epa, QPTEMM_OFFSET(offset))
227 227
228#define epa_store_qped(epa, offset, value)\ 228#define epa_store_qped(epa, offset, value)\
229 epa_store(epa, QPEDMM_OFFSET(offset), value) 229 epa_store(epa, QPEDMM_OFFSET(offset), value)
230#define epa_load_qped(epa, offset)\ 230#define epa_load_qped(epa, offset)\
231 epa_load(epa, QPEDMM_OFFSET(offset)) 231 epa_load(epa, QPEDMM_OFFSET(offset))
232 232
233#define epa_store_mrmw(epa, offset, value)\ 233#define epa_store_mrmw(epa, offset, value)\
234 epa_store(epa, MRMWMM_OFFSET(offset), value) 234 epa_store(epa, MRMWMM_OFFSET(offset), value)
235#define epa_load_mrmw(epa, offset)\ 235#define epa_load_mrmw(epa, offset)\
236 epa_load(epa, MRMWMM_OFFSET(offset)) 236 epa_load(epa, MRMWMM_OFFSET(offset))
237 237
238#define epa_store_base(epa, offset, value)\ 238#define epa_store_base(epa, offset, value)\
239 epa_store(epa, HCAGR_OFFSET(offset), value) 239 epa_store(epa, HCAGR_OFFSET(offset), value)
240#define epa_load_base(epa, offset)\ 240#define epa_load_base(epa, offset)\
241 epa_load(epa, HCAGR_OFFSET(offset)) 241 epa_load(epa, HCAGR_OFFSET(offset))
242 242
243static inline void ehea_update_sqa(struct ehea_qp *qp, u16 nr_wqes) 243static inline void ehea_update_sqa(struct ehea_qp *qp, u16 nr_wqes)
244{ 244{
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c
index 9e13433a268a..383144db4d18 100644
--- a/drivers/net/ehea/ehea_main.c
+++ b/drivers/net/ehea/ehea_main.c
@@ -81,7 +81,7 @@ MODULE_PARM_DESC(use_mcs, " 0:NAPI, 1:Multiple receive queues, Default = 1 ");
81static int port_name_cnt = 0; 81static int port_name_cnt = 0;
82 82
83static int __devinit ehea_probe_adapter(struct ibmebus_dev *dev, 83static int __devinit ehea_probe_adapter(struct ibmebus_dev *dev,
84 const struct of_device_id *id); 84 const struct of_device_id *id);
85 85
86static int __devexit ehea_remove(struct ibmebus_dev *dev); 86static int __devexit ehea_remove(struct ibmebus_dev *dev);
87 87
@@ -236,7 +236,7 @@ static int ehea_refill_rq_def(struct ehea_port_res *pr,
236 236
237 rwqe = ehea_get_next_rwqe(qp, rq_nr); 237 rwqe = ehea_get_next_rwqe(qp, rq_nr);
238 rwqe->wr_id = EHEA_BMASK_SET(EHEA_WR_ID_TYPE, wqe_type) 238 rwqe->wr_id = EHEA_BMASK_SET(EHEA_WR_ID_TYPE, wqe_type)
239 | EHEA_BMASK_SET(EHEA_WR_ID_INDEX, index); 239 | EHEA_BMASK_SET(EHEA_WR_ID_INDEX, index);
240 rwqe->sg_list[0].l_key = pr->recv_mr.lkey; 240 rwqe->sg_list[0].l_key = pr->recv_mr.lkey;
241 rwqe->sg_list[0].vaddr = (u64)skb->data; 241 rwqe->sg_list[0].vaddr = (u64)skb->data;
242 rwqe->sg_list[0].len = packet_size; 242 rwqe->sg_list[0].len = packet_size;
@@ -427,7 +427,7 @@ static struct ehea_cqe *ehea_proc_rwqes(struct net_device *dev,
427 break; 427 break;
428 } 428 }
429 skb_copy_to_linear_data(skb, ((char*)cqe) + 64, 429 skb_copy_to_linear_data(skb, ((char*)cqe) + 64,
430 cqe->num_bytes_transfered - 4); 430 cqe->num_bytes_transfered - 4);
431 ehea_fill_skb(port->netdev, skb, cqe); 431 ehea_fill_skb(port->netdev, skb, cqe);
432 } else if (rq == 2) { /* RQ2 */ 432 } else if (rq == 2) { /* RQ2 */
433 skb = get_skb_by_index(skb_arr_rq2, 433 skb = get_skb_by_index(skb_arr_rq2,
@@ -618,7 +618,7 @@ static struct ehea_port *ehea_get_port(struct ehea_adapter *adapter,
618 618
619 for (i = 0; i < EHEA_MAX_PORTS; i++) 619 for (i = 0; i < EHEA_MAX_PORTS; i++)
620 if (adapter->port[i]) 620 if (adapter->port[i])
621 if (adapter->port[i]->logical_port_id == logical_port) 621 if (adapter->port[i]->logical_port_id == logical_port)
622 return adapter->port[i]; 622 return adapter->port[i];
623 return NULL; 623 return NULL;
624} 624}
@@ -1695,6 +1695,7 @@ static void ehea_xmit2(struct sk_buff *skb, struct net_device *dev,
1695{ 1695{
1696 if (skb->protocol == htons(ETH_P_IP)) { 1696 if (skb->protocol == htons(ETH_P_IP)) {
1697 const struct iphdr *iph = ip_hdr(skb); 1697 const struct iphdr *iph = ip_hdr(skb);
1698
1698 /* IPv4 */ 1699 /* IPv4 */
1699 swqe->tx_control |= EHEA_SWQE_CRC 1700 swqe->tx_control |= EHEA_SWQE_CRC
1700 | EHEA_SWQE_IP_CHECKSUM 1701 | EHEA_SWQE_IP_CHECKSUM
@@ -1705,13 +1706,12 @@ static void ehea_xmit2(struct sk_buff *skb, struct net_device *dev,
1705 write_ip_start_end(swqe, skb); 1706 write_ip_start_end(swqe, skb);
1706 1707
1707 if (iph->protocol == IPPROTO_UDP) { 1708 if (iph->protocol == IPPROTO_UDP) {
1708 if ((iph->frag_off & IP_MF) || 1709 if ((iph->frag_off & IP_MF)
1709 (iph->frag_off & IP_OFFSET)) 1710 || (iph->frag_off & IP_OFFSET))
1710 /* IP fragment, so don't change cs */ 1711 /* IP fragment, so don't change cs */
1711 swqe->tx_control &= ~EHEA_SWQE_TCP_CHECKSUM; 1712 swqe->tx_control &= ~EHEA_SWQE_TCP_CHECKSUM;
1712 else 1713 else
1713 write_udp_offset_end(swqe, skb); 1714 write_udp_offset_end(swqe, skb);
1714
1715 } else if (iph->protocol == IPPROTO_TCP) { 1715 } else if (iph->protocol == IPPROTO_TCP) {
1716 write_tcp_offset_end(swqe, skb); 1716 write_tcp_offset_end(swqe, skb);
1717 } 1717 }
@@ -1739,6 +1739,7 @@ static void ehea_xmit3(struct sk_buff *skb, struct net_device *dev,
1739 1739
1740 if (skb->protocol == htons(ETH_P_IP)) { 1740 if (skb->protocol == htons(ETH_P_IP)) {
1741 const struct iphdr *iph = ip_hdr(skb); 1741 const struct iphdr *iph = ip_hdr(skb);
1742
1742 /* IPv4 */ 1743 /* IPv4 */
1743 write_ip_start_end(swqe, skb); 1744 write_ip_start_end(swqe, skb);
1744 1745
@@ -1751,8 +1752,8 @@ static void ehea_xmit3(struct sk_buff *skb, struct net_device *dev,
1751 write_tcp_offset_end(swqe, skb); 1752 write_tcp_offset_end(swqe, skb);
1752 1753
1753 } else if (iph->protocol == IPPROTO_UDP) { 1754 } else if (iph->protocol == IPPROTO_UDP) {
1754 if ((iph->frag_off & IP_MF) || 1755 if ((iph->frag_off & IP_MF)
1755 (iph->frag_off & IP_OFFSET)) 1756 || (iph->frag_off & IP_OFFSET))
1756 /* IP fragment, so don't change cs */ 1757 /* IP fragment, so don't change cs */
1757 swqe->tx_control |= EHEA_SWQE_CRC 1758 swqe->tx_control |= EHEA_SWQE_CRC
1758 | EHEA_SWQE_IMM_DATA_PRESENT; 1759 | EHEA_SWQE_IMM_DATA_PRESENT;
@@ -2407,7 +2408,7 @@ static void __devinit logical_port_release(struct device *dev)
2407} 2408}
2408 2409
2409static int ehea_driver_sysfs_add(struct device *dev, 2410static int ehea_driver_sysfs_add(struct device *dev,
2410 struct device_driver *driver) 2411 struct device_driver *driver)
2411{ 2412{
2412 int ret; 2413 int ret;
2413 2414
@@ -2424,7 +2425,7 @@ static int ehea_driver_sysfs_add(struct device *dev,
2424} 2425}
2425 2426
2426static void ehea_driver_sysfs_remove(struct device *dev, 2427static void ehea_driver_sysfs_remove(struct device *dev,
2427 struct device_driver *driver) 2428 struct device_driver *driver)
2428{ 2429{
2429 struct device_driver *drv = driver; 2430 struct device_driver *drv = driver;
2430 2431
@@ -2453,7 +2454,7 @@ static struct device *ehea_register_port(struct ehea_port *port,
2453 } 2454 }
2454 2455
2455 ret = device_create_file(&port->ofdev.dev, &dev_attr_log_port_id); 2456 ret = device_create_file(&port->ofdev.dev, &dev_attr_log_port_id);
2456 if (ret) { 2457 if (ret) {
2457 ehea_error("failed to register attributes, ret=%d", ret); 2458 ehea_error("failed to register attributes, ret=%d", ret);
2458 goto out_unreg_of_dev; 2459 goto out_unreg_of_dev;
2459 } 2460 }
@@ -2601,6 +2602,7 @@ static int ehea_setup_ports(struct ehea_adapter *adapter)
2601{ 2602{
2602 struct device_node *lhea_dn; 2603 struct device_node *lhea_dn;
2603 struct device_node *eth_dn = NULL; 2604 struct device_node *eth_dn = NULL;
2605
2604 const u32 *dn_log_port_id; 2606 const u32 *dn_log_port_id;
2605 int i = 0; 2607 int i = 0;
2606 2608
@@ -2608,7 +2610,7 @@ static int ehea_setup_ports(struct ehea_adapter *adapter)
2608 while ((eth_dn = of_get_next_child(lhea_dn, eth_dn))) { 2610 while ((eth_dn = of_get_next_child(lhea_dn, eth_dn))) {
2609 2611
2610 dn_log_port_id = of_get_property(eth_dn, "ibm,hea-port-no", 2612 dn_log_port_id = of_get_property(eth_dn, "ibm,hea-port-no",
2611 NULL); 2613 NULL);
2612 if (!dn_log_port_id) { 2614 if (!dn_log_port_id) {
2613 ehea_error("bad device node: eth_dn name=%s", 2615 ehea_error("bad device node: eth_dn name=%s",
2614 eth_dn->full_name); 2616 eth_dn->full_name);
@@ -2648,7 +2650,7 @@ static struct device_node *ehea_get_eth_dn(struct ehea_adapter *adapter,
2648 while ((eth_dn = of_get_next_child(lhea_dn, eth_dn))) { 2650 while ((eth_dn = of_get_next_child(lhea_dn, eth_dn))) {
2649 2651
2650 dn_log_port_id = of_get_property(eth_dn, "ibm,hea-port-no", 2652 dn_log_port_id = of_get_property(eth_dn, "ibm,hea-port-no",
2651 NULL); 2653 NULL);
2652 if (dn_log_port_id) 2654 if (dn_log_port_id)
2653 if (*dn_log_port_id == logical_port_id) 2655 if (*dn_log_port_id == logical_port_id)
2654 return eth_dn; 2656 return eth_dn;
@@ -2789,7 +2791,7 @@ static int __devinit ehea_probe_adapter(struct ibmebus_dev *dev,
2789 adapter->ebus_dev = dev; 2791 adapter->ebus_dev = dev;
2790 2792
2791 adapter_handle = of_get_property(dev->ofdev.node, "ibm,hea-handle", 2793 adapter_handle = of_get_property(dev->ofdev.node, "ibm,hea-handle",
2792 NULL); 2794 NULL);
2793 if (adapter_handle) 2795 if (adapter_handle)
2794 adapter->handle = *adapter_handle; 2796 adapter->handle = *adapter_handle;
2795 2797
@@ -2921,6 +2923,15 @@ static int check_module_parm(void)
2921 return ret; 2923 return ret;
2922} 2924}
2923 2925
2926static ssize_t ehea_show_capabilities(struct device_driver *drv,
2927 char *buf)
2928{
2929 return sprintf(buf, "%d", EHEA_CAPABILITIES);
2930}
2931
2932static DRIVER_ATTR(capabilities, S_IRUSR | S_IRGRP | S_IROTH,
2933 ehea_show_capabilities, NULL);
2934
2924int __init ehea_module_init(void) 2935int __init ehea_module_init(void)
2925{ 2936{
2926 int ret; 2937 int ret;
@@ -2932,8 +2943,19 @@ int __init ehea_module_init(void)
2932 if (ret) 2943 if (ret)
2933 goto out; 2944 goto out;
2934 ret = ibmebus_register_driver(&ehea_driver); 2945 ret = ibmebus_register_driver(&ehea_driver);
2935 if (ret) 2946 if (ret) {
2936 ehea_error("failed registering eHEA device driver on ebus"); 2947 ehea_error("failed registering eHEA device driver on ebus");
2948 goto out;
2949 }
2950
2951 ret = driver_create_file(&ehea_driver.driver,
2952 &driver_attr_capabilities);
2953 if (ret) {
2954 ehea_error("failed to register capabilities attribute, ret=%d",
2955 ret);
2956 ibmebus_unregister_driver(&ehea_driver);
2957 goto out;
2958 }
2937 2959
2938out: 2960out:
2939 return ret; 2961 return ret;
@@ -2941,6 +2963,7 @@ out:
2941 2963
2942static void __exit ehea_module_exit(void) 2964static void __exit ehea_module_exit(void)
2943{ 2965{
2966 driver_remove_file(&ehea_driver.driver, &driver_attr_capabilities);
2944 ibmebus_unregister_driver(&ehea_driver); 2967 ibmebus_unregister_driver(&ehea_driver);
2945} 2968}
2946 2969
diff --git a/drivers/net/ehea/ehea_qmr.c b/drivers/net/ehea/ehea_qmr.c
index f24a8862977d..29eaa46948b0 100644
--- a/drivers/net/ehea/ehea_qmr.c
+++ b/drivers/net/ehea/ehea_qmr.c
@@ -211,7 +211,7 @@ u64 ehea_destroy_cq_res(struct ehea_cq *cq, u64 force)
211 u64 hret; 211 u64 hret;
212 u64 adapter_handle = cq->adapter->handle; 212 u64 adapter_handle = cq->adapter->handle;
213 213
214 /* deregister all previous registered pages */ 214 /* deregister all previous registered pages */
215 hret = ehea_h_free_resource(adapter_handle, cq->fw_handle, force); 215 hret = ehea_h_free_resource(adapter_handle, cq->fw_handle, force);
216 if (hret != H_SUCCESS) 216 if (hret != H_SUCCESS)
217 return hret; 217 return hret;
@@ -362,7 +362,7 @@ int ehea_destroy_eq(struct ehea_eq *eq)
362 if (hret != H_SUCCESS) { 362 if (hret != H_SUCCESS) {
363 ehea_error("destroy EQ failed"); 363 ehea_error("destroy EQ failed");
364 return -EIO; 364 return -EIO;
365 } 365 }
366 366
367 return 0; 367 return 0;
368} 368}
@@ -507,44 +507,44 @@ out_freemem:
507 507
508u64 ehea_destroy_qp_res(struct ehea_qp *qp, u64 force) 508u64 ehea_destroy_qp_res(struct ehea_qp *qp, u64 force)
509{ 509{
510 u64 hret; 510 u64 hret;
511 struct ehea_qp_init_attr *qp_attr = &qp->init_attr; 511 struct ehea_qp_init_attr *qp_attr = &qp->init_attr;
512 512
513 513
514 ehea_h_disable_and_get_hea(qp->adapter->handle, qp->fw_handle); 514 ehea_h_disable_and_get_hea(qp->adapter->handle, qp->fw_handle);
515 hret = ehea_h_free_resource(qp->adapter->handle, qp->fw_handle, force); 515 hret = ehea_h_free_resource(qp->adapter->handle, qp->fw_handle, force);
516 if (hret != H_SUCCESS) 516 if (hret != H_SUCCESS)
517 return hret; 517 return hret;
518 518
519 hw_queue_dtor(&qp->hw_squeue); 519 hw_queue_dtor(&qp->hw_squeue);
520 hw_queue_dtor(&qp->hw_rqueue1); 520 hw_queue_dtor(&qp->hw_rqueue1);
521 521
522 if (qp_attr->rq_count > 1) 522 if (qp_attr->rq_count > 1)
523 hw_queue_dtor(&qp->hw_rqueue2); 523 hw_queue_dtor(&qp->hw_rqueue2);
524 if (qp_attr->rq_count > 2) 524 if (qp_attr->rq_count > 2)
525 hw_queue_dtor(&qp->hw_rqueue3); 525 hw_queue_dtor(&qp->hw_rqueue3);
526 kfree(qp); 526 kfree(qp);
527 527
528 return hret; 528 return hret;
529} 529}
530 530
531int ehea_destroy_qp(struct ehea_qp *qp) 531int ehea_destroy_qp(struct ehea_qp *qp)
532{ 532{
533 u64 hret; 533 u64 hret;
534 if (!qp) 534 if (!qp)
535 return 0; 535 return 0;
536 536
537 if ((hret = ehea_destroy_qp_res(qp, NORMAL_FREE)) == H_R_STATE) { 537 if ((hret = ehea_destroy_qp_res(qp, NORMAL_FREE)) == H_R_STATE) {
538 ehea_error_data(qp->adapter, qp->fw_handle); 538 ehea_error_data(qp->adapter, qp->fw_handle);
539 hret = ehea_destroy_qp_res(qp, FORCE_FREE); 539 hret = ehea_destroy_qp_res(qp, FORCE_FREE);
540 } 540 }
541 541
542 if (hret != H_SUCCESS) { 542 if (hret != H_SUCCESS) {
543 ehea_error("destroy QP failed"); 543 ehea_error("destroy QP failed");
544 return -EIO; 544 return -EIO;
545 } 545 }
546 546
547 return 0; 547 return 0;
548} 548}
549 549
550int ehea_reg_kernel_mr(struct ehea_adapter *adapter, struct ehea_mr *mr) 550int ehea_reg_kernel_mr(struct ehea_adapter *adapter, struct ehea_mr *mr)
diff --git a/drivers/net/fec_8xx/Kconfig b/drivers/net/fec_8xx/Kconfig
index a84c232395e3..afb34ded26ee 100644
--- a/drivers/net/fec_8xx/Kconfig
+++ b/drivers/net/fec_8xx/Kconfig
@@ -1,6 +1,6 @@
1config FEC_8XX 1config FEC_8XX
2 tristate "Motorola 8xx FEC driver" 2 tristate "Motorola 8xx FEC driver"
3 depends on NET_ETHERNET && 8xx 3 depends on 8XX
4 select MII 4 select MII
5 5
6config FEC_8XX_GENERIC_PHY 6config FEC_8XX_GENERIC_PHY
diff --git a/drivers/net/fs_enet/Kconfig b/drivers/net/fs_enet/Kconfig
index 6aaee67dd4b7..e27ee210b605 100644
--- a/drivers/net/fs_enet/Kconfig
+++ b/drivers/net/fs_enet/Kconfig
@@ -1,6 +1,6 @@
1config FS_ENET 1config FS_ENET
2 tristate "Freescale Ethernet Driver" 2 tristate "Freescale Ethernet Driver"
3 depends on NET_ETHERNET && (CPM1 || CPM2) 3 depends on CPM1 || CPM2
4 select MII 4 select MII
5 5
6config FS_ENET_HAS_SCC 6config FS_ENET_HAS_SCC
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index 1b854bf07b09..d7a1a58de766 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -130,6 +130,9 @@ static int gfar_remove(struct platform_device *pdev);
130static void free_skb_resources(struct gfar_private *priv); 130static void free_skb_resources(struct gfar_private *priv);
131static void gfar_set_multi(struct net_device *dev); 131static void gfar_set_multi(struct net_device *dev);
132static void gfar_set_hash_for_addr(struct net_device *dev, u8 *addr); 132static void gfar_set_hash_for_addr(struct net_device *dev, u8 *addr);
133static void gfar_configure_serdes(struct net_device *dev);
134extern int gfar_local_mdio_write(struct gfar_mii *regs, int mii_id, int regnum, u16 value);
135extern int gfar_local_mdio_read(struct gfar_mii *regs, int mii_id, int regnum);
133#ifdef CONFIG_GFAR_NAPI 136#ifdef CONFIG_GFAR_NAPI
134static int gfar_poll(struct net_device *dev, int *budget); 137static int gfar_poll(struct net_device *dev, int *budget);
135#endif 138#endif
@@ -451,6 +454,9 @@ static int init_phy(struct net_device *dev)
451 454
452 phydev = phy_connect(dev, phy_id, &adjust_link, 0, interface); 455 phydev = phy_connect(dev, phy_id, &adjust_link, 0, interface);
453 456
457 if (interface == PHY_INTERFACE_MODE_SGMII)
458 gfar_configure_serdes(dev);
459
454 if (IS_ERR(phydev)) { 460 if (IS_ERR(phydev)) {
455 printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name); 461 printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name);
456 return PTR_ERR(phydev); 462 return PTR_ERR(phydev);
@@ -465,6 +471,27 @@ static int init_phy(struct net_device *dev)
465 return 0; 471 return 0;
466} 472}
467 473
474static void gfar_configure_serdes(struct net_device *dev)
475{
476 struct gfar_private *priv = netdev_priv(dev);
477 struct gfar_mii __iomem *regs =
478 (void __iomem *)&priv->regs->gfar_mii_regs;
479
480 /* Initialise TBI i/f to communicate with serdes (lynx phy) */
481
482 /* Single clk mode, mii mode off(for aerdes communication) */
483 gfar_local_mdio_write(regs, TBIPA_VALUE, MII_TBICON, TBICON_CLK_SELECT);
484
485 /* Supported pause and full-duplex, no half-duplex */
486 gfar_local_mdio_write(regs, TBIPA_VALUE, MII_ADVERTISE,
487 ADVERTISE_1000XFULL | ADVERTISE_1000XPAUSE |
488 ADVERTISE_1000XPSE_ASYM);
489
490 /* ANEG enable, restart ANEG, full duplex mode, speed[1] set */
491 gfar_local_mdio_write(regs, TBIPA_VALUE, MII_BMCR, BMCR_ANENABLE |
492 BMCR_ANRESTART | BMCR_FULLDPLX | BMCR_SPEED1000);
493}
494
468static void init_registers(struct net_device *dev) 495static void init_registers(struct net_device *dev)
469{ 496{
470 struct gfar_private *priv = netdev_priv(dev); 497 struct gfar_private *priv = netdev_priv(dev);
diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h
index 39e9e321fcbc..d8e779c102fa 100644
--- a/drivers/net/gianfar.h
+++ b/drivers/net/gianfar.h
@@ -136,6 +136,12 @@ extern const char gfar_driver_version[];
136#define MIIMCFG_RESET 0x80000000 136#define MIIMCFG_RESET 0x80000000
137#define MIIMIND_BUSY 0x00000001 137#define MIIMIND_BUSY 0x00000001
138 138
139/* TBI register addresses */
140#define MII_TBICON 0x11
141
142/* TBICON register bit fields */
143#define TBICON_CLK_SELECT 0x0020
144
139/* MAC register bits */ 145/* MAC register bits */
140#define MACCFG1_SOFT_RESET 0x80000000 146#define MACCFG1_SOFT_RESET 0x80000000
141#define MACCFG1_RESET_RX_MC 0x00080000 147#define MACCFG1_RESET_RX_MC 0x00080000
diff --git a/drivers/net/gianfar_mii.c b/drivers/net/gianfar_mii.c
index bcc6b82f4a33..5dd34a1a7b89 100644
--- a/drivers/net/gianfar_mii.c
+++ b/drivers/net/gianfar_mii.c
@@ -43,13 +43,18 @@
43#include "gianfar.h" 43#include "gianfar.h"
44#include "gianfar_mii.h" 44#include "gianfar_mii.h"
45 45
46/* Write value to the PHY at mii_id at register regnum, 46/*
47 * on the bus, waiting until the write is done before returning. 47 * Write value to the PHY at mii_id at register regnum,
48 * All PHY configuration is done through the TSEC1 MIIM regs */ 48 * on the bus attached to the local interface, which may be different from the
49int gfar_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value) 49 * generic mdio bus (tied to a single interface), waiting until the write is
50 * done before returning. This is helpful in programming interfaces like
51 * the TBI which control interfaces like onchip SERDES and are always tied to
52 * the local mdio pins, which may not be the same as system mdio bus, used for
53 * controlling the external PHYs, for example.
54 */
55int gfar_local_mdio_write(struct gfar_mii *regs, int mii_id,
56 int regnum, u16 value)
50{ 57{
51 struct gfar_mii __iomem *regs = (void __iomem *)bus->priv;
52
53 /* Set the PHY address and the register address we want to write */ 58 /* Set the PHY address and the register address we want to write */
54 gfar_write(&regs->miimadd, (mii_id << 8) | regnum); 59 gfar_write(&regs->miimadd, (mii_id << 8) | regnum);
55 60
@@ -63,12 +68,19 @@ int gfar_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value)
63 return 0; 68 return 0;
64} 69}
65 70
66/* Read the bus for PHY at addr mii_id, register regnum, and 71/*
67 * return the value. Clears miimcom first. All PHY 72 * Read the bus for PHY at addr mii_id, register regnum, and
68 * configuration has to be done through the TSEC1 MIIM regs */ 73 * return the value. Clears miimcom first. All PHY operation
69int gfar_mdio_read(struct mii_bus *bus, int mii_id, int regnum) 74 * done on the bus attached to the local interface,
75 * which may be different from the generic mdio bus
76 * This is helpful in programming interfaces like
77 * the TBI which, inturn, control interfaces like onchip SERDES
78 * and are always tied to the local mdio pins, which may not be the
79 * same as system mdio bus, used for controlling the external PHYs, for eg.
80 */
81int gfar_local_mdio_read(struct gfar_mii *regs, int mii_id, int regnum)
82
70{ 83{
71 struct gfar_mii __iomem *regs = (void __iomem *)bus->priv;
72 u16 value; 84 u16 value;
73 85
74 /* Set the PHY address and the register address we want to read */ 86 /* Set the PHY address and the register address we want to read */
@@ -88,6 +100,27 @@ int gfar_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
88 return value; 100 return value;
89} 101}
90 102
103/* Write value to the PHY at mii_id at register regnum,
104 * on the bus, waiting until the write is done before returning.
105 * All PHY configuration is done through the TSEC1 MIIM regs */
106int gfar_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value)
107{
108 struct gfar_mii __iomem *regs = (void __iomem *)bus->priv;
109
110 /* Write to the local MII regs */
111 return(gfar_local_mdio_write(regs, mii_id, regnum, value));
112}
113
114/* Read the bus for PHY at addr mii_id, register regnum, and
115 * return the value. Clears miimcom first. All PHY
116 * configuration has to be done through the TSEC1 MIIM regs */
117int gfar_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
118{
119 struct gfar_mii __iomem *regs = (void __iomem *)bus->priv;
120
121 /* Read the local MII regs */
122 return(gfar_local_mdio_read(regs, mii_id, regnum));
123}
91 124
92/* Reset the MIIM registers, and wait for the bus to free */ 125/* Reset the MIIM registers, and wait for the bus to free */
93int gfar_mdio_reset(struct mii_bus *bus) 126int gfar_mdio_reset(struct mii_bus *bus)
diff --git a/drivers/net/ioc3-eth.c b/drivers/net/ioc3-eth.c
index f749e07c6425..3ca1e8ece548 100644
--- a/drivers/net/ioc3-eth.c
+++ b/drivers/net/ioc3-eth.c
@@ -352,13 +352,12 @@ static u64 nic_find(struct ioc3 *ioc3, int *last)
352 352
353static int nic_init(struct ioc3 *ioc3) 353static int nic_init(struct ioc3 *ioc3)
354{ 354{
355 const char *type; 355 const char *unknown = "unknown";
356 const char *type = unknown;
356 u8 crc; 357 u8 crc;
357 u8 serial[6]; 358 u8 serial[6];
358 int save = 0, i; 359 int save = 0, i;
359 360
360 type = "unknown";
361
362 while (1) { 361 while (1) {
363 u64 reg; 362 u64 reg;
364 reg = nic_find(ioc3, &save); 363 reg = nic_find(ioc3, &save);
@@ -392,7 +391,7 @@ static int nic_init(struct ioc3 *ioc3)
392 } 391 }
393 392
394 printk("Found %s NIC", type); 393 printk("Found %s NIC", type);
395 if (type != "unknown") { 394 if (type != unknown) {
396 printk (" registration number %02x:%02x:%02x:%02x:%02x:%02x," 395 printk (" registration number %02x:%02x:%02x:%02x:%02x:%02x,"
397 " CRC %02x", serial[0], serial[1], serial[2], 396 " CRC %02x", serial[0], serial[1], serial[2],
398 serial[3], serial[4], serial[5], crc); 397 serial[3], serial[4], serial[5], crc);
@@ -1103,20 +1102,28 @@ static int ioc3_close(struct net_device *dev)
1103 * MiniDINs; all other subdevices are left swinging in the wind, leave 1102 * MiniDINs; all other subdevices are left swinging in the wind, leave
1104 * them disabled. 1103 * them disabled.
1105 */ 1104 */
1106static inline int ioc3_is_menet(struct pci_dev *pdev) 1105
1106static int ioc3_adjacent_is_ioc3(struct pci_dev *pdev, int slot)
1107{
1108 struct pci_dev *dev = pci_get_slot(pdev->bus, PCI_DEVFN(slot, 0));
1109 int ret = 0;
1110
1111 if (dev) {
1112 if (dev->vendor == PCI_VENDOR_ID_SGI &&
1113 dev->device == PCI_DEVICE_ID_SGI_IOC3)
1114 ret = 1;
1115 pci_dev_put(dev);
1116 }
1117
1118 return ret;
1119}
1120
1121static int ioc3_is_menet(struct pci_dev *pdev)
1107{ 1122{
1108 struct pci_dev *dev; 1123 return pdev->bus->parent == NULL &&
1109 1124 ioc3_adjacent_is_ioc3(pdev, 0) &&
1110 return pdev->bus->parent == NULL 1125 ioc3_adjacent_is_ioc3(pdev, 1) &&
1111 && (dev = pci_find_slot(pdev->bus->number, PCI_DEVFN(0, 0))) 1126 ioc3_adjacent_is_ioc3(pdev, 2);
1112 && dev->vendor == PCI_VENDOR_ID_SGI
1113 && dev->device == PCI_DEVICE_ID_SGI_IOC3
1114 && (dev = pci_find_slot(pdev->bus->number, PCI_DEVFN(1, 0)))
1115 && dev->vendor == PCI_VENDOR_ID_SGI
1116 && dev->device == PCI_DEVICE_ID_SGI_IOC3
1117 && (dev = pci_find_slot(pdev->bus->number, PCI_DEVFN(2, 0)))
1118 && dev->vendor == PCI_VENDOR_ID_SGI
1119 && dev->device == PCI_DEVICE_ID_SGI_IOC3;
1120} 1127}
1121 1128
1122#ifdef CONFIG_SERIAL_8250 1129#ifdef CONFIG_SERIAL_8250
diff --git a/drivers/net/lasi_82596.c b/drivers/net/lasi_82596.c
index 741780e14b2c..efbae4b8398e 100644
--- a/drivers/net/lasi_82596.c
+++ b/drivers/net/lasi_82596.c
@@ -86,93 +86,36 @@
86#include <linux/dma-mapping.h> 86#include <linux/dma-mapping.h>
87 87
88#include <asm/io.h> 88#include <asm/io.h>
89#include <asm/pgtable.h>
90#include <asm/irq.h> 89#include <asm/irq.h>
91#include <asm/pdc.h> 90#include <asm/pdc.h>
92#include <asm/cache.h>
93#include <asm/parisc-device.h> 91#include <asm/parisc-device.h>
94 92
95#define LASI_82596_DRIVER_VERSION "LASI 82596 driver - Revision: 1.30" 93#define LASI_82596_DRIVER_VERSION "LASI 82596 driver - Revision: 1.30"
96 94
97/* DEBUG flags
98 */
99
100#define DEB_INIT 0x0001
101#define DEB_PROBE 0x0002
102#define DEB_SERIOUS 0x0004
103#define DEB_ERRORS 0x0008
104#define DEB_MULTI 0x0010
105#define DEB_TDR 0x0020
106#define DEB_OPEN 0x0040
107#define DEB_RESET 0x0080
108#define DEB_ADDCMD 0x0100
109#define DEB_STATUS 0x0200
110#define DEB_STARTTX 0x0400
111#define DEB_RXADDR 0x0800
112#define DEB_TXADDR 0x1000
113#define DEB_RXFRAME 0x2000
114#define DEB_INTS 0x4000
115#define DEB_STRUCT 0x8000
116#define DEB_ANY 0xffff
117
118
119#define DEB(x,y) if (i596_debug & (x)) { y; }
120
121
122#define CHECK_WBACK(priv, addr,len) \
123 do { dma_cache_sync((priv)->dev, (void *)addr, len, DMA_TO_DEVICE); } while (0)
124
125#define CHECK_INV(priv, addr,len) \
126 do { dma_cache_sync((priv)->dev, (void *)addr, len, DMA_FROM_DEVICE); } while(0)
127
128#define CHECK_WBACK_INV(priv, addr,len) \
129 do { dma_cache_sync((priv)->dev, (void *)addr, len, DMA_BIDIRECTIONAL); } while (0)
130
131
132#define PA_I82596_RESET 0 /* Offsets relative to LASI-LAN-Addr.*/ 95#define PA_I82596_RESET 0 /* Offsets relative to LASI-LAN-Addr.*/
133#define PA_CPU_PORT_L_ACCESS 4 96#define PA_CPU_PORT_L_ACCESS 4
134#define PA_CHANNEL_ATTENTION 8 97#define PA_CHANNEL_ATTENTION 8
135 98
99#define OPT_SWAP_PORT 0x0001 /* Need to wordswp on the MPU port */
136 100
137/* 101#define DMA_ALLOC dma_alloc_noncoherent
138 * Define various macros for Channel Attention, word swapping etc., dependent 102#define DMA_FREE dma_free_noncoherent
139 * on architecture. MVME and BVME are 680x0 based, otherwise it is Intel. 103#define DMA_WBACK(ndev, addr, len) \
140 */ 104 do { dma_cache_sync((ndev)->dev.parent, (void *)addr, len, DMA_TO_DEVICE); } while (0)
141 105
142#ifdef __BIG_ENDIAN 106#define DMA_INV(ndev, addr, len) \
143#define WSWAPrfd(x) (((u32)(x)<<16) | ((((u32)(x)))>>16)) 107 do { dma_cache_sync((ndev)->dev.parent, (void *)addr, len, DMA_FROM_DEVICE); } while (0)
144#define WSWAPrbd(x) (((u32)(x)<<16) | ((((u32)(x)))>>16))
145#define WSWAPiscp(x) (((u32)(x)<<16) | ((((u32)(x)))>>16))
146#define WSWAPscb(x) (((u32)(x)<<16) | ((((u32)(x)))>>16))
147#define WSWAPcmd(x) (((u32)(x)<<16) | ((((u32)(x)))>>16))
148#define WSWAPtbd(x) (((u32)(x)<<16) | ((((u32)(x)))>>16))
149#define WSWAPchar(x) (((u32)(x)<<16) | ((((u32)(x)))>>16))
150#define ISCP_BUSY 0x00010000
151#define MACH_IS_APRICOT 0
152#else
153#define WSWAPrfd(x) ((struct i596_rfd *)(x))
154#define WSWAPrbd(x) ((struct i596_rbd *)(x))
155#define WSWAPiscp(x) ((struct i596_iscp *)(x))
156#define WSWAPscb(x) ((struct i596_scb *)(x))
157#define WSWAPcmd(x) ((struct i596_cmd *)(x))
158#define WSWAPtbd(x) ((struct i596_tbd *)(x))
159#define WSWAPchar(x) ((char *)(x))
160#define ISCP_BUSY 0x0001
161#define MACH_IS_APRICOT 1
162#endif
163 108
164/* 109#define DMA_WBACK_INV(ndev, addr, len) \
165 * The MPU_PORT command allows direct access to the 82596. With PORT access 110 do { dma_cache_sync((ndev)->dev.parent, (void *)addr, len, DMA_BIDIRECTIONAL); } while (0)
166 * the following commands are available (p5-18). The 32-bit port command 111
167 * must be word-swapped with the most significant word written first. 112#define SYSBUS 0x0000006c;
168 * This only applies to VME boards. 113
169 */ 114/* big endian CPU, 82596 "big" endian mode */
170#define PORT_RESET 0x00 /* reset 82596 */ 115#define SWAP32(x) (((u32)(x)<<16) | ((((u32)(x)))>>16))
171#define PORT_SELFTEST 0x01 /* selftest */ 116#define SWAP16(x) (x)
172#define PORT_ALTSCP 0x02 /* alternate SCB address */
173#define PORT_ALTDUMP 0x03 /* Alternate DUMP address */
174 117
175static int i596_debug = (DEB_SERIOUS|DEB_PROBE); 118#include "lib82596.c"
176 119
177MODULE_AUTHOR("Richard Hirst"); 120MODULE_AUTHOR("Richard Hirst");
178MODULE_DESCRIPTION("i82596 driver"); 121MODULE_DESCRIPTION("i82596 driver");
@@ -180,255 +123,15 @@ MODULE_LICENSE("GPL");
180module_param(i596_debug, int, 0); 123module_param(i596_debug, int, 0);
181MODULE_PARM_DESC(i596_debug, "lasi_82596 debug mask"); 124MODULE_PARM_DESC(i596_debug, "lasi_82596 debug mask");
182 125
183/* Copy frames shorter than rx_copybreak, otherwise pass on up in 126static inline void ca(struct net_device *dev)
184 * a full sized sk_buff. Value of 100 stolen from tulip.c (!alpha).
185 */
186static int rx_copybreak = 100;
187
188#define MAX_DRIVERS 4 /* max count of drivers */
189
190#define PKT_BUF_SZ 1536
191#define MAX_MC_CNT 64
192
193#define I596_NULL ((u32)0xffffffff)
194
195#define CMD_EOL 0x8000 /* The last command of the list, stop. */
196#define CMD_SUSP 0x4000 /* Suspend after doing cmd. */
197#define CMD_INTR 0x2000 /* Interrupt after doing cmd. */
198
199#define CMD_FLEX 0x0008 /* Enable flexible memory model */
200
201enum commands {
202 CmdNOp = 0, CmdSASetup = 1, CmdConfigure = 2, CmdMulticastList = 3,
203 CmdTx = 4, CmdTDR = 5, CmdDump = 6, CmdDiagnose = 7
204};
205
206#define STAT_C 0x8000 /* Set to 0 after execution */
207#define STAT_B 0x4000 /* Command being executed */
208#define STAT_OK 0x2000 /* Command executed ok */
209#define STAT_A 0x1000 /* Command aborted */
210
211#define CUC_START 0x0100
212#define CUC_RESUME 0x0200
213#define CUC_SUSPEND 0x0300
214#define CUC_ABORT 0x0400
215#define RX_START 0x0010
216#define RX_RESUME 0x0020
217#define RX_SUSPEND 0x0030
218#define RX_ABORT 0x0040
219
220#define TX_TIMEOUT 5
221
222#define OPT_SWAP_PORT 0x0001 /* Need to wordswp on the MPU port */
223
224
225struct i596_reg {
226 unsigned short porthi;
227 unsigned short portlo;
228 u32 ca;
229};
230
231#define EOF 0x8000
232#define SIZE_MASK 0x3fff
233
234struct i596_tbd {
235 unsigned short size;
236 unsigned short pad;
237 dma_addr_t next;
238 dma_addr_t data;
239 u32 cache_pad[5]; /* Total 32 bytes... */
240};
241
242/* The command structure has two 'next' pointers; v_next is the address of
243 * the next command as seen by the CPU, b_next is the address of the next
244 * command as seen by the 82596. The b_next pointer, as used by the 82596
245 * always references the status field of the next command, rather than the
246 * v_next field, because the 82596 is unaware of v_next. It may seem more
247 * logical to put v_next at the end of the structure, but we cannot do that
248 * because the 82596 expects other fields to be there, depending on command
249 * type.
250 */
251
252struct i596_cmd {
253 struct i596_cmd *v_next; /* Address from CPUs viewpoint */
254 unsigned short status;
255 unsigned short command;
256 dma_addr_t b_next; /* Address from i596 viewpoint */
257};
258
259struct tx_cmd {
260 struct i596_cmd cmd;
261 dma_addr_t tbd;
262 unsigned short size;
263 unsigned short pad;
264 struct sk_buff *skb; /* So we can free it after tx */
265 dma_addr_t dma_addr;
266#ifdef __LP64__
267 u32 cache_pad[6]; /* Total 64 bytes... */
268#else
269 u32 cache_pad[1]; /* Total 32 bytes... */
270#endif
271};
272
273struct tdr_cmd {
274 struct i596_cmd cmd;
275 unsigned short status;
276 unsigned short pad;
277};
278
279struct mc_cmd {
280 struct i596_cmd cmd;
281 short mc_cnt;
282 char mc_addrs[MAX_MC_CNT*6];
283};
284
285struct sa_cmd {
286 struct i596_cmd cmd;
287 char eth_addr[8];
288};
289
290struct cf_cmd {
291 struct i596_cmd cmd;
292 char i596_config[16];
293};
294
295struct i596_rfd {
296 unsigned short stat;
297 unsigned short cmd;
298 dma_addr_t b_next; /* Address from i596 viewpoint */
299 dma_addr_t rbd;
300 unsigned short count;
301 unsigned short size;
302 struct i596_rfd *v_next; /* Address from CPUs viewpoint */
303 struct i596_rfd *v_prev;
304#ifndef __LP64__
305 u32 cache_pad[2]; /* Total 32 bytes... */
306#endif
307};
308
309struct i596_rbd {
310 /* hardware data */
311 unsigned short count;
312 unsigned short zero1;
313 dma_addr_t b_next;
314 dma_addr_t b_data; /* Address from i596 viewpoint */
315 unsigned short size;
316 unsigned short zero2;
317 /* driver data */
318 struct sk_buff *skb;
319 struct i596_rbd *v_next;
320 dma_addr_t b_addr; /* This rbd addr from i596 view */
321 unsigned char *v_data; /* Address from CPUs viewpoint */
322 /* Total 32 bytes... */
323#ifdef __LP64__
324 u32 cache_pad[4];
325#endif
326};
327
328/* These values as chosen so struct i596_private fits in one page... */
329
330#define TX_RING_SIZE 32
331#define RX_RING_SIZE 16
332
333struct i596_scb {
334 unsigned short status;
335 unsigned short command;
336 dma_addr_t cmd;
337 dma_addr_t rfd;
338 u32 crc_err;
339 u32 align_err;
340 u32 resource_err;
341 u32 over_err;
342 u32 rcvdt_err;
343 u32 short_err;
344 unsigned short t_on;
345 unsigned short t_off;
346};
347
348struct i596_iscp {
349 u32 stat;
350 dma_addr_t scb;
351};
352
353struct i596_scp {
354 u32 sysbus;
355 u32 pad;
356 dma_addr_t iscp;
357};
358
359struct i596_private {
360 volatile struct i596_scp scp __attribute__((aligned(32)));
361 volatile struct i596_iscp iscp __attribute__((aligned(32)));
362 volatile struct i596_scb scb __attribute__((aligned(32)));
363 struct sa_cmd sa_cmd __attribute__((aligned(32)));
364 struct cf_cmd cf_cmd __attribute__((aligned(32)));
365 struct tdr_cmd tdr_cmd __attribute__((aligned(32)));
366 struct mc_cmd mc_cmd __attribute__((aligned(32)));
367 struct i596_rfd rfds[RX_RING_SIZE] __attribute__((aligned(32)));
368 struct i596_rbd rbds[RX_RING_SIZE] __attribute__((aligned(32)));
369 struct tx_cmd tx_cmds[TX_RING_SIZE] __attribute__((aligned(32)));
370 struct i596_tbd tbds[TX_RING_SIZE] __attribute__((aligned(32)));
371 u32 stat;
372 int last_restart;
373 struct i596_rfd *rfd_head;
374 struct i596_rbd *rbd_head;
375 struct i596_cmd *cmd_tail;
376 struct i596_cmd *cmd_head;
377 int cmd_backlog;
378 u32 last_cmd;
379 struct net_device_stats stats;
380 int next_tx_cmd;
381 int options;
382 spinlock_t lock;
383 dma_addr_t dma_addr;
384 struct device *dev;
385};
386
387static const char init_setup[] =
388{
389 0x8E, /* length, prefetch on */
390 0xC8, /* fifo to 8, monitor off */
391 0x80, /* don't save bad frames */
392 0x2E, /* No source address insertion, 8 byte preamble */
393 0x00, /* priority and backoff defaults */
394 0x60, /* interframe spacing */
395 0x00, /* slot time LSB */
396 0xf2, /* slot time and retries */
397 0x00, /* promiscuous mode */
398 0x00, /* collision detect */
399 0x40, /* minimum frame length */
400 0xff,
401 0x00,
402 0x7f /* *multi IA */ };
403
404static int i596_open(struct net_device *dev);
405static int i596_start_xmit(struct sk_buff *skb, struct net_device *dev);
406static irqreturn_t i596_interrupt(int irq, void *dev_id);
407static int i596_close(struct net_device *dev);
408static struct net_device_stats *i596_get_stats(struct net_device *dev);
409static void i596_add_cmd(struct net_device *dev, struct i596_cmd *cmd);
410static void i596_tx_timeout (struct net_device *dev);
411static void print_eth(unsigned char *buf, char *str);
412static void set_multicast_list(struct net_device *dev);
413
414static int rx_ring_size = RX_RING_SIZE;
415static int ticks_limit = 100;
416static int max_cmd_backlog = TX_RING_SIZE-1;
417
418#ifdef CONFIG_NET_POLL_CONTROLLER
419static void i596_poll_controller(struct net_device *dev);
420#endif
421
422
423static inline void CA(struct net_device *dev)
424{ 127{
425 gsc_writel(0, dev->base_addr + PA_CHANNEL_ATTENTION); 128 gsc_writel(0, dev->base_addr + PA_CHANNEL_ATTENTION);
426} 129}
427 130
428 131
429static inline void MPU_PORT(struct net_device *dev, int c, dma_addr_t x) 132static void mpu_port(struct net_device *dev, int c, dma_addr_t x)
430{ 133{
431 struct i596_private *lp = dev->priv; 134 struct i596_private *lp = netdev_priv(dev);
432 135
433 u32 v = (u32) (c) | (u32) (x); 136 u32 v = (u32) (c) | (u32) (x);
434 u16 a, b; 137 u16 a, b;
@@ -446,1078 +149,15 @@ static inline void MPU_PORT(struct net_device *dev, int c, dma_addr_t x)
446 gsc_writel(b, dev->base_addr + PA_CPU_PORT_L_ACCESS); 149 gsc_writel(b, dev->base_addr + PA_CPU_PORT_L_ACCESS);
447} 150}
448 151
449
450static inline int wait_istat(struct net_device *dev, struct i596_private *lp, int delcnt, char *str)
451{
452 CHECK_INV(lp, &(lp->iscp), sizeof(struct i596_iscp));
453 while (--delcnt && lp->iscp.stat) {
454 udelay(10);
455 CHECK_INV(lp, &(lp->iscp), sizeof(struct i596_iscp));
456 }
457 if (!delcnt) {
458 printk("%s: %s, iscp.stat %04x, didn't clear\n",
459 dev->name, str, lp->iscp.stat);
460 return -1;
461 }
462 else
463 return 0;
464}
465
466
467static inline int wait_cmd(struct net_device *dev, struct i596_private *lp, int delcnt, char *str)
468{
469 CHECK_INV(lp, &(lp->scb), sizeof(struct i596_scb));
470 while (--delcnt && lp->scb.command) {
471 udelay(10);
472 CHECK_INV(lp, &(lp->scb), sizeof(struct i596_scb));
473 }
474 if (!delcnt) {
475 printk("%s: %s, status %4.4x, cmd %4.4x.\n",
476 dev->name, str, lp->scb.status, lp->scb.command);
477 return -1;
478 }
479 else
480 return 0;
481}
482
483
484static void i596_display_data(struct net_device *dev)
485{
486 struct i596_private *lp = dev->priv;
487 struct i596_cmd *cmd;
488 struct i596_rfd *rfd;
489 struct i596_rbd *rbd;
490
491 printk("lp and scp at %p, .sysbus = %08x, .iscp = %08x\n",
492 &lp->scp, lp->scp.sysbus, lp->scp.iscp);
493 printk("iscp at %p, iscp.stat = %08x, .scb = %08x\n",
494 &lp->iscp, lp->iscp.stat, lp->iscp.scb);
495 printk("scb at %p, scb.status = %04x, .command = %04x,"
496 " .cmd = %08x, .rfd = %08x\n",
497 &lp->scb, lp->scb.status, lp->scb.command,
498 lp->scb.cmd, lp->scb.rfd);
499 printk(" errors: crc %x, align %x, resource %x,"
500 " over %x, rcvdt %x, short %x\n",
501 lp->scb.crc_err, lp->scb.align_err, lp->scb.resource_err,
502 lp->scb.over_err, lp->scb.rcvdt_err, lp->scb.short_err);
503 cmd = lp->cmd_head;
504 while (cmd != NULL) {
505 printk("cmd at %p, .status = %04x, .command = %04x, .b_next = %08x\n",
506 cmd, cmd->status, cmd->command, cmd->b_next);
507 cmd = cmd->v_next;
508 }
509 rfd = lp->rfd_head;
510 printk("rfd_head = %p\n", rfd);
511 do {
512 printk(" %p .stat %04x, .cmd %04x, b_next %08x, rbd %08x,"
513 " count %04x\n",
514 rfd, rfd->stat, rfd->cmd, rfd->b_next, rfd->rbd,
515 rfd->count);
516 rfd = rfd->v_next;
517 } while (rfd != lp->rfd_head);
518 rbd = lp->rbd_head;
519 printk("rbd_head = %p\n", rbd);
520 do {
521 printk(" %p .count %04x, b_next %08x, b_data %08x, size %04x\n",
522 rbd, rbd->count, rbd->b_next, rbd->b_data, rbd->size);
523 rbd = rbd->v_next;
524 } while (rbd != lp->rbd_head);
525 CHECK_INV(lp, lp, sizeof(struct i596_private));
526}
527
528
529#if defined(ENABLE_MVME16x_NET) || defined(ENABLE_BVME6000_NET)
530static void i596_error(int irq, void *dev_id)
531{
532 struct net_device *dev = dev_id;
533 volatile unsigned char *pcc2 = (unsigned char *) 0xfff42000;
534
535 pcc2[0x28] = 1;
536 pcc2[0x2b] = 0x1d;
537 printk("%s: Error interrupt\n", dev->name);
538 i596_display_data(dev);
539}
540#endif
541
542#define virt_to_dma(lp,v) ((lp)->dma_addr + (dma_addr_t)((unsigned long)(v)-(unsigned long)(lp)))
543
544static inline void init_rx_bufs(struct net_device *dev)
545{
546 struct i596_private *lp = dev->priv;
547 int i;
548 struct i596_rfd *rfd;
549 struct i596_rbd *rbd;
550
551 /* First build the Receive Buffer Descriptor List */
552
553 for (i = 0, rbd = lp->rbds; i < rx_ring_size; i++, rbd++) {
554 dma_addr_t dma_addr;
555 struct sk_buff *skb = dev_alloc_skb(PKT_BUF_SZ + 4);
556
557 if (skb == NULL)
558 panic("%s: alloc_skb() failed", __FILE__);
559 skb_reserve(skb, 2);
560 dma_addr = dma_map_single(lp->dev, skb->data,PKT_BUF_SZ,
561 DMA_FROM_DEVICE);
562 skb->dev = dev;
563 rbd->v_next = rbd+1;
564 rbd->b_next = WSWAPrbd(virt_to_dma(lp,rbd+1));
565 rbd->b_addr = WSWAPrbd(virt_to_dma(lp,rbd));
566 rbd->skb = skb;
567 rbd->v_data = skb->data;
568 rbd->b_data = WSWAPchar(dma_addr);
569 rbd->size = PKT_BUF_SZ;
570 }
571 lp->rbd_head = lp->rbds;
572 rbd = lp->rbds + rx_ring_size - 1;
573 rbd->v_next = lp->rbds;
574 rbd->b_next = WSWAPrbd(virt_to_dma(lp,lp->rbds));
575
576 /* Now build the Receive Frame Descriptor List */
577
578 for (i = 0, rfd = lp->rfds; i < rx_ring_size; i++, rfd++) {
579 rfd->rbd = I596_NULL;
580 rfd->v_next = rfd+1;
581 rfd->v_prev = rfd-1;
582 rfd->b_next = WSWAPrfd(virt_to_dma(lp,rfd+1));
583 rfd->cmd = CMD_FLEX;
584 }
585 lp->rfd_head = lp->rfds;
586 lp->scb.rfd = WSWAPrfd(virt_to_dma(lp,lp->rfds));
587 rfd = lp->rfds;
588 rfd->rbd = WSWAPrbd(virt_to_dma(lp,lp->rbd_head));
589 rfd->v_prev = lp->rfds + rx_ring_size - 1;
590 rfd = lp->rfds + rx_ring_size - 1;
591 rfd->v_next = lp->rfds;
592 rfd->b_next = WSWAPrfd(virt_to_dma(lp,lp->rfds));
593 rfd->cmd = CMD_EOL|CMD_FLEX;
594
595 CHECK_WBACK_INV(lp, lp, sizeof(struct i596_private));
596}
597
598static inline void remove_rx_bufs(struct net_device *dev)
599{
600 struct i596_private *lp = dev->priv;
601 struct i596_rbd *rbd;
602 int i;
603
604 for (i = 0, rbd = lp->rbds; i < rx_ring_size; i++, rbd++) {
605 if (rbd->skb == NULL)
606 break;
607 dma_unmap_single(lp->dev,
608 (dma_addr_t)WSWAPchar(rbd->b_data),
609 PKT_BUF_SZ, DMA_FROM_DEVICE);
610 dev_kfree_skb(rbd->skb);
611 }
612}
613
614
615static void rebuild_rx_bufs(struct net_device *dev)
616{
617 struct i596_private *lp = dev->priv;
618 int i;
619
620 /* Ensure rx frame/buffer descriptors are tidy */
621
622 for (i = 0; i < rx_ring_size; i++) {
623 lp->rfds[i].rbd = I596_NULL;
624 lp->rfds[i].cmd = CMD_FLEX;
625 }
626 lp->rfds[rx_ring_size-1].cmd = CMD_EOL|CMD_FLEX;
627 lp->rfd_head = lp->rfds;
628 lp->scb.rfd = WSWAPrfd(virt_to_dma(lp,lp->rfds));
629 lp->rbd_head = lp->rbds;
630 lp->rfds[0].rbd = WSWAPrbd(virt_to_dma(lp,lp->rbds));
631
632 CHECK_WBACK_INV(lp, lp, sizeof(struct i596_private));
633}
634
635
636static int init_i596_mem(struct net_device *dev)
637{
638 struct i596_private *lp = dev->priv;
639 unsigned long flags;
640
641 disable_irq(dev->irq); /* disable IRQs from LAN */
642 DEB(DEB_INIT,
643 printk("RESET 82596 port: %lx (with IRQ %d disabled)\n",
644 (dev->base_addr + PA_I82596_RESET),
645 dev->irq));
646
647 gsc_writel(0, (dev->base_addr + PA_I82596_RESET)); /* Hard Reset */
648 udelay(100); /* Wait 100us - seems to help */
649
650 /* change the scp address */
651
652 lp->last_cmd = jiffies;
653
654
655 lp->scp.sysbus = 0x0000006c;
656 lp->scp.iscp = WSWAPiscp(virt_to_dma(lp,&(lp->iscp)));
657 lp->iscp.scb = WSWAPscb(virt_to_dma(lp,&(lp->scb)));
658 lp->iscp.stat = ISCP_BUSY;
659 lp->cmd_backlog = 0;
660
661 lp->cmd_head = NULL;
662 lp->scb.cmd = I596_NULL;
663
664 DEB(DEB_INIT, printk("%s: starting i82596.\n", dev->name));
665
666 CHECK_WBACK(lp, &(lp->scp), sizeof(struct i596_scp));
667 CHECK_WBACK(lp, &(lp->iscp), sizeof(struct i596_iscp));
668
669 MPU_PORT(dev, PORT_ALTSCP, virt_to_dma(lp,&lp->scp));
670
671 CA(dev);
672
673 if (wait_istat(dev, lp, 1000, "initialization timed out"))
674 goto failed;
675 DEB(DEB_INIT, printk("%s: i82596 initialization successful\n", dev->name));
676
677 /* Ensure rx frame/buffer descriptors are tidy */
678 rebuild_rx_bufs(dev);
679
680 lp->scb.command = 0;
681 CHECK_WBACK(lp, &(lp->scb), sizeof(struct i596_scb));
682
683 enable_irq(dev->irq); /* enable IRQs from LAN */
684
685 DEB(DEB_INIT, printk("%s: queuing CmdConfigure\n", dev->name));
686 memcpy(lp->cf_cmd.i596_config, init_setup, sizeof(init_setup));
687 lp->cf_cmd.cmd.command = CmdConfigure;
688 CHECK_WBACK(lp, &(lp->cf_cmd), sizeof(struct cf_cmd));
689 i596_add_cmd(dev, &lp->cf_cmd.cmd);
690
691 DEB(DEB_INIT, printk("%s: queuing CmdSASetup\n", dev->name));
692 memcpy(lp->sa_cmd.eth_addr, dev->dev_addr, 6);
693 lp->sa_cmd.cmd.command = CmdSASetup;
694 CHECK_WBACK(lp, &(lp->sa_cmd), sizeof(struct sa_cmd));
695 i596_add_cmd(dev, &lp->sa_cmd.cmd);
696
697 DEB(DEB_INIT, printk("%s: queuing CmdTDR\n", dev->name));
698 lp->tdr_cmd.cmd.command = CmdTDR;
699 CHECK_WBACK(lp, &(lp->tdr_cmd), sizeof(struct tdr_cmd));
700 i596_add_cmd(dev, &lp->tdr_cmd.cmd);
701
702 spin_lock_irqsave (&lp->lock, flags);
703
704 if (wait_cmd(dev, lp, 1000, "timed out waiting to issue RX_START")) {
705 spin_unlock_irqrestore (&lp->lock, flags);
706 goto failed;
707 }
708 DEB(DEB_INIT, printk("%s: Issuing RX_START\n", dev->name));
709 lp->scb.command = RX_START;
710 lp->scb.rfd = WSWAPrfd(virt_to_dma(lp,lp->rfds));
711 CHECK_WBACK(lp, &(lp->scb), sizeof(struct i596_scb));
712
713 CA(dev);
714
715 spin_unlock_irqrestore (&lp->lock, flags);
716
717 if (wait_cmd(dev, lp, 1000, "RX_START not processed"))
718 goto failed;
719 DEB(DEB_INIT, printk("%s: Receive unit started OK\n", dev->name));
720
721 return 0;
722
723failed:
724 printk("%s: Failed to initialise 82596\n", dev->name);
725 MPU_PORT(dev, PORT_RESET, 0);
726 return -1;
727}
728
729
730static inline int i596_rx(struct net_device *dev)
731{
732 struct i596_private *lp = dev->priv;
733 struct i596_rfd *rfd;
734 struct i596_rbd *rbd;
735 int frames = 0;
736
737 DEB(DEB_RXFRAME, printk("i596_rx(), rfd_head %p, rbd_head %p\n",
738 lp->rfd_head, lp->rbd_head));
739
740
741 rfd = lp->rfd_head; /* Ref next frame to check */
742
743 CHECK_INV(lp, rfd, sizeof(struct i596_rfd));
744 while ((rfd->stat) & STAT_C) { /* Loop while complete frames */
745 if (rfd->rbd == I596_NULL)
746 rbd = NULL;
747 else if (rfd->rbd == lp->rbd_head->b_addr) {
748 rbd = lp->rbd_head;
749 CHECK_INV(lp, rbd, sizeof(struct i596_rbd));
750 }
751 else {
752 printk("%s: rbd chain broken!\n", dev->name);
753 /* XXX Now what? */
754 rbd = NULL;
755 }
756 DEB(DEB_RXFRAME, printk(" rfd %p, rfd.rbd %08x, rfd.stat %04x\n",
757 rfd, rfd->rbd, rfd->stat));
758
759 if (rbd != NULL && ((rfd->stat) & STAT_OK)) {
760 /* a good frame */
761 int pkt_len = rbd->count & 0x3fff;
762 struct sk_buff *skb = rbd->skb;
763 int rx_in_place = 0;
764
765 DEB(DEB_RXADDR,print_eth(rbd->v_data, "received"));
766 frames++;
767
768 /* Check if the packet is long enough to just accept
769 * without copying to a properly sized skbuff.
770 */
771
772 if (pkt_len > rx_copybreak) {
773 struct sk_buff *newskb;
774 dma_addr_t dma_addr;
775
776 dma_unmap_single(lp->dev,(dma_addr_t)WSWAPchar(rbd->b_data), PKT_BUF_SZ, DMA_FROM_DEVICE);
777 /* Get fresh skbuff to replace filled one. */
778 newskb = dev_alloc_skb(PKT_BUF_SZ + 4);
779 if (newskb == NULL) {
780 skb = NULL; /* drop pkt */
781 goto memory_squeeze;
782 }
783 skb_reserve(newskb, 2);
784
785 /* Pass up the skb already on the Rx ring. */
786 skb_put(skb, pkt_len);
787 rx_in_place = 1;
788 rbd->skb = newskb;
789 newskb->dev = dev;
790 dma_addr = dma_map_single(lp->dev, newskb->data, PKT_BUF_SZ, DMA_FROM_DEVICE);
791 rbd->v_data = newskb->data;
792 rbd->b_data = WSWAPchar(dma_addr);
793 CHECK_WBACK_INV(lp, rbd, sizeof(struct i596_rbd));
794 }
795 else
796 skb = dev_alloc_skb(pkt_len + 2);
797memory_squeeze:
798 if (skb == NULL) {
799 /* XXX tulip.c can defer packets here!! */
800 printk("%s: i596_rx Memory squeeze, dropping packet.\n", dev->name);
801 lp->stats.rx_dropped++;
802 }
803 else {
804 if (!rx_in_place) {
805 /* 16 byte align the data fields */
806 dma_sync_single_for_cpu(lp->dev, (dma_addr_t)WSWAPchar(rbd->b_data), PKT_BUF_SZ, DMA_FROM_DEVICE);
807 skb_reserve(skb, 2);
808 memcpy(skb_put(skb,pkt_len), rbd->v_data, pkt_len);
809 dma_sync_single_for_device(lp->dev, (dma_addr_t)WSWAPchar(rbd->b_data), PKT_BUF_SZ, DMA_FROM_DEVICE);
810 }
811 skb->len = pkt_len;
812 skb->protocol=eth_type_trans(skb,dev);
813 netif_rx(skb);
814 dev->last_rx = jiffies;
815 lp->stats.rx_packets++;
816 lp->stats.rx_bytes+=pkt_len;
817 }
818 }
819 else {
820 DEB(DEB_ERRORS, printk("%s: Error, rfd.stat = 0x%04x\n",
821 dev->name, rfd->stat));
822 lp->stats.rx_errors++;
823 if ((rfd->stat) & 0x0001)
824 lp->stats.collisions++;
825 if ((rfd->stat) & 0x0080)
826 lp->stats.rx_length_errors++;
827 if ((rfd->stat) & 0x0100)
828 lp->stats.rx_over_errors++;
829 if ((rfd->stat) & 0x0200)
830 lp->stats.rx_fifo_errors++;
831 if ((rfd->stat) & 0x0400)
832 lp->stats.rx_frame_errors++;
833 if ((rfd->stat) & 0x0800)
834 lp->stats.rx_crc_errors++;
835 if ((rfd->stat) & 0x1000)
836 lp->stats.rx_length_errors++;
837 }
838
839 /* Clear the buffer descriptor count and EOF + F flags */
840
841 if (rbd != NULL && (rbd->count & 0x4000)) {
842 rbd->count = 0;
843 lp->rbd_head = rbd->v_next;
844 CHECK_WBACK_INV(lp, rbd, sizeof(struct i596_rbd));
845 }
846
847 /* Tidy the frame descriptor, marking it as end of list */
848
849 rfd->rbd = I596_NULL;
850 rfd->stat = 0;
851 rfd->cmd = CMD_EOL|CMD_FLEX;
852 rfd->count = 0;
853
854 /* Remove end-of-list from old end descriptor */
855
856 rfd->v_prev->cmd = CMD_FLEX;
857
858 /* Update record of next frame descriptor to process */
859
860 lp->scb.rfd = rfd->b_next;
861 lp->rfd_head = rfd->v_next;
862 CHECK_WBACK_INV(lp, rfd->v_prev, sizeof(struct i596_rfd));
863 CHECK_WBACK_INV(lp, rfd, sizeof(struct i596_rfd));
864 rfd = lp->rfd_head;
865 CHECK_INV(lp, rfd, sizeof(struct i596_rfd));
866 }
867
868 DEB(DEB_RXFRAME, printk("frames %d\n", frames));
869
870 return 0;
871}
872
873
874static inline void i596_cleanup_cmd(struct net_device *dev, struct i596_private *lp)
875{
876 struct i596_cmd *ptr;
877
878 while (lp->cmd_head != NULL) {
879 ptr = lp->cmd_head;
880 lp->cmd_head = ptr->v_next;
881 lp->cmd_backlog--;
882
883 switch ((ptr->command) & 0x7) {
884 case CmdTx:
885 {
886 struct tx_cmd *tx_cmd = (struct tx_cmd *) ptr;
887 struct sk_buff *skb = tx_cmd->skb;
888 dma_unmap_single(lp->dev, tx_cmd->dma_addr, skb->len, DMA_TO_DEVICE);
889
890 dev_kfree_skb(skb);
891
892 lp->stats.tx_errors++;
893 lp->stats.tx_aborted_errors++;
894
895 ptr->v_next = NULL;
896 ptr->b_next = I596_NULL;
897 tx_cmd->cmd.command = 0; /* Mark as free */
898 break;
899 }
900 default:
901 ptr->v_next = NULL;
902 ptr->b_next = I596_NULL;
903 }
904 CHECK_WBACK_INV(lp, ptr, sizeof(struct i596_cmd));
905 }
906
907 wait_cmd(dev, lp, 100, "i596_cleanup_cmd timed out");
908 lp->scb.cmd = I596_NULL;
909 CHECK_WBACK(lp, &(lp->scb), sizeof(struct i596_scb));
910}
911
912
913static inline void i596_reset(struct net_device *dev, struct i596_private *lp)
914{
915 unsigned long flags;
916
917 DEB(DEB_RESET, printk("i596_reset\n"));
918
919 spin_lock_irqsave (&lp->lock, flags);
920
921 wait_cmd(dev, lp, 100, "i596_reset timed out");
922
923 netif_stop_queue(dev);
924
925 /* FIXME: this command might cause an lpmc */
926 lp->scb.command = CUC_ABORT | RX_ABORT;
927 CHECK_WBACK(lp, &(lp->scb), sizeof(struct i596_scb));
928 CA(dev);
929
930 /* wait for shutdown */
931 wait_cmd(dev, lp, 1000, "i596_reset 2 timed out");
932 spin_unlock_irqrestore (&lp->lock, flags);
933
934 i596_cleanup_cmd(dev,lp);
935 i596_rx(dev);
936
937 netif_start_queue(dev);
938 init_i596_mem(dev);
939}
940
941
942static void i596_add_cmd(struct net_device *dev, struct i596_cmd *cmd)
943{
944 struct i596_private *lp = dev->priv;
945 unsigned long flags;
946
947 DEB(DEB_ADDCMD, printk("i596_add_cmd cmd_head %p\n", lp->cmd_head));
948
949 cmd->status = 0;
950 cmd->command |= (CMD_EOL | CMD_INTR);
951 cmd->v_next = NULL;
952 cmd->b_next = I596_NULL;
953 CHECK_WBACK(lp, cmd, sizeof(struct i596_cmd));
954
955 spin_lock_irqsave (&lp->lock, flags);
956
957 if (lp->cmd_head != NULL) {
958 lp->cmd_tail->v_next = cmd;
959 lp->cmd_tail->b_next = WSWAPcmd(virt_to_dma(lp,&cmd->status));
960 CHECK_WBACK(lp, lp->cmd_tail, sizeof(struct i596_cmd));
961 } else {
962 lp->cmd_head = cmd;
963 wait_cmd(dev, lp, 100, "i596_add_cmd timed out");
964 lp->scb.cmd = WSWAPcmd(virt_to_dma(lp,&cmd->status));
965 lp->scb.command = CUC_START;
966 CHECK_WBACK(lp, &(lp->scb), sizeof(struct i596_scb));
967 CA(dev);
968 }
969 lp->cmd_tail = cmd;
970 lp->cmd_backlog++;
971
972 spin_unlock_irqrestore (&lp->lock, flags);
973
974 if (lp->cmd_backlog > max_cmd_backlog) {
975 unsigned long tickssofar = jiffies - lp->last_cmd;
976
977 if (tickssofar < ticks_limit)
978 return;
979
980 printk("%s: command unit timed out, status resetting.\n", dev->name);
981#if 1
982 i596_reset(dev, lp);
983#endif
984 }
985}
986
987#if 0
988/* this function makes a perfectly adequate probe... but we have a
989 device list */
990static int i596_test(struct net_device *dev)
991{
992 struct i596_private *lp = dev->priv;
993 volatile int *tint;
994 u32 data;
995
996 tint = (volatile int *)(&(lp->scp));
997 data = virt_to_dma(lp,tint);
998
999 tint[1] = -1;
1000 CHECK_WBACK(lp, tint, PAGE_SIZE);
1001
1002 MPU_PORT(dev, 1, data);
1003
1004 for(data = 1000000; data; data--) {
1005 CHECK_INV(lp, tint, PAGE_SIZE);
1006 if(tint[1] != -1)
1007 break;
1008
1009 }
1010
1011 printk("i596_test result %d\n", tint[1]);
1012
1013}
1014#endif
1015
1016
1017static int i596_open(struct net_device *dev)
1018{
1019 DEB(DEB_OPEN, printk("%s: i596_open() irq %d.\n", dev->name, dev->irq));
1020
1021 if (request_irq(dev->irq, &i596_interrupt, 0, "i82596", dev)) {
1022 printk("%s: IRQ %d not free\n", dev->name, dev->irq);
1023 goto out;
1024 }
1025
1026 init_rx_bufs(dev);
1027
1028 if (init_i596_mem(dev)) {
1029 printk("%s: Failed to init memory\n", dev->name);
1030 goto out_remove_rx_bufs;
1031 }
1032
1033 netif_start_queue(dev);
1034
1035 return 0;
1036
1037out_remove_rx_bufs:
1038 remove_rx_bufs(dev);
1039 free_irq(dev->irq, dev);
1040out:
1041 return -EAGAIN;
1042}
1043
1044static void i596_tx_timeout (struct net_device *dev)
1045{
1046 struct i596_private *lp = dev->priv;
1047
1048 /* Transmitter timeout, serious problems. */
1049 DEB(DEB_ERRORS, printk("%s: transmit timed out, status resetting.\n",
1050 dev->name));
1051
1052 lp->stats.tx_errors++;
1053
1054 /* Try to restart the adaptor */
1055 if (lp->last_restart == lp->stats.tx_packets) {
1056 DEB(DEB_ERRORS, printk("Resetting board.\n"));
1057 /* Shutdown and restart */
1058 i596_reset (dev, lp);
1059 } else {
1060 /* Issue a channel attention signal */
1061 DEB(DEB_ERRORS, printk("Kicking board.\n"));
1062 lp->scb.command = CUC_START | RX_START;
1063 CHECK_WBACK_INV(lp, &(lp->scb), sizeof(struct i596_scb));
1064 CA (dev);
1065 lp->last_restart = lp->stats.tx_packets;
1066 }
1067
1068 dev->trans_start = jiffies;
1069 netif_wake_queue (dev);
1070}
1071
1072
1073static int i596_start_xmit(struct sk_buff *skb, struct net_device *dev)
1074{
1075 struct i596_private *lp = dev->priv;
1076 struct tx_cmd *tx_cmd;
1077 struct i596_tbd *tbd;
1078 short length = skb->len;
1079 dev->trans_start = jiffies;
1080
1081 DEB(DEB_STARTTX, printk("%s: i596_start_xmit(%x,%p) called\n", dev->name,
1082 skb->len, skb->data));
1083
1084 if (length < ETH_ZLEN) {
1085 if (skb_padto(skb, ETH_ZLEN))
1086 return 0;
1087 length = ETH_ZLEN;
1088 }
1089
1090 netif_stop_queue(dev);
1091
1092 tx_cmd = lp->tx_cmds + lp->next_tx_cmd;
1093 tbd = lp->tbds + lp->next_tx_cmd;
1094
1095 if (tx_cmd->cmd.command) {
1096 DEB(DEB_ERRORS, printk("%s: xmit ring full, dropping packet.\n",
1097 dev->name));
1098 lp->stats.tx_dropped++;
1099
1100 dev_kfree_skb(skb);
1101 } else {
1102 if (++lp->next_tx_cmd == TX_RING_SIZE)
1103 lp->next_tx_cmd = 0;
1104 tx_cmd->tbd = WSWAPtbd(virt_to_dma(lp,tbd));
1105 tbd->next = I596_NULL;
1106
1107 tx_cmd->cmd.command = CMD_FLEX | CmdTx;
1108 tx_cmd->skb = skb;
1109
1110 tx_cmd->pad = 0;
1111 tx_cmd->size = 0;
1112 tbd->pad = 0;
1113 tbd->size = EOF | length;
1114
1115 tx_cmd->dma_addr = dma_map_single(lp->dev, skb->data, skb->len,
1116 DMA_TO_DEVICE);
1117 tbd->data = WSWAPchar(tx_cmd->dma_addr);
1118
1119 DEB(DEB_TXADDR,print_eth(skb->data, "tx-queued"));
1120 CHECK_WBACK_INV(lp, tx_cmd, sizeof(struct tx_cmd));
1121 CHECK_WBACK_INV(lp, tbd, sizeof(struct i596_tbd));
1122 i596_add_cmd(dev, &tx_cmd->cmd);
1123
1124 lp->stats.tx_packets++;
1125 lp->stats.tx_bytes += length;
1126 }
1127
1128 netif_start_queue(dev);
1129
1130 return 0;
1131}
1132
1133static void print_eth(unsigned char *add, char *str)
1134{
1135 int i;
1136
1137 printk("i596 0x%p, ", add);
1138 for (i = 0; i < 6; i++)
1139 printk(" %02X", add[i + 6]);
1140 printk(" -->");
1141 for (i = 0; i < 6; i++)
1142 printk(" %02X", add[i]);
1143 printk(" %02X%02X, %s\n", add[12], add[13], str);
1144}
1145
1146
1147#define LAN_PROM_ADDR 0xF0810000 152#define LAN_PROM_ADDR 0xF0810000
1148 153
1149static int __devinit i82596_probe(struct net_device *dev,
1150 struct device *gen_dev)
1151{
1152 int i;
1153 struct i596_private *lp;
1154 char eth_addr[6];
1155 dma_addr_t dma_addr;
1156
1157 /* This lot is ensure things have been cache line aligned. */
1158 BUILD_BUG_ON(sizeof(struct i596_rfd) != 32);
1159 BUILD_BUG_ON(sizeof(struct i596_rbd) & 31);
1160 BUILD_BUG_ON(sizeof(struct tx_cmd) & 31);
1161 BUILD_BUG_ON(sizeof(struct i596_tbd) != 32);
1162#ifndef __LP64__
1163 BUILD_BUG_ON(sizeof(struct i596_private) > 4096);
1164#endif
1165
1166 if (!dev->base_addr || !dev->irq)
1167 return -ENODEV;
1168
1169 if (pdc_lan_station_id(eth_addr, dev->base_addr)) {
1170 for (i=0; i < 6; i++) {
1171 eth_addr[i] = gsc_readb(LAN_PROM_ADDR + i);
1172 }
1173 printk(KERN_INFO "%s: MAC of HP700 LAN read from EEPROM\n", __FILE__);
1174 }
1175
1176 dev->mem_start = (unsigned long) dma_alloc_noncoherent(gen_dev,
1177 sizeof(struct i596_private), &dma_addr, GFP_KERNEL);
1178 if (!dev->mem_start) {
1179 printk(KERN_ERR "%s: Couldn't get shared memory\n", __FILE__);
1180 return -ENOMEM;
1181 }
1182
1183 for (i = 0; i < 6; i++)
1184 dev->dev_addr[i] = eth_addr[i];
1185
1186 /* The 82596-specific entries in the device structure. */
1187 dev->open = i596_open;
1188 dev->stop = i596_close;
1189 dev->hard_start_xmit = i596_start_xmit;
1190 dev->get_stats = i596_get_stats;
1191 dev->set_multicast_list = set_multicast_list;
1192 dev->tx_timeout = i596_tx_timeout;
1193 dev->watchdog_timeo = TX_TIMEOUT;
1194#ifdef CONFIG_NET_POLL_CONTROLLER
1195 dev->poll_controller = i596_poll_controller;
1196#endif
1197
1198 dev->priv = (void *)(dev->mem_start);
1199
1200 lp = dev->priv;
1201 memset(lp, 0, sizeof(struct i596_private));
1202
1203 lp->scb.command = 0;
1204 lp->scb.cmd = I596_NULL;
1205 lp->scb.rfd = I596_NULL;
1206 spin_lock_init(&lp->lock);
1207 lp->dma_addr = dma_addr;
1208 lp->dev = gen_dev;
1209
1210 CHECK_WBACK_INV(lp, dev->mem_start, sizeof(struct i596_private));
1211
1212 i = register_netdev(dev);
1213 if (i) {
1214 lp = dev->priv;
1215 dma_free_noncoherent(lp->dev, sizeof(struct i596_private),
1216 (void *)dev->mem_start, lp->dma_addr);
1217 return i;
1218 };
1219
1220 DEB(DEB_PROBE, printk(KERN_INFO "%s: 82596 at %#3lx,", dev->name, dev->base_addr));
1221 for (i = 0; i < 6; i++)
1222 DEB(DEB_PROBE, printk(" %2.2X", dev->dev_addr[i]));
1223 DEB(DEB_PROBE, printk(" IRQ %d.\n", dev->irq));
1224 DEB(DEB_INIT, printk(KERN_INFO "%s: lp at 0x%p (%d bytes), lp->scb at 0x%p\n",
1225 dev->name, lp, (int)sizeof(struct i596_private), &lp->scb));
1226
1227 return 0;
1228}
1229
1230#ifdef CONFIG_NET_POLL_CONTROLLER
1231static void i596_poll_controller(struct net_device *dev)
1232{
1233 disable_irq(dev->irq);
1234 i596_interrupt(dev->irq, dev);
1235 enable_irq(dev->irq);
1236}
1237#endif
1238
1239static irqreturn_t i596_interrupt(int irq, void *dev_id)
1240{
1241 struct net_device *dev = dev_id;
1242 struct i596_private *lp;
1243 unsigned short status, ack_cmd = 0;
1244
1245 if (dev == NULL) {
1246 printk("%s: irq %d for unknown device.\n", __FUNCTION__, irq);
1247 return IRQ_NONE;
1248 }
1249
1250 lp = dev->priv;
1251
1252 spin_lock (&lp->lock);
1253
1254 wait_cmd(dev, lp, 100, "i596 interrupt, timeout");
1255 status = lp->scb.status;
1256
1257 DEB(DEB_INTS, printk("%s: i596 interrupt, IRQ %d, status %4.4x.\n",
1258 dev->name, irq, status));
1259
1260 ack_cmd = status & 0xf000;
1261
1262 if (!ack_cmd) {
1263 DEB(DEB_ERRORS, printk("%s: interrupt with no events\n", dev->name));
1264 spin_unlock (&lp->lock);
1265 return IRQ_NONE;
1266 }
1267
1268 if ((status & 0x8000) || (status & 0x2000)) {
1269 struct i596_cmd *ptr;
1270
1271 if ((status & 0x8000))
1272 DEB(DEB_INTS, printk("%s: i596 interrupt completed command.\n", dev->name));
1273 if ((status & 0x2000))
1274 DEB(DEB_INTS, printk("%s: i596 interrupt command unit inactive %x.\n", dev->name, status & 0x0700));
1275
1276 while (lp->cmd_head != NULL) {
1277 CHECK_INV(lp, lp->cmd_head, sizeof(struct i596_cmd));
1278 if (!(lp->cmd_head->status & STAT_C))
1279 break;
1280
1281 ptr = lp->cmd_head;
1282
1283 DEB(DEB_STATUS, printk("cmd_head->status = %04x, ->command = %04x\n",
1284 lp->cmd_head->status, lp->cmd_head->command));
1285 lp->cmd_head = ptr->v_next;
1286 lp->cmd_backlog--;
1287
1288 switch ((ptr->command) & 0x7) {
1289 case CmdTx:
1290 {
1291 struct tx_cmd *tx_cmd = (struct tx_cmd *) ptr;
1292 struct sk_buff *skb = tx_cmd->skb;
1293
1294 if ((ptr->status) & STAT_OK) {
1295 DEB(DEB_TXADDR, print_eth(skb->data, "tx-done"));
1296 } else {
1297 lp->stats.tx_errors++;
1298 if ((ptr->status) & 0x0020)
1299 lp->stats.collisions++;
1300 if (!((ptr->status) & 0x0040))
1301 lp->stats.tx_heartbeat_errors++;
1302 if ((ptr->status) & 0x0400)
1303 lp->stats.tx_carrier_errors++;
1304 if ((ptr->status) & 0x0800)
1305 lp->stats.collisions++;
1306 if ((ptr->status) & 0x1000)
1307 lp->stats.tx_aborted_errors++;
1308 }
1309 dma_unmap_single(lp->dev, tx_cmd->dma_addr, skb->len, DMA_TO_DEVICE);
1310 dev_kfree_skb_irq(skb);
1311
1312 tx_cmd->cmd.command = 0; /* Mark free */
1313 break;
1314 }
1315 case CmdTDR:
1316 {
1317 unsigned short status = ((struct tdr_cmd *)ptr)->status;
1318
1319 if (status & 0x8000) {
1320 DEB(DEB_ANY, printk("%s: link ok.\n", dev->name));
1321 } else {
1322 if (status & 0x4000)
1323 printk("%s: Transceiver problem.\n", dev->name);
1324 if (status & 0x2000)
1325 printk("%s: Termination problem.\n", dev->name);
1326 if (status & 0x1000)
1327 printk("%s: Short circuit.\n", dev->name);
1328
1329 DEB(DEB_TDR, printk("%s: Time %d.\n", dev->name, status & 0x07ff));
1330 }
1331 break;
1332 }
1333 case CmdConfigure:
1334 /* Zap command so set_multicast_list() knows it is free */
1335 ptr->command = 0;
1336 break;
1337 }
1338 ptr->v_next = NULL;
1339 ptr->b_next = I596_NULL;
1340 CHECK_WBACK(lp, ptr, sizeof(struct i596_cmd));
1341 lp->last_cmd = jiffies;
1342 }
1343
1344 /* This mess is arranging that only the last of any outstanding
1345 * commands has the interrupt bit set. Should probably really
1346 * only add to the cmd queue when the CU is stopped.
1347 */
1348 ptr = lp->cmd_head;
1349 while ((ptr != NULL) && (ptr != lp->cmd_tail)) {
1350 struct i596_cmd *prev = ptr;
1351
1352 ptr->command &= 0x1fff;
1353 ptr = ptr->v_next;
1354 CHECK_WBACK_INV(lp, prev, sizeof(struct i596_cmd));
1355 }
1356
1357 if ((lp->cmd_head != NULL))
1358 ack_cmd |= CUC_START;
1359 lp->scb.cmd = WSWAPcmd(virt_to_dma(lp,&lp->cmd_head->status));
1360 CHECK_WBACK_INV(lp, &lp->scb, sizeof(struct i596_scb));
1361 }
1362 if ((status & 0x1000) || (status & 0x4000)) {
1363 if ((status & 0x4000))
1364 DEB(DEB_INTS, printk("%s: i596 interrupt received a frame.\n", dev->name));
1365 i596_rx(dev);
1366 /* Only RX_START if stopped - RGH 07-07-96 */
1367 if (status & 0x1000) {
1368 if (netif_running(dev)) {
1369 DEB(DEB_ERRORS, printk("%s: i596 interrupt receive unit inactive, status 0x%x\n", dev->name, status));
1370 ack_cmd |= RX_START;
1371 lp->stats.rx_errors++;
1372 lp->stats.rx_fifo_errors++;
1373 rebuild_rx_bufs(dev);
1374 }
1375 }
1376 }
1377 wait_cmd(dev, lp, 100, "i596 interrupt, timeout");
1378 lp->scb.command = ack_cmd;
1379 CHECK_WBACK(lp, &lp->scb, sizeof(struct i596_scb));
1380
1381 /* DANGER: I suspect that some kind of interrupt
1382 acknowledgement aside from acking the 82596 might be needed
1383 here... but it's running acceptably without */
1384
1385 CA(dev);
1386
1387 wait_cmd(dev, lp, 100, "i596 interrupt, exit timeout");
1388 DEB(DEB_INTS, printk("%s: exiting interrupt.\n", dev->name));
1389
1390 spin_unlock (&lp->lock);
1391 return IRQ_HANDLED;
1392}
1393
1394static int i596_close(struct net_device *dev)
1395{
1396 struct i596_private *lp = dev->priv;
1397 unsigned long flags;
1398
1399 netif_stop_queue(dev);
1400
1401 DEB(DEB_INIT, printk("%s: Shutting down ethercard, status was %4.4x.\n",
1402 dev->name, lp->scb.status));
1403
1404 spin_lock_irqsave(&lp->lock, flags);
1405
1406 wait_cmd(dev, lp, 100, "close1 timed out");
1407 lp->scb.command = CUC_ABORT | RX_ABORT;
1408 CHECK_WBACK(lp, &lp->scb, sizeof(struct i596_scb));
1409
1410 CA(dev);
1411
1412 wait_cmd(dev, lp, 100, "close2 timed out");
1413 spin_unlock_irqrestore(&lp->lock, flags);
1414 DEB(DEB_STRUCT,i596_display_data(dev));
1415 i596_cleanup_cmd(dev,lp);
1416
1417 disable_irq(dev->irq);
1418
1419 free_irq(dev->irq, dev);
1420 remove_rx_bufs(dev);
1421
1422 return 0;
1423}
1424
1425static struct net_device_stats *
1426 i596_get_stats(struct net_device *dev)
1427{
1428 struct i596_private *lp = dev->priv;
1429
1430 return &lp->stats;
1431}
1432
1433/*
1434 * Set or clear the multicast filter for this adaptor.
1435 */
1436
1437static void set_multicast_list(struct net_device *dev)
1438{
1439 struct i596_private *lp = dev->priv;
1440 int config = 0, cnt;
1441
1442 DEB(DEB_MULTI, printk("%s: set multicast list, %d entries, promisc %s, allmulti %s\n",
1443 dev->name, dev->mc_count, dev->flags & IFF_PROMISC ? "ON" : "OFF",
1444 dev->flags & IFF_ALLMULTI ? "ON" : "OFF"));
1445
1446 if ((dev->flags & IFF_PROMISC) && !(lp->cf_cmd.i596_config[8] & 0x01)) {
1447 lp->cf_cmd.i596_config[8] |= 0x01;
1448 config = 1;
1449 }
1450 if (!(dev->flags & IFF_PROMISC) && (lp->cf_cmd.i596_config[8] & 0x01)) {
1451 lp->cf_cmd.i596_config[8] &= ~0x01;
1452 config = 1;
1453 }
1454 if ((dev->flags & IFF_ALLMULTI) && (lp->cf_cmd.i596_config[11] & 0x20)) {
1455 lp->cf_cmd.i596_config[11] &= ~0x20;
1456 config = 1;
1457 }
1458 if (!(dev->flags & IFF_ALLMULTI) && !(lp->cf_cmd.i596_config[11] & 0x20)) {
1459 lp->cf_cmd.i596_config[11] |= 0x20;
1460 config = 1;
1461 }
1462 if (config) {
1463 if (lp->cf_cmd.cmd.command)
1464 printk("%s: config change request already queued\n",
1465 dev->name);
1466 else {
1467 lp->cf_cmd.cmd.command = CmdConfigure;
1468 CHECK_WBACK_INV(lp, &lp->cf_cmd, sizeof(struct cf_cmd));
1469 i596_add_cmd(dev, &lp->cf_cmd.cmd);
1470 }
1471 }
1472
1473 cnt = dev->mc_count;
1474 if (cnt > MAX_MC_CNT)
1475 {
1476 cnt = MAX_MC_CNT;
1477 printk("%s: Only %d multicast addresses supported",
1478 dev->name, cnt);
1479 }
1480
1481 if (dev->mc_count > 0) {
1482 struct dev_mc_list *dmi;
1483 unsigned char *cp;
1484 struct mc_cmd *cmd;
1485
1486 cmd = &lp->mc_cmd;
1487 cmd->cmd.command = CmdMulticastList;
1488 cmd->mc_cnt = dev->mc_count * 6;
1489 cp = cmd->mc_addrs;
1490 for (dmi = dev->mc_list; cnt && dmi != NULL; dmi = dmi->next, cnt--, cp += 6) {
1491 memcpy(cp, dmi->dmi_addr, 6);
1492 if (i596_debug > 1)
1493 DEB(DEB_MULTI, printk("%s: Adding address %02x:%02x:%02x:%02x:%02x:%02x\n",
1494 dev->name, cp[0],cp[1],cp[2],cp[3],cp[4],cp[5]));
1495 }
1496 CHECK_WBACK_INV(lp, &lp->mc_cmd, sizeof(struct mc_cmd));
1497 i596_add_cmd(dev, &cmd->cmd);
1498 }
1499}
1500
1501static int debug = -1;
1502module_param(debug, int, 0);
1503MODULE_PARM_DESC(debug, "lasi_82596 debug mask");
1504
1505static int num_drivers;
1506static struct net_device *netdevs[MAX_DRIVERS];
1507
1508static int __devinit 154static int __devinit
1509lan_init_chip(struct parisc_device *dev) 155lan_init_chip(struct parisc_device *dev)
1510{ 156{
1511 struct net_device *netdevice; 157 struct net_device *netdevice;
158 struct i596_private *lp;
1512 int retval; 159 int retval;
1513 160 int i;
1514 if (num_drivers >= MAX_DRIVERS) {
1515 /* max count of possible i82596 drivers reached */
1516 return -ENOMEM;
1517 }
1518
1519 if (num_drivers == 0)
1520 printk(KERN_INFO LASI_82596_DRIVER_VERSION "\n");
1521 161
1522 if (!dev->irq) { 162 if (!dev->irq) {
1523 printk(KERN_ERR "%s: IRQ not found for i82596 at 0x%lx\n", 163 printk(KERN_ERR "%s: IRQ not found for i82596 at 0x%lx\n",
@@ -1528,28 +168,45 @@ lan_init_chip(struct parisc_device *dev)
1528 printk(KERN_INFO "Found i82596 at 0x%lx, IRQ %d\n", dev->hpa.start, 168 printk(KERN_INFO "Found i82596 at 0x%lx, IRQ %d\n", dev->hpa.start,
1529 dev->irq); 169 dev->irq);
1530 170
1531 netdevice = alloc_etherdev(0); 171 netdevice = alloc_etherdev(sizeof(struct i596_private));
1532 if (!netdevice) 172 if (!netdevice)
1533 return -ENOMEM; 173 return -ENOMEM;
174 SET_NETDEV_DEV(netdevice, &dev->dev);
175 parisc_set_drvdata (dev, netdevice);
1534 176
1535 netdevice->base_addr = dev->hpa.start; 177 netdevice->base_addr = dev->hpa.start;
1536 netdevice->irq = dev->irq; 178 netdevice->irq = dev->irq;
1537 179
1538 retval = i82596_probe(netdevice, &dev->dev); 180 if (pdc_lan_station_id(netdevice->dev_addr, netdevice->base_addr)) {
181 for (i = 0; i < 6; i++) {
182 netdevice->dev_addr[i] = gsc_readb(LAN_PROM_ADDR + i);
183 }
184 printk(KERN_INFO
185 "%s: MAC of HP700 LAN read from EEPROM\n", __FILE__);
186 }
187
188 lp = netdev_priv(netdevice);
189 lp->options = dev->id.sversion == 0x72 ? OPT_SWAP_PORT : 0;
190
191 retval = i82596_probe(netdevice);
1539 if (retval) { 192 if (retval) {
1540 free_netdev(netdevice); 193 free_netdev(netdevice);
1541 return -ENODEV; 194 return -ENODEV;
1542 } 195 }
1543
1544 if (dev->id.sversion == 0x72) {
1545 ((struct i596_private *)netdevice->priv)->options = OPT_SWAP_PORT;
1546 }
1547
1548 netdevs[num_drivers++] = netdevice;
1549
1550 return retval; 196 return retval;
1551} 197}
1552 198
199static int __devexit lan_remove_chip (struct parisc_device *pdev)
200{
201 struct net_device *dev = parisc_get_drvdata(pdev);
202 struct i596_private *lp = netdev_priv(dev);
203
204 unregister_netdev (dev);
205 DMA_FREE(&pdev->dev, sizeof(struct i596_private),
206 (void *)lp->dma, lp->dma_addr);
207 free_netdev (dev);
208 return 0;
209}
1553 210
1554static struct parisc_device_id lan_tbl[] = { 211static struct parisc_device_id lan_tbl[] = {
1555 { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0008a }, 212 { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0008a },
@@ -1563,12 +220,12 @@ static struct parisc_driver lan_driver = {
1563 .name = "lasi_82596", 220 .name = "lasi_82596",
1564 .id_table = lan_tbl, 221 .id_table = lan_tbl,
1565 .probe = lan_init_chip, 222 .probe = lan_init_chip,
223 .remove = __devexit_p(lan_remove_chip),
1566}; 224};
1567 225
1568static int __devinit lasi_82596_init(void) 226static int __devinit lasi_82596_init(void)
1569{ 227{
1570 if (debug >= 0) 228 printk(KERN_INFO LASI_82596_DRIVER_VERSION "\n");
1571 i596_debug = debug;
1572 return register_parisc_driver(&lan_driver); 229 return register_parisc_driver(&lan_driver);
1573} 230}
1574 231
@@ -1576,25 +233,6 @@ module_init(lasi_82596_init);
1576 233
1577static void __exit lasi_82596_exit(void) 234static void __exit lasi_82596_exit(void)
1578{ 235{
1579 int i;
1580
1581 for (i=0; i<MAX_DRIVERS; i++) {
1582 struct i596_private *lp;
1583 struct net_device *netdevice;
1584
1585 netdevice = netdevs[i];
1586 if (!netdevice)
1587 continue;
1588
1589 unregister_netdev(netdevice);
1590
1591 lp = netdevice->priv;
1592 dma_free_noncoherent(lp->dev, sizeof(struct i596_private),
1593 (void *)netdevice->mem_start, lp->dma_addr);
1594 free_netdev(netdevice);
1595 }
1596 num_drivers = 0;
1597
1598 unregister_parisc_driver(&lan_driver); 236 unregister_parisc_driver(&lan_driver);
1599} 237}
1600 238
diff --git a/drivers/net/lib82596.c b/drivers/net/lib82596.c
new file mode 100644
index 000000000000..5884f5bd04a4
--- /dev/null
+++ b/drivers/net/lib82596.c
@@ -0,0 +1,1434 @@
1/* lasi_82596.c -- driver for the intel 82596 ethernet controller, as
2 munged into HPPA boxen .
3
4 This driver is based upon 82596.c, original credits are below...
5 but there were too many hoops which HP wants jumped through to
6 keep this code in there in a sane manner.
7
8 3 primary sources of the mess --
9 1) hppa needs *lots* of cacheline flushing to keep this kind of
10 MMIO running.
11
12 2) The 82596 needs to see all of its pointers as their physical
13 address. Thus virt_to_bus/bus_to_virt are *everywhere*.
14
15 3) The implementation HP is using seems to be significantly pickier
16 about when and how the command and RX units are started. some
17 command ordering was changed.
18
19 Examination of the mach driver leads one to believe that there
20 might be a saner way to pull this off... anyone who feels like a
21 full rewrite can be my guest.
22
23 Split 02/13/2000 Sam Creasey (sammy@oh.verio.com)
24
25 02/01/2000 Initial modifications for parisc by Helge Deller (deller@gmx.de)
26 03/02/2000 changes for better/correct(?) cache-flushing (deller)
27*/
28
29/* 82596.c: A generic 82596 ethernet driver for linux. */
30/*
31 Based on Apricot.c
32 Written 1994 by Mark Evans.
33 This driver is for the Apricot 82596 bus-master interface
34
35 Modularised 12/94 Mark Evans
36
37
38 Modified to support the 82596 ethernet chips on 680x0 VME boards.
39 by Richard Hirst <richard@sleepie.demon.co.uk>
40 Renamed to be 82596.c
41
42 980825: Changed to receive directly in to sk_buffs which are
43 allocated at open() time. Eliminates copy on incoming frames
44 (small ones are still copied). Shared data now held in a
45 non-cached page, so we can run on 68060 in copyback mode.
46
47 TBD:
48 * look at deferring rx frames rather than discarding (as per tulip)
49 * handle tx ring full as per tulip
50 * performace test to tune rx_copybreak
51
52 Most of my modifications relate to the braindead big-endian
53 implementation by Intel. When the i596 is operating in
54 'big-endian' mode, it thinks a 32 bit value of 0x12345678
55 should be stored as 0x56781234. This is a real pain, when
56 you have linked lists which are shared by the 680x0 and the
57 i596.
58
59 Driver skeleton
60 Written 1993 by Donald Becker.
61 Copyright 1993 United States Government as represented by the Director,
62 National Security Agency. This software may only be used and distributed
63 according to the terms of the GNU General Public License as modified by SRC,
64 incorporated herein by reference.
65
66 The author may be reached as becker@scyld.com, or C/O
67 Scyld Computing Corporation, 410 Severn Ave., Suite 210, Annapolis MD 21403
68
69 */
70
71#include <linux/module.h>
72#include <linux/kernel.h>
73#include <linux/string.h>
74#include <linux/errno.h>
75#include <linux/ioport.h>
76#include <linux/slab.h>
77#include <linux/interrupt.h>
78#include <linux/delay.h>
79#include <linux/netdevice.h>
80#include <linux/etherdevice.h>
81#include <linux/skbuff.h>
82#include <linux/init.h>
83#include <linux/types.h>
84#include <linux/bitops.h>
85#include <linux/dma-mapping.h>
86#include <linux/io.h>
87#include <linux/irq.h>
88
89/* DEBUG flags
90 */
91
92#define DEB_INIT 0x0001
93#define DEB_PROBE 0x0002
94#define DEB_SERIOUS 0x0004
95#define DEB_ERRORS 0x0008
96#define DEB_MULTI 0x0010
97#define DEB_TDR 0x0020
98#define DEB_OPEN 0x0040
99#define DEB_RESET 0x0080
100#define DEB_ADDCMD 0x0100
101#define DEB_STATUS 0x0200
102#define DEB_STARTTX 0x0400
103#define DEB_RXADDR 0x0800
104#define DEB_TXADDR 0x1000
105#define DEB_RXFRAME 0x2000
106#define DEB_INTS 0x4000
107#define DEB_STRUCT 0x8000
108#define DEB_ANY 0xffff
109
110
111#define DEB(x, y) if (i596_debug & (x)) { y; }
112
113
114/*
115 * The MPU_PORT command allows direct access to the 82596. With PORT access
116 * the following commands are available (p5-18). The 32-bit port command
117 * must be word-swapped with the most significant word written first.
118 * This only applies to VME boards.
119 */
120#define PORT_RESET 0x00 /* reset 82596 */
121#define PORT_SELFTEST 0x01 /* selftest */
122#define PORT_ALTSCP 0x02 /* alternate SCB address */
123#define PORT_ALTDUMP 0x03 /* Alternate DUMP address */
124
125static int i596_debug = (DEB_SERIOUS|DEB_PROBE);
126
127/* Copy frames shorter than rx_copybreak, otherwise pass on up in
128 * a full sized sk_buff. Value of 100 stolen from tulip.c (!alpha).
129 */
130static int rx_copybreak = 100;
131
132#define PKT_BUF_SZ 1536
133#define MAX_MC_CNT 64
134
135#define ISCP_BUSY 0x0001
136
137#define I596_NULL ((u32)0xffffffff)
138
139#define CMD_EOL 0x8000 /* The last command of the list, stop. */
140#define CMD_SUSP 0x4000 /* Suspend after doing cmd. */
141#define CMD_INTR 0x2000 /* Interrupt after doing cmd. */
142
143#define CMD_FLEX 0x0008 /* Enable flexible memory model */
144
145enum commands {
146 CmdNOp = 0, CmdSASetup = 1, CmdConfigure = 2, CmdMulticastList = 3,
147 CmdTx = 4, CmdTDR = 5, CmdDump = 6, CmdDiagnose = 7
148};
149
150#define STAT_C 0x8000 /* Set to 0 after execution */
151#define STAT_B 0x4000 /* Command being executed */
152#define STAT_OK 0x2000 /* Command executed ok */
153#define STAT_A 0x1000 /* Command aborted */
154
155#define CUC_START 0x0100
156#define CUC_RESUME 0x0200
157#define CUC_SUSPEND 0x0300
158#define CUC_ABORT 0x0400
159#define RX_START 0x0010
160#define RX_RESUME 0x0020
161#define RX_SUSPEND 0x0030
162#define RX_ABORT 0x0040
163
164#define TX_TIMEOUT 5
165
166
167struct i596_reg {
168 unsigned short porthi;
169 unsigned short portlo;
170 u32 ca;
171};
172
173#define EOF 0x8000
174#define SIZE_MASK 0x3fff
175
176struct i596_tbd {
177 unsigned short size;
178 unsigned short pad;
179 dma_addr_t next;
180 dma_addr_t data;
181 u32 cache_pad[5]; /* Total 32 bytes... */
182};
183
184/* The command structure has two 'next' pointers; v_next is the address of
185 * the next command as seen by the CPU, b_next is the address of the next
186 * command as seen by the 82596. The b_next pointer, as used by the 82596
187 * always references the status field of the next command, rather than the
188 * v_next field, because the 82596 is unaware of v_next. It may seem more
189 * logical to put v_next at the end of the structure, but we cannot do that
190 * because the 82596 expects other fields to be there, depending on command
191 * type.
192 */
193
194struct i596_cmd {
195 struct i596_cmd *v_next; /* Address from CPUs viewpoint */
196 unsigned short status;
197 unsigned short command;
198 dma_addr_t b_next; /* Address from i596 viewpoint */
199};
200
201struct tx_cmd {
202 struct i596_cmd cmd;
203 dma_addr_t tbd;
204 unsigned short size;
205 unsigned short pad;
206 struct sk_buff *skb; /* So we can free it after tx */
207 dma_addr_t dma_addr;
208#ifdef __LP64__
209 u32 cache_pad[6]; /* Total 64 bytes... */
210#else
211 u32 cache_pad[1]; /* Total 32 bytes... */
212#endif
213};
214
215struct tdr_cmd {
216 struct i596_cmd cmd;
217 unsigned short status;
218 unsigned short pad;
219};
220
221struct mc_cmd {
222 struct i596_cmd cmd;
223 short mc_cnt;
224 char mc_addrs[MAX_MC_CNT*6];
225};
226
227struct sa_cmd {
228 struct i596_cmd cmd;
229 char eth_addr[8];
230};
231
232struct cf_cmd {
233 struct i596_cmd cmd;
234 char i596_config[16];
235};
236
237struct i596_rfd {
238 unsigned short stat;
239 unsigned short cmd;
240 dma_addr_t b_next; /* Address from i596 viewpoint */
241 dma_addr_t rbd;
242 unsigned short count;
243 unsigned short size;
244 struct i596_rfd *v_next; /* Address from CPUs viewpoint */
245 struct i596_rfd *v_prev;
246#ifndef __LP64__
247 u32 cache_pad[2]; /* Total 32 bytes... */
248#endif
249};
250
251struct i596_rbd {
252 /* hardware data */
253 unsigned short count;
254 unsigned short zero1;
255 dma_addr_t b_next;
256 dma_addr_t b_data; /* Address from i596 viewpoint */
257 unsigned short size;
258 unsigned short zero2;
259 /* driver data */
260 struct sk_buff *skb;
261 struct i596_rbd *v_next;
262 dma_addr_t b_addr; /* This rbd addr from i596 view */
263 unsigned char *v_data; /* Address from CPUs viewpoint */
264 /* Total 32 bytes... */
265#ifdef __LP64__
266 u32 cache_pad[4];
267#endif
268};
269
270/* These values as chosen so struct i596_dma fits in one page... */
271
272#define TX_RING_SIZE 32
273#define RX_RING_SIZE 16
274
275struct i596_scb {
276 unsigned short status;
277 unsigned short command;
278 dma_addr_t cmd;
279 dma_addr_t rfd;
280 u32 crc_err;
281 u32 align_err;
282 u32 resource_err;
283 u32 over_err;
284 u32 rcvdt_err;
285 u32 short_err;
286 unsigned short t_on;
287 unsigned short t_off;
288};
289
290struct i596_iscp {
291 u32 stat;
292 dma_addr_t scb;
293};
294
295struct i596_scp {
296 u32 sysbus;
297 u32 pad;
298 dma_addr_t iscp;
299};
300
301struct i596_dma {
302 struct i596_scp scp __attribute__((aligned(32)));
303 volatile struct i596_iscp iscp __attribute__((aligned(32)));
304 volatile struct i596_scb scb __attribute__((aligned(32)));
305 struct sa_cmd sa_cmd __attribute__((aligned(32)));
306 struct cf_cmd cf_cmd __attribute__((aligned(32)));
307 struct tdr_cmd tdr_cmd __attribute__((aligned(32)));
308 struct mc_cmd mc_cmd __attribute__((aligned(32)));
309 struct i596_rfd rfds[RX_RING_SIZE] __attribute__((aligned(32)));
310 struct i596_rbd rbds[RX_RING_SIZE] __attribute__((aligned(32)));
311 struct tx_cmd tx_cmds[TX_RING_SIZE] __attribute__((aligned(32)));
312 struct i596_tbd tbds[TX_RING_SIZE] __attribute__((aligned(32)));
313};
314
315struct i596_private {
316 struct i596_dma *dma;
317 u32 stat;
318 int last_restart;
319 struct i596_rfd *rfd_head;
320 struct i596_rbd *rbd_head;
321 struct i596_cmd *cmd_tail;
322 struct i596_cmd *cmd_head;
323 int cmd_backlog;
324 u32 last_cmd;
325 struct net_device_stats stats;
326 int next_tx_cmd;
327 int options;
328 spinlock_t lock; /* serialize access to chip */
329 dma_addr_t dma_addr;
330 void __iomem *mpu_port;
331 void __iomem *ca;
332};
333
334static const char init_setup[] =
335{
336 0x8E, /* length, prefetch on */
337 0xC8, /* fifo to 8, monitor off */
338 0x80, /* don't save bad frames */
339 0x2E, /* No source address insertion, 8 byte preamble */
340 0x00, /* priority and backoff defaults */
341 0x60, /* interframe spacing */
342 0x00, /* slot time LSB */
343 0xf2, /* slot time and retries */
344 0x00, /* promiscuous mode */
345 0x00, /* collision detect */
346 0x40, /* minimum frame length */
347 0xff,
348 0x00,
349 0x7f /* *multi IA */ };
350
351static int i596_open(struct net_device *dev);
352static int i596_start_xmit(struct sk_buff *skb, struct net_device *dev);
353static irqreturn_t i596_interrupt(int irq, void *dev_id);
354static int i596_close(struct net_device *dev);
355static struct net_device_stats *i596_get_stats(struct net_device *dev);
356static void i596_add_cmd(struct net_device *dev, struct i596_cmd *cmd);
357static void i596_tx_timeout (struct net_device *dev);
358static void print_eth(unsigned char *buf, char *str);
359static void set_multicast_list(struct net_device *dev);
360static inline void ca(struct net_device *dev);
361static void mpu_port(struct net_device *dev, int c, dma_addr_t x);
362
363static int rx_ring_size = RX_RING_SIZE;
364static int ticks_limit = 100;
365static int max_cmd_backlog = TX_RING_SIZE-1;
366
367#ifdef CONFIG_NET_POLL_CONTROLLER
368static void i596_poll_controller(struct net_device *dev);
369#endif
370
371
372static inline int wait_istat(struct net_device *dev, struct i596_dma *dma, int delcnt, char *str)
373{
374 DMA_INV(dev, &(dma->iscp), sizeof(struct i596_iscp));
375 while (--delcnt && dma->iscp.stat) {
376 udelay(10);
377 DMA_INV(dev, &(dma->iscp), sizeof(struct i596_iscp));
378 }
379 if (!delcnt) {
380 printk(KERN_ERR "%s: %s, iscp.stat %04x, didn't clear\n",
381 dev->name, str, SWAP16(dma->iscp.stat));
382 return -1;
383 } else
384 return 0;
385}
386
387
388static inline int wait_cmd(struct net_device *dev, struct i596_dma *dma, int delcnt, char *str)
389{
390 DMA_INV(dev, &(dma->scb), sizeof(struct i596_scb));
391 while (--delcnt && dma->scb.command) {
392 udelay(10);
393 DMA_INV(dev, &(dma->scb), sizeof(struct i596_scb));
394 }
395 if (!delcnt) {
396 printk(KERN_ERR "%s: %s, status %4.4x, cmd %4.4x.\n",
397 dev->name, str,
398 SWAP16(dma->scb.status),
399 SWAP16(dma->scb.command));
400 return -1;
401 } else
402 return 0;
403}
404
405
406static void i596_display_data(struct net_device *dev)
407{
408 struct i596_private *lp = netdev_priv(dev);
409 struct i596_dma *dma = lp->dma;
410 struct i596_cmd *cmd;
411 struct i596_rfd *rfd;
412 struct i596_rbd *rbd;
413
414 printk(KERN_DEBUG "lp and scp at %p, .sysbus = %08x, .iscp = %08x\n",
415 &dma->scp, dma->scp.sysbus, SWAP32(dma->scp.iscp));
416 printk(KERN_DEBUG "iscp at %p, iscp.stat = %08x, .scb = %08x\n",
417 &dma->iscp, SWAP32(dma->iscp.stat), SWAP32(dma->iscp.scb));
418 printk(KERN_DEBUG "scb at %p, scb.status = %04x, .command = %04x,"
419 " .cmd = %08x, .rfd = %08x\n",
420 &dma->scb, SWAP16(dma->scb.status), SWAP16(dma->scb.command),
421 SWAP16(dma->scb.cmd), SWAP32(dma->scb.rfd));
422 printk(KERN_DEBUG " errors: crc %x, align %x, resource %x,"
423 " over %x, rcvdt %x, short %x\n",
424 SWAP32(dma->scb.crc_err), SWAP32(dma->scb.align_err),
425 SWAP32(dma->scb.resource_err), SWAP32(dma->scb.over_err),
426 SWAP32(dma->scb.rcvdt_err), SWAP32(dma->scb.short_err));
427 cmd = lp->cmd_head;
428 while (cmd != NULL) {
429 printk(KERN_DEBUG
430 "cmd at %p, .status = %04x, .command = %04x,"
431 " .b_next = %08x\n",
432 cmd, SWAP16(cmd->status), SWAP16(cmd->command),
433 SWAP32(cmd->b_next));
434 cmd = cmd->v_next;
435 }
436 rfd = lp->rfd_head;
437 printk(KERN_DEBUG "rfd_head = %p\n", rfd);
438 do {
439 printk(KERN_DEBUG
440 " %p .stat %04x, .cmd %04x, b_next %08x, rbd %08x,"
441 " count %04x\n",
442 rfd, SWAP16(rfd->stat), SWAP16(rfd->cmd),
443 SWAP32(rfd->b_next), SWAP32(rfd->rbd),
444 SWAP16(rfd->count));
445 rfd = rfd->v_next;
446 } while (rfd != lp->rfd_head);
447 rbd = lp->rbd_head;
448 printk(KERN_DEBUG "rbd_head = %p\n", rbd);
449 do {
450 printk(KERN_DEBUG
451 " %p .count %04x, b_next %08x, b_data %08x,"
452 " size %04x\n",
453 rbd, SWAP16(rbd->count), SWAP32(rbd->b_next),
454 SWAP32(rbd->b_data), SWAP16(rbd->size));
455 rbd = rbd->v_next;
456 } while (rbd != lp->rbd_head);
457 DMA_INV(dev, dma, sizeof(struct i596_dma));
458}
459
460
461#define virt_to_dma(lp, v) ((lp)->dma_addr + (dma_addr_t)((unsigned long)(v)-(unsigned long)((lp)->dma)))
462
463static inline int init_rx_bufs(struct net_device *dev)
464{
465 struct i596_private *lp = netdev_priv(dev);
466 struct i596_dma *dma = lp->dma;
467 int i;
468 struct i596_rfd *rfd;
469 struct i596_rbd *rbd;
470
471 /* First build the Receive Buffer Descriptor List */
472
473 for (i = 0, rbd = dma->rbds; i < rx_ring_size; i++, rbd++) {
474 dma_addr_t dma_addr;
475 struct sk_buff *skb = netdev_alloc_skb(dev, PKT_BUF_SZ + 4);
476
477 if (skb == NULL)
478 return -1;
479 skb_reserve(skb, 2);
480 dma_addr = dma_map_single(dev->dev.parent, skb->data,
481 PKT_BUF_SZ, DMA_FROM_DEVICE);
482 rbd->v_next = rbd+1;
483 rbd->b_next = SWAP32(virt_to_dma(lp, rbd+1));
484 rbd->b_addr = SWAP32(virt_to_dma(lp, rbd));
485 rbd->skb = skb;
486 rbd->v_data = skb->data;
487 rbd->b_data = SWAP32(dma_addr);
488 rbd->size = SWAP16(PKT_BUF_SZ);
489 }
490 lp->rbd_head = dma->rbds;
491 rbd = dma->rbds + rx_ring_size - 1;
492 rbd->v_next = dma->rbds;
493 rbd->b_next = SWAP32(virt_to_dma(lp, dma->rbds));
494
495 /* Now build the Receive Frame Descriptor List */
496
497 for (i = 0, rfd = dma->rfds; i < rx_ring_size; i++, rfd++) {
498 rfd->rbd = I596_NULL;
499 rfd->v_next = rfd+1;
500 rfd->v_prev = rfd-1;
501 rfd->b_next = SWAP32(virt_to_dma(lp, rfd+1));
502 rfd->cmd = SWAP16(CMD_FLEX);
503 }
504 lp->rfd_head = dma->rfds;
505 dma->scb.rfd = SWAP32(virt_to_dma(lp, dma->rfds));
506 rfd = dma->rfds;
507 rfd->rbd = SWAP32(virt_to_dma(lp, lp->rbd_head));
508 rfd->v_prev = dma->rfds + rx_ring_size - 1;
509 rfd = dma->rfds + rx_ring_size - 1;
510 rfd->v_next = dma->rfds;
511 rfd->b_next = SWAP32(virt_to_dma(lp, dma->rfds));
512 rfd->cmd = SWAP16(CMD_EOL|CMD_FLEX);
513
514 DMA_WBACK_INV(dev, dma, sizeof(struct i596_dma));
515 return 0;
516}
517
518static inline void remove_rx_bufs(struct net_device *dev)
519{
520 struct i596_private *lp = netdev_priv(dev);
521 struct i596_rbd *rbd;
522 int i;
523
524 for (i = 0, rbd = lp->dma->rbds; i < rx_ring_size; i++, rbd++) {
525 if (rbd->skb == NULL)
526 break;
527 dma_unmap_single(dev->dev.parent,
528 (dma_addr_t)SWAP32(rbd->b_data),
529 PKT_BUF_SZ, DMA_FROM_DEVICE);
530 dev_kfree_skb(rbd->skb);
531 }
532}
533
534
535static void rebuild_rx_bufs(struct net_device *dev)
536{
537 struct i596_private *lp = netdev_priv(dev);
538 struct i596_dma *dma = lp->dma;
539 int i;
540
541 /* Ensure rx frame/buffer descriptors are tidy */
542
543 for (i = 0; i < rx_ring_size; i++) {
544 dma->rfds[i].rbd = I596_NULL;
545 dma->rfds[i].cmd = SWAP16(CMD_FLEX);
546 }
547 dma->rfds[rx_ring_size-1].cmd = SWAP16(CMD_EOL|CMD_FLEX);
548 lp->rfd_head = dma->rfds;
549 dma->scb.rfd = SWAP32(virt_to_dma(lp, dma->rfds));
550 lp->rbd_head = dma->rbds;
551 dma->rfds[0].rbd = SWAP32(virt_to_dma(lp, dma->rbds));
552
553 DMA_WBACK_INV(dev, dma, sizeof(struct i596_dma));
554}
555
556
557static int init_i596_mem(struct net_device *dev)
558{
559 struct i596_private *lp = netdev_priv(dev);
560 struct i596_dma *dma = lp->dma;
561 unsigned long flags;
562
563 mpu_port(dev, PORT_RESET, 0);
564 udelay(100); /* Wait 100us - seems to help */
565
566 /* change the scp address */
567
568 lp->last_cmd = jiffies;
569
570 dma->scp.sysbus = SYSBUS;
571 dma->scp.iscp = SWAP32(virt_to_dma(lp, &(dma->iscp)));
572 dma->iscp.scb = SWAP32(virt_to_dma(lp, &(dma->scb)));
573 dma->iscp.stat = SWAP32(ISCP_BUSY);
574 lp->cmd_backlog = 0;
575
576 lp->cmd_head = NULL;
577 dma->scb.cmd = I596_NULL;
578
579 DEB(DEB_INIT, printk(KERN_DEBUG "%s: starting i82596.\n", dev->name));
580
581 DMA_WBACK(dev, &(dma->scp), sizeof(struct i596_scp));
582 DMA_WBACK(dev, &(dma->iscp), sizeof(struct i596_iscp));
583 DMA_WBACK(dev, &(dma->scb), sizeof(struct i596_scb));
584
585 mpu_port(dev, PORT_ALTSCP, virt_to_dma(lp, &dma->scp));
586 ca(dev);
587 if (wait_istat(dev, dma, 1000, "initialization timed out"))
588 goto failed;
589 DEB(DEB_INIT, printk(KERN_DEBUG
590 "%s: i82596 initialization successful\n",
591 dev->name));
592
593 if (request_irq(dev->irq, &i596_interrupt, 0, "i82596", dev)) {
594 printk(KERN_ERR "%s: IRQ %d not free\n", dev->name, dev->irq);
595 goto failed;
596 }
597
598 /* Ensure rx frame/buffer descriptors are tidy */
599 rebuild_rx_bufs(dev);
600
601 dma->scb.command = 0;
602 DMA_WBACK(dev, &(dma->scb), sizeof(struct i596_scb));
603
604 DEB(DEB_INIT, printk(KERN_DEBUG
605 "%s: queuing CmdConfigure\n", dev->name));
606 memcpy(dma->cf_cmd.i596_config, init_setup, 14);
607 dma->cf_cmd.cmd.command = SWAP16(CmdConfigure);
608 DMA_WBACK(dev, &(dma->cf_cmd), sizeof(struct cf_cmd));
609 i596_add_cmd(dev, &dma->cf_cmd.cmd);
610
611 DEB(DEB_INIT, printk(KERN_DEBUG "%s: queuing CmdSASetup\n", dev->name));
612 memcpy(dma->sa_cmd.eth_addr, dev->dev_addr, 6);
613 dma->sa_cmd.cmd.command = SWAP16(CmdSASetup);
614 DMA_WBACK(dev, &(dma->sa_cmd), sizeof(struct sa_cmd));
615 i596_add_cmd(dev, &dma->sa_cmd.cmd);
616
617 DEB(DEB_INIT, printk(KERN_DEBUG "%s: queuing CmdTDR\n", dev->name));
618 dma->tdr_cmd.cmd.command = SWAP16(CmdTDR);
619 DMA_WBACK(dev, &(dma->tdr_cmd), sizeof(struct tdr_cmd));
620 i596_add_cmd(dev, &dma->tdr_cmd.cmd);
621
622 spin_lock_irqsave (&lp->lock, flags);
623
624 if (wait_cmd(dev, dma, 1000, "timed out waiting to issue RX_START")) {
625 spin_unlock_irqrestore (&lp->lock, flags);
626 goto failed_free_irq;
627 }
628 DEB(DEB_INIT, printk(KERN_DEBUG "%s: Issuing RX_START\n", dev->name));
629 dma->scb.command = SWAP16(RX_START);
630 dma->scb.rfd = SWAP32(virt_to_dma(lp, dma->rfds));
631 DMA_WBACK(dev, &(dma->scb), sizeof(struct i596_scb));
632
633 ca(dev);
634
635 spin_unlock_irqrestore (&lp->lock, flags);
636 if (wait_cmd(dev, dma, 1000, "RX_START not processed"))
637 goto failed_free_irq;
638 DEB(DEB_INIT, printk(KERN_DEBUG
639 "%s: Receive unit started OK\n", dev->name));
640 return 0;
641
642failed_free_irq:
643 free_irq(dev->irq, dev);
644failed:
645 printk(KERN_ERR "%s: Failed to initialise 82596\n", dev->name);
646 mpu_port(dev, PORT_RESET, 0);
647 return -1;
648}
649
650
651static inline int i596_rx(struct net_device *dev)
652{
653 struct i596_private *lp = netdev_priv(dev);
654 struct i596_rfd *rfd;
655 struct i596_rbd *rbd;
656 int frames = 0;
657
658 DEB(DEB_RXFRAME, printk(KERN_DEBUG
659 "i596_rx(), rfd_head %p, rbd_head %p\n",
660 lp->rfd_head, lp->rbd_head));
661
662
663 rfd = lp->rfd_head; /* Ref next frame to check */
664
665 DMA_INV(dev, rfd, sizeof(struct i596_rfd));
666 while (rfd->stat & SWAP16(STAT_C)) { /* Loop while complete frames */
667 if (rfd->rbd == I596_NULL)
668 rbd = NULL;
669 else if (rfd->rbd == lp->rbd_head->b_addr) {
670 rbd = lp->rbd_head;
671 DMA_INV(dev, rbd, sizeof(struct i596_rbd));
672 } else {
673 printk(KERN_ERR "%s: rbd chain broken!\n", dev->name);
674 /* XXX Now what? */
675 rbd = NULL;
676 }
677 DEB(DEB_RXFRAME, printk(KERN_DEBUG
678 " rfd %p, rfd.rbd %08x, rfd.stat %04x\n",
679 rfd, rfd->rbd, rfd->stat));
680
681 if (rbd != NULL && (rfd->stat & SWAP16(STAT_OK))) {
682 /* a good frame */
683 int pkt_len = SWAP16(rbd->count) & 0x3fff;
684 struct sk_buff *skb = rbd->skb;
685 int rx_in_place = 0;
686
687 DEB(DEB_RXADDR, print_eth(rbd->v_data, "received"));
688 frames++;
689
690 /* Check if the packet is long enough to just accept
691 * without copying to a properly sized skbuff.
692 */
693
694 if (pkt_len > rx_copybreak) {
695 struct sk_buff *newskb;
696 dma_addr_t dma_addr;
697
698 dma_unmap_single(dev->dev.parent,
699 (dma_addr_t)SWAP32(rbd->b_data),
700 PKT_BUF_SZ, DMA_FROM_DEVICE);
701 /* Get fresh skbuff to replace filled one. */
702 newskb = netdev_alloc_skb(dev, PKT_BUF_SZ + 4);
703 if (newskb == NULL) {
704 skb = NULL; /* drop pkt */
705 goto memory_squeeze;
706 }
707 skb_reserve(newskb, 2);
708
709 /* Pass up the skb already on the Rx ring. */
710 skb_put(skb, pkt_len);
711 rx_in_place = 1;
712 rbd->skb = newskb;
713 dma_addr = dma_map_single(dev->dev.parent,
714 newskb->data,
715 PKT_BUF_SZ,
716 DMA_FROM_DEVICE);
717 rbd->v_data = newskb->data;
718 rbd->b_data = SWAP32(dma_addr);
719 DMA_WBACK_INV(dev, rbd, sizeof(struct i596_rbd));
720 } else
721 skb = netdev_alloc_skb(dev, pkt_len + 2);
722memory_squeeze:
723 if (skb == NULL) {
724 /* XXX tulip.c can defer packets here!! */
725 printk(KERN_ERR
726 "%s: i596_rx Memory squeeze, dropping packet.\n",
727 dev->name);
728 lp->stats.rx_dropped++;
729 } else {
730 if (!rx_in_place) {
731 /* 16 byte align the data fields */
732 dma_sync_single_for_cpu(dev->dev.parent,
733 (dma_addr_t)SWAP32(rbd->b_data),
734 PKT_BUF_SZ, DMA_FROM_DEVICE);
735 skb_reserve(skb, 2);
736 memcpy(skb_put(skb, pkt_len), rbd->v_data, pkt_len);
737 dma_sync_single_for_device(dev->dev.parent,
738 (dma_addr_t)SWAP32(rbd->b_data),
739 PKT_BUF_SZ, DMA_FROM_DEVICE);
740 }
741 skb->len = pkt_len;
742 skb->protocol = eth_type_trans(skb, dev);
743 netif_rx(skb);
744 dev->last_rx = jiffies;
745 lp->stats.rx_packets++;
746 lp->stats.rx_bytes += pkt_len;
747 }
748 } else {
749 DEB(DEB_ERRORS, printk(KERN_DEBUG
750 "%s: Error, rfd.stat = 0x%04x\n",
751 dev->name, rfd->stat));
752 lp->stats.rx_errors++;
753 if (rfd->stat & SWAP16(0x0100))
754 lp->stats.collisions++;
755 if (rfd->stat & SWAP16(0x8000))
756 lp->stats.rx_length_errors++;
757 if (rfd->stat & SWAP16(0x0001))
758 lp->stats.rx_over_errors++;
759 if (rfd->stat & SWAP16(0x0002))
760 lp->stats.rx_fifo_errors++;
761 if (rfd->stat & SWAP16(0x0004))
762 lp->stats.rx_frame_errors++;
763 if (rfd->stat & SWAP16(0x0008))
764 lp->stats.rx_crc_errors++;
765 if (rfd->stat & SWAP16(0x0010))
766 lp->stats.rx_length_errors++;
767 }
768
769 /* Clear the buffer descriptor count and EOF + F flags */
770
771 if (rbd != NULL && (rbd->count & SWAP16(0x4000))) {
772 rbd->count = 0;
773 lp->rbd_head = rbd->v_next;
774 DMA_WBACK_INV(dev, rbd, sizeof(struct i596_rbd));
775 }
776
777 /* Tidy the frame descriptor, marking it as end of list */
778
779 rfd->rbd = I596_NULL;
780 rfd->stat = 0;
781 rfd->cmd = SWAP16(CMD_EOL|CMD_FLEX);
782 rfd->count = 0;
783
784 /* Update record of next frame descriptor to process */
785
786 lp->dma->scb.rfd = rfd->b_next;
787 lp->rfd_head = rfd->v_next;
788 DMA_WBACK_INV(dev, rfd, sizeof(struct i596_rfd));
789
790 /* Remove end-of-list from old end descriptor */
791
792 rfd->v_prev->cmd = SWAP16(CMD_FLEX);
793 DMA_WBACK_INV(dev, rfd->v_prev, sizeof(struct i596_rfd));
794 rfd = lp->rfd_head;
795 DMA_INV(dev, rfd, sizeof(struct i596_rfd));
796 }
797
798 DEB(DEB_RXFRAME, printk(KERN_DEBUG "frames %d\n", frames));
799
800 return 0;
801}
802
803
804static inline void i596_cleanup_cmd(struct net_device *dev, struct i596_private *lp)
805{
806 struct i596_cmd *ptr;
807
808 while (lp->cmd_head != NULL) {
809 ptr = lp->cmd_head;
810 lp->cmd_head = ptr->v_next;
811 lp->cmd_backlog--;
812
813 switch (SWAP16(ptr->command) & 0x7) {
814 case CmdTx:
815 {
816 struct tx_cmd *tx_cmd = (struct tx_cmd *) ptr;
817 struct sk_buff *skb = tx_cmd->skb;
818 dma_unmap_single(dev->dev.parent,
819 tx_cmd->dma_addr,
820 skb->len, DMA_TO_DEVICE);
821
822 dev_kfree_skb(skb);
823
824 lp->stats.tx_errors++;
825 lp->stats.tx_aborted_errors++;
826
827 ptr->v_next = NULL;
828 ptr->b_next = I596_NULL;
829 tx_cmd->cmd.command = 0; /* Mark as free */
830 break;
831 }
832 default:
833 ptr->v_next = NULL;
834 ptr->b_next = I596_NULL;
835 }
836 DMA_WBACK_INV(dev, ptr, sizeof(struct i596_cmd));
837 }
838
839 wait_cmd(dev, lp->dma, 100, "i596_cleanup_cmd timed out");
840 lp->dma->scb.cmd = I596_NULL;
841 DMA_WBACK(dev, &(lp->dma->scb), sizeof(struct i596_scb));
842}
843
844
845static inline void i596_reset(struct net_device *dev, struct i596_private *lp)
846{
847 unsigned long flags;
848
849 DEB(DEB_RESET, printk(KERN_DEBUG "i596_reset\n"));
850
851 spin_lock_irqsave (&lp->lock, flags);
852
853 wait_cmd(dev, lp->dma, 100, "i596_reset timed out");
854
855 netif_stop_queue(dev);
856
857 /* FIXME: this command might cause an lpmc */
858 lp->dma->scb.command = SWAP16(CUC_ABORT | RX_ABORT);
859 DMA_WBACK(dev, &(lp->dma->scb), sizeof(struct i596_scb));
860 ca(dev);
861
862 /* wait for shutdown */
863 wait_cmd(dev, lp->dma, 1000, "i596_reset 2 timed out");
864 spin_unlock_irqrestore (&lp->lock, flags);
865
866 i596_cleanup_cmd(dev, lp);
867 i596_rx(dev);
868
869 netif_start_queue(dev);
870 init_i596_mem(dev);
871}
872
873
874static void i596_add_cmd(struct net_device *dev, struct i596_cmd *cmd)
875{
876 struct i596_private *lp = netdev_priv(dev);
877 struct i596_dma *dma = lp->dma;
878 unsigned long flags;
879
880 DEB(DEB_ADDCMD, printk(KERN_DEBUG "i596_add_cmd cmd_head %p\n",
881 lp->cmd_head));
882
883 cmd->status = 0;
884 cmd->command |= SWAP16(CMD_EOL | CMD_INTR);
885 cmd->v_next = NULL;
886 cmd->b_next = I596_NULL;
887 DMA_WBACK(dev, cmd, sizeof(struct i596_cmd));
888
889 spin_lock_irqsave (&lp->lock, flags);
890
891 if (lp->cmd_head != NULL) {
892 lp->cmd_tail->v_next = cmd;
893 lp->cmd_tail->b_next = SWAP32(virt_to_dma(lp, &cmd->status));
894 DMA_WBACK(dev, lp->cmd_tail, sizeof(struct i596_cmd));
895 } else {
896 lp->cmd_head = cmd;
897 wait_cmd(dev, dma, 100, "i596_add_cmd timed out");
898 dma->scb.cmd = SWAP32(virt_to_dma(lp, &cmd->status));
899 dma->scb.command = SWAP16(CUC_START);
900 DMA_WBACK(dev, &(dma->scb), sizeof(struct i596_scb));
901 ca(dev);
902 }
903 lp->cmd_tail = cmd;
904 lp->cmd_backlog++;
905
906 spin_unlock_irqrestore (&lp->lock, flags);
907
908 if (lp->cmd_backlog > max_cmd_backlog) {
909 unsigned long tickssofar = jiffies - lp->last_cmd;
910
911 if (tickssofar < ticks_limit)
912 return;
913
914 printk(KERN_ERR
915 "%s: command unit timed out, status resetting.\n",
916 dev->name);
917#if 1
918 i596_reset(dev, lp);
919#endif
920 }
921}
922
923static int i596_open(struct net_device *dev)
924{
925 DEB(DEB_OPEN, printk(KERN_DEBUG
926 "%s: i596_open() irq %d.\n", dev->name, dev->irq));
927
928 if (init_rx_bufs(dev)) {
929 printk(KERN_ERR "%s: Failed to init rx bufs\n", dev->name);
930 return -EAGAIN;
931 }
932 if (init_i596_mem(dev)) {
933 printk(KERN_ERR "%s: Failed to init memory\n", dev->name);
934 goto out_remove_rx_bufs;
935 }
936 netif_start_queue(dev);
937
938 return 0;
939
940out_remove_rx_bufs:
941 remove_rx_bufs(dev);
942 return -EAGAIN;
943}
944
945static void i596_tx_timeout (struct net_device *dev)
946{
947 struct i596_private *lp = netdev_priv(dev);
948
949 /* Transmitter timeout, serious problems. */
950 DEB(DEB_ERRORS, printk(KERN_DEBUG
951 "%s: transmit timed out, status resetting.\n",
952 dev->name));
953
954 lp->stats.tx_errors++;
955
956 /* Try to restart the adaptor */
957 if (lp->last_restart == lp->stats.tx_packets) {
958 DEB(DEB_ERRORS, printk(KERN_DEBUG "Resetting board.\n"));
959 /* Shutdown and restart */
960 i596_reset (dev, lp);
961 } else {
962 /* Issue a channel attention signal */
963 DEB(DEB_ERRORS, printk(KERN_DEBUG "Kicking board.\n"));
964 lp->dma->scb.command = SWAP16(CUC_START | RX_START);
965 DMA_WBACK_INV(dev, &(lp->dma->scb), sizeof(struct i596_scb));
966 ca (dev);
967 lp->last_restart = lp->stats.tx_packets;
968 }
969
970 dev->trans_start = jiffies;
971 netif_wake_queue (dev);
972}
973
974
975static int i596_start_xmit(struct sk_buff *skb, struct net_device *dev)
976{
977 struct i596_private *lp = netdev_priv(dev);
978 struct tx_cmd *tx_cmd;
979 struct i596_tbd *tbd;
980 short length = skb->len;
981 dev->trans_start = jiffies;
982
983 DEB(DEB_STARTTX, printk(KERN_DEBUG
984 "%s: i596_start_xmit(%x,%p) called\n",
985 dev->name, skb->len, skb->data));
986
987 if (length < ETH_ZLEN) {
988 if (skb_padto(skb, ETH_ZLEN))
989 return 0;
990 length = ETH_ZLEN;
991 }
992
993 netif_stop_queue(dev);
994
995 tx_cmd = lp->dma->tx_cmds + lp->next_tx_cmd;
996 tbd = lp->dma->tbds + lp->next_tx_cmd;
997
998 if (tx_cmd->cmd.command) {
999 DEB(DEB_ERRORS, printk(KERN_DEBUG
1000 "%s: xmit ring full, dropping packet.\n",
1001 dev->name));
1002 lp->stats.tx_dropped++;
1003
1004 dev_kfree_skb(skb);
1005 } else {
1006 if (++lp->next_tx_cmd == TX_RING_SIZE)
1007 lp->next_tx_cmd = 0;
1008 tx_cmd->tbd = SWAP32(virt_to_dma(lp, tbd));
1009 tbd->next = I596_NULL;
1010
1011 tx_cmd->cmd.command = SWAP16(CMD_FLEX | CmdTx);
1012 tx_cmd->skb = skb;
1013
1014 tx_cmd->pad = 0;
1015 tx_cmd->size = 0;
1016 tbd->pad = 0;
1017 tbd->size = SWAP16(EOF | length);
1018
1019 tx_cmd->dma_addr = dma_map_single(dev->dev.parent, skb->data,
1020 skb->len, DMA_TO_DEVICE);
1021 tbd->data = SWAP32(tx_cmd->dma_addr);
1022
1023 DEB(DEB_TXADDR, print_eth(skb->data, "tx-queued"));
1024 DMA_WBACK_INV(dev, tx_cmd, sizeof(struct tx_cmd));
1025 DMA_WBACK_INV(dev, tbd, sizeof(struct i596_tbd));
1026 i596_add_cmd(dev, &tx_cmd->cmd);
1027
1028 lp->stats.tx_packets++;
1029 lp->stats.tx_bytes += length;
1030 }
1031
1032 netif_start_queue(dev);
1033
1034 return 0;
1035}
1036
1037static void print_eth(unsigned char *add, char *str)
1038{
1039 int i;
1040
1041 printk(KERN_DEBUG "i596 0x%p, ", add);
1042 for (i = 0; i < 6; i++)
1043 printk(" %02X", add[i + 6]);
1044 printk(" -->");
1045 for (i = 0; i < 6; i++)
1046 printk(" %02X", add[i]);
1047 printk(" %02X%02X, %s\n", add[12], add[13], str);
1048}
1049
1050static int __devinit i82596_probe(struct net_device *dev)
1051{
1052 int i;
1053 struct i596_private *lp = netdev_priv(dev);
1054 struct i596_dma *dma;
1055
1056 /* This lot is ensure things have been cache line aligned. */
1057 BUILD_BUG_ON(sizeof(struct i596_rfd) != 32);
1058 BUILD_BUG_ON(sizeof(struct i596_rbd) & 31);
1059 BUILD_BUG_ON(sizeof(struct tx_cmd) & 31);
1060 BUILD_BUG_ON(sizeof(struct i596_tbd) != 32);
1061#ifndef __LP64__
1062 BUILD_BUG_ON(sizeof(struct i596_dma) > 4096);
1063#endif
1064
1065 if (!dev->base_addr || !dev->irq)
1066 return -ENODEV;
1067
1068 dma = (struct i596_dma *) DMA_ALLOC(dev->dev.parent,
1069 sizeof(struct i596_dma), &lp->dma_addr, GFP_KERNEL);
1070 if (!dma) {
1071 printk(KERN_ERR "%s: Couldn't get shared memory\n", __FILE__);
1072 return -ENOMEM;
1073 }
1074
1075 /* The 82596-specific entries in the device structure. */
1076 dev->open = i596_open;
1077 dev->stop = i596_close;
1078 dev->hard_start_xmit = i596_start_xmit;
1079 dev->get_stats = i596_get_stats;
1080 dev->set_multicast_list = set_multicast_list;
1081 dev->tx_timeout = i596_tx_timeout;
1082 dev->watchdog_timeo = TX_TIMEOUT;
1083#ifdef CONFIG_NET_POLL_CONTROLLER
1084 dev->poll_controller = i596_poll_controller;
1085#endif
1086
1087 memset(dma, 0, sizeof(struct i596_dma));
1088 lp->dma = dma;
1089
1090 dma->scb.command = 0;
1091 dma->scb.cmd = I596_NULL;
1092 dma->scb.rfd = I596_NULL;
1093 spin_lock_init(&lp->lock);
1094
1095 DMA_WBACK_INV(dev, dma, sizeof(struct i596_dma));
1096
1097 i = register_netdev(dev);
1098 if (i) {
1099 DMA_FREE(dev->dev.parent, sizeof(struct i596_dma),
1100 (void *)dma, lp->dma_addr);
1101 return i;
1102 };
1103
1104 DEB(DEB_PROBE, printk(KERN_INFO "%s: 82596 at %#3lx,",
1105 dev->name, dev->base_addr));
1106 for (i = 0; i < 6; i++)
1107 DEB(DEB_PROBE, printk(" %2.2X", dev->dev_addr[i]));
1108 DEB(DEB_PROBE, printk(" IRQ %d.\n", dev->irq));
1109 DEB(DEB_INIT, printk(KERN_INFO
1110 "%s: dma at 0x%p (%d bytes), lp->scb at 0x%p\n",
1111 dev->name, dma, (int)sizeof(struct i596_dma),
1112 &dma->scb));
1113
1114 return 0;
1115}
1116
1117#ifdef CONFIG_NET_POLL_CONTROLLER
1118static void i596_poll_controller(struct net_device *dev)
1119{
1120 disable_irq(dev->irq);
1121 i596_interrupt(dev->irq, dev);
1122 enable_irq(dev->irq);
1123}
1124#endif
1125
1126static irqreturn_t i596_interrupt(int irq, void *dev_id)
1127{
1128 struct net_device *dev = dev_id;
1129 struct i596_private *lp;
1130 struct i596_dma *dma;
1131 unsigned short status, ack_cmd = 0;
1132
1133 if (dev == NULL) {
1134 printk(KERN_WARNING "%s: irq %d for unknown device.\n",
1135 __FUNCTION__, irq);
1136 return IRQ_NONE;
1137 }
1138
1139 lp = netdev_priv(dev);
1140 dma = lp->dma;
1141
1142 spin_lock (&lp->lock);
1143
1144 wait_cmd(dev, dma, 100, "i596 interrupt, timeout");
1145 status = SWAP16(dma->scb.status);
1146
1147 DEB(DEB_INTS, printk(KERN_DEBUG
1148 "%s: i596 interrupt, IRQ %d, status %4.4x.\n",
1149 dev->name, irq, status));
1150
1151 ack_cmd = status & 0xf000;
1152
1153 if (!ack_cmd) {
1154 DEB(DEB_ERRORS, printk(KERN_DEBUG
1155 "%s: interrupt with no events\n",
1156 dev->name));
1157 spin_unlock (&lp->lock);
1158 return IRQ_NONE;
1159 }
1160
1161 if ((status & 0x8000) || (status & 0x2000)) {
1162 struct i596_cmd *ptr;
1163
1164 if ((status & 0x8000))
1165 DEB(DEB_INTS,
1166 printk(KERN_DEBUG
1167 "%s: i596 interrupt completed command.\n",
1168 dev->name));
1169 if ((status & 0x2000))
1170 DEB(DEB_INTS,
1171 printk(KERN_DEBUG
1172 "%s: i596 interrupt command unit inactive %x.\n",
1173 dev->name, status & 0x0700));
1174
1175 while (lp->cmd_head != NULL) {
1176 DMA_INV(dev, lp->cmd_head, sizeof(struct i596_cmd));
1177 if (!(lp->cmd_head->status & SWAP16(STAT_C)))
1178 break;
1179
1180 ptr = lp->cmd_head;
1181
1182 DEB(DEB_STATUS,
1183 printk(KERN_DEBUG
1184 "cmd_head->status = %04x, ->command = %04x\n",
1185 SWAP16(lp->cmd_head->status),
1186 SWAP16(lp->cmd_head->command)));
1187 lp->cmd_head = ptr->v_next;
1188 lp->cmd_backlog--;
1189
1190 switch (SWAP16(ptr->command) & 0x7) {
1191 case CmdTx:
1192 {
1193 struct tx_cmd *tx_cmd = (struct tx_cmd *) ptr;
1194 struct sk_buff *skb = tx_cmd->skb;
1195
1196 if (ptr->status & SWAP16(STAT_OK)) {
1197 DEB(DEB_TXADDR,
1198 print_eth(skb->data, "tx-done"));
1199 } else {
1200 lp->stats.tx_errors++;
1201 if (ptr->status & SWAP16(0x0020))
1202 lp->stats.collisions++;
1203 if (!(ptr->status & SWAP16(0x0040)))
1204 lp->stats.tx_heartbeat_errors++;
1205 if (ptr->status & SWAP16(0x0400))
1206 lp->stats.tx_carrier_errors++;
1207 if (ptr->status & SWAP16(0x0800))
1208 lp->stats.collisions++;
1209 if (ptr->status & SWAP16(0x1000))
1210 lp->stats.tx_aborted_errors++;
1211 }
1212 dma_unmap_single(dev->dev.parent,
1213 tx_cmd->dma_addr,
1214 skb->len, DMA_TO_DEVICE);
1215 dev_kfree_skb_irq(skb);
1216
1217 tx_cmd->cmd.command = 0; /* Mark free */
1218 break;
1219 }
1220 case CmdTDR:
1221 {
1222 unsigned short status = SWAP16(((struct tdr_cmd *)ptr)->status);
1223
1224 if (status & 0x8000) {
1225 DEB(DEB_ANY,
1226 printk(KERN_DEBUG "%s: link ok.\n",
1227 dev->name));
1228 } else {
1229 if (status & 0x4000)
1230 printk(KERN_ERR
1231 "%s: Transceiver problem.\n",
1232 dev->name);
1233 if (status & 0x2000)
1234 printk(KERN_ERR
1235 "%s: Termination problem.\n",
1236 dev->name);
1237 if (status & 0x1000)
1238 printk(KERN_ERR
1239 "%s: Short circuit.\n",
1240 dev->name);
1241
1242 DEB(DEB_TDR,
1243 printk(KERN_DEBUG "%s: Time %d.\n",
1244 dev->name, status & 0x07ff));
1245 }
1246 break;
1247 }
1248 case CmdConfigure:
1249 /*
1250 * Zap command so set_multicast_list() know
1251 * it is free
1252 */
1253 ptr->command = 0;
1254 break;
1255 }
1256 ptr->v_next = NULL;
1257 ptr->b_next = I596_NULL;
1258 DMA_WBACK(dev, ptr, sizeof(struct i596_cmd));
1259 lp->last_cmd = jiffies;
1260 }
1261
1262 /* This mess is arranging that only the last of any outstanding
1263 * commands has the interrupt bit set. Should probably really
1264 * only add to the cmd queue when the CU is stopped.
1265 */
1266 ptr = lp->cmd_head;
1267 while ((ptr != NULL) && (ptr != lp->cmd_tail)) {
1268 struct i596_cmd *prev = ptr;
1269
1270 ptr->command &= SWAP16(0x1fff);
1271 ptr = ptr->v_next;
1272 DMA_WBACK_INV(dev, prev, sizeof(struct i596_cmd));
1273 }
1274
1275 if (lp->cmd_head != NULL)
1276 ack_cmd |= CUC_START;
1277 dma->scb.cmd = SWAP32(virt_to_dma(lp, &lp->cmd_head->status));
1278 DMA_WBACK_INV(dev, &dma->scb, sizeof(struct i596_scb));
1279 }
1280 if ((status & 0x1000) || (status & 0x4000)) {
1281 if ((status & 0x4000))
1282 DEB(DEB_INTS,
1283 printk(KERN_DEBUG
1284 "%s: i596 interrupt received a frame.\n",
1285 dev->name));
1286 i596_rx(dev);
1287 /* Only RX_START if stopped - RGH 07-07-96 */
1288 if (status & 0x1000) {
1289 if (netif_running(dev)) {
1290 DEB(DEB_ERRORS,
1291 printk(KERN_DEBUG
1292 "%s: i596 interrupt receive unit inactive, status 0x%x\n",
1293 dev->name, status));
1294 ack_cmd |= RX_START;
1295 lp->stats.rx_errors++;
1296 lp->stats.rx_fifo_errors++;
1297 rebuild_rx_bufs(dev);
1298 }
1299 }
1300 }
1301 wait_cmd(dev, dma, 100, "i596 interrupt, timeout");
1302 dma->scb.command = SWAP16(ack_cmd);
1303 DMA_WBACK(dev, &dma->scb, sizeof(struct i596_scb));
1304
1305 /* DANGER: I suspect that some kind of interrupt
1306 acknowledgement aside from acking the 82596 might be needed
1307 here... but it's running acceptably without */
1308
1309 ca(dev);
1310
1311 wait_cmd(dev, dma, 100, "i596 interrupt, exit timeout");
1312 DEB(DEB_INTS, printk(KERN_DEBUG "%s: exiting interrupt.\n", dev->name));
1313
1314 spin_unlock (&lp->lock);
1315 return IRQ_HANDLED;
1316}
1317
1318static int i596_close(struct net_device *dev)
1319{
1320 struct i596_private *lp = netdev_priv(dev);
1321 unsigned long flags;
1322
1323 netif_stop_queue(dev);
1324
1325 DEB(DEB_INIT,
1326 printk(KERN_DEBUG
1327 "%s: Shutting down ethercard, status was %4.4x.\n",
1328 dev->name, SWAP16(lp->dma->scb.status)));
1329
1330 spin_lock_irqsave(&lp->lock, flags);
1331
1332 wait_cmd(dev, lp->dma, 100, "close1 timed out");
1333 lp->dma->scb.command = SWAP16(CUC_ABORT | RX_ABORT);
1334 DMA_WBACK(dev, &lp->dma->scb, sizeof(struct i596_scb));
1335
1336 ca(dev);
1337
1338 wait_cmd(dev, lp->dma, 100, "close2 timed out");
1339 spin_unlock_irqrestore(&lp->lock, flags);
1340 DEB(DEB_STRUCT, i596_display_data(dev));
1341 i596_cleanup_cmd(dev, lp);
1342
1343 free_irq(dev->irq, dev);
1344 remove_rx_bufs(dev);
1345
1346 return 0;
1347}
1348
1349static struct net_device_stats *i596_get_stats(struct net_device *dev)
1350{
1351 struct i596_private *lp = netdev_priv(dev);
1352
1353 return &lp->stats;
1354}
1355
1356/*
1357 * Set or clear the multicast filter for this adaptor.
1358 */
1359
1360static void set_multicast_list(struct net_device *dev)
1361{
1362 struct i596_private *lp = netdev_priv(dev);
1363 struct i596_dma *dma = lp->dma;
1364 int config = 0, cnt;
1365
1366 DEB(DEB_MULTI,
1367 printk(KERN_DEBUG
1368 "%s: set multicast list, %d entries, promisc %s, allmulti %s\n",
1369 dev->name, dev->mc_count,
1370 dev->flags & IFF_PROMISC ? "ON" : "OFF",
1371 dev->flags & IFF_ALLMULTI ? "ON" : "OFF"));
1372
1373 if ((dev->flags & IFF_PROMISC) &&
1374 !(dma->cf_cmd.i596_config[8] & 0x01)) {
1375 dma->cf_cmd.i596_config[8] |= 0x01;
1376 config = 1;
1377 }
1378 if (!(dev->flags & IFF_PROMISC) &&
1379 (dma->cf_cmd.i596_config[8] & 0x01)) {
1380 dma->cf_cmd.i596_config[8] &= ~0x01;
1381 config = 1;
1382 }
1383 if ((dev->flags & IFF_ALLMULTI) &&
1384 (dma->cf_cmd.i596_config[11] & 0x20)) {
1385 dma->cf_cmd.i596_config[11] &= ~0x20;
1386 config = 1;
1387 }
1388 if (!(dev->flags & IFF_ALLMULTI) &&
1389 !(dma->cf_cmd.i596_config[11] & 0x20)) {
1390 dma->cf_cmd.i596_config[11] |= 0x20;
1391 config = 1;
1392 }
1393 if (config) {
1394 if (dma->cf_cmd.cmd.command)
1395 printk(KERN_INFO
1396 "%s: config change request already queued\n",
1397 dev->name);
1398 else {
1399 dma->cf_cmd.cmd.command = SWAP16(CmdConfigure);
1400 DMA_WBACK_INV(dev, &dma->cf_cmd, sizeof(struct cf_cmd));
1401 i596_add_cmd(dev, &dma->cf_cmd.cmd);
1402 }
1403 }
1404
1405 cnt = dev->mc_count;
1406 if (cnt > MAX_MC_CNT) {
1407 cnt = MAX_MC_CNT;
1408 printk(KERN_NOTICE "%s: Only %d multicast addresses supported",
1409 dev->name, cnt);
1410 }
1411
1412 if (dev->mc_count > 0) {
1413 struct dev_mc_list *dmi;
1414 unsigned char *cp;
1415 struct mc_cmd *cmd;
1416
1417 cmd = &dma->mc_cmd;
1418 cmd->cmd.command = SWAP16(CmdMulticastList);
1419 cmd->mc_cnt = SWAP16(dev->mc_count * 6);
1420 cp = cmd->mc_addrs;
1421 for (dmi = dev->mc_list;
1422 cnt && dmi != NULL;
1423 dmi = dmi->next, cnt--, cp += 6) {
1424 memcpy(cp, dmi->dmi_addr, 6);
1425 if (i596_debug > 1)
1426 DEB(DEB_MULTI,
1427 printk(KERN_DEBUG
1428 "%s: Adding address %02x:%02x:%02x:%02x:%02x:%02x\n",
1429 dev->name, cp[0], cp[1], cp[2], cp[3], cp[4], cp[5]));
1430 }
1431 DMA_WBACK_INV(dev, &dma->mc_cmd, sizeof(struct mc_cmd));
1432 i596_add_cmd(dev, &cmd->cmd);
1433 }
1434}
diff --git a/drivers/net/macmace.c b/drivers/net/macmace.c
index fef3193121f9..9a343b965975 100644
--- a/drivers/net/macmace.c
+++ b/drivers/net/macmace.c
@@ -577,7 +577,7 @@ static irqreturn_t mace_interrupt(int irq, void *dev_id)
577 struct mace_data *mp = netdev_priv(dev); 577 struct mace_data *mp = netdev_priv(dev);
578 volatile struct mace *mb = mp->mace; 578 volatile struct mace *mb = mp->mace;
579 int intr, fs; 579 int intr, fs;
580 unsigned int flags; 580 unsigned long flags;
581 581
582 /* don't want the dma interrupt handler to fire */ 582 /* don't want the dma interrupt handler to fire */
583 local_irq_save(flags); 583 local_irq_save(flags);
diff --git a/drivers/net/mlx4/qp.c b/drivers/net/mlx4/qp.c
index 7f8b7d55b6e1..492cfaaaa75c 100644
--- a/drivers/net/mlx4/qp.c
+++ b/drivers/net/mlx4/qp.c
@@ -113,8 +113,7 @@ int mlx4_qp_modify(struct mlx4_dev *dev, struct mlx4_mtt *mtt,
113 struct mlx4_cmd_mailbox *mailbox; 113 struct mlx4_cmd_mailbox *mailbox;
114 int ret = 0; 114 int ret = 0;
115 115
116 if (cur_state < 0 || cur_state >= MLX4_QP_NUM_STATE || 116 if (cur_state >= MLX4_QP_NUM_STATE || cur_state >= MLX4_QP_NUM_STATE ||
117 new_state < 0 || cur_state >= MLX4_QP_NUM_STATE ||
118 !op[cur_state][new_state]) 117 !op[cur_state][new_state])
119 return -EINVAL; 118 return -EINVAL;
120 119
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c
index d0cc122fa3f0..e1732c164a40 100644
--- a/drivers/net/myri10ge/myri10ge.c
+++ b/drivers/net/myri10ge/myri10ge.c
@@ -60,6 +60,7 @@
60#include <linux/crc32.h> 60#include <linux/crc32.h>
61#include <linux/moduleparam.h> 61#include <linux/moduleparam.h>
62#include <linux/io.h> 62#include <linux/io.h>
63#include <linux/log2.h>
63#include <net/checksum.h> 64#include <net/checksum.h>
64#include <asm/byteorder.h> 65#include <asm/byteorder.h>
65#include <asm/io.h> 66#include <asm/io.h>
@@ -1804,7 +1805,7 @@ static int myri10ge_open(struct net_device *dev)
1804 */ 1805 */
1805 big_pow2 = dev->mtu + ETH_HLEN + VLAN_HLEN + MXGEFW_PAD; 1806 big_pow2 = dev->mtu + ETH_HLEN + VLAN_HLEN + MXGEFW_PAD;
1806 if (big_pow2 < MYRI10GE_ALLOC_SIZE / 2) { 1807 if (big_pow2 < MYRI10GE_ALLOC_SIZE / 2) {
1807 while ((big_pow2 & (big_pow2 - 1)) != 0) 1808 while (!is_power_of_2(big_pow2))
1808 big_pow2++; 1809 big_pow2++;
1809 mgp->big_bytes = dev->mtu + ETH_HLEN + VLAN_HLEN + MXGEFW_PAD; 1810 mgp->big_bytes = dev->mtu + ETH_HLEN + VLAN_HLEN + MXGEFW_PAD;
1810 } else { 1811 } else {
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h
index 619503742b7d..325269d8ae38 100644
--- a/drivers/net/netxen/netxen_nic.h
+++ b/drivers/net/netxen/netxen_nic.h
@@ -1097,109 +1097,6 @@ int netxen_nic_change_mtu(struct net_device *netdev, int new_mtu);
1097int netxen_nic_set_mac(struct net_device *netdev, void *p); 1097int netxen_nic_set_mac(struct net_device *netdev, void *p);
1098struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev); 1098struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev);
1099 1099
1100static inline void netxen_nic_disable_int(struct netxen_adapter *adapter)
1101{
1102 uint32_t mask = 0x7ff;
1103 int retries = 32;
1104
1105 DPRINTK(1, INFO, "Entered ISR Disable \n");
1106
1107 switch (adapter->portnum) {
1108 case 0:
1109 writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_0));
1110 break;
1111 case 1:
1112 writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_1));
1113 break;
1114 case 2:
1115 writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_2));
1116 break;
1117 case 3:
1118 writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_3));
1119 break;
1120 }
1121
1122 if (adapter->intr_scheme != -1 &&
1123 adapter->intr_scheme != INTR_SCHEME_PERPORT) {
1124 writel(mask,
1125 (void *)(PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_MASK)));
1126 }
1127
1128 /* Window = 0 or 1 */
1129 if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) {
1130 do {
1131 writel(0xffffffff, (void *)
1132 (PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_TARGET_STATUS)));
1133 mask = readl((void *)
1134 (pci_base_offset(adapter, ISR_INT_VECTOR)));
1135 if (!(mask & 0x80))
1136 break;
1137 udelay(10);
1138 } while (--retries);
1139
1140 if (!retries) {
1141 printk(KERN_NOTICE "%s: Failed to disable interrupt completely\n",
1142 netxen_nic_driver_name);
1143 }
1144 }
1145
1146 DPRINTK(1, INFO, "Done with Disable Int\n");
1147
1148 return;
1149}
1150
1151static inline void netxen_nic_enable_int(struct netxen_adapter *adapter)
1152{
1153 u32 mask;
1154
1155 DPRINTK(1, INFO, "Entered ISR Enable \n");
1156
1157 if (adapter->intr_scheme != -1 &&
1158 adapter->intr_scheme != INTR_SCHEME_PERPORT) {
1159 switch (adapter->ahw.board_type) {
1160 case NETXEN_NIC_GBE:
1161 mask = 0x77b;
1162 break;
1163 case NETXEN_NIC_XGBE:
1164 mask = 0x77f;
1165 break;
1166 default:
1167 mask = 0x7ff;
1168 break;
1169 }
1170
1171 writel(mask,
1172 (void *)(PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_MASK)));
1173 }
1174 switch (adapter->portnum) {
1175 case 0:
1176 writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_0));
1177 break;
1178 case 1:
1179 writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_1));
1180 break;
1181 case 2:
1182 writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_2));
1183 break;
1184 case 3:
1185 writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_3));
1186 break;
1187 }
1188
1189 if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) {
1190 mask = 0xbff;
1191 if (adapter->intr_scheme != -1 &&
1192 adapter->intr_scheme != INTR_SCHEME_PERPORT) {
1193 writel(0X0, NETXEN_CRB_NORMALIZE(adapter, CRB_INT_VECTOR));
1194 }
1195 writel(mask,
1196 (void *)(PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_TARGET_MASK)));
1197 }
1198
1199 DPRINTK(1, INFO, "Done with enable Int\n");
1200
1201 return;
1202}
1203 1100
1204/* 1101/*
1205 * NetXen Board information 1102 * NetXen Board information
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index a66ff58366cf..56f8197b953b 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -156,6 +156,103 @@ static inline void netxen_nic_update_cmd_consumer(struct netxen_adapter *adapter
156#define ADAPTER_LIST_SIZE 12 156#define ADAPTER_LIST_SIZE 12
157int netxen_cards_found; 157int netxen_cards_found;
158 158
159static void netxen_nic_disable_int(struct netxen_adapter *adapter)
160{
161 uint32_t mask = 0x7ff;
162 int retries = 32;
163
164 DPRINTK(1, INFO, "Entered ISR Disable \n");
165
166 switch (adapter->portnum) {
167 case 0:
168 writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_0));
169 break;
170 case 1:
171 writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_1));
172 break;
173 case 2:
174 writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_2));
175 break;
176 case 3:
177 writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_3));
178 break;
179 }
180
181 if (adapter->intr_scheme != -1 &&
182 adapter->intr_scheme != INTR_SCHEME_PERPORT)
183 writel(mask,PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_MASK));
184
185 /* Window = 0 or 1 */
186 if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) {
187 do {
188 writel(0xffffffff,
189 PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_TARGET_STATUS));
190 mask = readl(pci_base_offset(adapter, ISR_INT_VECTOR));
191 if (!(mask & 0x80))
192 break;
193 udelay(10);
194 } while (--retries);
195
196 if (!retries) {
197 printk(KERN_NOTICE "%s: Failed to disable interrupt completely\n",
198 netxen_nic_driver_name);
199 }
200 }
201
202 DPRINTK(1, INFO, "Done with Disable Int\n");
203}
204
205static void netxen_nic_enable_int(struct netxen_adapter *adapter)
206{
207 u32 mask;
208
209 DPRINTK(1, INFO, "Entered ISR Enable \n");
210
211 if (adapter->intr_scheme != -1 &&
212 adapter->intr_scheme != INTR_SCHEME_PERPORT) {
213 switch (adapter->ahw.board_type) {
214 case NETXEN_NIC_GBE:
215 mask = 0x77b;
216 break;
217 case NETXEN_NIC_XGBE:
218 mask = 0x77f;
219 break;
220 default:
221 mask = 0x7ff;
222 break;
223 }
224
225 writel(mask, PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_MASK));
226 }
227
228 switch (adapter->portnum) {
229 case 0:
230 writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_0));
231 break;
232 case 1:
233 writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_1));
234 break;
235 case 2:
236 writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_2));
237 break;
238 case 3:
239 writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_3));
240 break;
241 }
242
243 if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) {
244 mask = 0xbff;
245 if (adapter->intr_scheme != -1 &&
246 adapter->intr_scheme != INTR_SCHEME_PERPORT) {
247 writel(0X0, NETXEN_CRB_NORMALIZE(adapter, CRB_INT_VECTOR));
248 }
249 writel(mask,
250 PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_TARGET_MASK));
251 }
252
253 DPRINTK(1, INFO, "Done with enable Int\n");
254}
255
159/* 256/*
160 * netxen_nic_probe() 257 * netxen_nic_probe()
161 * 258 *
diff --git a/drivers/net/netxen/netxen_nic_niu.c b/drivers/net/netxen/netxen_nic_niu.c
index 75102d30730f..05e0577a0e10 100644
--- a/drivers/net/netxen/netxen_nic_niu.c
+++ b/drivers/net/netxen/netxen_nic_niu.c
@@ -724,7 +724,7 @@ int netxen_niu_disable_gbe_port(struct netxen_adapter *adapter)
724 __u32 mac_cfg0; 724 __u32 mac_cfg0;
725 u32 port = physical_port[adapter->portnum]; 725 u32 port = physical_port[adapter->portnum];
726 726
727 if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS)) 727 if (port > NETXEN_NIU_MAX_GBE_PORTS)
728 return -EINVAL; 728 return -EINVAL;
729 mac_cfg0 = 0; 729 mac_cfg0 = 0;
730 netxen_gb_soft_reset(mac_cfg0); 730 netxen_gb_soft_reset(mac_cfg0);
@@ -757,7 +757,7 @@ int netxen_niu_set_promiscuous_mode(struct netxen_adapter *adapter,
757 __u32 reg; 757 __u32 reg;
758 u32 port = physical_port[adapter->portnum]; 758 u32 port = physical_port[adapter->portnum];
759 759
760 if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS)) 760 if (port > NETXEN_NIU_MAX_GBE_PORTS)
761 return -EINVAL; 761 return -EINVAL;
762 762
763 /* save previous contents */ 763 /* save previous contents */
@@ -894,7 +894,7 @@ int netxen_niu_xg_set_promiscuous_mode(struct netxen_adapter *adapter,
894 __u32 reg; 894 __u32 reg;
895 u32 port = physical_port[adapter->portnum]; 895 u32 port = physical_port[adapter->portnum];
896 896
897 if ((port < 0) || (port > NETXEN_NIU_MAX_XG_PORTS)) 897 if (port > NETXEN_NIU_MAX_XG_PORTS)
898 return -EINVAL; 898 return -EINVAL;
899 899
900 if (netxen_nic_hw_read_wx(adapter, 900 if (netxen_nic_hw_read_wx(adapter,
diff --git a/drivers/net/pasemi_mac.c b/drivers/net/pasemi_mac.c
index 8d38425e46c3..0b3066a6fe40 100644
--- a/drivers/net/pasemi_mac.c
+++ b/drivers/net/pasemi_mac.c
@@ -755,7 +755,7 @@ static int pasemi_mac_open(struct net_device *dev)
755 flags |= PAS_MAC_CFG_PCFG_TSR_1G | PAS_MAC_CFG_PCFG_SPD_1G; 755 flags |= PAS_MAC_CFG_PCFG_TSR_1G | PAS_MAC_CFG_PCFG_SPD_1G;
756 756
757 pci_write_config_dword(mac->iob_pdev, PAS_IOB_DMA_RXCH_CFG(mac->dma_rxch), 757 pci_write_config_dword(mac->iob_pdev, PAS_IOB_DMA_RXCH_CFG(mac->dma_rxch),
758 PAS_IOB_DMA_RXCH_CFG_CNTTH(1)); 758 PAS_IOB_DMA_RXCH_CFG_CNTTH(0));
759 759
760 pci_write_config_dword(mac->iob_pdev, PAS_IOB_DMA_TXCH_CFG(mac->dma_txch), 760 pci_write_config_dword(mac->iob_pdev, PAS_IOB_DMA_TXCH_CFG(mac->dma_txch),
761 PAS_IOB_DMA_TXCH_CFG_CNTTH(32)); 761 PAS_IOB_DMA_TXCH_CFG_CNTTH(32));
diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c
index 808fae1577e0..50dff1b81d34 100644
--- a/drivers/net/pcmcia/axnet_cs.c
+++ b/drivers/net/pcmcia/axnet_cs.c
@@ -521,6 +521,7 @@ static void mdio_write(kio_addr_t addr, int phy_id, int loc, int value)
521 521
522static int axnet_open(struct net_device *dev) 522static int axnet_open(struct net_device *dev)
523{ 523{
524 int ret;
524 axnet_dev_t *info = PRIV(dev); 525 axnet_dev_t *info = PRIV(dev);
525 struct pcmcia_device *link = info->p_dev; 526 struct pcmcia_device *link = info->p_dev;
526 527
@@ -529,9 +530,11 @@ static int axnet_open(struct net_device *dev)
529 if (!pcmcia_dev_present(link)) 530 if (!pcmcia_dev_present(link))
530 return -ENODEV; 531 return -ENODEV;
531 532
532 link->open++; 533 ret = request_irq(dev->irq, ei_irq_wrapper, IRQF_SHARED, "axnet_cs", dev);
534 if (ret)
535 return ret;
533 536
534 request_irq(dev->irq, ei_irq_wrapper, IRQF_SHARED, "axnet_cs", dev); 537 link->open++;
535 538
536 info->link_status = 0x00; 539 info->link_status = 0x00;
537 init_timer(&info->watchdog); 540 init_timer(&info->watchdog);
diff --git a/drivers/net/pcmcia/fmvj18x_cs.c b/drivers/net/pcmcia/fmvj18x_cs.c
index 3f93d4933235..85d5f2ca4bb5 100644
--- a/drivers/net/pcmcia/fmvj18x_cs.c
+++ b/drivers/net/pcmcia/fmvj18x_cs.c
@@ -109,7 +109,7 @@ static const struct ethtool_ops netdev_ethtool_ops;
109 card type 109 card type
110 */ 110 */
111typedef enum { MBH10302, MBH10304, TDK, CONTEC, LA501, UNGERMANN, 111typedef enum { MBH10302, MBH10304, TDK, CONTEC, LA501, UNGERMANN,
112 XXX10304 112 XXX10304, NEC, KME
113} cardtype_t; 113} cardtype_t;
114 114
115/* 115/*
@@ -374,6 +374,18 @@ static int fmvj18x_config(struct pcmcia_device *link)
374 link->io.NumPorts2 = 8; 374 link->io.NumPorts2 = 8;
375 } 375 }
376 break; 376 break;
377 case MANFID_NEC:
378 cardtype = NEC; /* MultiFunction Card */
379 link->conf.ConfigBase = 0x800;
380 link->conf.ConfigIndex = 0x47;
381 link->io.NumPorts2 = 8;
382 break;
383 case MANFID_KME:
384 cardtype = KME; /* MultiFunction Card */
385 link->conf.ConfigBase = 0x800;
386 link->conf.ConfigIndex = 0x47;
387 link->io.NumPorts2 = 8;
388 break;
377 case MANFID_CONTEC: 389 case MANFID_CONTEC:
378 cardtype = CONTEC; 390 cardtype = CONTEC;
379 break; 391 break;
@@ -450,6 +462,8 @@ static int fmvj18x_config(struct pcmcia_device *link)
450 case TDK: 462 case TDK:
451 case LA501: 463 case LA501:
452 case CONTEC: 464 case CONTEC:
465 case NEC:
466 case KME:
453 tuple.DesiredTuple = CISTPL_FUNCE; 467 tuple.DesiredTuple = CISTPL_FUNCE;
454 tuple.TupleOffset = 0; 468 tuple.TupleOffset = 0;
455 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); 469 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
@@ -469,6 +483,10 @@ static int fmvj18x_config(struct pcmcia_device *link)
469 card_name = "TDK LAK-CD021"; 483 card_name = "TDK LAK-CD021";
470 } else if( cardtype == LA501 ) { 484 } else if( cardtype == LA501 ) {
471 card_name = "LA501"; 485 card_name = "LA501";
486 } else if( cardtype == NEC ) {
487 card_name = "PK-UG-J001";
488 } else if( cardtype == KME ) {
489 card_name = "Panasonic";
472 } else { 490 } else {
473 card_name = "C-NET(PC)C"; 491 card_name = "C-NET(PC)C";
474 } 492 }
@@ -678,8 +696,11 @@ static struct pcmcia_device_id fmvj18x_ids[] = {
678 PCMCIA_DEVICE_PROD_ID1("PCMCIA MBH10302", 0x8f4005da), 696 PCMCIA_DEVICE_PROD_ID1("PCMCIA MBH10302", 0x8f4005da),
679 PCMCIA_DEVICE_PROD_ID1("UBKK,V2.0", 0x90888080), 697 PCMCIA_DEVICE_PROD_ID1("UBKK,V2.0", 0x90888080),
680 PCMCIA_PFC_DEVICE_PROD_ID12(0, "TDK", "GlobalNetworker 3410/3412", 0x1eae9475, 0xd9a93bed), 698 PCMCIA_PFC_DEVICE_PROD_ID12(0, "TDK", "GlobalNetworker 3410/3412", 0x1eae9475, 0xd9a93bed),
699 PCMCIA_PFC_DEVICE_PROD_ID12(0, "NEC", "PK-UG-J001" ,0x18df0ba0 ,0x831b1064),
681 PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0105, 0x0d0a), 700 PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0105, 0x0d0a),
682 PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0105, 0x0e0a), 701 PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0105, 0x0e0a),
702 PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0032, 0x0a05),
703 PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0032, 0x1101),
683 PCMCIA_DEVICE_NULL, 704 PCMCIA_DEVICE_NULL,
684}; 705};
685MODULE_DEVICE_TABLE(pcmcia, fmvj18x_ids); 706MODULE_DEVICE_TABLE(pcmcia, fmvj18x_ids);
diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c
index d88e9b2e93cf..63de89e93b70 100644
--- a/drivers/net/pcmcia/pcnet_cs.c
+++ b/drivers/net/pcmcia/pcnet_cs.c
@@ -960,6 +960,7 @@ static void mii_phy_probe(struct net_device *dev)
960 960
961static int pcnet_open(struct net_device *dev) 961static int pcnet_open(struct net_device *dev)
962{ 962{
963 int ret;
963 pcnet_dev_t *info = PRIV(dev); 964 pcnet_dev_t *info = PRIV(dev);
964 struct pcmcia_device *link = info->p_dev; 965 struct pcmcia_device *link = info->p_dev;
965 966
@@ -968,10 +969,12 @@ static int pcnet_open(struct net_device *dev)
968 if (!pcmcia_dev_present(link)) 969 if (!pcmcia_dev_present(link))
969 return -ENODEV; 970 return -ENODEV;
970 971
971 link->open++;
972
973 set_misc_reg(dev); 972 set_misc_reg(dev);
974 request_irq(dev->irq, ei_irq_wrapper, IRQF_SHARED, dev_info, dev); 973 ret = request_irq(dev->irq, ei_irq_wrapper, IRQF_SHARED, dev_info, dev);
974 if (ret)
975 return ret;
976
977 link->open++;
975 978
976 info->phy_id = info->eth_phy; 979 info->phy_id = info->eth_phy;
977 info->link_status = 0x00; 980 info->link_status = 0x00;
@@ -1552,6 +1555,7 @@ static struct pcmcia_device_id pcnet_ids[] = {
1552 PCMCIA_PFC_DEVICE_PROD_ID12(0, "Grey Cell", "GCS3000", 0x2a151fac, 0x48b932ae), 1555 PCMCIA_PFC_DEVICE_PROD_ID12(0, "Grey Cell", "GCS3000", 0x2a151fac, 0x48b932ae),
1553 PCMCIA_PFC_DEVICE_PROD_ID12(0, "Linksys", "EtherFast 10&100 + 56K PC Card (PCMLM56)", 0x0733cc81, 0xb3765033), 1556 PCMCIA_PFC_DEVICE_PROD_ID12(0, "Linksys", "EtherFast 10&100 + 56K PC Card (PCMLM56)", 0x0733cc81, 0xb3765033),
1554 PCMCIA_PFC_DEVICE_PROD_ID12(0, "LINKSYS", "PCMLM336", 0xf7cb0b07, 0x7a821b58), 1557 PCMCIA_PFC_DEVICE_PROD_ID12(0, "LINKSYS", "PCMLM336", 0xf7cb0b07, 0x7a821b58),
1558 PCMCIA_PFC_DEVICE_PROD_ID12(0, "MICRO RESEARCH", "COMBO-L/M-336", 0xb2ced065, 0x3ced0555),
1555 PCMCIA_PFC_DEVICE_PROD_ID12(0, "PCMCIAs", "ComboCard", 0xdcfe12d3, 0xcd8906cc), 1559 PCMCIA_PFC_DEVICE_PROD_ID12(0, "PCMCIAs", "ComboCard", 0xdcfe12d3, 0xcd8906cc),
1556 PCMCIA_PFC_DEVICE_PROD_ID12(0, "PCMCIAs", "LanModem", 0xdcfe12d3, 0xc67c648f), 1560 PCMCIA_PFC_DEVICE_PROD_ID12(0, "PCMCIAs", "LanModem", 0xdcfe12d3, 0xc67c648f),
1557 PCMCIA_MFC_DEVICE_PROD_ID12(0, "IBM", "Home and Away 28.8 PC Card ", 0xb569a6e5, 0x5bd4ff2c), 1561 PCMCIA_MFC_DEVICE_PROD_ID12(0, "IBM", "Home and Away 28.8 PC Card ", 0xb569a6e5, 0x5bd4ff2c),
@@ -1577,6 +1581,7 @@ static struct pcmcia_device_id pcnet_ids[] = {
1577 PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1103), 1581 PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1103),
1578 PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1121), 1582 PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1121),
1579 PCMCIA_DEVICE_PROD_ID12("2408LAN", "Ethernet", 0x352fff7f, 0x00b2e941), 1583 PCMCIA_DEVICE_PROD_ID12("2408LAN", "Ethernet", 0x352fff7f, 0x00b2e941),
1584 PCMCIA_DEVICE_PROD_ID1234("Socket", "CF 10/100 Ethernet Card", "Revision B", "05/11/06", 0xb38bcc2e, 0x4de88352, 0xeaca6c8d, 0x7e57c22e),
1580 PCMCIA_DEVICE_PROD_ID123("Cardwell", "PCMCIA", "ETHERNET", 0x9533672e, 0x281f1c5d, 0x3ff7175b), 1585 PCMCIA_DEVICE_PROD_ID123("Cardwell", "PCMCIA", "ETHERNET", 0x9533672e, 0x281f1c5d, 0x3ff7175b),
1581 PCMCIA_DEVICE_PROD_ID123("CNet ", "CN30BC", "ETHERNET", 0x9fe55d3d, 0x85601198, 0x3ff7175b), 1586 PCMCIA_DEVICE_PROD_ID123("CNet ", "CN30BC", "ETHERNET", 0x9fe55d3d, 0x85601198, 0x3ff7175b),
1582 PCMCIA_DEVICE_PROD_ID123("Digital", "Ethernet", "Adapter", 0x9999ab35, 0x00b2e941, 0x4b0d829e), 1587 PCMCIA_DEVICE_PROD_ID123("Digital", "Ethernet", "Adapter", 0x9999ab35, 0x00b2e941, 0x4b0d829e),
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index 09b6f259eb92..dd09011c7ee5 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -55,6 +55,11 @@ config BROADCOM_PHY
55 ---help--- 55 ---help---
56 Currently supports the BCM5411, BCM5421 and BCM5461 PHYs. 56 Currently supports the BCM5411, BCM5421 and BCM5461 PHYs.
57 57
58config ICPLUS_PHY
59 tristate "Drivers for ICPlus PHYs"
60 ---help---
61 Currently supports the IP175C PHY.
62
58config FIXED_PHY 63config FIXED_PHY
59 tristate "Drivers for PHY emulation on fixed speed/link" 64 tristate "Drivers for PHY emulation on fixed speed/link"
60 ---help--- 65 ---help---
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index bcd1efbd2a18..8885650647ff 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -11,4 +11,5 @@ obj-$(CONFIG_QSEMI_PHY) += qsemi.o
11obj-$(CONFIG_SMSC_PHY) += smsc.o 11obj-$(CONFIG_SMSC_PHY) += smsc.o
12obj-$(CONFIG_VITESSE_PHY) += vitesse.o 12obj-$(CONFIG_VITESSE_PHY) += vitesse.o
13obj-$(CONFIG_BROADCOM_PHY) += broadcom.o 13obj-$(CONFIG_BROADCOM_PHY) += broadcom.o
14obj-$(CONFIG_ICPLUS_PHY) += icplus.o
14obj-$(CONFIG_FIXED_PHY) += fixed.o 15obj-$(CONFIG_FIXED_PHY) += fixed.o
diff --git a/drivers/net/phy/icplus.c b/drivers/net/phy/icplus.c
new file mode 100644
index 000000000000..af3f1f2a9f87
--- /dev/null
+++ b/drivers/net/phy/icplus.c
@@ -0,0 +1,134 @@
1/*
2 * Driver for ICPlus PHYs
3 *
4 * Copyright (c) 2007 Freescale Semiconductor, Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 *
11 */
12#include <linux/kernel.h>
13#include <linux/string.h>
14#include <linux/errno.h>
15#include <linux/unistd.h>
16#include <linux/slab.h>
17#include <linux/interrupt.h>
18#include <linux/init.h>
19#include <linux/delay.h>
20#include <linux/netdevice.h>
21#include <linux/etherdevice.h>
22#include <linux/skbuff.h>
23#include <linux/spinlock.h>
24#include <linux/mm.h>
25#include <linux/module.h>
26#include <linux/mii.h>
27#include <linux/ethtool.h>
28#include <linux/phy.h>
29
30#include <asm/io.h>
31#include <asm/irq.h>
32#include <asm/uaccess.h>
33
34MODULE_DESCRIPTION("ICPlus IP175C PHY driver");
35MODULE_AUTHOR("Michael Barkowski");
36MODULE_LICENSE("GPL");
37
38static int ip175c_config_init(struct phy_device *phydev)
39{
40 int err, i;
41 static int full_reset_performed = 0;
42
43 if (full_reset_performed == 0) {
44
45 /* master reset */
46 err = phydev->bus->write(phydev->bus, 30, 0, 0x175c);
47 if (err < 0)
48 return err;
49
50 /* ensure no bus delays overlap reset period */
51 err = phydev->bus->read(phydev->bus, 30, 0);
52
53 /* data sheet specifies reset period is 2 msec */
54 mdelay(2);
55
56 /* enable IP175C mode */
57 err = phydev->bus->write(phydev->bus, 29, 31, 0x175c);
58 if (err < 0)
59 return err;
60
61 /* Set MII0 speed and duplex (in PHY mode) */
62 err = phydev->bus->write(phydev->bus, 29, 22, 0x420);
63 if (err < 0)
64 return err;
65
66 /* reset switch ports */
67 for (i = 0; i < 5; i++) {
68 err = phydev->bus->write(phydev->bus, i,
69 MII_BMCR, BMCR_RESET);
70 if (err < 0)
71 return err;
72 }
73
74 for (i = 0; i < 5; i++)
75 err = phydev->bus->read(phydev->bus, i, MII_BMCR);
76
77 mdelay(2);
78
79 full_reset_performed = 1;
80 }
81
82 if (phydev->addr != 4) {
83 phydev->state = PHY_RUNNING;
84 phydev->speed = SPEED_100;
85 phydev->duplex = DUPLEX_FULL;
86 phydev->link = 1;
87 netif_carrier_on(phydev->attached_dev);
88 }
89
90 return 0;
91}
92
93static int ip175c_read_status(struct phy_device *phydev)
94{
95 if (phydev->addr == 4) /* WAN port */
96 genphy_read_status(phydev);
97 else
98 /* Don't need to read status for switch ports */
99 phydev->irq = PHY_IGNORE_INTERRUPT;
100
101 return 0;
102}
103
104static int ip175c_config_aneg(struct phy_device *phydev)
105{
106 if (phydev->addr == 4) /* WAN port */
107 genphy_config_aneg(phydev);
108
109 return 0;
110}
111
112static struct phy_driver ip175c_driver = {
113 .phy_id = 0x02430d80,
114 .name = "ICPlus IP175C",
115 .phy_id_mask = 0x0ffffff0,
116 .features = PHY_BASIC_FEATURES,
117 .config_init = &ip175c_config_init,
118 .config_aneg = &ip175c_config_aneg,
119 .read_status = &ip175c_read_status,
120 .driver = { .owner = THIS_MODULE,},
121};
122
123static int __init ip175c_init(void)
124{
125 return phy_driver_register(&ip175c_driver);
126}
127
128static void __exit ip175c_exit(void)
129{
130 phy_driver_unregister(&ip175c_driver);
131}
132
133module_init(ip175c_init);
134module_exit(ip175c_exit);
diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
index b87f8d2a888b..d2ede5ff9fff 100644
--- a/drivers/net/phy/marvell.c
+++ b/drivers/net/phy/marvell.c
@@ -60,6 +60,7 @@
60#define MII_M1111_PHY_EXT_SR 0x1b 60#define MII_M1111_PHY_EXT_SR 0x1b
61#define MII_M1111_HWCFG_MODE_MASK 0xf 61#define MII_M1111_HWCFG_MODE_MASK 0xf
62#define MII_M1111_HWCFG_MODE_RGMII 0xb 62#define MII_M1111_HWCFG_MODE_RGMII 0xb
63#define MII_M1111_HWCFG_MODE_SGMII_NO_CLK 0x4
63 64
64MODULE_DESCRIPTION("Marvell PHY driver"); 65MODULE_DESCRIPTION("Marvell PHY driver");
65MODULE_AUTHOR("Andy Fleming"); 66MODULE_AUTHOR("Andy Fleming");
@@ -169,6 +170,21 @@ static int m88e1111_config_init(struct phy_device *phydev)
169 return err; 170 return err;
170 } 171 }
171 172
173 if (phydev->interface == PHY_INTERFACE_MODE_SGMII) {
174 int temp;
175
176 temp = phy_read(phydev, MII_M1111_PHY_EXT_SR);
177 if (temp < 0)
178 return temp;
179
180 temp &= ~(MII_M1111_HWCFG_MODE_MASK);
181 temp |= MII_M1111_HWCFG_MODE_SGMII_NO_CLK;
182
183 err = phy_write(phydev, MII_M1111_PHY_EXT_SR, temp);
184 if (err < 0)
185 return err;
186 }
187
172 err = phy_write(phydev, MII_BMCR, BMCR_RESET); 188 err = phy_write(phydev, MII_BMCR, BMCR_RESET);
173 if (err < 0) 189 if (err < 0)
174 return err; 190 return err;
@@ -238,77 +254,84 @@ static int m88e1145_config_init(struct phy_device *phydev)
238 return 0; 254 return 0;
239} 255}
240 256
241static struct phy_driver m88e1101_driver = { 257static struct phy_driver marvell_drivers[] = {
242 .phy_id = 0x01410c60, 258 {
243 .phy_id_mask = 0xfffffff0, 259 .phy_id = 0x01410c60,
244 .name = "Marvell 88E1101", 260 .phy_id_mask = 0xfffffff0,
245 .features = PHY_GBIT_FEATURES, 261 .name = "Marvell 88E1101",
246 .flags = PHY_HAS_INTERRUPT, 262 .features = PHY_GBIT_FEATURES,
247 .config_aneg = &marvell_config_aneg, 263 .flags = PHY_HAS_INTERRUPT,
248 .read_status = &genphy_read_status, 264 .config_aneg = &marvell_config_aneg,
249 .ack_interrupt = &marvell_ack_interrupt, 265 .read_status = &genphy_read_status,
250 .config_intr = &marvell_config_intr, 266 .ack_interrupt = &marvell_ack_interrupt,
251 .driver = {.owner = THIS_MODULE,}, 267 .config_intr = &marvell_config_intr,
252}; 268 .driver = {.owner = THIS_MODULE,},
253 269 },
254static struct phy_driver m88e1111_driver = { 270 {
255 .phy_id = 0x01410cc0, 271 .phy_id = 0x01410c90,
256 .phy_id_mask = 0xfffffff0, 272 .phy_id_mask = 0xfffffff0,
257 .name = "Marvell 88E1111", 273 .name = "Marvell 88E1112",
258 .features = PHY_GBIT_FEATURES, 274 .features = PHY_GBIT_FEATURES,
259 .flags = PHY_HAS_INTERRUPT, 275 .flags = PHY_HAS_INTERRUPT,
260 .config_aneg = &marvell_config_aneg, 276 .config_init = &m88e1111_config_init,
261 .read_status = &genphy_read_status, 277 .config_aneg = &marvell_config_aneg,
262 .ack_interrupt = &marvell_ack_interrupt, 278 .read_status = &genphy_read_status,
263 .config_intr = &marvell_config_intr, 279 .ack_interrupt = &marvell_ack_interrupt,
264 .config_init = &m88e1111_config_init, 280 .config_intr = &marvell_config_intr,
265 .driver = {.owner = THIS_MODULE,}, 281 .driver = {.owner = THIS_MODULE,},
266}; 282 },
267 283 {
268static struct phy_driver m88e1145_driver = { 284 .phy_id = 0x01410cc0,
269 .phy_id = 0x01410cd0, 285 .phy_id_mask = 0xfffffff0,
270 .phy_id_mask = 0xfffffff0, 286 .name = "Marvell 88E1111",
271 .name = "Marvell 88E1145", 287 .features = PHY_GBIT_FEATURES,
272 .features = PHY_GBIT_FEATURES, 288 .flags = PHY_HAS_INTERRUPT,
273 .flags = PHY_HAS_INTERRUPT, 289 .config_init = &m88e1111_config_init,
274 .config_init = &m88e1145_config_init, 290 .config_aneg = &marvell_config_aneg,
275 .config_aneg = &marvell_config_aneg, 291 .read_status = &genphy_read_status,
276 .read_status = &genphy_read_status, 292 .ack_interrupt = &marvell_ack_interrupt,
277 .ack_interrupt = &marvell_ack_interrupt, 293 .config_intr = &marvell_config_intr,
278 .config_intr = &marvell_config_intr, 294 .driver = {.owner = THIS_MODULE,},
279 .driver = {.owner = THIS_MODULE,}, 295 },
296 {
297 .phy_id = 0x01410cd0,
298 .phy_id_mask = 0xfffffff0,
299 .name = "Marvell 88E1145",
300 .features = PHY_GBIT_FEATURES,
301 .flags = PHY_HAS_INTERRUPT,
302 .config_init = &m88e1145_config_init,
303 .config_aneg = &marvell_config_aneg,
304 .read_status = &genphy_read_status,
305 .ack_interrupt = &marvell_ack_interrupt,
306 .config_intr = &marvell_config_intr,
307 .driver = {.owner = THIS_MODULE,},
308 }
280}; 309};
281 310
282static int __init marvell_init(void) 311static int __init marvell_init(void)
283{ 312{
284 int ret; 313 int ret;
314 int i;
285 315
286 ret = phy_driver_register(&m88e1101_driver); 316 for (i = 0; i < ARRAY_SIZE(marvell_drivers); i++) {
287 if (ret) 317 ret = phy_driver_register(&marvell_drivers[i]);
288 return ret;
289 318
290 ret = phy_driver_register(&m88e1111_driver); 319 if (ret) {
291 if (ret) 320 while (i-- > 0)
292 goto err1111; 321 phy_driver_unregister(&marvell_drivers[i]);
293 322 return ret;
294 ret = phy_driver_register(&m88e1145_driver); 323 }
295 if (ret) 324 }
296 goto err1145;
297 325
298 return 0; 326 return 0;
299
300err1145:
301 phy_driver_unregister(&m88e1111_driver);
302err1111:
303 phy_driver_unregister(&m88e1101_driver);
304 return ret;
305} 327}
306 328
307static void __exit marvell_exit(void) 329static void __exit marvell_exit(void)
308{ 330{
309 phy_driver_unregister(&m88e1101_driver); 331 int i;
310 phy_driver_unregister(&m88e1111_driver); 332
311 phy_driver_unregister(&m88e1145_driver); 333 for (i = 0; i < ARRAY_SIZE(marvell_drivers); i++)
334 phy_driver_unregister(&marvell_drivers[i]);
312} 335}
313 336
314module_init(marvell_init); 337module_init(marvell_init);
diff --git a/drivers/net/ps3_gelic_net.c b/drivers/net/ps3_gelic_net.c
new file mode 100644
index 000000000000..08d25066f051
--- /dev/null
+++ b/drivers/net/ps3_gelic_net.c
@@ -0,0 +1,1576 @@
1/*
2 * PS3 gelic network driver.
3 *
4 * Copyright (C) 2007 Sony Computer Entertainment Inc.
5 * Copyright 2006, 2007 Sony Corporation
6 *
7 * This file is based on: spider_net.c
8 *
9 * (C) Copyright IBM Corp. 2005
10 *
11 * Authors : Utz Bacher <utz.bacher@de.ibm.com>
12 * Jens Osterkamp <Jens.Osterkamp@de.ibm.com>
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2, or (at your option)
17 * any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 */
28
29#undef DEBUG
30
31#include <linux/kernel.h>
32#include <linux/module.h>
33
34#include <linux/etherdevice.h>
35#include <linux/ethtool.h>
36#include <linux/if_vlan.h>
37
38#include <linux/in.h>
39#include <linux/ip.h>
40#include <linux/tcp.h>
41
42#include <linux/dma-mapping.h>
43#include <net/checksum.h>
44#include <asm/firmware.h>
45#include <asm/ps3.h>
46#include <asm/lv1call.h>
47
48#include "ps3_gelic_net.h"
49
50#define DRV_NAME "Gelic Network Driver"
51#define DRV_VERSION "1.0"
52
53MODULE_AUTHOR("SCE Inc.");
54MODULE_DESCRIPTION("Gelic Network driver");
55MODULE_LICENSE("GPL");
56
57static inline struct device *ctodev(struct gelic_net_card *card)
58{
59 return &card->dev->core;
60}
61static inline unsigned int bus_id(struct gelic_net_card *card)
62{
63 return card->dev->bus_id;
64}
65static inline unsigned int dev_id(struct gelic_net_card *card)
66{
67 return card->dev->dev_id;
68}
69
70/* set irq_mask */
71static int gelic_net_set_irq_mask(struct gelic_net_card *card, u64 mask)
72{
73 int status;
74
75 status = lv1_net_set_interrupt_mask(bus_id(card), dev_id(card),
76 mask, 0);
77 if (status)
78 dev_info(ctodev(card),
79 "lv1_net_set_interrupt_mask failed %d\n", status);
80 return status;
81}
82static inline void gelic_net_rx_irq_on(struct gelic_net_card *card)
83{
84 gelic_net_set_irq_mask(card, card->ghiintmask | GELIC_NET_RXINT);
85}
86static inline void gelic_net_rx_irq_off(struct gelic_net_card *card)
87{
88 gelic_net_set_irq_mask(card, card->ghiintmask & ~GELIC_NET_RXINT);
89}
90/**
91 * gelic_net_get_descr_status -- returns the status of a descriptor
92 * @descr: descriptor to look at
93 *
94 * returns the status as in the dmac_cmd_status field of the descriptor
95 */
96static enum gelic_net_descr_status
97gelic_net_get_descr_status(struct gelic_net_descr *descr)
98{
99 u32 cmd_status;
100
101 cmd_status = descr->dmac_cmd_status;
102 cmd_status >>= GELIC_NET_DESCR_IND_PROC_SHIFT;
103 return cmd_status;
104}
105
106/**
107 * gelic_net_set_descr_status -- sets the status of a descriptor
108 * @descr: descriptor to change
109 * @status: status to set in the descriptor
110 *
111 * changes the status to the specified value. Doesn't change other bits
112 * in the status
113 */
114static void gelic_net_set_descr_status(struct gelic_net_descr *descr,
115 enum gelic_net_descr_status status)
116{
117 u32 cmd_status;
118
119 /* read the status */
120 cmd_status = descr->dmac_cmd_status;
121 /* clean the upper 4 bits */
122 cmd_status &= GELIC_NET_DESCR_IND_PROC_MASKO;
123 /* add the status to it */
124 cmd_status |= ((u32)status) << GELIC_NET_DESCR_IND_PROC_SHIFT;
125 /* and write it back */
126 descr->dmac_cmd_status = cmd_status;
127 /*
128 * dma_cmd_status field is used to indicate whether the descriptor
129 * is valid or not.
130 * Usually caller of this function wants to inform that to the
131 * hardware, so we assure here the hardware sees the change.
132 */
133 wmb();
134}
135
136/**
137 * gelic_net_free_chain - free descriptor chain
138 * @card: card structure
139 * @descr_in: address of desc
140 */
141static void gelic_net_free_chain(struct gelic_net_card *card,
142 struct gelic_net_descr *descr_in)
143{
144 struct gelic_net_descr *descr;
145
146 for (descr = descr_in; descr && descr->bus_addr; descr = descr->next) {
147 dma_unmap_single(ctodev(card), descr->bus_addr,
148 GELIC_NET_DESCR_SIZE, DMA_BIDIRECTIONAL);
149 descr->bus_addr = 0;
150 }
151}
152
153/**
154 * gelic_net_init_chain - links descriptor chain
155 * @card: card structure
156 * @chain: address of chain
157 * @start_descr: address of descriptor array
158 * @no: number of descriptors
159 *
160 * we manage a circular list that mirrors the hardware structure,
161 * except that the hardware uses bus addresses.
162 *
163 * returns 0 on success, <0 on failure
164 */
165static int gelic_net_init_chain(struct gelic_net_card *card,
166 struct gelic_net_descr_chain *chain,
167 struct gelic_net_descr *start_descr, int no)
168{
169 int i;
170 struct gelic_net_descr *descr;
171
172 descr = start_descr;
173 memset(descr, 0, sizeof(*descr) * no);
174
175 /* set up the hardware pointers in each descriptor */
176 for (i = 0; i < no; i++, descr++) {
177 gelic_net_set_descr_status(descr, GELIC_NET_DESCR_NOT_IN_USE);
178 descr->bus_addr =
179 dma_map_single(ctodev(card), descr,
180 GELIC_NET_DESCR_SIZE,
181 DMA_BIDIRECTIONAL);
182
183 if (!descr->bus_addr)
184 goto iommu_error;
185
186 descr->next = descr + 1;
187 descr->prev = descr - 1;
188 }
189 /* make them as ring */
190 (descr - 1)->next = start_descr;
191 start_descr->prev = (descr - 1);
192
193 /* chain bus addr of hw descriptor */
194 descr = start_descr;
195 for (i = 0; i < no; i++, descr++) {
196 descr->next_descr_addr = descr->next->bus_addr;
197 }
198
199 chain->head = start_descr;
200 chain->tail = start_descr;
201
202 /* do not chain last hw descriptor */
203 (descr - 1)->next_descr_addr = 0;
204
205 return 0;
206
207iommu_error:
208 for (i--, descr--; 0 <= i; i--, descr--)
209 if (descr->bus_addr)
210 dma_unmap_single(ctodev(card), descr->bus_addr,
211 GELIC_NET_DESCR_SIZE,
212 DMA_BIDIRECTIONAL);
213 return -ENOMEM;
214}
215
216/**
217 * gelic_net_prepare_rx_descr - reinitializes a rx descriptor
218 * @card: card structure
219 * @descr: descriptor to re-init
220 *
221 * return 0 on succes, <0 on failure
222 *
223 * allocates a new rx skb, iommu-maps it and attaches it to the descriptor.
224 * Activate the descriptor state-wise
225 */
226static int gelic_net_prepare_rx_descr(struct gelic_net_card *card,
227 struct gelic_net_descr *descr)
228{
229 int offset;
230 unsigned int bufsize;
231
232 if (gelic_net_get_descr_status(descr) != GELIC_NET_DESCR_NOT_IN_USE) {
233 dev_info(ctodev(card), "%s: ERROR status \n", __func__);
234 }
235 /* we need to round up the buffer size to a multiple of 128 */
236 bufsize = ALIGN(GELIC_NET_MAX_MTU, GELIC_NET_RXBUF_ALIGN);
237
238 /* and we need to have it 128 byte aligned, therefore we allocate a
239 * bit more */
240 descr->skb = netdev_alloc_skb(card->netdev,
241 bufsize + GELIC_NET_RXBUF_ALIGN - 1);
242 if (!descr->skb) {
243 descr->buf_addr = 0; /* tell DMAC don't touch memory */
244 dev_info(ctodev(card),
245 "%s:allocate skb failed !!\n", __func__);
246 return -ENOMEM;
247 }
248 descr->buf_size = bufsize;
249 descr->dmac_cmd_status = 0;
250 descr->result_size = 0;
251 descr->valid_size = 0;
252 descr->data_error = 0;
253
254 offset = ((unsigned long)descr->skb->data) &
255 (GELIC_NET_RXBUF_ALIGN - 1);
256 if (offset)
257 skb_reserve(descr->skb, GELIC_NET_RXBUF_ALIGN - offset);
258 /* io-mmu-map the skb */
259 descr->buf_addr = dma_map_single(ctodev(card), descr->skb->data,
260 GELIC_NET_MAX_MTU,
261 DMA_FROM_DEVICE);
262 if (!descr->buf_addr) {
263 dev_kfree_skb_any(descr->skb);
264 descr->skb = NULL;
265 dev_info(ctodev(card),
266 "%s:Could not iommu-map rx buffer\n", __func__);
267 gelic_net_set_descr_status(descr, GELIC_NET_DESCR_NOT_IN_USE);
268 return -ENOMEM;
269 } else {
270 gelic_net_set_descr_status(descr, GELIC_NET_DESCR_CARDOWNED);
271 return 0;
272 }
273}
274
275/**
276 * gelic_net_release_rx_chain - free all skb of rx descr
277 * @card: card structure
278 *
279 */
280static void gelic_net_release_rx_chain(struct gelic_net_card *card)
281{
282 struct gelic_net_descr *descr = card->rx_chain.head;
283
284 do {
285 if (descr->skb) {
286 dma_unmap_single(ctodev(card),
287 descr->buf_addr,
288 descr->skb->len,
289 DMA_FROM_DEVICE);
290 descr->buf_addr = 0;
291 dev_kfree_skb_any(descr->skb);
292 descr->skb = NULL;
293 descr->dmac_cmd_status = GELIC_NET_DESCR_NOT_IN_USE;
294 }
295 descr = descr->next;
296 } while (descr != card->rx_chain.head);
297}
298
299/**
300 * gelic_net_fill_rx_chain - fills descriptors/skbs in the rx chains
301 * @card: card structure
302 *
303 * fills all descriptors in the rx chain: allocates skbs
304 * and iommu-maps them.
305 * returns 0 on success, <0 on failure
306 */
307static int gelic_net_fill_rx_chain(struct gelic_net_card *card)
308{
309 struct gelic_net_descr *descr = card->rx_chain.head;
310 int ret;
311
312 do {
313 if (!descr->skb) {
314 ret = gelic_net_prepare_rx_descr(card, descr);
315 if (ret)
316 goto rewind;
317 }
318 descr = descr->next;
319 } while (descr != card->rx_chain.head);
320
321 return 0;
322rewind:
323 gelic_net_release_rx_chain(card);
324 return ret;
325}
326
327/**
328 * gelic_net_alloc_rx_skbs - allocates rx skbs in rx descriptor chains
329 * @card: card structure
330 *
331 * returns 0 on success, <0 on failure
332 */
333static int gelic_net_alloc_rx_skbs(struct gelic_net_card *card)
334{
335 struct gelic_net_descr_chain *chain;
336 int ret;
337 chain = &card->rx_chain;
338 ret = gelic_net_fill_rx_chain(card);
339 chain->head = card->rx_top->prev; /* point to the last */
340 return ret;
341}
342
343/**
344 * gelic_net_release_tx_descr - processes a used tx descriptor
345 * @card: card structure
346 * @descr: descriptor to release
347 *
348 * releases a used tx descriptor (unmapping, freeing of skb)
349 */
350static void gelic_net_release_tx_descr(struct gelic_net_card *card,
351 struct gelic_net_descr *descr)
352{
353 struct sk_buff *skb;
354
355
356 if (descr->data_status & (1 << GELIC_NET_TXDESC_TAIL)) {
357 /* 2nd descriptor */
358 skb = descr->skb;
359 dma_unmap_single(ctodev(card), descr->buf_addr, skb->len,
360 DMA_TO_DEVICE);
361 dev_kfree_skb_any(skb);
362 } else {
363 dma_unmap_single(ctodev(card), descr->buf_addr,
364 descr->buf_size, DMA_TO_DEVICE);
365 }
366
367 descr->buf_addr = 0;
368 descr->buf_size = 0;
369 descr->next_descr_addr = 0;
370 descr->result_size = 0;
371 descr->valid_size = 0;
372 descr->data_status = 0;
373 descr->data_error = 0;
374 descr->skb = NULL;
375
376 /* set descr status */
377 descr->dmac_cmd_status = GELIC_NET_DMAC_CMDSTAT_NOT_IN_USE;
378}
379
380/**
381 * gelic_net_release_tx_chain - processes sent tx descriptors
382 * @card: adapter structure
383 * @stop: net_stop sequence
384 *
385 * releases the tx descriptors that gelic has finished with
386 */
387static void gelic_net_release_tx_chain(struct gelic_net_card *card, int stop)
388{
389 struct gelic_net_descr_chain *tx_chain;
390 enum gelic_net_descr_status status;
391 int release = 0;
392
393 for (tx_chain = &card->tx_chain;
394 tx_chain->head != tx_chain->tail && tx_chain->tail;
395 tx_chain->tail = tx_chain->tail->next) {
396 status = gelic_net_get_descr_status(tx_chain->tail);
397 switch (status) {
398 case GELIC_NET_DESCR_RESPONSE_ERROR:
399 case GELIC_NET_DESCR_PROTECTION_ERROR:
400 case GELIC_NET_DESCR_FORCE_END:
401 if (printk_ratelimit())
402 dev_info(ctodev(card),
403 "%s: forcing end of tx descriptor " \
404 "with status %x\n",
405 __func__, status);
406 card->netdev_stats.tx_dropped++;
407 break;
408
409 case GELIC_NET_DESCR_COMPLETE:
410 card->netdev_stats.tx_packets++;
411 card->netdev_stats.tx_bytes +=
412 tx_chain->tail->skb->len;
413 break;
414
415 case GELIC_NET_DESCR_CARDOWNED:
416 /* pending tx request */
417 default:
418 /* any other value (== GELIC_NET_DESCR_NOT_IN_USE) */
419 goto out;
420 }
421 gelic_net_release_tx_descr(card, tx_chain->tail);
422 release = 1;
423 }
424out:
425 if (!stop && release)
426 netif_wake_queue(card->netdev);
427}
428
429/**
430 * gelic_net_set_multi - sets multicast addresses and promisc flags
431 * @netdev: interface device structure
432 *
433 * gelic_net_set_multi configures multicast addresses as needed for the
434 * netdev interface. It also sets up multicast, allmulti and promisc
435 * flags appropriately
436 */
437static void gelic_net_set_multi(struct net_device *netdev)
438{
439 struct gelic_net_card *card = netdev_priv(netdev);
440 struct dev_mc_list *mc;
441 unsigned int i;
442 uint8_t *p;
443 u64 addr;
444 int status;
445
446 /* clear all multicast address */
447 status = lv1_net_remove_multicast_address(bus_id(card), dev_id(card),
448 0, 1);
449 if (status)
450 dev_err(ctodev(card),
451 "lv1_net_remove_multicast_address failed %d\n",
452 status);
453 /* set broadcast address */
454 status = lv1_net_add_multicast_address(bus_id(card), dev_id(card),
455 GELIC_NET_BROADCAST_ADDR, 0);
456 if (status)
457 dev_err(ctodev(card),
458 "lv1_net_add_multicast_address failed, %d\n",
459 status);
460
461 if (netdev->flags & IFF_ALLMULTI
462 || netdev->mc_count > GELIC_NET_MC_COUNT_MAX) { /* list max */
463 status = lv1_net_add_multicast_address(bus_id(card),
464 dev_id(card),
465 0, 1);
466 if (status)
467 dev_err(ctodev(card),
468 "lv1_net_add_multicast_address failed, %d\n",
469 status);
470 return;
471 }
472
473 /* set multicast address */
474 for (mc = netdev->mc_list; mc; mc = mc->next) {
475 addr = 0;
476 p = mc->dmi_addr;
477 for (i = 0; i < ETH_ALEN; i++) {
478 addr <<= 8;
479 addr |= *p++;
480 }
481 status = lv1_net_add_multicast_address(bus_id(card),
482 dev_id(card),
483 addr, 0);
484 if (status)
485 dev_err(ctodev(card),
486 "lv1_net_add_multicast_address failed, %d\n",
487 status);
488 }
489}
490
491/**
492 * gelic_net_enable_rxdmac - enables the receive DMA controller
493 * @card: card structure
494 *
495 * gelic_net_enable_rxdmac enables the DMA controller by setting RX_DMA_EN
496 * in the GDADMACCNTR register
497 */
498static inline void gelic_net_enable_rxdmac(struct gelic_net_card *card)
499{
500 int status;
501
502 status = lv1_net_start_rx_dma(bus_id(card), dev_id(card),
503 card->rx_chain.tail->bus_addr, 0);
504 if (status)
505 dev_info(ctodev(card),
506 "lv1_net_start_rx_dma failed, status=%d\n", status);
507}
508
509/**
510 * gelic_net_disable_rxdmac - disables the receive DMA controller
511 * @card: card structure
512 *
513 * gelic_net_disable_rxdmac terminates processing on the DMA controller by
514 * turing off DMA and issueing a force end
515 */
516static inline void gelic_net_disable_rxdmac(struct gelic_net_card *card)
517{
518 int status;
519
520 /* this hvc blocks until the DMA in progress really stopped */
521 status = lv1_net_stop_rx_dma(bus_id(card), dev_id(card), 0);
522 if (status)
523 dev_err(ctodev(card),
524 "lv1_net_stop_rx_dma faild, %d\n", status);
525}
526
527/**
528 * gelic_net_disable_txdmac - disables the transmit DMA controller
529 * @card: card structure
530 *
531 * gelic_net_disable_txdmac terminates processing on the DMA controller by
532 * turing off DMA and issueing a force end
533 */
534static inline void gelic_net_disable_txdmac(struct gelic_net_card *card)
535{
536 int status;
537
538 /* this hvc blocks until the DMA in progress really stopped */
539 status = lv1_net_stop_tx_dma(bus_id(card), dev_id(card), 0);
540 if (status)
541 dev_err(ctodev(card),
542 "lv1_net_stop_tx_dma faild, status=%d\n", status);
543}
544
545/**
546 * gelic_net_stop - called upon ifconfig down
547 * @netdev: interface device structure
548 *
549 * always returns 0
550 */
551static int gelic_net_stop(struct net_device *netdev)
552{
553 struct gelic_net_card *card = netdev_priv(netdev);
554
555 netif_poll_disable(netdev);
556 netif_stop_queue(netdev);
557
558 /* turn off DMA, force end */
559 gelic_net_disable_rxdmac(card);
560 gelic_net_disable_txdmac(card);
561
562 gelic_net_set_irq_mask(card, 0);
563
564 /* disconnect event port */
565 free_irq(card->netdev->irq, card->netdev);
566 ps3_sb_event_receive_port_destroy(card->dev, card->netdev->irq);
567 card->netdev->irq = NO_IRQ;
568
569 netif_carrier_off(netdev);
570
571 /* release chains */
572 gelic_net_release_tx_chain(card, 1);
573 gelic_net_release_rx_chain(card);
574
575 gelic_net_free_chain(card, card->tx_top);
576 gelic_net_free_chain(card, card->rx_top);
577
578 return 0;
579}
580
581/**
582 * gelic_net_get_next_tx_descr - returns the next available tx descriptor
583 * @card: device structure to get descriptor from
584 *
585 * returns the address of the next descriptor, or NULL if not available.
586 */
587static struct gelic_net_descr *
588gelic_net_get_next_tx_descr(struct gelic_net_card *card)
589{
590 if (!card->tx_chain.head)
591 return NULL;
592 /* see if we can two consecutive free descrs */
593 if (card->tx_chain.tail != card->tx_chain.head->next &&
594 gelic_net_get_descr_status(card->tx_chain.head) ==
595 GELIC_NET_DESCR_NOT_IN_USE &&
596 card->tx_chain.tail != card->tx_chain.head->next->next &&
597 gelic_net_get_descr_status(card->tx_chain.head->next) ==
598 GELIC_NET_DESCR_NOT_IN_USE )
599 return card->tx_chain.head;
600 else
601 return NULL;
602
603}
604
605/**
606 * gelic_net_set_txdescr_cmdstat - sets the tx descriptor command field
607 * @descr: descriptor structure to fill out
608 * @skb: packet to consider
609 * @middle: middle of frame
610 *
611 * fills out the command and status field of the descriptor structure,
612 * depending on hardware checksum settings. This function assumes a wmb()
613 * has executed before.
614 */
615static void gelic_net_set_txdescr_cmdstat(struct gelic_net_descr *descr,
616 struct sk_buff *skb, int middle)
617{
618 u32 eofr;
619
620 if (middle)
621 eofr = 0;
622 else
623 eofr = GELIC_NET_DMAC_CMDSTAT_END_FRAME;
624
625 if (skb->ip_summed != CHECKSUM_PARTIAL)
626 descr->dmac_cmd_status = GELIC_NET_DMAC_CMDSTAT_NOCS | eofr;
627 else {
628 /* is packet ip?
629 * if yes: tcp? udp? */
630 if (skb->protocol == htons(ETH_P_IP)) {
631 if (ip_hdr(skb)->protocol == IPPROTO_TCP)
632 descr->dmac_cmd_status =
633 GELIC_NET_DMAC_CMDSTAT_TCPCS | eofr;
634 else if (ip_hdr(skb)->protocol == IPPROTO_UDP)
635 descr->dmac_cmd_status =
636 GELIC_NET_DMAC_CMDSTAT_UDPCS | eofr;
637 else /*
638 * the stack should checksum non-tcp and non-udp
639 * packets on his own: NETIF_F_IP_CSUM
640 */
641 descr->dmac_cmd_status =
642 GELIC_NET_DMAC_CMDSTAT_NOCS | eofr;
643 }
644 }
645}
646
647/**
648 * gelic_net_prepare_tx_descr_v - get dma address of skb_data
649 * @card: card structure
650 * @descr: descriptor structure
651 * @skb: packet to use
652 *
653 * returns 0 on success, <0 on failure.
654 *
655 */
656static int gelic_net_prepare_tx_descr_v(struct gelic_net_card *card,
657 struct gelic_net_descr *descr,
658 struct sk_buff *skb)
659{
660 dma_addr_t buf[2];
661 unsigned int vlan_len;
662
663 if (skb->len < GELIC_NET_VLAN_POS)
664 return -EINVAL;
665
666 memcpy(&descr->vlan, skb->data, GELIC_NET_VLAN_POS);
667 if (card->vlan_index != -1) {
668 descr->vlan.h_vlan_proto = htons(ETH_P_8021Q); /* vlan 0x8100*/
669 descr->vlan.h_vlan_TCI = htons(card->vlan_id[card->vlan_index]);
670 vlan_len = GELIC_NET_VLAN_POS + VLAN_HLEN; /* VLAN_HLEN=4 */
671 } else
672 vlan_len = GELIC_NET_VLAN_POS; /* no vlan tag */
673
674 /* first descr */
675 buf[0] = dma_map_single(ctodev(card), &descr->vlan,
676 vlan_len, DMA_TO_DEVICE);
677
678 if (!buf[0]) {
679 dev_err(ctodev(card),
680 "dma map 1 failed (%p, %i). Dropping packet\n",
681 skb->data, vlan_len);
682 return -ENOMEM;
683 }
684
685 descr->buf_addr = buf[0];
686 descr->buf_size = vlan_len;
687 descr->skb = skb; /* not used */
688 descr->data_status = 0;
689 gelic_net_set_txdescr_cmdstat(descr, skb, 1); /* not the frame end */
690
691 /* second descr */
692 card->tx_chain.head = card->tx_chain.head->next;
693 descr->next_descr_addr = descr->next->bus_addr;
694 descr = descr->next;
695 if (gelic_net_get_descr_status(descr) != GELIC_NET_DESCR_NOT_IN_USE)
696 /* XXX will be removed */
697 dev_err(ctodev(card), "descr is not free!\n");
698
699 buf[1] = dma_map_single(ctodev(card), skb->data + GELIC_NET_VLAN_POS,
700 skb->len - GELIC_NET_VLAN_POS,
701 DMA_TO_DEVICE);
702
703 if (!buf[1]) {
704 dev_err(ctodev(card),
705 "dma map 2 failed (%p, %i). Dropping packet\n",
706 skb->data + GELIC_NET_VLAN_POS,
707 skb->len - GELIC_NET_VLAN_POS);
708 dma_unmap_single(ctodev(card), buf[0], vlan_len,
709 DMA_TO_DEVICE);
710 return -ENOMEM;
711 }
712
713 descr->buf_addr = buf[1];
714 descr->buf_size = skb->len - GELIC_NET_VLAN_POS;
715 descr->skb = skb;
716 descr->data_status = 0;
717 descr->next_descr_addr = 0; /* terminate hw descr */
718 gelic_net_set_txdescr_cmdstat(descr, skb, 0);
719
720 return 0;
721}
722
723/**
724 * gelic_net_kick_txdma - enables TX DMA processing
725 * @card: card structure
726 * @descr: descriptor address to enable TX processing at
727 *
728 */
729static int gelic_net_kick_txdma(struct gelic_net_card *card,
730 struct gelic_net_descr *descr)
731{
732 int status = -ENXIO;
733 int count = 10;
734
735 if (card->tx_dma_progress)
736 return 0;
737
738 if (gelic_net_get_descr_status(descr) == GELIC_NET_DESCR_CARDOWNED) {
739 card->tx_dma_progress = 1;
740 /* sometimes we need retry here */
741 while (count--) {
742 status = lv1_net_start_tx_dma(bus_id(card),
743 dev_id(card),
744 descr->bus_addr, 0);
745 if (!status)
746 break;
747 }
748 if (!count)
749 dev_info(ctodev(card), "lv1_net_start_txdma failed," \
750 "status=%d %#lx\n",
751 status, card->irq_status);
752 }
753 return status;
754}
755
756/**
757 * gelic_net_xmit - transmits a frame over the device
758 * @skb: packet to send out
759 * @netdev: interface device structure
760 *
761 * returns 0 on success, <0 on failure
762 */
763static int gelic_net_xmit(struct sk_buff *skb, struct net_device *netdev)
764{
765 struct gelic_net_card *card = netdev_priv(netdev);
766 struct gelic_net_descr *descr = NULL;
767 int result;
768 unsigned long flags;
769
770 spin_lock_irqsave(&card->tx_dma_lock, flags);
771
772 gelic_net_release_tx_chain(card, 0);
773 if (!skb)
774 goto kick;
775 descr = gelic_net_get_next_tx_descr(card);
776 if (!descr) {
777 netif_stop_queue(netdev);
778 spin_unlock_irqrestore(&card->tx_dma_lock, flags);
779 return NETDEV_TX_BUSY;
780 }
781 result = gelic_net_prepare_tx_descr_v(card, descr, skb);
782
783 if (result)
784 goto error;
785
786 card->tx_chain.head = card->tx_chain.head->next;
787
788 if (descr->prev)
789 descr->prev->next_descr_addr = descr->bus_addr;
790kick:
791 /*
792 * as hardware descriptor is modified in the above lines,
793 * ensure that the hardware sees it
794 */
795 wmb();
796 if (gelic_net_kick_txdma(card, card->tx_chain.tail))
797 goto error;
798
799 netdev->trans_start = jiffies;
800 spin_unlock_irqrestore(&card->tx_dma_lock, flags);
801 return NETDEV_TX_OK;
802
803error:
804 card->netdev_stats.tx_dropped++;
805 spin_unlock_irqrestore(&card->tx_dma_lock, flags);
806 return NETDEV_TX_LOCKED;
807}
808
809/**
810 * gelic_net_pass_skb_up - takes an skb from a descriptor and passes it on
811 * @descr: descriptor to process
812 * @card: card structure
813 *
814 * iommu-unmaps the skb, fills out skb structure and passes the data to the
815 * stack. The descriptor state is not changed.
816 */
817static void gelic_net_pass_skb_up(struct gelic_net_descr *descr,
818 struct gelic_net_card *card)
819{
820 struct sk_buff *skb;
821 struct net_device *netdev;
822 u32 data_status, data_error;
823
824 data_status = descr->data_status;
825 data_error = descr->data_error;
826 netdev = card->netdev;
827 /* unmap skb buffer */
828 skb = descr->skb;
829 dma_unmap_single(ctodev(card), descr->buf_addr, GELIC_NET_MAX_MTU,
830 DMA_FROM_DEVICE);
831
832 skb_put(skb, descr->valid_size? descr->valid_size : descr->result_size);
833 if (!descr->valid_size)
834 dev_info(ctodev(card), "buffer full %x %x %x\n",
835 descr->result_size, descr->buf_size,
836 descr->dmac_cmd_status);
837
838 descr->skb = NULL;
839 /*
840 * the card put 2 bytes vlan tag in front
841 * of the ethernet frame
842 */
843 skb_pull(skb, 2);
844 skb->protocol = eth_type_trans(skb, netdev);
845
846 /* checksum offload */
847 if (card->rx_csum) {
848 if ((data_status & GELIC_NET_DATA_STATUS_CHK_MASK) &&
849 (!(data_error & GELIC_NET_DATA_ERROR_CHK_MASK)))
850 skb->ip_summed = CHECKSUM_UNNECESSARY;
851 else
852 skb->ip_summed = CHECKSUM_NONE;
853 } else
854 skb->ip_summed = CHECKSUM_NONE;
855
856 /* update netdevice statistics */
857 card->netdev_stats.rx_packets++;
858 card->netdev_stats.rx_bytes += skb->len;
859
860 /* pass skb up to stack */
861 netif_receive_skb(skb);
862}
863
864/**
865 * gelic_net_decode_one_descr - processes an rx descriptor
866 * @card: card structure
867 *
868 * returns 1 if a packet has been sent to the stack, otherwise 0
869 *
870 * processes an rx descriptor by iommu-unmapping the data buffer and passing
871 * the packet up to the stack
872 */
873static int gelic_net_decode_one_descr(struct gelic_net_card *card)
874{
875 enum gelic_net_descr_status status;
876 struct gelic_net_descr_chain *chain = &card->rx_chain;
877 struct gelic_net_descr *descr = chain->tail;
878 int dmac_chain_ended;
879
880 status = gelic_net_get_descr_status(descr);
881 /* is this descriptor terminated with next_descr == NULL? */
882 dmac_chain_ended =
883 descr->dmac_cmd_status & GELIC_NET_DMAC_CMDSTAT_RXDCEIS;
884
885 if (status == GELIC_NET_DESCR_CARDOWNED)
886 return 0;
887
888 if (status == GELIC_NET_DESCR_NOT_IN_USE) {
889 dev_dbg(ctodev(card), "dormant descr? %p\n", descr);
890 return 0;
891 }
892
893 if ((status == GELIC_NET_DESCR_RESPONSE_ERROR) ||
894 (status == GELIC_NET_DESCR_PROTECTION_ERROR) ||
895 (status == GELIC_NET_DESCR_FORCE_END)) {
896 dev_info(ctodev(card), "dropping RX descriptor with state %x\n",
897 status);
898 card->netdev_stats.rx_dropped++;
899 goto refill;
900 }
901
902 if ((status != GELIC_NET_DESCR_COMPLETE) &&
903 (status != GELIC_NET_DESCR_FRAME_END)) {
904 dev_dbg(ctodev(card), "RX descriptor with state %x\n",
905 status);
906 goto refill;
907 }
908
909 /* ok, we've got a packet in descr */
910 gelic_net_pass_skb_up(descr, card); /* 1: skb_up sccess */
911
912refill:
913 descr->next_descr_addr = 0; /* unlink the descr */
914
915 /* change the descriptor state: */
916 gelic_net_set_descr_status(descr, GELIC_NET_DESCR_NOT_IN_USE);
917
918 /* refill one desc
919 * FIXME: this can fail, but for now, just leave this
920 * descriptor without skb
921 */
922 gelic_net_prepare_rx_descr(card, descr);
923 chain->head = descr;
924 chain->tail = descr->next;
925 descr->prev->next_descr_addr = descr->bus_addr;
926
927 if (dmac_chain_ended) {
928 gelic_net_enable_rxdmac(card);
929 dev_dbg(ctodev(card), "reenable rx dma\n");
930 }
931
932 return 1;
933}
934
935/**
936 * gelic_net_poll - NAPI poll function called by the stack to return packets
937 * @netdev: interface device structure
938 * @budget: number of packets we can pass to the stack at most
939 *
940 * returns 0 if no more packets available to the driver/stack. Returns 1,
941 * if the quota is exceeded, but the driver has still packets.
942 *
943 */
944static int gelic_net_poll(struct net_device *netdev, int *budget)
945{
946 struct gelic_net_card *card = netdev_priv(netdev);
947 int packets_to_do, packets_done = 0;
948 int no_more_packets = 0;
949
950 packets_to_do = min(*budget, netdev->quota);
951
952 while (packets_to_do) {
953 if (gelic_net_decode_one_descr(card)) {
954 packets_done++;
955 packets_to_do--;
956 } else {
957 /* no more packets for the stack */
958 no_more_packets = 1;
959 break;
960 }
961 }
962 netdev->quota -= packets_done;
963 *budget -= packets_done;
964 if (no_more_packets) {
965 netif_rx_complete(netdev);
966 gelic_net_rx_irq_on(card);
967 return 0;
968 } else
969 return 1;
970}
971
972/**
973 * gelic_net_get_stats - get interface statistics
974 * @netdev: interface device structure
975 *
976 * returns the interface statistics residing in the gelic_net_card struct
977 */
978static struct net_device_stats *gelic_net_get_stats(struct net_device *netdev)
979{
980 struct gelic_net_card *card = netdev_priv(netdev);
981
982 return &card->netdev_stats;
983}
984
985/**
986 * gelic_net_change_mtu - changes the MTU of an interface
987 * @netdev: interface device structure
988 * @new_mtu: new MTU value
989 *
990 * returns 0 on success, <0 on failure
991 */
992static int gelic_net_change_mtu(struct net_device *netdev, int new_mtu)
993{
994 /* no need to re-alloc skbs or so -- the max mtu is about 2.3k
995 * and mtu is outbound only anyway */
996 if ((new_mtu < GELIC_NET_MIN_MTU) ||
997 (new_mtu > GELIC_NET_MAX_MTU)) {
998 return -EINVAL;
999 }
1000 netdev->mtu = new_mtu;
1001 return 0;
1002}
1003
1004/**
1005 * gelic_net_interrupt - event handler for gelic_net
1006 */
1007static irqreturn_t gelic_net_interrupt(int irq, void *ptr)
1008{
1009 unsigned long flags;
1010 struct net_device *netdev = ptr;
1011 struct gelic_net_card *card = netdev_priv(netdev);
1012 u64 status;
1013
1014 status = card->irq_status;
1015
1016 if (!status)
1017 return IRQ_NONE;
1018
1019 if (status & GELIC_NET_RXINT) {
1020 gelic_net_rx_irq_off(card);
1021 netif_rx_schedule(netdev);
1022 }
1023
1024 if (status & GELIC_NET_TXINT) {
1025 spin_lock_irqsave(&card->tx_dma_lock, flags);
1026 card->tx_dma_progress = 0;
1027 spin_unlock_irqrestore(&card->tx_dma_lock, flags);
1028 /* start pending DMA */
1029 gelic_net_xmit(NULL, netdev);
1030 }
1031 return IRQ_HANDLED;
1032}
1033
1034#ifdef CONFIG_NET_POLL_CONTROLLER
1035/**
1036 * gelic_net_poll_controller - artificial interrupt for netconsole etc.
1037 * @netdev: interface device structure
1038 *
1039 * see Documentation/networking/netconsole.txt
1040 */
1041static void gelic_net_poll_controller(struct net_device *netdev)
1042{
1043 struct gelic_net_card *card = netdev_priv(netdev);
1044
1045 gelic_net_set_irq_mask(card, 0);
1046 gelic_net_interrupt(netdev->irq, netdev);
1047 gelic_net_set_irq_mask(card, card->ghiintmask);
1048}
1049#endif /* CONFIG_NET_POLL_CONTROLLER */
1050
1051/**
1052 * gelic_net_open_device - open device and map dma region
1053 * @card: card structure
1054 */
1055static int gelic_net_open_device(struct gelic_net_card *card)
1056{
1057 int result;
1058
1059 result = ps3_sb_event_receive_port_setup(card->dev, PS3_BINDING_CPU_ANY,
1060 &card->netdev->irq);
1061
1062 if (result) {
1063 dev_info(ctodev(card),
1064 "%s:%d: gelic_net_open_device failed (%d)\n",
1065 __func__, __LINE__, result);
1066 result = -EPERM;
1067 goto fail_alloc_irq;
1068 }
1069
1070 result = request_irq(card->netdev->irq, gelic_net_interrupt,
1071 IRQF_DISABLED, "gelic network", card->netdev);
1072
1073 if (result) {
1074 dev_info(ctodev(card), "%s:%d: request_irq failed (%d)\n",
1075 __func__, __LINE__, result);
1076 goto fail_request_irq;
1077 }
1078
1079 return 0;
1080
1081fail_request_irq:
1082 ps3_sb_event_receive_port_destroy(card->dev, card->netdev->irq);
1083 card->netdev->irq = NO_IRQ;
1084fail_alloc_irq:
1085 return result;
1086}
1087
1088
1089/**
1090 * gelic_net_open - called upon ifonfig up
1091 * @netdev: interface device structure
1092 *
1093 * returns 0 on success, <0 on failure
1094 *
1095 * gelic_net_open allocates all the descriptors and memory needed for
1096 * operation, sets up multicast list and enables interrupts
1097 */
1098static int gelic_net_open(struct net_device *netdev)
1099{
1100 struct gelic_net_card *card = netdev_priv(netdev);
1101
1102 dev_dbg(ctodev(card), " -> %s:%d\n", __func__, __LINE__);
1103
1104 gelic_net_open_device(card);
1105
1106 if (gelic_net_init_chain(card, &card->tx_chain,
1107 card->descr, GELIC_NET_TX_DESCRIPTORS))
1108 goto alloc_tx_failed;
1109 if (gelic_net_init_chain(card, &card->rx_chain,
1110 card->descr + GELIC_NET_RX_DESCRIPTORS,
1111 GELIC_NET_RX_DESCRIPTORS))
1112 goto alloc_rx_failed;
1113
1114 /* head of chain */
1115 card->tx_top = card->tx_chain.head;
1116 card->rx_top = card->rx_chain.head;
1117 dev_dbg(ctodev(card), "descr rx %p, tx %p, size %#lx, num %#x\n",
1118 card->rx_top, card->tx_top, sizeof(struct gelic_net_descr),
1119 GELIC_NET_RX_DESCRIPTORS);
1120 /* allocate rx skbs */
1121 if (gelic_net_alloc_rx_skbs(card))
1122 goto alloc_skbs_failed;
1123
1124 card->tx_dma_progress = 0;
1125 card->ghiintmask = GELIC_NET_RXINT | GELIC_NET_TXINT;
1126
1127 gelic_net_set_irq_mask(card, card->ghiintmask);
1128 gelic_net_enable_rxdmac(card);
1129
1130 netif_start_queue(netdev);
1131 netif_carrier_on(netdev);
1132 netif_poll_enable(netdev);
1133
1134 return 0;
1135
1136alloc_skbs_failed:
1137 gelic_net_free_chain(card, card->rx_top);
1138alloc_rx_failed:
1139 gelic_net_free_chain(card, card->tx_top);
1140alloc_tx_failed:
1141 return -ENOMEM;
1142}
1143
1144#ifdef GELIC_NET_ETHTOOL
1145static void gelic_net_get_drvinfo (struct net_device *netdev,
1146 struct ethtool_drvinfo *info)
1147{
1148 strncpy(info->driver, DRV_NAME, sizeof(info->driver) - 1);
1149 strncpy(info->version, DRV_VERSION, sizeof(info->version) - 1);
1150}
1151
1152static int gelic_net_get_settings(struct net_device *netdev,
1153 struct ethtool_cmd *cmd)
1154{
1155 struct gelic_net_card *card = netdev_priv(netdev);
1156 int status;
1157 u64 v1, v2;
1158 int speed, duplex;
1159
1160 speed = duplex = -1;
1161 status = lv1_net_control(bus_id(card), dev_id(card),
1162 GELIC_NET_GET_ETH_PORT_STATUS, GELIC_NET_PORT, 0, 0,
1163 &v1, &v2);
1164 if (status) {
1165 /* link down */
1166 } else {
1167 if (v1 & GELIC_NET_FULL_DUPLEX) {
1168 duplex = DUPLEX_FULL;
1169 } else {
1170 duplex = DUPLEX_HALF;
1171 }
1172
1173 if (v1 & GELIC_NET_SPEED_10 ) {
1174 speed = SPEED_10;
1175 } else if (v1 & GELIC_NET_SPEED_100) {
1176 speed = SPEED_100;
1177 } else if (v1 & GELIC_NET_SPEED_1000) {
1178 speed = SPEED_1000;
1179 }
1180 }
1181 cmd->supported = SUPPORTED_TP | SUPPORTED_Autoneg |
1182 SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full |
1183 SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full |
1184 SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full;
1185 cmd->advertising = cmd->supported;
1186 cmd->speed = speed;
1187 cmd->duplex = duplex;
1188 cmd->autoneg = AUTONEG_ENABLE; /* always enabled */
1189 cmd->port = PORT_TP;
1190
1191 return 0;
1192}
1193
1194static u32 gelic_net_get_link(struct net_device *netdev)
1195{
1196 struct gelic_net_card *card = netdev_priv(netdev);
1197 int status;
1198 u64 v1, v2;
1199 int link;
1200
1201 status = lv1_net_control(bus_id(card), dev_id(card),
1202 GELIC_NET_GET_ETH_PORT_STATUS, GELIC_NET_PORT, 0, 0,
1203 &v1, &v2);
1204 if (status)
1205 return 0; /* link down */
1206
1207 if (v1 & GELIC_NET_LINK_UP)
1208 link = 1;
1209 else
1210 link = 0;
1211
1212 return link;
1213}
1214
1215static int gelic_net_nway_reset(struct net_device *netdev)
1216{
1217 if (netif_running(netdev)) {
1218 gelic_net_stop(netdev);
1219 gelic_net_open(netdev);
1220 }
1221 return 0;
1222}
1223
1224static u32 gelic_net_get_tx_csum(struct net_device *netdev)
1225{
1226 return (netdev->features & NETIF_F_IP_CSUM) != 0;
1227}
1228
1229static int gelic_net_set_tx_csum(struct net_device *netdev, u32 data)
1230{
1231 if (data)
1232 netdev->features |= NETIF_F_IP_CSUM;
1233 else
1234 netdev->features &= ~NETIF_F_IP_CSUM;
1235
1236 return 0;
1237}
1238
1239static u32 gelic_net_get_rx_csum(struct net_device *netdev)
1240{
1241 struct gelic_net_card *card = netdev_priv(netdev);
1242
1243 return card->rx_csum;
1244}
1245
1246static int gelic_net_set_rx_csum(struct net_device *netdev, u32 data)
1247{
1248 struct gelic_net_card *card = netdev_priv(netdev);
1249
1250 card->rx_csum = data;
1251 return 0;
1252}
1253
1254static struct ethtool_ops gelic_net_ethtool_ops = {
1255 .get_drvinfo = gelic_net_get_drvinfo,
1256 .get_settings = gelic_net_get_settings,
1257 .get_link = gelic_net_get_link,
1258 .nway_reset = gelic_net_nway_reset,
1259 .get_tx_csum = gelic_net_get_tx_csum,
1260 .set_tx_csum = gelic_net_set_tx_csum,
1261 .get_rx_csum = gelic_net_get_rx_csum,
1262 .set_rx_csum = gelic_net_set_rx_csum,
1263};
1264#endif
1265
1266/**
1267 * gelic_net_tx_timeout_task - task scheduled by the watchdog timeout
1268 * function (to be called not under interrupt status)
1269 * @work: work is context of tx timout task
1270 *
1271 * called as task when tx hangs, resets interface (if interface is up)
1272 */
1273static void gelic_net_tx_timeout_task(struct work_struct *work)
1274{
1275 struct gelic_net_card *card =
1276 container_of(work, struct gelic_net_card, tx_timeout_task);
1277 struct net_device *netdev = card->netdev;
1278
1279 dev_info(ctodev(card), "%s:Timed out. Restarting... \n", __func__);
1280
1281 if (!(netdev->flags & IFF_UP))
1282 goto out;
1283
1284 netif_device_detach(netdev);
1285 gelic_net_stop(netdev);
1286
1287 gelic_net_open(netdev);
1288 netif_device_attach(netdev);
1289
1290out:
1291 atomic_dec(&card->tx_timeout_task_counter);
1292}
1293
1294/**
1295 * gelic_net_tx_timeout - called when the tx timeout watchdog kicks in.
1296 * @netdev: interface device structure
1297 *
1298 * called, if tx hangs. Schedules a task that resets the interface
1299 */
1300static void gelic_net_tx_timeout(struct net_device *netdev)
1301{
1302 struct gelic_net_card *card;
1303
1304 card = netdev_priv(netdev);
1305 atomic_inc(&card->tx_timeout_task_counter);
1306 if (netdev->flags & IFF_UP)
1307 schedule_work(&card->tx_timeout_task);
1308 else
1309 atomic_dec(&card->tx_timeout_task_counter);
1310}
1311
1312/**
1313 * gelic_net_setup_netdev_ops - initialization of net_device operations
1314 * @netdev: net_device structure
1315 *
1316 * fills out function pointers in the net_device structure
1317 */
1318static void gelic_net_setup_netdev_ops(struct net_device *netdev)
1319{
1320 netdev->open = &gelic_net_open;
1321 netdev->stop = &gelic_net_stop;
1322 netdev->hard_start_xmit = &gelic_net_xmit;
1323 netdev->get_stats = &gelic_net_get_stats;
1324 netdev->set_multicast_list = &gelic_net_set_multi;
1325 netdev->change_mtu = &gelic_net_change_mtu;
1326 /* tx watchdog */
1327 netdev->tx_timeout = &gelic_net_tx_timeout;
1328 netdev->watchdog_timeo = GELIC_NET_WATCHDOG_TIMEOUT;
1329 /* NAPI */
1330 netdev->poll = &gelic_net_poll;
1331 netdev->weight = GELIC_NET_NAPI_WEIGHT;
1332#ifdef GELIC_NET_ETHTOOL
1333 netdev->ethtool_ops = &gelic_net_ethtool_ops;
1334#endif
1335}
1336
1337/**
1338 * gelic_net_setup_netdev - initialization of net_device
1339 * @card: card structure
1340 *
1341 * Returns 0 on success or <0 on failure
1342 *
1343 * gelic_net_setup_netdev initializes the net_device structure
1344 **/
1345static int gelic_net_setup_netdev(struct gelic_net_card *card)
1346{
1347 struct net_device *netdev = card->netdev;
1348 struct sockaddr addr;
1349 unsigned int i;
1350 int status;
1351 u64 v1, v2;
1352
1353 SET_MODULE_OWNER(netdev);
1354 SET_NETDEV_DEV(netdev, &card->dev->core);
1355 spin_lock_init(&card->tx_dma_lock);
1356
1357 card->rx_csum = GELIC_NET_RX_CSUM_DEFAULT;
1358
1359 gelic_net_setup_netdev_ops(netdev);
1360
1361 netdev->features = NETIF_F_IP_CSUM;
1362
1363 status = lv1_net_control(bus_id(card), dev_id(card),
1364 GELIC_NET_GET_MAC_ADDRESS,
1365 0, 0, 0, &v1, &v2);
1366 if (status || !is_valid_ether_addr((u8 *)&v1)) {
1367 dev_info(ctodev(card),
1368 "%s:lv1_net_control GET_MAC_ADDR failed %d\n",
1369 __func__, status);
1370 return -EINVAL;
1371 }
1372 v1 <<= 16;
1373 memcpy(addr.sa_data, &v1, ETH_ALEN);
1374 memcpy(netdev->dev_addr, addr.sa_data, ETH_ALEN);
1375 dev_info(ctodev(card), "MAC addr %02x:%02x:%02x:%02x:%02x:%02x\n",
1376 netdev->dev_addr[0], netdev->dev_addr[1],
1377 netdev->dev_addr[2], netdev->dev_addr[3],
1378 netdev->dev_addr[4], netdev->dev_addr[5]);
1379
1380 card->vlan_index = -1; /* no vlan */
1381 for (i = 0; i < GELIC_NET_VLAN_MAX; i++) {
1382 status = lv1_net_control(bus_id(card), dev_id(card),
1383 GELIC_NET_GET_VLAN_ID,
1384 i + 1, /* index; one based */
1385 0, 0, &v1, &v2);
1386 if (status == GELIC_NET_VLAN_NO_ENTRY) {
1387 dev_dbg(ctodev(card),
1388 "GELIC_VLAN_ID no entry:%d, VLAN disabled\n",
1389 status);
1390 card->vlan_id[i] = 0;
1391 } else if (status) {
1392 dev_dbg(ctodev(card),
1393 "%s:GELIC_NET_VLAN_ID faild, status=%d\n",
1394 __func__, status);
1395 card->vlan_id[i] = 0;
1396 } else {
1397 card->vlan_id[i] = (u32)v1;
1398 dev_dbg(ctodev(card), "vlan_id:%d, %lx\n", i, v1);
1399 }
1400 }
1401 if (card->vlan_id[GELIC_NET_VLAN_WIRED - 1])
1402 card->vlan_index = GELIC_NET_VLAN_WIRED - 1;
1403
1404 status = register_netdev(netdev);
1405 if (status) {
1406 dev_err(ctodev(card), "%s:Couldn't register net_device: %d\n",
1407 __func__, status);
1408 return status;
1409 }
1410
1411 return 0;
1412}
1413
1414/**
1415 * gelic_net_alloc_card - allocates net_device and card structure
1416 *
1417 * returns the card structure or NULL in case of errors
1418 *
1419 * the card and net_device structures are linked to each other
1420 */
1421static struct gelic_net_card *gelic_net_alloc_card(void)
1422{
1423 struct net_device *netdev;
1424 struct gelic_net_card *card;
1425 size_t alloc_size;
1426
1427 alloc_size = sizeof (*card) +
1428 sizeof (struct gelic_net_descr) * GELIC_NET_RX_DESCRIPTORS +
1429 sizeof (struct gelic_net_descr) * GELIC_NET_TX_DESCRIPTORS;
1430 /*
1431 * we assume private data is allocated 32 bytes (or more) aligned
1432 * so that gelic_net_descr should be 32 bytes aligned.
1433 * Current alloc_etherdev() does do it because NETDEV_ALIGN
1434 * is 32.
1435 * check this assumption here.
1436 */
1437 BUILD_BUG_ON(NETDEV_ALIGN < 32);
1438 BUILD_BUG_ON(offsetof(struct gelic_net_card, irq_status) % 8);
1439 BUILD_BUG_ON(offsetof(struct gelic_net_card, descr) % 32);
1440
1441 netdev = alloc_etherdev(alloc_size);
1442 if (!netdev)
1443 return NULL;
1444
1445 card = netdev_priv(netdev);
1446 card->netdev = netdev;
1447 INIT_WORK(&card->tx_timeout_task, gelic_net_tx_timeout_task);
1448 init_waitqueue_head(&card->waitq);
1449 atomic_set(&card->tx_timeout_task_counter, 0);
1450
1451 return card;
1452}
1453
1454/**
1455 * ps3_gelic_driver_probe - add a device to the control of this driver
1456 */
1457static int ps3_gelic_driver_probe (struct ps3_system_bus_device *dev)
1458{
1459 struct gelic_net_card *card = gelic_net_alloc_card();
1460 int result;
1461
1462 if (!card) {
1463 dev_info(&dev->core, "gelic_net_alloc_card failed\n");
1464 result = -ENOMEM;
1465 goto fail_alloc_card;
1466 }
1467
1468 ps3_system_bus_set_driver_data(dev, card);
1469 card->dev = dev;
1470
1471 result = ps3_open_hv_device(dev);
1472
1473 if (result) {
1474 dev_dbg(&dev->core, "ps3_open_hv_device failed\n");
1475 goto fail_open;
1476 }
1477
1478 result = ps3_dma_region_create(dev->d_region);
1479
1480 if (result) {
1481 dev_dbg(&dev->core, "ps3_dma_region_create failed(%d)\n",
1482 result);
1483 BUG_ON("check region type");
1484 goto fail_dma_region;
1485 }
1486
1487 result = lv1_net_set_interrupt_status_indicator(bus_id(card),
1488 dev_id(card),
1489 ps3_mm_phys_to_lpar(__pa(&card->irq_status)),
1490 0);
1491
1492 if (result) {
1493 dev_dbg(&dev->core,
1494 "lv1_net_set_interrupt_status_indicator failed: %s\n",
1495 ps3_result(result));
1496 result = -EIO;
1497 goto fail_status_indicator;
1498 }
1499
1500 result = gelic_net_setup_netdev(card);
1501
1502 if (result) {
1503 dev_dbg(&dev->core, "%s:%d: ps3_dma_region_create failed: "
1504 "(%d)\n", __func__, __LINE__, result);
1505 goto fail_setup_netdev;
1506 }
1507
1508 return 0;
1509
1510fail_setup_netdev:
1511 lv1_net_set_interrupt_status_indicator(bus_id(card),
1512 bus_id(card),
1513 0 , 0);
1514fail_status_indicator:
1515 ps3_dma_region_free(dev->d_region);
1516fail_dma_region:
1517 ps3_close_hv_device(dev);
1518fail_open:
1519 ps3_system_bus_set_driver_data(dev, NULL);
1520 free_netdev(card->netdev);
1521fail_alloc_card:
1522 return result;
1523}
1524
1525/**
1526 * ps3_gelic_driver_remove - remove a device from the control of this driver
1527 */
1528
1529static int ps3_gelic_driver_remove (struct ps3_system_bus_device *dev)
1530{
1531 struct gelic_net_card *card = ps3_system_bus_get_driver_data(dev);
1532
1533 wait_event(card->waitq,
1534 atomic_read(&card->tx_timeout_task_counter) == 0);
1535
1536 lv1_net_set_interrupt_status_indicator(bus_id(card), dev_id(card),
1537 0 , 0);
1538
1539 unregister_netdev(card->netdev);
1540 free_netdev(card->netdev);
1541
1542 ps3_system_bus_set_driver_data(dev, NULL);
1543
1544 ps3_dma_region_free(dev->d_region);
1545
1546 ps3_close_hv_device(dev);
1547
1548 return 0;
1549}
1550
1551static struct ps3_system_bus_driver ps3_gelic_driver = {
1552 .match_id = PS3_MATCH_ID_GELIC,
1553 .probe = ps3_gelic_driver_probe,
1554 .remove = ps3_gelic_driver_remove,
1555 .shutdown = ps3_gelic_driver_remove,
1556 .core.name = "ps3_gelic_driver",
1557 .core.owner = THIS_MODULE,
1558};
1559
1560static int __init ps3_gelic_driver_init (void)
1561{
1562 return firmware_has_feature(FW_FEATURE_PS3_LV1)
1563 ? ps3_system_bus_driver_register(&ps3_gelic_driver)
1564 : -ENODEV;
1565}
1566
1567static void __exit ps3_gelic_driver_exit (void)
1568{
1569 ps3_system_bus_driver_unregister(&ps3_gelic_driver);
1570}
1571
1572module_init (ps3_gelic_driver_init);
1573module_exit (ps3_gelic_driver_exit);
1574
1575MODULE_ALIAS(PS3_MODULE_ALIAS_GELIC);
1576
diff --git a/drivers/net/ps3_gelic_net.h b/drivers/net/ps3_gelic_net.h
new file mode 100644
index 000000000000..5e1c28654e16
--- /dev/null
+++ b/drivers/net/ps3_gelic_net.h
@@ -0,0 +1,239 @@
1/*
2 * PS3 Platfom gelic network driver.
3 *
4 * Copyright (C) 2007 Sony Computer Entertainment Inc.
5 * Copyright 2006, 2007 Sony Corporation.
6 *
7 * This file is based on: spider_net.h
8 *
9 * (C) Copyright IBM Corp. 2005
10 *
11 * Authors : Utz Bacher <utz.bacher@de.ibm.com>
12 * Jens Osterkamp <Jens.Osterkamp@de.ibm.com>
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2, or (at your option)
17 * any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 */
28#ifndef _GELIC_NET_H
29#define _GELIC_NET_H
30
31#define GELIC_NET_DRV_NAME "Gelic Network Driver"
32#define GELIC_NET_DRV_VERSION "1.0"
33
34#define GELIC_NET_ETHTOOL /* use ethtool */
35
36/* ioctl */
37#define GELIC_NET_GET_MODE (SIOCDEVPRIVATE + 0)
38#define GELIC_NET_SET_MODE (SIOCDEVPRIVATE + 1)
39
40/* descriptors */
41#define GELIC_NET_RX_DESCRIPTORS 128 /* num of descriptors */
42#define GELIC_NET_TX_DESCRIPTORS 128 /* num of descriptors */
43
44#define GELIC_NET_MAX_MTU 2308
45#define GELIC_NET_MIN_MTU 64
46#define GELIC_NET_RXBUF_ALIGN 128
47#define GELIC_NET_RX_CSUM_DEFAULT 1 /* hw chksum */
48#define GELIC_NET_WATCHDOG_TIMEOUT 5*HZ
49#define GELIC_NET_NAPI_WEIGHT (GELIC_NET_RX_DESCRIPTORS)
50#define GELIC_NET_BROADCAST_ADDR 0xffffffffffffL
51#define GELIC_NET_VLAN_POS (VLAN_ETH_ALEN * 2)
52#define GELIC_NET_VLAN_MAX 4
53#define GELIC_NET_MC_COUNT_MAX 32 /* multicast address list */
54
55enum gelic_net_int0_status {
56 GELIC_NET_GDTDCEINT = 24,
57 GELIC_NET_GRFANMINT = 28,
58};
59
60/* GHIINT1STS bits */
61enum gelic_net_int1_status {
62 GELIC_NET_GDADCEINT = 14,
63};
64
65/* interrupt mask */
66#define GELIC_NET_TXINT (1L << (GELIC_NET_GDTDCEINT + 32))
67
68#define GELIC_NET_RXINT0 (1L << (GELIC_NET_GRFANMINT + 32))
69#define GELIC_NET_RXINT1 (1L << GELIC_NET_GDADCEINT)
70#define GELIC_NET_RXINT (GELIC_NET_RXINT0 | GELIC_NET_RXINT1)
71
72 /* RX descriptor data_status bits */
73#define GELIC_NET_RXDMADU 0x80000000 /* destination MAC addr unknown */
74#define GELIC_NET_RXLSTFBF 0x40000000 /* last frame buffer */
75#define GELIC_NET_RXIPCHK 0x20000000 /* IP checksum performed */
76#define GELIC_NET_RXTCPCHK 0x10000000 /* TCP/UDP checksup performed */
77#define GELIC_NET_RXIPSPKT 0x08000000 /* IPsec packet */
78#define GELIC_NET_RXIPSAHPRT 0x04000000 /* IPsec AH protocol performed */
79#define GELIC_NET_RXIPSESPPRT 0x02000000 /* IPsec ESP protocol performed */
80#define GELIC_NET_RXSESPAH 0x01000000 /*
81 * IPsec ESP protocol auth
82 * performed
83 */
84
85#define GELIC_NET_RXWTPKT 0x00C00000 /*
86 * wakeup trigger packet
87 * 01: Magic Packet (TM)
88 * 10: ARP packet
89 * 11: Multicast MAC addr
90 */
91#define GELIC_NET_RXVLNPKT 0x00200000 /* VLAN packet */
92/* bit 20..16 reserved */
93#define GELIC_NET_RXRECNUM 0x0000ff00 /* reception receipt number */
94/* bit 7..0 reserved */
95
96#define GELIC_NET_TXDESC_TAIL 0
97#define GELIC_NET_DATA_STATUS_CHK_MASK (GELIC_NET_RXIPCHK | GELIC_NET_RXTCPCHK)
98
99/* RX descriptor data_error bits */
100/* bit 31 reserved */
101#define GELIC_NET_RXALNERR 0x40000000 /* alignement error 10/100M */
102#define GELIC_NET_RXOVERERR 0x20000000 /* oversize error */
103#define GELIC_NET_RXRNTERR 0x10000000 /* Runt error */
104#define GELIC_NET_RXIPCHKERR 0x08000000 /* IP checksum error */
105#define GELIC_NET_RXTCPCHKERR 0x04000000 /* TCP/UDP checksum error */
106#define GELIC_NET_RXUMCHSP 0x02000000 /* unmatched sp on sp */
107#define GELIC_NET_RXUMCHSPI 0x01000000 /* unmatched SPI on SAD */
108#define GELIC_NET_RXUMCHSAD 0x00800000 /* unmatched SAD */
109#define GELIC_NET_RXIPSAHERR 0x00400000 /* auth error on AH protocol
110 * processing */
111#define GELIC_NET_RXIPSESPAHERR 0x00200000 /* auth error on ESP protocol
112 * processing */
113#define GELIC_NET_RXDRPPKT 0x00100000 /* drop packet */
114#define GELIC_NET_RXIPFMTERR 0x00080000 /* IP packet format error */
115/* bit 18 reserved */
116#define GELIC_NET_RXDATAERR 0x00020000 /* IP packet format error */
117#define GELIC_NET_RXCALERR 0x00010000 /* cariier extension length
118 * error */
119#define GELIC_NET_RXCREXERR 0x00008000 /* carrier extention error */
120#define GELIC_NET_RXMLTCST 0x00004000 /* multicast address frame */
121/* bit 13..0 reserved */
122#define GELIC_NET_DATA_ERROR_CHK_MASK \
123 (GELIC_NET_RXIPCHKERR | GELIC_NET_RXTCPCHKERR)
124
125
126/* tx descriptor command and status */
127#define GELIC_NET_DMAC_CMDSTAT_NOCS 0xa0080000 /* middle of frame */
128#define GELIC_NET_DMAC_CMDSTAT_TCPCS 0xa00a0000
129#define GELIC_NET_DMAC_CMDSTAT_UDPCS 0xa00b0000
130#define GELIC_NET_DMAC_CMDSTAT_END_FRAME 0x00040000 /* end of frame */
131
132#define GELIC_NET_DMAC_CMDSTAT_RXDCEIS 0x00000002 /* descriptor chain end
133 * interrupt status */
134
135#define GELIC_NET_DMAC_CMDSTAT_CHAIN_END 0x00000002 /* RXDCEIS:DMA stopped */
136#define GELIC_NET_DMAC_CMDSTAT_NOT_IN_USE 0xb0000000
137#define GELIC_NET_DESCR_IND_PROC_SHIFT 28
138#define GELIC_NET_DESCR_IND_PROC_MASKO 0x0fffffff
139
140
141enum gelic_net_descr_status {
142 GELIC_NET_DESCR_COMPLETE = 0x00, /* used in rx and tx */
143 GELIC_NET_DESCR_RESPONSE_ERROR = 0x01, /* used in rx and tx */
144 GELIC_NET_DESCR_PROTECTION_ERROR = 0x02, /* used in rx and tx */
145 GELIC_NET_DESCR_FRAME_END = 0x04, /* used in rx */
146 GELIC_NET_DESCR_FORCE_END = 0x05, /* used in rx and tx */
147 GELIC_NET_DESCR_CARDOWNED = 0x0a, /* used in rx and tx */
148 GELIC_NET_DESCR_NOT_IN_USE /* any other value */
149};
150/* for lv1_net_control */
151#define GELIC_NET_GET_MAC_ADDRESS 0x0000000000000001
152#define GELIC_NET_GET_ETH_PORT_STATUS 0x0000000000000002
153#define GELIC_NET_SET_NEGOTIATION_MODE 0x0000000000000003
154#define GELIC_NET_GET_VLAN_ID 0x0000000000000004
155
156#define GELIC_NET_LINK_UP 0x0000000000000001
157#define GELIC_NET_FULL_DUPLEX 0x0000000000000002
158#define GELIC_NET_AUTO_NEG 0x0000000000000004
159#define GELIC_NET_SPEED_10 0x0000000000000010
160#define GELIC_NET_SPEED_100 0x0000000000000020
161#define GELIC_NET_SPEED_1000 0x0000000000000040
162
163#define GELIC_NET_VLAN_ALL 0x0000000000000001
164#define GELIC_NET_VLAN_WIRED 0x0000000000000002
165#define GELIC_NET_VLAN_WIRELESS 0x0000000000000003
166#define GELIC_NET_VLAN_PSP 0x0000000000000004
167#define GELIC_NET_VLAN_PORT0 0x0000000000000010
168#define GELIC_NET_VLAN_PORT1 0x0000000000000011
169#define GELIC_NET_VLAN_PORT2 0x0000000000000012
170#define GELIC_NET_VLAN_DAEMON_CLIENT_BSS 0x0000000000000013
171#define GELIC_NET_VLAN_LIBERO_CLIENT_BSS 0x0000000000000014
172#define GELIC_NET_VLAN_NO_ENTRY -6
173
174#define GELIC_NET_PORT 2 /* for port status */
175
176/* size of hardware part of gelic descriptor */
177#define GELIC_NET_DESCR_SIZE (32)
178struct gelic_net_descr {
179 /* as defined by the hardware */
180 u32 buf_addr;
181 u32 buf_size;
182 u32 next_descr_addr;
183 u32 dmac_cmd_status;
184 u32 result_size;
185 u32 valid_size; /* all zeroes for tx */
186 u32 data_status;
187 u32 data_error; /* all zeroes for tx */
188
189 /* used in the driver */
190 struct sk_buff *skb;
191 dma_addr_t bus_addr;
192 struct gelic_net_descr *next;
193 struct gelic_net_descr *prev;
194 struct vlan_ethhdr vlan;
195} __attribute__((aligned(32)));
196
197struct gelic_net_descr_chain {
198 /* we walk from tail to head */
199 struct gelic_net_descr *head;
200 struct gelic_net_descr *tail;
201};
202
203struct gelic_net_card {
204 struct net_device *netdev;
205 /*
206 * hypervisor requires irq_status should be
207 * 8 bytes aligned, but u64 member is
208 * always disposed in that manner
209 */
210 u64 irq_status;
211 u64 ghiintmask;
212
213 struct ps3_system_bus_device *dev;
214 u32 vlan_id[GELIC_NET_VLAN_MAX];
215 int vlan_index;
216
217 struct gelic_net_descr_chain tx_chain;
218 struct gelic_net_descr_chain rx_chain;
219 /* gurad dmac descriptor chain*/
220 spinlock_t chain_lock;
221
222 struct net_device_stats netdev_stats;
223 int rx_csum;
224 /* guard tx_dma_progress */
225 spinlock_t tx_dma_lock;
226 int tx_dma_progress;
227
228 struct work_struct tx_timeout_task;
229 atomic_t tx_timeout_task_counter;
230 wait_queue_head_t waitq;
231
232 struct gelic_net_descr *tx_top, *rx_top;
233 struct gelic_net_descr descr[0];
234};
235
236
237extern unsigned long p_to_lp(long pa);
238
239#endif /* _GELIC_NET_H */
diff --git a/drivers/net/qla3xxx.c b/drivers/net/qla3xxx.c
index 585be044ebbb..8be8be451ada 100755
--- a/drivers/net/qla3xxx.c
+++ b/drivers/net/qla3xxx.c
@@ -2433,37 +2433,22 @@ static int ql_get_seg_count(struct ql3_adapter *qdev,
2433 return -1; 2433 return -1;
2434} 2434}
2435 2435
2436static void ql_hw_csum_setup(struct sk_buff *skb, 2436static void ql_hw_csum_setup(const struct sk_buff *skb,
2437 struct ob_mac_iocb_req *mac_iocb_ptr) 2437 struct ob_mac_iocb_req *mac_iocb_ptr)
2438{ 2438{
2439 struct ethhdr *eth; 2439 const struct iphdr *ip = ip_hdr(skb);
2440 struct iphdr *ip = NULL;
2441 u8 offset = ETH_HLEN;
2442 2440
2443 eth = (struct ethhdr *)(skb->data); 2441 mac_iocb_ptr->ip_hdr_off = skb_network_offset(skb);
2442 mac_iocb_ptr->ip_hdr_len = ip->ihl;
2444 2443
2445 if (eth->h_proto == __constant_htons(ETH_P_IP)) { 2444 if (ip->protocol == IPPROTO_TCP) {
2446 ip = (struct iphdr *)&skb->data[ETH_HLEN]; 2445 mac_iocb_ptr->flags1 |= OB_3032MAC_IOCB_REQ_TC |
2447 } else if (eth->h_proto == htons(ETH_P_8021Q) &&
2448 ((struct vlan_ethhdr *)skb->data)->
2449 h_vlan_encapsulated_proto == __constant_htons(ETH_P_IP)) {
2450 ip = (struct iphdr *)&skb->data[VLAN_ETH_HLEN];
2451 offset = VLAN_ETH_HLEN;
2452 }
2453
2454 if (ip) {
2455 if (ip->protocol == IPPROTO_TCP) {
2456 mac_iocb_ptr->flags1 |= OB_3032MAC_IOCB_REQ_TC |
2457 OB_3032MAC_IOCB_REQ_IC; 2446 OB_3032MAC_IOCB_REQ_IC;
2458 mac_iocb_ptr->ip_hdr_off = offset; 2447 } else {
2459 mac_iocb_ptr->ip_hdr_len = ip->ihl; 2448 mac_iocb_ptr->flags1 |= OB_3032MAC_IOCB_REQ_UC |
2460 } else if (ip->protocol == IPPROTO_UDP) {
2461 mac_iocb_ptr->flags1 |= OB_3032MAC_IOCB_REQ_UC |
2462 OB_3032MAC_IOCB_REQ_IC; 2449 OB_3032MAC_IOCB_REQ_IC;
2463 mac_iocb_ptr->ip_hdr_off = offset;
2464 mac_iocb_ptr->ip_hdr_len = ip->ihl;
2465 }
2466 } 2450 }
2451
2467} 2452}
2468 2453
2469/* 2454/*
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 5ec7752caa48..982a9010c7a9 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -1,53 +1,11 @@
1/* 1/*
2========================================================================= 2 * r8169.c: RealTek 8169/8168/8101 ethernet driver.
3 r8169.c: A RealTek RTL-8169 Gigabit Ethernet driver for Linux kernel 2.4.x. 3 *
4 -------------------------------------------------------------------- 4 * Copyright (c) 2002 ShuChen <shuchen@realtek.com.tw>
5 5 * Copyright (c) 2003 - 2007 Francois Romieu <romieu@fr.zoreil.com>
6 History: 6 * Copyright (c) a lot of people too. Please respect their work.
7 Feb 4 2002 - created initially by ShuChen <shuchen@realtek.com.tw>. 7 *
8 May 20 2002 - Add link status force-mode and TBI mode support. 8 * See MAINTAINERS file for support contact information.
9 2004 - Massive updates. See kernel SCM system for details.
10=========================================================================
11 1. [DEPRECATED: use ethtool instead] The media can be forced in 5 modes.
12 Command: 'insmod r8169 media = SET_MEDIA'
13 Ex: 'insmod r8169 media = 0x04' will force PHY to operate in 100Mpbs Half-duplex.
14
15 SET_MEDIA can be:
16 _10_Half = 0x01
17 _10_Full = 0x02
18 _100_Half = 0x04
19 _100_Full = 0x08
20 _1000_Full = 0x10
21
22 2. Support TBI mode.
23=========================================================================
24VERSION 1.1 <2002/10/4>
25
26 The bit4:0 of MII register 4 is called "selector field", and have to be
27 00001b to indicate support of IEEE std 802.3 during NWay process of
28 exchanging Link Code Word (FLP).
29
30VERSION 1.2 <2002/11/30>
31
32 - Large style cleanup
33 - Use ether_crc in stock kernel (linux/crc32.h)
34 - Copy mc_filter setup code from 8139cp
35 (includes an optimization, and avoids set_bit use)
36
37VERSION 1.6LK <2004/04/14>
38
39 - Merge of Realtek's version 1.6
40 - Conversion to DMA API
41 - Suspend/resume
42 - Endianness
43 - Misc Rx/Tx bugs
44
45VERSION 2.2LK <2005/01/25>
46
47 - RX csum, TX csum/SG, TSO
48 - VLAN
49 - baby (< 7200) Jumbo frames support
50 - Merge of Realtek's version 2.2 (new phy)
51 */ 9 */
52 10
53#include <linux/module.h> 11#include <linux/module.h>
@@ -108,11 +66,6 @@ VERSION 2.2LK <2005/01/25>
108#define rtl8169_rx_quota(count, quota) count 66#define rtl8169_rx_quota(count, quota) count
109#endif 67#endif
110 68
111/* media options */
112#define MAX_UNITS 8
113static int media[MAX_UNITS] = { -1, -1, -1, -1, -1, -1, -1, -1 };
114static int num_media = 0;
115
116/* Maximum events (Rx packets, etc.) to handle at each interrupt. */ 69/* Maximum events (Rx packets, etc.) to handle at each interrupt. */
117static const int max_interrupt_work = 20; 70static const int max_interrupt_work = 20;
118 71
@@ -126,7 +79,7 @@ static const int multicast_filter_limit = 32;
126#define RX_FIFO_THRESH 7 /* 7 means NO threshold, Rx buffer level before first PCI xfer. */ 79#define RX_FIFO_THRESH 7 /* 7 means NO threshold, Rx buffer level before first PCI xfer. */
127#define RX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */ 80#define RX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */
128#define TX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */ 81#define TX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */
129#define EarlyTxThld 0x3F /* 0x3F means NO early transmit */ 82#define EarlyTxThld 0x3F /* 0x3F means NO early transmit */
130#define RxPacketMaxSize 0x3FE8 /* 16K - 1 - ETH_HLEN - VLAN - CRC... */ 83#define RxPacketMaxSize 0x3FE8 /* 16K - 1 - ETH_HLEN - VLAN - CRC... */
131#define SafeMtu 0x1c20 /* ... actually life sucks beyond ~7k */ 84#define SafeMtu 0x1c20 /* ... actually life sucks beyond ~7k */
132#define InterFrameGap 0x03 /* 3 means InterFrameGap = the shortest one */ 85#define InterFrameGap 0x03 /* 3 means InterFrameGap = the shortest one */
@@ -151,16 +104,17 @@ static const int multicast_filter_limit = 32;
151#define RTL_R32(reg) ((unsigned long) readl (ioaddr + (reg))) 104#define RTL_R32(reg) ((unsigned long) readl (ioaddr + (reg)))
152 105
153enum mac_version { 106enum mac_version {
154 RTL_GIGA_MAC_VER_01 = 0x00, 107 RTL_GIGA_MAC_VER_01 = 0x01, // 8169
155 RTL_GIGA_MAC_VER_02 = 0x01, 108 RTL_GIGA_MAC_VER_02 = 0x02, // 8169S
156 RTL_GIGA_MAC_VER_03 = 0x02, 109 RTL_GIGA_MAC_VER_03 = 0x03, // 8110S
157 RTL_GIGA_MAC_VER_04 = 0x03, 110 RTL_GIGA_MAC_VER_04 = 0x04, // 8169SB
158 RTL_GIGA_MAC_VER_05 = 0x04, 111 RTL_GIGA_MAC_VER_05 = 0x05, // 8110SCd
159 RTL_GIGA_MAC_VER_11 = 0x0b, 112 RTL_GIGA_MAC_VER_06 = 0x06, // 8110SCe
160 RTL_GIGA_MAC_VER_12 = 0x0c, 113 RTL_GIGA_MAC_VER_11 = 0x0b, // 8168Bb
161 RTL_GIGA_MAC_VER_13 = 0x0d, 114 RTL_GIGA_MAC_VER_12 = 0x0c, // 8168Be 8168Bf
162 RTL_GIGA_MAC_VER_14 = 0x0e, 115 RTL_GIGA_MAC_VER_13 = 0x0d, // 8101Eb 8101Ec
163 RTL_GIGA_MAC_VER_15 = 0x0f 116 RTL_GIGA_MAC_VER_14 = 0x0e, // 8101
117 RTL_GIGA_MAC_VER_15 = 0x0f // 8101
164}; 118};
165 119
166enum phy_version { 120enum phy_version {
@@ -180,11 +134,12 @@ static const struct {
180 u8 mac_version; 134 u8 mac_version;
181 u32 RxConfigMask; /* Clears the bits supported by this chip */ 135 u32 RxConfigMask; /* Clears the bits supported by this chip */
182} rtl_chip_info[] = { 136} rtl_chip_info[] = {
183 _R("RTL8169", RTL_GIGA_MAC_VER_01, 0xff7e1880), 137 _R("RTL8169", RTL_GIGA_MAC_VER_01, 0xff7e1880), // 8169
184 _R("RTL8169s/8110s", RTL_GIGA_MAC_VER_02, 0xff7e1880), 138 _R("RTL8169s", RTL_GIGA_MAC_VER_02, 0xff7e1880), // 8169S
185 _R("RTL8169s/8110s", RTL_GIGA_MAC_VER_03, 0xff7e1880), 139 _R("RTL8110s", RTL_GIGA_MAC_VER_03, 0xff7e1880), // 8110S
186 _R("RTL8169sb/8110sb", RTL_GIGA_MAC_VER_04, 0xff7e1880), 140 _R("RTL8169sb/8110sb", RTL_GIGA_MAC_VER_04, 0xff7e1880), // 8169SB
187 _R("RTL8169sc/8110sc", RTL_GIGA_MAC_VER_05, 0xff7e1880), 141 _R("RTL8169sc/8110sc", RTL_GIGA_MAC_VER_05, 0xff7e1880), // 8110SCd
142 _R("RTL8169sc/8110sc", RTL_GIGA_MAC_VER_06, 0xff7e1880), // 8110SCe
188 _R("RTL8168b/8111b", RTL_GIGA_MAC_VER_11, 0xff7e1880), // PCI-E 143 _R("RTL8168b/8111b", RTL_GIGA_MAC_VER_11, 0xff7e1880), // PCI-E
189 _R("RTL8168b/8111b", RTL_GIGA_MAC_VER_12, 0xff7e1880), // PCI-E 144 _R("RTL8168b/8111b", RTL_GIGA_MAC_VER_12, 0xff7e1880), // PCI-E
190 _R("RTL8101e", RTL_GIGA_MAC_VER_13, 0xff7e1880), // PCI-E 8139 145 _R("RTL8101e", RTL_GIGA_MAC_VER_13, 0xff7e1880), // PCI-E 8139
@@ -199,20 +154,15 @@ enum cfg_version {
199 RTL_CFG_2 154 RTL_CFG_2
200}; 155};
201 156
202static const struct { 157static void rtl_hw_start_8169(struct net_device *);
203 unsigned int region; 158static void rtl_hw_start_8168(struct net_device *);
204 unsigned int align; 159static void rtl_hw_start_8101(struct net_device *);
205} rtl_cfg_info[] = {
206 [RTL_CFG_0] = { 1, NET_IP_ALIGN },
207 [RTL_CFG_1] = { 2, NET_IP_ALIGN },
208 [RTL_CFG_2] = { 2, 8 }
209};
210 160
211static struct pci_device_id rtl8169_pci_tbl[] = { 161static struct pci_device_id rtl8169_pci_tbl[] = {
212 { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8129), 0, 0, RTL_CFG_0 }, 162 { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8129), 0, 0, RTL_CFG_0 },
213 { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8136), 0, 0, RTL_CFG_2 }, 163 { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8136), 0, 0, RTL_CFG_2 },
214 { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8167), 0, 0, RTL_CFG_0 }, 164 { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8167), 0, 0, RTL_CFG_0 },
215 { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8168), 0, 0, RTL_CFG_2 }, 165 { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8168), 0, 0, RTL_CFG_1 },
216 { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8169), 0, 0, RTL_CFG_0 }, 166 { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8169), 0, 0, RTL_CFG_0 },
217 { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4300), 0, 0, RTL_CFG_0 }, 167 { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4300), 0, 0, RTL_CFG_0 },
218 { PCI_DEVICE(0x1259, 0xc107), 0, 0, RTL_CFG_0 }, 168 { PCI_DEVICE(0x1259, 0xc107), 0, 0, RTL_CFG_0 },
@@ -230,62 +180,63 @@ static struct {
230 u32 msg_enable; 180 u32 msg_enable;
231} debug = { -1 }; 181} debug = { -1 };
232 182
233enum RTL8169_registers { 183enum rtl_registers {
234 MAC0 = 0, /* Ethernet hardware address. */ 184 MAC0 = 0, /* Ethernet hardware address. */
235 MAR0 = 8, /* Multicast filter. */ 185 MAC4 = 4,
236 CounterAddrLow = 0x10, 186 MAR0 = 8, /* Multicast filter. */
237 CounterAddrHigh = 0x14, 187 CounterAddrLow = 0x10,
238 TxDescStartAddrLow = 0x20, 188 CounterAddrHigh = 0x14,
239 TxDescStartAddrHigh = 0x24, 189 TxDescStartAddrLow = 0x20,
240 TxHDescStartAddrLow = 0x28, 190 TxDescStartAddrHigh = 0x24,
241 TxHDescStartAddrHigh = 0x2c, 191 TxHDescStartAddrLow = 0x28,
242 FLASH = 0x30, 192 TxHDescStartAddrHigh = 0x2c,
243 ERSR = 0x36, 193 FLASH = 0x30,
244 ChipCmd = 0x37, 194 ERSR = 0x36,
245 TxPoll = 0x38, 195 ChipCmd = 0x37,
246 IntrMask = 0x3C, 196 TxPoll = 0x38,
247 IntrStatus = 0x3E, 197 IntrMask = 0x3c,
248 TxConfig = 0x40, 198 IntrStatus = 0x3e,
249 RxConfig = 0x44, 199 TxConfig = 0x40,
250 RxMissed = 0x4C, 200 RxConfig = 0x44,
251 Cfg9346 = 0x50, 201 RxMissed = 0x4c,
252 Config0 = 0x51, 202 Cfg9346 = 0x50,
253 Config1 = 0x52, 203 Config0 = 0x51,
254 Config2 = 0x53, 204 Config1 = 0x52,
255 Config3 = 0x54, 205 Config2 = 0x53,
256 Config4 = 0x55, 206 Config3 = 0x54,
257 Config5 = 0x56, 207 Config4 = 0x55,
258 MultiIntr = 0x5C, 208 Config5 = 0x56,
259 PHYAR = 0x60, 209 MultiIntr = 0x5c,
260 TBICSR = 0x64, 210 PHYAR = 0x60,
261 TBI_ANAR = 0x68, 211 TBICSR = 0x64,
262 TBI_LPAR = 0x6A, 212 TBI_ANAR = 0x68,
263 PHYstatus = 0x6C, 213 TBI_LPAR = 0x6a,
264 RxMaxSize = 0xDA, 214 PHYstatus = 0x6c,
265 CPlusCmd = 0xE0, 215 RxMaxSize = 0xda,
266 IntrMitigate = 0xE2, 216 CPlusCmd = 0xe0,
267 RxDescAddrLow = 0xE4, 217 IntrMitigate = 0xe2,
268 RxDescAddrHigh = 0xE8, 218 RxDescAddrLow = 0xe4,
269 EarlyTxThres = 0xEC, 219 RxDescAddrHigh = 0xe8,
270 FuncEvent = 0xF0, 220 EarlyTxThres = 0xec,
271 FuncEventMask = 0xF4, 221 FuncEvent = 0xf0,
272 FuncPresetState = 0xF8, 222 FuncEventMask = 0xf4,
273 FuncForceEvent = 0xFC, 223 FuncPresetState = 0xf8,
224 FuncForceEvent = 0xfc,
274}; 225};
275 226
276enum RTL8169_register_content { 227enum rtl_register_content {
277 /* InterruptStatusBits */ 228 /* InterruptStatusBits */
278 SYSErr = 0x8000, 229 SYSErr = 0x8000,
279 PCSTimeout = 0x4000, 230 PCSTimeout = 0x4000,
280 SWInt = 0x0100, 231 SWInt = 0x0100,
281 TxDescUnavail = 0x80, 232 TxDescUnavail = 0x0080,
282 RxFIFOOver = 0x40, 233 RxFIFOOver = 0x0040,
283 LinkChg = 0x20, 234 LinkChg = 0x0020,
284 RxOverflow = 0x10, 235 RxOverflow = 0x0010,
285 TxErr = 0x08, 236 TxErr = 0x0008,
286 TxOK = 0x04, 237 TxOK = 0x0004,
287 RxErr = 0x02, 238 RxErr = 0x0002,
288 RxOK = 0x01, 239 RxOK = 0x0001,
289 240
290 /* RxStatusDesc */ 241 /* RxStatusDesc */
291 RxFOVF = (1 << 23), 242 RxFOVF = (1 << 23),
@@ -295,26 +246,31 @@ enum RTL8169_register_content {
295 RxCRC = (1 << 19), 246 RxCRC = (1 << 19),
296 247
297 /* ChipCmdBits */ 248 /* ChipCmdBits */
298 CmdReset = 0x10, 249 CmdReset = 0x10,
299 CmdRxEnb = 0x08, 250 CmdRxEnb = 0x08,
300 CmdTxEnb = 0x04, 251 CmdTxEnb = 0x04,
301 RxBufEmpty = 0x01, 252 RxBufEmpty = 0x01,
253
254 /* TXPoll register p.5 */
255 HPQ = 0x80, /* Poll cmd on the high prio queue */
256 NPQ = 0x40, /* Poll cmd on the low prio queue */
257 FSWInt = 0x01, /* Forced software interrupt */
302 258
303 /* Cfg9346Bits */ 259 /* Cfg9346Bits */
304 Cfg9346_Lock = 0x00, 260 Cfg9346_Lock = 0x00,
305 Cfg9346_Unlock = 0xC0, 261 Cfg9346_Unlock = 0xc0,
306 262
307 /* rx_mode_bits */ 263 /* rx_mode_bits */
308 AcceptErr = 0x20, 264 AcceptErr = 0x20,
309 AcceptRunt = 0x10, 265 AcceptRunt = 0x10,
310 AcceptBroadcast = 0x08, 266 AcceptBroadcast = 0x08,
311 AcceptMulticast = 0x04, 267 AcceptMulticast = 0x04,
312 AcceptMyPhys = 0x02, 268 AcceptMyPhys = 0x02,
313 AcceptAllPhys = 0x01, 269 AcceptAllPhys = 0x01,
314 270
315 /* RxConfigBits */ 271 /* RxConfigBits */
316 RxCfgFIFOShift = 13, 272 RxCfgFIFOShift = 13,
317 RxCfgDMAShift = 8, 273 RxCfgDMAShift = 8,
318 274
319 /* TxConfigBits */ 275 /* TxConfigBits */
320 TxInterFrameGapShift = 24, 276 TxInterFrameGapShift = 24,
@@ -323,6 +279,10 @@ enum RTL8169_register_content {
323 /* Config1 register p.24 */ 279 /* Config1 register p.24 */
324 PMEnable = (1 << 0), /* Power Management Enable */ 280 PMEnable = (1 << 0), /* Power Management Enable */
325 281
282 /* Config2 register p. 25 */
283 PCI_Clock_66MHz = 0x01,
284 PCI_Clock_33MHz = 0x00,
285
326 /* Config3 register p.25 */ 286 /* Config3 register p.25 */
327 MagicPacket = (1 << 5), /* Wake up when receives a Magic Packet */ 287 MagicPacket = (1 << 5), /* Wake up when receives a Magic Packet */
328 LinkUp = (1 << 4), /* Wake up when the cable connection is re-established */ 288 LinkUp = (1 << 4), /* Wake up when the cable connection is re-established */
@@ -343,36 +303,34 @@ enum RTL8169_register_content {
343 TBINwComplete = 0x01000000, 303 TBINwComplete = 0x01000000,
344 304
345 /* CPlusCmd p.31 */ 305 /* CPlusCmd p.31 */
306 PktCntrDisable = (1 << 7), // 8168
346 RxVlan = (1 << 6), 307 RxVlan = (1 << 6),
347 RxChkSum = (1 << 5), 308 RxChkSum = (1 << 5),
348 PCIDAC = (1 << 4), 309 PCIDAC = (1 << 4),
349 PCIMulRW = (1 << 3), 310 PCIMulRW = (1 << 3),
311 INTT_0 = 0x0000, // 8168
312 INTT_1 = 0x0001, // 8168
313 INTT_2 = 0x0002, // 8168
314 INTT_3 = 0x0003, // 8168
350 315
351 /* rtl8169_PHYstatus */ 316 /* rtl8169_PHYstatus */
352 TBI_Enable = 0x80, 317 TBI_Enable = 0x80,
353 TxFlowCtrl = 0x40, 318 TxFlowCtrl = 0x40,
354 RxFlowCtrl = 0x20, 319 RxFlowCtrl = 0x20,
355 _1000bpsF = 0x10, 320 _1000bpsF = 0x10,
356 _100bps = 0x08, 321 _100bps = 0x08,
357 _10bps = 0x04, 322 _10bps = 0x04,
358 LinkStatus = 0x02, 323 LinkStatus = 0x02,
359 FullDup = 0x01, 324 FullDup = 0x01,
360
361 /* _MediaType */
362 _10_Half = 0x01,
363 _10_Full = 0x02,
364 _100_Half = 0x04,
365 _100_Full = 0x08,
366 _1000_Full = 0x10,
367 325
368 /* _TBICSRBit */ 326 /* _TBICSRBit */
369 TBILinkOK = 0x02000000, 327 TBILinkOK = 0x02000000,
370 328
371 /* DumpCounterCommand */ 329 /* DumpCounterCommand */
372 CounterDump = 0x8, 330 CounterDump = 0x8,
373}; 331};
374 332
375enum _DescStatusBit { 333enum desc_status_bit {
376 DescOwn = (1 << 31), /* Descriptor is owned by NIC */ 334 DescOwn = (1 << 31), /* Descriptor is owned by NIC */
377 RingEnd = (1 << 30), /* End of descriptor ring */ 335 RingEnd = (1 << 30), /* End of descriptor ring */
378 FirstFrag = (1 << 29), /* First segment of a packet */ 336 FirstFrag = (1 << 29), /* First segment of a packet */
@@ -405,15 +363,15 @@ enum _DescStatusBit {
405#define RsvdMask 0x3fffc000 363#define RsvdMask 0x3fffc000
406 364
407struct TxDesc { 365struct TxDesc {
408 u32 opts1; 366 __le32 opts1;
409 u32 opts2; 367 __le32 opts2;
410 u64 addr; 368 __le64 addr;
411}; 369};
412 370
413struct RxDesc { 371struct RxDesc {
414 u32 opts1; 372 __le32 opts1;
415 u32 opts2; 373 __le32 opts2;
416 u64 addr; 374 __le64 addr;
417}; 375};
418 376
419struct ring_info { 377struct ring_info {
@@ -446,6 +404,8 @@ struct rtl8169_private {
446 unsigned rx_buf_sz; 404 unsigned rx_buf_sz;
447 struct timer_list timer; 405 struct timer_list timer;
448 u16 cp_cmd; 406 u16 cp_cmd;
407 u16 intr_event;
408 u16 napi_event;
449 u16 intr_mask; 409 u16 intr_mask;
450 int phy_auto_nego_reg; 410 int phy_auto_nego_reg;
451 int phy_1000_ctrl_reg; 411 int phy_1000_ctrl_reg;
@@ -455,6 +415,7 @@ struct rtl8169_private {
455 int (*set_speed)(struct net_device *, u8 autoneg, u16 speed, u8 duplex); 415 int (*set_speed)(struct net_device *, u8 autoneg, u16 speed, u8 duplex);
456 void (*get_settings)(struct net_device *, struct ethtool_cmd *); 416 void (*get_settings)(struct net_device *, struct ethtool_cmd *);
457 void (*phy_reset_enable)(void __iomem *); 417 void (*phy_reset_enable)(void __iomem *);
418 void (*hw_start)(struct net_device *);
458 unsigned int (*phy_reset_pending)(void __iomem *); 419 unsigned int (*phy_reset_pending)(void __iomem *);
459 unsigned int (*link_ok)(void __iomem *); 420 unsigned int (*link_ok)(void __iomem *);
460 struct delayed_work task; 421 struct delayed_work task;
@@ -463,8 +424,6 @@ struct rtl8169_private {
463 424
464MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>"); 425MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>");
465MODULE_DESCRIPTION("RealTek RTL-8169 Gigabit Ethernet driver"); 426MODULE_DESCRIPTION("RealTek RTL-8169 Gigabit Ethernet driver");
466module_param_array(media, int, &num_media, 0);
467MODULE_PARM_DESC(media, "force phy operation. Deprecated by ethtool (8).");
468module_param(rx_copybreak, int, 0); 427module_param(rx_copybreak, int, 0);
469MODULE_PARM_DESC(rx_copybreak, "Copy breakpoint for copy-only-tiny-frames"); 428MODULE_PARM_DESC(rx_copybreak, "Copy breakpoint for copy-only-tiny-frames");
470module_param(use_dac, int, 0); 429module_param(use_dac, int, 0);
@@ -478,9 +437,9 @@ static int rtl8169_open(struct net_device *dev);
478static int rtl8169_start_xmit(struct sk_buff *skb, struct net_device *dev); 437static int rtl8169_start_xmit(struct sk_buff *skb, struct net_device *dev);
479static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance); 438static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance);
480static int rtl8169_init_ring(struct net_device *dev); 439static int rtl8169_init_ring(struct net_device *dev);
481static void rtl8169_hw_start(struct net_device *dev); 440static void rtl_hw_start(struct net_device *dev);
482static int rtl8169_close(struct net_device *dev); 441static int rtl8169_close(struct net_device *dev);
483static void rtl8169_set_rx_mode(struct net_device *dev); 442static void rtl_set_rx_mode(struct net_device *dev);
484static void rtl8169_tx_timeout(struct net_device *dev); 443static void rtl8169_tx_timeout(struct net_device *dev);
485static struct net_device_stats *rtl8169_get_stats(struct net_device *dev); 444static struct net_device_stats *rtl8169_get_stats(struct net_device *dev);
486static int rtl8169_rx_interrupt(struct net_device *, struct rtl8169_private *, 445static int rtl8169_rx_interrupt(struct net_device *, struct rtl8169_private *,
@@ -493,35 +452,37 @@ static void rtl8169_rx_clear(struct rtl8169_private *tp);
493static int rtl8169_poll(struct net_device *dev, int *budget); 452static int rtl8169_poll(struct net_device *dev, int *budget);
494#endif 453#endif
495 454
496static const u16 rtl8169_intr_mask =
497 SYSErr | LinkChg | RxOverflow | RxFIFOOver | TxErr | TxOK | RxErr | RxOK;
498static const u16 rtl8169_napi_event =
499 RxOK | RxOverflow | RxFIFOOver | TxOK | TxErr;
500static const unsigned int rtl8169_rx_config = 455static const unsigned int rtl8169_rx_config =
501 (RX_FIFO_THRESH << RxCfgFIFOShift) | (RX_DMA_BURST << RxCfgDMAShift); 456 (RX_FIFO_THRESH << RxCfgFIFOShift) | (RX_DMA_BURST << RxCfgDMAShift);
502 457
503static void mdio_write(void __iomem *ioaddr, int RegAddr, int value) 458static void mdio_write(void __iomem *ioaddr, int reg_addr, int value)
504{ 459{
505 int i; 460 int i;
506 461
507 RTL_W32(PHYAR, 0x80000000 | (RegAddr & 0xFF) << 16 | value); 462 RTL_W32(PHYAR, 0x80000000 | (reg_addr & 0xFF) << 16 | value);
508 463
509 for (i = 20; i > 0; i--) { 464 for (i = 20; i > 0; i--) {
510 /* Check if the RTL8169 has completed writing to the specified MII register */ 465 /*
466 * Check if the RTL8169 has completed writing to the specified
467 * MII register.
468 */
511 if (!(RTL_R32(PHYAR) & 0x80000000)) 469 if (!(RTL_R32(PHYAR) & 0x80000000))
512 break; 470 break;
513 udelay(25); 471 udelay(25);
514 } 472 }
515} 473}
516 474
517static int mdio_read(void __iomem *ioaddr, int RegAddr) 475static int mdio_read(void __iomem *ioaddr, int reg_addr)
518{ 476{
519 int i, value = -1; 477 int i, value = -1;
520 478
521 RTL_W32(PHYAR, 0x0 | (RegAddr & 0xFF) << 16); 479 RTL_W32(PHYAR, 0x0 | (reg_addr & 0xFF) << 16);
522 480
523 for (i = 20; i > 0; i--) { 481 for (i = 20; i > 0; i--) {
524 /* Check if the RTL8169 has completed retrieving data from the specified MII register */ 482 /*
483 * Check if the RTL8169 has completed retrieving data from
484 * the specified MII register.
485 */
525 if (RTL_R32(PHYAR) & 0x80000000) { 486 if (RTL_R32(PHYAR) & 0x80000000) {
526 value = (int) (RTL_R32(PHYAR) & 0xFFFF); 487 value = (int) (RTL_R32(PHYAR) & 0xFFFF);
527 break; 488 break;
@@ -579,7 +540,8 @@ static void rtl8169_xmii_reset_enable(void __iomem *ioaddr)
579} 540}
580 541
581static void rtl8169_check_link_status(struct net_device *dev, 542static void rtl8169_check_link_status(struct net_device *dev,
582 struct rtl8169_private *tp, void __iomem *ioaddr) 543 struct rtl8169_private *tp,
544 void __iomem *ioaddr)
583{ 545{
584 unsigned long flags; 546 unsigned long flags;
585 547
@@ -596,38 +558,6 @@ static void rtl8169_check_link_status(struct net_device *dev,
596 spin_unlock_irqrestore(&tp->lock, flags); 558 spin_unlock_irqrestore(&tp->lock, flags);
597} 559}
598 560
599static void rtl8169_link_option(int idx, u8 *autoneg, u16 *speed, u8 *duplex)
600{
601 struct {
602 u16 speed;
603 u8 duplex;
604 u8 autoneg;
605 u8 media;
606 } link_settings[] = {
607 { SPEED_10, DUPLEX_HALF, AUTONEG_DISABLE, _10_Half },
608 { SPEED_10, DUPLEX_FULL, AUTONEG_DISABLE, _10_Full },
609 { SPEED_100, DUPLEX_HALF, AUTONEG_DISABLE, _100_Half },
610 { SPEED_100, DUPLEX_FULL, AUTONEG_DISABLE, _100_Full },
611 { SPEED_1000, DUPLEX_FULL, AUTONEG_DISABLE, _1000_Full },
612 /* Make TBI happy */
613 { SPEED_1000, DUPLEX_FULL, AUTONEG_ENABLE, 0xff }
614 }, *p;
615 unsigned char option;
616
617 option = ((idx < MAX_UNITS) && (idx >= 0)) ? media[idx] : 0xff;
618
619 if ((option != 0xff) && !idx && netif_msg_drv(&debug))
620 printk(KERN_WARNING PFX "media option is deprecated.\n");
621
622 for (p = link_settings; p->media != 0xff; p++) {
623 if (p->media == option)
624 break;
625 }
626 *autoneg = p->autoneg;
627 *speed = p->speed;
628 *duplex = p->duplex;
629}
630
631static void rtl8169_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) 561static void rtl8169_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
632{ 562{
633 struct rtl8169_private *tp = netdev_priv(dev); 563 struct rtl8169_private *tp = netdev_priv(dev);
@@ -667,7 +597,7 @@ static int rtl8169_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
667{ 597{
668 struct rtl8169_private *tp = netdev_priv(dev); 598 struct rtl8169_private *tp = netdev_priv(dev);
669 void __iomem *ioaddr = tp->mmio_addr; 599 void __iomem *ioaddr = tp->mmio_addr;
670 int i; 600 unsigned int i;
671 static struct { 601 static struct {
672 u32 opt; 602 u32 opt;
673 u16 reg; 603 u16 reg;
@@ -893,8 +823,7 @@ static int rtl8169_rx_vlan_skb(struct rtl8169_private *tp, struct RxDesc *desc,
893 int ret; 823 int ret;
894 824
895 if (tp->vlgrp && (opts2 & RxVlanTag)) { 825 if (tp->vlgrp && (opts2 & RxVlanTag)) {
896 rtl8169_rx_hwaccel_skb(skb, tp->vlgrp, 826 rtl8169_rx_hwaccel_skb(skb, tp->vlgrp, swab16(opts2 & 0xffff));
897 swab16(opts2 & 0xffff));
898 ret = 0; 827 ret = 0;
899 } else 828 } else
900 ret = -1; 829 ret = -1;
@@ -1115,7 +1044,6 @@ static void rtl8169_get_strings(struct net_device *dev, u32 stringset, u8 *data)
1115 } 1044 }
1116} 1045}
1117 1046
1118
1119static const struct ethtool_ops rtl8169_ethtool_ops = { 1047static const struct ethtool_ops rtl8169_ethtool_ops = {
1120 .get_drvinfo = rtl8169_get_drvinfo, 1048 .get_drvinfo = rtl8169_get_drvinfo,
1121 .get_regs_len = rtl8169_get_regs_len, 1049 .get_regs_len = rtl8169_get_regs_len,
@@ -1141,8 +1069,8 @@ static const struct ethtool_ops rtl8169_ethtool_ops = {
1141 .get_perm_addr = ethtool_op_get_perm_addr, 1069 .get_perm_addr = ethtool_op_get_perm_addr,
1142}; 1070};
1143 1071
1144static void rtl8169_write_gmii_reg_bit(void __iomem *ioaddr, int reg, int bitnum, 1072static void rtl8169_write_gmii_reg_bit(void __iomem *ioaddr, int reg,
1145 int bitval) 1073 int bitnum, int bitval)
1146{ 1074{
1147 int val; 1075 int val;
1148 1076
@@ -1152,8 +1080,20 @@ static void rtl8169_write_gmii_reg_bit(void __iomem *ioaddr, int reg, int bitnum
1152 mdio_write(ioaddr, reg, val & 0xffff); 1080 mdio_write(ioaddr, reg, val & 0xffff);
1153} 1081}
1154 1082
1155static void rtl8169_get_mac_version(struct rtl8169_private *tp, void __iomem *ioaddr) 1083static void rtl8169_get_mac_version(struct rtl8169_private *tp,
1084 void __iomem *ioaddr)
1156{ 1085{
1086 /*
1087 * The driver currently handles the 8168Bf and the 8168Be identically
1088 * but they can be identified more specifically through the test below
1089 * if needed:
1090 *
1091 * (RTL_R32(TxConfig) & 0x700000) == 0x500000 ? 8168Bf : 8168Be
1092 *
1093 * Same thing for the 8101Eb and the 8101Ec:
1094 *
1095 * (RTL_R32(TxConfig) & 0x700000) == 0x200000 ? 8101Eb : 8101Ec
1096 */
1157 const struct { 1097 const struct {
1158 u32 mask; 1098 u32 mask;
1159 int mac_version; 1099 int mac_version;
@@ -1163,6 +1103,7 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp, void __iomem *io
1163 { 0x34000000, RTL_GIGA_MAC_VER_13 }, 1103 { 0x34000000, RTL_GIGA_MAC_VER_13 },
1164 { 0x30800000, RTL_GIGA_MAC_VER_14 }, 1104 { 0x30800000, RTL_GIGA_MAC_VER_14 },
1165 { 0x30000000, RTL_GIGA_MAC_VER_11 }, 1105 { 0x30000000, RTL_GIGA_MAC_VER_11 },
1106 { 0x98000000, RTL_GIGA_MAC_VER_06 },
1166 { 0x18000000, RTL_GIGA_MAC_VER_05 }, 1107 { 0x18000000, RTL_GIGA_MAC_VER_05 },
1167 { 0x10000000, RTL_GIGA_MAC_VER_04 }, 1108 { 0x10000000, RTL_GIGA_MAC_VER_04 },
1168 { 0x04000000, RTL_GIGA_MAC_VER_03 }, 1109 { 0x04000000, RTL_GIGA_MAC_VER_03 },
@@ -1171,7 +1112,7 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp, void __iomem *io
1171 }, *p = mac_info; 1112 }, *p = mac_info;
1172 u32 reg; 1113 u32 reg;
1173 1114
1174 reg = RTL_R32(TxConfig) & 0x7c800000; 1115 reg = RTL_R32(TxConfig) & 0xfc800000;
1175 while ((reg & p->mask) != p->mask) 1116 while ((reg & p->mask) != p->mask)
1176 p++; 1117 p++;
1177 tp->mac_version = p->mac_version; 1118 tp->mac_version = p->mac_version;
@@ -1182,7 +1123,8 @@ static void rtl8169_print_mac_version(struct rtl8169_private *tp)
1182 dprintk("mac_version = 0x%02x\n", tp->mac_version); 1123 dprintk("mac_version = 0x%02x\n", tp->mac_version);
1183} 1124}
1184 1125
1185static void rtl8169_get_phy_version(struct rtl8169_private *tp, void __iomem *ioaddr) 1126static void rtl8169_get_phy_version(struct rtl8169_private *tp,
1127 void __iomem *ioaddr)
1186{ 1128{
1187 const struct { 1129 const struct {
1188 u16 mask; 1130 u16 mask;
@@ -1259,7 +1201,7 @@ static void rtl8169_hw_phy_config(struct net_device *dev)
1259 0xbf00 } //w 0 15 0 bf00 1201 0xbf00 } //w 0 15 0 bf00
1260 } 1202 }
1261 }, *p = phy_magic; 1203 }, *p = phy_magic;
1262 int i; 1204 unsigned int i;
1263 1205
1264 rtl8169_print_mac_version(tp); 1206 rtl8169_print_mac_version(tp);
1265 rtl8169_print_phy_version(tp); 1207 rtl8169_print_phy_version(tp);
@@ -1393,7 +1335,7 @@ static void rtl8169_phy_reset(struct net_device *dev,
1393 struct rtl8169_private *tp) 1335 struct rtl8169_private *tp)
1394{ 1336{
1395 void __iomem *ioaddr = tp->mmio_addr; 1337 void __iomem *ioaddr = tp->mmio_addr;
1396 int i; 1338 unsigned int i;
1397 1339
1398 tp->phy_reset_enable(ioaddr); 1340 tp->phy_reset_enable(ioaddr);
1399 for (i = 0; i < 100; i++) { 1341 for (i = 0; i < 100; i++) {
@@ -1408,21 +1350,16 @@ static void rtl8169_phy_reset(struct net_device *dev,
1408static void rtl8169_init_phy(struct net_device *dev, struct rtl8169_private *tp) 1350static void rtl8169_init_phy(struct net_device *dev, struct rtl8169_private *tp)
1409{ 1351{
1410 void __iomem *ioaddr = tp->mmio_addr; 1352 void __iomem *ioaddr = tp->mmio_addr;
1411 static int board_idx = -1;
1412 u8 autoneg, duplex;
1413 u16 speed;
1414
1415 board_idx++;
1416 1353
1417 rtl8169_hw_phy_config(dev); 1354 rtl8169_hw_phy_config(dev);
1418 1355
1419 dprintk("Set MAC Reg C+CR Offset 0x82h = 0x01h\n"); 1356 dprintk("Set MAC Reg C+CR Offset 0x82h = 0x01h\n");
1420 RTL_W8(0x82, 0x01); 1357 RTL_W8(0x82, 0x01);
1421 1358
1422 if (tp->mac_version < RTL_GIGA_MAC_VER_03) { 1359 pci_write_config_byte(tp->pci_dev, PCI_LATENCY_TIMER, 0x40);
1423 dprintk("Set PCI Latency=0x40\n"); 1360
1424 pci_write_config_byte(tp->pci_dev, PCI_LATENCY_TIMER, 0x40); 1361 if (tp->mac_version <= RTL_GIGA_MAC_VER_06)
1425 } 1362 pci_write_config_byte(tp->pci_dev, PCI_CACHE_LINE_SIZE, 0x08);
1426 1363
1427 if (tp->mac_version == RTL_GIGA_MAC_VER_02) { 1364 if (tp->mac_version == RTL_GIGA_MAC_VER_02) {
1428 dprintk("Set MAC Reg C+CR Offset 0x82h = 0x01h\n"); 1365 dprintk("Set MAC Reg C+CR Offset 0x82h = 0x01h\n");
@@ -1431,16 +1368,52 @@ static void rtl8169_init_phy(struct net_device *dev, struct rtl8169_private *tp)
1431 mdio_write(ioaddr, 0x0b, 0x0000); //w 0x0b 15 0 0 1368 mdio_write(ioaddr, 0x0b, 0x0000); //w 0x0b 15 0 0
1432 } 1369 }
1433 1370
1434 rtl8169_link_option(board_idx, &autoneg, &speed, &duplex);
1435
1436 rtl8169_phy_reset(dev, tp); 1371 rtl8169_phy_reset(dev, tp);
1437 1372
1438 rtl8169_set_speed(dev, autoneg, speed, duplex); 1373 /*
1374 * rtl8169_set_speed_xmii takes good care of the Fast Ethernet
1375 * only 8101. Don't panic.
1376 */
1377 rtl8169_set_speed(dev, AUTONEG_ENABLE, SPEED_1000, DUPLEX_FULL);
1439 1378
1440 if ((RTL_R8(PHYstatus) & TBI_Enable) && netif_msg_link(tp)) 1379 if ((RTL_R8(PHYstatus) & TBI_Enable) && netif_msg_link(tp))
1441 printk(KERN_INFO PFX "%s: TBI auto-negotiating\n", dev->name); 1380 printk(KERN_INFO PFX "%s: TBI auto-negotiating\n", dev->name);
1442} 1381}
1443 1382
1383static void rtl_rar_set(struct rtl8169_private *tp, u8 *addr)
1384{
1385 void __iomem *ioaddr = tp->mmio_addr;
1386 u32 high;
1387 u32 low;
1388
1389 low = addr[0] | (addr[1] << 8) | (addr[2] << 16) | (addr[3] << 24);
1390 high = addr[4] | (addr[5] << 8);
1391
1392 spin_lock_irq(&tp->lock);
1393
1394 RTL_W8(Cfg9346, Cfg9346_Unlock);
1395 RTL_W32(MAC0, low);
1396 RTL_W32(MAC4, high);
1397 RTL_W8(Cfg9346, Cfg9346_Lock);
1398
1399 spin_unlock_irq(&tp->lock);
1400}
1401
1402static int rtl_set_mac_address(struct net_device *dev, void *p)
1403{
1404 struct rtl8169_private *tp = netdev_priv(dev);
1405 struct sockaddr *addr = p;
1406
1407 if (!is_valid_ether_addr(addr->sa_data))
1408 return -EADDRNOTAVAIL;
1409
1410 memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
1411
1412 rtl_rar_set(tp, dev->dev_addr);
1413
1414 return 0;
1415}
1416
1444static int rtl8169_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) 1417static int rtl8169_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1445{ 1418{
1446 struct rtl8169_private *tp = netdev_priv(dev); 1419 struct rtl8169_private *tp = netdev_priv(dev);
@@ -1467,15 +1440,49 @@ static int rtl8169_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1467 return -EOPNOTSUPP; 1440 return -EOPNOTSUPP;
1468} 1441}
1469 1442
1443static const struct rtl_cfg_info {
1444 void (*hw_start)(struct net_device *);
1445 unsigned int region;
1446 unsigned int align;
1447 u16 intr_event;
1448 u16 napi_event;
1449} rtl_cfg_infos [] = {
1450 [RTL_CFG_0] = {
1451 .hw_start = rtl_hw_start_8169,
1452 .region = 1,
1453 .align = 0,
1454 .intr_event = SYSErr | LinkChg | RxOverflow |
1455 RxFIFOOver | TxErr | TxOK | RxOK | RxErr,
1456 .napi_event = RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow
1457 },
1458 [RTL_CFG_1] = {
1459 .hw_start = rtl_hw_start_8168,
1460 .region = 2,
1461 .align = 8,
1462 .intr_event = SYSErr | LinkChg | RxOverflow |
1463 TxErr | TxOK | RxOK | RxErr,
1464 .napi_event = TxErr | TxOK | RxOK | RxOverflow
1465 },
1466 [RTL_CFG_2] = {
1467 .hw_start = rtl_hw_start_8101,
1468 .region = 2,
1469 .align = 8,
1470 .intr_event = SYSErr | LinkChg | RxOverflow | PCSTimeout |
1471 RxFIFOOver | TxErr | TxOK | RxOK | RxErr,
1472 .napi_event = RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow
1473 }
1474};
1475
1470static int __devinit 1476static int __devinit
1471rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) 1477rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
1472{ 1478{
1473 const unsigned int region = rtl_cfg_info[ent->driver_data].region; 1479 const struct rtl_cfg_info *cfg = rtl_cfg_infos + ent->driver_data;
1480 const unsigned int region = cfg->region;
1474 struct rtl8169_private *tp; 1481 struct rtl8169_private *tp;
1475 struct net_device *dev; 1482 struct net_device *dev;
1476 void __iomem *ioaddr; 1483 void __iomem *ioaddr;
1477 unsigned int pm_cap; 1484 unsigned int i;
1478 int i, rc; 1485 int rc;
1479 1486
1480 if (netif_msg_drv(&debug)) { 1487 if (netif_msg_drv(&debug)) {
1481 printk(KERN_INFO "%s Gigabit Ethernet driver %s loaded\n", 1488 printk(KERN_INFO "%s Gigabit Ethernet driver %s loaded\n",
@@ -1508,20 +1515,6 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
1508 if (rc < 0) 1515 if (rc < 0)
1509 goto err_out_disable_2; 1516 goto err_out_disable_2;
1510 1517
1511 /* save power state before pci_enable_device overwrites it */
1512 pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM);
1513 if (pm_cap) {
1514 u16 pwr_command, acpi_idle_state;
1515
1516 pci_read_config_word(pdev, pm_cap + PCI_PM_CTRL, &pwr_command);
1517 acpi_idle_state = pwr_command & PCI_PM_CTRL_STATE_MASK;
1518 } else {
1519 if (netif_msg_probe(tp)) {
1520 dev_err(&pdev->dev,
1521 "PowerManagement capability not found.\n");
1522 }
1523 }
1524
1525 /* make sure PCI base addr 1 is MMIO */ 1518 /* make sure PCI base addr 1 is MMIO */
1526 if (!(pci_resource_flags(pdev, region) & IORESOURCE_MEM)) { 1519 if (!(pci_resource_flags(pdev, region) & IORESOURCE_MEM)) {
1527 if (netif_msg_probe(tp)) { 1520 if (netif_msg_probe(tp)) {
@@ -1585,7 +1578,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
1585 RTL_W8(ChipCmd, CmdReset); 1578 RTL_W8(ChipCmd, CmdReset);
1586 1579
1587 /* Check that the chip has finished the reset. */ 1580 /* Check that the chip has finished the reset. */
1588 for (i = 100; i > 0; i--) { 1581 for (i = 0; i < 100; i++) {
1589 if ((RTL_R8(ChipCmd) & CmdReset) == 0) 1582 if ((RTL_R8(ChipCmd) & CmdReset) == 0)
1590 break; 1583 break;
1591 msleep_interruptible(1); 1584 msleep_interruptible(1);
@@ -1647,11 +1640,12 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
1647 SET_ETHTOOL_OPS(dev, &rtl8169_ethtool_ops); 1640 SET_ETHTOOL_OPS(dev, &rtl8169_ethtool_ops);
1648 dev->stop = rtl8169_close; 1641 dev->stop = rtl8169_close;
1649 dev->tx_timeout = rtl8169_tx_timeout; 1642 dev->tx_timeout = rtl8169_tx_timeout;
1650 dev->set_multicast_list = rtl8169_set_rx_mode; 1643 dev->set_multicast_list = rtl_set_rx_mode;
1651 dev->watchdog_timeo = RTL8169_TX_TIMEOUT; 1644 dev->watchdog_timeo = RTL8169_TX_TIMEOUT;
1652 dev->irq = pdev->irq; 1645 dev->irq = pdev->irq;
1653 dev->base_addr = (unsigned long) ioaddr; 1646 dev->base_addr = (unsigned long) ioaddr;
1654 dev->change_mtu = rtl8169_change_mtu; 1647 dev->change_mtu = rtl8169_change_mtu;
1648 dev->set_mac_address = rtl_set_mac_address;
1655 1649
1656#ifdef CONFIG_R8169_NAPI 1650#ifdef CONFIG_R8169_NAPI
1657 dev->poll = rtl8169_poll; 1651 dev->poll = rtl8169_poll;
@@ -1670,7 +1664,10 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
1670 tp->intr_mask = 0xffff; 1664 tp->intr_mask = 0xffff;
1671 tp->pci_dev = pdev; 1665 tp->pci_dev = pdev;
1672 tp->mmio_addr = ioaddr; 1666 tp->mmio_addr = ioaddr;
1673 tp->align = rtl_cfg_info[ent->driver_data].align; 1667 tp->align = cfg->align;
1668 tp->hw_start = cfg->hw_start;
1669 tp->intr_event = cfg->intr_event;
1670 tp->napi_event = cfg->napi_event;
1674 1671
1675 init_timer(&tp->timer); 1672 init_timer(&tp->timer);
1676 tp->timer.data = (unsigned long) dev; 1673 tp->timer.data = (unsigned long) dev;
@@ -1685,15 +1682,17 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
1685 pci_set_drvdata(pdev, dev); 1682 pci_set_drvdata(pdev, dev);
1686 1683
1687 if (netif_msg_probe(tp)) { 1684 if (netif_msg_probe(tp)) {
1685 u32 xid = RTL_R32(TxConfig) & 0x7cf0f8ff;
1686
1688 printk(KERN_INFO "%s: %s at 0x%lx, " 1687 printk(KERN_INFO "%s: %s at 0x%lx, "
1689 "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x, " 1688 "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x, "
1690 "IRQ %d\n", 1689 "XID %08x IRQ %d\n",
1691 dev->name, 1690 dev->name,
1692 rtl_chip_info[tp->chipset].name, 1691 rtl_chip_info[tp->chipset].name,
1693 dev->base_addr, 1692 dev->base_addr,
1694 dev->dev_addr[0], dev->dev_addr[1], 1693 dev->dev_addr[0], dev->dev_addr[1],
1695 dev->dev_addr[2], dev->dev_addr[3], 1694 dev->dev_addr[2], dev->dev_addr[3],
1696 dev->dev_addr[4], dev->dev_addr[5], dev->irq); 1695 dev->dev_addr[4], dev->dev_addr[5], xid, dev->irq);
1697 } 1696 }
1698 1697
1699 rtl8169_init_phy(dev, tp); 1698 rtl8169_init_phy(dev, tp);
@@ -1714,15 +1713,11 @@ err_out_free_dev_1:
1714 goto out; 1713 goto out;
1715} 1714}
1716 1715
1717static void __devexit 1716static void __devexit rtl8169_remove_one(struct pci_dev *pdev)
1718rtl8169_remove_one(struct pci_dev *pdev)
1719{ 1717{
1720 struct net_device *dev = pci_get_drvdata(pdev); 1718 struct net_device *dev = pci_get_drvdata(pdev);
1721 struct rtl8169_private *tp = netdev_priv(dev); 1719 struct rtl8169_private *tp = netdev_priv(dev);
1722 1720
1723 assert(dev != NULL);
1724 assert(tp != NULL);
1725
1726 flush_scheduled_work(); 1721 flush_scheduled_work();
1727 1722
1728 unregister_netdev(dev); 1723 unregister_netdev(dev);
@@ -1774,7 +1769,7 @@ static int rtl8169_open(struct net_device *dev)
1774 if (retval < 0) 1769 if (retval < 0)
1775 goto err_release_ring_2; 1770 goto err_release_ring_2;
1776 1771
1777 rtl8169_hw_start(dev); 1772 rtl_hw_start(dev);
1778 1773
1779 rtl8169_request_timer(dev); 1774 rtl8169_request_timer(dev);
1780 1775
@@ -1805,7 +1800,7 @@ static void rtl8169_hw_reset(void __iomem *ioaddr)
1805 RTL_R8(ChipCmd); 1800 RTL_R8(ChipCmd);
1806} 1801}
1807 1802
1808static void rtl8169_set_rx_tx_config_registers(struct rtl8169_private *tp) 1803static void rtl_set_rx_tx_config_registers(struct rtl8169_private *tp)
1809{ 1804{
1810 void __iomem *ioaddr = tp->mmio_addr; 1805 void __iomem *ioaddr = tp->mmio_addr;
1811 u32 cfg = rtl8169_rx_config; 1806 u32 cfg = rtl8169_rx_config;
@@ -1818,45 +1813,90 @@ static void rtl8169_set_rx_tx_config_registers(struct rtl8169_private *tp)
1818 (InterFrameGap << TxInterFrameGapShift)); 1813 (InterFrameGap << TxInterFrameGapShift));
1819} 1814}
1820 1815
1821static void rtl8169_hw_start(struct net_device *dev) 1816static void rtl_hw_start(struct net_device *dev)
1822{ 1817{
1823 struct rtl8169_private *tp = netdev_priv(dev); 1818 struct rtl8169_private *tp = netdev_priv(dev);
1824 void __iomem *ioaddr = tp->mmio_addr; 1819 void __iomem *ioaddr = tp->mmio_addr;
1825 struct pci_dev *pdev = tp->pci_dev; 1820 unsigned int i;
1826 u16 cmd;
1827 u32 i;
1828 1821
1829 /* Soft reset the chip. */ 1822 /* Soft reset the chip. */
1830 RTL_W8(ChipCmd, CmdReset); 1823 RTL_W8(ChipCmd, CmdReset);
1831 1824
1832 /* Check that the chip has finished the reset. */ 1825 /* Check that the chip has finished the reset. */
1833 for (i = 100; i > 0; i--) { 1826 for (i = 0; i < 100; i++) {
1834 if ((RTL_R8(ChipCmd) & CmdReset) == 0) 1827 if ((RTL_R8(ChipCmd) & CmdReset) == 0)
1835 break; 1828 break;
1836 msleep_interruptible(1); 1829 msleep_interruptible(1);
1837 } 1830 }
1838 1831
1839 if (tp->mac_version == RTL_GIGA_MAC_VER_05) { 1832 tp->hw_start(dev);
1840 RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) | PCIMulRW);
1841 pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, 0x08);
1842 }
1843 1833
1844 if (tp->mac_version == RTL_GIGA_MAC_VER_13) { 1834 netif_start_queue(dev);
1845 pci_write_config_word(pdev, 0x68, 0x00); 1835}
1846 pci_write_config_word(pdev, 0x69, 0x08);
1847 }
1848 1836
1849 /* Undocumented stuff. */
1850 if (tp->mac_version == RTL_GIGA_MAC_VER_05) {
1851 /* Realtek's r1000_n.c driver uses '&& 0x01' here. Well... */
1852 if ((RTL_R8(Config2) & 0x07) & 0x01)
1853 RTL_W32(0x7c, 0x0007ffff);
1854 1837
1855 RTL_W32(0x7c, 0x0007ff00); 1838static void rtl_set_rx_tx_desc_registers(struct rtl8169_private *tp,
1839 void __iomem *ioaddr)
1840{
1841 /*
1842 * Magic spell: some iop3xx ARM board needs the TxDescAddrHigh
1843 * register to be written before TxDescAddrLow to work.
1844 * Switching from MMIO to I/O access fixes the issue as well.
1845 */
1846 RTL_W32(TxDescStartAddrHigh, ((u64) tp->TxPhyAddr) >> 32);
1847 RTL_W32(TxDescStartAddrLow, ((u64) tp->TxPhyAddr) & DMA_32BIT_MASK);
1848 RTL_W32(RxDescAddrHigh, ((u64) tp->RxPhyAddr) >> 32);
1849 RTL_W32(RxDescAddrLow, ((u64) tp->RxPhyAddr) & DMA_32BIT_MASK);
1850}
1851
1852static u16 rtl_rw_cpluscmd(void __iomem *ioaddr)
1853{
1854 u16 cmd;
1855
1856 cmd = RTL_R16(CPlusCmd);
1857 RTL_W16(CPlusCmd, cmd);
1858 return cmd;
1859}
1860
1861static void rtl_set_rx_max_size(void __iomem *ioaddr)
1862{
1863 /* Low hurts. Let's disable the filtering. */
1864 RTL_W16(RxMaxSize, 16383);
1865}
1866
1867static void rtl8169_set_magic_reg(void __iomem *ioaddr, unsigned mac_version)
1868{
1869 struct {
1870 u32 mac_version;
1871 u32 clk;
1872 u32 val;
1873 } cfg2_info [] = {
1874 { RTL_GIGA_MAC_VER_05, PCI_Clock_33MHz, 0x000fff00 }, // 8110SCd
1875 { RTL_GIGA_MAC_VER_05, PCI_Clock_66MHz, 0x000fffff },
1876 { RTL_GIGA_MAC_VER_06, PCI_Clock_33MHz, 0x00ffff00 }, // 8110SCe
1877 { RTL_GIGA_MAC_VER_06, PCI_Clock_66MHz, 0x00ffffff }
1878 }, *p = cfg2_info;
1879 unsigned int i;
1880 u32 clk;
1856 1881
1857 pci_read_config_word(pdev, PCI_COMMAND, &cmd); 1882 clk = RTL_R8(Config2) & PCI_Clock_66MHz;
1858 cmd = cmd & 0xef; 1883 for (i = 0; i < ARRAY_SIZE(cfg2_info); i++) {
1859 pci_write_config_word(pdev, PCI_COMMAND, cmd); 1884 if ((p->mac_version == mac_version) && (p->clk == clk)) {
1885 RTL_W32(0x7c, p->val);
1886 break;
1887 }
1888 }
1889}
1890
1891static void rtl_hw_start_8169(struct net_device *dev)
1892{
1893 struct rtl8169_private *tp = netdev_priv(dev);
1894 void __iomem *ioaddr = tp->mmio_addr;
1895 struct pci_dev *pdev = tp->pci_dev;
1896
1897 if (tp->mac_version == RTL_GIGA_MAC_VER_05) {
1898 RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) | PCIMulRW);
1899 pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, 0x08);
1860 } 1900 }
1861 1901
1862 RTL_W8(Cfg9346, Cfg9346_Unlock); 1902 RTL_W8(Cfg9346, Cfg9346_Unlock);
@@ -1868,19 +1908,11 @@ static void rtl8169_hw_start(struct net_device *dev)
1868 1908
1869 RTL_W8(EarlyTxThres, EarlyTxThld); 1909 RTL_W8(EarlyTxThres, EarlyTxThld);
1870 1910
1871 /* Low hurts. Let's disable the filtering. */ 1911 rtl_set_rx_max_size(ioaddr);
1872 RTL_W16(RxMaxSize, 16383);
1873
1874 if ((tp->mac_version == RTL_GIGA_MAC_VER_01) ||
1875 (tp->mac_version == RTL_GIGA_MAC_VER_02) ||
1876 (tp->mac_version == RTL_GIGA_MAC_VER_03) ||
1877 (tp->mac_version == RTL_GIGA_MAC_VER_04))
1878 rtl8169_set_rx_tx_config_registers(tp);
1879 1912
1880 cmd = RTL_R16(CPlusCmd); 1913 rtl_set_rx_tx_config_registers(tp);
1881 RTL_W16(CPlusCmd, cmd);
1882 1914
1883 tp->cp_cmd |= cmd | PCIMulRW; 1915 tp->cp_cmd |= rtl_rw_cpluscmd(ioaddr) | PCIMulRW;
1884 1916
1885 if ((tp->mac_version == RTL_GIGA_MAC_VER_02) || 1917 if ((tp->mac_version == RTL_GIGA_MAC_VER_02) ||
1886 (tp->mac_version == RTL_GIGA_MAC_VER_03)) { 1918 (tp->mac_version == RTL_GIGA_MAC_VER_03)) {
@@ -1891,29 +1923,15 @@ static void rtl8169_hw_start(struct net_device *dev)
1891 1923
1892 RTL_W16(CPlusCmd, tp->cp_cmd); 1924 RTL_W16(CPlusCmd, tp->cp_cmd);
1893 1925
1926 rtl8169_set_magic_reg(ioaddr, tp->mac_version);
1927
1894 /* 1928 /*
1895 * Undocumented corner. Supposedly: 1929 * Undocumented corner. Supposedly:
1896 * (TxTimer << 12) | (TxPackets << 8) | (RxTimer << 4) | RxPackets 1930 * (TxTimer << 12) | (TxPackets << 8) | (RxTimer << 4) | RxPackets
1897 */ 1931 */
1898 RTL_W16(IntrMitigate, 0x0000); 1932 RTL_W16(IntrMitigate, 0x0000);
1899 1933
1900 /* 1934 rtl_set_rx_tx_desc_registers(tp, ioaddr);
1901 * Magic spell: some iop3xx ARM board needs the TxDescAddrHigh
1902 * register to be written before TxDescAddrLow to work.
1903 * Switching from MMIO to I/O access fixes the issue as well.
1904 */
1905 RTL_W32(TxDescStartAddrHigh, ((u64) tp->TxPhyAddr >> 32));
1906 RTL_W32(TxDescStartAddrLow, ((u64) tp->TxPhyAddr & DMA_32BIT_MASK));
1907 RTL_W32(RxDescAddrHigh, ((u64) tp->RxPhyAddr >> 32));
1908 RTL_W32(RxDescAddrLow, ((u64) tp->RxPhyAddr & DMA_32BIT_MASK));
1909
1910 if ((tp->mac_version != RTL_GIGA_MAC_VER_01) &&
1911 (tp->mac_version != RTL_GIGA_MAC_VER_02) &&
1912 (tp->mac_version != RTL_GIGA_MAC_VER_03) &&
1913 (tp->mac_version != RTL_GIGA_MAC_VER_04)) {
1914 RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
1915 rtl8169_set_rx_tx_config_registers(tp);
1916 }
1917 1935
1918 RTL_W8(Cfg9346, Cfg9346_Lock); 1936 RTL_W8(Cfg9346, Cfg9346_Lock);
1919 1937
@@ -1922,15 +1940,107 @@ static void rtl8169_hw_start(struct net_device *dev)
1922 1940
1923 RTL_W32(RxMissed, 0); 1941 RTL_W32(RxMissed, 0);
1924 1942
1925 rtl8169_set_rx_mode(dev); 1943 rtl_set_rx_mode(dev);
1926 1944
1927 /* no early-rx interrupts */ 1945 /* no early-rx interrupts */
1928 RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xF000); 1946 RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xF000);
1929 1947
1930 /* Enable all known interrupts by setting the interrupt mask. */ 1948 /* Enable all known interrupts by setting the interrupt mask. */
1931 RTL_W16(IntrMask, rtl8169_intr_mask); 1949 RTL_W16(IntrMask, tp->intr_event);
1932 1950
1933 netif_start_queue(dev); 1951 RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
1952}
1953
1954static void rtl_hw_start_8168(struct net_device *dev)
1955{
1956 struct rtl8169_private *tp = netdev_priv(dev);
1957 void __iomem *ioaddr = tp->mmio_addr;
1958 struct pci_dev *pdev = tp->pci_dev;
1959 u8 ctl;
1960
1961 RTL_W8(Cfg9346, Cfg9346_Unlock);
1962
1963 RTL_W8(EarlyTxThres, EarlyTxThld);
1964
1965 rtl_set_rx_max_size(ioaddr);
1966
1967 rtl_set_rx_tx_config_registers(tp);
1968
1969 tp->cp_cmd |= RTL_R16(CPlusCmd) | PktCntrDisable | INTT_1;
1970
1971 RTL_W16(CPlusCmd, tp->cp_cmd);
1972
1973 /* Tx performance tweak. */
1974 pci_read_config_byte(pdev, 0x69, &ctl);
1975 ctl = (ctl & ~0x70) | 0x50;
1976 pci_write_config_byte(pdev, 0x69, ctl);
1977
1978 RTL_W16(IntrMitigate, 0x5151);
1979
1980 /* Work around for RxFIFO overflow. */
1981 if (tp->mac_version == RTL_GIGA_MAC_VER_11) {
1982 tp->intr_event |= RxFIFOOver | PCSTimeout;
1983 tp->intr_event &= ~RxOverflow;
1984 }
1985
1986 rtl_set_rx_tx_desc_registers(tp, ioaddr);
1987
1988 RTL_W8(Cfg9346, Cfg9346_Lock);
1989
1990 RTL_R8(IntrMask);
1991
1992 RTL_W32(RxMissed, 0);
1993
1994 rtl_set_rx_mode(dev);
1995
1996 RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
1997
1998 RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xF000);
1999
2000 RTL_W16(IntrMask, tp->intr_event);
2001}
2002
2003static void rtl_hw_start_8101(struct net_device *dev)
2004{
2005 struct rtl8169_private *tp = netdev_priv(dev);
2006 void __iomem *ioaddr = tp->mmio_addr;
2007 struct pci_dev *pdev = tp->pci_dev;
2008
2009 if (tp->mac_version == RTL_GIGA_MAC_VER_13) {
2010 pci_write_config_word(pdev, 0x68, 0x00);
2011 pci_write_config_word(pdev, 0x69, 0x08);
2012 }
2013
2014 RTL_W8(Cfg9346, Cfg9346_Unlock);
2015
2016 RTL_W8(EarlyTxThres, EarlyTxThld);
2017
2018 rtl_set_rx_max_size(ioaddr);
2019
2020 tp->cp_cmd |= rtl_rw_cpluscmd(ioaddr) | PCIMulRW;
2021
2022 RTL_W16(CPlusCmd, tp->cp_cmd);
2023
2024 RTL_W16(IntrMitigate, 0x0000);
2025
2026 rtl_set_rx_tx_desc_registers(tp, ioaddr);
2027
2028 RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
2029 rtl_set_rx_tx_config_registers(tp);
2030
2031 RTL_W8(Cfg9346, Cfg9346_Lock);
2032
2033 RTL_R8(IntrMask);
2034
2035 RTL_W32(RxMissed, 0);
2036
2037 rtl_set_rx_mode(dev);
2038
2039 RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
2040
2041 RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xf000);
2042
2043 RTL_W16(IntrMask, tp->intr_event);
1934} 2044}
1935 2045
1936static int rtl8169_change_mtu(struct net_device *dev, int new_mtu) 2046static int rtl8169_change_mtu(struct net_device *dev, int new_mtu)
@@ -1956,7 +2066,7 @@ static int rtl8169_change_mtu(struct net_device *dev, int new_mtu)
1956 2066
1957 netif_poll_enable(dev); 2067 netif_poll_enable(dev);
1958 2068
1959 rtl8169_hw_start(dev); 2069 rtl_hw_start(dev);
1960 2070
1961 rtl8169_request_timer(dev); 2071 rtl8169_request_timer(dev);
1962 2072
@@ -1997,38 +2107,38 @@ static inline void rtl8169_map_to_asic(struct RxDesc *desc, dma_addr_t mapping,
1997 rtl8169_mark_to_asic(desc, rx_buf_sz); 2107 rtl8169_mark_to_asic(desc, rx_buf_sz);
1998} 2108}
1999 2109
2000static int rtl8169_alloc_rx_skb(struct pci_dev *pdev, struct sk_buff **sk_buff, 2110static struct sk_buff *rtl8169_alloc_rx_skb(struct pci_dev *pdev,
2001 struct RxDesc *desc, int rx_buf_sz, 2111 struct net_device *dev,
2002 unsigned int align) 2112 struct RxDesc *desc, int rx_buf_sz,
2113 unsigned int align)
2003{ 2114{
2004 struct sk_buff *skb; 2115 struct sk_buff *skb;
2005 dma_addr_t mapping; 2116 dma_addr_t mapping;
2006 int ret = 0; 2117 unsigned int pad;
2007 2118
2008 skb = dev_alloc_skb(rx_buf_sz + align); 2119 pad = align ? align : NET_IP_ALIGN;
2120
2121 skb = netdev_alloc_skb(dev, rx_buf_sz + pad);
2009 if (!skb) 2122 if (!skb)
2010 goto err_out; 2123 goto err_out;
2011 2124
2012 skb_reserve(skb, (align - 1) & (unsigned long)skb->data); 2125 skb_reserve(skb, align ? ((pad - 1) & (unsigned long)skb->data) : pad);
2013 *sk_buff = skb;
2014 2126
2015 mapping = pci_map_single(pdev, skb->data, rx_buf_sz, 2127 mapping = pci_map_single(pdev, skb->data, rx_buf_sz,
2016 PCI_DMA_FROMDEVICE); 2128 PCI_DMA_FROMDEVICE);
2017 2129
2018 rtl8169_map_to_asic(desc, mapping, rx_buf_sz); 2130 rtl8169_map_to_asic(desc, mapping, rx_buf_sz);
2019
2020out: 2131out:
2021 return ret; 2132 return skb;
2022 2133
2023err_out: 2134err_out:
2024 ret = -ENOMEM;
2025 rtl8169_make_unusable_by_asic(desc); 2135 rtl8169_make_unusable_by_asic(desc);
2026 goto out; 2136 goto out;
2027} 2137}
2028 2138
2029static void rtl8169_rx_clear(struct rtl8169_private *tp) 2139static void rtl8169_rx_clear(struct rtl8169_private *tp)
2030{ 2140{
2031 int i; 2141 unsigned int i;
2032 2142
2033 for (i = 0; i < NUM_RX_DESC; i++) { 2143 for (i = 0; i < NUM_RX_DESC; i++) {
2034 if (tp->Rx_skbuff[i]) { 2144 if (tp->Rx_skbuff[i]) {
@@ -2043,16 +2153,22 @@ static u32 rtl8169_rx_fill(struct rtl8169_private *tp, struct net_device *dev,
2043{ 2153{
2044 u32 cur; 2154 u32 cur;
2045 2155
2046 for (cur = start; end - cur > 0; cur++) { 2156 for (cur = start; end - cur != 0; cur++) {
2047 int ret, i = cur % NUM_RX_DESC; 2157 struct sk_buff *skb;
2158 unsigned int i = cur % NUM_RX_DESC;
2159
2160 WARN_ON((s32)(end - cur) < 0);
2048 2161
2049 if (tp->Rx_skbuff[i]) 2162 if (tp->Rx_skbuff[i])
2050 continue; 2163 continue;
2051 2164
2052 ret = rtl8169_alloc_rx_skb(tp->pci_dev, tp->Rx_skbuff + i, 2165 skb = rtl8169_alloc_rx_skb(tp->pci_dev, dev,
2053 tp->RxDescArray + i, tp->rx_buf_sz, tp->align); 2166 tp->RxDescArray + i,
2054 if (ret < 0) 2167 tp->rx_buf_sz, tp->align);
2168 if (!skb)
2055 break; 2169 break;
2170
2171 tp->Rx_skbuff[i] = skb;
2056 } 2172 }
2057 return cur - start; 2173 return cur - start;
2058} 2174}
@@ -2164,14 +2280,9 @@ static void rtl8169_reinit_task(struct work_struct *work)
2164 2280
2165 ret = rtl8169_open(dev); 2281 ret = rtl8169_open(dev);
2166 if (unlikely(ret < 0)) { 2282 if (unlikely(ret < 0)) {
2167 if (net_ratelimit()) { 2283 if (net_ratelimit() && netif_msg_drv(tp)) {
2168 struct rtl8169_private *tp = netdev_priv(dev); 2284 printk(PFX KERN_ERR "%s: reinit failure (status = %d)."
2169 2285 " Rescheduling.\n", dev->name, ret);
2170 if (netif_msg_drv(tp)) {
2171 printk(PFX KERN_ERR
2172 "%s: reinit failure (status = %d)."
2173 " Rescheduling.\n", dev->name, ret);
2174 }
2175 } 2286 }
2176 rtl8169_schedule_work(dev, rtl8169_reinit_task); 2287 rtl8169_schedule_work(dev, rtl8169_reinit_task);
2177 } 2288 }
@@ -2198,16 +2309,12 @@ static void rtl8169_reset_task(struct work_struct *work)
2198 2309
2199 if (tp->dirty_rx == tp->cur_rx) { 2310 if (tp->dirty_rx == tp->cur_rx) {
2200 rtl8169_init_ring_indexes(tp); 2311 rtl8169_init_ring_indexes(tp);
2201 rtl8169_hw_start(dev); 2312 rtl_hw_start(dev);
2202 netif_wake_queue(dev); 2313 netif_wake_queue(dev);
2203 } else { 2314 } else {
2204 if (net_ratelimit()) { 2315 if (net_ratelimit() && netif_msg_intr(tp)) {
2205 struct rtl8169_private *tp = netdev_priv(dev); 2316 printk(PFX KERN_EMERG "%s: Rx buffers shortage\n",
2206 2317 dev->name);
2207 if (netif_msg_intr(tp)) {
2208 printk(PFX KERN_EMERG
2209 "%s: Rx buffers shortage\n", dev->name);
2210 }
2211 } 2318 }
2212 rtl8169_schedule_work(dev, rtl8169_reset_task); 2319 rtl8169_schedule_work(dev, rtl8169_reset_task);
2213 } 2320 }
@@ -2344,7 +2451,7 @@ static int rtl8169_start_xmit(struct sk_buff *skb, struct net_device *dev)
2344 2451
2345 smp_wmb(); 2452 smp_wmb();
2346 2453
2347 RTL_W8(TxPoll, 0x40); /* set polling bit */ 2454 RTL_W8(TxPoll, NPQ); /* set polling bit */
2348 2455
2349 if (TX_BUFFS_AVAIL(tp) < MAX_SKB_FRAGS) { 2456 if (TX_BUFFS_AVAIL(tp) < MAX_SKB_FRAGS) {
2350 netif_stop_queue(dev); 2457 netif_stop_queue(dev);
@@ -2414,16 +2521,12 @@ static void rtl8169_pcierr_interrupt(struct net_device *dev)
2414 rtl8169_schedule_work(dev, rtl8169_reinit_task); 2521 rtl8169_schedule_work(dev, rtl8169_reinit_task);
2415} 2522}
2416 2523
2417static void 2524static void rtl8169_tx_interrupt(struct net_device *dev,
2418rtl8169_tx_interrupt(struct net_device *dev, struct rtl8169_private *tp, 2525 struct rtl8169_private *tp,
2419 void __iomem *ioaddr) 2526 void __iomem *ioaddr)
2420{ 2527{
2421 unsigned int dirty_tx, tx_left; 2528 unsigned int dirty_tx, tx_left;
2422 2529
2423 assert(dev != NULL);
2424 assert(tp != NULL);
2425 assert(ioaddr != NULL);
2426
2427 dirty_tx = tp->dirty_tx; 2530 dirty_tx = tp->dirty_tx;
2428 smp_rmb(); 2531 smp_rmb();
2429 tx_left = tp->cur_tx - dirty_tx; 2532 tx_left = tp->cur_tx - dirty_tx;
@@ -2480,38 +2583,37 @@ static inline void rtl8169_rx_csum(struct sk_buff *skb, struct RxDesc *desc)
2480 skb->ip_summed = CHECKSUM_NONE; 2583 skb->ip_summed = CHECKSUM_NONE;
2481} 2584}
2482 2585
2483static inline int rtl8169_try_rx_copy(struct sk_buff **sk_buff, int pkt_size, 2586static inline bool rtl8169_try_rx_copy(struct sk_buff **sk_buff,
2484 struct RxDesc *desc, int rx_buf_sz, 2587 struct rtl8169_private *tp, int pkt_size,
2485 unsigned int align) 2588 dma_addr_t addr)
2486{ 2589{
2487 int ret = -1; 2590 struct sk_buff *skb;
2591 bool done = false;
2488 2592
2489 if (pkt_size < rx_copybreak) { 2593 if (pkt_size >= rx_copybreak)
2490 struct sk_buff *skb; 2594 goto out;
2491 2595
2492 skb = dev_alloc_skb(pkt_size + align); 2596 skb = netdev_alloc_skb(tp->dev, pkt_size + NET_IP_ALIGN);
2493 if (skb) { 2597 if (!skb)
2494 skb_reserve(skb, (align - 1) & (unsigned long)skb->data); 2598 goto out;
2495 eth_copy_and_sum(skb, sk_buff[0]->data, pkt_size, 0); 2599
2496 *sk_buff = skb; 2600 pci_dma_sync_single_for_cpu(tp->pci_dev, addr, pkt_size,
2497 rtl8169_mark_to_asic(desc, rx_buf_sz); 2601 PCI_DMA_FROMDEVICE);
2498 ret = 0; 2602 skb_reserve(skb, NET_IP_ALIGN);
2499 } 2603 skb_copy_from_linear_data(*sk_buff, skb->data, pkt_size);
2500 } 2604 *sk_buff = skb;
2501 return ret; 2605 done = true;
2606out:
2607 return done;
2502} 2608}
2503 2609
2504static int 2610static int rtl8169_rx_interrupt(struct net_device *dev,
2505rtl8169_rx_interrupt(struct net_device *dev, struct rtl8169_private *tp, 2611 struct rtl8169_private *tp,
2506 void __iomem *ioaddr) 2612 void __iomem *ioaddr)
2507{ 2613{
2508 unsigned int cur_rx, rx_left; 2614 unsigned int cur_rx, rx_left;
2509 unsigned int delta, count; 2615 unsigned int delta, count;
2510 2616
2511 assert(dev != NULL);
2512 assert(tp != NULL);
2513 assert(ioaddr != NULL);
2514
2515 cur_rx = tp->cur_rx; 2617 cur_rx = tp->cur_rx;
2516 rx_left = NUM_RX_DESC + tp->dirty_rx - cur_rx; 2618 rx_left = NUM_RX_DESC + tp->dirty_rx - cur_rx;
2517 rx_left = rtl8169_rx_quota(rx_left, (u32) dev->quota); 2619 rx_left = rtl8169_rx_quota(rx_left, (u32) dev->quota);
@@ -2544,9 +2646,9 @@ rtl8169_rx_interrupt(struct net_device *dev, struct rtl8169_private *tp,
2544 rtl8169_mark_to_asic(desc, tp->rx_buf_sz); 2646 rtl8169_mark_to_asic(desc, tp->rx_buf_sz);
2545 } else { 2647 } else {
2546 struct sk_buff *skb = tp->Rx_skbuff[entry]; 2648 struct sk_buff *skb = tp->Rx_skbuff[entry];
2649 dma_addr_t addr = le64_to_cpu(desc->addr);
2547 int pkt_size = (status & 0x00001FFF) - 4; 2650 int pkt_size = (status & 0x00001FFF) - 4;
2548 void (*pci_action)(struct pci_dev *, dma_addr_t, 2651 struct pci_dev *pdev = tp->pci_dev;
2549 size_t, int) = pci_dma_sync_single_for_device;
2550 2652
2551 /* 2653 /*
2552 * The driver does not support incoming fragmented 2654 * The driver does not support incoming fragmented
@@ -2562,19 +2664,16 @@ rtl8169_rx_interrupt(struct net_device *dev, struct rtl8169_private *tp,
2562 2664
2563 rtl8169_rx_csum(skb, desc); 2665 rtl8169_rx_csum(skb, desc);
2564 2666
2565 pci_dma_sync_single_for_cpu(tp->pci_dev, 2667 if (rtl8169_try_rx_copy(&skb, tp, pkt_size, addr)) {
2566 le64_to_cpu(desc->addr), tp->rx_buf_sz, 2668 pci_dma_sync_single_for_device(pdev, addr,
2567 PCI_DMA_FROMDEVICE); 2669 pkt_size, PCI_DMA_FROMDEVICE);
2568 2670 rtl8169_mark_to_asic(desc, tp->rx_buf_sz);
2569 if (rtl8169_try_rx_copy(&skb, pkt_size, desc, 2671 } else {
2570 tp->rx_buf_sz, tp->align)) { 2672 pci_unmap_single(pdev, addr, pkt_size,
2571 pci_action = pci_unmap_single; 2673 PCI_DMA_FROMDEVICE);
2572 tp->Rx_skbuff[entry] = NULL; 2674 tp->Rx_skbuff[entry] = NULL;
2573 } 2675 }
2574 2676
2575 pci_action(tp->pci_dev, le64_to_cpu(desc->addr),
2576 tp->rx_buf_sz, PCI_DMA_FROMDEVICE);
2577
2578 skb_put(skb, pkt_size); 2677 skb_put(skb, pkt_size);
2579 skb->protocol = eth_type_trans(skb, dev); 2678 skb->protocol = eth_type_trans(skb, dev);
2580 2679
@@ -2585,6 +2684,13 @@ rtl8169_rx_interrupt(struct net_device *dev, struct rtl8169_private *tp,
2585 tp->stats.rx_bytes += pkt_size; 2684 tp->stats.rx_bytes += pkt_size;
2586 tp->stats.rx_packets++; 2685 tp->stats.rx_packets++;
2587 } 2686 }
2687
2688 /* Work around for AMD plateform. */
2689 if ((desc->opts2 & 0xfffe000) &&
2690 (tp->mac_version == RTL_GIGA_MAC_VER_05)) {
2691 desc->opts2 = 0;
2692 cur_rx++;
2693 }
2588 } 2694 }
2589 2695
2590 count = cur_rx - tp->cur_rx; 2696 count = cur_rx - tp->cur_rx;
@@ -2608,11 +2714,9 @@ rtl8169_rx_interrupt(struct net_device *dev, struct rtl8169_private *tp,
2608 return count; 2714 return count;
2609} 2715}
2610 2716
2611/* The interrupt handler does all of the Rx thread work and cleans up after the Tx thread. */ 2717static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance)
2612static irqreturn_t
2613rtl8169_interrupt(int irq, void *dev_instance)
2614{ 2718{
2615 struct net_device *dev = (struct net_device *) dev_instance; 2719 struct net_device *dev = dev_instance;
2616 struct rtl8169_private *tp = netdev_priv(dev); 2720 struct rtl8169_private *tp = netdev_priv(dev);
2617 int boguscnt = max_interrupt_work; 2721 int boguscnt = max_interrupt_work;
2618 void __iomem *ioaddr = tp->mmio_addr; 2722 void __iomem *ioaddr = tp->mmio_addr;
@@ -2637,9 +2741,17 @@ rtl8169_interrupt(int irq, void *dev_instance)
2637 RTL_W16(IntrStatus, 2741 RTL_W16(IntrStatus,
2638 (status & RxFIFOOver) ? (status | RxOverflow) : status); 2742 (status & RxFIFOOver) ? (status | RxOverflow) : status);
2639 2743
2640 if (!(status & rtl8169_intr_mask)) 2744 if (!(status & tp->intr_event))
2641 break; 2745 break;
2642 2746
2747 /* Work around for rx fifo overflow */
2748 if (unlikely(status & RxFIFOOver) &&
2749 (tp->mac_version == RTL_GIGA_MAC_VER_11)) {
2750 netif_stop_queue(dev);
2751 rtl8169_tx_timeout(dev);
2752 break;
2753 }
2754
2643 if (unlikely(status & SYSErr)) { 2755 if (unlikely(status & SYSErr)) {
2644 rtl8169_pcierr_interrupt(dev); 2756 rtl8169_pcierr_interrupt(dev);
2645 break; 2757 break;
@@ -2649,8 +2761,8 @@ rtl8169_interrupt(int irq, void *dev_instance)
2649 rtl8169_check_link_status(dev, tp, ioaddr); 2761 rtl8169_check_link_status(dev, tp, ioaddr);
2650 2762
2651#ifdef CONFIG_R8169_NAPI 2763#ifdef CONFIG_R8169_NAPI
2652 RTL_W16(IntrMask, rtl8169_intr_mask & ~rtl8169_napi_event); 2764 RTL_W16(IntrMask, tp->intr_event & ~tp->napi_event);
2653 tp->intr_mask = ~rtl8169_napi_event; 2765 tp->intr_mask = ~tp->napi_event;
2654 2766
2655 if (likely(netif_rx_schedule_prep(dev))) 2767 if (likely(netif_rx_schedule_prep(dev)))
2656 __netif_rx_schedule(dev); 2768 __netif_rx_schedule(dev);
@@ -2661,9 +2773,9 @@ rtl8169_interrupt(int irq, void *dev_instance)
2661 break; 2773 break;
2662#else 2774#else
2663 /* Rx interrupt */ 2775 /* Rx interrupt */
2664 if (status & (RxOK | RxOverflow | RxFIFOOver)) { 2776 if (status & (RxOK | RxOverflow | RxFIFOOver))
2665 rtl8169_rx_interrupt(dev, tp, ioaddr); 2777 rtl8169_rx_interrupt(dev, tp, ioaddr);
2666 } 2778
2667 /* Tx interrupt */ 2779 /* Tx interrupt */
2668 if (status & (TxOK | TxErr)) 2780 if (status & (TxOK | TxErr))
2669 rtl8169_tx_interrupt(dev, tp, ioaddr); 2781 rtl8169_tx_interrupt(dev, tp, ioaddr);
@@ -2707,7 +2819,7 @@ static int rtl8169_poll(struct net_device *dev, int *budget)
2707 * write is safe - FR 2819 * write is safe - FR
2708 */ 2820 */
2709 smp_wmb(); 2821 smp_wmb();
2710 RTL_W16(IntrMask, rtl8169_intr_mask); 2822 RTL_W16(IntrMask, tp->intr_event);
2711 } 2823 }
2712 2824
2713 return (work_done >= work_to_do); 2825 return (work_done >= work_to_do);
@@ -2789,14 +2901,13 @@ static int rtl8169_close(struct net_device *dev)
2789 return 0; 2901 return 0;
2790} 2902}
2791 2903
2792static void 2904static void rtl_set_rx_mode(struct net_device *dev)
2793rtl8169_set_rx_mode(struct net_device *dev)
2794{ 2905{
2795 struct rtl8169_private *tp = netdev_priv(dev); 2906 struct rtl8169_private *tp = netdev_priv(dev);
2796 void __iomem *ioaddr = tp->mmio_addr; 2907 void __iomem *ioaddr = tp->mmio_addr;
2797 unsigned long flags; 2908 unsigned long flags;
2798 u32 mc_filter[2]; /* Multicast hash filter */ 2909 u32 mc_filter[2]; /* Multicast hash filter */
2799 int i, rx_mode; 2910 int rx_mode;
2800 u32 tmp = 0; 2911 u32 tmp = 0;
2801 2912
2802 if (dev->flags & IFF_PROMISC) { 2913 if (dev->flags & IFF_PROMISC) {
@@ -2816,6 +2927,8 @@ rtl8169_set_rx_mode(struct net_device *dev)
2816 mc_filter[1] = mc_filter[0] = 0xffffffff; 2927 mc_filter[1] = mc_filter[0] = 0xffffffff;
2817 } else { 2928 } else {
2818 struct dev_mc_list *mclist; 2929 struct dev_mc_list *mclist;
2930 unsigned int i;
2931
2819 rx_mode = AcceptBroadcast | AcceptMyPhys; 2932 rx_mode = AcceptBroadcast | AcceptMyPhys;
2820 mc_filter[1] = mc_filter[0] = 0; 2933 mc_filter[1] = mc_filter[0] = 0;
2821 for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count; 2934 for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
@@ -2840,10 +2953,11 @@ rtl8169_set_rx_mode(struct net_device *dev)
2840 mc_filter[1] = 0xffffffff; 2953 mc_filter[1] = 0xffffffff;
2841 } 2954 }
2842 2955
2843 RTL_W32(RxConfig, tmp);
2844 RTL_W32(MAR0 + 0, mc_filter[0]); 2956 RTL_W32(MAR0 + 0, mc_filter[0]);
2845 RTL_W32(MAR0 + 4, mc_filter[1]); 2957 RTL_W32(MAR0 + 4, mc_filter[1]);
2846 2958
2959 RTL_W32(RxConfig, tmp);
2960
2847 spin_unlock_irqrestore(&tp->lock, flags); 2961 spin_unlock_irqrestore(&tp->lock, flags);
2848} 2962}
2849 2963
@@ -2931,14 +3045,12 @@ static struct pci_driver rtl8169_pci_driver = {
2931#endif 3045#endif
2932}; 3046};
2933 3047
2934static int __init 3048static int __init rtl8169_init_module(void)
2935rtl8169_init_module(void)
2936{ 3049{
2937 return pci_register_driver(&rtl8169_pci_driver); 3050 return pci_register_driver(&rtl8169_pci_driver);
2938} 3051}
2939 3052
2940static void __exit 3053static void __exit rtl8169_cleanup_module(void)
2941rtl8169_cleanup_module(void)
2942{ 3054{
2943 pci_unregister_driver(&rtl8169_pci_driver); 3055 pci_unregister_driver(&rtl8169_pci_driver);
2944} 3056}
diff --git a/drivers/net/rrunner.c b/drivers/net/rrunner.c
index 25c73d47daad..5c2e41fac6d2 100644
--- a/drivers/net/rrunner.c
+++ b/drivers/net/rrunner.c
@@ -516,7 +516,7 @@ static unsigned int write_eeprom(struct rr_private *rrpriv,
516} 516}
517 517
518 518
519static int __init rr_init(struct net_device *dev) 519static int __devinit rr_init(struct net_device *dev)
520{ 520{
521 struct rr_private *rrpriv; 521 struct rr_private *rrpriv;
522 struct rr_regs __iomem *regs; 522 struct rr_regs __iomem *regs;
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index 09078ff84cd2..fa29a403a247 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -469,11 +469,18 @@ static struct pci_device_id s2io_tbl[] __devinitdata = {
469 469
470MODULE_DEVICE_TABLE(pci, s2io_tbl); 470MODULE_DEVICE_TABLE(pci, s2io_tbl);
471 471
472static struct pci_error_handlers s2io_err_handler = {
473 .error_detected = s2io_io_error_detected,
474 .slot_reset = s2io_io_slot_reset,
475 .resume = s2io_io_resume,
476};
477
472static struct pci_driver s2io_driver = { 478static struct pci_driver s2io_driver = {
473 .name = "S2IO", 479 .name = "S2IO",
474 .id_table = s2io_tbl, 480 .id_table = s2io_tbl,
475 .probe = s2io_init_nic, 481 .probe = s2io_init_nic,
476 .remove = __devexit_p(s2io_rem_nic), 482 .remove = __devexit_p(s2io_rem_nic),
483 .err_handler = &s2io_err_handler,
477}; 484};
478 485
479/* A simplifier macro used both by init and free shared_mem Fns(). */ 486/* A simplifier macro used both by init and free shared_mem Fns(). */
@@ -2689,6 +2696,9 @@ static void s2io_netpoll(struct net_device *dev)
2689 u64 val64 = 0xFFFFFFFFFFFFFFFFULL; 2696 u64 val64 = 0xFFFFFFFFFFFFFFFFULL;
2690 int i; 2697 int i;
2691 2698
2699 if (pci_channel_offline(nic->pdev))
2700 return;
2701
2692 disable_irq(dev->irq); 2702 disable_irq(dev->irq);
2693 2703
2694 atomic_inc(&nic->isr_cnt); 2704 atomic_inc(&nic->isr_cnt);
@@ -3215,6 +3225,8 @@ static void alarm_intr_handler(struct s2io_nic *nic)
3215 int i; 3225 int i;
3216 if (atomic_read(&nic->card_state) == CARD_DOWN) 3226 if (atomic_read(&nic->card_state) == CARD_DOWN)
3217 return; 3227 return;
3228 if (pci_channel_offline(nic->pdev))
3229 return;
3218 nic->mac_control.stats_info->sw_stat.ring_full_cnt = 0; 3230 nic->mac_control.stats_info->sw_stat.ring_full_cnt = 0;
3219 /* Handling the XPAK counters update */ 3231 /* Handling the XPAK counters update */
3220 if(nic->mac_control.stats_info->xpak_stat.xpak_timer_count < 72000) { 3232 if(nic->mac_control.stats_info->xpak_stat.xpak_timer_count < 72000) {
@@ -3958,7 +3970,6 @@ static int s2io_close(struct net_device *dev)
3958 /* Reset card, kill tasklet and free Tx and Rx buffers. */ 3970 /* Reset card, kill tasklet and free Tx and Rx buffers. */
3959 s2io_card_down(sp); 3971 s2io_card_down(sp);
3960 3972
3961 sp->device_close_flag = TRUE; /* Device is shut down. */
3962 return 0; 3973 return 0;
3963} 3974}
3964 3975
@@ -4314,6 +4325,10 @@ static irqreturn_t s2io_isr(int irq, void *dev_id)
4314 struct mac_info *mac_control; 4325 struct mac_info *mac_control;
4315 struct config_param *config; 4326 struct config_param *config;
4316 4327
4328 /* Pretend we handled any irq's from a disconnected card */
4329 if (pci_channel_offline(sp->pdev))
4330 return IRQ_NONE;
4331
4317 atomic_inc(&sp->isr_cnt); 4332 atomic_inc(&sp->isr_cnt);
4318 mac_control = &sp->mac_control; 4333 mac_control = &sp->mac_control;
4319 config = &sp->config; 4334 config = &sp->config;
@@ -6569,7 +6584,7 @@ static void s2io_rem_isr(struct s2io_nic * sp)
6569 } while(cnt < 5); 6584 } while(cnt < 5);
6570} 6585}
6571 6586
6572static void s2io_card_down(struct s2io_nic * sp) 6587static void do_s2io_card_down(struct s2io_nic * sp, int do_io)
6573{ 6588{
6574 int cnt = 0; 6589 int cnt = 0;
6575 struct XENA_dev_config __iomem *bar0 = sp->bar0; 6590 struct XENA_dev_config __iomem *bar0 = sp->bar0;
@@ -6584,7 +6599,8 @@ static void s2io_card_down(struct s2io_nic * sp)
6584 atomic_set(&sp->card_state, CARD_DOWN); 6599 atomic_set(&sp->card_state, CARD_DOWN);
6585 6600
6586 /* disable Tx and Rx traffic on the NIC */ 6601 /* disable Tx and Rx traffic on the NIC */
6587 stop_nic(sp); 6602 if (do_io)
6603 stop_nic(sp);
6588 6604
6589 s2io_rem_isr(sp); 6605 s2io_rem_isr(sp);
6590 6606
@@ -6592,7 +6608,7 @@ static void s2io_card_down(struct s2io_nic * sp)
6592 tasklet_kill(&sp->task); 6608 tasklet_kill(&sp->task);
6593 6609
6594 /* Check if the device is Quiescent and then Reset the NIC */ 6610 /* Check if the device is Quiescent and then Reset the NIC */
6595 do { 6611 while(do_io) {
6596 /* As per the HW requirement we need to replenish the 6612 /* As per the HW requirement we need to replenish the
6597 * receive buffer to avoid the ring bump. Since there is 6613 * receive buffer to avoid the ring bump. Since there is
6598 * no intention of processing the Rx frame at this pointwe are 6614 * no intention of processing the Rx frame at this pointwe are
@@ -6617,8 +6633,9 @@ static void s2io_card_down(struct s2io_nic * sp)
6617 (unsigned long long) val64); 6633 (unsigned long long) val64);
6618 break; 6634 break;
6619 } 6635 }
6620 } while (1); 6636 }
6621 s2io_reset(sp); 6637 if (do_io)
6638 s2io_reset(sp);
6622 6639
6623 spin_lock_irqsave(&sp->tx_lock, flags); 6640 spin_lock_irqsave(&sp->tx_lock, flags);
6624 /* Free all Tx buffers */ 6641 /* Free all Tx buffers */
@@ -6633,6 +6650,11 @@ static void s2io_card_down(struct s2io_nic * sp)
6633 clear_bit(0, &(sp->link_state)); 6650 clear_bit(0, &(sp->link_state));
6634} 6651}
6635 6652
6653static void s2io_card_down(struct s2io_nic * sp)
6654{
6655 do_s2io_card_down(sp, 1);
6656}
6657
6636static int s2io_card_up(struct s2io_nic * sp) 6658static int s2io_card_up(struct s2io_nic * sp)
6637{ 6659{
6638 int i, ret = 0; 6660 int i, ret = 0;
@@ -8010,3 +8032,85 @@ static void lro_append_pkt(struct s2io_nic *sp, struct lro *lro,
8010 sp->mac_control.stats_info->sw_stat.clubbed_frms_cnt++; 8032 sp->mac_control.stats_info->sw_stat.clubbed_frms_cnt++;
8011 return; 8033 return;
8012} 8034}
8035
8036/**
8037 * s2io_io_error_detected - called when PCI error is detected
8038 * @pdev: Pointer to PCI device
8039 * @state: The current pci connection state
8040 *
8041 * This function is called after a PCI bus error affecting
8042 * this device has been detected.
8043 */
8044static pci_ers_result_t s2io_io_error_detected(struct pci_dev *pdev,
8045 pci_channel_state_t state)
8046{
8047 struct net_device *netdev = pci_get_drvdata(pdev);
8048 struct s2io_nic *sp = netdev->priv;
8049
8050 netif_device_detach(netdev);
8051
8052 if (netif_running(netdev)) {
8053 /* Bring down the card, while avoiding PCI I/O */
8054 do_s2io_card_down(sp, 0);
8055 }
8056 pci_disable_device(pdev);
8057
8058 return PCI_ERS_RESULT_NEED_RESET;
8059}
8060
8061/**
8062 * s2io_io_slot_reset - called after the pci bus has been reset.
8063 * @pdev: Pointer to PCI device
8064 *
8065 * Restart the card from scratch, as if from a cold-boot.
8066 * At this point, the card has exprienced a hard reset,
8067 * followed by fixups by BIOS, and has its config space
8068 * set up identically to what it was at cold boot.
8069 */
8070static pci_ers_result_t s2io_io_slot_reset(struct pci_dev *pdev)
8071{
8072 struct net_device *netdev = pci_get_drvdata(pdev);
8073 struct s2io_nic *sp = netdev->priv;
8074
8075 if (pci_enable_device(pdev)) {
8076 printk(KERN_ERR "s2io: "
8077 "Cannot re-enable PCI device after reset.\n");
8078 return PCI_ERS_RESULT_DISCONNECT;
8079 }
8080
8081 pci_set_master(pdev);
8082 s2io_reset(sp);
8083
8084 return PCI_ERS_RESULT_RECOVERED;
8085}
8086
8087/**
8088 * s2io_io_resume - called when traffic can start flowing again.
8089 * @pdev: Pointer to PCI device
8090 *
8091 * This callback is called when the error recovery driver tells
8092 * us that its OK to resume normal operation.
8093 */
8094static void s2io_io_resume(struct pci_dev *pdev)
8095{
8096 struct net_device *netdev = pci_get_drvdata(pdev);
8097 struct s2io_nic *sp = netdev->priv;
8098
8099 if (netif_running(netdev)) {
8100 if (s2io_card_up(sp)) {
8101 printk(KERN_ERR "s2io: "
8102 "Can't bring device back up after reset.\n");
8103 return;
8104 }
8105
8106 if (s2io_set_mac_addr(netdev, netdev->dev_addr) == FAILURE) {
8107 s2io_card_down(sp);
8108 printk(KERN_ERR "s2io: "
8109 "Can't resetore mac addr after reset.\n");
8110 return;
8111 }
8112 }
8113
8114 netif_device_attach(netdev);
8115 netif_wake_queue(netdev);
8116}
diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h
index 54baa0b8ec7c..58592780f519 100644
--- a/drivers/net/s2io.h
+++ b/drivers/net/s2io.h
@@ -794,7 +794,6 @@ struct s2io_nic {
794 794
795 struct net_device_stats stats; 795 struct net_device_stats stats;
796 int high_dma_flag; 796 int high_dma_flag;
797 int device_close_flag;
798 int device_enabled_once; 797 int device_enabled_once;
799 798
800 char name[60]; 799 char name[60];
@@ -1052,6 +1051,11 @@ static void lro_append_pkt(struct s2io_nic *sp, struct lro *lro,
1052 struct sk_buff *skb, u32 tcp_len); 1051 struct sk_buff *skb, u32 tcp_len);
1053static int rts_ds_steer(struct s2io_nic *nic, u8 ds_codepoint, u8 ring); 1052static int rts_ds_steer(struct s2io_nic *nic, u8 ds_codepoint, u8 ring);
1054 1053
1054static pci_ers_result_t s2io_io_error_detected(struct pci_dev *pdev,
1055 pci_channel_state_t state);
1056static pci_ers_result_t s2io_io_slot_reset(struct pci_dev *pdev);
1057static void s2io_io_resume(struct pci_dev *pdev);
1058
1055#define s2io_tcp_mss(skb) skb_shinfo(skb)->gso_size 1059#define s2io_tcp_mss(skb) skb_shinfo(skb)->gso_size
1056#define s2io_udp_mss(skb) skb_shinfo(skb)->gso_size 1060#define s2io_udp_mss(skb) skb_shinfo(skb)->gso_size
1057#define s2io_offload_type(skb) skb_shinfo(skb)->gso_type 1061#define s2io_offload_type(skb) skb_shinfo(skb)->gso_type
diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c
index 2cb2e156c758..7c6e4808399a 100644
--- a/drivers/net/sis900.c
+++ b/drivers/net/sis900.c
@@ -573,7 +573,7 @@ static int __devinit sis900_probe(struct pci_dev *pci_dev,
573 * return error if it failed to found. 573 * return error if it failed to found.
574 */ 574 */
575 575
576static int __init sis900_mii_probe(struct net_device * net_dev) 576static int __devinit sis900_mii_probe(struct net_device * net_dev)
577{ 577{
578 struct sis900_private * sis_priv = net_dev->priv; 578 struct sis900_private * sis_priv = net_dev->priv;
579 const char *dev_name = pci_name(sis_priv->pci_dev); 579 const char *dev_name = pci_name(sis_priv->pci_dev);
diff --git a/drivers/net/sk98lin/Makefile b/drivers/net/sk98lin/Makefile
deleted file mode 100644
index afd900d5d730..000000000000
--- a/drivers/net/sk98lin/Makefile
+++ /dev/null
@@ -1,87 +0,0 @@
1#
2# Makefile for the SysKonnect SK-98xx device driver.
3#
4
5
6#
7# Standalone driver params
8# SKPARAM += -DSK_KERNEL_24
9# SKPARAM += -DSK_KERNEL_24_26
10# SKPARAM += -DSK_KERNEL_26
11# SKPARAM += -DSK_KERNEL_22_24
12
13obj-$(CONFIG_SK98LIN) += sk98lin.o
14sk98lin-objs := \
15 skge.o \
16 skethtool.o \
17 skdim.o \
18 skaddr.o \
19 skgehwt.o \
20 skgeinit.o \
21 skgepnmi.o \
22 skgesirq.o \
23 ski2c.o \
24 sklm80.o \
25 skqueue.o \
26 skrlmt.o \
27 sktimer.o \
28 skvpd.o \
29 skxmac2.o
30
31# DBGDEF = \
32# -DDEBUG
33
34ifdef DEBUG
35DBGDEF += \
36-DSK_DEBUG_CHKMOD=0x00000000L \
37-DSK_DEBUG_CHKCAT=0x00000000L
38endif
39
40
41# **** possible debug modules for SK_DEBUG_CHKMOD *****************
42# SK_DBGMOD_MERR 0x00000001L /* general module error indication */
43# SK_DBGMOD_HWM 0x00000002L /* Hardware init module */
44# SK_DBGMOD_RLMT 0x00000004L /* RLMT module */
45# SK_DBGMOD_VPD 0x00000008L /* VPD module */
46# SK_DBGMOD_I2C 0x00000010L /* I2C module */
47# SK_DBGMOD_PNMI 0x00000020L /* PNMI module */
48# SK_DBGMOD_CSUM 0x00000040L /* CSUM module */
49# SK_DBGMOD_ADDR 0x00000080L /* ADDR module */
50# SK_DBGMOD_DRV 0x00010000L /* DRV module */
51
52# **** possible debug categories for SK_DEBUG_CHKCAT **************
53# *** common modules ***
54# SK_DBGCAT_INIT 0x00000001L module/driver initialization
55# SK_DBGCAT_CTRL 0x00000002L controlling: add/rmv MCA/MAC and other controls (IOCTL)
56# SK_DBGCAT_ERR 0x00000004L error handling paths
57# SK_DBGCAT_TX 0x00000008L transmit path
58# SK_DBGCAT_RX 0x00000010L receive path
59# SK_DBGCAT_IRQ 0x00000020L general IRQ handling
60# SK_DBGCAT_QUEUE 0x00000040L any queue management
61# SK_DBGCAT_DUMP 0x00000080L large data output e.g. hex dump
62# SK_DBGCAT_FATAL 0x00000100L large data output e.g. hex dump
63
64# *** driver (file skge.c) ***
65# SK_DBGCAT_DRV_ENTRY 0x00010000 entry points
66# SK_DBGCAT_DRV_??? 0x00020000 not used
67# SK_DBGCAT_DRV_MCA 0x00040000 multicast
68# SK_DBGCAT_DRV_TX_PROGRESS 0x00080000 tx path
69# SK_DBGCAT_DRV_RX_PROGRESS 0x00100000 rx path
70# SK_DBGCAT_DRV_PROGRESS 0x00200000 general runtime
71# SK_DBGCAT_DRV_??? 0x00400000 not used
72# SK_DBGCAT_DRV_PROM 0x00800000 promiscuous mode
73# SK_DBGCAT_DRV_TX_FRAME 0x01000000 display tx frames
74# SK_DBGCAT_DRV_ERROR 0x02000000 error conditions
75# SK_DBGCAT_DRV_INT_SRC 0x04000000 interrupts sources
76# SK_DBGCAT_DRV_EVENT 0x08000000 driver events
77
78EXTRA_CFLAGS += -Idrivers/net/sk98lin -DSK_DIAG_SUPPORT -DGENESIS -DYUKON $(DBGDEF) $(SKPARAM)
79
80clean:
81 rm -f core *.o *.a *.s
82
83
84
85
86
87
diff --git a/drivers/net/sk98lin/h/lm80.h b/drivers/net/sk98lin/h/lm80.h
deleted file mode 100644
index 4e2dbbf78000..000000000000
--- a/drivers/net/sk98lin/h/lm80.h
+++ /dev/null
@@ -1,179 +0,0 @@
1/******************************************************************************
2 *
3 * Name: lm80.h
4 * Project: Gigabit Ethernet Adapters, Common Modules
5 * Version: $Revision: 1.6 $
6 * Date: $Date: 2003/05/13 17:26:52 $
7 * Purpose: Contains all defines for the LM80 Chip
8 * (National Semiconductor).
9 *
10 ******************************************************************************/
11
12/******************************************************************************
13 *
14 * (C)Copyright 1998-2002 SysKonnect.
15 * (C)Copyright 2002-2003 Marvell.
16 *
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation; either version 2 of the License, or
20 * (at your option) any later version.
21 *
22 * The information in this file is provided "AS IS" without warranty.
23 *
24 ******************************************************************************/
25
26#ifndef __INC_LM80_H
27#define __INC_LM80_H
28
29#ifdef __cplusplus
30extern "C" {
31#endif /* __cplusplus */
32
33/* defines ********************************************************************/
34
35/*
36 * LM80 register definition
37 *
38 * All registers are 8 bit wide
39 */
40#define LM80_CFG 0x00 /* Configuration Register */
41#define LM80_ISRC_1 0x01 /* Interrupt Status Register 1 */
42#define LM80_ISRC_2 0x02 /* Interrupt Status Register 2 */
43#define LM80_IMSK_1 0x03 /* Interrupt Mask Register 1 */
44#define LM80_IMSK_2 0x04 /* Interrupt Mask Register 2 */
45#define LM80_FAN_CTRL 0x05 /* Fan Devisor/RST#/OS# Register */
46#define LM80_TEMP_CTRL 0x06 /* OS# Config, Temp Res. Reg */
47 /* 0x07 - 0x1f reserved */
48 /* current values */
49#define LM80_VT0_IN 0x20 /* current Voltage 0 value */
50#define LM80_VT1_IN 0x21 /* current Voltage 1 value */
51#define LM80_VT2_IN 0x22 /* current Voltage 2 value */
52#define LM80_VT3_IN 0x23 /* current Voltage 3 value */
53#define LM80_VT4_IN 0x24 /* current Voltage 4 value */
54#define LM80_VT5_IN 0x25 /* current Voltage 5 value */
55#define LM80_VT6_IN 0x26 /* current Voltage 6 value */
56#define LM80_TEMP_IN 0x27 /* current Temperature value */
57#define LM80_FAN1_IN 0x28 /* current Fan 1 count */
58#define LM80_FAN2_IN 0x29 /* current Fan 2 count */
59 /* limit values */
60#define LM80_VT0_HIGH_LIM 0x2a /* high limit val for Voltage 0 */
61#define LM80_VT0_LOW_LIM 0x2b /* low limit val for Voltage 0 */
62#define LM80_VT1_HIGH_LIM 0x2c /* high limit val for Voltage 1 */
63#define LM80_VT1_LOW_LIM 0x2d /* low limit val for Voltage 1 */
64#define LM80_VT2_HIGH_LIM 0x2e /* high limit val for Voltage 2 */
65#define LM80_VT2_LOW_LIM 0x2f /* low limit val for Voltage 2 */
66#define LM80_VT3_HIGH_LIM 0x30 /* high limit val for Voltage 3 */
67#define LM80_VT3_LOW_LIM 0x31 /* low limit val for Voltage 3 */
68#define LM80_VT4_HIGH_LIM 0x32 /* high limit val for Voltage 4 */
69#define LM80_VT4_LOW_LIM 0x33 /* low limit val for Voltage 4 */
70#define LM80_VT5_HIGH_LIM 0x34 /* high limit val for Voltage 5 */
71#define LM80_VT5_LOW_LIM 0x35 /* low limit val for Voltage 5 */
72#define LM80_VT6_HIGH_LIM 0x36 /* high limit val for Voltage 6 */
73#define LM80_VT6_LOW_LIM 0x37 /* low limit val for Voltage 6 */
74#define LM80_THOT_LIM_UP 0x38 /* hot temperature limit (high) */
75#define LM80_THOT_LIM_LO 0x39 /* hot temperature limit (low) */
76#define LM80_TOS_LIM_UP 0x3a /* OS temperature limit (high) */
77#define LM80_TOS_LIM_LO 0x3b /* OS temperature limit (low) */
78#define LM80_FAN1_COUNT_LIM 0x3c /* Fan 1 count limit (high) */
79#define LM80_FAN2_COUNT_LIM 0x3d /* Fan 2 count limit (low) */
80 /* 0x3e - 0x3f reserved */
81
82/*
83 * LM80 bit definitions
84 */
85
86/* LM80_CFG Configuration Register */
87#define LM80_CFG_START (1<<0) /* start monitoring operation */
88#define LM80_CFG_INT_ENA (1<<1) /* enables the INT# Interrupt output */
89#define LM80_CFG_INT_POL (1<<2) /* INT# pol: 0 act low, 1 act high */
90#define LM80_CFG_INT_CLR (1<<3) /* disables INT#/RST_OUT#/OS# outputs */
91#define LM80_CFG_RESET (1<<4) /* signals a reset */
92#define LM80_CFG_CHASS_CLR (1<<5) /* clears Chassis Intrusion (CI) pin */
93#define LM80_CFG_GPO (1<<6) /* drives the GPO# pin */
94#define LM80_CFG_INIT (1<<7) /* restore power on defaults */
95
96/* LM80_ISRC_1 Interrupt Status Register 1 */
97/* LM80_IMSK_1 Interrupt Mask Register 1 */
98#define LM80_IS_VT0 (1<<0) /* limit exceeded for Voltage 0 */
99#define LM80_IS_VT1 (1<<1) /* limit exceeded for Voltage 1 */
100#define LM80_IS_VT2 (1<<2) /* limit exceeded for Voltage 2 */
101#define LM80_IS_VT3 (1<<3) /* limit exceeded for Voltage 3 */
102#define LM80_IS_VT4 (1<<4) /* limit exceeded for Voltage 4 */
103#define LM80_IS_VT5 (1<<5) /* limit exceeded for Voltage 5 */
104#define LM80_IS_VT6 (1<<6) /* limit exceeded for Voltage 6 */
105#define LM80_IS_INT_IN (1<<7) /* state of INT_IN# */
106
107/* LM80_ISRC_2 Interrupt Status Register 2 */
108/* LM80_IMSK_2 Interrupt Mask Register 2 */
109#define LM80_IS_TEMP (1<<0) /* HOT temperature limit exceeded */
110#define LM80_IS_BTI (1<<1) /* state of BTI# pin */
111#define LM80_IS_FAN1 (1<<2) /* count limit exceeded for Fan 1 */
112#define LM80_IS_FAN2 (1<<3) /* count limit exceeded for Fan 2 */
113#define LM80_IS_CI (1<<4) /* Chassis Intrusion occured */
114#define LM80_IS_OS (1<<5) /* OS temperature limit exceeded */
115 /* bit 6 and 7 are reserved in LM80_ISRC_2 */
116#define LM80_IS_HT_IRQ_MD (1<<6) /* Hot temperature interrupt mode */
117#define LM80_IS_OT_IRQ_MD (1<<7) /* OS temperature interrupt mode */
118
119/* LM80_FAN_CTRL Fan Devisor/RST#/OS# Register */
120#define LM80_FAN1_MD_SEL (1<<0) /* Fan 1 mode select */
121#define LM80_FAN2_MD_SEL (1<<1) /* Fan 2 mode select */
122#define LM80_FAN1_PRM_CTL (3<<2) /* Fan 1 speed control */
123#define LM80_FAN2_PRM_CTL (3<<4) /* Fan 2 speed control */
124#define LM80_FAN_OS_ENA (1<<6) /* enable OS mode on RST_OUT#/OS# pins*/
125#define LM80_FAN_RST_ENA (1<<7) /* sets RST_OUT#/OS# pins in RST mode */
126
127/* LM80_TEMP_CTRL OS# Config, Temp Res. Reg */
128#define LM80_TEMP_OS_STAT (1<<0) /* mirrors the state of RST_OUT#/OS# */
129#define LM80_TEMP_OS_POL (1<<1) /* select OS# polarity */
130#define LM80_TEMP_OS_MODE (1<<2) /* selects Interrupt mode */
131#define LM80_TEMP_RES (1<<3) /* selects 9 or 11 bit temp resulution*/
132#define LM80_TEMP_LSB (0xf<<4)/* 4 LSBs of 11 bit temp data */
133#define LM80_TEMP_LSB_9 (1<<7) /* LSB of 9 bit temperature data */
134
135 /* 0x07 - 0x1f reserved */
136/* LM80_VT0_IN current Voltage 0 value */
137/* LM80_VT1_IN current Voltage 1 value */
138/* LM80_VT2_IN current Voltage 2 value */
139/* LM80_VT3_IN current Voltage 3 value */
140/* LM80_VT4_IN current Voltage 4 value */
141/* LM80_VT5_IN current Voltage 5 value */
142/* LM80_VT6_IN current Voltage 6 value */
143/* LM80_TEMP_IN current temperature value */
144/* LM80_FAN1_IN current Fan 1 count */
145/* LM80_FAN2_IN current Fan 2 count */
146/* LM80_VT0_HIGH_LIM high limit val for Voltage 0 */
147/* LM80_VT0_LOW_LIM low limit val for Voltage 0 */
148/* LM80_VT1_HIGH_LIM high limit val for Voltage 1 */
149/* LM80_VT1_LOW_LIM low limit val for Voltage 1 */
150/* LM80_VT2_HIGH_LIM high limit val for Voltage 2 */
151/* LM80_VT2_LOW_LIM low limit val for Voltage 2 */
152/* LM80_VT3_HIGH_LIM high limit val for Voltage 3 */
153/* LM80_VT3_LOW_LIM low limit val for Voltage 3 */
154/* LM80_VT4_HIGH_LIM high limit val for Voltage 4 */
155/* LM80_VT4_LOW_LIM low limit val for Voltage 4 */
156/* LM80_VT5_HIGH_LIM high limit val for Voltage 5 */
157/* LM80_VT5_LOW_LIM low limit val for Voltage 5 */
158/* LM80_VT6_HIGH_LIM high limit val for Voltage 6 */
159/* LM80_VT6_LOW_LIM low limit val for Voltage 6 */
160/* LM80_THOT_LIM_UP hot temperature limit (high) */
161/* LM80_THOT_LIM_LO hot temperature limit (low) */
162/* LM80_TOS_LIM_UP OS temperature limit (high) */
163/* LM80_TOS_LIM_LO OS temperature limit (low) */
164/* LM80_FAN1_COUNT_LIM Fan 1 count limit (high) */
165/* LM80_FAN2_COUNT_LIM Fan 2 count limit (low) */
166 /* 0x3e - 0x3f reserved */
167
168#define LM80_ADDR 0x28 /* LM80 default addr */
169
170/* typedefs *******************************************************************/
171
172
173/* function prototypes ********************************************************/
174
175#ifdef __cplusplus
176}
177#endif /* __cplusplus */
178
179#endif /* __INC_LM80_H */
diff --git a/drivers/net/sk98lin/h/skaddr.h b/drivers/net/sk98lin/h/skaddr.h
deleted file mode 100644
index 423ad063d09b..000000000000
--- a/drivers/net/sk98lin/h/skaddr.h
+++ /dev/null
@@ -1,285 +0,0 @@
1/******************************************************************************
2 *
3 * Name: skaddr.h
4 * Project: Gigabit Ethernet Adapters, ADDR-Modul
5 * Version: $Revision: 1.29 $
6 * Date: $Date: 2003/05/13 16:57:24 $
7 * Purpose: Header file for Address Management (MC, UC, Prom).
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect GmbH.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25/******************************************************************************
26 *
27 * Description:
28 *
29 * This module is intended to manage multicast addresses and promiscuous mode
30 * on GEnesis adapters.
31 *
32 * Include File Hierarchy:
33 *
34 * "skdrv1st.h"
35 * ...
36 * "sktypes.h"
37 * "skqueue.h"
38 * "skaddr.h"
39 * ...
40 * "skdrv2nd.h"
41 *
42 ******************************************************************************/
43
44#ifndef __INC_SKADDR_H
45#define __INC_SKADDR_H
46
47#ifdef __cplusplus
48extern "C" {
49#endif /* cplusplus */
50
51/* defines ********************************************************************/
52
53#define SK_MAC_ADDR_LEN 6 /* Length of MAC address. */
54#define SK_MAX_ADDRS 14 /* #Addrs for exact match. */
55
56/* ----- Common return values ----- */
57
58#define SK_ADDR_SUCCESS 0 /* Function returned successfully. */
59#define SK_ADDR_ILLEGAL_PORT 100 /* Port number too high. */
60#define SK_ADDR_TOO_EARLY 101 /* Function called too early. */
61
62/* ----- Clear/Add flag bits ----- */
63
64#define SK_ADDR_PERMANENT 1 /* RLMT Address */
65
66/* ----- Additional Clear flag bits ----- */
67
68#define SK_MC_SW_ONLY 2 /* Do not update HW when clearing. */
69
70/* ----- Override flag bits ----- */
71
72#define SK_ADDR_LOGICAL_ADDRESS 0
73#define SK_ADDR_VIRTUAL_ADDRESS (SK_ADDR_LOGICAL_ADDRESS) /* old */
74#define SK_ADDR_PHYSICAL_ADDRESS 1
75#define SK_ADDR_CLEAR_LOGICAL 2
76#define SK_ADDR_SET_LOGICAL 4
77
78/* ----- Override return values ----- */
79
80#define SK_ADDR_OVERRIDE_SUCCESS (SK_ADDR_SUCCESS)
81#define SK_ADDR_DUPLICATE_ADDRESS 1
82#define SK_ADDR_MULTICAST_ADDRESS 2
83
84/* ----- Partitioning of excact match table ----- */
85
86#define SK_ADDR_EXACT_MATCHES 16 /* #Exact match entries. */
87
88#define SK_ADDR_FIRST_MATCH_RLMT 1
89#define SK_ADDR_LAST_MATCH_RLMT 2
90#define SK_ADDR_FIRST_MATCH_DRV 3
91#define SK_ADDR_LAST_MATCH_DRV (SK_ADDR_EXACT_MATCHES - 1)
92
93/* ----- SkAddrMcAdd/SkAddrMcUpdate return values ----- */
94
95#define SK_MC_FILTERING_EXACT 0 /* Exact filtering. */
96#define SK_MC_FILTERING_INEXACT 1 /* Inexact filtering. */
97
98/* ----- Additional SkAddrMcAdd return values ----- */
99
100#define SK_MC_ILLEGAL_ADDRESS 2 /* Illegal address. */
101#define SK_MC_ILLEGAL_PORT 3 /* Illegal port (not the active one). */
102#define SK_MC_RLMT_OVERFLOW 4 /* Too many RLMT mc addresses. */
103
104/* Promiscuous mode bits ----- */
105
106#define SK_PROM_MODE_NONE 0 /* Normal receive. */
107#define SK_PROM_MODE_LLC 1 /* Receive all LLC frames. */
108#define SK_PROM_MODE_ALL_MC 2 /* Receive all multicast frames. */
109/* #define SK_PROM_MODE_NON_LLC 4 */ /* Receive all non-LLC frames. */
110
111/* Macros */
112
113#ifdef OLD_STUFF
114#ifndef SK_ADDR_EQUAL
115/*
116 * "&" instead of "&&" allows better optimization on IA-64.
117 * The replacement is safe here, as all bytes exist.
118 */
119#ifndef SK_ADDR_DWORD_COMPARE
120#define SK_ADDR_EQUAL(A1,A2) ( \
121 (((SK_U8 *)(A1))[5] == ((SK_U8 *)(A2))[5]) & \
122 (((SK_U8 *)(A1))[4] == ((SK_U8 *)(A2))[4]) & \
123 (((SK_U8 *)(A1))[3] == ((SK_U8 *)(A2))[3]) & \
124 (((SK_U8 *)(A1))[2] == ((SK_U8 *)(A2))[2]) & \
125 (((SK_U8 *)(A1))[1] == ((SK_U8 *)(A2))[1]) & \
126 (((SK_U8 *)(A1))[0] == ((SK_U8 *)(A2))[0]))
127#else /* SK_ADDR_DWORD_COMPARE */
128#define SK_ADDR_EQUAL(A1,A2) ( \
129 (*(SK_U32 *)&(((SK_U8 *)(A1))[2]) == *(SK_U32 *)&(((SK_U8 *)(A2))[2])) & \
130 (*(SK_U32 *)&(((SK_U8 *)(A1))[0]) == *(SK_U32 *)&(((SK_U8 *)(A2))[0])))
131#endif /* SK_ADDR_DWORD_COMPARE */
132#endif /* SK_ADDR_EQUAL */
133#endif /* 0 */
134
135#ifndef SK_ADDR_EQUAL
136#ifndef SK_ADDR_DWORD_COMPARE
137#define SK_ADDR_EQUAL(A1,A2) ( \
138 (((SK_U8 SK_FAR *)(A1))[5] == ((SK_U8 SK_FAR *)(A2))[5]) & \
139 (((SK_U8 SK_FAR *)(A1))[4] == ((SK_U8 SK_FAR *)(A2))[4]) & \
140 (((SK_U8 SK_FAR *)(A1))[3] == ((SK_U8 SK_FAR *)(A2))[3]) & \
141 (((SK_U8 SK_FAR *)(A1))[2] == ((SK_U8 SK_FAR *)(A2))[2]) & \
142 (((SK_U8 SK_FAR *)(A1))[1] == ((SK_U8 SK_FAR *)(A2))[1]) & \
143 (((SK_U8 SK_FAR *)(A1))[0] == ((SK_U8 SK_FAR *)(A2))[0]))
144#else /* SK_ADDR_DWORD_COMPARE */
145#define SK_ADDR_EQUAL(A1,A2) ( \
146 (*(SK_U16 SK_FAR *)&(((SK_U8 SK_FAR *)(A1))[4]) == \
147 *(SK_U16 SK_FAR *)&(((SK_U8 SK_FAR *)(A2))[4])) && \
148 (*(SK_U32 SK_FAR *)&(((SK_U8 SK_FAR *)(A1))[0]) == \
149 *(SK_U32 SK_FAR *)&(((SK_U8 SK_FAR *)(A2))[0])))
150#endif /* SK_ADDR_DWORD_COMPARE */
151#endif /* SK_ADDR_EQUAL */
152
153/* typedefs *******************************************************************/
154
155typedef struct s_MacAddr {
156 SK_U8 a[SK_MAC_ADDR_LEN];
157} SK_MAC_ADDR;
158
159
160/* SK_FILTER is used to ensure alignment of the filter. */
161typedef union s_InexactFilter {
162 SK_U8 Bytes[8];
163 SK_U64 Val; /* Dummy entry for alignment only. */
164} SK_FILTER64;
165
166
167typedef struct s_AddrNet SK_ADDR_NET;
168
169
170typedef struct s_AddrPort {
171
172/* ----- Public part (read-only) ----- */
173
174 SK_MAC_ADDR CurrentMacAddress; /* Current physical MAC Address. */
175 SK_MAC_ADDR PermanentMacAddress; /* Permanent physical MAC Address. */
176 int PromMode; /* Promiscuous Mode. */
177
178/* ----- Private part ----- */
179
180 SK_MAC_ADDR PreviousMacAddress; /* Prev. phys. MAC Address. */
181 SK_BOOL CurrentMacAddressSet; /* CurrentMacAddress is set. */
182 SK_U8 Align01;
183
184 SK_U32 FirstExactMatchRlmt;
185 SK_U32 NextExactMatchRlmt;
186 SK_U32 FirstExactMatchDrv;
187 SK_U32 NextExactMatchDrv;
188 SK_MAC_ADDR Exact[SK_ADDR_EXACT_MATCHES];
189 SK_FILTER64 InexactFilter; /* For 64-bit hash register. */
190 SK_FILTER64 InexactRlmtFilter; /* For 64-bit hash register. */
191 SK_FILTER64 InexactDrvFilter; /* For 64-bit hash register. */
192} SK_ADDR_PORT;
193
194
195struct s_AddrNet {
196/* ----- Public part (read-only) ----- */
197
198 SK_MAC_ADDR CurrentMacAddress; /* Logical MAC Address. */
199 SK_MAC_ADDR PermanentMacAddress; /* Logical MAC Address. */
200
201/* ----- Private part ----- */
202
203 SK_U32 ActivePort; /* View of module ADDR. */
204 SK_BOOL CurrentMacAddressSet; /* CurrentMacAddress is set. */
205 SK_U8 Align01;
206 SK_U16 Align02;
207};
208
209
210typedef struct s_Addr {
211
212/* ----- Public part (read-only) ----- */
213
214 SK_ADDR_NET Net[SK_MAX_NETS];
215 SK_ADDR_PORT Port[SK_MAX_MACS];
216
217/* ----- Private part ----- */
218} SK_ADDR;
219
220/* function prototypes ********************************************************/
221
222#ifndef SK_KR_PROTO
223
224/* Functions provided by SkAddr */
225
226/* ANSI/C++ compliant function prototypes */
227
228extern int SkAddrInit(
229 SK_AC *pAC,
230 SK_IOC IoC,
231 int Level);
232
233extern int SkAddrMcClear(
234 SK_AC *pAC,
235 SK_IOC IoC,
236 SK_U32 PortNumber,
237 int Flags);
238
239extern int SkAddrMcAdd(
240 SK_AC *pAC,
241 SK_IOC IoC,
242 SK_U32 PortNumber,
243 SK_MAC_ADDR *pMc,
244 int Flags);
245
246extern int SkAddrMcUpdate(
247 SK_AC *pAC,
248 SK_IOC IoC,
249 SK_U32 PortNumber);
250
251extern int SkAddrOverride(
252 SK_AC *pAC,
253 SK_IOC IoC,
254 SK_U32 PortNumber,
255 SK_MAC_ADDR SK_FAR *pNewAddr,
256 int Flags);
257
258extern int SkAddrPromiscuousChange(
259 SK_AC *pAC,
260 SK_IOC IoC,
261 SK_U32 PortNumber,
262 int NewPromMode);
263
264#ifndef SK_SLIM
265extern int SkAddrSwap(
266 SK_AC *pAC,
267 SK_IOC IoC,
268 SK_U32 FromPortNumber,
269 SK_U32 ToPortNumber);
270#endif
271
272#else /* defined(SK_KR_PROTO)) */
273
274/* Non-ANSI/C++ compliant function prototypes */
275
276#error KR-style prototypes are not yet provided.
277
278#endif /* defined(SK_KR_PROTO)) */
279
280
281#ifdef __cplusplus
282}
283#endif /* __cplusplus */
284
285#endif /* __INC_SKADDR_H */
diff --git a/drivers/net/sk98lin/h/skcsum.h b/drivers/net/sk98lin/h/skcsum.h
deleted file mode 100644
index 6e256bd9a28c..000000000000
--- a/drivers/net/sk98lin/h/skcsum.h
+++ /dev/null
@@ -1,213 +0,0 @@
1/******************************************************************************
2 *
3 * Name: skcsum.h
4 * Project: GEnesis - SysKonnect SK-NET Gigabit Ethernet (SK-98xx)
5 * Version: $Revision: 1.10 $
6 * Date: $Date: 2003/08/20 13:59:57 $
7 * Purpose: Store/verify Internet checksum in send/receive packets.
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2001 SysKonnect GmbH.
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * The information in this file is provided "AS IS" without warranty.
21 *
22 ******************************************************************************/
23
24/******************************************************************************
25 *
26 * Description:
27 *
28 * Public header file for the "GEnesis" common module "CSUM".
29 *
30 * "GEnesis" is an abbreviation of "Gigabit Ethernet Network System in Silicon"
31 * and is the code name of this SysKonnect project.
32 *
33 * Compilation Options:
34 *
35 * SK_USE_CSUM - Define if CSUM is to be used. Otherwise, CSUM will be an
36 * empty module.
37 *
38 * SKCS_OVERWRITE_PROTO - Define to overwrite the default protocol id
39 * definitions. In this case, all SKCS_PROTO_xxx definitions must be made
40 * external.
41 *
42 * SKCS_OVERWRITE_STATUS - Define to overwrite the default return status
43 * definitions. In this case, all SKCS_STATUS_xxx definitions must be made
44 * external.
45 *
46 * Include File Hierarchy:
47 *
48 * "h/skcsum.h"
49 * "h/sktypes.h"
50 * "h/skqueue.h"
51 *
52 ******************************************************************************/
53
54#ifndef __INC_SKCSUM_H
55#define __INC_SKCSUM_H
56
57#include "h/sktypes.h"
58#include "h/skqueue.h"
59
60/* defines ********************************************************************/
61
62/*
63 * Define the default bit flags for 'SKCS_PACKET_INFO.ProtocolFlags' if no user
64 * overwrite.
65 */
66#ifndef SKCS_OVERWRITE_PROTO /* User overwrite? */
67#define SKCS_PROTO_IP 0x1 /* IP (Internet Protocol version 4) */
68#define SKCS_PROTO_TCP 0x2 /* TCP (Transmission Control Protocol) */
69#define SKCS_PROTO_UDP 0x4 /* UDP (User Datagram Protocol) */
70
71/* Indices for protocol statistics. */
72#define SKCS_PROTO_STATS_IP 0
73#define SKCS_PROTO_STATS_UDP 1
74#define SKCS_PROTO_STATS_TCP 2
75#define SKCS_NUM_PROTOCOLS 3 /* Number of supported protocols. */
76#endif /* !SKCS_OVERWRITE_PROTO */
77
78/*
79 * Define the default SKCS_STATUS type and values if no user overwrite.
80 *
81 * SKCS_STATUS_UNKNOWN_IP_VERSION - Not an IP v4 frame.
82 * SKCS_STATUS_IP_CSUM_ERROR - IP checksum error.
83 * SKCS_STATUS_IP_CSUM_ERROR_TCP - IP checksum error in TCP frame.
84 * SKCS_STATUS_IP_CSUM_ERROR_UDP - IP checksum error in UDP frame
85 * SKCS_STATUS_IP_FRAGMENT - IP fragment (IP checksum ok).
86 * SKCS_STATUS_IP_CSUM_OK - IP checksum ok (not a TCP or UDP frame).
87 * SKCS_STATUS_TCP_CSUM_ERROR - TCP checksum error (IP checksum ok).
88 * SKCS_STATUS_UDP_CSUM_ERROR - UDP checksum error (IP checksum ok).
89 * SKCS_STATUS_TCP_CSUM_OK - IP and TCP checksum ok.
90 * SKCS_STATUS_UDP_CSUM_OK - IP and UDP checksum ok.
91 * SKCS_STATUS_IP_CSUM_OK_NO_UDP - IP checksum OK and no UDP checksum.
92 */
93#ifndef SKCS_OVERWRITE_STATUS /* User overwrite? */
94#define SKCS_STATUS int /* Define status type. */
95
96#define SKCS_STATUS_UNKNOWN_IP_VERSION 1
97#define SKCS_STATUS_IP_CSUM_ERROR 2
98#define SKCS_STATUS_IP_FRAGMENT 3
99#define SKCS_STATUS_IP_CSUM_OK 4
100#define SKCS_STATUS_TCP_CSUM_ERROR 5
101#define SKCS_STATUS_UDP_CSUM_ERROR 6
102#define SKCS_STATUS_TCP_CSUM_OK 7
103#define SKCS_STATUS_UDP_CSUM_OK 8
104/* needed for Microsoft */
105#define SKCS_STATUS_IP_CSUM_ERROR_UDP 9
106#define SKCS_STATUS_IP_CSUM_ERROR_TCP 10
107/* UDP checksum may be omitted */
108#define SKCS_STATUS_IP_CSUM_OK_NO_UDP 11
109#endif /* !SKCS_OVERWRITE_STATUS */
110
111/* Clear protocol statistics event. */
112#define SK_CSUM_EVENT_CLEAR_PROTO_STATS 1
113
114/*
115 * Add two values in one's complement.
116 *
117 * Note: One of the two input values may be "longer" than 16-bit, but then the
118 * resulting sum may be 17 bits long. In this case, add zero to the result using
119 * SKCS_OC_ADD() again.
120 *
121 * Result = Value1 + Value2
122 */
123#define SKCS_OC_ADD(Result, Value1, Value2) { \
124 unsigned long Sum; \
125 \
126 Sum = (unsigned long) (Value1) + (unsigned long) (Value2); \
127 /* Add-in any carry. */ \
128 (Result) = (Sum & 0xffff) + (Sum >> 16); \
129}
130
131/*
132 * Subtract two values in one's complement.
133 *
134 * Result = Value1 - Value2
135 */
136#define SKCS_OC_SUB(Result, Value1, Value2) \
137 SKCS_OC_ADD((Result), (Value1), ~(Value2) & 0xffff)
138
139/* typedefs *******************************************************************/
140
141/*
142 * SKCS_PROTO_STATS - The CSUM protocol statistics structure.
143 *
144 * There is one instance of this structure for each protocol supported.
145 */
146typedef struct s_CsProtocolStatistics {
147 SK_U64 RxOkCts; /* Receive checksum ok. */
148 SK_U64 RxUnableCts; /* Unable to verify receive checksum. */
149 SK_U64 RxErrCts; /* Receive checksum error. */
150 SK_U64 TxOkCts; /* Transmit checksum ok. */
151 SK_U64 TxUnableCts; /* Unable to calculate checksum in hw. */
152} SKCS_PROTO_STATS;
153
154/*
155 * s_Csum - The CSUM module context structure.
156 */
157typedef struct s_Csum {
158 /* Enabled receive SK_PROTO_XXX bit flags. */
159 unsigned ReceiveFlags[SK_MAX_NETS];
160#ifdef TX_CSUM
161 unsigned TransmitFlags[SK_MAX_NETS];
162#endif /* TX_CSUM */
163
164 /* The protocol statistics structure; one per supported protocol. */
165 SKCS_PROTO_STATS ProtoStats[SK_MAX_NETS][SKCS_NUM_PROTOCOLS];
166} SK_CSUM;
167
168/*
169 * SKCS_PACKET_INFO - The packet information structure.
170 */
171typedef struct s_CsPacketInfo {
172 /* Bit field specifiying the desired/found protocols. */
173 unsigned ProtocolFlags;
174
175 /* Length of complete IP header, including any option fields. */
176 unsigned IpHeaderLength;
177
178 /* IP header checksum. */
179 unsigned IpHeaderChecksum;
180
181 /* TCP/UDP pseudo header checksum. */
182 unsigned PseudoHeaderChecksum;
183} SKCS_PACKET_INFO;
184
185/* function prototypes ********************************************************/
186
187#ifndef SK_CS_CALCULATE_CHECKSUM
188extern unsigned SkCsCalculateChecksum(
189 void *pData,
190 unsigned Length);
191#endif /* SK_CS_CALCULATE_CHECKSUM */
192
193extern int SkCsEvent(
194 SK_AC *pAc,
195 SK_IOC Ioc,
196 SK_U32 Event,
197 SK_EVPARA Param);
198
199extern SKCS_STATUS SkCsGetReceiveInfo(
200 SK_AC *pAc,
201 void *pIpHeader,
202 unsigned Checksum1,
203 unsigned Checksum2,
204 int NetNumber);
205
206extern void SkCsSetReceiveFlags(
207 SK_AC *pAc,
208 unsigned ReceiveFlags,
209 unsigned *pChecksum1Offset,
210 unsigned *pChecksum2Offset,
211 int NetNumber);
212
213#endif /* __INC_SKCSUM_H */
diff --git a/drivers/net/sk98lin/h/skdebug.h b/drivers/net/sk98lin/h/skdebug.h
deleted file mode 100644
index 3cba171d74b2..000000000000
--- a/drivers/net/sk98lin/h/skdebug.h
+++ /dev/null
@@ -1,74 +0,0 @@
1/******************************************************************************
2 *
3 * Name: skdebug.h
4 * Project: Gigabit Ethernet Adapters, Common Modules
5 * Version: $Revision: 1.14 $
6 * Date: $Date: 2003/05/13 17:26:00 $
7 * Purpose: SK specific DEBUG support
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25#ifndef __INC_SKDEBUG_H
26#define __INC_SKDEBUG_H
27
28#ifdef DEBUG
29#ifndef SK_DBG_MSG
30#define SK_DBG_MSG(pAC,comp,cat,arg) \
31 if ( ((comp) & SK_DBG_CHKMOD(pAC)) && \
32 ((cat) & SK_DBG_CHKCAT(pAC)) ) { \
33 SK_DBG_PRINTF arg ; \
34 }
35#endif
36#else
37#define SK_DBG_MSG(pAC,comp,lev,arg)
38#endif
39
40/* PLS NOTE:
41 * =========
42 * Due to any restrictions of kernel printf routines do not use other
43 * format identifiers as: %x %d %c %s .
44 * Never use any combined format identifiers such as: %lx %ld in your
45 * printf - argument (arg) because some OS specific kernel printfs may
46 * only support some basic identifiers.
47 */
48
49/* Debug modules */
50
51#define SK_DBGMOD_MERR 0x00000001L /* general module error indication */
52#define SK_DBGMOD_HWM 0x00000002L /* Hardware init module */
53#define SK_DBGMOD_RLMT 0x00000004L /* RLMT module */
54#define SK_DBGMOD_VPD 0x00000008L /* VPD module */
55#define SK_DBGMOD_I2C 0x00000010L /* I2C module */
56#define SK_DBGMOD_PNMI 0x00000020L /* PNMI module */
57#define SK_DBGMOD_CSUM 0x00000040L /* CSUM module */
58#define SK_DBGMOD_ADDR 0x00000080L /* ADDR module */
59#define SK_DBGMOD_PECP 0x00000100L /* PECP module */
60#define SK_DBGMOD_POWM 0x00000200L /* Power Management module */
61
62/* Debug events */
63
64#define SK_DBGCAT_INIT 0x00000001L /* module/driver initialization */
65#define SK_DBGCAT_CTRL 0x00000002L /* controlling devices */
66#define SK_DBGCAT_ERR 0x00000004L /* error handling paths */
67#define SK_DBGCAT_TX 0x00000008L /* transmit path */
68#define SK_DBGCAT_RX 0x00000010L /* receive path */
69#define SK_DBGCAT_IRQ 0x00000020L /* general IRQ handling */
70#define SK_DBGCAT_QUEUE 0x00000040L /* any queue management */
71#define SK_DBGCAT_DUMP 0x00000080L /* large data output e.g. hex dump */
72#define SK_DBGCAT_FATAL 0x00000100L /* fatal error */
73
74#endif /* __INC_SKDEBUG_H */
diff --git a/drivers/net/sk98lin/h/skdrv1st.h b/drivers/net/sk98lin/h/skdrv1st.h
deleted file mode 100644
index 91b8d4f45904..000000000000
--- a/drivers/net/sk98lin/h/skdrv1st.h
+++ /dev/null
@@ -1,188 +0,0 @@
1/******************************************************************************
2 *
3 * Name: skdrv1st.h
4 * Project: GEnesis, PCI Gigabit Ethernet Adapter
5 * Version: $Revision: 1.4 $
6 * Date: $Date: 2003/11/12 14:28:14 $
7 * Purpose: First header file for driver and all other modules
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect GmbH.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25/******************************************************************************
26 *
27 * Description:
28 *
29 * This is the first include file of the driver, which includes all
30 * neccessary system header files and some of the GEnesis header files.
31 * It also defines some basic items.
32 *
33 * Include File Hierarchy:
34 *
35 * see skge.c
36 *
37 ******************************************************************************/
38
39#ifndef __INC_SKDRV1ST_H
40#define __INC_SKDRV1ST_H
41
42typedef struct s_AC SK_AC;
43
44/* Set card versions */
45#define SK_FAR
46
47/* override some default functions with optimized linux functions */
48
49#define SK_PNMI_STORE_U16(p,v) memcpy((char*)(p),(char*)&(v),2)
50#define SK_PNMI_STORE_U32(p,v) memcpy((char*)(p),(char*)&(v),4)
51#define SK_PNMI_STORE_U64(p,v) memcpy((char*)(p),(char*)&(v),8)
52#define SK_PNMI_READ_U16(p,v) memcpy((char*)&(v),(char*)(p),2)
53#define SK_PNMI_READ_U32(p,v) memcpy((char*)&(v),(char*)(p),4)
54#define SK_PNMI_READ_U64(p,v) memcpy((char*)&(v),(char*)(p),8)
55
56#define SK_ADDR_EQUAL(a1,a2) (!memcmp(a1,a2,6))
57
58#include <linux/types.h>
59#include <linux/kernel.h>
60#include <linux/string.h>
61#include <linux/errno.h>
62#include <linux/ioport.h>
63#include <linux/slab.h>
64#include <linux/interrupt.h>
65#include <linux/pci.h>
66#include <linux/bitops.h>
67#include <asm/byteorder.h>
68#include <asm/io.h>
69#include <asm/irq.h>
70#include <linux/netdevice.h>
71#include <linux/etherdevice.h>
72#include <linux/skbuff.h>
73
74#include <linux/init.h>
75#include <asm/uaccess.h>
76#include <net/checksum.h>
77
78#define SK_CS_CALCULATE_CHECKSUM
79#ifndef CONFIG_X86_64
80#define SkCsCalculateChecksum(p,l) ((~ip_compute_csum(p, l)) & 0xffff)
81#else
82#define SkCsCalculateChecksum(p,l) ((~ip_fast_csum(p, l)) & 0xffff)
83#endif
84
85#include "h/sktypes.h"
86#include "h/skerror.h"
87#include "h/skdebug.h"
88#include "h/lm80.h"
89#include "h/xmac_ii.h"
90
91#ifdef __LITTLE_ENDIAN
92#define SK_LITTLE_ENDIAN
93#else
94#define SK_BIG_ENDIAN
95#endif
96
97#define SK_NET_DEVICE net_device
98
99
100/* we use gethrtime(), return unit: nanoseconds */
101#define SK_TICKS_PER_SEC 100
102
103#define SK_MEM_MAPPED_IO
104
105// #define SK_RLMT_SLOW_LOOKAHEAD
106
107#define SK_MAX_MACS 2
108#define SK_MAX_NETS 2
109
110#define SK_IOC char __iomem *
111
112typedef struct s_DrvRlmtMbuf SK_MBUF;
113
114#define SK_CONST64 INT64_C
115#define SK_CONSTU64 UINT64_C
116
117#define SK_MEMCPY(dest,src,size) memcpy(dest,src,size)
118#define SK_MEMCMP(s1,s2,size) memcmp(s1,s2,size)
119#define SK_MEMSET(dest,val,size) memset(dest,val,size)
120#define SK_STRLEN(pStr) strlen((char*)(pStr))
121#define SK_STRNCPY(pDest,pSrc,size) strncpy((char*)(pDest),(char*)(pSrc),size)
122#define SK_STRCMP(pStr1,pStr2) strcmp((char*)(pStr1),(char*)(pStr2))
123
124/* macros to access the adapter */
125#define SK_OUT8(b,a,v) writeb((v), ((b)+(a)))
126#define SK_OUT16(b,a,v) writew((v), ((b)+(a)))
127#define SK_OUT32(b,a,v) writel((v), ((b)+(a)))
128#define SK_IN8(b,a,pv) (*(pv) = readb((b)+(a)))
129#define SK_IN16(b,a,pv) (*(pv) = readw((b)+(a)))
130#define SK_IN32(b,a,pv) (*(pv) = readl((b)+(a)))
131
132#define int8_t char
133#define int16_t short
134#define int32_t long
135#define int64_t long long
136#define uint8_t u_char
137#define uint16_t u_short
138#define uint32_t u_long
139#define uint64_t unsigned long long
140#define t_scalar_t int
141#define t_uscalar_t unsigned int
142#define uintptr_t unsigned long
143
144#define __CONCAT__(A,B) A##B
145
146#define INT32_C(a) __CONCAT__(a,L)
147#define INT64_C(a) __CONCAT__(a,LL)
148#define UINT32_C(a) __CONCAT__(a,UL)
149#define UINT64_C(a) __CONCAT__(a,ULL)
150
151#ifdef DEBUG
152#define SK_DBG_PRINTF printk
153#ifndef SK_DEBUG_CHKMOD
154#define SK_DEBUG_CHKMOD 0
155#endif
156#ifndef SK_DEBUG_CHKCAT
157#define SK_DEBUG_CHKCAT 0
158#endif
159/* those come from the makefile */
160#define SK_DBG_CHKMOD(pAC) (SK_DEBUG_CHKMOD)
161#define SK_DBG_CHKCAT(pAC) (SK_DEBUG_CHKCAT)
162
163extern void SkDbgPrintf(const char *format,...);
164
165#define SK_DBGMOD_DRV 0x00010000
166
167/**** possible driver debug categories ********************************/
168#define SK_DBGCAT_DRV_ENTRY 0x00010000
169#define SK_DBGCAT_DRV_SAP 0x00020000
170#define SK_DBGCAT_DRV_MCA 0x00040000
171#define SK_DBGCAT_DRV_TX_PROGRESS 0x00080000
172#define SK_DBGCAT_DRV_RX_PROGRESS 0x00100000
173#define SK_DBGCAT_DRV_PROGRESS 0x00200000
174#define SK_DBGCAT_DRV_MSG 0x00400000
175#define SK_DBGCAT_DRV_PROM 0x00800000
176#define SK_DBGCAT_DRV_TX_FRAME 0x01000000
177#define SK_DBGCAT_DRV_ERROR 0x02000000
178#define SK_DBGCAT_DRV_INT_SRC 0x04000000
179#define SK_DBGCAT_DRV_EVENT 0x08000000
180
181#endif
182
183#define SK_ERR_LOG SkErrorLog
184
185extern void SkErrorLog(SK_AC*, int, int, char*);
186
187#endif
188
diff --git a/drivers/net/sk98lin/h/skdrv2nd.h b/drivers/net/sk98lin/h/skdrv2nd.h
deleted file mode 100644
index 3fa67171e832..000000000000
--- a/drivers/net/sk98lin/h/skdrv2nd.h
+++ /dev/null
@@ -1,447 +0,0 @@
1/******************************************************************************
2 *
3 * Name: skdrv2nd.h
4 * Project: GEnesis, PCI Gigabit Ethernet Adapter
5 * Version: $Revision: 1.10 $
6 * Date: $Date: 2003/12/11 16:04:45 $
7 * Purpose: Second header file for driver and all other modules
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect GmbH.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25/******************************************************************************
26 *
27 * Description:
28 *
29 * This is the second include file of the driver, which includes all other
30 * neccessary files and defines all structures and constants used by the
31 * driver and the common modules.
32 *
33 * Include File Hierarchy:
34 *
35 * see skge.c
36 *
37 ******************************************************************************/
38
39#ifndef __INC_SKDRV2ND_H
40#define __INC_SKDRV2ND_H
41
42#include "h/skqueue.h"
43#include "h/skgehwt.h"
44#include "h/sktimer.h"
45#include "h/ski2c.h"
46#include "h/skgepnmi.h"
47#include "h/skvpd.h"
48#include "h/skgehw.h"
49#include "h/skgeinit.h"
50#include "h/skaddr.h"
51#include "h/skgesirq.h"
52#include "h/skcsum.h"
53#include "h/skrlmt.h"
54#include "h/skgedrv.h"
55
56
57extern SK_MBUF *SkDrvAllocRlmtMbuf(SK_AC*, SK_IOC, unsigned);
58extern void SkDrvFreeRlmtMbuf(SK_AC*, SK_IOC, SK_MBUF*);
59extern SK_U64 SkOsGetTime(SK_AC*);
60extern int SkPciReadCfgDWord(SK_AC*, int, SK_U32*);
61extern int SkPciReadCfgWord(SK_AC*, int, SK_U16*);
62extern int SkPciReadCfgByte(SK_AC*, int, SK_U8*);
63extern int SkPciWriteCfgWord(SK_AC*, int, SK_U16);
64extern int SkPciWriteCfgByte(SK_AC*, int, SK_U8);
65extern int SkDrvEvent(SK_AC*, SK_IOC IoC, SK_U32, SK_EVPARA);
66
67#ifdef SK_DIAG_SUPPORT
68extern int SkDrvEnterDiagMode(SK_AC *pAc);
69extern int SkDrvLeaveDiagMode(SK_AC *pAc);
70#endif
71
72struct s_DrvRlmtMbuf {
73 SK_MBUF *pNext; /* Pointer to next RLMT Mbuf. */
74 SK_U8 *pData; /* Data buffer (virtually contig.). */
75 unsigned Size; /* Data buffer size. */
76 unsigned Length; /* Length of packet (<= Size). */
77 SK_U32 PortIdx; /* Receiving/transmitting port. */
78#ifdef SK_RLMT_MBUF_PRIVATE
79 SK_RLMT_MBUF Rlmt; /* Private part for RLMT. */
80#endif /* SK_RLMT_MBUF_PRIVATE */
81 struct sk_buff *pOs; /* Pointer to message block */
82};
83
84
85/*
86 * Time macros
87 */
88#if SK_TICKS_PER_SEC == 100
89#define SK_PNMI_HUNDREDS_SEC(t) (t)
90#else
91#define SK_PNMI_HUNDREDS_SEC(t) ((((unsigned long)t) * 100) / \
92 (SK_TICKS_PER_SEC))
93#endif
94
95/*
96 * New SkOsGetTime
97 */
98#define SkOsGetTimeCurrent(pAC, pUsec) {\
99 struct timeval t;\
100 do_gettimeofday(&t);\
101 *pUsec = ((((t.tv_sec) * 1000000L)+t.tv_usec)/10000);\
102}
103
104
105/*
106 * ioctl definitions
107 */
108#define SK_IOCTL_BASE (SIOCDEVPRIVATE)
109#define SK_IOCTL_GETMIB (SK_IOCTL_BASE + 0)
110#define SK_IOCTL_SETMIB (SK_IOCTL_BASE + 1)
111#define SK_IOCTL_PRESETMIB (SK_IOCTL_BASE + 2)
112#define SK_IOCTL_GEN (SK_IOCTL_BASE + 3)
113#define SK_IOCTL_DIAG (SK_IOCTL_BASE + 4)
114
115typedef struct s_IOCTL SK_GE_IOCTL;
116
117struct s_IOCTL {
118 char __user * pData;
119 unsigned int Len;
120};
121
122
123/*
124 * define sizes of descriptor rings in bytes
125 */
126
127#define TX_RING_SIZE (8*1024)
128#define RX_RING_SIZE (24*1024)
129
130/*
131 * Buffer size for ethernet packets
132 */
133#define ETH_BUF_SIZE 1540
134#define ETH_MAX_MTU 1514
135#define ETH_MIN_MTU 60
136#define ETH_MULTICAST_BIT 0x01
137#define SK_JUMBO_MTU 9000
138
139/*
140 * transmit priority selects the queue: LOW=asynchron, HIGH=synchron
141 */
142#define TX_PRIO_LOW 0
143#define TX_PRIO_HIGH 1
144
145/*
146 * alignment of rx/tx descriptors
147 */
148#define DESCR_ALIGN 64
149
150/*
151 * definitions for pnmi. TODO
152 */
153#define SK_DRIVER_RESET(pAC, IoC) 0
154#define SK_DRIVER_SENDEVENT(pAC, IoC) 0
155#define SK_DRIVER_SELFTEST(pAC, IoC) 0
156/* For get mtu you must add an own function */
157#define SK_DRIVER_GET_MTU(pAc,IoC,i) 0
158#define SK_DRIVER_SET_MTU(pAc,IoC,i,v) 0
159#define SK_DRIVER_PRESET_MTU(pAc,IoC,i,v) 0
160
161/*
162** Interim definition of SK_DRV_TIMER placed in this file until
163** common modules have been finalized
164*/
165#define SK_DRV_TIMER 11
166#define SK_DRV_MODERATION_TIMER 1
167#define SK_DRV_MODERATION_TIMER_LENGTH 1000000 /* 1 second */
168#define SK_DRV_RX_CLEANUP_TIMER 2
169#define SK_DRV_RX_CLEANUP_TIMER_LENGTH 1000000 /* 100 millisecs */
170
171/*
172** Definitions regarding transmitting frames
173** any calculating any checksum.
174*/
175#define C_LEN_ETHERMAC_HEADER_DEST_ADDR 6
176#define C_LEN_ETHERMAC_HEADER_SRC_ADDR 6
177#define C_LEN_ETHERMAC_HEADER_LENTYPE 2
178#define C_LEN_ETHERMAC_HEADER ( (C_LEN_ETHERMAC_HEADER_DEST_ADDR) + \
179 (C_LEN_ETHERMAC_HEADER_SRC_ADDR) + \
180 (C_LEN_ETHERMAC_HEADER_LENTYPE) )
181
182#define C_LEN_ETHERMTU_MINSIZE 46
183#define C_LEN_ETHERMTU_MAXSIZE_STD 1500
184#define C_LEN_ETHERMTU_MAXSIZE_JUMBO 9000
185
186#define C_LEN_ETHERNET_MINSIZE ( (C_LEN_ETHERMAC_HEADER) + \
187 (C_LEN_ETHERMTU_MINSIZE) )
188
189#define C_OFFSET_IPHEADER C_LEN_ETHERMAC_HEADER
190#define C_OFFSET_IPHEADER_IPPROTO 9
191#define C_OFFSET_TCPHEADER_TCPCS 16
192#define C_OFFSET_UDPHEADER_UDPCS 6
193
194#define C_OFFSET_IPPROTO ( (C_LEN_ETHERMAC_HEADER) + \
195 (C_OFFSET_IPHEADER_IPPROTO) )
196
197#define C_PROTO_ID_UDP 17 /* refer to RFC 790 or Stevens' */
198#define C_PROTO_ID_TCP 6 /* TCP/IP illustrated for details */
199
200/* TX and RX descriptors *****************************************************/
201
202typedef struct s_RxD RXD; /* the receive descriptor */
203
204struct s_RxD {
205 volatile SK_U32 RBControl; /* Receive Buffer Control */
206 SK_U32 VNextRxd; /* Next receive descriptor,low dword */
207 SK_U32 VDataLow; /* Receive buffer Addr, low dword */
208 SK_U32 VDataHigh; /* Receive buffer Addr, high dword */
209 SK_U32 FrameStat; /* Receive Frame Status word */
210 SK_U32 TimeStamp; /* Time stamp from XMAC */
211 SK_U32 TcpSums; /* TCP Sum 2 / TCP Sum 1 */
212 SK_U32 TcpSumStarts; /* TCP Sum Start 2 / TCP Sum Start 1 */
213 RXD *pNextRxd; /* Pointer to next Rxd */
214 struct sk_buff *pMBuf; /* Pointer to Linux' socket buffer */
215};
216
217typedef struct s_TxD TXD; /* the transmit descriptor */
218
219struct s_TxD {
220 volatile SK_U32 TBControl; /* Transmit Buffer Control */
221 SK_U32 VNextTxd; /* Next transmit descriptor,low dword */
222 SK_U32 VDataLow; /* Transmit Buffer Addr, low dword */
223 SK_U32 VDataHigh; /* Transmit Buffer Addr, high dword */
224 SK_U32 FrameStat; /* Transmit Frame Status Word */
225 SK_U32 TcpSumOfs; /* Reserved / TCP Sum Offset */
226 SK_U16 TcpSumSt; /* TCP Sum Start */
227 SK_U16 TcpSumWr; /* TCP Sum Write */
228 SK_U32 TcpReserved; /* not used */
229 TXD *pNextTxd; /* Pointer to next Txd */
230 struct sk_buff *pMBuf; /* Pointer to Linux' socket buffer */
231};
232
233/* Used interrupt bits in the interrupts source register *********************/
234
235#define DRIVER_IRQS ((IS_IRQ_SW) | \
236 (IS_R1_F) |(IS_R2_F) | \
237 (IS_XS1_F) |(IS_XA1_F) | \
238 (IS_XS2_F) |(IS_XA2_F))
239
240#define SPECIAL_IRQS ((IS_HW_ERR) |(IS_I2C_READY) | \
241 (IS_EXT_REG) |(IS_TIMINT) | \
242 (IS_PA_TO_RX1) |(IS_PA_TO_RX2) | \
243 (IS_PA_TO_TX1) |(IS_PA_TO_TX2) | \
244 (IS_MAC1) |(IS_LNK_SYNC_M1)| \
245 (IS_MAC2) |(IS_LNK_SYNC_M2)| \
246 (IS_R1_C) |(IS_R2_C) | \
247 (IS_XS1_C) |(IS_XA1_C) | \
248 (IS_XS2_C) |(IS_XA2_C))
249
250#define IRQ_MASK ((IS_IRQ_SW) | \
251 (IS_R1_B) |(IS_R1_F) |(IS_R2_B) |(IS_R2_F) | \
252 (IS_XS1_B) |(IS_XS1_F) |(IS_XA1_B)|(IS_XA1_F)| \
253 (IS_XS2_B) |(IS_XS2_F) |(IS_XA2_B)|(IS_XA2_F)| \
254 (IS_HW_ERR) |(IS_I2C_READY)| \
255 (IS_EXT_REG) |(IS_TIMINT) | \
256 (IS_PA_TO_RX1) |(IS_PA_TO_RX2)| \
257 (IS_PA_TO_TX1) |(IS_PA_TO_TX2)| \
258 (IS_MAC1) |(IS_MAC2) | \
259 (IS_R1_C) |(IS_R2_C) | \
260 (IS_XS1_C) |(IS_XA1_C) | \
261 (IS_XS2_C) |(IS_XA2_C))
262
263#define IRQ_HWE_MASK (IS_ERR_MSK) /* enable all HW irqs */
264
265typedef struct s_DevNet DEV_NET;
266
267struct s_DevNet {
268 int PortNr;
269 int NetNr;
270 SK_AC *pAC;
271};
272
273typedef struct s_TxPort TX_PORT;
274
275struct s_TxPort {
276 /* the transmit descriptor rings */
277 caddr_t pTxDescrRing; /* descriptor area memory */
278 SK_U64 VTxDescrRing; /* descr. area bus virt. addr. */
279 TXD *pTxdRingHead; /* Head of Tx rings */
280 TXD *pTxdRingTail; /* Tail of Tx rings */
281 TXD *pTxdRingPrev; /* descriptor sent previously */
282 int TxdRingFree; /* # of free entrys */
283 spinlock_t TxDesRingLock; /* serialize descriptor accesses */
284 SK_IOC HwAddr; /* bmu registers address */
285 int PortIndex; /* index number of port (0 or 1) */
286};
287
288typedef struct s_RxPort RX_PORT;
289
290struct s_RxPort {
291 /* the receive descriptor rings */
292 caddr_t pRxDescrRing; /* descriptor area memory */
293 SK_U64 VRxDescrRing; /* descr. area bus virt. addr. */
294 RXD *pRxdRingHead; /* Head of Rx rings */
295 RXD *pRxdRingTail; /* Tail of Rx rings */
296 RXD *pRxdRingPrev; /* descriptor given to BMU previously */
297 int RxdRingFree; /* # of free entrys */
298 int RxCsum; /* use receive checksum hardware */
299 spinlock_t RxDesRingLock; /* serialize descriptor accesses */
300 int RxFillLimit; /* limit for buffers in ring */
301 SK_IOC HwAddr; /* bmu registers address */
302 int PortIndex; /* index number of port (0 or 1) */
303};
304
305/* Definitions needed for interrupt moderation *******************************/
306
307#define IRQ_EOF_AS_TX ((IS_XA1_F) | (IS_XA2_F))
308#define IRQ_EOF_SY_TX ((IS_XS1_F) | (IS_XS2_F))
309#define IRQ_MASK_TX_ONLY ((IRQ_EOF_AS_TX)| (IRQ_EOF_SY_TX))
310#define IRQ_MASK_RX_ONLY ((IS_R1_F) | (IS_R2_F))
311#define IRQ_MASK_SP_ONLY (SPECIAL_IRQS)
312#define IRQ_MASK_TX_RX ((IRQ_MASK_TX_ONLY)| (IRQ_MASK_RX_ONLY))
313#define IRQ_MASK_SP_RX ((SPECIAL_IRQS) | (IRQ_MASK_RX_ONLY))
314#define IRQ_MASK_SP_TX ((SPECIAL_IRQS) | (IRQ_MASK_TX_ONLY))
315#define IRQ_MASK_RX_TX_SP ((SPECIAL_IRQS) | (IRQ_MASK_TX_RX))
316
317#define C_INT_MOD_NONE 1
318#define C_INT_MOD_STATIC 2
319#define C_INT_MOD_DYNAMIC 4
320
321#define C_CLK_FREQ_GENESIS 53215000 /* shorter: 53.125 MHz */
322#define C_CLK_FREQ_YUKON 78215000 /* shorter: 78.125 MHz */
323
324#define C_INTS_PER_SEC_DEFAULT 2000
325#define C_INT_MOD_ENABLE_PERCENTAGE 50 /* if higher 50% enable */
326#define C_INT_MOD_DISABLE_PERCENTAGE 50 /* if lower 50% disable */
327#define C_INT_MOD_IPS_LOWER_RANGE 30
328#define C_INT_MOD_IPS_UPPER_RANGE 40000
329
330
331typedef struct s_DynIrqModInfo DIM_INFO;
332struct s_DynIrqModInfo {
333 unsigned long PrevTimeVal;
334 unsigned int PrevSysLoad;
335 unsigned int PrevUsedTime;
336 unsigned int PrevTotalTime;
337 int PrevUsedDescrRatio;
338 int NbrProcessedDescr;
339 SK_U64 PrevPort0RxIntrCts;
340 SK_U64 PrevPort1RxIntrCts;
341 SK_U64 PrevPort0TxIntrCts;
342 SK_U64 PrevPort1TxIntrCts;
343 SK_BOOL ModJustEnabled; /* Moderation just enabled yes/no */
344
345 int MaxModIntsPerSec; /* Moderation Threshold */
346 int MaxModIntsPerSecUpperLimit; /* Upper limit for DIM */
347 int MaxModIntsPerSecLowerLimit; /* Lower limit for DIM */
348
349 long MaskIrqModeration; /* ModIrqType (eg. 'TxRx') */
350 SK_BOOL DisplayStats; /* Stats yes/no */
351 SK_BOOL AutoSizing; /* Resize DIM-timer on/off */
352 int IntModTypeSelect; /* EnableIntMod (eg. 'dynamic') */
353
354 SK_TIMER ModTimer; /* just some timer */
355};
356
357typedef struct s_PerStrm PER_STRM;
358
359#define SK_ALLOC_IRQ 0x00000001
360
361#ifdef SK_DIAG_SUPPORT
362#define DIAG_ACTIVE 1
363#define DIAG_NOTACTIVE 0
364#endif
365
366/****************************************************************************
367 * Per board structure / Adapter Context structure:
368 * Allocated within attach(9e) and freed within detach(9e).
369 * Contains all 'per device' necessary handles, flags, locks etc.:
370 */
371struct s_AC {
372 SK_GEINIT GIni; /* GE init struct */
373 SK_PNMI Pnmi; /* PNMI data struct */
374 SK_VPD vpd; /* vpd data struct */
375 SK_QUEUE Event; /* Event queue */
376 SK_HWT Hwt; /* Hardware Timer control struct */
377 SK_TIMCTRL Tim; /* Software Timer control struct */
378 SK_I2C I2c; /* I2C relevant data structure */
379 SK_ADDR Addr; /* for Address module */
380 SK_CSUM Csum; /* for checksum module */
381 SK_RLMT Rlmt; /* for rlmt module */
382 spinlock_t SlowPathLock; /* Normal IRQ lock */
383 struct timer_list BlinkTimer; /* for LED blinking */
384 int LedsOn;
385 SK_PNMI_STRUCT_DATA PnmiStruct; /* structure to get all Pnmi-Data */
386 int RlmtMode; /* link check mode to set */
387 int RlmtNets; /* Number of nets */
388
389 SK_IOC IoBase; /* register set of adapter */
390 int BoardLevel; /* level of active hw init (0-2) */
391
392 SK_U32 AllocFlag; /* flag allocation of resources */
393 struct pci_dev *PciDev; /* for access to pci config space */
394 struct SK_NET_DEVICE *dev[2]; /* pointer to device struct */
395
396 int RxBufSize; /* length of receive buffers */
397 struct net_device_stats stats; /* linux 'netstat -i' statistics */
398 int Index; /* internal board index number */
399
400 /* adapter RAM sizes for queues of active port */
401 int RxQueueSize; /* memory used for receive queue */
402 int TxSQueueSize; /* memory used for sync. tx queue */
403 int TxAQueueSize; /* memory used for async. tx queue */
404
405 int PromiscCount; /* promiscuous mode counter */
406 int AllMultiCount; /* allmulticast mode counter */
407 int MulticCount; /* number of different MC */
408 /* addresses for this board */
409 /* (may be more than HW can)*/
410
411 int HWRevision; /* Hardware revision */
412 int ActivePort; /* the active XMAC port */
413 int MaxPorts; /* number of activated ports */
414 int TxDescrPerRing; /* # of descriptors per tx ring */
415 int RxDescrPerRing; /* # of descriptors per rx ring */
416
417 caddr_t pDescrMem; /* Pointer to the descriptor area */
418 dma_addr_t pDescrMemDMA; /* PCI DMA address of area */
419
420 /* the port structures with descriptor rings */
421 TX_PORT TxPort[SK_MAX_MACS][2];
422 RX_PORT RxPort[SK_MAX_MACS];
423
424 SK_BOOL CheckQueue; /* check event queue soon */
425 SK_TIMER DrvCleanupTimer;/* to check for pending descriptors */
426 DIM_INFO DynIrqModInfo; /* all data related to DIM */
427
428 /* Only for tests */
429 int PortDown;
430 int ChipsetType; /* Chipset family type
431 * 0 == Genesis family support
432 * 1 == Yukon family support
433 */
434#ifdef SK_DIAG_SUPPORT
435 SK_U32 DiagModeActive; /* is diag active? */
436 SK_BOOL DiagFlowCtrl; /* for control purposes */
437 SK_PNMI_STRUCT_DATA PnmiBackup; /* backup structure for all Pnmi-Data */
438 SK_BOOL WasIfUp[SK_MAX_MACS]; /* for OpenClose while
439 * DIAG is busy with NIC
440 */
441#endif
442
443};
444
445
446#endif /* __INC_SKDRV2ND_H */
447
diff --git a/drivers/net/sk98lin/h/skerror.h b/drivers/net/sk98lin/h/skerror.h
deleted file mode 100644
index da062f766238..000000000000
--- a/drivers/net/sk98lin/h/skerror.h
+++ /dev/null
@@ -1,55 +0,0 @@
1/******************************************************************************
2 *
3 * Name: skerror.h
4 * Project: Gigabit Ethernet Adapters, Common Modules
5 * Version: $Revision: 1.7 $
6 * Date: $Date: 2003/05/13 17:25:13 $
7 * Purpose: SK specific Error log support
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25#ifndef _INC_SKERROR_H_
26#define _INC_SKERROR_H_
27
28/*
29 * Define Error Classes
30 */
31#define SK_ERRCL_OTHER (0) /* Other error */
32#define SK_ERRCL_CONFIG (1L<<0) /* Configuration error */
33#define SK_ERRCL_INIT (1L<<1) /* Initialization error */
34#define SK_ERRCL_NORES (1L<<2) /* Out of Resources error */
35#define SK_ERRCL_SW (1L<<3) /* Internal Software error */
36#define SK_ERRCL_HW (1L<<4) /* Hardware Failure */
37#define SK_ERRCL_COMM (1L<<5) /* Communication error */
38
39
40/*
41 * Define Error Code Bases
42 */
43#define SK_ERRBASE_RLMT 100 /* Base Error number for RLMT */
44#define SK_ERRBASE_HWINIT 200 /* Base Error number for HWInit */
45#define SK_ERRBASE_VPD 300 /* Base Error number for VPD */
46#define SK_ERRBASE_PNMI 400 /* Base Error number for PNMI */
47#define SK_ERRBASE_CSUM 500 /* Base Error number for Checksum */
48#define SK_ERRBASE_SIRQ 600 /* Base Error number for Special IRQ */
49#define SK_ERRBASE_I2C 700 /* Base Error number for I2C module */
50#define SK_ERRBASE_QUEUE 800 /* Base Error number for Scheduler */
51#define SK_ERRBASE_ADDR 900 /* Base Error number for Address module */
52#define SK_ERRBASE_PECP 1000 /* Base Error number for PECP */
53#define SK_ERRBASE_DRV 1100 /* Base Error number for Driver */
54
55#endif /* _INC_SKERROR_H_ */
diff --git a/drivers/net/sk98lin/h/skgedrv.h b/drivers/net/sk98lin/h/skgedrv.h
deleted file mode 100644
index 44fd4c3de818..000000000000
--- a/drivers/net/sk98lin/h/skgedrv.h
+++ /dev/null
@@ -1,51 +0,0 @@
1/******************************************************************************
2 *
3 * Name: skgedrv.h
4 * Project: Gigabit Ethernet Adapters, Common Modules
5 * Version: $Revision: 1.10 $
6 * Date: $Date: 2003/07/04 12:25:01 $
7 * Purpose: Interface with the driver
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25#ifndef __INC_SKGEDRV_H_
26#define __INC_SKGEDRV_H_
27
28/* defines ********************************************************************/
29
30/*
31 * Define the driver events.
32 * Usually the events are defined by the destination module.
33 * In case of the driver we put the definition of the events here.
34 */
35#define SK_DRV_PORT_RESET 1 /* The port needs to be reset */
36#define SK_DRV_NET_UP 2 /* The net is operational */
37#define SK_DRV_NET_DOWN 3 /* The net is down */
38#define SK_DRV_SWITCH_SOFT 4 /* Ports switch with both links connected */
39#define SK_DRV_SWITCH_HARD 5 /* Port switch due to link failure */
40#define SK_DRV_RLMT_SEND 6 /* Send a RLMT packet */
41#define SK_DRV_ADAP_FAIL 7 /* The whole adapter fails */
42#define SK_DRV_PORT_FAIL 8 /* One port fails */
43#define SK_DRV_SWITCH_INTERN 9 /* Port switch by the driver itself */
44#define SK_DRV_POWER_DOWN 10 /* Power down mode */
45#define SK_DRV_TIMER 11 /* Timer for free use */
46#ifdef SK_NO_RLMT
47#define SK_DRV_LINK_UP 12 /* Link Up event for driver */
48#define SK_DRV_LINK_DOWN 13 /* Link Down event for driver */
49#endif
50#define SK_DRV_DOWNSHIFT_DET 14 /* Downshift 4-Pair / 2-Pair (YUKON only) */
51#endif /* __INC_SKGEDRV_H_ */
diff --git a/drivers/net/sk98lin/h/skgehw.h b/drivers/net/sk98lin/h/skgehw.h
deleted file mode 100644
index f6282b7956db..000000000000
--- a/drivers/net/sk98lin/h/skgehw.h
+++ /dev/null
@@ -1,2126 +0,0 @@
1/******************************************************************************
2 *
3 * Name: skgehw.h
4 * Project: Gigabit Ethernet Adapters, Common Modules
5 * Version: $Revision: 1.56 $
6 * Date: $Date: 2003/09/23 09:01:00 $
7 * Purpose: Defines and Macros for the Gigabit Ethernet Adapter Product Family
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25#ifndef __INC_SKGEHW_H
26#define __INC_SKGEHW_H
27
28#ifdef __cplusplus
29extern "C" {
30#endif /* __cplusplus */
31
32/* defines ********************************************************************/
33
34#define BIT_31 (1UL << 31)
35#define BIT_30 (1L << 30)
36#define BIT_29 (1L << 29)
37#define BIT_28 (1L << 28)
38#define BIT_27 (1L << 27)
39#define BIT_26 (1L << 26)
40#define BIT_25 (1L << 25)
41#define BIT_24 (1L << 24)
42#define BIT_23 (1L << 23)
43#define BIT_22 (1L << 22)
44#define BIT_21 (1L << 21)
45#define BIT_20 (1L << 20)
46#define BIT_19 (1L << 19)
47#define BIT_18 (1L << 18)
48#define BIT_17 (1L << 17)
49#define BIT_16 (1L << 16)
50#define BIT_15 (1L << 15)
51#define BIT_14 (1L << 14)
52#define BIT_13 (1L << 13)
53#define BIT_12 (1L << 12)
54#define BIT_11 (1L << 11)
55#define BIT_10 (1L << 10)
56#define BIT_9 (1L << 9)
57#define BIT_8 (1L << 8)
58#define BIT_7 (1L << 7)
59#define BIT_6 (1L << 6)
60#define BIT_5 (1L << 5)
61#define BIT_4 (1L << 4)
62#define BIT_3 (1L << 3)
63#define BIT_2 (1L << 2)
64#define BIT_1 (1L << 1)
65#define BIT_0 1L
66
67#define BIT_15S (1U << 15)
68#define BIT_14S (1 << 14)
69#define BIT_13S (1 << 13)
70#define BIT_12S (1 << 12)
71#define BIT_11S (1 << 11)
72#define BIT_10S (1 << 10)
73#define BIT_9S (1 << 9)
74#define BIT_8S (1 << 8)
75#define BIT_7S (1 << 7)
76#define BIT_6S (1 << 6)
77#define BIT_5S (1 << 5)
78#define BIT_4S (1 << 4)
79#define BIT_3S (1 << 3)
80#define BIT_2S (1 << 2)
81#define BIT_1S (1 << 1)
82#define BIT_0S 1
83
84#define SHIFT31(x) ((x) << 31)
85#define SHIFT30(x) ((x) << 30)
86#define SHIFT29(x) ((x) << 29)
87#define SHIFT28(x) ((x) << 28)
88#define SHIFT27(x) ((x) << 27)
89#define SHIFT26(x) ((x) << 26)
90#define SHIFT25(x) ((x) << 25)
91#define SHIFT24(x) ((x) << 24)
92#define SHIFT23(x) ((x) << 23)
93#define SHIFT22(x) ((x) << 22)
94#define SHIFT21(x) ((x) << 21)
95#define SHIFT20(x) ((x) << 20)
96#define SHIFT19(x) ((x) << 19)
97#define SHIFT18(x) ((x) << 18)
98#define SHIFT17(x) ((x) << 17)
99#define SHIFT16(x) ((x) << 16)
100#define SHIFT15(x) ((x) << 15)
101#define SHIFT14(x) ((x) << 14)
102#define SHIFT13(x) ((x) << 13)
103#define SHIFT12(x) ((x) << 12)
104#define SHIFT11(x) ((x) << 11)
105#define SHIFT10(x) ((x) << 10)
106#define SHIFT9(x) ((x) << 9)
107#define SHIFT8(x) ((x) << 8)
108#define SHIFT7(x) ((x) << 7)
109#define SHIFT6(x) ((x) << 6)
110#define SHIFT5(x) ((x) << 5)
111#define SHIFT4(x) ((x) << 4)
112#define SHIFT3(x) ((x) << 3)
113#define SHIFT2(x) ((x) << 2)
114#define SHIFT1(x) ((x) << 1)
115#define SHIFT0(x) ((x) << 0)
116
117/*
118 * Configuration Space header
119 * Since this module is used for different OS', those may be
120 * duplicate on some of them (e.g. Linux). But to keep the
121 * common source, we have to live with this...
122 */
123#define PCI_VENDOR_ID 0x00 /* 16 bit Vendor ID */
124#define PCI_DEVICE_ID 0x02 /* 16 bit Device ID */
125#define PCI_COMMAND 0x04 /* 16 bit Command */
126#define PCI_STATUS 0x06 /* 16 bit Status */
127#define PCI_REV_ID 0x08 /* 8 bit Revision ID */
128#define PCI_CLASS_CODE 0x09 /* 24 bit Class Code */
129#define PCI_CACHE_LSZ 0x0c /* 8 bit Cache Line Size */
130#define PCI_LAT_TIM 0x0d /* 8 bit Latency Timer */
131#define PCI_HEADER_T 0x0e /* 8 bit Header Type */
132#define PCI_BIST 0x0f /* 8 bit Built-in selftest */
133#define PCI_BASE_1ST 0x10 /* 32 bit 1st Base address */
134#define PCI_BASE_2ND 0x14 /* 32 bit 2nd Base address */
135 /* Byte 0x18..0x2b: reserved */
136#define PCI_SUB_VID 0x2c /* 16 bit Subsystem Vendor ID */
137#define PCI_SUB_ID 0x2e /* 16 bit Subsystem ID */
138#define PCI_BASE_ROM 0x30 /* 32 bit Expansion ROM Base Address */
139#define PCI_CAP_PTR 0x34 /* 8 bit Capabilities Ptr */
140 /* Byte 0x35..0x3b: reserved */
141#define PCI_IRQ_LINE 0x3c /* 8 bit Interrupt Line */
142#define PCI_IRQ_PIN 0x3d /* 8 bit Interrupt Pin */
143#define PCI_MIN_GNT 0x3e /* 8 bit Min_Gnt */
144#define PCI_MAX_LAT 0x3f /* 8 bit Max_Lat */
145 /* Device Dependent Region */
146#define PCI_OUR_REG_1 0x40 /* 32 bit Our Register 1 */
147#define PCI_OUR_REG_2 0x44 /* 32 bit Our Register 2 */
148 /* Power Management Region */
149#define PCI_PM_CAP_ID 0x48 /* 8 bit Power Management Cap. ID */
150#define PCI_PM_NITEM 0x49 /* 8 bit Next Item Ptr */
151#define PCI_PM_CAP_REG 0x4a /* 16 bit Power Management Capabilities */
152#define PCI_PM_CTL_STS 0x4c /* 16 bit Power Manag. Control/Status */
153 /* Byte 0x4e: reserved */
154#define PCI_PM_DAT_REG 0x4f /* 8 bit Power Manag. Data Register */
155 /* VPD Region */
156#define PCI_VPD_CAP_ID 0x50 /* 8 bit VPD Cap. ID */
157#define PCI_VPD_NITEM 0x51 /* 8 bit Next Item Ptr */
158#define PCI_VPD_ADR_REG 0x52 /* 16 bit VPD Address Register */
159#define PCI_VPD_DAT_REG 0x54 /* 32 bit VPD Data Register */
160 /* Byte 0x58..0x59: reserved */
161#define PCI_SER_LD_CTRL 0x5a /* 16 bit SEEPROM Loader Ctrl (YUKON only) */
162 /* Byte 0x5c..0xff: reserved */
163
164/*
165 * I2C Address (PCI Config)
166 *
167 * Note: The temperature and voltage sensors are relocated on a different
168 * I2C bus.
169 */
170#define I2C_ADDR_VPD 0xa0 /* I2C address for the VPD EEPROM */
171
172/*
173 * Define Bits and Values of the registers
174 */
175/* PCI_COMMAND 16 bit Command */
176 /* Bit 15..11: reserved */
177#define PCI_INT_DIS BIT_10S /* Interrupt INTx# disable (PCI 2.3) */
178#define PCI_FBTEN BIT_9S /* Fast Back-To-Back enable */
179#define PCI_SERREN BIT_8S /* SERR enable */
180#define PCI_ADSTEP BIT_7S /* Address Stepping */
181#define PCI_PERREN BIT_6S /* Parity Report Response enable */
182#define PCI_VGA_SNOOP BIT_5S /* VGA palette snoop */
183#define PCI_MWIEN BIT_4S /* Memory write an inv cycl ena */
184#define PCI_SCYCEN BIT_3S /* Special Cycle enable */
185#define PCI_BMEN BIT_2S /* Bus Master enable */
186#define PCI_MEMEN BIT_1S /* Memory Space Access enable */
187#define PCI_IOEN BIT_0S /* I/O Space Access enable */
188
189#define PCI_COMMAND_VAL (PCI_FBTEN | PCI_SERREN | PCI_PERREN | PCI_MWIEN |\
190 PCI_BMEN | PCI_MEMEN | PCI_IOEN)
191
192/* PCI_STATUS 16 bit Status */
193#define PCI_PERR BIT_15S /* Parity Error */
194#define PCI_SERR BIT_14S /* Signaled SERR */
195#define PCI_RMABORT BIT_13S /* Received Master Abort */
196#define PCI_RTABORT BIT_12S /* Received Target Abort */
197 /* Bit 11: reserved */
198#define PCI_DEVSEL (3<<9) /* Bit 10.. 9: DEVSEL Timing */
199#define PCI_DEV_FAST (0<<9) /* fast */
200#define PCI_DEV_MEDIUM (1<<9) /* medium */
201#define PCI_DEV_SLOW (2<<9) /* slow */
202#define PCI_DATAPERR BIT_8S /* DATA Parity error detected */
203#define PCI_FB2BCAP BIT_7S /* Fast Back-to-Back Capability */
204#define PCI_UDF BIT_6S /* User Defined Features */
205#define PCI_66MHZCAP BIT_5S /* 66 MHz PCI bus clock capable */
206#define PCI_NEWCAP BIT_4S /* New cap. list implemented */
207#define PCI_INT_STAT BIT_3S /* Interrupt INTx# Status (PCI 2.3) */
208 /* Bit 2.. 0: reserved */
209
210#define PCI_ERRBITS (PCI_PERR | PCI_SERR | PCI_RMABORT | PCI_RTABORT |\
211 PCI_DATAPERR)
212
213/* PCI_CLASS_CODE 24 bit Class Code */
214/* Byte 2: Base Class (02) */
215/* Byte 1: SubClass (00) */
216/* Byte 0: Programming Interface (00) */
217
218/* PCI_CACHE_LSZ 8 bit Cache Line Size */
219/* Possible values: 0,2,4,8,16,32,64,128 */
220
221/* PCI_HEADER_T 8 bit Header Type */
222#define PCI_HD_MF_DEV BIT_7S /* 0= single, 1= multi-func dev */
223#define PCI_HD_TYPE 0x7f /* Bit 6..0: Header Layout 0= normal */
224
225/* PCI_BIST 8 bit Built-in selftest */
226/* Built-in Self test not supported (optional) */
227
228/* PCI_BASE_1ST 32 bit 1st Base address */
229#define PCI_MEMSIZE 0x4000L /* use 16 kB Memory Base */
230#define PCI_MEMBASE_MSK 0xffffc000L /* Bit 31..14: Memory Base Address */
231#define PCI_MEMSIZE_MSK 0x00003ff0L /* Bit 13.. 4: Memory Size Req. */
232#define PCI_PREFEN BIT_3 /* Prefetchable */
233#define PCI_MEM_TYP (3L<<2) /* Bit 2.. 1: Memory Type */
234#define PCI_MEM32BIT (0L<<1) /* Base addr anywhere in 32 Bit range */
235#define PCI_MEM1M (1L<<1) /* Base addr below 1 MegaByte */
236#define PCI_MEM64BIT (2L<<1) /* Base addr anywhere in 64 Bit range */
237#define PCI_MEMSPACE BIT_0 /* Memory Space Indicator */
238
239/* PCI_BASE_2ND 32 bit 2nd Base address */
240#define PCI_IOBASE 0xffffff00L /* Bit 31.. 8: I/O Base address */
241#define PCI_IOSIZE 0x000000fcL /* Bit 7.. 2: I/O Size Requirements */
242 /* Bit 1: reserved */
243#define PCI_IOSPACE BIT_0 /* I/O Space Indicator */
244
245/* PCI_BASE_ROM 32 bit Expansion ROM Base Address */
246#define PCI_ROMBASE_MSK 0xfffe0000L /* Bit 31..17: ROM Base address */
247#define PCI_ROMBASE_SIZ (0x1cL<<14) /* Bit 16..14: Treat as Base or Size */
248#define PCI_ROMSIZE (0x38L<<11) /* Bit 13..11: ROM Size Requirements */
249 /* Bit 10.. 1: reserved */
250#define PCI_ROMEN BIT_0 /* Address Decode enable */
251
252/* Device Dependent Region */
253/* PCI_OUR_REG_1 32 bit Our Register 1 */
254 /* Bit 31..29: reserved */
255#define PCI_PHY_COMA BIT_28 /* Set PHY to Coma Mode (YUKON only) */
256#define PCI_TEST_CAL BIT_27 /* Test PCI buffer calib. (YUKON only) */
257#define PCI_EN_CAL BIT_26 /* Enable PCI buffer calib. (YUKON only) */
258#define PCI_VIO BIT_25 /* PCI I/O Voltage, 0 = 3.3V, 1 = 5V */
259#define PCI_DIS_BOOT BIT_24 /* Disable BOOT via ROM */
260#define PCI_EN_IO BIT_23 /* Mapping to I/O space */
261#define PCI_EN_FPROM BIT_22 /* Enable FLASH mapping to memory */
262 /* 1 = Map Flash to memory */
263 /* 0 = Disable addr. dec */
264#define PCI_PAGESIZE (3L<<20) /* Bit 21..20: FLASH Page Size */
265#define PCI_PAGE_16 (0L<<20) /* 16 k pages */
266#define PCI_PAGE_32K (1L<<20) /* 32 k pages */
267#define PCI_PAGE_64K (2L<<20) /* 64 k pages */
268#define PCI_PAGE_128K (3L<<20) /* 128 k pages */
269 /* Bit 19: reserved */
270#define PCI_PAGEREG (7L<<16) /* Bit 18..16: Page Register */
271#define PCI_NOTAR BIT_15 /* No turnaround cycle */
272#define PCI_FORCE_BE BIT_14 /* Assert all BEs on MR */
273#define PCI_DIS_MRL BIT_13 /* Disable Mem Read Line */
274#define PCI_DIS_MRM BIT_12 /* Disable Mem Read Multiple */
275#define PCI_DIS_MWI BIT_11 /* Disable Mem Write & Invalidate */
276#define PCI_DISC_CLS BIT_10 /* Disc: cacheLsz bound */
277#define PCI_BURST_DIS BIT_9 /* Burst Disable */
278#define PCI_DIS_PCI_CLK BIT_8 /* Disable PCI clock driving */
279#define PCI_SKEW_DAS (0xfL<<4) /* Bit 7.. 4: Skew Ctrl, DAS Ext */
280#define PCI_SKEW_BASE 0xfL /* Bit 3.. 0: Skew Ctrl, Base */
281
282
283/* PCI_OUR_REG_2 32 bit Our Register 2 */
284#define PCI_VPD_WR_THR (0xffL<<24) /* Bit 31..24: VPD Write Threshold */
285#define PCI_DEV_SEL (0x7fL<<17) /* Bit 23..17: EEPROM Device Select */
286#define PCI_VPD_ROM_SZ (7L<<14) /* Bit 16..14: VPD ROM Size */
287 /* Bit 13..12: reserved */
288#define PCI_PATCH_DIR (0xfL<<8) /* Bit 11.. 8: Ext Patches dir 3..0 */
289#define PCI_PATCH_DIR_3 BIT_11
290#define PCI_PATCH_DIR_2 BIT_10
291#define PCI_PATCH_DIR_1 BIT_9
292#define PCI_PATCH_DIR_0 BIT_8
293#define PCI_EXT_PATCHS (0xfL<<4) /* Bit 7.. 4: Extended Patches 3..0 */
294#define PCI_EXT_PATCH_3 BIT_7
295#define PCI_EXT_PATCH_2 BIT_6
296#define PCI_EXT_PATCH_1 BIT_5
297#define PCI_EXT_PATCH_0 BIT_4
298#define PCI_EN_DUMMY_RD BIT_3 /* Enable Dummy Read */
299#define PCI_REV_DESC BIT_2 /* Reverse Desc. Bytes */
300 /* Bit 1: reserved */
301#define PCI_USEDATA64 BIT_0 /* Use 64Bit Data bus ext */
302
303
304/* Power Management Region */
305/* PCI_PM_CAP_REG 16 bit Power Management Capabilities */
306#define PCI_PME_SUP_MSK (0x1f<<11) /* Bit 15..11: PM Event Support Mask */
307#define PCI_PME_D3C_SUP BIT_15S /* PME from D3cold Support (if Vaux) */
308#define PCI_PME_D3H_SUP BIT_14S /* PME from D3hot Support */
309#define PCI_PME_D2_SUP BIT_13S /* PME from D2 Support */
310#define PCI_PME_D1_SUP BIT_12S /* PME from D1 Support */
311#define PCI_PME_D0_SUP BIT_11S /* PME from D0 Support */
312#define PCI_PM_D2_SUP BIT_10S /* D2 Support in 33 MHz mode */
313#define PCI_PM_D1_SUP BIT_9S /* D1 Support */
314 /* Bit 8.. 6: reserved */
315#define PCI_PM_DSI BIT_5S /* Device Specific Initialization */
316#define PCI_PM_APS BIT_4S /* Auxialiary Power Source */
317#define PCI_PME_CLOCK BIT_3S /* PM Event Clock */
318#define PCI_PM_VER_MSK 7 /* Bit 2.. 0: PM PCI Spec. version */
319
320/* PCI_PM_CTL_STS 16 bit Power Management Control/Status */
321#define PCI_PME_STATUS BIT_15S /* PME Status (YUKON only) */
322#define PCI_PM_DAT_SCL (3<<13) /* Bit 14..13: Data Reg. scaling factor */
323#define PCI_PM_DAT_SEL (0xf<<9) /* Bit 12.. 9: PM data selector field */
324#define PCI_PME_EN BIT_8S /* Enable PME# generation (YUKON only) */
325 /* Bit 7.. 2: reserved */
326#define PCI_PM_STATE_MSK 3 /* Bit 1.. 0: Power Management State */
327
328#define PCI_PM_STATE_D0 0 /* D0: Operational (default) */
329#define PCI_PM_STATE_D1 1 /* D1: (YUKON only) */
330#define PCI_PM_STATE_D2 2 /* D2: (YUKON only) */
331#define PCI_PM_STATE_D3 3 /* D3: HOT, Power Down and Reset */
332
333/* VPD Region */
334/* PCI_VPD_ADR_REG 16 bit VPD Address Register */
335#define PCI_VPD_FLAG BIT_15S /* starts VPD rd/wr cycle */
336#define PCI_VPD_ADR_MSK 0x7fffL /* Bit 14.. 0: VPD address mask */
337
338/* Control Register File (Address Map) */
339
340/*
341 * Bank 0
342 */
343#define B0_RAP 0x0000 /* 8 bit Register Address Port */
344 /* 0x0001 - 0x0003: reserved */
345#define B0_CTST 0x0004 /* 16 bit Control/Status register */
346#define B0_LED 0x0006 /* 8 Bit LED register */
347#define B0_POWER_CTRL 0x0007 /* 8 Bit Power Control reg (YUKON only) */
348#define B0_ISRC 0x0008 /* 32 bit Interrupt Source Register */
349#define B0_IMSK 0x000c /* 32 bit Interrupt Mask Register */
350#define B0_HWE_ISRC 0x0010 /* 32 bit HW Error Interrupt Src Reg */
351#define B0_HWE_IMSK 0x0014 /* 32 bit HW Error Interrupt Mask Reg */
352#define B0_SP_ISRC 0x0018 /* 32 bit Special Interrupt Source Reg */
353 /* 0x001c: reserved */
354
355/* B0 XMAC 1 registers (GENESIS only) */
356#define B0_XM1_IMSK 0x0020 /* 16 bit r/w XMAC 1 Interrupt Mask Register*/
357 /* 0x0022 - 0x0027: reserved */
358#define B0_XM1_ISRC 0x0028 /* 16 bit ro XMAC 1 Interrupt Status Reg */
359 /* 0x002a - 0x002f: reserved */
360#define B0_XM1_PHY_ADDR 0x0030 /* 16 bit r/w XMAC 1 PHY Address Register */
361 /* 0x0032 - 0x0033: reserved */
362#define B0_XM1_PHY_DATA 0x0034 /* 16 bit r/w XMAC 1 PHY Data Register */
363 /* 0x0036 - 0x003f: reserved */
364
365/* B0 XMAC 2 registers (GENESIS only) */
366#define B0_XM2_IMSK 0x0040 /* 16 bit r/w XMAC 2 Interrupt Mask Register*/
367 /* 0x0042 - 0x0047: reserved */
368#define B0_XM2_ISRC 0x0048 /* 16 bit ro XMAC 2 Interrupt Status Reg */
369 /* 0x004a - 0x004f: reserved */
370#define B0_XM2_PHY_ADDR 0x0050 /* 16 bit r/w XMAC 2 PHY Address Register */
371 /* 0x0052 - 0x0053: reserved */
372#define B0_XM2_PHY_DATA 0x0054 /* 16 bit r/w XMAC 2 PHY Data Register */
373 /* 0x0056 - 0x005f: reserved */
374
375/* BMU Control Status Registers */
376#define B0_R1_CSR 0x0060 /* 32 bit BMU Ctrl/Stat Rx Queue 1 */
377#define B0_R2_CSR 0x0064 /* 32 bit BMU Ctrl/Stat Rx Queue 2 */
378#define B0_XS1_CSR 0x0068 /* 32 bit BMU Ctrl/Stat Sync Tx Queue 1 */
379#define B0_XA1_CSR 0x006c /* 32 bit BMU Ctrl/Stat Async Tx Queue 1*/
380#define B0_XS2_CSR 0x0070 /* 32 bit BMU Ctrl/Stat Sync Tx Queue 2 */
381#define B0_XA2_CSR 0x0074 /* 32 bit BMU Ctrl/Stat Async Tx Queue 2*/
382 /* 0x0078 - 0x007f: reserved */
383
384/*
385 * Bank 1
386 * - completely empty (this is the RAP Block window)
387 * Note: if RAP = 1 this page is reserved
388 */
389
390/*
391 * Bank 2
392 */
393/* NA reg = 48 bit Network Address Register, 3x16 or 8x8 bit readable */
394#define B2_MAC_1 0x0100 /* NA reg MAC Address 1 */
395 /* 0x0106 - 0x0107: reserved */
396#define B2_MAC_2 0x0108 /* NA reg MAC Address 2 */
397 /* 0x010e - 0x010f: reserved */
398#define B2_MAC_3 0x0110 /* NA reg MAC Address 3 */
399 /* 0x0116 - 0x0117: reserved */
400#define B2_CONN_TYP 0x0118 /* 8 bit Connector type */
401#define B2_PMD_TYP 0x0119 /* 8 bit PMD type */
402#define B2_MAC_CFG 0x011a /* 8 bit MAC Configuration / Chip Revision */
403#define B2_CHIP_ID 0x011b /* 8 bit Chip Identification Number */
404 /* Eprom registers are currently of no use */
405#define B2_E_0 0x011c /* 8 bit EPROM Byte 0 (ext. SRAM size */
406#define B2_E_1 0x011d /* 8 bit EPROM Byte 1 (PHY type) */
407#define B2_E_2 0x011e /* 8 bit EPROM Byte 2 */
408#define B2_E_3 0x011f /* 8 bit EPROM Byte 3 */
409#define B2_FAR 0x0120 /* 32 bit Flash-Prom Addr Reg/Cnt */
410#define B2_FDP 0x0124 /* 8 bit Flash-Prom Data Port */
411 /* 0x0125 - 0x0127: reserved */
412#define B2_LD_CTRL 0x0128 /* 8 bit EPROM loader control register */
413#define B2_LD_TEST 0x0129 /* 8 bit EPROM loader test register */
414 /* 0x012a - 0x012f: reserved */
415#define B2_TI_INI 0x0130 /* 32 bit Timer Init Value */
416#define B2_TI_VAL 0x0134 /* 32 bit Timer Value */
417#define B2_TI_CTRL 0x0138 /* 8 bit Timer Control */
418#define B2_TI_TEST 0x0139 /* 8 Bit Timer Test */
419 /* 0x013a - 0x013f: reserved */
420#define B2_IRQM_INI 0x0140 /* 32 bit IRQ Moderation Timer Init Reg.*/
421#define B2_IRQM_VAL 0x0144 /* 32 bit IRQ Moderation Timer Value */
422#define B2_IRQM_CTRL 0x0148 /* 8 bit IRQ Moderation Timer Control */
423#define B2_IRQM_TEST 0x0149 /* 8 bit IRQ Moderation Timer Test */
424#define B2_IRQM_MSK 0x014c /* 32 bit IRQ Moderation Mask */
425#define B2_IRQM_HWE_MSK 0x0150 /* 32 bit IRQ Moderation HW Error Mask */
426 /* 0x0154 - 0x0157: reserved */
427#define B2_TST_CTRL1 0x0158 /* 8 bit Test Control Register 1 */
428#define B2_TST_CTRL2 0x0159 /* 8 bit Test Control Register 2 */
429 /* 0x015a - 0x015b: reserved */
430#define B2_GP_IO 0x015c /* 32 bit General Purpose I/O Register */
431#define B2_I2C_CTRL 0x0160 /* 32 bit I2C HW Control Register */
432#define B2_I2C_DATA 0x0164 /* 32 bit I2C HW Data Register */
433#define B2_I2C_IRQ 0x0168 /* 32 bit I2C HW IRQ Register */
434#define B2_I2C_SW 0x016c /* 32 bit I2C SW Port Register */
435
436/* Blink Source Counter (GENESIS only) */
437#define B2_BSC_INI 0x0170 /* 32 bit Blink Source Counter Init Val */
438#define B2_BSC_VAL 0x0174 /* 32 bit Blink Source Counter Value */
439#define B2_BSC_CTRL 0x0178 /* 8 bit Blink Source Counter Control */
440#define B2_BSC_STAT 0x0179 /* 8 bit Blink Source Counter Status */
441#define B2_BSC_TST 0x017a /* 16 bit Blink Source Counter Test Reg */
442 /* 0x017c - 0x017f: reserved */
443
444/*
445 * Bank 3
446 */
447/* RAM Random Registers */
448#define B3_RAM_ADDR 0x0180 /* 32 bit RAM Address, to read or write */
449#define B3_RAM_DATA_LO 0x0184 /* 32 bit RAM Data Word (low dWord) */
450#define B3_RAM_DATA_HI 0x0188 /* 32 bit RAM Data Word (high dWord) */
451 /* 0x018c - 0x018f: reserved */
452
453/* RAM Interface Registers */
454/*
455 * The HW-Spec. calls this registers Timeout Value 0..11. But this names are
456 * not usable in SW. Please notice these are NOT real timeouts, these are
457 * the number of qWords transferred continuously.
458 */
459#define B3_RI_WTO_R1 0x0190 /* 8 bit WR Timeout Queue R1 (TO0) */
460#define B3_RI_WTO_XA1 0x0191 /* 8 bit WR Timeout Queue XA1 (TO1) */
461#define B3_RI_WTO_XS1 0x0192 /* 8 bit WR Timeout Queue XS1 (TO2) */
462#define B3_RI_RTO_R1 0x0193 /* 8 bit RD Timeout Queue R1 (TO3) */
463#define B3_RI_RTO_XA1 0x0194 /* 8 bit RD Timeout Queue XA1 (TO4) */
464#define B3_RI_RTO_XS1 0x0195 /* 8 bit RD Timeout Queue XS1 (TO5) */
465#define B3_RI_WTO_R2 0x0196 /* 8 bit WR Timeout Queue R2 (TO6) */
466#define B3_RI_WTO_XA2 0x0197 /* 8 bit WR Timeout Queue XA2 (TO7) */
467#define B3_RI_WTO_XS2 0x0198 /* 8 bit WR Timeout Queue XS2 (TO8) */
468#define B3_RI_RTO_R2 0x0199 /* 8 bit RD Timeout Queue R2 (TO9) */
469#define B3_RI_RTO_XA2 0x019a /* 8 bit RD Timeout Queue XA2 (TO10)*/
470#define B3_RI_RTO_XS2 0x019b /* 8 bit RD Timeout Queue XS2 (TO11)*/
471#define B3_RI_TO_VAL 0x019c /* 8 bit Current Timeout Count Val */
472 /* 0x019d - 0x019f: reserved */
473#define B3_RI_CTRL 0x01a0 /* 16 bit RAM Interface Control Register */
474#define B3_RI_TEST 0x01a2 /* 8 bit RAM Interface Test Register */
475 /* 0x01a3 - 0x01af: reserved */
476
477/* MAC Arbiter Registers (GENESIS only) */
478/* these are the no. of qWord transferred continuously and NOT real timeouts */
479#define B3_MA_TOINI_RX1 0x01b0 /* 8 bit Timeout Init Val Rx Path MAC 1 */
480#define B3_MA_TOINI_RX2 0x01b1 /* 8 bit Timeout Init Val Rx Path MAC 2 */
481#define B3_MA_TOINI_TX1 0x01b2 /* 8 bit Timeout Init Val Tx Path MAC 1 */
482#define B3_MA_TOINI_TX2 0x01b3 /* 8 bit Timeout Init Val Tx Path MAC 2 */
483#define B3_MA_TOVAL_RX1 0x01b4 /* 8 bit Timeout Value Rx Path MAC 1 */
484#define B3_MA_TOVAL_RX2 0x01b5 /* 8 bit Timeout Value Rx Path MAC 1 */
485#define B3_MA_TOVAL_TX1 0x01b6 /* 8 bit Timeout Value Tx Path MAC 2 */
486#define B3_MA_TOVAL_TX2 0x01b7 /* 8 bit Timeout Value Tx Path MAC 2 */
487#define B3_MA_TO_CTRL 0x01b8 /* 16 bit MAC Arbiter Timeout Ctrl Reg */
488#define B3_MA_TO_TEST 0x01ba /* 16 bit MAC Arbiter Timeout Test Reg */
489 /* 0x01bc - 0x01bf: reserved */
490#define B3_MA_RCINI_RX1 0x01c0 /* 8 bit Recovery Init Val Rx Path MAC 1 */
491#define B3_MA_RCINI_RX2 0x01c1 /* 8 bit Recovery Init Val Rx Path MAC 2 */
492#define B3_MA_RCINI_TX1 0x01c2 /* 8 bit Recovery Init Val Tx Path MAC 1 */
493#define B3_MA_RCINI_TX2 0x01c3 /* 8 bit Recovery Init Val Tx Path MAC 2 */
494#define B3_MA_RCVAL_RX1 0x01c4 /* 8 bit Recovery Value Rx Path MAC 1 */
495#define B3_MA_RCVAL_RX2 0x01c5 /* 8 bit Recovery Value Rx Path MAC 1 */
496#define B3_MA_RCVAL_TX1 0x01c6 /* 8 bit Recovery Value Tx Path MAC 2 */
497#define B3_MA_RCVAL_TX2 0x01c7 /* 8 bit Recovery Value Tx Path MAC 2 */
498#define B3_MA_RC_CTRL 0x01c8 /* 16 bit MAC Arbiter Recovery Ctrl Reg */
499#define B3_MA_RC_TEST 0x01ca /* 16 bit MAC Arbiter Recovery Test Reg */
500 /* 0x01cc - 0x01cf: reserved */
501
502/* Packet Arbiter Registers (GENESIS only) */
503/* these are real timeouts */
504#define B3_PA_TOINI_RX1 0x01d0 /* 16 bit Timeout Init Val Rx Path MAC 1 */
505 /* 0x01d2 - 0x01d3: reserved */
506#define B3_PA_TOINI_RX2 0x01d4 /* 16 bit Timeout Init Val Rx Path MAC 2 */
507 /* 0x01d6 - 0x01d7: reserved */
508#define B3_PA_TOINI_TX1 0x01d8 /* 16 bit Timeout Init Val Tx Path MAC 1 */
509 /* 0x01da - 0x01db: reserved */
510#define B3_PA_TOINI_TX2 0x01dc /* 16 bit Timeout Init Val Tx Path MAC 2 */
511 /* 0x01de - 0x01df: reserved */
512#define B3_PA_TOVAL_RX1 0x01e0 /* 16 bit Timeout Val Rx Path MAC 1 */
513 /* 0x01e2 - 0x01e3: reserved */
514#define B3_PA_TOVAL_RX2 0x01e4 /* 16 bit Timeout Val Rx Path MAC 2 */
515 /* 0x01e6 - 0x01e7: reserved */
516#define B3_PA_TOVAL_TX1 0x01e8 /* 16 bit Timeout Val Tx Path MAC 1 */
517 /* 0x01ea - 0x01eb: reserved */
518#define B3_PA_TOVAL_TX2 0x01ec /* 16 bit Timeout Val Tx Path MAC 2 */
519 /* 0x01ee - 0x01ef: reserved */
520#define B3_PA_CTRL 0x01f0 /* 16 bit Packet Arbiter Ctrl Register */
521#define B3_PA_TEST 0x01f2 /* 16 bit Packet Arbiter Test Register */
522 /* 0x01f4 - 0x01ff: reserved */
523
524/*
525 * Bank 4 - 5
526 */
527/* Transmit Arbiter Registers MAC 1 and 2, use MR_ADDR() to access */
528#define TXA_ITI_INI 0x0200 /* 32 bit Tx Arb Interval Timer Init Val*/
529#define TXA_ITI_VAL 0x0204 /* 32 bit Tx Arb Interval Timer Value */
530#define TXA_LIM_INI 0x0208 /* 32 bit Tx Arb Limit Counter Init Val */
531#define TXA_LIM_VAL 0x020c /* 32 bit Tx Arb Limit Counter Value */
532#define TXA_CTRL 0x0210 /* 8 bit Tx Arbiter Control Register */
533#define TXA_TEST 0x0211 /* 8 bit Tx Arbiter Test Register */
534#define TXA_STAT 0x0212 /* 8 bit Tx Arbiter Status Register */
535 /* 0x0213 - 0x027f: reserved */
536 /* 0x0280 - 0x0292: MAC 2 */
537 /* 0x0213 - 0x027f: reserved */
538
539/*
540 * Bank 6
541 */
542/* External registers (GENESIS only) */
543#define B6_EXT_REG 0x0300
544
545/*
546 * Bank 7
547 */
548/* This is a copy of the Configuration register file (lower half) */
549#define B7_CFG_SPC 0x0380
550
551/*
552 * Bank 8 - 15
553 */
554/* Receive and Transmit Queue Registers, use Q_ADDR() to access */
555#define B8_Q_REGS 0x0400
556
557/* Queue Register Offsets, use Q_ADDR() to access */
558#define Q_D 0x00 /* 8*32 bit Current Descriptor */
559#define Q_DA_L 0x20 /* 32 bit Current Descriptor Address Low dWord */
560#define Q_DA_H 0x24 /* 32 bit Current Descriptor Address High dWord */
561#define Q_AC_L 0x28 /* 32 bit Current Address Counter Low dWord */
562#define Q_AC_H 0x2c /* 32 bit Current Address Counter High dWord */
563#define Q_BC 0x30 /* 32 bit Current Byte Counter */
564#define Q_CSR 0x34 /* 32 bit BMU Control/Status Register */
565#define Q_F 0x38 /* 32 bit Flag Register */
566#define Q_T1 0x3c /* 32 bit Test Register 1 */
567#define Q_T1_TR 0x3c /* 8 bit Test Register 1 Transfer SM */
568#define Q_T1_WR 0x3d /* 8 bit Test Register 1 Write Descriptor SM */
569#define Q_T1_RD 0x3e /* 8 bit Test Register 1 Read Descriptor SM */
570#define Q_T1_SV 0x3f /* 8 bit Test Register 1 Supervisor SM */
571#define Q_T2 0x40 /* 32 bit Test Register 2 */
572#define Q_T3 0x44 /* 32 bit Test Register 3 */
573 /* 0x48 - 0x7f: reserved */
574
575/*
576 * Bank 16 - 23
577 */
578/* RAM Buffer Registers */
579#define B16_RAM_REGS 0x0800
580
581/* RAM Buffer Register Offsets, use RB_ADDR() to access */
582#define RB_START 0x00 /* 32 bit RAM Buffer Start Address */
583#define RB_END 0x04 /* 32 bit RAM Buffer End Address */
584#define RB_WP 0x08 /* 32 bit RAM Buffer Write Pointer */
585#define RB_RP 0x0c /* 32 bit RAM Buffer Read Pointer */
586#define RB_RX_UTPP 0x10 /* 32 bit Rx Upper Threshold, Pause Pack */
587#define RB_RX_LTPP 0x14 /* 32 bit Rx Lower Threshold, Pause Pack */
588#define RB_RX_UTHP 0x18 /* 32 bit Rx Upper Threshold, High Prio */
589#define RB_RX_LTHP 0x1c /* 32 bit Rx Lower Threshold, High Prio */
590 /* 0x10 - 0x1f: reserved at Tx RAM Buffer Registers */
591#define RB_PC 0x20 /* 32 bit RAM Buffer Packet Counter */
592#define RB_LEV 0x24 /* 32 bit RAM Buffer Level Register */
593#define RB_CTRL 0x28 /* 8 bit RAM Buffer Control Register */
594#define RB_TST1 0x29 /* 8 bit RAM Buffer Test Register 1 */
595#define RB_TST2 0x2A /* 8 bit RAM Buffer Test Register 2 */
596 /* 0x2c - 0x7f: reserved */
597
598/*
599 * Bank 24
600 */
601/*
602 * Receive MAC FIFO, Receive LED, and Link_Sync regs (GENESIS only)
603 * use MR_ADDR() to access
604 */
605#define RX_MFF_EA 0x0c00 /* 32 bit Receive MAC FIFO End Address */
606#define RX_MFF_WP 0x0c04 /* 32 bit Receive MAC FIFO Write Pointer */
607 /* 0x0c08 - 0x0c0b: reserved */
608#define RX_MFF_RP 0x0c0c /* 32 bit Receive MAC FIFO Read Pointer */
609#define RX_MFF_PC 0x0c10 /* 32 bit Receive MAC FIFO Packet Cnt */
610#define RX_MFF_LEV 0x0c14 /* 32 bit Receive MAC FIFO Level */
611#define RX_MFF_CTRL1 0x0c18 /* 16 bit Receive MAC FIFO Control Reg 1*/
612#define RX_MFF_STAT_TO 0x0c1a /* 8 bit Receive MAC Status Timeout */
613#define RX_MFF_TIST_TO 0x0c1b /* 8 bit Receive MAC Time Stamp Timeout */
614#define RX_MFF_CTRL2 0x0c1c /* 8 bit Receive MAC FIFO Control Reg 2*/
615#define RX_MFF_TST1 0x0c1d /* 8 bit Receive MAC FIFO Test Reg 1 */
616#define RX_MFF_TST2 0x0c1e /* 8 bit Receive MAC FIFO Test Reg 2 */
617 /* 0x0c1f: reserved */
618#define RX_LED_INI 0x0c20 /* 32 bit Receive LED Cnt Init Value */
619#define RX_LED_VAL 0x0c24 /* 32 bit Receive LED Cnt Current Value */
620#define RX_LED_CTRL 0x0c28 /* 8 bit Receive LED Cnt Control Reg */
621#define RX_LED_TST 0x0c29 /* 8 bit Receive LED Cnt Test Register */
622 /* 0x0c2a - 0x0c2f: reserved */
623#define LNK_SYNC_INI 0x0c30 /* 32 bit Link Sync Cnt Init Value */
624#define LNK_SYNC_VAL 0x0c34 /* 32 bit Link Sync Cnt Current Value */
625#define LNK_SYNC_CTRL 0x0c38 /* 8 bit Link Sync Cnt Control Register */
626#define LNK_SYNC_TST 0x0c39 /* 8 bit Link Sync Cnt Test Register */
627 /* 0x0c3a - 0x0c3b: reserved */
628#define LNK_LED_REG 0x0c3c /* 8 bit Link LED Register */
629 /* 0x0c3d - 0x0c3f: reserved */
630
631/* Receive GMAC FIFO (YUKON only), use MR_ADDR() to access */
632#define RX_GMF_EA 0x0c40 /* 32 bit Rx GMAC FIFO End Address */
633#define RX_GMF_AF_THR 0x0c44 /* 32 bit Rx GMAC FIFO Almost Full Thresh. */
634#define RX_GMF_CTRL_T 0x0c48 /* 32 bit Rx GMAC FIFO Control/Test */
635#define RX_GMF_FL_MSK 0x0c4c /* 32 bit Rx GMAC FIFO Flush Mask */
636#define RX_GMF_FL_THR 0x0c50 /* 32 bit Rx GMAC FIFO Flush Threshold */
637 /* 0x0c54 - 0x0c5f: reserved */
638#define RX_GMF_WP 0x0c60 /* 32 bit Rx GMAC FIFO Write Pointer */
639 /* 0x0c64 - 0x0c67: reserved */
640#define RX_GMF_WLEV 0x0c68 /* 32 bit Rx GMAC FIFO Write Level */
641 /* 0x0c6c - 0x0c6f: reserved */
642#define RX_GMF_RP 0x0c70 /* 32 bit Rx GMAC FIFO Read Pointer */
643 /* 0x0c74 - 0x0c77: reserved */
644#define RX_GMF_RLEV 0x0c78 /* 32 bit Rx GMAC FIFO Read Level */
645 /* 0x0c7c - 0x0c7f: reserved */
646
647/*
648 * Bank 25
649 */
650 /* 0x0c80 - 0x0cbf: MAC 2 */
651 /* 0x0cc0 - 0x0cff: reserved */
652
653/*
654 * Bank 26
655 */
656/*
657 * Transmit MAC FIFO and Transmit LED Registers (GENESIS only),
658 * use MR_ADDR() to access
659 */
660#define TX_MFF_EA 0x0d00 /* 32 bit Transmit MAC FIFO End Address */
661#define TX_MFF_WP 0x0d04 /* 32 bit Transmit MAC FIFO WR Pointer */
662#define TX_MFF_WSP 0x0d08 /* 32 bit Transmit MAC FIFO WR Shadow Ptr */
663#define TX_MFF_RP 0x0d0c /* 32 bit Transmit MAC FIFO RD Pointer */
664#define TX_MFF_PC 0x0d10 /* 32 bit Transmit MAC FIFO Packet Cnt */
665#define TX_MFF_LEV 0x0d14 /* 32 bit Transmit MAC FIFO Level */
666#define TX_MFF_CTRL1 0x0d18 /* 16 bit Transmit MAC FIFO Ctrl Reg 1 */
667#define TX_MFF_WAF 0x0d1a /* 8 bit Transmit MAC Wait after flush */
668 /* 0x0c1b: reserved */
669#define TX_MFF_CTRL2 0x0d1c /* 8 bit Transmit MAC FIFO Ctrl Reg 2 */
670#define TX_MFF_TST1 0x0d1d /* 8 bit Transmit MAC FIFO Test Reg 1 */
671#define TX_MFF_TST2 0x0d1e /* 8 bit Transmit MAC FIFO Test Reg 2 */
672 /* 0x0d1f: reserved */
673#define TX_LED_INI 0x0d20 /* 32 bit Transmit LED Cnt Init Value */
674#define TX_LED_VAL 0x0d24 /* 32 bit Transmit LED Cnt Current Val */
675#define TX_LED_CTRL 0x0d28 /* 8 bit Transmit LED Cnt Control Reg */
676#define TX_LED_TST 0x0d29 /* 8 bit Transmit LED Cnt Test Reg */
677 /* 0x0d2a - 0x0d3f: reserved */
678
679/* Transmit GMAC FIFO (YUKON only), use MR_ADDR() to access */
680#define TX_GMF_EA 0x0d40 /* 32 bit Tx GMAC FIFO End Address */
681#define TX_GMF_AE_THR 0x0d44 /* 32 bit Tx GMAC FIFO Almost Empty Thresh.*/
682#define TX_GMF_CTRL_T 0x0d48 /* 32 bit Tx GMAC FIFO Control/Test */
683 /* 0x0d4c - 0x0d5f: reserved */
684#define TX_GMF_WP 0x0d60 /* 32 bit Tx GMAC FIFO Write Pointer */
685#define TX_GMF_WSP 0x0d64 /* 32 bit Tx GMAC FIFO Write Shadow Ptr. */
686#define TX_GMF_WLEV 0x0d68 /* 32 bit Tx GMAC FIFO Write Level */
687 /* 0x0d6c - 0x0d6f: reserved */
688#define TX_GMF_RP 0x0d70 /* 32 bit Tx GMAC FIFO Read Pointer */
689#define TX_GMF_RSTP 0x0d74 /* 32 bit Tx GMAC FIFO Restart Pointer */
690#define TX_GMF_RLEV 0x0d78 /* 32 bit Tx GMAC FIFO Read Level */
691 /* 0x0d7c - 0x0d7f: reserved */
692
693/*
694 * Bank 27
695 */
696 /* 0x0d80 - 0x0dbf: MAC 2 */
697 /* 0x0daa - 0x0dff: reserved */
698
699/*
700 * Bank 28
701 */
702/* Descriptor Poll Timer Registers */
703#define B28_DPT_INI 0x0e00 /* 24 bit Descriptor Poll Timer Init Val */
704#define B28_DPT_VAL 0x0e04 /* 24 bit Descriptor Poll Timer Curr Val */
705#define B28_DPT_CTRL 0x0e08 /* 8 bit Descriptor Poll Timer Ctrl Reg */
706 /* 0x0e09: reserved */
707#define B28_DPT_TST 0x0e0a /* 8 bit Descriptor Poll Timer Test Reg */
708 /* 0x0e0b: reserved */
709
710/* Time Stamp Timer Registers (YUKON only) */
711 /* 0x0e10: reserved */
712#define GMAC_TI_ST_VAL 0x0e14 /* 32 bit Time Stamp Timer Curr Val */
713#define GMAC_TI_ST_CTRL 0x0e18 /* 8 bit Time Stamp Timer Ctrl Reg */
714 /* 0x0e19: reserved */
715#define GMAC_TI_ST_TST 0x0e1a /* 8 bit Time Stamp Timer Test Reg */
716 /* 0x0e1b - 0x0e7f: reserved */
717
718/*
719 * Bank 29
720 */
721 /* 0x0e80 - 0x0efc: reserved */
722
723/*
724 * Bank 30
725 */
726/* GMAC and GPHY Control Registers (YUKON only) */
727#define GMAC_CTRL 0x0f00 /* 32 bit GMAC Control Reg */
728#define GPHY_CTRL 0x0f04 /* 32 bit GPHY Control Reg */
729#define GMAC_IRQ_SRC 0x0f08 /* 8 bit GMAC Interrupt Source Reg */
730 /* 0x0f09 - 0x0f0b: reserved */
731#define GMAC_IRQ_MSK 0x0f0c /* 8 bit GMAC Interrupt Mask Reg */
732 /* 0x0f0d - 0x0f0f: reserved */
733#define GMAC_LINK_CTRL 0x0f10 /* 16 bit Link Control Reg */
734 /* 0x0f14 - 0x0f1f: reserved */
735
736/* Wake-up Frame Pattern Match Control Registers (YUKON only) */
737
738#define WOL_REG_OFFS 0x20 /* HW-Bug: Address is + 0x20 against spec. */
739
740#define WOL_CTRL_STAT 0x0f20 /* 16 bit WOL Control/Status Reg */
741#define WOL_MATCH_CTL 0x0f22 /* 8 bit WOL Match Control Reg */
742#define WOL_MATCH_RES 0x0f23 /* 8 bit WOL Match Result Reg */
743#define WOL_MAC_ADDR_LO 0x0f24 /* 32 bit WOL MAC Address Low */
744#define WOL_MAC_ADDR_HI 0x0f28 /* 16 bit WOL MAC Address High */
745#define WOL_PATT_RPTR 0x0f2c /* 8 bit WOL Pattern Read Ptr */
746
747/* use this macro to access above registers */
748#define WOL_REG(Reg) ((Reg) + (pAC->GIni.GIWolOffs))
749
750
751/* WOL Pattern Length Registers (YUKON only) */
752
753#define WOL_PATT_LEN_LO 0x0f30 /* 32 bit WOL Pattern Length 3..0 */
754#define WOL_PATT_LEN_HI 0x0f34 /* 24 bit WOL Pattern Length 6..4 */
755
756/* WOL Pattern Counter Registers (YUKON only) */
757
758#define WOL_PATT_CNT_0 0x0f38 /* 32 bit WOL Pattern Counter 3..0 */
759#define WOL_PATT_CNT_4 0x0f3c /* 24 bit WOL Pattern Counter 6..4 */
760 /* 0x0f40 - 0x0f7f: reserved */
761
762/*
763 * Bank 31
764 */
765/* 0x0f80 - 0x0fff: reserved */
766
767/*
768 * Bank 32 - 33
769 */
770#define WOL_PATT_RAM_1 0x1000 /* WOL Pattern RAM Link 1 */
771
772/*
773 * Bank 0x22 - 0x3f
774 */
775/* 0x1100 - 0x1fff: reserved */
776
777/*
778 * Bank 0x40 - 0x4f
779 */
780#define BASE_XMAC_1 0x2000 /* XMAC 1 registers */
781
782/*
783 * Bank 0x50 - 0x5f
784 */
785
786#define BASE_GMAC_1 0x2800 /* GMAC 1 registers */
787
788/*
789 * Bank 0x60 - 0x6f
790 */
791#define BASE_XMAC_2 0x3000 /* XMAC 2 registers */
792
793/*
794 * Bank 0x70 - 0x7f
795 */
796#define BASE_GMAC_2 0x3800 /* GMAC 2 registers */
797
798/*
799 * Control Register Bit Definitions:
800 */
801/* B0_RAP 8 bit Register Address Port */
802 /* Bit 7: reserved */
803#define RAP_RAP 0x3f /* Bit 6..0: 0 = block 0,..,6f = block 6f */
804
805/* B0_CTST 16 bit Control/Status register */
806 /* Bit 15..14: reserved */
807#define CS_CLK_RUN_HOT BIT_13S /* CLK_RUN hot m. (YUKON-Lite only) */
808#define CS_CLK_RUN_RST BIT_12S /* CLK_RUN reset (YUKON-Lite only) */
809#define CS_CLK_RUN_ENA BIT_11S /* CLK_RUN enable (YUKON-Lite only) */
810#define CS_VAUX_AVAIL BIT_10S /* VAUX available (YUKON only) */
811#define CS_BUS_CLOCK BIT_9S /* Bus Clock 0/1 = 33/66 MHz */
812#define CS_BUS_SLOT_SZ BIT_8S /* Slot Size 0/1 = 32/64 bit slot */
813#define CS_ST_SW_IRQ BIT_7S /* Set IRQ SW Request */
814#define CS_CL_SW_IRQ BIT_6S /* Clear IRQ SW Request */
815#define CS_STOP_DONE BIT_5S /* Stop Master is finished */
816#define CS_STOP_MAST BIT_4S /* Command Bit to stop the master */
817#define CS_MRST_CLR BIT_3S /* Clear Master reset */
818#define CS_MRST_SET BIT_2S /* Set Master reset */
819#define CS_RST_CLR BIT_1S /* Clear Software reset */
820#define CS_RST_SET BIT_0S /* Set Software reset */
821
822/* B0_LED 8 Bit LED register */
823 /* Bit 7.. 2: reserved */
824#define LED_STAT_ON BIT_1S /* Status LED on */
825#define LED_STAT_OFF BIT_0S /* Status LED off */
826
827/* B0_POWER_CTRL 8 Bit Power Control reg (YUKON only) */
828#define PC_VAUX_ENA BIT_7 /* Switch VAUX Enable */
829#define PC_VAUX_DIS BIT_6 /* Switch VAUX Disable */
830#define PC_VCC_ENA BIT_5 /* Switch VCC Enable */
831#define PC_VCC_DIS BIT_4 /* Switch VCC Disable */
832#define PC_VAUX_ON BIT_3 /* Switch VAUX On */
833#define PC_VAUX_OFF BIT_2 /* Switch VAUX Off */
834#define PC_VCC_ON BIT_1 /* Switch VCC On */
835#define PC_VCC_OFF BIT_0 /* Switch VCC Off */
836
837/* B0_ISRC 32 bit Interrupt Source Register */
838/* B0_IMSK 32 bit Interrupt Mask Register */
839/* B0_SP_ISRC 32 bit Special Interrupt Source Reg */
840/* B2_IRQM_MSK 32 bit IRQ Moderation Mask */
841#define IS_ALL_MSK 0xbfffffffUL /* All Interrupt bits */
842#define IS_HW_ERR BIT_31 /* Interrupt HW Error */
843 /* Bit 30: reserved */
844#define IS_PA_TO_RX1 BIT_29 /* Packet Arb Timeout Rx1 */
845#define IS_PA_TO_RX2 BIT_28 /* Packet Arb Timeout Rx2 */
846#define IS_PA_TO_TX1 BIT_27 /* Packet Arb Timeout Tx1 */
847#define IS_PA_TO_TX2 BIT_26 /* Packet Arb Timeout Tx2 */
848#define IS_I2C_READY BIT_25 /* IRQ on end of I2C Tx */
849#define IS_IRQ_SW BIT_24 /* SW forced IRQ */
850#define IS_EXT_REG BIT_23 /* IRQ from LM80 or PHY (GENESIS only) */
851 /* IRQ from PHY (YUKON only) */
852#define IS_TIMINT BIT_22 /* IRQ from Timer */
853#define IS_MAC1 BIT_21 /* IRQ from MAC 1 */
854#define IS_LNK_SYNC_M1 BIT_20 /* Link Sync Cnt wrap MAC 1 */
855#define IS_MAC2 BIT_19 /* IRQ from MAC 2 */
856#define IS_LNK_SYNC_M2 BIT_18 /* Link Sync Cnt wrap MAC 2 */
857/* Receive Queue 1 */
858#define IS_R1_B BIT_17 /* Q_R1 End of Buffer */
859#define IS_R1_F BIT_16 /* Q_R1 End of Frame */
860#define IS_R1_C BIT_15 /* Q_R1 Encoding Error */
861/* Receive Queue 2 */
862#define IS_R2_B BIT_14 /* Q_R2 End of Buffer */
863#define IS_R2_F BIT_13 /* Q_R2 End of Frame */
864#define IS_R2_C BIT_12 /* Q_R2 Encoding Error */
865/* Synchronous Transmit Queue 1 */
866#define IS_XS1_B BIT_11 /* Q_XS1 End of Buffer */
867#define IS_XS1_F BIT_10 /* Q_XS1 End of Frame */
868#define IS_XS1_C BIT_9 /* Q_XS1 Encoding Error */
869/* Asynchronous Transmit Queue 1 */
870#define IS_XA1_B BIT_8 /* Q_XA1 End of Buffer */
871#define IS_XA1_F BIT_7 /* Q_XA1 End of Frame */
872#define IS_XA1_C BIT_6 /* Q_XA1 Encoding Error */
873/* Synchronous Transmit Queue 2 */
874#define IS_XS2_B BIT_5 /* Q_XS2 End of Buffer */
875#define IS_XS2_F BIT_4 /* Q_XS2 End of Frame */
876#define IS_XS2_C BIT_3 /* Q_XS2 Encoding Error */
877/* Asynchronous Transmit Queue 2 */
878#define IS_XA2_B BIT_2 /* Q_XA2 End of Buffer */
879#define IS_XA2_F BIT_1 /* Q_XA2 End of Frame */
880#define IS_XA2_C BIT_0 /* Q_XA2 Encoding Error */
881
882
883/* B0_HWE_ISRC 32 bit HW Error Interrupt Src Reg */
884/* B0_HWE_IMSK 32 bit HW Error Interrupt Mask Reg */
885/* B2_IRQM_HWE_MSK 32 bit IRQ Moderation HW Error Mask */
886#define IS_ERR_MSK 0x00000fffL /* All Error bits */
887 /* Bit 31..14: reserved */
888#define IS_IRQ_TIST_OV BIT_13 /* Time Stamp Timer Overflow (YUKON only) */
889#define IS_IRQ_SENSOR BIT_12 /* IRQ from Sensor (YUKON only) */
890#define IS_IRQ_MST_ERR BIT_11 /* IRQ master error detected */
891#define IS_IRQ_STAT BIT_10 /* IRQ status exception */
892#define IS_NO_STAT_M1 BIT_9 /* No Rx Status from MAC 1 */
893#define IS_NO_STAT_M2 BIT_8 /* No Rx Status from MAC 2 */
894#define IS_NO_TIST_M1 BIT_7 /* No Time Stamp from MAC 1 */
895#define IS_NO_TIST_M2 BIT_6 /* No Time Stamp from MAC 2 */
896#define IS_RAM_RD_PAR BIT_5 /* RAM Read Parity Error */
897#define IS_RAM_WR_PAR BIT_4 /* RAM Write Parity Error */
898#define IS_M1_PAR_ERR BIT_3 /* MAC 1 Parity Error */
899#define IS_M2_PAR_ERR BIT_2 /* MAC 2 Parity Error */
900#define IS_R1_PAR_ERR BIT_1 /* Queue R1 Parity Error */
901#define IS_R2_PAR_ERR BIT_0 /* Queue R2 Parity Error */
902
903/* B2_CONN_TYP 8 bit Connector type */
904/* B2_PMD_TYP 8 bit PMD type */
905/* Values of connector and PMD type comply to SysKonnect internal std */
906
907/* B2_MAC_CFG 8 bit MAC Configuration / Chip Revision */
908#define CFG_CHIP_R_MSK (0xf<<4) /* Bit 7.. 4: Chip Revision */
909 /* Bit 3.. 2: reserved */
910#define CFG_DIS_M2_CLK BIT_1S /* Disable Clock for 2nd MAC */
911#define CFG_SNG_MAC BIT_0S /* MAC Config: 0=2 MACs / 1=1 MAC*/
912
913/* B2_CHIP_ID 8 bit Chip Identification Number */
914#define CHIP_ID_GENESIS 0x0a /* Chip ID for GENESIS */
915#define CHIP_ID_YUKON 0xb0 /* Chip ID for YUKON */
916#define CHIP_ID_YUKON_LITE 0xb1 /* Chip ID for YUKON-Lite (Rev. A1-A3) */
917#define CHIP_ID_YUKON_LP 0xb2 /* Chip ID for YUKON-LP */
918
919#define CHIP_REV_YU_LITE_A1 3 /* Chip Rev. for YUKON-Lite A1,A2 */
920#define CHIP_REV_YU_LITE_A3 7 /* Chip Rev. for YUKON-Lite A3 */
921
922/* B2_FAR 32 bit Flash-Prom Addr Reg/Cnt */
923#define FAR_ADDR 0x1ffffL /* Bit 16.. 0: FPROM Address mask */
924
925/* B2_LD_CTRL 8 bit EPROM loader control register */
926/* Bits are currently reserved */
927
928/* B2_LD_TEST 8 bit EPROM loader test register */
929 /* Bit 7.. 4: reserved */
930#define LD_T_ON BIT_3S /* Loader Test mode on */
931#define LD_T_OFF BIT_2S /* Loader Test mode off */
932#define LD_T_STEP BIT_1S /* Decrement FPROM addr. Counter */
933#define LD_START BIT_0S /* Start loading FPROM */
934
935/*
936 * Timer Section
937 */
938/* B2_TI_CTRL 8 bit Timer control */
939/* B2_IRQM_CTRL 8 bit IRQ Moderation Timer Control */
940 /* Bit 7.. 3: reserved */
941#define TIM_START BIT_2S /* Start Timer */
942#define TIM_STOP BIT_1S /* Stop Timer */
943#define TIM_CLR_IRQ BIT_0S /* Clear Timer IRQ (!IRQM) */
944
945/* B2_TI_TEST 8 Bit Timer Test */
946/* B2_IRQM_TEST 8 bit IRQ Moderation Timer Test */
947/* B28_DPT_TST 8 bit Descriptor Poll Timer Test Reg */
948 /* Bit 7.. 3: reserved */
949#define TIM_T_ON BIT_2S /* Test mode on */
950#define TIM_T_OFF BIT_1S /* Test mode off */
951#define TIM_T_STEP BIT_0S /* Test step */
952
953/* B28_DPT_INI 32 bit Descriptor Poll Timer Init Val */
954/* B28_DPT_VAL 32 bit Descriptor Poll Timer Curr Val */
955 /* Bit 31..24: reserved */
956#define DPT_MSK 0x00ffffffL /* Bit 23.. 0: Desc Poll Timer Bits */
957
958/* B28_DPT_CTRL 8 bit Descriptor Poll Timer Ctrl Reg */
959 /* Bit 7.. 2: reserved */
960#define DPT_START BIT_1S /* Start Descriptor Poll Timer */
961#define DPT_STOP BIT_0S /* Stop Descriptor Poll Timer */
962
963/* B2_E_3 8 bit lower 4 bits used for HW self test result */
964#define B2_E3_RES_MASK 0x0f
965
966/* B2_TST_CTRL1 8 bit Test Control Register 1 */
967#define TST_FRC_DPERR_MR BIT_7S /* force DATAPERR on MST RD */
968#define TST_FRC_DPERR_MW BIT_6S /* force DATAPERR on MST WR */
969#define TST_FRC_DPERR_TR BIT_5S /* force DATAPERR on TRG RD */
970#define TST_FRC_DPERR_TW BIT_4S /* force DATAPERR on TRG WR */
971#define TST_FRC_APERR_M BIT_3S /* force ADDRPERR on MST */
972#define TST_FRC_APERR_T BIT_2S /* force ADDRPERR on TRG */
973#define TST_CFG_WRITE_ON BIT_1S /* Enable Config Reg WR */
974#define TST_CFG_WRITE_OFF BIT_0S /* Disable Config Reg WR */
975
976/* B2_TST_CTRL2 8 bit Test Control Register 2 */
977 /* Bit 7.. 4: reserved */
978 /* force the following error on the next master read/write */
979#define TST_FRC_DPERR_MR64 BIT_3S /* DataPERR RD 64 */
980#define TST_FRC_DPERR_MW64 BIT_2S /* DataPERR WR 64 */
981#define TST_FRC_APERR_1M64 BIT_1S /* AddrPERR on 1. phase */
982#define TST_FRC_APERR_2M64 BIT_0S /* AddrPERR on 2. phase */
983
984/* B2_GP_IO 32 bit General Purpose I/O Register */
985 /* Bit 31..26: reserved */
986#define GP_DIR_9 BIT_25 /* IO_9 direct, 0=In/1=Out */
987#define GP_DIR_8 BIT_24 /* IO_8 direct, 0=In/1=Out */
988#define GP_DIR_7 BIT_23 /* IO_7 direct, 0=In/1=Out */
989#define GP_DIR_6 BIT_22 /* IO_6 direct, 0=In/1=Out */
990#define GP_DIR_5 BIT_21 /* IO_5 direct, 0=In/1=Out */
991#define GP_DIR_4 BIT_20 /* IO_4 direct, 0=In/1=Out */
992#define GP_DIR_3 BIT_19 /* IO_3 direct, 0=In/1=Out */
993#define GP_DIR_2 BIT_18 /* IO_2 direct, 0=In/1=Out */
994#define GP_DIR_1 BIT_17 /* IO_1 direct, 0=In/1=Out */
995#define GP_DIR_0 BIT_16 /* IO_0 direct, 0=In/1=Out */
996 /* Bit 15..10: reserved */
997#define GP_IO_9 BIT_9 /* IO_9 pin */
998#define GP_IO_8 BIT_8 /* IO_8 pin */
999#define GP_IO_7 BIT_7 /* IO_7 pin */
1000#define GP_IO_6 BIT_6 /* IO_6 pin */
1001#define GP_IO_5 BIT_5 /* IO_5 pin */
1002#define GP_IO_4 BIT_4 /* IO_4 pin */
1003#define GP_IO_3 BIT_3 /* IO_3 pin */
1004#define GP_IO_2 BIT_2 /* IO_2 pin */
1005#define GP_IO_1 BIT_1 /* IO_1 pin */
1006#define GP_IO_0 BIT_0 /* IO_0 pin */
1007
1008/* B2_I2C_CTRL 32 bit I2C HW Control Register */
1009#define I2C_FLAG BIT_31 /* Start read/write if WR */
1010#define I2C_ADDR (0x7fffL<<16) /* Bit 30..16: Addr to be RD/WR */
1011#define I2C_DEV_SEL (0x7fL<<9) /* Bit 15.. 9: I2C Device Select */
1012 /* Bit 8.. 5: reserved */
1013#define I2C_BURST_LEN BIT_4 /* Burst Len, 1/4 bytes */
1014#define I2C_DEV_SIZE (7<<1) /* Bit 3.. 1: I2C Device Size */
1015#define I2C_025K_DEV (0<<1) /* 0: 256 Bytes or smal. */
1016#define I2C_05K_DEV (1<<1) /* 1: 512 Bytes */
1017#define I2C_1K_DEV (2<<1) /* 2: 1024 Bytes */
1018#define I2C_2K_DEV (3<<1) /* 3: 2048 Bytes */
1019#define I2C_4K_DEV (4<<1) /* 4: 4096 Bytes */
1020#define I2C_8K_DEV (5<<1) /* 5: 8192 Bytes */
1021#define I2C_16K_DEV (6<<1) /* 6: 16384 Bytes */
1022#define I2C_32K_DEV (7<<1) /* 7: 32768 Bytes */
1023#define I2C_STOP BIT_0 /* Interrupt I2C transfer */
1024
1025/* B2_I2C_IRQ 32 bit I2C HW IRQ Register */
1026 /* Bit 31.. 1 reserved */
1027#define I2C_CLR_IRQ BIT_0 /* Clear I2C IRQ */
1028
1029/* B2_I2C_SW 32 bit (8 bit access) I2C HW SW Port Register */
1030 /* Bit 7.. 3: reserved */
1031#define I2C_DATA_DIR BIT_2S /* direction of I2C_DATA */
1032#define I2C_DATA BIT_1S /* I2C Data Port */
1033#define I2C_CLK BIT_0S /* I2C Clock Port */
1034
1035/*
1036 * I2C Address
1037 */
1038#define I2C_SENS_ADDR LM80_ADDR /* I2C Sensor Address, (Volt and Temp)*/
1039
1040
1041/* B2_BSC_CTRL 8 bit Blink Source Counter Control */
1042 /* Bit 7.. 2: reserved */
1043#define BSC_START BIT_1S /* Start Blink Source Counter */
1044#define BSC_STOP BIT_0S /* Stop Blink Source Counter */
1045
1046/* B2_BSC_STAT 8 bit Blink Source Counter Status */
1047 /* Bit 7.. 1: reserved */
1048#define BSC_SRC BIT_0S /* Blink Source, 0=Off / 1=On */
1049
1050/* B2_BSC_TST 16 bit Blink Source Counter Test Reg */
1051#define BSC_T_ON BIT_2S /* Test mode on */
1052#define BSC_T_OFF BIT_1S /* Test mode off */
1053#define BSC_T_STEP BIT_0S /* Test step */
1054
1055
1056/* B3_RAM_ADDR 32 bit RAM Address, to read or write */
1057 /* Bit 31..19: reserved */
1058#define RAM_ADR_RAN 0x0007ffffL /* Bit 18.. 0: RAM Address Range */
1059
1060/* RAM Interface Registers */
1061/* B3_RI_CTRL 16 bit RAM Iface Control Register */
1062 /* Bit 15..10: reserved */
1063#define RI_CLR_RD_PERR BIT_9S /* Clear IRQ RAM Read Parity Err */
1064#define RI_CLR_WR_PERR BIT_8S /* Clear IRQ RAM Write Parity Err*/
1065 /* Bit 7.. 2: reserved */
1066#define RI_RST_CLR BIT_1S /* Clear RAM Interface Reset */
1067#define RI_RST_SET BIT_0S /* Set RAM Interface Reset */
1068
1069/* B3_RI_TEST 8 bit RAM Iface Test Register */
1070 /* Bit 15.. 4: reserved */
1071#define RI_T_EV BIT_3S /* Timeout Event occured */
1072#define RI_T_ON BIT_2S /* Timeout Timer Test On */
1073#define RI_T_OFF BIT_1S /* Timeout Timer Test Off */
1074#define RI_T_STEP BIT_0S /* Timeout Timer Step */
1075
1076/* MAC Arbiter Registers */
1077/* B3_MA_TO_CTRL 16 bit MAC Arbiter Timeout Ctrl Reg */
1078 /* Bit 15.. 4: reserved */
1079#define MA_FOE_ON BIT_3S /* XMAC Fast Output Enable ON */
1080#define MA_FOE_OFF BIT_2S /* XMAC Fast Output Enable OFF */
1081#define MA_RST_CLR BIT_1S /* Clear MAC Arbiter Reset */
1082#define MA_RST_SET BIT_0S /* Set MAC Arbiter Reset */
1083
1084/* B3_MA_RC_CTRL 16 bit MAC Arbiter Recovery Ctrl Reg */
1085 /* Bit 15.. 8: reserved */
1086#define MA_ENA_REC_TX2 BIT_7S /* Enable Recovery Timer TX2 */
1087#define MA_DIS_REC_TX2 BIT_6S /* Disable Recovery Timer TX2 */
1088#define MA_ENA_REC_TX1 BIT_5S /* Enable Recovery Timer TX1 */
1089#define MA_DIS_REC_TX1 BIT_4S /* Disable Recovery Timer TX1 */
1090#define MA_ENA_REC_RX2 BIT_3S /* Enable Recovery Timer RX2 */
1091#define MA_DIS_REC_RX2 BIT_2S /* Disable Recovery Timer RX2 */
1092#define MA_ENA_REC_RX1 BIT_1S /* Enable Recovery Timer RX1 */
1093#define MA_DIS_REC_RX1 BIT_0S /* Disable Recovery Timer RX1 */
1094
1095/* Packet Arbiter Registers */
1096/* B3_PA_CTRL 16 bit Packet Arbiter Ctrl Register */
1097 /* Bit 15..14: reserved */
1098#define PA_CLR_TO_TX2 BIT_13S /* Clear IRQ Packet Timeout TX2 */
1099#define PA_CLR_TO_TX1 BIT_12S /* Clear IRQ Packet Timeout TX1 */
1100#define PA_CLR_TO_RX2 BIT_11S /* Clear IRQ Packet Timeout RX2 */
1101#define PA_CLR_TO_RX1 BIT_10S /* Clear IRQ Packet Timeout RX1 */
1102#define PA_ENA_TO_TX2 BIT_9S /* Enable Timeout Timer TX2 */
1103#define PA_DIS_TO_TX2 BIT_8S /* Disable Timeout Timer TX2 */
1104#define PA_ENA_TO_TX1 BIT_7S /* Enable Timeout Timer TX1 */
1105#define PA_DIS_TO_TX1 BIT_6S /* Disable Timeout Timer TX1 */
1106#define PA_ENA_TO_RX2 BIT_5S /* Enable Timeout Timer RX2 */
1107#define PA_DIS_TO_RX2 BIT_4S /* Disable Timeout Timer RX2 */
1108#define PA_ENA_TO_RX1 BIT_3S /* Enable Timeout Timer RX1 */
1109#define PA_DIS_TO_RX1 BIT_2S /* Disable Timeout Timer RX1 */
1110#define PA_RST_CLR BIT_1S /* Clear MAC Arbiter Reset */
1111#define PA_RST_SET BIT_0S /* Set MAC Arbiter Reset */
1112
1113#define PA_ENA_TO_ALL (PA_ENA_TO_RX1 | PA_ENA_TO_RX2 |\
1114 PA_ENA_TO_TX1 | PA_ENA_TO_TX2)
1115
1116/* Rx/Tx Path related Arbiter Test Registers */
1117/* B3_MA_TO_TEST 16 bit MAC Arbiter Timeout Test Reg */
1118/* B3_MA_RC_TEST 16 bit MAC Arbiter Recovery Test Reg */
1119/* B3_PA_TEST 16 bit Packet Arbiter Test Register */
1120/* Bit 15, 11, 7, and 3 are reserved in B3_PA_TEST */
1121#define TX2_T_EV BIT_15S /* TX2 Timeout/Recv Event occured */
1122#define TX2_T_ON BIT_14S /* TX2 Timeout/Recv Timer Test On */
1123#define TX2_T_OFF BIT_13S /* TX2 Timeout/Recv Timer Tst Off */
1124#define TX2_T_STEP BIT_12S /* TX2 Timeout/Recv Timer Step */
1125#define TX1_T_EV BIT_11S /* TX1 Timeout/Recv Event occured */
1126#define TX1_T_ON BIT_10S /* TX1 Timeout/Recv Timer Test On */
1127#define TX1_T_OFF BIT_9S /* TX1 Timeout/Recv Timer Tst Off */
1128#define TX1_T_STEP BIT_8S /* TX1 Timeout/Recv Timer Step */
1129#define RX2_T_EV BIT_7S /* RX2 Timeout/Recv Event occured */
1130#define RX2_T_ON BIT_6S /* RX2 Timeout/Recv Timer Test On */
1131#define RX2_T_OFF BIT_5S /* RX2 Timeout/Recv Timer Tst Off */
1132#define RX2_T_STEP BIT_4S /* RX2 Timeout/Recv Timer Step */
1133#define RX1_T_EV BIT_3S /* RX1 Timeout/Recv Event occured */
1134#define RX1_T_ON BIT_2S /* RX1 Timeout/Recv Timer Test On */
1135#define RX1_T_OFF BIT_1S /* RX1 Timeout/Recv Timer Tst Off */
1136#define RX1_T_STEP BIT_0S /* RX1 Timeout/Recv Timer Step */
1137
1138
1139/* Transmit Arbiter Registers MAC 1 and 2, use MR_ADDR() to access */
1140/* TXA_ITI_INI 32 bit Tx Arb Interval Timer Init Val */
1141/* TXA_ITI_VAL 32 bit Tx Arb Interval Timer Value */
1142/* TXA_LIM_INI 32 bit Tx Arb Limit Counter Init Val */
1143/* TXA_LIM_VAL 32 bit Tx Arb Limit Counter Value */
1144 /* Bit 31..24: reserved */
1145#define TXA_MAX_VAL 0x00ffffffUL/* Bit 23.. 0: Max TXA Timer/Cnt Val */
1146
1147/* TXA_CTRL 8 bit Tx Arbiter Control Register */
1148#define TXA_ENA_FSYNC BIT_7S /* Enable force of sync Tx queue */
1149#define TXA_DIS_FSYNC BIT_6S /* Disable force of sync Tx queue */
1150#define TXA_ENA_ALLOC BIT_5S /* Enable alloc of free bandwidth */
1151#define TXA_DIS_ALLOC BIT_4S /* Disable alloc of free bandwidth */
1152#define TXA_START_RC BIT_3S /* Start sync Rate Control */
1153#define TXA_STOP_RC BIT_2S /* Stop sync Rate Control */
1154#define TXA_ENA_ARB BIT_1S /* Enable Tx Arbiter */
1155#define TXA_DIS_ARB BIT_0S /* Disable Tx Arbiter */
1156
1157/* TXA_TEST 8 bit Tx Arbiter Test Register */
1158 /* Bit 7.. 6: reserved */
1159#define TXA_INT_T_ON BIT_5S /* Tx Arb Interval Timer Test On */
1160#define TXA_INT_T_OFF BIT_4S /* Tx Arb Interval Timer Test Off */
1161#define TXA_INT_T_STEP BIT_3S /* Tx Arb Interval Timer Step */
1162#define TXA_LIM_T_ON BIT_2S /* Tx Arb Limit Timer Test On */
1163#define TXA_LIM_T_OFF BIT_1S /* Tx Arb Limit Timer Test Off */
1164#define TXA_LIM_T_STEP BIT_0S /* Tx Arb Limit Timer Step */
1165
1166/* TXA_STAT 8 bit Tx Arbiter Status Register */
1167 /* Bit 7.. 1: reserved */
1168#define TXA_PRIO_XS BIT_0S /* sync queue has prio to send */
1169
1170/* Q_BC 32 bit Current Byte Counter */
1171 /* Bit 31..16: reserved */
1172#define BC_MAX 0xffff /* Bit 15.. 0: Byte counter */
1173
1174/* BMU Control Status Registers */
1175/* B0_R1_CSR 32 bit BMU Ctrl/Stat Rx Queue 1 */
1176/* B0_R2_CSR 32 bit BMU Ctrl/Stat Rx Queue 2 */
1177/* B0_XA1_CSR 32 bit BMU Ctrl/Stat Sync Tx Queue 1 */
1178/* B0_XS1_CSR 32 bit BMU Ctrl/Stat Async Tx Queue 1 */
1179/* B0_XA2_CSR 32 bit BMU Ctrl/Stat Sync Tx Queue 2 */
1180/* B0_XS2_CSR 32 bit BMU Ctrl/Stat Async Tx Queue 2 */
1181/* Q_CSR 32 bit BMU Control/Status Register */
1182 /* Bit 31..25: reserved */
1183#define CSR_SV_IDLE BIT_24 /* BMU SM Idle */
1184 /* Bit 23..22: reserved */
1185#define CSR_DESC_CLR BIT_21 /* Clear Reset for Descr */
1186#define CSR_DESC_SET BIT_20 /* Set Reset for Descr */
1187#define CSR_FIFO_CLR BIT_19 /* Clear Reset for FIFO */
1188#define CSR_FIFO_SET BIT_18 /* Set Reset for FIFO */
1189#define CSR_HPI_RUN BIT_17 /* Release HPI SM */
1190#define CSR_HPI_RST BIT_16 /* Reset HPI SM to Idle */
1191#define CSR_SV_RUN BIT_15 /* Release Supervisor SM */
1192#define CSR_SV_RST BIT_14 /* Reset Supervisor SM */
1193#define CSR_DREAD_RUN BIT_13 /* Release Descr Read SM */
1194#define CSR_DREAD_RST BIT_12 /* Reset Descr Read SM */
1195#define CSR_DWRITE_RUN BIT_11 /* Release Descr Write SM */
1196#define CSR_DWRITE_RST BIT_10 /* Reset Descr Write SM */
1197#define CSR_TRANS_RUN BIT_9 /* Release Transfer SM */
1198#define CSR_TRANS_RST BIT_8 /* Reset Transfer SM */
1199#define CSR_ENA_POL BIT_7 /* Enable Descr Polling */
1200#define CSR_DIS_POL BIT_6 /* Disable Descr Polling */
1201#define CSR_STOP BIT_5 /* Stop Rx/Tx Queue */
1202#define CSR_START BIT_4 /* Start Rx/Tx Queue */
1203#define CSR_IRQ_CL_P BIT_3 /* (Rx) Clear Parity IRQ */
1204#define CSR_IRQ_CL_B BIT_2 /* Clear EOB IRQ */
1205#define CSR_IRQ_CL_F BIT_1 /* Clear EOF IRQ */
1206#define CSR_IRQ_CL_C BIT_0 /* Clear ERR IRQ */
1207
1208#define CSR_SET_RESET (CSR_DESC_SET | CSR_FIFO_SET | CSR_HPI_RST |\
1209 CSR_SV_RST | CSR_DREAD_RST | CSR_DWRITE_RST |\
1210 CSR_TRANS_RST)
1211#define CSR_CLR_RESET (CSR_DESC_CLR | CSR_FIFO_CLR | CSR_HPI_RUN |\
1212 CSR_SV_RUN | CSR_DREAD_RUN | CSR_DWRITE_RUN |\
1213 CSR_TRANS_RUN)
1214
1215/* Q_F 32 bit Flag Register */
1216 /* Bit 31..28: reserved */
1217#define F_ALM_FULL BIT_27 /* Rx FIFO: almost full */
1218#define F_EMPTY BIT_27 /* Tx FIFO: empty flag */
1219#define F_FIFO_EOF BIT_26 /* Tag (EOF Flag) bit in FIFO */
1220#define F_WM_REACHED BIT_25 /* Watermark reached */
1221 /* reserved */
1222#define F_FIFO_LEVEL (0x1fL<<16) /* Bit 23..16: # of Qwords in FIFO */
1223 /* Bit 15..11: reserved */
1224#define F_WATER_MARK 0x0007ffL /* Bit 10.. 0: Watermark */
1225
1226/* Q_T1 32 bit Test Register 1 */
1227/* Holds four State Machine control Bytes */
1228#define SM_CTRL_SV_MSK (0xffL<<24) /* Bit 31..24: Control Supervisor SM */
1229#define SM_CTRL_RD_MSK (0xffL<<16) /* Bit 23..16: Control Read Desc SM */
1230#define SM_CTRL_WR_MSK (0xffL<<8) /* Bit 15.. 8: Control Write Desc SM */
1231#define SM_CTRL_TR_MSK 0xffL /* Bit 7.. 0: Control Transfer SM */
1232
1233/* Q_T1_TR 8 bit Test Register 1 Transfer SM */
1234/* Q_T1_WR 8 bit Test Register 1 Write Descriptor SM */
1235/* Q_T1_RD 8 bit Test Register 1 Read Descriptor SM */
1236/* Q_T1_SV 8 bit Test Register 1 Supervisor SM */
1237
1238/* The control status byte of each machine looks like ... */
1239#define SM_STATE 0xf0 /* Bit 7.. 4: State which shall be loaded */
1240#define SM_LOAD BIT_3S /* Load the SM with SM_STATE */
1241#define SM_TEST_ON BIT_2S /* Switch on SM Test Mode */
1242#define SM_TEST_OFF BIT_1S /* Go off the Test Mode */
1243#define SM_STEP BIT_0S /* Step the State Machine */
1244/* The encoding of the states is not supported by the Diagnostics Tool */
1245
1246/* Q_T2 32 bit Test Register 2 */
1247 /* Bit 31.. 8: reserved */
1248#define T2_AC_T_ON BIT_7 /* Address Counter Test Mode on */
1249#define T2_AC_T_OFF BIT_6 /* Address Counter Test Mode off */
1250#define T2_BC_T_ON BIT_5 /* Byte Counter Test Mode on */
1251#define T2_BC_T_OFF BIT_4 /* Byte Counter Test Mode off */
1252#define T2_STEP04 BIT_3 /* Inc AC/Dec BC by 4 */
1253#define T2_STEP03 BIT_2 /* Inc AC/Dec BC by 3 */
1254#define T2_STEP02 BIT_1 /* Inc AC/Dec BC by 2 */
1255#define T2_STEP01 BIT_0 /* Inc AC/Dec BC by 1 */
1256
1257/* Q_T3 32 bit Test Register 3 */
1258 /* Bit 31.. 7: reserved */
1259#define T3_MUX_MSK (7<<4) /* Bit 6.. 4: Mux Position */
1260 /* Bit 3: reserved */
1261#define T3_VRAM_MSK 7 /* Bit 2.. 0: Virtual RAM Buffer Address */
1262
1263/* RAM Buffer Register Offsets, use RB_ADDR(Queue, Offs) to access */
1264/* RB_START 32 bit RAM Buffer Start Address */
1265/* RB_END 32 bit RAM Buffer End Address */
1266/* RB_WP 32 bit RAM Buffer Write Pointer */
1267/* RB_RP 32 bit RAM Buffer Read Pointer */
1268/* RB_RX_UTPP 32 bit Rx Upper Threshold, Pause Pack */
1269/* RB_RX_LTPP 32 bit Rx Lower Threshold, Pause Pack */
1270/* RB_RX_UTHP 32 bit Rx Upper Threshold, High Prio */
1271/* RB_RX_LTHP 32 bit Rx Lower Threshold, High Prio */
1272/* RB_PC 32 bit RAM Buffer Packet Counter */
1273/* RB_LEV 32 bit RAM Buffer Level Register */
1274 /* Bit 31..19: reserved */
1275#define RB_MSK 0x0007ffff /* Bit 18.. 0: RAM Buffer Pointer Bits */
1276
1277/* RB_TST2 8 bit RAM Buffer Test Register 2 */
1278 /* Bit 7.. 4: reserved */
1279#define RB_PC_DEC BIT_3S /* Packet Counter Decrem */
1280#define RB_PC_T_ON BIT_2S /* Packet Counter Test On */
1281#define RB_PC_T_OFF BIT_1S /* Packet Counter Tst Off */
1282#define RB_PC_INC BIT_0S /* Packet Counter Increm */
1283
1284/* RB_TST1 8 bit RAM Buffer Test Register 1 */
1285 /* Bit 7: reserved */
1286#define RB_WP_T_ON BIT_6S /* Write Pointer Test On */
1287#define RB_WP_T_OFF BIT_5S /* Write Pointer Test Off */
1288#define RB_WP_INC BIT_4S /* Write Pointer Increm */
1289 /* Bit 3: reserved */
1290#define RB_RP_T_ON BIT_2S /* Read Pointer Test On */
1291#define RB_RP_T_OFF BIT_1S /* Read Pointer Test Off */
1292#define RB_RP_DEC BIT_0S /* Read Pointer Decrement */
1293
1294/* RB_CTRL 8 bit RAM Buffer Control Register */
1295 /* Bit 7.. 6: reserved */
1296#define RB_ENA_STFWD BIT_5S /* Enable Store & Forward */
1297#define RB_DIS_STFWD BIT_4S /* Disable Store & Forward */
1298#define RB_ENA_OP_MD BIT_3S /* Enable Operation Mode */
1299#define RB_DIS_OP_MD BIT_2S /* Disable Operation Mode */
1300#define RB_RST_CLR BIT_1S /* Clear RAM Buf STM Reset */
1301#define RB_RST_SET BIT_0S /* Set RAM Buf STM Reset */
1302
1303
1304/* Receive and Transmit MAC FIFO Registers (GENESIS only) */
1305
1306/* RX_MFF_EA 32 bit Receive MAC FIFO End Address */
1307/* RX_MFF_WP 32 bit Receive MAC FIFO Write Pointer */
1308/* RX_MFF_RP 32 bit Receive MAC FIFO Read Pointer */
1309/* RX_MFF_PC 32 bit Receive MAC FIFO Packet Counter */
1310/* RX_MFF_LEV 32 bit Receive MAC FIFO Level */
1311/* TX_MFF_EA 32 bit Transmit MAC FIFO End Address */
1312/* TX_MFF_WP 32 bit Transmit MAC FIFO Write Pointer */
1313/* TX_MFF_WSP 32 bit Transmit MAC FIFO WR Shadow Pointer */
1314/* TX_MFF_RP 32 bit Transmit MAC FIFO Read Pointer */
1315/* TX_MFF_PC 32 bit Transmit MAC FIFO Packet Cnt */
1316/* TX_MFF_LEV 32 bit Transmit MAC FIFO Level */
1317 /* Bit 31.. 6: reserved */
1318#define MFF_MSK 0x007fL /* Bit 5.. 0: MAC FIFO Address/Ptr Bits */
1319
1320/* RX_MFF_CTRL1 16 bit Receive MAC FIFO Control Reg 1 */
1321 /* Bit 15..14: reserved */
1322#define MFF_ENA_RDY_PAT BIT_13S /* Enable Ready Patch */
1323#define MFF_DIS_RDY_PAT BIT_12S /* Disable Ready Patch */
1324#define MFF_ENA_TIM_PAT BIT_11S /* Enable Timing Patch */
1325#define MFF_DIS_TIM_PAT BIT_10S /* Disable Timing Patch */
1326#define MFF_ENA_ALM_FUL BIT_9S /* Enable AlmostFull Sign */
1327#define MFF_DIS_ALM_FUL BIT_8S /* Disable AlmostFull Sign */
1328#define MFF_ENA_PAUSE BIT_7S /* Enable Pause Signaling */
1329#define MFF_DIS_PAUSE BIT_6S /* Disable Pause Signaling */
1330#define MFF_ENA_FLUSH BIT_5S /* Enable Frame Flushing */
1331#define MFF_DIS_FLUSH BIT_4S /* Disable Frame Flushing */
1332#define MFF_ENA_TIST BIT_3S /* Enable Time Stamp Gener */
1333#define MFF_DIS_TIST BIT_2S /* Disable Time Stamp Gener */
1334#define MFF_CLR_INTIST BIT_1S /* Clear IRQ No Time Stamp */
1335#define MFF_CLR_INSTAT BIT_0S /* Clear IRQ No Status */
1336
1337#define MFF_RX_CTRL_DEF MFF_ENA_TIM_PAT
1338
1339/* TX_MFF_CTRL1 16 bit Transmit MAC FIFO Control Reg 1 */
1340#define MFF_CLR_PERR BIT_15S /* Clear Parity Error IRQ */
1341 /* Bit 14: reserved */
1342#define MFF_ENA_PKT_REC BIT_13S /* Enable Packet Recovery */
1343#define MFF_DIS_PKT_REC BIT_12S /* Disable Packet Recovery */
1344/* MFF_ENA_TIM_PAT (see RX_MFF_CTRL1) Bit 11: Enable Timing Patch */
1345/* MFF_DIS_TIM_PAT (see RX_MFF_CTRL1) Bit 10: Disable Timing Patch */
1346/* MFF_ENA_ALM_FUL (see RX_MFF_CTRL1) Bit 9: Enable Almost Full Sign */
1347/* MFF_DIS_ALM_FUL (see RX_MFF_CTRL1) Bit 8: Disable Almost Full Sign */
1348#define MFF_ENA_W4E BIT_7S /* Enable Wait for Empty */
1349#define MFF_DIS_W4E BIT_6S /* Disable Wait for Empty */
1350/* MFF_ENA_FLUSH (see RX_MFF_CTRL1) Bit 5: Enable Frame Flushing */
1351/* MFF_DIS_FLUSH (see RX_MFF_CTRL1) Bit 4: Disable Frame Flushing */
1352#define MFF_ENA_LOOPB BIT_3S /* Enable Loopback */
1353#define MFF_DIS_LOOPB BIT_2S /* Disable Loopback */
1354#define MFF_CLR_MAC_RST BIT_1S /* Clear XMAC Reset */
1355#define MFF_SET_MAC_RST BIT_0S /* Set XMAC Reset */
1356
1357#define MFF_TX_CTRL_DEF (MFF_ENA_PKT_REC | MFF_ENA_TIM_PAT | MFF_ENA_FLUSH)
1358
1359/* RX_MFF_TST2 8 bit Receive MAC FIFO Test Register 2 */
1360/* TX_MFF_TST2 8 bit Transmit MAC FIFO Test Register 2 */
1361 /* Bit 7: reserved */
1362#define MFF_WSP_T_ON BIT_6S /* Tx: Write Shadow Ptr TestOn */
1363#define MFF_WSP_T_OFF BIT_5S /* Tx: Write Shadow Ptr TstOff */
1364#define MFF_WSP_INC BIT_4S /* Tx: Write Shadow Ptr Increment */
1365#define MFF_PC_DEC BIT_3S /* Packet Counter Decrement */
1366#define MFF_PC_T_ON BIT_2S /* Packet Counter Test On */
1367#define MFF_PC_T_OFF BIT_1S /* Packet Counter Test Off */
1368#define MFF_PC_INC BIT_0S /* Packet Counter Increment */
1369
1370/* RX_MFF_TST1 8 bit Receive MAC FIFO Test Register 1 */
1371/* TX_MFF_TST1 8 bit Transmit MAC FIFO Test Register 1 */
1372 /* Bit 7: reserved */
1373#define MFF_WP_T_ON BIT_6S /* Write Pointer Test On */
1374#define MFF_WP_T_OFF BIT_5S /* Write Pointer Test Off */
1375#define MFF_WP_INC BIT_4S /* Write Pointer Increm */
1376 /* Bit 3: reserved */
1377#define MFF_RP_T_ON BIT_2S /* Read Pointer Test On */
1378#define MFF_RP_T_OFF BIT_1S /* Read Pointer Test Off */
1379#define MFF_RP_DEC BIT_0S /* Read Pointer Decrement */
1380
1381/* RX_MFF_CTRL2 8 bit Receive MAC FIFO Control Reg 2 */
1382/* TX_MFF_CTRL2 8 bit Transmit MAC FIFO Control Reg 2 */
1383 /* Bit 7..4: reserved */
1384#define MFF_ENA_OP_MD BIT_3S /* Enable Operation Mode */
1385#define MFF_DIS_OP_MD BIT_2S /* Disable Operation Mode */
1386#define MFF_RST_CLR BIT_1S /* Clear MAC FIFO Reset */
1387#define MFF_RST_SET BIT_0S /* Set MAC FIFO Reset */
1388
1389
1390/* Link LED Counter Registers (GENESIS only) */
1391
1392/* RX_LED_CTRL 8 bit Receive LED Cnt Control Reg */
1393/* TX_LED_CTRL 8 bit Transmit LED Cnt Control Reg */
1394/* LNK_SYNC_CTRL 8 bit Link Sync Cnt Control Register */
1395 /* Bit 7.. 3: reserved */
1396#define LED_START BIT_2S /* Start Timer */
1397#define LED_STOP BIT_1S /* Stop Timer */
1398#define LED_STATE BIT_0S /* Rx/Tx: LED State, 1=LED on */
1399#define LED_CLR_IRQ BIT_0S /* Lnk: Clear Link IRQ */
1400
1401/* RX_LED_TST 8 bit Receive LED Cnt Test Register */
1402/* TX_LED_TST 8 bit Transmit LED Cnt Test Register */
1403/* LNK_SYNC_TST 8 bit Link Sync Cnt Test Register */
1404 /* Bit 7.. 3: reserved */
1405#define LED_T_ON BIT_2S /* LED Counter Test mode On */
1406#define LED_T_OFF BIT_1S /* LED Counter Test mode Off */
1407#define LED_T_STEP BIT_0S /* LED Counter Step */
1408
1409/* LNK_LED_REG 8 bit Link LED Register */
1410 /* Bit 7.. 6: reserved */
1411#define LED_BLK_ON BIT_5S /* Link LED Blinking On */
1412#define LED_BLK_OFF BIT_4S /* Link LED Blinking Off */
1413#define LED_SYNC_ON BIT_3S /* Use Sync Wire to switch LED */
1414#define LED_SYNC_OFF BIT_2S /* Disable Sync Wire Input */
1415#define LED_ON BIT_1S /* switch LED on */
1416#define LED_OFF BIT_0S /* switch LED off */
1417
1418/* Receive and Transmit GMAC FIFO Registers (YUKON only) */
1419
1420/* RX_GMF_EA 32 bit Rx GMAC FIFO End Address */
1421/* RX_GMF_AF_THR 32 bit Rx GMAC FIFO Almost Full Thresh. */
1422/* RX_GMF_WP 32 bit Rx GMAC FIFO Write Pointer */
1423/* RX_GMF_WLEV 32 bit Rx GMAC FIFO Write Level */
1424/* RX_GMF_RP 32 bit Rx GMAC FIFO Read Pointer */
1425/* RX_GMF_RLEV 32 bit Rx GMAC FIFO Read Level */
1426/* TX_GMF_EA 32 bit Tx GMAC FIFO End Address */
1427/* TX_GMF_AE_THR 32 bit Tx GMAC FIFO Almost Empty Thresh.*/
1428/* TX_GMF_WP 32 bit Tx GMAC FIFO Write Pointer */
1429/* TX_GMF_WSP 32 bit Tx GMAC FIFO Write Shadow Ptr. */
1430/* TX_GMF_WLEV 32 bit Tx GMAC FIFO Write Level */
1431/* TX_GMF_RP 32 bit Tx GMAC FIFO Read Pointer */
1432/* TX_GMF_RSTP 32 bit Tx GMAC FIFO Restart Pointer */
1433/* TX_GMF_RLEV 32 bit Tx GMAC FIFO Read Level */
1434
1435/* RX_GMF_CTRL_T 32 bit Rx GMAC FIFO Control/Test */
1436 /* Bits 31..15: reserved */
1437#define GMF_WP_TST_ON BIT_14 /* Write Pointer Test On */
1438#define GMF_WP_TST_OFF BIT_13 /* Write Pointer Test Off */
1439#define GMF_WP_STEP BIT_12 /* Write Pointer Step/Increment */
1440 /* Bit 11: reserved */
1441#define GMF_RP_TST_ON BIT_10 /* Read Pointer Test On */
1442#define GMF_RP_TST_OFF BIT_9 /* Read Pointer Test Off */
1443#define GMF_RP_STEP BIT_8 /* Read Pointer Step/Increment */
1444#define GMF_RX_F_FL_ON BIT_7 /* Rx FIFO Flush Mode On */
1445#define GMF_RX_F_FL_OFF BIT_6 /* Rx FIFO Flush Mode Off */
1446#define GMF_CLI_RX_FO BIT_5 /* Clear IRQ Rx FIFO Overrun */
1447#define GMF_CLI_RX_FC BIT_4 /* Clear IRQ Rx Frame Complete */
1448#define GMF_OPER_ON BIT_3 /* Operational Mode On */
1449#define GMF_OPER_OFF BIT_2 /* Operational Mode Off */
1450#define GMF_RST_CLR BIT_1 /* Clear GMAC FIFO Reset */
1451#define GMF_RST_SET BIT_0 /* Set GMAC FIFO Reset */
1452
1453/* TX_GMF_CTRL_T 32 bit Tx GMAC FIFO Control/Test */
1454 /* Bits 31..19: reserved */
1455#define GMF_WSP_TST_ON BIT_18 /* Write Shadow Pointer Test On */
1456#define GMF_WSP_TST_OFF BIT_17 /* Write Shadow Pointer Test Off */
1457#define GMF_WSP_STEP BIT_16 /* Write Shadow Pointer Step/Increment */
1458 /* Bits 15..7: same as for RX_GMF_CTRL_T */
1459#define GMF_CLI_TX_FU BIT_6 /* Clear IRQ Tx FIFO Underrun */
1460#define GMF_CLI_TX_FC BIT_5 /* Clear IRQ Tx Frame Complete */
1461#define GMF_CLI_TX_PE BIT_4 /* Clear IRQ Tx Parity Error */
1462 /* Bits 3..0: same as for RX_GMF_CTRL_T */
1463
1464#define GMF_RX_CTRL_DEF (GMF_OPER_ON | GMF_RX_F_FL_ON)
1465#define GMF_TX_CTRL_DEF GMF_OPER_ON
1466
1467#define RX_GMF_FL_THR_DEF 0x0a /* Rx GMAC FIFO Flush Threshold default */
1468
1469/* GMAC_TI_ST_CTRL 8 bit Time Stamp Timer Ctrl Reg (YUKON only) */
1470 /* Bit 7.. 3: reserved */
1471#define GMT_ST_START BIT_2S /* Start Time Stamp Timer */
1472#define GMT_ST_STOP BIT_1S /* Stop Time Stamp Timer */
1473#define GMT_ST_CLR_IRQ BIT_0S /* Clear Time Stamp Timer IRQ */
1474
1475/* GMAC_CTRL 32 bit GMAC Control Reg (YUKON only) */
1476 /* Bits 31.. 8: reserved */
1477#define GMC_H_BURST_ON BIT_7 /* Half Duplex Burst Mode On */
1478#define GMC_H_BURST_OFF BIT_6 /* Half Duplex Burst Mode Off */
1479#define GMC_F_LOOPB_ON BIT_5 /* FIFO Loopback On */
1480#define GMC_F_LOOPB_OFF BIT_4 /* FIFO Loopback Off */
1481#define GMC_PAUSE_ON BIT_3 /* Pause On */
1482#define GMC_PAUSE_OFF BIT_2 /* Pause Off */
1483#define GMC_RST_CLR BIT_1 /* Clear GMAC Reset */
1484#define GMC_RST_SET BIT_0 /* Set GMAC Reset */
1485
1486/* GPHY_CTRL 32 bit GPHY Control Reg (YUKON only) */
1487 /* Bits 31..29: reserved */
1488#define GPC_SEL_BDT BIT_28 /* Select Bi-Dir. Transfer for MDC/MDIO */
1489#define GPC_INT_POL_HI BIT_27 /* IRQ Polarity is Active HIGH */
1490#define GPC_75_OHM BIT_26 /* Use 75 Ohm Termination instead of 50 */
1491#define GPC_DIS_FC BIT_25 /* Disable Automatic Fiber/Copper Detection */
1492#define GPC_DIS_SLEEP BIT_24 /* Disable Energy Detect */
1493#define GPC_HWCFG_M_3 BIT_23 /* HWCFG_MODE[3] */
1494#define GPC_HWCFG_M_2 BIT_22 /* HWCFG_MODE[2] */
1495#define GPC_HWCFG_M_1 BIT_21 /* HWCFG_MODE[1] */
1496#define GPC_HWCFG_M_0 BIT_20 /* HWCFG_MODE[0] */
1497#define GPC_ANEG_0 BIT_19 /* ANEG[0] */
1498#define GPC_ENA_XC BIT_18 /* Enable MDI crossover */
1499#define GPC_DIS_125 BIT_17 /* Disable 125 MHz clock */
1500#define GPC_ANEG_3 BIT_16 /* ANEG[3] */
1501#define GPC_ANEG_2 BIT_15 /* ANEG[2] */
1502#define GPC_ANEG_1 BIT_14 /* ANEG[1] */
1503#define GPC_ENA_PAUSE BIT_13 /* Enable Pause (SYM_OR_REM) */
1504#define GPC_PHYADDR_4 BIT_12 /* Bit 4 of Phy Addr */
1505#define GPC_PHYADDR_3 BIT_11 /* Bit 3 of Phy Addr */
1506#define GPC_PHYADDR_2 BIT_10 /* Bit 2 of Phy Addr */
1507#define GPC_PHYADDR_1 BIT_9 /* Bit 1 of Phy Addr */
1508#define GPC_PHYADDR_0 BIT_8 /* Bit 0 of Phy Addr */
1509 /* Bits 7..2: reserved */
1510#define GPC_RST_CLR BIT_1 /* Clear GPHY Reset */
1511#define GPC_RST_SET BIT_0 /* Set GPHY Reset */
1512
1513#define GPC_HWCFG_GMII_COP (GPC_HWCFG_M_3 | GPC_HWCFG_M_2 | \
1514 GPC_HWCFG_M_1 | GPC_HWCFG_M_0)
1515
1516#define GPC_HWCFG_GMII_FIB ( GPC_HWCFG_M_2 | \
1517 GPC_HWCFG_M_1 | GPC_HWCFG_M_0)
1518
1519#define GPC_ANEG_ADV_ALL_M (GPC_ANEG_3 | GPC_ANEG_2 | \
1520 GPC_ANEG_1 | GPC_ANEG_0)
1521
1522/* forced speed and duplex mode (don't mix with other ANEG bits) */
1523#define GPC_FRC10MBIT_HALF 0
1524#define GPC_FRC10MBIT_FULL GPC_ANEG_0
1525#define GPC_FRC100MBIT_HALF GPC_ANEG_1
1526#define GPC_FRC100MBIT_FULL (GPC_ANEG_0 | GPC_ANEG_1)
1527
1528/* auto-negotiation with limited advertised speeds */
1529/* mix only with master/slave settings (for copper) */
1530#define GPC_ADV_1000_HALF GPC_ANEG_2
1531#define GPC_ADV_1000_FULL GPC_ANEG_3
1532#define GPC_ADV_ALL (GPC_ANEG_2 | GPC_ANEG_3)
1533
1534/* master/slave settings */
1535/* only for copper with 1000 Mbps */
1536#define GPC_FORCE_MASTER 0
1537#define GPC_FORCE_SLAVE GPC_ANEG_0
1538#define GPC_PREF_MASTER GPC_ANEG_1
1539#define GPC_PREF_SLAVE (GPC_ANEG_1 | GPC_ANEG_0)
1540
1541/* GMAC_IRQ_SRC 8 bit GMAC Interrupt Source Reg (YUKON only) */
1542/* GMAC_IRQ_MSK 8 bit GMAC Interrupt Mask Reg (YUKON only) */
1543#define GM_IS_TX_CO_OV BIT_5 /* Transmit Counter Overflow IRQ */
1544#define GM_IS_RX_CO_OV BIT_4 /* Receive Counter Overflow IRQ */
1545#define GM_IS_TX_FF_UR BIT_3 /* Transmit FIFO Underrun */
1546#define GM_IS_TX_COMPL BIT_2 /* Frame Transmission Complete */
1547#define GM_IS_RX_FF_OR BIT_1 /* Receive FIFO Overrun */
1548#define GM_IS_RX_COMPL BIT_0 /* Frame Reception Complete */
1549
1550#define GMAC_DEF_MSK (GM_IS_TX_CO_OV | GM_IS_RX_CO_OV | \
1551 GM_IS_TX_FF_UR)
1552
1553/* GMAC_LINK_CTRL 16 bit GMAC Link Control Reg (YUKON only) */
1554 /* Bits 15.. 2: reserved */
1555#define GMLC_RST_CLR BIT_1S /* Clear GMAC Link Reset */
1556#define GMLC_RST_SET BIT_0S /* Set GMAC Link Reset */
1557
1558
1559/* WOL_CTRL_STAT 16 bit WOL Control/Status Reg */
1560#define WOL_CTL_LINK_CHG_OCC BIT_15S
1561#define WOL_CTL_MAGIC_PKT_OCC BIT_14S
1562#define WOL_CTL_PATTERN_OCC BIT_13S
1563
1564#define WOL_CTL_CLEAR_RESULT BIT_12S
1565
1566#define WOL_CTL_ENA_PME_ON_LINK_CHG BIT_11S
1567#define WOL_CTL_DIS_PME_ON_LINK_CHG BIT_10S
1568#define WOL_CTL_ENA_PME_ON_MAGIC_PKT BIT_9S
1569#define WOL_CTL_DIS_PME_ON_MAGIC_PKT BIT_8S
1570#define WOL_CTL_ENA_PME_ON_PATTERN BIT_7S
1571#define WOL_CTL_DIS_PME_ON_PATTERN BIT_6S
1572
1573#define WOL_CTL_ENA_LINK_CHG_UNIT BIT_5S
1574#define WOL_CTL_DIS_LINK_CHG_UNIT BIT_4S
1575#define WOL_CTL_ENA_MAGIC_PKT_UNIT BIT_3S
1576#define WOL_CTL_DIS_MAGIC_PKT_UNIT BIT_2S
1577#define WOL_CTL_ENA_PATTERN_UNIT BIT_1S
1578#define WOL_CTL_DIS_PATTERN_UNIT BIT_0S
1579
1580#define WOL_CTL_DEFAULT \
1581 (WOL_CTL_DIS_PME_ON_LINK_CHG | \
1582 WOL_CTL_DIS_PME_ON_PATTERN | \
1583 WOL_CTL_DIS_PME_ON_MAGIC_PKT | \
1584 WOL_CTL_DIS_LINK_CHG_UNIT | \
1585 WOL_CTL_DIS_PATTERN_UNIT | \
1586 WOL_CTL_DIS_MAGIC_PKT_UNIT)
1587
1588/* WOL_MATCH_CTL 8 bit WOL Match Control Reg */
1589#define WOL_CTL_PATT_ENA(x) (BIT_0 << (x))
1590
1591#define SK_NUM_WOL_PATTERN 7
1592#define SK_PATTERN_PER_WORD 4
1593#define SK_BITMASK_PATTERN 7
1594#define SK_POW_PATTERN_LENGTH 128
1595
1596#define WOL_LENGTH_MSK 0x7f
1597#define WOL_LENGTH_SHIFT 8
1598
1599
1600/* Receive and Transmit Descriptors ******************************************/
1601
1602/* Transmit Descriptor struct */
1603typedef struct s_HwTxd {
1604 SK_U32 volatile TxCtrl; /* Transmit Buffer Control Field */
1605 SK_U32 TxNext; /* Physical Address Pointer to the next TxD */
1606 SK_U32 TxAdrLo; /* Physical Tx Buffer Address lower dword */
1607 SK_U32 TxAdrHi; /* Physical Tx Buffer Address upper dword */
1608 SK_U32 TxStat; /* Transmit Frame Status Word */
1609#ifndef SK_USE_REV_DESC
1610 SK_U16 TxTcpOffs; /* TCP Checksum Calculation Start Value */
1611 SK_U16 TxRes1; /* 16 bit reserved field */
1612 SK_U16 TxTcpWp; /* TCP Checksum Write Position */
1613 SK_U16 TxTcpSp; /* TCP Checksum Calculation Start Position */
1614#else /* SK_USE_REV_DESC */
1615 SK_U16 TxRes1; /* 16 bit reserved field */
1616 SK_U16 TxTcpOffs; /* TCP Checksum Calculation Start Value */
1617 SK_U16 TxTcpSp; /* TCP Checksum Calculation Start Position */
1618 SK_U16 TxTcpWp; /* TCP Checksum Write Position */
1619#endif /* SK_USE_REV_DESC */
1620 SK_U32 TxRes2; /* 32 bit reserved field */
1621} SK_HWTXD;
1622
1623/* Receive Descriptor struct */
1624typedef struct s_HwRxd {
1625 SK_U32 volatile RxCtrl; /* Receive Buffer Control Field */
1626 SK_U32 RxNext; /* Physical Address Pointer to the next RxD */
1627 SK_U32 RxAdrLo; /* Physical Rx Buffer Address lower dword */
1628 SK_U32 RxAdrHi; /* Physical Rx Buffer Address upper dword */
1629 SK_U32 RxStat; /* Receive Frame Status Word */
1630 SK_U32 RxTiSt; /* Receive Time Stamp (from XMAC on GENESIS) */
1631#ifndef SK_USE_REV_DESC
1632 SK_U16 RxTcpSum1; /* TCP Checksum 1 */
1633 SK_U16 RxTcpSum2; /* TCP Checksum 2 */
1634 SK_U16 RxTcpSp1; /* TCP Checksum Calculation Start Position 1 */
1635 SK_U16 RxTcpSp2; /* TCP Checksum Calculation Start Position 2 */
1636#else /* SK_USE_REV_DESC */
1637 SK_U16 RxTcpSum2; /* TCP Checksum 2 */
1638 SK_U16 RxTcpSum1; /* TCP Checksum 1 */
1639 SK_U16 RxTcpSp2; /* TCP Checksum Calculation Start Position 2 */
1640 SK_U16 RxTcpSp1; /* TCP Checksum Calculation Start Position 1 */
1641#endif /* SK_USE_REV_DESC */
1642} SK_HWRXD;
1643
1644/*
1645 * Drivers which use the reverse descriptor feature (PCI_OUR_REG_2)
1646 * should set the define SK_USE_REV_DESC.
1647 * Structures are 'normaly' not endianess dependent. But in
1648 * this case the SK_U16 fields are bound to bit positions inside the
1649 * descriptor. RxTcpSum1 e.g. must start at bit 0 within the 6.th DWord.
1650 * The bit positions inside a DWord are of course endianess dependent and
1651 * swaps if the DWord is swapped by the hardware.
1652 */
1653
1654
1655/* Descriptor Bit Definition */
1656/* TxCtrl Transmit Buffer Control Field */
1657/* RxCtrl Receive Buffer Control Field */
1658#define BMU_OWN BIT_31 /* OWN bit: 0=host/1=BMU */
1659#define BMU_STF BIT_30 /* Start of Frame */
1660#define BMU_EOF BIT_29 /* End of Frame */
1661#define BMU_IRQ_EOB BIT_28 /* Req "End of Buffer" IRQ */
1662#define BMU_IRQ_EOF BIT_27 /* Req "End of Frame" IRQ */
1663/* TxCtrl specific bits */
1664#define BMU_STFWD BIT_26 /* (Tx) Store & Forward Frame */
1665#define BMU_NO_FCS BIT_25 /* (Tx) Disable MAC FCS (CRC) generation */
1666#define BMU_SW BIT_24 /* (Tx) 1 bit res. for SW use */
1667/* RxCtrl specific bits */
1668#define BMU_DEV_0 BIT_26 /* (Rx) Transfer data to Dev0 */
1669#define BMU_STAT_VAL BIT_25 /* (Rx) Rx Status Valid */
1670#define BMU_TIST_VAL BIT_24 /* (Rx) Rx TimeStamp Valid */
1671 /* Bit 23..16: BMU Check Opcodes */
1672#define BMU_CHECK (0x55L<<16) /* Default BMU check */
1673#define BMU_TCP_CHECK (0x56L<<16) /* Descr with TCP ext */
1674#define BMU_UDP_CHECK (0x57L<<16) /* Descr with UDP ext (YUKON only) */
1675#define BMU_BBC 0xffffL /* Bit 15.. 0: Buffer Byte Counter */
1676
1677/* TxStat Transmit Frame Status Word */
1678/* RxStat Receive Frame Status Word */
1679/*
1680 *Note: TxStat is reserved for ASIC loopback mode only
1681 *
1682 * The Bits of the Status words are defined in xmac_ii.h
1683 * (see XMR_FS bits)
1684 */
1685
1686/* macros ********************************************************************/
1687
1688/* Receive and Transmit Queues */
1689#define Q_R1 0x0000 /* Receive Queue 1 */
1690#define Q_R2 0x0080 /* Receive Queue 2 */
1691#define Q_XS1 0x0200 /* Synchronous Transmit Queue 1 */
1692#define Q_XA1 0x0280 /* Asynchronous Transmit Queue 1 */
1693#define Q_XS2 0x0300 /* Synchronous Transmit Queue 2 */
1694#define Q_XA2 0x0380 /* Asynchronous Transmit Queue 2 */
1695
1696/*
1697 * Macro Q_ADDR()
1698 *
1699 * Use this macro to access the Receive and Transmit Queue Registers.
1700 *
1701 * para:
1702 * Queue Queue to access.
1703 * Values: Q_R1, Q_R2, Q_XS1, Q_XA1, Q_XS2, and Q_XA2
1704 * Offs Queue register offset.
1705 * Values: Q_D, Q_DA_L ... Q_T2, Q_T3
1706 *
1707 * usage SK_IN32(pAC, Q_ADDR(Q_R2, Q_BC), pVal)
1708 */
1709#define Q_ADDR(Queue, Offs) (B8_Q_REGS + (Queue) + (Offs))
1710
1711/*
1712 * Macro RB_ADDR()
1713 *
1714 * Use this macro to access the RAM Buffer Registers.
1715 *
1716 * para:
1717 * Queue Queue to access.
1718 * Values: Q_R1, Q_R2, Q_XS1, Q_XA1, Q_XS2, and Q_XA2
1719 * Offs Queue register offset.
1720 * Values: RB_START, RB_END ... RB_LEV, RB_CTRL
1721 *
1722 * usage SK_IN32(pAC, RB_ADDR(Q_R2, RB_RP), pVal)
1723 */
1724#define RB_ADDR(Queue, Offs) (B16_RAM_REGS + (Queue) + (Offs))
1725
1726
1727/* MAC Related Registers */
1728#define MAC_1 0 /* belongs to the port near the slot */
1729#define MAC_2 1 /* belongs to the port far away from the slot */
1730
1731/*
1732 * Macro MR_ADDR()
1733 *
1734 * Use this macro to access a MAC Related Registers inside the ASIC.
1735 *
1736 * para:
1737 * Mac MAC to access.
1738 * Values: MAC_1, MAC_2
1739 * Offs MAC register offset.
1740 * Values: RX_MFF_EA, RX_MFF_WP ... LNK_LED_REG,
1741 * TX_MFF_EA, TX_MFF_WP ... TX_LED_TST
1742 *
1743 * usage SK_IN32(pAC, MR_ADDR(MAC_1, TX_MFF_EA), pVal)
1744 */
1745#define MR_ADDR(Mac, Offs) (((Mac) << 7) + (Offs))
1746
1747#ifdef SK_LITTLE_ENDIAN
1748#define XM_WORD_LO 0
1749#define XM_WORD_HI 1
1750#else /* !SK_LITTLE_ENDIAN */
1751#define XM_WORD_LO 1
1752#define XM_WORD_HI 0
1753#endif /* !SK_LITTLE_ENDIAN */
1754
1755
1756/*
1757 * macros to access the XMAC (GENESIS only)
1758 *
1759 * XM_IN16(), to read a 16 bit register (e.g. XM_MMU_CMD)
1760 * XM_OUT16(), to write a 16 bit register (e.g. XM_MMU_CMD)
1761 * XM_IN32(), to read a 32 bit register (e.g. XM_TX_EV_CNT)
1762 * XM_OUT32(), to write a 32 bit register (e.g. XM_TX_EV_CNT)
1763 * XM_INADDR(), to read a network address register (e.g. XM_SRC_CHK)
1764 * XM_OUTADDR(), to write a network address register (e.g. XM_SRC_CHK)
1765 * XM_INHASH(), to read the XM_HSM_CHK register
1766 * XM_OUTHASH() to write the XM_HSM_CHK register
1767 *
1768 * para:
1769 * Mac XMAC to access values: MAC_1 or MAC_2
1770 * IoC I/O context needed for SK I/O macros
1771 * Reg XMAC Register to read or write
1772 * (p)Val Value or pointer to the value which should be read or written
1773 *
1774 * usage: XM_OUT16(IoC, MAC_1, XM_MMU_CMD, Value);
1775 */
1776
1777#define XMA(Mac, Reg) \
1778 ((BASE_XMAC_1 + (Mac) * (BASE_XMAC_2 - BASE_XMAC_1)) | ((Reg) << 1))
1779
1780#define XM_IN16(IoC, Mac, Reg, pVal) \
1781 SK_IN16((IoC), XMA((Mac), (Reg)), (pVal))
1782
1783#define XM_OUT16(IoC, Mac, Reg, Val) \
1784 SK_OUT16((IoC), XMA((Mac), (Reg)), (Val))
1785
1786#define XM_IN32(IoC, Mac, Reg, pVal) { \
1787 SK_IN16((IoC), XMA((Mac), (Reg)), \
1788 (SK_U16 SK_FAR*)&((SK_U16 SK_FAR*)(pVal))[XM_WORD_LO]); \
1789 SK_IN16((IoC), XMA((Mac), (Reg+2)), \
1790 (SK_U16 SK_FAR*)&((SK_U16 SK_FAR*)(pVal))[XM_WORD_HI]); \
1791}
1792
1793#define XM_OUT32(IoC, Mac, Reg, Val) { \
1794 SK_OUT16((IoC), XMA((Mac), (Reg)), (SK_U16)((Val) & 0xffffL)); \
1795 SK_OUT16((IoC), XMA((Mac), (Reg+2)), (SK_U16)(((Val) >> 16) & 0xffffL));\
1796}
1797
1798/* Remember: we are always writing to / reading from LITTLE ENDIAN memory */
1799
1800#define XM_INADDR(IoC, Mac, Reg, pVal) { \
1801 SK_U16 Word; \
1802 SK_U8 *pByte; \
1803 pByte = (SK_U8 *)&((SK_U8 *)(pVal))[0]; \
1804 SK_IN16((IoC), XMA((Mac), (Reg)), &Word); \
1805 pByte[0] = (SK_U8)(Word & 0x00ff); \
1806 pByte[1] = (SK_U8)((Word >> 8) & 0x00ff); \
1807 SK_IN16((IoC), XMA((Mac), (Reg+2)), &Word); \
1808 pByte[2] = (SK_U8)(Word & 0x00ff); \
1809 pByte[3] = (SK_U8)((Word >> 8) & 0x00ff); \
1810 SK_IN16((IoC), XMA((Mac), (Reg+4)), &Word); \
1811 pByte[4] = (SK_U8)(Word & 0x00ff); \
1812 pByte[5] = (SK_U8)((Word >> 8) & 0x00ff); \
1813}
1814
1815#define XM_OUTADDR(IoC, Mac, Reg, pVal) { \
1816 SK_U8 SK_FAR *pByte; \
1817 pByte = (SK_U8 SK_FAR *)&((SK_U8 SK_FAR *)(pVal))[0]; \
1818 SK_OUT16((IoC), XMA((Mac), (Reg)), (SK_U16) \
1819 (((SK_U16)(pByte[0]) & 0x00ff) | \
1820 (((SK_U16)(pByte[1]) << 8) & 0xff00))); \
1821 SK_OUT16((IoC), XMA((Mac), (Reg+2)), (SK_U16) \
1822 (((SK_U16)(pByte[2]) & 0x00ff) | \
1823 (((SK_U16)(pByte[3]) << 8) & 0xff00))); \
1824 SK_OUT16((IoC), XMA((Mac), (Reg+4)), (SK_U16) \
1825 (((SK_U16)(pByte[4]) & 0x00ff) | \
1826 (((SK_U16)(pByte[5]) << 8) & 0xff00))); \
1827}
1828
1829#define XM_INHASH(IoC, Mac, Reg, pVal) { \
1830 SK_U16 Word; \
1831 SK_U8 SK_FAR *pByte; \
1832 pByte = (SK_U8 SK_FAR *)&((SK_U8 SK_FAR *)(pVal))[0]; \
1833 SK_IN16((IoC), XMA((Mac), (Reg)), &Word); \
1834 pByte[0] = (SK_U8)(Word & 0x00ff); \
1835 pByte[1] = (SK_U8)((Word >> 8) & 0x00ff); \
1836 SK_IN16((IoC), XMA((Mac), (Reg+2)), &Word); \
1837 pByte[2] = (SK_U8)(Word & 0x00ff); \
1838 pByte[3] = (SK_U8)((Word >> 8) & 0x00ff); \
1839 SK_IN16((IoC), XMA((Mac), (Reg+4)), &Word); \
1840 pByte[4] = (SK_U8)(Word & 0x00ff); \
1841 pByte[5] = (SK_U8)((Word >> 8) & 0x00ff); \
1842 SK_IN16((IoC), XMA((Mac), (Reg+6)), &Word); \
1843 pByte[6] = (SK_U8)(Word & 0x00ff); \
1844 pByte[7] = (SK_U8)((Word >> 8) & 0x00ff); \
1845}
1846
1847#define XM_OUTHASH(IoC, Mac, Reg, pVal) { \
1848 SK_U8 SK_FAR *pByte; \
1849 pByte = (SK_U8 SK_FAR *)&((SK_U8 SK_FAR *)(pVal))[0]; \
1850 SK_OUT16((IoC), XMA((Mac), (Reg)), (SK_U16) \
1851 (((SK_U16)(pByte[0]) & 0x00ff)| \
1852 (((SK_U16)(pByte[1]) << 8) & 0xff00))); \
1853 SK_OUT16((IoC), XMA((Mac), (Reg+2)), (SK_U16) \
1854 (((SK_U16)(pByte[2]) & 0x00ff)| \
1855 (((SK_U16)(pByte[3]) << 8) & 0xff00))); \
1856 SK_OUT16((IoC), XMA((Mac), (Reg+4)), (SK_U16) \
1857 (((SK_U16)(pByte[4]) & 0x00ff)| \
1858 (((SK_U16)(pByte[5]) << 8) & 0xff00))); \
1859 SK_OUT16((IoC), XMA((Mac), (Reg+6)), (SK_U16) \
1860 (((SK_U16)(pByte[6]) & 0x00ff)| \
1861 (((SK_U16)(pByte[7]) << 8) & 0xff00))); \
1862}
1863
1864/*
1865 * macros to access the GMAC (YUKON only)
1866 *
1867 * GM_IN16(), to read a 16 bit register (e.g. GM_GP_STAT)
1868 * GM_OUT16(), to write a 16 bit register (e.g. GM_GP_CTRL)
1869 * GM_IN32(), to read a 32 bit register (e.g. GM_)
1870 * GM_OUT32(), to write a 32 bit register (e.g. GM_)
1871 * GM_INADDR(), to read a network address register (e.g. GM_SRC_ADDR_1L)
1872 * GM_OUTADDR(), to write a network address register (e.g. GM_SRC_ADDR_2L)
1873 * GM_INHASH(), to read the GM_MC_ADDR_H1 register
1874 * GM_OUTHASH() to write the GM_MC_ADDR_H1 register
1875 *
1876 * para:
1877 * Mac GMAC to access values: MAC_1 or MAC_2
1878 * IoC I/O context needed for SK I/O macros
1879 * Reg GMAC Register to read or write
1880 * (p)Val Value or pointer to the value which should be read or written
1881 *
1882 * usage: GM_OUT16(IoC, MAC_1, GM_GP_CTRL, Value);
1883 */
1884
1885#define GMA(Mac, Reg) \
1886 ((BASE_GMAC_1 + (Mac) * (BASE_GMAC_2 - BASE_GMAC_1)) | (Reg))
1887
1888#define GM_IN16(IoC, Mac, Reg, pVal) \
1889 SK_IN16((IoC), GMA((Mac), (Reg)), (pVal))
1890
1891#define GM_OUT16(IoC, Mac, Reg, Val) \
1892 SK_OUT16((IoC), GMA((Mac), (Reg)), (Val))
1893
1894#define GM_IN32(IoC, Mac, Reg, pVal) { \
1895 SK_IN16((IoC), GMA((Mac), (Reg)), \
1896 (SK_U16 SK_FAR*)&((SK_U16 SK_FAR*)(pVal))[XM_WORD_LO]); \
1897 SK_IN16((IoC), GMA((Mac), (Reg+4)), \
1898 (SK_U16 SK_FAR*)&((SK_U16 SK_FAR*)(pVal))[XM_WORD_HI]); \
1899}
1900
1901#define GM_OUT32(IoC, Mac, Reg, Val) { \
1902 SK_OUT16((IoC), GMA((Mac), (Reg)), (SK_U16)((Val) & 0xffffL)); \
1903 SK_OUT16((IoC), GMA((Mac), (Reg+4)), (SK_U16)(((Val) >> 16) & 0xffffL));\
1904}
1905
1906#define GM_INADDR(IoC, Mac, Reg, pVal) { \
1907 SK_U16 Word; \
1908 SK_U8 *pByte; \
1909 pByte = (SK_U8 *)&((SK_U8 *)(pVal))[0]; \
1910 SK_IN16((IoC), GMA((Mac), (Reg)), &Word); \
1911 pByte[0] = (SK_U8)(Word & 0x00ff); \
1912 pByte[1] = (SK_U8)((Word >> 8) & 0x00ff); \
1913 SK_IN16((IoC), GMA((Mac), (Reg+4)), &Word); \
1914 pByte[2] = (SK_U8)(Word & 0x00ff); \
1915 pByte[3] = (SK_U8)((Word >> 8) & 0x00ff); \
1916 SK_IN16((IoC), GMA((Mac), (Reg+8)), &Word); \
1917 pByte[4] = (SK_U8)(Word & 0x00ff); \
1918 pByte[5] = (SK_U8)((Word >> 8) & 0x00ff); \
1919}
1920
1921#define GM_OUTADDR(IoC, Mac, Reg, pVal) { \
1922 SK_U8 SK_FAR *pByte; \
1923 pByte = (SK_U8 SK_FAR *)&((SK_U8 SK_FAR *)(pVal))[0]; \
1924 SK_OUT16((IoC), GMA((Mac), (Reg)), (SK_U16) \
1925 (((SK_U16)(pByte[0]) & 0x00ff) | \
1926 (((SK_U16)(pByte[1]) << 8) & 0xff00))); \
1927 SK_OUT16((IoC), GMA((Mac), (Reg+4)), (SK_U16) \
1928 (((SK_U16)(pByte[2]) & 0x00ff) | \
1929 (((SK_U16)(pByte[3]) << 8) & 0xff00))); \
1930 SK_OUT16((IoC), GMA((Mac), (Reg+8)), (SK_U16) \
1931 (((SK_U16)(pByte[4]) & 0x00ff) | \
1932 (((SK_U16)(pByte[5]) << 8) & 0xff00))); \
1933}
1934
1935#define GM_INHASH(IoC, Mac, Reg, pVal) { \
1936 SK_U16 Word; \
1937 SK_U8 *pByte; \
1938 pByte = (SK_U8 *)&((SK_U8 *)(pVal))[0]; \
1939 SK_IN16((IoC), GMA((Mac), (Reg)), &Word); \
1940 pByte[0] = (SK_U8)(Word & 0x00ff); \
1941 pByte[1] = (SK_U8)((Word >> 8) & 0x00ff); \
1942 SK_IN16((IoC), GMA((Mac), (Reg+4)), &Word); \
1943 pByte[2] = (SK_U8)(Word & 0x00ff); \
1944 pByte[3] = (SK_U8)((Word >> 8) & 0x00ff); \
1945 SK_IN16((IoC), GMA((Mac), (Reg+8)), &Word); \
1946 pByte[4] = (SK_U8)(Word & 0x00ff); \
1947 pByte[5] = (SK_U8)((Word >> 8) & 0x00ff); \
1948 SK_IN16((IoC), GMA((Mac), (Reg+12)), &Word); \
1949 pByte[6] = (SK_U8)(Word & 0x00ff); \
1950 pByte[7] = (SK_U8)((Word >> 8) & 0x00ff); \
1951}
1952
1953#define GM_OUTHASH(IoC, Mac, Reg, pVal) { \
1954 SK_U8 *pByte; \
1955 pByte = (SK_U8 *)&((SK_U8 *)(pVal))[0]; \
1956 SK_OUT16((IoC), GMA((Mac), (Reg)), (SK_U16) \
1957 (((SK_U16)(pByte[0]) & 0x00ff)| \
1958 (((SK_U16)(pByte[1]) << 8) & 0xff00))); \
1959 SK_OUT16((IoC), GMA((Mac), (Reg+4)), (SK_U16) \
1960 (((SK_U16)(pByte[2]) & 0x00ff)| \
1961 (((SK_U16)(pByte[3]) << 8) & 0xff00))); \
1962 SK_OUT16((IoC), GMA((Mac), (Reg+8)), (SK_U16) \
1963 (((SK_U16)(pByte[4]) & 0x00ff)| \
1964 (((SK_U16)(pByte[5]) << 8) & 0xff00))); \
1965 SK_OUT16((IoC), GMA((Mac), (Reg+12)), (SK_U16) \
1966 (((SK_U16)(pByte[6]) & 0x00ff)| \
1967 (((SK_U16)(pByte[7]) << 8) & 0xff00))); \
1968}
1969
1970/*
1971 * Different MAC Types
1972 */
1973#define SK_MAC_XMAC 0 /* Xaqti XMAC II */
1974#define SK_MAC_GMAC 1 /* Marvell GMAC */
1975
1976/*
1977 * Different PHY Types
1978 */
1979#define SK_PHY_XMAC 0 /* integrated in XMAC II */
1980#define SK_PHY_BCOM 1 /* Broadcom BCM5400 */
1981#define SK_PHY_LONE 2 /* Level One LXT1000 */
1982#define SK_PHY_NAT 3 /* National DP83891 */
1983#define SK_PHY_MARV_COPPER 4 /* Marvell 88E1011S */
1984#define SK_PHY_MARV_FIBER 5 /* Marvell 88E1011S working on fiber */
1985
1986/*
1987 * PHY addresses (bits 12..8 of PHY address reg)
1988 */
1989#define PHY_ADDR_XMAC (0<<8)
1990#define PHY_ADDR_BCOM (1<<8)
1991#define PHY_ADDR_LONE (3<<8)
1992#define PHY_ADDR_NAT (0<<8)
1993
1994/* GPHY address (bits 15..11 of SMI control reg) */
1995#define PHY_ADDR_MARV 0
1996
1997/*
1998 * macros to access the PHY
1999 *
2000 * PHY_READ() read a 16 bit value from the PHY
2001 * PHY_WRITE() write a 16 bit value to the PHY
2002 *
2003 * para:
2004 * IoC I/O context needed for SK I/O macros
2005 * pPort Pointer to port struct for PhyAddr
2006 * Mac XMAC to access values: MAC_1 or MAC_2
2007 * PhyReg PHY Register to read or write
2008 * (p)Val Value or pointer to the value which should be read or
2009 * written.
2010 *
2011 * usage: PHY_READ(IoC, pPort, MAC_1, PHY_CTRL, Value);
2012 * Warning: a PHY_READ on an uninitialized PHY (PHY still in reset) never
2013 * comes back. This is checked in DEBUG mode.
2014 */
2015#ifndef DEBUG
2016#define PHY_READ(IoC, pPort, Mac, PhyReg, pVal) { \
2017 SK_U16 Mmu; \
2018 \
2019 XM_OUT16((IoC), (Mac), XM_PHY_ADDR, (PhyReg) | (pPort)->PhyAddr); \
2020 XM_IN16((IoC), (Mac), XM_PHY_DATA, (pVal)); \
2021 if ((pPort)->PhyType != SK_PHY_XMAC) { \
2022 do { \
2023 XM_IN16((IoC), (Mac), XM_MMU_CMD, &Mmu); \
2024 } while ((Mmu & XM_MMU_PHY_RDY) == 0); \
2025 XM_IN16((IoC), (Mac), XM_PHY_DATA, (pVal)); \
2026 } \
2027}
2028#else
2029#define PHY_READ(IoC, pPort, Mac, PhyReg, pVal) { \
2030 SK_U16 Mmu; \
2031 int __i = 0; \
2032 \
2033 XM_OUT16((IoC), (Mac), XM_PHY_ADDR, (PhyReg) | (pPort)->PhyAddr); \
2034 XM_IN16((IoC), (Mac), XM_PHY_DATA, (pVal)); \
2035 if ((pPort)->PhyType != SK_PHY_XMAC) { \
2036 do { \
2037 XM_IN16((IoC), (Mac), XM_MMU_CMD, &Mmu); \
2038 __i++; \
2039 if (__i > 100000) { \
2040 SK_DBG_PRINTF("*****************************\n"); \
2041 SK_DBG_PRINTF("PHY_READ on uninitialized PHY\n"); \
2042 SK_DBG_PRINTF("*****************************\n"); \
2043 break; \
2044 } \
2045 } while ((Mmu & XM_MMU_PHY_RDY) == 0); \
2046 XM_IN16((IoC), (Mac), XM_PHY_DATA, (pVal)); \
2047 } \
2048}
2049#endif /* DEBUG */
2050
2051#define PHY_WRITE(IoC, pPort, Mac, PhyReg, Val) { \
2052 SK_U16 Mmu; \
2053 \
2054 if ((pPort)->PhyType != SK_PHY_XMAC) { \
2055 do { \
2056 XM_IN16((IoC), (Mac), XM_MMU_CMD, &Mmu); \
2057 } while ((Mmu & XM_MMU_PHY_BUSY) != 0); \
2058 } \
2059 XM_OUT16((IoC), (Mac), XM_PHY_ADDR, (PhyReg) | (pPort)->PhyAddr); \
2060 XM_OUT16((IoC), (Mac), XM_PHY_DATA, (Val)); \
2061 if ((pPort)->PhyType != SK_PHY_XMAC) { \
2062 do { \
2063 XM_IN16((IoC), (Mac), XM_MMU_CMD, &Mmu); \
2064 } while ((Mmu & XM_MMU_PHY_BUSY) != 0); \
2065 } \
2066}
2067
2068/*
2069 * Macro PCI_C()
2070 *
2071 * Use this macro to access PCI config register from the I/O space.
2072 *
2073 * para:
2074 * Addr PCI configuration register to access.
2075 * Values: PCI_VENDOR_ID ... PCI_VPD_ADR_REG,
2076 *
2077 * usage SK_IN16(pAC, PCI_C(PCI_VENDOR_ID), pVal);
2078 */
2079#define PCI_C(Addr) (B7_CFG_SPC + (Addr)) /* PCI Config Space */
2080
2081/*
2082 * Macro SK_HW_ADDR(Base, Addr)
2083 *
2084 * Calculates the effective HW address
2085 *
2086 * para:
2087 * Base I/O or memory base address
2088 * Addr Address offset
2089 *
2090 * usage: May be used in SK_INxx and SK_OUTxx macros
2091 * #define SK_IN8(pAC, Addr, pVal) ...\
2092 * *pVal = (SK_U8)inp(SK_HW_ADDR(pAC->Hw.Iop, Addr)))
2093 */
2094#ifdef SK_MEM_MAPPED_IO
2095#define SK_HW_ADDR(Base, Addr) ((Base) + (Addr))
2096#else /* SK_MEM_MAPPED_IO */
2097#define SK_HW_ADDR(Base, Addr) \
2098 ((Base) + (((Addr) & 0x7f) | (((Addr) >> 7 > 0) ? 0x80 : 0)))
2099#endif /* SK_MEM_MAPPED_IO */
2100
2101#define SZ_LONG (sizeof(SK_U32))
2102
2103/*
2104 * Macro SK_HWAC_LINK_LED()
2105 *
2106 * Use this macro to set the link LED mode.
2107 * para:
2108 * pAC Pointer to adapter context struct
2109 * IoC I/O context needed for SK I/O macros
2110 * Port Port number
2111 * Mode Mode to set for this LED
2112 */
2113#define SK_HWAC_LINK_LED(pAC, IoC, Port, Mode) \
2114 SK_OUT8(IoC, MR_ADDR(Port, LNK_LED_REG), Mode);
2115
2116
2117/* typedefs *******************************************************************/
2118
2119
2120/* function prototypes ********************************************************/
2121
2122#ifdef __cplusplus
2123}
2124#endif /* __cplusplus */
2125
2126#endif /* __INC_SKGEHW_H */
diff --git a/drivers/net/sk98lin/h/skgehwt.h b/drivers/net/sk98lin/h/skgehwt.h
deleted file mode 100644
index e6b0016a695c..000000000000
--- a/drivers/net/sk98lin/h/skgehwt.h
+++ /dev/null
@@ -1,48 +0,0 @@
1/******************************************************************************
2 *
3 * Name: skhwt.h
4 * Project: Gigabit Ethernet Adapters, Event Scheduler Module
5 * Version: $Revision: 1.7 $
6 * Date: $Date: 2003/09/16 12:55:08 $
7 * Purpose: Defines for the hardware timer functions
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect GmbH.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25/*
26 * SKGEHWT.H contains all defines and types for the timer functions
27 */
28
29#ifndef _SKGEHWT_H_
30#define _SKGEHWT_H_
31
32/*
33 * SK Hardware Timer
34 * - needed wherever the HWT module is used
35 * - use in Adapters context name pAC->Hwt
36 */
37typedef struct s_Hwt {
38 SK_U32 TStart; /* HWT start */
39 SK_U32 TStop; /* HWT stop */
40 int TActive; /* HWT: flag : active/inactive */
41} SK_HWT;
42
43extern void SkHwtInit(SK_AC *pAC, SK_IOC Ioc);
44extern void SkHwtStart(SK_AC *pAC, SK_IOC Ioc, SK_U32 Time);
45extern void SkHwtStop(SK_AC *pAC, SK_IOC Ioc);
46extern SK_U32 SkHwtRead(SK_AC *pAC, SK_IOC Ioc);
47extern void SkHwtIsr(SK_AC *pAC, SK_IOC Ioc);
48#endif /* _SKGEHWT_H_ */
diff --git a/drivers/net/sk98lin/h/skgei2c.h b/drivers/net/sk98lin/h/skgei2c.h
deleted file mode 100644
index d9b6f6d8dfe2..000000000000
--- a/drivers/net/sk98lin/h/skgei2c.h
+++ /dev/null
@@ -1,210 +0,0 @@
1/******************************************************************************
2 *
3 * Name: skgei2c.h
4 * Project: Gigabit Ethernet Adapters, TWSI-Module
5 * Version: $Revision: 1.25 $
6 * Date: $Date: 2003/10/20 09:06:05 $
7 * Purpose: Special defines for TWSI
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25/*
26 * SKGEI2C.H contains all SK-98xx specific defines for the TWSI handling
27 */
28
29#ifndef _INC_SKGEI2C_H_
30#define _INC_SKGEI2C_H_
31
32/*
33 * Macros to access the B2_I2C_CTRL
34 */
35#define SK_I2C_CTL(IoC, flag, dev, dev_size, reg, burst) \
36 SK_OUT32(IoC, B2_I2C_CTRL,\
37 (flag ? 0x80000000UL : 0x0L) | \
38 (((SK_U32)reg << 16) & I2C_ADDR) | \
39 (((SK_U32)dev << 9) & I2C_DEV_SEL) | \
40 (dev_size & I2C_DEV_SIZE) | \
41 ((burst << 4) & I2C_BURST_LEN))
42
43#define SK_I2C_STOP(IoC) { \
44 SK_U32 I2cCtrl; \
45 SK_IN32(IoC, B2_I2C_CTRL, &I2cCtrl); \
46 SK_OUT32(IoC, B2_I2C_CTRL, I2cCtrl | I2C_STOP); \
47}
48
49#define SK_I2C_GET_CTL(IoC, pI2cCtrl) SK_IN32(IoC, B2_I2C_CTRL, pI2cCtrl)
50
51/*
52 * Macros to access the TWSI SW Registers
53 */
54#define SK_I2C_SET_BIT(IoC, SetBits) { \
55 SK_U8 OrgBits; \
56 SK_IN8(IoC, B2_I2C_SW, &OrgBits); \
57 SK_OUT8(IoC, B2_I2C_SW, OrgBits | (SK_U8)(SetBits)); \
58}
59
60#define SK_I2C_CLR_BIT(IoC, ClrBits) { \
61 SK_U8 OrgBits; \
62 SK_IN8(IoC, B2_I2C_SW, &OrgBits); \
63 SK_OUT8(IoC, B2_I2C_SW, OrgBits & ~((SK_U8)(ClrBits))); \
64}
65
66#define SK_I2C_GET_SW(IoC, pI2cSw) SK_IN8(IoC, B2_I2C_SW, pI2cSw)
67
68/*
69 * define the possible sensor states
70 */
71#define SK_SEN_IDLE 0 /* Idle: sensor not read */
72#define SK_SEN_VALUE 1 /* Value Read cycle */
73#define SK_SEN_VALEXT 2 /* Extended Value Read cycle */
74
75/*
76 * Conversion factor to convert read Voltage sensor to milli Volt
77 * Conversion factor to convert read Temperature sensor to 10th degree Celsius
78 */
79#define SK_LM80_VT_LSB 22 /* 22mV LSB resolution */
80#define SK_LM80_TEMP_LSB 10 /* 1 degree LSB resolution */
81#define SK_LM80_TEMPEXT_LSB 5 /* 0.5 degree LSB resolution for ext. val. */
82
83/*
84 * formula: counter = (22500*60)/(rpm * divisor * pulses/2)
85 * assuming: 6500rpm, 4 pulses, divisor 1
86 */
87#define SK_LM80_FAN_FAKTOR ((22500L*60)/(1*2))
88
89/*
90 * Define sensor management data
91 * Maximum is reached on Genesis copper dual port and Yukon-64
92 * Board specific maximum is in pAC->I2c.MaxSens
93 */
94#define SK_MAX_SENSORS 8 /* maximal no. of installed sensors */
95#define SK_MIN_SENSORS 5 /* minimal no. of installed sensors */
96
97/*
98 * To watch the state machine (SM) use the timer in two ways
99 * instead of one as hitherto
100 */
101#define SK_TIMER_WATCH_SM 0 /* Watch the SM to finish in a spec. time */
102#define SK_TIMER_NEW_GAUGING 1 /* Start a new gauging when timer expires */
103
104/*
105 * Defines for the individual thresholds
106 */
107
108/* Temperature sensor */
109#define SK_SEN_TEMP_HIGH_ERR 800 /* Temperature High Err Threshold */
110#define SK_SEN_TEMP_HIGH_WARN 700 /* Temperature High Warn Threshold */
111#define SK_SEN_TEMP_LOW_WARN 100 /* Temperature Low Warn Threshold */
112#define SK_SEN_TEMP_LOW_ERR 0 /* Temperature Low Err Threshold */
113
114/* VCC which should be 5 V */
115#define SK_SEN_PCI_5V_HIGH_ERR 5588 /* Voltage PCI High Err Threshold */
116#define SK_SEN_PCI_5V_HIGH_WARN 5346 /* Voltage PCI High Warn Threshold */
117#define SK_SEN_PCI_5V_LOW_WARN 4664 /* Voltage PCI Low Warn Threshold */
118#define SK_SEN_PCI_5V_LOW_ERR 4422 /* Voltage PCI Low Err Threshold */
119
120/*
121 * VIO may be 5 V or 3.3 V. Initialization takes two parts:
122 * 1. Initialize lowest lower limit and highest higher limit.
123 * 2. After the first value is read correct the upper or the lower limit to
124 * the appropriate C constant.
125 *
126 * Warning limits are +-5% of the exepected voltage.
127 * Error limits are +-10% of the expected voltage.
128 */
129
130/* Bug fix AF: 16.Aug.2001: Correct the init base of LM80 sensor */
131
132#define SK_SEN_PCI_IO_5V_HIGH_ERR 5566 /* + 10% V PCI-IO High Err Threshold */
133#define SK_SEN_PCI_IO_5V_HIGH_WARN 5324 /* + 5% V PCI-IO High Warn Threshold */
134 /* 5000 mVolt */
135#define SK_SEN_PCI_IO_5V_LOW_WARN 4686 /* - 5% V PCI-IO Low Warn Threshold */
136#define SK_SEN_PCI_IO_5V_LOW_ERR 4444 /* - 10% V PCI-IO Low Err Threshold */
137
138#define SK_SEN_PCI_IO_RANGE_LIMITER 4000 /* 4000 mV range delimiter */
139
140/* correction values for the second pass */
141#define SK_SEN_PCI_IO_3V3_HIGH_ERR 3850 /* + 15% V PCI-IO High Err Threshold */
142#define SK_SEN_PCI_IO_3V3_HIGH_WARN 3674 /* + 10% V PCI-IO High Warn Threshold */
143 /* 3300 mVolt */
144#define SK_SEN_PCI_IO_3V3_LOW_WARN 2926 /* - 10% V PCI-IO Low Warn Threshold */
145#define SK_SEN_PCI_IO_3V3_LOW_ERR 2772 /* - 15% V PCI-IO Low Err Threshold */
146
147/*
148 * VDD voltage
149 */
150#define SK_SEN_VDD_HIGH_ERR 3630 /* Voltage ASIC High Err Threshold */
151#define SK_SEN_VDD_HIGH_WARN 3476 /* Voltage ASIC High Warn Threshold */
152#define SK_SEN_VDD_LOW_WARN 3146 /* Voltage ASIC Low Warn Threshold */
153#define SK_SEN_VDD_LOW_ERR 2970 /* Voltage ASIC Low Err Threshold */
154
155/*
156 * PHY PLL 3V3 voltage
157 */
158#define SK_SEN_PLL_3V3_HIGH_ERR 3630 /* Voltage PMA High Err Threshold */
159#define SK_SEN_PLL_3V3_HIGH_WARN 3476 /* Voltage PMA High Warn Threshold */
160#define SK_SEN_PLL_3V3_LOW_WARN 3146 /* Voltage PMA Low Warn Threshold */
161#define SK_SEN_PLL_3V3_LOW_ERR 2970 /* Voltage PMA Low Err Threshold */
162
163/*
164 * VAUX (YUKON only)
165 */
166#define SK_SEN_VAUX_3V3_HIGH_ERR 3630 /* Voltage VAUX High Err Threshold */
167#define SK_SEN_VAUX_3V3_HIGH_WARN 3476 /* Voltage VAUX High Warn Threshold */
168#define SK_SEN_VAUX_3V3_LOW_WARN 3146 /* Voltage VAUX Low Warn Threshold */
169#define SK_SEN_VAUX_3V3_LOW_ERR 2970 /* Voltage VAUX Low Err Threshold */
170#define SK_SEN_VAUX_0V_WARN_ERR 0 /* if VAUX not present */
171#define SK_SEN_VAUX_RANGE_LIMITER 1000 /* 1000 mV range delimiter */
172
173/*
174 * PHY 2V5 voltage
175 */
176#define SK_SEN_PHY_2V5_HIGH_ERR 2750 /* Voltage PHY High Err Threshold */
177#define SK_SEN_PHY_2V5_HIGH_WARN 2640 /* Voltage PHY High Warn Threshold */
178#define SK_SEN_PHY_2V5_LOW_WARN 2376 /* Voltage PHY Low Warn Threshold */
179#define SK_SEN_PHY_2V5_LOW_ERR 2222 /* Voltage PHY Low Err Threshold */
180
181/*
182 * ASIC Core 1V5 voltage (YUKON only)
183 */
184#define SK_SEN_CORE_1V5_HIGH_ERR 1650 /* Voltage ASIC Core High Err Threshold */
185#define SK_SEN_CORE_1V5_HIGH_WARN 1575 /* Voltage ASIC Core High Warn Threshold */
186#define SK_SEN_CORE_1V5_LOW_WARN 1425 /* Voltage ASIC Core Low Warn Threshold */
187#define SK_SEN_CORE_1V5_LOW_ERR 1350 /* Voltage ASIC Core Low Err Threshold */
188
189/*
190 * FAN 1 speed
191 */
192/* assuming: 6500rpm +-15%, 4 pulses,
193 * warning at: 80 %
194 * error at: 70 %
195 * no upper limit
196 */
197#define SK_SEN_FAN_HIGH_ERR 20000 /* FAN Speed High Err Threshold */
198#define SK_SEN_FAN_HIGH_WARN 20000 /* FAN Speed High Warn Threshold */
199#define SK_SEN_FAN_LOW_WARN 5200 /* FAN Speed Low Warn Threshold */
200#define SK_SEN_FAN_LOW_ERR 4550 /* FAN Speed Low Err Threshold */
201
202/*
203 * Some Voltages need dynamic thresholds
204 */
205#define SK_SEN_DYN_INIT_NONE 0 /* No dynamic init of thresholds */
206#define SK_SEN_DYN_INIT_PCI_IO 10 /* Init PCI-IO with new thresholds */
207#define SK_SEN_DYN_INIT_VAUX 11 /* Init VAUX with new thresholds */
208
209extern int SkLm80ReadSensor(SK_AC *pAC, SK_IOC IoC, SK_SENSOR *pSen);
210#endif /* n_INC_SKGEI2C_H */
diff --git a/drivers/net/sk98lin/h/skgeinit.h b/drivers/net/sk98lin/h/skgeinit.h
deleted file mode 100644
index 143e635ec24d..000000000000
--- a/drivers/net/sk98lin/h/skgeinit.h
+++ /dev/null
@@ -1,797 +0,0 @@
1/******************************************************************************
2 *
3 * Name: skgeinit.h
4 * Project: Gigabit Ethernet Adapters, Common Modules
5 * Version: $Revision: 1.83 $
6 * Date: $Date: 2003/09/16 14:07:37 $
7 * Purpose: Structures and prototypes for the GE Init Module
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25#ifndef __INC_SKGEINIT_H_
26#define __INC_SKGEINIT_H_
27
28#ifdef __cplusplus
29extern "C" {
30#endif /* __cplusplus */
31
32/* defines ********************************************************************/
33
34#define SK_TEST_VAL 0x11335577UL
35
36/* modifying Link LED behaviour (used with SkGeLinkLED()) */
37#define SK_LNK_OFF LED_OFF
38#define SK_LNK_ON (LED_ON | LED_BLK_OFF | LED_SYNC_OFF)
39#define SK_LNK_BLINK (LED_ON | LED_BLK_ON | LED_SYNC_ON)
40#define SK_LNK_PERM (LED_ON | LED_BLK_OFF | LED_SYNC_ON)
41#define SK_LNK_TST (LED_ON | LED_BLK_ON | LED_SYNC_OFF)
42
43/* parameter 'Mode' when calling SK_HWAC_LINK_LED() */
44#define SK_LED_OFF LED_OFF
45#define SK_LED_ACTIVE (LED_ON | LED_BLK_OFF | LED_SYNC_OFF)
46#define SK_LED_STANDBY (LED_ON | LED_BLK_ON | LED_SYNC_OFF)
47
48/* addressing LED Registers in SkGeXmitLED() */
49#define XMIT_LED_INI 0
50#define XMIT_LED_CNT (RX_LED_VAL - RX_LED_INI)
51#define XMIT_LED_CTRL (RX_LED_CTRL- RX_LED_INI)
52#define XMIT_LED_TST (RX_LED_TST - RX_LED_INI)
53
54/* parameter 'Mode' when calling SkGeXmitLED() */
55#define SK_LED_DIS 0
56#define SK_LED_ENA 1
57#define SK_LED_TST 2
58
59/* Counter and Timer constants, for a host clock of 62.5 MHz */
60#define SK_XMIT_DUR 0x002faf08UL /* 50 ms */
61#define SK_BLK_DUR 0x01dcd650UL /* 500 ms */
62
63#define SK_DPOLL_DEF 0x00ee6b28UL /* 250 ms at 62.5 MHz */
64
65#define SK_DPOLL_MAX 0x00ffffffUL /* 268 ms at 62.5 MHz */
66 /* 215 ms at 78.12 MHz */
67
68#define SK_FACT_62 100 /* is given in percent */
69#define SK_FACT_53 85 /* on GENESIS: 53.12 MHz */
70#define SK_FACT_78 125 /* on YUKON: 78.12 MHz */
71
72/* Timeout values */
73#define SK_MAC_TO_53 72 /* MAC arbiter timeout */
74#define SK_PKT_TO_53 0x2000 /* Packet arbiter timeout */
75#define SK_PKT_TO_MAX 0xffff /* Maximum value */
76#define SK_RI_TO_53 36 /* RAM interface timeout */
77
78#define SK_PHY_ACC_TO 600000 /* PHY access timeout */
79
80/* RAM Buffer High Pause Threshold values */
81#define SK_RB_ULPP ( 8 * 1024) /* Upper Level in kB/8 */
82#define SK_RB_LLPP_S (10 * 1024) /* Lower Level for small Queues */
83#define SK_RB_LLPP_B (16 * 1024) /* Lower Level for big Queues */
84
85#ifndef SK_BMU_RX_WM
86#define SK_BMU_RX_WM 0x600 /* BMU Rx Watermark */
87#endif
88#ifndef SK_BMU_TX_WM
89#define SK_BMU_TX_WM 0x600 /* BMU Tx Watermark */
90#endif
91
92/* XMAC II Rx High Watermark */
93#define SK_XM_RX_HI_WM 0x05aa /* 1450 */
94
95/* XMAC II Tx Threshold */
96#define SK_XM_THR_REDL 0x01fb /* .. for redundant link usage */
97#define SK_XM_THR_SL 0x01fb /* .. for single link adapters */
98#define SK_XM_THR_MULL 0x01fb /* .. for multiple link usage */
99#define SK_XM_THR_JUMBO 0x03fc /* .. for jumbo frame usage */
100
101/* values for GIPortUsage */
102#define SK_RED_LINK 1 /* redundant link usage */
103#define SK_MUL_LINK 2 /* multiple link usage */
104#define SK_JUMBO_LINK 3 /* driver uses jumbo frames */
105
106/* Minimum RAM Buffer Rx Queue Size */
107#define SK_MIN_RXQ_SIZE 16 /* 16 kB */
108
109/* Minimum RAM Buffer Tx Queue Size */
110#define SK_MIN_TXQ_SIZE 16 /* 16 kB */
111
112/* Queue Size units */
113#define QZ_UNITS 0x7
114#define QZ_STEP 8
115
116/* Percentage of queue size from whole memory */
117/* 80 % for receive */
118#define RAM_QUOTA_RX 80L
119/* 0% for sync transfer */
120#define RAM_QUOTA_SYNC 0L
121/* the rest (20%) is taken for async transfer */
122
123/* Get the rounded queue size in Bytes in 8k steps */
124#define ROUND_QUEUE_SIZE(SizeInBytes) \
125 ((((unsigned long) (SizeInBytes) + (QZ_STEP*1024L)-1) / 1024) & \
126 ~(QZ_STEP-1))
127
128/* Get the rounded queue size in KBytes in 8k steps */
129#define ROUND_QUEUE_SIZE_KB(Kilobytes) \
130 ROUND_QUEUE_SIZE((Kilobytes) * 1024L)
131
132/* Types of RAM Buffer Queues */
133#define SK_RX_SRAM_Q 1 /* small receive queue */
134#define SK_RX_BRAM_Q 2 /* big receive queue */
135#define SK_TX_RAM_Q 3 /* small or big transmit queue */
136
137/* parameter 'Dir' when calling SkGeStopPort() */
138#define SK_STOP_TX 1 /* Stops the transmit path, resets the XMAC */
139#define SK_STOP_RX 2 /* Stops the receive path */
140#define SK_STOP_ALL 3 /* Stops Rx and Tx path, resets the XMAC */
141
142/* parameter 'RstMode' when calling SkGeStopPort() */
143#define SK_SOFT_RST 1 /* perform a software reset */
144#define SK_HARD_RST 2 /* perform a hardware reset */
145
146/* Init Levels */
147#define SK_INIT_DATA 0 /* Init level 0: init data structures */
148#define SK_INIT_IO 1 /* Init level 1: init with IOs */
149#define SK_INIT_RUN 2 /* Init level 2: init for run time */
150
151/* Link Mode Parameter */
152#define SK_LMODE_HALF 1 /* Half Duplex Mode */
153#define SK_LMODE_FULL 2 /* Full Duplex Mode */
154#define SK_LMODE_AUTOHALF 3 /* AutoHalf Duplex Mode */
155#define SK_LMODE_AUTOFULL 4 /* AutoFull Duplex Mode */
156#define SK_LMODE_AUTOBOTH 5 /* AutoBoth Duplex Mode */
157#define SK_LMODE_AUTOSENSE 6 /* configured mode auto sensing */
158#define SK_LMODE_INDETERMINATED 7 /* indeterminated */
159
160/* Auto-negotiation timeout in 100ms granularity */
161#define SK_AND_MAX_TO 6 /* Wait 600 msec before link comes up */
162
163/* Auto-negotiation error codes */
164#define SK_AND_OK 0 /* no error */
165#define SK_AND_OTHER 1 /* other error than below */
166#define SK_AND_DUP_CAP 2 /* Duplex capabilities error */
167
168
169/* Link Speed Capabilities */
170#define SK_LSPEED_CAP_AUTO (1<<0) /* Automatic resolution */
171#define SK_LSPEED_CAP_10MBPS (1<<1) /* 10 Mbps */
172#define SK_LSPEED_CAP_100MBPS (1<<2) /* 100 Mbps */
173#define SK_LSPEED_CAP_1000MBPS (1<<3) /* 1000 Mbps */
174#define SK_LSPEED_CAP_INDETERMINATED (1<<4) /* indeterminated */
175
176/* Link Speed Parameter */
177#define SK_LSPEED_AUTO 1 /* Automatic resolution */
178#define SK_LSPEED_10MBPS 2 /* 10 Mbps */
179#define SK_LSPEED_100MBPS 3 /* 100 Mbps */
180#define SK_LSPEED_1000MBPS 4 /* 1000 Mbps */
181#define SK_LSPEED_INDETERMINATED 5 /* indeterminated */
182
183/* Link Speed Current State */
184#define SK_LSPEED_STAT_UNKNOWN 1
185#define SK_LSPEED_STAT_10MBPS 2
186#define SK_LSPEED_STAT_100MBPS 3
187#define SK_LSPEED_STAT_1000MBPS 4
188#define SK_LSPEED_STAT_INDETERMINATED 5
189
190
191/* Link Capability Parameter */
192#define SK_LMODE_CAP_HALF (1<<0) /* Half Duplex Mode */
193#define SK_LMODE_CAP_FULL (1<<1) /* Full Duplex Mode */
194#define SK_LMODE_CAP_AUTOHALF (1<<2) /* AutoHalf Duplex Mode */
195#define SK_LMODE_CAP_AUTOFULL (1<<3) /* AutoFull Duplex Mode */
196#define SK_LMODE_CAP_INDETERMINATED (1<<4) /* indeterminated */
197
198/* Link Mode Current State */
199#define SK_LMODE_STAT_UNKNOWN 1 /* Unknown Duplex Mode */
200#define SK_LMODE_STAT_HALF 2 /* Half Duplex Mode */
201#define SK_LMODE_STAT_FULL 3 /* Full Duplex Mode */
202#define SK_LMODE_STAT_AUTOHALF 4 /* Half Duplex Mode obtained by Auto-Neg */
203#define SK_LMODE_STAT_AUTOFULL 5 /* Full Duplex Mode obtained by Auto-Neg */
204#define SK_LMODE_STAT_INDETERMINATED 6 /* indeterminated */
205
206/* Flow Control Mode Parameter (and capabilities) */
207#define SK_FLOW_MODE_NONE 1 /* No Flow-Control */
208#define SK_FLOW_MODE_LOC_SEND 2 /* Local station sends PAUSE */
209#define SK_FLOW_MODE_SYMMETRIC 3 /* Both stations may send PAUSE */
210#define SK_FLOW_MODE_SYM_OR_REM 4 /* Both stations may send PAUSE or
211 * just the remote station may send PAUSE
212 */
213#define SK_FLOW_MODE_INDETERMINATED 5 /* indeterminated */
214
215/* Flow Control Status Parameter */
216#define SK_FLOW_STAT_NONE 1 /* No Flow Control */
217#define SK_FLOW_STAT_REM_SEND 2 /* Remote Station sends PAUSE */
218#define SK_FLOW_STAT_LOC_SEND 3 /* Local station sends PAUSE */
219#define SK_FLOW_STAT_SYMMETRIC 4 /* Both station may send PAUSE */
220#define SK_FLOW_STAT_INDETERMINATED 5 /* indeterminated */
221
222/* Master/Slave Mode Capabilities */
223#define SK_MS_CAP_AUTO (1<<0) /* Automatic resolution */
224#define SK_MS_CAP_MASTER (1<<1) /* This station is master */
225#define SK_MS_CAP_SLAVE (1<<2) /* This station is slave */
226#define SK_MS_CAP_INDETERMINATED (1<<3) /* indeterminated */
227
228/* Set Master/Slave Mode Parameter (and capabilities) */
229#define SK_MS_MODE_AUTO 1 /* Automatic resolution */
230#define SK_MS_MODE_MASTER 2 /* This station is master */
231#define SK_MS_MODE_SLAVE 3 /* This station is slave */
232#define SK_MS_MODE_INDETERMINATED 4 /* indeterminated */
233
234/* Master/Slave Status Parameter */
235#define SK_MS_STAT_UNSET 1 /* The M/S status is not set */
236#define SK_MS_STAT_MASTER 2 /* This station is master */
237#define SK_MS_STAT_SLAVE 3 /* This station is slave */
238#define SK_MS_STAT_FAULT 4 /* M/S resolution failed */
239#define SK_MS_STAT_INDETERMINATED 5 /* indeterminated */
240
241/* parameter 'Mode' when calling SkXmSetRxCmd() */
242#define SK_STRIP_FCS_ON (1<<0) /* Enable FCS stripping of Rx frames */
243#define SK_STRIP_FCS_OFF (1<<1) /* Disable FCS stripping of Rx frames */
244#define SK_STRIP_PAD_ON (1<<2) /* Enable pad byte stripping of Rx fr */
245#define SK_STRIP_PAD_OFF (1<<3) /* Disable pad byte stripping of Rx fr */
246#define SK_LENERR_OK_ON (1<<4) /* Don't chk fr for in range len error */
247#define SK_LENERR_OK_OFF (1<<5) /* Check frames for in range len error */
248#define SK_BIG_PK_OK_ON (1<<6) /* Don't set Rx Error bit for big frames */
249#define SK_BIG_PK_OK_OFF (1<<7) /* Set Rx Error bit for big frames */
250#define SK_SELF_RX_ON (1<<8) /* Enable Rx of own packets */
251#define SK_SELF_RX_OFF (1<<9) /* Disable Rx of own packets */
252
253/* parameter 'Para' when calling SkMacSetRxTxEn() */
254#define SK_MAC_LOOPB_ON (1<<0) /* Enable MAC Loopback Mode */
255#define SK_MAC_LOOPB_OFF (1<<1) /* Disable MAC Loopback Mode */
256#define SK_PHY_LOOPB_ON (1<<2) /* Enable PHY Loopback Mode */
257#define SK_PHY_LOOPB_OFF (1<<3) /* Disable PHY Loopback Mode */
258#define SK_PHY_FULLD_ON (1<<4) /* Enable GMII Full Duplex */
259#define SK_PHY_FULLD_OFF (1<<5) /* Disable GMII Full Duplex */
260
261/* States of PState */
262#define SK_PRT_RESET 0 /* the port is reset */
263#define SK_PRT_STOP 1 /* the port is stopped (similar to SW reset) */
264#define SK_PRT_INIT 2 /* the port is initialized */
265#define SK_PRT_RUN 3 /* the port has an active link */
266
267/* PHY power down modes */
268#define PHY_PM_OPERATIONAL_MODE 0 /* PHY operational mode */
269#define PHY_PM_DEEP_SLEEP 1 /* coma mode --> minimal power */
270#define PHY_PM_IEEE_POWER_DOWN 2 /* IEEE 22.2.4.1.5 compl. power down */
271#define PHY_PM_ENERGY_DETECT 3 /* energy detect */
272#define PHY_PM_ENERGY_DETECT_PLUS 4 /* energy detect plus */
273
274/* Default receive frame limit for Workaround of XMAC Errata */
275#define SK_DEF_RX_WA_LIM SK_CONSTU64(100)
276
277/* values for GILedBlinkCtrl (LED Blink Control) */
278#define SK_ACT_LED_BLINK (1<<0) /* Active LED blinking */
279#define SK_DUP_LED_NORMAL (1<<1) /* Duplex LED normal */
280#define SK_LED_LINK100_ON (1<<2) /* Link 100M LED on */
281
282/* Link Partner Status */
283#define SK_LIPA_UNKNOWN 0 /* Link partner is in unknown state */
284#define SK_LIPA_MANUAL 1 /* Link partner is in detected manual state */
285#define SK_LIPA_AUTO 2 /* Link partner is in auto-negotiation state */
286
287/* Maximum Restarts before restart is ignored (3Com WA) */
288#define SK_MAX_LRESTART 3 /* Max. 3 times the link is restarted */
289
290/* Max. Auto-neg. timeouts before link detection in sense mode is reset */
291#define SK_MAX_ANEG_TO 10 /* Max. 10 times the sense mode is reset */
292
293/* structures *****************************************************************/
294
295/*
296 * MAC specific functions
297 */
298typedef struct s_GeMacFunc {
299 int (*pFnMacUpdateStats)(SK_AC *pAC, SK_IOC IoC, unsigned int Port);
300 int (*pFnMacStatistic)(SK_AC *pAC, SK_IOC IoC, unsigned int Port,
301 SK_U16 StatAddr, SK_U32 SK_FAR *pVal);
302 int (*pFnMacResetCounter)(SK_AC *pAC, SK_IOC IoC, unsigned int Port);
303 int (*pFnMacOverflow)(SK_AC *pAC, SK_IOC IoC, unsigned int Port,
304 SK_U16 IStatus, SK_U64 SK_FAR *pVal);
305} SK_GEMACFUNC;
306
307/*
308 * Port Structure
309 */
310typedef struct s_GePort {
311#ifndef SK_DIAG
312 SK_TIMER PWaTimer; /* Workaround Timer */
313 SK_TIMER HalfDupChkTimer;
314#endif /* SK_DIAG */
315 SK_U32 PPrevShorts; /* Previous Short Counter checking */
316 SK_U32 PPrevFcs; /* Previous FCS Error Counter checking */
317 SK_U64 PPrevRx; /* Previous RxOk Counter checking */
318 SK_U64 PRxLim; /* Previous RxOk Counter checking */
319 SK_U64 LastOctets; /* For half duplex hang check */
320 int PLinkResCt; /* Link Restart Counter */
321 int PAutoNegTimeOut;/* Auto-negotiation timeout current value */
322 int PAutoNegTOCt; /* Auto-negotiation Timeout Counter */
323 int PRxQSize; /* Port Rx Queue Size in kB */
324 int PXSQSize; /* Port Synchronous Transmit Queue Size in kB */
325 int PXAQSize; /* Port Asynchronous Transmit Queue Size in kB */
326 SK_U32 PRxQRamStart; /* Receive Queue RAM Buffer Start Address */
327 SK_U32 PRxQRamEnd; /* Receive Queue RAM Buffer End Address */
328 SK_U32 PXsQRamStart; /* Sync Tx Queue RAM Buffer Start Address */
329 SK_U32 PXsQRamEnd; /* Sync Tx Queue RAM Buffer End Address */
330 SK_U32 PXaQRamStart; /* Async Tx Queue RAM Buffer Start Address */
331 SK_U32 PXaQRamEnd; /* Async Tx Queue RAM Buffer End Address */
332 SK_U32 PRxOverCnt; /* Receive Overflow Counter */
333 int PRxQOff; /* Rx Queue Address Offset */
334 int PXsQOff; /* Synchronous Tx Queue Address Offset */
335 int PXaQOff; /* Asynchronous Tx Queue Address Offset */
336 int PhyType; /* PHY used on this port */
337 int PState; /* Port status (reset, stop, init, run) */
338 SK_U16 PhyId1; /* PHY Id1 on this port */
339 SK_U16 PhyAddr; /* MDIO/MDC PHY address */
340 SK_U16 PIsave; /* Saved Interrupt status word */
341 SK_U16 PSsave; /* Saved PHY status word */
342 SK_U16 PGmANegAdv; /* Saved GPhy AutoNegAdvertisment register */
343 SK_BOOL PHWLinkUp; /* The hardware Link is up (wiring) */
344 SK_BOOL PLinkBroken; /* Is Link broken ? */
345 SK_BOOL PCheckPar; /* Do we check for parity errors ? */
346 SK_BOOL HalfDupTimerActive;
347 SK_U8 PLinkCap; /* Link Capabilities */
348 SK_U8 PLinkModeConf; /* Link Mode configured */
349 SK_U8 PLinkMode; /* Link Mode currently used */
350 SK_U8 PLinkModeStatus;/* Link Mode Status */
351 SK_U8 PLinkSpeedCap; /* Link Speed Capabilities(10/100/1000 Mbps) */
352 SK_U8 PLinkSpeed; /* configured Link Speed (10/100/1000 Mbps) */
353 SK_U8 PLinkSpeedUsed; /* current Link Speed (10/100/1000 Mbps) */
354 SK_U8 PFlowCtrlCap; /* Flow Control Capabilities */
355 SK_U8 PFlowCtrlMode; /* Flow Control Mode */
356 SK_U8 PFlowCtrlStatus;/* Flow Control Status */
357 SK_U8 PMSCap; /* Master/Slave Capabilities */
358 SK_U8 PMSMode; /* Master/Slave Mode */
359 SK_U8 PMSStatus; /* Master/Slave Status */
360 SK_BOOL PAutoNegFail; /* Auto-negotiation fail flag */
361 SK_U8 PLipaAutoNeg; /* Auto-negotiation possible with Link Partner */
362 SK_U8 PCableLen; /* Cable Length */
363 SK_U8 PMdiPairLen[4]; /* MDI[0..3] Pair Length */
364 SK_U8 PMdiPairSts[4]; /* MDI[0..3] Pair Diagnostic Status */
365 SK_U8 PPhyPowerState; /* PHY current power state */
366 int PMacColThres; /* MAC Collision Threshold */
367 int PMacJamLen; /* MAC Jam length */
368 int PMacJamIpgVal; /* MAC Jam IPG */
369 int PMacJamIpgData; /* MAC IPG Jam to Data */
370 int PMacIpgData; /* MAC Data IPG */
371 SK_BOOL PMacLimit4; /* reset collision counter and backoff algorithm */
372} SK_GEPORT;
373
374/*
375 * Gigabit Ethernet Initialization Struct
376 * (has to be included in the adapter context)
377 */
378typedef struct s_GeInit {
379 int GIChipId; /* Chip Identification Number */
380 int GIChipRev; /* Chip Revision Number */
381 SK_U8 GIPciHwRev; /* PCI HW Revision Number */
382 SK_BOOL GIGenesis; /* Genesis adapter ? */
383 SK_BOOL GIYukon; /* YUKON-A1/Bx chip */
384 SK_BOOL GIYukonLite; /* YUKON-Lite chip */
385 SK_BOOL GICopperType; /* Copper Type adapter ? */
386 SK_BOOL GIPciSlot64; /* 64-bit PCI Slot */
387 SK_BOOL GIPciClock66; /* 66 MHz PCI Clock */
388 SK_BOOL GIVauxAvail; /* VAUX available (YUKON) */
389 SK_BOOL GIYukon32Bit; /* 32-Bit YUKON adapter */
390 SK_U16 GILedBlinkCtrl; /* LED Blink Control */
391 int GIMacsFound; /* Number of MACs found on this adapter */
392 int GIMacType; /* MAC Type used on this adapter */
393 int GIHstClkFact; /* Host Clock Factor (62.5 / HstClk * 100) */
394 int GIPortUsage; /* Driver Port Usage */
395 int GILevel; /* Initialization Level completed */
396 int GIRamSize; /* The RAM size of the adapter in kB */
397 int GIWolOffs; /* WOL Register Offset (HW-Bug in Rev. A) */
398 SK_U32 GIRamOffs; /* RAM Address Offset for addr calculation */
399 SK_U32 GIPollTimerVal; /* Descr. Poll Timer Init Val (HstClk ticks) */
400 SK_U32 GIValIrqMask; /* Value for Interrupt Mask */
401 SK_U32 GITimeStampCnt; /* Time Stamp High Counter (YUKON only) */
402 SK_GEPORT GP[SK_MAX_MACS];/* Port Dependent Information */
403 SK_GEMACFUNC GIFunc; /* MAC depedent functions */
404} SK_GEINIT;
405
406/*
407 * Error numbers and messages for skxmac2.c and skgeinit.c
408 */
409#define SKERR_HWI_E001 (SK_ERRBASE_HWINIT)
410#define SKERR_HWI_E001MSG "SkXmClrExactAddr() has got illegal parameters"
411#define SKERR_HWI_E002 (SKERR_HWI_E001+1)
412#define SKERR_HWI_E002MSG "SkGeInit(): Level 1 call missing"
413#define SKERR_HWI_E003 (SKERR_HWI_E002+1)
414#define SKERR_HWI_E003MSG "SkGeInit() called with illegal init Level"
415#define SKERR_HWI_E004 (SKERR_HWI_E003+1)
416#define SKERR_HWI_E004MSG "SkGeInitPort(): Queue Size illegal configured"
417#define SKERR_HWI_E005 (SKERR_HWI_E004+1)
418#define SKERR_HWI_E005MSG "SkGeInitPort(): cannot init running ports"
419#define SKERR_HWI_E006 (SKERR_HWI_E005+1)
420#define SKERR_HWI_E006MSG "SkGeMacInit(): PState does not match HW state"
421#define SKERR_HWI_E007 (SKERR_HWI_E006+1)
422#define SKERR_HWI_E007MSG "SkXmInitDupMd() called with invalid Dup Mode"
423#define SKERR_HWI_E008 (SKERR_HWI_E007+1)
424#define SKERR_HWI_E008MSG "SkXmSetRxCmd() called with invalid Mode"
425#define SKERR_HWI_E009 (SKERR_HWI_E008+1)
426#define SKERR_HWI_E009MSG "SkGeCfgSync() called although PXSQSize zero"
427#define SKERR_HWI_E010 (SKERR_HWI_E009+1)
428#define SKERR_HWI_E010MSG "SkGeCfgSync() called with invalid parameters"
429#define SKERR_HWI_E011 (SKERR_HWI_E010+1)
430#define SKERR_HWI_E011MSG "SkGeInitPort(): Receive Queue Size too small"
431#define SKERR_HWI_E012 (SKERR_HWI_E011+1)
432#define SKERR_HWI_E012MSG "SkGeInitPort(): invalid Queue Size specified"
433#define SKERR_HWI_E013 (SKERR_HWI_E012+1)
434#define SKERR_HWI_E013MSG "SkGeInitPort(): cfg changed for running queue"
435#define SKERR_HWI_E014 (SKERR_HWI_E013+1)
436#define SKERR_HWI_E014MSG "SkGeInitPort(): unknown GIPortUsage specified"
437#define SKERR_HWI_E015 (SKERR_HWI_E014+1)
438#define SKERR_HWI_E015MSG "Illegal Link mode parameter"
439#define SKERR_HWI_E016 (SKERR_HWI_E015+1)
440#define SKERR_HWI_E016MSG "Illegal Flow control mode parameter"
441#define SKERR_HWI_E017 (SKERR_HWI_E016+1)
442#define SKERR_HWI_E017MSG "Illegal value specified for GIPollTimerVal"
443#define SKERR_HWI_E018 (SKERR_HWI_E017+1)
444#define SKERR_HWI_E018MSG "FATAL: SkGeStopPort() does not terminate (Tx)"
445#define SKERR_HWI_E019 (SKERR_HWI_E018+1)
446#define SKERR_HWI_E019MSG "Illegal Speed parameter"
447#define SKERR_HWI_E020 (SKERR_HWI_E019+1)
448#define SKERR_HWI_E020MSG "Illegal Master/Slave parameter"
449#define SKERR_HWI_E021 (SKERR_HWI_E020+1)
450#define SKERR_HWI_E021MSG "MacUpdateStats(): cannot update statistic counter"
451#define SKERR_HWI_E022 (SKERR_HWI_E021+1)
452#define SKERR_HWI_E022MSG "MacStatistic(): illegal statistic base address"
453#define SKERR_HWI_E023 (SKERR_HWI_E022+1)
454#define SKERR_HWI_E023MSG "SkGeInitPort(): Transmit Queue Size too small"
455#define SKERR_HWI_E024 (SKERR_HWI_E023+1)
456#define SKERR_HWI_E024MSG "FATAL: SkGeStopPort() does not terminate (Rx)"
457#define SKERR_HWI_E025 (SKERR_HWI_E024+1)
458#define SKERR_HWI_E025MSG ""
459
460/* function prototypes ********************************************************/
461
462#ifndef SK_KR_PROTO
463
464/*
465 * public functions in skgeinit.c
466 */
467extern void SkGePollTxD(
468 SK_AC *pAC,
469 SK_IOC IoC,
470 int Port,
471 SK_BOOL PollTxD);
472
473extern void SkGeYellowLED(
474 SK_AC *pAC,
475 SK_IOC IoC,
476 int State);
477
478extern int SkGeCfgSync(
479 SK_AC *pAC,
480 SK_IOC IoC,
481 int Port,
482 SK_U32 IntTime,
483 SK_U32 LimCount,
484 int SyncMode);
485
486extern void SkGeLoadLnkSyncCnt(
487 SK_AC *pAC,
488 SK_IOC IoC,
489 int Port,
490 SK_U32 CntVal);
491
492extern void SkGeStopPort(
493 SK_AC *pAC,
494 SK_IOC IoC,
495 int Port,
496 int Dir,
497 int RstMode);
498
499extern int SkGeInit(
500 SK_AC *pAC,
501 SK_IOC IoC,
502 int Level);
503
504extern void SkGeDeInit(
505 SK_AC *pAC,
506 SK_IOC IoC);
507
508extern int SkGeInitPort(
509 SK_AC *pAC,
510 SK_IOC IoC,
511 int Port);
512
513extern void SkGeXmitLED(
514 SK_AC *pAC,
515 SK_IOC IoC,
516 int Led,
517 int Mode);
518
519extern int SkGeInitAssignRamToQueues(
520 SK_AC *pAC,
521 int ActivePort,
522 SK_BOOL DualNet);
523
524/*
525 * public functions in skxmac2.c
526 */
527extern void SkMacRxTxDisable(
528 SK_AC *pAC,
529 SK_IOC IoC,
530 int Port);
531
532extern void SkMacSoftRst(
533 SK_AC *pAC,
534 SK_IOC IoC,
535 int Port);
536
537extern void SkMacHardRst(
538 SK_AC *pAC,
539 SK_IOC IoC,
540 int Port);
541
542extern void SkXmInitMac(
543 SK_AC *pAC,
544 SK_IOC IoC,
545 int Port);
546
547extern void SkGmInitMac(
548 SK_AC *pAC,
549 SK_IOC IoC,
550 int Port);
551
552extern void SkMacInitPhy(
553 SK_AC *pAC,
554 SK_IOC IoC,
555 int Port,
556 SK_BOOL DoLoop);
557
558extern void SkMacIrqDisable(
559 SK_AC *pAC,
560 SK_IOC IoC,
561 int Port);
562
563extern void SkMacFlushTxFifo(
564 SK_AC *pAC,
565 SK_IOC IoC,
566 int Port);
567
568extern void SkMacIrq(
569 SK_AC *pAC,
570 SK_IOC IoC,
571 int Port);
572
573extern int SkMacAutoNegDone(
574 SK_AC *pAC,
575 SK_IOC IoC,
576 int Port);
577
578extern void SkMacAutoNegLipaPhy(
579 SK_AC *pAC,
580 SK_IOC IoC,
581 int Port,
582 SK_U16 IStatus);
583
584extern int SkMacRxTxEnable(
585 SK_AC *pAC,
586 SK_IOC IoC,
587 int Port);
588
589extern void SkMacPromiscMode(
590 SK_AC *pAC,
591 SK_IOC IoC,
592 int Port,
593 SK_BOOL Enable);
594
595extern void SkMacHashing(
596 SK_AC *pAC,
597 SK_IOC IoC,
598 int Port,
599 SK_BOOL Enable);
600
601extern void SkXmPhyRead(
602 SK_AC *pAC,
603 SK_IOC IoC,
604 int Port,
605 int Addr,
606 SK_U16 SK_FAR *pVal);
607
608extern void SkXmPhyWrite(
609 SK_AC *pAC,
610 SK_IOC IoC,
611 int Port,
612 int Addr,
613 SK_U16 Val);
614
615extern void SkGmPhyRead(
616 SK_AC *pAC,
617 SK_IOC IoC,
618 int Port,
619 int Addr,
620 SK_U16 SK_FAR *pVal);
621
622extern void SkGmPhyWrite(
623 SK_AC *pAC,
624 SK_IOC IoC,
625 int Port,
626 int Addr,
627 SK_U16 Val);
628
629extern void SkXmClrExactAddr(
630 SK_AC *pAC,
631 SK_IOC IoC,
632 int Port,
633 int StartNum,
634 int StopNum);
635
636extern void SkXmAutoNegLipaXmac(
637 SK_AC *pAC,
638 SK_IOC IoC,
639 int Port,
640 SK_U16 IStatus);
641
642extern int SkXmUpdateStats(
643 SK_AC *pAC,
644 SK_IOC IoC,
645 unsigned int Port);
646
647extern int SkGmUpdateStats(
648 SK_AC *pAC,
649 SK_IOC IoC,
650 unsigned int Port);
651
652extern int SkXmMacStatistic(
653 SK_AC *pAC,
654 SK_IOC IoC,
655 unsigned int Port,
656 SK_U16 StatAddr,
657 SK_U32 SK_FAR *pVal);
658
659extern int SkGmMacStatistic(
660 SK_AC *pAC,
661 SK_IOC IoC,
662 unsigned int Port,
663 SK_U16 StatAddr,
664 SK_U32 SK_FAR *pVal);
665
666extern int SkXmResetCounter(
667 SK_AC *pAC,
668 SK_IOC IoC,
669 unsigned int Port);
670
671extern int SkGmResetCounter(
672 SK_AC *pAC,
673 SK_IOC IoC,
674 unsigned int Port);
675
676extern int SkXmOverflowStatus(
677 SK_AC *pAC,
678 SK_IOC IoC,
679 unsigned int Port,
680 SK_U16 IStatus,
681 SK_U64 SK_FAR *pStatus);
682
683extern int SkGmOverflowStatus(
684 SK_AC *pAC,
685 SK_IOC IoC,
686 unsigned int Port,
687 SK_U16 MacStatus,
688 SK_U64 SK_FAR *pStatus);
689
690extern int SkGmCableDiagStatus(
691 SK_AC *pAC,
692 SK_IOC IoC,
693 int Port,
694 SK_BOOL StartTest);
695
696#ifdef SK_DIAG
697extern void SkGePhyRead(
698 SK_AC *pAC,
699 SK_IOC IoC,
700 int Port,
701 int Addr,
702 SK_U16 *pVal);
703
704extern void SkGePhyWrite(
705 SK_AC *pAC,
706 SK_IOC IoC,
707 int Port,
708 int Addr,
709 SK_U16 Val);
710
711extern void SkMacSetRxCmd(
712 SK_AC *pAC,
713 SK_IOC IoC,
714 int Port,
715 int Mode);
716extern void SkMacCrcGener(
717 SK_AC *pAC,
718 SK_IOC IoC,
719 int Port,
720 SK_BOOL Enable);
721extern void SkMacTimeStamp(
722 SK_AC *pAC,
723 SK_IOC IoC,
724 int Port,
725 SK_BOOL Enable);
726extern void SkXmSendCont(
727 SK_AC *pAC,
728 SK_IOC IoC,
729 int Port,
730 SK_BOOL Enable);
731#endif /* SK_DIAG */
732
733#else /* SK_KR_PROTO */
734
735/*
736 * public functions in skgeinit.c
737 */
738extern void SkGePollTxD();
739extern void SkGeYellowLED();
740extern int SkGeCfgSync();
741extern void SkGeLoadLnkSyncCnt();
742extern void SkGeStopPort();
743extern int SkGeInit();
744extern void SkGeDeInit();
745extern int SkGeInitPort();
746extern void SkGeXmitLED();
747extern int SkGeInitAssignRamToQueues();
748
749/*
750 * public functions in skxmac2.c
751 */
752extern void SkMacRxTxDisable();
753extern void SkMacSoftRst();
754extern void SkMacHardRst();
755extern void SkMacInitPhy();
756extern int SkMacRxTxEnable();
757extern void SkMacPromiscMode();
758extern void SkMacHashing();
759extern void SkMacIrqDisable();
760extern void SkMacFlushTxFifo();
761extern void SkMacIrq();
762extern int SkMacAutoNegDone();
763extern void SkMacAutoNegLipaPhy();
764extern void SkXmInitMac();
765extern void SkXmPhyRead();
766extern void SkXmPhyWrite();
767extern void SkGmInitMac();
768extern void SkGmPhyRead();
769extern void SkGmPhyWrite();
770extern void SkXmClrExactAddr();
771extern void SkXmAutoNegLipaXmac();
772extern int SkXmUpdateStats();
773extern int SkGmUpdateStats();
774extern int SkXmMacStatistic();
775extern int SkGmMacStatistic();
776extern int SkXmResetCounter();
777extern int SkGmResetCounter();
778extern int SkXmOverflowStatus();
779extern int SkGmOverflowStatus();
780extern int SkGmCableDiagStatus();
781
782#ifdef SK_DIAG
783extern void SkGePhyRead();
784extern void SkGePhyWrite();
785extern void SkMacSetRxCmd();
786extern void SkMacCrcGener();
787extern void SkMacTimeStamp();
788extern void SkXmSendCont();
789#endif /* SK_DIAG */
790
791#endif /* SK_KR_PROTO */
792
793#ifdef __cplusplus
794}
795#endif /* __cplusplus */
796
797#endif /* __INC_SKGEINIT_H_ */
diff --git a/drivers/net/sk98lin/h/skgepnm2.h b/drivers/net/sk98lin/h/skgepnm2.h
deleted file mode 100644
index ddd304f1a48b..000000000000
--- a/drivers/net/sk98lin/h/skgepnm2.h
+++ /dev/null
@@ -1,334 +0,0 @@
1/*****************************************************************************
2 *
3 * Name: skgepnm2.h
4 * Project: GEnesis, PCI Gigabit Ethernet Adapter
5 * Version: $Revision: 1.36 $
6 * Date: $Date: 2003/05/23 12:45:13 $
7 * Purpose: Defines for Private Network Management Interface
8 *
9 ****************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect GmbH.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25#ifndef _SKGEPNM2_H_
26#define _SKGEPNM2_H_
27
28/*
29 * General definitions
30 */
31#define SK_PNMI_CHIPSET_XMAC 1 /* XMAC11800FP */
32#define SK_PNMI_CHIPSET_YUKON 2 /* YUKON */
33
34#define SK_PNMI_BUS_PCI 1 /* PCI bus*/
35
36/*
37 * Actions
38 */
39#define SK_PNMI_ACT_IDLE 1
40#define SK_PNMI_ACT_RESET 2
41#define SK_PNMI_ACT_SELFTEST 3
42#define SK_PNMI_ACT_RESETCNT 4
43
44/*
45 * VPD releated defines
46 */
47
48#define SK_PNMI_VPD_RW 1
49#define SK_PNMI_VPD_RO 2
50
51#define SK_PNMI_VPD_OK 0
52#define SK_PNMI_VPD_NOTFOUND 1
53#define SK_PNMI_VPD_CUT 2
54#define SK_PNMI_VPD_TIMEOUT 3
55#define SK_PNMI_VPD_FULL 4
56#define SK_PNMI_VPD_NOWRITE 5
57#define SK_PNMI_VPD_FATAL 6
58
59#define SK_PNMI_VPD_IGNORE 0
60#define SK_PNMI_VPD_CREATE 1
61#define SK_PNMI_VPD_DELETE 2
62
63
64/*
65 * RLMT related defines
66 */
67#define SK_PNMI_DEF_RLMT_CHG_THRES 240 /* 4 changes per minute */
68
69
70/*
71 * VCT internal status values
72 */
73#define SK_PNMI_VCT_PENDING 32
74#define SK_PNMI_VCT_TEST_DONE 64
75#define SK_PNMI_VCT_LINK 128
76
77/*
78 * Internal table definitions
79 */
80#define SK_PNMI_GET 0
81#define SK_PNMI_PRESET 1
82#define SK_PNMI_SET 2
83
84#define SK_PNMI_RO 0
85#define SK_PNMI_RW 1
86#define SK_PNMI_WO 2
87
88typedef struct s_OidTabEntry {
89 SK_U32 Id;
90 SK_U32 InstanceNo;
91 unsigned int StructSize;
92 unsigned int Offset;
93 int Access;
94 int (* Func)(SK_AC *pAc, SK_IOC pIo, int action,
95 SK_U32 Id, char* pBuf, unsigned int* pLen,
96 SK_U32 Instance, unsigned int TableIndex,
97 SK_U32 NetNumber);
98 SK_U16 Param;
99} SK_PNMI_TAB_ENTRY;
100
101
102/*
103 * Trap lengths
104 */
105#define SK_PNMI_TRAP_SIMPLE_LEN 17
106#define SK_PNMI_TRAP_SENSOR_LEN_BASE 46
107#define SK_PNMI_TRAP_RLMT_CHANGE_LEN 23
108#define SK_PNMI_TRAP_RLMT_PORT_LEN 23
109
110/*
111 * Number of MAC types supported
112 */
113#define SK_PNMI_MAC_TYPES (SK_MAC_GMAC + 1)
114
115/*
116 * MAC statistic data list (overall set for MAC types used)
117 */
118enum SK_MACSTATS {
119 SK_PNMI_HTX = 0,
120 SK_PNMI_HTX_OCTET,
121 SK_PNMI_HTX_OCTETHIGH = SK_PNMI_HTX_OCTET,
122 SK_PNMI_HTX_OCTETLOW,
123 SK_PNMI_HTX_BROADCAST,
124 SK_PNMI_HTX_MULTICAST,
125 SK_PNMI_HTX_UNICAST,
126 SK_PNMI_HTX_BURST,
127 SK_PNMI_HTX_PMACC,
128 SK_PNMI_HTX_MACC,
129 SK_PNMI_HTX_COL,
130 SK_PNMI_HTX_SINGLE_COL,
131 SK_PNMI_HTX_MULTI_COL,
132 SK_PNMI_HTX_EXCESS_COL,
133 SK_PNMI_HTX_LATE_COL,
134 SK_PNMI_HTX_DEFFERAL,
135 SK_PNMI_HTX_EXCESS_DEF,
136 SK_PNMI_HTX_UNDERRUN,
137 SK_PNMI_HTX_CARRIER,
138 SK_PNMI_HTX_UTILUNDER,
139 SK_PNMI_HTX_UTILOVER,
140 SK_PNMI_HTX_64,
141 SK_PNMI_HTX_127,
142 SK_PNMI_HTX_255,
143 SK_PNMI_HTX_511,
144 SK_PNMI_HTX_1023,
145 SK_PNMI_HTX_MAX,
146 SK_PNMI_HTX_LONGFRAMES,
147 SK_PNMI_HTX_SYNC,
148 SK_PNMI_HTX_SYNC_OCTET,
149 SK_PNMI_HTX_RESERVED,
150
151 SK_PNMI_HRX,
152 SK_PNMI_HRX_OCTET,
153 SK_PNMI_HRX_OCTETHIGH = SK_PNMI_HRX_OCTET,
154 SK_PNMI_HRX_OCTETLOW,
155 SK_PNMI_HRX_BADOCTET,
156 SK_PNMI_HRX_BADOCTETHIGH = SK_PNMI_HRX_BADOCTET,
157 SK_PNMI_HRX_BADOCTETLOW,
158 SK_PNMI_HRX_BROADCAST,
159 SK_PNMI_HRX_MULTICAST,
160 SK_PNMI_HRX_UNICAST,
161 SK_PNMI_HRX_PMACC,
162 SK_PNMI_HRX_MACC,
163 SK_PNMI_HRX_PMACC_ERR,
164 SK_PNMI_HRX_MACC_UNKWN,
165 SK_PNMI_HRX_BURST,
166 SK_PNMI_HRX_MISSED,
167 SK_PNMI_HRX_FRAMING,
168 SK_PNMI_HRX_UNDERSIZE,
169 SK_PNMI_HRX_OVERFLOW,
170 SK_PNMI_HRX_JABBER,
171 SK_PNMI_HRX_CARRIER,
172 SK_PNMI_HRX_IRLENGTH,
173 SK_PNMI_HRX_SYMBOL,
174 SK_PNMI_HRX_SHORTS,
175 SK_PNMI_HRX_RUNT,
176 SK_PNMI_HRX_TOO_LONG,
177 SK_PNMI_HRX_FCS,
178 SK_PNMI_HRX_CEXT,
179 SK_PNMI_HRX_UTILUNDER,
180 SK_PNMI_HRX_UTILOVER,
181 SK_PNMI_HRX_64,
182 SK_PNMI_HRX_127,
183 SK_PNMI_HRX_255,
184 SK_PNMI_HRX_511,
185 SK_PNMI_HRX_1023,
186 SK_PNMI_HRX_MAX,
187 SK_PNMI_HRX_LONGFRAMES,
188
189 SK_PNMI_HRX_RESERVED,
190
191 SK_PNMI_MAX_IDX /* NOTE: Ensure SK_PNMI_CNT_NO is set to this value */
192};
193
194/*
195 * MAC specific data
196 */
197typedef struct s_PnmiStatAddr {
198 SK_U16 Reg; /* MAC register containing the value */
199 SK_BOOL GetOffset; /* TRUE: Offset managed by PNMI (call GetStatVal())*/
200} SK_PNMI_STATADDR;
201
202
203/*
204 * SK_PNMI_STRUCT_DATA copy offset evaluation macros
205 */
206#define SK_PNMI_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_STRUCT_DATA *)0)->e))
207#define SK_PNMI_MAI_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_STRUCT_DATA *)0)->e))
208#define SK_PNMI_VPD_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_VPD *)0)->e))
209#define SK_PNMI_SEN_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_SENSOR *)0)->e))
210#define SK_PNMI_CHK_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_CHECKSUM *)0)->e))
211#define SK_PNMI_STA_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_STAT *)0)->e))
212#define SK_PNMI_CNF_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_CONF *)0)->e))
213#define SK_PNMI_RLM_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_RLMT *)0)->e))
214#define SK_PNMI_MON_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_RLMT_MONITOR *)0)->e))
215#define SK_PNMI_TRP_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_TRAP *)0)->e))
216
217#define SK_PNMI_SET_STAT(b,s,o) {SK_U32 Val32; char *pVal; \
218 Val32 = (s); \
219 pVal = (char *)(b) + ((SK_U32)(SK_UPTR) \
220 &(((SK_PNMI_STRUCT_DATA *)0)-> \
221 ReturnStatus.ErrorStatus)); \
222 SK_PNMI_STORE_U32(pVal, Val32); \
223 Val32 = (o); \
224 pVal = (char *)(b) + ((SK_U32)(SK_UPTR) \
225 &(((SK_PNMI_STRUCT_DATA *)0)-> \
226 ReturnStatus.ErrorOffset)); \
227 SK_PNMI_STORE_U32(pVal, Val32);}
228
229/*
230 * Time macros
231 */
232#ifndef SK_PNMI_HUNDREDS_SEC
233#if SK_TICKS_PER_SEC == 100
234#define SK_PNMI_HUNDREDS_SEC(t) (t)
235#else
236#define SK_PNMI_HUNDREDS_SEC(t) (((t) * 100) / (SK_TICKS_PER_SEC))
237#endif /* !SK_TICKS_PER_SEC */
238#endif /* !SK_PNMI_HUNDREDS_SEC */
239
240/*
241 * Macros to work around alignment problems
242 */
243#ifndef SK_PNMI_STORE_U16
244#define SK_PNMI_STORE_U16(p,v) {*(char *)(p) = *((char *)&(v)); \
245 *((char *)(p) + 1) = \
246 *(((char *)&(v)) + 1);}
247#endif
248
249#ifndef SK_PNMI_STORE_U32
250#define SK_PNMI_STORE_U32(p,v) {*(char *)(p) = *((char *)&(v)); \
251 *((char *)(p) + 1) = \
252 *(((char *)&(v)) + 1); \
253 *((char *)(p) + 2) = \
254 *(((char *)&(v)) + 2); \
255 *((char *)(p) + 3) = \
256 *(((char *)&(v)) + 3);}
257#endif
258
259#ifndef SK_PNMI_STORE_U64
260#define SK_PNMI_STORE_U64(p,v) {*(char *)(p) = *((char *)&(v)); \
261 *((char *)(p) + 1) = \
262 *(((char *)&(v)) + 1); \
263 *((char *)(p) + 2) = \
264 *(((char *)&(v)) + 2); \
265 *((char *)(p) + 3) = \
266 *(((char *)&(v)) + 3); \
267 *((char *)(p) + 4) = \
268 *(((char *)&(v)) + 4); \
269 *((char *)(p) + 5) = \
270 *(((char *)&(v)) + 5); \
271 *((char *)(p) + 6) = \
272 *(((char *)&(v)) + 6); \
273 *((char *)(p) + 7) = \
274 *(((char *)&(v)) + 7);}
275#endif
276
277#ifndef SK_PNMI_READ_U16
278#define SK_PNMI_READ_U16(p,v) {*((char *)&(v)) = *(char *)(p); \
279 *(((char *)&(v)) + 1) = \
280 *((char *)(p) + 1);}
281#endif
282
283#ifndef SK_PNMI_READ_U32
284#define SK_PNMI_READ_U32(p,v) {*((char *)&(v)) = *(char *)(p); \
285 *(((char *)&(v)) + 1) = \
286 *((char *)(p) + 1); \
287 *(((char *)&(v)) + 2) = \
288 *((char *)(p) + 2); \
289 *(((char *)&(v)) + 3) = \
290 *((char *)(p) + 3);}
291#endif
292
293#ifndef SK_PNMI_READ_U64
294#define SK_PNMI_READ_U64(p,v) {*((char *)&(v)) = *(char *)(p); \
295 *(((char *)&(v)) + 1) = \
296 *((char *)(p) + 1); \
297 *(((char *)&(v)) + 2) = \
298 *((char *)(p) + 2); \
299 *(((char *)&(v)) + 3) = \
300 *((char *)(p) + 3); \
301 *(((char *)&(v)) + 4) = \
302 *((char *)(p) + 4); \
303 *(((char *)&(v)) + 5) = \
304 *((char *)(p) + 5); \
305 *(((char *)&(v)) + 6) = \
306 *((char *)(p) + 6); \
307 *(((char *)&(v)) + 7) = \
308 *((char *)(p) + 7);}
309#endif
310
311/*
312 * Macros for Debug
313 */
314#ifdef DEBUG
315
316#define SK_PNMI_CHECKFLAGS(vSt) {if (pAC->Pnmi.MacUpdatedFlag > 0 || \
317 pAC->Pnmi.RlmtUpdatedFlag > 0 || \
318 pAC->Pnmi.SirqUpdatedFlag > 0) { \
319 SK_DBG_MSG(pAC, \
320 SK_DBGMOD_PNMI, \
321 SK_DBGCAT_CTRL, \
322 ("PNMI: ERR: %s MacUFlag=%d, RlmtUFlag=%d, SirqUFlag=%d\n", \
323 vSt, \
324 pAC->Pnmi.MacUpdatedFlag, \
325 pAC->Pnmi.RlmtUpdatedFlag, \
326 pAC->Pnmi.SirqUpdatedFlag))}}
327
328#else /* !DEBUG */
329
330#define SK_PNMI_CHECKFLAGS(vSt) /* Nothing */
331
332#endif /* !DEBUG */
333
334#endif /* _SKGEPNM2_H_ */
diff --git a/drivers/net/sk98lin/h/skgepnmi.h b/drivers/net/sk98lin/h/skgepnmi.h
deleted file mode 100644
index 1ed214ccb253..000000000000
--- a/drivers/net/sk98lin/h/skgepnmi.h
+++ /dev/null
@@ -1,962 +0,0 @@
1/*****************************************************************************
2 *
3 * Name: skgepnmi.h
4 * Project: GEnesis, PCI Gigabit Ethernet Adapter
5 * Version: $Revision: 1.62 $
6 * Date: $Date: 2003/08/15 12:31:52 $
7 * Purpose: Defines for Private Network Management Interface
8 *
9 ****************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect GmbH.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25#ifndef _SKGEPNMI_H_
26#define _SKGEPNMI_H_
27
28/*
29 * Include dependencies
30 */
31#include "h/sktypes.h"
32#include "h/skerror.h"
33#include "h/sktimer.h"
34#include "h/ski2c.h"
35#include "h/skaddr.h"
36#include "h/skrlmt.h"
37#include "h/skvpd.h"
38
39/*
40 * Management Database Version
41 */
42#define SK_PNMI_MDB_VERSION 0x00030001 /* 3.1 */
43
44
45/*
46 * Event definitions
47 */
48#define SK_PNMI_EVT_SIRQ_OVERFLOW 1 /* Counter overflow */
49#define SK_PNMI_EVT_SEN_WAR_LOW 2 /* Lower war thres exceeded */
50#define SK_PNMI_EVT_SEN_WAR_UPP 3 /* Upper war thres exceeded */
51#define SK_PNMI_EVT_SEN_ERR_LOW 4 /* Lower err thres exceeded */
52#define SK_PNMI_EVT_SEN_ERR_UPP 5 /* Upper err thres exceeded */
53#define SK_PNMI_EVT_CHG_EST_TIMER 6 /* Timer event for RLMT Chg */
54#define SK_PNMI_EVT_UTILIZATION_TIMER 7 /* Timer event for Utiliza. */
55#define SK_PNMI_EVT_CLEAR_COUNTER 8 /* Clear statistic counters */
56#define SK_PNMI_EVT_XMAC_RESET 9 /* XMAC will be reset */
57
58#define SK_PNMI_EVT_RLMT_PORT_UP 10 /* Port came logically up */
59#define SK_PNMI_EVT_RLMT_PORT_DOWN 11 /* Port went logically down */
60#define SK_PNMI_EVT_RLMT_SEGMENTATION 13 /* Two SP root bridges found */
61#define SK_PNMI_EVT_RLMT_ACTIVE_DOWN 14 /* Port went logically down */
62#define SK_PNMI_EVT_RLMT_ACTIVE_UP 15 /* Port came logically up */
63#define SK_PNMI_EVT_RLMT_SET_NETS 16 /* 1. Parameter is number of nets
64 1 = single net; 2 = dual net */
65#define SK_PNMI_EVT_VCT_RESET 17 /* VCT port reset timer event started with SET. */
66
67
68/*
69 * Return values
70 */
71#define SK_PNMI_ERR_OK 0
72#define SK_PNMI_ERR_GENERAL 1
73#define SK_PNMI_ERR_TOO_SHORT 2
74#define SK_PNMI_ERR_BAD_VALUE 3
75#define SK_PNMI_ERR_READ_ONLY 4
76#define SK_PNMI_ERR_UNKNOWN_OID 5
77#define SK_PNMI_ERR_UNKNOWN_INST 6
78#define SK_PNMI_ERR_UNKNOWN_NET 7
79#define SK_PNMI_ERR_NOT_SUPPORTED 10
80
81
82/*
83 * Return values of driver reset function SK_DRIVER_RESET() and
84 * driver event function SK_DRIVER_EVENT()
85 */
86#define SK_PNMI_ERR_OK 0
87#define SK_PNMI_ERR_FAIL 1
88
89
90/*
91 * Return values of driver test function SK_DRIVER_SELFTEST()
92 */
93#define SK_PNMI_TST_UNKNOWN (1 << 0)
94#define SK_PNMI_TST_TRANCEIVER (1 << 1)
95#define SK_PNMI_TST_ASIC (1 << 2)
96#define SK_PNMI_TST_SENSOR (1 << 3)
97#define SK_PNMI_TST_POWERMGMT (1 << 4)
98#define SK_PNMI_TST_PCI (1 << 5)
99#define SK_PNMI_TST_MAC (1 << 6)
100
101
102/*
103 * RLMT specific definitions
104 */
105#define SK_PNMI_RLMT_STATUS_STANDBY 1
106#define SK_PNMI_RLMT_STATUS_ACTIVE 2
107#define SK_PNMI_RLMT_STATUS_ERROR 3
108
109#define SK_PNMI_RLMT_LSTAT_PHY_DOWN 1
110#define SK_PNMI_RLMT_LSTAT_AUTONEG 2
111#define SK_PNMI_RLMT_LSTAT_LOG_DOWN 3
112#define SK_PNMI_RLMT_LSTAT_LOG_UP 4
113#define SK_PNMI_RLMT_LSTAT_INDETERMINATED 5
114
115#define SK_PNMI_RLMT_MODE_CHK_LINK (SK_RLMT_CHECK_LINK)
116#define SK_PNMI_RLMT_MODE_CHK_RX (SK_RLMT_CHECK_LOC_LINK)
117#define SK_PNMI_RLMT_MODE_CHK_SPT (SK_RLMT_CHECK_SEG)
118/* #define SK_PNMI_RLMT_MODE_CHK_EX */
119
120/*
121 * OID definition
122 */
123#ifndef _NDIS_ /* Check, whether NDIS already included OIDs */
124
125#define OID_GEN_XMIT_OK 0x00020101
126#define OID_GEN_RCV_OK 0x00020102
127#define OID_GEN_XMIT_ERROR 0x00020103
128#define OID_GEN_RCV_ERROR 0x00020104
129#define OID_GEN_RCV_NO_BUFFER 0x00020105
130
131/* #define OID_GEN_DIRECTED_BYTES_XMIT 0x00020201 */
132#define OID_GEN_DIRECTED_FRAMES_XMIT 0x00020202
133/* #define OID_GEN_MULTICAST_BYTES_XMIT 0x00020203 */
134#define OID_GEN_MULTICAST_FRAMES_XMIT 0x00020204
135/* #define OID_GEN_BROADCAST_BYTES_XMIT 0x00020205 */
136#define OID_GEN_BROADCAST_FRAMES_XMIT 0x00020206
137/* #define OID_GEN_DIRECTED_BYTES_RCV 0x00020207 */
138#define OID_GEN_DIRECTED_FRAMES_RCV 0x00020208
139/* #define OID_GEN_MULTICAST_BYTES_RCV 0x00020209 */
140#define OID_GEN_MULTICAST_FRAMES_RCV 0x0002020A
141/* #define OID_GEN_BROADCAST_BYTES_RCV 0x0002020B */
142#define OID_GEN_BROADCAST_FRAMES_RCV 0x0002020C
143#define OID_GEN_RCV_CRC_ERROR 0x0002020D
144#define OID_GEN_TRANSMIT_QUEUE_LENGTH 0x0002020E
145
146#define OID_802_3_PERMANENT_ADDRESS 0x01010101
147#define OID_802_3_CURRENT_ADDRESS 0x01010102
148/* #define OID_802_3_MULTICAST_LIST 0x01010103 */
149/* #define OID_802_3_MAXIMUM_LIST_SIZE 0x01010104 */
150/* #define OID_802_3_MAC_OPTIONS 0x01010105 */
151
152#define OID_802_3_RCV_ERROR_ALIGNMENT 0x01020101
153#define OID_802_3_XMIT_ONE_COLLISION 0x01020102
154#define OID_802_3_XMIT_MORE_COLLISIONS 0x01020103
155#define OID_802_3_XMIT_DEFERRED 0x01020201
156#define OID_802_3_XMIT_MAX_COLLISIONS 0x01020202
157#define OID_802_3_RCV_OVERRUN 0x01020203
158#define OID_802_3_XMIT_UNDERRUN 0x01020204
159#define OID_802_3_XMIT_TIMES_CRS_LOST 0x01020206
160#define OID_802_3_XMIT_LATE_COLLISIONS 0x01020207
161
162/*
163 * PnP and PM OIDs
164 */
165#ifdef SK_POWER_MGMT
166#define OID_PNP_CAPABILITIES 0xFD010100
167#define OID_PNP_SET_POWER 0xFD010101
168#define OID_PNP_QUERY_POWER 0xFD010102
169#define OID_PNP_ADD_WAKE_UP_PATTERN 0xFD010103
170#define OID_PNP_REMOVE_WAKE_UP_PATTERN 0xFD010104
171#define OID_PNP_ENABLE_WAKE_UP 0xFD010106
172#endif /* SK_POWER_MGMT */
173
174#endif /* _NDIS_ */
175
176#define OID_SKGE_MDB_VERSION 0xFF010100
177#define OID_SKGE_SUPPORTED_LIST 0xFF010101
178#define OID_SKGE_VPD_FREE_BYTES 0xFF010102
179#define OID_SKGE_VPD_ENTRIES_LIST 0xFF010103
180#define OID_SKGE_VPD_ENTRIES_NUMBER 0xFF010104
181#define OID_SKGE_VPD_KEY 0xFF010105
182#define OID_SKGE_VPD_VALUE 0xFF010106
183#define OID_SKGE_VPD_ACCESS 0xFF010107
184#define OID_SKGE_VPD_ACTION 0xFF010108
185
186#define OID_SKGE_PORT_NUMBER 0xFF010110
187#define OID_SKGE_DEVICE_TYPE 0xFF010111
188#define OID_SKGE_DRIVER_DESCR 0xFF010112
189#define OID_SKGE_DRIVER_VERSION 0xFF010113
190#define OID_SKGE_HW_DESCR 0xFF010114
191#define OID_SKGE_HW_VERSION 0xFF010115
192#define OID_SKGE_CHIPSET 0xFF010116
193#define OID_SKGE_ACTION 0xFF010117
194#define OID_SKGE_RESULT 0xFF010118
195#define OID_SKGE_BUS_TYPE 0xFF010119
196#define OID_SKGE_BUS_SPEED 0xFF01011A
197#define OID_SKGE_BUS_WIDTH 0xFF01011B
198/* 0xFF01011C unused */
199#define OID_SKGE_DIAG_ACTION 0xFF01011D
200#define OID_SKGE_DIAG_RESULT 0xFF01011E
201#define OID_SKGE_MTU 0xFF01011F
202#define OID_SKGE_PHYS_CUR_ADDR 0xFF010120
203#define OID_SKGE_PHYS_FAC_ADDR 0xFF010121
204#define OID_SKGE_PMD 0xFF010122
205#define OID_SKGE_CONNECTOR 0xFF010123
206#define OID_SKGE_LINK_CAP 0xFF010124
207#define OID_SKGE_LINK_MODE 0xFF010125
208#define OID_SKGE_LINK_MODE_STATUS 0xFF010126
209#define OID_SKGE_LINK_STATUS 0xFF010127
210#define OID_SKGE_FLOWCTRL_CAP 0xFF010128
211#define OID_SKGE_FLOWCTRL_MODE 0xFF010129
212#define OID_SKGE_FLOWCTRL_STATUS 0xFF01012A
213#define OID_SKGE_PHY_OPERATION_CAP 0xFF01012B
214#define OID_SKGE_PHY_OPERATION_MODE 0xFF01012C
215#define OID_SKGE_PHY_OPERATION_STATUS 0xFF01012D
216#define OID_SKGE_MULTICAST_LIST 0xFF01012E
217#define OID_SKGE_CURRENT_PACKET_FILTER 0xFF01012F
218
219#define OID_SKGE_TRAP 0xFF010130
220#define OID_SKGE_TRAP_NUMBER 0xFF010131
221
222#define OID_SKGE_RLMT_MODE 0xFF010140
223#define OID_SKGE_RLMT_PORT_NUMBER 0xFF010141
224#define OID_SKGE_RLMT_PORT_ACTIVE 0xFF010142
225#define OID_SKGE_RLMT_PORT_PREFERRED 0xFF010143
226#define OID_SKGE_INTERMEDIATE_SUPPORT 0xFF010160
227
228#define OID_SKGE_SPEED_CAP 0xFF010170
229#define OID_SKGE_SPEED_MODE 0xFF010171
230#define OID_SKGE_SPEED_STATUS 0xFF010172
231
232#define OID_SKGE_BOARDLEVEL 0xFF010180
233
234#define OID_SKGE_SENSOR_NUMBER 0xFF020100
235#define OID_SKGE_SENSOR_INDEX 0xFF020101
236#define OID_SKGE_SENSOR_DESCR 0xFF020102
237#define OID_SKGE_SENSOR_TYPE 0xFF020103
238#define OID_SKGE_SENSOR_VALUE 0xFF020104
239#define OID_SKGE_SENSOR_WAR_THRES_LOW 0xFF020105
240#define OID_SKGE_SENSOR_WAR_THRES_UPP 0xFF020106
241#define OID_SKGE_SENSOR_ERR_THRES_LOW 0xFF020107
242#define OID_SKGE_SENSOR_ERR_THRES_UPP 0xFF020108
243#define OID_SKGE_SENSOR_STATUS 0xFF020109
244#define OID_SKGE_SENSOR_WAR_CTS 0xFF02010A
245#define OID_SKGE_SENSOR_ERR_CTS 0xFF02010B
246#define OID_SKGE_SENSOR_WAR_TIME 0xFF02010C
247#define OID_SKGE_SENSOR_ERR_TIME 0xFF02010D
248
249#define OID_SKGE_CHKSM_NUMBER 0xFF020110
250#define OID_SKGE_CHKSM_RX_OK_CTS 0xFF020111
251#define OID_SKGE_CHKSM_RX_UNABLE_CTS 0xFF020112
252#define OID_SKGE_CHKSM_RX_ERR_CTS 0xFF020113
253#define OID_SKGE_CHKSM_TX_OK_CTS 0xFF020114
254#define OID_SKGE_CHKSM_TX_UNABLE_CTS 0xFF020115
255
256#define OID_SKGE_STAT_TX 0xFF020120
257#define OID_SKGE_STAT_TX_OCTETS 0xFF020121
258#define OID_SKGE_STAT_TX_BROADCAST 0xFF020122
259#define OID_SKGE_STAT_TX_MULTICAST 0xFF020123
260#define OID_SKGE_STAT_TX_UNICAST 0xFF020124
261#define OID_SKGE_STAT_TX_LONGFRAMES 0xFF020125
262#define OID_SKGE_STAT_TX_BURST 0xFF020126
263#define OID_SKGE_STAT_TX_PFLOWC 0xFF020127
264#define OID_SKGE_STAT_TX_FLOWC 0xFF020128
265#define OID_SKGE_STAT_TX_SINGLE_COL 0xFF020129
266#define OID_SKGE_STAT_TX_MULTI_COL 0xFF02012A
267#define OID_SKGE_STAT_TX_EXCESS_COL 0xFF02012B
268#define OID_SKGE_STAT_TX_LATE_COL 0xFF02012C
269#define OID_SKGE_STAT_TX_DEFFERAL 0xFF02012D
270#define OID_SKGE_STAT_TX_EXCESS_DEF 0xFF02012E
271#define OID_SKGE_STAT_TX_UNDERRUN 0xFF02012F
272#define OID_SKGE_STAT_TX_CARRIER 0xFF020130
273/* #define OID_SKGE_STAT_TX_UTIL 0xFF020131 */
274#define OID_SKGE_STAT_TX_64 0xFF020132
275#define OID_SKGE_STAT_TX_127 0xFF020133
276#define OID_SKGE_STAT_TX_255 0xFF020134
277#define OID_SKGE_STAT_TX_511 0xFF020135
278#define OID_SKGE_STAT_TX_1023 0xFF020136
279#define OID_SKGE_STAT_TX_MAX 0xFF020137
280#define OID_SKGE_STAT_TX_SYNC 0xFF020138
281#define OID_SKGE_STAT_TX_SYNC_OCTETS 0xFF020139
282#define OID_SKGE_STAT_RX 0xFF02013A
283#define OID_SKGE_STAT_RX_OCTETS 0xFF02013B
284#define OID_SKGE_STAT_RX_BROADCAST 0xFF02013C
285#define OID_SKGE_STAT_RX_MULTICAST 0xFF02013D
286#define OID_SKGE_STAT_RX_UNICAST 0xFF02013E
287#define OID_SKGE_STAT_RX_PFLOWC 0xFF02013F
288#define OID_SKGE_STAT_RX_FLOWC 0xFF020140
289#define OID_SKGE_STAT_RX_PFLOWC_ERR 0xFF020141
290#define OID_SKGE_STAT_RX_FLOWC_UNKWN 0xFF020142
291#define OID_SKGE_STAT_RX_BURST 0xFF020143
292#define OID_SKGE_STAT_RX_MISSED 0xFF020144
293#define OID_SKGE_STAT_RX_FRAMING 0xFF020145
294#define OID_SKGE_STAT_RX_OVERFLOW 0xFF020146
295#define OID_SKGE_STAT_RX_JABBER 0xFF020147
296#define OID_SKGE_STAT_RX_CARRIER 0xFF020148
297#define OID_SKGE_STAT_RX_IR_LENGTH 0xFF020149
298#define OID_SKGE_STAT_RX_SYMBOL 0xFF02014A
299#define OID_SKGE_STAT_RX_SHORTS 0xFF02014B
300#define OID_SKGE_STAT_RX_RUNT 0xFF02014C
301#define OID_SKGE_STAT_RX_CEXT 0xFF02014D
302#define OID_SKGE_STAT_RX_TOO_LONG 0xFF02014E
303#define OID_SKGE_STAT_RX_FCS 0xFF02014F
304/* #define OID_SKGE_STAT_RX_UTIL 0xFF020150 */
305#define OID_SKGE_STAT_RX_64 0xFF020151
306#define OID_SKGE_STAT_RX_127 0xFF020152
307#define OID_SKGE_STAT_RX_255 0xFF020153
308#define OID_SKGE_STAT_RX_511 0xFF020154
309#define OID_SKGE_STAT_RX_1023 0xFF020155
310#define OID_SKGE_STAT_RX_MAX 0xFF020156
311#define OID_SKGE_STAT_RX_LONGFRAMES 0xFF020157
312
313#define OID_SKGE_RLMT_CHANGE_CTS 0xFF020160
314#define OID_SKGE_RLMT_CHANGE_TIME 0xFF020161
315#define OID_SKGE_RLMT_CHANGE_ESTIM 0xFF020162
316#define OID_SKGE_RLMT_CHANGE_THRES 0xFF020163
317
318#define OID_SKGE_RLMT_PORT_INDEX 0xFF020164
319#define OID_SKGE_RLMT_STATUS 0xFF020165
320#define OID_SKGE_RLMT_TX_HELLO_CTS 0xFF020166
321#define OID_SKGE_RLMT_RX_HELLO_CTS 0xFF020167
322#define OID_SKGE_RLMT_TX_SP_REQ_CTS 0xFF020168
323#define OID_SKGE_RLMT_RX_SP_CTS 0xFF020169
324
325#define OID_SKGE_RLMT_MONITOR_NUMBER 0xFF010150
326#define OID_SKGE_RLMT_MONITOR_INDEX 0xFF010151
327#define OID_SKGE_RLMT_MONITOR_ADDR 0xFF010152
328#define OID_SKGE_RLMT_MONITOR_ERRS 0xFF010153
329#define OID_SKGE_RLMT_MONITOR_TIMESTAMP 0xFF010154
330#define OID_SKGE_RLMT_MONITOR_ADMIN 0xFF010155
331
332#define OID_SKGE_TX_SW_QUEUE_LEN 0xFF020170
333#define OID_SKGE_TX_SW_QUEUE_MAX 0xFF020171
334#define OID_SKGE_TX_RETRY 0xFF020172
335#define OID_SKGE_RX_INTR_CTS 0xFF020173
336#define OID_SKGE_TX_INTR_CTS 0xFF020174
337#define OID_SKGE_RX_NO_BUF_CTS 0xFF020175
338#define OID_SKGE_TX_NO_BUF_CTS 0xFF020176
339#define OID_SKGE_TX_USED_DESCR_NO 0xFF020177
340#define OID_SKGE_RX_DELIVERED_CTS 0xFF020178
341#define OID_SKGE_RX_OCTETS_DELIV_CTS 0xFF020179
342#define OID_SKGE_RX_HW_ERROR_CTS 0xFF02017A
343#define OID_SKGE_TX_HW_ERROR_CTS 0xFF02017B
344#define OID_SKGE_IN_ERRORS_CTS 0xFF02017C
345#define OID_SKGE_OUT_ERROR_CTS 0xFF02017D
346#define OID_SKGE_ERR_RECOVERY_CTS 0xFF02017E
347#define OID_SKGE_SYSUPTIME 0xFF02017F
348
349#define OID_SKGE_ALL_DATA 0xFF020190
350
351/* Defines for VCT. */
352#define OID_SKGE_VCT_GET 0xFF020200
353#define OID_SKGE_VCT_SET 0xFF020201
354#define OID_SKGE_VCT_STATUS 0xFF020202
355
356#ifdef SK_DIAG_SUPPORT
357/* Defines for driver DIAG mode. */
358#define OID_SKGE_DIAG_MODE 0xFF020204
359#endif /* SK_DIAG_SUPPORT */
360
361/* New OIDs */
362#define OID_SKGE_DRIVER_RELDATE 0xFF020210
363#define OID_SKGE_DRIVER_FILENAME 0xFF020211
364#define OID_SKGE_CHIPID 0xFF020212
365#define OID_SKGE_RAMSIZE 0xFF020213
366#define OID_SKGE_VAUXAVAIL 0xFF020214
367#define OID_SKGE_PHY_TYPE 0xFF020215
368#define OID_SKGE_PHY_LP_MODE 0xFF020216
369
370/* VCT struct to store a backup copy of VCT data after a port reset. */
371typedef struct s_PnmiVct {
372 SK_U8 VctStatus;
373 SK_U8 PCableLen;
374 SK_U32 PMdiPairLen[4];
375 SK_U8 PMdiPairSts[4];
376} SK_PNMI_VCT;
377
378
379/* VCT status values (to be given to CPA via OID_SKGE_VCT_STATUS). */
380#define SK_PNMI_VCT_NONE 0
381#define SK_PNMI_VCT_OLD_VCT_DATA 1
382#define SK_PNMI_VCT_NEW_VCT_DATA 2
383#define SK_PNMI_VCT_OLD_DSP_DATA 4
384#define SK_PNMI_VCT_NEW_DSP_DATA 8
385#define SK_PNMI_VCT_RUNNING 16
386
387
388/* VCT cable test status. */
389#define SK_PNMI_VCT_NORMAL_CABLE 0
390#define SK_PNMI_VCT_SHORT_CABLE 1
391#define SK_PNMI_VCT_OPEN_CABLE 2
392#define SK_PNMI_VCT_TEST_FAIL 3
393#define SK_PNMI_VCT_IMPEDANCE_MISMATCH 4
394
395#define OID_SKGE_TRAP_SEN_WAR_LOW 500
396#define OID_SKGE_TRAP_SEN_WAR_UPP 501
397#define OID_SKGE_TRAP_SEN_ERR_LOW 502
398#define OID_SKGE_TRAP_SEN_ERR_UPP 503
399#define OID_SKGE_TRAP_RLMT_CHANGE_THRES 520
400#define OID_SKGE_TRAP_RLMT_CHANGE_PORT 521
401#define OID_SKGE_TRAP_RLMT_PORT_DOWN 522
402#define OID_SKGE_TRAP_RLMT_PORT_UP 523
403#define OID_SKGE_TRAP_RLMT_SEGMENTATION 524
404
405#ifdef SK_DIAG_SUPPORT
406/* Defines for driver DIAG mode. */
407#define SK_DIAG_ATTACHED 2
408#define SK_DIAG_RUNNING 1
409#define SK_DIAG_IDLE 0
410#endif /* SK_DIAG_SUPPORT */
411
412/*
413 * Generic PNMI IOCTL subcommand definitions.
414 */
415#define SK_GET_SINGLE_VAR 1
416#define SK_SET_SINGLE_VAR 2
417#define SK_PRESET_SINGLE_VAR 3
418#define SK_GET_FULL_MIB 4
419#define SK_SET_FULL_MIB 5
420#define SK_PRESET_FULL_MIB 6
421
422
423/*
424 * Define error numbers and messages for syslog
425 */
426#define SK_PNMI_ERR001 (SK_ERRBASE_PNMI + 1)
427#define SK_PNMI_ERR001MSG "SkPnmiGetStruct: Unknown OID"
428#define SK_PNMI_ERR002 (SK_ERRBASE_PNMI + 2)
429#define SK_PNMI_ERR002MSG "SkPnmiGetStruct: Cannot read VPD keys"
430#define SK_PNMI_ERR003 (SK_ERRBASE_PNMI + 3)
431#define SK_PNMI_ERR003MSG "OidStruct: Called with wrong OID"
432#define SK_PNMI_ERR004 (SK_ERRBASE_PNMI + 4)
433#define SK_PNMI_ERR004MSG "OidStruct: Called with wrong action"
434#define SK_PNMI_ERR005 (SK_ERRBASE_PNMI + 5)
435#define SK_PNMI_ERR005MSG "Perform: Cannot reset driver"
436#define SK_PNMI_ERR006 (SK_ERRBASE_PNMI + 6)
437#define SK_PNMI_ERR006MSG "Perform: Unknown OID action command"
438#define SK_PNMI_ERR007 (SK_ERRBASE_PNMI + 7)
439#define SK_PNMI_ERR007MSG "General: Driver description not initialized"
440#define SK_PNMI_ERR008 (SK_ERRBASE_PNMI + 8)
441#define SK_PNMI_ERR008MSG "Addr: Tried to get unknown OID"
442#define SK_PNMI_ERR009 (SK_ERRBASE_PNMI + 9)
443#define SK_PNMI_ERR009MSG "Addr: Unknown OID"
444#define SK_PNMI_ERR010 (SK_ERRBASE_PNMI + 10)
445#define SK_PNMI_ERR010MSG "CsumStat: Unknown OID"
446#define SK_PNMI_ERR011 (SK_ERRBASE_PNMI + 11)
447#define SK_PNMI_ERR011MSG "SensorStat: Sensor descr string too long"
448#define SK_PNMI_ERR012 (SK_ERRBASE_PNMI + 12)
449#define SK_PNMI_ERR012MSG "SensorStat: Unknown OID"
450#define SK_PNMI_ERR013 (SK_ERRBASE_PNMI + 13)
451#define SK_PNMI_ERR013MSG ""
452#define SK_PNMI_ERR014 (SK_ERRBASE_PNMI + 14)
453#define SK_PNMI_ERR014MSG "Vpd: Cannot read VPD keys"
454#define SK_PNMI_ERR015 (SK_ERRBASE_PNMI + 15)
455#define SK_PNMI_ERR015MSG "Vpd: Internal array for VPD keys to small"
456#define SK_PNMI_ERR016 (SK_ERRBASE_PNMI + 16)
457#define SK_PNMI_ERR016MSG "Vpd: Key string too long"
458#define SK_PNMI_ERR017 (SK_ERRBASE_PNMI + 17)
459#define SK_PNMI_ERR017MSG "Vpd: Invalid VPD status pointer"
460#define SK_PNMI_ERR018 (SK_ERRBASE_PNMI + 18)
461#define SK_PNMI_ERR018MSG "Vpd: VPD data not valid"
462#define SK_PNMI_ERR019 (SK_ERRBASE_PNMI + 19)
463#define SK_PNMI_ERR019MSG "Vpd: VPD entries list string too long"
464#define SK_PNMI_ERR021 (SK_ERRBASE_PNMI + 21)
465#define SK_PNMI_ERR021MSG "Vpd: VPD data string too long"
466#define SK_PNMI_ERR022 (SK_ERRBASE_PNMI + 22)
467#define SK_PNMI_ERR022MSG "Vpd: VPD data string too long should be errored before"
468#define SK_PNMI_ERR023 (SK_ERRBASE_PNMI + 23)
469#define SK_PNMI_ERR023MSG "Vpd: Unknown OID in get action"
470#define SK_PNMI_ERR024 (SK_ERRBASE_PNMI + 24)
471#define SK_PNMI_ERR024MSG "Vpd: Unknown OID in preset/set action"
472#define SK_PNMI_ERR025 (SK_ERRBASE_PNMI + 25)
473#define SK_PNMI_ERR025MSG "Vpd: Cannot write VPD after modify entry"
474#define SK_PNMI_ERR026 (SK_ERRBASE_PNMI + 26)
475#define SK_PNMI_ERR026MSG "Vpd: Cannot update VPD"
476#define SK_PNMI_ERR027 (SK_ERRBASE_PNMI + 27)
477#define SK_PNMI_ERR027MSG "Vpd: Cannot delete VPD entry"
478#define SK_PNMI_ERR028 (SK_ERRBASE_PNMI + 28)
479#define SK_PNMI_ERR028MSG "Vpd: Cannot update VPD after delete entry"
480#define SK_PNMI_ERR029 (SK_ERRBASE_PNMI + 29)
481#define SK_PNMI_ERR029MSG "General: Driver description string too long"
482#define SK_PNMI_ERR030 (SK_ERRBASE_PNMI + 30)
483#define SK_PNMI_ERR030MSG "General: Driver version not initialized"
484#define SK_PNMI_ERR031 (SK_ERRBASE_PNMI + 31)
485#define SK_PNMI_ERR031MSG "General: Driver version string too long"
486#define SK_PNMI_ERR032 (SK_ERRBASE_PNMI + 32)
487#define SK_PNMI_ERR032MSG "General: Cannot read VPD Name for HW descr"
488#define SK_PNMI_ERR033 (SK_ERRBASE_PNMI + 33)
489#define SK_PNMI_ERR033MSG "General: HW description string too long"
490#define SK_PNMI_ERR034 (SK_ERRBASE_PNMI + 34)
491#define SK_PNMI_ERR034MSG "General: Unknown OID"
492#define SK_PNMI_ERR035 (SK_ERRBASE_PNMI + 35)
493#define SK_PNMI_ERR035MSG "Rlmt: Unknown OID"
494#define SK_PNMI_ERR036 (SK_ERRBASE_PNMI + 36)
495#define SK_PNMI_ERR036MSG ""
496#define SK_PNMI_ERR037 (SK_ERRBASE_PNMI + 37)
497#define SK_PNMI_ERR037MSG "Rlmt: SK_RLMT_MODE_CHANGE event return not 0"
498#define SK_PNMI_ERR038 (SK_ERRBASE_PNMI + 38)
499#define SK_PNMI_ERR038MSG "Rlmt: SK_RLMT_PREFPORT_CHANGE event return not 0"
500#define SK_PNMI_ERR039 (SK_ERRBASE_PNMI + 39)
501#define SK_PNMI_ERR039MSG "RlmtStat: Unknown OID"
502#define SK_PNMI_ERR040 (SK_ERRBASE_PNMI + 40)
503#define SK_PNMI_ERR040MSG "PowerManagement: Unknown OID"
504#define SK_PNMI_ERR041 (SK_ERRBASE_PNMI + 41)
505#define SK_PNMI_ERR041MSG "MacPrivateConf: Unknown OID"
506#define SK_PNMI_ERR042 (SK_ERRBASE_PNMI + 42)
507#define SK_PNMI_ERR042MSG "MacPrivateConf: SK_HWEV_SET_ROLE returned not 0"
508#define SK_PNMI_ERR043 (SK_ERRBASE_PNMI + 43)
509#define SK_PNMI_ERR043MSG "MacPrivateConf: SK_HWEV_SET_LMODE returned not 0"
510#define SK_PNMI_ERR044 (SK_ERRBASE_PNMI + 44)
511#define SK_PNMI_ERR044MSG "MacPrivateConf: SK_HWEV_SET_FLOWMODE returned not 0"
512#define SK_PNMI_ERR045 (SK_ERRBASE_PNMI + 45)
513#define SK_PNMI_ERR045MSG "MacPrivateConf: SK_HWEV_SET_SPEED returned not 0"
514#define SK_PNMI_ERR046 (SK_ERRBASE_PNMI + 46)
515#define SK_PNMI_ERR046MSG "Monitor: Unknown OID"
516#define SK_PNMI_ERR047 (SK_ERRBASE_PNMI + 47)
517#define SK_PNMI_ERR047MSG "SirqUpdate: Event function returns not 0"
518#define SK_PNMI_ERR048 (SK_ERRBASE_PNMI + 48)
519#define SK_PNMI_ERR048MSG "RlmtUpdate: Event function returns not 0"
520#define SK_PNMI_ERR049 (SK_ERRBASE_PNMI + 49)
521#define SK_PNMI_ERR049MSG "SkPnmiInit: Invalid size of 'CounterOffset' struct!!"
522#define SK_PNMI_ERR050 (SK_ERRBASE_PNMI + 50)
523#define SK_PNMI_ERR050MSG "SkPnmiInit: Invalid size of 'StatAddr' table!!"
524#define SK_PNMI_ERR051 (SK_ERRBASE_PNMI + 51)
525#define SK_PNMI_ERR051MSG "SkPnmiEvent: Port switch suspicious"
526#define SK_PNMI_ERR052 (SK_ERRBASE_PNMI + 52)
527#define SK_PNMI_ERR052MSG ""
528#define SK_PNMI_ERR053 (SK_ERRBASE_PNMI + 53)
529#define SK_PNMI_ERR053MSG "General: Driver release date not initialized"
530#define SK_PNMI_ERR054 (SK_ERRBASE_PNMI + 54)
531#define SK_PNMI_ERR054MSG "General: Driver release date string too long"
532#define SK_PNMI_ERR055 (SK_ERRBASE_PNMI + 55)
533#define SK_PNMI_ERR055MSG "General: Driver file name not initialized"
534#define SK_PNMI_ERR056 (SK_ERRBASE_PNMI + 56)
535#define SK_PNMI_ERR056MSG "General: Driver file name string too long"
536
537/*
538 * Management counter macros called by the driver
539 */
540#define SK_PNMI_SET_DRIVER_DESCR(pAC,v) ((pAC)->Pnmi.pDriverDescription = \
541 (char *)(v))
542
543#define SK_PNMI_SET_DRIVER_VER(pAC,v) ((pAC)->Pnmi.pDriverVersion = \
544 (char *)(v))
545
546#define SK_PNMI_SET_DRIVER_RELDATE(pAC,v) ((pAC)->Pnmi.pDriverReleaseDate = \
547 (char *)(v))
548
549#define SK_PNMI_SET_DRIVER_FILENAME(pAC,v) ((pAC)->Pnmi.pDriverFileName = \
550 (char *)(v))
551
552#define SK_PNMI_CNT_TX_QUEUE_LEN(pAC,v,p) \
553 { \
554 (pAC)->Pnmi.Port[p].TxSwQueueLen = (SK_U64)(v); \
555 if ((pAC)->Pnmi.Port[p].TxSwQueueLen > (pAC)->Pnmi.Port[p].TxSwQueueMax) { \
556 (pAC)->Pnmi.Port[p].TxSwQueueMax = (pAC)->Pnmi.Port[p].TxSwQueueLen; \
557 } \
558 }
559#define SK_PNMI_CNT_TX_RETRY(pAC,p) (((pAC)->Pnmi.Port[p].TxRetryCts)++)
560#define SK_PNMI_CNT_RX_INTR(pAC,p) (((pAC)->Pnmi.Port[p].RxIntrCts)++)
561#define SK_PNMI_CNT_TX_INTR(pAC,p) (((pAC)->Pnmi.Port[p].TxIntrCts)++)
562#define SK_PNMI_CNT_NO_RX_BUF(pAC,p) (((pAC)->Pnmi.Port[p].RxNoBufCts)++)
563#define SK_PNMI_CNT_NO_TX_BUF(pAC,p) (((pAC)->Pnmi.Port[p].TxNoBufCts)++)
564#define SK_PNMI_CNT_USED_TX_DESCR(pAC,v,p) \
565 ((pAC)->Pnmi.Port[p].TxUsedDescrNo=(SK_U64)(v));
566#define SK_PNMI_CNT_RX_OCTETS_DELIVERED(pAC,v,p) \
567 { \
568 ((pAC)->Pnmi.Port[p].RxDeliveredCts)++; \
569 (pAC)->Pnmi.Port[p].RxOctetsDeliveredCts += (SK_U64)(v); \
570 }
571#define SK_PNMI_CNT_ERR_RECOVERY(pAC,p) (((pAC)->Pnmi.Port[p].ErrRecoveryCts)++);
572
573#define SK_PNMI_CNT_SYNC_OCTETS(pAC,p,v) \
574 { \
575 if ((p) < SK_MAX_MACS) { \
576 ((pAC)->Pnmi.Port[p].StatSyncCts)++; \
577 (pAC)->Pnmi.Port[p].StatSyncOctetsCts += (SK_U64)(v); \
578 } \
579 }
580
581#define SK_PNMI_CNT_RX_LONGFRAMES(pAC,p) \
582 { \
583 if ((p) < SK_MAX_MACS) { \
584 ((pAC)->Pnmi.Port[p].StatRxLongFrameCts++); \
585 } \
586 }
587
588#define SK_PNMI_CNT_RX_FRAMETOOLONG(pAC,p) \
589 { \
590 if ((p) < SK_MAX_MACS) { \
591 ((pAC)->Pnmi.Port[p].StatRxFrameTooLongCts++); \
592 } \
593 }
594
595#define SK_PNMI_CNT_RX_PMACC_ERR(pAC,p) \
596 { \
597 if ((p) < SK_MAX_MACS) { \
598 ((pAC)->Pnmi.Port[p].StatRxPMaccErr++); \
599 } \
600 }
601
602/*
603 * Conversion Macros
604 */
605#define SK_PNMI_PORT_INST2LOG(i) ((unsigned int)(i) - 1)
606#define SK_PNMI_PORT_LOG2INST(l) ((unsigned int)(l) + 1)
607#define SK_PNMI_PORT_PHYS2LOG(p) ((unsigned int)(p) + 1)
608#define SK_PNMI_PORT_LOG2PHYS(pAC,l) ((unsigned int)(l) - 1)
609#define SK_PNMI_PORT_PHYS2INST(pAC,p) \
610 (pAC->Pnmi.DualNetActiveFlag ? 2 : ((unsigned int)(p) + 2))
611#define SK_PNMI_PORT_INST2PHYS(pAC,i) ((unsigned int)(i) - 2)
612
613/*
614 * Structure definition for SkPnmiGetStruct and SkPnmiSetStruct
615 */
616#define SK_PNMI_VPD_KEY_SIZE 5
617#define SK_PNMI_VPD_BUFSIZE (VPD_SIZE)
618#define SK_PNMI_VPD_ENTRIES (VPD_SIZE / 4)
619#define SK_PNMI_VPD_DATALEN 128 /* Number of data bytes */
620
621#define SK_PNMI_MULTICAST_LISTLEN 64
622#define SK_PNMI_SENSOR_ENTRIES (SK_MAX_SENSORS)
623#define SK_PNMI_CHECKSUM_ENTRIES 3
624#define SK_PNMI_MAC_ENTRIES (SK_MAX_MACS + 1)
625#define SK_PNMI_MONITOR_ENTRIES 20
626#define SK_PNMI_TRAP_ENTRIES 10
627#define SK_PNMI_TRAPLEN 128
628#define SK_PNMI_STRINGLEN1 80
629#define SK_PNMI_STRINGLEN2 25
630#define SK_PNMI_TRAP_QUEUE_LEN 512
631
632typedef struct s_PnmiVpd {
633 char VpdKey[SK_PNMI_VPD_KEY_SIZE];
634 char VpdValue[SK_PNMI_VPD_DATALEN];
635 SK_U8 VpdAccess;
636 SK_U8 VpdAction;
637} SK_PNMI_VPD;
638
639typedef struct s_PnmiSensor {
640 SK_U8 SensorIndex;
641 char SensorDescr[SK_PNMI_STRINGLEN2];
642 SK_U8 SensorType;
643 SK_U32 SensorValue;
644 SK_U32 SensorWarningThresholdLow;
645 SK_U32 SensorWarningThresholdHigh;
646 SK_U32 SensorErrorThresholdLow;
647 SK_U32 SensorErrorThresholdHigh;
648 SK_U8 SensorStatus;
649 SK_U64 SensorWarningCts;
650 SK_U64 SensorErrorCts;
651 SK_U64 SensorWarningTimestamp;
652 SK_U64 SensorErrorTimestamp;
653} SK_PNMI_SENSOR;
654
655typedef struct s_PnmiChecksum {
656 SK_U64 ChecksumRxOkCts;
657 SK_U64 ChecksumRxUnableCts;
658 SK_U64 ChecksumRxErrCts;
659 SK_U64 ChecksumTxOkCts;
660 SK_U64 ChecksumTxUnableCts;
661} SK_PNMI_CHECKSUM;
662
663typedef struct s_PnmiStat {
664 SK_U64 StatTxOkCts;
665 SK_U64 StatTxOctetsOkCts;
666 SK_U64 StatTxBroadcastOkCts;
667 SK_U64 StatTxMulticastOkCts;
668 SK_U64 StatTxUnicastOkCts;
669 SK_U64 StatTxLongFramesCts;
670 SK_U64 StatTxBurstCts;
671 SK_U64 StatTxPauseMacCtrlCts;
672 SK_U64 StatTxMacCtrlCts;
673 SK_U64 StatTxSingleCollisionCts;
674 SK_U64 StatTxMultipleCollisionCts;
675 SK_U64 StatTxExcessiveCollisionCts;
676 SK_U64 StatTxLateCollisionCts;
677 SK_U64 StatTxDeferralCts;
678 SK_U64 StatTxExcessiveDeferralCts;
679 SK_U64 StatTxFifoUnderrunCts;
680 SK_U64 StatTxCarrierCts;
681 SK_U64 Dummy1; /* StatTxUtilization */
682 SK_U64 StatTx64Cts;
683 SK_U64 StatTx127Cts;
684 SK_U64 StatTx255Cts;
685 SK_U64 StatTx511Cts;
686 SK_U64 StatTx1023Cts;
687 SK_U64 StatTxMaxCts;
688 SK_U64 StatTxSyncCts;
689 SK_U64 StatTxSyncOctetsCts;
690 SK_U64 StatRxOkCts;
691 SK_U64 StatRxOctetsOkCts;
692 SK_U64 StatRxBroadcastOkCts;
693 SK_U64 StatRxMulticastOkCts;
694 SK_U64 StatRxUnicastOkCts;
695 SK_U64 StatRxLongFramesCts;
696 SK_U64 StatRxPauseMacCtrlCts;
697 SK_U64 StatRxMacCtrlCts;
698 SK_U64 StatRxPauseMacCtrlErrorCts;
699 SK_U64 StatRxMacCtrlUnknownCts;
700 SK_U64 StatRxBurstCts;
701 SK_U64 StatRxMissedCts;
702 SK_U64 StatRxFramingCts;
703 SK_U64 StatRxFifoOverflowCts;
704 SK_U64 StatRxJabberCts;
705 SK_U64 StatRxCarrierCts;
706 SK_U64 StatRxIRLengthCts;
707 SK_U64 StatRxSymbolCts;
708 SK_U64 StatRxShortsCts;
709 SK_U64 StatRxRuntCts;
710 SK_U64 StatRxCextCts;
711 SK_U64 StatRxTooLongCts;
712 SK_U64 StatRxFcsCts;
713 SK_U64 Dummy2; /* StatRxUtilization */
714 SK_U64 StatRx64Cts;
715 SK_U64 StatRx127Cts;
716 SK_U64 StatRx255Cts;
717 SK_U64 StatRx511Cts;
718 SK_U64 StatRx1023Cts;
719 SK_U64 StatRxMaxCts;
720} SK_PNMI_STAT;
721
722typedef struct s_PnmiConf {
723 char ConfMacCurrentAddr[6];
724 char ConfMacFactoryAddr[6];
725 SK_U8 ConfPMD;
726 SK_U8 ConfConnector;
727 SK_U32 ConfPhyType;
728 SK_U32 ConfPhyMode;
729 SK_U8 ConfLinkCapability;
730 SK_U8 ConfLinkMode;
731 SK_U8 ConfLinkModeStatus;
732 SK_U8 ConfLinkStatus;
733 SK_U8 ConfFlowCtrlCapability;
734 SK_U8 ConfFlowCtrlMode;
735 SK_U8 ConfFlowCtrlStatus;
736 SK_U8 ConfPhyOperationCapability;
737 SK_U8 ConfPhyOperationMode;
738 SK_U8 ConfPhyOperationStatus;
739 SK_U8 ConfSpeedCapability;
740 SK_U8 ConfSpeedMode;
741 SK_U8 ConfSpeedStatus;
742} SK_PNMI_CONF;
743
744typedef struct s_PnmiRlmt {
745 SK_U32 RlmtIndex;
746 SK_U32 RlmtStatus;
747 SK_U64 RlmtTxHelloCts;
748 SK_U64 RlmtRxHelloCts;
749 SK_U64 RlmtTxSpHelloReqCts;
750 SK_U64 RlmtRxSpHelloCts;
751} SK_PNMI_RLMT;
752
753typedef struct s_PnmiRlmtMonitor {
754 SK_U32 RlmtMonitorIndex;
755 char RlmtMonitorAddr[6];
756 SK_U64 RlmtMonitorErrorCts;
757 SK_U64 RlmtMonitorTimestamp;
758 SK_U8 RlmtMonitorAdmin;
759} SK_PNMI_RLMT_MONITOR;
760
761typedef struct s_PnmiRequestStatus {
762 SK_U32 ErrorStatus;
763 SK_U32 ErrorOffset;
764} SK_PNMI_REQUEST_STATUS;
765
766typedef struct s_PnmiStrucData {
767 SK_U32 MgmtDBVersion;
768 SK_PNMI_REQUEST_STATUS ReturnStatus;
769 SK_U32 VpdFreeBytes;
770 char VpdEntriesList[SK_PNMI_VPD_ENTRIES * SK_PNMI_VPD_KEY_SIZE];
771 SK_U32 VpdEntriesNumber;
772 SK_PNMI_VPD Vpd[SK_PNMI_VPD_ENTRIES];
773 SK_U32 PortNumber;
774 SK_U32 DeviceType;
775 char DriverDescr[SK_PNMI_STRINGLEN1];
776 char DriverVersion[SK_PNMI_STRINGLEN2];
777 char DriverReleaseDate[SK_PNMI_STRINGLEN1];
778 char DriverFileName[SK_PNMI_STRINGLEN1];
779 char HwDescr[SK_PNMI_STRINGLEN1];
780 char HwVersion[SK_PNMI_STRINGLEN2];
781 SK_U16 Chipset;
782 SK_U32 ChipId;
783 SK_U8 VauxAvail;
784 SK_U32 RamSize;
785 SK_U32 MtuSize;
786 SK_U32 Action;
787 SK_U32 TestResult;
788 SK_U8 BusType;
789 SK_U8 BusSpeed;
790 SK_U8 BusWidth;
791 SK_U8 SensorNumber;
792 SK_PNMI_SENSOR Sensor[SK_PNMI_SENSOR_ENTRIES];
793 SK_U8 ChecksumNumber;
794 SK_PNMI_CHECKSUM Checksum[SK_PNMI_CHECKSUM_ENTRIES];
795 SK_PNMI_STAT Stat[SK_PNMI_MAC_ENTRIES];
796 SK_PNMI_CONF Conf[SK_PNMI_MAC_ENTRIES];
797 SK_U8 RlmtMode;
798 SK_U32 RlmtPortNumber;
799 SK_U8 RlmtPortActive;
800 SK_U8 RlmtPortPreferred;
801 SK_U64 RlmtChangeCts;
802 SK_U64 RlmtChangeTime;
803 SK_U64 RlmtChangeEstimate;
804 SK_U64 RlmtChangeThreshold;
805 SK_PNMI_RLMT Rlmt[SK_MAX_MACS];
806 SK_U32 RlmtMonitorNumber;
807 SK_PNMI_RLMT_MONITOR RlmtMonitor[SK_PNMI_MONITOR_ENTRIES];
808 SK_U32 TrapNumber;
809 SK_U8 Trap[SK_PNMI_TRAP_QUEUE_LEN];
810 SK_U64 TxSwQueueLen;
811 SK_U64 TxSwQueueMax;
812 SK_U64 TxRetryCts;
813 SK_U64 RxIntrCts;
814 SK_U64 TxIntrCts;
815 SK_U64 RxNoBufCts;
816 SK_U64 TxNoBufCts;
817 SK_U64 TxUsedDescrNo;
818 SK_U64 RxDeliveredCts;
819 SK_U64 RxOctetsDeliveredCts;
820 SK_U64 RxHwErrorsCts;
821 SK_U64 TxHwErrorsCts;
822 SK_U64 InErrorsCts;
823 SK_U64 OutErrorsCts;
824 SK_U64 ErrRecoveryCts;
825 SK_U64 SysUpTime;
826} SK_PNMI_STRUCT_DATA;
827
828#define SK_PNMI_STRUCT_SIZE (sizeof(SK_PNMI_STRUCT_DATA))
829#define SK_PNMI_MIN_STRUCT_SIZE ((unsigned int)(SK_UPTR)\
830 &(((SK_PNMI_STRUCT_DATA *)0)->VpdFreeBytes))
831 /*
832 * ReturnStatus field
833 * must be located
834 * before VpdFreeBytes
835 */
836
837/*
838 * Various definitions
839 */
840#define SK_PNMI_MAX_PROTOS 3
841
842#define SK_PNMI_CNT_NO 66 /* Must have the value of the enum
843 * SK_PNMI_MAX_IDX. Define SK_PNMI_CHECK
844 * for check while init phase 1
845 */
846
847/*
848 * Estimate data structure
849 */
850typedef struct s_PnmiEstimate {
851 unsigned int EstValueIndex;
852 SK_U64 EstValue[7];
853 SK_U64 Estimate;
854 SK_TIMER EstTimer;
855} SK_PNMI_ESTIMATE;
856
857
858/*
859 * VCT timer data structure
860 */
861typedef struct s_VctTimer {
862 SK_TIMER VctTimer;
863} SK_PNMI_VCT_TIMER;
864
865
866/*
867 * PNMI specific adapter context structure
868 */
869typedef struct s_PnmiPort {
870 SK_U64 StatSyncCts;
871 SK_U64 StatSyncOctetsCts;
872 SK_U64 StatRxLongFrameCts;
873 SK_U64 StatRxFrameTooLongCts;
874 SK_U64 StatRxPMaccErr;
875 SK_U64 TxSwQueueLen;
876 SK_U64 TxSwQueueMax;
877 SK_U64 TxRetryCts;
878 SK_U64 RxIntrCts;
879 SK_U64 TxIntrCts;
880 SK_U64 RxNoBufCts;
881 SK_U64 TxNoBufCts;
882 SK_U64 TxUsedDescrNo;
883 SK_U64 RxDeliveredCts;
884 SK_U64 RxOctetsDeliveredCts;
885 SK_U64 RxHwErrorsCts;
886 SK_U64 TxHwErrorsCts;
887 SK_U64 InErrorsCts;
888 SK_U64 OutErrorsCts;
889 SK_U64 ErrRecoveryCts;
890 SK_U64 RxShortZeroMark;
891 SK_U64 CounterOffset[SK_PNMI_CNT_NO];
892 SK_U32 CounterHigh[SK_PNMI_CNT_NO];
893 SK_BOOL ActiveFlag;
894 SK_U8 Align[3];
895} SK_PNMI_PORT;
896
897
898typedef struct s_PnmiData {
899 SK_PNMI_PORT Port [SK_MAX_MACS];
900 SK_PNMI_PORT BufPort [SK_MAX_MACS]; /* 2002-09-13 pweber */
901 SK_U64 VirtualCounterOffset[SK_PNMI_CNT_NO];
902 SK_U32 TestResult;
903 char HwVersion[10];
904 SK_U16 Align01;
905
906 char *pDriverDescription;
907 char *pDriverVersion;
908 char *pDriverReleaseDate;
909 char *pDriverFileName;
910
911 int MacUpdatedFlag;
912 int RlmtUpdatedFlag;
913 int SirqUpdatedFlag;
914
915 SK_U64 RlmtChangeCts;
916 SK_U64 RlmtChangeTime;
917 SK_PNMI_ESTIMATE RlmtChangeEstimate;
918 SK_U64 RlmtChangeThreshold;
919
920 SK_U64 StartUpTime;
921 SK_U32 DeviceType;
922 char PciBusSpeed;
923 char PciBusWidth;
924 char Chipset;
925 char PMD;
926 char Connector;
927 SK_BOOL DualNetActiveFlag;
928 SK_U16 Align02;
929
930 char TrapBuf[SK_PNMI_TRAP_QUEUE_LEN];
931 unsigned int TrapBufFree;
932 unsigned int TrapQueueBeg;
933 unsigned int TrapQueueEnd;
934 unsigned int TrapBufPad;
935 unsigned int TrapUnique;
936 SK_U8 VctStatus[SK_MAX_MACS];
937 SK_PNMI_VCT VctBackup[SK_MAX_MACS];
938 SK_PNMI_VCT_TIMER VctTimeout[SK_MAX_MACS];
939#ifdef SK_DIAG_SUPPORT
940 SK_U32 DiagAttached;
941#endif /* SK_DIAG_SUPPORT */
942} SK_PNMI;
943
944
945/*
946 * Function prototypes
947 */
948extern int SkPnmiInit(SK_AC *pAC, SK_IOC IoC, int Level);
949extern int SkPnmiSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void* pBuf,
950 unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
951extern int SkPnmiGetStruct(SK_AC *pAC, SK_IOC IoC, void* pBuf,
952 unsigned int *pLen, SK_U32 NetIndex);
953extern int SkPnmiPreSetStruct(SK_AC *pAC, SK_IOC IoC, void* pBuf,
954 unsigned int *pLen, SK_U32 NetIndex);
955extern int SkPnmiSetStruct(SK_AC *pAC, SK_IOC IoC, void* pBuf,
956 unsigned int *pLen, SK_U32 NetIndex);
957extern int SkPnmiEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event,
958 SK_EVPARA Param);
959extern int SkPnmiGenIoctl(SK_AC *pAC, SK_IOC IoC, void * pBuf,
960 unsigned int * pLen, SK_U32 NetIndex);
961
962#endif
diff --git a/drivers/net/sk98lin/h/skgesirq.h b/drivers/net/sk98lin/h/skgesirq.h
deleted file mode 100644
index 3eec6274e413..000000000000
--- a/drivers/net/sk98lin/h/skgesirq.h
+++ /dev/null
@@ -1,110 +0,0 @@
1/******************************************************************************
2 *
3 * Name: skgesirq.h
4 * Project: Gigabit Ethernet Adapters, Common Modules
5 * Version: $Revision: 1.30 $
6 * Date: $Date: 2003/07/04 12:34:13 $
7 * Purpose: SK specific Gigabit Ethernet special IRQ functions
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25#ifndef _INC_SKGESIRQ_H_
26#define _INC_SKGESIRQ_H_
27
28/* Define return codes of SkGePortCheckUp and CheckShort */
29#define SK_HW_PS_NONE 0 /* No action needed */
30#define SK_HW_PS_RESTART 1 /* Restart needed */
31#define SK_HW_PS_LINK 2 /* Link Up actions needed */
32
33/*
34 * Define the Event the special IRQ/INI module can handle
35 */
36#define SK_HWEV_WATIM 1 /* Timeout for WA Errata #2 XMAC */
37#define SK_HWEV_PORT_START 2 /* Port Start Event by RLMT */
38#define SK_HWEV_PORT_STOP 3 /* Port Stop Event by RLMT */
39#define SK_HWEV_CLEAR_STAT 4 /* Clear Statistics by PNMI */
40#define SK_HWEV_UPDATE_STAT 5 /* Update Statistics by PNMI */
41#define SK_HWEV_SET_LMODE 6 /* Set Link Mode by PNMI */
42#define SK_HWEV_SET_FLOWMODE 7 /* Set Flow Control Mode by PNMI */
43#define SK_HWEV_SET_ROLE 8 /* Set Master/Slave (Role) by PNMI */
44#define SK_HWEV_SET_SPEED 9 /* Set Link Speed by PNMI */
45#define SK_HWEV_HALFDUP_CHK 10 /* Half Duplex Hangup Workaround */
46
47#define SK_WA_ACT_TIME (5000000UL) /* 5 sec */
48#define SK_WA_INA_TIME (100000UL) /* 100 msec */
49
50#define SK_HALFDUP_CHK_TIME (10000UL) /* 10 msec */
51
52/*
53 * Define the error numbers and messages
54 */
55#define SKERR_SIRQ_E001 (SK_ERRBASE_SIRQ+0)
56#define SKERR_SIRQ_E001MSG "Unknown event"
57#define SKERR_SIRQ_E002 (SKERR_SIRQ_E001+1)
58#define SKERR_SIRQ_E002MSG "Packet timeout RX1"
59#define SKERR_SIRQ_E003 (SKERR_SIRQ_E002+1)
60#define SKERR_SIRQ_E003MSG "Packet timeout RX2"
61#define SKERR_SIRQ_E004 (SKERR_SIRQ_E003+1)
62#define SKERR_SIRQ_E004MSG "MAC 1 not correctly initialized"
63#define SKERR_SIRQ_E005 (SKERR_SIRQ_E004+1)
64#define SKERR_SIRQ_E005MSG "MAC 2 not correctly initialized"
65#define SKERR_SIRQ_E006 (SKERR_SIRQ_E005+1)
66#define SKERR_SIRQ_E006MSG "CHECK failure R1"
67#define SKERR_SIRQ_E007 (SKERR_SIRQ_E006+1)
68#define SKERR_SIRQ_E007MSG "CHECK failure R2"
69#define SKERR_SIRQ_E008 (SKERR_SIRQ_E007+1)
70#define SKERR_SIRQ_E008MSG "CHECK failure XS1"
71#define SKERR_SIRQ_E009 (SKERR_SIRQ_E008+1)
72#define SKERR_SIRQ_E009MSG "CHECK failure XA1"
73#define SKERR_SIRQ_E010 (SKERR_SIRQ_E009+1)
74#define SKERR_SIRQ_E010MSG "CHECK failure XS2"
75#define SKERR_SIRQ_E011 (SKERR_SIRQ_E010+1)
76#define SKERR_SIRQ_E011MSG "CHECK failure XA2"
77#define SKERR_SIRQ_E012 (SKERR_SIRQ_E011+1)
78#define SKERR_SIRQ_E012MSG "unexpected IRQ Master error"
79#define SKERR_SIRQ_E013 (SKERR_SIRQ_E012+1)
80#define SKERR_SIRQ_E013MSG "unexpected IRQ Status error"
81#define SKERR_SIRQ_E014 (SKERR_SIRQ_E013+1)
82#define SKERR_SIRQ_E014MSG "Parity error on RAM (read)"
83#define SKERR_SIRQ_E015 (SKERR_SIRQ_E014+1)
84#define SKERR_SIRQ_E015MSG "Parity error on RAM (write)"
85#define SKERR_SIRQ_E016 (SKERR_SIRQ_E015+1)
86#define SKERR_SIRQ_E016MSG "Parity error MAC 1"
87#define SKERR_SIRQ_E017 (SKERR_SIRQ_E016+1)
88#define SKERR_SIRQ_E017MSG "Parity error MAC 2"
89#define SKERR_SIRQ_E018 (SKERR_SIRQ_E017+1)
90#define SKERR_SIRQ_E018MSG "Parity error RX 1"
91#define SKERR_SIRQ_E019 (SKERR_SIRQ_E018+1)
92#define SKERR_SIRQ_E019MSG "Parity error RX 2"
93#define SKERR_SIRQ_E020 (SKERR_SIRQ_E019+1)
94#define SKERR_SIRQ_E020MSG "MAC transmit FIFO underrun"
95#define SKERR_SIRQ_E021 (SKERR_SIRQ_E020+1)
96#define SKERR_SIRQ_E021MSG "Spurious TWSI interrupt"
97#define SKERR_SIRQ_E022 (SKERR_SIRQ_E021+1)
98#define SKERR_SIRQ_E022MSG "Cable pair swap error"
99#define SKERR_SIRQ_E023 (SKERR_SIRQ_E022+1)
100#define SKERR_SIRQ_E023MSG "Auto-negotiation error"
101#define SKERR_SIRQ_E024 (SKERR_SIRQ_E023+1)
102#define SKERR_SIRQ_E024MSG "FIFO overflow error"
103#define SKERR_SIRQ_E025 (SKERR_SIRQ_E024+1)
104#define SKERR_SIRQ_E025MSG "2 Pair Downshift detected"
105
106extern void SkGeSirqIsr(SK_AC *pAC, SK_IOC IoC, SK_U32 Istatus);
107extern int SkGeSirqEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, SK_EVPARA Para);
108extern void SkHWLinkDown(SK_AC *pAC, SK_IOC IoC, int Port);
109
110#endif /* _INC_SKGESIRQ_H_ */
diff --git a/drivers/net/sk98lin/h/ski2c.h b/drivers/net/sk98lin/h/ski2c.h
deleted file mode 100644
index 6a63f4a15de6..000000000000
--- a/drivers/net/sk98lin/h/ski2c.h
+++ /dev/null
@@ -1,174 +0,0 @@
1/******************************************************************************
2 *
3 * Name: ski2c.h
4 * Project: Gigabit Ethernet Adapters, TWSI-Module
5 * Version: $Revision: 1.35 $
6 * Date: $Date: 2003/10/20 09:06:30 $
7 * Purpose: Defines to access Voltage and Temperature Sensor
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25/*
26 * SKI2C.H contains all I2C specific defines
27 */
28
29#ifndef _SKI2C_H_
30#define _SKI2C_H_
31
32typedef struct s_Sensor SK_SENSOR;
33
34#include "h/skgei2c.h"
35
36/*
37 * Define the I2C events.
38 */
39#define SK_I2CEV_IRQ 1 /* IRQ happened Event */
40#define SK_I2CEV_TIM 2 /* Timeout event */
41#define SK_I2CEV_CLEAR 3 /* Clear MIB Values */
42
43/*
44 * Define READ and WRITE Constants.
45 */
46#define I2C_READ 0
47#define I2C_WRITE 1
48#define I2C_BURST 1
49#define I2C_SINGLE 0
50
51#define SKERR_I2C_E001 (SK_ERRBASE_I2C+0)
52#define SKERR_I2C_E001MSG "Sensor index unknown"
53#define SKERR_I2C_E002 (SKERR_I2C_E001+1)
54#define SKERR_I2C_E002MSG "TWSI: transfer does not complete"
55#define SKERR_I2C_E003 (SKERR_I2C_E002+1)
56#define SKERR_I2C_E003MSG "LM80: NAK on device send"
57#define SKERR_I2C_E004 (SKERR_I2C_E003+1)
58#define SKERR_I2C_E004MSG "LM80: NAK on register send"
59#define SKERR_I2C_E005 (SKERR_I2C_E004+1)
60#define SKERR_I2C_E005MSG "LM80: NAK on device (2) send"
61#define SKERR_I2C_E006 (SKERR_I2C_E005+1)
62#define SKERR_I2C_E006MSG "Unknown event"
63#define SKERR_I2C_E007 (SKERR_I2C_E006+1)
64#define SKERR_I2C_E007MSG "LM80 read out of state"
65#define SKERR_I2C_E008 (SKERR_I2C_E007+1)
66#define SKERR_I2C_E008MSG "Unexpected sensor read completed"
67#define SKERR_I2C_E009 (SKERR_I2C_E008+1)
68#define SKERR_I2C_E009MSG "WARNING: temperature sensor out of range"
69#define SKERR_I2C_E010 (SKERR_I2C_E009+1)
70#define SKERR_I2C_E010MSG "WARNING: voltage sensor out of range"
71#define SKERR_I2C_E011 (SKERR_I2C_E010+1)
72#define SKERR_I2C_E011MSG "ERROR: temperature sensor out of range"
73#define SKERR_I2C_E012 (SKERR_I2C_E011+1)
74#define SKERR_I2C_E012MSG "ERROR: voltage sensor out of range"
75#define SKERR_I2C_E013 (SKERR_I2C_E012+1)
76#define SKERR_I2C_E013MSG "ERROR: couldn't init sensor"
77#define SKERR_I2C_E014 (SKERR_I2C_E013+1)
78#define SKERR_I2C_E014MSG "WARNING: fan sensor out of range"
79#define SKERR_I2C_E015 (SKERR_I2C_E014+1)
80#define SKERR_I2C_E015MSG "ERROR: fan sensor out of range"
81#define SKERR_I2C_E016 (SKERR_I2C_E015+1)
82#define SKERR_I2C_E016MSG "TWSI: active transfer does not complete"
83
84/*
85 * Define Timeout values
86 */
87#define SK_I2C_TIM_LONG 2000000L /* 2 seconds */
88#define SK_I2C_TIM_SHORT 100000L /* 100 milliseconds */
89#define SK_I2C_TIM_WATCH 1000000L /* 1 second */
90
91/*
92 * Define trap and error log hold times
93 */
94#ifndef SK_SEN_ERR_TR_HOLD
95#define SK_SEN_ERR_TR_HOLD (4*SK_TICKS_PER_SEC)
96#endif
97#ifndef SK_SEN_ERR_LOG_HOLD
98#define SK_SEN_ERR_LOG_HOLD (60*SK_TICKS_PER_SEC)
99#endif
100#ifndef SK_SEN_WARN_TR_HOLD
101#define SK_SEN_WARN_TR_HOLD (15*SK_TICKS_PER_SEC)
102#endif
103#ifndef SK_SEN_WARN_LOG_HOLD
104#define SK_SEN_WARN_LOG_HOLD (15*60*SK_TICKS_PER_SEC)
105#endif
106
107/*
108 * Defines for SenType
109 */
110#define SK_SEN_UNKNOWN 0
111#define SK_SEN_TEMP 1
112#define SK_SEN_VOLT 2
113#define SK_SEN_FAN 3
114
115/*
116 * Define for the SenErrorFlag
117 */
118#define SK_SEN_ERR_NOT_PRESENT 0 /* Error Flag: Sensor not present */
119#define SK_SEN_ERR_OK 1 /* Error Flag: O.K. */
120#define SK_SEN_ERR_WARN 2 /* Error Flag: Warning */
121#define SK_SEN_ERR_ERR 3 /* Error Flag: Error */
122#define SK_SEN_ERR_FAULTY 4 /* Error Flag: Faulty */
123
124/*
125 * Define the Sensor struct
126 */
127struct s_Sensor {
128 char *SenDesc; /* Description */
129 int SenType; /* Voltage or Temperature */
130 SK_I32 SenValue; /* Current value of the sensor */
131 SK_I32 SenThreErrHigh; /* High error Threshhold of this sensor */
132 SK_I32 SenThreWarnHigh; /* High warning Threshhold of this sensor */
133 SK_I32 SenThreErrLow; /* Lower error Threshold of the sensor */
134 SK_I32 SenThreWarnLow; /* Lower warning Threshold of the sensor */
135 int SenErrFlag; /* Sensor indicated an error */
136 SK_BOOL SenInit; /* Is sensor initialized ? */
137 SK_U64 SenErrCts; /* Error trap counter */
138 SK_U64 SenWarnCts; /* Warning trap counter */
139 SK_U64 SenBegErrTS; /* Begin error timestamp */
140 SK_U64 SenBegWarnTS; /* Begin warning timestamp */
141 SK_U64 SenLastErrTrapTS; /* Last error trap timestamp */
142 SK_U64 SenLastErrLogTS; /* Last error log timestamp */
143 SK_U64 SenLastWarnTrapTS; /* Last warning trap timestamp */
144 SK_U64 SenLastWarnLogTS; /* Last warning log timestamp */
145 int SenState; /* Sensor State (see HW specific include) */
146 int (*SenRead)(SK_AC *pAC, SK_IOC IoC, struct s_Sensor *pSen);
147 /* Sensors read function */
148 SK_U16 SenReg; /* Register Address for this sensor */
149 SK_U8 SenDev; /* Device Selection for this sensor */
150};
151
152typedef struct s_I2c {
153 SK_SENSOR SenTable[SK_MAX_SENSORS]; /* Sensor Table */
154 int CurrSens; /* Which sensor is currently queried */
155 int MaxSens; /* Max. number of sensors */
156 int TimerMode; /* Use the timer also to watch the state machine */
157 int InitLevel; /* Initialized Level */
158#ifndef SK_DIAG
159 int DummyReads; /* Number of non-checked dummy reads */
160 SK_TIMER SenTimer; /* Sensors timer */
161#endif /* !SK_DIAG */
162} SK_I2C;
163
164extern int SkI2cInit(SK_AC *pAC, SK_IOC IoC, int Level);
165#ifdef SK_DIAG
166extern SK_U32 SkI2cRead(SK_AC *pAC, SK_IOC IoC, int Dev, int Size, int Reg,
167 int Burst);
168#else /* !SK_DIAG */
169extern int SkI2cEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, SK_EVPARA Para);
170extern void SkI2cWaitIrq(SK_AC *pAC, SK_IOC IoC);
171extern void SkI2cIsr(SK_AC *pAC, SK_IOC IoC);
172#endif /* !SK_DIAG */
173#endif /* n_SKI2C_H */
174
diff --git a/drivers/net/sk98lin/h/skqueue.h b/drivers/net/sk98lin/h/skqueue.h
deleted file mode 100644
index 2ec40d4fdf60..000000000000
--- a/drivers/net/sk98lin/h/skqueue.h
+++ /dev/null
@@ -1,94 +0,0 @@
1/******************************************************************************
2 *
3 * Name: skqueue.h
4 * Project: Gigabit Ethernet Adapters, Event Scheduler Module
5 * Version: $Revision: 1.16 $
6 * Date: $Date: 2003/09/16 12:50:32 $
7 * Purpose: Defines for the Event queue
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect GmbH.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25/*
26 * SKQUEUE.H contains all defines and types for the event queue
27 */
28
29#ifndef _SKQUEUE_H_
30#define _SKQUEUE_H_
31
32
33/*
34 * define the event classes to be served
35 */
36#define SKGE_DRV 1 /* Driver Event Class */
37#define SKGE_RLMT 2 /* RLMT Event Class */
38#define SKGE_I2C 3 /* I2C Event Class */
39#define SKGE_PNMI 4 /* PNMI Event Class */
40#define SKGE_CSUM 5 /* Checksum Event Class */
41#define SKGE_HWAC 6 /* Hardware Access Event Class */
42
43#define SKGE_SWT 9 /* Software Timer Event Class */
44#define SKGE_LACP 10 /* LACP Aggregation Event Class */
45#define SKGE_RSF 11 /* RSF Aggregation Event Class */
46#define SKGE_MARKER 12 /* MARKER Aggregation Event Class */
47#define SKGE_FD 13 /* FD Distributor Event Class */
48
49/*
50 * define event queue as circular buffer
51 */
52#define SK_MAX_EVENT 64
53
54/*
55 * Parameter union for the Para stuff
56 */
57typedef union u_EvPara {
58 void *pParaPtr; /* Parameter Pointer */
59 SK_U64 Para64; /* Parameter 64bit version */
60 SK_U32 Para32[2]; /* Parameter Array of 32bit parameters */
61} SK_EVPARA;
62
63/*
64 * Event Queue
65 * skqueue.c
66 * events are class/value pairs
67 * class is addressee, e.g. RLMT, PNMI etc.
68 * value is command, e.g. line state change, ring op change etc.
69 */
70typedef struct s_EventElem {
71 SK_U32 Class; /* Event class */
72 SK_U32 Event; /* Event value */
73 SK_EVPARA Para; /* Event parameter */
74} SK_EVENTELEM;
75
76typedef struct s_Queue {
77 SK_EVENTELEM EvQueue[SK_MAX_EVENT];
78 SK_EVENTELEM *EvPut;
79 SK_EVENTELEM *EvGet;
80} SK_QUEUE;
81
82extern void SkEventInit(SK_AC *pAC, SK_IOC Ioc, int Level);
83extern void SkEventQueue(SK_AC *pAC, SK_U32 Class, SK_U32 Event,
84 SK_EVPARA Para);
85extern int SkEventDispatcher(SK_AC *pAC, SK_IOC Ioc);
86
87
88/* Define Error Numbers and messages */
89#define SKERR_Q_E001 (SK_ERRBASE_QUEUE+0)
90#define SKERR_Q_E001MSG "Event queue overflow"
91#define SKERR_Q_E002 (SKERR_Q_E001+1)
92#define SKERR_Q_E002MSG "Undefined event class"
93#endif /* _SKQUEUE_H_ */
94
diff --git a/drivers/net/sk98lin/h/skrlmt.h b/drivers/net/sk98lin/h/skrlmt.h
deleted file mode 100644
index ca75dfdcf2d6..000000000000
--- a/drivers/net/sk98lin/h/skrlmt.h
+++ /dev/null
@@ -1,438 +0,0 @@
1/******************************************************************************
2 *
3 * Name: skrlmt.h
4 * Project: GEnesis, PCI Gigabit Ethernet Adapter
5 * Version: $Revision: 1.37 $
6 * Date: $Date: 2003/04/15 09:43:43 $
7 * Purpose: Header file for Redundant Link ManagemenT.
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect GmbH.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25/******************************************************************************
26 *
27 * Description:
28 *
29 * This is the header file for Redundant Link ManagemenT.
30 *
31 * Include File Hierarchy:
32 *
33 * "skdrv1st.h"
34 * ...
35 * "sktypes.h"
36 * "skqueue.h"
37 * "skaddr.h"
38 * "skrlmt.h"
39 * ...
40 * "skdrv2nd.h"
41 *
42 ******************************************************************************/
43
44#ifndef __INC_SKRLMT_H
45#define __INC_SKRLMT_H
46
47#ifdef __cplusplus
48extern "C" {
49#endif /* cplusplus */
50
51/* defines ********************************************************************/
52
53#define SK_RLMT_NET_DOWN_TEMP 1 /* NET_DOWN due to last port down. */
54#define SK_RLMT_NET_DOWN_FINAL 2 /* NET_DOWN due to RLMT_STOP. */
55
56/* ----- Default queue sizes - must be multiples of 8 KB ----- */
57
58/* Less than 8 KB free in RX queue => pause frames. */
59#define SK_RLMT_STANDBY_QRXSIZE 128 /* Size of rx standby queue in KB. */
60#define SK_RLMT_STANDBY_QXASIZE 32 /* Size of async standby queue in KB. */
61#define SK_RLMT_STANDBY_QXSSIZE 0 /* Size of sync standby queue in KB. */
62
63#define SK_RLMT_MAX_TX_BUF_SIZE 60 /* Maximum RLMT transmit size. */
64
65/* ----- PORT states ----- */
66
67#define SK_RLMT_PS_INIT 0 /* Port state: Init. */
68#define SK_RLMT_PS_LINK_DOWN 1 /* Port state: Link down. */
69#define SK_RLMT_PS_DOWN 2 /* Port state: Port down. */
70#define SK_RLMT_PS_GOING_UP 3 /* Port state: Going up. */
71#define SK_RLMT_PS_UP 4 /* Port state: Up. */
72
73/* ----- RLMT states ----- */
74
75#define SK_RLMT_RS_INIT 0 /* RLMT state: Init. */
76#define SK_RLMT_RS_NET_DOWN 1 /* RLMT state: Net down. */
77#define SK_RLMT_RS_NET_UP 2 /* RLMT state: Net up. */
78
79/* ----- PORT events ----- */
80
81#define SK_RLMT_LINK_UP 1001 /* Link came up. */
82#define SK_RLMT_LINK_DOWN 1002 /* Link went down. */
83#define SK_RLMT_PORT_ADDR 1003 /* Port address changed. */
84
85/* ----- RLMT events ----- */
86
87#define SK_RLMT_START 2001 /* Start RLMT. */
88#define SK_RLMT_STOP 2002 /* Stop RLMT. */
89#define SK_RLMT_PACKET_RECEIVED 2003 /* Packet was received for RLMT. */
90#define SK_RLMT_STATS_CLEAR 2004 /* Clear statistics. */
91#define SK_RLMT_STATS_UPDATE 2005 /* Update statistics. */
92#define SK_RLMT_PREFPORT_CHANGE 2006 /* Change preferred port. */
93#define SK_RLMT_MODE_CHANGE 2007 /* New RlmtMode. */
94#define SK_RLMT_SET_NETS 2008 /* Number of Nets (1 or 2). */
95
96/* ----- RLMT mode bits ----- */
97
98/*
99 * CAUTION: These defines are private to RLMT.
100 * Please use the RLMT mode defines below.
101 */
102
103#define SK_RLMT_CHECK_LINK 1 /* Check Link. */
104#define SK_RLMT_CHECK_LOC_LINK 2 /* Check other link on same adapter. */
105#define SK_RLMT_CHECK_SEG 4 /* Check segmentation. */
106
107#ifndef RLMT_CHECK_REMOTE
108#define SK_RLMT_CHECK_OTHERS SK_RLMT_CHECK_LOC_LINK
109#else /* RLMT_CHECK_REMOTE */
110#define SK_RLMT_CHECK_REM_LINK 8 /* Check link(s) on other adapter(s). */
111#define SK_RLMT_MAX_REMOTE_PORTS_CHECKED 3
112#define SK_RLMT_CHECK_OTHERS \
113 (SK_RLMT_CHECK_LOC_LINK | SK_RLMT_CHECK_REM_LINK)
114#endif /* RLMT_CHECK_REMOTE */
115
116#ifndef SK_RLMT_ENABLE_TRANSPARENT
117#define SK_RLMT_TRANSPARENT 0 /* RLMT transparent - inactive. */
118#else /* SK_RLMT_ENABLE_TRANSPARENT */
119#define SK_RLMT_TRANSPARENT 128 /* RLMT transparent. */
120#endif /* SK_RLMT_ENABLE_TRANSPARENT */
121
122/* ----- RLMT modes ----- */
123
124/* Check Link State. */
125#define SK_RLMT_MODE_CLS (SK_RLMT_CHECK_LINK)
126
127/* Check Local Ports: check other links on the same adapter. */
128#define SK_RLMT_MODE_CLP (SK_RLMT_CHECK_LINK | SK_RLMT_CHECK_LOC_LINK)
129
130/* Check Local Ports and Segmentation Status. */
131#define SK_RLMT_MODE_CLPSS \
132 (SK_RLMT_CHECK_LINK | SK_RLMT_CHECK_LOC_LINK | SK_RLMT_CHECK_SEG)
133
134#ifdef RLMT_CHECK_REMOTE
135/* Check Local and Remote Ports: check links (local or remote). */
136 Name of define TBD!
137#define SK_RLMT_MODE_CRP \
138 (SK_RLMT_CHECK_LINK | SK_RLMT_CHECK_LOC_LINK | SK_RLMT_CHECK_REM_LINK)
139
140/* Check Local and Remote Ports and Segmentation Status. */
141 Name of define TBD!
142#define SK_RLMT_MODE_CRPSS \
143 (SK_RLMT_CHECK_LINK | SK_RLMT_CHECK_LOC_LINK | \
144 SK_RLMT_CHECK_REM_LINK | SK_RLMT_CHECK_SEG)
145#endif /* RLMT_CHECK_REMOTE */
146
147/* ----- RLMT lookahead result bits ----- */
148
149#define SK_RLMT_RX_RLMT 1 /* Give packet to RLMT. */
150#define SK_RLMT_RX_PROTOCOL 2 /* Give packet to protocol. */
151
152/* Macros */
153
154#if 0
155SK_AC *pAC /* adapter context */
156SK_U32 PortNum /* receiving port */
157unsigned PktLen /* received packet's length */
158SK_BOOL IsBc /* Flag: packet is broadcast */
159unsigned *pOffset /* offs. of bytes to present to SK_RLMT_LOOKAHEAD */
160unsigned *pNumBytes /* #Bytes to present to SK_RLMT_LOOKAHEAD */
161#endif /* 0 */
162
163#define SK_RLMT_PRE_LOOKAHEAD(pAC,PortNum,PktLen,IsBc,pOffset,pNumBytes) { \
164 SK_AC *_pAC; \
165 SK_U32 _PortNum; \
166 _pAC = (pAC); \
167 _PortNum = (SK_U32)(PortNum); \
168 /* _pAC->Rlmt.Port[_PortNum].PacketsRx++; */ \
169 _pAC->Rlmt.Port[_PortNum].PacketsPerTimeSlot++; \
170 if (_pAC->Rlmt.RlmtOff) { \
171 *(pNumBytes) = 0; \
172 } \
173 else {\
174 if ((_pAC->Rlmt.Port[_PortNum].Net->RlmtMode & SK_RLMT_TRANSPARENT) != 0) { \
175 *(pNumBytes) = 0; \
176 } \
177 else if (IsBc) { \
178 if (_pAC->Rlmt.Port[_PortNum].Net->RlmtMode != SK_RLMT_MODE_CLS) { \
179 *(pNumBytes) = 6; \
180 *(pOffset) = 6; \
181 } \
182 else { \
183 *(pNumBytes) = 0; \
184 } \
185 } \
186 else { \
187 if ((PktLen) > SK_RLMT_MAX_TX_BUF_SIZE) { \
188 /* _pAC->Rlmt.Port[_PortNum].DataPacketsPerTimeSlot++; */ \
189 *(pNumBytes) = 0; \
190 } \
191 else { \
192 *(pNumBytes) = 6; \
193 *(pOffset) = 0; \
194 } \
195 } \
196 } \
197}
198
199#if 0
200SK_AC *pAC /* adapter context */
201SK_U32 PortNum /* receiving port */
202SK_U8 *pLaPacket, /* received packet's data (points to pOffset) */
203SK_BOOL IsBc /* Flag: packet is broadcast */
204SK_BOOL IsMc /* Flag: packet is multicast */
205unsigned *pForRlmt /* Result: bits SK_RLMT_RX_RLMT, SK_RLMT_RX_PROTOCOL */
206SK_RLMT_LOOKAHEAD() expects *pNumBytes from
207packet offset *pOffset (s.a.) at *pLaPacket.
208
209If you use SK_RLMT_LOOKAHEAD in a path where you already know if the packet is
210BC, MC, or UC, you should use constants for IsBc and IsMc, so that your compiler
211can trash unneeded parts of the if construction.
212#endif /* 0 */
213
214#define SK_RLMT_LOOKAHEAD(pAC,PortNum,pLaPacket,IsBc,IsMc,pForRlmt) { \
215 SK_AC *_pAC; \
216 SK_U32 _PortNum; \
217 SK_U8 *_pLaPacket; \
218 _pAC = (pAC); \
219 _PortNum = (SK_U32)(PortNum); \
220 _pLaPacket = (SK_U8 *)(pLaPacket); \
221 if (IsBc) {\
222 if (!SK_ADDR_EQUAL(_pLaPacket, _pAC->Addr.Net[_pAC->Rlmt.Port[ \
223 _PortNum].Net->NetNumber].CurrentMacAddress.a)) { \
224 _pAC->Rlmt.Port[_PortNum].BcTimeStamp = SkOsGetTime(_pAC); \
225 _pAC->Rlmt.CheckSwitch = SK_TRUE; \
226 } \
227 /* _pAC->Rlmt.Port[_PortNum].DataPacketsPerTimeSlot++; */ \
228 *(pForRlmt) = SK_RLMT_RX_PROTOCOL; \
229 } \
230 else if (IsMc) { \
231 if (SK_ADDR_EQUAL(_pLaPacket, BridgeMcAddr.a)) { \
232 _pAC->Rlmt.Port[_PortNum].BpduPacketsPerTimeSlot++; \
233 if (_pAC->Rlmt.Port[_PortNum].Net->RlmtMode & SK_RLMT_CHECK_SEG) { \
234 *(pForRlmt) = SK_RLMT_RX_RLMT | SK_RLMT_RX_PROTOCOL; \
235 } \
236 else { \
237 *(pForRlmt) = SK_RLMT_RX_PROTOCOL; \
238 } \
239 } \
240 else if (SK_ADDR_EQUAL(_pLaPacket, SkRlmtMcAddr.a)) { \
241 *(pForRlmt) = SK_RLMT_RX_RLMT; \
242 } \
243 else { \
244 /* _pAC->Rlmt.Port[_PortNum].DataPacketsPerTimeSlot++; */ \
245 *(pForRlmt) = SK_RLMT_RX_PROTOCOL; \
246 } \
247 } \
248 else { \
249 if (SK_ADDR_EQUAL( \
250 _pLaPacket, \
251 _pAC->Addr.Port[_PortNum].CurrentMacAddress.a)) { \
252 *(pForRlmt) = SK_RLMT_RX_RLMT; \
253 } \
254 else { \
255 /* _pAC->Rlmt.Port[_PortNum].DataPacketsPerTimeSlot++; */ \
256 *(pForRlmt) = SK_RLMT_RX_PROTOCOL; \
257 } \
258 } \
259}
260
261#ifdef SK_RLMT_FAST_LOOKAHEAD
262Error: SK_RLMT_FAST_LOOKAHEAD no longer used. Use new macros for lookahead.
263#endif /* SK_RLMT_FAST_LOOKAHEAD */
264#ifdef SK_RLMT_SLOW_LOOKAHEAD
265Error: SK_RLMT_SLOW_LOOKAHEAD no longer used. Use new macros for lookahead.
266#endif /* SK_RLMT_SLOW_LOOKAHEAD */
267
268/* typedefs *******************************************************************/
269
270#ifdef SK_RLMT_MBUF_PRIVATE
271typedef struct s_RlmtMbuf {
272 some content
273} SK_RLMT_MBUF;
274#endif /* SK_RLMT_MBUF_PRIVATE */
275
276
277#ifdef SK_LA_INFO
278typedef struct s_Rlmt_PacketInfo {
279 unsigned PacketLength; /* Length of packet. */
280 unsigned PacketType; /* Directed/Multicast/Broadcast. */
281} SK_RLMT_PINFO;
282#endif /* SK_LA_INFO */
283
284
285typedef struct s_RootId {
286 SK_U8 Id[8]; /* Root Bridge Id. */
287} SK_RLMT_ROOT_ID;
288
289
290typedef struct s_port {
291 SK_MAC_ADDR CheckAddr;
292 SK_BOOL SuspectTx;
293} SK_PORT_CHECK;
294
295
296typedef struct s_RlmtNet SK_RLMT_NET;
297
298
299typedef struct s_RlmtPort {
300
301/* ----- Public part (read-only) ----- */
302
303 SK_U8 PortState; /* Current state of this port. */
304
305 /* For PNMI */
306 SK_BOOL LinkDown;
307 SK_BOOL PortDown;
308 SK_U8 Align01;
309
310 SK_U32 PortNumber; /* Number of port on adapter. */
311 SK_RLMT_NET * Net; /* Net port belongs to. */
312
313 SK_U64 TxHelloCts;
314 SK_U64 RxHelloCts;
315 SK_U64 TxSpHelloReqCts;
316 SK_U64 RxSpHelloCts;
317
318/* ----- Private part ----- */
319
320/* SK_U64 PacketsRx; */ /* Total packets received. */
321 SK_U32 PacketsPerTimeSlot; /* Packets rxed between TOs. */
322/* SK_U32 DataPacketsPerTimeSlot; */ /* Data packets ... */
323 SK_U32 BpduPacketsPerTimeSlot; /* BPDU packets rxed in TS. */
324 SK_U64 BcTimeStamp; /* Time of last BC receive. */
325 SK_U64 GuTimeStamp; /* Time of entering GOING_UP. */
326
327 SK_TIMER UpTimer; /* Timer struct Link/Port up. */
328 SK_TIMER DownRxTimer; /* Timer struct down rx. */
329 SK_TIMER DownTxTimer; /* Timer struct down tx. */
330
331 SK_U32 CheckingState; /* Checking State. */
332
333 SK_ADDR_PORT * AddrPort;
334
335 SK_U8 Random[4]; /* Random value. */
336 unsigned PortsChecked; /* #ports checked. */
337 unsigned PortsSuspect; /* #ports checked that are s. */
338 SK_PORT_CHECK PortCheck[1];
339/* SK_PORT_CHECK PortCheck[SK_MAX_MACS - 1]; */
340
341 SK_BOOL PortStarted; /* Port is started. */
342 SK_BOOL PortNoRx; /* NoRx for >= 1 time slot. */
343 SK_BOOL RootIdSet;
344 SK_RLMT_ROOT_ID Root; /* Root Bridge Id. */
345} SK_RLMT_PORT;
346
347
348struct s_RlmtNet {
349
350/* ----- Public part (read-only) ----- */
351
352 SK_U32 NetNumber; /* Number of net. */
353
354 SK_RLMT_PORT * Port[SK_MAX_MACS]; /* Ports that belong to this net. */
355 SK_U32 NumPorts; /* Number of ports. */
356 SK_U32 PrefPort; /* Preferred port. */
357
358 /* For PNMI */
359
360 SK_U32 ChgBcPrio; /* Change Priority of last broadcast received */
361 SK_U32 RlmtMode; /* Check ... */
362 SK_U32 ActivePort; /* Active port. */
363 SK_U32 Preference; /* 0xFFFFFFFF: Automatic. */
364
365 SK_U8 RlmtState; /* Current RLMT state. */
366
367/* ----- Private part ----- */
368 SK_BOOL RootIdSet;
369 SK_U16 Align01;
370
371 int LinksUp; /* #Links up. */
372 int PortsUp; /* #Ports up. */
373 SK_U32 TimeoutValue; /* RLMT timeout value. */
374
375 SK_U32 CheckingState; /* Checking State. */
376 SK_RLMT_ROOT_ID Root; /* Root Bridge Id. */
377
378 SK_TIMER LocTimer; /* Timer struct. */
379 SK_TIMER SegTimer; /* Timer struct. */
380};
381
382
383typedef struct s_Rlmt {
384
385/* ----- Public part (read-only) ----- */
386
387 SK_U32 NumNets; /* Number of nets. */
388 SK_U32 NetsStarted; /* Number of nets started. */
389 SK_RLMT_NET Net[SK_MAX_NETS]; /* Array of available nets. */
390 SK_RLMT_PORT Port[SK_MAX_MACS]; /* Array of available ports. */
391
392/* ----- Private part ----- */
393 SK_BOOL CheckSwitch;
394 SK_BOOL RlmtOff; /* set to zero if the Mac addresses
395 are equal or the second one
396 is zero */
397 SK_U16 Align01;
398
399} SK_RLMT;
400
401
402extern SK_MAC_ADDR BridgeMcAddr;
403extern SK_MAC_ADDR SkRlmtMcAddr;
404
405/* function prototypes ********************************************************/
406
407
408#ifndef SK_KR_PROTO
409
410/* Functions provided by SkRlmt */
411
412/* ANSI/C++ compliant function prototypes */
413
414extern void SkRlmtInit(
415 SK_AC *pAC,
416 SK_IOC IoC,
417 int Level);
418
419extern int SkRlmtEvent(
420 SK_AC *pAC,
421 SK_IOC IoC,
422 SK_U32 Event,
423 SK_EVPARA Para);
424
425#else /* defined(SK_KR_PROTO) */
426
427/* Non-ANSI/C++ compliant function prototypes */
428
429#error KR-style function prototypes are not yet provided.
430
431#endif /* defined(SK_KR_PROTO)) */
432
433
434#ifdef __cplusplus
435}
436#endif /* __cplusplus */
437
438#endif /* __INC_SKRLMT_H */
diff --git a/drivers/net/sk98lin/h/sktimer.h b/drivers/net/sk98lin/h/sktimer.h
deleted file mode 100644
index 04e6d7c1ec33..000000000000
--- a/drivers/net/sk98lin/h/sktimer.h
+++ /dev/null
@@ -1,63 +0,0 @@
1/******************************************************************************
2 *
3 * Name: sktimer.h
4 * Project: Gigabit Ethernet Adapters, Event Scheduler Module
5 * Version: $Revision: 1.11 $
6 * Date: $Date: 2003/09/16 12:58:18 $
7 * Purpose: Defines for the timer functions
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect GmbH.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25/*
26 * SKTIMER.H contains all defines and types for the timer functions
27 */
28
29#ifndef _SKTIMER_H_
30#define _SKTIMER_H_
31
32#include "h/skqueue.h"
33
34/*
35 * SK timer
36 * - needed wherever a timer is used. Put this in your data structure
37 * wherever you want.
38 */
39typedef struct s_Timer SK_TIMER;
40
41struct s_Timer {
42 SK_TIMER *TmNext; /* linked list */
43 SK_U32 TmClass; /* Timer Event class */
44 SK_U32 TmEvent; /* Timer Event value */
45 SK_EVPARA TmPara; /* Timer Event parameter */
46 SK_U32 TmDelta; /* delta time */
47 int TmActive; /* flag: active/inactive */
48};
49
50/*
51 * Timer control struct.
52 * - use in Adapters context name pAC->Tim
53 */
54typedef struct s_TimCtrl {
55 SK_TIMER *StQueue; /* Head of Timer queue */
56} SK_TIMCTRL;
57
58extern void SkTimerInit(SK_AC *pAC, SK_IOC Ioc, int Level);
59extern void SkTimerStop(SK_AC *pAC, SK_IOC Ioc, SK_TIMER *pTimer);
60extern void SkTimerStart(SK_AC *pAC, SK_IOC Ioc, SK_TIMER *pTimer,
61 SK_U32 Time, SK_U32 Class, SK_U32 Event, SK_EVPARA Para);
62extern void SkTimerDone(SK_AC *pAC, SK_IOC Ioc);
63#endif /* _SKTIMER_H_ */
diff --git a/drivers/net/sk98lin/h/sktypes.h b/drivers/net/sk98lin/h/sktypes.h
deleted file mode 100644
index 40edc96e1055..000000000000
--- a/drivers/net/sk98lin/h/sktypes.h
+++ /dev/null
@@ -1,69 +0,0 @@
1/******************************************************************************
2 *
3 * Name: sktypes.h
4 * Project: GEnesis, PCI Gigabit Ethernet Adapter
5 * Version: $Revision: 1.2 $
6 * Date: $Date: 2003/10/07 08:16:51 $
7 * Purpose: Define data types for Linux
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect GmbH.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25/******************************************************************************
26 *
27 * Description:
28 *
29 * In this file, all data types that are needed by the common modules
30 * are mapped to Linux data types.
31 *
32 *
33 * Include File Hierarchy:
34 *
35 *
36 ******************************************************************************/
37
38#ifndef __INC_SKTYPES_H
39#define __INC_SKTYPES_H
40
41
42/* defines *******************************************************************/
43
44/*
45 * Data types with a specific size. 'I' = signed, 'U' = unsigned.
46 */
47#define SK_I8 s8
48#define SK_U8 u8
49#define SK_I16 s16
50#define SK_U16 u16
51#define SK_I32 s32
52#define SK_U32 u32
53#define SK_I64 s64
54#define SK_U64 u64
55
56#define SK_UPTR ulong /* casting pointer <-> integral */
57
58/*
59* Boolean type.
60*/
61#define SK_BOOL SK_U8
62#define SK_FALSE 0
63#define SK_TRUE (!SK_FALSE)
64
65/* typedefs *******************************************************************/
66
67/* function prototypes ********************************************************/
68
69#endif /* __INC_SKTYPES_H */
diff --git a/drivers/net/sk98lin/h/skversion.h b/drivers/net/sk98lin/h/skversion.h
deleted file mode 100644
index a1a7294828e5..000000000000
--- a/drivers/net/sk98lin/h/skversion.h
+++ /dev/null
@@ -1,38 +0,0 @@
1/******************************************************************************
2 *
3 * Name: version.h
4 * Project: GEnesis, PCI Gigabit Ethernet Adapter
5 * Version: $Revision: 1.5 $
6 * Date: $Date: 2003/10/07 08:16:51 $
7 * Purpose: SK specific Error log support
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect GmbH.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25#ifdef lint
26static const char SysKonnectFileId[] = "@(#) (C) SysKonnect GmbH.";
27static const char SysKonnectBuildNumber[] =
28 "@(#)SK-BUILD: 6.23 PL: 01";
29#endif /* !defined(lint) */
30
31#define BOOT_STRING "sk98lin: Network Device Driver v6.23\n" \
32 "(C)Copyright 1999-2004 Marvell(R)."
33
34#define VER_STRING "6.23"
35#define DRIVER_FILE_NAME "sk98lin"
36#define DRIVER_REL_DATE "Feb-13-2004"
37
38
diff --git a/drivers/net/sk98lin/h/skvpd.h b/drivers/net/sk98lin/h/skvpd.h
deleted file mode 100644
index fdd9e48e8040..000000000000
--- a/drivers/net/sk98lin/h/skvpd.h
+++ /dev/null
@@ -1,248 +0,0 @@
1/******************************************************************************
2 *
3 * Name: skvpd.h
4 * Project: GEnesis, PCI Gigabit Ethernet Adapter
5 * Version: $Revision: 1.15 $
6 * Date: $Date: 2003/01/13 10:39:38 $
7 * Purpose: Defines and Macros for VPD handling
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2003 SysKonnect GmbH.
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * The information in this file is provided "AS IS" without warranty.
21 *
22 ******************************************************************************/
23
24/*
25 * skvpd.h contains Diagnostic specific defines for VPD handling
26 */
27
28#ifndef __INC_SKVPD_H_
29#define __INC_SKVPD_H_
30
31/*
32 * Define Resource Type Identifiers and VPD keywords
33 */
34#define RES_ID 0x82 /* Resource Type ID String (Product Name) */
35#define RES_VPD_R 0x90 /* start of VPD read only area */
36#define RES_VPD_W 0x91 /* start of VPD read/write area */
37#define RES_END 0x78 /* Resource Type End Tag */
38
39#ifndef VPD_NAME
40#define VPD_NAME "Name" /* Product Name, VPD name of RES_ID */
41#endif /* VPD_NAME */
42#define VPD_PN "PN" /* Adapter Part Number */
43#define VPD_EC "EC" /* Adapter Engineering Level */
44#define VPD_MN "MN" /* Manufacture ID */
45#define VPD_SN "SN" /* Serial Number */
46#define VPD_CP "CP" /* Extended Capability */
47#define VPD_RV "RV" /* Checksum and Reserved */
48#define VPD_YA "YA" /* Asset Tag Identifier */
49#define VPD_VL "VL" /* First Error Log Message (SK specific) */
50#define VPD_VF "VF" /* Second Error Log Message (SK specific) */
51#define VPD_RW "RW" /* Remaining Read / Write Area */
52
53/* 'type' values for vpd_setup_para() */
54#define VPD_RO_KEY 1 /* RO keys are "PN", "EC", "MN", "SN", "RV" */
55#define VPD_RW_KEY 2 /* RW keys are "Yx", "Vx", and "RW" */
56
57/* 'op' values for vpd_setup_para() */
58#define ADD_KEY 1 /* add the key at the pos "RV" or "RW" */
59#define OWR_KEY 2 /* overwrite key if already exists */
60
61/*
62 * Define READ and WRITE Constants.
63 */
64
65#define VPD_DEV_ID_GENESIS 0x4300
66
67#define VPD_SIZE_YUKON 256
68#define VPD_SIZE_GENESIS 512
69#define VPD_SIZE 512
70#define VPD_READ 0x0000
71#define VPD_WRITE 0x8000
72
73#define VPD_STOP(pAC,IoC) VPD_OUT16(pAC,IoC,PCI_VPD_ADR_REG,VPD_WRITE)
74
75#define VPD_GET_RES_LEN(p) ((unsigned int) \
76 (* (SK_U8 *)&(p)[1]) |\
77 ((* (SK_U8 *)&(p)[2]) << 8))
78#define VPD_GET_VPD_LEN(p) ((unsigned int)(* (SK_U8 *)&(p)[2]))
79#define VPD_GET_VAL(p) ((char *)&(p)[3])
80
81#define VPD_MAX_LEN 50
82
83/* VPD status */
84 /* bit 7..1 reserved */
85#define VPD_VALID (1<<0) /* VPD data buffer, vpd_free_ro, */
86 /* and vpd_free_rw valid */
87
88/*
89 * VPD structs
90 */
91typedef struct s_vpd_status {
92 unsigned short Align01; /* Alignment */
93 unsigned short vpd_status; /* VPD status, description see above */
94 int vpd_free_ro; /* unused bytes in read only area */
95 int vpd_free_rw; /* bytes available in read/write area */
96} SK_VPD_STATUS;
97
98typedef struct s_vpd {
99 SK_VPD_STATUS v; /* VPD status structure */
100 char vpd_buf[VPD_SIZE]; /* VPD buffer */
101 int rom_size; /* VPD ROM Size from PCI_OUR_REG_2 */
102 int vpd_size; /* saved VPD-size */
103} SK_VPD;
104
105typedef struct s_vpd_para {
106 unsigned int p_len; /* parameter length */
107 char *p_val; /* points to the value */
108} SK_VPD_PARA;
109
110/*
111 * structure of Large Resource Type Identifiers
112 */
113
114/* was removed because of alignment problems */
115
116/*
117 * structure of VPD keywords
118 */
119typedef struct s_vpd_key {
120 char p_key[2]; /* 2 bytes ID string */
121 unsigned char p_len; /* 1 byte length */
122 char p_val; /* start of the value string */
123} SK_VPD_KEY;
124
125
126/*
127 * System specific VPD macros
128 */
129#ifndef SKDIAG
130#ifndef VPD_DO_IO
131#define VPD_OUT8(pAC,IoC,Addr,Val) (void)SkPciWriteCfgByte(pAC,Addr,Val)
132#define VPD_OUT16(pAC,IoC,Addr,Val) (void)SkPciWriteCfgWord(pAC,Addr,Val)
133#define VPD_IN8(pAC,IoC,Addr,pVal) (void)SkPciReadCfgByte(pAC,Addr,pVal)
134#define VPD_IN16(pAC,IoC,Addr,pVal) (void)SkPciReadCfgWord(pAC,Addr,pVal)
135#define VPD_IN32(pAC,IoC,Addr,pVal) (void)SkPciReadCfgDWord(pAC,Addr,pVal)
136#else /* VPD_DO_IO */
137#define VPD_OUT8(pAC,IoC,Addr,Val) SK_OUT8(IoC,PCI_C(Addr),Val)
138#define VPD_OUT16(pAC,IoC,Addr,Val) SK_OUT16(IoC,PCI_C(Addr),Val)
139#define VPD_IN8(pAC,IoC,Addr,pVal) SK_IN8(IoC,PCI_C(Addr),pVal)
140#define VPD_IN16(pAC,IoC,Addr,pVal) SK_IN16(IoC,PCI_C(Addr),pVal)
141#define VPD_IN32(pAC,IoC,Addr,pVal) SK_IN32(IoC,PCI_C(Addr),pVal)
142#endif /* VPD_DO_IO */
143#else /* SKDIAG */
144#define VPD_OUT8(pAC,Ioc,Addr,Val) { \
145 if ((pAC)->DgT.DgUseCfgCycle) \
146 SkPciWriteCfgByte(pAC,Addr,Val); \
147 else \
148 SK_OUT8(pAC,PCI_C(Addr),Val); \
149 }
150#define VPD_OUT16(pAC,Ioc,Addr,Val) { \
151 if ((pAC)->DgT.DgUseCfgCycle) \
152 SkPciWriteCfgWord(pAC,Addr,Val); \
153 else \
154 SK_OUT16(pAC,PCI_C(Addr),Val); \
155 }
156#define VPD_IN8(pAC,Ioc,Addr,pVal) { \
157 if ((pAC)->DgT.DgUseCfgCycle) \
158 SkPciReadCfgByte(pAC,Addr,pVal); \
159 else \
160 SK_IN8(pAC,PCI_C(Addr),pVal); \
161 }
162#define VPD_IN16(pAC,Ioc,Addr,pVal) { \
163 if ((pAC)->DgT.DgUseCfgCycle) \
164 SkPciReadCfgWord(pAC,Addr,pVal); \
165 else \
166 SK_IN16(pAC,PCI_C(Addr),pVal); \
167 }
168#define VPD_IN32(pAC,Ioc,Addr,pVal) { \
169 if ((pAC)->DgT.DgUseCfgCycle) \
170 SkPciReadCfgDWord(pAC,Addr,pVal); \
171 else \
172 SK_IN32(pAC,PCI_C(Addr),pVal); \
173 }
174#endif /* nSKDIAG */
175
176/* function prototypes ********************************************************/
177
178#ifndef SK_KR_PROTO
179#ifdef SKDIAG
180extern SK_U32 VpdReadDWord(
181 SK_AC *pAC,
182 SK_IOC IoC,
183 int addr);
184#endif /* SKDIAG */
185
186extern SK_VPD_STATUS *VpdStat(
187 SK_AC *pAC,
188 SK_IOC IoC);
189
190extern int VpdKeys(
191 SK_AC *pAC,
192 SK_IOC IoC,
193 char *buf,
194 int *len,
195 int *elements);
196
197extern int VpdRead(
198 SK_AC *pAC,
199 SK_IOC IoC,
200 const char *key,
201 char *buf,
202 int *len);
203
204extern SK_BOOL VpdMayWrite(
205 char *key);
206
207extern int VpdWrite(
208 SK_AC *pAC,
209 SK_IOC IoC,
210 const char *key,
211 const char *buf);
212
213extern int VpdDelete(
214 SK_AC *pAC,
215 SK_IOC IoC,
216 char *key);
217
218extern int VpdUpdate(
219 SK_AC *pAC,
220 SK_IOC IoC);
221
222#ifdef SKDIAG
223extern int VpdReadBlock(
224 SK_AC *pAC,
225 SK_IOC IoC,
226 char *buf,
227 int addr,
228 int len);
229
230extern int VpdWriteBlock(
231 SK_AC *pAC,
232 SK_IOC IoC,
233 char *buf,
234 int addr,
235 int len);
236#endif /* SKDIAG */
237#else /* SK_KR_PROTO */
238extern SK_U32 VpdReadDWord();
239extern SK_VPD_STATUS *VpdStat();
240extern int VpdKeys();
241extern int VpdRead();
242extern SK_BOOL VpdMayWrite();
243extern int VpdWrite();
244extern int VpdDelete();
245extern int VpdUpdate();
246#endif /* SK_KR_PROTO */
247
248#endif /* __INC_SKVPD_H_ */
diff --git a/drivers/net/sk98lin/h/xmac_ii.h b/drivers/net/sk98lin/h/xmac_ii.h
deleted file mode 100644
index 7f8e6d0084c7..000000000000
--- a/drivers/net/sk98lin/h/xmac_ii.h
+++ /dev/null
@@ -1,1579 +0,0 @@
1/******************************************************************************
2 *
3 * Name: xmac_ii.h
4 * Project: Gigabit Ethernet Adapters, Common Modules
5 * Version: $Revision: 1.52 $
6 * Date: $Date: 2003/10/02 16:35:50 $
7 * Purpose: Defines and Macros for Gigabit Ethernet Controller
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25#ifndef __INC_XMAC_H
26#define __INC_XMAC_H
27
28#ifdef __cplusplus
29extern "C" {
30#endif /* __cplusplus */
31
32/* defines ********************************************************************/
33
34/*
35 * XMAC II registers
36 *
37 * The XMAC registers are 16 or 32 bits wide.
38 * The XMACs host processor interface is set to 16 bit mode,
39 * therefore ALL registers will be addressed with 16 bit accesses.
40 *
41 * The following macros are provided to access the XMAC registers
42 * XM_IN16(), XM_OUT16, XM_IN32(), XM_OUT32(), XM_INADR(), XM_OUTADR(),
43 * XM_INHASH(), and XM_OUTHASH().
44 * The macros are defined in SkGeHw.h.
45 *
46 * Note: NA reg = Network Address e.g DA, SA etc.
47 *
48 */
49#define XM_MMU_CMD 0x0000 /* 16 bit r/w MMU Command Register */
50 /* 0x0004: reserved */
51#define XM_POFF 0x0008 /* 32 bit r/w Packet Offset Register */
52#define XM_BURST 0x000c /* 32 bit r/w Burst Register for half duplex*/
53#define XM_1L_VLAN_TAG 0x0010 /* 16 bit r/w One Level VLAN Tag ID */
54#define XM_2L_VLAN_TAG 0x0014 /* 16 bit r/w Two Level VLAN Tag ID */
55 /* 0x0018 - 0x001e: reserved */
56#define XM_TX_CMD 0x0020 /* 16 bit r/w Transmit Command Register */
57#define XM_TX_RT_LIM 0x0024 /* 16 bit r/w Transmit Retry Limit Register */
58#define XM_TX_STIME 0x0028 /* 16 bit r/w Transmit Slottime Register */
59#define XM_TX_IPG 0x002c /* 16 bit r/w Transmit Inter Packet Gap */
60#define XM_RX_CMD 0x0030 /* 16 bit r/w Receive Command Register */
61#define XM_PHY_ADDR 0x0034 /* 16 bit r/w PHY Address Register */
62#define XM_PHY_DATA 0x0038 /* 16 bit r/w PHY Data Register */
63 /* 0x003c: reserved */
64#define XM_GP_PORT 0x0040 /* 32 bit r/w General Purpose Port Register */
65#define XM_IMSK 0x0044 /* 16 bit r/w Interrupt Mask Register */
66#define XM_ISRC 0x0048 /* 16 bit r/o Interrupt Status Register */
67#define XM_HW_CFG 0x004c /* 16 bit r/w Hardware Config Register */
68 /* 0x0050 - 0x005e: reserved */
69#define XM_TX_LO_WM 0x0060 /* 16 bit r/w Tx FIFO Low Water Mark */
70#define XM_TX_HI_WM 0x0062 /* 16 bit r/w Tx FIFO High Water Mark */
71#define XM_TX_THR 0x0064 /* 16 bit r/w Tx Request Threshold */
72#define XM_HT_THR 0x0066 /* 16 bit r/w Host Request Threshold */
73#define XM_PAUSE_DA 0x0068 /* NA reg r/w Pause Destination Address */
74 /* 0x006e: reserved */
75#define XM_CTL_PARA 0x0070 /* 32 bit r/w Control Parameter Register */
76#define XM_MAC_OPCODE 0x0074 /* 16 bit r/w Opcode for MAC control frames */
77#define XM_MAC_PTIME 0x0076 /* 16 bit r/w Pause time for MAC ctrl frames*/
78#define XM_TX_STAT 0x0078 /* 32 bit r/o Tx Status LIFO Register */
79
80 /* 0x0080 - 0x00fc: 16 NA reg r/w Exact Match Address Registers */
81 /* use the XM_EXM() macro to address */
82#define XM_EXM_START 0x0080 /* r/w Start Address of the EXM Regs */
83
84 /*
85 * XM_EXM(Reg)
86 *
87 * returns the XMAC address offset of specified Exact Match Addr Reg
88 *
89 * para: Reg EXM register to addr (0 .. 15)
90 *
91 * usage: XM_INADDR(IoC, MAC_1, XM_EXM(i), &val[i]);
92 */
93#define XM_EXM(Reg) (XM_EXM_START + ((Reg) << 3))
94
95#define XM_SRC_CHK 0x0100 /* NA reg r/w Source Check Address Register */
96#define XM_SA 0x0108 /* NA reg r/w Station Address Register */
97#define XM_HSM 0x0110 /* 64 bit r/w Hash Match Address Registers */
98#define XM_RX_LO_WM 0x0118 /* 16 bit r/w Receive Low Water Mark */
99#define XM_RX_HI_WM 0x011a /* 16 bit r/w Receive High Water Mark */
100#define XM_RX_THR 0x011c /* 32 bit r/w Receive Request Threshold */
101#define XM_DEV_ID 0x0120 /* 32 bit r/o Device ID Register */
102#define XM_MODE 0x0124 /* 32 bit r/w Mode Register */
103#define XM_LSA 0x0128 /* NA reg r/o Last Source Register */
104 /* 0x012e: reserved */
105#define XM_TS_READ 0x0130 /* 32 bit r/o Time Stamp Read Register */
106#define XM_TS_LOAD 0x0134 /* 32 bit r/o Time Stamp Load Value */
107 /* 0x0138 - 0x01fe: reserved */
108#define XM_STAT_CMD 0x0200 /* 16 bit r/w Statistics Command Register */
109#define XM_RX_CNT_EV 0x0204 /* 32 bit r/o Rx Counter Event Register */
110#define XM_TX_CNT_EV 0x0208 /* 32 bit r/o Tx Counter Event Register */
111#define XM_RX_EV_MSK 0x020c /* 32 bit r/w Rx Counter Event Mask */
112#define XM_TX_EV_MSK 0x0210 /* 32 bit r/w Tx Counter Event Mask */
113 /* 0x0204 - 0x027e: reserved */
114#define XM_TXF_OK 0x0280 /* 32 bit r/o Frames Transmitted OK Conuter */
115#define XM_TXO_OK_HI 0x0284 /* 32 bit r/o Octets Transmitted OK High Cnt*/
116#define XM_TXO_OK_LO 0x0288 /* 32 bit r/o Octets Transmitted OK Low Cnt */
117#define XM_TXF_BC_OK 0x028c /* 32 bit r/o Broadcast Frames Xmitted OK */
118#define XM_TXF_MC_OK 0x0290 /* 32 bit r/o Multicast Frames Xmitted OK */
119#define XM_TXF_UC_OK 0x0294 /* 32 bit r/o Unicast Frames Xmitted OK */
120#define XM_TXF_LONG 0x0298 /* 32 bit r/o Tx Long Frame Counter */
121#define XM_TXE_BURST 0x029c /* 32 bit r/o Tx Burst Event Counter */
122#define XM_TXF_MPAUSE 0x02a0 /* 32 bit r/o Tx Pause MAC Ctrl Frame Cnt */
123#define XM_TXF_MCTRL 0x02a4 /* 32 bit r/o Tx MAC Ctrl Frame Counter */
124#define XM_TXF_SNG_COL 0x02a8 /* 32 bit r/o Tx Single Collision Counter */
125#define XM_TXF_MUL_COL 0x02ac /* 32 bit r/o Tx Multiple Collision Counter */
126#define XM_TXF_ABO_COL 0x02b0 /* 32 bit r/o Tx aborted due to Exces. Col. */
127#define XM_TXF_LAT_COL 0x02b4 /* 32 bit r/o Tx Late Collision Counter */
128#define XM_TXF_DEF 0x02b8 /* 32 bit r/o Tx Deferred Frame Counter */
129#define XM_TXF_EX_DEF 0x02bc /* 32 bit r/o Tx Excessive Deferall Counter */
130#define XM_TXE_FIFO_UR 0x02c0 /* 32 bit r/o Tx FIFO Underrun Event Cnt */
131#define XM_TXE_CS_ERR 0x02c4 /* 32 bit r/o Tx Carrier Sense Error Cnt */
132#define XM_TXP_UTIL 0x02c8 /* 32 bit r/o Tx Utilization in % */
133 /* 0x02cc - 0x02ce: reserved */
134#define XM_TXF_64B 0x02d0 /* 32 bit r/o 64 Byte Tx Frame Counter */
135#define XM_TXF_127B 0x02d4 /* 32 bit r/o 65-127 Byte Tx Frame Counter */
136#define XM_TXF_255B 0x02d8 /* 32 bit r/o 128-255 Byte Tx Frame Counter */
137#define XM_TXF_511B 0x02dc /* 32 bit r/o 256-511 Byte Tx Frame Counter */
138#define XM_TXF_1023B 0x02e0 /* 32 bit r/o 512-1023 Byte Tx Frame Counter*/
139#define XM_TXF_MAX_SZ 0x02e4 /* 32 bit r/o 1024-MaxSize Byte Tx Frame Cnt*/
140 /* 0x02e8 - 0x02fe: reserved */
141#define XM_RXF_OK 0x0300 /* 32 bit r/o Frames Received OK */
142#define XM_RXO_OK_HI 0x0304 /* 32 bit r/o Octets Received OK High Cnt */
143#define XM_RXO_OK_LO 0x0308 /* 32 bit r/o Octets Received OK Low Counter*/
144#define XM_RXF_BC_OK 0x030c /* 32 bit r/o Broadcast Frames Received OK */
145#define XM_RXF_MC_OK 0x0310 /* 32 bit r/o Multicast Frames Received OK */
146#define XM_RXF_UC_OK 0x0314 /* 32 bit r/o Unicast Frames Received OK */
147#define XM_RXF_MPAUSE 0x0318 /* 32 bit r/o Rx Pause MAC Ctrl Frame Cnt */
148#define XM_RXF_MCTRL 0x031c /* 32 bit r/o Rx MAC Ctrl Frame Counter */
149#define XM_RXF_INV_MP 0x0320 /* 32 bit r/o Rx invalid Pause Frame Cnt */
150#define XM_RXF_INV_MOC 0x0324 /* 32 bit r/o Rx Frames with inv. MAC Opcode*/
151#define XM_RXE_BURST 0x0328 /* 32 bit r/o Rx Burst Event Counter */
152#define XM_RXE_FMISS 0x032c /* 32 bit r/o Rx Missed Frames Event Cnt */
153#define XM_RXF_FRA_ERR 0x0330 /* 32 bit r/o Rx Framing Error Counter */
154#define XM_RXE_FIFO_OV 0x0334 /* 32 bit r/o Rx FIFO overflow Event Cnt */
155#define XM_RXF_JAB_PKT 0x0338 /* 32 bit r/o Rx Jabber Packet Frame Cnt */
156#define XM_RXE_CAR_ERR 0x033c /* 32 bit r/o Rx Carrier Event Error Cnt */
157#define XM_RXF_LEN_ERR 0x0340 /* 32 bit r/o Rx in Range Length Error */
158#define XM_RXE_SYM_ERR 0x0344 /* 32 bit r/o Rx Symbol Error Counter */
159#define XM_RXE_SHT_ERR 0x0348 /* 32 bit r/o Rx Short Event Error Cnt */
160#define XM_RXE_RUNT 0x034c /* 32 bit r/o Rx Runt Event Counter */
161#define XM_RXF_LNG_ERR 0x0350 /* 32 bit r/o Rx Frame too Long Error Cnt */
162#define XM_RXF_FCS_ERR 0x0354 /* 32 bit r/o Rx Frame Check Seq. Error Cnt */
163 /* 0x0358 - 0x035a: reserved */
164#define XM_RXF_CEX_ERR 0x035c /* 32 bit r/o Rx Carrier Ext Error Frame Cnt*/
165#define XM_RXP_UTIL 0x0360 /* 32 bit r/o Rx Utilization in % */
166 /* 0x0364 - 0x0366: reserved */
167#define XM_RXF_64B 0x0368 /* 32 bit r/o 64 Byte Rx Frame Counter */
168#define XM_RXF_127B 0x036c /* 32 bit r/o 65-127 Byte Rx Frame Counter */
169#define XM_RXF_255B 0x0370 /* 32 bit r/o 128-255 Byte Rx Frame Counter */
170#define XM_RXF_511B 0x0374 /* 32 bit r/o 256-511 Byte Rx Frame Counter */
171#define XM_RXF_1023B 0x0378 /* 32 bit r/o 512-1023 Byte Rx Frame Counter*/
172#define XM_RXF_MAX_SZ 0x037c /* 32 bit r/o 1024-MaxSize Byte Rx Frame Cnt*/
173 /* 0x02e8 - 0x02fe: reserved */
174
175
176/*----------------------------------------------------------------------------*/
177/*
178 * XMAC Bit Definitions
179 *
180 * If the bit access behaviour differs from the register access behaviour
181 * (r/w, r/o) this is documented after the bit number.
182 * The following bit access behaviours are used:
183 * (sc) self clearing
184 * (ro) read only
185 */
186
187/* XM_MMU_CMD 16 bit r/w MMU Command Register */
188 /* Bit 15..13: reserved */
189#define XM_MMU_PHY_RDY (1<<12) /* Bit 12: PHY Read Ready */
190#define XM_MMU_PHY_BUSY (1<<11) /* Bit 11: PHY Busy */
191#define XM_MMU_IGN_PF (1<<10) /* Bit 10: Ignore Pause Frame */
192#define XM_MMU_MAC_LB (1<<9) /* Bit 9: Enable MAC Loopback */
193 /* Bit 8: reserved */
194#define XM_MMU_FRC_COL (1<<7) /* Bit 7: Force Collision */
195#define XM_MMU_SIM_COL (1<<6) /* Bit 6: Simulate Collision */
196#define XM_MMU_NO_PRE (1<<5) /* Bit 5: No MDIO Preamble */
197#define XM_MMU_GMII_FD (1<<4) /* Bit 4: GMII uses Full Duplex */
198#define XM_MMU_RAT_CTRL (1<<3) /* Bit 3: Enable Rate Control */
199#define XM_MMU_GMII_LOOP (1<<2) /* Bit 2: PHY is in Loopback Mode */
200#define XM_MMU_ENA_RX (1<<1) /* Bit 1: Enable Receiver */
201#define XM_MMU_ENA_TX (1<<0) /* Bit 0: Enable Transmitter */
202
203
204/* XM_TX_CMD 16 bit r/w Transmit Command Register */
205 /* Bit 15..7: reserved */
206#define XM_TX_BK2BK (1<<6) /* Bit 6: Ignor Carrier Sense (Tx Bk2Bk)*/
207#define XM_TX_ENC_BYP (1<<5) /* Bit 5: Set Encoder in Bypass Mode */
208#define XM_TX_SAM_LINE (1<<4) /* Bit 4: (sc) Start utilization calculation */
209#define XM_TX_NO_GIG_MD (1<<3) /* Bit 3: Disable Carrier Extension */
210#define XM_TX_NO_PRE (1<<2) /* Bit 2: Disable Preamble Generation */
211#define XM_TX_NO_CRC (1<<1) /* Bit 1: Disable CRC Generation */
212#define XM_TX_AUTO_PAD (1<<0) /* Bit 0: Enable Automatic Padding */
213
214
215/* XM_TX_RT_LIM 16 bit r/w Transmit Retry Limit Register */
216 /* Bit 15..5: reserved */
217#define XM_RT_LIM_MSK 0x1f /* Bit 4..0: Tx Retry Limit */
218
219
220/* XM_TX_STIME 16 bit r/w Transmit Slottime Register */
221 /* Bit 15..7: reserved */
222#define XM_STIME_MSK 0x7f /* Bit 6..0: Tx Slottime bits */
223
224
225/* XM_TX_IPG 16 bit r/w Transmit Inter Packet Gap */
226 /* Bit 15..8: reserved */
227#define XM_IPG_MSK 0xff /* Bit 7..0: IPG value bits */
228
229
230/* XM_RX_CMD 16 bit r/w Receive Command Register */
231 /* Bit 15..9: reserved */
232#define XM_RX_LENERR_OK (1<<8) /* Bit 8 don't set Rx Err bit for */
233 /* inrange error packets */
234#define XM_RX_BIG_PK_OK (1<<7) /* Bit 7 don't set Rx Err bit for */
235 /* jumbo packets */
236#define XM_RX_IPG_CAP (1<<6) /* Bit 6 repl. type field with IPG */
237#define XM_RX_TP_MD (1<<5) /* Bit 5: Enable transparent Mode */
238#define XM_RX_STRIP_FCS (1<<4) /* Bit 4: Enable FCS Stripping */
239#define XM_RX_SELF_RX (1<<3) /* Bit 3: Enable Rx of own packets */
240#define XM_RX_SAM_LINE (1<<2) /* Bit 2: (sc) Start utilization calculation */
241#define XM_RX_STRIP_PAD (1<<1) /* Bit 1: Strip pad bytes of Rx frames */
242#define XM_RX_DIS_CEXT (1<<0) /* Bit 0: Disable carrier ext. check */
243
244
245/* XM_PHY_ADDR 16 bit r/w PHY Address Register */
246 /* Bit 15..5: reserved */
247#define XM_PHY_ADDR_SZ 0x1f /* Bit 4..0: PHY Address bits */
248
249
250/* XM_GP_PORT 32 bit r/w General Purpose Port Register */
251 /* Bit 31..7: reserved */
252#define XM_GP_ANIP (1L<<6) /* Bit 6: (ro) Auto-Neg. in progress */
253#define XM_GP_FRC_INT (1L<<5) /* Bit 5: (sc) Force Interrupt */
254 /* Bit 4: reserved */
255#define XM_GP_RES_MAC (1L<<3) /* Bit 3: (sc) Reset MAC and FIFOs */
256#define XM_GP_RES_STAT (1L<<2) /* Bit 2: (sc) Reset the statistics module */
257 /* Bit 1: reserved */
258#define XM_GP_INP_ASS (1L<<0) /* Bit 0: (ro) GP Input Pin asserted */
259
260
261/* XM_IMSK 16 bit r/w Interrupt Mask Register */
262/* XM_ISRC 16 bit r/o Interrupt Status Register */
263 /* Bit 15: reserved */
264#define XM_IS_LNK_AE (1<<14) /* Bit 14: Link Asynchronous Event */
265#define XM_IS_TX_ABORT (1<<13) /* Bit 13: Transmit Abort, late Col. etc */
266#define XM_IS_FRC_INT (1<<12) /* Bit 12: Force INT bit set in GP */
267#define XM_IS_INP_ASS (1<<11) /* Bit 11: Input Asserted, GP bit 0 set */
268#define XM_IS_LIPA_RC (1<<10) /* Bit 10: Link Partner requests config */
269#define XM_IS_RX_PAGE (1<<9) /* Bit 9: Page Received */
270#define XM_IS_TX_PAGE (1<<8) /* Bit 8: Next Page Loaded for Transmit */
271#define XM_IS_AND (1<<7) /* Bit 7: Auto-Negotiation Done */
272#define XM_IS_TSC_OV (1<<6) /* Bit 6: Time Stamp Counter Overflow */
273#define XM_IS_RXC_OV (1<<5) /* Bit 5: Rx Counter Event Overflow */
274#define XM_IS_TXC_OV (1<<4) /* Bit 4: Tx Counter Event Overflow */
275#define XM_IS_RXF_OV (1<<3) /* Bit 3: Receive FIFO Overflow */
276#define XM_IS_TXF_UR (1<<2) /* Bit 2: Transmit FIFO Underrun */
277#define XM_IS_TX_COMP (1<<1) /* Bit 1: Frame Tx Complete */
278#define XM_IS_RX_COMP (1<<0) /* Bit 0: Frame Rx Complete */
279
280#define XM_DEF_MSK (~(XM_IS_INP_ASS | XM_IS_LIPA_RC | XM_IS_RX_PAGE |\
281 XM_IS_AND | XM_IS_RXC_OV | XM_IS_TXC_OV | XM_IS_TXF_UR))
282
283
284/* XM_HW_CFG 16 bit r/w Hardware Config Register */
285 /* Bit 15.. 4: reserved */
286#define XM_HW_GEN_EOP (1<<3) /* Bit 3: generate End of Packet pulse */
287#define XM_HW_COM4SIG (1<<2) /* Bit 2: use Comma Detect for Sig. Det.*/
288 /* Bit 1: reserved */
289#define XM_HW_GMII_MD (1<<0) /* Bit 0: GMII Interface selected */
290
291
292/* XM_TX_LO_WM 16 bit r/w Tx FIFO Low Water Mark */
293/* XM_TX_HI_WM 16 bit r/w Tx FIFO High Water Mark */
294 /* Bit 15..10 reserved */
295#define XM_TX_WM_MSK 0x01ff /* Bit 9.. 0 Tx FIFO Watermark bits */
296
297/* XM_TX_THR 16 bit r/w Tx Request Threshold */
298/* XM_HT_THR 16 bit r/w Host Request Threshold */
299/* XM_RX_THR 16 bit r/w Rx Request Threshold */
300 /* Bit 15..11 reserved */
301#define XM_THR_MSK 0x03ff /* Bit 10.. 0 Rx/Tx Request Threshold bits */
302
303
304/* XM_TX_STAT 32 bit r/o Tx Status LIFO Register */
305#define XM_ST_VALID (1UL<<31) /* Bit 31: Status Valid */
306#define XM_ST_BYTE_CNT (0x3fffL<<17) /* Bit 30..17: Tx frame Length */
307#define XM_ST_RETRY_CNT (0x1fL<<12) /* Bit 16..12: Retry Count */
308#define XM_ST_EX_COL (1L<<11) /* Bit 11: Excessive Collisions */
309#define XM_ST_EX_DEF (1L<<10) /* Bit 10: Excessive Deferral */
310#define XM_ST_BURST (1L<<9) /* Bit 9: p. xmitted in burst md*/
311#define XM_ST_DEFER (1L<<8) /* Bit 8: packet was defered */
312#define XM_ST_BC (1L<<7) /* Bit 7: Broadcast packet */
313#define XM_ST_MC (1L<<6) /* Bit 6: Multicast packet */
314#define XM_ST_UC (1L<<5) /* Bit 5: Unicast packet */
315#define XM_ST_TX_UR (1L<<4) /* Bit 4: FIFO Underrun occured */
316#define XM_ST_CS_ERR (1L<<3) /* Bit 3: Carrier Sense Error */
317#define XM_ST_LAT_COL (1L<<2) /* Bit 2: Late Collision Error */
318#define XM_ST_MUL_COL (1L<<1) /* Bit 1: Multiple Collisions */
319#define XM_ST_SGN_COL (1L<<0) /* Bit 0: Single Collision */
320
321/* XM_RX_LO_WM 16 bit r/w Receive Low Water Mark */
322/* XM_RX_HI_WM 16 bit r/w Receive High Water Mark */
323 /* Bit 15..11: reserved */
324#define XM_RX_WM_MSK 0x03ff /* Bit 11.. 0: Rx FIFO Watermark bits */
325
326
327/* XM_DEV_ID 32 bit r/o Device ID Register */
328#define XM_DEV_OUI (0x00ffffffUL<<8) /* Bit 31..8: Device OUI */
329#define XM_DEV_REV (0x07L << 5) /* Bit 7..5: Chip Rev Num */
330
331
332/* XM_MODE 32 bit r/w Mode Register */
333 /* Bit 31..27: reserved */
334#define XM_MD_ENA_REJ (1L<<26) /* Bit 26: Enable Frame Reject */
335#define XM_MD_SPOE_E (1L<<25) /* Bit 25: Send Pause on Edge */
336 /* extern generated */
337#define XM_MD_TX_REP (1L<<24) /* Bit 24: Transmit Repeater Mode */
338#define XM_MD_SPOFF_I (1L<<23) /* Bit 23: Send Pause on FIFO full */
339 /* intern generated */
340#define XM_MD_LE_STW (1L<<22) /* Bit 22: Rx Stat Word in Little Endian */
341#define XM_MD_TX_CONT (1L<<21) /* Bit 21: Send Continuous */
342#define XM_MD_TX_PAUSE (1L<<20) /* Bit 20: (sc) Send Pause Frame */
343#define XM_MD_ATS (1L<<19) /* Bit 19: Append Time Stamp */
344#define XM_MD_SPOL_I (1L<<18) /* Bit 18: Send Pause on Low */
345 /* intern generated */
346#define XM_MD_SPOH_I (1L<<17) /* Bit 17: Send Pause on High */
347 /* intern generated */
348#define XM_MD_CAP (1L<<16) /* Bit 16: Check Address Pair */
349#define XM_MD_ENA_HASH (1L<<15) /* Bit 15: Enable Hashing */
350#define XM_MD_CSA (1L<<14) /* Bit 14: Check Station Address */
351#define XM_MD_CAA (1L<<13) /* Bit 13: Check Address Array */
352#define XM_MD_RX_MCTRL (1L<<12) /* Bit 12: Rx MAC Control Frame */
353#define XM_MD_RX_RUNT (1L<<11) /* Bit 11: Rx Runt Frames */
354#define XM_MD_RX_IRLE (1L<<10) /* Bit 10: Rx in Range Len Err Frame */
355#define XM_MD_RX_LONG (1L<<9) /* Bit 9: Rx Long Frame */
356#define XM_MD_RX_CRCE (1L<<8) /* Bit 8: Rx CRC Error Frame */
357#define XM_MD_RX_ERR (1L<<7) /* Bit 7: Rx Error Frame */
358#define XM_MD_DIS_UC (1L<<6) /* Bit 6: Disable Rx Unicast */
359#define XM_MD_DIS_MC (1L<<5) /* Bit 5: Disable Rx Multicast */
360#define XM_MD_DIS_BC (1L<<4) /* Bit 4: Disable Rx Broadcast */
361#define XM_MD_ENA_PROM (1L<<3) /* Bit 3: Enable Promiscuous */
362#define XM_MD_ENA_BE (1L<<2) /* Bit 2: Enable Big Endian */
363#define XM_MD_FTF (1L<<1) /* Bit 1: (sc) Flush Tx FIFO */
364#define XM_MD_FRF (1L<<0) /* Bit 0: (sc) Flush Rx FIFO */
365
366#define XM_PAUSE_MODE (XM_MD_SPOE_E | XM_MD_SPOL_I | XM_MD_SPOH_I)
367#define XM_DEF_MODE (XM_MD_RX_RUNT | XM_MD_RX_IRLE | XM_MD_RX_LONG |\
368 XM_MD_RX_CRCE | XM_MD_RX_ERR | XM_MD_CSA | XM_MD_CAA)
369
370/* XM_STAT_CMD 16 bit r/w Statistics Command Register */
371 /* Bit 16..6: reserved */
372#define XM_SC_SNP_RXC (1<<5) /* Bit 5: (sc) Snap Rx Counters */
373#define XM_SC_SNP_TXC (1<<4) /* Bit 4: (sc) Snap Tx Counters */
374#define XM_SC_CP_RXC (1<<3) /* Bit 3: Copy Rx Counters Continuously */
375#define XM_SC_CP_TXC (1<<2) /* Bit 2: Copy Tx Counters Continuously */
376#define XM_SC_CLR_RXC (1<<1) /* Bit 1: (sc) Clear Rx Counters */
377#define XM_SC_CLR_TXC (1<<0) /* Bit 0: (sc) Clear Tx Counters */
378
379
380/* XM_RX_CNT_EV 32 bit r/o Rx Counter Event Register */
381/* XM_RX_EV_MSK 32 bit r/w Rx Counter Event Mask */
382#define XMR_MAX_SZ_OV (1UL<<31) /* Bit 31: 1024-MaxSize Rx Cnt Ov*/
383#define XMR_1023B_OV (1L<<30) /* Bit 30: 512-1023Byte Rx Cnt Ov*/
384#define XMR_511B_OV (1L<<29) /* Bit 29: 256-511 Byte Rx Cnt Ov*/
385#define XMR_255B_OV (1L<<28) /* Bit 28: 128-255 Byte Rx Cnt Ov*/
386#define XMR_127B_OV (1L<<27) /* Bit 27: 65-127 Byte Rx Cnt Ov */
387#define XMR_64B_OV (1L<<26) /* Bit 26: 64 Byte Rx Cnt Ov */
388#define XMR_UTIL_OV (1L<<25) /* Bit 25: Rx Util Cnt Overflow */
389#define XMR_UTIL_UR (1L<<24) /* Bit 24: Rx Util Cnt Underrun */
390#define XMR_CEX_ERR_OV (1L<<23) /* Bit 23: CEXT Err Cnt Ov */
391 /* Bit 22: reserved */
392#define XMR_FCS_ERR_OV (1L<<21) /* Bit 21: Rx FCS Error Cnt Ov */
393#define XMR_LNG_ERR_OV (1L<<20) /* Bit 20: Rx too Long Err Cnt Ov*/
394#define XMR_RUNT_OV (1L<<19) /* Bit 19: Runt Event Cnt Ov */
395#define XMR_SHT_ERR_OV (1L<<18) /* Bit 18: Rx Short Ev Err Cnt Ov*/
396#define XMR_SYM_ERR_OV (1L<<17) /* Bit 17: Rx Sym Err Cnt Ov */
397 /* Bit 16: reserved */
398#define XMR_CAR_ERR_OV (1L<<15) /* Bit 15: Rx Carr Ev Err Cnt Ov */
399#define XMR_JAB_PKT_OV (1L<<14) /* Bit 14: Rx Jabb Packet Cnt Ov */
400#define XMR_FIFO_OV (1L<<13) /* Bit 13: Rx FIFO Ov Ev Cnt Ov */
401#define XMR_FRA_ERR_OV (1L<<12) /* Bit 12: Rx Framing Err Cnt Ov */
402#define XMR_FMISS_OV (1L<<11) /* Bit 11: Rx Missed Ev Cnt Ov */
403#define XMR_BURST (1L<<10) /* Bit 10: Rx Burst Event Cnt Ov */
404#define XMR_INV_MOC (1L<<9) /* Bit 9: Rx with inv. MAC OC Ov*/
405#define XMR_INV_MP (1L<<8) /* Bit 8: Rx inv Pause Frame Ov */
406#define XMR_MCTRL_OV (1L<<7) /* Bit 7: Rx MAC Ctrl-F Cnt Ov */
407#define XMR_MPAUSE_OV (1L<<6) /* Bit 6: Rx Pause MAC Ctrl-F Ov*/
408#define XMR_UC_OK_OV (1L<<5) /* Bit 5: Rx Unicast Frame CntOv*/
409#define XMR_MC_OK_OV (1L<<4) /* Bit 4: Rx Multicast Cnt Ov */
410#define XMR_BC_OK_OV (1L<<3) /* Bit 3: Rx Broadcast Cnt Ov */
411#define XMR_OK_LO_OV (1L<<2) /* Bit 2: Octets Rx OK Low CntOv*/
412#define XMR_OK_HI_OV (1L<<1) /* Bit 1: Octets Rx OK Hi Cnt Ov*/
413#define XMR_OK_OV (1L<<0) /* Bit 0: Frames Received Ok Ov */
414
415#define XMR_DEF_MSK (XMR_OK_LO_OV | XMR_OK_HI_OV)
416
417/* XM_TX_CNT_EV 32 bit r/o Tx Counter Event Register */
418/* XM_TX_EV_MSK 32 bit r/w Tx Counter Event Mask */
419 /* Bit 31..26: reserved */
420#define XMT_MAX_SZ_OV (1L<<25) /* Bit 25: 1024-MaxSize Tx Cnt Ov*/
421#define XMT_1023B_OV (1L<<24) /* Bit 24: 512-1023Byte Tx Cnt Ov*/
422#define XMT_511B_OV (1L<<23) /* Bit 23: 256-511 Byte Tx Cnt Ov*/
423#define XMT_255B_OV (1L<<22) /* Bit 22: 128-255 Byte Tx Cnt Ov*/
424#define XMT_127B_OV (1L<<21) /* Bit 21: 65-127 Byte Tx Cnt Ov */
425#define XMT_64B_OV (1L<<20) /* Bit 20: 64 Byte Tx Cnt Ov */
426#define XMT_UTIL_OV (1L<<19) /* Bit 19: Tx Util Cnt Overflow */
427#define XMT_UTIL_UR (1L<<18) /* Bit 18: Tx Util Cnt Underrun */
428#define XMT_CS_ERR_OV (1L<<17) /* Bit 17: Tx Carr Sen Err Cnt Ov*/
429#define XMT_FIFO_UR_OV (1L<<16) /* Bit 16: Tx FIFO Ur Ev Cnt Ov */
430#define XMT_EX_DEF_OV (1L<<15) /* Bit 15: Tx Ex Deferall Cnt Ov */
431#define XMT_DEF (1L<<14) /* Bit 14: Tx Deferred Cnt Ov */
432#define XMT_LAT_COL_OV (1L<<13) /* Bit 13: Tx Late Col Cnt Ov */
433#define XMT_ABO_COL_OV (1L<<12) /* Bit 12: Tx abo dueto Ex Col Ov*/
434#define XMT_MUL_COL_OV (1L<<11) /* Bit 11: Tx Mult Col Cnt Ov */
435#define XMT_SNG_COL (1L<<10) /* Bit 10: Tx Single Col Cnt Ov */
436#define XMT_MCTRL_OV (1L<<9) /* Bit 9: Tx MAC Ctrl Counter Ov*/
437#define XMT_MPAUSE (1L<<8) /* Bit 8: Tx Pause MAC Ctrl-F Ov*/
438#define XMT_BURST (1L<<7) /* Bit 7: Tx Burst Event Cnt Ov */
439#define XMT_LONG (1L<<6) /* Bit 6: Tx Long Frame Cnt Ov */
440#define XMT_UC_OK_OV (1L<<5) /* Bit 5: Tx Unicast Cnt Ov */
441#define XMT_MC_OK_OV (1L<<4) /* Bit 4: Tx Multicast Cnt Ov */
442#define XMT_BC_OK_OV (1L<<3) /* Bit 3: Tx Broadcast Cnt Ov */
443#define XMT_OK_LO_OV (1L<<2) /* Bit 2: Octets Tx OK Low CntOv*/
444#define XMT_OK_HI_OV (1L<<1) /* Bit 1: Octets Tx OK Hi Cnt Ov*/
445#define XMT_OK_OV (1L<<0) /* Bit 0: Frames Tx Ok Ov */
446
447#define XMT_DEF_MSK (XMT_OK_LO_OV | XMT_OK_HI_OV)
448
449/*
450 * Receive Frame Status Encoding
451 */
452#define XMR_FS_LEN (0x3fffUL<<18) /* Bit 31..18: Rx Frame Length */
453#define XMR_FS_2L_VLAN (1L<<17) /* Bit 17: tagged wh 2Lev VLAN ID*/
454#define XMR_FS_1L_VLAN (1L<<16) /* Bit 16: tagged wh 1Lev VLAN ID*/
455#define XMR_FS_BC (1L<<15) /* Bit 15: Broadcast Frame */
456#define XMR_FS_MC (1L<<14) /* Bit 14: Multicast Frame */
457#define XMR_FS_UC (1L<<13) /* Bit 13: Unicast Frame */
458 /* Bit 12: reserved */
459#define XMR_FS_BURST (1L<<11) /* Bit 11: Burst Mode */
460#define XMR_FS_CEX_ERR (1L<<10) /* Bit 10: Carrier Ext. Error */
461#define XMR_FS_802_3 (1L<<9) /* Bit 9: 802.3 Frame */
462#define XMR_FS_COL_ERR (1L<<8) /* Bit 8: Collision Error */
463#define XMR_FS_CAR_ERR (1L<<7) /* Bit 7: Carrier Event Error */
464#define XMR_FS_LEN_ERR (1L<<6) /* Bit 6: In-Range Length Error */
465#define XMR_FS_FRA_ERR (1L<<5) /* Bit 5: Framing Error */
466#define XMR_FS_RUNT (1L<<4) /* Bit 4: Runt Frame */
467#define XMR_FS_LNG_ERR (1L<<3) /* Bit 3: Giant (Jumbo) Frame */
468#define XMR_FS_FCS_ERR (1L<<2) /* Bit 2: Frame Check Sequ Err */
469#define XMR_FS_ERR (1L<<1) /* Bit 1: Frame Error */
470#define XMR_FS_MCTRL (1L<<0) /* Bit 0: MAC Control Packet */
471
472/*
473 * XMR_FS_ERR will be set if
474 * XMR_FS_FCS_ERR, XMR_FS_LNG_ERR, XMR_FS_RUNT,
475 * XMR_FS_FRA_ERR, XMR_FS_LEN_ERR, or XMR_FS_CEX_ERR
476 * is set. XMR_FS_LNG_ERR and XMR_FS_LEN_ERR will issue
477 * XMR_FS_ERR unless the corresponding bit in the Receive Command
478 * Register is set.
479 */
480#define XMR_FS_ANY_ERR XMR_FS_ERR
481
482/*----------------------------------------------------------------------------*/
483/*
484 * XMAC-PHY Registers, indirect addressed over the XMAC
485 */
486#define PHY_XMAC_CTRL 0x00 /* 16 bit r/w PHY Control Register */
487#define PHY_XMAC_STAT 0x01 /* 16 bit r/w PHY Status Register */
488#define PHY_XMAC_ID0 0x02 /* 16 bit r/o PHY ID0 Register */
489#define PHY_XMAC_ID1 0x03 /* 16 bit r/o PHY ID1 Register */
490#define PHY_XMAC_AUNE_ADV 0x04 /* 16 bit r/w Auto-Neg. Advertisement */
491#define PHY_XMAC_AUNE_LP 0x05 /* 16 bit r/o Link Partner Abi Reg */
492#define PHY_XMAC_AUNE_EXP 0x06 /* 16 bit r/o Auto-Neg. Expansion Reg */
493#define PHY_XMAC_NEPG 0x07 /* 16 bit r/w Next Page Register */
494#define PHY_XMAC_NEPG_LP 0x08 /* 16 bit r/o Next Page Link Partner */
495 /* 0x09 - 0x0e: reserved */
496#define PHY_XMAC_EXT_STAT 0x0f /* 16 bit r/o Ext Status Register */
497#define PHY_XMAC_RES_ABI 0x10 /* 16 bit r/o PHY Resolved Ability */
498
499/*----------------------------------------------------------------------------*/
500/*
501 * Broadcom-PHY Registers, indirect addressed over XMAC
502 */
503#define PHY_BCOM_CTRL 0x00 /* 16 bit r/w PHY Control Register */
504#define PHY_BCOM_STAT 0x01 /* 16 bit r/o PHY Status Register */
505#define PHY_BCOM_ID0 0x02 /* 16 bit r/o PHY ID0 Register */
506#define PHY_BCOM_ID1 0x03 /* 16 bit r/o PHY ID1 Register */
507#define PHY_BCOM_AUNE_ADV 0x04 /* 16 bit r/w Auto-Neg. Advertisement */
508#define PHY_BCOM_AUNE_LP 0x05 /* 16 bit r/o Link Part Ability Reg */
509#define PHY_BCOM_AUNE_EXP 0x06 /* 16 bit r/o Auto-Neg. Expansion Reg */
510#define PHY_BCOM_NEPG 0x07 /* 16 bit r/w Next Page Register */
511#define PHY_BCOM_NEPG_LP 0x08 /* 16 bit r/o Next Page Link Partner */
512 /* Broadcom-specific registers */
513#define PHY_BCOM_1000T_CTRL 0x09 /* 16 bit r/w 1000Base-T Ctrl Reg */
514#define PHY_BCOM_1000T_STAT 0x0a /* 16 bit r/o 1000Base-T Status Reg */
515 /* 0x0b - 0x0e: reserved */
516#define PHY_BCOM_EXT_STAT 0x0f /* 16 bit r/o Extended Status Reg */
517#define PHY_BCOM_P_EXT_CTRL 0x10 /* 16 bit r/w PHY Extended Ctrl Reg */
518#define PHY_BCOM_P_EXT_STAT 0x11 /* 16 bit r/o PHY Extended Stat Reg */
519#define PHY_BCOM_RE_CTR 0x12 /* 16 bit r/w Receive Error Counter */
520#define PHY_BCOM_FC_CTR 0x13 /* 16 bit r/w False Carrier Sense Cnt */
521#define PHY_BCOM_RNO_CTR 0x14 /* 16 bit r/w Receiver NOT_OK Cnt */
522 /* 0x15 - 0x17: reserved */
523#define PHY_BCOM_AUX_CTRL 0x18 /* 16 bit r/w Auxiliary Control Reg */
524#define PHY_BCOM_AUX_STAT 0x19 /* 16 bit r/o Auxiliary Stat Summary */
525#define PHY_BCOM_INT_STAT 0x1a /* 16 bit r/o Interrupt Status Reg */
526#define PHY_BCOM_INT_MASK 0x1b /* 16 bit r/w Interrupt Mask Reg */
527 /* 0x1c: reserved */
528 /* 0x1d - 0x1f: test registers */
529
530/*----------------------------------------------------------------------------*/
531/*
532 * Marvel-PHY Registers, indirect addressed over GMAC
533 */
534#define PHY_MARV_CTRL 0x00 /* 16 bit r/w PHY Control Register */
535#define PHY_MARV_STAT 0x01 /* 16 bit r/o PHY Status Register */
536#define PHY_MARV_ID0 0x02 /* 16 bit r/o PHY ID0 Register */
537#define PHY_MARV_ID1 0x03 /* 16 bit r/o PHY ID1 Register */
538#define PHY_MARV_AUNE_ADV 0x04 /* 16 bit r/w Auto-Neg. Advertisement */
539#define PHY_MARV_AUNE_LP 0x05 /* 16 bit r/o Link Part Ability Reg */
540#define PHY_MARV_AUNE_EXP 0x06 /* 16 bit r/o Auto-Neg. Expansion Reg */
541#define PHY_MARV_NEPG 0x07 /* 16 bit r/w Next Page Register */
542#define PHY_MARV_NEPG_LP 0x08 /* 16 bit r/o Next Page Link Partner */
543 /* Marvel-specific registers */
544#define PHY_MARV_1000T_CTRL 0x09 /* 16 bit r/w 1000Base-T Ctrl Reg */
545#define PHY_MARV_1000T_STAT 0x0a /* 16 bit r/o 1000Base-T Status Reg */
546 /* 0x0b - 0x0e: reserved */
547#define PHY_MARV_EXT_STAT 0x0f /* 16 bit r/o Extended Status Reg */
548#define PHY_MARV_PHY_CTRL 0x10 /* 16 bit r/w PHY Specific Ctrl Reg */
549#define PHY_MARV_PHY_STAT 0x11 /* 16 bit r/o PHY Specific Stat Reg */
550#define PHY_MARV_INT_MASK 0x12 /* 16 bit r/w Interrupt Mask Reg */
551#define PHY_MARV_INT_STAT 0x13 /* 16 bit r/o Interrupt Status Reg */
552#define PHY_MARV_EXT_CTRL 0x14 /* 16 bit r/w Ext. PHY Specific Ctrl */
553#define PHY_MARV_RXE_CNT 0x15 /* 16 bit r/w Receive Error Counter */
554#define PHY_MARV_EXT_ADR 0x16 /* 16 bit r/w Ext. Ad. for Cable Diag. */
555 /* 0x17: reserved */
556#define PHY_MARV_LED_CTRL 0x18 /* 16 bit r/w LED Control Reg */
557#define PHY_MARV_LED_OVER 0x19 /* 16 bit r/w Manual LED Override Reg */
558#define PHY_MARV_EXT_CTRL_2 0x1a /* 16 bit r/w Ext. PHY Specific Ctrl 2 */
559#define PHY_MARV_EXT_P_STAT 0x1b /* 16 bit r/w Ext. PHY Spec. Stat Reg */
560#define PHY_MARV_CABLE_DIAG 0x1c /* 16 bit r/o Cable Diagnostic Reg */
561 /* 0x1d - 0x1f: reserved */
562
563/*----------------------------------------------------------------------------*/
564/*
565 * Level One-PHY Registers, indirect addressed over XMAC
566 */
567#define PHY_LONE_CTRL 0x00 /* 16 bit r/w PHY Control Register */
568#define PHY_LONE_STAT 0x01 /* 16 bit r/o PHY Status Register */
569#define PHY_LONE_ID0 0x02 /* 16 bit r/o PHY ID0 Register */
570#define PHY_LONE_ID1 0x03 /* 16 bit r/o PHY ID1 Register */
571#define PHY_LONE_AUNE_ADV 0x04 /* 16 bit r/w Auto-Neg. Advertisement */
572#define PHY_LONE_AUNE_LP 0x05 /* 16 bit r/o Link Part Ability Reg */
573#define PHY_LONE_AUNE_EXP 0x06 /* 16 bit r/o Auto-Neg. Expansion Reg */
574#define PHY_LONE_NEPG 0x07 /* 16 bit r/w Next Page Register */
575#define PHY_LONE_NEPG_LP 0x08 /* 16 bit r/o Next Page Link Partner */
576 /* Level One-specific registers */
577#define PHY_LONE_1000T_CTRL 0x09 /* 16 bit r/w 1000Base-T Control Reg*/
578#define PHY_LONE_1000T_STAT 0x0a /* 16 bit r/o 1000Base-T Status Reg */
579 /* 0x0b -0x0e: reserved */
580#define PHY_LONE_EXT_STAT 0x0f /* 16 bit r/o Extended Status Reg */
581#define PHY_LONE_PORT_CFG 0x10 /* 16 bit r/w Port Configuration Reg*/
582#define PHY_LONE_Q_STAT 0x11 /* 16 bit r/o Quick Status Reg */
583#define PHY_LONE_INT_ENAB 0x12 /* 16 bit r/w Interrupt Enable Reg */
584#define PHY_LONE_INT_STAT 0x13 /* 16 bit r/o Interrupt Status Reg */
585#define PHY_LONE_LED_CFG 0x14 /* 16 bit r/w LED Configuration Reg */
586#define PHY_LONE_PORT_CTRL 0x15 /* 16 bit r/w Port Control Reg */
587#define PHY_LONE_CIM 0x16 /* 16 bit r/o CIM Reg */
588 /* 0x17 -0x1c: reserved */
589
590/*----------------------------------------------------------------------------*/
591/*
592 * National-PHY Registers, indirect addressed over XMAC
593 */
594#define PHY_NAT_CTRL 0x00 /* 16 bit r/w PHY Control Register */
595#define PHY_NAT_STAT 0x01 /* 16 bit r/w PHY Status Register */
596#define PHY_NAT_ID0 0x02 /* 16 bit r/o PHY ID0 Register */
597#define PHY_NAT_ID1 0x03 /* 16 bit r/o PHY ID1 Register */
598#define PHY_NAT_AUNE_ADV 0x04 /* 16 bit r/w Auto-Neg. Advertisement */
599#define PHY_NAT_AUNE_LP 0x05 /* 16 bit r/o Link Partner Ability Reg */
600#define PHY_NAT_AUNE_EXP 0x06 /* 16 bit r/o Auto-Neg. Expansion Reg */
601#define PHY_NAT_NEPG 0x07 /* 16 bit r/w Next Page Register */
602#define PHY_NAT_NEPG_LP 0x08 /* 16 bit r/o Next Page Link Partner Reg */
603 /* National-specific registers */
604#define PHY_NAT_1000T_CTRL 0x09 /* 16 bit r/w 1000Base-T Control Reg */
605#define PHY_NAT_1000T_STAT 0x0a /* 16 bit r/o 1000Base-T Status Reg */
606 /* 0x0b -0x0e: reserved */
607#define PHY_NAT_EXT_STAT 0x0f /* 16 bit r/o Extended Status Register */
608#define PHY_NAT_EXT_CTRL1 0x10 /* 16 bit r/o Extended Control Reg1 */
609#define PHY_NAT_Q_STAT1 0x11 /* 16 bit r/o Quick Status Reg1 */
610#define PHY_NAT_10B_OP 0x12 /* 16 bit r/o 10Base-T Operations Reg */
611#define PHY_NAT_EXT_CTRL2 0x13 /* 16 bit r/o Extended Control Reg1 */
612#define PHY_NAT_Q_STAT2 0x14 /* 16 bit r/o Quick Status Reg2 */
613 /* 0x15 -0x18: reserved */
614#define PHY_NAT_PHY_ADDR 0x19 /* 16 bit r/o PHY Address Register */
615
616
617/*----------------------------------------------------------------------------*/
618
619/*
620 * PHY bit definitions
621 * Bits defined as PHY_X_..., PHY_B_..., PHY_L_... or PHY_N_... are
622 * XMAC/Broadcom/LevelOne/National/Marvell-specific.
623 * All other are general.
624 */
625
626/***** PHY_XMAC_CTRL 16 bit r/w PHY Control Register *****/
627/***** PHY_BCOM_CTRL 16 bit r/w PHY Control Register *****/
628/***** PHY_MARV_CTRL 16 bit r/w PHY Status Register *****/
629/***** PHY_LONE_CTRL 16 bit r/w PHY Control Register *****/
630#define PHY_CT_RESET (1<<15) /* Bit 15: (sc) clear all PHY related regs */
631#define PHY_CT_LOOP (1<<14) /* Bit 14: enable Loopback over PHY */
632#define PHY_CT_SPS_LSB (1<<13) /* Bit 13: (BC,L1) Speed select, lower bit */
633#define PHY_CT_ANE (1<<12) /* Bit 12: Auto-Negotiation Enabled */
634#define PHY_CT_PDOWN (1<<11) /* Bit 11: (BC,L1) Power Down Mode */
635#define PHY_CT_ISOL (1<<10) /* Bit 10: (BC,L1) Isolate Mode */
636#define PHY_CT_RE_CFG (1<<9) /* Bit 9: (sc) Restart Auto-Negotiation */
637#define PHY_CT_DUP_MD (1<<8) /* Bit 8: Duplex Mode */
638#define PHY_CT_COL_TST (1<<7) /* Bit 7: (BC,L1) Collision Test enabled */
639#define PHY_CT_SPS_MSB (1<<6) /* Bit 6: (BC,L1) Speed select, upper bit */
640 /* Bit 5..0: reserved */
641
642#define PHY_CT_SP1000 PHY_CT_SPS_MSB /* enable speed of 1000 Mbps */
643#define PHY_CT_SP100 PHY_CT_SPS_LSB /* enable speed of 100 Mbps */
644#define PHY_CT_SP10 (0) /* enable speed of 10 Mbps */
645
646
647/***** PHY_XMAC_STAT 16 bit r/w PHY Status Register *****/
648/***** PHY_BCOM_STAT 16 bit r/w PHY Status Register *****/
649/***** PHY_MARV_STAT 16 bit r/w PHY Status Register *****/
650/***** PHY_LONE_STAT 16 bit r/w PHY Status Register *****/
651 /* Bit 15..9: reserved */
652 /* (BC/L1) 100/10 Mbps cap bits ignored*/
653#define PHY_ST_EXT_ST (1<<8) /* Bit 8: Extended Status Present */
654 /* Bit 7: reserved */
655#define PHY_ST_PRE_SUP (1<<6) /* Bit 6: (BC/L1) preamble suppression */
656#define PHY_ST_AN_OVER (1<<5) /* Bit 5: Auto-Negotiation Over */
657#define PHY_ST_REM_FLT (1<<4) /* Bit 4: Remote Fault Condition Occured */
658#define PHY_ST_AN_CAP (1<<3) /* Bit 3: Auto-Negotiation Capability */
659#define PHY_ST_LSYNC (1<<2) /* Bit 2: Link Synchronized */
660#define PHY_ST_JAB_DET (1<<1) /* Bit 1: (BC/L1) Jabber Detected */
661#define PHY_ST_EXT_REG (1<<0) /* Bit 0: Extended Register available */
662
663
664/***** PHY_XMAC_ID1 16 bit r/o PHY ID1 Register */
665/***** PHY_BCOM_ID1 16 bit r/o PHY ID1 Register */
666/***** PHY_MARV_ID1 16 bit r/o PHY ID1 Register */
667/***** PHY_LONE_ID1 16 bit r/o PHY ID1 Register */
668#define PHY_I1_OUI_MSK (0x3f<<10) /* Bit 15..10: Organization Unique ID */
669#define PHY_I1_MOD_NUM (0x3f<<4) /* Bit 9.. 4: Model Number */
670#define PHY_I1_REV_MSK 0x0f /* Bit 3.. 0: Revision Number */
671
672/* different Broadcom PHY Ids */
673#define PHY_BCOM_ID1_A1 0x6041
674#define PHY_BCOM_ID1_B2 0x6043
675#define PHY_BCOM_ID1_C0 0x6044
676#define PHY_BCOM_ID1_C5 0x6047
677
678
679/***** PHY_XMAC_AUNE_ADV 16 bit r/w Auto-Negotiation Advertisement *****/
680/***** PHY_XMAC_AUNE_LP 16 bit r/o Link Partner Ability Reg *****/
681#define PHY_AN_NXT_PG (1<<15) /* Bit 15: Request Next Page */
682#define PHY_X_AN_ACK (1<<14) /* Bit 14: (ro) Acknowledge Received */
683#define PHY_X_AN_RFB (3<<12) /* Bit 13..12: Remote Fault Bits */
684 /* Bit 11.. 9: reserved */
685#define PHY_X_AN_PAUSE (3<<7) /* Bit 8.. 7: Pause Bits */
686#define PHY_X_AN_HD (1<<6) /* Bit 6: Half Duplex */
687#define PHY_X_AN_FD (1<<5) /* Bit 5: Full Duplex */
688 /* Bit 4.. 0: reserved */
689
690/***** PHY_BCOM_AUNE_ADV 16 bit r/w Auto-Negotiation Advertisement *****/
691/***** PHY_BCOM_AUNE_LP 16 bit r/o Link Partner Ability Reg *****/
692/* PHY_AN_NXT_PG (see XMAC) Bit 15: Request Next Page */
693 /* Bit 14: reserved */
694#define PHY_B_AN_RF (1<<13) /* Bit 13: Remote Fault */
695 /* Bit 12: reserved */
696#define PHY_B_AN_ASP (1<<11) /* Bit 11: Asymmetric Pause */
697#define PHY_B_AN_PC (1<<10) /* Bit 10: Pause Capable */
698 /* Bit 9..5: 100/10 BT cap bits ingnored */
699#define PHY_B_AN_SEL 0x1f /* Bit 4..0: Selector Field, 00001=Ethernet*/
700
701/***** PHY_LONE_AUNE_ADV 16 bit r/w Auto-Negotiation Advertisement *****/
702/***** PHY_LONE_AUNE_LP 16 bit r/o Link Partner Ability Reg *****/
703/* PHY_AN_NXT_PG (see XMAC) Bit 15: Request Next Page */
704 /* Bit 14: reserved */
705#define PHY_L_AN_RF (1<<13) /* Bit 13: Remote Fault */
706 /* Bit 12: reserved */
707#define PHY_L_AN_ASP (1<<11) /* Bit 11: Asymmetric Pause */
708#define PHY_L_AN_PC (1<<10) /* Bit 10: Pause Capable */
709 /* Bit 9..5: 100/10 BT cap bits ingnored */
710#define PHY_L_AN_SEL 0x1f /* Bit 4..0: Selector Field, 00001=Ethernet*/
711
712/***** PHY_NAT_AUNE_ADV 16 bit r/w Auto-Negotiation Advertisement *****/
713/***** PHY_NAT_AUNE_LP 16 bit r/o Link Partner Ability Reg *****/
714/* PHY_AN_NXT_PG (see XMAC) Bit 15: Request Next Page */
715 /* Bit 14: reserved */
716#define PHY_N_AN_RF (1<<13) /* Bit 13: Remote Fault */
717 /* Bit 12: reserved */
718#define PHY_N_AN_100F (1<<11) /* Bit 11: 100Base-T2 FD Support */
719#define PHY_N_AN_100H (1<<10) /* Bit 10: 100Base-T2 HD Support */
720 /* Bit 9..5: 100/10 BT cap bits ingnored */
721#define PHY_N_AN_SEL 0x1f /* Bit 4..0: Selector Field, 00001=Ethernet*/
722
723/* field type definition for PHY_x_AN_SEL */
724#define PHY_SEL_TYPE 0x01 /* 00001 = Ethernet */
725
726/***** PHY_XMAC_AUNE_EXP 16 bit r/o Auto-Negotiation Expansion Reg *****/
727 /* Bit 15..4: reserved */
728#define PHY_ANE_LP_NP (1<<3) /* Bit 3: Link Partner can Next Page */
729#define PHY_ANE_LOC_NP (1<<2) /* Bit 2: Local PHY can Next Page */
730#define PHY_ANE_RX_PG (1<<1) /* Bit 1: Page Received */
731 /* Bit 0: reserved */
732
733/***** PHY_BCOM_AUNE_EXP 16 bit r/o Auto-Negotiation Expansion Reg *****/
734/***** PHY_LONE_AUNE_EXP 16 bit r/o Auto-Negotiation Expansion Reg *****/
735/***** PHY_MARV_AUNE_EXP 16 bit r/o Auto-Negotiation Expansion Reg *****/
736 /* Bit 15..5: reserved */
737#define PHY_ANE_PAR_DF (1<<4) /* Bit 4: Parallel Detection Fault */
738/* PHY_ANE_LP_NP (see XMAC) Bit 3: Link Partner can Next Page */
739/* PHY_ANE_LOC_NP (see XMAC) Bit 2: Local PHY can Next Page */
740/* PHY_ANE_RX_PG (see XMAC) Bit 1: Page Received */
741#define PHY_ANE_LP_CAP (1<<0) /* Bit 0: Link Partner Auto-Neg. Cap. */
742
743/***** PHY_XMAC_NEPG 16 bit r/w Next Page Register *****/
744/***** PHY_BCOM_NEPG 16 bit r/w Next Page Register *****/
745/***** PHY_LONE_NEPG 16 bit r/w Next Page Register *****/
746/***** PHY_XMAC_NEPG_LP 16 bit r/o Next Page Link Partner *****/
747/***** PHY_BCOM_NEPG_LP 16 bit r/o Next Page Link Partner *****/
748/***** PHY_LONE_NEPG_LP 16 bit r/o Next Page Link Partner *****/
749#define PHY_NP_MORE (1<<15) /* Bit 15: More, Next Pages to follow */
750#define PHY_NP_ACK1 (1<<14) /* Bit 14: (ro) Ack1, for receiving a message */
751#define PHY_NP_MSG_VAL (1<<13) /* Bit 13: Message Page valid */
752#define PHY_NP_ACK2 (1<<12) /* Bit 12: Ack2, comply with msg content */
753#define PHY_NP_TOG (1<<11) /* Bit 11: Toggle Bit, ensure sync */
754#define PHY_NP_MSG 0x07ff /* Bit 10..0: Message from/to Link Partner */
755
756/*
757 * XMAC-Specific
758 */
759/***** PHY_XMAC_EXT_STAT 16 bit r/w Extended Status Register *****/
760#define PHY_X_EX_FD (1<<15) /* Bit 15: Device Supports Full Duplex */
761#define PHY_X_EX_HD (1<<14) /* Bit 14: Device Supports Half Duplex */
762 /* Bit 13..0: reserved */
763
764/***** PHY_XMAC_RES_ABI 16 bit r/o PHY Resolved Ability *****/
765 /* Bit 15..9: reserved */
766#define PHY_X_RS_PAUSE (3<<7) /* Bit 8..7: selected Pause Mode */
767#define PHY_X_RS_HD (1<<6) /* Bit 6: Half Duplex Mode selected */
768#define PHY_X_RS_FD (1<<5) /* Bit 5: Full Duplex Mode selected */
769#define PHY_X_RS_ABLMIS (1<<4) /* Bit 4: duplex or pause cap mismatch */
770#define PHY_X_RS_PAUMIS (1<<3) /* Bit 3: pause capability mismatch */
771 /* Bit 2..0: reserved */
772/*
773 * Remote Fault Bits (PHY_X_AN_RFB) encoding
774 */
775#define X_RFB_OK (0<<12) /* Bit 13..12 No errors, Link OK */
776#define X_RFB_LF (1<<12) /* Bit 13..12 Link Failure */
777#define X_RFB_OFF (2<<12) /* Bit 13..12 Offline */
778#define X_RFB_AN_ERR (3<<12) /* Bit 13..12 Auto-Negotiation Error */
779
780/*
781 * Pause Bits (PHY_X_AN_PAUSE and PHY_X_RS_PAUSE) encoding
782 */
783#define PHY_X_P_NO_PAUSE (0<<7) /* Bit 8..7: no Pause Mode */
784#define PHY_X_P_SYM_MD (1<<7) /* Bit 8..7: symmetric Pause Mode */
785#define PHY_X_P_ASYM_MD (2<<7) /* Bit 8..7: asymmetric Pause Mode */
786#define PHY_X_P_BOTH_MD (3<<7) /* Bit 8..7: both Pause Mode */
787
788
789/*
790 * Broadcom-Specific
791 */
792/***** PHY_BCOM_1000T_CTRL 16 bit r/w 1000Base-T Control Reg *****/
793#define PHY_B_1000C_TEST (7<<13) /* Bit 15..13: Test Modes */
794#define PHY_B_1000C_MSE (1<<12) /* Bit 12: Master/Slave Enable */
795#define PHY_B_1000C_MSC (1<<11) /* Bit 11: M/S Configuration */
796#define PHY_B_1000C_RD (1<<10) /* Bit 10: Repeater/DTE */
797#define PHY_B_1000C_AFD (1<<9) /* Bit 9: Advertise Full Duplex */
798#define PHY_B_1000C_AHD (1<<8) /* Bit 8: Advertise Half Duplex */
799 /* Bit 7..0: reserved */
800
801/***** PHY_BCOM_1000T_STAT 16 bit r/o 1000Base-T Status Reg *****/
802/***** PHY_MARV_1000T_STAT 16 bit r/o 1000Base-T Status Reg *****/
803#define PHY_B_1000S_MSF (1<<15) /* Bit 15: Master/Slave Fault */
804#define PHY_B_1000S_MSR (1<<14) /* Bit 14: Master/Slave Result */
805#define PHY_B_1000S_LRS (1<<13) /* Bit 13: Local Receiver Status */
806#define PHY_B_1000S_RRS (1<<12) /* Bit 12: Remote Receiver Status */
807#define PHY_B_1000S_LP_FD (1<<11) /* Bit 11: Link Partner can FD */
808#define PHY_B_1000S_LP_HD (1<<10) /* Bit 10: Link Partner can HD */
809 /* Bit 9..8: reserved */
810#define PHY_B_1000S_IEC 0xff /* Bit 7..0: Idle Error Count */
811
812/***** PHY_BCOM_EXT_STAT 16 bit r/o Extended Status Register *****/
813#define PHY_B_ES_X_FD_CAP (1<<15) /* Bit 15: 1000Base-X FD capable */
814#define PHY_B_ES_X_HD_CAP (1<<14) /* Bit 14: 1000Base-X HD capable */
815#define PHY_B_ES_T_FD_CAP (1<<13) /* Bit 13: 1000Base-T FD capable */
816#define PHY_B_ES_T_HD_CAP (1<<12) /* Bit 12: 1000Base-T HD capable */
817 /* Bit 11..0: reserved */
818
819/***** PHY_BCOM_P_EXT_CTRL 16 bit r/w PHY Extended Control Reg *****/
820#define PHY_B_PEC_MAC_PHY (1<<15) /* Bit 15: 10BIT/GMI-Interface */
821#define PHY_B_PEC_DIS_CROSS (1<<14) /* Bit 14: Disable MDI Crossover */
822#define PHY_B_PEC_TX_DIS (1<<13) /* Bit 13: Tx output Disabled */
823#define PHY_B_PEC_INT_DIS (1<<12) /* Bit 12: Interrupts Disabled */
824#define PHY_B_PEC_F_INT (1<<11) /* Bit 11: Force Interrupt */
825#define PHY_B_PEC_BY_45 (1<<10) /* Bit 10: Bypass 4B5B-Decoder */
826#define PHY_B_PEC_BY_SCR (1<<9) /* Bit 9: Bypass Scrambler */
827#define PHY_B_PEC_BY_MLT3 (1<<8) /* Bit 8: Bypass MLT3 Encoder */
828#define PHY_B_PEC_BY_RXA (1<<7) /* Bit 7: Bypass Rx Alignm. */
829#define PHY_B_PEC_RES_SCR (1<<6) /* Bit 6: Reset Scrambler */
830#define PHY_B_PEC_EN_LTR (1<<5) /* Bit 5: Ena LED Traffic Mode */
831#define PHY_B_PEC_LED_ON (1<<4) /* Bit 4: Force LED's on */
832#define PHY_B_PEC_LED_OFF (1<<3) /* Bit 3: Force LED's off */
833#define PHY_B_PEC_EX_IPG (1<<2) /* Bit 2: Extend Tx IPG Mode */
834#define PHY_B_PEC_3_LED (1<<1) /* Bit 1: Three Link LED mode */
835#define PHY_B_PEC_HIGH_LA (1<<0) /* Bit 0: GMII FIFO Elasticy */
836
837/***** PHY_BCOM_P_EXT_STAT 16 bit r/o PHY Extended Status Reg *****/
838 /* Bit 15..14: reserved */
839#define PHY_B_PES_CROSS_STAT (1<<13) /* Bit 13: MDI Crossover Status */
840#define PHY_B_PES_INT_STAT (1<<12) /* Bit 12: Interrupt Status */
841#define PHY_B_PES_RRS (1<<11) /* Bit 11: Remote Receiver Stat. */
842#define PHY_B_PES_LRS (1<<10) /* Bit 10: Local Receiver Stat. */
843#define PHY_B_PES_LOCKED (1<<9) /* Bit 9: Locked */
844#define PHY_B_PES_LS (1<<8) /* Bit 8: Link Status */
845#define PHY_B_PES_RF (1<<7) /* Bit 7: Remote Fault */
846#define PHY_B_PES_CE_ER (1<<6) /* Bit 6: Carrier Ext Error */
847#define PHY_B_PES_BAD_SSD (1<<5) /* Bit 5: Bad SSD */
848#define PHY_B_PES_BAD_ESD (1<<4) /* Bit 4: Bad ESD */
849#define PHY_B_PES_RX_ER (1<<3) /* Bit 3: Receive Error */
850#define PHY_B_PES_TX_ER (1<<2) /* Bit 2: Transmit Error */
851#define PHY_B_PES_LOCK_ER (1<<1) /* Bit 1: Lock Error */
852#define PHY_B_PES_MLT3_ER (1<<0) /* Bit 0: MLT3 code Error */
853
854/***** PHY_BCOM_FC_CTR 16 bit r/w False Carrier Counter *****/
855 /* Bit 15..8: reserved */
856#define PHY_B_FC_CTR 0xff /* Bit 7..0: False Carrier Counter */
857
858/***** PHY_BCOM_RNO_CTR 16 bit r/w Receive NOT_OK Counter *****/
859#define PHY_B_RC_LOC_MSK 0xff00 /* Bit 15..8: Local Rx NOT_OK cnt */
860#define PHY_B_RC_REM_MSK 0x00ff /* Bit 7..0: Remote Rx NOT_OK cnt */
861
862/***** PHY_BCOM_AUX_CTRL 16 bit r/w Auxiliary Control Reg *****/
863#define PHY_B_AC_L_SQE (1<<15) /* Bit 15: Low Squelch */
864#define PHY_B_AC_LONG_PACK (1<<14) /* Bit 14: Rx Long Packets */
865#define PHY_B_AC_ER_CTRL (3<<12) /* Bit 13..12: Edgerate Control */
866 /* Bit 11: reserved */
867#define PHY_B_AC_TX_TST (1<<10) /* Bit 10: Tx test bit, always 1 */
868 /* Bit 9.. 8: reserved */
869#define PHY_B_AC_DIS_PRF (1<<7) /* Bit 7: dis part resp filter */
870 /* Bit 6: reserved */
871#define PHY_B_AC_DIS_PM (1<<5) /* Bit 5: dis power management */
872 /* Bit 4: reserved */
873#define PHY_B_AC_DIAG (1<<3) /* Bit 3: Diagnostic Mode */
874 /* Bit 2.. 0: reserved */
875
876/***** PHY_BCOM_AUX_STAT 16 bit r/o Auxiliary Status Reg *****/
877#define PHY_B_AS_AN_C (1<<15) /* Bit 15: AutoNeg complete */
878#define PHY_B_AS_AN_CA (1<<14) /* Bit 14: AN Complete Ack */
879#define PHY_B_AS_ANACK_D (1<<13) /* Bit 13: AN Ack Detect */
880#define PHY_B_AS_ANAB_D (1<<12) /* Bit 12: AN Ability Detect */
881#define PHY_B_AS_NPW (1<<11) /* Bit 11: AN Next Page Wait */
882#define PHY_B_AS_AN_RES_MSK (7<<8) /* Bit 10..8: AN HDC */
883#define PHY_B_AS_PDF (1<<7) /* Bit 7: Parallel Detect. Fault */
884#define PHY_B_AS_RF (1<<6) /* Bit 6: Remote Fault */
885#define PHY_B_AS_ANP_R (1<<5) /* Bit 5: AN Page Received */
886#define PHY_B_AS_LP_ANAB (1<<4) /* Bit 4: LP AN Ability */
887#define PHY_B_AS_LP_NPAB (1<<3) /* Bit 3: LP Next Page Ability */
888#define PHY_B_AS_LS (1<<2) /* Bit 2: Link Status */
889#define PHY_B_AS_PRR (1<<1) /* Bit 1: Pause Resolution-Rx */
890#define PHY_B_AS_PRT (1<<0) /* Bit 0: Pause Resolution-Tx */
891
892#define PHY_B_AS_PAUSE_MSK (PHY_B_AS_PRR | PHY_B_AS_PRT)
893
894/***** PHY_BCOM_INT_STAT 16 bit r/o Interrupt Status Reg *****/
895/***** PHY_BCOM_INT_MASK 16 bit r/w Interrupt Mask Reg *****/
896 /* Bit 15: reserved */
897#define PHY_B_IS_PSE (1<<14) /* Bit 14: Pair Swap Error */
898#define PHY_B_IS_MDXI_SC (1<<13) /* Bit 13: MDIX Status Change */
899#define PHY_B_IS_HCT (1<<12) /* Bit 12: counter above 32k */
900#define PHY_B_IS_LCT (1<<11) /* Bit 11: counter above 128 */
901#define PHY_B_IS_AN_PR (1<<10) /* Bit 10: Page Received */
902#define PHY_B_IS_NO_HDCL (1<<9) /* Bit 9: No HCD Link */
903#define PHY_B_IS_NO_HDC (1<<8) /* Bit 8: No HCD */
904#define PHY_B_IS_NEG_USHDC (1<<7) /* Bit 7: Negotiated Unsup. HCD */
905#define PHY_B_IS_SCR_S_ER (1<<6) /* Bit 6: Scrambler Sync Error */
906#define PHY_B_IS_RRS_CHANGE (1<<5) /* Bit 5: Remote Rx Stat Change */
907#define PHY_B_IS_LRS_CHANGE (1<<4) /* Bit 4: Local Rx Stat Change */
908#define PHY_B_IS_DUP_CHANGE (1<<3) /* Bit 3: Duplex Mode Change */
909#define PHY_B_IS_LSP_CHANGE (1<<2) /* Bit 2: Link Speed Change */
910#define PHY_B_IS_LST_CHANGE (1<<1) /* Bit 1: Link Status Changed */
911#define PHY_B_IS_CRC_ER (1<<0) /* Bit 0: CRC Error */
912
913#define PHY_B_DEF_MSK (~(PHY_B_IS_AN_PR | PHY_B_IS_LST_CHANGE))
914
915/* Pause Bits (PHY_B_AN_ASP and PHY_B_AN_PC) encoding */
916#define PHY_B_P_NO_PAUSE (0<<10) /* Bit 11..10: no Pause Mode */
917#define PHY_B_P_SYM_MD (1<<10) /* Bit 11..10: symmetric Pause Mode */
918#define PHY_B_P_ASYM_MD (2<<10) /* Bit 11..10: asymmetric Pause Mode */
919#define PHY_B_P_BOTH_MD (3<<10) /* Bit 11..10: both Pause Mode */
920
921/*
922 * Resolved Duplex mode and Capabilities (Aux Status Summary Reg)
923 */
924#define PHY_B_RES_1000FD (7<<8) /* Bit 10..8: 1000Base-T Full Dup. */
925#define PHY_B_RES_1000HD (6<<8) /* Bit 10..8: 1000Base-T Half Dup. */
926/* others: 100/10: invalid for us */
927
928/*
929 * Level One-Specific
930 */
931/***** PHY_LONE_1000T_CTRL 16 bit r/w 1000Base-T Control Reg *****/
932#define PHY_L_1000C_TEST (7<<13) /* Bit 15..13: Test Modes */
933#define PHY_L_1000C_MSE (1<<12) /* Bit 12: Master/Slave Enable */
934#define PHY_L_1000C_MSC (1<<11) /* Bit 11: M/S Configuration */
935#define PHY_L_1000C_RD (1<<10) /* Bit 10: Repeater/DTE */
936#define PHY_L_1000C_AFD (1<<9) /* Bit 9: Advertise Full Duplex */
937#define PHY_L_1000C_AHD (1<<8) /* Bit 8: Advertise Half Duplex */
938 /* Bit 7..0: reserved */
939
940/***** PHY_LONE_1000T_STAT 16 bit r/o 1000Base-T Status Reg *****/
941#define PHY_L_1000S_MSF (1<<15) /* Bit 15: Master/Slave Fault */
942#define PHY_L_1000S_MSR (1<<14) /* Bit 14: Master/Slave Result */
943#define PHY_L_1000S_LRS (1<<13) /* Bit 13: Local Receiver Status */
944#define PHY_L_1000S_RRS (1<<12) /* Bit 12: Remote Receiver Status */
945#define PHY_L_1000S_LP_FD (1<<11) /* Bit 11: Link Partner can FD */
946#define PHY_L_1000S_LP_HD (1<<10) /* Bit 10: Link Partner can HD */
947 /* Bit 9..8: reserved */
948#define PHY_B_1000S_IEC 0xff /* Bit 7..0: Idle Error Count */
949
950/***** PHY_LONE_EXT_STAT 16 bit r/o Extended Status Register *****/
951#define PHY_L_ES_X_FD_CAP (1<<15) /* Bit 15: 1000Base-X FD capable */
952#define PHY_L_ES_X_HD_CAP (1<<14) /* Bit 14: 1000Base-X HD capable */
953#define PHY_L_ES_T_FD_CAP (1<<13) /* Bit 13: 1000Base-T FD capable */
954#define PHY_L_ES_T_HD_CAP (1<<12) /* Bit 12: 1000Base-T HD capable */
955 /* Bit 11..0: reserved */
956
957/***** PHY_LONE_PORT_CFG 16 bit r/w Port Configuration Reg *****/
958#define PHY_L_PC_REP_MODE (1<<15) /* Bit 15: Repeater Mode */
959 /* Bit 14: reserved */
960#define PHY_L_PC_TX_DIS (1<<13) /* Bit 13: Tx output Disabled */
961#define PHY_L_PC_BY_SCR (1<<12) /* Bit 12: Bypass Scrambler */
962#define PHY_L_PC_BY_45 (1<<11) /* Bit 11: Bypass 4B5B-Decoder */
963#define PHY_L_PC_JAB_DIS (1<<10) /* Bit 10: Jabber Disabled */
964#define PHY_L_PC_SQE (1<<9) /* Bit 9: Enable Heartbeat */
965#define PHY_L_PC_TP_LOOP (1<<8) /* Bit 8: TP Loopback */
966#define PHY_L_PC_SSS (1<<7) /* Bit 7: Smart Speed Selection */
967#define PHY_L_PC_FIFO_SIZE (1<<6) /* Bit 6: FIFO Size */
968#define PHY_L_PC_PRE_EN (1<<5) /* Bit 5: Preamble Enable */
969#define PHY_L_PC_CIM (1<<4) /* Bit 4: Carrier Integrity Mon */
970#define PHY_L_PC_10_SER (1<<3) /* Bit 3: Use Serial Output */
971#define PHY_L_PC_ANISOL (1<<2) /* Bit 2: Unisolate Port */
972#define PHY_L_PC_TEN_BIT (1<<1) /* Bit 1: 10bit iface mode on */
973#define PHY_L_PC_ALTCLOCK (1<<0) /* Bit 0: (ro) ALTCLOCK Mode on */
974
975/***** PHY_LONE_Q_STAT 16 bit r/o Quick Status Reg *****/
976#define PHY_L_QS_D_RATE (3<<14) /* Bit 15..14: Data Rate */
977#define PHY_L_QS_TX_STAT (1<<13) /* Bit 13: Transmitting */
978#define PHY_L_QS_RX_STAT (1<<12) /* Bit 12: Receiving */
979#define PHY_L_QS_COL_STAT (1<<11) /* Bit 11: Collision */
980#define PHY_L_QS_L_STAT (1<<10) /* Bit 10: Link is up */
981#define PHY_L_QS_DUP_MOD (1<<9) /* Bit 9: Full/Half Duplex */
982#define PHY_L_QS_AN (1<<8) /* Bit 8: AutoNeg is On */
983#define PHY_L_QS_AN_C (1<<7) /* Bit 7: AN is Complete */
984#define PHY_L_QS_LLE (7<<4) /* Bit 6: Line Length Estim. */
985#define PHY_L_QS_PAUSE (1<<3) /* Bit 3: LP advertised Pause */
986#define PHY_L_QS_AS_PAUSE (1<<2) /* Bit 2: LP adv. asym. Pause */
987#define PHY_L_QS_ISOLATE (1<<1) /* Bit 1: CIM Isolated */
988#define PHY_L_QS_EVENT (1<<0) /* Bit 0: Event has occurred */
989
990/***** PHY_LONE_INT_ENAB 16 bit r/w Interrupt Enable Reg *****/
991/***** PHY_LONE_INT_STAT 16 bit r/o Interrupt Status Reg *****/
992 /* Bit 15..14: reserved */
993#define PHY_L_IS_AN_F (1<<13) /* Bit 13: Auto-Negotiation fault */
994 /* Bit 12: not described */
995#define PHY_L_IS_CROSS (1<<11) /* Bit 11: Crossover used */
996#define PHY_L_IS_POL (1<<10) /* Bit 10: Polarity correct. used */
997#define PHY_L_IS_SS (1<<9) /* Bit 9: Smart Speed Downgrade */
998#define PHY_L_IS_CFULL (1<<8) /* Bit 8: Counter Full */
999#define PHY_L_IS_AN_C (1<<7) /* Bit 7: AutoNeg Complete */
1000#define PHY_L_IS_SPEED (1<<6) /* Bit 6: Speed Changed */
1001#define PHY_L_IS_DUP (1<<5) /* Bit 5: Duplex Changed */
1002#define PHY_L_IS_LS (1<<4) /* Bit 4: Link Status Changed */
1003#define PHY_L_IS_ISOL (1<<3) /* Bit 3: Isolate Occured */
1004#define PHY_L_IS_MDINT (1<<2) /* Bit 2: (ro) STAT: MII Int Pending */
1005#define PHY_L_IS_INTEN (1<<1) /* Bit 1: ENAB: Enable IRQs */
1006#define PHY_L_IS_FORCE (1<<0) /* Bit 0: ENAB: Force Interrupt */
1007
1008/* int. mask */
1009#define PHY_L_DEF_MSK (PHY_L_IS_LS | PHY_L_IS_ISOL | PHY_L_IS_INTEN)
1010
1011/***** PHY_LONE_LED_CFG 16 bit r/w LED Configuration Reg *****/
1012#define PHY_L_LC_LEDC (3<<14) /* Bit 15..14: Col/Blink/On/Off */
1013#define PHY_L_LC_LEDR (3<<12) /* Bit 13..12: Rx/Blink/On/Off */
1014#define PHY_L_LC_LEDT (3<<10) /* Bit 11..10: Tx/Blink/On/Off */
1015#define PHY_L_LC_LEDG (3<<8) /* Bit 9..8: Giga/Blink/On/Off */
1016#define PHY_L_LC_LEDS (3<<6) /* Bit 7..6: 10-100/Blink/On/Off */
1017#define PHY_L_LC_LEDL (3<<4) /* Bit 5..4: Link/Blink/On/Off */
1018#define PHY_L_LC_LEDF (3<<2) /* Bit 3..2: Duplex/Blink/On/Off */
1019#define PHY_L_LC_PSTRECH (1<<1) /* Bit 1: Strech LED Pulses */
1020#define PHY_L_LC_FREQ (1<<0) /* Bit 0: 30/100 ms */
1021
1022/***** PHY_LONE_PORT_CTRL 16 bit r/w Port Control Reg *****/
1023#define PHY_L_PC_TX_TCLK (1<<15) /* Bit 15: Enable TX_TCLK */
1024 /* Bit 14: reserved */
1025#define PHY_L_PC_ALT_NP (1<<13) /* Bit 14: Alternate Next Page */
1026#define PHY_L_PC_GMII_ALT (1<<12) /* Bit 13: Alternate GMII driver */
1027 /* Bit 11: reserved */
1028#define PHY_L_PC_TEN_CRS (1<<10) /* Bit 10: Extend CRS*/
1029 /* Bit 9..0: not described */
1030
1031/***** PHY_LONE_CIM 16 bit r/o CIM Reg *****/
1032#define PHY_L_CIM_ISOL (255<<8)/* Bit 15..8: Isolate Count */
1033#define PHY_L_CIM_FALSE_CAR (255<<0)/* Bit 7..0: False Carrier Count */
1034
1035
1036/*
1037 * Pause Bits (PHY_L_AN_ASP and PHY_L_AN_PC) encoding
1038 */
1039#define PHY_L_P_NO_PAUSE (0<<10) /* Bit 11..10: no Pause Mode */
1040#define PHY_L_P_SYM_MD (1<<10) /* Bit 11..10: symmetric Pause Mode */
1041#define PHY_L_P_ASYM_MD (2<<10) /* Bit 11..10: asymmetric Pause Mode */
1042#define PHY_L_P_BOTH_MD (3<<10) /* Bit 11..10: both Pause Mode */
1043
1044
1045/*
1046 * National-Specific
1047 */
1048/***** PHY_NAT_1000T_CTRL 16 bit r/w 1000Base-T Control Reg *****/
1049#define PHY_N_1000C_TEST (7<<13) /* Bit 15..13: Test Modes */
1050#define PHY_N_1000C_MSE (1<<12) /* Bit 12: Master/Slave Enable */
1051#define PHY_N_1000C_MSC (1<<11) /* Bit 11: M/S Configuration */
1052#define PHY_N_1000C_RD (1<<10) /* Bit 10: Repeater/DTE */
1053#define PHY_N_1000C_AFD (1<<9) /* Bit 9: Advertise Full Duplex */
1054#define PHY_N_1000C_AHD (1<<8) /* Bit 8: Advertise Half Duplex */
1055#define PHY_N_1000C_APC (1<<7) /* Bit 7: Asymmetric Pause Cap. */
1056 /* Bit 6..0: reserved */
1057
1058/***** PHY_NAT_1000T_STAT 16 bit r/o 1000Base-T Status Reg *****/
1059#define PHY_N_1000S_MSF (1<<15) /* Bit 15: Master/Slave Fault */
1060#define PHY_N_1000S_MSR (1<<14) /* Bit 14: Master/Slave Result */
1061#define PHY_N_1000S_LRS (1<<13) /* Bit 13: Local Receiver Status */
1062#define PHY_N_1000S_RRS (1<<12) /* Bit 12: Remote Receiver Status*/
1063#define PHY_N_1000S_LP_FD (1<<11) /* Bit 11: Link Partner can FD */
1064#define PHY_N_1000S_LP_HD (1<<10) /* Bit 10: Link Partner can HD */
1065#define PHY_N_1000C_LP_APC (1<<9) /* Bit 9: LP Asym. Pause Cap. */
1066 /* Bit 8: reserved */
1067#define PHY_N_1000S_IEC 0xff /* Bit 7..0: Idle Error Count */
1068
1069/***** PHY_NAT_EXT_STAT 16 bit r/o Extended Status Register *****/
1070#define PHY_N_ES_X_FD_CAP (1<<15) /* Bit 15: 1000Base-X FD capable */
1071#define PHY_N_ES_X_HD_CAP (1<<14) /* Bit 14: 1000Base-X HD capable */
1072#define PHY_N_ES_T_FD_CAP (1<<13) /* Bit 13: 1000Base-T FD capable */
1073#define PHY_N_ES_T_HD_CAP (1<<12) /* Bit 12: 1000Base-T HD capable */
1074 /* Bit 11..0: reserved */
1075
1076/* todo: those are still missing */
1077/***** PHY_NAT_EXT_CTRL1 16 bit r/o Extended Control Reg1 *****/
1078/***** PHY_NAT_Q_STAT1 16 bit r/o Quick Status Reg1 *****/
1079/***** PHY_NAT_10B_OP 16 bit r/o 10Base-T Operations Reg *****/
1080/***** PHY_NAT_EXT_CTRL2 16 bit r/o Extended Control Reg1 *****/
1081/***** PHY_NAT_Q_STAT2 16 bit r/o Quick Status Reg2 *****/
1082/***** PHY_NAT_PHY_ADDR 16 bit r/o PHY Address Register *****/
1083
1084/*
1085 * Marvell-Specific
1086 */
1087/***** PHY_MARV_AUNE_ADV 16 bit r/w Auto-Negotiation Advertisement *****/
1088/***** PHY_MARV_AUNE_LP 16 bit r/w Link Part Ability Reg *****/
1089#define PHY_M_AN_NXT_PG BIT_15 /* Request Next Page */
1090#define PHY_M_AN_ACK BIT_14 /* (ro) Acknowledge Received */
1091#define PHY_M_AN_RF BIT_13 /* Remote Fault */
1092 /* Bit 12: reserved */
1093#define PHY_M_AN_ASP BIT_11 /* Asymmetric Pause */
1094#define PHY_M_AN_PC BIT_10 /* MAC Pause implemented */
1095#define PHY_M_AN_100_FD BIT_8 /* Advertise 100Base-TX Full Duplex */
1096#define PHY_M_AN_100_HD BIT_7 /* Advertise 100Base-TX Half Duplex */
1097#define PHY_M_AN_10_FD BIT_6 /* Advertise 10Base-TX Full Duplex */
1098#define PHY_M_AN_10_HD BIT_5 /* Advertise 10Base-TX Half Duplex */
1099
1100/* special defines for FIBER (88E1011S only) */
1101#define PHY_M_AN_ASP_X BIT_8 /* Asymmetric Pause */
1102#define PHY_M_AN_PC_X BIT_7 /* MAC Pause implemented */
1103#define PHY_M_AN_1000X_AHD BIT_6 /* Advertise 10000Base-X Half Duplex */
1104#define PHY_M_AN_1000X_AFD BIT_5 /* Advertise 10000Base-X Full Duplex */
1105
1106/* Pause Bits (PHY_M_AN_ASP_X and PHY_M_AN_PC_X) encoding */
1107#define PHY_M_P_NO_PAUSE_X (0<<7) /* Bit 8.. 7: no Pause Mode */
1108#define PHY_M_P_SYM_MD_X (1<<7) /* Bit 8.. 7: symmetric Pause Mode */
1109#define PHY_M_P_ASYM_MD_X (2<<7) /* Bit 8.. 7: asymmetric Pause Mode */
1110#define PHY_M_P_BOTH_MD_X (3<<7) /* Bit 8.. 7: both Pause Mode */
1111
1112/***** PHY_MARV_1000T_CTRL 16 bit r/w 1000Base-T Control Reg *****/
1113#define PHY_M_1000C_TEST (7<<13) /* Bit 15..13: Test Modes */
1114#define PHY_M_1000C_MSE (1<<12) /* Bit 12: Manual Master/Slave Enable */
1115#define PHY_M_1000C_MSC (1<<11) /* Bit 11: M/S Configuration (1=Master) */
1116#define PHY_M_1000C_MPD (1<<10) /* Bit 10: Multi-Port Device */
1117#define PHY_M_1000C_AFD (1<<9) /* Bit 9: Advertise Full Duplex */
1118#define PHY_M_1000C_AHD (1<<8) /* Bit 8: Advertise Half Duplex */
1119 /* Bit 7..0: reserved */
1120
1121/***** PHY_MARV_PHY_CTRL 16 bit r/w PHY Specific Ctrl Reg *****/
1122#define PHY_M_PC_TX_FFD_MSK (3<<14) /* Bit 15..14: Tx FIFO Depth Mask */
1123#define PHY_M_PC_RX_FFD_MSK (3<<12) /* Bit 13..12: Rx FIFO Depth Mask */
1124#define PHY_M_PC_ASS_CRS_TX (1<<11) /* Bit 11: Assert CRS on Transmit */
1125#define PHY_M_PC_FL_GOOD (1<<10) /* Bit 10: Force Link Good */
1126#define PHY_M_PC_EN_DET_MSK (3<<8) /* Bit 9.. 8: Energy Detect Mask */
1127#define PHY_M_PC_ENA_EXT_D (1<<7) /* Bit 7: Enable Ext. Distance (10BT) */
1128#define PHY_M_PC_MDIX_MSK (3<<5) /* Bit 6.. 5: MDI/MDIX Config. Mask */
1129#define PHY_M_PC_DIS_125CLK (1<<4) /* Bit 4: Disable 125 CLK */
1130#define PHY_M_PC_MAC_POW_UP (1<<3) /* Bit 3: MAC Power up */
1131#define PHY_M_PC_SQE_T_ENA (1<<2) /* Bit 2: SQE Test Enabled */
1132#define PHY_M_PC_POL_R_DIS (1<<1) /* Bit 1: Polarity Reversal Disabled */
1133#define PHY_M_PC_DIS_JABBER (1<<0) /* Bit 0: Disable Jabber */
1134
1135#define PHY_M_PC_EN_DET SHIFT8(2) /* Energy Detect (Mode 1) */
1136#define PHY_M_PC_EN_DET_PLUS SHIFT8(3) /* Energy Detect Plus (Mode 2) */
1137
1138#define PHY_M_PC_MDI_XMODE(x) SHIFT5(x)
1139#define PHY_M_PC_MAN_MDI 0 /* 00 = Manual MDI configuration */
1140#define PHY_M_PC_MAN_MDIX 1 /* 01 = Manual MDIX configuration */
1141#define PHY_M_PC_ENA_AUTO 3 /* 11 = Enable Automatic Crossover */
1142
1143/***** PHY_MARV_PHY_STAT 16 bit r/o PHY Specific Status Reg *****/
1144#define PHY_M_PS_SPEED_MSK (3<<14) /* Bit 15..14: Speed Mask */
1145#define PHY_M_PS_SPEED_1000 (1<<15) /* 10 = 1000 Mbps */
1146#define PHY_M_PS_SPEED_100 (1<<14) /* 01 = 100 Mbps */
1147#define PHY_M_PS_SPEED_10 0 /* 00 = 10 Mbps */
1148#define PHY_M_PS_FULL_DUP (1<<13) /* Bit 13: Full Duplex */
1149#define PHY_M_PS_PAGE_REC (1<<12) /* Bit 12: Page Received */
1150#define PHY_M_PS_SPDUP_RES (1<<11) /* Bit 11: Speed & Duplex Resolved */
1151#define PHY_M_PS_LINK_UP (1<<10) /* Bit 10: Link Up */
1152#define PHY_M_PS_CABLE_MSK (3<<7) /* Bit 9.. 7: Cable Length Mask */
1153#define PHY_M_PS_MDI_X_STAT (1<<6) /* Bit 6: MDI Crossover Stat (1=MDIX) */
1154#define PHY_M_PS_DOWNS_STAT (1<<5) /* Bit 5: Downshift Status (1=downsh.) */
1155#define PHY_M_PS_ENDET_STAT (1<<4) /* Bit 4: Energy Detect Status (1=act) */
1156#define PHY_M_PS_TX_P_EN (1<<3) /* Bit 3: Tx Pause Enabled */
1157#define PHY_M_PS_RX_P_EN (1<<2) /* Bit 2: Rx Pause Enabled */
1158#define PHY_M_PS_POL_REV (1<<1) /* Bit 1: Polarity Reversed */
1159#define PHY_M_PC_JABBER (1<<0) /* Bit 0: Jabber */
1160
1161#define PHY_M_PS_PAUSE_MSK (PHY_M_PS_TX_P_EN | PHY_M_PS_RX_P_EN)
1162
1163/***** PHY_MARV_INT_MASK 16 bit r/w Interrupt Mask Reg *****/
1164/***** PHY_MARV_INT_STAT 16 bit r/o Interrupt Status Reg *****/
1165#define PHY_M_IS_AN_ERROR (1<<15) /* Bit 15: Auto-Negotiation Error */
1166#define PHY_M_IS_LSP_CHANGE (1<<14) /* Bit 14: Link Speed Changed */
1167#define PHY_M_IS_DUP_CHANGE (1<<13) /* Bit 13: Duplex Mode Changed */
1168#define PHY_M_IS_AN_PR (1<<12) /* Bit 12: Page Received */
1169#define PHY_M_IS_AN_COMPL (1<<11) /* Bit 11: Auto-Negotiation Completed */
1170#define PHY_M_IS_LST_CHANGE (1<<10) /* Bit 10: Link Status Changed */
1171#define PHY_M_IS_SYMB_ERROR (1<<9) /* Bit 9: Symbol Error */
1172#define PHY_M_IS_FALSE_CARR (1<<8) /* Bit 8: False Carrier */
1173#define PHY_M_IS_FIFO_ERROR (1<<7) /* Bit 7: FIFO Overflow/Underrun Error */
1174#define PHY_M_IS_MDI_CHANGE (1<<6) /* Bit 6: MDI Crossover Changed */
1175#define PHY_M_IS_DOWNSH_DET (1<<5) /* Bit 5: Downshift Detected */
1176#define PHY_M_IS_END_CHANGE (1<<4) /* Bit 4: Energy Detect Changed */
1177 /* Bit 3..2: reserved */
1178#define PHY_M_IS_POL_CHANGE (1<<1) /* Bit 1: Polarity Changed */
1179#define PHY_M_IS_JABBER (1<<0) /* Bit 0: Jabber */
1180
1181#define PHY_M_DEF_MSK (PHY_M_IS_AN_ERROR | PHY_M_IS_AN_PR | \
1182 PHY_M_IS_LST_CHANGE | PHY_M_IS_FIFO_ERROR)
1183
1184/***** PHY_MARV_EXT_CTRL 16 bit r/w Ext. PHY Specific Ctrl *****/
1185#define PHY_M_EC_M_DSC_MSK (3<<10) /* Bit 11..10: Master downshift counter */
1186#define PHY_M_EC_S_DSC_MSK (3<<8) /* Bit 9.. 8: Slave downshift counter */
1187#define PHY_M_EC_MAC_S_MSK (7<<4) /* Bit 6.. 4: Def. MAC interface speed */
1188#define PHY_M_EC_FIB_AN_ENA (1<<3) /* Bit 3: Fiber Auto-Neg. Enable */
1189
1190#define PHY_M_EC_M_DSC(x) SHIFT10(x) /* 00=1x; 01=2x; 10=3x; 11=4x */
1191#define PHY_M_EC_S_DSC(x) SHIFT8(x) /* 00=dis; 01=1x; 10=2x; 11=3x */
1192#define PHY_M_EC_MAC_S(x) SHIFT4(x) /* 01X=0; 110=2.5; 111=25 (MHz) */
1193
1194#define MAC_TX_CLK_0_MHZ 2
1195#define MAC_TX_CLK_2_5_MHZ 6
1196#define MAC_TX_CLK_25_MHZ 7
1197
1198/***** PHY_MARV_LED_CTRL 16 bit r/w LED Control Reg *****/
1199#define PHY_M_LEDC_DIS_LED (1<<15) /* Bit 15: Disable LED */
1200#define PHY_M_LEDC_PULS_MSK (7<<12) /* Bit 14..12: Pulse Stretch Mask */
1201#define PHY_M_LEDC_F_INT (1<<11) /* Bit 11: Force Interrupt */
1202#define PHY_M_LEDC_BL_R_MSK (7<<8) /* Bit 10.. 8: Blink Rate Mask */
1203 /* Bit 7.. 5: reserved */
1204#define PHY_M_LEDC_LINK_MSK (3<<3) /* Bit 4.. 3: Link Control Mask */
1205#define PHY_M_LEDC_DP_CTRL (1<<2) /* Bit 2: Duplex Control */
1206#define PHY_M_LEDC_RX_CTRL (1<<1) /* Bit 1: Rx activity / Link */
1207#define PHY_M_LEDC_TX_CTRL (1<<0) /* Bit 0: Tx activity / Link */
1208
1209#define PHY_M_LED_PULS_DUR(x) SHIFT12(x) /* Pulse Stretch Duration */
1210
1211#define PULS_NO_STR 0 /* no pulse stretching */
1212#define PULS_21MS 1 /* 21 ms to 42 ms */
1213#define PULS_42MS 2 /* 42 ms to 84 ms */
1214#define PULS_84MS 3 /* 84 ms to 170 ms */
1215#define PULS_170MS 4 /* 170 ms to 340 ms */
1216#define PULS_340MS 5 /* 340 ms to 670 ms */
1217#define PULS_670MS 6 /* 670 ms to 1.3 s */
1218#define PULS_1300MS 7 /* 1.3 s to 2.7 s */
1219
1220#define PHY_M_LED_BLINK_RT(x) SHIFT8(x) /* Blink Rate */
1221
1222#define BLINK_42MS 0 /* 42 ms */
1223#define BLINK_84MS 1 /* 84 ms */
1224#define BLINK_170MS 2 /* 170 ms */
1225#define BLINK_340MS 3 /* 340 ms */
1226#define BLINK_670MS 4 /* 670 ms */
1227 /* values 5 - 7: reserved */
1228
1229/***** PHY_MARV_LED_OVER 16 bit r/w Manual LED Override Reg *****/
1230#define PHY_M_LED_MO_DUP(x) SHIFT10(x) /* Bit 11..10: Duplex */
1231#define PHY_M_LED_MO_10(x) SHIFT8(x) /* Bit 9.. 8: Link 10 */
1232#define PHY_M_LED_MO_100(x) SHIFT6(x) /* Bit 7.. 6: Link 100 */
1233#define PHY_M_LED_MO_1000(x) SHIFT4(x) /* Bit 5.. 4: Link 1000 */
1234#define PHY_M_LED_MO_RX(x) SHIFT2(x) /* Bit 3.. 2: Rx */
1235#define PHY_M_LED_MO_TX(x) SHIFT0(x) /* Bit 1.. 0: Tx */
1236
1237#define MO_LED_NORM 0
1238#define MO_LED_BLINK 1
1239#define MO_LED_OFF 2
1240#define MO_LED_ON 3
1241
1242/***** PHY_MARV_EXT_CTRL_2 16 bit r/w Ext. PHY Specific Ctrl 2 *****/
1243 /* Bit 15.. 7: reserved */
1244#define PHY_M_EC2_FI_IMPED (1<<6) /* Bit 6: Fiber Input Impedance */
1245#define PHY_M_EC2_FO_IMPED (1<<5) /* Bit 5: Fiber Output Impedance */
1246#define PHY_M_EC2_FO_M_CLK (1<<4) /* Bit 4: Fiber Mode Clock Enable */
1247#define PHY_M_EC2_FO_BOOST (1<<3) /* Bit 3: Fiber Output Boost */
1248#define PHY_M_EC2_FO_AM_MSK 7 /* Bit 2.. 0: Fiber Output Amplitude */
1249
1250/***** PHY_MARV_EXT_P_STAT 16 bit r/w Ext. PHY Specific Status *****/
1251#define PHY_M_FC_AUTO_SEL (1<<15) /* Bit 15: Fiber/Copper Auto Sel. dis. */
1252#define PHY_M_FC_AN_REG_ACC (1<<14) /* Bit 14: Fiber/Copper Autoneg. reg acc */
1253#define PHY_M_FC_RESULUTION (1<<13) /* Bit 13: Fiber/Copper Resulution */
1254#define PHY_M_SER_IF_AN_BP (1<<12) /* Bit 12: Ser IF autoneg. bypass enable */
1255#define PHY_M_SER_IF_BP_ST (1<<11) /* Bit 11: Ser IF autoneg. bypass status */
1256#define PHY_M_IRQ_POLARITY (1<<10) /* Bit 10: IRQ polarity */
1257 /* Bit 9..4: reserved */
1258#define PHY_M_UNDOC1 (1<< 7) /* undocumented bit !! */
1259#define PHY_M_MODE_MASK (0xf<<0)/* Bit 3..0: copy of HWCFG MODE[3:0] */
1260
1261
1262/***** PHY_MARV_CABLE_DIAG 16 bit r/o Cable Diagnostic Reg *****/
1263#define PHY_M_CABD_ENA_TEST (1<<15) /* Bit 15: Enable Test */
1264#define PHY_M_CABD_STAT_MSK (3<<13) /* Bit 14..13: Status */
1265 /* Bit 12.. 8: reserved */
1266#define PHY_M_CABD_DIST_MSK 0xff /* Bit 7.. 0: Distance */
1267
1268/* values for Cable Diagnostic Status (11=fail; 00=OK; 10=open; 01=short) */
1269#define CABD_STAT_NORMAL 0
1270#define CABD_STAT_SHORT 1
1271#define CABD_STAT_OPEN 2
1272#define CABD_STAT_FAIL 3
1273
1274
1275/*
1276 * GMAC registers
1277 *
1278 * The GMAC registers are 16 or 32 bits wide.
1279 * The GMACs host processor interface is 16 bits wide,
1280 * therefore ALL registers will be addressed with 16 bit accesses.
1281 *
1282 * The following macros are provided to access the GMAC registers
1283 * GM_IN16(), GM_OUT16, GM_IN32(), GM_OUT32(), GM_INADR(), GM_OUTADR(),
1284 * GM_INHASH(), and GM_OUTHASH().
1285 * The macros are defined in SkGeHw.h.
1286 *
1287 * Note: NA reg = Network Address e.g DA, SA etc.
1288 *
1289 */
1290
1291/* Port Registers */
1292#define GM_GP_STAT 0x0000 /* 16 bit r/o General Purpose Status */
1293#define GM_GP_CTRL 0x0004 /* 16 bit r/w General Purpose Control */
1294#define GM_TX_CTRL 0x0008 /* 16 bit r/w Transmit Control Reg. */
1295#define GM_RX_CTRL 0x000c /* 16 bit r/w Receive Control Reg. */
1296#define GM_TX_FLOW_CTRL 0x0010 /* 16 bit r/w Transmit Flow-Control */
1297#define GM_TX_PARAM 0x0014 /* 16 bit r/w Transmit Parameter Reg. */
1298#define GM_SERIAL_MODE 0x0018 /* 16 bit r/w Serial Mode Register */
1299
1300/* Source Address Registers */
1301#define GM_SRC_ADDR_1L 0x001c /* 16 bit r/w Source Address 1 (low) */
1302#define GM_SRC_ADDR_1M 0x0020 /* 16 bit r/w Source Address 1 (middle) */
1303#define GM_SRC_ADDR_1H 0x0024 /* 16 bit r/w Source Address 1 (high) */
1304#define GM_SRC_ADDR_2L 0x0028 /* 16 bit r/w Source Address 2 (low) */
1305#define GM_SRC_ADDR_2M 0x002c /* 16 bit r/w Source Address 2 (middle) */
1306#define GM_SRC_ADDR_2H 0x0030 /* 16 bit r/w Source Address 2 (high) */
1307
1308/* Multicast Address Hash Registers */
1309#define GM_MC_ADDR_H1 0x0034 /* 16 bit r/w Multicast Address Hash 1 */
1310#define GM_MC_ADDR_H2 0x0038 /* 16 bit r/w Multicast Address Hash 2 */
1311#define GM_MC_ADDR_H3 0x003c /* 16 bit r/w Multicast Address Hash 3 */
1312#define GM_MC_ADDR_H4 0x0040 /* 16 bit r/w Multicast Address Hash 4 */
1313
1314/* Interrupt Source Registers */
1315#define GM_TX_IRQ_SRC 0x0044 /* 16 bit r/o Tx Overflow IRQ Source */
1316#define GM_RX_IRQ_SRC 0x0048 /* 16 bit r/o Rx Overflow IRQ Source */
1317#define GM_TR_IRQ_SRC 0x004c /* 16 bit r/o Tx/Rx Over. IRQ Source */
1318
1319/* Interrupt Mask Registers */
1320#define GM_TX_IRQ_MSK 0x0050 /* 16 bit r/w Tx Overflow IRQ Mask */
1321#define GM_RX_IRQ_MSK 0x0054 /* 16 bit r/w Rx Overflow IRQ Mask */
1322#define GM_TR_IRQ_MSK 0x0058 /* 16 bit r/w Tx/Rx Over. IRQ Mask */
1323
1324/* Serial Management Interface (SMI) Registers */
1325#define GM_SMI_CTRL 0x0080 /* 16 bit r/w SMI Control Register */
1326#define GM_SMI_DATA 0x0084 /* 16 bit r/w SMI Data Register */
1327#define GM_PHY_ADDR 0x0088 /* 16 bit r/w GPHY Address Register */
1328
1329/* MIB Counters */
1330#define GM_MIB_CNT_BASE 0x0100 /* Base Address of MIB Counters */
1331#define GM_MIB_CNT_SIZE 44 /* Number of MIB Counters */
1332
1333/*
1334 * MIB Counters base address definitions (low word) -
1335 * use offset 4 for access to high word (32 bit r/o)
1336 */
1337#define GM_RXF_UC_OK \
1338 (GM_MIB_CNT_BASE + 0) /* Unicast Frames Received OK */
1339#define GM_RXF_BC_OK \
1340 (GM_MIB_CNT_BASE + 8) /* Broadcast Frames Received OK */
1341#define GM_RXF_MPAUSE \
1342 (GM_MIB_CNT_BASE + 16) /* Pause MAC Ctrl Frames Received */
1343#define GM_RXF_MC_OK \
1344 (GM_MIB_CNT_BASE + 24) /* Multicast Frames Received OK */
1345#define GM_RXF_FCS_ERR \
1346 (GM_MIB_CNT_BASE + 32) /* Rx Frame Check Seq. Error */
1347 /* GM_MIB_CNT_BASE + 40: reserved */
1348#define GM_RXO_OK_LO \
1349 (GM_MIB_CNT_BASE + 48) /* Octets Received OK Low */
1350#define GM_RXO_OK_HI \
1351 (GM_MIB_CNT_BASE + 56) /* Octets Received OK High */
1352#define GM_RXO_ERR_LO \
1353 (GM_MIB_CNT_BASE + 64) /* Octets Received Invalid Low */
1354#define GM_RXO_ERR_HI \
1355 (GM_MIB_CNT_BASE + 72) /* Octets Received Invalid High */
1356#define GM_RXF_SHT \
1357 (GM_MIB_CNT_BASE + 80) /* Frames <64 Byte Received OK */
1358#define GM_RXE_FRAG \
1359 (GM_MIB_CNT_BASE + 88) /* Frames <64 Byte Received with FCS Err */
1360#define GM_RXF_64B \
1361 (GM_MIB_CNT_BASE + 96) /* 64 Byte Rx Frame */
1362#define GM_RXF_127B \
1363 (GM_MIB_CNT_BASE + 104) /* 65-127 Byte Rx Frame */
1364#define GM_RXF_255B \
1365 (GM_MIB_CNT_BASE + 112) /* 128-255 Byte Rx Frame */
1366#define GM_RXF_511B \
1367 (GM_MIB_CNT_BASE + 120) /* 256-511 Byte Rx Frame */
1368#define GM_RXF_1023B \
1369 (GM_MIB_CNT_BASE + 128) /* 512-1023 Byte Rx Frame */
1370#define GM_RXF_1518B \
1371 (GM_MIB_CNT_BASE + 136) /* 1024-1518 Byte Rx Frame */
1372#define GM_RXF_MAX_SZ \
1373 (GM_MIB_CNT_BASE + 144) /* 1519-MaxSize Byte Rx Frame */
1374#define GM_RXF_LNG_ERR \
1375 (GM_MIB_CNT_BASE + 152) /* Rx Frame too Long Error */
1376#define GM_RXF_JAB_PKT \
1377 (GM_MIB_CNT_BASE + 160) /* Rx Jabber Packet Frame */
1378 /* GM_MIB_CNT_BASE + 168: reserved */
1379#define GM_RXE_FIFO_OV \
1380 (GM_MIB_CNT_BASE + 176) /* Rx FIFO overflow Event */
1381 /* GM_MIB_CNT_BASE + 184: reserved */
1382#define GM_TXF_UC_OK \
1383 (GM_MIB_CNT_BASE + 192) /* Unicast Frames Xmitted OK */
1384#define GM_TXF_BC_OK \
1385 (GM_MIB_CNT_BASE + 200) /* Broadcast Frames Xmitted OK */
1386#define GM_TXF_MPAUSE \
1387 (GM_MIB_CNT_BASE + 208) /* Pause MAC Ctrl Frames Xmitted */
1388#define GM_TXF_MC_OK \
1389 (GM_MIB_CNT_BASE + 216) /* Multicast Frames Xmitted OK */
1390#define GM_TXO_OK_LO \
1391 (GM_MIB_CNT_BASE + 224) /* Octets Transmitted OK Low */
1392#define GM_TXO_OK_HI \
1393 (GM_MIB_CNT_BASE + 232) /* Octets Transmitted OK High */
1394#define GM_TXF_64B \
1395 (GM_MIB_CNT_BASE + 240) /* 64 Byte Tx Frame */
1396#define GM_TXF_127B \
1397 (GM_MIB_CNT_BASE + 248) /* 65-127 Byte Tx Frame */
1398#define GM_TXF_255B \
1399 (GM_MIB_CNT_BASE + 256) /* 128-255 Byte Tx Frame */
1400#define GM_TXF_511B \
1401 (GM_MIB_CNT_BASE + 264) /* 256-511 Byte Tx Frame */
1402#define GM_TXF_1023B \
1403 (GM_MIB_CNT_BASE + 272) /* 512-1023 Byte Tx Frame */
1404#define GM_TXF_1518B \
1405 (GM_MIB_CNT_BASE + 280) /* 1024-1518 Byte Tx Frame */
1406#define GM_TXF_MAX_SZ \
1407 (GM_MIB_CNT_BASE + 288) /* 1519-MaxSize Byte Tx Frame */
1408 /* GM_MIB_CNT_BASE + 296: reserved */
1409#define GM_TXF_COL \
1410 (GM_MIB_CNT_BASE + 304) /* Tx Collision */
1411#define GM_TXF_LAT_COL \
1412 (GM_MIB_CNT_BASE + 312) /* Tx Late Collision */
1413#define GM_TXF_ABO_COL \
1414 (GM_MIB_CNT_BASE + 320) /* Tx aborted due to Exces. Col. */
1415#define GM_TXF_MUL_COL \
1416 (GM_MIB_CNT_BASE + 328) /* Tx Multiple Collision */
1417#define GM_TXF_SNG_COL \
1418 (GM_MIB_CNT_BASE + 336) /* Tx Single Collision */
1419#define GM_TXE_FIFO_UR \
1420 (GM_MIB_CNT_BASE + 344) /* Tx FIFO Underrun Event */
1421
1422/*----------------------------------------------------------------------------*/
1423/*
1424 * GMAC Bit Definitions
1425 *
1426 * If the bit access behaviour differs from the register access behaviour
1427 * (r/w, r/o) this is documented after the bit number.
1428 * The following bit access behaviours are used:
1429 * (sc) self clearing
1430 * (r/o) read only
1431 */
1432
1433/* GM_GP_STAT 16 bit r/o General Purpose Status Register */
1434#define GM_GPSR_SPEED (1<<15) /* Bit 15: Port Speed (1 = 100 Mbps) */
1435#define GM_GPSR_DUPLEX (1<<14) /* Bit 14: Duplex Mode (1 = Full) */
1436#define GM_GPSR_FC_TX_DIS (1<<13) /* Bit 13: Tx Flow-Control Mode Disabled */
1437#define GM_GPSR_LINK_UP (1<<12) /* Bit 12: Link Up Status */
1438#define GM_GPSR_PAUSE (1<<11) /* Bit 11: Pause State */
1439#define GM_GPSR_TX_ACTIVE (1<<10) /* Bit 10: Tx in Progress */
1440#define GM_GPSR_EXC_COL (1<<9) /* Bit 9: Excessive Collisions Occured */
1441#define GM_GPSR_LAT_COL (1<<8) /* Bit 8: Late Collisions Occured */
1442 /* Bit 7..6: reserved */
1443#define GM_GPSR_PHY_ST_CH (1<<5) /* Bit 5: PHY Status Change */
1444#define GM_GPSR_GIG_SPEED (1<<4) /* Bit 4: Gigabit Speed (1 = 1000 Mbps) */
1445#define GM_GPSR_PART_MODE (1<<3) /* Bit 3: Partition mode */
1446#define GM_GPSR_FC_RX_DIS (1<<2) /* Bit 2: Rx Flow-Control Mode Disabled */
1447#define GM_GPSR_PROM_EN (1<<1) /* Bit 1: Promiscuous Mode Enabled */
1448 /* Bit 0: reserved */
1449
1450/* GM_GP_CTRL 16 bit r/w General Purpose Control Register */
1451 /* Bit 15: reserved */
1452#define GM_GPCR_PROM_ENA (1<<14) /* Bit 14: Enable Promiscuous Mode */
1453#define GM_GPCR_FC_TX_DIS (1<<13) /* Bit 13: Disable Tx Flow-Control Mode */
1454#define GM_GPCR_TX_ENA (1<<12) /* Bit 12: Enable Transmit */
1455#define GM_GPCR_RX_ENA (1<<11) /* Bit 11: Enable Receive */
1456#define GM_GPCR_BURST_ENA (1<<10) /* Bit 10: Enable Burst Mode */
1457#define GM_GPCR_LOOP_ENA (1<<9) /* Bit 9: Enable MAC Loopback Mode */
1458#define GM_GPCR_PART_ENA (1<<8) /* Bit 8: Enable Partition Mode */
1459#define GM_GPCR_GIGS_ENA (1<<7) /* Bit 7: Gigabit Speed (1000 Mbps) */
1460#define GM_GPCR_FL_PASS (1<<6) /* Bit 6: Force Link Pass */
1461#define GM_GPCR_DUP_FULL (1<<5) /* Bit 5: Full Duplex Mode */
1462#define GM_GPCR_FC_RX_DIS (1<<4) /* Bit 4: Disable Rx Flow-Control Mode */
1463#define GM_GPCR_SPEED_100 (1<<3) /* Bit 3: Port Speed 100 Mbps */
1464#define GM_GPCR_AU_DUP_DIS (1<<2) /* Bit 2: Disable Auto-Update Duplex */
1465#define GM_GPCR_AU_FCT_DIS (1<<1) /* Bit 1: Disable Auto-Update Flow-C. */
1466#define GM_GPCR_AU_SPD_DIS (1<<0) /* Bit 0: Disable Auto-Update Speed */
1467
1468#define GM_GPCR_SPEED_1000 (GM_GPCR_GIGS_ENA | GM_GPCR_SPEED_100)
1469#define GM_GPCR_AU_ALL_DIS (GM_GPCR_AU_DUP_DIS | GM_GPCR_AU_FCT_DIS |\
1470 GM_GPCR_AU_SPD_DIS)
1471
1472/* GM_TX_CTRL 16 bit r/w Transmit Control Register */
1473#define GM_TXCR_FORCE_JAM (1<<15) /* Bit 15: Force Jam / Flow-Control */
1474#define GM_TXCR_CRC_DIS (1<<14) /* Bit 14: Disable insertion of CRC */
1475#define GM_TXCR_PAD_DIS (1<<13) /* Bit 13: Disable padding of packets */
1476#define GM_TXCR_COL_THR_MSK (7<<10) /* Bit 12..10: Collision Threshold */
1477
1478#define TX_COL_THR(x) (SHIFT10(x) & GM_TXCR_COL_THR_MSK)
1479
1480#define TX_COL_DEF 0x04
1481
1482/* GM_RX_CTRL 16 bit r/w Receive Control Register */
1483#define GM_RXCR_UCF_ENA (1<<15) /* Bit 15: Enable Unicast filtering */
1484#define GM_RXCR_MCF_ENA (1<<14) /* Bit 14: Enable Multicast filtering */
1485#define GM_RXCR_CRC_DIS (1<<13) /* Bit 13: Remove 4-byte CRC */
1486#define GM_RXCR_PASS_FC (1<<12) /* Bit 12: Pass FC packets to FIFO */
1487
1488/* GM_TX_PARAM 16 bit r/w Transmit Parameter Register */
1489#define GM_TXPA_JAMLEN_MSK (0x03<<14) /* Bit 15..14: Jam Length */
1490#define GM_TXPA_JAMIPG_MSK (0x1f<<9) /* Bit 13..9: Jam IPG */
1491#define GM_TXPA_JAMDAT_MSK (0x1f<<4) /* Bit 8..4: IPG Jam to Data */
1492 /* Bit 3..0: reserved */
1493
1494#define TX_JAM_LEN_VAL(x) (SHIFT14(x) & GM_TXPA_JAMLEN_MSK)
1495#define TX_JAM_IPG_VAL(x) (SHIFT9(x) & GM_TXPA_JAMIPG_MSK)
1496#define TX_IPG_JAM_DATA(x) (SHIFT4(x) & GM_TXPA_JAMDAT_MSK)
1497
1498#define TX_JAM_LEN_DEF 0x03
1499#define TX_JAM_IPG_DEF 0x0b
1500#define TX_IPG_JAM_DEF 0x1c
1501
1502/* GM_SERIAL_MODE 16 bit r/w Serial Mode Register */
1503#define GM_SMOD_DATABL_MSK (0x1f<<11) /* Bit 15..11: Data Blinder (r/o) */
1504#define GM_SMOD_LIMIT_4 (1<<10) /* Bit 10: 4 consecutive Tx trials */
1505#define GM_SMOD_VLAN_ENA (1<<9) /* Bit 9: Enable VLAN (Max. Frame Len) */
1506#define GM_SMOD_JUMBO_ENA (1<<8) /* Bit 8: Enable Jumbo (Max. Frame Len) */
1507 /* Bit 7..5: reserved */
1508#define GM_SMOD_IPG_MSK 0x1f /* Bit 4..0: Inter-Packet Gap (IPG) */
1509
1510#define DATA_BLIND_VAL(x) (SHIFT11(x) & GM_SMOD_DATABL_MSK)
1511#define DATA_BLIND_DEF 0x04
1512
1513#define IPG_DATA_VAL(x) (x & GM_SMOD_IPG_MSK)
1514#define IPG_DATA_DEF 0x1e
1515
1516/* GM_SMI_CTRL 16 bit r/w SMI Control Register */
1517#define GM_SMI_CT_PHY_A_MSK (0x1f<<11) /* Bit 15..11: PHY Device Address */
1518#define GM_SMI_CT_REG_A_MSK (0x1f<<6) /* Bit 10.. 6: PHY Register Address */
1519#define GM_SMI_CT_OP_RD (1<<5) /* Bit 5: OpCode Read (0=Write)*/
1520#define GM_SMI_CT_RD_VAL (1<<4) /* Bit 4: Read Valid (Read completed) */
1521#define GM_SMI_CT_BUSY (1<<3) /* Bit 3: Busy (Operation in progress) */
1522 /* Bit 2..0: reserved */
1523
1524#define GM_SMI_CT_PHY_AD(x) (SHIFT11(x) & GM_SMI_CT_PHY_A_MSK)
1525#define GM_SMI_CT_REG_AD(x) (SHIFT6(x) & GM_SMI_CT_REG_A_MSK)
1526
1527 /* GM_PHY_ADDR 16 bit r/w GPHY Address Register */
1528 /* Bit 15..6: reserved */
1529#define GM_PAR_MIB_CLR (1<<5) /* Bit 5: Set MIB Clear Counter Mode */
1530#define GM_PAR_MIB_TST (1<<4) /* Bit 4: MIB Load Counter (Test Mode) */
1531 /* Bit 3..0: reserved */
1532
1533/* Receive Frame Status Encoding */
1534#define GMR_FS_LEN (0xffffUL<<16) /* Bit 31..16: Rx Frame Length */
1535 /* Bit 15..14: reserved */
1536#define GMR_FS_VLAN (1L<<13) /* Bit 13: VLAN Packet */
1537#define GMR_FS_JABBER (1L<<12) /* Bit 12: Jabber Packet */
1538#define GMR_FS_UN_SIZE (1L<<11) /* Bit 11: Undersize Packet */
1539#define GMR_FS_MC (1L<<10) /* Bit 10: Multicast Packet */
1540#define GMR_FS_BC (1L<<9) /* Bit 9: Broadcast Packet */
1541#define GMR_FS_RX_OK (1L<<8) /* Bit 8: Receive OK (Good Packet) */
1542#define GMR_FS_GOOD_FC (1L<<7) /* Bit 7: Good Flow-Control Packet */
1543#define GMR_FS_BAD_FC (1L<<6) /* Bit 6: Bad Flow-Control Packet */
1544#define GMR_FS_MII_ERR (1L<<5) /* Bit 5: MII Error */
1545#define GMR_FS_LONG_ERR (1L<<4) /* Bit 4: Too Long Packet */
1546#define GMR_FS_FRAGMENT (1L<<3) /* Bit 3: Fragment */
1547 /* Bit 2: reserved */
1548#define GMR_FS_CRC_ERR (1L<<1) /* Bit 1: CRC Error */
1549#define GMR_FS_RX_FF_OV (1L<<0) /* Bit 0: Rx FIFO Overflow */
1550
1551/*
1552 * GMR_FS_ANY_ERR (analogous to XMR_FS_ANY_ERR)
1553 */
1554#define GMR_FS_ANY_ERR (GMR_FS_CRC_ERR | \
1555 GMR_FS_LONG_ERR | \
1556 GMR_FS_MII_ERR | \
1557 GMR_FS_BAD_FC | \
1558 GMR_FS_GOOD_FC | \
1559 GMR_FS_JABBER)
1560
1561/* Rx GMAC FIFO Flush Mask (default) */
1562#define RX_FF_FL_DEF_MSK (GMR_FS_CRC_ERR | \
1563 GMR_FS_RX_FF_OV | \
1564 GMR_FS_MII_ERR | \
1565 GMR_FS_BAD_FC | \
1566 GMR_FS_GOOD_FC | \
1567 GMR_FS_UN_SIZE | \
1568 GMR_FS_JABBER)
1569
1570/* typedefs *******************************************************************/
1571
1572
1573/* function prototypes ********************************************************/
1574
1575#ifdef __cplusplus
1576}
1577#endif /* __cplusplus */
1578
1579#endif /* __INC_XMAC_H */
diff --git a/drivers/net/sk98lin/skaddr.c b/drivers/net/sk98lin/skaddr.c
deleted file mode 100644
index 6e6c56aa6d6f..000000000000
--- a/drivers/net/sk98lin/skaddr.c
+++ /dev/null
@@ -1,1788 +0,0 @@
1/******************************************************************************
2 *
3 * Name: skaddr.c
4 * Project: Gigabit Ethernet Adapters, ADDR-Module
5 * Version: $Revision: 1.52 $
6 * Date: $Date: 2003/06/02 13:46:15 $
7 * Purpose: Manage Addresses (Multicast and Unicast) and Promiscuous Mode.
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect GmbH.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25/******************************************************************************
26 *
27 * Description:
28 *
29 * This module is intended to manage multicast addresses, address override,
30 * and promiscuous mode on GEnesis and Yukon adapters.
31 *
32 * Address Layout:
33 * port address: physical MAC address
34 * 1st exact match: logical MAC address (GEnesis only)
35 * 2nd exact match: RLMT multicast (GEnesis only)
36 * exact match 3-13: OS-specific multicasts (GEnesis only)
37 *
38 * Include File Hierarchy:
39 *
40 * "skdrv1st.h"
41 * "skdrv2nd.h"
42 *
43 ******************************************************************************/
44
45#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
46static const char SysKonnectFileId[] =
47 "@(#) $Id: skaddr.c,v 1.52 2003/06/02 13:46:15 tschilli Exp $ (C) Marvell.";
48#endif /* DEBUG ||!LINT || !SK_SLIM */
49
50#define __SKADDR_C
51
52#ifdef __cplusplus
53extern "C" {
54#endif /* cplusplus */
55
56#include "h/skdrv1st.h"
57#include "h/skdrv2nd.h"
58
59/* defines ********************************************************************/
60
61
62#define XMAC_POLY 0xEDB88320UL /* CRC32-Poly - XMAC: Little Endian */
63#define GMAC_POLY 0x04C11DB7L /* CRC16-Poly - GMAC: Little Endian */
64#define HASH_BITS 6 /* #bits in hash */
65#define SK_MC_BIT 0x01
66
67/* Error numbers and messages. */
68
69#define SKERR_ADDR_E001 (SK_ERRBASE_ADDR + 0)
70#define SKERR_ADDR_E001MSG "Bad Flags."
71#define SKERR_ADDR_E002 (SKERR_ADDR_E001 + 1)
72#define SKERR_ADDR_E002MSG "New Error."
73
74/* typedefs *******************************************************************/
75
76/* None. */
77
78/* global variables ***********************************************************/
79
80/* 64-bit hash values with all bits set. */
81
82static const SK_U16 OnesHash[4] = {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF};
83
84/* local variables ************************************************************/
85
86#ifdef DEBUG
87static int Next0[SK_MAX_MACS] = {0};
88#endif /* DEBUG */
89
90static int SkAddrGmacMcAdd(SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber,
91 SK_MAC_ADDR *pMc, int Flags);
92static int SkAddrGmacMcClear(SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber,
93 int Flags);
94static int SkAddrGmacMcUpdate(SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber);
95static int SkAddrGmacPromiscuousChange(SK_AC *pAC, SK_IOC IoC,
96 SK_U32 PortNumber, int NewPromMode);
97static int SkAddrXmacMcAdd(SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber,
98 SK_MAC_ADDR *pMc, int Flags);
99static int SkAddrXmacMcClear(SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber,
100 int Flags);
101static int SkAddrXmacMcUpdate(SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber);
102static int SkAddrXmacPromiscuousChange(SK_AC *pAC, SK_IOC IoC,
103 SK_U32 PortNumber, int NewPromMode);
104
105/* functions ******************************************************************/
106
107/******************************************************************************
108 *
109 * SkAddrInit - initialize data, set state to init
110 *
111 * Description:
112 *
113 * SK_INIT_DATA
114 * ============
115 *
116 * This routine clears the multicast tables and resets promiscuous mode.
117 * Some entries are reserved for the "logical MAC address", the
118 * SK-RLMT multicast address, and the BPDU multicast address.
119 *
120 *
121 * SK_INIT_IO
122 * ==========
123 *
124 * All permanent MAC addresses are read from EPROM.
125 * If the current MAC addresses are not already set in software,
126 * they are set to the values of the permanent addresses.
127 * The current addresses are written to the corresponding MAC.
128 *
129 *
130 * SK_INIT_RUN
131 * ===========
132 *
133 * Nothing.
134 *
135 * Context:
136 * init, pageable
137 *
138 * Returns:
139 * SK_ADDR_SUCCESS
140 */
141int SkAddrInit(
142SK_AC *pAC, /* the adapter context */
143SK_IOC IoC, /* I/O context */
144int Level) /* initialization level */
145{
146 int j;
147 SK_U32 i;
148 SK_U8 *InAddr;
149 SK_U16 *OutAddr;
150 SK_ADDR_PORT *pAPort;
151
152 switch (Level) {
153 case SK_INIT_DATA:
154 SK_MEMSET((char *) &pAC->Addr, (SK_U8) 0,
155 (SK_U16) sizeof(SK_ADDR));
156
157 for (i = 0; i < SK_MAX_MACS; i++) {
158 pAPort = &pAC->Addr.Port[i];
159 pAPort->PromMode = SK_PROM_MODE_NONE;
160
161 pAPort->FirstExactMatchRlmt = SK_ADDR_FIRST_MATCH_RLMT;
162 pAPort->FirstExactMatchDrv = SK_ADDR_FIRST_MATCH_DRV;
163 pAPort->NextExactMatchRlmt = SK_ADDR_FIRST_MATCH_RLMT;
164 pAPort->NextExactMatchDrv = SK_ADDR_FIRST_MATCH_DRV;
165 }
166#ifdef xDEBUG
167 for (i = 0; i < SK_MAX_MACS; i++) {
168 if (pAC->Addr.Port[i].NextExactMatchRlmt <
169 SK_ADDR_FIRST_MATCH_RLMT) {
170 Next0[i] |= 4;
171 }
172 }
173#endif /* DEBUG */
174 /* pAC->Addr.InitDone = SK_INIT_DATA; */
175 break;
176
177 case SK_INIT_IO:
178#ifndef SK_NO_RLMT
179 for (i = 0; i < SK_MAX_NETS; i++) {
180 pAC->Addr.Net[i].ActivePort = pAC->Rlmt.Net[i].ActivePort;
181 }
182#endif /* !SK_NO_RLMT */
183#ifdef xDEBUG
184 for (i = 0; i < SK_MAX_MACS; i++) {
185 if (pAC->Addr.Port[i].NextExactMatchRlmt <
186 SK_ADDR_FIRST_MATCH_RLMT) {
187 Next0[i] |= 8;
188 }
189 }
190#endif /* DEBUG */
191
192 /* Read permanent logical MAC address from Control Register File. */
193 for (j = 0; j < SK_MAC_ADDR_LEN; j++) {
194 InAddr = (SK_U8 *) &pAC->Addr.Net[0].PermanentMacAddress.a[j];
195 SK_IN8(IoC, B2_MAC_1 + j, InAddr);
196 }
197
198 if (!pAC->Addr.Net[0].CurrentMacAddressSet) {
199 /* Set the current logical MAC address to the permanent one. */
200 pAC->Addr.Net[0].CurrentMacAddress =
201 pAC->Addr.Net[0].PermanentMacAddress;
202 pAC->Addr.Net[0].CurrentMacAddressSet = SK_TRUE;
203 }
204
205 /* Set the current logical MAC address. */
206 pAC->Addr.Port[pAC->Addr.Net[0].ActivePort].Exact[0] =
207 pAC->Addr.Net[0].CurrentMacAddress;
208#if SK_MAX_NETS > 1
209 /* Set logical MAC address for net 2 to (log | 3). */
210 if (!pAC->Addr.Net[1].CurrentMacAddressSet) {
211 pAC->Addr.Net[1].PermanentMacAddress =
212 pAC->Addr.Net[0].PermanentMacAddress;
213 pAC->Addr.Net[1].PermanentMacAddress.a[5] |= 3;
214 /* Set the current logical MAC address to the permanent one. */
215 pAC->Addr.Net[1].CurrentMacAddress =
216 pAC->Addr.Net[1].PermanentMacAddress;
217 pAC->Addr.Net[1].CurrentMacAddressSet = SK_TRUE;
218 }
219#endif /* SK_MAX_NETS > 1 */
220
221#ifdef DEBUG
222 for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) {
223 SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_INIT,
224 ("Permanent MAC Address (Net%d): %02X %02X %02X %02X %02X %02X\n",
225 i,
226 pAC->Addr.Net[i].PermanentMacAddress.a[0],
227 pAC->Addr.Net[i].PermanentMacAddress.a[1],
228 pAC->Addr.Net[i].PermanentMacAddress.a[2],
229 pAC->Addr.Net[i].PermanentMacAddress.a[3],
230 pAC->Addr.Net[i].PermanentMacAddress.a[4],
231 pAC->Addr.Net[i].PermanentMacAddress.a[5]))
232
233 SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_INIT,
234 ("Logical MAC Address (Net%d): %02X %02X %02X %02X %02X %02X\n",
235 i,
236 pAC->Addr.Net[i].CurrentMacAddress.a[0],
237 pAC->Addr.Net[i].CurrentMacAddress.a[1],
238 pAC->Addr.Net[i].CurrentMacAddress.a[2],
239 pAC->Addr.Net[i].CurrentMacAddress.a[3],
240 pAC->Addr.Net[i].CurrentMacAddress.a[4],
241 pAC->Addr.Net[i].CurrentMacAddress.a[5]))
242 }
243#endif /* DEBUG */
244
245 for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) {
246 pAPort = &pAC->Addr.Port[i];
247
248 /* Read permanent port addresses from Control Register File. */
249 for (j = 0; j < SK_MAC_ADDR_LEN; j++) {
250 InAddr = (SK_U8 *) &pAPort->PermanentMacAddress.a[j];
251 SK_IN8(IoC, B2_MAC_2 + 8 * i + j, InAddr);
252 }
253
254 if (!pAPort->CurrentMacAddressSet) {
255 /*
256 * Set the current and previous physical MAC address
257 * of this port to its permanent MAC address.
258 */
259 pAPort->CurrentMacAddress = pAPort->PermanentMacAddress;
260 pAPort->PreviousMacAddress = pAPort->PermanentMacAddress;
261 pAPort->CurrentMacAddressSet = SK_TRUE;
262 }
263
264 /* Set port's current physical MAC address. */
265 OutAddr = (SK_U16 *) &pAPort->CurrentMacAddress.a[0];
266#ifdef GENESIS
267 if (pAC->GIni.GIGenesis) {
268 XM_OUTADDR(IoC, i, XM_SA, OutAddr);
269 }
270#endif /* GENESIS */
271#ifdef YUKON
272 if (!pAC->GIni.GIGenesis) {
273 GM_OUTADDR(IoC, i, GM_SRC_ADDR_1L, OutAddr);
274 }
275#endif /* YUKON */
276#ifdef DEBUG
277 SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_INIT,
278 ("SkAddrInit: Permanent Physical MAC Address: %02X %02X %02X %02X %02X %02X\n",
279 pAPort->PermanentMacAddress.a[0],
280 pAPort->PermanentMacAddress.a[1],
281 pAPort->PermanentMacAddress.a[2],
282 pAPort->PermanentMacAddress.a[3],
283 pAPort->PermanentMacAddress.a[4],
284 pAPort->PermanentMacAddress.a[5]))
285
286 SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_INIT,
287 ("SkAddrInit: Physical MAC Address: %02X %02X %02X %02X %02X %02X\n",
288 pAPort->CurrentMacAddress.a[0],
289 pAPort->CurrentMacAddress.a[1],
290 pAPort->CurrentMacAddress.a[2],
291 pAPort->CurrentMacAddress.a[3],
292 pAPort->CurrentMacAddress.a[4],
293 pAPort->CurrentMacAddress.a[5]))
294#endif /* DEBUG */
295 }
296 /* pAC->Addr.InitDone = SK_INIT_IO; */
297 break;
298
299 case SK_INIT_RUN:
300#ifdef xDEBUG
301 for (i = 0; i < SK_MAX_MACS; i++) {
302 if (pAC->Addr.Port[i].NextExactMatchRlmt <
303 SK_ADDR_FIRST_MATCH_RLMT) {
304 Next0[i] |= 16;
305 }
306 }
307#endif /* DEBUG */
308
309 /* pAC->Addr.InitDone = SK_INIT_RUN; */
310 break;
311
312 default: /* error */
313 break;
314 }
315
316 return (SK_ADDR_SUCCESS);
317
318} /* SkAddrInit */
319
320#ifndef SK_SLIM
321
322/******************************************************************************
323 *
324 * SkAddrMcClear - clear the multicast table
325 *
326 * Description:
327 * This routine clears the multicast table.
328 *
329 * If not suppressed by Flag SK_MC_SW_ONLY, the hardware is updated
330 * immediately.
331 *
332 * It calls either SkAddrXmacMcClear or SkAddrGmacMcClear, according
333 * to the adapter in use. The real work is done there.
334 *
335 * Context:
336 * runtime, pageable
337 * may be called starting with SK_INIT_DATA with flag SK_MC_SW_ONLY
338 * may be called after SK_INIT_IO without limitation
339 *
340 * Returns:
341 * SK_ADDR_SUCCESS
342 * SK_ADDR_ILLEGAL_PORT
343 */
344int SkAddrMcClear(
345SK_AC *pAC, /* adapter context */
346SK_IOC IoC, /* I/O context */
347SK_U32 PortNumber, /* Index of affected port */
348int Flags) /* permanent/non-perm, sw-only */
349{
350 int ReturnCode;
351
352 if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) {
353 return (SK_ADDR_ILLEGAL_PORT);
354 }
355
356 if (pAC->GIni.GIGenesis) {
357 ReturnCode = SkAddrXmacMcClear(pAC, IoC, PortNumber, Flags);
358 }
359 else {
360 ReturnCode = SkAddrGmacMcClear(pAC, IoC, PortNumber, Flags);
361 }
362
363 return (ReturnCode);
364
365} /* SkAddrMcClear */
366
367#endif /* !SK_SLIM */
368
369#ifndef SK_SLIM
370
371/******************************************************************************
372 *
373 * SkAddrXmacMcClear - clear the multicast table
374 *
375 * Description:
376 * This routine clears the multicast table
377 * (either entry 2 or entries 3-16 and InexactFilter) of the given port.
378 * If not suppressed by Flag SK_MC_SW_ONLY, the hardware is updated
379 * immediately.
380 *
381 * Context:
382 * runtime, pageable
383 * may be called starting with SK_INIT_DATA with flag SK_MC_SW_ONLY
384 * may be called after SK_INIT_IO without limitation
385 *
386 * Returns:
387 * SK_ADDR_SUCCESS
388 * SK_ADDR_ILLEGAL_PORT
389 */
390static int SkAddrXmacMcClear(
391SK_AC *pAC, /* adapter context */
392SK_IOC IoC, /* I/O context */
393SK_U32 PortNumber, /* Index of affected port */
394int Flags) /* permanent/non-perm, sw-only */
395{
396 int i;
397
398 if (Flags & SK_ADDR_PERMANENT) { /* permanent => RLMT */
399
400 /* Clear RLMT multicast addresses. */
401 pAC->Addr.Port[PortNumber].NextExactMatchRlmt = SK_ADDR_FIRST_MATCH_RLMT;
402 }
403 else { /* not permanent => DRV */
404
405 /* Clear InexactFilter */
406 for (i = 0; i < 8; i++) {
407 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] = 0;
408 }
409
410 /* Clear DRV multicast addresses. */
411
412 pAC->Addr.Port[PortNumber].NextExactMatchDrv = SK_ADDR_FIRST_MATCH_DRV;
413 }
414
415 if (!(Flags & SK_MC_SW_ONLY)) {
416 (void) SkAddrXmacMcUpdate(pAC, IoC, PortNumber);
417 }
418
419 return (SK_ADDR_SUCCESS);
420
421} /* SkAddrXmacMcClear */
422
423#endif /* !SK_SLIM */
424
425#ifndef SK_SLIM
426
427/******************************************************************************
428 *
429 * SkAddrGmacMcClear - clear the multicast table
430 *
431 * Description:
432 * This routine clears the multicast hashing table (InexactFilter)
433 * (either the RLMT or the driver bits) of the given port.
434 *
435 * If not suppressed by Flag SK_MC_SW_ONLY, the hardware is updated
436 * immediately.
437 *
438 * Context:
439 * runtime, pageable
440 * may be called starting with SK_INIT_DATA with flag SK_MC_SW_ONLY
441 * may be called after SK_INIT_IO without limitation
442 *
443 * Returns:
444 * SK_ADDR_SUCCESS
445 * SK_ADDR_ILLEGAL_PORT
446 */
447static int SkAddrGmacMcClear(
448SK_AC *pAC, /* adapter context */
449SK_IOC IoC, /* I/O context */
450SK_U32 PortNumber, /* Index of affected port */
451int Flags) /* permanent/non-perm, sw-only */
452{
453 int i;
454
455#ifdef DEBUG
456 SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
457 ("GMAC InexactFilter (not cleared): %02X %02X %02X %02X %02X %02X %02X %02X\n",
458 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[0],
459 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[1],
460 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[2],
461 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[3],
462 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[4],
463 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[5],
464 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[6],
465 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[7]))
466#endif /* DEBUG */
467
468 /* Clear InexactFilter */
469 for (i = 0; i < 8; i++) {
470 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] = 0;
471 }
472
473 if (Flags & SK_ADDR_PERMANENT) { /* permanent => RLMT */
474
475 /* Copy DRV bits to InexactFilter. */
476 for (i = 0; i < 8; i++) {
477 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] |=
478 pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[i];
479
480 /* Clear InexactRlmtFilter. */
481 pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[i] = 0;
482
483 }
484 }
485 else { /* not permanent => DRV */
486
487 /* Copy RLMT bits to InexactFilter. */
488 for (i = 0; i < 8; i++) {
489 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] |=
490 pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[i];
491
492 /* Clear InexactDrvFilter. */
493 pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[i] = 0;
494 }
495 }
496
497#ifdef DEBUG
498 SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
499 ("GMAC InexactFilter (cleared): %02X %02X %02X %02X %02X %02X %02X %02X\n",
500 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[0],
501 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[1],
502 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[2],
503 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[3],
504 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[4],
505 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[5],
506 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[6],
507 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[7]))
508#endif /* DEBUG */
509
510 if (!(Flags & SK_MC_SW_ONLY)) {
511 (void) SkAddrGmacMcUpdate(pAC, IoC, PortNumber);
512 }
513
514 return (SK_ADDR_SUCCESS);
515
516} /* SkAddrGmacMcClear */
517
518#ifndef SK_ADDR_CHEAT
519
520/******************************************************************************
521 *
522 * SkXmacMcHash - hash multicast address
523 *
524 * Description:
525 * This routine computes the hash value for a multicast address.
526 * A CRC32 algorithm is used.
527 *
528 * Notes:
529 * The code was adapted from the XaQti data sheet.
530 *
531 * Context:
532 * runtime, pageable
533 *
534 * Returns:
535 * Hash value of multicast address.
536 */
537static SK_U32 SkXmacMcHash(
538unsigned char *pMc) /* Multicast address */
539{
540 SK_U32 Idx;
541 SK_U32 Bit;
542 SK_U32 Data;
543 SK_U32 Crc;
544
545 Crc = 0xFFFFFFFFUL;
546 for (Idx = 0; Idx < SK_MAC_ADDR_LEN; Idx++) {
547 Data = *pMc++;
548 for (Bit = 0; Bit < 8; Bit++, Data >>= 1) {
549 Crc = (Crc >> 1) ^ (((Crc ^ Data) & 1) ? XMAC_POLY : 0);
550 }
551 }
552
553 return (Crc & ((1 << HASH_BITS) - 1));
554
555} /* SkXmacMcHash */
556
557
558/******************************************************************************
559 *
560 * SkGmacMcHash - hash multicast address
561 *
562 * Description:
563 * This routine computes the hash value for a multicast address.
564 * A CRC16 algorithm is used.
565 *
566 * Notes:
567 *
568 *
569 * Context:
570 * runtime, pageable
571 *
572 * Returns:
573 * Hash value of multicast address.
574 */
575static SK_U32 SkGmacMcHash(
576unsigned char *pMc) /* Multicast address */
577{
578 SK_U32 Data;
579 SK_U32 TmpData;
580 SK_U32 Crc;
581 int Byte;
582 int Bit;
583
584 Crc = 0xFFFFFFFFUL;
585 for (Byte = 0; Byte < 6; Byte++) {
586 /* Get next byte. */
587 Data = (SK_U32) pMc[Byte];
588
589 /* Change bit order in byte. */
590 TmpData = Data;
591 for (Bit = 0; Bit < 8; Bit++) {
592 if (TmpData & 1L) {
593 Data |= 1L << (7 - Bit);
594 }
595 else {
596 Data &= ~(1L << (7 - Bit));
597 }
598 TmpData >>= 1;
599 }
600
601 Crc ^= (Data << 24);
602 for (Bit = 0; Bit < 8; Bit++) {
603 if (Crc & 0x80000000) {
604 Crc = (Crc << 1) ^ GMAC_POLY;
605 }
606 else {
607 Crc <<= 1;
608 }
609 }
610 }
611
612 return (Crc & ((1 << HASH_BITS) - 1));
613
614} /* SkGmacMcHash */
615
616#endif /* !SK_ADDR_CHEAT */
617
618/******************************************************************************
619 *
620 * SkAddrMcAdd - add a multicast address to a port
621 *
622 * Description:
623 * This routine enables reception for a given address on the given port.
624 *
625 * It calls either SkAddrXmacMcAdd or SkAddrGmacMcAdd, according to the
626 * adapter in use. The real work is done there.
627 *
628 * Notes:
629 * The return code is only valid for SK_PROM_MODE_NONE.
630 *
631 * Context:
632 * runtime, pageable
633 * may be called after SK_INIT_DATA
634 *
635 * Returns:
636 * SK_MC_FILTERING_EXACT
637 * SK_MC_FILTERING_INEXACT
638 * SK_MC_ILLEGAL_ADDRESS
639 * SK_MC_ILLEGAL_PORT
640 * SK_MC_RLMT_OVERFLOW
641 */
642int SkAddrMcAdd(
643SK_AC *pAC, /* adapter context */
644SK_IOC IoC, /* I/O context */
645SK_U32 PortNumber, /* Port Number */
646SK_MAC_ADDR *pMc, /* multicast address to be added */
647int Flags) /* permanent/non-permanent */
648{
649 int ReturnCode;
650
651 if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) {
652 return (SK_ADDR_ILLEGAL_PORT);
653 }
654
655 if (pAC->GIni.GIGenesis) {
656 ReturnCode = SkAddrXmacMcAdd(pAC, IoC, PortNumber, pMc, Flags);
657 }
658 else {
659 ReturnCode = SkAddrGmacMcAdd(pAC, IoC, PortNumber, pMc, Flags);
660 }
661
662 return (ReturnCode);
663
664} /* SkAddrMcAdd */
665
666
667/******************************************************************************
668 *
669 * SkAddrXmacMcAdd - add a multicast address to a port
670 *
671 * Description:
672 * This routine enables reception for a given address on the given port.
673 *
674 * Notes:
675 * The return code is only valid for SK_PROM_MODE_NONE.
676 *
677 * The multicast bit is only checked if there are no free exact match
678 * entries.
679 *
680 * Context:
681 * runtime, pageable
682 * may be called after SK_INIT_DATA
683 *
684 * Returns:
685 * SK_MC_FILTERING_EXACT
686 * SK_MC_FILTERING_INEXACT
687 * SK_MC_ILLEGAL_ADDRESS
688 * SK_MC_RLMT_OVERFLOW
689 */
690static int SkAddrXmacMcAdd(
691SK_AC *pAC, /* adapter context */
692SK_IOC IoC, /* I/O context */
693SK_U32 PortNumber, /* Port Number */
694SK_MAC_ADDR *pMc, /* multicast address to be added */
695int Flags) /* permanent/non-permanent */
696{
697 int i;
698 SK_U8 Inexact;
699#ifndef SK_ADDR_CHEAT
700 SK_U32 HashBit;
701#endif /* !defined(SK_ADDR_CHEAT) */
702
703 if (Flags & SK_ADDR_PERMANENT) { /* permanent => RLMT */
704#ifdef xDEBUG
705 if (pAC->Addr.Port[PortNumber].NextExactMatchRlmt <
706 SK_ADDR_FIRST_MATCH_RLMT) {
707 Next0[PortNumber] |= 1;
708 return (SK_MC_RLMT_OVERFLOW);
709 }
710#endif /* DEBUG */
711
712 if (pAC->Addr.Port[PortNumber].NextExactMatchRlmt >
713 SK_ADDR_LAST_MATCH_RLMT) {
714 return (SK_MC_RLMT_OVERFLOW);
715 }
716
717 /* Set a RLMT multicast address. */
718
719 pAC->Addr.Port[PortNumber].Exact[
720 pAC->Addr.Port[PortNumber].NextExactMatchRlmt++] = *pMc;
721
722 return (SK_MC_FILTERING_EXACT);
723 }
724
725#ifdef xDEBUG
726 if (pAC->Addr.Port[PortNumber].NextExactMatchDrv <
727 SK_ADDR_FIRST_MATCH_DRV) {
728 Next0[PortNumber] |= 2;
729 return (SK_MC_RLMT_OVERFLOW);
730 }
731#endif /* DEBUG */
732
733 if (pAC->Addr.Port[PortNumber].NextExactMatchDrv <= SK_ADDR_LAST_MATCH_DRV) {
734
735 /* Set exact match entry. */
736 pAC->Addr.Port[PortNumber].Exact[
737 pAC->Addr.Port[PortNumber].NextExactMatchDrv++] = *pMc;
738
739 /* Clear InexactFilter */
740 for (i = 0; i < 8; i++) {
741 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] = 0;
742 }
743 }
744 else {
745 if (!(pMc->a[0] & SK_MC_BIT)) {
746 /* Hashing only possible with multicast addresses */
747 return (SK_MC_ILLEGAL_ADDRESS);
748 }
749#ifndef SK_ADDR_CHEAT
750 /* Compute hash value of address. */
751 HashBit = 63 - SkXmacMcHash(&pMc->a[0]);
752
753 /* Add bit to InexactFilter. */
754 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[HashBit / 8] |=
755 1 << (HashBit % 8);
756#else /* SK_ADDR_CHEAT */
757 /* Set all bits in InexactFilter. */
758 for (i = 0; i < 8; i++) {
759 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] = 0xFF;
760 }
761#endif /* SK_ADDR_CHEAT */
762 }
763
764 for (Inexact = 0, i = 0; i < 8; i++) {
765 Inexact |= pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i];
766 }
767
768 if (Inexact == 0 && pAC->Addr.Port[PortNumber].PromMode == 0) {
769 return (SK_MC_FILTERING_EXACT);
770 }
771 else {
772 return (SK_MC_FILTERING_INEXACT);
773 }
774
775} /* SkAddrXmacMcAdd */
776
777
778/******************************************************************************
779 *
780 * SkAddrGmacMcAdd - add a multicast address to a port
781 *
782 * Description:
783 * This routine enables reception for a given address on the given port.
784 *
785 * Notes:
786 * The return code is only valid for SK_PROM_MODE_NONE.
787 *
788 * Context:
789 * runtime, pageable
790 * may be called after SK_INIT_DATA
791 *
792 * Returns:
793 * SK_MC_FILTERING_INEXACT
794 * SK_MC_ILLEGAL_ADDRESS
795 */
796static int SkAddrGmacMcAdd(
797SK_AC *pAC, /* adapter context */
798SK_IOC IoC, /* I/O context */
799SK_U32 PortNumber, /* Port Number */
800SK_MAC_ADDR *pMc, /* multicast address to be added */
801int Flags) /* permanent/non-permanent */
802{
803 int i;
804#ifndef SK_ADDR_CHEAT
805 SK_U32 HashBit;
806#endif /* !defined(SK_ADDR_CHEAT) */
807
808 if (!(pMc->a[0] & SK_MC_BIT)) {
809 /* Hashing only possible with multicast addresses */
810 return (SK_MC_ILLEGAL_ADDRESS);
811 }
812
813#ifndef SK_ADDR_CHEAT
814
815 /* Compute hash value of address. */
816 HashBit = SkGmacMcHash(&pMc->a[0]);
817
818 if (Flags & SK_ADDR_PERMANENT) { /* permanent => RLMT */
819
820 /* Add bit to InexactRlmtFilter. */
821 pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[HashBit / 8] |=
822 1 << (HashBit % 8);
823
824 /* Copy bit to InexactFilter. */
825 for (i = 0; i < 8; i++) {
826 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] |=
827 pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[i];
828 }
829#ifdef DEBUG
830 SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
831 ("GMAC InexactRlmtFilter: %02X %02X %02X %02X %02X %02X %02X %02X\n",
832 pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[0],
833 pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[1],
834 pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[2],
835 pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[3],
836 pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[4],
837 pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[5],
838 pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[6],
839 pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[7]))
840#endif /* DEBUG */
841 }
842 else { /* not permanent => DRV */
843
844 /* Add bit to InexactDrvFilter. */
845 pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[HashBit / 8] |=
846 1 << (HashBit % 8);
847
848 /* Copy bit to InexactFilter. */
849 for (i = 0; i < 8; i++) {
850 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] |=
851 pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[i];
852 }
853#ifdef DEBUG
854 SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
855 ("GMAC InexactDrvFilter: %02X %02X %02X %02X %02X %02X %02X %02X\n",
856 pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[0],
857 pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[1],
858 pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[2],
859 pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[3],
860 pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[4],
861 pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[5],
862 pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[6],
863 pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[7]))
864#endif /* DEBUG */
865 }
866
867#else /* SK_ADDR_CHEAT */
868
869 /* Set all bits in InexactFilter. */
870 for (i = 0; i < 8; i++) {
871 pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] = 0xFF;
872 }
873#endif /* SK_ADDR_CHEAT */
874
875 return (SK_MC_FILTERING_INEXACT);
876
877} /* SkAddrGmacMcAdd */
878
879#endif /* !SK_SLIM */
880
881/******************************************************************************
882 *
883 * SkAddrMcUpdate - update the HW MC address table and set the MAC address
884 *
885 * Description:
886 * This routine enables reception of the addresses contained in a local
887 * table for a given port.
888 * It also programs the port's current physical MAC address.
889 *
890 * It calls either SkAddrXmacMcUpdate or SkAddrGmacMcUpdate, according
891 * to the adapter in use. The real work is done there.
892 *
893 * Notes:
894 * The return code is only valid for SK_PROM_MODE_NONE.
895 *
896 * Context:
897 * runtime, pageable
898 * may be called after SK_INIT_IO
899 *
900 * Returns:
901 * SK_MC_FILTERING_EXACT
902 * SK_MC_FILTERING_INEXACT
903 * SK_ADDR_ILLEGAL_PORT
904 */
905int SkAddrMcUpdate(
906SK_AC *pAC, /* adapter context */
907SK_IOC IoC, /* I/O context */
908SK_U32 PortNumber) /* Port Number */
909{
910 int ReturnCode = 0;
911#if (!defined(SK_SLIM) || defined(DEBUG))
912 if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) {
913 return (SK_ADDR_ILLEGAL_PORT);
914 }
915#endif /* !SK_SLIM || DEBUG */
916
917#ifdef GENESIS
918 if (pAC->GIni.GIGenesis) {
919 ReturnCode = SkAddrXmacMcUpdate(pAC, IoC, PortNumber);
920 }
921#endif /* GENESIS */
922#ifdef YUKON
923 if (!pAC->GIni.GIGenesis) {
924 ReturnCode = SkAddrGmacMcUpdate(pAC, IoC, PortNumber);
925 }
926#endif /* YUKON */
927 return (ReturnCode);
928
929} /* SkAddrMcUpdate */
930
931
932#ifdef GENESIS
933
934/******************************************************************************
935 *
936 * SkAddrXmacMcUpdate - update the HW MC address table and set the MAC address
937 *
938 * Description:
939 * This routine enables reception of the addresses contained in a local
940 * table for a given port.
941 * It also programs the port's current physical MAC address.
942 *
943 * Notes:
944 * The return code is only valid for SK_PROM_MODE_NONE.
945 *
946 * Context:
947 * runtime, pageable
948 * may be called after SK_INIT_IO
949 *
950 * Returns:
951 * SK_MC_FILTERING_EXACT
952 * SK_MC_FILTERING_INEXACT
953 * SK_ADDR_ILLEGAL_PORT
954 */
955static int SkAddrXmacMcUpdate(
956SK_AC *pAC, /* adapter context */
957SK_IOC IoC, /* I/O context */
958SK_U32 PortNumber) /* Port Number */
959{
960 SK_U32 i;
961 SK_U8 Inexact;
962 SK_U16 *OutAddr;
963 SK_ADDR_PORT *pAPort;
964
965 SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
966 ("SkAddrXmacMcUpdate on Port %u.\n", PortNumber))
967
968 pAPort = &pAC->Addr.Port[PortNumber];
969
970#ifdef DEBUG
971 SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
972 ("Next0 on Port %d: %d\n", PortNumber, Next0[PortNumber]))
973#endif /* DEBUG */
974
975 /* Start with 0 to also program the logical MAC address. */
976 for (i = 0; i < pAPort->NextExactMatchRlmt; i++) {
977 /* Set exact match address i on XMAC */
978 OutAddr = (SK_U16 *) &pAPort->Exact[i].a[0];
979 XM_OUTADDR(IoC, PortNumber, XM_EXM(i), OutAddr);
980 }
981
982 /* Clear other permanent exact match addresses on XMAC */
983 if (pAPort->NextExactMatchRlmt <= SK_ADDR_LAST_MATCH_RLMT) {
984
985 SkXmClrExactAddr(pAC, IoC, PortNumber, pAPort->NextExactMatchRlmt,
986 SK_ADDR_LAST_MATCH_RLMT);
987 }
988
989 for (i = pAPort->FirstExactMatchDrv; i < pAPort->NextExactMatchDrv; i++) {
990 OutAddr = (SK_U16 *) &pAPort->Exact[i].a[0];
991 XM_OUTADDR(IoC, PortNumber, XM_EXM(i), OutAddr);
992 }
993
994 /* Clear other non-permanent exact match addresses on XMAC */
995 if (pAPort->NextExactMatchDrv <= SK_ADDR_LAST_MATCH_DRV) {
996
997 SkXmClrExactAddr(pAC, IoC, PortNumber, pAPort->NextExactMatchDrv,
998 SK_ADDR_LAST_MATCH_DRV);
999 }
1000
1001 for (Inexact = 0, i = 0; i < 8; i++) {
1002 Inexact |= pAPort->InexactFilter.Bytes[i];
1003 }
1004
1005 if (pAPort->PromMode & SK_PROM_MODE_ALL_MC) {
1006
1007 /* Set all bits in 64-bit hash register. */
1008 XM_OUTHASH(IoC, PortNumber, XM_HSM, &OnesHash);
1009
1010 /* Enable Hashing */
1011 SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE);
1012 }
1013 else if (Inexact != 0) {
1014
1015 /* Set 64-bit hash register to InexactFilter. */
1016 XM_OUTHASH(IoC, PortNumber, XM_HSM, &pAPort->InexactFilter.Bytes[0]);
1017
1018 /* Enable Hashing */
1019 SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE);
1020 }
1021 else {
1022 /* Disable Hashing */
1023 SkMacHashing(pAC, IoC, (int) PortNumber, SK_FALSE);
1024 }
1025
1026 if (pAPort->PromMode != SK_PROM_MODE_NONE) {
1027 (void) SkAddrXmacPromiscuousChange(pAC, IoC, PortNumber, pAPort->PromMode);
1028 }
1029
1030 /* Set port's current physical MAC address. */
1031 OutAddr = (SK_U16 *) &pAPort->CurrentMacAddress.a[0];
1032
1033 XM_OUTADDR(IoC, PortNumber, XM_SA, OutAddr);
1034
1035#ifdef xDEBUG
1036 for (i = 0; i < pAPort->NextExactMatchRlmt; i++) {
1037 SK_U8 InAddr8[6];
1038 SK_U16 *InAddr;
1039
1040 /* Get exact match address i from port PortNumber. */
1041 InAddr = (SK_U16 *) &InAddr8[0];
1042
1043 XM_INADDR(IoC, PortNumber, XM_EXM(i), InAddr);
1044
1045 SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
1046 ("SkAddrXmacMcUpdate: MC address %d on Port %u: ",
1047 "%02x %02x %02x %02x %02x %02x -- %02x %02x %02x %02x %02x %02x\n",
1048 i,
1049 PortNumber,
1050 InAddr8[0],
1051 InAddr8[1],
1052 InAddr8[2],
1053 InAddr8[3],
1054 InAddr8[4],
1055 InAddr8[5],
1056 pAPort->Exact[i].a[0],
1057 pAPort->Exact[i].a[1],
1058 pAPort->Exact[i].a[2],
1059 pAPort->Exact[i].a[3],
1060 pAPort->Exact[i].a[4],
1061 pAPort->Exact[i].a[5]))
1062 }
1063#endif /* DEBUG */
1064
1065 /* Determine return value. */
1066 if (Inexact == 0 && pAPort->PromMode == 0) {
1067 return (SK_MC_FILTERING_EXACT);
1068 }
1069 else {
1070 return (SK_MC_FILTERING_INEXACT);
1071 }
1072
1073} /* SkAddrXmacMcUpdate */
1074
1075#endif /* GENESIS */
1076
1077#ifdef YUKON
1078
1079/******************************************************************************
1080 *
1081 * SkAddrGmacMcUpdate - update the HW MC address table and set the MAC address
1082 *
1083 * Description:
1084 * This routine enables reception of the addresses contained in a local
1085 * table for a given port.
1086 * It also programs the port's current physical MAC address.
1087 *
1088 * Notes:
1089 * The return code is only valid for SK_PROM_MODE_NONE.
1090 *
1091 * Context:
1092 * runtime, pageable
1093 * may be called after SK_INIT_IO
1094 *
1095 * Returns:
1096 * SK_MC_FILTERING_EXACT
1097 * SK_MC_FILTERING_INEXACT
1098 * SK_ADDR_ILLEGAL_PORT
1099 */
1100static int SkAddrGmacMcUpdate(
1101SK_AC *pAC, /* adapter context */
1102SK_IOC IoC, /* I/O context */
1103SK_U32 PortNumber) /* Port Number */
1104{
1105#ifndef SK_SLIM
1106 SK_U32 i;
1107 SK_U8 Inexact;
1108#endif /* not SK_SLIM */
1109 SK_U16 *OutAddr;
1110 SK_ADDR_PORT *pAPort;
1111
1112 SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
1113 ("SkAddrGmacMcUpdate on Port %u.\n", PortNumber))
1114
1115 pAPort = &pAC->Addr.Port[PortNumber];
1116
1117#ifdef DEBUG
1118 SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
1119 ("Next0 on Port %d: %d\n", PortNumber, Next0[PortNumber]))
1120#endif /* DEBUG */
1121
1122#ifndef SK_SLIM
1123 for (Inexact = 0, i = 0; i < 8; i++) {
1124 Inexact |= pAPort->InexactFilter.Bytes[i];
1125 }
1126
1127 /* Set 64-bit hash register to InexactFilter. */
1128 GM_OUTHASH(IoC, PortNumber, GM_MC_ADDR_H1,
1129 &pAPort->InexactFilter.Bytes[0]);
1130
1131 if (pAPort->PromMode & SK_PROM_MODE_ALL_MC) {
1132
1133 /* Set all bits in 64-bit hash register. */
1134 GM_OUTHASH(IoC, PortNumber, GM_MC_ADDR_H1, &OnesHash);
1135
1136 /* Enable Hashing */
1137 SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE);
1138 }
1139 else {
1140 /* Enable Hashing. */
1141 SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE);
1142 }
1143
1144 if (pAPort->PromMode != SK_PROM_MODE_NONE) {
1145 (void) SkAddrGmacPromiscuousChange(pAC, IoC, PortNumber, pAPort->PromMode);
1146 }
1147#else /* SK_SLIM */
1148
1149 /* Set all bits in 64-bit hash register. */
1150 GM_OUTHASH(IoC, PortNumber, GM_MC_ADDR_H1, &OnesHash);
1151
1152 /* Enable Hashing */
1153 SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE);
1154
1155 (void) SkAddrGmacPromiscuousChange(pAC, IoC, PortNumber, pAPort->PromMode);
1156
1157#endif /* SK_SLIM */
1158
1159 /* Set port's current physical MAC address. */
1160 OutAddr = (SK_U16 *) &pAPort->CurrentMacAddress.a[0];
1161 GM_OUTADDR(IoC, PortNumber, GM_SRC_ADDR_1L, OutAddr);
1162
1163 /* Set port's current logical MAC address. */
1164 OutAddr = (SK_U16 *) &pAPort->Exact[0].a[0];
1165 GM_OUTADDR(IoC, PortNumber, GM_SRC_ADDR_2L, OutAddr);
1166
1167#ifdef DEBUG
1168 SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
1169 ("SkAddrGmacMcUpdate: Permanent Physical MAC Address: %02X %02X %02X %02X %02X %02X\n",
1170 pAPort->Exact[0].a[0],
1171 pAPort->Exact[0].a[1],
1172 pAPort->Exact[0].a[2],
1173 pAPort->Exact[0].a[3],
1174 pAPort->Exact[0].a[4],
1175 pAPort->Exact[0].a[5]))
1176
1177 SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
1178 ("SkAddrGmacMcUpdate: Physical MAC Address: %02X %02X %02X %02X %02X %02X\n",
1179 pAPort->CurrentMacAddress.a[0],
1180 pAPort->CurrentMacAddress.a[1],
1181 pAPort->CurrentMacAddress.a[2],
1182 pAPort->CurrentMacAddress.a[3],
1183 pAPort->CurrentMacAddress.a[4],
1184 pAPort->CurrentMacAddress.a[5]))
1185#endif /* DEBUG */
1186
1187#ifndef SK_SLIM
1188 /* Determine return value. */
1189 if (Inexact == 0 && pAPort->PromMode == 0) {
1190 return (SK_MC_FILTERING_EXACT);
1191 }
1192 else {
1193 return (SK_MC_FILTERING_INEXACT);
1194 }
1195#else /* SK_SLIM */
1196 return (SK_MC_FILTERING_INEXACT);
1197#endif /* SK_SLIM */
1198
1199} /* SkAddrGmacMcUpdate */
1200
1201#endif /* YUKON */
1202
1203#ifndef SK_NO_MAO
1204
1205/******************************************************************************
1206 *
1207 * SkAddrOverride - override a port's MAC address
1208 *
1209 * Description:
1210 * This routine overrides the MAC address of one port.
1211 *
1212 * Context:
1213 * runtime, pageable
1214 * may be called after SK_INIT_IO
1215 *
1216 * Returns:
1217 * SK_ADDR_SUCCESS if successful.
1218 * SK_ADDR_DUPLICATE_ADDRESS if duplicate MAC address.
1219 * SK_ADDR_MULTICAST_ADDRESS if multicast or broadcast address.
1220 * SK_ADDR_TOO_EARLY if SK_INIT_IO was not executed before.
1221 */
1222int SkAddrOverride(
1223SK_AC *pAC, /* adapter context */
1224SK_IOC IoC, /* I/O context */
1225SK_U32 PortNumber, /* Port Number */
1226SK_MAC_ADDR SK_FAR *pNewAddr, /* new MAC address */
1227int Flags) /* logical/physical MAC address */
1228{
1229#ifndef SK_NO_RLMT
1230 SK_EVPARA Para;
1231#endif /* !SK_NO_RLMT */
1232 SK_U32 NetNumber;
1233 SK_U32 i;
1234 SK_U16 SK_FAR *OutAddr;
1235
1236#ifndef SK_NO_RLMT
1237 NetNumber = pAC->Rlmt.Port[PortNumber].Net->NetNumber;
1238#else
1239 NetNumber = 0;
1240#endif /* SK_NO_RLMT */
1241#if (!defined(SK_SLIM) || defined(DEBUG))
1242 if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) {
1243 return (SK_ADDR_ILLEGAL_PORT);
1244 }
1245#endif /* !SK_SLIM || DEBUG */
1246 if (pNewAddr != NULL && (pNewAddr->a[0] & SK_MC_BIT) != 0) {
1247 return (SK_ADDR_MULTICAST_ADDRESS);
1248 }
1249
1250 if (!pAC->Addr.Net[NetNumber].CurrentMacAddressSet) {
1251 return (SK_ADDR_TOO_EARLY);
1252 }
1253
1254 if (Flags & SK_ADDR_SET_LOGICAL) { /* Activate logical MAC address. */
1255 /* Parameter *pNewAddr is ignored. */
1256 for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) {
1257 if (!pAC->Addr.Port[i].CurrentMacAddressSet) {
1258 return (SK_ADDR_TOO_EARLY);
1259 }
1260 }
1261#ifndef SK_NO_RLMT
1262 /* Set PortNumber to number of net's active port. */
1263 PortNumber = pAC->Rlmt.Net[NetNumber].
1264 Port[pAC->Addr.Net[NetNumber].ActivePort]->PortNumber;
1265#endif /* !SK_NO_RLMT */
1266 pAC->Addr.Port[PortNumber].Exact[0] =
1267 pAC->Addr.Net[NetNumber].CurrentMacAddress;
1268
1269 /* Write address to first exact match entry of active port. */
1270 (void) SkAddrMcUpdate(pAC, IoC, PortNumber);
1271 }
1272 else if (Flags & SK_ADDR_CLEAR_LOGICAL) {
1273 /* Deactivate logical MAC address. */
1274 /* Parameter *pNewAddr is ignored. */
1275 for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) {
1276 if (!pAC->Addr.Port[i].CurrentMacAddressSet) {
1277 return (SK_ADDR_TOO_EARLY);
1278 }
1279 }
1280#ifndef SK_NO_RLMT
1281 /* Set PortNumber to number of net's active port. */
1282 PortNumber = pAC->Rlmt.Net[NetNumber].
1283 Port[pAC->Addr.Net[NetNumber].ActivePort]->PortNumber;
1284#endif /* !SK_NO_RLMT */
1285 for (i = 0; i < SK_MAC_ADDR_LEN; i++ ) {
1286 pAC->Addr.Port[PortNumber].Exact[0].a[i] = 0;
1287 }
1288
1289 /* Write address to first exact match entry of active port. */
1290 (void) SkAddrMcUpdate(pAC, IoC, PortNumber);
1291 }
1292 else if (Flags & SK_ADDR_PHYSICAL_ADDRESS) { /* Physical MAC address. */
1293 if (SK_ADDR_EQUAL(pNewAddr->a,
1294 pAC->Addr.Net[NetNumber].CurrentMacAddress.a)) {
1295 return (SK_ADDR_DUPLICATE_ADDRESS);
1296 }
1297
1298 for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) {
1299 if (!pAC->Addr.Port[i].CurrentMacAddressSet) {
1300 return (SK_ADDR_TOO_EARLY);
1301 }
1302
1303 if (SK_ADDR_EQUAL(pNewAddr->a,
1304 pAC->Addr.Port[i].CurrentMacAddress.a)) {
1305 if (i == PortNumber) {
1306 return (SK_ADDR_SUCCESS);
1307 }
1308 else {
1309 return (SK_ADDR_DUPLICATE_ADDRESS);
1310 }
1311 }
1312 }
1313
1314 pAC->Addr.Port[PortNumber].PreviousMacAddress =
1315 pAC->Addr.Port[PortNumber].CurrentMacAddress;
1316 pAC->Addr.Port[PortNumber].CurrentMacAddress = *pNewAddr;
1317
1318 /* Change port's physical MAC address. */
1319 OutAddr = (SK_U16 SK_FAR *) pNewAddr;
1320#ifdef GENESIS
1321 if (pAC->GIni.GIGenesis) {
1322 XM_OUTADDR(IoC, PortNumber, XM_SA, OutAddr);
1323 }
1324#endif /* GENESIS */
1325#ifdef YUKON
1326 if (!pAC->GIni.GIGenesis) {
1327 GM_OUTADDR(IoC, PortNumber, GM_SRC_ADDR_1L, OutAddr);
1328 }
1329#endif /* YUKON */
1330
1331#ifndef SK_NO_RLMT
1332 /* Report address change to RLMT. */
1333 Para.Para32[0] = PortNumber;
1334 Para.Para32[0] = -1;
1335 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_PORT_ADDR, Para);
1336#endif /* !SK_NO_RLMT */
1337 }
1338 else { /* Logical MAC address. */
1339 if (SK_ADDR_EQUAL(pNewAddr->a,
1340 pAC->Addr.Net[NetNumber].CurrentMacAddress.a)) {
1341 return (SK_ADDR_SUCCESS);
1342 }
1343
1344 for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) {
1345 if (!pAC->Addr.Port[i].CurrentMacAddressSet) {
1346 return (SK_ADDR_TOO_EARLY);
1347 }
1348
1349 if (SK_ADDR_EQUAL(pNewAddr->a,
1350 pAC->Addr.Port[i].CurrentMacAddress.a)) {
1351 return (SK_ADDR_DUPLICATE_ADDRESS);
1352 }
1353 }
1354
1355 /*
1356 * In case that the physical and the logical MAC addresses are equal
1357 * we must also change the physical MAC address here.
1358 * In this case we have an adapter which initially was programmed with
1359 * two identical MAC addresses.
1360 */
1361 if (SK_ADDR_EQUAL(pAC->Addr.Port[PortNumber].CurrentMacAddress.a,
1362 pAC->Addr.Port[PortNumber].Exact[0].a)) {
1363
1364 pAC->Addr.Port[PortNumber].PreviousMacAddress =
1365 pAC->Addr.Port[PortNumber].CurrentMacAddress;
1366 pAC->Addr.Port[PortNumber].CurrentMacAddress = *pNewAddr;
1367
1368#ifndef SK_NO_RLMT
1369 /* Report address change to RLMT. */
1370 Para.Para32[0] = PortNumber;
1371 Para.Para32[0] = -1;
1372 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_PORT_ADDR, Para);
1373#endif /* !SK_NO_RLMT */
1374 }
1375
1376#ifndef SK_NO_RLMT
1377 /* Set PortNumber to number of net's active port. */
1378 PortNumber = pAC->Rlmt.Net[NetNumber].
1379 Port[pAC->Addr.Net[NetNumber].ActivePort]->PortNumber;
1380#endif /* !SK_NO_RLMT */
1381 pAC->Addr.Net[NetNumber].CurrentMacAddress = *pNewAddr;
1382 pAC->Addr.Port[PortNumber].Exact[0] = *pNewAddr;
1383#ifdef DEBUG
1384 SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
1385 ("SkAddrOverride: Permanent MAC Address: %02X %02X %02X %02X %02X %02X\n",
1386 pAC->Addr.Net[NetNumber].PermanentMacAddress.a[0],
1387 pAC->Addr.Net[NetNumber].PermanentMacAddress.a[1],
1388 pAC->Addr.Net[NetNumber].PermanentMacAddress.a[2],
1389 pAC->Addr.Net[NetNumber].PermanentMacAddress.a[3],
1390 pAC->Addr.Net[NetNumber].PermanentMacAddress.a[4],
1391 pAC->Addr.Net[NetNumber].PermanentMacAddress.a[5]))
1392
1393 SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
1394 ("SkAddrOverride: New logical MAC Address: %02X %02X %02X %02X %02X %02X\n",
1395 pAC->Addr.Net[NetNumber].CurrentMacAddress.a[0],
1396 pAC->Addr.Net[NetNumber].CurrentMacAddress.a[1],
1397 pAC->Addr.Net[NetNumber].CurrentMacAddress.a[2],
1398 pAC->Addr.Net[NetNumber].CurrentMacAddress.a[3],
1399 pAC->Addr.Net[NetNumber].CurrentMacAddress.a[4],
1400 pAC->Addr.Net[NetNumber].CurrentMacAddress.a[5]))
1401#endif /* DEBUG */
1402
1403 /* Write address to first exact match entry of active port. */
1404 (void) SkAddrMcUpdate(pAC, IoC, PortNumber);
1405 }
1406
1407 return (SK_ADDR_SUCCESS);
1408
1409} /* SkAddrOverride */
1410
1411
1412#endif /* SK_NO_MAO */
1413
1414/******************************************************************************
1415 *
1416 * SkAddrPromiscuousChange - set promiscuous mode for given port
1417 *
1418 * Description:
1419 * This routine manages promiscuous mode:
1420 * - none
1421 * - all LLC frames
1422 * - all MC frames
1423 *
1424 * It calls either SkAddrXmacPromiscuousChange or
1425 * SkAddrGmacPromiscuousChange, according to the adapter in use.
1426 * The real work is done there.
1427 *
1428 * Context:
1429 * runtime, pageable
1430 * may be called after SK_INIT_IO
1431 *
1432 * Returns:
1433 * SK_ADDR_SUCCESS
1434 * SK_ADDR_ILLEGAL_PORT
1435 */
1436int SkAddrPromiscuousChange(
1437SK_AC *pAC, /* adapter context */
1438SK_IOC IoC, /* I/O context */
1439SK_U32 PortNumber, /* port whose promiscuous mode changes */
1440int NewPromMode) /* new promiscuous mode */
1441{
1442 int ReturnCode = 0;
1443#if (!defined(SK_SLIM) || defined(DEBUG))
1444 if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) {
1445 return (SK_ADDR_ILLEGAL_PORT);
1446 }
1447#endif /* !SK_SLIM || DEBUG */
1448
1449#ifdef GENESIS
1450 if (pAC->GIni.GIGenesis) {
1451 ReturnCode =
1452 SkAddrXmacPromiscuousChange(pAC, IoC, PortNumber, NewPromMode);
1453 }
1454#endif /* GENESIS */
1455#ifdef YUKON
1456 if (!pAC->GIni.GIGenesis) {
1457 ReturnCode =
1458 SkAddrGmacPromiscuousChange(pAC, IoC, PortNumber, NewPromMode);
1459 }
1460#endif /* YUKON */
1461
1462 return (ReturnCode);
1463
1464} /* SkAddrPromiscuousChange */
1465
1466#ifdef GENESIS
1467
1468/******************************************************************************
1469 *
1470 * SkAddrXmacPromiscuousChange - set promiscuous mode for given port
1471 *
1472 * Description:
1473 * This routine manages promiscuous mode:
1474 * - none
1475 * - all LLC frames
1476 * - all MC frames
1477 *
1478 * Context:
1479 * runtime, pageable
1480 * may be called after SK_INIT_IO
1481 *
1482 * Returns:
1483 * SK_ADDR_SUCCESS
1484 * SK_ADDR_ILLEGAL_PORT
1485 */
1486static int SkAddrXmacPromiscuousChange(
1487SK_AC *pAC, /* adapter context */
1488SK_IOC IoC, /* I/O context */
1489SK_U32 PortNumber, /* port whose promiscuous mode changes */
1490int NewPromMode) /* new promiscuous mode */
1491{
1492 int i;
1493 SK_BOOL InexactModeBit;
1494 SK_U8 Inexact;
1495 SK_U8 HwInexact;
1496 SK_FILTER64 HwInexactFilter;
1497 SK_U16 LoMode; /* Lower 16 bits of XMAC Mode Register. */
1498 int CurPromMode = SK_PROM_MODE_NONE;
1499
1500 /* Read CurPromMode from Hardware. */
1501 XM_IN16(IoC, PortNumber, XM_MODE, &LoMode);
1502
1503 if ((LoMode & XM_MD_ENA_PROM) != 0) {
1504 /* Promiscuous mode! */
1505 CurPromMode |= SK_PROM_MODE_LLC;
1506 }
1507
1508 for (Inexact = 0xFF, i = 0; i < 8; i++) {
1509 Inexact &= pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i];
1510 }
1511 if (Inexact == 0xFF) {
1512 CurPromMode |= (pAC->Addr.Port[PortNumber].PromMode & SK_PROM_MODE_ALL_MC);
1513 }
1514 else {
1515 /* Get InexactModeBit (bit XM_MD_ENA_HASH in mode register) */
1516 XM_IN16(IoC, PortNumber, XM_MODE, &LoMode);
1517
1518 InexactModeBit = (LoMode & XM_MD_ENA_HASH) != 0;
1519
1520 /* Read 64-bit hash register from XMAC */
1521 XM_INHASH(IoC, PortNumber, XM_HSM, &HwInexactFilter.Bytes[0]);
1522
1523 for (HwInexact = 0xFF, i = 0; i < 8; i++) {
1524 HwInexact &= HwInexactFilter.Bytes[i];
1525 }
1526
1527 if (InexactModeBit && (HwInexact == 0xFF)) {
1528 CurPromMode |= SK_PROM_MODE_ALL_MC;
1529 }
1530 }
1531
1532 pAC->Addr.Port[PortNumber].PromMode = NewPromMode;
1533
1534 if (NewPromMode == CurPromMode) {
1535 return (SK_ADDR_SUCCESS);
1536 }
1537
1538 if ((NewPromMode & SK_PROM_MODE_ALL_MC) &&
1539 !(CurPromMode & SK_PROM_MODE_ALL_MC)) { /* All MC. */
1540
1541 /* Set all bits in 64-bit hash register. */
1542 XM_OUTHASH(IoC, PortNumber, XM_HSM, &OnesHash);
1543
1544 /* Enable Hashing */
1545 SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE);
1546 }
1547 else if ((CurPromMode & SK_PROM_MODE_ALL_MC) &&
1548 !(NewPromMode & SK_PROM_MODE_ALL_MC)) { /* Norm MC. */
1549 for (Inexact = 0, i = 0; i < 8; i++) {
1550 Inexact |= pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i];
1551 }
1552 if (Inexact == 0) {
1553 /* Disable Hashing */
1554 SkMacHashing(pAC, IoC, (int) PortNumber, SK_FALSE);
1555 }
1556 else {
1557 /* Set 64-bit hash register to InexactFilter. */
1558 XM_OUTHASH(IoC, PortNumber, XM_HSM,
1559 &pAC->Addr.Port[PortNumber].InexactFilter.Bytes[0]);
1560
1561 /* Enable Hashing */
1562 SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE);
1563 }
1564 }
1565
1566 if ((NewPromMode & SK_PROM_MODE_LLC) &&
1567 !(CurPromMode & SK_PROM_MODE_LLC)) { /* Prom. LLC */
1568 /* Set the MAC in Promiscuous Mode */
1569 SkMacPromiscMode(pAC, IoC, (int) PortNumber, SK_TRUE);
1570 }
1571 else if ((CurPromMode & SK_PROM_MODE_LLC) &&
1572 !(NewPromMode & SK_PROM_MODE_LLC)) { /* Norm. LLC. */
1573 /* Clear Promiscuous Mode */
1574 SkMacPromiscMode(pAC, IoC, (int) PortNumber, SK_FALSE);
1575 }
1576
1577 return (SK_ADDR_SUCCESS);
1578
1579} /* SkAddrXmacPromiscuousChange */
1580
1581#endif /* GENESIS */
1582
1583#ifdef YUKON
1584
1585/******************************************************************************
1586 *
1587 * SkAddrGmacPromiscuousChange - set promiscuous mode for given port
1588 *
1589 * Description:
1590 * This routine manages promiscuous mode:
1591 * - none
1592 * - all LLC frames
1593 * - all MC frames
1594 *
1595 * Context:
1596 * runtime, pageable
1597 * may be called after SK_INIT_IO
1598 *
1599 * Returns:
1600 * SK_ADDR_SUCCESS
1601 * SK_ADDR_ILLEGAL_PORT
1602 */
1603static int SkAddrGmacPromiscuousChange(
1604SK_AC *pAC, /* adapter context */
1605SK_IOC IoC, /* I/O context */
1606SK_U32 PortNumber, /* port whose promiscuous mode changes */
1607int NewPromMode) /* new promiscuous mode */
1608{
1609 SK_U16 ReceiveControl; /* GMAC Receive Control Register */
1610 int CurPromMode = SK_PROM_MODE_NONE;
1611
1612 /* Read CurPromMode from Hardware. */
1613 GM_IN16(IoC, PortNumber, GM_RX_CTRL, &ReceiveControl);
1614
1615 if ((ReceiveControl & (GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA)) == 0) {
1616 /* Promiscuous mode! */
1617 CurPromMode |= SK_PROM_MODE_LLC;
1618 }
1619
1620 if ((ReceiveControl & GM_RXCR_MCF_ENA) == 0) {
1621 /* All Multicast mode! */
1622 CurPromMode |= (pAC->Addr.Port[PortNumber].PromMode & SK_PROM_MODE_ALL_MC);
1623 }
1624
1625 pAC->Addr.Port[PortNumber].PromMode = NewPromMode;
1626
1627 if (NewPromMode == CurPromMode) {
1628 return (SK_ADDR_SUCCESS);
1629 }
1630
1631 if ((NewPromMode & SK_PROM_MODE_ALL_MC) &&
1632 !(CurPromMode & SK_PROM_MODE_ALL_MC)) { /* All MC */
1633
1634 /* Set all bits in 64-bit hash register. */
1635 GM_OUTHASH(IoC, PortNumber, GM_MC_ADDR_H1, &OnesHash);
1636
1637 /* Enable Hashing */
1638 SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE);
1639 }
1640
1641 if ((CurPromMode & SK_PROM_MODE_ALL_MC) &&
1642 !(NewPromMode & SK_PROM_MODE_ALL_MC)) { /* Norm. MC */
1643
1644 /* Set 64-bit hash register to InexactFilter. */
1645 GM_OUTHASH(IoC, PortNumber, GM_MC_ADDR_H1,
1646 &pAC->Addr.Port[PortNumber].InexactFilter.Bytes[0]);
1647
1648 /* Enable Hashing. */
1649 SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE);
1650 }
1651
1652 if ((NewPromMode & SK_PROM_MODE_LLC) &&
1653 !(CurPromMode & SK_PROM_MODE_LLC)) { /* Prom. LLC */
1654
1655 /* Set the MAC to Promiscuous Mode. */
1656 SkMacPromiscMode(pAC, IoC, (int) PortNumber, SK_TRUE);
1657 }
1658 else if ((CurPromMode & SK_PROM_MODE_LLC) &&
1659 !(NewPromMode & SK_PROM_MODE_LLC)) { /* Norm. LLC */
1660
1661 /* Clear Promiscuous Mode. */
1662 SkMacPromiscMode(pAC, IoC, (int) PortNumber, SK_FALSE);
1663 }
1664
1665 return (SK_ADDR_SUCCESS);
1666
1667} /* SkAddrGmacPromiscuousChange */
1668
1669#endif /* YUKON */
1670
1671#ifndef SK_SLIM
1672
1673/******************************************************************************
1674 *
1675 * SkAddrSwap - swap address info
1676 *
1677 * Description:
1678 * This routine swaps address info of two ports.
1679 *
1680 * Context:
1681 * runtime, pageable
1682 * may be called after SK_INIT_IO
1683 *
1684 * Returns:
1685 * SK_ADDR_SUCCESS
1686 * SK_ADDR_ILLEGAL_PORT
1687 */
1688int SkAddrSwap(
1689SK_AC *pAC, /* adapter context */
1690SK_IOC IoC, /* I/O context */
1691SK_U32 FromPortNumber, /* Port1 Index */
1692SK_U32 ToPortNumber) /* Port2 Index */
1693{
1694 int i;
1695 SK_U8 Byte;
1696 SK_MAC_ADDR MacAddr;
1697 SK_U32 DWord;
1698
1699 if (FromPortNumber >= (SK_U32) pAC->GIni.GIMacsFound) {
1700 return (SK_ADDR_ILLEGAL_PORT);
1701 }
1702
1703 if (ToPortNumber >= (SK_U32) pAC->GIni.GIMacsFound) {
1704 return (SK_ADDR_ILLEGAL_PORT);
1705 }
1706
1707 if (pAC->Rlmt.Port[FromPortNumber].Net != pAC->Rlmt.Port[ToPortNumber].Net) {
1708 return (SK_ADDR_ILLEGAL_PORT);
1709 }
1710
1711 /*
1712 * Swap:
1713 * - Exact Match Entries (GEnesis and Yukon)
1714 * Yukon uses first entry for the logical MAC
1715 * address (stored in the second GMAC register).
1716 * - FirstExactMatchRlmt (GEnesis only)
1717 * - NextExactMatchRlmt (GEnesis only)
1718 * - FirstExactMatchDrv (GEnesis only)
1719 * - NextExactMatchDrv (GEnesis only)
1720 * - 64-bit filter (InexactFilter)
1721 * - Promiscuous Mode
1722 * of ports.
1723 */
1724
1725 for (i = 0; i < SK_ADDR_EXACT_MATCHES; i++) {
1726 MacAddr = pAC->Addr.Port[FromPortNumber].Exact[i];
1727 pAC->Addr.Port[FromPortNumber].Exact[i] =
1728 pAC->Addr.Port[ToPortNumber].Exact[i];
1729 pAC->Addr.Port[ToPortNumber].Exact[i] = MacAddr;
1730 }
1731
1732 for (i = 0; i < 8; i++) {
1733 Byte = pAC->Addr.Port[FromPortNumber].InexactFilter.Bytes[i];
1734 pAC->Addr.Port[FromPortNumber].InexactFilter.Bytes[i] =
1735 pAC->Addr.Port[ToPortNumber].InexactFilter.Bytes[i];
1736 pAC->Addr.Port[ToPortNumber].InexactFilter.Bytes[i] = Byte;
1737 }
1738
1739 i = pAC->Addr.Port[FromPortNumber].PromMode;
1740 pAC->Addr.Port[FromPortNumber].PromMode = pAC->Addr.Port[ToPortNumber].PromMode;
1741 pAC->Addr.Port[ToPortNumber].PromMode = i;
1742
1743 if (pAC->GIni.GIGenesis) {
1744 DWord = pAC->Addr.Port[FromPortNumber].FirstExactMatchRlmt;
1745 pAC->Addr.Port[FromPortNumber].FirstExactMatchRlmt =
1746 pAC->Addr.Port[ToPortNumber].FirstExactMatchRlmt;
1747 pAC->Addr.Port[ToPortNumber].FirstExactMatchRlmt = DWord;
1748
1749 DWord = pAC->Addr.Port[FromPortNumber].NextExactMatchRlmt;
1750 pAC->Addr.Port[FromPortNumber].NextExactMatchRlmt =
1751 pAC->Addr.Port[ToPortNumber].NextExactMatchRlmt;
1752 pAC->Addr.Port[ToPortNumber].NextExactMatchRlmt = DWord;
1753
1754 DWord = pAC->Addr.Port[FromPortNumber].FirstExactMatchDrv;
1755 pAC->Addr.Port[FromPortNumber].FirstExactMatchDrv =
1756 pAC->Addr.Port[ToPortNumber].FirstExactMatchDrv;
1757 pAC->Addr.Port[ToPortNumber].FirstExactMatchDrv = DWord;
1758
1759 DWord = pAC->Addr.Port[FromPortNumber].NextExactMatchDrv;
1760 pAC->Addr.Port[FromPortNumber].NextExactMatchDrv =
1761 pAC->Addr.Port[ToPortNumber].NextExactMatchDrv;
1762 pAC->Addr.Port[ToPortNumber].NextExactMatchDrv = DWord;
1763 }
1764
1765 /* CAUTION: Solution works if only ports of one adapter are in use. */
1766 for (i = 0; (SK_U32) i < pAC->Rlmt.Net[pAC->Rlmt.Port[ToPortNumber].
1767 Net->NetNumber].NumPorts; i++) {
1768 if (pAC->Rlmt.Net[pAC->Rlmt.Port[ToPortNumber].Net->NetNumber].
1769 Port[i]->PortNumber == ToPortNumber) {
1770 pAC->Addr.Net[pAC->Rlmt.Port[ToPortNumber].Net->NetNumber].
1771 ActivePort = i;
1772 /* 20001207 RA: Was "ToPortNumber;". */
1773 }
1774 }
1775
1776 (void) SkAddrMcUpdate(pAC, IoC, FromPortNumber);
1777 (void) SkAddrMcUpdate(pAC, IoC, ToPortNumber);
1778
1779 return (SK_ADDR_SUCCESS);
1780
1781} /* SkAddrSwap */
1782
1783#endif /* !SK_SLIM */
1784
1785#ifdef __cplusplus
1786}
1787#endif /* __cplusplus */
1788
diff --git a/drivers/net/sk98lin/skdim.c b/drivers/net/sk98lin/skdim.c
deleted file mode 100644
index 37ce03fb8de3..000000000000
--- a/drivers/net/sk98lin/skdim.c
+++ /dev/null
@@ -1,742 +0,0 @@
1/******************************************************************************
2 *
3 * Name: skdim.c
4 * Project: GEnesis, PCI Gigabit Ethernet Adapter
5 * Version: $Revision: 1.5 $
6 * Date: $Date: 2003/11/28 12:55:40 $
7 * Purpose: All functions to maintain interrupt moderation
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect GmbH.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25/******************************************************************************
26 *
27 * Description:
28 *
29 * This module is intended to manage the dynamic interrupt moderation on both
30 * GEnesis and Yukon adapters.
31 *
32 * Include File Hierarchy:
33 *
34 * "skdrv1st.h"
35 * "skdrv2nd.h"
36 *
37 ******************************************************************************/
38
39#ifndef lint
40static const char SysKonnectFileId[] =
41 "@(#) $Id: skdim.c,v 1.5 2003/11/28 12:55:40 rroesler Exp $ (C) SysKonnect.";
42#endif
43
44#define __SKADDR_C
45
46#ifdef __cplusplus
47#error C++ is not yet supported.
48extern "C" {
49#endif
50
51/*******************************************************************************
52**
53** Includes
54**
55*******************************************************************************/
56
57#ifndef __INC_SKDRV1ST_H
58#include "h/skdrv1st.h"
59#endif
60
61#ifndef __INC_SKDRV2ND_H
62#include "h/skdrv2nd.h"
63#endif
64
65#include <linux/kernel_stat.h>
66
67/*******************************************************************************
68**
69** Defines
70**
71*******************************************************************************/
72
73/*******************************************************************************
74**
75** Typedefs
76**
77*******************************************************************************/
78
79/*******************************************************************************
80**
81** Local function prototypes
82**
83*******************************************************************************/
84
85static unsigned int GetCurrentSystemLoad(SK_AC *pAC);
86static SK_U64 GetIsrCalls(SK_AC *pAC);
87static SK_BOOL IsIntModEnabled(SK_AC *pAC);
88static void SetCurrIntCtr(SK_AC *pAC);
89static void EnableIntMod(SK_AC *pAC);
90static void DisableIntMod(SK_AC *pAC);
91static void ResizeDimTimerDuration(SK_AC *pAC);
92static void DisplaySelectedModerationType(SK_AC *pAC);
93static void DisplaySelectedModerationMask(SK_AC *pAC);
94static void DisplayDescrRatio(SK_AC *pAC);
95
96/*******************************************************************************
97**
98** Global variables
99**
100*******************************************************************************/
101
102/*******************************************************************************
103**
104** Local variables
105**
106*******************************************************************************/
107
108/*******************************************************************************
109**
110** Global functions
111**
112*******************************************************************************/
113
114/*******************************************************************************
115** Function : SkDimModerate
116** Description : Called in every ISR to check if moderation is to be applied
117** or not for the current number of interrupts
118** Programmer : Ralph Roesler
119** Last Modified: 22-mar-03
120** Returns : void (!)
121** Notes : -
122*******************************************************************************/
123
124void
125SkDimModerate(SK_AC *pAC) {
126 unsigned int CurrSysLoad = 0; /* expressed in percent */
127 unsigned int LoadIncrease = 0; /* expressed in percent */
128 SK_U64 ThresholdInts = 0;
129 SK_U64 IsrCallsPerSec = 0;
130
131#define M_DIMINFO pAC->DynIrqModInfo
132
133 if (!IsIntModEnabled(pAC)) {
134 if (M_DIMINFO.IntModTypeSelect == C_INT_MOD_DYNAMIC) {
135 CurrSysLoad = GetCurrentSystemLoad(pAC);
136 if (CurrSysLoad > 75) {
137 /*
138 ** More than 75% total system load! Enable the moderation
139 ** to shield the system against too many interrupts.
140 */
141 EnableIntMod(pAC);
142 } else if (CurrSysLoad > M_DIMINFO.PrevSysLoad) {
143 LoadIncrease = (CurrSysLoad - M_DIMINFO.PrevSysLoad);
144 if (LoadIncrease > ((M_DIMINFO.PrevSysLoad *
145 C_INT_MOD_ENABLE_PERCENTAGE) / 100)) {
146 if (CurrSysLoad > 10) {
147 /*
148 ** More than 50% increase with respect to the
149 ** previous load of the system. Most likely this
150 ** is due to our ISR-proc...
151 */
152 EnableIntMod(pAC);
153 }
154 }
155 } else {
156 /*
157 ** Neither too much system load at all nor too much increase
158 ** with respect to the previous system load. Hence, we can leave
159 ** the ISR-handling like it is without enabling moderation.
160 */
161 }
162 M_DIMINFO.PrevSysLoad = CurrSysLoad;
163 }
164 } else {
165 if (M_DIMINFO.IntModTypeSelect == C_INT_MOD_DYNAMIC) {
166 ThresholdInts = ((M_DIMINFO.MaxModIntsPerSec *
167 C_INT_MOD_DISABLE_PERCENTAGE) / 100);
168 IsrCallsPerSec = GetIsrCalls(pAC);
169 if (IsrCallsPerSec <= ThresholdInts) {
170 /*
171 ** The number of interrupts within the last second is
172 ** lower than the disable_percentage of the desried
173 ** maxrate. Therefore we can disable the moderation.
174 */
175 DisableIntMod(pAC);
176 M_DIMINFO.MaxModIntsPerSec =
177 (M_DIMINFO.MaxModIntsPerSecUpperLimit +
178 M_DIMINFO.MaxModIntsPerSecLowerLimit) / 2;
179 } else {
180 /*
181 ** The number of interrupts per sec is the same as expected.
182 ** Evalulate the descriptor-ratio. If it has changed, a resize
183 ** in the moderation timer might be useful
184 */
185 if (M_DIMINFO.AutoSizing) {
186 ResizeDimTimerDuration(pAC);
187 }
188 }
189 }
190 }
191
192 /*
193 ** Some information to the log...
194 */
195 if (M_DIMINFO.DisplayStats) {
196 DisplaySelectedModerationType(pAC);
197 DisplaySelectedModerationMask(pAC);
198 DisplayDescrRatio(pAC);
199 }
200
201 M_DIMINFO.NbrProcessedDescr = 0;
202 SetCurrIntCtr(pAC);
203}
204
205/*******************************************************************************
206** Function : SkDimStartModerationTimer
207** Description : Starts the audit-timer for the dynamic interrupt moderation
208** Programmer : Ralph Roesler
209** Last Modified: 22-mar-03
210** Returns : void (!)
211** Notes : -
212*******************************************************************************/
213
214void
215SkDimStartModerationTimer(SK_AC *pAC) {
216 SK_EVPARA EventParam; /* Event struct for timer event */
217
218 SK_MEMSET((char *) &EventParam, 0, sizeof(EventParam));
219 EventParam.Para32[0] = SK_DRV_MODERATION_TIMER;
220 SkTimerStart(pAC, pAC->IoBase, &pAC->DynIrqModInfo.ModTimer,
221 SK_DRV_MODERATION_TIMER_LENGTH,
222 SKGE_DRV, SK_DRV_TIMER, EventParam);
223}
224
225/*******************************************************************************
226** Function : SkDimEnableModerationIfNeeded
227** Description : Either enables or disables moderation
228** Programmer : Ralph Roesler
229** Last Modified: 22-mar-03
230** Returns : void (!)
231** Notes : This function is called when a particular adapter is opened
232** There is no Disable function, because when all interrupts
233** might be disable, the moderation timer has no meaning at all
234******************************************************************************/
235
236void
237SkDimEnableModerationIfNeeded(SK_AC *pAC) {
238
239 if (M_DIMINFO.IntModTypeSelect == C_INT_MOD_STATIC) {
240 EnableIntMod(pAC); /* notification print in this function */
241 } else if (M_DIMINFO.IntModTypeSelect == C_INT_MOD_DYNAMIC) {
242 SkDimStartModerationTimer(pAC);
243 if (M_DIMINFO.DisplayStats) {
244 printk("Dynamic moderation has been enabled\n");
245 }
246 } else {
247 if (M_DIMINFO.DisplayStats) {
248 printk("No moderation has been enabled\n");
249 }
250 }
251}
252
253/*******************************************************************************
254** Function : SkDimDisplayModerationSettings
255** Description : Displays the current settings regarding interrupt moderation
256** Programmer : Ralph Roesler
257** Last Modified: 22-mar-03
258** Returns : void (!)
259** Notes : -
260*******************************************************************************/
261
262void
263SkDimDisplayModerationSettings(SK_AC *pAC) {
264 DisplaySelectedModerationType(pAC);
265 DisplaySelectedModerationMask(pAC);
266}
267
268/*******************************************************************************
269**
270** Local functions
271**
272*******************************************************************************/
273
274/*******************************************************************************
275** Function : GetCurrentSystemLoad
276** Description : Retrieves the current system load of the system. This load
277** is evaluated for all processors within the system.
278** Programmer : Ralph Roesler
279** Last Modified: 22-mar-03
280** Returns : unsigned int: load expressed in percentage
281** Notes : The possible range being returned is from 0 up to 100.
282** Whereas 0 means 'no load at all' and 100 'system fully loaded'
283** It is impossible to determine what actually causes the system
284** to be in 100%, but maybe that is due to too much interrupts.
285*******************************************************************************/
286
287static unsigned int
288GetCurrentSystemLoad(SK_AC *pAC) {
289 unsigned long jif = jiffies;
290 unsigned int UserTime = 0;
291 unsigned int SystemTime = 0;
292 unsigned int NiceTime = 0;
293 unsigned int IdleTime = 0;
294 unsigned int TotalTime = 0;
295 unsigned int UsedTime = 0;
296 unsigned int SystemLoad = 0;
297
298 /* unsigned int NbrCpu = 0; */
299
300 /*
301 ** The following lines have been commented out, because
302 ** from kernel 2.5.44 onwards, the kernel-owned structure
303 **
304 ** struct kernel_stat kstat
305 **
306 ** is not marked as an exported symbol in the file
307 **
308 ** kernel/ksyms.c
309 **
310 ** As a consequence, using this driver as KLM is not possible
311 ** and any access of the structure kernel_stat via the
312 ** dedicated macros kstat_cpu(i).cpustat.xxx is to be avoided.
313 **
314 ** The kstat-information might be added again in future
315 ** versions of the 2.5.xx kernel, but for the time being,
316 ** number of interrupts will serve as indication how much
317 ** load we currently have...
318 **
319 ** for (NbrCpu = 0; NbrCpu < num_online_cpus(); NbrCpu++) {
320 ** UserTime = UserTime + kstat_cpu(NbrCpu).cpustat.user;
321 ** NiceTime = NiceTime + kstat_cpu(NbrCpu).cpustat.nice;
322 ** SystemTime = SystemTime + kstat_cpu(NbrCpu).cpustat.system;
323 ** }
324 */
325 SK_U64 ThresholdInts = 0;
326 SK_U64 IsrCallsPerSec = 0;
327
328 ThresholdInts = ((M_DIMINFO.MaxModIntsPerSec *
329 C_INT_MOD_ENABLE_PERCENTAGE) + 100);
330 IsrCallsPerSec = GetIsrCalls(pAC);
331 if (IsrCallsPerSec >= ThresholdInts) {
332 /*
333 ** We do not know how much the real CPU-load is!
334 ** Return 80% as a default in order to activate DIM
335 */
336 SystemLoad = 80;
337 return (SystemLoad);
338 }
339
340 UsedTime = UserTime + NiceTime + SystemTime;
341
342 IdleTime = jif * num_online_cpus() - UsedTime;
343 TotalTime = UsedTime + IdleTime;
344
345 SystemLoad = ( 100 * (UsedTime - M_DIMINFO.PrevUsedTime) ) /
346 (TotalTime - M_DIMINFO.PrevTotalTime);
347
348 if (M_DIMINFO.DisplayStats) {
349 printk("Current system load is: %u\n", SystemLoad);
350 }
351
352 M_DIMINFO.PrevTotalTime = TotalTime;
353 M_DIMINFO.PrevUsedTime = UsedTime;
354
355 return (SystemLoad);
356}
357
358/*******************************************************************************
359** Function : GetIsrCalls
360** Description : Depending on the selected moderation mask, this function will
361** return the number of interrupts handled in the previous time-
362** frame. This evaluated number is based on the current number
363** of interrupts stored in PNMI-context and the previous stored
364** interrupts.
365** Programmer : Ralph Roesler
366** Last Modified: 23-mar-03
367** Returns : int: the number of interrupts being executed in the last
368** timeframe
369** Notes : It makes only sense to call this function, when dynamic
370** interrupt moderation is applied
371*******************************************************************************/
372
373static SK_U64
374GetIsrCalls(SK_AC *pAC) {
375 SK_U64 RxPort0IntDiff = 0;
376 SK_U64 RxPort1IntDiff = 0;
377 SK_U64 TxPort0IntDiff = 0;
378 SK_U64 TxPort1IntDiff = 0;
379
380 if (pAC->DynIrqModInfo.MaskIrqModeration == IRQ_MASK_TX_ONLY) {
381 if (pAC->GIni.GIMacsFound == 2) {
382 TxPort1IntDiff = pAC->Pnmi.Port[1].TxIntrCts -
383 pAC->DynIrqModInfo.PrevPort1TxIntrCts;
384 }
385 TxPort0IntDiff = pAC->Pnmi.Port[0].TxIntrCts -
386 pAC->DynIrqModInfo.PrevPort0TxIntrCts;
387 } else if (pAC->DynIrqModInfo.MaskIrqModeration == IRQ_MASK_RX_ONLY) {
388 if (pAC->GIni.GIMacsFound == 2) {
389 RxPort1IntDiff = pAC->Pnmi.Port[1].RxIntrCts -
390 pAC->DynIrqModInfo.PrevPort1RxIntrCts;
391 }
392 RxPort0IntDiff = pAC->Pnmi.Port[0].RxIntrCts -
393 pAC->DynIrqModInfo.PrevPort0RxIntrCts;
394 } else {
395 if (pAC->GIni.GIMacsFound == 2) {
396 RxPort1IntDiff = pAC->Pnmi.Port[1].RxIntrCts -
397 pAC->DynIrqModInfo.PrevPort1RxIntrCts;
398 TxPort1IntDiff = pAC->Pnmi.Port[1].TxIntrCts -
399 pAC->DynIrqModInfo.PrevPort1TxIntrCts;
400 }
401 RxPort0IntDiff = pAC->Pnmi.Port[0].RxIntrCts -
402 pAC->DynIrqModInfo.PrevPort0RxIntrCts;
403 TxPort0IntDiff = pAC->Pnmi.Port[0].TxIntrCts -
404 pAC->DynIrqModInfo.PrevPort0TxIntrCts;
405 }
406
407 return (RxPort0IntDiff + RxPort1IntDiff + TxPort0IntDiff + TxPort1IntDiff);
408}
409
410/*******************************************************************************
411** Function : GetRxCalls
412** Description : This function will return the number of times a receive inter-
413** rupt was processed. This is needed to evaluate any resizing
414** factor.
415** Programmer : Ralph Roesler
416** Last Modified: 23-mar-03
417** Returns : SK_U64: the number of RX-ints being processed
418** Notes : It makes only sense to call this function, when dynamic
419** interrupt moderation is applied
420*******************************************************************************/
421
422static SK_U64
423GetRxCalls(SK_AC *pAC) {
424 SK_U64 RxPort0IntDiff = 0;
425 SK_U64 RxPort1IntDiff = 0;
426
427 if (pAC->GIni.GIMacsFound == 2) {
428 RxPort1IntDiff = pAC->Pnmi.Port[1].RxIntrCts -
429 pAC->DynIrqModInfo.PrevPort1RxIntrCts;
430 }
431 RxPort0IntDiff = pAC->Pnmi.Port[0].RxIntrCts -
432 pAC->DynIrqModInfo.PrevPort0RxIntrCts;
433
434 return (RxPort0IntDiff + RxPort1IntDiff);
435}
436
437/*******************************************************************************
438** Function : SetCurrIntCtr
439** Description : Will store the current number orf occured interrupts in the
440** adapter context. This is needed to evaluated the number of
441** interrupts within a current timeframe.
442** Programmer : Ralph Roesler
443** Last Modified: 23-mar-03
444** Returns : void (!)
445** Notes : -
446*******************************************************************************/
447
448static void
449SetCurrIntCtr(SK_AC *pAC) {
450 if (pAC->GIni.GIMacsFound == 2) {
451 pAC->DynIrqModInfo.PrevPort1RxIntrCts = pAC->Pnmi.Port[1].RxIntrCts;
452 pAC->DynIrqModInfo.PrevPort1TxIntrCts = pAC->Pnmi.Port[1].TxIntrCts;
453 }
454 pAC->DynIrqModInfo.PrevPort0RxIntrCts = pAC->Pnmi.Port[0].RxIntrCts;
455 pAC->DynIrqModInfo.PrevPort0TxIntrCts = pAC->Pnmi.Port[0].TxIntrCts;
456}
457
458/*******************************************************************************
459** Function : IsIntModEnabled()
460** Description : Retrieves the current value of the interrupts moderation
461** command register. Its content determines whether any
462** moderation is running or not.
463** Programmer : Ralph Roesler
464** Last Modified: 23-mar-03
465** Returns : SK_TRUE : if mod timer running
466** SK_FALSE : if no moderation is being performed
467** Notes : -
468*******************************************************************************/
469
470static SK_BOOL
471IsIntModEnabled(SK_AC *pAC) {
472 unsigned long CtrCmd;
473
474 SK_IN32(pAC->IoBase, B2_IRQM_CTRL, &CtrCmd);
475 if ((CtrCmd & TIM_START) == TIM_START) {
476 return SK_TRUE;
477 } else {
478 return SK_FALSE;
479 }
480}
481
482/*******************************************************************************
483** Function : EnableIntMod()
484** Description : Enables the interrupt moderation using the values stored in
485** in the pAC->DynIntMod data structure
486** Programmer : Ralph Roesler
487** Last Modified: 22-mar-03
488** Returns : -
489** Notes : -
490*******************************************************************************/
491
492static void
493EnableIntMod(SK_AC *pAC) {
494 unsigned long ModBase;
495
496 if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) {
497 ModBase = C_CLK_FREQ_GENESIS / pAC->DynIrqModInfo.MaxModIntsPerSec;
498 } else {
499 ModBase = C_CLK_FREQ_YUKON / pAC->DynIrqModInfo.MaxModIntsPerSec;
500 }
501
502 SK_OUT32(pAC->IoBase, B2_IRQM_INI, ModBase);
503 SK_OUT32(pAC->IoBase, B2_IRQM_MSK, pAC->DynIrqModInfo.MaskIrqModeration);
504 SK_OUT32(pAC->IoBase, B2_IRQM_CTRL, TIM_START);
505 if (M_DIMINFO.DisplayStats) {
506 printk("Enabled interrupt moderation (%i ints/sec)\n",
507 M_DIMINFO.MaxModIntsPerSec);
508 }
509}
510
511/*******************************************************************************
512** Function : DisableIntMod()
513** Description : Disables the interrupt moderation independent of what inter-
514** rupts are running or not
515** Programmer : Ralph Roesler
516** Last Modified: 23-mar-03
517** Returns : -
518** Notes : -
519*******************************************************************************/
520
521static void
522DisableIntMod(SK_AC *pAC) {
523
524 SK_OUT32(pAC->IoBase, B2_IRQM_CTRL, TIM_STOP);
525 if (M_DIMINFO.DisplayStats) {
526 printk("Disabled interrupt moderation\n");
527 }
528}
529
530/*******************************************************************************
531** Function : ResizeDimTimerDuration();
532** Description : Checks the current used descriptor ratio and resizes the
533** duration timer (longer/smaller) if possible.
534** Programmer : Ralph Roesler
535** Last Modified: 23-mar-03
536** Returns : -
537** Notes : There are both maximum and minimum timer duration value.
538** This function assumes that interrupt moderation is already
539** enabled!
540*******************************************************************************/
541
542static void
543ResizeDimTimerDuration(SK_AC *pAC) {
544 SK_BOOL IncreaseTimerDuration;
545 int TotalMaxNbrDescr;
546 int UsedDescrRatio;
547 int RatioDiffAbs;
548 int RatioDiffRel;
549 int NewMaxModIntsPerSec;
550 int ModAdjValue;
551 long ModBase;
552
553 /*
554 ** Check first if we are allowed to perform any modification
555 */
556 if (IsIntModEnabled(pAC)) {
557 if (M_DIMINFO.IntModTypeSelect != C_INT_MOD_DYNAMIC) {
558 return;
559 } else {
560 if (M_DIMINFO.ModJustEnabled) {
561 M_DIMINFO.ModJustEnabled = SK_FALSE;
562 return;
563 }
564 }
565 }
566
567 /*
568 ** If we got until here, we have to evaluate the amount of the
569 ** descriptor ratio change...
570 */
571 TotalMaxNbrDescr = pAC->RxDescrPerRing * GetRxCalls(pAC);
572 UsedDescrRatio = (M_DIMINFO.NbrProcessedDescr * 100) / TotalMaxNbrDescr;
573
574 if (UsedDescrRatio > M_DIMINFO.PrevUsedDescrRatio) {
575 RatioDiffAbs = (UsedDescrRatio - M_DIMINFO.PrevUsedDescrRatio);
576 RatioDiffRel = (RatioDiffAbs * 100) / UsedDescrRatio;
577 M_DIMINFO.PrevUsedDescrRatio = UsedDescrRatio;
578 IncreaseTimerDuration = SK_FALSE; /* in other words: DECREASE */
579 } else if (UsedDescrRatio < M_DIMINFO.PrevUsedDescrRatio) {
580 RatioDiffAbs = (M_DIMINFO.PrevUsedDescrRatio - UsedDescrRatio);
581 RatioDiffRel = (RatioDiffAbs * 100) / M_DIMINFO.PrevUsedDescrRatio;
582 M_DIMINFO.PrevUsedDescrRatio = UsedDescrRatio;
583 IncreaseTimerDuration = SK_TRUE; /* in other words: INCREASE */
584 } else {
585 RatioDiffAbs = (M_DIMINFO.PrevUsedDescrRatio - UsedDescrRatio);
586 RatioDiffRel = (RatioDiffAbs * 100) / M_DIMINFO.PrevUsedDescrRatio;
587 M_DIMINFO.PrevUsedDescrRatio = UsedDescrRatio;
588 IncreaseTimerDuration = SK_TRUE; /* in other words: INCREASE */
589 }
590
591 /*
592 ** Now we can determine the change in percent
593 */
594 if ((RatioDiffRel >= 0) && (RatioDiffRel <= 5) ) {
595 ModAdjValue = 1; /* 1% change - maybe some other value in future */
596 } else if ((RatioDiffRel > 5) && (RatioDiffRel <= 10) ) {
597 ModAdjValue = 1; /* 1% change - maybe some other value in future */
598 } else if ((RatioDiffRel > 10) && (RatioDiffRel <= 15) ) {
599 ModAdjValue = 1; /* 1% change - maybe some other value in future */
600 } else {
601 ModAdjValue = 1; /* 1% change - maybe some other value in future */
602 }
603
604 if (IncreaseTimerDuration) {
605 NewMaxModIntsPerSec = M_DIMINFO.MaxModIntsPerSec +
606 (M_DIMINFO.MaxModIntsPerSec * ModAdjValue) / 100;
607 } else {
608 NewMaxModIntsPerSec = M_DIMINFO.MaxModIntsPerSec -
609 (M_DIMINFO.MaxModIntsPerSec * ModAdjValue) / 100;
610 }
611
612 /*
613 ** Check if we exceed boundaries...
614 */
615 if ( (NewMaxModIntsPerSec > M_DIMINFO.MaxModIntsPerSecUpperLimit) ||
616 (NewMaxModIntsPerSec < M_DIMINFO.MaxModIntsPerSecLowerLimit)) {
617 if (M_DIMINFO.DisplayStats) {
618 printk("Cannot change ModTim from %i to %i ints/sec\n",
619 M_DIMINFO.MaxModIntsPerSec, NewMaxModIntsPerSec);
620 }
621 return;
622 } else {
623 if (M_DIMINFO.DisplayStats) {
624 printk("Resized ModTim from %i to %i ints/sec\n",
625 M_DIMINFO.MaxModIntsPerSec, NewMaxModIntsPerSec);
626 }
627 }
628
629 M_DIMINFO.MaxModIntsPerSec = NewMaxModIntsPerSec;
630
631 if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) {
632 ModBase = C_CLK_FREQ_GENESIS / pAC->DynIrqModInfo.MaxModIntsPerSec;
633 } else {
634 ModBase = C_CLK_FREQ_YUKON / pAC->DynIrqModInfo.MaxModIntsPerSec;
635 }
636
637 /*
638 ** We do not need to touch any other registers
639 */
640 SK_OUT32(pAC->IoBase, B2_IRQM_INI, ModBase);
641}
642
643/*******************************************************************************
644** Function : DisplaySelectedModerationType()
645** Description : Displays what type of moderation we have
646** Programmer : Ralph Roesler
647** Last Modified: 23-mar-03
648** Returns : void!
649** Notes : -
650*******************************************************************************/
651
652static void
653DisplaySelectedModerationType(SK_AC *pAC) {
654
655 if (pAC->DynIrqModInfo.DisplayStats) {
656 if (pAC->DynIrqModInfo.IntModTypeSelect == C_INT_MOD_STATIC) {
657 printk("Static int moderation runs with %i INTS/sec\n",
658 pAC->DynIrqModInfo.MaxModIntsPerSec);
659 } else if (pAC->DynIrqModInfo.IntModTypeSelect == C_INT_MOD_DYNAMIC) {
660 if (IsIntModEnabled(pAC)) {
661 printk("Dynamic int moderation runs with %i INTS/sec\n",
662 pAC->DynIrqModInfo.MaxModIntsPerSec);
663 } else {
664 printk("Dynamic int moderation currently not applied\n");
665 }
666 } else {
667 printk("No interrupt moderation selected!\n");
668 }
669 }
670}
671
672/*******************************************************************************
673** Function : DisplaySelectedModerationMask()
674** Description : Displays what interrupts are moderated
675** Programmer : Ralph Roesler
676** Last Modified: 23-mar-03
677** Returns : void!
678** Notes : -
679*******************************************************************************/
680
681static void
682DisplaySelectedModerationMask(SK_AC *pAC) {
683
684 if (pAC->DynIrqModInfo.DisplayStats) {
685 if (pAC->DynIrqModInfo.IntModTypeSelect != C_INT_MOD_NONE) {
686 switch (pAC->DynIrqModInfo.MaskIrqModeration) {
687 case IRQ_MASK_TX_ONLY:
688 printk("Only Tx-interrupts are moderated\n");
689 break;
690 case IRQ_MASK_RX_ONLY:
691 printk("Only Rx-interrupts are moderated\n");
692 break;
693 case IRQ_MASK_SP_ONLY:
694 printk("Only special-interrupts are moderated\n");
695 break;
696 case IRQ_MASK_TX_RX:
697 printk("Tx- and Rx-interrupts are moderated\n");
698 break;
699 case IRQ_MASK_SP_RX:
700 printk("Special- and Rx-interrupts are moderated\n");
701 break;
702 case IRQ_MASK_SP_TX:
703 printk("Special- and Tx-interrupts are moderated\n");
704 break;
705 case IRQ_MASK_RX_TX_SP:
706 printk("All Rx-, Tx and special-interrupts are moderated\n");
707 break;
708 default:
709 printk("Don't know what is moderated\n");
710 break;
711 }
712 } else {
713 printk("No specific interrupts masked for moderation\n");
714 }
715 }
716}
717
718/*******************************************************************************
719** Function : DisplayDescrRatio
720** Description : Like the name states...
721** Programmer : Ralph Roesler
722** Last Modified: 23-mar-03
723** Returns : void!
724** Notes : -
725*******************************************************************************/
726
727static void
728DisplayDescrRatio(SK_AC *pAC) {
729 int TotalMaxNbrDescr = 0;
730
731 if (pAC->DynIrqModInfo.DisplayStats) {
732 TotalMaxNbrDescr = pAC->RxDescrPerRing * GetRxCalls(pAC);
733 printk("Ratio descriptors: %i/%i\n",
734 M_DIMINFO.NbrProcessedDescr, TotalMaxNbrDescr);
735 }
736}
737
738/*******************************************************************************
739**
740** End of file
741**
742*******************************************************************************/
diff --git a/drivers/net/sk98lin/skethtool.c b/drivers/net/sk98lin/skethtool.c
deleted file mode 100644
index 36460694eb82..000000000000
--- a/drivers/net/sk98lin/skethtool.c
+++ /dev/null
@@ -1,628 +0,0 @@
1/******************************************************************************
2 *
3 * Name: skethtool.c
4 * Project: GEnesis, PCI Gigabit Ethernet Adapter
5 * Version: $Revision: 1.7 $
6 * Date: $Date: 2004/09/29 13:32:07 $
7 * Purpose: All functions regarding ethtool handling
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect GmbH.
14 * (C)Copyright 2002-2004 Marvell.
15 *
16 * Driver for Marvell Yukon/2 chipset and SysKonnect Gigabit Ethernet
17 * Server Adapters.
18 *
19 * Author: Ralph Roesler (rroesler@syskonnect.de)
20 * Mirko Lindner (mlindner@syskonnect.de)
21 *
22 * Address all question to: linux@syskonnect.de
23 *
24 * The technical manual for the adapters is available from SysKonnect's
25 * web pages: www.syskonnect.com
26 *
27 * This program is free software; you can redistribute it and/or modify
28 * it under the terms of the GNU General Public License as published by
29 * the Free Software Foundation; either version 2 of the License, or
30 * (at your option) any later version.
31 *
32 * The information in this file is provided "AS IS" without warranty.
33 *
34 *****************************************************************************/
35
36#include "h/skdrv1st.h"
37#include "h/skdrv2nd.h"
38#include "h/skversion.h"
39
40#include <linux/ethtool.h>
41#include <linux/timer.h>
42#include <linux/delay.h>
43
44/******************************************************************************
45 *
46 * Defines
47 *
48 *****************************************************************************/
49
50#define SUPP_COPPER_ALL (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | \
51 SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | \
52 SUPPORTED_1000baseT_Half| SUPPORTED_1000baseT_Full| \
53 SUPPORTED_TP)
54
55#define ADV_COPPER_ALL (ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full | \
56 ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full | \
57 ADVERTISED_1000baseT_Half| ADVERTISED_1000baseT_Full| \
58 ADVERTISED_TP)
59
60#define SUPP_FIBRE_ALL (SUPPORTED_1000baseT_Full | \
61 SUPPORTED_FIBRE | \
62 SUPPORTED_Autoneg)
63
64#define ADV_FIBRE_ALL (ADVERTISED_1000baseT_Full | \
65 ADVERTISED_FIBRE | \
66 ADVERTISED_Autoneg)
67
68
69/******************************************************************************
70 *
71 * Local Functions
72 *
73 *****************************************************************************/
74
75/*****************************************************************************
76 *
77 * getSettings - retrieves the current settings of the selected adapter
78 *
79 * Description:
80 * The current configuration of the selected adapter is returned.
81 * This configuration involves a)speed, b)duplex and c)autoneg plus
82 * a number of other variables.
83 *
84 * Returns: always 0
85 *
86 */
87static int getSettings(struct net_device *dev, struct ethtool_cmd *ecmd)
88{
89 const DEV_NET *pNet = netdev_priv(dev);
90 int port = pNet->PortNr;
91 const SK_AC *pAC = pNet->pAC;
92 const SK_GEPORT *pPort = &pAC->GIni.GP[port];
93
94 static int DuplexAutoNegConfMap[9][3]= {
95 { -1 , -1 , -1 },
96 { 0 , -1 , -1 },
97 { SK_LMODE_HALF , DUPLEX_HALF, AUTONEG_DISABLE },
98 { SK_LMODE_FULL , DUPLEX_FULL, AUTONEG_DISABLE },
99 { SK_LMODE_AUTOHALF , DUPLEX_HALF, AUTONEG_ENABLE },
100 { SK_LMODE_AUTOFULL , DUPLEX_FULL, AUTONEG_ENABLE },
101 { SK_LMODE_AUTOBOTH , DUPLEX_FULL, AUTONEG_ENABLE },
102 { SK_LMODE_AUTOSENSE , -1 , -1 },
103 { SK_LMODE_INDETERMINATED, -1 , -1 }
104 };
105 static int SpeedConfMap[6][2] = {
106 { 0 , -1 },
107 { SK_LSPEED_AUTO , -1 },
108 { SK_LSPEED_10MBPS , SPEED_10 },
109 { SK_LSPEED_100MBPS , SPEED_100 },
110 { SK_LSPEED_1000MBPS , SPEED_1000 },
111 { SK_LSPEED_INDETERMINATED, -1 }
112 };
113 static int AdvSpeedMap[6][2] = {
114 { 0 , -1 },
115 { SK_LSPEED_AUTO , -1 },
116 { SK_LSPEED_10MBPS , ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full },
117 { SK_LSPEED_100MBPS , ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full },
118 { SK_LSPEED_1000MBPS , ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full},
119 { SK_LSPEED_INDETERMINATED, -1 }
120 };
121
122 ecmd->phy_address = port;
123 ecmd->speed = SpeedConfMap[pPort->PLinkSpeedUsed][1];
124 ecmd->duplex = DuplexAutoNegConfMap[pPort->PLinkModeStatus][1];
125 ecmd->autoneg = DuplexAutoNegConfMap[pPort->PLinkModeStatus][2];
126 ecmd->transceiver = XCVR_INTERNAL;
127
128 if (pAC->GIni.GICopperType) {
129 ecmd->port = PORT_TP;
130 ecmd->supported = (SUPP_COPPER_ALL|SUPPORTED_Autoneg);
131 if (pAC->GIni.GIGenesis) {
132 ecmd->supported &= ~(SUPPORTED_10baseT_Half);
133 ecmd->supported &= ~(SUPPORTED_10baseT_Full);
134 ecmd->supported &= ~(SUPPORTED_100baseT_Half);
135 ecmd->supported &= ~(SUPPORTED_100baseT_Full);
136 } else {
137 if (pAC->GIni.GIChipId == CHIP_ID_YUKON) {
138 ecmd->supported &= ~(SUPPORTED_1000baseT_Half);
139 }
140#ifdef CHIP_ID_YUKON_FE
141 if (pAC->GIni.GIChipId == CHIP_ID_YUKON_FE) {
142 ecmd->supported &= ~(SUPPORTED_1000baseT_Half);
143 ecmd->supported &= ~(SUPPORTED_1000baseT_Full);
144 }
145#endif
146 }
147 if (pAC->GIni.GP[0].PLinkSpeed != SK_LSPEED_AUTO) {
148 ecmd->advertising = AdvSpeedMap[pPort->PLinkSpeed][1];
149 if (pAC->GIni.GIChipId == CHIP_ID_YUKON) {
150 ecmd->advertising &= ~(SUPPORTED_1000baseT_Half);
151 }
152 } else {
153 ecmd->advertising = ecmd->supported;
154 }
155
156 if (ecmd->autoneg == AUTONEG_ENABLE)
157 ecmd->advertising |= ADVERTISED_Autoneg;
158 } else {
159 ecmd->port = PORT_FIBRE;
160 ecmd->supported = SUPP_FIBRE_ALL;
161 ecmd->advertising = ADV_FIBRE_ALL;
162 }
163 return 0;
164}
165
166/*
167 * MIB infrastructure uses instance value starting at 1
168 * based on board and port.
169 */
170static inline u32 pnmiInstance(const DEV_NET *pNet)
171{
172 return 1 + (pNet->pAC->RlmtNets == 2) + pNet->PortNr;
173}
174
175/*****************************************************************************
176 *
177 * setSettings - configures the settings of a selected adapter
178 *
179 * Description:
180 * Possible settings that may be altered are a)speed, b)duplex or
181 * c)autonegotiation.
182 *
183 * Returns:
184 * 0: everything fine, no error
185 * <0: the return value is the error code of the failure
186 */
187static int setSettings(struct net_device *dev, struct ethtool_cmd *ecmd)
188{
189 DEV_NET *pNet = netdev_priv(dev);
190 SK_AC *pAC = pNet->pAC;
191 u32 instance;
192 char buf[4];
193 int len = 1;
194
195 if (ecmd->speed != SPEED_10 && ecmd->speed != SPEED_100
196 && ecmd->speed != SPEED_1000)
197 return -EINVAL;
198
199 if (ecmd->duplex != DUPLEX_HALF && ecmd->duplex != DUPLEX_FULL)
200 return -EINVAL;
201
202 if (ecmd->autoneg != AUTONEG_DISABLE && ecmd->autoneg != AUTONEG_ENABLE)
203 return -EINVAL;
204
205 if (ecmd->autoneg == AUTONEG_DISABLE)
206 *buf = (ecmd->duplex == DUPLEX_FULL)
207 ? SK_LMODE_FULL : SK_LMODE_HALF;
208 else
209 *buf = (ecmd->duplex == DUPLEX_FULL)
210 ? SK_LMODE_AUTOFULL : SK_LMODE_AUTOHALF;
211
212 instance = pnmiInstance(pNet);
213 if (SkPnmiSetVar(pAC, pAC->IoBase, OID_SKGE_LINK_MODE,
214 &buf, &len, instance, pNet->NetNr) != SK_PNMI_ERR_OK)
215 return -EINVAL;
216
217 switch(ecmd->speed) {
218 case SPEED_1000:
219 *buf = SK_LSPEED_1000MBPS;
220 break;
221 case SPEED_100:
222 *buf = SK_LSPEED_100MBPS;
223 break;
224 case SPEED_10:
225 *buf = SK_LSPEED_10MBPS;
226 }
227
228 if (SkPnmiSetVar(pAC, pAC->IoBase, OID_SKGE_SPEED_MODE,
229 &buf, &len, instance, pNet->NetNr) != SK_PNMI_ERR_OK)
230 return -EINVAL;
231
232 return 0;
233}
234
235/*****************************************************************************
236 *
237 * getDriverInfo - returns generic driver and adapter information
238 *
239 * Description:
240 * Generic driver information is returned via this function, such as
241 * the name of the driver, its version and and firmware version.
242 * In addition to this, the location of the selected adapter is
243 * returned as a bus info string (e.g. '01:05.0').
244 *
245 * Returns: N/A
246 *
247 */
248static void getDriverInfo(struct net_device *dev, struct ethtool_drvinfo *info)
249{
250 const DEV_NET *pNet = netdev_priv(dev);
251 const SK_AC *pAC = pNet->pAC;
252 char vers[32];
253
254 snprintf(vers, sizeof(vers)-1, VER_STRING "(v%d.%d)",
255 (pAC->GIni.GIPciHwRev >> 4) & 0xf, pAC->GIni.GIPciHwRev & 0xf);
256
257 strlcpy(info->driver, DRIVER_FILE_NAME, sizeof(info->driver));
258 strcpy(info->version, vers);
259 strcpy(info->fw_version, "N/A");
260 strlcpy(info->bus_info, pci_name(pAC->PciDev), ETHTOOL_BUSINFO_LEN);
261}
262
263/*
264 * Ethtool statistics support.
265 */
266static const char StringsStats[][ETH_GSTRING_LEN] = {
267 "rx_packets", "tx_packets",
268 "rx_bytes", "tx_bytes",
269 "rx_errors", "tx_errors",
270 "rx_dropped", "tx_dropped",
271 "multicasts", "collisions",
272 "rx_length_errors", "rx_buffer_overflow_errors",
273 "rx_crc_errors", "rx_frame_errors",
274 "rx_too_short_errors", "rx_too_long_errors",
275 "rx_carrier_extension_errors", "rx_symbol_errors",
276 "rx_llc_mac_size_errors", "rx_carrier_errors",
277 "rx_jabber_errors", "rx_missed_errors",
278 "tx_abort_collision_errors", "tx_carrier_errors",
279 "tx_buffer_underrun_errors", "tx_heartbeat_errors",
280 "tx_window_errors",
281};
282
283static int getStatsCount(struct net_device *dev)
284{
285 return ARRAY_SIZE(StringsStats);
286}
287
288static void getStrings(struct net_device *dev, u32 stringset, u8 *data)
289{
290 switch(stringset) {
291 case ETH_SS_STATS:
292 memcpy(data, *StringsStats, sizeof(StringsStats));
293 break;
294 }
295}
296
297static void getEthtoolStats(struct net_device *dev,
298 struct ethtool_stats *stats, u64 *data)
299{
300 const DEV_NET *pNet = netdev_priv(dev);
301 const SK_AC *pAC = pNet->pAC;
302 const SK_PNMI_STRUCT_DATA *pPnmiStruct = &pAC->PnmiStruct;
303
304 *data++ = pPnmiStruct->Stat[0].StatRxOkCts;
305 *data++ = pPnmiStruct->Stat[0].StatTxOkCts;
306 *data++ = pPnmiStruct->Stat[0].StatRxOctetsOkCts;
307 *data++ = pPnmiStruct->Stat[0].StatTxOctetsOkCts;
308 *data++ = pPnmiStruct->InErrorsCts;
309 *data++ = pPnmiStruct->Stat[0].StatTxSingleCollisionCts;
310 *data++ = pPnmiStruct->RxNoBufCts;
311 *data++ = pPnmiStruct->TxNoBufCts;
312 *data++ = pPnmiStruct->Stat[0].StatRxMulticastOkCts;
313 *data++ = pPnmiStruct->Stat[0].StatTxSingleCollisionCts;
314 *data++ = pPnmiStruct->Stat[0].StatRxRuntCts;
315 *data++ = pPnmiStruct->Stat[0].StatRxFifoOverflowCts;
316 *data++ = pPnmiStruct->Stat[0].StatRxFcsCts;
317 *data++ = pPnmiStruct->Stat[0].StatRxFramingCts;
318 *data++ = pPnmiStruct->Stat[0].StatRxShortsCts;
319 *data++ = pPnmiStruct->Stat[0].StatRxTooLongCts;
320 *data++ = pPnmiStruct->Stat[0].StatRxCextCts;
321 *data++ = pPnmiStruct->Stat[0].StatRxSymbolCts;
322 *data++ = pPnmiStruct->Stat[0].StatRxIRLengthCts;
323 *data++ = pPnmiStruct->Stat[0].StatRxCarrierCts;
324 *data++ = pPnmiStruct->Stat[0].StatRxJabberCts;
325 *data++ = pPnmiStruct->Stat[0].StatRxMissedCts;
326 *data++ = pAC->stats.tx_aborted_errors;
327 *data++ = pPnmiStruct->Stat[0].StatTxCarrierCts;
328 *data++ = pPnmiStruct->Stat[0].StatTxFifoUnderrunCts;
329 *data++ = pPnmiStruct->Stat[0].StatTxCarrierCts;
330 *data++ = pAC->stats.tx_window_errors;
331}
332
333
334/*****************************************************************************
335 *
336 * toggleLeds - Changes the LED state of an adapter
337 *
338 * Description:
339 * This function changes the current state of all LEDs of an adapter so
340 * that it can be located by a user.
341 *
342 * Returns: N/A
343 *
344 */
345static void toggleLeds(DEV_NET *pNet, int on)
346{
347 SK_AC *pAC = pNet->pAC;
348 int port = pNet->PortNr;
349 void __iomem *io = pAC->IoBase;
350
351 if (pAC->GIni.GIGenesis) {
352 SK_OUT8(io, MR_ADDR(port,LNK_LED_REG),
353 on ? SK_LNK_ON : SK_LNK_OFF);
354 SkGeYellowLED(pAC, io,
355 on ? (LED_ON >> 1) : (LED_OFF >> 1));
356 SkGeXmitLED(pAC, io, MR_ADDR(port,RX_LED_INI),
357 on ? SK_LED_TST : SK_LED_DIS);
358
359 if (pAC->GIni.GP[port].PhyType == SK_PHY_BCOM)
360 SkXmPhyWrite(pAC, io, port, PHY_BCOM_P_EXT_CTRL,
361 on ? PHY_B_PEC_LED_ON : PHY_B_PEC_LED_OFF);
362 else if (pAC->GIni.GP[port].PhyType == SK_PHY_LONE)
363 SkXmPhyWrite(pAC, io, port, PHY_LONE_LED_CFG,
364 on ? 0x0800 : PHY_L_LC_LEDT);
365 else
366 SkGeXmitLED(pAC, io, MR_ADDR(port,TX_LED_INI),
367 on ? SK_LED_TST : SK_LED_DIS);
368 } else {
369 const u16 YukLedOn = (PHY_M_LED_MO_DUP(MO_LED_ON) |
370 PHY_M_LED_MO_10(MO_LED_ON) |
371 PHY_M_LED_MO_100(MO_LED_ON) |
372 PHY_M_LED_MO_1000(MO_LED_ON) |
373 PHY_M_LED_MO_RX(MO_LED_ON));
374 const u16 YukLedOff = (PHY_M_LED_MO_DUP(MO_LED_OFF) |
375 PHY_M_LED_MO_10(MO_LED_OFF) |
376 PHY_M_LED_MO_100(MO_LED_OFF) |
377 PHY_M_LED_MO_1000(MO_LED_OFF) |
378 PHY_M_LED_MO_RX(MO_LED_OFF));
379
380
381 SkGmPhyWrite(pAC,io,port,PHY_MARV_LED_CTRL,0);
382 SkGmPhyWrite(pAC,io,port,PHY_MARV_LED_OVER,
383 on ? YukLedOn : YukLedOff);
384 }
385}
386
387/*****************************************************************************
388 *
389 * skGeBlinkTimer - Changes the LED state of an adapter
390 *
391 * Description:
392 * This function changes the current state of all LEDs of an adapter so
393 * that it can be located by a user. If the requested time interval for
394 * this test has elapsed, this function cleans up everything that was
395 * temporarily setup during the locate NIC test. This involves of course
396 * also closing or opening any adapter so that the initial board state
397 * is recovered.
398 *
399 * Returns: N/A
400 *
401 */
402void SkGeBlinkTimer(unsigned long data)
403{
404 struct net_device *dev = (struct net_device *) data;
405 DEV_NET *pNet = netdev_priv(dev);
406 SK_AC *pAC = pNet->pAC;
407
408 toggleLeds(pNet, pAC->LedsOn);
409
410 pAC->LedsOn = !pAC->LedsOn;
411 mod_timer(&pAC->BlinkTimer, jiffies + HZ/4);
412}
413
414/*****************************************************************************
415 *
416 * locateDevice - start the locate NIC feature of the elected adapter
417 *
418 * Description:
419 * This function is used if the user want to locate a particular NIC.
420 * All LEDs are regularly switched on and off, so the NIC can easily
421 * be identified.
422 *
423 * Returns:
424 * ==0: everything fine, no error, locateNIC test was started
425 * !=0: one locateNIC test runs already
426 *
427 */
428static int locateDevice(struct net_device *dev, u32 data)
429{
430 DEV_NET *pNet = netdev_priv(dev);
431 SK_AC *pAC = pNet->pAC;
432
433 if(!data || data > (u32)(MAX_SCHEDULE_TIMEOUT / HZ))
434 data = (u32)(MAX_SCHEDULE_TIMEOUT / HZ);
435
436 /* start blinking */
437 pAC->LedsOn = 0;
438 mod_timer(&pAC->BlinkTimer, jiffies);
439 msleep_interruptible(data * 1000);
440 del_timer_sync(&pAC->BlinkTimer);
441 toggleLeds(pNet, 0);
442
443 return 0;
444}
445
446/*****************************************************************************
447 *
448 * getPauseParams - retrieves the pause parameters
449 *
450 * Description:
451 * All current pause parameters of a selected adapter are placed
452 * in the passed ethtool_pauseparam structure and are returned.
453 *
454 * Returns: N/A
455 *
456 */
457static void getPauseParams(struct net_device *dev, struct ethtool_pauseparam *epause)
458{
459 DEV_NET *pNet = netdev_priv(dev);
460 SK_AC *pAC = pNet->pAC;
461 SK_GEPORT *pPort = &pAC->GIni.GP[pNet->PortNr];
462
463 epause->rx_pause = (pPort->PFlowCtrlMode == SK_FLOW_MODE_SYMMETRIC) ||
464 (pPort->PFlowCtrlMode == SK_FLOW_MODE_SYM_OR_REM);
465
466 epause->tx_pause = epause->rx_pause || (pPort->PFlowCtrlMode == SK_FLOW_MODE_LOC_SEND);
467 epause->autoneg = epause->rx_pause || epause->tx_pause;
468}
469
470/*****************************************************************************
471 *
472 * setPauseParams - configures the pause parameters of an adapter
473 *
474 * Description:
475 * This function sets the Rx or Tx pause parameters
476 *
477 * Returns:
478 * ==0: everything fine, no error
479 * !=0: the return value is the error code of the failure
480 */
481static int setPauseParams(struct net_device *dev , struct ethtool_pauseparam *epause)
482{
483 DEV_NET *pNet = netdev_priv(dev);
484 SK_AC *pAC = pNet->pAC;
485 SK_GEPORT *pPort = &pAC->GIni.GP[pNet->PortNr];
486 u32 instance = pnmiInstance(pNet);
487 struct ethtool_pauseparam old;
488 u8 oldspeed = pPort->PLinkSpeedUsed;
489 char buf[4];
490 int len = 1;
491 int ret;
492
493 /*
494 ** we have to determine the current settings to see if
495 ** the operator requested any modification of the flow
496 ** control parameters...
497 */
498 getPauseParams(dev, &old);
499
500 /*
501 ** perform modifications regarding the changes
502 ** requested by the operator
503 */
504 if (epause->autoneg != old.autoneg)
505 *buf = epause->autoneg ? SK_FLOW_MODE_NONE : SK_FLOW_MODE_SYMMETRIC;
506 else {
507 if (epause->rx_pause && epause->tx_pause)
508 *buf = SK_FLOW_MODE_SYMMETRIC;
509 else if (epause->rx_pause && !epause->tx_pause)
510 *buf = SK_FLOW_MODE_SYM_OR_REM;
511 else if (!epause->rx_pause && epause->tx_pause)
512 *buf = SK_FLOW_MODE_LOC_SEND;
513 else
514 *buf = SK_FLOW_MODE_NONE;
515 }
516
517 ret = SkPnmiSetVar(pAC, pAC->IoBase, OID_SKGE_FLOWCTRL_MODE,
518 &buf, &len, instance, pNet->NetNr);
519
520 if (ret != SK_PNMI_ERR_OK) {
521 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_CTRL,
522 ("ethtool (sk98lin): error changing rx/tx pause (%i)\n", ret));
523 goto err;
524 }
525
526 /*
527 ** It may be that autoneg has been disabled! Therefore
528 ** set the speed to the previously used value...
529 */
530 if (!epause->autoneg) {
531 len = 1;
532 ret = SkPnmiSetVar(pAC, pAC->IoBase, OID_SKGE_SPEED_MODE,
533 &oldspeed, &len, instance, pNet->NetNr);
534 if (ret != SK_PNMI_ERR_OK)
535 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_CTRL,
536 ("ethtool (sk98lin): error setting speed (%i)\n", ret));
537 }
538 err:
539 return ret ? -EIO : 0;
540}
541
542/* Only Yukon supports checksum offload. */
543static int setScatterGather(struct net_device *dev, u32 data)
544{
545 DEV_NET *pNet = netdev_priv(dev);
546 SK_AC *pAC = pNet->pAC;
547
548 if (pAC->GIni.GIChipId == CHIP_ID_GENESIS)
549 return -EOPNOTSUPP;
550 return ethtool_op_set_sg(dev, data);
551}
552
553static int setTxCsum(struct net_device *dev, u32 data)
554{
555 DEV_NET *pNet = netdev_priv(dev);
556 SK_AC *pAC = pNet->pAC;
557
558 if (pAC->GIni.GIChipId == CHIP_ID_GENESIS)
559 return -EOPNOTSUPP;
560
561 return ethtool_op_set_tx_csum(dev, data);
562}
563
564static u32 getRxCsum(struct net_device *dev)
565{
566 DEV_NET *pNet = netdev_priv(dev);
567 SK_AC *pAC = pNet->pAC;
568
569 return pAC->RxPort[pNet->PortNr].RxCsum;
570}
571
572static int setRxCsum(struct net_device *dev, u32 data)
573{
574 DEV_NET *pNet = netdev_priv(dev);
575 SK_AC *pAC = pNet->pAC;
576
577 if (pAC->GIni.GIChipId == CHIP_ID_GENESIS)
578 return -EOPNOTSUPP;
579
580 pAC->RxPort[pNet->PortNr].RxCsum = data != 0;
581 return 0;
582}
583
584static int getRegsLen(struct net_device *dev)
585{
586 return 0x4000;
587}
588
589/*
590 * Returns copy of whole control register region
591 * Note: skip RAM address register because accessing it will
592 * cause bus hangs!
593 */
594static void getRegs(struct net_device *dev, struct ethtool_regs *regs,
595 void *p)
596{
597 DEV_NET *pNet = netdev_priv(dev);
598 const void __iomem *io = pNet->pAC->IoBase;
599
600 regs->version = 1;
601 memset(p, 0, regs->len);
602 memcpy_fromio(p, io, B3_RAM_ADDR);
603
604 memcpy_fromio(p + B3_RI_WTO_R1, io + B3_RI_WTO_R1,
605 regs->len - B3_RI_WTO_R1);
606}
607
608const struct ethtool_ops SkGeEthtoolOps = {
609 .get_settings = getSettings,
610 .set_settings = setSettings,
611 .get_drvinfo = getDriverInfo,
612 .get_strings = getStrings,
613 .get_stats_count = getStatsCount,
614 .get_ethtool_stats = getEthtoolStats,
615 .phys_id = locateDevice,
616 .get_pauseparam = getPauseParams,
617 .set_pauseparam = setPauseParams,
618 .get_link = ethtool_op_get_link,
619 .get_perm_addr = ethtool_op_get_perm_addr,
620 .get_sg = ethtool_op_get_sg,
621 .set_sg = setScatterGather,
622 .get_tx_csum = ethtool_op_get_tx_csum,
623 .set_tx_csum = setTxCsum,
624 .get_rx_csum = getRxCsum,
625 .set_rx_csum = setRxCsum,
626 .get_regs = getRegs,
627 .get_regs_len = getRegsLen,
628};
diff --git a/drivers/net/sk98lin/skge.c b/drivers/net/sk98lin/skge.c
deleted file mode 100644
index bf218621db16..000000000000
--- a/drivers/net/sk98lin/skge.c
+++ /dev/null
@@ -1,5211 +0,0 @@
1/******************************************************************************
2 *
3 * Name: skge.c
4 * Project: GEnesis, PCI Gigabit Ethernet Adapter
5 * Version: $Revision: 1.45 $
6 * Date: $Date: 2004/02/12 14:41:02 $
7 * Purpose: The main driver source module
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect GmbH.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * Driver for Marvell Yukon chipset and SysKonnect Gigabit Ethernet
17 * Server Adapters.
18 *
19 * Created 10-Feb-1999, based on Linux' acenic.c, 3c59x.c and
20 * SysKonnects GEnesis Solaris driver
21 * Author: Christoph Goos (cgoos@syskonnect.de)
22 * Mirko Lindner (mlindner@syskonnect.de)
23 *
24 * Address all question to: linux@syskonnect.de
25 *
26 * The technical manual for the adapters is available from SysKonnect's
27 * web pages: www.syskonnect.com
28 * Goto "Support" and search Knowledge Base for "manual".
29 *
30 * This program is free software; you can redistribute it and/or modify
31 * it under the terms of the GNU General Public License as published by
32 * the Free Software Foundation; either version 2 of the License, or
33 * (at your option) any later version.
34 *
35 * The information in this file is provided "AS IS" without warranty.
36 *
37 ******************************************************************************/
38
39/******************************************************************************
40 *
41 * Possible compiler options (#define xxx / -Dxxx):
42 *
43 * debugging can be enable by changing SK_DEBUG_CHKMOD and
44 * SK_DEBUG_CHKCAT in makefile (described there).
45 *
46 ******************************************************************************/
47
48/******************************************************************************
49 *
50 * Description:
51 *
52 * This is the main module of the Linux GE driver.
53 *
54 * All source files except skge.c, skdrv1st.h, skdrv2nd.h and sktypes.h
55 * are part of SysKonnect's COMMON MODULES for the SK-98xx adapters.
56 * Those are used for drivers on multiple OS', so some thing may seem
57 * unnecessary complicated on Linux. Please do not try to 'clean up'
58 * them without VERY good reasons, because this will make it more
59 * difficult to keep the Linux driver in synchronisation with the
60 * other versions.
61 *
62 * Include file hierarchy:
63 *
64 * <linux/module.h>
65 *
66 * "h/skdrv1st.h"
67 * <linux/types.h>
68 * <linux/kernel.h>
69 * <linux/string.h>
70 * <linux/errno.h>
71 * <linux/ioport.h>
72 * <linux/slab.h>
73 * <linux/interrupt.h>
74 * <linux/pci.h>
75 * <linux/bitops.h>
76 * <asm/byteorder.h>
77 * <asm/io.h>
78 * <linux/netdevice.h>
79 * <linux/etherdevice.h>
80 * <linux/skbuff.h>
81 * those three depending on kernel version used:
82 * <linux/bios32.h>
83 * <linux/init.h>
84 * <asm/uaccess.h>
85 * <net/checksum.h>
86 *
87 * "h/skerror.h"
88 * "h/skdebug.h"
89 * "h/sktypes.h"
90 * "h/lm80.h"
91 * "h/xmac_ii.h"
92 *
93 * "h/skdrv2nd.h"
94 * "h/skqueue.h"
95 * "h/skgehwt.h"
96 * "h/sktimer.h"
97 * "h/ski2c.h"
98 * "h/skgepnmi.h"
99 * "h/skvpd.h"
100 * "h/skgehw.h"
101 * "h/skgeinit.h"
102 * "h/skaddr.h"
103 * "h/skgesirq.h"
104 * "h/skrlmt.h"
105 *
106 ******************************************************************************/
107
108#include "h/skversion.h"
109
110#include <linux/in.h>
111#include <linux/module.h>
112#include <linux/moduleparam.h>
113#include <linux/init.h>
114#include <linux/dma-mapping.h>
115#include <linux/ip.h>
116#include <linux/mii.h>
117#include <linux/mm.h>
118
119#include "h/skdrv1st.h"
120#include "h/skdrv2nd.h"
121
122/*******************************************************************************
123 *
124 * Defines
125 *
126 ******************************************************************************/
127
128/* for debuging on x86 only */
129/* #define BREAKPOINT() asm(" int $3"); */
130
131/* use the transmit hw checksum driver functionality */
132#define USE_SK_TX_CHECKSUM
133
134/* use the receive hw checksum driver functionality */
135#define USE_SK_RX_CHECKSUM
136
137/* use the scatter-gather functionality with sendfile() */
138#define SK_ZEROCOPY
139
140/* use of a transmit complete interrupt */
141#define USE_TX_COMPLETE
142
143/*
144 * threshold for copying small receive frames
145 * set to 0 to avoid copying, set to 9001 to copy all frames
146 */
147#define SK_COPY_THRESHOLD 50
148
149/* number of adapters that can be configured via command line params */
150#define SK_MAX_CARD_PARAM 16
151
152
153
154/*
155 * use those defines for a compile-in version of the driver instead
156 * of command line parameters
157 */
158// #define LINK_SPEED_A {"Auto", }
159// #define LINK_SPEED_B {"Auto", }
160// #define AUTO_NEG_A {"Sense", }
161// #define AUTO_NEG_B {"Sense", }
162// #define DUP_CAP_A {"Both", }
163// #define DUP_CAP_B {"Both", }
164// #define FLOW_CTRL_A {"SymOrRem", }
165// #define FLOW_CTRL_B {"SymOrRem", }
166// #define ROLE_A {"Auto", }
167// #define ROLE_B {"Auto", }
168// #define PREF_PORT {"A", }
169// #define CON_TYPE {"Auto", }
170// #define RLMT_MODE {"CheckLinkState", }
171
172#define DEV_KFREE_SKB(skb) dev_kfree_skb(skb)
173#define DEV_KFREE_SKB_IRQ(skb) dev_kfree_skb_irq(skb)
174#define DEV_KFREE_SKB_ANY(skb) dev_kfree_skb_any(skb)
175
176
177/* Set blink mode*/
178#define OEM_CONFIG_VALUE ( SK_ACT_LED_BLINK | \
179 SK_DUP_LED_NORMAL | \
180 SK_LED_LINK100_ON)
181
182
183/* Isr return value */
184#define SkIsrRetVar irqreturn_t
185#define SkIsrRetNone IRQ_NONE
186#define SkIsrRetHandled IRQ_HANDLED
187
188
189/*******************************************************************************
190 *
191 * Local Function Prototypes
192 *
193 ******************************************************************************/
194
195static void FreeResources(struct SK_NET_DEVICE *dev);
196static int SkGeBoardInit(struct SK_NET_DEVICE *dev, SK_AC *pAC);
197static SK_BOOL BoardAllocMem(SK_AC *pAC);
198static void BoardFreeMem(SK_AC *pAC);
199static void BoardInitMem(SK_AC *pAC);
200static void SetupRing(SK_AC*, void*, uintptr_t, RXD**, RXD**, RXD**, int*, SK_BOOL);
201static SkIsrRetVar SkGeIsr(int irq, void *dev_id);
202static SkIsrRetVar SkGeIsrOnePort(int irq, void *dev_id);
203static int SkGeOpen(struct SK_NET_DEVICE *dev);
204static int SkGeClose(struct SK_NET_DEVICE *dev);
205static int SkGeXmit(struct sk_buff *skb, struct SK_NET_DEVICE *dev);
206static int SkGeSetMacAddr(struct SK_NET_DEVICE *dev, void *p);
207static void SkGeSetRxMode(struct SK_NET_DEVICE *dev);
208static struct net_device_stats *SkGeStats(struct SK_NET_DEVICE *dev);
209static int SkGeIoctl(struct SK_NET_DEVICE *dev, struct ifreq *rq, int cmd);
210static void GetConfiguration(SK_AC*);
211static int XmitFrame(SK_AC*, TX_PORT*, struct sk_buff*);
212static void FreeTxDescriptors(SK_AC*pAC, TX_PORT*);
213static void FillRxRing(SK_AC*, RX_PORT*);
214static SK_BOOL FillRxDescriptor(SK_AC*, RX_PORT*);
215static void ReceiveIrq(SK_AC*, RX_PORT*, SK_BOOL);
216static void ClearAndStartRx(SK_AC*, int);
217static void ClearTxIrq(SK_AC*, int, int);
218static void ClearRxRing(SK_AC*, RX_PORT*);
219static void ClearTxRing(SK_AC*, TX_PORT*);
220static int SkGeChangeMtu(struct SK_NET_DEVICE *dev, int new_mtu);
221static void PortReInitBmu(SK_AC*, int);
222static int SkGeIocMib(DEV_NET*, unsigned int, int);
223static int SkGeInitPCI(SK_AC *pAC);
224static void StartDrvCleanupTimer(SK_AC *pAC);
225static void StopDrvCleanupTimer(SK_AC *pAC);
226static int XmitFrameSG(SK_AC*, TX_PORT*, struct sk_buff*);
227
228#ifdef SK_DIAG_SUPPORT
229static SK_U32 ParseDeviceNbrFromSlotName(const char *SlotName);
230static int SkDrvInitAdapter(SK_AC *pAC, int devNbr);
231static int SkDrvDeInitAdapter(SK_AC *pAC, int devNbr);
232#endif
233
234/*******************************************************************************
235 *
236 * Extern Function Prototypes
237 *
238 ******************************************************************************/
239extern void SkDimEnableModerationIfNeeded(SK_AC *pAC);
240extern void SkDimDisplayModerationSettings(SK_AC *pAC);
241extern void SkDimStartModerationTimer(SK_AC *pAC);
242extern void SkDimModerate(SK_AC *pAC);
243extern void SkGeBlinkTimer(unsigned long data);
244
245#ifdef DEBUG
246static void DumpMsg(struct sk_buff*, char*);
247static void DumpData(char*, int);
248static void DumpLong(char*, int);
249#endif
250
251/* global variables *********************************************************/
252static SK_BOOL DoPrintInterfaceChange = SK_TRUE;
253extern const struct ethtool_ops SkGeEthtoolOps;
254
255/* local variables **********************************************************/
256static uintptr_t TxQueueAddr[SK_MAX_MACS][2] = {{0x680, 0x600},{0x780, 0x700}};
257static uintptr_t RxQueueAddr[SK_MAX_MACS] = {0x400, 0x480};
258
259/*****************************************************************************
260 *
261 * SkPciWriteCfgDWord - write a 32 bit value to pci config space
262 *
263 * Description:
264 * This routine writes a 32 bit value to the pci configuration
265 * space.
266 *
267 * Returns:
268 * 0 - indicate everything worked ok.
269 * != 0 - error indication
270 */
271static inline int SkPciWriteCfgDWord(
272SK_AC *pAC, /* Adapter Control structure pointer */
273int PciAddr, /* PCI register address */
274SK_U32 Val) /* pointer to store the read value */
275{
276 pci_write_config_dword(pAC->PciDev, PciAddr, Val);
277 return(0);
278} /* SkPciWriteCfgDWord */
279
280/*****************************************************************************
281 *
282 * SkGeInitPCI - Init the PCI resources
283 *
284 * Description:
285 * This function initialize the PCI resources and IO
286 *
287 * Returns:
288 * 0 - indicate everything worked ok.
289 * != 0 - error indication
290 */
291static __devinit int SkGeInitPCI(SK_AC *pAC)
292{
293 struct SK_NET_DEVICE *dev = pAC->dev[0];
294 struct pci_dev *pdev = pAC->PciDev;
295 int retval;
296
297 dev->mem_start = pci_resource_start (pdev, 0);
298 pci_set_master(pdev);
299
300 retval = pci_request_regions(pdev, "sk98lin");
301 if (retval)
302 goto out;
303
304#ifdef SK_BIG_ENDIAN
305 /*
306 * On big endian machines, we use the adapter's aibility of
307 * reading the descriptors as big endian.
308 */
309 {
310 SK_U32 our2;
311 SkPciReadCfgDWord(pAC, PCI_OUR_REG_2, &our2);
312 our2 |= PCI_REV_DESC;
313 SkPciWriteCfgDWord(pAC, PCI_OUR_REG_2, our2);
314 }
315#endif
316
317 /*
318 * Remap the regs into kernel space.
319 */
320 pAC->IoBase = ioremap_nocache(dev->mem_start, 0x4000);
321 if (!pAC->IoBase) {
322 retval = -EIO;
323 goto out_release;
324 }
325
326 return 0;
327
328 out_release:
329 pci_release_regions(pdev);
330 out:
331 return retval;
332}
333
334
335/*****************************************************************************
336 *
337 * FreeResources - release resources allocated for adapter
338 *
339 * Description:
340 * This function releases the IRQ, unmaps the IO and
341 * frees the desriptor ring.
342 *
343 * Returns: N/A
344 *
345 */
346static void FreeResources(struct SK_NET_DEVICE *dev)
347{
348SK_U32 AllocFlag;
349DEV_NET *pNet;
350SK_AC *pAC;
351
352 pNet = netdev_priv(dev);
353 pAC = pNet->pAC;
354 AllocFlag = pAC->AllocFlag;
355 if (pAC->PciDev) {
356 pci_release_regions(pAC->PciDev);
357 }
358 if (AllocFlag & SK_ALLOC_IRQ) {
359 free_irq(dev->irq, dev);
360 }
361 if (pAC->IoBase) {
362 iounmap(pAC->IoBase);
363 }
364 if (pAC->pDescrMem) {
365 BoardFreeMem(pAC);
366 }
367
368} /* FreeResources */
369
370MODULE_AUTHOR("Mirko Lindner <mlindner@syskonnect.de>");
371MODULE_DESCRIPTION("SysKonnect SK-NET Gigabit Ethernet SK-98xx driver");
372MODULE_LICENSE("GPL");
373
374#ifdef LINK_SPEED_A
375static char *Speed_A[SK_MAX_CARD_PARAM] = LINK_SPEED;
376#else
377static char *Speed_A[SK_MAX_CARD_PARAM] = {"", };
378#endif
379
380#ifdef LINK_SPEED_B
381static char *Speed_B[SK_MAX_CARD_PARAM] = LINK_SPEED;
382#else
383static char *Speed_B[SK_MAX_CARD_PARAM] = {"", };
384#endif
385
386#ifdef AUTO_NEG_A
387static char *AutoNeg_A[SK_MAX_CARD_PARAM] = AUTO_NEG_A;
388#else
389static char *AutoNeg_A[SK_MAX_CARD_PARAM] = {"", };
390#endif
391
392#ifdef DUP_CAP_A
393static char *DupCap_A[SK_MAX_CARD_PARAM] = DUP_CAP_A;
394#else
395static char *DupCap_A[SK_MAX_CARD_PARAM] = {"", };
396#endif
397
398#ifdef FLOW_CTRL_A
399static char *FlowCtrl_A[SK_MAX_CARD_PARAM] = FLOW_CTRL_A;
400#else
401static char *FlowCtrl_A[SK_MAX_CARD_PARAM] = {"", };
402#endif
403
404#ifdef ROLE_A
405static char *Role_A[SK_MAX_CARD_PARAM] = ROLE_A;
406#else
407static char *Role_A[SK_MAX_CARD_PARAM] = {"", };
408#endif
409
410#ifdef AUTO_NEG_B
411static char *AutoNeg_B[SK_MAX_CARD_PARAM] = AUTO_NEG_B;
412#else
413static char *AutoNeg_B[SK_MAX_CARD_PARAM] = {"", };
414#endif
415
416#ifdef DUP_CAP_B
417static char *DupCap_B[SK_MAX_CARD_PARAM] = DUP_CAP_B;
418#else
419static char *DupCap_B[SK_MAX_CARD_PARAM] = {"", };
420#endif
421
422#ifdef FLOW_CTRL_B
423static char *FlowCtrl_B[SK_MAX_CARD_PARAM] = FLOW_CTRL_B;
424#else
425static char *FlowCtrl_B[SK_MAX_CARD_PARAM] = {"", };
426#endif
427
428#ifdef ROLE_B
429static char *Role_B[SK_MAX_CARD_PARAM] = ROLE_B;
430#else
431static char *Role_B[SK_MAX_CARD_PARAM] = {"", };
432#endif
433
434#ifdef CON_TYPE
435static char *ConType[SK_MAX_CARD_PARAM] = CON_TYPE;
436#else
437static char *ConType[SK_MAX_CARD_PARAM] = {"", };
438#endif
439
440#ifdef PREF_PORT
441static char *PrefPort[SK_MAX_CARD_PARAM] = PREF_PORT;
442#else
443static char *PrefPort[SK_MAX_CARD_PARAM] = {"", };
444#endif
445
446#ifdef RLMT_MODE
447static char *RlmtMode[SK_MAX_CARD_PARAM] = RLMT_MODE;
448#else
449static char *RlmtMode[SK_MAX_CARD_PARAM] = {"", };
450#endif
451
452static int IntsPerSec[SK_MAX_CARD_PARAM];
453static char *Moderation[SK_MAX_CARD_PARAM];
454static char *ModerationMask[SK_MAX_CARD_PARAM];
455static char *AutoSizing[SK_MAX_CARD_PARAM];
456static char *Stats[SK_MAX_CARD_PARAM];
457
458module_param_array(Speed_A, charp, NULL, 0);
459module_param_array(Speed_B, charp, NULL, 0);
460module_param_array(AutoNeg_A, charp, NULL, 0);
461module_param_array(AutoNeg_B, charp, NULL, 0);
462module_param_array(DupCap_A, charp, NULL, 0);
463module_param_array(DupCap_B, charp, NULL, 0);
464module_param_array(FlowCtrl_A, charp, NULL, 0);
465module_param_array(FlowCtrl_B, charp, NULL, 0);
466module_param_array(Role_A, charp, NULL, 0);
467module_param_array(Role_B, charp, NULL, 0);
468module_param_array(ConType, charp, NULL, 0);
469module_param_array(PrefPort, charp, NULL, 0);
470module_param_array(RlmtMode, charp, NULL, 0);
471/* used for interrupt moderation */
472module_param_array(IntsPerSec, int, NULL, 0);
473module_param_array(Moderation, charp, NULL, 0);
474module_param_array(Stats, charp, NULL, 0);
475module_param_array(ModerationMask, charp, NULL, 0);
476module_param_array(AutoSizing, charp, NULL, 0);
477
478/*****************************************************************************
479 *
480 * SkGeBoardInit - do level 0 and 1 initialization
481 *
482 * Description:
483 * This function prepares the board hardware for running. The desriptor
484 * ring is set up, the IRQ is allocated and the configuration settings
485 * are examined.
486 *
487 * Returns:
488 * 0, if everything is ok
489 * !=0, on error
490 */
491static int __devinit SkGeBoardInit(struct SK_NET_DEVICE *dev, SK_AC *pAC)
492{
493short i;
494unsigned long Flags;
495char *DescrString = "sk98lin: Driver for Linux"; /* this is given to PNMI */
496char *VerStr = VER_STRING;
497int Ret; /* return code of request_irq */
498SK_BOOL DualNet;
499
500 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
501 ("IoBase: %08lX\n", (unsigned long)pAC->IoBase));
502 for (i=0; i<SK_MAX_MACS; i++) {
503 pAC->TxPort[i][0].HwAddr = pAC->IoBase + TxQueueAddr[i][0];
504 pAC->TxPort[i][0].PortIndex = i;
505 pAC->RxPort[i].HwAddr = pAC->IoBase + RxQueueAddr[i];
506 pAC->RxPort[i].PortIndex = i;
507 }
508
509 /* Initialize the mutexes */
510 for (i=0; i<SK_MAX_MACS; i++) {
511 spin_lock_init(&pAC->TxPort[i][0].TxDesRingLock);
512 spin_lock_init(&pAC->RxPort[i].RxDesRingLock);
513 }
514 spin_lock_init(&pAC->SlowPathLock);
515
516 /* setup phy_id blink timer */
517 pAC->BlinkTimer.function = SkGeBlinkTimer;
518 pAC->BlinkTimer.data = (unsigned long) dev;
519 init_timer(&pAC->BlinkTimer);
520
521 /* level 0 init common modules here */
522
523 spin_lock_irqsave(&pAC->SlowPathLock, Flags);
524 /* Does a RESET on board ...*/
525 if (SkGeInit(pAC, pAC->IoBase, SK_INIT_DATA) != 0) {
526 printk("HWInit (0) failed.\n");
527 spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
528 return -EIO;
529 }
530 SkI2cInit( pAC, pAC->IoBase, SK_INIT_DATA);
531 SkEventInit(pAC, pAC->IoBase, SK_INIT_DATA);
532 SkPnmiInit( pAC, pAC->IoBase, SK_INIT_DATA);
533 SkAddrInit( pAC, pAC->IoBase, SK_INIT_DATA);
534 SkRlmtInit( pAC, pAC->IoBase, SK_INIT_DATA);
535 SkTimerInit(pAC, pAC->IoBase, SK_INIT_DATA);
536
537 pAC->BoardLevel = SK_INIT_DATA;
538 pAC->RxBufSize = ETH_BUF_SIZE;
539
540 SK_PNMI_SET_DRIVER_DESCR(pAC, DescrString);
541 SK_PNMI_SET_DRIVER_VER(pAC, VerStr);
542
543 spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
544
545 /* level 1 init common modules here (HW init) */
546 spin_lock_irqsave(&pAC->SlowPathLock, Flags);
547 if (SkGeInit(pAC, pAC->IoBase, SK_INIT_IO) != 0) {
548 printk("sk98lin: HWInit (1) failed.\n");
549 spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
550 return -EIO;
551 }
552 SkI2cInit( pAC, pAC->IoBase, SK_INIT_IO);
553 SkEventInit(pAC, pAC->IoBase, SK_INIT_IO);
554 SkPnmiInit( pAC, pAC->IoBase, SK_INIT_IO);
555 SkAddrInit( pAC, pAC->IoBase, SK_INIT_IO);
556 SkRlmtInit( pAC, pAC->IoBase, SK_INIT_IO);
557 SkTimerInit(pAC, pAC->IoBase, SK_INIT_IO);
558
559 /* Set chipset type support */
560 pAC->ChipsetType = 0;
561 if ((pAC->GIni.GIChipId == CHIP_ID_YUKON) ||
562 (pAC->GIni.GIChipId == CHIP_ID_YUKON_LITE)) {
563 pAC->ChipsetType = 1;
564 }
565
566 GetConfiguration(pAC);
567 if (pAC->RlmtNets == 2) {
568 pAC->GIni.GIPortUsage = SK_MUL_LINK;
569 }
570
571 pAC->BoardLevel = SK_INIT_IO;
572 spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
573
574 if (pAC->GIni.GIMacsFound == 2) {
575 Ret = request_irq(dev->irq, SkGeIsr, IRQF_SHARED, "sk98lin", dev);
576 } else if (pAC->GIni.GIMacsFound == 1) {
577 Ret = request_irq(dev->irq, SkGeIsrOnePort, IRQF_SHARED,
578 "sk98lin", dev);
579 } else {
580 printk(KERN_WARNING "sk98lin: Illegal number of ports: %d\n",
581 pAC->GIni.GIMacsFound);
582 return -EIO;
583 }
584
585 if (Ret) {
586 printk(KERN_WARNING "sk98lin: Requested IRQ %d is busy.\n",
587 dev->irq);
588 return Ret;
589 }
590 pAC->AllocFlag |= SK_ALLOC_IRQ;
591
592 /* Alloc memory for this board (Mem for RxD/TxD) : */
593 if(!BoardAllocMem(pAC)) {
594 printk("No memory for descriptor rings.\n");
595 return -ENOMEM;
596 }
597
598 BoardInitMem(pAC);
599 /* tschilling: New common function with minimum size check. */
600 DualNet = SK_FALSE;
601 if (pAC->RlmtNets == 2) {
602 DualNet = SK_TRUE;
603 }
604
605 if (SkGeInitAssignRamToQueues(
606 pAC,
607 pAC->ActivePort,
608 DualNet)) {
609 BoardFreeMem(pAC);
610 printk("sk98lin: SkGeInitAssignRamToQueues failed.\n");
611 return -EIO;
612 }
613
614 return (0);
615} /* SkGeBoardInit */
616
617
618/*****************************************************************************
619 *
620 * BoardAllocMem - allocate the memory for the descriptor rings
621 *
622 * Description:
623 * This function allocates the memory for all descriptor rings.
624 * Each ring is aligned for the desriptor alignment and no ring
625 * has a 4 GByte boundary in it (because the upper 32 bit must
626 * be constant for all descriptiors in one rings).
627 *
628 * Returns:
629 * SK_TRUE, if all memory could be allocated
630 * SK_FALSE, if not
631 */
632static __devinit SK_BOOL BoardAllocMem(SK_AC *pAC)
633{
634caddr_t pDescrMem; /* pointer to descriptor memory area */
635size_t AllocLength; /* length of complete descriptor area */
636int i; /* loop counter */
637unsigned long BusAddr;
638
639
640 /* rings plus one for alignment (do not cross 4 GB boundary) */
641 /* RX_RING_SIZE is assumed bigger than TX_RING_SIZE */
642#if (BITS_PER_LONG == 32)
643 AllocLength = (RX_RING_SIZE + TX_RING_SIZE) * pAC->GIni.GIMacsFound + 8;
644#else
645 AllocLength = (RX_RING_SIZE + TX_RING_SIZE) * pAC->GIni.GIMacsFound
646 + RX_RING_SIZE + 8;
647#endif
648
649 pDescrMem = pci_alloc_consistent(pAC->PciDev, AllocLength,
650 &pAC->pDescrMemDMA);
651
652 if (pDescrMem == NULL) {
653 return (SK_FALSE);
654 }
655 pAC->pDescrMem = pDescrMem;
656 BusAddr = (unsigned long) pAC->pDescrMemDMA;
657
658 /* Descriptors need 8 byte alignment, and this is ensured
659 * by pci_alloc_consistent.
660 */
661 for (i=0; i<pAC->GIni.GIMacsFound; i++) {
662 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
663 ("TX%d/A: pDescrMem: %lX, PhysDescrMem: %lX\n",
664 i, (unsigned long) pDescrMem,
665 BusAddr));
666 pAC->TxPort[i][0].pTxDescrRing = pDescrMem;
667 pAC->TxPort[i][0].VTxDescrRing = BusAddr;
668 pDescrMem += TX_RING_SIZE;
669 BusAddr += TX_RING_SIZE;
670
671 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
672 ("RX%d: pDescrMem: %lX, PhysDescrMem: %lX\n",
673 i, (unsigned long) pDescrMem,
674 (unsigned long)BusAddr));
675 pAC->RxPort[i].pRxDescrRing = pDescrMem;
676 pAC->RxPort[i].VRxDescrRing = BusAddr;
677 pDescrMem += RX_RING_SIZE;
678 BusAddr += RX_RING_SIZE;
679 } /* for */
680
681 return (SK_TRUE);
682} /* BoardAllocMem */
683
684
685/****************************************************************************
686 *
687 * BoardFreeMem - reverse of BoardAllocMem
688 *
689 * Description:
690 * Free all memory allocated in BoardAllocMem: adapter context,
691 * descriptor rings, locks.
692 *
693 * Returns: N/A
694 */
695static void BoardFreeMem(
696SK_AC *pAC)
697{
698size_t AllocLength; /* length of complete descriptor area */
699
700 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
701 ("BoardFreeMem\n"));
702#if (BITS_PER_LONG == 32)
703 AllocLength = (RX_RING_SIZE + TX_RING_SIZE) * pAC->GIni.GIMacsFound + 8;
704#else
705 AllocLength = (RX_RING_SIZE + TX_RING_SIZE) * pAC->GIni.GIMacsFound
706 + RX_RING_SIZE + 8;
707#endif
708
709 pci_free_consistent(pAC->PciDev, AllocLength,
710 pAC->pDescrMem, pAC->pDescrMemDMA);
711 pAC->pDescrMem = NULL;
712} /* BoardFreeMem */
713
714
715/*****************************************************************************
716 *
717 * BoardInitMem - initiate the descriptor rings
718 *
719 * Description:
720 * This function sets the descriptor rings up in memory.
721 * The adapter is initialized with the descriptor start addresses.
722 *
723 * Returns: N/A
724 */
725static __devinit void BoardInitMem(SK_AC *pAC)
726{
727int i; /* loop counter */
728int RxDescrSize; /* the size of a rx descriptor rounded up to alignment*/
729int TxDescrSize; /* the size of a tx descriptor rounded up to alignment*/
730
731 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
732 ("BoardInitMem\n"));
733
734 RxDescrSize = (((sizeof(RXD) - 1) / DESCR_ALIGN) + 1) * DESCR_ALIGN;
735 pAC->RxDescrPerRing = RX_RING_SIZE / RxDescrSize;
736 TxDescrSize = (((sizeof(TXD) - 1) / DESCR_ALIGN) + 1) * DESCR_ALIGN;
737 pAC->TxDescrPerRing = TX_RING_SIZE / RxDescrSize;
738
739 for (i=0; i<pAC->GIni.GIMacsFound; i++) {
740 SetupRing(
741 pAC,
742 pAC->TxPort[i][0].pTxDescrRing,
743 pAC->TxPort[i][0].VTxDescrRing,
744 (RXD**)&pAC->TxPort[i][0].pTxdRingHead,
745 (RXD**)&pAC->TxPort[i][0].pTxdRingTail,
746 (RXD**)&pAC->TxPort[i][0].pTxdRingPrev,
747 &pAC->TxPort[i][0].TxdRingFree,
748 SK_TRUE);
749 SetupRing(
750 pAC,
751 pAC->RxPort[i].pRxDescrRing,
752 pAC->RxPort[i].VRxDescrRing,
753 &pAC->RxPort[i].pRxdRingHead,
754 &pAC->RxPort[i].pRxdRingTail,
755 &pAC->RxPort[i].pRxdRingPrev,
756 &pAC->RxPort[i].RxdRingFree,
757 SK_FALSE);
758 }
759} /* BoardInitMem */
760
761
762/*****************************************************************************
763 *
764 * SetupRing - create one descriptor ring
765 *
766 * Description:
767 * This function creates one descriptor ring in the given memory area.
768 * The head, tail and number of free descriptors in the ring are set.
769 *
770 * Returns:
771 * none
772 */
773static void SetupRing(
774SK_AC *pAC,
775void *pMemArea, /* a pointer to the memory area for the ring */
776uintptr_t VMemArea, /* the virtual bus address of the memory area */
777RXD **ppRingHead, /* address where the head should be written */
778RXD **ppRingTail, /* address where the tail should be written */
779RXD **ppRingPrev, /* address where the tail should be written */
780int *pRingFree, /* address where the # of free descr. goes */
781SK_BOOL IsTx) /* flag: is this a tx ring */
782{
783int i; /* loop counter */
784int DescrSize; /* the size of a descriptor rounded up to alignment*/
785int DescrNum; /* number of descriptors per ring */
786RXD *pDescr; /* pointer to a descriptor (receive or transmit) */
787RXD *pNextDescr; /* pointer to the next descriptor */
788RXD *pPrevDescr; /* pointer to the previous descriptor */
789uintptr_t VNextDescr; /* the virtual bus address of the next descriptor */
790
791 if (IsTx == SK_TRUE) {
792 DescrSize = (((sizeof(TXD) - 1) / DESCR_ALIGN) + 1) *
793 DESCR_ALIGN;
794 DescrNum = TX_RING_SIZE / DescrSize;
795 } else {
796 DescrSize = (((sizeof(RXD) - 1) / DESCR_ALIGN) + 1) *
797 DESCR_ALIGN;
798 DescrNum = RX_RING_SIZE / DescrSize;
799 }
800
801 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
802 ("Descriptor size: %d Descriptor Number: %d\n",
803 DescrSize,DescrNum));
804
805 pDescr = (RXD*) pMemArea;
806 pPrevDescr = NULL;
807 pNextDescr = (RXD*) (((char*)pDescr) + DescrSize);
808 VNextDescr = VMemArea + DescrSize;
809 for(i=0; i<DescrNum; i++) {
810 /* set the pointers right */
811 pDescr->VNextRxd = VNextDescr & 0xffffffffULL;
812 pDescr->pNextRxd = pNextDescr;
813 if (!IsTx) pDescr->TcpSumStarts = ETH_HLEN << 16 | ETH_HLEN;
814
815 /* advance one step */
816 pPrevDescr = pDescr;
817 pDescr = pNextDescr;
818 pNextDescr = (RXD*) (((char*)pDescr) + DescrSize);
819 VNextDescr += DescrSize;
820 }
821 pPrevDescr->pNextRxd = (RXD*) pMemArea;
822 pPrevDescr->VNextRxd = VMemArea;
823 pDescr = (RXD*) pMemArea;
824 *ppRingHead = (RXD*) pMemArea;
825 *ppRingTail = *ppRingHead;
826 *ppRingPrev = pPrevDescr;
827 *pRingFree = DescrNum;
828} /* SetupRing */
829
830
831/*****************************************************************************
832 *
833 * PortReInitBmu - re-initiate the descriptor rings for one port
834 *
835 * Description:
836 * This function reinitializes the descriptor rings of one port
837 * in memory. The port must be stopped before.
838 * The HW is initialized with the descriptor start addresses.
839 *
840 * Returns:
841 * none
842 */
843static void PortReInitBmu(
844SK_AC *pAC, /* pointer to adapter context */
845int PortIndex) /* index of the port for which to re-init */
846{
847 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
848 ("PortReInitBmu "));
849
850 /* set address of first descriptor of ring in BMU */
851 SK_OUT32(pAC->IoBase, TxQueueAddr[PortIndex][TX_PRIO_LOW]+ Q_DA_L,
852 (uint32_t)(((caddr_t)
853 (pAC->TxPort[PortIndex][TX_PRIO_LOW].pTxdRingHead) -
854 pAC->TxPort[PortIndex][TX_PRIO_LOW].pTxDescrRing +
855 pAC->TxPort[PortIndex][TX_PRIO_LOW].VTxDescrRing) &
856 0xFFFFFFFF));
857 SK_OUT32(pAC->IoBase, TxQueueAddr[PortIndex][TX_PRIO_LOW]+ Q_DA_H,
858 (uint32_t)(((caddr_t)
859 (pAC->TxPort[PortIndex][TX_PRIO_LOW].pTxdRingHead) -
860 pAC->TxPort[PortIndex][TX_PRIO_LOW].pTxDescrRing +
861 pAC->TxPort[PortIndex][TX_PRIO_LOW].VTxDescrRing) >> 32));
862 SK_OUT32(pAC->IoBase, RxQueueAddr[PortIndex]+Q_DA_L,
863 (uint32_t)(((caddr_t)(pAC->RxPort[PortIndex].pRxdRingHead) -
864 pAC->RxPort[PortIndex].pRxDescrRing +
865 pAC->RxPort[PortIndex].VRxDescrRing) & 0xFFFFFFFF));
866 SK_OUT32(pAC->IoBase, RxQueueAddr[PortIndex]+Q_DA_H,
867 (uint32_t)(((caddr_t)(pAC->RxPort[PortIndex].pRxdRingHead) -
868 pAC->RxPort[PortIndex].pRxDescrRing +
869 pAC->RxPort[PortIndex].VRxDescrRing) >> 32));
870} /* PortReInitBmu */
871
872
873/****************************************************************************
874 *
875 * SkGeIsr - handle adapter interrupts
876 *
877 * Description:
878 * The interrupt routine is called when the network adapter
879 * generates an interrupt. It may also be called if another device
880 * shares this interrupt vector with the driver.
881 *
882 * Returns: N/A
883 *
884 */
885static SkIsrRetVar SkGeIsr(int irq, void *dev_id)
886{
887struct SK_NET_DEVICE *dev = (struct SK_NET_DEVICE *)dev_id;
888DEV_NET *pNet;
889SK_AC *pAC;
890SK_U32 IntSrc; /* interrupts source register contents */
891
892 pNet = netdev_priv(dev);
893 pAC = pNet->pAC;
894
895 /*
896 * Check and process if its our interrupt
897 */
898 SK_IN32(pAC->IoBase, B0_SP_ISRC, &IntSrc);
899 if (IntSrc == 0) {
900 return SkIsrRetNone;
901 }
902
903 while (((IntSrc & IRQ_MASK) & ~SPECIAL_IRQS) != 0) {
904#if 0 /* software irq currently not used */
905 if (IntSrc & IS_IRQ_SW) {
906 SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
907 SK_DBGCAT_DRV_INT_SRC,
908 ("Software IRQ\n"));
909 }
910#endif
911 if (IntSrc & IS_R1_F) {
912 SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
913 SK_DBGCAT_DRV_INT_SRC,
914 ("EOF RX1 IRQ\n"));
915 ReceiveIrq(pAC, &pAC->RxPort[0], SK_TRUE);
916 SK_PNMI_CNT_RX_INTR(pAC, 0);
917 }
918 if (IntSrc & IS_R2_F) {
919 SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
920 SK_DBGCAT_DRV_INT_SRC,
921 ("EOF RX2 IRQ\n"));
922 ReceiveIrq(pAC, &pAC->RxPort[1], SK_TRUE);
923 SK_PNMI_CNT_RX_INTR(pAC, 1);
924 }
925#ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */
926 if (IntSrc & IS_XA1_F) {
927 SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
928 SK_DBGCAT_DRV_INT_SRC,
929 ("EOF AS TX1 IRQ\n"));
930 SK_PNMI_CNT_TX_INTR(pAC, 0);
931 spin_lock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock);
932 FreeTxDescriptors(pAC, &pAC->TxPort[0][TX_PRIO_LOW]);
933 spin_unlock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock);
934 }
935 if (IntSrc & IS_XA2_F) {
936 SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
937 SK_DBGCAT_DRV_INT_SRC,
938 ("EOF AS TX2 IRQ\n"));
939 SK_PNMI_CNT_TX_INTR(pAC, 1);
940 spin_lock(&pAC->TxPort[1][TX_PRIO_LOW].TxDesRingLock);
941 FreeTxDescriptors(pAC, &pAC->TxPort[1][TX_PRIO_LOW]);
942 spin_unlock(&pAC->TxPort[1][TX_PRIO_LOW].TxDesRingLock);
943 }
944#if 0 /* only if sync. queues used */
945 if (IntSrc & IS_XS1_F) {
946 SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
947 SK_DBGCAT_DRV_INT_SRC,
948 ("EOF SY TX1 IRQ\n"));
949 SK_PNMI_CNT_TX_INTR(pAC, 1);
950 spin_lock(&pAC->TxPort[0][TX_PRIO_HIGH].TxDesRingLock);
951 FreeTxDescriptors(pAC, 0, TX_PRIO_HIGH);
952 spin_unlock(&pAC->TxPort[0][TX_PRIO_HIGH].TxDesRingLock);
953 ClearTxIrq(pAC, 0, TX_PRIO_HIGH);
954 }
955 if (IntSrc & IS_XS2_F) {
956 SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
957 SK_DBGCAT_DRV_INT_SRC,
958 ("EOF SY TX2 IRQ\n"));
959 SK_PNMI_CNT_TX_INTR(pAC, 1);
960 spin_lock(&pAC->TxPort[1][TX_PRIO_HIGH].TxDesRingLock);
961 FreeTxDescriptors(pAC, 1, TX_PRIO_HIGH);
962 spin_unlock(&pAC->TxPort[1][TX_PRIO_HIGH].TxDesRingLock);
963 ClearTxIrq(pAC, 1, TX_PRIO_HIGH);
964 }
965#endif
966#endif
967
968 /* do all IO at once */
969 if (IntSrc & IS_R1_F)
970 ClearAndStartRx(pAC, 0);
971 if (IntSrc & IS_R2_F)
972 ClearAndStartRx(pAC, 1);
973#ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */
974 if (IntSrc & IS_XA1_F)
975 ClearTxIrq(pAC, 0, TX_PRIO_LOW);
976 if (IntSrc & IS_XA2_F)
977 ClearTxIrq(pAC, 1, TX_PRIO_LOW);
978#endif
979 SK_IN32(pAC->IoBase, B0_ISRC, &IntSrc);
980 } /* while (IntSrc & IRQ_MASK != 0) */
981
982 IntSrc &= pAC->GIni.GIValIrqMask;
983 if ((IntSrc & SPECIAL_IRQS) || pAC->CheckQueue) {
984 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC,
985 ("SPECIAL IRQ DP-Cards => %x\n", IntSrc));
986 pAC->CheckQueue = SK_FALSE;
987 spin_lock(&pAC->SlowPathLock);
988 if (IntSrc & SPECIAL_IRQS)
989 SkGeSirqIsr(pAC, pAC->IoBase, IntSrc);
990
991 SkEventDispatcher(pAC, pAC->IoBase);
992 spin_unlock(&pAC->SlowPathLock);
993 }
994 /*
995 * do it all again is case we cleared an interrupt that
996 * came in after handling the ring (OUTs may be delayed
997 * in hardware buffers, but are through after IN)
998 *
999 * rroesler: has been commented out and shifted to
1000 * SkGeDrvEvent(), because it is timer
1001 * guarded now
1002 *
1003 ReceiveIrq(pAC, &pAC->RxPort[0], SK_TRUE);
1004 ReceiveIrq(pAC, &pAC->RxPort[1], SK_TRUE);
1005 */
1006
1007 if (pAC->CheckQueue) {
1008 pAC->CheckQueue = SK_FALSE;
1009 spin_lock(&pAC->SlowPathLock);
1010 SkEventDispatcher(pAC, pAC->IoBase);
1011 spin_unlock(&pAC->SlowPathLock);
1012 }
1013
1014 /* IRQ is processed - Enable IRQs again*/
1015 SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask);
1016
1017 return SkIsrRetHandled;
1018} /* SkGeIsr */
1019
1020
1021/****************************************************************************
1022 *
1023 * SkGeIsrOnePort - handle adapter interrupts for single port adapter
1024 *
1025 * Description:
1026 * The interrupt routine is called when the network adapter
1027 * generates an interrupt. It may also be called if another device
1028 * shares this interrupt vector with the driver.
1029 * This is the same as above, but handles only one port.
1030 *
1031 * Returns: N/A
1032 *
1033 */
1034static SkIsrRetVar SkGeIsrOnePort(int irq, void *dev_id)
1035{
1036struct SK_NET_DEVICE *dev = (struct SK_NET_DEVICE *)dev_id;
1037DEV_NET *pNet;
1038SK_AC *pAC;
1039SK_U32 IntSrc; /* interrupts source register contents */
1040
1041 pNet = netdev_priv(dev);
1042 pAC = pNet->pAC;
1043
1044 /*
1045 * Check and process if its our interrupt
1046 */
1047 SK_IN32(pAC->IoBase, B0_SP_ISRC, &IntSrc);
1048 if (IntSrc == 0) {
1049 return SkIsrRetNone;
1050 }
1051
1052 while (((IntSrc & IRQ_MASK) & ~SPECIAL_IRQS) != 0) {
1053#if 0 /* software irq currently not used */
1054 if (IntSrc & IS_IRQ_SW) {
1055 SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
1056 SK_DBGCAT_DRV_INT_SRC,
1057 ("Software IRQ\n"));
1058 }
1059#endif
1060 if (IntSrc & IS_R1_F) {
1061 SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
1062 SK_DBGCAT_DRV_INT_SRC,
1063 ("EOF RX1 IRQ\n"));
1064 ReceiveIrq(pAC, &pAC->RxPort[0], SK_TRUE);
1065 SK_PNMI_CNT_RX_INTR(pAC, 0);
1066 }
1067#ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */
1068 if (IntSrc & IS_XA1_F) {
1069 SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
1070 SK_DBGCAT_DRV_INT_SRC,
1071 ("EOF AS TX1 IRQ\n"));
1072 SK_PNMI_CNT_TX_INTR(pAC, 0);
1073 spin_lock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock);
1074 FreeTxDescriptors(pAC, &pAC->TxPort[0][TX_PRIO_LOW]);
1075 spin_unlock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock);
1076 }
1077#if 0 /* only if sync. queues used */
1078 if (IntSrc & IS_XS1_F) {
1079 SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
1080 SK_DBGCAT_DRV_INT_SRC,
1081 ("EOF SY TX1 IRQ\n"));
1082 SK_PNMI_CNT_TX_INTR(pAC, 0);
1083 spin_lock(&pAC->TxPort[0][TX_PRIO_HIGH].TxDesRingLock);
1084 FreeTxDescriptors(pAC, 0, TX_PRIO_HIGH);
1085 spin_unlock(&pAC->TxPort[0][TX_PRIO_HIGH].TxDesRingLock);
1086 ClearTxIrq(pAC, 0, TX_PRIO_HIGH);
1087 }
1088#endif
1089#endif
1090
1091 /* do all IO at once */
1092 if (IntSrc & IS_R1_F)
1093 ClearAndStartRx(pAC, 0);
1094#ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */
1095 if (IntSrc & IS_XA1_F)
1096 ClearTxIrq(pAC, 0, TX_PRIO_LOW);
1097#endif
1098 SK_IN32(pAC->IoBase, B0_ISRC, &IntSrc);
1099 } /* while (IntSrc & IRQ_MASK != 0) */
1100
1101 IntSrc &= pAC->GIni.GIValIrqMask;
1102 if ((IntSrc & SPECIAL_IRQS) || pAC->CheckQueue) {
1103 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC,
1104 ("SPECIAL IRQ SP-Cards => %x\n", IntSrc));
1105 pAC->CheckQueue = SK_FALSE;
1106 spin_lock(&pAC->SlowPathLock);
1107 if (IntSrc & SPECIAL_IRQS)
1108 SkGeSirqIsr(pAC, pAC->IoBase, IntSrc);
1109
1110 SkEventDispatcher(pAC, pAC->IoBase);
1111 spin_unlock(&pAC->SlowPathLock);
1112 }
1113 /*
1114 * do it all again is case we cleared an interrupt that
1115 * came in after handling the ring (OUTs may be delayed
1116 * in hardware buffers, but are through after IN)
1117 *
1118 * rroesler: has been commented out and shifted to
1119 * SkGeDrvEvent(), because it is timer
1120 * guarded now
1121 *
1122 ReceiveIrq(pAC, &pAC->RxPort[0], SK_TRUE);
1123 */
1124
1125 /* IRQ is processed - Enable IRQs again*/
1126 SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask);
1127
1128 return SkIsrRetHandled;
1129} /* SkGeIsrOnePort */
1130
1131#ifdef CONFIG_NET_POLL_CONTROLLER
1132/****************************************************************************
1133 *
1134 * SkGePollController - polling receive, for netconsole
1135 *
1136 * Description:
1137 * Polling receive - used by netconsole and other diagnostic tools
1138 * to allow network i/o with interrupts disabled.
1139 *
1140 * Returns: N/A
1141 */
1142static void SkGePollController(struct net_device *dev)
1143{
1144 disable_irq(dev->irq);
1145 SkGeIsr(dev->irq, dev);
1146 enable_irq(dev->irq);
1147}
1148#endif
1149
1150/****************************************************************************
1151 *
1152 * SkGeOpen - handle start of initialized adapter
1153 *
1154 * Description:
1155 * This function starts the initialized adapter.
1156 * The board level variable is set and the adapter is
1157 * brought to full functionality.
1158 * The device flags are set for operation.
1159 * Do all necessary level 2 initialization, enable interrupts and
1160 * give start command to RLMT.
1161 *
1162 * Returns:
1163 * 0 on success
1164 * != 0 on error
1165 */
1166static int SkGeOpen(
1167struct SK_NET_DEVICE *dev)
1168{
1169 DEV_NET *pNet;
1170 SK_AC *pAC;
1171 unsigned long Flags; /* for spin lock */
1172 int i;
1173 SK_EVPARA EvPara; /* an event parameter union */
1174
1175 pNet = netdev_priv(dev);
1176 pAC = pNet->pAC;
1177
1178 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
1179 ("SkGeOpen: pAC=0x%lX:\n", (unsigned long)pAC));
1180
1181#ifdef SK_DIAG_SUPPORT
1182 if (pAC->DiagModeActive == DIAG_ACTIVE) {
1183 if (pAC->Pnmi.DiagAttached == SK_DIAG_RUNNING) {
1184 return (-1); /* still in use by diag; deny actions */
1185 }
1186 }
1187#endif
1188
1189 /* Set blink mode */
1190 if ((pAC->PciDev->vendor == 0x1186) || (pAC->PciDev->vendor == 0x11ab ))
1191 pAC->GIni.GILedBlinkCtrl = OEM_CONFIG_VALUE;
1192
1193 if (pAC->BoardLevel == SK_INIT_DATA) {
1194 /* level 1 init common modules here */
1195 if (SkGeInit(pAC, pAC->IoBase, SK_INIT_IO) != 0) {
1196 printk("%s: HWInit (1) failed.\n", pAC->dev[pNet->PortNr]->name);
1197 return (-1);
1198 }
1199 SkI2cInit (pAC, pAC->IoBase, SK_INIT_IO);
1200 SkEventInit (pAC, pAC->IoBase, SK_INIT_IO);
1201 SkPnmiInit (pAC, pAC->IoBase, SK_INIT_IO);
1202 SkAddrInit (pAC, pAC->IoBase, SK_INIT_IO);
1203 SkRlmtInit (pAC, pAC->IoBase, SK_INIT_IO);
1204 SkTimerInit (pAC, pAC->IoBase, SK_INIT_IO);
1205 pAC->BoardLevel = SK_INIT_IO;
1206 }
1207
1208 if (pAC->BoardLevel != SK_INIT_RUN) {
1209 /* tschilling: Level 2 init modules here, check return value. */
1210 if (SkGeInit(pAC, pAC->IoBase, SK_INIT_RUN) != 0) {
1211 printk("%s: HWInit (2) failed.\n", pAC->dev[pNet->PortNr]->name);
1212 return (-1);
1213 }
1214 SkI2cInit (pAC, pAC->IoBase, SK_INIT_RUN);
1215 SkEventInit (pAC, pAC->IoBase, SK_INIT_RUN);
1216 SkPnmiInit (pAC, pAC->IoBase, SK_INIT_RUN);
1217 SkAddrInit (pAC, pAC->IoBase, SK_INIT_RUN);
1218 SkRlmtInit (pAC, pAC->IoBase, SK_INIT_RUN);
1219 SkTimerInit (pAC, pAC->IoBase, SK_INIT_RUN);
1220 pAC->BoardLevel = SK_INIT_RUN;
1221 }
1222
1223 for (i=0; i<pAC->GIni.GIMacsFound; i++) {
1224 /* Enable transmit descriptor polling. */
1225 SkGePollTxD(pAC, pAC->IoBase, i, SK_TRUE);
1226 FillRxRing(pAC, &pAC->RxPort[i]);
1227 }
1228 SkGeYellowLED(pAC, pAC->IoBase, 1);
1229
1230 StartDrvCleanupTimer(pAC);
1231 SkDimEnableModerationIfNeeded(pAC);
1232 SkDimDisplayModerationSettings(pAC);
1233
1234 pAC->GIni.GIValIrqMask &= IRQ_MASK;
1235
1236 /* enable Interrupts */
1237 SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask);
1238 SK_OUT32(pAC->IoBase, B0_HWE_IMSK, IRQ_HWE_MASK);
1239
1240 spin_lock_irqsave(&pAC->SlowPathLock, Flags);
1241
1242 if ((pAC->RlmtMode != 0) && (pAC->MaxPorts == 0)) {
1243 EvPara.Para32[0] = pAC->RlmtNets;
1244 EvPara.Para32[1] = -1;
1245 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_SET_NETS,
1246 EvPara);
1247 EvPara.Para32[0] = pAC->RlmtMode;
1248 EvPara.Para32[1] = 0;
1249 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_MODE_CHANGE,
1250 EvPara);
1251 }
1252
1253 EvPara.Para32[0] = pNet->NetNr;
1254 EvPara.Para32[1] = -1;
1255 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara);
1256 SkEventDispatcher(pAC, pAC->IoBase);
1257 spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
1258
1259 pAC->MaxPorts++;
1260
1261
1262 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
1263 ("SkGeOpen suceeded\n"));
1264
1265 return (0);
1266} /* SkGeOpen */
1267
1268
1269/****************************************************************************
1270 *
1271 * SkGeClose - Stop initialized adapter
1272 *
1273 * Description:
1274 * Close initialized adapter.
1275 *
1276 * Returns:
1277 * 0 - on success
1278 * error code - on error
1279 */
1280static int SkGeClose(
1281struct SK_NET_DEVICE *dev)
1282{
1283 DEV_NET *pNet;
1284 DEV_NET *newPtrNet;
1285 SK_AC *pAC;
1286
1287 unsigned long Flags; /* for spin lock */
1288 int i;
1289 int PortIdx;
1290 SK_EVPARA EvPara;
1291
1292 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
1293 ("SkGeClose: pAC=0x%lX ", (unsigned long)pAC));
1294
1295 pNet = netdev_priv(dev);
1296 pAC = pNet->pAC;
1297
1298#ifdef SK_DIAG_SUPPORT
1299 if (pAC->DiagModeActive == DIAG_ACTIVE) {
1300 if (pAC->DiagFlowCtrl == SK_FALSE) {
1301 /*
1302 ** notify that the interface which has been closed
1303 ** by operator interaction must not be started up
1304 ** again when the DIAG has finished.
1305 */
1306 newPtrNet = netdev_priv(pAC->dev[0]);
1307 if (newPtrNet == pNet) {
1308 pAC->WasIfUp[0] = SK_FALSE;
1309 } else {
1310 pAC->WasIfUp[1] = SK_FALSE;
1311 }
1312 return 0; /* return to system everything is fine... */
1313 } else {
1314 pAC->DiagFlowCtrl = SK_FALSE;
1315 }
1316 }
1317#endif
1318
1319 netif_stop_queue(dev);
1320
1321 if (pAC->RlmtNets == 1)
1322 PortIdx = pAC->ActivePort;
1323 else
1324 PortIdx = pNet->NetNr;
1325
1326 StopDrvCleanupTimer(pAC);
1327
1328 /*
1329 * Clear multicast table, promiscuous mode ....
1330 */
1331 SkAddrMcClear(pAC, pAC->IoBase, PortIdx, 0);
1332 SkAddrPromiscuousChange(pAC, pAC->IoBase, PortIdx,
1333 SK_PROM_MODE_NONE);
1334
1335 if (pAC->MaxPorts == 1) {
1336 spin_lock_irqsave(&pAC->SlowPathLock, Flags);
1337 /* disable interrupts */
1338 SK_OUT32(pAC->IoBase, B0_IMSK, 0);
1339 EvPara.Para32[0] = pNet->NetNr;
1340 EvPara.Para32[1] = -1;
1341 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
1342 SkEventDispatcher(pAC, pAC->IoBase);
1343 SK_OUT32(pAC->IoBase, B0_IMSK, 0);
1344 /* stop the hardware */
1345 SkGeDeInit(pAC, pAC->IoBase);
1346 pAC->BoardLevel = SK_INIT_DATA;
1347 spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
1348 } else {
1349
1350 spin_lock_irqsave(&pAC->SlowPathLock, Flags);
1351 EvPara.Para32[0] = pNet->NetNr;
1352 EvPara.Para32[1] = -1;
1353 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
1354 SkPnmiEvent(pAC, pAC->IoBase, SK_PNMI_EVT_XMAC_RESET, EvPara);
1355 SkEventDispatcher(pAC, pAC->IoBase);
1356 spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
1357
1358 /* Stop port */
1359 spin_lock_irqsave(&pAC->TxPort[pNet->PortNr]
1360 [TX_PRIO_LOW].TxDesRingLock, Flags);
1361 SkGeStopPort(pAC, pAC->IoBase, pNet->PortNr,
1362 SK_STOP_ALL, SK_HARD_RST);
1363 spin_unlock_irqrestore(&pAC->TxPort[pNet->PortNr]
1364 [TX_PRIO_LOW].TxDesRingLock, Flags);
1365 }
1366
1367 if (pAC->RlmtNets == 1) {
1368 /* clear all descriptor rings */
1369 for (i=0; i<pAC->GIni.GIMacsFound; i++) {
1370 ReceiveIrq(pAC, &pAC->RxPort[i], SK_TRUE);
1371 ClearRxRing(pAC, &pAC->RxPort[i]);
1372 ClearTxRing(pAC, &pAC->TxPort[i][TX_PRIO_LOW]);
1373 }
1374 } else {
1375 /* clear port descriptor rings */
1376 ReceiveIrq(pAC, &pAC->RxPort[pNet->PortNr], SK_TRUE);
1377 ClearRxRing(pAC, &pAC->RxPort[pNet->PortNr]);
1378 ClearTxRing(pAC, &pAC->TxPort[pNet->PortNr][TX_PRIO_LOW]);
1379 }
1380
1381 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
1382 ("SkGeClose: done "));
1383
1384 SK_MEMSET(&(pAC->PnmiBackup), 0, sizeof(SK_PNMI_STRUCT_DATA));
1385 SK_MEMCPY(&(pAC->PnmiBackup), &(pAC->PnmiStruct),
1386 sizeof(SK_PNMI_STRUCT_DATA));
1387
1388 pAC->MaxPorts--;
1389
1390 return (0);
1391} /* SkGeClose */
1392
1393
1394/*****************************************************************************
1395 *
1396 * SkGeXmit - Linux frame transmit function
1397 *
1398 * Description:
1399 * The system calls this function to send frames onto the wire.
1400 * It puts the frame in the tx descriptor ring. If the ring is
1401 * full then, the 'tbusy' flag is set.
1402 *
1403 * Returns:
1404 * 0, if everything is ok
1405 * !=0, on error
1406 * WARNING: returning 1 in 'tbusy' case caused system crashes (double
1407 * allocated skb's) !!!
1408 */
1409static int SkGeXmit(struct sk_buff *skb, struct SK_NET_DEVICE *dev)
1410{
1411DEV_NET *pNet;
1412SK_AC *pAC;
1413int Rc; /* return code of XmitFrame */
1414
1415 pNet = netdev_priv(dev);
1416 pAC = pNet->pAC;
1417
1418 if ((!skb_shinfo(skb)->nr_frags) ||
1419 (pAC->GIni.GIChipId == CHIP_ID_GENESIS)) {
1420 /* Don't activate scatter-gather and hardware checksum */
1421
1422 if (pAC->RlmtNets == 2)
1423 Rc = XmitFrame(
1424 pAC,
1425 &pAC->TxPort[pNet->PortNr][TX_PRIO_LOW],
1426 skb);
1427 else
1428 Rc = XmitFrame(
1429 pAC,
1430 &pAC->TxPort[pAC->ActivePort][TX_PRIO_LOW],
1431 skb);
1432 } else {
1433 /* scatter-gather and hardware TCP checksumming anabled*/
1434 if (pAC->RlmtNets == 2)
1435 Rc = XmitFrameSG(
1436 pAC,
1437 &pAC->TxPort[pNet->PortNr][TX_PRIO_LOW],
1438 skb);
1439 else
1440 Rc = XmitFrameSG(
1441 pAC,
1442 &pAC->TxPort[pAC->ActivePort][TX_PRIO_LOW],
1443 skb);
1444 }
1445
1446 /* Transmitter out of resources? */
1447 if (Rc <= 0) {
1448 netif_stop_queue(dev);
1449 }
1450
1451 /* If not taken, give buffer ownership back to the
1452 * queueing layer.
1453 */
1454 if (Rc < 0)
1455 return (1);
1456
1457 dev->trans_start = jiffies;
1458 return (0);
1459} /* SkGeXmit */
1460
1461
1462/*****************************************************************************
1463 *
1464 * XmitFrame - fill one socket buffer into the transmit ring
1465 *
1466 * Description:
1467 * This function puts a message into the transmit descriptor ring
1468 * if there is a descriptors left.
1469 * Linux skb's consist of only one continuous buffer.
1470 * The first step locks the ring. It is held locked
1471 * all time to avoid problems with SWITCH_../PORT_RESET.
1472 * Then the descriptoris allocated.
1473 * The second part is linking the buffer to the descriptor.
1474 * At the very last, the Control field of the descriptor
1475 * is made valid for the BMU and a start TX command is given
1476 * if necessary.
1477 *
1478 * Returns:
1479 * > 0 - on succes: the number of bytes in the message
1480 * = 0 - on resource shortage: this frame sent or dropped, now
1481 * the ring is full ( -> set tbusy)
1482 * < 0 - on failure: other problems ( -> return failure to upper layers)
1483 */
1484static int XmitFrame(
1485SK_AC *pAC, /* pointer to adapter context */
1486TX_PORT *pTxPort, /* pointer to struct of port to send to */
1487struct sk_buff *pMessage) /* pointer to send-message */
1488{
1489 TXD *pTxd; /* the rxd to fill */
1490 TXD *pOldTxd;
1491 unsigned long Flags;
1492 SK_U64 PhysAddr;
1493 int BytesSend = pMessage->len;
1494
1495 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS, ("X"));
1496
1497 spin_lock_irqsave(&pTxPort->TxDesRingLock, Flags);
1498#ifndef USE_TX_COMPLETE
1499 FreeTxDescriptors(pAC, pTxPort);
1500#endif
1501 if (pTxPort->TxdRingFree == 0) {
1502 /*
1503 ** no enough free descriptors in ring at the moment.
1504 ** Maybe free'ing some old one help?
1505 */
1506 FreeTxDescriptors(pAC, pTxPort);
1507 if (pTxPort->TxdRingFree == 0) {
1508 spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags);
1509 SK_PNMI_CNT_NO_TX_BUF(pAC, pTxPort->PortIndex);
1510 SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
1511 SK_DBGCAT_DRV_TX_PROGRESS,
1512 ("XmitFrame failed\n"));
1513 /*
1514 ** the desired message can not be sent
1515 ** Because tbusy seems to be set, the message
1516 ** should not be freed here. It will be used
1517 ** by the scheduler of the ethernet handler
1518 */
1519 return (-1);
1520 }
1521 }
1522
1523 /*
1524 ** If the passed socket buffer is of smaller MTU-size than 60,
1525 ** copy everything into new buffer and fill all bytes between
1526 ** the original packet end and the new packet end of 60 with 0x00.
1527 ** This is to resolve faulty padding by the HW with 0xaa bytes.
1528 */
1529 if (BytesSend < C_LEN_ETHERNET_MINSIZE) {
1530 if (skb_padto(pMessage, C_LEN_ETHERNET_MINSIZE)) {
1531 spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags);
1532 return 0;
1533 }
1534 pMessage->len = C_LEN_ETHERNET_MINSIZE;
1535 }
1536
1537 /*
1538 ** advance head counter behind descriptor needed for this frame,
1539 ** so that needed descriptor is reserved from that on. The next
1540 ** action will be to add the passed buffer to the TX-descriptor
1541 */
1542 pTxd = pTxPort->pTxdRingHead;
1543 pTxPort->pTxdRingHead = pTxd->pNextTxd;
1544 pTxPort->TxdRingFree--;
1545
1546#ifdef SK_DUMP_TX
1547 DumpMsg(pMessage, "XmitFrame");
1548#endif
1549
1550 /*
1551 ** First step is to map the data to be sent via the adapter onto
1552 ** the DMA memory. Kernel 2.2 uses virt_to_bus(), but kernels 2.4
1553 ** and 2.6 need to use pci_map_page() for that mapping.
1554 */
1555 PhysAddr = (SK_U64) pci_map_page(pAC->PciDev,
1556 virt_to_page(pMessage->data),
1557 ((unsigned long) pMessage->data & ~PAGE_MASK),
1558 pMessage->len,
1559 PCI_DMA_TODEVICE);
1560 pTxd->VDataLow = (SK_U32) (PhysAddr & 0xffffffff);
1561 pTxd->VDataHigh = (SK_U32) (PhysAddr >> 32);
1562 pTxd->pMBuf = pMessage;
1563
1564 if (pMessage->ip_summed == CHECKSUM_PARTIAL) {
1565 u16 hdrlen = skb_transport_offset(pMessage);
1566 u16 offset = hdrlen + pMessage->csum_offset;
1567
1568 if ((ipip_hdr(pMessage)->protocol == IPPROTO_UDP) &&
1569 (pAC->GIni.GIChipRev == 0) &&
1570 (pAC->GIni.GIChipId == CHIP_ID_YUKON)) {
1571 pTxd->TBControl = BMU_TCP_CHECK;
1572 } else {
1573 pTxd->TBControl = BMU_UDP_CHECK;
1574 }
1575
1576 pTxd->TcpSumOfs = 0;
1577 pTxd->TcpSumSt = hdrlen;
1578 pTxd->TcpSumWr = offset;
1579
1580 pTxd->TBControl |= BMU_OWN | BMU_STF |
1581 BMU_SW | BMU_EOF |
1582#ifdef USE_TX_COMPLETE
1583 BMU_IRQ_EOF |
1584#endif
1585 pMessage->len;
1586 } else {
1587 pTxd->TBControl = BMU_OWN | BMU_STF | BMU_CHECK |
1588 BMU_SW | BMU_EOF |
1589#ifdef USE_TX_COMPLETE
1590 BMU_IRQ_EOF |
1591#endif
1592 pMessage->len;
1593 }
1594
1595 /*
1596 ** If previous descriptor already done, give TX start cmd
1597 */
1598 pOldTxd = xchg(&pTxPort->pTxdRingPrev, pTxd);
1599 if ((pOldTxd->TBControl & BMU_OWN) == 0) {
1600 SK_OUT8(pTxPort->HwAddr, Q_CSR, CSR_START);
1601 }
1602
1603 /*
1604 ** after releasing the lock, the skb may immediately be free'd
1605 */
1606 spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags);
1607 if (pTxPort->TxdRingFree != 0) {
1608 return (BytesSend);
1609 } else {
1610 return (0);
1611 }
1612
1613} /* XmitFrame */
1614
1615/*****************************************************************************
1616 *
1617 * XmitFrameSG - fill one socket buffer into the transmit ring
1618 * (use SG and TCP/UDP hardware checksumming)
1619 *
1620 * Description:
1621 * This function puts a message into the transmit descriptor ring
1622 * if there is a descriptors left.
1623 *
1624 * Returns:
1625 * > 0 - on succes: the number of bytes in the message
1626 * = 0 - on resource shortage: this frame sent or dropped, now
1627 * the ring is full ( -> set tbusy)
1628 * < 0 - on failure: other problems ( -> return failure to upper layers)
1629 */
1630static int XmitFrameSG(
1631SK_AC *pAC, /* pointer to adapter context */
1632TX_PORT *pTxPort, /* pointer to struct of port to send to */
1633struct sk_buff *pMessage) /* pointer to send-message */
1634{
1635
1636 TXD *pTxd;
1637 TXD *pTxdFst;
1638 TXD *pTxdLst;
1639 int CurrFrag;
1640 int BytesSend;
1641 skb_frag_t *sk_frag;
1642 SK_U64 PhysAddr;
1643 unsigned long Flags;
1644 SK_U32 Control;
1645
1646 spin_lock_irqsave(&pTxPort->TxDesRingLock, Flags);
1647#ifndef USE_TX_COMPLETE
1648 FreeTxDescriptors(pAC, pTxPort);
1649#endif
1650 if ((skb_shinfo(pMessage)->nr_frags +1) > pTxPort->TxdRingFree) {
1651 FreeTxDescriptors(pAC, pTxPort);
1652 if ((skb_shinfo(pMessage)->nr_frags + 1) > pTxPort->TxdRingFree) {
1653 spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags);
1654 SK_PNMI_CNT_NO_TX_BUF(pAC, pTxPort->PortIndex);
1655 SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
1656 SK_DBGCAT_DRV_TX_PROGRESS,
1657 ("XmitFrameSG failed - Ring full\n"));
1658 /* this message can not be sent now */
1659 return(-1);
1660 }
1661 }
1662
1663 pTxd = pTxPort->pTxdRingHead;
1664 pTxdFst = pTxd;
1665 pTxdLst = pTxd;
1666 BytesSend = 0;
1667
1668 /*
1669 ** Map the first fragment (header) into the DMA-space
1670 */
1671 PhysAddr = (SK_U64) pci_map_page(pAC->PciDev,
1672 virt_to_page(pMessage->data),
1673 ((unsigned long) pMessage->data & ~PAGE_MASK),
1674 skb_headlen(pMessage),
1675 PCI_DMA_TODEVICE);
1676
1677 pTxd->VDataLow = (SK_U32) (PhysAddr & 0xffffffff);
1678 pTxd->VDataHigh = (SK_U32) (PhysAddr >> 32);
1679
1680 /*
1681 ** Does the HW need to evaluate checksum for TCP or UDP packets?
1682 */
1683 if (pMessage->ip_summed == CHECKSUM_PARTIAL) {
1684 u16 hdrlen = skb_transport_offset(pMessage);
1685 u16 offset = hdrlen + pMessage->csum_offset;
1686
1687 Control = BMU_STFWD;
1688
1689 /*
1690 ** We have to use the opcode for tcp here, because the
1691 ** opcode for udp is not working in the hardware yet
1692 ** (Revision 2.0)
1693 */
1694 if ((ipip_hdr(pMessage)->protocol == IPPROTO_UDP) &&
1695 (pAC->GIni.GIChipRev == 0) &&
1696 (pAC->GIni.GIChipId == CHIP_ID_YUKON)) {
1697 Control |= BMU_TCP_CHECK;
1698 } else {
1699 Control |= BMU_UDP_CHECK;
1700 }
1701
1702 pTxd->TcpSumOfs = 0;
1703 pTxd->TcpSumSt = hdrlen;
1704 pTxd->TcpSumWr = offset;
1705 } else
1706 Control = BMU_CHECK | BMU_SW;
1707
1708 pTxd->TBControl = BMU_STF | Control | skb_headlen(pMessage);
1709
1710 pTxd = pTxd->pNextTxd;
1711 pTxPort->TxdRingFree--;
1712 BytesSend += skb_headlen(pMessage);
1713
1714 /*
1715 ** Browse over all SG fragments and map each of them into the DMA space
1716 */
1717 for (CurrFrag = 0; CurrFrag < skb_shinfo(pMessage)->nr_frags; CurrFrag++) {
1718 sk_frag = &skb_shinfo(pMessage)->frags[CurrFrag];
1719 /*
1720 ** we already have the proper value in entry
1721 */
1722 PhysAddr = (SK_U64) pci_map_page(pAC->PciDev,
1723 sk_frag->page,
1724 sk_frag->page_offset,
1725 sk_frag->size,
1726 PCI_DMA_TODEVICE);
1727
1728 pTxd->VDataLow = (SK_U32) (PhysAddr & 0xffffffff);
1729 pTxd->VDataHigh = (SK_U32) (PhysAddr >> 32);
1730 pTxd->pMBuf = pMessage;
1731
1732 pTxd->TBControl = Control | BMU_OWN | sk_frag->size;
1733
1734 /*
1735 ** Do we have the last fragment?
1736 */
1737 if( (CurrFrag+1) == skb_shinfo(pMessage)->nr_frags ) {
1738#ifdef USE_TX_COMPLETE
1739 pTxd->TBControl |= BMU_EOF | BMU_IRQ_EOF;
1740#else
1741 pTxd->TBControl |= BMU_EOF;
1742#endif
1743 pTxdFst->TBControl |= BMU_OWN | BMU_SW;
1744 }
1745 pTxdLst = pTxd;
1746 pTxd = pTxd->pNextTxd;
1747 pTxPort->TxdRingFree--;
1748 BytesSend += sk_frag->size;
1749 }
1750
1751 /*
1752 ** If previous descriptor already done, give TX start cmd
1753 */
1754 if ((pTxPort->pTxdRingPrev->TBControl & BMU_OWN) == 0) {
1755 SK_OUT8(pTxPort->HwAddr, Q_CSR, CSR_START);
1756 }
1757
1758 pTxPort->pTxdRingPrev = pTxdLst;
1759 pTxPort->pTxdRingHead = pTxd;
1760
1761 spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags);
1762
1763 if (pTxPort->TxdRingFree > 0) {
1764 return (BytesSend);
1765 } else {
1766 return (0);
1767 }
1768}
1769
1770/*****************************************************************************
1771 *
1772 * FreeTxDescriptors - release descriptors from the descriptor ring
1773 *
1774 * Description:
1775 * This function releases descriptors from a transmit ring if they
1776 * have been sent by the BMU.
1777 * If a descriptors is sent, it can be freed and the message can
1778 * be freed, too.
1779 * The SOFTWARE controllable bit is used to prevent running around a
1780 * completely free ring for ever. If this bit is no set in the
1781 * frame (by XmitFrame), this frame has never been sent or is
1782 * already freed.
1783 * The Tx descriptor ring lock must be held while calling this function !!!
1784 *
1785 * Returns:
1786 * none
1787 */
1788static void FreeTxDescriptors(
1789SK_AC *pAC, /* pointer to the adapter context */
1790TX_PORT *pTxPort) /* pointer to destination port structure */
1791{
1792TXD *pTxd; /* pointer to the checked descriptor */
1793TXD *pNewTail; /* pointer to 'end' of the ring */
1794SK_U32 Control; /* TBControl field of descriptor */
1795SK_U64 PhysAddr; /* address of DMA mapping */
1796
1797 pNewTail = pTxPort->pTxdRingTail;
1798 pTxd = pNewTail;
1799 /*
1800 ** loop forever; exits if BMU_SW bit not set in start frame
1801 ** or BMU_OWN bit set in any frame
1802 */
1803 while (1) {
1804 Control = pTxd->TBControl;
1805 if ((Control & BMU_SW) == 0) {
1806 /*
1807 ** software controllable bit is set in first
1808 ** fragment when given to BMU. Not set means that
1809 ** this fragment was never sent or is already
1810 ** freed ( -> ring completely free now).
1811 */
1812 pTxPort->pTxdRingTail = pTxd;
1813 netif_wake_queue(pAC->dev[pTxPort->PortIndex]);
1814 return;
1815 }
1816 if (Control & BMU_OWN) {
1817 pTxPort->pTxdRingTail = pTxd;
1818 if (pTxPort->TxdRingFree > 0) {
1819 netif_wake_queue(pAC->dev[pTxPort->PortIndex]);
1820 }
1821 return;
1822 }
1823
1824 /*
1825 ** release the DMA mapping, because until not unmapped
1826 ** this buffer is considered being under control of the
1827 ** adapter card!
1828 */
1829 PhysAddr = ((SK_U64) pTxd->VDataHigh) << (SK_U64) 32;
1830 PhysAddr |= (SK_U64) pTxd->VDataLow;
1831 pci_unmap_page(pAC->PciDev, PhysAddr,
1832 pTxd->pMBuf->len,
1833 PCI_DMA_TODEVICE);
1834
1835 if (Control & BMU_EOF)
1836 DEV_KFREE_SKB_ANY(pTxd->pMBuf); /* free message */
1837
1838 pTxPort->TxdRingFree++;
1839 pTxd->TBControl &= ~BMU_SW;
1840 pTxd = pTxd->pNextTxd; /* point behind fragment with EOF */
1841 } /* while(forever) */
1842} /* FreeTxDescriptors */
1843
1844/*****************************************************************************
1845 *
1846 * FillRxRing - fill the receive ring with valid descriptors
1847 *
1848 * Description:
1849 * This function fills the receive ring descriptors with data
1850 * segments and makes them valid for the BMU.
1851 * The active ring is filled completely, if possible.
1852 * The non-active ring is filled only partial to save memory.
1853 *
1854 * Description of rx ring structure:
1855 * head - points to the descriptor which will be used next by the BMU
1856 * tail - points to the next descriptor to give to the BMU
1857 *
1858 * Returns: N/A
1859 */
1860static void FillRxRing(
1861SK_AC *pAC, /* pointer to the adapter context */
1862RX_PORT *pRxPort) /* ptr to port struct for which the ring
1863 should be filled */
1864{
1865unsigned long Flags;
1866
1867 spin_lock_irqsave(&pRxPort->RxDesRingLock, Flags);
1868 while (pRxPort->RxdRingFree > pRxPort->RxFillLimit) {
1869 if(!FillRxDescriptor(pAC, pRxPort))
1870 break;
1871 }
1872 spin_unlock_irqrestore(&pRxPort->RxDesRingLock, Flags);
1873} /* FillRxRing */
1874
1875
1876/*****************************************************************************
1877 *
1878 * FillRxDescriptor - fill one buffer into the receive ring
1879 *
1880 * Description:
1881 * The function allocates a new receive buffer and
1882 * puts it into the next descriptor.
1883 *
1884 * Returns:
1885 * SK_TRUE - a buffer was added to the ring
1886 * SK_FALSE - a buffer could not be added
1887 */
1888static SK_BOOL FillRxDescriptor(
1889SK_AC *pAC, /* pointer to the adapter context struct */
1890RX_PORT *pRxPort) /* ptr to port struct of ring to fill */
1891{
1892struct sk_buff *pMsgBlock; /* pointer to a new message block */
1893RXD *pRxd; /* the rxd to fill */
1894SK_U16 Length; /* data fragment length */
1895SK_U64 PhysAddr; /* physical address of a rx buffer */
1896
1897 pMsgBlock = alloc_skb(pAC->RxBufSize, GFP_ATOMIC);
1898 if (pMsgBlock == NULL) {
1899 SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
1900 SK_DBGCAT_DRV_ENTRY,
1901 ("%s: Allocation of rx buffer failed !\n",
1902 pAC->dev[pRxPort->PortIndex]->name));
1903 SK_PNMI_CNT_NO_RX_BUF(pAC, pRxPort->PortIndex);
1904 return(SK_FALSE);
1905 }
1906 skb_reserve(pMsgBlock, 2); /* to align IP frames */
1907 /* skb allocated ok, so add buffer */
1908 pRxd = pRxPort->pRxdRingTail;
1909 pRxPort->pRxdRingTail = pRxd->pNextRxd;
1910 pRxPort->RxdRingFree--;
1911 Length = pAC->RxBufSize;
1912 PhysAddr = (SK_U64) pci_map_page(pAC->PciDev,
1913 virt_to_page(pMsgBlock->data),
1914 ((unsigned long) pMsgBlock->data &
1915 ~PAGE_MASK),
1916 pAC->RxBufSize - 2,
1917 PCI_DMA_FROMDEVICE);
1918
1919 pRxd->VDataLow = (SK_U32) (PhysAddr & 0xffffffff);
1920 pRxd->VDataHigh = (SK_U32) (PhysAddr >> 32);
1921 pRxd->pMBuf = pMsgBlock;
1922 pRxd->RBControl = BMU_OWN |
1923 BMU_STF |
1924 BMU_IRQ_EOF |
1925 BMU_TCP_CHECK |
1926 Length;
1927 return (SK_TRUE);
1928
1929} /* FillRxDescriptor */
1930
1931
1932/*****************************************************************************
1933 *
1934 * ReQueueRxBuffer - fill one buffer back into the receive ring
1935 *
1936 * Description:
1937 * Fill a given buffer back into the rx ring. The buffer
1938 * has been previously allocated and aligned, and its phys.
1939 * address calculated, so this is no more necessary.
1940 *
1941 * Returns: N/A
1942 */
1943static void ReQueueRxBuffer(
1944SK_AC *pAC, /* pointer to the adapter context struct */
1945RX_PORT *pRxPort, /* ptr to port struct of ring to fill */
1946struct sk_buff *pMsg, /* pointer to the buffer */
1947SK_U32 PhysHigh, /* phys address high dword */
1948SK_U32 PhysLow) /* phys address low dword */
1949{
1950RXD *pRxd; /* the rxd to fill */
1951SK_U16 Length; /* data fragment length */
1952
1953 pRxd = pRxPort->pRxdRingTail;
1954 pRxPort->pRxdRingTail = pRxd->pNextRxd;
1955 pRxPort->RxdRingFree--;
1956 Length = pAC->RxBufSize;
1957
1958 pRxd->VDataLow = PhysLow;
1959 pRxd->VDataHigh = PhysHigh;
1960 pRxd->pMBuf = pMsg;
1961 pRxd->RBControl = BMU_OWN |
1962 BMU_STF |
1963 BMU_IRQ_EOF |
1964 BMU_TCP_CHECK |
1965 Length;
1966 return;
1967} /* ReQueueRxBuffer */
1968
1969/*****************************************************************************
1970 *
1971 * ReceiveIrq - handle a receive IRQ
1972 *
1973 * Description:
1974 * This function is called when a receive IRQ is set.
1975 * It walks the receive descriptor ring and sends up all
1976 * frames that are complete.
1977 *
1978 * Returns: N/A
1979 */
1980static void ReceiveIrq(
1981 SK_AC *pAC, /* pointer to adapter context */
1982 RX_PORT *pRxPort, /* pointer to receive port struct */
1983 SK_BOOL SlowPathLock) /* indicates if SlowPathLock is needed */
1984{
1985RXD *pRxd; /* pointer to receive descriptors */
1986SK_U32 Control; /* control field of descriptor */
1987struct sk_buff *pMsg; /* pointer to message holding frame */
1988struct sk_buff *pNewMsg; /* pointer to a new message for copying frame */
1989int FrameLength; /* total length of received frame */
1990SK_MBUF *pRlmtMbuf; /* ptr to a buffer for giving a frame to rlmt */
1991SK_EVPARA EvPara; /* an event parameter union */
1992unsigned long Flags; /* for spin lock */
1993int PortIndex = pRxPort->PortIndex;
1994unsigned int Offset;
1995unsigned int NumBytes;
1996unsigned int ForRlmt;
1997SK_BOOL IsBc;
1998SK_BOOL IsMc;
1999SK_BOOL IsBadFrame; /* Bad frame */
2000
2001SK_U32 FrameStat;
2002SK_U64 PhysAddr;
2003
2004rx_start:
2005 /* do forever; exit if BMU_OWN found */
2006 for ( pRxd = pRxPort->pRxdRingHead ;
2007 pRxPort->RxdRingFree < pAC->RxDescrPerRing ;
2008 pRxd = pRxd->pNextRxd,
2009 pRxPort->pRxdRingHead = pRxd,
2010 pRxPort->RxdRingFree ++) {
2011
2012 /*
2013 * For a better understanding of this loop
2014 * Go through every descriptor beginning at the head
2015 * Please note: the ring might be completely received so the OWN bit
2016 * set is not a good crirteria to leave that loop.
2017 * Therefore the RingFree counter is used.
2018 * On entry of this loop pRxd is a pointer to the Rxd that needs
2019 * to be checked next.
2020 */
2021
2022 Control = pRxd->RBControl;
2023
2024 /* check if this descriptor is ready */
2025 if ((Control & BMU_OWN) != 0) {
2026 /* this descriptor is not yet ready */
2027 /* This is the usual end of the loop */
2028 /* We don't need to start the ring again */
2029 FillRxRing(pAC, pRxPort);
2030 return;
2031 }
2032 pAC->DynIrqModInfo.NbrProcessedDescr++;
2033
2034 /* get length of frame and check it */
2035 FrameLength = Control & BMU_BBC;
2036 if (FrameLength > pAC->RxBufSize) {
2037 goto rx_failed;
2038 }
2039
2040 /* check for STF and EOF */
2041 if ((Control & (BMU_STF | BMU_EOF)) != (BMU_STF | BMU_EOF)) {
2042 goto rx_failed;
2043 }
2044
2045 /* here we have a complete frame in the ring */
2046 pMsg = pRxd->pMBuf;
2047
2048 FrameStat = pRxd->FrameStat;
2049
2050 /* check for frame length mismatch */
2051#define XMR_FS_LEN_SHIFT 18
2052#define GMR_FS_LEN_SHIFT 16
2053 if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) {
2054 if (FrameLength != (SK_U32) (FrameStat >> XMR_FS_LEN_SHIFT)) {
2055 SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
2056 SK_DBGCAT_DRV_RX_PROGRESS,
2057 ("skge: Frame length mismatch (%u/%u).\n",
2058 FrameLength,
2059 (SK_U32) (FrameStat >> XMR_FS_LEN_SHIFT)));
2060 goto rx_failed;
2061 }
2062 }
2063 else {
2064 if (FrameLength != (SK_U32) (FrameStat >> GMR_FS_LEN_SHIFT)) {
2065 SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
2066 SK_DBGCAT_DRV_RX_PROGRESS,
2067 ("skge: Frame length mismatch (%u/%u).\n",
2068 FrameLength,
2069 (SK_U32) (FrameStat >> XMR_FS_LEN_SHIFT)));
2070 goto rx_failed;
2071 }
2072 }
2073
2074 /* Set Rx Status */
2075 if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) {
2076 IsBc = (FrameStat & XMR_FS_BC) != 0;
2077 IsMc = (FrameStat & XMR_FS_MC) != 0;
2078 IsBadFrame = (FrameStat &
2079 (XMR_FS_ANY_ERR | XMR_FS_2L_VLAN)) != 0;
2080 } else {
2081 IsBc = (FrameStat & GMR_FS_BC) != 0;
2082 IsMc = (FrameStat & GMR_FS_MC) != 0;
2083 IsBadFrame = (((FrameStat & GMR_FS_ANY_ERR) != 0) ||
2084 ((FrameStat & GMR_FS_RX_OK) == 0));
2085 }
2086
2087 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 0,
2088 ("Received frame of length %d on port %d\n",
2089 FrameLength, PortIndex));
2090 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 0,
2091 ("Number of free rx descriptors: %d\n",
2092 pRxPort->RxdRingFree));
2093/* DumpMsg(pMsg, "Rx"); */
2094
2095 if ((Control & BMU_STAT_VAL) != BMU_STAT_VAL || (IsBadFrame)) {
2096#if 0
2097 (FrameStat & (XMR_FS_ANY_ERR | XMR_FS_2L_VLAN)) != 0) {
2098#endif
2099 /* there is a receive error in this frame */
2100 SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
2101 SK_DBGCAT_DRV_RX_PROGRESS,
2102 ("skge: Error in received frame, dropped!\n"
2103 "Control: %x\nRxStat: %x\n",
2104 Control, FrameStat));
2105
2106 ReQueueRxBuffer(pAC, pRxPort, pMsg,
2107 pRxd->VDataHigh, pRxd->VDataLow);
2108
2109 continue;
2110 }
2111
2112 /*
2113 * if short frame then copy data to reduce memory waste
2114 */
2115 if ((FrameLength < SK_COPY_THRESHOLD) &&
2116 ((pNewMsg = alloc_skb(FrameLength+2, GFP_ATOMIC)) != NULL)) {
2117 /*
2118 * Short frame detected and allocation successfull
2119 */
2120 /* use new skb and copy data */
2121 skb_reserve(pNewMsg, 2);
2122 skb_put(pNewMsg, FrameLength);
2123 PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32;
2124 PhysAddr |= (SK_U64) pRxd->VDataLow;
2125
2126 pci_dma_sync_single_for_cpu(pAC->PciDev,
2127 (dma_addr_t) PhysAddr,
2128 FrameLength,
2129 PCI_DMA_FROMDEVICE);
2130 skb_copy_to_linear_data(pNewMsg, pMsg, FrameLength);
2131
2132 pci_dma_sync_single_for_device(pAC->PciDev,
2133 (dma_addr_t) PhysAddr,
2134 FrameLength,
2135 PCI_DMA_FROMDEVICE);
2136 ReQueueRxBuffer(pAC, pRxPort, pMsg,
2137 pRxd->VDataHigh, pRxd->VDataLow);
2138
2139 pMsg = pNewMsg;
2140
2141 }
2142 else {
2143 /*
2144 * if large frame, or SKB allocation failed, pass
2145 * the SKB directly to the networking
2146 */
2147
2148 PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32;
2149 PhysAddr |= (SK_U64) pRxd->VDataLow;
2150
2151 /* release the DMA mapping */
2152 pci_unmap_single(pAC->PciDev,
2153 PhysAddr,
2154 pAC->RxBufSize - 2,
2155 PCI_DMA_FROMDEVICE);
2156
2157 /* set length in message */
2158 skb_put(pMsg, FrameLength);
2159 } /* frame > SK_COPY_TRESHOLD */
2160
2161#ifdef USE_SK_RX_CHECKSUM
2162 pMsg->csum = pRxd->TcpSums & 0xffff;
2163 pMsg->ip_summed = CHECKSUM_COMPLETE;
2164#else
2165 pMsg->ip_summed = CHECKSUM_NONE;
2166#endif
2167
2168 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 1,("V"));
2169 ForRlmt = SK_RLMT_RX_PROTOCOL;
2170#if 0
2171 IsBc = (FrameStat & XMR_FS_BC)==XMR_FS_BC;
2172#endif
2173 SK_RLMT_PRE_LOOKAHEAD(pAC, PortIndex, FrameLength,
2174 IsBc, &Offset, &NumBytes);
2175 if (NumBytes != 0) {
2176#if 0
2177 IsMc = (FrameStat & XMR_FS_MC)==XMR_FS_MC;
2178#endif
2179 SK_RLMT_LOOKAHEAD(pAC, PortIndex,
2180 &pMsg->data[Offset],
2181 IsBc, IsMc, &ForRlmt);
2182 }
2183 if (ForRlmt == SK_RLMT_RX_PROTOCOL) {
2184 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 1,("W"));
2185 /* send up only frames from active port */
2186 if ((PortIndex == pAC->ActivePort) ||
2187 (pAC->RlmtNets == 2)) {
2188 /* frame for upper layer */
2189 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 1,("U"));
2190#ifdef xDEBUG
2191 DumpMsg(pMsg, "Rx");
2192#endif
2193 SK_PNMI_CNT_RX_OCTETS_DELIVERED(pAC,
2194 FrameLength, pRxPort->PortIndex);
2195
2196 pMsg->protocol = eth_type_trans(pMsg,
2197 pAC->dev[pRxPort->PortIndex]);
2198 netif_rx(pMsg);
2199 pAC->dev[pRxPort->PortIndex]->last_rx = jiffies;
2200 }
2201 else {
2202 /* drop frame */
2203 SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
2204 SK_DBGCAT_DRV_RX_PROGRESS,
2205 ("D"));
2206 DEV_KFREE_SKB(pMsg);
2207 }
2208
2209 } /* if not for rlmt */
2210 else {
2211 /* packet for rlmt */
2212 SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
2213 SK_DBGCAT_DRV_RX_PROGRESS, ("R"));
2214 pRlmtMbuf = SkDrvAllocRlmtMbuf(pAC,
2215 pAC->IoBase, FrameLength);
2216 if (pRlmtMbuf != NULL) {
2217 pRlmtMbuf->pNext = NULL;
2218 pRlmtMbuf->Length = FrameLength;
2219 pRlmtMbuf->PortIdx = PortIndex;
2220 EvPara.pParaPtr = pRlmtMbuf;
2221 memcpy((char*)(pRlmtMbuf->pData),
2222 (char*)(pMsg->data),
2223 FrameLength);
2224
2225 /* SlowPathLock needed? */
2226 if (SlowPathLock == SK_TRUE) {
2227 spin_lock_irqsave(&pAC->SlowPathLock, Flags);
2228 SkEventQueue(pAC, SKGE_RLMT,
2229 SK_RLMT_PACKET_RECEIVED,
2230 EvPara);
2231 pAC->CheckQueue = SK_TRUE;
2232 spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
2233 } else {
2234 SkEventQueue(pAC, SKGE_RLMT,
2235 SK_RLMT_PACKET_RECEIVED,
2236 EvPara);
2237 pAC->CheckQueue = SK_TRUE;
2238 }
2239
2240 SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
2241 SK_DBGCAT_DRV_RX_PROGRESS,
2242 ("Q"));
2243 }
2244 if ((pAC->dev[pRxPort->PortIndex]->flags &
2245 (IFF_PROMISC | IFF_ALLMULTI)) != 0 ||
2246 (ForRlmt & SK_RLMT_RX_PROTOCOL) ==
2247 SK_RLMT_RX_PROTOCOL) {
2248 pMsg->protocol = eth_type_trans(pMsg,
2249 pAC->dev[pRxPort->PortIndex]);
2250 netif_rx(pMsg);
2251 pAC->dev[pRxPort->PortIndex]->last_rx = jiffies;
2252 }
2253 else {
2254 DEV_KFREE_SKB(pMsg);
2255 }
2256
2257 } /* if packet for rlmt */
2258 } /* for ... scanning the RXD ring */
2259
2260 /* RXD ring is empty -> fill and restart */
2261 FillRxRing(pAC, pRxPort);
2262 /* do not start if called from Close */
2263 if (pAC->BoardLevel > SK_INIT_DATA) {
2264 ClearAndStartRx(pAC, PortIndex);
2265 }
2266 return;
2267
2268rx_failed:
2269 /* remove error frame */
2270 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ERROR,
2271 ("Schrottdescriptor, length: 0x%x\n", FrameLength));
2272
2273 /* release the DMA mapping */
2274
2275 PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32;
2276 PhysAddr |= (SK_U64) pRxd->VDataLow;
2277 pci_unmap_page(pAC->PciDev,
2278 PhysAddr,
2279 pAC->RxBufSize - 2,
2280 PCI_DMA_FROMDEVICE);
2281 DEV_KFREE_SKB_IRQ(pRxd->pMBuf);
2282 pRxd->pMBuf = NULL;
2283 pRxPort->RxdRingFree++;
2284 pRxPort->pRxdRingHead = pRxd->pNextRxd;
2285 goto rx_start;
2286
2287} /* ReceiveIrq */
2288
2289
2290/*****************************************************************************
2291 *
2292 * ClearAndStartRx - give a start receive command to BMU, clear IRQ
2293 *
2294 * Description:
2295 * This function sends a start command and a clear interrupt
2296 * command for one receive queue to the BMU.
2297 *
2298 * Returns: N/A
2299 * none
2300 */
2301static void ClearAndStartRx(
2302SK_AC *pAC, /* pointer to the adapter context */
2303int PortIndex) /* index of the receive port (XMAC) */
2304{
2305 SK_OUT8(pAC->IoBase,
2306 RxQueueAddr[PortIndex]+Q_CSR,
2307 CSR_START | CSR_IRQ_CL_F);
2308} /* ClearAndStartRx */
2309
2310
2311/*****************************************************************************
2312 *
2313 * ClearTxIrq - give a clear transmit IRQ command to BMU
2314 *
2315 * Description:
2316 * This function sends a clear tx IRQ command for one
2317 * transmit queue to the BMU.
2318 *
2319 * Returns: N/A
2320 */
2321static void ClearTxIrq(
2322SK_AC *pAC, /* pointer to the adapter context */
2323int PortIndex, /* index of the transmit port (XMAC) */
2324int Prio) /* priority or normal queue */
2325{
2326 SK_OUT8(pAC->IoBase,
2327 TxQueueAddr[PortIndex][Prio]+Q_CSR,
2328 CSR_IRQ_CL_F);
2329} /* ClearTxIrq */
2330
2331
2332/*****************************************************************************
2333 *
2334 * ClearRxRing - remove all buffers from the receive ring
2335 *
2336 * Description:
2337 * This function removes all receive buffers from the ring.
2338 * The receive BMU must be stopped before calling this function.
2339 *
2340 * Returns: N/A
2341 */
2342static void ClearRxRing(
2343SK_AC *pAC, /* pointer to adapter context */
2344RX_PORT *pRxPort) /* pointer to rx port struct */
2345{
2346RXD *pRxd; /* pointer to the current descriptor */
2347unsigned long Flags;
2348SK_U64 PhysAddr;
2349
2350 if (pRxPort->RxdRingFree == pAC->RxDescrPerRing) {
2351 return;
2352 }
2353 spin_lock_irqsave(&pRxPort->RxDesRingLock, Flags);
2354 pRxd = pRxPort->pRxdRingHead;
2355 do {
2356 if (pRxd->pMBuf != NULL) {
2357
2358 PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32;
2359 PhysAddr |= (SK_U64) pRxd->VDataLow;
2360 pci_unmap_page(pAC->PciDev,
2361 PhysAddr,
2362 pAC->RxBufSize - 2,
2363 PCI_DMA_FROMDEVICE);
2364 DEV_KFREE_SKB(pRxd->pMBuf);
2365 pRxd->pMBuf = NULL;
2366 }
2367 pRxd->RBControl &= BMU_OWN;
2368 pRxd = pRxd->pNextRxd;
2369 pRxPort->RxdRingFree++;
2370 } while (pRxd != pRxPort->pRxdRingTail);
2371 pRxPort->pRxdRingTail = pRxPort->pRxdRingHead;
2372 spin_unlock_irqrestore(&pRxPort->RxDesRingLock, Flags);
2373} /* ClearRxRing */
2374
2375/*****************************************************************************
2376 *
2377 * ClearTxRing - remove all buffers from the transmit ring
2378 *
2379 * Description:
2380 * This function removes all transmit buffers from the ring.
2381 * The transmit BMU must be stopped before calling this function
2382 * and transmitting at the upper level must be disabled.
2383 * The BMU own bit of all descriptors is cleared, the rest is
2384 * done by calling FreeTxDescriptors.
2385 *
2386 * Returns: N/A
2387 */
2388static void ClearTxRing(
2389SK_AC *pAC, /* pointer to adapter context */
2390TX_PORT *pTxPort) /* pointer to tx prt struct */
2391{
2392TXD *pTxd; /* pointer to the current descriptor */
2393int i;
2394unsigned long Flags;
2395
2396 spin_lock_irqsave(&pTxPort->TxDesRingLock, Flags);
2397 pTxd = pTxPort->pTxdRingHead;
2398 for (i=0; i<pAC->TxDescrPerRing; i++) {
2399 pTxd->TBControl &= ~BMU_OWN;
2400 pTxd = pTxd->pNextTxd;
2401 }
2402 FreeTxDescriptors(pAC, pTxPort);
2403 spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags);
2404} /* ClearTxRing */
2405
2406/*****************************************************************************
2407 *
2408 * SkGeSetMacAddr - Set the hardware MAC address
2409 *
2410 * Description:
2411 * This function sets the MAC address used by the adapter.
2412 *
2413 * Returns:
2414 * 0, if everything is ok
2415 * !=0, on error
2416 */
2417static int SkGeSetMacAddr(struct SK_NET_DEVICE *dev, void *p)
2418{
2419
2420DEV_NET *pNet = netdev_priv(dev);
2421SK_AC *pAC = pNet->pAC;
2422
2423struct sockaddr *addr = p;
2424unsigned long Flags;
2425
2426 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
2427 ("SkGeSetMacAddr starts now...\n"));
2428 if(netif_running(dev))
2429 return -EBUSY;
2430
2431 memcpy(dev->dev_addr, addr->sa_data,dev->addr_len);
2432
2433 spin_lock_irqsave(&pAC->SlowPathLock, Flags);
2434
2435 if (pAC->RlmtNets == 2)
2436 SkAddrOverride(pAC, pAC->IoBase, pNet->NetNr,
2437 (SK_MAC_ADDR*)dev->dev_addr, SK_ADDR_VIRTUAL_ADDRESS);
2438 else
2439 SkAddrOverride(pAC, pAC->IoBase, pAC->ActivePort,
2440 (SK_MAC_ADDR*)dev->dev_addr, SK_ADDR_VIRTUAL_ADDRESS);
2441
2442
2443
2444 spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
2445 return 0;
2446} /* SkGeSetMacAddr */
2447
2448
2449/*****************************************************************************
2450 *
2451 * SkGeSetRxMode - set receive mode
2452 *
2453 * Description:
2454 * This function sets the receive mode of an adapter. The adapter
2455 * supports promiscuous mode, allmulticast mode and a number of
2456 * multicast addresses. If more multicast addresses the available
2457 * are selected, a hash function in the hardware is used.
2458 *
2459 * Returns:
2460 * 0, if everything is ok
2461 * !=0, on error
2462 */
2463static void SkGeSetRxMode(struct SK_NET_DEVICE *dev)
2464{
2465
2466DEV_NET *pNet;
2467SK_AC *pAC;
2468
2469struct dev_mc_list *pMcList;
2470int i;
2471int PortIdx;
2472unsigned long Flags;
2473
2474 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
2475 ("SkGeSetRxMode starts now... "));
2476
2477 pNet = netdev_priv(dev);
2478 pAC = pNet->pAC;
2479 if (pAC->RlmtNets == 1)
2480 PortIdx = pAC->ActivePort;
2481 else
2482 PortIdx = pNet->NetNr;
2483
2484 spin_lock_irqsave(&pAC->SlowPathLock, Flags);
2485 if (dev->flags & IFF_PROMISC) {
2486 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
2487 ("PROMISCUOUS mode\n"));
2488 SkAddrPromiscuousChange(pAC, pAC->IoBase, PortIdx,
2489 SK_PROM_MODE_LLC);
2490 } else if (dev->flags & IFF_ALLMULTI) {
2491 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
2492 ("ALLMULTI mode\n"));
2493 SkAddrPromiscuousChange(pAC, pAC->IoBase, PortIdx,
2494 SK_PROM_MODE_ALL_MC);
2495 } else {
2496 SkAddrPromiscuousChange(pAC, pAC->IoBase, PortIdx,
2497 SK_PROM_MODE_NONE);
2498 SkAddrMcClear(pAC, pAC->IoBase, PortIdx, 0);
2499
2500 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
2501 ("Number of MC entries: %d ", dev->mc_count));
2502
2503 pMcList = dev->mc_list;
2504 for (i=0; i<dev->mc_count; i++, pMcList = pMcList->next) {
2505 SkAddrMcAdd(pAC, pAC->IoBase, PortIdx,
2506 (SK_MAC_ADDR*)pMcList->dmi_addr, 0);
2507 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MCA,
2508 ("%02x:%02x:%02x:%02x:%02x:%02x\n",
2509 pMcList->dmi_addr[0],
2510 pMcList->dmi_addr[1],
2511 pMcList->dmi_addr[2],
2512 pMcList->dmi_addr[3],
2513 pMcList->dmi_addr[4],
2514 pMcList->dmi_addr[5]));
2515 }
2516 SkAddrMcUpdate(pAC, pAC->IoBase, PortIdx);
2517 }
2518 spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
2519
2520 return;
2521} /* SkGeSetRxMode */
2522
2523
2524/*****************************************************************************
2525 *
2526 * SkGeChangeMtu - set the MTU to another value
2527 *
2528 * Description:
2529 * This function sets is called whenever the MTU size is changed
2530 * (ifconfig mtu xxx dev ethX). If the MTU is bigger than standard
2531 * ethernet MTU size, long frame support is activated.
2532 *
2533 * Returns:
2534 * 0, if everything is ok
2535 * !=0, on error
2536 */
2537static int SkGeChangeMtu(struct SK_NET_DEVICE *dev, int NewMtu)
2538{
2539DEV_NET *pNet;
2540struct net_device *pOtherDev;
2541SK_AC *pAC;
2542unsigned long Flags;
2543int i;
2544SK_EVPARA EvPara;
2545
2546 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
2547 ("SkGeChangeMtu starts now...\n"));
2548
2549 pNet = netdev_priv(dev);
2550 pAC = pNet->pAC;
2551
2552 if ((NewMtu < 68) || (NewMtu > SK_JUMBO_MTU)) {
2553 return -EINVAL;
2554 }
2555
2556 if(pAC->BoardLevel != SK_INIT_RUN) {
2557 return -EINVAL;
2558 }
2559
2560#ifdef SK_DIAG_SUPPORT
2561 if (pAC->DiagModeActive == DIAG_ACTIVE) {
2562 if (pAC->DiagFlowCtrl == SK_FALSE) {
2563 return -1; /* still in use, deny any actions of MTU */
2564 } else {
2565 pAC->DiagFlowCtrl = SK_FALSE;
2566 }
2567 }
2568#endif
2569
2570 pOtherDev = pAC->dev[1 - pNet->NetNr];
2571
2572 if ( netif_running(pOtherDev) && (pOtherDev->mtu > 1500)
2573 && (NewMtu <= 1500))
2574 return 0;
2575
2576 pAC->RxBufSize = NewMtu + 32;
2577 dev->mtu = NewMtu;
2578
2579 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
2580 ("New MTU: %d\n", NewMtu));
2581
2582 /*
2583 ** Prevent any reconfiguration while changing the MTU
2584 ** by disabling any interrupts
2585 */
2586 SK_OUT32(pAC->IoBase, B0_IMSK, 0);
2587 spin_lock_irqsave(&pAC->SlowPathLock, Flags);
2588
2589 /*
2590 ** Notify RLMT that any ports are to be stopped
2591 */
2592 EvPara.Para32[0] = 0;
2593 EvPara.Para32[1] = -1;
2594 if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) {
2595 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
2596 EvPara.Para32[0] = 1;
2597 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
2598 } else {
2599 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
2600 }
2601
2602 /*
2603 ** After calling the SkEventDispatcher(), RLMT is aware about
2604 ** the stopped ports -> configuration can take place!
2605 */
2606 SkEventDispatcher(pAC, pAC->IoBase);
2607
2608 for (i=0; i<pAC->GIni.GIMacsFound; i++) {
2609 spin_lock(&pAC->TxPort[i][TX_PRIO_LOW].TxDesRingLock);
2610 netif_stop_queue(pAC->dev[i]);
2611
2612 }
2613
2614 /*
2615 ** Depending on the desired MTU size change, a different number of
2616 ** RX buffers need to be allocated
2617 */
2618 if (NewMtu > 1500) {
2619 /*
2620 ** Use less rx buffers
2621 */
2622 for (i=0; i<pAC->GIni.GIMacsFound; i++) {
2623 if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) {
2624 pAC->RxPort[i].RxFillLimit = pAC->RxDescrPerRing -
2625 (pAC->RxDescrPerRing / 4);
2626 } else {
2627 if (i == pAC->ActivePort) {
2628 pAC->RxPort[i].RxFillLimit = pAC->RxDescrPerRing -
2629 (pAC->RxDescrPerRing / 4);
2630 } else {
2631 pAC->RxPort[i].RxFillLimit = pAC->RxDescrPerRing -
2632 (pAC->RxDescrPerRing / 10);
2633 }
2634 }
2635 }
2636 } else {
2637 /*
2638 ** Use the normal amount of rx buffers
2639 */
2640 for (i=0; i<pAC->GIni.GIMacsFound; i++) {
2641 if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) {
2642 pAC->RxPort[i].RxFillLimit = 1;
2643 } else {
2644 if (i == pAC->ActivePort) {
2645 pAC->RxPort[i].RxFillLimit = 1;
2646 } else {
2647 pAC->RxPort[i].RxFillLimit = pAC->RxDescrPerRing -
2648 (pAC->RxDescrPerRing / 4);
2649 }
2650 }
2651 }
2652 }
2653
2654 SkGeDeInit(pAC, pAC->IoBase);
2655
2656 /*
2657 ** enable/disable hardware support for long frames
2658 */
2659 if (NewMtu > 1500) {
2660// pAC->JumboActivated = SK_TRUE; /* is never set back !!! */
2661 pAC->GIni.GIPortUsage = SK_JUMBO_LINK;
2662 } else {
2663 if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) {
2664 pAC->GIni.GIPortUsage = SK_MUL_LINK;
2665 } else {
2666 pAC->GIni.GIPortUsage = SK_RED_LINK;
2667 }
2668 }
2669
2670 SkGeInit( pAC, pAC->IoBase, SK_INIT_IO);
2671 SkI2cInit( pAC, pAC->IoBase, SK_INIT_IO);
2672 SkEventInit(pAC, pAC->IoBase, SK_INIT_IO);
2673 SkPnmiInit( pAC, pAC->IoBase, SK_INIT_IO);
2674 SkAddrInit( pAC, pAC->IoBase, SK_INIT_IO);
2675 SkRlmtInit( pAC, pAC->IoBase, SK_INIT_IO);
2676 SkTimerInit(pAC, pAC->IoBase, SK_INIT_IO);
2677
2678 /*
2679 ** tschilling:
2680 ** Speed and others are set back to default in level 1 init!
2681 */
2682 GetConfiguration(pAC);
2683
2684 SkGeInit( pAC, pAC->IoBase, SK_INIT_RUN);
2685 SkI2cInit( pAC, pAC->IoBase, SK_INIT_RUN);
2686 SkEventInit(pAC, pAC->IoBase, SK_INIT_RUN);
2687 SkPnmiInit( pAC, pAC->IoBase, SK_INIT_RUN);
2688 SkAddrInit( pAC, pAC->IoBase, SK_INIT_RUN);
2689 SkRlmtInit( pAC, pAC->IoBase, SK_INIT_RUN);
2690 SkTimerInit(pAC, pAC->IoBase, SK_INIT_RUN);
2691
2692 /*
2693 ** clear and reinit the rx rings here
2694 */
2695 for (i=0; i<pAC->GIni.GIMacsFound; i++) {
2696 ReceiveIrq(pAC, &pAC->RxPort[i], SK_TRUE);
2697 ClearRxRing(pAC, &pAC->RxPort[i]);
2698 FillRxRing(pAC, &pAC->RxPort[i]);
2699
2700 /*
2701 ** Enable transmit descriptor polling
2702 */
2703 SkGePollTxD(pAC, pAC->IoBase, i, SK_TRUE);
2704 FillRxRing(pAC, &pAC->RxPort[i]);
2705 };
2706
2707 SkGeYellowLED(pAC, pAC->IoBase, 1);
2708 SkDimEnableModerationIfNeeded(pAC);
2709 SkDimDisplayModerationSettings(pAC);
2710
2711 netif_start_queue(pAC->dev[pNet->PortNr]);
2712 for (i=pAC->GIni.GIMacsFound-1; i>=0; i--) {
2713 spin_unlock(&pAC->TxPort[i][TX_PRIO_LOW].TxDesRingLock);
2714 }
2715
2716 /*
2717 ** Enable Interrupts again
2718 */
2719 SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask);
2720 SK_OUT32(pAC->IoBase, B0_HWE_IMSK, IRQ_HWE_MASK);
2721
2722 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara);
2723 SkEventDispatcher(pAC, pAC->IoBase);
2724
2725 /*
2726 ** Notify RLMT about the changing and restarting one (or more) ports
2727 */
2728 if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) {
2729 EvPara.Para32[0] = pAC->RlmtNets;
2730 EvPara.Para32[1] = -1;
2731 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_SET_NETS, EvPara);
2732 EvPara.Para32[0] = pNet->PortNr;
2733 EvPara.Para32[1] = -1;
2734 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara);
2735
2736 if (netif_running(pOtherDev)) {
2737 DEV_NET *pOtherNet = netdev_priv(pOtherDev);
2738 EvPara.Para32[0] = pOtherNet->PortNr;
2739 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara);
2740 }
2741 } else {
2742 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara);
2743 }
2744
2745 SkEventDispatcher(pAC, pAC->IoBase);
2746 spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
2747
2748 /*
2749 ** While testing this driver with latest kernel 2.5 (2.5.70), it
2750 ** seems as if upper layers have a problem to handle a successful
2751 ** return value of '0'. If such a zero is returned, the complete
2752 ** system hangs for several minutes (!), which is in acceptable.
2753 **
2754 ** Currently it is not clear, what the exact reason for this problem
2755 ** is. The implemented workaround for 2.5 is to return the desired
2756 ** new MTU size if all needed changes for the new MTU size where
2757 ** performed. In kernels 2.2 and 2.4, a zero value is returned,
2758 ** which indicates the successful change of the mtu-size.
2759 */
2760 return NewMtu;
2761
2762} /* SkGeChangeMtu */
2763
2764
2765/*****************************************************************************
2766 *
2767 * SkGeStats - return ethernet device statistics
2768 *
2769 * Description:
2770 * This function return statistic data about the ethernet device
2771 * to the operating system.
2772 *
2773 * Returns:
2774 * pointer to the statistic structure.
2775 */
2776static struct net_device_stats *SkGeStats(struct SK_NET_DEVICE *dev)
2777{
2778DEV_NET *pNet = netdev_priv(dev);
2779SK_AC *pAC = pNet->pAC;
2780SK_PNMI_STRUCT_DATA *pPnmiStruct; /* structure for all Pnmi-Data */
2781SK_PNMI_STAT *pPnmiStat; /* pointer to virtual XMAC stat. data */
2782SK_PNMI_CONF *pPnmiConf; /* pointer to virtual link config. */
2783unsigned int Size; /* size of pnmi struct */
2784unsigned long Flags; /* for spin lock */
2785
2786 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
2787 ("SkGeStats starts now...\n"));
2788 pPnmiStruct = &pAC->PnmiStruct;
2789
2790#ifdef SK_DIAG_SUPPORT
2791 if ((pAC->DiagModeActive == DIAG_NOTACTIVE) &&
2792 (pAC->BoardLevel == SK_INIT_RUN)) {
2793#endif
2794 SK_MEMSET(pPnmiStruct, 0, sizeof(SK_PNMI_STRUCT_DATA));
2795 spin_lock_irqsave(&pAC->SlowPathLock, Flags);
2796 Size = SK_PNMI_STRUCT_SIZE;
2797 SkPnmiGetStruct(pAC, pAC->IoBase, pPnmiStruct, &Size, pNet->NetNr);
2798 spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
2799#ifdef SK_DIAG_SUPPORT
2800 }
2801#endif
2802
2803 pPnmiStat = &pPnmiStruct->Stat[0];
2804 pPnmiConf = &pPnmiStruct->Conf[0];
2805
2806 pAC->stats.rx_packets = (SK_U32) pPnmiStruct->RxDeliveredCts & 0xFFFFFFFF;
2807 pAC->stats.tx_packets = (SK_U32) pPnmiStat->StatTxOkCts & 0xFFFFFFFF;
2808 pAC->stats.rx_bytes = (SK_U32) pPnmiStruct->RxOctetsDeliveredCts;
2809 pAC->stats.tx_bytes = (SK_U32) pPnmiStat->StatTxOctetsOkCts;
2810
2811 if (dev->mtu <= 1500) {
2812 pAC->stats.rx_errors = (SK_U32) pPnmiStruct->InErrorsCts & 0xFFFFFFFF;
2813 } else {
2814 pAC->stats.rx_errors = (SK_U32) ((pPnmiStruct->InErrorsCts -
2815 pPnmiStat->StatRxTooLongCts) & 0xFFFFFFFF);
2816 }
2817
2818
2819 if (pAC->GIni.GP[0].PhyType == SK_PHY_XMAC && pAC->HWRevision < 12)
2820 pAC->stats.rx_errors = pAC->stats.rx_errors - pPnmiStat->StatRxShortsCts;
2821
2822 pAC->stats.tx_errors = (SK_U32) pPnmiStat->StatTxSingleCollisionCts & 0xFFFFFFFF;
2823 pAC->stats.rx_dropped = (SK_U32) pPnmiStruct->RxNoBufCts & 0xFFFFFFFF;
2824 pAC->stats.tx_dropped = (SK_U32) pPnmiStruct->TxNoBufCts & 0xFFFFFFFF;
2825 pAC->stats.multicast = (SK_U32) pPnmiStat->StatRxMulticastOkCts & 0xFFFFFFFF;
2826 pAC->stats.collisions = (SK_U32) pPnmiStat->StatTxSingleCollisionCts & 0xFFFFFFFF;
2827
2828 /* detailed rx_errors: */
2829 pAC->stats.rx_length_errors = (SK_U32) pPnmiStat->StatRxRuntCts & 0xFFFFFFFF;
2830 pAC->stats.rx_over_errors = (SK_U32) pPnmiStat->StatRxFifoOverflowCts & 0xFFFFFFFF;
2831 pAC->stats.rx_crc_errors = (SK_U32) pPnmiStat->StatRxFcsCts & 0xFFFFFFFF;
2832 pAC->stats.rx_frame_errors = (SK_U32) pPnmiStat->StatRxFramingCts & 0xFFFFFFFF;
2833 pAC->stats.rx_fifo_errors = (SK_U32) pPnmiStat->StatRxFifoOverflowCts & 0xFFFFFFFF;
2834 pAC->stats.rx_missed_errors = (SK_U32) pPnmiStat->StatRxMissedCts & 0xFFFFFFFF;
2835
2836 /* detailed tx_errors */
2837 pAC->stats.tx_aborted_errors = (SK_U32) 0;
2838 pAC->stats.tx_carrier_errors = (SK_U32) pPnmiStat->StatTxCarrierCts & 0xFFFFFFFF;
2839 pAC->stats.tx_fifo_errors = (SK_U32) pPnmiStat->StatTxFifoUnderrunCts & 0xFFFFFFFF;
2840 pAC->stats.tx_heartbeat_errors = (SK_U32) pPnmiStat->StatTxCarrierCts & 0xFFFFFFFF;
2841 pAC->stats.tx_window_errors = (SK_U32) 0;
2842
2843 return(&pAC->stats);
2844} /* SkGeStats */
2845
2846/*
2847 * Basic MII register access
2848 */
2849static int SkGeMiiIoctl(struct net_device *dev,
2850 struct mii_ioctl_data *data, int cmd)
2851{
2852 DEV_NET *pNet = netdev_priv(dev);
2853 SK_AC *pAC = pNet->pAC;
2854 SK_IOC IoC = pAC->IoBase;
2855 int Port = pNet->PortNr;
2856 SK_GEPORT *pPrt = &pAC->GIni.GP[Port];
2857 unsigned long Flags;
2858 int err = 0;
2859 int reg = data->reg_num & 0x1f;
2860 SK_U16 val = data->val_in;
2861
2862 if (!netif_running(dev))
2863 return -ENODEV; /* Phy still in reset */
2864
2865 spin_lock_irqsave(&pAC->SlowPathLock, Flags);
2866 switch(cmd) {
2867 case SIOCGMIIPHY:
2868 data->phy_id = pPrt->PhyAddr;
2869
2870 /* fallthru */
2871 case SIOCGMIIREG:
2872 if (pAC->GIni.GIGenesis)
2873 SkXmPhyRead(pAC, IoC, Port, reg, &val);
2874 else
2875 SkGmPhyRead(pAC, IoC, Port, reg, &val);
2876
2877 data->val_out = val;
2878 break;
2879
2880 case SIOCSMIIREG:
2881 if (!capable(CAP_NET_ADMIN))
2882 err = -EPERM;
2883
2884 else if (pAC->GIni.GIGenesis)
2885 SkXmPhyWrite(pAC, IoC, Port, reg, val);
2886 else
2887 SkGmPhyWrite(pAC, IoC, Port, reg, val);
2888 break;
2889 default:
2890 err = -EOPNOTSUPP;
2891 }
2892 spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
2893 return err;
2894}
2895
2896
2897/*****************************************************************************
2898 *
2899 * SkGeIoctl - IO-control function
2900 *
2901 * Description:
2902 * This function is called if an ioctl is issued on the device.
2903 * There are three subfunction for reading, writing and test-writing
2904 * the private MIB data structure (useful for SysKonnect-internal tools).
2905 *
2906 * Returns:
2907 * 0, if everything is ok
2908 * !=0, on error
2909 */
2910static int SkGeIoctl(struct SK_NET_DEVICE *dev, struct ifreq *rq, int cmd)
2911{
2912DEV_NET *pNet;
2913SK_AC *pAC;
2914void *pMemBuf;
2915struct pci_dev *pdev = NULL;
2916SK_GE_IOCTL Ioctl;
2917unsigned int Err = 0;
2918int Size = 0;
2919int Ret = 0;
2920unsigned int Length = 0;
2921int HeaderLength = sizeof(SK_U32) + sizeof(SK_U32);
2922
2923 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
2924 ("SkGeIoctl starts now...\n"));
2925
2926 pNet = netdev_priv(dev);
2927 pAC = pNet->pAC;
2928
2929 if (cmd == SIOCGMIIPHY || cmd == SIOCSMIIREG || cmd == SIOCGMIIREG)
2930 return SkGeMiiIoctl(dev, if_mii(rq), cmd);
2931
2932 if(copy_from_user(&Ioctl, rq->ifr_data, sizeof(SK_GE_IOCTL))) {
2933 return -EFAULT;
2934 }
2935
2936 switch(cmd) {
2937 case SK_IOCTL_SETMIB:
2938 case SK_IOCTL_PRESETMIB:
2939 if (!capable(CAP_NET_ADMIN)) return -EPERM;
2940 case SK_IOCTL_GETMIB:
2941 if(copy_from_user(&pAC->PnmiStruct, Ioctl.pData,
2942 Ioctl.Len<sizeof(pAC->PnmiStruct)?
2943 Ioctl.Len : sizeof(pAC->PnmiStruct))) {
2944 return -EFAULT;
2945 }
2946 Size = SkGeIocMib(pNet, Ioctl.Len, cmd);
2947 if(copy_to_user(Ioctl.pData, &pAC->PnmiStruct,
2948 Ioctl.Len<Size? Ioctl.Len : Size)) {
2949 return -EFAULT;
2950 }
2951 Ioctl.Len = Size;
2952 if(copy_to_user(rq->ifr_data, &Ioctl, sizeof(SK_GE_IOCTL))) {
2953 return -EFAULT;
2954 }
2955 break;
2956 case SK_IOCTL_GEN:
2957 if (Ioctl.Len < (sizeof(pAC->PnmiStruct) + HeaderLength)) {
2958 Length = Ioctl.Len;
2959 } else {
2960 Length = sizeof(pAC->PnmiStruct) + HeaderLength;
2961 }
2962 if (NULL == (pMemBuf = kmalloc(Length, GFP_KERNEL))) {
2963 return -ENOMEM;
2964 }
2965 if(copy_from_user(pMemBuf, Ioctl.pData, Length)) {
2966 Err = -EFAULT;
2967 goto fault_gen;
2968 }
2969 if ((Ret = SkPnmiGenIoctl(pAC, pAC->IoBase, pMemBuf, &Length, 0)) < 0) {
2970 Err = -EFAULT;
2971 goto fault_gen;
2972 }
2973 if(copy_to_user(Ioctl.pData, pMemBuf, Length) ) {
2974 Err = -EFAULT;
2975 goto fault_gen;
2976 }
2977 Ioctl.Len = Length;
2978 if(copy_to_user(rq->ifr_data, &Ioctl, sizeof(SK_GE_IOCTL))) {
2979 Err = -EFAULT;
2980 goto fault_gen;
2981 }
2982fault_gen:
2983 kfree(pMemBuf); /* cleanup everything */
2984 break;
2985#ifdef SK_DIAG_SUPPORT
2986 case SK_IOCTL_DIAG:
2987 if (!capable(CAP_NET_ADMIN)) return -EPERM;
2988 if (Ioctl.Len < (sizeof(pAC->PnmiStruct) + HeaderLength)) {
2989 Length = Ioctl.Len;
2990 } else {
2991 Length = sizeof(pAC->PnmiStruct) + HeaderLength;
2992 }
2993 if (NULL == (pMemBuf = kmalloc(Length, GFP_KERNEL))) {
2994 return -ENOMEM;
2995 }
2996 if(copy_from_user(pMemBuf, Ioctl.pData, Length)) {
2997 Err = -EFAULT;
2998 goto fault_diag;
2999 }
3000 pdev = pAC->PciDev;
3001 Length = 3 * sizeof(SK_U32); /* Error, Bus and Device */
3002 /*
3003 ** While coding this new IOCTL interface, only a few lines of code
3004 ** are to to be added. Therefore no dedicated function has been
3005 ** added. If more functionality is added, a separate function
3006 ** should be used...
3007 */
3008 * ((SK_U32 *)pMemBuf) = 0;
3009 * ((SK_U32 *)pMemBuf + 1) = pdev->bus->number;
3010 * ((SK_U32 *)pMemBuf + 2) = ParseDeviceNbrFromSlotName(pci_name(pdev));
3011 if(copy_to_user(Ioctl.pData, pMemBuf, Length) ) {
3012 Err = -EFAULT;
3013 goto fault_diag;
3014 }
3015 Ioctl.Len = Length;
3016 if(copy_to_user(rq->ifr_data, &Ioctl, sizeof(SK_GE_IOCTL))) {
3017 Err = -EFAULT;
3018 goto fault_diag;
3019 }
3020fault_diag:
3021 kfree(pMemBuf); /* cleanup everything */
3022 break;
3023#endif
3024 default:
3025 Err = -EOPNOTSUPP;
3026 }
3027
3028 return(Err);
3029
3030} /* SkGeIoctl */
3031
3032
3033/*****************************************************************************
3034 *
3035 * SkGeIocMib - handle a GetMib, SetMib- or PresetMib-ioctl message
3036 *
3037 * Description:
3038 * This function reads/writes the MIB data using PNMI (Private Network
3039 * Management Interface).
3040 * The destination for the data must be provided with the
3041 * ioctl call and is given to the driver in the form of
3042 * a user space address.
3043 * Copying from the user-provided data area into kernel messages
3044 * and back is done by copy_from_user and copy_to_user calls in
3045 * SkGeIoctl.
3046 *
3047 * Returns:
3048 * returned size from PNMI call
3049 */
3050static int SkGeIocMib(
3051DEV_NET *pNet, /* pointer to the adapter context */
3052unsigned int Size, /* length of ioctl data */
3053int mode) /* flag for set/preset */
3054{
3055unsigned long Flags; /* for spin lock */
3056SK_AC *pAC;
3057
3058 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
3059 ("SkGeIocMib starts now...\n"));
3060 pAC = pNet->pAC;
3061 /* access MIB */
3062 spin_lock_irqsave(&pAC->SlowPathLock, Flags);
3063 switch(mode) {
3064 case SK_IOCTL_GETMIB:
3065 SkPnmiGetStruct(pAC, pAC->IoBase, &pAC->PnmiStruct, &Size,
3066 pNet->NetNr);
3067 break;
3068 case SK_IOCTL_PRESETMIB:
3069 SkPnmiPreSetStruct(pAC, pAC->IoBase, &pAC->PnmiStruct, &Size,
3070 pNet->NetNr);
3071 break;
3072 case SK_IOCTL_SETMIB:
3073 SkPnmiSetStruct(pAC, pAC->IoBase, &pAC->PnmiStruct, &Size,
3074 pNet->NetNr);
3075 break;
3076 default:
3077 break;
3078 }
3079 spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
3080 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
3081 ("MIB data access succeeded\n"));
3082 return (Size);
3083} /* SkGeIocMib */
3084
3085
3086/*****************************************************************************
3087 *
3088 * GetConfiguration - read configuration information
3089 *
3090 * Description:
3091 * This function reads per-adapter configuration information from
3092 * the options provided on the command line.
3093 *
3094 * Returns:
3095 * none
3096 */
3097static void GetConfiguration(
3098SK_AC *pAC) /* pointer to the adapter context structure */
3099{
3100SK_I32 Port; /* preferred port */
3101SK_BOOL AutoSet;
3102SK_BOOL DupSet;
3103int LinkSpeed = SK_LSPEED_AUTO; /* Link speed */
3104int AutoNeg = 1; /* autoneg off (0) or on (1) */
3105int DuplexCap = 0; /* 0=both,1=full,2=half */
3106int FlowCtrl = SK_FLOW_MODE_SYM_OR_REM; /* FlowControl */
3107int MSMode = SK_MS_MODE_AUTO; /* master/slave mode */
3108
3109SK_BOOL IsConTypeDefined = SK_TRUE;
3110SK_BOOL IsLinkSpeedDefined = SK_TRUE;
3111SK_BOOL IsFlowCtrlDefined = SK_TRUE;
3112SK_BOOL IsRoleDefined = SK_TRUE;
3113SK_BOOL IsModeDefined = SK_TRUE;
3114/*
3115 * The two parameters AutoNeg. and DuplexCap. map to one configuration
3116 * parameter. The mapping is described by this table:
3117 * DuplexCap -> | both | full | half |
3118 * AutoNeg | | | |
3119 * -----------------------------------------------------------------
3120 * Off | illegal | Full | Half |
3121 * -----------------------------------------------------------------
3122 * On | AutoBoth | AutoFull | AutoHalf |
3123 * -----------------------------------------------------------------
3124 * Sense | AutoSense | AutoSense | AutoSense |
3125 */
3126int Capabilities[3][3] =
3127 { { -1, SK_LMODE_FULL , SK_LMODE_HALF },
3128 {SK_LMODE_AUTOBOTH , SK_LMODE_AUTOFULL , SK_LMODE_AUTOHALF },
3129 {SK_LMODE_AUTOSENSE, SK_LMODE_AUTOSENSE, SK_LMODE_AUTOSENSE} };
3130
3131#define DC_BOTH 0
3132#define DC_FULL 1
3133#define DC_HALF 2
3134#define AN_OFF 0
3135#define AN_ON 1
3136#define AN_SENS 2
3137#define M_CurrPort pAC->GIni.GP[Port]
3138
3139
3140 /*
3141 ** Set the default values first for both ports!
3142 */
3143 for (Port = 0; Port < SK_MAX_MACS; Port++) {
3144 M_CurrPort.PLinkModeConf = Capabilities[AN_ON][DC_BOTH];
3145 M_CurrPort.PFlowCtrlMode = SK_FLOW_MODE_SYM_OR_REM;
3146 M_CurrPort.PMSMode = SK_MS_MODE_AUTO;
3147 M_CurrPort.PLinkSpeed = SK_LSPEED_AUTO;
3148 }
3149
3150 /*
3151 ** Check merged parameter ConType. If it has not been used,
3152 ** verify any other parameter (e.g. AutoNeg) and use default values.
3153 **
3154 ** Stating both ConType and other lowlevel link parameters is also
3155 ** possible. If this is the case, the passed ConType-parameter is
3156 ** overwritten by the lowlevel link parameter.
3157 **
3158 ** The following settings are used for a merged ConType-parameter:
3159 **
3160 ** ConType DupCap AutoNeg FlowCtrl Role Speed
3161 ** ------- ------ ------- -------- ---------- -----
3162 ** Auto Both On SymOrRem Auto Auto
3163 ** 100FD Full Off None <ignored> 100
3164 ** 100HD Half Off None <ignored> 100
3165 ** 10FD Full Off None <ignored> 10
3166 ** 10HD Half Off None <ignored> 10
3167 **
3168 ** This ConType parameter is used for all ports of the adapter!
3169 */
3170 if ( (ConType != NULL) &&
3171 (pAC->Index < SK_MAX_CARD_PARAM) &&
3172 (ConType[pAC->Index] != NULL) ) {
3173
3174 /* Check chipset family */
3175 if ((!pAC->ChipsetType) &&
3176 (strcmp(ConType[pAC->Index],"Auto")!=0) &&
3177 (strcmp(ConType[pAC->Index],"")!=0)) {
3178 /* Set the speed parameter back */
3179 printk("sk98lin: Illegal value \"%s\" "
3180 "for ConType."
3181 " Using Auto.\n",
3182 ConType[pAC->Index]);
3183
3184 sprintf(ConType[pAC->Index], "Auto");
3185 }
3186
3187 if (strcmp(ConType[pAC->Index],"")==0) {
3188 IsConTypeDefined = SK_FALSE; /* No ConType defined */
3189 } else if (strcmp(ConType[pAC->Index],"Auto")==0) {
3190 for (Port = 0; Port < SK_MAX_MACS; Port++) {
3191 M_CurrPort.PLinkModeConf = Capabilities[AN_ON][DC_BOTH];
3192 M_CurrPort.PFlowCtrlMode = SK_FLOW_MODE_SYM_OR_REM;
3193 M_CurrPort.PMSMode = SK_MS_MODE_AUTO;
3194 M_CurrPort.PLinkSpeed = SK_LSPEED_AUTO;
3195 }
3196 } else if (strcmp(ConType[pAC->Index],"100FD")==0) {
3197 for (Port = 0; Port < SK_MAX_MACS; Port++) {
3198 M_CurrPort.PLinkModeConf = Capabilities[AN_OFF][DC_FULL];
3199 M_CurrPort.PFlowCtrlMode = SK_FLOW_MODE_NONE;
3200 M_CurrPort.PMSMode = SK_MS_MODE_AUTO;
3201 M_CurrPort.PLinkSpeed = SK_LSPEED_100MBPS;
3202 }
3203 } else if (strcmp(ConType[pAC->Index],"100HD")==0) {
3204 for (Port = 0; Port < SK_MAX_MACS; Port++) {
3205 M_CurrPort.PLinkModeConf = Capabilities[AN_OFF][DC_HALF];
3206 M_CurrPort.PFlowCtrlMode = SK_FLOW_MODE_NONE;
3207 M_CurrPort.PMSMode = SK_MS_MODE_AUTO;
3208 M_CurrPort.PLinkSpeed = SK_LSPEED_100MBPS;
3209 }
3210 } else if (strcmp(ConType[pAC->Index],"10FD")==0) {
3211 for (Port = 0; Port < SK_MAX_MACS; Port++) {
3212 M_CurrPort.PLinkModeConf = Capabilities[AN_OFF][DC_FULL];
3213 M_CurrPort.PFlowCtrlMode = SK_FLOW_MODE_NONE;
3214 M_CurrPort.PMSMode = SK_MS_MODE_AUTO;
3215 M_CurrPort.PLinkSpeed = SK_LSPEED_10MBPS;
3216 }
3217 } else if (strcmp(ConType[pAC->Index],"10HD")==0) {
3218 for (Port = 0; Port < SK_MAX_MACS; Port++) {
3219 M_CurrPort.PLinkModeConf = Capabilities[AN_OFF][DC_HALF];
3220 M_CurrPort.PFlowCtrlMode = SK_FLOW_MODE_NONE;
3221 M_CurrPort.PMSMode = SK_MS_MODE_AUTO;
3222 M_CurrPort.PLinkSpeed = SK_LSPEED_10MBPS;
3223 }
3224 } else {
3225 printk("sk98lin: Illegal value \"%s\" for ConType\n",
3226 ConType[pAC->Index]);
3227 IsConTypeDefined = SK_FALSE; /* Wrong ConType defined */
3228 }
3229 } else {
3230 IsConTypeDefined = SK_FALSE; /* No ConType defined */
3231 }
3232
3233 /*
3234 ** Parse any parameter settings for port A:
3235 ** a) any LinkSpeed stated?
3236 */
3237 if (Speed_A != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
3238 Speed_A[pAC->Index] != NULL) {
3239 if (strcmp(Speed_A[pAC->Index],"")==0) {
3240 IsLinkSpeedDefined = SK_FALSE;
3241 } else if (strcmp(Speed_A[pAC->Index],"Auto")==0) {
3242 LinkSpeed = SK_LSPEED_AUTO;
3243 } else if (strcmp(Speed_A[pAC->Index],"10")==0) {
3244 LinkSpeed = SK_LSPEED_10MBPS;
3245 } else if (strcmp(Speed_A[pAC->Index],"100")==0) {
3246 LinkSpeed = SK_LSPEED_100MBPS;
3247 } else if (strcmp(Speed_A[pAC->Index],"1000")==0) {
3248 LinkSpeed = SK_LSPEED_1000MBPS;
3249 } else {
3250 printk("sk98lin: Illegal value \"%s\" for Speed_A\n",
3251 Speed_A[pAC->Index]);
3252 IsLinkSpeedDefined = SK_FALSE;
3253 }
3254 } else {
3255 IsLinkSpeedDefined = SK_FALSE;
3256 }
3257
3258 /*
3259 ** Check speed parameter:
3260 ** Only copper type adapter and GE V2 cards
3261 */
3262 if (((!pAC->ChipsetType) || (pAC->GIni.GICopperType != SK_TRUE)) &&
3263 ((LinkSpeed != SK_LSPEED_AUTO) &&
3264 (LinkSpeed != SK_LSPEED_1000MBPS))) {
3265 printk("sk98lin: Illegal value for Speed_A. "
3266 "Not a copper card or GE V2 card\n Using "
3267 "speed 1000\n");
3268 LinkSpeed = SK_LSPEED_1000MBPS;
3269 }
3270
3271 /*
3272 ** Decide whether to set new config value if somethig valid has
3273 ** been received.
3274 */
3275 if (IsLinkSpeedDefined) {
3276 pAC->GIni.GP[0].PLinkSpeed = LinkSpeed;
3277 }
3278
3279 /*
3280 ** b) Any Autonegotiation and DuplexCapabilities set?
3281 ** Please note that both belong together...
3282 */
3283 AutoNeg = AN_ON; /* tschilling: Default: Autonegotiation on! */
3284 AutoSet = SK_FALSE;
3285 if (AutoNeg_A != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
3286 AutoNeg_A[pAC->Index] != NULL) {
3287 AutoSet = SK_TRUE;
3288 if (strcmp(AutoNeg_A[pAC->Index],"")==0) {
3289 AutoSet = SK_FALSE;
3290 } else if (strcmp(AutoNeg_A[pAC->Index],"On")==0) {
3291 AutoNeg = AN_ON;
3292 } else if (strcmp(AutoNeg_A[pAC->Index],"Off")==0) {
3293 AutoNeg = AN_OFF;
3294 } else if (strcmp(AutoNeg_A[pAC->Index],"Sense")==0) {
3295 AutoNeg = AN_SENS;
3296 } else {
3297 printk("sk98lin: Illegal value \"%s\" for AutoNeg_A\n",
3298 AutoNeg_A[pAC->Index]);
3299 }
3300 }
3301
3302 DuplexCap = DC_BOTH;
3303 DupSet = SK_FALSE;
3304 if (DupCap_A != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
3305 DupCap_A[pAC->Index] != NULL) {
3306 DupSet = SK_TRUE;
3307 if (strcmp(DupCap_A[pAC->Index],"")==0) {
3308 DupSet = SK_FALSE;
3309 } else if (strcmp(DupCap_A[pAC->Index],"Both")==0) {
3310 DuplexCap = DC_BOTH;
3311 } else if (strcmp(DupCap_A[pAC->Index],"Full")==0) {
3312 DuplexCap = DC_FULL;
3313 } else if (strcmp(DupCap_A[pAC->Index],"Half")==0) {
3314 DuplexCap = DC_HALF;
3315 } else {
3316 printk("sk98lin: Illegal value \"%s\" for DupCap_A\n",
3317 DupCap_A[pAC->Index]);
3318 }
3319 }
3320
3321 /*
3322 ** Check for illegal combinations
3323 */
3324 if ((LinkSpeed == SK_LSPEED_1000MBPS) &&
3325 ((DuplexCap == SK_LMODE_STAT_AUTOHALF) ||
3326 (DuplexCap == SK_LMODE_STAT_HALF)) &&
3327 (pAC->ChipsetType)) {
3328 printk("sk98lin: Half Duplex not possible with Gigabit speed!\n"
3329 " Using Full Duplex.\n");
3330 DuplexCap = DC_FULL;
3331 }
3332
3333 if ( AutoSet && AutoNeg==AN_SENS && DupSet) {
3334 printk("sk98lin, Port A: DuplexCapabilities"
3335 " ignored using Sense mode\n");
3336 }
3337
3338 if (AutoSet && AutoNeg==AN_OFF && DupSet && DuplexCap==DC_BOTH){
3339 printk("sk98lin: Port A: Illegal combination"
3340 " of values AutoNeg. and DuplexCap.\n Using "
3341 "Full Duplex\n");
3342 DuplexCap = DC_FULL;
3343 }
3344
3345 if (AutoSet && AutoNeg==AN_OFF && !DupSet) {
3346 DuplexCap = DC_FULL;
3347 }
3348
3349 if (!AutoSet && DupSet) {
3350 printk("sk98lin: Port A: Duplex setting not"
3351 " possible in\n default AutoNegotiation mode"
3352 " (Sense).\n Using AutoNegotiation On\n");
3353 AutoNeg = AN_ON;
3354 }
3355
3356 /*
3357 ** set the desired mode
3358 */
3359 if (AutoSet || DupSet) {
3360 pAC->GIni.GP[0].PLinkModeConf = Capabilities[AutoNeg][DuplexCap];
3361 }
3362
3363 /*
3364 ** c) Any Flowcontrol-parameter set?
3365 */
3366 if (FlowCtrl_A != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
3367 FlowCtrl_A[pAC->Index] != NULL) {
3368 if (strcmp(FlowCtrl_A[pAC->Index],"") == 0) {
3369 IsFlowCtrlDefined = SK_FALSE;
3370 } else if (strcmp(FlowCtrl_A[pAC->Index],"SymOrRem") == 0) {
3371 FlowCtrl = SK_FLOW_MODE_SYM_OR_REM;
3372 } else if (strcmp(FlowCtrl_A[pAC->Index],"Sym")==0) {
3373 FlowCtrl = SK_FLOW_MODE_SYMMETRIC;
3374 } else if (strcmp(FlowCtrl_A[pAC->Index],"LocSend")==0) {
3375 FlowCtrl = SK_FLOW_MODE_LOC_SEND;
3376 } else if (strcmp(FlowCtrl_A[pAC->Index],"None")==0) {
3377 FlowCtrl = SK_FLOW_MODE_NONE;
3378 } else {
3379 printk("sk98lin: Illegal value \"%s\" for FlowCtrl_A\n",
3380 FlowCtrl_A[pAC->Index]);
3381 IsFlowCtrlDefined = SK_FALSE;
3382 }
3383 } else {
3384 IsFlowCtrlDefined = SK_FALSE;
3385 }
3386
3387 if (IsFlowCtrlDefined) {
3388 if ((AutoNeg == AN_OFF) && (FlowCtrl != SK_FLOW_MODE_NONE)) {
3389 printk("sk98lin: Port A: FlowControl"
3390 " impossible without AutoNegotiation,"
3391 " disabled\n");
3392 FlowCtrl = SK_FLOW_MODE_NONE;
3393 }
3394 pAC->GIni.GP[0].PFlowCtrlMode = FlowCtrl;
3395 }
3396
3397 /*
3398 ** d) What is with the RoleParameter?
3399 */
3400 if (Role_A != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
3401 Role_A[pAC->Index] != NULL) {
3402 if (strcmp(Role_A[pAC->Index],"")==0) {
3403 IsRoleDefined = SK_FALSE;
3404 } else if (strcmp(Role_A[pAC->Index],"Auto")==0) {
3405 MSMode = SK_MS_MODE_AUTO;
3406 } else if (strcmp(Role_A[pAC->Index],"Master")==0) {
3407 MSMode = SK_MS_MODE_MASTER;
3408 } else if (strcmp(Role_A[pAC->Index],"Slave")==0) {
3409 MSMode = SK_MS_MODE_SLAVE;
3410 } else {
3411 printk("sk98lin: Illegal value \"%s\" for Role_A\n",
3412 Role_A[pAC->Index]);
3413 IsRoleDefined = SK_FALSE;
3414 }
3415 } else {
3416 IsRoleDefined = SK_FALSE;
3417 }
3418
3419 if (IsRoleDefined == SK_TRUE) {
3420 pAC->GIni.GP[0].PMSMode = MSMode;
3421 }
3422
3423
3424
3425 /*
3426 ** Parse any parameter settings for port B:
3427 ** a) any LinkSpeed stated?
3428 */
3429 IsConTypeDefined = SK_TRUE;
3430 IsLinkSpeedDefined = SK_TRUE;
3431 IsFlowCtrlDefined = SK_TRUE;
3432 IsModeDefined = SK_TRUE;
3433
3434 if (Speed_B != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
3435 Speed_B[pAC->Index] != NULL) {
3436 if (strcmp(Speed_B[pAC->Index],"")==0) {
3437 IsLinkSpeedDefined = SK_FALSE;
3438 } else if (strcmp(Speed_B[pAC->Index],"Auto")==0) {
3439 LinkSpeed = SK_LSPEED_AUTO;
3440 } else if (strcmp(Speed_B[pAC->Index],"10")==0) {
3441 LinkSpeed = SK_LSPEED_10MBPS;
3442 } else if (strcmp(Speed_B[pAC->Index],"100")==0) {
3443 LinkSpeed = SK_LSPEED_100MBPS;
3444 } else if (strcmp(Speed_B[pAC->Index],"1000")==0) {
3445 LinkSpeed = SK_LSPEED_1000MBPS;
3446 } else {
3447 printk("sk98lin: Illegal value \"%s\" for Speed_B\n",
3448 Speed_B[pAC->Index]);
3449 IsLinkSpeedDefined = SK_FALSE;
3450 }
3451 } else {
3452 IsLinkSpeedDefined = SK_FALSE;
3453 }
3454
3455 /*
3456 ** Check speed parameter:
3457 ** Only copper type adapter and GE V2 cards
3458 */
3459 if (((!pAC->ChipsetType) || (pAC->GIni.GICopperType != SK_TRUE)) &&
3460 ((LinkSpeed != SK_LSPEED_AUTO) &&
3461 (LinkSpeed != SK_LSPEED_1000MBPS))) {
3462 printk("sk98lin: Illegal value for Speed_B. "
3463 "Not a copper card or GE V2 card\n Using "
3464 "speed 1000\n");
3465 LinkSpeed = SK_LSPEED_1000MBPS;
3466 }
3467
3468 /*
3469 ** Decide whether to set new config value if somethig valid has
3470 ** been received.
3471 */
3472 if (IsLinkSpeedDefined) {
3473 pAC->GIni.GP[1].PLinkSpeed = LinkSpeed;
3474 }
3475
3476 /*
3477 ** b) Any Autonegotiation and DuplexCapabilities set?
3478 ** Please note that both belong together...
3479 */
3480 AutoNeg = AN_SENS; /* default: do auto Sense */
3481 AutoSet = SK_FALSE;
3482 if (AutoNeg_B != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
3483 AutoNeg_B[pAC->Index] != NULL) {
3484 AutoSet = SK_TRUE;
3485 if (strcmp(AutoNeg_B[pAC->Index],"")==0) {
3486 AutoSet = SK_FALSE;
3487 } else if (strcmp(AutoNeg_B[pAC->Index],"On")==0) {
3488 AutoNeg = AN_ON;
3489 } else if (strcmp(AutoNeg_B[pAC->Index],"Off")==0) {
3490 AutoNeg = AN_OFF;
3491 } else if (strcmp(AutoNeg_B[pAC->Index],"Sense")==0) {
3492 AutoNeg = AN_SENS;
3493 } else {
3494 printk("sk98lin: Illegal value \"%s\" for AutoNeg_B\n",
3495 AutoNeg_B[pAC->Index]);
3496 }
3497 }
3498
3499 DuplexCap = DC_BOTH;
3500 DupSet = SK_FALSE;
3501 if (DupCap_B != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
3502 DupCap_B[pAC->Index] != NULL) {
3503 DupSet = SK_TRUE;
3504 if (strcmp(DupCap_B[pAC->Index],"")==0) {
3505 DupSet = SK_FALSE;
3506 } else if (strcmp(DupCap_B[pAC->Index],"Both")==0) {
3507 DuplexCap = DC_BOTH;
3508 } else if (strcmp(DupCap_B[pAC->Index],"Full")==0) {
3509 DuplexCap = DC_FULL;
3510 } else if (strcmp(DupCap_B[pAC->Index],"Half")==0) {
3511 DuplexCap = DC_HALF;
3512 } else {
3513 printk("sk98lin: Illegal value \"%s\" for DupCap_B\n",
3514 DupCap_B[pAC->Index]);
3515 }
3516 }
3517
3518
3519 /*
3520 ** Check for illegal combinations
3521 */
3522 if ((LinkSpeed == SK_LSPEED_1000MBPS) &&
3523 ((DuplexCap == SK_LMODE_STAT_AUTOHALF) ||
3524 (DuplexCap == SK_LMODE_STAT_HALF)) &&
3525 (pAC->ChipsetType)) {
3526 printk("sk98lin: Half Duplex not possible with Gigabit speed!\n"
3527 " Using Full Duplex.\n");
3528 DuplexCap = DC_FULL;
3529 }
3530
3531 if (AutoSet && AutoNeg==AN_SENS && DupSet) {
3532 printk("sk98lin, Port B: DuplexCapabilities"
3533 " ignored using Sense mode\n");
3534 }
3535
3536 if (AutoSet && AutoNeg==AN_OFF && DupSet && DuplexCap==DC_BOTH){
3537 printk("sk98lin: Port B: Illegal combination"
3538 " of values AutoNeg. and DuplexCap.\n Using "
3539 "Full Duplex\n");
3540 DuplexCap = DC_FULL;
3541 }
3542
3543 if (AutoSet && AutoNeg==AN_OFF && !DupSet) {
3544 DuplexCap = DC_FULL;
3545 }
3546
3547 if (!AutoSet && DupSet) {
3548 printk("sk98lin: Port B: Duplex setting not"
3549 " possible in\n default AutoNegotiation mode"
3550 " (Sense).\n Using AutoNegotiation On\n");
3551 AutoNeg = AN_ON;
3552 }
3553
3554 /*
3555 ** set the desired mode
3556 */
3557 if (AutoSet || DupSet) {
3558 pAC->GIni.GP[1].PLinkModeConf = Capabilities[AutoNeg][DuplexCap];
3559 }
3560
3561 /*
3562 ** c) Any FlowCtrl parameter set?
3563 */
3564 if (FlowCtrl_B != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
3565 FlowCtrl_B[pAC->Index] != NULL) {
3566 if (strcmp(FlowCtrl_B[pAC->Index],"") == 0) {
3567 IsFlowCtrlDefined = SK_FALSE;
3568 } else if (strcmp(FlowCtrl_B[pAC->Index],"SymOrRem") == 0) {
3569 FlowCtrl = SK_FLOW_MODE_SYM_OR_REM;
3570 } else if (strcmp(FlowCtrl_B[pAC->Index],"Sym")==0) {
3571 FlowCtrl = SK_FLOW_MODE_SYMMETRIC;
3572 } else if (strcmp(FlowCtrl_B[pAC->Index],"LocSend")==0) {
3573 FlowCtrl = SK_FLOW_MODE_LOC_SEND;
3574 } else if (strcmp(FlowCtrl_B[pAC->Index],"None")==0) {
3575 FlowCtrl = SK_FLOW_MODE_NONE;
3576 } else {
3577 printk("sk98lin: Illegal value \"%s\" for FlowCtrl_B\n",
3578 FlowCtrl_B[pAC->Index]);
3579 IsFlowCtrlDefined = SK_FALSE;
3580 }
3581 } else {
3582 IsFlowCtrlDefined = SK_FALSE;
3583 }
3584
3585 if (IsFlowCtrlDefined) {
3586 if ((AutoNeg == AN_OFF) && (FlowCtrl != SK_FLOW_MODE_NONE)) {
3587 printk("sk98lin: Port B: FlowControl"
3588 " impossible without AutoNegotiation,"
3589 " disabled\n");
3590 FlowCtrl = SK_FLOW_MODE_NONE;
3591 }
3592 pAC->GIni.GP[1].PFlowCtrlMode = FlowCtrl;
3593 }
3594
3595 /*
3596 ** d) What is the RoleParameter?
3597 */
3598 if (Role_B != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
3599 Role_B[pAC->Index] != NULL) {
3600 if (strcmp(Role_B[pAC->Index],"")==0) {
3601 IsRoleDefined = SK_FALSE;
3602 } else if (strcmp(Role_B[pAC->Index],"Auto")==0) {
3603 MSMode = SK_MS_MODE_AUTO;
3604 } else if (strcmp(Role_B[pAC->Index],"Master")==0) {
3605 MSMode = SK_MS_MODE_MASTER;
3606 } else if (strcmp(Role_B[pAC->Index],"Slave")==0) {
3607 MSMode = SK_MS_MODE_SLAVE;
3608 } else {
3609 printk("sk98lin: Illegal value \"%s\" for Role_B\n",
3610 Role_B[pAC->Index]);
3611 IsRoleDefined = SK_FALSE;
3612 }
3613 } else {
3614 IsRoleDefined = SK_FALSE;
3615 }
3616
3617 if (IsRoleDefined) {
3618 pAC->GIni.GP[1].PMSMode = MSMode;
3619 }
3620
3621 /*
3622 ** Evaluate settings for both ports
3623 */
3624 pAC->ActivePort = 0;
3625 if (PrefPort != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
3626 PrefPort[pAC->Index] != NULL) {
3627 if (strcmp(PrefPort[pAC->Index],"") == 0) { /* Auto */
3628 pAC->ActivePort = 0;
3629 pAC->Rlmt.Net[0].Preference = -1; /* auto */
3630 pAC->Rlmt.Net[0].PrefPort = 0;
3631 } else if (strcmp(PrefPort[pAC->Index],"A") == 0) {
3632 /*
3633 ** do not set ActivePort here, thus a port
3634 ** switch is issued after net up.
3635 */
3636 Port = 0;
3637 pAC->Rlmt.Net[0].Preference = Port;
3638 pAC->Rlmt.Net[0].PrefPort = Port;
3639 } else if (strcmp(PrefPort[pAC->Index],"B") == 0) {
3640 /*
3641 ** do not set ActivePort here, thus a port
3642 ** switch is issued after net up.
3643 */
3644 if (pAC->GIni.GIMacsFound == 1) {
3645 printk("sk98lin: Illegal value \"B\" for PrefPort.\n"
3646 " Port B not available on single port adapters.\n");
3647
3648 pAC->ActivePort = 0;
3649 pAC->Rlmt.Net[0].Preference = -1; /* auto */
3650 pAC->Rlmt.Net[0].PrefPort = 0;
3651 } else {
3652 Port = 1;
3653 pAC->Rlmt.Net[0].Preference = Port;
3654 pAC->Rlmt.Net[0].PrefPort = Port;
3655 }
3656 } else {
3657 printk("sk98lin: Illegal value \"%s\" for PrefPort\n",
3658 PrefPort[pAC->Index]);
3659 }
3660 }
3661
3662 pAC->RlmtNets = 1;
3663
3664 if (RlmtMode != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
3665 RlmtMode[pAC->Index] != NULL) {
3666 if (strcmp(RlmtMode[pAC->Index], "") == 0) {
3667 pAC->RlmtMode = 0;
3668 } else if (strcmp(RlmtMode[pAC->Index], "CheckLinkState") == 0) {
3669 pAC->RlmtMode = SK_RLMT_CHECK_LINK;
3670 } else if (strcmp(RlmtMode[pAC->Index], "CheckLocalPort") == 0) {
3671 pAC->RlmtMode = SK_RLMT_CHECK_LINK |
3672 SK_RLMT_CHECK_LOC_LINK;
3673 } else if (strcmp(RlmtMode[pAC->Index], "CheckSeg") == 0) {
3674 pAC->RlmtMode = SK_RLMT_CHECK_LINK |
3675 SK_RLMT_CHECK_LOC_LINK |
3676 SK_RLMT_CHECK_SEG;
3677 } else if ((strcmp(RlmtMode[pAC->Index], "DualNet") == 0) &&
3678 (pAC->GIni.GIMacsFound == 2)) {
3679 pAC->RlmtMode = SK_RLMT_CHECK_LINK;
3680 pAC->RlmtNets = 2;
3681 } else {
3682 printk("sk98lin: Illegal value \"%s\" for"
3683 " RlmtMode, using default\n",
3684 RlmtMode[pAC->Index]);
3685 pAC->RlmtMode = 0;
3686 }
3687 } else {
3688 pAC->RlmtMode = 0;
3689 }
3690
3691 /*
3692 ** Check the interrupt moderation parameters
3693 */
3694 if (Moderation[pAC->Index] != NULL) {
3695 if (strcmp(Moderation[pAC->Index], "") == 0) {
3696 pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_NONE;
3697 } else if (strcmp(Moderation[pAC->Index], "Static") == 0) {
3698 pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_STATIC;
3699 } else if (strcmp(Moderation[pAC->Index], "Dynamic") == 0) {
3700 pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_DYNAMIC;
3701 } else if (strcmp(Moderation[pAC->Index], "None") == 0) {
3702 pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_NONE;
3703 } else {
3704 printk("sk98lin: Illegal value \"%s\" for Moderation.\n"
3705 " Disable interrupt moderation.\n",
3706 Moderation[pAC->Index]);
3707 pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_NONE;
3708 }
3709 } else {
3710 pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_NONE;
3711 }
3712
3713 if (Stats[pAC->Index] != NULL) {
3714 if (strcmp(Stats[pAC->Index], "Yes") == 0) {
3715 pAC->DynIrqModInfo.DisplayStats = SK_TRUE;
3716 } else {
3717 pAC->DynIrqModInfo.DisplayStats = SK_FALSE;
3718 }
3719 } else {
3720 pAC->DynIrqModInfo.DisplayStats = SK_FALSE;
3721 }
3722
3723 if (ModerationMask[pAC->Index] != NULL) {
3724 if (strcmp(ModerationMask[pAC->Index], "Rx") == 0) {
3725 pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_ONLY;
3726 } else if (strcmp(ModerationMask[pAC->Index], "Tx") == 0) {
3727 pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_ONLY;
3728 } else if (strcmp(ModerationMask[pAC->Index], "Sp") == 0) {
3729 pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_ONLY;
3730 } else if (strcmp(ModerationMask[pAC->Index], "RxSp") == 0) {
3731 pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_RX;
3732 } else if (strcmp(ModerationMask[pAC->Index], "SpRx") == 0) {
3733 pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_RX;
3734 } else if (strcmp(ModerationMask[pAC->Index], "RxTx") == 0) {
3735 pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_RX;
3736 } else if (strcmp(ModerationMask[pAC->Index], "TxRx") == 0) {
3737 pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_RX;
3738 } else if (strcmp(ModerationMask[pAC->Index], "TxSp") == 0) {
3739 pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_TX;
3740 } else if (strcmp(ModerationMask[pAC->Index], "SpTx") == 0) {
3741 pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_TX;
3742 } else if (strcmp(ModerationMask[pAC->Index], "RxTxSp") == 0) {
3743 pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
3744 } else if (strcmp(ModerationMask[pAC->Index], "RxSpTx") == 0) {
3745 pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
3746 } else if (strcmp(ModerationMask[pAC->Index], "TxRxSp") == 0) {
3747 pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
3748 } else if (strcmp(ModerationMask[pAC->Index], "TxSpRx") == 0) {
3749 pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
3750 } else if (strcmp(ModerationMask[pAC->Index], "SpTxRx") == 0) {
3751 pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
3752 } else if (strcmp(ModerationMask[pAC->Index], "SpRxTx") == 0) {
3753 pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
3754 } else { /* some rubbish */
3755 pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_ONLY;
3756 }
3757 } else { /* operator has stated nothing */
3758 pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_RX;
3759 }
3760
3761 if (AutoSizing[pAC->Index] != NULL) {
3762 if (strcmp(AutoSizing[pAC->Index], "On") == 0) {
3763 pAC->DynIrqModInfo.AutoSizing = SK_FALSE;
3764 } else {
3765 pAC->DynIrqModInfo.AutoSizing = SK_FALSE;
3766 }
3767 } else { /* operator has stated nothing */
3768 pAC->DynIrqModInfo.AutoSizing = SK_FALSE;
3769 }
3770
3771 if (IntsPerSec[pAC->Index] != 0) {
3772 if ((IntsPerSec[pAC->Index]< C_INT_MOD_IPS_LOWER_RANGE) ||
3773 (IntsPerSec[pAC->Index] > C_INT_MOD_IPS_UPPER_RANGE)) {
3774 printk("sk98lin: Illegal value \"%d\" for IntsPerSec. (Range: %d - %d)\n"
3775 " Using default value of %i.\n",
3776 IntsPerSec[pAC->Index],
3777 C_INT_MOD_IPS_LOWER_RANGE,
3778 C_INT_MOD_IPS_UPPER_RANGE,
3779 C_INTS_PER_SEC_DEFAULT);
3780 pAC->DynIrqModInfo.MaxModIntsPerSec = C_INTS_PER_SEC_DEFAULT;
3781 } else {
3782 pAC->DynIrqModInfo.MaxModIntsPerSec = IntsPerSec[pAC->Index];
3783 }
3784 } else {
3785 pAC->DynIrqModInfo.MaxModIntsPerSec = C_INTS_PER_SEC_DEFAULT;
3786 }
3787
3788 /*
3789 ** Evaluate upper and lower moderation threshold
3790 */
3791 pAC->DynIrqModInfo.MaxModIntsPerSecUpperLimit =
3792 pAC->DynIrqModInfo.MaxModIntsPerSec +
3793 (pAC->DynIrqModInfo.MaxModIntsPerSec / 2);
3794
3795 pAC->DynIrqModInfo.MaxModIntsPerSecLowerLimit =
3796 pAC->DynIrqModInfo.MaxModIntsPerSec -
3797 (pAC->DynIrqModInfo.MaxModIntsPerSec / 2);
3798
3799 pAC->DynIrqModInfo.PrevTimeVal = jiffies; /* initial value */
3800
3801
3802} /* GetConfiguration */
3803
3804
3805/*****************************************************************************
3806 *
3807 * ProductStr - return a adapter identification string from vpd
3808 *
3809 * Description:
3810 * This function reads the product name string from the vpd area
3811 * and puts it the field pAC->DeviceString.
3812 *
3813 * Returns: N/A
3814 */
3815static inline int ProductStr(
3816 SK_AC *pAC, /* pointer to adapter context */
3817 char *DeviceStr, /* result string */
3818 int StrLen /* length of the string */
3819)
3820{
3821char Keyword[] = VPD_NAME; /* vpd productname identifier */
3822int ReturnCode; /* return code from vpd_read */
3823unsigned long Flags;
3824
3825 spin_lock_irqsave(&pAC->SlowPathLock, Flags);
3826 ReturnCode = VpdRead(pAC, pAC->IoBase, Keyword, DeviceStr, &StrLen);
3827 spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
3828
3829 return ReturnCode;
3830} /* ProductStr */
3831
3832/*****************************************************************************
3833 *
3834 * StartDrvCleanupTimer - Start timer to check for descriptors which
3835 * might be placed in descriptor ring, but
3836 * havent been handled up to now
3837 *
3838 * Description:
3839 * This function requests a HW-timer fo the Yukon card. The actions to
3840 * perform when this timer expires, are located in the SkDrvEvent().
3841 *
3842 * Returns: N/A
3843 */
3844static void
3845StartDrvCleanupTimer(SK_AC *pAC) {
3846 SK_EVPARA EventParam; /* Event struct for timer event */
3847
3848 SK_MEMSET((char *) &EventParam, 0, sizeof(EventParam));
3849 EventParam.Para32[0] = SK_DRV_RX_CLEANUP_TIMER;
3850 SkTimerStart(pAC, pAC->IoBase, &pAC->DrvCleanupTimer,
3851 SK_DRV_RX_CLEANUP_TIMER_LENGTH,
3852 SKGE_DRV, SK_DRV_TIMER, EventParam);
3853}
3854
3855/*****************************************************************************
3856 *
3857 * StopDrvCleanupTimer - Stop timer to check for descriptors
3858 *
3859 * Description:
3860 * This function requests a HW-timer fo the Yukon card. The actions to
3861 * perform when this timer expires, are located in the SkDrvEvent().
3862 *
3863 * Returns: N/A
3864 */
3865static void
3866StopDrvCleanupTimer(SK_AC *pAC) {
3867 SkTimerStop(pAC, pAC->IoBase, &pAC->DrvCleanupTimer);
3868 SK_MEMSET((char *) &pAC->DrvCleanupTimer, 0, sizeof(SK_TIMER));
3869}
3870
3871/****************************************************************************/
3872/* functions for common modules *********************************************/
3873/****************************************************************************/
3874
3875
3876/*****************************************************************************
3877 *
3878 * SkDrvAllocRlmtMbuf - allocate an RLMT mbuf
3879 *
3880 * Description:
3881 * This routine returns an RLMT mbuf or NULL. The RLMT Mbuf structure
3882 * is embedded into a socket buff data area.
3883 *
3884 * Context:
3885 * runtime
3886 *
3887 * Returns:
3888 * NULL or pointer to Mbuf.
3889 */
3890SK_MBUF *SkDrvAllocRlmtMbuf(
3891SK_AC *pAC, /* pointer to adapter context */
3892SK_IOC IoC, /* the IO-context */
3893unsigned BufferSize) /* size of the requested buffer */
3894{
3895SK_MBUF *pRlmtMbuf; /* pointer to a new rlmt-mbuf structure */
3896struct sk_buff *pMsgBlock; /* pointer to a new message block */
3897
3898 pMsgBlock = alloc_skb(BufferSize + sizeof(SK_MBUF), GFP_ATOMIC);
3899 if (pMsgBlock == NULL) {
3900 return (NULL);
3901 }
3902 pRlmtMbuf = (SK_MBUF*) pMsgBlock->data;
3903 skb_reserve(pMsgBlock, sizeof(SK_MBUF));
3904 pRlmtMbuf->pNext = NULL;
3905 pRlmtMbuf->pOs = pMsgBlock;
3906 pRlmtMbuf->pData = pMsgBlock->data; /* Data buffer. */
3907 pRlmtMbuf->Size = BufferSize; /* Data buffer size. */
3908 pRlmtMbuf->Length = 0; /* Length of packet (<= Size). */
3909 return (pRlmtMbuf);
3910
3911} /* SkDrvAllocRlmtMbuf */
3912
3913
3914/*****************************************************************************
3915 *
3916 * SkDrvFreeRlmtMbuf - free an RLMT mbuf
3917 *
3918 * Description:
3919 * This routine frees one or more RLMT mbuf(s).
3920 *
3921 * Context:
3922 * runtime
3923 *
3924 * Returns:
3925 * Nothing
3926 */
3927void SkDrvFreeRlmtMbuf(
3928SK_AC *pAC, /* pointer to adapter context */
3929SK_IOC IoC, /* the IO-context */
3930SK_MBUF *pMbuf) /* size of the requested buffer */
3931{
3932SK_MBUF *pFreeMbuf;
3933SK_MBUF *pNextMbuf;
3934
3935 pFreeMbuf = pMbuf;
3936 do {
3937 pNextMbuf = pFreeMbuf->pNext;
3938 DEV_KFREE_SKB_ANY(pFreeMbuf->pOs);
3939 pFreeMbuf = pNextMbuf;
3940 } while ( pFreeMbuf != NULL );
3941} /* SkDrvFreeRlmtMbuf */
3942
3943
3944/*****************************************************************************
3945 *
3946 * SkOsGetTime - provide a time value
3947 *
3948 * Description:
3949 * This routine provides a time value. The unit is 1/HZ (defined by Linux).
3950 * It is not used for absolute time, but only for time differences.
3951 *
3952 *
3953 * Returns:
3954 * Time value
3955 */
3956SK_U64 SkOsGetTime(SK_AC *pAC)
3957{
3958 SK_U64 PrivateJiffies;
3959 SkOsGetTimeCurrent(pAC, &PrivateJiffies);
3960 return PrivateJiffies;
3961} /* SkOsGetTime */
3962
3963
3964/*****************************************************************************
3965 *
3966 * SkPciReadCfgDWord - read a 32 bit value from pci config space
3967 *
3968 * Description:
3969 * This routine reads a 32 bit value from the pci configuration
3970 * space.
3971 *
3972 * Returns:
3973 * 0 - indicate everything worked ok.
3974 * != 0 - error indication
3975 */
3976int SkPciReadCfgDWord(
3977SK_AC *pAC, /* Adapter Control structure pointer */
3978int PciAddr, /* PCI register address */
3979SK_U32 *pVal) /* pointer to store the read value */
3980{
3981 pci_read_config_dword(pAC->PciDev, PciAddr, pVal);
3982 return(0);
3983} /* SkPciReadCfgDWord */
3984
3985
3986/*****************************************************************************
3987 *
3988 * SkPciReadCfgWord - read a 16 bit value from pci config space
3989 *
3990 * Description:
3991 * This routine reads a 16 bit value from the pci configuration
3992 * space.
3993 *
3994 * Returns:
3995 * 0 - indicate everything worked ok.
3996 * != 0 - error indication
3997 */
3998int SkPciReadCfgWord(
3999SK_AC *pAC, /* Adapter Control structure pointer */
4000int PciAddr, /* PCI register address */
4001SK_U16 *pVal) /* pointer to store the read value */
4002{
4003 pci_read_config_word(pAC->PciDev, PciAddr, pVal);
4004 return(0);
4005} /* SkPciReadCfgWord */
4006
4007
4008/*****************************************************************************
4009 *
4010 * SkPciReadCfgByte - read a 8 bit value from pci config space
4011 *
4012 * Description:
4013 * This routine reads a 8 bit value from the pci configuration
4014 * space.
4015 *
4016 * Returns:
4017 * 0 - indicate everything worked ok.
4018 * != 0 - error indication
4019 */
4020int SkPciReadCfgByte(
4021SK_AC *pAC, /* Adapter Control structure pointer */
4022int PciAddr, /* PCI register address */
4023SK_U8 *pVal) /* pointer to store the read value */
4024{
4025 pci_read_config_byte(pAC->PciDev, PciAddr, pVal);
4026 return(0);
4027} /* SkPciReadCfgByte */
4028
4029
4030/*****************************************************************************
4031 *
4032 * SkPciWriteCfgWord - write a 16 bit value to pci config space
4033 *
4034 * Description:
4035 * This routine writes a 16 bit value to the pci configuration
4036 * space. The flag PciConfigUp indicates whether the config space
4037 * is accesible or must be set up first.
4038 *
4039 * Returns:
4040 * 0 - indicate everything worked ok.
4041 * != 0 - error indication
4042 */
4043int SkPciWriteCfgWord(
4044SK_AC *pAC, /* Adapter Control structure pointer */
4045int PciAddr, /* PCI register address */
4046SK_U16 Val) /* pointer to store the read value */
4047{
4048 pci_write_config_word(pAC->PciDev, PciAddr, Val);
4049 return(0);
4050} /* SkPciWriteCfgWord */
4051
4052
4053/*****************************************************************************
4054 *
4055 * SkPciWriteCfgWord - write a 8 bit value to pci config space
4056 *
4057 * Description:
4058 * This routine writes a 8 bit value to the pci configuration
4059 * space. The flag PciConfigUp indicates whether the config space
4060 * is accesible or must be set up first.
4061 *
4062 * Returns:
4063 * 0 - indicate everything worked ok.
4064 * != 0 - error indication
4065 */
4066int SkPciWriteCfgByte(
4067SK_AC *pAC, /* Adapter Control structure pointer */
4068int PciAddr, /* PCI register address */
4069SK_U8 Val) /* pointer to store the read value */
4070{
4071 pci_write_config_byte(pAC->PciDev, PciAddr, Val);
4072 return(0);
4073} /* SkPciWriteCfgByte */
4074
4075
4076/*****************************************************************************
4077 *
4078 * SkDrvEvent - handle driver events
4079 *
4080 * Description:
4081 * This function handles events from all modules directed to the driver
4082 *
4083 * Context:
4084 * Is called under protection of slow path lock.
4085 *
4086 * Returns:
4087 * 0 if everything ok
4088 * < 0 on error
4089 *
4090 */
4091int SkDrvEvent(
4092SK_AC *pAC, /* pointer to adapter context */
4093SK_IOC IoC, /* io-context */
4094SK_U32 Event, /* event-id */
4095SK_EVPARA Param) /* event-parameter */
4096{
4097SK_MBUF *pRlmtMbuf; /* pointer to a rlmt-mbuf structure */
4098struct sk_buff *pMsg; /* pointer to a message block */
4099int FromPort; /* the port from which we switch away */
4100int ToPort; /* the port we switch to */
4101SK_EVPARA NewPara; /* parameter for further events */
4102int Stat;
4103unsigned long Flags;
4104SK_BOOL DualNet;
4105
4106 switch (Event) {
4107 case SK_DRV_ADAP_FAIL:
4108 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
4109 ("ADAPTER FAIL EVENT\n"));
4110 printk("%s: Adapter failed.\n", pAC->dev[0]->name);
4111 /* disable interrupts */
4112 SK_OUT32(pAC->IoBase, B0_IMSK, 0);
4113 /* cgoos */
4114 break;
4115 case SK_DRV_PORT_FAIL:
4116 FromPort = Param.Para32[0];
4117 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
4118 ("PORT FAIL EVENT, Port: %d\n", FromPort));
4119 if (FromPort == 0) {
4120 printk("%s: Port A failed.\n", pAC->dev[0]->name);
4121 } else {
4122 printk("%s: Port B failed.\n", pAC->dev[1]->name);
4123 }
4124 /* cgoos */
4125 break;
4126 case SK_DRV_PORT_RESET: /* SK_U32 PortIdx */
4127 /* action list 4 */
4128 FromPort = Param.Para32[0];
4129 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
4130 ("PORT RESET EVENT, Port: %d ", FromPort));
4131 NewPara.Para64 = FromPort;
4132 SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_XMAC_RESET, NewPara);
4133 spin_lock_irqsave(
4134 &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
4135 Flags);
4136
4137 SkGeStopPort(pAC, IoC, FromPort, SK_STOP_ALL, SK_HARD_RST);
4138 netif_carrier_off(pAC->dev[Param.Para32[0]]);
4139 spin_unlock_irqrestore(
4140 &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
4141 Flags);
4142
4143 /* clear rx ring from received frames */
4144 ReceiveIrq(pAC, &pAC->RxPort[FromPort], SK_FALSE);
4145
4146 ClearTxRing(pAC, &pAC->TxPort[FromPort][TX_PRIO_LOW]);
4147 spin_lock_irqsave(
4148 &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
4149 Flags);
4150
4151 /* tschilling: Handling of return value inserted. */
4152 if (SkGeInitPort(pAC, IoC, FromPort)) {
4153 if (FromPort == 0) {
4154 printk("%s: SkGeInitPort A failed.\n", pAC->dev[0]->name);
4155 } else {
4156 printk("%s: SkGeInitPort B failed.\n", pAC->dev[1]->name);
4157 }
4158 }
4159 SkAddrMcUpdate(pAC,IoC, FromPort);
4160 PortReInitBmu(pAC, FromPort);
4161 SkGePollTxD(pAC, IoC, FromPort, SK_TRUE);
4162 ClearAndStartRx(pAC, FromPort);
4163 spin_unlock_irqrestore(
4164 &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
4165 Flags);
4166 break;
4167 case SK_DRV_NET_UP: /* SK_U32 PortIdx */
4168 { struct net_device *dev = pAC->dev[Param.Para32[0]];
4169 /* action list 5 */
4170 FromPort = Param.Para32[0];
4171 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
4172 ("NET UP EVENT, Port: %d ", Param.Para32[0]));
4173 /* Mac update */
4174 SkAddrMcUpdate(pAC,IoC, FromPort);
4175
4176 if (DoPrintInterfaceChange) {
4177 printk("%s: network connection up using"
4178 " port %c\n", pAC->dev[Param.Para32[0]]->name, 'A'+Param.Para32[0]);
4179
4180 /* tschilling: Values changed according to LinkSpeedUsed. */
4181 Stat = pAC->GIni.GP[FromPort].PLinkSpeedUsed;
4182 if (Stat == SK_LSPEED_STAT_10MBPS) {
4183 printk(" speed: 10\n");
4184 } else if (Stat == SK_LSPEED_STAT_100MBPS) {
4185 printk(" speed: 100\n");
4186 } else if (Stat == SK_LSPEED_STAT_1000MBPS) {
4187 printk(" speed: 1000\n");
4188 } else {
4189 printk(" speed: unknown\n");
4190 }
4191
4192
4193 Stat = pAC->GIni.GP[FromPort].PLinkModeStatus;
4194 if (Stat == SK_LMODE_STAT_AUTOHALF ||
4195 Stat == SK_LMODE_STAT_AUTOFULL) {
4196 printk(" autonegotiation: yes\n");
4197 }
4198 else {
4199 printk(" autonegotiation: no\n");
4200 }
4201 if (Stat == SK_LMODE_STAT_AUTOHALF ||
4202 Stat == SK_LMODE_STAT_HALF) {
4203 printk(" duplex mode: half\n");
4204 }
4205 else {
4206 printk(" duplex mode: full\n");
4207 }
4208 Stat = pAC->GIni.GP[FromPort].PFlowCtrlStatus;
4209 if (Stat == SK_FLOW_STAT_REM_SEND ) {
4210 printk(" flowctrl: remote send\n");
4211 }
4212 else if (Stat == SK_FLOW_STAT_LOC_SEND ){
4213 printk(" flowctrl: local send\n");
4214 }
4215 else if (Stat == SK_FLOW_STAT_SYMMETRIC ){
4216 printk(" flowctrl: symmetric\n");
4217 }
4218 else {
4219 printk(" flowctrl: none\n");
4220 }
4221
4222 /* tschilling: Check against CopperType now. */
4223 if ((pAC->GIni.GICopperType == SK_TRUE) &&
4224 (pAC->GIni.GP[FromPort].PLinkSpeedUsed ==
4225 SK_LSPEED_STAT_1000MBPS)) {
4226 Stat = pAC->GIni.GP[FromPort].PMSStatus;
4227 if (Stat == SK_MS_STAT_MASTER ) {
4228 printk(" role: master\n");
4229 }
4230 else if (Stat == SK_MS_STAT_SLAVE ) {
4231 printk(" role: slave\n");
4232 }
4233 else {
4234 printk(" role: ???\n");
4235 }
4236 }
4237
4238 /*
4239 Display dim (dynamic interrupt moderation)
4240 informations
4241 */
4242 if (pAC->DynIrqModInfo.IntModTypeSelect == C_INT_MOD_STATIC)
4243 printk(" irq moderation: static (%d ints/sec)\n",
4244 pAC->DynIrqModInfo.MaxModIntsPerSec);
4245 else if (pAC->DynIrqModInfo.IntModTypeSelect == C_INT_MOD_DYNAMIC)
4246 printk(" irq moderation: dynamic (%d ints/sec)\n",
4247 pAC->DynIrqModInfo.MaxModIntsPerSec);
4248 else
4249 printk(" irq moderation: disabled\n");
4250
4251
4252 printk(" scatter-gather: %s\n",
4253 (dev->features & NETIF_F_SG) ? "enabled" : "disabled");
4254 printk(" tx-checksum: %s\n",
4255 (dev->features & NETIF_F_IP_CSUM) ? "enabled" : "disabled");
4256 printk(" rx-checksum: %s\n",
4257 pAC->RxPort[Param.Para32[0]].RxCsum ? "enabled" : "disabled");
4258
4259 } else {
4260 DoPrintInterfaceChange = SK_TRUE;
4261 }
4262
4263 if ((Param.Para32[0] != pAC->ActivePort) &&
4264 (pAC->RlmtNets == 1)) {
4265 NewPara.Para32[0] = pAC->ActivePort;
4266 NewPara.Para32[1] = Param.Para32[0];
4267 SkEventQueue(pAC, SKGE_DRV, SK_DRV_SWITCH_INTERN,
4268 NewPara);
4269 }
4270
4271 /* Inform the world that link protocol is up. */
4272 netif_carrier_on(dev);
4273 break;
4274 }
4275 case SK_DRV_NET_DOWN: /* SK_U32 Reason */
4276 /* action list 7 */
4277 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
4278 ("NET DOWN EVENT "));
4279 if (DoPrintInterfaceChange) {
4280 printk("%s: network connection down\n",
4281 pAC->dev[Param.Para32[1]]->name);
4282 } else {
4283 DoPrintInterfaceChange = SK_TRUE;
4284 }
4285 netif_carrier_off(pAC->dev[Param.Para32[1]]);
4286 break;
4287 case SK_DRV_SWITCH_HARD: /* SK_U32 FromPortIdx SK_U32 ToPortIdx */
4288 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
4289 ("PORT SWITCH HARD "));
4290 case SK_DRV_SWITCH_SOFT: /* SK_U32 FromPortIdx SK_U32 ToPortIdx */
4291 /* action list 6 */
4292 printk("%s: switching to port %c\n", pAC->dev[0]->name,
4293 'A'+Param.Para32[1]);
4294 case SK_DRV_SWITCH_INTERN: /* SK_U32 FromPortIdx SK_U32 ToPortIdx */
4295 FromPort = Param.Para32[0];
4296 ToPort = Param.Para32[1];
4297 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
4298 ("PORT SWITCH EVENT, From: %d To: %d (Pref %d) ",
4299 FromPort, ToPort, pAC->Rlmt.Net[0].PrefPort));
4300 NewPara.Para64 = FromPort;
4301 SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_XMAC_RESET, NewPara);
4302 NewPara.Para64 = ToPort;
4303 SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_XMAC_RESET, NewPara);
4304 spin_lock_irqsave(
4305 &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
4306 Flags);
4307 spin_lock(&pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock);
4308 SkGeStopPort(pAC, IoC, FromPort, SK_STOP_ALL, SK_SOFT_RST);
4309 SkGeStopPort(pAC, IoC, ToPort, SK_STOP_ALL, SK_SOFT_RST);
4310 spin_unlock(&pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock);
4311 spin_unlock_irqrestore(
4312 &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
4313 Flags);
4314
4315 ReceiveIrq(pAC, &pAC->RxPort[FromPort], SK_FALSE); /* clears rx ring */
4316 ReceiveIrq(pAC, &pAC->RxPort[ToPort], SK_FALSE); /* clears rx ring */
4317
4318 ClearTxRing(pAC, &pAC->TxPort[FromPort][TX_PRIO_LOW]);
4319 ClearTxRing(pAC, &pAC->TxPort[ToPort][TX_PRIO_LOW]);
4320 spin_lock_irqsave(
4321 &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
4322 Flags);
4323 spin_lock(&pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock);
4324 pAC->ActivePort = ToPort;
4325#if 0
4326 SetQueueSizes(pAC);
4327#else
4328 /* tschilling: New common function with minimum size check. */
4329 DualNet = SK_FALSE;
4330 if (pAC->RlmtNets == 2) {
4331 DualNet = SK_TRUE;
4332 }
4333
4334 if (SkGeInitAssignRamToQueues(
4335 pAC,
4336 pAC->ActivePort,
4337 DualNet)) {
4338 spin_unlock(&pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock);
4339 spin_unlock_irqrestore(
4340 &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
4341 Flags);
4342 printk("SkGeInitAssignRamToQueues failed.\n");
4343 break;
4344 }
4345#endif
4346 /* tschilling: Handling of return values inserted. */
4347 if (SkGeInitPort(pAC, IoC, FromPort) ||
4348 SkGeInitPort(pAC, IoC, ToPort)) {
4349 printk("%s: SkGeInitPort failed.\n", pAC->dev[0]->name);
4350 }
4351 if (Event == SK_DRV_SWITCH_SOFT) {
4352 SkMacRxTxEnable(pAC, IoC, FromPort);
4353 }
4354 SkMacRxTxEnable(pAC, IoC, ToPort);
4355 SkAddrSwap(pAC, IoC, FromPort, ToPort);
4356 SkAddrMcUpdate(pAC, IoC, FromPort);
4357 SkAddrMcUpdate(pAC, IoC, ToPort);
4358 PortReInitBmu(pAC, FromPort);
4359 PortReInitBmu(pAC, ToPort);
4360 SkGePollTxD(pAC, IoC, FromPort, SK_TRUE);
4361 SkGePollTxD(pAC, IoC, ToPort, SK_TRUE);
4362 ClearAndStartRx(pAC, FromPort);
4363 ClearAndStartRx(pAC, ToPort);
4364 spin_unlock(&pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock);
4365 spin_unlock_irqrestore(
4366 &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
4367 Flags);
4368 break;
4369 case SK_DRV_RLMT_SEND: /* SK_MBUF *pMb */
4370 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
4371 ("RLS "));
4372 pRlmtMbuf = (SK_MBUF*) Param.pParaPtr;
4373 pMsg = (struct sk_buff*) pRlmtMbuf->pOs;
4374 skb_put(pMsg, pRlmtMbuf->Length);
4375 if (XmitFrame(pAC, &pAC->TxPort[pRlmtMbuf->PortIdx][TX_PRIO_LOW],
4376 pMsg) < 0)
4377
4378 DEV_KFREE_SKB_ANY(pMsg);
4379 break;
4380 case SK_DRV_TIMER:
4381 if (Param.Para32[0] == SK_DRV_MODERATION_TIMER) {
4382 /*
4383 ** expiration of the moderation timer implies that
4384 ** dynamic moderation is to be applied
4385 */
4386 SkDimStartModerationTimer(pAC);
4387 SkDimModerate(pAC);
4388 if (pAC->DynIrqModInfo.DisplayStats) {
4389 SkDimDisplayModerationSettings(pAC);
4390 }
4391 } else if (Param.Para32[0] == SK_DRV_RX_CLEANUP_TIMER) {
4392 /*
4393 ** check if we need to check for descriptors which
4394 ** haven't been handled the last millisecs
4395 */
4396 StartDrvCleanupTimer(pAC);
4397 if (pAC->GIni.GIMacsFound == 2) {
4398 ReceiveIrq(pAC, &pAC->RxPort[1], SK_FALSE);
4399 }
4400 ReceiveIrq(pAC, &pAC->RxPort[0], SK_FALSE);
4401 } else {
4402 printk("Expiration of unknown timer\n");
4403 }
4404 break;
4405 default:
4406 break;
4407 }
4408 SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
4409 ("END EVENT "));
4410
4411 return (0);
4412} /* SkDrvEvent */
4413
4414
4415/*****************************************************************************
4416 *
4417 * SkErrorLog - log errors
4418 *
4419 * Description:
4420 * This function logs errors to the system buffer and to the console
4421 *
4422 * Returns:
4423 * 0 if everything ok
4424 * < 0 on error
4425 *
4426 */
4427void SkErrorLog(
4428SK_AC *pAC,
4429int ErrClass,
4430int ErrNum,
4431char *pErrorMsg)
4432{
4433char ClassStr[80];
4434
4435 switch (ErrClass) {
4436 case SK_ERRCL_OTHER:
4437 strcpy(ClassStr, "Other error");
4438 break;
4439 case SK_ERRCL_CONFIG:
4440 strcpy(ClassStr, "Configuration error");
4441 break;
4442 case SK_ERRCL_INIT:
4443 strcpy(ClassStr, "Initialization error");
4444 break;
4445 case SK_ERRCL_NORES:
4446 strcpy(ClassStr, "Out of resources error");
4447 break;
4448 case SK_ERRCL_SW:
4449 strcpy(ClassStr, "internal Software error");
4450 break;
4451 case SK_ERRCL_HW:
4452 strcpy(ClassStr, "Hardware failure");
4453 break;
4454 case SK_ERRCL_COMM:
4455 strcpy(ClassStr, "Communication error");
4456 break;
4457 }
4458 printk(KERN_INFO "%s: -- ERROR --\n Class: %s\n"
4459 " Nr: 0x%x\n Msg: %s\n", pAC->dev[0]->name,
4460 ClassStr, ErrNum, pErrorMsg);
4461
4462} /* SkErrorLog */
4463
4464#ifdef SK_DIAG_SUPPORT
4465
4466/*****************************************************************************
4467 *
4468 * SkDrvEnterDiagMode - handles DIAG attach request
4469 *
4470 * Description:
4471 * Notify the kernel to NOT access the card any longer due to DIAG
4472 * Deinitialize the Card
4473 *
4474 * Returns:
4475 * int
4476 */
4477int SkDrvEnterDiagMode(
4478SK_AC *pAc) /* pointer to adapter context */
4479{
4480 DEV_NET *pNet = netdev_priv(pAc->dev[0]);
4481 SK_AC *pAC = pNet->pAC;
4482
4483 SK_MEMCPY(&(pAc->PnmiBackup), &(pAc->PnmiStruct),
4484 sizeof(SK_PNMI_STRUCT_DATA));
4485
4486 pAC->DiagModeActive = DIAG_ACTIVE;
4487 if (pAC->BoardLevel > SK_INIT_DATA) {
4488 if (netif_running(pAC->dev[0])) {
4489 pAC->WasIfUp[0] = SK_TRUE;
4490 pAC->DiagFlowCtrl = SK_TRUE; /* for SkGeClose */
4491 DoPrintInterfaceChange = SK_FALSE;
4492 SkDrvDeInitAdapter(pAC, 0); /* performs SkGeClose */
4493 } else {
4494 pAC->WasIfUp[0] = SK_FALSE;
4495 }
4496 if (pNet != netdev_priv(pAC->dev[1])) {
4497 pNet = netdev_priv(pAC->dev[1]);
4498 if (netif_running(pAC->dev[1])) {
4499 pAC->WasIfUp[1] = SK_TRUE;
4500 pAC->DiagFlowCtrl = SK_TRUE; /* for SkGeClose */
4501 DoPrintInterfaceChange = SK_FALSE;
4502 SkDrvDeInitAdapter(pAC, 1); /* do SkGeClose */
4503 } else {
4504 pAC->WasIfUp[1] = SK_FALSE;
4505 }
4506 }
4507 pAC->BoardLevel = SK_INIT_DATA;
4508 }
4509 return(0);
4510}
4511
4512/*****************************************************************************
4513 *
4514 * SkDrvLeaveDiagMode - handles DIAG detach request
4515 *
4516 * Description:
4517 * Notify the kernel to may access the card again after use by DIAG
4518 * Initialize the Card
4519 *
4520 * Returns:
4521 * int
4522 */
4523int SkDrvLeaveDiagMode(
4524SK_AC *pAc) /* pointer to adapter control context */
4525{
4526 SK_MEMCPY(&(pAc->PnmiStruct), &(pAc->PnmiBackup),
4527 sizeof(SK_PNMI_STRUCT_DATA));
4528 pAc->DiagModeActive = DIAG_NOTACTIVE;
4529 pAc->Pnmi.DiagAttached = SK_DIAG_IDLE;
4530 if (pAc->WasIfUp[0] == SK_TRUE) {
4531 pAc->DiagFlowCtrl = SK_TRUE; /* for SkGeClose */
4532 DoPrintInterfaceChange = SK_FALSE;
4533 SkDrvInitAdapter(pAc, 0); /* first device */
4534 }
4535 if (pAc->WasIfUp[1] == SK_TRUE) {
4536 pAc->DiagFlowCtrl = SK_TRUE; /* for SkGeClose */
4537 DoPrintInterfaceChange = SK_FALSE;
4538 SkDrvInitAdapter(pAc, 1); /* second device */
4539 }
4540 return(0);
4541}
4542
4543/*****************************************************************************
4544 *
4545 * ParseDeviceNbrFromSlotName - Evaluate PCI device number
4546 *
4547 * Description:
4548 * This function parses the PCI slot name information string and will
4549 * retrieve the devcie number out of it. The slot_name maintianed by
4550 * linux is in the form of '02:0a.0', whereas the first two characters
4551 * represent the bus number in hex (in the sample above this is
4552 * pci bus 0x02) and the next two characters the device number (0x0a).
4553 *
4554 * Returns:
4555 * SK_U32: The device number from the PCI slot name
4556 */
4557
4558static SK_U32 ParseDeviceNbrFromSlotName(
4559const char *SlotName) /* pointer to pci slot name eg. '02:0a.0' */
4560{
4561 char *CurrCharPos = (char *) SlotName;
4562 int FirstNibble = -1;
4563 int SecondNibble = -1;
4564 SK_U32 Result = 0;
4565
4566 while (*CurrCharPos != '\0') {
4567 if (*CurrCharPos == ':') {
4568 while (*CurrCharPos != '.') {
4569 CurrCharPos++;
4570 if ( (*CurrCharPos >= '0') &&
4571 (*CurrCharPos <= '9')) {
4572 if (FirstNibble == -1) {
4573 /* dec. value for '0' */
4574 FirstNibble = *CurrCharPos - 48;
4575 } else {
4576 SecondNibble = *CurrCharPos - 48;
4577 }
4578 } else if ( (*CurrCharPos >= 'a') &&
4579 (*CurrCharPos <= 'f') ) {
4580 if (FirstNibble == -1) {
4581 FirstNibble = *CurrCharPos - 87;
4582 } else {
4583 SecondNibble = *CurrCharPos - 87;
4584 }
4585 } else {
4586 Result = 0;
4587 }
4588 }
4589
4590 Result = FirstNibble;
4591 Result = Result << 4; /* first nibble is higher one */
4592 Result = Result | SecondNibble;
4593 }
4594 CurrCharPos++; /* next character */
4595 }
4596 return (Result);
4597}
4598
4599/****************************************************************************
4600 *
4601 * SkDrvDeInitAdapter - deinitialize adapter (this function is only
4602 * called if Diag attaches to that card)
4603 *
4604 * Description:
4605 * Close initialized adapter.
4606 *
4607 * Returns:
4608 * 0 - on success
4609 * error code - on error
4610 */
4611static int SkDrvDeInitAdapter(
4612SK_AC *pAC, /* pointer to adapter context */
4613int devNbr) /* what device is to be handled */
4614{
4615 struct SK_NET_DEVICE *dev;
4616
4617 dev = pAC->dev[devNbr];
4618
4619 /* On Linux 2.6 the network driver does NOT mess with reference
4620 ** counts. The driver MUST be able to be unloaded at any time
4621 ** due to the possibility of hotplug.
4622 */
4623 if (SkGeClose(dev) != 0) {
4624 return (-1);
4625 }
4626 return (0);
4627
4628} /* SkDrvDeInitAdapter() */
4629
4630/****************************************************************************
4631 *
4632 * SkDrvInitAdapter - Initialize adapter (this function is only
4633 * called if Diag deattaches from that card)
4634 *
4635 * Description:
4636 * Close initialized adapter.
4637 *
4638 * Returns:
4639 * 0 - on success
4640 * error code - on error
4641 */
4642static int SkDrvInitAdapter(
4643SK_AC *pAC, /* pointer to adapter context */
4644int devNbr) /* what device is to be handled */
4645{
4646 struct SK_NET_DEVICE *dev;
4647
4648 dev = pAC->dev[devNbr];
4649
4650 if (SkGeOpen(dev) != 0) {
4651 return (-1);
4652 }
4653
4654 /*
4655 ** Use correct MTU size and indicate to kernel TX queue can be started
4656 */
4657 if (SkGeChangeMtu(dev, dev->mtu) != 0) {
4658 return (-1);
4659 }
4660 return (0);
4661
4662} /* SkDrvInitAdapter */
4663
4664#endif
4665
4666#ifdef DEBUG
4667/****************************************************************************/
4668/* "debug only" section *****************************************************/
4669/****************************************************************************/
4670
4671
4672/*****************************************************************************
4673 *
4674 * DumpMsg - print a frame
4675 *
4676 * Description:
4677 * This function prints frames to the system logfile/to the console.
4678 *
4679 * Returns: N/A
4680 *
4681 */
4682static void DumpMsg(struct sk_buff *skb, char *str)
4683{
4684 int msglen;
4685
4686 if (skb == NULL) {
4687 printk("DumpMsg(): NULL-Message\n");
4688 return;
4689 }
4690
4691 if (skb->data == NULL) {
4692 printk("DumpMsg(): Message empty\n");
4693 return;
4694 }
4695
4696 msglen = skb->len;
4697 if (msglen > 64)
4698 msglen = 64;
4699
4700 printk("--- Begin of message from %s , len %d (from %d) ----\n", str, msglen, skb->len);
4701
4702 DumpData((char *)skb->data, msglen);
4703
4704 printk("------- End of message ---------\n");
4705} /* DumpMsg */
4706
4707
4708
4709/*****************************************************************************
4710 *
4711 * DumpData - print a data area
4712 *
4713 * Description:
4714 * This function prints a area of data to the system logfile/to the
4715 * console.
4716 *
4717 * Returns: N/A
4718 *
4719 */
4720static void DumpData(char *p, int size)
4721{
4722register int i;
4723int haddr, addr;
4724char hex_buffer[180];
4725char asc_buffer[180];
4726char HEXCHAR[] = "0123456789ABCDEF";
4727
4728 addr = 0;
4729 haddr = 0;
4730 hex_buffer[0] = 0;
4731 asc_buffer[0] = 0;
4732 for (i=0; i < size; ) {
4733 if (*p >= '0' && *p <='z')
4734 asc_buffer[addr] = *p;
4735 else
4736 asc_buffer[addr] = '.';
4737 addr++;
4738 asc_buffer[addr] = 0;
4739 hex_buffer[haddr] = HEXCHAR[(*p & 0xf0) >> 4];
4740 haddr++;
4741 hex_buffer[haddr] = HEXCHAR[*p & 0x0f];
4742 haddr++;
4743 hex_buffer[haddr] = ' ';
4744 haddr++;
4745 hex_buffer[haddr] = 0;
4746 p++;
4747 i++;
4748 if (i%16 == 0) {
4749 printk("%s %s\n", hex_buffer, asc_buffer);
4750 addr = 0;
4751 haddr = 0;
4752 }
4753 }
4754} /* DumpData */
4755
4756
4757/*****************************************************************************
4758 *
4759 * DumpLong - print a data area as long values
4760 *
4761 * Description:
4762 * This function prints a area of data to the system logfile/to the
4763 * console.
4764 *
4765 * Returns: N/A
4766 *
4767 */
4768static void DumpLong(char *pc, int size)
4769{
4770register int i;
4771int haddr, addr;
4772char hex_buffer[180];
4773char asc_buffer[180];
4774char HEXCHAR[] = "0123456789ABCDEF";
4775long *p;
4776int l;
4777
4778 addr = 0;
4779 haddr = 0;
4780 hex_buffer[0] = 0;
4781 asc_buffer[0] = 0;
4782 p = (long*) pc;
4783 for (i=0; i < size; ) {
4784 l = (long) *p;
4785 hex_buffer[haddr] = HEXCHAR[(l >> 28) & 0xf];
4786 haddr++;
4787 hex_buffer[haddr] = HEXCHAR[(l >> 24) & 0xf];
4788 haddr++;
4789 hex_buffer[haddr] = HEXCHAR[(l >> 20) & 0xf];
4790 haddr++;
4791 hex_buffer[haddr] = HEXCHAR[(l >> 16) & 0xf];
4792 haddr++;
4793 hex_buffer[haddr] = HEXCHAR[(l >> 12) & 0xf];
4794 haddr++;
4795 hex_buffer[haddr] = HEXCHAR[(l >> 8) & 0xf];
4796 haddr++;
4797 hex_buffer[haddr] = HEXCHAR[(l >> 4) & 0xf];
4798 haddr++;
4799 hex_buffer[haddr] = HEXCHAR[l & 0x0f];
4800 haddr++;
4801 hex_buffer[haddr] = ' ';
4802 haddr++;
4803 hex_buffer[haddr] = 0;
4804 p++;
4805 i++;
4806 if (i%8 == 0) {
4807 printk("%4x %s\n", (i-8)*4, hex_buffer);
4808 haddr = 0;
4809 }
4810 }
4811 printk("------------------------\n");
4812} /* DumpLong */
4813
4814#endif
4815
4816static int __devinit skge_probe_one(struct pci_dev *pdev,
4817 const struct pci_device_id *ent)
4818{
4819 SK_AC *pAC;
4820 DEV_NET *pNet = NULL;
4821 struct net_device *dev = NULL;
4822 static int boards_found = 0;
4823 int error = -ENODEV;
4824 int using_dac = 0;
4825 char DeviceStr[80];
4826
4827 if (pci_enable_device(pdev))
4828 goto out;
4829
4830 /* Configure DMA attributes. */
4831 if (sizeof(dma_addr_t) > sizeof(u32) &&
4832 !(error = pci_set_dma_mask(pdev, DMA_64BIT_MASK))) {
4833 using_dac = 1;
4834 error = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
4835 if (error < 0) {
4836 printk(KERN_ERR "sk98lin %s unable to obtain 64 bit DMA "
4837 "for consistent allocations\n", pci_name(pdev));
4838 goto out_disable_device;
4839 }
4840 } else {
4841 error = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
4842 if (error) {
4843 printk(KERN_ERR "sk98lin %s no usable DMA configuration\n",
4844 pci_name(pdev));
4845 goto out_disable_device;
4846 }
4847 }
4848
4849 error = -ENOMEM;
4850 dev = alloc_etherdev(sizeof(DEV_NET));
4851 if (!dev) {
4852 printk(KERN_ERR "sk98lin: unable to allocate etherdev "
4853 "structure!\n");
4854 goto out_disable_device;
4855 }
4856
4857 pNet = netdev_priv(dev);
4858 pNet->pAC = kzalloc(sizeof(SK_AC), GFP_KERNEL);
4859 if (!pNet->pAC) {
4860 printk(KERN_ERR "sk98lin: unable to allocate adapter "
4861 "structure!\n");
4862 goto out_free_netdev;
4863 }
4864
4865 pAC = pNet->pAC;
4866 pAC->PciDev = pdev;
4867
4868 pAC->dev[0] = dev;
4869 pAC->dev[1] = dev;
4870 pAC->CheckQueue = SK_FALSE;
4871
4872 dev->irq = pdev->irq;
4873
4874 error = SkGeInitPCI(pAC);
4875 if (error) {
4876 printk(KERN_ERR "sk98lin: PCI setup failed: %i\n", error);
4877 goto out_free_netdev;
4878 }
4879
4880 SET_MODULE_OWNER(dev);
4881 dev->open = &SkGeOpen;
4882 dev->stop = &SkGeClose;
4883 dev->hard_start_xmit = &SkGeXmit;
4884 dev->get_stats = &SkGeStats;
4885 dev->set_multicast_list = &SkGeSetRxMode;
4886 dev->set_mac_address = &SkGeSetMacAddr;
4887 dev->do_ioctl = &SkGeIoctl;
4888 dev->change_mtu = &SkGeChangeMtu;
4889#ifdef CONFIG_NET_POLL_CONTROLLER
4890 dev->poll_controller = &SkGePollController;
4891#endif
4892 SET_NETDEV_DEV(dev, &pdev->dev);
4893 SET_ETHTOOL_OPS(dev, &SkGeEthtoolOps);
4894
4895 /* Use only if yukon hardware */
4896 if (pAC->ChipsetType) {
4897#ifdef USE_SK_TX_CHECKSUM
4898 dev->features |= NETIF_F_IP_CSUM;
4899#endif
4900#ifdef SK_ZEROCOPY
4901 dev->features |= NETIF_F_SG;
4902#endif
4903#ifdef USE_SK_RX_CHECKSUM
4904 pAC->RxPort[0].RxCsum = 1;
4905#endif
4906 }
4907
4908 if (using_dac)
4909 dev->features |= NETIF_F_HIGHDMA;
4910
4911 pAC->Index = boards_found++;
4912
4913 error = SkGeBoardInit(dev, pAC);
4914 if (error)
4915 goto out_free_netdev;
4916
4917 /* Read Adapter name from VPD */
4918 if (ProductStr(pAC, DeviceStr, sizeof(DeviceStr)) != 0) {
4919 error = -EIO;
4920 printk(KERN_ERR "sk98lin: Could not read VPD data.\n");
4921 goto out_free_resources;
4922 }
4923
4924 /* Register net device */
4925 error = register_netdev(dev);
4926 if (error) {
4927 printk(KERN_ERR "sk98lin: Could not register device.\n");
4928 goto out_free_resources;
4929 }
4930
4931 /* Print adapter specific string from vpd */
4932 printk("%s: %s\n", dev->name, DeviceStr);
4933
4934 /* Print configuration settings */
4935 printk(" PrefPort:%c RlmtMode:%s\n",
4936 'A' + pAC->Rlmt.Net[0].Port[pAC->Rlmt.Net[0].PrefPort]->PortNumber,
4937 (pAC->RlmtMode==0) ? "Check Link State" :
4938 ((pAC->RlmtMode==1) ? "Check Link State" :
4939 ((pAC->RlmtMode==3) ? "Check Local Port" :
4940 ((pAC->RlmtMode==7) ? "Check Segmentation" :
4941 ((pAC->RlmtMode==17) ? "Dual Check Link State" :"Error")))));
4942
4943 SkGeYellowLED(pAC, pAC->IoBase, 1);
4944
4945 memcpy(&dev->dev_addr, &pAC->Addr.Net[0].CurrentMacAddress, 6);
4946 memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
4947
4948 pNet->PortNr = 0;
4949 pNet->NetNr = 0;
4950
4951 boards_found++;
4952
4953 pci_set_drvdata(pdev, dev);
4954
4955 /* More then one port found */
4956 if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) {
4957 dev = alloc_etherdev(sizeof(DEV_NET));
4958 if (!dev) {
4959 printk(KERN_ERR "sk98lin: unable to allocate etherdev "
4960 "structure!\n");
4961 goto single_port;
4962 }
4963
4964 pNet = netdev_priv(dev);
4965 pNet->PortNr = 1;
4966 pNet->NetNr = 1;
4967 pNet->pAC = pAC;
4968
4969 dev->open = &SkGeOpen;
4970 dev->stop = &SkGeClose;
4971 dev->hard_start_xmit = &SkGeXmit;
4972 dev->get_stats = &SkGeStats;
4973 dev->set_multicast_list = &SkGeSetRxMode;
4974 dev->set_mac_address = &SkGeSetMacAddr;
4975 dev->do_ioctl = &SkGeIoctl;
4976 dev->change_mtu = &SkGeChangeMtu;
4977 SET_NETDEV_DEV(dev, &pdev->dev);
4978 SET_ETHTOOL_OPS(dev, &SkGeEthtoolOps);
4979
4980 if (pAC->ChipsetType) {
4981#ifdef USE_SK_TX_CHECKSUM
4982 dev->features |= NETIF_F_IP_CSUM;
4983#endif
4984#ifdef SK_ZEROCOPY
4985 dev->features |= NETIF_F_SG;
4986#endif
4987#ifdef USE_SK_RX_CHECKSUM
4988 pAC->RxPort[1].RxCsum = 1;
4989#endif
4990 }
4991
4992 if (using_dac)
4993 dev->features |= NETIF_F_HIGHDMA;
4994
4995 error = register_netdev(dev);
4996 if (error) {
4997 printk(KERN_ERR "sk98lin: Could not register device"
4998 " for second port. (%d)\n", error);
4999 free_netdev(dev);
5000 goto single_port;
5001 }
5002
5003 pAC->dev[1] = dev;
5004 memcpy(&dev->dev_addr,
5005 &pAC->Addr.Net[1].CurrentMacAddress, 6);
5006 memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
5007
5008 printk("%s: %s\n", dev->name, DeviceStr);
5009 printk(" PrefPort:B RlmtMode:Dual Check Link State\n");
5010 }
5011
5012single_port:
5013
5014 /* Save the hardware revision */
5015 pAC->HWRevision = (((pAC->GIni.GIPciHwRev >> 4) & 0x0F)*10) +
5016 (pAC->GIni.GIPciHwRev & 0x0F);
5017
5018 /* Set driver globals */
5019 pAC->Pnmi.pDriverFileName = DRIVER_FILE_NAME;
5020 pAC->Pnmi.pDriverReleaseDate = DRIVER_REL_DATE;
5021
5022 memset(&pAC->PnmiBackup, 0, sizeof(SK_PNMI_STRUCT_DATA));
5023 memcpy(&pAC->PnmiBackup, &pAC->PnmiStruct, sizeof(SK_PNMI_STRUCT_DATA));
5024
5025 return 0;
5026
5027 out_free_resources:
5028 FreeResources(dev);
5029 out_free_netdev:
5030 free_netdev(dev);
5031 out_disable_device:
5032 pci_disable_device(pdev);
5033 out:
5034 return error;
5035}
5036
5037static void __devexit skge_remove_one(struct pci_dev *pdev)
5038{
5039 struct net_device *dev = pci_get_drvdata(pdev);
5040 DEV_NET *pNet = netdev_priv(dev);
5041 SK_AC *pAC = pNet->pAC;
5042 struct net_device *otherdev = pAC->dev[1];
5043
5044 unregister_netdev(dev);
5045
5046 SkGeYellowLED(pAC, pAC->IoBase, 0);
5047
5048 if (pAC->BoardLevel == SK_INIT_RUN) {
5049 SK_EVPARA EvPara;
5050 unsigned long Flags;
5051
5052 /* board is still alive */
5053 spin_lock_irqsave(&pAC->SlowPathLock, Flags);
5054 EvPara.Para32[0] = 0;
5055 EvPara.Para32[1] = -1;
5056 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
5057 EvPara.Para32[0] = 1;
5058 EvPara.Para32[1] = -1;
5059 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
5060 SkEventDispatcher(pAC, pAC->IoBase);
5061 /* disable interrupts */
5062 SK_OUT32(pAC->IoBase, B0_IMSK, 0);
5063 SkGeDeInit(pAC, pAC->IoBase);
5064 spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
5065 pAC->BoardLevel = SK_INIT_DATA;
5066 /* We do NOT check here, if IRQ was pending, of course*/
5067 }
5068
5069 if (pAC->BoardLevel == SK_INIT_IO) {
5070 /* board is still alive */
5071 SkGeDeInit(pAC, pAC->IoBase);
5072 pAC->BoardLevel = SK_INIT_DATA;
5073 }
5074
5075 FreeResources(dev);
5076 free_netdev(dev);
5077 if (otherdev != dev)
5078 free_netdev(otherdev);
5079 kfree(pAC);
5080}
5081
5082#ifdef CONFIG_PM
5083static int skge_suspend(struct pci_dev *pdev, pm_message_t state)
5084{
5085 struct net_device *dev = pci_get_drvdata(pdev);
5086 DEV_NET *pNet = netdev_priv(dev);
5087 SK_AC *pAC = pNet->pAC;
5088 struct net_device *otherdev = pAC->dev[1];
5089
5090 if (netif_running(dev)) {
5091 netif_carrier_off(dev);
5092 DoPrintInterfaceChange = SK_FALSE;
5093 SkDrvDeInitAdapter(pAC, 0); /* performs SkGeClose */
5094 netif_device_detach(dev);
5095 }
5096 if (otherdev != dev) {
5097 if (netif_running(otherdev)) {
5098 netif_carrier_off(otherdev);
5099 DoPrintInterfaceChange = SK_FALSE;
5100 SkDrvDeInitAdapter(pAC, 1); /* performs SkGeClose */
5101 netif_device_detach(otherdev);
5102 }
5103 }
5104
5105 pci_save_state(pdev);
5106 pci_enable_wake(pdev, pci_choose_state(pdev, state), 0);
5107 if (pAC->AllocFlag & SK_ALLOC_IRQ) {
5108 free_irq(dev->irq, dev);
5109 }
5110 pci_disable_device(pdev);
5111 pci_set_power_state(pdev, pci_choose_state(pdev, state));
5112
5113 return 0;
5114}
5115
5116static int skge_resume(struct pci_dev *pdev)
5117{
5118 struct net_device *dev = pci_get_drvdata(pdev);
5119 DEV_NET *pNet = netdev_priv(dev);
5120 SK_AC *pAC = pNet->pAC;
5121 struct net_device *otherdev = pAC->dev[1];
5122 int ret;
5123
5124 pci_set_power_state(pdev, PCI_D0);
5125 pci_restore_state(pdev);
5126 ret = pci_enable_device(pdev);
5127 if (ret) {
5128 printk(KERN_WARNING "sk98lin: unable to enable device %s "
5129 "in resume\n", dev->name);
5130 goto err_out;
5131 }
5132 pci_set_master(pdev);
5133 if (pAC->GIni.GIMacsFound == 2)
5134 ret = request_irq(dev->irq, SkGeIsr, IRQF_SHARED, "sk98lin", dev);
5135 else
5136 ret = request_irq(dev->irq, SkGeIsrOnePort, IRQF_SHARED, "sk98lin", dev);
5137 if (ret) {
5138 printk(KERN_WARNING "sk98lin: unable to acquire IRQ %d\n", dev->irq);
5139 ret = -EBUSY;
5140 goto err_out_disable_pdev;
5141 }
5142
5143 netif_device_attach(dev);
5144 if (netif_running(dev)) {
5145 DoPrintInterfaceChange = SK_FALSE;
5146 SkDrvInitAdapter(pAC, 0); /* first device */
5147 }
5148 if (otherdev != dev) {
5149 netif_device_attach(otherdev);
5150 if (netif_running(otherdev)) {
5151 DoPrintInterfaceChange = SK_FALSE;
5152 SkDrvInitAdapter(pAC, 1); /* second device */
5153 }
5154 }
5155
5156 return 0;
5157
5158err_out_disable_pdev:
5159 pci_disable_device(pdev);
5160err_out:
5161 pAC->AllocFlag &= ~SK_ALLOC_IRQ;
5162 dev->irq = 0;
5163 return ret;
5164}
5165#else
5166#define skge_suspend NULL
5167#define skge_resume NULL
5168#endif
5169
5170static struct pci_device_id skge_pci_tbl[] = {
5171 { PCI_VENDOR_ID_3COM, 0x1700, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
5172 { PCI_VENDOR_ID_3COM, 0x80eb, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
5173 { PCI_VENDOR_ID_SYSKONNECT, 0x4300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
5174 { PCI_VENDOR_ID_SYSKONNECT, 0x4320, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
5175/* DLink card does not have valid VPD so this driver gags
5176 * { PCI_VENDOR_ID_DLINK, 0x4c00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
5177 */
5178 { PCI_VENDOR_ID_MARVELL, 0x4320, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
5179 { PCI_VENDOR_ID_MARVELL, 0x5005, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
5180 { PCI_VENDOR_ID_CNET, 0x434e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
5181 { PCI_VENDOR_ID_LINKSYS, 0x1032, PCI_ANY_ID, 0x0015, },
5182 { PCI_VENDOR_ID_LINKSYS, 0x1064, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
5183 { 0 }
5184};
5185
5186MODULE_DEVICE_TABLE(pci, skge_pci_tbl);
5187
5188static struct pci_driver skge_driver = {
5189 .name = "sk98lin",
5190 .id_table = skge_pci_tbl,
5191 .probe = skge_probe_one,
5192 .remove = __devexit_p(skge_remove_one),
5193 .suspend = skge_suspend,
5194 .resume = skge_resume,
5195};
5196
5197static int __init skge_init(void)
5198{
5199 printk(KERN_NOTICE "sk98lin: driver has been replaced by the skge driver"
5200 " and is scheduled for removal\n");
5201
5202 return pci_register_driver(&skge_driver);
5203}
5204
5205static void __exit skge_exit(void)
5206{
5207 pci_unregister_driver(&skge_driver);
5208}
5209
5210module_init(skge_init);
5211module_exit(skge_exit);
diff --git a/drivers/net/sk98lin/skgehwt.c b/drivers/net/sk98lin/skgehwt.c
deleted file mode 100644
index db670993c2df..000000000000
--- a/drivers/net/sk98lin/skgehwt.c
+++ /dev/null
@@ -1,171 +0,0 @@
1/******************************************************************************
2 *
3 * Name: skgehwt.c
4 * Project: Gigabit Ethernet Adapters, Event Scheduler Module
5 * Version: $Revision: 1.15 $
6 * Date: $Date: 2003/09/16 13:41:23 $
7 * Purpose: Hardware Timer
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect GmbH.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25/*
26 * Event queue and dispatcher
27 */
28#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
29static const char SysKonnectFileId[] =
30 "@(#) $Id: skgehwt.c,v 1.15 2003/09/16 13:41:23 rschmidt Exp $ (C) Marvell.";
31#endif
32
33#include "h/skdrv1st.h" /* Driver Specific Definitions */
34#include "h/skdrv2nd.h" /* Adapter Control- and Driver specific Def. */
35
36#ifdef __C2MAN__
37/*
38 * Hardware Timer function queue management.
39 */
40intro()
41{}
42#endif
43
44/*
45 * Prototypes of local functions.
46 */
47#define SK_HWT_MAX (65000)
48
49/* correction factor */
50#define SK_HWT_FAC (1000 * (SK_U32)pAC->GIni.GIHstClkFact / 100)
51
52/*
53 * Initialize hardware timer.
54 *
55 * Must be called during init level 1.
56 */
57void SkHwtInit(
58SK_AC *pAC, /* Adapters context */
59SK_IOC Ioc) /* IoContext */
60{
61 pAC->Hwt.TStart = 0 ;
62 pAC->Hwt.TStop = 0 ;
63 pAC->Hwt.TActive = SK_FALSE;
64
65 SkHwtStop(pAC, Ioc);
66}
67
68/*
69 *
70 * Start hardware timer (clock ticks are 16us).
71 *
72 */
73void SkHwtStart(
74SK_AC *pAC, /* Adapters context */
75SK_IOC Ioc, /* IoContext */
76SK_U32 Time) /* Time in units of 16us to load the timer with. */
77{
78 SK_U32 Cnt;
79
80 if (Time > SK_HWT_MAX)
81 Time = SK_HWT_MAX;
82
83 pAC->Hwt.TStart = Time;
84 pAC->Hwt.TStop = 0L;
85
86 Cnt = Time;
87
88 /*
89 * if time < 16 us
90 * time = 16 us
91 */
92 if (!Cnt) {
93 Cnt++;
94 }
95
96 SK_OUT32(Ioc, B2_TI_INI, Cnt * SK_HWT_FAC);
97
98 SK_OUT16(Ioc, B2_TI_CTRL, TIM_START); /* Start timer. */
99
100 pAC->Hwt.TActive = SK_TRUE;
101}
102
103/*
104 * Stop hardware timer.
105 * and clear the timer IRQ
106 */
107void SkHwtStop(
108SK_AC *pAC, /* Adapters context */
109SK_IOC Ioc) /* IoContext */
110{
111 SK_OUT16(Ioc, B2_TI_CTRL, TIM_STOP);
112
113 SK_OUT16(Ioc, B2_TI_CTRL, TIM_CLR_IRQ);
114
115 pAC->Hwt.TActive = SK_FALSE;
116}
117
118
119/*
120 * Stop hardware timer and read time elapsed since last start.
121 *
122 * returns
123 * The elapsed time since last start in units of 16us.
124 *
125 */
126SK_U32 SkHwtRead(
127SK_AC *pAC, /* Adapters context */
128SK_IOC Ioc) /* IoContext */
129{
130 SK_U32 TRead;
131 SK_U32 IStatus;
132
133 if (pAC->Hwt.TActive) {
134
135 SkHwtStop(pAC, Ioc);
136
137 SK_IN32(Ioc, B2_TI_VAL, &TRead);
138 TRead /= SK_HWT_FAC;
139
140 SK_IN32(Ioc, B0_ISRC, &IStatus);
141
142 /* Check if timer expired (or wraped around) */
143 if ((TRead > pAC->Hwt.TStart) || (IStatus & IS_TIMINT)) {
144
145 SkHwtStop(pAC, Ioc);
146
147 pAC->Hwt.TStop = pAC->Hwt.TStart;
148 }
149 else {
150
151 pAC->Hwt.TStop = pAC->Hwt.TStart - TRead;
152 }
153 }
154 return(pAC->Hwt.TStop);
155}
156
157/*
158 * interrupt source= timer
159 */
160void SkHwtIsr(
161SK_AC *pAC, /* Adapters context */
162SK_IOC Ioc) /* IoContext */
163{
164 SkHwtStop(pAC, Ioc);
165
166 pAC->Hwt.TStop = pAC->Hwt.TStart;
167
168 SkTimerDone(pAC, Ioc);
169}
170
171/* End of file */
diff --git a/drivers/net/sk98lin/skgeinit.c b/drivers/net/sk98lin/skgeinit.c
deleted file mode 100644
index 67f1d6a5c15d..000000000000
--- a/drivers/net/sk98lin/skgeinit.c
+++ /dev/null
@@ -1,2005 +0,0 @@
1/******************************************************************************
2 *
3 * Name: skgeinit.c
4 * Project: Gigabit Ethernet Adapters, Common Modules
5 * Version: $Revision: 1.97 $
6 * Date: $Date: 2003/10/02 16:45:31 $
7 * Purpose: Contains functions to initialize the adapter
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25#include "h/skdrv1st.h"
26#include "h/skdrv2nd.h"
27
28/* global variables ***********************************************************/
29
30/* local variables ************************************************************/
31
32#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
33static const char SysKonnectFileId[] =
34 "@(#) $Id: skgeinit.c,v 1.97 2003/10/02 16:45:31 rschmidt Exp $ (C) Marvell.";
35#endif
36
37struct s_QOffTab {
38 int RxQOff; /* Receive Queue Address Offset */
39 int XsQOff; /* Sync Tx Queue Address Offset */
40 int XaQOff; /* Async Tx Queue Address Offset */
41};
42static struct s_QOffTab QOffTab[] = {
43 {Q_R1, Q_XS1, Q_XA1}, {Q_R2, Q_XS2, Q_XA2}
44};
45
46struct s_Config {
47 char ScanString[8];
48 SK_U32 Value;
49};
50
51static struct s_Config OemConfig = {
52 {'O','E','M','_','C','o','n','f'},
53#ifdef SK_OEM_CONFIG
54 OEM_CONFIG_VALUE,
55#else
56 0,
57#endif
58};
59
60/******************************************************************************
61 *
62 * SkGePollTxD() - Enable / Disable Descriptor Polling of TxD Rings
63 *
64 * Description:
65 * Enable or disable the descriptor polling of the transmit descriptor
66 * ring(s) (TxD) for port 'Port'.
67 * The new configuration is *not* saved over any SkGeStopPort() and
68 * SkGeInitPort() calls.
69 *
70 * Returns:
71 * nothing
72 */
73void SkGePollTxD(
74SK_AC *pAC, /* adapter context */
75SK_IOC IoC, /* IO context */
76int Port, /* Port Index (MAC_1 + n) */
77SK_BOOL PollTxD) /* SK_TRUE (enable pol.), SK_FALSE (disable pol.) */
78{
79 SK_GEPORT *pPrt;
80 SK_U32 DWord;
81
82 pPrt = &pAC->GIni.GP[Port];
83
84 DWord = (SK_U32)(PollTxD ? CSR_ENA_POL : CSR_DIS_POL);
85
86 if (pPrt->PXSQSize != 0) {
87 SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), DWord);
88 }
89
90 if (pPrt->PXAQSize != 0) {
91 SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), DWord);
92 }
93} /* SkGePollTxD */
94
95
96/******************************************************************************
97 *
98 * SkGeYellowLED() - Switch the yellow LED on or off.
99 *
100 * Description:
101 * Switch the yellow LED on or off.
102 *
103 * Note:
104 * This function may be called any time after SkGeInit(Level 1).
105 *
106 * Returns:
107 * nothing
108 */
109void SkGeYellowLED(
110SK_AC *pAC, /* adapter context */
111SK_IOC IoC, /* IO context */
112int State) /* yellow LED state, 0 = OFF, 0 != ON */
113{
114 if (State == 0) {
115 /* Switch yellow LED OFF */
116 SK_OUT8(IoC, B0_LED, LED_STAT_OFF);
117 }
118 else {
119 /* Switch yellow LED ON */
120 SK_OUT8(IoC, B0_LED, LED_STAT_ON);
121 }
122} /* SkGeYellowLED */
123
124
125#if (!defined(SK_SLIM) || defined(GENESIS))
126/******************************************************************************
127 *
128 * SkGeXmitLED() - Modify the Operational Mode of a transmission LED.
129 *
130 * Description:
131 * The Rx or Tx LED which is specified by 'Led' will be
132 * enabled, disabled or switched on in test mode.
133 *
134 * Note:
135 * 'Led' must contain the address offset of the LEDs INI register.
136 *
137 * Usage:
138 * SkGeXmitLED(pAC, IoC, MR_ADDR(Port, TX_LED_INI), SK_LED_ENA);
139 *
140 * Returns:
141 * nothing
142 */
143void SkGeXmitLED(
144SK_AC *pAC, /* adapter context */
145SK_IOC IoC, /* IO context */
146int Led, /* offset to the LED Init Value register */
147int Mode) /* Mode may be SK_LED_DIS, SK_LED_ENA, SK_LED_TST */
148{
149 SK_U32 LedIni;
150
151 switch (Mode) {
152 case SK_LED_ENA:
153 LedIni = SK_XMIT_DUR * (SK_U32)pAC->GIni.GIHstClkFact / 100;
154 SK_OUT32(IoC, Led + XMIT_LED_INI, LedIni);
155 SK_OUT8(IoC, Led + XMIT_LED_CTRL, LED_START);
156 break;
157 case SK_LED_TST:
158 SK_OUT8(IoC, Led + XMIT_LED_TST, LED_T_ON);
159 SK_OUT32(IoC, Led + XMIT_LED_CNT, 100);
160 SK_OUT8(IoC, Led + XMIT_LED_CTRL, LED_START);
161 break;
162 case SK_LED_DIS:
163 default:
164 /*
165 * Do NOT stop the LED Timer here. The LED might be
166 * in on state. But it needs to go off.
167 */
168 SK_OUT32(IoC, Led + XMIT_LED_CNT, 0);
169 SK_OUT8(IoC, Led + XMIT_LED_TST, LED_T_OFF);
170 break;
171 }
172
173 /*
174 * 1000BT: The Transmit LED is driven by the PHY.
175 * But the default LED configuration is used for
176 * Level One and Broadcom PHYs.
177 * (Broadcom: It may be that PHY_B_PEC_EN_LTR has to be set.)
178 * (In this case it has to be added here. But we will see. XXX)
179 */
180} /* SkGeXmitLED */
181#endif /* !SK_SLIM || GENESIS */
182
183
184/******************************************************************************
185 *
186 * DoCalcAddr() - Calculates the start and the end address of a queue.
187 *
188 * Description:
189 * This function calculates the start and the end address of a queue.
190 * Afterwards the 'StartVal' is incremented to the next start position.
191 * If the port is already initialized the calculated values
192 * will be checked against the configured values and an
193 * error will be returned, if they are not equal.
194 * If the port is not initialized the values will be written to
195 * *StartAdr and *EndAddr.
196 *
197 * Returns:
198 * 0: success
199 * 1: configuration error
200 */
201static int DoCalcAddr(
202SK_AC *pAC, /* adapter context */
203SK_GEPORT SK_FAR *pPrt, /* port index */
204int QuSize, /* size of the queue to configure in kB */
205SK_U32 SK_FAR *StartVal, /* start value for address calculation */
206SK_U32 SK_FAR *QuStartAddr,/* start addr to calculate */
207SK_U32 SK_FAR *QuEndAddr) /* end address to calculate */
208{
209 SK_U32 EndVal;
210 SK_U32 NextStart;
211 int Rtv;
212
213 Rtv = 0;
214 if (QuSize == 0) {
215 EndVal = *StartVal;
216 NextStart = EndVal;
217 }
218 else {
219 EndVal = *StartVal + ((SK_U32)QuSize * 1024) - 1;
220 NextStart = EndVal + 1;
221 }
222
223 if (pPrt->PState >= SK_PRT_INIT) {
224 if (*StartVal != *QuStartAddr || EndVal != *QuEndAddr) {
225 Rtv = 1;
226 }
227 }
228 else {
229 *QuStartAddr = *StartVal;
230 *QuEndAddr = EndVal;
231 }
232
233 *StartVal = NextStart;
234 return(Rtv);
235} /* DoCalcAddr */
236
237/******************************************************************************
238 *
239 * SkGeInitAssignRamToQueues() - allocate default queue sizes
240 *
241 * Description:
242 * This function assigns the memory to the different queues and ports.
243 * When DualNet is set to SK_TRUE all ports get the same amount of memory.
244 * Otherwise the first port gets most of the memory and all the
245 * other ports just the required minimum.
246 * This function can only be called when pAC->GIni.GIRamSize and
247 * pAC->GIni.GIMacsFound have been initialized, usually this happens
248 * at init level 1
249 *
250 * Returns:
251 * 0 - ok
252 * 1 - invalid input values
253 * 2 - not enough memory
254 */
255
256int SkGeInitAssignRamToQueues(
257SK_AC *pAC, /* Adapter context */
258int ActivePort, /* Active Port in RLMT mode */
259SK_BOOL DualNet) /* adapter context */
260{
261 int i;
262 int UsedKilobytes; /* memory already assigned */
263 int ActivePortKilobytes; /* memory available for active port */
264 SK_GEPORT *pGePort;
265
266 UsedKilobytes = 0;
267
268 if (ActivePort >= pAC->GIni.GIMacsFound) {
269 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
270 ("SkGeInitAssignRamToQueues: ActivePort (%d) invalid\n",
271 ActivePort));
272 return(1);
273 }
274 if (((pAC->GIni.GIMacsFound * (SK_MIN_RXQ_SIZE + SK_MIN_TXQ_SIZE)) +
275 ((RAM_QUOTA_SYNC == 0) ? 0 : SK_MIN_TXQ_SIZE)) > pAC->GIni.GIRamSize) {
276 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
277 ("SkGeInitAssignRamToQueues: Not enough memory (%d)\n",
278 pAC->GIni.GIRamSize));
279 return(2);
280 }
281
282 if (DualNet) {
283 /* every port gets the same amount of memory */
284 ActivePortKilobytes = pAC->GIni.GIRamSize / pAC->GIni.GIMacsFound;
285 for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
286
287 pGePort = &pAC->GIni.GP[i];
288
289 /* take away the minimum memory for active queues */
290 ActivePortKilobytes -= (SK_MIN_RXQ_SIZE + SK_MIN_TXQ_SIZE);
291
292 /* receive queue gets the minimum + 80% of the rest */
293 pGePort->PRxQSize = (int) (ROUND_QUEUE_SIZE_KB((
294 ActivePortKilobytes * (unsigned long) RAM_QUOTA_RX) / 100))
295 + SK_MIN_RXQ_SIZE;
296
297 ActivePortKilobytes -= (pGePort->PRxQSize - SK_MIN_RXQ_SIZE);
298
299 /* synchronous transmit queue */
300 pGePort->PXSQSize = 0;
301
302 /* asynchronous transmit queue */
303 pGePort->PXAQSize = (int) ROUND_QUEUE_SIZE_KB(ActivePortKilobytes +
304 SK_MIN_TXQ_SIZE);
305 }
306 }
307 else {
308 /* Rlmt Mode or single link adapter */
309
310 /* Set standby queue size defaults for all standby ports */
311 for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
312
313 if (i != ActivePort) {
314 pGePort = &pAC->GIni.GP[i];
315
316 pGePort->PRxQSize = SK_MIN_RXQ_SIZE;
317 pGePort->PXAQSize = SK_MIN_TXQ_SIZE;
318 pGePort->PXSQSize = 0;
319
320 /* Count used RAM */
321 UsedKilobytes += pGePort->PRxQSize + pGePort->PXAQSize;
322 }
323 }
324 /* what's left? */
325 ActivePortKilobytes = pAC->GIni.GIRamSize - UsedKilobytes;
326
327 /* assign it to the active port */
328 /* first take away the minimum memory */
329 ActivePortKilobytes -= (SK_MIN_RXQ_SIZE + SK_MIN_TXQ_SIZE);
330 pGePort = &pAC->GIni.GP[ActivePort];
331
332 /* receive queue get's the minimum + 80% of the rest */
333 pGePort->PRxQSize = (int) (ROUND_QUEUE_SIZE_KB((ActivePortKilobytes *
334 (unsigned long) RAM_QUOTA_RX) / 100)) + SK_MIN_RXQ_SIZE;
335
336 ActivePortKilobytes -= (pGePort->PRxQSize - SK_MIN_RXQ_SIZE);
337
338 /* synchronous transmit queue */
339 pGePort->PXSQSize = 0;
340
341 /* asynchronous transmit queue */
342 pGePort->PXAQSize = (int) ROUND_QUEUE_SIZE_KB(ActivePortKilobytes) +
343 SK_MIN_TXQ_SIZE;
344 }
345#ifdef VCPU
346 VCPUprintf(0, "PRxQSize=%u, PXSQSize=%u, PXAQSize=%u\n",
347 pGePort->PRxQSize, pGePort->PXSQSize, pGePort->PXAQSize);
348#endif /* VCPU */
349
350 return(0);
351} /* SkGeInitAssignRamToQueues */
352
353/******************************************************************************
354 *
355 * SkGeCheckQSize() - Checks the Adapters Queue Size Configuration
356 *
357 * Description:
358 * This function verifies the Queue Size Configuration specified
359 * in the variables PRxQSize, PXSQSize, and PXAQSize of all
360 * used ports.
361 * This requirements must be fullfilled to have a valid configuration:
362 * - The size of all queues must not exceed GIRamSize.
363 * - The queue sizes must be specified in units of 8 kB.
364 * - The size of Rx queues of available ports must not be
365 * smaller than 16 kB.
366 * - The size of at least one Tx queue (synch. or asynch.)
367 * of available ports must not be smaller than 16 kB
368 * when Jumbo Frames are used.
369 * - The RAM start and end addresses must not be changed
370 * for ports which are already initialized.
371 * Furthermore SkGeCheckQSize() defines the Start and End Addresses
372 * of all ports and stores them into the HWAC port structure.
373 *
374 * Returns:
375 * 0: Queue Size Configuration valid
376 * 1: Queue Size Configuration invalid
377 */
378static int SkGeCheckQSize(
379SK_AC *pAC, /* adapter context */
380int Port) /* port index */
381{
382 SK_GEPORT *pPrt;
383 int i;
384 int Rtv;
385 int Rtv2;
386 SK_U32 StartAddr;
387#ifndef SK_SLIM
388 int UsedMem; /* total memory used (max. found ports) */
389#endif
390
391 Rtv = 0;
392
393#ifndef SK_SLIM
394
395 UsedMem = 0;
396 for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
397 pPrt = &pAC->GIni.GP[i];
398
399 if ((pPrt->PRxQSize & QZ_UNITS) != 0 ||
400 (pPrt->PXSQSize & QZ_UNITS) != 0 ||
401 (pPrt->PXAQSize & QZ_UNITS) != 0) {
402
403 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E012, SKERR_HWI_E012MSG);
404 return(1);
405 }
406
407 if (i == Port && pPrt->PRxQSize < SK_MIN_RXQ_SIZE) {
408 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E011, SKERR_HWI_E011MSG);
409 return(1);
410 }
411
412 /*
413 * the size of at least one Tx queue (synch. or asynch.) has to be > 0.
414 * if Jumbo Frames are used, this size has to be >= 16 kB.
415 */
416 if ((i == Port && pPrt->PXSQSize == 0 && pPrt->PXAQSize == 0) ||
417 (pAC->GIni.GIPortUsage == SK_JUMBO_LINK &&
418 ((pPrt->PXSQSize > 0 && pPrt->PXSQSize < SK_MIN_TXQ_SIZE) ||
419 (pPrt->PXAQSize > 0 && pPrt->PXAQSize < SK_MIN_TXQ_SIZE)))) {
420 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E023, SKERR_HWI_E023MSG);
421 return(1);
422 }
423
424 UsedMem += pPrt->PRxQSize + pPrt->PXSQSize + pPrt->PXAQSize;
425 }
426
427 if (UsedMem > pAC->GIni.GIRamSize) {
428 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E012, SKERR_HWI_E012MSG);
429 return(1);
430 }
431#endif /* !SK_SLIM */
432
433 /* Now start address calculation */
434 StartAddr = pAC->GIni.GIRamOffs;
435 for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
436 pPrt = &pAC->GIni.GP[i];
437
438 /* Calculate/Check values for the receive queue */
439 Rtv2 = DoCalcAddr(pAC, pPrt, pPrt->PRxQSize, &StartAddr,
440 &pPrt->PRxQRamStart, &pPrt->PRxQRamEnd);
441 Rtv |= Rtv2;
442
443 /* Calculate/Check values for the synchronous Tx queue */
444 Rtv2 = DoCalcAddr(pAC, pPrt, pPrt->PXSQSize, &StartAddr,
445 &pPrt->PXsQRamStart, &pPrt->PXsQRamEnd);
446 Rtv |= Rtv2;
447
448 /* Calculate/Check values for the asynchronous Tx queue */
449 Rtv2 = DoCalcAddr(pAC, pPrt, pPrt->PXAQSize, &StartAddr,
450 &pPrt->PXaQRamStart, &pPrt->PXaQRamEnd);
451 Rtv |= Rtv2;
452
453 if (Rtv) {
454 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E013, SKERR_HWI_E013MSG);
455 return(1);
456 }
457 }
458
459 return(0);
460} /* SkGeCheckQSize */
461
462
463#ifdef GENESIS
464/******************************************************************************
465 *
466 * SkGeInitMacArb() - Initialize the MAC Arbiter
467 *
468 * Description:
469 * This function initializes the MAC Arbiter.
470 * It must not be called if there is still an
471 * initialized or active port.
472 *
473 * Returns:
474 * nothing
475 */
476static void SkGeInitMacArb(
477SK_AC *pAC, /* adapter context */
478SK_IOC IoC) /* IO context */
479{
480 /* release local reset */
481 SK_OUT16(IoC, B3_MA_TO_CTRL, MA_RST_CLR);
482
483 /* configure timeout values */
484 SK_OUT8(IoC, B3_MA_TOINI_RX1, SK_MAC_TO_53);
485 SK_OUT8(IoC, B3_MA_TOINI_RX2, SK_MAC_TO_53);
486 SK_OUT8(IoC, B3_MA_TOINI_TX1, SK_MAC_TO_53);
487 SK_OUT8(IoC, B3_MA_TOINI_TX2, SK_MAC_TO_53);
488
489 SK_OUT8(IoC, B3_MA_RCINI_RX1, 0);
490 SK_OUT8(IoC, B3_MA_RCINI_RX2, 0);
491 SK_OUT8(IoC, B3_MA_RCINI_TX1, 0);
492 SK_OUT8(IoC, B3_MA_RCINI_TX2, 0);
493
494 /* recovery values are needed for XMAC II Rev. B2 only */
495 /* Fast Output Enable Mode was intended to use with Rev. B2, but now? */
496
497 /*
498 * There is no start or enable button to push, therefore
499 * the MAC arbiter is configured and enabled now.
500 */
501} /* SkGeInitMacArb */
502
503
504/******************************************************************************
505 *
506 * SkGeInitPktArb() - Initialize the Packet Arbiter
507 *
508 * Description:
509 * This function initializes the Packet Arbiter.
510 * It must not be called if there is still an
511 * initialized or active port.
512 *
513 * Returns:
514 * nothing
515 */
516static void SkGeInitPktArb(
517SK_AC *pAC, /* adapter context */
518SK_IOC IoC) /* IO context */
519{
520 /* release local reset */
521 SK_OUT16(IoC, B3_PA_CTRL, PA_RST_CLR);
522
523 /* configure timeout values */
524 SK_OUT16(IoC, B3_PA_TOINI_RX1, SK_PKT_TO_MAX);
525 SK_OUT16(IoC, B3_PA_TOINI_RX2, SK_PKT_TO_MAX);
526 SK_OUT16(IoC, B3_PA_TOINI_TX1, SK_PKT_TO_MAX);
527 SK_OUT16(IoC, B3_PA_TOINI_TX2, SK_PKT_TO_MAX);
528
529 /*
530 * enable timeout timers if jumbo frames not used
531 * NOTE: the packet arbiter timeout interrupt is needed for
532 * half duplex hangup workaround
533 */
534 if (pAC->GIni.GIPortUsage != SK_JUMBO_LINK) {
535 if (pAC->GIni.GIMacsFound == 1) {
536 SK_OUT16(IoC, B3_PA_CTRL, PA_ENA_TO_TX1);
537 }
538 else {
539 SK_OUT16(IoC, B3_PA_CTRL, PA_ENA_TO_TX1 | PA_ENA_TO_TX2);
540 }
541 }
542} /* SkGeInitPktArb */
543#endif /* GENESIS */
544
545
546/******************************************************************************
547 *
548 * SkGeInitMacFifo() - Initialize the MAC FIFOs
549 *
550 * Description:
551 * Initialize all MAC FIFOs of the specified port
552 *
553 * Returns:
554 * nothing
555 */
556static void SkGeInitMacFifo(
557SK_AC *pAC, /* adapter context */
558SK_IOC IoC, /* IO context */
559int Port) /* Port Index (MAC_1 + n) */
560{
561 SK_U16 Word;
562#ifdef VCPU
563 SK_U32 DWord;
564#endif /* VCPU */
565 /*
566 * For each FIFO:
567 * - release local reset
568 * - use default value for MAC FIFO size
569 * - setup defaults for the control register
570 * - enable the FIFO
571 */
572
573#ifdef GENESIS
574 if (pAC->GIni.GIGenesis) {
575 /* Configure Rx MAC FIFO */
576 SK_OUT8(IoC, MR_ADDR(Port, RX_MFF_CTRL2), MFF_RST_CLR);
577 SK_OUT16(IoC, MR_ADDR(Port, RX_MFF_CTRL1), MFF_RX_CTRL_DEF);
578 SK_OUT8(IoC, MR_ADDR(Port, RX_MFF_CTRL2), MFF_ENA_OP_MD);
579
580 /* Configure Tx MAC FIFO */
581 SK_OUT8(IoC, MR_ADDR(Port, TX_MFF_CTRL2), MFF_RST_CLR);
582 SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_TX_CTRL_DEF);
583 SK_OUT8(IoC, MR_ADDR(Port, TX_MFF_CTRL2), MFF_ENA_OP_MD);
584
585 /* Enable frame flushing if jumbo frames used */
586 if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) {
587 SK_OUT16(IoC, MR_ADDR(Port, RX_MFF_CTRL1), MFF_ENA_FLUSH);
588 }
589 }
590#endif /* GENESIS */
591
592#ifdef YUKON
593 if (pAC->GIni.GIYukon) {
594 /* set Rx GMAC FIFO Flush Mask */
595 SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_FL_MSK), (SK_U16)RX_FF_FL_DEF_MSK);
596
597 Word = (SK_U16)GMF_RX_CTRL_DEF;
598
599 /* disable Rx GMAC FIFO Flush for YUKON-Lite Rev. A0 only */
600 if (pAC->GIni.GIYukonLite && pAC->GIni.GIChipId == CHIP_ID_YUKON) {
601
602 Word &= ~GMF_RX_F_FL_ON;
603 }
604
605 /* Configure Rx MAC FIFO */
606 SK_OUT8(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), (SK_U8)GMF_RST_CLR);
607 SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), Word);
608
609 /* set Rx GMAC FIFO Flush Threshold (default: 0x0a -> 56 bytes) */
610 SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_FL_THR), RX_GMF_FL_THR_DEF);
611
612 /* Configure Tx MAC FIFO */
613 SK_OUT8(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), (SK_U8)GMF_RST_CLR);
614 SK_OUT16(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), (SK_U16)GMF_TX_CTRL_DEF);
615
616#ifdef VCPU
617 SK_IN32(IoC, MR_ADDR(Port, RX_GMF_AF_THR), &DWord);
618 SK_IN32(IoC, MR_ADDR(Port, TX_GMF_AE_THR), &DWord);
619#endif /* VCPU */
620
621 /* set Tx GMAC FIFO Almost Empty Threshold */
622/* SK_OUT32(IoC, MR_ADDR(Port, TX_GMF_AE_THR), 0); */
623 }
624#endif /* YUKON */
625
626} /* SkGeInitMacFifo */
627
628#ifdef SK_LNK_SYNC_CNT
629/******************************************************************************
630 *
631 * SkGeLoadLnkSyncCnt() - Load the Link Sync Counter and starts counting
632 *
633 * Description:
634 * This function starts the Link Sync Counter of the specified
635 * port and enables the generation of an Link Sync IRQ.
636 * The Link Sync Counter may be used to detect an active link,
637 * if autonegotiation is not used.
638 *
639 * Note:
640 * o To ensure receiving the Link Sync Event the LinkSyncCounter
641 * should be initialized BEFORE clearing the XMAC's reset!
642 * o Enable IS_LNK_SYNC_M1 and IS_LNK_SYNC_M2 after calling this
643 * function.
644 *
645 * Returns:
646 * nothing
647 */
648void SkGeLoadLnkSyncCnt(
649SK_AC *pAC, /* adapter context */
650SK_IOC IoC, /* IO context */
651int Port, /* Port Index (MAC_1 + n) */
652SK_U32 CntVal) /* Counter value */
653{
654 SK_U32 OrgIMsk;
655 SK_U32 NewIMsk;
656 SK_U32 ISrc;
657 SK_BOOL IrqPend;
658
659 /* stop counter */
660 SK_OUT8(IoC, MR_ADDR(Port, LNK_SYNC_CTRL), LED_STOP);
661
662 /*
663 * ASIC problem:
664 * Each time starting the Link Sync Counter an IRQ is generated
665 * by the adapter. See problem report entry from 21.07.98
666 *
667 * Workaround: Disable Link Sync IRQ and clear the unexpeced IRQ
668 * if no IRQ is already pending.
669 */
670 IrqPend = SK_FALSE;
671 SK_IN32(IoC, B0_ISRC, &ISrc);
672 SK_IN32(IoC, B0_IMSK, &OrgIMsk);
673 if (Port == MAC_1) {
674 NewIMsk = OrgIMsk & ~IS_LNK_SYNC_M1;
675 if ((ISrc & IS_LNK_SYNC_M1) != 0) {
676 IrqPend = SK_TRUE;
677 }
678 }
679 else {
680 NewIMsk = OrgIMsk & ~IS_LNK_SYNC_M2;
681 if ((ISrc & IS_LNK_SYNC_M2) != 0) {
682 IrqPend = SK_TRUE;
683 }
684 }
685 if (!IrqPend) {
686 SK_OUT32(IoC, B0_IMSK, NewIMsk);
687 }
688
689 /* load counter */
690 SK_OUT32(IoC, MR_ADDR(Port, LNK_SYNC_INI), CntVal);
691
692 /* start counter */
693 SK_OUT8(IoC, MR_ADDR(Port, LNK_SYNC_CTRL), LED_START);
694
695 if (!IrqPend) {
696 /* clear the unexpected IRQ, and restore the interrupt mask */
697 SK_OUT8(IoC, MR_ADDR(Port, LNK_SYNC_CTRL), LED_CLR_IRQ);
698 SK_OUT32(IoC, B0_IMSK, OrgIMsk);
699 }
700} /* SkGeLoadLnkSyncCnt*/
701#endif /* SK_LNK_SYNC_CNT */
702
703#if defined(SK_DIAG) || defined(SK_CFG_SYNC)
704/******************************************************************************
705 *
706 * SkGeCfgSync() - Configure synchronous bandwidth for this port.
707 *
708 * Description:
709 * This function may be used to configure synchronous bandwidth
710 * to the specified port. This may be done any time after
711 * initializing the port. The configuration values are NOT saved
712 * in the HWAC port structure and will be overwritten any
713 * time when stopping and starting the port.
714 * Any values for the synchronous configuration will be ignored
715 * if the size of the synchronous queue is zero!
716 *
717 * The default configuration for the synchronous service is
718 * TXA_ENA_FSYNC. This means if the size of
719 * the synchronous queue is unequal zero but no specific
720 * synchronous bandwidth is configured, the synchronous queue
721 * will always have the 'unlimited' transmit priority!
722 *
723 * This mode will be restored if the synchronous bandwidth is
724 * deallocated ('IntTime' = 0 and 'LimCount' = 0).
725 *
726 * Returns:
727 * 0: success
728 * 1: parameter configuration error
729 * 2: try to configure quality of service although no
730 * synchronous queue is configured
731 */
732int SkGeCfgSync(
733SK_AC *pAC, /* adapter context */
734SK_IOC IoC, /* IO context */
735int Port, /* Port Index (MAC_1 + n) */
736SK_U32 IntTime, /* Interval Timer Value in units of 8ns */
737SK_U32 LimCount, /* Number of bytes to transfer during IntTime */
738int SyncMode) /* Sync Mode: TXA_ENA_ALLOC | TXA_DIS_ALLOC | 0 */
739{
740 int Rtv;
741
742 Rtv = 0;
743
744 /* check the parameters */
745 if (LimCount > IntTime ||
746 (LimCount == 0 && IntTime != 0) ||
747 (LimCount != 0 && IntTime == 0)) {
748
749 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E010, SKERR_HWI_E010MSG);
750 return(1);
751 }
752
753 if (pAC->GIni.GP[Port].PXSQSize == 0) {
754 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E009, SKERR_HWI_E009MSG);
755 return(2);
756 }
757
758 /* calculate register values */
759 IntTime = (IntTime / 2) * pAC->GIni.GIHstClkFact / 100;
760 LimCount = LimCount / 8;
761
762 if (IntTime > TXA_MAX_VAL || LimCount > TXA_MAX_VAL) {
763 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E010, SKERR_HWI_E010MSG);
764 return(1);
765 }
766
767 /*
768 * - Enable 'Force Sync' to ensure the synchronous queue
769 * has the priority while configuring the new values.
770 * - Also 'disable alloc' to ensure the settings complies
771 * to the SyncMode parameter.
772 * - Disable 'Rate Control' to configure the new values.
773 * - write IntTime and LimCount
774 * - start 'Rate Control' and disable 'Force Sync'
775 * if Interval Timer or Limit Counter not zero.
776 */
777 SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL),
778 TXA_ENA_FSYNC | TXA_DIS_ALLOC | TXA_STOP_RC);
779
780 SK_OUT32(IoC, MR_ADDR(Port, TXA_ITI_INI), IntTime);
781 SK_OUT32(IoC, MR_ADDR(Port, TXA_LIM_INI), LimCount);
782
783 SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL),
784 (SK_U8)(SyncMode & (TXA_ENA_ALLOC | TXA_DIS_ALLOC)));
785
786 if (IntTime != 0 || LimCount != 0) {
787 SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL), TXA_DIS_FSYNC | TXA_START_RC);
788 }
789
790 return(0);
791} /* SkGeCfgSync */
792#endif /* SK_DIAG || SK_CFG_SYNC*/
793
794
795/******************************************************************************
796 *
797 * DoInitRamQueue() - Initialize the RAM Buffer Address of a single Queue
798 *
799 * Desccription:
800 * If the queue is used, enable and initialize it.
801 * Make sure the queue is still reset, if it is not used.
802 *
803 * Returns:
804 * nothing
805 */
806static void DoInitRamQueue(
807SK_AC *pAC, /* adapter context */
808SK_IOC IoC, /* IO context */
809int QuIoOffs, /* Queue IO Address Offset */
810SK_U32 QuStartAddr, /* Queue Start Address */
811SK_U32 QuEndAddr, /* Queue End Address */
812int QuType) /* Queue Type (SK_RX_SRAM_Q|SK_RX_BRAM_Q|SK_TX_RAM_Q) */
813{
814 SK_U32 RxUpThresVal;
815 SK_U32 RxLoThresVal;
816
817 if (QuStartAddr != QuEndAddr) {
818 /* calculate thresholds, assume we have a big Rx queue */
819 RxUpThresVal = (QuEndAddr + 1 - QuStartAddr - SK_RB_ULPP) / 8;
820 RxLoThresVal = (QuEndAddr + 1 - QuStartAddr - SK_RB_LLPP_B)/8;
821
822 /* build HW address format */
823 QuStartAddr = QuStartAddr / 8;
824 QuEndAddr = QuEndAddr / 8;
825
826 /* release local reset */
827 SK_OUT8(IoC, RB_ADDR(QuIoOffs, RB_CTRL), RB_RST_CLR);
828
829 /* configure addresses */
830 SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_START), QuStartAddr);
831 SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_END), QuEndAddr);
832 SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_WP), QuStartAddr);
833 SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_RP), QuStartAddr);
834
835 switch (QuType) {
836 case SK_RX_SRAM_Q:
837 /* configure threshold for small Rx Queue */
838 RxLoThresVal += (SK_RB_LLPP_B - SK_RB_LLPP_S) / 8;
839
840 /* continue with SK_RX_BRAM_Q */
841 case SK_RX_BRAM_Q:
842 /* write threshold for Rx Queue */
843
844 SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_RX_UTPP), RxUpThresVal);
845 SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_RX_LTPP), RxLoThresVal);
846
847 /* the high priority threshold not used */
848 break;
849 case SK_TX_RAM_Q:
850 /*
851 * Do NOT use Store & Forward under normal operation due to
852 * performance optimization (GENESIS only).
853 * But if Jumbo Frames are configured (XMAC Tx FIFO is only 4 kB)
854 * or YUKON is used ((GMAC Tx FIFO is only 1 kB)
855 * we NEED Store & Forward of the RAM buffer.
856 */
857 if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK ||
858 pAC->GIni.GIYukon) {
859 /* enable Store & Forward Mode for the Tx Side */
860 SK_OUT8(IoC, RB_ADDR(QuIoOffs, RB_CTRL), RB_ENA_STFWD);
861 }
862 break;
863 }
864
865 /* set queue operational */
866 SK_OUT8(IoC, RB_ADDR(QuIoOffs, RB_CTRL), RB_ENA_OP_MD);
867 }
868 else {
869 /* ensure the queue is still disabled */
870 SK_OUT8(IoC, RB_ADDR(QuIoOffs, RB_CTRL), RB_RST_SET);
871 }
872} /* DoInitRamQueue */
873
874
875/******************************************************************************
876 *
877 * SkGeInitRamBufs() - Initialize the RAM Buffer Queues
878 *
879 * Description:
880 * Initialize all RAM Buffer Queues of the specified port
881 *
882 * Returns:
883 * nothing
884 */
885static void SkGeInitRamBufs(
886SK_AC *pAC, /* adapter context */
887SK_IOC IoC, /* IO context */
888int Port) /* Port Index (MAC_1 + n) */
889{
890 SK_GEPORT *pPrt;
891 int RxQType;
892
893 pPrt = &pAC->GIni.GP[Port];
894
895 if (pPrt->PRxQSize == SK_MIN_RXQ_SIZE) {
896 RxQType = SK_RX_SRAM_Q; /* small Rx Queue */
897 }
898 else {
899 RxQType = SK_RX_BRAM_Q; /* big Rx Queue */
900 }
901
902 DoInitRamQueue(pAC, IoC, pPrt->PRxQOff, pPrt->PRxQRamStart,
903 pPrt->PRxQRamEnd, RxQType);
904
905 DoInitRamQueue(pAC, IoC, pPrt->PXsQOff, pPrt->PXsQRamStart,
906 pPrt->PXsQRamEnd, SK_TX_RAM_Q);
907
908 DoInitRamQueue(pAC, IoC, pPrt->PXaQOff, pPrt->PXaQRamStart,
909 pPrt->PXaQRamEnd, SK_TX_RAM_Q);
910
911} /* SkGeInitRamBufs */
912
913
914/******************************************************************************
915 *
916 * SkGeInitRamIface() - Initialize the RAM Interface
917 *
918 * Description:
919 * This function initializes the Adapters RAM Interface.
920 *
921 * Note:
922 * This function is used in the diagnostics.
923 *
924 * Returns:
925 * nothing
926 */
927static void SkGeInitRamIface(
928SK_AC *pAC, /* adapter context */
929SK_IOC IoC) /* IO context */
930{
931 /* release local reset */
932 SK_OUT16(IoC, B3_RI_CTRL, RI_RST_CLR);
933
934 /* configure timeout values */
935 SK_OUT8(IoC, B3_RI_WTO_R1, SK_RI_TO_53);
936 SK_OUT8(IoC, B3_RI_WTO_XA1, SK_RI_TO_53);
937 SK_OUT8(IoC, B3_RI_WTO_XS1, SK_RI_TO_53);
938 SK_OUT8(IoC, B3_RI_RTO_R1, SK_RI_TO_53);
939 SK_OUT8(IoC, B3_RI_RTO_XA1, SK_RI_TO_53);
940 SK_OUT8(IoC, B3_RI_RTO_XS1, SK_RI_TO_53);
941 SK_OUT8(IoC, B3_RI_WTO_R2, SK_RI_TO_53);
942 SK_OUT8(IoC, B3_RI_WTO_XA2, SK_RI_TO_53);
943 SK_OUT8(IoC, B3_RI_WTO_XS2, SK_RI_TO_53);
944 SK_OUT8(IoC, B3_RI_RTO_R2, SK_RI_TO_53);
945 SK_OUT8(IoC, B3_RI_RTO_XA2, SK_RI_TO_53);
946 SK_OUT8(IoC, B3_RI_RTO_XS2, SK_RI_TO_53);
947
948} /* SkGeInitRamIface */
949
950
951/******************************************************************************
952 *
953 * SkGeInitBmu() - Initialize the BMU state machines
954 *
955 * Description:
956 * Initialize all BMU state machines of the specified port
957 *
958 * Returns:
959 * nothing
960 */
961static void SkGeInitBmu(
962SK_AC *pAC, /* adapter context */
963SK_IOC IoC, /* IO context */
964int Port) /* Port Index (MAC_1 + n) */
965{
966 SK_GEPORT *pPrt;
967 SK_U32 RxWm;
968 SK_U32 TxWm;
969
970 pPrt = &pAC->GIni.GP[Port];
971
972 RxWm = SK_BMU_RX_WM;
973 TxWm = SK_BMU_TX_WM;
974
975 if (!pAC->GIni.GIPciSlot64 && !pAC->GIni.GIPciClock66) {
976 /* for better performance */
977 RxWm /= 2;
978 TxWm /= 2;
979 }
980
981 /* Rx Queue: Release all local resets and set the watermark */
982 SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), CSR_CLR_RESET);
983 SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_F), RxWm);
984
985 /*
986 * Tx Queue: Release all local resets if the queue is used !
987 * set watermark
988 */
989 if (pPrt->PXSQSize != 0) {
990 SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_CLR_RESET);
991 SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_F), TxWm);
992 }
993
994 if (pPrt->PXAQSize != 0) {
995 SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_CLR_RESET);
996 SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_F), TxWm);
997 }
998 /*
999 * Do NOT enable the descriptor poll timers here, because
1000 * the descriptor addresses are not specified yet.
1001 */
1002} /* SkGeInitBmu */
1003
1004
1005/******************************************************************************
1006 *
1007 * TestStopBit() - Test the stop bit of the queue
1008 *
1009 * Description:
1010 * Stopping a queue is not as simple as it seems to be.
1011 * If descriptor polling is enabled, it may happen
1012 * that RX/TX stop is done and SV idle is NOT set.
1013 * In this case we have to issue another stop command.
1014 *
1015 * Returns:
1016 * The queues control status register
1017 */
1018static SK_U32 TestStopBit(
1019SK_AC *pAC, /* Adapter Context */
1020SK_IOC IoC, /* IO Context */
1021int QuIoOffs) /* Queue IO Address Offset */
1022{
1023 SK_U32 QuCsr; /* CSR contents */
1024
1025 SK_IN32(IoC, Q_ADDR(QuIoOffs, Q_CSR), &QuCsr);
1026
1027 if ((QuCsr & (CSR_STOP | CSR_SV_IDLE)) == 0) {
1028 /* Stop Descriptor overridden by start command */
1029 SK_OUT32(IoC, Q_ADDR(QuIoOffs, Q_CSR), CSR_STOP);
1030
1031 SK_IN32(IoC, Q_ADDR(QuIoOffs, Q_CSR), &QuCsr);
1032 }
1033
1034 return(QuCsr);
1035} /* TestStopBit */
1036
1037
1038/******************************************************************************
1039 *
1040 * SkGeStopPort() - Stop the Rx/Tx activity of the port 'Port'.
1041 *
1042 * Description:
1043 * After calling this function the descriptor rings and Rx and Tx
1044 * queues of this port may be reconfigured.
1045 *
1046 * It is possible to stop the receive and transmit path separate or
1047 * both together.
1048 *
1049 * Dir = SK_STOP_TX Stops the transmit path only and resets the MAC.
1050 * The receive queue is still active and
1051 * the pending Rx frames may be still transferred
1052 * into the RxD.
1053 * SK_STOP_RX Stop the receive path. The tansmit path
1054 * has to be stopped once before.
1055 * SK_STOP_ALL SK_STOP_TX + SK_STOP_RX
1056 *
1057 * RstMode = SK_SOFT_RST Resets the MAC. The PHY is still alive.
1058 * SK_HARD_RST Resets the MAC and the PHY.
1059 *
1060 * Example:
1061 * 1) A Link Down event was signaled for a port. Therefore the activity
1062 * of this port should be stopped and a hardware reset should be issued
1063 * to enable the workaround of XMAC Errata #2. But the received frames
1064 * should not be discarded.
1065 * ...
1066 * SkGeStopPort(pAC, IoC, Port, SK_STOP_TX, SK_HARD_RST);
1067 * (transfer all pending Rx frames)
1068 * SkGeStopPort(pAC, IoC, Port, SK_STOP_RX, SK_HARD_RST);
1069 * ...
1070 *
1071 * 2) An event was issued which request the driver to switch
1072 * the 'virtual active' link to an other already active port
1073 * as soon as possible. The frames in the receive queue of this
1074 * port may be lost. But the PHY must not be reset during this
1075 * event.
1076 * ...
1077 * SkGeStopPort(pAC, IoC, Port, SK_STOP_ALL, SK_SOFT_RST);
1078 * ...
1079 *
1080 * Extended Description:
1081 * If SK_STOP_TX is set,
1082 * o disable the MAC's receive and transmitter to prevent
1083 * from sending incomplete frames
1084 * o stop the port's transmit queues before terminating the
1085 * BMUs to prevent from performing incomplete PCI cycles
1086 * on the PCI bus
1087 * - The network Rx and Tx activity and PCI Tx transfer is
1088 * disabled now.
1089 * o reset the MAC depending on the RstMode
1090 * o Stop Interval Timer and Limit Counter of Tx Arbiter,
1091 * also disable Force Sync bit and Enable Alloc bit.
1092 * o perform a local reset of the port's Tx path
1093 * - reset the PCI FIFO of the async Tx queue
1094 * - reset the PCI FIFO of the sync Tx queue
1095 * - reset the RAM Buffer async Tx queue
1096 * - reset the RAM Buffer sync Tx queue
1097 * - reset the MAC Tx FIFO
1098 * o switch Link and Tx LED off, stop the LED counters
1099 *
1100 * If SK_STOP_RX is set,
1101 * o stop the port's receive queue
1102 * - The path data transfer activity is fully stopped now.
1103 * o perform a local reset of the port's Rx path
1104 * - reset the PCI FIFO of the Rx queue
1105 * - reset the RAM Buffer receive queue
1106 * - reset the MAC Rx FIFO
1107 * o switch Rx LED off, stop the LED counter
1108 *
1109 * If all ports are stopped,
1110 * o reset the RAM Interface.
1111 *
1112 * Notes:
1113 * o This function may be called during the driver states RESET_PORT and
1114 * SWITCH_PORT.
1115 */
1116void SkGeStopPort(
1117SK_AC *pAC, /* adapter context */
1118SK_IOC IoC, /* I/O context */
1119int Port, /* port to stop (MAC_1 + n) */
1120int Dir, /* Direction to Stop (SK_STOP_RX, SK_STOP_TX, SK_STOP_ALL) */
1121int RstMode)/* Reset Mode (SK_SOFT_RST, SK_HARD_RST) */
1122{
1123#ifndef SK_DIAG
1124 SK_EVPARA Para;
1125#endif /* !SK_DIAG */
1126 SK_GEPORT *pPrt;
1127 SK_U32 DWord;
1128 SK_U32 XsCsr;
1129 SK_U32 XaCsr;
1130 SK_U64 ToutStart;
1131 int i;
1132 int ToutCnt;
1133
1134 pPrt = &pAC->GIni.GP[Port];
1135
1136 if ((Dir & SK_STOP_TX) != 0) {
1137 /* disable receiver and transmitter */
1138 SkMacRxTxDisable(pAC, IoC, Port);
1139
1140 /* stop both transmit queues */
1141 /*
1142 * If the BMU is in the reset state CSR_STOP will terminate
1143 * immediately.
1144 */
1145 SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_STOP);
1146 SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_STOP);
1147
1148 ToutStart = SkOsGetTime(pAC);
1149 ToutCnt = 0;
1150 do {
1151 /*
1152 * Clear packet arbiter timeout to make sure
1153 * this loop will terminate.
1154 */
1155 SK_OUT16(IoC, B3_PA_CTRL, (SK_U16)((Port == MAC_1) ?
1156 PA_CLR_TO_TX1 : PA_CLR_TO_TX2));
1157
1158 /*
1159 * If the transfer stucks at the MAC the STOP command will not
1160 * terminate if we don't flush the XMAC's transmit FIFO !
1161 */
1162 SkMacFlushTxFifo(pAC, IoC, Port);
1163
1164 XsCsr = TestStopBit(pAC, IoC, pPrt->PXsQOff);
1165 XaCsr = TestStopBit(pAC, IoC, pPrt->PXaQOff);
1166
1167 if (SkOsGetTime(pAC) - ToutStart > (SK_TICKS_PER_SEC / 18)) {
1168 /*
1169 * Timeout of 1/18 second reached.
1170 * This needs to be checked at 1/18 sec only.
1171 */
1172 ToutCnt++;
1173 if (ToutCnt > 1) {
1174 /* Might be a problem when the driver event handler
1175 * calls StopPort again. XXX.
1176 */
1177
1178 /* Fatal Error, Loop aborted */
1179 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_HWI_E018,
1180 SKERR_HWI_E018MSG);
1181#ifndef SK_DIAG
1182 Para.Para64 = Port;
1183 SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
1184#endif /* !SK_DIAG */
1185 return;
1186 }
1187 /*
1188 * Cache incoherency workaround: Assume a start command
1189 * has been lost while sending the frame.
1190 */
1191 ToutStart = SkOsGetTime(pAC);
1192
1193 if ((XsCsr & CSR_STOP) != 0) {
1194 SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_START);
1195 }
1196 if ((XaCsr & CSR_STOP) != 0) {
1197 SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_START);
1198 }
1199 }
1200
1201 /*
1202 * Because of the ASIC problem report entry from 21.08.1998 it is
1203 * required to wait until CSR_STOP is reset and CSR_SV_IDLE is set.
1204 */
1205 } while ((XsCsr & (CSR_STOP | CSR_SV_IDLE)) != CSR_SV_IDLE ||
1206 (XaCsr & (CSR_STOP | CSR_SV_IDLE)) != CSR_SV_IDLE);
1207
1208 /* Reset the MAC depending on the RstMode */
1209 if (RstMode == SK_SOFT_RST) {
1210 SkMacSoftRst(pAC, IoC, Port);
1211 }
1212 else {
1213 SkMacHardRst(pAC, IoC, Port);
1214 }
1215
1216 /* Disable Force Sync bit and Enable Alloc bit */
1217 SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL),
1218 TXA_DIS_FSYNC | TXA_DIS_ALLOC | TXA_STOP_RC);
1219
1220 /* Stop Interval Timer and Limit Counter of Tx Arbiter */
1221 SK_OUT32(IoC, MR_ADDR(Port, TXA_ITI_INI), 0L);
1222 SK_OUT32(IoC, MR_ADDR(Port, TXA_LIM_INI), 0L);
1223
1224 /* Perform a local reset of the port's Tx path */
1225
1226 /* Reset the PCI FIFO of the async Tx queue */
1227 SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_SET_RESET);
1228 /* Reset the PCI FIFO of the sync Tx queue */
1229 SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_SET_RESET);
1230 /* Reset the RAM Buffer async Tx queue */
1231 SK_OUT8(IoC, RB_ADDR(pPrt->PXaQOff, RB_CTRL), RB_RST_SET);
1232 /* Reset the RAM Buffer sync Tx queue */
1233 SK_OUT8(IoC, RB_ADDR(pPrt->PXsQOff, RB_CTRL), RB_RST_SET);
1234
1235 /* Reset Tx MAC FIFO */
1236#ifdef GENESIS
1237 if (pAC->GIni.GIGenesis) {
1238 /* Note: MFF_RST_SET does NOT reset the XMAC ! */
1239 SK_OUT8(IoC, MR_ADDR(Port, TX_MFF_CTRL2), MFF_RST_SET);
1240
1241 /* switch Link and Tx LED off, stop the LED counters */
1242 /* Link LED is switched off by the RLMT and the Diag itself */
1243 SkGeXmitLED(pAC, IoC, MR_ADDR(Port, TX_LED_INI), SK_LED_DIS);
1244 }
1245#endif /* GENESIS */
1246
1247#ifdef YUKON
1248 if (pAC->GIni.GIYukon) {
1249 /* Reset TX MAC FIFO */
1250 SK_OUT8(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), (SK_U8)GMF_RST_SET);
1251 }
1252#endif /* YUKON */
1253 }
1254
1255 if ((Dir & SK_STOP_RX) != 0) {
1256 /*
1257 * The RX Stop Command will not terminate if no buffers
1258 * are queued in the RxD ring. But it will always reach
1259 * the Idle state. Therefore we can use this feature to
1260 * stop the transfer of received packets.
1261 */
1262 /* stop the port's receive queue */
1263 SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), CSR_STOP);
1264
1265 i = 100;
1266 do {
1267 /*
1268 * Clear packet arbiter timeout to make sure
1269 * this loop will terminate
1270 */
1271 SK_OUT16(IoC, B3_PA_CTRL, (SK_U16)((Port == MAC_1) ?
1272 PA_CLR_TO_RX1 : PA_CLR_TO_RX2));
1273
1274 DWord = TestStopBit(pAC, IoC, pPrt->PRxQOff);
1275
1276 /* timeout if i==0 (bug fix for #10748) */
1277 if (--i == 0) {
1278 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_HWI_E024,
1279 SKERR_HWI_E024MSG);
1280 break;
1281 }
1282 /*
1283 * because of the ASIC problem report entry from 21.08.98
1284 * it is required to wait until CSR_STOP is reset and
1285 * CSR_SV_IDLE is set.
1286 */
1287 } while ((DWord & (CSR_STOP | CSR_SV_IDLE)) != CSR_SV_IDLE);
1288
1289 /* The path data transfer activity is fully stopped now */
1290
1291 /* Perform a local reset of the port's Rx path */
1292
1293 /* Reset the PCI FIFO of the Rx queue */
1294 SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), CSR_SET_RESET);
1295 /* Reset the RAM Buffer receive queue */
1296 SK_OUT8(IoC, RB_ADDR(pPrt->PRxQOff, RB_CTRL), RB_RST_SET);
1297
1298 /* Reset Rx MAC FIFO */
1299#ifdef GENESIS
1300 if (pAC->GIni.GIGenesis) {
1301
1302 SK_OUT8(IoC, MR_ADDR(Port, RX_MFF_CTRL2), MFF_RST_SET);
1303
1304 /* switch Rx LED off, stop the LED counter */
1305 SkGeXmitLED(pAC, IoC, MR_ADDR(Port, RX_LED_INI), SK_LED_DIS);
1306 }
1307#endif /* GENESIS */
1308
1309#ifdef YUKON
1310 if (pAC->GIni.GIYukon) {
1311 /* Reset Rx MAC FIFO */
1312 SK_OUT8(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), (SK_U8)GMF_RST_SET);
1313 }
1314#endif /* YUKON */
1315 }
1316} /* SkGeStopPort */
1317
1318
1319/******************************************************************************
1320 *
1321 * SkGeInit0() - Level 0 Initialization
1322 *
1323 * Description:
1324 * - Initialize the BMU address offsets
1325 *
1326 * Returns:
1327 * nothing
1328 */
1329static void SkGeInit0(
1330SK_AC *pAC, /* adapter context */
1331SK_IOC IoC) /* IO context */
1332{
1333 int i;
1334 SK_GEPORT *pPrt;
1335
1336 for (i = 0; i < SK_MAX_MACS; i++) {
1337 pPrt = &pAC->GIni.GP[i];
1338
1339 pPrt->PState = SK_PRT_RESET;
1340 pPrt->PRxQOff = QOffTab[i].RxQOff;
1341 pPrt->PXsQOff = QOffTab[i].XsQOff;
1342 pPrt->PXaQOff = QOffTab[i].XaQOff;
1343 pPrt->PCheckPar = SK_FALSE;
1344 pPrt->PIsave = 0;
1345 pPrt->PPrevShorts = 0;
1346 pPrt->PLinkResCt = 0;
1347 pPrt->PAutoNegTOCt = 0;
1348 pPrt->PPrevRx = 0;
1349 pPrt->PPrevFcs = 0;
1350 pPrt->PRxLim = SK_DEF_RX_WA_LIM;
1351 pPrt->PLinkMode = (SK_U8)SK_LMODE_AUTOFULL;
1352 pPrt->PLinkSpeedCap = (SK_U8)SK_LSPEED_CAP_1000MBPS;
1353 pPrt->PLinkSpeed = (SK_U8)SK_LSPEED_1000MBPS;
1354 pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_UNKNOWN;
1355 pPrt->PLinkModeConf = (SK_U8)SK_LMODE_AUTOSENSE;
1356 pPrt->PFlowCtrlMode = (SK_U8)SK_FLOW_MODE_SYM_OR_REM;
1357 pPrt->PLinkCap = (SK_U8)(SK_LMODE_CAP_HALF | SK_LMODE_CAP_FULL |
1358 SK_LMODE_CAP_AUTOHALF | SK_LMODE_CAP_AUTOFULL);
1359 pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_UNKNOWN;
1360 pPrt->PFlowCtrlCap = (SK_U8)SK_FLOW_MODE_SYM_OR_REM;
1361 pPrt->PFlowCtrlStatus = (SK_U8)SK_FLOW_STAT_NONE;
1362 pPrt->PMSCap = 0;
1363 pPrt->PMSMode = (SK_U8)SK_MS_MODE_AUTO;
1364 pPrt->PMSStatus = (SK_U8)SK_MS_STAT_UNSET;
1365 pPrt->PLipaAutoNeg = (SK_U8)SK_LIPA_UNKNOWN;
1366 pPrt->PAutoNegFail = SK_FALSE;
1367 pPrt->PHWLinkUp = SK_FALSE;
1368 pPrt->PLinkBroken = SK_TRUE; /* See WA code */
1369 pPrt->PPhyPowerState = PHY_PM_OPERATIONAL_MODE;
1370 pPrt->PMacColThres = TX_COL_DEF;
1371 pPrt->PMacJamLen = TX_JAM_LEN_DEF;
1372 pPrt->PMacJamIpgVal = TX_JAM_IPG_DEF;
1373 pPrt->PMacJamIpgData = TX_IPG_JAM_DEF;
1374 pPrt->PMacIpgData = IPG_DATA_DEF;
1375 pPrt->PMacLimit4 = SK_FALSE;
1376 }
1377
1378 pAC->GIni.GIPortUsage = SK_RED_LINK;
1379 pAC->GIni.GILedBlinkCtrl = (SK_U16)OemConfig.Value;
1380 pAC->GIni.GIValIrqMask = IS_ALL_MSK;
1381
1382} /* SkGeInit0*/
1383
1384
1385/******************************************************************************
1386 *
1387 * SkGeInit1() - Level 1 Initialization
1388 *
1389 * Description:
1390 * o Do a software reset.
1391 * o Clear all reset bits.
1392 * o Verify that the detected hardware is present.
1393 * Return an error if not.
1394 * o Get the hardware configuration
1395 * + Read the number of MACs/Ports.
1396 * + Read the RAM size.
1397 * + Read the PCI Revision Id.
1398 * + Find out the adapters host clock speed
1399 * + Read and check the PHY type
1400 *
1401 * Returns:
1402 * 0: success
1403 * 5: Unexpected PHY type detected
1404 * 6: HW self test failed
1405 */
1406static int SkGeInit1(
1407SK_AC *pAC, /* adapter context */
1408SK_IOC IoC) /* IO context */
1409{
1410 SK_U8 Byte;
1411 SK_U16 Word;
1412 SK_U16 CtrlStat;
1413 SK_U32 DWord;
1414 int RetVal;
1415 int i;
1416
1417 RetVal = 0;
1418
1419 /* save CLK_RUN bits (YUKON-Lite) */
1420 SK_IN16(IoC, B0_CTST, &CtrlStat);
1421
1422 /* do the SW-reset */
1423 SK_OUT8(IoC, B0_CTST, CS_RST_SET);
1424
1425 /* release the SW-reset */
1426 SK_OUT8(IoC, B0_CTST, CS_RST_CLR);
1427
1428 /* reset all error bits in the PCI STATUS register */
1429 /*
1430 * Note: PCI Cfg cycles cannot be used, because they are not
1431 * available on some platforms after 'boot time'.
1432 */
1433 SK_IN16(IoC, PCI_C(PCI_STATUS), &Word);
1434
1435 SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON);
1436 SK_OUT16(IoC, PCI_C(PCI_STATUS), (SK_U16)(Word | PCI_ERRBITS));
1437 SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
1438
1439 /* release Master Reset */
1440 SK_OUT8(IoC, B0_CTST, CS_MRST_CLR);
1441
1442#ifdef CLK_RUN
1443 CtrlStat |= CS_CLK_RUN_ENA;
1444#endif /* CLK_RUN */
1445
1446 /* restore CLK_RUN bits */
1447 SK_OUT16(IoC, B0_CTST, (SK_U16)(CtrlStat &
1448 (CS_CLK_RUN_HOT | CS_CLK_RUN_RST | CS_CLK_RUN_ENA)));
1449
1450 /* read Chip Identification Number */
1451 SK_IN8(IoC, B2_CHIP_ID, &Byte);
1452 pAC->GIni.GIChipId = Byte;
1453
1454 /* read number of MACs */
1455 SK_IN8(IoC, B2_MAC_CFG, &Byte);
1456 pAC->GIni.GIMacsFound = (Byte & CFG_SNG_MAC) ? 1 : 2;
1457
1458 /* get Chip Revision Number */
1459 pAC->GIni.GIChipRev = (SK_U8)((Byte & CFG_CHIP_R_MSK) >> 4);
1460
1461 /* get diff. PCI parameters */
1462 SK_IN16(IoC, B0_CTST, &CtrlStat);
1463
1464 /* read the adapters RAM size */
1465 SK_IN8(IoC, B2_E_0, &Byte);
1466
1467 pAC->GIni.GIGenesis = SK_FALSE;
1468 pAC->GIni.GIYukon = SK_FALSE;
1469 pAC->GIni.GIYukonLite = SK_FALSE;
1470
1471#ifdef GENESIS
1472 if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) {
1473
1474 pAC->GIni.GIGenesis = SK_TRUE;
1475
1476 if (Byte == (SK_U8)3) {
1477 /* special case: 4 x 64k x 36, offset = 0x80000 */
1478 pAC->GIni.GIRamSize = 1024;
1479 pAC->GIni.GIRamOffs = (SK_U32)512 * 1024;
1480 }
1481 else {
1482 pAC->GIni.GIRamSize = (int)Byte * 512;
1483 pAC->GIni.GIRamOffs = 0;
1484 }
1485 /* all GE adapters work with 53.125 MHz host clock */
1486 pAC->GIni.GIHstClkFact = SK_FACT_53;
1487
1488 /* set Descr. Poll Timer Init Value to 250 ms */
1489 pAC->GIni.GIPollTimerVal =
1490 SK_DPOLL_DEF * (SK_U32)pAC->GIni.GIHstClkFact / 100;
1491 }
1492#endif /* GENESIS */
1493
1494#ifdef YUKON
1495 if (pAC->GIni.GIChipId != CHIP_ID_GENESIS) {
1496
1497 pAC->GIni.GIYukon = SK_TRUE;
1498
1499 pAC->GIni.GIRamSize = (Byte == (SK_U8)0) ? 128 : (int)Byte * 4;
1500
1501 pAC->GIni.GIRamOffs = 0;
1502
1503 /* WA for chip Rev. A */
1504 pAC->GIni.GIWolOffs = (pAC->GIni.GIChipId == CHIP_ID_YUKON &&
1505 pAC->GIni.GIChipRev == 0) ? WOL_REG_OFFS : 0;
1506
1507 /* get PM Capabilities of PCI config space */
1508 SK_IN16(IoC, PCI_C(PCI_PM_CAP_REG), &Word);
1509
1510 /* check if VAUX is available */
1511 if (((CtrlStat & CS_VAUX_AVAIL) != 0) &&
1512 /* check also if PME from D3cold is set */
1513 ((Word & PCI_PME_D3C_SUP) != 0)) {
1514 /* set entry in GE init struct */
1515 pAC->GIni.GIVauxAvail = SK_TRUE;
1516 }
1517
1518 if (pAC->GIni.GIChipId == CHIP_ID_YUKON_LITE) {
1519 /* this is Rev. A1 */
1520 pAC->GIni.GIYukonLite = SK_TRUE;
1521 }
1522 else {
1523 /* save Flash-Address Register */
1524 SK_IN32(IoC, B2_FAR, &DWord);
1525
1526 /* test Flash-Address Register */
1527 SK_OUT8(IoC, B2_FAR + 3, 0xff);
1528 SK_IN8(IoC, B2_FAR + 3, &Byte);
1529
1530 if (Byte != 0) {
1531 /* this is Rev. A0 */
1532 pAC->GIni.GIYukonLite = SK_TRUE;
1533
1534 /* restore Flash-Address Register */
1535 SK_OUT32(IoC, B2_FAR, DWord);
1536 }
1537 }
1538
1539 /* switch power to VCC (WA for VAUX problem) */
1540 SK_OUT8(IoC, B0_POWER_CTRL, (SK_U8)(PC_VAUX_ENA | PC_VCC_ENA |
1541 PC_VAUX_OFF | PC_VCC_ON));
1542
1543 /* read the Interrupt source */
1544 SK_IN32(IoC, B0_ISRC, &DWord);
1545
1546 if ((DWord & IS_HW_ERR) != 0) {
1547 /* read the HW Error Interrupt source */
1548 SK_IN32(IoC, B0_HWE_ISRC, &DWord);
1549
1550 if ((DWord & IS_IRQ_SENSOR) != 0) {
1551 /* disable HW Error IRQ */
1552 pAC->GIni.GIValIrqMask &= ~IS_HW_ERR;
1553 }
1554 }
1555
1556 for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
1557 /* set GMAC Link Control reset */
1558 SK_OUT16(IoC, MR_ADDR(i, GMAC_LINK_CTRL), GMLC_RST_SET);
1559
1560 /* clear GMAC Link Control reset */
1561 SK_OUT16(IoC, MR_ADDR(i, GMAC_LINK_CTRL), GMLC_RST_CLR);
1562 }
1563 /* all YU chips work with 78.125 MHz host clock */
1564 pAC->GIni.GIHstClkFact = SK_FACT_78;
1565
1566 pAC->GIni.GIPollTimerVal = SK_DPOLL_MAX; /* 215 ms */
1567 }
1568#endif /* YUKON */
1569
1570 /* check if 64-bit PCI Slot is present */
1571 pAC->GIni.GIPciSlot64 = (SK_BOOL)((CtrlStat & CS_BUS_SLOT_SZ) != 0);
1572
1573 /* check if 66 MHz PCI Clock is active */
1574 pAC->GIni.GIPciClock66 = (SK_BOOL)((CtrlStat & CS_BUS_CLOCK) != 0);
1575
1576 /* read PCI HW Revision Id. */
1577 SK_IN8(IoC, PCI_C(PCI_REV_ID), &Byte);
1578 pAC->GIni.GIPciHwRev = Byte;
1579
1580 /* read the PMD type */
1581 SK_IN8(IoC, B2_PMD_TYP, &Byte);
1582 pAC->GIni.GICopperType = (SK_U8)(Byte == 'T');
1583
1584 /* read the PHY type */
1585 SK_IN8(IoC, B2_E_1, &Byte);
1586
1587 Byte &= 0x0f; /* the PHY type is stored in the lower nibble */
1588 for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
1589
1590#ifdef GENESIS
1591 if (pAC->GIni.GIGenesis) {
1592 switch (Byte) {
1593 case SK_PHY_XMAC:
1594 pAC->GIni.GP[i].PhyAddr = PHY_ADDR_XMAC;
1595 break;
1596 case SK_PHY_BCOM:
1597 pAC->GIni.GP[i].PhyAddr = PHY_ADDR_BCOM;
1598 pAC->GIni.GP[i].PMSCap = (SK_U8)(SK_MS_CAP_AUTO |
1599 SK_MS_CAP_MASTER | SK_MS_CAP_SLAVE);
1600 break;
1601#ifdef OTHER_PHY
1602 case SK_PHY_LONE:
1603 pAC->GIni.GP[i].PhyAddr = PHY_ADDR_LONE;
1604 break;
1605 case SK_PHY_NAT:
1606 pAC->GIni.GP[i].PhyAddr = PHY_ADDR_NAT;
1607 break;
1608#endif /* OTHER_PHY */
1609 default:
1610 /* ERROR: unexpected PHY type detected */
1611 RetVal = 5;
1612 break;
1613 }
1614 }
1615#endif /* GENESIS */
1616
1617#ifdef YUKON
1618 if (pAC->GIni.GIYukon) {
1619
1620 if (Byte < (SK_U8)SK_PHY_MARV_COPPER) {
1621 /* if this field is not initialized */
1622 Byte = (SK_U8)SK_PHY_MARV_COPPER;
1623
1624 pAC->GIni.GICopperType = SK_TRUE;
1625 }
1626
1627 pAC->GIni.GP[i].PhyAddr = PHY_ADDR_MARV;
1628
1629 if (pAC->GIni.GICopperType) {
1630
1631 pAC->GIni.GP[i].PLinkSpeedCap = (SK_U8)(SK_LSPEED_CAP_AUTO |
1632 SK_LSPEED_CAP_10MBPS | SK_LSPEED_CAP_100MBPS |
1633 SK_LSPEED_CAP_1000MBPS);
1634
1635 pAC->GIni.GP[i].PLinkSpeed = (SK_U8)SK_LSPEED_AUTO;
1636
1637 pAC->GIni.GP[i].PMSCap = (SK_U8)(SK_MS_CAP_AUTO |
1638 SK_MS_CAP_MASTER | SK_MS_CAP_SLAVE);
1639 }
1640 else {
1641 Byte = (SK_U8)SK_PHY_MARV_FIBER;
1642 }
1643 }
1644#endif /* YUKON */
1645
1646 pAC->GIni.GP[i].PhyType = (int)Byte;
1647
1648 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
1649 ("PHY type: %d PHY addr: %04x\n", Byte,
1650 pAC->GIni.GP[i].PhyAddr));
1651 }
1652
1653 /* get MAC Type & set function pointers dependent on */
1654#ifdef GENESIS
1655 if (pAC->GIni.GIGenesis) {
1656
1657 pAC->GIni.GIMacType = SK_MAC_XMAC;
1658
1659 pAC->GIni.GIFunc.pFnMacUpdateStats = SkXmUpdateStats;
1660 pAC->GIni.GIFunc.pFnMacStatistic = SkXmMacStatistic;
1661 pAC->GIni.GIFunc.pFnMacResetCounter = SkXmResetCounter;
1662 pAC->GIni.GIFunc.pFnMacOverflow = SkXmOverflowStatus;
1663 }
1664#endif /* GENESIS */
1665
1666#ifdef YUKON
1667 if (pAC->GIni.GIYukon) {
1668
1669 pAC->GIni.GIMacType = SK_MAC_GMAC;
1670
1671 pAC->GIni.GIFunc.pFnMacUpdateStats = SkGmUpdateStats;
1672 pAC->GIni.GIFunc.pFnMacStatistic = SkGmMacStatistic;
1673 pAC->GIni.GIFunc.pFnMacResetCounter = SkGmResetCounter;
1674 pAC->GIni.GIFunc.pFnMacOverflow = SkGmOverflowStatus;
1675
1676#ifdef SPECIAL_HANDLING
1677 if (pAC->GIni.GIChipId == CHIP_ID_YUKON) {
1678 /* check HW self test result */
1679 SK_IN8(IoC, B2_E_3, &Byte);
1680 if (Byte & B2_E3_RES_MASK) {
1681 RetVal = 6;
1682 }
1683 }
1684#endif
1685 }
1686#endif /* YUKON */
1687
1688 return(RetVal);
1689} /* SkGeInit1 */
1690
1691
1692/******************************************************************************
1693 *
1694 * SkGeInit2() - Level 2 Initialization
1695 *
1696 * Description:
1697 * - start the Blink Source Counter
1698 * - start the Descriptor Poll Timer
1699 * - configure the MAC-Arbiter
1700 * - configure the Packet-Arbiter
1701 * - enable the Tx Arbiters
1702 * - enable the RAM Interface Arbiter
1703 *
1704 * Returns:
1705 * nothing
1706 */
1707static void SkGeInit2(
1708SK_AC *pAC, /* adapter context */
1709SK_IOC IoC) /* IO context */
1710{
1711#ifdef GENESIS
1712 SK_U32 DWord;
1713#endif /* GENESIS */
1714 int i;
1715
1716 /* start the Descriptor Poll Timer */
1717 if (pAC->GIni.GIPollTimerVal != 0) {
1718 if (pAC->GIni.GIPollTimerVal > SK_DPOLL_MAX) {
1719 pAC->GIni.GIPollTimerVal = SK_DPOLL_MAX;
1720
1721 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E017, SKERR_HWI_E017MSG);
1722 }
1723 SK_OUT32(IoC, B28_DPT_INI, pAC->GIni.GIPollTimerVal);
1724 SK_OUT8(IoC, B28_DPT_CTRL, DPT_START);
1725 }
1726
1727#ifdef GENESIS
1728 if (pAC->GIni.GIGenesis) {
1729 /* start the Blink Source Counter */
1730 DWord = SK_BLK_DUR * (SK_U32)pAC->GIni.GIHstClkFact / 100;
1731
1732 SK_OUT32(IoC, B2_BSC_INI, DWord);
1733 SK_OUT8(IoC, B2_BSC_CTRL, BSC_START);
1734
1735 /*
1736 * Configure the MAC Arbiter and the Packet Arbiter.
1737 * They will be started once and never be stopped.
1738 */
1739 SkGeInitMacArb(pAC, IoC);
1740
1741 SkGeInitPktArb(pAC, IoC);
1742 }
1743#endif /* GENESIS */
1744
1745#ifdef YUKON
1746 if (pAC->GIni.GIYukon) {
1747 /* start Time Stamp Timer */
1748 SK_OUT8(IoC, GMAC_TI_ST_CTRL, (SK_U8)GMT_ST_START);
1749 }
1750#endif /* YUKON */
1751
1752 /* enable the Tx Arbiters */
1753 for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
1754 SK_OUT8(IoC, MR_ADDR(i, TXA_CTRL), TXA_ENA_ARB);
1755 }
1756
1757 /* enable the RAM Interface Arbiter */
1758 SkGeInitRamIface(pAC, IoC);
1759
1760} /* SkGeInit2 */
1761
1762/******************************************************************************
1763 *
1764 * SkGeInit() - Initialize the GE Adapter with the specified level.
1765 *
1766 * Description:
1767 * Level 0: Initialize the Module structures.
1768 * Level 1: Generic Hardware Initialization. The IOP/MemBase pointer has
1769 * to be set before calling this level.
1770 *
1771 * o Do a software reset.
1772 * o Clear all reset bits.
1773 * o Verify that the detected hardware is present.
1774 * Return an error if not.
1775 * o Get the hardware configuration
1776 * + Set GIMacsFound with the number of MACs.
1777 * + Store the RAM size in GIRamSize.
1778 * + Save the PCI Revision ID in GIPciHwRev.
1779 * o return an error
1780 * if Number of MACs > SK_MAX_MACS
1781 *
1782 * After returning from Level 0 the adapter
1783 * may be accessed with IO operations.
1784 *
1785 * Level 2: start the Blink Source Counter
1786 *
1787 * Returns:
1788 * 0: success
1789 * 1: Number of MACs exceeds SK_MAX_MACS (after level 1)
1790 * 2: Adapter not present or not accessible
1791 * 3: Illegal initialization level
1792 * 4: Initialization Level 1 Call missing
1793 * 5: Unexpected PHY type detected
1794 * 6: HW self test failed
1795 */
1796int SkGeInit(
1797SK_AC *pAC, /* adapter context */
1798SK_IOC IoC, /* IO context */
1799int Level) /* initialization level */
1800{
1801 int RetVal; /* return value */
1802 SK_U32 DWord;
1803
1804 RetVal = 0;
1805 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
1806 ("SkGeInit(Level %d)\n", Level));
1807
1808 switch (Level) {
1809 case SK_INIT_DATA:
1810 /* Initialization Level 0 */
1811 SkGeInit0(pAC, IoC);
1812 pAC->GIni.GILevel = SK_INIT_DATA;
1813 break;
1814
1815 case SK_INIT_IO:
1816 /* Initialization Level 1 */
1817 RetVal = SkGeInit1(pAC, IoC);
1818 if (RetVal != 0) {
1819 break;
1820 }
1821
1822 /* check if the adapter seems to be accessible */
1823 SK_OUT32(IoC, B2_IRQM_INI, SK_TEST_VAL);
1824 SK_IN32(IoC, B2_IRQM_INI, &DWord);
1825 SK_OUT32(IoC, B2_IRQM_INI, 0L);
1826
1827 if (DWord != SK_TEST_VAL) {
1828 RetVal = 2;
1829 break;
1830 }
1831
1832 /* check if the number of GIMacsFound matches SK_MAX_MACS */
1833 if (pAC->GIni.GIMacsFound > SK_MAX_MACS) {
1834 RetVal = 1;
1835 break;
1836 }
1837
1838 /* Level 1 successfully passed */
1839 pAC->GIni.GILevel = SK_INIT_IO;
1840 break;
1841
1842 case SK_INIT_RUN:
1843 /* Initialization Level 2 */
1844 if (pAC->GIni.GILevel != SK_INIT_IO) {
1845#ifndef SK_DIAG
1846 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E002, SKERR_HWI_E002MSG);
1847#endif /* !SK_DIAG */
1848 RetVal = 4;
1849 break;
1850 }
1851 SkGeInit2(pAC, IoC);
1852
1853 /* Level 2 successfully passed */
1854 pAC->GIni.GILevel = SK_INIT_RUN;
1855 break;
1856
1857 default:
1858 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E003, SKERR_HWI_E003MSG);
1859 RetVal = 3;
1860 break;
1861 }
1862
1863 return(RetVal);
1864} /* SkGeInit */
1865
1866
1867/******************************************************************************
1868 *
1869 * SkGeDeInit() - Deinitialize the adapter
1870 *
1871 * Description:
1872 * All ports of the adapter will be stopped if not already done.
1873 * Do a software reset and switch off all LEDs.
1874 *
1875 * Returns:
1876 * nothing
1877 */
1878void SkGeDeInit(
1879SK_AC *pAC, /* adapter context */
1880SK_IOC IoC) /* IO context */
1881{
1882 int i;
1883 SK_U16 Word;
1884
1885#if (!defined(SK_SLIM) && !defined(VCPU))
1886 /* ensure I2C is ready */
1887 SkI2cWaitIrq(pAC, IoC);
1888#endif
1889
1890 /* stop all current transfer activity */
1891 for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
1892 if (pAC->GIni.GP[i].PState != SK_PRT_STOP &&
1893 pAC->GIni.GP[i].PState != SK_PRT_RESET) {
1894
1895 SkGeStopPort(pAC, IoC, i, SK_STOP_ALL, SK_HARD_RST);
1896 }
1897 }
1898
1899 /* Reset all bits in the PCI STATUS register */
1900 /*
1901 * Note: PCI Cfg cycles cannot be used, because they are not
1902 * available on some platforms after 'boot time'.
1903 */
1904 SK_IN16(IoC, PCI_C(PCI_STATUS), &Word);
1905
1906 SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON);
1907 SK_OUT16(IoC, PCI_C(PCI_STATUS), (SK_U16)(Word | PCI_ERRBITS));
1908 SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
1909
1910 /* do the reset, all LEDs are switched off now */
1911 SK_OUT8(IoC, B0_CTST, CS_RST_SET);
1912
1913 pAC->GIni.GILevel = SK_INIT_DATA;
1914} /* SkGeDeInit */
1915
1916
1917/******************************************************************************
1918 *
1919 * SkGeInitPort() Initialize the specified port.
1920 *
1921 * Description:
1922 * PRxQSize, PXSQSize, and PXAQSize has to be
1923 * configured for the specified port before calling this function.
1924 * The descriptor rings has to be initialized too.
1925 *
1926 * o (Re)configure queues of the specified port.
1927 * o configure the MAC of the specified port.
1928 * o put ASIC and MAC(s) in operational mode.
1929 * o initialize Rx/Tx and Sync LED
1930 * o initialize RAM Buffers and MAC FIFOs
1931 *
1932 * The port is ready to connect when returning.
1933 *
1934 * Note:
1935 * The MAC's Rx and Tx state machine is still disabled when returning.
1936 *
1937 * Returns:
1938 * 0: success
1939 * 1: Queue size initialization error. The configured values
1940 * for PRxQSize, PXSQSize, or PXAQSize are invalid for one
1941 * or more queues. The specified port was NOT initialized.
1942 * An error log entry was generated.
1943 * 2: The port has to be stopped before it can be initialized again.
1944 */
1945int SkGeInitPort(
1946SK_AC *pAC, /* adapter context */
1947SK_IOC IoC, /* IO context */
1948int Port) /* Port to configure */
1949{
1950 SK_GEPORT *pPrt;
1951
1952 pPrt = &pAC->GIni.GP[Port];
1953
1954 if (SkGeCheckQSize(pAC, Port) != 0) {
1955 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E004, SKERR_HWI_E004MSG);
1956 return(1);
1957 }
1958
1959 if (pPrt->PState == SK_PRT_INIT || pPrt->PState == SK_PRT_RUN) {
1960 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E005, SKERR_HWI_E005MSG);
1961 return(2);
1962 }
1963
1964 /* configuration ok, initialize the Port now */
1965
1966#ifdef GENESIS
1967 if (pAC->GIni.GIGenesis) {
1968 /* initialize Rx, Tx and Link LED */
1969 /*
1970 * If 1000BT Phy needs LED initialization than swap
1971 * LED and XMAC initialization order
1972 */
1973 SkGeXmitLED(pAC, IoC, MR_ADDR(Port, TX_LED_INI), SK_LED_ENA);
1974 SkGeXmitLED(pAC, IoC, MR_ADDR(Port, RX_LED_INI), SK_LED_ENA);
1975 /* The Link LED is initialized by RLMT or Diagnostics itself */
1976
1977 SkXmInitMac(pAC, IoC, Port);
1978 }
1979#endif /* GENESIS */
1980
1981#ifdef YUKON
1982 if (pAC->GIni.GIYukon) {
1983
1984 SkGmInitMac(pAC, IoC, Port);
1985 }
1986#endif /* YUKON */
1987
1988 /* do NOT initialize the Link Sync Counter */
1989
1990 SkGeInitMacFifo(pAC, IoC, Port);
1991
1992 SkGeInitRamBufs(pAC, IoC, Port);
1993
1994 if (pPrt->PXSQSize != 0) {
1995 /* enable Force Sync bit if synchronous queue available */
1996 SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL), TXA_ENA_FSYNC);
1997 }
1998
1999 SkGeInitBmu(pAC, IoC, Port);
2000
2001 /* mark port as initialized */
2002 pPrt->PState = SK_PRT_INIT;
2003
2004 return(0);
2005} /* SkGeInitPort */
diff --git a/drivers/net/sk98lin/skgemib.c b/drivers/net/sk98lin/skgemib.c
deleted file mode 100644
index 0a6f67a7a395..000000000000
--- a/drivers/net/sk98lin/skgemib.c
+++ /dev/null
@@ -1,1075 +0,0 @@
1/*****************************************************************************
2 *
3 * Name: skgemib.c
4 * Project: GEnesis, PCI Gigabit Ethernet Adapter
5 * Version: $Revision: 1.11 $
6 * Date: $Date: 2003/09/15 13:38:12 $
7 * Purpose: Private Network Management Interface Management Database
8 *
9 ****************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect GmbH.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25/*
26 * PRIVATE OID handler function prototypes
27 */
28PNMI_STATIC int Addr(SK_AC *pAC, SK_IOC IoC, int action,
29 SK_U32 Id, char *pBuf, unsigned int *pLen, SK_U32 Instance,
30 unsigned int TableIndex, SK_U32 NetIndex);
31PNMI_STATIC int CsumStat(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
32 char *pBuf, unsigned int *pLen, SK_U32 Instance,
33 unsigned int TableIndex, SK_U32 NetIndex);
34PNMI_STATIC int General(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
35 char *pBuf, unsigned int *pLen, SK_U32 Instance,
36 unsigned int TableIndex, SK_U32 NetIndex);
37PNMI_STATIC int Mac8023Stat(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
38 char *pBuf, unsigned int *pLen, SK_U32 Instance,
39 unsigned int TableIndex, SK_U32 NetIndex);
40PNMI_STATIC int MacPrivateConf(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
41 char *pBuf, unsigned int *pLen, SK_U32 Instance,
42 unsigned int TableIndex, SK_U32 NetIndex);
43PNMI_STATIC int MacPrivateStat(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
44 char *pBuf, unsigned int *pLen, SK_U32 Instance,
45 unsigned int TableIndex, SK_U32 NetIndex);
46PNMI_STATIC int Monitor(SK_AC *pAC, SK_IOC IoC, int action,
47 SK_U32 Id, char *pBuf, unsigned int *pLen, SK_U32 Instance,
48 unsigned int TableIndex, SK_U32 NetIndex);
49PNMI_STATIC int OidStruct(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
50 char *pBuf, unsigned int *pLen, SK_U32 Instance,
51 unsigned int TableIndex, SK_U32 NetIndex);
52PNMI_STATIC int Perform(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
53 char *pBuf, unsigned int* pLen, SK_U32 Instance,
54 unsigned int TableIndex, SK_U32 NetIndex);
55PNMI_STATIC int Rlmt(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
56 char *pBuf, unsigned int *pLen, SK_U32 Instance,
57 unsigned int TableIndex, SK_U32 NetIndex);
58PNMI_STATIC int RlmtStat(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
59 char *pBuf, unsigned int *pLen, SK_U32 Instance,
60 unsigned int TableIndex, SK_U32 NetIndex);
61PNMI_STATIC int SensorStat(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
62 char *pBuf, unsigned int *pLen, SK_U32 Instance,
63 unsigned int TableIndex, SK_U32 NetIndex);
64PNMI_STATIC int Vpd(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
65 char *pBuf, unsigned int *pLen, SK_U32 Instance,
66 unsigned int TableIndex, SK_U32 NetIndex);
67PNMI_STATIC int Vct(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
68 char *pBuf, unsigned int *pLen, SK_U32 Instance,
69 unsigned int TableIndex, SK_U32 NetIndex);
70
71#ifdef SK_POWER_MGMT
72PNMI_STATIC int PowerManagement(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
73 char *pBuf, unsigned int *pLen, SK_U32 Instance,
74 unsigned int TableIndex, SK_U32 NetIndex);
75#endif /* SK_POWER_MGMT */
76
77#ifdef SK_DIAG_SUPPORT
78PNMI_STATIC int DiagActions(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
79 char *pBuf, unsigned int *pLen, SK_U32 Instance,
80 unsigned int TableIndex, SK_U32 NetIndex);
81#endif /* SK_DIAG_SUPPORT */
82
83
84/* defines *******************************************************************/
85#define ID_TABLE_SIZE (sizeof(IdTable)/sizeof(IdTable[0]))
86
87
88/* global variables **********************************************************/
89
90/*
91 * Table to correlate OID with handler function and index to
92 * hardware register stored in StatAddress if applicable.
93 */
94PNMI_STATIC const SK_PNMI_TAB_ENTRY IdTable[] = {
95 {OID_GEN_XMIT_OK,
96 0,
97 0,
98 0,
99 SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX},
100 {OID_GEN_RCV_OK,
101 0,
102 0,
103 0,
104 SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX},
105 {OID_GEN_XMIT_ERROR,
106 0,
107 0,
108 0,
109 SK_PNMI_RO, General, 0},
110 {OID_GEN_RCV_ERROR,
111 0,
112 0,
113 0,
114 SK_PNMI_RO, General, 0},
115 {OID_GEN_RCV_NO_BUFFER,
116 0,
117 0,
118 0,
119 SK_PNMI_RO, General, 0},
120 {OID_GEN_DIRECTED_FRAMES_XMIT,
121 0,
122 0,
123 0,
124 SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_UNICAST},
125 {OID_GEN_MULTICAST_FRAMES_XMIT,
126 0,
127 0,
128 0,
129 SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_MULTICAST},
130 {OID_GEN_BROADCAST_FRAMES_XMIT,
131 0,
132 0,
133 0,
134 SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_BROADCAST},
135 {OID_GEN_DIRECTED_FRAMES_RCV,
136 0,
137 0,
138 0,
139 SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX_UNICAST},
140 {OID_GEN_MULTICAST_FRAMES_RCV,
141 0,
142 0,
143 0,
144 SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX_MULTICAST},
145 {OID_GEN_BROADCAST_FRAMES_RCV,
146 0,
147 0,
148 0,
149 SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX_BROADCAST},
150 {OID_GEN_RCV_CRC_ERROR,
151 0,
152 0,
153 0,
154 SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX_FCS},
155 {OID_GEN_TRANSMIT_QUEUE_LENGTH,
156 0,
157 0,
158 0,
159 SK_PNMI_RO, General, 0},
160 {OID_802_3_PERMANENT_ADDRESS,
161 0,
162 0,
163 0,
164 SK_PNMI_RO, Mac8023Stat, 0},
165 {OID_802_3_CURRENT_ADDRESS,
166 0,
167 0,
168 0,
169 SK_PNMI_RO, Mac8023Stat, 0},
170 {OID_802_3_RCV_ERROR_ALIGNMENT,
171 0,
172 0,
173 0,
174 SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX_FRAMING},
175 {OID_802_3_XMIT_ONE_COLLISION,
176 0,
177 0,
178 0,
179 SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_SINGLE_COL},
180 {OID_802_3_XMIT_MORE_COLLISIONS,
181 0,
182 0,
183 0,
184 SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_MULTI_COL},
185 {OID_802_3_XMIT_DEFERRED,
186 0,
187 0,
188 0,
189 SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_DEFFERAL},
190 {OID_802_3_XMIT_MAX_COLLISIONS,
191 0,
192 0,
193 0,
194 SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_EXCESS_COL},
195 {OID_802_3_RCV_OVERRUN,
196 0,
197 0,
198 0,
199 SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX_OVERFLOW},
200 {OID_802_3_XMIT_UNDERRUN,
201 0,
202 0,
203 0,
204 SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_UNDERRUN},
205 {OID_802_3_XMIT_TIMES_CRS_LOST,
206 0,
207 0,
208 0,
209 SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_CARRIER},
210 {OID_802_3_XMIT_LATE_COLLISIONS,
211 0,
212 0,
213 0,
214 SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_LATE_COL},
215#ifdef SK_POWER_MGMT
216 {OID_PNP_CAPABILITIES,
217 0,
218 0,
219 0,
220 SK_PNMI_RO, PowerManagement, 0},
221 {OID_PNP_SET_POWER,
222 0,
223 0,
224 0,
225 SK_PNMI_WO, PowerManagement, 0},
226 {OID_PNP_QUERY_POWER,
227 0,
228 0,
229 0,
230 SK_PNMI_RO, PowerManagement, 0},
231 {OID_PNP_ADD_WAKE_UP_PATTERN,
232 0,
233 0,
234 0,
235 SK_PNMI_WO, PowerManagement, 0},
236 {OID_PNP_REMOVE_WAKE_UP_PATTERN,
237 0,
238 0,
239 0,
240 SK_PNMI_WO, PowerManagement, 0},
241 {OID_PNP_ENABLE_WAKE_UP,
242 0,
243 0,
244 0,
245 SK_PNMI_RW, PowerManagement, 0},
246#endif /* SK_POWER_MGMT */
247#ifdef SK_DIAG_SUPPORT
248 {OID_SKGE_DIAG_MODE,
249 0,
250 0,
251 0,
252 SK_PNMI_RW, DiagActions, 0},
253#endif /* SK_DIAG_SUPPORT */
254 {OID_SKGE_MDB_VERSION,
255 1,
256 0,
257 SK_PNMI_MAI_OFF(MgmtDBVersion),
258 SK_PNMI_RO, General, 0},
259 {OID_SKGE_SUPPORTED_LIST,
260 0,
261 0,
262 0,
263 SK_PNMI_RO, General, 0},
264 {OID_SKGE_ALL_DATA,
265 0,
266 0,
267 0,
268 SK_PNMI_RW, OidStruct, 0},
269 {OID_SKGE_VPD_FREE_BYTES,
270 1,
271 0,
272 SK_PNMI_MAI_OFF(VpdFreeBytes),
273 SK_PNMI_RO, Vpd, 0},
274 {OID_SKGE_VPD_ENTRIES_LIST,
275 1,
276 0,
277 SK_PNMI_MAI_OFF(VpdEntriesList),
278 SK_PNMI_RO, Vpd, 0},
279 {OID_SKGE_VPD_ENTRIES_NUMBER,
280 1,
281 0,
282 SK_PNMI_MAI_OFF(VpdEntriesNumber),
283 SK_PNMI_RO, Vpd, 0},
284 {OID_SKGE_VPD_KEY,
285 SK_PNMI_VPD_ENTRIES,
286 sizeof(SK_PNMI_VPD),
287 SK_PNMI_OFF(Vpd) + SK_PNMI_VPD_OFF(VpdKey),
288 SK_PNMI_RO, Vpd, 0},
289 {OID_SKGE_VPD_VALUE,
290 SK_PNMI_VPD_ENTRIES,
291 sizeof(SK_PNMI_VPD),
292 SK_PNMI_OFF(Vpd) + SK_PNMI_VPD_OFF(VpdValue),
293 SK_PNMI_RO, Vpd, 0},
294 {OID_SKGE_VPD_ACCESS,
295 SK_PNMI_VPD_ENTRIES,
296 sizeof(SK_PNMI_VPD),
297 SK_PNMI_OFF(Vpd) + SK_PNMI_VPD_OFF(VpdAccess),
298 SK_PNMI_RO, Vpd, 0},
299 {OID_SKGE_VPD_ACTION,
300 SK_PNMI_VPD_ENTRIES,
301 sizeof(SK_PNMI_VPD),
302 SK_PNMI_OFF(Vpd) + SK_PNMI_VPD_OFF(VpdAction),
303 SK_PNMI_RW, Vpd, 0},
304 {OID_SKGE_PORT_NUMBER,
305 1,
306 0,
307 SK_PNMI_MAI_OFF(PortNumber),
308 SK_PNMI_RO, General, 0},
309 {OID_SKGE_DEVICE_TYPE,
310 1,
311 0,
312 SK_PNMI_MAI_OFF(DeviceType),
313 SK_PNMI_RO, General, 0},
314 {OID_SKGE_DRIVER_DESCR,
315 1,
316 0,
317 SK_PNMI_MAI_OFF(DriverDescr),
318 SK_PNMI_RO, General, 0},
319 {OID_SKGE_DRIVER_VERSION,
320 1,
321 0,
322 SK_PNMI_MAI_OFF(DriverVersion),
323 SK_PNMI_RO, General, 0},
324 {OID_SKGE_DRIVER_RELDATE,
325 1,
326 0,
327 SK_PNMI_MAI_OFF(DriverReleaseDate),
328 SK_PNMI_RO, General, 0},
329 {OID_SKGE_DRIVER_FILENAME,
330 1,
331 0,
332 SK_PNMI_MAI_OFF(DriverFileName),
333 SK_PNMI_RO, General, 0},
334 {OID_SKGE_HW_DESCR,
335 1,
336 0,
337 SK_PNMI_MAI_OFF(HwDescr),
338 SK_PNMI_RO, General, 0},
339 {OID_SKGE_HW_VERSION,
340 1,
341 0,
342 SK_PNMI_MAI_OFF(HwVersion),
343 SK_PNMI_RO, General, 0},
344 {OID_SKGE_CHIPSET,
345 1,
346 0,
347 SK_PNMI_MAI_OFF(Chipset),
348 SK_PNMI_RO, General, 0},
349 {OID_SKGE_CHIPID,
350 1,
351 0,
352 SK_PNMI_MAI_OFF(ChipId),
353 SK_PNMI_RO, General, 0},
354 {OID_SKGE_RAMSIZE,
355 1,
356 0,
357 SK_PNMI_MAI_OFF(RamSize),
358 SK_PNMI_RO, General, 0},
359 {OID_SKGE_VAUXAVAIL,
360 1,
361 0,
362 SK_PNMI_MAI_OFF(VauxAvail),
363 SK_PNMI_RO, General, 0},
364 {OID_SKGE_ACTION,
365 1,
366 0,
367 SK_PNMI_MAI_OFF(Action),
368 SK_PNMI_RW, Perform, 0},
369 {OID_SKGE_RESULT,
370 1,
371 0,
372 SK_PNMI_MAI_OFF(TestResult),
373 SK_PNMI_RO, General, 0},
374 {OID_SKGE_BUS_TYPE,
375 1,
376 0,
377 SK_PNMI_MAI_OFF(BusType),
378 SK_PNMI_RO, General, 0},
379 {OID_SKGE_BUS_SPEED,
380 1,
381 0,
382 SK_PNMI_MAI_OFF(BusSpeed),
383 SK_PNMI_RO, General, 0},
384 {OID_SKGE_BUS_WIDTH,
385 1,
386 0,
387 SK_PNMI_MAI_OFF(BusWidth),
388 SK_PNMI_RO, General, 0},
389 {OID_SKGE_TX_SW_QUEUE_LEN,
390 1,
391 0,
392 SK_PNMI_MAI_OFF(TxSwQueueLen),
393 SK_PNMI_RO, General, 0},
394 {OID_SKGE_TX_SW_QUEUE_MAX,
395 1,
396 0,
397 SK_PNMI_MAI_OFF(TxSwQueueMax),
398 SK_PNMI_RO, General, 0},
399 {OID_SKGE_TX_RETRY,
400 1,
401 0,
402 SK_PNMI_MAI_OFF(TxRetryCts),
403 SK_PNMI_RO, General, 0},
404 {OID_SKGE_RX_INTR_CTS,
405 1,
406 0,
407 SK_PNMI_MAI_OFF(RxIntrCts),
408 SK_PNMI_RO, General, 0},
409 {OID_SKGE_TX_INTR_CTS,
410 1,
411 0,
412 SK_PNMI_MAI_OFF(TxIntrCts),
413 SK_PNMI_RO, General, 0},
414 {OID_SKGE_RX_NO_BUF_CTS,
415 1,
416 0,
417 SK_PNMI_MAI_OFF(RxNoBufCts),
418 SK_PNMI_RO, General, 0},
419 {OID_SKGE_TX_NO_BUF_CTS,
420 1,
421 0,
422 SK_PNMI_MAI_OFF(TxNoBufCts),
423 SK_PNMI_RO, General, 0},
424 {OID_SKGE_TX_USED_DESCR_NO,
425 1,
426 0,
427 SK_PNMI_MAI_OFF(TxUsedDescrNo),
428 SK_PNMI_RO, General, 0},
429 {OID_SKGE_RX_DELIVERED_CTS,
430 1,
431 0,
432 SK_PNMI_MAI_OFF(RxDeliveredCts),
433 SK_PNMI_RO, General, 0},
434 {OID_SKGE_RX_OCTETS_DELIV_CTS,
435 1,
436 0,
437 SK_PNMI_MAI_OFF(RxOctetsDeliveredCts),
438 SK_PNMI_RO, General, 0},
439 {OID_SKGE_RX_HW_ERROR_CTS,
440 1,
441 0,
442 SK_PNMI_MAI_OFF(RxHwErrorsCts),
443 SK_PNMI_RO, General, 0},
444 {OID_SKGE_TX_HW_ERROR_CTS,
445 1,
446 0,
447 SK_PNMI_MAI_OFF(TxHwErrorsCts),
448 SK_PNMI_RO, General, 0},
449 {OID_SKGE_IN_ERRORS_CTS,
450 1,
451 0,
452 SK_PNMI_MAI_OFF(InErrorsCts),
453 SK_PNMI_RO, General, 0},
454 {OID_SKGE_OUT_ERROR_CTS,
455 1,
456 0,
457 SK_PNMI_MAI_OFF(OutErrorsCts),
458 SK_PNMI_RO, General, 0},
459 {OID_SKGE_ERR_RECOVERY_CTS,
460 1,
461 0,
462 SK_PNMI_MAI_OFF(ErrRecoveryCts),
463 SK_PNMI_RO, General, 0},
464 {OID_SKGE_SYSUPTIME,
465 1,
466 0,
467 SK_PNMI_MAI_OFF(SysUpTime),
468 SK_PNMI_RO, General, 0},
469 {OID_SKGE_SENSOR_NUMBER,
470 1,
471 0,
472 SK_PNMI_MAI_OFF(SensorNumber),
473 SK_PNMI_RO, General, 0},
474 {OID_SKGE_SENSOR_INDEX,
475 SK_PNMI_SENSOR_ENTRIES,
476 sizeof(SK_PNMI_SENSOR),
477 SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorIndex),
478 SK_PNMI_RO, SensorStat, 0},
479 {OID_SKGE_SENSOR_DESCR,
480 SK_PNMI_SENSOR_ENTRIES,
481 sizeof(SK_PNMI_SENSOR),
482 SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorDescr),
483 SK_PNMI_RO, SensorStat, 0},
484 {OID_SKGE_SENSOR_TYPE,
485 SK_PNMI_SENSOR_ENTRIES,
486 sizeof(SK_PNMI_SENSOR),
487 SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorType),
488 SK_PNMI_RO, SensorStat, 0},
489 {OID_SKGE_SENSOR_VALUE,
490 SK_PNMI_SENSOR_ENTRIES,
491 sizeof(SK_PNMI_SENSOR),
492 SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorValue),
493 SK_PNMI_RO, SensorStat, 0},
494 {OID_SKGE_SENSOR_WAR_THRES_LOW,
495 SK_PNMI_SENSOR_ENTRIES,
496 sizeof(SK_PNMI_SENSOR),
497 SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorWarningThresholdLow),
498 SK_PNMI_RO, SensorStat, 0},
499 {OID_SKGE_SENSOR_WAR_THRES_UPP,
500 SK_PNMI_SENSOR_ENTRIES,
501 sizeof(SK_PNMI_SENSOR),
502 SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorWarningThresholdHigh),
503 SK_PNMI_RO, SensorStat, 0},
504 {OID_SKGE_SENSOR_ERR_THRES_LOW,
505 SK_PNMI_SENSOR_ENTRIES,
506 sizeof(SK_PNMI_SENSOR),
507 SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorErrorThresholdLow),
508 SK_PNMI_RO, SensorStat, 0},
509 {OID_SKGE_SENSOR_ERR_THRES_UPP,
510 SK_PNMI_SENSOR_ENTRIES,
511 sizeof(SK_PNMI_SENSOR),
512 SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorErrorThresholdHigh),
513 SK_PNMI_RO, SensorStat, 0},
514 {OID_SKGE_SENSOR_STATUS,
515 SK_PNMI_SENSOR_ENTRIES,
516 sizeof(SK_PNMI_SENSOR),
517 SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorStatus),
518 SK_PNMI_RO, SensorStat, 0},
519 {OID_SKGE_SENSOR_WAR_CTS,
520 SK_PNMI_SENSOR_ENTRIES,
521 sizeof(SK_PNMI_SENSOR),
522 SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorWarningCts),
523 SK_PNMI_RO, SensorStat, 0},
524 {OID_SKGE_SENSOR_ERR_CTS,
525 SK_PNMI_SENSOR_ENTRIES,
526 sizeof(SK_PNMI_SENSOR),
527 SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorErrorCts),
528 SK_PNMI_RO, SensorStat, 0},
529 {OID_SKGE_SENSOR_WAR_TIME,
530 SK_PNMI_SENSOR_ENTRIES,
531 sizeof(SK_PNMI_SENSOR),
532 SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorWarningTimestamp),
533 SK_PNMI_RO, SensorStat, 0},
534 {OID_SKGE_SENSOR_ERR_TIME,
535 SK_PNMI_SENSOR_ENTRIES,
536 sizeof(SK_PNMI_SENSOR),
537 SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorErrorTimestamp),
538 SK_PNMI_RO, SensorStat, 0},
539 {OID_SKGE_CHKSM_NUMBER,
540 1,
541 0,
542 SK_PNMI_MAI_OFF(ChecksumNumber),
543 SK_PNMI_RO, General, 0},
544 {OID_SKGE_CHKSM_RX_OK_CTS,
545 SKCS_NUM_PROTOCOLS,
546 sizeof(SK_PNMI_CHECKSUM),
547 SK_PNMI_OFF(Checksum) + SK_PNMI_CHK_OFF(ChecksumRxOkCts),
548 SK_PNMI_RO, CsumStat, 0},
549 {OID_SKGE_CHKSM_RX_UNABLE_CTS,
550 SKCS_NUM_PROTOCOLS,
551 sizeof(SK_PNMI_CHECKSUM),
552 SK_PNMI_OFF(Checksum) + SK_PNMI_CHK_OFF(ChecksumRxUnableCts),
553 SK_PNMI_RO, CsumStat, 0},
554 {OID_SKGE_CHKSM_RX_ERR_CTS,
555 SKCS_NUM_PROTOCOLS,
556 sizeof(SK_PNMI_CHECKSUM),
557 SK_PNMI_OFF(Checksum) + SK_PNMI_CHK_OFF(ChecksumRxErrCts),
558 SK_PNMI_RO, CsumStat, 0},
559 {OID_SKGE_CHKSM_TX_OK_CTS,
560 SKCS_NUM_PROTOCOLS,
561 sizeof(SK_PNMI_CHECKSUM),
562 SK_PNMI_OFF(Checksum) + SK_PNMI_CHK_OFF(ChecksumTxOkCts),
563 SK_PNMI_RO, CsumStat, 0},
564 {OID_SKGE_CHKSM_TX_UNABLE_CTS,
565 SKCS_NUM_PROTOCOLS,
566 sizeof(SK_PNMI_CHECKSUM),
567 SK_PNMI_OFF(Checksum) + SK_PNMI_CHK_OFF(ChecksumTxUnableCts),
568 SK_PNMI_RO, CsumStat, 0},
569 {OID_SKGE_STAT_TX,
570 SK_PNMI_MAC_ENTRIES,
571 sizeof(SK_PNMI_STAT),
572 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxOkCts),
573 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX},
574 {OID_SKGE_STAT_TX_OCTETS,
575 SK_PNMI_MAC_ENTRIES,
576 sizeof(SK_PNMI_STAT),
577 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxOctetsOkCts),
578 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_OCTET},
579 {OID_SKGE_STAT_TX_BROADCAST,
580 SK_PNMI_MAC_ENTRIES,
581 sizeof(SK_PNMI_STAT),
582 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxBroadcastOkCts),
583 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_BROADCAST},
584 {OID_SKGE_STAT_TX_MULTICAST,
585 SK_PNMI_MAC_ENTRIES,
586 sizeof(SK_PNMI_STAT),
587 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxMulticastOkCts),
588 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_MULTICAST},
589 {OID_SKGE_STAT_TX_UNICAST,
590 SK_PNMI_MAC_ENTRIES,
591 sizeof(SK_PNMI_STAT),
592 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxUnicastOkCts),
593 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_UNICAST},
594 {OID_SKGE_STAT_TX_LONGFRAMES,
595 SK_PNMI_MAC_ENTRIES,
596 sizeof(SK_PNMI_STAT),
597 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxLongFramesCts),
598 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_LONGFRAMES},
599 {OID_SKGE_STAT_TX_BURST,
600 SK_PNMI_MAC_ENTRIES,
601 sizeof(SK_PNMI_STAT),
602 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxBurstCts),
603 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_BURST},
604 {OID_SKGE_STAT_TX_PFLOWC,
605 SK_PNMI_MAC_ENTRIES,
606 sizeof(SK_PNMI_STAT),
607 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxPauseMacCtrlCts),
608 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_PMACC},
609 {OID_SKGE_STAT_TX_FLOWC,
610 SK_PNMI_MAC_ENTRIES,
611 sizeof(SK_PNMI_STAT),
612 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxMacCtrlCts),
613 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_MACC},
614 {OID_SKGE_STAT_TX_SINGLE_COL,
615 SK_PNMI_MAC_ENTRIES,
616 sizeof(SK_PNMI_STAT),
617 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxSingleCollisionCts),
618 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_SINGLE_COL},
619 {OID_SKGE_STAT_TX_MULTI_COL,
620 SK_PNMI_MAC_ENTRIES,
621 sizeof(SK_PNMI_STAT),
622 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxMultipleCollisionCts),
623 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_MULTI_COL},
624 {OID_SKGE_STAT_TX_EXCESS_COL,
625 SK_PNMI_MAC_ENTRIES,
626 sizeof(SK_PNMI_STAT),
627 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxExcessiveCollisionCts),
628 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_EXCESS_COL},
629 {OID_SKGE_STAT_TX_LATE_COL,
630 SK_PNMI_MAC_ENTRIES,
631 sizeof(SK_PNMI_STAT),
632 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxLateCollisionCts),
633 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_LATE_COL},
634 {OID_SKGE_STAT_TX_DEFFERAL,
635 SK_PNMI_MAC_ENTRIES,
636 sizeof(SK_PNMI_STAT),
637 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxDeferralCts),
638 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_DEFFERAL},
639 {OID_SKGE_STAT_TX_EXCESS_DEF,
640 SK_PNMI_MAC_ENTRIES,
641 sizeof(SK_PNMI_STAT),
642 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxExcessiveDeferralCts),
643 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_EXCESS_DEF},
644 {OID_SKGE_STAT_TX_UNDERRUN,
645 SK_PNMI_MAC_ENTRIES,
646 sizeof(SK_PNMI_STAT),
647 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxFifoUnderrunCts),
648 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_UNDERRUN},
649 {OID_SKGE_STAT_TX_CARRIER,
650 SK_PNMI_MAC_ENTRIES,
651 sizeof(SK_PNMI_STAT),
652 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxCarrierCts),
653 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_CARRIER},
654/* {OID_SKGE_STAT_TX_UTIL,
655 SK_PNMI_MAC_ENTRIES,
656 sizeof(SK_PNMI_STAT),
657 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxUtilization),
658 SK_PNMI_RO, MacPrivateStat, (SK_U16)(-1)}, */
659 {OID_SKGE_STAT_TX_64,
660 SK_PNMI_MAC_ENTRIES,
661 sizeof(SK_PNMI_STAT),
662 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTx64Cts),
663 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_64},
664 {OID_SKGE_STAT_TX_127,
665 SK_PNMI_MAC_ENTRIES,
666 sizeof(SK_PNMI_STAT),
667 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTx127Cts),
668 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_127},
669 {OID_SKGE_STAT_TX_255,
670 SK_PNMI_MAC_ENTRIES,
671 sizeof(SK_PNMI_STAT),
672 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTx255Cts),
673 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_255},
674 {OID_SKGE_STAT_TX_511,
675 SK_PNMI_MAC_ENTRIES,
676 sizeof(SK_PNMI_STAT),
677 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTx511Cts),
678 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_511},
679 {OID_SKGE_STAT_TX_1023,
680 SK_PNMI_MAC_ENTRIES,
681 sizeof(SK_PNMI_STAT),
682 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTx1023Cts),
683 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_1023},
684 {OID_SKGE_STAT_TX_MAX,
685 SK_PNMI_MAC_ENTRIES,
686 sizeof(SK_PNMI_STAT),
687 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxMaxCts),
688 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_MAX},
689 {OID_SKGE_STAT_TX_SYNC,
690 SK_PNMI_MAC_ENTRIES,
691 sizeof(SK_PNMI_STAT),
692 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxSyncCts),
693 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_SYNC},
694 {OID_SKGE_STAT_TX_SYNC_OCTETS,
695 SK_PNMI_MAC_ENTRIES,
696 sizeof(SK_PNMI_STAT),
697 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxSyncOctetsCts),
698 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_SYNC_OCTET},
699 {OID_SKGE_STAT_RX,
700 SK_PNMI_MAC_ENTRIES,
701 sizeof(SK_PNMI_STAT),
702 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxOkCts),
703 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX},
704 {OID_SKGE_STAT_RX_OCTETS,
705 SK_PNMI_MAC_ENTRIES,
706 sizeof(SK_PNMI_STAT),
707 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxOctetsOkCts),
708 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_OCTET},
709 {OID_SKGE_STAT_RX_BROADCAST,
710 SK_PNMI_MAC_ENTRIES,
711 sizeof(SK_PNMI_STAT),
712 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxBroadcastOkCts),
713 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_BROADCAST},
714 {OID_SKGE_STAT_RX_MULTICAST,
715 SK_PNMI_MAC_ENTRIES,
716 sizeof(SK_PNMI_STAT),
717 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxMulticastOkCts),
718 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_MULTICAST},
719 {OID_SKGE_STAT_RX_UNICAST,
720 SK_PNMI_MAC_ENTRIES,
721 sizeof(SK_PNMI_STAT),
722 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxUnicastOkCts),
723 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_UNICAST},
724 {OID_SKGE_STAT_RX_LONGFRAMES,
725 SK_PNMI_MAC_ENTRIES,
726 sizeof(SK_PNMI_STAT),
727 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxLongFramesCts),
728 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_LONGFRAMES},
729 {OID_SKGE_STAT_RX_PFLOWC,
730 SK_PNMI_MAC_ENTRIES,
731 sizeof(SK_PNMI_STAT),
732 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxPauseMacCtrlCts),
733 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_PMACC},
734 {OID_SKGE_STAT_RX_FLOWC,
735 SK_PNMI_MAC_ENTRIES,
736 sizeof(SK_PNMI_STAT),
737 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxMacCtrlCts),
738 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_MACC},
739 {OID_SKGE_STAT_RX_PFLOWC_ERR,
740 SK_PNMI_MAC_ENTRIES,
741 sizeof(SK_PNMI_STAT),
742 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxPauseMacCtrlErrorCts),
743 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_PMACC_ERR},
744 {OID_SKGE_STAT_RX_FLOWC_UNKWN,
745 SK_PNMI_MAC_ENTRIES,
746 sizeof(SK_PNMI_STAT),
747 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxMacCtrlUnknownCts),
748 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_MACC_UNKWN},
749 {OID_SKGE_STAT_RX_BURST,
750 SK_PNMI_MAC_ENTRIES,
751 sizeof(SK_PNMI_STAT),
752 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxBurstCts),
753 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_BURST},
754 {OID_SKGE_STAT_RX_MISSED,
755 SK_PNMI_MAC_ENTRIES,
756 sizeof(SK_PNMI_STAT),
757 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxMissedCts),
758 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_MISSED},
759 {OID_SKGE_STAT_RX_FRAMING,
760 SK_PNMI_MAC_ENTRIES,
761 sizeof(SK_PNMI_STAT),
762 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxFramingCts),
763 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_FRAMING},
764 {OID_SKGE_STAT_RX_OVERFLOW,
765 SK_PNMI_MAC_ENTRIES,
766 sizeof(SK_PNMI_STAT),
767 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxFifoOverflowCts),
768 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_OVERFLOW},
769 {OID_SKGE_STAT_RX_JABBER,
770 SK_PNMI_MAC_ENTRIES,
771 sizeof(SK_PNMI_STAT),
772 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxJabberCts),
773 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_JABBER},
774 {OID_SKGE_STAT_RX_CARRIER,
775 SK_PNMI_MAC_ENTRIES,
776 sizeof(SK_PNMI_STAT),
777 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxCarrierCts),
778 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_CARRIER},
779 {OID_SKGE_STAT_RX_IR_LENGTH,
780 SK_PNMI_MAC_ENTRIES,
781 sizeof(SK_PNMI_STAT),
782 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxIRLengthCts),
783 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_IRLENGTH},
784 {OID_SKGE_STAT_RX_SYMBOL,
785 SK_PNMI_MAC_ENTRIES,
786 sizeof(SK_PNMI_STAT),
787 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxSymbolCts),
788 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_SYMBOL},
789 {OID_SKGE_STAT_RX_SHORTS,
790 SK_PNMI_MAC_ENTRIES,
791 sizeof(SK_PNMI_STAT),
792 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxShortsCts),
793 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_SHORTS},
794 {OID_SKGE_STAT_RX_RUNT,
795 SK_PNMI_MAC_ENTRIES,
796 sizeof(SK_PNMI_STAT),
797 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxRuntCts),
798 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_RUNT},
799 {OID_SKGE_STAT_RX_CEXT,
800 SK_PNMI_MAC_ENTRIES,
801 sizeof(SK_PNMI_STAT),
802 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxCextCts),
803 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_CEXT},
804 {OID_SKGE_STAT_RX_TOO_LONG,
805 SK_PNMI_MAC_ENTRIES,
806 sizeof(SK_PNMI_STAT),
807 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxTooLongCts),
808 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_TOO_LONG},
809 {OID_SKGE_STAT_RX_FCS,
810 SK_PNMI_MAC_ENTRIES,
811 sizeof(SK_PNMI_STAT),
812 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxFcsCts),
813 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_FCS},
814/* {OID_SKGE_STAT_RX_UTIL,
815 SK_PNMI_MAC_ENTRIES,
816 sizeof(SK_PNMI_STAT),
817 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxUtilization),
818 SK_PNMI_RO, MacPrivateStat, (SK_U16)(-1)}, */
819 {OID_SKGE_STAT_RX_64,
820 SK_PNMI_MAC_ENTRIES,
821 sizeof(SK_PNMI_STAT),
822 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRx64Cts),
823 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_64},
824 {OID_SKGE_STAT_RX_127,
825 SK_PNMI_MAC_ENTRIES,
826 sizeof(SK_PNMI_STAT),
827 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRx127Cts),
828 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_127},
829 {OID_SKGE_STAT_RX_255,
830 SK_PNMI_MAC_ENTRIES,
831 sizeof(SK_PNMI_STAT),
832 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRx255Cts),
833 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_255},
834 {OID_SKGE_STAT_RX_511,
835 SK_PNMI_MAC_ENTRIES,
836 sizeof(SK_PNMI_STAT),
837 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRx511Cts),
838 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_511},
839 {OID_SKGE_STAT_RX_1023,
840 SK_PNMI_MAC_ENTRIES,
841 sizeof(SK_PNMI_STAT),
842 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRx1023Cts),
843 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_1023},
844 {OID_SKGE_STAT_RX_MAX,
845 SK_PNMI_MAC_ENTRIES,
846 sizeof(SK_PNMI_STAT),
847 SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxMaxCts),
848 SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_MAX},
849 {OID_SKGE_PHYS_CUR_ADDR,
850 SK_PNMI_MAC_ENTRIES,
851 sizeof(SK_PNMI_CONF),
852 SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfMacCurrentAddr),
853 SK_PNMI_RW, Addr, 0},
854 {OID_SKGE_PHYS_FAC_ADDR,
855 SK_PNMI_MAC_ENTRIES,
856 sizeof(SK_PNMI_CONF),
857 SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfMacFactoryAddr),
858 SK_PNMI_RO, Addr, 0},
859 {OID_SKGE_PMD,
860 SK_PNMI_MAC_ENTRIES,
861 sizeof(SK_PNMI_CONF),
862 SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPMD),
863 SK_PNMI_RO, MacPrivateConf, 0},
864 {OID_SKGE_CONNECTOR,
865 SK_PNMI_MAC_ENTRIES,
866 sizeof(SK_PNMI_CONF),
867 SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfConnector),
868 SK_PNMI_RO, MacPrivateConf, 0},
869 {OID_SKGE_PHY_TYPE,
870 SK_PNMI_MAC_ENTRIES,
871 sizeof(SK_PNMI_CONF),
872 SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPhyType),
873 SK_PNMI_RO, MacPrivateConf, 0},
874 {OID_SKGE_LINK_CAP,
875 SK_PNMI_MAC_ENTRIES,
876 sizeof(SK_PNMI_CONF),
877 SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfLinkCapability),
878 SK_PNMI_RO, MacPrivateConf, 0},
879 {OID_SKGE_LINK_MODE,
880 SK_PNMI_MAC_ENTRIES,
881 sizeof(SK_PNMI_CONF),
882 SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfLinkMode),
883 SK_PNMI_RW, MacPrivateConf, 0},
884 {OID_SKGE_LINK_MODE_STATUS,
885 SK_PNMI_MAC_ENTRIES,
886 sizeof(SK_PNMI_CONF),
887 SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfLinkModeStatus),
888 SK_PNMI_RO, MacPrivateConf, 0},
889 {OID_SKGE_LINK_STATUS,
890 SK_PNMI_MAC_ENTRIES,
891 sizeof(SK_PNMI_CONF),
892 SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfLinkStatus),
893 SK_PNMI_RO, MacPrivateConf, 0},
894 {OID_SKGE_FLOWCTRL_CAP,
895 SK_PNMI_MAC_ENTRIES,
896 sizeof(SK_PNMI_CONF),
897 SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfFlowCtrlCapability),
898 SK_PNMI_RO, MacPrivateConf, 0},
899 {OID_SKGE_FLOWCTRL_MODE,
900 SK_PNMI_MAC_ENTRIES,
901 sizeof(SK_PNMI_CONF),
902 SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfFlowCtrlMode),
903 SK_PNMI_RW, MacPrivateConf, 0},
904 {OID_SKGE_FLOWCTRL_STATUS,
905 SK_PNMI_MAC_ENTRIES,
906 sizeof(SK_PNMI_CONF),
907 SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfFlowCtrlStatus),
908 SK_PNMI_RO, MacPrivateConf, 0},
909 {OID_SKGE_PHY_OPERATION_CAP,
910 SK_PNMI_MAC_ENTRIES,
911 sizeof(SK_PNMI_CONF),
912 SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPhyOperationCapability),
913 SK_PNMI_RO, MacPrivateConf, 0},
914 {OID_SKGE_PHY_OPERATION_MODE,
915 SK_PNMI_MAC_ENTRIES,
916 sizeof(SK_PNMI_CONF),
917 SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPhyOperationMode),
918 SK_PNMI_RW, MacPrivateConf, 0},
919 {OID_SKGE_PHY_OPERATION_STATUS,
920 SK_PNMI_MAC_ENTRIES,
921 sizeof(SK_PNMI_CONF),
922 SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPhyOperationStatus),
923 SK_PNMI_RO, MacPrivateConf, 0},
924 {OID_SKGE_SPEED_CAP,
925 SK_PNMI_MAC_ENTRIES,
926 sizeof(SK_PNMI_CONF),
927 SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfSpeedCapability),
928 SK_PNMI_RO, MacPrivateConf, 0},
929 {OID_SKGE_SPEED_MODE,
930 SK_PNMI_MAC_ENTRIES,
931 sizeof(SK_PNMI_CONF),
932 SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfSpeedMode),
933 SK_PNMI_RW, MacPrivateConf, 0},
934 {OID_SKGE_SPEED_STATUS,
935 SK_PNMI_MAC_ENTRIES,
936 sizeof(SK_PNMI_CONF),
937 SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfSpeedStatus),
938 SK_PNMI_RO, MacPrivateConf, 0},
939 {OID_SKGE_TRAP,
940 1,
941 0,
942 SK_PNMI_MAI_OFF(Trap),
943 SK_PNMI_RO, General, 0},
944 {OID_SKGE_TRAP_NUMBER,
945 1,
946 0,
947 SK_PNMI_MAI_OFF(TrapNumber),
948 SK_PNMI_RO, General, 0},
949 {OID_SKGE_RLMT_MODE,
950 1,
951 0,
952 SK_PNMI_MAI_OFF(RlmtMode),
953 SK_PNMI_RW, Rlmt, 0},
954 {OID_SKGE_RLMT_PORT_NUMBER,
955 1,
956 0,
957 SK_PNMI_MAI_OFF(RlmtPortNumber),
958 SK_PNMI_RO, Rlmt, 0},
959 {OID_SKGE_RLMT_PORT_ACTIVE,
960 1,
961 0,
962 SK_PNMI_MAI_OFF(RlmtPortActive),
963 SK_PNMI_RO, Rlmt, 0},
964 {OID_SKGE_RLMT_PORT_PREFERRED,
965 1,
966 0,
967 SK_PNMI_MAI_OFF(RlmtPortPreferred),
968 SK_PNMI_RW, Rlmt, 0},
969 {OID_SKGE_RLMT_CHANGE_CTS,
970 1,
971 0,
972 SK_PNMI_MAI_OFF(RlmtChangeCts),
973 SK_PNMI_RO, Rlmt, 0},
974 {OID_SKGE_RLMT_CHANGE_TIME,
975 1,
976 0,
977 SK_PNMI_MAI_OFF(RlmtChangeTime),
978 SK_PNMI_RO, Rlmt, 0},
979 {OID_SKGE_RLMT_CHANGE_ESTIM,
980 1,
981 0,
982 SK_PNMI_MAI_OFF(RlmtChangeEstimate),
983 SK_PNMI_RO, Rlmt, 0},
984 {OID_SKGE_RLMT_CHANGE_THRES,
985 1,
986 0,
987 SK_PNMI_MAI_OFF(RlmtChangeThreshold),
988 SK_PNMI_RW, Rlmt, 0},
989 {OID_SKGE_RLMT_PORT_INDEX,
990 SK_PNMI_MAC_ENTRIES,
991 sizeof(SK_PNMI_RLMT),
992 SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtIndex),
993 SK_PNMI_RO, RlmtStat, 0},
994 {OID_SKGE_RLMT_STATUS,
995 SK_PNMI_MAC_ENTRIES,
996 sizeof(SK_PNMI_RLMT),
997 SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtStatus),
998 SK_PNMI_RO, RlmtStat, 0},
999 {OID_SKGE_RLMT_TX_HELLO_CTS,
1000 SK_PNMI_MAC_ENTRIES,
1001 sizeof(SK_PNMI_RLMT),
1002 SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtTxHelloCts),
1003 SK_PNMI_RO, RlmtStat, 0},
1004 {OID_SKGE_RLMT_RX_HELLO_CTS,
1005 SK_PNMI_MAC_ENTRIES,
1006 sizeof(SK_PNMI_RLMT),
1007 SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtRxHelloCts),
1008 SK_PNMI_RO, RlmtStat, 0},
1009 {OID_SKGE_RLMT_TX_SP_REQ_CTS,
1010 SK_PNMI_MAC_ENTRIES,
1011 sizeof(SK_PNMI_RLMT),
1012 SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtTxSpHelloReqCts),
1013 SK_PNMI_RO, RlmtStat, 0},
1014 {OID_SKGE_RLMT_RX_SP_CTS,
1015 SK_PNMI_MAC_ENTRIES,
1016 sizeof(SK_PNMI_RLMT),
1017 SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtRxSpHelloCts),
1018 SK_PNMI_RO, RlmtStat, 0},
1019 {OID_SKGE_RLMT_MONITOR_NUMBER,
1020 1,
1021 0,
1022 SK_PNMI_MAI_OFF(RlmtMonitorNumber),
1023 SK_PNMI_RO, General, 0},
1024 {OID_SKGE_RLMT_MONITOR_INDEX,
1025 SK_PNMI_MONITOR_ENTRIES,
1026 sizeof(SK_PNMI_RLMT_MONITOR),
1027 SK_PNMI_OFF(RlmtMonitor) + SK_PNMI_MON_OFF(RlmtMonitorIndex),
1028 SK_PNMI_RO, Monitor, 0},
1029 {OID_SKGE_RLMT_MONITOR_ADDR,
1030 SK_PNMI_MONITOR_ENTRIES,
1031 sizeof(SK_PNMI_RLMT_MONITOR),
1032 SK_PNMI_OFF(RlmtMonitor) + SK_PNMI_MON_OFF(RlmtMonitorAddr),
1033 SK_PNMI_RO, Monitor, 0},
1034 {OID_SKGE_RLMT_MONITOR_ERRS,
1035 SK_PNMI_MONITOR_ENTRIES,
1036 sizeof(SK_PNMI_RLMT_MONITOR),
1037 SK_PNMI_OFF(RlmtMonitor) + SK_PNMI_MON_OFF(RlmtMonitorErrorCts),
1038 SK_PNMI_RO, Monitor, 0},
1039 {OID_SKGE_RLMT_MONITOR_TIMESTAMP,
1040 SK_PNMI_MONITOR_ENTRIES,
1041 sizeof(SK_PNMI_RLMT_MONITOR),
1042 SK_PNMI_OFF(RlmtMonitor) + SK_PNMI_MON_OFF(RlmtMonitorTimestamp),
1043 SK_PNMI_RO, Monitor, 0},
1044 {OID_SKGE_RLMT_MONITOR_ADMIN,
1045 SK_PNMI_MONITOR_ENTRIES,
1046 sizeof(SK_PNMI_RLMT_MONITOR),
1047 SK_PNMI_OFF(RlmtMonitor) + SK_PNMI_MON_OFF(RlmtMonitorAdmin),
1048 SK_PNMI_RW, Monitor, 0},
1049 {OID_SKGE_MTU,
1050 1,
1051 0,
1052 SK_PNMI_MAI_OFF(MtuSize),
1053 SK_PNMI_RW, MacPrivateConf, 0},
1054 {OID_SKGE_VCT_GET,
1055 0,
1056 0,
1057 0,
1058 SK_PNMI_RO, Vct, 0},
1059 {OID_SKGE_VCT_SET,
1060 0,
1061 0,
1062 0,
1063 SK_PNMI_WO, Vct, 0},
1064 {OID_SKGE_VCT_STATUS,
1065 0,
1066 0,
1067 0,
1068 SK_PNMI_RO, Vct, 0},
1069 {OID_SKGE_BOARDLEVEL,
1070 0,
1071 0,
1072 0,
1073 SK_PNMI_RO, General, 0},
1074};
1075
diff --git a/drivers/net/sk98lin/skgepnmi.c b/drivers/net/sk98lin/skgepnmi.c
deleted file mode 100644
index b36dd9ac6b29..000000000000
--- a/drivers/net/sk98lin/skgepnmi.c
+++ /dev/null
@@ -1,8210 +0,0 @@
1/*****************************************************************************
2 *
3 * Name: skgepnmi.c
4 * Project: GEnesis, PCI Gigabit Ethernet Adapter
5 * Version: $Revision: 1.111 $
6 * Date: $Date: 2003/09/15 13:35:35 $
7 * Purpose: Private Network Management Interface
8 *
9 ****************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect GmbH.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25
26#ifndef _lint
27static const char SysKonnectFileId[] =
28 "@(#) $Id: skgepnmi.c,v 1.111 2003/09/15 13:35:35 tschilli Exp $ (C) Marvell.";
29#endif /* !_lint */
30
31#include "h/skdrv1st.h"
32#include "h/sktypes.h"
33#include "h/xmac_ii.h"
34#include "h/skdebug.h"
35#include "h/skqueue.h"
36#include "h/skgepnmi.h"
37#include "h/skgesirq.h"
38#include "h/skcsum.h"
39#include "h/skvpd.h"
40#include "h/skgehw.h"
41#include "h/skgeinit.h"
42#include "h/skdrv2nd.h"
43#include "h/skgepnm2.h"
44#ifdef SK_POWER_MGMT
45#include "h/skgepmgt.h"
46#endif
47/* defines *******************************************************************/
48
49#ifndef DEBUG
50#define PNMI_STATIC static
51#else /* DEBUG */
52#define PNMI_STATIC
53#endif /* DEBUG */
54
55/*
56 * Public Function prototypes
57 */
58int SkPnmiInit(SK_AC *pAC, SK_IOC IoC, int level);
59int SkPnmiSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf,
60 unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
61int SkPnmiGetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf,
62 unsigned int *pLen, SK_U32 NetIndex);
63int SkPnmiPreSetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf,
64 unsigned int *pLen, SK_U32 NetIndex);
65int SkPnmiSetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf,
66 unsigned int *pLen, SK_U32 NetIndex);
67int SkPnmiEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, SK_EVPARA Param);
68int SkPnmiGenIoctl(SK_AC *pAC, SK_IOC IoC, void * pBuf,
69 unsigned int * pLen, SK_U32 NetIndex);
70
71
72/*
73 * Private Function prototypes
74 */
75
76PNMI_STATIC SK_U8 CalculateLinkModeStatus(SK_AC *pAC, SK_IOC IoC, unsigned int
77 PhysPortIndex);
78PNMI_STATIC SK_U8 CalculateLinkStatus(SK_AC *pAC, SK_IOC IoC, unsigned int
79 PhysPortIndex);
80PNMI_STATIC void CopyMac(char *pDst, SK_MAC_ADDR *pMac);
81PNMI_STATIC void CopyTrapQueue(SK_AC *pAC, char *pDstBuf);
82PNMI_STATIC SK_U64 GetPhysStatVal(SK_AC *pAC, SK_IOC IoC,
83 unsigned int PhysPortIndex, unsigned int StatIndex);
84PNMI_STATIC SK_U64 GetStatVal(SK_AC *pAC, SK_IOC IoC, unsigned int LogPortIndex,
85 unsigned int StatIndex, SK_U32 NetIndex);
86PNMI_STATIC char* GetTrapEntry(SK_AC *pAC, SK_U32 TrapId, unsigned int Size);
87PNMI_STATIC void GetTrapQueueLen(SK_AC *pAC, unsigned int *pLen,
88 unsigned int *pEntries);
89PNMI_STATIC int GetVpdKeyArr(SK_AC *pAC, SK_IOC IoC, char *pKeyArr,
90 unsigned int KeyArrLen, unsigned int *pKeyNo);
91PNMI_STATIC int LookupId(SK_U32 Id);
92PNMI_STATIC int MacUpdate(SK_AC *pAC, SK_IOC IoC, unsigned int FirstMac,
93 unsigned int LastMac);
94PNMI_STATIC int PnmiStruct(SK_AC *pAC, SK_IOC IoC, int Action, char *pBuf,
95 unsigned int *pLen, SK_U32 NetIndex);
96PNMI_STATIC int PnmiVar(SK_AC *pAC, SK_IOC IoC, int Action, SK_U32 Id,
97 char *pBuf, unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
98PNMI_STATIC void QueueRlmtNewMacTrap(SK_AC *pAC, unsigned int ActiveMac);
99PNMI_STATIC void QueueRlmtPortTrap(SK_AC *pAC, SK_U32 TrapId,
100 unsigned int PortIndex);
101PNMI_STATIC void QueueSensorTrap(SK_AC *pAC, SK_U32 TrapId,
102 unsigned int SensorIndex);
103PNMI_STATIC void QueueSimpleTrap(SK_AC *pAC, SK_U32 TrapId);
104PNMI_STATIC void ResetCounter(SK_AC *pAC, SK_IOC IoC, SK_U32 NetIndex);
105PNMI_STATIC int RlmtUpdate(SK_AC *pAC, SK_IOC IoC, SK_U32 NetIndex);
106PNMI_STATIC int SirqUpdate(SK_AC *pAC, SK_IOC IoC);
107PNMI_STATIC void VirtualConf(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, char *pBuf);
108PNMI_STATIC int Vct(SK_AC *pAC, SK_IOC IoC, int Action, SK_U32 Id, char *pBuf,
109 unsigned int *pLen, SK_U32 Instance, unsigned int TableIndex, SK_U32 NetIndex);
110PNMI_STATIC void CheckVctStatus(SK_AC *, SK_IOC, char *, SK_U32, SK_U32);
111
112/*
113 * Table to correlate OID with handler function and index to
114 * hardware register stored in StatAddress if applicable.
115 */
116#include "skgemib.c"
117
118/* global variables **********************************************************/
119
120/*
121 * Overflow status register bit table and corresponding counter
122 * dependent on MAC type - the number relates to the size of overflow
123 * mask returned by the pFnMacOverflow function
124 */
125PNMI_STATIC const SK_U16 StatOvrflwBit[][SK_PNMI_MAC_TYPES] = {
126/* Bit0 */ { SK_PNMI_HTX, SK_PNMI_HTX_UNICAST},
127/* Bit1 */ { SK_PNMI_HTX_OCTETHIGH, SK_PNMI_HTX_BROADCAST},
128/* Bit2 */ { SK_PNMI_HTX_OCTETLOW, SK_PNMI_HTX_PMACC},
129/* Bit3 */ { SK_PNMI_HTX_BROADCAST, SK_PNMI_HTX_MULTICAST},
130/* Bit4 */ { SK_PNMI_HTX_MULTICAST, SK_PNMI_HTX_OCTETLOW},
131/* Bit5 */ { SK_PNMI_HTX_UNICAST, SK_PNMI_HTX_OCTETHIGH},
132/* Bit6 */ { SK_PNMI_HTX_LONGFRAMES, SK_PNMI_HTX_64},
133/* Bit7 */ { SK_PNMI_HTX_BURST, SK_PNMI_HTX_127},
134/* Bit8 */ { SK_PNMI_HTX_PMACC, SK_PNMI_HTX_255},
135/* Bit9 */ { SK_PNMI_HTX_MACC, SK_PNMI_HTX_511},
136/* Bit10 */ { SK_PNMI_HTX_SINGLE_COL, SK_PNMI_HTX_1023},
137/* Bit11 */ { SK_PNMI_HTX_MULTI_COL, SK_PNMI_HTX_MAX},
138/* Bit12 */ { SK_PNMI_HTX_EXCESS_COL, SK_PNMI_HTX_LONGFRAMES},
139/* Bit13 */ { SK_PNMI_HTX_LATE_COL, SK_PNMI_HTX_RESERVED},
140/* Bit14 */ { SK_PNMI_HTX_DEFFERAL, SK_PNMI_HTX_COL},
141/* Bit15 */ { SK_PNMI_HTX_EXCESS_DEF, SK_PNMI_HTX_LATE_COL},
142/* Bit16 */ { SK_PNMI_HTX_UNDERRUN, SK_PNMI_HTX_EXCESS_COL},
143/* Bit17 */ { SK_PNMI_HTX_CARRIER, SK_PNMI_HTX_MULTI_COL},
144/* Bit18 */ { SK_PNMI_HTX_UTILUNDER, SK_PNMI_HTX_SINGLE_COL},
145/* Bit19 */ { SK_PNMI_HTX_UTILOVER, SK_PNMI_HTX_UNDERRUN},
146/* Bit20 */ { SK_PNMI_HTX_64, SK_PNMI_HTX_RESERVED},
147/* Bit21 */ { SK_PNMI_HTX_127, SK_PNMI_HTX_RESERVED},
148/* Bit22 */ { SK_PNMI_HTX_255, SK_PNMI_HTX_RESERVED},
149/* Bit23 */ { SK_PNMI_HTX_511, SK_PNMI_HTX_RESERVED},
150/* Bit24 */ { SK_PNMI_HTX_1023, SK_PNMI_HTX_RESERVED},
151/* Bit25 */ { SK_PNMI_HTX_MAX, SK_PNMI_HTX_RESERVED},
152/* Bit26 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
153/* Bit27 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
154/* Bit28 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
155/* Bit29 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
156/* Bit30 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
157/* Bit31 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
158/* Bit32 */ { SK_PNMI_HRX, SK_PNMI_HRX_UNICAST},
159/* Bit33 */ { SK_PNMI_HRX_OCTETHIGH, SK_PNMI_HRX_BROADCAST},
160/* Bit34 */ { SK_PNMI_HRX_OCTETLOW, SK_PNMI_HRX_PMACC},
161/* Bit35 */ { SK_PNMI_HRX_BROADCAST, SK_PNMI_HRX_MULTICAST},
162/* Bit36 */ { SK_PNMI_HRX_MULTICAST, SK_PNMI_HRX_FCS},
163/* Bit37 */ { SK_PNMI_HRX_UNICAST, SK_PNMI_HRX_RESERVED},
164/* Bit38 */ { SK_PNMI_HRX_PMACC, SK_PNMI_HRX_OCTETLOW},
165/* Bit39 */ { SK_PNMI_HRX_MACC, SK_PNMI_HRX_OCTETHIGH},
166/* Bit40 */ { SK_PNMI_HRX_PMACC_ERR, SK_PNMI_HRX_BADOCTETLOW},
167/* Bit41 */ { SK_PNMI_HRX_MACC_UNKWN, SK_PNMI_HRX_BADOCTETHIGH},
168/* Bit42 */ { SK_PNMI_HRX_BURST, SK_PNMI_HRX_UNDERSIZE},
169/* Bit43 */ { SK_PNMI_HRX_MISSED, SK_PNMI_HRX_RUNT},
170/* Bit44 */ { SK_PNMI_HRX_FRAMING, SK_PNMI_HRX_64},
171/* Bit45 */ { SK_PNMI_HRX_OVERFLOW, SK_PNMI_HRX_127},
172/* Bit46 */ { SK_PNMI_HRX_JABBER, SK_PNMI_HRX_255},
173/* Bit47 */ { SK_PNMI_HRX_CARRIER, SK_PNMI_HRX_511},
174/* Bit48 */ { SK_PNMI_HRX_IRLENGTH, SK_PNMI_HRX_1023},
175/* Bit49 */ { SK_PNMI_HRX_SYMBOL, SK_PNMI_HRX_MAX},
176/* Bit50 */ { SK_PNMI_HRX_SHORTS, SK_PNMI_HRX_LONGFRAMES},
177/* Bit51 */ { SK_PNMI_HRX_RUNT, SK_PNMI_HRX_TOO_LONG},
178/* Bit52 */ { SK_PNMI_HRX_TOO_LONG, SK_PNMI_HRX_JABBER},
179/* Bit53 */ { SK_PNMI_HRX_FCS, SK_PNMI_HRX_RESERVED},
180/* Bit54 */ { SK_PNMI_HRX_RESERVED, SK_PNMI_HRX_OVERFLOW},
181/* Bit55 */ { SK_PNMI_HRX_CEXT, SK_PNMI_HRX_RESERVED},
182/* Bit56 */ { SK_PNMI_HRX_UTILUNDER, SK_PNMI_HRX_RESERVED},
183/* Bit57 */ { SK_PNMI_HRX_UTILOVER, SK_PNMI_HRX_RESERVED},
184/* Bit58 */ { SK_PNMI_HRX_64, SK_PNMI_HRX_RESERVED},
185/* Bit59 */ { SK_PNMI_HRX_127, SK_PNMI_HRX_RESERVED},
186/* Bit60 */ { SK_PNMI_HRX_255, SK_PNMI_HRX_RESERVED},
187/* Bit61 */ { SK_PNMI_HRX_511, SK_PNMI_HRX_RESERVED},
188/* Bit62 */ { SK_PNMI_HRX_1023, SK_PNMI_HRX_RESERVED},
189/* Bit63 */ { SK_PNMI_HRX_MAX, SK_PNMI_HRX_RESERVED}
190};
191
192/*
193 * Table for hardware register saving on resets and port switches
194 */
195PNMI_STATIC const SK_PNMI_STATADDR StatAddr[SK_PNMI_MAX_IDX][SK_PNMI_MAC_TYPES] = {
196 /* SK_PNMI_HTX */
197 {{XM_TXF_OK, SK_TRUE}, {0, SK_FALSE}},
198 /* SK_PNMI_HTX_OCTETHIGH */
199 {{XM_TXO_OK_HI, SK_TRUE}, {GM_TXO_OK_HI, SK_TRUE}},
200 /* SK_PNMI_HTX_OCTETLOW */
201 {{XM_TXO_OK_LO, SK_FALSE}, {GM_TXO_OK_LO, SK_FALSE}},
202 /* SK_PNMI_HTX_BROADCAST */
203 {{XM_TXF_BC_OK, SK_TRUE}, {GM_TXF_BC_OK, SK_TRUE}},
204 /* SK_PNMI_HTX_MULTICAST */
205 {{XM_TXF_MC_OK, SK_TRUE}, {GM_TXF_MC_OK, SK_TRUE}},
206 /* SK_PNMI_HTX_UNICAST */
207 {{XM_TXF_UC_OK, SK_TRUE}, {GM_TXF_UC_OK, SK_TRUE}},
208 /* SK_PNMI_HTX_BURST */
209 {{XM_TXE_BURST, SK_TRUE}, {0, SK_FALSE}},
210 /* SK_PNMI_HTX_PMACC */
211 {{XM_TXF_MPAUSE, SK_TRUE}, {GM_TXF_MPAUSE, SK_TRUE}},
212 /* SK_PNMI_HTX_MACC */
213 {{XM_TXF_MCTRL, SK_TRUE}, {0, SK_FALSE}},
214 /* SK_PNMI_HTX_COL */
215 {{0, SK_FALSE}, {GM_TXF_COL, SK_TRUE}},
216 /* SK_PNMI_HTX_SINGLE_COL */
217 {{XM_TXF_SNG_COL, SK_TRUE}, {GM_TXF_SNG_COL, SK_TRUE}},
218 /* SK_PNMI_HTX_MULTI_COL */
219 {{XM_TXF_MUL_COL, SK_TRUE}, {GM_TXF_MUL_COL, SK_TRUE}},
220 /* SK_PNMI_HTX_EXCESS_COL */
221 {{XM_TXF_ABO_COL, SK_TRUE}, {GM_TXF_ABO_COL, SK_TRUE}},
222 /* SK_PNMI_HTX_LATE_COL */
223 {{XM_TXF_LAT_COL, SK_TRUE}, {GM_TXF_LAT_COL, SK_TRUE}},
224 /* SK_PNMI_HTX_DEFFERAL */
225 {{XM_TXF_DEF, SK_TRUE}, {0, SK_FALSE}},
226 /* SK_PNMI_HTX_EXCESS_DEF */
227 {{XM_TXF_EX_DEF, SK_TRUE}, {0, SK_FALSE}},
228 /* SK_PNMI_HTX_UNDERRUN */
229 {{XM_TXE_FIFO_UR, SK_TRUE}, {GM_TXE_FIFO_UR, SK_TRUE}},
230 /* SK_PNMI_HTX_CARRIER */
231 {{XM_TXE_CS_ERR, SK_TRUE}, {0, SK_FALSE}},
232 /* SK_PNMI_HTX_UTILUNDER */
233 {{0, SK_FALSE}, {0, SK_FALSE}},
234 /* SK_PNMI_HTX_UTILOVER */
235 {{0, SK_FALSE}, {0, SK_FALSE}},
236 /* SK_PNMI_HTX_64 */
237 {{XM_TXF_64B, SK_TRUE}, {GM_TXF_64B, SK_TRUE}},
238 /* SK_PNMI_HTX_127 */
239 {{XM_TXF_127B, SK_TRUE}, {GM_TXF_127B, SK_TRUE}},
240 /* SK_PNMI_HTX_255 */
241 {{XM_TXF_255B, SK_TRUE}, {GM_TXF_255B, SK_TRUE}},
242 /* SK_PNMI_HTX_511 */
243 {{XM_TXF_511B, SK_TRUE}, {GM_TXF_511B, SK_TRUE}},
244 /* SK_PNMI_HTX_1023 */
245 {{XM_TXF_1023B, SK_TRUE}, {GM_TXF_1023B, SK_TRUE}},
246 /* SK_PNMI_HTX_MAX */
247 {{XM_TXF_MAX_SZ, SK_TRUE}, {GM_TXF_1518B, SK_TRUE}},
248 /* SK_PNMI_HTX_LONGFRAMES */
249 {{XM_TXF_LONG, SK_TRUE}, {GM_TXF_MAX_SZ, SK_TRUE}},
250 /* SK_PNMI_HTX_SYNC */
251 {{0, SK_FALSE}, {0, SK_FALSE}},
252 /* SK_PNMI_HTX_SYNC_OCTET */
253 {{0, SK_FALSE}, {0, SK_FALSE}},
254 /* SK_PNMI_HTX_RESERVED */
255 {{0, SK_FALSE}, {0, SK_FALSE}},
256 /* SK_PNMI_HRX */
257 {{XM_RXF_OK, SK_TRUE}, {0, SK_FALSE}},
258 /* SK_PNMI_HRX_OCTETHIGH */
259 {{XM_RXO_OK_HI, SK_TRUE}, {GM_RXO_OK_HI, SK_TRUE}},
260 /* SK_PNMI_HRX_OCTETLOW */
261 {{XM_RXO_OK_LO, SK_FALSE}, {GM_RXO_OK_LO, SK_FALSE}},
262 /* SK_PNMI_HRX_BADOCTETHIGH */
263 {{0, SK_FALSE}, {GM_RXO_ERR_HI, SK_TRUE}},
264 /* SK_PNMI_HRX_BADOCTETLOW */
265 {{0, SK_FALSE}, {GM_RXO_ERR_LO, SK_TRUE}},
266 /* SK_PNMI_HRX_BROADCAST */
267 {{XM_RXF_BC_OK, SK_TRUE}, {GM_RXF_BC_OK, SK_TRUE}},
268 /* SK_PNMI_HRX_MULTICAST */
269 {{XM_RXF_MC_OK, SK_TRUE}, {GM_RXF_MC_OK, SK_TRUE}},
270 /* SK_PNMI_HRX_UNICAST */
271 {{XM_RXF_UC_OK, SK_TRUE}, {GM_RXF_UC_OK, SK_TRUE}},
272 /* SK_PNMI_HRX_PMACC */
273 {{XM_RXF_MPAUSE, SK_TRUE}, {GM_RXF_MPAUSE, SK_TRUE}},
274 /* SK_PNMI_HRX_MACC */
275 {{XM_RXF_MCTRL, SK_TRUE}, {0, SK_FALSE}},
276 /* SK_PNMI_HRX_PMACC_ERR */
277 {{XM_RXF_INV_MP, SK_TRUE}, {0, SK_FALSE}},
278 /* SK_PNMI_HRX_MACC_UNKWN */
279 {{XM_RXF_INV_MOC, SK_TRUE}, {0, SK_FALSE}},
280 /* SK_PNMI_HRX_BURST */
281 {{XM_RXE_BURST, SK_TRUE}, {0, SK_FALSE}},
282 /* SK_PNMI_HRX_MISSED */
283 {{XM_RXE_FMISS, SK_TRUE}, {0, SK_FALSE}},
284 /* SK_PNMI_HRX_FRAMING */
285 {{XM_RXF_FRA_ERR, SK_TRUE}, {0, SK_FALSE}},
286 /* SK_PNMI_HRX_UNDERSIZE */
287 {{0, SK_FALSE}, {GM_RXF_SHT, SK_TRUE}},
288 /* SK_PNMI_HRX_OVERFLOW */
289 {{XM_RXE_FIFO_OV, SK_TRUE}, {GM_RXE_FIFO_OV, SK_TRUE}},
290 /* SK_PNMI_HRX_JABBER */
291 {{XM_RXF_JAB_PKT, SK_TRUE}, {GM_RXF_JAB_PKT, SK_TRUE}},
292 /* SK_PNMI_HRX_CARRIER */
293 {{XM_RXE_CAR_ERR, SK_TRUE}, {0, SK_FALSE}},
294 /* SK_PNMI_HRX_IRLENGTH */
295 {{XM_RXF_LEN_ERR, SK_TRUE}, {0, SK_FALSE}},
296 /* SK_PNMI_HRX_SYMBOL */
297 {{XM_RXE_SYM_ERR, SK_TRUE}, {0, SK_FALSE}},
298 /* SK_PNMI_HRX_SHORTS */
299 {{XM_RXE_SHT_ERR, SK_TRUE}, {0, SK_FALSE}},
300 /* SK_PNMI_HRX_RUNT */
301 {{XM_RXE_RUNT, SK_TRUE}, {GM_RXE_FRAG, SK_TRUE}},
302 /* SK_PNMI_HRX_TOO_LONG */
303 {{XM_RXF_LNG_ERR, SK_TRUE}, {GM_RXF_LNG_ERR, SK_TRUE}},
304 /* SK_PNMI_HRX_FCS */
305 {{XM_RXF_FCS_ERR, SK_TRUE}, {GM_RXF_FCS_ERR, SK_TRUE}},
306 /* SK_PNMI_HRX_CEXT */
307 {{XM_RXF_CEX_ERR, SK_TRUE}, {0, SK_FALSE}},
308 /* SK_PNMI_HRX_UTILUNDER */
309 {{0, SK_FALSE}, {0, SK_FALSE}},
310 /* SK_PNMI_HRX_UTILOVER */
311 {{0, SK_FALSE}, {0, SK_FALSE}},
312 /* SK_PNMI_HRX_64 */
313 {{XM_RXF_64B, SK_TRUE}, {GM_RXF_64B, SK_TRUE}},
314 /* SK_PNMI_HRX_127 */
315 {{XM_RXF_127B, SK_TRUE}, {GM_RXF_127B, SK_TRUE}},
316 /* SK_PNMI_HRX_255 */
317 {{XM_RXF_255B, SK_TRUE}, {GM_RXF_255B, SK_TRUE}},
318 /* SK_PNMI_HRX_511 */
319 {{XM_RXF_511B, SK_TRUE}, {GM_RXF_511B, SK_TRUE}},
320 /* SK_PNMI_HRX_1023 */
321 {{XM_RXF_1023B, SK_TRUE}, {GM_RXF_1023B, SK_TRUE}},
322 /* SK_PNMI_HRX_MAX */
323 {{XM_RXF_MAX_SZ, SK_TRUE}, {GM_RXF_1518B, SK_TRUE}},
324 /* SK_PNMI_HRX_LONGFRAMES */
325 {{0, SK_FALSE}, {GM_RXF_MAX_SZ, SK_TRUE}},
326 /* SK_PNMI_HRX_RESERVED */
327 {{0, SK_FALSE}, {0, SK_FALSE}}
328};
329
330
331/*****************************************************************************
332 *
333 * Public functions
334 *
335 */
336
337/*****************************************************************************
338 *
339 * SkPnmiInit - Init function of PNMI
340 *
341 * Description:
342 * SK_INIT_DATA: Initialises the data structures
343 * SK_INIT_IO: Resets the XMAC statistics, determines the device and
344 * connector type.
345 * SK_INIT_RUN: Starts a timer event for port switch per hour
346 * calculation.
347 *
348 * Returns:
349 * Always 0
350 */
351int SkPnmiInit(
352SK_AC *pAC, /* Pointer to adapter context */
353SK_IOC IoC, /* IO context handle */
354int Level) /* Initialization level */
355{
356 unsigned int PortMax; /* Number of ports */
357 unsigned int PortIndex; /* Current port index in loop */
358 SK_U16 Val16; /* Multiple purpose 16 bit variable */
359 SK_U8 Val8; /* Mulitple purpose 8 bit variable */
360 SK_EVPARA EventParam; /* Event struct for timer event */
361 SK_PNMI_VCT *pVctBackupData;
362
363
364 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
365 ("PNMI: SkPnmiInit: Called, level=%d\n", Level));
366
367 switch (Level) {
368
369 case SK_INIT_DATA:
370 SK_MEMSET((char *)&pAC->Pnmi, 0, sizeof(pAC->Pnmi));
371 pAC->Pnmi.TrapBufFree = SK_PNMI_TRAP_QUEUE_LEN;
372 pAC->Pnmi.StartUpTime = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
373 pAC->Pnmi.RlmtChangeThreshold = SK_PNMI_DEF_RLMT_CHG_THRES;
374 for (PortIndex = 0; PortIndex < SK_MAX_MACS; PortIndex ++) {
375
376 pAC->Pnmi.Port[PortIndex].ActiveFlag = SK_FALSE;
377 pAC->Pnmi.DualNetActiveFlag = SK_FALSE;
378 }
379
380#ifdef SK_PNMI_CHECK
381 if (SK_PNMI_MAX_IDX != SK_PNMI_CNT_NO) {
382
383 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR049, SK_PNMI_ERR049MSG);
384
385 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_INIT | SK_DBGCAT_FATAL,
386 ("CounterOffset struct size (%d) differs from"
387 "SK_PNMI_MAX_IDX (%d)\n",
388 SK_PNMI_CNT_NO, SK_PNMI_MAX_IDX));
389 }
390
391 if (SK_PNMI_MAX_IDX !=
392 (sizeof(StatAddr) / (sizeof(SK_PNMI_STATADDR) * SK_PNMI_MAC_TYPES))) {
393
394 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR050, SK_PNMI_ERR050MSG);
395
396 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_INIT | SK_DBGCAT_FATAL,
397 ("StatAddr table size (%d) differs from "
398 "SK_PNMI_MAX_IDX (%d)\n",
399 (sizeof(StatAddr) /
400 (sizeof(SK_PNMI_STATADDR) * SK_PNMI_MAC_TYPES)),
401 SK_PNMI_MAX_IDX));
402 }
403#endif /* SK_PNMI_CHECK */
404 break;
405
406 case SK_INIT_IO:
407 /*
408 * Reset MAC counters
409 */
410 PortMax = pAC->GIni.GIMacsFound;
411
412 for (PortIndex = 0; PortIndex < PortMax; PortIndex ++) {
413
414 pAC->GIni.GIFunc.pFnMacResetCounter(pAC, IoC, PortIndex);
415 }
416
417 /* Initialize DSP variables for Vct() to 0xff => Never written! */
418 for (PortIndex = 0; PortIndex < PortMax; PortIndex ++) {
419 pAC->GIni.GP[PortIndex].PCableLen = 0xff;
420 pVctBackupData = &pAC->Pnmi.VctBackup[PortIndex];
421 pVctBackupData->PCableLen = 0xff;
422 }
423
424 /*
425 * Get pci bus speed
426 */
427 SK_IN16(IoC, B0_CTST, &Val16);
428 if ((Val16 & CS_BUS_CLOCK) == 0) {
429
430 pAC->Pnmi.PciBusSpeed = 33;
431 }
432 else {
433 pAC->Pnmi.PciBusSpeed = 66;
434 }
435
436 /*
437 * Get pci bus width
438 */
439 SK_IN16(IoC, B0_CTST, &Val16);
440 if ((Val16 & CS_BUS_SLOT_SZ) == 0) {
441
442 pAC->Pnmi.PciBusWidth = 32;
443 }
444 else {
445 pAC->Pnmi.PciBusWidth = 64;
446 }
447
448 /*
449 * Get chipset
450 */
451 switch (pAC->GIni.GIChipId) {
452 case CHIP_ID_GENESIS:
453 pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_XMAC;
454 break;
455
456 case CHIP_ID_YUKON:
457 pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_YUKON;
458 break;
459
460 default:
461 break;
462 }
463
464 /*
465 * Get PMD and DeviceType
466 */
467 SK_IN8(IoC, B2_PMD_TYP, &Val8);
468 switch (Val8) {
469 case 'S':
470 pAC->Pnmi.PMD = 3;
471 if (pAC->GIni.GIMacsFound > 1) {
472
473 pAC->Pnmi.DeviceType = 0x00020002;
474 }
475 else {
476 pAC->Pnmi.DeviceType = 0x00020001;
477 }
478 break;
479
480 case 'L':
481 pAC->Pnmi.PMD = 2;
482 if (pAC->GIni.GIMacsFound > 1) {
483
484 pAC->Pnmi.DeviceType = 0x00020004;
485 }
486 else {
487 pAC->Pnmi.DeviceType = 0x00020003;
488 }
489 break;
490
491 case 'C':
492 pAC->Pnmi.PMD = 4;
493 if (pAC->GIni.GIMacsFound > 1) {
494
495 pAC->Pnmi.DeviceType = 0x00020006;
496 }
497 else {
498 pAC->Pnmi.DeviceType = 0x00020005;
499 }
500 break;
501
502 case 'T':
503 pAC->Pnmi.PMD = 5;
504 if (pAC->GIni.GIMacsFound > 1) {
505
506 pAC->Pnmi.DeviceType = 0x00020008;
507 }
508 else {
509 pAC->Pnmi.DeviceType = 0x00020007;
510 }
511 break;
512
513 default :
514 pAC->Pnmi.PMD = 1;
515 pAC->Pnmi.DeviceType = 0;
516 break;
517 }
518
519 /*
520 * Get connector
521 */
522 SK_IN8(IoC, B2_CONN_TYP, &Val8);
523 switch (Val8) {
524 case 'C':
525 pAC->Pnmi.Connector = 2;
526 break;
527
528 case 'D':
529 pAC->Pnmi.Connector = 3;
530 break;
531
532 case 'F':
533 pAC->Pnmi.Connector = 4;
534 break;
535
536 case 'J':
537 pAC->Pnmi.Connector = 5;
538 break;
539
540 case 'V':
541 pAC->Pnmi.Connector = 6;
542 break;
543
544 default:
545 pAC->Pnmi.Connector = 1;
546 break;
547 }
548 break;
549
550 case SK_INIT_RUN:
551 /*
552 * Start timer for RLMT change counter
553 */
554 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
555 SkTimerStart(pAC, IoC, &pAC->Pnmi.RlmtChangeEstimate.EstTimer,
556 28125000, SKGE_PNMI, SK_PNMI_EVT_CHG_EST_TIMER,
557 EventParam);
558 break;
559
560 default:
561 break; /* Nothing todo */
562 }
563
564 return (0);
565}
566
567/*****************************************************************************
568 *
569 * SkPnmiGetVar - Retrieves the value of a single OID
570 *
571 * Description:
572 * Calls a general sub-function for all this stuff. If the instance
573 * -1 is passed, the values of all instances are returned in an
574 * array of values.
575 *
576 * Returns:
577 * SK_PNMI_ERR_OK The request was successfully performed
578 * SK_PNMI_ERR_GENERAL A general severe internal error occured
579 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to take
580 * the data.
581 * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown
582 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
583 * exist (e.g. port instance 3 on a two port
584 * adapter.
585 */
586static int SkPnmiGetVar(
587SK_AC *pAC, /* Pointer to adapter context */
588SK_IOC IoC, /* IO context handle */
589SK_U32 Id, /* Object ID that is to be processed */
590void *pBuf, /* Buffer to which the management data will be copied */
591unsigned int *pLen, /* On call: buffer length. On return: used buffer */
592SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
593SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
594{
595 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
596 ("PNMI: SkPnmiGetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n",
597 Id, *pLen, Instance, NetIndex));
598
599 return (PnmiVar(pAC, IoC, SK_PNMI_GET, Id, (char *)pBuf, pLen,
600 Instance, NetIndex));
601}
602
603/*****************************************************************************
604 *
605 * SkPnmiPreSetVar - Presets the value of a single OID
606 *
607 * Description:
608 * Calls a general sub-function for all this stuff. The preset does
609 * the same as a set, but returns just before finally setting the
610 * new value. This is useful to check if a set might be successfull.
611 * If the instance -1 is passed, an array of values is supposed and
612 * all instances of the OID will be set.
613 *
614 * Returns:
615 * SK_PNMI_ERR_OK The request was successfully performed.
616 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
617 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
618 * the correct data (e.g. a 32bit value is
619 * needed, but a 16 bit value was passed).
620 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
621 * value range.
622 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
623 * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown.
624 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
625 * exist (e.g. port instance 3 on a two port
626 * adapter.
627 */
628static int SkPnmiPreSetVar(
629SK_AC *pAC, /* Pointer to adapter context */
630SK_IOC IoC, /* IO context handle */
631SK_U32 Id, /* Object ID that is to be processed */
632void *pBuf, /* Buffer to which the management data will be copied */
633unsigned int *pLen, /* Total length of management data */
634SK_U32 Instance, /* Instance (1..n) that is to be set or -1 */
635SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
636{
637 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
638 ("PNMI: SkPnmiPreSetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n",
639 Id, *pLen, Instance, NetIndex));
640
641
642 return (PnmiVar(pAC, IoC, SK_PNMI_PRESET, Id, (char *)pBuf, pLen,
643 Instance, NetIndex));
644}
645
646/*****************************************************************************
647 *
648 * SkPnmiSetVar - Sets the value of a single OID
649 *
650 * Description:
651 * Calls a general sub-function for all this stuff. The preset does
652 * the same as a set, but returns just before finally setting the
653 * new value. This is useful to check if a set might be successfull.
654 * If the instance -1 is passed, an array of values is supposed and
655 * all instances of the OID will be set.
656 *
657 * Returns:
658 * SK_PNMI_ERR_OK The request was successfully performed.
659 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
660 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
661 * the correct data (e.g. a 32bit value is
662 * needed, but a 16 bit value was passed).
663 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
664 * value range.
665 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
666 * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown.
667 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
668 * exist (e.g. port instance 3 on a two port
669 * adapter.
670 */
671int SkPnmiSetVar(
672SK_AC *pAC, /* Pointer to adapter context */
673SK_IOC IoC, /* IO context handle */
674SK_U32 Id, /* Object ID that is to be processed */
675void *pBuf, /* Buffer to which the management data will be copied */
676unsigned int *pLen, /* Total length of management data */
677SK_U32 Instance, /* Instance (1..n) that is to be set or -1 */
678SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
679{
680 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
681 ("PNMI: SkPnmiSetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n",
682 Id, *pLen, Instance, NetIndex));
683
684 return (PnmiVar(pAC, IoC, SK_PNMI_SET, Id, (char *)pBuf, pLen,
685 Instance, NetIndex));
686}
687
688/*****************************************************************************
689 *
690 * SkPnmiGetStruct - Retrieves the management database in SK_PNMI_STRUCT_DATA
691 *
692 * Description:
693 * Runs through the IdTable, queries the single OIDs and stores the
694 * returned data into the management database structure
695 * SK_PNMI_STRUCT_DATA. The offset of the OID in the structure
696 * is stored in the IdTable. The return value of the function will also
697 * be stored in SK_PNMI_STRUCT_DATA if the passed buffer has the
698 * minimum size of SK_PNMI_MIN_STRUCT_SIZE.
699 *
700 * Returns:
701 * SK_PNMI_ERR_OK The request was successfully performed
702 * SK_PNMI_ERR_GENERAL A general severe internal error occured
703 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to take
704 * the data.
705 * SK_PNMI_ERR_UNKNOWN_NET The requested NetIndex doesn't exist
706 */
707int SkPnmiGetStruct(
708SK_AC *pAC, /* Pointer to adapter context */
709SK_IOC IoC, /* IO context handle */
710void *pBuf, /* Buffer to which the management data will be copied. */
711unsigned int *pLen, /* Length of buffer */
712SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
713{
714 int Ret;
715 unsigned int TableIndex;
716 unsigned int DstOffset;
717 unsigned int InstanceNo;
718 unsigned int InstanceCnt;
719 SK_U32 Instance;
720 unsigned int TmpLen;
721 char KeyArr[SK_PNMI_VPD_ENTRIES][SK_PNMI_VPD_KEY_SIZE];
722
723
724 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
725 ("PNMI: SkPnmiGetStruct: Called, BufLen=%d, NetIndex=%d\n",
726 *pLen, NetIndex));
727
728 if (*pLen < SK_PNMI_STRUCT_SIZE) {
729
730 if (*pLen >= SK_PNMI_MIN_STRUCT_SIZE) {
731
732 SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_TOO_SHORT,
733 (SK_U32)(-1));
734 }
735
736 *pLen = SK_PNMI_STRUCT_SIZE;
737 return (SK_PNMI_ERR_TOO_SHORT);
738 }
739
740 /*
741 * Check NetIndex
742 */
743 if (NetIndex >= pAC->Rlmt.NumNets) {
744 return (SK_PNMI_ERR_UNKNOWN_NET);
745 }
746
747 /* Update statistic */
748 SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On call");
749
750 if ((Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1)) !=
751 SK_PNMI_ERR_OK) {
752
753 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
754 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
755 return (Ret);
756 }
757
758 if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
759
760 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
761 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
762 return (Ret);
763 }
764
765 if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) {
766
767 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
768 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
769 return (Ret);
770 }
771
772 /*
773 * Increment semaphores to indicate that an update was
774 * already done
775 */
776 pAC->Pnmi.MacUpdatedFlag ++;
777 pAC->Pnmi.RlmtUpdatedFlag ++;
778 pAC->Pnmi.SirqUpdatedFlag ++;
779
780 /* Get vpd keys for instance calculation */
781 Ret = GetVpdKeyArr(pAC, IoC, &KeyArr[0][0], sizeof(KeyArr), &TmpLen);
782 if (Ret != SK_PNMI_ERR_OK) {
783
784 pAC->Pnmi.MacUpdatedFlag --;
785 pAC->Pnmi.RlmtUpdatedFlag --;
786 pAC->Pnmi.SirqUpdatedFlag --;
787
788 SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return");
789 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
790 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
791 return (SK_PNMI_ERR_GENERAL);
792 }
793
794 /* Retrieve values */
795 SK_MEMSET((char *)pBuf, 0, SK_PNMI_STRUCT_SIZE);
796 for (TableIndex = 0; TableIndex < ID_TABLE_SIZE; TableIndex ++) {
797
798 InstanceNo = IdTable[TableIndex].InstanceNo;
799 for (InstanceCnt = 1; InstanceCnt <= InstanceNo;
800 InstanceCnt ++) {
801
802 DstOffset = IdTable[TableIndex].Offset +
803 (InstanceCnt - 1) *
804 IdTable[TableIndex].StructSize;
805
806 /*
807 * For the VPD the instance is not an index number
808 * but the key itself. Determin with the instance
809 * counter the VPD key to be used.
810 */
811 if (IdTable[TableIndex].Id == OID_SKGE_VPD_KEY ||
812 IdTable[TableIndex].Id == OID_SKGE_VPD_VALUE ||
813 IdTable[TableIndex].Id == OID_SKGE_VPD_ACCESS ||
814 IdTable[TableIndex].Id == OID_SKGE_VPD_ACTION) {
815
816 SK_STRNCPY((char *)&Instance, KeyArr[InstanceCnt - 1], 4);
817 }
818 else {
819 Instance = (SK_U32)InstanceCnt;
820 }
821
822 TmpLen = *pLen - DstOffset;
823 Ret = IdTable[TableIndex].Func(pAC, IoC, SK_PNMI_GET,
824 IdTable[TableIndex].Id, (char *)pBuf +
825 DstOffset, &TmpLen, Instance, TableIndex, NetIndex);
826
827 /*
828 * An unknown instance error means that we reached
829 * the last instance of that variable. Proceed with
830 * the next OID in the table and ignore the return
831 * code.
832 */
833 if (Ret == SK_PNMI_ERR_UNKNOWN_INST) {
834
835 break;
836 }
837
838 if (Ret != SK_PNMI_ERR_OK) {
839
840 pAC->Pnmi.MacUpdatedFlag --;
841 pAC->Pnmi.RlmtUpdatedFlag --;
842 pAC->Pnmi.SirqUpdatedFlag --;
843
844 SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return");
845 SK_PNMI_SET_STAT(pBuf, Ret, DstOffset);
846 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
847 return (Ret);
848 }
849 }
850 }
851
852 pAC->Pnmi.MacUpdatedFlag --;
853 pAC->Pnmi.RlmtUpdatedFlag --;
854 pAC->Pnmi.SirqUpdatedFlag --;
855
856 *pLen = SK_PNMI_STRUCT_SIZE;
857 SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return");
858 SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_OK, (SK_U32)(-1));
859 return (SK_PNMI_ERR_OK);
860}
861
862/*****************************************************************************
863 *
864 * SkPnmiPreSetStruct - Presets the management database in SK_PNMI_STRUCT_DATA
865 *
866 * Description:
867 * Calls a general sub-function for all this set stuff. The preset does
868 * the same as a set, but returns just before finally setting the
869 * new value. This is useful to check if a set might be successfull.
870 * The sub-function runs through the IdTable, checks which OIDs are able
871 * to set, and calls the handler function of the OID to perform the
872 * preset. The return value of the function will also be stored in
873 * SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of
874 * SK_PNMI_MIN_STRUCT_SIZE.
875 *
876 * Returns:
877 * SK_PNMI_ERR_OK The request was successfully performed.
878 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
879 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
880 * the correct data (e.g. a 32bit value is
881 * needed, but a 16 bit value was passed).
882 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
883 * value range.
884 */
885int SkPnmiPreSetStruct(
886SK_AC *pAC, /* Pointer to adapter context */
887SK_IOC IoC, /* IO context handle */
888void *pBuf, /* Buffer which contains the data to be set */
889unsigned int *pLen, /* Length of buffer */
890SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
891{
892 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
893 ("PNMI: SkPnmiPreSetStruct: Called, BufLen=%d, NetIndex=%d\n",
894 *pLen, NetIndex));
895
896 return (PnmiStruct(pAC, IoC, SK_PNMI_PRESET, (char *)pBuf,
897 pLen, NetIndex));
898}
899
900/*****************************************************************************
901 *
902 * SkPnmiSetStruct - Sets the management database in SK_PNMI_STRUCT_DATA
903 *
904 * Description:
905 * Calls a general sub-function for all this set stuff. The return value
906 * of the function will also be stored in SK_PNMI_STRUCT_DATA if the
907 * passed buffer has the minimum size of SK_PNMI_MIN_STRUCT_SIZE.
908 * The sub-function runs through the IdTable, checks which OIDs are able
909 * to set, and calls the handler function of the OID to perform the
910 * set. The return value of the function will also be stored in
911 * SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of
912 * SK_PNMI_MIN_STRUCT_SIZE.
913 *
914 * Returns:
915 * SK_PNMI_ERR_OK The request was successfully performed.
916 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
917 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
918 * the correct data (e.g. a 32bit value is
919 * needed, but a 16 bit value was passed).
920 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
921 * value range.
922 */
923int SkPnmiSetStruct(
924SK_AC *pAC, /* Pointer to adapter context */
925SK_IOC IoC, /* IO context handle */
926void *pBuf, /* Buffer which contains the data to be set */
927unsigned int *pLen, /* Length of buffer */
928SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
929{
930 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
931 ("PNMI: SkPnmiSetStruct: Called, BufLen=%d, NetIndex=%d\n",
932 *pLen, NetIndex));
933
934 return (PnmiStruct(pAC, IoC, SK_PNMI_SET, (char *)pBuf,
935 pLen, NetIndex));
936}
937
938/*****************************************************************************
939 *
940 * SkPnmiEvent - Event handler
941 *
942 * Description:
943 * Handles the following events:
944 * SK_PNMI_EVT_SIRQ_OVERFLOW When a hardware counter overflows an
945 * interrupt will be generated which is
946 * first handled by SIRQ which generates a
947 * this event. The event increments the
948 * upper 32 bit of the 64 bit counter.
949 * SK_PNMI_EVT_SEN_XXX The event is generated by the I2C module
950 * when a sensor reports a warning or
951 * error. The event will store a trap
952 * message in the trap buffer.
953 * SK_PNMI_EVT_CHG_EST_TIMER The timer event was initiated by this
954 * module and is used to calculate the
955 * port switches per hour.
956 * SK_PNMI_EVT_CLEAR_COUNTER The event clears all counters and
957 * timestamps.
958 * SK_PNMI_EVT_XMAC_RESET The event is generated by the driver
959 * before a hard reset of the XMAC is
960 * performed. All counters will be saved
961 * and added to the hardware counter
962 * values after reset to grant continuous
963 * counter values.
964 * SK_PNMI_EVT_RLMT_PORT_UP Generated by RLMT to notify that a port
965 * went logically up. A trap message will
966 * be stored to the trap buffer.
967 * SK_PNMI_EVT_RLMT_PORT_DOWN Generated by RLMT to notify that a port
968 * went logically down. A trap message will
969 * be stored to the trap buffer.
970 * SK_PNMI_EVT_RLMT_SEGMENTATION Generated by RLMT to notify that two
971 * spanning tree root bridges were
972 * detected. A trap message will be stored
973 * to the trap buffer.
974 * SK_PNMI_EVT_RLMT_ACTIVE_DOWN Notifies PNMI that an active port went
975 * down. PNMI will not further add the
976 * statistic values to the virtual port.
977 * SK_PNMI_EVT_RLMT_ACTIVE_UP Notifies PNMI that a port went up and
978 * is now an active port. PNMI will now
979 * add the statistic data of this port to
980 * the virtual port.
981 * SK_PNMI_EVT_RLMT_SET_NETS Notifies PNMI about the net mode. The first parameter
982 * contains the number of nets. 1 means single net, 2 means
983 * dual net. The second parameter is -1
984 *
985 * Returns:
986 * Always 0
987 */
988int SkPnmiEvent(
989SK_AC *pAC, /* Pointer to adapter context */
990SK_IOC IoC, /* IO context handle */
991SK_U32 Event, /* Event-Id */
992SK_EVPARA Param) /* Event dependent parameter */
993{
994 unsigned int PhysPortIndex;
995 unsigned int MaxNetNumber;
996 int CounterIndex;
997 int Ret;
998 SK_U16 MacStatus;
999 SK_U64 OverflowStatus;
1000 SK_U64 Mask;
1001 int MacType;
1002 SK_U64 Value;
1003 SK_U32 Val32;
1004 SK_U16 Register;
1005 SK_EVPARA EventParam;
1006 SK_U64 NewestValue;
1007 SK_U64 OldestValue;
1008 SK_U64 Delta;
1009 SK_PNMI_ESTIMATE *pEst;
1010 SK_U32 NetIndex;
1011 SK_GEPORT *pPrt;
1012 SK_PNMI_VCT *pVctBackupData;
1013 SK_U32 RetCode;
1014 int i;
1015 SK_U32 CableLength;
1016
1017
1018#ifdef DEBUG
1019 if (Event != SK_PNMI_EVT_XMAC_RESET) {
1020
1021 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1022 ("PNMI: SkPnmiEvent: Called, Event=0x%x, Param=0x%x\n",
1023 (unsigned int)Event, (unsigned int)Param.Para64));
1024 }
1025#endif /* DEBUG */
1026 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On call");
1027
1028 MacType = pAC->GIni.GIMacType;
1029
1030 switch (Event) {
1031
1032 case SK_PNMI_EVT_SIRQ_OVERFLOW:
1033 PhysPortIndex = (int)Param.Para32[0];
1034 MacStatus = (SK_U16)Param.Para32[1];
1035#ifdef DEBUG
1036 if (PhysPortIndex >= SK_MAX_MACS) {
1037
1038 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1039 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SIRQ_OVERFLOW parameter"
1040 " wrong, PhysPortIndex=0x%x\n",
1041 PhysPortIndex));
1042 return (0);
1043 }
1044#endif /* DEBUG */
1045 OverflowStatus = 0;
1046
1047 /*
1048 * Check which source caused an overflow interrupt.
1049 */
1050 if ((pAC->GIni.GIFunc.pFnMacOverflow(pAC, IoC, PhysPortIndex,
1051 MacStatus, &OverflowStatus) != 0) ||
1052 (OverflowStatus == 0)) {
1053
1054 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
1055 return (0);
1056 }
1057
1058 /*
1059 * Check the overflow status register and increment
1060 * the upper dword of corresponding counter.
1061 */
1062 for (CounterIndex = 0; CounterIndex < sizeof(Mask) * 8;
1063 CounterIndex ++) {
1064
1065 Mask = (SK_U64)1 << CounterIndex;
1066 if ((OverflowStatus & Mask) == 0) {
1067
1068 continue;
1069 }
1070
1071 switch (StatOvrflwBit[CounterIndex][MacType]) {
1072
1073 case SK_PNMI_HTX_UTILUNDER:
1074 case SK_PNMI_HTX_UTILOVER:
1075 if (MacType == SK_MAC_XMAC) {
1076 XM_IN16(IoC, PhysPortIndex, XM_TX_CMD, &Register);
1077 Register |= XM_TX_SAM_LINE;
1078 XM_OUT16(IoC, PhysPortIndex, XM_TX_CMD, Register);
1079 }
1080 break;
1081
1082 case SK_PNMI_HRX_UTILUNDER:
1083 case SK_PNMI_HRX_UTILOVER:
1084 if (MacType == SK_MAC_XMAC) {
1085 XM_IN16(IoC, PhysPortIndex, XM_RX_CMD, &Register);
1086 Register |= XM_RX_SAM_LINE;
1087 XM_OUT16(IoC, PhysPortIndex, XM_RX_CMD, Register);
1088 }
1089 break;
1090
1091 case SK_PNMI_HTX_OCTETHIGH:
1092 case SK_PNMI_HTX_OCTETLOW:
1093 case SK_PNMI_HTX_RESERVED:
1094 case SK_PNMI_HRX_OCTETHIGH:
1095 case SK_PNMI_HRX_OCTETLOW:
1096 case SK_PNMI_HRX_IRLENGTH:
1097 case SK_PNMI_HRX_RESERVED:
1098
1099 /*
1100 * the following counters aren't be handled (id > 63)
1101 */
1102 case SK_PNMI_HTX_SYNC:
1103 case SK_PNMI_HTX_SYNC_OCTET:
1104 break;
1105
1106 case SK_PNMI_HRX_LONGFRAMES:
1107 if (MacType == SK_MAC_GMAC) {
1108 pAC->Pnmi.Port[PhysPortIndex].
1109 CounterHigh[CounterIndex] ++;
1110 }
1111 break;
1112
1113 default:
1114 pAC->Pnmi.Port[PhysPortIndex].
1115 CounterHigh[CounterIndex] ++;
1116 }
1117 }
1118 break;
1119
1120 case SK_PNMI_EVT_SEN_WAR_LOW:
1121#ifdef DEBUG
1122 if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
1123
1124 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1125 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_WAR_LOW parameter wrong, SensorIndex=%d\n",
1126 (unsigned int)Param.Para64));
1127 return (0);
1128 }
1129#endif /* DEBUG */
1130
1131 /*
1132 * Store a trap message in the trap buffer and generate
1133 * an event for user space applications with the
1134 * SK_DRIVER_SENDEVENT macro.
1135 */
1136 QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_WAR_LOW,
1137 (unsigned int)Param.Para64);
1138 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1139 break;
1140
1141 case SK_PNMI_EVT_SEN_WAR_UPP:
1142#ifdef DEBUG
1143 if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
1144
1145 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1146 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_WAR_UPP parameter wrong, SensorIndex=%d\n",
1147 (unsigned int)Param.Para64));
1148 return (0);
1149 }
1150#endif /* DEBUG */
1151
1152 /*
1153 * Store a trap message in the trap buffer and generate
1154 * an event for user space applications with the
1155 * SK_DRIVER_SENDEVENT macro.
1156 */
1157 QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_WAR_UPP,
1158 (unsigned int)Param.Para64);
1159 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1160 break;
1161
1162 case SK_PNMI_EVT_SEN_ERR_LOW:
1163#ifdef DEBUG
1164 if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
1165
1166 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1167 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_ERR_LOW parameter wrong, SensorIndex=%d\n",
1168 (unsigned int)Param.Para64));
1169 return (0);
1170 }
1171#endif /* DEBUG */
1172
1173 /*
1174 * Store a trap message in the trap buffer and generate
1175 * an event for user space applications with the
1176 * SK_DRIVER_SENDEVENT macro.
1177 */
1178 QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_ERR_LOW,
1179 (unsigned int)Param.Para64);
1180 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1181 break;
1182
1183 case SK_PNMI_EVT_SEN_ERR_UPP:
1184#ifdef DEBUG
1185 if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
1186
1187 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1188 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_ERR_UPP parameter wrong, SensorIndex=%d\n",
1189 (unsigned int)Param.Para64));
1190 return (0);
1191 }
1192#endif /* DEBUG */
1193
1194 /*
1195 * Store a trap message in the trap buffer and generate
1196 * an event for user space applications with the
1197 * SK_DRIVER_SENDEVENT macro.
1198 */
1199 QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_ERR_UPP,
1200 (unsigned int)Param.Para64);
1201 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1202 break;
1203
1204 case SK_PNMI_EVT_CHG_EST_TIMER:
1205 /*
1206 * Calculate port switch average on a per hour basis
1207 * Time interval for check : 28125 ms
1208 * Number of values for average : 8
1209 *
1210 * Be careful in changing these values, on change check
1211 * - typedef of SK_PNMI_ESTIMATE (Size of EstValue
1212 * array one less than value number)
1213 * - Timer initialization SkTimerStart() in SkPnmiInit
1214 * - Delta value below must be multiplicated with
1215 * power of 2
1216 *
1217 */
1218 pEst = &pAC->Pnmi.RlmtChangeEstimate;
1219 CounterIndex = pEst->EstValueIndex + 1;
1220 if (CounterIndex == 7) {
1221
1222 CounterIndex = 0;
1223 }
1224 pEst->EstValueIndex = CounterIndex;
1225
1226 NewestValue = pAC->Pnmi.RlmtChangeCts;
1227 OldestValue = pEst->EstValue[CounterIndex];
1228 pEst->EstValue[CounterIndex] = NewestValue;
1229
1230 /*
1231 * Calculate average. Delta stores the number of
1232 * port switches per 28125 * 8 = 225000 ms
1233 */
1234 if (NewestValue >= OldestValue) {
1235
1236 Delta = NewestValue - OldestValue;
1237 }
1238 else {
1239 /* Overflow situation */
1240 Delta = (SK_U64)(0 - OldestValue) + NewestValue;
1241 }
1242
1243 /*
1244 * Extrapolate delta to port switches per hour.
1245 * Estimate = Delta * (3600000 / 225000)
1246 * = Delta * 16
1247 * = Delta << 4
1248 */
1249 pAC->Pnmi.RlmtChangeEstimate.Estimate = Delta << 4;
1250
1251 /*
1252 * Check if threshold is exceeded. If the threshold is
1253 * permanently exceeded every 28125 ms an event will be
1254 * generated to remind the user of this condition.
1255 */
1256 if ((pAC->Pnmi.RlmtChangeThreshold != 0) &&
1257 (pAC->Pnmi.RlmtChangeEstimate.Estimate >=
1258 pAC->Pnmi.RlmtChangeThreshold)) {
1259
1260 QueueSimpleTrap(pAC, OID_SKGE_TRAP_RLMT_CHANGE_THRES);
1261 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1262 }
1263
1264 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
1265 SkTimerStart(pAC, IoC, &pAC->Pnmi.RlmtChangeEstimate.EstTimer,
1266 28125000, SKGE_PNMI, SK_PNMI_EVT_CHG_EST_TIMER,
1267 EventParam);
1268 break;
1269
1270 case SK_PNMI_EVT_CLEAR_COUNTER:
1271 /*
1272 * Param.Para32[0] contains the NetIndex (0 ..1).
1273 * Param.Para32[1] is reserved, contains -1.
1274 */
1275 NetIndex = (SK_U32)Param.Para32[0];
1276
1277#ifdef DEBUG
1278 if (NetIndex >= pAC->Rlmt.NumNets) {
1279
1280 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1281 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_CLEAR_COUNTER parameter wrong, NetIndex=%d\n",
1282 NetIndex));
1283
1284 return (0);
1285 }
1286#endif /* DEBUG */
1287
1288 /*
1289 * Set all counters and timestamps to zero.
1290 * The according NetIndex is required as a
1291 * parameter of the event.
1292 */
1293 ResetCounter(pAC, IoC, NetIndex);
1294 break;
1295
1296 case SK_PNMI_EVT_XMAC_RESET:
1297 /*
1298 * To grant continuous counter values store the current
1299 * XMAC statistic values to the entries 1..n of the
1300 * CounterOffset array. XMAC Errata #2
1301 */
1302#ifdef DEBUG
1303 if ((unsigned int)Param.Para64 >= SK_MAX_MACS) {
1304
1305 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1306 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_XMAC_RESET parameter wrong, PhysPortIndex=%d\n",
1307 (unsigned int)Param.Para64));
1308 return (0);
1309 }
1310#endif
1311 PhysPortIndex = (unsigned int)Param.Para64;
1312
1313 /*
1314 * Update XMAC statistic to get fresh values
1315 */
1316 Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
1317 if (Ret != SK_PNMI_ERR_OK) {
1318
1319 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
1320 return (0);
1321 }
1322 /*
1323 * Increment semaphore to indicate that an update was
1324 * already done
1325 */
1326 pAC->Pnmi.MacUpdatedFlag ++;
1327
1328 for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX;
1329 CounterIndex ++) {
1330
1331 if (!StatAddr[CounterIndex][MacType].GetOffset) {
1332
1333 continue;
1334 }
1335
1336 pAC->Pnmi.Port[PhysPortIndex].CounterOffset[CounterIndex] =
1337 GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex);
1338
1339 pAC->Pnmi.Port[PhysPortIndex].CounterHigh[CounterIndex] = 0;
1340 }
1341
1342 pAC->Pnmi.MacUpdatedFlag --;
1343 break;
1344
1345 case SK_PNMI_EVT_RLMT_PORT_UP:
1346 PhysPortIndex = (unsigned int)Param.Para32[0];
1347#ifdef DEBUG
1348 if (PhysPortIndex >= SK_MAX_MACS) {
1349
1350 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1351 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_PORT_UP parameter"
1352 " wrong, PhysPortIndex=%d\n", PhysPortIndex));
1353
1354 return (0);
1355 }
1356#endif /* DEBUG */
1357
1358 /*
1359 * Store a trap message in the trap buffer and generate an event for
1360 * user space applications with the SK_DRIVER_SENDEVENT macro.
1361 */
1362 QueueRlmtPortTrap(pAC, OID_SKGE_TRAP_RLMT_PORT_UP, PhysPortIndex);
1363 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1364
1365 /* Bugfix for XMAC errata (#10620)*/
1366 if (MacType == SK_MAC_XMAC) {
1367 /* Add incremental difference to offset (#10620)*/
1368 (void)pAC->GIni.GIFunc.pFnMacStatistic(pAC, IoC, PhysPortIndex,
1369 XM_RXE_SHT_ERR, &Val32);
1370
1371 Value = (((SK_U64)pAC->Pnmi.Port[PhysPortIndex].
1372 CounterHigh[SK_PNMI_HRX_SHORTS] << 32) | (SK_U64)Val32);
1373 pAC->Pnmi.Port[PhysPortIndex].CounterOffset[SK_PNMI_HRX_SHORTS] +=
1374 Value - pAC->Pnmi.Port[PhysPortIndex].RxShortZeroMark;
1375 }
1376
1377 /* Tell VctStatus() that a link was up meanwhile. */
1378 pAC->Pnmi.VctStatus[PhysPortIndex] |= SK_PNMI_VCT_LINK;
1379 break;
1380
1381 case SK_PNMI_EVT_RLMT_PORT_DOWN:
1382 PhysPortIndex = (unsigned int)Param.Para32[0];
1383
1384#ifdef DEBUG
1385 if (PhysPortIndex >= SK_MAX_MACS) {
1386
1387 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1388 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_PORT_DOWN parameter"
1389 " wrong, PhysPortIndex=%d\n", PhysPortIndex));
1390
1391 return (0);
1392 }
1393#endif /* DEBUG */
1394
1395 /*
1396 * Store a trap message in the trap buffer and generate an event for
1397 * user space applications with the SK_DRIVER_SENDEVENT macro.
1398 */
1399 QueueRlmtPortTrap(pAC, OID_SKGE_TRAP_RLMT_PORT_DOWN, PhysPortIndex);
1400 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1401
1402 /* Bugfix #10620 - get zero level for incremental difference */
1403 if (MacType == SK_MAC_XMAC) {
1404
1405 (void)pAC->GIni.GIFunc.pFnMacStatistic(pAC, IoC, PhysPortIndex,
1406 XM_RXE_SHT_ERR, &Val32);
1407
1408 pAC->Pnmi.Port[PhysPortIndex].RxShortZeroMark =
1409 (((SK_U64)pAC->Pnmi.Port[PhysPortIndex].
1410 CounterHigh[SK_PNMI_HRX_SHORTS] << 32) | (SK_U64)Val32);
1411 }
1412 break;
1413
1414 case SK_PNMI_EVT_RLMT_ACTIVE_DOWN:
1415 PhysPortIndex = (unsigned int)Param.Para32[0];
1416 NetIndex = (SK_U32)Param.Para32[1];
1417
1418#ifdef DEBUG
1419 if (PhysPortIndex >= SK_MAX_MACS) {
1420
1421 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1422 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_DOWN parameter too high, PhysPort=%d\n",
1423 PhysPortIndex));
1424 }
1425
1426 if (NetIndex >= pAC->Rlmt.NumNets) {
1427
1428 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1429 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_DOWN parameter too high, NetIndex=%d\n",
1430 NetIndex));
1431 }
1432#endif /* DEBUG */
1433
1434 /*
1435 * For now, ignore event if NetIndex != 0.
1436 */
1437 if (Param.Para32[1] != 0) {
1438
1439 return (0);
1440 }
1441
1442 /*
1443 * Nothing to do if port is already inactive
1444 */
1445 if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
1446
1447 return (0);
1448 }
1449
1450 /*
1451 * Update statistic counters to calculate new offset for the virtual
1452 * port and increment semaphore to indicate that an update was already
1453 * done.
1454 */
1455 if (MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1) !=
1456 SK_PNMI_ERR_OK) {
1457
1458 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
1459 return (0);
1460 }
1461 pAC->Pnmi.MacUpdatedFlag ++;
1462
1463 /*
1464 * Calculate new counter offset for virtual port to grant continous
1465 * counting on port switches. The virtual port consists of all currently
1466 * active ports. The port down event indicates that a port is removed
1467 * from the virtual port. Therefore add the counter value of the removed
1468 * port to the CounterOffset for the virtual port to grant the same
1469 * counter value.
1470 */
1471 for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX;
1472 CounterIndex ++) {
1473
1474 if (!StatAddr[CounterIndex][MacType].GetOffset) {
1475
1476 continue;
1477 }
1478
1479 Value = GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex);
1480
1481 pAC->Pnmi.VirtualCounterOffset[CounterIndex] += Value;
1482 }
1483
1484 /*
1485 * Set port to inactive
1486 */
1487 pAC->Pnmi.Port[PhysPortIndex].ActiveFlag = SK_FALSE;
1488
1489 pAC->Pnmi.MacUpdatedFlag --;
1490 break;
1491
1492 case SK_PNMI_EVT_RLMT_ACTIVE_UP:
1493 PhysPortIndex = (unsigned int)Param.Para32[0];
1494 NetIndex = (SK_U32)Param.Para32[1];
1495
1496#ifdef DEBUG
1497 if (PhysPortIndex >= SK_MAX_MACS) {
1498
1499 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1500 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_UP parameter too high, PhysPort=%d\n",
1501 PhysPortIndex));
1502 }
1503
1504 if (NetIndex >= pAC->Rlmt.NumNets) {
1505
1506 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1507 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_UP parameter too high, NetIndex=%d\n",
1508 NetIndex));
1509 }
1510#endif /* DEBUG */
1511
1512 /*
1513 * For now, ignore event if NetIndex != 0.
1514 */
1515 if (Param.Para32[1] != 0) {
1516
1517 return (0);
1518 }
1519
1520 /*
1521 * Nothing to do if port is already active
1522 */
1523 if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
1524
1525 return (0);
1526 }
1527
1528 /*
1529 * Statistic maintenance
1530 */
1531 pAC->Pnmi.RlmtChangeCts ++;
1532 pAC->Pnmi.RlmtChangeTime = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
1533
1534 /*
1535 * Store a trap message in the trap buffer and generate an event for
1536 * user space applications with the SK_DRIVER_SENDEVENT macro.
1537 */
1538 QueueRlmtNewMacTrap(pAC, PhysPortIndex);
1539 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1540
1541 /*
1542 * Update statistic counters to calculate new offset for the virtual
1543 * port and increment semaphore to indicate that an update was
1544 * already done.
1545 */
1546 if (MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1) !=
1547 SK_PNMI_ERR_OK) {
1548
1549 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
1550 return (0);
1551 }
1552 pAC->Pnmi.MacUpdatedFlag ++;
1553
1554 /*
1555 * Calculate new counter offset for virtual port to grant continous
1556 * counting on port switches. A new port is added to the virtual port.
1557 * Therefore substract the counter value of the new port from the
1558 * CounterOffset for the virtual port to grant the same value.
1559 */
1560 for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX;
1561 CounterIndex ++) {
1562
1563 if (!StatAddr[CounterIndex][MacType].GetOffset) {
1564
1565 continue;
1566 }
1567
1568 Value = GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex);
1569
1570 pAC->Pnmi.VirtualCounterOffset[CounterIndex] -= Value;
1571 }
1572
1573 /* Set port to active */
1574 pAC->Pnmi.Port[PhysPortIndex].ActiveFlag = SK_TRUE;
1575
1576 pAC->Pnmi.MacUpdatedFlag --;
1577 break;
1578
1579 case SK_PNMI_EVT_RLMT_SEGMENTATION:
1580 /*
1581 * Para.Para32[0] contains the NetIndex.
1582 */
1583
1584 /*
1585 * Store a trap message in the trap buffer and generate an event for
1586 * user space applications with the SK_DRIVER_SENDEVENT macro.
1587 */
1588 QueueSimpleTrap(pAC, OID_SKGE_TRAP_RLMT_SEGMENTATION);
1589 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1590 break;
1591
1592 case SK_PNMI_EVT_RLMT_SET_NETS:
1593 /*
1594 * Param.Para32[0] contains the number of Nets.
1595 * Param.Para32[1] is reserved, contains -1.
1596 */
1597 /*
1598 * Check number of nets
1599 */
1600 MaxNetNumber = pAC->GIni.GIMacsFound;
1601 if (((unsigned int)Param.Para32[0] < 1)
1602 || ((unsigned int)Param.Para32[0] > MaxNetNumber)) {
1603 return (SK_PNMI_ERR_UNKNOWN_NET);
1604 }
1605
1606 if ((unsigned int)Param.Para32[0] == 1) { /* single net mode */
1607 pAC->Pnmi.DualNetActiveFlag = SK_FALSE;
1608 }
1609 else { /* dual net mode */
1610 pAC->Pnmi.DualNetActiveFlag = SK_TRUE;
1611 }
1612 break;
1613
1614 case SK_PNMI_EVT_VCT_RESET:
1615 PhysPortIndex = Param.Para32[0];
1616 pPrt = &pAC->GIni.GP[PhysPortIndex];
1617 pVctBackupData = &pAC->Pnmi.VctBackup[PhysPortIndex];
1618
1619 if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING) {
1620 RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_FALSE);
1621 if (RetCode == 2) {
1622 /*
1623 * VCT test is still running.
1624 * Start VCT timer counter again.
1625 */
1626 SK_MEMSET((char *) &Param, 0, sizeof(Param));
1627 Param.Para32[0] = PhysPortIndex;
1628 Param.Para32[1] = -1;
1629 SkTimerStart(pAC, IoC,
1630 &pAC->Pnmi.VctTimeout[PhysPortIndex].VctTimer,
1631 4000000, SKGE_PNMI, SK_PNMI_EVT_VCT_RESET, Param);
1632 break;
1633 }
1634 pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_PENDING;
1635 pAC->Pnmi.VctStatus[PhysPortIndex] |=
1636 (SK_PNMI_VCT_NEW_VCT_DATA | SK_PNMI_VCT_TEST_DONE);
1637
1638 /* Copy results for later use to PNMI struct. */
1639 for (i = 0; i < 4; i++) {
1640 if (pPrt->PMdiPairSts[i] == SK_PNMI_VCT_NORMAL_CABLE) {
1641 if ((pPrt->PMdiPairLen[i] > 35) &&
1642 (pPrt->PMdiPairLen[i] < 0xff)) {
1643 pPrt->PMdiPairSts[i] = SK_PNMI_VCT_IMPEDANCE_MISMATCH;
1644 }
1645 }
1646 if ((pPrt->PMdiPairLen[i] > 35) &&
1647 (pPrt->PMdiPairLen[i] != 0xff)) {
1648 CableLength = 1000 *
1649 (((175 * pPrt->PMdiPairLen[i]) / 210) - 28);
1650 }
1651 else {
1652 CableLength = 0;
1653 }
1654 pVctBackupData->PMdiPairLen[i] = CableLength;
1655 pVctBackupData->PMdiPairSts[i] = pPrt->PMdiPairSts[i];
1656 }
1657
1658 Param.Para32[0] = PhysPortIndex;
1659 Param.Para32[1] = -1;
1660 SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Param);
1661 SkEventDispatcher(pAC, IoC);
1662 }
1663
1664 break;
1665
1666 default:
1667 break;
1668 }
1669
1670 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
1671 return (0);
1672}
1673
1674
1675/******************************************************************************
1676 *
1677 * Private functions
1678 *
1679 */
1680
1681/*****************************************************************************
1682 *
1683 * PnmiVar - Gets, presets, and sets single OIDs
1684 *
1685 * Description:
1686 * Looks up the requested OID, calls the corresponding handler
1687 * function, and passes the parameters with the get, preset, or
1688 * set command. The function is called by SkGePnmiGetVar,
1689 * SkGePnmiPreSetVar, or SkGePnmiSetVar.
1690 *
1691 * Returns:
1692 * SK_PNMI_ERR_XXX. For details have a look at the description of the
1693 * calling functions.
1694 * SK_PNMI_ERR_UNKNOWN_NET The requested NetIndex doesn't exist
1695 */
1696PNMI_STATIC int PnmiVar(
1697SK_AC *pAC, /* Pointer to adapter context */
1698SK_IOC IoC, /* IO context handle */
1699int Action, /* GET/PRESET/SET action */
1700SK_U32 Id, /* Object ID that is to be processed */
1701char *pBuf, /* Buffer used for the management data transfer */
1702unsigned int *pLen, /* Total length of pBuf management data */
1703SK_U32 Instance, /* Instance (1..n) that is to be set or -1 */
1704SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
1705{
1706 unsigned int TableIndex;
1707 int Ret;
1708
1709
1710 if ((TableIndex = LookupId(Id)) == (unsigned int)(-1)) {
1711
1712 *pLen = 0;
1713 return (SK_PNMI_ERR_UNKNOWN_OID);
1714 }
1715
1716 /* Check NetIndex */
1717 if (NetIndex >= pAC->Rlmt.NumNets) {
1718 return (SK_PNMI_ERR_UNKNOWN_NET);
1719 }
1720
1721 SK_PNMI_CHECKFLAGS("PnmiVar: On call");
1722
1723 Ret = IdTable[TableIndex].Func(pAC, IoC, Action, Id, pBuf, pLen,
1724 Instance, TableIndex, NetIndex);
1725
1726 SK_PNMI_CHECKFLAGS("PnmiVar: On return");
1727
1728 return (Ret);
1729}
1730
1731/*****************************************************************************
1732 *
1733 * PnmiStruct - Presets and Sets data in structure SK_PNMI_STRUCT_DATA
1734 *
1735 * Description:
1736 * The return value of the function will also be stored in
1737 * SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of
1738 * SK_PNMI_MIN_STRUCT_SIZE. The sub-function runs through the IdTable,
1739 * checks which OIDs are able to set, and calls the handler function of
1740 * the OID to perform the set. The return value of the function will
1741 * also be stored in SK_PNMI_STRUCT_DATA if the passed buffer has the
1742 * minimum size of SK_PNMI_MIN_STRUCT_SIZE. The function is called
1743 * by SkGePnmiPreSetStruct and SkGePnmiSetStruct.
1744 *
1745 * Returns:
1746 * SK_PNMI_ERR_XXX. The codes are described in the calling functions.
1747 * SK_PNMI_ERR_UNKNOWN_NET The requested NetIndex doesn't exist
1748 */
1749PNMI_STATIC int PnmiStruct(
1750SK_AC *pAC, /* Pointer to adapter context */
1751SK_IOC IoC, /* IO context handle */
1752int Action, /* PRESET/SET action to be performed */
1753char *pBuf, /* Buffer used for the management data transfer */
1754unsigned int *pLen, /* Length of pBuf management data buffer */
1755SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
1756{
1757 int Ret;
1758 unsigned int TableIndex;
1759 unsigned int DstOffset;
1760 unsigned int Len;
1761 unsigned int InstanceNo;
1762 unsigned int InstanceCnt;
1763 SK_U32 Instance;
1764 SK_U32 Id;
1765
1766
1767 /* Check if the passed buffer has the right size */
1768 if (*pLen < SK_PNMI_STRUCT_SIZE) {
1769
1770 /* Check if we can return the error within the buffer */
1771 if (*pLen >= SK_PNMI_MIN_STRUCT_SIZE) {
1772
1773 SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_TOO_SHORT,
1774 (SK_U32)(-1));
1775 }
1776
1777 *pLen = SK_PNMI_STRUCT_SIZE;
1778 return (SK_PNMI_ERR_TOO_SHORT);
1779 }
1780
1781 /* Check NetIndex */
1782 if (NetIndex >= pAC->Rlmt.NumNets) {
1783 return (SK_PNMI_ERR_UNKNOWN_NET);
1784 }
1785
1786 SK_PNMI_CHECKFLAGS("PnmiStruct: On call");
1787
1788 /*
1789 * Update the values of RLMT and SIRQ and increment semaphores to
1790 * indicate that an update was already done.
1791 */
1792 if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
1793
1794 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
1795 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
1796 return (Ret);
1797 }
1798
1799 if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) {
1800
1801 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
1802 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
1803 return (Ret);
1804 }
1805
1806 pAC->Pnmi.RlmtUpdatedFlag ++;
1807 pAC->Pnmi.SirqUpdatedFlag ++;
1808
1809 /* Preset/Set values */
1810 for (TableIndex = 0; TableIndex < ID_TABLE_SIZE; TableIndex ++) {
1811
1812 if ((IdTable[TableIndex].Access != SK_PNMI_RW) &&
1813 (IdTable[TableIndex].Access != SK_PNMI_WO)) {
1814
1815 continue;
1816 }
1817
1818 InstanceNo = IdTable[TableIndex].InstanceNo;
1819 Id = IdTable[TableIndex].Id;
1820
1821 for (InstanceCnt = 1; InstanceCnt <= InstanceNo;
1822 InstanceCnt ++) {
1823
1824 DstOffset = IdTable[TableIndex].Offset +
1825 (InstanceCnt - 1) *
1826 IdTable[TableIndex].StructSize;
1827
1828 /*
1829 * Because VPD multiple instance variables are
1830 * not setable we do not need to evaluate VPD
1831 * instances. Have a look to VPD instance
1832 * calculation in SkPnmiGetStruct().
1833 */
1834 Instance = (SK_U32)InstanceCnt;
1835
1836 /*
1837 * Evaluate needed buffer length
1838 */
1839 Len = 0;
1840 Ret = IdTable[TableIndex].Func(pAC, IoC,
1841 SK_PNMI_GET, IdTable[TableIndex].Id,
1842 NULL, &Len, Instance, TableIndex, NetIndex);
1843
1844 if (Ret == SK_PNMI_ERR_UNKNOWN_INST) {
1845
1846 break;
1847 }
1848 if (Ret != SK_PNMI_ERR_TOO_SHORT) {
1849
1850 pAC->Pnmi.RlmtUpdatedFlag --;
1851 pAC->Pnmi.SirqUpdatedFlag --;
1852
1853 SK_PNMI_CHECKFLAGS("PnmiStruct: On return");
1854 SK_PNMI_SET_STAT(pBuf,
1855 SK_PNMI_ERR_GENERAL, DstOffset);
1856 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
1857 return (SK_PNMI_ERR_GENERAL);
1858 }
1859 if (Id == OID_SKGE_VPD_ACTION) {
1860
1861 switch (*(pBuf + DstOffset)) {
1862
1863 case SK_PNMI_VPD_CREATE:
1864 Len = 3 + *(pBuf + DstOffset + 3);
1865 break;
1866
1867 case SK_PNMI_VPD_DELETE:
1868 Len = 3;
1869 break;
1870
1871 default:
1872 Len = 1;
1873 break;
1874 }
1875 }
1876
1877 /* Call the OID handler function */
1878 Ret = IdTable[TableIndex].Func(pAC, IoC, Action,
1879 IdTable[TableIndex].Id, pBuf + DstOffset,
1880 &Len, Instance, TableIndex, NetIndex);
1881
1882 if (Ret != SK_PNMI_ERR_OK) {
1883
1884 pAC->Pnmi.RlmtUpdatedFlag --;
1885 pAC->Pnmi.SirqUpdatedFlag --;
1886
1887 SK_PNMI_CHECKFLAGS("PnmiStruct: On return");
1888 SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_BAD_VALUE,
1889 DstOffset);
1890 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
1891 return (SK_PNMI_ERR_BAD_VALUE);
1892 }
1893 }
1894 }
1895
1896 pAC->Pnmi.RlmtUpdatedFlag --;
1897 pAC->Pnmi.SirqUpdatedFlag --;
1898
1899 SK_PNMI_CHECKFLAGS("PnmiStruct: On return");
1900 SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_OK, (SK_U32)(-1));
1901 return (SK_PNMI_ERR_OK);
1902}
1903
1904/*****************************************************************************
1905 *
1906 * LookupId - Lookup an OID in the IdTable
1907 *
1908 * Description:
1909 * Scans the IdTable to find the table entry of an OID.
1910 *
1911 * Returns:
1912 * The table index or -1 if not found.
1913 */
1914PNMI_STATIC int LookupId(
1915SK_U32 Id) /* Object identifier to be searched */
1916{
1917 int i;
1918
1919 for (i = 0; i < ID_TABLE_SIZE; i++) {
1920
1921 if (IdTable[i].Id == Id) {
1922
1923 return i;
1924 }
1925 }
1926
1927 return (-1);
1928}
1929
1930/*****************************************************************************
1931 *
1932 * OidStruct - Handler of OID_SKGE_ALL_DATA
1933 *
1934 * Description:
1935 * This OID performs a Get/Preset/SetStruct call and returns all data
1936 * in a SK_PNMI_STRUCT_DATA structure.
1937 *
1938 * Returns:
1939 * SK_PNMI_ERR_OK The request was successfully performed.
1940 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
1941 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
1942 * the correct data (e.g. a 32bit value is
1943 * needed, but a 16 bit value was passed).
1944 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
1945 * value range.
1946 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
1947 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
1948 * exist (e.g. port instance 3 on a two port
1949 * adapter.
1950 */
1951PNMI_STATIC int OidStruct(
1952SK_AC *pAC, /* Pointer to adapter context */
1953SK_IOC IoC, /* IO context handle */
1954int Action, /* GET/PRESET/SET action */
1955SK_U32 Id, /* Object ID that is to be processed */
1956char *pBuf, /* Buffer used for the management data transfer */
1957unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
1958SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
1959unsigned int TableIndex, /* Index to the Id table */
1960SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
1961{
1962 if (Id != OID_SKGE_ALL_DATA) {
1963
1964 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR003,
1965 SK_PNMI_ERR003MSG);
1966
1967 *pLen = 0;
1968 return (SK_PNMI_ERR_GENERAL);
1969 }
1970
1971 /*
1972 * Check instance. We only handle single instance variables
1973 */
1974 if (Instance != (SK_U32)(-1) && Instance != 1) {
1975
1976 *pLen = 0;
1977 return (SK_PNMI_ERR_UNKNOWN_INST);
1978 }
1979
1980 switch (Action) {
1981
1982 case SK_PNMI_GET:
1983 return (SkPnmiGetStruct(pAC, IoC, pBuf, pLen, NetIndex));
1984
1985 case SK_PNMI_PRESET:
1986 return (SkPnmiPreSetStruct(pAC, IoC, pBuf, pLen, NetIndex));
1987
1988 case SK_PNMI_SET:
1989 return (SkPnmiSetStruct(pAC, IoC, pBuf, pLen, NetIndex));
1990 }
1991
1992 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR004, SK_PNMI_ERR004MSG);
1993
1994 *pLen = 0;
1995 return (SK_PNMI_ERR_GENERAL);
1996}
1997
1998/*****************************************************************************
1999 *
2000 * Perform - OID handler of OID_SKGE_ACTION
2001 *
2002 * Description:
2003 * None.
2004 *
2005 * Returns:
2006 * SK_PNMI_ERR_OK The request was successfully performed.
2007 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2008 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2009 * the correct data (e.g. a 32bit value is
2010 * needed, but a 16 bit value was passed).
2011 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
2012 * value range.
2013 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
2014 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2015 * exist (e.g. port instance 3 on a two port
2016 * adapter.
2017 */
2018PNMI_STATIC int Perform(
2019SK_AC *pAC, /* Pointer to adapter context */
2020SK_IOC IoC, /* IO context handle */
2021int Action, /* GET/PRESET/SET action */
2022SK_U32 Id, /* Object ID that is to be processed */
2023char *pBuf, /* Buffer used for the management data transfer */
2024unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
2025SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2026unsigned int TableIndex, /* Index to the Id table */
2027SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
2028{
2029 int Ret;
2030 SK_U32 ActionOp;
2031
2032
2033 /*
2034 * Check instance. We only handle single instance variables
2035 */
2036 if (Instance != (SK_U32)(-1) && Instance != 1) {
2037
2038 *pLen = 0;
2039 return (SK_PNMI_ERR_UNKNOWN_INST);
2040 }
2041
2042 if (*pLen < sizeof(SK_U32)) {
2043
2044 *pLen = sizeof(SK_U32);
2045 return (SK_PNMI_ERR_TOO_SHORT);
2046 }
2047
2048 /* Check if a get should be performed */
2049 if (Action == SK_PNMI_GET) {
2050
2051 /* A get is easy. We always return the same value */
2052 ActionOp = (SK_U32)SK_PNMI_ACT_IDLE;
2053 SK_PNMI_STORE_U32(pBuf, ActionOp);
2054 *pLen = sizeof(SK_U32);
2055
2056 return (SK_PNMI_ERR_OK);
2057 }
2058
2059 /* Continue with PRESET/SET action */
2060 if (*pLen > sizeof(SK_U32)) {
2061
2062 return (SK_PNMI_ERR_BAD_VALUE);
2063 }
2064
2065 /* Check if the command is a known one */
2066 SK_PNMI_READ_U32(pBuf, ActionOp);
2067 if (*pLen > sizeof(SK_U32) ||
2068 (ActionOp != SK_PNMI_ACT_IDLE &&
2069 ActionOp != SK_PNMI_ACT_RESET &&
2070 ActionOp != SK_PNMI_ACT_SELFTEST &&
2071 ActionOp != SK_PNMI_ACT_RESETCNT)) {
2072
2073 *pLen = 0;
2074 return (SK_PNMI_ERR_BAD_VALUE);
2075 }
2076
2077 /* A preset ends here */
2078 if (Action == SK_PNMI_PRESET) {
2079
2080 return (SK_PNMI_ERR_OK);
2081 }
2082
2083 switch (ActionOp) {
2084
2085 case SK_PNMI_ACT_IDLE:
2086 /* Nothing to do */
2087 break;
2088
2089 case SK_PNMI_ACT_RESET:
2090 /*
2091 * Perform a driver reset or something that comes near
2092 * to this.
2093 */
2094 Ret = SK_DRIVER_RESET(pAC, IoC);
2095 if (Ret != 0) {
2096
2097 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR005,
2098 SK_PNMI_ERR005MSG);
2099
2100 return (SK_PNMI_ERR_GENERAL);
2101 }
2102 break;
2103
2104 case SK_PNMI_ACT_SELFTEST:
2105 /*
2106 * Perform a driver selftest or something similar to this.
2107 * Currently this feature is not used and will probably
2108 * implemented in another way.
2109 */
2110 Ret = SK_DRIVER_SELFTEST(pAC, IoC);
2111 pAC->Pnmi.TestResult = Ret;
2112 break;
2113
2114 case SK_PNMI_ACT_RESETCNT:
2115 /* Set all counters and timestamps to zero */
2116 ResetCounter(pAC, IoC, NetIndex);
2117 break;
2118
2119 default:
2120 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR006,
2121 SK_PNMI_ERR006MSG);
2122
2123 return (SK_PNMI_ERR_GENERAL);
2124 }
2125
2126 return (SK_PNMI_ERR_OK);
2127}
2128
2129/*****************************************************************************
2130 *
2131 * Mac8023Stat - OID handler of OID_GEN_XXX and OID_802_3_XXX
2132 *
2133 * Description:
2134 * Retrieves the statistic values of the virtual port (logical
2135 * index 0). Only special OIDs of NDIS are handled which consist
2136 * of a 32 bit instead of a 64 bit value. The OIDs are public
2137 * because perhaps some other platform can use them too.
2138 *
2139 * Returns:
2140 * SK_PNMI_ERR_OK The request was successfully performed.
2141 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2142 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2143 * the correct data (e.g. a 32bit value is
2144 * needed, but a 16 bit value was passed).
2145 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2146 * exist (e.g. port instance 3 on a two port
2147 * adapter.
2148 */
2149PNMI_STATIC int Mac8023Stat(
2150SK_AC *pAC, /* Pointer to adapter context */
2151SK_IOC IoC, /* IO context handle */
2152int Action, /* GET/PRESET/SET action */
2153SK_U32 Id, /* Object ID that is to be processed */
2154char *pBuf, /* Buffer used for the management data transfer */
2155unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
2156SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2157unsigned int TableIndex, /* Index to the Id table */
2158SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
2159{
2160 int Ret;
2161 SK_U64 StatVal;
2162 SK_U32 StatVal32;
2163 SK_BOOL Is64BitReq = SK_FALSE;
2164
2165 /*
2166 * Only the active Mac is returned
2167 */
2168 if (Instance != (SK_U32)(-1) && Instance != 1) {
2169
2170 *pLen = 0;
2171 return (SK_PNMI_ERR_UNKNOWN_INST);
2172 }
2173
2174 /*
2175 * Check action type
2176 */
2177 if (Action != SK_PNMI_GET) {
2178
2179 *pLen = 0;
2180 return (SK_PNMI_ERR_READ_ONLY);
2181 }
2182
2183 /* Check length */
2184 switch (Id) {
2185
2186 case OID_802_3_PERMANENT_ADDRESS:
2187 case OID_802_3_CURRENT_ADDRESS:
2188 if (*pLen < sizeof(SK_MAC_ADDR)) {
2189
2190 *pLen = sizeof(SK_MAC_ADDR);
2191 return (SK_PNMI_ERR_TOO_SHORT);
2192 }
2193 break;
2194
2195 default:
2196#ifndef SK_NDIS_64BIT_CTR
2197 if (*pLen < sizeof(SK_U32)) {
2198 *pLen = sizeof(SK_U32);
2199 return (SK_PNMI_ERR_TOO_SHORT);
2200 }
2201
2202#else /* SK_NDIS_64BIT_CTR */
2203
2204 /* for compatibility, at least 32bit are required for OID */
2205 if (*pLen < sizeof(SK_U32)) {
2206 /*
2207 * but indicate handling for 64bit values,
2208 * if insufficient space is provided
2209 */
2210 *pLen = sizeof(SK_U64);
2211 return (SK_PNMI_ERR_TOO_SHORT);
2212 }
2213
2214 Is64BitReq = (*pLen < sizeof(SK_U64)) ? SK_FALSE : SK_TRUE;
2215#endif /* SK_NDIS_64BIT_CTR */
2216 break;
2217 }
2218
2219 /*
2220 * Update all statistics, because we retrieve virtual MAC, which
2221 * consists of multiple physical statistics and increment semaphore
2222 * to indicate that an update was already done.
2223 */
2224 Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
2225 if ( Ret != SK_PNMI_ERR_OK) {
2226
2227 *pLen = 0;
2228 return (Ret);
2229 }
2230 pAC->Pnmi.MacUpdatedFlag ++;
2231
2232 /*
2233 * Get value (MAC Index 0 identifies the virtual MAC)
2234 */
2235 switch (Id) {
2236
2237 case OID_802_3_PERMANENT_ADDRESS:
2238 CopyMac(pBuf, &pAC->Addr.Net[NetIndex].PermanentMacAddress);
2239 *pLen = sizeof(SK_MAC_ADDR);
2240 break;
2241
2242 case OID_802_3_CURRENT_ADDRESS:
2243 CopyMac(pBuf, &pAC->Addr.Net[NetIndex].CurrentMacAddress);
2244 *pLen = sizeof(SK_MAC_ADDR);
2245 break;
2246
2247 default:
2248 StatVal = GetStatVal(pAC, IoC, 0, IdTable[TableIndex].Param, NetIndex);
2249
2250 /* by default 32bit values are evaluated */
2251 if (!Is64BitReq) {
2252 StatVal32 = (SK_U32)StatVal;
2253 SK_PNMI_STORE_U32(pBuf, StatVal32);
2254 *pLen = sizeof(SK_U32);
2255 }
2256 else {
2257 SK_PNMI_STORE_U64(pBuf, StatVal);
2258 *pLen = sizeof(SK_U64);
2259 }
2260 break;
2261 }
2262
2263 pAC->Pnmi.MacUpdatedFlag --;
2264
2265 return (SK_PNMI_ERR_OK);
2266}
2267
2268/*****************************************************************************
2269 *
2270 * MacPrivateStat - OID handler function of OID_SKGE_STAT_XXX
2271 *
2272 * Description:
2273 * Retrieves the MAC statistic data.
2274 *
2275 * Returns:
2276 * SK_PNMI_ERR_OK The request was successfully performed.
2277 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2278 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2279 * the correct data (e.g. a 32bit value is
2280 * needed, but a 16 bit value was passed).
2281 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2282 * exist (e.g. port instance 3 on a two port
2283 * adapter.
2284 */
2285PNMI_STATIC int MacPrivateStat(
2286SK_AC *pAC, /* Pointer to adapter context */
2287SK_IOC IoC, /* IO context handle */
2288int Action, /* GET/PRESET/SET action */
2289SK_U32 Id, /* Object ID that is to be processed */
2290char *pBuf, /* Buffer used for the management data transfer */
2291unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
2292SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2293unsigned int TableIndex, /* Index to the Id table */
2294SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
2295{
2296 unsigned int LogPortMax;
2297 unsigned int LogPortIndex;
2298 unsigned int PhysPortMax;
2299 unsigned int Limit;
2300 unsigned int Offset;
2301 int MacType;
2302 int Ret;
2303 SK_U64 StatVal;
2304
2305
2306
2307 /* Calculate instance if wished. MAC index 0 is the virtual MAC */
2308 PhysPortMax = pAC->GIni.GIMacsFound;
2309 LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
2310
2311 MacType = pAC->GIni.GIMacType;
2312
2313 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
2314 LogPortMax--;
2315 }
2316
2317 if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
2318 /* Check instance range */
2319 if ((Instance < 1) || (Instance > LogPortMax)) {
2320
2321 *pLen = 0;
2322 return (SK_PNMI_ERR_UNKNOWN_INST);
2323 }
2324 LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
2325 Limit = LogPortIndex + 1;
2326 }
2327
2328 else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
2329
2330 LogPortIndex = 0;
2331 Limit = LogPortMax;
2332 }
2333
2334 /* Check action */
2335 if (Action != SK_PNMI_GET) {
2336
2337 *pLen = 0;
2338 return (SK_PNMI_ERR_READ_ONLY);
2339 }
2340
2341 /* Check length */
2342 if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U64)) {
2343
2344 *pLen = (Limit - LogPortIndex) * sizeof(SK_U64);
2345 return (SK_PNMI_ERR_TOO_SHORT);
2346 }
2347
2348 /*
2349 * Update MAC statistic and increment semaphore to indicate that
2350 * an update was already done.
2351 */
2352 Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
2353 if (Ret != SK_PNMI_ERR_OK) {
2354
2355 *pLen = 0;
2356 return (Ret);
2357 }
2358 pAC->Pnmi.MacUpdatedFlag ++;
2359
2360 /* Get value */
2361 Offset = 0;
2362 for (; LogPortIndex < Limit; LogPortIndex ++) {
2363
2364 switch (Id) {
2365
2366/* XXX not yet implemented due to XMAC problems
2367 case OID_SKGE_STAT_TX_UTIL:
2368 return (SK_PNMI_ERR_GENERAL);
2369*/
2370/* XXX not yet implemented due to XMAC problems
2371 case OID_SKGE_STAT_RX_UTIL:
2372 return (SK_PNMI_ERR_GENERAL);
2373*/
2374 case OID_SKGE_STAT_RX:
2375 if (MacType == SK_MAC_GMAC) {
2376 StatVal =
2377 GetStatVal(pAC, IoC, LogPortIndex,
2378 SK_PNMI_HRX_BROADCAST, NetIndex) +
2379 GetStatVal(pAC, IoC, LogPortIndex,
2380 SK_PNMI_HRX_MULTICAST, NetIndex) +
2381 GetStatVal(pAC, IoC, LogPortIndex,
2382 SK_PNMI_HRX_UNICAST, NetIndex) +
2383 GetStatVal(pAC, IoC, LogPortIndex,
2384 SK_PNMI_HRX_UNDERSIZE, NetIndex);
2385 }
2386 else {
2387 StatVal = GetStatVal(pAC, IoC, LogPortIndex,
2388 IdTable[TableIndex].Param, NetIndex);
2389 }
2390 break;
2391
2392 case OID_SKGE_STAT_TX:
2393 if (MacType == SK_MAC_GMAC) {
2394 StatVal =
2395 GetStatVal(pAC, IoC, LogPortIndex,
2396 SK_PNMI_HTX_BROADCAST, NetIndex) +
2397 GetStatVal(pAC, IoC, LogPortIndex,
2398 SK_PNMI_HTX_MULTICAST, NetIndex) +
2399 GetStatVal(pAC, IoC, LogPortIndex,
2400 SK_PNMI_HTX_UNICAST, NetIndex);
2401 }
2402 else {
2403 StatVal = GetStatVal(pAC, IoC, LogPortIndex,
2404 IdTable[TableIndex].Param, NetIndex);
2405 }
2406 break;
2407
2408 default:
2409 StatVal = GetStatVal(pAC, IoC, LogPortIndex,
2410 IdTable[TableIndex].Param, NetIndex);
2411 }
2412 SK_PNMI_STORE_U64(pBuf + Offset, StatVal);
2413
2414 Offset += sizeof(SK_U64);
2415 }
2416 *pLen = Offset;
2417
2418 pAC->Pnmi.MacUpdatedFlag --;
2419
2420 return (SK_PNMI_ERR_OK);
2421}
2422
2423/*****************************************************************************
2424 *
2425 * Addr - OID handler function of OID_SKGE_PHYS_CUR_ADDR and _FAC_ADDR
2426 *
2427 * Description:
2428 * Get/Presets/Sets the current and factory MAC address. The MAC
2429 * address of the virtual port, which is reported to the OS, may
2430 * not be changed, but the physical ones. A set to the virtual port
2431 * will be ignored. No error should be reported because otherwise
2432 * a multiple instance set (-1) would always fail.
2433 *
2434 * Returns:
2435 * SK_PNMI_ERR_OK The request was successfully performed.
2436 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2437 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2438 * the correct data (e.g. a 32bit value is
2439 * needed, but a 16 bit value was passed).
2440 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
2441 * value range.
2442 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
2443 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2444 * exist (e.g. port instance 3 on a two port
2445 * adapter.
2446 */
2447PNMI_STATIC int Addr(
2448SK_AC *pAC, /* Pointer to adapter context */
2449SK_IOC IoC, /* IO context handle */
2450int Action, /* GET/PRESET/SET action */
2451SK_U32 Id, /* Object ID that is to be processed */
2452char *pBuf, /* Buffer used for the management data transfer */
2453unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
2454SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2455unsigned int TableIndex, /* Index to the Id table */
2456SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
2457{
2458 int Ret;
2459 unsigned int LogPortMax;
2460 unsigned int PhysPortMax;
2461 unsigned int LogPortIndex;
2462 unsigned int PhysPortIndex;
2463 unsigned int Limit;
2464 unsigned int Offset = 0;
2465
2466 /*
2467 * Calculate instance if wished. MAC index 0 is the virtual
2468 * MAC.
2469 */
2470 PhysPortMax = pAC->GIni.GIMacsFound;
2471 LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
2472
2473 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
2474 LogPortMax--;
2475 }
2476
2477 if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
2478 /* Check instance range */
2479 if ((Instance < 1) || (Instance > LogPortMax)) {
2480
2481 *pLen = 0;
2482 return (SK_PNMI_ERR_UNKNOWN_INST);
2483 }
2484 LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
2485 Limit = LogPortIndex + 1;
2486 }
2487 else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
2488
2489 LogPortIndex = 0;
2490 Limit = LogPortMax;
2491 }
2492
2493 /*
2494 * Perform Action
2495 */
2496 if (Action == SK_PNMI_GET) {
2497
2498 /* Check length */
2499 if (*pLen < (Limit - LogPortIndex) * 6) {
2500
2501 *pLen = (Limit - LogPortIndex) * 6;
2502 return (SK_PNMI_ERR_TOO_SHORT);
2503 }
2504
2505 /*
2506 * Get value
2507 */
2508 for (; LogPortIndex < Limit; LogPortIndex ++) {
2509
2510 switch (Id) {
2511
2512 case OID_SKGE_PHYS_CUR_ADDR:
2513 if (LogPortIndex == 0) {
2514 CopyMac(pBuf + Offset, &pAC->Addr.Net[NetIndex].CurrentMacAddress);
2515 }
2516 else {
2517 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
2518
2519 CopyMac(pBuf + Offset,
2520 &pAC->Addr.Port[PhysPortIndex].CurrentMacAddress);
2521 }
2522 Offset += 6;
2523 break;
2524
2525 case OID_SKGE_PHYS_FAC_ADDR:
2526 if (LogPortIndex == 0) {
2527 CopyMac(pBuf + Offset,
2528 &pAC->Addr.Net[NetIndex].PermanentMacAddress);
2529 }
2530 else {
2531 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
2532 pAC, LogPortIndex);
2533
2534 CopyMac(pBuf + Offset,
2535 &pAC->Addr.Port[PhysPortIndex].PermanentMacAddress);
2536 }
2537 Offset += 6;
2538 break;
2539
2540 default:
2541 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR008,
2542 SK_PNMI_ERR008MSG);
2543
2544 *pLen = 0;
2545 return (SK_PNMI_ERR_GENERAL);
2546 }
2547 }
2548
2549 *pLen = Offset;
2550 }
2551 else {
2552 /*
2553 * The logical MAC address may not be changed only
2554 * the physical ones
2555 */
2556 if (Id == OID_SKGE_PHYS_FAC_ADDR) {
2557
2558 *pLen = 0;
2559 return (SK_PNMI_ERR_READ_ONLY);
2560 }
2561
2562 /*
2563 * Only the current address may be changed
2564 */
2565 if (Id != OID_SKGE_PHYS_CUR_ADDR) {
2566
2567 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR009,
2568 SK_PNMI_ERR009MSG);
2569
2570 *pLen = 0;
2571 return (SK_PNMI_ERR_GENERAL);
2572 }
2573
2574 /* Check length */
2575 if (*pLen < (Limit - LogPortIndex) * 6) {
2576
2577 *pLen = (Limit - LogPortIndex) * 6;
2578 return (SK_PNMI_ERR_TOO_SHORT);
2579 }
2580 if (*pLen > (Limit - LogPortIndex) * 6) {
2581
2582 *pLen = 0;
2583 return (SK_PNMI_ERR_BAD_VALUE);
2584 }
2585
2586 /*
2587 * Check Action
2588 */
2589 if (Action == SK_PNMI_PRESET) {
2590
2591 *pLen = 0;
2592 return (SK_PNMI_ERR_OK);
2593 }
2594
2595 /*
2596 * Set OID_SKGE_MAC_CUR_ADDR
2597 */
2598 for (; LogPortIndex < Limit; LogPortIndex ++, Offset += 6) {
2599
2600 /*
2601 * A set to virtual port and set of broadcast
2602 * address will be ignored
2603 */
2604 if (LogPortIndex == 0 || SK_MEMCMP(pBuf + Offset,
2605 "\xff\xff\xff\xff\xff\xff", 6) == 0) {
2606
2607 continue;
2608 }
2609
2610 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC,
2611 LogPortIndex);
2612
2613 Ret = SkAddrOverride(pAC, IoC, PhysPortIndex,
2614 (SK_MAC_ADDR *)(pBuf + Offset),
2615 (LogPortIndex == 0 ? SK_ADDR_VIRTUAL_ADDRESS :
2616 SK_ADDR_PHYSICAL_ADDRESS));
2617 if (Ret != SK_ADDR_OVERRIDE_SUCCESS) {
2618
2619 return (SK_PNMI_ERR_GENERAL);
2620 }
2621 }
2622 *pLen = Offset;
2623 }
2624
2625 return (SK_PNMI_ERR_OK);
2626}
2627
2628/*****************************************************************************
2629 *
2630 * CsumStat - OID handler function of OID_SKGE_CHKSM_XXX
2631 *
2632 * Description:
2633 * Retrieves the statistic values of the CSUM module. The CSUM data
2634 * structure must be available in the SK_AC even if the CSUM module
2635 * is not included, because PNMI reads the statistic data from the
2636 * CSUM part of SK_AC directly.
2637 *
2638 * Returns:
2639 * SK_PNMI_ERR_OK The request was successfully performed.
2640 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2641 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2642 * the correct data (e.g. a 32bit value is
2643 * needed, but a 16 bit value was passed).
2644 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2645 * exist (e.g. port instance 3 on a two port
2646 * adapter.
2647 */
2648PNMI_STATIC int CsumStat(
2649SK_AC *pAC, /* Pointer to adapter context */
2650SK_IOC IoC, /* IO context handle */
2651int Action, /* GET/PRESET/SET action */
2652SK_U32 Id, /* Object ID that is to be processed */
2653char *pBuf, /* Buffer used for the management data transfer */
2654unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
2655SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2656unsigned int TableIndex, /* Index to the Id table */
2657SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
2658{
2659 unsigned int Index;
2660 unsigned int Limit;
2661 unsigned int Offset = 0;
2662 SK_U64 StatVal;
2663
2664
2665 /*
2666 * Calculate instance if wished
2667 */
2668 if (Instance != (SK_U32)(-1)) {
2669
2670 if ((Instance < 1) || (Instance > SKCS_NUM_PROTOCOLS)) {
2671
2672 *pLen = 0;
2673 return (SK_PNMI_ERR_UNKNOWN_INST);
2674 }
2675 Index = (unsigned int)Instance - 1;
2676 Limit = Index + 1;
2677 }
2678 else {
2679 Index = 0;
2680 Limit = SKCS_NUM_PROTOCOLS;
2681 }
2682
2683 /*
2684 * Check action
2685 */
2686 if (Action != SK_PNMI_GET) {
2687
2688 *pLen = 0;
2689 return (SK_PNMI_ERR_READ_ONLY);
2690 }
2691
2692 /* Check length */
2693 if (*pLen < (Limit - Index) * sizeof(SK_U64)) {
2694
2695 *pLen = (Limit - Index) * sizeof(SK_U64);
2696 return (SK_PNMI_ERR_TOO_SHORT);
2697 }
2698
2699 /*
2700 * Get value
2701 */
2702 for (; Index < Limit; Index ++) {
2703
2704 switch (Id) {
2705
2706 case OID_SKGE_CHKSM_RX_OK_CTS:
2707 StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxOkCts;
2708 break;
2709
2710 case OID_SKGE_CHKSM_RX_UNABLE_CTS:
2711 StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxUnableCts;
2712 break;
2713
2714 case OID_SKGE_CHKSM_RX_ERR_CTS:
2715 StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxErrCts;
2716 break;
2717
2718 case OID_SKGE_CHKSM_TX_OK_CTS:
2719 StatVal = pAC->Csum.ProtoStats[NetIndex][Index].TxOkCts;
2720 break;
2721
2722 case OID_SKGE_CHKSM_TX_UNABLE_CTS:
2723 StatVal = pAC->Csum.ProtoStats[NetIndex][Index].TxUnableCts;
2724 break;
2725
2726 default:
2727 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR010,
2728 SK_PNMI_ERR010MSG);
2729
2730 *pLen = 0;
2731 return (SK_PNMI_ERR_GENERAL);
2732 }
2733
2734 SK_PNMI_STORE_U64(pBuf + Offset, StatVal);
2735 Offset += sizeof(SK_U64);
2736 }
2737
2738 /*
2739 * Store used buffer space
2740 */
2741 *pLen = Offset;
2742
2743 return (SK_PNMI_ERR_OK);
2744}
2745
2746/*****************************************************************************
2747 *
2748 * SensorStat - OID handler function of OID_SKGE_SENSOR_XXX
2749 *
2750 * Description:
2751 * Retrieves the statistic values of the I2C module, which handles
2752 * the temperature and voltage sensors.
2753 *
2754 * Returns:
2755 * SK_PNMI_ERR_OK The request was successfully performed.
2756 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2757 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2758 * the correct data (e.g. a 32bit value is
2759 * needed, but a 16 bit value was passed).
2760 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2761 * exist (e.g. port instance 3 on a two port
2762 * adapter.
2763 */
2764PNMI_STATIC int SensorStat(
2765SK_AC *pAC, /* Pointer to adapter context */
2766SK_IOC IoC, /* IO context handle */
2767int Action, /* GET/PRESET/SET action */
2768SK_U32 Id, /* Object ID that is to be processed */
2769char *pBuf, /* Buffer used for the management data transfer */
2770unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
2771SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2772unsigned int TableIndex, /* Index to the Id table */
2773SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
2774{
2775 unsigned int i;
2776 unsigned int Index;
2777 unsigned int Limit;
2778 unsigned int Offset;
2779 unsigned int Len;
2780 SK_U32 Val32;
2781 SK_U64 Val64;
2782
2783
2784 /*
2785 * Calculate instance if wished
2786 */
2787 if ((Instance != (SK_U32)(-1))) {
2788
2789 if ((Instance < 1) || (Instance > (SK_U32)pAC->I2c.MaxSens)) {
2790
2791 *pLen = 0;
2792 return (SK_PNMI_ERR_UNKNOWN_INST);
2793 }
2794
2795 Index = (unsigned int)Instance -1;
2796 Limit = (unsigned int)Instance;
2797 }
2798 else {
2799 Index = 0;
2800 Limit = (unsigned int) pAC->I2c.MaxSens;
2801 }
2802
2803 /*
2804 * Check action
2805 */
2806 if (Action != SK_PNMI_GET) {
2807
2808 *pLen = 0;
2809 return (SK_PNMI_ERR_READ_ONLY);
2810 }
2811
2812 /* Check length */
2813 switch (Id) {
2814
2815 case OID_SKGE_SENSOR_VALUE:
2816 case OID_SKGE_SENSOR_WAR_THRES_LOW:
2817 case OID_SKGE_SENSOR_WAR_THRES_UPP:
2818 case OID_SKGE_SENSOR_ERR_THRES_LOW:
2819 case OID_SKGE_SENSOR_ERR_THRES_UPP:
2820 if (*pLen < (Limit - Index) * sizeof(SK_U32)) {
2821
2822 *pLen = (Limit - Index) * sizeof(SK_U32);
2823 return (SK_PNMI_ERR_TOO_SHORT);
2824 }
2825 break;
2826
2827 case OID_SKGE_SENSOR_DESCR:
2828 for (Offset = 0, i = Index; i < Limit; i ++) {
2829
2830 Len = (unsigned int)
2831 SK_STRLEN(pAC->I2c.SenTable[i].SenDesc) + 1;
2832 if (Len >= SK_PNMI_STRINGLEN2) {
2833
2834 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR011,
2835 SK_PNMI_ERR011MSG);
2836
2837 *pLen = 0;
2838 return (SK_PNMI_ERR_GENERAL);
2839 }
2840 Offset += Len;
2841 }
2842 if (*pLen < Offset) {
2843
2844 *pLen = Offset;
2845 return (SK_PNMI_ERR_TOO_SHORT);
2846 }
2847 break;
2848
2849 case OID_SKGE_SENSOR_INDEX:
2850 case OID_SKGE_SENSOR_TYPE:
2851 case OID_SKGE_SENSOR_STATUS:
2852 if (*pLen < Limit - Index) {
2853
2854 *pLen = Limit - Index;
2855 return (SK_PNMI_ERR_TOO_SHORT);
2856 }
2857 break;
2858
2859 case OID_SKGE_SENSOR_WAR_CTS:
2860 case OID_SKGE_SENSOR_WAR_TIME:
2861 case OID_SKGE_SENSOR_ERR_CTS:
2862 case OID_SKGE_SENSOR_ERR_TIME:
2863 if (*pLen < (Limit - Index) * sizeof(SK_U64)) {
2864
2865 *pLen = (Limit - Index) * sizeof(SK_U64);
2866 return (SK_PNMI_ERR_TOO_SHORT);
2867 }
2868 break;
2869
2870 default:
2871 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR012,
2872 SK_PNMI_ERR012MSG);
2873
2874 *pLen = 0;
2875 return (SK_PNMI_ERR_GENERAL);
2876
2877 }
2878
2879 /*
2880 * Get value
2881 */
2882 for (Offset = 0; Index < Limit; Index ++) {
2883
2884 switch (Id) {
2885
2886 case OID_SKGE_SENSOR_INDEX:
2887 *(pBuf + Offset) = (char)Index;
2888 Offset += sizeof(char);
2889 break;
2890
2891 case OID_SKGE_SENSOR_DESCR:
2892 Len = SK_STRLEN(pAC->I2c.SenTable[Index].SenDesc);
2893 SK_MEMCPY(pBuf + Offset + 1,
2894 pAC->I2c.SenTable[Index].SenDesc, Len);
2895 *(pBuf + Offset) = (char)Len;
2896 Offset += Len + 1;
2897 break;
2898
2899 case OID_SKGE_SENSOR_TYPE:
2900 *(pBuf + Offset) =
2901 (char)pAC->I2c.SenTable[Index].SenType;
2902 Offset += sizeof(char);
2903 break;
2904
2905 case OID_SKGE_SENSOR_VALUE:
2906 Val32 = (SK_U32)pAC->I2c.SenTable[Index].SenValue;
2907 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
2908 Offset += sizeof(SK_U32);
2909 break;
2910
2911 case OID_SKGE_SENSOR_WAR_THRES_LOW:
2912 Val32 = (SK_U32)pAC->I2c.SenTable[Index].
2913 SenThreWarnLow;
2914 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
2915 Offset += sizeof(SK_U32);
2916 break;
2917
2918 case OID_SKGE_SENSOR_WAR_THRES_UPP:
2919 Val32 = (SK_U32)pAC->I2c.SenTable[Index].
2920 SenThreWarnHigh;
2921 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
2922 Offset += sizeof(SK_U32);
2923 break;
2924
2925 case OID_SKGE_SENSOR_ERR_THRES_LOW:
2926 Val32 = (SK_U32)pAC->I2c.SenTable[Index].
2927 SenThreErrLow;
2928 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
2929 Offset += sizeof(SK_U32);
2930 break;
2931
2932 case OID_SKGE_SENSOR_ERR_THRES_UPP:
2933 Val32 = pAC->I2c.SenTable[Index].SenThreErrHigh;
2934 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
2935 Offset += sizeof(SK_U32);
2936 break;
2937
2938 case OID_SKGE_SENSOR_STATUS:
2939 *(pBuf + Offset) =
2940 (char)pAC->I2c.SenTable[Index].SenErrFlag;
2941 Offset += sizeof(char);
2942 break;
2943
2944 case OID_SKGE_SENSOR_WAR_CTS:
2945 Val64 = pAC->I2c.SenTable[Index].SenWarnCts;
2946 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
2947 Offset += sizeof(SK_U64);
2948 break;
2949
2950 case OID_SKGE_SENSOR_ERR_CTS:
2951 Val64 = pAC->I2c.SenTable[Index].SenErrCts;
2952 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
2953 Offset += sizeof(SK_U64);
2954 break;
2955
2956 case OID_SKGE_SENSOR_WAR_TIME:
2957 Val64 = SK_PNMI_HUNDREDS_SEC(pAC->I2c.SenTable[Index].
2958 SenBegWarnTS);
2959 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
2960 Offset += sizeof(SK_U64);
2961 break;
2962
2963 case OID_SKGE_SENSOR_ERR_TIME:
2964 Val64 = SK_PNMI_HUNDREDS_SEC(pAC->I2c.SenTable[Index].
2965 SenBegErrTS);
2966 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
2967 Offset += sizeof(SK_U64);
2968 break;
2969
2970 default:
2971 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
2972 ("SensorStat: Unknown OID should be handled before"));
2973
2974 return (SK_PNMI_ERR_GENERAL);
2975 }
2976 }
2977
2978 /*
2979 * Store used buffer space
2980 */
2981 *pLen = Offset;
2982
2983 return (SK_PNMI_ERR_OK);
2984}
2985
2986/*****************************************************************************
2987 *
2988 * Vpd - OID handler function of OID_SKGE_VPD_XXX
2989 *
2990 * Description:
2991 * Get/preset/set of VPD data. As instance the name of a VPD key
2992 * can be passed. The Instance parameter is a SK_U32 and can be
2993 * used as a string buffer for the VPD key, because their maximum
2994 * length is 4 byte.
2995 *
2996 * Returns:
2997 * SK_PNMI_ERR_OK The request was successfully performed.
2998 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2999 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
3000 * the correct data (e.g. a 32bit value is
3001 * needed, but a 16 bit value was passed).
3002 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
3003 * value range.
3004 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
3005 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
3006 * exist (e.g. port instance 3 on a two port
3007 * adapter.
3008 */
3009PNMI_STATIC int Vpd(
3010SK_AC *pAC, /* Pointer to adapter context */
3011SK_IOC IoC, /* IO context handle */
3012int Action, /* GET/PRESET/SET action */
3013SK_U32 Id, /* Object ID that is to be processed */
3014char *pBuf, /* Buffer used for the management data transfer */
3015unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
3016SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
3017unsigned int TableIndex, /* Index to the Id table */
3018SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
3019{
3020 SK_VPD_STATUS *pVpdStatus;
3021 unsigned int BufLen;
3022 char Buf[256];
3023 char KeyArr[SK_PNMI_VPD_ENTRIES][SK_PNMI_VPD_KEY_SIZE];
3024 char KeyStr[SK_PNMI_VPD_KEY_SIZE];
3025 unsigned int KeyNo;
3026 unsigned int Offset;
3027 unsigned int Index;
3028 unsigned int FirstIndex;
3029 unsigned int LastIndex;
3030 unsigned int Len;
3031 int Ret;
3032 SK_U32 Val32;
3033
3034 /*
3035 * Get array of all currently stored VPD keys
3036 */
3037 Ret = GetVpdKeyArr(pAC, IoC, &KeyArr[0][0], sizeof(KeyArr), &KeyNo);
3038 if (Ret != SK_PNMI_ERR_OK) {
3039 *pLen = 0;
3040 return (Ret);
3041 }
3042
3043 /*
3044 * If instance is not -1, try to find the requested VPD key for
3045 * the multiple instance variables. The other OIDs as for example
3046 * OID VPD_ACTION are single instance variables and must be
3047 * handled separatly.
3048 */
3049 FirstIndex = 0;
3050 LastIndex = KeyNo;
3051
3052 if ((Instance != (SK_U32)(-1))) {
3053
3054 if (Id == OID_SKGE_VPD_KEY || Id == OID_SKGE_VPD_VALUE ||
3055 Id == OID_SKGE_VPD_ACCESS) {
3056
3057 SK_STRNCPY(KeyStr, (char *)&Instance, 4);
3058 KeyStr[4] = 0;
3059
3060 for (Index = 0; Index < KeyNo; Index ++) {
3061
3062 if (SK_STRCMP(KeyStr, KeyArr[Index]) == 0) {
3063 FirstIndex = Index;
3064 LastIndex = Index+1;
3065 break;
3066 }
3067 }
3068 if (Index == KeyNo) {
3069
3070 *pLen = 0;
3071 return (SK_PNMI_ERR_UNKNOWN_INST);
3072 }
3073 }
3074 else if (Instance != 1) {
3075
3076 *pLen = 0;
3077 return (SK_PNMI_ERR_UNKNOWN_INST);
3078 }
3079 }
3080
3081 /*
3082 * Get value, if a query should be performed
3083 */
3084 if (Action == SK_PNMI_GET) {
3085
3086 switch (Id) {
3087
3088 case OID_SKGE_VPD_FREE_BYTES:
3089 /* Check length of buffer */
3090 if (*pLen < sizeof(SK_U32)) {
3091
3092 *pLen = sizeof(SK_U32);
3093 return (SK_PNMI_ERR_TOO_SHORT);
3094 }
3095 /* Get number of free bytes */
3096 pVpdStatus = VpdStat(pAC, IoC);
3097 if (pVpdStatus == NULL) {
3098
3099 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR017,
3100 SK_PNMI_ERR017MSG);
3101
3102 *pLen = 0;
3103 return (SK_PNMI_ERR_GENERAL);
3104 }
3105 if ((pVpdStatus->vpd_status & VPD_VALID) == 0) {
3106
3107 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR018,
3108 SK_PNMI_ERR018MSG);
3109
3110 *pLen = 0;
3111 return (SK_PNMI_ERR_GENERAL);
3112 }
3113
3114 Val32 = (SK_U32)pVpdStatus->vpd_free_rw;
3115 SK_PNMI_STORE_U32(pBuf, Val32);
3116 *pLen = sizeof(SK_U32);
3117 break;
3118
3119 case OID_SKGE_VPD_ENTRIES_LIST:
3120 /* Check length */
3121 for (Len = 0, Index = 0; Index < KeyNo; Index ++) {
3122
3123 Len += SK_STRLEN(KeyArr[Index]) + 1;
3124 }
3125 if (*pLen < Len) {
3126
3127 *pLen = Len;
3128 return (SK_PNMI_ERR_TOO_SHORT);
3129 }
3130
3131 /* Get value */
3132 *(pBuf) = (char)Len - 1;
3133 for (Offset = 1, Index = 0; Index < KeyNo; Index ++) {
3134
3135 Len = SK_STRLEN(KeyArr[Index]);
3136 SK_MEMCPY(pBuf + Offset, KeyArr[Index], Len);
3137
3138 Offset += Len;
3139
3140 if (Index < KeyNo - 1) {
3141
3142 *(pBuf + Offset) = ' ';
3143 Offset ++;
3144 }
3145 }
3146 *pLen = Offset;
3147 break;
3148
3149 case OID_SKGE_VPD_ENTRIES_NUMBER:
3150 /* Check length */
3151 if (*pLen < sizeof(SK_U32)) {
3152
3153 *pLen = sizeof(SK_U32);
3154 return (SK_PNMI_ERR_TOO_SHORT);
3155 }
3156
3157 Val32 = (SK_U32)KeyNo;
3158 SK_PNMI_STORE_U32(pBuf, Val32);
3159 *pLen = sizeof(SK_U32);
3160 break;
3161
3162 case OID_SKGE_VPD_KEY:
3163 /* Check buffer length, if it is large enough */
3164 for (Len = 0, Index = FirstIndex;
3165 Index < LastIndex; Index ++) {
3166
3167 Len += SK_STRLEN(KeyArr[Index]) + 1;
3168 }
3169 if (*pLen < Len) {
3170
3171 *pLen = Len;
3172 return (SK_PNMI_ERR_TOO_SHORT);
3173 }
3174
3175 /*
3176 * Get the key to an intermediate buffer, because
3177 * we have to prepend a length byte.
3178 */
3179 for (Offset = 0, Index = FirstIndex;
3180 Index < LastIndex; Index ++) {
3181
3182 Len = SK_STRLEN(KeyArr[Index]);
3183
3184 *(pBuf + Offset) = (char)Len;
3185 SK_MEMCPY(pBuf + Offset + 1, KeyArr[Index],
3186 Len);
3187 Offset += Len + 1;
3188 }
3189 *pLen = Offset;
3190 break;
3191
3192 case OID_SKGE_VPD_VALUE:
3193 /* Check the buffer length if it is large enough */
3194 for (Offset = 0, Index = FirstIndex;
3195 Index < LastIndex; Index ++) {
3196
3197 BufLen = 256;
3198 if (VpdRead(pAC, IoC, KeyArr[Index], Buf,
3199 (int *)&BufLen) > 0 ||
3200 BufLen >= SK_PNMI_VPD_DATALEN) {
3201
3202 SK_ERR_LOG(pAC, SK_ERRCL_SW,
3203 SK_PNMI_ERR021,
3204 SK_PNMI_ERR021MSG);
3205
3206 return (SK_PNMI_ERR_GENERAL);
3207 }
3208 Offset += BufLen + 1;
3209 }
3210 if (*pLen < Offset) {
3211
3212 *pLen = Offset;
3213 return (SK_PNMI_ERR_TOO_SHORT);
3214 }
3215
3216 /*
3217 * Get the value to an intermediate buffer, because
3218 * we have to prepend a length byte.
3219 */
3220 for (Offset = 0, Index = FirstIndex;
3221 Index < LastIndex; Index ++) {
3222
3223 BufLen = 256;
3224 if (VpdRead(pAC, IoC, KeyArr[Index], Buf,
3225 (int *)&BufLen) > 0 ||
3226 BufLen >= SK_PNMI_VPD_DATALEN) {
3227
3228 SK_ERR_LOG(pAC, SK_ERRCL_SW,
3229 SK_PNMI_ERR022,
3230 SK_PNMI_ERR022MSG);
3231
3232 *pLen = 0;
3233 return (SK_PNMI_ERR_GENERAL);
3234 }
3235
3236 *(pBuf + Offset) = (char)BufLen;
3237 SK_MEMCPY(pBuf + Offset + 1, Buf, BufLen);
3238 Offset += BufLen + 1;
3239 }
3240 *pLen = Offset;
3241 break;
3242
3243 case OID_SKGE_VPD_ACCESS:
3244 if (*pLen < LastIndex - FirstIndex) {
3245
3246 *pLen = LastIndex - FirstIndex;
3247 return (SK_PNMI_ERR_TOO_SHORT);
3248 }
3249
3250 for (Offset = 0, Index = FirstIndex;
3251 Index < LastIndex; Index ++) {
3252
3253 if (VpdMayWrite(KeyArr[Index])) {
3254
3255 *(pBuf + Offset) = SK_PNMI_VPD_RW;
3256 }
3257 else {
3258 *(pBuf + Offset) = SK_PNMI_VPD_RO;
3259 }
3260 Offset ++;
3261 }
3262 *pLen = Offset;
3263 break;
3264
3265 case OID_SKGE_VPD_ACTION:
3266 Offset = LastIndex - FirstIndex;
3267 if (*pLen < Offset) {
3268
3269 *pLen = Offset;
3270 return (SK_PNMI_ERR_TOO_SHORT);
3271 }
3272 SK_MEMSET(pBuf, 0, Offset);
3273 *pLen = Offset;
3274 break;
3275
3276 default:
3277 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR023,
3278 SK_PNMI_ERR023MSG);
3279
3280 *pLen = 0;
3281 return (SK_PNMI_ERR_GENERAL);
3282 }
3283 }
3284 else {
3285 /* The only OID which can be set is VPD_ACTION */
3286 if (Id != OID_SKGE_VPD_ACTION) {
3287
3288 if (Id == OID_SKGE_VPD_FREE_BYTES ||
3289 Id == OID_SKGE_VPD_ENTRIES_LIST ||
3290 Id == OID_SKGE_VPD_ENTRIES_NUMBER ||
3291 Id == OID_SKGE_VPD_KEY ||
3292 Id == OID_SKGE_VPD_VALUE ||
3293 Id == OID_SKGE_VPD_ACCESS) {
3294
3295 *pLen = 0;
3296 return (SK_PNMI_ERR_READ_ONLY);
3297 }
3298
3299 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR024,
3300 SK_PNMI_ERR024MSG);
3301
3302 *pLen = 0;
3303 return (SK_PNMI_ERR_GENERAL);
3304 }
3305
3306 /*
3307 * From this point we handle VPD_ACTION. Check the buffer
3308 * length. It should at least have the size of one byte.
3309 */
3310 if (*pLen < 1) {
3311
3312 *pLen = 1;
3313 return (SK_PNMI_ERR_TOO_SHORT);
3314 }
3315
3316 /*
3317 * The first byte contains the VPD action type we should
3318 * perform.
3319 */
3320 switch (*pBuf) {
3321
3322 case SK_PNMI_VPD_IGNORE:
3323 /* Nothing to do */
3324 break;
3325
3326 case SK_PNMI_VPD_CREATE:
3327 /*
3328 * We have to create a new VPD entry or we modify
3329 * an existing one. Check first the buffer length.
3330 */
3331 if (*pLen < 4) {
3332
3333 *pLen = 4;
3334 return (SK_PNMI_ERR_TOO_SHORT);
3335 }
3336 KeyStr[0] = pBuf[1];
3337 KeyStr[1] = pBuf[2];
3338 KeyStr[2] = 0;
3339
3340 /*
3341 * Is the entry writable or does it belong to the
3342 * read-only area?
3343 */
3344 if (!VpdMayWrite(KeyStr)) {
3345
3346 *pLen = 0;
3347 return (SK_PNMI_ERR_BAD_VALUE);
3348 }
3349
3350 Offset = (int)pBuf[3] & 0xFF;
3351
3352 SK_MEMCPY(Buf, pBuf + 4, Offset);
3353 Buf[Offset] = 0;
3354
3355 /* A preset ends here */
3356 if (Action == SK_PNMI_PRESET) {
3357
3358 return (SK_PNMI_ERR_OK);
3359 }
3360
3361 /* Write the new entry or modify an existing one */
3362 Ret = VpdWrite(pAC, IoC, KeyStr, Buf);
3363 if (Ret == SK_PNMI_VPD_NOWRITE ) {
3364
3365 *pLen = 0;
3366 return (SK_PNMI_ERR_BAD_VALUE);
3367 }
3368 else if (Ret != SK_PNMI_VPD_OK) {
3369
3370 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR025,
3371 SK_PNMI_ERR025MSG);
3372
3373 *pLen = 0;
3374 return (SK_PNMI_ERR_GENERAL);
3375 }
3376
3377 /*
3378 * Perform an update of the VPD data. This is
3379 * not mandantory, but just to be sure.
3380 */
3381 Ret = VpdUpdate(pAC, IoC);
3382 if (Ret != SK_PNMI_VPD_OK) {
3383
3384 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR026,
3385 SK_PNMI_ERR026MSG);
3386
3387 *pLen = 0;
3388 return (SK_PNMI_ERR_GENERAL);
3389 }
3390 break;
3391
3392 case SK_PNMI_VPD_DELETE:
3393 /* Check if the buffer size is plausible */
3394 if (*pLen < 3) {
3395
3396 *pLen = 3;
3397 return (SK_PNMI_ERR_TOO_SHORT);
3398 }
3399 if (*pLen > 3) {
3400
3401 *pLen = 0;
3402 return (SK_PNMI_ERR_BAD_VALUE);
3403 }
3404 KeyStr[0] = pBuf[1];
3405 KeyStr[1] = pBuf[2];
3406 KeyStr[2] = 0;
3407
3408 /* Find the passed key in the array */
3409 for (Index = 0; Index < KeyNo; Index ++) {
3410
3411 if (SK_STRCMP(KeyStr, KeyArr[Index]) == 0) {
3412
3413 break;
3414 }
3415 }
3416 /*
3417 * If we cannot find the key it is wrong, so we
3418 * return an appropriate error value.
3419 */
3420 if (Index == KeyNo) {
3421
3422 *pLen = 0;
3423 return (SK_PNMI_ERR_BAD_VALUE);
3424 }
3425
3426 if (Action == SK_PNMI_PRESET) {
3427
3428 return (SK_PNMI_ERR_OK);
3429 }
3430
3431 /* Ok, you wanted it and you will get it */
3432 Ret = VpdDelete(pAC, IoC, KeyStr);
3433 if (Ret != SK_PNMI_VPD_OK) {
3434
3435 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR027,
3436 SK_PNMI_ERR027MSG);
3437
3438 *pLen = 0;
3439 return (SK_PNMI_ERR_GENERAL);
3440 }
3441
3442 /*
3443 * Perform an update of the VPD data. This is
3444 * not mandantory, but just to be sure.
3445 */
3446 Ret = VpdUpdate(pAC, IoC);
3447 if (Ret != SK_PNMI_VPD_OK) {
3448
3449 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR028,
3450 SK_PNMI_ERR028MSG);
3451
3452 *pLen = 0;
3453 return (SK_PNMI_ERR_GENERAL);
3454 }
3455 break;
3456
3457 default:
3458 *pLen = 0;
3459 return (SK_PNMI_ERR_BAD_VALUE);
3460 }
3461 }
3462
3463 return (SK_PNMI_ERR_OK);
3464}
3465
3466/*****************************************************************************
3467 *
3468 * General - OID handler function of various single instance OIDs
3469 *
3470 * Description:
3471 * The code is simple. No description necessary.
3472 *
3473 * Returns:
3474 * SK_PNMI_ERR_OK The request was successfully performed.
3475 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
3476 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
3477 * the correct data (e.g. a 32bit value is
3478 * needed, but a 16 bit value was passed).
3479 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
3480 * exist (e.g. port instance 3 on a two port
3481 * adapter.
3482 */
3483PNMI_STATIC int General(
3484SK_AC *pAC, /* Pointer to adapter context */
3485SK_IOC IoC, /* IO context handle */
3486int Action, /* GET/PRESET/SET action */
3487SK_U32 Id, /* Object ID that is to be processed */
3488char *pBuf, /* Buffer used for the management data transfer */
3489unsigned int *pLen, /* On call: buffer length. On return: used buffer */
3490SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
3491unsigned int TableIndex, /* Index to the Id table */
3492SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
3493{
3494 int Ret;
3495 unsigned int Index;
3496 unsigned int Len;
3497 unsigned int Offset;
3498 unsigned int Val;
3499 SK_U8 Val8;
3500 SK_U16 Val16;
3501 SK_U32 Val32;
3502 SK_U64 Val64;
3503 SK_U64 Val64RxHwErrs = 0;
3504 SK_U64 Val64TxHwErrs = 0;
3505 SK_BOOL Is64BitReq = SK_FALSE;
3506 char Buf[256];
3507 int MacType;
3508
3509 /*
3510 * Check instance. We only handle single instance variables.
3511 */
3512 if (Instance != (SK_U32)(-1) && Instance != 1) {
3513
3514 *pLen = 0;
3515 return (SK_PNMI_ERR_UNKNOWN_INST);
3516 }
3517
3518 /*
3519 * Check action. We only allow get requests.
3520 */
3521 if (Action != SK_PNMI_GET) {
3522
3523 *pLen = 0;
3524 return (SK_PNMI_ERR_READ_ONLY);
3525 }
3526
3527 MacType = pAC->GIni.GIMacType;
3528
3529 /*
3530 * Check length for the various supported OIDs
3531 */
3532 switch (Id) {
3533
3534 case OID_GEN_XMIT_ERROR:
3535 case OID_GEN_RCV_ERROR:
3536 case OID_GEN_RCV_NO_BUFFER:
3537#ifndef SK_NDIS_64BIT_CTR
3538 if (*pLen < sizeof(SK_U32)) {
3539 *pLen = sizeof(SK_U32);
3540 return (SK_PNMI_ERR_TOO_SHORT);
3541 }
3542
3543#else /* SK_NDIS_64BIT_CTR */
3544
3545 /*
3546 * for compatibility, at least 32bit are required for oid
3547 */
3548 if (*pLen < sizeof(SK_U32)) {
3549 /*
3550 * but indicate handling for 64bit values,
3551 * if insufficient space is provided
3552 */
3553 *pLen = sizeof(SK_U64);
3554 return (SK_PNMI_ERR_TOO_SHORT);
3555 }
3556
3557 Is64BitReq = (*pLen < sizeof(SK_U64)) ? SK_FALSE : SK_TRUE;
3558#endif /* SK_NDIS_64BIT_CTR */
3559 break;
3560
3561 case OID_SKGE_PORT_NUMBER:
3562 case OID_SKGE_DEVICE_TYPE:
3563 case OID_SKGE_RESULT:
3564 case OID_SKGE_RLMT_MONITOR_NUMBER:
3565 case OID_GEN_TRANSMIT_QUEUE_LENGTH:
3566 case OID_SKGE_TRAP_NUMBER:
3567 case OID_SKGE_MDB_VERSION:
3568 case OID_SKGE_BOARDLEVEL:
3569 case OID_SKGE_CHIPID:
3570 case OID_SKGE_RAMSIZE:
3571 if (*pLen < sizeof(SK_U32)) {
3572
3573 *pLen = sizeof(SK_U32);
3574 return (SK_PNMI_ERR_TOO_SHORT);
3575 }
3576 break;
3577
3578 case OID_SKGE_CHIPSET:
3579 if (*pLen < sizeof(SK_U16)) {
3580
3581 *pLen = sizeof(SK_U16);
3582 return (SK_PNMI_ERR_TOO_SHORT);
3583 }
3584 break;
3585
3586 case OID_SKGE_BUS_TYPE:
3587 case OID_SKGE_BUS_SPEED:
3588 case OID_SKGE_BUS_WIDTH:
3589 case OID_SKGE_SENSOR_NUMBER:
3590 case OID_SKGE_CHKSM_NUMBER:
3591 case OID_SKGE_VAUXAVAIL:
3592 if (*pLen < sizeof(SK_U8)) {
3593
3594 *pLen = sizeof(SK_U8);
3595 return (SK_PNMI_ERR_TOO_SHORT);
3596 }
3597 break;
3598
3599 case OID_SKGE_TX_SW_QUEUE_LEN:
3600 case OID_SKGE_TX_SW_QUEUE_MAX:
3601 case OID_SKGE_TX_RETRY:
3602 case OID_SKGE_RX_INTR_CTS:
3603 case OID_SKGE_TX_INTR_CTS:
3604 case OID_SKGE_RX_NO_BUF_CTS:
3605 case OID_SKGE_TX_NO_BUF_CTS:
3606 case OID_SKGE_TX_USED_DESCR_NO:
3607 case OID_SKGE_RX_DELIVERED_CTS:
3608 case OID_SKGE_RX_OCTETS_DELIV_CTS:
3609 case OID_SKGE_RX_HW_ERROR_CTS:
3610 case OID_SKGE_TX_HW_ERROR_CTS:
3611 case OID_SKGE_IN_ERRORS_CTS:
3612 case OID_SKGE_OUT_ERROR_CTS:
3613 case OID_SKGE_ERR_RECOVERY_CTS:
3614 case OID_SKGE_SYSUPTIME:
3615 if (*pLen < sizeof(SK_U64)) {
3616
3617 *pLen = sizeof(SK_U64);
3618 return (SK_PNMI_ERR_TOO_SHORT);
3619 }
3620 break;
3621
3622 default:
3623 /* Checked later */
3624 break;
3625 }
3626
3627 /* Update statistic */
3628 if (Id == OID_SKGE_RX_HW_ERROR_CTS ||
3629 Id == OID_SKGE_TX_HW_ERROR_CTS ||
3630 Id == OID_SKGE_IN_ERRORS_CTS ||
3631 Id == OID_SKGE_OUT_ERROR_CTS ||
3632 Id == OID_GEN_XMIT_ERROR ||
3633 Id == OID_GEN_RCV_ERROR) {
3634
3635 /* Force the XMAC to update its statistic counters and
3636 * Increment semaphore to indicate that an update was
3637 * already done.
3638 */
3639 Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
3640 if (Ret != SK_PNMI_ERR_OK) {
3641
3642 *pLen = 0;
3643 return (Ret);
3644 }
3645 pAC->Pnmi.MacUpdatedFlag ++;
3646
3647 /*
3648 * Some OIDs consist of multiple hardware counters. Those
3649 * values which are contained in all of them will be added
3650 * now.
3651 */
3652 switch (Id) {
3653
3654 case OID_SKGE_RX_HW_ERROR_CTS:
3655 case OID_SKGE_IN_ERRORS_CTS:
3656 case OID_GEN_RCV_ERROR:
3657 Val64RxHwErrs =
3658 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_MISSED, NetIndex) +
3659 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_FRAMING, NetIndex) +
3660 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_OVERFLOW, NetIndex) +
3661 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_JABBER, NetIndex) +
3662 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_CARRIER, NetIndex) +
3663 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_IRLENGTH, NetIndex) +
3664 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_SYMBOL, NetIndex) +
3665 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_SHORTS, NetIndex) +
3666 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_RUNT, NetIndex) +
3667 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_TOO_LONG, NetIndex) +
3668 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_FCS, NetIndex) +
3669 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_CEXT, NetIndex);
3670 break;
3671
3672 case OID_SKGE_TX_HW_ERROR_CTS:
3673 case OID_SKGE_OUT_ERROR_CTS:
3674 case OID_GEN_XMIT_ERROR:
3675 Val64TxHwErrs =
3676 GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_EXCESS_COL, NetIndex) +
3677 GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_LATE_COL, NetIndex) +
3678 GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_UNDERRUN, NetIndex) +
3679 GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_CARRIER, NetIndex);
3680 break;
3681 }
3682 }
3683
3684 /*
3685 * Retrieve value
3686 */
3687 switch (Id) {
3688
3689 case OID_SKGE_SUPPORTED_LIST:
3690 Len = ID_TABLE_SIZE * sizeof(SK_U32);
3691 if (*pLen < Len) {
3692
3693 *pLen = Len;
3694 return (SK_PNMI_ERR_TOO_SHORT);
3695 }
3696 for (Offset = 0, Index = 0; Offset < Len;
3697 Offset += sizeof(SK_U32), Index ++) {
3698
3699 Val32 = (SK_U32)IdTable[Index].Id;
3700 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
3701 }
3702 *pLen = Len;
3703 break;
3704
3705 case OID_SKGE_BOARDLEVEL:
3706 Val32 = (SK_U32)pAC->GIni.GILevel;
3707 SK_PNMI_STORE_U32(pBuf, Val32);
3708 *pLen = sizeof(SK_U32);
3709 break;
3710
3711 case OID_SKGE_PORT_NUMBER:
3712 Val32 = (SK_U32)pAC->GIni.GIMacsFound;
3713 SK_PNMI_STORE_U32(pBuf, Val32);
3714 *pLen = sizeof(SK_U32);
3715 break;
3716
3717 case OID_SKGE_DEVICE_TYPE:
3718 Val32 = (SK_U32)pAC->Pnmi.DeviceType;
3719 SK_PNMI_STORE_U32(pBuf, Val32);
3720 *pLen = sizeof(SK_U32);
3721 break;
3722
3723 case OID_SKGE_DRIVER_DESCR:
3724 if (pAC->Pnmi.pDriverDescription == NULL) {
3725
3726 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR007,
3727 SK_PNMI_ERR007MSG);
3728
3729 *pLen = 0;
3730 return (SK_PNMI_ERR_GENERAL);
3731 }
3732
3733 Len = SK_STRLEN(pAC->Pnmi.pDriverDescription) + 1;
3734 if (Len > SK_PNMI_STRINGLEN1) {
3735
3736 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR029,
3737 SK_PNMI_ERR029MSG);
3738
3739 *pLen = 0;
3740 return (SK_PNMI_ERR_GENERAL);
3741 }
3742
3743 if (*pLen < Len) {
3744
3745 *pLen = Len;
3746 return (SK_PNMI_ERR_TOO_SHORT);
3747 }
3748 *pBuf = (char)(Len - 1);
3749 SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverDescription, Len - 1);
3750 *pLen = Len;
3751 break;
3752
3753 case OID_SKGE_DRIVER_VERSION:
3754 if (pAC->Pnmi.pDriverVersion == NULL) {
3755
3756 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030,
3757 SK_PNMI_ERR030MSG);
3758
3759 *pLen = 0;
3760 return (SK_PNMI_ERR_GENERAL);
3761 }
3762
3763 Len = SK_STRLEN(pAC->Pnmi.pDriverVersion) + 1;
3764 if (Len > SK_PNMI_STRINGLEN1) {
3765
3766 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031,
3767 SK_PNMI_ERR031MSG);
3768
3769 *pLen = 0;
3770 return (SK_PNMI_ERR_GENERAL);
3771 }
3772
3773 if (*pLen < Len) {
3774
3775 *pLen = Len;
3776 return (SK_PNMI_ERR_TOO_SHORT);
3777 }
3778 *pBuf = (char)(Len - 1);
3779 SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverVersion, Len - 1);
3780 *pLen = Len;
3781 break;
3782
3783 case OID_SKGE_DRIVER_RELDATE:
3784 if (pAC->Pnmi.pDriverReleaseDate == NULL) {
3785
3786 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030,
3787 SK_PNMI_ERR053MSG);
3788
3789 *pLen = 0;
3790 return (SK_PNMI_ERR_GENERAL);
3791 }
3792
3793 Len = SK_STRLEN(pAC->Pnmi.pDriverReleaseDate) + 1;
3794 if (Len > SK_PNMI_STRINGLEN1) {
3795
3796 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031,
3797 SK_PNMI_ERR054MSG);
3798
3799 *pLen = 0;
3800 return (SK_PNMI_ERR_GENERAL);
3801 }
3802
3803 if (*pLen < Len) {
3804
3805 *pLen = Len;
3806 return (SK_PNMI_ERR_TOO_SHORT);
3807 }
3808 *pBuf = (char)(Len - 1);
3809 SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverReleaseDate, Len - 1);
3810 *pLen = Len;
3811 break;
3812
3813 case OID_SKGE_DRIVER_FILENAME:
3814 if (pAC->Pnmi.pDriverFileName == NULL) {
3815
3816 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030,
3817 SK_PNMI_ERR055MSG);
3818
3819 *pLen = 0;
3820 return (SK_PNMI_ERR_GENERAL);
3821 }
3822
3823 Len = SK_STRLEN(pAC->Pnmi.pDriverFileName) + 1;
3824 if (Len > SK_PNMI_STRINGLEN1) {
3825
3826 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031,
3827 SK_PNMI_ERR056MSG);
3828
3829 *pLen = 0;
3830 return (SK_PNMI_ERR_GENERAL);
3831 }
3832
3833 if (*pLen < Len) {
3834
3835 *pLen = Len;
3836 return (SK_PNMI_ERR_TOO_SHORT);
3837 }
3838 *pBuf = (char)(Len - 1);
3839 SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverFileName, Len - 1);
3840 *pLen = Len;
3841 break;
3842
3843 case OID_SKGE_HW_DESCR:
3844 /*
3845 * The hardware description is located in the VPD. This
3846 * query may move to the initialisation routine. But
3847 * the VPD data is cached and therefore a call here
3848 * will not make much difference.
3849 */
3850 Len = 256;
3851 if (VpdRead(pAC, IoC, VPD_NAME, Buf, (int *)&Len) > 0) {
3852
3853 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR032,
3854 SK_PNMI_ERR032MSG);
3855
3856 *pLen = 0;
3857 return (SK_PNMI_ERR_GENERAL);
3858 }
3859 Len ++;
3860 if (Len > SK_PNMI_STRINGLEN1) {
3861
3862 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR033,
3863 SK_PNMI_ERR033MSG);
3864
3865 *pLen = 0;
3866 return (SK_PNMI_ERR_GENERAL);
3867 }
3868 if (*pLen < Len) {
3869
3870 *pLen = Len;
3871 return (SK_PNMI_ERR_TOO_SHORT);
3872 }
3873 *pBuf = (char)(Len - 1);
3874 SK_MEMCPY(pBuf + 1, Buf, Len - 1);
3875 *pLen = Len;
3876 break;
3877
3878 case OID_SKGE_HW_VERSION:
3879 /* Oh, I love to do some string manipulation */
3880 if (*pLen < 5) {
3881
3882 *pLen = 5;
3883 return (SK_PNMI_ERR_TOO_SHORT);
3884 }
3885 Val8 = (SK_U8)pAC->GIni.GIPciHwRev;
3886 pBuf[0] = 4;
3887 pBuf[1] = 'v';
3888 pBuf[2] = (char)(0x30 | ((Val8 >> 4) & 0x0F));
3889 pBuf[3] = '.';
3890 pBuf[4] = (char)(0x30 | (Val8 & 0x0F));
3891 *pLen = 5;
3892 break;
3893
3894 case OID_SKGE_CHIPSET:
3895 Val16 = pAC->Pnmi.Chipset;
3896 SK_PNMI_STORE_U16(pBuf, Val16);
3897 *pLen = sizeof(SK_U16);
3898 break;
3899
3900 case OID_SKGE_CHIPID:
3901 Val32 = pAC->GIni.GIChipId;
3902 SK_PNMI_STORE_U32(pBuf, Val32);
3903 *pLen = sizeof(SK_U32);
3904 break;
3905
3906 case OID_SKGE_RAMSIZE:
3907 Val32 = pAC->GIni.GIRamSize;
3908 SK_PNMI_STORE_U32(pBuf, Val32);
3909 *pLen = sizeof(SK_U32);
3910 break;
3911
3912 case OID_SKGE_VAUXAVAIL:
3913 *pBuf = (char) pAC->GIni.GIVauxAvail;
3914 *pLen = sizeof(char);
3915 break;
3916
3917 case OID_SKGE_BUS_TYPE:
3918 *pBuf = (char) SK_PNMI_BUS_PCI;
3919 *pLen = sizeof(char);
3920 break;
3921
3922 case OID_SKGE_BUS_SPEED:
3923 *pBuf = pAC->Pnmi.PciBusSpeed;
3924 *pLen = sizeof(char);
3925 break;
3926
3927 case OID_SKGE_BUS_WIDTH:
3928 *pBuf = pAC->Pnmi.PciBusWidth;
3929 *pLen = sizeof(char);
3930 break;
3931
3932 case OID_SKGE_RESULT:
3933 Val32 = pAC->Pnmi.TestResult;
3934 SK_PNMI_STORE_U32(pBuf, Val32);
3935 *pLen = sizeof(SK_U32);
3936 break;
3937
3938 case OID_SKGE_SENSOR_NUMBER:
3939 *pBuf = (char)pAC->I2c.MaxSens;
3940 *pLen = sizeof(char);
3941 break;
3942
3943 case OID_SKGE_CHKSM_NUMBER:
3944 *pBuf = SKCS_NUM_PROTOCOLS;
3945 *pLen = sizeof(char);
3946 break;
3947
3948 case OID_SKGE_TRAP_NUMBER:
3949 GetTrapQueueLen(pAC, &Len, &Val);
3950 Val32 = (SK_U32)Val;
3951 SK_PNMI_STORE_U32(pBuf, Val32);
3952 *pLen = sizeof(SK_U32);
3953 break;
3954
3955 case OID_SKGE_TRAP:
3956 GetTrapQueueLen(pAC, &Len, &Val);
3957 if (*pLen < Len) {
3958
3959 *pLen = Len;
3960 return (SK_PNMI_ERR_TOO_SHORT);
3961 }
3962 CopyTrapQueue(pAC, pBuf);
3963 *pLen = Len;
3964 break;
3965
3966 case OID_SKGE_RLMT_MONITOR_NUMBER:
3967/* XXX Not yet implemented by RLMT therefore we return zero elements */
3968 Val32 = 0;
3969 SK_PNMI_STORE_U32(pBuf, Val32);
3970 *pLen = sizeof(SK_U32);
3971 break;
3972
3973 case OID_SKGE_TX_SW_QUEUE_LEN:
3974 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
3975 if (MacType == SK_MAC_XMAC) {
3976 /* Dual net mode */
3977 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
3978 Val64 = pAC->Pnmi.BufPort[NetIndex].TxSwQueueLen;
3979 }
3980 /* Single net mode */
3981 else {
3982 Val64 = pAC->Pnmi.BufPort[0].TxSwQueueLen +
3983 pAC->Pnmi.BufPort[1].TxSwQueueLen;
3984 }
3985 }
3986 else {
3987 /* Dual net mode */
3988 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
3989 Val64 = pAC->Pnmi.Port[NetIndex].TxSwQueueLen;
3990 }
3991 /* Single net mode */
3992 else {
3993 Val64 = pAC->Pnmi.Port[0].TxSwQueueLen +
3994 pAC->Pnmi.Port[1].TxSwQueueLen;
3995 }
3996 }
3997 SK_PNMI_STORE_U64(pBuf, Val64);
3998 *pLen = sizeof(SK_U64);
3999 break;
4000
4001
4002 case OID_SKGE_TX_SW_QUEUE_MAX:
4003 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4004 if (MacType == SK_MAC_XMAC) {
4005 /* Dual net mode */
4006 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4007 Val64 = pAC->Pnmi.BufPort[NetIndex].TxSwQueueMax;
4008 }
4009 /* Single net mode */
4010 else {
4011 Val64 = pAC->Pnmi.BufPort[0].TxSwQueueMax +
4012 pAC->Pnmi.BufPort[1].TxSwQueueMax;
4013 }
4014 }
4015 else {
4016 /* Dual net mode */
4017 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4018 Val64 = pAC->Pnmi.Port[NetIndex].TxSwQueueMax;
4019 }
4020 /* Single net mode */
4021 else {
4022 Val64 = pAC->Pnmi.Port[0].TxSwQueueMax +
4023 pAC->Pnmi.Port[1].TxSwQueueMax;
4024 }
4025 }
4026 SK_PNMI_STORE_U64(pBuf, Val64);
4027 *pLen = sizeof(SK_U64);
4028 break;
4029
4030 case OID_SKGE_TX_RETRY:
4031 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4032 if (MacType == SK_MAC_XMAC) {
4033 /* Dual net mode */
4034 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4035 Val64 = pAC->Pnmi.BufPort[NetIndex].TxRetryCts;
4036 }
4037 /* Single net mode */
4038 else {
4039 Val64 = pAC->Pnmi.BufPort[0].TxRetryCts +
4040 pAC->Pnmi.BufPort[1].TxRetryCts;
4041 }
4042 }
4043 else {
4044 /* Dual net mode */
4045 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4046 Val64 = pAC->Pnmi.Port[NetIndex].TxRetryCts;
4047 }
4048 /* Single net mode */
4049 else {
4050 Val64 = pAC->Pnmi.Port[0].TxRetryCts +
4051 pAC->Pnmi.Port[1].TxRetryCts;
4052 }
4053 }
4054 SK_PNMI_STORE_U64(pBuf, Val64);
4055 *pLen = sizeof(SK_U64);
4056 break;
4057
4058 case OID_SKGE_RX_INTR_CTS:
4059 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4060 if (MacType == SK_MAC_XMAC) {
4061 /* Dual net mode */
4062 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4063 Val64 = pAC->Pnmi.BufPort[NetIndex].RxIntrCts;
4064 }
4065 /* Single net mode */
4066 else {
4067 Val64 = pAC->Pnmi.BufPort[0].RxIntrCts +
4068 pAC->Pnmi.BufPort[1].RxIntrCts;
4069 }
4070 }
4071 else {
4072 /* Dual net mode */
4073 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4074 Val64 = pAC->Pnmi.Port[NetIndex].RxIntrCts;
4075 }
4076 /* Single net mode */
4077 else {
4078 Val64 = pAC->Pnmi.Port[0].RxIntrCts +
4079 pAC->Pnmi.Port[1].RxIntrCts;
4080 }
4081 }
4082 SK_PNMI_STORE_U64(pBuf, Val64);
4083 *pLen = sizeof(SK_U64);
4084 break;
4085
4086 case OID_SKGE_TX_INTR_CTS:
4087 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4088 if (MacType == SK_MAC_XMAC) {
4089 /* Dual net mode */
4090 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4091 Val64 = pAC->Pnmi.BufPort[NetIndex].TxIntrCts;
4092 }
4093 /* Single net mode */
4094 else {
4095 Val64 = pAC->Pnmi.BufPort[0].TxIntrCts +
4096 pAC->Pnmi.BufPort[1].TxIntrCts;
4097 }
4098 }
4099 else {
4100 /* Dual net mode */
4101 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4102 Val64 = pAC->Pnmi.Port[NetIndex].TxIntrCts;
4103 }
4104 /* Single net mode */
4105 else {
4106 Val64 = pAC->Pnmi.Port[0].TxIntrCts +
4107 pAC->Pnmi.Port[1].TxIntrCts;
4108 }
4109 }
4110 SK_PNMI_STORE_U64(pBuf, Val64);
4111 *pLen = sizeof(SK_U64);
4112 break;
4113
4114 case OID_SKGE_RX_NO_BUF_CTS:
4115 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4116 if (MacType == SK_MAC_XMAC) {
4117 /* Dual net mode */
4118 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4119 Val64 = pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
4120 }
4121 /* Single net mode */
4122 else {
4123 Val64 = pAC->Pnmi.BufPort[0].RxNoBufCts +
4124 pAC->Pnmi.BufPort[1].RxNoBufCts;
4125 }
4126 }
4127 else {
4128 /* Dual net mode */
4129 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4130 Val64 = pAC->Pnmi.Port[NetIndex].RxNoBufCts;
4131 }
4132 /* Single net mode */
4133 else {
4134 Val64 = pAC->Pnmi.Port[0].RxNoBufCts +
4135 pAC->Pnmi.Port[1].RxNoBufCts;
4136 }
4137 }
4138 SK_PNMI_STORE_U64(pBuf, Val64);
4139 *pLen = sizeof(SK_U64);
4140 break;
4141
4142 case OID_SKGE_TX_NO_BUF_CTS:
4143 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4144 if (MacType == SK_MAC_XMAC) {
4145 /* Dual net mode */
4146 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4147 Val64 = pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
4148 }
4149 /* Single net mode */
4150 else {
4151 Val64 = pAC->Pnmi.BufPort[0].TxNoBufCts +
4152 pAC->Pnmi.BufPort[1].TxNoBufCts;
4153 }
4154 }
4155 else {
4156 /* Dual net mode */
4157 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4158 Val64 = pAC->Pnmi.Port[NetIndex].TxNoBufCts;
4159 }
4160 /* Single net mode */
4161 else {
4162 Val64 = pAC->Pnmi.Port[0].TxNoBufCts +
4163 pAC->Pnmi.Port[1].TxNoBufCts;
4164 }
4165 }
4166 SK_PNMI_STORE_U64(pBuf, Val64);
4167 *pLen = sizeof(SK_U64);
4168 break;
4169
4170 case OID_SKGE_TX_USED_DESCR_NO:
4171 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4172 if (MacType == SK_MAC_XMAC) {
4173 /* Dual net mode */
4174 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4175 Val64 = pAC->Pnmi.BufPort[NetIndex].TxUsedDescrNo;
4176 }
4177 /* Single net mode */
4178 else {
4179 Val64 = pAC->Pnmi.BufPort[0].TxUsedDescrNo +
4180 pAC->Pnmi.BufPort[1].TxUsedDescrNo;
4181 }
4182 }
4183 else {
4184 /* Dual net mode */
4185 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4186 Val64 = pAC->Pnmi.Port[NetIndex].TxUsedDescrNo;
4187 }
4188 /* Single net mode */
4189 else {
4190 Val64 = pAC->Pnmi.Port[0].TxUsedDescrNo +
4191 pAC->Pnmi.Port[1].TxUsedDescrNo;
4192 }
4193 }
4194 SK_PNMI_STORE_U64(pBuf, Val64);
4195 *pLen = sizeof(SK_U64);
4196 break;
4197
4198 case OID_SKGE_RX_DELIVERED_CTS:
4199 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4200 if (MacType == SK_MAC_XMAC) {
4201 /* Dual net mode */
4202 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4203 Val64 = pAC->Pnmi.BufPort[NetIndex].RxDeliveredCts;
4204 }
4205 /* Single net mode */
4206 else {
4207 Val64 = pAC->Pnmi.BufPort[0].RxDeliveredCts +
4208 pAC->Pnmi.BufPort[1].RxDeliveredCts;
4209 }
4210 }
4211 else {
4212 /* Dual net mode */
4213 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4214 Val64 = pAC->Pnmi.Port[NetIndex].RxDeliveredCts;
4215 }
4216 /* Single net mode */
4217 else {
4218 Val64 = pAC->Pnmi.Port[0].RxDeliveredCts +
4219 pAC->Pnmi.Port[1].RxDeliveredCts;
4220 }
4221 }
4222 SK_PNMI_STORE_U64(pBuf, Val64);
4223 *pLen = sizeof(SK_U64);
4224 break;
4225
4226 case OID_SKGE_RX_OCTETS_DELIV_CTS:
4227 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4228 if (MacType == SK_MAC_XMAC) {
4229 /* Dual net mode */
4230 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4231 Val64 = pAC->Pnmi.BufPort[NetIndex].RxOctetsDeliveredCts;
4232 }
4233 /* Single net mode */
4234 else {
4235 Val64 = pAC->Pnmi.BufPort[0].RxOctetsDeliveredCts +
4236 pAC->Pnmi.BufPort[1].RxOctetsDeliveredCts;
4237 }
4238 }
4239 else {
4240 /* Dual net mode */
4241 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4242 Val64 = pAC->Pnmi.Port[NetIndex].RxOctetsDeliveredCts;
4243 }
4244 /* Single net mode */
4245 else {
4246 Val64 = pAC->Pnmi.Port[0].RxOctetsDeliveredCts +
4247 pAC->Pnmi.Port[1].RxOctetsDeliveredCts;
4248 }
4249 }
4250 SK_PNMI_STORE_U64(pBuf, Val64);
4251 *pLen = sizeof(SK_U64);
4252 break;
4253
4254 case OID_SKGE_RX_HW_ERROR_CTS:
4255 SK_PNMI_STORE_U64(pBuf, Val64RxHwErrs);
4256 *pLen = sizeof(SK_U64);
4257 break;
4258
4259 case OID_SKGE_TX_HW_ERROR_CTS:
4260 SK_PNMI_STORE_U64(pBuf, Val64TxHwErrs);
4261 *pLen = sizeof(SK_U64);
4262 break;
4263
4264 case OID_SKGE_IN_ERRORS_CTS:
4265 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4266 if (MacType == SK_MAC_XMAC) {
4267 /* Dual net mode */
4268 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4269 Val64 = Val64RxHwErrs + pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
4270 }
4271 /* Single net mode */
4272 else {
4273 Val64 = Val64RxHwErrs +
4274 pAC->Pnmi.BufPort[0].RxNoBufCts +
4275 pAC->Pnmi.BufPort[1].RxNoBufCts;
4276 }
4277 }
4278 else {
4279 /* Dual net mode */
4280 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4281 Val64 = Val64RxHwErrs + pAC->Pnmi.Port[NetIndex].RxNoBufCts;
4282 }
4283 /* Single net mode */
4284 else {
4285 Val64 = Val64RxHwErrs +
4286 pAC->Pnmi.Port[0].RxNoBufCts +
4287 pAC->Pnmi.Port[1].RxNoBufCts;
4288 }
4289 }
4290 SK_PNMI_STORE_U64(pBuf, Val64);
4291 *pLen = sizeof(SK_U64);
4292 break;
4293
4294 case OID_SKGE_OUT_ERROR_CTS:
4295 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4296 if (MacType == SK_MAC_XMAC) {
4297 /* Dual net mode */
4298 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4299 Val64 = Val64TxHwErrs + pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
4300 }
4301 /* Single net mode */
4302 else {
4303 Val64 = Val64TxHwErrs +
4304 pAC->Pnmi.BufPort[0].TxNoBufCts +
4305 pAC->Pnmi.BufPort[1].TxNoBufCts;
4306 }
4307 }
4308 else {
4309 /* Dual net mode */
4310 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4311 Val64 = Val64TxHwErrs + pAC->Pnmi.Port[NetIndex].TxNoBufCts;
4312 }
4313 /* Single net mode */
4314 else {
4315 Val64 = Val64TxHwErrs +
4316 pAC->Pnmi.Port[0].TxNoBufCts +
4317 pAC->Pnmi.Port[1].TxNoBufCts;
4318 }
4319 }
4320 SK_PNMI_STORE_U64(pBuf, Val64);
4321 *pLen = sizeof(SK_U64);
4322 break;
4323
4324 case OID_SKGE_ERR_RECOVERY_CTS:
4325 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4326 if (MacType == SK_MAC_XMAC) {
4327 /* Dual net mode */
4328 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4329 Val64 = pAC->Pnmi.BufPort[NetIndex].ErrRecoveryCts;
4330 }
4331 /* Single net mode */
4332 else {
4333 Val64 = pAC->Pnmi.BufPort[0].ErrRecoveryCts +
4334 pAC->Pnmi.BufPort[1].ErrRecoveryCts;
4335 }
4336 }
4337 else {
4338 /* Dual net mode */
4339 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4340 Val64 = pAC->Pnmi.Port[NetIndex].ErrRecoveryCts;
4341 }
4342 /* Single net mode */
4343 else {
4344 Val64 = pAC->Pnmi.Port[0].ErrRecoveryCts +
4345 pAC->Pnmi.Port[1].ErrRecoveryCts;
4346 }
4347 }
4348 SK_PNMI_STORE_U64(pBuf, Val64);
4349 *pLen = sizeof(SK_U64);
4350 break;
4351
4352 case OID_SKGE_SYSUPTIME:
4353 Val64 = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
4354 Val64 -= pAC->Pnmi.StartUpTime;
4355 SK_PNMI_STORE_U64(pBuf, Val64);
4356 *pLen = sizeof(SK_U64);
4357 break;
4358
4359 case OID_SKGE_MDB_VERSION:
4360 Val32 = SK_PNMI_MDB_VERSION;
4361 SK_PNMI_STORE_U32(pBuf, Val32);
4362 *pLen = sizeof(SK_U32);
4363 break;
4364
4365 case OID_GEN_RCV_ERROR:
4366 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4367 if (MacType == SK_MAC_XMAC) {
4368 Val64 = Val64RxHwErrs + pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
4369 }
4370 else {
4371 Val64 = Val64RxHwErrs + pAC->Pnmi.Port[NetIndex].RxNoBufCts;
4372 }
4373
4374 /*
4375 * by default 32bit values are evaluated
4376 */
4377 if (!Is64BitReq) {
4378 Val32 = (SK_U32)Val64;
4379 SK_PNMI_STORE_U32(pBuf, Val32);
4380 *pLen = sizeof(SK_U32);
4381 }
4382 else {
4383 SK_PNMI_STORE_U64(pBuf, Val64);
4384 *pLen = sizeof(SK_U64);
4385 }
4386 break;
4387
4388 case OID_GEN_XMIT_ERROR:
4389 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4390 if (MacType == SK_MAC_XMAC) {
4391 Val64 = Val64TxHwErrs + pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
4392 }
4393 else {
4394 Val64 = Val64TxHwErrs + pAC->Pnmi.Port[NetIndex].TxNoBufCts;
4395 }
4396
4397 /*
4398 * by default 32bit values are evaluated
4399 */
4400 if (!Is64BitReq) {
4401 Val32 = (SK_U32)Val64;
4402 SK_PNMI_STORE_U32(pBuf, Val32);
4403 *pLen = sizeof(SK_U32);
4404 }
4405 else {
4406 SK_PNMI_STORE_U64(pBuf, Val64);
4407 *pLen = sizeof(SK_U64);
4408 }
4409 break;
4410
4411 case OID_GEN_RCV_NO_BUFFER:
4412 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4413 if (MacType == SK_MAC_XMAC) {
4414 Val64 = pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
4415 }
4416 else {
4417 Val64 = pAC->Pnmi.Port[NetIndex].RxNoBufCts;
4418 }
4419
4420 /*
4421 * by default 32bit values are evaluated
4422 */
4423 if (!Is64BitReq) {
4424 Val32 = (SK_U32)Val64;
4425 SK_PNMI_STORE_U32(pBuf, Val32);
4426 *pLen = sizeof(SK_U32);
4427 }
4428 else {
4429 SK_PNMI_STORE_U64(pBuf, Val64);
4430 *pLen = sizeof(SK_U64);
4431 }
4432 break;
4433
4434 case OID_GEN_TRANSMIT_QUEUE_LENGTH:
4435 Val32 = (SK_U32)pAC->Pnmi.Port[NetIndex].TxSwQueueLen;
4436 SK_PNMI_STORE_U32(pBuf, Val32);
4437 *pLen = sizeof(SK_U32);
4438 break;
4439
4440 default:
4441 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR034,
4442 SK_PNMI_ERR034MSG);
4443
4444 *pLen = 0;
4445 return (SK_PNMI_ERR_GENERAL);
4446 }
4447
4448 if (Id == OID_SKGE_RX_HW_ERROR_CTS ||
4449 Id == OID_SKGE_TX_HW_ERROR_CTS ||
4450 Id == OID_SKGE_IN_ERRORS_CTS ||
4451 Id == OID_SKGE_OUT_ERROR_CTS ||
4452 Id == OID_GEN_XMIT_ERROR ||
4453 Id == OID_GEN_RCV_ERROR) {
4454
4455 pAC->Pnmi.MacUpdatedFlag --;
4456 }
4457
4458 return (SK_PNMI_ERR_OK);
4459}
4460
4461/*****************************************************************************
4462 *
4463 * Rlmt - OID handler function of OID_SKGE_RLMT_XXX single instance.
4464 *
4465 * Description:
4466 * Get/Presets/Sets the RLMT OIDs.
4467 *
4468 * Returns:
4469 * SK_PNMI_ERR_OK The request was successfully performed.
4470 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
4471 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
4472 * the correct data (e.g. a 32bit value is
4473 * needed, but a 16 bit value was passed).
4474 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
4475 * value range.
4476 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
4477 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
4478 * exist (e.g. port instance 3 on a two port
4479 * adapter.
4480 */
4481PNMI_STATIC int Rlmt(
4482SK_AC *pAC, /* Pointer to adapter context */
4483SK_IOC IoC, /* IO context handle */
4484int Action, /* GET/PRESET/SET action */
4485SK_U32 Id, /* Object ID that is to be processed */
4486char *pBuf, /* Buffer used for the management data transfer */
4487unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
4488SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
4489unsigned int TableIndex, /* Index to the Id table */
4490SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
4491{
4492 int Ret;
4493 unsigned int PhysPortIndex;
4494 unsigned int PhysPortMax;
4495 SK_EVPARA EventParam;
4496 SK_U32 Val32;
4497 SK_U64 Val64;
4498
4499
4500 /*
4501 * Check instance. Only single instance OIDs are allowed here.
4502 */
4503 if (Instance != (SK_U32)(-1) && Instance != 1) {
4504
4505 *pLen = 0;
4506 return (SK_PNMI_ERR_UNKNOWN_INST);
4507 }
4508
4509 /*
4510 * Perform the requested action.
4511 */
4512 if (Action == SK_PNMI_GET) {
4513
4514 /*
4515 * Check if the buffer length is large enough.
4516 */
4517
4518 switch (Id) {
4519
4520 case OID_SKGE_RLMT_MODE:
4521 case OID_SKGE_RLMT_PORT_ACTIVE:
4522 case OID_SKGE_RLMT_PORT_PREFERRED:
4523 if (*pLen < sizeof(SK_U8)) {
4524
4525 *pLen = sizeof(SK_U8);
4526 return (SK_PNMI_ERR_TOO_SHORT);
4527 }
4528 break;
4529
4530 case OID_SKGE_RLMT_PORT_NUMBER:
4531 if (*pLen < sizeof(SK_U32)) {
4532
4533 *pLen = sizeof(SK_U32);
4534 return (SK_PNMI_ERR_TOO_SHORT);
4535 }
4536 break;
4537
4538 case OID_SKGE_RLMT_CHANGE_CTS:
4539 case OID_SKGE_RLMT_CHANGE_TIME:
4540 case OID_SKGE_RLMT_CHANGE_ESTIM:
4541 case OID_SKGE_RLMT_CHANGE_THRES:
4542 if (*pLen < sizeof(SK_U64)) {
4543
4544 *pLen = sizeof(SK_U64);
4545 return (SK_PNMI_ERR_TOO_SHORT);
4546 }
4547 break;
4548
4549 default:
4550 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR035,
4551 SK_PNMI_ERR035MSG);
4552
4553 *pLen = 0;
4554 return (SK_PNMI_ERR_GENERAL);
4555 }
4556
4557 /*
4558 * Update RLMT statistic and increment semaphores to indicate
4559 * that an update was already done. Maybe RLMT will hold its
4560 * statistic always up to date some time. Then we can
4561 * remove this type of call.
4562 */
4563 if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
4564
4565 *pLen = 0;
4566 return (Ret);
4567 }
4568 pAC->Pnmi.RlmtUpdatedFlag ++;
4569
4570 /*
4571 * Retrieve Value
4572 */
4573 switch (Id) {
4574
4575 case OID_SKGE_RLMT_MODE:
4576 *pBuf = (char)pAC->Rlmt.Net[0].RlmtMode;
4577 *pLen = sizeof(char);
4578 break;
4579
4580 case OID_SKGE_RLMT_PORT_NUMBER:
4581 Val32 = (SK_U32)pAC->GIni.GIMacsFound;
4582 SK_PNMI_STORE_U32(pBuf, Val32);
4583 *pLen = sizeof(SK_U32);
4584 break;
4585
4586 case OID_SKGE_RLMT_PORT_ACTIVE:
4587 *pBuf = 0;
4588 /*
4589 * If multiple ports may become active this OID
4590 * doesn't make sense any more. A new variable in
4591 * the port structure should be created. However,
4592 * for this variable the first active port is
4593 * returned.
4594 */
4595 PhysPortMax = pAC->GIni.GIMacsFound;
4596
4597 for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
4598 PhysPortIndex ++) {
4599
4600 if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
4601
4602 *pBuf = (char)SK_PNMI_PORT_PHYS2LOG(PhysPortIndex);
4603 break;
4604 }
4605 }
4606 *pLen = sizeof(char);
4607 break;
4608
4609 case OID_SKGE_RLMT_PORT_PREFERRED:
4610 *pBuf = (char)SK_PNMI_PORT_PHYS2LOG(pAC->Rlmt.Net[NetIndex].Preference);
4611 *pLen = sizeof(char);
4612 break;
4613
4614 case OID_SKGE_RLMT_CHANGE_CTS:
4615 Val64 = pAC->Pnmi.RlmtChangeCts;
4616 SK_PNMI_STORE_U64(pBuf, Val64);
4617 *pLen = sizeof(SK_U64);
4618 break;
4619
4620 case OID_SKGE_RLMT_CHANGE_TIME:
4621 Val64 = pAC->Pnmi.RlmtChangeTime;
4622 SK_PNMI_STORE_U64(pBuf, Val64);
4623 *pLen = sizeof(SK_U64);
4624 break;
4625
4626 case OID_SKGE_RLMT_CHANGE_ESTIM:
4627 Val64 = pAC->Pnmi.RlmtChangeEstimate.Estimate;
4628 SK_PNMI_STORE_U64(pBuf, Val64);
4629 *pLen = sizeof(SK_U64);
4630 break;
4631
4632 case OID_SKGE_RLMT_CHANGE_THRES:
4633 Val64 = pAC->Pnmi.RlmtChangeThreshold;
4634 SK_PNMI_STORE_U64(pBuf, Val64);
4635 *pLen = sizeof(SK_U64);
4636 break;
4637
4638 default:
4639 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
4640 ("Rlmt: Unknown OID should be handled before"));
4641
4642 pAC->Pnmi.RlmtUpdatedFlag --;
4643 *pLen = 0;
4644 return (SK_PNMI_ERR_GENERAL);
4645 }
4646
4647 pAC->Pnmi.RlmtUpdatedFlag --;
4648 }
4649 else {
4650 /* Perform a preset or set */
4651 switch (Id) {
4652
4653 case OID_SKGE_RLMT_MODE:
4654 /* Check if the buffer length is plausible */
4655 if (*pLen < sizeof(char)) {
4656
4657 *pLen = sizeof(char);
4658 return (SK_PNMI_ERR_TOO_SHORT);
4659 }
4660 /* Check if the value range is correct */
4661 if (*pLen != sizeof(char) ||
4662 (*pBuf & SK_PNMI_RLMT_MODE_CHK_LINK) == 0 ||
4663 *(SK_U8 *)pBuf > 15) {
4664
4665 *pLen = 0;
4666 return (SK_PNMI_ERR_BAD_VALUE);
4667 }
4668 /* The preset ends here */
4669 if (Action == SK_PNMI_PRESET) {
4670
4671 *pLen = 0;
4672 return (SK_PNMI_ERR_OK);
4673 }
4674 /* Send an event to RLMT to change the mode */
4675 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
4676 EventParam.Para32[0] |= (SK_U32)(*pBuf);
4677 EventParam.Para32[1] = 0;
4678 if (SkRlmtEvent(pAC, IoC, SK_RLMT_MODE_CHANGE,
4679 EventParam) > 0) {
4680
4681 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR037,
4682 SK_PNMI_ERR037MSG);
4683
4684 *pLen = 0;
4685 return (SK_PNMI_ERR_GENERAL);
4686 }
4687 break;
4688
4689 case OID_SKGE_RLMT_PORT_PREFERRED:
4690 /* Check if the buffer length is plausible */
4691 if (*pLen < sizeof(char)) {
4692
4693 *pLen = sizeof(char);
4694 return (SK_PNMI_ERR_TOO_SHORT);
4695 }
4696 /* Check if the value range is correct */
4697 if (*pLen != sizeof(char) || *(SK_U8 *)pBuf >
4698 (SK_U8)pAC->GIni.GIMacsFound) {
4699
4700 *pLen = 0;
4701 return (SK_PNMI_ERR_BAD_VALUE);
4702 }
4703 /* The preset ends here */
4704 if (Action == SK_PNMI_PRESET) {
4705
4706 *pLen = 0;
4707 return (SK_PNMI_ERR_OK);
4708 }
4709
4710 /*
4711 * Send an event to RLMT change the preferred port.
4712 * A param of -1 means automatic mode. RLMT will
4713 * make the decision which is the preferred port.
4714 */
4715 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
4716 EventParam.Para32[0] = (SK_U32)(*pBuf) - 1;
4717 EventParam.Para32[1] = NetIndex;
4718 if (SkRlmtEvent(pAC, IoC, SK_RLMT_PREFPORT_CHANGE,
4719 EventParam) > 0) {
4720
4721 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR038,
4722 SK_PNMI_ERR038MSG);
4723
4724 *pLen = 0;
4725 return (SK_PNMI_ERR_GENERAL);
4726 }
4727 break;
4728
4729 case OID_SKGE_RLMT_CHANGE_THRES:
4730 /* Check if the buffer length is plausible */
4731 if (*pLen < sizeof(SK_U64)) {
4732
4733 *pLen = sizeof(SK_U64);
4734 return (SK_PNMI_ERR_TOO_SHORT);
4735 }
4736 /*
4737 * There are not many restrictions to the
4738 * value range.
4739 */
4740 if (*pLen != sizeof(SK_U64)) {
4741
4742 *pLen = 0;
4743 return (SK_PNMI_ERR_BAD_VALUE);
4744 }
4745 /* A preset ends here */
4746 if (Action == SK_PNMI_PRESET) {
4747
4748 *pLen = 0;
4749 return (SK_PNMI_ERR_OK);
4750 }
4751 /*
4752 * Store the new threshold, which will be taken
4753 * on the next timer event.
4754 */
4755 SK_PNMI_READ_U64(pBuf, Val64);
4756 pAC->Pnmi.RlmtChangeThreshold = Val64;
4757 break;
4758
4759 default:
4760 /* The other OIDs are not be able for set */
4761 *pLen = 0;
4762 return (SK_PNMI_ERR_READ_ONLY);
4763 }
4764 }
4765
4766 return (SK_PNMI_ERR_OK);
4767}
4768
4769/*****************************************************************************
4770 *
4771 * RlmtStat - OID handler function of OID_SKGE_RLMT_XXX multiple instance.
4772 *
4773 * Description:
4774 * Performs get requests on multiple instance variables.
4775 *
4776 * Returns:
4777 * SK_PNMI_ERR_OK The request was successfully performed.
4778 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
4779 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
4780 * the correct data (e.g. a 32bit value is
4781 * needed, but a 16 bit value was passed).
4782 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
4783 * exist (e.g. port instance 3 on a two port
4784 * adapter.
4785 */
4786PNMI_STATIC int RlmtStat(
4787SK_AC *pAC, /* Pointer to adapter context */
4788SK_IOC IoC, /* IO context handle */
4789int Action, /* GET/PRESET/SET action */
4790SK_U32 Id, /* Object ID that is to be processed */
4791char *pBuf, /* Buffer used for the management data transfer */
4792unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
4793SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
4794unsigned int TableIndex, /* Index to the Id table */
4795SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
4796{
4797 unsigned int PhysPortMax;
4798 unsigned int PhysPortIndex;
4799 unsigned int Limit;
4800 unsigned int Offset;
4801 int Ret;
4802 SK_U32 Val32;
4803 SK_U64 Val64;
4804
4805 /*
4806 * Calculate the port indexes from the instance.
4807 */
4808 PhysPortMax = pAC->GIni.GIMacsFound;
4809
4810 if ((Instance != (SK_U32)(-1))) {
4811 /* Check instance range */
4812 if ((Instance < 1) || (Instance > PhysPortMax)) {
4813
4814 *pLen = 0;
4815 return (SK_PNMI_ERR_UNKNOWN_INST);
4816 }
4817
4818 /* Single net mode */
4819 PhysPortIndex = Instance - 1;
4820
4821 /* Dual net mode */
4822 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4823 PhysPortIndex = NetIndex;
4824 }
4825
4826 /* Both net modes */
4827 Limit = PhysPortIndex + 1;
4828 }
4829 else {
4830 /* Single net mode */
4831 PhysPortIndex = 0;
4832 Limit = PhysPortMax;
4833
4834 /* Dual net mode */
4835 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4836 PhysPortIndex = NetIndex;
4837 Limit = PhysPortIndex + 1;
4838 }
4839 }
4840
4841 /*
4842 * Currently only get requests are allowed.
4843 */
4844 if (Action != SK_PNMI_GET) {
4845
4846 *pLen = 0;
4847 return (SK_PNMI_ERR_READ_ONLY);
4848 }
4849
4850 /*
4851 * Check if the buffer length is large enough.
4852 */
4853 switch (Id) {
4854
4855 case OID_SKGE_RLMT_PORT_INDEX:
4856 case OID_SKGE_RLMT_STATUS:
4857 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U32)) {
4858
4859 *pLen = (Limit - PhysPortIndex) * sizeof(SK_U32);
4860 return (SK_PNMI_ERR_TOO_SHORT);
4861 }
4862 break;
4863
4864 case OID_SKGE_RLMT_TX_HELLO_CTS:
4865 case OID_SKGE_RLMT_RX_HELLO_CTS:
4866 case OID_SKGE_RLMT_TX_SP_REQ_CTS:
4867 case OID_SKGE_RLMT_RX_SP_CTS:
4868 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U64)) {
4869
4870 *pLen = (Limit - PhysPortIndex) * sizeof(SK_U64);
4871 return (SK_PNMI_ERR_TOO_SHORT);
4872 }
4873 break;
4874
4875 default:
4876 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR039,
4877 SK_PNMI_ERR039MSG);
4878
4879 *pLen = 0;
4880 return (SK_PNMI_ERR_GENERAL);
4881
4882 }
4883
4884 /*
4885 * Update statistic and increment semaphores to indicate that
4886 * an update was already done.
4887 */
4888 if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
4889
4890 *pLen = 0;
4891 return (Ret);
4892 }
4893 pAC->Pnmi.RlmtUpdatedFlag ++;
4894
4895 /*
4896 * Get value
4897 */
4898 Offset = 0;
4899 for (; PhysPortIndex < Limit; PhysPortIndex ++) {
4900
4901 switch (Id) {
4902
4903 case OID_SKGE_RLMT_PORT_INDEX:
4904 Val32 = PhysPortIndex;
4905 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
4906 Offset += sizeof(SK_U32);
4907 break;
4908
4909 case OID_SKGE_RLMT_STATUS:
4910 if (pAC->Rlmt.Port[PhysPortIndex].PortState ==
4911 SK_RLMT_PS_INIT ||
4912 pAC->Rlmt.Port[PhysPortIndex].PortState ==
4913 SK_RLMT_PS_DOWN) {
4914
4915 Val32 = SK_PNMI_RLMT_STATUS_ERROR;
4916 }
4917 else if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
4918
4919 Val32 = SK_PNMI_RLMT_STATUS_ACTIVE;
4920 }
4921 else {
4922 Val32 = SK_PNMI_RLMT_STATUS_STANDBY;
4923 }
4924 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
4925 Offset += sizeof(SK_U32);
4926 break;
4927
4928 case OID_SKGE_RLMT_TX_HELLO_CTS:
4929 Val64 = pAC->Rlmt.Port[PhysPortIndex].TxHelloCts;
4930 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
4931 Offset += sizeof(SK_U64);
4932 break;
4933
4934 case OID_SKGE_RLMT_RX_HELLO_CTS:
4935 Val64 = pAC->Rlmt.Port[PhysPortIndex].RxHelloCts;
4936 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
4937 Offset += sizeof(SK_U64);
4938 break;
4939
4940 case OID_SKGE_RLMT_TX_SP_REQ_CTS:
4941 Val64 = pAC->Rlmt.Port[PhysPortIndex].TxSpHelloReqCts;
4942 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
4943 Offset += sizeof(SK_U64);
4944 break;
4945
4946 case OID_SKGE_RLMT_RX_SP_CTS:
4947 Val64 = pAC->Rlmt.Port[PhysPortIndex].RxSpHelloCts;
4948 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
4949 Offset += sizeof(SK_U64);
4950 break;
4951
4952 default:
4953 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
4954 ("RlmtStat: Unknown OID should be errored before"));
4955
4956 pAC->Pnmi.RlmtUpdatedFlag --;
4957 *pLen = 0;
4958 return (SK_PNMI_ERR_GENERAL);
4959 }
4960 }
4961 *pLen = Offset;
4962
4963 pAC->Pnmi.RlmtUpdatedFlag --;
4964
4965 return (SK_PNMI_ERR_OK);
4966}
4967
4968/*****************************************************************************
4969 *
4970 * MacPrivateConf - OID handler function of OIDs concerning the configuration
4971 *
4972 * Description:
4973 * Get/Presets/Sets the OIDs concerning the configuration.
4974 *
4975 * Returns:
4976 * SK_PNMI_ERR_OK The request was successfully performed.
4977 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
4978 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
4979 * the correct data (e.g. a 32bit value is
4980 * needed, but a 16 bit value was passed).
4981 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
4982 * value range.
4983 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
4984 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
4985 * exist (e.g. port instance 3 on a two port
4986 * adapter.
4987 */
4988PNMI_STATIC int MacPrivateConf(
4989SK_AC *pAC, /* Pointer to adapter context */
4990SK_IOC IoC, /* IO context handle */
4991int Action, /* GET/PRESET/SET action */
4992SK_U32 Id, /* Object ID that is to be processed */
4993char *pBuf, /* Buffer used for the management data transfer */
4994unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
4995SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
4996unsigned int TableIndex, /* Index to the Id table */
4997SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
4998{
4999 unsigned int PhysPortMax;
5000 unsigned int PhysPortIndex;
5001 unsigned int LogPortMax;
5002 unsigned int LogPortIndex;
5003 unsigned int Limit;
5004 unsigned int Offset;
5005 char Val8;
5006 char *pBufPtr;
5007 int Ret;
5008 SK_EVPARA EventParam;
5009 SK_U32 Val32;
5010
5011 /*
5012 * Calculate instance if wished. MAC index 0 is the virtual MAC.
5013 */
5014 PhysPortMax = pAC->GIni.GIMacsFound;
5015 LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
5016
5017 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
5018 LogPortMax--;
5019 }
5020
5021 if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
5022 /* Check instance range */
5023 if ((Instance < 1) || (Instance > LogPortMax)) {
5024
5025 *pLen = 0;
5026 return (SK_PNMI_ERR_UNKNOWN_INST);
5027 }
5028 LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
5029 Limit = LogPortIndex + 1;
5030 }
5031
5032 else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
5033
5034 LogPortIndex = 0;
5035 Limit = LogPortMax;
5036 }
5037
5038 /*
5039 * Perform action
5040 */
5041 if (Action == SK_PNMI_GET) {
5042
5043 /* Check length */
5044 switch (Id) {
5045
5046 case OID_SKGE_PMD:
5047 case OID_SKGE_CONNECTOR:
5048 case OID_SKGE_LINK_CAP:
5049 case OID_SKGE_LINK_MODE:
5050 case OID_SKGE_LINK_MODE_STATUS:
5051 case OID_SKGE_LINK_STATUS:
5052 case OID_SKGE_FLOWCTRL_CAP:
5053 case OID_SKGE_FLOWCTRL_MODE:
5054 case OID_SKGE_FLOWCTRL_STATUS:
5055 case OID_SKGE_PHY_OPERATION_CAP:
5056 case OID_SKGE_PHY_OPERATION_MODE:
5057 case OID_SKGE_PHY_OPERATION_STATUS:
5058 case OID_SKGE_SPEED_CAP:
5059 case OID_SKGE_SPEED_MODE:
5060 case OID_SKGE_SPEED_STATUS:
5061 if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U8)) {
5062
5063 *pLen = (Limit - LogPortIndex) * sizeof(SK_U8);
5064 return (SK_PNMI_ERR_TOO_SHORT);
5065 }
5066 break;
5067
5068 case OID_SKGE_MTU:
5069 case OID_SKGE_PHY_TYPE:
5070 if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U32)) {
5071
5072 *pLen = (Limit - LogPortIndex) * sizeof(SK_U32);
5073 return (SK_PNMI_ERR_TOO_SHORT);
5074 }
5075 break;
5076
5077 default:
5078 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR041,
5079 SK_PNMI_ERR041MSG);
5080 *pLen = 0;
5081 return (SK_PNMI_ERR_GENERAL);
5082 }
5083
5084 /*
5085 * Update statistic and increment semaphore to indicate
5086 * that an update was already done.
5087 */
5088 if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) {
5089
5090 *pLen = 0;
5091 return (Ret);
5092 }
5093 pAC->Pnmi.SirqUpdatedFlag ++;
5094
5095 /*
5096 * Get value
5097 */
5098 Offset = 0;
5099 for (; LogPortIndex < Limit; LogPortIndex ++) {
5100
5101 pBufPtr = pBuf + Offset;
5102
5103 switch (Id) {
5104
5105 case OID_SKGE_PMD:
5106 *pBufPtr = pAC->Pnmi.PMD;
5107 Offset += sizeof(char);
5108 break;
5109
5110 case OID_SKGE_CONNECTOR:
5111 *pBufPtr = pAC->Pnmi.Connector;
5112 Offset += sizeof(char);
5113 break;
5114
5115 case OID_SKGE_PHY_TYPE:
5116 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5117 if (LogPortIndex == 0) {
5118 continue;
5119 }
5120 else {
5121 /* Get value for physical ports */
5122 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5123 pAC, LogPortIndex);
5124 Val32 = pAC->GIni.GP[PhysPortIndex].PhyType;
5125 SK_PNMI_STORE_U32(pBufPtr, Val32);
5126 }
5127 }
5128 else { /* DualNetMode */
5129
5130 Val32 = pAC->GIni.GP[NetIndex].PhyType;
5131 SK_PNMI_STORE_U32(pBufPtr, Val32);
5132 }
5133 Offset += sizeof(SK_U32);
5134 break;
5135
5136 case OID_SKGE_LINK_CAP:
5137 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5138 if (LogPortIndex == 0) {
5139 /* Get value for virtual port */
5140 VirtualConf(pAC, IoC, Id, pBufPtr);
5141 }
5142 else {
5143 /* Get value for physical ports */
5144 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5145 pAC, LogPortIndex);
5146
5147 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkCap;
5148 }
5149 }
5150 else { /* DualNetMode */
5151
5152 *pBufPtr = pAC->GIni.GP[NetIndex].PLinkCap;
5153 }
5154 Offset += sizeof(char);
5155 break;
5156
5157 case OID_SKGE_LINK_MODE:
5158 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5159 if (LogPortIndex == 0) {
5160 /* Get value for virtual port */
5161 VirtualConf(pAC, IoC, Id, pBufPtr);
5162 }
5163 else {
5164 /* Get value for physical ports */
5165 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5166 pAC, LogPortIndex);
5167
5168 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkModeConf;
5169 }
5170 }
5171 else { /* DualNetMode */
5172
5173 *pBufPtr = pAC->GIni.GP[NetIndex].PLinkModeConf;
5174 }
5175 Offset += sizeof(char);
5176 break;
5177
5178 case OID_SKGE_LINK_MODE_STATUS:
5179 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5180 if (LogPortIndex == 0) {
5181 /* Get value for virtual port */
5182 VirtualConf(pAC, IoC, Id, pBufPtr);
5183 }
5184 else {
5185 /* Get value for physical port */
5186 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5187 pAC, LogPortIndex);
5188
5189 *pBufPtr =
5190 CalculateLinkModeStatus(pAC, IoC, PhysPortIndex);
5191 }
5192 }
5193 else { /* DualNetMode */
5194
5195 *pBufPtr = CalculateLinkModeStatus(pAC, IoC, NetIndex);
5196 }
5197 Offset += sizeof(char);
5198 break;
5199
5200 case OID_SKGE_LINK_STATUS:
5201 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5202 if (LogPortIndex == 0) {
5203 /* Get value for virtual port */
5204 VirtualConf(pAC, IoC, Id, pBufPtr);
5205 }
5206 else {
5207 /* Get value for physical ports */
5208 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5209 pAC, LogPortIndex);
5210
5211 *pBufPtr = CalculateLinkStatus(pAC, IoC, PhysPortIndex);
5212 }
5213 }
5214 else { /* DualNetMode */
5215
5216 *pBufPtr = CalculateLinkStatus(pAC, IoC, NetIndex);
5217 }
5218 Offset += sizeof(char);
5219 break;
5220
5221 case OID_SKGE_FLOWCTRL_CAP:
5222 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5223 if (LogPortIndex == 0) {
5224 /* Get value for virtual port */
5225 VirtualConf(pAC, IoC, Id, pBufPtr);
5226 }
5227 else {
5228 /* Get value for physical ports */
5229 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5230 pAC, LogPortIndex);
5231
5232 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PFlowCtrlCap;
5233 }
5234 }
5235 else { /* DualNetMode */
5236
5237 *pBufPtr = pAC->GIni.GP[NetIndex].PFlowCtrlCap;
5238 }
5239 Offset += sizeof(char);
5240 break;
5241
5242 case OID_SKGE_FLOWCTRL_MODE:
5243 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5244 if (LogPortIndex == 0) {
5245 /* Get value for virtual port */
5246 VirtualConf(pAC, IoC, Id, pBufPtr);
5247 }
5248 else {
5249 /* Get value for physical port */
5250 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5251 pAC, LogPortIndex);
5252
5253 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PFlowCtrlMode;
5254 }
5255 }
5256 else { /* DualNetMode */
5257
5258 *pBufPtr = pAC->GIni.GP[NetIndex].PFlowCtrlMode;
5259 }
5260 Offset += sizeof(char);
5261 break;
5262
5263 case OID_SKGE_FLOWCTRL_STATUS:
5264 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5265 if (LogPortIndex == 0) {
5266 /* Get value for virtual port */
5267 VirtualConf(pAC, IoC, Id, pBufPtr);
5268 }
5269 else {
5270 /* Get value for physical port */
5271 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5272 pAC, LogPortIndex);
5273
5274 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PFlowCtrlStatus;
5275 }
5276 }
5277 else { /* DualNetMode */
5278
5279 *pBufPtr = pAC->GIni.GP[NetIndex].PFlowCtrlStatus;
5280 }
5281 Offset += sizeof(char);
5282 break;
5283
5284 case OID_SKGE_PHY_OPERATION_CAP:
5285 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5286 if (LogPortIndex == 0) {
5287 /* Get value for virtual port */
5288 VirtualConf(pAC, IoC, Id, pBufPtr);
5289 }
5290 else {
5291 /* Get value for physical ports */
5292 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5293 pAC, LogPortIndex);
5294
5295 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PMSCap;
5296 }
5297 }
5298 else { /* DualNetMode */
5299
5300 *pBufPtr = pAC->GIni.GP[NetIndex].PMSCap;
5301 }
5302 Offset += sizeof(char);
5303 break;
5304
5305 case OID_SKGE_PHY_OPERATION_MODE:
5306 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5307 if (LogPortIndex == 0) {
5308 /* Get value for virtual port */
5309 VirtualConf(pAC, IoC, Id, pBufPtr);
5310 }
5311 else {
5312 /* Get value for physical port */
5313 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5314 pAC, LogPortIndex);
5315
5316 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PMSMode;
5317 }
5318 }
5319 else { /* DualNetMode */
5320
5321 *pBufPtr = pAC->GIni.GP[NetIndex].PMSMode;
5322 }
5323 Offset += sizeof(char);
5324 break;
5325
5326 case OID_SKGE_PHY_OPERATION_STATUS:
5327 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5328 if (LogPortIndex == 0) {
5329 /* Get value for virtual port */
5330 VirtualConf(pAC, IoC, Id, pBufPtr);
5331 }
5332 else {
5333 /* Get value for physical port */
5334 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5335 pAC, LogPortIndex);
5336
5337 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PMSStatus;
5338 }
5339 }
5340 else {
5341
5342 *pBufPtr = pAC->GIni.GP[NetIndex].PMSStatus;
5343 }
5344 Offset += sizeof(char);
5345 break;
5346
5347 case OID_SKGE_SPEED_CAP:
5348 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5349 if (LogPortIndex == 0) {
5350 /* Get value for virtual port */
5351 VirtualConf(pAC, IoC, Id, pBufPtr);
5352 }
5353 else {
5354 /* Get value for physical ports */
5355 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5356 pAC, LogPortIndex);
5357
5358 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkSpeedCap;
5359 }
5360 }
5361 else { /* DualNetMode */
5362
5363 *pBufPtr = pAC->GIni.GP[NetIndex].PLinkSpeedCap;
5364 }
5365 Offset += sizeof(char);
5366 break;
5367
5368 case OID_SKGE_SPEED_MODE:
5369 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5370 if (LogPortIndex == 0) {
5371 /* Get value for virtual port */
5372 VirtualConf(pAC, IoC, Id, pBufPtr);
5373 }
5374 else {
5375 /* Get value for physical port */
5376 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5377 pAC, LogPortIndex);
5378
5379 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkSpeed;
5380 }
5381 }
5382 else { /* DualNetMode */
5383
5384 *pBufPtr = pAC->GIni.GP[NetIndex].PLinkSpeed;
5385 }
5386 Offset += sizeof(char);
5387 break;
5388
5389 case OID_SKGE_SPEED_STATUS:
5390 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5391 if (LogPortIndex == 0) {
5392 /* Get value for virtual port */
5393 VirtualConf(pAC, IoC, Id, pBufPtr);
5394 }
5395 else {
5396 /* Get value for physical port */
5397 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5398 pAC, LogPortIndex);
5399
5400 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed;
5401 }
5402 }
5403 else { /* DualNetMode */
5404
5405 *pBufPtr = pAC->GIni.GP[NetIndex].PLinkSpeedUsed;
5406 }
5407 Offset += sizeof(char);
5408 break;
5409
5410 case OID_SKGE_MTU:
5411 Val32 = SK_DRIVER_GET_MTU(pAC, IoC, NetIndex);
5412 SK_PNMI_STORE_U32(pBufPtr, Val32);
5413 Offset += sizeof(SK_U32);
5414 break;
5415
5416 default:
5417 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
5418 ("MacPrivateConf: Unknown OID should be handled before"));
5419
5420 pAC->Pnmi.SirqUpdatedFlag --;
5421 return (SK_PNMI_ERR_GENERAL);
5422 }
5423 }
5424 *pLen = Offset;
5425 pAC->Pnmi.SirqUpdatedFlag --;
5426
5427 return (SK_PNMI_ERR_OK);
5428 }
5429
5430 /*
5431 * From here SET or PRESET action. Check if the passed
5432 * buffer length is plausible.
5433 */
5434 switch (Id) {
5435
5436 case OID_SKGE_LINK_MODE:
5437 case OID_SKGE_FLOWCTRL_MODE:
5438 case OID_SKGE_PHY_OPERATION_MODE:
5439 case OID_SKGE_SPEED_MODE:
5440 if (*pLen < Limit - LogPortIndex) {
5441
5442 *pLen = Limit - LogPortIndex;
5443 return (SK_PNMI_ERR_TOO_SHORT);
5444 }
5445 if (*pLen != Limit - LogPortIndex) {
5446
5447 *pLen = 0;
5448 return (SK_PNMI_ERR_BAD_VALUE);
5449 }
5450 break;
5451
5452 case OID_SKGE_MTU:
5453 if (*pLen < sizeof(SK_U32)) {
5454
5455 *pLen = sizeof(SK_U32);
5456 return (SK_PNMI_ERR_TOO_SHORT);
5457 }
5458 if (*pLen != sizeof(SK_U32)) {
5459
5460 *pLen = 0;
5461 return (SK_PNMI_ERR_BAD_VALUE);
5462 }
5463 break;
5464
5465 default:
5466 *pLen = 0;
5467 return (SK_PNMI_ERR_READ_ONLY);
5468 }
5469
5470 /*
5471 * Perform preset or set
5472 */
5473 Offset = 0;
5474 for (; LogPortIndex < Limit; LogPortIndex ++) {
5475
5476 switch (Id) {
5477
5478 case OID_SKGE_LINK_MODE:
5479 /* Check the value range */
5480 Val8 = *(pBuf + Offset);
5481 if (Val8 == 0) {
5482
5483 Offset += sizeof(char);
5484 break;
5485 }
5486 if (Val8 < SK_LMODE_HALF ||
5487 (LogPortIndex != 0 && Val8 > SK_LMODE_AUTOSENSE) ||
5488 (LogPortIndex == 0 && Val8 > SK_LMODE_INDETERMINATED)) {
5489
5490 *pLen = 0;
5491 return (SK_PNMI_ERR_BAD_VALUE);
5492 }
5493
5494 /* The preset ends here */
5495 if (Action == SK_PNMI_PRESET) {
5496
5497 return (SK_PNMI_ERR_OK);
5498 }
5499
5500 if (LogPortIndex == 0) {
5501
5502 /*
5503 * The virtual port consists of all currently
5504 * active ports. Find them and send an event
5505 * with the new link mode to SIRQ.
5506 */
5507 for (PhysPortIndex = 0;
5508 PhysPortIndex < PhysPortMax;
5509 PhysPortIndex ++) {
5510
5511 if (!pAC->Pnmi.Port[PhysPortIndex].
5512 ActiveFlag) {
5513
5514 continue;
5515 }
5516
5517 EventParam.Para32[0] = PhysPortIndex;
5518 EventParam.Para32[1] = (SK_U32)Val8;
5519 if (SkGeSirqEvent(pAC, IoC,
5520 SK_HWEV_SET_LMODE,
5521 EventParam) > 0) {
5522
5523 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5524 SK_PNMI_ERR043,
5525 SK_PNMI_ERR043MSG);
5526
5527 *pLen = 0;
5528 return (SK_PNMI_ERR_GENERAL);
5529 }
5530 }
5531 }
5532 else {
5533 /*
5534 * Send an event with the new link mode to
5535 * the SIRQ module.
5536 */
5537 EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
5538 pAC, LogPortIndex);
5539 EventParam.Para32[1] = (SK_U32)Val8;
5540 if (SkGeSirqEvent(pAC, IoC, SK_HWEV_SET_LMODE,
5541 EventParam) > 0) {
5542
5543 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5544 SK_PNMI_ERR043,
5545 SK_PNMI_ERR043MSG);
5546
5547 *pLen = 0;
5548 return (SK_PNMI_ERR_GENERAL);
5549 }
5550 }
5551 Offset += sizeof(char);
5552 break;
5553
5554 case OID_SKGE_FLOWCTRL_MODE:
5555 /* Check the value range */
5556 Val8 = *(pBuf + Offset);
5557 if (Val8 == 0) {
5558
5559 Offset += sizeof(char);
5560 break;
5561 }
5562 if (Val8 < SK_FLOW_MODE_NONE ||
5563 (LogPortIndex != 0 && Val8 > SK_FLOW_MODE_SYM_OR_REM) ||
5564 (LogPortIndex == 0 && Val8 > SK_FLOW_MODE_INDETERMINATED)) {
5565
5566 *pLen = 0;
5567 return (SK_PNMI_ERR_BAD_VALUE);
5568 }
5569
5570 /* The preset ends here */
5571 if (Action == SK_PNMI_PRESET) {
5572
5573 return (SK_PNMI_ERR_OK);
5574 }
5575
5576 if (LogPortIndex == 0) {
5577
5578 /*
5579 * The virtual port consists of all currently
5580 * active ports. Find them and send an event
5581 * with the new flow control mode to SIRQ.
5582 */
5583 for (PhysPortIndex = 0;
5584 PhysPortIndex < PhysPortMax;
5585 PhysPortIndex ++) {
5586
5587 if (!pAC->Pnmi.Port[PhysPortIndex].
5588 ActiveFlag) {
5589
5590 continue;
5591 }
5592
5593 EventParam.Para32[0] = PhysPortIndex;
5594 EventParam.Para32[1] = (SK_U32)Val8;
5595 if (SkGeSirqEvent(pAC, IoC,
5596 SK_HWEV_SET_FLOWMODE,
5597 EventParam) > 0) {
5598
5599 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5600 SK_PNMI_ERR044,
5601 SK_PNMI_ERR044MSG);
5602
5603 *pLen = 0;
5604 return (SK_PNMI_ERR_GENERAL);
5605 }
5606 }
5607 }
5608 else {
5609 /*
5610 * Send an event with the new flow control
5611 * mode to the SIRQ module.
5612 */
5613 EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
5614 pAC, LogPortIndex);
5615 EventParam.Para32[1] = (SK_U32)Val8;
5616 if (SkGeSirqEvent(pAC, IoC,
5617 SK_HWEV_SET_FLOWMODE, EventParam)
5618 > 0) {
5619
5620 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5621 SK_PNMI_ERR044,
5622 SK_PNMI_ERR044MSG);
5623
5624 *pLen = 0;
5625 return (SK_PNMI_ERR_GENERAL);
5626 }
5627 }
5628 Offset += sizeof(char);
5629 break;
5630
5631 case OID_SKGE_PHY_OPERATION_MODE :
5632 /* Check the value range */
5633 Val8 = *(pBuf + Offset);
5634 if (Val8 == 0) {
5635 /* mode of this port remains unchanged */
5636 Offset += sizeof(char);
5637 break;
5638 }
5639 if (Val8 < SK_MS_MODE_AUTO ||
5640 (LogPortIndex != 0 && Val8 > SK_MS_MODE_SLAVE) ||
5641 (LogPortIndex == 0 && Val8 > SK_MS_MODE_INDETERMINATED)) {
5642
5643 *pLen = 0;
5644 return (SK_PNMI_ERR_BAD_VALUE);
5645 }
5646
5647 /* The preset ends here */
5648 if (Action == SK_PNMI_PRESET) {
5649
5650 return (SK_PNMI_ERR_OK);
5651 }
5652
5653 if (LogPortIndex == 0) {
5654
5655 /*
5656 * The virtual port consists of all currently
5657 * active ports. Find them and send an event
5658 * with new master/slave (role) mode to SIRQ.
5659 */
5660 for (PhysPortIndex = 0;
5661 PhysPortIndex < PhysPortMax;
5662 PhysPortIndex ++) {
5663
5664 if (!pAC->Pnmi.Port[PhysPortIndex].
5665 ActiveFlag) {
5666
5667 continue;
5668 }
5669
5670 EventParam.Para32[0] = PhysPortIndex;
5671 EventParam.Para32[1] = (SK_U32)Val8;
5672 if (SkGeSirqEvent(pAC, IoC,
5673 SK_HWEV_SET_ROLE,
5674 EventParam) > 0) {
5675
5676 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5677 SK_PNMI_ERR042,
5678 SK_PNMI_ERR042MSG);
5679
5680 *pLen = 0;
5681 return (SK_PNMI_ERR_GENERAL);
5682 }
5683 }
5684 }
5685 else {
5686 /*
5687 * Send an event with the new master/slave
5688 * (role) mode to the SIRQ module.
5689 */
5690 EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
5691 pAC, LogPortIndex);
5692 EventParam.Para32[1] = (SK_U32)Val8;
5693 if (SkGeSirqEvent(pAC, IoC,
5694 SK_HWEV_SET_ROLE, EventParam) > 0) {
5695
5696 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5697 SK_PNMI_ERR042,
5698 SK_PNMI_ERR042MSG);
5699
5700 *pLen = 0;
5701 return (SK_PNMI_ERR_GENERAL);
5702 }
5703 }
5704
5705 Offset += sizeof(char);
5706 break;
5707
5708 case OID_SKGE_SPEED_MODE:
5709 /* Check the value range */
5710 Val8 = *(pBuf + Offset);
5711 if (Val8 == 0) {
5712
5713 Offset += sizeof(char);
5714 break;
5715 }
5716 if (Val8 < (SK_LSPEED_AUTO) ||
5717 (LogPortIndex != 0 && Val8 > (SK_LSPEED_1000MBPS)) ||
5718 (LogPortIndex == 0 && Val8 > (SK_LSPEED_INDETERMINATED))) {
5719
5720 *pLen = 0;
5721 return (SK_PNMI_ERR_BAD_VALUE);
5722 }
5723
5724 /* The preset ends here */
5725 if (Action == SK_PNMI_PRESET) {
5726
5727 return (SK_PNMI_ERR_OK);
5728 }
5729
5730 if (LogPortIndex == 0) {
5731
5732 /*
5733 * The virtual port consists of all currently
5734 * active ports. Find them and send an event
5735 * with the new flow control mode to SIRQ.
5736 */
5737 for (PhysPortIndex = 0;
5738 PhysPortIndex < PhysPortMax;
5739 PhysPortIndex ++) {
5740
5741 if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
5742
5743 continue;
5744 }
5745
5746 EventParam.Para32[0] = PhysPortIndex;
5747 EventParam.Para32[1] = (SK_U32)Val8;
5748 if (SkGeSirqEvent(pAC, IoC,
5749 SK_HWEV_SET_SPEED,
5750 EventParam) > 0) {
5751
5752 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5753 SK_PNMI_ERR045,
5754 SK_PNMI_ERR045MSG);
5755
5756 *pLen = 0;
5757 return (SK_PNMI_ERR_GENERAL);
5758 }
5759 }
5760 }
5761 else {
5762 /*
5763 * Send an event with the new flow control
5764 * mode to the SIRQ module.
5765 */
5766 EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
5767 pAC, LogPortIndex);
5768 EventParam.Para32[1] = (SK_U32)Val8;
5769 if (SkGeSirqEvent(pAC, IoC,
5770 SK_HWEV_SET_SPEED,
5771 EventParam) > 0) {
5772
5773 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5774 SK_PNMI_ERR045,
5775 SK_PNMI_ERR045MSG);
5776
5777 *pLen = 0;
5778 return (SK_PNMI_ERR_GENERAL);
5779 }
5780 }
5781 Offset += sizeof(char);
5782 break;
5783
5784 case OID_SKGE_MTU :
5785 /* Check the value range */
5786 Val32 = *(SK_U32*)(pBuf + Offset);
5787 if (Val32 == 0) {
5788 /* mtu of this port remains unchanged */
5789 Offset += sizeof(SK_U32);
5790 break;
5791 }
5792 if (SK_DRIVER_PRESET_MTU(pAC, IoC, NetIndex, Val32) != 0) {
5793 *pLen = 0;
5794 return (SK_PNMI_ERR_BAD_VALUE);
5795 }
5796
5797 /* The preset ends here */
5798 if (Action == SK_PNMI_PRESET) {
5799 return (SK_PNMI_ERR_OK);
5800 }
5801
5802 if (SK_DRIVER_SET_MTU(pAC, IoC, NetIndex, Val32) != 0) {
5803 return (SK_PNMI_ERR_GENERAL);
5804 }
5805
5806 Offset += sizeof(SK_U32);
5807 break;
5808
5809 default:
5810 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
5811 ("MacPrivateConf: Unknown OID should be handled before set"));
5812
5813 *pLen = 0;
5814 return (SK_PNMI_ERR_GENERAL);
5815 }
5816 }
5817
5818 return (SK_PNMI_ERR_OK);
5819}
5820
5821/*****************************************************************************
5822 *
5823 * Monitor - OID handler function for RLMT_MONITOR_XXX
5824 *
5825 * Description:
5826 * Because RLMT currently does not support the monitoring of
5827 * remote adapter cards, we return always an empty table.
5828 *
5829 * Returns:
5830 * SK_PNMI_ERR_OK The request was successfully performed.
5831 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
5832 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
5833 * the correct data (e.g. a 32bit value is
5834 * needed, but a 16 bit value was passed).
5835 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
5836 * value range.
5837 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
5838 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
5839 * exist (e.g. port instance 3 on a two port
5840 * adapter.
5841 */
5842PNMI_STATIC int Monitor(
5843SK_AC *pAC, /* Pointer to adapter context */
5844SK_IOC IoC, /* IO context handle */
5845int Action, /* GET/PRESET/SET action */
5846SK_U32 Id, /* Object ID that is to be processed */
5847char *pBuf, /* Buffer used for the management data transfer */
5848unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
5849SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
5850unsigned int TableIndex, /* Index to the Id table */
5851SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
5852{
5853 unsigned int Index;
5854 unsigned int Limit;
5855 unsigned int Offset;
5856 unsigned int Entries;
5857
5858
5859 /*
5860 * Calculate instance if wished.
5861 */
5862 /* XXX Not yet implemented. Return always an empty table. */
5863 Entries = 0;
5864
5865 if ((Instance != (SK_U32)(-1))) {
5866
5867 if ((Instance < 1) || (Instance > Entries)) {
5868
5869 *pLen = 0;
5870 return (SK_PNMI_ERR_UNKNOWN_INST);
5871 }
5872
5873 Index = (unsigned int)Instance - 1;
5874 Limit = (unsigned int)Instance;
5875 }
5876 else {
5877 Index = 0;
5878 Limit = Entries;
5879 }
5880
5881 /*
5882 * Get/Set value
5883 */
5884 if (Action == SK_PNMI_GET) {
5885
5886 for (Offset=0; Index < Limit; Index ++) {
5887
5888 switch (Id) {
5889
5890 case OID_SKGE_RLMT_MONITOR_INDEX:
5891 case OID_SKGE_RLMT_MONITOR_ADDR:
5892 case OID_SKGE_RLMT_MONITOR_ERRS:
5893 case OID_SKGE_RLMT_MONITOR_TIMESTAMP:
5894 case OID_SKGE_RLMT_MONITOR_ADMIN:
5895 break;
5896
5897 default:
5898 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR046,
5899 SK_PNMI_ERR046MSG);
5900
5901 *pLen = 0;
5902 return (SK_PNMI_ERR_GENERAL);
5903 }
5904 }
5905 *pLen = Offset;
5906 }
5907 else {
5908 /* Only MONITOR_ADMIN can be set */
5909 if (Id != OID_SKGE_RLMT_MONITOR_ADMIN) {
5910
5911 *pLen = 0;
5912 return (SK_PNMI_ERR_READ_ONLY);
5913 }
5914
5915 /* Check if the length is plausible */
5916 if (*pLen < (Limit - Index)) {
5917
5918 return (SK_PNMI_ERR_TOO_SHORT);
5919 }
5920 /* Okay, we have a wide value range */
5921 if (*pLen != (Limit - Index)) {
5922
5923 *pLen = 0;
5924 return (SK_PNMI_ERR_BAD_VALUE);
5925 }
5926/*
5927 for (Offset=0; Index < Limit; Index ++) {
5928 }
5929*/
5930/*
5931 * XXX Not yet implemented. Return always BAD_VALUE, because the table
5932 * is empty.
5933 */
5934 *pLen = 0;
5935 return (SK_PNMI_ERR_BAD_VALUE);
5936 }
5937
5938 return (SK_PNMI_ERR_OK);
5939}
5940
5941/*****************************************************************************
5942 *
5943 * VirtualConf - Calculates the values of configuration OIDs for virtual port
5944 *
5945 * Description:
5946 * We handle here the get of the configuration group OIDs, which are
5947 * a little bit complicated. The virtual port consists of all currently
5948 * active physical ports. If multiple ports are active and configured
5949 * differently we get in some trouble to return a single value. So we
5950 * get the value of the first active port and compare it with that of
5951 * the other active ports. If they are not the same, we return a value
5952 * that indicates that the state is indeterminated.
5953 *
5954 * Returns:
5955 * Nothing
5956 */
5957PNMI_STATIC void VirtualConf(
5958SK_AC *pAC, /* Pointer to adapter context */
5959SK_IOC IoC, /* IO context handle */
5960SK_U32 Id, /* Object ID that is to be processed */
5961char *pBuf) /* Buffer used for the management data transfer */
5962{
5963 unsigned int PhysPortMax;
5964 unsigned int PhysPortIndex;
5965 SK_U8 Val8;
5966 SK_U32 Val32;
5967 SK_BOOL PortActiveFlag;
5968 SK_GEPORT *pPrt;
5969
5970 *pBuf = 0;
5971 PortActiveFlag = SK_FALSE;
5972 PhysPortMax = pAC->GIni.GIMacsFound;
5973
5974 for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
5975 PhysPortIndex ++) {
5976
5977 pPrt = &pAC->GIni.GP[PhysPortIndex];
5978
5979 /* Check if the physical port is active */
5980 if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
5981
5982 continue;
5983 }
5984
5985 PortActiveFlag = SK_TRUE;
5986
5987 switch (Id) {
5988
5989 case OID_SKGE_PHY_TYPE:
5990 /* Check if it is the first active port */
5991 if (*pBuf == 0) {
5992 Val32 = pPrt->PhyType;
5993 SK_PNMI_STORE_U32(pBuf, Val32);
5994 continue;
5995 }
5996
5997 case OID_SKGE_LINK_CAP:
5998
5999 /*
6000 * Different capabilities should not happen, but
6001 * in the case of the cases OR them all together.
6002 * From a curious point of view the virtual port
6003 * is capable of all found capabilities.
6004 */
6005 *pBuf |= pPrt->PLinkCap;
6006 break;
6007
6008 case OID_SKGE_LINK_MODE:
6009 /* Check if it is the first active port */
6010 if (*pBuf == 0) {
6011
6012 *pBuf = pPrt->PLinkModeConf;
6013 continue;
6014 }
6015
6016 /*
6017 * If we find an active port with a different link
6018 * mode than the first one we return a value that
6019 * indicates that the link mode is indeterminated.
6020 */
6021 if (*pBuf != pPrt->PLinkModeConf) {
6022
6023 *pBuf = SK_LMODE_INDETERMINATED;
6024 }
6025 break;
6026
6027 case OID_SKGE_LINK_MODE_STATUS:
6028 /* Get the link mode of the physical port */
6029 Val8 = CalculateLinkModeStatus(pAC, IoC, PhysPortIndex);
6030
6031 /* Check if it is the first active port */
6032 if (*pBuf == 0) {
6033
6034 *pBuf = Val8;
6035 continue;
6036 }
6037
6038 /*
6039 * If we find an active port with a different link
6040 * mode status than the first one we return a value
6041 * that indicates that the link mode status is
6042 * indeterminated.
6043 */
6044 if (*pBuf != Val8) {
6045
6046 *pBuf = SK_LMODE_STAT_INDETERMINATED;
6047 }
6048 break;
6049
6050 case OID_SKGE_LINK_STATUS:
6051 /* Get the link status of the physical port */
6052 Val8 = CalculateLinkStatus(pAC, IoC, PhysPortIndex);
6053
6054 /* Check if it is the first active port */
6055 if (*pBuf == 0) {
6056
6057 *pBuf = Val8;
6058 continue;
6059 }
6060
6061 /*
6062 * If we find an active port with a different link
6063 * status than the first one, we return a value
6064 * that indicates that the link status is
6065 * indeterminated.
6066 */
6067 if (*pBuf != Val8) {
6068
6069 *pBuf = SK_PNMI_RLMT_LSTAT_INDETERMINATED;
6070 }
6071 break;
6072
6073 case OID_SKGE_FLOWCTRL_CAP:
6074 /* Check if it is the first active port */
6075 if (*pBuf == 0) {
6076
6077 *pBuf = pPrt->PFlowCtrlCap;
6078 continue;
6079 }
6080
6081 /*
6082 * From a curious point of view the virtual port
6083 * is capable of all found capabilities.
6084 */
6085 *pBuf |= pPrt->PFlowCtrlCap;
6086 break;
6087
6088 case OID_SKGE_FLOWCTRL_MODE:
6089 /* Check if it is the first active port */
6090 if (*pBuf == 0) {
6091
6092 *pBuf = pPrt->PFlowCtrlMode;
6093 continue;
6094 }
6095
6096 /*
6097 * If we find an active port with a different flow
6098 * control mode than the first one, we return a value
6099 * that indicates that the mode is indeterminated.
6100 */
6101 if (*pBuf != pPrt->PFlowCtrlMode) {
6102
6103 *pBuf = SK_FLOW_MODE_INDETERMINATED;
6104 }
6105 break;
6106
6107 case OID_SKGE_FLOWCTRL_STATUS:
6108 /* Check if it is the first active port */
6109 if (*pBuf == 0) {
6110
6111 *pBuf = pPrt->PFlowCtrlStatus;
6112 continue;
6113 }
6114
6115 /*
6116 * If we find an active port with a different flow
6117 * control status than the first one, we return a
6118 * value that indicates that the status is
6119 * indeterminated.
6120 */
6121 if (*pBuf != pPrt->PFlowCtrlStatus) {
6122
6123 *pBuf = SK_FLOW_STAT_INDETERMINATED;
6124 }
6125 break;
6126
6127 case OID_SKGE_PHY_OPERATION_CAP:
6128 /* Check if it is the first active port */
6129 if (*pBuf == 0) {
6130
6131 *pBuf = pPrt->PMSCap;
6132 continue;
6133 }
6134
6135 /*
6136 * From a curious point of view the virtual port
6137 * is capable of all found capabilities.
6138 */
6139 *pBuf |= pPrt->PMSCap;
6140 break;
6141
6142 case OID_SKGE_PHY_OPERATION_MODE:
6143 /* Check if it is the first active port */
6144 if (*pBuf == 0) {
6145
6146 *pBuf = pPrt->PMSMode;
6147 continue;
6148 }
6149
6150 /*
6151 * If we find an active port with a different master/
6152 * slave mode than the first one, we return a value
6153 * that indicates that the mode is indeterminated.
6154 */
6155 if (*pBuf != pPrt->PMSMode) {
6156
6157 *pBuf = SK_MS_MODE_INDETERMINATED;
6158 }
6159 break;
6160
6161 case OID_SKGE_PHY_OPERATION_STATUS:
6162 /* Check if it is the first active port */
6163 if (*pBuf == 0) {
6164
6165 *pBuf = pPrt->PMSStatus;
6166 continue;
6167 }
6168
6169 /*
6170 * If we find an active port with a different master/
6171 * slave status than the first one, we return a
6172 * value that indicates that the status is
6173 * indeterminated.
6174 */
6175 if (*pBuf != pPrt->PMSStatus) {
6176
6177 *pBuf = SK_MS_STAT_INDETERMINATED;
6178 }
6179 break;
6180
6181 case OID_SKGE_SPEED_MODE:
6182 /* Check if it is the first active port */
6183 if (*pBuf == 0) {
6184
6185 *pBuf = pPrt->PLinkSpeed;
6186 continue;
6187 }
6188
6189 /*
6190 * If we find an active port with a different flow
6191 * control mode than the first one, we return a value
6192 * that indicates that the mode is indeterminated.
6193 */
6194 if (*pBuf != pPrt->PLinkSpeed) {
6195
6196 *pBuf = SK_LSPEED_INDETERMINATED;
6197 }
6198 break;
6199
6200 case OID_SKGE_SPEED_STATUS:
6201 /* Check if it is the first active port */
6202 if (*pBuf == 0) {
6203
6204 *pBuf = pPrt->PLinkSpeedUsed;
6205 continue;
6206 }
6207
6208 /*
6209 * If we find an active port with a different flow
6210 * control status than the first one, we return a
6211 * value that indicates that the status is
6212 * indeterminated.
6213 */
6214 if (*pBuf != pPrt->PLinkSpeedUsed) {
6215
6216 *pBuf = SK_LSPEED_STAT_INDETERMINATED;
6217 }
6218 break;
6219 }
6220 }
6221
6222 /*
6223 * If no port is active return an indeterminated answer
6224 */
6225 if (!PortActiveFlag) {
6226
6227 switch (Id) {
6228
6229 case OID_SKGE_LINK_CAP:
6230 *pBuf = SK_LMODE_CAP_INDETERMINATED;
6231 break;
6232
6233 case OID_SKGE_LINK_MODE:
6234 *pBuf = SK_LMODE_INDETERMINATED;
6235 break;
6236
6237 case OID_SKGE_LINK_MODE_STATUS:
6238 *pBuf = SK_LMODE_STAT_INDETERMINATED;
6239 break;
6240
6241 case OID_SKGE_LINK_STATUS:
6242 *pBuf = SK_PNMI_RLMT_LSTAT_INDETERMINATED;
6243 break;
6244
6245 case OID_SKGE_FLOWCTRL_CAP:
6246 case OID_SKGE_FLOWCTRL_MODE:
6247 *pBuf = SK_FLOW_MODE_INDETERMINATED;
6248 break;
6249
6250 case OID_SKGE_FLOWCTRL_STATUS:
6251 *pBuf = SK_FLOW_STAT_INDETERMINATED;
6252 break;
6253
6254 case OID_SKGE_PHY_OPERATION_CAP:
6255 *pBuf = SK_MS_CAP_INDETERMINATED;
6256 break;
6257
6258 case OID_SKGE_PHY_OPERATION_MODE:
6259 *pBuf = SK_MS_MODE_INDETERMINATED;
6260 break;
6261
6262 case OID_SKGE_PHY_OPERATION_STATUS:
6263 *pBuf = SK_MS_STAT_INDETERMINATED;
6264 break;
6265 case OID_SKGE_SPEED_CAP:
6266 *pBuf = SK_LSPEED_CAP_INDETERMINATED;
6267 break;
6268
6269 case OID_SKGE_SPEED_MODE:
6270 *pBuf = SK_LSPEED_INDETERMINATED;
6271 break;
6272
6273 case OID_SKGE_SPEED_STATUS:
6274 *pBuf = SK_LSPEED_STAT_INDETERMINATED;
6275 break;
6276 }
6277 }
6278}
6279
6280/*****************************************************************************
6281 *
6282 * CalculateLinkStatus - Determins the link status of a physical port
6283 *
6284 * Description:
6285 * Determins the link status the following way:
6286 * LSTAT_PHY_DOWN: Link is down
6287 * LSTAT_AUTONEG: Auto-negotiation failed
6288 * LSTAT_LOG_DOWN: Link is up but RLMT did not yet put the port
6289 * logically up.
6290 * LSTAT_LOG_UP: RLMT marked the port as up
6291 *
6292 * Returns:
6293 * Link status of physical port
6294 */
6295PNMI_STATIC SK_U8 CalculateLinkStatus(
6296SK_AC *pAC, /* Pointer to adapter context */
6297SK_IOC IoC, /* IO context handle */
6298unsigned int PhysPortIndex) /* Physical port index */
6299{
6300 SK_U8 Result;
6301
6302 if (!pAC->GIni.GP[PhysPortIndex].PHWLinkUp) {
6303
6304 Result = SK_PNMI_RLMT_LSTAT_PHY_DOWN;
6305 }
6306 else if (pAC->GIni.GP[PhysPortIndex].PAutoNegFail > 0) {
6307
6308 Result = SK_PNMI_RLMT_LSTAT_AUTONEG;
6309 }
6310 else if (!pAC->Rlmt.Port[PhysPortIndex].PortDown) {
6311
6312 Result = SK_PNMI_RLMT_LSTAT_LOG_UP;
6313 }
6314 else {
6315 Result = SK_PNMI_RLMT_LSTAT_LOG_DOWN;
6316 }
6317
6318 return (Result);
6319}
6320
6321/*****************************************************************************
6322 *
6323 * CalculateLinkModeStatus - Determins the link mode status of a phys. port
6324 *
6325 * Description:
6326 * The COMMON module only tells us if the mode is half or full duplex.
6327 * But in the decade of auto sensing it is useful for the user to
6328 * know if the mode was negotiated or forced. Therefore we have a
6329 * look to the mode, which was last used by the negotiation process.
6330 *
6331 * Returns:
6332 * The link mode status
6333 */
6334PNMI_STATIC SK_U8 CalculateLinkModeStatus(
6335SK_AC *pAC, /* Pointer to adapter context */
6336SK_IOC IoC, /* IO context handle */
6337unsigned int PhysPortIndex) /* Physical port index */
6338{
6339 SK_U8 Result;
6340
6341 /* Get the current mode, which can be full or half duplex */
6342 Result = pAC->GIni.GP[PhysPortIndex].PLinkModeStatus;
6343
6344 /* Check if no valid mode could be found (link is down) */
6345 if (Result < SK_LMODE_STAT_HALF) {
6346
6347 Result = SK_LMODE_STAT_UNKNOWN;
6348 }
6349 else if (pAC->GIni.GP[PhysPortIndex].PLinkMode >= SK_LMODE_AUTOHALF) {
6350
6351 /*
6352 * Auto-negotiation was used to bring up the link. Change
6353 * the already found duplex status that it indicates
6354 * auto-negotiation was involved.
6355 */
6356 if (Result == SK_LMODE_STAT_HALF) {
6357
6358 Result = SK_LMODE_STAT_AUTOHALF;
6359 }
6360 else if (Result == SK_LMODE_STAT_FULL) {
6361
6362 Result = SK_LMODE_STAT_AUTOFULL;
6363 }
6364 }
6365
6366 return (Result);
6367}
6368
6369/*****************************************************************************
6370 *
6371 * GetVpdKeyArr - Obtain an array of VPD keys
6372 *
6373 * Description:
6374 * Read the VPD keys and build an array of VPD keys, which are
6375 * easy to access.
6376 *
6377 * Returns:
6378 * SK_PNMI_ERR_OK Task successfully performed.
6379 * SK_PNMI_ERR_GENERAL Something went wrong.
6380 */
6381PNMI_STATIC int GetVpdKeyArr(
6382SK_AC *pAC, /* Pointer to adapter context */
6383SK_IOC IoC, /* IO context handle */
6384char *pKeyArr, /* Ptr KeyArray */
6385unsigned int KeyArrLen, /* Length of array in bytes */
6386unsigned int *pKeyNo) /* Number of keys */
6387{
6388 unsigned int BufKeysLen = SK_PNMI_VPD_BUFSIZE;
6389 char BufKeys[SK_PNMI_VPD_BUFSIZE];
6390 unsigned int StartOffset;
6391 unsigned int Offset;
6392 int Index;
6393 int Ret;
6394
6395
6396 SK_MEMSET(pKeyArr, 0, KeyArrLen);
6397
6398 /*
6399 * Get VPD key list
6400 */
6401 Ret = VpdKeys(pAC, IoC, (char *)&BufKeys, (int *)&BufKeysLen,
6402 (int *)pKeyNo);
6403 if (Ret > 0) {
6404
6405 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR014,
6406 SK_PNMI_ERR014MSG);
6407
6408 return (SK_PNMI_ERR_GENERAL);
6409 }
6410 /* If no keys are available return now */
6411 if (*pKeyNo == 0 || BufKeysLen == 0) {
6412
6413 return (SK_PNMI_ERR_OK);
6414 }
6415 /*
6416 * If the key list is too long for us trunc it and give a
6417 * errorlog notification. This case should not happen because
6418 * the maximum number of keys is limited due to RAM limitations
6419 */
6420 if (*pKeyNo > SK_PNMI_VPD_ENTRIES) {
6421
6422 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR015,
6423 SK_PNMI_ERR015MSG);
6424
6425 *pKeyNo = SK_PNMI_VPD_ENTRIES;
6426 }
6427
6428 /*
6429 * Now build an array of fixed string length size and copy
6430 * the keys together.
6431 */
6432 for (Index = 0, StartOffset = 0, Offset = 0; Offset < BufKeysLen;
6433 Offset ++) {
6434
6435 if (BufKeys[Offset] != 0) {
6436
6437 continue;
6438 }
6439
6440 if (Offset - StartOffset > SK_PNMI_VPD_KEY_SIZE) {
6441
6442 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR016,
6443 SK_PNMI_ERR016MSG);
6444 return (SK_PNMI_ERR_GENERAL);
6445 }
6446
6447 SK_STRNCPY(pKeyArr + Index * SK_PNMI_VPD_KEY_SIZE,
6448 &BufKeys[StartOffset], SK_PNMI_VPD_KEY_SIZE);
6449
6450 Index ++;
6451 StartOffset = Offset + 1;
6452 }
6453
6454 /* Last key not zero terminated? Get it anyway */
6455 if (StartOffset < Offset) {
6456
6457 SK_STRNCPY(pKeyArr + Index * SK_PNMI_VPD_KEY_SIZE,
6458 &BufKeys[StartOffset], SK_PNMI_VPD_KEY_SIZE);
6459 }
6460
6461 return (SK_PNMI_ERR_OK);
6462}
6463
6464/*****************************************************************************
6465 *
6466 * SirqUpdate - Let the SIRQ update its internal values
6467 *
6468 * Description:
6469 * Just to be sure that the SIRQ module holds its internal data
6470 * structures up to date, we send an update event before we make
6471 * any access.
6472 *
6473 * Returns:
6474 * SK_PNMI_ERR_OK Task successfully performed.
6475 * SK_PNMI_ERR_GENERAL Something went wrong.
6476 */
6477PNMI_STATIC int SirqUpdate(
6478SK_AC *pAC, /* Pointer to adapter context */
6479SK_IOC IoC) /* IO context handle */
6480{
6481 SK_EVPARA EventParam;
6482
6483
6484 /* Was the module already updated during the current PNMI call? */
6485 if (pAC->Pnmi.SirqUpdatedFlag > 0) {
6486
6487 return (SK_PNMI_ERR_OK);
6488 }
6489
6490 /* Send an synchronuous update event to the module */
6491 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
6492 if (SkGeSirqEvent(pAC, IoC, SK_HWEV_UPDATE_STAT, EventParam) > 0) {
6493
6494 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR047,
6495 SK_PNMI_ERR047MSG);
6496
6497 return (SK_PNMI_ERR_GENERAL);
6498 }
6499
6500 return (SK_PNMI_ERR_OK);
6501}
6502
6503/*****************************************************************************
6504 *
6505 * RlmtUpdate - Let the RLMT update its internal values
6506 *
6507 * Description:
6508 * Just to be sure that the RLMT module holds its internal data
6509 * structures up to date, we send an update event before we make
6510 * any access.
6511 *
6512 * Returns:
6513 * SK_PNMI_ERR_OK Task successfully performed.
6514 * SK_PNMI_ERR_GENERAL Something went wrong.
6515 */
6516PNMI_STATIC int RlmtUpdate(
6517SK_AC *pAC, /* Pointer to adapter context */
6518SK_IOC IoC, /* IO context handle */
6519SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
6520{
6521 SK_EVPARA EventParam;
6522
6523
6524 /* Was the module already updated during the current PNMI call? */
6525 if (pAC->Pnmi.RlmtUpdatedFlag > 0) {
6526
6527 return (SK_PNMI_ERR_OK);
6528 }
6529
6530 /* Send an synchronuous update event to the module */
6531 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
6532 EventParam.Para32[0] = NetIndex;
6533 EventParam.Para32[1] = (SK_U32)-1;
6534 if (SkRlmtEvent(pAC, IoC, SK_RLMT_STATS_UPDATE, EventParam) > 0) {
6535
6536 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR048,
6537 SK_PNMI_ERR048MSG);
6538
6539 return (SK_PNMI_ERR_GENERAL);
6540 }
6541
6542 return (SK_PNMI_ERR_OK);
6543}
6544
6545/*****************************************************************************
6546 *
6547 * MacUpdate - Force the XMAC to output the current statistic
6548 *
6549 * Description:
6550 * The XMAC holds its statistic internally. To obtain the current
6551 * values we must send a command so that the statistic data will
6552 * be written to a predefined memory area on the adapter.
6553 *
6554 * Returns:
6555 * SK_PNMI_ERR_OK Task successfully performed.
6556 * SK_PNMI_ERR_GENERAL Something went wrong.
6557 */
6558PNMI_STATIC int MacUpdate(
6559SK_AC *pAC, /* Pointer to adapter context */
6560SK_IOC IoC, /* IO context handle */
6561unsigned int FirstMac, /* Index of the first Mac to be updated */
6562unsigned int LastMac) /* Index of the last Mac to be updated */
6563{
6564 unsigned int MacIndex;
6565
6566 /*
6567 * Were the statistics already updated during the
6568 * current PNMI call?
6569 */
6570 if (pAC->Pnmi.MacUpdatedFlag > 0) {
6571
6572 return (SK_PNMI_ERR_OK);
6573 }
6574
6575 /* Send an update command to all MACs specified */
6576 for (MacIndex = FirstMac; MacIndex <= LastMac; MacIndex ++) {
6577
6578 /*
6579 * 2002-09-13 pweber: Freeze the current SW counters.
6580 * (That should be done as close as
6581 * possible to the update of the
6582 * HW counters)
6583 */
6584 if (pAC->GIni.GIMacType == SK_MAC_XMAC) {
6585 pAC->Pnmi.BufPort[MacIndex] = pAC->Pnmi.Port[MacIndex];
6586 }
6587
6588 /* 2002-09-13 pweber: Update the HW counter */
6589 if (pAC->GIni.GIFunc.pFnMacUpdateStats(pAC, IoC, MacIndex) != 0) {
6590
6591 return (SK_PNMI_ERR_GENERAL);
6592 }
6593 }
6594
6595 return (SK_PNMI_ERR_OK);
6596}
6597
6598/*****************************************************************************
6599 *
6600 * GetStatVal - Retrieve an XMAC statistic counter
6601 *
6602 * Description:
6603 * Retrieves the statistic counter of a virtual or physical port. The
6604 * virtual port is identified by the index 0. It consists of all
6605 * currently active ports. To obtain the counter value for this port
6606 * we must add the statistic counter of all active ports. To grant
6607 * continuous counter values for the virtual port even when port
6608 * switches occur we must additionally add a delta value, which was
6609 * calculated during a SK_PNMI_EVT_RLMT_ACTIVE_UP event.
6610 *
6611 * Returns:
6612 * Requested statistic value
6613 */
6614PNMI_STATIC SK_U64 GetStatVal(
6615SK_AC *pAC, /* Pointer to adapter context */
6616SK_IOC IoC, /* IO context handle */
6617unsigned int LogPortIndex, /* Index of the logical Port to be processed */
6618unsigned int StatIndex, /* Index to statistic value */
6619SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
6620{
6621 unsigned int PhysPortIndex;
6622 unsigned int PhysPortMax;
6623 SK_U64 Val = 0;
6624
6625
6626 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
6627
6628 PhysPortIndex = NetIndex;
6629
6630 Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex);
6631 }
6632 else { /* Single Net mode */
6633
6634 if (LogPortIndex == 0) {
6635
6636 PhysPortMax = pAC->GIni.GIMacsFound;
6637
6638 /* Add counter of all active ports */
6639 for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
6640 PhysPortIndex ++) {
6641
6642 if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
6643
6644 Val += GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex);
6645 }
6646 }
6647
6648 /* Correct value because of port switches */
6649 Val += pAC->Pnmi.VirtualCounterOffset[StatIndex];
6650 }
6651 else {
6652 /* Get counter value of physical port */
6653 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
6654
6655 Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex);
6656 }
6657 }
6658 return (Val);
6659}
6660
6661/*****************************************************************************
6662 *
6663 * GetPhysStatVal - Get counter value for physical port
6664 *
6665 * Description:
6666 * Builds a 64bit counter value. Except for the octet counters
6667 * the lower 32bit are counted in hardware and the upper 32bit
6668 * in software by monitoring counter overflow interrupts in the
6669 * event handler. To grant continous counter values during XMAC
6670 * resets (caused by a workaround) we must add a delta value.
6671 * The delta was calculated in the event handler when a
6672 * SK_PNMI_EVT_XMAC_RESET was received.
6673 *
6674 * Returns:
6675 * Counter value
6676 */
6677PNMI_STATIC SK_U64 GetPhysStatVal(
6678SK_AC *pAC, /* Pointer to adapter context */
6679SK_IOC IoC, /* IO context handle */
6680unsigned int PhysPortIndex, /* Index of the logical Port to be processed */
6681unsigned int StatIndex) /* Index to statistic value */
6682{
6683 SK_U64 Val = 0;
6684 SK_U32 LowVal = 0;
6685 SK_U32 HighVal = 0;
6686 SK_U16 Word;
6687 int MacType;
6688 unsigned int HelpIndex;
6689 SK_GEPORT *pPrt;
6690
6691 SK_PNMI_PORT *pPnmiPrt;
6692 SK_GEMACFUNC *pFnMac;
6693
6694 pPrt = &pAC->GIni.GP[PhysPortIndex];
6695
6696 MacType = pAC->GIni.GIMacType;
6697
6698 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
6699 if (MacType == SK_MAC_XMAC) {
6700 pPnmiPrt = &pAC->Pnmi.BufPort[PhysPortIndex];
6701 }
6702 else {
6703 pPnmiPrt = &pAC->Pnmi.Port[PhysPortIndex];
6704 }
6705
6706 pFnMac = &pAC->GIni.GIFunc;
6707
6708 switch (StatIndex) {
6709 case SK_PNMI_HTX:
6710 if (MacType == SK_MAC_GMAC) {
6711 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6712 StatAddr[SK_PNMI_HTX_BROADCAST][MacType].Reg,
6713 &LowVal);
6714 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6715 StatAddr[SK_PNMI_HTX_MULTICAST][MacType].Reg,
6716 &HighVal);
6717 LowVal += HighVal;
6718 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6719 StatAddr[SK_PNMI_HTX_UNICAST][MacType].Reg,
6720 &HighVal);
6721 LowVal += HighVal;
6722 }
6723 else {
6724 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6725 StatAddr[StatIndex][MacType].Reg,
6726 &LowVal);
6727 }
6728 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6729 break;
6730
6731 case SK_PNMI_HRX:
6732 if (MacType == SK_MAC_GMAC) {
6733 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6734 StatAddr[SK_PNMI_HRX_BROADCAST][MacType].Reg,
6735 &LowVal);
6736 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6737 StatAddr[SK_PNMI_HRX_MULTICAST][MacType].Reg,
6738 &HighVal);
6739 LowVal += HighVal;
6740 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6741 StatAddr[SK_PNMI_HRX_UNICAST][MacType].Reg,
6742 &HighVal);
6743 LowVal += HighVal;
6744 }
6745 else {
6746 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6747 StatAddr[StatIndex][MacType].Reg,
6748 &LowVal);
6749 }
6750 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6751 break;
6752
6753 case SK_PNMI_HTX_OCTET:
6754 case SK_PNMI_HRX_OCTET:
6755 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6756 StatAddr[StatIndex][MacType].Reg,
6757 &HighVal);
6758 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6759 StatAddr[StatIndex + 1][MacType].Reg,
6760 &LowVal);
6761 break;
6762
6763 case SK_PNMI_HTX_BURST:
6764 case SK_PNMI_HTX_EXCESS_DEF:
6765 case SK_PNMI_HTX_CARRIER:
6766 /* Not supported by GMAC */
6767 if (MacType == SK_MAC_GMAC) {
6768 return (Val);
6769 }
6770
6771 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6772 StatAddr[StatIndex][MacType].Reg,
6773 &LowVal);
6774 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6775 break;
6776
6777 case SK_PNMI_HTX_MACC:
6778 /* GMAC only supports PAUSE MAC control frames */
6779 if (MacType == SK_MAC_GMAC) {
6780 HelpIndex = SK_PNMI_HTX_PMACC;
6781 }
6782 else {
6783 HelpIndex = StatIndex;
6784 }
6785
6786 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6787 StatAddr[HelpIndex][MacType].Reg,
6788 &LowVal);
6789
6790 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6791 break;
6792
6793 case SK_PNMI_HTX_COL:
6794 case SK_PNMI_HRX_UNDERSIZE:
6795 /* Not supported by XMAC */
6796 if (MacType == SK_MAC_XMAC) {
6797 return (Val);
6798 }
6799
6800 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6801 StatAddr[StatIndex][MacType].Reg,
6802 &LowVal);
6803 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6804 break;
6805
6806 case SK_PNMI_HTX_DEFFERAL:
6807 /* Not supported by GMAC */
6808 if (MacType == SK_MAC_GMAC) {
6809 return (Val);
6810 }
6811
6812 /*
6813 * XMAC counts frames with deferred transmission
6814 * even in full-duplex mode.
6815 *
6816 * In full-duplex mode the counter remains constant!
6817 */
6818 if ((pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOFULL) ||
6819 (pPrt->PLinkModeStatus == SK_LMODE_STAT_FULL)) {
6820
6821 LowVal = 0;
6822 HighVal = 0;
6823 }
6824 else {
6825 /* Otherwise get contents of hardware register */
6826 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6827 StatAddr[StatIndex][MacType].Reg,
6828 &LowVal);
6829 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6830 }
6831 break;
6832
6833 case SK_PNMI_HRX_BADOCTET:
6834 /* Not supported by XMAC */
6835 if (MacType == SK_MAC_XMAC) {
6836 return (Val);
6837 }
6838
6839 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6840 StatAddr[StatIndex][MacType].Reg,
6841 &HighVal);
6842 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6843 StatAddr[StatIndex + 1][MacType].Reg,
6844 &LowVal);
6845 break;
6846
6847 case SK_PNMI_HTX_OCTETLOW:
6848 case SK_PNMI_HRX_OCTETLOW:
6849 case SK_PNMI_HRX_BADOCTETLOW:
6850 return (Val);
6851
6852 case SK_PNMI_HRX_LONGFRAMES:
6853 /* For XMAC the SW counter is managed by PNMI */
6854 if (MacType == SK_MAC_XMAC) {
6855 return (pPnmiPrt->StatRxLongFrameCts);
6856 }
6857
6858 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6859 StatAddr[StatIndex][MacType].Reg,
6860 &LowVal);
6861 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6862 break;
6863
6864 case SK_PNMI_HRX_TOO_LONG:
6865 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6866 StatAddr[StatIndex][MacType].Reg,
6867 &LowVal);
6868 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6869
6870 Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal);
6871
6872 if (MacType == SK_MAC_GMAC) {
6873 /* For GMAC the SW counter is additionally managed by PNMI */
6874 Val += pPnmiPrt->StatRxFrameTooLongCts;
6875 }
6876 else {
6877 /*
6878 * Frames longer than IEEE 802.3 frame max size are counted
6879 * by XMAC in frame_too_long counter even reception of long
6880 * frames was enabled and the frame was correct.
6881 * So correct the value by subtracting RxLongFrame counter.
6882 */
6883 Val -= pPnmiPrt->StatRxLongFrameCts;
6884 }
6885
6886 LowVal = (SK_U32)Val;
6887 HighVal = (SK_U32)(Val >> 32);
6888 break;
6889
6890 case SK_PNMI_HRX_SHORTS:
6891 /* Not supported by GMAC */
6892 if (MacType == SK_MAC_GMAC) {
6893 /* GM_RXE_FRAG?? */
6894 return (Val);
6895 }
6896
6897 /*
6898 * XMAC counts short frame errors even if link down (#10620)
6899 *
6900 * If link-down the counter remains constant
6901 */
6902 if (pPrt->PLinkModeStatus != SK_LMODE_STAT_UNKNOWN) {
6903
6904 /* Otherwise get incremental difference */
6905 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6906 StatAddr[StatIndex][MacType].Reg,
6907 &LowVal);
6908 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6909
6910 Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal);
6911 Val -= pPnmiPrt->RxShortZeroMark;
6912
6913 LowVal = (SK_U32)Val;
6914 HighVal = (SK_U32)(Val >> 32);
6915 }
6916 break;
6917
6918 case SK_PNMI_HRX_MACC:
6919 case SK_PNMI_HRX_MACC_UNKWN:
6920 case SK_PNMI_HRX_BURST:
6921 case SK_PNMI_HRX_MISSED:
6922 case SK_PNMI_HRX_FRAMING:
6923 case SK_PNMI_HRX_CARRIER:
6924 case SK_PNMI_HRX_IRLENGTH:
6925 case SK_PNMI_HRX_SYMBOL:
6926 case SK_PNMI_HRX_CEXT:
6927 /* Not supported by GMAC */
6928 if (MacType == SK_MAC_GMAC) {
6929 return (Val);
6930 }
6931
6932 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6933 StatAddr[StatIndex][MacType].Reg,
6934 &LowVal);
6935 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6936 break;
6937
6938 case SK_PNMI_HRX_PMACC_ERR:
6939 /* For GMAC the SW counter is managed by PNMI */
6940 if (MacType == SK_MAC_GMAC) {
6941 return (pPnmiPrt->StatRxPMaccErr);
6942 }
6943
6944 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6945 StatAddr[StatIndex][MacType].Reg,
6946 &LowVal);
6947 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6948 break;
6949
6950 /* SW counter managed by PNMI */
6951 case SK_PNMI_HTX_SYNC:
6952 LowVal = (SK_U32)pPnmiPrt->StatSyncCts;
6953 HighVal = (SK_U32)(pPnmiPrt->StatSyncCts >> 32);
6954 break;
6955
6956 /* SW counter managed by PNMI */
6957 case SK_PNMI_HTX_SYNC_OCTET:
6958 LowVal = (SK_U32)pPnmiPrt->StatSyncOctetsCts;
6959 HighVal = (SK_U32)(pPnmiPrt->StatSyncOctetsCts >> 32);
6960 break;
6961
6962 case SK_PNMI_HRX_FCS:
6963 /*
6964 * Broadcom filters FCS errors and counts it in
6965 * Receive Error Counter register
6966 */
6967 if (pPrt->PhyType == SK_PHY_BCOM) {
6968 /* do not read while not initialized (PHY_READ hangs!)*/
6969 if (pPrt->PState != SK_PRT_RESET) {
6970 SkXmPhyRead(pAC, IoC, PhysPortIndex, PHY_BCOM_RE_CTR, &Word);
6971
6972 LowVal = Word;
6973 }
6974 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6975 }
6976 else {
6977 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6978 StatAddr[StatIndex][MacType].Reg,
6979 &LowVal);
6980 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6981 }
6982 break;
6983
6984 default:
6985 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6986 StatAddr[StatIndex][MacType].Reg,
6987 &LowVal);
6988 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6989 break;
6990 }
6991
6992 Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal);
6993
6994 /* Correct value because of possible XMAC reset. XMAC Errata #2 */
6995 Val += pPnmiPrt->CounterOffset[StatIndex];
6996
6997 return (Val);
6998}
6999
7000/*****************************************************************************
7001 *
7002 * ResetCounter - Set all counters and timestamps to zero
7003 *
7004 * Description:
7005 * Notifies other common modules which store statistic data to
7006 * reset their counters and finally reset our own counters.
7007 *
7008 * Returns:
7009 * Nothing
7010 */
7011PNMI_STATIC void ResetCounter(
7012SK_AC *pAC, /* Pointer to adapter context */
7013SK_IOC IoC, /* IO context handle */
7014SK_U32 NetIndex)
7015{
7016 unsigned int PhysPortIndex;
7017 SK_EVPARA EventParam;
7018
7019
7020 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
7021
7022 /* Notify sensor module */
7023 SkEventQueue(pAC, SKGE_I2C, SK_I2CEV_CLEAR, EventParam);
7024
7025 /* Notify RLMT module */
7026 EventParam.Para32[0] = NetIndex;
7027 EventParam.Para32[1] = (SK_U32)-1;
7028 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STATS_CLEAR, EventParam);
7029 EventParam.Para32[1] = 0;
7030
7031 /* Notify SIRQ module */
7032 SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_CLEAR_STAT, EventParam);
7033
7034 /* Notify CSUM module */
7035#ifdef SK_USE_CSUM
7036 EventParam.Para32[0] = NetIndex;
7037 EventParam.Para32[1] = (SK_U32)-1;
7038 SkEventQueue(pAC, SKGE_CSUM, SK_CSUM_EVENT_CLEAR_PROTO_STATS,
7039 EventParam);
7040#endif /* SK_USE_CSUM */
7041
7042 /* Clear XMAC statistic */
7043 for (PhysPortIndex = 0; PhysPortIndex <
7044 (unsigned int)pAC->GIni.GIMacsFound; PhysPortIndex ++) {
7045
7046 (void)pAC->GIni.GIFunc.pFnMacResetCounter(pAC, IoC, PhysPortIndex);
7047
7048 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].CounterHigh,
7049 0, sizeof(pAC->Pnmi.Port[PhysPortIndex].CounterHigh));
7050 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7051 CounterOffset, 0, sizeof(pAC->Pnmi.Port[
7052 PhysPortIndex].CounterOffset));
7053 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].StatSyncCts,
7054 0, sizeof(pAC->Pnmi.Port[PhysPortIndex].StatSyncCts));
7055 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7056 StatSyncOctetsCts, 0, sizeof(pAC->Pnmi.Port[
7057 PhysPortIndex].StatSyncOctetsCts));
7058 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7059 StatRxLongFrameCts, 0, sizeof(pAC->Pnmi.Port[
7060 PhysPortIndex].StatRxLongFrameCts));
7061 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7062 StatRxFrameTooLongCts, 0, sizeof(pAC->Pnmi.Port[
7063 PhysPortIndex].StatRxFrameTooLongCts));
7064 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7065 StatRxPMaccErr, 0, sizeof(pAC->Pnmi.Port[
7066 PhysPortIndex].StatRxPMaccErr));
7067 }
7068
7069 /*
7070 * Clear local statistics
7071 */
7072 SK_MEMSET((char *)&pAC->Pnmi.VirtualCounterOffset, 0,
7073 sizeof(pAC->Pnmi.VirtualCounterOffset));
7074 pAC->Pnmi.RlmtChangeCts = 0;
7075 pAC->Pnmi.RlmtChangeTime = 0;
7076 SK_MEMSET((char *)&pAC->Pnmi.RlmtChangeEstimate.EstValue[0], 0,
7077 sizeof(pAC->Pnmi.RlmtChangeEstimate.EstValue));
7078 pAC->Pnmi.RlmtChangeEstimate.EstValueIndex = 0;
7079 pAC->Pnmi.RlmtChangeEstimate.Estimate = 0;
7080 pAC->Pnmi.Port[NetIndex].TxSwQueueMax = 0;
7081 pAC->Pnmi.Port[NetIndex].TxRetryCts = 0;
7082 pAC->Pnmi.Port[NetIndex].RxIntrCts = 0;
7083 pAC->Pnmi.Port[NetIndex].TxIntrCts = 0;
7084 pAC->Pnmi.Port[NetIndex].RxNoBufCts = 0;
7085 pAC->Pnmi.Port[NetIndex].TxNoBufCts = 0;
7086 pAC->Pnmi.Port[NetIndex].TxUsedDescrNo = 0;
7087 pAC->Pnmi.Port[NetIndex].RxDeliveredCts = 0;
7088 pAC->Pnmi.Port[NetIndex].RxOctetsDeliveredCts = 0;
7089 pAC->Pnmi.Port[NetIndex].ErrRecoveryCts = 0;
7090}
7091
7092/*****************************************************************************
7093 *
7094 * GetTrapEntry - Get an entry in the trap buffer
7095 *
7096 * Description:
7097 * The trap buffer stores various events. A user application somehow
7098 * gets notified that an event occured and retrieves the trap buffer
7099 * contens (or simply polls the buffer). The buffer is organized as
7100 * a ring which stores the newest traps at the beginning. The oldest
7101 * traps are overwritten by the newest ones. Each trap entry has a
7102 * unique number, so that applications may detect new trap entries.
7103 *
7104 * Returns:
7105 * A pointer to the trap entry
7106 */
7107PNMI_STATIC char* GetTrapEntry(
7108SK_AC *pAC, /* Pointer to adapter context */
7109SK_U32 TrapId, /* SNMP ID of the trap */
7110unsigned int Size) /* Space needed for trap entry */
7111{
7112 unsigned int BufPad = pAC->Pnmi.TrapBufPad;
7113 unsigned int BufFree = pAC->Pnmi.TrapBufFree;
7114 unsigned int Beg = pAC->Pnmi.TrapQueueBeg;
7115 unsigned int End = pAC->Pnmi.TrapQueueEnd;
7116 char *pBuf = &pAC->Pnmi.TrapBuf[0];
7117 int Wrap;
7118 unsigned int NeededSpace;
7119 unsigned int EntrySize;
7120 SK_U32 Val32;
7121 SK_U64 Val64;
7122
7123
7124 /* Last byte of entry will get a copy of the entry length */
7125 Size ++;
7126
7127 /*
7128 * Calculate needed buffer space */
7129 if (Beg >= Size) {
7130
7131 NeededSpace = Size;
7132 Wrap = SK_FALSE;
7133 }
7134 else {
7135 NeededSpace = Beg + Size;
7136 Wrap = SK_TRUE;
7137 }
7138
7139 /*
7140 * Check if enough buffer space is provided. Otherwise
7141 * free some entries. Leave one byte space between begin
7142 * and end of buffer to make it possible to detect whether
7143 * the buffer is full or empty
7144 */
7145 while (BufFree < NeededSpace + 1) {
7146
7147 if (End == 0) {
7148
7149 End = SK_PNMI_TRAP_QUEUE_LEN;
7150 }
7151
7152 EntrySize = (unsigned int)*((unsigned char *)pBuf + End - 1);
7153 BufFree += EntrySize;
7154 End -= EntrySize;
7155#ifdef DEBUG
7156 SK_MEMSET(pBuf + End, (char)(-1), EntrySize);
7157#endif /* DEBUG */
7158 if (End == BufPad) {
7159#ifdef DEBUG
7160 SK_MEMSET(pBuf, (char)(-1), End);
7161#endif /* DEBUG */
7162 BufFree += End;
7163 End = 0;
7164 BufPad = 0;
7165 }
7166 }
7167
7168 /*
7169 * Insert new entry as first entry. Newest entries are
7170 * stored at the beginning of the queue.
7171 */
7172 if (Wrap) {
7173
7174 BufPad = Beg;
7175 Beg = SK_PNMI_TRAP_QUEUE_LEN - Size;
7176 }
7177 else {
7178 Beg = Beg - Size;
7179 }
7180 BufFree -= NeededSpace;
7181
7182 /* Save the current offsets */
7183 pAC->Pnmi.TrapQueueBeg = Beg;
7184 pAC->Pnmi.TrapQueueEnd = End;
7185 pAC->Pnmi.TrapBufPad = BufPad;
7186 pAC->Pnmi.TrapBufFree = BufFree;
7187
7188 /* Initialize the trap entry */
7189 *(pBuf + Beg + Size - 1) = (char)Size;
7190 *(pBuf + Beg) = (char)Size;
7191 Val32 = (pAC->Pnmi.TrapUnique) ++;
7192 SK_PNMI_STORE_U32(pBuf + Beg + 1, Val32);
7193 SK_PNMI_STORE_U32(pBuf + Beg + 1 + sizeof(SK_U32), TrapId);
7194 Val64 = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
7195 SK_PNMI_STORE_U64(pBuf + Beg + 1 + 2 * sizeof(SK_U32), Val64);
7196
7197 return (pBuf + Beg);
7198}
7199
7200/*****************************************************************************
7201 *
7202 * CopyTrapQueue - Copies the trap buffer for the TRAP OID
7203 *
7204 * Description:
7205 * On a query of the TRAP OID the trap buffer contents will be
7206 * copied continuously to the request buffer, which must be large
7207 * enough. No length check is performed.
7208 *
7209 * Returns:
7210 * Nothing
7211 */
7212PNMI_STATIC void CopyTrapQueue(
7213SK_AC *pAC, /* Pointer to adapter context */
7214char *pDstBuf) /* Buffer to which the queued traps will be copied */
7215{
7216 unsigned int BufPad = pAC->Pnmi.TrapBufPad;
7217 unsigned int Trap = pAC->Pnmi.TrapQueueBeg;
7218 unsigned int End = pAC->Pnmi.TrapQueueEnd;
7219 char *pBuf = &pAC->Pnmi.TrapBuf[0];
7220 unsigned int Len;
7221 unsigned int DstOff = 0;
7222
7223
7224 while (Trap != End) {
7225
7226 Len = (unsigned int)*(pBuf + Trap);
7227
7228 /*
7229 * Last byte containing a copy of the length will
7230 * not be copied.
7231 */
7232 *(pDstBuf + DstOff) = (char)(Len - 1);
7233 SK_MEMCPY(pDstBuf + DstOff + 1, pBuf + Trap + 1, Len - 2);
7234 DstOff += Len - 1;
7235
7236 Trap += Len;
7237 if (Trap == SK_PNMI_TRAP_QUEUE_LEN) {
7238
7239 Trap = BufPad;
7240 }
7241 }
7242}
7243
7244/*****************************************************************************
7245 *
7246 * GetTrapQueueLen - Get the length of the trap buffer
7247 *
7248 * Description:
7249 * Evaluates the number of currently stored traps and the needed
7250 * buffer size to retrieve them.
7251 *
7252 * Returns:
7253 * Nothing
7254 */
7255PNMI_STATIC void GetTrapQueueLen(
7256SK_AC *pAC, /* Pointer to adapter context */
7257unsigned int *pLen, /* Length in Bytes of all queued traps */
7258unsigned int *pEntries) /* Returns number of trapes stored in queue */
7259{
7260 unsigned int BufPad = pAC->Pnmi.TrapBufPad;
7261 unsigned int Trap = pAC->Pnmi.TrapQueueBeg;
7262 unsigned int End = pAC->Pnmi.TrapQueueEnd;
7263 char *pBuf = &pAC->Pnmi.TrapBuf[0];
7264 unsigned int Len;
7265 unsigned int Entries = 0;
7266 unsigned int TotalLen = 0;
7267
7268
7269 while (Trap != End) {
7270
7271 Len = (unsigned int)*(pBuf + Trap);
7272 TotalLen += Len - 1;
7273 Entries ++;
7274
7275 Trap += Len;
7276 if (Trap == SK_PNMI_TRAP_QUEUE_LEN) {
7277
7278 Trap = BufPad;
7279 }
7280 }
7281
7282 *pEntries = Entries;
7283 *pLen = TotalLen;
7284}
7285
7286/*****************************************************************************
7287 *
7288 * QueueSimpleTrap - Store a simple trap to the trap buffer
7289 *
7290 * Description:
7291 * A simple trap is a trap with now additional data. It consists
7292 * simply of a trap code.
7293 *
7294 * Returns:
7295 * Nothing
7296 */
7297PNMI_STATIC void QueueSimpleTrap(
7298SK_AC *pAC, /* Pointer to adapter context */
7299SK_U32 TrapId) /* Type of sensor trap */
7300{
7301 GetTrapEntry(pAC, TrapId, SK_PNMI_TRAP_SIMPLE_LEN);
7302}
7303
7304/*****************************************************************************
7305 *
7306 * QueueSensorTrap - Stores a sensor trap in the trap buffer
7307 *
7308 * Description:
7309 * Gets an entry in the trap buffer and fills it with sensor related
7310 * data.
7311 *
7312 * Returns:
7313 * Nothing
7314 */
7315PNMI_STATIC void QueueSensorTrap(
7316SK_AC *pAC, /* Pointer to adapter context */
7317SK_U32 TrapId, /* Type of sensor trap */
7318unsigned int SensorIndex) /* Index of sensor which caused the trap */
7319{
7320 char *pBuf;
7321 unsigned int Offset;
7322 unsigned int DescrLen;
7323 SK_U32 Val32;
7324
7325
7326 /* Get trap buffer entry */
7327 DescrLen = SK_STRLEN(pAC->I2c.SenTable[SensorIndex].SenDesc);
7328 pBuf = GetTrapEntry(pAC, TrapId,
7329 SK_PNMI_TRAP_SENSOR_LEN_BASE + DescrLen);
7330 Offset = SK_PNMI_TRAP_SIMPLE_LEN;
7331
7332 /* Store additionally sensor trap related data */
7333 Val32 = OID_SKGE_SENSOR_INDEX;
7334 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
7335 *(pBuf + Offset + 4) = 4;
7336 Val32 = (SK_U32)SensorIndex;
7337 SK_PNMI_STORE_U32(pBuf + Offset + 5, Val32);
7338 Offset += 9;
7339
7340 Val32 = (SK_U32)OID_SKGE_SENSOR_DESCR;
7341 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
7342 *(pBuf + Offset + 4) = (char)DescrLen;
7343 SK_MEMCPY(pBuf + Offset + 5, pAC->I2c.SenTable[SensorIndex].SenDesc,
7344 DescrLen);
7345 Offset += DescrLen + 5;
7346
7347 Val32 = OID_SKGE_SENSOR_TYPE;
7348 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
7349 *(pBuf + Offset + 4) = 1;
7350 *(pBuf + Offset + 5) = (char)pAC->I2c.SenTable[SensorIndex].SenType;
7351 Offset += 6;
7352
7353 Val32 = OID_SKGE_SENSOR_VALUE;
7354 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
7355 *(pBuf + Offset + 4) = 4;
7356 Val32 = (SK_U32)pAC->I2c.SenTable[SensorIndex].SenValue;
7357 SK_PNMI_STORE_U32(pBuf + Offset + 5, Val32);
7358}
7359
7360/*****************************************************************************
7361 *
7362 * QueueRlmtNewMacTrap - Store a port switch trap in the trap buffer
7363 *
7364 * Description:
7365 * Nothing further to explain.
7366 *
7367 * Returns:
7368 * Nothing
7369 */
7370PNMI_STATIC void QueueRlmtNewMacTrap(
7371SK_AC *pAC, /* Pointer to adapter context */
7372unsigned int ActiveMac) /* Index (0..n) of the currently active port */
7373{
7374 char *pBuf;
7375 SK_U32 Val32;
7376
7377
7378 pBuf = GetTrapEntry(pAC, OID_SKGE_TRAP_RLMT_CHANGE_PORT,
7379 SK_PNMI_TRAP_RLMT_CHANGE_LEN);
7380
7381 Val32 = OID_SKGE_RLMT_PORT_ACTIVE;
7382 SK_PNMI_STORE_U32(pBuf + SK_PNMI_TRAP_SIMPLE_LEN, Val32);
7383 *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 4) = 1;
7384 *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 5) = (char)ActiveMac;
7385}
7386
7387/*****************************************************************************
7388 *
7389 * QueueRlmtPortTrap - Store port related RLMT trap to trap buffer
7390 *
7391 * Description:
7392 * Nothing further to explain.
7393 *
7394 * Returns:
7395 * Nothing
7396 */
7397PNMI_STATIC void QueueRlmtPortTrap(
7398SK_AC *pAC, /* Pointer to adapter context */
7399SK_U32 TrapId, /* Type of RLMT port trap */
7400unsigned int PortIndex) /* Index of the port, which changed its state */
7401{
7402 char *pBuf;
7403 SK_U32 Val32;
7404
7405
7406 pBuf = GetTrapEntry(pAC, TrapId, SK_PNMI_TRAP_RLMT_PORT_LEN);
7407
7408 Val32 = OID_SKGE_RLMT_PORT_INDEX;
7409 SK_PNMI_STORE_U32(pBuf + SK_PNMI_TRAP_SIMPLE_LEN, Val32);
7410 *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 4) = 1;
7411 *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 5) = (char)PortIndex;
7412}
7413
7414/*****************************************************************************
7415 *
7416 * CopyMac - Copies a MAC address
7417 *
7418 * Description:
7419 * Nothing further to explain.
7420 *
7421 * Returns:
7422 * Nothing
7423 */
7424PNMI_STATIC void CopyMac(
7425char *pDst, /* Pointer to destination buffer */
7426SK_MAC_ADDR *pMac) /* Pointer of Source */
7427{
7428 int i;
7429
7430
7431 for (i = 0; i < sizeof(SK_MAC_ADDR); i ++) {
7432
7433 *(pDst + i) = pMac->a[i];
7434 }
7435}
7436
7437#ifdef SK_POWER_MGMT
7438/*****************************************************************************
7439 *
7440 * PowerManagement - OID handler function of PowerManagement OIDs
7441 *
7442 * Description:
7443 * The code is simple. No description necessary.
7444 *
7445 * Returns:
7446 * SK_PNMI_ERR_OK The request was successfully performed.
7447 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
7448 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
7449 * the correct data (e.g. a 32bit value is
7450 * needed, but a 16 bit value was passed).
7451 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
7452 * exist (e.g. port instance 3 on a two port
7453 * adapter.
7454 */
7455
7456PNMI_STATIC int PowerManagement(
7457SK_AC *pAC, /* Pointer to adapter context */
7458SK_IOC IoC, /* IO context handle */
7459int Action, /* Get/PreSet/Set action */
7460SK_U32 Id, /* Object ID that is to be processed */
7461char *pBuf, /* Buffer to which to mgmt data will be retrieved */
7462unsigned int *pLen, /* On call: buffer length. On return: used buffer */
7463SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
7464unsigned int TableIndex, /* Index to the Id table */
7465SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
7466{
7467
7468 SK_U32 RetCode = SK_PNMI_ERR_GENERAL;
7469
7470 /*
7471 * Check instance. We only handle single instance variables
7472 */
7473 if (Instance != (SK_U32)(-1) && Instance != 1) {
7474
7475 *pLen = 0;
7476 return (SK_PNMI_ERR_UNKNOWN_INST);
7477 }
7478
7479
7480 /* Check length */
7481 switch (Id) {
7482
7483 case OID_PNP_CAPABILITIES:
7484 if (*pLen < sizeof(SK_PNP_CAPABILITIES)) {
7485
7486 *pLen = sizeof(SK_PNP_CAPABILITIES);
7487 return (SK_PNMI_ERR_TOO_SHORT);
7488 }
7489 break;
7490
7491 case OID_PNP_SET_POWER:
7492 case OID_PNP_QUERY_POWER:
7493 if (*pLen < sizeof(SK_DEVICE_POWER_STATE))
7494 {
7495 *pLen = sizeof(SK_DEVICE_POWER_STATE);
7496 return (SK_PNMI_ERR_TOO_SHORT);
7497 }
7498 break;
7499
7500 case OID_PNP_ADD_WAKE_UP_PATTERN:
7501 case OID_PNP_REMOVE_WAKE_UP_PATTERN:
7502 if (*pLen < sizeof(SK_PM_PACKET_PATTERN)) {
7503
7504 *pLen = sizeof(SK_PM_PACKET_PATTERN);
7505 return (SK_PNMI_ERR_TOO_SHORT);
7506 }
7507 break;
7508
7509 case OID_PNP_ENABLE_WAKE_UP:
7510 if (*pLen < sizeof(SK_U32)) {
7511
7512 *pLen = sizeof(SK_U32);
7513 return (SK_PNMI_ERR_TOO_SHORT);
7514 }
7515 break;
7516 }
7517
7518 /*
7519 * Perform action
7520 */
7521 if (Action == SK_PNMI_GET) {
7522
7523 /*
7524 * Get value
7525 */
7526 switch (Id) {
7527
7528 case OID_PNP_CAPABILITIES:
7529 RetCode = SkPowerQueryPnPCapabilities(pAC, IoC, pBuf, pLen);
7530 break;
7531
7532 case OID_PNP_QUERY_POWER:
7533 /* The Windows DDK describes: An OID_PNP_QUERY_POWER requests
7534 the miniport to indicate whether it can transition its NIC
7535 to the low-power state.
7536 A miniport driver must always return NDIS_STATUS_SUCCESS
7537 to a query of OID_PNP_QUERY_POWER. */
7538 *pLen = sizeof(SK_DEVICE_POWER_STATE);
7539 RetCode = SK_PNMI_ERR_OK;
7540 break;
7541
7542 /* NDIS handles these OIDs as write-only.
7543 * So in case of get action the buffer with written length = 0
7544 * is returned
7545 */
7546 case OID_PNP_SET_POWER:
7547 case OID_PNP_ADD_WAKE_UP_PATTERN:
7548 case OID_PNP_REMOVE_WAKE_UP_PATTERN:
7549 *pLen = 0;
7550 RetCode = SK_PNMI_ERR_NOT_SUPPORTED;
7551 break;
7552
7553 case OID_PNP_ENABLE_WAKE_UP:
7554 RetCode = SkPowerGetEnableWakeUp(pAC, IoC, pBuf, pLen);
7555 break;
7556
7557 default:
7558 RetCode = SK_PNMI_ERR_GENERAL;
7559 break;
7560 }
7561
7562 return (RetCode);
7563 }
7564
7565
7566 /*
7567 * Perform preset or set
7568 */
7569
7570 /* POWER module does not support PRESET action */
7571 if (Action == SK_PNMI_PRESET) {
7572 return (SK_PNMI_ERR_OK);
7573 }
7574
7575 switch (Id) {
7576 case OID_PNP_SET_POWER:
7577 RetCode = SkPowerSetPower(pAC, IoC, pBuf, pLen);
7578 break;
7579
7580 case OID_PNP_ADD_WAKE_UP_PATTERN:
7581 RetCode = SkPowerAddWakeUpPattern(pAC, IoC, pBuf, pLen);
7582 break;
7583
7584 case OID_PNP_REMOVE_WAKE_UP_PATTERN:
7585 RetCode = SkPowerRemoveWakeUpPattern(pAC, IoC, pBuf, pLen);
7586 break;
7587
7588 case OID_PNP_ENABLE_WAKE_UP:
7589 RetCode = SkPowerSetEnableWakeUp(pAC, IoC, pBuf, pLen);
7590 break;
7591
7592 default:
7593 RetCode = SK_PNMI_ERR_READ_ONLY;
7594 }
7595
7596 return (RetCode);
7597}
7598#endif /* SK_POWER_MGMT */
7599
7600#ifdef SK_DIAG_SUPPORT
7601/*****************************************************************************
7602 *
7603 * DiagActions - OID handler function of Diagnostic driver
7604 *
7605 * Description:
7606 * The code is simple. No description necessary.
7607 *
7608 * Returns:
7609 * SK_PNMI_ERR_OK The request was successfully performed.
7610 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
7611 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
7612 * the correct data (e.g. a 32bit value is
7613 * needed, but a 16 bit value was passed).
7614 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
7615 * exist (e.g. port instance 3 on a two port
7616 * adapter.
7617 */
7618
7619PNMI_STATIC int DiagActions(
7620SK_AC *pAC, /* Pointer to adapter context */
7621SK_IOC IoC, /* IO context handle */
7622int Action, /* GET/PRESET/SET action */
7623SK_U32 Id, /* Object ID that is to be processed */
7624char *pBuf, /* Buffer used for the management data transfer */
7625unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
7626SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
7627unsigned int TableIndex, /* Index to the Id table */
7628SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
7629{
7630
7631 SK_U32 DiagStatus;
7632 SK_U32 RetCode = SK_PNMI_ERR_GENERAL;
7633
7634 /*
7635 * Check instance. We only handle single instance variables.
7636 */
7637 if (Instance != (SK_U32)(-1) && Instance != 1) {
7638
7639 *pLen = 0;
7640 return (SK_PNMI_ERR_UNKNOWN_INST);
7641 }
7642
7643 /*
7644 * Check length.
7645 */
7646 switch (Id) {
7647
7648 case OID_SKGE_DIAG_MODE:
7649 if (*pLen < sizeof(SK_U32)) {
7650
7651 *pLen = sizeof(SK_U32);
7652 return (SK_PNMI_ERR_TOO_SHORT);
7653 }
7654 break;
7655
7656 default:
7657 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR040, SK_PNMI_ERR040MSG);
7658 *pLen = 0;
7659 return (SK_PNMI_ERR_GENERAL);
7660 }
7661
7662 /* Perform action. */
7663
7664 /* GET value. */
7665 if (Action == SK_PNMI_GET) {
7666
7667 switch (Id) {
7668
7669 case OID_SKGE_DIAG_MODE:
7670 DiagStatus = pAC->Pnmi.DiagAttached;
7671 SK_PNMI_STORE_U32(pBuf, DiagStatus);
7672 *pLen = sizeof(SK_U32);
7673 RetCode = SK_PNMI_ERR_OK;
7674 break;
7675
7676 default:
7677 *pLen = 0;
7678 RetCode = SK_PNMI_ERR_GENERAL;
7679 break;
7680 }
7681 return (RetCode);
7682 }
7683
7684 /* From here SET or PRESET value. */
7685
7686 /* PRESET value is not supported. */
7687 if (Action == SK_PNMI_PRESET) {
7688 return (SK_PNMI_ERR_OK);
7689 }
7690
7691 /* SET value. */
7692 switch (Id) {
7693 case OID_SKGE_DIAG_MODE:
7694
7695 /* Handle the SET. */
7696 switch (*pBuf) {
7697
7698 /* Attach the DIAG to this adapter. */
7699 case SK_DIAG_ATTACHED:
7700 /* Check if we come from running */
7701 if (pAC->Pnmi.DiagAttached == SK_DIAG_RUNNING) {
7702
7703 RetCode = SkDrvLeaveDiagMode(pAC);
7704
7705 }
7706 else if (pAC->Pnmi.DiagAttached == SK_DIAG_IDLE) {
7707
7708 RetCode = SK_PNMI_ERR_OK;
7709 }
7710
7711 else {
7712
7713 RetCode = SK_PNMI_ERR_GENERAL;
7714
7715 }
7716
7717 if (RetCode == SK_PNMI_ERR_OK) {
7718
7719 pAC->Pnmi.DiagAttached = SK_DIAG_ATTACHED;
7720 }
7721 break;
7722
7723 /* Enter the DIAG mode in the driver. */
7724 case SK_DIAG_RUNNING:
7725 RetCode = SK_PNMI_ERR_OK;
7726
7727 /*
7728 * If DiagAttached is set, we can tell the driver
7729 * to enter the DIAG mode.
7730 */
7731 if (pAC->Pnmi.DiagAttached == SK_DIAG_ATTACHED) {
7732 /* If DiagMode is not active, we can enter it. */
7733 if (!pAC->DiagModeActive) {
7734
7735 RetCode = SkDrvEnterDiagMode(pAC);
7736 }
7737 else {
7738
7739 RetCode = SK_PNMI_ERR_GENERAL;
7740 }
7741 }
7742 else {
7743
7744 RetCode = SK_PNMI_ERR_GENERAL;
7745 }
7746
7747 if (RetCode == SK_PNMI_ERR_OK) {
7748
7749 pAC->Pnmi.DiagAttached = SK_DIAG_RUNNING;
7750 }
7751 break;
7752
7753 case SK_DIAG_IDLE:
7754 /* Check if we come from running */
7755 if (pAC->Pnmi.DiagAttached == SK_DIAG_RUNNING) {
7756
7757 RetCode = SkDrvLeaveDiagMode(pAC);
7758
7759 }
7760 else if (pAC->Pnmi.DiagAttached == SK_DIAG_ATTACHED) {
7761
7762 RetCode = SK_PNMI_ERR_OK;
7763 }
7764
7765 else {
7766
7767 RetCode = SK_PNMI_ERR_GENERAL;
7768
7769 }
7770
7771 if (RetCode == SK_PNMI_ERR_OK) {
7772
7773 pAC->Pnmi.DiagAttached = SK_DIAG_IDLE;
7774 }
7775 break;
7776
7777 default:
7778 RetCode = SK_PNMI_ERR_BAD_VALUE;
7779 break;
7780 }
7781 break;
7782
7783 default:
7784 RetCode = SK_PNMI_ERR_GENERAL;
7785 }
7786
7787 if (RetCode == SK_PNMI_ERR_OK) {
7788 *pLen = sizeof(SK_U32);
7789 }
7790 else {
7791
7792 *pLen = 0;
7793 }
7794 return (RetCode);
7795}
7796#endif /* SK_DIAG_SUPPORT */
7797
7798/*****************************************************************************
7799 *
7800 * Vct - OID handler function of OIDs
7801 *
7802 * Description:
7803 * The code is simple. No description necessary.
7804 *
7805 * Returns:
7806 * SK_PNMI_ERR_OK The request was performed successfully.
7807 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
7808 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
7809 * the correct data (e.g. a 32bit value is
7810 * needed, but a 16 bit value was passed).
7811 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
7812 * exist (e.g. port instance 3 on a two port
7813 * adapter).
7814 * SK_PNMI_ERR_READ_ONLY Only the Get action is allowed.
7815 *
7816 */
7817
7818PNMI_STATIC int Vct(
7819SK_AC *pAC, /* Pointer to adapter context */
7820SK_IOC IoC, /* IO context handle */
7821int Action, /* GET/PRESET/SET action */
7822SK_U32 Id, /* Object ID that is to be processed */
7823char *pBuf, /* Buffer used for the management data transfer */
7824unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
7825SK_U32 Instance, /* Instance (-1,2..n) that is to be queried */
7826unsigned int TableIndex, /* Index to the Id table */
7827SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
7828{
7829 SK_GEPORT *pPrt;
7830 SK_PNMI_VCT *pVctBackupData;
7831 SK_U32 LogPortMax;
7832 SK_U32 PhysPortMax;
7833 SK_U32 PhysPortIndex;
7834 SK_U32 Limit;
7835 SK_U32 Offset;
7836 SK_BOOL Link;
7837 SK_U32 RetCode = SK_PNMI_ERR_GENERAL;
7838 int i;
7839 SK_EVPARA Para;
7840 SK_U32 CableLength;
7841
7842 /*
7843 * Calculate the port indexes from the instance.
7844 */
7845 PhysPortMax = pAC->GIni.GIMacsFound;
7846 LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
7847
7848 /* Dual net mode? */
7849 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
7850 LogPortMax--;
7851 }
7852
7853 if ((Instance != (SK_U32) (-1))) {
7854 /* Check instance range. */
7855 if ((Instance < 2) || (Instance > LogPortMax)) {
7856 *pLen = 0;
7857 return (SK_PNMI_ERR_UNKNOWN_INST);
7858 }
7859
7860 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
7861 PhysPortIndex = NetIndex;
7862 }
7863 else {
7864 PhysPortIndex = Instance - 2;
7865 }
7866 Limit = PhysPortIndex + 1;
7867 }
7868 else {
7869 /*
7870 * Instance == (SK_U32) (-1), get all Instances of that OID.
7871 *
7872 * Not implemented yet. May be used in future releases.
7873 */
7874 PhysPortIndex = 0;
7875 Limit = PhysPortMax;
7876 }
7877
7878 pPrt = &pAC->GIni.GP[PhysPortIndex];
7879 if (pPrt->PHWLinkUp) {
7880 Link = SK_TRUE;
7881 }
7882 else {
7883 Link = SK_FALSE;
7884 }
7885
7886 /* Check MAC type */
7887 if (pPrt->PhyType != SK_PHY_MARV_COPPER) {
7888 *pLen = 0;
7889 return (SK_PNMI_ERR_GENERAL);
7890 }
7891
7892 /* Initialize backup data pointer. */
7893 pVctBackupData = &pAC->Pnmi.VctBackup[PhysPortIndex];
7894
7895 /* Check action type */
7896 if (Action == SK_PNMI_GET) {
7897 /* Check length */
7898 switch (Id) {
7899
7900 case OID_SKGE_VCT_GET:
7901 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_PNMI_VCT)) {
7902 *pLen = (Limit - PhysPortIndex) * sizeof(SK_PNMI_VCT);
7903 return (SK_PNMI_ERR_TOO_SHORT);
7904 }
7905 break;
7906
7907 case OID_SKGE_VCT_STATUS:
7908 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U8)) {
7909 *pLen = (Limit - PhysPortIndex) * sizeof(SK_U8);
7910 return (SK_PNMI_ERR_TOO_SHORT);
7911 }
7912 break;
7913
7914 default:
7915 *pLen = 0;
7916 return (SK_PNMI_ERR_GENERAL);
7917 }
7918
7919 /* Get value */
7920 Offset = 0;
7921 for (; PhysPortIndex < Limit; PhysPortIndex++) {
7922 switch (Id) {
7923
7924 case OID_SKGE_VCT_GET:
7925 if ((Link == SK_FALSE) &&
7926 (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING)) {
7927 RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_FALSE);
7928 if (RetCode == 0) {
7929 pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_PENDING;
7930 pAC->Pnmi.VctStatus[PhysPortIndex] |=
7931 (SK_PNMI_VCT_NEW_VCT_DATA | SK_PNMI_VCT_TEST_DONE);
7932
7933 /* Copy results for later use to PNMI struct. */
7934 for (i = 0; i < 4; i++) {
7935 if (pPrt->PMdiPairSts[i] == SK_PNMI_VCT_NORMAL_CABLE) {
7936 if ((pPrt->PMdiPairLen[i] > 35) && (pPrt->PMdiPairLen[i] < 0xff)) {
7937 pPrt->PMdiPairSts[i] = SK_PNMI_VCT_IMPEDANCE_MISMATCH;
7938 }
7939 }
7940 if ((pPrt->PMdiPairLen[i] > 35) && (pPrt->PMdiPairLen[i] != 0xff)) {
7941 CableLength = 1000 * (((175 * pPrt->PMdiPairLen[i]) / 210) - 28);
7942 }
7943 else {
7944 CableLength = 0;
7945 }
7946 pVctBackupData->PMdiPairLen[i] = CableLength;
7947 pVctBackupData->PMdiPairSts[i] = pPrt->PMdiPairSts[i];
7948 }
7949
7950 Para.Para32[0] = PhysPortIndex;
7951 Para.Para32[1] = -1;
7952 SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Para);
7953 SkEventDispatcher(pAC, IoC);
7954 }
7955 else {
7956 ; /* VCT test is running. */
7957 }
7958 }
7959
7960 /* Get all results. */
7961 CheckVctStatus(pAC, IoC, pBuf, Offset, PhysPortIndex);
7962 Offset += sizeof(SK_U8);
7963 *(pBuf + Offset) = pPrt->PCableLen;
7964 Offset += sizeof(SK_U8);
7965 for (i = 0; i < 4; i++) {
7966 SK_PNMI_STORE_U32((pBuf + Offset), pVctBackupData->PMdiPairLen[i]);
7967 Offset += sizeof(SK_U32);
7968 }
7969 for (i = 0; i < 4; i++) {
7970 *(pBuf + Offset) = pVctBackupData->PMdiPairSts[i];
7971 Offset += sizeof(SK_U8);
7972 }
7973
7974 RetCode = SK_PNMI_ERR_OK;
7975 break;
7976
7977 case OID_SKGE_VCT_STATUS:
7978 CheckVctStatus(pAC, IoC, pBuf, Offset, PhysPortIndex);
7979 Offset += sizeof(SK_U8);
7980 RetCode = SK_PNMI_ERR_OK;
7981 break;
7982
7983 default:
7984 *pLen = 0;
7985 return (SK_PNMI_ERR_GENERAL);
7986 }
7987 } /* for */
7988 *pLen = Offset;
7989 return (RetCode);
7990
7991 } /* if SK_PNMI_GET */
7992
7993 /*
7994 * From here SET or PRESET action. Check if the passed
7995 * buffer length is plausible.
7996 */
7997
7998 /* Check length */
7999 switch (Id) {
8000 case OID_SKGE_VCT_SET:
8001 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U32)) {
8002 *pLen = (Limit - PhysPortIndex) * sizeof(SK_U32);
8003 return (SK_PNMI_ERR_TOO_SHORT);
8004 }
8005 break;
8006
8007 default:
8008 *pLen = 0;
8009 return (SK_PNMI_ERR_GENERAL);
8010 }
8011
8012 /*
8013 * Perform preset or set.
8014 */
8015
8016 /* VCT does not support PRESET action. */
8017 if (Action == SK_PNMI_PRESET) {
8018 return (SK_PNMI_ERR_OK);
8019 }
8020
8021 Offset = 0;
8022 for (; PhysPortIndex < Limit; PhysPortIndex++) {
8023 switch (Id) {
8024 case OID_SKGE_VCT_SET: /* Start VCT test. */
8025 if (Link == SK_FALSE) {
8026 SkGeStopPort(pAC, IoC, PhysPortIndex, SK_STOP_ALL, SK_SOFT_RST);
8027
8028 RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_TRUE);
8029 if (RetCode == 0) { /* RetCode: 0 => Start! */
8030 pAC->Pnmi.VctStatus[PhysPortIndex] |= SK_PNMI_VCT_PENDING;
8031 pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_NEW_VCT_DATA;
8032 pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_LINK;
8033
8034 /*
8035 * Start VCT timer counter.
8036 */
8037 SK_MEMSET((char *) &Para, 0, sizeof(Para));
8038 Para.Para32[0] = PhysPortIndex;
8039 Para.Para32[1] = -1;
8040 SkTimerStart(pAC, IoC, &pAC->Pnmi.VctTimeout[PhysPortIndex].VctTimer,
8041 4000000, SKGE_PNMI, SK_PNMI_EVT_VCT_RESET, Para);
8042 SK_PNMI_STORE_U32((pBuf + Offset), RetCode);
8043 RetCode = SK_PNMI_ERR_OK;
8044 }
8045 else { /* RetCode: 2 => Running! */
8046 SK_PNMI_STORE_U32((pBuf + Offset), RetCode);
8047 RetCode = SK_PNMI_ERR_OK;
8048 }
8049 }
8050 else { /* RetCode: 4 => Link! */
8051 RetCode = 4;
8052 SK_PNMI_STORE_U32((pBuf + Offset), RetCode);
8053 RetCode = SK_PNMI_ERR_OK;
8054 }
8055 Offset += sizeof(SK_U32);
8056 break;
8057
8058 default:
8059 *pLen = 0;
8060 return (SK_PNMI_ERR_GENERAL);
8061 }
8062 } /* for */
8063 *pLen = Offset;
8064 return (RetCode);
8065
8066} /* Vct */
8067
8068
8069PNMI_STATIC void CheckVctStatus(
8070SK_AC *pAC,
8071SK_IOC IoC,
8072char *pBuf,
8073SK_U32 Offset,
8074SK_U32 PhysPortIndex)
8075{
8076 SK_GEPORT *pPrt;
8077 SK_PNMI_VCT *pVctData;
8078 SK_U32 RetCode;
8079
8080 pPrt = &pAC->GIni.GP[PhysPortIndex];
8081
8082 pVctData = (SK_PNMI_VCT *) (pBuf + Offset);
8083 pVctData->VctStatus = SK_PNMI_VCT_NONE;
8084
8085 if (!pPrt->PHWLinkUp) {
8086
8087 /* Was a VCT test ever made before? */
8088 if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_TEST_DONE) {
8089 if ((pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_LINK)) {
8090 pVctData->VctStatus |= SK_PNMI_VCT_OLD_VCT_DATA;
8091 }
8092 else {
8093 pVctData->VctStatus |= SK_PNMI_VCT_NEW_VCT_DATA;
8094 }
8095 }
8096
8097 /* Check VCT test status. */
8098 RetCode = SkGmCableDiagStatus(pAC,IoC, PhysPortIndex, SK_FALSE);
8099 if (RetCode == 2) { /* VCT test is running. */
8100 pVctData->VctStatus |= SK_PNMI_VCT_RUNNING;
8101 }
8102 else { /* VCT data was copied to pAC here. Check PENDING state. */
8103 if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING) {
8104 pVctData->VctStatus |= SK_PNMI_VCT_NEW_VCT_DATA;
8105 }
8106 }
8107
8108 if (pPrt->PCableLen != 0xff) { /* Old DSP value. */
8109 pVctData->VctStatus |= SK_PNMI_VCT_OLD_DSP_DATA;
8110 }
8111 }
8112 else {
8113
8114 /* Was a VCT test ever made before? */
8115 if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_TEST_DONE) {
8116 pVctData->VctStatus &= ~SK_PNMI_VCT_NEW_VCT_DATA;
8117 pVctData->VctStatus |= SK_PNMI_VCT_OLD_VCT_DATA;
8118 }
8119
8120 /* DSP only valid in 100/1000 modes. */
8121 if (pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed !=
8122 SK_LSPEED_STAT_10MBPS) {
8123 pVctData->VctStatus |= SK_PNMI_VCT_NEW_DSP_DATA;
8124 }
8125 }
8126} /* CheckVctStatus */
8127
8128
8129/*****************************************************************************
8130 *
8131 * SkPnmiGenIoctl - Handles new generic PNMI IOCTL, calls the needed
8132 * PNMI function depending on the subcommand and
8133 * returns all data belonging to the complete database
8134 * or OID request.
8135 *
8136 * Description:
8137 * Looks up the requested subcommand, calls the corresponding handler
8138 * function and passes all required parameters to it.
8139 * The function is called by the driver. It is needed to handle the new
8140 * generic PNMI IOCTL. This IOCTL is given to the driver and contains both
8141 * the OID and a subcommand to decide what kind of request has to be done.
8142 *
8143 * Returns:
8144 * SK_PNMI_ERR_OK The request was successfully performed
8145 * SK_PNMI_ERR_GENERAL A general severe internal error occured
8146 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to take
8147 * the data.
8148 * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown
8149 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
8150 * exist (e.g. port instance 3 on a two port
8151 * adapter.
8152 */
8153int SkPnmiGenIoctl(
8154SK_AC *pAC, /* Pointer to adapter context struct */
8155SK_IOC IoC, /* I/O context */
8156void *pBuf, /* Buffer used for the management data transfer */
8157unsigned int *pLen, /* Length of buffer */
8158SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
8159{
8160SK_I32 Mode; /* Store value of subcommand. */
8161SK_U32 Oid; /* Store value of OID. */
8162int ReturnCode; /* Store return value to show status of PNMI action. */
8163int HeaderLength; /* Length of desired action plus OID. */
8164
8165 ReturnCode = SK_PNMI_ERR_GENERAL;
8166
8167 SK_MEMCPY(&Mode, pBuf, sizeof(SK_I32));
8168 SK_MEMCPY(&Oid, (char *) pBuf + sizeof(SK_I32), sizeof(SK_U32));
8169 HeaderLength = sizeof(SK_I32) + sizeof(SK_U32);
8170 *pLen = *pLen - HeaderLength;
8171 SK_MEMCPY((char *) pBuf + sizeof(SK_I32), (char *) pBuf + HeaderLength, *pLen);
8172
8173 switch(Mode) {
8174 case SK_GET_SINGLE_VAR:
8175 ReturnCode = SkPnmiGetVar(pAC, IoC, Oid,
8176 (char *) pBuf + sizeof(SK_I32), pLen,
8177 ((SK_U32) (-1)), NetIndex);
8178 SK_PNMI_STORE_U32(pBuf, ReturnCode);
8179 *pLen = *pLen + sizeof(SK_I32);
8180 break;
8181 case SK_PRESET_SINGLE_VAR:
8182 ReturnCode = SkPnmiPreSetVar(pAC, IoC, Oid,
8183 (char *) pBuf + sizeof(SK_I32), pLen,
8184 ((SK_U32) (-1)), NetIndex);
8185 SK_PNMI_STORE_U32(pBuf, ReturnCode);
8186 *pLen = *pLen + sizeof(SK_I32);
8187 break;
8188 case SK_SET_SINGLE_VAR:
8189 ReturnCode = SkPnmiSetVar(pAC, IoC, Oid,
8190 (char *) pBuf + sizeof(SK_I32), pLen,
8191 ((SK_U32) (-1)), NetIndex);
8192 SK_PNMI_STORE_U32(pBuf, ReturnCode);
8193 *pLen = *pLen + sizeof(SK_I32);
8194 break;
8195 case SK_GET_FULL_MIB:
8196 ReturnCode = SkPnmiGetStruct(pAC, IoC, pBuf, pLen, NetIndex);
8197 break;
8198 case SK_PRESET_FULL_MIB:
8199 ReturnCode = SkPnmiPreSetStruct(pAC, IoC, pBuf, pLen, NetIndex);
8200 break;
8201 case SK_SET_FULL_MIB:
8202 ReturnCode = SkPnmiSetStruct(pAC, IoC, pBuf, pLen, NetIndex);
8203 break;
8204 default:
8205 break;
8206 }
8207
8208 return (ReturnCode);
8209
8210} /* SkGeIocGen */
diff --git a/drivers/net/sk98lin/skgesirq.c b/drivers/net/sk98lin/skgesirq.c
deleted file mode 100644
index 3e7aa49afd00..000000000000
--- a/drivers/net/sk98lin/skgesirq.c
+++ /dev/null
@@ -1,2229 +0,0 @@
1/******************************************************************************
2 *
3 * Name: skgesirq.c
4 * Project: Gigabit Ethernet Adapters, Common Modules
5 * Version: $Revision: 1.92 $
6 * Date: $Date: 2003/09/16 14:37:07 $
7 * Purpose: Special IRQ module
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25/*
26 * Special Interrupt handler
27 *
28 * The following abstract should show how this module is included
29 * in the driver path:
30 *
31 * In the ISR of the driver the bits for frame transmission complete and
32 * for receive complete are checked and handled by the driver itself.
33 * The bits of the slow path mask are checked after that and then the
34 * entry into the so-called "slow path" is prepared. It is an implementors
35 * decision whether this is executed directly or just scheduled by
36 * disabling the mask. In the interrupt service routine some events may be
37 * generated, so it would be a good idea to call the EventDispatcher
38 * right after this ISR.
39 *
40 * The Interrupt source register of the adapter is NOT read by this module.
41 * SO if the drivers implementor needs a while loop around the
42 * slow data paths interrupt bits, he needs to call the SkGeSirqIsr() for
43 * each loop entered.
44 *
45 * However, the MAC Interrupt status registers are read in a while loop.
46 *
47 */
48
49#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
50static const char SysKonnectFileId[] =
51 "@(#) $Id: skgesirq.c,v 1.92 2003/09/16 14:37:07 rschmidt Exp $ (C) Marvell.";
52#endif
53
54#include "h/skdrv1st.h" /* Driver Specific Definitions */
55#ifndef SK_SLIM
56#include "h/skgepnmi.h" /* PNMI Definitions */
57#include "h/skrlmt.h" /* RLMT Definitions */
58#endif
59#include "h/skdrv2nd.h" /* Adapter Control and Driver specific Def. */
60
61/* local function prototypes */
62#ifdef GENESIS
63static int SkGePortCheckUpXmac(SK_AC*, SK_IOC, int, SK_BOOL);
64static int SkGePortCheckUpBcom(SK_AC*, SK_IOC, int, SK_BOOL);
65static void SkPhyIsrBcom(SK_AC*, SK_IOC, int, SK_U16);
66#endif /* GENESIS */
67#ifdef YUKON
68static int SkGePortCheckUpGmac(SK_AC*, SK_IOC, int, SK_BOOL);
69static void SkPhyIsrGmac(SK_AC*, SK_IOC, int, SK_U16);
70#endif /* YUKON */
71#ifdef OTHER_PHY
72static int SkGePortCheckUpLone(SK_AC*, SK_IOC, int, SK_BOOL);
73static int SkGePortCheckUpNat(SK_AC*, SK_IOC, int, SK_BOOL);
74static void SkPhyIsrLone(SK_AC*, SK_IOC, int, SK_U16);
75#endif /* OTHER_PHY */
76
77#ifdef GENESIS
78/*
79 * array of Rx counter from XMAC which are checked
80 * in AutoSense mode to check whether a link is not able to auto-negotiate.
81 */
82static const SK_U16 SkGeRxRegs[]= {
83 XM_RXF_64B,
84 XM_RXF_127B,
85 XM_RXF_255B,
86 XM_RXF_511B,
87 XM_RXF_1023B,
88 XM_RXF_MAX_SZ
89} ;
90#endif /* GENESIS */
91
92#ifdef __C2MAN__
93/*
94 * Special IRQ function
95 *
96 * General Description:
97 *
98 */
99intro()
100{}
101#endif
102
103/******************************************************************************
104 *
105 * SkHWInitDefSense() - Default Autosensing mode initialization
106 *
107 * Description: sets the PLinkMode for HWInit
108 *
109 * Returns: N/A
110 */
111static void SkHWInitDefSense(
112SK_AC *pAC, /* adapter context */
113SK_IOC IoC, /* IO context */
114int Port) /* Port Index (MAC_1 + n) */
115{
116 SK_GEPORT *pPrt; /* GIni Port struct pointer */
117
118 pPrt = &pAC->GIni.GP[Port];
119
120 pPrt->PAutoNegTimeOut = 0;
121
122 if (pPrt->PLinkModeConf != SK_LMODE_AUTOSENSE) {
123 pPrt->PLinkMode = pPrt->PLinkModeConf;
124 return;
125 }
126
127 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
128 ("AutoSensing: First mode %d on Port %d\n",
129 (int)SK_LMODE_AUTOFULL, Port));
130
131 pPrt->PLinkMode = (SK_U8)SK_LMODE_AUTOFULL;
132
133 return;
134} /* SkHWInitDefSense */
135
136
137#ifdef GENESIS
138/******************************************************************************
139 *
140 * SkHWSenseGetNext() - Get Next Autosensing Mode
141 *
142 * Description: gets the appropriate next mode
143 *
144 * Note:
145 *
146 */
147static SK_U8 SkHWSenseGetNext(
148SK_AC *pAC, /* adapter context */
149SK_IOC IoC, /* IO context */
150int Port) /* Port Index (MAC_1 + n) */
151{
152 SK_GEPORT *pPrt; /* GIni Port struct pointer */
153
154 pPrt = &pAC->GIni.GP[Port];
155
156 pPrt->PAutoNegTimeOut = 0;
157
158 if (pPrt->PLinkModeConf != (SK_U8)SK_LMODE_AUTOSENSE) {
159 /* Leave all as configured */
160 return(pPrt->PLinkModeConf);
161 }
162
163 if (pPrt->PLinkMode == (SK_U8)SK_LMODE_AUTOFULL) {
164 /* Return next mode AUTOBOTH */
165 return ((SK_U8)SK_LMODE_AUTOBOTH);
166 }
167
168 /* Return default autofull */
169 return ((SK_U8)SK_LMODE_AUTOFULL);
170} /* SkHWSenseGetNext */
171
172
173/******************************************************************************
174 *
175 * SkHWSenseSetNext() - Autosensing Set next mode
176 *
177 * Description: sets the appropriate next mode
178 *
179 * Returns: N/A
180 */
181static void SkHWSenseSetNext(
182SK_AC *pAC, /* adapter context */
183SK_IOC IoC, /* IO context */
184int Port, /* Port Index (MAC_1 + n) */
185SK_U8 NewMode) /* New Mode to be written in sense mode */
186{
187 SK_GEPORT *pPrt; /* GIni Port struct pointer */
188
189 pPrt = &pAC->GIni.GP[Port];
190
191 pPrt->PAutoNegTimeOut = 0;
192
193 if (pPrt->PLinkModeConf != (SK_U8)SK_LMODE_AUTOSENSE) {
194 return;
195 }
196
197 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
198 ("AutoSensing: next mode %d on Port %d\n",
199 (int)NewMode, Port));
200
201 pPrt->PLinkMode = NewMode;
202
203 return;
204} /* SkHWSenseSetNext */
205#endif /* GENESIS */
206
207
208/******************************************************************************
209 *
210 * SkHWLinkDown() - Link Down handling
211 *
212 * Description: handles the hardware link down signal
213 *
214 * Returns: N/A
215 */
216void SkHWLinkDown(
217SK_AC *pAC, /* adapter context */
218SK_IOC IoC, /* IO context */
219int Port) /* Port Index (MAC_1 + n) */
220{
221 SK_GEPORT *pPrt; /* GIni Port struct pointer */
222
223 pPrt = &pAC->GIni.GP[Port];
224
225 /* Disable all MAC interrupts */
226 SkMacIrqDisable(pAC, IoC, Port);
227
228 /* Disable Receiver and Transmitter */
229 SkMacRxTxDisable(pAC, IoC, Port);
230
231 /* Init default sense mode */
232 SkHWInitDefSense(pAC, IoC, Port);
233
234 if (pPrt->PHWLinkUp == SK_FALSE) {
235 return;
236 }
237
238 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
239 ("Link down Port %d\n", Port));
240
241 /* Set Link to DOWN */
242 pPrt->PHWLinkUp = SK_FALSE;
243
244 /* Reset Port stati */
245 pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_UNKNOWN;
246 pPrt->PFlowCtrlStatus = (SK_U8)SK_FLOW_STAT_NONE;
247 pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_INDETERMINATED;
248
249 /* Re-init Phy especially when the AutoSense default is set now */
250 SkMacInitPhy(pAC, IoC, Port, SK_FALSE);
251
252 /* GP0: used for workaround of Rev. C Errata 2 */
253
254 /* Do NOT signal to RLMT */
255
256 /* Do NOT start the timer here */
257} /* SkHWLinkDown */
258
259
260/******************************************************************************
261 *
262 * SkHWLinkUp() - Link Up handling
263 *
264 * Description: handles the hardware link up signal
265 *
266 * Returns: N/A
267 */
268static void SkHWLinkUp(
269SK_AC *pAC, /* adapter context */
270SK_IOC IoC, /* IO context */
271int Port) /* Port Index (MAC_1 + n) */
272{
273 SK_GEPORT *pPrt; /* GIni Port struct pointer */
274
275 pPrt = &pAC->GIni.GP[Port];
276
277 if (pPrt->PHWLinkUp) {
278 /* We do NOT need to proceed on active link */
279 return;
280 }
281
282 pPrt->PHWLinkUp = SK_TRUE;
283 pPrt->PAutoNegFail = SK_FALSE;
284 pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_UNKNOWN;
285
286 if (pPrt->PLinkMode != (SK_U8)SK_LMODE_AUTOHALF &&
287 pPrt->PLinkMode != (SK_U8)SK_LMODE_AUTOFULL &&
288 pPrt->PLinkMode != (SK_U8)SK_LMODE_AUTOBOTH) {
289 /* Link is up and no Auto-negotiation should be done */
290
291 /* Link speed should be the configured one */
292 switch (pPrt->PLinkSpeed) {
293 case SK_LSPEED_AUTO:
294 /* default is 1000 Mbps */
295 case SK_LSPEED_1000MBPS:
296 pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_1000MBPS;
297 break;
298 case SK_LSPEED_100MBPS:
299 pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_100MBPS;
300 break;
301 case SK_LSPEED_10MBPS:
302 pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_10MBPS;
303 break;
304 }
305
306 /* Set Link Mode Status */
307 if (pPrt->PLinkMode == SK_LMODE_FULL) {
308 pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_FULL;
309 }
310 else {
311 pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_HALF;
312 }
313
314 /* No flow control without auto-negotiation */
315 pPrt->PFlowCtrlStatus = (SK_U8)SK_FLOW_STAT_NONE;
316
317 /* enable Rx/Tx */
318 (void)SkMacRxTxEnable(pAC, IoC, Port);
319 }
320} /* SkHWLinkUp */
321
322
323/******************************************************************************
324 *
325 * SkMacParity() - MAC parity workaround
326 *
327 * Description: handles MAC parity errors correctly
328 *
329 * Returns: N/A
330 */
331static void SkMacParity(
332SK_AC *pAC, /* adapter context */
333SK_IOC IoC, /* IO context */
334int Port) /* Port Index of the port failed */
335{
336 SK_EVPARA Para;
337 SK_GEPORT *pPrt; /* GIni Port struct pointer */
338 SK_U32 TxMax; /* Tx Max Size Counter */
339
340 pPrt = &pAC->GIni.GP[Port];
341
342 /* Clear IRQ Tx Parity Error */
343#ifdef GENESIS
344 if (pAC->GIni.GIGenesis) {
345
346 SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_CLR_PERR);
347 }
348#endif /* GENESIS */
349
350#ifdef YUKON
351 if (pAC->GIni.GIYukon) {
352 /* HW-Bug #8: cleared by GMF_CLI_TX_FC instead of GMF_CLI_TX_PE */
353 SK_OUT8(IoC, MR_ADDR(Port, TX_GMF_CTRL_T),
354 (SK_U8)((pAC->GIni.GIChipId == CHIP_ID_YUKON &&
355 pAC->GIni.GIChipRev == 0) ? GMF_CLI_TX_FC : GMF_CLI_TX_PE));
356 }
357#endif /* YUKON */
358
359 if (pPrt->PCheckPar) {
360
361 if (Port == MAC_1) {
362 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E016, SKERR_SIRQ_E016MSG);
363 }
364 else {
365 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E017, SKERR_SIRQ_E017MSG);
366 }
367 Para.Para64 = Port;
368 SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
369
370 Para.Para32[0] = Port;
371 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
372
373 return;
374 }
375
376 /* Check whether frames with a size of 1k were sent */
377#ifdef GENESIS
378 if (pAC->GIni.GIGenesis) {
379 /* Snap statistic counters */
380 (void)SkXmUpdateStats(pAC, IoC, Port);
381
382 (void)SkXmMacStatistic(pAC, IoC, Port, XM_TXF_MAX_SZ, &TxMax);
383 }
384#endif /* GENESIS */
385
386#ifdef YUKON
387 if (pAC->GIni.GIYukon) {
388
389 (void)SkGmMacStatistic(pAC, IoC, Port, GM_TXF_1518B, &TxMax);
390 }
391#endif /* YUKON */
392
393 if (TxMax > 0) {
394 /* From now on check the parity */
395 pPrt->PCheckPar = SK_TRUE;
396 }
397} /* SkMacParity */
398
399
400/******************************************************************************
401 *
402 * SkGeHwErr() - Hardware Error service routine
403 *
404 * Description: handles all HW Error interrupts
405 *
406 * Returns: N/A
407 */
408static void SkGeHwErr(
409SK_AC *pAC, /* adapter context */
410SK_IOC IoC, /* IO context */
411SK_U32 HwStatus) /* Interrupt status word */
412{
413 SK_EVPARA Para;
414 SK_U16 Word;
415
416 if ((HwStatus & (IS_IRQ_MST_ERR | IS_IRQ_STAT)) != 0) {
417 /* PCI Errors occured */
418 if ((HwStatus & IS_IRQ_STAT) != 0) {
419 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E013, SKERR_SIRQ_E013MSG);
420 }
421 else {
422 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E012, SKERR_SIRQ_E012MSG);
423 }
424
425 /* Reset all bits in the PCI STATUS register */
426 SK_IN16(IoC, PCI_C(PCI_STATUS), &Word);
427
428 SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON);
429 SK_OUT16(IoC, PCI_C(PCI_STATUS), (SK_U16)(Word | PCI_ERRBITS));
430 SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
431
432 Para.Para64 = 0;
433 SkEventQueue(pAC, SKGE_DRV, SK_DRV_ADAP_FAIL, Para);
434 }
435
436#ifdef GENESIS
437 if (pAC->GIni.GIGenesis) {
438
439 if ((HwStatus & IS_NO_STAT_M1) != 0) {
440 /* Ignore it */
441 /* This situation is also indicated in the descriptor */
442 SK_OUT16(IoC, MR_ADDR(MAC_1, RX_MFF_CTRL1), MFF_CLR_INSTAT);
443 }
444
445 if ((HwStatus & IS_NO_STAT_M2) != 0) {
446 /* Ignore it */
447 /* This situation is also indicated in the descriptor */
448 SK_OUT16(IoC, MR_ADDR(MAC_2, RX_MFF_CTRL1), MFF_CLR_INSTAT);
449 }
450
451 if ((HwStatus & IS_NO_TIST_M1) != 0) {
452 /* Ignore it */
453 /* This situation is also indicated in the descriptor */
454 SK_OUT16(IoC, MR_ADDR(MAC_1, RX_MFF_CTRL1), MFF_CLR_INTIST);
455 }
456
457 if ((HwStatus & IS_NO_TIST_M2) != 0) {
458 /* Ignore it */
459 /* This situation is also indicated in the descriptor */
460 SK_OUT16(IoC, MR_ADDR(MAC_2, RX_MFF_CTRL1), MFF_CLR_INTIST);
461 }
462 }
463#endif /* GENESIS */
464
465#ifdef YUKON
466 if (pAC->GIni.GIYukon) {
467 /* This is necessary only for Rx timing measurements */
468 if ((HwStatus & IS_IRQ_TIST_OV) != 0) {
469 /* increment Time Stamp Timer counter (high) */
470 pAC->GIni.GITimeStampCnt++;
471
472 /* Clear Time Stamp Timer IRQ */
473 SK_OUT8(IoC, GMAC_TI_ST_CTRL, (SK_U8)GMT_ST_CLR_IRQ);
474 }
475
476 if ((HwStatus & IS_IRQ_SENSOR) != 0) {
477 /* no sensors on 32-bit Yukon */
478 if (pAC->GIni.GIYukon32Bit) {
479 /* disable HW Error IRQ */
480 pAC->GIni.GIValIrqMask &= ~IS_HW_ERR;
481 }
482 }
483 }
484#endif /* YUKON */
485
486 if ((HwStatus & IS_RAM_RD_PAR) != 0) {
487 SK_OUT16(IoC, B3_RI_CTRL, RI_CLR_RD_PERR);
488 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E014, SKERR_SIRQ_E014MSG);
489 Para.Para64 = 0;
490 SkEventQueue(pAC, SKGE_DRV, SK_DRV_ADAP_FAIL, Para);
491 }
492
493 if ((HwStatus & IS_RAM_WR_PAR) != 0) {
494 SK_OUT16(IoC, B3_RI_CTRL, RI_CLR_WR_PERR);
495 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E015, SKERR_SIRQ_E015MSG);
496 Para.Para64 = 0;
497 SkEventQueue(pAC, SKGE_DRV, SK_DRV_ADAP_FAIL, Para);
498 }
499
500 if ((HwStatus & IS_M1_PAR_ERR) != 0) {
501 SkMacParity(pAC, IoC, MAC_1);
502 }
503
504 if ((HwStatus & IS_M2_PAR_ERR) != 0) {
505 SkMacParity(pAC, IoC, MAC_2);
506 }
507
508 if ((HwStatus & IS_R1_PAR_ERR) != 0) {
509 /* Clear IRQ */
510 SK_OUT32(IoC, B0_R1_CSR, CSR_IRQ_CL_P);
511
512 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E018, SKERR_SIRQ_E018MSG);
513 Para.Para64 = MAC_1;
514 SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
515
516 Para.Para32[0] = MAC_1;
517 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
518 }
519
520 if ((HwStatus & IS_R2_PAR_ERR) != 0) {
521 /* Clear IRQ */
522 SK_OUT32(IoC, B0_R2_CSR, CSR_IRQ_CL_P);
523
524 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E019, SKERR_SIRQ_E019MSG);
525 Para.Para64 = MAC_2;
526 SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
527
528 Para.Para32[0] = MAC_2;
529 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
530 }
531} /* SkGeHwErr */
532
533
534/******************************************************************************
535 *
536 * SkGeSirqIsr() - Special Interrupt Service Routine
537 *
538 * Description: handles all non data transfer specific interrupts (slow path)
539 *
540 * Returns: N/A
541 */
542void SkGeSirqIsr(
543SK_AC *pAC, /* adapter context */
544SK_IOC IoC, /* IO context */
545SK_U32 Istatus) /* Interrupt status word */
546{
547 SK_EVPARA Para;
548 SK_U32 RegVal32; /* Read register value */
549 SK_GEPORT *pPrt; /* GIni Port struct pointer */
550 SK_U16 PhyInt;
551 int i;
552
553 if (((Istatus & IS_HW_ERR) & pAC->GIni.GIValIrqMask) != 0) {
554 /* read the HW Error Interrupt source */
555 SK_IN32(IoC, B0_HWE_ISRC, &RegVal32);
556
557 SkGeHwErr(pAC, IoC, RegVal32);
558 }
559
560 /*
561 * Packet Timeout interrupts
562 */
563 /* Check whether MACs are correctly initialized */
564 if (((Istatus & (IS_PA_TO_RX1 | IS_PA_TO_TX1)) != 0) &&
565 pAC->GIni.GP[MAC_1].PState == SK_PRT_RESET) {
566 /* MAC 1 was not initialized but Packet timeout occured */
567 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E004,
568 SKERR_SIRQ_E004MSG);
569 }
570
571 if (((Istatus & (IS_PA_TO_RX2 | IS_PA_TO_TX2)) != 0) &&
572 pAC->GIni.GP[MAC_2].PState == SK_PRT_RESET) {
573 /* MAC 2 was not initialized but Packet timeout occured */
574 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E005,
575 SKERR_SIRQ_E005MSG);
576 }
577
578 if ((Istatus & IS_PA_TO_RX1) != 0) {
579 /* Means network is filling us up */
580 SK_ERR_LOG(pAC, SK_ERRCL_HW | SK_ERRCL_INIT, SKERR_SIRQ_E002,
581 SKERR_SIRQ_E002MSG);
582 SK_OUT16(IoC, B3_PA_CTRL, PA_CLR_TO_RX1);
583 }
584
585 if ((Istatus & IS_PA_TO_RX2) != 0) {
586 /* Means network is filling us up */
587 SK_ERR_LOG(pAC, SK_ERRCL_HW | SK_ERRCL_INIT, SKERR_SIRQ_E003,
588 SKERR_SIRQ_E003MSG);
589 SK_OUT16(IoC, B3_PA_CTRL, PA_CLR_TO_RX2);
590 }
591
592 if ((Istatus & IS_PA_TO_TX1) != 0) {
593
594 pPrt = &pAC->GIni.GP[0];
595
596 /* May be a normal situation in a server with a slow network */
597 SK_OUT16(IoC, B3_PA_CTRL, PA_CLR_TO_TX1);
598
599#ifdef GENESIS
600 if (pAC->GIni.GIGenesis) {
601 /*
602 * workaround: if in half duplex mode, check for Tx hangup.
603 * Read number of TX'ed bytes, wait for 10 ms, then compare
604 * the number with current value. If nothing changed, we assume
605 * that Tx is hanging and do a FIFO flush (see event routine).
606 */
607 if ((pPrt->PLinkModeStatus == SK_LMODE_STAT_HALF ||
608 pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOHALF) &&
609 !pPrt->HalfDupTimerActive) {
610 /*
611 * many more pack. arb. timeouts may come in between,
612 * we ignore those
613 */
614 pPrt->HalfDupTimerActive = SK_TRUE;
615 /* Snap statistic counters */
616 (void)SkXmUpdateStats(pAC, IoC, 0);
617
618 (void)SkXmMacStatistic(pAC, IoC, 0, XM_TXO_OK_HI, &RegVal32);
619
620 pPrt->LastOctets = (SK_U64)RegVal32 << 32;
621
622 (void)SkXmMacStatistic(pAC, IoC, 0, XM_TXO_OK_LO, &RegVal32);
623
624 pPrt->LastOctets += RegVal32;
625
626 Para.Para32[0] = 0;
627 SkTimerStart(pAC, IoC, &pPrt->HalfDupChkTimer, SK_HALFDUP_CHK_TIME,
628 SKGE_HWAC, SK_HWEV_HALFDUP_CHK, Para);
629 }
630 }
631#endif /* GENESIS */
632 }
633
634 if ((Istatus & IS_PA_TO_TX2) != 0) {
635
636 pPrt = &pAC->GIni.GP[1];
637
638 /* May be a normal situation in a server with a slow network */
639 SK_OUT16(IoC, B3_PA_CTRL, PA_CLR_TO_TX2);
640
641#ifdef GENESIS
642 if (pAC->GIni.GIGenesis) {
643 /* workaround: see above */
644 if ((pPrt->PLinkModeStatus == SK_LMODE_STAT_HALF ||
645 pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOHALF) &&
646 !pPrt->HalfDupTimerActive) {
647 pPrt->HalfDupTimerActive = SK_TRUE;
648 /* Snap statistic counters */
649 (void)SkXmUpdateStats(pAC, IoC, 1);
650
651 (void)SkXmMacStatistic(pAC, IoC, 1, XM_TXO_OK_HI, &RegVal32);
652
653 pPrt->LastOctets = (SK_U64)RegVal32 << 32;
654
655 (void)SkXmMacStatistic(pAC, IoC, 1, XM_TXO_OK_LO, &RegVal32);
656
657 pPrt->LastOctets += RegVal32;
658
659 Para.Para32[0] = 1;
660 SkTimerStart(pAC, IoC, &pPrt->HalfDupChkTimer, SK_HALFDUP_CHK_TIME,
661 SKGE_HWAC, SK_HWEV_HALFDUP_CHK, Para);
662 }
663 }
664#endif /* GENESIS */
665 }
666
667 /* Check interrupts of the particular queues */
668 if ((Istatus & IS_R1_C) != 0) {
669 /* Clear IRQ */
670 SK_OUT32(IoC, B0_R1_CSR, CSR_IRQ_CL_C);
671 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E006,
672 SKERR_SIRQ_E006MSG);
673 Para.Para64 = MAC_1;
674 SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
675 Para.Para32[0] = MAC_1;
676 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
677 }
678
679 if ((Istatus & IS_R2_C) != 0) {
680 /* Clear IRQ */
681 SK_OUT32(IoC, B0_R2_CSR, CSR_IRQ_CL_C);
682 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E007,
683 SKERR_SIRQ_E007MSG);
684 Para.Para64 = MAC_2;
685 SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
686 Para.Para32[0] = MAC_2;
687 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
688 }
689
690 if ((Istatus & IS_XS1_C) != 0) {
691 /* Clear IRQ */
692 SK_OUT32(IoC, B0_XS1_CSR, CSR_IRQ_CL_C);
693 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E008,
694 SKERR_SIRQ_E008MSG);
695 Para.Para64 = MAC_1;
696 SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
697 Para.Para32[0] = MAC_1;
698 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
699 }
700
701 if ((Istatus & IS_XA1_C) != 0) {
702 /* Clear IRQ */
703 SK_OUT32(IoC, B0_XA1_CSR, CSR_IRQ_CL_C);
704 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E009,
705 SKERR_SIRQ_E009MSG);
706 Para.Para64 = MAC_1;
707 SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
708 Para.Para32[0] = MAC_1;
709 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
710 }
711
712 if ((Istatus & IS_XS2_C) != 0) {
713 /* Clear IRQ */
714 SK_OUT32(IoC, B0_XS2_CSR, CSR_IRQ_CL_C);
715 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E010,
716 SKERR_SIRQ_E010MSG);
717 Para.Para64 = MAC_2;
718 SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
719 Para.Para32[0] = MAC_2;
720 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
721 }
722
723 if ((Istatus & IS_XA2_C) != 0) {
724 /* Clear IRQ */
725 SK_OUT32(IoC, B0_XA2_CSR, CSR_IRQ_CL_C);
726 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E011,
727 SKERR_SIRQ_E011MSG);
728 Para.Para64 = MAC_2;
729 SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);
730 Para.Para32[0] = MAC_2;
731 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
732 }
733
734 /* External reg interrupt */
735 if ((Istatus & IS_EXT_REG) != 0) {
736 /* Test IRQs from PHY */
737 for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
738
739 pPrt = &pAC->GIni.GP[i];
740
741 if (pPrt->PState == SK_PRT_RESET) {
742 continue;
743 }
744
745#ifdef GENESIS
746 if (pAC->GIni.GIGenesis) {
747
748 switch (pPrt->PhyType) {
749
750 case SK_PHY_XMAC:
751 break;
752
753 case SK_PHY_BCOM:
754 SkXmPhyRead(pAC, IoC, i, PHY_BCOM_INT_STAT, &PhyInt);
755
756 if ((PhyInt & ~PHY_B_DEF_MSK) != 0) {
757 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
758 ("Port %d Bcom Int: 0x%04X\n",
759 i, PhyInt));
760 SkPhyIsrBcom(pAC, IoC, i, PhyInt);
761 }
762 break;
763#ifdef OTHER_PHY
764 case SK_PHY_LONE:
765 SkXmPhyRead(pAC, IoC, i, PHY_LONE_INT_STAT, &PhyInt);
766
767 if ((PhyInt & PHY_L_DEF_MSK) != 0) {
768 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
769 ("Port %d Lone Int: %x\n",
770 i, PhyInt));
771 SkPhyIsrLone(pAC, IoC, i, PhyInt);
772 }
773 break;
774#endif /* OTHER_PHY */
775 }
776 }
777#endif /* GENESIS */
778
779#ifdef YUKON
780 if (pAC->GIni.GIYukon) {
781 /* Read PHY Interrupt Status */
782 SkGmPhyRead(pAC, IoC, i, PHY_MARV_INT_STAT, &PhyInt);
783
784 if ((PhyInt & PHY_M_DEF_MSK) != 0) {
785 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
786 ("Port %d Marv Int: 0x%04X\n",
787 i, PhyInt));
788 SkPhyIsrGmac(pAC, IoC, i, PhyInt);
789 }
790 }
791#endif /* YUKON */
792 }
793 }
794
795 /* I2C Ready interrupt */
796 if ((Istatus & IS_I2C_READY) != 0) {
797#ifdef SK_SLIM
798 SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ);
799#else
800 SkI2cIsr(pAC, IoC);
801#endif
802 }
803
804 /* SW forced interrupt */
805 if ((Istatus & IS_IRQ_SW) != 0) {
806 /* clear the software IRQ */
807 SK_OUT8(IoC, B0_CTST, CS_CL_SW_IRQ);
808 }
809
810 if ((Istatus & IS_LNK_SYNC_M1) != 0) {
811 /*
812 * We do NOT need the Link Sync interrupt, because it shows
813 * us only a link going down.
814 */
815 /* clear interrupt */
816 SK_OUT8(IoC, MR_ADDR(MAC_1, LNK_SYNC_CTRL), LED_CLR_IRQ);
817 }
818
819 /* Check MAC after link sync counter */
820 if ((Istatus & IS_MAC1) != 0) {
821 /* IRQ from MAC 1 */
822 SkMacIrq(pAC, IoC, MAC_1);
823 }
824
825 if ((Istatus & IS_LNK_SYNC_M2) != 0) {
826 /*
827 * We do NOT need the Link Sync interrupt, because it shows
828 * us only a link going down.
829 */
830 /* clear interrupt */
831 SK_OUT8(IoC, MR_ADDR(MAC_2, LNK_SYNC_CTRL), LED_CLR_IRQ);
832 }
833
834 /* Check MAC after link sync counter */
835 if ((Istatus & IS_MAC2) != 0) {
836 /* IRQ from MAC 2 */
837 SkMacIrq(pAC, IoC, MAC_2);
838 }
839
840 /* Timer interrupt (served last) */
841 if ((Istatus & IS_TIMINT) != 0) {
842 /* check for HW Errors */
843 if (((Istatus & IS_HW_ERR) & ~pAC->GIni.GIValIrqMask) != 0) {
844 /* read the HW Error Interrupt source */
845 SK_IN32(IoC, B0_HWE_ISRC, &RegVal32);
846
847 SkGeHwErr(pAC, IoC, RegVal32);
848 }
849
850 SkHwtIsr(pAC, IoC);
851 }
852
853} /* SkGeSirqIsr */
854
855
856#ifdef GENESIS
857/******************************************************************************
858 *
859 * SkGePortCheckShorts() - Implementing XMAC Workaround Errata # 2
860 *
861 * return:
862 * 0 o.k. nothing needed
863 * 1 Restart needed on this port
864 */
865static int SkGePortCheckShorts(
866SK_AC *pAC, /* Adapter Context */
867SK_IOC IoC, /* IO Context */
868int Port) /* Which port should be checked */
869{
870 SK_U32 Shorts; /* Short Event Counter */
871 SK_U32 CheckShorts; /* Check value for Short Event Counter */
872 SK_U64 RxCts; /* Rx Counter (packets on network) */
873 SK_U32 RxTmp; /* Rx temp. Counter */
874 SK_U32 FcsErrCts; /* FCS Error Counter */
875 SK_GEPORT *pPrt; /* GIni Port struct pointer */
876 int Rtv; /* Return value */
877 int i;
878
879 pPrt = &pAC->GIni.GP[Port];
880
881 /* Default: no action */
882 Rtv = SK_HW_PS_NONE;
883
884 (void)SkXmUpdateStats(pAC, IoC, Port);
885
886 /* Extra precaution: check for short Event counter */
887 (void)SkXmMacStatistic(pAC, IoC, Port, XM_RXE_SHT_ERR, &Shorts);
888
889 /*
890 * Read Rx counters (packets seen on the network and not necessarily
891 * really received.
892 */
893 RxCts = 0;
894
895 for (i = 0; i < sizeof(SkGeRxRegs)/sizeof(SkGeRxRegs[0]); i++) {
896
897 (void)SkXmMacStatistic(pAC, IoC, Port, SkGeRxRegs[i], &RxTmp);
898
899 RxCts += (SK_U64)RxTmp;
900 }
901
902 /* On default: check shorts against zero */
903 CheckShorts = 0;
904
905 /* Extra precaution on active links */
906 if (pPrt->PHWLinkUp) {
907 /* Reset Link Restart counter */
908 pPrt->PLinkResCt = 0;
909 pPrt->PAutoNegTOCt = 0;
910
911 /* If link is up check for 2 */
912 CheckShorts = 2;
913
914 (void)SkXmMacStatistic(pAC, IoC, Port, XM_RXF_FCS_ERR, &FcsErrCts);
915
916 if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE &&
917 pPrt->PLipaAutoNeg == SK_LIPA_UNKNOWN &&
918 (pPrt->PLinkMode == SK_LMODE_HALF ||
919 pPrt->PLinkMode == SK_LMODE_FULL)) {
920 /*
921 * This is autosensing and we are in the fallback
922 * manual full/half duplex mode.
923 */
924 if (RxCts == pPrt->PPrevRx) {
925 /* Nothing received, restart link */
926 pPrt->PPrevFcs = FcsErrCts;
927 pPrt->PPrevShorts = Shorts;
928
929 return(SK_HW_PS_RESTART);
930 }
931 else {
932 pPrt->PLipaAutoNeg = SK_LIPA_MANUAL;
933 }
934 }
935
936 if (((RxCts - pPrt->PPrevRx) > pPrt->PRxLim) ||
937 (!(FcsErrCts - pPrt->PPrevFcs))) {
938 /*
939 * Note: The compare with zero above has to be done the way shown,
940 * otherwise the Linux driver will have a problem.
941 */
942 /*
943 * We received a bunch of frames or no CRC error occured on the
944 * network -> ok.
945 */
946 pPrt->PPrevRx = RxCts;
947 pPrt->PPrevFcs = FcsErrCts;
948 pPrt->PPrevShorts = Shorts;
949
950 return(SK_HW_PS_NONE);
951 }
952
953 pPrt->PPrevFcs = FcsErrCts;
954 }
955
956
957 if ((Shorts - pPrt->PPrevShorts) > CheckShorts) {
958 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
959 ("Short Event Count Restart Port %d \n", Port));
960 Rtv = SK_HW_PS_RESTART;
961 }
962
963 pPrt->PPrevShorts = Shorts;
964 pPrt->PPrevRx = RxCts;
965
966 return(Rtv);
967} /* SkGePortCheckShorts */
968#endif /* GENESIS */
969
970
971/******************************************************************************
972 *
973 * SkGePortCheckUp() - Check if the link is up
974 *
975 * return:
976 * 0 o.k. nothing needed
977 * 1 Restart needed on this port
978 * 2 Link came up
979 */
980static int SkGePortCheckUp(
981SK_AC *pAC, /* Adapter Context */
982SK_IOC IoC, /* IO Context */
983int Port) /* Which port should be checked */
984{
985 SK_GEPORT *pPrt; /* GIni Port struct pointer */
986 SK_BOOL AutoNeg; /* Is Auto-negotiation used ? */
987 int Rtv; /* Return value */
988
989 Rtv = SK_HW_PS_NONE;
990
991 pPrt = &pAC->GIni.GP[Port];
992
993 if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
994 AutoNeg = SK_FALSE;
995 }
996 else {
997 AutoNeg = SK_TRUE;
998 }
999
1000#ifdef GENESIS
1001 if (pAC->GIni.GIGenesis) {
1002
1003 switch (pPrt->PhyType) {
1004
1005 case SK_PHY_XMAC:
1006 Rtv = SkGePortCheckUpXmac(pAC, IoC, Port, AutoNeg);
1007 break;
1008 case SK_PHY_BCOM:
1009 Rtv = SkGePortCheckUpBcom(pAC, IoC, Port, AutoNeg);
1010 break;
1011#ifdef OTHER_PHY
1012 case SK_PHY_LONE:
1013 Rtv = SkGePortCheckUpLone(pAC, IoC, Port, AutoNeg);
1014 break;
1015 case SK_PHY_NAT:
1016 Rtv = SkGePortCheckUpNat(pAC, IoC, Port, AutoNeg);
1017 break;
1018#endif /* OTHER_PHY */
1019 }
1020 }
1021#endif /* GENESIS */
1022
1023#ifdef YUKON
1024 if (pAC->GIni.GIYukon) {
1025
1026 Rtv = SkGePortCheckUpGmac(pAC, IoC, Port, AutoNeg);
1027 }
1028#endif /* YUKON */
1029
1030 return(Rtv);
1031} /* SkGePortCheckUp */
1032
1033
1034#ifdef GENESIS
1035/******************************************************************************
1036 *
1037 * SkGePortCheckUpXmac() - Implementing of the Workaround Errata # 2
1038 *
1039 * return:
1040 * 0 o.k. nothing needed
1041 * 1 Restart needed on this port
1042 * 2 Link came up
1043 */
1044static int SkGePortCheckUpXmac(
1045SK_AC *pAC, /* Adapter Context */
1046SK_IOC IoC, /* IO Context */
1047int Port, /* Which port should be checked */
1048SK_BOOL AutoNeg) /* Is Auto-negotiation used ? */
1049{
1050 SK_U32 Shorts; /* Short Event Counter */
1051 SK_GEPORT *pPrt; /* GIni Port struct pointer */
1052 int Done;
1053 SK_U32 GpReg; /* General Purpose register value */
1054 SK_U16 Isrc; /* Interrupt source register */
1055 SK_U16 IsrcSum; /* Interrupt source register sum */
1056 SK_U16 LpAb; /* Link Partner Ability */
1057 SK_U16 ResAb; /* Resolved Ability */
1058 SK_U16 ExtStat; /* Extended Status Register */
1059 SK_U8 NextMode; /* Next AutoSensing Mode */
1060
1061 pPrt = &pAC->GIni.GP[Port];
1062
1063 if (pPrt->PHWLinkUp) {
1064 if (pPrt->PhyType != SK_PHY_XMAC) {
1065 return(SK_HW_PS_NONE);
1066 }
1067 else {
1068 return(SkGePortCheckShorts(pAC, IoC, Port));
1069 }
1070 }
1071
1072 IsrcSum = pPrt->PIsave;
1073 pPrt->PIsave = 0;
1074
1075 /* Now wait for each port's link */
1076 if (pPrt->PLinkBroken) {
1077 /* Link was broken */
1078 XM_IN32(IoC, Port, XM_GP_PORT, &GpReg);
1079
1080 if ((GpReg & XM_GP_INP_ASS) == 0) {
1081 /* The Link is in sync */
1082 XM_IN16(IoC, Port, XM_ISRC, &Isrc);
1083 IsrcSum |= Isrc;
1084 SkXmAutoNegLipaXmac(pAC, IoC, Port, IsrcSum);
1085
1086 if ((Isrc & XM_IS_INP_ASS) == 0) {
1087 /* It has been in sync since last time */
1088 /* Restart the PORT */
1089 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
1090 ("Link in sync Restart Port %d\n", Port));
1091
1092 (void)SkXmUpdateStats(pAC, IoC, Port);
1093
1094 /* We now need to reinitialize the PrevShorts counter */
1095 (void)SkXmMacStatistic(pAC, IoC, Port, XM_RXE_SHT_ERR, &Shorts);
1096 pPrt->PPrevShorts = Shorts;
1097
1098 pPrt->PLinkBroken = SK_FALSE;
1099
1100 /*
1101 * Link Restart Workaround:
1102 * it may be possible that the other Link side
1103 * restarts its link as well an we detect
1104 * another LinkBroken. To prevent this
1105 * happening we check for a maximum number
1106 * of consecutive restart. If those happens,
1107 * we do NOT restart the active link and
1108 * check whether the link is now o.k.
1109 */
1110 pPrt->PLinkResCt++;
1111
1112 pPrt->PAutoNegTimeOut = 0;
1113
1114 if (pPrt->PLinkResCt < SK_MAX_LRESTART) {
1115 return(SK_HW_PS_RESTART);
1116 }
1117
1118 pPrt->PLinkResCt = 0;
1119
1120 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1121 ("Do NOT restart on Port %d %x %x\n", Port, Isrc, IsrcSum));
1122 }
1123 else {
1124 pPrt->PIsave = (SK_U16)(IsrcSum & XM_IS_AND);
1125
1126 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1127 ("Save Sync/nosync Port %d %x %x\n", Port, Isrc, IsrcSum));
1128
1129 /* Do nothing more if link is broken */
1130 return(SK_HW_PS_NONE);
1131 }
1132 }
1133 else {
1134 /* Do nothing more if link is broken */
1135 return(SK_HW_PS_NONE);
1136 }
1137
1138 }
1139 else {
1140 /* Link was not broken, check if it is */
1141 XM_IN16(IoC, Port, XM_ISRC, &Isrc);
1142 IsrcSum |= Isrc;
1143 if ((Isrc & XM_IS_INP_ASS) != 0) {
1144 XM_IN16(IoC, Port, XM_ISRC, &Isrc);
1145 IsrcSum |= Isrc;
1146 if ((Isrc & XM_IS_INP_ASS) != 0) {
1147 XM_IN16(IoC, Port, XM_ISRC, &Isrc);
1148 IsrcSum |= Isrc;
1149 if ((Isrc & XM_IS_INP_ASS) != 0) {
1150 pPrt->PLinkBroken = SK_TRUE;
1151 /* Re-Init Link partner Autoneg flag */
1152 pPrt->PLipaAutoNeg = SK_LIPA_UNKNOWN;
1153 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
1154 ("Link broken Port %d\n", Port));
1155
1156 /* Cable removed-> reinit sense mode */
1157 SkHWInitDefSense(pAC, IoC, Port);
1158
1159 return(SK_HW_PS_RESTART);
1160 }
1161 }
1162 }
1163 else {
1164 SkXmAutoNegLipaXmac(pAC, IoC, Port, Isrc);
1165
1166 if (SkGePortCheckShorts(pAC, IoC, Port) == SK_HW_PS_RESTART) {
1167 return(SK_HW_PS_RESTART);
1168 }
1169 }
1170 }
1171
1172 /*
1173 * here we usually can check whether the link is in sync and
1174 * auto-negotiation is done.
1175 */
1176 XM_IN32(IoC, Port, XM_GP_PORT, &GpReg);
1177 XM_IN16(IoC, Port, XM_ISRC, &Isrc);
1178 IsrcSum |= Isrc;
1179
1180 SkXmAutoNegLipaXmac(pAC, IoC, Port, IsrcSum);
1181
1182 if ((GpReg & XM_GP_INP_ASS) != 0 || (IsrcSum & XM_IS_INP_ASS) != 0) {
1183 if ((GpReg & XM_GP_INP_ASS) == 0) {
1184 /* Save Auto-negotiation Done interrupt only if link is in sync */
1185 pPrt->PIsave = (SK_U16)(IsrcSum & XM_IS_AND);
1186 }
1187#ifdef DEBUG
1188 if ((pPrt->PIsave & XM_IS_AND) != 0) {
1189 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1190 ("AutoNeg done rescheduled Port %d\n", Port));
1191 }
1192#endif /* DEBUG */
1193 return(SK_HW_PS_NONE);
1194 }
1195
1196 if (AutoNeg) {
1197 if ((IsrcSum & XM_IS_AND) != 0) {
1198 SkHWLinkUp(pAC, IoC, Port);
1199 Done = SkMacAutoNegDone(pAC, IoC, Port);
1200 if (Done != SK_AND_OK) {
1201 /* Get PHY parameters, for debugging only */
1202 SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_AUNE_LP, &LpAb);
1203 SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_RES_ABI, &ResAb);
1204 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1205 ("AutoNeg FAIL Port %d (LpAb %x, ResAb %x)\n",
1206 Port, LpAb, ResAb));
1207
1208 /* Try next possible mode */
1209 NextMode = SkHWSenseGetNext(pAC, IoC, Port);
1210 SkHWLinkDown(pAC, IoC, Port);
1211 if (Done == SK_AND_DUP_CAP) {
1212 /* GoTo next mode */
1213 SkHWSenseSetNext(pAC, IoC, Port, NextMode);
1214 }
1215
1216 return(SK_HW_PS_RESTART);
1217 }
1218 /*
1219 * Dummy Read extended status to prevent extra link down/ups
1220 * (clear Page Received bit if set)
1221 */
1222 SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_AUNE_EXP, &ExtStat);
1223
1224 return(SK_HW_PS_LINK);
1225 }
1226
1227 /* AutoNeg not done, but HW link is up. Check for timeouts */
1228 pPrt->PAutoNegTimeOut++;
1229 if (pPrt->PAutoNegTimeOut >= SK_AND_MAX_TO) {
1230 /* Increase the Timeout counter */
1231 pPrt->PAutoNegTOCt++;
1232
1233 /* Timeout occured */
1234 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
1235 ("AutoNeg timeout Port %d\n", Port));
1236 if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE &&
1237 pPrt->PLipaAutoNeg != SK_LIPA_AUTO) {
1238 /* Set Link manually up */
1239 SkHWSenseSetNext(pAC, IoC, Port, SK_LMODE_FULL);
1240 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
1241 ("Set manual full duplex Port %d\n", Port));
1242 }
1243
1244 if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE &&
1245 pPrt->PLipaAutoNeg == SK_LIPA_AUTO &&
1246 pPrt->PAutoNegTOCt >= SK_MAX_ANEG_TO) {
1247 /*
1248 * This is rather complicated.
1249 * we need to check here whether the LIPA_AUTO
1250 * we saw before is false alert. We saw at one
1251 * switch ( SR8800) that on boot time it sends
1252 * just one auto-neg packet and does no further
1253 * auto-negotiation.
1254 * Solution: we restart the autosensing after
1255 * a few timeouts.
1256 */
1257 pPrt->PAutoNegTOCt = 0;
1258 pPrt->PLipaAutoNeg = SK_LIPA_UNKNOWN;
1259 SkHWInitDefSense(pAC, IoC, Port);
1260 }
1261
1262 /* Do the restart */
1263 return(SK_HW_PS_RESTART);
1264 }
1265 }
1266 else {
1267 /* Link is up and we don't need more */
1268#ifdef DEBUG
1269 if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) {
1270 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1271 ("ERROR: Lipa auto detected on port %d\n", Port));
1272 }
1273#endif /* DEBUG */
1274 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
1275 ("Link sync(GP), Port %d\n", Port));
1276 SkHWLinkUp(pAC, IoC, Port);
1277
1278 /*
1279 * Link sync (GP) and so assume a good connection. But if not received
1280 * a bunch of frames received in a time slot (maybe broken tx cable)
1281 * the port is restart.
1282 */
1283 return(SK_HW_PS_LINK);
1284 }
1285
1286 return(SK_HW_PS_NONE);
1287} /* SkGePortCheckUpXmac */
1288
1289
1290/******************************************************************************
1291 *
1292 * SkGePortCheckUpBcom() - Check if the link is up on Bcom PHY
1293 *
1294 * return:
1295 * 0 o.k. nothing needed
1296 * 1 Restart needed on this port
1297 * 2 Link came up
1298 */
1299static int SkGePortCheckUpBcom(
1300SK_AC *pAC, /* Adapter Context */
1301SK_IOC IoC, /* IO Context */
1302int Port, /* Which port should be checked */
1303SK_BOOL AutoNeg) /* Is Auto-negotiation used ? */
1304{
1305 SK_GEPORT *pPrt; /* GIni Port struct pointer */
1306 int Done;
1307 SK_U16 Isrc; /* Interrupt source register */
1308 SK_U16 PhyStat; /* Phy Status Register */
1309 SK_U16 ResAb; /* Master/Slave resolution */
1310 SK_U16 Ctrl; /* Broadcom control flags */
1311#ifdef DEBUG
1312 SK_U16 LpAb;
1313 SK_U16 ExtStat;
1314#endif /* DEBUG */
1315
1316 pPrt = &pAC->GIni.GP[Port];
1317
1318 /* Check for No HCD Link events (#10523) */
1319 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_STAT, &Isrc);
1320
1321#ifdef xDEBUG
1322 if ((Isrc & ~(PHY_B_IS_HCT | PHY_B_IS_LCT)) ==
1323 (PHY_B_IS_SCR_S_ER | PHY_B_IS_RRS_CHANGE | PHY_B_IS_LRS_CHANGE)) {
1324
1325 SK_U32 Stat1, Stat2, Stat3;
1326
1327 Stat1 = 0;
1328 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_MASK, &Stat1);
1329 CMSMPrintString(
1330 pAC->pConfigTable,
1331 MSG_TYPE_RUNTIME_INFO,
1332 "CheckUp1 - Stat: %x, Mask: %x",
1333 (void *)Isrc,
1334 (void *)Stat1);
1335
1336 Stat1 = 0;
1337 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_CTRL, &Stat1);
1338 Stat2 = 0;
1339 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_STAT, &Stat2);
1340 Stat1 = Stat1 << 16 | Stat2;
1341 Stat2 = 0;
1342 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_ADV, &Stat2);
1343 Stat3 = 0;
1344 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_LP, &Stat3);
1345 Stat2 = Stat2 << 16 | Stat3;
1346 CMSMPrintString(
1347 pAC->pConfigTable,
1348 MSG_TYPE_RUNTIME_INFO,
1349 "Ctrl/Stat: %x, AN Adv/LP: %x",
1350 (void *)Stat1,
1351 (void *)Stat2);
1352
1353 Stat1 = 0;
1354 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_EXP, &Stat1);
1355 Stat2 = 0;
1356 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_EXT_STAT, &Stat2);
1357 Stat1 = Stat1 << 16 | Stat2;
1358 Stat2 = 0;
1359 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_CTRL, &Stat2);
1360 Stat3 = 0;
1361 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &Stat3);
1362 Stat2 = Stat2 << 16 | Stat3;
1363 CMSMPrintString(
1364 pAC->pConfigTable,
1365 MSG_TYPE_RUNTIME_INFO,
1366 "AN Exp/IEEE Ext: %x, 1000T Ctrl/Stat: %x",
1367 (void *)Stat1,
1368 (void *)Stat2);
1369
1370 Stat1 = 0;
1371 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_P_EXT_CTRL, &Stat1);
1372 Stat2 = 0;
1373 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_P_EXT_STAT, &Stat2);
1374 Stat1 = Stat1 << 16 | Stat2;
1375 Stat2 = 0;
1376 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &Stat2);
1377 Stat3 = 0;
1378 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_STAT, &Stat3);
1379 Stat2 = Stat2 << 16 | Stat3;
1380 CMSMPrintString(
1381 pAC->pConfigTable,
1382 MSG_TYPE_RUNTIME_INFO,
1383 "PHY Ext Ctrl/Stat: %x, Aux Ctrl/Stat: %x",
1384 (void *)Stat1,
1385 (void *)Stat2);
1386 }
1387#endif /* DEBUG */
1388
1389 if ((Isrc & (PHY_B_IS_NO_HDCL /* | PHY_B_IS_NO_HDC */)) != 0) {
1390 /*
1391 * Workaround BCom Errata:
1392 * enable and disable loopback mode if "NO HCD" occurs.
1393 */
1394 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_CTRL, &Ctrl);
1395 SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_CTRL,
1396 (SK_U16)(Ctrl | PHY_CT_LOOP));
1397 SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_CTRL,
1398 (SK_U16)(Ctrl & ~PHY_CT_LOOP));
1399 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1400 ("No HCD Link event, Port %d\n", Port));
1401#ifdef xDEBUG
1402 CMSMPrintString(
1403 pAC->pConfigTable,
1404 MSG_TYPE_RUNTIME_INFO,
1405 "No HCD link event, port %d.",
1406 (void *)Port,
1407 (void *)NULL);
1408#endif /* DEBUG */
1409 }
1410
1411 /* Not obsolete: link status bit is latched to 0 and autoclearing! */
1412 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_STAT, &PhyStat);
1413
1414 if (pPrt->PHWLinkUp) {
1415 return(SK_HW_PS_NONE);
1416 }
1417
1418#ifdef xDEBUG
1419 {
1420 SK_U32 Stat1, Stat2, Stat3;
1421
1422 Stat1 = 0;
1423 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_MASK, &Stat1);
1424 CMSMPrintString(
1425 pAC->pConfigTable,
1426 MSG_TYPE_RUNTIME_INFO,
1427 "CheckUp1a - Stat: %x, Mask: %x",
1428 (void *)Isrc,
1429 (void *)Stat1);
1430
1431 Stat1 = 0;
1432 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_CTRL, &Stat1);
1433 Stat2 = 0;
1434 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_STAT, &PhyStat);
1435 Stat1 = Stat1 << 16 | PhyStat;
1436 Stat2 = 0;
1437 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_ADV, &Stat2);
1438 Stat3 = 0;
1439 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_LP, &Stat3);
1440 Stat2 = Stat2 << 16 | Stat3;
1441 CMSMPrintString(
1442 pAC->pConfigTable,
1443 MSG_TYPE_RUNTIME_INFO,
1444 "Ctrl/Stat: %x, AN Adv/LP: %x",
1445 (void *)Stat1,
1446 (void *)Stat2);
1447
1448 Stat1 = 0;
1449 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_EXP, &Stat1);
1450 Stat2 = 0;
1451 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_EXT_STAT, &Stat2);
1452 Stat1 = Stat1 << 16 | Stat2;
1453 Stat2 = 0;
1454 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_CTRL, &Stat2);
1455 Stat3 = 0;
1456 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &ResAb);
1457 Stat2 = Stat2 << 16 | ResAb;
1458 CMSMPrintString(
1459 pAC->pConfigTable,
1460 MSG_TYPE_RUNTIME_INFO,
1461 "AN Exp/IEEE Ext: %x, 1000T Ctrl/Stat: %x",
1462 (void *)Stat1,
1463 (void *)Stat2);
1464
1465 Stat1 = 0;
1466 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_P_EXT_CTRL, &Stat1);
1467 Stat2 = 0;
1468 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_P_EXT_STAT, &Stat2);
1469 Stat1 = Stat1 << 16 | Stat2;
1470 Stat2 = 0;
1471 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &Stat2);
1472 Stat3 = 0;
1473 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_STAT, &Stat3);
1474 Stat2 = Stat2 << 16 | Stat3;
1475 CMSMPrintString(
1476 pAC->pConfigTable,
1477 MSG_TYPE_RUNTIME_INFO,
1478 "PHY Ext Ctrl/Stat: %x, Aux Ctrl/Stat: %x",
1479 (void *)Stat1,
1480 (void *)Stat2);
1481 }
1482#endif /* DEBUG */
1483
1484 /*
1485 * Here we usually can check whether the link is in sync and
1486 * auto-negotiation is done.
1487 */
1488
1489 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_STAT, &PhyStat);
1490
1491 SkMacAutoNegLipaPhy(pAC, IoC, Port, PhyStat);
1492
1493 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1494 ("CheckUp Port %d, PhyStat: 0x%04X\n", Port, PhyStat));
1495
1496 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &ResAb);
1497
1498 if ((ResAb & PHY_B_1000S_MSF) != 0) {
1499 /* Error */
1500 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1501 ("Master/Slave Fault port %d\n", Port));
1502
1503 pPrt->PAutoNegFail = SK_TRUE;
1504 pPrt->PMSStatus = SK_MS_STAT_FAULT;
1505
1506 return(SK_HW_PS_RESTART);
1507 }
1508
1509 if ((PhyStat & PHY_ST_LSYNC) == 0) {
1510 return(SK_HW_PS_NONE);
1511 }
1512
1513 pPrt->PMSStatus = ((ResAb & PHY_B_1000S_MSR) != 0) ?
1514 SK_MS_STAT_MASTER : SK_MS_STAT_SLAVE;
1515
1516 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1517 ("Port %d, ResAb: 0x%04X\n", Port, ResAb));
1518
1519 if (AutoNeg) {
1520 if ((PhyStat & PHY_ST_AN_OVER) != 0) {
1521
1522 SkHWLinkUp(pAC, IoC, Port);
1523
1524 Done = SkMacAutoNegDone(pAC, IoC, Port);
1525
1526 if (Done != SK_AND_OK) {
1527#ifdef DEBUG
1528 /* Get PHY parameters, for debugging only */
1529 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_LP, &LpAb);
1530 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &ExtStat);
1531 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1532 ("AutoNeg FAIL Port %d (LpAb %x, 1000TStat %x)\n",
1533 Port, LpAb, ExtStat));
1534#endif /* DEBUG */
1535 return(SK_HW_PS_RESTART);
1536 }
1537 else {
1538#ifdef xDEBUG
1539 /* Dummy read ISR to prevent extra link downs/ups */
1540 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_STAT, &ExtStat);
1541
1542 if ((ExtStat & ~(PHY_B_IS_HCT | PHY_B_IS_LCT)) != 0) {
1543 CMSMPrintString(
1544 pAC->pConfigTable,
1545 MSG_TYPE_RUNTIME_INFO,
1546 "CheckUp2 - Stat: %x",
1547 (void *)ExtStat,
1548 (void *)NULL);
1549 }
1550#endif /* DEBUG */
1551 return(SK_HW_PS_LINK);
1552 }
1553 }
1554 }
1555 else { /* !AutoNeg */
1556 /* Link is up and we don't need more. */
1557#ifdef DEBUG
1558 if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) {
1559 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1560 ("ERROR: Lipa auto detected on port %d\n", Port));
1561 }
1562#endif /* DEBUG */
1563
1564#ifdef xDEBUG
1565 /* Dummy read ISR to prevent extra link downs/ups */
1566 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_STAT, &ExtStat);
1567
1568 if ((ExtStat & ~(PHY_B_IS_HCT | PHY_B_IS_LCT)) != 0) {
1569 CMSMPrintString(
1570 pAC->pConfigTable,
1571 MSG_TYPE_RUNTIME_INFO,
1572 "CheckUp3 - Stat: %x",
1573 (void *)ExtStat,
1574 (void *)NULL);
1575 }
1576#endif /* DEBUG */
1577
1578 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
1579 ("Link sync(GP), Port %d\n", Port));
1580 SkHWLinkUp(pAC, IoC, Port);
1581
1582 return(SK_HW_PS_LINK);
1583 }
1584
1585 return(SK_HW_PS_NONE);
1586} /* SkGePortCheckUpBcom */
1587#endif /* GENESIS */
1588
1589
1590#ifdef YUKON
1591/******************************************************************************
1592 *
1593 * SkGePortCheckUpGmac() - Check if the link is up on Marvell PHY
1594 *
1595 * return:
1596 * 0 o.k. nothing needed
1597 * 1 Restart needed on this port
1598 * 2 Link came up
1599 */
1600static int SkGePortCheckUpGmac(
1601SK_AC *pAC, /* Adapter Context */
1602SK_IOC IoC, /* IO Context */
1603int Port, /* Which port should be checked */
1604SK_BOOL AutoNeg) /* Is Auto-negotiation used ? */
1605{
1606 SK_GEPORT *pPrt; /* GIni Port struct pointer */
1607 int Done;
1608 SK_U16 PhyIsrc; /* PHY Interrupt source */
1609 SK_U16 PhyStat; /* PPY Status */
1610 SK_U16 PhySpecStat;/* PHY Specific Status */
1611 SK_U16 ResAb; /* Master/Slave resolution */
1612 SK_EVPARA Para;
1613#ifdef DEBUG
1614 SK_U16 Word; /* I/O helper */
1615#endif /* DEBUG */
1616
1617 pPrt = &pAC->GIni.GP[Port];
1618
1619 if (pPrt->PHWLinkUp) {
1620 return(SK_HW_PS_NONE);
1621 }
1622
1623 /* Read PHY Status */
1624 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_STAT, &PhyStat);
1625
1626 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1627 ("CheckUp Port %d, PhyStat: 0x%04X\n", Port, PhyStat));
1628
1629 /* Read PHY Interrupt Status */
1630 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_INT_STAT, &PhyIsrc);
1631
1632 if ((PhyIsrc & PHY_M_IS_AN_COMPL) != 0) {
1633 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1634 ("Auto-Negotiation Completed, PhyIsrc: 0x%04X\n", PhyIsrc));
1635 }
1636
1637 if ((PhyIsrc & PHY_M_IS_LSP_CHANGE) != 0) {
1638 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1639 ("Link Speed Changed, PhyIsrc: 0x%04X\n", PhyIsrc));
1640 }
1641
1642 SkMacAutoNegLipaPhy(pAC, IoC, Port, PhyStat);
1643
1644 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_1000T_STAT, &ResAb);
1645
1646 if ((ResAb & PHY_B_1000S_MSF) != 0) {
1647 /* Error */
1648 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1649 ("Master/Slave Fault port %d\n", Port));
1650
1651 pPrt->PAutoNegFail = SK_TRUE;
1652 pPrt->PMSStatus = SK_MS_STAT_FAULT;
1653
1654 return(SK_HW_PS_RESTART);
1655 }
1656
1657 /* Read PHY Specific Status */
1658 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_STAT, &PhySpecStat);
1659
1660 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1661 ("Phy1000BT: 0x%04X, PhySpecStat: 0x%04X\n", ResAb, PhySpecStat));
1662
1663#ifdef DEBUG
1664 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_EXP, &Word);
1665
1666 if ((PhyIsrc & PHY_M_IS_AN_PR) != 0 || (Word & PHY_ANE_RX_PG) != 0 ||
1667 (PhySpecStat & PHY_M_PS_PAGE_REC) != 0) {
1668 /* Read PHY Next Page Link Partner */
1669 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_NEPG_LP, &Word);
1670
1671 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1672 ("Page Received, NextPage: 0x%04X\n", Word));
1673 }
1674#endif /* DEBUG */
1675
1676 if ((PhySpecStat & PHY_M_PS_LINK_UP) == 0) {
1677 return(SK_HW_PS_NONE);
1678 }
1679
1680 if ((PhySpecStat & PHY_M_PS_DOWNS_STAT) != 0 ||
1681 (PhyIsrc & PHY_M_IS_DOWNSH_DET) != 0) {
1682 /* Downshift detected */
1683 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E025, SKERR_SIRQ_E025MSG);
1684
1685 Para.Para64 = Port;
1686 SkEventQueue(pAC, SKGE_DRV, SK_DRV_DOWNSHIFT_DET, Para);
1687
1688 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1689 ("Downshift detected, PhyIsrc: 0x%04X\n", PhyIsrc));
1690 }
1691
1692 pPrt->PMSStatus = ((ResAb & PHY_B_1000S_MSR) != 0) ?
1693 SK_MS_STAT_MASTER : SK_MS_STAT_SLAVE;
1694
1695 pPrt->PCableLen = (SK_U8)((PhySpecStat & PHY_M_PS_CABLE_MSK) >> 7);
1696
1697 if (AutoNeg) {
1698 /* Auto-Negotiation Over ? */
1699 if ((PhyStat & PHY_ST_AN_OVER) != 0) {
1700
1701 SkHWLinkUp(pAC, IoC, Port);
1702
1703 Done = SkMacAutoNegDone(pAC, IoC, Port);
1704
1705 if (Done != SK_AND_OK) {
1706 return(SK_HW_PS_RESTART);
1707 }
1708
1709 return(SK_HW_PS_LINK);
1710 }
1711 }
1712 else { /* !AutoNeg */
1713 /* Link is up and we don't need more */
1714#ifdef DEBUG
1715 if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) {
1716 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1717 ("ERROR: Lipa auto detected on port %d\n", Port));
1718 }
1719#endif /* DEBUG */
1720
1721 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
1722 ("Link sync, Port %d\n", Port));
1723 SkHWLinkUp(pAC, IoC, Port);
1724
1725 return(SK_HW_PS_LINK);
1726 }
1727
1728 return(SK_HW_PS_NONE);
1729} /* SkGePortCheckUpGmac */
1730#endif /* YUKON */
1731
1732
1733#ifdef OTHER_PHY
1734/******************************************************************************
1735 *
1736 * SkGePortCheckUpLone() - Check if the link is up on Level One PHY
1737 *
1738 * return:
1739 * 0 o.k. nothing needed
1740 * 1 Restart needed on this port
1741 * 2 Link came up
1742 */
1743static int SkGePortCheckUpLone(
1744SK_AC *pAC, /* Adapter Context */
1745SK_IOC IoC, /* IO Context */
1746int Port, /* Which port should be checked */
1747SK_BOOL AutoNeg) /* Is Auto-negotiation used ? */
1748{
1749 SK_GEPORT *pPrt; /* GIni Port struct pointer */
1750 int Done;
1751 SK_U16 Isrc; /* Interrupt source register */
1752 SK_U16 LpAb; /* Link Partner Ability */
1753 SK_U16 ExtStat; /* Extended Status Register */
1754 SK_U16 PhyStat; /* Phy Status Register */
1755 SK_U16 StatSum;
1756 SK_U8 NextMode; /* Next AutoSensing Mode */
1757
1758 pPrt = &pAC->GIni.GP[Port];
1759
1760 if (pPrt->PHWLinkUp) {
1761 return(SK_HW_PS_NONE);
1762 }
1763
1764 StatSum = pPrt->PIsave;
1765 pPrt->PIsave = 0;
1766
1767 /*
1768 * here we usually can check whether the link is in sync and
1769 * auto-negotiation is done.
1770 */
1771 SkXmPhyRead(pAC, IoC, Port, PHY_LONE_STAT, &PhyStat);
1772 StatSum |= PhyStat;
1773
1774 SkMacAutoNegLipaPhy(pAC, IoC, Port, PhyStat);
1775
1776 if ((PhyStat & PHY_ST_LSYNC) == 0) {
1777 /* Save Auto-negotiation Done bit */
1778 pPrt->PIsave = (SK_U16)(StatSum & PHY_ST_AN_OVER);
1779#ifdef DEBUG
1780 if ((pPrt->PIsave & PHY_ST_AN_OVER) != 0) {
1781 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1782 ("AutoNeg done rescheduled Port %d\n", Port));
1783 }
1784#endif /* DEBUG */
1785 return(SK_HW_PS_NONE);
1786 }
1787
1788 if (AutoNeg) {
1789 if ((StatSum & PHY_ST_AN_OVER) != 0) {
1790 SkHWLinkUp(pAC, IoC, Port);
1791 Done = SkMacAutoNegDone(pAC, IoC, Port);
1792 if (Done != SK_AND_OK) {
1793 /* Get PHY parameters, for debugging only */
1794 SkXmPhyRead(pAC, IoC, Port, PHY_LONE_AUNE_LP, &LpAb);
1795 SkXmPhyRead(pAC, IoC, Port, PHY_LONE_1000T_STAT, &ExtStat);
1796 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1797 ("AutoNeg FAIL Port %d (LpAb %x, 1000TStat %x)\n",
1798 Port, LpAb, ExtStat));
1799
1800 /* Try next possible mode */
1801 NextMode = SkHWSenseGetNext(pAC, IoC, Port);
1802 SkHWLinkDown(pAC, IoC, Port);
1803 if (Done == SK_AND_DUP_CAP) {
1804 /* GoTo next mode */
1805 SkHWSenseSetNext(pAC, IoC, Port, NextMode);
1806 }
1807
1808 return(SK_HW_PS_RESTART);
1809
1810 }
1811 else {
1812 /*
1813 * Dummy Read interrupt status to prevent
1814 * extra link down/ups
1815 */
1816 SkXmPhyRead(pAC, IoC, Port, PHY_LONE_INT_STAT, &ExtStat);
1817 return(SK_HW_PS_LINK);
1818 }
1819 }
1820
1821 /* AutoNeg not done, but HW link is up. Check for timeouts */
1822 pPrt->PAutoNegTimeOut++;
1823 if (pPrt->PAutoNegTimeOut >= SK_AND_MAX_TO) {
1824 /* Timeout occured */
1825 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
1826 ("AutoNeg timeout Port %d\n", Port));
1827 if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE &&
1828 pPrt->PLipaAutoNeg != SK_LIPA_AUTO) {
1829 /* Set Link manually up */
1830 SkHWSenseSetNext(pAC, IoC, Port, SK_LMODE_FULL);
1831 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
1832 ("Set manual full duplex Port %d\n", Port));
1833 }
1834
1835 /* Do the restart */
1836 return(SK_HW_PS_RESTART);
1837 }
1838 }
1839 else {
1840 /* Link is up and we don't need more */
1841#ifdef DEBUG
1842 if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) {
1843 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1844 ("ERROR: Lipa auto detected on port %d\n", Port));
1845 }
1846#endif /* DEBUG */
1847
1848 /*
1849 * Dummy Read interrupt status to prevent
1850 * extra link down/ups
1851 */
1852 SkXmPhyRead(pAC, IoC, Port, PHY_LONE_INT_STAT, &ExtStat);
1853
1854 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
1855 ("Link sync(GP), Port %d\n", Port));
1856 SkHWLinkUp(pAC, IoC, Port);
1857
1858 return(SK_HW_PS_LINK);
1859 }
1860
1861 return(SK_HW_PS_NONE);
1862} /* SkGePortCheckUpLone */
1863
1864
1865/******************************************************************************
1866 *
1867 * SkGePortCheckUpNat() - Check if the link is up on National PHY
1868 *
1869 * return:
1870 * 0 o.k. nothing needed
1871 * 1 Restart needed on this port
1872 * 2 Link came up
1873 */
1874static int SkGePortCheckUpNat(
1875SK_AC *pAC, /* Adapter Context */
1876SK_IOC IoC, /* IO Context */
1877int Port, /* Which port should be checked */
1878SK_BOOL AutoNeg) /* Is Auto-negotiation used ? */
1879{
1880 /* todo: National */
1881 return(SK_HW_PS_NONE);
1882} /* SkGePortCheckUpNat */
1883#endif /* OTHER_PHY */
1884
1885
1886/******************************************************************************
1887 *
1888 * SkGeSirqEvent() - Event Service Routine
1889 *
1890 * Description:
1891 *
1892 * Notes:
1893 */
1894int SkGeSirqEvent(
1895SK_AC *pAC, /* Adapter Context */
1896SK_IOC IoC, /* Io Context */
1897SK_U32 Event, /* Module specific Event */
1898SK_EVPARA Para) /* Event specific Parameter */
1899{
1900 SK_GEPORT *pPrt; /* GIni Port struct pointer */
1901 SK_U32 Port;
1902 SK_U32 Val32;
1903 int PortStat;
1904 SK_U8 Val8;
1905#ifdef GENESIS
1906 SK_U64 Octets;
1907#endif /* GENESIS */
1908
1909 Port = Para.Para32[0];
1910 pPrt = &pAC->GIni.GP[Port];
1911
1912 switch (Event) {
1913 case SK_HWEV_WATIM:
1914 if (pPrt->PState == SK_PRT_RESET) {
1915
1916 PortStat = SK_HW_PS_NONE;
1917 }
1918 else {
1919 /* Check whether port came up */
1920 PortStat = SkGePortCheckUp(pAC, IoC, (int)Port);
1921 }
1922
1923 switch (PortStat) {
1924 case SK_HW_PS_RESTART:
1925 if (pPrt->PHWLinkUp) {
1926 /* Set Link to down */
1927 SkHWLinkDown(pAC, IoC, (int)Port);
1928
1929 /*
1930 * Signal directly to RLMT to ensure correct
1931 * sequence of SWITCH and RESET event.
1932 */
1933 SkRlmtEvent(pAC, IoC, SK_RLMT_LINK_DOWN, Para);
1934 }
1935
1936 /* Restart needed */
1937 SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Para);
1938 break;
1939
1940 case SK_HW_PS_LINK:
1941 /* Signal to RLMT */
1942 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_UP, Para);
1943 break;
1944 }
1945
1946 /* Start again the check Timer */
1947 if (pPrt->PHWLinkUp) {
1948 Val32 = SK_WA_ACT_TIME;
1949 }
1950 else {
1951 Val32 = SK_WA_INA_TIME;
1952 }
1953
1954 /* Todo: still needed for non-XMAC PHYs??? */
1955 /* Start workaround Errata #2 timer */
1956 SkTimerStart(pAC, IoC, &pPrt->PWaTimer, Val32,
1957 SKGE_HWAC, SK_HWEV_WATIM, Para);
1958 break;
1959
1960 case SK_HWEV_PORT_START:
1961 if (pPrt->PHWLinkUp) {
1962 /*
1963 * Signal directly to RLMT to ensure correct
1964 * sequence of SWITCH and RESET event.
1965 */
1966 SkRlmtEvent(pAC, IoC, SK_RLMT_LINK_DOWN, Para);
1967 }
1968
1969 SkHWLinkDown(pAC, IoC, (int)Port);
1970
1971 /* Schedule Port RESET */
1972 SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Para);
1973
1974 /* Start workaround Errata #2 timer */
1975 SkTimerStart(pAC, IoC, &pPrt->PWaTimer, SK_WA_INA_TIME,
1976 SKGE_HWAC, SK_HWEV_WATIM, Para);
1977 break;
1978
1979 case SK_HWEV_PORT_STOP:
1980 if (pPrt->PHWLinkUp) {
1981 /*
1982 * Signal directly to RLMT to ensure correct
1983 * sequence of SWITCH and RESET event.
1984 */
1985 SkRlmtEvent(pAC, IoC, SK_RLMT_LINK_DOWN, Para);
1986 }
1987
1988 /* Stop Workaround Timer */
1989 SkTimerStop(pAC, IoC, &pPrt->PWaTimer);
1990
1991 SkHWLinkDown(pAC, IoC, (int)Port);
1992 break;
1993
1994 case SK_HWEV_UPDATE_STAT:
1995 /* We do NOT need to update any statistics */
1996 break;
1997
1998 case SK_HWEV_CLEAR_STAT:
1999 /* We do NOT need to clear any statistics */
2000 for (Port = 0; Port < (SK_U32)pAC->GIni.GIMacsFound; Port++) {
2001 pPrt->PPrevRx = 0;
2002 pPrt->PPrevFcs = 0;
2003 pPrt->PPrevShorts = 0;
2004 }
2005 break;
2006
2007 case SK_HWEV_SET_LMODE:
2008 Val8 = (SK_U8)Para.Para32[1];
2009 if (pPrt->PLinkModeConf != Val8) {
2010 /* Set New link mode */
2011 pPrt->PLinkModeConf = Val8;
2012
2013 /* Restart Port */
2014 SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_STOP, Para);
2015 SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_START, Para);
2016 }
2017 break;
2018
2019 case SK_HWEV_SET_FLOWMODE:
2020 Val8 = (SK_U8)Para.Para32[1];
2021 if (pPrt->PFlowCtrlMode != Val8) {
2022 /* Set New Flow Control mode */
2023 pPrt->PFlowCtrlMode = Val8;
2024
2025 /* Restart Port */
2026 SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_STOP, Para);
2027 SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_START, Para);
2028 }
2029 break;
2030
2031 case SK_HWEV_SET_ROLE:
2032 /* not possible for fiber */
2033 if (!pAC->GIni.GICopperType) {
2034 break;
2035 }
2036 Val8 = (SK_U8)Para.Para32[1];
2037 if (pPrt->PMSMode != Val8) {
2038 /* Set New Role (Master/Slave) mode */
2039 pPrt->PMSMode = Val8;
2040
2041 /* Restart Port */
2042 SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_STOP, Para);
2043 SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_START, Para);
2044 }
2045 break;
2046
2047 case SK_HWEV_SET_SPEED:
2048 if (pPrt->PhyType != SK_PHY_MARV_COPPER) {
2049 break;
2050 }
2051 Val8 = (SK_U8)Para.Para32[1];
2052 if (pPrt->PLinkSpeed != Val8) {
2053 /* Set New Speed parameter */
2054 pPrt->PLinkSpeed = Val8;
2055
2056 /* Restart Port */
2057 SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_STOP, Para);
2058 SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_START, Para);
2059 }
2060 break;
2061
2062#ifdef GENESIS
2063 case SK_HWEV_HALFDUP_CHK:
2064 if (pAC->GIni.GIGenesis) {
2065 /*
2066 * half duplex hangup workaround.
2067 * See packet arbiter timeout interrupt for description
2068 */
2069 pPrt->HalfDupTimerActive = SK_FALSE;
2070 if (pPrt->PLinkModeStatus == SK_LMODE_STAT_HALF ||
2071 pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOHALF) {
2072 /* Snap statistic counters */
2073 (void)SkXmUpdateStats(pAC, IoC, Port);
2074
2075 (void)SkXmMacStatistic(pAC, IoC, Port, XM_TXO_OK_HI, &Val32);
2076
2077 Octets = (SK_U64)Val32 << 32;
2078
2079 (void)SkXmMacStatistic(pAC, IoC, Port, XM_TXO_OK_LO, &Val32);
2080
2081 Octets += Val32;
2082
2083 if (pPrt->LastOctets == Octets) {
2084 /* Tx hanging, a FIFO flush restarts it */
2085 SkMacFlushTxFifo(pAC, IoC, Port);
2086 }
2087 }
2088 }
2089 break;
2090#endif /* GENESIS */
2091
2092 default:
2093 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_SIRQ_E001, SKERR_SIRQ_E001MSG);
2094 break;
2095 }
2096
2097 return(0);
2098} /* SkGeSirqEvent */
2099
2100
2101#ifdef GENESIS
2102/******************************************************************************
2103 *
2104 * SkPhyIsrBcom() - PHY interrupt service routine
2105 *
2106 * Description: handles all interrupts from BCom PHY
2107 *
2108 * Returns: N/A
2109 */
2110static void SkPhyIsrBcom(
2111SK_AC *pAC, /* Adapter Context */
2112SK_IOC IoC, /* Io Context */
2113int Port, /* Port Num = PHY Num */
2114SK_U16 IStatus) /* Interrupt Status */
2115{
2116 SK_GEPORT *pPrt; /* GIni Port struct pointer */
2117 SK_EVPARA Para;
2118
2119 pPrt = &pAC->GIni.GP[Port];
2120
2121 if ((IStatus & PHY_B_IS_PSE) != 0) {
2122 /* Incorrectable pair swap error */
2123 SK_ERR_LOG(pAC, SK_ERRCL_HW | SK_ERRCL_INIT, SKERR_SIRQ_E022,
2124 SKERR_SIRQ_E022MSG);
2125 }
2126
2127 if ((IStatus & (PHY_B_IS_AN_PR | PHY_B_IS_LST_CHANGE)) != 0) {
2128
2129 SkHWLinkDown(pAC, IoC, Port);
2130
2131 Para.Para32[0] = (SK_U32)Port;
2132 /* Signal to RLMT */
2133 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
2134
2135 /* Start workaround Errata #2 timer */
2136 SkTimerStart(pAC, IoC, &pPrt->PWaTimer, SK_WA_INA_TIME,
2137 SKGE_HWAC, SK_HWEV_WATIM, Para);
2138 }
2139
2140} /* SkPhyIsrBcom */
2141#endif /* GENESIS */
2142
2143
2144#ifdef YUKON
2145/******************************************************************************
2146 *
2147 * SkPhyIsrGmac() - PHY interrupt service routine
2148 *
2149 * Description: handles all interrupts from Marvell PHY
2150 *
2151 * Returns: N/A
2152 */
2153static void SkPhyIsrGmac(
2154SK_AC *pAC, /* Adapter Context */
2155SK_IOC IoC, /* Io Context */
2156int Port, /* Port Num = PHY Num */
2157SK_U16 IStatus) /* Interrupt Status */
2158{
2159 SK_GEPORT *pPrt; /* GIni Port struct pointer */
2160 SK_EVPARA Para;
2161 SK_U16 Word;
2162
2163 pPrt = &pAC->GIni.GP[Port];
2164
2165 if ((IStatus & (PHY_M_IS_AN_PR | PHY_M_IS_LST_CHANGE)) != 0) {
2166
2167 SkHWLinkDown(pAC, IoC, Port);
2168
2169 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_ADV, &Word);
2170
2171 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2172 ("AutoNeg.Adv: 0x%04X\n", Word));
2173
2174 /* Set Auto-negotiation advertisement */
2175 if (pPrt->PFlowCtrlMode == SK_FLOW_MODE_SYM_OR_REM) {
2176 /* restore Asymmetric Pause bit */
2177 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_AUNE_ADV,
2178 (SK_U16)(Word | PHY_M_AN_ASP));
2179 }
2180
2181 Para.Para32[0] = (SK_U32)Port;
2182 /* Signal to RLMT */
2183 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
2184 }
2185
2186 if ((IStatus & PHY_M_IS_AN_ERROR) != 0) {
2187 /* Auto-Negotiation Error */
2188 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E023, SKERR_SIRQ_E023MSG);
2189 }
2190
2191 if ((IStatus & PHY_M_IS_FIFO_ERROR) != 0) {
2192 /* FIFO Overflow/Underrun Error */
2193 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E024, SKERR_SIRQ_E024MSG);
2194 }
2195
2196} /* SkPhyIsrGmac */
2197#endif /* YUKON */
2198
2199
2200#ifdef OTHER_PHY
2201/******************************************************************************
2202 *
2203 * SkPhyIsrLone() - PHY interrupt service routine
2204 *
2205 * Description: handles all interrupts from LONE PHY
2206 *
2207 * Returns: N/A
2208 */
2209static void SkPhyIsrLone(
2210SK_AC *pAC, /* Adapter Context */
2211SK_IOC IoC, /* Io Context */
2212int Port, /* Port Num = PHY Num */
2213SK_U16 IStatus) /* Interrupt Status */
2214{
2215 SK_EVPARA Para;
2216
2217 if (IStatus & (PHY_L_IS_DUP | PHY_L_IS_ISOL)) {
2218
2219 SkHWLinkDown(pAC, IoC, Port);
2220
2221 Para.Para32[0] = (SK_U32)Port;
2222 /* Signal to RLMT */
2223 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
2224 }
2225
2226} /* SkPhyIsrLone */
2227#endif /* OTHER_PHY */
2228
2229/* End of File */
diff --git a/drivers/net/sk98lin/ski2c.c b/drivers/net/sk98lin/ski2c.c
deleted file mode 100644
index 79bf57cb5326..000000000000
--- a/drivers/net/sk98lin/ski2c.c
+++ /dev/null
@@ -1,1296 +0,0 @@
1/******************************************************************************
2 *
3 * Name: ski2c.c
4 * Project: Gigabit Ethernet Adapters, TWSI-Module
5 * Version: $Revision: 1.59 $
6 * Date: $Date: 2003/10/20 09:07:25 $
7 * Purpose: Functions to access Voltage and Temperature Sensor
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25/*
26 * I2C Protocol
27 */
28#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
29static const char SysKonnectFileId[] =
30 "@(#) $Id: ski2c.c,v 1.59 2003/10/20 09:07:25 rschmidt Exp $ (C) Marvell. ";
31#endif
32
33#include "h/skdrv1st.h" /* Driver Specific Definitions */
34#include "h/lm80.h"
35#include "h/skdrv2nd.h" /* Adapter Control- and Driver specific Def. */
36
37#ifdef __C2MAN__
38/*
39 I2C protocol implementation.
40
41 General Description:
42
43 The I2C protocol is used for the temperature sensors and for
44 the serial EEPROM which hold the configuration.
45
46 This file covers functions that allow to read write and do
47 some bulk requests a specified I2C address.
48
49 The Genesis has 2 I2C buses. One for the EEPROM which holds
50 the VPD Data and one for temperature and voltage sensor.
51 The following picture shows the I2C buses, I2C devices and
52 their control registers.
53
54 Note: The VPD functions are in skvpd.c
55.
56. PCI Config I2C Bus for VPD Data:
57.
58. +------------+
59. | VPD EEPROM |
60. +------------+
61. |
62. | <-- I2C
63. |
64. +-----------+-----------+
65. | |
66. +-----------------+ +-----------------+
67. | PCI_VPD_ADR_REG | | PCI_VPD_DAT_REG |
68. +-----------------+ +-----------------+
69.
70.
71. I2C Bus for LM80 sensor:
72.
73. +-----------------+
74. | Temperature and |
75. | Voltage Sensor |
76. | LM80 |
77. +-----------------+
78. |
79. |
80. I2C --> |
81. |
82. +----+
83. +-------------->| OR |<--+
84. | +----+ |
85. +------+------+ |
86. | | |
87. +--------+ +--------+ +----------+
88. | B2_I2C | | B2_I2C | | B2_I2C |
89. | _CTRL | | _DATA | | _SW |
90. +--------+ +--------+ +----------+
91.
92 The I2C bus may be driven by the B2_I2C_SW or by the B2_I2C_CTRL
93 and B2_I2C_DATA registers.
94 For driver software it is recommended to use the I2C control and
95 data register, because I2C bus timing is done by the ASIC and
96 an interrupt may be received when the I2C request is completed.
97
98 Clock Rate Timing: MIN MAX generated by
99 VPD EEPROM: 50 kHz 100 kHz HW
100 LM80 over I2C Ctrl/Data reg. 50 kHz 100 kHz HW
101 LM80 over B2_I2C_SW register 0 400 kHz SW
102
103 Note: The clock generated by the hardware is dependend on the
104 PCI clock. If the PCI bus clock is 33 MHz, the I2C/VPD
105 clock is 50 kHz.
106 */
107intro()
108{}
109#endif
110
111#ifdef SK_DIAG
112/*
113 * I2C Fast Mode timing values used by the LM80.
114 * If new devices are added to the I2C bus the timing values have to be checked.
115 */
116#ifndef I2C_SLOW_TIMING
117#define T_CLK_LOW 1300L /* clock low time in ns */
118#define T_CLK_HIGH 600L /* clock high time in ns */
119#define T_DATA_IN_SETUP 100L /* data in Set-up Time */
120#define T_START_HOLD 600L /* start condition hold time */
121#define T_START_SETUP 600L /* start condition Set-up time */
122#define T_STOP_SETUP 600L /* stop condition Set-up time */
123#define T_BUS_IDLE 1300L /* time the bus must free after Tx */
124#define T_CLK_2_DATA_OUT 900L /* max. clock low to data output valid */
125#else /* I2C_SLOW_TIMING */
126/* I2C Standard Mode Timing */
127#define T_CLK_LOW 4700L /* clock low time in ns */
128#define T_CLK_HIGH 4000L /* clock high time in ns */
129#define T_DATA_IN_SETUP 250L /* data in Set-up Time */
130#define T_START_HOLD 4000L /* start condition hold time */
131#define T_START_SETUP 4700L /* start condition Set-up time */
132#define T_STOP_SETUP 4000L /* stop condition Set-up time */
133#define T_BUS_IDLE 4700L /* time the bus must free after Tx */
134#endif /* !I2C_SLOW_TIMING */
135
136#define NS2BCLK(x) (((x)*125)/10000)
137
138/*
139 * I2C Wire Operations
140 *
141 * About I2C_CLK_LOW():
142 *
143 * The Data Direction bit (I2C_DATA_DIR) has to be set to input when setting
144 * clock to low, to prevent the ASIC and the I2C data client from driving the
145 * serial data line simultaneously (ASIC: last bit of a byte = '1', I2C client
146 * send an 'ACK'). See also Concentrator Bugreport No. 10192.
147 */
148#define I2C_DATA_HIGH(IoC) SK_I2C_SET_BIT(IoC, I2C_DATA)
149#define I2C_DATA_LOW(IoC) SK_I2C_CLR_BIT(IoC, I2C_DATA)
150#define I2C_DATA_OUT(IoC) SK_I2C_SET_BIT(IoC, I2C_DATA_DIR)
151#define I2C_DATA_IN(IoC) SK_I2C_CLR_BIT(IoC, I2C_DATA_DIR | I2C_DATA)
152#define I2C_CLK_HIGH(IoC) SK_I2C_SET_BIT(IoC, I2C_CLK)
153#define I2C_CLK_LOW(IoC) SK_I2C_CLR_BIT(IoC, I2C_CLK | I2C_DATA_DIR)
154#define I2C_START_COND(IoC) SK_I2C_CLR_BIT(IoC, I2C_CLK)
155
156#define NS2CLKT(x) ((x*125L)/10000)
157
158/*--------------- I2C Interface Register Functions --------------- */
159
160/*
161 * sending one bit
162 */
163void SkI2cSndBit(
164SK_IOC IoC, /* I/O Context */
165SK_U8 Bit) /* Bit to send */
166{
167 I2C_DATA_OUT(IoC);
168 if (Bit) {
169 I2C_DATA_HIGH(IoC);
170 }
171 else {
172 I2C_DATA_LOW(IoC);
173 }
174 SkDgWaitTime(IoC, NS2BCLK(T_DATA_IN_SETUP));
175 I2C_CLK_HIGH(IoC);
176 SkDgWaitTime(IoC, NS2BCLK(T_CLK_HIGH));
177 I2C_CLK_LOW(IoC);
178} /* SkI2cSndBit*/
179
180
181/*
182 * Signal a start to the I2C Bus.
183 *
184 * A start is signaled when data goes to low in a high clock cycle.
185 *
186 * Ends with Clock Low.
187 *
188 * Status: not tested
189 */
190void SkI2cStart(
191SK_IOC IoC) /* I/O Context */
192{
193 /* Init data and Clock to output lines */
194 /* Set Data high */
195 I2C_DATA_OUT(IoC);
196 I2C_DATA_HIGH(IoC);
197 /* Set Clock high */
198 I2C_CLK_HIGH(IoC);
199
200 SkDgWaitTime(IoC, NS2BCLK(T_START_SETUP));
201
202 /* Set Data Low */
203 I2C_DATA_LOW(IoC);
204
205 SkDgWaitTime(IoC, NS2BCLK(T_START_HOLD));
206
207 /* Clock low without Data to Input */
208 I2C_START_COND(IoC);
209
210 SkDgWaitTime(IoC, NS2BCLK(T_CLK_LOW));
211} /* SkI2cStart */
212
213
214void SkI2cStop(
215SK_IOC IoC) /* I/O Context */
216{
217 /* Init data and Clock to output lines */
218 /* Set Data low */
219 I2C_DATA_OUT(IoC);
220 I2C_DATA_LOW(IoC);
221
222 SkDgWaitTime(IoC, NS2BCLK(T_CLK_2_DATA_OUT));
223
224 /* Set Clock high */
225 I2C_CLK_HIGH(IoC);
226
227 SkDgWaitTime(IoC, NS2BCLK(T_STOP_SETUP));
228
229 /*
230 * Set Data High: Do it by setting the Data Line to Input.
231 * Because of a pull up resistor the Data Line
232 * floods to high.
233 */
234 I2C_DATA_IN(IoC);
235
236 /*
237 * When I2C activity is stopped
238 * o DATA should be set to input and
239 * o CLOCK should be set to high!
240 */
241 SkDgWaitTime(IoC, NS2BCLK(T_BUS_IDLE));
242} /* SkI2cStop */
243
244
245/*
246 * Receive just one bit via the I2C bus.
247 *
248 * Note: Clock must be set to LOW before calling this function.
249 *
250 * Returns The received bit.
251 */
252int SkI2cRcvBit(
253SK_IOC IoC) /* I/O Context */
254{
255 int Bit;
256 SK_U8 I2cSwCtrl;
257
258 /* Init data as input line */
259 I2C_DATA_IN(IoC);
260
261 SkDgWaitTime(IoC, NS2BCLK(T_CLK_2_DATA_OUT));
262
263 I2C_CLK_HIGH(IoC);
264
265 SkDgWaitTime(IoC, NS2BCLK(T_CLK_HIGH));
266
267 SK_I2C_GET_SW(IoC, &I2cSwCtrl);
268
269 Bit = (I2cSwCtrl & I2C_DATA) ? 1 : 0;
270
271 I2C_CLK_LOW(IoC);
272 SkDgWaitTime(IoC, NS2BCLK(T_CLK_LOW-T_CLK_2_DATA_OUT));
273
274 return(Bit);
275} /* SkI2cRcvBit */
276
277
278/*
279 * Receive an ACK.
280 *
281 * returns 0 If acknowledged
282 * 1 in case of an error
283 */
284int SkI2cRcvAck(
285SK_IOC IoC) /* I/O Context */
286{
287 /*
288 * Received bit must be zero.
289 */
290 return(SkI2cRcvBit(IoC) != 0);
291} /* SkI2cRcvAck */
292
293
294/*
295 * Send an NACK.
296 */
297void SkI2cSndNAck(
298SK_IOC IoC) /* I/O Context */
299{
300 /*
301 * Received bit must be zero.
302 */
303 SkI2cSndBit(IoC, 1);
304} /* SkI2cSndNAck */
305
306
307/*
308 * Send an ACK.
309 */
310void SkI2cSndAck(
311SK_IOC IoC) /* I/O Context */
312{
313 /*
314 * Received bit must be zero.
315 */
316 SkI2cSndBit(IoC, 0);
317} /* SkI2cSndAck */
318
319
320/*
321 * Send one byte to the I2C device and wait for ACK.
322 *
323 * Return acknowleged status.
324 */
325int SkI2cSndByte(
326SK_IOC IoC, /* I/O Context */
327int Byte) /* byte to send */
328{
329 int i;
330
331 for (i = 0; i < 8; i++) {
332 if (Byte & (1<<(7-i))) {
333 SkI2cSndBit(IoC, 1);
334 }
335 else {
336 SkI2cSndBit(IoC, 0);
337 }
338 }
339
340 return(SkI2cRcvAck(IoC));
341} /* SkI2cSndByte */
342
343
344/*
345 * Receive one byte and ack it.
346 *
347 * Return byte.
348 */
349int SkI2cRcvByte(
350SK_IOC IoC, /* I/O Context */
351int Last) /* Last Byte Flag */
352{
353 int i;
354 int Byte = 0;
355
356 for (i = 0; i < 8; i++) {
357 Byte <<= 1;
358 Byte |= SkI2cRcvBit(IoC);
359 }
360
361 if (Last) {
362 SkI2cSndNAck(IoC);
363 }
364 else {
365 SkI2cSndAck(IoC);
366 }
367
368 return(Byte);
369} /* SkI2cRcvByte */
370
371
372/*
373 * Start dialog and send device address
374 *
375 * Return 0 if acknowleged, 1 in case of an error
376 */
377int SkI2cSndDev(
378SK_IOC IoC, /* I/O Context */
379int Addr, /* Device Address */
380int Rw) /* Read / Write Flag */
381{
382 SkI2cStart(IoC);
383 Rw = ~Rw;
384 Rw &= I2C_WRITE;
385 return(SkI2cSndByte(IoC, (Addr<<1) | Rw));
386} /* SkI2cSndDev */
387
388#endif /* SK_DIAG */
389
390/*----------------- I2C CTRL Register Functions ----------*/
391
392/*
393 * waits for a completion of an I2C transfer
394 *
395 * returns 0: success, transfer completes
396 * 1: error, transfer does not complete, I2C transfer
397 * killed, wait loop terminated.
398 */
399static int SkI2cWait(
400SK_AC *pAC, /* Adapter Context */
401SK_IOC IoC, /* I/O Context */
402int Event) /* complete event to wait for (I2C_READ or I2C_WRITE) */
403{
404 SK_U64 StartTime;
405 SK_U64 CurrentTime;
406 SK_U32 I2cCtrl;
407
408 StartTime = SkOsGetTime(pAC);
409
410 do {
411 CurrentTime = SkOsGetTime(pAC);
412
413 if (CurrentTime - StartTime > SK_TICKS_PER_SEC / 8) {
414
415 SK_I2C_STOP(IoC);
416#ifndef SK_DIAG
417 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E002, SKERR_I2C_E002MSG);
418#endif /* !SK_DIAG */
419 return(1);
420 }
421
422 SK_I2C_GET_CTL(IoC, &I2cCtrl);
423
424#ifdef xYUKON_DBG
425 printf("StartTime=%lu, CurrentTime=%lu\n",
426 StartTime, CurrentTime);
427 if (kbhit()) {
428 return(1);
429 }
430#endif /* YUKON_DBG */
431
432 } while ((I2cCtrl & I2C_FLAG) == (SK_U32)Event << 31);
433
434 return(0);
435} /* SkI2cWait */
436
437
438/*
439 * waits for a completion of an I2C transfer
440 *
441 * Returns
442 * Nothing
443 */
444void SkI2cWaitIrq(
445SK_AC *pAC, /* Adapter Context */
446SK_IOC IoC) /* I/O Context */
447{
448 SK_SENSOR *pSen;
449 SK_U64 StartTime;
450 SK_U32 IrqSrc;
451
452 pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
453
454 if (pSen->SenState == SK_SEN_IDLE) {
455 return;
456 }
457
458 StartTime = SkOsGetTime(pAC);
459
460 do {
461 if (SkOsGetTime(pAC) - StartTime > SK_TICKS_PER_SEC / 8) {
462
463 SK_I2C_STOP(IoC);
464#ifndef SK_DIAG
465 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E016, SKERR_I2C_E016MSG);
466#endif /* !SK_DIAG */
467 return;
468 }
469
470 SK_IN32(IoC, B0_ISRC, &IrqSrc);
471
472 } while ((IrqSrc & IS_I2C_READY) == 0);
473
474 pSen->SenState = SK_SEN_IDLE;
475 return;
476} /* SkI2cWaitIrq */
477
478/*
479 * writes a single byte or 4 bytes into the I2C device
480 *
481 * returns 0: success
482 * 1: error
483 */
484static int SkI2cWrite(
485SK_AC *pAC, /* Adapter Context */
486SK_IOC IoC, /* I/O Context */
487SK_U32 I2cData, /* I2C Data to write */
488int I2cDev, /* I2C Device Address */
489int I2cDevSize, /* I2C Device Size (e.g. I2C_025K_DEV or I2C_2K_DEV) */
490int I2cReg, /* I2C Device Register Address */
491int I2cBurst) /* I2C Burst Flag */
492{
493 SK_OUT32(IoC, B2_I2C_DATA, I2cData);
494
495 SK_I2C_CTL(IoC, I2C_WRITE, I2cDev, I2cDevSize, I2cReg, I2cBurst);
496
497 return(SkI2cWait(pAC, IoC, I2C_WRITE));
498} /* SkI2cWrite*/
499
500
501#ifdef SK_DIAG
502/*
503 * reads a single byte or 4 bytes from the I2C device
504 *
505 * returns the word read
506 */
507SK_U32 SkI2cRead(
508SK_AC *pAC, /* Adapter Context */
509SK_IOC IoC, /* I/O Context */
510int I2cDev, /* I2C Device Address */
511int I2cDevSize, /* I2C Device Size (e.g. I2C_025K_DEV or I2C_2K_DEV) */
512int I2cReg, /* I2C Device Register Address */
513int I2cBurst) /* I2C Burst Flag */
514{
515 SK_U32 Data;
516
517 SK_OUT32(IoC, B2_I2C_DATA, 0);
518 SK_I2C_CTL(IoC, I2C_READ, I2cDev, I2cDevSize, I2cReg, I2cBurst);
519
520 if (SkI2cWait(pAC, IoC, I2C_READ) != 0) {
521 w_print("%s\n", SKERR_I2C_E002MSG);
522 }
523
524 SK_IN32(IoC, B2_I2C_DATA, &Data);
525
526 return(Data);
527} /* SkI2cRead */
528#endif /* SK_DIAG */
529
530
531/*
532 * read a sensor's value
533 *
534 * This function reads a sensor's value from the I2C sensor chip. The sensor
535 * is defined by its index into the sensors database in the struct pAC points
536 * to.
537 * Returns
538 * 1 if the read is completed
539 * 0 if the read must be continued (I2C Bus still allocated)
540 */
541static int SkI2cReadSensor(
542SK_AC *pAC, /* Adapter Context */
543SK_IOC IoC, /* I/O Context */
544SK_SENSOR *pSen) /* Sensor to be read */
545{
546 if (pSen->SenRead != NULL) {
547 return((*pSen->SenRead)(pAC, IoC, pSen));
548 }
549 else {
550 return(0); /* no success */
551 }
552} /* SkI2cReadSensor */
553
554/*
555 * Do the Init state 0 initialization
556 */
557static int SkI2cInit0(
558SK_AC *pAC) /* Adapter Context */
559{
560 int i;
561
562 /* Begin with first sensor */
563 pAC->I2c.CurrSens = 0;
564
565 /* Begin with timeout control for state machine */
566 pAC->I2c.TimerMode = SK_TIMER_WATCH_SM;
567
568 /* Set sensor number to zero */
569 pAC->I2c.MaxSens = 0;
570
571#ifndef SK_DIAG
572 /* Initialize Number of Dummy Reads */
573 pAC->I2c.DummyReads = SK_MAX_SENSORS;
574#endif
575
576 for (i = 0; i < SK_MAX_SENSORS; i++) {
577 pAC->I2c.SenTable[i].SenDesc = "unknown";
578 pAC->I2c.SenTable[i].SenType = SK_SEN_UNKNOWN;
579 pAC->I2c.SenTable[i].SenThreErrHigh = 0;
580 pAC->I2c.SenTable[i].SenThreErrLow = 0;
581 pAC->I2c.SenTable[i].SenThreWarnHigh = 0;
582 pAC->I2c.SenTable[i].SenThreWarnLow = 0;
583 pAC->I2c.SenTable[i].SenReg = LM80_FAN2_IN;
584 pAC->I2c.SenTable[i].SenInit = SK_SEN_DYN_INIT_NONE;
585 pAC->I2c.SenTable[i].SenValue = 0;
586 pAC->I2c.SenTable[i].SenErrFlag = SK_SEN_ERR_NOT_PRESENT;
587 pAC->I2c.SenTable[i].SenErrCts = 0;
588 pAC->I2c.SenTable[i].SenBegErrTS = 0;
589 pAC->I2c.SenTable[i].SenState = SK_SEN_IDLE;
590 pAC->I2c.SenTable[i].SenRead = NULL;
591 pAC->I2c.SenTable[i].SenDev = 0;
592 }
593
594 /* Now we are "INIT data"ed */
595 pAC->I2c.InitLevel = SK_INIT_DATA;
596 return(0);
597} /* SkI2cInit0*/
598
599
600/*
601 * Do the init state 1 initialization
602 *
603 * initialize the following register of the LM80:
604 * Configuration register:
605 * - START, noINT, activeLOW, noINT#Clear, noRESET, noCI, noGPO#, noINIT
606 *
607 * Interrupt Mask Register 1:
608 * - all interrupts are Disabled (0xff)
609 *
610 * Interrupt Mask Register 2:
611 * - all interrupts are Disabled (0xff) Interrupt modi doesn't matter.
612 *
613 * Fan Divisor/RST_OUT register:
614 * - Divisors set to 1 (bits 00), all others 0s.
615 *
616 * OS# Configuration/Temperature resolution Register:
617 * - all 0s
618 *
619 */
620static int SkI2cInit1(
621SK_AC *pAC, /* Adapter Context */
622SK_IOC IoC) /* I/O Context */
623{
624 int i;
625 SK_U8 I2cSwCtrl;
626 SK_GEPORT *pPrt; /* GIni Port struct pointer */
627
628 if (pAC->I2c.InitLevel != SK_INIT_DATA) {
629 /* ReInit not needed in I2C module */
630 return(0);
631 }
632
633 /* Set the Direction of I2C-Data Pin to IN */
634 SK_I2C_CLR_BIT(IoC, I2C_DATA_DIR | I2C_DATA);
635 /* Check for 32-Bit Yukon with Low at I2C-Data Pin */
636 SK_I2C_GET_SW(IoC, &I2cSwCtrl);
637
638 if ((I2cSwCtrl & I2C_DATA) == 0) {
639 /* this is a 32-Bit board */
640 pAC->GIni.GIYukon32Bit = SK_TRUE;
641 return(0);
642 }
643
644 /* Check for 64 Bit Yukon without sensors */
645 if (SkI2cWrite(pAC, IoC, 0, LM80_ADDR, I2C_025K_DEV, LM80_CFG, 0) != 0) {
646 return(0);
647 }
648
649 (void)SkI2cWrite(pAC, IoC, 0xffUL, LM80_ADDR, I2C_025K_DEV, LM80_IMSK_1, 0);
650
651 (void)SkI2cWrite(pAC, IoC, 0xffUL, LM80_ADDR, I2C_025K_DEV, LM80_IMSK_2, 0);
652
653 (void)SkI2cWrite(pAC, IoC, 0, LM80_ADDR, I2C_025K_DEV, LM80_FAN_CTRL, 0);
654
655 (void)SkI2cWrite(pAC, IoC, 0, LM80_ADDR, I2C_025K_DEV, LM80_TEMP_CTRL, 0);
656
657 (void)SkI2cWrite(pAC, IoC, (SK_U32)LM80_CFG_START, LM80_ADDR, I2C_025K_DEV,
658 LM80_CFG, 0);
659
660 /*
661 * MaxSens has to be updated here, because PhyType is not
662 * set when performing Init Level 0
663 */
664 pAC->I2c.MaxSens = 5;
665
666 pPrt = &pAC->GIni.GP[0];
667
668 if (pAC->GIni.GIGenesis) {
669 if (pPrt->PhyType == SK_PHY_BCOM) {
670 if (pAC->GIni.GIMacsFound == 1) {
671 pAC->I2c.MaxSens += 1;
672 }
673 else {
674 pAC->I2c.MaxSens += 3;
675 }
676 }
677 }
678 else {
679 pAC->I2c.MaxSens += 3;
680 }
681
682 for (i = 0; i < pAC->I2c.MaxSens; i++) {
683 switch (i) {
684 case 0:
685 pAC->I2c.SenTable[i].SenDesc = "Temperature";
686 pAC->I2c.SenTable[i].SenType = SK_SEN_TEMP;
687 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_TEMP_HIGH_ERR;
688 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_TEMP_HIGH_WARN;
689 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_TEMP_LOW_WARN;
690 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_TEMP_LOW_ERR;
691 pAC->I2c.SenTable[i].SenReg = LM80_TEMP_IN;
692 break;
693 case 1:
694 pAC->I2c.SenTable[i].SenDesc = "Voltage PCI";
695 pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
696 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PCI_5V_HIGH_ERR;
697 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PCI_5V_HIGH_WARN;
698 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PCI_5V_LOW_WARN;
699 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PCI_5V_LOW_ERR;
700 pAC->I2c.SenTable[i].SenReg = LM80_VT0_IN;
701 break;
702 case 2:
703 pAC->I2c.SenTable[i].SenDesc = "Voltage PCI-IO";
704 pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
705 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PCI_IO_5V_HIGH_ERR;
706 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PCI_IO_5V_HIGH_WARN;
707 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PCI_IO_3V3_LOW_WARN;
708 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PCI_IO_3V3_LOW_ERR;
709 pAC->I2c.SenTable[i].SenReg = LM80_VT1_IN;
710 pAC->I2c.SenTable[i].SenInit = SK_SEN_DYN_INIT_PCI_IO;
711 break;
712 case 3:
713 pAC->I2c.SenTable[i].SenDesc = "Voltage ASIC";
714 pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
715 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_VDD_HIGH_ERR;
716 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_VDD_HIGH_WARN;
717 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_VDD_LOW_WARN;
718 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_VDD_LOW_ERR;
719 pAC->I2c.SenTable[i].SenReg = LM80_VT2_IN;
720 break;
721 case 4:
722 if (pAC->GIni.GIGenesis) {
723 if (pPrt->PhyType == SK_PHY_BCOM) {
724 pAC->I2c.SenTable[i].SenDesc = "Voltage PHY A PLL";
725 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PLL_3V3_HIGH_ERR;
726 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PLL_3V3_HIGH_WARN;
727 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PLL_3V3_LOW_WARN;
728 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PLL_3V3_LOW_ERR;
729 }
730 else {
731 pAC->I2c.SenTable[i].SenDesc = "Voltage PMA";
732 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PLL_3V3_HIGH_ERR;
733 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PLL_3V3_HIGH_WARN;
734 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PLL_3V3_LOW_WARN;
735 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PLL_3V3_LOW_ERR;
736 }
737 }
738 else {
739 pAC->I2c.SenTable[i].SenDesc = "Voltage VAUX";
740 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_VAUX_3V3_HIGH_ERR;
741 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_VAUX_3V3_HIGH_WARN;
742 if (pAC->GIni.GIVauxAvail) {
743 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_VAUX_3V3_LOW_WARN;
744 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_VAUX_3V3_LOW_ERR;
745 }
746 else {
747 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_VAUX_0V_WARN_ERR;
748 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_VAUX_0V_WARN_ERR;
749 }
750 }
751 pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
752 pAC->I2c.SenTable[i].SenReg = LM80_VT3_IN;
753 break;
754 case 5:
755 if (pAC->GIni.GIGenesis) {
756 pAC->I2c.SenTable[i].SenDesc = "Voltage PHY 2V5";
757 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PHY_2V5_HIGH_ERR;
758 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PHY_2V5_HIGH_WARN;
759 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PHY_2V5_LOW_WARN;
760 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PHY_2V5_LOW_ERR;
761 }
762 else {
763 pAC->I2c.SenTable[i].SenDesc = "Voltage Core 1V5";
764 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_CORE_1V5_HIGH_ERR;
765 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_CORE_1V5_HIGH_WARN;
766 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_CORE_1V5_LOW_WARN;
767 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_CORE_1V5_LOW_ERR;
768 }
769 pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
770 pAC->I2c.SenTable[i].SenReg = LM80_VT4_IN;
771 break;
772 case 6:
773 if (pAC->GIni.GIGenesis) {
774 pAC->I2c.SenTable[i].SenDesc = "Voltage PHY B PLL";
775 }
776 else {
777 pAC->I2c.SenTable[i].SenDesc = "Voltage PHY 3V3";
778 }
779 pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
780 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PLL_3V3_HIGH_ERR;
781 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PLL_3V3_HIGH_WARN;
782 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PLL_3V3_LOW_WARN;
783 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PLL_3V3_LOW_ERR;
784 pAC->I2c.SenTable[i].SenReg = LM80_VT5_IN;
785 break;
786 case 7:
787 if (pAC->GIni.GIGenesis) {
788 pAC->I2c.SenTable[i].SenDesc = "Speed Fan";
789 pAC->I2c.SenTable[i].SenType = SK_SEN_FAN;
790 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_FAN_HIGH_ERR;
791 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_FAN_HIGH_WARN;
792 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_FAN_LOW_WARN;
793 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_FAN_LOW_ERR;
794 pAC->I2c.SenTable[i].SenReg = LM80_FAN2_IN;
795 }
796 else {
797 pAC->I2c.SenTable[i].SenDesc = "Voltage PHY 2V5";
798 pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT;
799 pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PHY_2V5_HIGH_ERR;
800 pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PHY_2V5_HIGH_WARN;
801 pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PHY_2V5_LOW_WARN;
802 pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PHY_2V5_LOW_ERR;
803 pAC->I2c.SenTable[i].SenReg = LM80_VT6_IN;
804 }
805 break;
806 default:
807 SK_ERR_LOG(pAC, SK_ERRCL_INIT | SK_ERRCL_SW,
808 SKERR_I2C_E001, SKERR_I2C_E001MSG);
809 break;
810 }
811
812 pAC->I2c.SenTable[i].SenValue = 0;
813 pAC->I2c.SenTable[i].SenErrFlag = SK_SEN_ERR_OK;
814 pAC->I2c.SenTable[i].SenErrCts = 0;
815 pAC->I2c.SenTable[i].SenBegErrTS = 0;
816 pAC->I2c.SenTable[i].SenState = SK_SEN_IDLE;
817 pAC->I2c.SenTable[i].SenRead = SkLm80ReadSensor;
818 pAC->I2c.SenTable[i].SenDev = LM80_ADDR;
819 }
820
821#ifndef SK_DIAG
822 pAC->I2c.DummyReads = pAC->I2c.MaxSens;
823#endif /* !SK_DIAG */
824
825 /* Clear I2C IRQ */
826 SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ);
827
828 /* Now we are I/O initialized */
829 pAC->I2c.InitLevel = SK_INIT_IO;
830 return(0);
831} /* SkI2cInit1 */
832
833
834/*
835 * Init level 2: Start first sensor read.
836 */
837static int SkI2cInit2(
838SK_AC *pAC, /* Adapter Context */
839SK_IOC IoC) /* I/O Context */
840{
841 int ReadComplete;
842 SK_SENSOR *pSen;
843
844 if (pAC->I2c.InitLevel != SK_INIT_IO) {
845 /* ReInit not needed in I2C module */
846 /* Init0 and Init2 not permitted */
847 return(0);
848 }
849
850 pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
851 ReadComplete = SkI2cReadSensor(pAC, IoC, pSen);
852
853 if (ReadComplete) {
854 SK_ERR_LOG(pAC, SK_ERRCL_INIT, SKERR_I2C_E008, SKERR_I2C_E008MSG);
855 }
856
857 /* Now we are correctly initialized */
858 pAC->I2c.InitLevel = SK_INIT_RUN;
859
860 return(0);
861} /* SkI2cInit2*/
862
863
864/*
865 * Initialize I2C devices
866 *
867 * Get the first voltage value and discard it.
868 * Go into temperature read mode. A default pointer is not set.
869 *
870 * The things to be done depend on the init level in the parameter list:
871 * Level 0:
872 * Initialize only the data structures. Do NOT access hardware.
873 * Level 1:
874 * Initialize hardware through SK_IN / SK_OUT commands. Do NOT use interrupts.
875 * Level 2:
876 * Everything is possible. Interrupts may be used from now on.
877 *
878 * return:
879 * 0 = success
880 * other = error.
881 */
882int SkI2cInit(
883SK_AC *pAC, /* Adapter Context */
884SK_IOC IoC, /* I/O Context needed in levels 1 and 2 */
885int Level) /* Init Level */
886{
887
888 switch (Level) {
889 case SK_INIT_DATA:
890 return(SkI2cInit0(pAC));
891 case SK_INIT_IO:
892 return(SkI2cInit1(pAC, IoC));
893 case SK_INIT_RUN:
894 return(SkI2cInit2(pAC, IoC));
895 default:
896 break;
897 }
898
899 return(0);
900} /* SkI2cInit */
901
902
903#ifndef SK_DIAG
904
905/*
906 * Interrupt service function for the I2C Interface
907 *
908 * Clears the Interrupt source
909 *
910 * Reads the register and check it for sending a trap.
911 *
912 * Starts the timer if necessary.
913 */
914void SkI2cIsr(
915SK_AC *pAC, /* Adapter Context */
916SK_IOC IoC) /* I/O Context */
917{
918 SK_EVPARA Para;
919
920 /* Clear I2C IRQ */
921 SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ);
922
923 Para.Para64 = 0;
924 SkEventQueue(pAC, SKGE_I2C, SK_I2CEV_IRQ, Para);
925} /* SkI2cIsr */
926
927
928/*
929 * Check this sensors Value against the threshold and send events.
930 */
931static void SkI2cCheckSensor(
932SK_AC *pAC, /* Adapter Context */
933SK_SENSOR *pSen)
934{
935 SK_EVPARA ParaLocal;
936 SK_BOOL TooHigh; /* Is sensor too high? */
937 SK_BOOL TooLow; /* Is sensor too low? */
938 SK_U64 CurrTime; /* Current Time */
939 SK_BOOL DoTrapSend; /* We need to send a trap */
940 SK_BOOL DoErrLog; /* We need to log the error */
941 SK_BOOL IsError; /* We need to log the error */
942
943 /* Check Dummy Reads first */
944 if (pAC->I2c.DummyReads > 0) {
945 pAC->I2c.DummyReads--;
946 return;
947 }
948
949 /* Get the current time */
950 CurrTime = SkOsGetTime(pAC);
951
952 /* Set para to the most useful setting: The current sensor. */
953 ParaLocal.Para64 = (SK_U64)pAC->I2c.CurrSens;
954
955 /* Check the Value against the thresholds. First: Error Thresholds */
956 TooHigh = (pSen->SenValue > pSen->SenThreErrHigh);
957 TooLow = (pSen->SenValue < pSen->SenThreErrLow);
958
959 IsError = SK_FALSE;
960 if (TooHigh || TooLow) {
961 /* Error condition is satisfied */
962 DoTrapSend = SK_TRUE;
963 DoErrLog = SK_TRUE;
964
965 /* Now error condition is satisfied */
966 IsError = SK_TRUE;
967
968 if (pSen->SenErrFlag == SK_SEN_ERR_ERR) {
969 /* This state is the former one */
970
971 /* So check first whether we have to send a trap */
972 if (pSen->SenLastErrTrapTS + SK_SEN_ERR_TR_HOLD >
973 CurrTime) {
974 /*
975 * Do NOT send the Trap. The hold back time
976 * has to run out first.
977 */
978 DoTrapSend = SK_FALSE;
979 }
980
981 /* Check now whether we have to log an Error */
982 if (pSen->SenLastErrLogTS + SK_SEN_ERR_LOG_HOLD >
983 CurrTime) {
984 /*
985 * Do NOT log the error. The hold back time
986 * has to run out first.
987 */
988 DoErrLog = SK_FALSE;
989 }
990 }
991 else {
992 /* We came from a different state -> Set Begin Time Stamp */
993 pSen->SenBegErrTS = CurrTime;
994 pSen->SenErrFlag = SK_SEN_ERR_ERR;
995 }
996
997 if (DoTrapSend) {
998 /* Set current Time */
999 pSen->SenLastErrTrapTS = CurrTime;
1000 pSen->SenErrCts++;
1001
1002 /* Queue PNMI Event */
1003 SkEventQueue(pAC, SKGE_PNMI, (TooHigh ?
1004 SK_PNMI_EVT_SEN_ERR_UPP :
1005 SK_PNMI_EVT_SEN_ERR_LOW),
1006 ParaLocal);
1007 }
1008
1009 if (DoErrLog) {
1010 /* Set current Time */
1011 pSen->SenLastErrLogTS = CurrTime;
1012
1013 if (pSen->SenType == SK_SEN_TEMP) {
1014 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E011, SKERR_I2C_E011MSG);
1015 }
1016 else if (pSen->SenType == SK_SEN_VOLT) {
1017 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E012, SKERR_I2C_E012MSG);
1018 }
1019 else {
1020 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E015, SKERR_I2C_E015MSG);
1021 }
1022 }
1023 }
1024
1025 /* Check the Value against the thresholds */
1026 /* 2nd: Warning thresholds */
1027 TooHigh = (pSen->SenValue > pSen->SenThreWarnHigh);
1028 TooLow = (pSen->SenValue < pSen->SenThreWarnLow);
1029
1030 if (!IsError && (TooHigh || TooLow)) {
1031 /* Error condition is satisfied */
1032 DoTrapSend = SK_TRUE;
1033 DoErrLog = SK_TRUE;
1034
1035 if (pSen->SenErrFlag == SK_SEN_ERR_WARN) {
1036 /* This state is the former one */
1037
1038 /* So check first whether we have to send a trap */
1039 if (pSen->SenLastWarnTrapTS + SK_SEN_WARN_TR_HOLD > CurrTime) {
1040 /*
1041 * Do NOT send the Trap. The hold back time
1042 * has to run out first.
1043 */
1044 DoTrapSend = SK_FALSE;
1045 }
1046
1047 /* Check now whether we have to log an Error */
1048 if (pSen->SenLastWarnLogTS + SK_SEN_WARN_LOG_HOLD > CurrTime) {
1049 /*
1050 * Do NOT log the error. The hold back time
1051 * has to run out first.
1052 */
1053 DoErrLog = SK_FALSE;
1054 }
1055 }
1056 else {
1057 /* We came from a different state -> Set Begin Time Stamp */
1058 pSen->SenBegWarnTS = CurrTime;
1059 pSen->SenErrFlag = SK_SEN_ERR_WARN;
1060 }
1061
1062 if (DoTrapSend) {
1063 /* Set current Time */
1064 pSen->SenLastWarnTrapTS = CurrTime;
1065 pSen->SenWarnCts++;
1066
1067 /* Queue PNMI Event */
1068 SkEventQueue(pAC, SKGE_PNMI, (TooHigh ?
1069 SK_PNMI_EVT_SEN_WAR_UPP :
1070 SK_PNMI_EVT_SEN_WAR_LOW),
1071 ParaLocal);
1072 }
1073
1074 if (DoErrLog) {
1075 /* Set current Time */
1076 pSen->SenLastWarnLogTS = CurrTime;
1077
1078 if (pSen->SenType == SK_SEN_TEMP) {
1079 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E009, SKERR_I2C_E009MSG);
1080 }
1081 else if (pSen->SenType == SK_SEN_VOLT) {
1082 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E010, SKERR_I2C_E010MSG);
1083 }
1084 else {
1085 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E014, SKERR_I2C_E014MSG);
1086 }
1087 }
1088 }
1089
1090 /* Check for NO error at all */
1091 if (!IsError && !TooHigh && !TooLow) {
1092 /* Set o.k. Status if no error and no warning condition */
1093 pSen->SenErrFlag = SK_SEN_ERR_OK;
1094 }
1095
1096 /* End of check against the thresholds */
1097
1098 /* Bug fix AF: 16.Aug.2001: Correct the init base
1099 * of LM80 sensor.
1100 */
1101 if (pSen->SenInit == SK_SEN_DYN_INIT_PCI_IO) {
1102
1103 pSen->SenInit = SK_SEN_DYN_INIT_NONE;
1104
1105 if (pSen->SenValue > SK_SEN_PCI_IO_RANGE_LIMITER) {
1106 /* 5V PCI-IO Voltage */
1107 pSen->SenThreWarnLow = SK_SEN_PCI_IO_5V_LOW_WARN;
1108 pSen->SenThreErrLow = SK_SEN_PCI_IO_5V_LOW_ERR;
1109 }
1110 else {
1111 /* 3.3V PCI-IO Voltage */
1112 pSen->SenThreWarnHigh = SK_SEN_PCI_IO_3V3_HIGH_WARN;
1113 pSen->SenThreErrHigh = SK_SEN_PCI_IO_3V3_HIGH_ERR;
1114 }
1115 }
1116
1117#ifdef TEST_ONLY
1118 /* Dynamic thresholds also for VAUX of LM80 sensor */
1119 if (pSen->SenInit == SK_SEN_DYN_INIT_VAUX) {
1120
1121 pSen->SenInit = SK_SEN_DYN_INIT_NONE;
1122
1123 /* 3.3V VAUX Voltage */
1124 if (pSen->SenValue > SK_SEN_VAUX_RANGE_LIMITER) {
1125 pSen->SenThreWarnLow = SK_SEN_VAUX_3V3_LOW_WARN;
1126 pSen->SenThreErrLow = SK_SEN_VAUX_3V3_LOW_ERR;
1127 }
1128 /* 0V VAUX Voltage */
1129 else {
1130 pSen->SenThreWarnHigh = SK_SEN_VAUX_0V_WARN_ERR;
1131 pSen->SenThreErrHigh = SK_SEN_VAUX_0V_WARN_ERR;
1132 }
1133 }
1134
1135 /*
1136 * Check initialization state:
1137 * The VIO Thresholds need adaption
1138 */
1139 if (!pSen->SenInit && pSen->SenReg == LM80_VT1_IN &&
1140 pSen->SenValue > SK_SEN_WARNLOW2C &&
1141 pSen->SenValue < SK_SEN_WARNHIGH2) {
1142 pSen->SenThreErrLow = SK_SEN_ERRLOW2C;
1143 pSen->SenThreWarnLow = SK_SEN_WARNLOW2C;
1144 pSen->SenInit = SK_TRUE;
1145 }
1146
1147 if (!pSen->SenInit && pSen->SenReg == LM80_VT1_IN &&
1148 pSen->SenValue > SK_SEN_WARNLOW2 &&
1149 pSen->SenValue < SK_SEN_WARNHIGH2C) {
1150 pSen->SenThreErrHigh = SK_SEN_ERRHIGH2C;
1151 pSen->SenThreWarnHigh = SK_SEN_WARNHIGH2C;
1152 pSen->SenInit = SK_TRUE;
1153 }
1154#endif
1155
1156 if (pSen->SenInit != SK_SEN_DYN_INIT_NONE) {
1157 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E013, SKERR_I2C_E013MSG);
1158 }
1159} /* SkI2cCheckSensor */
1160
1161
1162/*
1163 * The only Event to be served is the timeout event
1164 *
1165 */
1166int SkI2cEvent(
1167SK_AC *pAC, /* Adapter Context */
1168SK_IOC IoC, /* I/O Context */
1169SK_U32 Event, /* Module specific Event */
1170SK_EVPARA Para) /* Event specific Parameter */
1171{
1172 int ReadComplete;
1173 SK_SENSOR *pSen;
1174 SK_U32 Time;
1175 SK_EVPARA ParaLocal;
1176 int i;
1177
1178 /* New case: no sensors */
1179 if (pAC->I2c.MaxSens == 0) {
1180 return(0);
1181 }
1182
1183 switch (Event) {
1184 case SK_I2CEV_IRQ:
1185 pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
1186 ReadComplete = SkI2cReadSensor(pAC, IoC, pSen);
1187
1188 if (ReadComplete) {
1189 /* Check sensor against defined thresholds */
1190 SkI2cCheckSensor(pAC, pSen);
1191
1192 /* Increment Current sensor and set appropriate Timeout */
1193 pAC->I2c.CurrSens++;
1194 if (pAC->I2c.CurrSens >= pAC->I2c.MaxSens) {
1195 pAC->I2c.CurrSens = 0;
1196 Time = SK_I2C_TIM_LONG;
1197 }
1198 else {
1199 Time = SK_I2C_TIM_SHORT;
1200 }
1201
1202 /* Start Timer */
1203 ParaLocal.Para64 = (SK_U64)0;
1204
1205 pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING;
1206
1207 SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time,
1208 SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
1209 }
1210 else {
1211 /* Start Timer */
1212 ParaLocal.Para64 = (SK_U64)0;
1213
1214 pAC->I2c.TimerMode = SK_TIMER_WATCH_SM;
1215
1216 SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, SK_I2C_TIM_WATCH,
1217 SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
1218 }
1219 break;
1220 case SK_I2CEV_TIM:
1221 if (pAC->I2c.TimerMode == SK_TIMER_NEW_GAUGING) {
1222
1223 ParaLocal.Para64 = (SK_U64)0;
1224 SkTimerStop(pAC, IoC, &pAC->I2c.SenTimer);
1225
1226 pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
1227 ReadComplete = SkI2cReadSensor(pAC, IoC, pSen);
1228
1229 if (ReadComplete) {
1230 /* Check sensor against defined thresholds */
1231 SkI2cCheckSensor(pAC, pSen);
1232
1233 /* Increment Current sensor and set appropriate Timeout */
1234 pAC->I2c.CurrSens++;
1235 if (pAC->I2c.CurrSens == pAC->I2c.MaxSens) {
1236 pAC->I2c.CurrSens = 0;
1237 Time = SK_I2C_TIM_LONG;
1238 }
1239 else {
1240 Time = SK_I2C_TIM_SHORT;
1241 }
1242
1243 /* Start Timer */
1244 ParaLocal.Para64 = (SK_U64)0;
1245
1246 pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING;
1247
1248 SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time,
1249 SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
1250 }
1251 }
1252 else {
1253 pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
1254 pSen->SenErrFlag = SK_SEN_ERR_FAULTY;
1255 SK_I2C_STOP(IoC);
1256
1257 /* Increment Current sensor and set appropriate Timeout */
1258 pAC->I2c.CurrSens++;
1259 if (pAC->I2c.CurrSens == pAC->I2c.MaxSens) {
1260 pAC->I2c.CurrSens = 0;
1261 Time = SK_I2C_TIM_LONG;
1262 }
1263 else {
1264 Time = SK_I2C_TIM_SHORT;
1265 }
1266
1267 /* Start Timer */
1268 ParaLocal.Para64 = (SK_U64)0;
1269
1270 pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING;
1271
1272 SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time,
1273 SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
1274 }
1275 break;
1276 case SK_I2CEV_CLEAR:
1277 for (i = 0; i < SK_MAX_SENSORS; i++) {
1278 pAC->I2c.SenTable[i].SenErrFlag = SK_SEN_ERR_OK;
1279 pAC->I2c.SenTable[i].SenErrCts = 0;
1280 pAC->I2c.SenTable[i].SenWarnCts = 0;
1281 pAC->I2c.SenTable[i].SenBegErrTS = 0;
1282 pAC->I2c.SenTable[i].SenBegWarnTS = 0;
1283 pAC->I2c.SenTable[i].SenLastErrTrapTS = (SK_U64)0;
1284 pAC->I2c.SenTable[i].SenLastErrLogTS = (SK_U64)0;
1285 pAC->I2c.SenTable[i].SenLastWarnTrapTS = (SK_U64)0;
1286 pAC->I2c.SenTable[i].SenLastWarnLogTS = (SK_U64)0;
1287 }
1288 break;
1289 default:
1290 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E006, SKERR_I2C_E006MSG);
1291 }
1292
1293 return(0);
1294} /* SkI2cEvent*/
1295
1296#endif /* !SK_DIAG */
diff --git a/drivers/net/sk98lin/sklm80.c b/drivers/net/sk98lin/sklm80.c
deleted file mode 100644
index a204f5bb55d4..000000000000
--- a/drivers/net/sk98lin/sklm80.c
+++ /dev/null
@@ -1,141 +0,0 @@
1/******************************************************************************
2 *
3 * Name: sklm80.c
4 * Project: Gigabit Ethernet Adapters, TWSI-Module
5 * Version: $Revision: 1.22 $
6 * Date: $Date: 2003/10/20 09:08:21 $
7 * Purpose: Functions to access Voltage and Temperature Sensor (LM80)
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25/*
26 LM80 functions
27*/
28#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
29static const char SysKonnectFileId[] =
30 "@(#) $Id: sklm80.c,v 1.22 2003/10/20 09:08:21 rschmidt Exp $ (C) Marvell. ";
31#endif
32
33#include "h/skdrv1st.h" /* Driver Specific Definitions */
34#include "h/lm80.h"
35#include "h/skdrv2nd.h" /* Adapter Control- and Driver specific Def. */
36
37#define BREAK_OR_WAIT(pAC,IoC,Event) break
38
39/*
40 * read a sensors value (LM80 specific)
41 *
42 * This function reads a sensors value from the I2C sensor chip LM80.
43 * The sensor is defined by its index into the sensors database in the struct
44 * pAC points to.
45 *
46 * Returns 1 if the read is completed
47 * 0 if the read must be continued (I2C Bus still allocated)
48 */
49int SkLm80ReadSensor(
50SK_AC *pAC, /* Adapter Context */
51SK_IOC IoC, /* I/O Context needed in level 1 and 2 */
52SK_SENSOR *pSen) /* Sensor to be read */
53{
54 SK_I32 Value;
55
56 switch (pSen->SenState) {
57 case SK_SEN_IDLE:
58 /* Send address to ADDR register */
59 SK_I2C_CTL(IoC, I2C_READ, pSen->SenDev, I2C_025K_DEV, pSen->SenReg, 0);
60
61 pSen->SenState = SK_SEN_VALUE ;
62 BREAK_OR_WAIT(pAC, IoC, I2C_READ);
63
64 case SK_SEN_VALUE:
65 /* Read value from data register */
66 SK_IN32(IoC, B2_I2C_DATA, ((SK_U32 *)&Value));
67
68 Value &= 0xff; /* only least significant byte is valid */
69
70 /* Do NOT check the Value against the thresholds */
71 /* Checking is done in the calling instance */
72
73 if (pSen->SenType == SK_SEN_VOLT) {
74 /* Voltage sensor */
75 pSen->SenValue = Value * SK_LM80_VT_LSB;
76 pSen->SenState = SK_SEN_IDLE ;
77 return(1);
78 }
79
80 if (pSen->SenType == SK_SEN_FAN) {
81 if (Value != 0 && Value != 0xff) {
82 /* Fan speed counter */
83 pSen->SenValue = SK_LM80_FAN_FAKTOR/Value;
84 }
85 else {
86 /* Indicate Fan error */
87 pSen->SenValue = 0;
88 }
89 pSen->SenState = SK_SEN_IDLE ;
90 return(1);
91 }
92
93 /* First: correct the value: it might be negative */
94 if ((Value & 0x80) != 0) {
95 /* Value is negative */
96 Value = Value - 256;
97 }
98
99 /* We have a temperature sensor and need to get the signed extension.
100 * For now we get the extension from the last reading, so in the normal
101 * case we won't see flickering temperatures.
102 */
103 pSen->SenValue = (Value * SK_LM80_TEMP_LSB) +
104 (pSen->SenValue % SK_LM80_TEMP_LSB);
105
106 /* Send address to ADDR register */
107 SK_I2C_CTL(IoC, I2C_READ, pSen->SenDev, I2C_025K_DEV, LM80_TEMP_CTRL, 0);
108
109 pSen->SenState = SK_SEN_VALEXT ;
110 BREAK_OR_WAIT(pAC, IoC, I2C_READ);
111
112 case SK_SEN_VALEXT:
113 /* Read value from data register */
114 SK_IN32(IoC, B2_I2C_DATA, ((SK_U32 *)&Value));
115 Value &= LM80_TEMP_LSB_9; /* only bit 7 is valid */
116
117 /* cut the LSB bit */
118 pSen->SenValue = ((pSen->SenValue / SK_LM80_TEMP_LSB) *
119 SK_LM80_TEMP_LSB);
120
121 if (pSen->SenValue < 0) {
122 /* Value negative: The bit value must be subtracted */
123 pSen->SenValue -= ((Value >> 7) * SK_LM80_TEMPEXT_LSB);
124 }
125 else {
126 /* Value positive: The bit value must be added */
127 pSen->SenValue += ((Value >> 7) * SK_LM80_TEMPEXT_LSB);
128 }
129
130 pSen->SenState = SK_SEN_IDLE ;
131 return(1);
132
133 default:
134 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E007, SKERR_I2C_E007MSG);
135 return(1);
136 }
137
138 /* Not completed */
139 return(0);
140}
141
diff --git a/drivers/net/sk98lin/skqueue.c b/drivers/net/sk98lin/skqueue.c
deleted file mode 100644
index 0275b4f71d9b..000000000000
--- a/drivers/net/sk98lin/skqueue.c
+++ /dev/null
@@ -1,179 +0,0 @@
1/******************************************************************************
2 *
3 * Name: skqueue.c
4 * Project: Gigabit Ethernet Adapters, Event Scheduler Module
5 * Version: $Revision: 1.20 $
6 * Date: $Date: 2003/09/16 13:44:00 $
7 * Purpose: Management of an event queue.
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect GmbH.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25
26/*
27 * Event queue and dispatcher
28 */
29#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
30static const char SysKonnectFileId[] =
31 "@(#) $Id: skqueue.c,v 1.20 2003/09/16 13:44:00 rschmidt Exp $ (C) Marvell.";
32#endif
33
34#include "h/skdrv1st.h" /* Driver Specific Definitions */
35#include "h/skqueue.h" /* Queue Definitions */
36#include "h/skdrv2nd.h" /* Adapter Control- and Driver specific Def. */
37
38#ifdef __C2MAN__
39/*
40 Event queue management.
41
42 General Description:
43
44 */
45intro()
46{}
47#endif
48
49#define PRINTF(a,b,c)
50
51/*
52 * init event queue management
53 *
54 * Must be called during init level 0.
55 */
56void SkEventInit(
57SK_AC *pAC, /* Adapter context */
58SK_IOC Ioc, /* IO context */
59int Level) /* Init level */
60{
61 switch (Level) {
62 case SK_INIT_DATA:
63 pAC->Event.EvPut = pAC->Event.EvGet = pAC->Event.EvQueue;
64 break;
65 default:
66 break;
67 }
68}
69
70/*
71 * add event to queue
72 */
73void SkEventQueue(
74SK_AC *pAC, /* Adapters context */
75SK_U32 Class, /* Event Class */
76SK_U32 Event, /* Event to be queued */
77SK_EVPARA Para) /* Event parameter */
78{
79 pAC->Event.EvPut->Class = Class;
80 pAC->Event.EvPut->Event = Event;
81 pAC->Event.EvPut->Para = Para;
82
83 if (++pAC->Event.EvPut == &pAC->Event.EvQueue[SK_MAX_EVENT])
84 pAC->Event.EvPut = pAC->Event.EvQueue;
85
86 if (pAC->Event.EvPut == pAC->Event.EvGet) {
87 SK_ERR_LOG(pAC, SK_ERRCL_NORES, SKERR_Q_E001, SKERR_Q_E001MSG);
88 }
89}
90
91/*
92 * event dispatcher
93 * while event queue is not empty
94 * get event from queue
95 * send command to state machine
96 * end
97 * return error reported by individual Event function
98 * 0 if no error occured.
99 */
100int SkEventDispatcher(
101SK_AC *pAC, /* Adapters Context */
102SK_IOC Ioc) /* Io context */
103{
104 SK_EVENTELEM *pEv; /* pointer into queue */
105 SK_U32 Class;
106 int Rtv;
107
108 pEv = pAC->Event.EvGet;
109
110 PRINTF("dispatch get %x put %x\n", pEv, pAC->Event.ev_put);
111
112 while (pEv != pAC->Event.EvPut) {
113 PRINTF("dispatch Class %d Event %d\n", pEv->Class, pEv->Event);
114
115 switch (Class = pEv->Class) {
116#ifndef SK_USE_LAC_EV
117#ifndef SK_SLIM
118 case SKGE_RLMT: /* RLMT Event */
119 Rtv = SkRlmtEvent(pAC, Ioc, pEv->Event, pEv->Para);
120 break;
121 case SKGE_I2C: /* I2C Event */
122 Rtv = SkI2cEvent(pAC, Ioc, pEv->Event, pEv->Para);
123 break;
124 case SKGE_PNMI: /* PNMI Event */
125 Rtv = SkPnmiEvent(pAC, Ioc, pEv->Event, pEv->Para);
126 break;
127#endif /* not SK_SLIM */
128#endif /* not SK_USE_LAC_EV */
129 case SKGE_DRV: /* Driver Event */
130 Rtv = SkDrvEvent(pAC, Ioc, pEv->Event, pEv->Para);
131 break;
132#ifndef SK_USE_SW_TIMER
133 case SKGE_HWAC:
134 Rtv = SkGeSirqEvent(pAC, Ioc, pEv->Event, pEv->Para);
135 break;
136#else /* !SK_USE_SW_TIMER */
137 case SKGE_SWT :
138 Rtv = SkSwtEvent(pAC, Ioc, pEv->Event, pEv->Para);
139 break;
140#endif /* !SK_USE_SW_TIMER */
141#ifdef SK_USE_LAC_EV
142 case SKGE_LACP :
143 Rtv = SkLacpEvent(pAC, Ioc, pEv->Event, pEv->Para);
144 break;
145 case SKGE_RSF :
146 Rtv = SkRsfEvent(pAC, Ioc, pEv->Event, pEv->Para);
147 break;
148 case SKGE_MARKER :
149 Rtv = SkMarkerEvent(pAC, Ioc, pEv->Event, pEv->Para);
150 break;
151 case SKGE_FD :
152 Rtv = SkFdEvent(pAC, Ioc, pEv->Event, pEv->Para);
153 break;
154#endif /* SK_USE_LAC_EV */
155#ifdef SK_USE_CSUM
156 case SKGE_CSUM :
157 Rtv = SkCsEvent(pAC, Ioc, pEv->Event, pEv->Para);
158 break;
159#endif /* SK_USE_CSUM */
160 default :
161 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_Q_E002, SKERR_Q_E002MSG);
162 Rtv = 0;
163 }
164
165 if (Rtv != 0) {
166 return(Rtv);
167 }
168
169 if (++pEv == &pAC->Event.EvQueue[SK_MAX_EVENT])
170 pEv = pAC->Event.EvQueue;
171
172 /* Renew get: it is used in queue_events to detect overruns */
173 pAC->Event.EvGet = pEv;
174 }
175
176 return(0);
177}
178
179/* End of file */
diff --git a/drivers/net/sk98lin/skrlmt.c b/drivers/net/sk98lin/skrlmt.c
deleted file mode 100644
index be8d1ccddf6d..000000000000
--- a/drivers/net/sk98lin/skrlmt.c
+++ /dev/null
@@ -1,3257 +0,0 @@
1/******************************************************************************
2 *
3 * Name: skrlmt.c
4 * Project: GEnesis, PCI Gigabit Ethernet Adapter
5 * Version: $Revision: 1.69 $
6 * Date: $Date: 2003/04/15 09:39:22 $
7 * Purpose: Manage links on SK-NET Adapters, esp. redundant ones.
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect GmbH.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25/******************************************************************************
26 *
27 * Description:
28 *
29 * This module contains code for Link ManagemenT (LMT) of SK-NET Adapters.
30 * It is mainly intended for adapters with more than one link.
31 * For such adapters, this module realizes Redundant Link ManagemenT (RLMT).
32 *
33 * Include File Hierarchy:
34 *
35 * "skdrv1st.h"
36 * "skdrv2nd.h"
37 *
38 ******************************************************************************/
39
40#ifndef lint
41static const char SysKonnectFileId[] =
42 "@(#) $Id: skrlmt.c,v 1.69 2003/04/15 09:39:22 tschilli Exp $ (C) Marvell.";
43#endif /* !defined(lint) */
44
45#define __SKRLMT_C
46
47#ifdef __cplusplus
48extern "C" {
49#endif /* cplusplus */
50
51#include "h/skdrv1st.h"
52#include "h/skdrv2nd.h"
53
54/* defines ********************************************************************/
55
56#ifndef SK_HWAC_LINK_LED
57#define SK_HWAC_LINK_LED(a,b,c,d)
58#endif /* !defined(SK_HWAC_LINK_LED) */
59
60#ifndef DEBUG
61#define RLMT_STATIC static
62#else /* DEBUG */
63#define RLMT_STATIC
64
65#ifndef SK_LITTLE_ENDIAN
66/* First 32 bits */
67#define OFFS_LO32 1
68
69/* Second 32 bits */
70#define OFFS_HI32 0
71#else /* SK_LITTLE_ENDIAN */
72/* First 32 bits */
73#define OFFS_LO32 0
74
75/* Second 32 bits */
76#define OFFS_HI32 1
77#endif /* SK_LITTLE_ENDIAN */
78
79#endif /* DEBUG */
80
81/* ----- Private timeout values ----- */
82
83#define SK_RLMT_MIN_TO_VAL 125000 /* 1/8 sec. */
84#define SK_RLMT_DEF_TO_VAL 1000000 /* 1 sec. */
85#define SK_RLMT_PORTDOWN_TIM_VAL 900000 /* another 0.9 sec. */
86#define SK_RLMT_PORTSTART_TIM_VAL 100000 /* 0.1 sec. */
87#define SK_RLMT_PORTUP_TIM_VAL 2500000 /* 2.5 sec. */
88#define SK_RLMT_SEG_TO_VAL 900000000 /* 15 min. */
89
90/* Assume tick counter increment is 1 - may be set OS-dependent. */
91#ifndef SK_TICK_INCR
92#define SK_TICK_INCR SK_CONSTU64(1)
93#endif /* !defined(SK_TICK_INCR) */
94
95/*
96 * Amount that a time stamp must be later to be recognized as "substantially
97 * later". This is about 1/128 sec, but above 1 tick counter increment.
98 */
99#define SK_RLMT_BC_DELTA (1 + ((SK_TICKS_PER_SEC >> 7) > SK_TICK_INCR ? \
100 (SK_TICKS_PER_SEC >> 7) : SK_TICK_INCR))
101
102/* ----- Private RLMT defaults ----- */
103
104#define SK_RLMT_DEF_PREF_PORT 0 /* "Lower" port. */
105#define SK_RLMT_DEF_MODE SK_RLMT_CHECK_LINK /* Default RLMT Mode. */
106
107/* ----- Private RLMT checking states ----- */
108
109#define SK_RLMT_RCS_SEG 1 /* RLMT Check State: check seg. */
110#define SK_RLMT_RCS_START_SEG 2 /* RLMT Check State: start check seg. */
111#define SK_RLMT_RCS_SEND_SEG 4 /* RLMT Check State: send BPDU packet */
112#define SK_RLMT_RCS_REPORT_SEG 8 /* RLMT Check State: report seg. */
113
114/* ----- Private PORT checking states ----- */
115
116#define SK_RLMT_PCS_TX 1 /* Port Check State: check tx. */
117#define SK_RLMT_PCS_RX 2 /* Port Check State: check rx. */
118
119/* ----- Private PORT events ----- */
120
121/* Note: Update simulation when changing these. */
122#define SK_RLMT_PORTSTART_TIM 1100 /* Port start timeout. */
123#define SK_RLMT_PORTUP_TIM 1101 /* Port can now go up. */
124#define SK_RLMT_PORTDOWN_RX_TIM 1102 /* Port did not receive once ... */
125#define SK_RLMT_PORTDOWN 1103 /* Port went down. */
126#define SK_RLMT_PORTDOWN_TX_TIM 1104 /* Partner did not receive ... */
127
128/* ----- Private RLMT events ----- */
129
130/* Note: Update simulation when changing these. */
131#define SK_RLMT_TIM 2100 /* RLMT timeout. */
132#define SK_RLMT_SEG_TIM 2101 /* RLMT segmentation check timeout. */
133
134#define TO_SHORTEN(tim) ((tim) / 2)
135
136/* Error numbers and messages. */
137#define SKERR_RLMT_E001 (SK_ERRBASE_RLMT + 0)
138#define SKERR_RLMT_E001_MSG "No Packet."
139#define SKERR_RLMT_E002 (SKERR_RLMT_E001 + 1)
140#define SKERR_RLMT_E002_MSG "Short Packet."
141#define SKERR_RLMT_E003 (SKERR_RLMT_E002 + 1)
142#define SKERR_RLMT_E003_MSG "Unknown RLMT event."
143#define SKERR_RLMT_E004 (SKERR_RLMT_E003 + 1)
144#define SKERR_RLMT_E004_MSG "PortsUp incorrect."
145#define SKERR_RLMT_E005 (SKERR_RLMT_E004 + 1)
146#define SKERR_RLMT_E005_MSG \
147 "Net seems to be segmented (different root bridges are reported on the ports)."
148#define SKERR_RLMT_E006 (SKERR_RLMT_E005 + 1)
149#define SKERR_RLMT_E006_MSG "Duplicate MAC Address detected."
150#define SKERR_RLMT_E007 (SKERR_RLMT_E006 + 1)
151#define SKERR_RLMT_E007_MSG "LinksUp incorrect."
152#define SKERR_RLMT_E008 (SKERR_RLMT_E007 + 1)
153#define SKERR_RLMT_E008_MSG "Port not started but link came up."
154#define SKERR_RLMT_E009 (SKERR_RLMT_E008 + 1)
155#define SKERR_RLMT_E009_MSG "Corrected illegal setting of Preferred Port."
156#define SKERR_RLMT_E010 (SKERR_RLMT_E009 + 1)
157#define SKERR_RLMT_E010_MSG "Ignored illegal Preferred Port."
158
159/* LLC field values. */
160#define LLC_COMMAND_RESPONSE_BIT 1
161#define LLC_TEST_COMMAND 0xE3
162#define LLC_UI 0x03
163
164/* RLMT Packet fields. */
165#define SK_RLMT_DSAP 0
166#define SK_RLMT_SSAP 0
167#define SK_RLMT_CTRL (LLC_TEST_COMMAND)
168#define SK_RLMT_INDICATOR0 0x53 /* S */
169#define SK_RLMT_INDICATOR1 0x4B /* K */
170#define SK_RLMT_INDICATOR2 0x2D /* - */
171#define SK_RLMT_INDICATOR3 0x52 /* R */
172#define SK_RLMT_INDICATOR4 0x4C /* L */
173#define SK_RLMT_INDICATOR5 0x4D /* M */
174#define SK_RLMT_INDICATOR6 0x54 /* T */
175#define SK_RLMT_PACKET_VERSION 0
176
177/* RLMT SPT Flag values. */
178#define SK_RLMT_SPT_FLAG_CHANGE 0x01
179#define SK_RLMT_SPT_FLAG_CHANGE_ACK 0x80
180
181/* RLMT SPT Packet fields. */
182#define SK_RLMT_SPT_DSAP 0x42
183#define SK_RLMT_SPT_SSAP 0x42
184#define SK_RLMT_SPT_CTRL (LLC_UI)
185#define SK_RLMT_SPT_PROTOCOL_ID0 0x00
186#define SK_RLMT_SPT_PROTOCOL_ID1 0x00
187#define SK_RLMT_SPT_PROTOCOL_VERSION_ID 0x00
188#define SK_RLMT_SPT_BPDU_TYPE 0x00
189#define SK_RLMT_SPT_FLAGS 0x00 /* ?? */
190#define SK_RLMT_SPT_ROOT_ID0 0xFF /* Lowest possible priority. */
191#define SK_RLMT_SPT_ROOT_ID1 0xFF /* Lowest possible priority. */
192
193/* Remaining 6 bytes will be the current port address. */
194#define SK_RLMT_SPT_ROOT_PATH_COST0 0x00
195#define SK_RLMT_SPT_ROOT_PATH_COST1 0x00
196#define SK_RLMT_SPT_ROOT_PATH_COST2 0x00
197#define SK_RLMT_SPT_ROOT_PATH_COST3 0x00
198#define SK_RLMT_SPT_BRIDGE_ID0 0xFF /* Lowest possible priority. */
199#define SK_RLMT_SPT_BRIDGE_ID1 0xFF /* Lowest possible priority. */
200
201/* Remaining 6 bytes will be the current port address. */
202#define SK_RLMT_SPT_PORT_ID0 0xFF /* Lowest possible priority. */
203#define SK_RLMT_SPT_PORT_ID1 0xFF /* Lowest possible priority. */
204#define SK_RLMT_SPT_MSG_AGE0 0x00
205#define SK_RLMT_SPT_MSG_AGE1 0x00
206#define SK_RLMT_SPT_MAX_AGE0 0x00
207#define SK_RLMT_SPT_MAX_AGE1 0xFF
208#define SK_RLMT_SPT_HELLO_TIME0 0x00
209#define SK_RLMT_SPT_HELLO_TIME1 0xFF
210#define SK_RLMT_SPT_FWD_DELAY0 0x00
211#define SK_RLMT_SPT_FWD_DELAY1 0x40
212
213/* Size defines. */
214#define SK_RLMT_MIN_PACKET_SIZE 34
215#define SK_RLMT_MAX_PACKET_SIZE (SK_RLMT_MAX_TX_BUF_SIZE)
216#define SK_PACKET_DATA_LEN (SK_RLMT_MAX_PACKET_SIZE - \
217 SK_RLMT_MIN_PACKET_SIZE)
218
219/* ----- RLMT packet types ----- */
220#define SK_PACKET_ANNOUNCE 1 /* Port announcement. */
221#define SK_PACKET_ALIVE 2 /* Alive packet to port. */
222#define SK_PACKET_ADDR_CHANGED 3 /* Port address changed. */
223#define SK_PACKET_CHECK_TX 4 /* Check your tx line. */
224
225#ifdef SK_LITTLE_ENDIAN
226#define SK_U16_TO_NETWORK_ORDER(Val,Addr) { \
227 SK_U8 *_Addr = (SK_U8*)(Addr); \
228 SK_U16 _Val = (SK_U16)(Val); \
229 *_Addr++ = (SK_U8)(_Val >> 8); \
230 *_Addr = (SK_U8)(_Val & 0xFF); \
231}
232#endif /* SK_LITTLE_ENDIAN */
233
234#ifdef SK_BIG_ENDIAN
235#define SK_U16_TO_NETWORK_ORDER(Val,Addr) (*(SK_U16*)(Addr) = (SK_U16)(Val))
236#endif /* SK_BIG_ENDIAN */
237
238#define AUTONEG_FAILED SK_FALSE
239#define AUTONEG_SUCCESS SK_TRUE
240
241
242/* typedefs *******************************************************************/
243
244/* RLMT packet. Length: SK_RLMT_MAX_PACKET_SIZE (60) bytes. */
245typedef struct s_RlmtPacket {
246 SK_U8 DstAddr[SK_MAC_ADDR_LEN];
247 SK_U8 SrcAddr[SK_MAC_ADDR_LEN];
248 SK_U8 TypeLen[2];
249 SK_U8 DSap;
250 SK_U8 SSap;
251 SK_U8 Ctrl;
252 SK_U8 Indicator[7];
253 SK_U8 RlmtPacketType[2];
254 SK_U8 Align1[2];
255 SK_U8 Random[4]; /* Random value of requesting(!) station. */
256 SK_U8 RlmtPacketVersion[2]; /* RLMT Packet version. */
257 SK_U8 Data[SK_PACKET_DATA_LEN];
258} SK_RLMT_PACKET;
259
260typedef struct s_SpTreeRlmtPacket {
261 SK_U8 DstAddr[SK_MAC_ADDR_LEN];
262 SK_U8 SrcAddr[SK_MAC_ADDR_LEN];
263 SK_U8 TypeLen[2];
264 SK_U8 DSap;
265 SK_U8 SSap;
266 SK_U8 Ctrl;
267 SK_U8 ProtocolId[2];
268 SK_U8 ProtocolVersionId;
269 SK_U8 BpduType;
270 SK_U8 Flags;
271 SK_U8 RootId[8];
272 SK_U8 RootPathCost[4];
273 SK_U8 BridgeId[8];
274 SK_U8 PortId[2];
275 SK_U8 MessageAge[2];
276 SK_U8 MaxAge[2];
277 SK_U8 HelloTime[2];
278 SK_U8 ForwardDelay[2];
279} SK_SPTREE_PACKET;
280
281/* global variables ***********************************************************/
282
283SK_MAC_ADDR SkRlmtMcAddr = {{0x01, 0x00, 0x5A, 0x52, 0x4C, 0x4D}};
284SK_MAC_ADDR BridgeMcAddr = {{0x01, 0x80, 0xC2, 0x00, 0x00, 0x00}};
285
286/* local variables ************************************************************/
287
288/* None. */
289
290/* functions ******************************************************************/
291
292RLMT_STATIC void SkRlmtCheckSwitch(
293 SK_AC *pAC,
294 SK_IOC IoC,
295 SK_U32 NetIdx);
296RLMT_STATIC void SkRlmtCheckSeg(
297 SK_AC *pAC,
298 SK_IOC IoC,
299 SK_U32 NetIdx);
300RLMT_STATIC void SkRlmtEvtSetNets(
301 SK_AC *pAC,
302 SK_IOC IoC,
303 SK_EVPARA Para);
304
305/******************************************************************************
306 *
307 * SkRlmtInit - initialize data, set state to init
308 *
309 * Description:
310 *
311 * SK_INIT_DATA
312 * ============
313 *
314 * This routine initializes all RLMT-related variables to a known state.
315 * The initial state is SK_RLMT_RS_INIT.
316 * All ports are initialized to SK_RLMT_PS_INIT.
317 *
318 *
319 * SK_INIT_IO
320 * ==========
321 *
322 * Nothing.
323 *
324 *
325 * SK_INIT_RUN
326 * ===========
327 *
328 * Determine the adapter's random value.
329 * Set the hw registers, the "logical MAC address", the
330 * RLMT multicast address, and eventually the BPDU multicast address.
331 *
332 * Context:
333 * init, pageable
334 *
335 * Returns:
336 * Nothing.
337 */
338void SkRlmtInit(
339SK_AC *pAC, /* Adapter Context */
340SK_IOC IoC, /* I/O Context */
341int Level) /* Initialization Level */
342{
343 SK_U32 i, j;
344 SK_U64 Random;
345 SK_EVPARA Para;
346 SK_MAC_ADDR VirtualMacAddress;
347 SK_MAC_ADDR PhysicalAMacAddress;
348 SK_BOOL VirtualMacAddressSet;
349 SK_BOOL PhysicalAMacAddressSet;
350
351 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_INIT,
352 ("RLMT Init level %d.\n", Level))
353
354 switch (Level) {
355 case SK_INIT_DATA: /* Initialize data structures. */
356 SK_MEMSET((char *)&pAC->Rlmt, 0, sizeof(SK_RLMT));
357
358 for (i = 0; i < SK_MAX_MACS; i++) {
359 pAC->Rlmt.Port[i].PortState = SK_RLMT_PS_INIT;
360 pAC->Rlmt.Port[i].LinkDown = SK_TRUE;
361 pAC->Rlmt.Port[i].PortDown = SK_TRUE;
362 pAC->Rlmt.Port[i].PortStarted = SK_FALSE;
363 pAC->Rlmt.Port[i].PortNoRx = SK_FALSE;
364 pAC->Rlmt.Port[i].RootIdSet = SK_FALSE;
365 pAC->Rlmt.Port[i].PortNumber = i;
366 pAC->Rlmt.Port[i].Net = &pAC->Rlmt.Net[0];
367 pAC->Rlmt.Port[i].AddrPort = &pAC->Addr.Port[i];
368 }
369
370 pAC->Rlmt.NumNets = 1;
371 for (i = 0; i < SK_MAX_NETS; i++) {
372 pAC->Rlmt.Net[i].RlmtState = SK_RLMT_RS_INIT;
373 pAC->Rlmt.Net[i].RootIdSet = SK_FALSE;
374 pAC->Rlmt.Net[i].PrefPort = SK_RLMT_DEF_PREF_PORT;
375 pAC->Rlmt.Net[i].Preference = 0xFFFFFFFF; /* Automatic. */
376 /* Just assuming. */
377 pAC->Rlmt.Net[i].ActivePort = pAC->Rlmt.Net[i].PrefPort;
378 pAC->Rlmt.Net[i].RlmtMode = SK_RLMT_DEF_MODE;
379 pAC->Rlmt.Net[i].TimeoutValue = SK_RLMT_DEF_TO_VAL;
380 pAC->Rlmt.Net[i].NetNumber = i;
381 }
382
383 pAC->Rlmt.Net[0].Port[0] = &pAC->Rlmt.Port[0];
384 pAC->Rlmt.Net[0].Port[1] = &pAC->Rlmt.Port[1];
385#if SK_MAX_NETS > 1
386 pAC->Rlmt.Net[1].Port[0] = &pAC->Rlmt.Port[1];
387#endif /* SK_MAX_NETS > 1 */
388 break;
389
390 case SK_INIT_IO: /* GIMacsFound first available here. */
391 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_INIT,
392 ("RLMT: %d MACs were detected.\n", pAC->GIni.GIMacsFound))
393
394 pAC->Rlmt.Net[0].NumPorts = pAC->GIni.GIMacsFound;
395
396 /* Initialize HW registers? */
397 if (pAC->GIni.GIMacsFound == 1) {
398 Para.Para32[0] = SK_RLMT_MODE_CLS;
399 Para.Para32[1] = 0;
400 (void)SkRlmtEvent(pAC, IoC, SK_RLMT_MODE_CHANGE, Para);
401 }
402 break;
403
404 case SK_INIT_RUN:
405 /* Ensure RLMT is set to one net. */
406 if (pAC->Rlmt.NumNets > 1) {
407 Para.Para32[0] = 1;
408 Para.Para32[1] = -1;
409 SkRlmtEvtSetNets(pAC, IoC, Para);
410 }
411
412 for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
413 Random = SkOsGetTime(pAC);
414 *(SK_U32*)&pAC->Rlmt.Port[i].Random = *(SK_U32*)&Random;
415
416 for (j = 0; j < 4; j++) {
417 pAC->Rlmt.Port[i].Random[j] ^= pAC->Rlmt.Port[i].AddrPort->
418 CurrentMacAddress.a[SK_MAC_ADDR_LEN - 1 - j];
419 }
420
421 (void)SkAddrMcClear(pAC, IoC, i, SK_ADDR_PERMANENT | SK_MC_SW_ONLY);
422
423 /* Add RLMT MC address. */
424 (void)SkAddrMcAdd(pAC, IoC, i, &SkRlmtMcAddr, SK_ADDR_PERMANENT);
425
426 if (pAC->Rlmt.Net[0].RlmtMode & SK_RLMT_CHECK_SEG) {
427 /* Add BPDU MC address. */
428 (void)SkAddrMcAdd(pAC, IoC, i, &BridgeMcAddr, SK_ADDR_PERMANENT);
429 }
430
431 (void)SkAddrMcUpdate(pAC, IoC, i);
432 }
433
434 VirtualMacAddressSet = SK_FALSE;
435 /* Read virtual MAC address from Control Register File. */
436 for (j = 0; j < SK_MAC_ADDR_LEN; j++) {
437
438 SK_IN8(IoC, B2_MAC_1 + j, &VirtualMacAddress.a[j]);
439 VirtualMacAddressSet |= VirtualMacAddress.a[j];
440 }
441
442 PhysicalAMacAddressSet = SK_FALSE;
443 /* Read physical MAC address for MAC A from Control Register File. */
444 for (j = 0; j < SK_MAC_ADDR_LEN; j++) {
445
446 SK_IN8(IoC, B2_MAC_2 + j, &PhysicalAMacAddress.a[j]);
447 PhysicalAMacAddressSet |= PhysicalAMacAddress.a[j];
448 }
449
450 /* check if the two mac addresses contain reasonable values */
451 if (!VirtualMacAddressSet || !PhysicalAMacAddressSet) {
452
453 pAC->Rlmt.RlmtOff = SK_TRUE;
454 }
455
456 /* if the two mac addresses are equal switch off the RLMT_PRE_LOOKAHEAD
457 and the RLMT_LOOKAHEAD macros */
458 else if (SK_ADDR_EQUAL(PhysicalAMacAddress.a, VirtualMacAddress.a)) {
459
460 pAC->Rlmt.RlmtOff = SK_TRUE;
461 }
462 else {
463 pAC->Rlmt.RlmtOff = SK_FALSE;
464 }
465 break;
466
467 default: /* error */
468 break;
469 }
470 return;
471} /* SkRlmtInit */
472
473
474/******************************************************************************
475 *
476 * SkRlmtBuildCheckChain - build the check chain
477 *
478 * Description:
479 * This routine builds the local check chain:
480 * - Each port that is up checks the next port.
481 * - The last port that is up checks the first port that is up.
482 *
483 * Notes:
484 * - Currently only local ports are considered when building the chain.
485 * - Currently the SuspectState is just reset;
486 * it would be better to save it ...
487 *
488 * Context:
489 * runtime, pageable?
490 *
491 * Returns:
492 * Nothing
493 */
494RLMT_STATIC void SkRlmtBuildCheckChain(
495SK_AC *pAC, /* Adapter Context */
496SK_U32 NetIdx) /* Net Number */
497{
498 SK_U32 i;
499 SK_U32 NumMacsUp;
500 SK_RLMT_PORT * FirstMacUp;
501 SK_RLMT_PORT * PrevMacUp;
502
503 FirstMacUp = NULL;
504 PrevMacUp = NULL;
505
506 if (!(pAC->Rlmt.Net[NetIdx].RlmtMode & SK_RLMT_CHECK_LOC_LINK)) {
507 for (i = 0; i < pAC->Rlmt.Net[i].NumPorts; i++) {
508 pAC->Rlmt.Net[NetIdx].Port[i]->PortsChecked = 0;
509 }
510 return; /* Done. */
511 }
512
513 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
514 ("SkRlmtBuildCheckChain.\n"))
515
516 NumMacsUp = 0;
517
518 for (i = 0; i < pAC->Rlmt.Net[NetIdx].NumPorts; i++) {
519 pAC->Rlmt.Net[NetIdx].Port[i]->PortsChecked = 0;
520 pAC->Rlmt.Net[NetIdx].Port[i]->PortsSuspect = 0;
521 pAC->Rlmt.Net[NetIdx].Port[i]->CheckingState &=
522 ~(SK_RLMT_PCS_RX | SK_RLMT_PCS_TX);
523
524 /*
525 * If more than two links are detected we should consider
526 * checking at least two other ports:
527 * 1. the next port that is not LinkDown and
528 * 2. the next port that is not PortDown.
529 */
530 if (!pAC->Rlmt.Net[NetIdx].Port[i]->LinkDown) {
531 if (NumMacsUp == 0) {
532 FirstMacUp = pAC->Rlmt.Net[NetIdx].Port[i];
533 }
534 else {
535 PrevMacUp->PortCheck[
536 pAC->Rlmt.Net[NetIdx].Port[i]->PortsChecked].CheckAddr =
537 pAC->Rlmt.Net[NetIdx].Port[i]->AddrPort->CurrentMacAddress;
538 PrevMacUp->PortCheck[
539 PrevMacUp->PortsChecked].SuspectTx = SK_FALSE;
540 PrevMacUp->PortsChecked++;
541 }
542 PrevMacUp = pAC->Rlmt.Net[NetIdx].Port[i];
543 NumMacsUp++;
544 }
545 }
546
547 if (NumMacsUp > 1) {
548 PrevMacUp->PortCheck[PrevMacUp->PortsChecked].CheckAddr =
549 FirstMacUp->AddrPort->CurrentMacAddress;
550 PrevMacUp->PortCheck[PrevMacUp->PortsChecked].SuspectTx =
551 SK_FALSE;
552 PrevMacUp->PortsChecked++;
553 }
554
555#ifdef DEBUG
556 for (i = 0; i < pAC->Rlmt.Net[NetIdx].NumPorts; i++) {
557 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
558 ("Port %d checks %d other ports: %2X.\n", i,
559 pAC->Rlmt.Net[NetIdx].Port[i]->PortsChecked,
560 pAC->Rlmt.Net[NetIdx].Port[i]->PortCheck[0].CheckAddr.a[5]))
561 }
562#endif /* DEBUG */
563
564 return;
565} /* SkRlmtBuildCheckChain */
566
567
568/******************************************************************************
569 *
570 * SkRlmtBuildPacket - build an RLMT packet
571 *
572 * Description:
573 * This routine sets up an RLMT packet.
574 *
575 * Context:
576 * runtime, pageable?
577 *
578 * Returns:
579 * NULL or pointer to RLMT mbuf
580 */
581RLMT_STATIC SK_MBUF *SkRlmtBuildPacket(
582SK_AC *pAC, /* Adapter Context */
583SK_IOC IoC, /* I/O Context */
584SK_U32 PortNumber, /* Sending port */
585SK_U16 PacketType, /* RLMT packet type */
586SK_MAC_ADDR *SrcAddr, /* Source address */
587SK_MAC_ADDR *DestAddr) /* Destination address */
588{
589 int i;
590 SK_U16 Length;
591 SK_MBUF *pMb;
592 SK_RLMT_PACKET *pPacket;
593
594#ifdef DEBUG
595 SK_U8 CheckSrc = 0;
596 SK_U8 CheckDest = 0;
597
598 for (i = 0; i < SK_MAC_ADDR_LEN; ++i) {
599 CheckSrc |= SrcAddr->a[i];
600 CheckDest |= DestAddr->a[i];
601 }
602
603 if ((CheckSrc == 0) || (CheckDest == 0)) {
604 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_ERR,
605 ("SkRlmtBuildPacket: Invalid %s%saddr.\n",
606 (CheckSrc == 0 ? "Src" : ""), (CheckDest == 0 ? "Dest" : "")))
607 }
608#endif
609
610 if ((pMb = SkDrvAllocRlmtMbuf(pAC, IoC, SK_RLMT_MAX_PACKET_SIZE)) != NULL) {
611 pPacket = (SK_RLMT_PACKET*)pMb->pData;
612 for (i = 0; i < SK_MAC_ADDR_LEN; i++) {
613 pPacket->DstAddr[i] = DestAddr->a[i];
614 pPacket->SrcAddr[i] = SrcAddr->a[i];
615 }
616 pPacket->DSap = SK_RLMT_DSAP;
617 pPacket->SSap = SK_RLMT_SSAP;
618 pPacket->Ctrl = SK_RLMT_CTRL;
619 pPacket->Indicator[0] = SK_RLMT_INDICATOR0;
620 pPacket->Indicator[1] = SK_RLMT_INDICATOR1;
621 pPacket->Indicator[2] = SK_RLMT_INDICATOR2;
622 pPacket->Indicator[3] = SK_RLMT_INDICATOR3;
623 pPacket->Indicator[4] = SK_RLMT_INDICATOR4;
624 pPacket->Indicator[5] = SK_RLMT_INDICATOR5;
625 pPacket->Indicator[6] = SK_RLMT_INDICATOR6;
626
627 SK_U16_TO_NETWORK_ORDER(PacketType, &pPacket->RlmtPacketType[0]);
628
629 for (i = 0; i < 4; i++) {
630 pPacket->Random[i] = pAC->Rlmt.Port[PortNumber].Random[i];
631 }
632
633 SK_U16_TO_NETWORK_ORDER(
634 SK_RLMT_PACKET_VERSION, &pPacket->RlmtPacketVersion[0]);
635
636 for (i = 0; i < SK_PACKET_DATA_LEN; i++) {
637 pPacket->Data[i] = 0x00;
638 }
639
640 Length = SK_RLMT_MAX_PACKET_SIZE; /* Or smaller. */
641 pMb->Length = Length;
642 pMb->PortIdx = PortNumber;
643 Length -= 14;
644 SK_U16_TO_NETWORK_ORDER(Length, &pPacket->TypeLen[0]);
645
646 if (PacketType == SK_PACKET_ALIVE) {
647 pAC->Rlmt.Port[PortNumber].TxHelloCts++;
648 }
649 }
650
651 return (pMb);
652} /* SkRlmtBuildPacket */
653
654
655/******************************************************************************
656 *
657 * SkRlmtBuildSpanningTreePacket - build spanning tree check packet
658 *
659 * Description:
660 * This routine sets up a BPDU packet for spanning tree check.
661 *
662 * Context:
663 * runtime, pageable?
664 *
665 * Returns:
666 * NULL or pointer to RLMT mbuf
667 */
668RLMT_STATIC SK_MBUF *SkRlmtBuildSpanningTreePacket(
669SK_AC *pAC, /* Adapter Context */
670SK_IOC IoC, /* I/O Context */
671SK_U32 PortNumber) /* Sending port */
672{
673 unsigned i;
674 SK_U16 Length;
675 SK_MBUF *pMb;
676 SK_SPTREE_PACKET *pSPacket;
677
678 if ((pMb = SkDrvAllocRlmtMbuf(pAC, IoC, SK_RLMT_MAX_PACKET_SIZE)) !=
679 NULL) {
680 pSPacket = (SK_SPTREE_PACKET*)pMb->pData;
681 for (i = 0; i < SK_MAC_ADDR_LEN; i++) {
682 pSPacket->DstAddr[i] = BridgeMcAddr.a[i];
683 pSPacket->SrcAddr[i] =
684 pAC->Addr.Port[PortNumber].CurrentMacAddress.a[i];
685 }
686 pSPacket->DSap = SK_RLMT_SPT_DSAP;
687 pSPacket->SSap = SK_RLMT_SPT_SSAP;
688 pSPacket->Ctrl = SK_RLMT_SPT_CTRL;
689
690 pSPacket->ProtocolId[0] = SK_RLMT_SPT_PROTOCOL_ID0;
691 pSPacket->ProtocolId[1] = SK_RLMT_SPT_PROTOCOL_ID1;
692 pSPacket->ProtocolVersionId = SK_RLMT_SPT_PROTOCOL_VERSION_ID;
693 pSPacket->BpduType = SK_RLMT_SPT_BPDU_TYPE;
694 pSPacket->Flags = SK_RLMT_SPT_FLAGS;
695 pSPacket->RootId[0] = SK_RLMT_SPT_ROOT_ID0;
696 pSPacket->RootId[1] = SK_RLMT_SPT_ROOT_ID1;
697 pSPacket->RootPathCost[0] = SK_RLMT_SPT_ROOT_PATH_COST0;
698 pSPacket->RootPathCost[1] = SK_RLMT_SPT_ROOT_PATH_COST1;
699 pSPacket->RootPathCost[2] = SK_RLMT_SPT_ROOT_PATH_COST2;
700 pSPacket->RootPathCost[3] = SK_RLMT_SPT_ROOT_PATH_COST3;
701 pSPacket->BridgeId[0] = SK_RLMT_SPT_BRIDGE_ID0;
702 pSPacket->BridgeId[1] = SK_RLMT_SPT_BRIDGE_ID1;
703
704 /*
705 * Use logical MAC address as bridge ID and filter these packets
706 * on receive.
707 */
708 for (i = 0; i < SK_MAC_ADDR_LEN; i++) {
709 pSPacket->BridgeId[i + 2] = pSPacket->RootId[i + 2] =
710 pAC->Addr.Net[pAC->Rlmt.Port[PortNumber].Net->NetNumber].
711 CurrentMacAddress.a[i];
712 }
713 pSPacket->PortId[0] = SK_RLMT_SPT_PORT_ID0;
714 pSPacket->PortId[1] = SK_RLMT_SPT_PORT_ID1;
715 pSPacket->MessageAge[0] = SK_RLMT_SPT_MSG_AGE0;
716 pSPacket->MessageAge[1] = SK_RLMT_SPT_MSG_AGE1;
717 pSPacket->MaxAge[0] = SK_RLMT_SPT_MAX_AGE0;
718 pSPacket->MaxAge[1] = SK_RLMT_SPT_MAX_AGE1;
719 pSPacket->HelloTime[0] = SK_RLMT_SPT_HELLO_TIME0;
720 pSPacket->HelloTime[1] = SK_RLMT_SPT_HELLO_TIME1;
721 pSPacket->ForwardDelay[0] = SK_RLMT_SPT_FWD_DELAY0;
722 pSPacket->ForwardDelay[1] = SK_RLMT_SPT_FWD_DELAY1;
723
724 Length = SK_RLMT_MAX_PACKET_SIZE; /* Or smaller. */
725 pMb->Length = Length;
726 pMb->PortIdx = PortNumber;
727 Length -= 14;
728 SK_U16_TO_NETWORK_ORDER(Length, &pSPacket->TypeLen[0]);
729
730 pAC->Rlmt.Port[PortNumber].TxSpHelloReqCts++;
731 }
732
733 return (pMb);
734} /* SkRlmtBuildSpanningTreePacket */
735
736
737/******************************************************************************
738 *
739 * SkRlmtSend - build and send check packets
740 *
741 * Description:
742 * Depending on the RLMT state and the checking state, several packets
743 * are sent through the indicated port.
744 *
745 * Context:
746 * runtime, pageable?
747 *
748 * Returns:
749 * Nothing.
750 */
751RLMT_STATIC void SkRlmtSend(
752SK_AC *pAC, /* Adapter Context */
753SK_IOC IoC, /* I/O Context */
754SK_U32 PortNumber) /* Sending port */
755{
756 unsigned j;
757 SK_EVPARA Para;
758 SK_RLMT_PORT *pRPort;
759
760 pRPort = &pAC->Rlmt.Port[PortNumber];
761 if (pAC->Rlmt.Port[PortNumber].Net->RlmtMode & SK_RLMT_CHECK_LOC_LINK) {
762 if (pRPort->CheckingState & (SK_RLMT_PCS_TX | SK_RLMT_PCS_RX)) {
763 /* Port is suspicious. Send the RLMT packet to the RLMT mc addr. */
764 if ((Para.pParaPtr = SkRlmtBuildPacket(pAC, IoC, PortNumber,
765 SK_PACKET_ALIVE, &pAC->Addr.Port[PortNumber].CurrentMacAddress,
766 &SkRlmtMcAddr)) != NULL) {
767 SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
768 }
769 }
770 else {
771 /*
772 * Send a directed RLMT packet to all ports that are
773 * checked by the indicated port.
774 */
775 for (j = 0; j < pRPort->PortsChecked; j++) {
776 if ((Para.pParaPtr = SkRlmtBuildPacket(pAC, IoC, PortNumber,
777 SK_PACKET_ALIVE, &pAC->Addr.Port[PortNumber].CurrentMacAddress,
778 &pRPort->PortCheck[j].CheckAddr)) != NULL) {
779 SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
780 }
781 }
782 }
783 }
784
785 if ((pAC->Rlmt.Port[PortNumber].Net->RlmtMode & SK_RLMT_CHECK_SEG) &&
786 (pAC->Rlmt.Port[PortNumber].Net->CheckingState & SK_RLMT_RCS_SEND_SEG)) {
787 /*
788 * Send a BPDU packet to make a connected switch tell us
789 * the correct root bridge.
790 */
791 if ((Para.pParaPtr =
792 SkRlmtBuildSpanningTreePacket(pAC, IoC, PortNumber)) != NULL) {
793 pAC->Rlmt.Port[PortNumber].Net->CheckingState &= ~SK_RLMT_RCS_SEND_SEG;
794 pRPort->RootIdSet = SK_FALSE;
795
796 SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
797 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_TX,
798 ("SkRlmtSend: BPDU Packet on Port %u.\n", PortNumber))
799 }
800 }
801 return;
802} /* SkRlmtSend */
803
804
805/******************************************************************************
806 *
807 * SkRlmtPortReceives - check if port is (going) down and bring it up
808 *
809 * Description:
810 * This routine checks if a port who received a non-BPDU packet
811 * needs to go up or needs to be stopped going down.
812 *
813 * Context:
814 * runtime, pageable?
815 *
816 * Returns:
817 * Nothing.
818 */
819RLMT_STATIC void SkRlmtPortReceives(
820SK_AC *pAC, /* Adapter Context */
821SK_IOC IoC, /* I/O Context */
822SK_U32 PortNumber) /* Port to check */
823{
824 SK_RLMT_PORT *pRPort;
825 SK_EVPARA Para;
826
827 pRPort = &pAC->Rlmt.Port[PortNumber];
828 pRPort->PortNoRx = SK_FALSE;
829
830 if ((pRPort->PortState == SK_RLMT_PS_DOWN) &&
831 !(pRPort->CheckingState & SK_RLMT_PCS_TX)) {
832 /*
833 * Port is marked down (rx), but received a non-BPDU packet.
834 * Bring it up.
835 */
836 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
837 ("SkRlmtPacketReceive: Received on PortDown.\n"))
838
839 pRPort->PortState = SK_RLMT_PS_GOING_UP;
840 pRPort->GuTimeStamp = SkOsGetTime(pAC);
841 Para.Para32[0] = PortNumber;
842 Para.Para32[1] = (SK_U32)-1;
843 SkTimerStart(pAC, IoC, &pRPort->UpTimer, SK_RLMT_PORTUP_TIM_VAL,
844 SKGE_RLMT, SK_RLMT_PORTUP_TIM, Para);
845 pRPort->CheckingState &= ~SK_RLMT_PCS_RX;
846 /* pAC->Rlmt.CheckSwitch = SK_TRUE; */
847 SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber);
848 } /* PortDown && !SuspectTx */
849 else if (pRPort->CheckingState & SK_RLMT_PCS_RX) {
850 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
851 ("SkRlmtPacketReceive: Stop bringing port down.\n"))
852 SkTimerStop(pAC, IoC, &pRPort->DownRxTimer);
853 pRPort->CheckingState &= ~SK_RLMT_PCS_RX;
854 /* pAC->Rlmt.CheckSwitch = SK_TRUE; */
855 SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber);
856 } /* PortGoingDown */
857
858 return;
859} /* SkRlmtPortReceives */
860
861
862/******************************************************************************
863 *
864 * SkRlmtPacketReceive - receive a packet for closer examination
865 *
866 * Description:
867 * This routine examines a packet more closely than SK_RLMT_LOOKAHEAD.
868 *
869 * Context:
870 * runtime, pageable?
871 *
872 * Returns:
873 * Nothing.
874 */
875RLMT_STATIC void SkRlmtPacketReceive(
876SK_AC *pAC, /* Adapter Context */
877SK_IOC IoC, /* I/O Context */
878SK_MBUF *pMb) /* Received packet */
879{
880#ifdef xDEBUG
881 extern void DumpData(char *p, int size);
882#endif /* DEBUG */
883 int i;
884 unsigned j;
885 SK_U16 PacketType;
886 SK_U32 PortNumber;
887 SK_ADDR_PORT *pAPort;
888 SK_RLMT_PORT *pRPort;
889 SK_RLMT_PACKET *pRPacket;
890 SK_SPTREE_PACKET *pSPacket;
891 SK_EVPARA Para;
892
893 PortNumber = pMb->PortIdx;
894 pAPort = &pAC->Addr.Port[PortNumber];
895 pRPort = &pAC->Rlmt.Port[PortNumber];
896
897 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
898 ("SkRlmtPacketReceive: PortNumber == %d.\n", PortNumber))
899
900 pRPacket = (SK_RLMT_PACKET*)pMb->pData;
901 pSPacket = (SK_SPTREE_PACKET*)pRPacket;
902
903#ifdef xDEBUG
904 DumpData((char *)pRPacket, 32);
905#endif /* DEBUG */
906
907 if ((pRPort->PacketsPerTimeSlot - pRPort->BpduPacketsPerTimeSlot) != 0) {
908 SkRlmtPortReceives(pAC, IoC, PortNumber);
909 }
910
911 /* Check destination address. */
912
913 if (!SK_ADDR_EQUAL(pAPort->CurrentMacAddress.a, pRPacket->DstAddr) &&
914 !SK_ADDR_EQUAL(SkRlmtMcAddr.a, pRPacket->DstAddr) &&
915 !SK_ADDR_EQUAL(BridgeMcAddr.a, pRPacket->DstAddr)) {
916
917 /* Not sent to current MAC or registered MC address => Trash it. */
918 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
919 ("SkRlmtPacketReceive: Not for me.\n"))
920
921 SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
922 return;
923 }
924 else if (SK_ADDR_EQUAL(pAPort->CurrentMacAddress.a, pRPacket->SrcAddr)) {
925
926 /*
927 * Was sent by same port (may happen during port switching
928 * or in case of duplicate MAC addresses).
929 */
930
931 /*
932 * Check for duplicate address here:
933 * If Packet.Random != My.Random => DupAddr.
934 */
935 for (i = 3; i >= 0; i--) {
936 if (pRPort->Random[i] != pRPacket->Random[i]) {
937 break;
938 }
939 }
940
941 /*
942 * CAUTION: Do not check for duplicate MAC address in RLMT Alive Reply
943 * packets (they have the LLC_COMMAND_RESPONSE_BIT set in
944 * pRPacket->SSap).
945 */
946 if (i >= 0 && pRPacket->DSap == SK_RLMT_DSAP &&
947 pRPacket->Ctrl == SK_RLMT_CTRL &&
948 pRPacket->SSap == SK_RLMT_SSAP &&
949 pRPacket->Indicator[0] == SK_RLMT_INDICATOR0 &&
950 pRPacket->Indicator[1] == SK_RLMT_INDICATOR1 &&
951 pRPacket->Indicator[2] == SK_RLMT_INDICATOR2 &&
952 pRPacket->Indicator[3] == SK_RLMT_INDICATOR3 &&
953 pRPacket->Indicator[4] == SK_RLMT_INDICATOR4 &&
954 pRPacket->Indicator[5] == SK_RLMT_INDICATOR5 &&
955 pRPacket->Indicator[6] == SK_RLMT_INDICATOR6) {
956 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
957 ("SkRlmtPacketReceive: Duplicate MAC Address.\n"))
958
959 /* Error Log entry. */
960 SK_ERR_LOG(pAC, SK_ERRCL_COMM, SKERR_RLMT_E006, SKERR_RLMT_E006_MSG);
961 }
962 else {
963 /* Simply trash it. */
964 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
965 ("SkRlmtPacketReceive: Sent by me.\n"))
966 }
967
968 SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
969 return;
970 }
971
972 /* Check SuspectTx entries. */
973 if (pRPort->PortsSuspect > 0) {
974 for (j = 0; j < pRPort->PortsChecked; j++) {
975 if (pRPort->PortCheck[j].SuspectTx &&
976 SK_ADDR_EQUAL(
977 pRPacket->SrcAddr, pRPort->PortCheck[j].CheckAddr.a)) {
978 pRPort->PortCheck[j].SuspectTx = SK_FALSE;
979 pRPort->PortsSuspect--;
980 break;
981 }
982 }
983 }
984
985 /* Determine type of packet. */
986 if (pRPacket->DSap == SK_RLMT_DSAP &&
987 pRPacket->Ctrl == SK_RLMT_CTRL &&
988 (pRPacket->SSap & ~LLC_COMMAND_RESPONSE_BIT) == SK_RLMT_SSAP &&
989 pRPacket->Indicator[0] == SK_RLMT_INDICATOR0 &&
990 pRPacket->Indicator[1] == SK_RLMT_INDICATOR1 &&
991 pRPacket->Indicator[2] == SK_RLMT_INDICATOR2 &&
992 pRPacket->Indicator[3] == SK_RLMT_INDICATOR3 &&
993 pRPacket->Indicator[4] == SK_RLMT_INDICATOR4 &&
994 pRPacket->Indicator[5] == SK_RLMT_INDICATOR5 &&
995 pRPacket->Indicator[6] == SK_RLMT_INDICATOR6) {
996
997 /* It's an RLMT packet. */
998 PacketType = (SK_U16)((pRPacket->RlmtPacketType[0] << 8) |
999 pRPacket->RlmtPacketType[1]);
1000
1001 switch (PacketType) {
1002 case SK_PACKET_ANNOUNCE: /* Not yet used. */
1003#if 0
1004 /* Build the check chain. */
1005 SkRlmtBuildCheckChain(pAC);
1006#endif /* 0 */
1007
1008 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
1009 ("SkRlmtPacketReceive: Announce.\n"))
1010
1011 SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
1012 break;
1013
1014 case SK_PACKET_ALIVE:
1015 if (pRPacket->SSap & LLC_COMMAND_RESPONSE_BIT) {
1016 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
1017 ("SkRlmtPacketReceive: Alive Reply.\n"))
1018
1019 if (!(pAC->Addr.Port[PortNumber].PromMode & SK_PROM_MODE_LLC) ||
1020 SK_ADDR_EQUAL(
1021 pRPacket->DstAddr, pAPort->CurrentMacAddress.a)) {
1022 /* Obviously we could send something. */
1023 if (pRPort->CheckingState & SK_RLMT_PCS_TX) {
1024 pRPort->CheckingState &= ~SK_RLMT_PCS_TX;
1025 SkTimerStop(pAC, IoC, &pRPort->DownTxTimer);
1026 }
1027
1028 if ((pRPort->PortState == SK_RLMT_PS_DOWN) &&
1029 !(pRPort->CheckingState & SK_RLMT_PCS_RX)) {
1030 pRPort->PortState = SK_RLMT_PS_GOING_UP;
1031 pRPort->GuTimeStamp = SkOsGetTime(pAC);
1032
1033 SkTimerStop(pAC, IoC, &pRPort->DownTxTimer);
1034
1035 Para.Para32[0] = PortNumber;
1036 Para.Para32[1] = (SK_U32)-1;
1037 SkTimerStart(pAC, IoC, &pRPort->UpTimer,
1038 SK_RLMT_PORTUP_TIM_VAL, SKGE_RLMT,
1039 SK_RLMT_PORTUP_TIM, Para);
1040 }
1041 }
1042
1043 /* Mark sending port as alive? */
1044 SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
1045 }
1046 else { /* Alive Request Packet. */
1047 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
1048 ("SkRlmtPacketReceive: Alive Request.\n"))
1049
1050 pRPort->RxHelloCts++;
1051
1052 /* Answer. */
1053 for (i = 0; i < SK_MAC_ADDR_LEN; i++) {
1054 pRPacket->DstAddr[i] = pRPacket->SrcAddr[i];
1055 pRPacket->SrcAddr[i] =
1056 pAC->Addr.Port[PortNumber].CurrentMacAddress.a[i];
1057 }
1058 pRPacket->SSap |= LLC_COMMAND_RESPONSE_BIT;
1059
1060 Para.pParaPtr = pMb;
1061 SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
1062 }
1063 break;
1064
1065 case SK_PACKET_CHECK_TX:
1066 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
1067 ("SkRlmtPacketReceive: Check your tx line.\n"))
1068
1069 /* A port checking us requests us to check our tx line. */
1070 pRPort->CheckingState |= SK_RLMT_PCS_TX;
1071
1072 /* Start PortDownTx timer. */
1073 Para.Para32[0] = PortNumber;
1074 Para.Para32[1] = (SK_U32)-1;
1075 SkTimerStart(pAC, IoC, &pRPort->DownTxTimer,
1076 SK_RLMT_PORTDOWN_TIM_VAL, SKGE_RLMT,
1077 SK_RLMT_PORTDOWN_TX_TIM, Para);
1078
1079 SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
1080
1081 if ((Para.pParaPtr = SkRlmtBuildPacket(pAC, IoC, PortNumber,
1082 SK_PACKET_ALIVE, &pAC->Addr.Port[PortNumber].CurrentMacAddress,
1083 &SkRlmtMcAddr)) != NULL) {
1084 SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
1085 }
1086 break;
1087
1088 case SK_PACKET_ADDR_CHANGED:
1089 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
1090 ("SkRlmtPacketReceive: Address Change.\n"))
1091
1092 /* Build the check chain. */
1093 SkRlmtBuildCheckChain(pAC, pRPort->Net->NetNumber);
1094 SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
1095 break;
1096
1097 default:
1098 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
1099 ("SkRlmtPacketReceive: Unknown RLMT packet.\n"))
1100
1101 /* RA;:;: ??? */
1102 SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
1103 }
1104 }
1105 else if (pSPacket->DSap == SK_RLMT_SPT_DSAP &&
1106 pSPacket->Ctrl == SK_RLMT_SPT_CTRL &&
1107 (pSPacket->SSap & ~LLC_COMMAND_RESPONSE_BIT) == SK_RLMT_SPT_SSAP) {
1108 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
1109 ("SkRlmtPacketReceive: BPDU Packet.\n"))
1110
1111 /* Spanning Tree packet. */
1112 pRPort->RxSpHelloCts++;
1113
1114 if (!SK_ADDR_EQUAL(&pSPacket->RootId[2], &pAC->Addr.Net[pAC->Rlmt.
1115 Port[PortNumber].Net->NetNumber].CurrentMacAddress.a[0])) {
1116 /*
1117 * Check segmentation if a new root bridge is set and
1118 * the segmentation check is not currently running.
1119 */
1120 if (!SK_ADDR_EQUAL(&pSPacket->RootId[2], &pRPort->Root.Id[2]) &&
1121 (pAC->Rlmt.Port[PortNumber].Net->LinksUp > 1) &&
1122 (pAC->Rlmt.Port[PortNumber].Net->RlmtMode & SK_RLMT_CHECK_SEG)
1123 != 0 && (pAC->Rlmt.Port[PortNumber].Net->CheckingState &
1124 SK_RLMT_RCS_SEG) == 0) {
1125 pAC->Rlmt.Port[PortNumber].Net->CheckingState |=
1126 SK_RLMT_RCS_START_SEG | SK_RLMT_RCS_SEND_SEG;
1127 }
1128
1129 /* Store tree view of this port. */
1130 for (i = 0; i < 8; i++) {
1131 pRPort->Root.Id[i] = pSPacket->RootId[i];
1132 }
1133 pRPort->RootIdSet = SK_TRUE;
1134
1135 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_DUMP,
1136 ("Root ID %d: %02x %02x %02x %02x %02x %02x %02x %02x.\n",
1137 PortNumber,
1138 pRPort->Root.Id[0], pRPort->Root.Id[1],
1139 pRPort->Root.Id[2], pRPort->Root.Id[3],
1140 pRPort->Root.Id[4], pRPort->Root.Id[5],
1141 pRPort->Root.Id[6], pRPort->Root.Id[7]))
1142 }
1143
1144 SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
1145 if ((pAC->Rlmt.Port[PortNumber].Net->CheckingState &
1146 SK_RLMT_RCS_REPORT_SEG) != 0) {
1147 SkRlmtCheckSeg(pAC, IoC, pAC->Rlmt.Port[PortNumber].Net->NetNumber);
1148 }
1149 }
1150 else {
1151 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
1152 ("SkRlmtPacketReceive: Unknown Packet Type.\n"))
1153
1154 /* Unknown packet. */
1155 SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
1156 }
1157 return;
1158} /* SkRlmtPacketReceive */
1159
1160
1161/******************************************************************************
1162 *
1163 * SkRlmtCheckPort - check if a port works
1164 *
1165 * Description:
1166 * This routine checks if a port whose link is up received something
1167 * and if it seems to transmit successfully.
1168 *
1169 * # PortState: PsInit, PsLinkDown, PsDown, PsGoingUp, PsUp
1170 * # PortCheckingState (Bitfield): ChkTx, ChkRx, ChkSeg
1171 * # RlmtCheckingState (Bitfield): ChkSeg, StartChkSeg, ReportSeg
1172 *
1173 * if (Rx - RxBpdu == 0) { # No rx.
1174 * if (state == PsUp) {
1175 * PortCheckingState |= ChkRx
1176 * }
1177 * if (ModeCheckSeg && (Timeout ==
1178 * TO_SHORTEN(RLMT_DEFAULT_TIMEOUT))) {
1179 * RlmtCheckingState |= ChkSeg)
1180 * PortCheckingState |= ChkSeg
1181 * }
1182 * NewTimeout = TO_SHORTEN(Timeout)
1183 * if (NewTimeout < RLMT_MIN_TIMEOUT) {
1184 * NewTimeout = RLMT_MIN_TIMEOUT
1185 * PortState = PsDown
1186 * ...
1187 * }
1188 * }
1189 * else { # something was received
1190 * # Set counter to 0 at LinkDown?
1191 * # No - rx may be reported after LinkDown ???
1192 * PortCheckingState &= ~ChkRx
1193 * NewTimeout = RLMT_DEFAULT_TIMEOUT
1194 * if (RxAck == 0) {
1195 * possible reasons:
1196 * is my tx line bad? --
1197 * send RLMT multicast and report
1198 * back internally? (only possible
1199 * between ports on same adapter)
1200 * }
1201 * if (RxChk == 0) {
1202 * possible reasons:
1203 * - tx line of port set to check me
1204 * maybe bad
1205 * - no other port/adapter available or set
1206 * to check me
1207 * - adapter checking me has a longer
1208 * timeout
1209 * ??? anything that can be done here?
1210 * }
1211 * }
1212 *
1213 * Context:
1214 * runtime, pageable?
1215 *
1216 * Returns:
1217 * New timeout value.
1218 */
1219RLMT_STATIC SK_U32 SkRlmtCheckPort(
1220SK_AC *pAC, /* Adapter Context */
1221SK_IOC IoC, /* I/O Context */
1222SK_U32 PortNumber) /* Port to check */
1223{
1224 unsigned i;
1225 SK_U32 NewTimeout;
1226 SK_RLMT_PORT *pRPort;
1227 SK_EVPARA Para;
1228
1229 pRPort = &pAC->Rlmt.Port[PortNumber];
1230
1231 if ((pRPort->PacketsPerTimeSlot - pRPort->BpduPacketsPerTimeSlot) == 0) {
1232 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
1233 ("SkRlmtCheckPort %d: No (%d) receives in last time slot.\n",
1234 PortNumber, pRPort->PacketsPerTimeSlot))
1235
1236 /*
1237 * Check segmentation if there was no receive at least twice
1238 * in a row (PortNoRx is already set) and the segmentation
1239 * check is not currently running.
1240 */
1241
1242 if (pRPort->PortNoRx && (pAC->Rlmt.Port[PortNumber].Net->LinksUp > 1) &&
1243 (pAC->Rlmt.Port[PortNumber].Net->RlmtMode & SK_RLMT_CHECK_SEG) &&
1244 !(pAC->Rlmt.Port[PortNumber].Net->CheckingState & SK_RLMT_RCS_SEG)) {
1245 pAC->Rlmt.Port[PortNumber].Net->CheckingState |=
1246 SK_RLMT_RCS_START_SEG | SK_RLMT_RCS_SEND_SEG;
1247 }
1248
1249 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
1250 ("SkRlmtCheckPort: PortsSuspect %d, PcsRx %d.\n",
1251 pRPort->PortsSuspect, pRPort->CheckingState & SK_RLMT_PCS_RX))
1252
1253 if (pRPort->PortState != SK_RLMT_PS_DOWN) {
1254 NewTimeout = TO_SHORTEN(pAC->Rlmt.Port[PortNumber].Net->TimeoutValue);
1255 if (NewTimeout < SK_RLMT_MIN_TO_VAL) {
1256 NewTimeout = SK_RLMT_MIN_TO_VAL;
1257 }
1258
1259 if (!(pRPort->CheckingState & SK_RLMT_PCS_RX)) {
1260 Para.Para32[0] = PortNumber;
1261 pRPort->CheckingState |= SK_RLMT_PCS_RX;
1262
1263 /*
1264 * What shall we do if the port checked by this one receives
1265 * our request frames? What's bad - our rx line or his tx line?
1266 */
1267 Para.Para32[1] = (SK_U32)-1;
1268 SkTimerStart(pAC, IoC, &pRPort->DownRxTimer,
1269 SK_RLMT_PORTDOWN_TIM_VAL, SKGE_RLMT,
1270 SK_RLMT_PORTDOWN_RX_TIM, Para);
1271
1272 for (i = 0; i < pRPort->PortsChecked; i++) {
1273 if (pRPort->PortCheck[i].SuspectTx) {
1274 continue;
1275 }
1276 pRPort->PortCheck[i].SuspectTx = SK_TRUE;
1277 pRPort->PortsSuspect++;
1278 if ((Para.pParaPtr =
1279 SkRlmtBuildPacket(pAC, IoC, PortNumber, SK_PACKET_CHECK_TX,
1280 &pAC->Addr.Port[PortNumber].CurrentMacAddress,
1281 &pRPort->PortCheck[i].CheckAddr)) != NULL) {
1282 SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
1283 }
1284 }
1285 }
1286 }
1287 else { /* PortDown -- or all partners suspect. */
1288 NewTimeout = SK_RLMT_DEF_TO_VAL;
1289 }
1290 pRPort->PortNoRx = SK_TRUE;
1291 }
1292 else { /* A non-BPDU packet was received. */
1293 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
1294 ("SkRlmtCheckPort %d: %d (%d) receives in last time slot.\n",
1295 PortNumber,
1296 pRPort->PacketsPerTimeSlot - pRPort->BpduPacketsPerTimeSlot,
1297 pRPort->PacketsPerTimeSlot))
1298
1299 SkRlmtPortReceives(pAC, IoC, PortNumber);
1300 if (pAC->Rlmt.CheckSwitch) {
1301 SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber);
1302 }
1303
1304 NewTimeout = SK_RLMT_DEF_TO_VAL;
1305 }
1306
1307 return (NewTimeout);
1308} /* SkRlmtCheckPort */
1309
1310
1311/******************************************************************************
1312 *
1313 * SkRlmtSelectBcRx - select new active port, criteria 1 (CLP)
1314 *
1315 * Description:
1316 * This routine selects the port that received a broadcast frame
1317 * substantially later than all other ports.
1318 *
1319 * Context:
1320 * runtime, pageable?
1321 *
1322 * Returns:
1323 * SK_BOOL
1324 */
1325RLMT_STATIC SK_BOOL SkRlmtSelectBcRx(
1326SK_AC *pAC, /* Adapter Context */
1327SK_IOC IoC, /* I/O Context */
1328SK_U32 Active, /* Active port */
1329SK_U32 PrefPort, /* Preferred port */
1330SK_U32 *pSelect) /* New active port */
1331{
1332 SK_U64 BcTimeStamp;
1333 SK_U32 i;
1334 SK_BOOL PortFound;
1335
1336 BcTimeStamp = 0; /* Not totally necessary, but feeling better. */
1337 PortFound = SK_FALSE;
1338
1339 /* Select port with the latest TimeStamp. */
1340 for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
1341
1342 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
1343 ("TimeStamp Port %d (Down: %d, NoRx: %d): %08x %08x.\n",
1344 i,
1345 pAC->Rlmt.Port[i].PortDown, pAC->Rlmt.Port[i].PortNoRx,
1346 *((SK_U32*)(&pAC->Rlmt.Port[i].BcTimeStamp) + OFFS_HI32),
1347 *((SK_U32*)(&pAC->Rlmt.Port[i].BcTimeStamp) + OFFS_LO32)))
1348
1349 if (!pAC->Rlmt.Port[i].PortDown && !pAC->Rlmt.Port[i].PortNoRx) {
1350 if (!PortFound || pAC->Rlmt.Port[i].BcTimeStamp > BcTimeStamp) {
1351 BcTimeStamp = pAC->Rlmt.Port[i].BcTimeStamp;
1352 *pSelect = i;
1353 PortFound = SK_TRUE;
1354 }
1355 }
1356 }
1357
1358 if (PortFound) {
1359 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
1360 ("Port %d received the last broadcast.\n", *pSelect))
1361
1362 /* Look if another port's time stamp is similar. */
1363 for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
1364 if (i == *pSelect) {
1365 continue;
1366 }
1367 if (!pAC->Rlmt.Port[i].PortDown && !pAC->Rlmt.Port[i].PortNoRx &&
1368 (pAC->Rlmt.Port[i].BcTimeStamp >
1369 BcTimeStamp - SK_RLMT_BC_DELTA ||
1370 pAC->Rlmt.Port[i].BcTimeStamp +
1371 SK_RLMT_BC_DELTA > BcTimeStamp)) {
1372 PortFound = SK_FALSE;
1373
1374 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
1375 ("Port %d received a broadcast at a similar time.\n", i))
1376 break;
1377 }
1378 }
1379 }
1380
1381#ifdef DEBUG
1382 if (PortFound) {
1383 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
1384 ("SK_RLMT_SELECT_BCRX found Port %d receiving the substantially "
1385 "latest broadcast (%u).\n",
1386 *pSelect,
1387 BcTimeStamp - pAC->Rlmt.Port[1 - *pSelect].BcTimeStamp))
1388 }
1389#endif /* DEBUG */
1390
1391 return (PortFound);
1392} /* SkRlmtSelectBcRx */
1393
1394
1395/******************************************************************************
1396 *
1397 * SkRlmtSelectNotSuspect - select new active port, criteria 2 (CLP)
1398 *
1399 * Description:
1400 * This routine selects a good port (it is PortUp && !SuspectRx).
1401 *
1402 * Context:
1403 * runtime, pageable?
1404 *
1405 * Returns:
1406 * SK_BOOL
1407 */
1408RLMT_STATIC SK_BOOL SkRlmtSelectNotSuspect(
1409SK_AC *pAC, /* Adapter Context */
1410SK_IOC IoC, /* I/O Context */
1411SK_U32 Active, /* Active port */
1412SK_U32 PrefPort, /* Preferred port */
1413SK_U32 *pSelect) /* New active port */
1414{
1415 SK_U32 i;
1416 SK_BOOL PortFound;
1417
1418 PortFound = SK_FALSE;
1419
1420 /* Select first port that is PortUp && !SuspectRx. */
1421 for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
1422 if (!pAC->Rlmt.Port[i].PortDown &&
1423 !(pAC->Rlmt.Port[i].CheckingState & SK_RLMT_PCS_RX)) {
1424 *pSelect = i;
1425 if (!pAC->Rlmt.Port[Active].PortDown &&
1426 !(pAC->Rlmt.Port[Active].CheckingState & SK_RLMT_PCS_RX)) {
1427 *pSelect = Active;
1428 }
1429 if (!pAC->Rlmt.Port[PrefPort].PortDown &&
1430 !(pAC->Rlmt.Port[PrefPort].CheckingState & SK_RLMT_PCS_RX)) {
1431 *pSelect = PrefPort;
1432 }
1433 PortFound = SK_TRUE;
1434 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
1435 ("SK_RLMT_SELECT_NOTSUSPECT found Port %d up and not check RX.\n",
1436 *pSelect))
1437 break;
1438 }
1439 }
1440 return (PortFound);
1441} /* SkRlmtSelectNotSuspect */
1442
1443
1444/******************************************************************************
1445 *
1446 * SkRlmtSelectUp - select new active port, criteria 3, 4 (CLP)
1447 *
1448 * Description:
1449 * This routine selects a port that is up.
1450 *
1451 * Context:
1452 * runtime, pageable?
1453 *
1454 * Returns:
1455 * SK_BOOL
1456 */
1457RLMT_STATIC SK_BOOL SkRlmtSelectUp(
1458SK_AC *pAC, /* Adapter Context */
1459SK_IOC IoC, /* I/O Context */
1460SK_U32 Active, /* Active port */
1461SK_U32 PrefPort, /* Preferred port */
1462SK_U32 *pSelect, /* New active port */
1463SK_BOOL AutoNegDone) /* Successfully auto-negotiated? */
1464{
1465 SK_U32 i;
1466 SK_BOOL PortFound;
1467
1468 PortFound = SK_FALSE;
1469
1470 /* Select first port that is PortUp. */
1471 for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
1472 if (pAC->Rlmt.Port[i].PortState == SK_RLMT_PS_UP &&
1473 pAC->GIni.GP[i].PAutoNegFail != AutoNegDone) {
1474 *pSelect = i;
1475 if (pAC->Rlmt.Port[Active].PortState == SK_RLMT_PS_UP &&
1476 pAC->GIni.GP[Active].PAutoNegFail != AutoNegDone) {
1477 *pSelect = Active;
1478 }
1479 if (pAC->Rlmt.Port[PrefPort].PortState == SK_RLMT_PS_UP &&
1480 pAC->GIni.GP[PrefPort].PAutoNegFail != AutoNegDone) {
1481 *pSelect = PrefPort;
1482 }
1483 PortFound = SK_TRUE;
1484 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
1485 ("SK_RLMT_SELECT_UP found Port %d up.\n", *pSelect))
1486 break;
1487 }
1488 }
1489 return (PortFound);
1490} /* SkRlmtSelectUp */
1491
1492
1493/******************************************************************************
1494 *
1495 * SkRlmtSelectGoingUp - select new active port, criteria 5, 6 (CLP)
1496 *
1497 * Description:
1498 * This routine selects the port that is going up for the longest time.
1499 *
1500 * Context:
1501 * runtime, pageable?
1502 *
1503 * Returns:
1504 * SK_BOOL
1505 */
1506RLMT_STATIC SK_BOOL SkRlmtSelectGoingUp(
1507SK_AC *pAC, /* Adapter Context */
1508SK_IOC IoC, /* I/O Context */
1509SK_U32 Active, /* Active port */
1510SK_U32 PrefPort, /* Preferred port */
1511SK_U32 *pSelect, /* New active port */
1512SK_BOOL AutoNegDone) /* Successfully auto-negotiated? */
1513{
1514 SK_U64 GuTimeStamp;
1515 SK_U32 i;
1516 SK_BOOL PortFound;
1517
1518 GuTimeStamp = 0;
1519 PortFound = SK_FALSE;
1520
1521 /* Select port that is PortGoingUp for the longest time. */
1522 for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
1523 if (pAC->Rlmt.Port[i].PortState == SK_RLMT_PS_GOING_UP &&
1524 pAC->GIni.GP[i].PAutoNegFail != AutoNegDone) {
1525 GuTimeStamp = pAC->Rlmt.Port[i].GuTimeStamp;
1526 *pSelect = i;
1527 PortFound = SK_TRUE;
1528 break;
1529 }
1530 }
1531
1532 if (!PortFound) {
1533 return (SK_FALSE);
1534 }
1535
1536 for (i = *pSelect + 1; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
1537 if (pAC->Rlmt.Port[i].PortState == SK_RLMT_PS_GOING_UP &&
1538 pAC->Rlmt.Port[i].GuTimeStamp < GuTimeStamp &&
1539 pAC->GIni.GP[i].PAutoNegFail != AutoNegDone) {
1540 GuTimeStamp = pAC->Rlmt.Port[i].GuTimeStamp;
1541 *pSelect = i;
1542 }
1543 }
1544
1545 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
1546 ("SK_RLMT_SELECT_GOINGUP found Port %d going up.\n", *pSelect))
1547 return (SK_TRUE);
1548} /* SkRlmtSelectGoingUp */
1549
1550
1551/******************************************************************************
1552 *
1553 * SkRlmtSelectDown - select new active port, criteria 7, 8 (CLP)
1554 *
1555 * Description:
1556 * This routine selects a port that is down.
1557 *
1558 * Context:
1559 * runtime, pageable?
1560 *
1561 * Returns:
1562 * SK_BOOL
1563 */
1564RLMT_STATIC SK_BOOL SkRlmtSelectDown(
1565SK_AC *pAC, /* Adapter Context */
1566SK_IOC IoC, /* I/O Context */
1567SK_U32 Active, /* Active port */
1568SK_U32 PrefPort, /* Preferred port */
1569SK_U32 *pSelect, /* New active port */
1570SK_BOOL AutoNegDone) /* Successfully auto-negotiated? */
1571{
1572 SK_U32 i;
1573 SK_BOOL PortFound;
1574
1575 PortFound = SK_FALSE;
1576
1577 /* Select first port that is PortDown. */
1578 for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
1579 if (pAC->Rlmt.Port[i].PortState == SK_RLMT_PS_DOWN &&
1580 pAC->GIni.GP[i].PAutoNegFail != AutoNegDone) {
1581 *pSelect = i;
1582 if (pAC->Rlmt.Port[Active].PortState == SK_RLMT_PS_DOWN &&
1583 pAC->GIni.GP[Active].PAutoNegFail != AutoNegDone) {
1584 *pSelect = Active;
1585 }
1586 if (pAC->Rlmt.Port[PrefPort].PortState == SK_RLMT_PS_DOWN &&
1587 pAC->GIni.GP[PrefPort].PAutoNegFail != AutoNegDone) {
1588 *pSelect = PrefPort;
1589 }
1590 PortFound = SK_TRUE;
1591 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
1592 ("SK_RLMT_SELECT_DOWN found Port %d down.\n", *pSelect))
1593 break;
1594 }
1595 }
1596 return (PortFound);
1597} /* SkRlmtSelectDown */
1598
1599
1600/******************************************************************************
1601 *
1602 * SkRlmtCheckSwitch - select new active port and switch to it
1603 *
1604 * Description:
1605 * This routine decides which port should be the active one and queues
1606 * port switching if necessary.
1607 *
1608 * Context:
1609 * runtime, pageable?
1610 *
1611 * Returns:
1612 * Nothing.
1613 */
1614RLMT_STATIC void SkRlmtCheckSwitch(
1615SK_AC *pAC, /* Adapter Context */
1616SK_IOC IoC, /* I/O Context */
1617SK_U32 NetIdx) /* Net index */
1618{
1619 SK_EVPARA Para;
1620 SK_U32 Active;
1621 SK_U32 PrefPort;
1622 SK_U32 i;
1623 SK_BOOL PortFound;
1624
1625 Active = pAC->Rlmt.Net[NetIdx].ActivePort; /* Index of active port. */
1626 PrefPort = pAC->Rlmt.Net[NetIdx].PrefPort; /* Index of preferred port. */
1627 PortFound = SK_FALSE;
1628 pAC->Rlmt.CheckSwitch = SK_FALSE;
1629
1630#if 0 /* RW 2001/10/18 - active port becomes always prefered one */
1631 if (pAC->Rlmt.Net[NetIdx].Preference == 0xFFFFFFFF) { /* Automatic */
1632 /* disable auto-fail back */
1633 PrefPort = Active;
1634 }
1635#endif
1636
1637 if (pAC->Rlmt.Net[NetIdx].LinksUp == 0) {
1638 /* Last link went down - shut down the net. */
1639 pAC->Rlmt.Net[NetIdx].RlmtState = SK_RLMT_RS_NET_DOWN;
1640 Para.Para32[0] = SK_RLMT_NET_DOWN_TEMP;
1641 Para.Para32[1] = NetIdx;
1642 SkEventQueue(pAC, SKGE_DRV, SK_DRV_NET_DOWN, Para);
1643
1644 Para.Para32[0] = pAC->Rlmt.Net[NetIdx].
1645 Port[pAC->Rlmt.Net[NetIdx].ActivePort]->PortNumber;
1646 Para.Para32[1] = NetIdx;
1647 SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_ACTIVE_DOWN, Para);
1648 return;
1649 } /* pAC->Rlmt.LinksUp == 0 */
1650 else if (pAC->Rlmt.Net[NetIdx].LinksUp == 1 &&
1651 pAC->Rlmt.Net[NetIdx].RlmtState == SK_RLMT_RS_NET_DOWN) {
1652 /* First link came up - get the net up. */
1653 pAC->Rlmt.Net[NetIdx].RlmtState = SK_RLMT_RS_NET_UP;
1654
1655 /*
1656 * If pAC->Rlmt.ActivePort != Para.Para32[0],
1657 * the DRV switches to the port that came up.
1658 */
1659 for (i = 0; i < pAC->Rlmt.Net[NetIdx].NumPorts; i++) {
1660 if (!pAC->Rlmt.Net[NetIdx].Port[i]->LinkDown) {
1661 if (!pAC->Rlmt.Net[NetIdx].Port[Active]->LinkDown) {
1662 i = Active;
1663 }
1664 if (!pAC->Rlmt.Net[NetIdx].Port[PrefPort]->LinkDown) {
1665 i = PrefPort;
1666 }
1667 PortFound = SK_TRUE;
1668 break;
1669 }
1670 }
1671
1672 if (PortFound) {
1673 Para.Para32[0] = pAC->Rlmt.Net[NetIdx].Port[i]->PortNumber;
1674 Para.Para32[1] = NetIdx;
1675 SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_ACTIVE_UP, Para);
1676
1677 pAC->Rlmt.Net[NetIdx].ActivePort = i;
1678 Para.Para32[0] = pAC->Rlmt.Net[NetIdx].Port[i]->PortNumber;
1679 Para.Para32[1] = NetIdx;
1680 SkEventQueue(pAC, SKGE_DRV, SK_DRV_NET_UP, Para);
1681
1682 if ((pAC->Rlmt.Net[NetIdx].RlmtMode & SK_RLMT_TRANSPARENT) == 0 &&
1683 (Para.pParaPtr = SkRlmtBuildPacket(pAC, IoC,
1684 pAC->Rlmt.Net[NetIdx].Port[i]->PortNumber,
1685 SK_PACKET_ANNOUNCE, &pAC->Addr.Net[NetIdx].
1686 CurrentMacAddress, &SkRlmtMcAddr)) != NULL) {
1687 /*
1688 * Send announce packet to RLMT multicast address to force
1689 * switches to learn the new location of the logical MAC address.
1690 */
1691 SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
1692 }
1693 }
1694 else {
1695 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E007, SKERR_RLMT_E007_MSG);
1696 }
1697
1698 return;
1699 } /* LinksUp == 1 && RlmtState == SK_RLMT_RS_NET_DOWN */
1700 else { /* Cannot be reached in dual-net mode. */
1701 Para.Para32[0] = Active;
1702
1703 /*
1704 * Preselection:
1705 * If RLMT Mode != CheckLinkState
1706 * select port that received a broadcast frame substantially later
1707 * than all other ports
1708 * else select first port that is not SuspectRx
1709 * else select first port that is PortUp
1710 * else select port that is PortGoingUp for the longest time
1711 * else select first port that is PortDown
1712 * else stop.
1713 *
1714 * For the preselected port:
1715 * If ActivePort is equal in quality, select ActivePort.
1716 *
1717 * If PrefPort is equal in quality, select PrefPort.
1718 *
1719 * If ActivePort != SelectedPort,
1720 * If old ActivePort is LinkDown,
1721 * SwitchHard
1722 * else
1723 * SwitchSoft
1724 */
1725 /* check of ChgBcPrio flag added */
1726 if ((pAC->Rlmt.Net[0].RlmtMode != SK_RLMT_MODE_CLS) &&
1727 (!pAC->Rlmt.Net[0].ChgBcPrio)) {
1728
1729 if (!PortFound) {
1730 PortFound = SkRlmtSelectBcRx(
1731 pAC, IoC, Active, PrefPort, &Para.Para32[1]);
1732 }
1733
1734 if (!PortFound) {
1735 PortFound = SkRlmtSelectNotSuspect(
1736 pAC, IoC, Active, PrefPort, &Para.Para32[1]);
1737 }
1738 } /* pAC->Rlmt.RlmtMode != SK_RLMT_MODE_CLS */
1739
1740 /* with changed priority for last broadcast received */
1741 if ((pAC->Rlmt.Net[0].RlmtMode != SK_RLMT_MODE_CLS) &&
1742 (pAC->Rlmt.Net[0].ChgBcPrio)) {
1743 if (!PortFound) {
1744 PortFound = SkRlmtSelectNotSuspect(
1745 pAC, IoC, Active, PrefPort, &Para.Para32[1]);
1746 }
1747
1748 if (!PortFound) {
1749 PortFound = SkRlmtSelectBcRx(
1750 pAC, IoC, Active, PrefPort, &Para.Para32[1]);
1751 }
1752 } /* pAC->Rlmt.RlmtMode != SK_RLMT_MODE_CLS */
1753
1754 if (!PortFound) {
1755 PortFound = SkRlmtSelectUp(
1756 pAC, IoC, Active, PrefPort, &Para.Para32[1], AUTONEG_SUCCESS);
1757 }
1758
1759 if (!PortFound) {
1760 PortFound = SkRlmtSelectUp(
1761 pAC, IoC, Active, PrefPort, &Para.Para32[1], AUTONEG_FAILED);
1762 }
1763
1764 if (!PortFound) {
1765 PortFound = SkRlmtSelectGoingUp(
1766 pAC, IoC, Active, PrefPort, &Para.Para32[1], AUTONEG_SUCCESS);
1767 }
1768
1769 if (!PortFound) {
1770 PortFound = SkRlmtSelectGoingUp(
1771 pAC, IoC, Active, PrefPort, &Para.Para32[1], AUTONEG_FAILED);
1772 }
1773
1774 if (pAC->Rlmt.Net[0].RlmtMode != SK_RLMT_MODE_CLS) {
1775 if (!PortFound) {
1776 PortFound = SkRlmtSelectDown(pAC, IoC,
1777 Active, PrefPort, &Para.Para32[1], AUTONEG_SUCCESS);
1778 }
1779
1780 if (!PortFound) {
1781 PortFound = SkRlmtSelectDown(pAC, IoC,
1782 Active, PrefPort, &Para.Para32[1], AUTONEG_FAILED);
1783 }
1784 } /* pAC->Rlmt.RlmtMode != SK_RLMT_MODE_CLS */
1785
1786 if (PortFound) {
1787
1788 if (Para.Para32[1] != Active) {
1789 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
1790 ("Active: %d, Para1: %d.\n", Active, Para.Para32[1]))
1791 pAC->Rlmt.Net[NetIdx].ActivePort = Para.Para32[1];
1792 Para.Para32[0] = pAC->Rlmt.Net[NetIdx].
1793 Port[Para.Para32[0]]->PortNumber;
1794 Para.Para32[1] = pAC->Rlmt.Net[NetIdx].
1795 Port[Para.Para32[1]]->PortNumber;
1796 SK_HWAC_LINK_LED(pAC, IoC, Para.Para32[1], SK_LED_ACTIVE);
1797 if (pAC->Rlmt.Port[Active].LinkDown) {
1798 SkEventQueue(pAC, SKGE_DRV, SK_DRV_SWITCH_HARD, Para);
1799 }
1800 else {
1801 SK_HWAC_LINK_LED(pAC, IoC, Para.Para32[0], SK_LED_STANDBY);
1802 SkEventQueue(pAC, SKGE_DRV, SK_DRV_SWITCH_SOFT, Para);
1803 }
1804 Para.Para32[1] = NetIdx;
1805 Para.Para32[0] =
1806 pAC->Rlmt.Net[NetIdx].Port[Para.Para32[0]]->PortNumber;
1807 SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_ACTIVE_DOWN, Para);
1808 Para.Para32[0] = pAC->Rlmt.Net[NetIdx].
1809 Port[pAC->Rlmt.Net[NetIdx].ActivePort]->PortNumber;
1810 SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_ACTIVE_UP, Para);
1811 if ((pAC->Rlmt.Net[NetIdx].RlmtMode & SK_RLMT_TRANSPARENT) == 0 &&
1812 (Para.pParaPtr = SkRlmtBuildPacket(pAC, IoC, Para.Para32[0],
1813 SK_PACKET_ANNOUNCE, &pAC->Addr.Net[NetIdx].CurrentMacAddress,
1814 &SkRlmtMcAddr)) != NULL) {
1815 /*
1816 * Send announce packet to RLMT multicast address to force
1817 * switches to learn the new location of the logical
1818 * MAC address.
1819 */
1820 SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
1821 } /* (Para.pParaPtr = SkRlmtBuildPacket(...)) != NULL */
1822 } /* Para.Para32[1] != Active */
1823 } /* PortFound */
1824 else {
1825 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E004, SKERR_RLMT_E004_MSG);
1826 }
1827 } /* LinksUp > 1 || LinksUp == 1 && RlmtState != SK_RLMT_RS_NET_DOWN */
1828 return;
1829} /* SkRlmtCheckSwitch */
1830
1831
1832/******************************************************************************
1833 *
1834 * SkRlmtCheckSeg - Report if segmentation is detected
1835 *
1836 * Description:
1837 * This routine checks if the ports see different root bridges and reports
1838 * segmentation in such a case.
1839 *
1840 * Context:
1841 * runtime, pageable?
1842 *
1843 * Returns:
1844 * Nothing.
1845 */
1846RLMT_STATIC void SkRlmtCheckSeg(
1847SK_AC *pAC, /* Adapter Context */
1848SK_IOC IoC, /* I/O Context */
1849SK_U32 NetIdx) /* Net number */
1850{
1851 SK_EVPARA Para;
1852 SK_RLMT_NET *pNet;
1853 SK_U32 i, j;
1854 SK_BOOL Equal;
1855
1856 pNet = &pAC->Rlmt.Net[NetIdx];
1857 pNet->RootIdSet = SK_FALSE;
1858 Equal = SK_TRUE;
1859
1860 for (i = 0; i < pNet->NumPorts; i++) {
1861 if (pNet->Port[i]->LinkDown || !pNet->Port[i]->RootIdSet) {
1862 continue;
1863 }
1864
1865 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_DUMP,
1866 ("Root ID %d: %02x %02x %02x %02x %02x %02x %02x %02x.\n", i,
1867 pNet->Port[i]->Root.Id[0], pNet->Port[i]->Root.Id[1],
1868 pNet->Port[i]->Root.Id[2], pNet->Port[i]->Root.Id[3],
1869 pNet->Port[i]->Root.Id[4], pNet->Port[i]->Root.Id[5],
1870 pNet->Port[i]->Root.Id[6], pNet->Port[i]->Root.Id[7]))
1871
1872 if (!pNet->RootIdSet) {
1873 pNet->Root = pNet->Port[i]->Root;
1874 pNet->RootIdSet = SK_TRUE;
1875 continue;
1876 }
1877
1878 for (j = 0; j < 8; j ++) {
1879 Equal &= pNet->Port[i]->Root.Id[j] == pNet->Root.Id[j];
1880 if (!Equal) {
1881 break;
1882 }
1883 }
1884
1885 if (!Equal) {
1886 SK_ERR_LOG(pAC, SK_ERRCL_COMM, SKERR_RLMT_E005, SKERR_RLMT_E005_MSG);
1887 Para.Para32[0] = NetIdx;
1888 Para.Para32[1] = (SK_U32)-1;
1889 SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_SEGMENTATION, Para);
1890
1891 pNet->CheckingState &= ~SK_RLMT_RCS_REPORT_SEG;
1892
1893 /* 2000-03-06 RA: New. */
1894 Para.Para32[0] = NetIdx;
1895 Para.Para32[1] = (SK_U32)-1;
1896 SkTimerStart(pAC, IoC, &pNet->SegTimer, SK_RLMT_SEG_TO_VAL,
1897 SKGE_RLMT, SK_RLMT_SEG_TIM, Para);
1898 break;
1899 }
1900 } /* for (i = 0; i < pNet->NumPorts; i++) */
1901
1902 /* 2000-03-06 RA: Moved here. */
1903 /* Segmentation check not running anymore. */
1904 pNet->CheckingState &= ~SK_RLMT_RCS_SEG;
1905
1906} /* SkRlmtCheckSeg */
1907
1908
1909/******************************************************************************
1910 *
1911 * SkRlmtPortStart - initialize port variables and start port
1912 *
1913 * Description:
1914 * This routine initializes a port's variables and issues a PORT_START
1915 * to the HWAC module. This handles retries if the start fails or the
1916 * link eventually goes down.
1917 *
1918 * Context:
1919 * runtime, pageable?
1920 *
1921 * Returns:
1922 * Nothing
1923 */
1924RLMT_STATIC void SkRlmtPortStart(
1925SK_AC *pAC, /* Adapter Context */
1926SK_IOC IoC, /* I/O Context */
1927SK_U32 PortNumber) /* Port number */
1928{
1929 SK_EVPARA Para;
1930
1931 pAC->Rlmt.Port[PortNumber].PortState = SK_RLMT_PS_LINK_DOWN;
1932 pAC->Rlmt.Port[PortNumber].PortStarted = SK_TRUE;
1933 pAC->Rlmt.Port[PortNumber].LinkDown = SK_TRUE;
1934 pAC->Rlmt.Port[PortNumber].PortDown = SK_TRUE;
1935 pAC->Rlmt.Port[PortNumber].CheckingState = 0;
1936 pAC->Rlmt.Port[PortNumber].RootIdSet = SK_FALSE;
1937 Para.Para32[0] = PortNumber;
1938 Para.Para32[1] = (SK_U32)-1;
1939 SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_START, Para);
1940} /* SkRlmtPortStart */
1941
1942
1943/******************************************************************************
1944 *
1945 * SkRlmtEvtPortStartTim - PORT_START_TIM
1946 *
1947 * Description:
1948 * This routine handles PORT_START_TIM events.
1949 *
1950 * Context:
1951 * runtime, pageable?
1952 * may be called after SK_INIT_IO
1953 *
1954 * Returns:
1955 * Nothing
1956 */
1957RLMT_STATIC void SkRlmtEvtPortStartTim(
1958SK_AC *pAC, /* Adapter Context */
1959SK_IOC IoC, /* I/O Context */
1960SK_EVPARA Para) /* SK_U32 PortNumber; SK_U32 -1 */
1961{
1962 SK_U32 i;
1963
1964 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
1965 ("SK_RLMT_PORTSTART_TIMEOUT Port %d Event BEGIN.\n", Para.Para32[0]))
1966
1967 if (Para.Para32[1] != (SK_U32)-1) {
1968 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
1969 ("Bad Parameter.\n"))
1970 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
1971 ("SK_RLMT_PORTSTART_TIMEOUT Event EMPTY.\n"))
1972 return;
1973 }
1974
1975 /*
1976 * Used to start non-preferred ports if the preferred one
1977 * does not come up.
1978 * This timeout needs only be set when starting the first
1979 * (preferred) port.
1980 */
1981 if (pAC->Rlmt.Port[Para.Para32[0]].LinkDown) {
1982 /* PORT_START failed. */
1983 for (i = 0; i < pAC->Rlmt.Port[Para.Para32[0]].Net->NumPorts; i++) {
1984 if (!pAC->Rlmt.Port[Para.Para32[0]].Net->Port[i]->PortStarted) {
1985 SkRlmtPortStart(pAC, IoC,
1986 pAC->Rlmt.Port[Para.Para32[0]].Net->Port[i]->PortNumber);
1987 }
1988 }
1989 }
1990
1991 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
1992 ("SK_RLMT_PORTSTART_TIMEOUT Event END.\n"))
1993} /* SkRlmtEvtPortStartTim */
1994
1995
1996/******************************************************************************
1997 *
1998 * SkRlmtEvtLinkUp - LINK_UP
1999 *
2000 * Description:
2001 * This routine handles LLINK_UP events.
2002 *
2003 * Context:
2004 * runtime, pageable?
2005 * may be called after SK_INIT_IO
2006 *
2007 * Returns:
2008 * Nothing
2009 */
2010RLMT_STATIC void SkRlmtEvtLinkUp(
2011SK_AC *pAC, /* Adapter Context */
2012SK_IOC IoC, /* I/O Context */
2013SK_EVPARA Para) /* SK_U32 PortNumber; SK_U32 Undefined */
2014{
2015 SK_U32 i;
2016 SK_RLMT_PORT *pRPort;
2017 SK_EVPARA Para2;
2018
2019 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2020 ("SK_RLMT_LINK_UP Port %d Event BEGIN.\n", Para.Para32[0]))
2021
2022 pRPort = &pAC->Rlmt.Port[Para.Para32[0]];
2023 if (!pRPort->PortStarted) {
2024 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E008, SKERR_RLMT_E008_MSG);
2025
2026 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2027 ("SK_RLMT_LINK_UP Event EMPTY.\n"))
2028 return;
2029 }
2030
2031 if (!pRPort->LinkDown) {
2032 /* RA;:;: Any better solution? */
2033 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2034 ("SK_RLMT_LINK_UP Event EMPTY.\n"))
2035 return;
2036 }
2037
2038 SkTimerStop(pAC, IoC, &pRPort->UpTimer);
2039 SkTimerStop(pAC, IoC, &pRPort->DownRxTimer);
2040 SkTimerStop(pAC, IoC, &pRPort->DownTxTimer);
2041
2042 /* Do something if timer already fired? */
2043
2044 pRPort->LinkDown = SK_FALSE;
2045 pRPort->PortState = SK_RLMT_PS_GOING_UP;
2046 pRPort->GuTimeStamp = SkOsGetTime(pAC);
2047 pRPort->BcTimeStamp = 0;
2048 pRPort->Net->LinksUp++;
2049 if (pRPort->Net->LinksUp == 1) {
2050 SK_HWAC_LINK_LED(pAC, IoC, Para.Para32[0], SK_LED_ACTIVE);
2051 }
2052 else {
2053 SK_HWAC_LINK_LED(pAC, IoC, Para.Para32[0], SK_LED_STANDBY);
2054 }
2055
2056 for (i = 0; i < pRPort->Net->NumPorts; i++) {
2057 if (!pRPort->Net->Port[i]->PortStarted) {
2058 SkRlmtPortStart(pAC, IoC, pRPort->Net->Port[i]->PortNumber);
2059 }
2060 }
2061
2062 SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber);
2063
2064 if (pRPort->Net->LinksUp >= 2) {
2065 if (pRPort->Net->RlmtMode & SK_RLMT_CHECK_LOC_LINK) {
2066 /* Build the check chain. */
2067 SkRlmtBuildCheckChain(pAC, pRPort->Net->NetNumber);
2068 }
2069 }
2070
2071 /* If the first link comes up, start the periodical RLMT timeout. */
2072 if (pRPort->Net->NumPorts > 1 && pRPort->Net->LinksUp == 1 &&
2073 (pRPort->Net->RlmtMode & SK_RLMT_CHECK_OTHERS) != 0) {
2074 Para2.Para32[0] = pRPort->Net->NetNumber;
2075 Para2.Para32[1] = (SK_U32)-1;
2076 SkTimerStart(pAC, IoC, &pRPort->Net->LocTimer,
2077 pRPort->Net->TimeoutValue, SKGE_RLMT, SK_RLMT_TIM, Para2);
2078 }
2079
2080 Para2 = Para;
2081 Para2.Para32[1] = (SK_U32)-1;
2082 SkTimerStart(pAC, IoC, &pRPort->UpTimer, SK_RLMT_PORTUP_TIM_VAL,
2083 SKGE_RLMT, SK_RLMT_PORTUP_TIM, Para2);
2084
2085 /* Later: if (pAC->Rlmt.RlmtMode & SK_RLMT_CHECK_LOC_LINK) && */
2086 if ((pRPort->Net->RlmtMode & SK_RLMT_TRANSPARENT) == 0 &&
2087 (pRPort->Net->RlmtMode & SK_RLMT_CHECK_LINK) != 0 &&
2088 (Para2.pParaPtr =
2089 SkRlmtBuildPacket(pAC, IoC, Para.Para32[0], SK_PACKET_ANNOUNCE,
2090 &pAC->Addr.Port[Para.Para32[0]].CurrentMacAddress, &SkRlmtMcAddr)
2091 ) != NULL) {
2092 /* Send "new" packet to RLMT multicast address. */
2093 SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para2);
2094 }
2095
2096 if (pRPort->Net->RlmtMode & SK_RLMT_CHECK_SEG) {
2097 if ((Para2.pParaPtr =
2098 SkRlmtBuildSpanningTreePacket(pAC, IoC, Para.Para32[0])) != NULL) {
2099 pAC->Rlmt.Port[Para.Para32[0]].RootIdSet = SK_FALSE;
2100 pRPort->Net->CheckingState |=
2101 SK_RLMT_RCS_SEG | SK_RLMT_RCS_REPORT_SEG;
2102
2103 SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para2);
2104
2105 Para.Para32[1] = (SK_U32)-1;
2106 SkTimerStart(pAC, IoC, &pRPort->Net->SegTimer,
2107 SK_RLMT_SEG_TO_VAL, SKGE_RLMT, SK_RLMT_SEG_TIM, Para);
2108 }
2109 }
2110
2111 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2112 ("SK_RLMT_LINK_UP Event END.\n"))
2113} /* SkRlmtEvtLinkUp */
2114
2115
2116/******************************************************************************
2117 *
2118 * SkRlmtEvtPortUpTim - PORT_UP_TIM
2119 *
2120 * Description:
2121 * This routine handles PORT_UP_TIM events.
2122 *
2123 * Context:
2124 * runtime, pageable?
2125 * may be called after SK_INIT_IO
2126 *
2127 * Returns:
2128 * Nothing
2129 */
2130RLMT_STATIC void SkRlmtEvtPortUpTim(
2131SK_AC *pAC, /* Adapter Context */
2132SK_IOC IoC, /* I/O Context */
2133SK_EVPARA Para) /* SK_U32 PortNumber; SK_U32 -1 */
2134{
2135 SK_RLMT_PORT *pRPort;
2136
2137 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2138 ("SK_RLMT_PORTUP_TIM Port %d Event BEGIN.\n", Para.Para32[0]))
2139
2140 if (Para.Para32[1] != (SK_U32)-1) {
2141 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2142 ("Bad Parameter.\n"))
2143 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2144 ("SK_RLMT_PORTUP_TIM Event EMPTY.\n"))
2145 return;
2146 }
2147
2148 pRPort = &pAC->Rlmt.Port[Para.Para32[0]];
2149 if (pRPort->LinkDown || (pRPort->PortState == SK_RLMT_PS_UP)) {
2150 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2151 ("SK_RLMT_PORTUP_TIM Port %d Event EMPTY.\n", Para.Para32[0]))
2152 return;
2153 }
2154
2155 pRPort->PortDown = SK_FALSE;
2156 pRPort->PortState = SK_RLMT_PS_UP;
2157 pRPort->Net->PortsUp++;
2158 if (pRPort->Net->RlmtState != SK_RLMT_RS_INIT) {
2159 if (pAC->Rlmt.NumNets <= 1) {
2160 SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber);
2161 }
2162 SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_PORT_UP, Para);
2163 }
2164
2165 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2166 ("SK_RLMT_PORTUP_TIM Event END.\n"))
2167} /* SkRlmtEvtPortUpTim */
2168
2169
2170/******************************************************************************
2171 *
2172 * SkRlmtEvtPortDownTim - PORT_DOWN_*
2173 *
2174 * Description:
2175 * This routine handles PORT_DOWN_* events.
2176 *
2177 * Context:
2178 * runtime, pageable?
2179 * may be called after SK_INIT_IO
2180 *
2181 * Returns:
2182 * Nothing
2183 */
2184RLMT_STATIC void SkRlmtEvtPortDownX(
2185SK_AC *pAC, /* Adapter Context */
2186SK_IOC IoC, /* I/O Context */
2187SK_U32 Event, /* Event code */
2188SK_EVPARA Para) /* SK_U32 PortNumber; SK_U32 -1 */
2189{
2190 SK_RLMT_PORT *pRPort;
2191
2192 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2193 ("SK_RLMT_PORTDOWN* Port %d Event (%d) BEGIN.\n",
2194 Para.Para32[0], Event))
2195
2196 if (Para.Para32[1] != (SK_U32)-1) {
2197 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2198 ("Bad Parameter.\n"))
2199 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2200 ("SK_RLMT_PORTDOWN* Event EMPTY.\n"))
2201 return;
2202 }
2203
2204 pRPort = &pAC->Rlmt.Port[Para.Para32[0]];
2205 if (!pRPort->PortStarted || (Event == SK_RLMT_PORTDOWN_TX_TIM &&
2206 !(pRPort->CheckingState & SK_RLMT_PCS_TX))) {
2207 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2208 ("SK_RLMT_PORTDOWN* Event (%d) EMPTY.\n", Event))
2209 return;
2210 }
2211
2212 /* Stop port's timers. */
2213 SkTimerStop(pAC, IoC, &pRPort->UpTimer);
2214 SkTimerStop(pAC, IoC, &pRPort->DownRxTimer);
2215 SkTimerStop(pAC, IoC, &pRPort->DownTxTimer);
2216
2217 if (pRPort->PortState != SK_RLMT_PS_LINK_DOWN) {
2218 pRPort->PortState = SK_RLMT_PS_DOWN;
2219 }
2220
2221 if (!pRPort->PortDown) {
2222 pRPort->Net->PortsUp--;
2223 pRPort->PortDown = SK_TRUE;
2224 SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_PORT_DOWN, Para);
2225 }
2226
2227 pRPort->PacketsPerTimeSlot = 0;
2228 /* pRPort->DataPacketsPerTimeSlot = 0; */
2229 pRPort->BpduPacketsPerTimeSlot = 0;
2230 pRPort->BcTimeStamp = 0;
2231
2232 /*
2233 * RA;:;: To be checked:
2234 * - actions at RLMT_STOP: We should not switch anymore.
2235 */
2236 if (pRPort->Net->RlmtState != SK_RLMT_RS_INIT) {
2237 if (Para.Para32[0] ==
2238 pRPort->Net->Port[pRPort->Net->ActivePort]->PortNumber) {
2239 /* Active Port went down. */
2240 SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber);
2241 }
2242 }
2243
2244 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2245 ("SK_RLMT_PORTDOWN* Event (%d) END.\n", Event))
2246} /* SkRlmtEvtPortDownX */
2247
2248
2249/******************************************************************************
2250 *
2251 * SkRlmtEvtLinkDown - LINK_DOWN
2252 *
2253 * Description:
2254 * This routine handles LINK_DOWN events.
2255 *
2256 * Context:
2257 * runtime, pageable?
2258 * may be called after SK_INIT_IO
2259 *
2260 * Returns:
2261 * Nothing
2262 */
2263RLMT_STATIC void SkRlmtEvtLinkDown(
2264SK_AC *pAC, /* Adapter Context */
2265SK_IOC IoC, /* I/O Context */
2266SK_EVPARA Para) /* SK_U32 PortNumber; SK_U32 Undefined */
2267{
2268 SK_RLMT_PORT *pRPort;
2269
2270 pRPort = &pAC->Rlmt.Port[Para.Para32[0]];
2271 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2272 ("SK_RLMT_LINK_DOWN Port %d Event BEGIN.\n", Para.Para32[0]))
2273
2274 if (!pAC->Rlmt.Port[Para.Para32[0]].LinkDown) {
2275 pRPort->Net->LinksUp--;
2276 pRPort->LinkDown = SK_TRUE;
2277 pRPort->PortState = SK_RLMT_PS_LINK_DOWN;
2278 SK_HWAC_LINK_LED(pAC, IoC, Para.Para32[0], SK_LED_OFF);
2279
2280 if ((pRPort->Net->RlmtMode & SK_RLMT_CHECK_LOC_LINK) != 0) {
2281 /* Build the check chain. */
2282 SkRlmtBuildCheckChain(pAC, pRPort->Net->NetNumber);
2283 }
2284
2285 /* Ensure that port is marked down. */
2286 Para.Para32[1] = -1;
2287 (void)SkRlmtEvent(pAC, IoC, SK_RLMT_PORTDOWN, Para);
2288 }
2289
2290 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2291 ("SK_RLMT_LINK_DOWN Event END.\n"))
2292} /* SkRlmtEvtLinkDown */
2293
2294
2295/******************************************************************************
2296 *
2297 * SkRlmtEvtPortAddr - PORT_ADDR
2298 *
2299 * Description:
2300 * This routine handles PORT_ADDR events.
2301 *
2302 * Context:
2303 * runtime, pageable?
2304 * may be called after SK_INIT_IO
2305 *
2306 * Returns:
2307 * Nothing
2308 */
2309RLMT_STATIC void SkRlmtEvtPortAddr(
2310SK_AC *pAC, /* Adapter Context */
2311SK_IOC IoC, /* I/O Context */
2312SK_EVPARA Para) /* SK_U32 PortNumber; SK_U32 -1 */
2313{
2314 SK_U32 i, j;
2315 SK_RLMT_PORT *pRPort;
2316 SK_MAC_ADDR *pOldMacAddr;
2317 SK_MAC_ADDR *pNewMacAddr;
2318
2319 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2320 ("SK_RLMT_PORT_ADDR Port %d Event BEGIN.\n", Para.Para32[0]))
2321
2322 if (Para.Para32[1] != (SK_U32)-1) {
2323 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2324 ("Bad Parameter.\n"))
2325 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2326 ("SK_RLMT_PORT_ADDR Event EMPTY.\n"))
2327 return;
2328 }
2329
2330 /* Port's physical MAC address changed. */
2331 pOldMacAddr = &pAC->Addr.Port[Para.Para32[0]].PreviousMacAddress;
2332 pNewMacAddr = &pAC->Addr.Port[Para.Para32[0]].CurrentMacAddress;
2333
2334 /*
2335 * NOTE: This is not scalable for solutions where ports are
2336 * checked remotely. There, we need to send an RLMT
2337 * address change packet - and how do we ensure delivery?
2338 */
2339 for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
2340 pRPort = &pAC->Rlmt.Port[i];
2341 for (j = 0; j < pRPort->PortsChecked; j++) {
2342 if (SK_ADDR_EQUAL(
2343 pRPort->PortCheck[j].CheckAddr.a, pOldMacAddr->a)) {
2344 pRPort->PortCheck[j].CheckAddr = *pNewMacAddr;
2345 }
2346 }
2347 }
2348
2349 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2350 ("SK_RLMT_PORT_ADDR Event END.\n"))
2351} /* SkRlmtEvtPortAddr */
2352
2353
2354/******************************************************************************
2355 *
2356 * SkRlmtEvtStart - START
2357 *
2358 * Description:
2359 * This routine handles START events.
2360 *
2361 * Context:
2362 * runtime, pageable?
2363 * may be called after SK_INIT_IO
2364 *
2365 * Returns:
2366 * Nothing
2367 */
2368RLMT_STATIC void SkRlmtEvtStart(
2369SK_AC *pAC, /* Adapter Context */
2370SK_IOC IoC, /* I/O Context */
2371SK_EVPARA Para) /* SK_U32 NetNumber; SK_U32 -1 */
2372{
2373 SK_EVPARA Para2;
2374 SK_U32 PortIdx;
2375 SK_U32 PortNumber;
2376
2377 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2378 ("SK_RLMT_START Net %d Event BEGIN.\n", Para.Para32[0]))
2379
2380 if (Para.Para32[1] != (SK_U32)-1) {
2381 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2382 ("Bad Parameter.\n"))
2383 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2384 ("SK_RLMT_START Event EMPTY.\n"))
2385 return;
2386 }
2387
2388 if (Para.Para32[0] >= pAC->Rlmt.NumNets) {
2389 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2390 ("Bad NetNumber %d.\n", Para.Para32[0]))
2391 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2392 ("SK_RLMT_START Event EMPTY.\n"))
2393 return;
2394 }
2395
2396 if (pAC->Rlmt.Net[Para.Para32[0]].RlmtState != SK_RLMT_RS_INIT) {
2397 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2398 ("SK_RLMT_START Event EMPTY.\n"))
2399 return;
2400 }
2401
2402 if (pAC->Rlmt.NetsStarted >= pAC->Rlmt.NumNets) {
2403 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2404 ("All nets should have been started.\n"))
2405 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2406 ("SK_RLMT_START Event EMPTY.\n"))
2407 return;
2408 }
2409
2410 if (pAC->Rlmt.Net[Para.Para32[0]].PrefPort >=
2411 pAC->Rlmt.Net[Para.Para32[0]].NumPorts) {
2412 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E009, SKERR_RLMT_E009_MSG);
2413
2414 /* Change PrefPort to internal default. */
2415 Para2.Para32[0] = 0xFFFFFFFF;
2416 Para2.Para32[1] = Para.Para32[0];
2417 (void)SkRlmtEvent(pAC, IoC, SK_RLMT_PREFPORT_CHANGE, Para2);
2418 }
2419
2420 PortIdx = pAC->Rlmt.Net[Para.Para32[0]].PrefPort;
2421 PortNumber = pAC->Rlmt.Net[Para.Para32[0]].Port[PortIdx]->PortNumber;
2422
2423 pAC->Rlmt.Net[Para.Para32[0]].LinksUp = 0;
2424 pAC->Rlmt.Net[Para.Para32[0]].PortsUp = 0;
2425 pAC->Rlmt.Net[Para.Para32[0]].CheckingState = 0;
2426 pAC->Rlmt.Net[Para.Para32[0]].RlmtState = SK_RLMT_RS_NET_DOWN;
2427
2428 /* Start preferred port. */
2429 SkRlmtPortStart(pAC, IoC, PortNumber);
2430
2431 /* Start Timer (for first port only). */
2432 Para2.Para32[0] = PortNumber;
2433 Para2.Para32[1] = (SK_U32)-1;
2434 SkTimerStart(pAC, IoC, &pAC->Rlmt.Port[PortNumber].UpTimer,
2435 SK_RLMT_PORTSTART_TIM_VAL, SKGE_RLMT, SK_RLMT_PORTSTART_TIM, Para2);
2436
2437 pAC->Rlmt.NetsStarted++;
2438
2439 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2440 ("SK_RLMT_START Event END.\n"))
2441} /* SkRlmtEvtStart */
2442
2443
2444/******************************************************************************
2445 *
2446 * SkRlmtEvtStop - STOP
2447 *
2448 * Description:
2449 * This routine handles STOP events.
2450 *
2451 * Context:
2452 * runtime, pageable?
2453 * may be called after SK_INIT_IO
2454 *
2455 * Returns:
2456 * Nothing
2457 */
2458RLMT_STATIC void SkRlmtEvtStop(
2459SK_AC *pAC, /* Adapter Context */
2460SK_IOC IoC, /* I/O Context */
2461SK_EVPARA Para) /* SK_U32 NetNumber; SK_U32 -1 */
2462{
2463 SK_EVPARA Para2;
2464 SK_U32 PortNumber;
2465 SK_U32 i;
2466
2467 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2468 ("SK_RLMT_STOP Net %d Event BEGIN.\n", Para.Para32[0]))
2469
2470 if (Para.Para32[1] != (SK_U32)-1) {
2471 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2472 ("Bad Parameter.\n"))
2473 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2474 ("SK_RLMT_STOP Event EMPTY.\n"))
2475 return;
2476 }
2477
2478 if (Para.Para32[0] >= pAC->Rlmt.NumNets) {
2479 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2480 ("Bad NetNumber %d.\n", Para.Para32[0]))
2481 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2482 ("SK_RLMT_STOP Event EMPTY.\n"))
2483 return;
2484 }
2485
2486 if (pAC->Rlmt.Net[Para.Para32[0]].RlmtState == SK_RLMT_RS_INIT) {
2487 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2488 ("SK_RLMT_STOP Event EMPTY.\n"))
2489 return;
2490 }
2491
2492 if (pAC->Rlmt.NetsStarted == 0) {
2493 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2494 ("All nets are stopped.\n"))
2495 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2496 ("SK_RLMT_STOP Event EMPTY.\n"))
2497 return;
2498 }
2499
2500 /* Stop RLMT timers. */
2501 SkTimerStop(pAC, IoC, &pAC->Rlmt.Net[Para.Para32[0]].LocTimer);
2502 SkTimerStop(pAC, IoC, &pAC->Rlmt.Net[Para.Para32[0]].SegTimer);
2503
2504 /* Stop net. */
2505 pAC->Rlmt.Net[Para.Para32[0]].RlmtState = SK_RLMT_RS_INIT;
2506 pAC->Rlmt.Net[Para.Para32[0]].RootIdSet = SK_FALSE;
2507 Para2.Para32[0] = SK_RLMT_NET_DOWN_FINAL;
2508 Para2.Para32[1] = Para.Para32[0]; /* Net# */
2509 SkEventQueue(pAC, SKGE_DRV, SK_DRV_NET_DOWN, Para2);
2510
2511 /* Stop ports. */
2512 for (i = 0; i < pAC->Rlmt.Net[Para.Para32[0]].NumPorts; i++) {
2513 PortNumber = pAC->Rlmt.Net[Para.Para32[0]].Port[i]->PortNumber;
2514 if (pAC->Rlmt.Port[PortNumber].PortState != SK_RLMT_PS_INIT) {
2515 SkTimerStop(pAC, IoC, &pAC->Rlmt.Port[PortNumber].UpTimer);
2516 SkTimerStop(pAC, IoC, &pAC->Rlmt.Port[PortNumber].DownRxTimer);
2517 SkTimerStop(pAC, IoC, &pAC->Rlmt.Port[PortNumber].DownTxTimer);
2518
2519 pAC->Rlmt.Port[PortNumber].PortState = SK_RLMT_PS_INIT;
2520 pAC->Rlmt.Port[PortNumber].RootIdSet = SK_FALSE;
2521 pAC->Rlmt.Port[PortNumber].PortStarted = SK_FALSE;
2522 Para2.Para32[0] = PortNumber;
2523 Para2.Para32[1] = (SK_U32)-1;
2524 SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_STOP, Para2);
2525 }
2526 }
2527
2528 pAC->Rlmt.NetsStarted--;
2529
2530 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2531 ("SK_RLMT_STOP Event END.\n"))
2532} /* SkRlmtEvtStop */
2533
2534
2535/******************************************************************************
2536 *
2537 * SkRlmtEvtTim - TIM
2538 *
2539 * Description:
2540 * This routine handles TIM events.
2541 *
2542 * Context:
2543 * runtime, pageable?
2544 * may be called after SK_INIT_IO
2545 *
2546 * Returns:
2547 * Nothing
2548 */
2549RLMT_STATIC void SkRlmtEvtTim(
2550SK_AC *pAC, /* Adapter Context */
2551SK_IOC IoC, /* I/O Context */
2552SK_EVPARA Para) /* SK_U32 NetNumber; SK_U32 -1 */
2553{
2554 SK_RLMT_PORT *pRPort;
2555 SK_U32 Timeout;
2556 SK_U32 NewTimeout;
2557 SK_U32 PortNumber;
2558 SK_U32 i;
2559
2560 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2561 ("SK_RLMT_TIM Event BEGIN.\n"))
2562
2563 if (Para.Para32[1] != (SK_U32)-1) {
2564 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2565 ("Bad Parameter.\n"))
2566 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2567 ("SK_RLMT_TIM Event EMPTY.\n"))
2568 return;
2569 }
2570
2571 if ((pAC->Rlmt.Net[Para.Para32[0]].RlmtMode & SK_RLMT_CHECK_OTHERS) == 0 ||
2572 pAC->Rlmt.Net[Para.Para32[0]].LinksUp == 0) {
2573 /* Mode changed or all links down: No more link checking. */
2574 return;
2575 }
2576
2577#if 0
2578 pAC->Rlmt.SwitchCheckCounter--;
2579 if (pAC->Rlmt.SwitchCheckCounter == 0) {
2580 pAC->Rlmt.SwitchCheckCounter;
2581 }
2582#endif /* 0 */
2583
2584 NewTimeout = SK_RLMT_DEF_TO_VAL;
2585 for (i = 0; i < pAC->Rlmt.Net[Para.Para32[0]].NumPorts; i++) {
2586 PortNumber = pAC->Rlmt.Net[Para.Para32[0]].Port[i]->PortNumber;
2587 pRPort = &pAC->Rlmt.Port[PortNumber];
2588 if (!pRPort->LinkDown) {
2589 Timeout = SkRlmtCheckPort(pAC, IoC, PortNumber);
2590 if (Timeout < NewTimeout) {
2591 NewTimeout = Timeout;
2592 }
2593
2594 /*
2595 * These counters should be set to 0 for all ports before the
2596 * first frame is sent in the next loop.
2597 */
2598 pRPort->PacketsPerTimeSlot = 0;
2599 /* pRPort->DataPacketsPerTimeSlot = 0; */
2600 pRPort->BpduPacketsPerTimeSlot = 0;
2601 }
2602 }
2603 pAC->Rlmt.Net[Para.Para32[0]].TimeoutValue = NewTimeout;
2604
2605 if (pAC->Rlmt.Net[Para.Para32[0]].LinksUp > 1) {
2606 /*
2607 * If checking remote ports, also send packets if
2608 * (LinksUp == 1) &&
2609 * this port checks at least one (remote) port.
2610 */
2611
2612 /*
2613 * Must be new loop, as SkRlmtCheckPort can request to
2614 * check segmentation when e.g. checking the last port.
2615 */
2616 for (i = 0; i < pAC->Rlmt.Net[Para.Para32[0]].NumPorts; i++) {
2617 if (!pAC->Rlmt.Net[Para.Para32[0]].Port[i]->LinkDown) {
2618 SkRlmtSend(pAC, IoC,
2619 pAC->Rlmt.Net[Para.Para32[0]].Port[i]->PortNumber);
2620 }
2621 }
2622 }
2623
2624 SkTimerStart(pAC, IoC, &pAC->Rlmt.Net[Para.Para32[0]].LocTimer,
2625 pAC->Rlmt.Net[Para.Para32[0]].TimeoutValue, SKGE_RLMT, SK_RLMT_TIM,
2626 Para);
2627
2628 if (pAC->Rlmt.Net[Para.Para32[0]].LinksUp > 1 &&
2629 (pAC->Rlmt.Net[Para.Para32[0]].RlmtMode & SK_RLMT_CHECK_SEG) &&
2630 (pAC->Rlmt.Net[Para.Para32[0]].CheckingState & SK_RLMT_RCS_START_SEG)) {
2631 SkTimerStart(pAC, IoC, &pAC->Rlmt.Net[Para.Para32[0]].SegTimer,
2632 SK_RLMT_SEG_TO_VAL, SKGE_RLMT, SK_RLMT_SEG_TIM, Para);
2633 pAC->Rlmt.Net[Para.Para32[0]].CheckingState &= ~SK_RLMT_RCS_START_SEG;
2634 pAC->Rlmt.Net[Para.Para32[0]].CheckingState |=
2635 SK_RLMT_RCS_SEG | SK_RLMT_RCS_REPORT_SEG;
2636 }
2637
2638 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2639 ("SK_RLMT_TIM Event END.\n"))
2640} /* SkRlmtEvtTim */
2641
2642
2643/******************************************************************************
2644 *
2645 * SkRlmtEvtSegTim - SEG_TIM
2646 *
2647 * Description:
2648 * This routine handles SEG_TIM events.
2649 *
2650 * Context:
2651 * runtime, pageable?
2652 * may be called after SK_INIT_IO
2653 *
2654 * Returns:
2655 * Nothing
2656 */
2657RLMT_STATIC void SkRlmtEvtSegTim(
2658SK_AC *pAC, /* Adapter Context */
2659SK_IOC IoC, /* I/O Context */
2660SK_EVPARA Para) /* SK_U32 NetNumber; SK_U32 -1 */
2661{
2662#ifdef xDEBUG
2663 int j;
2664#endif /* DEBUG */
2665
2666 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2667 ("SK_RLMT_SEG_TIM Event BEGIN.\n"))
2668
2669 if (Para.Para32[1] != (SK_U32)-1) {
2670 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2671 ("Bad Parameter.\n"))
2672 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2673 ("SK_RLMT_SEG_TIM Event EMPTY.\n"))
2674 return;
2675 }
2676
2677#ifdef xDEBUG
2678 for (j = 0; j < pAC->Rlmt.Net[Para.Para32[0]].NumPorts; j++) {
2679 SK_ADDR_PORT *pAPort;
2680 SK_U32 k;
2681 SK_U16 *InAddr;
2682 SK_U8 InAddr8[6];
2683
2684 InAddr = (SK_U16 *)&InAddr8[0];
2685 pAPort = pAC->Rlmt.Net[Para.Para32[0]].Port[j]->AddrPort;
2686 for (k = 0; k < pAPort->NextExactMatchRlmt; k++) {
2687 /* Get exact match address k from port j. */
2688 XM_INADDR(IoC, pAC->Rlmt.Net[Para.Para32[0]].Port[j]->PortNumber,
2689 XM_EXM(k), InAddr);
2690 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2691 ("MC address %d on Port %u: %02x %02x %02x %02x %02x %02x -- %02x %02x %02x %02x %02x %02x.\n",
2692 k, pAC->Rlmt.Net[Para.Para32[0]].Port[j]->PortNumber,
2693 InAddr8[0], InAddr8[1], InAddr8[2],
2694 InAddr8[3], InAddr8[4], InAddr8[5],
2695 pAPort->Exact[k].a[0], pAPort->Exact[k].a[1],
2696 pAPort->Exact[k].a[2], pAPort->Exact[k].a[3],
2697 pAPort->Exact[k].a[4], pAPort->Exact[k].a[5]))
2698 }
2699 }
2700#endif /* xDEBUG */
2701
2702 SkRlmtCheckSeg(pAC, IoC, Para.Para32[0]);
2703
2704 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2705 ("SK_RLMT_SEG_TIM Event END.\n"))
2706} /* SkRlmtEvtSegTim */
2707
2708
2709/******************************************************************************
2710 *
2711 * SkRlmtEvtPacketRx - PACKET_RECEIVED
2712 *
2713 * Description:
2714 * This routine handles PACKET_RECEIVED events.
2715 *
2716 * Context:
2717 * runtime, pageable?
2718 * may be called after SK_INIT_IO
2719 *
2720 * Returns:
2721 * Nothing
2722 */
2723RLMT_STATIC void SkRlmtEvtPacketRx(
2724SK_AC *pAC, /* Adapter Context */
2725SK_IOC IoC, /* I/O Context */
2726SK_EVPARA Para) /* SK_MBUF *pMb */
2727{
2728 SK_MBUF *pMb;
2729 SK_MBUF *pNextMb;
2730 SK_U32 NetNumber;
2731
2732
2733 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2734 ("SK_RLMT_PACKET_RECEIVED Event BEGIN.\n"))
2735
2736 /* Should we ignore frames during port switching? */
2737
2738#ifdef DEBUG
2739 pMb = Para.pParaPtr;
2740 if (pMb == NULL) {
2741 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("No mbuf.\n"))
2742 }
2743 else if (pMb->pNext != NULL) {
2744 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2745 ("More than one mbuf or pMb->pNext not set.\n"))
2746 }
2747#endif /* DEBUG */
2748
2749 for (pMb = Para.pParaPtr; pMb != NULL; pMb = pNextMb) {
2750 pNextMb = pMb->pNext;
2751 pMb->pNext = NULL;
2752
2753 NetNumber = pAC->Rlmt.Port[pMb->PortIdx].Net->NetNumber;
2754 if (pAC->Rlmt.Net[NetNumber].RlmtState == SK_RLMT_RS_INIT) {
2755 SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
2756 }
2757 else {
2758 SkRlmtPacketReceive(pAC, IoC, pMb);
2759 }
2760 }
2761
2762 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2763 ("SK_RLMT_PACKET_RECEIVED Event END.\n"))
2764} /* SkRlmtEvtPacketRx */
2765
2766
2767/******************************************************************************
2768 *
2769 * SkRlmtEvtStatsClear - STATS_CLEAR
2770 *
2771 * Description:
2772 * This routine handles STATS_CLEAR events.
2773 *
2774 * Context:
2775 * runtime, pageable?
2776 * may be called after SK_INIT_IO
2777 *
2778 * Returns:
2779 * Nothing
2780 */
2781RLMT_STATIC void SkRlmtEvtStatsClear(
2782SK_AC *pAC, /* Adapter Context */
2783SK_IOC IoC, /* I/O Context */
2784SK_EVPARA Para) /* SK_U32 NetNumber; SK_U32 -1 */
2785{
2786 SK_U32 i;
2787 SK_RLMT_PORT *pRPort;
2788
2789 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2790 ("SK_RLMT_STATS_CLEAR Event BEGIN.\n"))
2791
2792 if (Para.Para32[1] != (SK_U32)-1) {
2793 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2794 ("Bad Parameter.\n"))
2795 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2796 ("SK_RLMT_STATS_CLEAR Event EMPTY.\n"))
2797 return;
2798 }
2799
2800 if (Para.Para32[0] >= pAC->Rlmt.NumNets) {
2801 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2802 ("Bad NetNumber %d.\n", Para.Para32[0]))
2803 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2804 ("SK_RLMT_STATS_CLEAR Event EMPTY.\n"))
2805 return;
2806 }
2807
2808 /* Clear statistics for logical and physical ports. */
2809 for (i = 0; i < pAC->Rlmt.Net[Para.Para32[0]].NumPorts; i++) {
2810 pRPort =
2811 &pAC->Rlmt.Port[pAC->Rlmt.Net[Para.Para32[0]].Port[i]->PortNumber];
2812 pRPort->TxHelloCts = 0;
2813 pRPort->RxHelloCts = 0;
2814 pRPort->TxSpHelloReqCts = 0;
2815 pRPort->RxSpHelloCts = 0;
2816 }
2817
2818 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2819 ("SK_RLMT_STATS_CLEAR Event END.\n"))
2820} /* SkRlmtEvtStatsClear */
2821
2822
2823/******************************************************************************
2824 *
2825 * SkRlmtEvtStatsUpdate - STATS_UPDATE
2826 *
2827 * Description:
2828 * This routine handles STATS_UPDATE events.
2829 *
2830 * Context:
2831 * runtime, pageable?
2832 * may be called after SK_INIT_IO
2833 *
2834 * Returns:
2835 * Nothing
2836 */
2837RLMT_STATIC void SkRlmtEvtStatsUpdate(
2838SK_AC *pAC, /* Adapter Context */
2839SK_IOC IoC, /* I/O Context */
2840SK_EVPARA Para) /* SK_U32 NetNumber; SK_U32 -1 */
2841{
2842 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2843 ("SK_RLMT_STATS_UPDATE Event BEGIN.\n"))
2844
2845 if (Para.Para32[1] != (SK_U32)-1) {
2846 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2847 ("Bad Parameter.\n"))
2848 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2849 ("SK_RLMT_STATS_UPDATE Event EMPTY.\n"))
2850 return;
2851 }
2852
2853 if (Para.Para32[0] >= pAC->Rlmt.NumNets) {
2854 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2855 ("Bad NetNumber %d.\n", Para.Para32[0]))
2856 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2857 ("SK_RLMT_STATS_UPDATE Event EMPTY.\n"))
2858 return;
2859 }
2860
2861 /* Update statistics - currently always up-to-date. */
2862
2863 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2864 ("SK_RLMT_STATS_UPDATE Event END.\n"))
2865} /* SkRlmtEvtStatsUpdate */
2866
2867
2868/******************************************************************************
2869 *
2870 * SkRlmtEvtPrefportChange - PREFPORT_CHANGE
2871 *
2872 * Description:
2873 * This routine handles PREFPORT_CHANGE events.
2874 *
2875 * Context:
2876 * runtime, pageable?
2877 * may be called after SK_INIT_IO
2878 *
2879 * Returns:
2880 * Nothing
2881 */
2882RLMT_STATIC void SkRlmtEvtPrefportChange(
2883SK_AC *pAC, /* Adapter Context */
2884SK_IOC IoC, /* I/O Context */
2885SK_EVPARA Para) /* SK_U32 PortIndex; SK_U32 NetNumber */
2886{
2887 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2888 ("SK_RLMT_PREFPORT_CHANGE to Port %d Event BEGIN.\n", Para.Para32[0]))
2889
2890 if (Para.Para32[1] >= pAC->Rlmt.NumNets) {
2891 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2892 ("Bad NetNumber %d.\n", Para.Para32[1]))
2893 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2894 ("SK_RLMT_PREFPORT_CHANGE Event EMPTY.\n"))
2895 return;
2896 }
2897
2898 /* 0xFFFFFFFF == auto-mode. */
2899 if (Para.Para32[0] == 0xFFFFFFFF) {
2900 pAC->Rlmt.Net[Para.Para32[1]].PrefPort = SK_RLMT_DEF_PREF_PORT;
2901 }
2902 else {
2903 if (Para.Para32[0] >= pAC->Rlmt.Net[Para.Para32[1]].NumPorts) {
2904 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E010, SKERR_RLMT_E010_MSG);
2905
2906 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2907 ("SK_RLMT_PREFPORT_CHANGE Event EMPTY.\n"))
2908 return;
2909 }
2910
2911 pAC->Rlmt.Net[Para.Para32[1]].PrefPort = Para.Para32[0];
2912 }
2913
2914 pAC->Rlmt.Net[Para.Para32[1]].Preference = Para.Para32[0];
2915
2916 if (pAC->Rlmt.Net[Para.Para32[1]].RlmtState != SK_RLMT_RS_INIT) {
2917 SkRlmtCheckSwitch(pAC, IoC, Para.Para32[1]);
2918 }
2919
2920 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2921 ("SK_RLMT_PREFPORT_CHANGE Event END.\n"))
2922} /* SkRlmtEvtPrefportChange */
2923
2924
2925/******************************************************************************
2926 *
2927 * SkRlmtEvtSetNets - SET_NETS
2928 *
2929 * Description:
2930 * This routine handles SET_NETS events.
2931 *
2932 * Context:
2933 * runtime, pageable?
2934 * may be called after SK_INIT_IO
2935 *
2936 * Returns:
2937 * Nothing
2938 */
2939RLMT_STATIC void SkRlmtEvtSetNets(
2940SK_AC *pAC, /* Adapter Context */
2941SK_IOC IoC, /* I/O Context */
2942SK_EVPARA Para) /* SK_U32 NumNets; SK_U32 -1 */
2943{
2944 int i;
2945
2946 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2947 ("SK_RLMT_SET_NETS Event BEGIN.\n"))
2948
2949 if (Para.Para32[1] != (SK_U32)-1) {
2950 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2951 ("Bad Parameter.\n"))
2952 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2953 ("SK_RLMT_SET_NETS Event EMPTY.\n"))
2954 return;
2955 }
2956
2957 if (Para.Para32[0] == 0 || Para.Para32[0] > SK_MAX_NETS ||
2958 Para.Para32[0] > (SK_U32)pAC->GIni.GIMacsFound) {
2959 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2960 ("Bad number of nets: %d.\n", Para.Para32[0]))
2961 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2962 ("SK_RLMT_SET_NETS Event EMPTY.\n"))
2963 return;
2964 }
2965
2966 if (Para.Para32[0] == pAC->Rlmt.NumNets) { /* No change. */
2967 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2968 ("SK_RLMT_SET_NETS Event EMPTY.\n"))
2969 return;
2970 }
2971
2972 /* Entering and leaving dual mode only allowed while nets are stopped. */
2973 if (pAC->Rlmt.NetsStarted > 0) {
2974 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2975 ("Changing dual mode only allowed while all nets are stopped.\n"))
2976 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2977 ("SK_RLMT_SET_NETS Event EMPTY.\n"))
2978 return;
2979 }
2980
2981 if (Para.Para32[0] == 1) {
2982 if (pAC->Rlmt.NumNets > 1) {
2983 /* Clear logical MAC addr from second net's active port. */
2984 (void)SkAddrOverride(pAC, IoC, pAC->Rlmt.Net[1].Port[pAC->Addr.
2985 Net[1].ActivePort]->PortNumber, NULL, SK_ADDR_CLEAR_LOGICAL);
2986 pAC->Rlmt.Net[1].NumPorts = 0;
2987 }
2988
2989 pAC->Rlmt.NumNets = Para.Para32[0];
2990 for (i = 0; (SK_U32)i < pAC->Rlmt.NumNets; i++) {
2991 pAC->Rlmt.Net[i].RlmtState = SK_RLMT_RS_INIT;
2992 pAC->Rlmt.Net[i].RootIdSet = SK_FALSE;
2993 pAC->Rlmt.Net[i].Preference = 0xFFFFFFFF; /* "Automatic" */
2994 pAC->Rlmt.Net[i].PrefPort = SK_RLMT_DEF_PREF_PORT;
2995 /* Just assuming. */
2996 pAC->Rlmt.Net[i].ActivePort = pAC->Rlmt.Net[i].PrefPort;
2997 pAC->Rlmt.Net[i].RlmtMode = SK_RLMT_DEF_MODE;
2998 pAC->Rlmt.Net[i].TimeoutValue = SK_RLMT_DEF_TO_VAL;
2999 pAC->Rlmt.Net[i].NetNumber = i;
3000 }
3001
3002 pAC->Rlmt.Port[1].Net= &pAC->Rlmt.Net[0];
3003 pAC->Rlmt.Net[0].NumPorts = pAC->GIni.GIMacsFound;
3004
3005 SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_SET_NETS, Para);
3006
3007 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
3008 ("RLMT: Changed to one net with two ports.\n"))
3009 }
3010 else if (Para.Para32[0] == 2) {
3011 pAC->Rlmt.Port[1].Net= &pAC->Rlmt.Net[1];
3012 pAC->Rlmt.Net[1].NumPorts = pAC->GIni.GIMacsFound - 1;
3013 pAC->Rlmt.Net[0].NumPorts =
3014 pAC->GIni.GIMacsFound - pAC->Rlmt.Net[1].NumPorts;
3015
3016 pAC->Rlmt.NumNets = Para.Para32[0];
3017 for (i = 0; (SK_U32)i < pAC->Rlmt.NumNets; i++) {
3018 pAC->Rlmt.Net[i].RlmtState = SK_RLMT_RS_INIT;
3019 pAC->Rlmt.Net[i].RootIdSet = SK_FALSE;
3020 pAC->Rlmt.Net[i].Preference = 0xFFFFFFFF; /* "Automatic" */
3021 pAC->Rlmt.Net[i].PrefPort = SK_RLMT_DEF_PREF_PORT;
3022 /* Just assuming. */
3023 pAC->Rlmt.Net[i].ActivePort = pAC->Rlmt.Net[i].PrefPort;
3024 pAC->Rlmt.Net[i].RlmtMode = SK_RLMT_DEF_MODE;
3025 pAC->Rlmt.Net[i].TimeoutValue = SK_RLMT_DEF_TO_VAL;
3026
3027 pAC->Rlmt.Net[i].NetNumber = i;
3028 }
3029
3030 /* Set logical MAC addr on second net's active port. */
3031 (void)SkAddrOverride(pAC, IoC, pAC->Rlmt.Net[1].Port[pAC->Addr.
3032 Net[1].ActivePort]->PortNumber, NULL, SK_ADDR_SET_LOGICAL);
3033
3034 SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_SET_NETS, Para);
3035
3036 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
3037 ("RLMT: Changed to two nets with one port each.\n"))
3038 }
3039 else {
3040 /* Not implemented for more than two nets. */
3041 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
3042 ("SetNets not implemented for more than two nets.\n"))
3043 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
3044 ("SK_RLMT_SET_NETS Event EMPTY.\n"))
3045 return;
3046 }
3047
3048 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
3049 ("SK_RLMT_SET_NETS Event END.\n"))
3050} /* SkRlmtSetNets */
3051
3052
3053/******************************************************************************
3054 *
3055 * SkRlmtEvtModeChange - MODE_CHANGE
3056 *
3057 * Description:
3058 * This routine handles MODE_CHANGE events.
3059 *
3060 * Context:
3061 * runtime, pageable?
3062 * may be called after SK_INIT_IO
3063 *
3064 * Returns:
3065 * Nothing
3066 */
3067RLMT_STATIC void SkRlmtEvtModeChange(
3068SK_AC *pAC, /* Adapter Context */
3069SK_IOC IoC, /* I/O Context */
3070SK_EVPARA Para) /* SK_U32 NewMode; SK_U32 NetNumber */
3071{
3072 SK_EVPARA Para2;
3073 SK_U32 i;
3074 SK_U32 PrevRlmtMode;
3075
3076 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
3077 ("SK_RLMT_MODE_CHANGE Event BEGIN.\n"))
3078
3079 if (Para.Para32[1] >= pAC->Rlmt.NumNets) {
3080 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
3081 ("Bad NetNumber %d.\n", Para.Para32[1]))
3082 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
3083 ("SK_RLMT_MODE_CHANGE Event EMPTY.\n"))
3084 return;
3085 }
3086
3087 Para.Para32[0] |= SK_RLMT_CHECK_LINK;
3088
3089 if ((pAC->Rlmt.Net[Para.Para32[1]].NumPorts == 1) &&
3090 Para.Para32[0] != SK_RLMT_MODE_CLS) {
3091 pAC->Rlmt.Net[Para.Para32[1]].RlmtMode = SK_RLMT_MODE_CLS;
3092 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
3093 ("Forced RLMT mode to CLS on single port net.\n"))
3094 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
3095 ("SK_RLMT_MODE_CHANGE Event EMPTY.\n"))
3096 return;
3097 }
3098
3099 /* Update RLMT mode. */
3100 PrevRlmtMode = pAC->Rlmt.Net[Para.Para32[1]].RlmtMode;
3101 pAC->Rlmt.Net[Para.Para32[1]].RlmtMode = Para.Para32[0];
3102
3103 if ((PrevRlmtMode & SK_RLMT_CHECK_LOC_LINK) !=
3104 (pAC->Rlmt.Net[Para.Para32[1]].RlmtMode & SK_RLMT_CHECK_LOC_LINK)) {
3105 /* SK_RLMT_CHECK_LOC_LINK bit changed. */
3106 if ((PrevRlmtMode & SK_RLMT_CHECK_OTHERS) == 0 &&
3107 pAC->Rlmt.Net[Para.Para32[1]].NumPorts > 1 &&
3108 pAC->Rlmt.Net[Para.Para32[1]].PortsUp >= 1) {
3109 /* 20001207 RA: Was "PortsUp == 1". */
3110 Para2.Para32[0] = Para.Para32[1];
3111 Para2.Para32[1] = (SK_U32)-1;
3112 SkTimerStart(pAC, IoC, &pAC->Rlmt.Net[Para.Para32[1]].LocTimer,
3113 pAC->Rlmt.Net[Para.Para32[1]].TimeoutValue,
3114 SKGE_RLMT, SK_RLMT_TIM, Para2);
3115 }
3116 }
3117
3118 if ((PrevRlmtMode & SK_RLMT_CHECK_SEG) !=
3119 (pAC->Rlmt.Net[Para.Para32[1]].RlmtMode & SK_RLMT_CHECK_SEG)) {
3120 /* SK_RLMT_CHECK_SEG bit changed. */
3121 for (i = 0; i < pAC->Rlmt.Net[Para.Para32[1]].NumPorts; i++) {
3122 (void)SkAddrMcClear(pAC, IoC,
3123 pAC->Rlmt.Net[Para.Para32[1]].Port[i]->PortNumber,
3124 SK_ADDR_PERMANENT | SK_MC_SW_ONLY);
3125
3126 /* Add RLMT MC address. */
3127 (void)SkAddrMcAdd(pAC, IoC,
3128 pAC->Rlmt.Net[Para.Para32[1]].Port[i]->PortNumber,
3129 &SkRlmtMcAddr, SK_ADDR_PERMANENT);
3130
3131 if ((pAC->Rlmt.Net[Para.Para32[1]].RlmtMode &
3132 SK_RLMT_CHECK_SEG) != 0) {
3133 /* Add BPDU MC address. */
3134 (void)SkAddrMcAdd(pAC, IoC,
3135 pAC->Rlmt.Net[Para.Para32[1]].Port[i]->PortNumber,
3136 &BridgeMcAddr, SK_ADDR_PERMANENT);
3137
3138 if (pAC->Rlmt.Net[Para.Para32[1]].RlmtState != SK_RLMT_RS_INIT) {
3139 if (!pAC->Rlmt.Net[Para.Para32[1]].Port[i]->LinkDown &&
3140 (Para2.pParaPtr = SkRlmtBuildSpanningTreePacket(
3141 pAC, IoC, i)) != NULL) {
3142 pAC->Rlmt.Net[Para.Para32[1]].Port[i]->RootIdSet =
3143 SK_FALSE;
3144 SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para2);
3145 }
3146 }
3147 }
3148 (void)SkAddrMcUpdate(pAC, IoC,
3149 pAC->Rlmt.Net[Para.Para32[1]].Port[i]->PortNumber);
3150 } /* for ... */
3151
3152 if ((pAC->Rlmt.Net[Para.Para32[1]].RlmtMode & SK_RLMT_CHECK_SEG) != 0) {
3153 Para2.Para32[0] = Para.Para32[1];
3154 Para2.Para32[1] = (SK_U32)-1;
3155 SkTimerStart(pAC, IoC, &pAC->Rlmt.Net[Para.Para32[1]].SegTimer,
3156 SK_RLMT_SEG_TO_VAL, SKGE_RLMT, SK_RLMT_SEG_TIM, Para2);
3157 }
3158 } /* SK_RLMT_CHECK_SEG bit changed. */
3159
3160 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
3161 ("SK_RLMT_MODE_CHANGE Event END.\n"))
3162} /* SkRlmtEvtModeChange */
3163
3164
3165/******************************************************************************
3166 *
3167 * SkRlmtEvent - a PORT- or an RLMT-specific event happened
3168 *
3169 * Description:
3170 * This routine calls subroutines to handle PORT- and RLMT-specific events.
3171 *
3172 * Context:
3173 * runtime, pageable?
3174 * may be called after SK_INIT_IO
3175 *
3176 * Returns:
3177 * 0
3178 */
3179int SkRlmtEvent(
3180SK_AC *pAC, /* Adapter Context */
3181SK_IOC IoC, /* I/O Context */
3182SK_U32 Event, /* Event code */
3183SK_EVPARA Para) /* Event-specific parameter */
3184{
3185 switch (Event) {
3186
3187 /* ----- PORT events ----- */
3188
3189 case SK_RLMT_PORTSTART_TIM: /* From RLMT via TIME. */
3190 SkRlmtEvtPortStartTim(pAC, IoC, Para);
3191 break;
3192 case SK_RLMT_LINK_UP: /* From SIRQ. */
3193 SkRlmtEvtLinkUp(pAC, IoC, Para);
3194 break;
3195 case SK_RLMT_PORTUP_TIM: /* From RLMT via TIME. */
3196 SkRlmtEvtPortUpTim(pAC, IoC, Para);
3197 break;
3198 case SK_RLMT_PORTDOWN: /* From RLMT. */
3199 case SK_RLMT_PORTDOWN_RX_TIM: /* From RLMT via TIME. */
3200 case SK_RLMT_PORTDOWN_TX_TIM: /* From RLMT via TIME. */
3201 SkRlmtEvtPortDownX(pAC, IoC, Event, Para);
3202 break;
3203 case SK_RLMT_LINK_DOWN: /* From SIRQ. */
3204 SkRlmtEvtLinkDown(pAC, IoC, Para);
3205 break;
3206 case SK_RLMT_PORT_ADDR: /* From ADDR. */
3207 SkRlmtEvtPortAddr(pAC, IoC, Para);
3208 break;
3209
3210 /* ----- RLMT events ----- */
3211
3212 case SK_RLMT_START: /* From DRV. */
3213 SkRlmtEvtStart(pAC, IoC, Para);
3214 break;
3215 case SK_RLMT_STOP: /* From DRV. */
3216 SkRlmtEvtStop(pAC, IoC, Para);
3217 break;
3218 case SK_RLMT_TIM: /* From RLMT via TIME. */
3219 SkRlmtEvtTim(pAC, IoC, Para);
3220 break;
3221 case SK_RLMT_SEG_TIM:
3222 SkRlmtEvtSegTim(pAC, IoC, Para);
3223 break;
3224 case SK_RLMT_PACKET_RECEIVED: /* From DRV. */
3225 SkRlmtEvtPacketRx(pAC, IoC, Para);
3226 break;
3227 case SK_RLMT_STATS_CLEAR: /* From PNMI. */
3228 SkRlmtEvtStatsClear(pAC, IoC, Para);
3229 break;
3230 case SK_RLMT_STATS_UPDATE: /* From PNMI. */
3231 SkRlmtEvtStatsUpdate(pAC, IoC, Para);
3232 break;
3233 case SK_RLMT_PREFPORT_CHANGE: /* From PNMI. */
3234 SkRlmtEvtPrefportChange(pAC, IoC, Para);
3235 break;
3236 case SK_RLMT_MODE_CHANGE: /* From PNMI. */
3237 SkRlmtEvtModeChange(pAC, IoC, Para);
3238 break;
3239 case SK_RLMT_SET_NETS: /* From DRV. */
3240 SkRlmtEvtSetNets(pAC, IoC, Para);
3241 break;
3242
3243 /* ----- Unknown events ----- */
3244
3245 default: /* Create error log entry. */
3246 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
3247 ("Unknown RLMT Event %d.\n", Event))
3248 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E003, SKERR_RLMT_E003_MSG);
3249 break;
3250 } /* switch() */
3251
3252 return (0);
3253} /* SkRlmtEvent */
3254
3255#ifdef __cplusplus
3256}
3257#endif /* __cplusplus */
diff --git a/drivers/net/sk98lin/sktimer.c b/drivers/net/sk98lin/sktimer.c
deleted file mode 100644
index 4e462955ecd8..000000000000
--- a/drivers/net/sk98lin/sktimer.c
+++ /dev/null
@@ -1,250 +0,0 @@
1/******************************************************************************
2 *
3 * Name: sktimer.c
4 * Project: Gigabit Ethernet Adapters, Event Scheduler Module
5 * Version: $Revision: 1.14 $
6 * Date: $Date: 2003/09/16 13:46:51 $
7 * Purpose: High level timer functions.
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect GmbH.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25
26/*
27 * Event queue and dispatcher
28 */
29#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
30static const char SysKonnectFileId[] =
31 "@(#) $Id: sktimer.c,v 1.14 2003/09/16 13:46:51 rschmidt Exp $ (C) Marvell.";
32#endif
33
34#include "h/skdrv1st.h" /* Driver Specific Definitions */
35#include "h/skdrv2nd.h" /* Adapter Control- and Driver specific Def. */
36
37#ifdef __C2MAN__
38/*
39 Event queue management.
40
41 General Description:
42
43 */
44intro()
45{}
46#endif
47
48
49/* Forward declaration */
50static void timer_done(SK_AC *pAC,SK_IOC Ioc,int Restart);
51
52
53/*
54 * Inits the software timer
55 *
56 * needs to be called during Init level 1.
57 */
58void SkTimerInit(
59SK_AC *pAC, /* Adapters context */
60SK_IOC Ioc, /* IoContext */
61int Level) /* Init Level */
62{
63 switch (Level) {
64 case SK_INIT_DATA:
65 pAC->Tim.StQueue = NULL;
66 break;
67 case SK_INIT_IO:
68 SkHwtInit(pAC, Ioc);
69 SkTimerDone(pAC, Ioc);
70 break;
71 default:
72 break;
73 }
74}
75
76/*
77 * Stops a high level timer
78 * - If a timer is not in the queue the function returns normally, too.
79 */
80void SkTimerStop(
81SK_AC *pAC, /* Adapters context */
82SK_IOC Ioc, /* IoContext */
83SK_TIMER *pTimer) /* Timer Pointer to be started */
84{
85 SK_TIMER **ppTimPrev;
86 SK_TIMER *pTm;
87
88 /*
89 * remove timer from queue
90 */
91 pTimer->TmActive = SK_FALSE;
92
93 if (pAC->Tim.StQueue == pTimer && !pTimer->TmNext) {
94 SkHwtStop(pAC, Ioc);
95 }
96
97 for (ppTimPrev = &pAC->Tim.StQueue; (pTm = *ppTimPrev);
98 ppTimPrev = &pTm->TmNext ) {
99
100 if (pTm == pTimer) {
101 /*
102 * Timer found in queue
103 * - dequeue it and
104 * - correct delta of the next timer
105 */
106 *ppTimPrev = pTm->TmNext;
107
108 if (pTm->TmNext) {
109 /* correct delta of next timer in queue */
110 pTm->TmNext->TmDelta += pTm->TmDelta;
111 }
112 return;
113 }
114 }
115}
116
117/*
118 * Start a high level software timer
119 */
120void SkTimerStart(
121SK_AC *pAC, /* Adapters context */
122SK_IOC Ioc, /* IoContext */
123SK_TIMER *pTimer, /* Timer Pointer to be started */
124SK_U32 Time, /* Time value */
125SK_U32 Class, /* Event Class for this timer */
126SK_U32 Event, /* Event Value for this timer */
127SK_EVPARA Para) /* Event Parameter for this timer */
128{
129 SK_TIMER **ppTimPrev;
130 SK_TIMER *pTm;
131 SK_U32 Delta;
132
133 Time /= 16; /* input is uS, clock ticks are 16uS */
134
135 if (!Time)
136 Time = 1;
137
138 SkTimerStop(pAC, Ioc, pTimer);
139
140 pTimer->TmClass = Class;
141 pTimer->TmEvent = Event;
142 pTimer->TmPara = Para;
143 pTimer->TmActive = SK_TRUE;
144
145 if (!pAC->Tim.StQueue) {
146 /* First Timer to be started */
147 pAC->Tim.StQueue = pTimer;
148 pTimer->TmNext = NULL;
149 pTimer->TmDelta = Time;
150
151 SkHwtStart(pAC, Ioc, Time);
152
153 return;
154 }
155
156 /*
157 * timer correction
158 */
159 timer_done(pAC, Ioc, 0);
160
161 /*
162 * find position in queue
163 */
164 Delta = 0;
165 for (ppTimPrev = &pAC->Tim.StQueue; (pTm = *ppTimPrev);
166 ppTimPrev = &pTm->TmNext ) {
167
168 if (Delta + pTm->TmDelta > Time) {
169 /* Position found */
170 /* Here the timer needs to be inserted. */
171 break;
172 }
173 Delta += pTm->TmDelta;
174 }
175
176 /* insert in queue */
177 *ppTimPrev = pTimer;
178 pTimer->TmNext = pTm;
179 pTimer->TmDelta = Time - Delta;
180
181 if (pTm) {
182 /* There is a next timer
183 * -> correct its Delta value.
184 */
185 pTm->TmDelta -= pTimer->TmDelta;
186 }
187
188 /* restart with first */
189 SkHwtStart(pAC, Ioc, pAC->Tim.StQueue->TmDelta);
190}
191
192
193void SkTimerDone(
194SK_AC *pAC, /* Adapters context */
195SK_IOC Ioc) /* IoContext */
196{
197 timer_done(pAC, Ioc, 1);
198}
199
200
201static void timer_done(
202SK_AC *pAC, /* Adapters context */
203SK_IOC Ioc, /* IoContext */
204int Restart) /* Do we need to restart the Hardware timer ? */
205{
206 SK_U32 Delta;
207 SK_TIMER *pTm;
208 SK_TIMER *pTComp; /* Timer completed now now */
209 SK_TIMER **ppLast; /* Next field of Last timer to be deq */
210 int Done = 0;
211
212 Delta = SkHwtRead(pAC, Ioc);
213
214 ppLast = &pAC->Tim.StQueue;
215 pTm = pAC->Tim.StQueue;
216 while (pTm && !Done) {
217 if (Delta >= pTm->TmDelta) {
218 /* Timer ran out */
219 pTm->TmActive = SK_FALSE;
220 Delta -= pTm->TmDelta;
221 ppLast = &pTm->TmNext;
222 pTm = pTm->TmNext;
223 }
224 else {
225 /* We found the first timer that did not run out */
226 pTm->TmDelta -= Delta;
227 Delta = 0;
228 Done = 1;
229 }
230 }
231 *ppLast = NULL;
232 /*
233 * pTm points to the first Timer that did not run out.
234 * StQueue points to the first Timer that run out.
235 */
236
237 for ( pTComp = pAC->Tim.StQueue; pTComp; pTComp = pTComp->TmNext) {
238 SkEventQueue(pAC,pTComp->TmClass, pTComp->TmEvent, pTComp->TmPara);
239 }
240
241 /* Set head of timer queue to the first timer that did not run out */
242 pAC->Tim.StQueue = pTm;
243
244 if (Restart && pAC->Tim.StQueue) {
245 /* Restart HW timer */
246 SkHwtStart(pAC, Ioc, pAC->Tim.StQueue->TmDelta);
247 }
248}
249
250/* End of file */
diff --git a/drivers/net/sk98lin/skvpd.c b/drivers/net/sk98lin/skvpd.c
deleted file mode 100644
index 1e662aaebf84..000000000000
--- a/drivers/net/sk98lin/skvpd.c
+++ /dev/null
@@ -1,1091 +0,0 @@
1/******************************************************************************
2 *
3 * Name: skvpd.c
4 * Project: GEnesis, PCI Gigabit Ethernet Adapter
5 * Version: $Revision: 1.37 $
6 * Date: $Date: 2003/01/13 10:42:45 $
7 * Purpose: Shared software to read and write VPD data
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2003 SysKonnect GmbH.
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * The information in this file is provided "AS IS" without warranty.
21 *
22 ******************************************************************************/
23
24/*
25 Please refer skvpd.txt for information how to include this module
26 */
27static const char SysKonnectFileId[] =
28 "@(#)$Id: skvpd.c,v 1.37 2003/01/13 10:42:45 rschmidt Exp $ (C) SK";
29
30#include "h/skdrv1st.h"
31#include "h/sktypes.h"
32#include "h/skdebug.h"
33#include "h/skdrv2nd.h"
34
35/*
36 * Static functions
37 */
38#ifndef SK_KR_PROTO
39static SK_VPD_PARA *vpd_find_para(
40 SK_AC *pAC,
41 const char *key,
42 SK_VPD_PARA *p);
43#else /* SK_KR_PROTO */
44static SK_VPD_PARA *vpd_find_para();
45#endif /* SK_KR_PROTO */
46
47/*
48 * waits for a completion of a VPD transfer
49 * The VPD transfer must complete within SK_TICKS_PER_SEC/16
50 *
51 * returns 0: success, transfer completes
52 * error exit(9) with a error message
53 */
54static int VpdWait(
55SK_AC *pAC, /* Adapters context */
56SK_IOC IoC, /* IO Context */
57int event) /* event to wait for (VPD_READ / VPD_write) completion*/
58{
59 SK_U64 start_time;
60 SK_U16 state;
61
62 SK_DBG_MSG(pAC,SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
63 ("VPD wait for %s\n", event?"Write":"Read"));
64 start_time = SkOsGetTime(pAC);
65 do {
66 if (SkOsGetTime(pAC) - start_time > SK_TICKS_PER_SEC) {
67
68 /* Bug fix AF: Thu Mar 28 2002
69 * Do not call: VPD_STOP(pAC, IoC);
70 * A pending VPD read cycle can not be aborted by writing
71 * VPD_WRITE to the PCI_VPD_ADR_REG (VPD address register).
72 * Although the write threshold in the OUR-register protects
73 * VPD read only space from being overwritten this does not
74 * protect a VPD read from being `converted` into a VPD write
75 * operation (on the fly). As a consequence the VPD_STOP would
76 * delete VPD read only data. In case of any problems with the
77 * I2C bus we exit the loop here. The I2C read operation can
78 * not be aborted except by a reset (->LR).
79 */
80 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_FATAL | SK_DBGCAT_ERR,
81 ("ERROR:VPD wait timeout\n"));
82 return(1);
83 }
84
85 VPD_IN16(pAC, IoC, PCI_VPD_ADR_REG, &state);
86
87 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
88 ("state = %x, event %x\n",state,event));
89 } while((int)(state & PCI_VPD_FLAG) == event);
90
91 return(0);
92}
93
94#ifdef SKDIAG
95
96/*
97 * Read the dword at address 'addr' from the VPD EEPROM.
98 *
99 * Needed Time: MIN 1,3 ms MAX 2,6 ms
100 *
101 * Note: The DWord is returned in the endianess of the machine the routine
102 * is running on.
103 *
104 * Returns the data read.
105 */
106SK_U32 VpdReadDWord(
107SK_AC *pAC, /* Adapters context */
108SK_IOC IoC, /* IO Context */
109int addr) /* VPD address */
110{
111 SK_U32 Rtv;
112
113 /* start VPD read */
114 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
115 ("VPD read dword at 0x%x\n",addr));
116 addr &= ~VPD_WRITE; /* ensure the R/W bit is set to read */
117
118 VPD_OUT16(pAC, IoC, PCI_VPD_ADR_REG, (SK_U16)addr);
119
120 /* ignore return code here */
121 (void)VpdWait(pAC, IoC, VPD_READ);
122
123 /* Don't swap here, it's a data stream of bytes */
124 Rtv = 0;
125
126 VPD_IN32(pAC, IoC, PCI_VPD_DAT_REG, &Rtv);
127
128 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
129 ("VPD read dword data = 0x%x\n",Rtv));
130 return(Rtv);
131}
132
133#endif /* SKDIAG */
134
135/*
136 * Read one Stream of 'len' bytes of VPD data, starting at 'addr' from
137 * or to the I2C EEPROM.
138 *
139 * Returns number of bytes read / written.
140 */
141static int VpdWriteStream(
142SK_AC *pAC, /* Adapters context */
143SK_IOC IoC, /* IO Context */
144char *buf, /* data buffer */
145int Addr, /* VPD start address */
146int Len) /* number of bytes to read / to write */
147{
148 int i;
149 int j;
150 SK_U16 AdrReg;
151 int Rtv;
152 SK_U8 * pComp; /* Compare pointer */
153 SK_U8 Data; /* Input Data for Compare */
154
155 /* Init Compare Pointer */
156 pComp = (SK_U8 *) buf;
157
158 for (i = 0; i < Len; i++, buf++) {
159 if ((i%sizeof(SK_U32)) == 0) {
160 /*
161 * At the begin of each cycle read the Data Reg
162 * So it is initialized even if only a few bytes
163 * are written.
164 */
165 AdrReg = (SK_U16) Addr;
166 AdrReg &= ~VPD_WRITE; /* READ operation */
167
168 VPD_OUT16(pAC, IoC, PCI_VPD_ADR_REG, AdrReg);
169
170 /* Wait for termination */
171 Rtv = VpdWait(pAC, IoC, VPD_READ);
172 if (Rtv != 0) {
173 return(i);
174 }
175 }
176
177 /* Write current Byte */
178 VPD_OUT8(pAC, IoC, PCI_VPD_DAT_REG + (i%sizeof(SK_U32)),
179 *(SK_U8*)buf);
180
181 if (((i%sizeof(SK_U32)) == 3) || (i == (Len - 1))) {
182 /* New Address needs to be written to VPD_ADDR reg */
183 AdrReg = (SK_U16) Addr;
184 Addr += sizeof(SK_U32);
185 AdrReg |= VPD_WRITE; /* WRITE operation */
186
187 VPD_OUT16(pAC, IoC, PCI_VPD_ADR_REG, AdrReg);
188
189 /* Wait for termination */
190 Rtv = VpdWait(pAC, IoC, VPD_WRITE);
191 if (Rtv != 0) {
192 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
193 ("Write Timed Out\n"));
194 return(i - (i%sizeof(SK_U32)));
195 }
196
197 /*
198 * Now re-read to verify
199 */
200 AdrReg &= ~VPD_WRITE; /* READ operation */
201
202 VPD_OUT16(pAC, IoC, PCI_VPD_ADR_REG, AdrReg);
203
204 /* Wait for termination */
205 Rtv = VpdWait(pAC, IoC, VPD_READ);
206 if (Rtv != 0) {
207 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
208 ("Verify Timed Out\n"));
209 return(i - (i%sizeof(SK_U32)));
210 }
211
212 for (j = 0; j <= (int)(i%sizeof(SK_U32)); j++, pComp++) {
213
214 VPD_IN8(pAC, IoC, PCI_VPD_DAT_REG + j, &Data);
215
216 if (Data != *pComp) {
217 /* Verify Error */
218 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
219 ("WriteStream Verify Error\n"));
220 return(i - (i%sizeof(SK_U32)) + j);
221 }
222 }
223 }
224 }
225
226 return(Len);
227}
228
229
230/*
231 * Read one Stream of 'len' bytes of VPD data, starting at 'addr' from
232 * or to the I2C EEPROM.
233 *
234 * Returns number of bytes read / written.
235 */
236static int VpdReadStream(
237SK_AC *pAC, /* Adapters context */
238SK_IOC IoC, /* IO Context */
239char *buf, /* data buffer */
240int Addr, /* VPD start address */
241int Len) /* number of bytes to read / to write */
242{
243 int i;
244 SK_U16 AdrReg;
245 int Rtv;
246
247 for (i = 0; i < Len; i++, buf++) {
248 if ((i%sizeof(SK_U32)) == 0) {
249 /* New Address needs to be written to VPD_ADDR reg */
250 AdrReg = (SK_U16) Addr;
251 Addr += sizeof(SK_U32);
252 AdrReg &= ~VPD_WRITE; /* READ operation */
253
254 VPD_OUT16(pAC, IoC, PCI_VPD_ADR_REG, AdrReg);
255
256 /* Wait for termination */
257 Rtv = VpdWait(pAC, IoC, VPD_READ);
258 if (Rtv != 0) {
259 return(i);
260 }
261 }
262 VPD_IN8(pAC, IoC, PCI_VPD_DAT_REG + (i%sizeof(SK_U32)),
263 (SK_U8 *)buf);
264 }
265
266 return(Len);
267}
268
269/*
270 * Read ore writes 'len' bytes of VPD data, starting at 'addr' from
271 * or to the I2C EEPROM.
272 *
273 * Returns number of bytes read / written.
274 */
275static int VpdTransferBlock(
276SK_AC *pAC, /* Adapters context */
277SK_IOC IoC, /* IO Context */
278char *buf, /* data buffer */
279int addr, /* VPD start address */
280int len, /* number of bytes to read / to write */
281int dir) /* transfer direction may be VPD_READ or VPD_WRITE */
282{
283 int Rtv; /* Return value */
284 int vpd_rom_size;
285
286 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
287 ("VPD %s block, addr = 0x%x, len = %d\n",
288 dir ? "write" : "read", addr, len));
289
290 if (len == 0)
291 return(0);
292
293 vpd_rom_size = pAC->vpd.rom_size;
294
295 if (addr > vpd_rom_size - 4) {
296 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
297 ("Address error: 0x%x, exp. < 0x%x\n",
298 addr, vpd_rom_size - 4));
299 return(0);
300 }
301
302 if (addr + len > vpd_rom_size) {
303 len = vpd_rom_size - addr;
304 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
305 ("Warning: len was cut to %d\n", len));
306 }
307
308 if (dir == VPD_READ) {
309 Rtv = VpdReadStream(pAC, IoC, buf, addr, len);
310 }
311 else {
312 Rtv = VpdWriteStream(pAC, IoC, buf, addr, len);
313 }
314
315 return(Rtv);
316}
317
318#ifdef SKDIAG
319
320/*
321 * Read 'len' bytes of VPD data, starting at 'addr'.
322 *
323 * Returns number of bytes read.
324 */
325int VpdReadBlock(
326SK_AC *pAC, /* pAC pointer */
327SK_IOC IoC, /* IO Context */
328char *buf, /* buffer were the data should be stored */
329int addr, /* start reading at the VPD address */
330int len) /* number of bytes to read */
331{
332 return(VpdTransferBlock(pAC, IoC, buf, addr, len, VPD_READ));
333}
334
335/*
336 * Write 'len' bytes of *but to the VPD EEPROM, starting at 'addr'.
337 *
338 * Returns number of bytes writes.
339 */
340int VpdWriteBlock(
341SK_AC *pAC, /* pAC pointer */
342SK_IOC IoC, /* IO Context */
343char *buf, /* buffer, holds the data to write */
344int addr, /* start writing at the VPD address */
345int len) /* number of bytes to write */
346{
347 return(VpdTransferBlock(pAC, IoC, buf, addr, len, VPD_WRITE));
348}
349#endif /* SKDIAG */
350
351/*
352 * (re)initialize the VPD buffer
353 *
354 * Reads the VPD data from the EEPROM into the VPD buffer.
355 * Get the remaining read only and read / write space.
356 *
357 * return 0: success
358 * 1: fatal VPD error
359 */
360static int VpdInit(
361SK_AC *pAC, /* Adapters context */
362SK_IOC IoC) /* IO Context */
363{
364 SK_VPD_PARA *r, rp; /* RW or RV */
365 int i;
366 unsigned char x;
367 int vpd_size;
368 SK_U16 dev_id;
369 SK_U32 our_reg2;
370
371 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_INIT, ("VpdInit .. "));
372
373 VPD_IN16(pAC, IoC, PCI_DEVICE_ID, &dev_id);
374
375 VPD_IN32(pAC, IoC, PCI_OUR_REG_2, &our_reg2);
376
377 pAC->vpd.rom_size = 256 << ((our_reg2 & PCI_VPD_ROM_SZ) >> 14);
378
379 /*
380 * this function might get used before the hardware is initialized
381 * therefore we cannot always trust in GIChipId
382 */
383 if (((pAC->vpd.v.vpd_status & VPD_VALID) == 0 &&
384 dev_id != VPD_DEV_ID_GENESIS) ||
385 ((pAC->vpd.v.vpd_status & VPD_VALID) != 0 &&
386 !pAC->GIni.GIGenesis)) {
387
388 /* for Yukon the VPD size is always 256 */
389 vpd_size = VPD_SIZE_YUKON;
390 }
391 else {
392 /* Genesis uses the maximum ROM size up to 512 for VPD */
393 if (pAC->vpd.rom_size > VPD_SIZE_GENESIS) {
394 vpd_size = VPD_SIZE_GENESIS;
395 }
396 else {
397 vpd_size = pAC->vpd.rom_size;
398 }
399 }
400
401 /* read the VPD data into the VPD buffer */
402 if (VpdTransferBlock(pAC, IoC, pAC->vpd.vpd_buf, 0, vpd_size, VPD_READ)
403 != vpd_size) {
404
405 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
406 ("Block Read Error\n"));
407 return(1);
408 }
409
410 pAC->vpd.vpd_size = vpd_size;
411
412 /* Asus K8V Se Deluxe bugfix. Correct VPD content */
413 /* MBo April 2004 */
414 if (((unsigned char)pAC->vpd.vpd_buf[0x3f] == 0x38) &&
415 ((unsigned char)pAC->vpd.vpd_buf[0x40] == 0x3c) &&
416 ((unsigned char)pAC->vpd.vpd_buf[0x41] == 0x45)) {
417 printk("sk98lin: Asus mainboard with buggy VPD? "
418 "Correcting data.\n");
419 pAC->vpd.vpd_buf[0x40] = 0x38;
420 }
421
422
423 /* find the end tag of the RO area */
424 if (!(r = vpd_find_para(pAC, VPD_RV, &rp))) {
425 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
426 ("Encoding Error: RV Tag not found\n"));
427 return(1);
428 }
429
430 if (r->p_val + r->p_len > pAC->vpd.vpd_buf + vpd_size/2) {
431 SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
432 ("Encoding Error: Invalid VPD struct size\n"));
433 return(1);
434 }
435 pAC->vpd.v.vpd_free_ro = r->p_len - 1;
436
437 /* test the checksum */
438 for (i = 0, x = 0; (unsigned)i <= (unsigned)vpd_size/2 - r->p_len; i++) {
439 x += pAC->vpd.vpd_buf[i];
440 }
441
442 if (x != 0) {
443 /* checksum error */
444 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
445 ("VPD Checksum Error\n"));
446 return(1);
447 }
448
449 /* find and check the end tag of the RW area */
450 if (!(r = vpd_find_para(pAC, VPD_RW, &rp))) {
451 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
452 ("Encoding Error: RV Tag not found\n"));
453 return(1);
454 }
455
456 if (r->p_val < pAC->vpd.vpd_buf + vpd_size/2) {
457 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
458 ("Encoding Error: Invalid VPD struct size\n"));
459 return(1);
460 }
461 pAC->vpd.v.vpd_free_rw = r->p_len;
462
463 /* everything seems to be ok */
464 if (pAC->GIni.GIChipId != 0) {
465 pAC->vpd.v.vpd_status |= VPD_VALID;
466 }
467
468 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_INIT,
469 ("done. Free RO = %d, Free RW = %d\n",
470 pAC->vpd.v.vpd_free_ro, pAC->vpd.v.vpd_free_rw));
471
472 return(0);
473}
474
475/*
476 * find the Keyword 'key' in the VPD buffer and fills the
477 * parameter struct 'p' with it's values
478 *
479 * returns *p success
480 * 0: parameter was not found or VPD encoding error
481 */
482static SK_VPD_PARA *vpd_find_para(
483SK_AC *pAC, /* common data base */
484const char *key, /* keyword to find (e.g. "MN") */
485SK_VPD_PARA *p) /* parameter description struct */
486{
487 char *v ; /* points to VPD buffer */
488 int max; /* Maximum Number of Iterations */
489
490 v = pAC->vpd.vpd_buf;
491 max = 128;
492
493 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
494 ("VPD find para %s .. ",key));
495
496 /* check mandatory resource type ID string (Product Name) */
497 if (*v != (char)RES_ID) {
498 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
499 ("Error: 0x%x missing\n", RES_ID));
500 return NULL;
501 }
502
503 if (strcmp(key, VPD_NAME) == 0) {
504 p->p_len = VPD_GET_RES_LEN(v);
505 p->p_val = VPD_GET_VAL(v);
506 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
507 ("found, len = %d\n", p->p_len));
508 return(p);
509 }
510
511 v += 3 + VPD_GET_RES_LEN(v) + 3;
512 for (;; ) {
513 if (SK_MEMCMP(key,v,2) == 0) {
514 p->p_len = VPD_GET_VPD_LEN(v);
515 p->p_val = VPD_GET_VAL(v);
516 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
517 ("found, len = %d\n",p->p_len));
518 return(p);
519 }
520
521 /* exit when reaching the "RW" Tag or the maximum of itera. */
522 max--;
523 if (SK_MEMCMP(VPD_RW,v,2) == 0 || max == 0) {
524 break;
525 }
526
527 if (SK_MEMCMP(VPD_RV,v,2) == 0) {
528 v += 3 + VPD_GET_VPD_LEN(v) + 3; /* skip VPD-W */
529 }
530 else {
531 v += 3 + VPD_GET_VPD_LEN(v);
532 }
533 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
534 ("scanning '%c%c' len = %d\n",v[0],v[1],v[2]));
535 }
536
537#ifdef DEBUG
538 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL, ("not found\n"));
539 if (max == 0) {
540 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
541 ("Key/Len Encoding error\n"));
542 }
543#endif /* DEBUG */
544 return NULL;
545}
546
547/*
548 * Move 'n' bytes. Begin with the last byte if 'n' is > 0,
549 * Start with the last byte if n is < 0.
550 *
551 * returns nothing
552 */
553static void vpd_move_para(
554char *start, /* start of memory block */
555char *end, /* end of memory block to move */
556int n) /* number of bytes the memory block has to be moved */
557{
558 char *p;
559 int i; /* number of byte copied */
560
561 if (n == 0)
562 return;
563
564 i = (int) (end - start + 1);
565 if (n < 0) {
566 p = start + n;
567 while (i != 0) {
568 *p++ = *start++;
569 i--;
570 }
571 }
572 else {
573 p = end + n;
574 while (i != 0) {
575 *p-- = *end--;
576 i--;
577 }
578 }
579}
580
581/*
582 * setup the VPD keyword 'key' at 'ip'.
583 *
584 * returns nothing
585 */
586static void vpd_insert_key(
587const char *key, /* keyword to insert */
588const char *buf, /* buffer with the keyword value */
589int len, /* length of the value string */
590char *ip) /* inseration point */
591{
592 SK_VPD_KEY *p;
593
594 p = (SK_VPD_KEY *) ip;
595 p->p_key[0] = key[0];
596 p->p_key[1] = key[1];
597 p->p_len = (unsigned char) len;
598 SK_MEMCPY(&p->p_val,buf,len);
599}
600
601/*
602 * Setup the VPD end tag "RV" / "RW".
603 * Also correct the remaining space variables vpd_free_ro / vpd_free_rw.
604 *
605 * returns 0: success
606 * 1: encoding error
607 */
608static int vpd_mod_endtag(
609SK_AC *pAC, /* common data base */
610char *etp) /* end pointer input position */
611{
612 SK_VPD_KEY *p;
613 unsigned char x;
614 int i;
615 int vpd_size;
616
617 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
618 ("VPD modify endtag at 0x%x = '%c%c'\n",etp,etp[0],etp[1]));
619
620 vpd_size = pAC->vpd.vpd_size;
621
622 p = (SK_VPD_KEY *) etp;
623
624 if (p->p_key[0] != 'R' || (p->p_key[1] != 'V' && p->p_key[1] != 'W')) {
625 /* something wrong here, encoding error */
626 SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
627 ("Encoding Error: invalid end tag\n"));
628 return(1);
629 }
630 if (etp > pAC->vpd.vpd_buf + vpd_size/2) {
631 /* create "RW" tag */
632 p->p_len = (unsigned char)(pAC->vpd.vpd_buf+vpd_size-etp-3-1);
633 pAC->vpd.v.vpd_free_rw = (int) p->p_len;
634 i = pAC->vpd.v.vpd_free_rw;
635 etp += 3;
636 }
637 else {
638 /* create "RV" tag */
639 p->p_len = (unsigned char)(pAC->vpd.vpd_buf+vpd_size/2-etp-3);
640 pAC->vpd.v.vpd_free_ro = (int) p->p_len - 1;
641
642 /* setup checksum */
643 for (i = 0, x = 0; i < vpd_size/2 - p->p_len; i++) {
644 x += pAC->vpd.vpd_buf[i];
645 }
646 p->p_val = (char) 0 - x;
647 i = pAC->vpd.v.vpd_free_ro;
648 etp += 4;
649 }
650 while (i) {
651 *etp++ = 0x00;
652 i--;
653 }
654
655 return(0);
656}
657
658/*
659 * Insert a VPD keyword into the VPD buffer.
660 *
661 * The keyword 'key' is inserted at the position 'ip' in the
662 * VPD buffer.
663 * The keywords behind the input position will
664 * be moved. The VPD end tag "RV" or "RW" is generated again.
665 *
666 * returns 0: success
667 * 2: value string was cut
668 * 4: VPD full, keyword was not written
669 * 6: fatal VPD error
670 *
671 */
672static int VpdSetupPara(
673SK_AC *pAC, /* common data base */
674const char *key, /* keyword to insert */
675const char *buf, /* buffer with the keyword value */
676int len, /* length of the keyword value */
677int type, /* VPD_RO_KEY or VPD_RW_KEY */
678int op) /* operation to do: ADD_KEY or OWR_KEY */
679{
680 SK_VPD_PARA vp;
681 char *etp; /* end tag position */
682 int free; /* remaining space in selected area */
683 char *ip; /* input position inside the VPD buffer */
684 int rtv; /* return code */
685 int head; /* additional haeder bytes to move */
686 int found; /* additinoal bytes if the keyword was found */
687 int vpd_size;
688
689 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
690 ("VPD setup para key = %s, val = %s\n",key,buf));
691
692 vpd_size = pAC->vpd.vpd_size;
693
694 rtv = 0;
695 ip = NULL;
696 if (type == VPD_RW_KEY) {
697 /* end tag is "RW" */
698 free = pAC->vpd.v.vpd_free_rw;
699 etp = pAC->vpd.vpd_buf + (vpd_size - free - 1 - 3);
700 }
701 else {
702 /* end tag is "RV" */
703 free = pAC->vpd.v.vpd_free_ro;
704 etp = pAC->vpd.vpd_buf + (vpd_size/2 - free - 4);
705 }
706 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
707 ("Free RO = %d, Free RW = %d\n",
708 pAC->vpd.v.vpd_free_ro, pAC->vpd.v.vpd_free_rw));
709
710 head = 0;
711 found = 0;
712 if (op == OWR_KEY) {
713 if (vpd_find_para(pAC, key, &vp)) {
714 found = 3;
715 ip = vp.p_val - 3;
716 free += vp.p_len + 3;
717 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
718 ("Overwrite Key\n"));
719 }
720 else {
721 op = ADD_KEY;
722 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
723 ("Add Key\n"));
724 }
725 }
726 if (op == ADD_KEY) {
727 ip = etp;
728 vp.p_len = 0;
729 head = 3;
730 }
731
732 if (len + 3 > free) {
733 if (free < 7) {
734 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
735 ("VPD Buffer Overflow, keyword not written\n"));
736 return(4);
737 }
738 /* cut it again */
739 len = free - 3;
740 rtv = 2;
741 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
742 ("VPD Buffer Full, Keyword was cut\n"));
743 }
744
745 vpd_move_para(ip + vp.p_len + found, etp+2, len-vp.p_len+head);
746 vpd_insert_key(key, buf, len, ip);
747 if (vpd_mod_endtag(pAC, etp + len - vp.p_len + head)) {
748 pAC->vpd.v.vpd_status &= ~VPD_VALID;
749 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
750 ("VPD Encoding Error\n"));
751 return(6);
752 }
753
754 return(rtv);
755}
756
757
758/*
759 * Read the contents of the VPD EEPROM and copy it to the
760 * VPD buffer if not already done.
761 *
762 * return: A pointer to the vpd_status structure. The structure contains
763 * this fields.
764 */
765SK_VPD_STATUS *VpdStat(
766SK_AC *pAC, /* Adapters context */
767SK_IOC IoC) /* IO Context */
768{
769 if ((pAC->vpd.v.vpd_status & VPD_VALID) == 0) {
770 (void)VpdInit(pAC, IoC);
771 }
772 return(&pAC->vpd.v);
773}
774
775
776/*
777 * Read the contents of the VPD EEPROM and copy it to the VPD
778 * buffer if not already done.
779 * Scan the VPD buffer for VPD keywords and create the VPD
780 * keyword list by copying the keywords to 'buf', all after
781 * each other and terminated with a '\0'.
782 *
783 * Exceptions: o The Resource Type ID String (product name) is called "Name"
784 * o The VPD end tags 'RV' and 'RW' are not listed
785 *
786 * The number of copied keywords is counted in 'elements'.
787 *
788 * returns 0: success
789 * 2: buffer overfull, one or more keywords are missing
790 * 6: fatal VPD error
791 *
792 * example values after returning:
793 *
794 * buf = "Name\0PN\0EC\0MN\0SN\0CP\0VF\0VL\0YA\0"
795 * *len = 30
796 * *elements = 9
797 */
798int VpdKeys(
799SK_AC *pAC, /* common data base */
800SK_IOC IoC, /* IO Context */
801char *buf, /* buffer where to copy the keywords */
802int *len, /* buffer length */
803int *elements) /* number of keywords returned */
804{
805 char *v;
806 int n;
807
808 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX, ("list VPD keys .. "));
809 *elements = 0;
810 if ((pAC->vpd.v.vpd_status & VPD_VALID) == 0) {
811 if (VpdInit(pAC, IoC) != 0) {
812 *len = 0;
813 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
814 ("VPD Init Error, terminated\n"));
815 return(6);
816 }
817 }
818
819 if ((signed)strlen(VPD_NAME) + 1 <= *len) {
820 v = pAC->vpd.vpd_buf;
821 strcpy(buf,VPD_NAME);
822 n = strlen(VPD_NAME) + 1;
823 buf += n;
824 *elements = 1;
825 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX,
826 ("'%c%c' ",v[0],v[1]));
827 }
828 else {
829 *len = 0;
830 SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR,
831 ("buffer overflow\n"));
832 return(2);
833 }
834
835 v += 3 + VPD_GET_RES_LEN(v) + 3;
836 for (;; ) {
837 /* exit when reaching the "RW" Tag */
838 if (SK_MEMCMP(VPD_RW,v,2) == 0) {
839 break;
840 }
841
842 if (SK_MEMCMP(VPD_RV,v,2) == 0) {
843 v += 3 + VPD_GET_VPD_LEN(v) + 3; /* skip VPD-W */
844 continue;
845 }
846
847 if (n+3 <= *len) {
848 SK_MEMCPY(buf,v,2);
849 buf += 2;
850 *buf++ = '\0';
851 n += 3;
852 v += 3 + VPD_GET_VPD_LEN(v);
853 *elements += 1;
854 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX,
855 ("'%c%c' ",v[0],v[1]));
856 }
857 else {
858 *len = n;
859 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
860 ("buffer overflow\n"));
861 return(2);
862 }
863 }
864
865 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX, ("\n"));
866 *len = n;
867 return(0);
868}
869
870
871/*
872 * Read the contents of the VPD EEPROM and copy it to the
873 * VPD buffer if not already done. Search for the VPD keyword
874 * 'key' and copy its value to 'buf'. Add a terminating '\0'.
875 * If the value does not fit into the buffer cut it after
876 * 'len' - 1 bytes.
877 *
878 * returns 0: success
879 * 1: keyword not found
880 * 2: value string was cut
881 * 3: VPD transfer timeout
882 * 6: fatal VPD error
883 */
884int VpdRead(
885SK_AC *pAC, /* common data base */
886SK_IOC IoC, /* IO Context */
887const char *key, /* keyword to read (e.g. "MN") */
888char *buf, /* buffer where to copy the keyword value */
889int *len) /* buffer length */
890{
891 SK_VPD_PARA *p, vp;
892
893 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX, ("VPD read %s .. ", key));
894 if ((pAC->vpd.v.vpd_status & VPD_VALID) == 0) {
895 if (VpdInit(pAC, IoC) != 0) {
896 *len = 0;
897 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
898 ("VPD init error\n"));
899 return(6);
900 }
901 }
902
903 if ((p = vpd_find_para(pAC, key, &vp)) != NULL) {
904 if (p->p_len > (*(unsigned *)len)-1) {
905 p->p_len = *len - 1;
906 }
907 SK_MEMCPY(buf, p->p_val, p->p_len);
908 buf[p->p_len] = '\0';
909 *len = p->p_len;
910 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX,
911 ("%c%c%c%c.., len = %d\n",
912 buf[0],buf[1],buf[2],buf[3],*len));
913 }
914 else {
915 *len = 0;
916 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, ("not found\n"));
917 return(1);
918 }
919 return(0);
920}
921
922
923/*
924 * Check whether a given key may be written
925 *
926 * returns
927 * SK_TRUE Yes it may be written
928 * SK_FALSE No it may be written
929 */
930SK_BOOL VpdMayWrite(
931char *key) /* keyword to write (allowed values "Yx", "Vx") */
932{
933 if ((*key != 'Y' && *key != 'V') ||
934 key[1] < '0' || key[1] > 'Z' ||
935 (key[1] > '9' && key[1] < 'A') || strlen(key) != 2) {
936
937 return(SK_FALSE);
938 }
939 return(SK_TRUE);
940}
941
942/*
943 * Read the contents of the VPD EEPROM and copy it to the VPD
944 * buffer if not already done. Insert/overwrite the keyword 'key'
945 * in the VPD buffer. Cut the keyword value if it does not fit
946 * into the VPD read / write area.
947 *
948 * returns 0: success
949 * 2: value string was cut
950 * 3: VPD transfer timeout
951 * 4: VPD full, keyword was not written
952 * 5: keyword cannot be written
953 * 6: fatal VPD error
954 */
955int VpdWrite(
956SK_AC *pAC, /* common data base */
957SK_IOC IoC, /* IO Context */
958const char *key, /* keyword to write (allowed values "Yx", "Vx") */
959const char *buf) /* buffer where the keyword value can be read from */
960{
961 int len; /* length of the keyword to write */
962 int rtv; /* return code */
963 int rtv2;
964
965 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_TX,
966 ("VPD write %s = %s\n",key,buf));
967
968 if ((*key != 'Y' && *key != 'V') ||
969 key[1] < '0' || key[1] > 'Z' ||
970 (key[1] > '9' && key[1] < 'A') || strlen(key) != 2) {
971
972 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
973 ("illegal key tag, keyword not written\n"));
974 return(5);
975 }
976
977 if ((pAC->vpd.v.vpd_status & VPD_VALID) == 0) {
978 if (VpdInit(pAC, IoC) != 0) {
979 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
980 ("VPD init error\n"));
981 return(6);
982 }
983 }
984
985 rtv = 0;
986 len = strlen(buf);
987 if (len > VPD_MAX_LEN) {
988 /* cut it */
989 len = VPD_MAX_LEN;
990 rtv = 2;
991 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
992 ("keyword too long, cut after %d bytes\n",VPD_MAX_LEN));
993 }
994 if ((rtv2 = VpdSetupPara(pAC, key, buf, len, VPD_RW_KEY, OWR_KEY)) != 0) {
995 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
996 ("VPD write error\n"));
997 return(rtv2);
998 }
999
1000 return(rtv);
1001}
1002
1003/*
1004 * Read the contents of the VPD EEPROM and copy it to the
1005 * VPD buffer if not already done. Remove the VPD keyword
1006 * 'key' from the VPD buffer.
1007 * Only the keywords in the read/write area can be deleted.
1008 * Keywords in the read only area cannot be deleted.
1009 *
1010 * returns 0: success, keyword was removed
1011 * 1: keyword not found
1012 * 5: keyword cannot be deleted
1013 * 6: fatal VPD error
1014 */
1015int VpdDelete(
1016SK_AC *pAC, /* common data base */
1017SK_IOC IoC, /* IO Context */
1018char *key) /* keyword to read (e.g. "MN") */
1019{
1020 SK_VPD_PARA *p, vp;
1021 char *etp;
1022 int vpd_size;
1023
1024 vpd_size = pAC->vpd.vpd_size;
1025
1026 SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_TX,("VPD delete key %s\n",key));
1027 if ((pAC->vpd.v.vpd_status & VPD_VALID) == 0) {
1028 if (VpdInit(pAC, IoC) != 0) {
1029 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
1030 ("VPD init error\n"));
1031 return(6);
1032 }
1033 }
1034
1035 if ((p = vpd_find_para(pAC, key, &vp)) != NULL) {
1036 if (p->p_val < pAC->vpd.vpd_buf + vpd_size/2) {
1037 /* try to delete read only keyword */
1038 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
1039 ("cannot delete RO keyword\n"));
1040 return(5);
1041 }
1042
1043 etp = pAC->vpd.vpd_buf + (vpd_size-pAC->vpd.v.vpd_free_rw-1-3);
1044
1045 vpd_move_para(vp.p_val+vp.p_len, etp+2,
1046 - ((int)(vp.p_len + 3)));
1047 if (vpd_mod_endtag(pAC, etp - vp.p_len - 3)) {
1048 pAC->vpd.v.vpd_status &= ~VPD_VALID;
1049 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
1050 ("VPD encoding error\n"));
1051 return(6);
1052 }
1053 }
1054 else {
1055 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
1056 ("keyword not found\n"));
1057 return(1);
1058 }
1059
1060 return(0);
1061}
1062
1063/*
1064 * If the VPD buffer contains valid data write the VPD
1065 * read/write area back to the VPD EEPROM.
1066 *
1067 * returns 0: success
1068 * 3: VPD transfer timeout
1069 */
1070int VpdUpdate(
1071SK_AC *pAC, /* Adapters context */
1072SK_IOC IoC) /* IO Context */
1073{
1074 int vpd_size;
1075
1076 vpd_size = pAC->vpd.vpd_size;
1077
1078 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_TX, ("VPD update .. "));
1079 if ((pAC->vpd.v.vpd_status & VPD_VALID) != 0) {
1080 if (VpdTransferBlock(pAC, IoC, pAC->vpd.vpd_buf + vpd_size/2,
1081 vpd_size/2, vpd_size/2, VPD_WRITE) != vpd_size/2) {
1082
1083 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
1084 ("transfer timed out\n"));
1085 return(3);
1086 }
1087 }
1088 SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_TX, ("done\n"));
1089 return(0);
1090}
1091
diff --git a/drivers/net/sk98lin/skxmac2.c b/drivers/net/sk98lin/skxmac2.c
deleted file mode 100644
index b4e75022a657..000000000000
--- a/drivers/net/sk98lin/skxmac2.c
+++ /dev/null
@@ -1,4160 +0,0 @@
1/******************************************************************************
2 *
3 * Name: skxmac2.c
4 * Project: Gigabit Ethernet Adapters, Common Modules
5 * Version: $Revision: 1.102 $
6 * Date: $Date: 2003/10/02 16:53:58 $
7 * Purpose: Contains functions to initialize the MACs and PHYs
8 *
9 ******************************************************************************/
10
11/******************************************************************************
12 *
13 * (C)Copyright 1998-2002 SysKonnect.
14 * (C)Copyright 2002-2003 Marvell.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * The information in this file is provided "AS IS" without warranty.
22 *
23 ******************************************************************************/
24
25#include "h/skdrv1st.h"
26#include "h/skdrv2nd.h"
27
28/* typedefs *******************************************************************/
29
30/* BCOM PHY magic pattern list */
31typedef struct s_PhyHack {
32 int PhyReg; /* Phy register */
33 SK_U16 PhyVal; /* Value to write */
34} BCOM_HACK;
35
36/* local variables ************************************************************/
37
38#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
39static const char SysKonnectFileId[] =
40 "@(#) $Id: skxmac2.c,v 1.102 2003/10/02 16:53:58 rschmidt Exp $ (C) Marvell.";
41#endif
42
43#ifdef GENESIS
44static BCOM_HACK BcomRegA1Hack[] = {
45 { 0x18, 0x0c20 }, { 0x17, 0x0012 }, { 0x15, 0x1104 }, { 0x17, 0x0013 },
46 { 0x15, 0x0404 }, { 0x17, 0x8006 }, { 0x15, 0x0132 }, { 0x17, 0x8006 },
47 { 0x15, 0x0232 }, { 0x17, 0x800D }, { 0x15, 0x000F }, { 0x18, 0x0420 },
48 { 0, 0 }
49};
50static BCOM_HACK BcomRegC0Hack[] = {
51 { 0x18, 0x0c20 }, { 0x17, 0x0012 }, { 0x15, 0x1204 }, { 0x17, 0x0013 },
52 { 0x15, 0x0A04 }, { 0x18, 0x0420 },
53 { 0, 0 }
54};
55#endif
56
57/* function prototypes ********************************************************/
58#ifdef GENESIS
59static void SkXmInitPhyXmac(SK_AC*, SK_IOC, int, SK_BOOL);
60static void SkXmInitPhyBcom(SK_AC*, SK_IOC, int, SK_BOOL);
61static int SkXmAutoNegDoneXmac(SK_AC*, SK_IOC, int);
62static int SkXmAutoNegDoneBcom(SK_AC*, SK_IOC, int);
63#endif /* GENESIS */
64#ifdef YUKON
65static void SkGmInitPhyMarv(SK_AC*, SK_IOC, int, SK_BOOL);
66static int SkGmAutoNegDoneMarv(SK_AC*, SK_IOC, int);
67#endif /* YUKON */
68#ifdef OTHER_PHY
69static void SkXmInitPhyLone(SK_AC*, SK_IOC, int, SK_BOOL);
70static void SkXmInitPhyNat (SK_AC*, SK_IOC, int, SK_BOOL);
71static int SkXmAutoNegDoneLone(SK_AC*, SK_IOC, int);
72static int SkXmAutoNegDoneNat (SK_AC*, SK_IOC, int);
73#endif /* OTHER_PHY */
74
75
76#ifdef GENESIS
77/******************************************************************************
78 *
79 * SkXmPhyRead() - Read from XMAC PHY register
80 *
81 * Description: reads a 16-bit word from XMAC PHY or ext. PHY
82 *
83 * Returns:
84 * nothing
85 */
86void SkXmPhyRead(
87SK_AC *pAC, /* Adapter Context */
88SK_IOC IoC, /* I/O Context */
89int Port, /* Port Index (MAC_1 + n) */
90int PhyReg, /* Register Address (Offset) */
91SK_U16 SK_FAR *pVal) /* Pointer to Value */
92{
93 SK_U16 Mmu;
94 SK_GEPORT *pPrt;
95
96 pPrt = &pAC->GIni.GP[Port];
97
98 /* write the PHY register's address */
99 XM_OUT16(IoC, Port, XM_PHY_ADDR, PhyReg | pPrt->PhyAddr);
100
101 /* get the PHY register's value */
102 XM_IN16(IoC, Port, XM_PHY_DATA, pVal);
103
104 if (pPrt->PhyType != SK_PHY_XMAC) {
105 do {
106 XM_IN16(IoC, Port, XM_MMU_CMD, &Mmu);
107 /* wait until 'Ready' is set */
108 } while ((Mmu & XM_MMU_PHY_RDY) == 0);
109
110 /* get the PHY register's value */
111 XM_IN16(IoC, Port, XM_PHY_DATA, pVal);
112 }
113} /* SkXmPhyRead */
114
115
116/******************************************************************************
117 *
118 * SkXmPhyWrite() - Write to XMAC PHY register
119 *
120 * Description: writes a 16-bit word to XMAC PHY or ext. PHY
121 *
122 * Returns:
123 * nothing
124 */
125void SkXmPhyWrite(
126SK_AC *pAC, /* Adapter Context */
127SK_IOC IoC, /* I/O Context */
128int Port, /* Port Index (MAC_1 + n) */
129int PhyReg, /* Register Address (Offset) */
130SK_U16 Val) /* Value */
131{
132 SK_U16 Mmu;
133 SK_GEPORT *pPrt;
134
135 pPrt = &pAC->GIni.GP[Port];
136
137 if (pPrt->PhyType != SK_PHY_XMAC) {
138 do {
139 XM_IN16(IoC, Port, XM_MMU_CMD, &Mmu);
140 /* wait until 'Busy' is cleared */
141 } while ((Mmu & XM_MMU_PHY_BUSY) != 0);
142 }
143
144 /* write the PHY register's address */
145 XM_OUT16(IoC, Port, XM_PHY_ADDR, PhyReg | pPrt->PhyAddr);
146
147 /* write the PHY register's value */
148 XM_OUT16(IoC, Port, XM_PHY_DATA, Val);
149
150 if (pPrt->PhyType != SK_PHY_XMAC) {
151 do {
152 XM_IN16(IoC, Port, XM_MMU_CMD, &Mmu);
153 /* wait until 'Busy' is cleared */
154 } while ((Mmu & XM_MMU_PHY_BUSY) != 0);
155 }
156} /* SkXmPhyWrite */
157#endif /* GENESIS */
158
159
160#ifdef YUKON
161/******************************************************************************
162 *
163 * SkGmPhyRead() - Read from GPHY register
164 *
165 * Description: reads a 16-bit word from GPHY through MDIO
166 *
167 * Returns:
168 * nothing
169 */
170void SkGmPhyRead(
171SK_AC *pAC, /* Adapter Context */
172SK_IOC IoC, /* I/O Context */
173int Port, /* Port Index (MAC_1 + n) */
174int PhyReg, /* Register Address (Offset) */
175SK_U16 SK_FAR *pVal) /* Pointer to Value */
176{
177 SK_U16 Ctrl;
178 SK_GEPORT *pPrt;
179#ifdef VCPU
180 u_long SimCyle;
181 u_long SimLowTime;
182
183 VCPUgetTime(&SimCyle, &SimLowTime);
184 VCPUprintf(0, "SkGmPhyRead(%u), SimCyle=%u, SimLowTime=%u\n",
185 PhyReg, SimCyle, SimLowTime);
186#endif /* VCPU */
187
188 pPrt = &pAC->GIni.GP[Port];
189
190 /* set PHY-Register offset and 'Read' OpCode (= 1) */
191 *pVal = (SK_U16)(GM_SMI_CT_PHY_AD(pPrt->PhyAddr) |
192 GM_SMI_CT_REG_AD(PhyReg) | GM_SMI_CT_OP_RD);
193
194 GM_OUT16(IoC, Port, GM_SMI_CTRL, *pVal);
195
196 GM_IN16(IoC, Port, GM_SMI_CTRL, &Ctrl);
197
198 /* additional check for MDC/MDIO activity */
199 if ((Ctrl & GM_SMI_CT_BUSY) == 0) {
200 *pVal = 0;
201 return;
202 }
203
204 *pVal |= GM_SMI_CT_BUSY;
205
206 do {
207#ifdef VCPU
208 VCPUwaitTime(1000);
209#endif /* VCPU */
210
211 GM_IN16(IoC, Port, GM_SMI_CTRL, &Ctrl);
212
213 /* wait until 'ReadValid' is set */
214 } while (Ctrl == *pVal);
215
216 /* get the PHY register's value */
217 GM_IN16(IoC, Port, GM_SMI_DATA, pVal);
218
219#ifdef VCPU
220 VCPUgetTime(&SimCyle, &SimLowTime);
221 VCPUprintf(0, "VCPUgetTime(), SimCyle=%u, SimLowTime=%u\n",
222 SimCyle, SimLowTime);
223#endif /* VCPU */
224
225} /* SkGmPhyRead */
226
227
228/******************************************************************************
229 *
230 * SkGmPhyWrite() - Write to GPHY register
231 *
232 * Description: writes a 16-bit word to GPHY through MDIO
233 *
234 * Returns:
235 * nothing
236 */
237void SkGmPhyWrite(
238SK_AC *pAC, /* Adapter Context */
239SK_IOC IoC, /* I/O Context */
240int Port, /* Port Index (MAC_1 + n) */
241int PhyReg, /* Register Address (Offset) */
242SK_U16 Val) /* Value */
243{
244 SK_U16 Ctrl;
245 SK_GEPORT *pPrt;
246#ifdef VCPU
247 SK_U32 DWord;
248 u_long SimCyle;
249 u_long SimLowTime;
250
251 VCPUgetTime(&SimCyle, &SimLowTime);
252 VCPUprintf(0, "SkGmPhyWrite(Reg=%u, Val=0x%04x), SimCyle=%u, SimLowTime=%u\n",
253 PhyReg, Val, SimCyle, SimLowTime);
254#endif /* VCPU */
255
256 pPrt = &pAC->GIni.GP[Port];
257
258 /* write the PHY register's value */
259 GM_OUT16(IoC, Port, GM_SMI_DATA, Val);
260
261 /* set PHY-Register offset and 'Write' OpCode (= 0) */
262 Val = GM_SMI_CT_PHY_AD(pPrt->PhyAddr) | GM_SMI_CT_REG_AD(PhyReg);
263
264 GM_OUT16(IoC, Port, GM_SMI_CTRL, Val);
265
266 GM_IN16(IoC, Port, GM_SMI_CTRL, &Ctrl);
267
268 /* additional check for MDC/MDIO activity */
269 if ((Ctrl & GM_SMI_CT_BUSY) == 0) {
270 return;
271 }
272
273 Val |= GM_SMI_CT_BUSY;
274
275 do {
276#ifdef VCPU
277 /* read Timer value */
278 SK_IN32(IoC, B2_TI_VAL, &DWord);
279
280 VCPUwaitTime(1000);
281#endif /* VCPU */
282
283 GM_IN16(IoC, Port, GM_SMI_CTRL, &Ctrl);
284
285 /* wait until 'Busy' is cleared */
286 } while (Ctrl == Val);
287
288#ifdef VCPU
289 VCPUgetTime(&SimCyle, &SimLowTime);
290 VCPUprintf(0, "VCPUgetTime(), SimCyle=%u, SimLowTime=%u\n",
291 SimCyle, SimLowTime);
292#endif /* VCPU */
293
294} /* SkGmPhyWrite */
295#endif /* YUKON */
296
297
298#ifdef SK_DIAG
299/******************************************************************************
300 *
301 * SkGePhyRead() - Read from PHY register
302 *
303 * Description: calls a read PHY routine dep. on board type
304 *
305 * Returns:
306 * nothing
307 */
308void SkGePhyRead(
309SK_AC *pAC, /* Adapter Context */
310SK_IOC IoC, /* I/O Context */
311int Port, /* Port Index (MAC_1 + n) */
312int PhyReg, /* Register Address (Offset) */
313SK_U16 *pVal) /* Pointer to Value */
314{
315 void (*r_func)(SK_AC *pAC, SK_IOC IoC, int Port, int Reg, SK_U16 *pVal);
316
317 if (pAC->GIni.GIGenesis) {
318 r_func = SkXmPhyRead;
319 }
320 else {
321 r_func = SkGmPhyRead;
322 }
323
324 r_func(pAC, IoC, Port, PhyReg, pVal);
325} /* SkGePhyRead */
326
327
328/******************************************************************************
329 *
330 * SkGePhyWrite() - Write to PHY register
331 *
332 * Description: calls a write PHY routine dep. on board type
333 *
334 * Returns:
335 * nothing
336 */
337void SkGePhyWrite(
338SK_AC *pAC, /* Adapter Context */
339SK_IOC IoC, /* I/O Context */
340int Port, /* Port Index (MAC_1 + n) */
341int PhyReg, /* Register Address (Offset) */
342SK_U16 Val) /* Value */
343{
344 void (*w_func)(SK_AC *pAC, SK_IOC IoC, int Port, int Reg, SK_U16 Val);
345
346 if (pAC->GIni.GIGenesis) {
347 w_func = SkXmPhyWrite;
348 }
349 else {
350 w_func = SkGmPhyWrite;
351 }
352
353 w_func(pAC, IoC, Port, PhyReg, Val);
354} /* SkGePhyWrite */
355#endif /* SK_DIAG */
356
357
358/******************************************************************************
359 *
360 * SkMacPromiscMode() - Enable / Disable Promiscuous Mode
361 *
362 * Description:
363 * enables / disables promiscuous mode by setting Mode Register (XMAC) or
364 * Receive Control Register (GMAC) dep. on board type
365 *
366 * Returns:
367 * nothing
368 */
369void SkMacPromiscMode(
370SK_AC *pAC, /* adapter context */
371SK_IOC IoC, /* IO context */
372int Port, /* Port Index (MAC_1 + n) */
373SK_BOOL Enable) /* Enable / Disable */
374{
375#ifdef YUKON
376 SK_U16 RcReg;
377#endif
378#ifdef GENESIS
379 SK_U32 MdReg;
380#endif
381
382#ifdef GENESIS
383 if (pAC->GIni.GIGenesis) {
384
385 XM_IN32(IoC, Port, XM_MODE, &MdReg);
386 /* enable or disable promiscuous mode */
387 if (Enable) {
388 MdReg |= XM_MD_ENA_PROM;
389 }
390 else {
391 MdReg &= ~XM_MD_ENA_PROM;
392 }
393 /* setup Mode Register */
394 XM_OUT32(IoC, Port, XM_MODE, MdReg);
395 }
396#endif /* GENESIS */
397
398#ifdef YUKON
399 if (pAC->GIni.GIYukon) {
400
401 GM_IN16(IoC, Port, GM_RX_CTRL, &RcReg);
402
403 /* enable or disable unicast and multicast filtering */
404 if (Enable) {
405 RcReg &= ~(GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA);
406 }
407 else {
408 RcReg |= (GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA);
409 }
410 /* setup Receive Control Register */
411 GM_OUT16(IoC, Port, GM_RX_CTRL, RcReg);
412 }
413#endif /* YUKON */
414
415} /* SkMacPromiscMode*/
416
417
418/******************************************************************************
419 *
420 * SkMacHashing() - Enable / Disable Hashing
421 *
422 * Description:
423 * enables / disables hashing by setting Mode Register (XMAC) or
424 * Receive Control Register (GMAC) dep. on board type
425 *
426 * Returns:
427 * nothing
428 */
429void SkMacHashing(
430SK_AC *pAC, /* adapter context */
431SK_IOC IoC, /* IO context */
432int Port, /* Port Index (MAC_1 + n) */
433SK_BOOL Enable) /* Enable / Disable */
434{
435#ifdef YUKON
436 SK_U16 RcReg;
437#endif
438#ifdef GENESIS
439 SK_U32 MdReg;
440#endif
441
442#ifdef GENESIS
443 if (pAC->GIni.GIGenesis) {
444
445 XM_IN32(IoC, Port, XM_MODE, &MdReg);
446 /* enable or disable hashing */
447 if (Enable) {
448 MdReg |= XM_MD_ENA_HASH;
449 }
450 else {
451 MdReg &= ~XM_MD_ENA_HASH;
452 }
453 /* setup Mode Register */
454 XM_OUT32(IoC, Port, XM_MODE, MdReg);
455 }
456#endif /* GENESIS */
457
458#ifdef YUKON
459 if (pAC->GIni.GIYukon) {
460
461 GM_IN16(IoC, Port, GM_RX_CTRL, &RcReg);
462
463 /* enable or disable multicast filtering */
464 if (Enable) {
465 RcReg |= GM_RXCR_MCF_ENA;
466 }
467 else {
468 RcReg &= ~GM_RXCR_MCF_ENA;
469 }
470 /* setup Receive Control Register */
471 GM_OUT16(IoC, Port, GM_RX_CTRL, RcReg);
472 }
473#endif /* YUKON */
474
475} /* SkMacHashing*/
476
477
478#ifdef SK_DIAG
479/******************************************************************************
480 *
481 * SkXmSetRxCmd() - Modify the value of the XMAC's Rx Command Register
482 *
483 * Description:
484 * The features
485 * - FCS stripping, SK_STRIP_FCS_ON/OFF
486 * - pad byte stripping, SK_STRIP_PAD_ON/OFF
487 * - don't set XMR_FS_ERR in status SK_LENERR_OK_ON/OFF
488 * for inrange length error frames
489 * - don't set XMR_FS_ERR in status SK_BIG_PK_OK_ON/OFF
490 * for frames > 1514 bytes
491 * - enable Rx of own packets SK_SELF_RX_ON/OFF
492 *
493 * for incoming packets may be enabled/disabled by this function.
494 * Additional modes may be added later.
495 * Multiple modes can be enabled/disabled at the same time.
496 * The new configuration is written to the Rx Command register immediately.
497 *
498 * Returns:
499 * nothing
500 */
501static void SkXmSetRxCmd(
502SK_AC *pAC, /* adapter context */
503SK_IOC IoC, /* IO context */
504int Port, /* Port Index (MAC_1 + n) */
505int Mode) /* Mode is SK_STRIP_FCS_ON/OFF, SK_STRIP_PAD_ON/OFF,
506 SK_LENERR_OK_ON/OFF, or SK_BIG_PK_OK_ON/OFF */
507{
508 SK_U16 OldRxCmd;
509 SK_U16 RxCmd;
510
511 XM_IN16(IoC, Port, XM_RX_CMD, &OldRxCmd);
512
513 RxCmd = OldRxCmd;
514
515 switch (Mode & (SK_STRIP_FCS_ON | SK_STRIP_FCS_OFF)) {
516 case SK_STRIP_FCS_ON:
517 RxCmd |= XM_RX_STRIP_FCS;
518 break;
519 case SK_STRIP_FCS_OFF:
520 RxCmd &= ~XM_RX_STRIP_FCS;
521 break;
522 }
523
524 switch (Mode & (SK_STRIP_PAD_ON | SK_STRIP_PAD_OFF)) {
525 case SK_STRIP_PAD_ON:
526 RxCmd |= XM_RX_STRIP_PAD;
527 break;
528 case SK_STRIP_PAD_OFF:
529 RxCmd &= ~XM_RX_STRIP_PAD;
530 break;
531 }
532
533 switch (Mode & (SK_LENERR_OK_ON | SK_LENERR_OK_OFF)) {
534 case SK_LENERR_OK_ON:
535 RxCmd |= XM_RX_LENERR_OK;
536 break;
537 case SK_LENERR_OK_OFF:
538 RxCmd &= ~XM_RX_LENERR_OK;
539 break;
540 }
541
542 switch (Mode & (SK_BIG_PK_OK_ON | SK_BIG_PK_OK_OFF)) {
543 case SK_BIG_PK_OK_ON:
544 RxCmd |= XM_RX_BIG_PK_OK;
545 break;
546 case SK_BIG_PK_OK_OFF:
547 RxCmd &= ~XM_RX_BIG_PK_OK;
548 break;
549 }
550
551 switch (Mode & (SK_SELF_RX_ON | SK_SELF_RX_OFF)) {
552 case SK_SELF_RX_ON:
553 RxCmd |= XM_RX_SELF_RX;
554 break;
555 case SK_SELF_RX_OFF:
556 RxCmd &= ~XM_RX_SELF_RX;
557 break;
558 }
559
560 /* Write the new mode to the Rx command register if required */
561 if (OldRxCmd != RxCmd) {
562 XM_OUT16(IoC, Port, XM_RX_CMD, RxCmd);
563 }
564} /* SkXmSetRxCmd */
565
566
567/******************************************************************************
568 *
569 * SkGmSetRxCmd() - Modify the value of the GMAC's Rx Control Register
570 *
571 * Description:
572 * The features
573 * - FCS (CRC) stripping, SK_STRIP_FCS_ON/OFF
574 * - don't set GMR_FS_LONG_ERR SK_BIG_PK_OK_ON/OFF
575 * for frames > 1514 bytes
576 * - enable Rx of own packets SK_SELF_RX_ON/OFF
577 *
578 * for incoming packets may be enabled/disabled by this function.
579 * Additional modes may be added later.
580 * Multiple modes can be enabled/disabled at the same time.
581 * The new configuration is written to the Rx Command register immediately.
582 *
583 * Returns:
584 * nothing
585 */
586static void SkGmSetRxCmd(
587SK_AC *pAC, /* adapter context */
588SK_IOC IoC, /* IO context */
589int Port, /* Port Index (MAC_1 + n) */
590int Mode) /* Mode is SK_STRIP_FCS_ON/OFF, SK_STRIP_PAD_ON/OFF,
591 SK_LENERR_OK_ON/OFF, or SK_BIG_PK_OK_ON/OFF */
592{
593 SK_U16 OldRxCmd;
594 SK_U16 RxCmd;
595
596 if ((Mode & (SK_STRIP_FCS_ON | SK_STRIP_FCS_OFF)) != 0) {
597
598 GM_IN16(IoC, Port, GM_RX_CTRL, &OldRxCmd);
599
600 RxCmd = OldRxCmd;
601
602 if ((Mode & SK_STRIP_FCS_ON) != 0) {
603 RxCmd |= GM_RXCR_CRC_DIS;
604 }
605 else {
606 RxCmd &= ~GM_RXCR_CRC_DIS;
607 }
608 /* Write the new mode to the Rx control register if required */
609 if (OldRxCmd != RxCmd) {
610 GM_OUT16(IoC, Port, GM_RX_CTRL, RxCmd);
611 }
612 }
613
614 if ((Mode & (SK_BIG_PK_OK_ON | SK_BIG_PK_OK_OFF)) != 0) {
615
616 GM_IN16(IoC, Port, GM_SERIAL_MODE, &OldRxCmd);
617
618 RxCmd = OldRxCmd;
619
620 if ((Mode & SK_BIG_PK_OK_ON) != 0) {
621 RxCmd |= GM_SMOD_JUMBO_ENA;
622 }
623 else {
624 RxCmd &= ~GM_SMOD_JUMBO_ENA;
625 }
626 /* Write the new mode to the Rx control register if required */
627 if (OldRxCmd != RxCmd) {
628 GM_OUT16(IoC, Port, GM_SERIAL_MODE, RxCmd);
629 }
630 }
631} /* SkGmSetRxCmd */
632
633
634/******************************************************************************
635 *
636 * SkMacSetRxCmd() - Modify the value of the MAC's Rx Control Register
637 *
638 * Description: modifies the MAC's Rx Control reg. dep. on board type
639 *
640 * Returns:
641 * nothing
642 */
643void SkMacSetRxCmd(
644SK_AC *pAC, /* adapter context */
645SK_IOC IoC, /* IO context */
646int Port, /* Port Index (MAC_1 + n) */
647int Mode) /* Rx Mode */
648{
649 if (pAC->GIni.GIGenesis) {
650
651 SkXmSetRxCmd(pAC, IoC, Port, Mode);
652 }
653 else {
654
655 SkGmSetRxCmd(pAC, IoC, Port, Mode);
656 }
657
658} /* SkMacSetRxCmd */
659
660
661/******************************************************************************
662 *
663 * SkMacCrcGener() - Enable / Disable CRC Generation
664 *
665 * Description: enables / disables CRC generation dep. on board type
666 *
667 * Returns:
668 * nothing
669 */
670void SkMacCrcGener(
671SK_AC *pAC, /* adapter context */
672SK_IOC IoC, /* IO context */
673int Port, /* Port Index (MAC_1 + n) */
674SK_BOOL Enable) /* Enable / Disable */
675{
676 SK_U16 Word;
677
678 if (pAC->GIni.GIGenesis) {
679
680 XM_IN16(IoC, Port, XM_TX_CMD, &Word);
681
682 if (Enable) {
683 Word &= ~XM_TX_NO_CRC;
684 }
685 else {
686 Word |= XM_TX_NO_CRC;
687 }
688 /* setup Tx Command Register */
689 XM_OUT16(IoC, Port, XM_TX_CMD, Word);
690 }
691 else {
692
693 GM_IN16(IoC, Port, GM_TX_CTRL, &Word);
694
695 if (Enable) {
696 Word &= ~GM_TXCR_CRC_DIS;
697 }
698 else {
699 Word |= GM_TXCR_CRC_DIS;
700 }
701 /* setup Tx Control Register */
702 GM_OUT16(IoC, Port, GM_TX_CTRL, Word);
703 }
704
705} /* SkMacCrcGener*/
706
707#endif /* SK_DIAG */
708
709
710#ifdef GENESIS
711/******************************************************************************
712 *
713 * SkXmClrExactAddr() - Clear Exact Match Address Registers
714 *
715 * Description:
716 * All Exact Match Address registers of the XMAC 'Port' will be
717 * cleared starting with 'StartNum' up to (and including) the
718 * Exact Match address number of 'StopNum'.
719 *
720 * Returns:
721 * nothing
722 */
723void SkXmClrExactAddr(
724SK_AC *pAC, /* adapter context */
725SK_IOC IoC, /* IO context */
726int Port, /* Port Index (MAC_1 + n) */
727int StartNum, /* Begin with this Address Register Index (0..15) */
728int StopNum) /* Stop after finished with this Register Idx (0..15) */
729{
730 int i;
731 SK_U16 ZeroAddr[3] = {0x0000, 0x0000, 0x0000};
732
733 if ((unsigned)StartNum > 15 || (unsigned)StopNum > 15 ||
734 StartNum > StopNum) {
735
736 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E001, SKERR_HWI_E001MSG);
737 return;
738 }
739
740 for (i = StartNum; i <= StopNum; i++) {
741 XM_OUTADDR(IoC, Port, XM_EXM(i), &ZeroAddr[0]);
742 }
743} /* SkXmClrExactAddr */
744#endif /* GENESIS */
745
746
747/******************************************************************************
748 *
749 * SkMacFlushTxFifo() - Flush the MAC's transmit FIFO
750 *
751 * Description:
752 * Flush the transmit FIFO of the MAC specified by the index 'Port'
753 *
754 * Returns:
755 * nothing
756 */
757void SkMacFlushTxFifo(
758SK_AC *pAC, /* adapter context */
759SK_IOC IoC, /* IO context */
760int Port) /* Port Index (MAC_1 + n) */
761{
762#ifdef GENESIS
763 SK_U32 MdReg;
764
765 if (pAC->GIni.GIGenesis) {
766
767 XM_IN32(IoC, Port, XM_MODE, &MdReg);
768
769 XM_OUT32(IoC, Port, XM_MODE, MdReg | XM_MD_FTF);
770 }
771#endif /* GENESIS */
772
773#ifdef YUKON
774 if (pAC->GIni.GIYukon) {
775 /* no way to flush the FIFO we have to issue a reset */
776 /* TBD */
777 }
778#endif /* YUKON */
779
780} /* SkMacFlushTxFifo */
781
782
783/******************************************************************************
784 *
785 * SkMacFlushRxFifo() - Flush the MAC's receive FIFO
786 *
787 * Description:
788 * Flush the receive FIFO of the MAC specified by the index 'Port'
789 *
790 * Returns:
791 * nothing
792 */
793static void SkMacFlushRxFifo(
794SK_AC *pAC, /* adapter context */
795SK_IOC IoC, /* IO context */
796int Port) /* Port Index (MAC_1 + n) */
797{
798#ifdef GENESIS
799 SK_U32 MdReg;
800
801 if (pAC->GIni.GIGenesis) {
802
803 XM_IN32(IoC, Port, XM_MODE, &MdReg);
804
805 XM_OUT32(IoC, Port, XM_MODE, MdReg | XM_MD_FRF);
806 }
807#endif /* GENESIS */
808
809#ifdef YUKON
810 if (pAC->GIni.GIYukon) {
811 /* no way to flush the FIFO we have to issue a reset */
812 /* TBD */
813 }
814#endif /* YUKON */
815
816} /* SkMacFlushRxFifo */
817
818
819#ifdef GENESIS
820/******************************************************************************
821 *
822 * SkXmSoftRst() - Do a XMAC software reset
823 *
824 * Description:
825 * The PHY registers should not be destroyed during this
826 * kind of software reset. Therefore the XMAC Software Reset
827 * (XM_GP_RES_MAC bit in XM_GP_PORT) must not be used!
828 *
829 * The software reset is done by
830 * - disabling the Rx and Tx state machine,
831 * - resetting the statistics module,
832 * - clear all other significant XMAC Mode,
833 * Command, and Control Registers
834 * - clearing the Hash Register and the
835 * Exact Match Address registers, and
836 * - flushing the XMAC's Rx and Tx FIFOs.
837 *
838 * Note:
839 * Another requirement when stopping the XMAC is to
840 * avoid sending corrupted frames on the network.
841 * Disabling the Tx state machine will NOT interrupt
842 * the currently transmitted frame. But we must take care
843 * that the Tx FIFO is cleared AFTER the current frame
844 * is complete sent to the network.
845 *
846 * It takes about 12ns to send a frame with 1538 bytes.
847 * One PCI clock goes at least 15ns (66MHz). Therefore
848 * after reading XM_GP_PORT back, we are sure that the
849 * transmitter is disabled AND idle. And this means
850 * we may flush the transmit FIFO now.
851 *
852 * Returns:
853 * nothing
854 */
855static void SkXmSoftRst(
856SK_AC *pAC, /* adapter context */
857SK_IOC IoC, /* IO context */
858int Port) /* Port Index (MAC_1 + n) */
859{
860 SK_U16 ZeroAddr[4] = {0x0000, 0x0000, 0x0000, 0x0000};
861
862 /* reset the statistics module */
863 XM_OUT32(IoC, Port, XM_GP_PORT, XM_GP_RES_STAT);
864
865 /* disable all XMAC IRQs */
866 XM_OUT16(IoC, Port, XM_IMSK, 0xffff);
867
868 XM_OUT32(IoC, Port, XM_MODE, 0); /* clear Mode Reg */
869
870 XM_OUT16(IoC, Port, XM_TX_CMD, 0); /* reset TX CMD Reg */
871 XM_OUT16(IoC, Port, XM_RX_CMD, 0); /* reset RX CMD Reg */
872
873 /* disable all PHY IRQs */
874 switch (pAC->GIni.GP[Port].PhyType) {
875 case SK_PHY_BCOM:
876 SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_INT_MASK, 0xffff);
877 break;
878#ifdef OTHER_PHY
879 case SK_PHY_LONE:
880 SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_INT_ENAB, 0);
881 break;
882 case SK_PHY_NAT:
883 /* todo: National
884 SkXmPhyWrite(pAC, IoC, Port, PHY_NAT_INT_MASK, 0xffff); */
885 break;
886#endif /* OTHER_PHY */
887 }
888
889 /* clear the Hash Register */
890 XM_OUTHASH(IoC, Port, XM_HSM, &ZeroAddr);
891
892 /* clear the Exact Match Address registers */
893 SkXmClrExactAddr(pAC, IoC, Port, 0, 15);
894
895 /* clear the Source Check Address registers */
896 XM_OUTHASH(IoC, Port, XM_SRC_CHK, &ZeroAddr);
897
898} /* SkXmSoftRst */
899
900
901/******************************************************************************
902 *
903 * SkXmHardRst() - Do a XMAC hardware reset
904 *
905 * Description:
906 * The XMAC of the specified 'Port' and all connected devices
907 * (PHY and SERDES) will receive a reset signal on its *Reset pins.
908 * External PHYs must be reset by clearing a bit in the GPIO register
909 * (Timing requirements: Broadcom: 400ns, Level One: none, National: 80ns).
910 *
911 * ATTENTION:
912 * It is absolutely necessary to reset the SW_RST Bit first
913 * before calling this function.
914 *
915 * Returns:
916 * nothing
917 */
918static void SkXmHardRst(
919SK_AC *pAC, /* adapter context */
920SK_IOC IoC, /* IO context */
921int Port) /* Port Index (MAC_1 + n) */
922{
923 SK_U32 Reg;
924 int i;
925 int TOut;
926 SK_U16 Word;
927
928 for (i = 0; i < 4; i++) {
929 /* TX_MFF_CTRL1 has 32 bits, but only the lowest 16 bits are used */
930 SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_CLR_MAC_RST);
931
932 TOut = 0;
933 do {
934 if (TOut++ > 10000) {
935 /*
936 * Adapter seems to be in RESET state.
937 * Registers cannot be written.
938 */
939 return;
940 }
941
942 SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_SET_MAC_RST);
943
944 SK_IN16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), &Word);
945
946 } while ((Word & MFF_SET_MAC_RST) == 0);
947 }
948
949 /* For external PHYs there must be special handling */
950 if (pAC->GIni.GP[Port].PhyType != SK_PHY_XMAC) {
951
952 SK_IN32(IoC, B2_GP_IO, &Reg);
953
954 if (Port == 0) {
955 Reg |= GP_DIR_0; /* set to output */
956 Reg &= ~GP_IO_0; /* set PHY reset (active low) */
957 }
958 else {
959 Reg |= GP_DIR_2; /* set to output */
960 Reg &= ~GP_IO_2; /* set PHY reset (active low) */
961 }
962 /* reset external PHY */
963 SK_OUT32(IoC, B2_GP_IO, Reg);
964
965 /* short delay */
966 SK_IN32(IoC, B2_GP_IO, &Reg);
967 }
968} /* SkXmHardRst */
969
970
971/******************************************************************************
972 *
973 * SkXmClearRst() - Release the PHY & XMAC reset
974 *
975 * Description:
976 *
977 * Returns:
978 * nothing
979 */
980static void SkXmClearRst(
981SK_AC *pAC, /* adapter context */
982SK_IOC IoC, /* IO context */
983int Port) /* Port Index (MAC_1 + n) */
984{
985 SK_U32 DWord;
986
987 /* clear HW reset */
988 SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_CLR_MAC_RST);
989
990 if (pAC->GIni.GP[Port].PhyType != SK_PHY_XMAC) {
991
992 SK_IN32(IoC, B2_GP_IO, &DWord);
993
994 if (Port == 0) {
995 DWord |= (GP_DIR_0 | GP_IO_0); /* set to output */
996 }
997 else {
998 DWord |= (GP_DIR_2 | GP_IO_2); /* set to output */
999 }
1000 /* Clear PHY reset */
1001 SK_OUT32(IoC, B2_GP_IO, DWord);
1002
1003 /* Enable GMII interface */
1004 XM_OUT16(IoC, Port, XM_HW_CFG, XM_HW_GMII_MD);
1005 }
1006} /* SkXmClearRst */
1007#endif /* GENESIS */
1008
1009
1010#ifdef YUKON
1011/******************************************************************************
1012 *
1013 * SkGmSoftRst() - Do a GMAC software reset
1014 *
1015 * Description:
1016 * The GPHY registers should not be destroyed during this
1017 * kind of software reset.
1018 *
1019 * Returns:
1020 * nothing
1021 */
1022static void SkGmSoftRst(
1023SK_AC *pAC, /* adapter context */
1024SK_IOC IoC, /* IO context */
1025int Port) /* Port Index (MAC_1 + n) */
1026{
1027 SK_U16 EmptyHash[4] = {0x0000, 0x0000, 0x0000, 0x0000};
1028 SK_U16 RxCtrl;
1029
1030 /* reset the statistics module */
1031
1032 /* disable all GMAC IRQs */
1033 SK_OUT8(IoC, GMAC_IRQ_MSK, 0);
1034
1035 /* disable all PHY IRQs */
1036 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_INT_MASK, 0);
1037
1038 /* clear the Hash Register */
1039 GM_OUTHASH(IoC, Port, GM_MC_ADDR_H1, EmptyHash);
1040
1041 /* Enable Unicast and Multicast filtering */
1042 GM_IN16(IoC, Port, GM_RX_CTRL, &RxCtrl);
1043
1044 GM_OUT16(IoC, Port, GM_RX_CTRL,
1045 (SK_U16)(RxCtrl | GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA));
1046
1047} /* SkGmSoftRst */
1048
1049
1050/******************************************************************************
1051 *
1052 * SkGmHardRst() - Do a GMAC hardware reset
1053 *
1054 * Description:
1055 *
1056 * Returns:
1057 * nothing
1058 */
1059static void SkGmHardRst(
1060SK_AC *pAC, /* adapter context */
1061SK_IOC IoC, /* IO context */
1062int Port) /* Port Index (MAC_1 + n) */
1063{
1064 SK_U32 DWord;
1065
1066 /* WA code for COMA mode */
1067 if (pAC->GIni.GIYukonLite &&
1068 pAC->GIni.GIChipRev >= CHIP_REV_YU_LITE_A3) {
1069
1070 SK_IN32(IoC, B2_GP_IO, &DWord);
1071
1072 DWord |= (GP_DIR_9 | GP_IO_9);
1073
1074 /* set PHY reset */
1075 SK_OUT32(IoC, B2_GP_IO, DWord);
1076 }
1077
1078 /* set GPHY Control reset */
1079 SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), GPC_RST_SET);
1080
1081 /* set GMAC Control reset */
1082 SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_SET);
1083
1084} /* SkGmHardRst */
1085
1086
1087/******************************************************************************
1088 *
1089 * SkGmClearRst() - Release the GPHY & GMAC reset
1090 *
1091 * Description:
1092 *
1093 * Returns:
1094 * nothing
1095 */
1096static void SkGmClearRst(
1097SK_AC *pAC, /* adapter context */
1098SK_IOC IoC, /* IO context */
1099int Port) /* Port Index (MAC_1 + n) */
1100{
1101 SK_U32 DWord;
1102
1103#ifdef XXX
1104 /* clear GMAC Control reset */
1105 SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_CLR);
1106
1107 /* set GMAC Control reset */
1108 SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_SET);
1109#endif /* XXX */
1110
1111 /* WA code for COMA mode */
1112 if (pAC->GIni.GIYukonLite &&
1113 pAC->GIni.GIChipRev >= CHIP_REV_YU_LITE_A3) {
1114
1115 SK_IN32(IoC, B2_GP_IO, &DWord);
1116
1117 DWord |= GP_DIR_9; /* set to output */
1118 DWord &= ~GP_IO_9; /* clear PHY reset (active high) */
1119
1120 /* clear PHY reset */
1121 SK_OUT32(IoC, B2_GP_IO, DWord);
1122 }
1123
1124 /* set HWCFG_MODE */
1125 DWord = GPC_INT_POL_HI | GPC_DIS_FC | GPC_DIS_SLEEP |
1126 GPC_ENA_XC | GPC_ANEG_ADV_ALL_M | GPC_ENA_PAUSE |
1127 (pAC->GIni.GICopperType ? GPC_HWCFG_GMII_COP :
1128 GPC_HWCFG_GMII_FIB);
1129
1130 /* set GPHY Control reset */
1131 SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), DWord | GPC_RST_SET);
1132
1133 /* release GPHY Control reset */
1134 SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), DWord | GPC_RST_CLR);
1135
1136#ifdef VCPU
1137 VCpuWait(9000);
1138#endif /* VCPU */
1139
1140 /* clear GMAC Control reset */
1141 SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_PAUSE_ON | GMC_RST_CLR);
1142
1143#ifdef VCPU
1144 VCpuWait(2000);
1145
1146 SK_IN32(IoC, MR_ADDR(Port, GPHY_CTRL), &DWord);
1147
1148 SK_IN32(IoC, B0_ISRC, &DWord);
1149#endif /* VCPU */
1150
1151} /* SkGmClearRst */
1152#endif /* YUKON */
1153
1154
1155/******************************************************************************
1156 *
1157 * SkMacSoftRst() - Do a MAC software reset
1158 *
1159 * Description: calls a MAC software reset routine dep. on board type
1160 *
1161 * Returns:
1162 * nothing
1163 */
1164void SkMacSoftRst(
1165SK_AC *pAC, /* adapter context */
1166SK_IOC IoC, /* IO context */
1167int Port) /* Port Index (MAC_1 + n) */
1168{
1169 SK_GEPORT *pPrt;
1170
1171 pPrt = &pAC->GIni.GP[Port];
1172
1173 /* disable receiver and transmitter */
1174 SkMacRxTxDisable(pAC, IoC, Port);
1175
1176#ifdef GENESIS
1177 if (pAC->GIni.GIGenesis) {
1178
1179 SkXmSoftRst(pAC, IoC, Port);
1180 }
1181#endif /* GENESIS */
1182
1183#ifdef YUKON
1184 if (pAC->GIni.GIYukon) {
1185
1186 SkGmSoftRst(pAC, IoC, Port);
1187 }
1188#endif /* YUKON */
1189
1190 /* flush the MAC's Rx and Tx FIFOs */
1191 SkMacFlushTxFifo(pAC, IoC, Port);
1192
1193 SkMacFlushRxFifo(pAC, IoC, Port);
1194
1195 pPrt->PState = SK_PRT_STOP;
1196
1197} /* SkMacSoftRst */
1198
1199
1200/******************************************************************************
1201 *
1202 * SkMacHardRst() - Do a MAC hardware reset
1203 *
1204 * Description: calls a MAC hardware reset routine dep. on board type
1205 *
1206 * Returns:
1207 * nothing
1208 */
1209void SkMacHardRst(
1210SK_AC *pAC, /* adapter context */
1211SK_IOC IoC, /* IO context */
1212int Port) /* Port Index (MAC_1 + n) */
1213{
1214
1215#ifdef GENESIS
1216 if (pAC->GIni.GIGenesis) {
1217
1218 SkXmHardRst(pAC, IoC, Port);
1219 }
1220#endif /* GENESIS */
1221
1222#ifdef YUKON
1223 if (pAC->GIni.GIYukon) {
1224
1225 SkGmHardRst(pAC, IoC, Port);
1226 }
1227#endif /* YUKON */
1228
1229 pAC->GIni.GP[Port].PState = SK_PRT_RESET;
1230
1231} /* SkMacHardRst */
1232
1233
1234#ifdef GENESIS
1235/******************************************************************************
1236 *
1237 * SkXmInitMac() - Initialize the XMAC II
1238 *
1239 * Description:
1240 * Initialize the XMAC of the specified port.
1241 * The XMAC must be reset or stopped before calling this function.
1242 *
1243 * Note:
1244 * The XMAC's Rx and Tx state machine is still disabled when returning.
1245 *
1246 * Returns:
1247 * nothing
1248 */
1249void SkXmInitMac(
1250SK_AC *pAC, /* adapter context */
1251SK_IOC IoC, /* IO context */
1252int Port) /* Port Index (MAC_1 + n) */
1253{
1254 SK_GEPORT *pPrt;
1255 int i;
1256 SK_U16 SWord;
1257
1258 pPrt = &pAC->GIni.GP[Port];
1259
1260 if (pPrt->PState == SK_PRT_STOP) {
1261 /* Port State: SK_PRT_STOP */
1262 /* Verify that the reset bit is cleared */
1263 SK_IN16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), &SWord);
1264
1265 if ((SWord & MFF_SET_MAC_RST) != 0) {
1266 /* PState does not match HW state */
1267 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E006, SKERR_HWI_E006MSG);
1268 /* Correct it */
1269 pPrt->PState = SK_PRT_RESET;
1270 }
1271 }
1272
1273 if (pPrt->PState == SK_PRT_RESET) {
1274
1275 SkXmClearRst(pAC, IoC, Port);
1276
1277 if (pPrt->PhyType != SK_PHY_XMAC) {
1278 /* read Id from external PHY (all have the same address) */
1279 SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_ID1, &pPrt->PhyId1);
1280
1281 /*
1282 * Optimize MDIO transfer by suppressing preamble.
1283 * Must be done AFTER first access to BCOM chip.
1284 */
1285 XM_IN16(IoC, Port, XM_MMU_CMD, &SWord);
1286
1287 XM_OUT16(IoC, Port, XM_MMU_CMD, SWord | XM_MMU_NO_PRE);
1288
1289 if (pPrt->PhyId1 == PHY_BCOM_ID1_C0) {
1290 /*
1291 * Workaround BCOM Errata for the C0 type.
1292 * Write magic patterns to reserved registers.
1293 */
1294 i = 0;
1295 while (BcomRegC0Hack[i].PhyReg != 0) {
1296 SkXmPhyWrite(pAC, IoC, Port, BcomRegC0Hack[i].PhyReg,
1297 BcomRegC0Hack[i].PhyVal);
1298 i++;
1299 }
1300 }
1301 else if (pPrt->PhyId1 == PHY_BCOM_ID1_A1) {
1302 /*
1303 * Workaround BCOM Errata for the A1 type.
1304 * Write magic patterns to reserved registers.
1305 */
1306 i = 0;
1307 while (BcomRegA1Hack[i].PhyReg != 0) {
1308 SkXmPhyWrite(pAC, IoC, Port, BcomRegA1Hack[i].PhyReg,
1309 BcomRegA1Hack[i].PhyVal);
1310 i++;
1311 }
1312 }
1313
1314 /*
1315 * Workaround BCOM Errata (#10523) for all BCom PHYs.
1316 * Disable Power Management after reset.
1317 */
1318 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &SWord);
1319
1320 SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUX_CTRL,
1321 (SK_U16)(SWord | PHY_B_AC_DIS_PM));
1322
1323 /* PHY LED initialization is done in SkGeXmitLED() */
1324 }
1325
1326 /* Dummy read the Interrupt source register */
1327 XM_IN16(IoC, Port, XM_ISRC, &SWord);
1328
1329 /*
1330 * The auto-negotiation process starts immediately after
1331 * clearing the reset. The auto-negotiation process should be
1332 * started by the SIRQ, therefore stop it here immediately.
1333 */
1334 SkMacInitPhy(pAC, IoC, Port, SK_FALSE);
1335
1336#ifdef TEST_ONLY
1337 /* temp. code: enable signal detect */
1338 /* WARNING: do not override GMII setting above */
1339 XM_OUT16(IoC, Port, XM_HW_CFG, XM_HW_COM4SIG);
1340#endif
1341 }
1342
1343 /*
1344 * configure the XMACs Station Address
1345 * B2_MAC_2 = xx xx xx xx xx x1 is programmed to XMAC A
1346 * B2_MAC_3 = xx xx xx xx xx x2 is programmed to XMAC B
1347 */
1348 for (i = 0; i < 3; i++) {
1349 /*
1350 * The following 2 statements are together endianess
1351 * independent. Remember this when changing.
1352 */
1353 SK_IN16(IoC, (B2_MAC_2 + Port * 8 + i * 2), &SWord);
1354
1355 XM_OUT16(IoC, Port, (XM_SA + i * 2), SWord);
1356 }
1357
1358 /* Tx Inter Packet Gap (XM_TX_IPG): use default */
1359 /* Tx High Water Mark (XM_TX_HI_WM): use default */
1360 /* Tx Low Water Mark (XM_TX_LO_WM): use default */
1361 /* Host Request Threshold (XM_HT_THR): use default */
1362 /* Rx Request Threshold (XM_RX_THR): use default */
1363 /* Rx Low Water Mark (XM_RX_LO_WM): use default */
1364
1365 /* configure Rx High Water Mark (XM_RX_HI_WM) */
1366 XM_OUT16(IoC, Port, XM_RX_HI_WM, SK_XM_RX_HI_WM);
1367
1368 /* Configure Tx Request Threshold */
1369 SWord = SK_XM_THR_SL; /* for single port */
1370
1371 if (pAC->GIni.GIMacsFound > 1) {
1372 switch (pAC->GIni.GIPortUsage) {
1373 case SK_RED_LINK:
1374 SWord = SK_XM_THR_REDL; /* redundant link */
1375 break;
1376 case SK_MUL_LINK:
1377 SWord = SK_XM_THR_MULL; /* load balancing */
1378 break;
1379 case SK_JUMBO_LINK:
1380 SWord = SK_XM_THR_JUMBO; /* jumbo frames */
1381 break;
1382 default:
1383 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E014, SKERR_HWI_E014MSG);
1384 break;
1385 }
1386 }
1387 XM_OUT16(IoC, Port, XM_TX_THR, SWord);
1388
1389 /* setup register defaults for the Tx Command Register */
1390 XM_OUT16(IoC, Port, XM_TX_CMD, XM_TX_AUTO_PAD);
1391
1392 /* setup register defaults for the Rx Command Register */
1393 SWord = XM_RX_STRIP_FCS | XM_RX_LENERR_OK;
1394
1395 if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) {
1396 SWord |= XM_RX_BIG_PK_OK;
1397 }
1398
1399 if (pPrt->PLinkMode == SK_LMODE_HALF) {
1400 /*
1401 * If in manual half duplex mode the other side might be in
1402 * full duplex mode, so ignore if a carrier extension is not seen
1403 * on frames received
1404 */
1405 SWord |= XM_RX_DIS_CEXT;
1406 }
1407
1408 XM_OUT16(IoC, Port, XM_RX_CMD, SWord);
1409
1410 /*
1411 * setup register defaults for the Mode Register
1412 * - Don't strip error frames to avoid Store & Forward
1413 * on the Rx side.
1414 * - Enable 'Check Station Address' bit
1415 * - Enable 'Check Address Array' bit
1416 */
1417 XM_OUT32(IoC, Port, XM_MODE, XM_DEF_MODE);
1418
1419 /*
1420 * Initialize the Receive Counter Event Mask (XM_RX_EV_MSK)
1421 * - Enable all bits excepting 'Octets Rx OK Low CntOv'
1422 * and 'Octets Rx OK Hi Cnt Ov'.
1423 */
1424 XM_OUT32(IoC, Port, XM_RX_EV_MSK, XMR_DEF_MSK);
1425
1426 /*
1427 * Initialize the Transmit Counter Event Mask (XM_TX_EV_MSK)
1428 * - Enable all bits excepting 'Octets Tx OK Low CntOv'
1429 * and 'Octets Tx OK Hi Cnt Ov'.
1430 */
1431 XM_OUT32(IoC, Port, XM_TX_EV_MSK, XMT_DEF_MSK);
1432
1433 /*
1434 * Do NOT init XMAC interrupt mask here.
1435 * All interrupts remain disable until link comes up!
1436 */
1437
1438 /*
1439 * Any additional configuration changes may be done now.
1440 * The last action is to enable the Rx and Tx state machine.
1441 * This should be done after the auto-negotiation process
1442 * has been completed successfully.
1443 */
1444} /* SkXmInitMac */
1445#endif /* GENESIS */
1446
1447
1448#ifdef YUKON
1449/******************************************************************************
1450 *
1451 * SkGmInitMac() - Initialize the GMAC
1452 *
1453 * Description:
1454 * Initialize the GMAC of the specified port.
1455 * The GMAC must be reset or stopped before calling this function.
1456 *
1457 * Note:
1458 * The GMAC's Rx and Tx state machine is still disabled when returning.
1459 *
1460 * Returns:
1461 * nothing
1462 */
1463void SkGmInitMac(
1464SK_AC *pAC, /* adapter context */
1465SK_IOC IoC, /* IO context */
1466int Port) /* Port Index (MAC_1 + n) */
1467{
1468 SK_GEPORT *pPrt;
1469 int i;
1470 SK_U16 SWord;
1471 SK_U32 DWord;
1472
1473 pPrt = &pAC->GIni.GP[Port];
1474
1475 if (pPrt->PState == SK_PRT_STOP) {
1476 /* Port State: SK_PRT_STOP */
1477 /* Verify that the reset bit is cleared */
1478 SK_IN32(IoC, MR_ADDR(Port, GMAC_CTRL), &DWord);
1479
1480 if ((DWord & GMC_RST_SET) != 0) {
1481 /* PState does not match HW state */
1482 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E006, SKERR_HWI_E006MSG);
1483 /* Correct it */
1484 pPrt->PState = SK_PRT_RESET;
1485 }
1486 }
1487
1488 if (pPrt->PState == SK_PRT_RESET) {
1489
1490 SkGmHardRst(pAC, IoC, Port);
1491
1492 SkGmClearRst(pAC, IoC, Port);
1493
1494 /* Auto-negotiation ? */
1495 if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
1496 /* Auto-negotiation disabled */
1497
1498 /* get General Purpose Control */
1499 GM_IN16(IoC, Port, GM_GP_CTRL, &SWord);
1500
1501 /* disable auto-update for speed, duplex and flow-control */
1502 SWord |= GM_GPCR_AU_ALL_DIS;
1503
1504 /* setup General Purpose Control Register */
1505 GM_OUT16(IoC, Port, GM_GP_CTRL, SWord);
1506
1507 SWord = GM_GPCR_AU_ALL_DIS;
1508 }
1509 else {
1510 SWord = 0;
1511 }
1512
1513 /* speed settings */
1514 switch (pPrt->PLinkSpeed) {
1515 case SK_LSPEED_AUTO:
1516 case SK_LSPEED_1000MBPS:
1517 SWord |= GM_GPCR_SPEED_1000 | GM_GPCR_SPEED_100;
1518 break;
1519 case SK_LSPEED_100MBPS:
1520 SWord |= GM_GPCR_SPEED_100;
1521 break;
1522 case SK_LSPEED_10MBPS:
1523 break;
1524 }
1525
1526 /* duplex settings */
1527 if (pPrt->PLinkMode != SK_LMODE_HALF) {
1528 /* set full duplex */
1529 SWord |= GM_GPCR_DUP_FULL;
1530 }
1531
1532 /* flow-control settings */
1533 switch (pPrt->PFlowCtrlMode) {
1534 case SK_FLOW_MODE_NONE:
1535 /* set Pause Off */
1536 SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_PAUSE_OFF);
1537 /* disable Tx & Rx flow-control */
1538 SWord |= GM_GPCR_FC_TX_DIS | GM_GPCR_FC_RX_DIS | GM_GPCR_AU_FCT_DIS;
1539 break;
1540 case SK_FLOW_MODE_LOC_SEND:
1541 /* disable Rx flow-control */
1542 SWord |= GM_GPCR_FC_RX_DIS | GM_GPCR_AU_FCT_DIS;
1543 break;
1544 case SK_FLOW_MODE_SYMMETRIC:
1545 case SK_FLOW_MODE_SYM_OR_REM:
1546 /* enable Tx & Rx flow-control */
1547 break;
1548 }
1549
1550 /* setup General Purpose Control Register */
1551 GM_OUT16(IoC, Port, GM_GP_CTRL, SWord);
1552
1553 /* dummy read the Interrupt Source Register */
1554 SK_IN16(IoC, GMAC_IRQ_SRC, &SWord);
1555
1556#ifndef VCPU
1557 /* read Id from PHY */
1558 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_ID1, &pPrt->PhyId1);
1559
1560 SkGmInitPhyMarv(pAC, IoC, Port, SK_FALSE);
1561#endif /* VCPU */
1562 }
1563
1564 (void)SkGmResetCounter(pAC, IoC, Port);
1565
1566 /* setup Transmit Control Register */
1567 GM_OUT16(IoC, Port, GM_TX_CTRL, TX_COL_THR(pPrt->PMacColThres));
1568
1569 /* setup Receive Control Register */
1570 GM_OUT16(IoC, Port, GM_RX_CTRL, GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA |
1571 GM_RXCR_CRC_DIS);
1572
1573 /* setup Transmit Flow Control Register */
1574 GM_OUT16(IoC, Port, GM_TX_FLOW_CTRL, 0xffff);
1575
1576 /* setup Transmit Parameter Register */
1577#ifdef VCPU
1578 GM_IN16(IoC, Port, GM_TX_PARAM, &SWord);
1579#endif /* VCPU */
1580
1581 SWord = TX_JAM_LEN_VAL(pPrt->PMacJamLen) |
1582 TX_JAM_IPG_VAL(pPrt->PMacJamIpgVal) |
1583 TX_IPG_JAM_DATA(pPrt->PMacJamIpgData);
1584
1585 GM_OUT16(IoC, Port, GM_TX_PARAM, SWord);
1586
1587 /* configure the Serial Mode Register */
1588#ifdef VCPU
1589 GM_IN16(IoC, Port, GM_SERIAL_MODE, &SWord);
1590#endif /* VCPU */
1591
1592 SWord = GM_SMOD_VLAN_ENA | IPG_DATA_VAL(pPrt->PMacIpgData);
1593
1594 if (pPrt->PMacLimit4) {
1595 /* reset of collision counter after 4 consecutive collisions */
1596 SWord |= GM_SMOD_LIMIT_4;
1597 }
1598
1599 if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) {
1600 /* enable jumbo mode (Max. Frame Length = 9018) */
1601 SWord |= GM_SMOD_JUMBO_ENA;
1602 }
1603
1604 GM_OUT16(IoC, Port, GM_SERIAL_MODE, SWord);
1605
1606 /*
1607 * configure the GMACs Station Addresses
1608 * in PROM you can find our addresses at:
1609 * B2_MAC_1 = xx xx xx xx xx x0 virtual address
1610 * B2_MAC_2 = xx xx xx xx xx x1 is programmed to GMAC A
1611 * B2_MAC_3 = xx xx xx xx xx x2 is reserved for DualPort
1612 */
1613
1614 for (i = 0; i < 3; i++) {
1615 /*
1616 * The following 2 statements are together endianess
1617 * independent. Remember this when changing.
1618 */
1619 /* physical address: will be used for pause frames */
1620 SK_IN16(IoC, (B2_MAC_2 + Port * 8 + i * 2), &SWord);
1621
1622#ifdef WA_DEV_16
1623 /* WA for deviation #16 */
1624 if (pAC->GIni.GIChipId == CHIP_ID_YUKON && pAC->GIni.GIChipRev == 0) {
1625 /* swap the address bytes */
1626 SWord = ((SWord & 0xff00) >> 8) | ((SWord & 0x00ff) << 8);
1627
1628 /* write to register in reversed order */
1629 GM_OUT16(IoC, Port, (GM_SRC_ADDR_1L + (2 - i) * 4), SWord);
1630 }
1631 else {
1632 GM_OUT16(IoC, Port, (GM_SRC_ADDR_1L + i * 4), SWord);
1633 }
1634#else
1635 GM_OUT16(IoC, Port, (GM_SRC_ADDR_1L + i * 4), SWord);
1636#endif /* WA_DEV_16 */
1637
1638 /* virtual address: will be used for data */
1639 SK_IN16(IoC, (B2_MAC_1 + Port * 8 + i * 2), &SWord);
1640
1641 GM_OUT16(IoC, Port, (GM_SRC_ADDR_2L + i * 4), SWord);
1642
1643 /* reset Multicast filtering Hash registers 1-3 */
1644 GM_OUT16(IoC, Port, GM_MC_ADDR_H1 + 4*i, 0);
1645 }
1646
1647 /* reset Multicast filtering Hash register 4 */
1648 GM_OUT16(IoC, Port, GM_MC_ADDR_H4, 0);
1649
1650 /* enable interrupt mask for counter overflows */
1651 GM_OUT16(IoC, Port, GM_TX_IRQ_MSK, 0);
1652 GM_OUT16(IoC, Port, GM_RX_IRQ_MSK, 0);
1653 GM_OUT16(IoC, Port, GM_TR_IRQ_MSK, 0);
1654
1655#if defined(SK_DIAG) || defined(DEBUG)
1656 /* read General Purpose Status */
1657 GM_IN16(IoC, Port, GM_GP_STAT, &SWord);
1658
1659 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1660 ("MAC Stat Reg.=0x%04X\n", SWord));
1661#endif /* SK_DIAG || DEBUG */
1662
1663#ifdef SK_DIAG
1664 c_print("MAC Stat Reg=0x%04X\n", SWord);
1665#endif /* SK_DIAG */
1666
1667} /* SkGmInitMac */
1668#endif /* YUKON */
1669
1670
1671#ifdef GENESIS
1672/******************************************************************************
1673 *
1674 * SkXmInitDupMd() - Initialize the XMACs Duplex Mode
1675 *
1676 * Description:
1677 * This function initializes the XMACs Duplex Mode.
1678 * It should be called after successfully finishing
1679 * the Auto-negotiation Process
1680 *
1681 * Returns:
1682 * nothing
1683 */
1684static void SkXmInitDupMd(
1685SK_AC *pAC, /* adapter context */
1686SK_IOC IoC, /* IO context */
1687int Port) /* Port Index (MAC_1 + n) */
1688{
1689 switch (pAC->GIni.GP[Port].PLinkModeStatus) {
1690 case SK_LMODE_STAT_AUTOHALF:
1691 case SK_LMODE_STAT_HALF:
1692 /* Configuration Actions for Half Duplex Mode */
1693 /*
1694 * XM_BURST = default value. We are probable not quick
1695 * enough at the 'XMAC' bus to burst 8kB.
1696 * The XMAC stops bursting if no transmit frames
1697 * are available or the burst limit is exceeded.
1698 */
1699 /* XM_TX_RT_LIM = default value (15) */
1700 /* XM_TX_STIME = default value (0xff = 4096 bit times) */
1701 break;
1702 case SK_LMODE_STAT_AUTOFULL:
1703 case SK_LMODE_STAT_FULL:
1704 /* Configuration Actions for Full Duplex Mode */
1705 /*
1706 * The duplex mode is configured by the PHY,
1707 * therefore it seems to be that there is nothing
1708 * to do here.
1709 */
1710 break;
1711 case SK_LMODE_STAT_UNKNOWN:
1712 default:
1713 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E007, SKERR_HWI_E007MSG);
1714 break;
1715 }
1716} /* SkXmInitDupMd */
1717
1718
1719/******************************************************************************
1720 *
1721 * SkXmInitPauseMd() - initialize the Pause Mode to be used for this port
1722 *
1723 * Description:
1724 * This function initializes the Pause Mode which should
1725 * be used for this port.
1726 * It should be called after successfully finishing
1727 * the Auto-negotiation Process
1728 *
1729 * Returns:
1730 * nothing
1731 */
1732static void SkXmInitPauseMd(
1733SK_AC *pAC, /* adapter context */
1734SK_IOC IoC, /* IO context */
1735int Port) /* Port Index (MAC_1 + n) */
1736{
1737 SK_GEPORT *pPrt;
1738 SK_U32 DWord;
1739 SK_U16 Word;
1740
1741 pPrt = &pAC->GIni.GP[Port];
1742
1743 XM_IN16(IoC, Port, XM_MMU_CMD, &Word);
1744
1745 if (pPrt->PFlowCtrlStatus == SK_FLOW_STAT_NONE ||
1746 pPrt->PFlowCtrlStatus == SK_FLOW_STAT_LOC_SEND) {
1747
1748 /* Disable Pause Frame Reception */
1749 Word |= XM_MMU_IGN_PF;
1750 }
1751 else {
1752 /*
1753 * enabling pause frame reception is required for 1000BT
1754 * because the XMAC is not reset if the link is going down
1755 */
1756 /* Enable Pause Frame Reception */
1757 Word &= ~XM_MMU_IGN_PF;
1758 }
1759
1760 XM_OUT16(IoC, Port, XM_MMU_CMD, Word);
1761
1762 XM_IN32(IoC, Port, XM_MODE, &DWord);
1763
1764 if (pPrt->PFlowCtrlStatus == SK_FLOW_STAT_SYMMETRIC ||
1765 pPrt->PFlowCtrlStatus == SK_FLOW_STAT_LOC_SEND) {
1766
1767 /*
1768 * Configure Pause Frame Generation
1769 * Use internal and external Pause Frame Generation.
1770 * Sending pause frames is edge triggered.
1771 * Send a Pause frame with the maximum pause time if
1772 * internal oder external FIFO full condition occurs.
1773 * Send a zero pause time frame to re-start transmission.
1774 */
1775
1776 /* XM_PAUSE_DA = '010000C28001' (default) */
1777
1778 /* XM_MAC_PTIME = 0xffff (maximum) */
1779 /* remember this value is defined in big endian (!) */
1780 XM_OUT16(IoC, Port, XM_MAC_PTIME, 0xffff);
1781
1782 /* Set Pause Mode in Mode Register */
1783 DWord |= XM_PAUSE_MODE;
1784
1785 /* Set Pause Mode in MAC Rx FIFO */
1786 SK_OUT16(IoC, MR_ADDR(Port, RX_MFF_CTRL1), MFF_ENA_PAUSE);
1787 }
1788 else {
1789 /*
1790 * disable pause frame generation is required for 1000BT
1791 * because the XMAC is not reset if the link is going down
1792 */
1793 /* Disable Pause Mode in Mode Register */
1794 DWord &= ~XM_PAUSE_MODE;
1795
1796 /* Disable Pause Mode in MAC Rx FIFO */
1797 SK_OUT16(IoC, MR_ADDR(Port, RX_MFF_CTRL1), MFF_DIS_PAUSE);
1798 }
1799
1800 XM_OUT32(IoC, Port, XM_MODE, DWord);
1801} /* SkXmInitPauseMd*/
1802
1803
1804/******************************************************************************
1805 *
1806 * SkXmInitPhyXmac() - Initialize the XMAC Phy registers
1807 *
1808 * Description: initializes all the XMACs Phy registers
1809 *
1810 * Note:
1811 *
1812 * Returns:
1813 * nothing
1814 */
1815static void SkXmInitPhyXmac(
1816SK_AC *pAC, /* adapter context */
1817SK_IOC IoC, /* IO context */
1818int Port, /* Port Index (MAC_1 + n) */
1819SK_BOOL DoLoop) /* Should a Phy LoopBack be set-up? */
1820{
1821 SK_GEPORT *pPrt;
1822 SK_U16 Ctrl;
1823
1824 pPrt = &pAC->GIni.GP[Port];
1825 Ctrl = 0;
1826
1827 /* Auto-negotiation ? */
1828 if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
1829 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1830 ("InitPhyXmac: no auto-negotiation Port %d\n", Port));
1831 /* Set DuplexMode in Config register */
1832 if (pPrt->PLinkMode == SK_LMODE_FULL) {
1833 Ctrl |= PHY_CT_DUP_MD;
1834 }
1835
1836 /*
1837 * Do NOT enable Auto-negotiation here. This would hold
1838 * the link down because no IDLEs are transmitted
1839 */
1840 }
1841 else {
1842 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1843 ("InitPhyXmac: with auto-negotiation Port %d\n", Port));
1844 /* Set Auto-negotiation advertisement */
1845
1846 /* Set Full/half duplex capabilities */
1847 switch (pPrt->PLinkMode) {
1848 case SK_LMODE_AUTOHALF:
1849 Ctrl |= PHY_X_AN_HD;
1850 break;
1851 case SK_LMODE_AUTOFULL:
1852 Ctrl |= PHY_X_AN_FD;
1853 break;
1854 case SK_LMODE_AUTOBOTH:
1855 Ctrl |= PHY_X_AN_FD | PHY_X_AN_HD;
1856 break;
1857 default:
1858 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E015,
1859 SKERR_HWI_E015MSG);
1860 }
1861
1862 /* Set Flow-control capabilities */
1863 switch (pPrt->PFlowCtrlMode) {
1864 case SK_FLOW_MODE_NONE:
1865 Ctrl |= PHY_X_P_NO_PAUSE;
1866 break;
1867 case SK_FLOW_MODE_LOC_SEND:
1868 Ctrl |= PHY_X_P_ASYM_MD;
1869 break;
1870 case SK_FLOW_MODE_SYMMETRIC:
1871 Ctrl |= PHY_X_P_SYM_MD;
1872 break;
1873 case SK_FLOW_MODE_SYM_OR_REM:
1874 Ctrl |= PHY_X_P_BOTH_MD;
1875 break;
1876 default:
1877 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016,
1878 SKERR_HWI_E016MSG);
1879 }
1880
1881 /* Write AutoNeg Advertisement Register */
1882 SkXmPhyWrite(pAC, IoC, Port, PHY_XMAC_AUNE_ADV, Ctrl);
1883
1884 /* Restart Auto-negotiation */
1885 Ctrl = PHY_CT_ANE | PHY_CT_RE_CFG;
1886 }
1887
1888 if (DoLoop) {
1889 /* Set the Phy Loopback bit, too */
1890 Ctrl |= PHY_CT_LOOP;
1891 }
1892
1893 /* Write to the Phy control register */
1894 SkXmPhyWrite(pAC, IoC, Port, PHY_XMAC_CTRL, Ctrl);
1895} /* SkXmInitPhyXmac */
1896
1897
1898/******************************************************************************
1899 *
1900 * SkXmInitPhyBcom() - Initialize the Broadcom Phy registers
1901 *
1902 * Description: initializes all the Broadcom Phy registers
1903 *
1904 * Note:
1905 *
1906 * Returns:
1907 * nothing
1908 */
1909static void SkXmInitPhyBcom(
1910SK_AC *pAC, /* adapter context */
1911SK_IOC IoC, /* IO context */
1912int Port, /* Port Index (MAC_1 + n) */
1913SK_BOOL DoLoop) /* Should a Phy LoopBack be set-up? */
1914{
1915 SK_GEPORT *pPrt;
1916 SK_U16 Ctrl1;
1917 SK_U16 Ctrl2;
1918 SK_U16 Ctrl3;
1919 SK_U16 Ctrl4;
1920 SK_U16 Ctrl5;
1921
1922 Ctrl1 = PHY_CT_SP1000;
1923 Ctrl2 = 0;
1924 Ctrl3 = PHY_SEL_TYPE;
1925 Ctrl4 = PHY_B_PEC_EN_LTR;
1926 Ctrl5 = PHY_B_AC_TX_TST;
1927
1928 pPrt = &pAC->GIni.GP[Port];
1929
1930 /* manually Master/Slave ? */
1931 if (pPrt->PMSMode != SK_MS_MODE_AUTO) {
1932 Ctrl2 |= PHY_B_1000C_MSE;
1933
1934 if (pPrt->PMSMode == SK_MS_MODE_MASTER) {
1935 Ctrl2 |= PHY_B_1000C_MSC;
1936 }
1937 }
1938 /* Auto-negotiation ? */
1939 if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
1940 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1941 ("InitPhyBcom: no auto-negotiation Port %d\n", Port));
1942 /* Set DuplexMode in Config register */
1943 if (pPrt->PLinkMode == SK_LMODE_FULL) {
1944 Ctrl1 |= PHY_CT_DUP_MD;
1945 }
1946
1947 /* Determine Master/Slave manually if not already done */
1948 if (pPrt->PMSMode == SK_MS_MODE_AUTO) {
1949 Ctrl2 |= PHY_B_1000C_MSE; /* set it to Slave */
1950 }
1951
1952 /*
1953 * Do NOT enable Auto-negotiation here. This would hold
1954 * the link down because no IDLES are transmitted
1955 */
1956 }
1957 else {
1958 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
1959 ("InitPhyBcom: with auto-negotiation Port %d\n", Port));
1960 /* Set Auto-negotiation advertisement */
1961
1962 /*
1963 * Workaround BCOM Errata #1 for the C5 type.
1964 * 1000Base-T Link Acquisition Failure in Slave Mode
1965 * Set Repeater/DTE bit 10 of the 1000Base-T Control Register
1966 */
1967 Ctrl2 |= PHY_B_1000C_RD;
1968
1969 /* Set Full/half duplex capabilities */
1970 switch (pPrt->PLinkMode) {
1971 case SK_LMODE_AUTOHALF:
1972 Ctrl2 |= PHY_B_1000C_AHD;
1973 break;
1974 case SK_LMODE_AUTOFULL:
1975 Ctrl2 |= PHY_B_1000C_AFD;
1976 break;
1977 case SK_LMODE_AUTOBOTH:
1978 Ctrl2 |= PHY_B_1000C_AFD | PHY_B_1000C_AHD;
1979 break;
1980 default:
1981 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E015,
1982 SKERR_HWI_E015MSG);
1983 }
1984
1985 /* Set Flow-control capabilities */
1986 switch (pPrt->PFlowCtrlMode) {
1987 case SK_FLOW_MODE_NONE:
1988 Ctrl3 |= PHY_B_P_NO_PAUSE;
1989 break;
1990 case SK_FLOW_MODE_LOC_SEND:
1991 Ctrl3 |= PHY_B_P_ASYM_MD;
1992 break;
1993 case SK_FLOW_MODE_SYMMETRIC:
1994 Ctrl3 |= PHY_B_P_SYM_MD;
1995 break;
1996 case SK_FLOW_MODE_SYM_OR_REM:
1997 Ctrl3 |= PHY_B_P_BOTH_MD;
1998 break;
1999 default:
2000 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016,
2001 SKERR_HWI_E016MSG);
2002 }
2003
2004 /* Restart Auto-negotiation */
2005 Ctrl1 |= PHY_CT_ANE | PHY_CT_RE_CFG;
2006 }
2007
2008 /* Initialize LED register here? */
2009 /* No. Please do it in SkDgXmitLed() (if required) and swap
2010 init order of LEDs and XMAC. (MAl) */
2011
2012 /* Write 1000Base-T Control Register */
2013 SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_1000T_CTRL, Ctrl2);
2014 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2015 ("Set 1000B-T Ctrl Reg=0x%04X\n", Ctrl2));
2016
2017 /* Write AutoNeg Advertisement Register */
2018 SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUNE_ADV, Ctrl3);
2019 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2020 ("Set Auto-Neg.Adv.Reg=0x%04X\n", Ctrl3));
2021
2022 if (DoLoop) {
2023 /* Set the Phy Loopback bit, too */
2024 Ctrl1 |= PHY_CT_LOOP;
2025 }
2026
2027 if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) {
2028 /* configure FIFO to high latency for transmission of ext. packets */
2029 Ctrl4 |= PHY_B_PEC_HIGH_LA;
2030
2031 /* configure reception of extended packets */
2032 Ctrl5 |= PHY_B_AC_LONG_PACK;
2033
2034 SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, Ctrl5);
2035 }
2036
2037 /* Configure LED Traffic Mode and Jumbo Frame usage if specified */
2038 SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_P_EXT_CTRL, Ctrl4);
2039
2040 /* Write to the Phy control register */
2041 SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_CTRL, Ctrl1);
2042 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2043 ("PHY Control Reg=0x%04X\n", Ctrl1));
2044} /* SkXmInitPhyBcom */
2045#endif /* GENESIS */
2046
2047#ifdef YUKON
2048/******************************************************************************
2049 *
2050 * SkGmInitPhyMarv() - Initialize the Marvell Phy registers
2051 *
2052 * Description: initializes all the Marvell Phy registers
2053 *
2054 * Note:
2055 *
2056 * Returns:
2057 * nothing
2058 */
2059static void SkGmInitPhyMarv(
2060SK_AC *pAC, /* adapter context */
2061SK_IOC IoC, /* IO context */
2062int Port, /* Port Index (MAC_1 + n) */
2063SK_BOOL DoLoop) /* Should a Phy LoopBack be set-up? */
2064{
2065 SK_GEPORT *pPrt;
2066 SK_U16 PhyCtrl;
2067 SK_U16 C1000BaseT;
2068 SK_U16 AutoNegAdv;
2069 SK_U16 ExtPhyCtrl;
2070 SK_U16 LedCtrl;
2071 SK_BOOL AutoNeg;
2072#if defined(SK_DIAG) || defined(DEBUG)
2073 SK_U16 PhyStat;
2074 SK_U16 PhyStat1;
2075 SK_U16 PhySpecStat;
2076#endif /* SK_DIAG || DEBUG */
2077
2078 pPrt = &pAC->GIni.GP[Port];
2079
2080 /* Auto-negotiation ? */
2081 if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
2082 AutoNeg = SK_FALSE;
2083 }
2084 else {
2085 AutoNeg = SK_TRUE;
2086 }
2087
2088 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2089 ("InitPhyMarv: Port %d, auto-negotiation %s\n",
2090 Port, AutoNeg ? "ON" : "OFF"));
2091
2092#ifdef VCPU
2093 VCPUprintf(0, "SkGmInitPhyMarv(), Port=%u, DoLoop=%u\n",
2094 Port, DoLoop);
2095#else /* VCPU */
2096 if (DoLoop) {
2097 /* Set 'MAC Power up'-bit, set Manual MDI configuration */
2098 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL,
2099 PHY_M_PC_MAC_POW_UP);
2100 }
2101 else if (AutoNeg && pPrt->PLinkSpeed == SK_LSPEED_AUTO) {
2102 /* Read Ext. PHY Specific Control */
2103 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_EXT_CTRL, &ExtPhyCtrl);
2104
2105 ExtPhyCtrl &= ~(PHY_M_EC_M_DSC_MSK | PHY_M_EC_S_DSC_MSK |
2106 PHY_M_EC_MAC_S_MSK);
2107
2108 ExtPhyCtrl |= PHY_M_EC_MAC_S(MAC_TX_CLK_25_MHZ) |
2109 PHY_M_EC_M_DSC(0) | PHY_M_EC_S_DSC(1);
2110
2111 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_CTRL, ExtPhyCtrl);
2112 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2113 ("Set Ext. PHY Ctrl=0x%04X\n", ExtPhyCtrl));
2114 }
2115
2116 /* Read PHY Control */
2117 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &PhyCtrl);
2118
2119 if (!AutoNeg) {
2120 /* Disable Auto-negotiation */
2121 PhyCtrl &= ~PHY_CT_ANE;
2122 }
2123
2124 PhyCtrl |= PHY_CT_RESET;
2125 /* Assert software reset */
2126 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, PhyCtrl);
2127#endif /* VCPU */
2128
2129 PhyCtrl = 0 /* PHY_CT_COL_TST */;
2130 C1000BaseT = 0;
2131 AutoNegAdv = PHY_SEL_TYPE;
2132
2133 /* manually Master/Slave ? */
2134 if (pPrt->PMSMode != SK_MS_MODE_AUTO) {
2135 /* enable Manual Master/Slave */
2136 C1000BaseT |= PHY_M_1000C_MSE;
2137
2138 if (pPrt->PMSMode == SK_MS_MODE_MASTER) {
2139 C1000BaseT |= PHY_M_1000C_MSC; /* set it to Master */
2140 }
2141 }
2142
2143 /* Auto-negotiation ? */
2144 if (!AutoNeg) {
2145
2146 if (pPrt->PLinkMode == SK_LMODE_FULL) {
2147 /* Set Full Duplex Mode */
2148 PhyCtrl |= PHY_CT_DUP_MD;
2149 }
2150
2151 /* Set Master/Slave manually if not already done */
2152 if (pPrt->PMSMode == SK_MS_MODE_AUTO) {
2153 C1000BaseT |= PHY_M_1000C_MSE; /* set it to Slave */
2154 }
2155
2156 /* Set Speed */
2157 switch (pPrt->PLinkSpeed) {
2158 case SK_LSPEED_AUTO:
2159 case SK_LSPEED_1000MBPS:
2160 PhyCtrl |= PHY_CT_SP1000;
2161 break;
2162 case SK_LSPEED_100MBPS:
2163 PhyCtrl |= PHY_CT_SP100;
2164 break;
2165 case SK_LSPEED_10MBPS:
2166 break;
2167 default:
2168 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E019,
2169 SKERR_HWI_E019MSG);
2170 }
2171
2172 if (!DoLoop) {
2173 PhyCtrl |= PHY_CT_RESET;
2174 }
2175 }
2176 else {
2177 /* Set Auto-negotiation advertisement */
2178
2179 if (pAC->GIni.GICopperType) {
2180 /* Set Speed capabilities */
2181 switch (pPrt->PLinkSpeed) {
2182 case SK_LSPEED_AUTO:
2183 C1000BaseT |= PHY_M_1000C_AHD | PHY_M_1000C_AFD;
2184 AutoNegAdv |= PHY_M_AN_100_FD | PHY_M_AN_100_HD |
2185 PHY_M_AN_10_FD | PHY_M_AN_10_HD;
2186 break;
2187 case SK_LSPEED_1000MBPS:
2188 C1000BaseT |= PHY_M_1000C_AHD | PHY_M_1000C_AFD;
2189 break;
2190 case SK_LSPEED_100MBPS:
2191 AutoNegAdv |= PHY_M_AN_100_FD | PHY_M_AN_100_HD |
2192 /* advertise 10Base-T also */
2193 PHY_M_AN_10_FD | PHY_M_AN_10_HD;
2194 break;
2195 case SK_LSPEED_10MBPS:
2196 AutoNegAdv |= PHY_M_AN_10_FD | PHY_M_AN_10_HD;
2197 break;
2198 default:
2199 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E019,
2200 SKERR_HWI_E019MSG);
2201 }
2202
2203 /* Set Full/half duplex capabilities */
2204 switch (pPrt->PLinkMode) {
2205 case SK_LMODE_AUTOHALF:
2206 C1000BaseT &= ~PHY_M_1000C_AFD;
2207 AutoNegAdv &= ~(PHY_M_AN_100_FD | PHY_M_AN_10_FD);
2208 break;
2209 case SK_LMODE_AUTOFULL:
2210 C1000BaseT &= ~PHY_M_1000C_AHD;
2211 AutoNegAdv &= ~(PHY_M_AN_100_HD | PHY_M_AN_10_HD);
2212 break;
2213 case SK_LMODE_AUTOBOTH:
2214 break;
2215 default:
2216 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E015,
2217 SKERR_HWI_E015MSG);
2218 }
2219
2220 /* Set Flow-control capabilities */
2221 switch (pPrt->PFlowCtrlMode) {
2222 case SK_FLOW_MODE_NONE:
2223 AutoNegAdv |= PHY_B_P_NO_PAUSE;
2224 break;
2225 case SK_FLOW_MODE_LOC_SEND:
2226 AutoNegAdv |= PHY_B_P_ASYM_MD;
2227 break;
2228 case SK_FLOW_MODE_SYMMETRIC:
2229 AutoNegAdv |= PHY_B_P_SYM_MD;
2230 break;
2231 case SK_FLOW_MODE_SYM_OR_REM:
2232 AutoNegAdv |= PHY_B_P_BOTH_MD;
2233 break;
2234 default:
2235 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016,
2236 SKERR_HWI_E016MSG);
2237 }
2238 }
2239 else { /* special defines for FIBER (88E1011S only) */
2240
2241 /* Set Full/half duplex capabilities */
2242 switch (pPrt->PLinkMode) {
2243 case SK_LMODE_AUTOHALF:
2244 AutoNegAdv |= PHY_M_AN_1000X_AHD;
2245 break;
2246 case SK_LMODE_AUTOFULL:
2247 AutoNegAdv |= PHY_M_AN_1000X_AFD;
2248 break;
2249 case SK_LMODE_AUTOBOTH:
2250 AutoNegAdv |= PHY_M_AN_1000X_AHD | PHY_M_AN_1000X_AFD;
2251 break;
2252 default:
2253 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E015,
2254 SKERR_HWI_E015MSG);
2255 }
2256
2257 /* Set Flow-control capabilities */
2258 switch (pPrt->PFlowCtrlMode) {
2259 case SK_FLOW_MODE_NONE:
2260 AutoNegAdv |= PHY_M_P_NO_PAUSE_X;
2261 break;
2262 case SK_FLOW_MODE_LOC_SEND:
2263 AutoNegAdv |= PHY_M_P_ASYM_MD_X;
2264 break;
2265 case SK_FLOW_MODE_SYMMETRIC:
2266 AutoNegAdv |= PHY_M_P_SYM_MD_X;
2267 break;
2268 case SK_FLOW_MODE_SYM_OR_REM:
2269 AutoNegAdv |= PHY_M_P_BOTH_MD_X;
2270 break;
2271 default:
2272 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016,
2273 SKERR_HWI_E016MSG);
2274 }
2275 }
2276
2277 if (!DoLoop) {
2278 /* Restart Auto-negotiation */
2279 PhyCtrl |= PHY_CT_ANE | PHY_CT_RE_CFG;
2280 }
2281 }
2282
2283#ifdef VCPU
2284 /*
2285 * E-mail from Gu Lin (08-03-2002):
2286 */
2287
2288 /* Program PHY register 30 as 16'h0708 for simulation speed up */
2289 SkGmPhyWrite(pAC, IoC, Port, 30, 0x0700 /* 0x0708 */);
2290
2291 VCpuWait(2000);
2292
2293#else /* VCPU */
2294
2295 /* Write 1000Base-T Control Register */
2296 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_1000T_CTRL, C1000BaseT);
2297 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2298 ("Set 1000B-T Ctrl =0x%04X\n", C1000BaseT));
2299
2300 /* Write AutoNeg Advertisement Register */
2301 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_AUNE_ADV, AutoNegAdv);
2302 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2303 ("Set Auto-Neg.Adv.=0x%04X\n", AutoNegAdv));
2304#endif /* VCPU */
2305
2306 if (DoLoop) {
2307 /* Set the PHY Loopback bit */
2308 PhyCtrl |= PHY_CT_LOOP;
2309
2310#ifdef XXX
2311 /* Program PHY register 16 as 16'h0400 to force link good */
2312 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, PHY_M_PC_FL_GOOD);
2313#endif /* XXX */
2314
2315#ifndef VCPU
2316 if (pPrt->PLinkSpeed != SK_LSPEED_AUTO) {
2317 /* Write Ext. PHY Specific Control */
2318 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_CTRL,
2319 (SK_U16)((pPrt->PLinkSpeed + 2) << 4));
2320 }
2321#endif /* VCPU */
2322 }
2323#ifdef TEST_ONLY
2324 else if (pPrt->PLinkSpeed == SK_LSPEED_10MBPS) {
2325 /* Write PHY Specific Control */
2326 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL,
2327 PHY_M_PC_EN_DET_MSK);
2328 }
2329#endif
2330
2331 /* Write to the PHY Control register */
2332 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, PhyCtrl);
2333 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2334 ("Set PHY Ctrl Reg.=0x%04X\n", PhyCtrl));
2335
2336#ifdef VCPU
2337 VCpuWait(2000);
2338#else
2339
2340 LedCtrl = PHY_M_LED_PULS_DUR(PULS_170MS) | PHY_M_LED_BLINK_RT(BLINK_84MS);
2341
2342 if ((pAC->GIni.GILedBlinkCtrl & SK_ACT_LED_BLINK) != 0) {
2343 LedCtrl |= PHY_M_LEDC_RX_CTRL | PHY_M_LEDC_TX_CTRL;
2344 }
2345
2346 if ((pAC->GIni.GILedBlinkCtrl & SK_DUP_LED_NORMAL) != 0) {
2347 LedCtrl |= PHY_M_LEDC_DP_CTRL;
2348 }
2349
2350 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_LED_CTRL, LedCtrl);
2351
2352 if ((pAC->GIni.GILedBlinkCtrl & SK_LED_LINK100_ON) != 0) {
2353 /* only in forced 100 Mbps mode */
2354 if (!AutoNeg && pPrt->PLinkSpeed == SK_LSPEED_100MBPS) {
2355
2356 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_LED_OVER,
2357 PHY_M_LED_MO_100(MO_LED_ON));
2358 }
2359 }
2360
2361#ifdef SK_DIAG
2362 c_print("Set PHY Ctrl=0x%04X\n", PhyCtrl);
2363 c_print("Set 1000 B-T=0x%04X\n", C1000BaseT);
2364 c_print("Set Auto-Neg=0x%04X\n", AutoNegAdv);
2365 c_print("Set Ext Ctrl=0x%04X\n", ExtPhyCtrl);
2366#endif /* SK_DIAG */
2367
2368#if defined(SK_DIAG) || defined(DEBUG)
2369 /* Read PHY Control */
2370 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &PhyCtrl);
2371 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2372 ("PHY Ctrl Reg.=0x%04X\n", PhyCtrl));
2373
2374 /* Read 1000Base-T Control Register */
2375 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_1000T_CTRL, &C1000BaseT);
2376 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2377 ("1000B-T Ctrl =0x%04X\n", C1000BaseT));
2378
2379 /* Read AutoNeg Advertisement Register */
2380 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_ADV, &AutoNegAdv);
2381 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2382 ("Auto-Neg.Adv.=0x%04X\n", AutoNegAdv));
2383
2384 /* Read Ext. PHY Specific Control */
2385 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_EXT_CTRL, &ExtPhyCtrl);
2386 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2387 ("Ext. PHY Ctrl=0x%04X\n", ExtPhyCtrl));
2388
2389 /* Read PHY Status */
2390 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_STAT, &PhyStat);
2391 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2392 ("PHY Stat Reg.=0x%04X\n", PhyStat));
2393 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_STAT, &PhyStat1);
2394 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2395 ("PHY Stat Reg.=0x%04X\n", PhyStat1));
2396
2397 /* Read PHY Specific Status */
2398 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_STAT, &PhySpecStat);
2399 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2400 ("PHY Spec Stat=0x%04X\n", PhySpecStat));
2401#endif /* SK_DIAG || DEBUG */
2402
2403#ifdef SK_DIAG
2404 c_print("PHY Ctrl Reg=0x%04X\n", PhyCtrl);
2405 c_print("PHY 1000 Reg=0x%04X\n", C1000BaseT);
2406 c_print("PHY AnAd Reg=0x%04X\n", AutoNegAdv);
2407 c_print("Ext Ctrl Reg=0x%04X\n", ExtPhyCtrl);
2408 c_print("PHY Stat Reg=0x%04X\n", PhyStat);
2409 c_print("PHY Stat Reg=0x%04X\n", PhyStat1);
2410 c_print("PHY Spec Reg=0x%04X\n", PhySpecStat);
2411#endif /* SK_DIAG */
2412
2413#endif /* VCPU */
2414
2415} /* SkGmInitPhyMarv */
2416#endif /* YUKON */
2417
2418
2419#ifdef OTHER_PHY
2420/******************************************************************************
2421 *
2422 * SkXmInitPhyLone() - Initialize the Level One Phy registers
2423 *
2424 * Description: initializes all the Level One Phy registers
2425 *
2426 * Note:
2427 *
2428 * Returns:
2429 * nothing
2430 */
2431static void SkXmInitPhyLone(
2432SK_AC *pAC, /* adapter context */
2433SK_IOC IoC, /* IO context */
2434int Port, /* Port Index (MAC_1 + n) */
2435SK_BOOL DoLoop) /* Should a Phy LoopBack be set-up? */
2436{
2437 SK_GEPORT *pPrt;
2438 SK_U16 Ctrl1;
2439 SK_U16 Ctrl2;
2440 SK_U16 Ctrl3;
2441
2442 Ctrl1 = PHY_CT_SP1000;
2443 Ctrl2 = 0;
2444 Ctrl3 = PHY_SEL_TYPE;
2445
2446 pPrt = &pAC->GIni.GP[Port];
2447
2448 /* manually Master/Slave ? */
2449 if (pPrt->PMSMode != SK_MS_MODE_AUTO) {
2450 Ctrl2 |= PHY_L_1000C_MSE;
2451
2452 if (pPrt->PMSMode == SK_MS_MODE_MASTER) {
2453 Ctrl2 |= PHY_L_1000C_MSC;
2454 }
2455 }
2456 /* Auto-negotiation ? */
2457 if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
2458 /*
2459 * level one spec say: "1000 Mbps: manual mode not allowed"
2460 * but lets see what happens...
2461 */
2462 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2463 ("InitPhyLone: no auto-negotiation Port %d\n", Port));
2464 /* Set DuplexMode in Config register */
2465 if (pPrt->PLinkMode == SK_LMODE_FULL) {
2466 Ctrl1 |= PHY_CT_DUP_MD;
2467 }
2468
2469 /* Determine Master/Slave manually if not already done */
2470 if (pPrt->PMSMode == SK_MS_MODE_AUTO) {
2471 Ctrl2 |= PHY_L_1000C_MSE; /* set it to Slave */
2472 }
2473
2474 /*
2475 * Do NOT enable Auto-negotiation here. This would hold
2476 * the link down because no IDLES are transmitted
2477 */
2478 }
2479 else {
2480 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2481 ("InitPhyLone: with auto-negotiation Port %d\n", Port));
2482 /* Set Auto-negotiation advertisement */
2483
2484 /* Set Full/half duplex capabilities */
2485 switch (pPrt->PLinkMode) {
2486 case SK_LMODE_AUTOHALF:
2487 Ctrl2 |= PHY_L_1000C_AHD;
2488 break;
2489 case SK_LMODE_AUTOFULL:
2490 Ctrl2 |= PHY_L_1000C_AFD;
2491 break;
2492 case SK_LMODE_AUTOBOTH:
2493 Ctrl2 |= PHY_L_1000C_AFD | PHY_L_1000C_AHD;
2494 break;
2495 default:
2496 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E015,
2497 SKERR_HWI_E015MSG);
2498 }
2499
2500 /* Set Flow-control capabilities */
2501 switch (pPrt->PFlowCtrlMode) {
2502 case SK_FLOW_MODE_NONE:
2503 Ctrl3 |= PHY_L_P_NO_PAUSE;
2504 break;
2505 case SK_FLOW_MODE_LOC_SEND:
2506 Ctrl3 |= PHY_L_P_ASYM_MD;
2507 break;
2508 case SK_FLOW_MODE_SYMMETRIC:
2509 Ctrl3 |= PHY_L_P_SYM_MD;
2510 break;
2511 case SK_FLOW_MODE_SYM_OR_REM:
2512 Ctrl3 |= PHY_L_P_BOTH_MD;
2513 break;
2514 default:
2515 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016,
2516 SKERR_HWI_E016MSG);
2517 }
2518
2519 /* Restart Auto-negotiation */
2520 Ctrl1 = PHY_CT_ANE | PHY_CT_RE_CFG;
2521 }
2522
2523 /* Write 1000Base-T Control Register */
2524 SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_1000T_CTRL, Ctrl2);
2525 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2526 ("1000B-T Ctrl Reg=0x%04X\n", Ctrl2));
2527
2528 /* Write AutoNeg Advertisement Register */
2529 SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_AUNE_ADV, Ctrl3);
2530 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2531 ("Auto-Neg.Adv.Reg=0x%04X\n", Ctrl3));
2532
2533 if (DoLoop) {
2534 /* Set the Phy Loopback bit, too */
2535 Ctrl1 |= PHY_CT_LOOP;
2536 }
2537
2538 /* Write to the Phy control register */
2539 SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_CTRL, Ctrl1);
2540 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2541 ("PHY Control Reg=0x%04X\n", Ctrl1));
2542} /* SkXmInitPhyLone */
2543
2544
2545/******************************************************************************
2546 *
2547 * SkXmInitPhyNat() - Initialize the National Phy registers
2548 *
2549 * Description: initializes all the National Phy registers
2550 *
2551 * Note:
2552 *
2553 * Returns:
2554 * nothing
2555 */
2556static void SkXmInitPhyNat(
2557SK_AC *pAC, /* adapter context */
2558SK_IOC IoC, /* IO context */
2559int Port, /* Port Index (MAC_1 + n) */
2560SK_BOOL DoLoop) /* Should a Phy LoopBack be set-up? */
2561{
2562/* todo: National */
2563} /* SkXmInitPhyNat */
2564#endif /* OTHER_PHY */
2565
2566
2567/******************************************************************************
2568 *
2569 * SkMacInitPhy() - Initialize the PHY registers
2570 *
2571 * Description: calls the Init PHY routines dep. on board type
2572 *
2573 * Note:
2574 *
2575 * Returns:
2576 * nothing
2577 */
2578void SkMacInitPhy(
2579SK_AC *pAC, /* adapter context */
2580SK_IOC IoC, /* IO context */
2581int Port, /* Port Index (MAC_1 + n) */
2582SK_BOOL DoLoop) /* Should a Phy LoopBack be set-up? */
2583{
2584 SK_GEPORT *pPrt;
2585
2586 pPrt = &pAC->GIni.GP[Port];
2587
2588#ifdef GENESIS
2589 if (pAC->GIni.GIGenesis) {
2590
2591 switch (pPrt->PhyType) {
2592 case SK_PHY_XMAC:
2593 SkXmInitPhyXmac(pAC, IoC, Port, DoLoop);
2594 break;
2595 case SK_PHY_BCOM:
2596 SkXmInitPhyBcom(pAC, IoC, Port, DoLoop);
2597 break;
2598#ifdef OTHER_PHY
2599 case SK_PHY_LONE:
2600 SkXmInitPhyLone(pAC, IoC, Port, DoLoop);
2601 break;
2602 case SK_PHY_NAT:
2603 SkXmInitPhyNat(pAC, IoC, Port, DoLoop);
2604 break;
2605#endif /* OTHER_PHY */
2606 }
2607 }
2608#endif /* GENESIS */
2609
2610#ifdef YUKON
2611 if (pAC->GIni.GIYukon) {
2612
2613 SkGmInitPhyMarv(pAC, IoC, Port, DoLoop);
2614 }
2615#endif /* YUKON */
2616
2617} /* SkMacInitPhy */
2618
2619
2620#ifdef GENESIS
2621/******************************************************************************
2622 *
2623 * SkXmAutoNegDoneXmac() - Auto-negotiation handling
2624 *
2625 * Description:
2626 * This function handles the auto-negotiation if the Done bit is set.
2627 *
2628 * Returns:
2629 * SK_AND_OK o.k.
2630 * SK_AND_DUP_CAP Duplex capability error happened
2631 * SK_AND_OTHER Other error happened
2632 */
2633static int SkXmAutoNegDoneXmac(
2634SK_AC *pAC, /* adapter context */
2635SK_IOC IoC, /* IO context */
2636int Port) /* Port Index (MAC_1 + n) */
2637{
2638 SK_GEPORT *pPrt;
2639 SK_U16 ResAb; /* Resolved Ability */
2640 SK_U16 LPAb; /* Link Partner Ability */
2641
2642 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2643 ("AutoNegDoneXmac, Port %d\n", Port));
2644
2645 pPrt = &pAC->GIni.GP[Port];
2646
2647 /* Get PHY parameters */
2648 SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_AUNE_LP, &LPAb);
2649 SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_RES_ABI, &ResAb);
2650
2651 if ((LPAb & PHY_X_AN_RFB) != 0) {
2652 /* At least one of the remote fault bit is set */
2653 /* Error */
2654 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2655 ("AutoNegFail: Remote fault bit set Port %d\n", Port));
2656 pPrt->PAutoNegFail = SK_TRUE;
2657 return(SK_AND_OTHER);
2658 }
2659
2660 /* Check Duplex mismatch */
2661 if ((ResAb & (PHY_X_RS_HD | PHY_X_RS_FD)) == PHY_X_RS_FD) {
2662 pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOFULL;
2663 }
2664 else if ((ResAb & (PHY_X_RS_HD | PHY_X_RS_FD)) == PHY_X_RS_HD) {
2665 pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOHALF;
2666 }
2667 else {
2668 /* Error */
2669 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2670 ("AutoNegFail: Duplex mode mismatch Port %d\n", Port));
2671 pPrt->PAutoNegFail = SK_TRUE;
2672 return(SK_AND_DUP_CAP);
2673 }
2674
2675 /* Check PAUSE mismatch */
2676 /* We are NOT using chapter 4.23 of the Xaqti manual */
2677 /* We are using IEEE 802.3z/D5.0 Table 37-4 */
2678 if ((pPrt->PFlowCtrlMode == SK_FLOW_MODE_SYMMETRIC ||
2679 pPrt->PFlowCtrlMode == SK_FLOW_MODE_SYM_OR_REM) &&
2680 (LPAb & PHY_X_P_SYM_MD) != 0) {
2681 /* Symmetric PAUSE */
2682 pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC;
2683 }
2684 else if (pPrt->PFlowCtrlMode == SK_FLOW_MODE_SYM_OR_REM &&
2685 (LPAb & PHY_X_RS_PAUSE) == PHY_X_P_ASYM_MD) {
2686 /* Enable PAUSE receive, disable PAUSE transmit */
2687 pPrt->PFlowCtrlStatus = SK_FLOW_STAT_REM_SEND;
2688 }
2689 else if (pPrt->PFlowCtrlMode == SK_FLOW_MODE_LOC_SEND &&
2690 (LPAb & PHY_X_RS_PAUSE) == PHY_X_P_BOTH_MD) {
2691 /* Disable PAUSE receive, enable PAUSE transmit */
2692 pPrt->PFlowCtrlStatus = SK_FLOW_STAT_LOC_SEND;
2693 }
2694 else {
2695 /* PAUSE mismatch -> no PAUSE */
2696 pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE;
2697 }
2698 pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_1000MBPS;
2699
2700 return(SK_AND_OK);
2701} /* SkXmAutoNegDoneXmac */
2702
2703
2704/******************************************************************************
2705 *
2706 * SkXmAutoNegDoneBcom() - Auto-negotiation handling
2707 *
2708 * Description:
2709 * This function handles the auto-negotiation if the Done bit is set.
2710 *
2711 * Returns:
2712 * SK_AND_OK o.k.
2713 * SK_AND_DUP_CAP Duplex capability error happened
2714 * SK_AND_OTHER Other error happened
2715 */
2716static int SkXmAutoNegDoneBcom(
2717SK_AC *pAC, /* adapter context */
2718SK_IOC IoC, /* IO context */
2719int Port) /* Port Index (MAC_1 + n) */
2720{
2721 SK_GEPORT *pPrt;
2722 SK_U16 LPAb; /* Link Partner Ability */
2723 SK_U16 AuxStat; /* Auxiliary Status */
2724
2725#ifdef TEST_ONLY
272601-Sep-2000 RA;:;:
2727 SK_U16 ResAb; /* Resolved Ability */
2728#endif /* 0 */
2729
2730 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2731 ("AutoNegDoneBcom, Port %d\n", Port));
2732 pPrt = &pAC->GIni.GP[Port];
2733
2734 /* Get PHY parameters */
2735 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_LP, &LPAb);
2736#ifdef TEST_ONLY
273701-Sep-2000 RA;:;:
2738 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &ResAb);
2739#endif /* 0 */
2740
2741 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_STAT, &AuxStat);
2742
2743 if ((LPAb & PHY_B_AN_RF) != 0) {
2744 /* Remote fault bit is set: Error */
2745 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2746 ("AutoNegFail: Remote fault bit set Port %d\n", Port));
2747 pPrt->PAutoNegFail = SK_TRUE;
2748 return(SK_AND_OTHER);
2749 }
2750
2751 /* Check Duplex mismatch */
2752 if ((AuxStat & PHY_B_AS_AN_RES_MSK) == PHY_B_RES_1000FD) {
2753 pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOFULL;
2754 }
2755 else if ((AuxStat & PHY_B_AS_AN_RES_MSK) == PHY_B_RES_1000HD) {
2756 pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOHALF;
2757 }
2758 else {
2759 /* Error */
2760 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2761 ("AutoNegFail: Duplex mode mismatch Port %d\n", Port));
2762 pPrt->PAutoNegFail = SK_TRUE;
2763 return(SK_AND_DUP_CAP);
2764 }
2765
2766#ifdef TEST_ONLY
276701-Sep-2000 RA;:;:
2768 /* Check Master/Slave resolution */
2769 if ((ResAb & PHY_B_1000S_MSF) != 0) {
2770 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2771 ("Master/Slave Fault Port %d\n", Port));
2772 pPrt->PAutoNegFail = SK_TRUE;
2773 pPrt->PMSStatus = SK_MS_STAT_FAULT;
2774 return(SK_AND_OTHER);
2775 }
2776
2777 pPrt->PMSStatus = ((ResAb & PHY_B_1000S_MSR) != 0) ?
2778 SK_MS_STAT_MASTER : SK_MS_STAT_SLAVE;
2779#endif /* 0 */
2780
2781 /* Check PAUSE mismatch ??? */
2782 /* We are using IEEE 802.3z/D5.0 Table 37-4 */
2783 if ((AuxStat & PHY_B_AS_PAUSE_MSK) == PHY_B_AS_PAUSE_MSK) {
2784 /* Symmetric PAUSE */
2785 pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC;
2786 }
2787 else if ((AuxStat & PHY_B_AS_PAUSE_MSK) == PHY_B_AS_PRR) {
2788 /* Enable PAUSE receive, disable PAUSE transmit */
2789 pPrt->PFlowCtrlStatus = SK_FLOW_STAT_REM_SEND;
2790 }
2791 else if ((AuxStat & PHY_B_AS_PAUSE_MSK) == PHY_B_AS_PRT) {
2792 /* Disable PAUSE receive, enable PAUSE transmit */
2793 pPrt->PFlowCtrlStatus = SK_FLOW_STAT_LOC_SEND;
2794 }
2795 else {
2796 /* PAUSE mismatch -> no PAUSE */
2797 pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE;
2798 }
2799 pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_1000MBPS;
2800
2801 return(SK_AND_OK);
2802} /* SkXmAutoNegDoneBcom */
2803#endif /* GENESIS */
2804
2805
2806#ifdef YUKON
2807/******************************************************************************
2808 *
2809 * SkGmAutoNegDoneMarv() - Auto-negotiation handling
2810 *
2811 * Description:
2812 * This function handles the auto-negotiation if the Done bit is set.
2813 *
2814 * Returns:
2815 * SK_AND_OK o.k.
2816 * SK_AND_DUP_CAP Duplex capability error happened
2817 * SK_AND_OTHER Other error happened
2818 */
2819static int SkGmAutoNegDoneMarv(
2820SK_AC *pAC, /* adapter context */
2821SK_IOC IoC, /* IO context */
2822int Port) /* Port Index (MAC_1 + n) */
2823{
2824 SK_GEPORT *pPrt;
2825 SK_U16 LPAb; /* Link Partner Ability */
2826 SK_U16 ResAb; /* Resolved Ability */
2827 SK_U16 AuxStat; /* Auxiliary Status */
2828
2829 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2830 ("AutoNegDoneMarv, Port %d\n", Port));
2831 pPrt = &pAC->GIni.GP[Port];
2832
2833 /* Get PHY parameters */
2834 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_LP, &LPAb);
2835 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2836 ("Link P.Abil.=0x%04X\n", LPAb));
2837
2838 if ((LPAb & PHY_M_AN_RF) != 0) {
2839 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2840 ("AutoNegFail: Remote fault bit set Port %d\n", Port));
2841 pPrt->PAutoNegFail = SK_TRUE;
2842 return(SK_AND_OTHER);
2843 }
2844
2845 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_1000T_STAT, &ResAb);
2846
2847 /* Check Master/Slave resolution */
2848 if ((ResAb & PHY_B_1000S_MSF) != 0) {
2849 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2850 ("Master/Slave Fault Port %d\n", Port));
2851 pPrt->PAutoNegFail = SK_TRUE;
2852 pPrt->PMSStatus = SK_MS_STAT_FAULT;
2853 return(SK_AND_OTHER);
2854 }
2855
2856 pPrt->PMSStatus = ((ResAb & PHY_B_1000S_MSR) != 0) ?
2857 (SK_U8)SK_MS_STAT_MASTER : (SK_U8)SK_MS_STAT_SLAVE;
2858
2859 /* Read PHY Specific Status */
2860 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_STAT, &AuxStat);
2861
2862 /* Check Speed & Duplex resolved */
2863 if ((AuxStat & PHY_M_PS_SPDUP_RES) == 0) {
2864 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2865 ("AutoNegFail: Speed & Duplex not resolved, Port %d\n", Port));
2866 pPrt->PAutoNegFail = SK_TRUE;
2867 pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_UNKNOWN;
2868 return(SK_AND_DUP_CAP);
2869 }
2870
2871 if ((AuxStat & PHY_M_PS_FULL_DUP) != 0) {
2872 pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOFULL;
2873 }
2874 else {
2875 pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOHALF;
2876 }
2877
2878 /* Check PAUSE mismatch ??? */
2879 /* We are using IEEE 802.3z/D5.0 Table 37-4 */
2880 if ((AuxStat & PHY_M_PS_PAUSE_MSK) == PHY_M_PS_PAUSE_MSK) {
2881 /* Symmetric PAUSE */
2882 pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC;
2883 }
2884 else if ((AuxStat & PHY_M_PS_PAUSE_MSK) == PHY_M_PS_RX_P_EN) {
2885 /* Enable PAUSE receive, disable PAUSE transmit */
2886 pPrt->PFlowCtrlStatus = SK_FLOW_STAT_REM_SEND;
2887 }
2888 else if ((AuxStat & PHY_M_PS_PAUSE_MSK) == PHY_M_PS_TX_P_EN) {
2889 /* Disable PAUSE receive, enable PAUSE transmit */
2890 pPrt->PFlowCtrlStatus = SK_FLOW_STAT_LOC_SEND;
2891 }
2892 else {
2893 /* PAUSE mismatch -> no PAUSE */
2894 pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE;
2895 }
2896
2897 /* set used link speed */
2898 switch ((unsigned)(AuxStat & PHY_M_PS_SPEED_MSK)) {
2899 case (unsigned)PHY_M_PS_SPEED_1000:
2900 pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_1000MBPS;
2901 break;
2902 case PHY_M_PS_SPEED_100:
2903 pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_100MBPS;
2904 break;
2905 default:
2906 pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_10MBPS;
2907 }
2908
2909 return(SK_AND_OK);
2910} /* SkGmAutoNegDoneMarv */
2911#endif /* YUKON */
2912
2913
2914#ifdef OTHER_PHY
2915/******************************************************************************
2916 *
2917 * SkXmAutoNegDoneLone() - Auto-negotiation handling
2918 *
2919 * Description:
2920 * This function handles the auto-negotiation if the Done bit is set.
2921 *
2922 * Returns:
2923 * SK_AND_OK o.k.
2924 * SK_AND_DUP_CAP Duplex capability error happened
2925 * SK_AND_OTHER Other error happened
2926 */
2927static int SkXmAutoNegDoneLone(
2928SK_AC *pAC, /* adapter context */
2929SK_IOC IoC, /* IO context */
2930int Port) /* Port Index (MAC_1 + n) */
2931{
2932 SK_GEPORT *pPrt;
2933 SK_U16 ResAb; /* Resolved Ability */
2934 SK_U16 LPAb; /* Link Partner Ability */
2935 SK_U16 QuickStat; /* Auxiliary Status */
2936
2937 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2938 ("AutoNegDoneLone, Port %d\n", Port));
2939 pPrt = &pAC->GIni.GP[Port];
2940
2941 /* Get PHY parameters */
2942 SkXmPhyRead(pAC, IoC, Port, PHY_LONE_AUNE_LP, &LPAb);
2943 SkXmPhyRead(pAC, IoC, Port, PHY_LONE_1000T_STAT, &ResAb);
2944 SkXmPhyRead(pAC, IoC, Port, PHY_LONE_Q_STAT, &QuickStat);
2945
2946 if ((LPAb & PHY_L_AN_RF) != 0) {
2947 /* Remote fault bit is set */
2948 /* Error */
2949 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2950 ("AutoNegFail: Remote fault bit set Port %d\n", Port));
2951 pPrt->PAutoNegFail = SK_TRUE;
2952 return(SK_AND_OTHER);
2953 }
2954
2955 /* Check Duplex mismatch */
2956 if ((QuickStat & PHY_L_QS_DUP_MOD) != 0) {
2957 pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOFULL;
2958 }
2959 else {
2960 pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOHALF;
2961 }
2962
2963 /* Check Master/Slave resolution */
2964 if ((ResAb & PHY_L_1000S_MSF) != 0) {
2965 /* Error */
2966 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
2967 ("Master/Slave Fault Port %d\n", Port));
2968 pPrt->PAutoNegFail = SK_TRUE;
2969 pPrt->PMSStatus = SK_MS_STAT_FAULT;
2970 return(SK_AND_OTHER);
2971 }
2972 else if (ResAb & PHY_L_1000S_MSR) {
2973 pPrt->PMSStatus = SK_MS_STAT_MASTER;
2974 }
2975 else {
2976 pPrt->PMSStatus = SK_MS_STAT_SLAVE;
2977 }
2978
2979 /* Check PAUSE mismatch */
2980 /* We are using IEEE 802.3z/D5.0 Table 37-4 */
2981 /* we must manually resolve the abilities here */
2982 pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE;
2983
2984 switch (pPrt->PFlowCtrlMode) {
2985 case SK_FLOW_MODE_NONE:
2986 /* default */
2987 break;
2988 case SK_FLOW_MODE_LOC_SEND:
2989 if ((QuickStat & (PHY_L_QS_PAUSE | PHY_L_QS_AS_PAUSE)) ==
2990 (PHY_L_QS_PAUSE | PHY_L_QS_AS_PAUSE)) {
2991 /* Disable PAUSE receive, enable PAUSE transmit */
2992 pPrt->PFlowCtrlStatus = SK_FLOW_STAT_LOC_SEND;
2993 }
2994 break;
2995 case SK_FLOW_MODE_SYMMETRIC:
2996 if ((QuickStat & PHY_L_QS_PAUSE) != 0) {
2997 /* Symmetric PAUSE */
2998 pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC;
2999 }
3000 break;
3001 case SK_FLOW_MODE_SYM_OR_REM:
3002 if ((QuickStat & (PHY_L_QS_PAUSE | PHY_L_QS_AS_PAUSE)) ==
3003 PHY_L_QS_AS_PAUSE) {
3004 /* Enable PAUSE receive, disable PAUSE transmit */
3005 pPrt->PFlowCtrlStatus = SK_FLOW_STAT_REM_SEND;
3006 }
3007 else if ((QuickStat & PHY_L_QS_PAUSE) != 0) {
3008 /* Symmetric PAUSE */
3009 pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC;
3010 }
3011 break;
3012 default:
3013 SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016,
3014 SKERR_HWI_E016MSG);
3015 }
3016
3017 return(SK_AND_OK);
3018} /* SkXmAutoNegDoneLone */
3019
3020
3021/******************************************************************************
3022 *
3023 * SkXmAutoNegDoneNat() - Auto-negotiation handling
3024 *
3025 * Description:
3026 * This function handles the auto-negotiation if the Done bit is set.
3027 *
3028 * Returns:
3029 * SK_AND_OK o.k.
3030 * SK_AND_DUP_CAP Duplex capability error happened
3031 * SK_AND_OTHER Other error happened
3032 */
3033static int SkXmAutoNegDoneNat(
3034SK_AC *pAC, /* adapter context */
3035SK_IOC IoC, /* IO context */
3036int Port) /* Port Index (MAC_1 + n) */
3037{
3038/* todo: National */
3039 return(SK_AND_OK);
3040} /* SkXmAutoNegDoneNat */
3041#endif /* OTHER_PHY */
3042
3043
3044/******************************************************************************
3045 *
3046 * SkMacAutoNegDone() - Auto-negotiation handling
3047 *
3048 * Description: calls the auto-negotiation done routines dep. on board type
3049 *
3050 * Returns:
3051 * SK_AND_OK o.k.
3052 * SK_AND_DUP_CAP Duplex capability error happened
3053 * SK_AND_OTHER Other error happened
3054 */
3055int SkMacAutoNegDone(
3056SK_AC *pAC, /* adapter context */
3057SK_IOC IoC, /* IO context */
3058int Port) /* Port Index (MAC_1 + n) */
3059{
3060 SK_GEPORT *pPrt;
3061 int Rtv;
3062
3063 Rtv = SK_AND_OK;
3064
3065 pPrt = &pAC->GIni.GP[Port];
3066
3067#ifdef GENESIS
3068 if (pAC->GIni.GIGenesis) {
3069
3070 switch (pPrt->PhyType) {
3071
3072 case SK_PHY_XMAC:
3073 Rtv = SkXmAutoNegDoneXmac(pAC, IoC, Port);
3074 break;
3075 case SK_PHY_BCOM:
3076 Rtv = SkXmAutoNegDoneBcom(pAC, IoC, Port);
3077 break;
3078#ifdef OTHER_PHY
3079 case SK_PHY_LONE:
3080 Rtv = SkXmAutoNegDoneLone(pAC, IoC, Port);
3081 break;
3082 case SK_PHY_NAT:
3083 Rtv = SkXmAutoNegDoneNat(pAC, IoC, Port);
3084 break;
3085#endif /* OTHER_PHY */
3086 default:
3087 return(SK_AND_OTHER);
3088 }
3089 }
3090#endif /* GENESIS */
3091
3092#ifdef YUKON
3093 if (pAC->GIni.GIYukon) {
3094
3095 Rtv = SkGmAutoNegDoneMarv(pAC, IoC, Port);
3096 }
3097#endif /* YUKON */
3098
3099 if (Rtv != SK_AND_OK) {
3100 return(Rtv);
3101 }
3102
3103 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
3104 ("AutoNeg done Port %d\n", Port));
3105
3106 /* We checked everything and may now enable the link */
3107 pPrt->PAutoNegFail = SK_FALSE;
3108
3109 SkMacRxTxEnable(pAC, IoC, Port);
3110
3111 return(SK_AND_OK);
3112} /* SkMacAutoNegDone */
3113
3114
3115/******************************************************************************
3116 *
3117 * SkMacRxTxEnable() - Enable Rx/Tx activity if port is up
3118 *
3119 * Description: enables Rx/Tx dep. on board type
3120 *
3121 * Returns:
3122 * 0 o.k.
3123 * != 0 Error happened
3124 */
3125int SkMacRxTxEnable(
3126SK_AC *pAC, /* adapter context */
3127SK_IOC IoC, /* IO context */
3128int Port) /* Port Index (MAC_1 + n) */
3129{
3130 SK_GEPORT *pPrt;
3131 SK_U16 Reg; /* 16-bit register value */
3132 SK_U16 IntMask; /* MAC interrupt mask */
3133#ifdef GENESIS
3134 SK_U16 SWord;
3135#endif
3136
3137 pPrt = &pAC->GIni.GP[Port];
3138
3139 if (!pPrt->PHWLinkUp) {
3140 /* The Hardware link is NOT up */
3141 return(0);
3142 }
3143
3144 if ((pPrt->PLinkMode == SK_LMODE_AUTOHALF ||
3145 pPrt->PLinkMode == SK_LMODE_AUTOFULL ||
3146 pPrt->PLinkMode == SK_LMODE_AUTOBOTH) &&
3147 pPrt->PAutoNegFail) {
3148 /* Auto-negotiation is not done or failed */
3149 return(0);
3150 }
3151
3152#ifdef GENESIS
3153 if (pAC->GIni.GIGenesis) {
3154 /* set Duplex Mode and Pause Mode */
3155 SkXmInitDupMd(pAC, IoC, Port);
3156
3157 SkXmInitPauseMd(pAC, IoC, Port);
3158
3159 /*
3160 * Initialize the Interrupt Mask Register. Default IRQs are...
3161 * - Link Asynchronous Event
3162 * - Link Partner requests config
3163 * - Auto Negotiation Done
3164 * - Rx Counter Event Overflow
3165 * - Tx Counter Event Overflow
3166 * - Transmit FIFO Underrun
3167 */
3168 IntMask = XM_DEF_MSK;
3169
3170#ifdef DEBUG
3171 /* add IRQ for Receive FIFO Overflow */
3172 IntMask &= ~XM_IS_RXF_OV;
3173#endif /* DEBUG */
3174
3175 if (pPrt->PhyType != SK_PHY_XMAC) {
3176 /* disable GP0 interrupt bit */
3177 IntMask |= XM_IS_INP_ASS;
3178 }
3179 XM_OUT16(IoC, Port, XM_IMSK, IntMask);
3180
3181 /* get MMU Command Reg. */
3182 XM_IN16(IoC, Port, XM_MMU_CMD, &Reg);
3183
3184 if (pPrt->PhyType != SK_PHY_XMAC &&
3185 (pPrt->PLinkModeStatus == SK_LMODE_STAT_FULL ||
3186 pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOFULL)) {
3187 /* set to Full Duplex */
3188 Reg |= XM_MMU_GMII_FD;
3189 }
3190
3191 switch (pPrt->PhyType) {
3192 case SK_PHY_BCOM:
3193 /*
3194 * Workaround BCOM Errata (#10523) for all BCom Phys
3195 * Enable Power Management after link up
3196 */
3197 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &SWord);
3198 SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUX_CTRL,
3199 (SK_U16)(SWord & ~PHY_B_AC_DIS_PM));
3200 SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_INT_MASK,
3201 (SK_U16)PHY_B_DEF_MSK);
3202 break;
3203#ifdef OTHER_PHY
3204 case SK_PHY_LONE:
3205 SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_INT_ENAB, PHY_L_DEF_MSK);
3206 break;
3207 case SK_PHY_NAT:
3208 /* todo National:
3209 SkXmPhyWrite(pAC, IoC, Port, PHY_NAT_INT_MASK, PHY_N_DEF_MSK); */
3210 /* no interrupts possible from National ??? */
3211 break;
3212#endif /* OTHER_PHY */
3213 }
3214
3215 /* enable Rx/Tx */
3216 XM_OUT16(IoC, Port, XM_MMU_CMD, Reg | XM_MMU_ENA_RX | XM_MMU_ENA_TX);
3217 }
3218#endif /* GENESIS */
3219
3220#ifdef YUKON
3221 if (pAC->GIni.GIYukon) {
3222 /*
3223 * Initialize the Interrupt Mask Register. Default IRQs are...
3224 * - Rx Counter Event Overflow
3225 * - Tx Counter Event Overflow
3226 * - Transmit FIFO Underrun
3227 */
3228 IntMask = GMAC_DEF_MSK;
3229
3230#ifdef DEBUG
3231 /* add IRQ for Receive FIFO Overrun */
3232 IntMask |= GM_IS_RX_FF_OR;
3233#endif /* DEBUG */
3234
3235 SK_OUT8(IoC, GMAC_IRQ_MSK, (SK_U8)IntMask);
3236
3237 /* get General Purpose Control */
3238 GM_IN16(IoC, Port, GM_GP_CTRL, &Reg);
3239
3240 if (pPrt->PLinkModeStatus == SK_LMODE_STAT_FULL ||
3241 pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOFULL) {
3242 /* set to Full Duplex */
3243 Reg |= GM_GPCR_DUP_FULL;
3244 }
3245
3246 /* enable Rx/Tx */
3247 GM_OUT16(IoC, Port, GM_GP_CTRL, (SK_U16)(Reg | GM_GPCR_RX_ENA |
3248 GM_GPCR_TX_ENA));
3249
3250#ifndef VCPU
3251 /* Enable all PHY interrupts */
3252 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_INT_MASK,
3253 (SK_U16)PHY_M_DEF_MSK);
3254#endif /* VCPU */
3255 }
3256#endif /* YUKON */
3257
3258 return(0);
3259
3260} /* SkMacRxTxEnable */
3261
3262
3263/******************************************************************************
3264 *
3265 * SkMacRxTxDisable() - Disable Receiver and Transmitter
3266 *
3267 * Description: disables Rx/Tx dep. on board type
3268 *
3269 * Returns: N/A
3270 */
3271void SkMacRxTxDisable(
3272SK_AC *pAC, /* Adapter Context */
3273SK_IOC IoC, /* IO context */
3274int Port) /* Port Index (MAC_1 + n) */
3275{
3276 SK_U16 Word;
3277
3278#ifdef GENESIS
3279 if (pAC->GIni.GIGenesis) {
3280
3281 XM_IN16(IoC, Port, XM_MMU_CMD, &Word);
3282
3283 XM_OUT16(IoC, Port, XM_MMU_CMD, Word & ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX));
3284
3285 /* dummy read to ensure writing */
3286 XM_IN16(IoC, Port, XM_MMU_CMD, &Word);
3287 }
3288#endif /* GENESIS */
3289
3290#ifdef YUKON
3291 if (pAC->GIni.GIYukon) {
3292
3293 GM_IN16(IoC, Port, GM_GP_CTRL, &Word);
3294
3295 GM_OUT16(IoC, Port, GM_GP_CTRL, (SK_U16)(Word & ~(GM_GPCR_RX_ENA |
3296 GM_GPCR_TX_ENA)));
3297
3298 /* dummy read to ensure writing */
3299 GM_IN16(IoC, Port, GM_GP_CTRL, &Word);
3300 }
3301#endif /* YUKON */
3302
3303} /* SkMacRxTxDisable */
3304
3305
3306/******************************************************************************
3307 *
3308 * SkMacIrqDisable() - Disable IRQ from MAC
3309 *
3310 * Description: sets the IRQ-mask to disable IRQ dep. on board type
3311 *
3312 * Returns: N/A
3313 */
3314void SkMacIrqDisable(
3315SK_AC *pAC, /* Adapter Context */
3316SK_IOC IoC, /* IO context */
3317int Port) /* Port Index (MAC_1 + n) */
3318{
3319 SK_GEPORT *pPrt;
3320#ifdef GENESIS
3321 SK_U16 Word;
3322#endif
3323
3324 pPrt = &pAC->GIni.GP[Port];
3325
3326#ifdef GENESIS
3327 if (pAC->GIni.GIGenesis) {
3328
3329 /* disable all XMAC IRQs */
3330 XM_OUT16(IoC, Port, XM_IMSK, 0xffff);
3331
3332 /* Disable all PHY interrupts */
3333 switch (pPrt->PhyType) {
3334 case SK_PHY_BCOM:
3335 /* Make sure that PHY is initialized */
3336 if (pPrt->PState != SK_PRT_RESET) {
3337 /* NOT allowed if BCOM is in RESET state */
3338 /* Workaround BCOM Errata (#10523) all BCom */
3339 /* Disable Power Management if link is down */
3340 SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &Word);
3341 SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUX_CTRL,
3342 (SK_U16)(Word | PHY_B_AC_DIS_PM));
3343 SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_INT_MASK, 0xffff);
3344 }
3345 break;
3346#ifdef OTHER_PHY
3347 case SK_PHY_LONE:
3348 SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_INT_ENAB, 0);
3349 break;
3350 case SK_PHY_NAT:
3351 /* todo: National
3352 SkXmPhyWrite(pAC, IoC, Port, PHY_NAT_INT_MASK, 0xffff); */
3353 break;
3354#endif /* OTHER_PHY */
3355 }
3356 }
3357#endif /* GENESIS */
3358
3359#ifdef YUKON
3360 if (pAC->GIni.GIYukon) {
3361 /* disable all GMAC IRQs */
3362 SK_OUT8(IoC, GMAC_IRQ_MSK, 0);
3363
3364#ifndef VCPU
3365 /* Disable all PHY interrupts */
3366 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_INT_MASK, 0);
3367#endif /* VCPU */
3368 }
3369#endif /* YUKON */
3370
3371} /* SkMacIrqDisable */
3372
3373
3374#ifdef SK_DIAG
3375/******************************************************************************
3376 *
3377 * SkXmSendCont() - Enable / Disable Send Continuous Mode
3378 *
3379 * Description: enable / disable Send Continuous Mode on XMAC
3380 *
3381 * Returns:
3382 * nothing
3383 */
3384void SkXmSendCont(
3385SK_AC *pAC, /* adapter context */
3386SK_IOC IoC, /* IO context */
3387int Port, /* Port Index (MAC_1 + n) */
3388SK_BOOL Enable) /* Enable / Disable */
3389{
3390 SK_U32 MdReg;
3391
3392 XM_IN32(IoC, Port, XM_MODE, &MdReg);
3393
3394 if (Enable) {
3395 MdReg |= XM_MD_TX_CONT;
3396 }
3397 else {
3398 MdReg &= ~XM_MD_TX_CONT;
3399 }
3400 /* setup Mode Register */
3401 XM_OUT32(IoC, Port, XM_MODE, MdReg);
3402
3403} /* SkXmSendCont */
3404
3405
3406/******************************************************************************
3407 *
3408 * SkMacTimeStamp() - Enable / Disable Time Stamp
3409 *
3410 * Description: enable / disable Time Stamp generation for Rx packets
3411 *
3412 * Returns:
3413 * nothing
3414 */
3415void SkMacTimeStamp(
3416SK_AC *pAC, /* adapter context */
3417SK_IOC IoC, /* IO context */
3418int Port, /* Port Index (MAC_1 + n) */
3419SK_BOOL Enable) /* Enable / Disable */
3420{
3421 SK_U32 MdReg;
3422 SK_U8 TimeCtrl;
3423
3424 if (pAC->GIni.GIGenesis) {
3425
3426 XM_IN32(IoC, Port, XM_MODE, &MdReg);
3427
3428 if (Enable) {
3429 MdReg |= XM_MD_ATS;
3430 }
3431 else {
3432 MdReg &= ~XM_MD_ATS;
3433 }
3434 /* setup Mode Register */
3435 XM_OUT32(IoC, Port, XM_MODE, MdReg);
3436 }
3437 else {
3438 if (Enable) {
3439 TimeCtrl = GMT_ST_START | GMT_ST_CLR_IRQ;
3440 }
3441 else {
3442 TimeCtrl = GMT_ST_STOP | GMT_ST_CLR_IRQ;
3443 }
3444 /* Start/Stop Time Stamp Timer */
3445 SK_OUT8(IoC, GMAC_TI_ST_CTRL, TimeCtrl);
3446 }
3447
3448} /* SkMacTimeStamp*/
3449
3450#else /* !SK_DIAG */
3451
3452#ifdef GENESIS
3453/******************************************************************************
3454 *
3455 * SkXmAutoNegLipaXmac() - Decides whether Link Partner could do auto-neg
3456 *
3457 * This function analyses the Interrupt status word. If any of the
3458 * Auto-negotiating interrupt bits are set, the PLipaAutoNeg variable
3459 * is set true.
3460 */
3461void SkXmAutoNegLipaXmac(
3462SK_AC *pAC, /* adapter context */
3463SK_IOC IoC, /* IO context */
3464int Port, /* Port Index (MAC_1 + n) */
3465SK_U16 IStatus) /* Interrupt Status word to analyse */
3466{
3467 SK_GEPORT *pPrt;
3468
3469 pPrt = &pAC->GIni.GP[Port];
3470
3471 if (pPrt->PLipaAutoNeg != SK_LIPA_AUTO &&
3472 (IStatus & (XM_IS_LIPA_RC | XM_IS_RX_PAGE | XM_IS_AND)) != 0) {
3473
3474 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
3475 ("AutoNegLipa: AutoNeg detected on Port %d, IStatus=0x%04X\n",
3476 Port, IStatus));
3477 pPrt->PLipaAutoNeg = SK_LIPA_AUTO;
3478 }
3479} /* SkXmAutoNegLipaXmac */
3480#endif /* GENESIS */
3481
3482
3483/******************************************************************************
3484 *
3485 * SkMacAutoNegLipaPhy() - Decides whether Link Partner could do auto-neg
3486 *
3487 * This function analyses the PHY status word.
3488 * If any of the Auto-negotiating bits are set, the PLipaAutoNeg variable
3489 * is set true.
3490 */
3491void SkMacAutoNegLipaPhy(
3492SK_AC *pAC, /* adapter context */
3493SK_IOC IoC, /* IO context */
3494int Port, /* Port Index (MAC_1 + n) */
3495SK_U16 PhyStat) /* PHY Status word to analyse */
3496{
3497 SK_GEPORT *pPrt;
3498
3499 pPrt = &pAC->GIni.GP[Port];
3500
3501 if (pPrt->PLipaAutoNeg != SK_LIPA_AUTO &&
3502 (PhyStat & PHY_ST_AN_OVER) != 0) {
3503
3504 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
3505 ("AutoNegLipa: AutoNeg detected on Port %d, PhyStat=0x%04X\n",
3506 Port, PhyStat));
3507 pPrt->PLipaAutoNeg = SK_LIPA_AUTO;
3508 }
3509} /* SkMacAutoNegLipaPhy */
3510
3511
3512#ifdef GENESIS
3513/******************************************************************************
3514 *
3515 * SkXmIrq() - Interrupt Service Routine
3516 *
3517 * Description: services an Interrupt Request of the XMAC
3518 *
3519 * Note:
3520 * With an external PHY, some interrupt bits are not meaningfull any more:
3521 * - LinkAsyncEvent (bit #14) XM_IS_LNK_AE
3522 * - LinkPartnerReqConfig (bit #10) XM_IS_LIPA_RC
3523 * - Page Received (bit #9) XM_IS_RX_PAGE
3524 * - NextPageLoadedForXmt (bit #8) XM_IS_TX_PAGE
3525 * - AutoNegDone (bit #7) XM_IS_AND
3526 * Also probably not valid any more is the GP0 input bit:
3527 * - GPRegisterBit0set XM_IS_INP_ASS
3528 *
3529 * Returns:
3530 * nothing
3531 */
3532static void SkXmIrq(
3533SK_AC *pAC, /* adapter context */
3534SK_IOC IoC, /* IO context */
3535int Port) /* Port Index (MAC_1 + n) */
3536{
3537 SK_GEPORT *pPrt;
3538 SK_EVPARA Para;
3539 SK_U16 IStatus; /* Interrupt status read from the XMAC */
3540 SK_U16 IStatus2;
3541#ifdef SK_SLIM
3542 SK_U64 OverflowStatus;
3543#endif
3544
3545 pPrt = &pAC->GIni.GP[Port];
3546
3547 XM_IN16(IoC, Port, XM_ISRC, &IStatus);
3548
3549 /* LinkPartner Auto-negable? */
3550 if (pPrt->PhyType == SK_PHY_XMAC) {
3551 SkXmAutoNegLipaXmac(pAC, IoC, Port, IStatus);
3552 }
3553 else {
3554 /* mask bits that are not used with ext. PHY */
3555 IStatus &= ~(XM_IS_LNK_AE | XM_IS_LIPA_RC |
3556 XM_IS_RX_PAGE | XM_IS_TX_PAGE |
3557 XM_IS_AND | XM_IS_INP_ASS);
3558 }
3559
3560 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
3561 ("XmacIrq Port %d Isr 0x%04X\n", Port, IStatus));
3562
3563 if (!pPrt->PHWLinkUp) {
3564 /* Spurious XMAC interrupt */
3565 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
3566 ("SkXmIrq: spurious interrupt on Port %d\n", Port));
3567 return;
3568 }
3569
3570 if ((IStatus & XM_IS_INP_ASS) != 0) {
3571 /* Reread ISR Register if link is not in sync */
3572 XM_IN16(IoC, Port, XM_ISRC, &IStatus2);
3573
3574 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
3575 ("SkXmIrq: Link async. Double check Port %d 0x%04X 0x%04X\n",
3576 Port, IStatus, IStatus2));
3577 IStatus &= ~XM_IS_INP_ASS;
3578 IStatus |= IStatus2;
3579 }
3580
3581 if ((IStatus & XM_IS_LNK_AE) != 0) {
3582 /* not used, GP0 is used instead */
3583 }
3584
3585 if ((IStatus & XM_IS_TX_ABORT) != 0) {
3586 /* not used */
3587 }
3588
3589 if ((IStatus & XM_IS_FRC_INT) != 0) {
3590 /* not used, use ASIC IRQ instead if needed */
3591 }
3592
3593 if ((IStatus & (XM_IS_INP_ASS | XM_IS_LIPA_RC | XM_IS_RX_PAGE)) != 0) {
3594 SkHWLinkDown(pAC, IoC, Port);
3595
3596 /* Signal to RLMT */
3597 Para.Para32[0] = (SK_U32)Port;
3598 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para);
3599
3600 /* Start workaround Errata #2 timer */
3601 SkTimerStart(pAC, IoC, &pPrt->PWaTimer, SK_WA_INA_TIME,
3602 SKGE_HWAC, SK_HWEV_WATIM, Para);
3603 }
3604
3605 if ((IStatus & XM_IS_RX_PAGE) != 0) {
3606 /* not used */
3607 }
3608
3609 if ((IStatus & XM_IS_TX_PAGE) != 0) {
3610 /* not used */
3611 }
3612
3613 if ((IStatus & XM_IS_AND) != 0) {
3614 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
3615 ("SkXmIrq: AND on link that is up Port %d\n", Port));
3616 }
3617
3618 if ((IStatus & XM_IS_TSC_OV) != 0) {
3619 /* not used */
3620 }
3621
3622 /* Combined Tx & Rx Counter Overflow SIRQ Event */
3623 if ((IStatus & (XM_IS_RXC_OV | XM_IS_TXC_OV)) != 0) {
3624#ifdef SK_SLIM
3625 SkXmOverflowStatus(pAC, IoC, Port, IStatus, &OverflowStatus);
3626#else
3627 Para.Para32[0] = (SK_U32)Port;
3628 Para.Para32[1] = (SK_U32)IStatus;
3629 SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_SIRQ_OVERFLOW, Para);
3630#endif /* SK_SLIM */
3631 }
3632
3633 if ((IStatus & XM_IS_RXF_OV) != 0) {
3634 /* normal situation -> no effect */
3635#ifdef DEBUG
3636 pPrt->PRxOverCnt++;
3637#endif /* DEBUG */
3638 }
3639
3640 if ((IStatus & XM_IS_TXF_UR) != 0) {
3641 /* may NOT happen -> error log */
3642 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E020, SKERR_SIRQ_E020MSG);
3643 }
3644
3645 if ((IStatus & XM_IS_TX_COMP) != 0) {
3646 /* not served here */
3647 }
3648
3649 if ((IStatus & XM_IS_RX_COMP) != 0) {
3650 /* not served here */
3651 }
3652} /* SkXmIrq */
3653#endif /* GENESIS */
3654
3655
3656#ifdef YUKON
3657/******************************************************************************
3658 *
3659 * SkGmIrq() - Interrupt Service Routine
3660 *
3661 * Description: services an Interrupt Request of the GMAC
3662 *
3663 * Note:
3664 *
3665 * Returns:
3666 * nothing
3667 */
3668static void SkGmIrq(
3669SK_AC *pAC, /* adapter context */
3670SK_IOC IoC, /* IO context */
3671int Port) /* Port Index (MAC_1 + n) */
3672{
3673 SK_GEPORT *pPrt;
3674 SK_U8 IStatus; /* Interrupt status */
3675#ifdef SK_SLIM
3676 SK_U64 OverflowStatus;
3677#else
3678 SK_EVPARA Para;
3679#endif
3680
3681 pPrt = &pAC->GIni.GP[Port];
3682
3683 SK_IN8(IoC, GMAC_IRQ_SRC, &IStatus);
3684
3685#ifdef XXX
3686 /* LinkPartner Auto-negable? */
3687 SkMacAutoNegLipaPhy(pAC, IoC, Port, IStatus);
3688#endif /* XXX */
3689
3690 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ,
3691 ("GmacIrq Port %d Isr 0x%04X\n", Port, IStatus));
3692
3693 /* Combined Tx & Rx Counter Overflow SIRQ Event */
3694 if (IStatus & (GM_IS_RX_CO_OV | GM_IS_TX_CO_OV)) {
3695 /* these IRQs will be cleared by reading GMACs register */
3696#ifdef SK_SLIM
3697 SkGmOverflowStatus(pAC, IoC, Port, IStatus, &OverflowStatus);
3698#else
3699 Para.Para32[0] = (SK_U32)Port;
3700 Para.Para32[1] = (SK_U32)IStatus;
3701 SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_SIRQ_OVERFLOW, Para);
3702#endif
3703 }
3704
3705 if (IStatus & GM_IS_RX_FF_OR) {
3706 /* clear GMAC Rx FIFO Overrun IRQ */
3707 SK_OUT8(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), (SK_U8)GMF_CLI_RX_FO);
3708#ifdef DEBUG
3709 pPrt->PRxOverCnt++;
3710#endif /* DEBUG */
3711 }
3712
3713 if (IStatus & GM_IS_TX_FF_UR) {
3714 /* clear GMAC Tx FIFO Underrun IRQ */
3715 SK_OUT8(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), (SK_U8)GMF_CLI_TX_FU);
3716 /* may NOT happen -> error log */
3717 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E020, SKERR_SIRQ_E020MSG);
3718 }
3719
3720 if (IStatus & GM_IS_TX_COMPL) {
3721 /* not served here */
3722 }
3723
3724 if (IStatus & GM_IS_RX_COMPL) {
3725 /* not served here */
3726 }
3727} /* SkGmIrq */
3728#endif /* YUKON */
3729
3730
3731/******************************************************************************
3732 *
3733 * SkMacIrq() - Interrupt Service Routine for MAC
3734 *
3735 * Description: calls the Interrupt Service Routine dep. on board type
3736 *
3737 * Returns:
3738 * nothing
3739 */
3740void SkMacIrq(
3741SK_AC *pAC, /* adapter context */
3742SK_IOC IoC, /* IO context */
3743int Port) /* Port Index (MAC_1 + n) */
3744{
3745#ifdef GENESIS
3746 if (pAC->GIni.GIGenesis) {
3747 /* IRQ from XMAC */
3748 SkXmIrq(pAC, IoC, Port);
3749 }
3750#endif /* GENESIS */
3751
3752#ifdef YUKON
3753 if (pAC->GIni.GIYukon) {
3754 /* IRQ from GMAC */
3755 SkGmIrq(pAC, IoC, Port);
3756 }
3757#endif /* YUKON */
3758
3759} /* SkMacIrq */
3760
3761#endif /* !SK_DIAG */
3762
3763#ifdef GENESIS
3764/******************************************************************************
3765 *
3766 * SkXmUpdateStats() - Force the XMAC to output the current statistic
3767 *
3768 * Description:
3769 * The XMAC holds its statistic internally. To obtain the current
3770 * values a command must be sent so that the statistic data will
3771 * be written to a predefined memory area on the adapter.
3772 *
3773 * Returns:
3774 * 0: success
3775 * 1: something went wrong
3776 */
3777int SkXmUpdateStats(
3778SK_AC *pAC, /* adapter context */
3779SK_IOC IoC, /* IO context */
3780unsigned int Port) /* Port Index (MAC_1 + n) */
3781{
3782 SK_GEPORT *pPrt;
3783 SK_U16 StatReg;
3784 int WaitIndex;
3785
3786 pPrt = &pAC->GIni.GP[Port];
3787 WaitIndex = 0;
3788
3789 /* Send an update command to XMAC specified */
3790 XM_OUT16(IoC, Port, XM_STAT_CMD, XM_SC_SNP_TXC | XM_SC_SNP_RXC);
3791
3792 /*
3793 * It is an auto-clearing register. If the command bits
3794 * went to zero again, the statistics are transferred.
3795 * Normally the command should be executed immediately.
3796 * But just to be sure we execute a loop.
3797 */
3798 do {
3799
3800 XM_IN16(IoC, Port, XM_STAT_CMD, &StatReg);
3801
3802 if (++WaitIndex > 10) {
3803
3804 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_HWI_E021, SKERR_HWI_E021MSG);
3805
3806 return(1);
3807 }
3808 } while ((StatReg & (XM_SC_SNP_TXC | XM_SC_SNP_RXC)) != 0);
3809
3810 return(0);
3811} /* SkXmUpdateStats */
3812
3813
3814/******************************************************************************
3815 *
3816 * SkXmMacStatistic() - Get XMAC counter value
3817 *
3818 * Description:
3819 * Gets the 32bit counter value. Except for the octet counters
3820 * the lower 32bit are counted in hardware and the upper 32bit
3821 * must be counted in software by monitoring counter overflow interrupts.
3822 *
3823 * Returns:
3824 * 0: success
3825 * 1: something went wrong
3826 */
3827int SkXmMacStatistic(
3828SK_AC *pAC, /* adapter context */
3829SK_IOC IoC, /* IO context */
3830unsigned int Port, /* Port Index (MAC_1 + n) */
3831SK_U16 StatAddr, /* MIB counter base address */
3832SK_U32 SK_FAR *pVal) /* ptr to return statistic value */
3833{
3834 if ((StatAddr < XM_TXF_OK) || (StatAddr > XM_RXF_MAX_SZ)) {
3835
3836 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E022, SKERR_HWI_E022MSG);
3837
3838 return(1);
3839 }
3840
3841 XM_IN32(IoC, Port, StatAddr, pVal);
3842
3843 return(0);
3844} /* SkXmMacStatistic */
3845
3846
3847/******************************************************************************
3848 *
3849 * SkXmResetCounter() - Clear MAC statistic counter
3850 *
3851 * Description:
3852 * Force the XMAC to clear its statistic counter.
3853 *
3854 * Returns:
3855 * 0: success
3856 * 1: something went wrong
3857 */
3858int SkXmResetCounter(
3859SK_AC *pAC, /* adapter context */
3860SK_IOC IoC, /* IO context */
3861unsigned int Port) /* Port Index (MAC_1 + n) */
3862{
3863 XM_OUT16(IoC, Port, XM_STAT_CMD, XM_SC_CLR_RXC | XM_SC_CLR_TXC);
3864 /* Clear two times according to Errata #3 */
3865 XM_OUT16(IoC, Port, XM_STAT_CMD, XM_SC_CLR_RXC | XM_SC_CLR_TXC);
3866
3867 return(0);
3868} /* SkXmResetCounter */
3869
3870
3871/******************************************************************************
3872 *
3873 * SkXmOverflowStatus() - Gets the status of counter overflow interrupt
3874 *
3875 * Description:
3876 * Checks the source causing an counter overflow interrupt. On success the
3877 * resulting counter overflow status is written to <pStatus>, whereas the
3878 * upper dword stores the XMAC ReceiveCounterEvent register and the lower
3879 * dword the XMAC TransmitCounterEvent register.
3880 *
3881 * Note:
3882 * For XMAC the interrupt source is a self-clearing register, so the source
3883 * must be checked only once. SIRQ module does another check to be sure
3884 * that no interrupt get lost during process time.
3885 *
3886 * Returns:
3887 * 0: success
3888 * 1: something went wrong
3889 */
3890int SkXmOverflowStatus(
3891SK_AC *pAC, /* adapter context */
3892SK_IOC IoC, /* IO context */
3893unsigned int Port, /* Port Index (MAC_1 + n) */
3894SK_U16 IStatus, /* Interupt Status from MAC */
3895SK_U64 SK_FAR *pStatus) /* ptr for return overflow status value */
3896{
3897 SK_U64 Status; /* Overflow status */
3898 SK_U32 RegVal;
3899
3900 Status = 0;
3901
3902 if ((IStatus & XM_IS_RXC_OV) != 0) {
3903
3904 XM_IN32(IoC, Port, XM_RX_CNT_EV, &RegVal);
3905 Status |= (SK_U64)RegVal << 32;
3906 }
3907
3908 if ((IStatus & XM_IS_TXC_OV) != 0) {
3909
3910 XM_IN32(IoC, Port, XM_TX_CNT_EV, &RegVal);
3911 Status |= (SK_U64)RegVal;
3912 }
3913
3914 *pStatus = Status;
3915
3916 return(0);
3917} /* SkXmOverflowStatus */
3918#endif /* GENESIS */
3919
3920
3921#ifdef YUKON
3922/******************************************************************************
3923 *
3924 * SkGmUpdateStats() - Force the GMAC to output the current statistic
3925 *
3926 * Description:
3927 * Empty function for GMAC. Statistic data is accessible in direct way.
3928 *
3929 * Returns:
3930 * 0: success
3931 * 1: something went wrong
3932 */
3933int SkGmUpdateStats(
3934SK_AC *pAC, /* adapter context */
3935SK_IOC IoC, /* IO context */
3936unsigned int Port) /* Port Index (MAC_1 + n) */
3937{
3938 return(0);
3939}
3940
3941
3942/******************************************************************************
3943 *
3944 * SkGmMacStatistic() - Get GMAC counter value
3945 *
3946 * Description:
3947 * Gets the 32bit counter value. Except for the octet counters
3948 * the lower 32bit are counted in hardware and the upper 32bit
3949 * must be counted in software by monitoring counter overflow interrupts.
3950 *
3951 * Returns:
3952 * 0: success
3953 * 1: something went wrong
3954 */
3955int SkGmMacStatistic(
3956SK_AC *pAC, /* adapter context */
3957SK_IOC IoC, /* IO context */
3958unsigned int Port, /* Port Index (MAC_1 + n) */
3959SK_U16 StatAddr, /* MIB counter base address */
3960SK_U32 SK_FAR *pVal) /* ptr to return statistic value */
3961{
3962
3963 if ((StatAddr < GM_RXF_UC_OK) || (StatAddr > GM_TXE_FIFO_UR)) {
3964
3965 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E022, SKERR_HWI_E022MSG);
3966
3967 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
3968 ("SkGmMacStat: wrong MIB counter 0x%04X\n", StatAddr));
3969 return(1);
3970 }
3971
3972 GM_IN32(IoC, Port, StatAddr, pVal);
3973
3974 return(0);
3975} /* SkGmMacStatistic */
3976
3977
3978/******************************************************************************
3979 *
3980 * SkGmResetCounter() - Clear MAC statistic counter
3981 *
3982 * Description:
3983 * Force GMAC to clear its statistic counter.
3984 *
3985 * Returns:
3986 * 0: success
3987 * 1: something went wrong
3988 */
3989int SkGmResetCounter(
3990SK_AC *pAC, /* adapter context */
3991SK_IOC IoC, /* IO context */
3992unsigned int Port) /* Port Index (MAC_1 + n) */
3993{
3994 SK_U16 Reg; /* Phy Address Register */
3995 SK_U16 Word;
3996 int i;
3997
3998 GM_IN16(IoC, Port, GM_PHY_ADDR, &Reg);
3999
4000 /* set MIB Clear Counter Mode */
4001 GM_OUT16(IoC, Port, GM_PHY_ADDR, Reg | GM_PAR_MIB_CLR);
4002
4003 /* read all MIB Counters with Clear Mode set */
4004 for (i = 0; i < GM_MIB_CNT_SIZE; i++) {
4005 /* the reset is performed only when the lower 16 bits are read */
4006 GM_IN16(IoC, Port, GM_MIB_CNT_BASE + 8*i, &Word);
4007 }
4008
4009 /* clear MIB Clear Counter Mode */
4010 GM_OUT16(IoC, Port, GM_PHY_ADDR, Reg);
4011
4012 return(0);
4013} /* SkGmResetCounter */
4014
4015
4016/******************************************************************************
4017 *
4018 * SkGmOverflowStatus() - Gets the status of counter overflow interrupt
4019 *
4020 * Description:
4021 * Checks the source causing an counter overflow interrupt. On success the
4022 * resulting counter overflow status is written to <pStatus>, whereas the
4023 * the following bit coding is used:
4024 * 63:56 - unused
4025 * 55:48 - TxRx interrupt register bit7:0
4026 * 32:47 - Rx interrupt register
4027 * 31:24 - unused
4028 * 23:16 - TxRx interrupt register bit15:8
4029 * 15:0 - Tx interrupt register
4030 *
4031 * Returns:
4032 * 0: success
4033 * 1: something went wrong
4034 */
4035int SkGmOverflowStatus(
4036SK_AC *pAC, /* adapter context */
4037SK_IOC IoC, /* IO context */
4038unsigned int Port, /* Port Index (MAC_1 + n) */
4039SK_U16 IStatus, /* Interupt Status from MAC */
4040SK_U64 SK_FAR *pStatus) /* ptr for return overflow status value */
4041{
4042 SK_U64 Status; /* Overflow status */
4043 SK_U16 RegVal;
4044
4045 Status = 0;
4046
4047 if ((IStatus & GM_IS_RX_CO_OV) != 0) {
4048 /* this register is self-clearing after read */
4049 GM_IN16(IoC, Port, GM_RX_IRQ_SRC, &RegVal);
4050 Status |= (SK_U64)RegVal << 32;
4051 }
4052
4053 if ((IStatus & GM_IS_TX_CO_OV) != 0) {
4054 /* this register is self-clearing after read */
4055 GM_IN16(IoC, Port, GM_TX_IRQ_SRC, &RegVal);
4056 Status |= (SK_U64)RegVal;
4057 }
4058
4059 /* this register is self-clearing after read */
4060 GM_IN16(IoC, Port, GM_TR_IRQ_SRC, &RegVal);
4061 /* Rx overflow interrupt register bits (LoByte)*/
4062 Status |= (SK_U64)((SK_U8)RegVal) << 48;
4063 /* Tx overflow interrupt register bits (HiByte)*/
4064 Status |= (SK_U64)(RegVal >> 8) << 16;
4065
4066 *pStatus = Status;
4067
4068 return(0);
4069} /* SkGmOverflowStatus */
4070
4071
4072#ifndef SK_SLIM
4073/******************************************************************************
4074 *
4075 * SkGmCableDiagStatus() - Starts / Gets status of cable diagnostic test
4076 *
4077 * Description:
4078 * starts the cable diagnostic test if 'StartTest' is true
4079 * gets the results if 'StartTest' is true
4080 *
4081 * NOTE: this test is meaningful only when link is down
4082 *
4083 * Returns:
4084 * 0: success
4085 * 1: no YUKON copper
4086 * 2: test in progress
4087 */
4088int SkGmCableDiagStatus(
4089SK_AC *pAC, /* adapter context */
4090SK_IOC IoC, /* IO context */
4091int Port, /* Port Index (MAC_1 + n) */
4092SK_BOOL StartTest) /* flag for start / get result */
4093{
4094 int i;
4095 SK_U16 RegVal;
4096 SK_GEPORT *pPrt;
4097
4098 pPrt = &pAC->GIni.GP[Port];
4099
4100 if (pPrt->PhyType != SK_PHY_MARV_COPPER) {
4101
4102 return(1);
4103 }
4104
4105 if (StartTest) {
4106 /* only start the cable test */
4107 if ((pPrt->PhyId1 & PHY_I1_REV_MSK) < 4) {
4108 /* apply TDR workaround from Marvell */
4109 SkGmPhyWrite(pAC, IoC, Port, 29, 0x001e);
4110
4111 SkGmPhyWrite(pAC, IoC, Port, 30, 0xcc00);
4112 SkGmPhyWrite(pAC, IoC, Port, 30, 0xc800);
4113 SkGmPhyWrite(pAC, IoC, Port, 30, 0xc400);
4114 SkGmPhyWrite(pAC, IoC, Port, 30, 0xc000);
4115 SkGmPhyWrite(pAC, IoC, Port, 30, 0xc100);
4116 }
4117
4118 /* set address to 0 for MDI[0] */
4119 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, 0);
4120
4121 /* Read Cable Diagnostic Reg */
4122 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CABLE_DIAG, &RegVal);
4123
4124 /* start Cable Diagnostic Test */
4125 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CABLE_DIAG,
4126 (SK_U16)(RegVal | PHY_M_CABD_ENA_TEST));
4127
4128 return(0);
4129 }
4130
4131 /* Read Cable Diagnostic Reg */
4132 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CABLE_DIAG, &RegVal);
4133
4134 SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
4135 ("PHY Cable Diag.=0x%04X\n", RegVal));
4136
4137 if ((RegVal & PHY_M_CABD_ENA_TEST) != 0) {
4138 /* test is running */
4139 return(2);
4140 }
4141
4142 /* get the test results */
4143 for (i = 0; i < 4; i++) {
4144 /* set address to i for MDI[i] */
4145 SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, (SK_U16)i);
4146
4147 /* get Cable Diagnostic values */
4148 SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CABLE_DIAG, &RegVal);
4149
4150 pPrt->PMdiPairLen[i] = (SK_U8)(RegVal & PHY_M_CABD_DIST_MSK);
4151
4152 pPrt->PMdiPairSts[i] = (SK_U8)((RegVal & PHY_M_CABD_STAT_MSK) >> 13);
4153 }
4154
4155 return(0);
4156} /* SkGmCableDiagStatus */
4157#endif /* !SK_SLIM */
4158#endif /* YUKON */
4159
4160/* End of file */
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index fe01b961b597..a2f32151559e 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -39,6 +39,7 @@
39#include <linux/workqueue.h> 39#include <linux/workqueue.h>
40#include <linux/if_vlan.h> 40#include <linux/if_vlan.h>
41#include <linux/prefetch.h> 41#include <linux/prefetch.h>
42#include <linux/debugfs.h>
42#include <linux/mii.h> 43#include <linux/mii.h>
43 44
44#include <asm/irq.h> 45#include <asm/irq.h>
@@ -50,7 +51,7 @@
50#include "sky2.h" 51#include "sky2.h"
51 52
52#define DRV_NAME "sky2" 53#define DRV_NAME "sky2"
53#define DRV_VERSION "1.14" 54#define DRV_VERSION "1.16"
54#define PFX DRV_NAME " " 55#define PFX DRV_NAME " "
55 56
56/* 57/*
@@ -64,7 +65,6 @@
64#define RX_MAX_PENDING (RX_LE_SIZE/6 - 2) 65#define RX_MAX_PENDING (RX_LE_SIZE/6 - 2)
65#define RX_DEF_PENDING RX_MAX_PENDING 66#define RX_DEF_PENDING RX_MAX_PENDING
66#define RX_SKB_ALIGN 8 67#define RX_SKB_ALIGN 8
67#define RX_BUF_WRITE 16
68 68
69#define TX_RING_SIZE 512 69#define TX_RING_SIZE 512
70#define TX_DEF_PENDING (TX_RING_SIZE - 1) 70#define TX_DEF_PENDING (TX_RING_SIZE - 1)
@@ -77,6 +77,9 @@
77#define NAPI_WEIGHT 64 77#define NAPI_WEIGHT 64
78#define PHY_RETRIES 1000 78#define PHY_RETRIES 1000
79 79
80#define SKY2_EEPROM_MAGIC 0x9955aabb
81
82
80#define RING_NEXT(x,s) (((x)+1) & ((s)-1)) 83#define RING_NEXT(x,s) (((x)+1) & ((s)-1))
81 84
82static const u32 default_msg = 85static const u32 default_msg =
@@ -96,7 +99,7 @@ static int disable_msi = 0;
96module_param(disable_msi, int, 0); 99module_param(disable_msi, int, 0);
97MODULE_PARM_DESC(disable_msi, "Disable Message Signaled Interrupt (MSI)"); 100MODULE_PARM_DESC(disable_msi, "Disable Message Signaled Interrupt (MSI)");
98 101
99static int idle_timeout = 0; 102static int idle_timeout = 100;
100module_param(idle_timeout, int, 0); 103module_param(idle_timeout, int, 0);
101MODULE_PARM_DESC(idle_timeout, "Watchdog timer for lost interrupts (ms)"); 104MODULE_PARM_DESC(idle_timeout, "Watchdog timer for lost interrupts (ms)");
102 105
@@ -130,7 +133,7 @@ static const struct pci_device_id sky2_id_table[] = {
130 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4368) }, /* 88EC034 */ 133 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4368) }, /* 88EC034 */
131 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4369) }, /* 88EC042 */ 134 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4369) }, /* 88EC042 */
132 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436A) }, /* 88E8058 */ 135 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436A) }, /* 88E8058 */
133// { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436B) }, /* 88E8071 */ 136 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436B) }, /* 88E8071 */
134 { 0 } 137 { 0 }
135}; 138};
136 139
@@ -217,13 +220,24 @@ static void sky2_power_on(struct sky2_hw *hw)
217 sky2_write8(hw, B2_Y2_CLK_GATE, 0); 220 sky2_write8(hw, B2_Y2_CLK_GATE, 0);
218 221
219 if (hw->chip_id == CHIP_ID_YUKON_EC_U || hw->chip_id == CHIP_ID_YUKON_EX) { 222 if (hw->chip_id == CHIP_ID_YUKON_EC_U || hw->chip_id == CHIP_ID_YUKON_EX) {
220 u32 reg1; 223 u32 reg;
221 224
222 sky2_pci_write32(hw, PCI_DEV_REG3, 0); 225 reg = sky2_pci_read32(hw, PCI_DEV_REG4);
223 reg1 = sky2_pci_read32(hw, PCI_DEV_REG4); 226 /* set all bits to 0 except bits 15..12 and 8 */
224 reg1 &= P_ASPM_CONTROL_MSK; 227 reg &= P_ASPM_CONTROL_MSK;
225 sky2_pci_write32(hw, PCI_DEV_REG4, reg1); 228 sky2_pci_write32(hw, PCI_DEV_REG4, reg);
226 sky2_pci_write32(hw, PCI_DEV_REG5, 0); 229
230 reg = sky2_pci_read32(hw, PCI_DEV_REG5);
231 /* set all bits to 0 except bits 28 & 27 */
232 reg &= P_CTL_TIM_VMAIN_AV_MSK;
233 sky2_pci_write32(hw, PCI_DEV_REG5, reg);
234
235 sky2_pci_write32(hw, PCI_CFG_REG_1, 0);
236
237 /* Enable workaround for dev 4.107 on Yukon-Ultra & Extreme */
238 reg = sky2_read32(hw, B2_GP_IO);
239 reg |= GLB_GPIO_STAT_RACE_DIS;
240 sky2_write32(hw, B2_GP_IO, reg);
227 } 241 }
228} 242}
229 243
@@ -650,6 +664,30 @@ static void sky2_wol_init(struct sky2_port *sky2)
650 664
651} 665}
652 666
667static void sky2_set_tx_stfwd(struct sky2_hw *hw, unsigned port)
668{
669 if (hw->chip_id == CHIP_ID_YUKON_EX && hw->chip_rev != CHIP_REV_YU_EX_A0) {
670 sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T),
671 TX_STFW_ENA |
672 (hw->dev[port]->mtu > ETH_DATA_LEN) ? TX_JUMBO_ENA : TX_JUMBO_DIS);
673 } else {
674 if (hw->dev[port]->mtu > ETH_DATA_LEN) {
675 /* set Tx GMAC FIFO Almost Empty Threshold */
676 sky2_write32(hw, SK_REG(port, TX_GMF_AE_THR),
677 (ECU_JUMBO_WM << 16) | ECU_AE_THR);
678
679 sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T),
680 TX_JUMBO_ENA | TX_STFW_DIS);
681
682 /* Can't do offload because of lack of store/forward */
683 hw->dev[port]->features &= ~(NETIF_F_TSO | NETIF_F_SG
684 | NETIF_F_ALL_CSUM);
685 } else
686 sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T),
687 TX_JUMBO_DIS | TX_STFW_ENA);
688 }
689}
690
653static void sky2_mac_init(struct sky2_hw *hw, unsigned port) 691static void sky2_mac_init(struct sky2_hw *hw, unsigned port)
654{ 692{
655 struct sky2_port *sky2 = netdev_priv(hw->dev[port]); 693 struct sky2_port *sky2 = netdev_priv(hw->dev[port]);
@@ -730,8 +768,11 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port)
730 768
731 /* Configure Rx MAC FIFO */ 769 /* Configure Rx MAC FIFO */
732 sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_CLR); 770 sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_CLR);
733 sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), 771 reg = GMF_OPER_ON | GMF_RX_F_FL_ON;
734 GMF_OPER_ON | GMF_RX_F_FL_ON); 772 if (hw->chip_id == CHIP_ID_YUKON_EX)
773 reg |= GMF_RX_OVER_ON;
774
775 sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), reg);
735 776
736 /* Flush Rx MAC FIFO on any flow control or error */ 777 /* Flush Rx MAC FIFO on any flow control or error */
737 sky2_write16(hw, SK_REG(port, RX_GMF_FL_MSK), GMR_FS_ANY_ERR); 778 sky2_write16(hw, SK_REG(port, RX_GMF_FL_MSK), GMR_FS_ANY_ERR);
@@ -747,16 +788,7 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port)
747 sky2_write8(hw, SK_REG(port, RX_GMF_LP_THR), 768/8); 788 sky2_write8(hw, SK_REG(port, RX_GMF_LP_THR), 768/8);
748 sky2_write8(hw, SK_REG(port, RX_GMF_UP_THR), 1024/8); 789 sky2_write8(hw, SK_REG(port, RX_GMF_UP_THR), 1024/8);
749 790
750 /* set Tx GMAC FIFO Almost Empty Threshold */ 791 sky2_set_tx_stfwd(hw, port);
751 sky2_write32(hw, SK_REG(port, TX_GMF_AE_THR),
752 (ECU_JUMBO_WM << 16) | ECU_AE_THR);
753
754 if (hw->dev[port]->mtu > ETH_DATA_LEN)
755 sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T),
756 TX_JUMBO_ENA | TX_STFW_DIS);
757 else
758 sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T),
759 TX_JUMBO_DIS | TX_STFW_ENA);
760 } 792 }
761 793
762} 794}
@@ -861,24 +893,18 @@ static inline struct sky2_rx_le *sky2_next_rx(struct sky2_port *sky2)
861 return le; 893 return le;
862} 894}
863 895
864/* Return high part of DMA address (could be 32 or 64 bit) */
865static inline u32 high32(dma_addr_t a)
866{
867 return sizeof(a) > sizeof(u32) ? (a >> 16) >> 16 : 0;
868}
869
870/* Build description to hardware for one receive segment */ 896/* Build description to hardware for one receive segment */
871static void sky2_rx_add(struct sky2_port *sky2, u8 op, 897static void sky2_rx_add(struct sky2_port *sky2, u8 op,
872 dma_addr_t map, unsigned len) 898 dma_addr_t map, unsigned len)
873{ 899{
874 struct sky2_rx_le *le; 900 struct sky2_rx_le *le;
875 u32 hi = high32(map); 901 u32 hi = upper_32_bits(map);
876 902
877 if (sky2->rx_addr64 != hi) { 903 if (sky2->rx_addr64 != hi) {
878 le = sky2_next_rx(sky2); 904 le = sky2_next_rx(sky2);
879 le->addr = cpu_to_le32(hi); 905 le->addr = cpu_to_le32(hi);
880 le->opcode = OP_ADDR64 | HW_OWNER; 906 le->opcode = OP_ADDR64 | HW_OWNER;
881 sky2->rx_addr64 = high32(map + len); 907 sky2->rx_addr64 = upper_32_bits(map + len);
882 } 908 }
883 909
884 le = sky2_next_rx(sky2); 910 le = sky2_next_rx(sky2);
@@ -939,14 +965,16 @@ static void rx_set_checksum(struct sky2_port *sky2)
939{ 965{
940 struct sky2_rx_le *le; 966 struct sky2_rx_le *le;
941 967
942 le = sky2_next_rx(sky2); 968 if (sky2->hw->chip_id != CHIP_ID_YUKON_EX) {
943 le->addr = cpu_to_le32((ETH_HLEN << 16) | ETH_HLEN); 969 le = sky2_next_rx(sky2);
944 le->ctrl = 0; 970 le->addr = cpu_to_le32((ETH_HLEN << 16) | ETH_HLEN);
945 le->opcode = OP_TCPSTART | HW_OWNER; 971 le->ctrl = 0;
972 le->opcode = OP_TCPSTART | HW_OWNER;
946 973
947 sky2_write32(sky2->hw, 974 sky2_write32(sky2->hw,
948 Q_ADDR(rxqaddr[sky2->port], Q_CSR), 975 Q_ADDR(rxqaddr[sky2->port], Q_CSR),
949 sky2->rx_csum ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM); 976 sky2->rx_csum ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM);
977 }
950 978
951} 979}
952 980
@@ -1106,6 +1134,11 @@ nomem:
1106 return NULL; 1134 return NULL;
1107} 1135}
1108 1136
1137static inline void sky2_rx_update(struct sky2_port *sky2, unsigned rxq)
1138{
1139 sky2_put_idx(sky2->hw, rxq, sky2->rx_put);
1140}
1141
1109/* 1142/*
1110 * Allocate and setup receiver buffer pool. 1143 * Allocate and setup receiver buffer pool.
1111 * Normal case this ends up creating one list element for skb 1144 * Normal case this ends up creating one list element for skb
@@ -1134,15 +1167,14 @@ static int sky2_rx_start(struct sky2_port *sky2)
1134 if (hw->chip_id == CHIP_ID_YUKON_EC_U && 1167 if (hw->chip_id == CHIP_ID_YUKON_EC_U &&
1135 (hw->chip_rev == CHIP_REV_YU_EC_U_A1 1168 (hw->chip_rev == CHIP_REV_YU_EC_U_A1
1136 || hw->chip_rev == CHIP_REV_YU_EC_U_B0)) 1169 || hw->chip_rev == CHIP_REV_YU_EC_U_B0))
1137 sky2_write32(hw, Q_ADDR(rxq, Q_F), F_M_RX_RAM_DIS); 1170 sky2_write32(hw, Q_ADDR(rxq, Q_TEST), F_M_RX_RAM_DIS);
1138 1171
1139 sky2_prefetch_init(hw, rxq, sky2->rx_le_map, RX_LE_SIZE - 1); 1172 sky2_prefetch_init(hw, rxq, sky2->rx_le_map, RX_LE_SIZE - 1);
1140 1173
1141 rx_set_checksum(sky2); 1174 rx_set_checksum(sky2);
1142 1175
1143 /* Space needed for frame data + headers rounded up */ 1176 /* Space needed for frame data + headers rounded up */
1144 size = ALIGN(sky2->netdev->mtu + ETH_HLEN + VLAN_HLEN, 8) 1177 size = roundup(sky2->netdev->mtu + ETH_HLEN + VLAN_HLEN, 8);
1145 + 8;
1146 1178
1147 /* Stopping point for hardware truncation */ 1179 /* Stopping point for hardware truncation */
1148 thresh = (size - 8) / sizeof(u32); 1180 thresh = (size - 8) / sizeof(u32);
@@ -1197,7 +1229,7 @@ static int sky2_rx_start(struct sky2_port *sky2)
1197 } 1229 }
1198 1230
1199 /* Tell chip about available buffers */ 1231 /* Tell chip about available buffers */
1200 sky2_put_idx(hw, rxq, sky2->rx_put); 1232 sky2_rx_update(sky2, rxq);
1201 return 0; 1233 return 0;
1202nomem: 1234nomem:
1203 sky2_rx_clean(sky2); 1235 sky2_rx_clean(sky2);
@@ -1234,6 +1266,8 @@ static int sky2_up(struct net_device *dev)
1234 if (netif_msg_ifup(sky2)) 1266 if (netif_msg_ifup(sky2))
1235 printk(KERN_INFO PFX "%s: enabling interface\n", dev->name); 1267 printk(KERN_INFO PFX "%s: enabling interface\n", dev->name);
1236 1268
1269 netif_carrier_off(dev);
1270
1237 /* must be power of 2 */ 1271 /* must be power of 2 */
1238 sky2->tx_le = pci_alloc_consistent(hw->pdev, 1272 sky2->tx_le = pci_alloc_consistent(hw->pdev,
1239 TX_RING_SIZE * 1273 TX_RING_SIZE *
@@ -1285,6 +1319,10 @@ static int sky2_up(struct net_device *dev)
1285 1319
1286 sky2_qset(hw, txqaddr[port]); 1320 sky2_qset(hw, txqaddr[port]);
1287 1321
1322 /* This is copied from sk98lin 10.0.5.3; no one tells me about erratta's */
1323 if (hw->chip_id == CHIP_ID_YUKON_EX && hw->chip_rev == CHIP_REV_YU_EX_B0)
1324 sky2_write32(hw, Q_ADDR(txqaddr[port], Q_TEST), F_TX_CHK_AUTO_OFF);
1325
1288 /* Set almost empty threshold */ 1326 /* Set almost empty threshold */
1289 if (hw->chip_id == CHIP_ID_YUKON_EC_U 1327 if (hw->chip_id == CHIP_ID_YUKON_EC_U
1290 && hw->chip_rev == CHIP_REV_YU_EC_U_A0) 1328 && hw->chip_rev == CHIP_REV_YU_EC_U_A0)
@@ -1380,27 +1418,30 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
1380 1418
1381 len = skb_headlen(skb); 1419 len = skb_headlen(skb);
1382 mapping = pci_map_single(hw->pdev, skb->data, len, PCI_DMA_TODEVICE); 1420 mapping = pci_map_single(hw->pdev, skb->data, len, PCI_DMA_TODEVICE);
1383 addr64 = high32(mapping); 1421 addr64 = upper_32_bits(mapping);
1384 1422
1385 /* Send high bits if changed or crosses boundary */ 1423 /* Send high bits if changed or crosses boundary */
1386 if (addr64 != sky2->tx_addr64 || high32(mapping + len) != sky2->tx_addr64) { 1424 if (addr64 != sky2->tx_addr64 ||
1425 upper_32_bits(mapping + len) != sky2->tx_addr64) {
1387 le = get_tx_le(sky2); 1426 le = get_tx_le(sky2);
1388 le->addr = cpu_to_le32(addr64); 1427 le->addr = cpu_to_le32(addr64);
1389 le->opcode = OP_ADDR64 | HW_OWNER; 1428 le->opcode = OP_ADDR64 | HW_OWNER;
1390 sky2->tx_addr64 = high32(mapping + len); 1429 sky2->tx_addr64 = upper_32_bits(mapping + len);
1391 } 1430 }
1392 1431
1393 /* Check for TCP Segmentation Offload */ 1432 /* Check for TCP Segmentation Offload */
1394 mss = skb_shinfo(skb)->gso_size; 1433 mss = skb_shinfo(skb)->gso_size;
1395 if (mss != 0) { 1434 if (mss != 0) {
1396 mss += tcp_optlen(skb); /* TCP options */ 1435 if (hw->chip_id != CHIP_ID_YUKON_EX)
1397 mss += ip_hdrlen(skb) + sizeof(struct tcphdr); 1436 mss += ETH_HLEN + ip_hdrlen(skb) + tcp_hdrlen(skb);
1398 mss += ETH_HLEN; 1437
1399 1438 if (mss != sky2->tx_last_mss) {
1400 if (mss != sky2->tx_last_mss) { 1439 le = get_tx_le(sky2);
1401 le = get_tx_le(sky2); 1440 le->addr = cpu_to_le32(mss);
1402 le->addr = cpu_to_le32(mss); 1441 if (hw->chip_id == CHIP_ID_YUKON_EX)
1403 le->opcode = OP_LRGLEN | HW_OWNER; 1442 le->opcode = OP_MSS | HW_OWNER;
1443 else
1444 le->opcode = OP_LRGLEN | HW_OWNER;
1404 sky2->tx_last_mss = mss; 1445 sky2->tx_last_mss = mss;
1405 } 1446 }
1406 } 1447 }
@@ -1422,24 +1463,30 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
1422 1463
1423 /* Handle TCP checksum offload */ 1464 /* Handle TCP checksum offload */
1424 if (skb->ip_summed == CHECKSUM_PARTIAL) { 1465 if (skb->ip_summed == CHECKSUM_PARTIAL) {
1425 const unsigned offset = skb_transport_offset(skb); 1466 /* On Yukon EX (some versions) encoding change. */
1426 u32 tcpsum; 1467 if (hw->chip_id == CHIP_ID_YUKON_EX
1427 1468 && hw->chip_rev != CHIP_REV_YU_EX_B0)
1428 tcpsum = offset << 16; /* sum start */ 1469 ctrl |= CALSUM; /* auto checksum */
1429 tcpsum |= offset + skb->csum_offset; /* sum write */ 1470 else {
1430 1471 const unsigned offset = skb_transport_offset(skb);
1431 ctrl |= CALSUM | WR_SUM | INIT_SUM | LOCK_SUM; 1472 u32 tcpsum;
1432 if (ip_hdr(skb)->protocol == IPPROTO_UDP) 1473
1433 ctrl |= UDPTCP; 1474 tcpsum = offset << 16; /* sum start */
1434 1475 tcpsum |= offset + skb->csum_offset; /* sum write */
1435 if (tcpsum != sky2->tx_tcpsum) { 1476
1436 sky2->tx_tcpsum = tcpsum; 1477 ctrl |= CALSUM | WR_SUM | INIT_SUM | LOCK_SUM;
1437 1478 if (ip_hdr(skb)->protocol == IPPROTO_UDP)
1438 le = get_tx_le(sky2); 1479 ctrl |= UDPTCP;
1439 le->addr = cpu_to_le32(tcpsum); 1480
1440 le->length = 0; /* initial checksum value */ 1481 if (tcpsum != sky2->tx_tcpsum) {
1441 le->ctrl = 1; /* one packet */ 1482 sky2->tx_tcpsum = tcpsum;
1442 le->opcode = OP_TCPLISW | HW_OWNER; 1483
1484 le = get_tx_le(sky2);
1485 le->addr = cpu_to_le32(tcpsum);
1486 le->length = 0; /* initial checksum value */
1487 le->ctrl = 1; /* one packet */
1488 le->opcode = OP_TCPLISW | HW_OWNER;
1489 }
1443 } 1490 }
1444 } 1491 }
1445 1492
@@ -1459,7 +1506,7 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
1459 1506
1460 mapping = pci_map_page(hw->pdev, frag->page, frag->page_offset, 1507 mapping = pci_map_page(hw->pdev, frag->page, frag->page_offset,
1461 frag->size, PCI_DMA_TODEVICE); 1508 frag->size, PCI_DMA_TODEVICE);
1462 addr64 = high32(mapping); 1509 addr64 = upper_32_bits(mapping);
1463 if (addr64 != sky2->tx_addr64) { 1510 if (addr64 != sky2->tx_addr64) {
1464 le = get_tx_le(sky2); 1511 le = get_tx_le(sky2);
1465 le->addr = cpu_to_le32(addr64); 1512 le->addr = cpu_to_le32(addr64);
@@ -1529,13 +1576,13 @@ static void sky2_tx_complete(struct sky2_port *sky2, u16 done)
1529 if (unlikely(netif_msg_tx_done(sky2))) 1576 if (unlikely(netif_msg_tx_done(sky2)))
1530 printk(KERN_DEBUG "%s: tx done %u\n", 1577 printk(KERN_DEBUG "%s: tx done %u\n",
1531 dev->name, idx); 1578 dev->name, idx);
1579
1532 sky2->net_stats.tx_packets++; 1580 sky2->net_stats.tx_packets++;
1533 sky2->net_stats.tx_bytes += re->skb->len; 1581 sky2->net_stats.tx_bytes += re->skb->len;
1534 1582
1535 dev_kfree_skb_any(re->skb); 1583 dev_kfree_skb_any(re->skb);
1584 sky2->tx_next = RING_NEXT(idx, TX_RING_SIZE);
1536 } 1585 }
1537
1538 le->opcode = 0; /* paranoia */
1539 } 1586 }
1540 1587
1541 sky2->tx_cons = idx; 1588 sky2->tx_cons = idx;
@@ -1573,7 +1620,6 @@ static int sky2_down(struct net_device *dev)
1573 1620
1574 /* Stop more packets from being queued */ 1621 /* Stop more packets from being queued */
1575 netif_stop_queue(dev); 1622 netif_stop_queue(dev);
1576 netif_carrier_off(dev);
1577 1623
1578 /* Disable port IRQ */ 1624 /* Disable port IRQ */
1579 imask = sky2_read32(hw, B0_IMSK); 1625 imask = sky2_read32(hw, B0_IMSK);
@@ -1625,6 +1671,8 @@ static int sky2_down(struct net_device *dev)
1625 1671
1626 sky2_phy_power(hw, port, 0); 1672 sky2_phy_power(hw, port, 0);
1627 1673
1674 netif_carrier_off(dev);
1675
1628 /* turn off LED's */ 1676 /* turn off LED's */
1629 sky2_write16(hw, B0_Y2LED, LED_STAT_OFF); 1677 sky2_write16(hw, B0_Y2LED, LED_STAT_OFF);
1630 1678
@@ -1689,7 +1737,6 @@ static void sky2_link_up(struct sky2_port *sky2)
1689 gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_DEF_MSK); 1737 gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_DEF_MSK);
1690 1738
1691 netif_carrier_on(sky2->netdev); 1739 netif_carrier_on(sky2->netdev);
1692 netif_wake_queue(sky2->netdev);
1693 1740
1694 /* Turn on link LED */ 1741 /* Turn on link LED */
1695 sky2_write8(hw, SK_REG(port, LNK_LED_REG), 1742 sky2_write8(hw, SK_REG(port, LNK_LED_REG),
@@ -1741,7 +1788,6 @@ static void sky2_link_down(struct sky2_port *sky2)
1741 gma_write16(hw, port, GM_GP_CTRL, reg); 1788 gma_write16(hw, port, GM_GP_CTRL, reg);
1742 1789
1743 netif_carrier_off(sky2->netdev); 1790 netif_carrier_off(sky2->netdev);
1744 netif_stop_queue(sky2->netdev);
1745 1791
1746 /* Turn on link LED */ 1792 /* Turn on link LED */
1747 sky2_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_OFF); 1793 sky2_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_OFF);
@@ -1913,15 +1959,8 @@ static int sky2_change_mtu(struct net_device *dev, int new_mtu)
1913 1959
1914 synchronize_irq(hw->pdev->irq); 1960 synchronize_irq(hw->pdev->irq);
1915 1961
1916 if (hw->chip_id == CHIP_ID_YUKON_EC_U || hw->chip_id == CHIP_ID_YUKON_EX) { 1962 if (hw->chip_id == CHIP_ID_YUKON_EC_U || hw->chip_id == CHIP_ID_YUKON_EX)
1917 if (new_mtu > ETH_DATA_LEN) { 1963 sky2_set_tx_stfwd(hw, port);
1918 sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T),
1919 TX_JUMBO_ENA | TX_STFW_DIS);
1920 dev->features &= NETIF_F_TSO | NETIF_F_SG | NETIF_F_IP_CSUM;
1921 } else
1922 sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T),
1923 TX_JUMBO_DIS | TX_STFW_ENA);
1924 }
1925 1964
1926 ctl = gma_read16(hw, port, GM_GP_CTRL); 1965 ctl = gma_read16(hw, port, GM_GP_CTRL);
1927 gma_write16(hw, port, GM_GP_CTRL, ctl & ~GM_GPCR_RX_ENA); 1966 gma_write16(hw, port, GM_GP_CTRL, ctl & ~GM_GPCR_RX_ENA);
@@ -2019,8 +2058,6 @@ static struct sk_buff *receive_new(struct sky2_port *sky2,
2019 struct sk_buff *skb, *nskb; 2058 struct sk_buff *skb, *nskb;
2020 unsigned hdr_space = sky2->rx_data_size; 2059 unsigned hdr_space = sky2->rx_data_size;
2021 2060
2022 pr_debug(PFX "receive new length=%d\n", length);
2023
2024 /* Don't be tricky about reusing pages (yet) */ 2061 /* Don't be tricky about reusing pages (yet) */
2025 nskb = sky2_rx_alloc(sky2); 2062 nskb = sky2_rx_alloc(sky2);
2026 if (unlikely(!nskb)) 2063 if (unlikely(!nskb))
@@ -2064,6 +2101,9 @@ static struct sk_buff *sky2_receive(struct net_device *dev,
2064 if (!(status & GMR_FS_RX_OK)) 2101 if (!(status & GMR_FS_RX_OK))
2065 goto resubmit; 2102 goto resubmit;
2066 2103
2104 if (status >> 16 != length)
2105 goto len_mismatch;
2106
2067 if (length < copybreak) 2107 if (length < copybreak)
2068 skb = receive_copy(sky2, re, length); 2108 skb = receive_copy(sky2, re, length);
2069 else 2109 else
@@ -2073,6 +2113,11 @@ resubmit:
2073 2113
2074 return skb; 2114 return skb;
2075 2115
2116len_mismatch:
2117 /* Truncation of overlength packets
2118 causes PHY length to not match MAC length */
2119 ++sky2->net_stats.rx_length_errors;
2120
2076error: 2121error:
2077 ++sky2->net_stats.rx_errors; 2122 ++sky2->net_stats.rx_errors;
2078 if (status & GMR_FS_RX_FF_OV) { 2123 if (status & GMR_FS_RX_FF_OV) {
@@ -2109,15 +2154,16 @@ static inline void sky2_tx_done(struct net_device *dev, u16 last)
2109/* Process status response ring */ 2154/* Process status response ring */
2110static int sky2_status_intr(struct sky2_hw *hw, int to_do) 2155static int sky2_status_intr(struct sky2_hw *hw, int to_do)
2111{ 2156{
2112 struct sky2_port *sky2;
2113 int work_done = 0; 2157 int work_done = 0;
2114 unsigned buf_write[2] = { 0, 0 }; 2158 unsigned rx[2] = { 0, 0 };
2115 u16 hwidx = sky2_read16(hw, STAT_PUT_IDX); 2159 u16 hwidx = sky2_read16(hw, STAT_PUT_IDX);
2116 2160
2117 rmb(); 2161 rmb();
2118 2162
2119 while (hw->st_idx != hwidx) { 2163 while (hw->st_idx != hwidx) {
2164 struct sky2_port *sky2;
2120 struct sky2_status_le *le = hw->st_le + hw->st_idx; 2165 struct sky2_status_le *le = hw->st_le + hw->st_idx;
2166 unsigned port = le->css & CSS_LINK_BIT;
2121 struct net_device *dev; 2167 struct net_device *dev;
2122 struct sk_buff *skb; 2168 struct sk_buff *skb;
2123 u32 status; 2169 u32 status;
@@ -2125,19 +2171,28 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do)
2125 2171
2126 hw->st_idx = RING_NEXT(hw->st_idx, STATUS_RING_SIZE); 2172 hw->st_idx = RING_NEXT(hw->st_idx, STATUS_RING_SIZE);
2127 2173
2128 BUG_ON(le->link >= 2); 2174 dev = hw->dev[port];
2129 dev = hw->dev[le->link];
2130
2131 sky2 = netdev_priv(dev); 2175 sky2 = netdev_priv(dev);
2132 length = le16_to_cpu(le->length); 2176 length = le16_to_cpu(le->length);
2133 status = le32_to_cpu(le->status); 2177 status = le32_to_cpu(le->status);
2134 2178
2135 switch (le->opcode & ~HW_OWNER) { 2179 switch (le->opcode & ~HW_OWNER) {
2136 case OP_RXSTAT: 2180 case OP_RXSTAT:
2181 ++rx[port];
2137 skb = sky2_receive(dev, length, status); 2182 skb = sky2_receive(dev, length, status);
2138 if (unlikely(!skb)) { 2183 if (unlikely(!skb)) {
2139 sky2->net_stats.rx_dropped++; 2184 sky2->net_stats.rx_dropped++;
2140 goto force_update; 2185 break;
2186 }
2187
2188 /* This chip reports checksum status differently */
2189 if (hw->chip_id == CHIP_ID_YUKON_EX) {
2190 if (sky2->rx_csum &&
2191 (le->css & (CSS_ISIPV4 | CSS_ISIPV6)) &&
2192 (le->css & CSS_TCPUDPCSOK))
2193 skb->ip_summed = CHECKSUM_UNNECESSARY;
2194 else
2195 skb->ip_summed = CHECKSUM_NONE;
2141 } 2196 }
2142 2197
2143 skb->protocol = eth_type_trans(skb, dev); 2198 skb->protocol = eth_type_trans(skb, dev);
@@ -2154,13 +2209,6 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do)
2154#endif 2209#endif
2155 netif_receive_skb(skb); 2210 netif_receive_skb(skb);
2156 2211
2157 /* Update receiver after 16 frames */
2158 if (++buf_write[le->link] == RX_BUF_WRITE) {
2159force_update:
2160 sky2_put_idx(hw, rxqaddr[le->link], sky2->rx_put);
2161 buf_write[le->link] = 0;
2162 }
2163
2164 /* Stop after net poll weight */ 2212 /* Stop after net poll weight */
2165 if (++work_done >= to_do) 2213 if (++work_done >= to_do)
2166 goto exit_loop; 2214 goto exit_loop;
@@ -2179,6 +2227,9 @@ force_update:
2179 if (!sky2->rx_csum) 2227 if (!sky2->rx_csum)
2180 break; 2228 break;
2181 2229
2230 if (hw->chip_id == CHIP_ID_YUKON_EX)
2231 break;
2232
2182 /* Both checksum counters are programmed to start at 2233 /* Both checksum counters are programmed to start at
2183 * the same offset, so unless there is a problem they 2234 * the same offset, so unless there is a problem they
2184 * should match. This failure is an early indication that 2235 * should match. This failure is an early indication that
@@ -2194,7 +2245,7 @@ force_update:
2194 dev->name, status); 2245 dev->name, status);
2195 sky2->rx_csum = 0; 2246 sky2->rx_csum = 0;
2196 sky2_write32(sky2->hw, 2247 sky2_write32(sky2->hw,
2197 Q_ADDR(rxqaddr[le->link], Q_CSR), 2248 Q_ADDR(rxqaddr[port], Q_CSR),
2198 BMU_DIS_RX_CHKSUM); 2249 BMU_DIS_RX_CHKSUM);
2199 } 2250 }
2200 break; 2251 break;
@@ -2213,24 +2264,18 @@ force_update:
2213 if (net_ratelimit()) 2264 if (net_ratelimit())
2214 printk(KERN_WARNING PFX 2265 printk(KERN_WARNING PFX
2215 "unknown status opcode 0x%x\n", le->opcode); 2266 "unknown status opcode 0x%x\n", le->opcode);
2216 goto exit_loop;
2217 } 2267 }
2218 } 2268 }
2219 2269
2220 /* Fully processed status ring so clear irq */ 2270 /* Fully processed status ring so clear irq */
2221 sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ); 2271 sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ);
2222 mmiowb();
2223 2272
2224exit_loop: 2273exit_loop:
2225 if (buf_write[0]) { 2274 if (rx[0])
2226 sky2 = netdev_priv(hw->dev[0]); 2275 sky2_rx_update(netdev_priv(hw->dev[0]), Q_R1);
2227 sky2_put_idx(hw, Q_R1, sky2->rx_put);
2228 }
2229 2276
2230 if (buf_write[1]) { 2277 if (rx[1])
2231 sky2 = netdev_priv(hw->dev[1]); 2278 sky2_rx_update(netdev_priv(hw->dev[1]), Q_R2);
2232 sky2_put_idx(hw, Q_R2, sky2->rx_put);
2233 }
2234 2279
2235 return work_done; 2280 return work_done;
2236} 2281}
@@ -2427,8 +2472,7 @@ static void sky2_err_intr(struct sky2_hw *hw, u32 status)
2427static int sky2_poll(struct net_device *dev0, int *budget) 2472static int sky2_poll(struct net_device *dev0, int *budget)
2428{ 2473{
2429 struct sky2_hw *hw = ((struct sky2_port *) netdev_priv(dev0))->hw; 2474 struct sky2_hw *hw = ((struct sky2_port *) netdev_priv(dev0))->hw;
2430 int work_limit = min(dev0->quota, *budget); 2475 int work_done;
2431 int work_done = 0;
2432 u32 status = sky2_read32(hw, B0_Y2_SP_EISR); 2476 u32 status = sky2_read32(hw, B0_Y2_SP_EISR);
2433 2477
2434 if (unlikely(status & Y2_IS_ERROR)) 2478 if (unlikely(status & Y2_IS_ERROR))
@@ -2440,18 +2484,25 @@ static int sky2_poll(struct net_device *dev0, int *budget)
2440 if (status & Y2_IS_IRQ_PHY2) 2484 if (status & Y2_IS_IRQ_PHY2)
2441 sky2_phy_intr(hw, 1); 2485 sky2_phy_intr(hw, 1);
2442 2486
2443 work_done = sky2_status_intr(hw, work_limit); 2487 work_done = sky2_status_intr(hw, min(dev0->quota, *budget));
2444 if (work_done < work_limit) { 2488 *budget -= work_done;
2445 netif_rx_complete(dev0); 2489 dev0->quota -= work_done;
2446 2490
2447 /* end of interrupt, re-enables also acts as I/O synchronization */ 2491 /* More work? */
2448 sky2_read32(hw, B0_Y2_SP_LISR); 2492 if (hw->st_idx != sky2_read16(hw, STAT_PUT_IDX))
2449 return 0;
2450 } else {
2451 *budget -= work_done;
2452 dev0->quota -= work_done;
2453 return 1; 2493 return 1;
2494
2495 /* Bug/Errata workaround?
2496 * Need to kick the TX irq moderation timer.
2497 */
2498 if (sky2_read8(hw, STAT_TX_TIMER_CTRL) == TIM_START) {
2499 sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_STOP);
2500 sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_START);
2454 } 2501 }
2502 netif_rx_complete(dev0);
2503
2504 sky2_read32(hw, B0_Y2_SP_LISR);
2505 return 0;
2455} 2506}
2456 2507
2457static irqreturn_t sky2_intr(int irq, void *dev_id) 2508static irqreturn_t sky2_intr(int irq, void *dev_id)
@@ -2513,6 +2564,9 @@ static int __devinit sky2_init(struct sky2_hw *hw)
2513{ 2564{
2514 u8 t8; 2565 u8 t8;
2515 2566
2567 /* Enable all clocks */
2568 sky2_pci_write32(hw, PCI_DEV_REG3, 0);
2569
2516 sky2_write8(hw, B0_CTST, CS_RST_CLR); 2570 sky2_write8(hw, B0_CTST, CS_RST_CLR);
2517 2571
2518 hw->chip_id = sky2_read8(hw, B2_CHIP_ID); 2572 hw->chip_id = sky2_read8(hw, B2_CHIP_ID);
@@ -2522,14 +2576,6 @@ static int __devinit sky2_init(struct sky2_hw *hw)
2522 return -EOPNOTSUPP; 2576 return -EOPNOTSUPP;
2523 } 2577 }
2524 2578
2525 if (hw->chip_id == CHIP_ID_YUKON_EX)
2526 dev_warn(&hw->pdev->dev, "this driver not yet tested on this chip type\n"
2527 "Please report success or failure to <netdev@vger.kernel.org>\n");
2528
2529 /* Make sure and enable all clocks */
2530 if (hw->chip_id == CHIP_ID_YUKON_EX || hw->chip_id == CHIP_ID_YUKON_EC_U)
2531 sky2_pci_write32(hw, PCI_DEV_REG3, 0);
2532
2533 hw->chip_rev = (sky2_read8(hw, B2_MAC_CFG) & CFG_CHIP_R_MSK) >> 4; 2579 hw->chip_rev = (sky2_read8(hw, B2_MAC_CFG) & CFG_CHIP_R_MSK) >> 4;
2534 2580
2535 /* This rev is really old, and requires untested workarounds */ 2581 /* This rev is really old, and requires untested workarounds */
@@ -2589,6 +2635,11 @@ static void sky2_reset(struct sky2_hw *hw)
2589 for (i = 0; i < hw->ports; i++) { 2635 for (i = 0; i < hw->ports; i++) {
2590 sky2_write8(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_SET); 2636 sky2_write8(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_SET);
2591 sky2_write8(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_CLR); 2637 sky2_write8(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_CLR);
2638
2639 if (hw->chip_id == CHIP_ID_YUKON_EX)
2640 sky2_write16(hw, SK_REG(i, GMAC_CTRL),
2641 GMC_BYP_MACSECRX_ON | GMC_BYP_MACSECTX_ON
2642 | GMC_BYP_RETR_ON);
2592 } 2643 }
2593 2644
2594 sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); 2645 sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
@@ -2675,8 +2726,6 @@ static void sky2_restart(struct work_struct *work)
2675 struct net_device *dev; 2726 struct net_device *dev;
2676 int i, err; 2727 int i, err;
2677 2728
2678 dev_dbg(&hw->pdev->dev, "restarting\n");
2679
2680 del_timer_sync(&hw->idle_timer); 2729 del_timer_sync(&hw->idle_timer);
2681 2730
2682 rtnl_lock(); 2731 rtnl_lock();
@@ -2735,7 +2784,7 @@ static int sky2_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
2735 2784
2736 sky2->wol = wol->wolopts; 2785 sky2->wol = wol->wolopts;
2737 2786
2738 if (hw->chip_id == CHIP_ID_YUKON_EC_U) 2787 if (hw->chip_id == CHIP_ID_YUKON_EC_U || hw->chip_id == CHIP_ID_YUKON_EX)
2739 sky2_write32(hw, B0_CTST, sky2->wol 2788 sky2_write32(hw, B0_CTST, sky2->wol
2740 ? Y2_HW_WOL_ON : Y2_HW_WOL_OFF); 2789 ? Y2_HW_WOL_ON : Y2_HW_WOL_OFF);
2741 2790
@@ -3330,7 +3379,7 @@ static int sky2_get_regs_len(struct net_device *dev)
3330 3379
3331/* 3380/*
3332 * Returns copy of control register region 3381 * Returns copy of control register region
3333 * Note: access to the RAM address register set will cause timeouts. 3382 * Note: ethtool_get_regs always provides full size (16k) buffer
3334 */ 3383 */
3335static void sky2_get_regs(struct net_device *dev, struct ethtool_regs *regs, 3384static void sky2_get_regs(struct net_device *dev, struct ethtool_regs *regs,
3336 void *p) 3385 void *p)
@@ -3338,15 +3387,19 @@ static void sky2_get_regs(struct net_device *dev, struct ethtool_regs *regs,
3338 const struct sky2_port *sky2 = netdev_priv(dev); 3387 const struct sky2_port *sky2 = netdev_priv(dev);
3339 const void __iomem *io = sky2->hw->regs; 3388 const void __iomem *io = sky2->hw->regs;
3340 3389
3341 BUG_ON(regs->len < B3_RI_WTO_R1);
3342 regs->version = 1; 3390 regs->version = 1;
3343 memset(p, 0, regs->len); 3391 memset(p, 0, regs->len);
3344 3392
3345 memcpy_fromio(p, io, B3_RAM_ADDR); 3393 memcpy_fromio(p, io, B3_RAM_ADDR);
3346 3394
3347 memcpy_fromio(p + B3_RI_WTO_R1, 3395 /* skip diagnostic ram region */
3348 io + B3_RI_WTO_R1, 3396 memcpy_fromio(p + B3_RI_WTO_R1, io + B3_RI_WTO_R1, 0x2000 - B3_RI_WTO_R1);
3349 regs->len - B3_RI_WTO_R1); 3397
3398 /* copy GMAC registers */
3399 memcpy_fromio(p + BASE_GMAC_1, io + BASE_GMAC_1, 0x1000);
3400 if (sky2->hw->ports > 1)
3401 memcpy_fromio(p + BASE_GMAC_2, io + BASE_GMAC_2, 0x1000);
3402
3350} 3403}
3351 3404
3352/* In order to do Jumbo packets on these chips, need to turn off the 3405/* In order to do Jumbo packets on these chips, need to turn off the
@@ -3357,9 +3410,7 @@ static int no_tx_offload(struct net_device *dev)
3357 const struct sky2_port *sky2 = netdev_priv(dev); 3410 const struct sky2_port *sky2 = netdev_priv(dev);
3358 const struct sky2_hw *hw = sky2->hw; 3411 const struct sky2_hw *hw = sky2->hw;
3359 3412
3360 return dev->mtu > ETH_DATA_LEN && 3413 return dev->mtu > ETH_DATA_LEN && hw->chip_id == CHIP_ID_YUKON_EC_U;
3361 (hw->chip_id == CHIP_ID_YUKON_EX
3362 || hw->chip_id == CHIP_ID_YUKON_EC_U);
3363} 3414}
3364 3415
3365static int sky2_set_tx_csum(struct net_device *dev, u32 data) 3416static int sky2_set_tx_csum(struct net_device *dev, u32 data)
@@ -3379,39 +3430,315 @@ static int sky2_set_tso(struct net_device *dev, u32 data)
3379 return ethtool_op_set_tso(dev, data); 3430 return ethtool_op_set_tso(dev, data);
3380} 3431}
3381 3432
3433static int sky2_get_eeprom_len(struct net_device *dev)
3434{
3435 struct sky2_port *sky2 = netdev_priv(dev);
3436 u16 reg2;
3437
3438 reg2 = sky2_pci_read32(sky2->hw, PCI_DEV_REG2);
3439 return 1 << ( ((reg2 & PCI_VPD_ROM_SZ) >> 14) + 8);
3440}
3441
3442static u32 sky2_vpd_read(struct sky2_hw *hw, int cap, u16 offset)
3443{
3444 sky2_pci_write16(hw, cap + PCI_VPD_ADDR, offset);
3445
3446 while (!(sky2_pci_read16(hw, cap + PCI_VPD_ADDR) & PCI_VPD_ADDR_F))
3447 cpu_relax();
3448 return sky2_pci_read32(hw, cap + PCI_VPD_DATA);
3449}
3450
3451static void sky2_vpd_write(struct sky2_hw *hw, int cap, u16 offset, u32 val)
3452{
3453 sky2_pci_write32(hw, cap + PCI_VPD_DATA, val);
3454 sky2_pci_write16(hw, cap + PCI_VPD_ADDR, offset | PCI_VPD_ADDR_F);
3455 do {
3456 cpu_relax();
3457 } while (sky2_pci_read16(hw, cap + PCI_VPD_ADDR) & PCI_VPD_ADDR_F);
3458}
3459
3460static int sky2_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
3461 u8 *data)
3462{
3463 struct sky2_port *sky2 = netdev_priv(dev);
3464 int cap = pci_find_capability(sky2->hw->pdev, PCI_CAP_ID_VPD);
3465 int length = eeprom->len;
3466 u16 offset = eeprom->offset;
3467
3468 if (!cap)
3469 return -EINVAL;
3470
3471 eeprom->magic = SKY2_EEPROM_MAGIC;
3472
3473 while (length > 0) {
3474 u32 val = sky2_vpd_read(sky2->hw, cap, offset);
3475 int n = min_t(int, length, sizeof(val));
3476
3477 memcpy(data, &val, n);
3478 length -= n;
3479 data += n;
3480 offset += n;
3481 }
3482 return 0;
3483}
3484
3485static int sky2_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
3486 u8 *data)
3487{
3488 struct sky2_port *sky2 = netdev_priv(dev);
3489 int cap = pci_find_capability(sky2->hw->pdev, PCI_CAP_ID_VPD);
3490 int length = eeprom->len;
3491 u16 offset = eeprom->offset;
3492
3493 if (!cap)
3494 return -EINVAL;
3495
3496 if (eeprom->magic != SKY2_EEPROM_MAGIC)
3497 return -EINVAL;
3498
3499 while (length > 0) {
3500 u32 val;
3501 int n = min_t(int, length, sizeof(val));
3502
3503 if (n < sizeof(val))
3504 val = sky2_vpd_read(sky2->hw, cap, offset);
3505 memcpy(&val, data, n);
3506
3507 sky2_vpd_write(sky2->hw, cap, offset, val);
3508
3509 length -= n;
3510 data += n;
3511 offset += n;
3512 }
3513 return 0;
3514}
3515
3516
3382static const struct ethtool_ops sky2_ethtool_ops = { 3517static const struct ethtool_ops sky2_ethtool_ops = {
3383 .get_settings = sky2_get_settings, 3518 .get_settings = sky2_get_settings,
3384 .set_settings = sky2_set_settings, 3519 .set_settings = sky2_set_settings,
3385 .get_drvinfo = sky2_get_drvinfo, 3520 .get_drvinfo = sky2_get_drvinfo,
3386 .get_wol = sky2_get_wol, 3521 .get_wol = sky2_get_wol,
3387 .set_wol = sky2_set_wol, 3522 .set_wol = sky2_set_wol,
3388 .get_msglevel = sky2_get_msglevel, 3523 .get_msglevel = sky2_get_msglevel,
3389 .set_msglevel = sky2_set_msglevel, 3524 .set_msglevel = sky2_set_msglevel,
3390 .nway_reset = sky2_nway_reset, 3525 .nway_reset = sky2_nway_reset,
3391 .get_regs_len = sky2_get_regs_len, 3526 .get_regs_len = sky2_get_regs_len,
3392 .get_regs = sky2_get_regs, 3527 .get_regs = sky2_get_regs,
3393 .get_link = ethtool_op_get_link, 3528 .get_link = ethtool_op_get_link,
3394 .get_sg = ethtool_op_get_sg, 3529 .get_eeprom_len = sky2_get_eeprom_len,
3395 .set_sg = ethtool_op_set_sg, 3530 .get_eeprom = sky2_get_eeprom,
3396 .get_tx_csum = ethtool_op_get_tx_csum, 3531 .set_eeprom = sky2_set_eeprom,
3397 .set_tx_csum = sky2_set_tx_csum, 3532 .get_sg = ethtool_op_get_sg,
3398 .get_tso = ethtool_op_get_tso, 3533 .set_sg = ethtool_op_set_sg,
3399 .set_tso = sky2_set_tso, 3534 .get_tx_csum = ethtool_op_get_tx_csum,
3400 .get_rx_csum = sky2_get_rx_csum, 3535 .set_tx_csum = sky2_set_tx_csum,
3401 .set_rx_csum = sky2_set_rx_csum, 3536 .get_tso = ethtool_op_get_tso,
3402 .get_strings = sky2_get_strings, 3537 .set_tso = sky2_set_tso,
3403 .get_coalesce = sky2_get_coalesce, 3538 .get_rx_csum = sky2_get_rx_csum,
3404 .set_coalesce = sky2_set_coalesce, 3539 .set_rx_csum = sky2_set_rx_csum,
3405 .get_ringparam = sky2_get_ringparam, 3540 .get_strings = sky2_get_strings,
3406 .set_ringparam = sky2_set_ringparam, 3541 .get_coalesce = sky2_get_coalesce,
3542 .set_coalesce = sky2_set_coalesce,
3543 .get_ringparam = sky2_get_ringparam,
3544 .set_ringparam = sky2_set_ringparam,
3407 .get_pauseparam = sky2_get_pauseparam, 3545 .get_pauseparam = sky2_get_pauseparam,
3408 .set_pauseparam = sky2_set_pauseparam, 3546 .set_pauseparam = sky2_set_pauseparam,
3409 .phys_id = sky2_phys_id, 3547 .phys_id = sky2_phys_id,
3410 .get_stats_count = sky2_get_stats_count, 3548 .get_stats_count = sky2_get_stats_count,
3411 .get_ethtool_stats = sky2_get_ethtool_stats, 3549 .get_ethtool_stats = sky2_get_ethtool_stats,
3412 .get_perm_addr = ethtool_op_get_perm_addr, 3550 .get_perm_addr = ethtool_op_get_perm_addr,
3413}; 3551};
3414 3552
3553#ifdef CONFIG_SKY2_DEBUG
3554
3555static struct dentry *sky2_debug;
3556
3557static int sky2_debug_show(struct seq_file *seq, void *v)
3558{
3559 struct net_device *dev = seq->private;
3560 const struct sky2_port *sky2 = netdev_priv(dev);
3561 const struct sky2_hw *hw = sky2->hw;
3562 unsigned port = sky2->port;
3563 unsigned idx, last;
3564 int sop;
3565
3566 if (!netif_running(dev))
3567 return -ENETDOWN;
3568
3569 seq_printf(seq, "IRQ src=%x mask=%x control=%x\n",
3570 sky2_read32(hw, B0_ISRC),
3571 sky2_read32(hw, B0_IMSK),
3572 sky2_read32(hw, B0_Y2_SP_ICR));
3573
3574 netif_poll_disable(hw->dev[0]);
3575 last = sky2_read16(hw, STAT_PUT_IDX);
3576
3577 if (hw->st_idx == last)
3578 seq_puts(seq, "Status ring (empty)\n");
3579 else {
3580 seq_puts(seq, "Status ring\n");
3581 for (idx = hw->st_idx; idx != last && idx < STATUS_RING_SIZE;
3582 idx = RING_NEXT(idx, STATUS_RING_SIZE)) {
3583 const struct sky2_status_le *le = hw->st_le + idx;
3584 seq_printf(seq, "[%d] %#x %d %#x\n",
3585 idx, le->opcode, le->length, le->status);
3586 }
3587 seq_puts(seq, "\n");
3588 }
3589
3590 seq_printf(seq, "Tx ring pending=%u...%u report=%d done=%d\n",
3591 sky2->tx_cons, sky2->tx_prod,
3592 sky2_read16(hw, port == 0 ? STAT_TXA1_RIDX : STAT_TXA2_RIDX),
3593 sky2_read16(hw, Q_ADDR(txqaddr[port], Q_DONE)));
3594
3595 /* Dump contents of tx ring */
3596 sop = 1;
3597 for (idx = sky2->tx_next; idx != sky2->tx_prod && idx < TX_RING_SIZE;
3598 idx = RING_NEXT(idx, TX_RING_SIZE)) {
3599 const struct sky2_tx_le *le = sky2->tx_le + idx;
3600 u32 a = le32_to_cpu(le->addr);
3601
3602 if (sop)
3603 seq_printf(seq, "%u:", idx);
3604 sop = 0;
3605
3606 switch(le->opcode & ~HW_OWNER) {
3607 case OP_ADDR64:
3608 seq_printf(seq, " %#x:", a);
3609 break;
3610 case OP_LRGLEN:
3611 seq_printf(seq, " mtu=%d", a);
3612 break;
3613 case OP_VLAN:
3614 seq_printf(seq, " vlan=%d", be16_to_cpu(le->length));
3615 break;
3616 case OP_TCPLISW:
3617 seq_printf(seq, " csum=%#x", a);
3618 break;
3619 case OP_LARGESEND:
3620 seq_printf(seq, " tso=%#x(%d)", a, le16_to_cpu(le->length));
3621 break;
3622 case OP_PACKET:
3623 seq_printf(seq, " %#x(%d)", a, le16_to_cpu(le->length));
3624 break;
3625 case OP_BUFFER:
3626 seq_printf(seq, " frag=%#x(%d)", a, le16_to_cpu(le->length));
3627 break;
3628 default:
3629 seq_printf(seq, " op=%#x,%#x(%d)", le->opcode,
3630 a, le16_to_cpu(le->length));
3631 }
3632
3633 if (le->ctrl & EOP) {
3634 seq_putc(seq, '\n');
3635 sop = 1;
3636 }
3637 }
3638
3639 seq_printf(seq, "\nRx ring hw get=%d put=%d last=%d\n",
3640 sky2_read16(hw, Y2_QADDR(rxqaddr[port], PREF_UNIT_GET_IDX)),
3641 last = sky2_read16(hw, Y2_QADDR(rxqaddr[port], PREF_UNIT_PUT_IDX)),
3642 sky2_read16(hw, Y2_QADDR(rxqaddr[port], PREF_UNIT_LAST_IDX)));
3643
3644 netif_poll_enable(hw->dev[0]);
3645 return 0;
3646}
3647
3648static int sky2_debug_open(struct inode *inode, struct file *file)
3649{
3650 return single_open(file, sky2_debug_show, inode->i_private);
3651}
3652
3653static const struct file_operations sky2_debug_fops = {
3654 .owner = THIS_MODULE,
3655 .open = sky2_debug_open,
3656 .read = seq_read,
3657 .llseek = seq_lseek,
3658 .release = single_release,
3659};
3660
3661/*
3662 * Use network device events to create/remove/rename
3663 * debugfs file entries
3664 */
3665static int sky2_device_event(struct notifier_block *unused,
3666 unsigned long event, void *ptr)
3667{
3668 struct net_device *dev = ptr;
3669
3670 if (dev->open == sky2_up) {
3671 struct sky2_port *sky2 = netdev_priv(dev);
3672
3673 switch(event) {
3674 case NETDEV_CHANGENAME:
3675 if (!netif_running(dev))
3676 break;
3677 /* fallthrough */
3678 case NETDEV_DOWN:
3679 case NETDEV_GOING_DOWN:
3680 if (sky2->debugfs) {
3681 printk(KERN_DEBUG PFX "%s: remove debugfs\n",
3682 dev->name);
3683 debugfs_remove(sky2->debugfs);
3684 sky2->debugfs = NULL;
3685 }
3686
3687 if (event != NETDEV_CHANGENAME)
3688 break;
3689 /* fallthrough for changename */
3690 case NETDEV_UP:
3691 if (sky2_debug) {
3692 struct dentry *d;
3693 d = debugfs_create_file(dev->name, S_IRUGO,
3694 sky2_debug, dev,
3695 &sky2_debug_fops);
3696 if (d == NULL || IS_ERR(d))
3697 printk(KERN_INFO PFX
3698 "%s: debugfs create failed\n",
3699 dev->name);
3700 else
3701 sky2->debugfs = d;
3702 }
3703 break;
3704 }
3705 }
3706
3707 return NOTIFY_DONE;
3708}
3709
3710static struct notifier_block sky2_notifier = {
3711 .notifier_call = sky2_device_event,
3712};
3713
3714
3715static __init void sky2_debug_init(void)
3716{
3717 struct dentry *ent;
3718
3719 ent = debugfs_create_dir("sky2", NULL);
3720 if (!ent || IS_ERR(ent))
3721 return;
3722
3723 sky2_debug = ent;
3724 register_netdevice_notifier(&sky2_notifier);
3725}
3726
3727static __exit void sky2_debug_cleanup(void)
3728{
3729 if (sky2_debug) {
3730 unregister_netdevice_notifier(&sky2_notifier);
3731 debugfs_remove(sky2_debug);
3732 sky2_debug = NULL;
3733 }
3734}
3735
3736#else
3737#define sky2_debug_init()
3738#define sky2_debug_cleanup()
3739#endif
3740
3741
3415/* Initialize network device */ 3742/* Initialize network device */
3416static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw, 3743static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw,
3417 unsigned port, 3744 unsigned port,
@@ -3486,10 +3813,6 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw,
3486 memcpy_fromio(dev->dev_addr, hw->regs + B2_MAC_1 + port * 8, ETH_ALEN); 3813 memcpy_fromio(dev->dev_addr, hw->regs + B2_MAC_1 + port * 8, ETH_ALEN);
3487 memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len); 3814 memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
3488 3815
3489 /* device is off until link detection */
3490 netif_carrier_off(dev);
3491 netif_stop_queue(dev);
3492
3493 return dev; 3816 return dev;
3494} 3817}
3495 3818
@@ -3906,12 +4229,14 @@ static struct pci_driver sky2_driver = {
3906 4229
3907static int __init sky2_init_module(void) 4230static int __init sky2_init_module(void)
3908{ 4231{
4232 sky2_debug_init();
3909 return pci_register_driver(&sky2_driver); 4233 return pci_register_driver(&sky2_driver);
3910} 4234}
3911 4235
3912static void __exit sky2_cleanup_module(void) 4236static void __exit sky2_cleanup_module(void)
3913{ 4237{
3914 pci_unregister_driver(&sky2_driver); 4238 pci_unregister_driver(&sky2_driver);
4239 sky2_debug_cleanup();
3915} 4240}
3916 4241
3917module_init(sky2_init_module); 4242module_init(sky2_init_module);
diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h
index b8c4a3b5eadf..dce4d276d443 100644
--- a/drivers/net/sky2.h
+++ b/drivers/net/sky2.h
@@ -14,6 +14,8 @@ enum {
14 PCI_DEV_REG3 = 0x80, 14 PCI_DEV_REG3 = 0x80,
15 PCI_DEV_REG4 = 0x84, 15 PCI_DEV_REG4 = 0x84,
16 PCI_DEV_REG5 = 0x88, 16 PCI_DEV_REG5 = 0x88,
17 PCI_CFG_REG_0 = 0x90,
18 PCI_CFG_REG_1 = 0x94,
17}; 19};
18 20
19enum { 21enum {
@@ -28,6 +30,7 @@ enum {
28enum pci_dev_reg_1 { 30enum pci_dev_reg_1 {
29 PCI_Y2_PIG_ENA = 1<<31, /* Enable Plug-in-Go (YUKON-2) */ 31 PCI_Y2_PIG_ENA = 1<<31, /* Enable Plug-in-Go (YUKON-2) */
30 PCI_Y2_DLL_DIS = 1<<30, /* Disable PCI DLL (YUKON-2) */ 32 PCI_Y2_DLL_DIS = 1<<30, /* Disable PCI DLL (YUKON-2) */
33 PCI_SW_PWR_ON_RST= 1<<30, /* SW Power on Reset (Yukon-EX) */
31 PCI_Y2_PHY2_COMA = 1<<29, /* Set PHY 2 to Coma Mode (YUKON-2) */ 34 PCI_Y2_PHY2_COMA = 1<<29, /* Set PHY 2 to Coma Mode (YUKON-2) */
32 PCI_Y2_PHY1_COMA = 1<<28, /* Set PHY 1 to Coma Mode (YUKON-2) */ 35 PCI_Y2_PHY1_COMA = 1<<28, /* Set PHY 1 to Coma Mode (YUKON-2) */
33 PCI_Y2_PHY2_POWD = 1<<27, /* Set PHY 2 to Power Down (YUKON-2) */ 36 PCI_Y2_PHY2_POWD = 1<<27, /* Set PHY 2 to Power Down (YUKON-2) */
@@ -67,6 +70,80 @@ enum pci_dev_reg_4 {
67 | P_ASPM_CLKRUN_REQUEST | P_ASPM_INT_FIFO_EMPTY, 70 | P_ASPM_CLKRUN_REQUEST | P_ASPM_INT_FIFO_EMPTY,
68}; 71};
69 72
73/* PCI_OUR_REG_5 32 bit Our Register 5 (Yukon-ECU only) */
74enum pci_dev_reg_5 {
75 /* Bit 31..27: for A3 & later */
76 P_CTL_DIV_CORE_CLK_ENA = 1<<31, /* Divide Core Clock Enable */
77 P_CTL_SRESET_VMAIN_AV = 1<<30, /* Soft Reset for Vmain_av De-Glitch */
78 P_CTL_BYPASS_VMAIN_AV = 1<<29, /* Bypass En. for Vmain_av De-Glitch */
79 P_CTL_TIM_VMAIN_AV_MSK = 3<<27, /* Bit 28..27: Timer Vmain_av Mask */
80 /* Bit 26..16: Release Clock on Event */
81 P_REL_PCIE_RST_DE_ASS = 1<<26, /* PCIe Reset De-Asserted */
82 P_REL_GPHY_REC_PACKET = 1<<25, /* GPHY Received Packet */
83 P_REL_INT_FIFO_N_EMPTY = 1<<24, /* Internal FIFO Not Empty */
84 P_REL_MAIN_PWR_AVAIL = 1<<23, /* Main Power Available */
85 P_REL_CLKRUN_REQ_REL = 1<<22, /* CLKRUN Request Release */
86 P_REL_PCIE_RESET_ASS = 1<<21, /* PCIe Reset Asserted */
87 P_REL_PME_ASSERTED = 1<<20, /* PME Asserted */
88 P_REL_PCIE_EXIT_L1_ST = 1<<19, /* PCIe Exit L1 State */
89 P_REL_LOADER_NOT_FIN = 1<<18, /* EPROM Loader Not Finished */
90 P_REL_PCIE_RX_EX_IDLE = 1<<17, /* PCIe Rx Exit Electrical Idle State */
91 P_REL_GPHY_LINK_UP = 1<<16, /* GPHY Link Up */
92
93 /* Bit 10.. 0: Mask for Gate Clock */
94 P_GAT_PCIE_RST_ASSERTED = 1<<10,/* PCIe Reset Asserted */
95 P_GAT_GPHY_N_REC_PACKET = 1<<9, /* GPHY Not Received Packet */
96 P_GAT_INT_FIFO_EMPTY = 1<<8, /* Internal FIFO Empty */
97 P_GAT_MAIN_PWR_N_AVAIL = 1<<7, /* Main Power Not Available */
98 P_GAT_CLKRUN_REQ_REL = 1<<6, /* CLKRUN Not Requested */
99 P_GAT_PCIE_RESET_ASS = 1<<5, /* PCIe Reset Asserted */
100 P_GAT_PME_DE_ASSERTED = 1<<4, /* PME De-Asserted */
101 P_GAT_PCIE_ENTER_L1_ST = 1<<3, /* PCIe Enter L1 State */
102 P_GAT_LOADER_FINISHED = 1<<2, /* EPROM Loader Finished */
103 P_GAT_PCIE_RX_EL_IDLE = 1<<1, /* PCIe Rx Electrical Idle State */
104 P_GAT_GPHY_LINK_DOWN = 1<<0, /* GPHY Link Down */
105
106 PCIE_OUR5_EVENT_CLK_D3_SET = P_REL_GPHY_REC_PACKET |
107 P_REL_INT_FIFO_N_EMPTY |
108 P_REL_PCIE_EXIT_L1_ST |
109 P_REL_PCIE_RX_EX_IDLE |
110 P_GAT_GPHY_N_REC_PACKET |
111 P_GAT_INT_FIFO_EMPTY |
112 P_GAT_PCIE_ENTER_L1_ST |
113 P_GAT_PCIE_RX_EL_IDLE,
114};
115
116#/* PCI_CFG_REG_1 32 bit Config Register 1 (Yukon-Ext only) */
117enum pci_cfg_reg1 {
118 P_CF1_DIS_REL_EVT_RST = 1<<24, /* Dis. Rel. Event during PCIE reset */
119 /* Bit 23..21: Release Clock on Event */
120 P_CF1_REL_LDR_NOT_FIN = 1<<23, /* EEPROM Loader Not Finished */
121 P_CF1_REL_VMAIN_AVLBL = 1<<22, /* Vmain available */
122 P_CF1_REL_PCIE_RESET = 1<<21, /* PCI-E reset */
123 /* Bit 20..18: Gate Clock on Event */
124 P_CF1_GAT_LDR_NOT_FIN = 1<<20, /* EEPROM Loader Finished */
125 P_CF1_GAT_PCIE_RX_IDLE = 1<<19, /* PCI-E Rx Electrical idle */
126 P_CF1_GAT_PCIE_RESET = 1<<18, /* PCI-E Reset */
127 P_CF1_PRST_PHY_CLKREQ = 1<<17, /* Enable PCI-E rst & PM2PHY gen. CLKREQ */
128 P_CF1_PCIE_RST_CLKREQ = 1<<16, /* Enable PCI-E rst generate CLKREQ */
129
130 P_CF1_ENA_CFG_LDR_DONE = 1<<8, /* Enable core level Config loader done */
131
132 P_CF1_ENA_TXBMU_RD_IDLE = 1<<1, /* Enable TX BMU Read IDLE for ASPM */
133 P_CF1_ENA_TXBMU_WR_IDLE = 1<<0, /* Enable TX BMU Write IDLE for ASPM */
134
135 PCIE_CFG1_EVENT_CLK_D3_SET = P_CF1_DIS_REL_EVT_RST |
136 P_CF1_REL_LDR_NOT_FIN |
137 P_CF1_REL_VMAIN_AVLBL |
138 P_CF1_REL_PCIE_RESET |
139 P_CF1_GAT_LDR_NOT_FIN |
140 P_CF1_GAT_PCIE_RESET |
141 P_CF1_PRST_PHY_CLKREQ |
142 P_CF1_ENA_CFG_LDR_DONE |
143 P_CF1_ENA_TXBMU_RD_IDLE |
144 P_CF1_ENA_TXBMU_WR_IDLE,
145};
146
70 147
71#define PCI_STATUS_ERROR_BITS (PCI_STATUS_DETECTED_PARITY | \ 148#define PCI_STATUS_ERROR_BITS (PCI_STATUS_DETECTED_PARITY | \
72 PCI_STATUS_SIG_SYSTEM_ERROR | \ 149 PCI_STATUS_SIG_SYSTEM_ERROR | \
@@ -364,6 +441,20 @@ enum {
364 TST_CFG_WRITE_OFF= 1<<0, /* Disable Config Reg WR */ 441 TST_CFG_WRITE_OFF= 1<<0, /* Disable Config Reg WR */
365}; 442};
366 443
444/* B2_GPIO */
445enum {
446 GLB_GPIO_CLK_DEB_ENA = 1<<31, /* Clock Debug Enable */
447 GLB_GPIO_CLK_DBG_MSK = 0xf<<26, /* Clock Debug */
448
449 GLB_GPIO_INT_RST_D3_DIS = 1<<15, /* Disable Internal Reset After D3 to D0 */
450 GLB_GPIO_LED_PAD_SPEED_UP = 1<<14, /* LED PAD Speed Up */
451 GLB_GPIO_STAT_RACE_DIS = 1<<13, /* Status Race Disable */
452 GLB_GPIO_TEST_SEL_MSK = 3<<11, /* Testmode Select */
453 GLB_GPIO_TEST_SEL_BASE = 1<<11,
454 GLB_GPIO_RAND_ENA = 1<<10, /* Random Enable */
455 GLB_GPIO_RAND_BIT_1 = 1<<9, /* Random Bit 1 */
456};
457
367/* B2_MAC_CFG 8 bit MAC Configuration / Chip Revision */ 458/* B2_MAC_CFG 8 bit MAC Configuration / Chip Revision */
368enum { 459enum {
369 CFG_CHIP_R_MSK = 0xf<<4, /* Bit 7.. 4: Chip Revision */ 460 CFG_CHIP_R_MSK = 0xf<<4, /* Bit 7.. 4: Chip Revision */
@@ -392,6 +483,11 @@ enum {
392 CHIP_REV_YU_FE_A2 = 2, 483 CHIP_REV_YU_FE_A2 = 2,
393 484
394}; 485};
486enum yukon_ex_rev {
487 CHIP_REV_YU_EX_A0 = 1,
488 CHIP_REV_YU_EX_B0 = 2,
489};
490
395 491
396/* B2_Y2_CLK_GATE 8 bit Clock Gating (Yukon-2 only) */ 492/* B2_Y2_CLK_GATE 8 bit Clock Gating (Yukon-2 only) */
397enum { 493enum {
@@ -515,23 +611,15 @@ enum {
515enum { 611enum {
516 B8_Q_REGS = 0x0400, /* base of Queue registers */ 612 B8_Q_REGS = 0x0400, /* base of Queue registers */
517 Q_D = 0x00, /* 8*32 bit Current Descriptor */ 613 Q_D = 0x00, /* 8*32 bit Current Descriptor */
518 Q_DA_L = 0x20, /* 32 bit Current Descriptor Address Low dWord */ 614 Q_VLAN = 0x20, /* 16 bit Current VLAN Tag */
519 Q_DA_H = 0x24, /* 32 bit Current Descriptor Address High dWord */ 615 Q_DONE = 0x24, /* 16 bit Done Index */
520 Q_AC_L = 0x28, /* 32 bit Current Address Counter Low dWord */ 616 Q_AC_L = 0x28, /* 32 bit Current Address Counter Low dWord */
521 Q_AC_H = 0x2c, /* 32 bit Current Address Counter High dWord */ 617 Q_AC_H = 0x2c, /* 32 bit Current Address Counter High dWord */
522 Q_BC = 0x30, /* 32 bit Current Byte Counter */ 618 Q_BC = 0x30, /* 32 bit Current Byte Counter */
523 Q_CSR = 0x34, /* 32 bit BMU Control/Status Register */ 619 Q_CSR = 0x34, /* 32 bit BMU Control/Status Register */
524 Q_F = 0x38, /* 32 bit Flag Register */ 620 Q_TEST = 0x38, /* 32 bit Test/Control Register */
525 Q_T1 = 0x3c, /* 32 bit Test Register 1 */
526 Q_T1_TR = 0x3c, /* 8 bit Test Register 1 Transfer SM */
527 Q_T1_WR = 0x3d, /* 8 bit Test Register 1 Write Descriptor SM */
528 Q_T1_RD = 0x3e, /* 8 bit Test Register 1 Read Descriptor SM */
529 Q_T1_SV = 0x3f, /* 8 bit Test Register 1 Supervisor SM */
530 Q_T2 = 0x40, /* 32 bit Test Register 2 */
531 Q_T3 = 0x44, /* 32 bit Test Register 3 */
532 621
533/* Yukon-2 */ 622/* Yukon-2 */
534 Q_DONE = 0x24, /* 16 bit Done Index (Yukon-2 only) */
535 Q_WM = 0x40, /* 16 bit FIFO Watermark */ 623 Q_WM = 0x40, /* 16 bit FIFO Watermark */
536 Q_AL = 0x42, /* 8 bit FIFO Alignment */ 624 Q_AL = 0x42, /* 8 bit FIFO Alignment */
537 Q_RSP = 0x44, /* 16 bit FIFO Read Shadow Pointer */ 625 Q_RSP = 0x44, /* 16 bit FIFO Read Shadow Pointer */
@@ -545,15 +633,16 @@ enum {
545}; 633};
546#define Q_ADDR(reg, offs) (B8_Q_REGS + (reg) + (offs)) 634#define Q_ADDR(reg, offs) (B8_Q_REGS + (reg) + (offs))
547 635
548/* Q_F 32 bit Flag Register */ 636/* Q_TEST 32 bit Test Register */
549enum { 637enum {
550 F_ALM_FULL = 1<<27, /* Rx FIFO: almost full */ 638 /* Transmit */
551 F_EMPTY = 1<<27, /* Tx FIFO: empty flag */ 639 F_TX_CHK_AUTO_OFF = 1<<31, /* Tx checksum auto calc off (Yukon EX) */
552 F_FIFO_EOF = 1<<26, /* Tag (EOF Flag) bit in FIFO */ 640 F_TX_CHK_AUTO_ON = 1<<30, /* Tx checksum auto calc off (Yukon EX) */
553 F_WM_REACHED = 1<<25, /* Watermark reached */ 641
642 /* Receive */
554 F_M_RX_RAM_DIS = 1<<24, /* MAC Rx RAM Read Port disable */ 643 F_M_RX_RAM_DIS = 1<<24, /* MAC Rx RAM Read Port disable */
555 F_FIFO_LEVEL = 0x1fL<<16, /* Bit 23..16: # of Qwords in FIFO */ 644
556 F_WATER_MARK = 0x0007ffL, /* Bit 10.. 0: Watermark */ 645 /* Hardware testbits not used */
557}; 646};
558 647
559/* Queue Prefetch Unit Offsets, use Y2_QADDR() to address (Yukon-2 only)*/ 648/* Queue Prefetch Unit Offsets, use Y2_QADDR() to address (Yukon-2 only)*/
@@ -1608,6 +1697,16 @@ enum {
1608 RX_VLAN_STRIP_ON = 1<<25, /* enable VLAN stripping */ 1697 RX_VLAN_STRIP_ON = 1<<25, /* enable VLAN stripping */
1609 RX_VLAN_STRIP_OFF = 1<<24, /* disable VLAN stripping */ 1698 RX_VLAN_STRIP_OFF = 1<<24, /* disable VLAN stripping */
1610 1699
1700 RX_MACSEC_FLUSH_ON = 1<<23,
1701 RX_MACSEC_FLUSH_OFF = 1<<22,
1702 RX_MACSEC_ASF_FLUSH_ON = 1<<21,
1703 RX_MACSEC_ASF_FLUSH_OFF = 1<<20,
1704
1705 GMF_RX_OVER_ON = 1<<19, /* enable flushing on receive overrun */
1706 GMF_RX_OVER_OFF = 1<<18, /* disable flushing on receive overrun */
1707 GMF_ASF_RX_OVER_ON = 1<<17, /* enable flushing of ASF when overrun */
1708 GMF_ASF_RX_OVER_OFF = 1<<16, /* disable flushing of ASF when overrun */
1709
1611 GMF_WP_TST_ON = 1<<14, /* Write Pointer Test On */ 1710 GMF_WP_TST_ON = 1<<14, /* Write Pointer Test On */
1612 GMF_WP_TST_OFF = 1<<13, /* Write Pointer Test Off */ 1711 GMF_WP_TST_OFF = 1<<13, /* Write Pointer Test Off */
1613 GMF_WP_STEP = 1<<12, /* Write Pointer Step/Increment */ 1712 GMF_WP_STEP = 1<<12, /* Write Pointer Step/Increment */
@@ -1720,6 +1819,15 @@ enum {
1720 1819
1721/* GMAC_CTRL 32 bit GMAC Control Reg (YUKON only) */ 1820/* GMAC_CTRL 32 bit GMAC Control Reg (YUKON only) */
1722enum { 1821enum {
1822 GMC_SET_RST = 1<<15,/* MAC SEC RST */
1823 GMC_SEC_RST_OFF = 1<<14,/* MAC SEC RSt OFF */
1824 GMC_BYP_MACSECRX_ON = 1<<13,/* Bypass macsec RX */
1825 GMC_BYP_MACSECRX_OFF= 1<<12,/* Bypass macsec RX off */
1826 GMC_BYP_MACSECTX_ON = 1<<11,/* Bypass macsec TX */
1827 GMC_BYP_MACSECTX_OFF= 1<<10,/* Bypass macsec TX off*/
1828 GMC_BYP_RETR_ON = 1<<9, /* Bypass retransmit FIFO On */
1829 GMC_BYP_RETR_OFF= 1<<8, /* Bypass retransmit FIFO Off */
1830
1723 GMC_H_BURST_ON = 1<<7, /* Half Duplex Burst Mode On */ 1831 GMC_H_BURST_ON = 1<<7, /* Half Duplex Burst Mode On */
1724 GMC_H_BURST_OFF = 1<<6, /* Half Duplex Burst Mode Off */ 1832 GMC_H_BURST_OFF = 1<<6, /* Half Duplex Burst Mode Off */
1725 GMC_F_LOOPB_ON = 1<<5, /* FIFO Loopback On */ 1833 GMC_F_LOOPB_ON = 1<<5, /* FIFO Loopback On */
@@ -1805,9 +1913,13 @@ enum {
1805 OP_ADDR64VLAN = OP_ADDR64 | OP_VLAN, 1913 OP_ADDR64VLAN = OP_ADDR64 | OP_VLAN,
1806 OP_LRGLEN = 0x24, 1914 OP_LRGLEN = 0x24,
1807 OP_LRGLENVLAN = OP_LRGLEN | OP_VLAN, 1915 OP_LRGLENVLAN = OP_LRGLEN | OP_VLAN,
1916 OP_MSS = 0x28,
1917 OP_MSSVLAN = OP_MSS | OP_VLAN,
1918
1808 OP_BUFFER = 0x40, 1919 OP_BUFFER = 0x40,
1809 OP_PACKET = 0x41, 1920 OP_PACKET = 0x41,
1810 OP_LARGESEND = 0x43, 1921 OP_LARGESEND = 0x43,
1922 OP_LSOV2 = 0x45,
1811 1923
1812/* YUKON-2 STATUS opcodes defines */ 1924/* YUKON-2 STATUS opcodes defines */
1813 OP_RXSTAT = 0x60, 1925 OP_RXSTAT = 0x60,
@@ -1818,6 +1930,19 @@ enum {
1818 OP_RXTIMEVLAN = OP_RXTIMESTAMP | OP_RXVLAN, 1930 OP_RXTIMEVLAN = OP_RXTIMESTAMP | OP_RXVLAN,
1819 OP_RSS_HASH = 0x65, 1931 OP_RSS_HASH = 0x65,
1820 OP_TXINDEXLE = 0x68, 1932 OP_TXINDEXLE = 0x68,
1933 OP_MACSEC = 0x6c,
1934 OP_PUTIDX = 0x70,
1935};
1936
1937enum status_css {
1938 CSS_TCPUDPCSOK = 1<<7, /* TCP / UDP checksum is ok */
1939 CSS_ISUDP = 1<<6, /* packet is a UDP packet */
1940 CSS_ISTCP = 1<<5, /* packet is a TCP packet */
1941 CSS_ISIPFRAG = 1<<4, /* packet is a TCP/UDP frag, CS calc not done */
1942 CSS_ISIPV6 = 1<<3, /* packet is a IPv6 packet */
1943 CSS_IPV4CSUMOK = 1<<2, /* IP v4: TCP header checksum is ok */
1944 CSS_ISIPV4 = 1<<1, /* packet is a IPv4 packet */
1945 CSS_LINK_BIT = 1<<0, /* port number (legacy) */
1821}; 1946};
1822 1947
1823/* Yukon 2 hardware interface */ 1948/* Yukon 2 hardware interface */
@@ -1838,7 +1963,7 @@ struct sky2_rx_le {
1838struct sky2_status_le { 1963struct sky2_status_le {
1839 __le32 status; /* also checksum */ 1964 __le32 status; /* also checksum */
1840 __le16 length; /* also vlan tag */ 1965 __le16 length; /* also vlan tag */
1841 u8 link; 1966 u8 css;
1842 u8 opcode; 1967 u8 opcode;
1843} __attribute((packed)); 1968} __attribute((packed));
1844 1969
@@ -1873,6 +1998,7 @@ struct sky2_port {
1873 struct sky2_tx_le *tx_le; 1998 struct sky2_tx_le *tx_le;
1874 u16 tx_cons; /* next le to check */ 1999 u16 tx_cons; /* next le to check */
1875 u16 tx_prod; /* next le to use */ 2000 u16 tx_prod; /* next le to use */
2001 u16 tx_next; /* debug only */
1876 u32 tx_addr64; 2002 u32 tx_addr64;
1877 u16 tx_pending; 2003 u16 tx_pending;
1878 u16 tx_last_mss; 2004 u16 tx_last_mss;
@@ -1903,6 +2029,9 @@ struct sky2_port {
1903 enum flow_control flow_mode; 2029 enum flow_control flow_mode;
1904 enum flow_control flow_status; 2030 enum flow_control flow_status;
1905 2031
2032#ifdef CONFIG_SKY2_DEBUG
2033 struct dentry *debugfs;
2034#endif
1906 struct net_device_stats net_stats; 2035 struct net_device_stats net_stats;
1907 2036
1908}; 2037};
diff --git a/drivers/net/sni_82596.c b/drivers/net/sni_82596.c
new file mode 100644
index 000000000000..2cf6794acb4f
--- /dev/null
+++ b/drivers/net/sni_82596.c
@@ -0,0 +1,185 @@
1/*
2 * sni_82596.c -- driver for intel 82596 ethernet controller, as
3 * used in older SNI RM machines
4 */
5
6#include <linux/module.h>
7#include <linux/kernel.h>
8#include <linux/string.h>
9#include <linux/errno.h>
10#include <linux/ioport.h>
11#include <linux/slab.h>
12#include <linux/interrupt.h>
13#include <linux/delay.h>
14#include <linux/netdevice.h>
15#include <linux/etherdevice.h>
16#include <linux/skbuff.h>
17#include <linux/init.h>
18#include <linux/types.h>
19#include <linux/bitops.h>
20#include <linux/platform_device.h>
21#include <linux/io.h>
22#include <linux/irq.h>
23
24#define SNI_82596_DRIVER_VERSION "SNI RM 82596 driver - Revision: 0.01"
25
26static const char sni_82596_string[] = "snirm_82596";
27
28#define DMA_ALLOC dma_alloc_coherent
29#define DMA_FREE dma_free_coherent
30#define DMA_WBACK(priv, addr, len) do { } while (0)
31#define DMA_INV(priv, addr, len) do { } while (0)
32#define DMA_WBACK_INV(priv, addr, len) do { } while (0)
33
34#define SYSBUS 0x00004400
35
36/* big endian CPU, 82596 little endian */
37#define SWAP32(x) cpu_to_le32((u32)(x))
38#define SWAP16(x) cpu_to_le16((u16)(x))
39
40#define OPT_MPU_16BIT 0x01
41
42#include "lib82596.c"
43
44MODULE_AUTHOR("Thomas Bogendoerfer");
45MODULE_DESCRIPTION("i82596 driver");
46MODULE_LICENSE("GPL");
47module_param(i596_debug, int, 0);
48MODULE_PARM_DESC(i596_debug, "82596 debug mask");
49
50static inline void ca(struct net_device *dev)
51{
52 struct i596_private *lp = netdev_priv(dev);
53
54 writel(0, lp->ca);
55}
56
57
58static void mpu_port(struct net_device *dev, int c, dma_addr_t x)
59{
60 struct i596_private *lp = netdev_priv(dev);
61
62 u32 v = (u32) (c) | (u32) (x);
63
64 if (lp->options & OPT_MPU_16BIT) {
65 writew(v & 0xffff, lp->mpu_port);
66 wmb(); /* order writes to MPU port */
67 udelay(1);
68 writew(v >> 16, lp->mpu_port);
69 } else {
70 writel(v, lp->mpu_port);
71 wmb(); /* order writes to MPU port */
72 udelay(1);
73 writel(v, lp->mpu_port);
74 }
75}
76
77
78static int __devinit sni_82596_probe(struct platform_device *dev)
79{
80 struct net_device *netdevice;
81 struct i596_private *lp;
82 struct resource *res, *ca, *idprom, *options;
83 int retval = -ENOMEM;
84 void __iomem *mpu_addr;
85 void __iomem *ca_addr;
86 u8 __iomem *eth_addr;
87
88 res = platform_get_resource(dev, IORESOURCE_MEM, 0);
89 ca = platform_get_resource(dev, IORESOURCE_MEM, 1);
90 options = platform_get_resource(dev, 0, 0);
91 idprom = platform_get_resource(dev, IORESOURCE_MEM, 2);
92 if (!res || !ca || !options || !idprom)
93 return -ENODEV;
94 mpu_addr = ioremap_nocache(res->start, 4);
95 if (!mpu_addr)
96 return -ENOMEM;
97 ca_addr = ioremap_nocache(ca->start, 4);
98 if (!ca_addr)
99 goto probe_failed_free_mpu;
100
101 printk(KERN_INFO "Found i82596 at 0x%x\n", res->start);
102
103 netdevice = alloc_etherdev(sizeof(struct i596_private));
104 if (!netdevice)
105 goto probe_failed_free_ca;
106
107 SET_NETDEV_DEV(netdevice, &dev->dev);
108 platform_set_drvdata (dev, netdevice);
109
110 netdevice->base_addr = res->start;
111 netdevice->irq = platform_get_irq(dev, 0);
112
113 eth_addr = ioremap_nocache(idprom->start, 0x10);
114 if (!eth_addr)
115 goto probe_failed;
116
117 /* someone seems to like messed up stuff */
118 netdevice->dev_addr[0] = readb(eth_addr + 0x0b);
119 netdevice->dev_addr[1] = readb(eth_addr + 0x0a);
120 netdevice->dev_addr[2] = readb(eth_addr + 0x09);
121 netdevice->dev_addr[3] = readb(eth_addr + 0x08);
122 netdevice->dev_addr[4] = readb(eth_addr + 0x07);
123 netdevice->dev_addr[5] = readb(eth_addr + 0x06);
124 iounmap(eth_addr);
125
126 if (!netdevice->irq) {
127 printk(KERN_ERR "%s: IRQ not found for i82596 at 0x%lx\n",
128 __FILE__, netdevice->base_addr);
129 goto probe_failed;
130 }
131
132 lp = netdev_priv(netdevice);
133 lp->options = options->flags & IORESOURCE_BITS;
134 lp->ca = ca_addr;
135 lp->mpu_port = mpu_addr;
136
137 retval = i82596_probe(netdevice);
138 if (retval == 0)
139 return 0;
140
141probe_failed:
142 free_netdev(netdevice);
143probe_failed_free_ca:
144 iounmap(ca_addr);
145probe_failed_free_mpu:
146 iounmap(mpu_addr);
147 return retval;
148}
149
150static int __devexit sni_82596_driver_remove(struct platform_device *pdev)
151{
152 struct net_device *dev = platform_get_drvdata(pdev);
153 struct i596_private *lp = netdev_priv(dev);
154
155 unregister_netdev(dev);
156 DMA_FREE(dev->dev.parent, sizeof(struct i596_private),
157 lp->dma, lp->dma_addr);
158 iounmap(lp->ca);
159 iounmap(lp->mpu_port);
160 free_netdev (dev);
161 return 0;
162}
163
164static struct platform_driver sni_82596_driver = {
165 .probe = sni_82596_probe,
166 .remove = __devexit_p(sni_82596_driver_remove),
167 .driver = {
168 .name = sni_82596_string,
169 },
170};
171
172static int __devinit sni_82596_init(void)
173{
174 printk(KERN_INFO SNI_82596_DRIVER_VERSION "\n");
175 return platform_driver_register(&sni_82596_driver);
176}
177
178
179static void __exit sni_82596_exit(void)
180{
181 platform_driver_unregister(&sni_82596_driver);
182}
183
184module_init(sni_82596_init);
185module_exit(sni_82596_exit);
diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c
index 7a4aa6a9f949..590b12c7246c 100644
--- a/drivers/net/spider_net.c
+++ b/drivers/net/spider_net.c
@@ -434,7 +434,8 @@ spider_net_prepare_rx_descr(struct spider_net_card *card,
434 bufsize + SPIDER_NET_RXBUF_ALIGN - 1); 434 bufsize + SPIDER_NET_RXBUF_ALIGN - 1);
435 if (!descr->skb) { 435 if (!descr->skb) {
436 if (netif_msg_rx_err(card) && net_ratelimit()) 436 if (netif_msg_rx_err(card) && net_ratelimit())
437 pr_err("Not enough memory to allocate rx buffer\n"); 437 dev_err(&card->netdev->dev,
438 "Not enough memory to allocate rx buffer\n");
438 card->spider_stats.alloc_rx_skb_error++; 439 card->spider_stats.alloc_rx_skb_error++;
439 return -ENOMEM; 440 return -ENOMEM;
440 } 441 }
@@ -455,7 +456,7 @@ spider_net_prepare_rx_descr(struct spider_net_card *card,
455 dev_kfree_skb_any(descr->skb); 456 dev_kfree_skb_any(descr->skb);
456 descr->skb = NULL; 457 descr->skb = NULL;
457 if (netif_msg_rx_err(card) && net_ratelimit()) 458 if (netif_msg_rx_err(card) && net_ratelimit())
458 pr_err("Could not iommu-map rx buffer\n"); 459 dev_err(&card->netdev->dev, "Could not iommu-map rx buffer\n");
459 card->spider_stats.rx_iommu_map_error++; 460 card->spider_stats.rx_iommu_map_error++;
460 hwdescr->dmac_cmd_status = SPIDER_NET_DESCR_NOT_IN_USE; 461 hwdescr->dmac_cmd_status = SPIDER_NET_DESCR_NOT_IN_USE;
461 } else { 462 } else {
@@ -500,6 +501,20 @@ spider_net_enable_rxdmac(struct spider_net_card *card)
500} 501}
501 502
502/** 503/**
504 * spider_net_disable_rxdmac - disables the receive DMA controller
505 * @card: card structure
506 *
507 * spider_net_disable_rxdmac terminates processing on the DMA controller
508 * by turing off the DMA controller, with the force-end flag set.
509 */
510static inline void
511spider_net_disable_rxdmac(struct spider_net_card *card)
512{
513 spider_net_write_reg(card, SPIDER_NET_GDADMACCNTR,
514 SPIDER_NET_DMA_RX_FEND_VALUE);
515}
516
517/**
503 * spider_net_refill_rx_chain - refills descriptors/skbs in the rx chains 518 * spider_net_refill_rx_chain - refills descriptors/skbs in the rx chains
504 * @card: card structure 519 * @card: card structure
505 * 520 *
@@ -655,20 +670,6 @@ write_hash:
655} 670}
656 671
657/** 672/**
658 * spider_net_disable_rxdmac - disables the receive DMA controller
659 * @card: card structure
660 *
661 * spider_net_disable_rxdmac terminates processing on the DMA controller by
662 * turing off DMA and issueing a force end
663 */
664static void
665spider_net_disable_rxdmac(struct spider_net_card *card)
666{
667 spider_net_write_reg(card, SPIDER_NET_GDADMACCNTR,
668 SPIDER_NET_DMA_RX_FEND_VALUE);
669}
670
671/**
672 * spider_net_prepare_tx_descr - fill tx descriptor with skb data 673 * spider_net_prepare_tx_descr - fill tx descriptor with skb data
673 * @card: card structure 674 * @card: card structure
674 * @descr: descriptor structure to fill out 675 * @descr: descriptor structure to fill out
@@ -692,7 +693,7 @@ spider_net_prepare_tx_descr(struct spider_net_card *card,
692 buf = pci_map_single(card->pdev, skb->data, skb->len, PCI_DMA_TODEVICE); 693 buf = pci_map_single(card->pdev, skb->data, skb->len, PCI_DMA_TODEVICE);
693 if (pci_dma_mapping_error(buf)) { 694 if (pci_dma_mapping_error(buf)) {
694 if (netif_msg_tx_err(card) && net_ratelimit()) 695 if (netif_msg_tx_err(card) && net_ratelimit())
695 pr_err("could not iommu-map packet (%p, %i). " 696 dev_err(&card->netdev->dev, "could not iommu-map packet (%p, %i). "
696 "Dropping packet\n", skb->data, skb->len); 697 "Dropping packet\n", skb->data, skb->len);
697 card->spider_stats.tx_iommu_map_error++; 698 card->spider_stats.tx_iommu_map_error++;
698 return -ENOMEM; 699 return -ENOMEM;
@@ -715,7 +716,7 @@ spider_net_prepare_tx_descr(struct spider_net_card *card,
715 hwdescr->data_status = 0; 716 hwdescr->data_status = 0;
716 717
717 hwdescr->dmac_cmd_status = 718 hwdescr->dmac_cmd_status =
718 SPIDER_NET_DESCR_CARDOWNED | SPIDER_NET_DMAC_NOCS; 719 SPIDER_NET_DESCR_CARDOWNED | SPIDER_NET_DMAC_TXFRMTL;
719 spin_unlock_irqrestore(&chain->lock, flags); 720 spin_unlock_irqrestore(&chain->lock, flags);
720 721
721 if (skb->ip_summed == CHECKSUM_PARTIAL) 722 if (skb->ip_summed == CHECKSUM_PARTIAL)
@@ -832,9 +833,8 @@ spider_net_release_tx_chain(struct spider_net_card *card, int brutal)
832 case SPIDER_NET_DESCR_PROTECTION_ERROR: 833 case SPIDER_NET_DESCR_PROTECTION_ERROR:
833 case SPIDER_NET_DESCR_FORCE_END: 834 case SPIDER_NET_DESCR_FORCE_END:
834 if (netif_msg_tx_err(card)) 835 if (netif_msg_tx_err(card))
835 pr_err("%s: forcing end of tx descriptor " 836 dev_err(&card->netdev->dev, "forcing end of tx descriptor "
836 "with status x%02x\n", 837 "with status x%02x\n", status);
837 card->netdev->name, status);
838 card->netdev_stats.tx_errors++; 838 card->netdev_stats.tx_errors++;
839 break; 839 break;
840 840
@@ -1022,34 +1022,94 @@ spider_net_pass_skb_up(struct spider_net_descr *descr,
1022 netif_receive_skb(skb); 1022 netif_receive_skb(skb);
1023} 1023}
1024 1024
1025#ifdef DEBUG
1026static void show_rx_chain(struct spider_net_card *card) 1025static void show_rx_chain(struct spider_net_card *card)
1027{ 1026{
1028 struct spider_net_descr_chain *chain = &card->rx_chain; 1027 struct spider_net_descr_chain *chain = &card->rx_chain;
1029 struct spider_net_descr *start= chain->tail; 1028 struct spider_net_descr *start= chain->tail;
1030 struct spider_net_descr *descr= start; 1029 struct spider_net_descr *descr= start;
1030 struct spider_net_hw_descr *hwd = start->hwdescr;
1031 struct device *dev = &card->netdev->dev;
1032 u32 curr_desc, next_desc;
1031 int status; 1033 int status;
1032 1034
1035 int tot = 0;
1033 int cnt = 0; 1036 int cnt = 0;
1034 int cstat = spider_net_get_descr_status(descr); 1037 int off = start - chain->ring;
1035 printk(KERN_INFO "RX chain tail at descr=%ld\n", 1038 int cstat = hwd->dmac_cmd_status;
1036 (start - card->descr) - card->tx_chain.num_desc); 1039
1040 dev_info(dev, "Total number of descrs=%d\n",
1041 chain->num_desc);
1042 dev_info(dev, "Chain tail located at descr=%d, status=0x%x\n",
1043 off, cstat);
1044
1045 curr_desc = spider_net_read_reg(card, SPIDER_NET_GDACTDPA);
1046 next_desc = spider_net_read_reg(card, SPIDER_NET_GDACNEXTDA);
1047
1037 status = cstat; 1048 status = cstat;
1038 do 1049 do
1039 { 1050 {
1040 status = spider_net_get_descr_status(descr); 1051 hwd = descr->hwdescr;
1052 off = descr - chain->ring;
1053 status = hwd->dmac_cmd_status;
1054
1055 if (descr == chain->head)
1056 dev_info(dev, "Chain head is at %d, head status=0x%x\n",
1057 off, status);
1058
1059 if (curr_desc == descr->bus_addr)
1060 dev_info(dev, "HW curr desc (GDACTDPA) is at %d, status=0x%x\n",
1061 off, status);
1062
1063 if (next_desc == descr->bus_addr)
1064 dev_info(dev, "HW next desc (GDACNEXTDA) is at %d, status=0x%x\n",
1065 off, status);
1066
1067 if (hwd->next_descr_addr == 0)
1068 dev_info(dev, "chain is cut at %d\n", off);
1069
1041 if (cstat != status) { 1070 if (cstat != status) {
1042 printk(KERN_INFO "Have %d descrs with stat=x%08x\n", cnt, cstat); 1071 int from = (chain->num_desc + off - cnt) % chain->num_desc;
1072 int to = (chain->num_desc + off - 1) % chain->num_desc;
1073 dev_info(dev, "Have %d (from %d to %d) descrs "
1074 "with stat=0x%08x\n", cnt, from, to, cstat);
1043 cstat = status; 1075 cstat = status;
1044 cnt = 0; 1076 cnt = 0;
1045 } 1077 }
1078
1046 cnt ++; 1079 cnt ++;
1080 tot ++;
1081 descr = descr->next;
1082 } while (descr != start);
1083
1084 dev_info(dev, "Last %d descrs with stat=0x%08x "
1085 "for a total of %d descrs\n", cnt, cstat, tot);
1086
1087#ifdef DEBUG
1088 /* Now dump the whole ring */
1089 descr = start;
1090 do
1091 {
1092 struct spider_net_hw_descr *hwd = descr->hwdescr;
1093 status = spider_net_get_descr_status(hwd);
1094 cnt = descr - chain->ring;
1095 dev_info(dev, "Descr %d stat=0x%08x skb=%p\n",
1096 cnt, status, descr->skb);
1097 dev_info(dev, "bus addr=%08x buf addr=%08x sz=%d\n",
1098 descr->bus_addr, hwd->buf_addr, hwd->buf_size);
1099 dev_info(dev, "next=%08x result sz=%d valid sz=%d\n",
1100 hwd->next_descr_addr, hwd->result_size,
1101 hwd->valid_size);
1102 dev_info(dev, "dmac=%08x data stat=%08x data err=%08x\n",
1103 hwd->dmac_cmd_status, hwd->data_status,
1104 hwd->data_error);
1105 dev_info(dev, "\n");
1106
1047 descr = descr->next; 1107 descr = descr->next;
1048 } while (descr != start); 1108 } while (descr != start);
1049 printk(KERN_INFO "Last %d descrs with stat=x%08x\n", cnt, cstat);
1050}
1051#endif 1109#endif
1052 1110
1111}
1112
1053/** 1113/**
1054 * spider_net_resync_head_ptr - Advance head ptr past empty descrs 1114 * spider_net_resync_head_ptr - Advance head ptr past empty descrs
1055 * 1115 *
@@ -1127,6 +1187,7 @@ spider_net_decode_one_descr(struct spider_net_card *card)
1127 struct spider_net_descr_chain *chain = &card->rx_chain; 1187 struct spider_net_descr_chain *chain = &card->rx_chain;
1128 struct spider_net_descr *descr = chain->tail; 1188 struct spider_net_descr *descr = chain->tail;
1129 struct spider_net_hw_descr *hwdescr = descr->hwdescr; 1189 struct spider_net_hw_descr *hwdescr = descr->hwdescr;
1190 u32 hw_buf_addr;
1130 int status; 1191 int status;
1131 1192
1132 status = spider_net_get_descr_status(hwdescr); 1193 status = spider_net_get_descr_status(hwdescr);
@@ -1140,15 +1201,17 @@ spider_net_decode_one_descr(struct spider_net_card *card)
1140 chain->tail = descr->next; 1201 chain->tail = descr->next;
1141 1202
1142 /* unmap descriptor */ 1203 /* unmap descriptor */
1143 pci_unmap_single(card->pdev, hwdescr->buf_addr, 1204 hw_buf_addr = hwdescr->buf_addr;
1205 hwdescr->buf_addr = 0xffffffff;
1206 pci_unmap_single(card->pdev, hw_buf_addr,
1144 SPIDER_NET_MAX_FRAME, PCI_DMA_FROMDEVICE); 1207 SPIDER_NET_MAX_FRAME, PCI_DMA_FROMDEVICE);
1145 1208
1146 if ( (status == SPIDER_NET_DESCR_RESPONSE_ERROR) || 1209 if ( (status == SPIDER_NET_DESCR_RESPONSE_ERROR) ||
1147 (status == SPIDER_NET_DESCR_PROTECTION_ERROR) || 1210 (status == SPIDER_NET_DESCR_PROTECTION_ERROR) ||
1148 (status == SPIDER_NET_DESCR_FORCE_END) ) { 1211 (status == SPIDER_NET_DESCR_FORCE_END) ) {
1149 if (netif_msg_rx_err(card)) 1212 if (netif_msg_rx_err(card))
1150 pr_err("%s: dropping RX descriptor with state %d\n", 1213 dev_err(&card->netdev->dev,
1151 card->netdev->name, status); 1214 "dropping RX descriptor with state %d\n", status);
1152 card->netdev_stats.rx_dropped++; 1215 card->netdev_stats.rx_dropped++;
1153 goto bad_desc; 1216 goto bad_desc;
1154 } 1217 }
@@ -1156,8 +1219,8 @@ spider_net_decode_one_descr(struct spider_net_card *card)
1156 if ( (status != SPIDER_NET_DESCR_COMPLETE) && 1219 if ( (status != SPIDER_NET_DESCR_COMPLETE) &&
1157 (status != SPIDER_NET_DESCR_FRAME_END) ) { 1220 (status != SPIDER_NET_DESCR_FRAME_END) ) {
1158 if (netif_msg_rx_err(card)) 1221 if (netif_msg_rx_err(card))
1159 pr_err("%s: RX descriptor with unknown state %d\n", 1222 dev_err(&card->netdev->dev,
1160 card->netdev->name, status); 1223 "RX descriptor with unknown state %d\n", status);
1161 card->spider_stats.rx_desc_unk_state++; 1224 card->spider_stats.rx_desc_unk_state++;
1162 goto bad_desc; 1225 goto bad_desc;
1163 } 1226 }
@@ -1165,18 +1228,17 @@ spider_net_decode_one_descr(struct spider_net_card *card)
1165 /* The cases we'll throw away the packet immediately */ 1228 /* The cases we'll throw away the packet immediately */
1166 if (hwdescr->data_error & SPIDER_NET_DESTROY_RX_FLAGS) { 1229 if (hwdescr->data_error & SPIDER_NET_DESTROY_RX_FLAGS) {
1167 if (netif_msg_rx_err(card)) 1230 if (netif_msg_rx_err(card))
1168 pr_err("%s: error in received descriptor found, " 1231 dev_err(&card->netdev->dev,
1232 "error in received descriptor found, "
1169 "data_status=x%08x, data_error=x%08x\n", 1233 "data_status=x%08x, data_error=x%08x\n",
1170 card->netdev->name,
1171 hwdescr->data_status, hwdescr->data_error); 1234 hwdescr->data_status, hwdescr->data_error);
1172 goto bad_desc; 1235 goto bad_desc;
1173 } 1236 }
1174 1237
1175 if (hwdescr->dmac_cmd_status & 0xfcf4) { 1238 if (hwdescr->dmac_cmd_status & SPIDER_NET_DESCR_BAD_STATUS) {
1176 pr_err("%s: bad status, cmd_status=x%08x\n", 1239 dev_err(&card->netdev->dev, "bad status, cmd_status=x%08x\n",
1177 card->netdev->name,
1178 hwdescr->dmac_cmd_status); 1240 hwdescr->dmac_cmd_status);
1179 pr_err("buf_addr=x%08x\n", hwdescr->buf_addr); 1241 pr_err("buf_addr=x%08x\n", hw_buf_addr);
1180 pr_err("buf_size=x%08x\n", hwdescr->buf_size); 1242 pr_err("buf_size=x%08x\n", hwdescr->buf_size);
1181 pr_err("next_descr_addr=x%08x\n", hwdescr->next_descr_addr); 1243 pr_err("next_descr_addr=x%08x\n", hwdescr->next_descr_addr);
1182 pr_err("result_size=x%08x\n", hwdescr->result_size); 1244 pr_err("result_size=x%08x\n", hwdescr->result_size);
@@ -1196,6 +1258,8 @@ spider_net_decode_one_descr(struct spider_net_card *card)
1196 return 1; 1258 return 1;
1197 1259
1198bad_desc: 1260bad_desc:
1261 if (netif_msg_rx_err(card))
1262 show_rx_chain(card);
1199 dev_kfree_skb_irq(descr->skb); 1263 dev_kfree_skb_irq(descr->skb);
1200 descr->skb = NULL; 1264 descr->skb = NULL;
1201 hwdescr->dmac_cmd_status = SPIDER_NET_DESCR_NOT_IN_USE; 1265 hwdescr->dmac_cmd_status = SPIDER_NET_DESCR_NOT_IN_USE;
@@ -1221,7 +1285,6 @@ spider_net_poll(struct net_device *netdev, int *budget)
1221 int packets_to_do, packets_done = 0; 1285 int packets_to_do, packets_done = 0;
1222 int no_more_packets = 0; 1286 int no_more_packets = 0;
1223 1287
1224 spider_net_cleanup_tx_ring(card);
1225 packets_to_do = min(*budget, netdev->quota); 1288 packets_to_do = min(*budget, netdev->quota);
1226 1289
1227 while (packets_to_do) { 1290 while (packets_to_do) {
@@ -1246,6 +1309,8 @@ spider_net_poll(struct net_device *netdev, int *budget)
1246 spider_net_refill_rx_chain(card); 1309 spider_net_refill_rx_chain(card);
1247 spider_net_enable_rxdmac(card); 1310 spider_net_enable_rxdmac(card);
1248 1311
1312 spider_net_cleanup_tx_ring(card);
1313
1249 /* if all packets are in the stack, enable interrupts and return 0 */ 1314 /* if all packets are in the stack, enable interrupts and return 0 */
1250 /* if not, return 1 */ 1315 /* if not, return 1 */
1251 if (no_more_packets) { 1316 if (no_more_packets) {
@@ -1376,11 +1441,17 @@ static void
1376spider_net_handle_error_irq(struct spider_net_card *card, u32 status_reg) 1441spider_net_handle_error_irq(struct spider_net_card *card, u32 status_reg)
1377{ 1442{
1378 u32 error_reg1, error_reg2; 1443 u32 error_reg1, error_reg2;
1444 u32 mask_reg1, mask_reg2;
1379 u32 i; 1445 u32 i;
1380 int show_error = 1; 1446 int show_error = 1;
1381 1447
1382 error_reg1 = spider_net_read_reg(card, SPIDER_NET_GHIINT1STS); 1448 error_reg1 = spider_net_read_reg(card, SPIDER_NET_GHIINT1STS);
1383 error_reg2 = spider_net_read_reg(card, SPIDER_NET_GHIINT2STS); 1449 error_reg2 = spider_net_read_reg(card, SPIDER_NET_GHIINT2STS);
1450 mask_reg1 = spider_net_read_reg(card, SPIDER_NET_GHIINT1MSK);
1451 mask_reg2 = spider_net_read_reg(card,SPIDER_NET_GHIINT2MSK);
1452
1453 error_reg1 &= mask_reg1;
1454 error_reg2 &= mask_reg2;
1384 1455
1385 /* check GHIINT0STS ************************************/ 1456 /* check GHIINT0STS ************************************/
1386 if (status_reg) 1457 if (status_reg)
@@ -1415,7 +1486,7 @@ spider_net_handle_error_irq(struct spider_net_card *card, u32 status_reg)
1415 case SPIDER_NET_GPWFFINT: 1486 case SPIDER_NET_GPWFFINT:
1416 /* PHY command queue full */ 1487 /* PHY command queue full */
1417 if (netif_msg_intr(card)) 1488 if (netif_msg_intr(card))
1418 pr_err("PHY write queue full\n"); 1489 dev_err(&card->netdev->dev, "PHY write queue full\n");
1419 show_error = 0; 1490 show_error = 0;
1420 break; 1491 break;
1421 1492
@@ -1582,9 +1653,8 @@ spider_net_handle_error_irq(struct spider_net_card *card, u32 status_reg)
1582 } 1653 }
1583 1654
1584 if ((show_error) && (netif_msg_intr(card)) && net_ratelimit()) 1655 if ((show_error) && (netif_msg_intr(card)) && net_ratelimit())
1585 pr_err("Got error interrupt on %s, GHIINT0STS = 0x%08x, " 1656 dev_err(&card->netdev->dev, "Error interrupt, GHIINT0STS = 0x%08x, "
1586 "GHIINT1STS = 0x%08x, GHIINT2STS = 0x%08x\n", 1657 "GHIINT1STS = 0x%08x, GHIINT2STS = 0x%08x\n",
1587 card->netdev->name,
1588 status_reg, error_reg1, error_reg2); 1658 status_reg, error_reg1, error_reg2);
1589 1659
1590 /* clear interrupt sources */ 1660 /* clear interrupt sources */
@@ -1609,9 +1679,11 @@ spider_net_interrupt(int irq, void *ptr)
1609{ 1679{
1610 struct net_device *netdev = ptr; 1680 struct net_device *netdev = ptr;
1611 struct spider_net_card *card = netdev_priv(netdev); 1681 struct spider_net_card *card = netdev_priv(netdev);
1612 u32 status_reg; 1682 u32 status_reg, mask_reg;
1613 1683
1614 status_reg = spider_net_read_reg(card, SPIDER_NET_GHIINT0STS); 1684 status_reg = spider_net_read_reg(card, SPIDER_NET_GHIINT0STS);
1685 mask_reg = spider_net_read_reg(card, SPIDER_NET_GHIINT0MSK);
1686 status_reg &= mask_reg;
1615 1687
1616 if (!status_reg) 1688 if (!status_reg)
1617 return IRQ_NONE; 1689 return IRQ_NONE;
@@ -1653,6 +1725,38 @@ spider_net_poll_controller(struct net_device *netdev)
1653#endif /* CONFIG_NET_POLL_CONTROLLER */ 1725#endif /* CONFIG_NET_POLL_CONTROLLER */
1654 1726
1655/** 1727/**
1728 * spider_net_enable_interrupts - enable interrupts
1729 * @card: card structure
1730 *
1731 * spider_net_enable_interrupt enables several interrupts
1732 */
1733static void
1734spider_net_enable_interrupts(struct spider_net_card *card)
1735{
1736 spider_net_write_reg(card, SPIDER_NET_GHIINT0MSK,
1737 SPIDER_NET_INT0_MASK_VALUE);
1738 spider_net_write_reg(card, SPIDER_NET_GHIINT1MSK,
1739 SPIDER_NET_INT1_MASK_VALUE);
1740 spider_net_write_reg(card, SPIDER_NET_GHIINT2MSK,
1741 SPIDER_NET_INT2_MASK_VALUE);
1742}
1743
1744/**
1745 * spider_net_disable_interrupts - disable interrupts
1746 * @card: card structure
1747 *
1748 * spider_net_disable_interrupts disables all the interrupts
1749 */
1750static void
1751spider_net_disable_interrupts(struct spider_net_card *card)
1752{
1753 spider_net_write_reg(card, SPIDER_NET_GHIINT0MSK, 0);
1754 spider_net_write_reg(card, SPIDER_NET_GHIINT1MSK, 0);
1755 spider_net_write_reg(card, SPIDER_NET_GHIINT2MSK, 0);
1756 spider_net_write_reg(card, SPIDER_NET_GMACINTEN, 0);
1757}
1758
1759/**
1656 * spider_net_init_card - initializes the card 1760 * spider_net_init_card - initializes the card
1657 * @card: card structure 1761 * @card: card structure
1658 * 1762 *
@@ -1672,6 +1776,7 @@ spider_net_init_card(struct spider_net_card *card)
1672 spider_net_write_reg(card, SPIDER_NET_GMACOPEMD, 1776 spider_net_write_reg(card, SPIDER_NET_GMACOPEMD,
1673 spider_net_read_reg(card, SPIDER_NET_GMACOPEMD) | 0x4); 1777 spider_net_read_reg(card, SPIDER_NET_GMACOPEMD) | 0x4);
1674 1778
1779 spider_net_disable_interrupts(card);
1675} 1780}
1676 1781
1677/** 1782/**
@@ -1759,14 +1864,6 @@ spider_net_enable_card(struct spider_net_card *card)
1759 spider_net_write_reg(card, SPIDER_NET_GMACOPEMD, 1864 spider_net_write_reg(card, SPIDER_NET_GMACOPEMD,
1760 SPIDER_NET_OPMODE_VALUE); 1865 SPIDER_NET_OPMODE_VALUE);
1761 1866
1762 /* set interrupt mask registers */
1763 spider_net_write_reg(card, SPIDER_NET_GHIINT0MSK,
1764 SPIDER_NET_INT0_MASK_VALUE);
1765 spider_net_write_reg(card, SPIDER_NET_GHIINT1MSK,
1766 SPIDER_NET_INT1_MASK_VALUE);
1767 spider_net_write_reg(card, SPIDER_NET_GHIINT2MSK,
1768 SPIDER_NET_INT2_MASK_VALUE);
1769
1770 spider_net_write_reg(card, SPIDER_NET_GDTDMACCNTR, 1867 spider_net_write_reg(card, SPIDER_NET_GDTDMACCNTR,
1771 SPIDER_NET_GDTBSTA); 1868 SPIDER_NET_GDTBSTA);
1772} 1869}
@@ -1849,7 +1946,8 @@ spider_net_init_firmware(struct spider_net_card *card)
1849 SPIDER_NET_FIRMWARE_NAME, &card->pdev->dev) == 0) { 1946 SPIDER_NET_FIRMWARE_NAME, &card->pdev->dev) == 0) {
1850 if ( (firmware->size != SPIDER_NET_FIRMWARE_LEN) && 1947 if ( (firmware->size != SPIDER_NET_FIRMWARE_LEN) &&
1851 netif_msg_probe(card) ) { 1948 netif_msg_probe(card) ) {
1852 pr_err("Incorrect size of spidernet firmware in " \ 1949 dev_err(&card->netdev->dev,
1950 "Incorrect size of spidernet firmware in " \
1853 "filesystem. Looking in host firmware...\n"); 1951 "filesystem. Looking in host firmware...\n");
1854 goto try_host_fw; 1952 goto try_host_fw;
1855 } 1953 }
@@ -1873,8 +1971,8 @@ try_host_fw:
1873 1971
1874 if ( (fw_size != SPIDER_NET_FIRMWARE_LEN) && 1972 if ( (fw_size != SPIDER_NET_FIRMWARE_LEN) &&
1875 netif_msg_probe(card) ) { 1973 netif_msg_probe(card) ) {
1876 pr_err("Incorrect size of spidernet firmware in " \ 1974 dev_err(&card->netdev->dev,
1877 "host firmware\n"); 1975 "Incorrect size of spidernet firmware in host firmware\n");
1878 goto done; 1976 goto done;
1879 } 1977 }
1880 1978
@@ -1884,7 +1982,8 @@ done:
1884 return err; 1982 return err;
1885out_err: 1983out_err:
1886 if (netif_msg_probe(card)) 1984 if (netif_msg_probe(card))
1887 pr_err("Couldn't find spidernet firmware in filesystem " \ 1985 dev_err(&card->netdev->dev,
1986 "Couldn't find spidernet firmware in filesystem " \
1888 "or host firmware\n"); 1987 "or host firmware\n");
1889 return err; 1988 return err;
1890} 1989}
@@ -1941,6 +2040,8 @@ spider_net_open(struct net_device *netdev)
1941 netif_carrier_on(netdev); 2040 netif_carrier_on(netdev);
1942 netif_poll_enable(netdev); 2041 netif_poll_enable(netdev);
1943 2042
2043 spider_net_enable_interrupts(card);
2044
1944 return 0; 2045 return 0;
1945 2046
1946register_int_failed: 2047register_int_failed:
@@ -2113,11 +2214,7 @@ spider_net_stop(struct net_device *netdev)
2113 del_timer_sync(&card->tx_timer); 2214 del_timer_sync(&card->tx_timer);
2114 del_timer_sync(&card->aneg_timer); 2215 del_timer_sync(&card->aneg_timer);
2115 2216
2116 /* disable/mask all interrupts */ 2217 spider_net_disable_interrupts(card);
2117 spider_net_write_reg(card, SPIDER_NET_GHIINT0MSK, 0);
2118 spider_net_write_reg(card, SPIDER_NET_GHIINT1MSK, 0);
2119 spider_net_write_reg(card, SPIDER_NET_GHIINT2MSK, 0);
2120 spider_net_write_reg(card, SPIDER_NET_GMACINTEN, 0);
2121 2218
2122 free_irq(netdev->irq, netdev); 2219 free_irq(netdev->irq, netdev);
2123 2220
@@ -2279,13 +2376,14 @@ spider_net_setup_netdev(struct spider_net_card *card)
2279 2376
2280 result = spider_net_set_mac(netdev, &addr); 2377 result = spider_net_set_mac(netdev, &addr);
2281 if ((result) && (netif_msg_probe(card))) 2378 if ((result) && (netif_msg_probe(card)))
2282 pr_err("Failed to set MAC address: %i\n", result); 2379 dev_err(&card->netdev->dev,
2380 "Failed to set MAC address: %i\n", result);
2283 2381
2284 result = register_netdev(netdev); 2382 result = register_netdev(netdev);
2285 if (result) { 2383 if (result) {
2286 if (netif_msg_probe(card)) 2384 if (netif_msg_probe(card))
2287 pr_err("Couldn't register net_device: %i\n", 2385 dev_err(&card->netdev->dev,
2288 result); 2386 "Couldn't register net_device: %i\n", result);
2289 return result; 2387 return result;
2290 } 2388 }
2291 2389
@@ -2363,17 +2461,19 @@ spider_net_setup_pci_dev(struct pci_dev *pdev)
2363 unsigned long mmio_start, mmio_len; 2461 unsigned long mmio_start, mmio_len;
2364 2462
2365 if (pci_enable_device(pdev)) { 2463 if (pci_enable_device(pdev)) {
2366 pr_err("Couldn't enable PCI device\n"); 2464 dev_err(&pdev->dev, "Couldn't enable PCI device\n");
2367 return NULL; 2465 return NULL;
2368 } 2466 }
2369 2467
2370 if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) { 2468 if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
2371 pr_err("Couldn't find proper PCI device base address.\n"); 2469 dev_err(&pdev->dev,
2470 "Couldn't find proper PCI device base address.\n");
2372 goto out_disable_dev; 2471 goto out_disable_dev;
2373 } 2472 }
2374 2473
2375 if (pci_request_regions(pdev, spider_net_driver_name)) { 2474 if (pci_request_regions(pdev, spider_net_driver_name)) {
2376 pr_err("Couldn't obtain PCI resources, aborting.\n"); 2475 dev_err(&pdev->dev,
2476 "Couldn't obtain PCI resources, aborting.\n");
2377 goto out_disable_dev; 2477 goto out_disable_dev;
2378 } 2478 }
2379 2479
@@ -2381,8 +2481,8 @@ spider_net_setup_pci_dev(struct pci_dev *pdev)
2381 2481
2382 card = spider_net_alloc_card(); 2482 card = spider_net_alloc_card();
2383 if (!card) { 2483 if (!card) {
2384 pr_err("Couldn't allocate net_device structure, " 2484 dev_err(&pdev->dev,
2385 "aborting.\n"); 2485 "Couldn't allocate net_device structure, aborting.\n");
2386 goto out_release_regions; 2486 goto out_release_regions;
2387 } 2487 }
2388 card->pdev = pdev; 2488 card->pdev = pdev;
@@ -2396,7 +2496,8 @@ spider_net_setup_pci_dev(struct pci_dev *pdev)
2396 card->regs = ioremap(mmio_start, mmio_len); 2496 card->regs = ioremap(mmio_start, mmio_len);
2397 2497
2398 if (!card->regs) { 2498 if (!card->regs) {
2399 pr_err("Couldn't obtain PCI resources, aborting.\n"); 2499 dev_err(&pdev->dev,
2500 "Couldn't obtain PCI resources, aborting.\n");
2400 goto out_release_regions; 2501 goto out_release_regions;
2401 } 2502 }
2402 2503
diff --git a/drivers/net/spider_net.h b/drivers/net/spider_net.h
index 1d054aa71504..dbbdb8cee3c6 100644
--- a/drivers/net/spider_net.h
+++ b/drivers/net/spider_net.h
@@ -349,11 +349,23 @@ enum spider_net_int2_status {
349#define SPIDER_NET_GPRDAT_MASK 0x0000ffff 349#define SPIDER_NET_GPRDAT_MASK 0x0000ffff
350 350
351#define SPIDER_NET_DMAC_NOINTR_COMPLETE 0x00800000 351#define SPIDER_NET_DMAC_NOINTR_COMPLETE 0x00800000
352#define SPIDER_NET_DMAC_NOCS 0x00040000 352#define SPIDER_NET_DMAC_TXFRMTL 0x00040000
353#define SPIDER_NET_DMAC_TCP 0x00020000 353#define SPIDER_NET_DMAC_TCP 0x00020000
354#define SPIDER_NET_DMAC_UDP 0x00030000 354#define SPIDER_NET_DMAC_UDP 0x00030000
355#define SPIDER_NET_TXDCEST 0x08000000 355#define SPIDER_NET_TXDCEST 0x08000000
356 356
357#define SPIDER_NET_DESCR_RXFDIS 0x00000001
358#define SPIDER_NET_DESCR_RXDCEIS 0x00000002
359#define SPIDER_NET_DESCR_RXDEN0IS 0x00000004
360#define SPIDER_NET_DESCR_RXINVDIS 0x00000008
361#define SPIDER_NET_DESCR_RXRERRIS 0x00000010
362#define SPIDER_NET_DESCR_RXFDCIMS 0x00000100
363#define SPIDER_NET_DESCR_RXDCEIMS 0x00000200
364#define SPIDER_NET_DESCR_RXDEN0IMS 0x00000400
365#define SPIDER_NET_DESCR_RXINVDIMS 0x00000800
366#define SPIDER_NET_DESCR_RXRERRMIS 0x00001000
367#define SPIDER_NET_DESCR_UNUSED 0x077fe0e0
368
357#define SPIDER_NET_DESCR_IND_PROC_MASK 0xF0000000 369#define SPIDER_NET_DESCR_IND_PROC_MASK 0xF0000000
358#define SPIDER_NET_DESCR_COMPLETE 0x00000000 /* used in rx and tx */ 370#define SPIDER_NET_DESCR_COMPLETE 0x00000000 /* used in rx and tx */
359#define SPIDER_NET_DESCR_RESPONSE_ERROR 0x10000000 /* used in rx and tx */ 371#define SPIDER_NET_DESCR_RESPONSE_ERROR 0x10000000 /* used in rx and tx */
@@ -364,6 +376,13 @@ enum spider_net_int2_status {
364#define SPIDER_NET_DESCR_NOT_IN_USE 0xF0000000 376#define SPIDER_NET_DESCR_NOT_IN_USE 0xF0000000
365#define SPIDER_NET_DESCR_TXDESFLG 0x00800000 377#define SPIDER_NET_DESCR_TXDESFLG 0x00800000
366 378
379#define SPIDER_NET_DESCR_BAD_STATUS (SPIDER_NET_DESCR_RXDEN0IS | \
380 SPIDER_NET_DESCR_RXRERRIS | \
381 SPIDER_NET_DESCR_RXDEN0IMS | \
382 SPIDER_NET_DESCR_RXINVDIMS | \
383 SPIDER_NET_DESCR_RXRERRMIS | \
384 SPIDER_NET_DESCR_UNUSED)
385
367/* Descriptor, as defined by the hardware */ 386/* Descriptor, as defined by the hardware */
368struct spider_net_hw_descr { 387struct spider_net_hw_descr {
369 u32 buf_addr; 388 u32 buf_addr;
diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c
index 51c3fe2108a3..15146a119230 100644
--- a/drivers/net/sunhme.c
+++ b/drivers/net/sunhme.c
@@ -2625,7 +2625,7 @@ static void quattro_sbus_free_irqs(void)
2625#endif /* CONFIG_SBUS */ 2625#endif /* CONFIG_SBUS */
2626 2626
2627#ifdef CONFIG_PCI 2627#ifdef CONFIG_PCI
2628static struct quattro * __init quattro_pci_find(struct pci_dev *pdev) 2628static struct quattro * __devinit quattro_pci_find(struct pci_dev *pdev)
2629{ 2629{
2630 struct pci_dev *bdev = pdev->bus->self; 2630 struct pci_dev *bdev = pdev->bus->self;
2631 struct quattro *qp; 2631 struct quattro *qp;
diff --git a/drivers/net/tc35815.c b/drivers/net/tc35815.c
index 463d600ed83d..75655add3f34 100644
--- a/drivers/net/tc35815.c
+++ b/drivers/net/tc35815.c
@@ -23,9 +23,9 @@
23 */ 23 */
24 24
25#ifdef TC35815_NAPI 25#ifdef TC35815_NAPI
26#define DRV_VERSION "1.35-NAPI" 26#define DRV_VERSION "1.36-NAPI"
27#else 27#else
28#define DRV_VERSION "1.35" 28#define DRV_VERSION "1.36"
29#endif 29#endif
30static const char *version = "tc35815.c:v" DRV_VERSION "\n"; 30static const char *version = "tc35815.c:v" DRV_VERSION "\n";
31#define MODNAME "tc35815" 31#define MODNAME "tc35815"
@@ -49,6 +49,7 @@ static const char *version = "tc35815.c:v" DRV_VERSION "\n";
49#include <linux/pci.h> 49#include <linux/pci.h>
50#include <linux/mii.h> 50#include <linux/mii.h>
51#include <linux/ethtool.h> 51#include <linux/ethtool.h>
52#include <linux/platform_device.h>
52#include <asm/io.h> 53#include <asm/io.h>
53#include <asm/byteorder.h> 54#include <asm/byteorder.h>
54 55
@@ -597,13 +598,46 @@ static int tc_mdio_read(struct net_device *dev, int phy_id, int location);
597static void tc_mdio_write(struct net_device *dev, int phy_id, int location, 598static void tc_mdio_write(struct net_device *dev, int phy_id, int location,
598 int val); 599 int val);
599 600
600static void __devinit tc35815_init_dev_addr (struct net_device *dev) 601#ifdef CONFIG_CPU_TX49XX
602/*
603 * Find a platform_device providing a MAC address. The platform code
604 * should provide a "tc35815-mac" device with a MAC address in its
605 * platform_data.
606 */
607static int __devinit tc35815_mac_match(struct device *dev, void *data)
608{
609 struct platform_device *plat_dev = to_platform_device(dev);
610 struct pci_dev *pci_dev = data;
611 unsigned int id = (pci_dev->bus->number << 8) | pci_dev->devfn;
612 return !strcmp(plat_dev->name, "tc35815-mac") && plat_dev->id == id;
613}
614
615static int __devinit tc35815_read_plat_dev_addr(struct net_device *dev)
616{
617 struct tc35815_local *lp = dev->priv;
618 struct device *pd = bus_find_device(&platform_bus_type, NULL,
619 lp->pci_dev, tc35815_mac_match);
620 if (pd) {
621 if (pd->platform_data)
622 memcpy(dev->dev_addr, pd->platform_data, ETH_ALEN);
623 put_device(pd);
624 return is_valid_ether_addr(dev->dev_addr) ? 0 : -ENODEV;
625 }
626 return -ENODEV;
627}
628#else
629static int __devinit tc35815_read_plat_dev_addr(struct device *dev)
630{
631 return -ENODEV;
632}
633#endif
634
635static int __devinit tc35815_init_dev_addr (struct net_device *dev)
601{ 636{
602 struct tc35815_regs __iomem *tr = 637 struct tc35815_regs __iomem *tr =
603 (struct tc35815_regs __iomem *)dev->base_addr; 638 (struct tc35815_regs __iomem *)dev->base_addr;
604 int i; 639 int i;
605 640
606 /* dev_addr will be overwritten on NETDEV_REGISTER event */
607 while (tc_readl(&tr->PROM_Ctl) & PROM_Busy) 641 while (tc_readl(&tr->PROM_Ctl) & PROM_Busy)
608 ; 642 ;
609 for (i = 0; i < 6; i += 2) { 643 for (i = 0; i < 6; i += 2) {
@@ -615,6 +649,9 @@ static void __devinit tc35815_init_dev_addr (struct net_device *dev)
615 dev->dev_addr[i] = data & 0xff; 649 dev->dev_addr[i] = data & 0xff;
616 dev->dev_addr[i+1] = data >> 8; 650 dev->dev_addr[i+1] = data >> 8;
617 } 651 }
652 if (!is_valid_ether_addr(dev->dev_addr))
653 return tc35815_read_plat_dev_addr(dev);
654 return 0;
618} 655}
619 656
620static int __devinit tc35815_init_one (struct pci_dev *pdev, 657static int __devinit tc35815_init_one (struct pci_dev *pdev,
@@ -724,7 +761,10 @@ static int __devinit tc35815_init_one (struct pci_dev *pdev,
724 tc35815_chip_reset(dev); 761 tc35815_chip_reset(dev);
725 762
726 /* Retrieve the ethernet address. */ 763 /* Retrieve the ethernet address. */
727 tc35815_init_dev_addr(dev); 764 if (tc35815_init_dev_addr(dev)) {
765 dev_warn(&pdev->dev, "not valid ether addr\n");
766 random_ether_addr(dev->dev_addr);
767 }
728 768
729 rc = register_netdev (dev); 769 rc = register_netdev (dev);
730 if (rc) 770 if (rc)
diff --git a/drivers/net/tokenring/3c359.c b/drivers/net/tokenring/3c359.c
index e22a3f5333ef..9f1b6ab9c228 100644
--- a/drivers/net/tokenring/3c359.c
+++ b/drivers/net/tokenring/3c359.c
@@ -363,7 +363,7 @@ static int __devinit xl_probe(struct pci_dev *pdev,
363} 363}
364 364
365 365
366static int __init xl_init(struct net_device *dev) 366static int __devinit xl_init(struct net_device *dev)
367{ 367{
368 struct xl_private *xl_priv = (struct xl_private *)dev->priv ; 368 struct xl_private *xl_priv = (struct xl_private *)dev->priv ;
369 369
diff --git a/drivers/net/tulip/Kconfig b/drivers/net/tulip/Kconfig
index 8c9634a98c11..1c537d5a3062 100644
--- a/drivers/net/tulip/Kconfig
+++ b/drivers/net/tulip/Kconfig
@@ -2,17 +2,17 @@
2# Tulip family network device configuration 2# Tulip family network device configuration
3# 3#
4 4
5menu "Tulip family network device support" 5menuconfig NET_TULIP
6 depends on NET_ETHERNET && (PCI || EISA || CARDBUS)
7
8config NET_TULIP
9 bool "\"Tulip\" family network device support" 6 bool "\"Tulip\" family network device support"
7 depends on PCI || EISA || CARDBUS
10 help 8 help
11 This selects the "Tulip" family of EISA/PCI network cards. 9 This selects the "Tulip" family of EISA/PCI network cards.
12 10
11if NET_TULIP
12
13config DE2104X 13config DE2104X
14 tristate "Early DECchip Tulip (dc2104x) PCI support (EXPERIMENTAL)" 14 tristate "Early DECchip Tulip (dc2104x) PCI support (EXPERIMENTAL)"
15 depends on NET_TULIP && PCI && EXPERIMENTAL 15 depends on PCI && EXPERIMENTAL
16 select CRC32 16 select CRC32
17 ---help--- 17 ---help---
18 This driver is developed for the SMC EtherPower series Ethernet 18 This driver is developed for the SMC EtherPower series Ethernet
@@ -30,7 +30,7 @@ config DE2104X
30 30
31config TULIP 31config TULIP
32 tristate "DECchip Tulip (dc2114x) PCI support" 32 tristate "DECchip Tulip (dc2114x) PCI support"
33 depends on NET_TULIP && PCI 33 depends on PCI
34 select CRC32 34 select CRC32
35 ---help--- 35 ---help---
36 This driver is developed for the SMC EtherPower series Ethernet 36 This driver is developed for the SMC EtherPower series Ethernet
@@ -95,7 +95,7 @@ config TULIP_NAPI_HW_MITIGATION
95 95
96config DE4X5 96config DE4X5
97 tristate "Generic DECchip & DIGITAL EtherWORKS PCI/EISA" 97 tristate "Generic DECchip & DIGITAL EtherWORKS PCI/EISA"
98 depends on NET_TULIP && (PCI || EISA) 98 depends on PCI || EISA
99 select CRC32 99 select CRC32
100 ---help--- 100 ---help---
101 This is support for the DIGITAL series of PCI/EISA Ethernet cards. 101 This is support for the DIGITAL series of PCI/EISA Ethernet cards.
@@ -112,7 +112,7 @@ config DE4X5
112 112
113config WINBOND_840 113config WINBOND_840
114 tristate "Winbond W89c840 Ethernet support" 114 tristate "Winbond W89c840 Ethernet support"
115 depends on NET_TULIP && PCI 115 depends on PCI
116 select CRC32 116 select CRC32
117 select MII 117 select MII
118 help 118 help
@@ -123,7 +123,7 @@ config WINBOND_840
123 123
124config DM9102 124config DM9102
125 tristate "Davicom DM910x/DM980x support" 125 tristate "Davicom DM910x/DM980x support"
126 depends on NET_TULIP && PCI 126 depends on PCI
127 select CRC32 127 select CRC32
128 ---help--- 128 ---help---
129 This driver is for DM9102(A)/DM9132/DM9801 compatible PCI cards from 129 This driver is for DM9102(A)/DM9132/DM9801 compatible PCI cards from
@@ -137,7 +137,7 @@ config DM9102
137 137
138config ULI526X 138config ULI526X
139 tristate "ULi M526x controller support" 139 tristate "ULi M526x controller support"
140 depends on NET_TULIP && PCI 140 depends on PCI
141 select CRC32 141 select CRC32
142 ---help--- 142 ---help---
143 This driver is for ULi M5261/M5263 10/100M Ethernet Controller 143 This driver is for ULi M5261/M5263 10/100M Ethernet Controller
@@ -149,7 +149,7 @@ config ULI526X
149 149
150config PCMCIA_XIRCOM 150config PCMCIA_XIRCOM
151 tristate "Xircom CardBus support (new driver)" 151 tristate "Xircom CardBus support (new driver)"
152 depends on NET_TULIP && CARDBUS 152 depends on CARDBUS
153 ---help--- 153 ---help---
154 This driver is for the Digital "Tulip" Ethernet CardBus adapters. 154 This driver is for the Digital "Tulip" Ethernet CardBus adapters.
155 It should work with most DEC 21*4*-based chips/ethercards, as well 155 It should work with most DEC 21*4*-based chips/ethercards, as well
@@ -162,7 +162,7 @@ config PCMCIA_XIRCOM
162 162
163config PCMCIA_XIRTULIP 163config PCMCIA_XIRTULIP
164 tristate "Xircom Tulip-like CardBus support (old driver)" 164 tristate "Xircom Tulip-like CardBus support (old driver)"
165 depends on NET_TULIP && CARDBUS && BROKEN_ON_SMP 165 depends on CARDBUS && BROKEN_ON_SMP
166 select CRC32 166 select CRC32
167 ---help--- 167 ---help---
168 This driver is for the Digital "Tulip" Ethernet CardBus adapters. 168 This driver is for the Digital "Tulip" Ethernet CardBus adapters.
@@ -174,5 +174,4 @@ config PCMCIA_XIRTULIP
174 <file:Documentation/networking/net-modules.txt>. The module will 174 <file:Documentation/networking/net-modules.txt>. The module will
175 be called xircom_tulip_cb. If unsure, say N. 175 be called xircom_tulip_cb. If unsure, say N.
176 176
177endmenu 177endif # NET_TULIP
178
diff --git a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c
index 861729806dc1..d380e0b3f05a 100644
--- a/drivers/net/tulip/de2104x.c
+++ b/drivers/net/tulip/de2104x.c
@@ -785,7 +785,6 @@ static void __de_set_rx_mode (struct net_device *dev)
785 785
786 de->tx_head = NEXT_TX(entry); 786 de->tx_head = NEXT_TX(entry);
787 787
788 BUG_ON(TX_BUFFS_AVAIL(de) < 0);
789 if (TX_BUFFS_AVAIL(de) == 0) 788 if (TX_BUFFS_AVAIL(de) == 0)
790 netif_stop_queue(dev); 789 netif_stop_queue(dev);
791 790
diff --git a/drivers/net/tulip/de4x5.c b/drivers/net/tulip/de4x5.c
index 62143f92c231..42fca26afc50 100644
--- a/drivers/net/tulip/de4x5.c
+++ b/drivers/net/tulip/de4x5.c
@@ -597,7 +597,7 @@ static char *args;
597#endif 597#endif
598 598
599struct parameters { 599struct parameters {
600 int fdx; 600 bool fdx;
601 int autosense; 601 int autosense;
602}; 602};
603 603
@@ -809,10 +809,10 @@ struct de4x5_private {
809 s32 irq_en; /* Summary interrupt bits */ 809 s32 irq_en; /* Summary interrupt bits */
810 int media; /* Media (eg TP), mode (eg 100B)*/ 810 int media; /* Media (eg TP), mode (eg 100B)*/
811 int c_media; /* Remember the last media conn */ 811 int c_media; /* Remember the last media conn */
812 int fdx; /* media full duplex flag */ 812 bool fdx; /* media full duplex flag */
813 int linkOK; /* Link is OK */ 813 int linkOK; /* Link is OK */
814 int autosense; /* Allow/disallow autosensing */ 814 int autosense; /* Allow/disallow autosensing */
815 int tx_enable; /* Enable descriptor polling */ 815 bool tx_enable; /* Enable descriptor polling */
816 int setup_f; /* Setup frame filtering type */ 816 int setup_f; /* Setup frame filtering type */
817 int local_state; /* State within a 'media' state */ 817 int local_state; /* State within a 'media' state */
818 struct mii_phy phy[DE4X5_MAX_PHY]; /* List of attached PHY devices */ 818 struct mii_phy phy[DE4X5_MAX_PHY]; /* List of attached PHY devices */
@@ -838,8 +838,8 @@ struct de4x5_private {
838 struct de4x5_srom srom; /* A copy of the SROM */ 838 struct de4x5_srom srom; /* A copy of the SROM */
839 int cfrv; /* Card CFRV copy */ 839 int cfrv; /* Card CFRV copy */
840 int rx_ovf; /* Check for 'RX overflow' tag */ 840 int rx_ovf; /* Check for 'RX overflow' tag */
841 int useSROM; /* For non-DEC card use SROM */ 841 bool useSROM; /* For non-DEC card use SROM */
842 int useMII; /* Infoblock using the MII */ 842 bool useMII; /* Infoblock using the MII */
843 int asBitValid; /* Autosense bits in GEP? */ 843 int asBitValid; /* Autosense bits in GEP? */
844 int asPolarity; /* 0 => asserted high */ 844 int asPolarity; /* 0 => asserted high */
845 int asBit; /* Autosense bit number in GEP */ 845 int asBit; /* Autosense bit number in GEP */
@@ -928,7 +928,7 @@ static int dc21040_state(struct net_device *dev, int csr13, int csr14, int c
928static int test_media(struct net_device *dev, s32 irqs, s32 irq_mask, s32 csr13, s32 csr14, s32 csr15, s32 msec); 928static int test_media(struct net_device *dev, s32 irqs, s32 irq_mask, s32 csr13, s32 csr14, s32 csr15, s32 msec);
929static int test_for_100Mb(struct net_device *dev, int msec); 929static int test_for_100Mb(struct net_device *dev, int msec);
930static int wait_for_link(struct net_device *dev); 930static int wait_for_link(struct net_device *dev);
931static int test_mii_reg(struct net_device *dev, int reg, int mask, int pol, long msec); 931static int test_mii_reg(struct net_device *dev, int reg, int mask, bool pol, long msec);
932static int is_spd_100(struct net_device *dev); 932static int is_spd_100(struct net_device *dev);
933static int is_100_up(struct net_device *dev); 933static int is_100_up(struct net_device *dev);
934static int is_10_up(struct net_device *dev); 934static int is_10_up(struct net_device *dev);
@@ -1109,7 +1109,7 @@ de4x5_hw_init(struct net_device *dev, u_long iobase, struct device *gendev)
1109 /* 1109 /*
1110 ** Now find out what kind of DC21040/DC21041/DC21140 board we have. 1110 ** Now find out what kind of DC21040/DC21041/DC21140 board we have.
1111 */ 1111 */
1112 lp->useSROM = FALSE; 1112 lp->useSROM = false;
1113 if (lp->bus == PCI) { 1113 if (lp->bus == PCI) {
1114 PCI_signature(name, lp); 1114 PCI_signature(name, lp);
1115 } else { 1115 } else {
@@ -1137,7 +1137,7 @@ de4x5_hw_init(struct net_device *dev, u_long iobase, struct device *gendev)
1137 lp->cache.gepc = GEP_INIT; 1137 lp->cache.gepc = GEP_INIT;
1138 lp->asBit = GEP_SLNK; 1138 lp->asBit = GEP_SLNK;
1139 lp->asPolarity = GEP_SLNK; 1139 lp->asPolarity = GEP_SLNK;
1140 lp->asBitValid = TRUE; 1140 lp->asBitValid = ~0;
1141 lp->timeout = -1; 1141 lp->timeout = -1;
1142 lp->gendev = gendev; 1142 lp->gendev = gendev;
1143 spin_lock_init(&lp->lock); 1143 spin_lock_init(&lp->lock);
@@ -1463,7 +1463,7 @@ de4x5_queue_pkt(struct sk_buff *skb, struct net_device *dev)
1463 u_long flags = 0; 1463 u_long flags = 0;
1464 1464
1465 netif_stop_queue(dev); 1465 netif_stop_queue(dev);
1466 if (lp->tx_enable == NO) { /* Cannot send for now */ 1466 if (!lp->tx_enable) { /* Cannot send for now */
1467 return -1; 1467 return -1;
1468 } 1468 }
1469 1469
@@ -2424,7 +2424,7 @@ dc21040_autoconf(struct net_device *dev)
2424 switch (lp->media) { 2424 switch (lp->media) {
2425 case INIT: 2425 case INIT:
2426 DISABLE_IRQs; 2426 DISABLE_IRQs;
2427 lp->tx_enable = NO; 2427 lp->tx_enable = false;
2428 lp->timeout = -1; 2428 lp->timeout = -1;
2429 de4x5_save_skbs(dev); 2429 de4x5_save_skbs(dev);
2430 if ((lp->autosense == AUTO) || (lp->autosense == TP)) { 2430 if ((lp->autosense == AUTO) || (lp->autosense == TP)) {
@@ -2477,7 +2477,7 @@ dc21040_autoconf(struct net_device *dev)
2477 lp->c_media = lp->media; 2477 lp->c_media = lp->media;
2478 } 2478 }
2479 lp->media = INIT; 2479 lp->media = INIT;
2480 lp->tx_enable = NO; 2480 lp->tx_enable = false;
2481 break; 2481 break;
2482 } 2482 }
2483 2483
@@ -2578,7 +2578,7 @@ dc21041_autoconf(struct net_device *dev)
2578 switch (lp->media) { 2578 switch (lp->media) {
2579 case INIT: 2579 case INIT:
2580 DISABLE_IRQs; 2580 DISABLE_IRQs;
2581 lp->tx_enable = NO; 2581 lp->tx_enable = false;
2582 lp->timeout = -1; 2582 lp->timeout = -1;
2583 de4x5_save_skbs(dev); /* Save non transmitted skb's */ 2583 de4x5_save_skbs(dev); /* Save non transmitted skb's */
2584 if ((lp->autosense == AUTO) || (lp->autosense == TP_NW)) { 2584 if ((lp->autosense == AUTO) || (lp->autosense == TP_NW)) {
@@ -2757,7 +2757,7 @@ dc21041_autoconf(struct net_device *dev)
2757 lp->c_media = lp->media; 2757 lp->c_media = lp->media;
2758 } 2758 }
2759 lp->media = INIT; 2759 lp->media = INIT;
2760 lp->tx_enable = NO; 2760 lp->tx_enable = false;
2761 break; 2761 break;
2762 } 2762 }
2763 2763
@@ -2781,7 +2781,7 @@ dc21140m_autoconf(struct net_device *dev)
2781 case INIT: 2781 case INIT:
2782 if (lp->timeout < 0) { 2782 if (lp->timeout < 0) {
2783 DISABLE_IRQs; 2783 DISABLE_IRQs;
2784 lp->tx_enable = FALSE; 2784 lp->tx_enable = false;
2785 lp->linkOK = 0; 2785 lp->linkOK = 0;
2786 de4x5_save_skbs(dev); /* Save non transmitted skb's */ 2786 de4x5_save_skbs(dev); /* Save non transmitted skb's */
2787 } 2787 }
@@ -2830,7 +2830,7 @@ dc21140m_autoconf(struct net_device *dev)
2830 if (lp->timeout < 0) { 2830 if (lp->timeout < 0) {
2831 mii_wr(MII_CR_ASSE | MII_CR_RAN, MII_CR, lp->phy[lp->active].addr, DE4X5_MII); 2831 mii_wr(MII_CR_ASSE | MII_CR_RAN, MII_CR, lp->phy[lp->active].addr, DE4X5_MII);
2832 } 2832 }
2833 cr = test_mii_reg(dev, MII_CR, MII_CR_RAN, FALSE, 500); 2833 cr = test_mii_reg(dev, MII_CR, MII_CR_RAN, false, 500);
2834 if (cr < 0) { 2834 if (cr < 0) {
2835 next_tick = cr & ~TIMER_CB; 2835 next_tick = cr & ~TIMER_CB;
2836 } else { 2836 } else {
@@ -2845,7 +2845,7 @@ dc21140m_autoconf(struct net_device *dev)
2845 break; 2845 break;
2846 2846
2847 case 1: 2847 case 1:
2848 if ((sr=test_mii_reg(dev, MII_SR, MII_SR_ASSC, TRUE, 2000)) < 0) { 2848 if ((sr=test_mii_reg(dev, MII_SR, MII_SR_ASSC, true, 2000)) < 0) {
2849 next_tick = sr & ~TIMER_CB; 2849 next_tick = sr & ~TIMER_CB;
2850 } else { 2850 } else {
2851 lp->media = SPD_DET; 2851 lp->media = SPD_DET;
@@ -2857,10 +2857,10 @@ dc21140m_autoconf(struct net_device *dev)
2857 if (!(anlpa & MII_ANLPA_RF) && 2857 if (!(anlpa & MII_ANLPA_RF) &&
2858 (cap = anlpa & MII_ANLPA_TAF & ana)) { 2858 (cap = anlpa & MII_ANLPA_TAF & ana)) {
2859 if (cap & MII_ANA_100M) { 2859 if (cap & MII_ANA_100M) {
2860 lp->fdx = ((ana & anlpa & MII_ANA_FDAM & MII_ANA_100M) ? TRUE : FALSE); 2860 lp->fdx = (ana & anlpa & MII_ANA_FDAM & MII_ANA_100M) != 0;
2861 lp->media = _100Mb; 2861 lp->media = _100Mb;
2862 } else if (cap & MII_ANA_10M) { 2862 } else if (cap & MII_ANA_10M) {
2863 lp->fdx = ((ana & anlpa & MII_ANA_FDAM & MII_ANA_10M) ? TRUE : FALSE); 2863 lp->fdx = (ana & anlpa & MII_ANA_FDAM & MII_ANA_10M) != 0;
2864 2864
2865 lp->media = _10Mb; 2865 lp->media = _10Mb;
2866 } 2866 }
@@ -2932,7 +2932,7 @@ dc21140m_autoconf(struct net_device *dev)
2932 lp->c_media = lp->media; 2932 lp->c_media = lp->media;
2933 } 2933 }
2934 lp->media = INIT; 2934 lp->media = INIT;
2935 lp->tx_enable = FALSE; 2935 lp->tx_enable = false;
2936 break; 2936 break;
2937 } 2937 }
2938 2938
@@ -2965,7 +2965,7 @@ dc2114x_autoconf(struct net_device *dev)
2965 case INIT: 2965 case INIT:
2966 if (lp->timeout < 0) { 2966 if (lp->timeout < 0) {
2967 DISABLE_IRQs; 2967 DISABLE_IRQs;
2968 lp->tx_enable = FALSE; 2968 lp->tx_enable = false;
2969 lp->linkOK = 0; 2969 lp->linkOK = 0;
2970 lp->timeout = -1; 2970 lp->timeout = -1;
2971 de4x5_save_skbs(dev); /* Save non transmitted skb's */ 2971 de4x5_save_skbs(dev); /* Save non transmitted skb's */
@@ -3013,7 +3013,7 @@ dc2114x_autoconf(struct net_device *dev)
3013 if (lp->timeout < 0) { 3013 if (lp->timeout < 0) {
3014 mii_wr(MII_CR_ASSE | MII_CR_RAN, MII_CR, lp->phy[lp->active].addr, DE4X5_MII); 3014 mii_wr(MII_CR_ASSE | MII_CR_RAN, MII_CR, lp->phy[lp->active].addr, DE4X5_MII);
3015 } 3015 }
3016 cr = test_mii_reg(dev, MII_CR, MII_CR_RAN, FALSE, 500); 3016 cr = test_mii_reg(dev, MII_CR, MII_CR_RAN, false, 500);
3017 if (cr < 0) { 3017 if (cr < 0) {
3018 next_tick = cr & ~TIMER_CB; 3018 next_tick = cr & ~TIMER_CB;
3019 } else { 3019 } else {
@@ -3028,7 +3028,8 @@ dc2114x_autoconf(struct net_device *dev)
3028 break; 3028 break;
3029 3029
3030 case 1: 3030 case 1:
3031 if ((sr=test_mii_reg(dev, MII_SR, MII_SR_ASSC, TRUE, 2000)) < 0) { 3031 sr = test_mii_reg(dev, MII_SR, MII_SR_ASSC, true, 2000);
3032 if (sr < 0) {
3032 next_tick = sr & ~TIMER_CB; 3033 next_tick = sr & ~TIMER_CB;
3033 } else { 3034 } else {
3034 lp->media = SPD_DET; 3035 lp->media = SPD_DET;
@@ -3040,10 +3041,10 @@ dc2114x_autoconf(struct net_device *dev)
3040 if (!(anlpa & MII_ANLPA_RF) && 3041 if (!(anlpa & MII_ANLPA_RF) &&
3041 (cap = anlpa & MII_ANLPA_TAF & ana)) { 3042 (cap = anlpa & MII_ANLPA_TAF & ana)) {
3042 if (cap & MII_ANA_100M) { 3043 if (cap & MII_ANA_100M) {
3043 lp->fdx = ((ana & anlpa & MII_ANA_FDAM & MII_ANA_100M) ? TRUE : FALSE); 3044 lp->fdx = (ana & anlpa & MII_ANA_FDAM & MII_ANA_100M) != 0;
3044 lp->media = _100Mb; 3045 lp->media = _100Mb;
3045 } else if (cap & MII_ANA_10M) { 3046 } else if (cap & MII_ANA_10M) {
3046 lp->fdx = ((ana & anlpa & MII_ANA_FDAM & MII_ANA_10M) ? TRUE : FALSE); 3047 lp->fdx = (ana & anlpa & MII_ANA_FDAM & MII_ANA_10M) != 0;
3047 lp->media = _10Mb; 3048 lp->media = _10Mb;
3048 } 3049 }
3049 } 3050 }
@@ -3222,14 +3223,14 @@ srom_map_media(struct net_device *dev)
3222{ 3223{
3223 struct de4x5_private *lp = netdev_priv(dev); 3224 struct de4x5_private *lp = netdev_priv(dev);
3224 3225
3225 lp->fdx = 0; 3226 lp->fdx = false;
3226 if (lp->infoblock_media == lp->media) 3227 if (lp->infoblock_media == lp->media)
3227 return 0; 3228 return 0;
3228 3229
3229 switch(lp->infoblock_media) { 3230 switch(lp->infoblock_media) {
3230 case SROM_10BASETF: 3231 case SROM_10BASETF:
3231 if (!lp->params.fdx) return -1; 3232 if (!lp->params.fdx) return -1;
3232 lp->fdx = TRUE; 3233 lp->fdx = true;
3233 case SROM_10BASET: 3234 case SROM_10BASET:
3234 if (lp->params.fdx && !lp->fdx) return -1; 3235 if (lp->params.fdx && !lp->fdx) return -1;
3235 if ((lp->chipset == DC21140) || ((lp->chipset & ~0x00ff) == DC2114x)) { 3236 if ((lp->chipset == DC21140) || ((lp->chipset & ~0x00ff) == DC2114x)) {
@@ -3249,7 +3250,7 @@ srom_map_media(struct net_device *dev)
3249 3250
3250 case SROM_100BASETF: 3251 case SROM_100BASETF:
3251 if (!lp->params.fdx) return -1; 3252 if (!lp->params.fdx) return -1;
3252 lp->fdx = TRUE; 3253 lp->fdx = true;
3253 case SROM_100BASET: 3254 case SROM_100BASET:
3254 if (lp->params.fdx && !lp->fdx) return -1; 3255 if (lp->params.fdx && !lp->fdx) return -1;
3255 lp->media = _100Mb; 3256 lp->media = _100Mb;
@@ -3261,7 +3262,7 @@ srom_map_media(struct net_device *dev)
3261 3262
3262 case SROM_100BASEFF: 3263 case SROM_100BASEFF:
3263 if (!lp->params.fdx) return -1; 3264 if (!lp->params.fdx) return -1;
3264 lp->fdx = TRUE; 3265 lp->fdx = true;
3265 case SROM_100BASEF: 3266 case SROM_100BASEF:
3266 if (lp->params.fdx && !lp->fdx) return -1; 3267 if (lp->params.fdx && !lp->fdx) return -1;
3267 lp->media = _100Mb; 3268 lp->media = _100Mb;
@@ -3297,7 +3298,7 @@ de4x5_init_connection(struct net_device *dev)
3297 spin_lock_irqsave(&lp->lock, flags); 3298 spin_lock_irqsave(&lp->lock, flags);
3298 de4x5_rst_desc_ring(dev); 3299 de4x5_rst_desc_ring(dev);
3299 de4x5_setup_intr(dev); 3300 de4x5_setup_intr(dev);
3300 lp->tx_enable = YES; 3301 lp->tx_enable = true;
3301 spin_unlock_irqrestore(&lp->lock, flags); 3302 spin_unlock_irqrestore(&lp->lock, flags);
3302 outl(POLL_DEMAND, DE4X5_TPD); 3303 outl(POLL_DEMAND, DE4X5_TPD);
3303 3304
@@ -3336,7 +3337,7 @@ de4x5_reset_phy(struct net_device *dev)
3336 } 3337 }
3337 } 3338 }
3338 if (lp->useMII) { 3339 if (lp->useMII) {
3339 next_tick = test_mii_reg(dev, MII_CR, MII_CR_RST, FALSE, 500); 3340 next_tick = test_mii_reg(dev, MII_CR, MII_CR_RST, false, 500);
3340 } 3341 }
3341 } else if (lp->chipset == DC21140) { 3342 } else if (lp->chipset == DC21140) {
3342 PHY_HARD_RESET; 3343 PHY_HARD_RESET;
@@ -3466,7 +3467,7 @@ wait_for_link(struct net_device *dev)
3466** 3467**
3467*/ 3468*/
3468static int 3469static int
3469test_mii_reg(struct net_device *dev, int reg, int mask, int pol, long msec) 3470test_mii_reg(struct net_device *dev, int reg, int mask, bool pol, long msec)
3470{ 3471{
3471 struct de4x5_private *lp = netdev_priv(dev); 3472 struct de4x5_private *lp = netdev_priv(dev);
3472 int test; 3473 int test;
@@ -3476,9 +3477,8 @@ test_mii_reg(struct net_device *dev, int reg, int mask, int pol, long msec)
3476 lp->timeout = msec/100; 3477 lp->timeout = msec/100;
3477 } 3478 }
3478 3479
3479 if (pol) pol = ~0;
3480 reg = mii_rd((u_char)reg, lp->phy[lp->active].addr, DE4X5_MII) & mask; 3480 reg = mii_rd((u_char)reg, lp->phy[lp->active].addr, DE4X5_MII) & mask;
3481 test = (reg ^ pol) & mask; 3481 test = (reg ^ (pol ? ~0 : 0)) & mask;
3482 3482
3483 if (test && --lp->timeout) { 3483 if (test && --lp->timeout) {
3484 reg = 100 | TIMER_CB; 3484 reg = 100 | TIMER_CB;
@@ -3992,10 +3992,10 @@ PCI_signature(char *name, struct de4x5_private *lp)
3992 ))))))); 3992 )))))));
3993 } 3993 }
3994 if (lp->chipset != DC21041) { 3994 if (lp->chipset != DC21041) {
3995 lp->useSROM = TRUE; /* card is not recognisably DEC */ 3995 lp->useSROM = true; /* card is not recognisably DEC */
3996 } 3996 }
3997 } else if ((lp->chipset & ~0x00ff) == DC2114x) { 3997 } else if ((lp->chipset & ~0x00ff) == DC2114x) {
3998 lp->useSROM = TRUE; 3998 lp->useSROM = true;
3999 } 3999 }
4000 4000
4001 return status; 4001 return status;
@@ -4216,7 +4216,7 @@ srom_repair(struct net_device *dev, int card)
4216 memset((char *)&lp->srom, 0, sizeof(struct de4x5_srom)); 4216 memset((char *)&lp->srom, 0, sizeof(struct de4x5_srom));
4217 memcpy(lp->srom.ieee_addr, (char *)dev->dev_addr, ETH_ALEN); 4217 memcpy(lp->srom.ieee_addr, (char *)dev->dev_addr, ETH_ALEN);
4218 memcpy(lp->srom.info, (char *)&srom_repair_info[SMC-1], 100); 4218 memcpy(lp->srom.info, (char *)&srom_repair_info[SMC-1], 100);
4219 lp->useSROM = TRUE; 4219 lp->useSROM = true;
4220 break; 4220 break;
4221 } 4221 }
4222 4222
@@ -4392,7 +4392,7 @@ srom_infoleaf_info(struct net_device *dev)
4392 if (lp->chipset == infoleaf_array[i].chipset) break; 4392 if (lp->chipset == infoleaf_array[i].chipset) break;
4393 } 4393 }
4394 if (i == INFOLEAF_SIZE) { 4394 if (i == INFOLEAF_SIZE) {
4395 lp->useSROM = FALSE; 4395 lp->useSROM = false;
4396 printk("%s: Cannot find correct chipset for SROM decoding!\n", 4396 printk("%s: Cannot find correct chipset for SROM decoding!\n",
4397 dev->name); 4397 dev->name);
4398 return -ENXIO; 4398 return -ENXIO;
@@ -4409,7 +4409,7 @@ srom_infoleaf_info(struct net_device *dev)
4409 if (lp->device == *p) break; 4409 if (lp->device == *p) break;
4410 } 4410 }
4411 if (i == 0) { 4411 if (i == 0) {
4412 lp->useSROM = FALSE; 4412 lp->useSROM = false;
4413 printk("%s: Cannot find correct PCI device [%d] for SROM decoding!\n", 4413 printk("%s: Cannot find correct PCI device [%d] for SROM decoding!\n",
4414 dev->name, lp->device); 4414 dev->name, lp->device);
4415 return -ENXIO; 4415 return -ENXIO;
@@ -4542,7 +4542,7 @@ dc21140_infoleaf(struct net_device *dev)
4542 } 4542 }
4543 lp->media = INIT; 4543 lp->media = INIT;
4544 lp->tcount = 0; 4544 lp->tcount = 0;
4545 lp->tx_enable = FALSE; 4545 lp->tx_enable = false;
4546 } 4546 }
4547 4547
4548 return next_tick & ~TIMER_CB; 4548 return next_tick & ~TIMER_CB;
@@ -4577,7 +4577,7 @@ dc21142_infoleaf(struct net_device *dev)
4577 } 4577 }
4578 lp->media = INIT; 4578 lp->media = INIT;
4579 lp->tcount = 0; 4579 lp->tcount = 0;
4580 lp->tx_enable = FALSE; 4580 lp->tx_enable = false;
4581 } 4581 }
4582 4582
4583 return next_tick & ~TIMER_CB; 4583 return next_tick & ~TIMER_CB;
@@ -4611,7 +4611,7 @@ dc21143_infoleaf(struct net_device *dev)
4611 } 4611 }
4612 lp->media = INIT; 4612 lp->media = INIT;
4613 lp->tcount = 0; 4613 lp->tcount = 0;
4614 lp->tx_enable = FALSE; 4614 lp->tx_enable = false;
4615 } 4615 }
4616 4616
4617 return next_tick & ~TIMER_CB; 4617 return next_tick & ~TIMER_CB;
@@ -4650,7 +4650,7 @@ compact_infoblock(struct net_device *dev, u_char count, u_char *p)
4650 lp->asBit = 1 << ((csr6 >> 1) & 0x07); 4650 lp->asBit = 1 << ((csr6 >> 1) & 0x07);
4651 lp->asPolarity = ((csr6 & 0x80) ? -1 : 0) & lp->asBit; 4651 lp->asPolarity = ((csr6 & 0x80) ? -1 : 0) & lp->asBit;
4652 lp->infoblock_csr6 = OMR_DEF | ((csr6 & 0x71) << 18); 4652 lp->infoblock_csr6 = OMR_DEF | ((csr6 & 0x71) << 18);
4653 lp->useMII = FALSE; 4653 lp->useMII = false;
4654 4654
4655 de4x5_switch_mac_port(dev); 4655 de4x5_switch_mac_port(dev);
4656 } 4656 }
@@ -4691,7 +4691,7 @@ type0_infoblock(struct net_device *dev, u_char count, u_char *p)
4691 lp->asBit = 1 << ((csr6 >> 1) & 0x07); 4691 lp->asBit = 1 << ((csr6 >> 1) & 0x07);
4692 lp->asPolarity = ((csr6 & 0x80) ? -1 : 0) & lp->asBit; 4692 lp->asPolarity = ((csr6 & 0x80) ? -1 : 0) & lp->asBit;
4693 lp->infoblock_csr6 = OMR_DEF | ((csr6 & 0x71) << 18); 4693 lp->infoblock_csr6 = OMR_DEF | ((csr6 & 0x71) << 18);
4694 lp->useMII = FALSE; 4694 lp->useMII = false;
4695 4695
4696 de4x5_switch_mac_port(dev); 4696 de4x5_switch_mac_port(dev);
4697 } 4697 }
@@ -4731,7 +4731,7 @@ type1_infoblock(struct net_device *dev, u_char count, u_char *p)
4731 lp->ibn = 1; 4731 lp->ibn = 1;
4732 lp->active = *p; 4732 lp->active = *p;
4733 lp->infoblock_csr6 = OMR_MII_100; 4733 lp->infoblock_csr6 = OMR_MII_100;
4734 lp->useMII = TRUE; 4734 lp->useMII = true;
4735 lp->infoblock_media = ANS; 4735 lp->infoblock_media = ANS;
4736 4736
4737 de4x5_switch_mac_port(dev); 4737 de4x5_switch_mac_port(dev);
@@ -4773,7 +4773,7 @@ type2_infoblock(struct net_device *dev, u_char count, u_char *p)
4773 lp->cache.gepc = ((s32)(TWIDDLE(p)) << 16); p += 2; 4773 lp->cache.gepc = ((s32)(TWIDDLE(p)) << 16); p += 2;
4774 lp->cache.gep = ((s32)(TWIDDLE(p)) << 16); 4774 lp->cache.gep = ((s32)(TWIDDLE(p)) << 16);
4775 lp->infoblock_csr6 = OMR_SIA; 4775 lp->infoblock_csr6 = OMR_SIA;
4776 lp->useMII = FALSE; 4776 lp->useMII = false;
4777 4777
4778 de4x5_switch_mac_port(dev); 4778 de4x5_switch_mac_port(dev);
4779 } 4779 }
@@ -4814,7 +4814,7 @@ type3_infoblock(struct net_device *dev, u_char count, u_char *p)
4814 lp->active = *p; 4814 lp->active = *p;
4815 if (MOTO_SROM_BUG) lp->active = 0; 4815 if (MOTO_SROM_BUG) lp->active = 0;
4816 lp->infoblock_csr6 = OMR_MII_100; 4816 lp->infoblock_csr6 = OMR_MII_100;
4817 lp->useMII = TRUE; 4817 lp->useMII = true;
4818 lp->infoblock_media = ANS; 4818 lp->infoblock_media = ANS;
4819 4819
4820 de4x5_switch_mac_port(dev); 4820 de4x5_switch_mac_port(dev);
@@ -4856,7 +4856,7 @@ type4_infoblock(struct net_device *dev, u_char count, u_char *p)
4856 lp->asBit = 1 << ((csr6 >> 1) & 0x07); 4856 lp->asBit = 1 << ((csr6 >> 1) & 0x07);
4857 lp->asPolarity = ((csr6 & 0x80) ? -1 : 0) & lp->asBit; 4857 lp->asPolarity = ((csr6 & 0x80) ? -1 : 0) & lp->asBit;
4858 lp->infoblock_csr6 = OMR_DEF | ((csr6 & 0x71) << 18); 4858 lp->infoblock_csr6 = OMR_DEF | ((csr6 & 0x71) << 18);
4859 lp->useMII = FALSE; 4859 lp->useMII = false;
4860 4860
4861 de4x5_switch_mac_port(dev); 4861 de4x5_switch_mac_port(dev);
4862 } 4862 }
@@ -5077,7 +5077,7 @@ mii_get_phy(struct net_device *dev)
5077 int id; 5077 int id;
5078 5078
5079 lp->active = 0; 5079 lp->active = 0;
5080 lp->useMII = TRUE; 5080 lp->useMII = true;
5081 5081
5082 /* Search the MII address space for possible PHY devices */ 5082 /* Search the MII address space for possible PHY devices */
5083 for (n=0, lp->mii_cnt=0, i=1; !((i==1) && (n==1)); i=(i+1)%DE4X5_MAX_MII) { 5083 for (n=0, lp->mii_cnt=0, i=1; !((i==1) && (n==1)); i=(i+1)%DE4X5_MAX_MII) {
@@ -5127,7 +5127,7 @@ mii_get_phy(struct net_device *dev)
5127 de4x5_dbg_mii(dev, k); 5127 de4x5_dbg_mii(dev, k);
5128 } 5128 }
5129 } 5129 }
5130 if (!lp->mii_cnt) lp->useMII = FALSE; 5130 if (!lp->mii_cnt) lp->useMII = false;
5131 5131
5132 return lp->mii_cnt; 5132 return lp->mii_cnt;
5133} 5133}
diff --git a/drivers/net/tulip/de4x5.h b/drivers/net/tulip/de4x5.h
index 57226e5eb8a6..12af0cc037fb 100644
--- a/drivers/net/tulip/de4x5.h
+++ b/drivers/net/tulip/de4x5.h
@@ -893,15 +893,6 @@
893#define PHYS_ADDR_ONLY 1 /* Update the physical address only */ 893#define PHYS_ADDR_ONLY 1 /* Update the physical address only */
894 894
895/* 895/*
896** Booleans
897*/
898#define NO 0
899#define FALSE 0
900
901#define YES ~0
902#define TRUE ~0
903
904/*
905** Adapter state 896** Adapter state
906*/ 897*/
907#define INITIALISED 0 /* After h/w initialised and mem alloc'd */ 898#define INITIALISED 0 /* After h/w initialised and mem alloc'd */
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c
index 18b731bb4da1..e4736a3b1b7a 100644
--- a/drivers/net/ucc_geth.c
+++ b/drivers/net/ucc_geth.c
@@ -2276,7 +2276,7 @@ static void ucc_geth_stop(struct ucc_geth_private *ugeth)
2276 phy_stop(phydev); 2276 phy_stop(phydev);
2277 2277
2278 /* Mask all interrupts */ 2278 /* Mask all interrupts */
2279 out_be32(ugeth->uccf->p_ucce, 0x00000000); 2279 out_be32(ugeth->uccf->p_uccm, 0x00000000);
2280 2280
2281 /* Clear all interrupts */ 2281 /* Clear all interrupts */
2282 out_be32(ugeth->uccf->p_ucce, 0xffffffff); 2282 out_be32(ugeth->uccf->p_ucce, 0xffffffff);
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index a12f576391cf..37bf4f2c0a44 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -192,7 +192,7 @@ static int init_status (struct usbnet *dev, struct usb_interface *intf)
192 usb_pipeendpoint(pipe), maxp, period); 192 usb_pipeendpoint(pipe), maxp, period);
193 } 193 }
194 } 194 }
195 return 0; 195 return 0;
196} 196}
197 197
198/* Passes this packet up the stack, updating its accounting. 198/* Passes this packet up the stack, updating its accounting.
@@ -326,7 +326,7 @@ static void rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags)
326 if (netif_running (dev->net) 326 if (netif_running (dev->net)
327 && netif_device_present (dev->net) 327 && netif_device_present (dev->net)
328 && !test_bit (EVENT_RX_HALT, &dev->flags)) { 328 && !test_bit (EVENT_RX_HALT, &dev->flags)) {
329 switch (retval = usb_submit_urb (urb, GFP_ATOMIC)){ 329 switch (retval = usb_submit_urb (urb, GFP_ATOMIC)) {
330 case -EPIPE: 330 case -EPIPE:
331 usbnet_defer_kevent (dev, EVENT_RX_HALT); 331 usbnet_defer_kevent (dev, EVENT_RX_HALT);
332 break; 332 break;
@@ -393,8 +393,8 @@ static void rx_complete (struct urb *urb)
393 entry->urb = NULL; 393 entry->urb = NULL;
394 394
395 switch (urb_status) { 395 switch (urb_status) {
396 // success 396 /* success */
397 case 0: 397 case 0:
398 if (skb->len < dev->net->hard_header_len) { 398 if (skb->len < dev->net->hard_header_len) {
399 entry->state = rx_cleanup; 399 entry->state = rx_cleanup;
400 dev->stats.rx_errors++; 400 dev->stats.rx_errors++;
@@ -404,28 +404,30 @@ static void rx_complete (struct urb *urb)
404 } 404 }
405 break; 405 break;
406 406
407 // stalls need manual reset. this is rare ... except that 407 /* stalls need manual reset. this is rare ... except that
408 // when going through USB 2.0 TTs, unplug appears this way. 408 * when going through USB 2.0 TTs, unplug appears this way.
409 // we avoid the highspeed version of the ETIMEOUT/EILSEQ 409 * we avoid the highspeed version of the ETIMEOUT/EILSEQ
410 // storm, recovering as needed. 410 * storm, recovering as needed.
411 case -EPIPE: 411 */
412 case -EPIPE:
412 dev->stats.rx_errors++; 413 dev->stats.rx_errors++;
413 usbnet_defer_kevent (dev, EVENT_RX_HALT); 414 usbnet_defer_kevent (dev, EVENT_RX_HALT);
414 // FALLTHROUGH 415 // FALLTHROUGH
415 416
416 // software-driven interface shutdown 417 /* software-driven interface shutdown */
417 case -ECONNRESET: // async unlink 418 case -ECONNRESET: /* async unlink */
418 case -ESHUTDOWN: // hardware gone 419 case -ESHUTDOWN: /* hardware gone */
419 if (netif_msg_ifdown (dev)) 420 if (netif_msg_ifdown (dev))
420 devdbg (dev, "rx shutdown, code %d", urb_status); 421 devdbg (dev, "rx shutdown, code %d", urb_status);
421 goto block; 422 goto block;
422 423
423 // we get controller i/o faults during khubd disconnect() delays. 424 /* we get controller i/o faults during khubd disconnect() delays.
424 // throttle down resubmits, to avoid log floods; just temporarily, 425 * throttle down resubmits, to avoid log floods; just temporarily,
425 // so we still recover when the fault isn't a khubd delay. 426 * so we still recover when the fault isn't a khubd delay.
426 case -EPROTO: 427 */
427 case -ETIME: 428 case -EPROTO:
428 case -EILSEQ: 429 case -ETIME:
430 case -EILSEQ:
429 dev->stats.rx_errors++; 431 dev->stats.rx_errors++;
430 if (!timer_pending (&dev->delay)) { 432 if (!timer_pending (&dev->delay)) {
431 mod_timer (&dev->delay, jiffies + THROTTLE_JIFFIES); 433 mod_timer (&dev->delay, jiffies + THROTTLE_JIFFIES);
@@ -438,12 +440,12 @@ block:
438 urb = NULL; 440 urb = NULL;
439 break; 441 break;
440 442
441 // data overrun ... flush fifo? 443 /* data overrun ... flush fifo? */
442 case -EOVERFLOW: 444 case -EOVERFLOW:
443 dev->stats.rx_over_errors++; 445 dev->stats.rx_over_errors++;
444 // FALLTHROUGH 446 // FALLTHROUGH
445 447
446 default: 448 default:
447 entry->state = rx_cleanup; 449 entry->state = rx_cleanup;
448 dev->stats.rx_errors++; 450 dev->stats.rx_errors++;
449 if (netif_msg_rx_err (dev)) 451 if (netif_msg_rx_err (dev))
@@ -471,22 +473,22 @@ static void intr_complete (struct urb *urb)
471 int status = urb->status; 473 int status = urb->status;
472 474
473 switch (status) { 475 switch (status) {
474 /* success */ 476 /* success */
475 case 0: 477 case 0:
476 dev->driver_info->status(dev, urb); 478 dev->driver_info->status(dev, urb);
477 break; 479 break;
478 480
479 /* software-driven interface shutdown */ 481 /* software-driven interface shutdown */
480 case -ENOENT: // urb killed 482 case -ENOENT: /* urb killed */
481 case -ESHUTDOWN: // hardware gone 483 case -ESHUTDOWN: /* hardware gone */
482 if (netif_msg_ifdown (dev)) 484 if (netif_msg_ifdown (dev))
483 devdbg (dev, "intr shutdown, code %d", status); 485 devdbg (dev, "intr shutdown, code %d", status);
484 return; 486 return;
485 487
486 /* NOTE: not throttling like RX/TX, since this endpoint 488 /* NOTE: not throttling like RX/TX, since this endpoint
487 * already polls infrequently 489 * already polls infrequently
488 */ 490 */
489 default: 491 default:
490 devdbg (dev, "intr status %d", status); 492 devdbg (dev, "intr status %d", status);
491 break; 493 break;
492 } 494 }
@@ -569,9 +571,9 @@ static int usbnet_stop (struct net_device *net)
569 temp = unlink_urbs (dev, &dev->txq) + unlink_urbs (dev, &dev->rxq); 571 temp = unlink_urbs (dev, &dev->txq) + unlink_urbs (dev, &dev->rxq);
570 572
571 // maybe wait for deletions to finish. 573 // maybe wait for deletions to finish.
572 while (!skb_queue_empty(&dev->rxq) && 574 while (!skb_queue_empty(&dev->rxq)
573 !skb_queue_empty(&dev->txq) && 575 && !skb_queue_empty(&dev->txq)
574 !skb_queue_empty(&dev->done)) { 576 && !skb_queue_empty(&dev->done)) {
575 msleep(UNLINK_TIMEOUT_MS); 577 msleep(UNLINK_TIMEOUT_MS);
576 if (netif_msg_ifdown (dev)) 578 if (netif_msg_ifdown (dev))
577 devdbg (dev, "waited for %d urb completions", temp); 579 devdbg (dev, "waited for %d urb completions", temp);
@@ -1011,16 +1013,16 @@ static void usbnet_bh (unsigned long param)
1011 while ((skb = skb_dequeue (&dev->done))) { 1013 while ((skb = skb_dequeue (&dev->done))) {
1012 entry = (struct skb_data *) skb->cb; 1014 entry = (struct skb_data *) skb->cb;
1013 switch (entry->state) { 1015 switch (entry->state) {
1014 case rx_done: 1016 case rx_done:
1015 entry->state = rx_cleanup; 1017 entry->state = rx_cleanup;
1016 rx_process (dev, skb); 1018 rx_process (dev, skb);
1017 continue; 1019 continue;
1018 case tx_done: 1020 case tx_done:
1019 case rx_cleanup: 1021 case rx_cleanup:
1020 usb_free_urb (entry->urb); 1022 usb_free_urb (entry->urb);
1021 dev_kfree_skb (skb); 1023 dev_kfree_skb (skb);
1022 continue; 1024 continue;
1023 default: 1025 default:
1024 devdbg (dev, "bogus skb state %d", entry->state); 1026 devdbg (dev, "bogus skb state %d", entry->state);
1025 } 1027 }
1026 } 1028 }
@@ -1211,7 +1213,7 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
1211 status = 0; 1213 status = 0;
1212 1214
1213 } 1215 }
1214 if (status == 0 && dev->status) 1216 if (status >= 0 && dev->status)
1215 status = init_status (dev, udev); 1217 status = init_status (dev, udev);
1216 if (status < 0) 1218 if (status < 0)
1217 goto out3; 1219 goto out3;
diff --git a/drivers/net/usb/usbnet.h b/drivers/net/usb/usbnet.h
index a3f8b9e7bc00..a6c5820767de 100644
--- a/drivers/net/usb/usbnet.h
+++ b/drivers/net/usb/usbnet.h
@@ -47,7 +47,7 @@ struct usbnet {
47 unsigned long data [5]; 47 unsigned long data [5];
48 u32 xid; 48 u32 xid;
49 u32 hard_mtu; /* count any extra framing */ 49 u32 hard_mtu; /* count any extra framing */
50 size_t rx_urb_size; /* size for rx urbs */ 50 size_t rx_urb_size; /* size for rx urbs */
51 struct mii_if_info mii; 51 struct mii_if_info mii;
52 52
53 /* various kinds of pending driver work */ 53 /* various kinds of pending driver work */
@@ -85,7 +85,7 @@ struct driver_info {
85#define FLAG_NO_SETINT 0x0010 /* device can't set_interface() */ 85#define FLAG_NO_SETINT 0x0010 /* device can't set_interface() */
86#define FLAG_ETHER 0x0020 /* maybe use "eth%d" names */ 86#define FLAG_ETHER 0x0020 /* maybe use "eth%d" names */
87 87
88#define FLAG_FRAMING_AX 0x0040 /* AX88772/178 packets */ 88#define FLAG_FRAMING_AX 0x0040 /* AX88772/178 packets */
89 89
90 /* init device ... can sleep, or cause probe() failure */ 90 /* init device ... can sleep, or cause probe() failure */
91 int (*bind)(struct usbnet *, struct usb_interface *); 91 int (*bind)(struct usbnet *, struct usb_interface *);
@@ -146,9 +146,9 @@ extern void usbnet_cdc_unbind (struct usbnet *, struct usb_interface *);
146 146
147/* CDC and RNDIS support the same host-chosen packet filters for IN transfers */ 147/* CDC and RNDIS support the same host-chosen packet filters for IN transfers */
148#define DEFAULT_FILTER (USB_CDC_PACKET_TYPE_BROADCAST \ 148#define DEFAULT_FILTER (USB_CDC_PACKET_TYPE_BROADCAST \
149 |USB_CDC_PACKET_TYPE_ALL_MULTICAST \ 149 |USB_CDC_PACKET_TYPE_ALL_MULTICAST \
150 |USB_CDC_PACKET_TYPE_PROMISCUOUS \ 150 |USB_CDC_PACKET_TYPE_PROMISCUOUS \
151 |USB_CDC_PACKET_TYPE_DIRECTED) 151 |USB_CDC_PACKET_TYPE_DIRECTED)
152 152
153 153
154/* we record the state for each of our queued skbs */ 154/* we record the state for each of our queued skbs */
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index fa2399cbd5ca..ae27af0141c0 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -546,6 +546,18 @@ config USB_ZD1201
546 To compile this driver as a module, choose M here: the 546 To compile this driver as a module, choose M here: the
547 module will be called zd1201. 547 module will be called zd1201.
548 548
549config RTL8187
550 tristate "Realtek 8187 USB support"
551 depends on MAC80211 && USB && WLAN_80211 && EXPERIMENTAL
552 select EEPROM_93CX6
553 ---help---
554 This is a driver for RTL8187 based cards.
555 These are USB based chips found in cards such as:
556
557 Netgear WG111v2
558
559 Thanks to Realtek for their support!
560
549source "drivers/net/wireless/hostap/Kconfig" 561source "drivers/net/wireless/hostap/Kconfig"
550source "drivers/net/wireless/bcm43xx/Kconfig" 562source "drivers/net/wireless/bcm43xx/Kconfig"
551source "drivers/net/wireless/zd1211rw/Kconfig" 563source "drivers/net/wireless/zd1211rw/Kconfig"
diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile
index d2124602263b..ef35bc6c4a22 100644
--- a/drivers/net/wireless/Makefile
+++ b/drivers/net/wireless/Makefile
@@ -44,3 +44,6 @@ obj-$(CONFIG_PCMCIA_WL3501) += wl3501_cs.o
44 44
45obj-$(CONFIG_USB_ZD1201) += zd1201.o 45obj-$(CONFIG_USB_ZD1201) += zd1201.o
46obj-$(CONFIG_LIBERTAS_USB) += libertas/ 46obj-$(CONFIG_LIBERTAS_USB) += libertas/
47
48rtl8187-objs := rtl8187_dev.o rtl8187_rtl8225.o
49obj-$(CONFIG_RTL8187) += rtl8187.o
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_phy.c b/drivers/net/wireless/bcm43xx/bcm43xx_phy.c
index b37f1e348700..d779199c30d0 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_phy.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_phy.c
@@ -1638,7 +1638,7 @@ void bcm43xx_phy_set_baseband_attenuation(struct bcm43xx_private *bcm,
1638 return; 1638 return;
1639 } 1639 }
1640 1640
1641 if (phy->analog > 1) { 1641 if (phy->analog == 1) {
1642 value = bcm43xx_phy_read(bcm, 0x0060) & ~0x003C; 1642 value = bcm43xx_phy_read(bcm, 0x0060) & ~0x003C;
1643 value |= (baseband_attenuation << 2) & 0x003C; 1643 value |= (baseband_attenuation << 2) & 0x003C;
1644 } else { 1644 } else {
diff --git a/drivers/net/wireless/hostap/hostap_ap.c b/drivers/net/wireless/hostap/hostap_ap.c
index 5b3abd54d0e5..90900525379c 100644
--- a/drivers/net/wireless/hostap/hostap_ap.c
+++ b/drivers/net/wireless/hostap/hostap_ap.c
@@ -326,7 +326,6 @@ static int ap_control_proc_read(char *page, char **start, off_t off,
326 char *p = page; 326 char *p = page;
327 struct ap_data *ap = (struct ap_data *) data; 327 struct ap_data *ap = (struct ap_data *) data;
328 char *policy_txt; 328 char *policy_txt;
329 struct list_head *ptr;
330 struct mac_entry *entry; 329 struct mac_entry *entry;
331 330
332 if (off != 0) { 331 if (off != 0) {
@@ -352,14 +351,12 @@ static int ap_control_proc_read(char *page, char **start, off_t off,
352 p += sprintf(p, "MAC entries: %u\n", ap->mac_restrictions.entries); 351 p += sprintf(p, "MAC entries: %u\n", ap->mac_restrictions.entries);
353 p += sprintf(p, "MAC list:\n"); 352 p += sprintf(p, "MAC list:\n");
354 spin_lock_bh(&ap->mac_restrictions.lock); 353 spin_lock_bh(&ap->mac_restrictions.lock);
355 for (ptr = ap->mac_restrictions.mac_list.next; 354 list_for_each_entry(entry, &ap->mac_restrictions.mac_list, list) {
356 ptr != &ap->mac_restrictions.mac_list; ptr = ptr->next) {
357 if (p - page > PAGE_SIZE - 80) { 355 if (p - page > PAGE_SIZE - 80) {
358 p += sprintf(p, "All entries did not fit one page.\n"); 356 p += sprintf(p, "All entries did not fit one page.\n");
359 break; 357 break;
360 } 358 }
361 359
362 entry = list_entry(ptr, struct mac_entry, list);
363 p += sprintf(p, MACSTR "\n", MAC2STR(entry->addr)); 360 p += sprintf(p, MACSTR "\n", MAC2STR(entry->addr));
364 } 361 }
365 spin_unlock_bh(&ap->mac_restrictions.lock); 362 spin_unlock_bh(&ap->mac_restrictions.lock);
@@ -413,7 +410,6 @@ int ap_control_del_mac(struct mac_restrictions *mac_restrictions, u8 *mac)
413static int ap_control_mac_deny(struct mac_restrictions *mac_restrictions, 410static int ap_control_mac_deny(struct mac_restrictions *mac_restrictions,
414 u8 *mac) 411 u8 *mac)
415{ 412{
416 struct list_head *ptr;
417 struct mac_entry *entry; 413 struct mac_entry *entry;
418 int found = 0; 414 int found = 0;
419 415
@@ -421,10 +417,7 @@ static int ap_control_mac_deny(struct mac_restrictions *mac_restrictions,
421 return 0; 417 return 0;
422 418
423 spin_lock_bh(&mac_restrictions->lock); 419 spin_lock_bh(&mac_restrictions->lock);
424 for (ptr = mac_restrictions->mac_list.next; 420 list_for_each_entry(entry, &mac_restrictions->mac_list, list) {
425 ptr != &mac_restrictions->mac_list; ptr = ptr->next) {
426 entry = list_entry(ptr, struct mac_entry, list);
427
428 if (memcmp(entry->addr, mac, ETH_ALEN) == 0) { 421 if (memcmp(entry->addr, mac, ETH_ALEN) == 0) {
429 found = 1; 422 found = 1;
430 break; 423 break;
@@ -519,7 +512,7 @@ static int prism2_ap_proc_read(char *page, char **start, off_t off,
519{ 512{
520 char *p = page; 513 char *p = page;
521 struct ap_data *ap = (struct ap_data *) data; 514 struct ap_data *ap = (struct ap_data *) data;
522 struct list_head *ptr; 515 struct sta_info *sta;
523 int i; 516 int i;
524 517
525 if (off > PROC_LIMIT) { 518 if (off > PROC_LIMIT) {
@@ -529,9 +522,7 @@ static int prism2_ap_proc_read(char *page, char **start, off_t off,
529 522
530 p += sprintf(p, "# BSSID CHAN SIGNAL NOISE RATE SSID FLAGS\n"); 523 p += sprintf(p, "# BSSID CHAN SIGNAL NOISE RATE SSID FLAGS\n");
531 spin_lock_bh(&ap->sta_table_lock); 524 spin_lock_bh(&ap->sta_table_lock);
532 for (ptr = ap->sta_list.next; ptr != &ap->sta_list; ptr = ptr->next) { 525 list_for_each_entry(sta, &ap->sta_list, list) {
533 struct sta_info *sta = (struct sta_info *) ptr;
534
535 if (!sta->ap) 526 if (!sta->ap)
536 continue; 527 continue;
537 528
@@ -861,7 +852,7 @@ void hostap_init_ap_proc(local_info_t *local)
861 852
862void hostap_free_data(struct ap_data *ap) 853void hostap_free_data(struct ap_data *ap)
863{ 854{
864 struct list_head *n, *ptr; 855 struct sta_info *n, *sta;
865 856
866 if (ap == NULL || !ap->initialized) { 857 if (ap == NULL || !ap->initialized) {
867 printk(KERN_DEBUG "hostap_free_data: ap has not yet been " 858 printk(KERN_DEBUG "hostap_free_data: ap has not yet been "
@@ -875,8 +866,7 @@ void hostap_free_data(struct ap_data *ap)
875 ap->crypt = ap->crypt_priv = NULL; 866 ap->crypt = ap->crypt_priv = NULL;
876#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */ 867#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
877 868
878 list_for_each_safe(ptr, n, &ap->sta_list) { 869 list_for_each_entry_safe(sta, n, &ap->sta_list, list) {
879 struct sta_info *sta = list_entry(ptr, struct sta_info, list);
880 ap_sta_hash_del(ap, sta); 870 ap_sta_hash_del(ap, sta);
881 list_del(&sta->list); 871 list_del(&sta->list);
882 if ((sta->flags & WLAN_STA_ASSOC) && !sta->ap && sta->local) 872 if ((sta->flags & WLAN_STA_ASSOC) && !sta->ap && sta->local)
@@ -2704,6 +2694,8 @@ ap_tx_ret hostap_handle_sta_tx(local_info_t *local, struct hostap_tx_data *tx)
2704 2694
2705 if (hdr->addr1[0] & 0x01) { 2695 if (hdr->addr1[0] & 0x01) {
2706 /* broadcast/multicast frame - no AP related processing */ 2696 /* broadcast/multicast frame - no AP related processing */
2697 if (local->ap->num_sta <= 0)
2698 ret = AP_TX_DROP;
2707 goto out; 2699 goto out;
2708 } 2700 }
2709 2701
@@ -3198,15 +3190,14 @@ int hostap_update_rx_stats(struct ap_data *ap,
3198 3190
3199void hostap_update_rates(local_info_t *local) 3191void hostap_update_rates(local_info_t *local)
3200{ 3192{
3201 struct list_head *ptr; 3193 struct sta_info *sta;
3202 struct ap_data *ap = local->ap; 3194 struct ap_data *ap = local->ap;
3203 3195
3204 if (!ap) 3196 if (!ap)
3205 return; 3197 return;
3206 3198
3207 spin_lock_bh(&ap->sta_table_lock); 3199 spin_lock_bh(&ap->sta_table_lock);
3208 for (ptr = ap->sta_list.next; ptr != &ap->sta_list; ptr = ptr->next) { 3200 list_for_each_entry(sta, &ap->sta_list, list) {
3209 struct sta_info *sta = (struct sta_info *) ptr;
3210 prism2_check_tx_rates(sta); 3201 prism2_check_tx_rates(sta);
3211 } 3202 }
3212 spin_unlock_bh(&ap->sta_table_lock); 3203 spin_unlock_bh(&ap->sta_table_lock);
@@ -3242,11 +3233,10 @@ void * ap_crypt_get_ptrs(struct ap_data *ap, u8 *addr, int permanent,
3242void hostap_add_wds_links(local_info_t *local) 3233void hostap_add_wds_links(local_info_t *local)
3243{ 3234{
3244 struct ap_data *ap = local->ap; 3235 struct ap_data *ap = local->ap;
3245 struct list_head *ptr; 3236 struct sta_info *sta;
3246 3237
3247 spin_lock_bh(&ap->sta_table_lock); 3238 spin_lock_bh(&ap->sta_table_lock);
3248 list_for_each(ptr, &ap->sta_list) { 3239 list_for_each_entry(sta, &ap->sta_list, list) {
3249 struct sta_info *sta = list_entry(ptr, struct sta_info, list);
3250 if (sta->ap) 3240 if (sta->ap)
3251 hostap_wds_link_oper(local, sta->addr, WDS_ADD); 3241 hostap_wds_link_oper(local, sta->addr, WDS_ADD);
3252 } 3242 }
diff --git a/drivers/net/wireless/hostap/hostap_config.h b/drivers/net/wireless/hostap/hostap_config.h
index c090a5aebb58..30acd39d76a2 100644
--- a/drivers/net/wireless/hostap/hostap_config.h
+++ b/drivers/net/wireless/hostap/hostap_config.h
@@ -1,8 +1,6 @@
1#ifndef HOSTAP_CONFIG_H 1#ifndef HOSTAP_CONFIG_H
2#define HOSTAP_CONFIG_H 2#define HOSTAP_CONFIG_H
3 3
4#define PRISM2_VERSION "0.4.4-kernel"
5
6/* In the previous versions of Host AP driver, support for user space version 4/* In the previous versions of Host AP driver, support for user space version
7 * of IEEE 802.11 management (hostapd) used to be disabled in the default 5 * of IEEE 802.11 management (hostapd) used to be disabled in the default
8 * configuration. From now on, support for hostapd is always included and it is 6 * configuration. From now on, support for hostapd is always included and it is
diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c
index ee1532b62e42..30e723f65979 100644
--- a/drivers/net/wireless/hostap/hostap_cs.c
+++ b/drivers/net/wireless/hostap/hostap_cs.c
@@ -22,7 +22,6 @@
22#include "hostap_wlan.h" 22#include "hostap_wlan.h"
23 23
24 24
25static char *version = PRISM2_VERSION " (Jouni Malinen <j@w1.fi>)";
26static dev_info_t dev_info = "hostap_cs"; 25static dev_info_t dev_info = "hostap_cs";
27 26
28MODULE_AUTHOR("Jouni Malinen"); 27MODULE_AUTHOR("Jouni Malinen");
@@ -30,7 +29,6 @@ MODULE_DESCRIPTION("Support for Intersil Prism2-based 802.11 wireless LAN "
30 "cards (PC Card)."); 29 "cards (PC Card).");
31MODULE_SUPPORTED_DEVICE("Intersil Prism2-based WLAN cards (PC Card)"); 30MODULE_SUPPORTED_DEVICE("Intersil Prism2-based WLAN cards (PC Card)");
32MODULE_LICENSE("GPL"); 31MODULE_LICENSE("GPL");
33MODULE_VERSION(PRISM2_VERSION);
34 32
35 33
36static int ignore_cis_vcc; 34static int ignore_cis_vcc;
@@ -910,14 +908,12 @@ static struct pcmcia_driver hostap_driver = {
910 908
911static int __init init_prism2_pccard(void) 909static int __init init_prism2_pccard(void)
912{ 910{
913 printk(KERN_INFO "%s: %s\n", dev_info, version);
914 return pcmcia_register_driver(&hostap_driver); 911 return pcmcia_register_driver(&hostap_driver);
915} 912}
916 913
917static void __exit exit_prism2_pccard(void) 914static void __exit exit_prism2_pccard(void)
918{ 915{
919 pcmcia_unregister_driver(&hostap_driver); 916 pcmcia_unregister_driver(&hostap_driver);
920 printk(KERN_INFO "%s: Driver unloaded\n", dev_info);
921} 917}
922 918
923 919
diff --git a/drivers/net/wireless/hostap/hostap_ioctl.c b/drivers/net/wireless/hostap/hostap_ioctl.c
index cdea7f71b9eb..8c71077d653c 100644
--- a/drivers/net/wireless/hostap/hostap_ioctl.c
+++ b/drivers/net/wireless/hostap/hostap_ioctl.c
@@ -3893,8 +3893,6 @@ static void prism2_get_drvinfo(struct net_device *dev,
3893 local = iface->local; 3893 local = iface->local;
3894 3894
3895 strncpy(info->driver, "hostap", sizeof(info->driver) - 1); 3895 strncpy(info->driver, "hostap", sizeof(info->driver) - 1);
3896 strncpy(info->version, PRISM2_VERSION,
3897 sizeof(info->version) - 1);
3898 snprintf(info->fw_version, sizeof(info->fw_version) - 1, 3896 snprintf(info->fw_version, sizeof(info->fw_version) - 1,
3899 "%d.%d.%d", (local->sta_fw_ver >> 16) & 0xff, 3897 "%d.%d.%d", (local->sta_fw_ver >> 16) & 0xff,
3900 (local->sta_fw_ver >> 8) & 0xff, 3898 (local->sta_fw_ver >> 8) & 0xff,
diff --git a/drivers/net/wireless/hostap/hostap_main.c b/drivers/net/wireless/hostap/hostap_main.c
index 4743426cf6ad..446de51bab74 100644
--- a/drivers/net/wireless/hostap/hostap_main.c
+++ b/drivers/net/wireless/hostap/hostap_main.c
@@ -37,7 +37,6 @@
37MODULE_AUTHOR("Jouni Malinen"); 37MODULE_AUTHOR("Jouni Malinen");
38MODULE_DESCRIPTION("Host AP common routines"); 38MODULE_DESCRIPTION("Host AP common routines");
39MODULE_LICENSE("GPL"); 39MODULE_LICENSE("GPL");
40MODULE_VERSION(PRISM2_VERSION);
41 40
42#define TX_TIMEOUT (2 * HZ) 41#define TX_TIMEOUT (2 * HZ)
43 42
diff --git a/drivers/net/wireless/hostap/hostap_pci.c b/drivers/net/wireless/hostap/hostap_pci.c
index db4899ed4bb1..0cd48d151f5e 100644
--- a/drivers/net/wireless/hostap/hostap_pci.c
+++ b/drivers/net/wireless/hostap/hostap_pci.c
@@ -20,7 +20,6 @@
20#include "hostap_wlan.h" 20#include "hostap_wlan.h"
21 21
22 22
23static char *version = PRISM2_VERSION " (Jouni Malinen <j@w1.fi>)";
24static char *dev_info = "hostap_pci"; 23static char *dev_info = "hostap_pci";
25 24
26 25
@@ -29,7 +28,6 @@ MODULE_DESCRIPTION("Support for Intersil Prism2.5-based 802.11 wireless LAN "
29 "PCI cards."); 28 "PCI cards.");
30MODULE_SUPPORTED_DEVICE("Intersil Prism2.5-based WLAN PCI cards"); 29MODULE_SUPPORTED_DEVICE("Intersil Prism2.5-based WLAN PCI cards");
31MODULE_LICENSE("GPL"); 30MODULE_LICENSE("GPL");
32MODULE_VERSION(PRISM2_VERSION);
33 31
34 32
35/* struct local_info::hw_priv */ 33/* struct local_info::hw_priv */
@@ -462,8 +460,6 @@ static struct pci_driver prism2_pci_drv_id = {
462 460
463static int __init init_prism2_pci(void) 461static int __init init_prism2_pci(void)
464{ 462{
465 printk(KERN_INFO "%s: %s\n", dev_info, version);
466
467 return pci_register_driver(&prism2_pci_drv_id); 463 return pci_register_driver(&prism2_pci_drv_id);
468} 464}
469 465
@@ -471,7 +467,6 @@ static int __init init_prism2_pci(void)
471static void __exit exit_prism2_pci(void) 467static void __exit exit_prism2_pci(void)
472{ 468{
473 pci_unregister_driver(&prism2_pci_drv_id); 469 pci_unregister_driver(&prism2_pci_drv_id);
474 printk(KERN_INFO "%s: Driver unloaded\n", dev_info);
475} 470}
476 471
477 472
diff --git a/drivers/net/wireless/hostap/hostap_plx.c b/drivers/net/wireless/hostap/hostap_plx.c
index f0fd5ecdb24d..0183df757b3e 100644
--- a/drivers/net/wireless/hostap/hostap_plx.c
+++ b/drivers/net/wireless/hostap/hostap_plx.c
@@ -23,7 +23,6 @@
23#include "hostap_wlan.h" 23#include "hostap_wlan.h"
24 24
25 25
26static char *version = PRISM2_VERSION " (Jouni Malinen <j@w1.fi>)";
27static char *dev_info = "hostap_plx"; 26static char *dev_info = "hostap_plx";
28 27
29 28
@@ -32,7 +31,6 @@ MODULE_DESCRIPTION("Support for Intersil Prism2-based 802.11 wireless LAN "
32 "cards (PLX)."); 31 "cards (PLX).");
33MODULE_SUPPORTED_DEVICE("Intersil Prism2-based WLAN cards (PLX)"); 32MODULE_SUPPORTED_DEVICE("Intersil Prism2-based WLAN cards (PLX)");
34MODULE_LICENSE("GPL"); 33MODULE_LICENSE("GPL");
35MODULE_VERSION(PRISM2_VERSION);
36 34
37 35
38static int ignore_cis; 36static int ignore_cis;
@@ -623,8 +621,6 @@ static struct pci_driver prism2_plx_drv_id = {
623 621
624static int __init init_prism2_plx(void) 622static int __init init_prism2_plx(void)
625{ 623{
626 printk(KERN_INFO "%s: %s\n", dev_info, version);
627
628 return pci_register_driver(&prism2_plx_drv_id); 624 return pci_register_driver(&prism2_plx_drv_id);
629} 625}
630 626
@@ -632,7 +628,6 @@ static int __init init_prism2_plx(void)
632static void __exit exit_prism2_plx(void) 628static void __exit exit_prism2_plx(void)
633{ 629{
634 pci_unregister_driver(&prism2_plx_drv_id); 630 pci_unregister_driver(&prism2_plx_drv_id);
635 printk(KERN_INFO "%s: Driver unloaded\n", dev_info);
636} 631}
637 632
638 633
diff --git a/drivers/net/wireless/rtl8187.h b/drivers/net/wireless/rtl8187.h
new file mode 100644
index 000000000000..6124e467b156
--- /dev/null
+++ b/drivers/net/wireless/rtl8187.h
@@ -0,0 +1,145 @@
1/*
2 * Definitions for RTL8187 hardware
3 *
4 * Copyright 2007 Michael Wu <flamingice@sourmilk.net>
5 * Copyright 2007 Andrea Merello <andreamrl@tiscali.it>
6 *
7 * Based on the r8187 driver, which is:
8 * Copyright 2005 Andrea Merello <andreamrl@tiscali.it>, et al.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#ifndef RTL8187_H
16#define RTL8187_H
17
18#include "rtl818x.h"
19
20#define RTL8187_EEPROM_TXPWR_BASE 0x05
21#define RTL8187_EEPROM_MAC_ADDR 0x07
22#define RTL8187_EEPROM_TXPWR_CHAN_1 0x16 /* 3 channels */
23#define RTL8187_EEPROM_TXPWR_CHAN_6 0x1B /* 2 channels */
24#define RTL8187_EEPROM_TXPWR_CHAN_4 0x3D /* 2 channels */
25
26#define RTL8187_REQT_READ 0xC0
27#define RTL8187_REQT_WRITE 0x40
28#define RTL8187_REQ_GET_REG 0x05
29#define RTL8187_REQ_SET_REG 0x05
30
31#define RTL8187_MAX_RX 0x9C4
32
33struct rtl8187_rx_info {
34 struct urb *urb;
35 struct ieee80211_hw *dev;
36};
37
38struct rtl8187_rx_hdr {
39 __le16 len;
40 __le16 rate;
41 u8 noise;
42 u8 signal;
43 u8 agc;
44 u8 reserved;
45 __le64 mac_time;
46} __attribute__((packed));
47
48struct rtl8187_tx_info {
49 struct ieee80211_tx_control *control;
50 struct urb *urb;
51 struct ieee80211_hw *dev;
52};
53
54struct rtl8187_tx_hdr {
55 __le32 flags;
56#define RTL8187_TX_FLAG_NO_ENCRYPT (1 << 15)
57#define RTL8187_TX_FLAG_MORE_FRAG (1 << 17)
58#define RTL8187_TX_FLAG_CTS (1 << 18)
59#define RTL8187_TX_FLAG_RTS (1 << 23)
60 __le16 rts_duration;
61 __le16 len;
62 __le32 retry;
63} __attribute__((packed));
64
65struct rtl8187_priv {
66 /* common between rtl818x drivers */
67 struct rtl818x_csr *map;
68 void (*rf_init)(struct ieee80211_hw *);
69 int mode;
70
71 /* rtl8187 specific */
72 struct ieee80211_channel channels[14];
73 struct ieee80211_rate rates[12];
74 struct ieee80211_hw_mode modes[2];
75 struct usb_device *udev;
76 u8 *hwaddr;
77 u16 txpwr_base;
78 u8 asic_rev;
79 struct sk_buff_head rx_queue;
80};
81
82void rtl8187_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data);
83
84static inline u8 rtl818x_ioread8(struct rtl8187_priv *priv, u8 *addr)
85{
86 u8 val;
87
88 usb_control_msg(priv->udev, usb_rcvctrlpipe(priv->udev, 0),
89 RTL8187_REQ_GET_REG, RTL8187_REQT_READ,
90 (unsigned long)addr, 0, &val, sizeof(val), HZ / 2);
91
92 return val;
93}
94
95static inline u16 rtl818x_ioread16(struct rtl8187_priv *priv, __le16 *addr)
96{
97 __le16 val;
98
99 usb_control_msg(priv->udev, usb_rcvctrlpipe(priv->udev, 0),
100 RTL8187_REQ_GET_REG, RTL8187_REQT_READ,
101 (unsigned long)addr, 0, &val, sizeof(val), HZ / 2);
102
103 return le16_to_cpu(val);
104}
105
106static inline u32 rtl818x_ioread32(struct rtl8187_priv *priv, __le32 *addr)
107{
108 __le32 val;
109
110 usb_control_msg(priv->udev, usb_rcvctrlpipe(priv->udev, 0),
111 RTL8187_REQ_GET_REG, RTL8187_REQT_READ,
112 (unsigned long)addr, 0, &val, sizeof(val), HZ / 2);
113
114 return le32_to_cpu(val);
115}
116
117static inline void rtl818x_iowrite8(struct rtl8187_priv *priv,
118 u8 *addr, u8 val)
119{
120 usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0),
121 RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE,
122 (unsigned long)addr, 0, &val, sizeof(val), HZ / 2);
123}
124
125static inline void rtl818x_iowrite16(struct rtl8187_priv *priv,
126 __le16 *addr, u16 val)
127{
128 __le16 buf = cpu_to_le16(val);
129
130 usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0),
131 RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE,
132 (unsigned long)addr, 0, &buf, sizeof(buf), HZ / 2);
133}
134
135static inline void rtl818x_iowrite32(struct rtl8187_priv *priv,
136 __le32 *addr, u32 val)
137{
138 __le32 buf = cpu_to_le32(val);
139
140 usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0),
141 RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE,
142 (unsigned long)addr, 0, &buf, sizeof(buf), HZ / 2);
143}
144
145#endif /* RTL8187_H */
diff --git a/drivers/net/wireless/rtl8187_dev.c b/drivers/net/wireless/rtl8187_dev.c
new file mode 100644
index 000000000000..cea85894b7f2
--- /dev/null
+++ b/drivers/net/wireless/rtl8187_dev.c
@@ -0,0 +1,731 @@
1/*
2 * Linux device driver for RTL8187
3 *
4 * Copyright 2007 Michael Wu <flamingice@sourmilk.net>
5 * Copyright 2007 Andrea Merello <andreamrl@tiscali.it>
6 *
7 * Based on the r8187 driver, which is:
8 * Copyright 2005 Andrea Merello <andreamrl@tiscali.it>, et al.
9 *
10 * Magic delays and register offsets below are taken from the original
11 * r8187 driver sources. Thanks to Realtek for their support!
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2 as
15 * published by the Free Software Foundation.
16 */
17
18#include <linux/init.h>
19#include <linux/usb.h>
20#include <linux/delay.h>
21#include <linux/etherdevice.h>
22#include <linux/eeprom_93cx6.h>
23#include <net/mac80211.h>
24
25#include "rtl8187.h"
26#include "rtl8187_rtl8225.h"
27
28MODULE_AUTHOR("Michael Wu <flamingice@sourmilk.net>");
29MODULE_AUTHOR("Andrea Merello <andreamrl@tiscali.it>");
30MODULE_DESCRIPTION("RTL8187 USB wireless driver");
31MODULE_LICENSE("GPL");
32
33static struct usb_device_id rtl8187_table[] __devinitdata = {
34 /* Realtek */
35 {USB_DEVICE(0x0bda, 0x8187)},
36 /* Netgear */
37 {USB_DEVICE(0x0846, 0x6100)},
38 {USB_DEVICE(0x0846, 0x6a00)},
39 {}
40};
41
42MODULE_DEVICE_TABLE(usb, rtl8187_table);
43
44void rtl8187_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data)
45{
46 struct rtl8187_priv *priv = dev->priv;
47
48 data <<= 8;
49 data |= addr | 0x80;
50
51 rtl818x_iowrite8(priv, &priv->map->PHY[3], (data >> 24) & 0xFF);
52 rtl818x_iowrite8(priv, &priv->map->PHY[2], (data >> 16) & 0xFF);
53 rtl818x_iowrite8(priv, &priv->map->PHY[1], (data >> 8) & 0xFF);
54 rtl818x_iowrite8(priv, &priv->map->PHY[0], data & 0xFF);
55
56 msleep(1);
57}
58
59static void rtl8187_tx_cb(struct urb *urb)
60{
61 struct ieee80211_tx_status status = { {0} };
62 struct sk_buff *skb = (struct sk_buff *)urb->context;
63 struct rtl8187_tx_info *info = (struct rtl8187_tx_info *)skb->cb;
64
65 usb_free_urb(info->urb);
66 if (info->control)
67 memcpy(&status.control, info->control, sizeof(status.control));
68 kfree(info->control);
69 skb_pull(skb, sizeof(struct rtl8187_tx_hdr));
70 status.flags |= IEEE80211_TX_STATUS_ACK;
71 ieee80211_tx_status_irqsafe(info->dev, skb, &status);
72}
73
74static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb,
75 struct ieee80211_tx_control *control)
76{
77 struct rtl8187_priv *priv = dev->priv;
78 struct rtl8187_tx_hdr *hdr;
79 struct rtl8187_tx_info *info;
80 struct urb *urb;
81 u32 tmp;
82
83 urb = usb_alloc_urb(0, GFP_ATOMIC);
84 if (!urb) {
85 kfree_skb(skb);
86 return 0;
87 }
88
89 hdr = (struct rtl8187_tx_hdr *)skb_push(skb, sizeof(*hdr));
90 tmp = skb->len - sizeof(*hdr);
91 tmp |= RTL8187_TX_FLAG_NO_ENCRYPT;
92 tmp |= control->rts_cts_rate << 19;
93 tmp |= control->tx_rate << 24;
94 if (ieee80211_get_morefrag((struct ieee80211_hdr *)skb))
95 tmp |= RTL8187_TX_FLAG_MORE_FRAG;
96 if (control->flags & IEEE80211_TXCTL_USE_RTS_CTS) {
97 tmp |= RTL8187_TX_FLAG_RTS;
98 hdr->rts_duration =
99 ieee80211_rts_duration(dev, skb->len, control);
100 }
101 if (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT)
102 tmp |= RTL8187_TX_FLAG_CTS;
103 hdr->flags = cpu_to_le32(tmp);
104 hdr->len = 0;
105 tmp = control->retry_limit << 8;
106 hdr->retry = cpu_to_le32(tmp);
107
108 info = (struct rtl8187_tx_info *)skb->cb;
109 info->control = kmemdup(control, sizeof(*control), GFP_ATOMIC);
110 info->urb = urb;
111 info->dev = dev;
112 usb_fill_bulk_urb(urb, priv->udev, usb_sndbulkpipe(priv->udev, 2),
113 hdr, skb->len, rtl8187_tx_cb, skb);
114 usb_submit_urb(urb, GFP_ATOMIC);
115
116 return 0;
117}
118
119static void rtl8187_rx_cb(struct urb *urb)
120{
121 struct sk_buff *skb = (struct sk_buff *)urb->context;
122 struct rtl8187_rx_info *info = (struct rtl8187_rx_info *)skb->cb;
123 struct ieee80211_hw *dev = info->dev;
124 struct rtl8187_priv *priv = dev->priv;
125 struct rtl8187_rx_hdr *hdr;
126 struct ieee80211_rx_status rx_status = { 0 };
127 int rate, signal;
128
129 spin_lock(&priv->rx_queue.lock);
130 if (skb->next)
131 __skb_unlink(skb, &priv->rx_queue);
132 else {
133 spin_unlock(&priv->rx_queue.lock);
134 return;
135 }
136 spin_unlock(&priv->rx_queue.lock);
137
138 if (unlikely(urb->status)) {
139 usb_free_urb(urb);
140 dev_kfree_skb_irq(skb);
141 return;
142 }
143
144 skb_put(skb, urb->actual_length);
145 hdr = (struct rtl8187_rx_hdr *)(skb_tail_pointer(skb) - sizeof(*hdr));
146 skb_trim(skb, le16_to_cpu(hdr->len) & 0x0FFF);
147
148 signal = hdr->agc >> 1;
149 rate = (le16_to_cpu(hdr->rate) >> 4) & 0xF;
150 if (rate > 3) { /* OFDM rate */
151 if (signal > 90)
152 signal = 90;
153 else if (signal < 25)
154 signal = 25;
155 signal = 90 - signal;
156 } else { /* CCK rate */
157 if (signal > 95)
158 signal = 95;
159 else if (signal < 30)
160 signal = 30;
161 signal = 95 - signal;
162 }
163
164 rx_status.antenna = (hdr->signal >> 7) & 1;
165 rx_status.signal = 64 - min(hdr->noise, (u8)64);
166 rx_status.ssi = signal;
167 rx_status.rate = rate;
168 rx_status.freq = dev->conf.freq;
169 rx_status.channel = dev->conf.channel;
170 rx_status.phymode = dev->conf.phymode;
171 rx_status.mactime = le64_to_cpu(hdr->mac_time);
172 ieee80211_rx_irqsafe(dev, skb, &rx_status);
173
174 skb = dev_alloc_skb(RTL8187_MAX_RX);
175 if (unlikely(!skb)) {
176 usb_free_urb(urb);
177 /* TODO check rx queue length and refill *somewhere* */
178 return;
179 }
180
181 info = (struct rtl8187_rx_info *)skb->cb;
182 info->urb = urb;
183 info->dev = dev;
184 urb->transfer_buffer = skb_tail_pointer(skb);
185 urb->context = skb;
186 skb_queue_tail(&priv->rx_queue, skb);
187
188 usb_submit_urb(urb, GFP_ATOMIC);
189}
190
191static int rtl8187_init_urbs(struct ieee80211_hw *dev)
192{
193 struct rtl8187_priv *priv = dev->priv;
194 struct urb *entry;
195 struct sk_buff *skb;
196 struct rtl8187_rx_info *info;
197
198 while (skb_queue_len(&priv->rx_queue) < 8) {
199 skb = __dev_alloc_skb(RTL8187_MAX_RX, GFP_KERNEL);
200 if (!skb)
201 break;
202 entry = usb_alloc_urb(0, GFP_KERNEL);
203 if (!entry) {
204 kfree_skb(skb);
205 break;
206 }
207 usb_fill_bulk_urb(entry, priv->udev,
208 usb_rcvbulkpipe(priv->udev, 1),
209 skb_tail_pointer(skb),
210 RTL8187_MAX_RX, rtl8187_rx_cb, skb);
211 info = (struct rtl8187_rx_info *)skb->cb;
212 info->urb = entry;
213 info->dev = dev;
214 skb_queue_tail(&priv->rx_queue, skb);
215 usb_submit_urb(entry, GFP_KERNEL);
216 }
217
218 return 0;
219}
220
221static int rtl8187_init_hw(struct ieee80211_hw *dev)
222{
223 struct rtl8187_priv *priv = dev->priv;
224 u8 reg;
225 int i;
226
227 /* reset */
228 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
229 reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
230 rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | RTL818X_CONFIG3_ANAPARAM_WRITE);
231 rtl818x_iowrite32(priv, &priv->map->ANAPARAM, RTL8225_ANAPARAM_ON);
232 rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, RTL8225_ANAPARAM2_ON);
233 rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE);
234 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
235
236 rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0);
237
238 msleep(200);
239 rtl818x_iowrite8(priv, (u8 *)0xFE18, 0x10);
240 rtl818x_iowrite8(priv, (u8 *)0xFE18, 0x11);
241 rtl818x_iowrite8(priv, (u8 *)0xFE18, 0x00);
242 msleep(200);
243
244 reg = rtl818x_ioread8(priv, &priv->map->CMD);
245 reg &= (1 << 1);
246 reg |= RTL818X_CMD_RESET;
247 rtl818x_iowrite8(priv, &priv->map->CMD, reg);
248
249 i = 10;
250 do {
251 msleep(2);
252 if (!(rtl818x_ioread8(priv, &priv->map->CMD) &
253 RTL818X_CMD_RESET))
254 break;
255 } while (--i);
256
257 if (!i) {
258 printk(KERN_ERR "%s: Reset timeout!\n", wiphy_name(dev->wiphy));
259 return -ETIMEDOUT;
260 }
261
262 /* reload registers from eeprom */
263 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_LOAD);
264
265 i = 10;
266 do {
267 msleep(4);
268 if (!(rtl818x_ioread8(priv, &priv->map->EEPROM_CMD) &
269 RTL818X_EEPROM_CMD_CONFIG))
270 break;
271 } while (--i);
272
273 if (!i) {
274 printk(KERN_ERR "%s: eeprom reset timeout!\n",
275 wiphy_name(dev->wiphy));
276 return -ETIMEDOUT;
277 }
278
279 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
280 reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
281 rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | RTL818X_CONFIG3_ANAPARAM_WRITE);
282 rtl818x_iowrite32(priv, &priv->map->ANAPARAM, RTL8225_ANAPARAM_ON);
283 rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, RTL8225_ANAPARAM2_ON);
284 rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE);
285 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
286
287 /* setup card */
288 rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0);
289 rtl818x_iowrite8(priv, &priv->map->GPIO, 0);
290
291 rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, (4 << 8));
292 rtl818x_iowrite8(priv, &priv->map->GPIO, 1);
293 rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0);
294
295 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
296 for (i = 0; i < ETH_ALEN; i++)
297 rtl818x_iowrite8(priv, &priv->map->MAC[i], priv->hwaddr[i]);
298
299 rtl818x_iowrite16(priv, (__le16 *)0xFFF4, 0xFFFF);
300 reg = rtl818x_ioread8(priv, &priv->map->CONFIG1);
301 reg &= 0x3F;
302 reg |= 0x80;
303 rtl818x_iowrite8(priv, &priv->map->CONFIG1, reg);
304
305 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
306
307 rtl818x_iowrite32(priv, &priv->map->INT_TIMEOUT, 0);
308 rtl818x_iowrite8(priv, &priv->map->WPA_CONF, 0);
309 rtl818x_iowrite8(priv, &priv->map->RATE_FALLBACK, 0x81);
310
311 // TODO: set RESP_RATE and BRSR properly
312 rtl818x_iowrite8(priv, &priv->map->RESP_RATE, (8 << 4) | 0);
313 rtl818x_iowrite16(priv, &priv->map->BRSR, 0x01F3);
314
315 /* host_usb_init */
316 rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0);
317 rtl818x_iowrite8(priv, &priv->map->GPIO, 0);
318 reg = rtl818x_ioread8(priv, (u8 *)0xFE53);
319 rtl818x_iowrite8(priv, (u8 *)0xFE53, reg | (1 << 7));
320 rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, (4 << 8));
321 rtl818x_iowrite8(priv, &priv->map->GPIO, 0x20);
322 rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0);
323 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x80);
324 rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x80);
325 rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x80);
326 msleep(100);
327
328 rtl818x_iowrite32(priv, &priv->map->RF_TIMING, 0x000a8008);
329 rtl818x_iowrite16(priv, &priv->map->BRSR, 0xFFFF);
330 rtl818x_iowrite32(priv, &priv->map->RF_PARA, 0x00100044);
331 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
332 rtl818x_iowrite8(priv, &priv->map->CONFIG3, 0x44);
333 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
334 rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FF7);
335 msleep(100);
336
337 priv->rf_init(dev);
338
339 rtl818x_iowrite16(priv, &priv->map->BRSR, 0x01F3);
340 reg = rtl818x_ioread16(priv, &priv->map->PGSELECT) & 0xfffe;
341 rtl818x_iowrite16(priv, &priv->map->PGSELECT, reg | 0x1);
342 rtl818x_iowrite16(priv, (__le16 *)0xFFFE, 0x10);
343 rtl818x_iowrite8(priv, &priv->map->TALLY_SEL, 0x80);
344 rtl818x_iowrite8(priv, (u8 *)0xFFFF, 0x60);
345 rtl818x_iowrite16(priv, &priv->map->PGSELECT, reg);
346
347 return 0;
348}
349
350static void rtl8187_set_channel(struct ieee80211_hw *dev, int channel)
351{
352 u32 reg;
353 struct rtl8187_priv *priv = dev->priv;
354
355 reg = rtl818x_ioread32(priv, &priv->map->TX_CONF);
356 /* Enable TX loopback on MAC level to avoid TX during channel
357 * changes, as this has be seen to causes problems and the
358 * card will stop work until next reset
359 */
360 rtl818x_iowrite32(priv, &priv->map->TX_CONF,
361 reg | RTL818X_TX_CONF_LOOPBACK_MAC);
362 msleep(10);
363 rtl8225_rf_set_channel(dev, channel);
364 msleep(10);
365 rtl818x_iowrite32(priv, &priv->map->TX_CONF, reg);
366}
367
368static int rtl8187_open(struct ieee80211_hw *dev)
369{
370 struct rtl8187_priv *priv = dev->priv;
371 u32 reg;
372 int ret;
373
374 ret = rtl8187_init_hw(dev);
375 if (ret)
376 return ret;
377
378 rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0xFFFF);
379
380 rtl8187_init_urbs(dev);
381
382 reg = RTL818X_RX_CONF_ONLYERLPKT |
383 RTL818X_RX_CONF_RX_AUTORESETPHY |
384 RTL818X_RX_CONF_BSSID |
385 RTL818X_RX_CONF_MGMT |
386 RTL818X_RX_CONF_CTRL |
387 RTL818X_RX_CONF_DATA |
388 (7 << 13 /* RX FIFO threshold NONE */) |
389 (7 << 10 /* MAX RX DMA */) |
390 RTL818X_RX_CONF_BROADCAST |
391 RTL818X_RX_CONF_MULTICAST |
392 RTL818X_RX_CONF_NICMAC;
393 if (priv->mode == IEEE80211_IF_TYPE_MNTR)
394 reg |= RTL818X_RX_CONF_MONITOR;
395
396 rtl818x_iowrite32(priv, &priv->map->RX_CONF, reg);
397
398 reg = rtl818x_ioread8(priv, &priv->map->CW_CONF);
399 reg &= ~RTL818X_CW_CONF_PERPACKET_CW_SHIFT;
400 reg |= RTL818X_CW_CONF_PERPACKET_RETRY_SHIFT;
401 rtl818x_iowrite8(priv, &priv->map->CW_CONF, reg);
402
403 reg = rtl818x_ioread8(priv, &priv->map->TX_AGC_CTL);
404 reg &= ~RTL818X_TX_AGC_CTL_PERPACKET_GAIN_SHIFT;
405 reg &= ~RTL818X_TX_AGC_CTL_PERPACKET_ANTSEL_SHIFT;
406 reg &= ~RTL818X_TX_AGC_CTL_FEEDBACK_ANT;
407 rtl818x_iowrite8(priv, &priv->map->TX_AGC_CTL, reg);
408
409 reg = RTL818X_TX_CONF_CW_MIN |
410 (7 << 21 /* MAX TX DMA */) |
411 RTL818X_TX_CONF_NO_ICV;
412 rtl818x_iowrite32(priv, &priv->map->TX_CONF, reg);
413
414 reg = rtl818x_ioread8(priv, &priv->map->CMD);
415 reg |= RTL818X_CMD_TX_ENABLE;
416 reg |= RTL818X_CMD_RX_ENABLE;
417 rtl818x_iowrite8(priv, &priv->map->CMD, reg);
418
419 return 0;
420}
421
422static int rtl8187_stop(struct ieee80211_hw *dev)
423{
424 struct rtl8187_priv *priv = dev->priv;
425 struct rtl8187_rx_info *info;
426 struct sk_buff *skb;
427 u32 reg;
428
429 rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0);
430
431 reg = rtl818x_ioread8(priv, &priv->map->CMD);
432 reg &= ~RTL818X_CMD_TX_ENABLE;
433 reg &= ~RTL818X_CMD_RX_ENABLE;
434 rtl818x_iowrite8(priv, &priv->map->CMD, reg);
435
436 rtl8225_rf_stop(dev);
437
438 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
439 reg = rtl818x_ioread8(priv, &priv->map->CONFIG4);
440 rtl818x_iowrite8(priv, &priv->map->CONFIG4, reg | RTL818X_CONFIG4_VCOOFF);
441 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
442
443 while ((skb = skb_dequeue(&priv->rx_queue))) {
444 info = (struct rtl8187_rx_info *)skb->cb;
445 usb_kill_urb(info->urb);
446 kfree_skb(skb);
447 }
448 return 0;
449}
450
451static int rtl8187_add_interface(struct ieee80211_hw *dev,
452 struct ieee80211_if_init_conf *conf)
453{
454 struct rtl8187_priv *priv = dev->priv;
455
456 /* NOTE: using IEEE80211_IF_TYPE_MGMT to indicate no mode selected */
457 if (priv->mode != IEEE80211_IF_TYPE_MGMT)
458 return -1;
459
460 switch (conf->type) {
461 case IEEE80211_IF_TYPE_STA:
462 case IEEE80211_IF_TYPE_MNTR:
463 priv->mode = conf->type;
464 break;
465 default:
466 return -EOPNOTSUPP;
467 }
468
469 priv->hwaddr = conf->mac_addr;
470
471 return 0;
472}
473
474static void rtl8187_remove_interface(struct ieee80211_hw *dev,
475 struct ieee80211_if_init_conf *conf)
476{
477 struct rtl8187_priv *priv = dev->priv;
478 priv->mode = IEEE80211_IF_TYPE_MGMT;
479}
480
481static int rtl8187_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf)
482{
483 struct rtl8187_priv *priv = dev->priv;
484 rtl8187_set_channel(dev, conf->channel);
485
486 rtl818x_iowrite8(priv, &priv->map->SIFS, 0x22);
487
488 if (conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME) {
489 rtl818x_iowrite8(priv, &priv->map->SLOT, 0x9);
490 rtl818x_iowrite8(priv, &priv->map->DIFS, 0x14);
491 rtl818x_iowrite8(priv, &priv->map->EIFS, 91 - 0x14);
492 rtl818x_iowrite8(priv, &priv->map->CW_VAL, 0x73);
493 } else {
494 rtl818x_iowrite8(priv, &priv->map->SLOT, 0x14);
495 rtl818x_iowrite8(priv, &priv->map->DIFS, 0x24);
496 rtl818x_iowrite8(priv, &priv->map->EIFS, 91 - 0x24);
497 rtl818x_iowrite8(priv, &priv->map->CW_VAL, 0xa5);
498 }
499
500 rtl818x_iowrite16(priv, &priv->map->ATIM_WND, 2);
501 rtl818x_iowrite16(priv, &priv->map->ATIMTR_INTERVAL, 100);
502 rtl818x_iowrite16(priv, &priv->map->BEACON_INTERVAL, 100);
503 rtl818x_iowrite16(priv, &priv->map->BEACON_INTERVAL_TIME, 100);
504 return 0;
505}
506
507static int rtl8187_config_interface(struct ieee80211_hw *dev, int if_id,
508 struct ieee80211_if_conf *conf)
509{
510 struct rtl8187_priv *priv = dev->priv;
511 int i;
512
513 for (i = 0; i < ETH_ALEN; i++)
514 rtl818x_iowrite8(priv, &priv->map->BSSID[i], conf->bssid[i]);
515
516 if (is_valid_ether_addr(conf->bssid))
517 rtl818x_iowrite8(priv, &priv->map->MSR, RTL818X_MSR_INFRA);
518 else
519 rtl818x_iowrite8(priv, &priv->map->MSR, RTL818X_MSR_NO_LINK);
520
521 return 0;
522}
523
524static const struct ieee80211_ops rtl8187_ops = {
525 .tx = rtl8187_tx,
526 .open = rtl8187_open,
527 .stop = rtl8187_stop,
528 .add_interface = rtl8187_add_interface,
529 .remove_interface = rtl8187_remove_interface,
530 .config = rtl8187_config,
531 .config_interface = rtl8187_config_interface,
532};
533
534static void rtl8187_eeprom_register_read(struct eeprom_93cx6 *eeprom)
535{
536 struct ieee80211_hw *dev = eeprom->data;
537 struct rtl8187_priv *priv = dev->priv;
538 u8 reg = rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
539
540 eeprom->reg_data_in = reg & RTL818X_EEPROM_CMD_WRITE;
541 eeprom->reg_data_out = reg & RTL818X_EEPROM_CMD_READ;
542 eeprom->reg_data_clock = reg & RTL818X_EEPROM_CMD_CK;
543 eeprom->reg_chip_select = reg & RTL818X_EEPROM_CMD_CS;
544}
545
546static void rtl8187_eeprom_register_write(struct eeprom_93cx6 *eeprom)
547{
548 struct ieee80211_hw *dev = eeprom->data;
549 struct rtl8187_priv *priv = dev->priv;
550 u8 reg = RTL818X_EEPROM_CMD_PROGRAM;
551
552 if (eeprom->reg_data_in)
553 reg |= RTL818X_EEPROM_CMD_WRITE;
554 if (eeprom->reg_data_out)
555 reg |= RTL818X_EEPROM_CMD_READ;
556 if (eeprom->reg_data_clock)
557 reg |= RTL818X_EEPROM_CMD_CK;
558 if (eeprom->reg_chip_select)
559 reg |= RTL818X_EEPROM_CMD_CS;
560
561 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, reg);
562 udelay(10);
563}
564
565static int __devinit rtl8187_probe(struct usb_interface *intf,
566 const struct usb_device_id *id)
567{
568 struct usb_device *udev = interface_to_usbdev(intf);
569 struct ieee80211_hw *dev;
570 struct rtl8187_priv *priv;
571 struct eeprom_93cx6 eeprom;
572 struct ieee80211_channel *channel;
573 u16 txpwr, reg;
574 int err, i;
575
576 dev = ieee80211_alloc_hw(sizeof(*priv), &rtl8187_ops);
577 if (!dev) {
578 printk(KERN_ERR "rtl8187: ieee80211 alloc failed\n");
579 return -ENOMEM;
580 }
581
582 priv = dev->priv;
583
584 SET_IEEE80211_DEV(dev, &intf->dev);
585 usb_set_intfdata(intf, dev);
586 priv->udev = udev;
587
588 usb_get_dev(udev);
589
590 skb_queue_head_init(&priv->rx_queue);
591 memcpy(priv->channels, rtl818x_channels, sizeof(rtl818x_channels));
592 memcpy(priv->rates, rtl818x_rates, sizeof(rtl818x_rates));
593 priv->map = (struct rtl818x_csr *)0xFF00;
594 priv->modes[0].mode = MODE_IEEE80211G;
595 priv->modes[0].num_rates = ARRAY_SIZE(rtl818x_rates);
596 priv->modes[0].rates = priv->rates;
597 priv->modes[0].num_channels = ARRAY_SIZE(rtl818x_channels);
598 priv->modes[0].channels = priv->channels;
599 priv->modes[1].mode = MODE_IEEE80211B;
600 priv->modes[1].num_rates = 4;
601 priv->modes[1].rates = priv->rates;
602 priv->modes[1].num_channels = ARRAY_SIZE(rtl818x_channels);
603 priv->modes[1].channels = priv->channels;
604 priv->mode = IEEE80211_IF_TYPE_MGMT;
605 dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
606 IEEE80211_HW_RX_INCLUDES_FCS |
607 IEEE80211_HW_WEP_INCLUDE_IV |
608 IEEE80211_HW_DATA_NULLFUNC_ACK;
609 dev->extra_tx_headroom = sizeof(struct rtl8187_tx_hdr);
610 dev->queues = 1;
611 dev->max_rssi = 65;
612 dev->max_signal = 64;
613
614 for (i = 0; i < 2; i++)
615 if ((err = ieee80211_register_hwmode(dev, &priv->modes[i])))
616 goto err_free_dev;
617
618 eeprom.data = dev;
619 eeprom.register_read = rtl8187_eeprom_register_read;
620 eeprom.register_write = rtl8187_eeprom_register_write;
621 if (rtl818x_ioread32(priv, &priv->map->RX_CONF) & (1 << 6))
622 eeprom.width = PCI_EEPROM_WIDTH_93C66;
623 else
624 eeprom.width = PCI_EEPROM_WIDTH_93C46;
625
626 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
627 udelay(10);
628
629 eeprom_93cx6_multiread(&eeprom, RTL8187_EEPROM_MAC_ADDR,
630 (__le16 __force *)dev->wiphy->perm_addr, 3);
631 if (!is_valid_ether_addr(dev->wiphy->perm_addr)) {
632 printk(KERN_WARNING "rtl8187: Invalid hwaddr! Using randomly "
633 "generated MAC address\n");
634 random_ether_addr(dev->wiphy->perm_addr);
635 }
636
637 channel = priv->channels;
638 for (i = 0; i < 3; i++) {
639 eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_CHAN_1 + i,
640 &txpwr);
641 (*channel++).val = txpwr & 0xFF;
642 (*channel++).val = txpwr >> 8;
643 }
644 for (i = 0; i < 2; i++) {
645 eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_CHAN_4 + i,
646 &txpwr);
647 (*channel++).val = txpwr & 0xFF;
648 (*channel++).val = txpwr >> 8;
649 }
650 for (i = 0; i < 2; i++) {
651 eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_CHAN_6 + i,
652 &txpwr);
653 (*channel++).val = txpwr & 0xFF;
654 (*channel++).val = txpwr >> 8;
655 }
656
657 eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_BASE,
658 &priv->txpwr_base);
659
660 reg = rtl818x_ioread16(priv, &priv->map->PGSELECT) & ~1;
661 rtl818x_iowrite16(priv, &priv->map->PGSELECT, reg | 1);
662 /* 0 means asic B-cut, we should use SW 3 wire
663 * bit-by-bit banging for radio. 1 means we can use
664 * USB specific request to write radio registers */
665 priv->asic_rev = rtl818x_ioread8(priv, (u8 *)0xFFFE) & 0x3;
666 rtl818x_iowrite16(priv, &priv->map->PGSELECT, reg);
667 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
668
669 rtl8225_write(dev, 0, 0x1B7);
670
671 if (rtl8225_read(dev, 8) != 0x588 || rtl8225_read(dev, 9) != 0x700)
672 priv->rf_init = rtl8225_rf_init;
673 else
674 priv->rf_init = rtl8225z2_rf_init;
675
676 rtl8225_write(dev, 0, 0x0B7);
677
678 err = ieee80211_register_hw(dev);
679 if (err) {
680 printk(KERN_ERR "rtl8187: Cannot register device\n");
681 goto err_free_dev;
682 }
683
684 printk(KERN_INFO "%s: hwaddr " MAC_FMT ", rtl8187 V%d + %s\n",
685 wiphy_name(dev->wiphy), MAC_ARG(dev->wiphy->perm_addr),
686 priv->asic_rev, priv->rf_init == rtl8225_rf_init ?
687 "rtl8225" : "rtl8225z2");
688
689 return 0;
690
691 err_free_dev:
692 ieee80211_free_hw(dev);
693 usb_set_intfdata(intf, NULL);
694 usb_put_dev(udev);
695 return err;
696}
697
698static void __devexit rtl8187_disconnect(struct usb_interface *intf)
699{
700 struct ieee80211_hw *dev = usb_get_intfdata(intf);
701 struct rtl8187_priv *priv;
702
703 if (!dev)
704 return;
705
706 ieee80211_unregister_hw(dev);
707
708 priv = dev->priv;
709 usb_put_dev(interface_to_usbdev(intf));
710 ieee80211_free_hw(dev);
711}
712
713static struct usb_driver rtl8187_driver = {
714 .name = KBUILD_MODNAME,
715 .id_table = rtl8187_table,
716 .probe = rtl8187_probe,
717 .disconnect = rtl8187_disconnect,
718};
719
720static int __init rtl8187_init(void)
721{
722 return usb_register(&rtl8187_driver);
723}
724
725static void __exit rtl8187_exit(void)
726{
727 usb_deregister(&rtl8187_driver);
728}
729
730module_init(rtl8187_init);
731module_exit(rtl8187_exit);
diff --git a/drivers/net/wireless/rtl8187_rtl8225.c b/drivers/net/wireless/rtl8187_rtl8225.c
new file mode 100644
index 000000000000..e25a09f1b068
--- /dev/null
+++ b/drivers/net/wireless/rtl8187_rtl8225.c
@@ -0,0 +1,745 @@
1/*
2 * Radio tuning for RTL8225 on RTL8187
3 *
4 * Copyright 2007 Michael Wu <flamingice@sourmilk.net>
5 * Copyright 2007 Andrea Merello <andreamrl@tiscali.it>
6 *
7 * Based on the r8187 driver, which is:
8 * Copyright 2005 Andrea Merello <andreamrl@tiscali.it>, et al.
9 *
10 * Magic delays, register offsets, and phy value tables below are
11 * taken from the original r8187 driver sources. Thanks to Realtek
12 * for their support!
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License version 2 as
16 * published by the Free Software Foundation.
17 */
18
19#include <linux/init.h>
20#include <linux/usb.h>
21#include <net/mac80211.h>
22
23#include "rtl8187.h"
24#include "rtl8187_rtl8225.h"
25
26static void rtl8225_write_bitbang(struct ieee80211_hw *dev, u8 addr, u16 data)
27{
28 struct rtl8187_priv *priv = dev->priv;
29 u16 reg80, reg84, reg82;
30 u32 bangdata;
31 int i;
32
33 bangdata = (data << 4) | (addr & 0xf);
34
35 reg80 = rtl818x_ioread16(priv, &priv->map->RFPinsOutput) & 0xfff3;
36 reg82 = rtl818x_ioread16(priv, &priv->map->RFPinsEnable);
37
38 rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82 | 0x7);
39
40 reg84 = rtl818x_ioread16(priv, &priv->map->RFPinsSelect);
41 rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84 | 0x7);
42 udelay(10);
43
44 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
45 udelay(2);
46 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80);
47 udelay(10);
48
49 for (i = 15; i >= 0; i--) {
50 u16 reg = reg80 | (bangdata & (1 << i)) >> i;
51
52 if (i & 1)
53 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg);
54
55 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg | (1 << 1));
56 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg | (1 << 1));
57
58 if (!(i & 1))
59 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg);
60 }
61
62 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
63 udelay(10);
64
65 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
66 rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84);
67 msleep(2);
68}
69
70static void rtl8225_write_8051(struct ieee80211_hw *dev, u8 addr, u16 data)
71{
72 struct rtl8187_priv *priv = dev->priv;
73 u16 reg80, reg82, reg84;
74
75 reg80 = rtl818x_ioread16(priv, &priv->map->RFPinsOutput);
76 reg82 = rtl818x_ioread16(priv, &priv->map->RFPinsEnable);
77 reg84 = rtl818x_ioread16(priv, &priv->map->RFPinsSelect);
78
79 reg80 &= ~(0x3 << 2);
80 reg84 &= ~0xF;
81
82 rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82 | 0x0007);
83 rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84 | 0x0007);
84 udelay(10);
85
86 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
87 udelay(2);
88
89 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80);
90 udelay(10);
91
92 usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0),
93 RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE,
94 addr, 0x8225, &data, sizeof(data), HZ / 2);
95
96 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
97 udelay(10);
98
99 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
100 rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84);
101 msleep(2);
102}
103
104void rtl8225_write(struct ieee80211_hw *dev, u8 addr, u16 data)
105{
106 struct rtl8187_priv *priv = dev->priv;
107
108 if (priv->asic_rev)
109 rtl8225_write_8051(dev, addr, data);
110 else
111 rtl8225_write_bitbang(dev, addr, data);
112}
113
114u16 rtl8225_read(struct ieee80211_hw *dev, u8 addr)
115{
116 struct rtl8187_priv *priv = dev->priv;
117 u16 reg80, reg82, reg84, out;
118 int i;
119
120 reg80 = rtl818x_ioread16(priv, &priv->map->RFPinsOutput);
121 reg82 = rtl818x_ioread16(priv, &priv->map->RFPinsEnable);
122 reg84 = rtl818x_ioread16(priv, &priv->map->RFPinsSelect);
123
124 reg80 &= ~0xF;
125
126 rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82 | 0x000F);
127 rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84 | 0x000F);
128
129 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
130 udelay(4);
131 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80);
132 udelay(5);
133
134 for (i = 4; i >= 0; i--) {
135 u16 reg = reg80 | ((addr >> i) & 1);
136
137 if (!(i & 1)) {
138 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg);
139 udelay(1);
140 }
141
142 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
143 reg | (1 << 1));
144 udelay(2);
145 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
146 reg | (1 << 1));
147 udelay(2);
148
149 if (i & 1) {
150 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg);
151 udelay(1);
152 }
153 }
154
155 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
156 reg80 | (1 << 3) | (1 << 1));
157 udelay(2);
158 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
159 reg80 | (1 << 3));
160 udelay(2);
161 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
162 reg80 | (1 << 3));
163 udelay(2);
164
165 out = 0;
166 for (i = 11; i >= 0; i--) {
167 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
168 reg80 | (1 << 3));
169 udelay(1);
170 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
171 reg80 | (1 << 3) | (1 << 1));
172 udelay(2);
173 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
174 reg80 | (1 << 3) | (1 << 1));
175 udelay(2);
176 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
177 reg80 | (1 << 3) | (1 << 1));
178 udelay(2);
179
180 if (rtl818x_ioread16(priv, &priv->map->RFPinsInput) & (1 << 1))
181 out |= 1 << i;
182
183 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
184 reg80 | (1 << 3));
185 udelay(2);
186 }
187
188 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
189 reg80 | (1 << 3) | (1 << 2));
190 udelay(2);
191
192 rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82);
193 rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84);
194 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x03A0);
195
196 return out;
197}
198
199static const u16 rtl8225bcd_rxgain[] = {
200 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
201 0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
202 0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
203 0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
204 0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
205 0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
206 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
207 0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
208 0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d,
209 0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9,
210 0x07aa, 0x07ab, 0x07ac, 0x07ad, 0x07b0, 0x07b1, 0x07b2, 0x07b3,
211 0x07b4, 0x07b5, 0x07b8, 0x07b9, 0x07ba, 0x07bb, 0x07bb
212};
213
214static const u8 rtl8225_agc[] = {
215 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e,
216 0x9d, 0x9c, 0x9b, 0x9a, 0x99, 0x98, 0x97, 0x96,
217 0x95, 0x94, 0x93, 0x92, 0x91, 0x90, 0x8f, 0x8e,
218 0x8d, 0x8c, 0x8b, 0x8a, 0x89, 0x88, 0x87, 0x86,
219 0x85, 0x84, 0x83, 0x82, 0x81, 0x80, 0x3f, 0x3e,
220 0x3d, 0x3c, 0x3b, 0x3a, 0x39, 0x38, 0x37, 0x36,
221 0x35, 0x34, 0x33, 0x32, 0x31, 0x30, 0x2f, 0x2e,
222 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26,
223 0x25, 0x24, 0x23, 0x22, 0x21, 0x20, 0x1f, 0x1e,
224 0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18, 0x17, 0x16,
225 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x0e,
226 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06,
227 0x05, 0x04, 0x03, 0x02, 0x01, 0x01, 0x01, 0x01,
228 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
229 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
230 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01
231};
232
233static const u8 rtl8225_gain[] = {
234 0x23, 0x88, 0x7c, 0xa5, /* -82dBm */
235 0x23, 0x88, 0x7c, 0xb5, /* -82dBm */
236 0x23, 0x88, 0x7c, 0xc5, /* -82dBm */
237 0x33, 0x80, 0x79, 0xc5, /* -78dBm */
238 0x43, 0x78, 0x76, 0xc5, /* -74dBm */
239 0x53, 0x60, 0x73, 0xc5, /* -70dBm */
240 0x63, 0x58, 0x70, 0xc5, /* -66dBm */
241};
242
243static const u8 rtl8225_threshold[] = {
244 0x8d, 0x8d, 0x8d, 0x8d, 0x9d, 0xad, 0xbd
245};
246
247static const u8 rtl8225_tx_gain_cck_ofdm[] = {
248 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0x7e
249};
250
251static const u8 rtl8225_tx_power_cck[] = {
252 0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02,
253 0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02,
254 0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02,
255 0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02,
256 0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03,
257 0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03
258};
259
260static const u8 rtl8225_tx_power_cck_ch14[] = {
261 0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00,
262 0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00,
263 0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00,
264 0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00,
265 0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00,
266 0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00
267};
268
269static const u8 rtl8225_tx_power_ofdm[] = {
270 0x80, 0x90, 0xa2, 0xb5, 0xcb, 0xe4
271};
272
273static const u32 rtl8225_chan[] = {
274 0x085c, 0x08dc, 0x095c, 0x09dc, 0x0a5c, 0x0adc, 0x0b5c,
275 0x0bdc, 0x0c5c, 0x0cdc, 0x0d5c, 0x0ddc, 0x0e5c, 0x0f72
276};
277
278static void rtl8225_rf_set_tx_power(struct ieee80211_hw *dev, int channel)
279{
280 struct rtl8187_priv *priv = dev->priv;
281 u8 cck_power, ofdm_power;
282 const u8 *tmp;
283 u32 reg;
284 int i;
285
286 cck_power = priv->channels[channel - 1].val & 0xF;
287 ofdm_power = priv->channels[channel - 1].val >> 4;
288
289 cck_power = min(cck_power, (u8)11);
290 ofdm_power = min(ofdm_power, (u8)35);
291
292 rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK,
293 rtl8225_tx_gain_cck_ofdm[cck_power / 6] >> 1);
294
295 if (channel == 14)
296 tmp = &rtl8225_tx_power_cck_ch14[(cck_power % 6) * 8];
297 else
298 tmp = &rtl8225_tx_power_cck[(cck_power % 6) * 8];
299
300 for (i = 0; i < 8; i++)
301 rtl8225_write_phy_cck(dev, 0x44 + i, *tmp++);
302
303 msleep(1); // FIXME: optional?
304
305 /* anaparam2 on */
306 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
307 reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
308 rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | RTL818X_CONFIG3_ANAPARAM_WRITE);
309 rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, RTL8225_ANAPARAM2_ON);
310 rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE);
311 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
312
313 rtl8225_write_phy_ofdm(dev, 2, 0x42);
314 rtl8225_write_phy_ofdm(dev, 6, 0x00);
315 rtl8225_write_phy_ofdm(dev, 8, 0x00);
316
317 rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM,
318 rtl8225_tx_gain_cck_ofdm[ofdm_power / 6] >> 1);
319
320 tmp = &rtl8225_tx_power_ofdm[ofdm_power % 6];
321
322 rtl8225_write_phy_ofdm(dev, 5, *tmp);
323 rtl8225_write_phy_ofdm(dev, 7, *tmp);
324
325 msleep(1);
326}
327
328void rtl8225_rf_init(struct ieee80211_hw *dev)
329{
330 struct rtl8187_priv *priv = dev->priv;
331 int i;
332
333 rtl8225_write(dev, 0x0, 0x067); msleep(1);
334 rtl8225_write(dev, 0x1, 0xFE0); msleep(1);
335 rtl8225_write(dev, 0x2, 0x44D); msleep(1);
336 rtl8225_write(dev, 0x3, 0x441); msleep(1);
337 rtl8225_write(dev, 0x4, 0x486); msleep(1);
338 rtl8225_write(dev, 0x5, 0xBC0); msleep(1);
339 rtl8225_write(dev, 0x6, 0xAE6); msleep(1);
340 rtl8225_write(dev, 0x7, 0x82A); msleep(1);
341 rtl8225_write(dev, 0x8, 0x01F); msleep(1);
342 rtl8225_write(dev, 0x9, 0x334); msleep(1);
343 rtl8225_write(dev, 0xA, 0xFD4); msleep(1);
344 rtl8225_write(dev, 0xB, 0x391); msleep(1);
345 rtl8225_write(dev, 0xC, 0x050); msleep(1);
346 rtl8225_write(dev, 0xD, 0x6DB); msleep(1);
347 rtl8225_write(dev, 0xE, 0x029); msleep(1);
348 rtl8225_write(dev, 0xF, 0x914); msleep(100);
349
350 rtl8225_write(dev, 0x2, 0xC4D); msleep(200);
351 rtl8225_write(dev, 0x2, 0x44D); msleep(200);
352
353 if (!(rtl8225_read(dev, 6) & (1 << 7))) {
354 rtl8225_write(dev, 0x02, 0x0c4d);
355 msleep(200);
356 rtl8225_write(dev, 0x02, 0x044d);
357 msleep(100);
358 if (!(rtl8225_read(dev, 6) & (1 << 7)))
359 printk(KERN_WARNING "%s: RF Calibration Failed! %x\n",
360 wiphy_name(dev->wiphy), rtl8225_read(dev, 6));
361 }
362
363 rtl8225_write(dev, 0x0, 0x127);
364
365 for (i = 0; i < ARRAY_SIZE(rtl8225bcd_rxgain); i++) {
366 rtl8225_write(dev, 0x1, i + 1);
367 rtl8225_write(dev, 0x2, rtl8225bcd_rxgain[i]);
368 }
369
370 rtl8225_write(dev, 0x0, 0x027);
371 rtl8225_write(dev, 0x0, 0x22F);
372
373 for (i = 0; i < ARRAY_SIZE(rtl8225_agc); i++) {
374 rtl8225_write_phy_ofdm(dev, 0xB, rtl8225_agc[i]);
375 msleep(1);
376 rtl8225_write_phy_ofdm(dev, 0xA, 0x80 + i);
377 msleep(1);
378 }
379
380 msleep(1);
381
382 rtl8225_write_phy_ofdm(dev, 0x00, 0x01); msleep(1);
383 rtl8225_write_phy_ofdm(dev, 0x01, 0x02); msleep(1);
384 rtl8225_write_phy_ofdm(dev, 0x02, 0x42); msleep(1);
385 rtl8225_write_phy_ofdm(dev, 0x03, 0x00); msleep(1);
386 rtl8225_write_phy_ofdm(dev, 0x04, 0x00); msleep(1);
387 rtl8225_write_phy_ofdm(dev, 0x05, 0x00); msleep(1);
388 rtl8225_write_phy_ofdm(dev, 0x06, 0x40); msleep(1);
389 rtl8225_write_phy_ofdm(dev, 0x07, 0x00); msleep(1);
390 rtl8225_write_phy_ofdm(dev, 0x08, 0x40); msleep(1);
391 rtl8225_write_phy_ofdm(dev, 0x09, 0xfe); msleep(1);
392 rtl8225_write_phy_ofdm(dev, 0x0a, 0x09); msleep(1);
393 rtl8225_write_phy_ofdm(dev, 0x0b, 0x80); msleep(1);
394 rtl8225_write_phy_ofdm(dev, 0x0c, 0x01); msleep(1);
395 rtl8225_write_phy_ofdm(dev, 0x0e, 0xd3); msleep(1);
396 rtl8225_write_phy_ofdm(dev, 0x0f, 0x38); msleep(1);
397 rtl8225_write_phy_ofdm(dev, 0x10, 0x84); msleep(1);
398 rtl8225_write_phy_ofdm(dev, 0x11, 0x06); msleep(1);
399 rtl8225_write_phy_ofdm(dev, 0x12, 0x20); msleep(1);
400 rtl8225_write_phy_ofdm(dev, 0x13, 0x20); msleep(1);
401 rtl8225_write_phy_ofdm(dev, 0x14, 0x00); msleep(1);
402 rtl8225_write_phy_ofdm(dev, 0x15, 0x40); msleep(1);
403 rtl8225_write_phy_ofdm(dev, 0x16, 0x00); msleep(1);
404 rtl8225_write_phy_ofdm(dev, 0x17, 0x40); msleep(1);
405 rtl8225_write_phy_ofdm(dev, 0x18, 0xef); msleep(1);
406 rtl8225_write_phy_ofdm(dev, 0x19, 0x19); msleep(1);
407 rtl8225_write_phy_ofdm(dev, 0x1a, 0x20); msleep(1);
408 rtl8225_write_phy_ofdm(dev, 0x1b, 0x76); msleep(1);
409 rtl8225_write_phy_ofdm(dev, 0x1c, 0x04); msleep(1);
410 rtl8225_write_phy_ofdm(dev, 0x1e, 0x95); msleep(1);
411 rtl8225_write_phy_ofdm(dev, 0x1f, 0x75); msleep(1);
412 rtl8225_write_phy_ofdm(dev, 0x20, 0x1f); msleep(1);
413 rtl8225_write_phy_ofdm(dev, 0x21, 0x27); msleep(1);
414 rtl8225_write_phy_ofdm(dev, 0x22, 0x16); msleep(1);
415 rtl8225_write_phy_ofdm(dev, 0x24, 0x46); msleep(1);
416 rtl8225_write_phy_ofdm(dev, 0x25, 0x20); msleep(1);
417 rtl8225_write_phy_ofdm(dev, 0x26, 0x90); msleep(1);
418 rtl8225_write_phy_ofdm(dev, 0x27, 0x88); msleep(1);
419
420 rtl8225_write_phy_ofdm(dev, 0x0d, rtl8225_gain[2 * 4]);
421 rtl8225_write_phy_ofdm(dev, 0x1b, rtl8225_gain[2 * 4 + 2]);
422 rtl8225_write_phy_ofdm(dev, 0x1d, rtl8225_gain[2 * 4 + 3]);
423 rtl8225_write_phy_ofdm(dev, 0x23, rtl8225_gain[2 * 4 + 1]);
424
425 rtl8225_write_phy_cck(dev, 0x00, 0x98); msleep(1);
426 rtl8225_write_phy_cck(dev, 0x03, 0x20); msleep(1);
427 rtl8225_write_phy_cck(dev, 0x04, 0x7e); msleep(1);
428 rtl8225_write_phy_cck(dev, 0x05, 0x12); msleep(1);
429 rtl8225_write_phy_cck(dev, 0x06, 0xfc); msleep(1);
430 rtl8225_write_phy_cck(dev, 0x07, 0x78); msleep(1);
431 rtl8225_write_phy_cck(dev, 0x08, 0x2e); msleep(1);
432 rtl8225_write_phy_cck(dev, 0x10, 0x9b); msleep(1);
433 rtl8225_write_phy_cck(dev, 0x11, 0x88); msleep(1);
434 rtl8225_write_phy_cck(dev, 0x12, 0x47); msleep(1);
435 rtl8225_write_phy_cck(dev, 0x13, 0xd0);
436 rtl8225_write_phy_cck(dev, 0x19, 0x00);
437 rtl8225_write_phy_cck(dev, 0x1a, 0xa0);
438 rtl8225_write_phy_cck(dev, 0x1b, 0x08);
439 rtl8225_write_phy_cck(dev, 0x40, 0x86);
440 rtl8225_write_phy_cck(dev, 0x41, 0x8d); msleep(1);
441 rtl8225_write_phy_cck(dev, 0x42, 0x15); msleep(1);
442 rtl8225_write_phy_cck(dev, 0x43, 0x18); msleep(1);
443 rtl8225_write_phy_cck(dev, 0x44, 0x1f); msleep(1);
444 rtl8225_write_phy_cck(dev, 0x45, 0x1e); msleep(1);
445 rtl8225_write_phy_cck(dev, 0x46, 0x1a); msleep(1);
446 rtl8225_write_phy_cck(dev, 0x47, 0x15); msleep(1);
447 rtl8225_write_phy_cck(dev, 0x48, 0x10); msleep(1);
448 rtl8225_write_phy_cck(dev, 0x49, 0x0a); msleep(1);
449 rtl8225_write_phy_cck(dev, 0x4a, 0x05); msleep(1);
450 rtl8225_write_phy_cck(dev, 0x4b, 0x02); msleep(1);
451 rtl8225_write_phy_cck(dev, 0x4c, 0x05); msleep(1);
452
453 rtl818x_iowrite8(priv, &priv->map->TESTR, 0x0D);
454
455 rtl8225_rf_set_tx_power(dev, 1);
456
457 /* RX antenna default to A */
458 rtl8225_write_phy_cck(dev, 0x10, 0x9b); msleep(1); /* B: 0xDB */
459 rtl8225_write_phy_ofdm(dev, 0x26, 0x90); msleep(1); /* B: 0x10 */
460
461 rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03); /* B: 0x00 */
462 msleep(1);
463 rtl818x_iowrite32(priv, (__le32 *)0xFF94, 0x3dc00002);
464
465 /* set sensitivity */
466 rtl8225_write(dev, 0x0c, 0x50);
467 rtl8225_write_phy_ofdm(dev, 0x0d, rtl8225_gain[2 * 4]);
468 rtl8225_write_phy_ofdm(dev, 0x1b, rtl8225_gain[2 * 4 + 2]);
469 rtl8225_write_phy_ofdm(dev, 0x1d, rtl8225_gain[2 * 4 + 3]);
470 rtl8225_write_phy_ofdm(dev, 0x23, rtl8225_gain[2 * 4 + 1]);
471 rtl8225_write_phy_cck(dev, 0x41, rtl8225_threshold[2]);
472}
473
474static const u8 rtl8225z2_tx_power_cck_ch14[] = {
475 0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00
476};
477
478static const u8 rtl8225z2_tx_power_cck[] = {
479 0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04
480};
481
482static const u8 rtl8225z2_tx_power_ofdm[] = {
483 0x42, 0x00, 0x40, 0x00, 0x40
484};
485
486static const u8 rtl8225z2_tx_gain_cck_ofdm[] = {
487 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
488 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
489 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11,
490 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
491 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
492 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23
493};
494
495static void rtl8225z2_rf_set_tx_power(struct ieee80211_hw *dev, int channel)
496{
497 struct rtl8187_priv *priv = dev->priv;
498 u8 cck_power, ofdm_power;
499 const u8 *tmp;
500 u32 reg;
501 int i;
502
503 cck_power = priv->channels[channel - 1].val & 0xF;
504 ofdm_power = priv->channels[channel - 1].val >> 4;
505
506 cck_power = min(cck_power, (u8)15);
507 cck_power += priv->txpwr_base & 0xF;
508 cck_power = min(cck_power, (u8)35);
509
510 ofdm_power = min(ofdm_power, (u8)15);
511 ofdm_power += priv->txpwr_base >> 4;
512 ofdm_power = min(ofdm_power, (u8)35);
513
514 if (channel == 14)
515 tmp = rtl8225z2_tx_power_cck_ch14;
516 else
517 tmp = rtl8225z2_tx_power_cck;
518
519 for (i = 0; i < 8; i++)
520 rtl8225_write_phy_cck(dev, 0x44 + i, *tmp++);
521
522 rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK,
523 rtl8225z2_tx_gain_cck_ofdm[cck_power]);
524 msleep(1);
525
526 /* anaparam2 on */
527 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
528 reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
529 rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | RTL818X_CONFIG3_ANAPARAM_WRITE);
530 rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, RTL8225_ANAPARAM2_ON);
531 rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE);
532 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
533
534 rtl8225_write_phy_ofdm(dev, 2, 0x42);
535 rtl8225_write_phy_ofdm(dev, 5, 0x00);
536 rtl8225_write_phy_ofdm(dev, 6, 0x40);
537 rtl8225_write_phy_ofdm(dev, 7, 0x00);
538 rtl8225_write_phy_ofdm(dev, 8, 0x40);
539
540 rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM,
541 rtl8225z2_tx_gain_cck_ofdm[ofdm_power]);
542 msleep(1);
543}
544
545static const u16 rtl8225z2_rxgain[] = {
546 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
547 0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
548 0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
549 0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
550 0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
551 0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
552 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
553 0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
554 0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d,
555 0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9,
556 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03b0, 0x03b1, 0x03b2, 0x03b3,
557 0x03b4, 0x03b5, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bb
558};
559
560static const u8 rtl8225z2_gain_bg[] = {
561 0x23, 0x15, 0xa5, /* -82-1dBm */
562 0x23, 0x15, 0xb5, /* -82-2dBm */
563 0x23, 0x15, 0xc5, /* -82-3dBm */
564 0x33, 0x15, 0xc5, /* -78dBm */
565 0x43, 0x15, 0xc5, /* -74dBm */
566 0x53, 0x15, 0xc5, /* -70dBm */
567 0x63, 0x15, 0xc5 /* -66dBm */
568};
569
570void rtl8225z2_rf_init(struct ieee80211_hw *dev)
571{
572 struct rtl8187_priv *priv = dev->priv;
573 int i;
574
575 rtl8225_write(dev, 0x0, 0x2BF); msleep(1);
576 rtl8225_write(dev, 0x1, 0xEE0); msleep(1);
577 rtl8225_write(dev, 0x2, 0x44D); msleep(1);
578 rtl8225_write(dev, 0x3, 0x441); msleep(1);
579 rtl8225_write(dev, 0x4, 0x8C3); msleep(1);
580 rtl8225_write(dev, 0x5, 0xC72); msleep(1);
581 rtl8225_write(dev, 0x6, 0x0E6); msleep(1);
582 rtl8225_write(dev, 0x7, 0x82A); msleep(1);
583 rtl8225_write(dev, 0x8, 0x03F); msleep(1);
584 rtl8225_write(dev, 0x9, 0x335); msleep(1);
585 rtl8225_write(dev, 0xa, 0x9D4); msleep(1);
586 rtl8225_write(dev, 0xb, 0x7BB); msleep(1);
587 rtl8225_write(dev, 0xc, 0x850); msleep(1);
588 rtl8225_write(dev, 0xd, 0xCDF); msleep(1);
589 rtl8225_write(dev, 0xe, 0x02B); msleep(1);
590 rtl8225_write(dev, 0xf, 0x114); msleep(100);
591
592 rtl8225_write(dev, 0x0, 0x1B7);
593
594 for (i = 0; i < ARRAY_SIZE(rtl8225z2_rxgain); i++) {
595 rtl8225_write(dev, 0x1, i + 1);
596 rtl8225_write(dev, 0x2, rtl8225z2_rxgain[i]);
597 }
598
599 rtl8225_write(dev, 0x3, 0x080);
600 rtl8225_write(dev, 0x5, 0x004);
601 rtl8225_write(dev, 0x0, 0x0B7);
602 rtl8225_write(dev, 0x2, 0xc4D);
603
604 msleep(200);
605 rtl8225_write(dev, 0x2, 0x44D);
606 msleep(100);
607
608 if (!(rtl8225_read(dev, 6) & (1 << 7))) {
609 rtl8225_write(dev, 0x02, 0x0C4D);
610 msleep(200);
611 rtl8225_write(dev, 0x02, 0x044D);
612 msleep(100);
613 if (!(rtl8225_read(dev, 6) & (1 << 7)))
614 printk(KERN_WARNING "%s: RF Calibration Failed! %x\n",
615 wiphy_name(dev->wiphy), rtl8225_read(dev, 6));
616 }
617
618 msleep(200);
619
620 rtl8225_write(dev, 0x0, 0x2BF);
621
622 for (i = 0; i < ARRAY_SIZE(rtl8225_agc); i++) {
623 rtl8225_write_phy_ofdm(dev, 0xB, rtl8225_agc[i]);
624 msleep(1);
625 rtl8225_write_phy_ofdm(dev, 0xA, 0x80 + i);
626 msleep(1);
627 }
628
629 msleep(1);
630
631 rtl8225_write_phy_ofdm(dev, 0x00, 0x01); msleep(1);
632 rtl8225_write_phy_ofdm(dev, 0x01, 0x02); msleep(1);
633 rtl8225_write_phy_ofdm(dev, 0x02, 0x42); msleep(1);
634 rtl8225_write_phy_ofdm(dev, 0x03, 0x00); msleep(1);
635 rtl8225_write_phy_ofdm(dev, 0x04, 0x00); msleep(1);
636 rtl8225_write_phy_ofdm(dev, 0x05, 0x00); msleep(1);
637 rtl8225_write_phy_ofdm(dev, 0x06, 0x40); msleep(1);
638 rtl8225_write_phy_ofdm(dev, 0x07, 0x00); msleep(1);
639 rtl8225_write_phy_ofdm(dev, 0x08, 0x40); msleep(1);
640 rtl8225_write_phy_ofdm(dev, 0x09, 0xfe); msleep(1);
641 rtl8225_write_phy_ofdm(dev, 0x0a, 0x08); msleep(1);
642 rtl8225_write_phy_ofdm(dev, 0x0b, 0x80); msleep(1);
643 rtl8225_write_phy_ofdm(dev, 0x0c, 0x01); msleep(1);
644 rtl8225_write_phy_ofdm(dev, 0x0d, 0x43);
645 rtl8225_write_phy_ofdm(dev, 0x0e, 0xd3); msleep(1);
646 rtl8225_write_phy_ofdm(dev, 0x0f, 0x38); msleep(1);
647 rtl8225_write_phy_ofdm(dev, 0x10, 0x84); msleep(1);
648 rtl8225_write_phy_ofdm(dev, 0x11, 0x07); msleep(1);
649 rtl8225_write_phy_ofdm(dev, 0x12, 0x20); msleep(1);
650 rtl8225_write_phy_ofdm(dev, 0x13, 0x20); msleep(1);
651 rtl8225_write_phy_ofdm(dev, 0x14, 0x00); msleep(1);
652 rtl8225_write_phy_ofdm(dev, 0x15, 0x40); msleep(1);
653 rtl8225_write_phy_ofdm(dev, 0x16, 0x00); msleep(1);
654 rtl8225_write_phy_ofdm(dev, 0x17, 0x40); msleep(1);
655 rtl8225_write_phy_ofdm(dev, 0x18, 0xef); msleep(1);
656 rtl8225_write_phy_ofdm(dev, 0x19, 0x19); msleep(1);
657 rtl8225_write_phy_ofdm(dev, 0x1a, 0x20); msleep(1);
658 rtl8225_write_phy_ofdm(dev, 0x1b, 0x15); msleep(1);
659 rtl8225_write_phy_ofdm(dev, 0x1c, 0x04); msleep(1);
660 rtl8225_write_phy_ofdm(dev, 0x1d, 0xc5); msleep(1);
661 rtl8225_write_phy_ofdm(dev, 0x1e, 0x95); msleep(1);
662 rtl8225_write_phy_ofdm(dev, 0x1f, 0x75); msleep(1);
663 rtl8225_write_phy_ofdm(dev, 0x20, 0x1f); msleep(1);
664 rtl8225_write_phy_ofdm(dev, 0x21, 0x17); msleep(1);
665 rtl8225_write_phy_ofdm(dev, 0x22, 0x16); msleep(1);
666 rtl8225_write_phy_ofdm(dev, 0x23, 0x80); msleep(1); //FIXME: not needed?
667 rtl8225_write_phy_ofdm(dev, 0x24, 0x46); msleep(1);
668 rtl8225_write_phy_ofdm(dev, 0x25, 0x00); msleep(1);
669 rtl8225_write_phy_ofdm(dev, 0x26, 0x90); msleep(1);
670 rtl8225_write_phy_ofdm(dev, 0x27, 0x88); msleep(1);
671
672 rtl8225_write_phy_ofdm(dev, 0x0b, rtl8225z2_gain_bg[4 * 3]);
673 rtl8225_write_phy_ofdm(dev, 0x1b, rtl8225z2_gain_bg[4 * 3 + 1]);
674 rtl8225_write_phy_ofdm(dev, 0x1d, rtl8225z2_gain_bg[4 * 3 + 2]);
675 rtl8225_write_phy_ofdm(dev, 0x21, 0x37);
676
677 rtl8225_write_phy_cck(dev, 0x00, 0x98); msleep(1);
678 rtl8225_write_phy_cck(dev, 0x03, 0x20); msleep(1);
679 rtl8225_write_phy_cck(dev, 0x04, 0x7e); msleep(1);
680 rtl8225_write_phy_cck(dev, 0x05, 0x12); msleep(1);
681 rtl8225_write_phy_cck(dev, 0x06, 0xfc); msleep(1);
682 rtl8225_write_phy_cck(dev, 0x07, 0x78); msleep(1);
683 rtl8225_write_phy_cck(dev, 0x08, 0x2e); msleep(1);
684 rtl8225_write_phy_cck(dev, 0x10, 0x9b); msleep(1);
685 rtl8225_write_phy_cck(dev, 0x11, 0x88); msleep(1);
686 rtl8225_write_phy_cck(dev, 0x12, 0x47); msleep(1);
687 rtl8225_write_phy_cck(dev, 0x13, 0xd0);
688 rtl8225_write_phy_cck(dev, 0x19, 0x00);
689 rtl8225_write_phy_cck(dev, 0x1a, 0xa0);
690 rtl8225_write_phy_cck(dev, 0x1b, 0x08);
691 rtl8225_write_phy_cck(dev, 0x40, 0x86);
692 rtl8225_write_phy_cck(dev, 0x41, 0x8d); msleep(1);
693 rtl8225_write_phy_cck(dev, 0x42, 0x15); msleep(1);
694 rtl8225_write_phy_cck(dev, 0x43, 0x18); msleep(1);
695 rtl8225_write_phy_cck(dev, 0x44, 0x36); msleep(1);
696 rtl8225_write_phy_cck(dev, 0x45, 0x35); msleep(1);
697 rtl8225_write_phy_cck(dev, 0x46, 0x2e); msleep(1);
698 rtl8225_write_phy_cck(dev, 0x47, 0x25); msleep(1);
699 rtl8225_write_phy_cck(dev, 0x48, 0x1c); msleep(1);
700 rtl8225_write_phy_cck(dev, 0x49, 0x12); msleep(1);
701 rtl8225_write_phy_cck(dev, 0x4a, 0x09); msleep(1);
702 rtl8225_write_phy_cck(dev, 0x4b, 0x04); msleep(1);
703 rtl8225_write_phy_cck(dev, 0x4c, 0x05); msleep(1);
704
705 rtl818x_iowrite8(priv, (u8 *)0xFF5B, 0x0D); msleep(1);
706
707 rtl8225z2_rf_set_tx_power(dev, 1);
708
709 /* RX antenna default to A */
710 rtl8225_write_phy_cck(dev, 0x10, 0x9b); msleep(1); /* B: 0xDB */
711 rtl8225_write_phy_ofdm(dev, 0x26, 0x90); msleep(1); /* B: 0x10 */
712
713 rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03); /* B: 0x00 */
714 msleep(1);
715 rtl818x_iowrite32(priv, (__le32 *)0xFF94, 0x3dc00002);
716}
717
718void rtl8225_rf_stop(struct ieee80211_hw *dev)
719{
720 u8 reg;
721 struct rtl8187_priv *priv = dev->priv;
722
723 rtl8225_write(dev, 0x4, 0x1f); msleep(1);
724
725 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
726 reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
727 rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | RTL818X_CONFIG3_ANAPARAM_WRITE);
728 rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, RTL8225_ANAPARAM2_OFF);
729 rtl818x_iowrite32(priv, &priv->map->ANAPARAM, RTL8225_ANAPARAM_OFF);
730 rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE);
731 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
732}
733
734void rtl8225_rf_set_channel(struct ieee80211_hw *dev, int channel)
735{
736 struct rtl8187_priv *priv = dev->priv;
737
738 if (priv->rf_init == rtl8225_rf_init)
739 rtl8225_rf_set_tx_power(dev, channel);
740 else
741 rtl8225z2_rf_set_tx_power(dev, channel);
742
743 rtl8225_write(dev, 0x7, rtl8225_chan[channel - 1]);
744 msleep(10);
745}
diff --git a/drivers/net/wireless/rtl8187_rtl8225.h b/drivers/net/wireless/rtl8187_rtl8225.h
new file mode 100644
index 000000000000..798ba4a97376
--- /dev/null
+++ b/drivers/net/wireless/rtl8187_rtl8225.h
@@ -0,0 +1,44 @@
1/*
2 * Radio tuning definitions for RTL8225 on RTL8187
3 *
4 * Copyright 2007 Michael Wu <flamingice@sourmilk.net>
5 * Copyright 2007 Andrea Merello <andreamrl@tiscali.it>
6 *
7 * Based on the r8187 driver, which is:
8 * Copyright 2005 Andrea Merello <andreamrl@tiscali.it>, et al.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#ifndef RTL8187_RTL8225_H
16#define RTL8187_RTL8225_H
17
18#define RTL8225_ANAPARAM_ON 0xa0000a59
19#define RTL8225_ANAPARAM2_ON 0x860c7312
20#define RTL8225_ANAPARAM_OFF 0xa00beb59
21#define RTL8225_ANAPARAM2_OFF 0x840dec11
22
23void rtl8225_write(struct ieee80211_hw *, u8 addr, u16 data);
24u16 rtl8225_read(struct ieee80211_hw *, u8 addr);
25
26void rtl8225_rf_init(struct ieee80211_hw *);
27void rtl8225z2_rf_init(struct ieee80211_hw *);
28void rtl8225_rf_stop(struct ieee80211_hw *);
29void rtl8225_rf_set_channel(struct ieee80211_hw *, int);
30
31
32static inline void rtl8225_write_phy_ofdm(struct ieee80211_hw *dev,
33 u8 addr, u32 data)
34{
35 rtl8187_write_phy(dev, addr, data);
36}
37
38static inline void rtl8225_write_phy_cck(struct ieee80211_hw *dev,
39 u8 addr, u32 data)
40{
41 rtl8187_write_phy(dev, addr, data | 0x10000);
42}
43
44#endif /* RTL8187_RTL8225_H */
diff --git a/drivers/net/wireless/rtl818x.h b/drivers/net/wireless/rtl818x.h
new file mode 100644
index 000000000000..283de30628e1
--- /dev/null
+++ b/drivers/net/wireless/rtl818x.h
@@ -0,0 +1,226 @@
1/*
2 * Definitions for RTL818x hardware
3 *
4 * Copyright 2007 Michael Wu <flamingice@sourmilk.net>
5 * Copyright 2007 Andrea Merello <andreamrl@tiscali.it>
6 *
7 * Based on the r8187 driver, which is:
8 * Copyright 2005 Andrea Merello <andreamrl@tiscali.it>, et al.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#ifndef RTL818X_H
16#define RTL818X_H
17
18struct rtl818x_csr {
19 u8 MAC[6];
20 u8 reserved_0[2];
21 __le32 MAR[2];
22 u8 RX_FIFO_COUNT;
23 u8 reserved_1;
24 u8 TX_FIFO_COUNT;
25 u8 BQREQ;
26 u8 reserved_2[4];
27 __le32 TSFT[2];
28 __le32 TLPDA;
29 __le32 TNPDA;
30 __le32 THPDA;
31 __le16 BRSR;
32 u8 BSSID[6];
33 u8 RESP_RATE;
34 u8 EIFS;
35 u8 reserved_3[1];
36 u8 CMD;
37#define RTL818X_CMD_TX_ENABLE (1 << 2)
38#define RTL818X_CMD_RX_ENABLE (1 << 3)
39#define RTL818X_CMD_RESET (1 << 4)
40 u8 reserved_4[4];
41 __le16 INT_MASK;
42 __le16 INT_STATUS;
43#define RTL818X_INT_RX_OK (1 << 0)
44#define RTL818X_INT_RX_ERR (1 << 1)
45#define RTL818X_INT_TXL_OK (1 << 2)
46#define RTL818X_INT_TXL_ERR (1 << 3)
47#define RTL818X_INT_RX_DU (1 << 4)
48#define RTL818X_INT_RX_FO (1 << 5)
49#define RTL818X_INT_TXN_OK (1 << 6)
50#define RTL818X_INT_TXN_ERR (1 << 7)
51#define RTL818X_INT_TXH_OK (1 << 8)
52#define RTL818X_INT_TXH_ERR (1 << 9)
53#define RTL818X_INT_TXB_OK (1 << 10)
54#define RTL818X_INT_TXB_ERR (1 << 11)
55#define RTL818X_INT_ATIM (1 << 12)
56#define RTL818X_INT_BEACON (1 << 13)
57#define RTL818X_INT_TIME_OUT (1 << 14)
58#define RTL818X_INT_TX_FO (1 << 15)
59 __le32 TX_CONF;
60#define RTL818X_TX_CONF_LOOPBACK_MAC (1 << 17)
61#define RTL818X_TX_CONF_NO_ICV (1 << 19)
62#define RTL818X_TX_CONF_DISCW (1 << 20)
63#define RTL818X_TX_CONF_R8180_ABCD (2 << 25)
64#define RTL818X_TX_CONF_R8180_F (3 << 25)
65#define RTL818X_TX_CONF_R8185_ABC (4 << 25)
66#define RTL818X_TX_CONF_R8185_D (5 << 25)
67#define RTL818X_TX_CONF_HWVER_MASK (7 << 25)
68#define RTL818X_TX_CONF_CW_MIN (1 << 31)
69 __le32 RX_CONF;
70#define RTL818X_RX_CONF_MONITOR (1 << 0)
71#define RTL818X_RX_CONF_NICMAC (1 << 1)
72#define RTL818X_RX_CONF_MULTICAST (1 << 2)
73#define RTL818X_RX_CONF_BROADCAST (1 << 3)
74#define RTL818X_RX_CONF_DATA (1 << 18)
75#define RTL818X_RX_CONF_CTRL (1 << 19)
76#define RTL818X_RX_CONF_MGMT (1 << 20)
77#define RTL818X_RX_CONF_BSSID (1 << 23)
78#define RTL818X_RX_CONF_RX_AUTORESETPHY (1 << 28)
79#define RTL818X_RX_CONF_ONLYERLPKT (1 << 31)
80 __le32 INT_TIMEOUT;
81 __le32 TBDA;
82 u8 EEPROM_CMD;
83#define RTL818X_EEPROM_CMD_READ (1 << 0)
84#define RTL818X_EEPROM_CMD_WRITE (1 << 1)
85#define RTL818X_EEPROM_CMD_CK (1 << 2)
86#define RTL818X_EEPROM_CMD_CS (1 << 3)
87#define RTL818X_EEPROM_CMD_NORMAL (0 << 6)
88#define RTL818X_EEPROM_CMD_LOAD (1 << 6)
89#define RTL818X_EEPROM_CMD_PROGRAM (2 << 6)
90#define RTL818X_EEPROM_CMD_CONFIG (3 << 6)
91 u8 CONFIG0;
92 u8 CONFIG1;
93 u8 CONFIG2;
94 __le32 ANAPARAM;
95 u8 MSR;
96#define RTL818X_MSR_NO_LINK (0 << 2)
97#define RTL818X_MSR_ADHOC (1 << 2)
98#define RTL818X_MSR_INFRA (2 << 2)
99 u8 CONFIG3;
100#define RTL818X_CONFIG3_ANAPARAM_WRITE (1 << 6)
101 u8 CONFIG4;
102#define RTL818X_CONFIG4_POWEROFF (1 << 6)
103#define RTL818X_CONFIG4_VCOOFF (1 << 7)
104 u8 TESTR;
105 u8 reserved_9[2];
106 __le16 PGSELECT;
107 __le32 ANAPARAM2;
108 u8 reserved_10[12];
109 __le16 BEACON_INTERVAL;
110 __le16 ATIM_WND;
111 __le16 BEACON_INTERVAL_TIME;
112 __le16 ATIMTR_INTERVAL;
113 u8 reserved_11[4];
114 u8 PHY[4];
115 __le16 RFPinsOutput;
116 __le16 RFPinsEnable;
117 __le16 RFPinsSelect;
118 __le16 RFPinsInput;
119 __le32 RF_PARA;
120 __le32 RF_TIMING;
121 u8 GP_ENABLE;
122 u8 GPIO;
123 u8 reserved_12[10];
124 u8 TX_AGC_CTL;
125#define RTL818X_TX_AGC_CTL_PERPACKET_GAIN_SHIFT (1 << 0)
126#define RTL818X_TX_AGC_CTL_PERPACKET_ANTSEL_SHIFT (1 << 1)
127#define RTL818X_TX_AGC_CTL_FEEDBACK_ANT (1 << 2)
128 u8 TX_GAIN_CCK;
129 u8 TX_GAIN_OFDM;
130 u8 TX_ANTENNA;
131 u8 reserved_13[16];
132 u8 WPA_CONF;
133 u8 reserved_14[3];
134 u8 SIFS;
135 u8 DIFS;
136 u8 SLOT;
137 u8 reserved_15[5];
138 u8 CW_CONF;
139#define RTL818X_CW_CONF_PERPACKET_CW_SHIFT (1 << 0)
140#define RTL818X_CW_CONF_PERPACKET_RETRY_SHIFT (1 << 1)
141 u8 CW_VAL;
142 u8 RATE_FALLBACK;
143 u8 reserved_16[25];
144 u8 CONFIG5;
145 u8 TX_DMA_POLLING;
146 u8 reserved_17[2];
147 __le16 CWR;
148 u8 RETRY_CTR;
149 u8 reserved_18[5];
150 __le32 RDSAR;
151 u8 reserved_19[18];
152 u16 TALLY_CNT;
153 u8 TALLY_SEL;
154} __attribute__((packed));
155
156static const struct ieee80211_rate rtl818x_rates[] = {
157 { .rate = 10,
158 .val = 0,
159 .flags = IEEE80211_RATE_CCK },
160 { .rate = 20,
161 .val = 1,
162 .flags = IEEE80211_RATE_CCK },
163 { .rate = 55,
164 .val = 2,
165 .flags = IEEE80211_RATE_CCK },
166 { .rate = 110,
167 .val = 3,
168 .flags = IEEE80211_RATE_CCK },
169 { .rate = 60,
170 .val = 4,
171 .flags = IEEE80211_RATE_OFDM },
172 { .rate = 90,
173 .val = 5,
174 .flags = IEEE80211_RATE_OFDM },
175 { .rate = 120,
176 .val = 6,
177 .flags = IEEE80211_RATE_OFDM },
178 { .rate = 180,
179 .val = 7,
180 .flags = IEEE80211_RATE_OFDM },
181 { .rate = 240,
182 .val = 8,
183 .flags = IEEE80211_RATE_OFDM },
184 { .rate = 360,
185 .val = 9,
186 .flags = IEEE80211_RATE_OFDM },
187 { .rate = 480,
188 .val = 10,
189 .flags = IEEE80211_RATE_OFDM },
190 { .rate = 540,
191 .val = 11,
192 .flags = IEEE80211_RATE_OFDM },
193};
194
195static const struct ieee80211_channel rtl818x_channels[] = {
196 { .chan = 1,
197 .freq = 2412},
198 { .chan = 2,
199 .freq = 2417},
200 { .chan = 3,
201 .freq = 2422},
202 { .chan = 4,
203 .freq = 2427},
204 { .chan = 5,
205 .freq = 2432},
206 { .chan = 6,
207 .freq = 2437},
208 { .chan = 7,
209 .freq = 2442},
210 { .chan = 8,
211 .freq = 2447},
212 { .chan = 9,
213 .freq = 2452},
214 { .chan = 10,
215 .freq = 2457},
216 { .chan = 11,
217 .freq = 2462},
218 { .chan = 12,
219 .freq = 2467},
220 { .chan = 13,
221 .freq = 2472},
222 { .chan = 14,
223 .freq = 2484}
224};
225
226#endif /* RTL818X_H */
diff --git a/drivers/net/wireless/zd1211rw/Makefile b/drivers/net/wireless/zd1211rw/Makefile
index 6603ad5be63d..4d505903352c 100644
--- a/drivers/net/wireless/zd1211rw/Makefile
+++ b/drivers/net/wireless/zd1211rw/Makefile
@@ -3,7 +3,7 @@ obj-$(CONFIG_ZD1211RW) += zd1211rw.o
3zd1211rw-objs := zd_chip.o zd_ieee80211.o \ 3zd1211rw-objs := zd_chip.o zd_ieee80211.o \
4 zd_mac.o zd_netdev.o \ 4 zd_mac.o zd_netdev.o \
5 zd_rf_al2230.o zd_rf_rf2959.o \ 5 zd_rf_al2230.o zd_rf_rf2959.o \
6 zd_rf_al7230b.o \ 6 zd_rf_al7230b.o zd_rf_uw2453.o \
7 zd_rf.o zd_usb.o zd_util.o 7 zd_rf.o zd_usb.o zd_util.o
8 8
9ifeq ($(CONFIG_ZD1211RW_DEBUG),y) 9ifeq ($(CONFIG_ZD1211RW_DEBUG),y)
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.c b/drivers/net/wireless/zd1211rw/zd_chip.c
index 95b4a2a26707..5b624bfc01a6 100644
--- a/drivers/net/wireless/zd1211rw/zd_chip.c
+++ b/drivers/net/wireless/zd1211rw/zd_chip.c
@@ -1253,6 +1253,9 @@ static int update_channel_integration_and_calibration(struct zd_chip *chip,
1253{ 1253{
1254 int r; 1254 int r;
1255 1255
1256 if (!zd_rf_should_update_pwr_int(&chip->rf))
1257 return 0;
1258
1256 r = update_pwr_int(chip, channel); 1259 r = update_pwr_int(chip, channel);
1257 if (r) 1260 if (r)
1258 return r; 1261 return r;
@@ -1283,7 +1286,7 @@ static int patch_cck_gain(struct zd_chip *chip)
1283 int r; 1286 int r;
1284 u32 value; 1287 u32 value;
1285 1288
1286 if (!chip->patch_cck_gain) 1289 if (!chip->patch_cck_gain || !zd_rf_should_patch_cck_gain(&chip->rf))
1287 return 0; 1290 return 0;
1288 1291
1289 ZD_ASSERT(mutex_is_locked(&chip->mutex)); 1292 ZD_ASSERT(mutex_is_locked(&chip->mutex));
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.h b/drivers/net/wireless/zd1211rw/zd_chip.h
index ce0a5f6da0d2..79d0288c193a 100644
--- a/drivers/net/wireless/zd1211rw/zd_chip.h
+++ b/drivers/net/wireless/zd1211rw/zd_chip.h
@@ -608,6 +608,9 @@ enum {
608#define CR_ZD1211B_TXOP CTL_REG(0x0b20) 608#define CR_ZD1211B_TXOP CTL_REG(0x0b20)
609#define CR_ZD1211B_RETRY_MAX CTL_REG(0x0b28) 609#define CR_ZD1211B_RETRY_MAX CTL_REG(0x0b28)
610 610
611/* Used to detect PLL lock */
612#define UW2453_INTR_REG ((zd_addr_t)0x85c1)
613
611#define CWIN_SIZE 0x007f043f 614#define CWIN_SIZE 0x007f043f
612 615
613 616
diff --git a/drivers/net/wireless/zd1211rw/zd_rf.c b/drivers/net/wireless/zd1211rw/zd_rf.c
index 549c23bcd6cc..7407409b60b1 100644
--- a/drivers/net/wireless/zd1211rw/zd_rf.c
+++ b/drivers/net/wireless/zd1211rw/zd_rf.c
@@ -52,34 +52,38 @@ const char *zd_rf_name(u8 type)
52void zd_rf_init(struct zd_rf *rf) 52void zd_rf_init(struct zd_rf *rf)
53{ 53{
54 memset(rf, 0, sizeof(*rf)); 54 memset(rf, 0, sizeof(*rf));
55
56 /* default to update channel integration, as almost all RF's do want
57 * this */
58 rf->update_channel_int = 1;
55} 59}
56 60
57void zd_rf_clear(struct zd_rf *rf) 61void zd_rf_clear(struct zd_rf *rf)
58{ 62{
63 if (rf->clear)
64 rf->clear(rf);
59 ZD_MEMCLEAR(rf, sizeof(*rf)); 65 ZD_MEMCLEAR(rf, sizeof(*rf));
60} 66}
61 67
62int zd_rf_init_hw(struct zd_rf *rf, u8 type) 68int zd_rf_init_hw(struct zd_rf *rf, u8 type)
63{ 69{
64 int r, t; 70 int r = 0;
71 int t;
65 struct zd_chip *chip = zd_rf_to_chip(rf); 72 struct zd_chip *chip = zd_rf_to_chip(rf);
66 73
67 ZD_ASSERT(mutex_is_locked(&chip->mutex)); 74 ZD_ASSERT(mutex_is_locked(&chip->mutex));
68 switch (type) { 75 switch (type) {
69 case RF2959_RF: 76 case RF2959_RF:
70 r = zd_rf_init_rf2959(rf); 77 r = zd_rf_init_rf2959(rf);
71 if (r)
72 return r;
73 break; 78 break;
74 case AL2230_RF: 79 case AL2230_RF:
75 r = zd_rf_init_al2230(rf); 80 r = zd_rf_init_al2230(rf);
76 if (r)
77 return r;
78 break; 81 break;
79 case AL7230B_RF: 82 case AL7230B_RF:
80 r = zd_rf_init_al7230b(rf); 83 r = zd_rf_init_al7230b(rf);
81 if (r) 84 break;
82 return r; 85 case UW2453_RF:
86 r = zd_rf_init_uw2453(rf);
83 break; 87 break;
84 default: 88 default:
85 dev_err(zd_chip_dev(chip), 89 dev_err(zd_chip_dev(chip),
@@ -88,6 +92,9 @@ int zd_rf_init_hw(struct zd_rf *rf, u8 type)
88 return -ENODEV; 92 return -ENODEV;
89 } 93 }
90 94
95 if (r)
96 return r;
97
91 rf->type = type; 98 rf->type = type;
92 99
93 r = zd_chip_lock_phy_regs(chip); 100 r = zd_chip_lock_phy_regs(chip);
diff --git a/drivers/net/wireless/zd1211rw/zd_rf.h b/drivers/net/wireless/zd1211rw/zd_rf.h
index aa9cc105ce60..c6dfd8227f6e 100644
--- a/drivers/net/wireless/zd1211rw/zd_rf.h
+++ b/drivers/net/wireless/zd1211rw/zd_rf.h
@@ -48,12 +48,26 @@ struct zd_rf {
48 48
49 u8 channel; 49 u8 channel;
50 50
51 /* whether channel integration and calibration should be updated
52 * defaults to 1 (yes) */
53 u8 update_channel_int:1;
54
55 /* whether CR47 should be patched from the EEPROM, if the appropriate
56 * flag is set in the POD. The vendor driver suggests that this should
57 * be done for all RF's, but a bug in their code prevents but their
58 * HW_OverWritePhyRegFromE2P() routine from ever taking effect. */
59 u8 patch_cck_gain:1;
60
61 /* private RF driver data */
62 void *priv;
63
51 /* RF-specific functions */ 64 /* RF-specific functions */
52 int (*init_hw)(struct zd_rf *rf); 65 int (*init_hw)(struct zd_rf *rf);
53 int (*set_channel)(struct zd_rf *rf, u8 channel); 66 int (*set_channel)(struct zd_rf *rf, u8 channel);
54 int (*switch_radio_on)(struct zd_rf *rf); 67 int (*switch_radio_on)(struct zd_rf *rf);
55 int (*switch_radio_off)(struct zd_rf *rf); 68 int (*switch_radio_off)(struct zd_rf *rf);
56 int (*patch_6m_band_edge)(struct zd_rf *rf, u8 channel); 69 int (*patch_6m_band_edge)(struct zd_rf *rf, u8 channel);
70 void (*clear)(struct zd_rf *rf);
57}; 71};
58 72
59const char *zd_rf_name(u8 type); 73const char *zd_rf_name(u8 type);
@@ -71,10 +85,24 @@ int zd_switch_radio_off(struct zd_rf *rf);
71int zd_rf_patch_6m_band_edge(struct zd_rf *rf, u8 channel); 85int zd_rf_patch_6m_band_edge(struct zd_rf *rf, u8 channel);
72int zd_rf_generic_patch_6m(struct zd_rf *rf, u8 channel); 86int zd_rf_generic_patch_6m(struct zd_rf *rf, u8 channel);
73 87
88static inline int zd_rf_should_update_pwr_int(struct zd_rf *rf)
89{
90 return rf->update_channel_int;
91}
92
93static inline int zd_rf_should_patch_cck_gain(struct zd_rf *rf)
94{
95 return rf->patch_cck_gain;
96}
97
98int zd_rf_patch_6m_band_edge(struct zd_rf *rf, u8 channel);
99int zd_rf_generic_patch_6m(struct zd_rf *rf, u8 channel);
100
74/* Functions for individual RF chips */ 101/* Functions for individual RF chips */
75 102
76int zd_rf_init_rf2959(struct zd_rf *rf); 103int zd_rf_init_rf2959(struct zd_rf *rf);
77int zd_rf_init_al2230(struct zd_rf *rf); 104int zd_rf_init_al2230(struct zd_rf *rf);
78int zd_rf_init_al7230b(struct zd_rf *rf); 105int zd_rf_init_al7230b(struct zd_rf *rf);
106int zd_rf_init_uw2453(struct zd_rf *rf);
79 107
80#endif /* _ZD_RF_H */ 108#endif /* _ZD_RF_H */
diff --git a/drivers/net/wireless/zd1211rw/zd_rf_al2230.c b/drivers/net/wireless/zd1211rw/zd_rf_al2230.c
index 511392acfedf..e7a4ecf7b6e2 100644
--- a/drivers/net/wireless/zd1211rw/zd_rf_al2230.c
+++ b/drivers/net/wireless/zd1211rw/zd_rf_al2230.c
@@ -432,5 +432,6 @@ int zd_rf_init_al2230(struct zd_rf *rf)
432 rf->switch_radio_on = zd1211_al2230_switch_radio_on; 432 rf->switch_radio_on = zd1211_al2230_switch_radio_on;
433 } 433 }
434 rf->patch_6m_band_edge = zd_rf_generic_patch_6m; 434 rf->patch_6m_band_edge = zd_rf_generic_patch_6m;
435 rf->patch_cck_gain = 1;
435 return 0; 436 return 0;
436} 437}
diff --git a/drivers/net/wireless/zd1211rw/zd_rf_al7230b.c b/drivers/net/wireless/zd1211rw/zd_rf_al7230b.c
index 5e5e9ddc6a74..f4e8b6ada854 100644
--- a/drivers/net/wireless/zd1211rw/zd_rf_al7230b.c
+++ b/drivers/net/wireless/zd1211rw/zd_rf_al7230b.c
@@ -483,6 +483,7 @@ int zd_rf_init_al7230b(struct zd_rf *rf)
483 rf->switch_radio_on = zd1211_al7230b_switch_radio_on; 483 rf->switch_radio_on = zd1211_al7230b_switch_radio_on;
484 rf->set_channel = zd1211_al7230b_set_channel; 484 rf->set_channel = zd1211_al7230b_set_channel;
485 rf->patch_6m_band_edge = zd_rf_generic_patch_6m; 485 rf->patch_6m_band_edge = zd_rf_generic_patch_6m;
486 rf->patch_cck_gain = 1;
486 } 487 }
487 488
488 rf->switch_radio_off = al7230b_switch_radio_off; 489 rf->switch_radio_off = al7230b_switch_radio_off;
diff --git a/drivers/net/wireless/zd1211rw/zd_rf_uw2453.c b/drivers/net/wireless/zd1211rw/zd_rf_uw2453.c
new file mode 100644
index 000000000000..414e40d571ab
--- /dev/null
+++ b/drivers/net/wireless/zd1211rw/zd_rf_uw2453.c
@@ -0,0 +1,534 @@
1/* zd_rf_uw2453.c: Functions for the UW2453 RF controller
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 */
17
18#include <linux/kernel.h>
19
20#include "zd_rf.h"
21#include "zd_usb.h"
22#include "zd_chip.h"
23
24/* This RF programming code is based upon the code found in v2.16.0.0 of the
25 * ZyDAS vendor driver. Unlike other RF's, Ubec publish full technical specs
26 * for this RF on their website, so we're able to understand more than
27 * usual as to what is going on. Thumbs up for Ubec for doing that. */
28
29/* The 3-wire serial interface provides access to 8 write-only registers.
30 * The data format is a 4 bit register address followed by a 20 bit value. */
31#define UW2453_REGWRITE(reg, val) ((((reg) & 0xf) << 20) | ((val) & 0xfffff))
32
33/* For channel tuning, we have to configure registers 1 (synthesizer), 2 (synth
34 * fractional divide ratio) and 3 (VCO config).
35 *
36 * We configure the RF to produce an interrupt when the PLL is locked onto
37 * the configured frequency. During initialization, we run through a variety
38 * of different VCO configurations on channel 1 until we detect a PLL lock.
39 * When this happens, we remember which VCO configuration produced the lock
40 * and use it later. Actually, we use the configuration *after* the one that
41 * produced the lock, which seems odd, but it works.
42 *
43 * If we do not see a PLL lock on any standard VCO config, we fall back on an
44 * autocal configuration, which has a fixed (as opposed to per-channel) VCO
45 * config and different synth values from the standard set (divide ratio
46 * is still shared with the standard set). */
47
48/* The per-channel synth values for all standard VCO configurations. These get
49 * written to register 1. */
50static const u8 uw2453_std_synth[] = {
51 RF_CHANNEL( 1) = 0x47,
52 RF_CHANNEL( 2) = 0x47,
53 RF_CHANNEL( 3) = 0x67,
54 RF_CHANNEL( 4) = 0x67,
55 RF_CHANNEL( 5) = 0x67,
56 RF_CHANNEL( 6) = 0x67,
57 RF_CHANNEL( 7) = 0x57,
58 RF_CHANNEL( 8) = 0x57,
59 RF_CHANNEL( 9) = 0x57,
60 RF_CHANNEL(10) = 0x57,
61 RF_CHANNEL(11) = 0x77,
62 RF_CHANNEL(12) = 0x77,
63 RF_CHANNEL(13) = 0x77,
64 RF_CHANNEL(14) = 0x4f,
65};
66
67/* This table stores the synthesizer fractional divide ratio for *all* VCO
68 * configurations (both standard and autocal). These get written to register 2.
69 */
70static const u16 uw2453_synth_divide[] = {
71 RF_CHANNEL( 1) = 0x999,
72 RF_CHANNEL( 2) = 0x99b,
73 RF_CHANNEL( 3) = 0x998,
74 RF_CHANNEL( 4) = 0x99a,
75 RF_CHANNEL( 5) = 0x999,
76 RF_CHANNEL( 6) = 0x99b,
77 RF_CHANNEL( 7) = 0x998,
78 RF_CHANNEL( 8) = 0x99a,
79 RF_CHANNEL( 9) = 0x999,
80 RF_CHANNEL(10) = 0x99b,
81 RF_CHANNEL(11) = 0x998,
82 RF_CHANNEL(12) = 0x99a,
83 RF_CHANNEL(13) = 0x999,
84 RF_CHANNEL(14) = 0xccc,
85};
86
87/* Here is the data for all the standard VCO configurations. We shrink our
88 * table a little by observing that both channels in a consecutive pair share
89 * the same value. We also observe that the high 4 bits ([0:3] in the specs)
90 * are all 'Reserved' and are always set to 0x4 - we chop them off in the data
91 * below. */
92#define CHAN_TO_PAIRIDX(a) ((a - 1) / 2)
93#define RF_CHANPAIR(a,b) [CHAN_TO_PAIRIDX(a)]
94static const u16 uw2453_std_vco_cfg[][7] = {
95 { /* table 1 */
96 RF_CHANPAIR( 1, 2) = 0x664d,
97 RF_CHANPAIR( 3, 4) = 0x604d,
98 RF_CHANPAIR( 5, 6) = 0x6675,
99 RF_CHANPAIR( 7, 8) = 0x6475,
100 RF_CHANPAIR( 9, 10) = 0x6655,
101 RF_CHANPAIR(11, 12) = 0x6455,
102 RF_CHANPAIR(13, 14) = 0x6665,
103 },
104 { /* table 2 */
105 RF_CHANPAIR( 1, 2) = 0x666d,
106 RF_CHANPAIR( 3, 4) = 0x606d,
107 RF_CHANPAIR( 5, 6) = 0x664d,
108 RF_CHANPAIR( 7, 8) = 0x644d,
109 RF_CHANPAIR( 9, 10) = 0x6675,
110 RF_CHANPAIR(11, 12) = 0x6475,
111 RF_CHANPAIR(13, 14) = 0x6655,
112 },
113 { /* table 3 */
114 RF_CHANPAIR( 1, 2) = 0x665d,
115 RF_CHANPAIR( 3, 4) = 0x605d,
116 RF_CHANPAIR( 5, 6) = 0x666d,
117 RF_CHANPAIR( 7, 8) = 0x646d,
118 RF_CHANPAIR( 9, 10) = 0x664d,
119 RF_CHANPAIR(11, 12) = 0x644d,
120 RF_CHANPAIR(13, 14) = 0x6675,
121 },
122 { /* table 4 */
123 RF_CHANPAIR( 1, 2) = 0x667d,
124 RF_CHANPAIR( 3, 4) = 0x607d,
125 RF_CHANPAIR( 5, 6) = 0x665d,
126 RF_CHANPAIR( 7, 8) = 0x645d,
127 RF_CHANPAIR( 9, 10) = 0x666d,
128 RF_CHANPAIR(11, 12) = 0x646d,
129 RF_CHANPAIR(13, 14) = 0x664d,
130 },
131 { /* table 5 */
132 RF_CHANPAIR( 1, 2) = 0x6643,
133 RF_CHANPAIR( 3, 4) = 0x6043,
134 RF_CHANPAIR( 5, 6) = 0x667d,
135 RF_CHANPAIR( 7, 8) = 0x647d,
136 RF_CHANPAIR( 9, 10) = 0x665d,
137 RF_CHANPAIR(11, 12) = 0x645d,
138 RF_CHANPAIR(13, 14) = 0x666d,
139 },
140 { /* table 6 */
141 RF_CHANPAIR( 1, 2) = 0x6663,
142 RF_CHANPAIR( 3, 4) = 0x6063,
143 RF_CHANPAIR( 5, 6) = 0x6643,
144 RF_CHANPAIR( 7, 8) = 0x6443,
145 RF_CHANPAIR( 9, 10) = 0x667d,
146 RF_CHANPAIR(11, 12) = 0x647d,
147 RF_CHANPAIR(13, 14) = 0x665d,
148 },
149 { /* table 7 */
150 RF_CHANPAIR( 1, 2) = 0x6653,
151 RF_CHANPAIR( 3, 4) = 0x6053,
152 RF_CHANPAIR( 5, 6) = 0x6663,
153 RF_CHANPAIR( 7, 8) = 0x6463,
154 RF_CHANPAIR( 9, 10) = 0x6643,
155 RF_CHANPAIR(11, 12) = 0x6443,
156 RF_CHANPAIR(13, 14) = 0x667d,
157 },
158 { /* table 8 */
159 RF_CHANPAIR( 1, 2) = 0x6673,
160 RF_CHANPAIR( 3, 4) = 0x6073,
161 RF_CHANPAIR( 5, 6) = 0x6653,
162 RF_CHANPAIR( 7, 8) = 0x6453,
163 RF_CHANPAIR( 9, 10) = 0x6663,
164 RF_CHANPAIR(11, 12) = 0x6463,
165 RF_CHANPAIR(13, 14) = 0x6643,
166 },
167 { /* table 9 */
168 RF_CHANPAIR( 1, 2) = 0x664b,
169 RF_CHANPAIR( 3, 4) = 0x604b,
170 RF_CHANPAIR( 5, 6) = 0x6673,
171 RF_CHANPAIR( 7, 8) = 0x6473,
172 RF_CHANPAIR( 9, 10) = 0x6653,
173 RF_CHANPAIR(11, 12) = 0x6453,
174 RF_CHANPAIR(13, 14) = 0x6663,
175 },
176 { /* table 10 */
177 RF_CHANPAIR( 1, 2) = 0x666b,
178 RF_CHANPAIR( 3, 4) = 0x606b,
179 RF_CHANPAIR( 5, 6) = 0x664b,
180 RF_CHANPAIR( 7, 8) = 0x644b,
181 RF_CHANPAIR( 9, 10) = 0x6673,
182 RF_CHANPAIR(11, 12) = 0x6473,
183 RF_CHANPAIR(13, 14) = 0x6653,
184 },
185 { /* table 11 */
186 RF_CHANPAIR( 1, 2) = 0x665b,
187 RF_CHANPAIR( 3, 4) = 0x605b,
188 RF_CHANPAIR( 5, 6) = 0x666b,
189 RF_CHANPAIR( 7, 8) = 0x646b,
190 RF_CHANPAIR( 9, 10) = 0x664b,
191 RF_CHANPAIR(11, 12) = 0x644b,
192 RF_CHANPAIR(13, 14) = 0x6673,
193 },
194
195};
196
197/* The per-channel synth values for autocal. These get written to register 1. */
198static const u16 uw2453_autocal_synth[] = {
199 RF_CHANNEL( 1) = 0x6847,
200 RF_CHANNEL( 2) = 0x6847,
201 RF_CHANNEL( 3) = 0x6867,
202 RF_CHANNEL( 4) = 0x6867,
203 RF_CHANNEL( 5) = 0x6867,
204 RF_CHANNEL( 6) = 0x6867,
205 RF_CHANNEL( 7) = 0x6857,
206 RF_CHANNEL( 8) = 0x6857,
207 RF_CHANNEL( 9) = 0x6857,
208 RF_CHANNEL(10) = 0x6857,
209 RF_CHANNEL(11) = 0x6877,
210 RF_CHANNEL(12) = 0x6877,
211 RF_CHANNEL(13) = 0x6877,
212 RF_CHANNEL(14) = 0x684f,
213};
214
215/* The VCO configuration for autocal (all channels) */
216static const u16 UW2453_AUTOCAL_VCO_CFG = 0x6662;
217
218/* TX gain settings. The array index corresponds to the TX power integration
219 * values found in the EEPROM. The values get written to register 7. */
220static u32 uw2453_txgain[] = {
221 [0x00] = 0x0e313,
222 [0x01] = 0x0fb13,
223 [0x02] = 0x0e093,
224 [0x03] = 0x0f893,
225 [0x04] = 0x0ea93,
226 [0x05] = 0x1f093,
227 [0x06] = 0x1f493,
228 [0x07] = 0x1f693,
229 [0x08] = 0x1f393,
230 [0x09] = 0x1f35b,
231 [0x0a] = 0x1e6db,
232 [0x0b] = 0x1ff3f,
233 [0x0c] = 0x1ffff,
234 [0x0d] = 0x361d7,
235 [0x0e] = 0x37fbf,
236 [0x0f] = 0x3ff8b,
237 [0x10] = 0x3ff33,
238 [0x11] = 0x3fb3f,
239 [0x12] = 0x3ffff,
240};
241
242/* RF-specific structure */
243struct uw2453_priv {
244 /* index into synth/VCO config tables where PLL lock was found
245 * -1 means autocal */
246 int config;
247};
248
249#define UW2453_PRIV(rf) ((struct uw2453_priv *) (rf)->priv)
250
251static int uw2453_synth_set_channel(struct zd_chip *chip, int channel,
252 bool autocal)
253{
254 int r;
255 int idx = channel - 1;
256 u32 val;
257
258 if (autocal)
259 val = UW2453_REGWRITE(1, uw2453_autocal_synth[idx]);
260 else
261 val = UW2453_REGWRITE(1, uw2453_std_synth[idx]);
262
263 r = zd_rfwrite_locked(chip, val, RF_RV_BITS);
264 if (r)
265 return r;
266
267 return zd_rfwrite_locked(chip,
268 UW2453_REGWRITE(2, uw2453_synth_divide[idx]), RF_RV_BITS);
269}
270
271static int uw2453_write_vco_cfg(struct zd_chip *chip, u16 value)
272{
273 /* vendor driver always sets these upper bits even though the specs say
274 * they are reserved */
275 u32 val = 0x40000 | value;
276 return zd_rfwrite_locked(chip, UW2453_REGWRITE(3, val), RF_RV_BITS);
277}
278
279static int uw2453_init_mode(struct zd_chip *chip)
280{
281 static const u32 rv[] = {
282 UW2453_REGWRITE(0, 0x25f98), /* enter IDLE mode */
283 UW2453_REGWRITE(0, 0x25f9a), /* enter CAL_VCO mode */
284 UW2453_REGWRITE(0, 0x25f94), /* enter RX/TX mode */
285 UW2453_REGWRITE(0, 0x27fd4), /* power down RSSI circuit */
286 };
287
288 return zd_rfwritev_locked(chip, rv, ARRAY_SIZE(rv), RF_RV_BITS);
289}
290
291static int uw2453_set_tx_gain_level(struct zd_chip *chip, int channel)
292{
293 u8 int_value = chip->pwr_int_values[channel - 1];
294
295 if (int_value >= ARRAY_SIZE(uw2453_txgain)) {
296 dev_dbg_f(zd_chip_dev(chip), "can't configure TX gain for "
297 "int value %x on channel %d\n", int_value, channel);
298 return 0;
299 }
300
301 return zd_rfwrite_locked(chip,
302 UW2453_REGWRITE(7, uw2453_txgain[int_value]), RF_RV_BITS);
303}
304
305static int uw2453_init_hw(struct zd_rf *rf)
306{
307 int i, r;
308 int found_config = -1;
309 u16 intr_status;
310 struct zd_chip *chip = zd_rf_to_chip(rf);
311
312 static const struct zd_ioreq16 ioreqs[] = {
313 { CR10, 0x89 }, { CR15, 0x20 },
314 { CR17, 0x28 }, /* 6112 no change */
315 { CR23, 0x38 }, { CR24, 0x20 }, { CR26, 0x93 },
316 { CR27, 0x15 }, { CR28, 0x3e }, { CR29, 0x00 },
317 { CR33, 0x28 }, { CR34, 0x30 },
318 { CR35, 0x43 }, /* 6112 3e->43 */
319 { CR41, 0x24 }, { CR44, 0x32 },
320 { CR46, 0x92 }, /* 6112 96->92 */
321 { CR47, 0x1e },
322 { CR48, 0x04 }, /* 5602 Roger */
323 { CR49, 0xfa }, { CR79, 0x58 }, { CR80, 0x30 },
324 { CR81, 0x30 }, { CR87, 0x0a }, { CR89, 0x04 },
325 { CR91, 0x00 }, { CR92, 0x0a }, { CR98, 0x8d },
326 { CR99, 0x28 }, { CR100, 0x02 },
327 { CR101, 0x09 }, /* 6112 13->1f 6220 1f->13 6407 13->9 */
328 { CR102, 0x27 },
329 { CR106, 0x1c }, /* 5d07 5112 1f->1c 6220 1c->1f 6221 1f->1c */
330 { CR107, 0x1c }, /* 6220 1c->1a 5221 1a->1c */
331 { CR109, 0x13 },
332 { CR110, 0x1f }, /* 6112 13->1f 6221 1f->13 6407 13->0x09 */
333 { CR111, 0x13 }, { CR112, 0x1f }, { CR113, 0x27 },
334 { CR114, 0x23 }, /* 6221 27->23 */
335 { CR115, 0x24 }, /* 6112 24->1c 6220 1c->24 */
336 { CR116, 0x24 }, /* 6220 1c->24 */
337 { CR117, 0xfa }, /* 6112 fa->f8 6220 f8->f4 6220 f4->fa */
338 { CR118, 0xf0 }, /* 5d07 6112 f0->f2 6220 f2->f0 */
339 { CR119, 0x1a }, /* 6112 1a->10 6220 10->14 6220 14->1a */
340 { CR120, 0x4f },
341 { CR121, 0x1f }, /* 6220 4f->1f */
342 { CR122, 0xf0 }, { CR123, 0x57 }, { CR125, 0xad },
343 { CR126, 0x6c }, { CR127, 0x03 },
344 { CR128, 0x14 }, /* 6302 12->11 */
345 { CR129, 0x12 }, /* 6301 10->0f */
346 { CR130, 0x10 }, { CR137, 0x50 }, { CR138, 0xa8 },
347 { CR144, 0xac }, { CR146, 0x20 }, { CR252, 0xff },
348 { CR253, 0xff },
349 };
350
351 static const u32 rv[] = {
352 UW2453_REGWRITE(4, 0x2b), /* configure reciever gain */
353 UW2453_REGWRITE(5, 0x19e4f), /* configure transmitter gain */
354 UW2453_REGWRITE(6, 0xf81ad), /* enable RX/TX filter tuning */
355 UW2453_REGWRITE(7, 0x3fffe), /* disable TX gain in test mode */
356
357 /* enter CAL_FIL mode, TX gain set by registers, RX gain set by pins,
358 * RSSI circuit powered down, reduced RSSI range */
359 UW2453_REGWRITE(0, 0x25f9c), /* 5d01 cal_fil */
360
361 /* synthesizer configuration for channel 1 */
362 UW2453_REGWRITE(1, 0x47),
363 UW2453_REGWRITE(2, 0x999),
364
365 /* disable manual VCO band selection */
366 UW2453_REGWRITE(3, 0x7602),
367
368 /* enable manual VCO band selection, configure current level */
369 UW2453_REGWRITE(3, 0x46063),
370 };
371
372 r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
373 if (r)
374 return r;
375
376 r = zd_rfwritev_locked(chip, rv, ARRAY_SIZE(rv), RF_RV_BITS);
377 if (r)
378 return r;
379
380 r = uw2453_init_mode(chip);
381 if (r)
382 return r;
383
384 /* Try all standard VCO configuration settings on channel 1 */
385 for (i = 0; i < ARRAY_SIZE(uw2453_std_vco_cfg) - 1; i++) {
386 /* Configure synthesizer for channel 1 */
387 r = uw2453_synth_set_channel(chip, 1, false);
388 if (r)
389 return r;
390
391 /* Write VCO config */
392 r = uw2453_write_vco_cfg(chip, uw2453_std_vco_cfg[i][0]);
393 if (r)
394 return r;
395
396 /* ack interrupt event */
397 r = zd_iowrite16_locked(chip, 0x0f, UW2453_INTR_REG);
398 if (r)
399 return r;
400
401 /* check interrupt status */
402 r = zd_ioread16_locked(chip, &intr_status, UW2453_INTR_REG);
403 if (r)
404 return r;
405
406 if (!intr_status & 0xf) {
407 dev_dbg_f(zd_chip_dev(chip),
408 "PLL locked on configuration %d\n", i);
409 found_config = i;
410 break;
411 }
412 }
413
414 if (found_config == -1) {
415 /* autocal */
416 dev_dbg_f(zd_chip_dev(chip),
417 "PLL did not lock, using autocal\n");
418
419 r = uw2453_synth_set_channel(chip, 1, true);
420 if (r)
421 return r;
422
423 r = uw2453_write_vco_cfg(chip, UW2453_AUTOCAL_VCO_CFG);
424 if (r)
425 return r;
426 }
427
428 /* To match the vendor driver behaviour, we use the configuration after
429 * the one that produced a lock. */
430 UW2453_PRIV(rf)->config = found_config + 1;
431
432 return zd_iowrite16_locked(chip, 0x06, CR203);
433}
434
435static int uw2453_set_channel(struct zd_rf *rf, u8 channel)
436{
437 int r;
438 u16 vco_cfg;
439 int config = UW2453_PRIV(rf)->config;
440 bool autocal = (config == -1);
441 struct zd_chip *chip = zd_rf_to_chip(rf);
442
443 static const struct zd_ioreq16 ioreqs[] = {
444 { CR80, 0x30 }, { CR81, 0x30 }, { CR79, 0x58 },
445 { CR12, 0xf0 }, { CR77, 0x1b }, { CR78, 0x58 },
446 };
447
448 r = uw2453_synth_set_channel(chip, channel, autocal);
449 if (r)
450 return r;
451
452 if (autocal)
453 vco_cfg = UW2453_AUTOCAL_VCO_CFG;
454 else
455 vco_cfg = uw2453_std_vco_cfg[config][CHAN_TO_PAIRIDX(channel)];
456
457 r = uw2453_write_vco_cfg(chip, vco_cfg);
458 if (r)
459 return r;
460
461 r = uw2453_init_mode(chip);
462 if (r)
463 return r;
464
465 r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
466 if (r)
467 return r;
468
469 r = uw2453_set_tx_gain_level(chip, channel);
470 if (r)
471 return r;
472
473 return zd_iowrite16_locked(chip, 0x06, CR203);
474}
475
476static int uw2453_switch_radio_on(struct zd_rf *rf)
477{
478 int r;
479 struct zd_chip *chip = zd_rf_to_chip(rf);
480 struct zd_ioreq16 ioreqs[] = {
481 { CR11, 0x00 }, { CR251, 0x3f },
482 };
483
484 /* enter RXTX mode */
485 r = zd_rfwrite_locked(chip, UW2453_REGWRITE(0, 0x25f94), RF_RV_BITS);
486 if (r)
487 return r;
488
489 if (chip->is_zd1211b)
490 ioreqs[1].value = 0x7f;
491
492 return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
493}
494
495static int uw2453_switch_radio_off(struct zd_rf *rf)
496{
497 int r;
498 struct zd_chip *chip = zd_rf_to_chip(rf);
499 static const struct zd_ioreq16 ioreqs[] = {
500 { CR11, 0x04 }, { CR251, 0x2f },
501 };
502
503 /* enter IDLE mode */
504 /* FIXME: shouldn't we go to SLEEP? sent email to zydas */
505 r = zd_rfwrite_locked(chip, UW2453_REGWRITE(0, 0x25f90), RF_RV_BITS);
506 if (r)
507 return r;
508
509 return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
510}
511
512static void uw2453_clear(struct zd_rf *rf)
513{
514 kfree(rf->priv);
515}
516
517int zd_rf_init_uw2453(struct zd_rf *rf)
518{
519 rf->init_hw = uw2453_init_hw;
520 rf->set_channel = uw2453_set_channel;
521 rf->switch_radio_on = uw2453_switch_radio_on;
522 rf->switch_radio_off = uw2453_switch_radio_off;
523 rf->patch_6m_band_edge = zd_rf_generic_patch_6m;
524 rf->clear = uw2453_clear;
525 /* we have our own TX integration code */
526 rf->update_channel_int = 0;
527
528 rf->priv = kmalloc(sizeof(struct uw2453_priv), GFP_KERNEL);
529 if (rf->priv == NULL)
530 return -ENOMEM;
531
532 return 0;
533}
534
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c
index 8459549d0cee..740a2194fdde 100644
--- a/drivers/net/wireless/zd1211rw/zd_usb.c
+++ b/drivers/net/wireless/zd1211rw/zd_usb.c
@@ -54,6 +54,7 @@ static struct usb_device_id usb_ids[] = {
54 { USB_DEVICE(0x0586, 0x3401), .driver_info = DEVICE_ZD1211 }, 54 { USB_DEVICE(0x0586, 0x3401), .driver_info = DEVICE_ZD1211 },
55 { USB_DEVICE(0x14ea, 0xab13), .driver_info = DEVICE_ZD1211 }, 55 { USB_DEVICE(0x14ea, 0xab13), .driver_info = DEVICE_ZD1211 },
56 { USB_DEVICE(0x13b1, 0x001e), .driver_info = DEVICE_ZD1211 }, 56 { USB_DEVICE(0x13b1, 0x001e), .driver_info = DEVICE_ZD1211 },
57 { USB_DEVICE(0x0586, 0x3407), .driver_info = DEVICE_ZD1211 },
57 /* ZD1211B */ 58 /* ZD1211B */
58 { USB_DEVICE(0x0ace, 0x1215), .driver_info = DEVICE_ZD1211B }, 59 { USB_DEVICE(0x0ace, 0x1215), .driver_info = DEVICE_ZD1211B },
59 { USB_DEVICE(0x157e, 0x300d), .driver_info = DEVICE_ZD1211B }, 60 { USB_DEVICE(0x157e, 0x300d), .driver_info = DEVICE_ZD1211B },
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
new file mode 100644
index 000000000000..ab9c3e5a7c1d
--- /dev/null
+++ b/drivers/power/Kconfig
@@ -0,0 +1,51 @@
1menuconfig POWER_SUPPLY
2 tristate "Power supply class support"
3 help
4 Say Y here to enable power supply class support. This allows
5 power supply (batteries, AC, USB) monitoring by userspace
6 via sysfs and uevent (if available) and/or APM kernel interface
7 (if selected below).
8
9if POWER_SUPPLY
10
11config POWER_SUPPLY_DEBUG
12 bool "Power supply debug"
13 help
14 Say Y here to enable debugging messages for power supply class
15 and drivers.
16
17config PDA_POWER
18 tristate "Generic PDA/phone power driver"
19 help
20 Say Y here to enable generic power driver for PDAs and phones with
21 one or two external power supplies (AC/USB) connected to main and
22 backup batteries, and optional builtin charger.
23
24config APM_POWER
25 tristate "APM emulation for class batteries"
26 depends on APM_EMULATION
27 help
28 Say Y here to enable support APM status emulation using
29 battery class devices.
30
31config BATTERY_DS2760
32 tristate "DS2760 battery driver (HP iPAQ & others)"
33 select W1
34 select W1_SLAVE_DS2760
35 help
36 Say Y here to enable support for batteries with ds2760 chip.
37
38config BATTERY_PMU
39 tristate "Apple PMU battery"
40 depends on ADB_PMU
41 help
42 Say Y here to expose battery information on Apple machines
43 through the generic battery class.
44
45config BATTERY_OLPC
46 tristate "One Laptop Per Child battery"
47 depends on X86_32 && OLPC
48 help
49 Say Y to enable support for the battery on the OLPC laptop.
50
51endif # POWER_SUPPLY
diff --git a/drivers/power/Makefile b/drivers/power/Makefile
new file mode 100644
index 000000000000..6413ded5fe5f
--- /dev/null
+++ b/drivers/power/Makefile
@@ -0,0 +1,22 @@
1power_supply-objs := power_supply_core.o
2
3ifeq ($(CONFIG_SYSFS),y)
4power_supply-objs += power_supply_sysfs.o
5endif
6
7ifeq ($(CONFIG_LEDS_TRIGGERS),y)
8power_supply-objs += power_supply_leds.o
9endif
10
11ifeq ($(CONFIG_POWER_SUPPLY_DEBUG),y)
12EXTRA_CFLAGS += -DDEBUG
13endif
14
15obj-$(CONFIG_POWER_SUPPLY) += power_supply.o
16
17obj-$(CONFIG_PDA_POWER) += pda_power.o
18obj-$(CONFIG_APM_POWER) += apm_power.o
19
20obj-$(CONFIG_BATTERY_DS2760) += ds2760_battery.o
21obj-$(CONFIG_BATTERY_PMU) += pmu_battery.o
22obj-$(CONFIG_BATTERY_OLPC) += olpc_battery.o
diff --git a/drivers/power/apm_power.c b/drivers/power/apm_power.c
new file mode 100644
index 000000000000..042bd950d036
--- /dev/null
+++ b/drivers/power/apm_power.c
@@ -0,0 +1,243 @@
1/*
2 * Copyright © 2007 Anton Vorontsov <cbou@mail.ru>
3 * Copyright © 2007 Eugeny Boger <eugenyboger@dgap.mipt.ru>
4 *
5 * Author: Eugeny Boger <eugenyboger@dgap.mipt.ru>
6 *
7 * Use consistent with the GNU GPL is permitted,
8 * provided that this copyright notice is
9 * preserved in its entirety in all copies and derived works.
10 */
11
12#include <linux/module.h>
13#include <linux/power_supply.h>
14#include <linux/apm-emulation.h>
15
16#define PSY_PROP(psy, prop, val) psy->get_property(psy, \
17 POWER_SUPPLY_PROP_##prop, val)
18
19#define _MPSY_PROP(prop, val) main_battery->get_property(main_battery, \
20 prop, val)
21
22#define MPSY_PROP(prop, val) _MPSY_PROP(POWER_SUPPLY_PROP_##prop, val)
23
24static struct power_supply *main_battery;
25
26static void find_main_battery(void)
27{
28 struct device *dev;
29 struct power_supply *bat, *batm;
30 union power_supply_propval full;
31 int max_charge = 0;
32
33 main_battery = NULL;
34 batm = NULL;
35 list_for_each_entry(dev, &power_supply_class->devices, node) {
36 bat = dev_get_drvdata(dev);
37 /* If none of battery devices cantains 'use_for_apm' flag,
38 choice one with maximum design charge */
39 if (!PSY_PROP(bat, CHARGE_FULL_DESIGN, &full)) {
40 if (full.intval > max_charge) {
41 batm = bat;
42 max_charge = full.intval;
43 }
44 }
45
46 if (bat->use_for_apm)
47 main_battery = bat;
48 }
49 if (!main_battery)
50 main_battery = batm;
51
52 return;
53}
54
55static int calculate_time(int status)
56{
57 union power_supply_propval charge_full, charge_empty;
58 union power_supply_propval charge, I;
59
60 if (MPSY_PROP(CHARGE_FULL, &charge_full)) {
61 /* if battery can't report this property, use design value */
62 if (MPSY_PROP(CHARGE_FULL_DESIGN, &charge_full))
63 return -1;
64 }
65
66 if (MPSY_PROP(CHARGE_EMPTY, &charge_empty)) {
67 /* if battery can't report this property, use design value */
68 if (MPSY_PROP(CHARGE_EMPTY_DESIGN, &charge_empty))
69 charge_empty.intval = 0;
70 }
71
72 if (MPSY_PROP(CHARGE_AVG, &charge)) {
73 /* if battery can't report average value, use momentary */
74 if (MPSY_PROP(CHARGE_NOW, &charge))
75 return -1;
76 }
77
78 if (MPSY_PROP(CURRENT_AVG, &I)) {
79 /* if battery can't report average value, use momentary */
80 if (MPSY_PROP(CURRENT_NOW, &I))
81 return -1;
82 }
83
84 if (status == POWER_SUPPLY_STATUS_CHARGING)
85 return ((charge.intval - charge_full.intval) * 60L) /
86 I.intval;
87 else
88 return -((charge.intval - charge_empty.intval) * 60L) /
89 I.intval;
90}
91
92static int calculate_capacity(int using_charge)
93{
94 enum power_supply_property full_prop, empty_prop;
95 enum power_supply_property full_design_prop, empty_design_prop;
96 enum power_supply_property now_prop, avg_prop;
97 union power_supply_propval empty, full, cur;
98 int ret;
99
100 if (using_charge) {
101 full_prop = POWER_SUPPLY_PROP_CHARGE_FULL;
102 empty_prop = POWER_SUPPLY_PROP_CHARGE_EMPTY;
103 full_design_prop = POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN;
104 empty_design_prop = POWER_SUPPLY_PROP_CHARGE_EMPTY_DESIGN;
105 now_prop = POWER_SUPPLY_PROP_CHARGE_NOW;
106 avg_prop = POWER_SUPPLY_PROP_CHARGE_AVG;
107 } else {
108 full_prop = POWER_SUPPLY_PROP_ENERGY_FULL;
109 empty_prop = POWER_SUPPLY_PROP_ENERGY_EMPTY;
110 full_design_prop = POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN;
111 empty_design_prop = POWER_SUPPLY_PROP_ENERGY_EMPTY_DESIGN;
112 now_prop = POWER_SUPPLY_PROP_ENERGY_NOW;
113 avg_prop = POWER_SUPPLY_PROP_ENERGY_AVG;
114 }
115
116 if (_MPSY_PROP(full_prop, &full)) {
117 /* if battery can't report this property, use design value */
118 if (_MPSY_PROP(full_design_prop, &full))
119 return -1;
120 }
121
122 if (_MPSY_PROP(avg_prop, &cur)) {
123 /* if battery can't report average value, use momentary */
124 if (_MPSY_PROP(now_prop, &cur))
125 return -1;
126 }
127
128 if (_MPSY_PROP(empty_prop, &empty)) {
129 /* if battery can't report this property, use design value */
130 if (_MPSY_PROP(empty_design_prop, &empty))
131 empty.intval = 0;
132 }
133
134 if (full.intval - empty.intval)
135 ret = ((cur.intval - empty.intval) * 100L) /
136 (full.intval - empty.intval);
137 else
138 return -1;
139
140 if (ret > 100)
141 return 100;
142 else if (ret < 0)
143 return 0;
144
145 return ret;
146}
147
148static void apm_battery_apm_get_power_status(struct apm_power_info *info)
149{
150 union power_supply_propval status;
151 union power_supply_propval capacity, time_to_full, time_to_empty;
152
153 down(&power_supply_class->sem);
154 find_main_battery();
155 if (!main_battery) {
156 up(&power_supply_class->sem);
157 return;
158 }
159
160 /* status */
161
162 if (MPSY_PROP(STATUS, &status))
163 status.intval = POWER_SUPPLY_STATUS_UNKNOWN;
164
165 /* ac line status */
166
167 if ((status.intval == POWER_SUPPLY_STATUS_CHARGING) ||
168 (status.intval == POWER_SUPPLY_STATUS_NOT_CHARGING) ||
169 (status.intval == POWER_SUPPLY_STATUS_FULL))
170 info->ac_line_status = APM_AC_ONLINE;
171 else
172 info->ac_line_status = APM_AC_OFFLINE;
173
174 /* battery life (i.e. capacity, in percents) */
175
176 if (MPSY_PROP(CAPACITY, &capacity) == 0) {
177 info->battery_life = capacity.intval;
178 } else {
179 /* try calculate using energy */
180 info->battery_life = calculate_capacity(0);
181 /* if failed try calculate using charge instead */
182 if (info->battery_life == -1)
183 info->battery_life = calculate_capacity(1);
184 }
185
186 /* charging status */
187
188 if (status.intval == POWER_SUPPLY_STATUS_CHARGING) {
189 info->battery_status = APM_BATTERY_STATUS_CHARGING;
190 } else {
191 if (info->battery_life > 50)
192 info->battery_status = APM_BATTERY_STATUS_HIGH;
193 else if (info->battery_life > 5)
194 info->battery_status = APM_BATTERY_STATUS_LOW;
195 else
196 info->battery_status = APM_BATTERY_STATUS_CRITICAL;
197 }
198 info->battery_flag = info->battery_status;
199
200 /* time */
201
202 info->units = APM_UNITS_MINS;
203
204 if (status.intval == POWER_SUPPLY_STATUS_CHARGING) {
205 if (MPSY_PROP(TIME_TO_FULL_AVG, &time_to_full)) {
206 if (MPSY_PROP(TIME_TO_FULL_NOW, &time_to_full))
207 info->time = calculate_time(status.intval);
208 else
209 info->time = time_to_full.intval / 60;
210 }
211 } else {
212 if (MPSY_PROP(TIME_TO_EMPTY_AVG, &time_to_empty)) {
213 if (MPSY_PROP(TIME_TO_EMPTY_NOW, &time_to_empty))
214 info->time = calculate_time(status.intval);
215 else
216 info->time = time_to_empty.intval / 60;
217 }
218 }
219
220 up(&power_supply_class->sem);
221 return;
222}
223
224static int __init apm_battery_init(void)
225{
226 printk(KERN_INFO "APM Battery Driver\n");
227
228 apm_get_power_status = apm_battery_apm_get_power_status;
229 return 0;
230}
231
232static void __exit apm_battery_exit(void)
233{
234 apm_get_power_status = NULL;
235 return;
236}
237
238module_init(apm_battery_init);
239module_exit(apm_battery_exit);
240
241MODULE_AUTHOR("Eugeny Boger <eugenyboger@dgap.mipt.ru>");
242MODULE_DESCRIPTION("APM emulation driver for battery monitoring class");
243MODULE_LICENSE("GPL");
diff --git a/drivers/power/ds2760_battery.c b/drivers/power/ds2760_battery.c
new file mode 100644
index 000000000000..00e1ea6f1de2
--- /dev/null
+++ b/drivers/power/ds2760_battery.c
@@ -0,0 +1,470 @@
1/*
2 * Driver for batteries with DS2760 chips inside.
3 *
4 * Copyright © 2007 Anton Vorontsov
5 * 2004-2007 Matt Reimer
6 * 2004 Szabolcs Gyurko
7 *
8 * Use consistent with the GNU GPL is permitted,
9 * provided that this copyright notice is
10 * preserved in its entirety in all copies and derived works.
11 *
12 * Author: Anton Vorontsov <cbou@mail.ru>
13 * February 2007
14 *
15 * Matt Reimer <mreimer@vpop.net>
16 * April 2004, 2005, 2007
17 *
18 * Szabolcs Gyurko <szabolcs.gyurko@tlt.hu>
19 * September 2004
20 */
21
22#include <linux/module.h>
23#include <linux/param.h>
24#include <linux/jiffies.h>
25#include <linux/workqueue.h>
26#include <linux/pm.h>
27#include <linux/platform_device.h>
28#include <linux/power_supply.h>
29
30#include "../w1/w1.h"
31#include "../w1/slaves/w1_ds2760.h"
32
33struct ds2760_device_info {
34 struct device *dev;
35
36 /* DS2760 data, valid after calling ds2760_battery_read_status() */
37 unsigned long update_time; /* jiffies when data read */
38 char raw[DS2760_DATA_SIZE]; /* raw DS2760 data */
39 int voltage_raw; /* units of 4.88 mV */
40 int voltage_uV; /* units of µV */
41 int current_raw; /* units of 0.625 mA */
42 int current_uA; /* units of µA */
43 int accum_current_raw; /* units of 0.25 mAh */
44 int accum_current_uAh; /* units of µAh */
45 int temp_raw; /* units of 0.125 °C */
46 int temp_C; /* units of 0.1 °C */
47 int rated_capacity; /* units of µAh */
48 int rem_capacity; /* percentage */
49 int full_active_uAh; /* units of µAh */
50 int empty_uAh; /* units of µAh */
51 int life_sec; /* units of seconds */
52 int charge_status; /* POWER_SUPPLY_STATUS_* */
53
54 int full_counter;
55 struct power_supply bat;
56 struct device *w1_dev;
57 struct workqueue_struct *monitor_wqueue;
58 struct delayed_work monitor_work;
59};
60
61static unsigned int cache_time = 1000;
62module_param(cache_time, uint, 0644);
63MODULE_PARM_DESC(cache_time, "cache time in milliseconds");
64
65/* Some batteries have their rated capacity stored a N * 10 mAh, while
66 * others use an index into this table. */
67static int rated_capacities[] = {
68 0,
69 920, /* Samsung */
70 920, /* BYD */
71 920, /* Lishen */
72 920, /* NEC */
73 1440, /* Samsung */
74 1440, /* BYD */
75 1440, /* Lishen */
76 1440, /* NEC */
77 2880, /* Samsung */
78 2880, /* BYD */
79 2880, /* Lishen */
80 2880 /* NEC */
81};
82
83/* array is level at temps 0°C, 10°C, 20°C, 30°C, 40°C
84 * temp is in Celsius */
85static int battery_interpolate(int array[], int temp)
86{
87 int index, dt;
88
89 if (temp <= 0)
90 return array[0];
91 if (temp >= 40)
92 return array[4];
93
94 index = temp / 10;
95 dt = temp % 10;
96
97 return array[index] + (((array[index + 1] - array[index]) * dt) / 10);
98}
99
100static int ds2760_battery_read_status(struct ds2760_device_info *di)
101{
102 int ret, i, start, count, scale[5];
103
104 if (di->update_time && time_before(jiffies, di->update_time +
105 msecs_to_jiffies(cache_time)))
106 return 0;
107
108 /* The first time we read the entire contents of SRAM/EEPROM,
109 * but after that we just read the interesting bits that change. */
110 if (di->update_time == 0) {
111 start = 0;
112 count = DS2760_DATA_SIZE;
113 } else {
114 start = DS2760_VOLTAGE_MSB;
115 count = DS2760_TEMP_LSB - start + 1;
116 }
117
118 ret = w1_ds2760_read(di->w1_dev, di->raw + start, start, count);
119 if (ret != count) {
120 dev_warn(di->dev, "call to w1_ds2760_read failed (0x%p)\n",
121 di->w1_dev);
122 return 1;
123 }
124
125 di->update_time = jiffies;
126
127 /* DS2760 reports voltage in units of 4.88mV, but the battery class
128 * reports in units of uV, so convert by multiplying by 4880. */
129 di->voltage_raw = (di->raw[DS2760_VOLTAGE_MSB] << 3) |
130 (di->raw[DS2760_VOLTAGE_LSB] >> 5);
131 di->voltage_uV = di->voltage_raw * 4880;
132
133 /* DS2760 reports current in signed units of 0.625mA, but the battery
134 * class reports in units of µA, so convert by multiplying by 625. */
135 di->current_raw =
136 (((signed char)di->raw[DS2760_CURRENT_MSB]) << 5) |
137 (di->raw[DS2760_CURRENT_LSB] >> 3);
138 di->current_uA = di->current_raw * 625;
139
140 /* DS2760 reports accumulated current in signed units of 0.25mAh. */
141 di->accum_current_raw =
142 (((signed char)di->raw[DS2760_CURRENT_ACCUM_MSB]) << 8) |
143 di->raw[DS2760_CURRENT_ACCUM_LSB];
144 di->accum_current_uAh = di->accum_current_raw * 250;
145
146 /* DS2760 reports temperature in signed units of 0.125°C, but the
147 * battery class reports in units of 1/10 °C, so we convert by
148 * multiplying by .125 * 10 = 1.25. */
149 di->temp_raw = (((signed char)di->raw[DS2760_TEMP_MSB]) << 3) |
150 (di->raw[DS2760_TEMP_LSB] >> 5);
151 di->temp_C = di->temp_raw + (di->temp_raw / 4);
152
153 /* At least some battery monitors (e.g. HP iPAQ) store the battery's
154 * maximum rated capacity. */
155 if (di->raw[DS2760_RATED_CAPACITY] < ARRAY_SIZE(rated_capacities))
156 di->rated_capacity = rated_capacities[
157 (unsigned int)di->raw[DS2760_RATED_CAPACITY]];
158 else
159 di->rated_capacity = di->raw[DS2760_RATED_CAPACITY] * 10;
160
161 di->rated_capacity *= 1000; /* convert to µAh */
162
163 /* Calculate the full level at the present temperature. */
164 di->full_active_uAh = di->raw[DS2760_ACTIVE_FULL] << 8 |
165 di->raw[DS2760_ACTIVE_FULL + 1];
166
167 scale[0] = di->raw[DS2760_ACTIVE_FULL] << 8 |
168 di->raw[DS2760_ACTIVE_FULL + 1];
169 for (i = 1; i < 5; i++)
170 scale[i] = scale[i - 1] + di->raw[DS2760_ACTIVE_FULL + 2 + i];
171
172 di->full_active_uAh = battery_interpolate(scale, di->temp_C / 10);
173 di->full_active_uAh *= 1000; /* convert to µAh */
174
175 /* Calculate the empty level at the present temperature. */
176 scale[4] = di->raw[DS2760_ACTIVE_EMPTY + 4];
177 for (i = 3; i >= 0; i--)
178 scale[i] = scale[i + 1] + di->raw[DS2760_ACTIVE_EMPTY + i];
179
180 di->empty_uAh = battery_interpolate(scale, di->temp_C / 10);
181 di->empty_uAh *= 1000; /* convert to µAh */
182
183 /* From Maxim Application Note 131: remaining capacity =
184 * ((ICA - Empty Value) / (Full Value - Empty Value)) x 100% */
185 di->rem_capacity = ((di->accum_current_uAh - di->empty_uAh) * 100L) /
186 (di->full_active_uAh - di->empty_uAh);
187
188 if (di->rem_capacity < 0)
189 di->rem_capacity = 0;
190 if (di->rem_capacity > 100)
191 di->rem_capacity = 100;
192
193 if (di->current_uA)
194 di->life_sec = -((di->accum_current_uAh - di->empty_uAh) *
195 3600L) / di->current_uA;
196 else
197 di->life_sec = 0;
198
199 return 0;
200}
201
202static void ds2760_battery_update_status(struct ds2760_device_info *di)
203{
204 int old_charge_status = di->charge_status;
205
206 ds2760_battery_read_status(di);
207
208 if (di->charge_status == POWER_SUPPLY_STATUS_UNKNOWN)
209 di->full_counter = 0;
210
211 if (power_supply_am_i_supplied(&di->bat)) {
212 if (di->current_uA > 10000) {
213 di->charge_status = POWER_SUPPLY_STATUS_CHARGING;
214 di->full_counter = 0;
215 } else if (di->current_uA < -5000) {
216 if (di->charge_status != POWER_SUPPLY_STATUS_NOT_CHARGING)
217 dev_notice(di->dev, "not enough power to "
218 "charge\n");
219 di->charge_status = POWER_SUPPLY_STATUS_NOT_CHARGING;
220 di->full_counter = 0;
221 } else if (di->current_uA < 10000 &&
222 di->charge_status != POWER_SUPPLY_STATUS_FULL) {
223
224 /* Don't consider the battery to be full unless
225 * we've seen the current < 10 mA at least two
226 * consecutive times. */
227
228 di->full_counter++;
229
230 if (di->full_counter < 2) {
231 di->charge_status = POWER_SUPPLY_STATUS_CHARGING;
232 } else {
233 unsigned char acr[2];
234 int acr_val;
235
236 /* acr is in units of 0.25 mAh */
237 acr_val = di->full_active_uAh * 4L / 1000;
238
239 acr[0] = acr_val >> 8;
240 acr[1] = acr_val & 0xff;
241
242 if (w1_ds2760_write(di->w1_dev, acr,
243 DS2760_CURRENT_ACCUM_MSB, 2) < 2)
244 dev_warn(di->dev,
245 "ACR reset failed\n");
246
247 di->charge_status = POWER_SUPPLY_STATUS_FULL;
248 }
249 }
250 } else {
251 di->charge_status = POWER_SUPPLY_STATUS_DISCHARGING;
252 di->full_counter = 0;
253 }
254
255 if (di->charge_status != old_charge_status)
256 power_supply_changed(&di->bat);
257
258 return;
259}
260
261static void ds2760_battery_work(struct work_struct *work)
262{
263 struct ds2760_device_info *di = container_of(work,
264 struct ds2760_device_info, monitor_work.work);
265 const int interval = HZ * 60;
266
267 dev_dbg(di->dev, "%s\n", __FUNCTION__);
268
269 ds2760_battery_update_status(di);
270 queue_delayed_work(di->monitor_wqueue, &di->monitor_work, interval);
271
272 return;
273}
274
275#define to_ds2760_device_info(x) container_of((x), struct ds2760_device_info, \
276 bat);
277
278static void ds2760_battery_external_power_changed(struct power_supply *psy)
279{
280 struct ds2760_device_info *di = to_ds2760_device_info(psy);
281
282 dev_dbg(di->dev, "%s\n", __FUNCTION__);
283
284 cancel_delayed_work(&di->monitor_work);
285 queue_delayed_work(di->monitor_wqueue, &di->monitor_work, HZ/10);
286
287 return;
288}
289
290static int ds2760_battery_get_property(struct power_supply *psy,
291 enum power_supply_property psp,
292 union power_supply_propval *val)
293{
294 struct ds2760_device_info *di = to_ds2760_device_info(psy);
295
296 switch (psp) {
297 case POWER_SUPPLY_PROP_STATUS:
298 val->intval = di->charge_status;
299 return 0;
300 default:
301 break;
302 }
303
304 ds2760_battery_read_status(di);
305
306 switch (psp) {
307 case POWER_SUPPLY_PROP_VOLTAGE_NOW:
308 val->intval = di->voltage_uV;
309 break;
310 case POWER_SUPPLY_PROP_CURRENT_NOW:
311 val->intval = di->current_uA;
312 break;
313 case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
314 val->intval = di->rated_capacity;
315 break;
316 case POWER_SUPPLY_PROP_CHARGE_FULL:
317 val->intval = di->full_active_uAh;
318 break;
319 case POWER_SUPPLY_PROP_CHARGE_EMPTY:
320 val->intval = di->empty_uAh;
321 break;
322 case POWER_SUPPLY_PROP_CHARGE_NOW:
323 val->intval = di->accum_current_uAh;
324 break;
325 case POWER_SUPPLY_PROP_TEMP:
326 val->intval = di->temp_C;
327 break;
328 default:
329 return -EINVAL;
330 }
331
332 return 0;
333}
334
335static enum power_supply_property ds2760_battery_props[] = {
336 POWER_SUPPLY_PROP_STATUS,
337 POWER_SUPPLY_PROP_VOLTAGE_NOW,
338 POWER_SUPPLY_PROP_CURRENT_NOW,
339 POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
340 POWER_SUPPLY_PROP_CHARGE_FULL,
341 POWER_SUPPLY_PROP_CHARGE_EMPTY,
342 POWER_SUPPLY_PROP_CHARGE_NOW,
343 POWER_SUPPLY_PROP_TEMP,
344};
345
346static int ds2760_battery_probe(struct platform_device *pdev)
347{
348 int retval = 0;
349 struct ds2760_device_info *di;
350 struct ds2760_platform_data *pdata;
351
352 di = kzalloc(sizeof(*di), GFP_KERNEL);
353 if (!di) {
354 retval = -ENOMEM;
355 goto di_alloc_failed;
356 }
357
358 platform_set_drvdata(pdev, di);
359
360 pdata = pdev->dev.platform_data;
361 di->dev = &pdev->dev;
362 di->w1_dev = pdev->dev.parent;
363 di->bat.name = pdev->dev.bus_id;
364 di->bat.type = POWER_SUPPLY_TYPE_BATTERY;
365 di->bat.properties = ds2760_battery_props;
366 di->bat.num_properties = ARRAY_SIZE(ds2760_battery_props);
367 di->bat.get_property = ds2760_battery_get_property;
368 di->bat.external_power_changed =
369 ds2760_battery_external_power_changed;
370
371 di->charge_status = POWER_SUPPLY_STATUS_UNKNOWN;
372
373 retval = power_supply_register(&pdev->dev, &di->bat);
374 if (retval) {
375 dev_err(di->dev, "failed to register battery");
376 goto batt_failed;
377 }
378
379 INIT_DELAYED_WORK(&di->monitor_work, ds2760_battery_work);
380 di->monitor_wqueue = create_singlethread_workqueue(pdev->dev.bus_id);
381 if (!di->monitor_wqueue) {
382 retval = -ESRCH;
383 goto workqueue_failed;
384 }
385 queue_delayed_work(di->monitor_wqueue, &di->monitor_work, HZ * 1);
386
387 goto success;
388
389workqueue_failed:
390 power_supply_unregister(&di->bat);
391batt_failed:
392 kfree(di);
393di_alloc_failed:
394success:
395 return retval;
396}
397
398static int ds2760_battery_remove(struct platform_device *pdev)
399{
400 struct ds2760_device_info *di = platform_get_drvdata(pdev);
401
402 cancel_rearming_delayed_workqueue(di->monitor_wqueue,
403 &di->monitor_work);
404 destroy_workqueue(di->monitor_wqueue);
405 power_supply_unregister(&di->bat);
406
407 return 0;
408}
409
410#ifdef CONFIG_PM
411
412static int ds2760_battery_suspend(struct platform_device *pdev,
413 pm_message_t state)
414{
415 struct ds2760_device_info *di = platform_get_drvdata(pdev);
416
417 di->charge_status = POWER_SUPPLY_STATUS_UNKNOWN;
418
419 return 0;
420}
421
422static int ds2760_battery_resume(struct platform_device *pdev)
423{
424 struct ds2760_device_info *di = platform_get_drvdata(pdev);
425
426 di->charge_status = POWER_SUPPLY_STATUS_UNKNOWN;
427 power_supply_changed(&di->bat);
428
429 cancel_delayed_work(&di->monitor_work);
430 queue_delayed_work(di->monitor_wqueue, &di->monitor_work, HZ);
431
432 return 0;
433}
434
435#else
436
437#define ds2760_battery_suspend NULL
438#define ds2760_battery_resume NULL
439
440#endif /* CONFIG_PM */
441
442static struct platform_driver ds2760_battery_driver = {
443 .driver = {
444 .name = "ds2760-battery",
445 },
446 .probe = ds2760_battery_probe,
447 .remove = ds2760_battery_remove,
448 .suspend = ds2760_battery_suspend,
449 .resume = ds2760_battery_resume,
450};
451
452static int __init ds2760_battery_init(void)
453{
454 return platform_driver_register(&ds2760_battery_driver);
455}
456
457static void __exit ds2760_battery_exit(void)
458{
459 platform_driver_unregister(&ds2760_battery_driver);
460 return;
461}
462
463module_init(ds2760_battery_init);
464module_exit(ds2760_battery_exit);
465
466MODULE_LICENSE("GPL");
467MODULE_AUTHOR("Szabolcs Gyurko <szabolcs.gyurko@tlt.hu>, "
468 "Matt Reimer <mreimer@vpop.net>, "
469 "Anton Vorontsov <cbou@mail.ru>");
470MODULE_DESCRIPTION("ds2760 battery driver");
diff --git a/drivers/power/olpc_battery.c b/drivers/power/olpc_battery.c
new file mode 100644
index 000000000000..878684df7667
--- /dev/null
+++ b/drivers/power/olpc_battery.c
@@ -0,0 +1,352 @@
1/*
2 * Battery driver for One Laptop Per Child board.
3 *
4 * Copyright © 2006 David Woodhouse <dwmw2@infradead.org>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/module.h>
12#include <linux/err.h>
13#include <linux/platform_device.h>
14#include <linux/power_supply.h>
15#include <linux/jiffies.h>
16#include <linux/sched.h>
17#include <asm/olpc.h>
18
19
20#define EC_BAT_VOLTAGE 0x10 /* uint16_t, *9.76/32, mV */
21#define EC_BAT_CURRENT 0x11 /* int16_t, *15.625/120, mA */
22#define EC_BAT_ACR 0x12
23#define EC_BAT_TEMP 0x13 /* uint16_t, *100/256, °C */
24#define EC_AMB_TEMP 0x14 /* uint16_t, *100/256, °C */
25#define EC_BAT_STATUS 0x15 /* uint8_t, bitmask */
26#define EC_BAT_SOC 0x16 /* uint8_t, percentage */
27#define EC_BAT_SERIAL 0x17 /* uint8_t[6] */
28#define EC_BAT_EEPROM 0x18 /* uint8_t adr as input, uint8_t output */
29#define EC_BAT_ERRCODE 0x1f /* uint8_t, bitmask */
30
31#define BAT_STAT_PRESENT 0x01
32#define BAT_STAT_FULL 0x02
33#define BAT_STAT_LOW 0x04
34#define BAT_STAT_DESTROY 0x08
35#define BAT_STAT_AC 0x10
36#define BAT_STAT_CHARGING 0x20
37#define BAT_STAT_DISCHARGING 0x40
38
39#define BAT_ERR_INFOFAIL 0x02
40#define BAT_ERR_OVERVOLTAGE 0x04
41#define BAT_ERR_OVERTEMP 0x05
42#define BAT_ERR_GAUGESTOP 0x06
43#define BAT_ERR_OUT_OF_CONTROL 0x07
44#define BAT_ERR_ID_FAIL 0x09
45#define BAT_ERR_ACR_FAIL 0x10
46
47#define BAT_ADDR_MFR_TYPE 0x5F
48
49/*********************************************************************
50 * Power
51 *********************************************************************/
52
53static int olpc_ac_get_prop(struct power_supply *psy,
54 enum power_supply_property psp,
55 union power_supply_propval *val)
56{
57 int ret = 0;
58 uint8_t status;
59
60 switch (psp) {
61 case POWER_SUPPLY_PROP_ONLINE:
62 ret = olpc_ec_cmd(EC_BAT_STATUS, NULL, 0, &status, 1);
63 if (ret)
64 return ret;
65
66 val->intval = !!(status & BAT_STAT_AC);
67 break;
68 default:
69 ret = -EINVAL;
70 break;
71 }
72 return ret;
73}
74
75static enum power_supply_property olpc_ac_props[] = {
76 POWER_SUPPLY_PROP_ONLINE,
77};
78
79static struct power_supply olpc_ac = {
80 .name = "olpc-ac",
81 .type = POWER_SUPPLY_TYPE_MAINS,
82 .properties = olpc_ac_props,
83 .num_properties = ARRAY_SIZE(olpc_ac_props),
84 .get_property = olpc_ac_get_prop,
85};
86
87/*********************************************************************
88 * Battery properties
89 *********************************************************************/
90static int olpc_bat_get_property(struct power_supply *psy,
91 enum power_supply_property psp,
92 union power_supply_propval *val)
93{
94 int ret = 0;
95 int16_t ec_word;
96 uint8_t ec_byte;
97
98 ret = olpc_ec_cmd(EC_BAT_STATUS, NULL, 0, &ec_byte, 1);
99 if (ret)
100 return ret;
101
102 /* Theoretically there's a race here -- the battery could be
103 removed immediately after we check whether it's present, and
104 then we query for some other property of the now-absent battery.
105 It doesn't matter though -- the EC will return the last-known
106 information, and it's as if we just ran that _little_ bit faster
107 and managed to read it out before the battery went away. */
108 if (!(ec_byte & BAT_STAT_PRESENT) && psp != POWER_SUPPLY_PROP_PRESENT)
109 return -ENODEV;
110
111 switch (psp) {
112 case POWER_SUPPLY_PROP_STATUS:
113 if (olpc_platform_info.ecver > 0x44) {
114 if (ec_byte & BAT_STAT_CHARGING)
115 val->intval = POWER_SUPPLY_STATUS_CHARGING;
116 else if (ec_byte & BAT_STAT_DISCHARGING)
117 val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
118 else if (ec_byte & BAT_STAT_FULL)
119 val->intval = POWER_SUPPLY_STATUS_FULL;
120 else /* er,... */
121 val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
122 } else {
123 /* Older EC didn't report charge/discharge bits */
124 if (!(ec_byte & BAT_STAT_AC)) /* No AC means discharging */
125 val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
126 else if (ec_byte & BAT_STAT_FULL)
127 val->intval = POWER_SUPPLY_STATUS_FULL;
128 else /* Not _necessarily_ true but EC doesn't tell all yet */
129 val->intval = POWER_SUPPLY_STATUS_CHARGING;
130 break;
131 }
132 case POWER_SUPPLY_PROP_PRESENT:
133 val->intval = !!(ec_byte & BAT_STAT_PRESENT);
134 break;
135
136 case POWER_SUPPLY_PROP_HEALTH:
137 if (ec_byte & BAT_STAT_DESTROY)
138 val->intval = POWER_SUPPLY_HEALTH_DEAD;
139 else {
140 ret = olpc_ec_cmd(EC_BAT_ERRCODE, NULL, 0, &ec_byte, 1);
141 if (ret)
142 return ret;
143
144 switch (ec_byte) {
145 case 0:
146 val->intval = POWER_SUPPLY_HEALTH_GOOD;
147 break;
148
149 case BAT_ERR_OVERTEMP:
150 val->intval = POWER_SUPPLY_HEALTH_OVERHEAT;
151 break;
152
153 case BAT_ERR_OVERVOLTAGE:
154 val->intval = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
155 break;
156
157 case BAT_ERR_INFOFAIL:
158 case BAT_ERR_OUT_OF_CONTROL:
159 case BAT_ERR_ID_FAIL:
160 case BAT_ERR_ACR_FAIL:
161 val->intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
162 break;
163
164 default:
165 /* Eep. We don't know this failure code */
166 return -EIO;
167 }
168 }
169 break;
170
171 case POWER_SUPPLY_PROP_MANUFACTURER:
172 ec_byte = BAT_ADDR_MFR_TYPE;
173 ret = olpc_ec_cmd(EC_BAT_EEPROM, &ec_byte, 1, &ec_byte, 1);
174 if (ret)
175 return ret;
176
177 switch (ec_byte >> 4) {
178 case 1:
179 val->strval = "Gold Peak";
180 break;
181 case 2:
182 val->strval = "BYD";
183 break;
184 default:
185 val->strval = "Unknown";
186 break;
187 }
188 break;
189 case POWER_SUPPLY_PROP_TECHNOLOGY:
190 ec_byte = BAT_ADDR_MFR_TYPE;
191 ret = olpc_ec_cmd(EC_BAT_EEPROM, &ec_byte, 1, &ec_byte, 1);
192 if (ret)
193 return ret;
194
195 switch (ec_byte & 0xf) {
196 case 1:
197 val->intval = POWER_SUPPLY_TECHNOLOGY_NiMH;
198 break;
199 case 2:
200 val->intval = POWER_SUPPLY_TECHNOLOGY_LiFe;
201 break;
202 default:
203 val->intval = POWER_SUPPLY_TECHNOLOGY_UNKNOWN;
204 break;
205 }
206 break;
207 case POWER_SUPPLY_PROP_VOLTAGE_AVG:
208 ret = olpc_ec_cmd(EC_BAT_VOLTAGE, NULL, 0, (void *)&ec_word, 2);
209 if (ret)
210 return ret;
211
212 ec_word = be16_to_cpu(ec_word);
213 val->intval = ec_word * 9760L / 32;
214 break;
215 case POWER_SUPPLY_PROP_CURRENT_AVG:
216 ret = olpc_ec_cmd(EC_BAT_CURRENT, NULL, 0, (void *)&ec_word, 2);
217 if (ret)
218 return ret;
219
220 ec_word = be16_to_cpu(ec_word);
221 val->intval = ec_word * 15625L / 120;
222 break;
223 case POWER_SUPPLY_PROP_CAPACITY:
224 ret = olpc_ec_cmd(EC_BAT_SOC, NULL, 0, &ec_byte, 1);
225 if (ret)
226 return ret;
227 val->intval = ec_byte;
228 break;
229 case POWER_SUPPLY_PROP_CAPACITY_LEVEL:
230 if (ec_byte & BAT_STAT_FULL)
231 val->intval = POWER_SUPPLY_CAPACITY_LEVEL_FULL;
232 else if (ec_byte & BAT_STAT_LOW)
233 val->intval = POWER_SUPPLY_CAPACITY_LEVEL_LOW;
234 else
235 val->intval = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL;
236 break;
237 case POWER_SUPPLY_PROP_TEMP:
238 ret = olpc_ec_cmd(EC_BAT_TEMP, NULL, 0, (void *)&ec_word, 2);
239 if (ret)
240 return ret;
241 ec_word = be16_to_cpu(ec_word);
242 val->intval = ec_word * 100 / 256;
243 break;
244 case POWER_SUPPLY_PROP_TEMP_AMBIENT:
245 ret = olpc_ec_cmd(EC_AMB_TEMP, NULL, 0, (void *)&ec_word, 2);
246 if (ret)
247 return ret;
248
249 ec_word = be16_to_cpu(ec_word);
250 val->intval = ec_word * 100 / 256;
251 break;
252 default:
253 ret = -EINVAL;
254 break;
255 }
256
257 return ret;
258}
259
260static enum power_supply_property olpc_bat_props[] = {
261 POWER_SUPPLY_PROP_STATUS,
262 POWER_SUPPLY_PROP_PRESENT,
263 POWER_SUPPLY_PROP_HEALTH,
264 POWER_SUPPLY_PROP_TECHNOLOGY,
265 POWER_SUPPLY_PROP_VOLTAGE_AVG,
266 POWER_SUPPLY_PROP_CURRENT_AVG,
267 POWER_SUPPLY_PROP_CAPACITY,
268 POWER_SUPPLY_PROP_CAPACITY_LEVEL,
269 POWER_SUPPLY_PROP_TEMP,
270 POWER_SUPPLY_PROP_TEMP_AMBIENT,
271 POWER_SUPPLY_PROP_MANUFACTURER,
272};
273
274/*********************************************************************
275 * Initialisation
276 *********************************************************************/
277
278static struct platform_device *bat_pdev;
279
280static struct power_supply olpc_bat = {
281 .properties = olpc_bat_props,
282 .num_properties = ARRAY_SIZE(olpc_bat_props),
283 .get_property = olpc_bat_get_property,
284 .use_for_apm = 1,
285};
286
287void olpc_battery_trigger_uevent(unsigned long cause)
288{
289 if (cause & EC_SCI_SRC_ACPWR)
290 kobject_uevent(&olpc_ac.dev->kobj, KOBJ_CHANGE);
291 if (cause & (EC_SCI_SRC_BATERR|EC_SCI_SRC_BATSOC|EC_SCI_SRC_BATTERY))
292 kobject_uevent(&olpc_bat.dev->kobj, KOBJ_CHANGE);
293}
294
295static int __init olpc_bat_init(void)
296{
297 int ret = 0;
298 uint8_t status;
299
300 if (!olpc_platform_info.ecver)
301 return -ENXIO;
302 if (olpc_platform_info.ecver < 0x43) {
303 printk(KERN_NOTICE "OLPC EC version 0x%02x too old for battery driver.\n", olpc_platform_info.ecver);
304 return -ENXIO;
305 }
306
307 ret = olpc_ec_cmd(EC_BAT_STATUS, NULL, 0, &status, 1);
308 if (ret)
309 return ret;
310
311 /* Ignore the status. It doesn't actually matter */
312
313 bat_pdev = platform_device_register_simple("olpc-battery", 0, NULL, 0);
314 if (IS_ERR(bat_pdev))
315 return PTR_ERR(bat_pdev);
316
317 ret = power_supply_register(&bat_pdev->dev, &olpc_ac);
318 if (ret)
319 goto ac_failed;
320
321 olpc_bat.name = bat_pdev->name;
322
323 ret = power_supply_register(&bat_pdev->dev, &olpc_bat);
324 if (ret)
325 goto battery_failed;
326
327 olpc_register_battery_callback(&olpc_battery_trigger_uevent);
328 goto success;
329
330battery_failed:
331 power_supply_unregister(&olpc_ac);
332ac_failed:
333 platform_device_unregister(bat_pdev);
334success:
335 return ret;
336}
337
338static void __exit olpc_bat_exit(void)
339{
340 olpc_deregister_battery_callback();
341 power_supply_unregister(&olpc_bat);
342 power_supply_unregister(&olpc_ac);
343 platform_device_unregister(bat_pdev);
344 return;
345}
346
347module_init(olpc_bat_init);
348module_exit(olpc_bat_exit);
349
350MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
351MODULE_LICENSE("GPL");
352MODULE_DESCRIPTION("Battery driver for One Laptop Per Child 'XO' machine");
diff --git a/drivers/power/pda_power.c b/drivers/power/pda_power.c
new file mode 100644
index 000000000000..4e1eb040e148
--- /dev/null
+++ b/drivers/power/pda_power.c
@@ -0,0 +1,261 @@
1/*
2 * Common power driver for PDAs and phones with one or two external
3 * power supplies (AC/USB) connected to main and backup batteries,
4 * and optional builtin charger.
5 *
6 * Copyright © 2007 Anton Vorontsov <cbou@mail.ru>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/module.h>
14#include <linux/platform_device.h>
15#include <linux/interrupt.h>
16#include <linux/power_supply.h>
17#include <linux/pda_power.h>
18#include <linux/timer.h>
19#include <linux/jiffies.h>
20
21static inline unsigned int get_irq_flags(struct resource *res)
22{
23 unsigned int flags = IRQF_DISABLED | IRQF_SHARED;
24
25 flags |= res->flags & IRQF_TRIGGER_MASK;
26
27 return flags;
28}
29
30static struct device *dev;
31static struct pda_power_pdata *pdata;
32static struct resource *ac_irq, *usb_irq;
33static struct timer_list charger_timer;
34static struct timer_list supply_timer;
35
36static int pda_power_get_property(struct power_supply *psy,
37 enum power_supply_property psp,
38 union power_supply_propval *val)
39{
40 switch (psp) {
41 case POWER_SUPPLY_PROP_ONLINE:
42 if (psy->type == POWER_SUPPLY_TYPE_MAINS)
43 val->intval = pdata->is_ac_online ?
44 pdata->is_ac_online() : 0;
45 else
46 val->intval = pdata->is_usb_online ?
47 pdata->is_usb_online() : 0;
48 break;
49 default:
50 return -EINVAL;
51 }
52 return 0;
53}
54
55static enum power_supply_property pda_power_props[] = {
56 POWER_SUPPLY_PROP_ONLINE,
57};
58
59static char *pda_power_supplied_to[] = {
60 "main-battery",
61 "backup-battery",
62};
63
64static struct power_supply pda_power_supplies[] = {
65 {
66 .name = "ac",
67 .type = POWER_SUPPLY_TYPE_MAINS,
68 .supplied_to = pda_power_supplied_to,
69 .num_supplicants = ARRAY_SIZE(pda_power_supplied_to),
70 .properties = pda_power_props,
71 .num_properties = ARRAY_SIZE(pda_power_props),
72 .get_property = pda_power_get_property,
73 },
74 {
75 .name = "usb",
76 .type = POWER_SUPPLY_TYPE_USB,
77 .supplied_to = pda_power_supplied_to,
78 .num_supplicants = ARRAY_SIZE(pda_power_supplied_to),
79 .properties = pda_power_props,
80 .num_properties = ARRAY_SIZE(pda_power_props),
81 .get_property = pda_power_get_property,
82 },
83};
84
85static void update_charger(void)
86{
87 if (!pdata->set_charge)
88 return;
89
90 if (pdata->is_ac_online && pdata->is_ac_online()) {
91 dev_dbg(dev, "charger on (AC)\n");
92 pdata->set_charge(PDA_POWER_CHARGE_AC);
93 } else if (pdata->is_usb_online && pdata->is_usb_online()) {
94 dev_dbg(dev, "charger on (USB)\n");
95 pdata->set_charge(PDA_POWER_CHARGE_USB);
96 } else {
97 dev_dbg(dev, "charger off\n");
98 pdata->set_charge(0);
99 }
100
101 return;
102}
103
104static void supply_timer_func(unsigned long irq)
105{
106 if (ac_irq && irq == ac_irq->start)
107 power_supply_changed(&pda_power_supplies[0]);
108 else if (usb_irq && irq == usb_irq->start)
109 power_supply_changed(&pda_power_supplies[1]);
110 return;
111}
112
113static void charger_timer_func(unsigned long irq)
114{
115 update_charger();
116
117 /* Okay, charger set. Now wait a bit before notifying supplicants,
118 * charge power should stabilize. */
119 supply_timer.data = irq;
120 mod_timer(&supply_timer,
121 jiffies + msecs_to_jiffies(pdata->wait_for_charger));
122 return;
123}
124
125static irqreturn_t power_changed_isr(int irq, void *unused)
126{
127 /* Wait a bit before reading ac/usb line status and setting charger,
128 * because ac/usb status readings may lag from irq. */
129 charger_timer.data = irq;
130 mod_timer(&charger_timer,
131 jiffies + msecs_to_jiffies(pdata->wait_for_status));
132 return IRQ_HANDLED;
133}
134
135static int pda_power_probe(struct platform_device *pdev)
136{
137 int ret = 0;
138
139 dev = &pdev->dev;
140
141 if (pdev->id != -1) {
142 dev_err(dev, "it's meaningless to register several "
143 "pda_powers; use id = -1\n");
144 ret = -EINVAL;
145 goto wrongid;
146 }
147
148 pdata = pdev->dev.platform_data;
149
150 update_charger();
151
152 if (!pdata->wait_for_status)
153 pdata->wait_for_status = 500;
154
155 if (!pdata->wait_for_charger)
156 pdata->wait_for_charger = 500;
157
158 setup_timer(&charger_timer, charger_timer_func, 0);
159 setup_timer(&supply_timer, supply_timer_func, 0);
160
161 ac_irq = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "ac");
162 usb_irq = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "usb");
163 if (!ac_irq && !usb_irq) {
164 dev_err(dev, "no ac/usb irq specified\n");
165 ret = -ENODEV;
166 goto noirqs;
167 }
168
169 if (pdata->supplied_to) {
170 pda_power_supplies[0].supplied_to = pdata->supplied_to;
171 pda_power_supplies[1].supplied_to = pdata->supplied_to;
172 pda_power_supplies[0].num_supplicants = pdata->num_supplicants;
173 pda_power_supplies[1].num_supplicants = pdata->num_supplicants;
174 }
175
176 ret = power_supply_register(&pdev->dev, &pda_power_supplies[0]);
177 if (ret) {
178 dev_err(dev, "failed to register %s power supply\n",
179 pda_power_supplies[0].name);
180 goto supply0_failed;
181 }
182
183 ret = power_supply_register(&pdev->dev, &pda_power_supplies[1]);
184 if (ret) {
185 dev_err(dev, "failed to register %s power supply\n",
186 pda_power_supplies[1].name);
187 goto supply1_failed;
188 }
189
190 if (ac_irq) {
191 ret = request_irq(ac_irq->start, power_changed_isr,
192 get_irq_flags(ac_irq), ac_irq->name,
193 &pda_power_supplies[0]);
194 if (ret) {
195 dev_err(dev, "request ac irq failed\n");
196 goto ac_irq_failed;
197 }
198 }
199
200 if (usb_irq) {
201 ret = request_irq(usb_irq->start, power_changed_isr,
202 get_irq_flags(usb_irq), usb_irq->name,
203 &pda_power_supplies[1]);
204 if (ret) {
205 dev_err(dev, "request usb irq failed\n");
206 goto usb_irq_failed;
207 }
208 }
209
210 goto success;
211
212usb_irq_failed:
213 if (ac_irq)
214 free_irq(ac_irq->start, &pda_power_supplies[0]);
215ac_irq_failed:
216 power_supply_unregister(&pda_power_supplies[1]);
217supply1_failed:
218 power_supply_unregister(&pda_power_supplies[0]);
219supply0_failed:
220noirqs:
221wrongid:
222success:
223 return ret;
224}
225
226static int pda_power_remove(struct platform_device *pdev)
227{
228 if (usb_irq)
229 free_irq(usb_irq->start, &pda_power_supplies[1]);
230 if (ac_irq)
231 free_irq(ac_irq->start, &pda_power_supplies[0]);
232 del_timer_sync(&charger_timer);
233 del_timer_sync(&supply_timer);
234 power_supply_unregister(&pda_power_supplies[1]);
235 power_supply_unregister(&pda_power_supplies[0]);
236 return 0;
237}
238
239static struct platform_driver pda_power_pdrv = {
240 .driver = {
241 .name = "pda-power",
242 },
243 .probe = pda_power_probe,
244 .remove = pda_power_remove,
245};
246
247static int __init pda_power_init(void)
248{
249 return platform_driver_register(&pda_power_pdrv);
250}
251
252static void __exit pda_power_exit(void)
253{
254 platform_driver_unregister(&pda_power_pdrv);
255 return;
256}
257
258module_init(pda_power_init);
259module_exit(pda_power_exit);
260MODULE_LICENSE("GPL");
261MODULE_AUTHOR("Anton Vorontsov <cbou@mail.ru>");
diff --git a/drivers/power/pmu_battery.c b/drivers/power/pmu_battery.c
new file mode 100644
index 000000000000..2fea4af0e40a
--- /dev/null
+++ b/drivers/power/pmu_battery.c
@@ -0,0 +1,215 @@
1/*
2 * Battery class driver for Apple PMU
3 *
4 * Copyright © 2006 David Woodhouse <dwmw2@infradead.org>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/module.h>
12#include <linux/platform_device.h>
13#include <linux/err.h>
14#include <linux/power_supply.h>
15#include <linux/adb.h>
16#include <linux/pmu.h>
17
18static struct pmu_battery_dev {
19 struct power_supply bat;
20 struct pmu_battery_info *pbi;
21 char name[16];
22 int propval;
23} *pbats[PMU_MAX_BATTERIES];
24
25#define to_pmu_battery_dev(x) container_of(x, struct pmu_battery_dev, bat)
26
27/*********************************************************************
28 * Power
29 *********************************************************************/
30
31static int pmu_get_ac_prop(struct power_supply *psy,
32 enum power_supply_property psp,
33 union power_supply_propval *val)
34{
35 switch (psp) {
36 case POWER_SUPPLY_PROP_ONLINE:
37 val->intval = (!!(pmu_power_flags & PMU_PWR_AC_PRESENT)) ||
38 (pmu_battery_count == 0);
39 break;
40 default:
41 return -EINVAL;
42 }
43
44 return 0;
45}
46
47static enum power_supply_property pmu_ac_props[] = {
48 POWER_SUPPLY_PROP_ONLINE,
49};
50
51static struct power_supply pmu_ac = {
52 .name = "pmu-ac",
53 .type = POWER_SUPPLY_TYPE_MAINS,
54 .properties = pmu_ac_props,
55 .num_properties = ARRAY_SIZE(pmu_ac_props),
56 .get_property = pmu_get_ac_prop,
57};
58
59/*********************************************************************
60 * Battery properties
61 *********************************************************************/
62
63static char *pmu_batt_types[] = {
64 "Smart", "Comet", "Hooper", "Unknown"
65};
66
67static char *pmu_bat_get_model_name(struct pmu_battery_info *pbi)
68{
69 switch (pbi->flags & PMU_BATT_TYPE_MASK) {
70 case PMU_BATT_TYPE_SMART:
71 return pmu_batt_types[0];
72 case PMU_BATT_TYPE_COMET:
73 return pmu_batt_types[1];
74 case PMU_BATT_TYPE_HOOPER:
75 return pmu_batt_types[2];
76 default: break;
77 }
78 return pmu_batt_types[3];
79}
80
81static int pmu_bat_get_property(struct power_supply *psy,
82 enum power_supply_property psp,
83 union power_supply_propval *val)
84{
85 struct pmu_battery_dev *pbat = to_pmu_battery_dev(psy);
86 struct pmu_battery_info *pbi = pbat->pbi;
87
88 switch (psp) {
89 case POWER_SUPPLY_PROP_STATUS:
90 if (pbi->flags & PMU_BATT_CHARGING)
91 val->intval = POWER_SUPPLY_STATUS_CHARGING;
92 else
93 val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
94 break;
95 case POWER_SUPPLY_PROP_PRESENT:
96 val->intval = !!(pbi->flags & PMU_BATT_PRESENT);
97 break;
98 case POWER_SUPPLY_PROP_MODEL_NAME:
99 val->strval = pmu_bat_get_model_name(pbi);
100 break;
101 case POWER_SUPPLY_PROP_ENERGY_AVG:
102 val->intval = pbi->charge * 1000; /* mWh -> µWh */
103 break;
104 case POWER_SUPPLY_PROP_ENERGY_FULL:
105 val->intval = pbi->max_charge * 1000; /* mWh -> µWh */
106 break;
107 case POWER_SUPPLY_PROP_CURRENT_AVG:
108 val->intval = pbi->amperage * 1000; /* mA -> µA */
109 break;
110 case POWER_SUPPLY_PROP_VOLTAGE_AVG:
111 val->intval = pbi->voltage * 1000; /* mV -> µV */
112 break;
113 case POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG:
114 val->intval = pbi->time_remaining;
115 break;
116 default:
117 return -EINVAL;
118 }
119
120 return 0;
121}
122
123static enum power_supply_property pmu_bat_props[] = {
124 POWER_SUPPLY_PROP_STATUS,
125 POWER_SUPPLY_PROP_PRESENT,
126 POWER_SUPPLY_PROP_MODEL_NAME,
127 POWER_SUPPLY_PROP_ENERGY_AVG,
128 POWER_SUPPLY_PROP_ENERGY_FULL,
129 POWER_SUPPLY_PROP_CURRENT_AVG,
130 POWER_SUPPLY_PROP_VOLTAGE_AVG,
131 POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG,
132};
133
134/*********************************************************************
135 * Initialisation
136 *********************************************************************/
137
138static struct platform_device *bat_pdev;
139
140static int __init pmu_bat_init(void)
141{
142 int ret;
143 int i;
144
145 bat_pdev = platform_device_register_simple("pmu-battery",
146 0, NULL, 0);
147 if (IS_ERR(bat_pdev)) {
148 ret = PTR_ERR(bat_pdev);
149 goto pdev_register_failed;
150 }
151
152 ret = power_supply_register(&bat_pdev->dev, &pmu_ac);
153 if (ret)
154 goto ac_register_failed;
155
156 for (i = 0; i < pmu_battery_count; i++) {
157 struct pmu_battery_dev *pbat = kzalloc(sizeof(*pbat),
158 GFP_KERNEL);
159 if (!pbat)
160 break;
161
162 sprintf(pbat->name, "PMU battery %d", i);
163 pbat->bat.name = pbat->name;
164 pbat->bat.properties = pmu_bat_props;
165 pbat->bat.num_properties = ARRAY_SIZE(pmu_bat_props);
166 pbat->bat.get_property = pmu_bat_get_property;
167 pbat->pbi = &pmu_batteries[i];
168
169 ret = power_supply_register(&bat_pdev->dev, &pbat->bat);
170 if (ret) {
171 kfree(pbat);
172 goto battery_register_failed;
173 }
174 pbats[i] = pbat;
175 }
176
177 goto success;
178
179battery_register_failed:
180 while (i--) {
181 if (!pbats[i])
182 continue;
183 power_supply_unregister(&pbats[i]->bat);
184 kfree(pbats[i]);
185 }
186 power_supply_unregister(&pmu_ac);
187ac_register_failed:
188 platform_device_unregister(bat_pdev);
189pdev_register_failed:
190success:
191 return ret;
192}
193
194static void __exit pmu_bat_exit(void)
195{
196 int i;
197
198 for (i = 0; i < PMU_MAX_BATTERIES; i++) {
199 if (!pbats[i])
200 continue;
201 power_supply_unregister(&pbats[i]->bat);
202 kfree(pbats[i]);
203 }
204 power_supply_unregister(&pmu_ac);
205 platform_device_unregister(bat_pdev);
206
207 return;
208}
209
210module_init(pmu_bat_init);
211module_exit(pmu_bat_exit);
212
213MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
214MODULE_LICENSE("GPL");
215MODULE_DESCRIPTION("PMU battery driver");
diff --git a/drivers/power/power_supply.h b/drivers/power/power_supply.h
new file mode 100644
index 000000000000..a9880d468ee4
--- /dev/null
+++ b/drivers/power/power_supply.h
@@ -0,0 +1,42 @@
1/*
2 * Functions private to power supply class
3 *
4 * Copyright © 2007 Anton Vorontsov <cbou@mail.ru>
5 * Copyright © 2004 Szabolcs Gyurko
6 * Copyright © 2003 Ian Molton <spyro@f2s.com>
7 *
8 * Modified: 2004, Oct Szabolcs Gyurko
9 *
10 * You may use this code as per GPL version 2
11 */
12
13#ifdef CONFIG_SYSFS
14
15extern int power_supply_create_attrs(struct power_supply *psy);
16extern void power_supply_remove_attrs(struct power_supply *psy);
17extern int power_supply_uevent(struct device *dev, char **envp, int num_envp,
18 char *buffer, int buffer_size);
19
20#else
21
22static inline int power_supply_create_attrs(struct power_supply *psy)
23{ return 0; }
24static inline void power_supply_remove_attrs(struct power_supply *psy) {}
25#define power_supply_uevent NULL
26
27#endif /* CONFIG_SYSFS */
28
29#ifdef CONFIG_LEDS_TRIGGERS
30
31extern void power_supply_update_leds(struct power_supply *psy);
32extern int power_supply_create_triggers(struct power_supply *psy);
33extern void power_supply_remove_triggers(struct power_supply *psy);
34
35#else
36
37static inline void power_supply_update_leds(struct power_supply *psy) {}
38static inline int power_supply_create_triggers(struct power_supply *psy)
39{ return 0; }
40static inline void power_supply_remove_triggers(struct power_supply *psy) {}
41
42#endif /* CONFIG_LEDS_TRIGGERS */
diff --git a/drivers/power/power_supply_core.c b/drivers/power/power_supply_core.c
new file mode 100644
index 000000000000..e87ea5156755
--- /dev/null
+++ b/drivers/power/power_supply_core.c
@@ -0,0 +1,168 @@
1/*
2 * Universal power supply monitor class
3 *
4 * Copyright © 2007 Anton Vorontsov <cbou@mail.ru>
5 * Copyright © 2004 Szabolcs Gyurko
6 * Copyright © 2003 Ian Molton <spyro@f2s.com>
7 *
8 * Modified: 2004, Oct Szabolcs Gyurko
9 *
10 * You may use this code as per GPL version 2
11 */
12
13#include <linux/module.h>
14#include <linux/types.h>
15#include <linux/init.h>
16#include <linux/device.h>
17#include <linux/err.h>
18#include <linux/power_supply.h>
19#include "power_supply.h"
20
21struct class *power_supply_class;
22
23static void power_supply_changed_work(struct work_struct *work)
24{
25 struct power_supply *psy = container_of(work, struct power_supply,
26 changed_work);
27 int i;
28
29 dev_dbg(psy->dev, "%s\n", __FUNCTION__);
30
31 for (i = 0; i < psy->num_supplicants; i++) {
32 struct device *dev;
33
34 down(&power_supply_class->sem);
35 list_for_each_entry(dev, &power_supply_class->devices, node) {
36 struct power_supply *pst = dev_get_drvdata(dev);
37
38 if (!strcmp(psy->supplied_to[i], pst->name)) {
39 if (pst->external_power_changed)
40 pst->external_power_changed(pst);
41 }
42 }
43 up(&power_supply_class->sem);
44 }
45
46 power_supply_update_leds(psy);
47
48 kobject_uevent(&psy->dev->kobj, KOBJ_CHANGE);
49
50 return;
51}
52
53void power_supply_changed(struct power_supply *psy)
54{
55 dev_dbg(psy->dev, "%s\n", __FUNCTION__);
56
57 schedule_work(&psy->changed_work);
58
59 return;
60}
61
62int power_supply_am_i_supplied(struct power_supply *psy)
63{
64 union power_supply_propval ret = {0,};
65 struct device *dev;
66
67 down(&power_supply_class->sem);
68 list_for_each_entry(dev, &power_supply_class->devices, node) {
69 struct power_supply *epsy = dev_get_drvdata(dev);
70 int i;
71
72 for (i = 0; i < epsy->num_supplicants; i++) {
73 if (!strcmp(epsy->supplied_to[i], psy->name)) {
74 if (epsy->get_property(epsy,
75 POWER_SUPPLY_PROP_ONLINE, &ret))
76 continue;
77 if (ret.intval)
78 goto out;
79 }
80 }
81 }
82out:
83 up(&power_supply_class->sem);
84
85 dev_dbg(psy->dev, "%s %d\n", __FUNCTION__, ret.intval);
86
87 return ret.intval;
88}
89
90int power_supply_register(struct device *parent, struct power_supply *psy)
91{
92 int rc = 0;
93
94 psy->dev = device_create(power_supply_class, parent, 0,
95 "%s", psy->name);
96 if (IS_ERR(psy->dev)) {
97 rc = PTR_ERR(psy->dev);
98 goto dev_create_failed;
99 }
100
101 dev_set_drvdata(psy->dev, psy);
102
103 INIT_WORK(&psy->changed_work, power_supply_changed_work);
104
105 rc = power_supply_create_attrs(psy);
106 if (rc)
107 goto create_attrs_failed;
108
109 rc = power_supply_create_triggers(psy);
110 if (rc)
111 goto create_triggers_failed;
112
113 power_supply_changed(psy);
114
115 goto success;
116
117create_triggers_failed:
118 power_supply_remove_attrs(psy);
119create_attrs_failed:
120 device_unregister(psy->dev);
121dev_create_failed:
122success:
123 return rc;
124}
125
126void power_supply_unregister(struct power_supply *psy)
127{
128 flush_scheduled_work();
129 power_supply_remove_triggers(psy);
130 power_supply_remove_attrs(psy);
131 device_unregister(psy->dev);
132 return;
133}
134
135static int __init power_supply_class_init(void)
136{
137 power_supply_class = class_create(THIS_MODULE, "power_supply");
138
139 if (IS_ERR(power_supply_class))
140 return PTR_ERR(power_supply_class);
141
142 power_supply_class->dev_uevent = power_supply_uevent;
143
144 return 0;
145}
146
147static void __exit power_supply_class_exit(void)
148{
149 class_destroy(power_supply_class);
150 return;
151}
152
153EXPORT_SYMBOL_GPL(power_supply_changed);
154EXPORT_SYMBOL_GPL(power_supply_am_i_supplied);
155EXPORT_SYMBOL_GPL(power_supply_register);
156EXPORT_SYMBOL_GPL(power_supply_unregister);
157
158/* exported for the APM Power driver, APM emulation */
159EXPORT_SYMBOL_GPL(power_supply_class);
160
161subsys_initcall(power_supply_class_init);
162module_exit(power_supply_class_exit);
163
164MODULE_DESCRIPTION("Universal power supply monitor class");
165MODULE_AUTHOR("Ian Molton <spyro@f2s.com>, "
166 "Szabolcs Gyurko, "
167 "Anton Vorontsov <cbou@mail.ru>");
168MODULE_LICENSE("GPL");
diff --git a/drivers/power/power_supply_leds.c b/drivers/power/power_supply_leds.c
new file mode 100644
index 000000000000..7232490bb595
--- /dev/null
+++ b/drivers/power/power_supply_leds.c
@@ -0,0 +1,176 @@
1/*
2 * LEDs triggers for power supply class
3 *
4 * Copyright © 2007 Anton Vorontsov <cbou@mail.ru>
5 * Copyright © 2004 Szabolcs Gyurko
6 * Copyright © 2003 Ian Molton <spyro@f2s.com>
7 *
8 * Modified: 2004, Oct Szabolcs Gyurko
9 *
10 * You may use this code as per GPL version 2
11 */
12
13#include <linux/power_supply.h>
14
15/* Battery specific LEDs triggers. */
16
17static void power_supply_update_bat_leds(struct power_supply *psy)
18{
19 union power_supply_propval status;
20
21 if (psy->get_property(psy, POWER_SUPPLY_PROP_STATUS, &status))
22 return;
23
24 dev_dbg(psy->dev, "%s %d\n", __FUNCTION__, status.intval);
25
26 switch (status.intval) {
27 case POWER_SUPPLY_STATUS_FULL:
28 led_trigger_event(psy->charging_full_trig, LED_FULL);
29 led_trigger_event(psy->charging_trig, LED_OFF);
30 led_trigger_event(psy->full_trig, LED_FULL);
31 break;
32 case POWER_SUPPLY_STATUS_CHARGING:
33 led_trigger_event(psy->charging_full_trig, LED_FULL);
34 led_trigger_event(psy->charging_trig, LED_FULL);
35 led_trigger_event(psy->full_trig, LED_OFF);
36 break;
37 default:
38 led_trigger_event(psy->charging_full_trig, LED_OFF);
39 led_trigger_event(psy->charging_trig, LED_OFF);
40 led_trigger_event(psy->full_trig, LED_OFF);
41 break;
42 }
43
44 return;
45}
46
47static int power_supply_create_bat_triggers(struct power_supply *psy)
48{
49 int rc = 0;
50
51 psy->charging_full_trig_name = kmalloc(strlen(psy->name) +
52 sizeof("-charging-or-full"), GFP_KERNEL);
53 if (!psy->charging_full_trig_name)
54 goto charging_full_failed;
55
56 psy->charging_trig_name = kmalloc(strlen(psy->name) +
57 sizeof("-charging"), GFP_KERNEL);
58 if (!psy->charging_trig_name)
59 goto charging_failed;
60
61 psy->full_trig_name = kmalloc(strlen(psy->name) +
62 sizeof("-full"), GFP_KERNEL);
63 if (!psy->full_trig_name)
64 goto full_failed;
65
66 strcpy(psy->charging_full_trig_name, psy->name);
67 strcat(psy->charging_full_trig_name, "-charging-or-full");
68 strcpy(psy->charging_trig_name, psy->name);
69 strcat(psy->charging_trig_name, "-charging");
70 strcpy(psy->full_trig_name, psy->name);
71 strcat(psy->full_trig_name, "-full");
72
73 led_trigger_register_simple(psy->charging_full_trig_name,
74 &psy->charging_full_trig);
75 led_trigger_register_simple(psy->charging_trig_name,
76 &psy->charging_trig);
77 led_trigger_register_simple(psy->full_trig_name,
78 &psy->full_trig);
79
80 goto success;
81
82full_failed:
83 kfree(psy->charging_trig_name);
84charging_failed:
85 kfree(psy->charging_full_trig_name);
86charging_full_failed:
87 rc = -ENOMEM;
88success:
89 return rc;
90}
91
92static void power_supply_remove_bat_triggers(struct power_supply *psy)
93{
94 led_trigger_unregister_simple(psy->charging_full_trig);
95 led_trigger_unregister_simple(psy->charging_trig);
96 led_trigger_unregister_simple(psy->full_trig);
97 kfree(psy->full_trig_name);
98 kfree(psy->charging_trig_name);
99 kfree(psy->charging_full_trig_name);
100 return;
101}
102
103/* Generated power specific LEDs triggers. */
104
105static void power_supply_update_gen_leds(struct power_supply *psy)
106{
107 union power_supply_propval online;
108
109 if (psy->get_property(psy, POWER_SUPPLY_PROP_ONLINE, &online))
110 return;
111
112 dev_dbg(psy->dev, "%s %d\n", __FUNCTION__, online.intval);
113
114 if (online.intval)
115 led_trigger_event(psy->online_trig, LED_FULL);
116 else
117 led_trigger_event(psy->online_trig, LED_OFF);
118
119 return;
120}
121
122static int power_supply_create_gen_triggers(struct power_supply *psy)
123{
124 int rc = 0;
125
126 psy->online_trig_name = kmalloc(strlen(psy->name) + sizeof("-online"),
127 GFP_KERNEL);
128 if (!psy->online_trig_name)
129 goto online_failed;
130
131 strcpy(psy->online_trig_name, psy->name);
132 strcat(psy->online_trig_name, "-online");
133
134 led_trigger_register_simple(psy->online_trig_name, &psy->online_trig);
135
136 goto success;
137
138online_failed:
139 rc = -ENOMEM;
140success:
141 return rc;
142}
143
144static void power_supply_remove_gen_triggers(struct power_supply *psy)
145{
146 led_trigger_unregister_simple(psy->online_trig);
147 kfree(psy->online_trig_name);
148 return;
149}
150
151/* Choice what triggers to create&update. */
152
153void power_supply_update_leds(struct power_supply *psy)
154{
155 if (psy->type == POWER_SUPPLY_TYPE_BATTERY)
156 power_supply_update_bat_leds(psy);
157 else
158 power_supply_update_gen_leds(psy);
159 return;
160}
161
162int power_supply_create_triggers(struct power_supply *psy)
163{
164 if (psy->type == POWER_SUPPLY_TYPE_BATTERY)
165 return power_supply_create_bat_triggers(psy);
166 return power_supply_create_gen_triggers(psy);
167}
168
169void power_supply_remove_triggers(struct power_supply *psy)
170{
171 if (psy->type == POWER_SUPPLY_TYPE_BATTERY)
172 power_supply_remove_bat_triggers(psy);
173 else
174 power_supply_remove_gen_triggers(psy);
175 return;
176}
diff --git a/drivers/power/power_supply_sysfs.c b/drivers/power/power_supply_sysfs.c
new file mode 100644
index 000000000000..c07d4258d347
--- /dev/null
+++ b/drivers/power/power_supply_sysfs.c
@@ -0,0 +1,299 @@
1/*
2 * Sysfs interface for the universal power supply monitor class
3 *
4 * Copyright © 2007 David Woodhouse <dwmw2@infradead.org>
5 * Copyright © 2007 Anton Vorontsov <cbou@mail.ru>
6 * Copyright © 2004 Szabolcs Gyurko
7 * Copyright © 2003 Ian Molton <spyro@f2s.com>
8 *
9 * Modified: 2004, Oct Szabolcs Gyurko
10 *
11 * You may use this code as per GPL version 2
12 */
13
14#include <linux/ctype.h>
15#include <linux/power_supply.h>
16
17/*
18 * This is because the name "current" breaks the device attr macro.
19 * The "current" word resolves to "(get_current())" so instead of
20 * "current" "(get_current())" appears in the sysfs.
21 *
22 * The source of this definition is the device.h which calls __ATTR
23 * macro in sysfs.h which calls the __stringify macro.
24 *
25 * Only modification that the name is not tried to be resolved
26 * (as a macro let's say).
27 */
28
29#define POWER_SUPPLY_ATTR(_name) \
30{ \
31 .attr = { .name = #_name, .mode = 0444, .owner = THIS_MODULE }, \
32 .show = power_supply_show_property, \
33 .store = NULL, \
34}
35
36static struct device_attribute power_supply_attrs[];
37
38static ssize_t power_supply_show_property(struct device *dev,
39 struct device_attribute *attr,
40 char *buf) {
41 static char *status_text[] = {
42 "Unknown", "Charging", "Discharging", "Not charging", "Full"
43 };
44 static char *health_text[] = {
45 "Unknown", "Good", "Overheat", "Dead", "Over voltage",
46 "Unspecified failure"
47 };
48 static char *technology_text[] = {
49 "Unknown", "NiMH", "Li-ion", "Li-poly", "LiFe", "NiCd"
50 };
51 static char *capacity_level_text[] = {
52 "Unknown", "Critical", "Low", "Normal", "High", "Full"
53 };
54 ssize_t ret;
55 struct power_supply *psy = dev_get_drvdata(dev);
56 const ptrdiff_t off = attr - power_supply_attrs;
57 union power_supply_propval value;
58
59 ret = psy->get_property(psy, off, &value);
60
61 if (ret < 0) {
62 if (ret != -ENODEV)
63 dev_err(dev, "driver failed to report `%s' property\n",
64 attr->attr.name);
65 return ret;
66 }
67
68 if (off == POWER_SUPPLY_PROP_STATUS)
69 return sprintf(buf, "%s\n", status_text[value.intval]);
70 else if (off == POWER_SUPPLY_PROP_HEALTH)
71 return sprintf(buf, "%s\n", health_text[value.intval]);
72 else if (off == POWER_SUPPLY_PROP_TECHNOLOGY)
73 return sprintf(buf, "%s\n", technology_text[value.intval]);
74 else if (off == POWER_SUPPLY_PROP_CAPACITY_LEVEL)
75 return sprintf(buf, "%s\n",
76 capacity_level_text[value.intval]);
77 else if (off >= POWER_SUPPLY_PROP_MODEL_NAME)
78 return sprintf(buf, "%s\n", value.strval);
79
80 return sprintf(buf, "%d\n", value.intval);
81}
82
83/* Must be in the same order as POWER_SUPPLY_PROP_* */
84static struct device_attribute power_supply_attrs[] = {
85 /* Properties of type `int' */
86 POWER_SUPPLY_ATTR(status),
87 POWER_SUPPLY_ATTR(health),
88 POWER_SUPPLY_ATTR(present),
89 POWER_SUPPLY_ATTR(online),
90 POWER_SUPPLY_ATTR(technology),
91 POWER_SUPPLY_ATTR(voltage_max_design),
92 POWER_SUPPLY_ATTR(voltage_min_design),
93 POWER_SUPPLY_ATTR(voltage_now),
94 POWER_SUPPLY_ATTR(voltage_avg),
95 POWER_SUPPLY_ATTR(current_now),
96 POWER_SUPPLY_ATTR(current_avg),
97 POWER_SUPPLY_ATTR(charge_full_design),
98 POWER_SUPPLY_ATTR(charge_empty_design),
99 POWER_SUPPLY_ATTR(charge_full),
100 POWER_SUPPLY_ATTR(charge_empty),
101 POWER_SUPPLY_ATTR(charge_now),
102 POWER_SUPPLY_ATTR(charge_avg),
103 POWER_SUPPLY_ATTR(energy_full_design),
104 POWER_SUPPLY_ATTR(energy_empty_design),
105 POWER_SUPPLY_ATTR(energy_full),
106 POWER_SUPPLY_ATTR(energy_empty),
107 POWER_SUPPLY_ATTR(energy_now),
108 POWER_SUPPLY_ATTR(energy_avg),
109 POWER_SUPPLY_ATTR(capacity),
110 POWER_SUPPLY_ATTR(capacity_level),
111 POWER_SUPPLY_ATTR(temp),
112 POWER_SUPPLY_ATTR(temp_ambient),
113 POWER_SUPPLY_ATTR(time_to_empty_now),
114 POWER_SUPPLY_ATTR(time_to_empty_avg),
115 POWER_SUPPLY_ATTR(time_to_full_now),
116 POWER_SUPPLY_ATTR(time_to_full_avg),
117 /* Properties of type `const char *' */
118 POWER_SUPPLY_ATTR(model_name),
119 POWER_SUPPLY_ATTR(manufacturer),
120};
121
122static ssize_t power_supply_show_static_attrs(struct device *dev,
123 struct device_attribute *attr,
124 char *buf) {
125 static char *type_text[] = { "Battery", "UPS", "Mains", "USB" };
126 struct power_supply *psy = dev_get_drvdata(dev);
127
128 return sprintf(buf, "%s\n", type_text[psy->type]);
129}
130
131static struct device_attribute power_supply_static_attrs[] = {
132 __ATTR(type, 0444, power_supply_show_static_attrs, NULL),
133};
134
135int power_supply_create_attrs(struct power_supply *psy)
136{
137 int rc = 0;
138 int i, j;
139
140 for (i = 0; i < ARRAY_SIZE(power_supply_static_attrs); i++) {
141 rc = device_create_file(psy->dev,
142 &power_supply_static_attrs[i]);
143 if (rc)
144 goto statics_failed;
145 }
146
147 for (j = 0; j < psy->num_properties; j++) {
148 rc = device_create_file(psy->dev,
149 &power_supply_attrs[psy->properties[j]]);
150 if (rc)
151 goto dynamics_failed;
152 }
153
154 goto succeed;
155
156dynamics_failed:
157 while (j--)
158 device_remove_file(psy->dev,
159 &power_supply_attrs[psy->properties[j]]);
160statics_failed:
161 while (i--)
162 device_remove_file(psy->dev,
163 &power_supply_static_attrs[psy->properties[i]]);
164succeed:
165 return rc;
166}
167
168void power_supply_remove_attrs(struct power_supply *psy)
169{
170 int i;
171
172 for (i = 0; i < ARRAY_SIZE(power_supply_static_attrs); i++)
173 device_remove_file(psy->dev,
174 &power_supply_static_attrs[i]);
175
176 for (i = 0; i < psy->num_properties; i++)
177 device_remove_file(psy->dev,
178 &power_supply_attrs[psy->properties[i]]);
179
180 return;
181}
182
183static char *kstruprdup(const char *str, gfp_t gfp)
184{
185 char *ret, *ustr;
186
187 ustr = ret = kmalloc(strlen(str) + 1, gfp);
188
189 if (!ret)
190 return NULL;
191
192 while (*str)
193 *ustr++ = toupper(*str++);
194
195 *ustr = 0;
196
197 return ret;
198}
199
200int power_supply_uevent(struct device *dev, char **envp, int num_envp,
201 char *buffer, int buffer_size)
202{
203 struct power_supply *psy = dev_get_drvdata(dev);
204 int i = 0, length = 0, ret = 0, j;
205 char *prop_buf;
206 char *attrname;
207
208 dev_dbg(dev, "uevent\n");
209
210 if (!psy) {
211 dev_dbg(dev, "No power supply yet\n");
212 return ret;
213 }
214
215 dev_dbg(dev, "POWER_SUPPLY_NAME=%s\n", psy->name);
216
217 ret = add_uevent_var(envp, num_envp, &i, buffer, buffer_size,
218 &length, "POWER_SUPPLY_NAME=%s", psy->name);
219 if (ret)
220 return ret;
221
222 prop_buf = (char *)get_zeroed_page(GFP_KERNEL);
223 if (!prop_buf)
224 return -ENOMEM;
225
226 for (j = 0; j < ARRAY_SIZE(power_supply_static_attrs); j++) {
227 struct device_attribute *attr;
228 char *line;
229
230 attr = &power_supply_static_attrs[j];
231
232 ret = power_supply_show_static_attrs(dev, attr, prop_buf);
233 if (ret < 0)
234 goto out;
235
236 line = strchr(prop_buf, '\n');
237 if (line)
238 *line = 0;
239
240 attrname = kstruprdup(attr->attr.name, GFP_KERNEL);
241 if (!attrname) {
242 ret = -ENOMEM;
243 goto out;
244 }
245
246 dev_dbg(dev, "Static prop %s=%s\n", attrname, prop_buf);
247
248 ret = add_uevent_var(envp, num_envp, &i, buffer, buffer_size,
249 &length, "POWER_SUPPLY_%s=%s",
250 attrname, prop_buf);
251 kfree(attrname);
252 if (ret)
253 goto out;
254 }
255
256 dev_dbg(dev, "%zd dynamic props\n", psy->num_properties);
257
258 for (j = 0; j < psy->num_properties; j++) {
259 struct device_attribute *attr;
260 char *line;
261
262 attr = &power_supply_attrs[psy->properties[j]];
263
264 ret = power_supply_show_property(dev, attr, prop_buf);
265 if (ret == -ENODEV) {
266 /* When a battery is absent, we expect -ENODEV. Don't abort;
267 send the uevent with at least the the PRESENT=0 property */
268 ret = 0;
269 continue;
270 }
271
272 if (ret < 0)
273 goto out;
274
275 line = strchr(prop_buf, '\n');
276 if (line)
277 *line = 0;
278
279 attrname = kstruprdup(attr->attr.name, GFP_KERNEL);
280 if (!attrname) {
281 ret = -ENOMEM;
282 goto out;
283 }
284
285 dev_dbg(dev, "prop %s=%s\n", attrname, prop_buf);
286
287 ret = add_uevent_var(envp, num_envp, &i, buffer, buffer_size,
288 &length, "POWER_SUPPLY_%s=%s",
289 attrname, prop_buf);
290 kfree(attrname);
291 if (ret)
292 goto out;
293 }
294
295out:
296 free_page((unsigned long)prop_buf);
297
298 return ret;
299}
diff --git a/drivers/s390/block/dasd_proc.c b/drivers/s390/block/dasd_proc.c
index 8b3b0f4a157c..ac7e8ef504cb 100644
--- a/drivers/s390/block/dasd_proc.c
+++ b/drivers/s390/block/dasd_proc.c
@@ -28,6 +28,7 @@ static struct proc_dir_entry *dasd_proc_root_entry = NULL;
28static struct proc_dir_entry *dasd_devices_entry = NULL; 28static struct proc_dir_entry *dasd_devices_entry = NULL;
29static struct proc_dir_entry *dasd_statistics_entry = NULL; 29static struct proc_dir_entry *dasd_statistics_entry = NULL;
30 30
31#ifdef CONFIG_DASD_PROFILE
31static char * 32static char *
32dasd_get_user_string(const char __user *user_buf, size_t user_len) 33dasd_get_user_string(const char __user *user_buf, size_t user_len)
33{ 34{
@@ -47,6 +48,7 @@ dasd_get_user_string(const char __user *user_buf, size_t user_len)
47 buffer[user_len] = 0; 48 buffer[user_len] = 0;
48 return buffer; 49 return buffer;
49} 50}
51#endif /* CONFIG_DASD_PROFILE */
50 52
51static int 53static int
52dasd_devices_show(struct seq_file *m, void *v) 54dasd_devices_show(struct seq_file *m, void *v)
@@ -167,6 +169,7 @@ dasd_calc_metrics(char *page, char **start, off_t off,
167 return len; 169 return len;
168} 170}
169 171
172#ifdef CONFIG_DASD_PROFILE
170static char * 173static char *
171dasd_statistics_array(char *str, unsigned int *array, int shift) 174dasd_statistics_array(char *str, unsigned int *array, int shift)
172{ 175{
@@ -180,6 +183,7 @@ dasd_statistics_array(char *str, unsigned int *array, int shift)
180 str += sprintf(str,"\n"); 183 str += sprintf(str,"\n");
181 return str; 184 return str;
182} 185}
186#endif /* CONFIG_DASD_PROFILE */
183 187
184static int 188static int
185dasd_statistics_read(char *page, char **start, off_t off, 189dasd_statistics_read(char *page, char **start, off_t off,
diff --git a/drivers/s390/char/sclp.h b/drivers/s390/char/sclp.h
index dbb99d1b6f57..c7318a125852 100644
--- a/drivers/s390/char/sclp.h
+++ b/drivers/s390/char/sclp.h
@@ -72,6 +72,18 @@ typedef unsigned int sclp_cmdw_t;
72 72
73typedef u32 sccb_mask_t; /* ATTENTION: assumes 32bit mask !!! */ 73typedef u32 sccb_mask_t; /* ATTENTION: assumes 32bit mask !!! */
74 74
75struct sccb_header {
76 u16 length;
77 u8 function_code;
78 u8 control_mask[3];
79 u16 response_code;
80} __attribute__((packed));
81
82extern u64 sclp_facilities;
83
84#define SCLP_HAS_CHP_INFO (sclp_facilities & 0x8000000000000000ULL)
85#define SCLP_HAS_CHP_RECONFIG (sclp_facilities & 0x2000000000000000ULL)
86
75struct gds_subvector { 87struct gds_subvector {
76 u8 length; 88 u8 length;
77 u8 key; 89 u8 key;
diff --git a/drivers/s390/char/sclp_chp.c b/drivers/s390/char/sclp_chp.c
index a66b914519b5..c68f5e7e63a0 100644
--- a/drivers/s390/char/sclp_chp.c
+++ b/drivers/s390/char/sclp_chp.c
@@ -55,6 +55,8 @@ static int do_configure(sclp_cmdw_t cmd)
55 struct chp_cfg_data *data; 55 struct chp_cfg_data *data;
56 int rc; 56 int rc;
57 57
58 if (!SCLP_HAS_CHP_RECONFIG)
59 return -EOPNOTSUPP;
58 /* Prepare sccb. */ 60 /* Prepare sccb. */
59 data = (struct chp_cfg_data *) get_zeroed_page(GFP_KERNEL | GFP_DMA); 61 data = (struct chp_cfg_data *) get_zeroed_page(GFP_KERNEL | GFP_DMA);
60 if (!data) 62 if (!data)
@@ -152,6 +154,8 @@ int sclp_chp_read_info(struct sclp_chp_info *info)
152 struct chp_info_data *data; 154 struct chp_info_data *data;
153 int rc; 155 int rc;
154 156
157 if (!SCLP_HAS_CHP_INFO)
158 return -EOPNOTSUPP;
155 /* Prepare sccb. */ 159 /* Prepare sccb. */
156 data = (struct chp_info_data *) get_zeroed_page(GFP_KERNEL | GFP_DMA); 160 data = (struct chp_info_data *) get_zeroed_page(GFP_KERNEL | GFP_DMA);
157 if (!data) 161 if (!data)
diff --git a/drivers/s390/char/sclp_info.c b/drivers/s390/char/sclp_info.c
index 7bcbe643b087..a1136e052750 100644
--- a/drivers/s390/char/sclp_info.c
+++ b/drivers/s390/char/sclp_info.c
@@ -11,47 +11,106 @@
11#include <asm/sclp.h> 11#include <asm/sclp.h>
12#include "sclp.h" 12#include "sclp.h"
13 13
14struct sclp_readinfo_sccb s390_readinfo_sccb; 14struct sclp_readinfo_sccb {
15 struct sccb_header header; /* 0-7 */
16 u16 rnmax; /* 8-9 */
17 u8 rnsize; /* 10 */
18 u8 _reserved0[24 - 11]; /* 11-23 */
19 u8 loadparm[8]; /* 24-31 */
20 u8 _reserved1[48 - 32]; /* 32-47 */
21 u64 facilities; /* 48-55 */
22 u8 _reserved2[91 - 56]; /* 56-90 */
23 u8 flags; /* 91 */
24 u8 _reserved3[100 - 92]; /* 92-99 */
25 u32 rnsize2; /* 100-103 */
26 u64 rnmax2; /* 104-111 */
27 u8 _reserved4[4096 - 112]; /* 112-4095 */
28} __attribute__((packed, aligned(4096)));
29
30static struct sclp_readinfo_sccb __initdata early_readinfo_sccb;
31static int __initdata early_readinfo_sccb_valid;
32
33u64 sclp_facilities;
15 34
16void __init sclp_readinfo_early(void) 35void __init sclp_readinfo_early(void)
17{ 36{
18 sclp_cmdw_t command;
19 struct sccb_header *sccb;
20 int ret; 37 int ret;
38 int i;
39 struct sclp_readinfo_sccb *sccb;
40 sclp_cmdw_t commands[] = {SCLP_CMDW_READ_SCP_INFO_FORCED,
41 SCLP_CMDW_READ_SCP_INFO};
21 42
22 __ctl_set_bit(0, 9); /* enable service signal subclass mask */ 43 /* Enable service signal subclass mask. */
23 44 __ctl_set_bit(0, 9);
24 sccb = &s390_readinfo_sccb.header; 45 sccb = &early_readinfo_sccb;
25 command = SCLP_CMDW_READ_SCP_INFO_FORCED; 46 for (i = 0; i < ARRAY_SIZE(commands); i++) {
26 while (1) { 47 do {
27 u16 response; 48 memset(sccb, 0, sizeof(*sccb));
28 49 sccb->header.length = sizeof(*sccb);
29 memset(&s390_readinfo_sccb, 0, sizeof(s390_readinfo_sccb)); 50 sccb->header.control_mask[2] = 0x80;
30 sccb->length = sizeof(s390_readinfo_sccb); 51 ret = sclp_service_call(commands[i], sccb);
31 sccb->control_mask[2] = 0x80; 52 } while (ret == -EBUSY);
32
33 ret = sclp_service_call(command, &s390_readinfo_sccb);
34
35 if (ret == -EIO)
36 goto out;
37 if (ret == -EBUSY)
38 continue;
39 53
54 if (ret)
55 break;
40 __load_psw_mask(PSW_BASE_BITS | PSW_MASK_EXT | 56 __load_psw_mask(PSW_BASE_BITS | PSW_MASK_EXT |
41 PSW_MASK_WAIT | PSW_DEFAULT_KEY); 57 PSW_MASK_WAIT | PSW_DEFAULT_KEY);
42 local_irq_disable(); 58 local_irq_disable();
59 /*
60 * Contents of the sccb might have changed
61 * therefore a barrier is needed.
62 */
43 barrier(); 63 barrier();
64 if (sccb->header.response_code == 0x10) {
65 early_readinfo_sccb_valid = 1;
66 break;
67 }
68 if (sccb->header.response_code != 0x1f0)
69 break;
70 }
71 /* Disable service signal subclass mask again. */
72 __ctl_clear_bit(0, 9);
73}
44 74
45 response = sccb->response_code; 75void __init sclp_facilities_detect(void)
76{
77 if (!early_readinfo_sccb_valid)
78 return;
79 sclp_facilities = early_readinfo_sccb.facilities;
80}
46 81
47 if (response == 0x10) 82unsigned long long __init sclp_memory_detect(void)
48 break; 83{
84 unsigned long long memsize;
85 struct sclp_readinfo_sccb *sccb;
49 86
50 if (response != 0x1f0 || command == SCLP_CMDW_READ_SCP_INFO) 87 if (!early_readinfo_sccb_valid)
51 break; 88 return 0;
89 sccb = &early_readinfo_sccb;
90 if (sccb->rnsize)
91 memsize = sccb->rnsize << 20;
92 else
93 memsize = sccb->rnsize2 << 20;
94 if (sccb->rnmax)
95 memsize *= sccb->rnmax;
96 else
97 memsize *= sccb->rnmax2;
98 return memsize;
99}
52 100
53 command = SCLP_CMDW_READ_SCP_INFO; 101/*
54 } 102 * This function will be called after sclp_memory_detect(), which gets called
55out: 103 * early from early.c code. Therefore the sccb should have valid contents.
56 __ctl_clear_bit(0, 9); /* disable service signal subclass mask */ 104 */
105void __init sclp_get_ipl_info(struct sclp_ipl_info *info)
106{
107 struct sclp_readinfo_sccb *sccb;
108
109 if (!early_readinfo_sccb_valid)
110 return;
111 sccb = &early_readinfo_sccb;
112 info->is_valid = 1;
113 if (sccb->flags & 0x2)
114 info->has_dump = 1;
115 memcpy(&info->loadparm, &sccb->loadparm, LOADPARM_LEN);
57} 116}
diff --git a/drivers/s390/char/vmcp.c b/drivers/s390/char/vmcp.c
index fce3dac5cb3e..82e6a6b253eb 100644
--- a/drivers/s390/char/vmcp.c
+++ b/drivers/s390/char/vmcp.c
@@ -175,13 +175,12 @@ static long vmcp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
175 175
176static const struct file_operations vmcp_fops = { 176static const struct file_operations vmcp_fops = {
177 .owner = THIS_MODULE, 177 .owner = THIS_MODULE,
178 .open = &vmcp_open, 178 .open = vmcp_open,
179 .release = &vmcp_release, 179 .release = vmcp_release,
180 .read = &vmcp_read, 180 .read = vmcp_read,
181 .llseek = &no_llseek, 181 .write = vmcp_write,
182 .write = &vmcp_write, 182 .unlocked_ioctl = vmcp_ioctl,
183 .unlocked_ioctl = &vmcp_ioctl, 183 .compat_ioctl = vmcp_ioctl
184 .compat_ioctl = &vmcp_ioctl
185}; 184};
186 185
187static struct miscdevice vmcp_dev = { 186static struct miscdevice vmcp_dev = {
diff --git a/drivers/s390/char/vmlogrdr.c b/drivers/s390/char/vmlogrdr.c
index a5a00e9ae4d0..12f7a4ce82c1 100644
--- a/drivers/s390/char/vmlogrdr.c
+++ b/drivers/s390/char/vmlogrdr.c
@@ -835,7 +835,7 @@ static void vmlogrdr_cleanup(void)
835} 835}
836 836
837 837
838static int vmlogrdr_init(void) 838static int __init vmlogrdr_init(void)
839{ 839{
840 int rc; 840 int rc;
841 int i; 841 int i;
@@ -885,7 +885,7 @@ cleanup:
885} 885}
886 886
887 887
888static void vmlogrdr_exit(void) 888static void __exit vmlogrdr_exit(void)
889{ 889{
890 vmlogrdr_cleanup(); 890 vmlogrdr_cleanup();
891 printk (KERN_INFO "vmlogrdr: driver unloaded\n"); 891 printk (KERN_INFO "vmlogrdr: driver unloaded\n");
diff --git a/drivers/s390/char/zcore.c b/drivers/s390/char/zcore.c
index 4e711a985d59..3712ede16723 100644
--- a/drivers/s390/char/zcore.c
+++ b/drivers/s390/char/zcore.c
@@ -156,7 +156,7 @@ static int memcpy_real(void *dest, unsigned long src, size_t count)
156 return rc; 156 return rc;
157} 157}
158 158
159static int memcpy_real_user(__user void *dest, unsigned long src, size_t count) 159static int memcpy_real_user(void __user *dest, unsigned long src, size_t count)
160{ 160{
161 static char buf[4096]; 161 static char buf[4096];
162 int offs = 0, size; 162 int offs = 0, size;
diff --git a/drivers/s390/cio/device_id.c b/drivers/s390/cio/device_id.c
index 997f46874537..60b9347f7c92 100644
--- a/drivers/s390/cio/device_id.c
+++ b/drivers/s390/cio/device_id.c
@@ -27,7 +27,6 @@
27/* 27/*
28 * diag210 is used under VM to get information about a virtual device 28 * diag210 is used under VM to get information about a virtual device
29 */ 29 */
30#ifdef CONFIG_64BIT
31int 30int
32diag210(struct diag210 * addr) 31diag210(struct diag210 * addr)
33{ 32{
@@ -43,6 +42,7 @@ diag210(struct diag210 * addr)
43 spin_lock_irqsave(&diag210_lock, flags); 42 spin_lock_irqsave(&diag210_lock, flags);
44 diag210_tmp = *addr; 43 diag210_tmp = *addr;
45 44
45#ifdef CONFIG_64BIT
46 asm volatile( 46 asm volatile(
47 " lhi %0,-1\n" 47 " lhi %0,-1\n"
48 " sam31\n" 48 " sam31\n"
@@ -51,19 +51,8 @@ diag210(struct diag210 * addr)
51 " srl %0,28\n" 51 " srl %0,28\n"
52 "1: sam64\n" 52 "1: sam64\n"
53 EX_TABLE(0b,1b) 53 EX_TABLE(0b,1b)
54 : "=&d" (ccode) : "a" (__pa(&diag210_tmp)) : "cc", "memory"); 54 : "=&d" (ccode) : "a" (&diag210_tmp) : "cc", "memory");
55
56 *addr = diag210_tmp;
57 spin_unlock_irqrestore(&diag210_lock, flags);
58
59 return ccode;
60}
61#else 55#else
62int
63diag210(struct diag210 * addr)
64{
65 int ccode;
66
67 asm volatile( 56 asm volatile(
68 " lhi %0,-1\n" 57 " lhi %0,-1\n"
69 " diag %1,0,0x210\n" 58 " diag %1,0,0x210\n"
@@ -71,11 +60,14 @@ diag210(struct diag210 * addr)
71 " srl %0,28\n" 60 " srl %0,28\n"
72 "1:\n" 61 "1:\n"
73 EX_TABLE(0b,1b) 62 EX_TABLE(0b,1b)
74 : "=&d" (ccode) : "a" (__pa(addr)) : "cc", "memory"); 63 : "=&d" (ccode) : "a" (&diag210_tmp) : "cc", "memory");
64#endif
65
66 *addr = diag210_tmp;
67 spin_unlock_irqrestore(&diag210_lock, flags);
75 68
76 return ccode; 69 return ccode;
77} 70}
78#endif
79 71
80/* 72/*
81 * Input : 73 * Input :
diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c
index 5aac0ec36368..90bd22014513 100644
--- a/drivers/s390/crypto/ap_bus.c
+++ b/drivers/s390/crypto/ap_bus.c
@@ -43,6 +43,7 @@ static void ap_poll_all(unsigned long);
43static void ap_poll_timeout(unsigned long); 43static void ap_poll_timeout(unsigned long);
44static int ap_poll_thread_start(void); 44static int ap_poll_thread_start(void);
45static void ap_poll_thread_stop(void); 45static void ap_poll_thread_stop(void);
46static void ap_request_timeout(unsigned long);
46 47
47/** 48/**
48 * Module description. 49 * Module description.
@@ -189,6 +190,7 @@ int ap_send(ap_qid_t qid, unsigned long long psmid, void *msg, size_t length)
189 case AP_RESPONSE_NORMAL: 190 case AP_RESPONSE_NORMAL:
190 return 0; 191 return 0;
191 case AP_RESPONSE_Q_FULL: 192 case AP_RESPONSE_Q_FULL:
193 case AP_RESPONSE_RESET_IN_PROGRESS:
192 return -EBUSY; 194 return -EBUSY;
193 default: /* Device is gone. */ 195 default: /* Device is gone. */
194 return -ENODEV; 196 return -ENODEV;
@@ -252,6 +254,8 @@ int ap_recv(ap_qid_t qid, unsigned long long *psmid, void *msg, size_t length)
252 if (status.queue_empty) 254 if (status.queue_empty)
253 return -ENOENT; 255 return -ENOENT;
254 return -EBUSY; 256 return -EBUSY;
257 case AP_RESPONSE_RESET_IN_PROGRESS:
258 return -EBUSY;
255 default: 259 default:
256 return -ENODEV; 260 return -ENODEV;
257 } 261 }
@@ -326,11 +330,12 @@ static int ap_init_queue(ap_qid_t qid)
326 i = AP_MAX_RESET; /* return with -ENODEV */ 330 i = AP_MAX_RESET; /* return with -ENODEV */
327 break; 331 break;
328 case AP_RESPONSE_RESET_IN_PROGRESS: 332 case AP_RESPONSE_RESET_IN_PROGRESS:
333 rc = -EBUSY;
329 case AP_RESPONSE_BUSY: 334 case AP_RESPONSE_BUSY:
330 default: 335 default:
331 break; 336 break;
332 } 337 }
333 if (rc != -ENODEV) 338 if (rc != -ENODEV && rc != -EBUSY)
334 break; 339 break;
335 if (i < AP_MAX_RESET - 1) { 340 if (i < AP_MAX_RESET - 1) {
336 udelay(5); 341 udelay(5);
@@ -341,6 +346,40 @@ static int ap_init_queue(ap_qid_t qid)
341} 346}
342 347
343/** 348/**
349 * Arm request timeout if a AP device was idle and a new request is submitted.
350 */
351static void ap_increase_queue_count(struct ap_device *ap_dev)
352{
353 int timeout = ap_dev->drv->request_timeout;
354
355 ap_dev->queue_count++;
356 if (ap_dev->queue_count == 1) {
357 mod_timer(&ap_dev->timeout, jiffies + timeout);
358 ap_dev->reset = AP_RESET_ARMED;
359 }
360}
361
362/**
363 * AP device is still alive, re-schedule request timeout if there are still
364 * pending requests.
365 */
366static void ap_decrease_queue_count(struct ap_device *ap_dev)
367{
368 int timeout = ap_dev->drv->request_timeout;
369
370 ap_dev->queue_count--;
371 if (ap_dev->queue_count > 0)
372 mod_timer(&ap_dev->timeout, jiffies + timeout);
373 else
374 /**
375 * The timeout timer should to be disabled now - since
376 * del_timer_sync() is very expensive, we just tell via the
377 * reset flag to ignore the pending timeout timer.
378 */
379 ap_dev->reset = AP_RESET_IGNORE;
380}
381
382/**
344 * AP device related attributes. 383 * AP device related attributes.
345 */ 384 */
346static ssize_t ap_hwtype_show(struct device *dev, 385static ssize_t ap_hwtype_show(struct device *dev,
@@ -498,6 +537,7 @@ static int ap_device_remove(struct device *dev)
498 struct ap_driver *ap_drv = ap_dev->drv; 537 struct ap_driver *ap_drv = ap_dev->drv;
499 538
500 ap_flush_queue(ap_dev); 539 ap_flush_queue(ap_dev);
540 del_timer_sync(&ap_dev->timeout);
501 if (ap_drv->remove) 541 if (ap_drv->remove)
502 ap_drv->remove(ap_dev); 542 ap_drv->remove(ap_dev);
503 spin_lock_bh(&ap_device_lock); 543 spin_lock_bh(&ap_device_lock);
@@ -759,17 +799,21 @@ static void ap_scan_bus(struct work_struct *unused)
759 __ap_scan_bus); 799 __ap_scan_bus);
760 rc = ap_query_queue(qid, &queue_depth, &device_type); 800 rc = ap_query_queue(qid, &queue_depth, &device_type);
761 if (dev) { 801 if (dev) {
802 if (rc == -EBUSY) {
803 set_current_state(TASK_UNINTERRUPTIBLE);
804 schedule_timeout(AP_RESET_TIMEOUT);
805 rc = ap_query_queue(qid, &queue_depth,
806 &device_type);
807 }
762 ap_dev = to_ap_dev(dev); 808 ap_dev = to_ap_dev(dev);
763 spin_lock_bh(&ap_dev->lock); 809 spin_lock_bh(&ap_dev->lock);
764 if (rc || ap_dev->unregistered) { 810 if (rc || ap_dev->unregistered) {
765 spin_unlock_bh(&ap_dev->lock); 811 spin_unlock_bh(&ap_dev->lock);
766 put_device(dev);
767 device_unregister(dev); 812 device_unregister(dev);
813 put_device(dev);
768 continue; 814 continue;
769 } else 815 }
770 spin_unlock_bh(&ap_dev->lock); 816 spin_unlock_bh(&ap_dev->lock);
771 }
772 if (dev) {
773 put_device(dev); 817 put_device(dev);
774 continue; 818 continue;
775 } 819 }
@@ -788,6 +832,8 @@ static void ap_scan_bus(struct work_struct *unused)
788 INIT_LIST_HEAD(&ap_dev->pendingq); 832 INIT_LIST_HEAD(&ap_dev->pendingq);
789 INIT_LIST_HEAD(&ap_dev->requestq); 833 INIT_LIST_HEAD(&ap_dev->requestq);
790 INIT_LIST_HEAD(&ap_dev->list); 834 INIT_LIST_HEAD(&ap_dev->list);
835 setup_timer(&ap_dev->timeout, ap_request_timeout,
836 (unsigned long) ap_dev);
791 if (device_type == 0) 837 if (device_type == 0)
792 ap_probe_device_type(ap_dev); 838 ap_probe_device_type(ap_dev);
793 else 839 else
@@ -853,7 +899,7 @@ static int ap_poll_read(struct ap_device *ap_dev, unsigned long *flags)
853 switch (status.response_code) { 899 switch (status.response_code) {
854 case AP_RESPONSE_NORMAL: 900 case AP_RESPONSE_NORMAL:
855 atomic_dec(&ap_poll_requests); 901 atomic_dec(&ap_poll_requests);
856 ap_dev->queue_count--; 902 ap_decrease_queue_count(ap_dev);
857 list_for_each_entry(ap_msg, &ap_dev->pendingq, list) { 903 list_for_each_entry(ap_msg, &ap_dev->pendingq, list) {
858 if (ap_msg->psmid != ap_dev->reply->psmid) 904 if (ap_msg->psmid != ap_dev->reply->psmid)
859 continue; 905 continue;
@@ -904,7 +950,7 @@ static int ap_poll_write(struct ap_device *ap_dev, unsigned long *flags)
904 switch (status.response_code) { 950 switch (status.response_code) {
905 case AP_RESPONSE_NORMAL: 951 case AP_RESPONSE_NORMAL:
906 atomic_inc(&ap_poll_requests); 952 atomic_inc(&ap_poll_requests);
907 ap_dev->queue_count++; 953 ap_increase_queue_count(ap_dev);
908 list_move_tail(&ap_msg->list, &ap_dev->pendingq); 954 list_move_tail(&ap_msg->list, &ap_dev->pendingq);
909 ap_dev->requestq_count--; 955 ap_dev->requestq_count--;
910 ap_dev->pendingq_count++; 956 ap_dev->pendingq_count++;
@@ -914,6 +960,7 @@ static int ap_poll_write(struct ap_device *ap_dev, unsigned long *flags)
914 *flags |= 2; 960 *flags |= 2;
915 break; 961 break;
916 case AP_RESPONSE_Q_FULL: 962 case AP_RESPONSE_Q_FULL:
963 case AP_RESPONSE_RESET_IN_PROGRESS:
917 *flags |= 2; 964 *flags |= 2;
918 break; 965 break;
919 case AP_RESPONSE_MESSAGE_TOO_BIG: 966 case AP_RESPONSE_MESSAGE_TOO_BIG:
@@ -960,10 +1007,11 @@ static int __ap_queue_message(struct ap_device *ap_dev, struct ap_message *ap_ms
960 list_add_tail(&ap_msg->list, &ap_dev->pendingq); 1007 list_add_tail(&ap_msg->list, &ap_dev->pendingq);
961 atomic_inc(&ap_poll_requests); 1008 atomic_inc(&ap_poll_requests);
962 ap_dev->pendingq_count++; 1009 ap_dev->pendingq_count++;
963 ap_dev->queue_count++; 1010 ap_increase_queue_count(ap_dev);
964 ap_dev->total_request_count++; 1011 ap_dev->total_request_count++;
965 break; 1012 break;
966 case AP_RESPONSE_Q_FULL: 1013 case AP_RESPONSE_Q_FULL:
1014 case AP_RESPONSE_RESET_IN_PROGRESS:
967 list_add_tail(&ap_msg->list, &ap_dev->requestq); 1015 list_add_tail(&ap_msg->list, &ap_dev->requestq);
968 ap_dev->requestq_count++; 1016 ap_dev->requestq_count++;
969 ap_dev->total_request_count++; 1017 ap_dev->total_request_count++;
@@ -1046,6 +1094,25 @@ static void ap_poll_timeout(unsigned long unused)
1046} 1094}
1047 1095
1048/** 1096/**
1097 * Reset a not responding AP device and move all requests from the
1098 * pending queue to the request queue.
1099 */
1100static void ap_reset(struct ap_device *ap_dev)
1101{
1102 int rc;
1103
1104 ap_dev->reset = AP_RESET_IGNORE;
1105 atomic_sub(ap_dev->queue_count, &ap_poll_requests);
1106 ap_dev->queue_count = 0;
1107 list_splice_init(&ap_dev->pendingq, &ap_dev->requestq);
1108 ap_dev->requestq_count += ap_dev->pendingq_count;
1109 ap_dev->pendingq_count = 0;
1110 rc = ap_init_queue(ap_dev->qid);
1111 if (rc == -ENODEV)
1112 ap_dev->unregistered = 1;
1113}
1114
1115/**
1049 * Poll all AP devices on the bus in a round robin fashion. Continue 1116 * Poll all AP devices on the bus in a round robin fashion. Continue
1050 * polling until bit 2^0 of the control flags is not set. If bit 2^1 1117 * polling until bit 2^0 of the control flags is not set. If bit 2^1
1051 * of the control flags has been set arm the poll timer. 1118 * of the control flags has been set arm the poll timer.
@@ -1056,6 +1123,8 @@ static int __ap_poll_all(struct ap_device *ap_dev, unsigned long *flags)
1056 if (!ap_dev->unregistered) { 1123 if (!ap_dev->unregistered) {
1057 if (ap_poll_queue(ap_dev, flags)) 1124 if (ap_poll_queue(ap_dev, flags))
1058 ap_dev->unregistered = 1; 1125 ap_dev->unregistered = 1;
1126 if (ap_dev->reset == AP_RESET_DO)
1127 ap_reset(ap_dev);
1059 } 1128 }
1060 spin_unlock(&ap_dev->lock); 1129 spin_unlock(&ap_dev->lock);
1061 return 0; 1130 return 0;
@@ -1147,6 +1216,17 @@ static void ap_poll_thread_stop(void)
1147 mutex_unlock(&ap_poll_thread_mutex); 1216 mutex_unlock(&ap_poll_thread_mutex);
1148} 1217}
1149 1218
1219/**
1220 * Handling of request timeouts
1221 */
1222static void ap_request_timeout(unsigned long data)
1223{
1224 struct ap_device *ap_dev = (struct ap_device *) data;
1225
1226 if (ap_dev->reset == AP_RESET_ARMED)
1227 ap_dev->reset = AP_RESET_DO;
1228}
1229
1150static void ap_reset_domain(void) 1230static void ap_reset_domain(void)
1151{ 1231{
1152 int i; 1232 int i;
diff --git a/drivers/s390/crypto/ap_bus.h b/drivers/s390/crypto/ap_bus.h
index 008559ea742b..87c2d6442875 100644
--- a/drivers/s390/crypto/ap_bus.h
+++ b/drivers/s390/crypto/ap_bus.h
@@ -33,6 +33,7 @@
33#define AP_DEVICES 64 /* Number of AP devices. */ 33#define AP_DEVICES 64 /* Number of AP devices. */
34#define AP_DOMAINS 16 /* Number of AP domains. */ 34#define AP_DOMAINS 16 /* Number of AP domains. */
35#define AP_MAX_RESET 90 /* Maximum number of resets. */ 35#define AP_MAX_RESET 90 /* Maximum number of resets. */
36#define AP_RESET_TIMEOUT (HZ/2) /* Time in ticks for reset timeouts. */
36#define AP_CONFIG_TIME 30 /* Time in seconds between AP bus rescans. */ 37#define AP_CONFIG_TIME 30 /* Time in seconds between AP bus rescans. */
37#define AP_POLL_TIME 1 /* Time in ticks between receive polls. */ 38#define AP_POLL_TIME 1 /* Time in ticks between receive polls. */
38 39
@@ -83,6 +84,13 @@ struct ap_queue_status {
83#define AP_DEVICE_TYPE_CEX2A 6 84#define AP_DEVICE_TYPE_CEX2A 6
84#define AP_DEVICE_TYPE_CEX2C 7 85#define AP_DEVICE_TYPE_CEX2C 7
85 86
87/**
88 * AP reset flag states
89 */
90#define AP_RESET_IGNORE 0 /* request timeout will be ignored */
91#define AP_RESET_ARMED 1 /* request timeout timer is active */
92#define AP_RESET_DO 2 /* AP reset required */
93
86struct ap_device; 94struct ap_device;
87struct ap_message; 95struct ap_message;
88 96
@@ -95,6 +103,7 @@ struct ap_driver {
95 /* receive is called from tasklet context */ 103 /* receive is called from tasklet context */
96 void (*receive)(struct ap_device *, struct ap_message *, 104 void (*receive)(struct ap_device *, struct ap_message *,
97 struct ap_message *); 105 struct ap_message *);
106 int request_timeout; /* request timeout in jiffies */
98}; 107};
99 108
100#define to_ap_drv(x) container_of((x), struct ap_driver, driver) 109#define to_ap_drv(x) container_of((x), struct ap_driver, driver)
@@ -112,6 +121,8 @@ struct ap_device {
112 int queue_depth; /* AP queue depth.*/ 121 int queue_depth; /* AP queue depth.*/
113 int device_type; /* AP device type. */ 122 int device_type; /* AP device type. */
114 int unregistered; /* marks AP device as unregistered */ 123 int unregistered; /* marks AP device as unregistered */
124 struct timer_list timeout; /* Timer for request timeouts. */
125 int reset; /* Reset required after req. timeout. */
115 126
116 int queue_count; /* # messages currently on AP queue. */ 127 int queue_count; /* # messages currently on AP queue. */
117 128
diff --git a/drivers/s390/crypto/zcrypt_cex2a.c b/drivers/s390/crypto/zcrypt_cex2a.c
index 5bb13a9d0898..08657f604b8c 100644
--- a/drivers/s390/crypto/zcrypt_cex2a.c
+++ b/drivers/s390/crypto/zcrypt_cex2a.c
@@ -70,6 +70,7 @@ static struct ap_driver zcrypt_cex2a_driver = {
70 .remove = zcrypt_cex2a_remove, 70 .remove = zcrypt_cex2a_remove,
71 .receive = zcrypt_cex2a_receive, 71 .receive = zcrypt_cex2a_receive,
72 .ids = zcrypt_cex2a_ids, 72 .ids = zcrypt_cex2a_ids,
73 .request_timeout = CEX2A_CLEANUP_TIME,
73}; 74};
74 75
75/** 76/**
@@ -306,18 +307,13 @@ static long zcrypt_cex2a_modexpo(struct zcrypt_device *zdev,
306 goto out_free; 307 goto out_free;
307 init_completion(&work); 308 init_completion(&work);
308 ap_queue_message(zdev->ap_dev, &ap_msg); 309 ap_queue_message(zdev->ap_dev, &ap_msg);
309 rc = wait_for_completion_interruptible_timeout( 310 rc = wait_for_completion_interruptible(&work);
310 &work, CEX2A_CLEANUP_TIME); 311 if (rc == 0)
311 if (rc > 0)
312 rc = convert_response(zdev, &ap_msg, mex->outputdata, 312 rc = convert_response(zdev, &ap_msg, mex->outputdata,
313 mex->outputdatalength); 313 mex->outputdatalength);
314 else { 314 else
315 /* Signal pending or message timed out. */ 315 /* Signal pending. */
316 ap_cancel_message(zdev->ap_dev, &ap_msg); 316 ap_cancel_message(zdev->ap_dev, &ap_msg);
317 if (rc == 0)
318 /* Message timed out. */
319 rc = -ETIME;
320 }
321out_free: 317out_free:
322 kfree(ap_msg.message); 318 kfree(ap_msg.message);
323 return rc; 319 return rc;
@@ -348,18 +344,13 @@ static long zcrypt_cex2a_modexpo_crt(struct zcrypt_device *zdev,
348 goto out_free; 344 goto out_free;
349 init_completion(&work); 345 init_completion(&work);
350 ap_queue_message(zdev->ap_dev, &ap_msg); 346 ap_queue_message(zdev->ap_dev, &ap_msg);
351 rc = wait_for_completion_interruptible_timeout( 347 rc = wait_for_completion_interruptible(&work);
352 &work, CEX2A_CLEANUP_TIME); 348 if (rc == 0)
353 if (rc > 0)
354 rc = convert_response(zdev, &ap_msg, crt->outputdata, 349 rc = convert_response(zdev, &ap_msg, crt->outputdata,
355 crt->outputdatalength); 350 crt->outputdatalength);
356 else { 351 else
357 /* Signal pending or message timed out. */ 352 /* Signal pending. */
358 ap_cancel_message(zdev->ap_dev, &ap_msg); 353 ap_cancel_message(zdev->ap_dev, &ap_msg);
359 if (rc == 0)
360 /* Message timed out. */
361 rc = -ETIME;
362 }
363out_free: 354out_free:
364 kfree(ap_msg.message); 355 kfree(ap_msg.message);
365 return rc; 356 return rc;
diff --git a/drivers/s390/crypto/zcrypt_pcica.c b/drivers/s390/crypto/zcrypt_pcica.c
index 818ffe05ac00..6e93b4751782 100644
--- a/drivers/s390/crypto/zcrypt_pcica.c
+++ b/drivers/s390/crypto/zcrypt_pcica.c
@@ -70,6 +70,7 @@ static struct ap_driver zcrypt_pcica_driver = {
70 .remove = zcrypt_pcica_remove, 70 .remove = zcrypt_pcica_remove,
71 .receive = zcrypt_pcica_receive, 71 .receive = zcrypt_pcica_receive,
72 .ids = zcrypt_pcica_ids, 72 .ids = zcrypt_pcica_ids,
73 .request_timeout = PCICA_CLEANUP_TIME,
73}; 74};
74 75
75/** 76/**
@@ -290,18 +291,13 @@ static long zcrypt_pcica_modexpo(struct zcrypt_device *zdev,
290 goto out_free; 291 goto out_free;
291 init_completion(&work); 292 init_completion(&work);
292 ap_queue_message(zdev->ap_dev, &ap_msg); 293 ap_queue_message(zdev->ap_dev, &ap_msg);
293 rc = wait_for_completion_interruptible_timeout( 294 rc = wait_for_completion_interruptible(&work);
294 &work, PCICA_CLEANUP_TIME); 295 if (rc == 0)
295 if (rc > 0)
296 rc = convert_response(zdev, &ap_msg, mex->outputdata, 296 rc = convert_response(zdev, &ap_msg, mex->outputdata,
297 mex->outputdatalength); 297 mex->outputdatalength);
298 else { 298 else
299 /* Signal pending or message timed out. */ 299 /* Signal pending. */
300 ap_cancel_message(zdev->ap_dev, &ap_msg); 300 ap_cancel_message(zdev->ap_dev, &ap_msg);
301 if (rc == 0)
302 /* Message timed out. */
303 rc = -ETIME;
304 }
305out_free: 301out_free:
306 kfree(ap_msg.message); 302 kfree(ap_msg.message);
307 return rc; 303 return rc;
@@ -332,18 +328,13 @@ static long zcrypt_pcica_modexpo_crt(struct zcrypt_device *zdev,
332 goto out_free; 328 goto out_free;
333 init_completion(&work); 329 init_completion(&work);
334 ap_queue_message(zdev->ap_dev, &ap_msg); 330 ap_queue_message(zdev->ap_dev, &ap_msg);
335 rc = wait_for_completion_interruptible_timeout( 331 rc = wait_for_completion_interruptible(&work);
336 &work, PCICA_CLEANUP_TIME); 332 if (rc == 0)
337 if (rc > 0)
338 rc = convert_response(zdev, &ap_msg, crt->outputdata, 333 rc = convert_response(zdev, &ap_msg, crt->outputdata,
339 crt->outputdatalength); 334 crt->outputdatalength);
340 else { 335 else
341 /* Signal pending or message timed out. */ 336 /* Signal pending. */
342 ap_cancel_message(zdev->ap_dev, &ap_msg); 337 ap_cancel_message(zdev->ap_dev, &ap_msg);
343 if (rc == 0)
344 /* Message timed out. */
345 rc = -ETIME;
346 }
347out_free: 338out_free:
348 kfree(ap_msg.message); 339 kfree(ap_msg.message);
349 return rc; 340 return rc;
diff --git a/drivers/s390/crypto/zcrypt_pcicc.c b/drivers/s390/crypto/zcrypt_pcicc.c
index f295a403b29a..d6d59bf9ac38 100644
--- a/drivers/s390/crypto/zcrypt_pcicc.c
+++ b/drivers/s390/crypto/zcrypt_pcicc.c
@@ -82,6 +82,7 @@ static struct ap_driver zcrypt_pcicc_driver = {
82 .remove = zcrypt_pcicc_remove, 82 .remove = zcrypt_pcicc_remove,
83 .receive = zcrypt_pcicc_receive, 83 .receive = zcrypt_pcicc_receive,
84 .ids = zcrypt_pcicc_ids, 84 .ids = zcrypt_pcicc_ids,
85 .request_timeout = PCICC_CLEANUP_TIME,
85}; 86};
86 87
87/** 88/**
@@ -501,18 +502,13 @@ static long zcrypt_pcicc_modexpo(struct zcrypt_device *zdev,
501 goto out_free; 502 goto out_free;
502 init_completion(&work); 503 init_completion(&work);
503 ap_queue_message(zdev->ap_dev, &ap_msg); 504 ap_queue_message(zdev->ap_dev, &ap_msg);
504 rc = wait_for_completion_interruptible_timeout( 505 rc = wait_for_completion_interruptible(&work);
505 &work, PCICC_CLEANUP_TIME); 506 if (rc == 0)
506 if (rc > 0)
507 rc = convert_response(zdev, &ap_msg, mex->outputdata, 507 rc = convert_response(zdev, &ap_msg, mex->outputdata,
508 mex->outputdatalength); 508 mex->outputdatalength);
509 else { 509 else
510 /* Signal pending or message timed out. */ 510 /* Signal pending. */
511 ap_cancel_message(zdev->ap_dev, &ap_msg); 511 ap_cancel_message(zdev->ap_dev, &ap_msg);
512 if (rc == 0)
513 /* Message timed out. */
514 rc = -ETIME;
515 }
516out_free: 512out_free:
517 free_page((unsigned long) ap_msg.message); 513 free_page((unsigned long) ap_msg.message);
518 return rc; 514 return rc;
@@ -544,18 +540,13 @@ static long zcrypt_pcicc_modexpo_crt(struct zcrypt_device *zdev,
544 goto out_free; 540 goto out_free;
545 init_completion(&work); 541 init_completion(&work);
546 ap_queue_message(zdev->ap_dev, &ap_msg); 542 ap_queue_message(zdev->ap_dev, &ap_msg);
547 rc = wait_for_completion_interruptible_timeout( 543 rc = wait_for_completion_interruptible(&work);
548 &work, PCICC_CLEANUP_TIME); 544 if (rc == 0)
549 if (rc > 0)
550 rc = convert_response(zdev, &ap_msg, crt->outputdata, 545 rc = convert_response(zdev, &ap_msg, crt->outputdata,
551 crt->outputdatalength); 546 crt->outputdatalength);
552 else { 547 else
553 /* Signal pending or message timed out. */ 548 /* Signal pending. */
554 ap_cancel_message(zdev->ap_dev, &ap_msg); 549 ap_cancel_message(zdev->ap_dev, &ap_msg);
555 if (rc == 0)
556 /* Message timed out. */
557 rc = -ETIME;
558 }
559out_free: 550out_free:
560 free_page((unsigned long) ap_msg.message); 551 free_page((unsigned long) ap_msg.message);
561 return rc; 552 return rc;
diff --git a/drivers/s390/crypto/zcrypt_pcixcc.c b/drivers/s390/crypto/zcrypt_pcixcc.c
index 252443b6bd1b..64948788d301 100644
--- a/drivers/s390/crypto/zcrypt_pcixcc.c
+++ b/drivers/s390/crypto/zcrypt_pcixcc.c
@@ -93,6 +93,7 @@ static struct ap_driver zcrypt_pcixcc_driver = {
93 .remove = zcrypt_pcixcc_remove, 93 .remove = zcrypt_pcixcc_remove,
94 .receive = zcrypt_pcixcc_receive, 94 .receive = zcrypt_pcixcc_receive,
95 .ids = zcrypt_pcixcc_ids, 95 .ids = zcrypt_pcixcc_ids,
96 .request_timeout = PCIXCC_CLEANUP_TIME,
96}; 97};
97 98
98/** 99/**
@@ -641,18 +642,13 @@ static long zcrypt_pcixcc_modexpo(struct zcrypt_device *zdev,
641 goto out_free; 642 goto out_free;
642 init_completion(&resp_type.work); 643 init_completion(&resp_type.work);
643 ap_queue_message(zdev->ap_dev, &ap_msg); 644 ap_queue_message(zdev->ap_dev, &ap_msg);
644 rc = wait_for_completion_interruptible_timeout( 645 rc = wait_for_completion_interruptible(&resp_type.work);
645 &resp_type.work, PCIXCC_CLEANUP_TIME); 646 if (rc == 0)
646 if (rc > 0)
647 rc = convert_response_ica(zdev, &ap_msg, mex->outputdata, 647 rc = convert_response_ica(zdev, &ap_msg, mex->outputdata,
648 mex->outputdatalength); 648 mex->outputdatalength);
649 else { 649 else
650 /* Signal pending or message timed out. */ 650 /* Signal pending. */
651 ap_cancel_message(zdev->ap_dev, &ap_msg); 651 ap_cancel_message(zdev->ap_dev, &ap_msg);
652 if (rc == 0)
653 /* Message timed out. */
654 rc = -ETIME;
655 }
656out_free: 652out_free:
657 free_page((unsigned long) ap_msg.message); 653 free_page((unsigned long) ap_msg.message);
658 return rc; 654 return rc;
@@ -685,18 +681,13 @@ static long zcrypt_pcixcc_modexpo_crt(struct zcrypt_device *zdev,
685 goto out_free; 681 goto out_free;
686 init_completion(&resp_type.work); 682 init_completion(&resp_type.work);
687 ap_queue_message(zdev->ap_dev, &ap_msg); 683 ap_queue_message(zdev->ap_dev, &ap_msg);
688 rc = wait_for_completion_interruptible_timeout( 684 rc = wait_for_completion_interruptible(&resp_type.work);
689 &resp_type.work, PCIXCC_CLEANUP_TIME); 685 if (rc == 0)
690 if (rc > 0)
691 rc = convert_response_ica(zdev, &ap_msg, crt->outputdata, 686 rc = convert_response_ica(zdev, &ap_msg, crt->outputdata,
692 crt->outputdatalength); 687 crt->outputdatalength);
693 else { 688 else
694 /* Signal pending or message timed out. */ 689 /* Signal pending. */
695 ap_cancel_message(zdev->ap_dev, &ap_msg); 690 ap_cancel_message(zdev->ap_dev, &ap_msg);
696 if (rc == 0)
697 /* Message timed out. */
698 rc = -ETIME;
699 }
700out_free: 691out_free:
701 free_page((unsigned long) ap_msg.message); 692 free_page((unsigned long) ap_msg.message);
702 return rc; 693 return rc;
@@ -729,17 +720,12 @@ static long zcrypt_pcixcc_send_cprb(struct zcrypt_device *zdev,
729 goto out_free; 720 goto out_free;
730 init_completion(&resp_type.work); 721 init_completion(&resp_type.work);
731 ap_queue_message(zdev->ap_dev, &ap_msg); 722 ap_queue_message(zdev->ap_dev, &ap_msg);
732 rc = wait_for_completion_interruptible_timeout( 723 rc = wait_for_completion_interruptible(&resp_type.work);
733 &resp_type.work, PCIXCC_CLEANUP_TIME); 724 if (rc == 0)
734 if (rc > 0)
735 rc = convert_response_xcrb(zdev, &ap_msg, xcRB); 725 rc = convert_response_xcrb(zdev, &ap_msg, xcRB);
736 else { 726 else
737 /* Signal pending or message timed out. */ 727 /* Signal pending. */
738 ap_cancel_message(zdev->ap_dev, &ap_msg); 728 ap_cancel_message(zdev->ap_dev, &ap_msg);
739 if (rc == 0)
740 /* Message timed out. */
741 rc = -ETIME;
742 }
743out_free: 729out_free:
744 memset(ap_msg.message, 0x0, ap_msg.length); 730 memset(ap_msg.message, 0x0, ap_msg.length);
745 kfree(ap_msg.message); 731 kfree(ap_msg.message);
diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c
index 6b76babc7fbf..a0ea43598515 100644
--- a/drivers/serial/serial_cs.c
+++ b/drivers/serial/serial_cs.c
@@ -842,12 +842,16 @@ static struct pcmcia_device_id serial_ids[] = {
842 PCMCIA_PFC_DEVICE_PROD_ID12(1, "Linksys", "EtherFast 10&100 + 56K PC Card (PCMLM56)", 0x0733cc81, 0xb3765033), 842 PCMCIA_PFC_DEVICE_PROD_ID12(1, "Linksys", "EtherFast 10&100 + 56K PC Card (PCMLM56)", 0x0733cc81, 0xb3765033),
843 PCMCIA_PFC_DEVICE_PROD_ID12(1, "LINKSYS", "PCMLM336", 0xf7cb0b07, 0x7a821b58), 843 PCMCIA_PFC_DEVICE_PROD_ID12(1, "LINKSYS", "PCMLM336", 0xf7cb0b07, 0x7a821b58),
844 PCMCIA_PFC_DEVICE_PROD_ID12(1, "MEGAHERTZ", "XJEM1144/CCEM1144", 0xf510db04, 0x52d21e1e), 844 PCMCIA_PFC_DEVICE_PROD_ID12(1, "MEGAHERTZ", "XJEM1144/CCEM1144", 0xf510db04, 0x52d21e1e),
845 PCMCIA_PFC_DEVICE_PROD_ID12(1, "MICRO RESEARCH", "COMBO-L/M-336", 0xb2ced065, 0x3ced0555),
846 PCMCIA_PFC_DEVICE_PROD_ID12(1, "NEC", "PK-UG-J001" ,0x18df0ba0 ,0x831b1064),
845 PCMCIA_PFC_DEVICE_PROD_ID12(1, "Ositech", "Trumpcard:Jack of Diamonds Modem+Ethernet", 0xc2f80cd, 0x656947b9), 847 PCMCIA_PFC_DEVICE_PROD_ID12(1, "Ositech", "Trumpcard:Jack of Diamonds Modem+Ethernet", 0xc2f80cd, 0x656947b9),
846 PCMCIA_PFC_DEVICE_PROD_ID12(1, "Ositech", "Trumpcard:Jack of Hearts Modem+Ethernet", 0xc2f80cd, 0xdc9ba5ed), 848 PCMCIA_PFC_DEVICE_PROD_ID12(1, "Ositech", "Trumpcard:Jack of Hearts Modem+Ethernet", 0xc2f80cd, 0xdc9ba5ed),
847 PCMCIA_PFC_DEVICE_PROD_ID12(1, "PCMCIAs", "ComboCard", 0xdcfe12d3, 0xcd8906cc), 849 PCMCIA_PFC_DEVICE_PROD_ID12(1, "PCMCIAs", "ComboCard", 0xdcfe12d3, 0xcd8906cc),
848 PCMCIA_PFC_DEVICE_PROD_ID12(1, "PCMCIAs", "LanModem", 0xdcfe12d3, 0xc67c648f), 850 PCMCIA_PFC_DEVICE_PROD_ID12(1, "PCMCIAs", "LanModem", 0xdcfe12d3, 0xc67c648f),
849 PCMCIA_PFC_DEVICE_PROD_ID12(1, "TDK", "GlobalNetworker 3410/3412", 0x1eae9475, 0xd9a93bed), 851 PCMCIA_PFC_DEVICE_PROD_ID12(1, "TDK", "GlobalNetworker 3410/3412", 0x1eae9475, 0xd9a93bed),
850 PCMCIA_PFC_DEVICE_PROD_ID12(1, "Xircom", "CreditCard Ethernet+Modem II", 0x2e3ee845, 0xeca401bf), 852 PCMCIA_PFC_DEVICE_PROD_ID12(1, "Xircom", "CreditCard Ethernet+Modem II", 0x2e3ee845, 0xeca401bf),
853 PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0032, 0x0a05),
854 PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0032, 0x1101),
851 PCMCIA_MFC_DEVICE_MANF_CARD(0, 0x0104, 0x0070), 855 PCMCIA_MFC_DEVICE_MANF_CARD(0, 0x0104, 0x0070),
852 PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x0101, 0x0562), 856 PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x0101, 0x0562),
853 PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x0104, 0x0070), 857 PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x0104, 0x0070),
diff --git a/drivers/tc/zs.c b/drivers/tc/zs.c
index 61de78a9f6ee..4fff61b32dcb 100644
--- a/drivers/tc/zs.c
+++ b/drivers/tc/zs.c
@@ -143,7 +143,7 @@ static struct console sercons;
143static unsigned long break_pressed; /* break, really ... */ 143static unsigned long break_pressed; /* break, really ... */
144#endif 144#endif
145 145
146static unsigned char zs_init_regs[16] __initdata = { 146static unsigned char zs_init_regs[16] = {
147 0, /* write 0 */ 147 0, /* write 0 */
148 0, /* write 1 */ 148 0, /* write 1 */
149 0, /* write 2 */ 149 0, /* write 2 */
@@ -1581,7 +1581,7 @@ static void __init show_serial_version(void)
1581/* Initialize Z8530s zs_channels 1581/* Initialize Z8530s zs_channels
1582 */ 1582 */
1583 1583
1584static void __init probe_sccs(void) 1584static void probe_sccs(void)
1585{ 1585{
1586 struct dec_serial **pp; 1586 struct dec_serial **pp;
1587 int i, n, n_chips = 0, n_channels, chip, channel; 1587 int i, n, n_chips = 0, n_channels, chip, channel;
@@ -1923,7 +1923,7 @@ static struct tty_driver *serial_console_device(struct console *c, int *index)
1923 * - initialize the serial port 1923 * - initialize the serial port
1924 * Return non-zero if we didn't find a serial port. 1924 * Return non-zero if we didn't find a serial port.
1925 */ 1925 */
1926static int __init serial_console_setup(struct console *co, char *options) 1926static int serial_console_setup(struct console *co, char *options)
1927{ 1927{
1928 struct dec_serial *info; 1928 struct dec_serial *info;
1929 int baud = 9600; 1929 int baud = 9600;
diff --git a/drivers/w1/slaves/Kconfig b/drivers/w1/slaves/Kconfig
index 904e5aeb696c..df95d6c2cefa 100644
--- a/drivers/w1/slaves/Kconfig
+++ b/drivers/w1/slaves/Kconfig
@@ -35,4 +35,17 @@ config W1_SLAVE_DS2433_CRC
35 Each block has 30 bytes of data and a two byte CRC16. 35 Each block has 30 bytes of data and a two byte CRC16.
36 Full block writes are only allowed if the CRC is valid. 36 Full block writes are only allowed if the CRC is valid.
37 37
38config W1_SLAVE_DS2760
39 tristate "Dallas 2760 battery monitor chip (HP iPAQ & others)"
40 depends on W1
41 help
42 If you enable this you will have the DS2760 battery monitor
43 chip support.
44
45 The battery monitor chip is used in many batteries/devices
46 as the one who is responsible for charging/discharging/monitoring
47 Li+ batteries.
48
49 If you are unsure, say N.
50
38endmenu 51endmenu
diff --git a/drivers/w1/slaves/Makefile b/drivers/w1/slaves/Makefile
index 725dcfdfddb4..a8eb7524df1d 100644
--- a/drivers/w1/slaves/Makefile
+++ b/drivers/w1/slaves/Makefile
@@ -5,4 +5,5 @@
5obj-$(CONFIG_W1_SLAVE_THERM) += w1_therm.o 5obj-$(CONFIG_W1_SLAVE_THERM) += w1_therm.o
6obj-$(CONFIG_W1_SLAVE_SMEM) += w1_smem.o 6obj-$(CONFIG_W1_SLAVE_SMEM) += w1_smem.o
7obj-$(CONFIG_W1_SLAVE_DS2433) += w1_ds2433.o 7obj-$(CONFIG_W1_SLAVE_DS2433) += w1_ds2433.o
8obj-$(CONFIG_W1_SLAVE_DS2760) += w1_ds2760.o
8 9
diff --git a/drivers/w1/slaves/w1_ds2760.c b/drivers/w1/slaves/w1_ds2760.c
new file mode 100644
index 000000000000..88a37fbccc3f
--- /dev/null
+++ b/drivers/w1/slaves/w1_ds2760.c
@@ -0,0 +1,213 @@
1/*
2 * 1-Wire implementation for the ds2760 chip
3 *
4 * Copyright © 2004-2005, Szabolcs Gyurko <szabolcs.gyurko@tlt.hu>
5 *
6 * Use consistent with the GNU GPL is permitted,
7 * provided that this copyright notice is
8 * preserved in its entirety in all copies and derived works.
9 *
10 */
11
12#include <linux/kernel.h>
13#include <linux/module.h>
14#include <linux/device.h>
15#include <linux/types.h>
16#include <linux/platform_device.h>
17#include <linux/mutex.h>
18#include <linux/idr.h>
19
20#include "../w1.h"
21#include "../w1_int.h"
22#include "../w1_family.h"
23#include "w1_ds2760.h"
24
25static int w1_ds2760_io(struct device *dev, char *buf, int addr, size_t count,
26 int io)
27{
28 struct w1_slave *sl = container_of(dev, struct w1_slave, dev);
29
30 if (!dev)
31 return 0;
32
33 mutex_lock(&sl->master->mutex);
34
35 if (addr > DS2760_DATA_SIZE || addr < 0) {
36 count = 0;
37 goto out;
38 }
39 if (addr + count > DS2760_DATA_SIZE)
40 count = DS2760_DATA_SIZE - addr;
41
42 if (!w1_reset_select_slave(sl)) {
43 if (!io) {
44 w1_write_8(sl->master, W1_DS2760_READ_DATA);
45 w1_write_8(sl->master, addr);
46 count = w1_read_block(sl->master, buf, count);
47 } else {
48 w1_write_8(sl->master, W1_DS2760_WRITE_DATA);
49 w1_write_8(sl->master, addr);
50 w1_write_block(sl->master, buf, count);
51 /* XXX w1_write_block returns void, not n_written */
52 }
53 }
54
55out:
56 mutex_unlock(&sl->master->mutex);
57
58 return count;
59}
60
61int w1_ds2760_read(struct device *dev, char *buf, int addr, size_t count)
62{
63 return w1_ds2760_io(dev, buf, addr, count, 0);
64}
65
66int w1_ds2760_write(struct device *dev, char *buf, int addr, size_t count)
67{
68 return w1_ds2760_io(dev, buf, addr, count, 1);
69}
70
71static ssize_t w1_ds2760_read_bin(struct kobject *kobj, char *buf, loff_t off,
72 size_t count)
73{
74 struct device *dev = container_of(kobj, struct device, kobj);
75 return w1_ds2760_read(dev, buf, off, count);
76}
77
78static struct bin_attribute w1_ds2760_bin_attr = {
79 .attr = {
80 .name = "w1_slave",
81 .mode = S_IRUGO,
82 .owner = THIS_MODULE,
83 },
84 .size = DS2760_DATA_SIZE,
85 .read = w1_ds2760_read_bin,
86};
87
88static DEFINE_IDR(bat_idr);
89static DEFINE_MUTEX(bat_idr_lock);
90
91static int new_bat_id(void)
92{
93 int ret;
94
95 while (1) {
96 int id;
97
98 ret = idr_pre_get(&bat_idr, GFP_KERNEL);
99 if (ret == 0)
100 return -ENOMEM;
101
102 mutex_lock(&bat_idr_lock);
103 ret = idr_get_new(&bat_idr, NULL, &id);
104 mutex_unlock(&bat_idr_lock);
105
106 if (ret == 0) {
107 ret = id & MAX_ID_MASK;
108 break;
109 } else if (ret == -EAGAIN) {
110 continue;
111 } else {
112 break;
113 }
114 }
115
116 return ret;
117}
118
119static void release_bat_id(int id)
120{
121 mutex_lock(&bat_idr_lock);
122 idr_remove(&bat_idr, id);
123 mutex_unlock(&bat_idr_lock);
124
125 return;
126}
127
128static int w1_ds2760_add_slave(struct w1_slave *sl)
129{
130 int ret;
131 int id;
132 struct platform_device *pdev;
133
134 id = new_bat_id();
135 if (id < 0) {
136 ret = id;
137 goto noid;
138 }
139
140 pdev = platform_device_alloc("ds2760-battery", id);
141 if (!pdev) {
142 ret = -ENOMEM;
143 goto pdev_alloc_failed;
144 }
145 pdev->dev.parent = &sl->dev;
146
147 ret = platform_device_add(pdev);
148 if (ret)
149 goto pdev_add_failed;
150
151 ret = sysfs_create_bin_file(&sl->dev.kobj, &w1_ds2760_bin_attr);
152 if (ret)
153 goto bin_attr_failed;
154
155 dev_set_drvdata(&sl->dev, pdev);
156
157 goto success;
158
159bin_attr_failed:
160pdev_add_failed:
161 platform_device_unregister(pdev);
162pdev_alloc_failed:
163 release_bat_id(id);
164noid:
165success:
166 return ret;
167}
168
169static void w1_ds2760_remove_slave(struct w1_slave *sl)
170{
171 struct platform_device *pdev = dev_get_drvdata(&sl->dev);
172 int id = pdev->id;
173
174 platform_device_unregister(pdev);
175 release_bat_id(id);
176 sysfs_remove_bin_file(&sl->dev.kobj, &w1_ds2760_bin_attr);
177
178 return;
179}
180
181static struct w1_family_ops w1_ds2760_fops = {
182 .add_slave = w1_ds2760_add_slave,
183 .remove_slave = w1_ds2760_remove_slave,
184};
185
186static struct w1_family w1_ds2760_family = {
187 .fid = W1_FAMILY_DS2760,
188 .fops = &w1_ds2760_fops,
189};
190
191static int __init w1_ds2760_init(void)
192{
193 printk(KERN_INFO "1-Wire driver for the DS2760 battery monitor "
194 " chip - (c) 2004-2005, Szabolcs Gyurko\n");
195 idr_init(&bat_idr);
196 return w1_register_family(&w1_ds2760_family);
197}
198
199static void __exit w1_ds2760_exit(void)
200{
201 w1_unregister_family(&w1_ds2760_family);
202 idr_destroy(&bat_idr);
203}
204
205EXPORT_SYMBOL(w1_ds2760_read);
206EXPORT_SYMBOL(w1_ds2760_write);
207
208module_init(w1_ds2760_init);
209module_exit(w1_ds2760_exit);
210
211MODULE_LICENSE("GPL");
212MODULE_AUTHOR("Szabolcs Gyurko <szabolcs.gyurko@tlt.hu>");
213MODULE_DESCRIPTION("1-wire Driver Dallas 2760 battery monitor chip");
diff --git a/drivers/w1/slaves/w1_ds2760.h b/drivers/w1/slaves/w1_ds2760.h
new file mode 100644
index 000000000000..f1302429cb02
--- /dev/null
+++ b/drivers/w1/slaves/w1_ds2760.h
@@ -0,0 +1,50 @@
1/*
2 * 1-Wire implementation for the ds2760 chip
3 *
4 * Copyright © 2004-2005, Szabolcs Gyurko <szabolcs.gyurko@tlt.hu>
5 *
6 * Use consistent with the GNU GPL is permitted,
7 * provided that this copyright notice is
8 * preserved in its entirety in all copies and derived works.
9 *
10 */
11
12#ifndef __w1_ds2760_h__
13#define __w1_ds2760_h__
14
15/* Known commands to the DS2760 chip */
16#define W1_DS2760_SWAP 0xAA
17#define W1_DS2760_READ_DATA 0x69
18#define W1_DS2760_WRITE_DATA 0x6C
19#define W1_DS2760_COPY_DATA 0x48
20#define W1_DS2760_RECALL_DATA 0xB8
21#define W1_DS2760_LOCK 0x6A
22
23/* Number of valid register addresses */
24#define DS2760_DATA_SIZE 0x40
25
26#define DS2760_PROTECTION_REG 0x00
27#define DS2760_STATUS_REG 0x01
28#define DS2760_EEPROM_REG 0x07
29#define DS2760_SPECIAL_FEATURE_REG 0x08
30#define DS2760_VOLTAGE_MSB 0x0c
31#define DS2760_VOLTAGE_LSB 0x0d
32#define DS2760_CURRENT_MSB 0x0e
33#define DS2760_CURRENT_LSB 0x0f
34#define DS2760_CURRENT_ACCUM_MSB 0x10
35#define DS2760_CURRENT_ACCUM_LSB 0x11
36#define DS2760_TEMP_MSB 0x18
37#define DS2760_TEMP_LSB 0x19
38#define DS2760_EEPROM_BLOCK0 0x20
39#define DS2760_ACTIVE_FULL 0x20
40#define DS2760_EEPROM_BLOCK1 0x30
41#define DS2760_RATED_CAPACITY 0x32
42#define DS2760_CURRENT_OFFSET_BIAS 0x33
43#define DS2760_ACTIVE_EMPTY 0x3b
44
45extern int w1_ds2760_read(struct device *dev, char *buf, int addr,
46 size_t count);
47extern int w1_ds2760_write(struct device *dev, char *buf, int addr,
48 size_t count);
49
50#endif /* !__w1_ds2760_h__ */
diff --git a/drivers/w1/w1_family.h b/drivers/w1/w1_family.h
index 1e2ac40c2c14..ef1e1dafa19a 100644
--- a/drivers/w1/w1_family.h
+++ b/drivers/w1/w1_family.h
@@ -33,6 +33,7 @@
33#define W1_THERM_DS1822 0x22 33#define W1_THERM_DS1822 0x22
34#define W1_EEPROM_DS2433 0x23 34#define W1_EEPROM_DS2433 0x23
35#define W1_THERM_DS18B20 0x28 35#define W1_THERM_DS18B20 0x28
36#define W1_FAMILY_DS2760 0x30
36 37
37#define MAXNAMELEN 32 38#define MAXNAMELEN 32
38 39
diff --git a/fs/adfs/file.c b/fs/adfs/file.c
index f544a2855923..36e381c6a99a 100644
--- a/fs/adfs/file.c
+++ b/fs/adfs/file.c
@@ -33,7 +33,7 @@ const struct file_operations adfs_file_operations = {
33 .fsync = file_fsync, 33 .fsync = file_fsync,
34 .write = do_sync_write, 34 .write = do_sync_write,
35 .aio_write = generic_file_aio_write, 35 .aio_write = generic_file_aio_write,
36 .sendfile = generic_file_sendfile, 36 .splice_read = generic_file_splice_read,
37}; 37};
38 38
39const struct inode_operations adfs_file_inode_operations = { 39const struct inode_operations adfs_file_inode_operations = {
diff --git a/fs/affs/file.c b/fs/affs/file.c
index c8796906f584..c314a35f0918 100644
--- a/fs/affs/file.c
+++ b/fs/affs/file.c
@@ -35,7 +35,7 @@ const struct file_operations affs_file_operations = {
35 .open = affs_file_open, 35 .open = affs_file_open,
36 .release = affs_file_release, 36 .release = affs_file_release,
37 .fsync = file_fsync, 37 .fsync = file_fsync,
38 .sendfile = generic_file_sendfile, 38 .splice_read = generic_file_splice_read,
39}; 39};
40 40
41const struct inode_operations affs_file_inode_operations = { 41const struct inode_operations affs_file_inode_operations = {
diff --git a/fs/afs/file.c b/fs/afs/file.c
index 9c0e721d9fc2..aede7eb66dd4 100644
--- a/fs/afs/file.c
+++ b/fs/afs/file.c
@@ -32,7 +32,7 @@ const struct file_operations afs_file_operations = {
32 .aio_read = generic_file_aio_read, 32 .aio_read = generic_file_aio_read,
33 .aio_write = afs_file_write, 33 .aio_write = afs_file_write,
34 .mmap = generic_file_readonly_mmap, 34 .mmap = generic_file_readonly_mmap,
35 .sendfile = generic_file_sendfile, 35 .splice_read = generic_file_splice_read,
36 .fsync = afs_fsync, 36 .fsync = afs_fsync,
37}; 37};
38 38
diff --git a/fs/bad_inode.c b/fs/bad_inode.c
index 329ee473eede..521ff7caadbd 100644
--- a/fs/bad_inode.c
+++ b/fs/bad_inode.c
@@ -114,12 +114,6 @@ static int bad_file_lock(struct file *file, int cmd, struct file_lock *fl)
114 return -EIO; 114 return -EIO;
115} 115}
116 116
117static ssize_t bad_file_sendfile(struct file *in_file, loff_t *ppos,
118 size_t count, read_actor_t actor, void *target)
119{
120 return -EIO;
121}
122
123static ssize_t bad_file_sendpage(struct file *file, struct page *page, 117static ssize_t bad_file_sendpage(struct file *file, struct page *page,
124 int off, size_t len, loff_t *pos, int more) 118 int off, size_t len, loff_t *pos, int more)
125{ 119{
@@ -182,7 +176,6 @@ static const struct file_operations bad_file_ops =
182 .aio_fsync = bad_file_aio_fsync, 176 .aio_fsync = bad_file_aio_fsync,
183 .fasync = bad_file_fasync, 177 .fasync = bad_file_fasync,
184 .lock = bad_file_lock, 178 .lock = bad_file_lock,
185 .sendfile = bad_file_sendfile,
186 .sendpage = bad_file_sendpage, 179 .sendpage = bad_file_sendpage,
187 .get_unmapped_area = bad_file_get_unmapped_area, 180 .get_unmapped_area = bad_file_get_unmapped_area,
188 .check_flags = bad_file_check_flags, 181 .check_flags = bad_file_check_flags,
diff --git a/fs/bfs/file.c b/fs/bfs/file.c
index ef4d1fa04e65..24310e9ee05a 100644
--- a/fs/bfs/file.c
+++ b/fs/bfs/file.c
@@ -24,7 +24,7 @@ const struct file_operations bfs_file_operations = {
24 .write = do_sync_write, 24 .write = do_sync_write,
25 .aio_write = generic_file_aio_write, 25 .aio_write = generic_file_aio_write,
26 .mmap = generic_file_mmap, 26 .mmap = generic_file_mmap,
27 .sendfile = generic_file_sendfile, 27 .splice_read = generic_file_splice_read,
28}; 28};
29 29
30static int bfs_move_block(unsigned long from, unsigned long to, struct super_block *sb) 30static int bfs_move_block(unsigned long from, unsigned long to, struct super_block *sb)
diff --git a/fs/bio.c b/fs/bio.c
index 093345f00128..33e46340a766 100644
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -1223,8 +1223,6 @@ EXPORT_SYMBOL(bio_hw_segments);
1223EXPORT_SYMBOL(bio_add_page); 1223EXPORT_SYMBOL(bio_add_page);
1224EXPORT_SYMBOL(bio_add_pc_page); 1224EXPORT_SYMBOL(bio_add_pc_page);
1225EXPORT_SYMBOL(bio_get_nr_vecs); 1225EXPORT_SYMBOL(bio_get_nr_vecs);
1226EXPORT_SYMBOL(bio_map_user);
1227EXPORT_SYMBOL(bio_unmap_user);
1228EXPORT_SYMBOL(bio_map_kern); 1226EXPORT_SYMBOL(bio_map_kern);
1229EXPORT_SYMBOL(bio_pair_release); 1227EXPORT_SYMBOL(bio_pair_release);
1230EXPORT_SYMBOL(bio_split); 1228EXPORT_SYMBOL(bio_split);
diff --git a/fs/block_dev.c b/fs/block_dev.c
index ea1480a16f51..b3e9bfa748cf 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -1346,7 +1346,6 @@ const struct file_operations def_blk_fops = {
1346#ifdef CONFIG_COMPAT 1346#ifdef CONFIG_COMPAT
1347 .compat_ioctl = compat_blkdev_ioctl, 1347 .compat_ioctl = compat_blkdev_ioctl,
1348#endif 1348#endif
1349 .sendfile = generic_file_sendfile,
1350 .splice_read = generic_file_splice_read, 1349 .splice_read = generic_file_splice_read,
1351 .splice_write = generic_file_splice_write, 1350 .splice_write = generic_file_splice_write,
1352}; 1351};
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 7c04752b76cb..8b0cbf4a4ad0 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -616,7 +616,7 @@ const struct file_operations cifs_file_ops = {
616 .fsync = cifs_fsync, 616 .fsync = cifs_fsync,
617 .flush = cifs_flush, 617 .flush = cifs_flush,
618 .mmap = cifs_file_mmap, 618 .mmap = cifs_file_mmap,
619 .sendfile = generic_file_sendfile, 619 .splice_read = generic_file_splice_read,
620 .llseek = cifs_llseek, 620 .llseek = cifs_llseek,
621#ifdef CONFIG_CIFS_POSIX 621#ifdef CONFIG_CIFS_POSIX
622 .ioctl = cifs_ioctl, 622 .ioctl = cifs_ioctl,
@@ -637,7 +637,7 @@ const struct file_operations cifs_file_direct_ops = {
637 .lock = cifs_lock, 637 .lock = cifs_lock,
638 .fsync = cifs_fsync, 638 .fsync = cifs_fsync,
639 .flush = cifs_flush, 639 .flush = cifs_flush,
640 .sendfile = generic_file_sendfile, /* BB removeme BB */ 640 .splice_read = generic_file_splice_read,
641#ifdef CONFIG_CIFS_POSIX 641#ifdef CONFIG_CIFS_POSIX
642 .ioctl = cifs_ioctl, 642 .ioctl = cifs_ioctl,
643#endif /* CONFIG_CIFS_POSIX */ 643#endif /* CONFIG_CIFS_POSIX */
@@ -656,7 +656,7 @@ const struct file_operations cifs_file_nobrl_ops = {
656 .fsync = cifs_fsync, 656 .fsync = cifs_fsync,
657 .flush = cifs_flush, 657 .flush = cifs_flush,
658 .mmap = cifs_file_mmap, 658 .mmap = cifs_file_mmap,
659 .sendfile = generic_file_sendfile, 659 .splice_read = generic_file_splice_read,
660 .llseek = cifs_llseek, 660 .llseek = cifs_llseek,
661#ifdef CONFIG_CIFS_POSIX 661#ifdef CONFIG_CIFS_POSIX
662 .ioctl = cifs_ioctl, 662 .ioctl = cifs_ioctl,
@@ -676,7 +676,7 @@ const struct file_operations cifs_file_direct_nobrl_ops = {
676 .release = cifs_close, 676 .release = cifs_close,
677 .fsync = cifs_fsync, 677 .fsync = cifs_fsync,
678 .flush = cifs_flush, 678 .flush = cifs_flush,
679 .sendfile = generic_file_sendfile, /* BB removeme BB */ 679 .splice_read = generic_file_splice_read,
680#ifdef CONFIG_CIFS_POSIX 680#ifdef CONFIG_CIFS_POSIX
681 .ioctl = cifs_ioctl, 681 .ioctl = cifs_ioctl,
682#endif /* CONFIG_CIFS_POSIX */ 682#endif /* CONFIG_CIFS_POSIX */
diff --git a/fs/coda/file.c b/fs/coda/file.c
index 5ef2b609ec7d..99dbe866816d 100644
--- a/fs/coda/file.c
+++ b/fs/coda/file.c
@@ -47,8 +47,9 @@ coda_file_read(struct file *coda_file, char __user *buf, size_t count, loff_t *p
47} 47}
48 48
49static ssize_t 49static ssize_t
50coda_file_sendfile(struct file *coda_file, loff_t *ppos, size_t count, 50coda_file_splice_read(struct file *coda_file, loff_t *ppos,
51 read_actor_t actor, void *target) 51 struct pipe_inode_info *pipe, size_t count,
52 unsigned int flags)
52{ 53{
53 struct coda_file_info *cfi; 54 struct coda_file_info *cfi;
54 struct file *host_file; 55 struct file *host_file;
@@ -57,10 +58,10 @@ coda_file_sendfile(struct file *coda_file, loff_t *ppos, size_t count,
57 BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC); 58 BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC);
58 host_file = cfi->cfi_container; 59 host_file = cfi->cfi_container;
59 60
60 if (!host_file->f_op || !host_file->f_op->sendfile) 61 if (!host_file->f_op || !host_file->f_op->splice_read)
61 return -EINVAL; 62 return -EINVAL;
62 63
63 return host_file->f_op->sendfile(host_file, ppos, count, actor, target); 64 return host_file->f_op->splice_read(host_file, ppos, pipe, count,flags);
64} 65}
65 66
66static ssize_t 67static ssize_t
@@ -295,6 +296,6 @@ const struct file_operations coda_file_operations = {
295 .flush = coda_flush, 296 .flush = coda_flush,
296 .release = coda_release, 297 .release = coda_release,
297 .fsync = coda_fsync, 298 .fsync = coda_fsync,
298 .sendfile = coda_file_sendfile, 299 .splice_read = coda_file_splice_read,
299}; 300};
300 301
diff --git a/fs/dlm/Makefile b/fs/dlm/Makefile
index 604cf7dc5f39..d248e60951ba 100644
--- a/fs/dlm/Makefile
+++ b/fs/dlm/Makefile
@@ -8,6 +8,7 @@ dlm-y := ast.o \
8 member.o \ 8 member.o \
9 memory.o \ 9 memory.o \
10 midcomms.o \ 10 midcomms.o \
11 netlink.o \
11 lowcomms.o \ 12 lowcomms.o \
12 rcom.o \ 13 rcom.o \
13 recover.o \ 14 recover.o \
diff --git a/fs/dlm/config.c b/fs/dlm/config.c
index 822abdcd1434..5069b2cb5a1f 100644
--- a/fs/dlm/config.c
+++ b/fs/dlm/config.c
@@ -90,6 +90,7 @@ struct cluster {
90 unsigned int cl_scan_secs; 90 unsigned int cl_scan_secs;
91 unsigned int cl_log_debug; 91 unsigned int cl_log_debug;
92 unsigned int cl_protocol; 92 unsigned int cl_protocol;
93 unsigned int cl_timewarn_cs;
93}; 94};
94 95
95enum { 96enum {
@@ -103,6 +104,7 @@ enum {
103 CLUSTER_ATTR_SCAN_SECS, 104 CLUSTER_ATTR_SCAN_SECS,
104 CLUSTER_ATTR_LOG_DEBUG, 105 CLUSTER_ATTR_LOG_DEBUG,
105 CLUSTER_ATTR_PROTOCOL, 106 CLUSTER_ATTR_PROTOCOL,
107 CLUSTER_ATTR_TIMEWARN_CS,
106}; 108};
107 109
108struct cluster_attribute { 110struct cluster_attribute {
@@ -162,6 +164,7 @@ CLUSTER_ATTR(toss_secs, 1);
162CLUSTER_ATTR(scan_secs, 1); 164CLUSTER_ATTR(scan_secs, 1);
163CLUSTER_ATTR(log_debug, 0); 165CLUSTER_ATTR(log_debug, 0);
164CLUSTER_ATTR(protocol, 0); 166CLUSTER_ATTR(protocol, 0);
167CLUSTER_ATTR(timewarn_cs, 1);
165 168
166static struct configfs_attribute *cluster_attrs[] = { 169static struct configfs_attribute *cluster_attrs[] = {
167 [CLUSTER_ATTR_TCP_PORT] = &cluster_attr_tcp_port.attr, 170 [CLUSTER_ATTR_TCP_PORT] = &cluster_attr_tcp_port.attr,
@@ -174,6 +177,7 @@ static struct configfs_attribute *cluster_attrs[] = {
174 [CLUSTER_ATTR_SCAN_SECS] = &cluster_attr_scan_secs.attr, 177 [CLUSTER_ATTR_SCAN_SECS] = &cluster_attr_scan_secs.attr,
175 [CLUSTER_ATTR_LOG_DEBUG] = &cluster_attr_log_debug.attr, 178 [CLUSTER_ATTR_LOG_DEBUG] = &cluster_attr_log_debug.attr,
176 [CLUSTER_ATTR_PROTOCOL] = &cluster_attr_protocol.attr, 179 [CLUSTER_ATTR_PROTOCOL] = &cluster_attr_protocol.attr,
180 [CLUSTER_ATTR_TIMEWARN_CS] = &cluster_attr_timewarn_cs.attr,
177 NULL, 181 NULL,
178}; 182};
179 183
@@ -429,6 +433,8 @@ static struct config_group *make_cluster(struct config_group *g,
429 cl->cl_toss_secs = dlm_config.ci_toss_secs; 433 cl->cl_toss_secs = dlm_config.ci_toss_secs;
430 cl->cl_scan_secs = dlm_config.ci_scan_secs; 434 cl->cl_scan_secs = dlm_config.ci_scan_secs;
431 cl->cl_log_debug = dlm_config.ci_log_debug; 435 cl->cl_log_debug = dlm_config.ci_log_debug;
436 cl->cl_protocol = dlm_config.ci_protocol;
437 cl->cl_timewarn_cs = dlm_config.ci_timewarn_cs;
432 438
433 space_list = &sps->ss_group; 439 space_list = &sps->ss_group;
434 comm_list = &cms->cs_group; 440 comm_list = &cms->cs_group;
@@ -748,9 +754,16 @@ static ssize_t node_weight_write(struct node *nd, const char *buf, size_t len)
748 754
749static struct space *get_space(char *name) 755static struct space *get_space(char *name)
750{ 756{
757 struct config_item *i;
758
751 if (!space_list) 759 if (!space_list)
752 return NULL; 760 return NULL;
753 return to_space(config_group_find_obj(space_list, name)); 761
762 down(&space_list->cg_subsys->su_sem);
763 i = config_group_find_obj(space_list, name);
764 up(&space_list->cg_subsys->su_sem);
765
766 return to_space(i);
754} 767}
755 768
756static void put_space(struct space *sp) 769static void put_space(struct space *sp)
@@ -776,20 +789,20 @@ static struct comm *get_comm(int nodeid, struct sockaddr_storage *addr)
776 if (cm->nodeid != nodeid) 789 if (cm->nodeid != nodeid)
777 continue; 790 continue;
778 found = 1; 791 found = 1;
792 config_item_get(i);
779 break; 793 break;
780 } else { 794 } else {
781 if (!cm->addr_count || 795 if (!cm->addr_count ||
782 memcmp(cm->addr[0], addr, sizeof(*addr))) 796 memcmp(cm->addr[0], addr, sizeof(*addr)))
783 continue; 797 continue;
784 found = 1; 798 found = 1;
799 config_item_get(i);
785 break; 800 break;
786 } 801 }
787 } 802 }
788 up(&clusters_root.subsys.su_sem); 803 up(&clusters_root.subsys.su_sem);
789 804
790 if (found) 805 if (!found)
791 config_item_get(i);
792 else
793 cm = NULL; 806 cm = NULL;
794 return cm; 807 return cm;
795} 808}
@@ -909,6 +922,7 @@ int dlm_our_addr(struct sockaddr_storage *addr, int num)
909#define DEFAULT_SCAN_SECS 5 922#define DEFAULT_SCAN_SECS 5
910#define DEFAULT_LOG_DEBUG 0 923#define DEFAULT_LOG_DEBUG 0
911#define DEFAULT_PROTOCOL 0 924#define DEFAULT_PROTOCOL 0
925#define DEFAULT_TIMEWARN_CS 500 /* 5 sec = 500 centiseconds */
912 926
913struct dlm_config_info dlm_config = { 927struct dlm_config_info dlm_config = {
914 .ci_tcp_port = DEFAULT_TCP_PORT, 928 .ci_tcp_port = DEFAULT_TCP_PORT,
@@ -920,6 +934,7 @@ struct dlm_config_info dlm_config = {
920 .ci_toss_secs = DEFAULT_TOSS_SECS, 934 .ci_toss_secs = DEFAULT_TOSS_SECS,
921 .ci_scan_secs = DEFAULT_SCAN_SECS, 935 .ci_scan_secs = DEFAULT_SCAN_SECS,
922 .ci_log_debug = DEFAULT_LOG_DEBUG, 936 .ci_log_debug = DEFAULT_LOG_DEBUG,
923 .ci_protocol = DEFAULT_PROTOCOL 937 .ci_protocol = DEFAULT_PROTOCOL,
938 .ci_timewarn_cs = DEFAULT_TIMEWARN_CS
924}; 939};
925 940
diff --git a/fs/dlm/config.h b/fs/dlm/config.h
index 967cc3d72e5e..a3170fe22090 100644
--- a/fs/dlm/config.h
+++ b/fs/dlm/config.h
@@ -27,6 +27,7 @@ struct dlm_config_info {
27 int ci_scan_secs; 27 int ci_scan_secs;
28 int ci_log_debug; 28 int ci_log_debug;
29 int ci_protocol; 29 int ci_protocol;
30 int ci_timewarn_cs;
30}; 31};
31 32
32extern struct dlm_config_info dlm_config; 33extern struct dlm_config_info dlm_config;
diff --git a/fs/dlm/debug_fs.c b/fs/dlm/debug_fs.c
index 61ba670b9e02..12c3bfd5e660 100644
--- a/fs/dlm/debug_fs.c
+++ b/fs/dlm/debug_fs.c
@@ -17,6 +17,7 @@
17#include <linux/debugfs.h> 17#include <linux/debugfs.h>
18 18
19#include "dlm_internal.h" 19#include "dlm_internal.h"
20#include "lock.h"
20 21
21#define DLM_DEBUG_BUF_LEN 4096 22#define DLM_DEBUG_BUF_LEN 4096
22static char debug_buf[DLM_DEBUG_BUF_LEN]; 23static char debug_buf[DLM_DEBUG_BUF_LEN];
@@ -26,6 +27,8 @@ static struct dentry *dlm_root;
26 27
27struct rsb_iter { 28struct rsb_iter {
28 int entry; 29 int entry;
30 int locks;
31 int header;
29 struct dlm_ls *ls; 32 struct dlm_ls *ls;
30 struct list_head *next; 33 struct list_head *next;
31 struct dlm_rsb *rsb; 34 struct dlm_rsb *rsb;
@@ -57,8 +60,8 @@ static char *print_lockmode(int mode)
57 } 60 }
58} 61}
59 62
60static void print_lock(struct seq_file *s, struct dlm_lkb *lkb, 63static void print_resource_lock(struct seq_file *s, struct dlm_lkb *lkb,
61 struct dlm_rsb *res) 64 struct dlm_rsb *res)
62{ 65{
63 seq_printf(s, "%08x %s", lkb->lkb_id, print_lockmode(lkb->lkb_grmode)); 66 seq_printf(s, "%08x %s", lkb->lkb_id, print_lockmode(lkb->lkb_grmode));
64 67
@@ -85,6 +88,8 @@ static int print_resource(struct dlm_rsb *res, struct seq_file *s)
85 struct dlm_lkb *lkb; 88 struct dlm_lkb *lkb;
86 int i, lvblen = res->res_ls->ls_lvblen, recover_list, root_list; 89 int i, lvblen = res->res_ls->ls_lvblen, recover_list, root_list;
87 90
91 lock_rsb(res);
92
88 seq_printf(s, "\nResource %p Name (len=%d) \"", res, res->res_length); 93 seq_printf(s, "\nResource %p Name (len=%d) \"", res, res->res_length);
89 for (i = 0; i < res->res_length; i++) { 94 for (i = 0; i < res->res_length; i++) {
90 if (isprint(res->res_name[i])) 95 if (isprint(res->res_name[i]))
@@ -129,15 +134,15 @@ static int print_resource(struct dlm_rsb *res, struct seq_file *s)
129 /* Print the locks attached to this resource */ 134 /* Print the locks attached to this resource */
130 seq_printf(s, "Granted Queue\n"); 135 seq_printf(s, "Granted Queue\n");
131 list_for_each_entry(lkb, &res->res_grantqueue, lkb_statequeue) 136 list_for_each_entry(lkb, &res->res_grantqueue, lkb_statequeue)
132 print_lock(s, lkb, res); 137 print_resource_lock(s, lkb, res);
133 138
134 seq_printf(s, "Conversion Queue\n"); 139 seq_printf(s, "Conversion Queue\n");
135 list_for_each_entry(lkb, &res->res_convertqueue, lkb_statequeue) 140 list_for_each_entry(lkb, &res->res_convertqueue, lkb_statequeue)
136 print_lock(s, lkb, res); 141 print_resource_lock(s, lkb, res);
137 142
138 seq_printf(s, "Waiting Queue\n"); 143 seq_printf(s, "Waiting Queue\n");
139 list_for_each_entry(lkb, &res->res_waitqueue, lkb_statequeue) 144 list_for_each_entry(lkb, &res->res_waitqueue, lkb_statequeue)
140 print_lock(s, lkb, res); 145 print_resource_lock(s, lkb, res);
141 146
142 if (list_empty(&res->res_lookup)) 147 if (list_empty(&res->res_lookup))
143 goto out; 148 goto out;
@@ -151,6 +156,61 @@ static int print_resource(struct dlm_rsb *res, struct seq_file *s)
151 seq_printf(s, "\n"); 156 seq_printf(s, "\n");
152 } 157 }
153 out: 158 out:
159 unlock_rsb(res);
160 return 0;
161}
162
163static void print_lock(struct seq_file *s, struct dlm_lkb *lkb, struct dlm_rsb *r)
164{
165 struct dlm_user_args *ua;
166 unsigned int waiting = 0;
167 uint64_t xid = 0;
168
169 if (lkb->lkb_flags & DLM_IFL_USER) {
170 ua = (struct dlm_user_args *) lkb->lkb_astparam;
171 if (ua)
172 xid = ua->xid;
173 }
174
175 if (lkb->lkb_timestamp)
176 waiting = jiffies_to_msecs(jiffies - lkb->lkb_timestamp);
177
178 /* id nodeid remid pid xid exflags flags sts grmode rqmode time_ms
179 r_nodeid r_len r_name */
180
181 seq_printf(s, "%x %d %x %u %llu %x %x %d %d %d %u %u %d \"%s\"\n",
182 lkb->lkb_id,
183 lkb->lkb_nodeid,
184 lkb->lkb_remid,
185 lkb->lkb_ownpid,
186 (unsigned long long)xid,
187 lkb->lkb_exflags,
188 lkb->lkb_flags,
189 lkb->lkb_status,
190 lkb->lkb_grmode,
191 lkb->lkb_rqmode,
192 waiting,
193 r->res_nodeid,
194 r->res_length,
195 r->res_name);
196}
197
198static int print_locks(struct dlm_rsb *r, struct seq_file *s)
199{
200 struct dlm_lkb *lkb;
201
202 lock_rsb(r);
203
204 list_for_each_entry(lkb, &r->res_grantqueue, lkb_statequeue)
205 print_lock(s, lkb, r);
206
207 list_for_each_entry(lkb, &r->res_convertqueue, lkb_statequeue)
208 print_lock(s, lkb, r);
209
210 list_for_each_entry(lkb, &r->res_waitqueue, lkb_statequeue)
211 print_lock(s, lkb, r);
212
213 unlock_rsb(r);
154 return 0; 214 return 0;
155} 215}
156 216
@@ -166,6 +226,9 @@ static int rsb_iter_next(struct rsb_iter *ri)
166 read_lock(&ls->ls_rsbtbl[i].lock); 226 read_lock(&ls->ls_rsbtbl[i].lock);
167 if (!list_empty(&ls->ls_rsbtbl[i].list)) { 227 if (!list_empty(&ls->ls_rsbtbl[i].list)) {
168 ri->next = ls->ls_rsbtbl[i].list.next; 228 ri->next = ls->ls_rsbtbl[i].list.next;
229 ri->rsb = list_entry(ri->next, struct dlm_rsb,
230 res_hashchain);
231 dlm_hold_rsb(ri->rsb);
169 read_unlock(&ls->ls_rsbtbl[i].lock); 232 read_unlock(&ls->ls_rsbtbl[i].lock);
170 break; 233 break;
171 } 234 }
@@ -176,6 +239,7 @@ static int rsb_iter_next(struct rsb_iter *ri)
176 if (ri->entry >= ls->ls_rsbtbl_size) 239 if (ri->entry >= ls->ls_rsbtbl_size)
177 return 1; 240 return 1;
178 } else { 241 } else {
242 struct dlm_rsb *old = ri->rsb;
179 i = ri->entry; 243 i = ri->entry;
180 read_lock(&ls->ls_rsbtbl[i].lock); 244 read_lock(&ls->ls_rsbtbl[i].lock);
181 ri->next = ri->next->next; 245 ri->next = ri->next->next;
@@ -184,11 +248,14 @@ static int rsb_iter_next(struct rsb_iter *ri)
184 ri->next = NULL; 248 ri->next = NULL;
185 ri->entry++; 249 ri->entry++;
186 read_unlock(&ls->ls_rsbtbl[i].lock); 250 read_unlock(&ls->ls_rsbtbl[i].lock);
251 dlm_put_rsb(old);
187 goto top; 252 goto top;
188 } 253 }
254 ri->rsb = list_entry(ri->next, struct dlm_rsb, res_hashchain);
255 dlm_hold_rsb(ri->rsb);
189 read_unlock(&ls->ls_rsbtbl[i].lock); 256 read_unlock(&ls->ls_rsbtbl[i].lock);
257 dlm_put_rsb(old);
190 } 258 }
191 ri->rsb = list_entry(ri->next, struct dlm_rsb, res_hashchain);
192 259
193 return 0; 260 return 0;
194} 261}
@@ -202,7 +269,7 @@ static struct rsb_iter *rsb_iter_init(struct dlm_ls *ls)
202{ 269{
203 struct rsb_iter *ri; 270 struct rsb_iter *ri;
204 271
205 ri = kmalloc(sizeof *ri, GFP_KERNEL); 272 ri = kzalloc(sizeof *ri, GFP_KERNEL);
206 if (!ri) 273 if (!ri)
207 return NULL; 274 return NULL;
208 275
@@ -260,7 +327,17 @@ static int rsb_seq_show(struct seq_file *file, void *iter_ptr)
260{ 327{
261 struct rsb_iter *ri = iter_ptr; 328 struct rsb_iter *ri = iter_ptr;
262 329
263 print_resource(ri->rsb, file); 330 if (ri->locks) {
331 if (ri->header) {
332 seq_printf(file, "id nodeid remid pid xid exflags flags "
333 "sts grmode rqmode time_ms r_nodeid "
334 "r_len r_name\n");
335 ri->header = 0;
336 }
337 print_locks(ri->rsb, file);
338 } else {
339 print_resource(ri->rsb, file);
340 }
264 341
265 return 0; 342 return 0;
266} 343}
@@ -296,6 +373,83 @@ static const struct file_operations rsb_fops = {
296}; 373};
297 374
298/* 375/*
376 * Dump state in compact per-lock listing
377 */
378
379static struct rsb_iter *locks_iter_init(struct dlm_ls *ls, loff_t *pos)
380{
381 struct rsb_iter *ri;
382
383 ri = kzalloc(sizeof *ri, GFP_KERNEL);
384 if (!ri)
385 return NULL;
386
387 ri->ls = ls;
388 ri->entry = 0;
389 ri->next = NULL;
390 ri->locks = 1;
391
392 if (*pos == 0)
393 ri->header = 1;
394
395 if (rsb_iter_next(ri)) {
396 rsb_iter_free(ri);
397 return NULL;
398 }
399
400 return ri;
401}
402
403static void *locks_seq_start(struct seq_file *file, loff_t *pos)
404{
405 struct rsb_iter *ri;
406 loff_t n = *pos;
407
408 ri = locks_iter_init(file->private, pos);
409 if (!ri)
410 return NULL;
411
412 while (n--) {
413 if (rsb_iter_next(ri)) {
414 rsb_iter_free(ri);
415 return NULL;
416 }
417 }
418
419 return ri;
420}
421
422static struct seq_operations locks_seq_ops = {
423 .start = locks_seq_start,
424 .next = rsb_seq_next,
425 .stop = rsb_seq_stop,
426 .show = rsb_seq_show,
427};
428
429static int locks_open(struct inode *inode, struct file *file)
430{
431 struct seq_file *seq;
432 int ret;
433
434 ret = seq_open(file, &locks_seq_ops);
435 if (ret)
436 return ret;
437
438 seq = file->private_data;
439 seq->private = inode->i_private;
440
441 return 0;
442}
443
444static const struct file_operations locks_fops = {
445 .owner = THIS_MODULE,
446 .open = locks_open,
447 .read = seq_read,
448 .llseek = seq_lseek,
449 .release = seq_release
450};
451
452/*
299 * dump lkb's on the ls_waiters list 453 * dump lkb's on the ls_waiters list
300 */ 454 */
301 455
@@ -362,6 +516,20 @@ int dlm_create_debug_file(struct dlm_ls *ls)
362 return -ENOMEM; 516 return -ENOMEM;
363 } 517 }
364 518
519 memset(name, 0, sizeof(name));
520 snprintf(name, DLM_LOCKSPACE_LEN+8, "%s_locks", ls->ls_name);
521
522 ls->ls_debug_locks_dentry = debugfs_create_file(name,
523 S_IFREG | S_IRUGO,
524 dlm_root,
525 ls,
526 &locks_fops);
527 if (!ls->ls_debug_locks_dentry) {
528 debugfs_remove(ls->ls_debug_waiters_dentry);
529 debugfs_remove(ls->ls_debug_rsb_dentry);
530 return -ENOMEM;
531 }
532
365 return 0; 533 return 0;
366} 534}
367 535
@@ -371,6 +539,8 @@ void dlm_delete_debug_file(struct dlm_ls *ls)
371 debugfs_remove(ls->ls_debug_rsb_dentry); 539 debugfs_remove(ls->ls_debug_rsb_dentry);
372 if (ls->ls_debug_waiters_dentry) 540 if (ls->ls_debug_waiters_dentry)
373 debugfs_remove(ls->ls_debug_waiters_dentry); 541 debugfs_remove(ls->ls_debug_waiters_dentry);
542 if (ls->ls_debug_locks_dentry)
543 debugfs_remove(ls->ls_debug_locks_dentry);
374} 544}
375 545
376int dlm_register_debugfs(void) 546int dlm_register_debugfs(void)
diff --git a/fs/dlm/dlm_internal.h b/fs/dlm/dlm_internal.h
index 30994d68f6a0..74901e981e10 100644
--- a/fs/dlm/dlm_internal.h
+++ b/fs/dlm/dlm_internal.h
@@ -151,6 +151,7 @@ struct dlm_args {
151 void *bastaddr; 151 void *bastaddr;
152 int mode; 152 int mode;
153 struct dlm_lksb *lksb; 153 struct dlm_lksb *lksb;
154 unsigned long timeout;
154}; 155};
155 156
156 157
@@ -213,6 +214,9 @@ struct dlm_args {
213#define DLM_IFL_OVERLAP_UNLOCK 0x00080000 214#define DLM_IFL_OVERLAP_UNLOCK 0x00080000
214#define DLM_IFL_OVERLAP_CANCEL 0x00100000 215#define DLM_IFL_OVERLAP_CANCEL 0x00100000
215#define DLM_IFL_ENDOFLIFE 0x00200000 216#define DLM_IFL_ENDOFLIFE 0x00200000
217#define DLM_IFL_WATCH_TIMEWARN 0x00400000
218#define DLM_IFL_TIMEOUT_CANCEL 0x00800000
219#define DLM_IFL_DEADLOCK_CANCEL 0x01000000
216#define DLM_IFL_USER 0x00000001 220#define DLM_IFL_USER 0x00000001
217#define DLM_IFL_ORPHAN 0x00000002 221#define DLM_IFL_ORPHAN 0x00000002
218 222
@@ -243,6 +247,9 @@ struct dlm_lkb {
243 struct list_head lkb_wait_reply; /* waiting for remote reply */ 247 struct list_head lkb_wait_reply; /* waiting for remote reply */
244 struct list_head lkb_astqueue; /* need ast to be sent */ 248 struct list_head lkb_astqueue; /* need ast to be sent */
245 struct list_head lkb_ownqueue; /* list of locks for a process */ 249 struct list_head lkb_ownqueue; /* list of locks for a process */
250 struct list_head lkb_time_list;
251 unsigned long lkb_timestamp;
252 unsigned long lkb_timeout_cs;
246 253
247 char *lkb_lvbptr; 254 char *lkb_lvbptr;
248 struct dlm_lksb *lkb_lksb; /* caller's status block */ 255 struct dlm_lksb *lkb_lksb; /* caller's status block */
@@ -447,12 +454,16 @@ struct dlm_ls {
447 struct mutex ls_orphans_mutex; 454 struct mutex ls_orphans_mutex;
448 struct list_head ls_orphans; 455 struct list_head ls_orphans;
449 456
457 struct mutex ls_timeout_mutex;
458 struct list_head ls_timeout;
459
450 struct list_head ls_nodes; /* current nodes in ls */ 460 struct list_head ls_nodes; /* current nodes in ls */
451 struct list_head ls_nodes_gone; /* dead node list, recovery */ 461 struct list_head ls_nodes_gone; /* dead node list, recovery */
452 int ls_num_nodes; /* number of nodes in ls */ 462 int ls_num_nodes; /* number of nodes in ls */
453 int ls_low_nodeid; 463 int ls_low_nodeid;
454 int ls_total_weight; 464 int ls_total_weight;
455 int *ls_node_array; 465 int *ls_node_array;
466 gfp_t ls_allocation;
456 467
457 struct dlm_rsb ls_stub_rsb; /* for returning errors */ 468 struct dlm_rsb ls_stub_rsb; /* for returning errors */
458 struct dlm_lkb ls_stub_lkb; /* for returning errors */ 469 struct dlm_lkb ls_stub_lkb; /* for returning errors */
@@ -460,9 +471,12 @@ struct dlm_ls {
460 471
461 struct dentry *ls_debug_rsb_dentry; /* debugfs */ 472 struct dentry *ls_debug_rsb_dentry; /* debugfs */
462 struct dentry *ls_debug_waiters_dentry; /* debugfs */ 473 struct dentry *ls_debug_waiters_dentry; /* debugfs */
474 struct dentry *ls_debug_locks_dentry; /* debugfs */
463 475
464 wait_queue_head_t ls_uevent_wait; /* user part of join/leave */ 476 wait_queue_head_t ls_uevent_wait; /* user part of join/leave */
465 int ls_uevent_result; 477 int ls_uevent_result;
478 struct completion ls_members_done;
479 int ls_members_result;
466 480
467 struct miscdevice ls_device; 481 struct miscdevice ls_device;
468 482
@@ -472,6 +486,7 @@ struct dlm_ls {
472 struct task_struct *ls_recoverd_task; 486 struct task_struct *ls_recoverd_task;
473 struct mutex ls_recoverd_active; 487 struct mutex ls_recoverd_active;
474 spinlock_t ls_recover_lock; 488 spinlock_t ls_recover_lock;
489 unsigned long ls_recover_begin; /* jiffies timestamp */
475 uint32_t ls_recover_status; /* DLM_RS_ */ 490 uint32_t ls_recover_status; /* DLM_RS_ */
476 uint64_t ls_recover_seq; 491 uint64_t ls_recover_seq;
477 struct dlm_recover *ls_recover_args; 492 struct dlm_recover *ls_recover_args;
@@ -501,6 +516,7 @@ struct dlm_ls {
501#define LSFL_RCOM_READY 3 516#define LSFL_RCOM_READY 3
502#define LSFL_RCOM_WAIT 4 517#define LSFL_RCOM_WAIT 4
503#define LSFL_UEVENT_WAIT 5 518#define LSFL_UEVENT_WAIT 5
519#define LSFL_TIMEWARN 6
504 520
505/* much of this is just saving user space pointers associated with the 521/* much of this is just saving user space pointers associated with the
506 lock that we pass back to the user lib with an ast */ 522 lock that we pass back to the user lib with an ast */
@@ -518,6 +534,7 @@ struct dlm_user_args {
518 void __user *castaddr; 534 void __user *castaddr;
519 void __user *bastparam; 535 void __user *bastparam;
520 void __user *bastaddr; 536 void __user *bastaddr;
537 uint64_t xid;
521}; 538};
522 539
523#define DLM_PROC_FLAGS_CLOSING 1 540#define DLM_PROC_FLAGS_CLOSING 1
diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c
index d8d6e729f96b..b455919c1998 100644
--- a/fs/dlm/lock.c
+++ b/fs/dlm/lock.c
@@ -82,10 +82,13 @@ static int send_bast(struct dlm_rsb *r, struct dlm_lkb *lkb, int mode);
82static int send_lookup(struct dlm_rsb *r, struct dlm_lkb *lkb); 82static int send_lookup(struct dlm_rsb *r, struct dlm_lkb *lkb);
83static int send_remove(struct dlm_rsb *r); 83static int send_remove(struct dlm_rsb *r);
84static int _request_lock(struct dlm_rsb *r, struct dlm_lkb *lkb); 84static int _request_lock(struct dlm_rsb *r, struct dlm_lkb *lkb);
85static int _cancel_lock(struct dlm_rsb *r, struct dlm_lkb *lkb);
85static void __receive_convert_reply(struct dlm_rsb *r, struct dlm_lkb *lkb, 86static void __receive_convert_reply(struct dlm_rsb *r, struct dlm_lkb *lkb,
86 struct dlm_message *ms); 87 struct dlm_message *ms);
87static int receive_extralen(struct dlm_message *ms); 88static int receive_extralen(struct dlm_message *ms);
88static void do_purge(struct dlm_ls *ls, int nodeid, int pid); 89static void do_purge(struct dlm_ls *ls, int nodeid, int pid);
90static void del_timeout(struct dlm_lkb *lkb);
91void dlm_timeout_warn(struct dlm_lkb *lkb);
89 92
90/* 93/*
91 * Lock compatibilty matrix - thanks Steve 94 * Lock compatibilty matrix - thanks Steve
@@ -194,17 +197,17 @@ void dlm_dump_rsb(struct dlm_rsb *r)
194 197
195/* Threads cannot use the lockspace while it's being recovered */ 198/* Threads cannot use the lockspace while it's being recovered */
196 199
197static inline void lock_recovery(struct dlm_ls *ls) 200static inline void dlm_lock_recovery(struct dlm_ls *ls)
198{ 201{
199 down_read(&ls->ls_in_recovery); 202 down_read(&ls->ls_in_recovery);
200} 203}
201 204
202static inline void unlock_recovery(struct dlm_ls *ls) 205void dlm_unlock_recovery(struct dlm_ls *ls)
203{ 206{
204 up_read(&ls->ls_in_recovery); 207 up_read(&ls->ls_in_recovery);
205} 208}
206 209
207static inline int lock_recovery_try(struct dlm_ls *ls) 210int dlm_lock_recovery_try(struct dlm_ls *ls)
208{ 211{
209 return down_read_trylock(&ls->ls_in_recovery); 212 return down_read_trylock(&ls->ls_in_recovery);
210} 213}
@@ -286,8 +289,22 @@ static void queue_cast(struct dlm_rsb *r, struct dlm_lkb *lkb, int rv)
286 if (is_master_copy(lkb)) 289 if (is_master_copy(lkb))
287 return; 290 return;
288 291
292 del_timeout(lkb);
293
289 DLM_ASSERT(lkb->lkb_lksb, dlm_print_lkb(lkb);); 294 DLM_ASSERT(lkb->lkb_lksb, dlm_print_lkb(lkb););
290 295
296 /* if the operation was a cancel, then return -DLM_ECANCEL, if a
297 timeout caused the cancel then return -ETIMEDOUT */
298 if (rv == -DLM_ECANCEL && (lkb->lkb_flags & DLM_IFL_TIMEOUT_CANCEL)) {
299 lkb->lkb_flags &= ~DLM_IFL_TIMEOUT_CANCEL;
300 rv = -ETIMEDOUT;
301 }
302
303 if (rv == -DLM_ECANCEL && (lkb->lkb_flags & DLM_IFL_DEADLOCK_CANCEL)) {
304 lkb->lkb_flags &= ~DLM_IFL_DEADLOCK_CANCEL;
305 rv = -EDEADLK;
306 }
307
291 lkb->lkb_lksb->sb_status = rv; 308 lkb->lkb_lksb->sb_status = rv;
292 lkb->lkb_lksb->sb_flags = lkb->lkb_sbflags; 309 lkb->lkb_lksb->sb_flags = lkb->lkb_sbflags;
293 310
@@ -581,6 +598,7 @@ static int create_lkb(struct dlm_ls *ls, struct dlm_lkb **lkb_ret)
581 kref_init(&lkb->lkb_ref); 598 kref_init(&lkb->lkb_ref);
582 INIT_LIST_HEAD(&lkb->lkb_ownqueue); 599 INIT_LIST_HEAD(&lkb->lkb_ownqueue);
583 INIT_LIST_HEAD(&lkb->lkb_rsb_lookup); 600 INIT_LIST_HEAD(&lkb->lkb_rsb_lookup);
601 INIT_LIST_HEAD(&lkb->lkb_time_list);
584 602
585 get_random_bytes(&bucket, sizeof(bucket)); 603 get_random_bytes(&bucket, sizeof(bucket));
586 bucket &= (ls->ls_lkbtbl_size - 1); 604 bucket &= (ls->ls_lkbtbl_size - 1);
@@ -985,15 +1003,136 @@ void dlm_scan_rsbs(struct dlm_ls *ls)
985{ 1003{
986 int i; 1004 int i;
987 1005
988 if (dlm_locking_stopped(ls))
989 return;
990
991 for (i = 0; i < ls->ls_rsbtbl_size; i++) { 1006 for (i = 0; i < ls->ls_rsbtbl_size; i++) {
992 shrink_bucket(ls, i); 1007 shrink_bucket(ls, i);
1008 if (dlm_locking_stopped(ls))
1009 break;
993 cond_resched(); 1010 cond_resched();
994 } 1011 }
995} 1012}
996 1013
1014static void add_timeout(struct dlm_lkb *lkb)
1015{
1016 struct dlm_ls *ls = lkb->lkb_resource->res_ls;
1017
1018 if (is_master_copy(lkb)) {
1019 lkb->lkb_timestamp = jiffies;
1020 return;
1021 }
1022
1023 if (test_bit(LSFL_TIMEWARN, &ls->ls_flags) &&
1024 !(lkb->lkb_exflags & DLM_LKF_NODLCKWT)) {
1025 lkb->lkb_flags |= DLM_IFL_WATCH_TIMEWARN;
1026 goto add_it;
1027 }
1028 if (lkb->lkb_exflags & DLM_LKF_TIMEOUT)
1029 goto add_it;
1030 return;
1031
1032 add_it:
1033 DLM_ASSERT(list_empty(&lkb->lkb_time_list), dlm_print_lkb(lkb););
1034 mutex_lock(&ls->ls_timeout_mutex);
1035 hold_lkb(lkb);
1036 lkb->lkb_timestamp = jiffies;
1037 list_add_tail(&lkb->lkb_time_list, &ls->ls_timeout);
1038 mutex_unlock(&ls->ls_timeout_mutex);
1039}
1040
1041static void del_timeout(struct dlm_lkb *lkb)
1042{
1043 struct dlm_ls *ls = lkb->lkb_resource->res_ls;
1044
1045 mutex_lock(&ls->ls_timeout_mutex);
1046 if (!list_empty(&lkb->lkb_time_list)) {
1047 list_del_init(&lkb->lkb_time_list);
1048 unhold_lkb(lkb);
1049 }
1050 mutex_unlock(&ls->ls_timeout_mutex);
1051}
1052
1053/* FIXME: is it safe to look at lkb_exflags, lkb_flags, lkb_timestamp, and
1054 lkb_lksb_timeout without lock_rsb? Note: we can't lock timeout_mutex
1055 and then lock rsb because of lock ordering in add_timeout. We may need
1056 to specify some special timeout-related bits in the lkb that are just to
1057 be accessed under the timeout_mutex. */
1058
1059void dlm_scan_timeout(struct dlm_ls *ls)
1060{
1061 struct dlm_rsb *r;
1062 struct dlm_lkb *lkb;
1063 int do_cancel, do_warn;
1064
1065 for (;;) {
1066 if (dlm_locking_stopped(ls))
1067 break;
1068
1069 do_cancel = 0;
1070 do_warn = 0;
1071 mutex_lock(&ls->ls_timeout_mutex);
1072 list_for_each_entry(lkb, &ls->ls_timeout, lkb_time_list) {
1073
1074 if ((lkb->lkb_exflags & DLM_LKF_TIMEOUT) &&
1075 time_after_eq(jiffies, lkb->lkb_timestamp +
1076 lkb->lkb_timeout_cs * HZ/100))
1077 do_cancel = 1;
1078
1079 if ((lkb->lkb_flags & DLM_IFL_WATCH_TIMEWARN) &&
1080 time_after_eq(jiffies, lkb->lkb_timestamp +
1081 dlm_config.ci_timewarn_cs * HZ/100))
1082 do_warn = 1;
1083
1084 if (!do_cancel && !do_warn)
1085 continue;
1086 hold_lkb(lkb);
1087 break;
1088 }
1089 mutex_unlock(&ls->ls_timeout_mutex);
1090
1091 if (!do_cancel && !do_warn)
1092 break;
1093
1094 r = lkb->lkb_resource;
1095 hold_rsb(r);
1096 lock_rsb(r);
1097
1098 if (do_warn) {
1099 /* clear flag so we only warn once */
1100 lkb->lkb_flags &= ~DLM_IFL_WATCH_TIMEWARN;
1101 if (!(lkb->lkb_exflags & DLM_LKF_TIMEOUT))
1102 del_timeout(lkb);
1103 dlm_timeout_warn(lkb);
1104 }
1105
1106 if (do_cancel) {
1107 log_debug(ls, "timeout cancel %x node %d %s",
1108 lkb->lkb_id, lkb->lkb_nodeid, r->res_name);
1109 lkb->lkb_flags &= ~DLM_IFL_WATCH_TIMEWARN;
1110 lkb->lkb_flags |= DLM_IFL_TIMEOUT_CANCEL;
1111 del_timeout(lkb);
1112 _cancel_lock(r, lkb);
1113 }
1114
1115 unlock_rsb(r);
1116 unhold_rsb(r);
1117 dlm_put_lkb(lkb);
1118 }
1119}
1120
1121/* This is only called by dlm_recoverd, and we rely on dlm_ls_stop() stopping
1122 dlm_recoverd before checking/setting ls_recover_begin. */
1123
1124void dlm_adjust_timeouts(struct dlm_ls *ls)
1125{
1126 struct dlm_lkb *lkb;
1127 long adj = jiffies - ls->ls_recover_begin;
1128
1129 ls->ls_recover_begin = 0;
1130 mutex_lock(&ls->ls_timeout_mutex);
1131 list_for_each_entry(lkb, &ls->ls_timeout, lkb_time_list)
1132 lkb->lkb_timestamp += adj;
1133 mutex_unlock(&ls->ls_timeout_mutex);
1134}
1135
997/* lkb is master or local copy */ 1136/* lkb is master or local copy */
998 1137
999static void set_lvb_lock(struct dlm_rsb *r, struct dlm_lkb *lkb) 1138static void set_lvb_lock(struct dlm_rsb *r, struct dlm_lkb *lkb)
@@ -1275,10 +1414,8 @@ static int queue_conflict(struct list_head *head, struct dlm_lkb *lkb)
1275 * queue for one resource. The granted mode of each lock blocks the requested 1414 * queue for one resource. The granted mode of each lock blocks the requested
1276 * mode of the other lock." 1415 * mode of the other lock."
1277 * 1416 *
1278 * Part 2: if the granted mode of lkb is preventing the first lkb in the 1417 * Part 2: if the granted mode of lkb is preventing an earlier lkb in the
1279 * convert queue from being granted, then demote lkb (set grmode to NL). 1418 * convert queue from being granted, then deadlk/demote lkb.
1280 * This second form requires that we check for conv-deadlk even when
1281 * now == 0 in _can_be_granted().
1282 * 1419 *
1283 * Example: 1420 * Example:
1284 * Granted Queue: empty 1421 * Granted Queue: empty
@@ -1287,41 +1424,52 @@ static int queue_conflict(struct list_head *head, struct dlm_lkb *lkb)
1287 * 1424 *
1288 * The first lock can't be granted because of the granted mode of the second 1425 * The first lock can't be granted because of the granted mode of the second
1289 * lock and the second lock can't be granted because it's not first in the 1426 * lock and the second lock can't be granted because it's not first in the
1290 * list. We demote the granted mode of the second lock (the lkb passed to this 1427 * list. We either cancel lkb's conversion (PR->EX) and return EDEADLK, or we
1291 * function). 1428 * demote the granted mode of lkb (from PR to NL) if it has the CONVDEADLK
1429 * flag set and return DEMOTED in the lksb flags.
1430 *
1431 * Originally, this function detected conv-deadlk in a more limited scope:
1432 * - if !modes_compat(lkb1, lkb2) && !modes_compat(lkb2, lkb1), or
1433 * - if lkb1 was the first entry in the queue (not just earlier), and was
1434 * blocked by the granted mode of lkb2, and there was nothing on the
1435 * granted queue preventing lkb1 from being granted immediately, i.e.
1436 * lkb2 was the only thing preventing lkb1 from being granted.
1437 *
1438 * That second condition meant we'd only say there was conv-deadlk if
1439 * resolving it (by demotion) would lead to the first lock on the convert
1440 * queue being granted right away. It allowed conversion deadlocks to exist
1441 * between locks on the convert queue while they couldn't be granted anyway.
1292 * 1442 *
1293 * After the resolution, the "grant pending" function needs to go back and try 1443 * Now, we detect and take action on conversion deadlocks immediately when
1294 * to grant locks on the convert queue again since the first lock can now be 1444 * they're created, even if they may not be immediately consequential. If
1295 * granted. 1445 * lkb1 exists anywhere in the convert queue and lkb2 comes in with a granted
1446 * mode that would prevent lkb1's conversion from being granted, we do a
1447 * deadlk/demote on lkb2 right away and don't let it onto the convert queue.
1448 * I think this means that the lkb_is_ahead condition below should always
1449 * be zero, i.e. there will never be conv-deadlk between two locks that are
1450 * both already on the convert queue.
1296 */ 1451 */
1297 1452
1298static int conversion_deadlock_detect(struct dlm_rsb *rsb, struct dlm_lkb *lkb) 1453static int conversion_deadlock_detect(struct dlm_rsb *r, struct dlm_lkb *lkb2)
1299{ 1454{
1300 struct dlm_lkb *this, *first = NULL, *self = NULL; 1455 struct dlm_lkb *lkb1;
1456 int lkb_is_ahead = 0;
1301 1457
1302 list_for_each_entry(this, &rsb->res_convertqueue, lkb_statequeue) { 1458 list_for_each_entry(lkb1, &r->res_convertqueue, lkb_statequeue) {
1303 if (!first) 1459 if (lkb1 == lkb2) {
1304 first = this; 1460 lkb_is_ahead = 1;
1305 if (this == lkb) {
1306 self = lkb;
1307 continue; 1461 continue;
1308 } 1462 }
1309 1463
1310 if (!modes_compat(this, lkb) && !modes_compat(lkb, this)) 1464 if (!lkb_is_ahead) {
1311 return 1; 1465 if (!modes_compat(lkb2, lkb1))
1312 } 1466 return 1;
1313 1467 } else {
1314 /* if lkb is on the convert queue and is preventing the first 1468 if (!modes_compat(lkb2, lkb1) &&
1315 from being granted, then there's deadlock and we demote lkb. 1469 !modes_compat(lkb1, lkb2))
1316 multiple converting locks may need to do this before the first 1470 return 1;
1317 converting lock can be granted. */ 1471 }
1318
1319 if (self && self != first) {
1320 if (!modes_compat(lkb, first) &&
1321 !queue_conflict(&rsb->res_grantqueue, first))
1322 return 1;
1323 } 1472 }
1324
1325 return 0; 1473 return 0;
1326} 1474}
1327 1475
@@ -1450,42 +1598,57 @@ static int _can_be_granted(struct dlm_rsb *r, struct dlm_lkb *lkb, int now)
1450 if (!now && !conv && list_empty(&r->res_convertqueue) && 1598 if (!now && !conv && list_empty(&r->res_convertqueue) &&
1451 first_in_list(lkb, &r->res_waitqueue)) 1599 first_in_list(lkb, &r->res_waitqueue))
1452 return 1; 1600 return 1;
1453
1454 out: 1601 out:
1455 /*
1456 * The following, enabled by CONVDEADLK, departs from VMS.
1457 */
1458
1459 if (conv && (lkb->lkb_exflags & DLM_LKF_CONVDEADLK) &&
1460 conversion_deadlock_detect(r, lkb)) {
1461 lkb->lkb_grmode = DLM_LOCK_NL;
1462 lkb->lkb_sbflags |= DLM_SBF_DEMOTED;
1463 }
1464
1465 return 0; 1602 return 0;
1466} 1603}
1467 1604
1468/* 1605static int can_be_granted(struct dlm_rsb *r, struct dlm_lkb *lkb, int now,
1469 * The ALTPR and ALTCW flags aren't traditional lock manager flags, but are a 1606 int *err)
1470 * simple way to provide a big optimization to applications that can use them.
1471 */
1472
1473static int can_be_granted(struct dlm_rsb *r, struct dlm_lkb *lkb, int now)
1474{ 1607{
1475 uint32_t flags = lkb->lkb_exflags;
1476 int rv; 1608 int rv;
1477 int8_t alt = 0, rqmode = lkb->lkb_rqmode; 1609 int8_t alt = 0, rqmode = lkb->lkb_rqmode;
1610 int8_t is_convert = (lkb->lkb_grmode != DLM_LOCK_IV);
1611
1612 if (err)
1613 *err = 0;
1478 1614
1479 rv = _can_be_granted(r, lkb, now); 1615 rv = _can_be_granted(r, lkb, now);
1480 if (rv) 1616 if (rv)
1481 goto out; 1617 goto out;
1482 1618
1483 if (lkb->lkb_sbflags & DLM_SBF_DEMOTED) 1619 /*
1620 * The CONVDEADLK flag is non-standard and tells the dlm to resolve
1621 * conversion deadlocks by demoting grmode to NL, otherwise the dlm
1622 * cancels one of the locks.
1623 */
1624
1625 if (is_convert && can_be_queued(lkb) &&
1626 conversion_deadlock_detect(r, lkb)) {
1627 if (lkb->lkb_exflags & DLM_LKF_CONVDEADLK) {
1628 lkb->lkb_grmode = DLM_LOCK_NL;
1629 lkb->lkb_sbflags |= DLM_SBF_DEMOTED;
1630 } else if (!(lkb->lkb_exflags & DLM_LKF_NODLCKWT)) {
1631 if (err)
1632 *err = -EDEADLK;
1633 else {
1634 log_print("can_be_granted deadlock %x now %d",
1635 lkb->lkb_id, now);
1636 dlm_dump_rsb(r);
1637 }
1638 }
1484 goto out; 1639 goto out;
1640 }
1485 1641
1486 if (rqmode != DLM_LOCK_PR && flags & DLM_LKF_ALTPR) 1642 /*
1643 * The ALTPR and ALTCW flags are non-standard and tell the dlm to try
1644 * to grant a request in a mode other than the normal rqmode. It's a
1645 * simple way to provide a big optimization to applications that can
1646 * use them.
1647 */
1648
1649 if (rqmode != DLM_LOCK_PR && (lkb->lkb_exflags & DLM_LKF_ALTPR))
1487 alt = DLM_LOCK_PR; 1650 alt = DLM_LOCK_PR;
1488 else if (rqmode != DLM_LOCK_CW && flags & DLM_LKF_ALTCW) 1651 else if (rqmode != DLM_LOCK_CW && (lkb->lkb_exflags & DLM_LKF_ALTCW))
1489 alt = DLM_LOCK_CW; 1652 alt = DLM_LOCK_CW;
1490 1653
1491 if (alt) { 1654 if (alt) {
@@ -1500,10 +1663,20 @@ static int can_be_granted(struct dlm_rsb *r, struct dlm_lkb *lkb, int now)
1500 return rv; 1663 return rv;
1501} 1664}
1502 1665
1666/* FIXME: I don't think that can_be_granted() can/will demote or find deadlock
1667 for locks pending on the convert list. Once verified (watch for these
1668 log_prints), we should be able to just call _can_be_granted() and not
1669 bother with the demote/deadlk cases here (and there's no easy way to deal
1670 with a deadlk here, we'd have to generate something like grant_lock with
1671 the deadlk error.) */
1672
1673/* returns the highest requested mode of all blocked conversions */
1674
1503static int grant_pending_convert(struct dlm_rsb *r, int high) 1675static int grant_pending_convert(struct dlm_rsb *r, int high)
1504{ 1676{
1505 struct dlm_lkb *lkb, *s; 1677 struct dlm_lkb *lkb, *s;
1506 int hi, demoted, quit, grant_restart, demote_restart; 1678 int hi, demoted, quit, grant_restart, demote_restart;
1679 int deadlk;
1507 1680
1508 quit = 0; 1681 quit = 0;
1509 restart: 1682 restart:
@@ -1513,14 +1686,29 @@ static int grant_pending_convert(struct dlm_rsb *r, int high)
1513 1686
1514 list_for_each_entry_safe(lkb, s, &r->res_convertqueue, lkb_statequeue) { 1687 list_for_each_entry_safe(lkb, s, &r->res_convertqueue, lkb_statequeue) {
1515 demoted = is_demoted(lkb); 1688 demoted = is_demoted(lkb);
1516 if (can_be_granted(r, lkb, 0)) { 1689 deadlk = 0;
1690
1691 if (can_be_granted(r, lkb, 0, &deadlk)) {
1517 grant_lock_pending(r, lkb); 1692 grant_lock_pending(r, lkb);
1518 grant_restart = 1; 1693 grant_restart = 1;
1519 } else { 1694 continue;
1520 hi = max_t(int, lkb->lkb_rqmode, hi);
1521 if (!demoted && is_demoted(lkb))
1522 demote_restart = 1;
1523 } 1695 }
1696
1697 if (!demoted && is_demoted(lkb)) {
1698 log_print("WARN: pending demoted %x node %d %s",
1699 lkb->lkb_id, lkb->lkb_nodeid, r->res_name);
1700 demote_restart = 1;
1701 continue;
1702 }
1703
1704 if (deadlk) {
1705 log_print("WARN: pending deadlock %x node %d %s",
1706 lkb->lkb_id, lkb->lkb_nodeid, r->res_name);
1707 dlm_dump_rsb(r);
1708 continue;
1709 }
1710
1711 hi = max_t(int, lkb->lkb_rqmode, hi);
1524 } 1712 }
1525 1713
1526 if (grant_restart) 1714 if (grant_restart)
@@ -1538,7 +1726,7 @@ static int grant_pending_wait(struct dlm_rsb *r, int high)
1538 struct dlm_lkb *lkb, *s; 1726 struct dlm_lkb *lkb, *s;
1539 1727
1540 list_for_each_entry_safe(lkb, s, &r->res_waitqueue, lkb_statequeue) { 1728 list_for_each_entry_safe(lkb, s, &r->res_waitqueue, lkb_statequeue) {
1541 if (can_be_granted(r, lkb, 0)) 1729 if (can_be_granted(r, lkb, 0, NULL))
1542 grant_lock_pending(r, lkb); 1730 grant_lock_pending(r, lkb);
1543 else 1731 else
1544 high = max_t(int, lkb->lkb_rqmode, high); 1732 high = max_t(int, lkb->lkb_rqmode, high);
@@ -1733,7 +1921,7 @@ static void confirm_master(struct dlm_rsb *r, int error)
1733} 1921}
1734 1922
1735static int set_lock_args(int mode, struct dlm_lksb *lksb, uint32_t flags, 1923static int set_lock_args(int mode, struct dlm_lksb *lksb, uint32_t flags,
1736 int namelen, uint32_t parent_lkid, void *ast, 1924 int namelen, unsigned long timeout_cs, void *ast,
1737 void *astarg, void *bast, struct dlm_args *args) 1925 void *astarg, void *bast, struct dlm_args *args)
1738{ 1926{
1739 int rv = -EINVAL; 1927 int rv = -EINVAL;
@@ -1776,10 +1964,6 @@ static int set_lock_args(int mode, struct dlm_lksb *lksb, uint32_t flags,
1776 if (flags & DLM_LKF_VALBLK && !lksb->sb_lvbptr) 1964 if (flags & DLM_LKF_VALBLK && !lksb->sb_lvbptr)
1777 goto out; 1965 goto out;
1778 1966
1779 /* parent/child locks not yet supported */
1780 if (parent_lkid)
1781 goto out;
1782
1783 if (flags & DLM_LKF_CONVERT && !lksb->sb_lkid) 1967 if (flags & DLM_LKF_CONVERT && !lksb->sb_lkid)
1784 goto out; 1968 goto out;
1785 1969
@@ -1791,6 +1975,7 @@ static int set_lock_args(int mode, struct dlm_lksb *lksb, uint32_t flags,
1791 args->astaddr = ast; 1975 args->astaddr = ast;
1792 args->astparam = (long) astarg; 1976 args->astparam = (long) astarg;
1793 args->bastaddr = bast; 1977 args->bastaddr = bast;
1978 args->timeout = timeout_cs;
1794 args->mode = mode; 1979 args->mode = mode;
1795 args->lksb = lksb; 1980 args->lksb = lksb;
1796 rv = 0; 1981 rv = 0;
@@ -1845,6 +2030,7 @@ static int validate_lock_args(struct dlm_ls *ls, struct dlm_lkb *lkb,
1845 lkb->lkb_lksb = args->lksb; 2030 lkb->lkb_lksb = args->lksb;
1846 lkb->lkb_lvbptr = args->lksb->sb_lvbptr; 2031 lkb->lkb_lvbptr = args->lksb->sb_lvbptr;
1847 lkb->lkb_ownpid = (int) current->pid; 2032 lkb->lkb_ownpid = (int) current->pid;
2033 lkb->lkb_timeout_cs = args->timeout;
1848 rv = 0; 2034 rv = 0;
1849 out: 2035 out:
1850 return rv; 2036 return rv;
@@ -1903,6 +2089,9 @@ static int validate_unlock_args(struct dlm_lkb *lkb, struct dlm_args *args)
1903 if (is_overlap(lkb)) 2089 if (is_overlap(lkb))
1904 goto out; 2090 goto out;
1905 2091
2092 /* don't let scand try to do a cancel */
2093 del_timeout(lkb);
2094
1906 if (lkb->lkb_flags & DLM_IFL_RESEND) { 2095 if (lkb->lkb_flags & DLM_IFL_RESEND) {
1907 lkb->lkb_flags |= DLM_IFL_OVERLAP_CANCEL; 2096 lkb->lkb_flags |= DLM_IFL_OVERLAP_CANCEL;
1908 rv = -EBUSY; 2097 rv = -EBUSY;
@@ -1934,6 +2123,9 @@ static int validate_unlock_args(struct dlm_lkb *lkb, struct dlm_args *args)
1934 if (is_overlap_unlock(lkb)) 2123 if (is_overlap_unlock(lkb))
1935 goto out; 2124 goto out;
1936 2125
2126 /* don't let scand try to do a cancel */
2127 del_timeout(lkb);
2128
1937 if (lkb->lkb_flags & DLM_IFL_RESEND) { 2129 if (lkb->lkb_flags & DLM_IFL_RESEND) {
1938 lkb->lkb_flags |= DLM_IFL_OVERLAP_UNLOCK; 2130 lkb->lkb_flags |= DLM_IFL_OVERLAP_UNLOCK;
1939 rv = -EBUSY; 2131 rv = -EBUSY;
@@ -1984,7 +2176,7 @@ static int do_request(struct dlm_rsb *r, struct dlm_lkb *lkb)
1984{ 2176{
1985 int error = 0; 2177 int error = 0;
1986 2178
1987 if (can_be_granted(r, lkb, 1)) { 2179 if (can_be_granted(r, lkb, 1, NULL)) {
1988 grant_lock(r, lkb); 2180 grant_lock(r, lkb);
1989 queue_cast(r, lkb, 0); 2181 queue_cast(r, lkb, 0);
1990 goto out; 2182 goto out;
@@ -1994,6 +2186,7 @@ static int do_request(struct dlm_rsb *r, struct dlm_lkb *lkb)
1994 error = -EINPROGRESS; 2186 error = -EINPROGRESS;
1995 add_lkb(r, lkb, DLM_LKSTS_WAITING); 2187 add_lkb(r, lkb, DLM_LKSTS_WAITING);
1996 send_blocking_asts(r, lkb); 2188 send_blocking_asts(r, lkb);
2189 add_timeout(lkb);
1997 goto out; 2190 goto out;
1998 } 2191 }
1999 2192
@@ -2009,16 +2202,32 @@ static int do_request(struct dlm_rsb *r, struct dlm_lkb *lkb)
2009static int do_convert(struct dlm_rsb *r, struct dlm_lkb *lkb) 2202static int do_convert(struct dlm_rsb *r, struct dlm_lkb *lkb)
2010{ 2203{
2011 int error = 0; 2204 int error = 0;
2205 int deadlk = 0;
2012 2206
2013 /* changing an existing lock may allow others to be granted */ 2207 /* changing an existing lock may allow others to be granted */
2014 2208
2015 if (can_be_granted(r, lkb, 1)) { 2209 if (can_be_granted(r, lkb, 1, &deadlk)) {
2016 grant_lock(r, lkb); 2210 grant_lock(r, lkb);
2017 queue_cast(r, lkb, 0); 2211 queue_cast(r, lkb, 0);
2018 grant_pending_locks(r); 2212 grant_pending_locks(r);
2019 goto out; 2213 goto out;
2020 } 2214 }
2021 2215
2216 /* can_be_granted() detected that this lock would block in a conversion
2217 deadlock, so we leave it on the granted queue and return EDEADLK in
2218 the ast for the convert. */
2219
2220 if (deadlk) {
2221 /* it's left on the granted queue */
2222 log_debug(r->res_ls, "deadlock %x node %d sts%d g%d r%d %s",
2223 lkb->lkb_id, lkb->lkb_nodeid, lkb->lkb_status,
2224 lkb->lkb_grmode, lkb->lkb_rqmode, r->res_name);
2225 revert_lock(r, lkb);
2226 queue_cast(r, lkb, -EDEADLK);
2227 error = -EDEADLK;
2228 goto out;
2229 }
2230
2022 /* is_demoted() means the can_be_granted() above set the grmode 2231 /* is_demoted() means the can_be_granted() above set the grmode
2023 to NL, and left us on the granted queue. This auto-demotion 2232 to NL, and left us on the granted queue. This auto-demotion
2024 (due to CONVDEADLK) might mean other locks, and/or this lock, are 2233 (due to CONVDEADLK) might mean other locks, and/or this lock, are
@@ -2041,6 +2250,7 @@ static int do_convert(struct dlm_rsb *r, struct dlm_lkb *lkb)
2041 del_lkb(r, lkb); 2250 del_lkb(r, lkb);
2042 add_lkb(r, lkb, DLM_LKSTS_CONVERT); 2251 add_lkb(r, lkb, DLM_LKSTS_CONVERT);
2043 send_blocking_asts(r, lkb); 2252 send_blocking_asts(r, lkb);
2253 add_timeout(lkb);
2044 goto out; 2254 goto out;
2045 } 2255 }
2046 2256
@@ -2274,7 +2484,7 @@ int dlm_lock(dlm_lockspace_t *lockspace,
2274 if (!ls) 2484 if (!ls)
2275 return -EINVAL; 2485 return -EINVAL;
2276 2486
2277 lock_recovery(ls); 2487 dlm_lock_recovery(ls);
2278 2488
2279 if (convert) 2489 if (convert)
2280 error = find_lkb(ls, lksb->sb_lkid, &lkb); 2490 error = find_lkb(ls, lksb->sb_lkid, &lkb);
@@ -2284,7 +2494,7 @@ int dlm_lock(dlm_lockspace_t *lockspace,
2284 if (error) 2494 if (error)
2285 goto out; 2495 goto out;
2286 2496
2287 error = set_lock_args(mode, lksb, flags, namelen, parent_lkid, ast, 2497 error = set_lock_args(mode, lksb, flags, namelen, 0, ast,
2288 astarg, bast, &args); 2498 astarg, bast, &args);
2289 if (error) 2499 if (error)
2290 goto out_put; 2500 goto out_put;
@@ -2299,10 +2509,10 @@ int dlm_lock(dlm_lockspace_t *lockspace,
2299 out_put: 2509 out_put:
2300 if (convert || error) 2510 if (convert || error)
2301 __put_lkb(ls, lkb); 2511 __put_lkb(ls, lkb);
2302 if (error == -EAGAIN) 2512 if (error == -EAGAIN || error == -EDEADLK)
2303 error = 0; 2513 error = 0;
2304 out: 2514 out:
2305 unlock_recovery(ls); 2515 dlm_unlock_recovery(ls);
2306 dlm_put_lockspace(ls); 2516 dlm_put_lockspace(ls);
2307 return error; 2517 return error;
2308} 2518}
@@ -2322,7 +2532,7 @@ int dlm_unlock(dlm_lockspace_t *lockspace,
2322 if (!ls) 2532 if (!ls)
2323 return -EINVAL; 2533 return -EINVAL;
2324 2534
2325 lock_recovery(ls); 2535 dlm_lock_recovery(ls);
2326 2536
2327 error = find_lkb(ls, lkid, &lkb); 2537 error = find_lkb(ls, lkid, &lkb);
2328 if (error) 2538 if (error)
@@ -2344,7 +2554,7 @@ int dlm_unlock(dlm_lockspace_t *lockspace,
2344 out_put: 2554 out_put:
2345 dlm_put_lkb(lkb); 2555 dlm_put_lkb(lkb);
2346 out: 2556 out:
2347 unlock_recovery(ls); 2557 dlm_unlock_recovery(ls);
2348 dlm_put_lockspace(ls); 2558 dlm_put_lockspace(ls);
2349 return error; 2559 return error;
2350} 2560}
@@ -2384,7 +2594,7 @@ static int _create_message(struct dlm_ls *ls, int mb_len,
2384 pass into lowcomms_commit and a message buffer (mb) that we 2594 pass into lowcomms_commit and a message buffer (mb) that we
2385 write our data into */ 2595 write our data into */
2386 2596
2387 mh = dlm_lowcomms_get_buffer(to_nodeid, mb_len, GFP_KERNEL, &mb); 2597 mh = dlm_lowcomms_get_buffer(to_nodeid, mb_len, ls->ls_allocation, &mb);
2388 if (!mh) 2598 if (!mh)
2389 return -ENOBUFS; 2599 return -ENOBUFS;
2390 2600
@@ -3111,9 +3321,10 @@ static void receive_request_reply(struct dlm_ls *ls, struct dlm_message *ms)
3111 lkb->lkb_remid = ms->m_lkid; 3321 lkb->lkb_remid = ms->m_lkid;
3112 if (is_altmode(lkb)) 3322 if (is_altmode(lkb))
3113 munge_altmode(lkb, ms); 3323 munge_altmode(lkb, ms);
3114 if (result) 3324 if (result) {
3115 add_lkb(r, lkb, DLM_LKSTS_WAITING); 3325 add_lkb(r, lkb, DLM_LKSTS_WAITING);
3116 else { 3326 add_timeout(lkb);
3327 } else {
3117 grant_lock_pc(r, lkb, ms); 3328 grant_lock_pc(r, lkb, ms);
3118 queue_cast(r, lkb, 0); 3329 queue_cast(r, lkb, 0);
3119 } 3330 }
@@ -3172,6 +3383,12 @@ static void __receive_convert_reply(struct dlm_rsb *r, struct dlm_lkb *lkb,
3172 queue_cast(r, lkb, -EAGAIN); 3383 queue_cast(r, lkb, -EAGAIN);
3173 break; 3384 break;
3174 3385
3386 case -EDEADLK:
3387 receive_flags_reply(lkb, ms);
3388 revert_lock_pc(r, lkb);
3389 queue_cast(r, lkb, -EDEADLK);
3390 break;
3391
3175 case -EINPROGRESS: 3392 case -EINPROGRESS:
3176 /* convert was queued on remote master */ 3393 /* convert was queued on remote master */
3177 receive_flags_reply(lkb, ms); 3394 receive_flags_reply(lkb, ms);
@@ -3179,6 +3396,7 @@ static void __receive_convert_reply(struct dlm_rsb *r, struct dlm_lkb *lkb,
3179 munge_demoted(lkb, ms); 3396 munge_demoted(lkb, ms);
3180 del_lkb(r, lkb); 3397 del_lkb(r, lkb);
3181 add_lkb(r, lkb, DLM_LKSTS_CONVERT); 3398 add_lkb(r, lkb, DLM_LKSTS_CONVERT);
3399 add_timeout(lkb);
3182 break; 3400 break;
3183 3401
3184 case 0: 3402 case 0:
@@ -3298,8 +3516,7 @@ static void _receive_cancel_reply(struct dlm_lkb *lkb, struct dlm_message *ms)
3298 case -DLM_ECANCEL: 3516 case -DLM_ECANCEL:
3299 receive_flags_reply(lkb, ms); 3517 receive_flags_reply(lkb, ms);
3300 revert_lock_pc(r, lkb); 3518 revert_lock_pc(r, lkb);
3301 if (ms->m_result) 3519 queue_cast(r, lkb, -DLM_ECANCEL);
3302 queue_cast(r, lkb, -DLM_ECANCEL);
3303 break; 3520 break;
3304 case 0: 3521 case 0:
3305 break; 3522 break;
@@ -3424,7 +3641,7 @@ int dlm_receive_message(struct dlm_header *hd, int nodeid, int recovery)
3424 } 3641 }
3425 } 3642 }
3426 3643
3427 if (lock_recovery_try(ls)) 3644 if (dlm_lock_recovery_try(ls))
3428 break; 3645 break;
3429 schedule(); 3646 schedule();
3430 } 3647 }
@@ -3503,7 +3720,7 @@ int dlm_receive_message(struct dlm_header *hd, int nodeid, int recovery)
3503 log_error(ls, "unknown message type %d", ms->m_type); 3720 log_error(ls, "unknown message type %d", ms->m_type);
3504 } 3721 }
3505 3722
3506 unlock_recovery(ls); 3723 dlm_unlock_recovery(ls);
3507 out: 3724 out:
3508 dlm_put_lockspace(ls); 3725 dlm_put_lockspace(ls);
3509 dlm_astd_wake(); 3726 dlm_astd_wake();
@@ -4034,13 +4251,13 @@ int dlm_recover_process_copy(struct dlm_ls *ls, struct dlm_rcom *rc)
4034 4251
4035int dlm_user_request(struct dlm_ls *ls, struct dlm_user_args *ua, 4252int dlm_user_request(struct dlm_ls *ls, struct dlm_user_args *ua,
4036 int mode, uint32_t flags, void *name, unsigned int namelen, 4253 int mode, uint32_t flags, void *name, unsigned int namelen,
4037 uint32_t parent_lkid) 4254 unsigned long timeout_cs)
4038{ 4255{
4039 struct dlm_lkb *lkb; 4256 struct dlm_lkb *lkb;
4040 struct dlm_args args; 4257 struct dlm_args args;
4041 int error; 4258 int error;
4042 4259
4043 lock_recovery(ls); 4260 dlm_lock_recovery(ls);
4044 4261
4045 error = create_lkb(ls, &lkb); 4262 error = create_lkb(ls, &lkb);
4046 if (error) { 4263 if (error) {
@@ -4062,7 +4279,7 @@ int dlm_user_request(struct dlm_ls *ls, struct dlm_user_args *ua,
4062 When DLM_IFL_USER is set, the dlm knows that this is a userspace 4279 When DLM_IFL_USER is set, the dlm knows that this is a userspace
4063 lock and that lkb_astparam is the dlm_user_args structure. */ 4280 lock and that lkb_astparam is the dlm_user_args structure. */
4064 4281
4065 error = set_lock_args(mode, &ua->lksb, flags, namelen, parent_lkid, 4282 error = set_lock_args(mode, &ua->lksb, flags, namelen, timeout_cs,
4066 DLM_FAKE_USER_AST, ua, DLM_FAKE_USER_AST, &args); 4283 DLM_FAKE_USER_AST, ua, DLM_FAKE_USER_AST, &args);
4067 lkb->lkb_flags |= DLM_IFL_USER; 4284 lkb->lkb_flags |= DLM_IFL_USER;
4068 ua->old_mode = DLM_LOCK_IV; 4285 ua->old_mode = DLM_LOCK_IV;
@@ -4094,19 +4311,20 @@ int dlm_user_request(struct dlm_ls *ls, struct dlm_user_args *ua,
4094 list_add_tail(&lkb->lkb_ownqueue, &ua->proc->locks); 4311 list_add_tail(&lkb->lkb_ownqueue, &ua->proc->locks);
4095 spin_unlock(&ua->proc->locks_spin); 4312 spin_unlock(&ua->proc->locks_spin);
4096 out: 4313 out:
4097 unlock_recovery(ls); 4314 dlm_unlock_recovery(ls);
4098 return error; 4315 return error;
4099} 4316}
4100 4317
4101int dlm_user_convert(struct dlm_ls *ls, struct dlm_user_args *ua_tmp, 4318int dlm_user_convert(struct dlm_ls *ls, struct dlm_user_args *ua_tmp,
4102 int mode, uint32_t flags, uint32_t lkid, char *lvb_in) 4319 int mode, uint32_t flags, uint32_t lkid, char *lvb_in,
4320 unsigned long timeout_cs)
4103{ 4321{
4104 struct dlm_lkb *lkb; 4322 struct dlm_lkb *lkb;
4105 struct dlm_args args; 4323 struct dlm_args args;
4106 struct dlm_user_args *ua; 4324 struct dlm_user_args *ua;
4107 int error; 4325 int error;
4108 4326
4109 lock_recovery(ls); 4327 dlm_lock_recovery(ls);
4110 4328
4111 error = find_lkb(ls, lkid, &lkb); 4329 error = find_lkb(ls, lkid, &lkb);
4112 if (error) 4330 if (error)
@@ -4127,6 +4345,7 @@ int dlm_user_convert(struct dlm_ls *ls, struct dlm_user_args *ua_tmp,
4127 if (lvb_in && ua->lksb.sb_lvbptr) 4345 if (lvb_in && ua->lksb.sb_lvbptr)
4128 memcpy(ua->lksb.sb_lvbptr, lvb_in, DLM_USER_LVB_LEN); 4346 memcpy(ua->lksb.sb_lvbptr, lvb_in, DLM_USER_LVB_LEN);
4129 4347
4348 ua->xid = ua_tmp->xid;
4130 ua->castparam = ua_tmp->castparam; 4349 ua->castparam = ua_tmp->castparam;
4131 ua->castaddr = ua_tmp->castaddr; 4350 ua->castaddr = ua_tmp->castaddr;
4132 ua->bastparam = ua_tmp->bastparam; 4351 ua->bastparam = ua_tmp->bastparam;
@@ -4134,19 +4353,19 @@ int dlm_user_convert(struct dlm_ls *ls, struct dlm_user_args *ua_tmp,
4134 ua->user_lksb = ua_tmp->user_lksb; 4353 ua->user_lksb = ua_tmp->user_lksb;
4135 ua->old_mode = lkb->lkb_grmode; 4354 ua->old_mode = lkb->lkb_grmode;
4136 4355
4137 error = set_lock_args(mode, &ua->lksb, flags, 0, 0, DLM_FAKE_USER_AST, 4356 error = set_lock_args(mode, &ua->lksb, flags, 0, timeout_cs,
4138 ua, DLM_FAKE_USER_AST, &args); 4357 DLM_FAKE_USER_AST, ua, DLM_FAKE_USER_AST, &args);
4139 if (error) 4358 if (error)
4140 goto out_put; 4359 goto out_put;
4141 4360
4142 error = convert_lock(ls, lkb, &args); 4361 error = convert_lock(ls, lkb, &args);
4143 4362
4144 if (error == -EINPROGRESS || error == -EAGAIN) 4363 if (error == -EINPROGRESS || error == -EAGAIN || error == -EDEADLK)
4145 error = 0; 4364 error = 0;
4146 out_put: 4365 out_put:
4147 dlm_put_lkb(lkb); 4366 dlm_put_lkb(lkb);
4148 out: 4367 out:
4149 unlock_recovery(ls); 4368 dlm_unlock_recovery(ls);
4150 kfree(ua_tmp); 4369 kfree(ua_tmp);
4151 return error; 4370 return error;
4152} 4371}
@@ -4159,7 +4378,7 @@ int dlm_user_unlock(struct dlm_ls *ls, struct dlm_user_args *ua_tmp,
4159 struct dlm_user_args *ua; 4378 struct dlm_user_args *ua;
4160 int error; 4379 int error;
4161 4380
4162 lock_recovery(ls); 4381 dlm_lock_recovery(ls);
4163 4382
4164 error = find_lkb(ls, lkid, &lkb); 4383 error = find_lkb(ls, lkid, &lkb);
4165 if (error) 4384 if (error)
@@ -4194,7 +4413,7 @@ int dlm_user_unlock(struct dlm_ls *ls, struct dlm_user_args *ua_tmp,
4194 out_put: 4413 out_put:
4195 dlm_put_lkb(lkb); 4414 dlm_put_lkb(lkb);
4196 out: 4415 out:
4197 unlock_recovery(ls); 4416 dlm_unlock_recovery(ls);
4198 kfree(ua_tmp); 4417 kfree(ua_tmp);
4199 return error; 4418 return error;
4200} 4419}
@@ -4207,7 +4426,7 @@ int dlm_user_cancel(struct dlm_ls *ls, struct dlm_user_args *ua_tmp,
4207 struct dlm_user_args *ua; 4426 struct dlm_user_args *ua;
4208 int error; 4427 int error;
4209 4428
4210 lock_recovery(ls); 4429 dlm_lock_recovery(ls);
4211 4430
4212 error = find_lkb(ls, lkid, &lkb); 4431 error = find_lkb(ls, lkid, &lkb);
4213 if (error) 4432 if (error)
@@ -4231,11 +4450,59 @@ int dlm_user_cancel(struct dlm_ls *ls, struct dlm_user_args *ua_tmp,
4231 out_put: 4450 out_put:
4232 dlm_put_lkb(lkb); 4451 dlm_put_lkb(lkb);
4233 out: 4452 out:
4234 unlock_recovery(ls); 4453 dlm_unlock_recovery(ls);
4235 kfree(ua_tmp); 4454 kfree(ua_tmp);
4236 return error; 4455 return error;
4237} 4456}
4238 4457
4458int dlm_user_deadlock(struct dlm_ls *ls, uint32_t flags, uint32_t lkid)
4459{
4460 struct dlm_lkb *lkb;
4461 struct dlm_args args;
4462 struct dlm_user_args *ua;
4463 struct dlm_rsb *r;
4464 int error;
4465
4466 dlm_lock_recovery(ls);
4467
4468 error = find_lkb(ls, lkid, &lkb);
4469 if (error)
4470 goto out;
4471
4472 ua = (struct dlm_user_args *)lkb->lkb_astparam;
4473
4474 error = set_unlock_args(flags, ua, &args);
4475 if (error)
4476 goto out_put;
4477
4478 /* same as cancel_lock(), but set DEADLOCK_CANCEL after lock_rsb */
4479
4480 r = lkb->lkb_resource;
4481 hold_rsb(r);
4482 lock_rsb(r);
4483
4484 error = validate_unlock_args(lkb, &args);
4485 if (error)
4486 goto out_r;
4487 lkb->lkb_flags |= DLM_IFL_DEADLOCK_CANCEL;
4488
4489 error = _cancel_lock(r, lkb);
4490 out_r:
4491 unlock_rsb(r);
4492 put_rsb(r);
4493
4494 if (error == -DLM_ECANCEL)
4495 error = 0;
4496 /* from validate_unlock_args() */
4497 if (error == -EBUSY)
4498 error = 0;
4499 out_put:
4500 dlm_put_lkb(lkb);
4501 out:
4502 dlm_unlock_recovery(ls);
4503 return error;
4504}
4505
4239/* lkb's that are removed from the waiters list by revert are just left on the 4506/* lkb's that are removed from the waiters list by revert are just left on the
4240 orphans list with the granted orphan locks, to be freed by purge */ 4507 orphans list with the granted orphan locks, to be freed by purge */
4241 4508
@@ -4314,12 +4581,13 @@ void dlm_clear_proc_locks(struct dlm_ls *ls, struct dlm_user_proc *proc)
4314{ 4581{
4315 struct dlm_lkb *lkb, *safe; 4582 struct dlm_lkb *lkb, *safe;
4316 4583
4317 lock_recovery(ls); 4584 dlm_lock_recovery(ls);
4318 4585
4319 while (1) { 4586 while (1) {
4320 lkb = del_proc_lock(ls, proc); 4587 lkb = del_proc_lock(ls, proc);
4321 if (!lkb) 4588 if (!lkb)
4322 break; 4589 break;
4590 del_timeout(lkb);
4323 if (lkb->lkb_exflags & DLM_LKF_PERSISTENT) 4591 if (lkb->lkb_exflags & DLM_LKF_PERSISTENT)
4324 orphan_proc_lock(ls, lkb); 4592 orphan_proc_lock(ls, lkb);
4325 else 4593 else
@@ -4347,7 +4615,7 @@ void dlm_clear_proc_locks(struct dlm_ls *ls, struct dlm_user_proc *proc)
4347 } 4615 }
4348 4616
4349 mutex_unlock(&ls->ls_clear_proc_locks); 4617 mutex_unlock(&ls->ls_clear_proc_locks);
4350 unlock_recovery(ls); 4618 dlm_unlock_recovery(ls);
4351} 4619}
4352 4620
4353static void purge_proc_locks(struct dlm_ls *ls, struct dlm_user_proc *proc) 4621static void purge_proc_locks(struct dlm_ls *ls, struct dlm_user_proc *proc)
@@ -4429,12 +4697,12 @@ int dlm_user_purge(struct dlm_ls *ls, struct dlm_user_proc *proc,
4429 if (nodeid != dlm_our_nodeid()) { 4697 if (nodeid != dlm_our_nodeid()) {
4430 error = send_purge(ls, nodeid, pid); 4698 error = send_purge(ls, nodeid, pid);
4431 } else { 4699 } else {
4432 lock_recovery(ls); 4700 dlm_lock_recovery(ls);
4433 if (pid == current->pid) 4701 if (pid == current->pid)
4434 purge_proc_locks(ls, proc); 4702 purge_proc_locks(ls, proc);
4435 else 4703 else
4436 do_purge(ls, nodeid, pid); 4704 do_purge(ls, nodeid, pid);
4437 unlock_recovery(ls); 4705 dlm_unlock_recovery(ls);
4438 } 4706 }
4439 return error; 4707 return error;
4440} 4708}
diff --git a/fs/dlm/lock.h b/fs/dlm/lock.h
index 64fc4ec40668..1720313c22df 100644
--- a/fs/dlm/lock.h
+++ b/fs/dlm/lock.h
@@ -1,7 +1,7 @@
1/****************************************************************************** 1/******************************************************************************
2******************************************************************************* 2*******************************************************************************
3** 3**
4** Copyright (C) 2005 Red Hat, Inc. All rights reserved. 4** Copyright (C) 2005-2007 Red Hat, Inc. All rights reserved.
5** 5**
6** This copyrighted material is made available to anyone wishing to use, 6** This copyrighted material is made available to anyone wishing to use,
7** modify, copy, or redistribute it subject to the terms and conditions 7** modify, copy, or redistribute it subject to the terms and conditions
@@ -24,6 +24,10 @@ void dlm_put_rsb(struct dlm_rsb *r);
24void dlm_hold_rsb(struct dlm_rsb *r); 24void dlm_hold_rsb(struct dlm_rsb *r);
25int dlm_put_lkb(struct dlm_lkb *lkb); 25int dlm_put_lkb(struct dlm_lkb *lkb);
26void dlm_scan_rsbs(struct dlm_ls *ls); 26void dlm_scan_rsbs(struct dlm_ls *ls);
27int dlm_lock_recovery_try(struct dlm_ls *ls);
28void dlm_unlock_recovery(struct dlm_ls *ls);
29void dlm_scan_timeout(struct dlm_ls *ls);
30void dlm_adjust_timeouts(struct dlm_ls *ls);
27 31
28int dlm_purge_locks(struct dlm_ls *ls); 32int dlm_purge_locks(struct dlm_ls *ls);
29void dlm_purge_mstcpy_locks(struct dlm_rsb *r); 33void dlm_purge_mstcpy_locks(struct dlm_rsb *r);
@@ -34,15 +38,18 @@ int dlm_recover_master_copy(struct dlm_ls *ls, struct dlm_rcom *rc);
34int dlm_recover_process_copy(struct dlm_ls *ls, struct dlm_rcom *rc); 38int dlm_recover_process_copy(struct dlm_ls *ls, struct dlm_rcom *rc);
35 39
36int dlm_user_request(struct dlm_ls *ls, struct dlm_user_args *ua, int mode, 40int dlm_user_request(struct dlm_ls *ls, struct dlm_user_args *ua, int mode,
37 uint32_t flags, void *name, unsigned int namelen, uint32_t parent_lkid); 41 uint32_t flags, void *name, unsigned int namelen,
42 unsigned long timeout_cs);
38int dlm_user_convert(struct dlm_ls *ls, struct dlm_user_args *ua_tmp, 43int dlm_user_convert(struct dlm_ls *ls, struct dlm_user_args *ua_tmp,
39 int mode, uint32_t flags, uint32_t lkid, char *lvb_in); 44 int mode, uint32_t flags, uint32_t lkid, char *lvb_in,
45 unsigned long timeout_cs);
40int dlm_user_unlock(struct dlm_ls *ls, struct dlm_user_args *ua_tmp, 46int dlm_user_unlock(struct dlm_ls *ls, struct dlm_user_args *ua_tmp,
41 uint32_t flags, uint32_t lkid, char *lvb_in); 47 uint32_t flags, uint32_t lkid, char *lvb_in);
42int dlm_user_cancel(struct dlm_ls *ls, struct dlm_user_args *ua_tmp, 48int dlm_user_cancel(struct dlm_ls *ls, struct dlm_user_args *ua_tmp,
43 uint32_t flags, uint32_t lkid); 49 uint32_t flags, uint32_t lkid);
44int dlm_user_purge(struct dlm_ls *ls, struct dlm_user_proc *proc, 50int dlm_user_purge(struct dlm_ls *ls, struct dlm_user_proc *proc,
45 int nodeid, int pid); 51 int nodeid, int pid);
52int dlm_user_deadlock(struct dlm_ls *ls, uint32_t flags, uint32_t lkid);
46void dlm_clear_proc_locks(struct dlm_ls *ls, struct dlm_user_proc *proc); 53void dlm_clear_proc_locks(struct dlm_ls *ls, struct dlm_user_proc *proc);
47 54
48static inline int is_master(struct dlm_rsb *r) 55static inline int is_master(struct dlm_rsb *r)
diff --git a/fs/dlm/lockspace.c b/fs/dlm/lockspace.c
index a677b2a5eed4..1dc72105ab12 100644
--- a/fs/dlm/lockspace.c
+++ b/fs/dlm/lockspace.c
@@ -197,13 +197,24 @@ static int do_uevent(struct dlm_ls *ls, int in)
197 else 197 else
198 kobject_uevent(&ls->ls_kobj, KOBJ_OFFLINE); 198 kobject_uevent(&ls->ls_kobj, KOBJ_OFFLINE);
199 199
200 log_debug(ls, "%s the lockspace group...", in ? "joining" : "leaving");
201
202 /* dlm_controld will see the uevent, do the necessary group management
203 and then write to sysfs to wake us */
204
200 error = wait_event_interruptible(ls->ls_uevent_wait, 205 error = wait_event_interruptible(ls->ls_uevent_wait,
201 test_and_clear_bit(LSFL_UEVENT_WAIT, &ls->ls_flags)); 206 test_and_clear_bit(LSFL_UEVENT_WAIT, &ls->ls_flags));
207
208 log_debug(ls, "group event done %d %d", error, ls->ls_uevent_result);
209
202 if (error) 210 if (error)
203 goto out; 211 goto out;
204 212
205 error = ls->ls_uevent_result; 213 error = ls->ls_uevent_result;
206 out: 214 out:
215 if (error)
216 log_error(ls, "group %s failed %d %d", in ? "join" : "leave",
217 error, ls->ls_uevent_result);
207 return error; 218 return error;
208} 219}
209 220
@@ -234,8 +245,13 @@ static int dlm_scand(void *data)
234 struct dlm_ls *ls; 245 struct dlm_ls *ls;
235 246
236 while (!kthread_should_stop()) { 247 while (!kthread_should_stop()) {
237 list_for_each_entry(ls, &lslist, ls_list) 248 list_for_each_entry(ls, &lslist, ls_list) {
238 dlm_scan_rsbs(ls); 249 if (dlm_lock_recovery_try(ls)) {
250 dlm_scan_rsbs(ls);
251 dlm_scan_timeout(ls);
252 dlm_unlock_recovery(ls);
253 }
254 }
239 schedule_timeout_interruptible(dlm_config.ci_scan_secs * HZ); 255 schedule_timeout_interruptible(dlm_config.ci_scan_secs * HZ);
240 } 256 }
241 return 0; 257 return 0;
@@ -395,6 +411,7 @@ static int new_lockspace(char *name, int namelen, void **lockspace,
395{ 411{
396 struct dlm_ls *ls; 412 struct dlm_ls *ls;
397 int i, size, error = -ENOMEM; 413 int i, size, error = -ENOMEM;
414 int do_unreg = 0;
398 415
399 if (namelen > DLM_LOCKSPACE_LEN) 416 if (namelen > DLM_LOCKSPACE_LEN)
400 return -EINVAL; 417 return -EINVAL;
@@ -417,11 +434,22 @@ static int new_lockspace(char *name, int namelen, void **lockspace,
417 goto out; 434 goto out;
418 memcpy(ls->ls_name, name, namelen); 435 memcpy(ls->ls_name, name, namelen);
419 ls->ls_namelen = namelen; 436 ls->ls_namelen = namelen;
420 ls->ls_exflags = flags;
421 ls->ls_lvblen = lvblen; 437 ls->ls_lvblen = lvblen;
422 ls->ls_count = 0; 438 ls->ls_count = 0;
423 ls->ls_flags = 0; 439 ls->ls_flags = 0;
424 440
441 if (flags & DLM_LSFL_TIMEWARN)
442 set_bit(LSFL_TIMEWARN, &ls->ls_flags);
443
444 if (flags & DLM_LSFL_FS)
445 ls->ls_allocation = GFP_NOFS;
446 else
447 ls->ls_allocation = GFP_KERNEL;
448
449 /* ls_exflags are forced to match among nodes, and we don't
450 need to require all nodes to have TIMEWARN or FS set */
451 ls->ls_exflags = (flags & ~(DLM_LSFL_TIMEWARN | DLM_LSFL_FS));
452
425 size = dlm_config.ci_rsbtbl_size; 453 size = dlm_config.ci_rsbtbl_size;
426 ls->ls_rsbtbl_size = size; 454 ls->ls_rsbtbl_size = size;
427 455
@@ -461,6 +489,8 @@ static int new_lockspace(char *name, int namelen, void **lockspace,
461 mutex_init(&ls->ls_waiters_mutex); 489 mutex_init(&ls->ls_waiters_mutex);
462 INIT_LIST_HEAD(&ls->ls_orphans); 490 INIT_LIST_HEAD(&ls->ls_orphans);
463 mutex_init(&ls->ls_orphans_mutex); 491 mutex_init(&ls->ls_orphans_mutex);
492 INIT_LIST_HEAD(&ls->ls_timeout);
493 mutex_init(&ls->ls_timeout_mutex);
464 494
465 INIT_LIST_HEAD(&ls->ls_nodes); 495 INIT_LIST_HEAD(&ls->ls_nodes);
466 INIT_LIST_HEAD(&ls->ls_nodes_gone); 496 INIT_LIST_HEAD(&ls->ls_nodes_gone);
@@ -477,6 +507,8 @@ static int new_lockspace(char *name, int namelen, void **lockspace,
477 507
478 init_waitqueue_head(&ls->ls_uevent_wait); 508 init_waitqueue_head(&ls->ls_uevent_wait);
479 ls->ls_uevent_result = 0; 509 ls->ls_uevent_result = 0;
510 init_completion(&ls->ls_members_done);
511 ls->ls_members_result = -1;
480 512
481 ls->ls_recoverd_task = NULL; 513 ls->ls_recoverd_task = NULL;
482 mutex_init(&ls->ls_recoverd_active); 514 mutex_init(&ls->ls_recoverd_active);
@@ -513,32 +545,49 @@ static int new_lockspace(char *name, int namelen, void **lockspace,
513 error = dlm_recoverd_start(ls); 545 error = dlm_recoverd_start(ls);
514 if (error) { 546 if (error) {
515 log_error(ls, "can't start dlm_recoverd %d", error); 547 log_error(ls, "can't start dlm_recoverd %d", error);
516 goto out_rcomfree; 548 goto out_delist;
517 } 549 }
518 550
519 dlm_create_debug_file(ls);
520
521 error = kobject_setup(ls); 551 error = kobject_setup(ls);
522 if (error) 552 if (error)
523 goto out_del; 553 goto out_stop;
524 554
525 error = kobject_register(&ls->ls_kobj); 555 error = kobject_register(&ls->ls_kobj);
526 if (error) 556 if (error)
527 goto out_del; 557 goto out_stop;
558
559 /* let kobject handle freeing of ls if there's an error */
560 do_unreg = 1;
561
562 /* This uevent triggers dlm_controld in userspace to add us to the
563 group of nodes that are members of this lockspace (managed by the
564 cluster infrastructure.) Once it's done that, it tells us who the
565 current lockspace members are (via configfs) and then tells the
566 lockspace to start running (via sysfs) in dlm_ls_start(). */
528 567
529 error = do_uevent(ls, 1); 568 error = do_uevent(ls, 1);
530 if (error) 569 if (error)
531 goto out_unreg; 570 goto out_stop;
571
572 wait_for_completion(&ls->ls_members_done);
573 error = ls->ls_members_result;
574 if (error)
575 goto out_members;
576
577 dlm_create_debug_file(ls);
578
579 log_debug(ls, "join complete");
532 580
533 *lockspace = ls; 581 *lockspace = ls;
534 return 0; 582 return 0;
535 583
536 out_unreg: 584 out_members:
537 kobject_unregister(&ls->ls_kobj); 585 do_uevent(ls, 0);
538 out_del: 586 dlm_clear_members(ls);
539 dlm_delete_debug_file(ls); 587 kfree(ls->ls_node_array);
588 out_stop:
540 dlm_recoverd_stop(ls); 589 dlm_recoverd_stop(ls);
541 out_rcomfree: 590 out_delist:
542 spin_lock(&lslist_lock); 591 spin_lock(&lslist_lock);
543 list_del(&ls->ls_list); 592 list_del(&ls->ls_list);
544 spin_unlock(&lslist_lock); 593 spin_unlock(&lslist_lock);
@@ -550,7 +599,10 @@ static int new_lockspace(char *name, int namelen, void **lockspace,
550 out_rsbfree: 599 out_rsbfree:
551 kfree(ls->ls_rsbtbl); 600 kfree(ls->ls_rsbtbl);
552 out_lsfree: 601 out_lsfree:
553 kfree(ls); 602 if (do_unreg)
603 kobject_unregister(&ls->ls_kobj);
604 else
605 kfree(ls);
554 out: 606 out:
555 module_put(THIS_MODULE); 607 module_put(THIS_MODULE);
556 return error; 608 return error;
@@ -570,6 +622,8 @@ int dlm_new_lockspace(char *name, int namelen, void **lockspace,
570 error = new_lockspace(name, namelen, lockspace, flags, lvblen); 622 error = new_lockspace(name, namelen, lockspace, flags, lvblen);
571 if (!error) 623 if (!error)
572 ls_count++; 624 ls_count++;
625 else if (!ls_count)
626 threads_stop();
573 out: 627 out:
574 mutex_unlock(&ls_lock); 628 mutex_unlock(&ls_lock);
575 return error; 629 return error;
@@ -696,7 +750,7 @@ static int release_lockspace(struct dlm_ls *ls, int force)
696 dlm_clear_members_gone(ls); 750 dlm_clear_members_gone(ls);
697 kfree(ls->ls_node_array); 751 kfree(ls->ls_node_array);
698 kobject_unregister(&ls->ls_kobj); 752 kobject_unregister(&ls->ls_kobj);
699 /* The ls structure will be freed when the kobject is done with */ 753 /* The ls structure will be freed when the kobject is done with */
700 754
701 mutex_lock(&ls_lock); 755 mutex_lock(&ls_lock);
702 ls_count--; 756 ls_count--;
diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c
index 27970a58d29b..0553a6158dcb 100644
--- a/fs/dlm/lowcomms.c
+++ b/fs/dlm/lowcomms.c
@@ -260,7 +260,7 @@ static int nodeid_to_addr(int nodeid, struct sockaddr *retaddr)
260static void lowcomms_data_ready(struct sock *sk, int count_unused) 260static void lowcomms_data_ready(struct sock *sk, int count_unused)
261{ 261{
262 struct connection *con = sock2con(sk); 262 struct connection *con = sock2con(sk);
263 if (!test_and_set_bit(CF_READ_PENDING, &con->flags)) 263 if (con && !test_and_set_bit(CF_READ_PENDING, &con->flags))
264 queue_work(recv_workqueue, &con->rwork); 264 queue_work(recv_workqueue, &con->rwork);
265} 265}
266 266
@@ -268,7 +268,7 @@ static void lowcomms_write_space(struct sock *sk)
268{ 268{
269 struct connection *con = sock2con(sk); 269 struct connection *con = sock2con(sk);
270 270
271 if (!test_and_set_bit(CF_WRITE_PENDING, &con->flags)) 271 if (con && !test_and_set_bit(CF_WRITE_PENDING, &con->flags))
272 queue_work(send_workqueue, &con->swork); 272 queue_work(send_workqueue, &con->swork);
273} 273}
274 274
@@ -720,11 +720,17 @@ static int tcp_accept_from_sock(struct connection *con)
720 INIT_WORK(&othercon->rwork, process_recv_sockets); 720 INIT_WORK(&othercon->rwork, process_recv_sockets);
721 set_bit(CF_IS_OTHERCON, &othercon->flags); 721 set_bit(CF_IS_OTHERCON, &othercon->flags);
722 newcon->othercon = othercon; 722 newcon->othercon = othercon;
723 othercon->sock = newsock;
724 newsock->sk->sk_user_data = othercon;
725 add_sock(newsock, othercon);
726 addcon = othercon;
727 }
728 else {
729 printk("Extra connection from node %d attempted\n", nodeid);
730 result = -EAGAIN;
731 mutex_unlock(&newcon->sock_mutex);
732 goto accept_err;
723 } 733 }
724 othercon->sock = newsock;
725 newsock->sk->sk_user_data = othercon;
726 add_sock(newsock, othercon);
727 addcon = othercon;
728 } 734 }
729 else { 735 else {
730 newsock->sk->sk_user_data = newcon; 736 newsock->sk->sk_user_data = newcon;
@@ -1400,8 +1406,11 @@ void dlm_lowcomms_stop(void)
1400 down(&connections_lock); 1406 down(&connections_lock);
1401 for (i = 0; i <= max_nodeid; i++) { 1407 for (i = 0; i <= max_nodeid; i++) {
1402 con = __nodeid2con(i, 0); 1408 con = __nodeid2con(i, 0);
1403 if (con) 1409 if (con) {
1404 con->flags |= 0xFF; 1410 con->flags |= 0xFF;
1411 if (con->sock)
1412 con->sock->sk->sk_user_data = NULL;
1413 }
1405 } 1414 }
1406 up(&connections_lock); 1415 up(&connections_lock);
1407 1416
diff --git a/fs/dlm/main.c b/fs/dlm/main.c
index 162fbae58fe5..eca2907f2386 100644
--- a/fs/dlm/main.c
+++ b/fs/dlm/main.c
@@ -2,7 +2,7 @@
2******************************************************************************* 2*******************************************************************************
3** 3**
4** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. 4** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
5** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. 5** Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
6** 6**
7** This copyrighted material is made available to anyone wishing to use, 7** This copyrighted material is made available to anyone wishing to use,
8** modify, copy, or redistribute it subject to the terms and conditions 8** modify, copy, or redistribute it subject to the terms and conditions
@@ -25,6 +25,8 @@ void dlm_unregister_debugfs(void);
25static inline int dlm_register_debugfs(void) { return 0; } 25static inline int dlm_register_debugfs(void) { return 0; }
26static inline void dlm_unregister_debugfs(void) { } 26static inline void dlm_unregister_debugfs(void) { }
27#endif 27#endif
28int dlm_netlink_init(void);
29void dlm_netlink_exit(void);
28 30
29static int __init init_dlm(void) 31static int __init init_dlm(void)
30{ 32{
@@ -50,10 +52,16 @@ static int __init init_dlm(void)
50 if (error) 52 if (error)
51 goto out_debug; 53 goto out_debug;
52 54
55 error = dlm_netlink_init();
56 if (error)
57 goto out_user;
58
53 printk("DLM (built %s %s) installed\n", __DATE__, __TIME__); 59 printk("DLM (built %s %s) installed\n", __DATE__, __TIME__);
54 60
55 return 0; 61 return 0;
56 62
63 out_user:
64 dlm_user_exit();
57 out_debug: 65 out_debug:
58 dlm_unregister_debugfs(); 66 dlm_unregister_debugfs();
59 out_config: 67 out_config:
@@ -68,6 +76,7 @@ static int __init init_dlm(void)
68 76
69static void __exit exit_dlm(void) 77static void __exit exit_dlm(void)
70{ 78{
79 dlm_netlink_exit();
71 dlm_user_exit(); 80 dlm_user_exit();
72 dlm_config_exit(); 81 dlm_config_exit();
73 dlm_memory_exit(); 82 dlm_memory_exit();
diff --git a/fs/dlm/member.c b/fs/dlm/member.c
index 85e2897bd740..073599dced2a 100644
--- a/fs/dlm/member.c
+++ b/fs/dlm/member.c
@@ -1,7 +1,7 @@
1/****************************************************************************** 1/******************************************************************************
2******************************************************************************* 2*******************************************************************************
3** 3**
4** Copyright (C) 2005 Red Hat, Inc. All rights reserved. 4** Copyright (C) 2005-2007 Red Hat, Inc. All rights reserved.
5** 5**
6** This copyrighted material is made available to anyone wishing to use, 6** This copyrighted material is made available to anyone wishing to use,
7** modify, copy, or redistribute it subject to the terms and conditions 7** modify, copy, or redistribute it subject to the terms and conditions
@@ -233,6 +233,12 @@ int dlm_recover_members(struct dlm_ls *ls, struct dlm_recover *rv, int *neg_out)
233 *neg_out = neg; 233 *neg_out = neg;
234 234
235 error = ping_members(ls); 235 error = ping_members(ls);
236 if (!error || error == -EPROTO) {
237 /* new_lockspace() may be waiting to know if the config
238 is good or bad */
239 ls->ls_members_result = error;
240 complete(&ls->ls_members_done);
241 }
236 if (error) 242 if (error)
237 goto out; 243 goto out;
238 244
@@ -284,6 +290,9 @@ int dlm_ls_stop(struct dlm_ls *ls)
284 dlm_recoverd_suspend(ls); 290 dlm_recoverd_suspend(ls);
285 ls->ls_recover_status = 0; 291 ls->ls_recover_status = 0;
286 dlm_recoverd_resume(ls); 292 dlm_recoverd_resume(ls);
293
294 if (!ls->ls_recover_begin)
295 ls->ls_recover_begin = jiffies;
287 return 0; 296 return 0;
288} 297}
289 298
diff --git a/fs/dlm/netlink.c b/fs/dlm/netlink.c
new file mode 100644
index 000000000000..863b87d0dc71
--- /dev/null
+++ b/fs/dlm/netlink.c
@@ -0,0 +1,153 @@
1/*
2 * Copyright (C) 2007 Red Hat, Inc. All rights reserved.
3 *
4 * This copyrighted material is made available to anyone wishing to use,
5 * modify, copy, or redistribute it subject to the terms and conditions
6 * of the GNU General Public License v.2.
7 */
8
9#include <net/genetlink.h>
10#include <linux/dlm.h>
11#include <linux/dlm_netlink.h>
12
13#include "dlm_internal.h"
14
15static uint32_t dlm_nl_seqnum;
16static uint32_t listener_nlpid;
17
18static struct genl_family family = {
19 .id = GENL_ID_GENERATE,
20 .name = DLM_GENL_NAME,
21 .version = DLM_GENL_VERSION,
22};
23
24static int prepare_data(u8 cmd, struct sk_buff **skbp, size_t size)
25{
26 struct sk_buff *skb;
27 void *data;
28
29 skb = genlmsg_new(size, GFP_KERNEL);
30 if (!skb)
31 return -ENOMEM;
32
33 /* add the message headers */
34 data = genlmsg_put(skb, 0, dlm_nl_seqnum++, &family, 0, cmd);
35 if (!data) {
36 nlmsg_free(skb);
37 return -EINVAL;
38 }
39
40 *skbp = skb;
41 return 0;
42}
43
44static struct dlm_lock_data *mk_data(struct sk_buff *skb)
45{
46 struct nlattr *ret;
47
48 ret = nla_reserve(skb, DLM_TYPE_LOCK, sizeof(struct dlm_lock_data));
49 if (!ret)
50 return NULL;
51 return nla_data(ret);
52}
53
54static int send_data(struct sk_buff *skb)
55{
56 struct genlmsghdr *genlhdr = nlmsg_data((struct nlmsghdr *)skb->data);
57 void *data = genlmsg_data(genlhdr);
58 int rv;
59
60 rv = genlmsg_end(skb, data);
61 if (rv < 0) {
62 nlmsg_free(skb);
63 return rv;
64 }
65
66 return genlmsg_unicast(skb, listener_nlpid);
67}
68
69static int user_cmd(struct sk_buff *skb, struct genl_info *info)
70{
71 listener_nlpid = info->snd_pid;
72 printk("user_cmd nlpid %u\n", listener_nlpid);
73 return 0;
74}
75
76static struct genl_ops dlm_nl_ops = {
77 .cmd = DLM_CMD_HELLO,
78 .doit = user_cmd,
79};
80
81int dlm_netlink_init(void)
82{
83 int rv;
84
85 rv = genl_register_family(&family);
86 if (rv)
87 return rv;
88
89 rv = genl_register_ops(&family, &dlm_nl_ops);
90 if (rv < 0)
91 goto err;
92 return 0;
93 err:
94 genl_unregister_family(&family);
95 return rv;
96}
97
98void dlm_netlink_exit(void)
99{
100 genl_unregister_ops(&family, &dlm_nl_ops);
101 genl_unregister_family(&family);
102}
103
104static void fill_data(struct dlm_lock_data *data, struct dlm_lkb *lkb)
105{
106 struct dlm_rsb *r = lkb->lkb_resource;
107 struct dlm_user_args *ua = (struct dlm_user_args *) lkb->lkb_astparam;
108
109 memset(data, 0, sizeof(struct dlm_lock_data));
110
111 data->version = DLM_LOCK_DATA_VERSION;
112 data->nodeid = lkb->lkb_nodeid;
113 data->ownpid = lkb->lkb_ownpid;
114 data->id = lkb->lkb_id;
115 data->remid = lkb->lkb_remid;
116 data->status = lkb->lkb_status;
117 data->grmode = lkb->lkb_grmode;
118 data->rqmode = lkb->lkb_rqmode;
119 data->timestamp = lkb->lkb_timestamp;
120 if (ua)
121 data->xid = ua->xid;
122 if (r) {
123 data->lockspace_id = r->res_ls->ls_global_id;
124 data->resource_namelen = r->res_length;
125 memcpy(data->resource_name, r->res_name, r->res_length);
126 }
127}
128
129void dlm_timeout_warn(struct dlm_lkb *lkb)
130{
131 struct dlm_lock_data *data;
132 struct sk_buff *send_skb;
133 size_t size;
134 int rv;
135
136 size = nla_total_size(sizeof(struct dlm_lock_data)) +
137 nla_total_size(0); /* why this? */
138
139 rv = prepare_data(DLM_CMD_TIMEOUT, &send_skb, size);
140 if (rv < 0)
141 return;
142
143 data = mk_data(send_skb);
144 if (!data) {
145 nlmsg_free(send_skb);
146 return;
147 }
148
149 fill_data(data, lkb);
150
151 send_data(send_skb);
152}
153
diff --git a/fs/dlm/rcom.c b/fs/dlm/rcom.c
index 6bfbd6153809..e3a1527cbdbe 100644
--- a/fs/dlm/rcom.c
+++ b/fs/dlm/rcom.c
@@ -38,7 +38,7 @@ static int create_rcom(struct dlm_ls *ls, int to_nodeid, int type, int len,
38 char *mb; 38 char *mb;
39 int mb_len = sizeof(struct dlm_rcom) + len; 39 int mb_len = sizeof(struct dlm_rcom) + len;
40 40
41 mh = dlm_lowcomms_get_buffer(to_nodeid, mb_len, GFP_KERNEL, &mb); 41 mh = dlm_lowcomms_get_buffer(to_nodeid, mb_len, ls->ls_allocation, &mb);
42 if (!mh) { 42 if (!mh) {
43 log_print("create_rcom to %d type %d len %d ENOBUFS", 43 log_print("create_rcom to %d type %d len %d ENOBUFS",
44 to_nodeid, type, len); 44 to_nodeid, type, len);
@@ -90,7 +90,7 @@ static int check_config(struct dlm_ls *ls, struct dlm_rcom *rc, int nodeid)
90 log_error(ls, "version mismatch: %x nodeid %d: %x", 90 log_error(ls, "version mismatch: %x nodeid %d: %x",
91 DLM_HEADER_MAJOR | DLM_HEADER_MINOR, nodeid, 91 DLM_HEADER_MAJOR | DLM_HEADER_MINOR, nodeid,
92 rc->rc_header.h_version); 92 rc->rc_header.h_version);
93 return -EINVAL; 93 return -EPROTO;
94 } 94 }
95 95
96 if (rf->rf_lvblen != ls->ls_lvblen || 96 if (rf->rf_lvblen != ls->ls_lvblen ||
@@ -98,7 +98,7 @@ static int check_config(struct dlm_ls *ls, struct dlm_rcom *rc, int nodeid)
98 log_error(ls, "config mismatch: %d,%x nodeid %d: %d,%x", 98 log_error(ls, "config mismatch: %d,%x nodeid %d: %d,%x",
99 ls->ls_lvblen, ls->ls_exflags, 99 ls->ls_lvblen, ls->ls_exflags,
100 nodeid, rf->rf_lvblen, rf->rf_lsflags); 100 nodeid, rf->rf_lvblen, rf->rf_lsflags);
101 return -EINVAL; 101 return -EPROTO;
102 } 102 }
103 return 0; 103 return 0;
104} 104}
@@ -386,7 +386,8 @@ static void receive_rcom_lock_reply(struct dlm_ls *ls, struct dlm_rcom *rc_in)
386 dlm_recover_process_copy(ls, rc_in); 386 dlm_recover_process_copy(ls, rc_in);
387} 387}
388 388
389static int send_ls_not_ready(int nodeid, struct dlm_rcom *rc_in) 389static int send_ls_not_ready(struct dlm_ls *ls, int nodeid,
390 struct dlm_rcom *rc_in)
390{ 391{
391 struct dlm_rcom *rc; 392 struct dlm_rcom *rc;
392 struct rcom_config *rf; 393 struct rcom_config *rf;
@@ -394,7 +395,7 @@ static int send_ls_not_ready(int nodeid, struct dlm_rcom *rc_in)
394 char *mb; 395 char *mb;
395 int mb_len = sizeof(struct dlm_rcom) + sizeof(struct rcom_config); 396 int mb_len = sizeof(struct dlm_rcom) + sizeof(struct rcom_config);
396 397
397 mh = dlm_lowcomms_get_buffer(nodeid, mb_len, GFP_KERNEL, &mb); 398 mh = dlm_lowcomms_get_buffer(nodeid, mb_len, ls->ls_allocation, &mb);
398 if (!mh) 399 if (!mh)
399 return -ENOBUFS; 400 return -ENOBUFS;
400 memset(mb, 0, mb_len); 401 memset(mb, 0, mb_len);
@@ -464,7 +465,7 @@ void dlm_receive_rcom(struct dlm_header *hd, int nodeid)
464 log_print("lockspace %x from %d type %x not found", 465 log_print("lockspace %x from %d type %x not found",
465 hd->h_lockspace, nodeid, rc->rc_type); 466 hd->h_lockspace, nodeid, rc->rc_type);
466 if (rc->rc_type == DLM_RCOM_STATUS) 467 if (rc->rc_type == DLM_RCOM_STATUS)
467 send_ls_not_ready(nodeid, rc); 468 send_ls_not_ready(ls, nodeid, rc);
468 return; 469 return;
469 } 470 }
470 471
diff --git a/fs/dlm/recoverd.c b/fs/dlm/recoverd.c
index 3cb636d60249..66575997861c 100644
--- a/fs/dlm/recoverd.c
+++ b/fs/dlm/recoverd.c
@@ -2,7 +2,7 @@
2******************************************************************************* 2*******************************************************************************
3** 3**
4** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. 4** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
5** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. 5** Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
6** 6**
7** This copyrighted material is made available to anyone wishing to use, 7** This copyrighted material is made available to anyone wishing to use,
8** modify, copy, or redistribute it subject to the terms and conditions 8** modify, copy, or redistribute it subject to the terms and conditions
@@ -190,6 +190,8 @@ static int ls_recover(struct dlm_ls *ls, struct dlm_recover *rv)
190 190
191 dlm_clear_members_gone(ls); 191 dlm_clear_members_gone(ls);
192 192
193 dlm_adjust_timeouts(ls);
194
193 error = enable_locking(ls, rv->seq); 195 error = enable_locking(ls, rv->seq);
194 if (error) { 196 if (error) {
195 log_debug(ls, "enable_locking failed %d", error); 197 log_debug(ls, "enable_locking failed %d", error);
diff --git a/fs/dlm/user.c b/fs/dlm/user.c
index b0201ec325a7..6438941ab1f8 100644
--- a/fs/dlm/user.c
+++ b/fs/dlm/user.c
@@ -33,16 +33,17 @@ static const struct file_operations device_fops;
33struct dlm_lock_params32 { 33struct dlm_lock_params32 {
34 __u8 mode; 34 __u8 mode;
35 __u8 namelen; 35 __u8 namelen;
36 __u16 flags; 36 __u16 unused;
37 __u32 flags;
37 __u32 lkid; 38 __u32 lkid;
38 __u32 parent; 39 __u32 parent;
39 40 __u64 xid;
41 __u64 timeout;
40 __u32 castparam; 42 __u32 castparam;
41 __u32 castaddr; 43 __u32 castaddr;
42 __u32 bastparam; 44 __u32 bastparam;
43 __u32 bastaddr; 45 __u32 bastaddr;
44 __u32 lksb; 46 __u32 lksb;
45
46 char lvb[DLM_USER_LVB_LEN]; 47 char lvb[DLM_USER_LVB_LEN];
47 char name[0]; 48 char name[0];
48}; 49};
@@ -68,6 +69,7 @@ struct dlm_lksb32 {
68}; 69};
69 70
70struct dlm_lock_result32 { 71struct dlm_lock_result32 {
72 __u32 version[3];
71 __u32 length; 73 __u32 length;
72 __u32 user_astaddr; 74 __u32 user_astaddr;
73 __u32 user_astparam; 75 __u32 user_astparam;
@@ -102,6 +104,8 @@ static void compat_input(struct dlm_write_request *kb,
102 kb->i.lock.flags = kb32->i.lock.flags; 104 kb->i.lock.flags = kb32->i.lock.flags;
103 kb->i.lock.lkid = kb32->i.lock.lkid; 105 kb->i.lock.lkid = kb32->i.lock.lkid;
104 kb->i.lock.parent = kb32->i.lock.parent; 106 kb->i.lock.parent = kb32->i.lock.parent;
107 kb->i.lock.xid = kb32->i.lock.xid;
108 kb->i.lock.timeout = kb32->i.lock.timeout;
105 kb->i.lock.castparam = (void *)(long)kb32->i.lock.castparam; 109 kb->i.lock.castparam = (void *)(long)kb32->i.lock.castparam;
106 kb->i.lock.castaddr = (void *)(long)kb32->i.lock.castaddr; 110 kb->i.lock.castaddr = (void *)(long)kb32->i.lock.castaddr;
107 kb->i.lock.bastparam = (void *)(long)kb32->i.lock.bastparam; 111 kb->i.lock.bastparam = (void *)(long)kb32->i.lock.bastparam;
@@ -115,6 +119,10 @@ static void compat_input(struct dlm_write_request *kb,
115static void compat_output(struct dlm_lock_result *res, 119static void compat_output(struct dlm_lock_result *res,
116 struct dlm_lock_result32 *res32) 120 struct dlm_lock_result32 *res32)
117{ 121{
122 res32->version[0] = res->version[0];
123 res32->version[1] = res->version[1];
124 res32->version[2] = res->version[2];
125
118 res32->user_astaddr = (__u32)(long)res->user_astaddr; 126 res32->user_astaddr = (__u32)(long)res->user_astaddr;
119 res32->user_astparam = (__u32)(long)res->user_astparam; 127 res32->user_astparam = (__u32)(long)res->user_astparam;
120 res32->user_lksb = (__u32)(long)res->user_lksb; 128 res32->user_lksb = (__u32)(long)res->user_lksb;
@@ -130,6 +138,36 @@ static void compat_output(struct dlm_lock_result *res,
130} 138}
131#endif 139#endif
132 140
141/* Figure out if this lock is at the end of its life and no longer
142 available for the application to use. The lkb still exists until
143 the final ast is read. A lock becomes EOL in three situations:
144 1. a noqueue request fails with EAGAIN
145 2. an unlock completes with EUNLOCK
146 3. a cancel of a waiting request completes with ECANCEL/EDEADLK
147 An EOL lock needs to be removed from the process's list of locks.
148 And we can't allow any new operation on an EOL lock. This is
149 not related to the lifetime of the lkb struct which is managed
150 entirely by refcount. */
151
152static int lkb_is_endoflife(struct dlm_lkb *lkb, int sb_status, int type)
153{
154 switch (sb_status) {
155 case -DLM_EUNLOCK:
156 return 1;
157 case -DLM_ECANCEL:
158 case -ETIMEDOUT:
159 case -EDEADLK:
160 if (lkb->lkb_grmode == DLM_LOCK_IV)
161 return 1;
162 break;
163 case -EAGAIN:
164 if (type == AST_COMP && lkb->lkb_grmode == DLM_LOCK_IV)
165 return 1;
166 break;
167 }
168 return 0;
169}
170
133/* we could possibly check if the cancel of an orphan has resulted in the lkb 171/* we could possibly check if the cancel of an orphan has resulted in the lkb
134 being removed and then remove that lkb from the orphans list and free it */ 172 being removed and then remove that lkb from the orphans list and free it */
135 173
@@ -176,25 +214,7 @@ void dlm_user_add_ast(struct dlm_lkb *lkb, int type)
176 log_debug(ls, "ast overlap %x status %x %x", 214 log_debug(ls, "ast overlap %x status %x %x",
177 lkb->lkb_id, ua->lksb.sb_status, lkb->lkb_flags); 215 lkb->lkb_id, ua->lksb.sb_status, lkb->lkb_flags);
178 216
179 /* Figure out if this lock is at the end of its life and no longer 217 eol = lkb_is_endoflife(lkb, ua->lksb.sb_status, type);
180 available for the application to use. The lkb still exists until
181 the final ast is read. A lock becomes EOL in three situations:
182 1. a noqueue request fails with EAGAIN
183 2. an unlock completes with EUNLOCK
184 3. a cancel of a waiting request completes with ECANCEL
185 An EOL lock needs to be removed from the process's list of locks.
186 And we can't allow any new operation on an EOL lock. This is
187 not related to the lifetime of the lkb struct which is managed
188 entirely by refcount. */
189
190 if (type == AST_COMP &&
191 lkb->lkb_grmode == DLM_LOCK_IV &&
192 ua->lksb.sb_status == -EAGAIN)
193 eol = 1;
194 else if (ua->lksb.sb_status == -DLM_EUNLOCK ||
195 (ua->lksb.sb_status == -DLM_ECANCEL &&
196 lkb->lkb_grmode == DLM_LOCK_IV))
197 eol = 1;
198 if (eol) { 218 if (eol) {
199 lkb->lkb_ast_type &= ~AST_BAST; 219 lkb->lkb_ast_type &= ~AST_BAST;
200 lkb->lkb_flags |= DLM_IFL_ENDOFLIFE; 220 lkb->lkb_flags |= DLM_IFL_ENDOFLIFE;
@@ -252,16 +272,18 @@ static int device_user_lock(struct dlm_user_proc *proc,
252 ua->castaddr = params->castaddr; 272 ua->castaddr = params->castaddr;
253 ua->bastparam = params->bastparam; 273 ua->bastparam = params->bastparam;
254 ua->bastaddr = params->bastaddr; 274 ua->bastaddr = params->bastaddr;
275 ua->xid = params->xid;
255 276
256 if (params->flags & DLM_LKF_CONVERT) 277 if (params->flags & DLM_LKF_CONVERT)
257 error = dlm_user_convert(ls, ua, 278 error = dlm_user_convert(ls, ua,
258 params->mode, params->flags, 279 params->mode, params->flags,
259 params->lkid, params->lvb); 280 params->lkid, params->lvb,
281 (unsigned long) params->timeout);
260 else { 282 else {
261 error = dlm_user_request(ls, ua, 283 error = dlm_user_request(ls, ua,
262 params->mode, params->flags, 284 params->mode, params->flags,
263 params->name, params->namelen, 285 params->name, params->namelen,
264 params->parent); 286 (unsigned long) params->timeout);
265 if (!error) 287 if (!error)
266 error = ua->lksb.sb_lkid; 288 error = ua->lksb.sb_lkid;
267 } 289 }
@@ -299,6 +321,22 @@ static int device_user_unlock(struct dlm_user_proc *proc,
299 return error; 321 return error;
300} 322}
301 323
324static int device_user_deadlock(struct dlm_user_proc *proc,
325 struct dlm_lock_params *params)
326{
327 struct dlm_ls *ls;
328 int error;
329
330 ls = dlm_find_lockspace_local(proc->lockspace);
331 if (!ls)
332 return -ENOENT;
333
334 error = dlm_user_deadlock(ls, params->flags, params->lkid);
335
336 dlm_put_lockspace(ls);
337 return error;
338}
339
302static int create_misc_device(struct dlm_ls *ls, char *name) 340static int create_misc_device(struct dlm_ls *ls, char *name)
303{ 341{
304 int error, len; 342 int error, len;
@@ -348,7 +386,7 @@ static int device_create_lockspace(struct dlm_lspace_params *params)
348 return -EPERM; 386 return -EPERM;
349 387
350 error = dlm_new_lockspace(params->name, strlen(params->name), 388 error = dlm_new_lockspace(params->name, strlen(params->name),
351 &lockspace, 0, DLM_USER_LVB_LEN); 389 &lockspace, params->flags, DLM_USER_LVB_LEN);
352 if (error) 390 if (error)
353 return error; 391 return error;
354 392
@@ -524,6 +562,14 @@ static ssize_t device_write(struct file *file, const char __user *buf,
524 error = device_user_unlock(proc, &kbuf->i.lock); 562 error = device_user_unlock(proc, &kbuf->i.lock);
525 break; 563 break;
526 564
565 case DLM_USER_DEADLOCK:
566 if (!proc) {
567 log_print("no locking on control device");
568 goto out_sig;
569 }
570 error = device_user_deadlock(proc, &kbuf->i.lock);
571 break;
572
527 case DLM_USER_CREATE_LOCKSPACE: 573 case DLM_USER_CREATE_LOCKSPACE:
528 if (proc) { 574 if (proc) {
529 log_print("create/remove only on control device"); 575 log_print("create/remove only on control device");
@@ -641,6 +687,9 @@ static int copy_result_to_user(struct dlm_user_args *ua, int compat, int type,
641 int struct_len; 687 int struct_len;
642 688
643 memset(&result, 0, sizeof(struct dlm_lock_result)); 689 memset(&result, 0, sizeof(struct dlm_lock_result));
690 result.version[0] = DLM_DEVICE_VERSION_MAJOR;
691 result.version[1] = DLM_DEVICE_VERSION_MINOR;
692 result.version[2] = DLM_DEVICE_VERSION_PATCH;
644 memcpy(&result.lksb, &ua->lksb, sizeof(struct dlm_lksb)); 693 memcpy(&result.lksb, &ua->lksb, sizeof(struct dlm_lksb));
645 result.user_lksb = ua->user_lksb; 694 result.user_lksb = ua->user_lksb;
646 695
@@ -699,6 +748,20 @@ static int copy_result_to_user(struct dlm_user_args *ua, int compat, int type,
699 return error; 748 return error;
700} 749}
701 750
751static int copy_version_to_user(char __user *buf, size_t count)
752{
753 struct dlm_device_version ver;
754
755 memset(&ver, 0, sizeof(struct dlm_device_version));
756 ver.version[0] = DLM_DEVICE_VERSION_MAJOR;
757 ver.version[1] = DLM_DEVICE_VERSION_MINOR;
758 ver.version[2] = DLM_DEVICE_VERSION_PATCH;
759
760 if (copy_to_user(buf, &ver, sizeof(struct dlm_device_version)))
761 return -EFAULT;
762 return sizeof(struct dlm_device_version);
763}
764
702/* a read returns a single ast described in a struct dlm_lock_result */ 765/* a read returns a single ast described in a struct dlm_lock_result */
703 766
704static ssize_t device_read(struct file *file, char __user *buf, size_t count, 767static ssize_t device_read(struct file *file, char __user *buf, size_t count,
@@ -710,6 +773,16 @@ static ssize_t device_read(struct file *file, char __user *buf, size_t count,
710 DECLARE_WAITQUEUE(wait, current); 773 DECLARE_WAITQUEUE(wait, current);
711 int error, type=0, bmode=0, removed = 0; 774 int error, type=0, bmode=0, removed = 0;
712 775
776 if (count == sizeof(struct dlm_device_version)) {
777 error = copy_version_to_user(buf, count);
778 return error;
779 }
780
781 if (!proc) {
782 log_print("non-version read from control device %zu", count);
783 return -EINVAL;
784 }
785
713#ifdef CONFIG_COMPAT 786#ifdef CONFIG_COMPAT
714 if (count < sizeof(struct dlm_lock_result32)) 787 if (count < sizeof(struct dlm_lock_result32))
715#else 788#else
@@ -747,11 +820,6 @@ static ssize_t device_read(struct file *file, char __user *buf, size_t count,
747 } 820 }
748 } 821 }
749 822
750 if (list_empty(&proc->asts)) {
751 spin_unlock(&proc->asts_spin);
752 return -EAGAIN;
753 }
754
755 /* there may be both completion and blocking asts to return for 823 /* there may be both completion and blocking asts to return for
756 the lkb, don't remove lkb from asts list unless no asts remain */ 824 the lkb, don't remove lkb from asts list unless no asts remain */
757 825
@@ -823,6 +891,7 @@ static const struct file_operations device_fops = {
823static const struct file_operations ctl_device_fops = { 891static const struct file_operations ctl_device_fops = {
824 .open = ctl_device_open, 892 .open = ctl_device_open,
825 .release = ctl_device_close, 893 .release = ctl_device_close,
894 .read = device_read,
826 .write = device_write, 895 .write = device_write,
827 .owner = THIS_MODULE, 896 .owner = THIS_MODULE,
828}; 897};
diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c
index 59288d817078..94f456fe4d9b 100644
--- a/fs/ecryptfs/file.c
+++ b/fs/ecryptfs/file.c
@@ -338,16 +338,17 @@ static int ecryptfs_fasync(int fd, struct file *file, int flag)
338 return rc; 338 return rc;
339} 339}
340 340
341static ssize_t ecryptfs_sendfile(struct file *file, loff_t * ppos, 341static ssize_t ecryptfs_splice_read(struct file *file, loff_t * ppos,
342 size_t count, read_actor_t actor, void *target) 342 struct pipe_inode_info *pipe, size_t count,
343 unsigned int flags)
343{ 344{
344 struct file *lower_file = NULL; 345 struct file *lower_file = NULL;
345 int rc = -EINVAL; 346 int rc = -EINVAL;
346 347
347 lower_file = ecryptfs_file_to_lower(file); 348 lower_file = ecryptfs_file_to_lower(file);
348 if (lower_file->f_op && lower_file->f_op->sendfile) 349 if (lower_file->f_op && lower_file->f_op->splice_read)
349 rc = lower_file->f_op->sendfile(lower_file, ppos, count, 350 rc = lower_file->f_op->splice_read(lower_file, ppos, pipe,
350 actor, target); 351 count, flags);
351 352
352 return rc; 353 return rc;
353} 354}
@@ -364,7 +365,7 @@ const struct file_operations ecryptfs_dir_fops = {
364 .release = ecryptfs_release, 365 .release = ecryptfs_release,
365 .fsync = ecryptfs_fsync, 366 .fsync = ecryptfs_fsync,
366 .fasync = ecryptfs_fasync, 367 .fasync = ecryptfs_fasync,
367 .sendfile = ecryptfs_sendfile, 368 .splice_read = ecryptfs_splice_read,
368}; 369};
369 370
370const struct file_operations ecryptfs_main_fops = { 371const struct file_operations ecryptfs_main_fops = {
@@ -381,7 +382,7 @@ const struct file_operations ecryptfs_main_fops = {
381 .release = ecryptfs_release, 382 .release = ecryptfs_release,
382 .fsync = ecryptfs_fsync, 383 .fsync = ecryptfs_fsync,
383 .fasync = ecryptfs_fasync, 384 .fasync = ecryptfs_fasync,
384 .sendfile = ecryptfs_sendfile, 385 .splice_read = ecryptfs_splice_read,
385}; 386};
386 387
387static int 388static int
diff --git a/fs/ext2/file.c b/fs/ext2/file.c
index 566d4e2d3852..04afeecaaef3 100644
--- a/fs/ext2/file.c
+++ b/fs/ext2/file.c
@@ -53,7 +53,6 @@ const struct file_operations ext2_file_operations = {
53 .open = generic_file_open, 53 .open = generic_file_open,
54 .release = ext2_release_file, 54 .release = ext2_release_file,
55 .fsync = ext2_sync_file, 55 .fsync = ext2_sync_file,
56 .sendfile = generic_file_sendfile,
57 .splice_read = generic_file_splice_read, 56 .splice_read = generic_file_splice_read,
58 .splice_write = generic_file_splice_write, 57 .splice_write = generic_file_splice_write,
59}; 58};
@@ -71,7 +70,6 @@ const struct file_operations ext2_xip_file_operations = {
71 .open = generic_file_open, 70 .open = generic_file_open,
72 .release = ext2_release_file, 71 .release = ext2_release_file,
73 .fsync = ext2_sync_file, 72 .fsync = ext2_sync_file,
74 .sendfile = xip_file_sendfile,
75}; 73};
76#endif 74#endif
77 75
diff --git a/fs/ext3/file.c b/fs/ext3/file.c
index 1e6f13864536..acc4913d3019 100644
--- a/fs/ext3/file.c
+++ b/fs/ext3/file.c
@@ -120,7 +120,6 @@ const struct file_operations ext3_file_operations = {
120 .open = generic_file_open, 120 .open = generic_file_open,
121 .release = ext3_release_file, 121 .release = ext3_release_file,
122 .fsync = ext3_sync_file, 122 .fsync = ext3_sync_file,
123 .sendfile = generic_file_sendfile,
124 .splice_read = generic_file_splice_read, 123 .splice_read = generic_file_splice_read,
125 .splice_write = generic_file_splice_write, 124 .splice_write = generic_file_splice_write,
126}; 125};
diff --git a/fs/ext4/file.c b/fs/ext4/file.c
index 3c6c1fd2be90..d4c8186aed64 100644
--- a/fs/ext4/file.c
+++ b/fs/ext4/file.c
@@ -120,7 +120,6 @@ const struct file_operations ext4_file_operations = {
120 .open = generic_file_open, 120 .open = generic_file_open,
121 .release = ext4_release_file, 121 .release = ext4_release_file,
122 .fsync = ext4_sync_file, 122 .fsync = ext4_sync_file,
123 .sendfile = generic_file_sendfile,
124 .splice_read = generic_file_splice_read, 123 .splice_read = generic_file_splice_read,
125 .splice_write = generic_file_splice_write, 124 .splice_write = generic_file_splice_write,
126}; 125};
diff --git a/fs/fat/file.c b/fs/fat/file.c
index 55d3c7461c5b..69a83b59dce8 100644
--- a/fs/fat/file.c
+++ b/fs/fat/file.c
@@ -134,7 +134,7 @@ const struct file_operations fat_file_operations = {
134 .release = fat_file_release, 134 .release = fat_file_release,
135 .ioctl = fat_generic_ioctl, 135 .ioctl = fat_generic_ioctl,
136 .fsync = file_fsync, 136 .fsync = file_fsync,
137 .sendfile = generic_file_sendfile, 137 .splice_read = generic_file_splice_read,
138}; 138};
139 139
140static int fat_cont_expand(struct inode *inode, loff_t size) 140static int fat_cont_expand(struct inode *inode, loff_t size)
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index adf7995232b8..f79de7c8cdfa 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -802,7 +802,7 @@ static const struct file_operations fuse_file_operations = {
802 .release = fuse_release, 802 .release = fuse_release,
803 .fsync = fuse_fsync, 803 .fsync = fuse_fsync,
804 .lock = fuse_file_lock, 804 .lock = fuse_file_lock,
805 .sendfile = generic_file_sendfile, 805 .splice_read = generic_file_splice_read,
806}; 806};
807 807
808static const struct file_operations fuse_direct_io_file_operations = { 808static const struct file_operations fuse_direct_io_file_operations = {
@@ -814,7 +814,7 @@ static const struct file_operations fuse_direct_io_file_operations = {
814 .release = fuse_release, 814 .release = fuse_release,
815 .fsync = fuse_fsync, 815 .fsync = fuse_fsync,
816 .lock = fuse_file_lock, 816 .lock = fuse_file_lock,
817 /* no mmap and sendfile */ 817 /* no mmap and splice_read */
818}; 818};
819 819
820static const struct address_space_operations fuse_file_aops = { 820static const struct address_space_operations fuse_file_aops = {
diff --git a/fs/gfs2/Makefile b/fs/gfs2/Makefile
index e3f1ada643ac..04ad0caebedb 100644
--- a/fs/gfs2/Makefile
+++ b/fs/gfs2/Makefile
@@ -1,7 +1,7 @@
1obj-$(CONFIG_GFS2_FS) += gfs2.o 1obj-$(CONFIG_GFS2_FS) += gfs2.o
2gfs2-y := acl.o bmap.o daemon.o dir.o eaops.o eattr.o glock.o \ 2gfs2-y := acl.o bmap.o daemon.o dir.o eaops.o eattr.o glock.o \
3 glops.o inode.o lm.o log.o lops.o locking.o main.o meta_io.o \ 3 glops.o inode.o lm.o log.o lops.o locking.o main.o meta_io.o \
4 mount.o ondisk.o ops_address.o ops_dentry.o ops_export.o ops_file.o \ 4 mount.o ops_address.o ops_dentry.o ops_export.o ops_file.o \
5 ops_fstype.o ops_inode.o ops_super.o ops_vm.o quota.o \ 5 ops_fstype.o ops_inode.o ops_super.o ops_vm.o quota.o \
6 recovery.o rgrp.o super.o sys.o trans.o util.o 6 recovery.o rgrp.o super.o sys.o trans.o util.o
7 7
diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c
index c53a5d2d0590..cd805a66880d 100644
--- a/fs/gfs2/bmap.c
+++ b/fs/gfs2/bmap.c
@@ -718,7 +718,7 @@ static int do_strip(struct gfs2_inode *ip, struct buffer_head *dibh,
718 for (x = 0; x < rlist.rl_rgrps; x++) { 718 for (x = 0; x < rlist.rl_rgrps; x++) {
719 struct gfs2_rgrpd *rgd; 719 struct gfs2_rgrpd *rgd;
720 rgd = rlist.rl_ghs[x].gh_gl->gl_object; 720 rgd = rlist.rl_ghs[x].gh_gl->gl_object;
721 rg_blocks += rgd->rd_ri.ri_length; 721 rg_blocks += rgd->rd_length;
722 } 722 }
723 723
724 error = gfs2_glock_nq_m(rlist.rl_rgrps, rlist.rl_ghs); 724 error = gfs2_glock_nq_m(rlist.rl_rgrps, rlist.rl_ghs);
@@ -772,7 +772,7 @@ static int do_strip(struct gfs2_inode *ip, struct buffer_head *dibh,
772 gfs2_free_data(ip, bstart, blen); 772 gfs2_free_data(ip, bstart, blen);
773 } 773 }
774 774
775 ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC; 775 ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME;
776 776
777 gfs2_dinode_out(ip, dibh->b_data); 777 gfs2_dinode_out(ip, dibh->b_data);
778 778
@@ -824,7 +824,7 @@ static int do_grow(struct gfs2_inode *ip, u64 size)
824 goto out_gunlock_q; 824 goto out_gunlock_q;
825 825
826 error = gfs2_trans_begin(sdp, 826 error = gfs2_trans_begin(sdp,
827 sdp->sd_max_height + al->al_rgd->rd_ri.ri_length + 827 sdp->sd_max_height + al->al_rgd->rd_length +
828 RES_JDATA + RES_DINODE + RES_STATFS + RES_QUOTA, 0); 828 RES_JDATA + RES_DINODE + RES_STATFS + RES_QUOTA, 0);
829 if (error) 829 if (error)
830 goto out_ipres; 830 goto out_ipres;
@@ -847,7 +847,7 @@ static int do_grow(struct gfs2_inode *ip, u64 size)
847 } 847 }
848 848
849 ip->i_di.di_size = size; 849 ip->i_di.di_size = size;
850 ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC; 850 ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME;
851 851
852 error = gfs2_meta_inode_buffer(ip, &dibh); 852 error = gfs2_meta_inode_buffer(ip, &dibh);
853 if (error) 853 if (error)
@@ -885,7 +885,6 @@ static int gfs2_block_truncate_page(struct address_space *mapping)
885 unsigned blocksize, iblock, length, pos; 885 unsigned blocksize, iblock, length, pos;
886 struct buffer_head *bh; 886 struct buffer_head *bh;
887 struct page *page; 887 struct page *page;
888 void *kaddr;
889 int err; 888 int err;
890 889
891 page = grab_cache_page(mapping, index); 890 page = grab_cache_page(mapping, index);
@@ -928,15 +927,13 @@ static int gfs2_block_truncate_page(struct address_space *mapping)
928 /* Uhhuh. Read error. Complain and punt. */ 927 /* Uhhuh. Read error. Complain and punt. */
929 if (!buffer_uptodate(bh)) 928 if (!buffer_uptodate(bh))
930 goto unlock; 929 goto unlock;
930 err = 0;
931 } 931 }
932 932
933 if (sdp->sd_args.ar_data == GFS2_DATA_ORDERED || gfs2_is_jdata(ip)) 933 if (sdp->sd_args.ar_data == GFS2_DATA_ORDERED || gfs2_is_jdata(ip))
934 gfs2_trans_add_bh(ip->i_gl, bh, 0); 934 gfs2_trans_add_bh(ip->i_gl, bh, 0);
935 935
936 kaddr = kmap_atomic(page, KM_USER0); 936 zero_user_page(page, offset, length, KM_USER0);
937 memset(kaddr + offset, 0, length);
938 flush_dcache_page(page);
939 kunmap_atomic(kaddr, KM_USER0);
940 937
941unlock: 938unlock:
942 unlock_page(page); 939 unlock_page(page);
@@ -962,7 +959,7 @@ static int trunc_start(struct gfs2_inode *ip, u64 size)
962 959
963 if (gfs2_is_stuffed(ip)) { 960 if (gfs2_is_stuffed(ip)) {
964 ip->i_di.di_size = size; 961 ip->i_di.di_size = size;
965 ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC; 962 ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME;
966 gfs2_trans_add_bh(ip->i_gl, dibh, 1); 963 gfs2_trans_add_bh(ip->i_gl, dibh, 1);
967 gfs2_dinode_out(ip, dibh->b_data); 964 gfs2_dinode_out(ip, dibh->b_data);
968 gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode) + size); 965 gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode) + size);
@@ -974,7 +971,7 @@ static int trunc_start(struct gfs2_inode *ip, u64 size)
974 971
975 if (!error) { 972 if (!error) {
976 ip->i_di.di_size = size; 973 ip->i_di.di_size = size;
977 ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC; 974 ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME;
978 ip->i_di.di_flags |= GFS2_DIF_TRUNC_IN_PROG; 975 ip->i_di.di_flags |= GFS2_DIF_TRUNC_IN_PROG;
979 gfs2_trans_add_bh(ip->i_gl, dibh, 1); 976 gfs2_trans_add_bh(ip->i_gl, dibh, 1);
980 gfs2_dinode_out(ip, dibh->b_data); 977 gfs2_dinode_out(ip, dibh->b_data);
@@ -1044,10 +1041,10 @@ static int trunc_end(struct gfs2_inode *ip)
1044 ip->i_di.di_height = 0; 1041 ip->i_di.di_height = 0;
1045 ip->i_di.di_goal_meta = 1042 ip->i_di.di_goal_meta =
1046 ip->i_di.di_goal_data = 1043 ip->i_di.di_goal_data =
1047 ip->i_num.no_addr; 1044 ip->i_no_addr;
1048 gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode)); 1045 gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode));
1049 } 1046 }
1050 ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC; 1047 ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME;
1051 ip->i_di.di_flags &= ~GFS2_DIF_TRUNC_IN_PROG; 1048 ip->i_di.di_flags &= ~GFS2_DIF_TRUNC_IN_PROG;
1052 1049
1053 gfs2_trans_add_bh(ip->i_gl, dibh, 1); 1050 gfs2_trans_add_bh(ip->i_gl, dibh, 1);
diff --git a/fs/gfs2/daemon.c b/fs/gfs2/daemon.c
index 683cb5bda870..3548d9f31e0d 100644
--- a/fs/gfs2/daemon.c
+++ b/fs/gfs2/daemon.c
@@ -16,6 +16,7 @@
16#include <linux/delay.h> 16#include <linux/delay.h>
17#include <linux/gfs2_ondisk.h> 17#include <linux/gfs2_ondisk.h>
18#include <linux/lm_interface.h> 18#include <linux/lm_interface.h>
19#include <linux/freezer.h>
19 20
20#include "gfs2.h" 21#include "gfs2.h"
21#include "incore.h" 22#include "incore.h"
@@ -49,6 +50,8 @@ int gfs2_scand(void *data)
49 while (!kthread_should_stop()) { 50 while (!kthread_should_stop()) {
50 gfs2_scand_internal(sdp); 51 gfs2_scand_internal(sdp);
51 t = gfs2_tune_get(sdp, gt_scand_secs) * HZ; 52 t = gfs2_tune_get(sdp, gt_scand_secs) * HZ;
53 if (freezing(current))
54 refrigerator();
52 schedule_timeout_interruptible(t); 55 schedule_timeout_interruptible(t);
53 } 56 }
54 57
@@ -74,6 +77,8 @@ int gfs2_glockd(void *data)
74 wait_event_interruptible(sdp->sd_reclaim_wq, 77 wait_event_interruptible(sdp->sd_reclaim_wq,
75 (atomic_read(&sdp->sd_reclaim_count) || 78 (atomic_read(&sdp->sd_reclaim_count) ||
76 kthread_should_stop())); 79 kthread_should_stop()));
80 if (freezing(current))
81 refrigerator();
77 } 82 }
78 83
79 return 0; 84 return 0;
@@ -93,6 +98,8 @@ int gfs2_recoverd(void *data)
93 while (!kthread_should_stop()) { 98 while (!kthread_should_stop()) {
94 gfs2_check_journals(sdp); 99 gfs2_check_journals(sdp);
95 t = gfs2_tune_get(sdp, gt_recoverd_secs) * HZ; 100 t = gfs2_tune_get(sdp, gt_recoverd_secs) * HZ;
101 if (freezing(current))
102 refrigerator();
96 schedule_timeout_interruptible(t); 103 schedule_timeout_interruptible(t);
97 } 104 }
98 105
@@ -141,6 +148,8 @@ int gfs2_logd(void *data)
141 } 148 }
142 149
143 t = gfs2_tune_get(sdp, gt_logd_secs) * HZ; 150 t = gfs2_tune_get(sdp, gt_logd_secs) * HZ;
151 if (freezing(current))
152 refrigerator();
144 schedule_timeout_interruptible(t); 153 schedule_timeout_interruptible(t);
145 } 154 }
146 155
@@ -191,6 +200,8 @@ int gfs2_quotad(void *data)
191 gfs2_quota_scan(sdp); 200 gfs2_quota_scan(sdp);
192 201
193 t = gfs2_tune_get(sdp, gt_quotad_secs) * HZ; 202 t = gfs2_tune_get(sdp, gt_quotad_secs) * HZ;
203 if (freezing(current))
204 refrigerator();
194 schedule_timeout_interruptible(t); 205 schedule_timeout_interruptible(t);
195 } 206 }
196 207
diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c
index a96fa07b3f3b..2beb2f401aa2 100644
--- a/fs/gfs2/dir.c
+++ b/fs/gfs2/dir.c
@@ -130,7 +130,7 @@ static int gfs2_dir_write_stuffed(struct gfs2_inode *ip, const char *buf,
130 memcpy(dibh->b_data + offset + sizeof(struct gfs2_dinode), buf, size); 130 memcpy(dibh->b_data + offset + sizeof(struct gfs2_dinode), buf, size);
131 if (ip->i_di.di_size < offset + size) 131 if (ip->i_di.di_size < offset + size)
132 ip->i_di.di_size = offset + size; 132 ip->i_di.di_size = offset + size;
133 ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC; 133 ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME;
134 gfs2_dinode_out(ip, dibh->b_data); 134 gfs2_dinode_out(ip, dibh->b_data);
135 135
136 brelse(dibh); 136 brelse(dibh);
@@ -228,7 +228,7 @@ out:
228 228
229 if (ip->i_di.di_size < offset + copied) 229 if (ip->i_di.di_size < offset + copied)
230 ip->i_di.di_size = offset + copied; 230 ip->i_di.di_size = offset + copied;
231 ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC; 231 ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME;
232 232
233 gfs2_trans_add_bh(ip->i_gl, dibh, 1); 233 gfs2_trans_add_bh(ip->i_gl, dibh, 1);
234 gfs2_dinode_out(ip, dibh->b_data); 234 gfs2_dinode_out(ip, dibh->b_data);
@@ -1456,7 +1456,7 @@ int gfs2_dir_read(struct inode *inode, u64 *offset, void *opaque,
1456 if (dip->i_di.di_entries != g.offset) { 1456 if (dip->i_di.di_entries != g.offset) {
1457 fs_warn(sdp, "Number of entries corrupt in dir %llu, " 1457 fs_warn(sdp, "Number of entries corrupt in dir %llu, "
1458 "ip->i_di.di_entries (%u) != g.offset (%u)\n", 1458 "ip->i_di.di_entries (%u) != g.offset (%u)\n",
1459 (unsigned long long)dip->i_num.no_addr, 1459 (unsigned long long)dip->i_no_addr,
1460 dip->i_di.di_entries, 1460 dip->i_di.di_entries,
1461 g.offset); 1461 g.offset);
1462 error = -EIO; 1462 error = -EIO;
@@ -1488,24 +1488,55 @@ out:
1488 * Returns: errno 1488 * Returns: errno
1489 */ 1489 */
1490 1490
1491int gfs2_dir_search(struct inode *dir, const struct qstr *name, 1491struct inode *gfs2_dir_search(struct inode *dir, const struct qstr *name)
1492 struct gfs2_inum_host *inum, unsigned int *type)
1493{ 1492{
1494 struct buffer_head *bh; 1493 struct buffer_head *bh;
1495 struct gfs2_dirent *dent; 1494 struct gfs2_dirent *dent;
1495 struct inode *inode;
1496
1497 dent = gfs2_dirent_search(dir, name, gfs2_dirent_find, &bh);
1498 if (dent) {
1499 if (IS_ERR(dent))
1500 return ERR_PTR(PTR_ERR(dent));
1501 inode = gfs2_inode_lookup(dir->i_sb,
1502 be16_to_cpu(dent->de_type),
1503 be64_to_cpu(dent->de_inum.no_addr),
1504 be64_to_cpu(dent->de_inum.no_formal_ino));
1505 brelse(bh);
1506 return inode;
1507 }
1508 return ERR_PTR(-ENOENT);
1509}
1510
1511int gfs2_dir_check(struct inode *dir, const struct qstr *name,
1512 const struct gfs2_inode *ip)
1513{
1514 struct buffer_head *bh;
1515 struct gfs2_dirent *dent;
1516 int ret = -ENOENT;
1496 1517
1497 dent = gfs2_dirent_search(dir, name, gfs2_dirent_find, &bh); 1518 dent = gfs2_dirent_search(dir, name, gfs2_dirent_find, &bh);
1498 if (dent) { 1519 if (dent) {
1499 if (IS_ERR(dent)) 1520 if (IS_ERR(dent))
1500 return PTR_ERR(dent); 1521 return PTR_ERR(dent);
1501 if (inum) 1522 if (ip) {
1502 gfs2_inum_in(inum, (char *)&dent->de_inum); 1523 if (be64_to_cpu(dent->de_inum.no_addr) != ip->i_no_addr)
1503 if (type) 1524 goto out;
1504 *type = be16_to_cpu(dent->de_type); 1525 if (be64_to_cpu(dent->de_inum.no_formal_ino) !=
1526 ip->i_no_formal_ino)
1527 goto out;
1528 if (unlikely(IF2DT(ip->i_inode.i_mode) !=
1529 be16_to_cpu(dent->de_type))) {
1530 gfs2_consist_inode(GFS2_I(dir));
1531 ret = -EIO;
1532 goto out;
1533 }
1534 }
1535 ret = 0;
1536out:
1505 brelse(bh); 1537 brelse(bh);
1506 return 0;
1507 } 1538 }
1508 return -ENOENT; 1539 return ret;
1509} 1540}
1510 1541
1511static int dir_new_leaf(struct inode *inode, const struct qstr *name) 1542static int dir_new_leaf(struct inode *inode, const struct qstr *name)
@@ -1565,7 +1596,7 @@ static int dir_new_leaf(struct inode *inode, const struct qstr *name)
1565 */ 1596 */
1566 1597
1567int gfs2_dir_add(struct inode *inode, const struct qstr *name, 1598int gfs2_dir_add(struct inode *inode, const struct qstr *name,
1568 const struct gfs2_inum_host *inum, unsigned type) 1599 const struct gfs2_inode *nip, unsigned type)
1569{ 1600{
1570 struct gfs2_inode *ip = GFS2_I(inode); 1601 struct gfs2_inode *ip = GFS2_I(inode);
1571 struct buffer_head *bh; 1602 struct buffer_head *bh;
@@ -1580,7 +1611,7 @@ int gfs2_dir_add(struct inode *inode, const struct qstr *name,
1580 if (IS_ERR(dent)) 1611 if (IS_ERR(dent))
1581 return PTR_ERR(dent); 1612 return PTR_ERR(dent);
1582 dent = gfs2_init_dirent(inode, dent, name, bh); 1613 dent = gfs2_init_dirent(inode, dent, name, bh);
1583 gfs2_inum_out(inum, (char *)&dent->de_inum); 1614 gfs2_inum_out(nip, dent);
1584 dent->de_type = cpu_to_be16(type); 1615 dent->de_type = cpu_to_be16(type);
1585 if (ip->i_di.di_flags & GFS2_DIF_EXHASH) { 1616 if (ip->i_di.di_flags & GFS2_DIF_EXHASH) {
1586 leaf = (struct gfs2_leaf *)bh->b_data; 1617 leaf = (struct gfs2_leaf *)bh->b_data;
@@ -1592,7 +1623,7 @@ int gfs2_dir_add(struct inode *inode, const struct qstr *name,
1592 break; 1623 break;
1593 gfs2_trans_add_bh(ip->i_gl, bh, 1); 1624 gfs2_trans_add_bh(ip->i_gl, bh, 1);
1594 ip->i_di.di_entries++; 1625 ip->i_di.di_entries++;
1595 ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC; 1626 ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME;
1596 gfs2_dinode_out(ip, bh->b_data); 1627 gfs2_dinode_out(ip, bh->b_data);
1597 brelse(bh); 1628 brelse(bh);
1598 error = 0; 1629 error = 0;
@@ -1678,7 +1709,7 @@ int gfs2_dir_del(struct gfs2_inode *dip, const struct qstr *name)
1678 gfs2_consist_inode(dip); 1709 gfs2_consist_inode(dip);
1679 gfs2_trans_add_bh(dip->i_gl, bh, 1); 1710 gfs2_trans_add_bh(dip->i_gl, bh, 1);
1680 dip->i_di.di_entries--; 1711 dip->i_di.di_entries--;
1681 dip->i_inode.i_mtime = dip->i_inode.i_ctime = CURRENT_TIME_SEC; 1712 dip->i_inode.i_mtime = dip->i_inode.i_ctime = CURRENT_TIME;
1682 gfs2_dinode_out(dip, bh->b_data); 1713 gfs2_dinode_out(dip, bh->b_data);
1683 brelse(bh); 1714 brelse(bh);
1684 mark_inode_dirty(&dip->i_inode); 1715 mark_inode_dirty(&dip->i_inode);
@@ -1700,7 +1731,7 @@ int gfs2_dir_del(struct gfs2_inode *dip, const struct qstr *name)
1700 */ 1731 */
1701 1732
1702int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename, 1733int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename,
1703 struct gfs2_inum_host *inum, unsigned int new_type) 1734 const struct gfs2_inode *nip, unsigned int new_type)
1704{ 1735{
1705 struct buffer_head *bh; 1736 struct buffer_head *bh;
1706 struct gfs2_dirent *dent; 1737 struct gfs2_dirent *dent;
@@ -1715,7 +1746,7 @@ int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename,
1715 return PTR_ERR(dent); 1746 return PTR_ERR(dent);
1716 1747
1717 gfs2_trans_add_bh(dip->i_gl, bh, 1); 1748 gfs2_trans_add_bh(dip->i_gl, bh, 1);
1718 gfs2_inum_out(inum, (char *)&dent->de_inum); 1749 gfs2_inum_out(nip, dent);
1719 dent->de_type = cpu_to_be16(new_type); 1750 dent->de_type = cpu_to_be16(new_type);
1720 1751
1721 if (dip->i_di.di_flags & GFS2_DIF_EXHASH) { 1752 if (dip->i_di.di_flags & GFS2_DIF_EXHASH) {
@@ -1726,7 +1757,7 @@ int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename,
1726 gfs2_trans_add_bh(dip->i_gl, bh, 1); 1757 gfs2_trans_add_bh(dip->i_gl, bh, 1);
1727 } 1758 }
1728 1759
1729 dip->i_inode.i_mtime = dip->i_inode.i_ctime = CURRENT_TIME_SEC; 1760 dip->i_inode.i_mtime = dip->i_inode.i_ctime = CURRENT_TIME;
1730 gfs2_dinode_out(dip, bh->b_data); 1761 gfs2_dinode_out(dip, bh->b_data);
1731 brelse(bh); 1762 brelse(bh);
1732 return 0; 1763 return 0;
@@ -1867,7 +1898,7 @@ static int leaf_dealloc(struct gfs2_inode *dip, u32 index, u32 len,
1867 for (x = 0; x < rlist.rl_rgrps; x++) { 1898 for (x = 0; x < rlist.rl_rgrps; x++) {
1868 struct gfs2_rgrpd *rgd; 1899 struct gfs2_rgrpd *rgd;
1869 rgd = rlist.rl_ghs[x].gh_gl->gl_object; 1900 rgd = rlist.rl_ghs[x].gh_gl->gl_object;
1870 rg_blocks += rgd->rd_ri.ri_length; 1901 rg_blocks += rgd->rd_length;
1871 } 1902 }
1872 1903
1873 error = gfs2_glock_nq_m(rlist.rl_rgrps, rlist.rl_ghs); 1904 error = gfs2_glock_nq_m(rlist.rl_rgrps, rlist.rl_ghs);
diff --git a/fs/gfs2/dir.h b/fs/gfs2/dir.h
index 48fe89046bba..8a468cac9328 100644
--- a/fs/gfs2/dir.h
+++ b/fs/gfs2/dir.h
@@ -16,15 +16,16 @@ struct inode;
16struct gfs2_inode; 16struct gfs2_inode;
17struct gfs2_inum; 17struct gfs2_inum;
18 18
19int gfs2_dir_search(struct inode *dir, const struct qstr *filename, 19struct inode *gfs2_dir_search(struct inode *dir, const struct qstr *filename);
20 struct gfs2_inum_host *inum, unsigned int *type); 20int gfs2_dir_check(struct inode *dir, const struct qstr *filename,
21 const struct gfs2_inode *ip);
21int gfs2_dir_add(struct inode *inode, const struct qstr *filename, 22int gfs2_dir_add(struct inode *inode, const struct qstr *filename,
22 const struct gfs2_inum_host *inum, unsigned int type); 23 const struct gfs2_inode *ip, unsigned int type);
23int gfs2_dir_del(struct gfs2_inode *dip, const struct qstr *filename); 24int gfs2_dir_del(struct gfs2_inode *dip, const struct qstr *filename);
24int gfs2_dir_read(struct inode *inode, u64 *offset, void *opaque, 25int gfs2_dir_read(struct inode *inode, u64 *offset, void *opaque,
25 filldir_t filldir); 26 filldir_t filldir);
26int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename, 27int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename,
27 struct gfs2_inum_host *new_inum, unsigned int new_type); 28 const struct gfs2_inode *nip, unsigned int new_type);
28 29
29int gfs2_dir_exhash_dealloc(struct gfs2_inode *dip); 30int gfs2_dir_exhash_dealloc(struct gfs2_inode *dip);
30 31
diff --git a/fs/gfs2/eattr.c b/fs/gfs2/eattr.c
index 5b83ca6acab1..2a7435b5c4dc 100644
--- a/fs/gfs2/eattr.c
+++ b/fs/gfs2/eattr.c
@@ -254,7 +254,7 @@ static int ea_dealloc_unstuffed(struct gfs2_inode *ip, struct buffer_head *bh,
254 if (error) 254 if (error)
255 return error; 255 return error;
256 256
257 error = gfs2_trans_begin(sdp, rgd->rd_ri.ri_length + RES_DINODE + 257 error = gfs2_trans_begin(sdp, rgd->rd_length + RES_DINODE +
258 RES_EATTR + RES_STATFS + RES_QUOTA, blks); 258 RES_EATTR + RES_STATFS + RES_QUOTA, blks);
259 if (error) 259 if (error)
260 goto out_gunlock; 260 goto out_gunlock;
@@ -300,7 +300,7 @@ static int ea_dealloc_unstuffed(struct gfs2_inode *ip, struct buffer_head *bh,
300 300
301 error = gfs2_meta_inode_buffer(ip, &dibh); 301 error = gfs2_meta_inode_buffer(ip, &dibh);
302 if (!error) { 302 if (!error) {
303 ip->i_inode.i_ctime = CURRENT_TIME_SEC; 303 ip->i_inode.i_ctime = CURRENT_TIME;
304 gfs2_trans_add_bh(ip->i_gl, dibh, 1); 304 gfs2_trans_add_bh(ip->i_gl, dibh, 1);
305 gfs2_dinode_out(ip, dibh->b_data); 305 gfs2_dinode_out(ip, dibh->b_data);
306 brelse(dibh); 306 brelse(dibh);
@@ -700,7 +700,7 @@ static int ea_alloc_skeleton(struct gfs2_inode *ip, struct gfs2_ea_request *er,
700 goto out_gunlock_q; 700 goto out_gunlock_q;
701 701
702 error = gfs2_trans_begin(GFS2_SB(&ip->i_inode), 702 error = gfs2_trans_begin(GFS2_SB(&ip->i_inode),
703 blks + al->al_rgd->rd_ri.ri_length + 703 blks + al->al_rgd->rd_length +
704 RES_DINODE + RES_STATFS + RES_QUOTA, 0); 704 RES_DINODE + RES_STATFS + RES_QUOTA, 0);
705 if (error) 705 if (error)
706 goto out_ipres; 706 goto out_ipres;
@@ -717,7 +717,7 @@ static int ea_alloc_skeleton(struct gfs2_inode *ip, struct gfs2_ea_request *er,
717 (er->er_mode & S_IFMT)); 717 (er->er_mode & S_IFMT));
718 ip->i_inode.i_mode = er->er_mode; 718 ip->i_inode.i_mode = er->er_mode;
719 } 719 }
720 ip->i_inode.i_ctime = CURRENT_TIME_SEC; 720 ip->i_inode.i_ctime = CURRENT_TIME;
721 gfs2_trans_add_bh(ip->i_gl, dibh, 1); 721 gfs2_trans_add_bh(ip->i_gl, dibh, 1);
722 gfs2_dinode_out(ip, dibh->b_data); 722 gfs2_dinode_out(ip, dibh->b_data);
723 brelse(dibh); 723 brelse(dibh);
@@ -852,7 +852,7 @@ static int ea_set_simple_noalloc(struct gfs2_inode *ip, struct buffer_head *bh,
852 (ip->i_inode.i_mode & S_IFMT) == (er->er_mode & S_IFMT)); 852 (ip->i_inode.i_mode & S_IFMT) == (er->er_mode & S_IFMT));
853 ip->i_inode.i_mode = er->er_mode; 853 ip->i_inode.i_mode = er->er_mode;
854 } 854 }
855 ip->i_inode.i_ctime = CURRENT_TIME_SEC; 855 ip->i_inode.i_ctime = CURRENT_TIME;
856 gfs2_trans_add_bh(ip->i_gl, dibh, 1); 856 gfs2_trans_add_bh(ip->i_gl, dibh, 1);
857 gfs2_dinode_out(ip, dibh->b_data); 857 gfs2_dinode_out(ip, dibh->b_data);
858 brelse(dibh); 858 brelse(dibh);
@@ -1133,7 +1133,7 @@ static int ea_remove_stuffed(struct gfs2_inode *ip, struct gfs2_ea_location *el)
1133 1133
1134 error = gfs2_meta_inode_buffer(ip, &dibh); 1134 error = gfs2_meta_inode_buffer(ip, &dibh);
1135 if (!error) { 1135 if (!error) {
1136 ip->i_inode.i_ctime = CURRENT_TIME_SEC; 1136 ip->i_inode.i_ctime = CURRENT_TIME;
1137 gfs2_trans_add_bh(ip->i_gl, dibh, 1); 1137 gfs2_trans_add_bh(ip->i_gl, dibh, 1);
1138 gfs2_dinode_out(ip, dibh->b_data); 1138 gfs2_dinode_out(ip, dibh->b_data);
1139 brelse(dibh); 1139 brelse(dibh);
@@ -1352,7 +1352,7 @@ static int ea_dealloc_indirect(struct gfs2_inode *ip)
1352 for (x = 0; x < rlist.rl_rgrps; x++) { 1352 for (x = 0; x < rlist.rl_rgrps; x++) {
1353 struct gfs2_rgrpd *rgd; 1353 struct gfs2_rgrpd *rgd;
1354 rgd = rlist.rl_ghs[x].gh_gl->gl_object; 1354 rgd = rlist.rl_ghs[x].gh_gl->gl_object;
1355 rg_blocks += rgd->rd_ri.ri_length; 1355 rg_blocks += rgd->rd_length;
1356 } 1356 }
1357 1357
1358 error = gfs2_glock_nq_m(rlist.rl_rgrps, rlist.rl_ghs); 1358 error = gfs2_glock_nq_m(rlist.rl_rgrps, rlist.rl_ghs);
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index 1815429a2978..3f0974e1afef 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -422,11 +422,11 @@ void gfs2_holder_uninit(struct gfs2_holder *gh)
422static void gfs2_holder_wake(struct gfs2_holder *gh) 422static void gfs2_holder_wake(struct gfs2_holder *gh)
423{ 423{
424 clear_bit(HIF_WAIT, &gh->gh_iflags); 424 clear_bit(HIF_WAIT, &gh->gh_iflags);
425 smp_mb(); 425 smp_mb__after_clear_bit();
426 wake_up_bit(&gh->gh_iflags, HIF_WAIT); 426 wake_up_bit(&gh->gh_iflags, HIF_WAIT);
427} 427}
428 428
429static int holder_wait(void *word) 429static int just_schedule(void *word)
430{ 430{
431 schedule(); 431 schedule();
432 return 0; 432 return 0;
@@ -435,7 +435,20 @@ static int holder_wait(void *word)
435static void wait_on_holder(struct gfs2_holder *gh) 435static void wait_on_holder(struct gfs2_holder *gh)
436{ 436{
437 might_sleep(); 437 might_sleep();
438 wait_on_bit(&gh->gh_iflags, HIF_WAIT, holder_wait, TASK_UNINTERRUPTIBLE); 438 wait_on_bit(&gh->gh_iflags, HIF_WAIT, just_schedule, TASK_UNINTERRUPTIBLE);
439}
440
441static void gfs2_demote_wake(struct gfs2_glock *gl)
442{
443 clear_bit(GLF_DEMOTE, &gl->gl_flags);
444 smp_mb__after_clear_bit();
445 wake_up_bit(&gl->gl_flags, GLF_DEMOTE);
446}
447
448static void wait_on_demote(struct gfs2_glock *gl)
449{
450 might_sleep();
451 wait_on_bit(&gl->gl_flags, GLF_DEMOTE, just_schedule, TASK_UNINTERRUPTIBLE);
439} 452}
440 453
441/** 454/**
@@ -528,7 +541,7 @@ static int rq_demote(struct gfs2_glock *gl)
528 541
529 if (gl->gl_state == gl->gl_demote_state || 542 if (gl->gl_state == gl->gl_demote_state ||
530 gl->gl_state == LM_ST_UNLOCKED) { 543 gl->gl_state == LM_ST_UNLOCKED) {
531 clear_bit(GLF_DEMOTE, &gl->gl_flags); 544 gfs2_demote_wake(gl);
532 return 0; 545 return 0;
533 } 546 }
534 set_bit(GLF_LOCK, &gl->gl_flags); 547 set_bit(GLF_LOCK, &gl->gl_flags);
@@ -666,12 +679,22 @@ static void gfs2_glmutex_unlock(struct gfs2_glock *gl)
666 * practise: LM_ST_SHARED and LM_ST_UNLOCKED 679 * practise: LM_ST_SHARED and LM_ST_UNLOCKED
667 */ 680 */
668 681
669static void handle_callback(struct gfs2_glock *gl, unsigned int state) 682static void handle_callback(struct gfs2_glock *gl, unsigned int state, int remote)
670{ 683{
671 spin_lock(&gl->gl_spin); 684 spin_lock(&gl->gl_spin);
672 if (test_and_set_bit(GLF_DEMOTE, &gl->gl_flags) == 0) { 685 if (test_and_set_bit(GLF_DEMOTE, &gl->gl_flags) == 0) {
673 gl->gl_demote_state = state; 686 gl->gl_demote_state = state;
674 gl->gl_demote_time = jiffies; 687 gl->gl_demote_time = jiffies;
688 if (remote && gl->gl_ops->go_type == LM_TYPE_IOPEN &&
689 gl->gl_object) {
690 struct inode *inode = igrab(gl->gl_object);
691 spin_unlock(&gl->gl_spin);
692 if (inode) {
693 d_prune_aliases(inode);
694 iput(inode);
695 }
696 return;
697 }
675 } else if (gl->gl_demote_state != LM_ST_UNLOCKED) { 698 } else if (gl->gl_demote_state != LM_ST_UNLOCKED) {
676 gl->gl_demote_state = state; 699 gl->gl_demote_state = state;
677 } 700 }
@@ -740,7 +763,7 @@ static void xmote_bh(struct gfs2_glock *gl, unsigned int ret)
740 if (ret & LM_OUT_CANCELED) 763 if (ret & LM_OUT_CANCELED)
741 op_done = 0; 764 op_done = 0;
742 else 765 else
743 clear_bit(GLF_DEMOTE, &gl->gl_flags); 766 gfs2_demote_wake(gl);
744 } else { 767 } else {
745 spin_lock(&gl->gl_spin); 768 spin_lock(&gl->gl_spin);
746 list_del_init(&gh->gh_list); 769 list_del_init(&gh->gh_list);
@@ -848,7 +871,7 @@ static void drop_bh(struct gfs2_glock *gl, unsigned int ret)
848 gfs2_assert_warn(sdp, !ret); 871 gfs2_assert_warn(sdp, !ret);
849 872
850 state_change(gl, LM_ST_UNLOCKED); 873 state_change(gl, LM_ST_UNLOCKED);
851 clear_bit(GLF_DEMOTE, &gl->gl_flags); 874 gfs2_demote_wake(gl);
852 875
853 if (glops->go_inval) 876 if (glops->go_inval)
854 glops->go_inval(gl, DIO_METADATA); 877 glops->go_inval(gl, DIO_METADATA);
@@ -1174,7 +1197,7 @@ void gfs2_glock_dq(struct gfs2_holder *gh)
1174 const struct gfs2_glock_operations *glops = gl->gl_ops; 1197 const struct gfs2_glock_operations *glops = gl->gl_ops;
1175 1198
1176 if (gh->gh_flags & GL_NOCACHE) 1199 if (gh->gh_flags & GL_NOCACHE)
1177 handle_callback(gl, LM_ST_UNLOCKED); 1200 handle_callback(gl, LM_ST_UNLOCKED, 0);
1178 1201
1179 gfs2_glmutex_lock(gl); 1202 gfs2_glmutex_lock(gl);
1180 1203
@@ -1196,6 +1219,13 @@ void gfs2_glock_dq(struct gfs2_holder *gh)
1196 spin_unlock(&gl->gl_spin); 1219 spin_unlock(&gl->gl_spin);
1197} 1220}
1198 1221
1222void gfs2_glock_dq_wait(struct gfs2_holder *gh)
1223{
1224 struct gfs2_glock *gl = gh->gh_gl;
1225 gfs2_glock_dq(gh);
1226 wait_on_demote(gl);
1227}
1228
1199/** 1229/**
1200 * gfs2_glock_dq_uninit - dequeue a holder from a glock and initialize it 1230 * gfs2_glock_dq_uninit - dequeue a holder from a glock and initialize it
1201 * @gh: the holder structure 1231 * @gh: the holder structure
@@ -1297,10 +1327,6 @@ static int nq_m_sync(unsigned int num_gh, struct gfs2_holder *ghs,
1297 * @num_gh: the number of structures 1327 * @num_gh: the number of structures
1298 * @ghs: an array of struct gfs2_holder structures 1328 * @ghs: an array of struct gfs2_holder structures
1299 * 1329 *
1300 * Figure out how big an impact this function has. Either:
1301 * 1) Replace this code with code that calls gfs2_glock_prefetch()
1302 * 2) Forget async stuff and just call nq_m_sync()
1303 * 3) Leave it like it is
1304 * 1330 *
1305 * Returns: 0 on success (all glocks acquired), 1331 * Returns: 0 on success (all glocks acquired),
1306 * errno on failure (no glocks acquired) 1332 * errno on failure (no glocks acquired)
@@ -1308,62 +1334,28 @@ static int nq_m_sync(unsigned int num_gh, struct gfs2_holder *ghs,
1308 1334
1309int gfs2_glock_nq_m(unsigned int num_gh, struct gfs2_holder *ghs) 1335int gfs2_glock_nq_m(unsigned int num_gh, struct gfs2_holder *ghs)
1310{ 1336{
1311 int *e; 1337 struct gfs2_holder *tmp[4];
1312 unsigned int x; 1338 struct gfs2_holder **pph = tmp;
1313 int borked = 0, serious = 0;
1314 int error = 0; 1339 int error = 0;
1315 1340
1316 if (!num_gh) 1341 switch(num_gh) {
1342 case 0:
1317 return 0; 1343 return 0;
1318 1344 case 1:
1319 if (num_gh == 1) {
1320 ghs->gh_flags &= ~(LM_FLAG_TRY | GL_ASYNC); 1345 ghs->gh_flags &= ~(LM_FLAG_TRY | GL_ASYNC);
1321 return gfs2_glock_nq(ghs); 1346 return gfs2_glock_nq(ghs);
1322 } 1347 default:
1323 1348 if (num_gh <= 4)
1324 e = kcalloc(num_gh, sizeof(struct gfs2_holder *), GFP_KERNEL);
1325 if (!e)
1326 return -ENOMEM;
1327
1328 for (x = 0; x < num_gh; x++) {
1329 ghs[x].gh_flags |= LM_FLAG_TRY | GL_ASYNC;
1330 error = gfs2_glock_nq(&ghs[x]);
1331 if (error) {
1332 borked = 1;
1333 serious = error;
1334 num_gh = x;
1335 break; 1349 break;
1336 } 1350 pph = kmalloc(num_gh * sizeof(struct gfs2_holder *), GFP_NOFS);
1337 } 1351 if (!pph)
1338 1352 return -ENOMEM;
1339 for (x = 0; x < num_gh; x++) {
1340 error = e[x] = glock_wait_internal(&ghs[x]);
1341 if (error) {
1342 borked = 1;
1343 if (error != GLR_TRYFAILED && error != GLR_CANCELED)
1344 serious = error;
1345 }
1346 } 1353 }
1347 1354
1348 if (!borked) { 1355 error = nq_m_sync(num_gh, ghs, pph);
1349 kfree(e);
1350 return 0;
1351 }
1352
1353 for (x = 0; x < num_gh; x++)
1354 if (!e[x])
1355 gfs2_glock_dq(&ghs[x]);
1356
1357 if (serious)
1358 error = serious;
1359 else {
1360 for (x = 0; x < num_gh; x++)
1361 gfs2_holder_reinit(ghs[x].gh_state, ghs[x].gh_flags,
1362 &ghs[x]);
1363 error = nq_m_sync(num_gh, ghs, (struct gfs2_holder **)e);
1364 }
1365 1356
1366 kfree(e); 1357 if (pph != tmp)
1358 kfree(pph);
1367 1359
1368 return error; 1360 return error;
1369} 1361}
@@ -1456,7 +1448,7 @@ static void blocking_cb(struct gfs2_sbd *sdp, struct lm_lockname *name,
1456 if (!gl) 1448 if (!gl)
1457 return; 1449 return;
1458 1450
1459 handle_callback(gl, state); 1451 handle_callback(gl, state, 1);
1460 1452
1461 spin_lock(&gl->gl_spin); 1453 spin_lock(&gl->gl_spin);
1462 run_queue(gl); 1454 run_queue(gl);
@@ -1596,7 +1588,7 @@ void gfs2_reclaim_glock(struct gfs2_sbd *sdp)
1596 if (gfs2_glmutex_trylock(gl)) { 1588 if (gfs2_glmutex_trylock(gl)) {
1597 if (list_empty(&gl->gl_holders) && 1589 if (list_empty(&gl->gl_holders) &&
1598 gl->gl_state != LM_ST_UNLOCKED && demote_ok(gl)) 1590 gl->gl_state != LM_ST_UNLOCKED && demote_ok(gl))
1599 handle_callback(gl, LM_ST_UNLOCKED); 1591 handle_callback(gl, LM_ST_UNLOCKED, 0);
1600 gfs2_glmutex_unlock(gl); 1592 gfs2_glmutex_unlock(gl);
1601 } 1593 }
1602 1594
@@ -1709,7 +1701,7 @@ static void clear_glock(struct gfs2_glock *gl)
1709 if (gfs2_glmutex_trylock(gl)) { 1701 if (gfs2_glmutex_trylock(gl)) {
1710 if (list_empty(&gl->gl_holders) && 1702 if (list_empty(&gl->gl_holders) &&
1711 gl->gl_state != LM_ST_UNLOCKED) 1703 gl->gl_state != LM_ST_UNLOCKED)
1712 handle_callback(gl, LM_ST_UNLOCKED); 1704 handle_callback(gl, LM_ST_UNLOCKED, 0);
1713 gfs2_glmutex_unlock(gl); 1705 gfs2_glmutex_unlock(gl);
1714 } 1706 }
1715} 1707}
@@ -1823,7 +1815,8 @@ static int dump_inode(struct glock_iter *gi, struct gfs2_inode *ip)
1823 1815
1824 print_dbg(gi, " Inode:\n"); 1816 print_dbg(gi, " Inode:\n");
1825 print_dbg(gi, " num = %llu/%llu\n", 1817 print_dbg(gi, " num = %llu/%llu\n",
1826 ip->i_num.no_formal_ino, ip->i_num.no_addr); 1818 (unsigned long long)ip->i_no_formal_ino,
1819 (unsigned long long)ip->i_no_addr);
1827 print_dbg(gi, " type = %u\n", IF2DT(ip->i_inode.i_mode)); 1820 print_dbg(gi, " type = %u\n", IF2DT(ip->i_inode.i_mode));
1828 print_dbg(gi, " i_flags ="); 1821 print_dbg(gi, " i_flags =");
1829 for (x = 0; x < 32; x++) 1822 for (x = 0; x < 32; x++)
@@ -1909,8 +1902,8 @@ static int dump_glock(struct glock_iter *gi, struct gfs2_glock *gl)
1909 } 1902 }
1910 if (test_bit(GLF_DEMOTE, &gl->gl_flags)) { 1903 if (test_bit(GLF_DEMOTE, &gl->gl_flags)) {
1911 print_dbg(gi, " Demotion req to state %u (%llu uS ago)\n", 1904 print_dbg(gi, " Demotion req to state %u (%llu uS ago)\n",
1912 gl->gl_demote_state, 1905 gl->gl_demote_state, (unsigned long long)
1913 (u64)(jiffies - gl->gl_demote_time)*(1000000/HZ)); 1906 (jiffies - gl->gl_demote_time)*(1000000/HZ));
1914 } 1907 }
1915 if (gl->gl_ops == &gfs2_inode_glops && gl->gl_object) { 1908 if (gl->gl_ops == &gfs2_inode_glops && gl->gl_object) {
1916 if (!test_bit(GLF_LOCK, &gl->gl_flags) && 1909 if (!test_bit(GLF_LOCK, &gl->gl_flags) &&
diff --git a/fs/gfs2/glock.h b/fs/gfs2/glock.h
index b3e152db70c8..7721ca3fff9e 100644
--- a/fs/gfs2/glock.h
+++ b/fs/gfs2/glock.h
@@ -87,6 +87,7 @@ int gfs2_glock_nq(struct gfs2_holder *gh);
87int gfs2_glock_poll(struct gfs2_holder *gh); 87int gfs2_glock_poll(struct gfs2_holder *gh);
88int gfs2_glock_wait(struct gfs2_holder *gh); 88int gfs2_glock_wait(struct gfs2_holder *gh);
89void gfs2_glock_dq(struct gfs2_holder *gh); 89void gfs2_glock_dq(struct gfs2_holder *gh);
90void gfs2_glock_dq_wait(struct gfs2_holder *gh);
90 91
91void gfs2_glock_dq_uninit(struct gfs2_holder *gh); 92void gfs2_glock_dq_uninit(struct gfs2_holder *gh);
92int gfs2_glock_nq_num(struct gfs2_sbd *sdp, 93int gfs2_glock_nq_num(struct gfs2_sbd *sdp,
diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c
index 7b82657a9910..777ca46010e8 100644
--- a/fs/gfs2/glops.c
+++ b/fs/gfs2/glops.c
@@ -156,9 +156,9 @@ static void inode_go_sync(struct gfs2_glock *gl)
156 ip = NULL; 156 ip = NULL;
157 157
158 if (test_bit(GLF_DIRTY, &gl->gl_flags)) { 158 if (test_bit(GLF_DIRTY, &gl->gl_flags)) {
159 gfs2_log_flush(gl->gl_sbd, gl);
160 if (ip) 159 if (ip)
161 filemap_fdatawrite(ip->i_inode.i_mapping); 160 filemap_fdatawrite(ip->i_inode.i_mapping);
161 gfs2_log_flush(gl->gl_sbd, gl);
162 gfs2_meta_sync(gl); 162 gfs2_meta_sync(gl);
163 if (ip) { 163 if (ip) {
164 struct address_space *mapping = ip->i_inode.i_mapping; 164 struct address_space *mapping = ip->i_inode.i_mapping;
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h
index d995441373ab..170ba93829c0 100644
--- a/fs/gfs2/incore.h
+++ b/fs/gfs2/incore.h
@@ -28,6 +28,14 @@ struct gfs2_sbd;
28 28
29typedef void (*gfs2_glop_bh_t) (struct gfs2_glock *gl, unsigned int ret); 29typedef void (*gfs2_glop_bh_t) (struct gfs2_glock *gl, unsigned int ret);
30 30
31struct gfs2_log_header_host {
32 u64 lh_sequence; /* Sequence number of this transaction */
33 u32 lh_flags; /* GFS2_LOG_HEAD_... */
34 u32 lh_tail; /* Block number of log tail */
35 u32 lh_blkno;
36 u32 lh_hash;
37};
38
31/* 39/*
32 * Structure of operations that are associated with each 40 * Structure of operations that are associated with each
33 * type of element in the log. 41 * type of element in the log.
@@ -60,12 +68,23 @@ struct gfs2_bitmap {
60 u32 bi_len; 68 u32 bi_len;
61}; 69};
62 70
71struct gfs2_rgrp_host {
72 u32 rg_flags;
73 u32 rg_free;
74 u32 rg_dinodes;
75 u64 rg_igeneration;
76};
77
63struct gfs2_rgrpd { 78struct gfs2_rgrpd {
64 struct list_head rd_list; /* Link with superblock */ 79 struct list_head rd_list; /* Link with superblock */
65 struct list_head rd_list_mru; 80 struct list_head rd_list_mru;
66 struct list_head rd_recent; /* Recently used rgrps */ 81 struct list_head rd_recent; /* Recently used rgrps */
67 struct gfs2_glock *rd_gl; /* Glock for this rgrp */ 82 struct gfs2_glock *rd_gl; /* Glock for this rgrp */
68 struct gfs2_rindex_host rd_ri; 83 u64 rd_addr; /* grp block disk address */
84 u64 rd_data0; /* first data location */
85 u32 rd_length; /* length of rgrp header in fs blocks */
86 u32 rd_data; /* num of data blocks in rgrp */
87 u32 rd_bitbytes; /* number of bytes in data bitmaps */
69 struct gfs2_rgrp_host rd_rg; 88 struct gfs2_rgrp_host rd_rg;
70 u64 rd_rg_vn; 89 u64 rd_rg_vn;
71 struct gfs2_bitmap *rd_bits; 90 struct gfs2_bitmap *rd_bits;
@@ -76,6 +95,8 @@ struct gfs2_rgrpd {
76 u32 rd_last_alloc_data; 95 u32 rd_last_alloc_data;
77 u32 rd_last_alloc_meta; 96 u32 rd_last_alloc_meta;
78 struct gfs2_sbd *rd_sbd; 97 struct gfs2_sbd *rd_sbd;
98 unsigned long rd_flags;
99#define GFS2_RDF_CHECK 0x0001 /* Need to check for unlinked inodes */
79}; 100};
80 101
81enum gfs2_state_bits { 102enum gfs2_state_bits {
@@ -211,10 +232,24 @@ enum {
211 GIF_SW_PAGED = 3, 232 GIF_SW_PAGED = 3,
212}; 233};
213 234
235struct gfs2_dinode_host {
236 u64 di_size; /* number of bytes in file */
237 u64 di_blocks; /* number of blocks in file */
238 u64 di_goal_meta; /* rgrp to alloc from next */
239 u64 di_goal_data; /* data block goal */
240 u64 di_generation; /* generation number for NFS */
241 u32 di_flags; /* GFS2_DIF_... */
242 u16 di_height; /* height of metadata */
243 /* These only apply to directories */
244 u16 di_depth; /* Number of bits in the table */
245 u32 di_entries; /* The number of entries in the directory */
246 u64 di_eattr; /* extended attribute block number */
247};
248
214struct gfs2_inode { 249struct gfs2_inode {
215 struct inode i_inode; 250 struct inode i_inode;
216 struct gfs2_inum_host i_num; 251 u64 i_no_addr;
217 252 u64 i_no_formal_ino;
218 unsigned long i_flags; /* GIF_... */ 253 unsigned long i_flags; /* GIF_... */
219 254
220 struct gfs2_dinode_host i_di; /* To be replaced by ref to block */ 255 struct gfs2_dinode_host i_di; /* To be replaced by ref to block */
@@ -275,14 +310,6 @@ enum {
275 QDF_LOCKED = 2, 310 QDF_LOCKED = 2,
276}; 311};
277 312
278struct gfs2_quota_lvb {
279 __be32 qb_magic;
280 u32 __pad;
281 __be64 qb_limit; /* Hard limit of # blocks to alloc */
282 __be64 qb_warn; /* Warn user when alloc is above this # */
283 __be64 qb_value; /* Current # blocks allocated */
284};
285
286struct gfs2_quota_data { 313struct gfs2_quota_data {
287 struct list_head qd_list; 314 struct list_head qd_list;
288 unsigned int qd_count; 315 unsigned int qd_count;
@@ -327,7 +354,9 @@ struct gfs2_trans {
327 354
328 unsigned int tr_num_buf; 355 unsigned int tr_num_buf;
329 unsigned int tr_num_buf_new; 356 unsigned int tr_num_buf_new;
357 unsigned int tr_num_databuf_new;
330 unsigned int tr_num_buf_rm; 358 unsigned int tr_num_buf_rm;
359 unsigned int tr_num_databuf_rm;
331 struct list_head tr_list_buf; 360 struct list_head tr_list_buf;
332 361
333 unsigned int tr_num_revoke; 362 unsigned int tr_num_revoke;
@@ -354,6 +383,12 @@ struct gfs2_jdesc {
354 unsigned int jd_blocks; 383 unsigned int jd_blocks;
355}; 384};
356 385
386struct gfs2_statfs_change_host {
387 s64 sc_total;
388 s64 sc_free;
389 s64 sc_dinodes;
390};
391
357#define GFS2_GLOCKD_DEFAULT 1 392#define GFS2_GLOCKD_DEFAULT 1
358#define GFS2_GLOCKD_MAX 16 393#define GFS2_GLOCKD_MAX 16
359 394
@@ -426,6 +461,28 @@ enum {
426 461
427#define GFS2_FSNAME_LEN 256 462#define GFS2_FSNAME_LEN 256
428 463
464struct gfs2_inum_host {
465 u64 no_formal_ino;
466 u64 no_addr;
467};
468
469struct gfs2_sb_host {
470 u32 sb_magic;
471 u32 sb_type;
472 u32 sb_format;
473
474 u32 sb_fs_format;
475 u32 sb_multihost_format;
476 u32 sb_bsize;
477 u32 sb_bsize_shift;
478
479 struct gfs2_inum_host sb_master_dir;
480 struct gfs2_inum_host sb_root_dir;
481
482 char sb_lockproto[GFS2_LOCKNAME_LEN];
483 char sb_locktable[GFS2_LOCKNAME_LEN];
484};
485
429struct gfs2_sbd { 486struct gfs2_sbd {
430 struct super_block *sd_vfs; 487 struct super_block *sd_vfs;
431 struct super_block *sd_vfs_meta; 488 struct super_block *sd_vfs_meta;
@@ -544,6 +601,7 @@ struct gfs2_sbd {
544 601
545 unsigned int sd_log_blks_reserved; 602 unsigned int sd_log_blks_reserved;
546 unsigned int sd_log_commited_buf; 603 unsigned int sd_log_commited_buf;
604 unsigned int sd_log_commited_databuf;
547 unsigned int sd_log_commited_revoke; 605 unsigned int sd_log_commited_revoke;
548 606
549 unsigned int sd_log_num_gl; 607 unsigned int sd_log_num_gl;
@@ -552,7 +610,6 @@ struct gfs2_sbd {
552 unsigned int sd_log_num_rg; 610 unsigned int sd_log_num_rg;
553 unsigned int sd_log_num_databuf; 611 unsigned int sd_log_num_databuf;
554 unsigned int sd_log_num_jdata; 612 unsigned int sd_log_num_jdata;
555 unsigned int sd_log_num_hdrs;
556 613
557 struct list_head sd_log_le_gl; 614 struct list_head sd_log_le_gl;
558 struct list_head sd_log_le_buf; 615 struct list_head sd_log_le_buf;
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index df0b8b3018b9..34f7bcdea1e9 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -38,12 +38,17 @@
38#include "trans.h" 38#include "trans.h"
39#include "util.h" 39#include "util.h"
40 40
41struct gfs2_inum_range_host {
42 u64 ir_start;
43 u64 ir_length;
44};
45
41static int iget_test(struct inode *inode, void *opaque) 46static int iget_test(struct inode *inode, void *opaque)
42{ 47{
43 struct gfs2_inode *ip = GFS2_I(inode); 48 struct gfs2_inode *ip = GFS2_I(inode);
44 struct gfs2_inum_host *inum = opaque; 49 u64 *no_addr = opaque;
45 50
46 if (ip->i_num.no_addr == inum->no_addr && 51 if (ip->i_no_addr == *no_addr &&
47 inode->i_private != NULL) 52 inode->i_private != NULL)
48 return 1; 53 return 1;
49 54
@@ -53,37 +58,70 @@ static int iget_test(struct inode *inode, void *opaque)
53static int iget_set(struct inode *inode, void *opaque) 58static int iget_set(struct inode *inode, void *opaque)
54{ 59{
55 struct gfs2_inode *ip = GFS2_I(inode); 60 struct gfs2_inode *ip = GFS2_I(inode);
56 struct gfs2_inum_host *inum = opaque; 61 u64 *no_addr = opaque;
57 62
58 ip->i_num = *inum; 63 inode->i_ino = (unsigned long)*no_addr;
59 inode->i_ino = inum->no_addr; 64 ip->i_no_addr = *no_addr;
60 return 0; 65 return 0;
61} 66}
62 67
63struct inode *gfs2_ilookup(struct super_block *sb, struct gfs2_inum_host *inum) 68struct inode *gfs2_ilookup(struct super_block *sb, u64 no_addr)
69{
70 unsigned long hash = (unsigned long)no_addr;
71 return ilookup5(sb, hash, iget_test, &no_addr);
72}
73
74static struct inode *gfs2_iget(struct super_block *sb, u64 no_addr)
64{ 75{
65 return ilookup5(sb, (unsigned long)inum->no_addr, 76 unsigned long hash = (unsigned long)no_addr;
66 iget_test, inum); 77 return iget5_locked(sb, hash, iget_test, iget_set, &no_addr);
67} 78}
68 79
69static struct inode *gfs2_iget(struct super_block *sb, struct gfs2_inum_host *inum) 80/**
81 * GFS2 lookup code fills in vfs inode contents based on info obtained
82 * from directory entry inside gfs2_inode_lookup(). This has caused issues
83 * with NFS code path since its get_dentry routine doesn't have the relevant
84 * directory entry when gfs2_inode_lookup() is invoked. Part of the code
85 * segment inside gfs2_inode_lookup code needs to get moved around.
86 *
87 * Clean up I_LOCK and I_NEW as well.
88 **/
89
90void gfs2_set_iop(struct inode *inode)
70{ 91{
71 return iget5_locked(sb, (unsigned long)inum->no_addr, 92 umode_t mode = inode->i_mode;
72 iget_test, iget_set, inum); 93
94 if (S_ISREG(mode)) {
95 inode->i_op = &gfs2_file_iops;
96 inode->i_fop = &gfs2_file_fops;
97 inode->i_mapping->a_ops = &gfs2_file_aops;
98 } else if (S_ISDIR(mode)) {
99 inode->i_op = &gfs2_dir_iops;
100 inode->i_fop = &gfs2_dir_fops;
101 } else if (S_ISLNK(mode)) {
102 inode->i_op = &gfs2_symlink_iops;
103 } else {
104 inode->i_op = &gfs2_dev_iops;
105 }
106
107 unlock_new_inode(inode);
73} 108}
74 109
75/** 110/**
76 * gfs2_inode_lookup - Lookup an inode 111 * gfs2_inode_lookup - Lookup an inode
77 * @sb: The super block 112 * @sb: The super block
78 * @inum: The inode number 113 * @no_addr: The inode number
79 * @type: The type of the inode 114 * @type: The type of the inode
80 * 115 *
81 * Returns: A VFS inode, or an error 116 * Returns: A VFS inode, or an error
82 */ 117 */
83 118
84struct inode *gfs2_inode_lookup(struct super_block *sb, struct gfs2_inum_host *inum, unsigned int type) 119struct inode *gfs2_inode_lookup(struct super_block *sb,
120 unsigned int type,
121 u64 no_addr,
122 u64 no_formal_ino)
85{ 123{
86 struct inode *inode = gfs2_iget(sb, inum); 124 struct inode *inode = gfs2_iget(sb, no_addr);
87 struct gfs2_inode *ip = GFS2_I(inode); 125 struct gfs2_inode *ip = GFS2_I(inode);
88 struct gfs2_glock *io_gl; 126 struct gfs2_glock *io_gl;
89 int error; 127 int error;
@@ -93,29 +131,15 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, struct gfs2_inum_host *i
93 131
94 if (inode->i_state & I_NEW) { 132 if (inode->i_state & I_NEW) {
95 struct gfs2_sbd *sdp = GFS2_SB(inode); 133 struct gfs2_sbd *sdp = GFS2_SB(inode);
96 umode_t mode = DT2IF(type);
97 inode->i_private = ip; 134 inode->i_private = ip;
98 inode->i_mode = mode; 135 ip->i_no_formal_ino = no_formal_ino;
99
100 if (S_ISREG(mode)) {
101 inode->i_op = &gfs2_file_iops;
102 inode->i_fop = &gfs2_file_fops;
103 inode->i_mapping->a_ops = &gfs2_file_aops;
104 } else if (S_ISDIR(mode)) {
105 inode->i_op = &gfs2_dir_iops;
106 inode->i_fop = &gfs2_dir_fops;
107 } else if (S_ISLNK(mode)) {
108 inode->i_op = &gfs2_symlink_iops;
109 } else {
110 inode->i_op = &gfs2_dev_iops;
111 }
112 136
113 error = gfs2_glock_get(sdp, inum->no_addr, &gfs2_inode_glops, CREATE, &ip->i_gl); 137 error = gfs2_glock_get(sdp, no_addr, &gfs2_inode_glops, CREATE, &ip->i_gl);
114 if (unlikely(error)) 138 if (unlikely(error))
115 goto fail; 139 goto fail;
116 ip->i_gl->gl_object = ip; 140 ip->i_gl->gl_object = ip;
117 141
118 error = gfs2_glock_get(sdp, inum->no_addr, &gfs2_iopen_glops, CREATE, &io_gl); 142 error = gfs2_glock_get(sdp, no_addr, &gfs2_iopen_glops, CREATE, &io_gl);
119 if (unlikely(error)) 143 if (unlikely(error))
120 goto fail_put; 144 goto fail_put;
121 145
@@ -123,12 +147,38 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, struct gfs2_inum_host *i
123 error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, GL_EXACT, &ip->i_iopen_gh); 147 error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, GL_EXACT, &ip->i_iopen_gh);
124 if (unlikely(error)) 148 if (unlikely(error))
125 goto fail_iopen; 149 goto fail_iopen;
150 ip->i_iopen_gh.gh_gl->gl_object = ip;
126 151
127 gfs2_glock_put(io_gl); 152 gfs2_glock_put(io_gl);
128 unlock_new_inode(inode); 153
154 if ((type == DT_UNKNOWN) && (no_formal_ino == 0))
155 goto gfs2_nfsbypass;
156
157 inode->i_mode = DT2IF(type);
158
159 /*
160 * We must read the inode in order to work out its type in
161 * this case. Note that this doesn't happen often as we normally
162 * know the type beforehand. This code path only occurs during
163 * unlinked inode recovery (where it is safe to do this glock,
164 * which is not true in the general case).
165 */
166 if (type == DT_UNKNOWN) {
167 struct gfs2_holder gh;
168 error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh);
169 if (unlikely(error))
170 goto fail_glock;
171 /* Inode is now uptodate */
172 gfs2_glock_dq_uninit(&gh);
173 }
174
175 gfs2_set_iop(inode);
129 } 176 }
130 177
178gfs2_nfsbypass:
131 return inode; 179 return inode;
180fail_glock:
181 gfs2_glock_dq(&ip->i_iopen_gh);
132fail_iopen: 182fail_iopen:
133 gfs2_glock_put(io_gl); 183 gfs2_glock_put(io_gl);
134fail_put: 184fail_put:
@@ -144,14 +194,12 @@ static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf)
144 struct gfs2_dinode_host *di = &ip->i_di; 194 struct gfs2_dinode_host *di = &ip->i_di;
145 const struct gfs2_dinode *str = buf; 195 const struct gfs2_dinode *str = buf;
146 196
147 if (ip->i_num.no_addr != be64_to_cpu(str->di_num.no_addr)) { 197 if (ip->i_no_addr != be64_to_cpu(str->di_num.no_addr)) {
148 if (gfs2_consist_inode(ip)) 198 if (gfs2_consist_inode(ip))
149 gfs2_dinode_print(ip); 199 gfs2_dinode_print(ip);
150 return -EIO; 200 return -EIO;
151 } 201 }
152 if (ip->i_num.no_formal_ino != be64_to_cpu(str->di_num.no_formal_ino)) 202 ip->i_no_formal_ino = be64_to_cpu(str->di_num.no_formal_ino);
153 return -ESTALE;
154
155 ip->i_inode.i_mode = be32_to_cpu(str->di_mode); 203 ip->i_inode.i_mode = be32_to_cpu(str->di_mode);
156 ip->i_inode.i_rdev = 0; 204 ip->i_inode.i_rdev = 0;
157 switch (ip->i_inode.i_mode & S_IFMT) { 205 switch (ip->i_inode.i_mode & S_IFMT) {
@@ -175,11 +223,11 @@ static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf)
175 di->di_blocks = be64_to_cpu(str->di_blocks); 223 di->di_blocks = be64_to_cpu(str->di_blocks);
176 gfs2_set_inode_blocks(&ip->i_inode); 224 gfs2_set_inode_blocks(&ip->i_inode);
177 ip->i_inode.i_atime.tv_sec = be64_to_cpu(str->di_atime); 225 ip->i_inode.i_atime.tv_sec = be64_to_cpu(str->di_atime);
178 ip->i_inode.i_atime.tv_nsec = 0; 226 ip->i_inode.i_atime.tv_nsec = be32_to_cpu(str->di_atime_nsec);
179 ip->i_inode.i_mtime.tv_sec = be64_to_cpu(str->di_mtime); 227 ip->i_inode.i_mtime.tv_sec = be64_to_cpu(str->di_mtime);
180 ip->i_inode.i_mtime.tv_nsec = 0; 228 ip->i_inode.i_mtime.tv_nsec = be32_to_cpu(str->di_mtime_nsec);
181 ip->i_inode.i_ctime.tv_sec = be64_to_cpu(str->di_ctime); 229 ip->i_inode.i_ctime.tv_sec = be64_to_cpu(str->di_ctime);
182 ip->i_inode.i_ctime.tv_nsec = 0; 230 ip->i_inode.i_ctime.tv_nsec = be32_to_cpu(str->di_ctime_nsec);
183 231
184 di->di_goal_meta = be64_to_cpu(str->di_goal_meta); 232 di->di_goal_meta = be64_to_cpu(str->di_goal_meta);
185 di->di_goal_data = be64_to_cpu(str->di_goal_data); 233 di->di_goal_data = be64_to_cpu(str->di_goal_data);
@@ -247,7 +295,7 @@ int gfs2_dinode_dealloc(struct gfs2_inode *ip)
247 if (error) 295 if (error)
248 goto out_qs; 296 goto out_qs;
249 297
250 rgd = gfs2_blk2rgrpd(sdp, ip->i_num.no_addr); 298 rgd = gfs2_blk2rgrpd(sdp, ip->i_no_addr);
251 if (!rgd) { 299 if (!rgd) {
252 gfs2_consist_inode(ip); 300 gfs2_consist_inode(ip);
253 error = -EIO; 301 error = -EIO;
@@ -314,7 +362,7 @@ int gfs2_change_nlink(struct gfs2_inode *ip, int diff)
314 else 362 else
315 drop_nlink(&ip->i_inode); 363 drop_nlink(&ip->i_inode);
316 364
317 ip->i_inode.i_ctime = CURRENT_TIME_SEC; 365 ip->i_inode.i_ctime = CURRENT_TIME;
318 366
319 gfs2_trans_add_bh(ip->i_gl, dibh, 1); 367 gfs2_trans_add_bh(ip->i_gl, dibh, 1);
320 gfs2_dinode_out(ip, dibh->b_data); 368 gfs2_dinode_out(ip, dibh->b_data);
@@ -366,9 +414,7 @@ struct inode *gfs2_lookupi(struct inode *dir, const struct qstr *name,
366 struct super_block *sb = dir->i_sb; 414 struct super_block *sb = dir->i_sb;
367 struct gfs2_inode *dip = GFS2_I(dir); 415 struct gfs2_inode *dip = GFS2_I(dir);
368 struct gfs2_holder d_gh; 416 struct gfs2_holder d_gh;
369 struct gfs2_inum_host inum; 417 int error = 0;
370 unsigned int type;
371 int error;
372 struct inode *inode = NULL; 418 struct inode *inode = NULL;
373 int unlock = 0; 419 int unlock = 0;
374 420
@@ -395,12 +441,9 @@ struct inode *gfs2_lookupi(struct inode *dir, const struct qstr *name,
395 goto out; 441 goto out;
396 } 442 }
397 443
398 error = gfs2_dir_search(dir, name, &inum, &type); 444 inode = gfs2_dir_search(dir, name);
399 if (error) 445 if (IS_ERR(inode))
400 goto out; 446 error = PTR_ERR(inode);
401
402 inode = gfs2_inode_lookup(sb, &inum, type);
403
404out: 447out:
405 if (unlock) 448 if (unlock)
406 gfs2_glock_dq_uninit(&d_gh); 449 gfs2_glock_dq_uninit(&d_gh);
@@ -409,6 +452,22 @@ out:
409 return inode ? inode : ERR_PTR(error); 452 return inode ? inode : ERR_PTR(error);
410} 453}
411 454
455static void gfs2_inum_range_in(struct gfs2_inum_range_host *ir, const void *buf)
456{
457 const struct gfs2_inum_range *str = buf;
458
459 ir->ir_start = be64_to_cpu(str->ir_start);
460 ir->ir_length = be64_to_cpu(str->ir_length);
461}
462
463static void gfs2_inum_range_out(const struct gfs2_inum_range_host *ir, void *buf)
464{
465 struct gfs2_inum_range *str = buf;
466
467 str->ir_start = cpu_to_be64(ir->ir_start);
468 str->ir_length = cpu_to_be64(ir->ir_length);
469}
470
412static int pick_formal_ino_1(struct gfs2_sbd *sdp, u64 *formal_ino) 471static int pick_formal_ino_1(struct gfs2_sbd *sdp, u64 *formal_ino)
413{ 472{
414 struct gfs2_inode *ip = GFS2_I(sdp->sd_ir_inode); 473 struct gfs2_inode *ip = GFS2_I(sdp->sd_ir_inode);
@@ -548,7 +607,7 @@ static int create_ok(struct gfs2_inode *dip, const struct qstr *name,
548 if (!dip->i_inode.i_nlink) 607 if (!dip->i_inode.i_nlink)
549 return -EPERM; 608 return -EPERM;
550 609
551 error = gfs2_dir_search(&dip->i_inode, name, NULL, NULL); 610 error = gfs2_dir_check(&dip->i_inode, name, NULL);
552 switch (error) { 611 switch (error) {
553 case -ENOENT: 612 case -ENOENT:
554 error = 0; 613 error = 0;
@@ -588,8 +647,7 @@ static void munge_mode_uid_gid(struct gfs2_inode *dip, unsigned int *mode,
588 *gid = current->fsgid; 647 *gid = current->fsgid;
589} 648}
590 649
591static int alloc_dinode(struct gfs2_inode *dip, struct gfs2_inum_host *inum, 650static int alloc_dinode(struct gfs2_inode *dip, u64 *no_addr, u64 *generation)
592 u64 *generation)
593{ 651{
594 struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); 652 struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
595 int error; 653 int error;
@@ -605,7 +663,7 @@ static int alloc_dinode(struct gfs2_inode *dip, struct gfs2_inum_host *inum,
605 if (error) 663 if (error)
606 goto out_ipreserv; 664 goto out_ipreserv;
607 665
608 inum->no_addr = gfs2_alloc_di(dip, generation); 666 *no_addr = gfs2_alloc_di(dip, generation);
609 667
610 gfs2_trans_end(sdp); 668 gfs2_trans_end(sdp);
611 669
@@ -635,6 +693,7 @@ static void init_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl,
635 struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); 693 struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
636 struct gfs2_dinode *di; 694 struct gfs2_dinode *di;
637 struct buffer_head *dibh; 695 struct buffer_head *dibh;
696 struct timespec tv = CURRENT_TIME;
638 697
639 dibh = gfs2_meta_new(gl, inum->no_addr); 698 dibh = gfs2_meta_new(gl, inum->no_addr);
640 gfs2_trans_add_bh(gl, dibh, 1); 699 gfs2_trans_add_bh(gl, dibh, 1);
@@ -650,7 +709,7 @@ static void init_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl,
650 di->di_nlink = 0; 709 di->di_nlink = 0;
651 di->di_size = 0; 710 di->di_size = 0;
652 di->di_blocks = cpu_to_be64(1); 711 di->di_blocks = cpu_to_be64(1);
653 di->di_atime = di->di_mtime = di->di_ctime = cpu_to_be64(get_seconds()); 712 di->di_atime = di->di_mtime = di->di_ctime = cpu_to_be64(tv.tv_sec);
654 di->di_major = cpu_to_be32(MAJOR(dev)); 713 di->di_major = cpu_to_be32(MAJOR(dev));
655 di->di_minor = cpu_to_be32(MINOR(dev)); 714 di->di_minor = cpu_to_be32(MINOR(dev));
656 di->di_goal_meta = di->di_goal_data = cpu_to_be64(inum->no_addr); 715 di->di_goal_meta = di->di_goal_data = cpu_to_be64(inum->no_addr);
@@ -680,6 +739,9 @@ static void init_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl,
680 di->di_entries = 0; 739 di->di_entries = 0;
681 memset(&di->__pad4, 0, sizeof(di->__pad4)); 740 memset(&di->__pad4, 0, sizeof(di->__pad4));
682 di->di_eattr = 0; 741 di->di_eattr = 0;
742 di->di_atime_nsec = cpu_to_be32(tv.tv_nsec);
743 di->di_mtime_nsec = cpu_to_be32(tv.tv_nsec);
744 di->di_ctime_nsec = cpu_to_be32(tv.tv_nsec);
683 memset(&di->di_reserved, 0, sizeof(di->di_reserved)); 745 memset(&di->di_reserved, 0, sizeof(di->di_reserved));
684 746
685 brelse(dibh); 747 brelse(dibh);
@@ -749,7 +811,7 @@ static int link_dinode(struct gfs2_inode *dip, const struct qstr *name,
749 goto fail_quota_locks; 811 goto fail_quota_locks;
750 812
751 error = gfs2_trans_begin(sdp, sdp->sd_max_dirres + 813 error = gfs2_trans_begin(sdp, sdp->sd_max_dirres +
752 al->al_rgd->rd_ri.ri_length + 814 al->al_rgd->rd_length +
753 2 * RES_DINODE + 815 2 * RES_DINODE +
754 RES_STATFS + RES_QUOTA, 0); 816 RES_STATFS + RES_QUOTA, 0);
755 if (error) 817 if (error)
@@ -760,7 +822,7 @@ static int link_dinode(struct gfs2_inode *dip, const struct qstr *name,
760 goto fail_quota_locks; 822 goto fail_quota_locks;
761 } 823 }
762 824
763 error = gfs2_dir_add(&dip->i_inode, name, &ip->i_num, IF2DT(ip->i_inode.i_mode)); 825 error = gfs2_dir_add(&dip->i_inode, name, ip, IF2DT(ip->i_inode.i_mode));
764 if (error) 826 if (error)
765 goto fail_end_trans; 827 goto fail_end_trans;
766 828
@@ -840,11 +902,11 @@ static int gfs2_security_init(struct gfs2_inode *dip, struct gfs2_inode *ip)
840struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name, 902struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name,
841 unsigned int mode, dev_t dev) 903 unsigned int mode, dev_t dev)
842{ 904{
843 struct inode *inode; 905 struct inode *inode = NULL;
844 struct gfs2_inode *dip = ghs->gh_gl->gl_object; 906 struct gfs2_inode *dip = ghs->gh_gl->gl_object;
845 struct inode *dir = &dip->i_inode; 907 struct inode *dir = &dip->i_inode;
846 struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); 908 struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
847 struct gfs2_inum_host inum; 909 struct gfs2_inum_host inum = { .no_addr = 0, .no_formal_ino = 0 };
848 int error; 910 int error;
849 u64 generation; 911 u64 generation;
850 912
@@ -864,7 +926,7 @@ struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name,
864 if (error) 926 if (error)
865 goto fail_gunlock; 927 goto fail_gunlock;
866 928
867 error = alloc_dinode(dip, &inum, &generation); 929 error = alloc_dinode(dip, &inum.no_addr, &generation);
868 if (error) 930 if (error)
869 goto fail_gunlock; 931 goto fail_gunlock;
870 932
@@ -877,34 +939,36 @@ struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name,
877 if (error) 939 if (error)
878 goto fail_gunlock2; 940 goto fail_gunlock2;
879 941
880 inode = gfs2_inode_lookup(dir->i_sb, &inum, IF2DT(mode)); 942 inode = gfs2_inode_lookup(dir->i_sb, IF2DT(mode),
943 inum.no_addr,
944 inum.no_formal_ino);
881 if (IS_ERR(inode)) 945 if (IS_ERR(inode))
882 goto fail_gunlock2; 946 goto fail_gunlock2;
883 947
884 error = gfs2_inode_refresh(GFS2_I(inode)); 948 error = gfs2_inode_refresh(GFS2_I(inode));
885 if (error) 949 if (error)
886 goto fail_iput; 950 goto fail_gunlock2;
887 951
888 error = gfs2_acl_create(dip, GFS2_I(inode)); 952 error = gfs2_acl_create(dip, GFS2_I(inode));
889 if (error) 953 if (error)
890 goto fail_iput; 954 goto fail_gunlock2;
891 955
892 error = gfs2_security_init(dip, GFS2_I(inode)); 956 error = gfs2_security_init(dip, GFS2_I(inode));
893 if (error) 957 if (error)
894 goto fail_iput; 958 goto fail_gunlock2;
895 959
896 error = link_dinode(dip, name, GFS2_I(inode)); 960 error = link_dinode(dip, name, GFS2_I(inode));
897 if (error) 961 if (error)
898 goto fail_iput; 962 goto fail_gunlock2;
899 963
900 if (!inode) 964 if (!inode)
901 return ERR_PTR(-ENOMEM); 965 return ERR_PTR(-ENOMEM);
902 return inode; 966 return inode;
903 967
904fail_iput:
905 iput(inode);
906fail_gunlock2: 968fail_gunlock2:
907 gfs2_glock_dq_uninit(ghs + 1); 969 gfs2_glock_dq_uninit(ghs + 1);
970 if (inode)
971 iput(inode);
908fail_gunlock: 972fail_gunlock:
909 gfs2_glock_dq(ghs); 973 gfs2_glock_dq(ghs);
910fail: 974fail:
@@ -976,10 +1040,8 @@ int gfs2_rmdiri(struct gfs2_inode *dip, const struct qstr *name,
976 */ 1040 */
977 1041
978int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name, 1042int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name,
979 struct gfs2_inode *ip) 1043 const struct gfs2_inode *ip)
980{ 1044{
981 struct gfs2_inum_host inum;
982 unsigned int type;
983 int error; 1045 int error;
984 1046
985 if (IS_IMMUTABLE(&ip->i_inode) || IS_APPEND(&ip->i_inode)) 1047 if (IS_IMMUTABLE(&ip->i_inode) || IS_APPEND(&ip->i_inode))
@@ -997,18 +1059,10 @@ int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name,
997 if (error) 1059 if (error)
998 return error; 1060 return error;
999 1061
1000 error = gfs2_dir_search(&dip->i_inode, name, &inum, &type); 1062 error = gfs2_dir_check(&dip->i_inode, name, ip);
1001 if (error) 1063 if (error)
1002 return error; 1064 return error;
1003 1065
1004 if (!gfs2_inum_equal(&inum, &ip->i_num))
1005 return -ENOENT;
1006
1007 if (IF2DT(ip->i_inode.i_mode) != type) {
1008 gfs2_consist_inode(dip);
1009 return -EIO;
1010 }
1011
1012 return 0; 1066 return 0;
1013} 1067}
1014 1068
@@ -1132,10 +1186,11 @@ int gfs2_glock_nq_atime(struct gfs2_holder *gh)
1132 struct gfs2_glock *gl = gh->gh_gl; 1186 struct gfs2_glock *gl = gh->gh_gl;
1133 struct gfs2_sbd *sdp = gl->gl_sbd; 1187 struct gfs2_sbd *sdp = gl->gl_sbd;
1134 struct gfs2_inode *ip = gl->gl_object; 1188 struct gfs2_inode *ip = gl->gl_object;
1135 s64 curtime, quantum = gfs2_tune_get(sdp, gt_atime_quantum); 1189 s64 quantum = gfs2_tune_get(sdp, gt_atime_quantum);
1136 unsigned int state; 1190 unsigned int state;
1137 int flags; 1191 int flags;
1138 int error; 1192 int error;
1193 struct timespec tv = CURRENT_TIME;
1139 1194
1140 if (gfs2_assert_warn(sdp, gh->gh_flags & GL_ATIME) || 1195 if (gfs2_assert_warn(sdp, gh->gh_flags & GL_ATIME) ||
1141 gfs2_assert_warn(sdp, !(gh->gh_flags & GL_ASYNC)) || 1196 gfs2_assert_warn(sdp, !(gh->gh_flags & GL_ASYNC)) ||
@@ -1153,8 +1208,7 @@ int gfs2_glock_nq_atime(struct gfs2_holder *gh)
1153 (sdp->sd_vfs->s_flags & MS_RDONLY)) 1208 (sdp->sd_vfs->s_flags & MS_RDONLY))
1154 return 0; 1209 return 0;
1155 1210
1156 curtime = get_seconds(); 1211 if (tv.tv_sec - ip->i_inode.i_atime.tv_sec >= quantum) {
1157 if (curtime - ip->i_inode.i_atime.tv_sec >= quantum) {
1158 gfs2_glock_dq(gh); 1212 gfs2_glock_dq(gh);
1159 gfs2_holder_reinit(LM_ST_EXCLUSIVE, gh->gh_flags & ~LM_FLAG_ANY, 1213 gfs2_holder_reinit(LM_ST_EXCLUSIVE, gh->gh_flags & ~LM_FLAG_ANY,
1160 gh); 1214 gh);
@@ -1165,8 +1219,8 @@ int gfs2_glock_nq_atime(struct gfs2_holder *gh)
1165 /* Verify that atime hasn't been updated while we were 1219 /* Verify that atime hasn't been updated while we were
1166 trying to get exclusive lock. */ 1220 trying to get exclusive lock. */
1167 1221
1168 curtime = get_seconds(); 1222 tv = CURRENT_TIME;
1169 if (curtime - ip->i_inode.i_atime.tv_sec >= quantum) { 1223 if (tv.tv_sec - ip->i_inode.i_atime.tv_sec >= quantum) {
1170 struct buffer_head *dibh; 1224 struct buffer_head *dibh;
1171 struct gfs2_dinode *di; 1225 struct gfs2_dinode *di;
1172 1226
@@ -1180,11 +1234,12 @@ int gfs2_glock_nq_atime(struct gfs2_holder *gh)
1180 if (error) 1234 if (error)
1181 goto fail_end_trans; 1235 goto fail_end_trans;
1182 1236
1183 ip->i_inode.i_atime.tv_sec = curtime; 1237 ip->i_inode.i_atime = tv;
1184 1238
1185 gfs2_trans_add_bh(ip->i_gl, dibh, 1); 1239 gfs2_trans_add_bh(ip->i_gl, dibh, 1);
1186 di = (struct gfs2_dinode *)dibh->b_data; 1240 di = (struct gfs2_dinode *)dibh->b_data;
1187 di->di_atime = cpu_to_be64(ip->i_inode.i_atime.tv_sec); 1241 di->di_atime = cpu_to_be64(ip->i_inode.i_atime.tv_sec);
1242 di->di_atime_nsec = cpu_to_be32(ip->i_inode.i_atime.tv_nsec);
1188 brelse(dibh); 1243 brelse(dibh);
1189 1244
1190 gfs2_trans_end(sdp); 1245 gfs2_trans_end(sdp);
@@ -1252,3 +1307,66 @@ int gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr)
1252 return error; 1307 return error;
1253} 1308}
1254 1309
1310void gfs2_dinode_out(const struct gfs2_inode *ip, void *buf)
1311{
1312 const struct gfs2_dinode_host *di = &ip->i_di;
1313 struct gfs2_dinode *str = buf;
1314
1315 str->di_header.mh_magic = cpu_to_be32(GFS2_MAGIC);
1316 str->di_header.mh_type = cpu_to_be32(GFS2_METATYPE_DI);
1317 str->di_header.__pad0 = 0;
1318 str->di_header.mh_format = cpu_to_be32(GFS2_FORMAT_DI);
1319 str->di_header.__pad1 = 0;
1320 str->di_num.no_addr = cpu_to_be64(ip->i_no_addr);
1321 str->di_num.no_formal_ino = cpu_to_be64(ip->i_no_formal_ino);
1322 str->di_mode = cpu_to_be32(ip->i_inode.i_mode);
1323 str->di_uid = cpu_to_be32(ip->i_inode.i_uid);
1324 str->di_gid = cpu_to_be32(ip->i_inode.i_gid);
1325 str->di_nlink = cpu_to_be32(ip->i_inode.i_nlink);
1326 str->di_size = cpu_to_be64(di->di_size);
1327 str->di_blocks = cpu_to_be64(di->di_blocks);
1328 str->di_atime = cpu_to_be64(ip->i_inode.i_atime.tv_sec);
1329 str->di_mtime = cpu_to_be64(ip->i_inode.i_mtime.tv_sec);
1330 str->di_ctime = cpu_to_be64(ip->i_inode.i_ctime.tv_sec);
1331
1332 str->di_goal_meta = cpu_to_be64(di->di_goal_meta);
1333 str->di_goal_data = cpu_to_be64(di->di_goal_data);
1334 str->di_generation = cpu_to_be64(di->di_generation);
1335
1336 str->di_flags = cpu_to_be32(di->di_flags);
1337 str->di_height = cpu_to_be16(di->di_height);
1338 str->di_payload_format = cpu_to_be32(S_ISDIR(ip->i_inode.i_mode) &&
1339 !(ip->i_di.di_flags & GFS2_DIF_EXHASH) ?
1340 GFS2_FORMAT_DE : 0);
1341 str->di_depth = cpu_to_be16(di->di_depth);
1342 str->di_entries = cpu_to_be32(di->di_entries);
1343
1344 str->di_eattr = cpu_to_be64(di->di_eattr);
1345 str->di_atime_nsec = cpu_to_be32(ip->i_inode.i_atime.tv_nsec);
1346 str->di_mtime_nsec = cpu_to_be32(ip->i_inode.i_mtime.tv_nsec);
1347 str->di_ctime_nsec = cpu_to_be32(ip->i_inode.i_ctime.tv_nsec);
1348}
1349
1350void gfs2_dinode_print(const struct gfs2_inode *ip)
1351{
1352 const struct gfs2_dinode_host *di = &ip->i_di;
1353
1354 printk(KERN_INFO " no_formal_ino = %llu\n",
1355 (unsigned long long)ip->i_no_formal_ino);
1356 printk(KERN_INFO " no_addr = %llu\n",
1357 (unsigned long long)ip->i_no_addr);
1358 printk(KERN_INFO " di_size = %llu\n", (unsigned long long)di->di_size);
1359 printk(KERN_INFO " di_blocks = %llu\n",
1360 (unsigned long long)di->di_blocks);
1361 printk(KERN_INFO " di_goal_meta = %llu\n",
1362 (unsigned long long)di->di_goal_meta);
1363 printk(KERN_INFO " di_goal_data = %llu\n",
1364 (unsigned long long)di->di_goal_data);
1365 printk(KERN_INFO " di_flags = 0x%.8X\n", di->di_flags);
1366 printk(KERN_INFO " di_height = %u\n", di->di_height);
1367 printk(KERN_INFO " di_depth = %u\n", di->di_depth);
1368 printk(KERN_INFO " di_entries = %u\n", di->di_entries);
1369 printk(KERN_INFO " di_eattr = %llu\n",
1370 (unsigned long long)di->di_eattr);
1371}
1372
diff --git a/fs/gfs2/inode.h b/fs/gfs2/inode.h
index b57f448b15bc..4517ac82c01c 100644
--- a/fs/gfs2/inode.h
+++ b/fs/gfs2/inode.h
@@ -10,17 +10,17 @@
10#ifndef __INODE_DOT_H__ 10#ifndef __INODE_DOT_H__
11#define __INODE_DOT_H__ 11#define __INODE_DOT_H__
12 12
13static inline int gfs2_is_stuffed(struct gfs2_inode *ip) 13static inline int gfs2_is_stuffed(const struct gfs2_inode *ip)
14{ 14{
15 return !ip->i_di.di_height; 15 return !ip->i_di.di_height;
16} 16}
17 17
18static inline int gfs2_is_jdata(struct gfs2_inode *ip) 18static inline int gfs2_is_jdata(const struct gfs2_inode *ip)
19{ 19{
20 return ip->i_di.di_flags & GFS2_DIF_JDATA; 20 return ip->i_di.di_flags & GFS2_DIF_JDATA;
21} 21}
22 22
23static inline int gfs2_is_dir(struct gfs2_inode *ip) 23static inline int gfs2_is_dir(const struct gfs2_inode *ip)
24{ 24{
25 return S_ISDIR(ip->i_inode.i_mode); 25 return S_ISDIR(ip->i_inode.i_mode);
26} 26}
@@ -32,9 +32,25 @@ static inline void gfs2_set_inode_blocks(struct inode *inode)
32 (GFS2_SB(inode)->sd_sb.sb_bsize_shift - GFS2_BASIC_BLOCK_SHIFT); 32 (GFS2_SB(inode)->sd_sb.sb_bsize_shift - GFS2_BASIC_BLOCK_SHIFT);
33} 33}
34 34
35static inline int gfs2_check_inum(const struct gfs2_inode *ip, u64 no_addr,
36 u64 no_formal_ino)
37{
38 return ip->i_no_addr == no_addr && ip->i_no_formal_ino == no_formal_ino;
39}
40
41static inline void gfs2_inum_out(const struct gfs2_inode *ip,
42 struct gfs2_dirent *dent)
43{
44 dent->de_inum.no_formal_ino = cpu_to_be64(ip->i_no_formal_ino);
45 dent->de_inum.no_addr = cpu_to_be64(ip->i_no_addr);
46}
47
48
35void gfs2_inode_attr_in(struct gfs2_inode *ip); 49void gfs2_inode_attr_in(struct gfs2_inode *ip);
36struct inode *gfs2_inode_lookup(struct super_block *sb, struct gfs2_inum_host *inum, unsigned type); 50void gfs2_set_iop(struct inode *inode);
37struct inode *gfs2_ilookup(struct super_block *sb, struct gfs2_inum_host *inum); 51struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned type,
52 u64 no_addr, u64 no_formal_ino);
53struct inode *gfs2_ilookup(struct super_block *sb, u64 no_addr);
38 54
39int gfs2_inode_refresh(struct gfs2_inode *ip); 55int gfs2_inode_refresh(struct gfs2_inode *ip);
40 56
@@ -47,12 +63,14 @@ struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name,
47int gfs2_rmdiri(struct gfs2_inode *dip, const struct qstr *name, 63int gfs2_rmdiri(struct gfs2_inode *dip, const struct qstr *name,
48 struct gfs2_inode *ip); 64 struct gfs2_inode *ip);
49int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name, 65int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name,
50 struct gfs2_inode *ip); 66 const struct gfs2_inode *ip);
51int gfs2_ok_to_move(struct gfs2_inode *this, struct gfs2_inode *to); 67int gfs2_ok_to_move(struct gfs2_inode *this, struct gfs2_inode *to);
52int gfs2_readlinki(struct gfs2_inode *ip, char **buf, unsigned int *len); 68int gfs2_readlinki(struct gfs2_inode *ip, char **buf, unsigned int *len);
53int gfs2_glock_nq_atime(struct gfs2_holder *gh); 69int gfs2_glock_nq_atime(struct gfs2_holder *gh);
54int gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr); 70int gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr);
55struct inode *gfs2_lookup_simple(struct inode *dip, const char *name); 71struct inode *gfs2_lookup_simple(struct inode *dip, const char *name);
72void gfs2_dinode_out(const struct gfs2_inode *ip, void *buf);
73void gfs2_dinode_print(const struct gfs2_inode *ip);
56 74
57#endif /* __INODE_DOT_H__ */ 75#endif /* __INODE_DOT_H__ */
58 76
diff --git a/fs/gfs2/locking/dlm/lock.c b/fs/gfs2/locking/dlm/lock.c
index c305255bfe8a..542a797ac89a 100644
--- a/fs/gfs2/locking/dlm/lock.c
+++ b/fs/gfs2/locking/dlm/lock.c
@@ -174,7 +174,6 @@ static int gdlm_create_lp(struct gdlm_ls *ls, struct lm_lockname *name,
174 lp->cur = DLM_LOCK_IV; 174 lp->cur = DLM_LOCK_IV;
175 lp->lvb = NULL; 175 lp->lvb = NULL;
176 lp->hold_null = NULL; 176 lp->hold_null = NULL;
177 init_completion(&lp->ast_wait);
178 INIT_LIST_HEAD(&lp->clist); 177 INIT_LIST_HEAD(&lp->clist);
179 INIT_LIST_HEAD(&lp->blist); 178 INIT_LIST_HEAD(&lp->blist);
180 INIT_LIST_HEAD(&lp->delay_list); 179 INIT_LIST_HEAD(&lp->delay_list);
@@ -399,6 +398,12 @@ static void gdlm_del_lvb(struct gdlm_lock *lp)
399 lp->lksb.sb_lvbptr = NULL; 398 lp->lksb.sb_lvbptr = NULL;
400} 399}
401 400
401static int gdlm_ast_wait(void *word)
402{
403 schedule();
404 return 0;
405}
406
402/* This can do a synchronous dlm request (requiring a lock_dlm thread to get 407/* This can do a synchronous dlm request (requiring a lock_dlm thread to get
403 the completion) because gfs won't call hold_lvb() during a callback (from 408 the completion) because gfs won't call hold_lvb() during a callback (from
404 the context of a lock_dlm thread). */ 409 the context of a lock_dlm thread). */
@@ -424,10 +429,10 @@ static int hold_null_lock(struct gdlm_lock *lp)
424 lpn->lkf = DLM_LKF_VALBLK | DLM_LKF_EXPEDITE; 429 lpn->lkf = DLM_LKF_VALBLK | DLM_LKF_EXPEDITE;
425 set_bit(LFL_NOBAST, &lpn->flags); 430 set_bit(LFL_NOBAST, &lpn->flags);
426 set_bit(LFL_INLOCK, &lpn->flags); 431 set_bit(LFL_INLOCK, &lpn->flags);
432 set_bit(LFL_AST_WAIT, &lpn->flags);
427 433
428 init_completion(&lpn->ast_wait);
429 gdlm_do_lock(lpn); 434 gdlm_do_lock(lpn);
430 wait_for_completion(&lpn->ast_wait); 435 wait_on_bit(&lpn->flags, LFL_AST_WAIT, gdlm_ast_wait, TASK_UNINTERRUPTIBLE);
431 error = lpn->lksb.sb_status; 436 error = lpn->lksb.sb_status;
432 if (error) { 437 if (error) {
433 printk(KERN_INFO "lock_dlm: hold_null_lock dlm error %d\n", 438 printk(KERN_INFO "lock_dlm: hold_null_lock dlm error %d\n",
diff --git a/fs/gfs2/locking/dlm/lock_dlm.h b/fs/gfs2/locking/dlm/lock_dlm.h
index d074c6e6f9bf..24d70f73b651 100644
--- a/fs/gfs2/locking/dlm/lock_dlm.h
+++ b/fs/gfs2/locking/dlm/lock_dlm.h
@@ -101,6 +101,7 @@ enum {
101 LFL_NOBAST = 10, 101 LFL_NOBAST = 10,
102 LFL_HEADQUE = 11, 102 LFL_HEADQUE = 11,
103 LFL_UNLOCK_DELETE = 12, 103 LFL_UNLOCK_DELETE = 12,
104 LFL_AST_WAIT = 13,
104}; 105};
105 106
106struct gdlm_lock { 107struct gdlm_lock {
@@ -117,7 +118,6 @@ struct gdlm_lock {
117 unsigned long flags; /* lock_dlm flags LFL_ */ 118 unsigned long flags; /* lock_dlm flags LFL_ */
118 119
119 int bast_mode; /* protected by async_lock */ 120 int bast_mode; /* protected by async_lock */
120 struct completion ast_wait;
121 121
122 struct list_head clist; /* complete */ 122 struct list_head clist; /* complete */
123 struct list_head blist; /* blocking */ 123 struct list_head blist; /* blocking */
diff --git a/fs/gfs2/locking/dlm/mount.c b/fs/gfs2/locking/dlm/mount.c
index 1d8faa3da8af..41c5b04caaba 100644
--- a/fs/gfs2/locking/dlm/mount.c
+++ b/fs/gfs2/locking/dlm/mount.c
@@ -147,7 +147,7 @@ static int gdlm_mount(char *table_name, char *host_data,
147 147
148 error = dlm_new_lockspace(ls->fsname, strlen(ls->fsname), 148 error = dlm_new_lockspace(ls->fsname, strlen(ls->fsname),
149 &ls->dlm_lockspace, 149 &ls->dlm_lockspace,
150 nodir ? DLM_LSFL_NODIR : 0, 150 DLM_LSFL_FS | (nodir ? DLM_LSFL_NODIR : 0),
151 GDLM_LVB_SIZE); 151 GDLM_LVB_SIZE);
152 if (error) { 152 if (error) {
153 log_error("dlm_new_lockspace error %d", error); 153 log_error("dlm_new_lockspace error %d", error);
diff --git a/fs/gfs2/locking/dlm/plock.c b/fs/gfs2/locking/dlm/plock.c
index f82495e18c2d..fba1f1d87e4f 100644
--- a/fs/gfs2/locking/dlm/plock.c
+++ b/fs/gfs2/locking/dlm/plock.c
@@ -242,7 +242,7 @@ int gdlm_plock_get(void *lockspace, struct lm_lockname *name,
242 op->info.number = name->ln_number; 242 op->info.number = name->ln_number;
243 op->info.start = fl->fl_start; 243 op->info.start = fl->fl_start;
244 op->info.end = fl->fl_end; 244 op->info.end = fl->fl_end;
245 245 op->info.owner = (__u64)(long) fl->fl_owner;
246 246
247 send_op(op); 247 send_op(op);
248 wait_event(recv_wq, (op->done != 0)); 248 wait_event(recv_wq, (op->done != 0));
@@ -254,16 +254,20 @@ int gdlm_plock_get(void *lockspace, struct lm_lockname *name,
254 } 254 }
255 spin_unlock(&ops_lock); 255 spin_unlock(&ops_lock);
256 256
257 /* info.rv from userspace is 1 for conflict, 0 for no-conflict,
258 -ENOENT if there are no locks on the file */
259
257 rv = op->info.rv; 260 rv = op->info.rv;
258 261
259 fl->fl_type = F_UNLCK; 262 fl->fl_type = F_UNLCK;
260 if (rv == -ENOENT) 263 if (rv == -ENOENT)
261 rv = 0; 264 rv = 0;
262 else if (rv == 0 && op->info.pid != fl->fl_pid) { 265 else if (rv > 0) {
263 fl->fl_type = (op->info.ex) ? F_WRLCK : F_RDLCK; 266 fl->fl_type = (op->info.ex) ? F_WRLCK : F_RDLCK;
264 fl->fl_pid = op->info.pid; 267 fl->fl_pid = op->info.pid;
265 fl->fl_start = op->info.start; 268 fl->fl_start = op->info.start;
266 fl->fl_end = op->info.end; 269 fl->fl_end = op->info.end;
270 rv = 0;
267 } 271 }
268 272
269 kfree(op); 273 kfree(op);
diff --git a/fs/gfs2/locking/dlm/thread.c b/fs/gfs2/locking/dlm/thread.c
index 9cf1f168eaf8..1aca51e45092 100644
--- a/fs/gfs2/locking/dlm/thread.c
+++ b/fs/gfs2/locking/dlm/thread.c
@@ -44,6 +44,13 @@ static void process_blocking(struct gdlm_lock *lp, int bast_mode)
44 ls->fscb(ls->sdp, cb, &lp->lockname); 44 ls->fscb(ls->sdp, cb, &lp->lockname);
45} 45}
46 46
47static void wake_up_ast(struct gdlm_lock *lp)
48{
49 clear_bit(LFL_AST_WAIT, &lp->flags);
50 smp_mb__after_clear_bit();
51 wake_up_bit(&lp->flags, LFL_AST_WAIT);
52}
53
47static void process_complete(struct gdlm_lock *lp) 54static void process_complete(struct gdlm_lock *lp)
48{ 55{
49 struct gdlm_ls *ls = lp->ls; 56 struct gdlm_ls *ls = lp->ls;
@@ -136,7 +143,7 @@ static void process_complete(struct gdlm_lock *lp)
136 */ 143 */
137 144
138 if (test_and_clear_bit(LFL_SYNC_LVB, &lp->flags)) { 145 if (test_and_clear_bit(LFL_SYNC_LVB, &lp->flags)) {
139 complete(&lp->ast_wait); 146 wake_up_ast(lp);
140 return; 147 return;
141 } 148 }
142 149
@@ -214,7 +221,7 @@ out:
214 if (test_bit(LFL_INLOCK, &lp->flags)) { 221 if (test_bit(LFL_INLOCK, &lp->flags)) {
215 clear_bit(LFL_NOBLOCK, &lp->flags); 222 clear_bit(LFL_NOBLOCK, &lp->flags);
216 lp->cur = lp->req; 223 lp->cur = lp->req;
217 complete(&lp->ast_wait); 224 wake_up_ast(lp);
218 return; 225 return;
219 } 226 }
220 227
diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c
index 291415ddfe51..f49a12e24086 100644
--- a/fs/gfs2/log.c
+++ b/fs/gfs2/log.c
@@ -83,6 +83,11 @@ static void gfs2_ail1_start_one(struct gfs2_sbd *sdp, struct gfs2_ail *ai)
83 83
84 gfs2_assert(sdp, bd->bd_ail == ai); 84 gfs2_assert(sdp, bd->bd_ail == ai);
85 85
86 if (!bh){
87 list_move(&bd->bd_ail_st_list, &ai->ai_ail2_list);
88 continue;
89 }
90
86 if (!buffer_busy(bh)) { 91 if (!buffer_busy(bh)) {
87 if (!buffer_uptodate(bh)) { 92 if (!buffer_uptodate(bh)) {
88 gfs2_log_unlock(sdp); 93 gfs2_log_unlock(sdp);
@@ -125,6 +130,11 @@ static int gfs2_ail1_empty_one(struct gfs2_sbd *sdp, struct gfs2_ail *ai, int fl
125 bd_ail_st_list) { 130 bd_ail_st_list) {
126 bh = bd->bd_bh; 131 bh = bd->bd_bh;
127 132
133 if (!bh){
134 list_move(&bd->bd_ail_st_list, &ai->ai_ail2_list);
135 continue;
136 }
137
128 gfs2_assert(sdp, bd->bd_ail == ai); 138 gfs2_assert(sdp, bd->bd_ail == ai);
129 139
130 if (buffer_busy(bh)) { 140 if (buffer_busy(bh)) {
@@ -262,8 +272,8 @@ static void ail2_empty(struct gfs2_sbd *sdp, unsigned int new_tail)
262 * @sdp: The GFS2 superblock 272 * @sdp: The GFS2 superblock
263 * @blks: The number of blocks to reserve 273 * @blks: The number of blocks to reserve
264 * 274 *
265 * Note that we never give out the last 6 blocks of the journal. Thats 275 * Note that we never give out the last few blocks of the journal. Thats
266 * due to the fact that there is are a small number of header blocks 276 * due to the fact that there is a small number of header blocks
267 * associated with each log flush. The exact number can't be known until 277 * associated with each log flush. The exact number can't be known until
268 * flush time, so we ensure that we have just enough free blocks at all 278 * flush time, so we ensure that we have just enough free blocks at all
269 * times to avoid running out during a log flush. 279 * times to avoid running out during a log flush.
@@ -274,6 +284,7 @@ static void ail2_empty(struct gfs2_sbd *sdp, unsigned int new_tail)
274int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks) 284int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks)
275{ 285{
276 unsigned int try = 0; 286 unsigned int try = 0;
287 unsigned reserved_blks = 6 * (4096 / sdp->sd_vfs->s_blocksize);
277 288
278 if (gfs2_assert_warn(sdp, blks) || 289 if (gfs2_assert_warn(sdp, blks) ||
279 gfs2_assert_warn(sdp, blks <= sdp->sd_jdesc->jd_blocks)) 290 gfs2_assert_warn(sdp, blks <= sdp->sd_jdesc->jd_blocks))
@@ -281,7 +292,7 @@ int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks)
281 292
282 mutex_lock(&sdp->sd_log_reserve_mutex); 293 mutex_lock(&sdp->sd_log_reserve_mutex);
283 gfs2_log_lock(sdp); 294 gfs2_log_lock(sdp);
284 while(sdp->sd_log_blks_free <= (blks + 6)) { 295 while(sdp->sd_log_blks_free <= (blks + reserved_blks)) {
285 gfs2_log_unlock(sdp); 296 gfs2_log_unlock(sdp);
286 gfs2_ail1_empty(sdp, 0); 297 gfs2_ail1_empty(sdp, 0);
287 gfs2_log_flush(sdp, NULL); 298 gfs2_log_flush(sdp, NULL);
@@ -357,6 +368,58 @@ static inline unsigned int log_distance(struct gfs2_sbd *sdp, unsigned int newer
357 return dist; 368 return dist;
358} 369}
359 370
371/**
372 * calc_reserved - Calculate the number of blocks to reserve when
373 * refunding a transaction's unused buffers.
374 * @sdp: The GFS2 superblock
375 *
376 * This is complex. We need to reserve room for all our currently used
377 * metadata buffers (e.g. normal file I/O rewriting file time stamps) and
378 * all our journaled data buffers for journaled files (e.g. files in the
379 * meta_fs like rindex, or files for which chattr +j was done.)
380 * If we don't reserve enough space, gfs2_log_refund and gfs2_log_flush
381 * will count it as free space (sd_log_blks_free) and corruption will follow.
382 *
383 * We can have metadata bufs and jdata bufs in the same journal. So each
384 * type gets its own log header, for which we need to reserve a block.
385 * In fact, each type has the potential for needing more than one header
386 * in cases where we have more buffers than will fit on a journal page.
387 * Metadata journal entries take up half the space of journaled buffer entries.
388 * Thus, metadata entries have buf_limit (502) and journaled buffers have
389 * databuf_limit (251) before they cause a wrap around.
390 *
391 * Also, we need to reserve blocks for revoke journal entries and one for an
392 * overall header for the lot.
393 *
394 * Returns: the number of blocks reserved
395 */
396static unsigned int calc_reserved(struct gfs2_sbd *sdp)
397{
398 unsigned int reserved = 0;
399 unsigned int mbuf_limit, metabufhdrs_needed;
400 unsigned int dbuf_limit, databufhdrs_needed;
401 unsigned int revokes = 0;
402
403 mbuf_limit = buf_limit(sdp);
404 metabufhdrs_needed = (sdp->sd_log_commited_buf +
405 (mbuf_limit - 1)) / mbuf_limit;
406 dbuf_limit = databuf_limit(sdp);
407 databufhdrs_needed = (sdp->sd_log_commited_databuf +
408 (dbuf_limit - 1)) / dbuf_limit;
409
410 if (sdp->sd_log_commited_revoke)
411 revokes = gfs2_struct2blk(sdp, sdp->sd_log_commited_revoke,
412 sizeof(u64));
413
414 reserved = sdp->sd_log_commited_buf + metabufhdrs_needed +
415 sdp->sd_log_commited_databuf + databufhdrs_needed +
416 revokes;
417 /* One for the overall header */
418 if (reserved)
419 reserved++;
420 return reserved;
421}
422
360static unsigned int current_tail(struct gfs2_sbd *sdp) 423static unsigned int current_tail(struct gfs2_sbd *sdp)
361{ 424{
362 struct gfs2_ail *ai; 425 struct gfs2_ail *ai;
@@ -447,14 +510,14 @@ struct buffer_head *gfs2_log_fake_buf(struct gfs2_sbd *sdp,
447 return bh; 510 return bh;
448} 511}
449 512
450static void log_pull_tail(struct gfs2_sbd *sdp, unsigned int new_tail, int pull) 513static void log_pull_tail(struct gfs2_sbd *sdp, unsigned int new_tail)
451{ 514{
452 unsigned int dist = log_distance(sdp, new_tail, sdp->sd_log_tail); 515 unsigned int dist = log_distance(sdp, new_tail, sdp->sd_log_tail);
453 516
454 ail2_empty(sdp, new_tail); 517 ail2_empty(sdp, new_tail);
455 518
456 gfs2_log_lock(sdp); 519 gfs2_log_lock(sdp);
457 sdp->sd_log_blks_free += dist - (pull ? 1 : 0); 520 sdp->sd_log_blks_free += dist;
458 gfs2_assert_withdraw(sdp, sdp->sd_log_blks_free <= sdp->sd_jdesc->jd_blocks); 521 gfs2_assert_withdraw(sdp, sdp->sd_log_blks_free <= sdp->sd_jdesc->jd_blocks);
459 gfs2_log_unlock(sdp); 522 gfs2_log_unlock(sdp);
460 523
@@ -504,7 +567,7 @@ static void log_write_header(struct gfs2_sbd *sdp, u32 flags, int pull)
504 brelse(bh); 567 brelse(bh);
505 568
506 if (sdp->sd_log_tail != tail) 569 if (sdp->sd_log_tail != tail)
507 log_pull_tail(sdp, tail, pull); 570 log_pull_tail(sdp, tail);
508 else 571 else
509 gfs2_assert_withdraw(sdp, !pull); 572 gfs2_assert_withdraw(sdp, !pull);
510 573
@@ -517,6 +580,7 @@ static void log_flush_commit(struct gfs2_sbd *sdp)
517 struct list_head *head = &sdp->sd_log_flush_list; 580 struct list_head *head = &sdp->sd_log_flush_list;
518 struct gfs2_log_buf *lb; 581 struct gfs2_log_buf *lb;
519 struct buffer_head *bh; 582 struct buffer_head *bh;
583 int flushcount = 0;
520 584
521 while (!list_empty(head)) { 585 while (!list_empty(head)) {
522 lb = list_entry(head->next, struct gfs2_log_buf, lb_list); 586 lb = list_entry(head->next, struct gfs2_log_buf, lb_list);
@@ -533,9 +597,20 @@ static void log_flush_commit(struct gfs2_sbd *sdp)
533 } else 597 } else
534 brelse(bh); 598 brelse(bh);
535 kfree(lb); 599 kfree(lb);
600 flushcount++;
536 } 601 }
537 602
538 log_write_header(sdp, 0, 0); 603 /* If nothing was journaled, the header is unplanned and unwanted. */
604 if (flushcount) {
605 log_write_header(sdp, 0, 0);
606 } else {
607 unsigned int tail;
608 tail = current_tail(sdp);
609
610 gfs2_ail1_empty(sdp, 0);
611 if (sdp->sd_log_tail != tail)
612 log_pull_tail(sdp, tail);
613 }
539} 614}
540 615
541/** 616/**
@@ -565,7 +640,10 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl)
565 INIT_LIST_HEAD(&ai->ai_ail1_list); 640 INIT_LIST_HEAD(&ai->ai_ail1_list);
566 INIT_LIST_HEAD(&ai->ai_ail2_list); 641 INIT_LIST_HEAD(&ai->ai_ail2_list);
567 642
568 gfs2_assert_withdraw(sdp, sdp->sd_log_num_buf == sdp->sd_log_commited_buf); 643 gfs2_assert_withdraw(sdp,
644 sdp->sd_log_num_buf + sdp->sd_log_num_jdata ==
645 sdp->sd_log_commited_buf +
646 sdp->sd_log_commited_databuf);
569 gfs2_assert_withdraw(sdp, 647 gfs2_assert_withdraw(sdp,
570 sdp->sd_log_num_revoke == sdp->sd_log_commited_revoke); 648 sdp->sd_log_num_revoke == sdp->sd_log_commited_revoke);
571 649
@@ -576,16 +654,19 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl)
576 lops_before_commit(sdp); 654 lops_before_commit(sdp);
577 if (!list_empty(&sdp->sd_log_flush_list)) 655 if (!list_empty(&sdp->sd_log_flush_list))
578 log_flush_commit(sdp); 656 log_flush_commit(sdp);
579 else if (sdp->sd_log_tail != current_tail(sdp) && !sdp->sd_log_idle) 657 else if (sdp->sd_log_tail != current_tail(sdp) && !sdp->sd_log_idle){
658 gfs2_log_lock(sdp);
659 sdp->sd_log_blks_free--; /* Adjust for unreserved buffer */
660 gfs2_log_unlock(sdp);
580 log_write_header(sdp, 0, PULL); 661 log_write_header(sdp, 0, PULL);
662 }
581 lops_after_commit(sdp, ai); 663 lops_after_commit(sdp, ai);
582 664
583 gfs2_log_lock(sdp); 665 gfs2_log_lock(sdp);
584 sdp->sd_log_head = sdp->sd_log_flush_head; 666 sdp->sd_log_head = sdp->sd_log_flush_head;
585 sdp->sd_log_blks_free -= sdp->sd_log_num_hdrs;
586 sdp->sd_log_blks_reserved = 0; 667 sdp->sd_log_blks_reserved = 0;
587 sdp->sd_log_commited_buf = 0; 668 sdp->sd_log_commited_buf = 0;
588 sdp->sd_log_num_hdrs = 0; 669 sdp->sd_log_commited_databuf = 0;
589 sdp->sd_log_commited_revoke = 0; 670 sdp->sd_log_commited_revoke = 0;
590 671
591 if (!list_empty(&ai->ai_ail1_list)) { 672 if (!list_empty(&ai->ai_ail1_list)) {
@@ -602,32 +683,26 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl)
602 683
603static void log_refund(struct gfs2_sbd *sdp, struct gfs2_trans *tr) 684static void log_refund(struct gfs2_sbd *sdp, struct gfs2_trans *tr)
604{ 685{
605 unsigned int reserved = 0; 686 unsigned int reserved;
606 unsigned int old; 687 unsigned int old;
607 688
608 gfs2_log_lock(sdp); 689 gfs2_log_lock(sdp);
609 690
610 sdp->sd_log_commited_buf += tr->tr_num_buf_new - tr->tr_num_buf_rm; 691 sdp->sd_log_commited_buf += tr->tr_num_buf_new - tr->tr_num_buf_rm;
611 gfs2_assert_withdraw(sdp, ((int)sdp->sd_log_commited_buf) >= 0); 692 sdp->sd_log_commited_databuf += tr->tr_num_databuf_new -
693 tr->tr_num_databuf_rm;
694 gfs2_assert_withdraw(sdp, (((int)sdp->sd_log_commited_buf) >= 0) ||
695 (((int)sdp->sd_log_commited_databuf) >= 0));
612 sdp->sd_log_commited_revoke += tr->tr_num_revoke - tr->tr_num_revoke_rm; 696 sdp->sd_log_commited_revoke += tr->tr_num_revoke - tr->tr_num_revoke_rm;
613 gfs2_assert_withdraw(sdp, ((int)sdp->sd_log_commited_revoke) >= 0); 697 gfs2_assert_withdraw(sdp, ((int)sdp->sd_log_commited_revoke) >= 0);
614 698 reserved = calc_reserved(sdp);
615 if (sdp->sd_log_commited_buf)
616 reserved += sdp->sd_log_commited_buf;
617 if (sdp->sd_log_commited_revoke)
618 reserved += gfs2_struct2blk(sdp, sdp->sd_log_commited_revoke,
619 sizeof(u64));
620 if (reserved)
621 reserved++;
622
623 old = sdp->sd_log_blks_free; 699 old = sdp->sd_log_blks_free;
624 sdp->sd_log_blks_free += tr->tr_reserved - 700 sdp->sd_log_blks_free += tr->tr_reserved -
625 (reserved - sdp->sd_log_blks_reserved); 701 (reserved - sdp->sd_log_blks_reserved);
626 702
627 gfs2_assert_withdraw(sdp, sdp->sd_log_blks_free >= old); 703 gfs2_assert_withdraw(sdp, sdp->sd_log_blks_free >= old);
628 gfs2_assert_withdraw(sdp, 704 gfs2_assert_withdraw(sdp, sdp->sd_log_blks_free <=
629 sdp->sd_log_blks_free <= sdp->sd_jdesc->jd_blocks + 705 sdp->sd_jdesc->jd_blocks);
630 sdp->sd_log_num_hdrs);
631 706
632 sdp->sd_log_blks_reserved = reserved; 707 sdp->sd_log_blks_reserved = reserved;
633 708
@@ -673,13 +748,13 @@ void gfs2_log_shutdown(struct gfs2_sbd *sdp)
673 gfs2_assert_withdraw(sdp, !sdp->sd_log_num_revoke); 748 gfs2_assert_withdraw(sdp, !sdp->sd_log_num_revoke);
674 gfs2_assert_withdraw(sdp, !sdp->sd_log_num_rg); 749 gfs2_assert_withdraw(sdp, !sdp->sd_log_num_rg);
675 gfs2_assert_withdraw(sdp, !sdp->sd_log_num_databuf); 750 gfs2_assert_withdraw(sdp, !sdp->sd_log_num_databuf);
676 gfs2_assert_withdraw(sdp, !sdp->sd_log_num_hdrs);
677 gfs2_assert_withdraw(sdp, list_empty(&sdp->sd_ail1_list)); 751 gfs2_assert_withdraw(sdp, list_empty(&sdp->sd_ail1_list));
678 752
679 sdp->sd_log_flush_head = sdp->sd_log_head; 753 sdp->sd_log_flush_head = sdp->sd_log_head;
680 sdp->sd_log_flush_wrapped = 0; 754 sdp->sd_log_flush_wrapped = 0;
681 755
682 log_write_header(sdp, GFS2_LOG_HEAD_UNMOUNT, 0); 756 log_write_header(sdp, GFS2_LOG_HEAD_UNMOUNT,
757 (sdp->sd_log_tail == current_tail(sdp)) ? 0 : PULL);
683 758
684 gfs2_assert_warn(sdp, sdp->sd_log_blks_free == sdp->sd_jdesc->jd_blocks); 759 gfs2_assert_warn(sdp, sdp->sd_log_blks_free == sdp->sd_jdesc->jd_blocks);
685 gfs2_assert_warn(sdp, sdp->sd_log_head == sdp->sd_log_tail); 760 gfs2_assert_warn(sdp, sdp->sd_log_head == sdp->sd_log_tail);
diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c
index f82d84d05d23..aff70f0698fd 100644
--- a/fs/gfs2/lops.c
+++ b/fs/gfs2/lops.c
@@ -17,6 +17,7 @@
17 17
18#include "gfs2.h" 18#include "gfs2.h"
19#include "incore.h" 19#include "incore.h"
20#include "inode.h"
20#include "glock.h" 21#include "glock.h"
21#include "log.h" 22#include "log.h"
22#include "lops.h" 23#include "lops.h"
@@ -117,15 +118,13 @@ static void buf_lo_before_commit(struct gfs2_sbd *sdp)
117 struct gfs2_log_descriptor *ld; 118 struct gfs2_log_descriptor *ld;
118 struct gfs2_bufdata *bd1 = NULL, *bd2; 119 struct gfs2_bufdata *bd1 = NULL, *bd2;
119 unsigned int total = sdp->sd_log_num_buf; 120 unsigned int total = sdp->sd_log_num_buf;
120 unsigned int offset = sizeof(struct gfs2_log_descriptor); 121 unsigned int offset = BUF_OFFSET;
121 unsigned int limit; 122 unsigned int limit;
122 unsigned int num; 123 unsigned int num;
123 unsigned n; 124 unsigned n;
124 __be64 *ptr; 125 __be64 *ptr;
125 126
126 offset += sizeof(__be64) - 1; 127 limit = buf_limit(sdp);
127 offset &= ~(sizeof(__be64) - 1);
128 limit = (sdp->sd_sb.sb_bsize - offset)/sizeof(__be64);
129 /* for 4k blocks, limit = 503 */ 128 /* for 4k blocks, limit = 503 */
130 129
131 bd1 = bd2 = list_prepare_entry(bd1, &sdp->sd_log_le_buf, bd_le.le_list); 130 bd1 = bd2 = list_prepare_entry(bd1, &sdp->sd_log_le_buf, bd_le.le_list);
@@ -134,7 +133,6 @@ static void buf_lo_before_commit(struct gfs2_sbd *sdp)
134 if (total > limit) 133 if (total > limit)
135 num = limit; 134 num = limit;
136 bh = gfs2_log_get_buf(sdp); 135 bh = gfs2_log_get_buf(sdp);
137 sdp->sd_log_num_hdrs++;
138 ld = (struct gfs2_log_descriptor *)bh->b_data; 136 ld = (struct gfs2_log_descriptor *)bh->b_data;
139 ptr = (__be64 *)(bh->b_data + offset); 137 ptr = (__be64 *)(bh->b_data + offset);
140 ld->ld_header.mh_magic = cpu_to_be32(GFS2_MAGIC); 138 ld->ld_header.mh_magic = cpu_to_be32(GFS2_MAGIC);
@@ -469,25 +467,28 @@ static void databuf_lo_add(struct gfs2_sbd *sdp, struct gfs2_log_element *le)
469 struct gfs2_inode *ip = GFS2_I(mapping->host); 467 struct gfs2_inode *ip = GFS2_I(mapping->host);
470 468
471 gfs2_log_lock(sdp); 469 gfs2_log_lock(sdp);
470 if (!list_empty(&bd->bd_list_tr)) {
471 gfs2_log_unlock(sdp);
472 return;
473 }
472 tr->tr_touched = 1; 474 tr->tr_touched = 1;
473 if (list_empty(&bd->bd_list_tr) && 475 if (gfs2_is_jdata(ip)) {
474 (ip->i_di.di_flags & GFS2_DIF_JDATA)) {
475 tr->tr_num_buf++; 476 tr->tr_num_buf++;
476 list_add(&bd->bd_list_tr, &tr->tr_list_buf); 477 list_add(&bd->bd_list_tr, &tr->tr_list_buf);
477 gfs2_log_unlock(sdp);
478 gfs2_pin(sdp, bd->bd_bh);
479 tr->tr_num_buf_new++;
480 } else {
481 gfs2_log_unlock(sdp);
482 } 478 }
479 gfs2_log_unlock(sdp);
480 if (!list_empty(&le->le_list))
481 return;
482
483 gfs2_trans_add_gl(bd->bd_gl); 483 gfs2_trans_add_gl(bd->bd_gl);
484 gfs2_log_lock(sdp); 484 if (gfs2_is_jdata(ip)) {
485 if (list_empty(&le->le_list)) { 485 sdp->sd_log_num_jdata++;
486 if (ip->i_di.di_flags & GFS2_DIF_JDATA) 486 gfs2_pin(sdp, bd->bd_bh);
487 sdp->sd_log_num_jdata++; 487 tr->tr_num_databuf_new++;
488 sdp->sd_log_num_databuf++;
489 list_add(&le->le_list, &sdp->sd_log_le_databuf);
490 } 488 }
489 sdp->sd_log_num_databuf++;
490 gfs2_log_lock(sdp);
491 list_add(&le->le_list, &sdp->sd_log_le_databuf);
491 gfs2_log_unlock(sdp); 492 gfs2_log_unlock(sdp);
492} 493}
493 494
@@ -520,7 +521,6 @@ static void databuf_lo_before_commit(struct gfs2_sbd *sdp)
520 LIST_HEAD(started); 521 LIST_HEAD(started);
521 struct gfs2_bufdata *bd1 = NULL, *bd2, *bdt; 522 struct gfs2_bufdata *bd1 = NULL, *bd2, *bdt;
522 struct buffer_head *bh = NULL,*bh1 = NULL; 523 struct buffer_head *bh = NULL,*bh1 = NULL;
523 unsigned int offset = sizeof(struct gfs2_log_descriptor);
524 struct gfs2_log_descriptor *ld; 524 struct gfs2_log_descriptor *ld;
525 unsigned int limit; 525 unsigned int limit;
526 unsigned int total_dbuf = sdp->sd_log_num_databuf; 526 unsigned int total_dbuf = sdp->sd_log_num_databuf;
@@ -528,9 +528,7 @@ static void databuf_lo_before_commit(struct gfs2_sbd *sdp)
528 unsigned int num, n; 528 unsigned int num, n;
529 __be64 *ptr = NULL; 529 __be64 *ptr = NULL;
530 530
531 offset += 2*sizeof(__be64) - 1; 531 limit = databuf_limit(sdp);
532 offset &= ~(2*sizeof(__be64) - 1);
533 limit = (sdp->sd_sb.sb_bsize - offset)/sizeof(__be64);
534 532
535 /* 533 /*
536 * Start writing ordered buffers, write journaled buffers 534 * Start writing ordered buffers, write journaled buffers
@@ -581,10 +579,10 @@ static void databuf_lo_before_commit(struct gfs2_sbd *sdp)
581 gfs2_log_unlock(sdp); 579 gfs2_log_unlock(sdp);
582 if (!bh) { 580 if (!bh) {
583 bh = gfs2_log_get_buf(sdp); 581 bh = gfs2_log_get_buf(sdp);
584 sdp->sd_log_num_hdrs++;
585 ld = (struct gfs2_log_descriptor *) 582 ld = (struct gfs2_log_descriptor *)
586 bh->b_data; 583 bh->b_data;
587 ptr = (__be64 *)(bh->b_data + offset); 584 ptr = (__be64 *)(bh->b_data +
585 DATABUF_OFFSET);
588 ld->ld_header.mh_magic = 586 ld->ld_header.mh_magic =
589 cpu_to_be32(GFS2_MAGIC); 587 cpu_to_be32(GFS2_MAGIC);
590 ld->ld_header.mh_type = 588 ld->ld_header.mh_type =
@@ -605,7 +603,7 @@ static void databuf_lo_before_commit(struct gfs2_sbd *sdp)
605 if (unlikely(magic != 0)) 603 if (unlikely(magic != 0))
606 set_buffer_escaped(bh1); 604 set_buffer_escaped(bh1);
607 gfs2_log_lock(sdp); 605 gfs2_log_lock(sdp);
608 if (n++ > num) 606 if (++n >= num)
609 break; 607 break;
610 } else if (!bh1) { 608 } else if (!bh1) {
611 total_dbuf--; 609 total_dbuf--;
@@ -622,6 +620,7 @@ static void databuf_lo_before_commit(struct gfs2_sbd *sdp)
622 } 620 }
623 gfs2_log_unlock(sdp); 621 gfs2_log_unlock(sdp);
624 if (bh) { 622 if (bh) {
623 set_buffer_mapped(bh);
625 set_buffer_dirty(bh); 624 set_buffer_dirty(bh);
626 ll_rw_block(WRITE, 1, &bh); 625 ll_rw_block(WRITE, 1, &bh);
627 bh = NULL; 626 bh = NULL;
diff --git a/fs/gfs2/lops.h b/fs/gfs2/lops.h
index 965bc65c7c64..41a00df75587 100644
--- a/fs/gfs2/lops.h
+++ b/fs/gfs2/lops.h
@@ -13,6 +13,13 @@
13#include <linux/list.h> 13#include <linux/list.h>
14#include "incore.h" 14#include "incore.h"
15 15
16#define BUF_OFFSET \
17 ((sizeof(struct gfs2_log_descriptor) + sizeof(__be64) - 1) & \
18 ~(sizeof(__be64) - 1))
19#define DATABUF_OFFSET \
20 ((sizeof(struct gfs2_log_descriptor) + (2 * sizeof(__be64) - 1)) & \
21 ~(2 * sizeof(__be64) - 1))
22
16extern const struct gfs2_log_operations gfs2_glock_lops; 23extern const struct gfs2_log_operations gfs2_glock_lops;
17extern const struct gfs2_log_operations gfs2_buf_lops; 24extern const struct gfs2_log_operations gfs2_buf_lops;
18extern const struct gfs2_log_operations gfs2_revoke_lops; 25extern const struct gfs2_log_operations gfs2_revoke_lops;
@@ -21,6 +28,22 @@ extern const struct gfs2_log_operations gfs2_databuf_lops;
21 28
22extern const struct gfs2_log_operations *gfs2_log_ops[]; 29extern const struct gfs2_log_operations *gfs2_log_ops[];
23 30
31static inline unsigned int buf_limit(struct gfs2_sbd *sdp)
32{
33 unsigned int limit;
34
35 limit = (sdp->sd_sb.sb_bsize - BUF_OFFSET) / sizeof(__be64);
36 return limit;
37}
38
39static inline unsigned int databuf_limit(struct gfs2_sbd *sdp)
40{
41 unsigned int limit;
42
43 limit = (sdp->sd_sb.sb_bsize - DATABUF_OFFSET) / (2 * sizeof(__be64));
44 return limit;
45}
46
24static inline void lops_init_le(struct gfs2_log_element *le, 47static inline void lops_init_le(struct gfs2_log_element *le,
25 const struct gfs2_log_operations *lops) 48 const struct gfs2_log_operations *lops)
26{ 49{
diff --git a/fs/gfs2/meta_io.c b/fs/gfs2/meta_io.c
index e62d4f620c58..8da343b34ae7 100644
--- a/fs/gfs2/meta_io.c
+++ b/fs/gfs2/meta_io.c
@@ -387,12 +387,18 @@ void gfs2_meta_wipe(struct gfs2_inode *ip, u64 bstart, u32 blen)
387 387
388 if (test_clear_buffer_pinned(bh)) { 388 if (test_clear_buffer_pinned(bh)) {
389 struct gfs2_trans *tr = current->journal_info; 389 struct gfs2_trans *tr = current->journal_info;
390 struct gfs2_inode *bh_ip =
391 GFS2_I(bh->b_page->mapping->host);
392
390 gfs2_log_lock(sdp); 393 gfs2_log_lock(sdp);
391 list_del_init(&bd->bd_le.le_list); 394 list_del_init(&bd->bd_le.le_list);
392 gfs2_assert_warn(sdp, sdp->sd_log_num_buf); 395 gfs2_assert_warn(sdp, sdp->sd_log_num_buf);
393 sdp->sd_log_num_buf--; 396 sdp->sd_log_num_buf--;
394 gfs2_log_unlock(sdp); 397 gfs2_log_unlock(sdp);
395 tr->tr_num_buf_rm++; 398 if (bh_ip->i_inode.i_private != NULL)
399 tr->tr_num_databuf_rm++;
400 else
401 tr->tr_num_buf_rm++;
396 brelse(bh); 402 brelse(bh);
397 } 403 }
398 if (bd) { 404 if (bd) {
diff --git a/fs/gfs2/meta_io.h b/fs/gfs2/meta_io.h
index e037425bc042..527bf19d9690 100644
--- a/fs/gfs2/meta_io.h
+++ b/fs/gfs2/meta_io.h
@@ -63,7 +63,7 @@ int gfs2_meta_indirect_buffer(struct gfs2_inode *ip, int height, u64 num,
63static inline int gfs2_meta_inode_buffer(struct gfs2_inode *ip, 63static inline int gfs2_meta_inode_buffer(struct gfs2_inode *ip,
64 struct buffer_head **bhp) 64 struct buffer_head **bhp)
65{ 65{
66 return gfs2_meta_indirect_buffer(ip, 0, ip->i_num.no_addr, 0, bhp); 66 return gfs2_meta_indirect_buffer(ip, 0, ip->i_no_addr, 0, bhp);
67} 67}
68 68
69struct buffer_head *gfs2_meta_ra(struct gfs2_glock *gl, u64 dblock, u32 extlen); 69struct buffer_head *gfs2_meta_ra(struct gfs2_glock *gl, u64 dblock, u32 extlen);
diff --git a/fs/gfs2/mount.c b/fs/gfs2/mount.c
index 4864659555d4..6f006a804db3 100644
--- a/fs/gfs2/mount.c
+++ b/fs/gfs2/mount.c
@@ -82,20 +82,19 @@ int gfs2_mount_args(struct gfs2_sbd *sdp, char *data_arg, int remount)
82 char *options, *o, *v; 82 char *options, *o, *v;
83 int error = 0; 83 int error = 0;
84 84
85 if (!remount) { 85 /* If someone preloaded options, use those instead */
86 /* If someone preloaded options, use those instead */ 86 spin_lock(&gfs2_sys_margs_lock);
87 spin_lock(&gfs2_sys_margs_lock); 87 if (!remount && gfs2_sys_margs) {
88 if (gfs2_sys_margs) { 88 data = gfs2_sys_margs;
89 data = gfs2_sys_margs; 89 gfs2_sys_margs = NULL;
90 gfs2_sys_margs = NULL;
91 }
92 spin_unlock(&gfs2_sys_margs_lock);
93
94 /* Set some defaults */
95 args->ar_num_glockd = GFS2_GLOCKD_DEFAULT;
96 args->ar_quota = GFS2_QUOTA_DEFAULT;
97 args->ar_data = GFS2_DATA_DEFAULT;
98 } 90 }
91 spin_unlock(&gfs2_sys_margs_lock);
92
93 /* Set some defaults */
94 memset(args, 0, sizeof(struct gfs2_args));
95 args->ar_num_glockd = GFS2_GLOCKD_DEFAULT;
96 args->ar_quota = GFS2_QUOTA_DEFAULT;
97 args->ar_data = GFS2_DATA_DEFAULT;
99 98
100 /* Split the options into tokens with the "," character and 99 /* Split the options into tokens with the "," character and
101 process them */ 100 process them */
diff --git a/fs/gfs2/ondisk.c b/fs/gfs2/ondisk.c
deleted file mode 100644
index d9ecfd23a49e..000000000000
--- a/fs/gfs2/ondisk.c
+++ /dev/null
@@ -1,251 +0,0 @@
1/*
2 * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
3 * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
4 *
5 * This copyrighted material is made available to anyone wishing to use,
6 * modify, copy, or redistribute it subject to the terms and conditions
7 * of the GNU General Public License version 2.
8 */
9
10#include <linux/slab.h>
11#include <linux/spinlock.h>
12#include <linux/completion.h>
13#include <linux/buffer_head.h>
14
15#include "gfs2.h"
16#include <linux/gfs2_ondisk.h>
17#include <linux/lm_interface.h>
18#include "incore.h"
19
20#define pv(struct, member, fmt) printk(KERN_INFO " "#member" = "fmt"\n", \
21 struct->member);
22
23/*
24 * gfs2_xxx_in - read in an xxx struct
25 * first arg: the cpu-order structure
26 * buf: the disk-order buffer
27 *
28 * gfs2_xxx_out - write out an xxx struct
29 * first arg: the cpu-order structure
30 * buf: the disk-order buffer
31 *
32 * gfs2_xxx_print - print out an xxx struct
33 * first arg: the cpu-order structure
34 */
35
36void gfs2_inum_in(struct gfs2_inum_host *no, const void *buf)
37{
38 const struct gfs2_inum *str = buf;
39
40 no->no_formal_ino = be64_to_cpu(str->no_formal_ino);
41 no->no_addr = be64_to_cpu(str->no_addr);
42}
43
44void gfs2_inum_out(const struct gfs2_inum_host *no, void *buf)
45{
46 struct gfs2_inum *str = buf;
47
48 str->no_formal_ino = cpu_to_be64(no->no_formal_ino);
49 str->no_addr = cpu_to_be64(no->no_addr);
50}
51
52static void gfs2_inum_print(const struct gfs2_inum_host *no)
53{
54 printk(KERN_INFO " no_formal_ino = %llu\n", (unsigned long long)no->no_formal_ino);
55 printk(KERN_INFO " no_addr = %llu\n", (unsigned long long)no->no_addr);
56}
57
58static void gfs2_meta_header_in(struct gfs2_meta_header_host *mh, const void *buf)
59{
60 const struct gfs2_meta_header *str = buf;
61
62 mh->mh_magic = be32_to_cpu(str->mh_magic);
63 mh->mh_type = be32_to_cpu(str->mh_type);
64 mh->mh_format = be32_to_cpu(str->mh_format);
65}
66
67void gfs2_sb_in(struct gfs2_sb_host *sb, const void *buf)
68{
69 const struct gfs2_sb *str = buf;
70
71 gfs2_meta_header_in(&sb->sb_header, buf);
72
73 sb->sb_fs_format = be32_to_cpu(str->sb_fs_format);
74 sb->sb_multihost_format = be32_to_cpu(str->sb_multihost_format);
75 sb->sb_bsize = be32_to_cpu(str->sb_bsize);
76 sb->sb_bsize_shift = be32_to_cpu(str->sb_bsize_shift);
77
78 gfs2_inum_in(&sb->sb_master_dir, (char *)&str->sb_master_dir);
79 gfs2_inum_in(&sb->sb_root_dir, (char *)&str->sb_root_dir);
80
81 memcpy(sb->sb_lockproto, str->sb_lockproto, GFS2_LOCKNAME_LEN);
82 memcpy(sb->sb_locktable, str->sb_locktable, GFS2_LOCKNAME_LEN);
83}
84
85void gfs2_rindex_in(struct gfs2_rindex_host *ri, const void *buf)
86{
87 const struct gfs2_rindex *str = buf;
88
89 ri->ri_addr = be64_to_cpu(str->ri_addr);
90 ri->ri_length = be32_to_cpu(str->ri_length);
91 ri->ri_data0 = be64_to_cpu(str->ri_data0);
92 ri->ri_data = be32_to_cpu(str->ri_data);
93 ri->ri_bitbytes = be32_to_cpu(str->ri_bitbytes);
94
95}
96
97void gfs2_rindex_print(const struct gfs2_rindex_host *ri)
98{
99 printk(KERN_INFO " ri_addr = %llu\n", (unsigned long long)ri->ri_addr);
100 pv(ri, ri_length, "%u");
101
102 printk(KERN_INFO " ri_data0 = %llu\n", (unsigned long long)ri->ri_data0);
103 pv(ri, ri_data, "%u");
104
105 pv(ri, ri_bitbytes, "%u");
106}
107
108void gfs2_rgrp_in(struct gfs2_rgrp_host *rg, const void *buf)
109{
110 const struct gfs2_rgrp *str = buf;
111
112 rg->rg_flags = be32_to_cpu(str->rg_flags);
113 rg->rg_free = be32_to_cpu(str->rg_free);
114 rg->rg_dinodes = be32_to_cpu(str->rg_dinodes);
115 rg->rg_igeneration = be64_to_cpu(str->rg_igeneration);
116}
117
118void gfs2_rgrp_out(const struct gfs2_rgrp_host *rg, void *buf)
119{
120 struct gfs2_rgrp *str = buf;
121
122 str->rg_flags = cpu_to_be32(rg->rg_flags);
123 str->rg_free = cpu_to_be32(rg->rg_free);
124 str->rg_dinodes = cpu_to_be32(rg->rg_dinodes);
125 str->__pad = cpu_to_be32(0);
126 str->rg_igeneration = cpu_to_be64(rg->rg_igeneration);
127 memset(&str->rg_reserved, 0, sizeof(str->rg_reserved));
128}
129
130void gfs2_quota_in(struct gfs2_quota_host *qu, const void *buf)
131{
132 const struct gfs2_quota *str = buf;
133
134 qu->qu_limit = be64_to_cpu(str->qu_limit);
135 qu->qu_warn = be64_to_cpu(str->qu_warn);
136 qu->qu_value = be64_to_cpu(str->qu_value);
137}
138
139void gfs2_dinode_out(const struct gfs2_inode *ip, void *buf)
140{
141 const struct gfs2_dinode_host *di = &ip->i_di;
142 struct gfs2_dinode *str = buf;
143
144 str->di_header.mh_magic = cpu_to_be32(GFS2_MAGIC);
145 str->di_header.mh_type = cpu_to_be32(GFS2_METATYPE_DI);
146 str->di_header.__pad0 = 0;
147 str->di_header.mh_format = cpu_to_be32(GFS2_FORMAT_DI);
148 str->di_header.__pad1 = 0;
149
150 gfs2_inum_out(&ip->i_num, &str->di_num);
151
152 str->di_mode = cpu_to_be32(ip->i_inode.i_mode);
153 str->di_uid = cpu_to_be32(ip->i_inode.i_uid);
154 str->di_gid = cpu_to_be32(ip->i_inode.i_gid);
155 str->di_nlink = cpu_to_be32(ip->i_inode.i_nlink);
156 str->di_size = cpu_to_be64(di->di_size);
157 str->di_blocks = cpu_to_be64(di->di_blocks);
158 str->di_atime = cpu_to_be64(ip->i_inode.i_atime.tv_sec);
159 str->di_mtime = cpu_to_be64(ip->i_inode.i_mtime.tv_sec);
160 str->di_ctime = cpu_to_be64(ip->i_inode.i_ctime.tv_sec);
161
162 str->di_goal_meta = cpu_to_be64(di->di_goal_meta);
163 str->di_goal_data = cpu_to_be64(di->di_goal_data);
164 str->di_generation = cpu_to_be64(di->di_generation);
165
166 str->di_flags = cpu_to_be32(di->di_flags);
167 str->di_height = cpu_to_be16(di->di_height);
168 str->di_payload_format = cpu_to_be32(S_ISDIR(ip->i_inode.i_mode) &&
169 !(ip->i_di.di_flags & GFS2_DIF_EXHASH) ?
170 GFS2_FORMAT_DE : 0);
171 str->di_depth = cpu_to_be16(di->di_depth);
172 str->di_entries = cpu_to_be32(di->di_entries);
173
174 str->di_eattr = cpu_to_be64(di->di_eattr);
175}
176
177void gfs2_dinode_print(const struct gfs2_inode *ip)
178{
179 const struct gfs2_dinode_host *di = &ip->i_di;
180
181 gfs2_inum_print(&ip->i_num);
182
183 printk(KERN_INFO " di_size = %llu\n", (unsigned long long)di->di_size);
184 printk(KERN_INFO " di_blocks = %llu\n", (unsigned long long)di->di_blocks);
185 printk(KERN_INFO " di_goal_meta = %llu\n", (unsigned long long)di->di_goal_meta);
186 printk(KERN_INFO " di_goal_data = %llu\n", (unsigned long long)di->di_goal_data);
187
188 pv(di, di_flags, "0x%.8X");
189 pv(di, di_height, "%u");
190
191 pv(di, di_depth, "%u");
192 pv(di, di_entries, "%u");
193
194 printk(KERN_INFO " di_eattr = %llu\n", (unsigned long long)di->di_eattr);
195}
196
197void gfs2_log_header_in(struct gfs2_log_header_host *lh, const void *buf)
198{
199 const struct gfs2_log_header *str = buf;
200
201 gfs2_meta_header_in(&lh->lh_header, buf);
202 lh->lh_sequence = be64_to_cpu(str->lh_sequence);
203 lh->lh_flags = be32_to_cpu(str->lh_flags);
204 lh->lh_tail = be32_to_cpu(str->lh_tail);
205 lh->lh_blkno = be32_to_cpu(str->lh_blkno);
206 lh->lh_hash = be32_to_cpu(str->lh_hash);
207}
208
209void gfs2_inum_range_in(struct gfs2_inum_range_host *ir, const void *buf)
210{
211 const struct gfs2_inum_range *str = buf;
212
213 ir->ir_start = be64_to_cpu(str->ir_start);
214 ir->ir_length = be64_to_cpu(str->ir_length);
215}
216
217void gfs2_inum_range_out(const struct gfs2_inum_range_host *ir, void *buf)
218{
219 struct gfs2_inum_range *str = buf;
220
221 str->ir_start = cpu_to_be64(ir->ir_start);
222 str->ir_length = cpu_to_be64(ir->ir_length);
223}
224
225void gfs2_statfs_change_in(struct gfs2_statfs_change_host *sc, const void *buf)
226{
227 const struct gfs2_statfs_change *str = buf;
228
229 sc->sc_total = be64_to_cpu(str->sc_total);
230 sc->sc_free = be64_to_cpu(str->sc_free);
231 sc->sc_dinodes = be64_to_cpu(str->sc_dinodes);
232}
233
234void gfs2_statfs_change_out(const struct gfs2_statfs_change_host *sc, void *buf)
235{
236 struct gfs2_statfs_change *str = buf;
237
238 str->sc_total = cpu_to_be64(sc->sc_total);
239 str->sc_free = cpu_to_be64(sc->sc_free);
240 str->sc_dinodes = cpu_to_be64(sc->sc_dinodes);
241}
242
243void gfs2_quota_change_in(struct gfs2_quota_change_host *qc, const void *buf)
244{
245 const struct gfs2_quota_change *str = buf;
246
247 qc->qc_change = be64_to_cpu(str->qc_change);
248 qc->qc_flags = be32_to_cpu(str->qc_flags);
249 qc->qc_id = be32_to_cpu(str->qc_id);
250}
251
diff --git a/fs/gfs2/ops_address.c b/fs/gfs2/ops_address.c
index 30c15622174f..26c888890c24 100644
--- a/fs/gfs2/ops_address.c
+++ b/fs/gfs2/ops_address.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. 2 * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
3 * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. 3 * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
4 * 4 *
5 * This copyrighted material is made available to anyone wishing to use, 5 * This copyrighted material is made available to anyone wishing to use,
6 * modify, copy, or redistribute it subject to the terms and conditions 6 * modify, copy, or redistribute it subject to the terms and conditions
@@ -32,6 +32,7 @@
32#include "trans.h" 32#include "trans.h"
33#include "rgrp.h" 33#include "rgrp.h"
34#include "ops_file.h" 34#include "ops_file.h"
35#include "super.h"
35#include "util.h" 36#include "util.h"
36#include "glops.h" 37#include "glops.h"
37 38
@@ -49,6 +50,8 @@ static void gfs2_page_add_databufs(struct gfs2_inode *ip, struct page *page,
49 end = start + bsize; 50 end = start + bsize;
50 if (end <= from || start >= to) 51 if (end <= from || start >= to)
51 continue; 52 continue;
53 if (gfs2_is_jdata(ip))
54 set_buffer_uptodate(bh);
52 gfs2_trans_add_bh(ip->i_gl, bh, 0); 55 gfs2_trans_add_bh(ip->i_gl, bh, 0);
53 } 56 }
54} 57}
@@ -134,7 +137,9 @@ static int gfs2_writepage(struct page *page, struct writeback_control *wbc)
134 return 0; /* don't care */ 137 return 0; /* don't care */
135 } 138 }
136 139
137 if (sdp->sd_args.ar_data == GFS2_DATA_ORDERED || gfs2_is_jdata(ip)) { 140 if ((sdp->sd_args.ar_data == GFS2_DATA_ORDERED || gfs2_is_jdata(ip)) &&
141 PageChecked(page)) {
142 ClearPageChecked(page);
138 error = gfs2_trans_begin(sdp, RES_DINODE + 1, 0); 143 error = gfs2_trans_begin(sdp, RES_DINODE + 1, 0);
139 if (error) 144 if (error)
140 goto out_ignore; 145 goto out_ignore;
@@ -203,11 +208,7 @@ static int stuffed_readpage(struct gfs2_inode *ip, struct page *page)
203 * so we need to supply one here. It doesn't happen often. 208 * so we need to supply one here. It doesn't happen often.
204 */ 209 */
205 if (unlikely(page->index)) { 210 if (unlikely(page->index)) {
206 kaddr = kmap_atomic(page, KM_USER0); 211 zero_user_page(page, 0, PAGE_CACHE_SIZE, KM_USER0);
207 memset(kaddr, 0, PAGE_CACHE_SIZE);
208 kunmap_atomic(kaddr, KM_USER0);
209 flush_dcache_page(page);
210 SetPageUptodate(page);
211 return 0; 212 return 0;
212 } 213 }
213 214
@@ -450,6 +451,31 @@ out_uninit:
450} 451}
451 452
452/** 453/**
454 * adjust_fs_space - Adjusts the free space available due to gfs2_grow
455 * @inode: the rindex inode
456 */
457static void adjust_fs_space(struct inode *inode)
458{
459 struct gfs2_sbd *sdp = inode->i_sb->s_fs_info;
460 struct gfs2_statfs_change_host *m_sc = &sdp->sd_statfs_master;
461 struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local;
462 u64 fs_total, new_free;
463
464 /* Total up the file system space, according to the latest rindex. */
465 fs_total = gfs2_ri_total(sdp);
466
467 spin_lock(&sdp->sd_statfs_spin);
468 if (fs_total > (m_sc->sc_total + l_sc->sc_total))
469 new_free = fs_total - (m_sc->sc_total + l_sc->sc_total);
470 else
471 new_free = 0;
472 spin_unlock(&sdp->sd_statfs_spin);
473 fs_warn(sdp, "File system extended by %llu blocks.\n",
474 (unsigned long long)new_free);
475 gfs2_statfs_change(sdp, new_free, new_free, 0);
476}
477
478/**
453 * gfs2_commit_write - Commit write to a file 479 * gfs2_commit_write - Commit write to a file
454 * @file: The file to write to 480 * @file: The file to write to
455 * @page: The page containing the data 481 * @page: The page containing the data
@@ -511,6 +537,9 @@ static int gfs2_commit_write(struct file *file, struct page *page,
511 di->di_size = cpu_to_be64(inode->i_size); 537 di->di_size = cpu_to_be64(inode->i_size);
512 } 538 }
513 539
540 if (inode == sdp->sd_rindex)
541 adjust_fs_space(inode);
542
514 brelse(dibh); 543 brelse(dibh);
515 gfs2_trans_end(sdp); 544 gfs2_trans_end(sdp);
516 if (al->al_requested) { 545 if (al->al_requested) {
@@ -543,6 +572,23 @@ fail_nounlock:
543} 572}
544 573
545/** 574/**
575 * gfs2_set_page_dirty - Page dirtying function
576 * @page: The page to dirty
577 *
578 * Returns: 1 if it dirtyed the page, or 0 otherwise
579 */
580
581static int gfs2_set_page_dirty(struct page *page)
582{
583 struct gfs2_inode *ip = GFS2_I(page->mapping->host);
584 struct gfs2_sbd *sdp = GFS2_SB(page->mapping->host);
585
586 if (sdp->sd_args.ar_data == GFS2_DATA_ORDERED || gfs2_is_jdata(ip))
587 SetPageChecked(page);
588 return __set_page_dirty_buffers(page);
589}
590
591/**
546 * gfs2_bmap - Block map function 592 * gfs2_bmap - Block map function
547 * @mapping: Address space info 593 * @mapping: Address space info
548 * @lblock: The block to map 594 * @lblock: The block to map
@@ -578,6 +624,8 @@ static void discard_buffer(struct gfs2_sbd *sdp, struct buffer_head *bh)
578 if (bd) { 624 if (bd) {
579 bd->bd_bh = NULL; 625 bd->bd_bh = NULL;
580 bh->b_private = NULL; 626 bh->b_private = NULL;
627 if (!bd->bd_ail && list_empty(&bd->bd_le.le_list))
628 kmem_cache_free(gfs2_bufdata_cachep, bd);
581 } 629 }
582 gfs2_log_unlock(sdp); 630 gfs2_log_unlock(sdp);
583 631
@@ -598,6 +646,8 @@ static void gfs2_invalidatepage(struct page *page, unsigned long offset)
598 unsigned int curr_off = 0; 646 unsigned int curr_off = 0;
599 647
600 BUG_ON(!PageLocked(page)); 648 BUG_ON(!PageLocked(page));
649 if (offset == 0)
650 ClearPageChecked(page);
601 if (!page_has_buffers(page)) 651 if (!page_has_buffers(page))
602 return; 652 return;
603 653
@@ -728,8 +778,8 @@ static unsigned limit = 0;
728 return; 778 return;
729 779
730 fs_warn(sdp, "ip = %llu %llu\n", 780 fs_warn(sdp, "ip = %llu %llu\n",
731 (unsigned long long)ip->i_num.no_formal_ino, 781 (unsigned long long)ip->i_no_formal_ino,
732 (unsigned long long)ip->i_num.no_addr); 782 (unsigned long long)ip->i_no_addr);
733 783
734 for (x = 0; x < GFS2_MAX_META_HEIGHT; x++) 784 for (x = 0; x < GFS2_MAX_META_HEIGHT; x++)
735 fs_warn(sdp, "ip->i_cache[%u] = %s\n", 785 fs_warn(sdp, "ip->i_cache[%u] = %s\n",
@@ -810,6 +860,7 @@ const struct address_space_operations gfs2_file_aops = {
810 .sync_page = block_sync_page, 860 .sync_page = block_sync_page,
811 .prepare_write = gfs2_prepare_write, 861 .prepare_write = gfs2_prepare_write,
812 .commit_write = gfs2_commit_write, 862 .commit_write = gfs2_commit_write,
863 .set_page_dirty = gfs2_set_page_dirty,
813 .bmap = gfs2_bmap, 864 .bmap = gfs2_bmap,
814 .invalidatepage = gfs2_invalidatepage, 865 .invalidatepage = gfs2_invalidatepage,
815 .releasepage = gfs2_releasepage, 866 .releasepage = gfs2_releasepage,
diff --git a/fs/gfs2/ops_address.h b/fs/gfs2/ops_address.h
index 35aaee4aa7e1..fa1b5b3d28b9 100644
--- a/fs/gfs2/ops_address.h
+++ b/fs/gfs2/ops_address.h
@@ -1,6 +1,6 @@
1/* 1/*
2 * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. 2 * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
3 * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. 3 * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
4 * 4 *
5 * This copyrighted material is made available to anyone wishing to use, 5 * This copyrighted material is made available to anyone wishing to use,
6 * modify, copy, or redistribute it subject to the terms and conditions 6 * modify, copy, or redistribute it subject to the terms and conditions
diff --git a/fs/gfs2/ops_dentry.c b/fs/gfs2/ops_dentry.c
index a6fdc52f554a..793e334d098e 100644
--- a/fs/gfs2/ops_dentry.c
+++ b/fs/gfs2/ops_dentry.c
@@ -21,6 +21,7 @@
21#include "glock.h" 21#include "glock.h"
22#include "ops_dentry.h" 22#include "ops_dentry.h"
23#include "util.h" 23#include "util.h"
24#include "inode.h"
24 25
25/** 26/**
26 * gfs2_drevalidate - Check directory lookup consistency 27 * gfs2_drevalidate - Check directory lookup consistency
@@ -40,14 +41,15 @@ static int gfs2_drevalidate(struct dentry *dentry, struct nameidata *nd)
40 struct gfs2_inode *dip = GFS2_I(parent->d_inode); 41 struct gfs2_inode *dip = GFS2_I(parent->d_inode);
41 struct inode *inode = dentry->d_inode; 42 struct inode *inode = dentry->d_inode;
42 struct gfs2_holder d_gh; 43 struct gfs2_holder d_gh;
43 struct gfs2_inode *ip; 44 struct gfs2_inode *ip = NULL;
44 struct gfs2_inum_host inum;
45 unsigned int type;
46 int error; 45 int error;
47 int had_lock=0; 46 int had_lock=0;
48 47
49 if (inode && is_bad_inode(inode)) 48 if (inode) {
50 goto invalid; 49 if (is_bad_inode(inode))
50 goto invalid;
51 ip = GFS2_I(inode);
52 }
51 53
52 if (sdp->sd_args.ar_localcaching) 54 if (sdp->sd_args.ar_localcaching)
53 goto valid; 55 goto valid;
@@ -59,7 +61,7 @@ static int gfs2_drevalidate(struct dentry *dentry, struct nameidata *nd)
59 goto fail; 61 goto fail;
60 } 62 }
61 63
62 error = gfs2_dir_search(parent->d_inode, &dentry->d_name, &inum, &type); 64 error = gfs2_dir_check(parent->d_inode, &dentry->d_name, ip);
63 switch (error) { 65 switch (error) {
64 case 0: 66 case 0:
65 if (!inode) 67 if (!inode)
@@ -73,16 +75,6 @@ static int gfs2_drevalidate(struct dentry *dentry, struct nameidata *nd)
73 goto fail_gunlock; 75 goto fail_gunlock;
74 } 76 }
75 77
76 ip = GFS2_I(inode);
77
78 if (!gfs2_inum_equal(&ip->i_num, &inum))
79 goto invalid_gunlock;
80
81 if (IF2DT(ip->i_inode.i_mode) != type) {
82 gfs2_consist_inode(dip);
83 goto fail_gunlock;
84 }
85
86valid_gunlock: 78valid_gunlock:
87 if (!had_lock) 79 if (!had_lock)
88 gfs2_glock_dq_uninit(&d_gh); 80 gfs2_glock_dq_uninit(&d_gh);
diff --git a/fs/gfs2/ops_export.c b/fs/gfs2/ops_export.c
index aad918337a46..99ea5659bc2c 100644
--- a/fs/gfs2/ops_export.c
+++ b/fs/gfs2/ops_export.c
@@ -22,10 +22,14 @@
22#include "glops.h" 22#include "glops.h"
23#include "inode.h" 23#include "inode.h"
24#include "ops_dentry.h" 24#include "ops_dentry.h"
25#include "ops_export.h" 25#include "ops_fstype.h"
26#include "rgrp.h" 26#include "rgrp.h"
27#include "util.h" 27#include "util.h"
28 28
29#define GFS2_SMALL_FH_SIZE 4
30#define GFS2_LARGE_FH_SIZE 8
31#define GFS2_OLD_FH_SIZE 10
32
29static struct dentry *gfs2_decode_fh(struct super_block *sb, 33static struct dentry *gfs2_decode_fh(struct super_block *sb,
30 __u32 *p, 34 __u32 *p,
31 int fh_len, 35 int fh_len,
@@ -35,31 +39,28 @@ static struct dentry *gfs2_decode_fh(struct super_block *sb,
35 void *context) 39 void *context)
36{ 40{
37 __be32 *fh = (__force __be32 *)p; 41 __be32 *fh = (__force __be32 *)p;
38 struct gfs2_fh_obj fh_obj; 42 struct gfs2_inum_host inum, parent;
39 struct gfs2_inum_host *this, parent;
40 43
41 this = &fh_obj.this;
42 fh_obj.imode = DT_UNKNOWN;
43 memset(&parent, 0, sizeof(struct gfs2_inum)); 44 memset(&parent, 0, sizeof(struct gfs2_inum));
44 45
45 switch (fh_len) { 46 switch (fh_len) {
46 case GFS2_LARGE_FH_SIZE: 47 case GFS2_LARGE_FH_SIZE:
48 case GFS2_OLD_FH_SIZE:
47 parent.no_formal_ino = ((u64)be32_to_cpu(fh[4])) << 32; 49 parent.no_formal_ino = ((u64)be32_to_cpu(fh[4])) << 32;
48 parent.no_formal_ino |= be32_to_cpu(fh[5]); 50 parent.no_formal_ino |= be32_to_cpu(fh[5]);
49 parent.no_addr = ((u64)be32_to_cpu(fh[6])) << 32; 51 parent.no_addr = ((u64)be32_to_cpu(fh[6])) << 32;
50 parent.no_addr |= be32_to_cpu(fh[7]); 52 parent.no_addr |= be32_to_cpu(fh[7]);
51 fh_obj.imode = be32_to_cpu(fh[8]);
52 case GFS2_SMALL_FH_SIZE: 53 case GFS2_SMALL_FH_SIZE:
53 this->no_formal_ino = ((u64)be32_to_cpu(fh[0])) << 32; 54 inum.no_formal_ino = ((u64)be32_to_cpu(fh[0])) << 32;
54 this->no_formal_ino |= be32_to_cpu(fh[1]); 55 inum.no_formal_ino |= be32_to_cpu(fh[1]);
55 this->no_addr = ((u64)be32_to_cpu(fh[2])) << 32; 56 inum.no_addr = ((u64)be32_to_cpu(fh[2])) << 32;
56 this->no_addr |= be32_to_cpu(fh[3]); 57 inum.no_addr |= be32_to_cpu(fh[3]);
57 break; 58 break;
58 default: 59 default:
59 return NULL; 60 return NULL;
60 } 61 }
61 62
62 return gfs2_export_ops.find_exported_dentry(sb, &fh_obj, &parent, 63 return gfs2_export_ops.find_exported_dentry(sb, &inum, &parent,
63 acceptable, context); 64 acceptable, context);
64} 65}
65 66
@@ -75,10 +76,10 @@ static int gfs2_encode_fh(struct dentry *dentry, __u32 *p, int *len,
75 (connectable && *len < GFS2_LARGE_FH_SIZE)) 76 (connectable && *len < GFS2_LARGE_FH_SIZE))
76 return 255; 77 return 255;
77 78
78 fh[0] = cpu_to_be32(ip->i_num.no_formal_ino >> 32); 79 fh[0] = cpu_to_be32(ip->i_no_formal_ino >> 32);
79 fh[1] = cpu_to_be32(ip->i_num.no_formal_ino & 0xFFFFFFFF); 80 fh[1] = cpu_to_be32(ip->i_no_formal_ino & 0xFFFFFFFF);
80 fh[2] = cpu_to_be32(ip->i_num.no_addr >> 32); 81 fh[2] = cpu_to_be32(ip->i_no_addr >> 32);
81 fh[3] = cpu_to_be32(ip->i_num.no_addr & 0xFFFFFFFF); 82 fh[3] = cpu_to_be32(ip->i_no_addr & 0xFFFFFFFF);
82 *len = GFS2_SMALL_FH_SIZE; 83 *len = GFS2_SMALL_FH_SIZE;
83 84
84 if (!connectable || inode == sb->s_root->d_inode) 85 if (!connectable || inode == sb->s_root->d_inode)
@@ -90,13 +91,10 @@ static int gfs2_encode_fh(struct dentry *dentry, __u32 *p, int *len,
90 igrab(inode); 91 igrab(inode);
91 spin_unlock(&dentry->d_lock); 92 spin_unlock(&dentry->d_lock);
92 93
93 fh[4] = cpu_to_be32(ip->i_num.no_formal_ino >> 32); 94 fh[4] = cpu_to_be32(ip->i_no_formal_ino >> 32);
94 fh[5] = cpu_to_be32(ip->i_num.no_formal_ino & 0xFFFFFFFF); 95 fh[5] = cpu_to_be32(ip->i_no_formal_ino & 0xFFFFFFFF);
95 fh[6] = cpu_to_be32(ip->i_num.no_addr >> 32); 96 fh[6] = cpu_to_be32(ip->i_no_addr >> 32);
96 fh[7] = cpu_to_be32(ip->i_num.no_addr & 0xFFFFFFFF); 97 fh[7] = cpu_to_be32(ip->i_no_addr & 0xFFFFFFFF);
97
98 fh[8] = cpu_to_be32(inode->i_mode);
99 fh[9] = 0; /* pad to double word */
100 *len = GFS2_LARGE_FH_SIZE; 98 *len = GFS2_LARGE_FH_SIZE;
101 99
102 iput(inode); 100 iput(inode);
@@ -144,7 +142,8 @@ static int gfs2_get_name(struct dentry *parent, char *name,
144 ip = GFS2_I(inode); 142 ip = GFS2_I(inode);
145 143
146 *name = 0; 144 *name = 0;
147 gnfd.inum = ip->i_num; 145 gnfd.inum.no_addr = ip->i_no_addr;
146 gnfd.inum.no_formal_ino = ip->i_no_formal_ino;
148 gnfd.name = name; 147 gnfd.name = name;
149 148
150 error = gfs2_glock_nq_init(dip->i_gl, LM_ST_SHARED, 0, &gh); 149 error = gfs2_glock_nq_init(dip->i_gl, LM_ST_SHARED, 0, &gh);
@@ -192,8 +191,7 @@ static struct dentry *gfs2_get_parent(struct dentry *child)
192static struct dentry *gfs2_get_dentry(struct super_block *sb, void *inum_obj) 191static struct dentry *gfs2_get_dentry(struct super_block *sb, void *inum_obj)
193{ 192{
194 struct gfs2_sbd *sdp = sb->s_fs_info; 193 struct gfs2_sbd *sdp = sb->s_fs_info;
195 struct gfs2_fh_obj *fh_obj = (struct gfs2_fh_obj *)inum_obj; 194 struct gfs2_inum_host *inum = inum_obj;
196 struct gfs2_inum_host *inum = &fh_obj->this;
197 struct gfs2_holder i_gh, ri_gh, rgd_gh; 195 struct gfs2_holder i_gh, ri_gh, rgd_gh;
198 struct gfs2_rgrpd *rgd; 196 struct gfs2_rgrpd *rgd;
199 struct inode *inode; 197 struct inode *inode;
@@ -202,9 +200,9 @@ static struct dentry *gfs2_get_dentry(struct super_block *sb, void *inum_obj)
202 200
203 /* System files? */ 201 /* System files? */
204 202
205 inode = gfs2_ilookup(sb, inum); 203 inode = gfs2_ilookup(sb, inum->no_addr);
206 if (inode) { 204 if (inode) {
207 if (GFS2_I(inode)->i_num.no_formal_ino != inum->no_formal_ino) { 205 if (GFS2_I(inode)->i_no_formal_ino != inum->no_formal_ino) {
208 iput(inode); 206 iput(inode);
209 return ERR_PTR(-ESTALE); 207 return ERR_PTR(-ESTALE);
210 } 208 }
@@ -236,7 +234,9 @@ static struct dentry *gfs2_get_dentry(struct super_block *sb, void *inum_obj)
236 gfs2_glock_dq_uninit(&rgd_gh); 234 gfs2_glock_dq_uninit(&rgd_gh);
237 gfs2_glock_dq_uninit(&ri_gh); 235 gfs2_glock_dq_uninit(&ri_gh);
238 236
239 inode = gfs2_inode_lookup(sb, inum, fh_obj->imode); 237 inode = gfs2_inode_lookup(sb, DT_UNKNOWN,
238 inum->no_addr,
239 0);
240 if (!inode) 240 if (!inode)
241 goto fail; 241 goto fail;
242 if (IS_ERR(inode)) { 242 if (IS_ERR(inode)) {
@@ -250,6 +250,15 @@ static struct dentry *gfs2_get_dentry(struct super_block *sb, void *inum_obj)
250 goto fail; 250 goto fail;
251 } 251 }
252 252
253 /* Pick up the works we bypass in gfs2_inode_lookup */
254 if (inode->i_state & I_NEW)
255 gfs2_set_iop(inode);
256
257 if (GFS2_I(inode)->i_no_formal_ino != inum->no_formal_ino) {
258 iput(inode);
259 goto fail;
260 }
261
253 error = -EIO; 262 error = -EIO;
254 if (GFS2_I(inode)->i_di.di_flags & GFS2_DIF_SYSTEM) { 263 if (GFS2_I(inode)->i_di.di_flags & GFS2_DIF_SYSTEM) {
255 iput(inode); 264 iput(inode);
diff --git a/fs/gfs2/ops_export.h b/fs/gfs2/ops_export.h
deleted file mode 100644
index f925a955b3b8..000000000000
--- a/fs/gfs2/ops_export.h
+++ /dev/null
@@ -1,22 +0,0 @@
1/*
2 * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
3 * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
4 *
5 * This copyrighted material is made available to anyone wishing to use,
6 * modify, copy, or redistribute it subject to the terms and conditions
7 * of the GNU General Public License version 2.
8 */
9
10#ifndef __OPS_EXPORT_DOT_H__
11#define __OPS_EXPORT_DOT_H__
12
13#define GFS2_SMALL_FH_SIZE 4
14#define GFS2_LARGE_FH_SIZE 10
15
16extern struct export_operations gfs2_export_ops;
17struct gfs2_fh_obj {
18 struct gfs2_inum_host this;
19 __u32 imode;
20};
21
22#endif /* __OPS_EXPORT_DOT_H__ */
diff --git a/fs/gfs2/ops_file.c b/fs/gfs2/ops_file.c
index 064df8804582..196d83266e34 100644
--- a/fs/gfs2/ops_file.c
+++ b/fs/gfs2/ops_file.c
@@ -502,7 +502,7 @@ static int gfs2_lock(struct file *file, int cmd, struct file_lock *fl)
502 struct gfs2_inode *ip = GFS2_I(file->f_mapping->host); 502 struct gfs2_inode *ip = GFS2_I(file->f_mapping->host);
503 struct gfs2_sbd *sdp = GFS2_SB(file->f_mapping->host); 503 struct gfs2_sbd *sdp = GFS2_SB(file->f_mapping->host);
504 struct lm_lockname name = 504 struct lm_lockname name =
505 { .ln_number = ip->i_num.no_addr, 505 { .ln_number = ip->i_no_addr,
506 .ln_type = LM_TYPE_PLOCK }; 506 .ln_type = LM_TYPE_PLOCK };
507 507
508 if (!(fl->fl_flags & FL_POSIX)) 508 if (!(fl->fl_flags & FL_POSIX))
@@ -557,7 +557,7 @@ static int do_flock(struct file *file, int cmd, struct file_lock *fl)
557 gfs2_glock_dq_uninit(fl_gh); 557 gfs2_glock_dq_uninit(fl_gh);
558 } else { 558 } else {
559 error = gfs2_glock_get(GFS2_SB(&ip->i_inode), 559 error = gfs2_glock_get(GFS2_SB(&ip->i_inode),
560 ip->i_num.no_addr, &gfs2_flock_glops, 560 ip->i_no_addr, &gfs2_flock_glops,
561 CREATE, &gl); 561 CREATE, &gl);
562 if (error) 562 if (error)
563 goto out; 563 goto out;
@@ -635,7 +635,6 @@ const struct file_operations gfs2_file_fops = {
635 .release = gfs2_close, 635 .release = gfs2_close,
636 .fsync = gfs2_fsync, 636 .fsync = gfs2_fsync,
637 .lock = gfs2_lock, 637 .lock = gfs2_lock,
638 .sendfile = generic_file_sendfile,
639 .flock = gfs2_flock, 638 .flock = gfs2_flock,
640 .splice_read = generic_file_splice_read, 639 .splice_read = generic_file_splice_read,
641 .splice_write = generic_file_splice_write, 640 .splice_write = generic_file_splice_write,
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c
index 2c5f8e7def0d..cf5aa5050548 100644
--- a/fs/gfs2/ops_fstype.c
+++ b/fs/gfs2/ops_fstype.c
@@ -27,7 +27,6 @@
27#include "inode.h" 27#include "inode.h"
28#include "lm.h" 28#include "lm.h"
29#include "mount.h" 29#include "mount.h"
30#include "ops_export.h"
31#include "ops_fstype.h" 30#include "ops_fstype.h"
32#include "ops_super.h" 31#include "ops_super.h"
33#include "recovery.h" 32#include "recovery.h"
@@ -105,6 +104,7 @@ static void init_vfs(struct super_block *sb, unsigned noatime)
105 sb->s_magic = GFS2_MAGIC; 104 sb->s_magic = GFS2_MAGIC;
106 sb->s_op = &gfs2_super_ops; 105 sb->s_op = &gfs2_super_ops;
107 sb->s_export_op = &gfs2_export_ops; 106 sb->s_export_op = &gfs2_export_ops;
107 sb->s_time_gran = 1;
108 sb->s_maxbytes = MAX_LFS_FILESIZE; 108 sb->s_maxbytes = MAX_LFS_FILESIZE;
109 109
110 if (sb->s_flags & (MS_NOATIME | MS_NODIRATIME)) 110 if (sb->s_flags & (MS_NOATIME | MS_NODIRATIME))
@@ -116,7 +116,6 @@ static void init_vfs(struct super_block *sb, unsigned noatime)
116 116
117static int init_names(struct gfs2_sbd *sdp, int silent) 117static int init_names(struct gfs2_sbd *sdp, int silent)
118{ 118{
119 struct page *page;
120 char *proto, *table; 119 char *proto, *table;
121 int error = 0; 120 int error = 0;
122 121
@@ -126,14 +125,9 @@ static int init_names(struct gfs2_sbd *sdp, int silent)
126 /* Try to autodetect */ 125 /* Try to autodetect */
127 126
128 if (!proto[0] || !table[0]) { 127 if (!proto[0] || !table[0]) {
129 struct gfs2_sb *sb; 128 error = gfs2_read_super(sdp, GFS2_SB_ADDR >> sdp->sd_fsb2bb_shift);
130 page = gfs2_read_super(sdp->sd_vfs, GFS2_SB_ADDR >> sdp->sd_fsb2bb_shift); 129 if (error)
131 if (!page) 130 return error;
132 return -ENOBUFS;
133 sb = kmap(page);
134 gfs2_sb_in(&sdp->sd_sb, sb);
135 kunmap(page);
136 __free_page(page);
137 131
138 error = gfs2_check_sb(sdp, &sdp->sd_sb, silent); 132 error = gfs2_check_sb(sdp, &sdp->sd_sb, silent);
139 if (error) 133 if (error)
@@ -151,6 +145,9 @@ static int init_names(struct gfs2_sbd *sdp, int silent)
151 snprintf(sdp->sd_proto_name, GFS2_FSNAME_LEN, "%s", proto); 145 snprintf(sdp->sd_proto_name, GFS2_FSNAME_LEN, "%s", proto);
152 snprintf(sdp->sd_table_name, GFS2_FSNAME_LEN, "%s", table); 146 snprintf(sdp->sd_table_name, GFS2_FSNAME_LEN, "%s", table);
153 147
148 while ((table = strchr(sdp->sd_table_name, '/')))
149 *table = '_';
150
154out: 151out:
155 return error; 152 return error;
156} 153}
@@ -236,17 +233,17 @@ fail:
236 return error; 233 return error;
237} 234}
238 235
239static struct inode *gfs2_lookup_root(struct super_block *sb, 236static inline struct inode *gfs2_lookup_root(struct super_block *sb,
240 struct gfs2_inum_host *inum) 237 u64 no_addr)
241{ 238{
242 return gfs2_inode_lookup(sb, inum, DT_DIR); 239 return gfs2_inode_lookup(sb, DT_DIR, no_addr, 0);
243} 240}
244 241
245static int init_sb(struct gfs2_sbd *sdp, int silent, int undo) 242static int init_sb(struct gfs2_sbd *sdp, int silent, int undo)
246{ 243{
247 struct super_block *sb = sdp->sd_vfs; 244 struct super_block *sb = sdp->sd_vfs;
248 struct gfs2_holder sb_gh; 245 struct gfs2_holder sb_gh;
249 struct gfs2_inum_host *inum; 246 u64 no_addr;
250 struct inode *inode; 247 struct inode *inode;
251 int error = 0; 248 int error = 0;
252 249
@@ -289,10 +286,10 @@ static int init_sb(struct gfs2_sbd *sdp, int silent, int undo)
289 sb_set_blocksize(sb, sdp->sd_sb.sb_bsize); 286 sb_set_blocksize(sb, sdp->sd_sb.sb_bsize);
290 287
291 /* Get the root inode */ 288 /* Get the root inode */
292 inum = &sdp->sd_sb.sb_root_dir; 289 no_addr = sdp->sd_sb.sb_root_dir.no_addr;
293 if (sb->s_type == &gfs2meta_fs_type) 290 if (sb->s_type == &gfs2meta_fs_type)
294 inum = &sdp->sd_sb.sb_master_dir; 291 no_addr = sdp->sd_sb.sb_master_dir.no_addr;
295 inode = gfs2_lookup_root(sb, inum); 292 inode = gfs2_lookup_root(sb, no_addr);
296 if (IS_ERR(inode)) { 293 if (IS_ERR(inode)) {
297 error = PTR_ERR(inode); 294 error = PTR_ERR(inode);
298 fs_err(sdp, "can't read in root inode: %d\n", error); 295 fs_err(sdp, "can't read in root inode: %d\n", error);
@@ -449,7 +446,7 @@ static int init_inodes(struct gfs2_sbd *sdp, int undo)
449 if (undo) 446 if (undo)
450 goto fail_qinode; 447 goto fail_qinode;
451 448
452 inode = gfs2_lookup_root(sdp->sd_vfs, &sdp->sd_sb.sb_master_dir); 449 inode = gfs2_lookup_root(sdp->sd_vfs, sdp->sd_sb.sb_master_dir.no_addr);
453 if (IS_ERR(inode)) { 450 if (IS_ERR(inode)) {
454 error = PTR_ERR(inode); 451 error = PTR_ERR(inode);
455 fs_err(sdp, "can't read in master directory: %d\n", error); 452 fs_err(sdp, "can't read in master directory: %d\n", error);
diff --git a/fs/gfs2/ops_fstype.h b/fs/gfs2/ops_fstype.h
index 7cc2c296271b..407029b3b2b3 100644
--- a/fs/gfs2/ops_fstype.h
+++ b/fs/gfs2/ops_fstype.h
@@ -14,5 +14,6 @@
14 14
15extern struct file_system_type gfs2_fs_type; 15extern struct file_system_type gfs2_fs_type;
16extern struct file_system_type gfs2meta_fs_type; 16extern struct file_system_type gfs2meta_fs_type;
17extern struct export_operations gfs2_export_ops;
17 18
18#endif /* __OPS_FSTYPE_DOT_H__ */ 19#endif /* __OPS_FSTYPE_DOT_H__ */
diff --git a/fs/gfs2/ops_inode.c b/fs/gfs2/ops_inode.c
index d85f6e05cb95..911c115b5c6c 100644
--- a/fs/gfs2/ops_inode.c
+++ b/fs/gfs2/ops_inode.c
@@ -157,7 +157,7 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir,
157 if (error) 157 if (error)
158 goto out_gunlock; 158 goto out_gunlock;
159 159
160 error = gfs2_dir_search(dir, &dentry->d_name, NULL, NULL); 160 error = gfs2_dir_check(dir, &dentry->d_name, NULL);
161 switch (error) { 161 switch (error) {
162 case -ENOENT: 162 case -ENOENT:
163 break; 163 break;
@@ -206,7 +206,7 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir,
206 goto out_gunlock_q; 206 goto out_gunlock_q;
207 207
208 error = gfs2_trans_begin(sdp, sdp->sd_max_dirres + 208 error = gfs2_trans_begin(sdp, sdp->sd_max_dirres +
209 al->al_rgd->rd_ri.ri_length + 209 al->al_rgd->rd_length +
210 2 * RES_DINODE + RES_STATFS + 210 2 * RES_DINODE + RES_STATFS +
211 RES_QUOTA, 0); 211 RES_QUOTA, 0);
212 if (error) 212 if (error)
@@ -217,8 +217,7 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir,
217 goto out_ipres; 217 goto out_ipres;
218 } 218 }
219 219
220 error = gfs2_dir_add(dir, &dentry->d_name, &ip->i_num, 220 error = gfs2_dir_add(dir, &dentry->d_name, ip, IF2DT(inode->i_mode));
221 IF2DT(inode->i_mode));
222 if (error) 221 if (error)
223 goto out_end_trans; 222 goto out_end_trans;
224 223
@@ -275,7 +274,7 @@ static int gfs2_unlink(struct inode *dir, struct dentry *dentry)
275 gfs2_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs); 274 gfs2_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs);
276 gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + 1); 275 gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + 1);
277 276
278 rgd = gfs2_blk2rgrpd(sdp, ip->i_num.no_addr); 277 rgd = gfs2_blk2rgrpd(sdp, ip->i_no_addr);
279 gfs2_holder_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, ghs + 2); 278 gfs2_holder_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, ghs + 2);
280 279
281 280
@@ -420,7 +419,7 @@ static int gfs2_mkdir(struct inode *dir, struct dentry *dentry, int mode)
420 dent = (struct gfs2_dirent *)((char*)dent + GFS2_DIRENT_SIZE(1)); 419 dent = (struct gfs2_dirent *)((char*)dent + GFS2_DIRENT_SIZE(1));
421 gfs2_qstr2dirent(&str, dibh->b_size - GFS2_DIRENT_SIZE(1) - sizeof(struct gfs2_dinode), dent); 420 gfs2_qstr2dirent(&str, dibh->b_size - GFS2_DIRENT_SIZE(1) - sizeof(struct gfs2_dinode), dent);
422 421
423 gfs2_inum_out(&dip->i_num, &dent->de_inum); 422 gfs2_inum_out(dip, dent);
424 dent->de_type = cpu_to_be16(DT_DIR); 423 dent->de_type = cpu_to_be16(DT_DIR);
425 424
426 gfs2_dinode_out(ip, di); 425 gfs2_dinode_out(ip, di);
@@ -472,7 +471,7 @@ static int gfs2_rmdir(struct inode *dir, struct dentry *dentry)
472 gfs2_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs); 471 gfs2_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs);
473 gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + 1); 472 gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + 1);
474 473
475 rgd = gfs2_blk2rgrpd(sdp, ip->i_num.no_addr); 474 rgd = gfs2_blk2rgrpd(sdp, ip->i_no_addr);
476 gfs2_holder_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, ghs + 2); 475 gfs2_holder_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, ghs + 2);
477 476
478 error = gfs2_glock_nq_m(3, ghs); 477 error = gfs2_glock_nq_m(3, ghs);
@@ -614,7 +613,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
614 * this is the case of the target file already existing 613 * this is the case of the target file already existing
615 * so we unlink before doing the rename 614 * so we unlink before doing the rename
616 */ 615 */
617 nrgd = gfs2_blk2rgrpd(sdp, nip->i_num.no_addr); 616 nrgd = gfs2_blk2rgrpd(sdp, nip->i_no_addr);
618 if (nrgd) 617 if (nrgd)
619 gfs2_holder_init(nrgd->rd_gl, LM_ST_EXCLUSIVE, 0, ghs + num_gh++); 618 gfs2_holder_init(nrgd->rd_gl, LM_ST_EXCLUSIVE, 0, ghs + num_gh++);
620 } 619 }
@@ -653,7 +652,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
653 if (error) 652 if (error)
654 goto out_gunlock; 653 goto out_gunlock;
655 654
656 error = gfs2_dir_search(ndir, &ndentry->d_name, NULL, NULL); 655 error = gfs2_dir_check(ndir, &ndentry->d_name, NULL);
657 switch (error) { 656 switch (error) {
658 case -ENOENT: 657 case -ENOENT:
659 error = 0; 658 error = 0;
@@ -712,7 +711,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
712 goto out_gunlock_q; 711 goto out_gunlock_q;
713 712
714 error = gfs2_trans_begin(sdp, sdp->sd_max_dirres + 713 error = gfs2_trans_begin(sdp, sdp->sd_max_dirres +
715 al->al_rgd->rd_ri.ri_length + 714 al->al_rgd->rd_length +
716 4 * RES_DINODE + 4 * RES_LEAF + 715 4 * RES_DINODE + 4 * RES_LEAF +
717 RES_STATFS + RES_QUOTA + 4, 0); 716 RES_STATFS + RES_QUOTA + 4, 0);
718 if (error) 717 if (error)
@@ -750,7 +749,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
750 if (error) 749 if (error)
751 goto out_end_trans; 750 goto out_end_trans;
752 751
753 error = gfs2_dir_mvino(ip, &name, &ndip->i_num, DT_DIR); 752 error = gfs2_dir_mvino(ip, &name, ndip, DT_DIR);
754 if (error) 753 if (error)
755 goto out_end_trans; 754 goto out_end_trans;
756 } else { 755 } else {
@@ -758,7 +757,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
758 error = gfs2_meta_inode_buffer(ip, &dibh); 757 error = gfs2_meta_inode_buffer(ip, &dibh);
759 if (error) 758 if (error)
760 goto out_end_trans; 759 goto out_end_trans;
761 ip->i_inode.i_ctime = CURRENT_TIME_SEC; 760 ip->i_inode.i_ctime = CURRENT_TIME;
762 gfs2_trans_add_bh(ip->i_gl, dibh, 1); 761 gfs2_trans_add_bh(ip->i_gl, dibh, 1);
763 gfs2_dinode_out(ip, dibh->b_data); 762 gfs2_dinode_out(ip, dibh->b_data);
764 brelse(dibh); 763 brelse(dibh);
@@ -768,8 +767,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
768 if (error) 767 if (error)
769 goto out_end_trans; 768 goto out_end_trans;
770 769
771 error = gfs2_dir_add(ndir, &ndentry->d_name, &ip->i_num, 770 error = gfs2_dir_add(ndir, &ndentry->d_name, ip, IF2DT(ip->i_inode.i_mode));
772 IF2DT(ip->i_inode.i_mode));
773 if (error) 771 if (error)
774 goto out_end_trans; 772 goto out_end_trans;
775 773
@@ -905,8 +903,8 @@ static int setattr_size(struct inode *inode, struct iattr *attr)
905 } 903 }
906 904
907 error = gfs2_truncatei(ip, attr->ia_size); 905 error = gfs2_truncatei(ip, attr->ia_size);
908 if (error) 906 if (error && (inode->i_size != ip->i_di.di_size))
909 return error; 907 i_size_write(inode, ip->i_di.di_size);
910 908
911 return error; 909 return error;
912} 910}
diff --git a/fs/gfs2/ops_super.c b/fs/gfs2/ops_super.c
index 485ce3d49923..603d940f1159 100644
--- a/fs/gfs2/ops_super.c
+++ b/fs/gfs2/ops_super.c
@@ -326,8 +326,10 @@ static void gfs2_clear_inode(struct inode *inode)
326 gfs2_glock_schedule_for_reclaim(ip->i_gl); 326 gfs2_glock_schedule_for_reclaim(ip->i_gl);
327 gfs2_glock_put(ip->i_gl); 327 gfs2_glock_put(ip->i_gl);
328 ip->i_gl = NULL; 328 ip->i_gl = NULL;
329 if (ip->i_iopen_gh.gh_gl) 329 if (ip->i_iopen_gh.gh_gl) {
330 ip->i_iopen_gh.gh_gl->gl_object = NULL;
330 gfs2_glock_dq_uninit(&ip->i_iopen_gh); 331 gfs2_glock_dq_uninit(&ip->i_iopen_gh);
332 }
331 } 333 }
332} 334}
333 335
@@ -422,13 +424,13 @@ static void gfs2_delete_inode(struct inode *inode)
422 if (!inode->i_private) 424 if (!inode->i_private)
423 goto out; 425 goto out;
424 426
425 error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, LM_FLAG_TRY_1CB, &gh); 427 error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh);
426 if (unlikely(error)) { 428 if (unlikely(error)) {
427 gfs2_glock_dq_uninit(&ip->i_iopen_gh); 429 gfs2_glock_dq_uninit(&ip->i_iopen_gh);
428 goto out; 430 goto out;
429 } 431 }
430 432
431 gfs2_glock_dq(&ip->i_iopen_gh); 433 gfs2_glock_dq_wait(&ip->i_iopen_gh);
432 gfs2_holder_reinit(LM_ST_EXCLUSIVE, LM_FLAG_TRY_1CB | GL_NOCACHE, &ip->i_iopen_gh); 434 gfs2_holder_reinit(LM_ST_EXCLUSIVE, LM_FLAG_TRY_1CB | GL_NOCACHE, &ip->i_iopen_gh);
433 error = gfs2_glock_nq(&ip->i_iopen_gh); 435 error = gfs2_glock_nq(&ip->i_iopen_gh);
434 if (error) 436 if (error)
diff --git a/fs/gfs2/ops_vm.c b/fs/gfs2/ops_vm.c
index aa0dbd2aac1b..404b7cc9f8c4 100644
--- a/fs/gfs2/ops_vm.c
+++ b/fs/gfs2/ops_vm.c
@@ -66,7 +66,7 @@ static int alloc_page_backing(struct gfs2_inode *ip, struct page *page)
66 if (error) 66 if (error)
67 goto out_gunlock_q; 67 goto out_gunlock_q;
68 68
69 error = gfs2_trans_begin(sdp, al->al_rgd->rd_ri.ri_length + 69 error = gfs2_trans_begin(sdp, al->al_rgd->rd_length +
70 ind_blocks + RES_DINODE + 70 ind_blocks + RES_DINODE +
71 RES_STATFS + RES_QUOTA, 0); 71 RES_STATFS + RES_QUOTA, 0);
72 if (error) 72 if (error)
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c
index c186857e48a8..6e546ee8f3d4 100644
--- a/fs/gfs2/quota.c
+++ b/fs/gfs2/quota.c
@@ -66,6 +66,18 @@
66#define QUOTA_USER 1 66#define QUOTA_USER 1
67#define QUOTA_GROUP 0 67#define QUOTA_GROUP 0
68 68
69struct gfs2_quota_host {
70 u64 qu_limit;
71 u64 qu_warn;
72 s64 qu_value;
73};
74
75struct gfs2_quota_change_host {
76 u64 qc_change;
77 u32 qc_flags; /* GFS2_QCF_... */
78 u32 qc_id;
79};
80
69static u64 qd2offset(struct gfs2_quota_data *qd) 81static u64 qd2offset(struct gfs2_quota_data *qd)
70{ 82{
71 u64 offset; 83 u64 offset;
@@ -561,6 +573,25 @@ static void do_qc(struct gfs2_quota_data *qd, s64 change)
561 mutex_unlock(&sdp->sd_quota_mutex); 573 mutex_unlock(&sdp->sd_quota_mutex);
562} 574}
563 575
576static void gfs2_quota_in(struct gfs2_quota_host *qu, const void *buf)
577{
578 const struct gfs2_quota *str = buf;
579
580 qu->qu_limit = be64_to_cpu(str->qu_limit);
581 qu->qu_warn = be64_to_cpu(str->qu_warn);
582 qu->qu_value = be64_to_cpu(str->qu_value);
583}
584
585static void gfs2_quota_out(const struct gfs2_quota_host *qu, void *buf)
586{
587 struct gfs2_quota *str = buf;
588
589 str->qu_limit = cpu_to_be64(qu->qu_limit);
590 str->qu_warn = cpu_to_be64(qu->qu_warn);
591 str->qu_value = cpu_to_be64(qu->qu_value);
592 memset(&str->qu_reserved, 0, sizeof(str->qu_reserved));
593}
594
564/** 595/**
565 * gfs2_adjust_quota 596 * gfs2_adjust_quota
566 * 597 *
@@ -573,12 +604,13 @@ static int gfs2_adjust_quota(struct gfs2_inode *ip, loff_t loc,
573 struct inode *inode = &ip->i_inode; 604 struct inode *inode = &ip->i_inode;
574 struct address_space *mapping = inode->i_mapping; 605 struct address_space *mapping = inode->i_mapping;
575 unsigned long index = loc >> PAGE_CACHE_SHIFT; 606 unsigned long index = loc >> PAGE_CACHE_SHIFT;
576 unsigned offset = loc & (PAGE_CACHE_SHIFT - 1); 607 unsigned offset = loc & (PAGE_CACHE_SIZE - 1);
577 unsigned blocksize, iblock, pos; 608 unsigned blocksize, iblock, pos;
578 struct buffer_head *bh; 609 struct buffer_head *bh;
579 struct page *page; 610 struct page *page;
580 void *kaddr; 611 void *kaddr;
581 __be64 *ptr; 612 char *ptr;
613 struct gfs2_quota_host qp;
582 s64 value; 614 s64 value;
583 int err = -EIO; 615 int err = -EIO;
584 616
@@ -620,13 +652,17 @@ static int gfs2_adjust_quota(struct gfs2_inode *ip, loff_t loc,
620 652
621 kaddr = kmap_atomic(page, KM_USER0); 653 kaddr = kmap_atomic(page, KM_USER0);
622 ptr = kaddr + offset; 654 ptr = kaddr + offset;
623 value = (s64)be64_to_cpu(*ptr) + change; 655 gfs2_quota_in(&qp, ptr);
624 *ptr = cpu_to_be64(value); 656 qp.qu_value += change;
657 value = qp.qu_value;
658 gfs2_quota_out(&qp, ptr);
625 flush_dcache_page(page); 659 flush_dcache_page(page);
626 kunmap_atomic(kaddr, KM_USER0); 660 kunmap_atomic(kaddr, KM_USER0);
627 err = 0; 661 err = 0;
628 qd->qd_qb.qb_magic = cpu_to_be32(GFS2_MAGIC); 662 qd->qd_qb.qb_magic = cpu_to_be32(GFS2_MAGIC);
629 qd->qd_qb.qb_value = cpu_to_be64(value); 663 qd->qd_qb.qb_value = cpu_to_be64(value);
664 ((struct gfs2_quota_lvb*)(qd->qd_gl->gl_lvb))->qb_magic = cpu_to_be32(GFS2_MAGIC);
665 ((struct gfs2_quota_lvb*)(qd->qd_gl->gl_lvb))->qb_value = cpu_to_be64(value);
630unlock: 666unlock:
631 unlock_page(page); 667 unlock_page(page);
632 page_cache_release(page); 668 page_cache_release(page);
@@ -689,7 +725,7 @@ static int do_sync(unsigned int num_qd, struct gfs2_quota_data **qda)
689 goto out_alloc; 725 goto out_alloc;
690 726
691 error = gfs2_trans_begin(sdp, 727 error = gfs2_trans_begin(sdp,
692 al->al_rgd->rd_ri.ri_length + 728 al->al_rgd->rd_length +
693 num_qd * data_blocks + 729 num_qd * data_blocks +
694 nalloc * ind_blocks + 730 nalloc * ind_blocks +
695 RES_DINODE + num_qd + 731 RES_DINODE + num_qd +
@@ -709,7 +745,7 @@ static int do_sync(unsigned int num_qd, struct gfs2_quota_data **qda)
709 offset = qd2offset(qd); 745 offset = qd2offset(qd);
710 error = gfs2_adjust_quota(ip, offset, qd->qd_change_sync, 746 error = gfs2_adjust_quota(ip, offset, qd->qd_change_sync,
711 (struct gfs2_quota_data *) 747 (struct gfs2_quota_data *)
712 qd->qd_gl->gl_lvb); 748 qd);
713 if (error) 749 if (error)
714 goto out_end_trans; 750 goto out_end_trans;
715 751
@@ -1050,6 +1086,15 @@ int gfs2_quota_refresh(struct gfs2_sbd *sdp, int user, u32 id)
1050 return error; 1086 return error;
1051} 1087}
1052 1088
1089static void gfs2_quota_change_in(struct gfs2_quota_change_host *qc, const void *buf)
1090{
1091 const struct gfs2_quota_change *str = buf;
1092
1093 qc->qc_change = be64_to_cpu(str->qc_change);
1094 qc->qc_flags = be32_to_cpu(str->qc_flags);
1095 qc->qc_id = be32_to_cpu(str->qc_id);
1096}
1097
1053int gfs2_quota_init(struct gfs2_sbd *sdp) 1098int gfs2_quota_init(struct gfs2_sbd *sdp)
1054{ 1099{
1055 struct gfs2_inode *ip = GFS2_I(sdp->sd_qc_inode); 1100 struct gfs2_inode *ip = GFS2_I(sdp->sd_qc_inode);
diff --git a/fs/gfs2/recovery.c b/fs/gfs2/recovery.c
index 8bc182c7e2ef..5ada38c99a2c 100644
--- a/fs/gfs2/recovery.c
+++ b/fs/gfs2/recovery.c
@@ -116,6 +116,22 @@ void gfs2_revoke_clean(struct gfs2_sbd *sdp)
116 } 116 }
117} 117}
118 118
119static int gfs2_log_header_in(struct gfs2_log_header_host *lh, const void *buf)
120{
121 const struct gfs2_log_header *str = buf;
122
123 if (str->lh_header.mh_magic != cpu_to_be32(GFS2_MAGIC) ||
124 str->lh_header.mh_type != cpu_to_be32(GFS2_METATYPE_LH))
125 return 1;
126
127 lh->lh_sequence = be64_to_cpu(str->lh_sequence);
128 lh->lh_flags = be32_to_cpu(str->lh_flags);
129 lh->lh_tail = be32_to_cpu(str->lh_tail);
130 lh->lh_blkno = be32_to_cpu(str->lh_blkno);
131 lh->lh_hash = be32_to_cpu(str->lh_hash);
132 return 0;
133}
134
119/** 135/**
120 * get_log_header - read the log header for a given segment 136 * get_log_header - read the log header for a given segment
121 * @jd: the journal 137 * @jd: the journal
@@ -147,12 +163,10 @@ static int get_log_header(struct gfs2_jdesc *jd, unsigned int blk,
147 sizeof(u32)); 163 sizeof(u32));
148 hash = crc32_le(hash, (unsigned char const *)&nothing, sizeof(nothing)); 164 hash = crc32_le(hash, (unsigned char const *)&nothing, sizeof(nothing));
149 hash ^= (u32)~0; 165 hash ^= (u32)~0;
150 gfs2_log_header_in(&lh, bh->b_data); 166 error = gfs2_log_header_in(&lh, bh->b_data);
151 brelse(bh); 167 brelse(bh);
152 168
153 if (lh.lh_header.mh_magic != GFS2_MAGIC || 169 if (error || lh.lh_blkno != blk || lh.lh_hash != hash)
154 lh.lh_header.mh_type != GFS2_METATYPE_LH ||
155 lh.lh_blkno != blk || lh.lh_hash != hash)
156 return 1; 170 return 1;
157 171
158 *head = lh; 172 *head = lh;
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
index 1727f5012efe..e4e040625153 100644
--- a/fs/gfs2/rgrp.c
+++ b/fs/gfs2/rgrp.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. 2 * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
3 * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. 3 * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
4 * 4 *
5 * This copyrighted material is made available to anyone wishing to use, 5 * This copyrighted material is made available to anyone wishing to use,
6 * modify, copy, or redistribute it subject to the terms and conditions 6 * modify, copy, or redistribute it subject to the terms and conditions
@@ -28,6 +28,7 @@
28#include "ops_file.h" 28#include "ops_file.h"
29#include "util.h" 29#include "util.h"
30#include "log.h" 30#include "log.h"
31#include "inode.h"
31 32
32#define BFITNOENT ((u32)~0) 33#define BFITNOENT ((u32)~0)
33 34
@@ -50,6 +51,9 @@ static const char valid_change[16] = {
50 1, 0, 0, 0 51 1, 0, 0, 0
51}; 52};
52 53
54static u32 rgblk_search(struct gfs2_rgrpd *rgd, u32 goal,
55 unsigned char old_state, unsigned char new_state);
56
53/** 57/**
54 * gfs2_setbit - Set a bit in the bitmaps 58 * gfs2_setbit - Set a bit in the bitmaps
55 * @buffer: the buffer that holds the bitmaps 59 * @buffer: the buffer that holds the bitmaps
@@ -204,7 +208,7 @@ void gfs2_rgrp_verify(struct gfs2_rgrpd *rgd)
204{ 208{
205 struct gfs2_sbd *sdp = rgd->rd_sbd; 209 struct gfs2_sbd *sdp = rgd->rd_sbd;
206 struct gfs2_bitmap *bi = NULL; 210 struct gfs2_bitmap *bi = NULL;
207 u32 length = rgd->rd_ri.ri_length; 211 u32 length = rgd->rd_length;
208 u32 count[4], tmp; 212 u32 count[4], tmp;
209 int buf, x; 213 int buf, x;
210 214
@@ -227,7 +231,7 @@ void gfs2_rgrp_verify(struct gfs2_rgrpd *rgd)
227 return; 231 return;
228 } 232 }
229 233
230 tmp = rgd->rd_ri.ri_data - 234 tmp = rgd->rd_data -
231 rgd->rd_rg.rg_free - 235 rgd->rd_rg.rg_free -
232 rgd->rd_rg.rg_dinodes; 236 rgd->rd_rg.rg_dinodes;
233 if (count[1] + count[2] != tmp) { 237 if (count[1] + count[2] != tmp) {
@@ -253,10 +257,10 @@ void gfs2_rgrp_verify(struct gfs2_rgrpd *rgd)
253 257
254} 258}
255 259
256static inline int rgrp_contains_block(struct gfs2_rindex_host *ri, u64 block) 260static inline int rgrp_contains_block(struct gfs2_rgrpd *rgd, u64 block)
257{ 261{
258 u64 first = ri->ri_data0; 262 u64 first = rgd->rd_data0;
259 u64 last = first + ri->ri_data; 263 u64 last = first + rgd->rd_data;
260 return first <= block && block < last; 264 return first <= block && block < last;
261} 265}
262 266
@@ -275,7 +279,7 @@ struct gfs2_rgrpd *gfs2_blk2rgrpd(struct gfs2_sbd *sdp, u64 blk)
275 spin_lock(&sdp->sd_rindex_spin); 279 spin_lock(&sdp->sd_rindex_spin);
276 280
277 list_for_each_entry(rgd, &sdp->sd_rindex_mru_list, rd_list_mru) { 281 list_for_each_entry(rgd, &sdp->sd_rindex_mru_list, rd_list_mru) {
278 if (rgrp_contains_block(&rgd->rd_ri, blk)) { 282 if (rgrp_contains_block(rgd, blk)) {
279 list_move(&rgd->rd_list_mru, &sdp->sd_rindex_mru_list); 283 list_move(&rgd->rd_list_mru, &sdp->sd_rindex_mru_list);
280 spin_unlock(&sdp->sd_rindex_spin); 284 spin_unlock(&sdp->sd_rindex_spin);
281 return rgd; 285 return rgd;
@@ -354,6 +358,15 @@ void gfs2_clear_rgrpd(struct gfs2_sbd *sdp)
354 mutex_unlock(&sdp->sd_rindex_mutex); 358 mutex_unlock(&sdp->sd_rindex_mutex);
355} 359}
356 360
361static void gfs2_rindex_print(const struct gfs2_rgrpd *rgd)
362{
363 printk(KERN_INFO " ri_addr = %llu\n", (unsigned long long)rgd->rd_addr);
364 printk(KERN_INFO " ri_length = %u\n", rgd->rd_length);
365 printk(KERN_INFO " ri_data0 = %llu\n", (unsigned long long)rgd->rd_data0);
366 printk(KERN_INFO " ri_data = %u\n", rgd->rd_data);
367 printk(KERN_INFO " ri_bitbytes = %u\n", rgd->rd_bitbytes);
368}
369
357/** 370/**
358 * gfs2_compute_bitstructs - Compute the bitmap sizes 371 * gfs2_compute_bitstructs - Compute the bitmap sizes
359 * @rgd: The resource group descriptor 372 * @rgd: The resource group descriptor
@@ -367,7 +380,7 @@ static int compute_bitstructs(struct gfs2_rgrpd *rgd)
367{ 380{
368 struct gfs2_sbd *sdp = rgd->rd_sbd; 381 struct gfs2_sbd *sdp = rgd->rd_sbd;
369 struct gfs2_bitmap *bi; 382 struct gfs2_bitmap *bi;
370 u32 length = rgd->rd_ri.ri_length; /* # blocks in hdr & bitmap */ 383 u32 length = rgd->rd_length; /* # blocks in hdr & bitmap */
371 u32 bytes_left, bytes; 384 u32 bytes_left, bytes;
372 int x; 385 int x;
373 386
@@ -378,7 +391,7 @@ static int compute_bitstructs(struct gfs2_rgrpd *rgd)
378 if (!rgd->rd_bits) 391 if (!rgd->rd_bits)
379 return -ENOMEM; 392 return -ENOMEM;
380 393
381 bytes_left = rgd->rd_ri.ri_bitbytes; 394 bytes_left = rgd->rd_bitbytes;
382 395
383 for (x = 0; x < length; x++) { 396 for (x = 0; x < length; x++) {
384 bi = rgd->rd_bits + x; 397 bi = rgd->rd_bits + x;
@@ -399,14 +412,14 @@ static int compute_bitstructs(struct gfs2_rgrpd *rgd)
399 } else if (x + 1 == length) { 412 } else if (x + 1 == length) {
400 bytes = bytes_left; 413 bytes = bytes_left;
401 bi->bi_offset = sizeof(struct gfs2_meta_header); 414 bi->bi_offset = sizeof(struct gfs2_meta_header);
402 bi->bi_start = rgd->rd_ri.ri_bitbytes - bytes_left; 415 bi->bi_start = rgd->rd_bitbytes - bytes_left;
403 bi->bi_len = bytes; 416 bi->bi_len = bytes;
404 /* other blocks */ 417 /* other blocks */
405 } else { 418 } else {
406 bytes = sdp->sd_sb.sb_bsize - 419 bytes = sdp->sd_sb.sb_bsize -
407 sizeof(struct gfs2_meta_header); 420 sizeof(struct gfs2_meta_header);
408 bi->bi_offset = sizeof(struct gfs2_meta_header); 421 bi->bi_offset = sizeof(struct gfs2_meta_header);
409 bi->bi_start = rgd->rd_ri.ri_bitbytes - bytes_left; 422 bi->bi_start = rgd->rd_bitbytes - bytes_left;
410 bi->bi_len = bytes; 423 bi->bi_len = bytes;
411 } 424 }
412 425
@@ -418,9 +431,9 @@ static int compute_bitstructs(struct gfs2_rgrpd *rgd)
418 return -EIO; 431 return -EIO;
419 } 432 }
420 bi = rgd->rd_bits + (length - 1); 433 bi = rgd->rd_bits + (length - 1);
421 if ((bi->bi_start + bi->bi_len) * GFS2_NBBY != rgd->rd_ri.ri_data) { 434 if ((bi->bi_start + bi->bi_len) * GFS2_NBBY != rgd->rd_data) {
422 if (gfs2_consist_rgrpd(rgd)) { 435 if (gfs2_consist_rgrpd(rgd)) {
423 gfs2_rindex_print(&rgd->rd_ri); 436 gfs2_rindex_print(rgd);
424 fs_err(sdp, "start=%u len=%u offset=%u\n", 437 fs_err(sdp, "start=%u len=%u offset=%u\n",
425 bi->bi_start, bi->bi_len, bi->bi_offset); 438 bi->bi_start, bi->bi_len, bi->bi_offset);
426 } 439 }
@@ -431,9 +444,104 @@ static int compute_bitstructs(struct gfs2_rgrpd *rgd)
431} 444}
432 445
433/** 446/**
434 * gfs2_ri_update - Pull in a new resource index from the disk 447 * gfs2_ri_total - Total up the file system space, according to the rindex.
448 *
449 */
450u64 gfs2_ri_total(struct gfs2_sbd *sdp)
451{
452 u64 total_data = 0;
453 struct inode *inode = sdp->sd_rindex;
454 struct gfs2_inode *ip = GFS2_I(inode);
455 char buf[sizeof(struct gfs2_rindex)];
456 struct file_ra_state ra_state;
457 int error, rgrps;
458
459 mutex_lock(&sdp->sd_rindex_mutex);
460 file_ra_state_init(&ra_state, inode->i_mapping);
461 for (rgrps = 0;; rgrps++) {
462 loff_t pos = rgrps * sizeof(struct gfs2_rindex);
463
464 if (pos + sizeof(struct gfs2_rindex) >= ip->i_di.di_size)
465 break;
466 error = gfs2_internal_read(ip, &ra_state, buf, &pos,
467 sizeof(struct gfs2_rindex));
468 if (error != sizeof(struct gfs2_rindex))
469 break;
470 total_data += be32_to_cpu(((struct gfs2_rindex *)buf)->ri_data);
471 }
472 mutex_unlock(&sdp->sd_rindex_mutex);
473 return total_data;
474}
475
476static void gfs2_rindex_in(struct gfs2_rgrpd *rgd, const void *buf)
477{
478 const struct gfs2_rindex *str = buf;
479
480 rgd->rd_addr = be64_to_cpu(str->ri_addr);
481 rgd->rd_length = be32_to_cpu(str->ri_length);
482 rgd->rd_data0 = be64_to_cpu(str->ri_data0);
483 rgd->rd_data = be32_to_cpu(str->ri_data);
484 rgd->rd_bitbytes = be32_to_cpu(str->ri_bitbytes);
485}
486
487/**
488 * read_rindex_entry - Pull in a new resource index entry from the disk
435 * @gl: The glock covering the rindex inode 489 * @gl: The glock covering the rindex inode
436 * 490 *
491 * Returns: 0 on success, error code otherwise
492 */
493
494static int read_rindex_entry(struct gfs2_inode *ip,
495 struct file_ra_state *ra_state)
496{
497 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
498 loff_t pos = sdp->sd_rgrps * sizeof(struct gfs2_rindex);
499 char buf[sizeof(struct gfs2_rindex)];
500 int error;
501 struct gfs2_rgrpd *rgd;
502
503 error = gfs2_internal_read(ip, ra_state, buf, &pos,
504 sizeof(struct gfs2_rindex));
505 if (!error)
506 return 0;
507 if (error != sizeof(struct gfs2_rindex)) {
508 if (error > 0)
509 error = -EIO;
510 return error;
511 }
512
513 rgd = kzalloc(sizeof(struct gfs2_rgrpd), GFP_NOFS);
514 error = -ENOMEM;
515 if (!rgd)
516 return error;
517
518 mutex_init(&rgd->rd_mutex);
519 lops_init_le(&rgd->rd_le, &gfs2_rg_lops);
520 rgd->rd_sbd = sdp;
521
522 list_add_tail(&rgd->rd_list, &sdp->sd_rindex_list);
523 list_add_tail(&rgd->rd_list_mru, &sdp->sd_rindex_mru_list);
524
525 gfs2_rindex_in(rgd, buf);
526 error = compute_bitstructs(rgd);
527 if (error)
528 return error;
529
530 error = gfs2_glock_get(sdp, rgd->rd_addr,
531 &gfs2_rgrp_glops, CREATE, &rgd->rd_gl);
532 if (error)
533 return error;
534
535 rgd->rd_gl->gl_object = rgd;
536 rgd->rd_rg_vn = rgd->rd_gl->gl_vn - 1;
537 rgd->rd_flags |= GFS2_RDF_CHECK;
538 return error;
539}
540
541/**
542 * gfs2_ri_update - Pull in a new resource index from the disk
543 * @ip: pointer to the rindex inode
544 *
437 * Returns: 0 on successful update, error code otherwise 545 * Returns: 0 on successful update, error code otherwise
438 */ 546 */
439 547
@@ -441,13 +549,11 @@ static int gfs2_ri_update(struct gfs2_inode *ip)
441{ 549{
442 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); 550 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
443 struct inode *inode = &ip->i_inode; 551 struct inode *inode = &ip->i_inode;
444 struct gfs2_rgrpd *rgd;
445 char buf[sizeof(struct gfs2_rindex)];
446 struct file_ra_state ra_state; 552 struct file_ra_state ra_state;
447 u64 junk = ip->i_di.di_size; 553 u64 rgrp_count = ip->i_di.di_size;
448 int error; 554 int error;
449 555
450 if (do_div(junk, sizeof(struct gfs2_rindex))) { 556 if (do_div(rgrp_count, sizeof(struct gfs2_rindex))) {
451 gfs2_consist_inode(ip); 557 gfs2_consist_inode(ip);
452 return -EIO; 558 return -EIO;
453 } 559 }
@@ -455,50 +561,50 @@ static int gfs2_ri_update(struct gfs2_inode *ip)
455 clear_rgrpdi(sdp); 561 clear_rgrpdi(sdp);
456 562
457 file_ra_state_init(&ra_state, inode->i_mapping); 563 file_ra_state_init(&ra_state, inode->i_mapping);
458 for (sdp->sd_rgrps = 0;; sdp->sd_rgrps++) { 564 for (sdp->sd_rgrps = 0; sdp->sd_rgrps < rgrp_count; sdp->sd_rgrps++) {
459 loff_t pos = sdp->sd_rgrps * sizeof(struct gfs2_rindex); 565 error = read_rindex_entry(ip, &ra_state);
460 error = gfs2_internal_read(ip, &ra_state, buf, &pos, 566 if (error) {
461 sizeof(struct gfs2_rindex)); 567 clear_rgrpdi(sdp);
462 if (!error) 568 return error;
463 break;
464 if (error != sizeof(struct gfs2_rindex)) {
465 if (error > 0)
466 error = -EIO;
467 goto fail;
468 } 569 }
570 }
469 571
470 rgd = kzalloc(sizeof(struct gfs2_rgrpd), GFP_NOFS); 572 sdp->sd_rindex_vn = ip->i_gl->gl_vn;
471 error = -ENOMEM; 573 return 0;
472 if (!rgd) 574}
473 goto fail;
474
475 mutex_init(&rgd->rd_mutex);
476 lops_init_le(&rgd->rd_le, &gfs2_rg_lops);
477 rgd->rd_sbd = sdp;
478
479 list_add_tail(&rgd->rd_list, &sdp->sd_rindex_list);
480 list_add_tail(&rgd->rd_list_mru, &sdp->sd_rindex_mru_list);
481
482 gfs2_rindex_in(&rgd->rd_ri, buf);
483 error = compute_bitstructs(rgd);
484 if (error)
485 goto fail;
486 575
487 error = gfs2_glock_get(sdp, rgd->rd_ri.ri_addr, 576/**
488 &gfs2_rgrp_glops, CREATE, &rgd->rd_gl); 577 * gfs2_ri_update_special - Pull in a new resource index from the disk
489 if (error) 578 *
490 goto fail; 579 * This is a special version that's safe to call from gfs2_inplace_reserve_i.
580 * In this case we know that we don't have any resource groups in memory yet.
581 *
582 * @ip: pointer to the rindex inode
583 *
584 * Returns: 0 on successful update, error code otherwise
585 */
586static int gfs2_ri_update_special(struct gfs2_inode *ip)
587{
588 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
589 struct inode *inode = &ip->i_inode;
590 struct file_ra_state ra_state;
591 int error;
491 592
492 rgd->rd_gl->gl_object = rgd; 593 file_ra_state_init(&ra_state, inode->i_mapping);
493 rgd->rd_rg_vn = rgd->rd_gl->gl_vn - 1; 594 for (sdp->sd_rgrps = 0;; sdp->sd_rgrps++) {
595 /* Ignore partials */
596 if ((sdp->sd_rgrps + 1) * sizeof(struct gfs2_rindex) >
597 ip->i_di.di_size)
598 break;
599 error = read_rindex_entry(ip, &ra_state);
600 if (error) {
601 clear_rgrpdi(sdp);
602 return error;
603 }
494 } 604 }
495 605
496 sdp->sd_rindex_vn = ip->i_gl->gl_vn; 606 sdp->sd_rindex_vn = ip->i_gl->gl_vn;
497 return 0; 607 return 0;
498
499fail:
500 clear_rgrpdi(sdp);
501 return error;
502} 608}
503 609
504/** 610/**
@@ -543,6 +649,28 @@ int gfs2_rindex_hold(struct gfs2_sbd *sdp, struct gfs2_holder *ri_gh)
543 return error; 649 return error;
544} 650}
545 651
652static void gfs2_rgrp_in(struct gfs2_rgrp_host *rg, const void *buf)
653{
654 const struct gfs2_rgrp *str = buf;
655
656 rg->rg_flags = be32_to_cpu(str->rg_flags);
657 rg->rg_free = be32_to_cpu(str->rg_free);
658 rg->rg_dinodes = be32_to_cpu(str->rg_dinodes);
659 rg->rg_igeneration = be64_to_cpu(str->rg_igeneration);
660}
661
662static void gfs2_rgrp_out(const struct gfs2_rgrp_host *rg, void *buf)
663{
664 struct gfs2_rgrp *str = buf;
665
666 str->rg_flags = cpu_to_be32(rg->rg_flags);
667 str->rg_free = cpu_to_be32(rg->rg_free);
668 str->rg_dinodes = cpu_to_be32(rg->rg_dinodes);
669 str->__pad = cpu_to_be32(0);
670 str->rg_igeneration = cpu_to_be64(rg->rg_igeneration);
671 memset(&str->rg_reserved, 0, sizeof(str->rg_reserved));
672}
673
546/** 674/**
547 * gfs2_rgrp_bh_get - Read in a RG's header and bitmaps 675 * gfs2_rgrp_bh_get - Read in a RG's header and bitmaps
548 * @rgd: the struct gfs2_rgrpd describing the RG to read in 676 * @rgd: the struct gfs2_rgrpd describing the RG to read in
@@ -557,7 +685,7 @@ int gfs2_rgrp_bh_get(struct gfs2_rgrpd *rgd)
557{ 685{
558 struct gfs2_sbd *sdp = rgd->rd_sbd; 686 struct gfs2_sbd *sdp = rgd->rd_sbd;
559 struct gfs2_glock *gl = rgd->rd_gl; 687 struct gfs2_glock *gl = rgd->rd_gl;
560 unsigned int length = rgd->rd_ri.ri_length; 688 unsigned int length = rgd->rd_length;
561 struct gfs2_bitmap *bi; 689 struct gfs2_bitmap *bi;
562 unsigned int x, y; 690 unsigned int x, y;
563 int error; 691 int error;
@@ -575,7 +703,7 @@ int gfs2_rgrp_bh_get(struct gfs2_rgrpd *rgd)
575 703
576 for (x = 0; x < length; x++) { 704 for (x = 0; x < length; x++) {
577 bi = rgd->rd_bits + x; 705 bi = rgd->rd_bits + x;
578 error = gfs2_meta_read(gl, rgd->rd_ri.ri_addr + x, 0, &bi->bi_bh); 706 error = gfs2_meta_read(gl, rgd->rd_addr + x, 0, &bi->bi_bh);
579 if (error) 707 if (error)
580 goto fail; 708 goto fail;
581 } 709 }
@@ -637,7 +765,7 @@ void gfs2_rgrp_bh_hold(struct gfs2_rgrpd *rgd)
637void gfs2_rgrp_bh_put(struct gfs2_rgrpd *rgd) 765void gfs2_rgrp_bh_put(struct gfs2_rgrpd *rgd)
638{ 766{
639 struct gfs2_sbd *sdp = rgd->rd_sbd; 767 struct gfs2_sbd *sdp = rgd->rd_sbd;
640 int x, length = rgd->rd_ri.ri_length; 768 int x, length = rgd->rd_length;
641 769
642 spin_lock(&sdp->sd_rindex_spin); 770 spin_lock(&sdp->sd_rindex_spin);
643 gfs2_assert_warn(rgd->rd_sbd, rgd->rd_bh_count); 771 gfs2_assert_warn(rgd->rd_sbd, rgd->rd_bh_count);
@@ -660,7 +788,7 @@ void gfs2_rgrp_bh_put(struct gfs2_rgrpd *rgd)
660void gfs2_rgrp_repolish_clones(struct gfs2_rgrpd *rgd) 788void gfs2_rgrp_repolish_clones(struct gfs2_rgrpd *rgd)
661{ 789{
662 struct gfs2_sbd *sdp = rgd->rd_sbd; 790 struct gfs2_sbd *sdp = rgd->rd_sbd;
663 unsigned int length = rgd->rd_ri.ri_length; 791 unsigned int length = rgd->rd_length;
664 unsigned int x; 792 unsigned int x;
665 793
666 for (x = 0; x < length; x++) { 794 for (x = 0; x < length; x++) {
@@ -722,6 +850,38 @@ static int try_rgrp_fit(struct gfs2_rgrpd *rgd, struct gfs2_alloc *al)
722} 850}
723 851
724/** 852/**
853 * try_rgrp_unlink - Look for any unlinked, allocated, but unused inodes
854 * @rgd: The rgrp
855 *
856 * Returns: The inode, if one has been found
857 */
858
859static struct inode *try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked)
860{
861 struct inode *inode;
862 u32 goal = 0;
863 u64 no_addr;
864
865 for(;;) {
866 goal = rgblk_search(rgd, goal, GFS2_BLKST_UNLINKED,
867 GFS2_BLKST_UNLINKED);
868 if (goal == 0)
869 return 0;
870 no_addr = goal + rgd->rd_data0;
871 if (no_addr <= *last_unlinked)
872 continue;
873 *last_unlinked = no_addr;
874 inode = gfs2_inode_lookup(rgd->rd_sbd->sd_vfs, DT_UNKNOWN,
875 no_addr, -1);
876 if (!IS_ERR(inode))
877 return inode;
878 }
879
880 rgd->rd_flags &= ~GFS2_RDF_CHECK;
881 return NULL;
882}
883
884/**
725 * recent_rgrp_first - get first RG from "recent" list 885 * recent_rgrp_first - get first RG from "recent" list
726 * @sdp: The GFS2 superblock 886 * @sdp: The GFS2 superblock
727 * @rglast: address of the rgrp used last 887 * @rglast: address of the rgrp used last
@@ -743,7 +903,7 @@ static struct gfs2_rgrpd *recent_rgrp_first(struct gfs2_sbd *sdp,
743 goto first; 903 goto first;
744 904
745 list_for_each_entry(rgd, &sdp->sd_rindex_recent_list, rd_recent) { 905 list_for_each_entry(rgd, &sdp->sd_rindex_recent_list, rd_recent) {
746 if (rgd->rd_ri.ri_addr == rglast) 906 if (rgd->rd_addr == rglast)
747 goto out; 907 goto out;
748 } 908 }
749 909
@@ -882,8 +1042,9 @@ static void forward_rgrp_set(struct gfs2_sbd *sdp, struct gfs2_rgrpd *rgd)
882 * Returns: errno 1042 * Returns: errno
883 */ 1043 */
884 1044
885static int get_local_rgrp(struct gfs2_inode *ip) 1045static struct inode *get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked)
886{ 1046{
1047 struct inode *inode = NULL;
887 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); 1048 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
888 struct gfs2_rgrpd *rgd, *begin = NULL; 1049 struct gfs2_rgrpd *rgd, *begin = NULL;
889 struct gfs2_alloc *al = &ip->i_alloc; 1050 struct gfs2_alloc *al = &ip->i_alloc;
@@ -903,7 +1064,11 @@ static int get_local_rgrp(struct gfs2_inode *ip)
903 case 0: 1064 case 0:
904 if (try_rgrp_fit(rgd, al)) 1065 if (try_rgrp_fit(rgd, al))
905 goto out; 1066 goto out;
1067 if (rgd->rd_flags & GFS2_RDF_CHECK)
1068 inode = try_rgrp_unlink(rgd, last_unlinked);
906 gfs2_glock_dq_uninit(&al->al_rgd_gh); 1069 gfs2_glock_dq_uninit(&al->al_rgd_gh);
1070 if (inode)
1071 return inode;
907 rgd = recent_rgrp_next(rgd, 1); 1072 rgd = recent_rgrp_next(rgd, 1);
908 break; 1073 break;
909 1074
@@ -912,7 +1077,7 @@ static int get_local_rgrp(struct gfs2_inode *ip)
912 break; 1077 break;
913 1078
914 default: 1079 default:
915 return error; 1080 return ERR_PTR(error);
916 } 1081 }
917 } 1082 }
918 1083
@@ -927,7 +1092,11 @@ static int get_local_rgrp(struct gfs2_inode *ip)
927 case 0: 1092 case 0:
928 if (try_rgrp_fit(rgd, al)) 1093 if (try_rgrp_fit(rgd, al))
929 goto out; 1094 goto out;
1095 if (rgd->rd_flags & GFS2_RDF_CHECK)
1096 inode = try_rgrp_unlink(rgd, last_unlinked);
930 gfs2_glock_dq_uninit(&al->al_rgd_gh); 1097 gfs2_glock_dq_uninit(&al->al_rgd_gh);
1098 if (inode)
1099 return inode;
931 break; 1100 break;
932 1101
933 case GLR_TRYFAILED: 1102 case GLR_TRYFAILED:
@@ -935,7 +1104,7 @@ static int get_local_rgrp(struct gfs2_inode *ip)
935 break; 1104 break;
936 1105
937 default: 1106 default:
938 return error; 1107 return ERR_PTR(error);
939 } 1108 }
940 1109
941 rgd = gfs2_rgrpd_get_next(rgd); 1110 rgd = gfs2_rgrpd_get_next(rgd);
@@ -944,7 +1113,7 @@ static int get_local_rgrp(struct gfs2_inode *ip)
944 1113
945 if (rgd == begin) { 1114 if (rgd == begin) {
946 if (++loops >= 3) 1115 if (++loops >= 3)
947 return -ENOSPC; 1116 return ERR_PTR(-ENOSPC);
948 if (!skipped) 1117 if (!skipped)
949 loops++; 1118 loops++;
950 flags = 0; 1119 flags = 0;
@@ -954,7 +1123,7 @@ static int get_local_rgrp(struct gfs2_inode *ip)
954 } 1123 }
955 1124
956out: 1125out:
957 ip->i_last_rg_alloc = rgd->rd_ri.ri_addr; 1126 ip->i_last_rg_alloc = rgd->rd_addr;
958 1127
959 if (begin) { 1128 if (begin) {
960 recent_rgrp_add(rgd); 1129 recent_rgrp_add(rgd);
@@ -964,7 +1133,7 @@ out:
964 forward_rgrp_set(sdp, rgd); 1133 forward_rgrp_set(sdp, rgd);
965 } 1134 }
966 1135
967 return 0; 1136 return NULL;
968} 1137}
969 1138
970/** 1139/**
@@ -978,19 +1147,33 @@ int gfs2_inplace_reserve_i(struct gfs2_inode *ip, char *file, unsigned int line)
978{ 1147{
979 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); 1148 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
980 struct gfs2_alloc *al = &ip->i_alloc; 1149 struct gfs2_alloc *al = &ip->i_alloc;
981 int error; 1150 struct inode *inode;
1151 int error = 0;
1152 u64 last_unlinked = 0;
982 1153
983 if (gfs2_assert_warn(sdp, al->al_requested)) 1154 if (gfs2_assert_warn(sdp, al->al_requested))
984 return -EINVAL; 1155 return -EINVAL;
985 1156
986 error = gfs2_rindex_hold(sdp, &al->al_ri_gh); 1157try_again:
1158 /* We need to hold the rindex unless the inode we're using is
1159 the rindex itself, in which case it's already held. */
1160 if (ip != GFS2_I(sdp->sd_rindex))
1161 error = gfs2_rindex_hold(sdp, &al->al_ri_gh);
1162 else if (!sdp->sd_rgrps) /* We may not have the rindex read in, so: */
1163 error = gfs2_ri_update_special(ip);
1164
987 if (error) 1165 if (error)
988 return error; 1166 return error;
989 1167
990 error = get_local_rgrp(ip); 1168 inode = get_local_rgrp(ip, &last_unlinked);
991 if (error) { 1169 if (inode) {
992 gfs2_glock_dq_uninit(&al->al_ri_gh); 1170 if (ip != GFS2_I(sdp->sd_rindex))
993 return error; 1171 gfs2_glock_dq_uninit(&al->al_ri_gh);
1172 if (IS_ERR(inode))
1173 return PTR_ERR(inode);
1174 iput(inode);
1175 gfs2_log_flush(sdp, NULL);
1176 goto try_again;
994 } 1177 }
995 1178
996 al->al_file = file; 1179 al->al_file = file;
@@ -1019,7 +1202,8 @@ void gfs2_inplace_release(struct gfs2_inode *ip)
1019 1202
1020 al->al_rgd = NULL; 1203 al->al_rgd = NULL;
1021 gfs2_glock_dq_uninit(&al->al_rgd_gh); 1204 gfs2_glock_dq_uninit(&al->al_rgd_gh);
1022 gfs2_glock_dq_uninit(&al->al_ri_gh); 1205 if (ip != GFS2_I(sdp->sd_rindex))
1206 gfs2_glock_dq_uninit(&al->al_ri_gh);
1023} 1207}
1024 1208
1025/** 1209/**
@@ -1037,8 +1221,8 @@ unsigned char gfs2_get_block_type(struct gfs2_rgrpd *rgd, u64 block)
1037 unsigned int buf; 1221 unsigned int buf;
1038 unsigned char type; 1222 unsigned char type;
1039 1223
1040 length = rgd->rd_ri.ri_length; 1224 length = rgd->rd_length;
1041 rgrp_block = block - rgd->rd_ri.ri_data0; 1225 rgrp_block = block - rgd->rd_data0;
1042 1226
1043 for (buf = 0; buf < length; buf++) { 1227 for (buf = 0; buf < length; buf++) {
1044 bi = rgd->rd_bits + buf; 1228 bi = rgd->rd_bits + buf;
@@ -1077,10 +1261,10 @@ unsigned char gfs2_get_block_type(struct gfs2_rgrpd *rgd, u64 block)
1077 */ 1261 */
1078 1262
1079static u32 rgblk_search(struct gfs2_rgrpd *rgd, u32 goal, 1263static u32 rgblk_search(struct gfs2_rgrpd *rgd, u32 goal,
1080 unsigned char old_state, unsigned char new_state) 1264 unsigned char old_state, unsigned char new_state)
1081{ 1265{
1082 struct gfs2_bitmap *bi = NULL; 1266 struct gfs2_bitmap *bi = NULL;
1083 u32 length = rgd->rd_ri.ri_length; 1267 u32 length = rgd->rd_length;
1084 u32 blk = 0; 1268 u32 blk = 0;
1085 unsigned int buf, x; 1269 unsigned int buf, x;
1086 1270
@@ -1118,17 +1302,18 @@ static u32 rgblk_search(struct gfs2_rgrpd *rgd, u32 goal,
1118 goal = 0; 1302 goal = 0;
1119 } 1303 }
1120 1304
1121 if (gfs2_assert_withdraw(rgd->rd_sbd, x <= length)) 1305 if (old_state != new_state) {
1122 blk = 0; 1306 gfs2_assert_withdraw(rgd->rd_sbd, blk != BFITNOENT);
1123 1307
1124 gfs2_trans_add_bh(rgd->rd_gl, bi->bi_bh, 1); 1308 gfs2_trans_add_bh(rgd->rd_gl, bi->bi_bh, 1);
1125 gfs2_setbit(rgd, bi->bi_bh->b_data + bi->bi_offset, 1309 gfs2_setbit(rgd, bi->bi_bh->b_data + bi->bi_offset,
1126 bi->bi_len, blk, new_state);
1127 if (bi->bi_clone)
1128 gfs2_setbit(rgd, bi->bi_clone + bi->bi_offset,
1129 bi->bi_len, blk, new_state); 1310 bi->bi_len, blk, new_state);
1311 if (bi->bi_clone)
1312 gfs2_setbit(rgd, bi->bi_clone + bi->bi_offset,
1313 bi->bi_len, blk, new_state);
1314 }
1130 1315
1131 return bi->bi_start * GFS2_NBBY + blk; 1316 return (blk == BFITNOENT) ? 0 : (bi->bi_start * GFS2_NBBY) + blk;
1132} 1317}
1133 1318
1134/** 1319/**
@@ -1156,9 +1341,9 @@ static struct gfs2_rgrpd *rgblk_free(struct gfs2_sbd *sdp, u64 bstart,
1156 return NULL; 1341 return NULL;
1157 } 1342 }
1158 1343
1159 length = rgd->rd_ri.ri_length; 1344 length = rgd->rd_length;
1160 1345
1161 rgrp_blk = bstart - rgd->rd_ri.ri_data0; 1346 rgrp_blk = bstart - rgd->rd_data0;
1162 1347
1163 while (blen--) { 1348 while (blen--) {
1164 for (buf = 0; buf < length; buf++) { 1349 for (buf = 0; buf < length; buf++) {
@@ -1202,15 +1387,15 @@ u64 gfs2_alloc_data(struct gfs2_inode *ip)
1202 u32 goal, blk; 1387 u32 goal, blk;
1203 u64 block; 1388 u64 block;
1204 1389
1205 if (rgrp_contains_block(&rgd->rd_ri, ip->i_di.di_goal_data)) 1390 if (rgrp_contains_block(rgd, ip->i_di.di_goal_data))
1206 goal = ip->i_di.di_goal_data - rgd->rd_ri.ri_data0; 1391 goal = ip->i_di.di_goal_data - rgd->rd_data0;
1207 else 1392 else
1208 goal = rgd->rd_last_alloc_data; 1393 goal = rgd->rd_last_alloc_data;
1209 1394
1210 blk = rgblk_search(rgd, goal, GFS2_BLKST_FREE, GFS2_BLKST_USED); 1395 blk = rgblk_search(rgd, goal, GFS2_BLKST_FREE, GFS2_BLKST_USED);
1211 rgd->rd_last_alloc_data = blk; 1396 rgd->rd_last_alloc_data = blk;
1212 1397
1213 block = rgd->rd_ri.ri_data0 + blk; 1398 block = rgd->rd_data0 + blk;
1214 ip->i_di.di_goal_data = block; 1399 ip->i_di.di_goal_data = block;
1215 1400
1216 gfs2_assert_withdraw(sdp, rgd->rd_rg.rg_free); 1401 gfs2_assert_withdraw(sdp, rgd->rd_rg.rg_free);
@@ -1246,15 +1431,15 @@ u64 gfs2_alloc_meta(struct gfs2_inode *ip)
1246 u32 goal, blk; 1431 u32 goal, blk;
1247 u64 block; 1432 u64 block;
1248 1433
1249 if (rgrp_contains_block(&rgd->rd_ri, ip->i_di.di_goal_meta)) 1434 if (rgrp_contains_block(rgd, ip->i_di.di_goal_meta))
1250 goal = ip->i_di.di_goal_meta - rgd->rd_ri.ri_data0; 1435 goal = ip->i_di.di_goal_meta - rgd->rd_data0;
1251 else 1436 else
1252 goal = rgd->rd_last_alloc_meta; 1437 goal = rgd->rd_last_alloc_meta;
1253 1438
1254 blk = rgblk_search(rgd, goal, GFS2_BLKST_FREE, GFS2_BLKST_USED); 1439 blk = rgblk_search(rgd, goal, GFS2_BLKST_FREE, GFS2_BLKST_USED);
1255 rgd->rd_last_alloc_meta = blk; 1440 rgd->rd_last_alloc_meta = blk;
1256 1441
1257 block = rgd->rd_ri.ri_data0 + blk; 1442 block = rgd->rd_data0 + blk;
1258 ip->i_di.di_goal_meta = block; 1443 ip->i_di.di_goal_meta = block;
1259 1444
1260 gfs2_assert_withdraw(sdp, rgd->rd_rg.rg_free); 1445 gfs2_assert_withdraw(sdp, rgd->rd_rg.rg_free);
@@ -1296,7 +1481,7 @@ u64 gfs2_alloc_di(struct gfs2_inode *dip, u64 *generation)
1296 1481
1297 rgd->rd_last_alloc_meta = blk; 1482 rgd->rd_last_alloc_meta = blk;
1298 1483
1299 block = rgd->rd_ri.ri_data0 + blk; 1484 block = rgd->rd_data0 + blk;
1300 1485
1301 gfs2_assert_withdraw(sdp, rgd->rd_rg.rg_free); 1486 gfs2_assert_withdraw(sdp, rgd->rd_rg.rg_free);
1302 rgd->rd_rg.rg_free--; 1487 rgd->rd_rg.rg_free--;
@@ -1379,7 +1564,7 @@ void gfs2_unlink_di(struct inode *inode)
1379 struct gfs2_inode *ip = GFS2_I(inode); 1564 struct gfs2_inode *ip = GFS2_I(inode);
1380 struct gfs2_sbd *sdp = GFS2_SB(inode); 1565 struct gfs2_sbd *sdp = GFS2_SB(inode);
1381 struct gfs2_rgrpd *rgd; 1566 struct gfs2_rgrpd *rgd;
1382 u64 blkno = ip->i_num.no_addr; 1567 u64 blkno = ip->i_no_addr;
1383 1568
1384 rgd = rgblk_free(sdp, blkno, 1, GFS2_BLKST_UNLINKED); 1569 rgd = rgblk_free(sdp, blkno, 1, GFS2_BLKST_UNLINKED);
1385 if (!rgd) 1570 if (!rgd)
@@ -1414,9 +1599,9 @@ static void gfs2_free_uninit_di(struct gfs2_rgrpd *rgd, u64 blkno)
1414 1599
1415void gfs2_free_di(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip) 1600void gfs2_free_di(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip)
1416{ 1601{
1417 gfs2_free_uninit_di(rgd, ip->i_num.no_addr); 1602 gfs2_free_uninit_di(rgd, ip->i_no_addr);
1418 gfs2_quota_change(ip, -1, ip->i_inode.i_uid, ip->i_inode.i_gid); 1603 gfs2_quota_change(ip, -1, ip->i_inode.i_uid, ip->i_inode.i_gid);
1419 gfs2_meta_wipe(ip, ip->i_num.no_addr, 1); 1604 gfs2_meta_wipe(ip, ip->i_no_addr, 1);
1420} 1605}
1421 1606
1422/** 1607/**
diff --git a/fs/gfs2/rgrp.h b/fs/gfs2/rgrp.h
index b01e0cfc99b5..b4c6adfc6f2e 100644
--- a/fs/gfs2/rgrp.h
+++ b/fs/gfs2/rgrp.h
@@ -65,5 +65,6 @@ void gfs2_rlist_add(struct gfs2_sbd *sdp, struct gfs2_rgrp_list *rlist,
65void gfs2_rlist_alloc(struct gfs2_rgrp_list *rlist, unsigned int state, 65void gfs2_rlist_alloc(struct gfs2_rgrp_list *rlist, unsigned int state,
66 int flags); 66 int flags);
67void gfs2_rlist_free(struct gfs2_rgrp_list *rlist); 67void gfs2_rlist_free(struct gfs2_rgrp_list *rlist);
68u64 gfs2_ri_total(struct gfs2_sbd *sdp);
68 69
69#endif /* __RGRP_DOT_H__ */ 70#endif /* __RGRP_DOT_H__ */
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c
index 4fdda974dc83..f916b9740c75 100644
--- a/fs/gfs2/super.c
+++ b/fs/gfs2/super.c
@@ -95,8 +95,8 @@ int gfs2_check_sb(struct gfs2_sbd *sdp, struct gfs2_sb_host *sb, int silent)
95{ 95{
96 unsigned int x; 96 unsigned int x;
97 97
98 if (sb->sb_header.mh_magic != GFS2_MAGIC || 98 if (sb->sb_magic != GFS2_MAGIC ||
99 sb->sb_header.mh_type != GFS2_METATYPE_SB) { 99 sb->sb_type != GFS2_METATYPE_SB) {
100 if (!silent) 100 if (!silent)
101 printk(KERN_WARNING "GFS2: not a GFS2 filesystem\n"); 101 printk(KERN_WARNING "GFS2: not a GFS2 filesystem\n");
102 return -EINVAL; 102 return -EINVAL;
@@ -174,10 +174,31 @@ static int end_bio_io_page(struct bio *bio, unsigned int bytes_done, int error)
174 return 0; 174 return 0;
175} 175}
176 176
177static void gfs2_sb_in(struct gfs2_sb_host *sb, const void *buf)
178{
179 const struct gfs2_sb *str = buf;
180
181 sb->sb_magic = be32_to_cpu(str->sb_header.mh_magic);
182 sb->sb_type = be32_to_cpu(str->sb_header.mh_type);
183 sb->sb_format = be32_to_cpu(str->sb_header.mh_format);
184 sb->sb_fs_format = be32_to_cpu(str->sb_fs_format);
185 sb->sb_multihost_format = be32_to_cpu(str->sb_multihost_format);
186 sb->sb_bsize = be32_to_cpu(str->sb_bsize);
187 sb->sb_bsize_shift = be32_to_cpu(str->sb_bsize_shift);
188 sb->sb_master_dir.no_addr = be64_to_cpu(str->sb_master_dir.no_addr);
189 sb->sb_master_dir.no_formal_ino = be64_to_cpu(str->sb_master_dir.no_formal_ino);
190 sb->sb_root_dir.no_addr = be64_to_cpu(str->sb_root_dir.no_addr);
191 sb->sb_root_dir.no_formal_ino = be64_to_cpu(str->sb_root_dir.no_formal_ino);
192
193 memcpy(sb->sb_lockproto, str->sb_lockproto, GFS2_LOCKNAME_LEN);
194 memcpy(sb->sb_locktable, str->sb_locktable, GFS2_LOCKNAME_LEN);
195}
196
177/** 197/**
178 * gfs2_read_super - Read the gfs2 super block from disk 198 * gfs2_read_super - Read the gfs2 super block from disk
179 * @sb: The VFS super block 199 * @sdp: The GFS2 super block
180 * @sector: The location of the super block 200 * @sector: The location of the super block
201 * @error: The error code to return
181 * 202 *
182 * This uses the bio functions to read the super block from disk 203 * This uses the bio functions to read the super block from disk
183 * because we want to be 100% sure that we never read cached data. 204 * because we want to be 100% sure that we never read cached data.
@@ -189,17 +210,19 @@ static int end_bio_io_page(struct bio *bio, unsigned int bytes_done, int error)
189 * the master directory (contains pointers to journals etc) and the 210 * the master directory (contains pointers to journals etc) and the
190 * root directory. 211 * root directory.
191 * 212 *
192 * Returns: A page containing the sb or NULL 213 * Returns: 0 on success or error
193 */ 214 */
194 215
195struct page *gfs2_read_super(struct super_block *sb, sector_t sector) 216int gfs2_read_super(struct gfs2_sbd *sdp, sector_t sector)
196{ 217{
218 struct super_block *sb = sdp->sd_vfs;
219 struct gfs2_sb *p;
197 struct page *page; 220 struct page *page;
198 struct bio *bio; 221 struct bio *bio;
199 222
200 page = alloc_page(GFP_KERNEL); 223 page = alloc_page(GFP_KERNEL);
201 if (unlikely(!page)) 224 if (unlikely(!page))
202 return NULL; 225 return -ENOBUFS;
203 226
204 ClearPageUptodate(page); 227 ClearPageUptodate(page);
205 ClearPageDirty(page); 228 ClearPageDirty(page);
@@ -208,7 +231,7 @@ struct page *gfs2_read_super(struct super_block *sb, sector_t sector)
208 bio = bio_alloc(GFP_KERNEL, 1); 231 bio = bio_alloc(GFP_KERNEL, 1);
209 if (unlikely(!bio)) { 232 if (unlikely(!bio)) {
210 __free_page(page); 233 __free_page(page);
211 return NULL; 234 return -ENOBUFS;
212 } 235 }
213 236
214 bio->bi_sector = sector * (sb->s_blocksize >> 9); 237 bio->bi_sector = sector * (sb->s_blocksize >> 9);
@@ -222,9 +245,13 @@ struct page *gfs2_read_super(struct super_block *sb, sector_t sector)
222 bio_put(bio); 245 bio_put(bio);
223 if (!PageUptodate(page)) { 246 if (!PageUptodate(page)) {
224 __free_page(page); 247 __free_page(page);
225 return NULL; 248 return -EIO;
226 } 249 }
227 return page; 250 p = kmap(page);
251 gfs2_sb_in(&sdp->sd_sb, p);
252 kunmap(page);
253 __free_page(page);
254 return 0;
228} 255}
229 256
230/** 257/**
@@ -241,19 +268,13 @@ int gfs2_read_sb(struct gfs2_sbd *sdp, struct gfs2_glock *gl, int silent)
241 u32 tmp_blocks; 268 u32 tmp_blocks;
242 unsigned int x; 269 unsigned int x;
243 int error; 270 int error;
244 struct page *page;
245 char *sb;
246 271
247 page = gfs2_read_super(sdp->sd_vfs, GFS2_SB_ADDR >> sdp->sd_fsb2bb_shift); 272 error = gfs2_read_super(sdp, GFS2_SB_ADDR >> sdp->sd_fsb2bb_shift);
248 if (!page) { 273 if (error) {
249 if (!silent) 274 if (!silent)
250 fs_err(sdp, "can't read superblock\n"); 275 fs_err(sdp, "can't read superblock\n");
251 return -EIO; 276 return error;
252 } 277 }
253 sb = kmap(page);
254 gfs2_sb_in(&sdp->sd_sb, sb);
255 kunmap(page);
256 __free_page(page);
257 278
258 error = gfs2_check_sb(sdp, &sdp->sd_sb, silent); 279 error = gfs2_check_sb(sdp, &sdp->sd_sb, silent);
259 if (error) 280 if (error)
@@ -360,7 +381,7 @@ int gfs2_jindex_hold(struct gfs2_sbd *sdp, struct gfs2_holder *ji_gh)
360 name.len = sprintf(buf, "journal%u", sdp->sd_journals); 381 name.len = sprintf(buf, "journal%u", sdp->sd_journals);
361 name.hash = gfs2_disk_hash(name.name, name.len); 382 name.hash = gfs2_disk_hash(name.name, name.len);
362 383
363 error = gfs2_dir_search(sdp->sd_jindex, &name, NULL, NULL); 384 error = gfs2_dir_check(sdp->sd_jindex, &name, NULL);
364 if (error == -ENOENT) { 385 if (error == -ENOENT) {
365 error = 0; 386 error = 0;
366 break; 387 break;
@@ -593,6 +614,24 @@ int gfs2_make_fs_ro(struct gfs2_sbd *sdp)
593 return error; 614 return error;
594} 615}
595 616
617static void gfs2_statfs_change_in(struct gfs2_statfs_change_host *sc, const void *buf)
618{
619 const struct gfs2_statfs_change *str = buf;
620
621 sc->sc_total = be64_to_cpu(str->sc_total);
622 sc->sc_free = be64_to_cpu(str->sc_free);
623 sc->sc_dinodes = be64_to_cpu(str->sc_dinodes);
624}
625
626static void gfs2_statfs_change_out(const struct gfs2_statfs_change_host *sc, void *buf)
627{
628 struct gfs2_statfs_change *str = buf;
629
630 str->sc_total = cpu_to_be64(sc->sc_total);
631 str->sc_free = cpu_to_be64(sc->sc_free);
632 str->sc_dinodes = cpu_to_be64(sc->sc_dinodes);
633}
634
596int gfs2_statfs_init(struct gfs2_sbd *sdp) 635int gfs2_statfs_init(struct gfs2_sbd *sdp)
597{ 636{
598 struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode); 637 struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode);
@@ -772,7 +811,7 @@ static int statfs_slow_fill(struct gfs2_rgrpd *rgd,
772 struct gfs2_statfs_change_host *sc) 811 struct gfs2_statfs_change_host *sc)
773{ 812{
774 gfs2_rgrp_verify(rgd); 813 gfs2_rgrp_verify(rgd);
775 sc->sc_total += rgd->rd_ri.ri_data; 814 sc->sc_total += rgd->rd_data;
776 sc->sc_free += rgd->rd_rg.rg_free; 815 sc->sc_free += rgd->rd_rg.rg_free;
777 sc->sc_dinodes += rgd->rd_rg.rg_dinodes; 816 sc->sc_dinodes += rgd->rd_rg.rg_dinodes;
778 return 0; 817 return 0;
diff --git a/fs/gfs2/super.h b/fs/gfs2/super.h
index e590b2df11dc..60a870e430be 100644
--- a/fs/gfs2/super.h
+++ b/fs/gfs2/super.h
@@ -16,7 +16,7 @@ void gfs2_tune_init(struct gfs2_tune *gt);
16 16
17int gfs2_check_sb(struct gfs2_sbd *sdp, struct gfs2_sb_host *sb, int silent); 17int gfs2_check_sb(struct gfs2_sbd *sdp, struct gfs2_sb_host *sb, int silent);
18int gfs2_read_sb(struct gfs2_sbd *sdp, struct gfs2_glock *gl, int silent); 18int gfs2_read_sb(struct gfs2_sbd *sdp, struct gfs2_glock *gl, int silent);
19struct page *gfs2_read_super(struct super_block *sb, sector_t sector); 19int gfs2_read_super(struct gfs2_sbd *sdp, sector_t sector);
20 20
21static inline unsigned int gfs2_jindex_size(struct gfs2_sbd *sdp) 21static inline unsigned int gfs2_jindex_size(struct gfs2_sbd *sdp)
22{ 22{
diff --git a/fs/gfs2/util.c b/fs/gfs2/util.c
index 601eaa1b9ed6..424a0774eda8 100644
--- a/fs/gfs2/util.c
+++ b/fs/gfs2/util.c
@@ -115,8 +115,8 @@ int gfs2_consist_inode_i(struct gfs2_inode *ip, int cluster_wide,
115 "GFS2: fsid=%s: inode = %llu %llu\n" 115 "GFS2: fsid=%s: inode = %llu %llu\n"
116 "GFS2: fsid=%s: function = %s, file = %s, line = %u\n", 116 "GFS2: fsid=%s: function = %s, file = %s, line = %u\n",
117 sdp->sd_fsname, 117 sdp->sd_fsname,
118 sdp->sd_fsname, (unsigned long long)ip->i_num.no_formal_ino, 118 sdp->sd_fsname, (unsigned long long)ip->i_no_formal_ino,
119 (unsigned long long)ip->i_num.no_addr, 119 (unsigned long long)ip->i_no_addr,
120 sdp->sd_fsname, function, file, line); 120 sdp->sd_fsname, function, file, line);
121 return rv; 121 return rv;
122} 122}
@@ -137,7 +137,7 @@ int gfs2_consist_rgrpd_i(struct gfs2_rgrpd *rgd, int cluster_wide,
137 "GFS2: fsid=%s: RG = %llu\n" 137 "GFS2: fsid=%s: RG = %llu\n"
138 "GFS2: fsid=%s: function = %s, file = %s, line = %u\n", 138 "GFS2: fsid=%s: function = %s, file = %s, line = %u\n",
139 sdp->sd_fsname, 139 sdp->sd_fsname,
140 sdp->sd_fsname, (unsigned long long)rgd->rd_ri.ri_addr, 140 sdp->sd_fsname, (unsigned long long)rgd->rd_addr,
141 sdp->sd_fsname, function, file, line); 141 sdp->sd_fsname, function, file, line);
142 return rv; 142 return rv;
143} 143}
diff --git a/fs/hfs/inode.c b/fs/hfs/inode.c
index 9a934db0bd8a..bc835f272a6e 100644
--- a/fs/hfs/inode.c
+++ b/fs/hfs/inode.c
@@ -607,7 +607,7 @@ static const struct file_operations hfs_file_operations = {
607 .write = do_sync_write, 607 .write = do_sync_write,
608 .aio_write = generic_file_aio_write, 608 .aio_write = generic_file_aio_write,
609 .mmap = generic_file_mmap, 609 .mmap = generic_file_mmap,
610 .sendfile = generic_file_sendfile, 610 .splice_read = generic_file_splice_read,
611 .fsync = file_fsync, 611 .fsync = file_fsync,
612 .open = hfs_file_open, 612 .open = hfs_file_open,
613 .release = hfs_file_release, 613 .release = hfs_file_release,
diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c
index 45dab5d6cc10..409ce5429c91 100644
--- a/fs/hfsplus/inode.c
+++ b/fs/hfsplus/inode.c
@@ -288,7 +288,7 @@ static const struct file_operations hfsplus_file_operations = {
288 .write = do_sync_write, 288 .write = do_sync_write,
289 .aio_write = generic_file_aio_write, 289 .aio_write = generic_file_aio_write,
290 .mmap = generic_file_mmap, 290 .mmap = generic_file_mmap,
291 .sendfile = generic_file_sendfile, 291 .splice_read = generic_file_splice_read,
292 .fsync = file_fsync, 292 .fsync = file_fsync,
293 .open = hfsplus_file_open, 293 .open = hfsplus_file_open,
294 .release = hfsplus_file_release, 294 .release = hfsplus_file_release,
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c
index 8286491dbf31..c77862032e84 100644
--- a/fs/hostfs/hostfs_kern.c
+++ b/fs/hostfs/hostfs_kern.c
@@ -390,7 +390,7 @@ int hostfs_fsync(struct file *file, struct dentry *dentry, int datasync)
390static const struct file_operations hostfs_file_fops = { 390static const struct file_operations hostfs_file_fops = {
391 .llseek = generic_file_llseek, 391 .llseek = generic_file_llseek,
392 .read = do_sync_read, 392 .read = do_sync_read,
393 .sendfile = generic_file_sendfile, 393 .splice_read = generic_file_splice_read,
394 .aio_read = generic_file_aio_read, 394 .aio_read = generic_file_aio_read,
395 .aio_write = generic_file_aio_write, 395 .aio_write = generic_file_aio_write,
396 .write = do_sync_write, 396 .write = do_sync_write,
diff --git a/fs/hpfs/file.c b/fs/hpfs/file.c
index b4eafc0f1e54..5b53e5c5d8df 100644
--- a/fs/hpfs/file.c
+++ b/fs/hpfs/file.c
@@ -129,7 +129,7 @@ const struct file_operations hpfs_file_ops =
129 .mmap = generic_file_mmap, 129 .mmap = generic_file_mmap,
130 .release = hpfs_file_release, 130 .release = hpfs_file_release,
131 .fsync = hpfs_file_fsync, 131 .fsync = hpfs_file_fsync,
132 .sendfile = generic_file_sendfile, 132 .splice_read = generic_file_splice_read,
133}; 133};
134 134
135const struct inode_operations hpfs_file_iops = 135const struct inode_operations hpfs_file_iops =
diff --git a/fs/jffs2/file.c b/fs/jffs2/file.c
index 99871279a1ed..c2530197be0c 100644
--- a/fs/jffs2/file.c
+++ b/fs/jffs2/file.c
@@ -47,7 +47,7 @@ const struct file_operations jffs2_file_operations =
47 .ioctl = jffs2_ioctl, 47 .ioctl = jffs2_ioctl,
48 .mmap = generic_file_readonly_mmap, 48 .mmap = generic_file_readonly_mmap,
49 .fsync = jffs2_fsync, 49 .fsync = jffs2_fsync,
50 .sendfile = generic_file_sendfile 50 .splice_read = generic_file_splice_read,
51}; 51};
52 52
53/* jffs2_file_inode_operations */ 53/* jffs2_file_inode_operations */
diff --git a/fs/jfs/endian24.h b/fs/jfs/endian24.h
index 79494c4f2b10..fa92f7f1d0d0 100644
--- a/fs/jfs/endian24.h
+++ b/fs/jfs/endian24.h
@@ -29,7 +29,7 @@
29 __u32 __x = (x); \ 29 __u32 __x = (x); \
30 ((__u32)( \ 30 ((__u32)( \
31 ((__x & (__u32)0x000000ffUL) << 16) | \ 31 ((__x & (__u32)0x000000ffUL) << 16) | \
32 (__x & (__u32)0x0000ff00UL) | \ 32 (__x & (__u32)0x0000ff00UL) | \
33 ((__x & (__u32)0x00ff0000UL) >> 16) )); \ 33 ((__x & (__u32)0x00ff0000UL) >> 16) )); \
34}) 34})
35 35
diff --git a/fs/jfs/file.c b/fs/jfs/file.c
index f7f8eff19b7b..87eb93694af7 100644
--- a/fs/jfs/file.c
+++ b/fs/jfs/file.c
@@ -108,7 +108,6 @@ const struct file_operations jfs_file_operations = {
108 .aio_read = generic_file_aio_read, 108 .aio_read = generic_file_aio_read,
109 .aio_write = generic_file_aio_write, 109 .aio_write = generic_file_aio_write,
110 .mmap = generic_file_mmap, 110 .mmap = generic_file_mmap,
111 .sendfile = generic_file_sendfile,
112 .splice_read = generic_file_splice_read, 111 .splice_read = generic_file_splice_read,
113 .splice_write = generic_file_splice_write, 112 .splice_write = generic_file_splice_write,
114 .fsync = jfs_fsync, 113 .fsync = jfs_fsync,
diff --git a/fs/jfs/jfs_debug.c b/fs/jfs/jfs_debug.c
index 9c5d59632aac..887f5759e536 100644
--- a/fs/jfs/jfs_debug.c
+++ b/fs/jfs/jfs_debug.c
@@ -26,34 +26,6 @@
26#include "jfs_filsys.h" 26#include "jfs_filsys.h"
27#include "jfs_debug.h" 27#include "jfs_debug.h"
28 28
29#ifdef CONFIG_JFS_DEBUG
30void dump_mem(char *label, void *data, int length)
31{
32 int i, j;
33 int *intptr = data;
34 char *charptr = data;
35 char buf[10], line[80];
36
37 printk("%s: dump of %d bytes of data at 0x%p\n\n", label, length,
38 data);
39 for (i = 0; i < length; i += 16) {
40 line[0] = 0;
41 for (j = 0; (j < 4) && (i + j * 4 < length); j++) {
42 sprintf(buf, " %08x", intptr[i / 4 + j]);
43 strcat(line, buf);
44 }
45 buf[0] = ' ';
46 buf[2] = 0;
47 for (j = 0; (j < 16) && (i + j < length); j++) {
48 buf[1] =
49 isprint(charptr[i + j]) ? charptr[i + j] : '.';
50 strcat(line, buf);
51 }
52 printk("%s\n", line);
53 }
54}
55#endif
56
57#ifdef PROC_FS_JFS /* see jfs_debug.h */ 29#ifdef PROC_FS_JFS /* see jfs_debug.h */
58 30
59static struct proc_dir_entry *base; 31static struct proc_dir_entry *base;
diff --git a/fs/jfs/jfs_debug.h b/fs/jfs/jfs_debug.h
index 7378798f0b21..044c1e654cc0 100644
--- a/fs/jfs/jfs_debug.h
+++ b/fs/jfs/jfs_debug.h
@@ -62,7 +62,6 @@ extern void jfs_proc_clean(void);
62 62
63extern int jfsloglevel; 63extern int jfsloglevel;
64 64
65extern void dump_mem(char *label, void *data, int length);
66extern int jfs_txanchor_read(char *, char **, off_t, int, int *, void *); 65extern int jfs_txanchor_read(char *, char **, off_t, int, int *, void *);
67 66
68/* information message: e.g., configuration, major event */ 67/* information message: e.g., configuration, major event */
@@ -94,7 +93,6 @@ extern int jfs_txanchor_read(char *, char **, off_t, int, int *, void *);
94 * --------- 93 * ---------
95 */ 94 */
96#else /* CONFIG_JFS_DEBUG */ 95#else /* CONFIG_JFS_DEBUG */
97#define dump_mem(label,data,length) do {} while (0)
98#define ASSERT(p) do {} while (0) 96#define ASSERT(p) do {} while (0)
99#define jfs_info(fmt, arg...) do {} while (0) 97#define jfs_info(fmt, arg...) do {} while (0)
100#define jfs_debug(fmt, arg...) do {} while (0) 98#define jfs_debug(fmt, arg...) do {} while (0)
diff --git a/fs/jfs/jfs_dinode.h b/fs/jfs/jfs_dinode.h
index 40b20111383c..c387540d3425 100644
--- a/fs/jfs/jfs_dinode.h
+++ b/fs/jfs/jfs_dinode.h
@@ -19,23 +19,23 @@
19#define _H_JFS_DINODE 19#define _H_JFS_DINODE
20 20
21/* 21/*
22 * jfs_dinode.h: on-disk inode manager 22 * jfs_dinode.h: on-disk inode manager
23 */ 23 */
24 24
25#define INODESLOTSIZE 128 25#define INODESLOTSIZE 128
26#define L2INODESLOTSIZE 7 26#define L2INODESLOTSIZE 7
27#define log2INODESIZE 9 /* log2(bytes per dinode) */ 27#define log2INODESIZE 9 /* log2(bytes per dinode) */
28 28
29 29
30/* 30/*
31 * on-disk inode : 512 bytes 31 * on-disk inode : 512 bytes
32 * 32 *
33 * note: align 64-bit fields on 8-byte boundary. 33 * note: align 64-bit fields on 8-byte boundary.
34 */ 34 */
35struct dinode { 35struct dinode {
36 /* 36 /*
37 * I. base area (128 bytes) 37 * I. base area (128 bytes)
38 * ------------------------ 38 * ------------------------
39 * 39 *
40 * define generic/POSIX attributes 40 * define generic/POSIX attributes
41 */ 41 */
@@ -70,16 +70,16 @@ struct dinode {
70 __le32 di_acltype; /* 4: Type of ACL */ 70 __le32 di_acltype; /* 4: Type of ACL */
71 71
72 /* 72 /*
73 * Extension Areas. 73 * Extension Areas.
74 * 74 *
75 * Historically, the inode was partitioned into 4 128-byte areas, 75 * Historically, the inode was partitioned into 4 128-byte areas,
76 * the last 3 being defined as unions which could have multiple 76 * the last 3 being defined as unions which could have multiple
77 * uses. The first 96 bytes had been completely unused until 77 * uses. The first 96 bytes had been completely unused until
78 * an index table was added to the directory. It is now more 78 * an index table was added to the directory. It is now more
79 * useful to describe the last 3/4 of the inode as a single 79 * useful to describe the last 3/4 of the inode as a single
80 * union. We would probably be better off redesigning the 80 * union. We would probably be better off redesigning the
81 * entire structure from scratch, but we don't want to break 81 * entire structure from scratch, but we don't want to break
82 * commonality with OS/2's JFS at this time. 82 * commonality with OS/2's JFS at this time.
83 */ 83 */
84 union { 84 union {
85 struct { 85 struct {
@@ -95,7 +95,7 @@ struct dinode {
95 } _dir; /* (384) */ 95 } _dir; /* (384) */
96#define di_dirtable u._dir._table 96#define di_dirtable u._dir._table
97#define di_dtroot u._dir._dtroot 97#define di_dtroot u._dir._dtroot
98#define di_parent di_dtroot.header.idotdot 98#define di_parent di_dtroot.header.idotdot
99#define di_DASD di_dtroot.header.DASD 99#define di_DASD di_dtroot.header.DASD
100 100
101 struct { 101 struct {
@@ -127,14 +127,14 @@ struct dinode {
127#define di_inlinedata u._file._u2._special._u 127#define di_inlinedata u._file._u2._special._u
128#define di_rdev u._file._u2._special._u._rdev 128#define di_rdev u._file._u2._special._u._rdev
129#define di_fastsymlink u._file._u2._special._u._fastsymlink 129#define di_fastsymlink u._file._u2._special._u._fastsymlink
130#define di_inlineea u._file._u2._special._inlineea 130#define di_inlineea u._file._u2._special._inlineea
131 } u; 131 } u;
132}; 132};
133 133
134/* extended mode bits (on-disk inode di_mode) */ 134/* extended mode bits (on-disk inode di_mode) */
135#define IFJOURNAL 0x00010000 /* journalled file */ 135#define IFJOURNAL 0x00010000 /* journalled file */
136#define ISPARSE 0x00020000 /* sparse file enabled */ 136#define ISPARSE 0x00020000 /* sparse file enabled */
137#define INLINEEA 0x00040000 /* inline EA area free */ 137#define INLINEEA 0x00040000 /* inline EA area free */
138#define ISWAPFILE 0x00800000 /* file open for pager swap space */ 138#define ISWAPFILE 0x00800000 /* file open for pager swap space */
139 139
140/* more extended mode bits: attributes for OS/2 */ 140/* more extended mode bits: attributes for OS/2 */
diff --git a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c
index f3b1ebb22280..e1985066b1c6 100644
--- a/fs/jfs/jfs_dmap.c
+++ b/fs/jfs/jfs_dmap.c
@@ -154,12 +154,12 @@ static const s8 budtab[256] = {
154 * the in-core descriptor is initialized from disk. 154 * the in-core descriptor is initialized from disk.
155 * 155 *
156 * PARAMETERS: 156 * PARAMETERS:
157 * ipbmap - pointer to in-core inode for the block map. 157 * ipbmap - pointer to in-core inode for the block map.
158 * 158 *
159 * RETURN VALUES: 159 * RETURN VALUES:
160 * 0 - success 160 * 0 - success
161 * -ENOMEM - insufficient memory 161 * -ENOMEM - insufficient memory
162 * -EIO - i/o error 162 * -EIO - i/o error
163 */ 163 */
164int dbMount(struct inode *ipbmap) 164int dbMount(struct inode *ipbmap)
165{ 165{
@@ -232,11 +232,11 @@ int dbMount(struct inode *ipbmap)
232 * the memory for this descriptor is freed. 232 * the memory for this descriptor is freed.
233 * 233 *
234 * PARAMETERS: 234 * PARAMETERS:
235 * ipbmap - pointer to in-core inode for the block map. 235 * ipbmap - pointer to in-core inode for the block map.
236 * 236 *
237 * RETURN VALUES: 237 * RETURN VALUES:
238 * 0 - success 238 * 0 - success
239 * -EIO - i/o error 239 * -EIO - i/o error
240 */ 240 */
241int dbUnmount(struct inode *ipbmap, int mounterror) 241int dbUnmount(struct inode *ipbmap, int mounterror)
242{ 242{
@@ -320,13 +320,13 @@ int dbSync(struct inode *ipbmap)
320 * at a time. 320 * at a time.
321 * 321 *
322 * PARAMETERS: 322 * PARAMETERS:
323 * ip - pointer to in-core inode; 323 * ip - pointer to in-core inode;
324 * blkno - starting block number to be freed. 324 * blkno - starting block number to be freed.
325 * nblocks - number of blocks to be freed. 325 * nblocks - number of blocks to be freed.
326 * 326 *
327 * RETURN VALUES: 327 * RETURN VALUES:
328 * 0 - success 328 * 0 - success
329 * -EIO - i/o error 329 * -EIO - i/o error
330 */ 330 */
331int dbFree(struct inode *ip, s64 blkno, s64 nblocks) 331int dbFree(struct inode *ip, s64 blkno, s64 nblocks)
332{ 332{
@@ -395,23 +395,23 @@ int dbFree(struct inode *ip, s64 blkno, s64 nblocks)
395/* 395/*
396 * NAME: dbUpdatePMap() 396 * NAME: dbUpdatePMap()
397 * 397 *
398 * FUNCTION: update the allocation state (free or allocate) of the 398 * FUNCTION: update the allocation state (free or allocate) of the
399 * specified block range in the persistent block allocation map. 399 * specified block range in the persistent block allocation map.
400 * 400 *
401 * the blocks will be updated in the persistent map one 401 * the blocks will be updated in the persistent map one
402 * dmap at a time. 402 * dmap at a time.
403 * 403 *
404 * PARAMETERS: 404 * PARAMETERS:
405 * ipbmap - pointer to in-core inode for the block map. 405 * ipbmap - pointer to in-core inode for the block map.
406 * free - 'true' if block range is to be freed from the persistent 406 * free - 'true' if block range is to be freed from the persistent
407 * map; 'false' if it is to be allocated. 407 * map; 'false' if it is to be allocated.
408 * blkno - starting block number of the range. 408 * blkno - starting block number of the range.
409 * nblocks - number of contiguous blocks in the range. 409 * nblocks - number of contiguous blocks in the range.
410 * tblk - transaction block; 410 * tblk - transaction block;
411 * 411 *
412 * RETURN VALUES: 412 * RETURN VALUES:
413 * 0 - success 413 * 0 - success
414 * -EIO - i/o error 414 * -EIO - i/o error
415 */ 415 */
416int 416int
417dbUpdatePMap(struct inode *ipbmap, 417dbUpdatePMap(struct inode *ipbmap,
@@ -573,7 +573,7 @@ dbUpdatePMap(struct inode *ipbmap,
573/* 573/*
574 * NAME: dbNextAG() 574 * NAME: dbNextAG()
575 * 575 *
576 * FUNCTION: find the preferred allocation group for new allocations. 576 * FUNCTION: find the preferred allocation group for new allocations.
577 * 577 *
578 * Within the allocation groups, we maintain a preferred 578 * Within the allocation groups, we maintain a preferred
579 * allocation group which consists of a group with at least 579 * allocation group which consists of a group with at least
@@ -589,10 +589,10 @@ dbUpdatePMap(struct inode *ipbmap,
589 * empty ags around for large allocations. 589 * empty ags around for large allocations.
590 * 590 *
591 * PARAMETERS: 591 * PARAMETERS:
592 * ipbmap - pointer to in-core inode for the block map. 592 * ipbmap - pointer to in-core inode for the block map.
593 * 593 *
594 * RETURN VALUES: 594 * RETURN VALUES:
595 * the preferred allocation group number. 595 * the preferred allocation group number.
596 */ 596 */
597int dbNextAG(struct inode *ipbmap) 597int dbNextAG(struct inode *ipbmap)
598{ 598{
@@ -656,7 +656,7 @@ unlock:
656/* 656/*
657 * NAME: dbAlloc() 657 * NAME: dbAlloc()
658 * 658 *
659 * FUNCTION: attempt to allocate a specified number of contiguous free 659 * FUNCTION: attempt to allocate a specified number of contiguous free
660 * blocks from the working allocation block map. 660 * blocks from the working allocation block map.
661 * 661 *
662 * the block allocation policy uses hints and a multi-step 662 * the block allocation policy uses hints and a multi-step
@@ -680,16 +680,16 @@ unlock:
680 * size or requests that specify no hint value. 680 * size or requests that specify no hint value.
681 * 681 *
682 * PARAMETERS: 682 * PARAMETERS:
683 * ip - pointer to in-core inode; 683 * ip - pointer to in-core inode;
684 * hint - allocation hint. 684 * hint - allocation hint.
685 * nblocks - number of contiguous blocks in the range. 685 * nblocks - number of contiguous blocks in the range.
686 * results - on successful return, set to the starting block number 686 * results - on successful return, set to the starting block number
687 * of the newly allocated contiguous range. 687 * of the newly allocated contiguous range.
688 * 688 *
689 * RETURN VALUES: 689 * RETURN VALUES:
690 * 0 - success 690 * 0 - success
691 * -ENOSPC - insufficient disk resources 691 * -ENOSPC - insufficient disk resources
692 * -EIO - i/o error 692 * -EIO - i/o error
693 */ 693 */
694int dbAlloc(struct inode *ip, s64 hint, s64 nblocks, s64 * results) 694int dbAlloc(struct inode *ip, s64 hint, s64 nblocks, s64 * results)
695{ 695{
@@ -706,12 +706,6 @@ int dbAlloc(struct inode *ip, s64 hint, s64 nblocks, s64 * results)
706 /* assert that nblocks is valid */ 706 /* assert that nblocks is valid */
707 assert(nblocks > 0); 707 assert(nblocks > 0);
708 708
709#ifdef _STILL_TO_PORT
710 /* DASD limit check F226941 */
711 if (OVER_LIMIT(ip, nblocks))
712 return -ENOSPC;
713#endif /* _STILL_TO_PORT */
714
715 /* get the log2 number of blocks to be allocated. 709 /* get the log2 number of blocks to be allocated.
716 * if the number of blocks is not a log2 multiple, 710 * if the number of blocks is not a log2 multiple,
717 * it will be rounded up to the next log2 multiple. 711 * it will be rounded up to the next log2 multiple.
@@ -720,7 +714,6 @@ int dbAlloc(struct inode *ip, s64 hint, s64 nblocks, s64 * results)
720 714
721 bmp = JFS_SBI(ip->i_sb)->bmap; 715 bmp = JFS_SBI(ip->i_sb)->bmap;
722 716
723//retry: /* serialize w.r.t.extendfs() */
724 mapSize = bmp->db_mapsize; 717 mapSize = bmp->db_mapsize;
725 718
726 /* the hint should be within the map */ 719 /* the hint should be within the map */
@@ -879,17 +872,17 @@ int dbAlloc(struct inode *ip, s64 hint, s64 nblocks, s64 * results)
879/* 872/*
880 * NAME: dbAllocExact() 873 * NAME: dbAllocExact()
881 * 874 *
882 * FUNCTION: try to allocate the requested extent; 875 * FUNCTION: try to allocate the requested extent;
883 * 876 *
884 * PARAMETERS: 877 * PARAMETERS:
885 * ip - pointer to in-core inode; 878 * ip - pointer to in-core inode;
886 * blkno - extent address; 879 * blkno - extent address;
887 * nblocks - extent length; 880 * nblocks - extent length;
888 * 881 *
889 * RETURN VALUES: 882 * RETURN VALUES:
890 * 0 - success 883 * 0 - success
891 * -ENOSPC - insufficient disk resources 884 * -ENOSPC - insufficient disk resources
892 * -EIO - i/o error 885 * -EIO - i/o error
893 */ 886 */
894int dbAllocExact(struct inode *ip, s64 blkno, int nblocks) 887int dbAllocExact(struct inode *ip, s64 blkno, int nblocks)
895{ 888{
@@ -946,7 +939,7 @@ int dbAllocExact(struct inode *ip, s64 blkno, int nblocks)
946/* 939/*
947 * NAME: dbReAlloc() 940 * NAME: dbReAlloc()
948 * 941 *
949 * FUNCTION: attempt to extend a current allocation by a specified 942 * FUNCTION: attempt to extend a current allocation by a specified
950 * number of blocks. 943 * number of blocks.
951 * 944 *
952 * this routine attempts to satisfy the allocation request 945 * this routine attempts to satisfy the allocation request
@@ -959,21 +952,21 @@ int dbAllocExact(struct inode *ip, s64 blkno, int nblocks)
959 * number of blocks required. 952 * number of blocks required.
960 * 953 *
961 * PARAMETERS: 954 * PARAMETERS:
962 * ip - pointer to in-core inode requiring allocation. 955 * ip - pointer to in-core inode requiring allocation.
963 * blkno - starting block of the current allocation. 956 * blkno - starting block of the current allocation.
964 * nblocks - number of contiguous blocks within the current 957 * nblocks - number of contiguous blocks within the current
965 * allocation. 958 * allocation.
966 * addnblocks - number of blocks to add to the allocation. 959 * addnblocks - number of blocks to add to the allocation.
967 * results - on successful return, set to the starting block number 960 * results - on successful return, set to the starting block number
968 * of the existing allocation if the existing allocation 961 * of the existing allocation if the existing allocation
969 * was extended in place or to a newly allocated contiguous 962 * was extended in place or to a newly allocated contiguous
970 * range if the existing allocation could not be extended 963 * range if the existing allocation could not be extended
971 * in place. 964 * in place.
972 * 965 *
973 * RETURN VALUES: 966 * RETURN VALUES:
974 * 0 - success 967 * 0 - success
975 * -ENOSPC - insufficient disk resources 968 * -ENOSPC - insufficient disk resources
976 * -EIO - i/o error 969 * -EIO - i/o error
977 */ 970 */
978int 971int
979dbReAlloc(struct inode *ip, 972dbReAlloc(struct inode *ip,
@@ -1004,7 +997,7 @@ dbReAlloc(struct inode *ip,
1004/* 997/*
1005 * NAME: dbExtend() 998 * NAME: dbExtend()
1006 * 999 *
1007 * FUNCTION: attempt to extend a current allocation by a specified 1000 * FUNCTION: attempt to extend a current allocation by a specified
1008 * number of blocks. 1001 * number of blocks.
1009 * 1002 *
1010 * this routine attempts to satisfy the allocation request 1003 * this routine attempts to satisfy the allocation request
@@ -1013,16 +1006,16 @@ dbReAlloc(struct inode *ip,
1013 * immediately following the current allocation. 1006 * immediately following the current allocation.
1014 * 1007 *
1015 * PARAMETERS: 1008 * PARAMETERS:
1016 * ip - pointer to in-core inode requiring allocation. 1009 * ip - pointer to in-core inode requiring allocation.
1017 * blkno - starting block of the current allocation. 1010 * blkno - starting block of the current allocation.
1018 * nblocks - number of contiguous blocks within the current 1011 * nblocks - number of contiguous blocks within the current
1019 * allocation. 1012 * allocation.
1020 * addnblocks - number of blocks to add to the allocation. 1013 * addnblocks - number of blocks to add to the allocation.
1021 * 1014 *
1022 * RETURN VALUES: 1015 * RETURN VALUES:
1023 * 0 - success 1016 * 0 - success
1024 * -ENOSPC - insufficient disk resources 1017 * -ENOSPC - insufficient disk resources
1025 * -EIO - i/o error 1018 * -EIO - i/o error
1026 */ 1019 */
1027static int dbExtend(struct inode *ip, s64 blkno, s64 nblocks, s64 addnblocks) 1020static int dbExtend(struct inode *ip, s64 blkno, s64 nblocks, s64 addnblocks)
1028{ 1021{
@@ -1109,19 +1102,19 @@ static int dbExtend(struct inode *ip, s64 blkno, s64 nblocks, s64 addnblocks)
1109/* 1102/*
1110 * NAME: dbAllocNext() 1103 * NAME: dbAllocNext()
1111 * 1104 *
1112 * FUNCTION: attempt to allocate the blocks of the specified block 1105 * FUNCTION: attempt to allocate the blocks of the specified block
1113 * range within a dmap. 1106 * range within a dmap.
1114 * 1107 *
1115 * PARAMETERS: 1108 * PARAMETERS:
1116 * bmp - pointer to bmap descriptor 1109 * bmp - pointer to bmap descriptor
1117 * dp - pointer to dmap. 1110 * dp - pointer to dmap.
1118 * blkno - starting block number of the range. 1111 * blkno - starting block number of the range.
1119 * nblocks - number of contiguous free blocks of the range. 1112 * nblocks - number of contiguous free blocks of the range.
1120 * 1113 *
1121 * RETURN VALUES: 1114 * RETURN VALUES:
1122 * 0 - success 1115 * 0 - success
1123 * -ENOSPC - insufficient disk resources 1116 * -ENOSPC - insufficient disk resources
1124 * -EIO - i/o error 1117 * -EIO - i/o error
1125 * 1118 *
1126 * serialization: IREAD_LOCK(ipbmap) held on entry/exit; 1119 * serialization: IREAD_LOCK(ipbmap) held on entry/exit;
1127 */ 1120 */
@@ -1233,7 +1226,7 @@ static int dbAllocNext(struct bmap * bmp, struct dmap * dp, s64 blkno,
1233/* 1226/*
1234 * NAME: dbAllocNear() 1227 * NAME: dbAllocNear()
1235 * 1228 *
1236 * FUNCTION: attempt to allocate a number of contiguous free blocks near 1229 * FUNCTION: attempt to allocate a number of contiguous free blocks near
1237 * a specified block (hint) within a dmap. 1230 * a specified block (hint) within a dmap.
1238 * 1231 *
1239 * starting with the dmap leaf that covers the hint, we'll 1232 * starting with the dmap leaf that covers the hint, we'll
@@ -1242,18 +1235,18 @@ static int dbAllocNext(struct bmap * bmp, struct dmap * dp, s64 blkno,
1242 * the desired free space. 1235 * the desired free space.
1243 * 1236 *
1244 * PARAMETERS: 1237 * PARAMETERS:
1245 * bmp - pointer to bmap descriptor 1238 * bmp - pointer to bmap descriptor
1246 * dp - pointer to dmap. 1239 * dp - pointer to dmap.
1247 * blkno - block number to allocate near. 1240 * blkno - block number to allocate near.
1248 * nblocks - actual number of contiguous free blocks desired. 1241 * nblocks - actual number of contiguous free blocks desired.
1249 * l2nb - log2 number of contiguous free blocks desired. 1242 * l2nb - log2 number of contiguous free blocks desired.
1250 * results - on successful return, set to the starting block number 1243 * results - on successful return, set to the starting block number
1251 * of the newly allocated range. 1244 * of the newly allocated range.
1252 * 1245 *
1253 * RETURN VALUES: 1246 * RETURN VALUES:
1254 * 0 - success 1247 * 0 - success
1255 * -ENOSPC - insufficient disk resources 1248 * -ENOSPC - insufficient disk resources
1256 * -EIO - i/o error 1249 * -EIO - i/o error
1257 * 1250 *
1258 * serialization: IREAD_LOCK(ipbmap) held on entry/exit; 1251 * serialization: IREAD_LOCK(ipbmap) held on entry/exit;
1259 */ 1252 */
@@ -1316,7 +1309,7 @@ dbAllocNear(struct bmap * bmp,
1316/* 1309/*
1317 * NAME: dbAllocAG() 1310 * NAME: dbAllocAG()
1318 * 1311 *
1319 * FUNCTION: attempt to allocate the specified number of contiguous 1312 * FUNCTION: attempt to allocate the specified number of contiguous
1320 * free blocks within the specified allocation group. 1313 * free blocks within the specified allocation group.
1321 * 1314 *
1322 * unless the allocation group size is equal to the number 1315 * unless the allocation group size is equal to the number
@@ -1353,17 +1346,17 @@ dbAllocNear(struct bmap * bmp,
1353 * the allocation group. 1346 * the allocation group.
1354 * 1347 *
1355 * PARAMETERS: 1348 * PARAMETERS:
1356 * bmp - pointer to bmap descriptor 1349 * bmp - pointer to bmap descriptor
1357 * agno - allocation group number. 1350 * agno - allocation group number.
1358 * nblocks - actual number of contiguous free blocks desired. 1351 * nblocks - actual number of contiguous free blocks desired.
1359 * l2nb - log2 number of contiguous free blocks desired. 1352 * l2nb - log2 number of contiguous free blocks desired.
1360 * results - on successful return, set to the starting block number 1353 * results - on successful return, set to the starting block number
1361 * of the newly allocated range. 1354 * of the newly allocated range.
1362 * 1355 *
1363 * RETURN VALUES: 1356 * RETURN VALUES:
1364 * 0 - success 1357 * 0 - success
1365 * -ENOSPC - insufficient disk resources 1358 * -ENOSPC - insufficient disk resources
1366 * -EIO - i/o error 1359 * -EIO - i/o error
1367 * 1360 *
1368 * note: IWRITE_LOCK(ipmap) held on entry/exit; 1361 * note: IWRITE_LOCK(ipmap) held on entry/exit;
1369 */ 1362 */
@@ -1546,7 +1539,7 @@ dbAllocAG(struct bmap * bmp, int agno, s64 nblocks, int l2nb, s64 * results)
1546/* 1539/*
1547 * NAME: dbAllocAny() 1540 * NAME: dbAllocAny()
1548 * 1541 *
1549 * FUNCTION: attempt to allocate the specified number of contiguous 1542 * FUNCTION: attempt to allocate the specified number of contiguous
1550 * free blocks anywhere in the file system. 1543 * free blocks anywhere in the file system.
1551 * 1544 *
1552 * dbAllocAny() attempts to find the sufficient free space by 1545 * dbAllocAny() attempts to find the sufficient free space by
@@ -1556,16 +1549,16 @@ dbAllocAG(struct bmap * bmp, int agno, s64 nblocks, int l2nb, s64 * results)
1556 * desired free space is allocated. 1549 * desired free space is allocated.
1557 * 1550 *
1558 * PARAMETERS: 1551 * PARAMETERS:
1559 * bmp - pointer to bmap descriptor 1552 * bmp - pointer to bmap descriptor
1560 * nblocks - actual number of contiguous free blocks desired. 1553 * nblocks - actual number of contiguous free blocks desired.
1561 * l2nb - log2 number of contiguous free blocks desired. 1554 * l2nb - log2 number of contiguous free blocks desired.
1562 * results - on successful return, set to the starting block number 1555 * results - on successful return, set to the starting block number
1563 * of the newly allocated range. 1556 * of the newly allocated range.
1564 * 1557 *
1565 * RETURN VALUES: 1558 * RETURN VALUES:
1566 * 0 - success 1559 * 0 - success
1567 * -ENOSPC - insufficient disk resources 1560 * -ENOSPC - insufficient disk resources
1568 * -EIO - i/o error 1561 * -EIO - i/o error
1569 * 1562 *
1570 * serialization: IWRITE_LOCK(ipbmap) held on entry/exit; 1563 * serialization: IWRITE_LOCK(ipbmap) held on entry/exit;
1571 */ 1564 */
@@ -1598,9 +1591,9 @@ static int dbAllocAny(struct bmap * bmp, s64 nblocks, int l2nb, s64 * results)
1598/* 1591/*
1599 * NAME: dbFindCtl() 1592 * NAME: dbFindCtl()
1600 * 1593 *
1601 * FUNCTION: starting at a specified dmap control page level and block 1594 * FUNCTION: starting at a specified dmap control page level and block
1602 * number, search down the dmap control levels for a range of 1595 * number, search down the dmap control levels for a range of
1603 * contiguous free blocks large enough to satisfy an allocation 1596 * contiguous free blocks large enough to satisfy an allocation
1604 * request for the specified number of free blocks. 1597 * request for the specified number of free blocks.
1605 * 1598 *
1606 * if sufficient contiguous free blocks are found, this routine 1599 * if sufficient contiguous free blocks are found, this routine
@@ -1609,17 +1602,17 @@ static int dbAllocAny(struct bmap * bmp, s64 nblocks, int l2nb, s64 * results)
1609 * is sufficient in size. 1602 * is sufficient in size.
1610 * 1603 *
1611 * PARAMETERS: 1604 * PARAMETERS:
1612 * bmp - pointer to bmap descriptor 1605 * bmp - pointer to bmap descriptor
1613 * level - starting dmap control page level. 1606 * level - starting dmap control page level.
1614 * l2nb - log2 number of contiguous free blocks desired. 1607 * l2nb - log2 number of contiguous free blocks desired.
1615 * *blkno - on entry, starting block number for conducting the search. 1608 * *blkno - on entry, starting block number for conducting the search.
1616 * on successful return, the first block within a dmap page 1609 * on successful return, the first block within a dmap page
1617 * that contains or starts a range of contiguous free blocks. 1610 * that contains or starts a range of contiguous free blocks.
1618 * 1611 *
1619 * RETURN VALUES: 1612 * RETURN VALUES:
1620 * 0 - success 1613 * 0 - success
1621 * -ENOSPC - insufficient disk resources 1614 * -ENOSPC - insufficient disk resources
1622 * -EIO - i/o error 1615 * -EIO - i/o error
1623 * 1616 *
1624 * serialization: IWRITE_LOCK(ipbmap) held on entry/exit; 1617 * serialization: IWRITE_LOCK(ipbmap) held on entry/exit;
1625 */ 1618 */
@@ -1699,7 +1692,7 @@ static int dbFindCtl(struct bmap * bmp, int l2nb, int level, s64 * blkno)
1699/* 1692/*
1700 * NAME: dbAllocCtl() 1693 * NAME: dbAllocCtl()
1701 * 1694 *
1702 * FUNCTION: attempt to allocate a specified number of contiguous 1695 * FUNCTION: attempt to allocate a specified number of contiguous
1703 * blocks starting within a specific dmap. 1696 * blocks starting within a specific dmap.
1704 * 1697 *
1705 * this routine is called by higher level routines that search 1698 * this routine is called by higher level routines that search
@@ -1726,18 +1719,18 @@ static int dbFindCtl(struct bmap * bmp, int l2nb, int level, s64 * blkno)
1726 * first dmap (i.e. blkno). 1719 * first dmap (i.e. blkno).
1727 * 1720 *
1728 * PARAMETERS: 1721 * PARAMETERS:
1729 * bmp - pointer to bmap descriptor 1722 * bmp - pointer to bmap descriptor
1730 * nblocks - actual number of contiguous free blocks to allocate. 1723 * nblocks - actual number of contiguous free blocks to allocate.
1731 * l2nb - log2 number of contiguous free blocks to allocate. 1724 * l2nb - log2 number of contiguous free blocks to allocate.
1732 * blkno - starting block number of the dmap to start the allocation 1725 * blkno - starting block number of the dmap to start the allocation
1733 * from. 1726 * from.
1734 * results - on successful return, set to the starting block number 1727 * results - on successful return, set to the starting block number
1735 * of the newly allocated range. 1728 * of the newly allocated range.
1736 * 1729 *
1737 * RETURN VALUES: 1730 * RETURN VALUES:
1738 * 0 - success 1731 * 0 - success
1739 * -ENOSPC - insufficient disk resources 1732 * -ENOSPC - insufficient disk resources
1740 * -EIO - i/o error 1733 * -EIO - i/o error
1741 * 1734 *
1742 * serialization: IWRITE_LOCK(ipbmap) held on entry/exit; 1735 * serialization: IWRITE_LOCK(ipbmap) held on entry/exit;
1743 */ 1736 */
@@ -1870,7 +1863,7 @@ dbAllocCtl(struct bmap * bmp, s64 nblocks, int l2nb, s64 blkno, s64 * results)
1870/* 1863/*
1871 * NAME: dbAllocDmapLev() 1864 * NAME: dbAllocDmapLev()
1872 * 1865 *
1873 * FUNCTION: attempt to allocate a specified number of contiguous blocks 1866 * FUNCTION: attempt to allocate a specified number of contiguous blocks
1874 * from a specified dmap. 1867 * from a specified dmap.
1875 * 1868 *
1876 * this routine checks if the contiguous blocks are available. 1869 * this routine checks if the contiguous blocks are available.
@@ -1878,17 +1871,17 @@ dbAllocCtl(struct bmap * bmp, s64 nblocks, int l2nb, s64 blkno, s64 * results)
1878 * returned. 1871 * returned.
1879 * 1872 *
1880 * PARAMETERS: 1873 * PARAMETERS:
1881 * mp - pointer to bmap descriptor 1874 * mp - pointer to bmap descriptor
1882 * dp - pointer to dmap to attempt to allocate blocks from. 1875 * dp - pointer to dmap to attempt to allocate blocks from.
1883 * l2nb - log2 number of contiguous block desired. 1876 * l2nb - log2 number of contiguous block desired.
1884 * nblocks - actual number of contiguous block desired. 1877 * nblocks - actual number of contiguous block desired.
1885 * results - on successful return, set to the starting block number 1878 * results - on successful return, set to the starting block number
1886 * of the newly allocated range. 1879 * of the newly allocated range.
1887 * 1880 *
1888 * RETURN VALUES: 1881 * RETURN VALUES:
1889 * 0 - success 1882 * 0 - success
1890 * -ENOSPC - insufficient disk resources 1883 * -ENOSPC - insufficient disk resources
1891 * -EIO - i/o error 1884 * -EIO - i/o error
1892 * 1885 *
1893 * serialization: IREAD_LOCK(ipbmap), e.g., from dbAlloc(), or 1886 * serialization: IREAD_LOCK(ipbmap), e.g., from dbAlloc(), or
1894 * IWRITE_LOCK(ipbmap), e.g., dbAllocCtl(), held on entry/exit; 1887 * IWRITE_LOCK(ipbmap), e.g., dbAllocCtl(), held on entry/exit;
@@ -1933,7 +1926,7 @@ dbAllocDmapLev(struct bmap * bmp,
1933/* 1926/*
1934 * NAME: dbAllocDmap() 1927 * NAME: dbAllocDmap()
1935 * 1928 *
1936 * FUNCTION: adjust the disk allocation map to reflect the allocation 1929 * FUNCTION: adjust the disk allocation map to reflect the allocation
1937 * of a specified block range within a dmap. 1930 * of a specified block range within a dmap.
1938 * 1931 *
1939 * this routine allocates the specified blocks from the dmap 1932 * this routine allocates the specified blocks from the dmap
@@ -1946,14 +1939,14 @@ dbAllocDmapLev(struct bmap * bmp,
1946 * covers this dmap. 1939 * covers this dmap.
1947 * 1940 *
1948 * PARAMETERS: 1941 * PARAMETERS:
1949 * bmp - pointer to bmap descriptor 1942 * bmp - pointer to bmap descriptor
1950 * dp - pointer to dmap to allocate the block range from. 1943 * dp - pointer to dmap to allocate the block range from.
1951 * blkno - starting block number of the block to be allocated. 1944 * blkno - starting block number of the block to be allocated.
1952 * nblocks - number of blocks to be allocated. 1945 * nblocks - number of blocks to be allocated.
1953 * 1946 *
1954 * RETURN VALUES: 1947 * RETURN VALUES:
1955 * 0 - success 1948 * 0 - success
1956 * -EIO - i/o error 1949 * -EIO - i/o error
1957 * 1950 *
1958 * serialization: IREAD_LOCK(ipbmap) or IWRITE_LOCK(ipbmap) held on entry/exit; 1951 * serialization: IREAD_LOCK(ipbmap) or IWRITE_LOCK(ipbmap) held on entry/exit;
1959 */ 1952 */
@@ -1989,7 +1982,7 @@ static int dbAllocDmap(struct bmap * bmp, struct dmap * dp, s64 blkno,
1989/* 1982/*
1990 * NAME: dbFreeDmap() 1983 * NAME: dbFreeDmap()
1991 * 1984 *
1992 * FUNCTION: adjust the disk allocation map to reflect the allocation 1985 * FUNCTION: adjust the disk allocation map to reflect the allocation
1993 * of a specified block range within a dmap. 1986 * of a specified block range within a dmap.
1994 * 1987 *
1995 * this routine frees the specified blocks from the dmap through 1988 * this routine frees the specified blocks from the dmap through
@@ -1997,18 +1990,18 @@ static int dbAllocDmap(struct bmap * bmp, struct dmap * dp, s64 blkno,
1997 * causes the maximum string of free blocks within the dmap to 1990 * causes the maximum string of free blocks within the dmap to
1998 * change (i.e. the value of the root of the dmap's dmtree), this 1991 * change (i.e. the value of the root of the dmap's dmtree), this
1999 * routine will cause this change to be reflected up through the 1992 * routine will cause this change to be reflected up through the
2000 * appropriate levels of the dmap control pages by a call to 1993 * appropriate levels of the dmap control pages by a call to
2001 * dbAdjCtl() for the L0 dmap control page that covers this dmap. 1994 * dbAdjCtl() for the L0 dmap control page that covers this dmap.
2002 * 1995 *
2003 * PARAMETERS: 1996 * PARAMETERS:
2004 * bmp - pointer to bmap descriptor 1997 * bmp - pointer to bmap descriptor
2005 * dp - pointer to dmap to free the block range from. 1998 * dp - pointer to dmap to free the block range from.
2006 * blkno - starting block number of the block to be freed. 1999 * blkno - starting block number of the block to be freed.
2007 * nblocks - number of blocks to be freed. 2000 * nblocks - number of blocks to be freed.
2008 * 2001 *
2009 * RETURN VALUES: 2002 * RETURN VALUES:
2010 * 0 - success 2003 * 0 - success
2011 * -EIO - i/o error 2004 * -EIO - i/o error
2012 * 2005 *
2013 * serialization: IREAD_LOCK(ipbmap) or IWRITE_LOCK(ipbmap) held on entry/exit; 2006 * serialization: IREAD_LOCK(ipbmap) or IWRITE_LOCK(ipbmap) held on entry/exit;
2014 */ 2007 */
@@ -2055,7 +2048,7 @@ static int dbFreeDmap(struct bmap * bmp, struct dmap * dp, s64 blkno,
2055/* 2048/*
2056 * NAME: dbAllocBits() 2049 * NAME: dbAllocBits()
2057 * 2050 *
2058 * FUNCTION: allocate a specified block range from a dmap. 2051 * FUNCTION: allocate a specified block range from a dmap.
2059 * 2052 *
2060 * this routine updates the dmap to reflect the working 2053 * this routine updates the dmap to reflect the working
2061 * state allocation of the specified block range. it directly 2054 * state allocation of the specified block range. it directly
@@ -2065,10 +2058,10 @@ static int dbFreeDmap(struct bmap * bmp, struct dmap * dp, s64 blkno,
2065 * dmap's dmtree, as a whole, to reflect the allocated range. 2058 * dmap's dmtree, as a whole, to reflect the allocated range.
2066 * 2059 *
2067 * PARAMETERS: 2060 * PARAMETERS:
2068 * bmp - pointer to bmap descriptor 2061 * bmp - pointer to bmap descriptor
2069 * dp - pointer to dmap to allocate bits from. 2062 * dp - pointer to dmap to allocate bits from.
2070 * blkno - starting block number of the bits to be allocated. 2063 * blkno - starting block number of the bits to be allocated.
2071 * nblocks - number of bits to be allocated. 2064 * nblocks - number of bits to be allocated.
2072 * 2065 *
2073 * RETURN VALUES: none 2066 * RETURN VALUES: none
2074 * 2067 *
@@ -2149,7 +2142,7 @@ static void dbAllocBits(struct bmap * bmp, struct dmap * dp, s64 blkno,
2149 * the allocated words. 2142 * the allocated words.
2150 */ 2143 */
2151 for (; nwords > 0; nwords -= nw) { 2144 for (; nwords > 0; nwords -= nw) {
2152 if (leaf[word] < BUDMIN) { 2145 if (leaf[word] < BUDMIN) {
2153 jfs_error(bmp->db_ipbmap->i_sb, 2146 jfs_error(bmp->db_ipbmap->i_sb,
2154 "dbAllocBits: leaf page " 2147 "dbAllocBits: leaf page "
2155 "corrupt"); 2148 "corrupt");
@@ -2202,7 +2195,7 @@ static void dbAllocBits(struct bmap * bmp, struct dmap * dp, s64 blkno,
2202/* 2195/*
2203 * NAME: dbFreeBits() 2196 * NAME: dbFreeBits()
2204 * 2197 *
2205 * FUNCTION: free a specified block range from a dmap. 2198 * FUNCTION: free a specified block range from a dmap.
2206 * 2199 *
2207 * this routine updates the dmap to reflect the working 2200 * this routine updates the dmap to reflect the working
2208 * state allocation of the specified block range. it directly 2201 * state allocation of the specified block range. it directly
@@ -2212,10 +2205,10 @@ static void dbAllocBits(struct bmap * bmp, struct dmap * dp, s64 blkno,
2212 * dmtree, as a whole, to reflect the deallocated range. 2205 * dmtree, as a whole, to reflect the deallocated range.
2213 * 2206 *
2214 * PARAMETERS: 2207 * PARAMETERS:
2215 * bmp - pointer to bmap descriptor 2208 * bmp - pointer to bmap descriptor
2216 * dp - pointer to dmap to free bits from. 2209 * dp - pointer to dmap to free bits from.
2217 * blkno - starting block number of the bits to be freed. 2210 * blkno - starting block number of the bits to be freed.
2218 * nblocks - number of bits to be freed. 2211 * nblocks - number of bits to be freed.
2219 * 2212 *
2220 * RETURN VALUES: 0 for success 2213 * RETURN VALUES: 0 for success
2221 * 2214 *
@@ -2388,19 +2381,19 @@ static int dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno,
2388 * the new root value and the next dmap control page level to 2381 * the new root value and the next dmap control page level to
2389 * be adjusted. 2382 * be adjusted.
2390 * PARAMETERS: 2383 * PARAMETERS:
2391 * bmp - pointer to bmap descriptor 2384 * bmp - pointer to bmap descriptor
2392 * blkno - the first block of a block range within a dmap. it is 2385 * blkno - the first block of a block range within a dmap. it is
2393 * the allocation or deallocation of this block range that 2386 * the allocation or deallocation of this block range that
2394 * requires the dmap control page to be adjusted. 2387 * requires the dmap control page to be adjusted.
2395 * newval - the new value of the lower level dmap or dmap control 2388 * newval - the new value of the lower level dmap or dmap control
2396 * page root. 2389 * page root.
2397 * alloc - 'true' if adjustment is due to an allocation. 2390 * alloc - 'true' if adjustment is due to an allocation.
2398 * level - current level of dmap control page (i.e. L0, L1, L2) to 2391 * level - current level of dmap control page (i.e. L0, L1, L2) to
2399 * be adjusted. 2392 * be adjusted.
2400 * 2393 *
2401 * RETURN VALUES: 2394 * RETURN VALUES:
2402 * 0 - success 2395 * 0 - success
2403 * -EIO - i/o error 2396 * -EIO - i/o error
2404 * 2397 *
2405 * serialization: IREAD_LOCK(ipbmap) or IWRITE_LOCK(ipbmap) held on entry/exit; 2398 * serialization: IREAD_LOCK(ipbmap) or IWRITE_LOCK(ipbmap) held on entry/exit;
2406 */ 2399 */
@@ -2544,16 +2537,16 @@ dbAdjCtl(struct bmap * bmp, s64 blkno, int newval, int alloc, int level)
2544/* 2537/*
2545 * NAME: dbSplit() 2538 * NAME: dbSplit()
2546 * 2539 *
2547 * FUNCTION: update the leaf of a dmtree with a new value, splitting 2540 * FUNCTION: update the leaf of a dmtree with a new value, splitting
2548 * the leaf from the binary buddy system of the dmtree's 2541 * the leaf from the binary buddy system of the dmtree's
2549 * leaves, as required. 2542 * leaves, as required.
2550 * 2543 *
2551 * PARAMETERS: 2544 * PARAMETERS:
2552 * tp - pointer to the tree containing the leaf. 2545 * tp - pointer to the tree containing the leaf.
2553 * leafno - the number of the leaf to be updated. 2546 * leafno - the number of the leaf to be updated.
2554 * splitsz - the size the binary buddy system starting at the leaf 2547 * splitsz - the size the binary buddy system starting at the leaf
2555 * must be split to, specified as the log2 number of blocks. 2548 * must be split to, specified as the log2 number of blocks.
2556 * newval - the new value for the leaf. 2549 * newval - the new value for the leaf.
2557 * 2550 *
2558 * RETURN VALUES: none 2551 * RETURN VALUES: none
2559 * 2552 *
@@ -2600,7 +2593,7 @@ static void dbSplit(dmtree_t * tp, int leafno, int splitsz, int newval)
2600/* 2593/*
2601 * NAME: dbBackSplit() 2594 * NAME: dbBackSplit()
2602 * 2595 *
2603 * FUNCTION: back split the binary buddy system of dmtree leaves 2596 * FUNCTION: back split the binary buddy system of dmtree leaves
2604 * that hold a specified leaf until the specified leaf 2597 * that hold a specified leaf until the specified leaf
2605 * starts its own binary buddy system. 2598 * starts its own binary buddy system.
2606 * 2599 *
@@ -2617,8 +2610,8 @@ static void dbSplit(dmtree_t * tp, int leafno, int splitsz, int newval)
2617 * in which a previous join operation must be backed out. 2610 * in which a previous join operation must be backed out.
2618 * 2611 *
2619 * PARAMETERS: 2612 * PARAMETERS:
2620 * tp - pointer to the tree containing the leaf. 2613 * tp - pointer to the tree containing the leaf.
2621 * leafno - the number of the leaf to be updated. 2614 * leafno - the number of the leaf to be updated.
2622 * 2615 *
2623 * RETURN VALUES: none 2616 * RETURN VALUES: none
2624 * 2617 *
@@ -2692,14 +2685,14 @@ static int dbBackSplit(dmtree_t * tp, int leafno)
2692/* 2685/*
2693 * NAME: dbJoin() 2686 * NAME: dbJoin()
2694 * 2687 *
2695 * FUNCTION: update the leaf of a dmtree with a new value, joining 2688 * FUNCTION: update the leaf of a dmtree with a new value, joining
2696 * the leaf with other leaves of the dmtree into a multi-leaf 2689 * the leaf with other leaves of the dmtree into a multi-leaf
2697 * binary buddy system, as required. 2690 * binary buddy system, as required.
2698 * 2691 *
2699 * PARAMETERS: 2692 * PARAMETERS:
2700 * tp - pointer to the tree containing the leaf. 2693 * tp - pointer to the tree containing the leaf.
2701 * leafno - the number of the leaf to be updated. 2694 * leafno - the number of the leaf to be updated.
2702 * newval - the new value for the leaf. 2695 * newval - the new value for the leaf.
2703 * 2696 *
2704 * RETURN VALUES: none 2697 * RETURN VALUES: none
2705 */ 2698 */
@@ -2785,15 +2778,15 @@ static int dbJoin(dmtree_t * tp, int leafno, int newval)
2785/* 2778/*
2786 * NAME: dbAdjTree() 2779 * NAME: dbAdjTree()
2787 * 2780 *
2788 * FUNCTION: update a leaf of a dmtree with a new value, adjusting 2781 * FUNCTION: update a leaf of a dmtree with a new value, adjusting
2789 * the dmtree, as required, to reflect the new leaf value. 2782 * the dmtree, as required, to reflect the new leaf value.
2790 * the combination of any buddies must already be done before 2783 * the combination of any buddies must already be done before
2791 * this is called. 2784 * this is called.
2792 * 2785 *
2793 * PARAMETERS: 2786 * PARAMETERS:
2794 * tp - pointer to the tree to be adjusted. 2787 * tp - pointer to the tree to be adjusted.
2795 * leafno - the number of the leaf to be updated. 2788 * leafno - the number of the leaf to be updated.
2796 * newval - the new value for the leaf. 2789 * newval - the new value for the leaf.
2797 * 2790 *
2798 * RETURN VALUES: none 2791 * RETURN VALUES: none
2799 */ 2792 */
@@ -2852,7 +2845,7 @@ static void dbAdjTree(dmtree_t * tp, int leafno, int newval)
2852/* 2845/*
2853 * NAME: dbFindLeaf() 2846 * NAME: dbFindLeaf()
2854 * 2847 *
2855 * FUNCTION: search a dmtree_t for sufficient free blocks, returning 2848 * FUNCTION: search a dmtree_t for sufficient free blocks, returning
2856 * the index of a leaf describing the free blocks if 2849 * the index of a leaf describing the free blocks if
2857 * sufficient free blocks are found. 2850 * sufficient free blocks are found.
2858 * 2851 *
@@ -2861,15 +2854,15 @@ static void dbAdjTree(dmtree_t * tp, int leafno, int newval)
2861 * free space. 2854 * free space.
2862 * 2855 *
2863 * PARAMETERS: 2856 * PARAMETERS:
2864 * tp - pointer to the tree to be searched. 2857 * tp - pointer to the tree to be searched.
2865 * l2nb - log2 number of free blocks to search for. 2858 * l2nb - log2 number of free blocks to search for.
2866 * leafidx - return pointer to be set to the index of the leaf 2859 * leafidx - return pointer to be set to the index of the leaf
2867 * describing at least l2nb free blocks if sufficient 2860 * describing at least l2nb free blocks if sufficient
2868 * free blocks are found. 2861 * free blocks are found.
2869 * 2862 *
2870 * RETURN VALUES: 2863 * RETURN VALUES:
2871 * 0 - success 2864 * 0 - success
2872 * -ENOSPC - insufficient free blocks. 2865 * -ENOSPC - insufficient free blocks.
2873 */ 2866 */
2874static int dbFindLeaf(dmtree_t * tp, int l2nb, int *leafidx) 2867static int dbFindLeaf(dmtree_t * tp, int l2nb, int *leafidx)
2875{ 2868{
@@ -2916,18 +2909,18 @@ static int dbFindLeaf(dmtree_t * tp, int l2nb, int *leafidx)
2916/* 2909/*
2917 * NAME: dbFindBits() 2910 * NAME: dbFindBits()
2918 * 2911 *
2919 * FUNCTION: find a specified number of binary buddy free bits within a 2912 * FUNCTION: find a specified number of binary buddy free bits within a
2920 * dmap bitmap word value. 2913 * dmap bitmap word value.
2921 * 2914 *
2922 * this routine searches the bitmap value for (1 << l2nb) free 2915 * this routine searches the bitmap value for (1 << l2nb) free
2923 * bits at (1 << l2nb) alignments within the value. 2916 * bits at (1 << l2nb) alignments within the value.
2924 * 2917 *
2925 * PARAMETERS: 2918 * PARAMETERS:
2926 * word - dmap bitmap word value. 2919 * word - dmap bitmap word value.
2927 * l2nb - number of free bits specified as a log2 number. 2920 * l2nb - number of free bits specified as a log2 number.
2928 * 2921 *
2929 * RETURN VALUES: 2922 * RETURN VALUES:
2930 * starting bit number of free bits. 2923 * starting bit number of free bits.
2931 */ 2924 */
2932static int dbFindBits(u32 word, int l2nb) 2925static int dbFindBits(u32 word, int l2nb)
2933{ 2926{
@@ -2963,14 +2956,14 @@ static int dbFindBits(u32 word, int l2nb)
2963/* 2956/*
2964 * NAME: dbMaxBud(u8 *cp) 2957 * NAME: dbMaxBud(u8 *cp)
2965 * 2958 *
2966 * FUNCTION: determine the largest binary buddy string of free 2959 * FUNCTION: determine the largest binary buddy string of free
2967 * bits within 32-bits of the map. 2960 * bits within 32-bits of the map.
2968 * 2961 *
2969 * PARAMETERS: 2962 * PARAMETERS:
2970 * cp - pointer to the 32-bit value. 2963 * cp - pointer to the 32-bit value.
2971 * 2964 *
2972 * RETURN VALUES: 2965 * RETURN VALUES:
2973 * largest binary buddy of free bits within a dmap word. 2966 * largest binary buddy of free bits within a dmap word.
2974 */ 2967 */
2975static int dbMaxBud(u8 * cp) 2968static int dbMaxBud(u8 * cp)
2976{ 2969{
@@ -3000,14 +2993,14 @@ static int dbMaxBud(u8 * cp)
3000/* 2993/*
3001 * NAME: cnttz(uint word) 2994 * NAME: cnttz(uint word)
3002 * 2995 *
3003 * FUNCTION: determine the number of trailing zeros within a 32-bit 2996 * FUNCTION: determine the number of trailing zeros within a 32-bit
3004 * value. 2997 * value.
3005 * 2998 *
3006 * PARAMETERS: 2999 * PARAMETERS:
3007 * value - 32-bit value to be examined. 3000 * value - 32-bit value to be examined.
3008 * 3001 *
3009 * RETURN VALUES: 3002 * RETURN VALUES:
3010 * count of trailing zeros 3003 * count of trailing zeros
3011 */ 3004 */
3012static int cnttz(u32 word) 3005static int cnttz(u32 word)
3013{ 3006{
@@ -3025,14 +3018,14 @@ static int cnttz(u32 word)
3025/* 3018/*
3026 * NAME: cntlz(u32 value) 3019 * NAME: cntlz(u32 value)
3027 * 3020 *
3028 * FUNCTION: determine the number of leading zeros within a 32-bit 3021 * FUNCTION: determine the number of leading zeros within a 32-bit
3029 * value. 3022 * value.
3030 * 3023 *
3031 * PARAMETERS: 3024 * PARAMETERS:
3032 * value - 32-bit value to be examined. 3025 * value - 32-bit value to be examined.
3033 * 3026 *
3034 * RETURN VALUES: 3027 * RETURN VALUES:
3035 * count of leading zeros 3028 * count of leading zeros
3036 */ 3029 */
3037static int cntlz(u32 value) 3030static int cntlz(u32 value)
3038{ 3031{
@@ -3050,14 +3043,14 @@ static int cntlz(u32 value)
3050 * NAME: blkstol2(s64 nb) 3043 * NAME: blkstol2(s64 nb)
3051 * 3044 *
3052 * FUNCTION: convert a block count to its log2 value. if the block 3045 * FUNCTION: convert a block count to its log2 value. if the block
3053 * count is not a l2 multiple, it is rounded up to the next 3046 * count is not a l2 multiple, it is rounded up to the next
3054 * larger l2 multiple. 3047 * larger l2 multiple.
3055 * 3048 *
3056 * PARAMETERS: 3049 * PARAMETERS:
3057 * nb - number of blocks 3050 * nb - number of blocks
3058 * 3051 *
3059 * RETURN VALUES: 3052 * RETURN VALUES:
3060 * log2 number of blocks 3053 * log2 number of blocks
3061 */ 3054 */
3062static int blkstol2(s64 nb) 3055static int blkstol2(s64 nb)
3063{ 3056{
@@ -3099,13 +3092,13 @@ static int blkstol2(s64 nb)
3099 * at a time. 3092 * at a time.
3100 * 3093 *
3101 * PARAMETERS: 3094 * PARAMETERS:
3102 * ip - pointer to in-core inode; 3095 * ip - pointer to in-core inode;
3103 * blkno - starting block number to be freed. 3096 * blkno - starting block number to be freed.
3104 * nblocks - number of blocks to be freed. 3097 * nblocks - number of blocks to be freed.
3105 * 3098 *
3106 * RETURN VALUES: 3099 * RETURN VALUES:
3107 * 0 - success 3100 * 0 - success
3108 * -EIO - i/o error 3101 * -EIO - i/o error
3109 */ 3102 */
3110int dbAllocBottomUp(struct inode *ip, s64 blkno, s64 nblocks) 3103int dbAllocBottomUp(struct inode *ip, s64 blkno, s64 nblocks)
3111{ 3104{
@@ -3278,10 +3271,10 @@ static int dbAllocDmapBU(struct bmap * bmp, struct dmap * dp, s64 blkno,
3278 * L2 3271 * L2
3279 * | 3272 * |
3280 * L1---------------------------------L1 3273 * L1---------------------------------L1
3281 * | | 3274 * | |
3282 * L0---------L0---------L0 L0---------L0---------L0 3275 * L0---------L0---------L0 L0---------L0---------L0
3283 * | | | | | | 3276 * | | | | | |
3284 * d0,...,dn d0,...,dn d0,...,dn d0,...,dn d0,...,dn d0,.,dm; 3277 * d0,...,dn d0,...,dn d0,...,dn d0,...,dn d0,...,dn d0,.,dm;
3285 * L2L1L0d0,...,dnL0d0,...,dnL0d0,...,dnL1L0d0,...,dnL0d0,...,dnL0d0,..dm 3278 * L2L1L0d0,...,dnL0d0,...,dnL0d0,...,dnL1L0d0,...,dnL0d0,...,dnL0d0,..dm
3286 * 3279 *
3287 * <---old---><----------------------------extend-----------------------> 3280 * <---old---><----------------------------extend----------------------->
@@ -3307,7 +3300,7 @@ int dbExtendFS(struct inode *ipbmap, s64 blkno, s64 nblocks)
3307 (long long) blkno, (long long) nblocks, (long long) newsize); 3300 (long long) blkno, (long long) nblocks, (long long) newsize);
3308 3301
3309 /* 3302 /*
3310 * initialize bmap control page. 3303 * initialize bmap control page.
3311 * 3304 *
3312 * all the data in bmap control page should exclude 3305 * all the data in bmap control page should exclude
3313 * the mkfs hidden dmap page. 3306 * the mkfs hidden dmap page.
@@ -3330,7 +3323,7 @@ int dbExtendFS(struct inode *ipbmap, s64 blkno, s64 nblocks)
3330 bmp->db_numag += ((u32) newsize % (u32) bmp->db_agsize) ? 1 : 0; 3323 bmp->db_numag += ((u32) newsize % (u32) bmp->db_agsize) ? 1 : 0;
3331 3324
3332 /* 3325 /*
3333 * reconfigure db_agfree[] 3326 * reconfigure db_agfree[]
3334 * from old AG configuration to new AG configuration; 3327 * from old AG configuration to new AG configuration;
3335 * 3328 *
3336 * coalesce contiguous k (newAGSize/oldAGSize) AGs; 3329 * coalesce contiguous k (newAGSize/oldAGSize) AGs;
@@ -3362,7 +3355,7 @@ int dbExtendFS(struct inode *ipbmap, s64 blkno, s64 nblocks)
3362 bmp->db_maxag = bmp->db_maxag / k; 3355 bmp->db_maxag = bmp->db_maxag / k;
3363 3356
3364 /* 3357 /*
3365 * extend bmap 3358 * extend bmap
3366 * 3359 *
3367 * update bit maps and corresponding level control pages; 3360 * update bit maps and corresponding level control pages;
3368 * global control page db_nfree, db_agfree[agno], db_maxfreebud; 3361 * global control page db_nfree, db_agfree[agno], db_maxfreebud;
@@ -3410,7 +3403,7 @@ int dbExtendFS(struct inode *ipbmap, s64 blkno, s64 nblocks)
3410 /* compute start L0 */ 3403 /* compute start L0 */
3411 j = 0; 3404 j = 0;
3412 l1leaf = l1dcp->stree + CTLLEAFIND; 3405 l1leaf = l1dcp->stree + CTLLEAFIND;
3413 p += nbperpage; /* 1st L0 of L1.k */ 3406 p += nbperpage; /* 1st L0 of L1.k */
3414 } 3407 }
3415 3408
3416 /* 3409 /*
@@ -3548,7 +3541,7 @@ errout:
3548 return -EIO; 3541 return -EIO;
3549 3542
3550 /* 3543 /*
3551 * finalize bmap control page 3544 * finalize bmap control page
3552 */ 3545 */
3553finalize: 3546finalize:
3554 3547
@@ -3567,7 +3560,7 @@ void dbFinalizeBmap(struct inode *ipbmap)
3567 int i, n; 3560 int i, n;
3568 3561
3569 /* 3562 /*
3570 * finalize bmap control page 3563 * finalize bmap control page
3571 */ 3564 */
3572//finalize: 3565//finalize:
3573 /* 3566 /*
@@ -3953,8 +3946,8 @@ static int dbGetL2AGSize(s64 nblocks)
3953 * convert number of map pages to the zero origin top dmapctl level 3946 * convert number of map pages to the zero origin top dmapctl level
3954 */ 3947 */
3955#define BMAPPGTOLEV(npages) \ 3948#define BMAPPGTOLEV(npages) \
3956 (((npages) <= 3 + MAXL0PAGES) ? 0 \ 3949 (((npages) <= 3 + MAXL0PAGES) ? 0 : \
3957 : ((npages) <= 2 + MAXL1PAGES) ? 1 : 2) 3950 ((npages) <= 2 + MAXL1PAGES) ? 1 : 2)
3958 3951
3959s64 dbMapFileSizeToMapSize(struct inode * ipbmap) 3952s64 dbMapFileSizeToMapSize(struct inode * ipbmap)
3960{ 3953{
@@ -3981,8 +3974,8 @@ s64 dbMapFileSizeToMapSize(struct inode * ipbmap)
3981 factor = 3974 factor =
3982 (i == 2) ? MAXL1PAGES : ((i == 1) ? MAXL0PAGES : 1); 3975 (i == 2) ? MAXL1PAGES : ((i == 1) ? MAXL0PAGES : 1);
3983 complete = (u32) npages / factor; 3976 complete = (u32) npages / factor;
3984 ndmaps += complete * ((i == 2) ? LPERCTL * LPERCTL 3977 ndmaps += complete * ((i == 2) ? LPERCTL * LPERCTL :
3985 : ((i == 1) ? LPERCTL : 1)); 3978 ((i == 1) ? LPERCTL : 1));
3986 3979
3987 /* pages in last/incomplete child */ 3980 /* pages in last/incomplete child */
3988 npages = (u32) npages % factor; 3981 npages = (u32) npages % factor;
diff --git a/fs/jfs/jfs_dmap.h b/fs/jfs/jfs_dmap.h
index 45ea454c74bd..11e6d471b364 100644
--- a/fs/jfs/jfs_dmap.h
+++ b/fs/jfs/jfs_dmap.h
@@ -83,7 +83,7 @@ static __inline signed char TREEMAX(signed char *cp)
83 * - 1 is added to account for the control page of the map. 83 * - 1 is added to account for the control page of the map.
84 */ 84 */
85#define BLKTODMAP(b,s) \ 85#define BLKTODMAP(b,s) \
86 ((((b) >> 13) + ((b) >> 23) + ((b) >> 33) + 3 + 1) << (s)) 86 ((((b) >> 13) + ((b) >> 23) + ((b) >> 33) + 3 + 1) << (s))
87 87
88/* 88/*
89 * convert disk block number to the logical block number of the LEVEL 0 89 * convert disk block number to the logical block number of the LEVEL 0
@@ -98,7 +98,7 @@ static __inline signed char TREEMAX(signed char *cp)
98 * - 1 is added to account for the control page of the map. 98 * - 1 is added to account for the control page of the map.
99 */ 99 */
100#define BLKTOL0(b,s) \ 100#define BLKTOL0(b,s) \
101 (((((b) >> 23) << 10) + ((b) >> 23) + ((b) >> 33) + 2 + 1) << (s)) 101 (((((b) >> 23) << 10) + ((b) >> 23) + ((b) >> 33) + 2 + 1) << (s))
102 102
103/* 103/*
104 * convert disk block number to the logical block number of the LEVEL 1 104 * convert disk block number to the logical block number of the LEVEL 1
@@ -120,7 +120,7 @@ static __inline signed char TREEMAX(signed char *cp)
120 * at the specified level which describes the disk block. 120 * at the specified level which describes the disk block.
121 */ 121 */
122#define BLKTOCTL(b,s,l) \ 122#define BLKTOCTL(b,s,l) \
123 (((l) == 2) ? 1 : ((l) == 1) ? BLKTOL1((b),(s)) : BLKTOL0((b),(s))) 123 (((l) == 2) ? 1 : ((l) == 1) ? BLKTOL1((b),(s)) : BLKTOL0((b),(s)))
124 124
125/* 125/*
126 * convert aggregate map size to the zero origin dmapctl level of the 126 * convert aggregate map size to the zero origin dmapctl level of the
@@ -145,27 +145,27 @@ static __inline signed char TREEMAX(signed char *cp)
145 * dmaptree must be consistent with dmapctl. 145 * dmaptree must be consistent with dmapctl.
146 */ 146 */
147struct dmaptree { 147struct dmaptree {
148 __le32 nleafs; /* 4: number of tree leafs */ 148 __le32 nleafs; /* 4: number of tree leafs */
149 __le32 l2nleafs; /* 4: l2 number of tree leafs */ 149 __le32 l2nleafs; /* 4: l2 number of tree leafs */
150 __le32 leafidx; /* 4: index of first tree leaf */ 150 __le32 leafidx; /* 4: index of first tree leaf */
151 __le32 height; /* 4: height of the tree */ 151 __le32 height; /* 4: height of the tree */
152 s8 budmin; /* 1: min l2 tree leaf value to combine */ 152 s8 budmin; /* 1: min l2 tree leaf value to combine */
153 s8 stree[TREESIZE]; /* TREESIZE: tree */ 153 s8 stree[TREESIZE]; /* TREESIZE: tree */
154 u8 pad[2]; /* 2: pad to word boundary */ 154 u8 pad[2]; /* 2: pad to word boundary */
155}; /* - 360 - */ 155}; /* - 360 - */
156 156
157/* 157/*
158 * dmap page per 8K blocks bitmap 158 * dmap page per 8K blocks bitmap
159 */ 159 */
160struct dmap { 160struct dmap {
161 __le32 nblocks; /* 4: num blks covered by this dmap */ 161 __le32 nblocks; /* 4: num blks covered by this dmap */
162 __le32 nfree; /* 4: num of free blks in this dmap */ 162 __le32 nfree; /* 4: num of free blks in this dmap */
163 __le64 start; /* 8: starting blkno for this dmap */ 163 __le64 start; /* 8: starting blkno for this dmap */
164 struct dmaptree tree; /* 360: dmap tree */ 164 struct dmaptree tree; /* 360: dmap tree */
165 u8 pad[1672]; /* 1672: pad to 2048 bytes */ 165 u8 pad[1672]; /* 1672: pad to 2048 bytes */
166 __le32 wmap[LPERDMAP]; /* 1024: bits of the working map */ 166 __le32 wmap[LPERDMAP]; /* 1024: bits of the working map */
167 __le32 pmap[LPERDMAP]; /* 1024: bits of the persistent map */ 167 __le32 pmap[LPERDMAP]; /* 1024: bits of the persistent map */
168}; /* - 4096 - */ 168}; /* - 4096 - */
169 169
170/* 170/*
171 * disk map control page per level. 171 * disk map control page per level.
@@ -173,14 +173,14 @@ struct dmap {
173 * dmapctl must be consistent with dmaptree. 173 * dmapctl must be consistent with dmaptree.
174 */ 174 */
175struct dmapctl { 175struct dmapctl {
176 __le32 nleafs; /* 4: number of tree leafs */ 176 __le32 nleafs; /* 4: number of tree leafs */
177 __le32 l2nleafs; /* 4: l2 number of tree leafs */ 177 __le32 l2nleafs; /* 4: l2 number of tree leafs */
178 __le32 leafidx; /* 4: index of the first tree leaf */ 178 __le32 leafidx; /* 4: index of the first tree leaf */
179 __le32 height; /* 4: height of tree */ 179 __le32 height; /* 4: height of tree */
180 s8 budmin; /* 1: minimum l2 tree leaf value */ 180 s8 budmin; /* 1: minimum l2 tree leaf value */
181 s8 stree[CTLTREESIZE]; /* CTLTREESIZE: dmapctl tree */ 181 s8 stree[CTLTREESIZE]; /* CTLTREESIZE: dmapctl tree */
182 u8 pad[2714]; /* 2714: pad to 4096 */ 182 u8 pad[2714]; /* 2714: pad to 4096 */
183}; /* - 4096 - */ 183}; /* - 4096 - */
184 184
185/* 185/*
186 * common definition for dmaptree within dmap and dmapctl 186 * common definition for dmaptree within dmap and dmapctl
@@ -202,41 +202,41 @@ typedef union dmtree {
202 * on-disk aggregate disk allocation map descriptor. 202 * on-disk aggregate disk allocation map descriptor.
203 */ 203 */
204struct dbmap_disk { 204struct dbmap_disk {
205 __le64 dn_mapsize; /* 8: number of blocks in aggregate */ 205 __le64 dn_mapsize; /* 8: number of blocks in aggregate */
206 __le64 dn_nfree; /* 8: num free blks in aggregate map */ 206 __le64 dn_nfree; /* 8: num free blks in aggregate map */
207 __le32 dn_l2nbperpage; /* 4: number of blks per page */ 207 __le32 dn_l2nbperpage; /* 4: number of blks per page */
208 __le32 dn_numag; /* 4: total number of ags */ 208 __le32 dn_numag; /* 4: total number of ags */
209 __le32 dn_maxlevel; /* 4: number of active ags */ 209 __le32 dn_maxlevel; /* 4: number of active ags */
210 __le32 dn_maxag; /* 4: max active alloc group number */ 210 __le32 dn_maxag; /* 4: max active alloc group number */
211 __le32 dn_agpref; /* 4: preferred alloc group (hint) */ 211 __le32 dn_agpref; /* 4: preferred alloc group (hint) */
212 __le32 dn_aglevel; /* 4: dmapctl level holding the AG */ 212 __le32 dn_aglevel; /* 4: dmapctl level holding the AG */
213 __le32 dn_agheigth; /* 4: height in dmapctl of the AG */ 213 __le32 dn_agheigth; /* 4: height in dmapctl of the AG */
214 __le32 dn_agwidth; /* 4: width in dmapctl of the AG */ 214 __le32 dn_agwidth; /* 4: width in dmapctl of the AG */
215 __le32 dn_agstart; /* 4: start tree index at AG height */ 215 __le32 dn_agstart; /* 4: start tree index at AG height */
216 __le32 dn_agl2size; /* 4: l2 num of blks per alloc group */ 216 __le32 dn_agl2size; /* 4: l2 num of blks per alloc group */
217 __le64 dn_agfree[MAXAG];/* 8*MAXAG: per AG free count */ 217 __le64 dn_agfree[MAXAG];/* 8*MAXAG: per AG free count */
218 __le64 dn_agsize; /* 8: num of blks per alloc group */ 218 __le64 dn_agsize; /* 8: num of blks per alloc group */
219 s8 dn_maxfreebud; /* 1: max free buddy system */ 219 s8 dn_maxfreebud; /* 1: max free buddy system */
220 u8 pad[3007]; /* 3007: pad to 4096 */ 220 u8 pad[3007]; /* 3007: pad to 4096 */
221}; /* - 4096 - */ 221}; /* - 4096 - */
222 222
223struct dbmap { 223struct dbmap {
224 s64 dn_mapsize; /* number of blocks in aggregate */ 224 s64 dn_mapsize; /* number of blocks in aggregate */
225 s64 dn_nfree; /* num free blks in aggregate map */ 225 s64 dn_nfree; /* num free blks in aggregate map */
226 int dn_l2nbperpage; /* number of blks per page */ 226 int dn_l2nbperpage; /* number of blks per page */
227 int dn_numag; /* total number of ags */ 227 int dn_numag; /* total number of ags */
228 int dn_maxlevel; /* number of active ags */ 228 int dn_maxlevel; /* number of active ags */
229 int dn_maxag; /* max active alloc group number */ 229 int dn_maxag; /* max active alloc group number */
230 int dn_agpref; /* preferred alloc group (hint) */ 230 int dn_agpref; /* preferred alloc group (hint) */
231 int dn_aglevel; /* dmapctl level holding the AG */ 231 int dn_aglevel; /* dmapctl level holding the AG */
232 int dn_agheigth; /* height in dmapctl of the AG */ 232 int dn_agheigth; /* height in dmapctl of the AG */
233 int dn_agwidth; /* width in dmapctl of the AG */ 233 int dn_agwidth; /* width in dmapctl of the AG */
234 int dn_agstart; /* start tree index at AG height */ 234 int dn_agstart; /* start tree index at AG height */
235 int dn_agl2size; /* l2 num of blks per alloc group */ 235 int dn_agl2size; /* l2 num of blks per alloc group */
236 s64 dn_agfree[MAXAG]; /* per AG free count */ 236 s64 dn_agfree[MAXAG]; /* per AG free count */
237 s64 dn_agsize; /* num of blks per alloc group */ 237 s64 dn_agsize; /* num of blks per alloc group */
238 signed char dn_maxfreebud; /* max free buddy system */ 238 signed char dn_maxfreebud; /* max free buddy system */
239}; /* - 4096 - */ 239}; /* - 4096 - */
240/* 240/*
241 * in-memory aggregate disk allocation map descriptor. 241 * in-memory aggregate disk allocation map descriptor.
242 */ 242 */
diff --git a/fs/jfs/jfs_dtree.c b/fs/jfs/jfs_dtree.c
index 6d62f3222892..c14ba3cfa818 100644
--- a/fs/jfs/jfs_dtree.c
+++ b/fs/jfs/jfs_dtree.c
@@ -315,8 +315,8 @@ static inline void lock_index(tid_t tid, struct inode *ip, struct metapage * mp,
315 lv = &llck->lv[llck->index]; 315 lv = &llck->lv[llck->index];
316 316
317 /* 317 /*
318 * Linelock slot size is twice the size of directory table 318 * Linelock slot size is twice the size of directory table
319 * slot size. 512 entries per page. 319 * slot size. 512 entries per page.
320 */ 320 */
321 lv->offset = ((index - 2) & 511) >> 1; 321 lv->offset = ((index - 2) & 511) >> 1;
322 lv->length = 1; 322 lv->length = 1;
@@ -615,7 +615,7 @@ int dtSearch(struct inode *ip, struct component_name * key, ino_t * data,
615 btstack->nsplit = 1; 615 btstack->nsplit = 1;
616 616
617 /* 617 /*
618 * search down tree from root: 618 * search down tree from root:
619 * 619 *
620 * between two consecutive entries of <Ki, Pi> and <Kj, Pj> of 620 * between two consecutive entries of <Ki, Pi> and <Kj, Pj> of
621 * internal page, child page Pi contains entry with k, Ki <= K < Kj. 621 * internal page, child page Pi contains entry with k, Ki <= K < Kj.
@@ -659,7 +659,7 @@ int dtSearch(struct inode *ip, struct component_name * key, ino_t * data,
659 } 659 }
660 if (cmp == 0) { 660 if (cmp == 0) {
661 /* 661 /*
662 * search hit 662 * search hit
663 */ 663 */
664 /* search hit - leaf page: 664 /* search hit - leaf page:
665 * return the entry found 665 * return the entry found
@@ -723,7 +723,7 @@ int dtSearch(struct inode *ip, struct component_name * key, ino_t * data,
723 } 723 }
724 724
725 /* 725 /*
726 * search miss 726 * search miss
727 * 727 *
728 * base is the smallest index with key (Kj) greater than 728 * base is the smallest index with key (Kj) greater than
729 * search key (K) and may be zero or (maxindex + 1) index. 729 * search key (K) and may be zero or (maxindex + 1) index.
@@ -834,7 +834,7 @@ int dtInsert(tid_t tid, struct inode *ip,
834 struct lv *lv; 834 struct lv *lv;
835 835
836 /* 836 /*
837 * retrieve search result 837 * retrieve search result
838 * 838 *
839 * dtSearch() returns (leaf page pinned, index at which to insert). 839 * dtSearch() returns (leaf page pinned, index at which to insert).
840 * n.b. dtSearch() may return index of (maxindex + 1) of 840 * n.b. dtSearch() may return index of (maxindex + 1) of
@@ -843,7 +843,7 @@ int dtInsert(tid_t tid, struct inode *ip,
843 DT_GETSEARCH(ip, btstack->top, bn, mp, p, index); 843 DT_GETSEARCH(ip, btstack->top, bn, mp, p, index);
844 844
845 /* 845 /*
846 * insert entry for new key 846 * insert entry for new key
847 */ 847 */
848 if (DO_INDEX(ip)) { 848 if (DO_INDEX(ip)) {
849 if (JFS_IP(ip)->next_index == DIREND) { 849 if (JFS_IP(ip)->next_index == DIREND) {
@@ -860,9 +860,9 @@ int dtInsert(tid_t tid, struct inode *ip,
860 data.leaf.ino = *fsn; 860 data.leaf.ino = *fsn;
861 861
862 /* 862 /*
863 * leaf page does not have enough room for new entry: 863 * leaf page does not have enough room for new entry:
864 * 864 *
865 * extend/split the leaf page; 865 * extend/split the leaf page;
866 * 866 *
867 * dtSplitUp() will insert the entry and unpin the leaf page. 867 * dtSplitUp() will insert the entry and unpin the leaf page.
868 */ 868 */
@@ -877,9 +877,9 @@ int dtInsert(tid_t tid, struct inode *ip,
877 } 877 }
878 878
879 /* 879 /*
880 * leaf page does have enough room for new entry: 880 * leaf page does have enough room for new entry:
881 * 881 *
882 * insert the new data entry into the leaf page; 882 * insert the new data entry into the leaf page;
883 */ 883 */
884 BT_MARK_DIRTY(mp, ip); 884 BT_MARK_DIRTY(mp, ip);
885 /* 885 /*
@@ -967,13 +967,13 @@ static int dtSplitUp(tid_t tid,
967 } 967 }
968 968
969 /* 969 /*
970 * split leaf page 970 * split leaf page
971 * 971 *
972 * The split routines insert the new entry, and 972 * The split routines insert the new entry, and
973 * acquire txLock as appropriate. 973 * acquire txLock as appropriate.
974 */ 974 */
975 /* 975 /*
976 * split root leaf page: 976 * split root leaf page:
977 */ 977 */
978 if (sp->header.flag & BT_ROOT) { 978 if (sp->header.flag & BT_ROOT) {
979 /* 979 /*
@@ -1012,7 +1012,7 @@ static int dtSplitUp(tid_t tid,
1012 } 1012 }
1013 1013
1014 /* 1014 /*
1015 * extend first leaf page 1015 * extend first leaf page
1016 * 1016 *
1017 * extend the 1st extent if less than buffer page size 1017 * extend the 1st extent if less than buffer page size
1018 * (dtExtendPage() reurns leaf page unpinned) 1018 * (dtExtendPage() reurns leaf page unpinned)
@@ -1068,7 +1068,7 @@ static int dtSplitUp(tid_t tid,
1068 } 1068 }
1069 1069
1070 /* 1070 /*
1071 * split leaf page <sp> into <sp> and a new right page <rp>. 1071 * split leaf page <sp> into <sp> and a new right page <rp>.
1072 * 1072 *
1073 * return <rp> pinned and its extent descriptor <rpxd> 1073 * return <rp> pinned and its extent descriptor <rpxd>
1074 */ 1074 */
@@ -1433,7 +1433,7 @@ static int dtSplitPage(tid_t tid, struct inode *ip, struct dtsplit * split,
1433 rp->header.freecnt = rp->header.maxslot - fsi; 1433 rp->header.freecnt = rp->header.maxslot - fsi;
1434 1434
1435 /* 1435 /*
1436 * sequential append at tail: append without split 1436 * sequential append at tail: append without split
1437 * 1437 *
1438 * If splitting the last page on a level because of appending 1438 * If splitting the last page on a level because of appending
1439 * a entry to it (skip is maxentry), it's likely that the access is 1439 * a entry to it (skip is maxentry), it's likely that the access is
@@ -1467,7 +1467,7 @@ static int dtSplitPage(tid_t tid, struct inode *ip, struct dtsplit * split,
1467 } 1467 }
1468 1468
1469 /* 1469 /*
1470 * non-sequential insert (at possibly middle page) 1470 * non-sequential insert (at possibly middle page)
1471 */ 1471 */
1472 1472
1473 /* 1473 /*
@@ -1508,7 +1508,7 @@ static int dtSplitPage(tid_t tid, struct inode *ip, struct dtsplit * split,
1508 left = 0; 1508 left = 0;
1509 1509
1510 /* 1510 /*
1511 * compute fill factor for split pages 1511 * compute fill factor for split pages
1512 * 1512 *
1513 * <nxt> traces the next entry to move to rp 1513 * <nxt> traces the next entry to move to rp
1514 * <off> traces the next entry to stay in sp 1514 * <off> traces the next entry to stay in sp
@@ -1551,7 +1551,7 @@ static int dtSplitPage(tid_t tid, struct inode *ip, struct dtsplit * split,
1551 /* <nxt> poins to the 1st entry to move */ 1551 /* <nxt> poins to the 1st entry to move */
1552 1552
1553 /* 1553 /*
1554 * move entries to right page 1554 * move entries to right page
1555 * 1555 *
1556 * dtMoveEntry() initializes rp and reserves entry for insertion 1556 * dtMoveEntry() initializes rp and reserves entry for insertion
1557 * 1557 *
@@ -1677,7 +1677,7 @@ static int dtExtendPage(tid_t tid,
1677 return (rc); 1677 return (rc);
1678 1678
1679 /* 1679 /*
1680 * extend the extent 1680 * extend the extent
1681 */ 1681 */
1682 pxdlist = split->pxdlist; 1682 pxdlist = split->pxdlist;
1683 pxd = &pxdlist->pxd[pxdlist->npxd]; 1683 pxd = &pxdlist->pxd[pxdlist->npxd];
@@ -1722,7 +1722,7 @@ static int dtExtendPage(tid_t tid,
1722 } 1722 }
1723 1723
1724 /* 1724 /*
1725 * extend the page 1725 * extend the page
1726 */ 1726 */
1727 sp->header.self = *pxd; 1727 sp->header.self = *pxd;
1728 1728
@@ -1739,9 +1739,6 @@ static int dtExtendPage(tid_t tid,
1739 /* update buffer extent descriptor of extended page */ 1739 /* update buffer extent descriptor of extended page */
1740 xlen = lengthPXD(pxd); 1740 xlen = lengthPXD(pxd);
1741 xsize = xlen << JFS_SBI(sb)->l2bsize; 1741 xsize = xlen << JFS_SBI(sb)->l2bsize;
1742#ifdef _STILL_TO_PORT
1743 bmSetXD(smp, xaddr, xsize);
1744#endif /* _STILL_TO_PORT */
1745 1742
1746 /* 1743 /*
1747 * copy old stbl to new stbl at start of extended area 1744 * copy old stbl to new stbl at start of extended area
@@ -1836,7 +1833,7 @@ static int dtExtendPage(tid_t tid,
1836 } 1833 }
1837 1834
1838 /* 1835 /*
1839 * update parent entry on the parent/root page 1836 * update parent entry on the parent/root page
1840 */ 1837 */
1841 /* 1838 /*
1842 * acquire a transaction lock on the parent/root page 1839 * acquire a transaction lock on the parent/root page
@@ -1904,7 +1901,7 @@ static int dtSplitRoot(tid_t tid,
1904 sp = &JFS_IP(ip)->i_dtroot; 1901 sp = &JFS_IP(ip)->i_dtroot;
1905 1902
1906 /* 1903 /*
1907 * allocate/initialize a single (right) child page 1904 * allocate/initialize a single (right) child page
1908 * 1905 *
1909 * N.B. at first split, a one (or two) block to fit new entry 1906 * N.B. at first split, a one (or two) block to fit new entry
1910 * is allocated; at subsequent split, a full page is allocated; 1907 * is allocated; at subsequent split, a full page is allocated;
@@ -1943,7 +1940,7 @@ static int dtSplitRoot(tid_t tid,
1943 rp->header.prev = 0; 1940 rp->header.prev = 0;
1944 1941
1945 /* 1942 /*
1946 * move in-line root page into new right page extent 1943 * move in-line root page into new right page extent
1947 */ 1944 */
1948 /* linelock header + copied entries + new stbl (1st slot) in new page */ 1945 /* linelock header + copied entries + new stbl (1st slot) in new page */
1949 ASSERT(dtlck->index == 0); 1946 ASSERT(dtlck->index == 0);
@@ -2016,7 +2013,7 @@ static int dtSplitRoot(tid_t tid,
2016 dtInsertEntry(rp, split->index, split->key, split->data, &dtlck); 2013 dtInsertEntry(rp, split->index, split->key, split->data, &dtlck);
2017 2014
2018 /* 2015 /*
2019 * reset parent/root page 2016 * reset parent/root page
2020 * 2017 *
2021 * set the 1st entry offset to 0, which force the left-most key 2018 * set the 1st entry offset to 0, which force the left-most key
2022 * at any level of the tree to be less than any search key. 2019 * at any level of the tree to be less than any search key.
@@ -2102,7 +2099,7 @@ int dtDelete(tid_t tid,
2102 dtpage_t *np; 2099 dtpage_t *np;
2103 2100
2104 /* 2101 /*
2105 * search for the entry to delete: 2102 * search for the entry to delete:
2106 * 2103 *
2107 * dtSearch() returns (leaf page pinned, index at which to delete). 2104 * dtSearch() returns (leaf page pinned, index at which to delete).
2108 */ 2105 */
@@ -2253,7 +2250,7 @@ static int dtDeleteUp(tid_t tid, struct inode *ip,
2253 int i; 2250 int i;
2254 2251
2255 /* 2252 /*
2256 * keep the root leaf page which has become empty 2253 * keep the root leaf page which has become empty
2257 */ 2254 */
2258 if (BT_IS_ROOT(fmp)) { 2255 if (BT_IS_ROOT(fmp)) {
2259 /* 2256 /*
@@ -2269,7 +2266,7 @@ static int dtDeleteUp(tid_t tid, struct inode *ip,
2269 } 2266 }
2270 2267
2271 /* 2268 /*
2272 * free the non-root leaf page 2269 * free the non-root leaf page
2273 */ 2270 */
2274 /* 2271 /*
2275 * acquire a transaction lock on the page 2272 * acquire a transaction lock on the page
@@ -2299,7 +2296,7 @@ static int dtDeleteUp(tid_t tid, struct inode *ip,
2299 discard_metapage(fmp); 2296 discard_metapage(fmp);
2300 2297
2301 /* 2298 /*
2302 * propagate page deletion up the directory tree 2299 * propagate page deletion up the directory tree
2303 * 2300 *
2304 * If the delete from the parent page makes it empty, 2301 * If the delete from the parent page makes it empty,
2305 * continue all the way up the tree. 2302 * continue all the way up the tree.
@@ -2440,10 +2437,10 @@ static int dtDeleteUp(tid_t tid, struct inode *ip,
2440 2437
2441#ifdef _NOTYET 2438#ifdef _NOTYET
2442/* 2439/*
2443 * NAME: dtRelocate() 2440 * NAME: dtRelocate()
2444 * 2441 *
2445 * FUNCTION: relocate dtpage (internal or leaf) of directory; 2442 * FUNCTION: relocate dtpage (internal or leaf) of directory;
2446 * This function is mainly used by defragfs utility. 2443 * This function is mainly used by defragfs utility.
2447 */ 2444 */
2448int dtRelocate(tid_t tid, struct inode *ip, s64 lmxaddr, pxd_t * opxd, 2445int dtRelocate(tid_t tid, struct inode *ip, s64 lmxaddr, pxd_t * opxd,
2449 s64 nxaddr) 2446 s64 nxaddr)
@@ -2471,8 +2468,8 @@ int dtRelocate(tid_t tid, struct inode *ip, s64 lmxaddr, pxd_t * opxd,
2471 xlen); 2468 xlen);
2472 2469
2473 /* 2470 /*
2474 * 1. get the internal parent dtpage covering 2471 * 1. get the internal parent dtpage covering
2475 * router entry for the tartget page to be relocated; 2472 * router entry for the tartget page to be relocated;
2476 */ 2473 */
2477 rc = dtSearchNode(ip, lmxaddr, opxd, &btstack); 2474 rc = dtSearchNode(ip, lmxaddr, opxd, &btstack);
2478 if (rc) 2475 if (rc)
@@ -2483,7 +2480,7 @@ int dtRelocate(tid_t tid, struct inode *ip, s64 lmxaddr, pxd_t * opxd,
2483 jfs_info("dtRelocate: parent router entry validated."); 2480 jfs_info("dtRelocate: parent router entry validated.");
2484 2481
2485 /* 2482 /*
2486 * 2. relocate the target dtpage 2483 * 2. relocate the target dtpage
2487 */ 2484 */
2488 /* read in the target page from src extent */ 2485 /* read in the target page from src extent */
2489 DT_GETPAGE(ip, oxaddr, mp, PSIZE, p, rc); 2486 DT_GETPAGE(ip, oxaddr, mp, PSIZE, p, rc);
@@ -2581,9 +2578,7 @@ int dtRelocate(tid_t tid, struct inode *ip, s64 lmxaddr, pxd_t * opxd,
2581 2578
2582 /* update the buffer extent descriptor of the dtpage */ 2579 /* update the buffer extent descriptor of the dtpage */
2583 xsize = xlen << JFS_SBI(ip->i_sb)->l2bsize; 2580 xsize = xlen << JFS_SBI(ip->i_sb)->l2bsize;
2584#ifdef _STILL_TO_PORT 2581
2585 bmSetXD(mp, nxaddr, xsize);
2586#endif /* _STILL_TO_PORT */
2587 /* unpin the relocated page */ 2582 /* unpin the relocated page */
2588 DT_PUTPAGE(mp); 2583 DT_PUTPAGE(mp);
2589 jfs_info("dtRelocate: target dtpage relocated."); 2584 jfs_info("dtRelocate: target dtpage relocated.");
@@ -2594,7 +2589,7 @@ int dtRelocate(tid_t tid, struct inode *ip, s64 lmxaddr, pxd_t * opxd,
2594 */ 2589 */
2595 2590
2596 /* 2591 /*
2597 * 3. acquire maplock for the source extent to be freed; 2592 * 3. acquire maplock for the source extent to be freed;
2598 */ 2593 */
2599 /* for dtpage relocation, write a LOG_NOREDOPAGE record 2594 /* for dtpage relocation, write a LOG_NOREDOPAGE record
2600 * for the source dtpage (logredo() will init NoRedoPage 2595 * for the source dtpage (logredo() will init NoRedoPage
@@ -2609,7 +2604,7 @@ int dtRelocate(tid_t tid, struct inode *ip, s64 lmxaddr, pxd_t * opxd,
2609 pxdlock->index = 1; 2604 pxdlock->index = 1;
2610 2605
2611 /* 2606 /*
2612 * 4. update the parent router entry for relocation; 2607 * 4. update the parent router entry for relocation;
2613 * 2608 *
2614 * acquire tlck for the parent entry covering the target dtpage; 2609 * acquire tlck for the parent entry covering the target dtpage;
2615 * write LOG_REDOPAGE to apply after image only; 2610 * write LOG_REDOPAGE to apply after image only;
@@ -2637,7 +2632,7 @@ int dtRelocate(tid_t tid, struct inode *ip, s64 lmxaddr, pxd_t * opxd,
2637 * NAME: dtSearchNode() 2632 * NAME: dtSearchNode()
2638 * 2633 *
2639 * FUNCTION: Search for an dtpage containing a specified address 2634 * FUNCTION: Search for an dtpage containing a specified address
2640 * This function is mainly used by defragfs utility. 2635 * This function is mainly used by defragfs utility.
2641 * 2636 *
2642 * NOTE: Search result on stack, the found page is pinned at exit. 2637 * NOTE: Search result on stack, the found page is pinned at exit.
2643 * The result page must be an internal dtpage. 2638 * The result page must be an internal dtpage.
@@ -2660,7 +2655,7 @@ static int dtSearchNode(struct inode *ip, s64 lmxaddr, pxd_t * kpxd,
2660 BT_CLR(btstack); /* reset stack */ 2655 BT_CLR(btstack); /* reset stack */
2661 2656
2662 /* 2657 /*
2663 * descend tree to the level with specified leftmost page 2658 * descend tree to the level with specified leftmost page
2664 * 2659 *
2665 * by convention, root bn = 0. 2660 * by convention, root bn = 0.
2666 */ 2661 */
@@ -2699,7 +2694,7 @@ static int dtSearchNode(struct inode *ip, s64 lmxaddr, pxd_t * kpxd,
2699 } 2694 }
2700 2695
2701 /* 2696 /*
2702 * search each page at the current levevl 2697 * search each page at the current levevl
2703 */ 2698 */
2704 loop: 2699 loop:
2705 stbl = DT_GETSTBL(p); 2700 stbl = DT_GETSTBL(p);
@@ -3044,9 +3039,9 @@ int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
3044 if (DO_INDEX(ip)) { 3039 if (DO_INDEX(ip)) {
3045 /* 3040 /*
3046 * persistent index is stored in directory entries. 3041 * persistent index is stored in directory entries.
3047 * Special cases: 0 = . 3042 * Special cases: 0 = .
3048 * 1 = .. 3043 * 1 = ..
3049 * -1 = End of directory 3044 * -1 = End of directory
3050 */ 3045 */
3051 do_index = 1; 3046 do_index = 1;
3052 3047
@@ -3128,10 +3123,10 @@ int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
3128 /* 3123 /*
3129 * Legacy filesystem - OS/2 & Linux JFS < 0.3.6 3124 * Legacy filesystem - OS/2 & Linux JFS < 0.3.6
3130 * 3125 *
3131 * pn = index = 0: First entry "." 3126 * pn = index = 0: First entry "."
3132 * pn = 0; index = 1: Second entry ".." 3127 * pn = 0; index = 1: Second entry ".."
3133 * pn > 0: Real entries, pn=1 -> leftmost page 3128 * pn > 0: Real entries, pn=1 -> leftmost page
3134 * pn = index = -1: No more entries 3129 * pn = index = -1: No more entries
3135 */ 3130 */
3136 dtpos = filp->f_pos; 3131 dtpos = filp->f_pos;
3137 if (dtpos == 0) { 3132 if (dtpos == 0) {
@@ -3351,7 +3346,7 @@ static int dtReadFirst(struct inode *ip, struct btstack * btstack)
3351 BT_CLR(btstack); /* reset stack */ 3346 BT_CLR(btstack); /* reset stack */
3352 3347
3353 /* 3348 /*
3354 * descend leftmost path of the tree 3349 * descend leftmost path of the tree
3355 * 3350 *
3356 * by convention, root bn = 0. 3351 * by convention, root bn = 0.
3357 */ 3352 */
@@ -4531,7 +4526,7 @@ int dtModify(tid_t tid, struct inode *ip,
4531 struct ldtentry *entry; 4526 struct ldtentry *entry;
4532 4527
4533 /* 4528 /*
4534 * search for the entry to modify: 4529 * search for the entry to modify:
4535 * 4530 *
4536 * dtSearch() returns (leaf page pinned, index at which to modify). 4531 * dtSearch() returns (leaf page pinned, index at which to modify).
4537 */ 4532 */
diff --git a/fs/jfs/jfs_dtree.h b/fs/jfs/jfs_dtree.h
index af8513f78648..8561c6ecece0 100644
--- a/fs/jfs/jfs_dtree.h
+++ b/fs/jfs/jfs_dtree.h
@@ -35,7 +35,7 @@ typedef union {
35 35
36 36
37/* 37/*
38 * entry segment/slot 38 * entry segment/slot
39 * 39 *
40 * an entry consists of type dependent head/only segment/slot and 40 * an entry consists of type dependent head/only segment/slot and
41 * additional segments/slots linked vi next field; 41 * additional segments/slots linked vi next field;
diff --git a/fs/jfs/jfs_extent.c b/fs/jfs/jfs_extent.c
index a35bdca6a805..7ae1e3281de9 100644
--- a/fs/jfs/jfs_extent.c
+++ b/fs/jfs/jfs_extent.c
@@ -34,8 +34,8 @@ static int extBrealloc(struct inode *, s64, s64, s64 *, s64 *);
34#endif 34#endif
35static s64 extRoundDown(s64 nb); 35static s64 extRoundDown(s64 nb);
36 36
37#define DPD(a) (printk("(a): %d\n",(a))) 37#define DPD(a) (printk("(a): %d\n",(a)))
38#define DPC(a) (printk("(a): %c\n",(a))) 38#define DPC(a) (printk("(a): %c\n",(a)))
39#define DPL1(a) \ 39#define DPL1(a) \
40{ \ 40{ \
41 if ((a) >> 32) \ 41 if ((a) >> 32) \
@@ -51,19 +51,19 @@ static s64 extRoundDown(s64 nb);
51 printk("(a): %x\n",(a) << 32); \ 51 printk("(a): %x\n",(a) << 32); \
52} 52}
53 53
54#define DPD1(a) (printk("(a): %d ",(a))) 54#define DPD1(a) (printk("(a): %d ",(a)))
55#define DPX(a) (printk("(a): %08x\n",(a))) 55#define DPX(a) (printk("(a): %08x\n",(a)))
56#define DPX1(a) (printk("(a): %08x ",(a))) 56#define DPX1(a) (printk("(a): %08x ",(a)))
57#define DPS(a) (printk("%s\n",(a))) 57#define DPS(a) (printk("%s\n",(a)))
58#define DPE(a) (printk("\nENTERING: %s\n",(a))) 58#define DPE(a) (printk("\nENTERING: %s\n",(a)))
59#define DPE1(a) (printk("\nENTERING: %s",(a))) 59#define DPE1(a) (printk("\nENTERING: %s",(a)))
60#define DPS1(a) (printk(" %s ",(a))) 60#define DPS1(a) (printk(" %s ",(a)))
61 61
62 62
63/* 63/*
64 * NAME: extAlloc() 64 * NAME: extAlloc()
65 * 65 *
66 * FUNCTION: allocate an extent for a specified page range within a 66 * FUNCTION: allocate an extent for a specified page range within a
67 * file. 67 * file.
68 * 68 *
69 * PARAMETERS: 69 * PARAMETERS:
@@ -78,9 +78,9 @@ static s64 extRoundDown(s64 nb);
78 * should be marked as allocated but not recorded. 78 * should be marked as allocated but not recorded.
79 * 79 *
80 * RETURN VALUES: 80 * RETURN VALUES:
81 * 0 - success 81 * 0 - success
82 * -EIO - i/o error. 82 * -EIO - i/o error.
83 * -ENOSPC - insufficient disk resources. 83 * -ENOSPC - insufficient disk resources.
84 */ 84 */
85int 85int
86extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, bool abnr) 86extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, bool abnr)
@@ -192,9 +192,9 @@ extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, bool abnr)
192 192
193#ifdef _NOTYET 193#ifdef _NOTYET
194/* 194/*
195 * NAME: extRealloc() 195 * NAME: extRealloc()
196 * 196 *
197 * FUNCTION: extend the allocation of a file extent containing a 197 * FUNCTION: extend the allocation of a file extent containing a
198 * partial back last page. 198 * partial back last page.
199 * 199 *
200 * PARAMETERS: 200 * PARAMETERS:
@@ -207,9 +207,9 @@ extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, bool abnr)
207 * should be marked as allocated but not recorded. 207 * should be marked as allocated but not recorded.
208 * 208 *
209 * RETURN VALUES: 209 * RETURN VALUES:
210 * 0 - success 210 * 0 - success
211 * -EIO - i/o error. 211 * -EIO - i/o error.
212 * -ENOSPC - insufficient disk resources. 212 * -ENOSPC - insufficient disk resources.
213 */ 213 */
214int extRealloc(struct inode *ip, s64 nxlen, xad_t * xp, bool abnr) 214int extRealloc(struct inode *ip, s64 nxlen, xad_t * xp, bool abnr)
215{ 215{
@@ -345,9 +345,9 @@ exit:
345 345
346 346
347/* 347/*
348 * NAME: extHint() 348 * NAME: extHint()
349 * 349 *
350 * FUNCTION: produce an extent allocation hint for a file offset. 350 * FUNCTION: produce an extent allocation hint for a file offset.
351 * 351 *
352 * PARAMETERS: 352 * PARAMETERS:
353 * ip - the inode of the file. 353 * ip - the inode of the file.
@@ -356,8 +356,8 @@ exit:
356 * the hint. 356 * the hint.
357 * 357 *
358 * RETURN VALUES: 358 * RETURN VALUES:
359 * 0 - success 359 * 0 - success
360 * -EIO - i/o error. 360 * -EIO - i/o error.
361 */ 361 */
362int extHint(struct inode *ip, s64 offset, xad_t * xp) 362int extHint(struct inode *ip, s64 offset, xad_t * xp)
363{ 363{
@@ -387,7 +387,7 @@ int extHint(struct inode *ip, s64 offset, xad_t * xp)
387 lxdl.nlxd = 1; 387 lxdl.nlxd = 1;
388 lxdl.lxd = &lxd; 388 lxdl.lxd = &lxd;
389 LXDoffset(&lxd, prev) 389 LXDoffset(&lxd, prev)
390 LXDlength(&lxd, nbperpage); 390 LXDlength(&lxd, nbperpage);
391 391
392 xadl.maxnxad = 1; 392 xadl.maxnxad = 1;
393 xadl.nxad = 0; 393 xadl.nxad = 0;
@@ -397,11 +397,11 @@ int extHint(struct inode *ip, s64 offset, xad_t * xp)
397 if ((rc = xtLookupList(ip, &lxdl, &xadl, 0))) 397 if ((rc = xtLookupList(ip, &lxdl, &xadl, 0)))
398 return (rc); 398 return (rc);
399 399
400 /* check if not extent exists for the previous page. 400 /* check if no extent exists for the previous page.
401 * this is possible for sparse files. 401 * this is possible for sparse files.
402 */ 402 */
403 if (xadl.nxad == 0) { 403 if (xadl.nxad == 0) {
404// assert(ISSPARSE(ip)); 404// assert(ISSPARSE(ip));
405 return (0); 405 return (0);
406 } 406 }
407 407
@@ -410,28 +410,28 @@ int extHint(struct inode *ip, s64 offset, xad_t * xp)
410 */ 410 */
411 xp->flag &= XAD_NOTRECORDED; 411 xp->flag &= XAD_NOTRECORDED;
412 412
413 if(xadl.nxad != 1 || lengthXAD(xp) != nbperpage) { 413 if(xadl.nxad != 1 || lengthXAD(xp) != nbperpage) {
414 jfs_error(ip->i_sb, "extHint: corrupt xtree"); 414 jfs_error(ip->i_sb, "extHint: corrupt xtree");
415 return -EIO; 415 return -EIO;
416 } 416 }
417 417
418 return (0); 418 return (0);
419} 419}
420 420
421 421
422/* 422/*
423 * NAME: extRecord() 423 * NAME: extRecord()
424 * 424 *
425 * FUNCTION: change a page with a file from not recorded to recorded. 425 * FUNCTION: change a page with a file from not recorded to recorded.
426 * 426 *
427 * PARAMETERS: 427 * PARAMETERS:
428 * ip - inode of the file. 428 * ip - inode of the file.
429 * cp - cbuf of the file page. 429 * cp - cbuf of the file page.
430 * 430 *
431 * RETURN VALUES: 431 * RETURN VALUES:
432 * 0 - success 432 * 0 - success
433 * -EIO - i/o error. 433 * -EIO - i/o error.
434 * -ENOSPC - insufficient disk resources. 434 * -ENOSPC - insufficient disk resources.
435 */ 435 */
436int extRecord(struct inode *ip, xad_t * xp) 436int extRecord(struct inode *ip, xad_t * xp)
437{ 437{
@@ -451,9 +451,9 @@ int extRecord(struct inode *ip, xad_t * xp)
451 451
452#ifdef _NOTYET 452#ifdef _NOTYET
453/* 453/*
454 * NAME: extFill() 454 * NAME: extFill()
455 * 455 *
456 * FUNCTION: allocate disk space for a file page that represents 456 * FUNCTION: allocate disk space for a file page that represents
457 * a file hole. 457 * a file hole.
458 * 458 *
459 * PARAMETERS: 459 * PARAMETERS:
@@ -461,16 +461,16 @@ int extRecord(struct inode *ip, xad_t * xp)
461 * cp - cbuf of the file page represent the hole. 461 * cp - cbuf of the file page represent the hole.
462 * 462 *
463 * RETURN VALUES: 463 * RETURN VALUES:
464 * 0 - success 464 * 0 - success
465 * -EIO - i/o error. 465 * -EIO - i/o error.
466 * -ENOSPC - insufficient disk resources. 466 * -ENOSPC - insufficient disk resources.
467 */ 467 */
468int extFill(struct inode *ip, xad_t * xp) 468int extFill(struct inode *ip, xad_t * xp)
469{ 469{
470 int rc, nbperpage = JFS_SBI(ip->i_sb)->nbperpage; 470 int rc, nbperpage = JFS_SBI(ip->i_sb)->nbperpage;
471 s64 blkno = offsetXAD(xp) >> ip->i_blkbits; 471 s64 blkno = offsetXAD(xp) >> ip->i_blkbits;
472 472
473// assert(ISSPARSE(ip)); 473// assert(ISSPARSE(ip));
474 474
475 /* initialize the extent allocation hint */ 475 /* initialize the extent allocation hint */
476 XADaddress(xp, 0); 476 XADaddress(xp, 0);
@@ -489,7 +489,7 @@ int extFill(struct inode *ip, xad_t * xp)
489/* 489/*
490 * NAME: extBalloc() 490 * NAME: extBalloc()
491 * 491 *
492 * FUNCTION: allocate disk blocks to form an extent. 492 * FUNCTION: allocate disk blocks to form an extent.
493 * 493 *
494 * initially, we will try to allocate disk blocks for the 494 * initially, we will try to allocate disk blocks for the
495 * requested size (nblocks). if this fails (nblocks 495 * requested size (nblocks). if this fails (nblocks
@@ -513,9 +513,9 @@ int extFill(struct inode *ip, xad_t * xp)
513 * allocated block range. 513 * allocated block range.
514 * 514 *
515 * RETURN VALUES: 515 * RETURN VALUES:
516 * 0 - success 516 * 0 - success
517 * -EIO - i/o error. 517 * -EIO - i/o error.
518 * -ENOSPC - insufficient disk resources. 518 * -ENOSPC - insufficient disk resources.
519 */ 519 */
520static int 520static int
521extBalloc(struct inode *ip, s64 hint, s64 * nblocks, s64 * blkno) 521extBalloc(struct inode *ip, s64 hint, s64 * nblocks, s64 * blkno)
@@ -580,7 +580,7 @@ extBalloc(struct inode *ip, s64 hint, s64 * nblocks, s64 * blkno)
580/* 580/*
581 * NAME: extBrealloc() 581 * NAME: extBrealloc()
582 * 582 *
583 * FUNCTION: attempt to extend an extent's allocation. 583 * FUNCTION: attempt to extend an extent's allocation.
584 * 584 *
585 * Initially, we will try to extend the extent's allocation 585 * Initially, we will try to extend the extent's allocation
586 * in place. If this fails, we'll try to move the extent 586 * in place. If this fails, we'll try to move the extent
@@ -597,8 +597,8 @@ extBalloc(struct inode *ip, s64 hint, s64 * nblocks, s64 * blkno)
597 * 597 *
598 * PARAMETERS: 598 * PARAMETERS:
599 * ip - the inode of the file. 599 * ip - the inode of the file.
600 * blkno - starting block number of the extents current allocation. 600 * blkno - starting block number of the extents current allocation.
601 * nblks - number of blocks within the extents current allocation. 601 * nblks - number of blocks within the extents current allocation.
602 * newnblks - pointer to a s64 value. on entry, this value is the 602 * newnblks - pointer to a s64 value. on entry, this value is the
603 * the new desired extent size (number of blocks). on 603 * the new desired extent size (number of blocks). on
604 * successful exit, this value is set to the extent's actual 604 * successful exit, this value is set to the extent's actual
@@ -606,9 +606,9 @@ extBalloc(struct inode *ip, s64 hint, s64 * nblocks, s64 * blkno)
606 * newblkno - the starting block number of the extents new allocation. 606 * newblkno - the starting block number of the extents new allocation.
607 * 607 *
608 * RETURN VALUES: 608 * RETURN VALUES:
609 * 0 - success 609 * 0 - success
610 * -EIO - i/o error. 610 * -EIO - i/o error.
611 * -ENOSPC - insufficient disk resources. 611 * -ENOSPC - insufficient disk resources.
612 */ 612 */
613static int 613static int
614extBrealloc(struct inode *ip, 614extBrealloc(struct inode *ip,
@@ -634,16 +634,16 @@ extBrealloc(struct inode *ip,
634 634
635 635
636/* 636/*
637 * NAME: extRoundDown() 637 * NAME: extRoundDown()
638 * 638 *
639 * FUNCTION: round down a specified number of blocks to the next 639 * FUNCTION: round down a specified number of blocks to the next
640 * smallest power of 2 number. 640 * smallest power of 2 number.
641 * 641 *
642 * PARAMETERS: 642 * PARAMETERS:
643 * nb - the inode of the file. 643 * nb - the inode of the file.
644 * 644 *
645 * RETURN VALUES: 645 * RETURN VALUES:
646 * next smallest power of 2 number. 646 * next smallest power of 2 number.
647 */ 647 */
648static s64 extRoundDown(s64 nb) 648static s64 extRoundDown(s64 nb)
649{ 649{
diff --git a/fs/jfs/jfs_filsys.h b/fs/jfs/jfs_filsys.h
index 38f70ac03bec..b3f5463fbe52 100644
--- a/fs/jfs/jfs_filsys.h
+++ b/fs/jfs/jfs_filsys.h
@@ -34,9 +34,9 @@
34#define JFS_UNICODE 0x00000001 /* unicode name */ 34#define JFS_UNICODE 0x00000001 /* unicode name */
35 35
36/* mount time flags for error handling */ 36/* mount time flags for error handling */
37#define JFS_ERR_REMOUNT_RO 0x00000002 /* remount read-only */ 37#define JFS_ERR_REMOUNT_RO 0x00000002 /* remount read-only */
38#define JFS_ERR_CONTINUE 0x00000004 /* continue */ 38#define JFS_ERR_CONTINUE 0x00000004 /* continue */
39#define JFS_ERR_PANIC 0x00000008 /* panic */ 39#define JFS_ERR_PANIC 0x00000008 /* panic */
40 40
41/* Quota support */ 41/* Quota support */
42#define JFS_USRQUOTA 0x00000010 42#define JFS_USRQUOTA 0x00000010
@@ -83,7 +83,6 @@
83/* case-insensitive name/directory support */ 83/* case-insensitive name/directory support */
84 84
85#define JFS_AIX 0x80000000 /* AIX support */ 85#define JFS_AIX 0x80000000 /* AIX support */
86/* POSIX name/directory support - Never implemented*/
87 86
88/* 87/*
89 * buffer cache configuration 88 * buffer cache configuration
@@ -113,10 +112,10 @@
113#define IDATASIZE 256 /* inode inline data size */ 112#define IDATASIZE 256 /* inode inline data size */
114#define IXATTRSIZE 128 /* inode inline extended attribute size */ 113#define IXATTRSIZE 128 /* inode inline extended attribute size */
115 114
116#define XTPAGE_SIZE 4096 115#define XTPAGE_SIZE 4096
117#define log2_PAGESIZE 12 116#define log2_PAGESIZE 12
118 117
119#define IAG_SIZE 4096 118#define IAG_SIZE 4096
120#define IAG_EXTENT_SIZE 4096 119#define IAG_EXTENT_SIZE 4096
121#define INOSPERIAG 4096 /* number of disk inodes per iag */ 120#define INOSPERIAG 4096 /* number of disk inodes per iag */
122#define L2INOSPERIAG 12 /* l2 number of disk inodes per iag */ 121#define L2INOSPERIAG 12 /* l2 number of disk inodes per iag */
diff --git a/fs/jfs/jfs_imap.c b/fs/jfs/jfs_imap.c
index c6530227cda6..3870ba8b9086 100644
--- a/fs/jfs/jfs_imap.c
+++ b/fs/jfs/jfs_imap.c
@@ -93,21 +93,21 @@ static int copy_from_dinode(struct dinode *, struct inode *);
93static void copy_to_dinode(struct dinode *, struct inode *); 93static void copy_to_dinode(struct dinode *, struct inode *);
94 94
95/* 95/*
96 * NAME: diMount() 96 * NAME: diMount()
97 * 97 *
98 * FUNCTION: initialize the incore inode map control structures for 98 * FUNCTION: initialize the incore inode map control structures for
99 * a fileset or aggregate init time. 99 * a fileset or aggregate init time.
100 * 100 *
101 * the inode map's control structure (dinomap) is 101 * the inode map's control structure (dinomap) is
102 * brought in from disk and placed in virtual memory. 102 * brought in from disk and placed in virtual memory.
103 * 103 *
104 * PARAMETERS: 104 * PARAMETERS:
105 * ipimap - pointer to inode map inode for the aggregate or fileset. 105 * ipimap - pointer to inode map inode for the aggregate or fileset.
106 * 106 *
107 * RETURN VALUES: 107 * RETURN VALUES:
108 * 0 - success 108 * 0 - success
109 * -ENOMEM - insufficient free virtual memory. 109 * -ENOMEM - insufficient free virtual memory.
110 * -EIO - i/o error. 110 * -EIO - i/o error.
111 */ 111 */
112int diMount(struct inode *ipimap) 112int diMount(struct inode *ipimap)
113{ 113{
@@ -180,18 +180,18 @@ int diMount(struct inode *ipimap)
180 180
181 181
182/* 182/*
183 * NAME: diUnmount() 183 * NAME: diUnmount()
184 * 184 *
185 * FUNCTION: write to disk the incore inode map control structures for 185 * FUNCTION: write to disk the incore inode map control structures for
186 * a fileset or aggregate at unmount time. 186 * a fileset or aggregate at unmount time.
187 * 187 *
188 * PARAMETERS: 188 * PARAMETERS:
189 * ipimap - pointer to inode map inode for the aggregate or fileset. 189 * ipimap - pointer to inode map inode for the aggregate or fileset.
190 * 190 *
191 * RETURN VALUES: 191 * RETURN VALUES:
192 * 0 - success 192 * 0 - success
193 * -ENOMEM - insufficient free virtual memory. 193 * -ENOMEM - insufficient free virtual memory.
194 * -EIO - i/o error. 194 * -EIO - i/o error.
195 */ 195 */
196int diUnmount(struct inode *ipimap, int mounterror) 196int diUnmount(struct inode *ipimap, int mounterror)
197{ 197{
@@ -274,9 +274,9 @@ int diSync(struct inode *ipimap)
274 274
275 275
276/* 276/*
277 * NAME: diRead() 277 * NAME: diRead()
278 * 278 *
279 * FUNCTION: initialize an incore inode from disk. 279 * FUNCTION: initialize an incore inode from disk.
280 * 280 *
281 * on entry, the specifed incore inode should itself 281 * on entry, the specifed incore inode should itself
282 * specify the disk inode number corresponding to the 282 * specify the disk inode number corresponding to the
@@ -285,7 +285,7 @@ int diSync(struct inode *ipimap)
285 * this routine handles incore inode initialization for 285 * this routine handles incore inode initialization for
286 * both "special" and "regular" inodes. special inodes 286 * both "special" and "regular" inodes. special inodes
287 * are those required early in the mount process and 287 * are those required early in the mount process and
288 * require special handling since much of the file system 288 * require special handling since much of the file system
289 * is not yet initialized. these "special" inodes are 289 * is not yet initialized. these "special" inodes are
290 * identified by a NULL inode map inode pointer and are 290 * identified by a NULL inode map inode pointer and are
291 * actually initialized by a call to diReadSpecial(). 291 * actually initialized by a call to diReadSpecial().
@@ -298,12 +298,12 @@ int diSync(struct inode *ipimap)
298 * incore inode. 298 * incore inode.
299 * 299 *
300 * PARAMETERS: 300 * PARAMETERS:
301 * ip - pointer to incore inode to be initialized from disk. 301 * ip - pointer to incore inode to be initialized from disk.
302 * 302 *
303 * RETURN VALUES: 303 * RETURN VALUES:
304 * 0 - success 304 * 0 - success
305 * -EIO - i/o error. 305 * -EIO - i/o error.
306 * -ENOMEM - insufficient memory 306 * -ENOMEM - insufficient memory
307 * 307 *
308 */ 308 */
309int diRead(struct inode *ip) 309int diRead(struct inode *ip)
@@ -410,26 +410,26 @@ int diRead(struct inode *ip)
410 410
411 411
412/* 412/*
413 * NAME: diReadSpecial() 413 * NAME: diReadSpecial()
414 * 414 *
415 * FUNCTION: initialize a 'special' inode from disk. 415 * FUNCTION: initialize a 'special' inode from disk.
416 * 416 *
417 * this routines handles aggregate level inodes. The 417 * this routines handles aggregate level inodes. The
418 * inode cache cannot differentiate between the 418 * inode cache cannot differentiate between the
419 * aggregate inodes and the filesystem inodes, so we 419 * aggregate inodes and the filesystem inodes, so we
420 * handle these here. We don't actually use the aggregate 420 * handle these here. We don't actually use the aggregate
421 * inode map, since these inodes are at a fixed location 421 * inode map, since these inodes are at a fixed location
422 * and in some cases the aggregate inode map isn't initialized 422 * and in some cases the aggregate inode map isn't initialized
423 * yet. 423 * yet.
424 * 424 *
425 * PARAMETERS: 425 * PARAMETERS:
426 * sb - filesystem superblock 426 * sb - filesystem superblock
427 * inum - aggregate inode number 427 * inum - aggregate inode number
428 * secondary - 1 if secondary aggregate inode table 428 * secondary - 1 if secondary aggregate inode table
429 * 429 *
430 * RETURN VALUES: 430 * RETURN VALUES:
431 * new inode - success 431 * new inode - success
432 * NULL - i/o error. 432 * NULL - i/o error.
433 */ 433 */
434struct inode *diReadSpecial(struct super_block *sb, ino_t inum, int secondary) 434struct inode *diReadSpecial(struct super_block *sb, ino_t inum, int secondary)
435{ 435{
@@ -502,12 +502,12 @@ struct inode *diReadSpecial(struct super_block *sb, ino_t inum, int secondary)
502} 502}
503 503
504/* 504/*
505 * NAME: diWriteSpecial() 505 * NAME: diWriteSpecial()
506 * 506 *
507 * FUNCTION: Write the special inode to disk 507 * FUNCTION: Write the special inode to disk
508 * 508 *
509 * PARAMETERS: 509 * PARAMETERS:
510 * ip - special inode 510 * ip - special inode
511 * secondary - 1 if secondary aggregate inode table 511 * secondary - 1 if secondary aggregate inode table
512 * 512 *
513 * RETURN VALUES: none 513 * RETURN VALUES: none
@@ -554,9 +554,9 @@ void diWriteSpecial(struct inode *ip, int secondary)
554} 554}
555 555
556/* 556/*
557 * NAME: diFreeSpecial() 557 * NAME: diFreeSpecial()
558 * 558 *
559 * FUNCTION: Free allocated space for special inode 559 * FUNCTION: Free allocated space for special inode
560 */ 560 */
561void diFreeSpecial(struct inode *ip) 561void diFreeSpecial(struct inode *ip)
562{ 562{
@@ -572,9 +572,9 @@ void diFreeSpecial(struct inode *ip)
572 572
573 573
574/* 574/*
575 * NAME: diWrite() 575 * NAME: diWrite()
576 * 576 *
577 * FUNCTION: write the on-disk inode portion of the in-memory inode 577 * FUNCTION: write the on-disk inode portion of the in-memory inode
578 * to its corresponding on-disk inode. 578 * to its corresponding on-disk inode.
579 * 579 *
580 * on entry, the specifed incore inode should itself 580 * on entry, the specifed incore inode should itself
@@ -589,11 +589,11 @@ void diFreeSpecial(struct inode *ip)
589 * 589 *
590 * PARAMETERS: 590 * PARAMETERS:
591 * tid - transacation id 591 * tid - transacation id
592 * ip - pointer to incore inode to be written to the inode extent. 592 * ip - pointer to incore inode to be written to the inode extent.
593 * 593 *
594 * RETURN VALUES: 594 * RETURN VALUES:
595 * 0 - success 595 * 0 - success
596 * -EIO - i/o error. 596 * -EIO - i/o error.
597 */ 597 */
598int diWrite(tid_t tid, struct inode *ip) 598int diWrite(tid_t tid, struct inode *ip)
599{ 599{
@@ -730,7 +730,7 @@ int diWrite(tid_t tid, struct inode *ip)
730 ilinelock = (struct linelock *) & tlck->lock; 730 ilinelock = (struct linelock *) & tlck->lock;
731 731
732 /* 732 /*
733 * regular file: 16 byte (XAD slot) granularity 733 * regular file: 16 byte (XAD slot) granularity
734 */ 734 */
735 if (type & tlckXTREE) { 735 if (type & tlckXTREE) {
736 xtpage_t *p, *xp; 736 xtpage_t *p, *xp;
@@ -755,7 +755,7 @@ int diWrite(tid_t tid, struct inode *ip)
755 xad->flag &= ~(XAD_NEW | XAD_EXTENDED); 755 xad->flag &= ~(XAD_NEW | XAD_EXTENDED);
756 } 756 }
757 /* 757 /*
758 * directory: 32 byte (directory entry slot) granularity 758 * directory: 32 byte (directory entry slot) granularity
759 */ 759 */
760 else if (type & tlckDTREE) { 760 else if (type & tlckDTREE) {
761 dtpage_t *p, *xp; 761 dtpage_t *p, *xp;
@@ -800,9 +800,8 @@ int diWrite(tid_t tid, struct inode *ip)
800 } 800 }
801 801
802 /* 802 /*
803 * lock/copy inode base: 128 byte slot granularity 803 * lock/copy inode base: 128 byte slot granularity
804 */ 804 */
805// baseDinode:
806 lv = & dilinelock->lv[dilinelock->index]; 805 lv = & dilinelock->lv[dilinelock->index];
807 lv->offset = dioffset >> L2INODESLOTSIZE; 806 lv->offset = dioffset >> L2INODESLOTSIZE;
808 copy_to_dinode(dp, ip); 807 copy_to_dinode(dp, ip);
@@ -813,17 +812,6 @@ int diWrite(tid_t tid, struct inode *ip)
813 lv->length = 1; 812 lv->length = 1;
814 dilinelock->index++; 813 dilinelock->index++;
815 814
816#ifdef _JFS_FASTDASD
817 /*
818 * We aren't logging changes to the DASD used in directory inodes,
819 * but we need to write them to disk. If we don't unmount cleanly,
820 * mount will recalculate the DASD used.
821 */
822 if (S_ISDIR(ip->i_mode)
823 && (ip->i_ipmnt->i_mntflag & JFS_DASD_ENABLED))
824 memcpy(&dp->di_DASD, &ip->i_DASD, sizeof(struct dasd));
825#endif /* _JFS_FASTDASD */
826
827 /* release the buffer holding the updated on-disk inode. 815 /* release the buffer holding the updated on-disk inode.
828 * the buffer will be later written by commit processing. 816 * the buffer will be later written by commit processing.
829 */ 817 */
@@ -834,9 +822,9 @@ int diWrite(tid_t tid, struct inode *ip)
834 822
835 823
836/* 824/*
837 * NAME: diFree(ip) 825 * NAME: diFree(ip)
838 * 826 *
839 * FUNCTION: free a specified inode from the inode working map 827 * FUNCTION: free a specified inode from the inode working map
840 * for a fileset or aggregate. 828 * for a fileset or aggregate.
841 * 829 *
842 * if the inode to be freed represents the first (only) 830 * if the inode to be freed represents the first (only)
@@ -865,11 +853,11 @@ int diWrite(tid_t tid, struct inode *ip)
865 * any updates and are held until all updates are complete. 853 * any updates and are held until all updates are complete.
866 * 854 *
867 * PARAMETERS: 855 * PARAMETERS:
868 * ip - inode to be freed. 856 * ip - inode to be freed.
869 * 857 *
870 * RETURN VALUES: 858 * RETURN VALUES:
871 * 0 - success 859 * 0 - success
872 * -EIO - i/o error. 860 * -EIO - i/o error.
873 */ 861 */
874int diFree(struct inode *ip) 862int diFree(struct inode *ip)
875{ 863{
@@ -902,7 +890,8 @@ int diFree(struct inode *ip)
902 * the map. 890 * the map.
903 */ 891 */
904 if (iagno >= imap->im_nextiag) { 892 if (iagno >= imap->im_nextiag) {
905 dump_mem("imap", imap, 32); 893 print_hex_dump(KERN_ERR, "imap: ", DUMP_PREFIX_ADDRESS, 16, 4,
894 imap, 32, 0);
906 jfs_error(ip->i_sb, 895 jfs_error(ip->i_sb,
907 "diFree: inum = %d, iagno = %d, nextiag = %d", 896 "diFree: inum = %d, iagno = %d, nextiag = %d",
908 (uint) inum, iagno, imap->im_nextiag); 897 (uint) inum, iagno, imap->im_nextiag);
@@ -964,8 +953,8 @@ int diFree(struct inode *ip)
964 return -EIO; 953 return -EIO;
965 } 954 }
966 /* 955 /*
967 * inode extent still has some inodes or below low water mark: 956 * inode extent still has some inodes or below low water mark:
968 * keep the inode extent; 957 * keep the inode extent;
969 */ 958 */
970 if (bitmap || 959 if (bitmap ||
971 imap->im_agctl[agno].numfree < 96 || 960 imap->im_agctl[agno].numfree < 96 ||
@@ -1047,12 +1036,12 @@ int diFree(struct inode *ip)
1047 1036
1048 1037
1049 /* 1038 /*
1050 * inode extent has become free and above low water mark: 1039 * inode extent has become free and above low water mark:
1051 * free the inode extent; 1040 * free the inode extent;
1052 */ 1041 */
1053 1042
1054 /* 1043 /*
1055 * prepare to update iag list(s) (careful update step 1) 1044 * prepare to update iag list(s) (careful update step 1)
1056 */ 1045 */
1057 amp = bmp = cmp = dmp = NULL; 1046 amp = bmp = cmp = dmp = NULL;
1058 fwd = back = -1; 1047 fwd = back = -1;
@@ -1152,7 +1141,7 @@ int diFree(struct inode *ip)
1152 invalidate_pxd_metapages(ip, freepxd); 1141 invalidate_pxd_metapages(ip, freepxd);
1153 1142
1154 /* 1143 /*
1155 * update iag list(s) (careful update step 2) 1144 * update iag list(s) (careful update step 2)
1156 */ 1145 */
1157 /* add the iag to the ag extent free list if this is the 1146 /* add the iag to the ag extent free list if this is the
1158 * first free extent for the iag. 1147 * first free extent for the iag.
@@ -1338,20 +1327,20 @@ diInitInode(struct inode *ip, int iagno, int ino, int extno, struct iag * iagp)
1338 1327
1339 1328
1340/* 1329/*
1341 * NAME: diAlloc(pip,dir,ip) 1330 * NAME: diAlloc(pip,dir,ip)
1342 * 1331 *
1343 * FUNCTION: allocate a disk inode from the inode working map 1332 * FUNCTION: allocate a disk inode from the inode working map
1344 * for a fileset or aggregate. 1333 * for a fileset or aggregate.
1345 * 1334 *
1346 * PARAMETERS: 1335 * PARAMETERS:
1347 * pip - pointer to incore inode for the parent inode. 1336 * pip - pointer to incore inode for the parent inode.
1348 * dir - 'true' if the new disk inode is for a directory. 1337 * dir - 'true' if the new disk inode is for a directory.
1349 * ip - pointer to a new inode 1338 * ip - pointer to a new inode
1350 * 1339 *
1351 * RETURN VALUES: 1340 * RETURN VALUES:
1352 * 0 - success. 1341 * 0 - success.
1353 * -ENOSPC - insufficient disk resources. 1342 * -ENOSPC - insufficient disk resources.
1354 * -EIO - i/o error. 1343 * -EIO - i/o error.
1355 */ 1344 */
1356int diAlloc(struct inode *pip, bool dir, struct inode *ip) 1345int diAlloc(struct inode *pip, bool dir, struct inode *ip)
1357{ 1346{
@@ -1433,7 +1422,7 @@ int diAlloc(struct inode *pip, bool dir, struct inode *ip)
1433 addext = (imap->im_agctl[agno].numfree < 32 && iagp->nfreeexts); 1422 addext = (imap->im_agctl[agno].numfree < 32 && iagp->nfreeexts);
1434 1423
1435 /* 1424 /*
1436 * try to allocate from the IAG 1425 * try to allocate from the IAG
1437 */ 1426 */
1438 /* check if the inode may be allocated from the iag 1427 /* check if the inode may be allocated from the iag
1439 * (i.e. the inode has free inodes or new extent can be added). 1428 * (i.e. the inode has free inodes or new extent can be added).
@@ -1633,9 +1622,9 @@ int diAlloc(struct inode *pip, bool dir, struct inode *ip)
1633 1622
1634 1623
1635/* 1624/*
1636 * NAME: diAllocAG(imap,agno,dir,ip) 1625 * NAME: diAllocAG(imap,agno,dir,ip)
1637 * 1626 *
1638 * FUNCTION: allocate a disk inode from the allocation group. 1627 * FUNCTION: allocate a disk inode from the allocation group.
1639 * 1628 *
1640 * this routine first determines if a new extent of free 1629 * this routine first determines if a new extent of free
1641 * inodes should be added for the allocation group, with 1630 * inodes should be added for the allocation group, with
@@ -1649,17 +1638,17 @@ int diAlloc(struct inode *pip, bool dir, struct inode *ip)
1649 * PRE CONDITION: Already have the AG lock for this AG. 1638 * PRE CONDITION: Already have the AG lock for this AG.
1650 * 1639 *
1651 * PARAMETERS: 1640 * PARAMETERS:
1652 * imap - pointer to inode map control structure. 1641 * imap - pointer to inode map control structure.
1653 * agno - allocation group to allocate from. 1642 * agno - allocation group to allocate from.
1654 * dir - 'true' if the new disk inode is for a directory. 1643 * dir - 'true' if the new disk inode is for a directory.
1655 * ip - pointer to the new inode to be filled in on successful return 1644 * ip - pointer to the new inode to be filled in on successful return
1656 * with the disk inode number allocated, its extent address 1645 * with the disk inode number allocated, its extent address
1657 * and the start of the ag. 1646 * and the start of the ag.
1658 * 1647 *
1659 * RETURN VALUES: 1648 * RETURN VALUES:
1660 * 0 - success. 1649 * 0 - success.
1661 * -ENOSPC - insufficient disk resources. 1650 * -ENOSPC - insufficient disk resources.
1662 * -EIO - i/o error. 1651 * -EIO - i/o error.
1663 */ 1652 */
1664static int 1653static int
1665diAllocAG(struct inomap * imap, int agno, bool dir, struct inode *ip) 1654diAllocAG(struct inomap * imap, int agno, bool dir, struct inode *ip)
@@ -1709,9 +1698,9 @@ diAllocAG(struct inomap * imap, int agno, bool dir, struct inode *ip)
1709 1698
1710 1699
1711/* 1700/*
1712 * NAME: diAllocAny(imap,agno,dir,iap) 1701 * NAME: diAllocAny(imap,agno,dir,iap)
1713 * 1702 *
1714 * FUNCTION: allocate a disk inode from any other allocation group. 1703 * FUNCTION: allocate a disk inode from any other allocation group.
1715 * 1704 *
1716 * this routine is called when an allocation attempt within 1705 * this routine is called when an allocation attempt within
1717 * the primary allocation group has failed. if attempts to 1706 * the primary allocation group has failed. if attempts to
@@ -1719,17 +1708,17 @@ diAllocAG(struct inomap * imap, int agno, bool dir, struct inode *ip)
1719 * specified primary group. 1708 * specified primary group.
1720 * 1709 *
1721 * PARAMETERS: 1710 * PARAMETERS:
1722 * imap - pointer to inode map control structure. 1711 * imap - pointer to inode map control structure.
1723 * agno - primary allocation group (to avoid). 1712 * agno - primary allocation group (to avoid).
1724 * dir - 'true' if the new disk inode is for a directory. 1713 * dir - 'true' if the new disk inode is for a directory.
1725 * ip - pointer to a new inode to be filled in on successful return 1714 * ip - pointer to a new inode to be filled in on successful return
1726 * with the disk inode number allocated, its extent address 1715 * with the disk inode number allocated, its extent address
1727 * and the start of the ag. 1716 * and the start of the ag.
1728 * 1717 *
1729 * RETURN VALUES: 1718 * RETURN VALUES:
1730 * 0 - success. 1719 * 0 - success.
1731 * -ENOSPC - insufficient disk resources. 1720 * -ENOSPC - insufficient disk resources.
1732 * -EIO - i/o error. 1721 * -EIO - i/o error.
1733 */ 1722 */
1734static int 1723static int
1735diAllocAny(struct inomap * imap, int agno, bool dir, struct inode *ip) 1724diAllocAny(struct inomap * imap, int agno, bool dir, struct inode *ip)
@@ -1772,9 +1761,9 @@ diAllocAny(struct inomap * imap, int agno, bool dir, struct inode *ip)
1772 1761
1773 1762
1774/* 1763/*
1775 * NAME: diAllocIno(imap,agno,ip) 1764 * NAME: diAllocIno(imap,agno,ip)
1776 * 1765 *
1777 * FUNCTION: allocate a disk inode from the allocation group's free 1766 * FUNCTION: allocate a disk inode from the allocation group's free
1778 * inode list, returning an error if this free list is 1767 * inode list, returning an error if this free list is
1779 * empty (i.e. no iags on the list). 1768 * empty (i.e. no iags on the list).
1780 * 1769 *
@@ -1785,16 +1774,16 @@ diAllocAny(struct inomap * imap, int agno, bool dir, struct inode *ip)
1785 * PRE CONDITION: Already have AG lock for this AG. 1774 * PRE CONDITION: Already have AG lock for this AG.
1786 * 1775 *
1787 * PARAMETERS: 1776 * PARAMETERS:
1788 * imap - pointer to inode map control structure. 1777 * imap - pointer to inode map control structure.
1789 * agno - allocation group. 1778 * agno - allocation group.
1790 * ip - pointer to new inode to be filled in on successful return 1779 * ip - pointer to new inode to be filled in on successful return
1791 * with the disk inode number allocated, its extent address 1780 * with the disk inode number allocated, its extent address
1792 * and the start of the ag. 1781 * and the start of the ag.
1793 * 1782 *
1794 * RETURN VALUES: 1783 * RETURN VALUES:
1795 * 0 - success. 1784 * 0 - success.
1796 * -ENOSPC - insufficient disk resources. 1785 * -ENOSPC - insufficient disk resources.
1797 * -EIO - i/o error. 1786 * -EIO - i/o error.
1798 */ 1787 */
1799static int diAllocIno(struct inomap * imap, int agno, struct inode *ip) 1788static int diAllocIno(struct inomap * imap, int agno, struct inode *ip)
1800{ 1789{
@@ -1890,7 +1879,7 @@ static int diAllocIno(struct inomap * imap, int agno, struct inode *ip)
1890 1879
1891 1880
1892/* 1881/*
1893 * NAME: diAllocExt(imap,agno,ip) 1882 * NAME: diAllocExt(imap,agno,ip)
1894 * 1883 *
1895 * FUNCTION: add a new extent of free inodes to an iag, allocating 1884 * FUNCTION: add a new extent of free inodes to an iag, allocating
1896 * an inode from this extent to satisfy the current allocation 1885 * an inode from this extent to satisfy the current allocation
@@ -1910,16 +1899,16 @@ static int diAllocIno(struct inomap * imap, int agno, struct inode *ip)
1910 * for the purpose of satisfying this request. 1899 * for the purpose of satisfying this request.
1911 * 1900 *
1912 * PARAMETERS: 1901 * PARAMETERS:
1913 * imap - pointer to inode map control structure. 1902 * imap - pointer to inode map control structure.
1914 * agno - allocation group number. 1903 * agno - allocation group number.
1915 * ip - pointer to new inode to be filled in on successful return 1904 * ip - pointer to new inode to be filled in on successful return
1916 * with the disk inode number allocated, its extent address 1905 * with the disk inode number allocated, its extent address
1917 * and the start of the ag. 1906 * and the start of the ag.
1918 * 1907 *
1919 * RETURN VALUES: 1908 * RETURN VALUES:
1920 * 0 - success. 1909 * 0 - success.
1921 * -ENOSPC - insufficient disk resources. 1910 * -ENOSPC - insufficient disk resources.
1922 * -EIO - i/o error. 1911 * -EIO - i/o error.
1923 */ 1912 */
1924static int diAllocExt(struct inomap * imap, int agno, struct inode *ip) 1913static int diAllocExt(struct inomap * imap, int agno, struct inode *ip)
1925{ 1914{
@@ -2010,7 +1999,7 @@ static int diAllocExt(struct inomap * imap, int agno, struct inode *ip)
2010 1999
2011 2000
2012/* 2001/*
2013 * NAME: diAllocBit(imap,iagp,ino) 2002 * NAME: diAllocBit(imap,iagp,ino)
2014 * 2003 *
2015 * FUNCTION: allocate a backed inode from an iag. 2004 * FUNCTION: allocate a backed inode from an iag.
2016 * 2005 *
@@ -2030,14 +2019,14 @@ static int diAllocExt(struct inomap * imap, int agno, struct inode *ip)
2030 * this AG. Must have read lock on imap inode. 2019 * this AG. Must have read lock on imap inode.
2031 * 2020 *
2032 * PARAMETERS: 2021 * PARAMETERS:
2033 * imap - pointer to inode map control structure. 2022 * imap - pointer to inode map control structure.
2034 * iagp - pointer to iag. 2023 * iagp - pointer to iag.
2035 * ino - inode number to be allocated within the iag. 2024 * ino - inode number to be allocated within the iag.
2036 * 2025 *
2037 * RETURN VALUES: 2026 * RETURN VALUES:
2038 * 0 - success. 2027 * 0 - success.
2039 * -ENOSPC - insufficient disk resources. 2028 * -ENOSPC - insufficient disk resources.
2040 * -EIO - i/o error. 2029 * -EIO - i/o error.
2041 */ 2030 */
2042static int diAllocBit(struct inomap * imap, struct iag * iagp, int ino) 2031static int diAllocBit(struct inomap * imap, struct iag * iagp, int ino)
2043{ 2032{
@@ -2144,11 +2133,11 @@ static int diAllocBit(struct inomap * imap, struct iag * iagp, int ino)
2144 2133
2145 2134
2146/* 2135/*
2147 * NAME: diNewExt(imap,iagp,extno) 2136 * NAME: diNewExt(imap,iagp,extno)
2148 * 2137 *
2149 * FUNCTION: initialize a new extent of inodes for an iag, allocating 2138 * FUNCTION: initialize a new extent of inodes for an iag, allocating
2150 * the first inode of the extent for use for the current 2139 * the first inode of the extent for use for the current
2151 * allocation request. 2140 * allocation request.
2152 * 2141 *
2153 * disk resources are allocated for the new extent of inodes 2142 * disk resources are allocated for the new extent of inodes
2154 * and the inodes themselves are initialized to reflect their 2143 * and the inodes themselves are initialized to reflect their
@@ -2177,14 +2166,14 @@ static int diAllocBit(struct inomap * imap, struct iag * iagp, int ino)
2177 * this AG. Must have read lock on imap inode. 2166 * this AG. Must have read lock on imap inode.
2178 * 2167 *
2179 * PARAMETERS: 2168 * PARAMETERS:
2180 * imap - pointer to inode map control structure. 2169 * imap - pointer to inode map control structure.
2181 * iagp - pointer to iag. 2170 * iagp - pointer to iag.
2182 * extno - extent number. 2171 * extno - extent number.
2183 * 2172 *
2184 * RETURN VALUES: 2173 * RETURN VALUES:
2185 * 0 - success. 2174 * 0 - success.
2186 * -ENOSPC - insufficient disk resources. 2175 * -ENOSPC - insufficient disk resources.
2187 * -EIO - i/o error. 2176 * -EIO - i/o error.
2188 */ 2177 */
2189static int diNewExt(struct inomap * imap, struct iag * iagp, int extno) 2178static int diNewExt(struct inomap * imap, struct iag * iagp, int extno)
2190{ 2179{
@@ -2430,7 +2419,7 @@ static int diNewExt(struct inomap * imap, struct iag * iagp, int extno)
2430 2419
2431 2420
2432/* 2421/*
2433 * NAME: diNewIAG(imap,iagnop,agno) 2422 * NAME: diNewIAG(imap,iagnop,agno)
2434 * 2423 *
2435 * FUNCTION: allocate a new iag for an allocation group. 2424 * FUNCTION: allocate a new iag for an allocation group.
2436 * 2425 *
@@ -2443,16 +2432,16 @@ static int diNewExt(struct inomap * imap, struct iag * iagp, int extno)
2443 * and returned to satisfy the request. 2432 * and returned to satisfy the request.
2444 * 2433 *
2445 * PARAMETERS: 2434 * PARAMETERS:
2446 * imap - pointer to inode map control structure. 2435 * imap - pointer to inode map control structure.
2447 * iagnop - pointer to an iag number set with the number of the 2436 * iagnop - pointer to an iag number set with the number of the
2448 * newly allocated iag upon successful return. 2437 * newly allocated iag upon successful return.
2449 * agno - allocation group number. 2438 * agno - allocation group number.
2450 * bpp - Buffer pointer to be filled in with new IAG's buffer 2439 * bpp - Buffer pointer to be filled in with new IAG's buffer
2451 * 2440 *
2452 * RETURN VALUES: 2441 * RETURN VALUES:
2453 * 0 - success. 2442 * 0 - success.
2454 * -ENOSPC - insufficient disk resources. 2443 * -ENOSPC - insufficient disk resources.
2455 * -EIO - i/o error. 2444 * -EIO - i/o error.
2456 * 2445 *
2457 * serialization: 2446 * serialization:
2458 * AG lock held on entry/exit; 2447 * AG lock held on entry/exit;
@@ -2461,7 +2450,7 @@ static int diNewExt(struct inomap * imap, struct iag * iagp, int extno)
2461 * 2450 *
2462 * note: new iag transaction: 2451 * note: new iag transaction:
2463 * . synchronously write iag; 2452 * . synchronously write iag;
2464 * . write log of xtree and inode of imap; 2453 * . write log of xtree and inode of imap;
2465 * . commit; 2454 * . commit;
2466 * . synchronous write of xtree (right to left, bottom to top); 2455 * . synchronous write of xtree (right to left, bottom to top);
2467 * . at start of logredo(): init in-memory imap with one additional iag page; 2456 * . at start of logredo(): init in-memory imap with one additional iag page;
@@ -2481,9 +2470,6 @@ diNewIAG(struct inomap * imap, int *iagnop, int agno, struct metapage ** mpp)
2481 s64 xaddr = 0; 2470 s64 xaddr = 0;
2482 s64 blkno; 2471 s64 blkno;
2483 tid_t tid; 2472 tid_t tid;
2484#ifdef _STILL_TO_PORT
2485 xad_t xad;
2486#endif /* _STILL_TO_PORT */
2487 struct inode *iplist[1]; 2473 struct inode *iplist[1];
2488 2474
2489 /* pick up pointers to the inode map and mount inodes */ 2475 /* pick up pointers to the inode map and mount inodes */
@@ -2674,15 +2660,15 @@ diNewIAG(struct inomap * imap, int *iagnop, int agno, struct metapage ** mpp)
2674} 2660}
2675 2661
2676/* 2662/*
2677 * NAME: diIAGRead() 2663 * NAME: diIAGRead()
2678 * 2664 *
2679 * FUNCTION: get the buffer for the specified iag within a fileset 2665 * FUNCTION: get the buffer for the specified iag within a fileset
2680 * or aggregate inode map. 2666 * or aggregate inode map.
2681 * 2667 *
2682 * PARAMETERS: 2668 * PARAMETERS:
2683 * imap - pointer to inode map control structure. 2669 * imap - pointer to inode map control structure.
2684 * iagno - iag number. 2670 * iagno - iag number.
2685 * bpp - point to buffer pointer to be filled in on successful 2671 * bpp - point to buffer pointer to be filled in on successful
2686 * exit. 2672 * exit.
2687 * 2673 *
2688 * SERIALIZATION: 2674 * SERIALIZATION:
@@ -2691,8 +2677,8 @@ diNewIAG(struct inomap * imap, int *iagnop, int agno, struct metapage ** mpp)
2691 * the read lock is unnecessary.) 2677 * the read lock is unnecessary.)
2692 * 2678 *
2693 * RETURN VALUES: 2679 * RETURN VALUES:
2694 * 0 - success. 2680 * 0 - success.
2695 * -EIO - i/o error. 2681 * -EIO - i/o error.
2696 */ 2682 */
2697static int diIAGRead(struct inomap * imap, int iagno, struct metapage ** mpp) 2683static int diIAGRead(struct inomap * imap, int iagno, struct metapage ** mpp)
2698{ 2684{
@@ -2712,17 +2698,17 @@ static int diIAGRead(struct inomap * imap, int iagno, struct metapage ** mpp)
2712} 2698}
2713 2699
2714/* 2700/*
2715 * NAME: diFindFree() 2701 * NAME: diFindFree()
2716 * 2702 *
2717 * FUNCTION: find the first free bit in a word starting at 2703 * FUNCTION: find the first free bit in a word starting at
2718 * the specified bit position. 2704 * the specified bit position.
2719 * 2705 *
2720 * PARAMETERS: 2706 * PARAMETERS:
2721 * word - word to be examined. 2707 * word - word to be examined.
2722 * start - starting bit position. 2708 * start - starting bit position.
2723 * 2709 *
2724 * RETURN VALUES: 2710 * RETURN VALUES:
2725 * bit position of first free bit in the word or 32 if 2711 * bit position of first free bit in the word or 32 if
2726 * no free bits were found. 2712 * no free bits were found.
2727 */ 2713 */
2728static int diFindFree(u32 word, int start) 2714static int diFindFree(u32 word, int start)
@@ -2897,7 +2883,7 @@ int diExtendFS(struct inode *ipimap, struct inode *ipbmap)
2897 atomic_read(&imap->im_numfree)); 2883 atomic_read(&imap->im_numfree));
2898 2884
2899 /* 2885 /*
2900 * reconstruct imap 2886 * reconstruct imap
2901 * 2887 *
2902 * coalesce contiguous k (newAGSize/oldAGSize) AGs; 2888 * coalesce contiguous k (newAGSize/oldAGSize) AGs;
2903 * i.e., (AGi, ..., AGj) where i = k*n and j = k*(n+1) - 1 to AGn; 2889 * i.e., (AGi, ..., AGj) where i = k*n and j = k*(n+1) - 1 to AGn;
@@ -2913,7 +2899,7 @@ int diExtendFS(struct inode *ipimap, struct inode *ipbmap)
2913 } 2899 }
2914 2900
2915 /* 2901 /*
2916 * process each iag page of the map. 2902 * process each iag page of the map.
2917 * 2903 *
2918 * rebuild AG Free Inode List, AG Free Inode Extent List; 2904 * rebuild AG Free Inode List, AG Free Inode Extent List;
2919 */ 2905 */
@@ -2932,7 +2918,7 @@ int diExtendFS(struct inode *ipimap, struct inode *ipbmap)
2932 2918
2933 /* leave free iag in the free iag list */ 2919 /* leave free iag in the free iag list */
2934 if (iagp->nfreeexts == cpu_to_le32(EXTSPERIAG)) { 2920 if (iagp->nfreeexts == cpu_to_le32(EXTSPERIAG)) {
2935 release_metapage(bp); 2921 release_metapage(bp);
2936 continue; 2922 continue;
2937 } 2923 }
2938 2924
@@ -3063,13 +3049,13 @@ static void duplicateIXtree(struct super_block *sb, s64 blkno,
3063} 3049}
3064 3050
3065/* 3051/*
3066 * NAME: copy_from_dinode() 3052 * NAME: copy_from_dinode()
3067 * 3053 *
3068 * FUNCTION: Copies inode info from disk inode to in-memory inode 3054 * FUNCTION: Copies inode info from disk inode to in-memory inode
3069 * 3055 *
3070 * RETURN VALUES: 3056 * RETURN VALUES:
3071 * 0 - success 3057 * 0 - success
3072 * -ENOMEM - insufficient memory 3058 * -ENOMEM - insufficient memory
3073 */ 3059 */
3074static int copy_from_dinode(struct dinode * dip, struct inode *ip) 3060static int copy_from_dinode(struct dinode * dip, struct inode *ip)
3075{ 3061{
@@ -3151,9 +3137,9 @@ static int copy_from_dinode(struct dinode * dip, struct inode *ip)
3151} 3137}
3152 3138
3153/* 3139/*
3154 * NAME: copy_to_dinode() 3140 * NAME: copy_to_dinode()
3155 * 3141 *
3156 * FUNCTION: Copies inode info from in-memory inode to disk inode 3142 * FUNCTION: Copies inode info from in-memory inode to disk inode
3157 */ 3143 */
3158static void copy_to_dinode(struct dinode * dip, struct inode *ip) 3144static void copy_to_dinode(struct dinode * dip, struct inode *ip)
3159{ 3145{
diff --git a/fs/jfs/jfs_imap.h b/fs/jfs/jfs_imap.h
index 4f9c346ed498..610a0e9d8941 100644
--- a/fs/jfs/jfs_imap.h
+++ b/fs/jfs/jfs_imap.h
@@ -24,17 +24,17 @@
24 * jfs_imap.h: disk inode manager 24 * jfs_imap.h: disk inode manager
25 */ 25 */
26 26
27#define EXTSPERIAG 128 /* number of disk inode extent per iag */ 27#define EXTSPERIAG 128 /* number of disk inode extent per iag */
28#define IMAPBLKNO 0 /* lblkno of dinomap within inode map */ 28#define IMAPBLKNO 0 /* lblkno of dinomap within inode map */
29#define SMAPSZ 4 /* number of words per summary map */ 29#define SMAPSZ 4 /* number of words per summary map */
30#define EXTSPERSUM 32 /* number of extents per summary map entry */ 30#define EXTSPERSUM 32 /* number of extents per summary map entry */
31#define L2EXTSPERSUM 5 /* l2 number of extents per summary map */ 31#define L2EXTSPERSUM 5 /* l2 number of extents per summary map */
32#define PGSPERIEXT 4 /* number of 4K pages per dinode extent */ 32#define PGSPERIEXT 4 /* number of 4K pages per dinode extent */
33#define MAXIAGS ((1<<20)-1) /* maximum number of iags */ 33#define MAXIAGS ((1<<20)-1) /* maximum number of iags */
34#define MAXAG 128 /* maximum number of allocation groups */ 34#define MAXAG 128 /* maximum number of allocation groups */
35 35
36#define AMAPSIZE 512 /* bytes in the IAG allocation maps */ 36#define AMAPSIZE 512 /* bytes in the IAG allocation maps */
37#define SMAPSIZE 16 /* bytes in the IAG summary maps */ 37#define SMAPSIZE 16 /* bytes in the IAG summary maps */
38 38
39/* convert inode number to iag number */ 39/* convert inode number to iag number */
40#define INOTOIAG(ino) ((ino) >> L2INOSPERIAG) 40#define INOTOIAG(ino) ((ino) >> L2INOSPERIAG)
@@ -60,31 +60,31 @@
60 * inode allocation group page (per 4096 inodes of an AG) 60 * inode allocation group page (per 4096 inodes of an AG)
61 */ 61 */
62struct iag { 62struct iag {
63 __le64 agstart; /* 8: starting block of ag */ 63 __le64 agstart; /* 8: starting block of ag */
64 __le32 iagnum; /* 4: inode allocation group number */ 64 __le32 iagnum; /* 4: inode allocation group number */
65 __le32 inofreefwd; /* 4: ag inode free list forward */ 65 __le32 inofreefwd; /* 4: ag inode free list forward */
66 __le32 inofreeback; /* 4: ag inode free list back */ 66 __le32 inofreeback; /* 4: ag inode free list back */
67 __le32 extfreefwd; /* 4: ag inode extent free list forward */ 67 __le32 extfreefwd; /* 4: ag inode extent free list forward */
68 __le32 extfreeback; /* 4: ag inode extent free list back */ 68 __le32 extfreeback; /* 4: ag inode extent free list back */
69 __le32 iagfree; /* 4: iag free list */ 69 __le32 iagfree; /* 4: iag free list */
70 70
71 /* summary map: 1 bit per inode extent */ 71 /* summary map: 1 bit per inode extent */
72 __le32 inosmap[SMAPSZ]; /* 16: sum map of mapwords w/ free inodes; 72 __le32 inosmap[SMAPSZ]; /* 16: sum map of mapwords w/ free inodes;
73 * note: this indicates free and backed 73 * note: this indicates free and backed
74 * inodes, if the extent is not backed the 74 * inodes, if the extent is not backed the
75 * value will be 1. if the extent is 75 * value will be 1. if the extent is
76 * backed but all inodes are being used the 76 * backed but all inodes are being used the
77 * value will be 1. if the extent is 77 * value will be 1. if the extent is
78 * backed but at least one of the inodes is 78 * backed but at least one of the inodes is
79 * free the value will be 0. 79 * free the value will be 0.
80 */ 80 */
81 __le32 extsmap[SMAPSZ]; /* 16: sum map of mapwords w/ free extents */ 81 __le32 extsmap[SMAPSZ]; /* 16: sum map of mapwords w/ free extents */
82 __le32 nfreeinos; /* 4: number of free inodes */ 82 __le32 nfreeinos; /* 4: number of free inodes */
83 __le32 nfreeexts; /* 4: number of free extents */ 83 __le32 nfreeexts; /* 4: number of free extents */
84 /* (72) */ 84 /* (72) */
85 u8 pad[1976]; /* 1976: pad to 2048 bytes */ 85 u8 pad[1976]; /* 1976: pad to 2048 bytes */
86 /* allocation bit map: 1 bit per inode (0 - free, 1 - allocated) */ 86 /* allocation bit map: 1 bit per inode (0 - free, 1 - allocated) */
87 __le32 wmap[EXTSPERIAG]; /* 512: working allocation map */ 87 __le32 wmap[EXTSPERIAG]; /* 512: working allocation map */
88 __le32 pmap[EXTSPERIAG]; /* 512: persistent allocation map */ 88 __le32 pmap[EXTSPERIAG]; /* 512: persistent allocation map */
89 pxd_t inoext[EXTSPERIAG]; /* 1024: inode extent addresses */ 89 pxd_t inoext[EXTSPERIAG]; /* 1024: inode extent addresses */
90}; /* (4096) */ 90}; /* (4096) */
@@ -93,44 +93,44 @@ struct iag {
93 * per AG control information (in inode map control page) 93 * per AG control information (in inode map control page)
94 */ 94 */
95struct iagctl_disk { 95struct iagctl_disk {
96 __le32 inofree; /* 4: free inode list anchor */ 96 __le32 inofree; /* 4: free inode list anchor */
97 __le32 extfree; /* 4: free extent list anchor */ 97 __le32 extfree; /* 4: free extent list anchor */
98 __le32 numinos; /* 4: number of backed inodes */ 98 __le32 numinos; /* 4: number of backed inodes */
99 __le32 numfree; /* 4: number of free inodes */ 99 __le32 numfree; /* 4: number of free inodes */
100}; /* (16) */ 100}; /* (16) */
101 101
102struct iagctl { 102struct iagctl {
103 int inofree; /* free inode list anchor */ 103 int inofree; /* free inode list anchor */
104 int extfree; /* free extent list anchor */ 104 int extfree; /* free extent list anchor */
105 int numinos; /* number of backed inodes */ 105 int numinos; /* number of backed inodes */
106 int numfree; /* number of free inodes */ 106 int numfree; /* number of free inodes */
107}; 107};
108 108
109/* 109/*
110 * per fileset/aggregate inode map control page 110 * per fileset/aggregate inode map control page
111 */ 111 */
112struct dinomap_disk { 112struct dinomap_disk {
113 __le32 in_freeiag; /* 4: free iag list anchor */ 113 __le32 in_freeiag; /* 4: free iag list anchor */
114 __le32 in_nextiag; /* 4: next free iag number */ 114 __le32 in_nextiag; /* 4: next free iag number */
115 __le32 in_numinos; /* 4: num of backed inodes */ 115 __le32 in_numinos; /* 4: num of backed inodes */
116 __le32 in_numfree; /* 4: num of free backed inodes */ 116 __le32 in_numfree; /* 4: num of free backed inodes */
117 __le32 in_nbperiext; /* 4: num of blocks per inode extent */ 117 __le32 in_nbperiext; /* 4: num of blocks per inode extent */
118 __le32 in_l2nbperiext; /* 4: l2 of in_nbperiext */ 118 __le32 in_l2nbperiext; /* 4: l2 of in_nbperiext */
119 __le32 in_diskblock; /* 4: for standalone test driver */ 119 __le32 in_diskblock; /* 4: for standalone test driver */
120 __le32 in_maxag; /* 4: for standalone test driver */ 120 __le32 in_maxag; /* 4: for standalone test driver */
121 u8 pad[2016]; /* 2016: pad to 2048 */ 121 u8 pad[2016]; /* 2016: pad to 2048 */
122 struct iagctl_disk in_agctl[MAXAG]; /* 2048: AG control information */ 122 struct iagctl_disk in_agctl[MAXAG]; /* 2048: AG control information */
123}; /* (4096) */ 123}; /* (4096) */
124 124
125struct dinomap { 125struct dinomap {
126 int in_freeiag; /* free iag list anchor */ 126 int in_freeiag; /* free iag list anchor */
127 int in_nextiag; /* next free iag number */ 127 int in_nextiag; /* next free iag number */
128 int in_numinos; /* num of backed inodes */ 128 int in_numinos; /* num of backed inodes */
129 int in_numfree; /* num of free backed inodes */ 129 int in_numfree; /* num of free backed inodes */
130 int in_nbperiext; /* num of blocks per inode extent */ 130 int in_nbperiext; /* num of blocks per inode extent */
131 int in_l2nbperiext; /* l2 of in_nbperiext */ 131 int in_l2nbperiext; /* l2 of in_nbperiext */
132 int in_diskblock; /* for standalone test driver */ 132 int in_diskblock; /* for standalone test driver */
133 int in_maxag; /* for standalone test driver */ 133 int in_maxag; /* for standalone test driver */
134 struct iagctl in_agctl[MAXAG]; /* AG control information */ 134 struct iagctl in_agctl[MAXAG]; /* AG control information */
135}; 135};
136 136
@@ -139,9 +139,9 @@ struct dinomap {
139 */ 139 */
140struct inomap { 140struct inomap {
141 struct dinomap im_imap; /* 4096: inode allocation control */ 141 struct dinomap im_imap; /* 4096: inode allocation control */
142 struct inode *im_ipimap; /* 4: ptr to inode for imap */ 142 struct inode *im_ipimap; /* 4: ptr to inode for imap */
143 struct mutex im_freelock; /* 4: iag free list lock */ 143 struct mutex im_freelock; /* 4: iag free list lock */
144 struct mutex im_aglock[MAXAG]; /* 512: per AG locks */ 144 struct mutex im_aglock[MAXAG]; /* 512: per AG locks */
145 u32 *im_DBGdimap; 145 u32 *im_DBGdimap;
146 atomic_t im_numinos; /* num of backed inodes */ 146 atomic_t im_numinos; /* num of backed inodes */
147 atomic_t im_numfree; /* num of free backed inodes */ 147 atomic_t im_numfree; /* num of free backed inodes */
diff --git a/fs/jfs/jfs_incore.h b/fs/jfs/jfs_incore.h
index 8f453eff3c83..cb8f30985ad1 100644
--- a/fs/jfs/jfs_incore.h
+++ b/fs/jfs/jfs_incore.h
@@ -40,7 +40,7 @@ struct jfs_inode_info {
40 uint mode2; /* jfs-specific mode */ 40 uint mode2; /* jfs-specific mode */
41 uint saved_uid; /* saved for uid mount option */ 41 uint saved_uid; /* saved for uid mount option */
42 uint saved_gid; /* saved for gid mount option */ 42 uint saved_gid; /* saved for gid mount option */
43 pxd_t ixpxd; /* inode extent descriptor */ 43 pxd_t ixpxd; /* inode extent descriptor */
44 dxd_t acl; /* dxd describing acl */ 44 dxd_t acl; /* dxd describing acl */
45 dxd_t ea; /* dxd describing ea */ 45 dxd_t ea; /* dxd describing ea */
46 time_t otime; /* time created */ 46 time_t otime; /* time created */
@@ -190,7 +190,7 @@ struct jfs_sb_info {
190 uint gengen; /* inode generation generator*/ 190 uint gengen; /* inode generation generator*/
191 uint inostamp; /* shows inode belongs to fileset*/ 191 uint inostamp; /* shows inode belongs to fileset*/
192 192
193 /* Formerly in ipbmap */ 193 /* Formerly in ipbmap */
194 struct bmap *bmap; /* incore bmap descriptor */ 194 struct bmap *bmap; /* incore bmap descriptor */
195 struct nls_table *nls_tab; /* current codepage */ 195 struct nls_table *nls_tab; /* current codepage */
196 struct inode *direct_inode; /* metadata inode */ 196 struct inode *direct_inode; /* metadata inode */
diff --git a/fs/jfs/jfs_logmgr.c b/fs/jfs/jfs_logmgr.c
index 44a2f33cb98d..de3e4a506dbc 100644
--- a/fs/jfs/jfs_logmgr.c
+++ b/fs/jfs/jfs_logmgr.c
@@ -244,7 +244,7 @@ int lmLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
244 goto writeRecord; 244 goto writeRecord;
245 245
246 /* 246 /*
247 * initialize/update page/transaction recovery lsn 247 * initialize/update page/transaction recovery lsn
248 */ 248 */
249 lsn = log->lsn; 249 lsn = log->lsn;
250 250
@@ -263,7 +263,7 @@ int lmLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
263 } 263 }
264 264
265 /* 265 /*
266 * initialize/update lsn of tblock of the page 266 * initialize/update lsn of tblock of the page
267 * 267 *
268 * transaction inherits oldest lsn of pages associated 268 * transaction inherits oldest lsn of pages associated
269 * with allocation/deallocation of resources (their 269 * with allocation/deallocation of resources (their
@@ -307,7 +307,7 @@ int lmLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
307 LOGSYNC_UNLOCK(log, flags); 307 LOGSYNC_UNLOCK(log, flags);
308 308
309 /* 309 /*
310 * write the log record 310 * write the log record
311 */ 311 */
312 writeRecord: 312 writeRecord:
313 lsn = lmWriteRecord(log, tblk, lrd, tlck); 313 lsn = lmWriteRecord(log, tblk, lrd, tlck);
@@ -372,7 +372,7 @@ lmWriteRecord(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
372 goto moveLrd; 372 goto moveLrd;
373 373
374 /* 374 /*
375 * move log record data 375 * move log record data
376 */ 376 */
377 /* retrieve source meta-data page to log */ 377 /* retrieve source meta-data page to log */
378 if (tlck->flag & tlckPAGELOCK) { 378 if (tlck->flag & tlckPAGELOCK) {
@@ -465,7 +465,7 @@ lmWriteRecord(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
465 } 465 }
466 466
467 /* 467 /*
468 * move log record descriptor 468 * move log record descriptor
469 */ 469 */
470 moveLrd: 470 moveLrd:
471 lrd->length = cpu_to_le16(len); 471 lrd->length = cpu_to_le16(len);
@@ -574,7 +574,7 @@ static int lmNextPage(struct jfs_log * log)
574 LOGGC_LOCK(log); 574 LOGGC_LOCK(log);
575 575
576 /* 576 /*
577 * write or queue the full page at the tail of write queue 577 * write or queue the full page at the tail of write queue
578 */ 578 */
579 /* get the tail tblk on commit queue */ 579 /* get the tail tblk on commit queue */
580 if (list_empty(&log->cqueue)) 580 if (list_empty(&log->cqueue))
@@ -625,7 +625,7 @@ static int lmNextPage(struct jfs_log * log)
625 LOGGC_UNLOCK(log); 625 LOGGC_UNLOCK(log);
626 626
627 /* 627 /*
628 * allocate/initialize next page 628 * allocate/initialize next page
629 */ 629 */
630 /* if log wraps, the first data page of log is 2 630 /* if log wraps, the first data page of log is 2
631 * (0 never used, 1 is superblock). 631 * (0 never used, 1 is superblock).
@@ -953,7 +953,7 @@ static int lmLogSync(struct jfs_log * log, int hard_sync)
953 } 953 }
954 954
955 /* 955 /*
956 * forward syncpt 956 * forward syncpt
957 */ 957 */
958 /* if last sync is same as last syncpt, 958 /* if last sync is same as last syncpt,
959 * invoke sync point forward processing to update sync. 959 * invoke sync point forward processing to update sync.
@@ -989,7 +989,7 @@ static int lmLogSync(struct jfs_log * log, int hard_sync)
989 lsn = log->lsn; 989 lsn = log->lsn;
990 990
991 /* 991 /*
992 * setup next syncpt trigger (SWAG) 992 * setup next syncpt trigger (SWAG)
993 */ 993 */
994 logsize = log->logsize; 994 logsize = log->logsize;
995 995
@@ -1000,11 +1000,11 @@ static int lmLogSync(struct jfs_log * log, int hard_sync)
1000 if (more < 2 * LOGPSIZE) { 1000 if (more < 2 * LOGPSIZE) {
1001 jfs_warn("\n ... Log Wrap ... Log Wrap ... Log Wrap ...\n"); 1001 jfs_warn("\n ... Log Wrap ... Log Wrap ... Log Wrap ...\n");
1002 /* 1002 /*
1003 * log wrapping 1003 * log wrapping
1004 * 1004 *
1005 * option 1 - panic ? No.! 1005 * option 1 - panic ? No.!
1006 * option 2 - shutdown file systems 1006 * option 2 - shutdown file systems
1007 * associated with log ? 1007 * associated with log ?
1008 * option 3 - extend log ? 1008 * option 3 - extend log ?
1009 */ 1009 */
1010 /* 1010 /*
@@ -1062,7 +1062,7 @@ void jfs_syncpt(struct jfs_log *log, int hard_sync)
1062/* 1062/*
1063 * NAME: lmLogOpen() 1063 * NAME: lmLogOpen()
1064 * 1064 *
1065 * FUNCTION: open the log on first open; 1065 * FUNCTION: open the log on first open;
1066 * insert filesystem in the active list of the log. 1066 * insert filesystem in the active list of the log.
1067 * 1067 *
1068 * PARAMETER: ipmnt - file system mount inode 1068 * PARAMETER: ipmnt - file system mount inode
@@ -1113,7 +1113,7 @@ int lmLogOpen(struct super_block *sb)
1113 init_waitqueue_head(&log->syncwait); 1113 init_waitqueue_head(&log->syncwait);
1114 1114
1115 /* 1115 /*
1116 * external log as separate logical volume 1116 * external log as separate logical volume
1117 * 1117 *
1118 * file systems to log may have n-to-1 relationship; 1118 * file systems to log may have n-to-1 relationship;
1119 */ 1119 */
@@ -1155,7 +1155,7 @@ journal_found:
1155 return 0; 1155 return 0;
1156 1156
1157 /* 1157 /*
1158 * unwind on error 1158 * unwind on error
1159 */ 1159 */
1160 shutdown: /* unwind lbmLogInit() */ 1160 shutdown: /* unwind lbmLogInit() */
1161 list_del(&log->journal_list); 1161 list_del(&log->journal_list);
@@ -1427,7 +1427,7 @@ int lmLogInit(struct jfs_log * log)
1427 return 0; 1427 return 0;
1428 1428
1429 /* 1429 /*
1430 * unwind on error 1430 * unwind on error
1431 */ 1431 */
1432 errout30: /* release log page */ 1432 errout30: /* release log page */
1433 log->wqueue = NULL; 1433 log->wqueue = NULL;
@@ -1480,7 +1480,7 @@ int lmLogClose(struct super_block *sb)
1480 1480
1481 if (test_bit(log_INLINELOG, &log->flag)) { 1481 if (test_bit(log_INLINELOG, &log->flag)) {
1482 /* 1482 /*
1483 * in-line log in host file system 1483 * in-line log in host file system
1484 */ 1484 */
1485 rc = lmLogShutdown(log); 1485 rc = lmLogShutdown(log);
1486 kfree(log); 1486 kfree(log);
@@ -1504,7 +1504,7 @@ int lmLogClose(struct super_block *sb)
1504 goto out; 1504 goto out;
1505 1505
1506 /* 1506 /*
1507 * external log as separate logical volume 1507 * external log as separate logical volume
1508 */ 1508 */
1509 list_del(&log->journal_list); 1509 list_del(&log->journal_list);
1510 bdev = log->bdev; 1510 bdev = log->bdev;
@@ -1622,20 +1622,26 @@ void jfs_flush_journal(struct jfs_log *log, int wait)
1622 if (!list_empty(&log->synclist)) { 1622 if (!list_empty(&log->synclist)) {
1623 struct logsyncblk *lp; 1623 struct logsyncblk *lp;
1624 1624
1625 printk(KERN_ERR "jfs_flush_journal: synclist not empty\n");
1625 list_for_each_entry(lp, &log->synclist, synclist) { 1626 list_for_each_entry(lp, &log->synclist, synclist) {
1626 if (lp->xflag & COMMIT_PAGE) { 1627 if (lp->xflag & COMMIT_PAGE) {
1627 struct metapage *mp = (struct metapage *)lp; 1628 struct metapage *mp = (struct metapage *)lp;
1628 dump_mem("orphan metapage", lp, 1629 print_hex_dump(KERN_ERR, "metapage: ",
1629 sizeof(struct metapage)); 1630 DUMP_PREFIX_ADDRESS, 16, 4,
1630 dump_mem("page", mp->page, sizeof(struct page)); 1631 mp, sizeof(struct metapage), 0);
1631 } 1632 print_hex_dump(KERN_ERR, "page: ",
1632 else 1633 DUMP_PREFIX_ADDRESS, 16,
1633 dump_mem("orphan tblock", lp, 1634 sizeof(long), mp->page,
1634 sizeof(struct tblock)); 1635 sizeof(struct page), 0);
1636 } else
1637 print_hex_dump(KERN_ERR, "tblock:",
1638 DUMP_PREFIX_ADDRESS, 16, 4,
1639 lp, sizeof(struct tblock), 0);
1635 } 1640 }
1636 } 1641 }
1642#else
1643 WARN_ON(!list_empty(&log->synclist));
1637#endif 1644#endif
1638 //assert(list_empty(&log->synclist));
1639 clear_bit(log_FLUSH, &log->flag); 1645 clear_bit(log_FLUSH, &log->flag);
1640} 1646}
1641 1647
@@ -1723,7 +1729,7 @@ int lmLogShutdown(struct jfs_log * log)
1723 * 1729 *
1724 * PARAMETE: log - pointer to logs inode. 1730 * PARAMETE: log - pointer to logs inode.
1725 * fsdev - kdev_t of filesystem. 1731 * fsdev - kdev_t of filesystem.
1726 * serial - pointer to returned log serial number 1732 * serial - pointer to returned log serial number
1727 * activate - insert/remove device from active list. 1733 * activate - insert/remove device from active list.
1728 * 1734 *
1729 * RETURN: 0 - success 1735 * RETURN: 0 - success
@@ -1963,7 +1969,7 @@ static void lbmfree(struct lbuf * bp)
1963 * FUNCTION: add a log buffer to the log redrive list 1969 * FUNCTION: add a log buffer to the log redrive list
1964 * 1970 *
1965 * PARAMETER: 1971 * PARAMETER:
1966 * bp - log buffer 1972 * bp - log buffer
1967 * 1973 *
1968 * NOTES: 1974 * NOTES:
1969 * Takes log_redrive_lock. 1975 * Takes log_redrive_lock.
@@ -2054,7 +2060,7 @@ static void lbmWrite(struct jfs_log * log, struct lbuf * bp, int flag,
2054 bp->l_flag = flag; 2060 bp->l_flag = flag;
2055 2061
2056 /* 2062 /*
2057 * insert bp at tail of write queue associated with log 2063 * insert bp at tail of write queue associated with log
2058 * 2064 *
2059 * (request is either for bp already/currently at head of queue 2065 * (request is either for bp already/currently at head of queue
2060 * or new bp to be inserted at tail) 2066 * or new bp to be inserted at tail)
@@ -2117,7 +2123,7 @@ static void lbmDirectWrite(struct jfs_log * log, struct lbuf * bp, int flag)
2117 log->base + (bp->l_pn << (L2LOGPSIZE - log->l2bsize)); 2123 log->base + (bp->l_pn << (L2LOGPSIZE - log->l2bsize));
2118 2124
2119 /* 2125 /*
2120 * initiate pageout of the page 2126 * initiate pageout of the page
2121 */ 2127 */
2122 lbmStartIO(bp); 2128 lbmStartIO(bp);
2123} 2129}
@@ -2128,7 +2134,7 @@ static void lbmDirectWrite(struct jfs_log * log, struct lbuf * bp, int flag)
2128 * 2134 *
2129 * FUNCTION: Interface to DD strategy routine 2135 * FUNCTION: Interface to DD strategy routine
2130 * 2136 *
2131 * RETURN: none 2137 * RETURN: none
2132 * 2138 *
2133 * serialization: LCACHE_LOCK() is NOT held during log i/o; 2139 * serialization: LCACHE_LOCK() is NOT held during log i/o;
2134 */ 2140 */
@@ -2222,7 +2228,7 @@ static int lbmIODone(struct bio *bio, unsigned int bytes_done, int error)
2222 bio_put(bio); 2228 bio_put(bio);
2223 2229
2224 /* 2230 /*
2225 * pagein completion 2231 * pagein completion
2226 */ 2232 */
2227 if (bp->l_flag & lbmREAD) { 2233 if (bp->l_flag & lbmREAD) {
2228 bp->l_flag &= ~lbmREAD; 2234 bp->l_flag &= ~lbmREAD;
@@ -2236,7 +2242,7 @@ static int lbmIODone(struct bio *bio, unsigned int bytes_done, int error)
2236 } 2242 }
2237 2243
2238 /* 2244 /*
2239 * pageout completion 2245 * pageout completion
2240 * 2246 *
2241 * the bp at the head of write queue has completed pageout. 2247 * the bp at the head of write queue has completed pageout.
2242 * 2248 *
@@ -2302,7 +2308,7 @@ static int lbmIODone(struct bio *bio, unsigned int bytes_done, int error)
2302 } 2308 }
2303 2309
2304 /* 2310 /*
2305 * synchronous pageout: 2311 * synchronous pageout:
2306 * 2312 *
2307 * buffer has not necessarily been removed from write queue 2313 * buffer has not necessarily been removed from write queue
2308 * (e.g., synchronous write of partial-page with COMMIT): 2314 * (e.g., synchronous write of partial-page with COMMIT):
@@ -2316,7 +2322,7 @@ static int lbmIODone(struct bio *bio, unsigned int bytes_done, int error)
2316 } 2322 }
2317 2323
2318 /* 2324 /*
2319 * Group Commit pageout: 2325 * Group Commit pageout:
2320 */ 2326 */
2321 else if (bp->l_flag & lbmGC) { 2327 else if (bp->l_flag & lbmGC) {
2322 LCACHE_UNLOCK(flags); 2328 LCACHE_UNLOCK(flags);
@@ -2324,7 +2330,7 @@ static int lbmIODone(struct bio *bio, unsigned int bytes_done, int error)
2324 } 2330 }
2325 2331
2326 /* 2332 /*
2327 * asynchronous pageout: 2333 * asynchronous pageout:
2328 * 2334 *
2329 * buffer must have been removed from write queue: 2335 * buffer must have been removed from write queue:
2330 * insert buffer at head of freelist where it can be recycled 2336 * insert buffer at head of freelist where it can be recycled
@@ -2375,7 +2381,7 @@ int jfsIOWait(void *arg)
2375 * FUNCTION: format file system log 2381 * FUNCTION: format file system log
2376 * 2382 *
2377 * PARAMETERS: 2383 * PARAMETERS:
2378 * log - volume log 2384 * log - volume log
2379 * logAddress - start address of log space in FS block 2385 * logAddress - start address of log space in FS block
2380 * logSize - length of log space in FS block; 2386 * logSize - length of log space in FS block;
2381 * 2387 *
@@ -2407,16 +2413,16 @@ int lmLogFormat(struct jfs_log *log, s64 logAddress, int logSize)
2407 npages = logSize >> sbi->l2nbperpage; 2413 npages = logSize >> sbi->l2nbperpage;
2408 2414
2409 /* 2415 /*
2410 * log space: 2416 * log space:
2411 * 2417 *
2412 * page 0 - reserved; 2418 * page 0 - reserved;
2413 * page 1 - log superblock; 2419 * page 1 - log superblock;
2414 * page 2 - log data page: A SYNC log record is written 2420 * page 2 - log data page: A SYNC log record is written
2415 * into this page at logform time; 2421 * into this page at logform time;
2416 * pages 3-N - log data page: set to empty log data pages; 2422 * pages 3-N - log data page: set to empty log data pages;
2417 */ 2423 */
2418 /* 2424 /*
2419 * init log superblock: log page 1 2425 * init log superblock: log page 1
2420 */ 2426 */
2421 logsuper = (struct logsuper *) bp->l_ldata; 2427 logsuper = (struct logsuper *) bp->l_ldata;
2422 2428
@@ -2436,7 +2442,7 @@ int lmLogFormat(struct jfs_log *log, s64 logAddress, int logSize)
2436 goto exit; 2442 goto exit;
2437 2443
2438 /* 2444 /*
2439 * init pages 2 to npages-1 as log data pages: 2445 * init pages 2 to npages-1 as log data pages:
2440 * 2446 *
2441 * log page sequence number (lpsn) initialization: 2447 * log page sequence number (lpsn) initialization:
2442 * 2448 *
@@ -2479,7 +2485,7 @@ int lmLogFormat(struct jfs_log *log, s64 logAddress, int logSize)
2479 goto exit; 2485 goto exit;
2480 2486
2481 /* 2487 /*
2482 * initialize succeeding log pages: lpsn = 0, 1, ..., (N-2) 2488 * initialize succeeding log pages: lpsn = 0, 1, ..., (N-2)
2483 */ 2489 */
2484 for (lspn = 0; lspn < npages - 3; lspn++) { 2490 for (lspn = 0; lspn < npages - 3; lspn++) {
2485 lp->h.page = lp->t.page = cpu_to_le32(lspn); 2491 lp->h.page = lp->t.page = cpu_to_le32(lspn);
@@ -2495,7 +2501,7 @@ int lmLogFormat(struct jfs_log *log, s64 logAddress, int logSize)
2495 rc = 0; 2501 rc = 0;
2496exit: 2502exit:
2497 /* 2503 /*
2498 * finalize log 2504 * finalize log
2499 */ 2505 */
2500 /* release the buffer */ 2506 /* release the buffer */
2501 lbmFree(bp); 2507 lbmFree(bp);
diff --git a/fs/jfs/jfs_logmgr.h b/fs/jfs/jfs_logmgr.h
index a53fb17ea219..1f85ef0ec045 100644
--- a/fs/jfs/jfs_logmgr.h
+++ b/fs/jfs/jfs_logmgr.h
@@ -144,7 +144,7 @@ struct logpage {
144 * 144 *
145 * (this comment should be rewritten !) 145 * (this comment should be rewritten !)
146 * jfs uses only "after" log records (only a single writer is allowed 146 * jfs uses only "after" log records (only a single writer is allowed
147 * in a page, pages are written to temporary paging space if 147 * in a page, pages are written to temporary paging space if
148 * if they must be written to disk before commit, and i/o is 148 * if they must be written to disk before commit, and i/o is
149 * scheduled for modified pages to their home location after 149 * scheduled for modified pages to their home location after
150 * the log records containing the after values and the commit 150 * the log records containing the after values and the commit
@@ -153,7 +153,7 @@ struct logpage {
153 * 153 *
154 * a log record consists of a data area of variable length followed by 154 * a log record consists of a data area of variable length followed by
155 * a descriptor of fixed size LOGRDSIZE bytes. 155 * a descriptor of fixed size LOGRDSIZE bytes.
156 * the data area is rounded up to an integral number of 4-bytes and 156 * the data area is rounded up to an integral number of 4-bytes and
157 * must be no longer than LOGPSIZE. 157 * must be no longer than LOGPSIZE.
158 * the descriptor is of size of multiple of 4-bytes and aligned on a 158 * the descriptor is of size of multiple of 4-bytes and aligned on a
159 * 4-byte boundary. 159 * 4-byte boundary.
@@ -215,13 +215,13 @@ struct lrd {
215 union { 215 union {
216 216
217 /* 217 /*
218 * COMMIT: commit 218 * COMMIT: commit
219 * 219 *
220 * transaction commit: no type-dependent information; 220 * transaction commit: no type-dependent information;
221 */ 221 */
222 222
223 /* 223 /*
224 * REDOPAGE: after-image 224 * REDOPAGE: after-image
225 * 225 *
226 * apply after-image; 226 * apply after-image;
227 * 227 *
@@ -236,7 +236,7 @@ struct lrd {
236 } redopage; /* (20) */ 236 } redopage; /* (20) */
237 237
238 /* 238 /*
239 * NOREDOPAGE: the page is freed 239 * NOREDOPAGE: the page is freed
240 * 240 *
241 * do not apply after-image records which precede this record 241 * do not apply after-image records which precede this record
242 * in the log with the same page block number to this page. 242 * in the log with the same page block number to this page.
@@ -252,7 +252,7 @@ struct lrd {
252 } noredopage; /* (20) */ 252 } noredopage; /* (20) */
253 253
254 /* 254 /*
255 * UPDATEMAP: update block allocation map 255 * UPDATEMAP: update block allocation map
256 * 256 *
257 * either in-line PXD, 257 * either in-line PXD,
258 * or out-of-line XADLIST; 258 * or out-of-line XADLIST;
@@ -268,7 +268,7 @@ struct lrd {
268 } updatemap; /* (20) */ 268 } updatemap; /* (20) */
269 269
270 /* 270 /*
271 * NOREDOINOEXT: the inode extent is freed 271 * NOREDOINOEXT: the inode extent is freed
272 * 272 *
273 * do not apply after-image records which precede this 273 * do not apply after-image records which precede this
274 * record in the log with the any of the 4 page block 274 * record in the log with the any of the 4 page block
@@ -286,7 +286,7 @@ struct lrd {
286 } noredoinoext; /* (20) */ 286 } noredoinoext; /* (20) */
287 287
288 /* 288 /*
289 * SYNCPT: log sync point 289 * SYNCPT: log sync point
290 * 290 *
291 * replay log upto syncpt address specified; 291 * replay log upto syncpt address specified;
292 */ 292 */
@@ -295,13 +295,13 @@ struct lrd {
295 } syncpt; 295 } syncpt;
296 296
297 /* 297 /*
298 * MOUNT: file system mount 298 * MOUNT: file system mount
299 * 299 *
300 * file system mount: no type-dependent information; 300 * file system mount: no type-dependent information;
301 */ 301 */
302 302
303 /* 303 /*
304 * ? FREEXTENT: free specified extent(s) 304 * ? FREEXTENT: free specified extent(s)
305 * 305 *
306 * free specified extent(s) from block allocation map 306 * free specified extent(s) from block allocation map
307 * N.B.: nextents should be length of data/sizeof(xad_t) 307 * N.B.: nextents should be length of data/sizeof(xad_t)
@@ -314,7 +314,7 @@ struct lrd {
314 } freextent; 314 } freextent;
315 315
316 /* 316 /*
317 * ? NOREDOFILE: this file is freed 317 * ? NOREDOFILE: this file is freed
318 * 318 *
319 * do not apply records which precede this record in the log 319 * do not apply records which precede this record in the log
320 * with the same inode number. 320 * with the same inode number.
@@ -330,7 +330,7 @@ struct lrd {
330 } noredofile; 330 } noredofile;
331 331
332 /* 332 /*
333 * ? NEWPAGE: 333 * ? NEWPAGE:
334 * 334 *
335 * metadata type dependent 335 * metadata type dependent
336 */ 336 */
@@ -342,7 +342,7 @@ struct lrd {
342 } newpage; 342 } newpage;
343 343
344 /* 344 /*
345 * ? DUMMY: filler 345 * ? DUMMY: filler
346 * 346 *
347 * no type-dependent information 347 * no type-dependent information
348 */ 348 */
diff --git a/fs/jfs/jfs_metapage.c b/fs/jfs/jfs_metapage.c
index 43d4f69afbec..77c7f1129dde 100644
--- a/fs/jfs/jfs_metapage.c
+++ b/fs/jfs/jfs_metapage.c
@@ -472,7 +472,8 @@ add_failed:
472 printk(KERN_ERR "JFS: bio_add_page failed unexpectedly\n"); 472 printk(KERN_ERR "JFS: bio_add_page failed unexpectedly\n");
473 goto skip; 473 goto skip;
474dump_bio: 474dump_bio:
475 dump_mem("bio", bio, sizeof(*bio)); 475 print_hex_dump(KERN_ERR, "JFS: dump of bio: ", DUMP_PREFIX_ADDRESS, 16,
476 4, bio, sizeof(*bio), 0);
476skip: 477skip:
477 bio_put(bio); 478 bio_put(bio);
478 unlock_page(page); 479 unlock_page(page);
diff --git a/fs/jfs/jfs_mount.c b/fs/jfs/jfs_mount.c
index 4dd479834897..644429acb8c0 100644
--- a/fs/jfs/jfs_mount.c
+++ b/fs/jfs/jfs_mount.c
@@ -80,7 +80,7 @@ static int logMOUNT(struct super_block *sb);
80 */ 80 */
81int jfs_mount(struct super_block *sb) 81int jfs_mount(struct super_block *sb)
82{ 82{
83 int rc = 0; /* Return code */ 83 int rc = 0; /* Return code */
84 struct jfs_sb_info *sbi = JFS_SBI(sb); 84 struct jfs_sb_info *sbi = JFS_SBI(sb);
85 struct inode *ipaimap = NULL; 85 struct inode *ipaimap = NULL;
86 struct inode *ipaimap2 = NULL; 86 struct inode *ipaimap2 = NULL;
@@ -169,7 +169,7 @@ int jfs_mount(struct super_block *sb)
169 sbi->ipaimap2 = NULL; 169 sbi->ipaimap2 = NULL;
170 170
171 /* 171 /*
172 * mount (the only/single) fileset 172 * mount (the only/single) fileset
173 */ 173 */
174 /* 174 /*
175 * open fileset inode allocation map (aka fileset inode) 175 * open fileset inode allocation map (aka fileset inode)
@@ -195,7 +195,7 @@ int jfs_mount(struct super_block *sb)
195 goto out; 195 goto out;
196 196
197 /* 197 /*
198 * unwind on error 198 * unwind on error
199 */ 199 */
200 errout41: /* close fileset inode allocation map inode */ 200 errout41: /* close fileset inode allocation map inode */
201 diFreeSpecial(ipimap); 201 diFreeSpecial(ipimap);
diff --git a/fs/jfs/jfs_txnmgr.c b/fs/jfs/jfs_txnmgr.c
index 25430d0b0d59..7aa1f7004eaf 100644
--- a/fs/jfs/jfs_txnmgr.c
+++ b/fs/jfs/jfs_txnmgr.c
@@ -18,7 +18,7 @@
18 */ 18 */
19 19
20/* 20/*
21 * jfs_txnmgr.c: transaction manager 21 * jfs_txnmgr.c: transaction manager
22 * 22 *
23 * notes: 23 * notes:
24 * transaction starts with txBegin() and ends with txCommit() 24 * transaction starts with txBegin() and ends with txCommit()
@@ -60,7 +60,7 @@
60#include "jfs_debug.h" 60#include "jfs_debug.h"
61 61
62/* 62/*
63 * transaction management structures 63 * transaction management structures
64 */ 64 */
65static struct { 65static struct {
66 int freetid; /* index of a free tid structure */ 66 int freetid; /* index of a free tid structure */
@@ -103,19 +103,19 @@ module_param(nTxLock, int, 0);
103MODULE_PARM_DESC(nTxLock, 103MODULE_PARM_DESC(nTxLock,
104 "Number of transaction locks (max:65536)"); 104 "Number of transaction locks (max:65536)");
105 105
106struct tblock *TxBlock; /* transaction block table */ 106struct tblock *TxBlock; /* transaction block table */
107static int TxLockLWM; /* Low water mark for number of txLocks used */ 107static int TxLockLWM; /* Low water mark for number of txLocks used */
108static int TxLockHWM; /* High water mark for number of txLocks used */ 108static int TxLockHWM; /* High water mark for number of txLocks used */
109static int TxLockVHWM; /* Very High water mark */ 109static int TxLockVHWM; /* Very High water mark */
110struct tlock *TxLock; /* transaction lock table */ 110struct tlock *TxLock; /* transaction lock table */
111 111
112/* 112/*
113 * transaction management lock 113 * transaction management lock
114 */ 114 */
115static DEFINE_SPINLOCK(jfsTxnLock); 115static DEFINE_SPINLOCK(jfsTxnLock);
116 116
117#define TXN_LOCK() spin_lock(&jfsTxnLock) 117#define TXN_LOCK() spin_lock(&jfsTxnLock)
118#define TXN_UNLOCK() spin_unlock(&jfsTxnLock) 118#define TXN_UNLOCK() spin_unlock(&jfsTxnLock)
119 119
120#define LAZY_LOCK_INIT() spin_lock_init(&TxAnchor.LazyLock); 120#define LAZY_LOCK_INIT() spin_lock_init(&TxAnchor.LazyLock);
121#define LAZY_LOCK(flags) spin_lock_irqsave(&TxAnchor.LazyLock, flags) 121#define LAZY_LOCK(flags) spin_lock_irqsave(&TxAnchor.LazyLock, flags)
@@ -148,7 +148,7 @@ static inline void TXN_SLEEP_DROP_LOCK(wait_queue_head_t * event)
148#define TXN_WAKEUP(event) wake_up_all(event) 148#define TXN_WAKEUP(event) wake_up_all(event)
149 149
150/* 150/*
151 * statistics 151 * statistics
152 */ 152 */
153static struct { 153static struct {
154 tid_t maxtid; /* 4: biggest tid ever used */ 154 tid_t maxtid; /* 4: biggest tid ever used */
@@ -181,8 +181,8 @@ static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
181static void LogSyncRelease(struct metapage * mp); 181static void LogSyncRelease(struct metapage * mp);
182 182
183/* 183/*
184 * transaction block/lock management 184 * transaction block/lock management
185 * --------------------------------- 185 * ---------------------------------
186 */ 186 */
187 187
188/* 188/*
@@ -227,9 +227,9 @@ static void txLockFree(lid_t lid)
227} 227}
228 228
229/* 229/*
230 * NAME: txInit() 230 * NAME: txInit()
231 * 231 *
232 * FUNCTION: initialize transaction management structures 232 * FUNCTION: initialize transaction management structures
233 * 233 *
234 * RETURN: 234 * RETURN:
235 * 235 *
@@ -333,9 +333,9 @@ int txInit(void)
333} 333}
334 334
335/* 335/*
336 * NAME: txExit() 336 * NAME: txExit()
337 * 337 *
338 * FUNCTION: clean up when module is unloaded 338 * FUNCTION: clean up when module is unloaded
339 */ 339 */
340void txExit(void) 340void txExit(void)
341{ 341{
@@ -346,12 +346,12 @@ void txExit(void)
346} 346}
347 347
348/* 348/*
349 * NAME: txBegin() 349 * NAME: txBegin()
350 * 350 *
351 * FUNCTION: start a transaction. 351 * FUNCTION: start a transaction.
352 * 352 *
353 * PARAMETER: sb - superblock 353 * PARAMETER: sb - superblock
354 * flag - force for nested tx; 354 * flag - force for nested tx;
355 * 355 *
356 * RETURN: tid - transaction id 356 * RETURN: tid - transaction id
357 * 357 *
@@ -447,13 +447,13 @@ tid_t txBegin(struct super_block *sb, int flag)
447} 447}
448 448
449/* 449/*
450 * NAME: txBeginAnon() 450 * NAME: txBeginAnon()
451 * 451 *
452 * FUNCTION: start an anonymous transaction. 452 * FUNCTION: start an anonymous transaction.
453 * Blocks if logsync or available tlocks are low to prevent 453 * Blocks if logsync or available tlocks are low to prevent
454 * anonymous tlocks from depleting supply. 454 * anonymous tlocks from depleting supply.
455 * 455 *
456 * PARAMETER: sb - superblock 456 * PARAMETER: sb - superblock
457 * 457 *
458 * RETURN: none 458 * RETURN: none
459 */ 459 */
@@ -489,11 +489,11 @@ void txBeginAnon(struct super_block *sb)
489} 489}
490 490
491/* 491/*
492 * txEnd() 492 * txEnd()
493 * 493 *
494 * function: free specified transaction block. 494 * function: free specified transaction block.
495 * 495 *
496 * logsync barrier processing: 496 * logsync barrier processing:
497 * 497 *
498 * serialization: 498 * serialization:
499 */ 499 */
@@ -577,13 +577,13 @@ wakeup:
577} 577}
578 578
579/* 579/*
580 * txLock() 580 * txLock()
581 * 581 *
582 * function: acquire a transaction lock on the specified <mp> 582 * function: acquire a transaction lock on the specified <mp>
583 * 583 *
584 * parameter: 584 * parameter:
585 * 585 *
586 * return: transaction lock id 586 * return: transaction lock id
587 * 587 *
588 * serialization: 588 * serialization:
589 */ 589 */
@@ -829,12 +829,16 @@ struct tlock *txLock(tid_t tid, struct inode *ip, struct metapage * mp,
829 /* Only locks on ipimap or ipaimap should reach here */ 829 /* Only locks on ipimap or ipaimap should reach here */
830 /* assert(jfs_ip->fileset == AGGREGATE_I); */ 830 /* assert(jfs_ip->fileset == AGGREGATE_I); */
831 if (jfs_ip->fileset != AGGREGATE_I) { 831 if (jfs_ip->fileset != AGGREGATE_I) {
832 jfs_err("txLock: trying to lock locked page!"); 832 printk(KERN_ERR "txLock: trying to lock locked page!");
833 dump_mem("ip", ip, sizeof(struct inode)); 833 print_hex_dump(KERN_ERR, "ip: ", DUMP_PREFIX_ADDRESS, 16, 4,
834 dump_mem("mp", mp, sizeof(struct metapage)); 834 ip, sizeof(*ip), 0);
835 dump_mem("Locker's tblk", tid_to_tblock(tid), 835 print_hex_dump(KERN_ERR, "mp: ", DUMP_PREFIX_ADDRESS, 16, 4,
836 sizeof(struct tblock)); 836 mp, sizeof(*mp), 0);
837 dump_mem("Tlock", tlck, sizeof(struct tlock)); 837 print_hex_dump(KERN_ERR, "Locker's tblock: ",
838 DUMP_PREFIX_ADDRESS, 16, 4, tid_to_tblock(tid),
839 sizeof(struct tblock), 0);
840 print_hex_dump(KERN_ERR, "Tlock: ", DUMP_PREFIX_ADDRESS, 16, 4,
841 tlck, sizeof(*tlck), 0);
838 BUG(); 842 BUG();
839 } 843 }
840 INCREMENT(stattx.waitlock); /* statistics */ 844 INCREMENT(stattx.waitlock); /* statistics */
@@ -857,17 +861,17 @@ struct tlock *txLock(tid_t tid, struct inode *ip, struct metapage * mp,
857} 861}
858 862
859/* 863/*
860 * NAME: txRelease() 864 * NAME: txRelease()
861 * 865 *
862 * FUNCTION: Release buffers associated with transaction locks, but don't 866 * FUNCTION: Release buffers associated with transaction locks, but don't
863 * mark homeok yet. The allows other transactions to modify 867 * mark homeok yet. The allows other transactions to modify
864 * buffers, but won't let them go to disk until commit record 868 * buffers, but won't let them go to disk until commit record
865 * actually gets written. 869 * actually gets written.
866 * 870 *
867 * PARAMETER: 871 * PARAMETER:
868 * tblk - 872 * tblk -
869 * 873 *
870 * RETURN: Errors from subroutines. 874 * RETURN: Errors from subroutines.
871 */ 875 */
872static void txRelease(struct tblock * tblk) 876static void txRelease(struct tblock * tblk)
873{ 877{
@@ -896,10 +900,10 @@ static void txRelease(struct tblock * tblk)
896} 900}
897 901
898/* 902/*
899 * NAME: txUnlock() 903 * NAME: txUnlock()
900 * 904 *
901 * FUNCTION: Initiates pageout of pages modified by tid in journalled 905 * FUNCTION: Initiates pageout of pages modified by tid in journalled
902 * objects and frees their lockwords. 906 * objects and frees their lockwords.
903 */ 907 */
904static void txUnlock(struct tblock * tblk) 908static void txUnlock(struct tblock * tblk)
905{ 909{
@@ -983,10 +987,10 @@ static void txUnlock(struct tblock * tblk)
983} 987}
984 988
985/* 989/*
986 * txMaplock() 990 * txMaplock()
987 * 991 *
988 * function: allocate a transaction lock for freed page/entry; 992 * function: allocate a transaction lock for freed page/entry;
989 * for freed page, maplock is used as xtlock/dtlock type; 993 * for freed page, maplock is used as xtlock/dtlock type;
990 */ 994 */
991struct tlock *txMaplock(tid_t tid, struct inode *ip, int type) 995struct tlock *txMaplock(tid_t tid, struct inode *ip, int type)
992{ 996{
@@ -1057,7 +1061,7 @@ struct tlock *txMaplock(tid_t tid, struct inode *ip, int type)
1057} 1061}
1058 1062
1059/* 1063/*
1060 * txLinelock() 1064 * txLinelock()
1061 * 1065 *
1062 * function: allocate a transaction lock for log vector list 1066 * function: allocate a transaction lock for log vector list
1063 */ 1067 */
@@ -1092,39 +1096,39 @@ struct linelock *txLinelock(struct linelock * tlock)
1092} 1096}
1093 1097
1094/* 1098/*
1095 * transaction commit management 1099 * transaction commit management
1096 * ----------------------------- 1100 * -----------------------------
1097 */ 1101 */
1098 1102
1099/* 1103/*
1100 * NAME: txCommit() 1104 * NAME: txCommit()
1101 * 1105 *
1102 * FUNCTION: commit the changes to the objects specified in 1106 * FUNCTION: commit the changes to the objects specified in
1103 * clist. For journalled segments only the 1107 * clist. For journalled segments only the
1104 * changes of the caller are committed, ie by tid. 1108 * changes of the caller are committed, ie by tid.
1105 * for non-journalled segments the data are flushed to 1109 * for non-journalled segments the data are flushed to
1106 * disk and then the change to the disk inode and indirect 1110 * disk and then the change to the disk inode and indirect
1107 * blocks committed (so blocks newly allocated to the 1111 * blocks committed (so blocks newly allocated to the
1108 * segment will be made a part of the segment atomically). 1112 * segment will be made a part of the segment atomically).
1109 * 1113 *
1110 * all of the segments specified in clist must be in 1114 * all of the segments specified in clist must be in
1111 * one file system. no more than 6 segments are needed 1115 * one file system. no more than 6 segments are needed
1112 * to handle all unix svcs. 1116 * to handle all unix svcs.
1113 * 1117 *
1114 * if the i_nlink field (i.e. disk inode link count) 1118 * if the i_nlink field (i.e. disk inode link count)
1115 * is zero, and the type of inode is a regular file or 1119 * is zero, and the type of inode is a regular file or
1116 * directory, or symbolic link , the inode is truncated 1120 * directory, or symbolic link , the inode is truncated
1117 * to zero length. the truncation is committed but the 1121 * to zero length. the truncation is committed but the
1118 * VM resources are unaffected until it is closed (see 1122 * VM resources are unaffected until it is closed (see
1119 * iput and iclose). 1123 * iput and iclose).
1120 * 1124 *
1121 * PARAMETER: 1125 * PARAMETER:
1122 * 1126 *
1123 * RETURN: 1127 * RETURN:
1124 * 1128 *
1125 * serialization: 1129 * serialization:
1126 * on entry the inode lock on each segment is assumed 1130 * on entry the inode lock on each segment is assumed
1127 * to be held. 1131 * to be held.
1128 * 1132 *
1129 * i/o error: 1133 * i/o error:
1130 */ 1134 */
@@ -1175,7 +1179,7 @@ int txCommit(tid_t tid, /* transaction identifier */
1175 if ((flag & (COMMIT_FORCE | COMMIT_SYNC)) == 0) 1179 if ((flag & (COMMIT_FORCE | COMMIT_SYNC)) == 0)
1176 tblk->xflag |= COMMIT_LAZY; 1180 tblk->xflag |= COMMIT_LAZY;
1177 /* 1181 /*
1178 * prepare non-journaled objects for commit 1182 * prepare non-journaled objects for commit
1179 * 1183 *
1180 * flush data pages of non-journaled file 1184 * flush data pages of non-journaled file
1181 * to prevent the file getting non-initialized disk blocks 1185 * to prevent the file getting non-initialized disk blocks
@@ -1186,7 +1190,7 @@ int txCommit(tid_t tid, /* transaction identifier */
1186 cd.nip = nip; 1190 cd.nip = nip;
1187 1191
1188 /* 1192 /*
1189 * acquire transaction lock on (on-disk) inodes 1193 * acquire transaction lock on (on-disk) inodes
1190 * 1194 *
1191 * update on-disk inode from in-memory inode 1195 * update on-disk inode from in-memory inode
1192 * acquiring transaction locks for AFTER records 1196 * acquiring transaction locks for AFTER records
@@ -1262,7 +1266,7 @@ int txCommit(tid_t tid, /* transaction identifier */
1262 } 1266 }
1263 1267
1264 /* 1268 /*
1265 * write log records from transaction locks 1269 * write log records from transaction locks
1266 * 1270 *
1267 * txUpdateMap() resets XAD_NEW in XAD. 1271 * txUpdateMap() resets XAD_NEW in XAD.
1268 */ 1272 */
@@ -1294,7 +1298,7 @@ int txCommit(tid_t tid, /* transaction identifier */
1294 !test_cflag(COMMIT_Nolink, tblk->u.ip))); 1298 !test_cflag(COMMIT_Nolink, tblk->u.ip)));
1295 1299
1296 /* 1300 /*
1297 * write COMMIT log record 1301 * write COMMIT log record
1298 */ 1302 */
1299 lrd->type = cpu_to_le16(LOG_COMMIT); 1303 lrd->type = cpu_to_le16(LOG_COMMIT);
1300 lrd->length = 0; 1304 lrd->length = 0;
@@ -1303,7 +1307,7 @@ int txCommit(tid_t tid, /* transaction identifier */
1303 lmGroupCommit(log, tblk); 1307 lmGroupCommit(log, tblk);
1304 1308
1305 /* 1309 /*
1306 * - transaction is now committed - 1310 * - transaction is now committed -
1307 */ 1311 */
1308 1312
1309 /* 1313 /*
@@ -1314,11 +1318,11 @@ int txCommit(tid_t tid, /* transaction identifier */
1314 txForce(tblk); 1318 txForce(tblk);
1315 1319
1316 /* 1320 /*
1317 * update allocation map. 1321 * update allocation map.
1318 * 1322 *
1319 * update inode allocation map and inode: 1323 * update inode allocation map and inode:
1320 * free pager lock on memory object of inode if any. 1324 * free pager lock on memory object of inode if any.
1321 * update block allocation map. 1325 * update block allocation map.
1322 * 1326 *
1323 * txUpdateMap() resets XAD_NEW in XAD. 1327 * txUpdateMap() resets XAD_NEW in XAD.
1324 */ 1328 */
@@ -1326,7 +1330,7 @@ int txCommit(tid_t tid, /* transaction identifier */
1326 txUpdateMap(tblk); 1330 txUpdateMap(tblk);
1327 1331
1328 /* 1332 /*
1329 * free transaction locks and pageout/free pages 1333 * free transaction locks and pageout/free pages
1330 */ 1334 */
1331 txRelease(tblk); 1335 txRelease(tblk);
1332 1336
@@ -1335,7 +1339,7 @@ int txCommit(tid_t tid, /* transaction identifier */
1335 1339
1336 1340
1337 /* 1341 /*
1338 * reset in-memory object state 1342 * reset in-memory object state
1339 */ 1343 */
1340 for (k = 0; k < cd.nip; k++) { 1344 for (k = 0; k < cd.nip; k++) {
1341 ip = cd.iplist[k]; 1345 ip = cd.iplist[k];
@@ -1358,11 +1362,11 @@ int txCommit(tid_t tid, /* transaction identifier */
1358} 1362}
1359 1363
1360/* 1364/*
1361 * NAME: txLog() 1365 * NAME: txLog()
1362 * 1366 *
1363 * FUNCTION: Writes AFTER log records for all lines modified 1367 * FUNCTION: Writes AFTER log records for all lines modified
1364 * by tid for segments specified by inodes in comdata. 1368 * by tid for segments specified by inodes in comdata.
1365 * Code assumes only WRITELOCKS are recorded in lockwords. 1369 * Code assumes only WRITELOCKS are recorded in lockwords.
1366 * 1370 *
1367 * PARAMETERS: 1371 * PARAMETERS:
1368 * 1372 *
@@ -1421,12 +1425,12 @@ static int txLog(struct jfs_log * log, struct tblock * tblk, struct commit * cd)
1421} 1425}
1422 1426
1423/* 1427/*
1424 * diLog() 1428 * diLog()
1425 * 1429 *
1426 * function: log inode tlock and format maplock to update bmap; 1430 * function: log inode tlock and format maplock to update bmap;
1427 */ 1431 */
1428static int diLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, 1432static int diLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
1429 struct tlock * tlck, struct commit * cd) 1433 struct tlock * tlck, struct commit * cd)
1430{ 1434{
1431 int rc = 0; 1435 int rc = 0;
1432 struct metapage *mp; 1436 struct metapage *mp;
@@ -1442,7 +1446,7 @@ static int diLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
1442 pxd = &lrd->log.redopage.pxd; 1446 pxd = &lrd->log.redopage.pxd;
1443 1447
1444 /* 1448 /*
1445 * inode after image 1449 * inode after image
1446 */ 1450 */
1447 if (tlck->type & tlckENTRY) { 1451 if (tlck->type & tlckENTRY) {
1448 /* log after-image for logredo(): */ 1452 /* log after-image for logredo(): */
@@ -1456,7 +1460,7 @@ static int diLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
1456 tlck->flag |= tlckWRITEPAGE; 1460 tlck->flag |= tlckWRITEPAGE;
1457 } else if (tlck->type & tlckFREE) { 1461 } else if (tlck->type & tlckFREE) {
1458 /* 1462 /*
1459 * free inode extent 1463 * free inode extent
1460 * 1464 *
1461 * (pages of the freed inode extent have been invalidated and 1465 * (pages of the freed inode extent have been invalidated and
1462 * a maplock for free of the extent has been formatted at 1466 * a maplock for free of the extent has been formatted at
@@ -1498,7 +1502,7 @@ static int diLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
1498 jfs_err("diLog: UFO type tlck:0x%p", tlck); 1502 jfs_err("diLog: UFO type tlck:0x%p", tlck);
1499#ifdef _JFS_WIP 1503#ifdef _JFS_WIP
1500 /* 1504 /*
1501 * alloc/free external EA extent 1505 * alloc/free external EA extent
1502 * 1506 *
1503 * a maplock for txUpdateMap() to update bPWMAP for alloc/free 1507 * a maplock for txUpdateMap() to update bPWMAP for alloc/free
1504 * of the extent has been formatted at txLock() time; 1508 * of the extent has been formatted at txLock() time;
@@ -1534,9 +1538,9 @@ static int diLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
1534} 1538}
1535 1539
1536/* 1540/*
1537 * dataLog() 1541 * dataLog()
1538 * 1542 *
1539 * function: log data tlock 1543 * function: log data tlock
1540 */ 1544 */
1541static int dataLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, 1545static int dataLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
1542 struct tlock * tlck) 1546 struct tlock * tlck)
@@ -1580,9 +1584,9 @@ static int dataLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
1580} 1584}
1581 1585
1582/* 1586/*
1583 * dtLog() 1587 * dtLog()
1584 * 1588 *
1585 * function: log dtree tlock and format maplock to update bmap; 1589 * function: log dtree tlock and format maplock to update bmap;
1586 */ 1590 */
1587static void dtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, 1591static void dtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
1588 struct tlock * tlck) 1592 struct tlock * tlck)
@@ -1603,10 +1607,10 @@ static void dtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
1603 lrd->log.redopage.type |= cpu_to_le16(LOG_BTROOT); 1607 lrd->log.redopage.type |= cpu_to_le16(LOG_BTROOT);
1604 1608
1605 /* 1609 /*
1606 * page extension via relocation: entry insertion; 1610 * page extension via relocation: entry insertion;
1607 * page extension in-place: entry insertion; 1611 * page extension in-place: entry insertion;
1608 * new right page from page split, reinitialized in-line 1612 * new right page from page split, reinitialized in-line
1609 * root from root page split: entry insertion; 1613 * root from root page split: entry insertion;
1610 */ 1614 */
1611 if (tlck->type & (tlckNEW | tlckEXTEND)) { 1615 if (tlck->type & (tlckNEW | tlckEXTEND)) {
1612 /* log after-image of the new page for logredo(): 1616 /* log after-image of the new page for logredo():
@@ -1641,8 +1645,8 @@ static void dtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
1641 } 1645 }
1642 1646
1643 /* 1647 /*
1644 * entry insertion/deletion, 1648 * entry insertion/deletion,
1645 * sibling page link update (old right page before split); 1649 * sibling page link update (old right page before split);
1646 */ 1650 */
1647 if (tlck->type & (tlckENTRY | tlckRELINK)) { 1651 if (tlck->type & (tlckENTRY | tlckRELINK)) {
1648 /* log after-image for logredo(): */ 1652 /* log after-image for logredo(): */
@@ -1658,11 +1662,11 @@ static void dtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
1658 } 1662 }
1659 1663
1660 /* 1664 /*
1661 * page deletion: page has been invalidated 1665 * page deletion: page has been invalidated
1662 * page relocation: source extent 1666 * page relocation: source extent
1663 * 1667 *
1664 * a maplock for free of the page has been formatted 1668 * a maplock for free of the page has been formatted
1665 * at txLock() time); 1669 * at txLock() time);
1666 */ 1670 */
1667 if (tlck->type & (tlckFREE | tlckRELOCATE)) { 1671 if (tlck->type & (tlckFREE | tlckRELOCATE)) {
1668 /* log LOG_NOREDOPAGE of the deleted page for logredo() 1672 /* log LOG_NOREDOPAGE of the deleted page for logredo()
@@ -1683,9 +1687,9 @@ static void dtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
1683} 1687}
1684 1688
1685/* 1689/*
1686 * xtLog() 1690 * xtLog()
1687 * 1691 *
1688 * function: log xtree tlock and format maplock to update bmap; 1692 * function: log xtree tlock and format maplock to update bmap;
1689 */ 1693 */
1690static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, 1694static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
1691 struct tlock * tlck) 1695 struct tlock * tlck)
@@ -1725,8 +1729,8 @@ static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
1725 xadlock = (struct xdlistlock *) maplock; 1729 xadlock = (struct xdlistlock *) maplock;
1726 1730
1727 /* 1731 /*
1728 * entry insertion/extension; 1732 * entry insertion/extension;
1729 * sibling page link update (old right page before split); 1733 * sibling page link update (old right page before split);
1730 */ 1734 */
1731 if (tlck->type & (tlckNEW | tlckGROW | tlckRELINK)) { 1735 if (tlck->type & (tlckNEW | tlckGROW | tlckRELINK)) {
1732 /* log after-image for logredo(): 1736 /* log after-image for logredo():
@@ -1801,7 +1805,7 @@ static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
1801 } 1805 }
1802 1806
1803 /* 1807 /*
1804 * page deletion: file deletion/truncation (ref. xtTruncate()) 1808 * page deletion: file deletion/truncation (ref. xtTruncate())
1805 * 1809 *
1806 * (page will be invalidated after log is written and bmap 1810 * (page will be invalidated after log is written and bmap
1807 * is updated from the page); 1811 * is updated from the page);
@@ -1908,13 +1912,13 @@ static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
1908 } 1912 }
1909 1913
1910 /* 1914 /*
1911 * page/entry truncation: file truncation (ref. xtTruncate()) 1915 * page/entry truncation: file truncation (ref. xtTruncate())
1912 * 1916 *
1913 * |----------+------+------+---------------| 1917 * |----------+------+------+---------------|
1914 * | | | 1918 * | | |
1915 * | | hwm - hwm before truncation 1919 * | | hwm - hwm before truncation
1916 * | next - truncation point 1920 * | next - truncation point
1917 * lwm - lwm before truncation 1921 * lwm - lwm before truncation
1918 * header ? 1922 * header ?
1919 */ 1923 */
1920 if (tlck->type & tlckTRUNCATE) { 1924 if (tlck->type & tlckTRUNCATE) {
@@ -1937,7 +1941,7 @@ static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
1937 twm = xtlck->twm.offset; 1941 twm = xtlck->twm.offset;
1938 1942
1939 /* 1943 /*
1940 * write log records 1944 * write log records
1941 */ 1945 */
1942 /* log after-image for logredo(): 1946 /* log after-image for logredo():
1943 * 1947 *
@@ -1997,7 +2001,7 @@ static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
1997 } 2001 }
1998 2002
1999 /* 2003 /*
2000 * format maplock(s) for txUpdateMap() to update bmap 2004 * format maplock(s) for txUpdateMap() to update bmap
2001 */ 2005 */
2002 maplock->index = 0; 2006 maplock->index = 0;
2003 2007
@@ -2069,9 +2073,9 @@ static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
2069} 2073}
2070 2074
2071/* 2075/*
2072 * mapLog() 2076 * mapLog()
2073 * 2077 *
2074 * function: log from maplock of freed data extents; 2078 * function: log from maplock of freed data extents;
2075 */ 2079 */
2076static void mapLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, 2080static void mapLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
2077 struct tlock * tlck) 2081 struct tlock * tlck)
@@ -2081,7 +2085,7 @@ static void mapLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
2081 pxd_t *pxd; 2085 pxd_t *pxd;
2082 2086
2083 /* 2087 /*
2084 * page relocation: free the source page extent 2088 * page relocation: free the source page extent
2085 * 2089 *
2086 * a maplock for txUpdateMap() for free of the page 2090 * a maplock for txUpdateMap() for free of the page
2087 * has been formatted at txLock() time saving the src 2091 * has been formatted at txLock() time saving the src
@@ -2155,10 +2159,10 @@ static void mapLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
2155} 2159}
2156 2160
2157/* 2161/*
2158 * txEA() 2162 * txEA()
2159 * 2163 *
2160 * function: acquire maplock for EA/ACL extents or 2164 * function: acquire maplock for EA/ACL extents or
2161 * set COMMIT_INLINE flag; 2165 * set COMMIT_INLINE flag;
2162 */ 2166 */
2163void txEA(tid_t tid, struct inode *ip, dxd_t * oldea, dxd_t * newea) 2167void txEA(tid_t tid, struct inode *ip, dxd_t * oldea, dxd_t * newea)
2164{ 2168{
@@ -2207,10 +2211,10 @@ void txEA(tid_t tid, struct inode *ip, dxd_t * oldea, dxd_t * newea)
2207} 2211}
2208 2212
2209/* 2213/*
2210 * txForce() 2214 * txForce()
2211 * 2215 *
2212 * function: synchronously write pages locked by transaction 2216 * function: synchronously write pages locked by transaction
2213 * after txLog() but before txUpdateMap(); 2217 * after txLog() but before txUpdateMap();
2214 */ 2218 */
2215static void txForce(struct tblock * tblk) 2219static void txForce(struct tblock * tblk)
2216{ 2220{
@@ -2273,10 +2277,10 @@ static void txForce(struct tblock * tblk)
2273} 2277}
2274 2278
2275/* 2279/*
2276 * txUpdateMap() 2280 * txUpdateMap()
2277 * 2281 *
2278 * function: update persistent allocation map (and working map 2282 * function: update persistent allocation map (and working map
2279 * if appropriate); 2283 * if appropriate);
2280 * 2284 *
2281 * parameter: 2285 * parameter:
2282 */ 2286 */
@@ -2298,7 +2302,7 @@ static void txUpdateMap(struct tblock * tblk)
2298 2302
2299 2303
2300 /* 2304 /*
2301 * update block allocation map 2305 * update block allocation map
2302 * 2306 *
2303 * update allocation state in pmap (and wmap) and 2307 * update allocation state in pmap (and wmap) and
2304 * update lsn of the pmap page; 2308 * update lsn of the pmap page;
@@ -2382,7 +2386,7 @@ static void txUpdateMap(struct tblock * tblk)
2382 } 2386 }
2383 } 2387 }
2384 /* 2388 /*
2385 * update inode allocation map 2389 * update inode allocation map
2386 * 2390 *
2387 * update allocation state in pmap and 2391 * update allocation state in pmap and
2388 * update lsn of the pmap page; 2392 * update lsn of the pmap page;
@@ -2407,24 +2411,24 @@ static void txUpdateMap(struct tblock * tblk)
2407} 2411}
2408 2412
2409/* 2413/*
2410 * txAllocPMap() 2414 * txAllocPMap()
2411 * 2415 *
2412 * function: allocate from persistent map; 2416 * function: allocate from persistent map;
2413 * 2417 *
2414 * parameter: 2418 * parameter:
2415 * ipbmap - 2419 * ipbmap -
2416 * malock - 2420 * malock -
2417 * xad list: 2421 * xad list:
2418 * pxd: 2422 * pxd:
2419 * 2423 *
2420 * maptype - 2424 * maptype -
2421 * allocate from persistent map; 2425 * allocate from persistent map;
2422 * free from persistent map; 2426 * free from persistent map;
2423 * (e.g., tmp file - free from working map at releae 2427 * (e.g., tmp file - free from working map at releae
2424 * of last reference); 2428 * of last reference);
2425 * free from persistent and working map; 2429 * free from persistent and working map;
2426 * 2430 *
2427 * lsn - log sequence number; 2431 * lsn - log sequence number;
2428 */ 2432 */
2429static void txAllocPMap(struct inode *ip, struct maplock * maplock, 2433static void txAllocPMap(struct inode *ip, struct maplock * maplock,
2430 struct tblock * tblk) 2434 struct tblock * tblk)
@@ -2478,9 +2482,9 @@ static void txAllocPMap(struct inode *ip, struct maplock * maplock,
2478} 2482}
2479 2483
2480/* 2484/*
2481 * txFreeMap() 2485 * txFreeMap()
2482 * 2486 *
2483 * function: free from persistent and/or working map; 2487 * function: free from persistent and/or working map;
2484 * 2488 *
2485 * todo: optimization 2489 * todo: optimization
2486 */ 2490 */
@@ -2579,9 +2583,9 @@ void txFreeMap(struct inode *ip,
2579} 2583}
2580 2584
2581/* 2585/*
2582 * txFreelock() 2586 * txFreelock()
2583 * 2587 *
2584 * function: remove tlock from inode anonymous locklist 2588 * function: remove tlock from inode anonymous locklist
2585 */ 2589 */
2586void txFreelock(struct inode *ip) 2590void txFreelock(struct inode *ip)
2587{ 2591{
@@ -2619,7 +2623,7 @@ void txFreelock(struct inode *ip)
2619} 2623}
2620 2624
2621/* 2625/*
2622 * txAbort() 2626 * txAbort()
2623 * 2627 *
2624 * function: abort tx before commit; 2628 * function: abort tx before commit;
2625 * 2629 *
@@ -2679,7 +2683,7 @@ void txAbort(tid_t tid, int dirty)
2679} 2683}
2680 2684
2681/* 2685/*
2682 * txLazyCommit(void) 2686 * txLazyCommit(void)
2683 * 2687 *
2684 * All transactions except those changing ipimap (COMMIT_FORCE) are 2688 * All transactions except those changing ipimap (COMMIT_FORCE) are
2685 * processed by this routine. This insures that the inode and block 2689 * processed by this routine. This insures that the inode and block
@@ -2728,7 +2732,7 @@ static void txLazyCommit(struct tblock * tblk)
2728} 2732}
2729 2733
2730/* 2734/*
2731 * jfs_lazycommit(void) 2735 * jfs_lazycommit(void)
2732 * 2736 *
2733 * To be run as a kernel daemon. If lbmIODone is called in an interrupt 2737 * To be run as a kernel daemon. If lbmIODone is called in an interrupt
2734 * context, or where blocking is not wanted, this routine will process 2738 * context, or where blocking is not wanted, this routine will process
@@ -2913,7 +2917,7 @@ void txResume(struct super_block *sb)
2913} 2917}
2914 2918
2915/* 2919/*
2916 * jfs_sync(void) 2920 * jfs_sync(void)
2917 * 2921 *
2918 * To be run as a kernel daemon. This is awakened when tlocks run low. 2922 * To be run as a kernel daemon. This is awakened when tlocks run low.
2919 * We write any inodes that have anonymous tlocks so they will become 2923 * We write any inodes that have anonymous tlocks so they will become
diff --git a/fs/jfs/jfs_txnmgr.h b/fs/jfs/jfs_txnmgr.h
index 7863cf21afca..ab7288937019 100644
--- a/fs/jfs/jfs_txnmgr.h
+++ b/fs/jfs/jfs_txnmgr.h
@@ -94,7 +94,7 @@ extern struct tblock *TxBlock; /* transaction block table */
94 */ 94 */
95struct tlock { 95struct tlock {
96 lid_t next; /* 2: index next lockword on tid locklist 96 lid_t next; /* 2: index next lockword on tid locklist
97 * next lockword on freelist 97 * next lockword on freelist
98 */ 98 */
99 tid_t tid; /* 2: transaction id holding lock */ 99 tid_t tid; /* 2: transaction id holding lock */
100 100
diff --git a/fs/jfs/jfs_types.h b/fs/jfs/jfs_types.h
index 09b252958687..649f9817accd 100644
--- a/fs/jfs/jfs_types.h
+++ b/fs/jfs/jfs_types.h
@@ -21,7 +21,7 @@
21/* 21/*
22 * jfs_types.h: 22 * jfs_types.h:
23 * 23 *
24 * basic type/utility definitions 24 * basic type/utility definitions
25 * 25 *
26 * note: this header file must be the 1st include file 26 * note: this header file must be the 1st include file
27 * of JFS include list in all JFS .c file. 27 * of JFS include list in all JFS .c file.
@@ -54,8 +54,8 @@ struct timestruc_t {
54 */ 54 */
55 55
56#define LEFTMOSTONE 0x80000000 56#define LEFTMOSTONE 0x80000000
57#define HIGHORDER 0x80000000u /* high order bit on */ 57#define HIGHORDER 0x80000000u /* high order bit on */
58#define ONES 0xffffffffu /* all bit on */ 58#define ONES 0xffffffffu /* all bit on */
59 59
60/* 60/*
61 * logical xd (lxd) 61 * logical xd (lxd)
@@ -148,7 +148,7 @@ typedef struct {
148#define sizeDXD(dxd) le32_to_cpu((dxd)->size) 148#define sizeDXD(dxd) le32_to_cpu((dxd)->size)
149 149
150/* 150/*
151 * directory entry argument 151 * directory entry argument
152 */ 152 */
153struct component_name { 153struct component_name {
154 int namlen; 154 int namlen;
@@ -160,14 +160,14 @@ struct component_name {
160 * DASD limit information - stored in directory inode 160 * DASD limit information - stored in directory inode
161 */ 161 */
162struct dasd { 162struct dasd {
163 u8 thresh; /* Alert Threshold (in percent) */ 163 u8 thresh; /* Alert Threshold (in percent) */
164 u8 delta; /* Alert Threshold delta (in percent) */ 164 u8 delta; /* Alert Threshold delta (in percent) */
165 u8 rsrvd1; 165 u8 rsrvd1;
166 u8 limit_hi; /* DASD limit (in logical blocks) */ 166 u8 limit_hi; /* DASD limit (in logical blocks) */
167 __le32 limit_lo; /* DASD limit (in logical blocks) */ 167 __le32 limit_lo; /* DASD limit (in logical blocks) */
168 u8 rsrvd2[3]; 168 u8 rsrvd2[3];
169 u8 used_hi; /* DASD usage (in logical blocks) */ 169 u8 used_hi; /* DASD usage (in logical blocks) */
170 __le32 used_lo; /* DASD usage (in logical blocks) */ 170 __le32 used_lo; /* DASD usage (in logical blocks) */
171}; 171};
172 172
173#define DASDLIMIT(dasdp) \ 173#define DASDLIMIT(dasdp) \
diff --git a/fs/jfs/jfs_umount.c b/fs/jfs/jfs_umount.c
index a386f48c73fc..7971f37534a3 100644
--- a/fs/jfs/jfs_umount.c
+++ b/fs/jfs/jfs_umount.c
@@ -60,7 +60,7 @@ int jfs_umount(struct super_block *sb)
60 jfs_info("UnMount JFS: sb:0x%p", sb); 60 jfs_info("UnMount JFS: sb:0x%p", sb);
61 61
62 /* 62 /*
63 * update superblock and close log 63 * update superblock and close log
64 * 64 *
65 * if mounted read-write and log based recovery was enabled 65 * if mounted read-write and log based recovery was enabled
66 */ 66 */
diff --git a/fs/jfs/jfs_xtree.c b/fs/jfs/jfs_xtree.c
index acc97c46d8a4..1543906a2e0d 100644
--- a/fs/jfs/jfs_xtree.c
+++ b/fs/jfs/jfs_xtree.c
@@ -16,7 +16,7 @@
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */ 17 */
18/* 18/*
19 * jfs_xtree.c: extent allocation descriptor B+-tree manager 19 * jfs_xtree.c: extent allocation descriptor B+-tree manager
20 */ 20 */
21 21
22#include <linux/fs.h> 22#include <linux/fs.h>
@@ -32,30 +32,30 @@
32/* 32/*
33 * xtree local flag 33 * xtree local flag
34 */ 34 */
35#define XT_INSERT 0x00000001 35#define XT_INSERT 0x00000001
36 36
37/* 37/*
38 * xtree key/entry comparison: extent offset 38 * xtree key/entry comparison: extent offset
39 * 39 *
40 * return: 40 * return:
41 * -1: k < start of extent 41 * -1: k < start of extent
42 * 0: start_of_extent <= k <= end_of_extent 42 * 0: start_of_extent <= k <= end_of_extent
43 * 1: k > end_of_extent 43 * 1: k > end_of_extent
44 */ 44 */
45#define XT_CMP(CMP, K, X, OFFSET64)\ 45#define XT_CMP(CMP, K, X, OFFSET64)\
46{\ 46{\
47 OFFSET64 = offsetXAD(X);\ 47 OFFSET64 = offsetXAD(X);\
48 (CMP) = ((K) >= OFFSET64 + lengthXAD(X)) ? 1 :\ 48 (CMP) = ((K) >= OFFSET64 + lengthXAD(X)) ? 1 :\
49 ((K) < OFFSET64) ? -1 : 0;\ 49 ((K) < OFFSET64) ? -1 : 0;\
50} 50}
51 51
52/* write a xad entry */ 52/* write a xad entry */
53#define XT_PUTENTRY(XAD, FLAG, OFF, LEN, ADDR)\ 53#define XT_PUTENTRY(XAD, FLAG, OFF, LEN, ADDR)\
54{\ 54{\
55 (XAD)->flag = (FLAG);\ 55 (XAD)->flag = (FLAG);\
56 XADoffset((XAD), (OFF));\ 56 XADoffset((XAD), (OFF));\
57 XADlength((XAD), (LEN));\ 57 XADlength((XAD), (LEN));\
58 XADaddress((XAD), (ADDR));\ 58 XADaddress((XAD), (ADDR));\
59} 59}
60 60
61#define XT_PAGE(IP, MP) BT_PAGE(IP, MP, xtpage_t, i_xtroot) 61#define XT_PAGE(IP, MP) BT_PAGE(IP, MP, xtpage_t, i_xtroot)
@@ -76,13 +76,13 @@
76 MP = NULL;\ 76 MP = NULL;\
77 RC = -EIO;\ 77 RC = -EIO;\
78 }\ 78 }\
79 }\ 79 }\
80} 80}
81 81
82/* for consistency */ 82/* for consistency */
83#define XT_PUTPAGE(MP) BT_PUTPAGE(MP) 83#define XT_PUTPAGE(MP) BT_PUTPAGE(MP)
84 84
85#define XT_GETSEARCH(IP, LEAF, BN, MP, P, INDEX) \ 85#define XT_GETSEARCH(IP, LEAF, BN, MP, P, INDEX) \
86 BT_GETSEARCH(IP, LEAF, BN, MP, xtpage_t, P, INDEX, i_xtroot) 86 BT_GETSEARCH(IP, LEAF, BN, MP, xtpage_t, P, INDEX, i_xtroot)
87/* xtree entry parameter descriptor */ 87/* xtree entry parameter descriptor */
88struct xtsplit { 88struct xtsplit {
@@ -97,7 +97,7 @@ struct xtsplit {
97 97
98 98
99/* 99/*
100 * statistics 100 * statistics
101 */ 101 */
102#ifdef CONFIG_JFS_STATISTICS 102#ifdef CONFIG_JFS_STATISTICS
103static struct { 103static struct {
@@ -136,7 +136,7 @@ static int xtRelink(tid_t tid, struct inode *ip, xtpage_t * fp);
136#endif /* _STILL_TO_PORT */ 136#endif /* _STILL_TO_PORT */
137 137
138/* 138/*
139 * xtLookup() 139 * xtLookup()
140 * 140 *
141 * function: map a single page into a physical extent; 141 * function: map a single page into a physical extent;
142 */ 142 */
@@ -179,7 +179,7 @@ int xtLookup(struct inode *ip, s64 lstart,
179 } 179 }
180 180
181 /* 181 /*
182 * compute the physical extent covering logical extent 182 * compute the physical extent covering logical extent
183 * 183 *
184 * N.B. search may have failed (e.g., hole in sparse file), 184 * N.B. search may have failed (e.g., hole in sparse file),
185 * and returned the index of the next entry. 185 * and returned the index of the next entry.
@@ -220,27 +220,27 @@ int xtLookup(struct inode *ip, s64 lstart,
220 220
221 221
222/* 222/*
223 * xtLookupList() 223 * xtLookupList()
224 * 224 *
225 * function: map a single logical extent into a list of physical extent; 225 * function: map a single logical extent into a list of physical extent;
226 * 226 *
227 * parameter: 227 * parameter:
228 * struct inode *ip, 228 * struct inode *ip,
229 * struct lxdlist *lxdlist, lxd list (in) 229 * struct lxdlist *lxdlist, lxd list (in)
230 * struct xadlist *xadlist, xad list (in/out) 230 * struct xadlist *xadlist, xad list (in/out)
231 * int flag) 231 * int flag)
232 * 232 *
233 * coverage of lxd by xad under assumption of 233 * coverage of lxd by xad under assumption of
234 * . lxd's are ordered and disjoint. 234 * . lxd's are ordered and disjoint.
235 * . xad's are ordered and disjoint. 235 * . xad's are ordered and disjoint.
236 * 236 *
237 * return: 237 * return:
238 * 0: success 238 * 0: success
239 * 239 *
240 * note: a page being written (even a single byte) is backed fully, 240 * note: a page being written (even a single byte) is backed fully,
241 * except the last page which is only backed with blocks 241 * except the last page which is only backed with blocks
242 * required to cover the last byte; 242 * required to cover the last byte;
243 * the extent backing a page is fully contained within an xad; 243 * the extent backing a page is fully contained within an xad;
244 */ 244 */
245int xtLookupList(struct inode *ip, struct lxdlist * lxdlist, 245int xtLookupList(struct inode *ip, struct lxdlist * lxdlist,
246 struct xadlist * xadlist, int flag) 246 struct xadlist * xadlist, int flag)
@@ -284,7 +284,7 @@ int xtLookupList(struct inode *ip, struct lxdlist * lxdlist,
284 return rc; 284 return rc;
285 285
286 /* 286 /*
287 * compute the physical extent covering logical extent 287 * compute the physical extent covering logical extent
288 * 288 *
289 * N.B. search may have failed (e.g., hole in sparse file), 289 * N.B. search may have failed (e.g., hole in sparse file),
290 * and returned the index of the next entry. 290 * and returned the index of the next entry.
@@ -343,7 +343,7 @@ int xtLookupList(struct inode *ip, struct lxdlist * lxdlist,
343 if (lstart >= size) 343 if (lstart >= size)
344 goto mapend; 344 goto mapend;
345 345
346 /* compare with the current xad */ 346 /* compare with the current xad */
347 goto compare1; 347 goto compare1;
348 } 348 }
349 /* lxd is covered by xad */ 349 /* lxd is covered by xad */
@@ -430,7 +430,7 @@ int xtLookupList(struct inode *ip, struct lxdlist * lxdlist,
430 /* 430 /*
431 * lxd is partially covered by xad 431 * lxd is partially covered by xad
432 */ 432 */
433 else { /* (xend < lend) */ 433 else { /* (xend < lend) */
434 434
435 /* 435 /*
436 * get next xad 436 * get next xad
@@ -477,22 +477,22 @@ int xtLookupList(struct inode *ip, struct lxdlist * lxdlist,
477 477
478 478
479/* 479/*
480 * xtSearch() 480 * xtSearch()
481 * 481 *
482 * function: search for the xad entry covering specified offset. 482 * function: search for the xad entry covering specified offset.
483 * 483 *
484 * parameters: 484 * parameters:
485 * ip - file object; 485 * ip - file object;
486 * xoff - extent offset; 486 * xoff - extent offset;
487 * nextp - address of next extent (if any) for search miss 487 * nextp - address of next extent (if any) for search miss
488 * cmpp - comparison result: 488 * cmpp - comparison result:
489 * btstack - traverse stack; 489 * btstack - traverse stack;
490 * flag - search process flag (XT_INSERT); 490 * flag - search process flag (XT_INSERT);
491 * 491 *
492 * returns: 492 * returns:
493 * btstack contains (bn, index) of search path traversed to the entry. 493 * btstack contains (bn, index) of search path traversed to the entry.
494 * *cmpp is set to result of comparison with the entry returned. 494 * *cmpp is set to result of comparison with the entry returned.
495 * the page containing the entry is pinned at exit. 495 * the page containing the entry is pinned at exit.
496 */ 496 */
497static int xtSearch(struct inode *ip, s64 xoff, s64 *nextp, 497static int xtSearch(struct inode *ip, s64 xoff, s64 *nextp,
498 int *cmpp, struct btstack * btstack, int flag) 498 int *cmpp, struct btstack * btstack, int flag)
@@ -517,7 +517,7 @@ static int xtSearch(struct inode *ip, s64 xoff, s64 *nextp,
517 btstack->nsplit = 0; 517 btstack->nsplit = 0;
518 518
519 /* 519 /*
520 * search down tree from root: 520 * search down tree from root:
521 * 521 *
522 * between two consecutive entries of <Ki, Pi> and <Kj, Pj> of 522 * between two consecutive entries of <Ki, Pi> and <Kj, Pj> of
523 * internal page, child page Pi contains entry with k, Ki <= K < Kj. 523 * internal page, child page Pi contains entry with k, Ki <= K < Kj.
@@ -642,7 +642,7 @@ static int xtSearch(struct inode *ip, s64 xoff, s64 *nextp,
642 XT_CMP(cmp, xoff, &p->xad[index], t64); 642 XT_CMP(cmp, xoff, &p->xad[index], t64);
643 if (cmp == 0) { 643 if (cmp == 0) {
644 /* 644 /*
645 * search hit 645 * search hit
646 */ 646 */
647 /* search hit - leaf page: 647 /* search hit - leaf page:
648 * return the entry found 648 * return the entry found
@@ -692,7 +692,7 @@ static int xtSearch(struct inode *ip, s64 xoff, s64 *nextp,
692 } 692 }
693 693
694 /* 694 /*
695 * search miss 695 * search miss
696 * 696 *
697 * base is the smallest index with key (Kj) greater than 697 * base is the smallest index with key (Kj) greater than
698 * search key (K) and may be zero or maxentry index. 698 * search key (K) and may be zero or maxentry index.
@@ -773,22 +773,22 @@ static int xtSearch(struct inode *ip, s64 xoff, s64 *nextp,
773} 773}
774 774
775/* 775/*
776 * xtInsert() 776 * xtInsert()
777 * 777 *
778 * function: 778 * function:
779 * 779 *
780 * parameter: 780 * parameter:
781 * tid - transaction id; 781 * tid - transaction id;
782 * ip - file object; 782 * ip - file object;
783 * xflag - extent flag (XAD_NOTRECORDED): 783 * xflag - extent flag (XAD_NOTRECORDED):
784 * xoff - extent offset; 784 * xoff - extent offset;
785 * xlen - extent length; 785 * xlen - extent length;
786 * xaddrp - extent address pointer (in/out): 786 * xaddrp - extent address pointer (in/out):
787 * if (*xaddrp) 787 * if (*xaddrp)
788 * caller allocated data extent at *xaddrp; 788 * caller allocated data extent at *xaddrp;
789 * else 789 * else
790 * allocate data extent and return its xaddr; 790 * allocate data extent and return its xaddr;
791 * flag - 791 * flag -
792 * 792 *
793 * return: 793 * return:
794 */ 794 */
@@ -813,7 +813,7 @@ int xtInsert(tid_t tid, /* transaction id */
813 jfs_info("xtInsert: nxoff:0x%lx nxlen:0x%x", (ulong) xoff, xlen); 813 jfs_info("xtInsert: nxoff:0x%lx nxlen:0x%x", (ulong) xoff, xlen);
814 814
815 /* 815 /*
816 * search for the entry location at which to insert: 816 * search for the entry location at which to insert:
817 * 817 *
818 * xtFastSearch() and xtSearch() both returns (leaf page 818 * xtFastSearch() and xtSearch() both returns (leaf page
819 * pinned, index at which to insert). 819 * pinned, index at which to insert).
@@ -853,13 +853,13 @@ int xtInsert(tid_t tid, /* transaction id */
853 } 853 }
854 854
855 /* 855 /*
856 * insert entry for new extent 856 * insert entry for new extent
857 */ 857 */
858 xflag |= XAD_NEW; 858 xflag |= XAD_NEW;
859 859
860 /* 860 /*
861 * if the leaf page is full, split the page and 861 * if the leaf page is full, split the page and
862 * propagate up the router entry for the new page from split 862 * propagate up the router entry for the new page from split
863 * 863 *
864 * The xtSplitUp() will insert the entry and unpin the leaf page. 864 * The xtSplitUp() will insert the entry and unpin the leaf page.
865 */ 865 */
@@ -886,7 +886,7 @@ int xtInsert(tid_t tid, /* transaction id */
886 } 886 }
887 887
888 /* 888 /*
889 * insert the new entry into the leaf page 889 * insert the new entry into the leaf page
890 */ 890 */
891 /* 891 /*
892 * acquire a transaction lock on the leaf page; 892 * acquire a transaction lock on the leaf page;
@@ -930,16 +930,16 @@ int xtInsert(tid_t tid, /* transaction id */
930 930
931 931
932/* 932/*
933 * xtSplitUp() 933 * xtSplitUp()
934 * 934 *
935 * function: 935 * function:
936 * split full pages as propagating insertion up the tree 936 * split full pages as propagating insertion up the tree
937 * 937 *
938 * parameter: 938 * parameter:
939 * tid - transaction id; 939 * tid - transaction id;
940 * ip - file object; 940 * ip - file object;
941 * split - entry parameter descriptor; 941 * split - entry parameter descriptor;
942 * btstack - traverse stack from xtSearch() 942 * btstack - traverse stack from xtSearch()
943 * 943 *
944 * return: 944 * return:
945 */ 945 */
@@ -1199,22 +1199,22 @@ xtSplitUp(tid_t tid,
1199 1199
1200 1200
1201/* 1201/*
1202 * xtSplitPage() 1202 * xtSplitPage()
1203 * 1203 *
1204 * function: 1204 * function:
1205 * split a full non-root page into 1205 * split a full non-root page into
1206 * original/split/left page and new right page 1206 * original/split/left page and new right page
1207 * i.e., the original/split page remains as left page. 1207 * i.e., the original/split page remains as left page.
1208 * 1208 *
1209 * parameter: 1209 * parameter:
1210 * int tid, 1210 * int tid,
1211 * struct inode *ip, 1211 * struct inode *ip,
1212 * struct xtsplit *split, 1212 * struct xtsplit *split,
1213 * struct metapage **rmpp, 1213 * struct metapage **rmpp,
1214 * u64 *rbnp, 1214 * u64 *rbnp,
1215 * 1215 *
1216 * return: 1216 * return:
1217 * Pointer to page in which to insert or NULL on error. 1217 * Pointer to page in which to insert or NULL on error.
1218 */ 1218 */
1219static int 1219static int
1220xtSplitPage(tid_t tid, struct inode *ip, 1220xtSplitPage(tid_t tid, struct inode *ip,
@@ -1248,9 +1248,9 @@ xtSplitPage(tid_t tid, struct inode *ip,
1248 rbn = addressPXD(pxd); 1248 rbn = addressPXD(pxd);
1249 1249
1250 /* Allocate blocks to quota. */ 1250 /* Allocate blocks to quota. */
1251 if (DQUOT_ALLOC_BLOCK(ip, lengthPXD(pxd))) { 1251 if (DQUOT_ALLOC_BLOCK(ip, lengthPXD(pxd))) {
1252 rc = -EDQUOT; 1252 rc = -EDQUOT;
1253 goto clean_up; 1253 goto clean_up;
1254 } 1254 }
1255 1255
1256 quota_allocation += lengthPXD(pxd); 1256 quota_allocation += lengthPXD(pxd);
@@ -1304,7 +1304,7 @@ xtSplitPage(tid_t tid, struct inode *ip,
1304 skip = split->index; 1304 skip = split->index;
1305 1305
1306 /* 1306 /*
1307 * sequential append at tail (after last entry of last page) 1307 * sequential append at tail (after last entry of last page)
1308 * 1308 *
1309 * if splitting the last page on a level because of appending 1309 * if splitting the last page on a level because of appending
1310 * a entry to it (skip is maxentry), it's likely that the access is 1310 * a entry to it (skip is maxentry), it's likely that the access is
@@ -1342,7 +1342,7 @@ xtSplitPage(tid_t tid, struct inode *ip,
1342 } 1342 }
1343 1343
1344 /* 1344 /*
1345 * non-sequential insert (at possibly middle page) 1345 * non-sequential insert (at possibly middle page)
1346 */ 1346 */
1347 1347
1348 /* 1348 /*
@@ -1465,25 +1465,24 @@ xtSplitPage(tid_t tid, struct inode *ip,
1465 1465
1466 1466
1467/* 1467/*
1468 * xtSplitRoot() 1468 * xtSplitRoot()
1469 * 1469 *
1470 * function: 1470 * function:
1471 * split the full root page into 1471 * split the full root page into original/root/split page and new
1472 * original/root/split page and new right page 1472 * right page
1473 * i.e., root remains fixed in tree anchor (inode) and 1473 * i.e., root remains fixed in tree anchor (inode) and the root is
1474 * the root is copied to a single new right child page 1474 * copied to a single new right child page since root page <<
1475 * since root page << non-root page, and 1475 * non-root page, and the split root page contains a single entry
1476 * the split root page contains a single entry for the 1476 * for the new right child page.
1477 * new right child page.
1478 * 1477 *
1479 * parameter: 1478 * parameter:
1480 * int tid, 1479 * int tid,
1481 * struct inode *ip, 1480 * struct inode *ip,
1482 * struct xtsplit *split, 1481 * struct xtsplit *split,
1483 * struct metapage **rmpp) 1482 * struct metapage **rmpp)
1484 * 1483 *
1485 * return: 1484 * return:
1486 * Pointer to page in which to insert or NULL on error. 1485 * Pointer to page in which to insert or NULL on error.
1487 */ 1486 */
1488static int 1487static int
1489xtSplitRoot(tid_t tid, 1488xtSplitRoot(tid_t tid,
@@ -1505,7 +1504,7 @@ xtSplitRoot(tid_t tid,
1505 INCREMENT(xtStat.split); 1504 INCREMENT(xtStat.split);
1506 1505
1507 /* 1506 /*
1508 * allocate a single (right) child page 1507 * allocate a single (right) child page
1509 */ 1508 */
1510 pxdlist = split->pxdlist; 1509 pxdlist = split->pxdlist;
1511 pxd = &pxdlist->pxd[pxdlist->npxd]; 1510 pxd = &pxdlist->pxd[pxdlist->npxd];
@@ -1573,7 +1572,7 @@ xtSplitRoot(tid_t tid,
1573 } 1572 }
1574 1573
1575 /* 1574 /*
1576 * reset the root 1575 * reset the root
1577 * 1576 *
1578 * init root with the single entry for the new right page 1577 * init root with the single entry for the new right page
1579 * set the 1st entry offset to 0, which force the left-most key 1578 * set the 1st entry offset to 0, which force the left-most key
@@ -1610,7 +1609,7 @@ xtSplitRoot(tid_t tid,
1610 1609
1611 1610
1612/* 1611/*
1613 * xtExtend() 1612 * xtExtend()
1614 * 1613 *
1615 * function: extend in-place; 1614 * function: extend in-place;
1616 * 1615 *
@@ -1677,7 +1676,7 @@ int xtExtend(tid_t tid, /* transaction id */
1677 goto extendOld; 1676 goto extendOld;
1678 1677
1679 /* 1678 /*
1680 * extent overflow: insert entry for new extent 1679 * extent overflow: insert entry for new extent
1681 */ 1680 */
1682//insertNew: 1681//insertNew:
1683 xoff = offsetXAD(xad) + MAXXLEN; 1682 xoff = offsetXAD(xad) + MAXXLEN;
@@ -1685,8 +1684,8 @@ int xtExtend(tid_t tid, /* transaction id */
1685 nextindex = le16_to_cpu(p->header.nextindex); 1684 nextindex = le16_to_cpu(p->header.nextindex);
1686 1685
1687 /* 1686 /*
1688 * if the leaf page is full, insert the new entry and 1687 * if the leaf page is full, insert the new entry and
1689 * propagate up the router entry for the new page from split 1688 * propagate up the router entry for the new page from split
1690 * 1689 *
1691 * The xtSplitUp() will insert the entry and unpin the leaf page. 1690 * The xtSplitUp() will insert the entry and unpin the leaf page.
1692 */ 1691 */
@@ -1731,7 +1730,7 @@ int xtExtend(tid_t tid, /* transaction id */
1731 } 1730 }
1732 } 1731 }
1733 /* 1732 /*
1734 * insert the new entry into the leaf page 1733 * insert the new entry into the leaf page
1735 */ 1734 */
1736 else { 1735 else {
1737 /* insert the new entry: mark the entry NEW */ 1736 /* insert the new entry: mark the entry NEW */
@@ -1771,11 +1770,11 @@ int xtExtend(tid_t tid, /* transaction id */
1771 1770
1772#ifdef _NOTYET 1771#ifdef _NOTYET
1773/* 1772/*
1774 * xtTailgate() 1773 * xtTailgate()
1775 * 1774 *
1776 * function: split existing 'tail' extent 1775 * function: split existing 'tail' extent
1777 * (split offset >= start offset of tail extent), and 1776 * (split offset >= start offset of tail extent), and
1778 * relocate and extend the split tail half; 1777 * relocate and extend the split tail half;
1779 * 1778 *
1780 * note: existing extent may or may not have been committed. 1779 * note: existing extent may or may not have been committed.
1781 * caller is responsible for pager buffer cache update, and 1780 * caller is responsible for pager buffer cache update, and
@@ -1804,7 +1803,7 @@ int xtTailgate(tid_t tid, /* transaction id */
1804 1803
1805/* 1804/*
1806printf("xtTailgate: nxoff:0x%lx nxlen:0x%x nxaddr:0x%lx\n", 1805printf("xtTailgate: nxoff:0x%lx nxlen:0x%x nxaddr:0x%lx\n",
1807 (ulong)xoff, xlen, (ulong)xaddr); 1806 (ulong)xoff, xlen, (ulong)xaddr);
1808*/ 1807*/
1809 1808
1810 /* there must exist extent to be tailgated */ 1809 /* there must exist extent to be tailgated */
@@ -1842,18 +1841,18 @@ printf("xtTailgate: nxoff:0x%lx nxlen:0x%x nxaddr:0x%lx\n",
1842 xad = &p->xad[index]; 1841 xad = &p->xad[index];
1843/* 1842/*
1844printf("xtTailgate: xoff:0x%lx xlen:0x%x xaddr:0x%lx\n", 1843printf("xtTailgate: xoff:0x%lx xlen:0x%x xaddr:0x%lx\n",
1845 (ulong)offsetXAD(xad), lengthXAD(xad), (ulong)addressXAD(xad)); 1844 (ulong)offsetXAD(xad), lengthXAD(xad), (ulong)addressXAD(xad));
1846*/ 1845*/
1847 if ((llen = xoff - offsetXAD(xad)) == 0) 1846 if ((llen = xoff - offsetXAD(xad)) == 0)
1848 goto updateOld; 1847 goto updateOld;
1849 1848
1850 /* 1849 /*
1851 * partially replace extent: insert entry for new extent 1850 * partially replace extent: insert entry for new extent
1852 */ 1851 */
1853//insertNew: 1852//insertNew:
1854 /* 1853 /*
1855 * if the leaf page is full, insert the new entry and 1854 * if the leaf page is full, insert the new entry and
1856 * propagate up the router entry for the new page from split 1855 * propagate up the router entry for the new page from split
1857 * 1856 *
1858 * The xtSplitUp() will insert the entry and unpin the leaf page. 1857 * The xtSplitUp() will insert the entry and unpin the leaf page.
1859 */ 1858 */
@@ -1898,7 +1897,7 @@ printf("xtTailgate: xoff:0x%lx xlen:0x%x xaddr:0x%lx\n",
1898 } 1897 }
1899 } 1898 }
1900 /* 1899 /*
1901 * insert the new entry into the leaf page 1900 * insert the new entry into the leaf page
1902 */ 1901 */
1903 else { 1902 else {
1904 /* insert the new entry: mark the entry NEW */ 1903 /* insert the new entry: mark the entry NEW */
@@ -1955,17 +1954,17 @@ printf("xtTailgate: xoff:0x%lx xlen:0x%x xaddr:0x%lx\n",
1955#endif /* _NOTYET */ 1954#endif /* _NOTYET */
1956 1955
1957/* 1956/*
1958 * xtUpdate() 1957 * xtUpdate()
1959 * 1958 *
1960 * function: update XAD; 1959 * function: update XAD;
1961 * 1960 *
1962 * update extent for allocated_but_not_recorded or 1961 * update extent for allocated_but_not_recorded or
1963 * compressed extent; 1962 * compressed extent;
1964 * 1963 *
1965 * parameter: 1964 * parameter:
1966 * nxad - new XAD; 1965 * nxad - new XAD;
1967 * logical extent of the specified XAD must be completely 1966 * logical extent of the specified XAD must be completely
1968 * contained by an existing XAD; 1967 * contained by an existing XAD;
1969 */ 1968 */
1970int xtUpdate(tid_t tid, struct inode *ip, xad_t * nxad) 1969int xtUpdate(tid_t tid, struct inode *ip, xad_t * nxad)
1971{ /* new XAD */ 1970{ /* new XAD */
@@ -2416,19 +2415,19 @@ printf("xtUpdate.updateLeft.split p:0x%p\n", p);
2416 2415
2417 2416
2418/* 2417/*
2419 * xtAppend() 2418 * xtAppend()
2420 * 2419 *
2421 * function: grow in append mode from contiguous region specified ; 2420 * function: grow in append mode from contiguous region specified ;
2422 * 2421 *
2423 * parameter: 2422 * parameter:
2424 * tid - transaction id; 2423 * tid - transaction id;
2425 * ip - file object; 2424 * ip - file object;
2426 * xflag - extent flag: 2425 * xflag - extent flag:
2427 * xoff - extent offset; 2426 * xoff - extent offset;
2428 * maxblocks - max extent length; 2427 * maxblocks - max extent length;
2429 * xlen - extent length (in/out); 2428 * xlen - extent length (in/out);
2430 * xaddrp - extent address pointer (in/out): 2429 * xaddrp - extent address pointer (in/out):
2431 * flag - 2430 * flag -
2432 * 2431 *
2433 * return: 2432 * return:
2434 */ 2433 */
@@ -2460,7 +2459,7 @@ int xtAppend(tid_t tid, /* transaction id */
2460 (ulong) xoff, maxblocks, xlen, (ulong) xaddr); 2459 (ulong) xoff, maxblocks, xlen, (ulong) xaddr);
2461 2460
2462 /* 2461 /*
2463 * search for the entry location at which to insert: 2462 * search for the entry location at which to insert:
2464 * 2463 *
2465 * xtFastSearch() and xtSearch() both returns (leaf page 2464 * xtFastSearch() and xtSearch() both returns (leaf page
2466 * pinned, index at which to insert). 2465 * pinned, index at which to insert).
@@ -2482,13 +2481,13 @@ int xtAppend(tid_t tid, /* transaction id */
2482 xlen = min(xlen, (int)(next - xoff)); 2481 xlen = min(xlen, (int)(next - xoff));
2483//insert: 2482//insert:
2484 /* 2483 /*
2485 * insert entry for new extent 2484 * insert entry for new extent
2486 */ 2485 */
2487 xflag |= XAD_NEW; 2486 xflag |= XAD_NEW;
2488 2487
2489 /* 2488 /*
2490 * if the leaf page is full, split the page and 2489 * if the leaf page is full, split the page and
2491 * propagate up the router entry for the new page from split 2490 * propagate up the router entry for the new page from split
2492 * 2491 *
2493 * The xtSplitUp() will insert the entry and unpin the leaf page. 2492 * The xtSplitUp() will insert the entry and unpin the leaf page.
2494 */ 2493 */
@@ -2545,7 +2544,7 @@ int xtAppend(tid_t tid, /* transaction id */
2545 return 0; 2544 return 0;
2546 2545
2547 /* 2546 /*
2548 * insert the new entry into the leaf page 2547 * insert the new entry into the leaf page
2549 */ 2548 */
2550 insertLeaf: 2549 insertLeaf:
2551 /* 2550 /*
@@ -2589,17 +2588,17 @@ int xtAppend(tid_t tid, /* transaction id */
2589 2588
2590/* - TBD for defragmentaion/reorganization - 2589/* - TBD for defragmentaion/reorganization -
2591 * 2590 *
2592 * xtDelete() 2591 * xtDelete()
2593 * 2592 *
2594 * function: 2593 * function:
2595 * delete the entry with the specified key. 2594 * delete the entry with the specified key.
2596 * 2595 *
2597 * N.B.: whole extent of the entry is assumed to be deleted. 2596 * N.B.: whole extent of the entry is assumed to be deleted.
2598 * 2597 *
2599 * parameter: 2598 * parameter:
2600 * 2599 *
2601 * return: 2600 * return:
2602 * ENOENT: if the entry is not found. 2601 * ENOENT: if the entry is not found.
2603 * 2602 *
2604 * exception: 2603 * exception:
2605 */ 2604 */
@@ -2665,10 +2664,10 @@ int xtDelete(tid_t tid, struct inode *ip, s64 xoff, s32 xlen, int flag)
2665 2664
2666/* - TBD for defragmentaion/reorganization - 2665/* - TBD for defragmentaion/reorganization -
2667 * 2666 *
2668 * xtDeleteUp() 2667 * xtDeleteUp()
2669 * 2668 *
2670 * function: 2669 * function:
2671 * free empty pages as propagating deletion up the tree 2670 * free empty pages as propagating deletion up the tree
2672 * 2671 *
2673 * parameter: 2672 * parameter:
2674 * 2673 *
@@ -2815,15 +2814,15 @@ xtDeleteUp(tid_t tid, struct inode *ip,
2815 2814
2816 2815
2817/* 2816/*
2818 * NAME: xtRelocate() 2817 * NAME: xtRelocate()
2819 * 2818 *
2820 * FUNCTION: relocate xtpage or data extent of regular file; 2819 * FUNCTION: relocate xtpage or data extent of regular file;
2821 * This function is mainly used by defragfs utility. 2820 * This function is mainly used by defragfs utility.
2822 * 2821 *
2823 * NOTE: This routine does not have the logic to handle 2822 * NOTE: This routine does not have the logic to handle
2824 * uncommitted allocated extent. The caller should call 2823 * uncommitted allocated extent. The caller should call
2825 * txCommit() to commit all the allocation before call 2824 * txCommit() to commit all the allocation before call
2826 * this routine. 2825 * this routine.
2827 */ 2826 */
2828int 2827int
2829xtRelocate(tid_t tid, struct inode * ip, xad_t * oxad, /* old XAD */ 2828xtRelocate(tid_t tid, struct inode * ip, xad_t * oxad, /* old XAD */
@@ -2865,8 +2864,8 @@ xtRelocate(tid_t tid, struct inode * ip, xad_t * oxad, /* old XAD */
2865 xtype, (ulong) xoff, xlen, (ulong) oxaddr, (ulong) nxaddr); 2864 xtype, (ulong) xoff, xlen, (ulong) oxaddr, (ulong) nxaddr);
2866 2865
2867 /* 2866 /*
2868 * 1. get and validate the parent xtpage/xad entry 2867 * 1. get and validate the parent xtpage/xad entry
2869 * covering the source extent to be relocated; 2868 * covering the source extent to be relocated;
2870 */ 2869 */
2871 if (xtype == DATAEXT) { 2870 if (xtype == DATAEXT) {
2872 /* search in leaf entry */ 2871 /* search in leaf entry */
@@ -2910,7 +2909,7 @@ xtRelocate(tid_t tid, struct inode * ip, xad_t * oxad, /* old XAD */
2910 jfs_info("xtRelocate: parent xad entry validated."); 2909 jfs_info("xtRelocate: parent xad entry validated.");
2911 2910
2912 /* 2911 /*
2913 * 2. relocate the extent 2912 * 2. relocate the extent
2914 */ 2913 */
2915 if (xtype == DATAEXT) { 2914 if (xtype == DATAEXT) {
2916 /* if the extent is allocated-but-not-recorded 2915 /* if the extent is allocated-but-not-recorded
@@ -2923,7 +2922,7 @@ xtRelocate(tid_t tid, struct inode * ip, xad_t * oxad, /* old XAD */
2923 XT_PUTPAGE(pmp); 2922 XT_PUTPAGE(pmp);
2924 2923
2925 /* 2924 /*
2926 * cmRelocate() 2925 * cmRelocate()
2927 * 2926 *
2928 * copy target data pages to be relocated; 2927 * copy target data pages to be relocated;
2929 * 2928 *
@@ -2945,8 +2944,8 @@ xtRelocate(tid_t tid, struct inode * ip, xad_t * oxad, /* old XAD */
2945 pno = offset >> CM_L2BSIZE; 2944 pno = offset >> CM_L2BSIZE;
2946 npages = (nbytes + (CM_BSIZE - 1)) >> CM_L2BSIZE; 2945 npages = (nbytes + (CM_BSIZE - 1)) >> CM_L2BSIZE;
2947/* 2946/*
2948 npages = ((offset + nbytes - 1) >> CM_L2BSIZE) - 2947 npages = ((offset + nbytes - 1) >> CM_L2BSIZE) -
2949 (offset >> CM_L2BSIZE) + 1; 2948 (offset >> CM_L2BSIZE) + 1;
2950*/ 2949*/
2951 sxaddr = oxaddr; 2950 sxaddr = oxaddr;
2952 dxaddr = nxaddr; 2951 dxaddr = nxaddr;
@@ -2981,7 +2980,7 @@ xtRelocate(tid_t tid, struct inode * ip, xad_t * oxad, /* old XAD */
2981 2980
2982 XT_GETSEARCH(ip, btstack.top, bn, pmp, pp, index); 2981 XT_GETSEARCH(ip, btstack.top, bn, pmp, pp, index);
2983 jfs_info("xtRelocate: target data extent relocated."); 2982 jfs_info("xtRelocate: target data extent relocated.");
2984 } else { /* (xtype == XTPAGE) */ 2983 } else { /* (xtype == XTPAGE) */
2985 2984
2986 /* 2985 /*
2987 * read in the target xtpage from the source extent; 2986 * read in the target xtpage from the source extent;
@@ -3026,16 +3025,14 @@ xtRelocate(tid_t tid, struct inode * ip, xad_t * oxad, /* old XAD */
3026 */ 3025 */
3027 if (lmp) { 3026 if (lmp) {
3028 BT_MARK_DIRTY(lmp, ip); 3027 BT_MARK_DIRTY(lmp, ip);
3029 tlck = 3028 tlck = txLock(tid, ip, lmp, tlckXTREE | tlckRELINK);
3030 txLock(tid, ip, lmp, tlckXTREE | tlckRELINK);
3031 lp->header.next = cpu_to_le64(nxaddr); 3029 lp->header.next = cpu_to_le64(nxaddr);
3032 XT_PUTPAGE(lmp); 3030 XT_PUTPAGE(lmp);
3033 } 3031 }
3034 3032
3035 if (rmp) { 3033 if (rmp) {
3036 BT_MARK_DIRTY(rmp, ip); 3034 BT_MARK_DIRTY(rmp, ip);
3037 tlck = 3035 tlck = txLock(tid, ip, rmp, tlckXTREE | tlckRELINK);
3038 txLock(tid, ip, rmp, tlckXTREE | tlckRELINK);
3039 rp->header.prev = cpu_to_le64(nxaddr); 3036 rp->header.prev = cpu_to_le64(nxaddr);
3040 XT_PUTPAGE(rmp); 3037 XT_PUTPAGE(rmp);
3041 } 3038 }
@@ -3062,7 +3059,7 @@ xtRelocate(tid_t tid, struct inode * ip, xad_t * oxad, /* old XAD */
3062 * scan may be skipped by commit() and logredo(); 3059 * scan may be skipped by commit() and logredo();
3063 */ 3060 */
3064 BT_MARK_DIRTY(mp, ip); 3061 BT_MARK_DIRTY(mp, ip);
3065 /* tlckNEW init xtlck->lwm.offset = XTENTRYSTART; */ 3062 /* tlckNEW init xtlck->lwm.offset = XTENTRYSTART; */
3066 tlck = txLock(tid, ip, mp, tlckXTREE | tlckNEW); 3063 tlck = txLock(tid, ip, mp, tlckXTREE | tlckNEW);
3067 xtlck = (struct xtlock *) & tlck->lock; 3064 xtlck = (struct xtlock *) & tlck->lock;
3068 3065
@@ -3084,7 +3081,7 @@ xtRelocate(tid_t tid, struct inode * ip, xad_t * oxad, /* old XAD */
3084 } 3081 }
3085 3082
3086 /* 3083 /*
3087 * 3. acquire maplock for the source extent to be freed; 3084 * 3. acquire maplock for the source extent to be freed;
3088 * 3085 *
3089 * acquire a maplock saving the src relocated extent address; 3086 * acquire a maplock saving the src relocated extent address;
3090 * to free of the extent at commit time; 3087 * to free of the extent at commit time;
@@ -3105,7 +3102,7 @@ xtRelocate(tid_t tid, struct inode * ip, xad_t * oxad, /* old XAD */
3105 * is no buffer associated with this lock since the buffer 3102 * is no buffer associated with this lock since the buffer
3106 * has been redirected to the target location. 3103 * has been redirected to the target location.
3107 */ 3104 */
3108 else /* (xtype == XTPAGE) */ 3105 else /* (xtype == XTPAGE) */
3109 tlck = txMaplock(tid, ip, tlckMAP | tlckRELOCATE); 3106 tlck = txMaplock(tid, ip, tlckMAP | tlckRELOCATE);
3110 3107
3111 pxdlock = (struct pxd_lock *) & tlck->lock; 3108 pxdlock = (struct pxd_lock *) & tlck->lock;
@@ -3115,7 +3112,7 @@ xtRelocate(tid_t tid, struct inode * ip, xad_t * oxad, /* old XAD */
3115 pxdlock->index = 1; 3112 pxdlock->index = 1;
3116 3113
3117 /* 3114 /*
3118 * 4. update the parent xad entry for relocation; 3115 * 4. update the parent xad entry for relocation;
3119 * 3116 *
3120 * acquire tlck for the parent entry with XAD_NEW as entry 3117 * acquire tlck for the parent entry with XAD_NEW as entry
3121 * update which will write LOG_REDOPAGE and update bmap for 3118 * update which will write LOG_REDOPAGE and update bmap for
@@ -3143,22 +3140,22 @@ xtRelocate(tid_t tid, struct inode * ip, xad_t * oxad, /* old XAD */
3143 3140
3144 3141
3145/* 3142/*
3146 * xtSearchNode() 3143 * xtSearchNode()
3147 * 3144 *
3148 * function: search for the internal xad entry covering specified extent. 3145 * function: search for the internal xad entry covering specified extent.
3149 * This function is mainly used by defragfs utility. 3146 * This function is mainly used by defragfs utility.
3150 * 3147 *
3151 * parameters: 3148 * parameters:
3152 * ip - file object; 3149 * ip - file object;
3153 * xad - extent to find; 3150 * xad - extent to find;
3154 * cmpp - comparison result: 3151 * cmpp - comparison result:
3155 * btstack - traverse stack; 3152 * btstack - traverse stack;
3156 * flag - search process flag; 3153 * flag - search process flag;
3157 * 3154 *
3158 * returns: 3155 * returns:
3159 * btstack contains (bn, index) of search path traversed to the entry. 3156 * btstack contains (bn, index) of search path traversed to the entry.
3160 * *cmpp is set to result of comparison with the entry returned. 3157 * *cmpp is set to result of comparison with the entry returned.
3161 * the page containing the entry is pinned at exit. 3158 * the page containing the entry is pinned at exit.
3162 */ 3159 */
3163static int xtSearchNode(struct inode *ip, xad_t * xad, /* required XAD entry */ 3160static int xtSearchNode(struct inode *ip, xad_t * xad, /* required XAD entry */
3164 int *cmpp, struct btstack * btstack, int flag) 3161 int *cmpp, struct btstack * btstack, int flag)
@@ -3181,7 +3178,7 @@ static int xtSearchNode(struct inode *ip, xad_t * xad, /* required XAD entry */
3181 xaddr = addressXAD(xad); 3178 xaddr = addressXAD(xad);
3182 3179
3183 /* 3180 /*
3184 * search down tree from root: 3181 * search down tree from root:
3185 * 3182 *
3186 * between two consecutive entries of <Ki, Pi> and <Kj, Pj> of 3183 * between two consecutive entries of <Ki, Pi> and <Kj, Pj> of
3187 * internal page, child page Pi contains entry with k, Ki <= K < Kj. 3184 * internal page, child page Pi contains entry with k, Ki <= K < Kj.
@@ -3217,7 +3214,7 @@ static int xtSearchNode(struct inode *ip, xad_t * xad, /* required XAD entry */
3217 XT_CMP(cmp, xoff, &p->xad[index], t64); 3214 XT_CMP(cmp, xoff, &p->xad[index], t64);
3218 if (cmp == 0) { 3215 if (cmp == 0) {
3219 /* 3216 /*
3220 * search hit 3217 * search hit
3221 * 3218 *
3222 * verify for exact match; 3219 * verify for exact match;
3223 */ 3220 */
@@ -3245,7 +3242,7 @@ static int xtSearchNode(struct inode *ip, xad_t * xad, /* required XAD entry */
3245 } 3242 }
3246 3243
3247 /* 3244 /*
3248 * search miss - non-leaf page: 3245 * search miss - non-leaf page:
3249 * 3246 *
3250 * base is the smallest index with key (Kj) greater than 3247 * base is the smallest index with key (Kj) greater than
3251 * search key (K) and may be zero or maxentry index. 3248 * search key (K) and may be zero or maxentry index.
@@ -3268,15 +3265,15 @@ static int xtSearchNode(struct inode *ip, xad_t * xad, /* required XAD entry */
3268 3265
3269 3266
3270/* 3267/*
3271 * xtRelink() 3268 * xtRelink()
3272 * 3269 *
3273 * function: 3270 * function:
3274 * link around a freed page. 3271 * link around a freed page.
3275 * 3272 *
3276 * Parameter: 3273 * Parameter:
3277 * int tid, 3274 * int tid,
3278 * struct inode *ip, 3275 * struct inode *ip,
3279 * xtpage_t *p) 3276 * xtpage_t *p)
3280 * 3277 *
3281 * returns: 3278 * returns:
3282 */ 3279 */
@@ -3338,7 +3335,7 @@ static int xtRelink(tid_t tid, struct inode *ip, xtpage_t * p)
3338 3335
3339 3336
3340/* 3337/*
3341 * xtInitRoot() 3338 * xtInitRoot()
3342 * 3339 *
3343 * initialize file root (inline in inode) 3340 * initialize file root (inline in inode)
3344 */ 3341 */
@@ -3385,42 +3382,42 @@ void xtInitRoot(tid_t tid, struct inode *ip)
3385#define MAX_TRUNCATE_LEAVES 50 3382#define MAX_TRUNCATE_LEAVES 50
3386 3383
3387/* 3384/*
3388 * xtTruncate() 3385 * xtTruncate()
3389 * 3386 *
3390 * function: 3387 * function:
3391 * traverse for truncation logging backward bottom up; 3388 * traverse for truncation logging backward bottom up;
3392 * terminate at the last extent entry at the current subtree 3389 * terminate at the last extent entry at the current subtree
3393 * root page covering new down size. 3390 * root page covering new down size.
3394 * truncation may occur within the last extent entry. 3391 * truncation may occur within the last extent entry.
3395 * 3392 *
3396 * parameter: 3393 * parameter:
3397 * int tid, 3394 * int tid,
3398 * struct inode *ip, 3395 * struct inode *ip,
3399 * s64 newsize, 3396 * s64 newsize,
3400 * int type) {PWMAP, PMAP, WMAP; DELETE, TRUNCATE} 3397 * int type) {PWMAP, PMAP, WMAP; DELETE, TRUNCATE}
3401 * 3398 *
3402 * return: 3399 * return:
3403 * 3400 *
3404 * note: 3401 * note:
3405 * PWMAP: 3402 * PWMAP:
3406 * 1. truncate (non-COMMIT_NOLINK file) 3403 * 1. truncate (non-COMMIT_NOLINK file)
3407 * by jfs_truncate() or jfs_open(O_TRUNC): 3404 * by jfs_truncate() or jfs_open(O_TRUNC):
3408 * xtree is updated; 3405 * xtree is updated;
3409 * 2. truncate index table of directory when last entry removed 3406 * 2. truncate index table of directory when last entry removed
3410 * map update via tlock at commit time; 3407 * map update via tlock at commit time;
3411 * PMAP: 3408 * PMAP:
3412 * Call xtTruncate_pmap instead 3409 * Call xtTruncate_pmap instead
3413 * WMAP: 3410 * WMAP:
3414 * 1. remove (free zero link count) on last reference release 3411 * 1. remove (free zero link count) on last reference release
3415 * (pmap has been freed at commit zero link count); 3412 * (pmap has been freed at commit zero link count);
3416 * 2. truncate (COMMIT_NOLINK file, i.e., tmp file): 3413 * 2. truncate (COMMIT_NOLINK file, i.e., tmp file):
3417 * xtree is updated; 3414 * xtree is updated;
3418 * map update directly at truncation time; 3415 * map update directly at truncation time;
3419 * 3416 *
3420 * if (DELETE) 3417 * if (DELETE)
3421 * no LOG_NOREDOPAGE is required (NOREDOFILE is sufficient); 3418 * no LOG_NOREDOPAGE is required (NOREDOFILE is sufficient);
3422 * else if (TRUNCATE) 3419 * else if (TRUNCATE)
3423 * must write LOG_NOREDOPAGE for deleted index page; 3420 * must write LOG_NOREDOPAGE for deleted index page;
3424 * 3421 *
3425 * pages may already have been tlocked by anonymous transactions 3422 * pages may already have been tlocked by anonymous transactions
3426 * during file growth (i.e., write) before truncation; 3423 * during file growth (i.e., write) before truncation;
@@ -3493,7 +3490,7 @@ s64 xtTruncate(tid_t tid, struct inode *ip, s64 newsize, int flag)
3493 * retained in the new sized file. 3490 * retained in the new sized file.
3494 * if type is PMAP, the data and index pages are NOT 3491 * if type is PMAP, the data and index pages are NOT
3495 * freed, and the data and index blocks are NOT freed 3492 * freed, and the data and index blocks are NOT freed
3496 * from working map. 3493 * from working map.
3497 * (this will allow continued access of data/index of 3494 * (this will allow continued access of data/index of
3498 * temporary file (zerolink count file truncated to zero-length)). 3495 * temporary file (zerolink count file truncated to zero-length)).
3499 */ 3496 */
@@ -3542,7 +3539,7 @@ s64 xtTruncate(tid_t tid, struct inode *ip, s64 newsize, int flag)
3542 goto getChild; 3539 goto getChild;
3543 3540
3544 /* 3541 /*
3545 * leaf page 3542 * leaf page
3546 */ 3543 */
3547 freed = 0; 3544 freed = 0;
3548 3545
@@ -3916,7 +3913,7 @@ s64 xtTruncate(tid_t tid, struct inode *ip, s64 newsize, int flag)
3916 } 3913 }
3917 3914
3918 /* 3915 /*
3919 * internal page: go down to child page of current entry 3916 * internal page: go down to child page of current entry
3920 */ 3917 */
3921 getChild: 3918 getChild:
3922 /* save current parent entry for the child page */ 3919 /* save current parent entry for the child page */
@@ -3965,7 +3962,7 @@ s64 xtTruncate(tid_t tid, struct inode *ip, s64 newsize, int flag)
3965 3962
3966 3963
3967/* 3964/*
3968 * xtTruncate_pmap() 3965 * xtTruncate_pmap()
3969 * 3966 *
3970 * function: 3967 * function:
3971 * Perform truncate to zero lenghth for deleted file, leaving the 3968 * Perform truncate to zero lenghth for deleted file, leaving the
@@ -3974,9 +3971,9 @@ s64 xtTruncate(tid_t tid, struct inode *ip, s64 newsize, int flag)
3974 * is committed to disk. 3971 * is committed to disk.
3975 * 3972 *
3976 * parameter: 3973 * parameter:
3977 * tid_t tid, 3974 * tid_t tid,
3978 * struct inode *ip, 3975 * struct inode *ip,
3979 * s64 committed_size) 3976 * s64 committed_size)
3980 * 3977 *
3981 * return: new committed size 3978 * return: new committed size
3982 * 3979 *
@@ -4050,7 +4047,7 @@ s64 xtTruncate_pmap(tid_t tid, struct inode *ip, s64 committed_size)
4050 } 4047 }
4051 4048
4052 /* 4049 /*
4053 * leaf page 4050 * leaf page
4054 */ 4051 */
4055 4052
4056 if (++locked_leaves > MAX_TRUNCATE_LEAVES) { 4053 if (++locked_leaves > MAX_TRUNCATE_LEAVES) {
@@ -4062,7 +4059,7 @@ s64 xtTruncate_pmap(tid_t tid, struct inode *ip, s64 committed_size)
4062 xoff = offsetXAD(xad); 4059 xoff = offsetXAD(xad);
4063 xlen = lengthXAD(xad); 4060 xlen = lengthXAD(xad);
4064 XT_PUTPAGE(mp); 4061 XT_PUTPAGE(mp);
4065 return (xoff + xlen) << JFS_SBI(ip->i_sb)->l2bsize; 4062 return (xoff + xlen) << JFS_SBI(ip->i_sb)->l2bsize;
4066 } 4063 }
4067 tlck = txLock(tid, ip, mp, tlckXTREE); 4064 tlck = txLock(tid, ip, mp, tlckXTREE);
4068 tlck->type = tlckXTREE | tlckFREE; 4065 tlck->type = tlckXTREE | tlckFREE;
@@ -4099,8 +4096,7 @@ s64 xtTruncate_pmap(tid_t tid, struct inode *ip, s64 committed_size)
4099 */ 4096 */
4100 tlck = txLock(tid, ip, mp, tlckXTREE); 4097 tlck = txLock(tid, ip, mp, tlckXTREE);
4101 xtlck = (struct xtlock *) & tlck->lock; 4098 xtlck = (struct xtlock *) & tlck->lock;
4102 xtlck->hwm.offset = 4099 xtlck->hwm.offset = le16_to_cpu(p->header.nextindex) - 1;
4103 le16_to_cpu(p->header.nextindex) - 1;
4104 tlck->type = tlckXTREE | tlckFREE; 4100 tlck->type = tlckXTREE | tlckFREE;
4105 4101
4106 XT_PUTPAGE(mp); 4102 XT_PUTPAGE(mp);
@@ -4118,7 +4114,7 @@ s64 xtTruncate_pmap(tid_t tid, struct inode *ip, s64 committed_size)
4118 else 4114 else
4119 index--; 4115 index--;
4120 /* 4116 /*
4121 * internal page: go down to child page of current entry 4117 * internal page: go down to child page of current entry
4122 */ 4118 */
4123 getChild: 4119 getChild:
4124 /* save current parent entry for the child page */ 4120 /* save current parent entry for the child page */
diff --git a/fs/jfs/jfs_xtree.h b/fs/jfs/jfs_xtree.h
index 164f6f2b1019..70815c8a3d6a 100644
--- a/fs/jfs/jfs_xtree.h
+++ b/fs/jfs/jfs_xtree.h
@@ -19,14 +19,14 @@
19#define _H_JFS_XTREE 19#define _H_JFS_XTREE
20 20
21/* 21/*
22 * jfs_xtree.h: extent allocation descriptor B+-tree manager 22 * jfs_xtree.h: extent allocation descriptor B+-tree manager
23 */ 23 */
24 24
25#include "jfs_btree.h" 25#include "jfs_btree.h"
26 26
27 27
28/* 28/*
29 * extent allocation descriptor (xad) 29 * extent allocation descriptor (xad)
30 */ 30 */
31typedef struct xad { 31typedef struct xad {
32 unsigned flag:8; /* 1: flag */ 32 unsigned flag:8; /* 1: flag */
@@ -38,30 +38,30 @@ typedef struct xad {
38 __le32 addr2; /* 4: address in unit of fsblksize */ 38 __le32 addr2; /* 4: address in unit of fsblksize */
39} xad_t; /* (16) */ 39} xad_t; /* (16) */
40 40
41#define MAXXLEN ((1 << 24) - 1) 41#define MAXXLEN ((1 << 24) - 1)
42 42
43#define XTSLOTSIZE 16 43#define XTSLOTSIZE 16
44#define L2XTSLOTSIZE 4 44#define L2XTSLOTSIZE 4
45 45
46/* xad_t field construction */ 46/* xad_t field construction */
47#define XADoffset(xad, offset64)\ 47#define XADoffset(xad, offset64)\
48{\ 48{\
49 (xad)->off1 = ((u64)offset64) >> 32;\ 49 (xad)->off1 = ((u64)offset64) >> 32;\
50 (xad)->off2 = __cpu_to_le32((offset64) & 0xffffffff);\ 50 (xad)->off2 = __cpu_to_le32((offset64) & 0xffffffff);\
51} 51}
52#define XADaddress(xad, address64)\ 52#define XADaddress(xad, address64)\
53{\ 53{\
54 (xad)->addr1 = ((u64)address64) >> 32;\ 54 (xad)->addr1 = ((u64)address64) >> 32;\
55 (xad)->addr2 = __cpu_to_le32((address64) & 0xffffffff);\ 55 (xad)->addr2 = __cpu_to_le32((address64) & 0xffffffff);\
56} 56}
57#define XADlength(xad, length32) (xad)->len = __cpu_to_le24(length32) 57#define XADlength(xad, length32) (xad)->len = __cpu_to_le24(length32)
58 58
59/* xad_t field extraction */ 59/* xad_t field extraction */
60#define offsetXAD(xad)\ 60#define offsetXAD(xad)\
61 ( ((s64)((xad)->off1)) << 32 | __le32_to_cpu((xad)->off2)) 61 ( ((s64)((xad)->off1)) << 32 | __le32_to_cpu((xad)->off2))
62#define addressXAD(xad)\ 62#define addressXAD(xad)\
63 ( ((s64)((xad)->addr1)) << 32 | __le32_to_cpu((xad)->addr2)) 63 ( ((s64)((xad)->addr1)) << 32 | __le32_to_cpu((xad)->addr2))
64#define lengthXAD(xad) __le24_to_cpu((xad)->len) 64#define lengthXAD(xad) __le24_to_cpu((xad)->len)
65 65
66/* xad list */ 66/* xad list */
67struct xadlist { 67struct xadlist {
@@ -71,22 +71,22 @@ struct xadlist {
71}; 71};
72 72
73/* xad_t flags */ 73/* xad_t flags */
74#define XAD_NEW 0x01 /* new */ 74#define XAD_NEW 0x01 /* new */
75#define XAD_EXTENDED 0x02 /* extended */ 75#define XAD_EXTENDED 0x02 /* extended */
76#define XAD_COMPRESSED 0x04 /* compressed with recorded length */ 76#define XAD_COMPRESSED 0x04 /* compressed with recorded length */
77#define XAD_NOTRECORDED 0x08 /* allocated but not recorded */ 77#define XAD_NOTRECORDED 0x08 /* allocated but not recorded */
78#define XAD_COW 0x10 /* copy-on-write */ 78#define XAD_COW 0x10 /* copy-on-write */
79 79
80 80
81/* possible values for maxentry */ 81/* possible values for maxentry */
82#define XTROOTINITSLOT_DIR 6 82#define XTROOTINITSLOT_DIR 6
83#define XTROOTINITSLOT 10 83#define XTROOTINITSLOT 10
84#define XTROOTMAXSLOT 18 84#define XTROOTMAXSLOT 18
85#define XTPAGEMAXSLOT 256 85#define XTPAGEMAXSLOT 256
86#define XTENTRYSTART 2 86#define XTENTRYSTART 2
87 87
88/* 88/*
89 * xtree page: 89 * xtree page:
90 */ 90 */
91typedef union { 91typedef union {
92 struct xtheader { 92 struct xtheader {
@@ -106,7 +106,7 @@ typedef union {
106} xtpage_t; 106} xtpage_t;
107 107
108/* 108/*
109 * external declaration 109 * external declaration
110 */ 110 */
111extern int xtLookup(struct inode *ip, s64 lstart, s64 llen, 111extern int xtLookup(struct inode *ip, s64 lstart, s64 llen,
112 int *pflag, s64 * paddr, int *plen, int flag); 112 int *pflag, s64 * paddr, int *plen, int flag);
diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c
index 41c204771262..25161c4121e4 100644
--- a/fs/jfs/namei.c
+++ b/fs/jfs/namei.c
@@ -328,7 +328,7 @@ static int jfs_mkdir(struct inode *dip, struct dentry *dentry, int mode)
328 * dentry - child directory dentry 328 * dentry - child directory dentry
329 * 329 *
330 * RETURN: -EINVAL - if name is . or .. 330 * RETURN: -EINVAL - if name is . or ..
331 * -EINVAL - if . or .. exist but are invalid. 331 * -EINVAL - if . or .. exist but are invalid.
332 * errors from subroutines 332 * errors from subroutines
333 * 333 *
334 * note: 334 * note:
@@ -517,7 +517,7 @@ static int jfs_unlink(struct inode *dip, struct dentry *dentry)
517 inode_dec_link_count(ip); 517 inode_dec_link_count(ip);
518 518
519 /* 519 /*
520 * commit zero link count object 520 * commit zero link count object
521 */ 521 */
522 if (ip->i_nlink == 0) { 522 if (ip->i_nlink == 0) {
523 assert(!test_cflag(COMMIT_Nolink, ip)); 523 assert(!test_cflag(COMMIT_Nolink, ip));
@@ -596,7 +596,7 @@ static int jfs_unlink(struct inode *dip, struct dentry *dentry)
596/* 596/*
597 * NAME: commitZeroLink() 597 * NAME: commitZeroLink()
598 * 598 *
599 * FUNCTION: for non-directory, called by jfs_remove(), 599 * FUNCTION: for non-directory, called by jfs_remove(),
600 * truncate a regular file, directory or symbolic 600 * truncate a regular file, directory or symbolic
601 * link to zero length. return 0 if type is not 601 * link to zero length. return 0 if type is not
602 * one of these. 602 * one of these.
@@ -676,7 +676,7 @@ static s64 commitZeroLink(tid_t tid, struct inode *ip)
676/* 676/*
677 * NAME: jfs_free_zero_link() 677 * NAME: jfs_free_zero_link()
678 * 678 *
679 * FUNCTION: for non-directory, called by iClose(), 679 * FUNCTION: for non-directory, called by iClose(),
680 * free resources of a file from cache and WORKING map 680 * free resources of a file from cache and WORKING map
681 * for a file previously committed with zero link count 681 * for a file previously committed with zero link count
682 * while associated with a pager object, 682 * while associated with a pager object,
@@ -855,12 +855,12 @@ static int jfs_link(struct dentry *old_dentry,
855 * NAME: jfs_symlink(dip, dentry, name) 855 * NAME: jfs_symlink(dip, dentry, name)
856 * 856 *
857 * FUNCTION: creates a symbolic link to <symlink> by name <name> 857 * FUNCTION: creates a symbolic link to <symlink> by name <name>
858 * in directory <dip> 858 * in directory <dip>
859 * 859 *
860 * PARAMETER: dip - parent directory vnode 860 * PARAMETER: dip - parent directory vnode
861 * dentry - dentry of symbolic link 861 * dentry - dentry of symbolic link
862 * name - the path name of the existing object 862 * name - the path name of the existing object
863 * that will be the source of the link 863 * that will be the source of the link
864 * 864 *
865 * RETURN: errors from subroutines 865 * RETURN: errors from subroutines
866 * 866 *
@@ -1052,9 +1052,9 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry,
1052 1052
1053 1053
1054/* 1054/*
1055 * NAME: jfs_rename 1055 * NAME: jfs_rename
1056 * 1056 *
1057 * FUNCTION: rename a file or directory 1057 * FUNCTION: rename a file or directory
1058 */ 1058 */
1059static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry, 1059static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry,
1060 struct inode *new_dir, struct dentry *new_dentry) 1060 struct inode *new_dir, struct dentry *new_dentry)
@@ -1331,9 +1331,9 @@ static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry,
1331 1331
1332 1332
1333/* 1333/*
1334 * NAME: jfs_mknod 1334 * NAME: jfs_mknod
1335 * 1335 *
1336 * FUNCTION: Create a special file (device) 1336 * FUNCTION: Create a special file (device)
1337 */ 1337 */
1338static int jfs_mknod(struct inode *dir, struct dentry *dentry, 1338static int jfs_mknod(struct inode *dir, struct dentry *dentry,
1339 int mode, dev_t rdev) 1339 int mode, dev_t rdev)
diff --git a/fs/jfs/resize.c b/fs/jfs/resize.c
index 79d625f3f733..71984ee95346 100644
--- a/fs/jfs/resize.c
+++ b/fs/jfs/resize.c
@@ -29,17 +29,17 @@
29#include "jfs_txnmgr.h" 29#include "jfs_txnmgr.h"
30#include "jfs_debug.h" 30#include "jfs_debug.h"
31 31
32#define BITSPERPAGE (PSIZE << 3) 32#define BITSPERPAGE (PSIZE << 3)
33#define L2MEGABYTE 20 33#define L2MEGABYTE 20
34#define MEGABYTE (1 << L2MEGABYTE) 34#define MEGABYTE (1 << L2MEGABYTE)
35#define MEGABYTE32 (MEGABYTE << 5) 35#define MEGABYTE32 (MEGABYTE << 5)
36 36
37/* convert block number to bmap file page number */ 37/* convert block number to bmap file page number */
38#define BLKTODMAPN(b)\ 38#define BLKTODMAPN(b)\
39 (((b) >> 13) + ((b) >> 23) + ((b) >> 33) + 3 + 1) 39 (((b) >> 13) + ((b) >> 23) + ((b) >> 33) + 3 + 1)
40 40
41/* 41/*
42 * jfs_extendfs() 42 * jfs_extendfs()
43 * 43 *
44 * function: extend file system; 44 * function: extend file system;
45 * 45 *
@@ -48,9 +48,9 @@
48 * workspace space 48 * workspace space
49 * 49 *
50 * input: 50 * input:
51 * new LVSize: in LV blocks (required) 51 * new LVSize: in LV blocks (required)
52 * new LogSize: in LV blocks (optional) 52 * new LogSize: in LV blocks (optional)
53 * new FSSize: in LV blocks (optional) 53 * new FSSize: in LV blocks (optional)
54 * 54 *
55 * new configuration: 55 * new configuration:
56 * 1. set new LogSize as specified or default from new LVSize; 56 * 1. set new LogSize as specified or default from new LVSize;
@@ -125,8 +125,8 @@ int jfs_extendfs(struct super_block *sb, s64 newLVSize, int newLogSize)
125 } 125 }
126 126
127 /* 127 /*
128 * reconfigure LV spaces 128 * reconfigure LV spaces
129 * --------------------- 129 * ---------------------
130 * 130 *
131 * validate new size, or, if not specified, determine new size 131 * validate new size, or, if not specified, determine new size
132 */ 132 */
@@ -198,7 +198,7 @@ int jfs_extendfs(struct super_block *sb, s64 newLVSize, int newLogSize)
198 log_formatted = 1; 198 log_formatted = 1;
199 } 199 }
200 /* 200 /*
201 * quiesce file system 201 * quiesce file system
202 * 202 *
203 * (prepare to move the inline log and to prevent map update) 203 * (prepare to move the inline log and to prevent map update)
204 * 204 *
@@ -270,8 +270,8 @@ int jfs_extendfs(struct super_block *sb, s64 newLVSize, int newLogSize)
270 } 270 }
271 271
272 /* 272 /*
273 * extend block allocation map 273 * extend block allocation map
274 * --------------------------- 274 * ---------------------------
275 * 275 *
276 * extendfs() for new extension, retry after crash recovery; 276 * extendfs() for new extension, retry after crash recovery;
277 * 277 *
@@ -283,7 +283,7 @@ int jfs_extendfs(struct super_block *sb, s64 newLVSize, int newLogSize)
283 * s_size: aggregate size in physical blocks; 283 * s_size: aggregate size in physical blocks;
284 */ 284 */
285 /* 285 /*
286 * compute the new block allocation map configuration 286 * compute the new block allocation map configuration
287 * 287 *
288 * map dinode: 288 * map dinode:
289 * di_size: map file size in byte; 289 * di_size: map file size in byte;
@@ -301,7 +301,7 @@ int jfs_extendfs(struct super_block *sb, s64 newLVSize, int newLogSize)
301 newNpages = BLKTODMAPN(t64) + 1; 301 newNpages = BLKTODMAPN(t64) + 1;
302 302
303 /* 303 /*
304 * extend map from current map (WITHOUT growing mapfile) 304 * extend map from current map (WITHOUT growing mapfile)
305 * 305 *
306 * map new extension with unmapped part of the last partial 306 * map new extension with unmapped part of the last partial
307 * dmap page, if applicable, and extra page(s) allocated 307 * dmap page, if applicable, and extra page(s) allocated
@@ -341,8 +341,8 @@ int jfs_extendfs(struct super_block *sb, s64 newLVSize, int newLogSize)
341 XSize -= nblocks; 341 XSize -= nblocks;
342 342
343 /* 343 /*
344 * grow map file to cover remaining extension 344 * grow map file to cover remaining extension
345 * and/or one extra dmap page for next extendfs(); 345 * and/or one extra dmap page for next extendfs();
346 * 346 *
347 * allocate new map pages and its backing blocks, and 347 * allocate new map pages and its backing blocks, and
348 * update map file xtree 348 * update map file xtree
@@ -422,8 +422,8 @@ int jfs_extendfs(struct super_block *sb, s64 newLVSize, int newLogSize)
422 dbFinalizeBmap(ipbmap); 422 dbFinalizeBmap(ipbmap);
423 423
424 /* 424 /*
425 * update inode allocation map 425 * update inode allocation map
426 * --------------------------- 426 * ---------------------------
427 * 427 *
428 * move iag lists from old to new iag; 428 * move iag lists from old to new iag;
429 * agstart field is not updated for logredo() to reconstruct 429 * agstart field is not updated for logredo() to reconstruct
@@ -442,8 +442,8 @@ int jfs_extendfs(struct super_block *sb, s64 newLVSize, int newLogSize)
442 } 442 }
443 443
444 /* 444 /*
445 * finalize 445 * finalize
446 * -------- 446 * --------
447 * 447 *
448 * extension is committed when on-disk super block is 448 * extension is committed when on-disk super block is
449 * updated with new descriptors: logredo will recover 449 * updated with new descriptors: logredo will recover
@@ -480,7 +480,7 @@ int jfs_extendfs(struct super_block *sb, s64 newLVSize, int newLogSize)
480 diFreeSpecial(ipbmap2); 480 diFreeSpecial(ipbmap2);
481 481
482 /* 482 /*
483 * update superblock 483 * update superblock
484 */ 484 */
485 if ((rc = readSuper(sb, &bh))) 485 if ((rc = readSuper(sb, &bh)))
486 goto error_out; 486 goto error_out;
@@ -530,7 +530,7 @@ int jfs_extendfs(struct super_block *sb, s64 newLVSize, int newLogSize)
530 530
531 resume: 531 resume:
532 /* 532 /*
533 * resume file system transactions 533 * resume file system transactions
534 */ 534 */
535 txResume(sb); 535 txResume(sb);
536 536
diff --git a/fs/jfs/xattr.c b/fs/jfs/xattr.c
index b753ba216450..b2375f0774b7 100644
--- a/fs/jfs/xattr.c
+++ b/fs/jfs/xattr.c
@@ -63,9 +63,9 @@
63 * 63 *
64 * On-disk: 64 * On-disk:
65 * 65 *
66 * FEALISTs are stored on disk using blocks allocated by dbAlloc() and 66 * FEALISTs are stored on disk using blocks allocated by dbAlloc() and
67 * written directly. An EA list may be in-lined in the inode if there is 67 * written directly. An EA list may be in-lined in the inode if there is
68 * sufficient room available. 68 * sufficient room available.
69 */ 69 */
70 70
71struct ea_buffer { 71struct ea_buffer {
@@ -590,7 +590,8 @@ static int ea_get(struct inode *inode, struct ea_buffer *ea_buf, int min_size)
590 size_check: 590 size_check:
591 if (EALIST_SIZE(ea_buf->xattr) != ea_size) { 591 if (EALIST_SIZE(ea_buf->xattr) != ea_size) {
592 printk(KERN_ERR "ea_get: invalid extended attribute\n"); 592 printk(KERN_ERR "ea_get: invalid extended attribute\n");
593 dump_mem("xattr", ea_buf->xattr, ea_size); 593 print_hex_dump(KERN_ERR, "", DUMP_PREFIX_ADDRESS, 16, 1,
594 ea_buf->xattr, ea_size, 1);
594 ea_release(inode, ea_buf); 595 ea_release(inode, ea_buf);
595 rc = -EIO; 596 rc = -EIO;
596 goto clean_up; 597 goto clean_up;
diff --git a/fs/minix/file.c b/fs/minix/file.c
index f92baa1d7570..17765f697e50 100644
--- a/fs/minix/file.c
+++ b/fs/minix/file.c
@@ -23,7 +23,7 @@ const struct file_operations minix_file_operations = {
23 .aio_write = generic_file_aio_write, 23 .aio_write = generic_file_aio_write,
24 .mmap = generic_file_mmap, 24 .mmap = generic_file_mmap,
25 .fsync = minix_sync_file, 25 .fsync = minix_sync_file,
26 .sendfile = generic_file_sendfile, 26 .splice_read = generic_file_splice_read,
27}; 27};
28 28
29const struct inode_operations minix_file_inode_operations = { 29const struct inode_operations minix_file_inode_operations = {
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index 9eb8eb4e4a08..8689b736fdd9 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -41,7 +41,9 @@ static int nfs_file_open(struct inode *, struct file *);
41static int nfs_file_release(struct inode *, struct file *); 41static int nfs_file_release(struct inode *, struct file *);
42static loff_t nfs_file_llseek(struct file *file, loff_t offset, int origin); 42static loff_t nfs_file_llseek(struct file *file, loff_t offset, int origin);
43static int nfs_file_mmap(struct file *, struct vm_area_struct *); 43static int nfs_file_mmap(struct file *, struct vm_area_struct *);
44static ssize_t nfs_file_sendfile(struct file *, loff_t *, size_t, read_actor_t, void *); 44static ssize_t nfs_file_splice_read(struct file *filp, loff_t *ppos,
45 struct pipe_inode_info *pipe,
46 size_t count, unsigned int flags);
45static ssize_t nfs_file_read(struct kiocb *, const struct iovec *iov, 47static ssize_t nfs_file_read(struct kiocb *, const struct iovec *iov,
46 unsigned long nr_segs, loff_t pos); 48 unsigned long nr_segs, loff_t pos);
47static ssize_t nfs_file_write(struct kiocb *, const struct iovec *iov, 49static ssize_t nfs_file_write(struct kiocb *, const struct iovec *iov,
@@ -65,7 +67,7 @@ const struct file_operations nfs_file_operations = {
65 .fsync = nfs_fsync, 67 .fsync = nfs_fsync,
66 .lock = nfs_lock, 68 .lock = nfs_lock,
67 .flock = nfs_flock, 69 .flock = nfs_flock,
68 .sendfile = nfs_file_sendfile, 70 .splice_read = nfs_file_splice_read,
69 .check_flags = nfs_check_flags, 71 .check_flags = nfs_check_flags,
70}; 72};
71 73
@@ -224,20 +226,21 @@ nfs_file_read(struct kiocb *iocb, const struct iovec *iov,
224} 226}
225 227
226static ssize_t 228static ssize_t
227nfs_file_sendfile(struct file *filp, loff_t *ppos, size_t count, 229nfs_file_splice_read(struct file *filp, loff_t *ppos,
228 read_actor_t actor, void *target) 230 struct pipe_inode_info *pipe, size_t count,
231 unsigned int flags)
229{ 232{
230 struct dentry *dentry = filp->f_path.dentry; 233 struct dentry *dentry = filp->f_path.dentry;
231 struct inode *inode = dentry->d_inode; 234 struct inode *inode = dentry->d_inode;
232 ssize_t res; 235 ssize_t res;
233 236
234 dfprintk(VFS, "nfs: sendfile(%s/%s, %lu@%Lu)\n", 237 dfprintk(VFS, "nfs: splice_read(%s/%s, %lu@%Lu)\n",
235 dentry->d_parent->d_name.name, dentry->d_name.name, 238 dentry->d_parent->d_name.name, dentry->d_name.name,
236 (unsigned long) count, (unsigned long long) *ppos); 239 (unsigned long) count, (unsigned long long) *ppos);
237 240
238 res = nfs_revalidate_mapping(inode, filp->f_mapping); 241 res = nfs_revalidate_mapping(inode, filp->f_mapping);
239 if (!res) 242 if (!res)
240 res = generic_file_sendfile(filp, ppos, count, actor, target); 243 res = generic_file_splice_read(filp, ppos, pipe, count, flags);
241 return res; 244 return res;
242} 245}
243 246
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 7e6aa245b5d5..8604e35bd48e 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -23,7 +23,7 @@
23#include <linux/file.h> 23#include <linux/file.h>
24#include <linux/mount.h> 24#include <linux/mount.h>
25#include <linux/major.h> 25#include <linux/major.h>
26#include <linux/ext2_fs.h> 26#include <linux/splice.h>
27#include <linux/proc_fs.h> 27#include <linux/proc_fs.h>
28#include <linux/stat.h> 28#include <linux/stat.h>
29#include <linux/fcntl.h> 29#include <linux/fcntl.h>
@@ -801,26 +801,32 @@ found:
801} 801}
802 802
803/* 803/*
804 * Grab and keep cached pages assosiated with a file in the svc_rqst 804 * Grab and keep cached pages associated with a file in the svc_rqst
805 * so that they can be passed to the netowork sendmsg/sendpage routines 805 * so that they can be passed to the network sendmsg/sendpage routines
806 * directrly. They will be released after the sending has completed. 806 * directly. They will be released after the sending has completed.
807 */ 807 */
808static int 808static int
809nfsd_read_actor(read_descriptor_t *desc, struct page *page, unsigned long offset , unsigned long size) 809nfsd_splice_actor(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
810 struct splice_desc *sd)
810{ 811{
811 unsigned long count = desc->count; 812 struct svc_rqst *rqstp = sd->u.data;
812 struct svc_rqst *rqstp = desc->arg.data;
813 struct page **pp = rqstp->rq_respages + rqstp->rq_resused; 813 struct page **pp = rqstp->rq_respages + rqstp->rq_resused;
814 struct page *page = buf->page;
815 size_t size;
816 int ret;
817
818 ret = buf->ops->confirm(pipe, buf);
819 if (unlikely(ret))
820 return ret;
814 821
815 if (size > count) 822 size = sd->len;
816 size = count;
817 823
818 if (rqstp->rq_res.page_len == 0) { 824 if (rqstp->rq_res.page_len == 0) {
819 get_page(page); 825 get_page(page);
820 put_page(*pp); 826 put_page(*pp);
821 *pp = page; 827 *pp = page;
822 rqstp->rq_resused++; 828 rqstp->rq_resused++;
823 rqstp->rq_res.page_base = offset; 829 rqstp->rq_res.page_base = buf->offset;
824 rqstp->rq_res.page_len = size; 830 rqstp->rq_res.page_len = size;
825 } else if (page != pp[-1]) { 831 } else if (page != pp[-1]) {
826 get_page(page); 832 get_page(page);
@@ -832,11 +838,15 @@ nfsd_read_actor(read_descriptor_t *desc, struct page *page, unsigned long offset
832 } else 838 } else
833 rqstp->rq_res.page_len += size; 839 rqstp->rq_res.page_len += size;
834 840
835 desc->count = count - size;
836 desc->written += size;
837 return size; 841 return size;
838} 842}
839 843
844static int nfsd_direct_splice_actor(struct pipe_inode_info *pipe,
845 struct splice_desc *sd)
846{
847 return __splice_from_pipe(pipe, sd, nfsd_splice_actor);
848}
849
840static __be32 850static __be32
841nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, 851nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
842 loff_t offset, struct kvec *vec, int vlen, unsigned long *count) 852 loff_t offset, struct kvec *vec, int vlen, unsigned long *count)
@@ -861,10 +871,15 @@ nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
861 if (ra && ra->p_set) 871 if (ra && ra->p_set)
862 file->f_ra = ra->p_ra; 872 file->f_ra = ra->p_ra;
863 873
864 if (file->f_op->sendfile && rqstp->rq_sendfile_ok) { 874 if (file->f_op->splice_read && rqstp->rq_splice_ok) {
865 rqstp->rq_resused = 1; 875 struct splice_desc sd = {
866 host_err = file->f_op->sendfile(file, &offset, *count, 876 .len = 0,
867 nfsd_read_actor, rqstp); 877 .total_len = *count,
878 .pos = offset,
879 .u.data = rqstp,
880 };
881
882 host_err = splice_direct_to_actor(file, &sd, nfsd_direct_splice_actor);
868 } else { 883 } else {
869 oldfs = get_fs(); 884 oldfs = get_fs();
870 set_fs(KERNEL_DS); 885 set_fs(KERNEL_DS);
diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c
index 7ed56390b582..ffcc504a1667 100644
--- a/fs/ntfs/file.c
+++ b/fs/ntfs/file.c
@@ -2276,7 +2276,7 @@ const struct file_operations ntfs_file_ops = {
2276 mounted filesystem. */ 2276 mounted filesystem. */
2277 .mmap = generic_file_mmap, /* Mmap file. */ 2277 .mmap = generic_file_mmap, /* Mmap file. */
2278 .open = ntfs_file_open, /* Open file. */ 2278 .open = ntfs_file_open, /* Open file. */
2279 .sendfile = generic_file_sendfile, /* Zero-copy data send with 2279 .splice_read = generic_file_splice_read /* Zero-copy data send with
2280 the data source being on 2280 the data source being on
2281 the ntfs partition. We do 2281 the ntfs partition. We do
2282 not need to care about the 2282 not need to care about the
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c
index ac6c96431bbc..4979b6675717 100644
--- a/fs/ocfs2/file.c
+++ b/fs/ocfs2/file.c
@@ -31,7 +31,7 @@
31#include <linux/pagemap.h> 31#include <linux/pagemap.h>
32#include <linux/uio.h> 32#include <linux/uio.h>
33#include <linux/sched.h> 33#include <linux/sched.h>
34#include <linux/pipe_fs_i.h> 34#include <linux/splice.h>
35#include <linux/mount.h> 35#include <linux/mount.h>
36#include <linux/writeback.h> 36#include <linux/writeback.h>
37 37
@@ -1583,7 +1583,7 @@ static int ocfs2_splice_write_actor(struct pipe_inode_info *pipe,
1583 ssize_t copied = 0; 1583 ssize_t copied = 0;
1584 struct ocfs2_splice_write_priv sp; 1584 struct ocfs2_splice_write_priv sp;
1585 1585
1586 ret = buf->ops->pin(pipe, buf); 1586 ret = buf->ops->confirm(pipe, buf);
1587 if (ret) 1587 if (ret)
1588 goto out; 1588 goto out;
1589 1589
@@ -1604,7 +1604,7 @@ static int ocfs2_splice_write_actor(struct pipe_inode_info *pipe,
1604 * might enter ocfs2_buffered_write_cluster() more 1604 * might enter ocfs2_buffered_write_cluster() more
1605 * than once, so keep track of our progress here. 1605 * than once, so keep track of our progress here.
1606 */ 1606 */
1607 copied = ocfs2_buffered_write_cluster(sd->file, 1607 copied = ocfs2_buffered_write_cluster(sd->u.file,
1608 (loff_t)sd->pos + total, 1608 (loff_t)sd->pos + total,
1609 count, 1609 count,
1610 ocfs2_map_and_write_splice_data, 1610 ocfs2_map_and_write_splice_data,
@@ -1636,9 +1636,14 @@ static ssize_t __ocfs2_file_splice_write(struct pipe_inode_info *pipe,
1636 int ret, err; 1636 int ret, err;
1637 struct address_space *mapping = out->f_mapping; 1637 struct address_space *mapping = out->f_mapping;
1638 struct inode *inode = mapping->host; 1638 struct inode *inode = mapping->host;
1639 1639 struct splice_desc sd = {
1640 ret = __splice_from_pipe(pipe, out, ppos, len, flags, 1640 .total_len = len,
1641 ocfs2_splice_write_actor); 1641 .flags = flags,
1642 .pos = *ppos,
1643 .u.file = out,
1644 };
1645
1646 ret = __splice_from_pipe(pipe, &sd, ocfs2_splice_write_actor);
1642 if (ret > 0) { 1647 if (ret > 0) {
1643 *ppos += ret; 1648 *ppos += ret;
1644 1649
@@ -1817,7 +1822,6 @@ const struct inode_operations ocfs2_special_file_iops = {
1817const struct file_operations ocfs2_fops = { 1822const struct file_operations ocfs2_fops = {
1818 .read = do_sync_read, 1823 .read = do_sync_read,
1819 .write = do_sync_write, 1824 .write = do_sync_write,
1820 .sendfile = generic_file_sendfile,
1821 .mmap = ocfs2_mmap, 1825 .mmap = ocfs2_mmap,
1822 .fsync = ocfs2_sync_file, 1826 .fsync = ocfs2_sync_file,
1823 .release = ocfs2_file_release, 1827 .release = ocfs2_file_release,
diff --git a/fs/partitions/ibm.c b/fs/partitions/ibm.c
index 9f7ad4244f63..1e064c4a4f86 100644
--- a/fs/partitions/ibm.c
+++ b/fs/partitions/ibm.c
@@ -45,7 +45,7 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev)
45{ 45{
46 int blocksize, offset, size,res; 46 int blocksize, offset, size,res;
47 loff_t i_size; 47 loff_t i_size;
48 dasd_information_t *info; 48 dasd_information2_t *info;
49 struct hd_geometry *geo; 49 struct hd_geometry *geo;
50 char type[5] = {0,}; 50 char type[5] = {0,};
51 char name[7] = {0,}; 51 char name[7] = {0,};
@@ -64,14 +64,17 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev)
64 if (i_size == 0) 64 if (i_size == 0)
65 goto out_exit; 65 goto out_exit;
66 66
67 if ((info = kmalloc(sizeof(dasd_information_t), GFP_KERNEL)) == NULL) 67 info = kmalloc(sizeof(dasd_information2_t), GFP_KERNEL);
68 if (info == NULL)
68 goto out_exit; 69 goto out_exit;
69 if ((geo = kmalloc(sizeof(struct hd_geometry), GFP_KERNEL)) == NULL) 70 geo = kmalloc(sizeof(struct hd_geometry), GFP_KERNEL);
71 if (geo == NULL)
70 goto out_nogeo; 72 goto out_nogeo;
71 if ((label = kmalloc(sizeof(union label_t), GFP_KERNEL)) == NULL) 73 label = kmalloc(sizeof(union label_t), GFP_KERNEL);
74 if (label == NULL)
72 goto out_nolab; 75 goto out_nolab;
73 76
74 if (ioctl_by_bdev(bdev, BIODASDINFO, (unsigned long)info) != 0 || 77 if (ioctl_by_bdev(bdev, BIODASDINFO2, (unsigned long)info) != 0 ||
75 ioctl_by_bdev(bdev, HDIO_GETGEO, (unsigned long)geo) != 0) 78 ioctl_by_bdev(bdev, HDIO_GETGEO, (unsigned long)geo) != 0)
76 goto out_freeall; 79 goto out_freeall;
77 80
@@ -96,84 +99,108 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev)
96 res = 1; 99 res = 1;
97 100
98 /* 101 /*
99 * Three different types: CMS1, VOL1 and LNX1/unlabeled 102 * Three different formats: LDL, CDL and unformated disk
103 *
104 * identified by info->format
105 *
106 * unformated disks we do not have to care about
100 */ 107 */
101 if (strncmp(type, "CMS1", 4) == 0) { 108 if (info->format == DASD_FORMAT_LDL) {
102 /* 109 if (strncmp(type, "CMS1", 4) == 0) {
103 * VM style CMS1 labeled disk 110 /*
104 */ 111 * VM style CMS1 labeled disk
105 if (label->cms.disk_offset != 0) { 112 */
106 printk("CMS1/%8s(MDSK):", name); 113 if (label->cms.disk_offset != 0) {
107 /* disk is reserved minidisk */ 114 printk("CMS1/%8s(MDSK):", name);
108 blocksize = label->cms.block_size; 115 /* disk is reserved minidisk */
109 offset = label->cms.disk_offset; 116 blocksize = label->cms.block_size;
110 size = (label->cms.block_count - 1) * (blocksize >> 9); 117 offset = label->cms.disk_offset;
118 size = (label->cms.block_count - 1)
119 * (blocksize >> 9);
120 } else {
121 printk("CMS1/%8s:", name);
122 offset = (info->label_block + 1);
123 size = i_size >> 9;
124 }
111 } else { 125 } else {
112 printk("CMS1/%8s:", name); 126 /*
127 * Old style LNX1 or unlabeled disk
128 */
129 if (strncmp(type, "LNX1", 4) == 0)
130 printk ("LNX1/%8s:", name);
131 else
132 printk("(nonl)");
113 offset = (info->label_block + 1); 133 offset = (info->label_block + 1);
114 size = i_size >> 9; 134 size = i_size >> 9;
115 } 135 }
116 put_partition(state, 1, offset*(blocksize >> 9), 136 put_partition(state, 1, offset*(blocksize >> 9),
117 size-offset*(blocksize >> 9)); 137 size-offset*(blocksize >> 9));
118 } else if ((strncmp(type, "VOL1", 4) == 0) && 138 } else if (info->format == DASD_FORMAT_CDL) {
119 (!info->FBA_layout) && (!strcmp(info->type, "ECKD"))) {
120 /* 139 /*
121 * New style VOL1 labeled disk 140 * New style CDL formatted disk
122 */ 141 */
123 unsigned int blk; 142 unsigned int blk;
124 int counter; 143 int counter;
125 144
126 printk("VOL1/%8s:", name);
127
128 /* get block number and read then go through format1 labels */
129 blk = cchhb2blk(&label->vol.vtoc, geo) + 1;
130 counter = 0;
131 while ((data = read_dev_sector(bdev, blk*(blocksize/512),
132 &sect)) != NULL) {
133 struct vtoc_format1_label f1;
134
135 memcpy(&f1, data, sizeof(struct vtoc_format1_label));
136 put_dev_sector(sect);
137
138 /* skip FMT4 / FMT5 / FMT7 labels */
139 if (f1.DS1FMTID == _ascebc['4']
140 || f1.DS1FMTID == _ascebc['5']
141 || f1.DS1FMTID == _ascebc['7']) {
142 blk++;
143 continue;
144 }
145
146 /* only FMT1 valid at this point */
147 if (f1.DS1FMTID != _ascebc['1'])
148 break;
149
150 /* OK, we got valid partition data */
151 offset = cchh2blk(&f1.DS1EXT1.llimit, geo);
152 size = cchh2blk(&f1.DS1EXT1.ulimit, geo) -
153 offset + geo->sectors;
154 if (counter >= state->limit)
155 break;
156 put_partition(state, counter + 1,
157 offset * (blocksize >> 9),
158 size * (blocksize >> 9));
159 counter++;
160 blk++;
161 }
162 if (!data)
163 /* Are we not supposed to report this ? */
164 goto out_readerr;
165 } else {
166 /* 145 /*
167 * Old style LNX1 or unlabeled disk 146 * check if VOL1 label is available
147 * if not, something is wrong, skipping partition detection
168 */ 148 */
169 if (strncmp(type, "LNX1", 4) == 0) 149 if (strncmp(type, "VOL1", 4) == 0) {
170 printk ("LNX1/%8s:", name); 150 printk("VOL1/%8s:", name);
171 else 151 /*
172 printk("(nonl)/%8s:", name); 152 * get block number and read then go through format1
173 offset = (info->label_block + 1); 153 * labels
174 size = i_size >> 9; 154 */
175 put_partition(state, 1, offset*(blocksize >> 9), 155 blk = cchhb2blk(&label->vol.vtoc, geo) + 1;
176 size-offset*(blocksize >> 9)); 156 counter = 0;
157 data = read_dev_sector(bdev, blk * (blocksize/512),
158 &sect);
159 while (data != NULL) {
160 struct vtoc_format1_label f1;
161
162 memcpy(&f1, data,
163 sizeof(struct vtoc_format1_label));
164 put_dev_sector(sect);
165
166 /* skip FMT4 / FMT5 / FMT7 labels */
167 if (f1.DS1FMTID == _ascebc['4']
168 || f1.DS1FMTID == _ascebc['5']
169 || f1.DS1FMTID == _ascebc['7']) {
170 blk++;
171 data = read_dev_sector(bdev, blk *
172 (blocksize/512),
173 &sect);
174 continue;
175 }
176
177 /* only FMT1 valid at this point */
178 if (f1.DS1FMTID != _ascebc['1'])
179 break;
180
181 /* OK, we got valid partition data */
182 offset = cchh2blk(&f1.DS1EXT1.llimit, geo);
183 size = cchh2blk(&f1.DS1EXT1.ulimit, geo) -
184 offset + geo->sectors;
185 if (counter >= state->limit)
186 break;
187 put_partition(state, counter + 1,
188 offset * (blocksize >> 9),
189 size * (blocksize >> 9));
190 counter++;
191 blk++;
192 data = read_dev_sector(bdev,
193 blk * (blocksize/512),
194 &sect);
195 }
196
197 if (!data)
198 /* Are we not supposed to report this ? */
199 goto out_readerr;
200 } else
201 printk(KERN_WARNING "Warning, expected Label VOL1 not "
202 "found, treating as CDL formated Disk");
203
177 } 204 }
178 205
179 printk("\n"); 206 printk("\n");
diff --git a/fs/pipe.c b/fs/pipe.c
index 3a89592bdf57..d007830d9c87 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -164,6 +164,20 @@ static void anon_pipe_buf_release(struct pipe_inode_info *pipe,
164 page_cache_release(page); 164 page_cache_release(page);
165} 165}
166 166
167/**
168 * generic_pipe_buf_map - virtually map a pipe buffer
169 * @pipe: the pipe that the buffer belongs to
170 * @buf: the buffer that should be mapped
171 * @atomic: whether to use an atomic map
172 *
173 * Description:
174 * This function returns a kernel virtual address mapping for the
175 * passed in @pipe_buffer. If @atomic is set, an atomic map is provided
176 * and the caller has to be careful not to fault before calling
177 * the unmap function.
178 *
179 * Note that this function occupies KM_USER0 if @atomic != 0.
180 */
167void *generic_pipe_buf_map(struct pipe_inode_info *pipe, 181void *generic_pipe_buf_map(struct pipe_inode_info *pipe,
168 struct pipe_buffer *buf, int atomic) 182 struct pipe_buffer *buf, int atomic)
169{ 183{
@@ -175,6 +189,15 @@ void *generic_pipe_buf_map(struct pipe_inode_info *pipe,
175 return kmap(buf->page); 189 return kmap(buf->page);
176} 190}
177 191
192/**
193 * generic_pipe_buf_unmap - unmap a previously mapped pipe buffer
194 * @pipe: the pipe that the buffer belongs to
195 * @buf: the buffer that should be unmapped
196 * @map_data: the data that the mapping function returned
197 *
198 * Description:
199 * This function undoes the mapping that ->map() provided.
200 */
178void generic_pipe_buf_unmap(struct pipe_inode_info *pipe, 201void generic_pipe_buf_unmap(struct pipe_inode_info *pipe,
179 struct pipe_buffer *buf, void *map_data) 202 struct pipe_buffer *buf, void *map_data)
180{ 203{
@@ -185,11 +208,28 @@ void generic_pipe_buf_unmap(struct pipe_inode_info *pipe,
185 kunmap(buf->page); 208 kunmap(buf->page);
186} 209}
187 210
211/**
212 * generic_pipe_buf_steal - attempt to take ownership of a @pipe_buffer
213 * @pipe: the pipe that the buffer belongs to
214 * @buf: the buffer to attempt to steal
215 *
216 * Description:
217 * This function attempts to steal the @struct page attached to
218 * @buf. If successful, this function returns 0 and returns with
219 * the page locked. The caller may then reuse the page for whatever
220 * he wishes, the typical use is insertion into a different file
221 * page cache.
222 */
188int generic_pipe_buf_steal(struct pipe_inode_info *pipe, 223int generic_pipe_buf_steal(struct pipe_inode_info *pipe,
189 struct pipe_buffer *buf) 224 struct pipe_buffer *buf)
190{ 225{
191 struct page *page = buf->page; 226 struct page *page = buf->page;
192 227
228 /*
229 * A reference of one is golden, that means that the owner of this
230 * page is the only one holding a reference to it. lock the page
231 * and return OK.
232 */
193 if (page_count(page) == 1) { 233 if (page_count(page) == 1) {
194 lock_page(page); 234 lock_page(page);
195 return 0; 235 return 0;
@@ -198,12 +238,32 @@ int generic_pipe_buf_steal(struct pipe_inode_info *pipe,
198 return 1; 238 return 1;
199} 239}
200 240
201void generic_pipe_buf_get(struct pipe_inode_info *info, struct pipe_buffer *buf) 241/**
242 * generic_pipe_buf_get - get a reference to a @struct pipe_buffer
243 * @pipe: the pipe that the buffer belongs to
244 * @buf: the buffer to get a reference to
245 *
246 * Description:
247 * This function grabs an extra reference to @buf. It's used in
248 * in the tee() system call, when we duplicate the buffers in one
249 * pipe into another.
250 */
251void generic_pipe_buf_get(struct pipe_inode_info *pipe, struct pipe_buffer *buf)
202{ 252{
203 page_cache_get(buf->page); 253 page_cache_get(buf->page);
204} 254}
205 255
206int generic_pipe_buf_pin(struct pipe_inode_info *info, struct pipe_buffer *buf) 256/**
257 * generic_pipe_buf_confirm - verify contents of the pipe buffer
258 * @pipe: the pipe that the buffer belongs to
259 * @buf: the buffer to confirm
260 *
261 * Description:
262 * This function does nothing, because the generic pipe code uses
263 * pages that are always good when inserted into the pipe.
264 */
265int generic_pipe_buf_confirm(struct pipe_inode_info *info,
266 struct pipe_buffer *buf)
207{ 267{
208 return 0; 268 return 0;
209} 269}
@@ -212,7 +272,7 @@ static const struct pipe_buf_operations anon_pipe_buf_ops = {
212 .can_merge = 1, 272 .can_merge = 1,
213 .map = generic_pipe_buf_map, 273 .map = generic_pipe_buf_map,
214 .unmap = generic_pipe_buf_unmap, 274 .unmap = generic_pipe_buf_unmap,
215 .pin = generic_pipe_buf_pin, 275 .confirm = generic_pipe_buf_confirm,
216 .release = anon_pipe_buf_release, 276 .release = anon_pipe_buf_release,
217 .steal = generic_pipe_buf_steal, 277 .steal = generic_pipe_buf_steal,
218 .get = generic_pipe_buf_get, 278 .get = generic_pipe_buf_get,
@@ -252,7 +312,7 @@ pipe_read(struct kiocb *iocb, const struct iovec *_iov,
252 if (chars > total_len) 312 if (chars > total_len)
253 chars = total_len; 313 chars = total_len;
254 314
255 error = ops->pin(pipe, buf); 315 error = ops->confirm(pipe, buf);
256 if (error) { 316 if (error) {
257 if (!ret) 317 if (!ret)
258 error = ret; 318 error = ret;
@@ -373,7 +433,7 @@ pipe_write(struct kiocb *iocb, const struct iovec *_iov,
373 int error, atomic = 1; 433 int error, atomic = 1;
374 void *addr; 434 void *addr;
375 435
376 error = ops->pin(pipe, buf); 436 error = ops->confirm(pipe, buf);
377 if (error) 437 if (error)
378 goto out; 438 goto out;
379 439
diff --git a/fs/proc/array.c b/fs/proc/array.c
index 74f30e0c0381..98e78e2f18d6 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -165,7 +165,6 @@ static inline char * task_state(struct task_struct *p, char *buffer)
165 rcu_read_lock(); 165 rcu_read_lock();
166 buffer += sprintf(buffer, 166 buffer += sprintf(buffer,
167 "State:\t%s\n" 167 "State:\t%s\n"
168 "SleepAVG:\t%lu%%\n"
169 "Tgid:\t%d\n" 168 "Tgid:\t%d\n"
170 "Pid:\t%d\n" 169 "Pid:\t%d\n"
171 "PPid:\t%d\n" 170 "PPid:\t%d\n"
@@ -173,7 +172,6 @@ static inline char * task_state(struct task_struct *p, char *buffer)
173 "Uid:\t%d\t%d\t%d\t%d\n" 172 "Uid:\t%d\t%d\t%d\t%d\n"
174 "Gid:\t%d\t%d\t%d\t%d\n", 173 "Gid:\t%d\t%d\t%d\t%d\n",
175 get_task_state(p), 174 get_task_state(p),
176 (p->sleep_avg/1024)*100/(1020000000/1024),
177 p->tgid, p->pid, 175 p->tgid, p->pid,
178 pid_alive(p) ? rcu_dereference(p->real_parent)->tgid : 0, 176 pid_alive(p) ? rcu_dereference(p->real_parent)->tgid : 0,
179 pid_alive(p) && p->ptrace ? rcu_dereference(p->parent)->pid : 0, 177 pid_alive(p) && p->ptrace ? rcu_dereference(p->parent)->pid : 0,
@@ -312,6 +310,41 @@ int proc_pid_status(struct task_struct *task, char * buffer)
312 return buffer - orig; 310 return buffer - orig;
313} 311}
314 312
313static clock_t task_utime(struct task_struct *p)
314{
315 clock_t utime = cputime_to_clock_t(p->utime),
316 total = utime + cputime_to_clock_t(p->stime);
317 u64 temp;
318
319 /*
320 * Use CFS's precise accounting:
321 */
322 temp = (u64)nsec_to_clock_t(p->se.sum_exec_runtime);
323
324 if (total) {
325 temp *= utime;
326 do_div(temp, total);
327 }
328 utime = (clock_t)temp;
329
330 return utime;
331}
332
333static clock_t task_stime(struct task_struct *p)
334{
335 clock_t stime = cputime_to_clock_t(p->stime);
336
337 /*
338 * Use CFS's precise accounting. (we subtract utime from
339 * the total, to make sure the total observed by userspace
340 * grows monotonically - apps rely on that):
341 */
342 stime = nsec_to_clock_t(p->se.sum_exec_runtime) - task_utime(p);
343
344 return stime;
345}
346
347
315static int do_task_stat(struct task_struct *task, char * buffer, int whole) 348static int do_task_stat(struct task_struct *task, char * buffer, int whole)
316{ 349{
317 unsigned long vsize, eip, esp, wchan = ~0UL; 350 unsigned long vsize, eip, esp, wchan = ~0UL;
@@ -326,7 +359,8 @@ static int do_task_stat(struct task_struct *task, char * buffer, int whole)
326 unsigned long long start_time; 359 unsigned long long start_time;
327 unsigned long cmin_flt = 0, cmaj_flt = 0; 360 unsigned long cmin_flt = 0, cmaj_flt = 0;
328 unsigned long min_flt = 0, maj_flt = 0; 361 unsigned long min_flt = 0, maj_flt = 0;
329 cputime_t cutime, cstime, utime, stime; 362 cputime_t cutime, cstime;
363 clock_t utime, stime;
330 unsigned long rsslim = 0; 364 unsigned long rsslim = 0;
331 char tcomm[sizeof(task->comm)]; 365 char tcomm[sizeof(task->comm)];
332 unsigned long flags; 366 unsigned long flags;
@@ -344,7 +378,8 @@ static int do_task_stat(struct task_struct *task, char * buffer, int whole)
344 378
345 sigemptyset(&sigign); 379 sigemptyset(&sigign);
346 sigemptyset(&sigcatch); 380 sigemptyset(&sigcatch);
347 cutime = cstime = utime = stime = cputime_zero; 381 cutime = cstime = cputime_zero;
382 utime = stime = 0;
348 383
349 rcu_read_lock(); 384 rcu_read_lock();
350 if (lock_task_sighand(task, &flags)) { 385 if (lock_task_sighand(task, &flags)) {
@@ -370,15 +405,15 @@ static int do_task_stat(struct task_struct *task, char * buffer, int whole)
370 do { 405 do {
371 min_flt += t->min_flt; 406 min_flt += t->min_flt;
372 maj_flt += t->maj_flt; 407 maj_flt += t->maj_flt;
373 utime = cputime_add(utime, t->utime); 408 utime += task_utime(t);
374 stime = cputime_add(stime, t->stime); 409 stime += task_stime(t);
375 t = next_thread(t); 410 t = next_thread(t);
376 } while (t != task); 411 } while (t != task);
377 412
378 min_flt += sig->min_flt; 413 min_flt += sig->min_flt;
379 maj_flt += sig->maj_flt; 414 maj_flt += sig->maj_flt;
380 utime = cputime_add(utime, sig->utime); 415 utime += cputime_to_clock_t(sig->utime);
381 stime = cputime_add(stime, sig->stime); 416 stime += cputime_to_clock_t(sig->stime);
382 } 417 }
383 418
384 sid = signal_session(sig); 419 sid = signal_session(sig);
@@ -394,8 +429,8 @@ static int do_task_stat(struct task_struct *task, char * buffer, int whole)
394 if (!whole) { 429 if (!whole) {
395 min_flt = task->min_flt; 430 min_flt = task->min_flt;
396 maj_flt = task->maj_flt; 431 maj_flt = task->maj_flt;
397 utime = task->utime; 432 utime = task_utime(task);
398 stime = task->stime; 433 stime = task_stime(task);
399 } 434 }
400 435
401 /* scale priority and nice values from timeslices to -20..20 */ 436 /* scale priority and nice values from timeslices to -20..20 */
@@ -426,8 +461,8 @@ static int do_task_stat(struct task_struct *task, char * buffer, int whole)
426 cmin_flt, 461 cmin_flt,
427 maj_flt, 462 maj_flt,
428 cmaj_flt, 463 cmaj_flt,
429 cputime_to_clock_t(utime), 464 utime,
430 cputime_to_clock_t(stime), 465 stime,
431 cputime_to_clock_t(cutime), 466 cputime_to_clock_t(cutime),
432 cputime_to_clock_t(cstime), 467 cputime_to_clock_t(cstime),
433 priority, 468 priority,
diff --git a/fs/proc/base.c b/fs/proc/base.c
index a5fa1fdafc4e..46ea5d56e1bb 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -296,7 +296,7 @@ static int proc_pid_wchan(struct task_struct *task, char *buffer)
296 */ 296 */
297static int proc_pid_schedstat(struct task_struct *task, char *buffer) 297static int proc_pid_schedstat(struct task_struct *task, char *buffer)
298{ 298{
299 return sprintf(buffer, "%lu %lu %lu\n", 299 return sprintf(buffer, "%llu %llu %lu\n",
300 task->sched_info.cpu_time, 300 task->sched_info.cpu_time,
301 task->sched_info.run_delay, 301 task->sched_info.run_delay,
302 task->sched_info.pcnt); 302 task->sched_info.pcnt);
@@ -929,6 +929,69 @@ static const struct file_operations proc_fault_inject_operations = {
929}; 929};
930#endif 930#endif
931 931
932#ifdef CONFIG_SCHED_DEBUG
933/*
934 * Print out various scheduling related per-task fields:
935 */
936static int sched_show(struct seq_file *m, void *v)
937{
938 struct inode *inode = m->private;
939 struct task_struct *p;
940
941 WARN_ON(!inode);
942
943 p = get_proc_task(inode);
944 if (!p)
945 return -ESRCH;
946 proc_sched_show_task(p, m);
947
948 put_task_struct(p);
949
950 return 0;
951}
952
953static ssize_t
954sched_write(struct file *file, const char __user *buf,
955 size_t count, loff_t *offset)
956{
957 struct inode *inode = file->f_path.dentry->d_inode;
958 struct task_struct *p;
959
960 WARN_ON(!inode);
961
962 p = get_proc_task(inode);
963 if (!p)
964 return -ESRCH;
965 proc_sched_set_task(p);
966
967 put_task_struct(p);
968
969 return count;
970}
971
972static int sched_open(struct inode *inode, struct file *filp)
973{
974 int ret;
975
976 ret = single_open(filp, sched_show, NULL);
977 if (!ret) {
978 struct seq_file *m = filp->private_data;
979
980 m->private = inode;
981 }
982 return ret;
983}
984
985static const struct file_operations proc_pid_sched_operations = {
986 .open = sched_open,
987 .read = seq_read,
988 .write = sched_write,
989 .llseek = seq_lseek,
990 .release = seq_release,
991};
992
993#endif
994
932static void *proc_pid_follow_link(struct dentry *dentry, struct nameidata *nd) 995static void *proc_pid_follow_link(struct dentry *dentry, struct nameidata *nd)
933{ 996{
934 struct inode *inode = dentry->d_inode; 997 struct inode *inode = dentry->d_inode;
@@ -1963,6 +2026,9 @@ static const struct pid_entry tgid_base_stuff[] = {
1963 INF("environ", S_IRUSR, pid_environ), 2026 INF("environ", S_IRUSR, pid_environ),
1964 INF("auxv", S_IRUSR, pid_auxv), 2027 INF("auxv", S_IRUSR, pid_auxv),
1965 INF("status", S_IRUGO, pid_status), 2028 INF("status", S_IRUGO, pid_status),
2029#ifdef CONFIG_SCHED_DEBUG
2030 REG("sched", S_IRUGO|S_IWUSR, pid_sched),
2031#endif
1966 INF("cmdline", S_IRUGO, pid_cmdline), 2032 INF("cmdline", S_IRUGO, pid_cmdline),
1967 INF("stat", S_IRUGO, tgid_stat), 2033 INF("stat", S_IRUGO, tgid_stat),
1968 INF("statm", S_IRUGO, pid_statm), 2034 INF("statm", S_IRUGO, pid_statm),
@@ -2247,6 +2313,9 @@ static const struct pid_entry tid_base_stuff[] = {
2247 INF("environ", S_IRUSR, pid_environ), 2313 INF("environ", S_IRUSR, pid_environ),
2248 INF("auxv", S_IRUSR, pid_auxv), 2314 INF("auxv", S_IRUSR, pid_auxv),
2249 INF("status", S_IRUGO, pid_status), 2315 INF("status", S_IRUGO, pid_status),
2316#ifdef CONFIG_SCHED_DEBUG
2317 REG("sched", S_IRUGO|S_IWUSR, pid_sched),
2318#endif
2250 INF("cmdline", S_IRUGO, pid_cmdline), 2319 INF("cmdline", S_IRUGO, pid_cmdline),
2251 INF("stat", S_IRUGO, tid_stat), 2320 INF("stat", S_IRUGO, tid_stat),
2252 INF("statm", S_IRUGO, pid_statm), 2321 INF("statm", S_IRUGO, pid_statm),
diff --git a/fs/qnx4/file.c b/fs/qnx4/file.c
index 44649981bbc8..867f42b02035 100644
--- a/fs/qnx4/file.c
+++ b/fs/qnx4/file.c
@@ -25,7 +25,7 @@ const struct file_operations qnx4_file_operations =
25 .read = do_sync_read, 25 .read = do_sync_read,
26 .aio_read = generic_file_aio_read, 26 .aio_read = generic_file_aio_read,
27 .mmap = generic_file_mmap, 27 .mmap = generic_file_mmap,
28 .sendfile = generic_file_sendfile, 28 .splice_read = generic_file_splice_read,
29#ifdef CONFIG_QNX4FS_RW 29#ifdef CONFIG_QNX4FS_RW
30 .write = do_sync_write, 30 .write = do_sync_write,
31 .aio_write = generic_file_aio_write, 31 .aio_write = generic_file_aio_write,
diff --git a/fs/ramfs/file-mmu.c b/fs/ramfs/file-mmu.c
index 2f14774a124f..97bdc0b2f9d2 100644
--- a/fs/ramfs/file-mmu.c
+++ b/fs/ramfs/file-mmu.c
@@ -41,7 +41,7 @@ const struct file_operations ramfs_file_operations = {
41 .aio_write = generic_file_aio_write, 41 .aio_write = generic_file_aio_write,
42 .mmap = generic_file_mmap, 42 .mmap = generic_file_mmap,
43 .fsync = simple_sync_file, 43 .fsync = simple_sync_file,
44 .sendfile = generic_file_sendfile, 44 .splice_read = generic_file_splice_read,
45 .llseek = generic_file_llseek, 45 .llseek = generic_file_llseek,
46}; 46};
47 47
diff --git a/fs/ramfs/file-nommu.c b/fs/ramfs/file-nommu.c
index 5d258c40a2fd..cad2b7ace630 100644
--- a/fs/ramfs/file-nommu.c
+++ b/fs/ramfs/file-nommu.c
@@ -42,7 +42,7 @@ const struct file_operations ramfs_file_operations = {
42 .write = do_sync_write, 42 .write = do_sync_write,
43 .aio_write = generic_file_aio_write, 43 .aio_write = generic_file_aio_write,
44 .fsync = simple_sync_file, 44 .fsync = simple_sync_file,
45 .sendfile = generic_file_sendfile, 45 .splice_read = generic_file_splice_read,
46 .llseek = generic_file_llseek, 46 .llseek = generic_file_llseek,
47}; 47};
48 48
diff --git a/fs/read_write.c b/fs/read_write.c
index 4d03008f015b..507ddff48a9a 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -15,6 +15,7 @@
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/syscalls.h> 16#include <linux/syscalls.h>
17#include <linux/pagemap.h> 17#include <linux/pagemap.h>
18#include <linux/splice.h>
18#include "read_write.h" 19#include "read_write.h"
19 20
20#include <asm/uaccess.h> 21#include <asm/uaccess.h>
@@ -25,7 +26,7 @@ const struct file_operations generic_ro_fops = {
25 .read = do_sync_read, 26 .read = do_sync_read,
26 .aio_read = generic_file_aio_read, 27 .aio_read = generic_file_aio_read,
27 .mmap = generic_file_readonly_mmap, 28 .mmap = generic_file_readonly_mmap,
28 .sendfile = generic_file_sendfile, 29 .splice_read = generic_file_splice_read,
29}; 30};
30 31
31EXPORT_SYMBOL(generic_ro_fops); 32EXPORT_SYMBOL(generic_ro_fops);
@@ -708,7 +709,7 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
708 struct inode * in_inode, * out_inode; 709 struct inode * in_inode, * out_inode;
709 loff_t pos; 710 loff_t pos;
710 ssize_t retval; 711 ssize_t retval;
711 int fput_needed_in, fput_needed_out; 712 int fput_needed_in, fput_needed_out, fl;
712 713
713 /* 714 /*
714 * Get input file, and verify that it is ok.. 715 * Get input file, and verify that it is ok..
@@ -723,7 +724,7 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
723 in_inode = in_file->f_path.dentry->d_inode; 724 in_inode = in_file->f_path.dentry->d_inode;
724 if (!in_inode) 725 if (!in_inode)
725 goto fput_in; 726 goto fput_in;
726 if (!in_file->f_op || !in_file->f_op->sendfile) 727 if (!in_file->f_op || !in_file->f_op->splice_read)
727 goto fput_in; 728 goto fput_in;
728 retval = -ESPIPE; 729 retval = -ESPIPE;
729 if (!ppos) 730 if (!ppos)
@@ -776,7 +777,18 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
776 count = max - pos; 777 count = max - pos;
777 } 778 }
778 779
779 retval = in_file->f_op->sendfile(in_file, ppos, count, file_send_actor, out_file); 780 fl = 0;
781#if 0
782 /*
783 * We need to debate whether we can enable this or not. The
784 * man page documents EAGAIN return for the output at least,
785 * and the application is arguably buggy if it doesn't expect
786 * EAGAIN on a non-blocking file descriptor.
787 */
788 if (in_file->f_flags & O_NONBLOCK)
789 fl = SPLICE_F_NONBLOCK;
790#endif
791 retval = do_splice_direct(in_file, ppos, out_file, count, fl);
780 792
781 if (retval > 0) { 793 if (retval > 0) {
782 add_rchar(current, retval); 794 add_rchar(current, retval);
diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c
index 9e451a68580f..30eebfb1b2d8 100644
--- a/fs/reiserfs/file.c
+++ b/fs/reiserfs/file.c
@@ -1531,7 +1531,6 @@ const struct file_operations reiserfs_file_operations = {
1531 .open = generic_file_open, 1531 .open = generic_file_open,
1532 .release = reiserfs_file_release, 1532 .release = reiserfs_file_release,
1533 .fsync = reiserfs_sync_file, 1533 .fsync = reiserfs_sync_file,
1534 .sendfile = generic_file_sendfile,
1535 .aio_read = generic_file_aio_read, 1534 .aio_read = generic_file_aio_read,
1536 .aio_write = generic_file_aio_write, 1535 .aio_write = generic_file_aio_write,
1537 .splice_read = generic_file_splice_read, 1536 .splice_read = generic_file_splice_read,
diff --git a/fs/smbfs/file.c b/fs/smbfs/file.c
index aea3f8aa54c0..c5d78a7e492b 100644
--- a/fs/smbfs/file.c
+++ b/fs/smbfs/file.c
@@ -262,8 +262,9 @@ out:
262} 262}
263 263
264static ssize_t 264static ssize_t
265smb_file_sendfile(struct file *file, loff_t *ppos, 265smb_file_splice_read(struct file *file, loff_t *ppos,
266 size_t count, read_actor_t actor, void *target) 266 struct pipe_inode_info *pipe, size_t count,
267 unsigned int flags)
267{ 268{
268 struct dentry *dentry = file->f_path.dentry; 269 struct dentry *dentry = file->f_path.dentry;
269 ssize_t status; 270 ssize_t status;
@@ -277,7 +278,7 @@ smb_file_sendfile(struct file *file, loff_t *ppos,
277 DENTRY_PATH(dentry), status); 278 DENTRY_PATH(dentry), status);
278 goto out; 279 goto out;
279 } 280 }
280 status = generic_file_sendfile(file, ppos, count, actor, target); 281 status = generic_file_splice_read(file, ppos, pipe, count, flags);
281out: 282out:
282 return status; 283 return status;
283} 284}
@@ -416,7 +417,7 @@ const struct file_operations smb_file_operations =
416 .open = smb_file_open, 417 .open = smb_file_open,
417 .release = smb_file_release, 418 .release = smb_file_release,
418 .fsync = smb_fsync, 419 .fsync = smb_fsync,
419 .sendfile = smb_file_sendfile, 420 .splice_read = smb_file_splice_read,
420}; 421};
421 422
422const struct inode_operations smb_file_inode_operations = 423const struct inode_operations smb_file_inode_operations =
diff --git a/fs/splice.c b/fs/splice.c
index e7d7080de2f9..ed2ce995475c 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -20,7 +20,7 @@
20#include <linux/fs.h> 20#include <linux/fs.h>
21#include <linux/file.h> 21#include <linux/file.h>
22#include <linux/pagemap.h> 22#include <linux/pagemap.h>
23#include <linux/pipe_fs_i.h> 23#include <linux/splice.h>
24#include <linux/mm_inline.h> 24#include <linux/mm_inline.h>
25#include <linux/swap.h> 25#include <linux/swap.h>
26#include <linux/writeback.h> 26#include <linux/writeback.h>
@@ -29,22 +29,6 @@
29#include <linux/syscalls.h> 29#include <linux/syscalls.h>
30#include <linux/uio.h> 30#include <linux/uio.h>
31 31
32struct partial_page {
33 unsigned int offset;
34 unsigned int len;
35};
36
37/*
38 * Passed to splice_to_pipe
39 */
40struct splice_pipe_desc {
41 struct page **pages; /* page map */
42 struct partial_page *partial; /* pages[] may not be contig */
43 int nr_pages; /* number of pages in map */
44 unsigned int flags; /* splice flags */
45 const struct pipe_buf_operations *ops;/* ops associated with output pipe */
46};
47
48/* 32/*
49 * Attempt to steal a page from a pipe buffer. This should perhaps go into 33 * Attempt to steal a page from a pipe buffer. This should perhaps go into
50 * a vm helper function, it's already simplified quite a bit by the 34 * a vm helper function, it's already simplified quite a bit by the
@@ -101,8 +85,12 @@ static void page_cache_pipe_buf_release(struct pipe_inode_info *pipe,
101 buf->flags &= ~PIPE_BUF_FLAG_LRU; 85 buf->flags &= ~PIPE_BUF_FLAG_LRU;
102} 86}
103 87
104static int page_cache_pipe_buf_pin(struct pipe_inode_info *pipe, 88/*
105 struct pipe_buffer *buf) 89 * Check whether the contents of buf is OK to access. Since the content
90 * is a page cache page, IO may be in flight.
91 */
92static int page_cache_pipe_buf_confirm(struct pipe_inode_info *pipe,
93 struct pipe_buffer *buf)
106{ 94{
107 struct page *page = buf->page; 95 struct page *page = buf->page;
108 int err; 96 int err;
@@ -143,7 +131,7 @@ static const struct pipe_buf_operations page_cache_pipe_buf_ops = {
143 .can_merge = 0, 131 .can_merge = 0,
144 .map = generic_pipe_buf_map, 132 .map = generic_pipe_buf_map,
145 .unmap = generic_pipe_buf_unmap, 133 .unmap = generic_pipe_buf_unmap,
146 .pin = page_cache_pipe_buf_pin, 134 .confirm = page_cache_pipe_buf_confirm,
147 .release = page_cache_pipe_buf_release, 135 .release = page_cache_pipe_buf_release,
148 .steal = page_cache_pipe_buf_steal, 136 .steal = page_cache_pipe_buf_steal,
149 .get = generic_pipe_buf_get, 137 .get = generic_pipe_buf_get,
@@ -163,18 +151,25 @@ static const struct pipe_buf_operations user_page_pipe_buf_ops = {
163 .can_merge = 0, 151 .can_merge = 0,
164 .map = generic_pipe_buf_map, 152 .map = generic_pipe_buf_map,
165 .unmap = generic_pipe_buf_unmap, 153 .unmap = generic_pipe_buf_unmap,
166 .pin = generic_pipe_buf_pin, 154 .confirm = generic_pipe_buf_confirm,
167 .release = page_cache_pipe_buf_release, 155 .release = page_cache_pipe_buf_release,
168 .steal = user_page_pipe_buf_steal, 156 .steal = user_page_pipe_buf_steal,
169 .get = generic_pipe_buf_get, 157 .get = generic_pipe_buf_get,
170}; 158};
171 159
172/* 160/**
173 * Pipe output worker. This sets up our pipe format with the page cache 161 * splice_to_pipe - fill passed data into a pipe
174 * pipe buffer operations. Otherwise very similar to the regular pipe_writev(). 162 * @pipe: pipe to fill
163 * @spd: data to fill
164 *
165 * Description:
166 * @spd contains a map of pages and len/offset tupples, a long with
167 * the struct pipe_buf_operations associated with these pages. This
168 * function will link that data to the pipe.
169 *
175 */ 170 */
176static ssize_t splice_to_pipe(struct pipe_inode_info *pipe, 171ssize_t splice_to_pipe(struct pipe_inode_info *pipe,
177 struct splice_pipe_desc *spd) 172 struct splice_pipe_desc *spd)
178{ 173{
179 unsigned int spd_pages = spd->nr_pages; 174 unsigned int spd_pages = spd->nr_pages;
180 int ret, do_wakeup, page_nr; 175 int ret, do_wakeup, page_nr;
@@ -201,6 +196,7 @@ static ssize_t splice_to_pipe(struct pipe_inode_info *pipe,
201 buf->page = spd->pages[page_nr]; 196 buf->page = spd->pages[page_nr];
202 buf->offset = spd->partial[page_nr].offset; 197 buf->offset = spd->partial[page_nr].offset;
203 buf->len = spd->partial[page_nr].len; 198 buf->len = spd->partial[page_nr].len;
199 buf->private = spd->partial[page_nr].private;
204 buf->ops = spd->ops; 200 buf->ops = spd->ops;
205 if (spd->flags & SPLICE_F_GIFT) 201 if (spd->flags & SPLICE_F_GIFT)
206 buf->flags |= PIPE_BUF_FLAG_GIFT; 202 buf->flags |= PIPE_BUF_FLAG_GIFT;
@@ -296,19 +292,15 @@ __generic_file_splice_read(struct file *in, loff_t *ppos,
296 page_cache_readahead(mapping, &in->f_ra, in, index, nr_pages); 292 page_cache_readahead(mapping, &in->f_ra, in, index, nr_pages);
297 293
298 /* 294 /*
299 * Now fill in the holes:
300 */
301 error = 0;
302
303 /*
304 * Lookup the (hopefully) full range of pages we need. 295 * Lookup the (hopefully) full range of pages we need.
305 */ 296 */
306 spd.nr_pages = find_get_pages_contig(mapping, index, nr_pages, pages); 297 spd.nr_pages = find_get_pages_contig(mapping, index, nr_pages, pages);
307 298
308 /* 299 /*
309 * If find_get_pages_contig() returned fewer pages than we needed, 300 * If find_get_pages_contig() returned fewer pages than we needed,
310 * allocate the rest. 301 * allocate the rest and fill in the holes.
311 */ 302 */
303 error = 0;
312 index += spd.nr_pages; 304 index += spd.nr_pages;
313 while (spd.nr_pages < nr_pages) { 305 while (spd.nr_pages < nr_pages) {
314 /* 306 /*
@@ -470,11 +462,16 @@ fill_it:
470/** 462/**
471 * generic_file_splice_read - splice data from file to a pipe 463 * generic_file_splice_read - splice data from file to a pipe
472 * @in: file to splice from 464 * @in: file to splice from
465 * @ppos: position in @in
473 * @pipe: pipe to splice to 466 * @pipe: pipe to splice to
474 * @len: number of bytes to splice 467 * @len: number of bytes to splice
475 * @flags: splice modifier flags 468 * @flags: splice modifier flags
476 * 469 *
477 * Will read pages from given file and fill them into a pipe. 470 * Description:
471 * Will read pages from given file and fill them into a pipe. Can be
472 * used as long as the address_space operations for the source implements
473 * a readpage() hook.
474 *
478 */ 475 */
479ssize_t generic_file_splice_read(struct file *in, loff_t *ppos, 476ssize_t generic_file_splice_read(struct file *in, loff_t *ppos,
480 struct pipe_inode_info *pipe, size_t len, 477 struct pipe_inode_info *pipe, size_t len,
@@ -528,11 +525,11 @@ EXPORT_SYMBOL(generic_file_splice_read);
528static int pipe_to_sendpage(struct pipe_inode_info *pipe, 525static int pipe_to_sendpage(struct pipe_inode_info *pipe,
529 struct pipe_buffer *buf, struct splice_desc *sd) 526 struct pipe_buffer *buf, struct splice_desc *sd)
530{ 527{
531 struct file *file = sd->file; 528 struct file *file = sd->u.file;
532 loff_t pos = sd->pos; 529 loff_t pos = sd->pos;
533 int ret, more; 530 int ret, more;
534 531
535 ret = buf->ops->pin(pipe, buf); 532 ret = buf->ops->confirm(pipe, buf);
536 if (!ret) { 533 if (!ret) {
537 more = (sd->flags & SPLICE_F_MORE) || sd->len < sd->total_len; 534 more = (sd->flags & SPLICE_F_MORE) || sd->len < sd->total_len;
538 535
@@ -566,7 +563,7 @@ static int pipe_to_sendpage(struct pipe_inode_info *pipe,
566static int pipe_to_file(struct pipe_inode_info *pipe, struct pipe_buffer *buf, 563static int pipe_to_file(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
567 struct splice_desc *sd) 564 struct splice_desc *sd)
568{ 565{
569 struct file *file = sd->file; 566 struct file *file = sd->u.file;
570 struct address_space *mapping = file->f_mapping; 567 struct address_space *mapping = file->f_mapping;
571 unsigned int offset, this_len; 568 unsigned int offset, this_len;
572 struct page *page; 569 struct page *page;
@@ -576,7 +573,7 @@ static int pipe_to_file(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
576 /* 573 /*
577 * make sure the data in this buffer is uptodate 574 * make sure the data in this buffer is uptodate
578 */ 575 */
579 ret = buf->ops->pin(pipe, buf); 576 ret = buf->ops->confirm(pipe, buf);
580 if (unlikely(ret)) 577 if (unlikely(ret))
581 return ret; 578 return ret;
582 579
@@ -663,36 +660,37 @@ out_ret:
663 return ret; 660 return ret;
664} 661}
665 662
666/* 663/**
667 * Pipe input worker. Most of this logic works like a regular pipe, the 664 * __splice_from_pipe - splice data from a pipe to given actor
668 * key here is the 'actor' worker passed in that actually moves the data 665 * @pipe: pipe to splice from
669 * to the wanted destination. See pipe_to_file/pipe_to_sendpage above. 666 * @sd: information to @actor
667 * @actor: handler that splices the data
668 *
669 * Description:
670 * This function does little more than loop over the pipe and call
671 * @actor to do the actual moving of a single struct pipe_buffer to
672 * the desired destination. See pipe_to_file, pipe_to_sendpage, or
673 * pipe_to_user.
674 *
670 */ 675 */
671ssize_t __splice_from_pipe(struct pipe_inode_info *pipe, 676ssize_t __splice_from_pipe(struct pipe_inode_info *pipe, struct splice_desc *sd,
672 struct file *out, loff_t *ppos, size_t len, 677 splice_actor *actor)
673 unsigned int flags, splice_actor *actor)
674{ 678{
675 int ret, do_wakeup, err; 679 int ret, do_wakeup, err;
676 struct splice_desc sd;
677 680
678 ret = 0; 681 ret = 0;
679 do_wakeup = 0; 682 do_wakeup = 0;
680 683
681 sd.total_len = len;
682 sd.flags = flags;
683 sd.file = out;
684 sd.pos = *ppos;
685
686 for (;;) { 684 for (;;) {
687 if (pipe->nrbufs) { 685 if (pipe->nrbufs) {
688 struct pipe_buffer *buf = pipe->bufs + pipe->curbuf; 686 struct pipe_buffer *buf = pipe->bufs + pipe->curbuf;
689 const struct pipe_buf_operations *ops = buf->ops; 687 const struct pipe_buf_operations *ops = buf->ops;
690 688
691 sd.len = buf->len; 689 sd->len = buf->len;
692 if (sd.len > sd.total_len) 690 if (sd->len > sd->total_len)
693 sd.len = sd.total_len; 691 sd->len = sd->total_len;
694 692
695 err = actor(pipe, buf, &sd); 693 err = actor(pipe, buf, sd);
696 if (err <= 0) { 694 if (err <= 0) {
697 if (!ret && err != -ENODATA) 695 if (!ret && err != -ENODATA)
698 ret = err; 696 ret = err;
@@ -704,10 +702,10 @@ ssize_t __splice_from_pipe(struct pipe_inode_info *pipe,
704 buf->offset += err; 702 buf->offset += err;
705 buf->len -= err; 703 buf->len -= err;
706 704
707 sd.len -= err; 705 sd->len -= err;
708 sd.pos += err; 706 sd->pos += err;
709 sd.total_len -= err; 707 sd->total_len -= err;
710 if (sd.len) 708 if (sd->len)
711 continue; 709 continue;
712 710
713 if (!buf->len) { 711 if (!buf->len) {
@@ -719,7 +717,7 @@ ssize_t __splice_from_pipe(struct pipe_inode_info *pipe,
719 do_wakeup = 1; 717 do_wakeup = 1;
720 } 718 }
721 719
722 if (!sd.total_len) 720 if (!sd->total_len)
723 break; 721 break;
724 } 722 }
725 723
@@ -732,7 +730,7 @@ ssize_t __splice_from_pipe(struct pipe_inode_info *pipe,
732 break; 730 break;
733 } 731 }
734 732
735 if (flags & SPLICE_F_NONBLOCK) { 733 if (sd->flags & SPLICE_F_NONBLOCK) {
736 if (!ret) 734 if (!ret)
737 ret = -EAGAIN; 735 ret = -EAGAIN;
738 break; 736 break;
@@ -766,12 +764,32 @@ ssize_t __splice_from_pipe(struct pipe_inode_info *pipe,
766} 764}
767EXPORT_SYMBOL(__splice_from_pipe); 765EXPORT_SYMBOL(__splice_from_pipe);
768 766
767/**
768 * splice_from_pipe - splice data from a pipe to a file
769 * @pipe: pipe to splice from
770 * @out: file to splice to
771 * @ppos: position in @out
772 * @len: how many bytes to splice
773 * @flags: splice modifier flags
774 * @actor: handler that splices the data
775 *
776 * Description:
777 * See __splice_from_pipe. This function locks the input and output inodes,
778 * otherwise it's identical to __splice_from_pipe().
779 *
780 */
769ssize_t splice_from_pipe(struct pipe_inode_info *pipe, struct file *out, 781ssize_t splice_from_pipe(struct pipe_inode_info *pipe, struct file *out,
770 loff_t *ppos, size_t len, unsigned int flags, 782 loff_t *ppos, size_t len, unsigned int flags,
771 splice_actor *actor) 783 splice_actor *actor)
772{ 784{
773 ssize_t ret; 785 ssize_t ret;
774 struct inode *inode = out->f_mapping->host; 786 struct inode *inode = out->f_mapping->host;
787 struct splice_desc sd = {
788 .total_len = len,
789 .flags = flags,
790 .pos = *ppos,
791 .u.file = out,
792 };
775 793
776 /* 794 /*
777 * The actor worker might be calling ->prepare_write and 795 * The actor worker might be calling ->prepare_write and
@@ -780,7 +798,7 @@ ssize_t splice_from_pipe(struct pipe_inode_info *pipe, struct file *out,
780 * pipe->inode, we have to order lock acquiry here. 798 * pipe->inode, we have to order lock acquiry here.
781 */ 799 */
782 inode_double_lock(inode, pipe->inode); 800 inode_double_lock(inode, pipe->inode);
783 ret = __splice_from_pipe(pipe, out, ppos, len, flags, actor); 801 ret = __splice_from_pipe(pipe, &sd, actor);
784 inode_double_unlock(inode, pipe->inode); 802 inode_double_unlock(inode, pipe->inode);
785 803
786 return ret; 804 return ret;
@@ -790,12 +808,14 @@ ssize_t splice_from_pipe(struct pipe_inode_info *pipe, struct file *out,
790 * generic_file_splice_write_nolock - generic_file_splice_write without mutexes 808 * generic_file_splice_write_nolock - generic_file_splice_write without mutexes
791 * @pipe: pipe info 809 * @pipe: pipe info
792 * @out: file to write to 810 * @out: file to write to
811 * @ppos: position in @out
793 * @len: number of bytes to splice 812 * @len: number of bytes to splice
794 * @flags: splice modifier flags 813 * @flags: splice modifier flags
795 * 814 *
796 * Will either move or copy pages (determined by @flags options) from 815 * Description:
797 * the given pipe inode to the given file. The caller is responsible 816 * Will either move or copy pages (determined by @flags options) from
798 * for acquiring i_mutex on both inodes. 817 * the given pipe inode to the given file. The caller is responsible
818 * for acquiring i_mutex on both inodes.
799 * 819 *
800 */ 820 */
801ssize_t 821ssize_t
@@ -804,6 +824,12 @@ generic_file_splice_write_nolock(struct pipe_inode_info *pipe, struct file *out,
804{ 824{
805 struct address_space *mapping = out->f_mapping; 825 struct address_space *mapping = out->f_mapping;
806 struct inode *inode = mapping->host; 826 struct inode *inode = mapping->host;
827 struct splice_desc sd = {
828 .total_len = len,
829 .flags = flags,
830 .pos = *ppos,
831 .u.file = out,
832 };
807 ssize_t ret; 833 ssize_t ret;
808 int err; 834 int err;
809 835
@@ -811,7 +837,7 @@ generic_file_splice_write_nolock(struct pipe_inode_info *pipe, struct file *out,
811 if (unlikely(err)) 837 if (unlikely(err))
812 return err; 838 return err;
813 839
814 ret = __splice_from_pipe(pipe, out, ppos, len, flags, pipe_to_file); 840 ret = __splice_from_pipe(pipe, &sd, pipe_to_file);
815 if (ret > 0) { 841 if (ret > 0) {
816 unsigned long nr_pages; 842 unsigned long nr_pages;
817 843
@@ -841,11 +867,13 @@ EXPORT_SYMBOL(generic_file_splice_write_nolock);
841 * generic_file_splice_write - splice data from a pipe to a file 867 * generic_file_splice_write - splice data from a pipe to a file
842 * @pipe: pipe info 868 * @pipe: pipe info
843 * @out: file to write to 869 * @out: file to write to
870 * @ppos: position in @out
844 * @len: number of bytes to splice 871 * @len: number of bytes to splice
845 * @flags: splice modifier flags 872 * @flags: splice modifier flags
846 * 873 *
847 * Will either move or copy pages (determined by @flags options) from 874 * Description:
848 * the given pipe inode to the given file. 875 * Will either move or copy pages (determined by @flags options) from
876 * the given pipe inode to the given file.
849 * 877 *
850 */ 878 */
851ssize_t 879ssize_t
@@ -896,13 +924,15 @@ EXPORT_SYMBOL(generic_file_splice_write);
896 924
897/** 925/**
898 * generic_splice_sendpage - splice data from a pipe to a socket 926 * generic_splice_sendpage - splice data from a pipe to a socket
899 * @inode: pipe inode 927 * @pipe: pipe to splice from
900 * @out: socket to write to 928 * @out: socket to write to
929 * @ppos: position in @out
901 * @len: number of bytes to splice 930 * @len: number of bytes to splice
902 * @flags: splice modifier flags 931 * @flags: splice modifier flags
903 * 932 *
904 * Will send @len bytes from the pipe to a network socket. No data copying 933 * Description:
905 * is involved. 934 * Will send @len bytes from the pipe to a network socket. No data copying
935 * is involved.
906 * 936 *
907 */ 937 */
908ssize_t generic_splice_sendpage(struct pipe_inode_info *pipe, struct file *out, 938ssize_t generic_splice_sendpage(struct pipe_inode_info *pipe, struct file *out,
@@ -956,14 +986,27 @@ static long do_splice_to(struct file *in, loff_t *ppos,
956 return in->f_op->splice_read(in, ppos, pipe, len, flags); 986 return in->f_op->splice_read(in, ppos, pipe, len, flags);
957} 987}
958 988
959long do_splice_direct(struct file *in, loff_t *ppos, struct file *out, 989/**
960 size_t len, unsigned int flags) 990 * splice_direct_to_actor - splices data directly between two non-pipes
991 * @in: file to splice from
992 * @sd: actor information on where to splice to
993 * @actor: handles the data splicing
994 *
995 * Description:
996 * This is a special case helper to splice directly between two
997 * points, without requiring an explicit pipe. Internally an allocated
998 * pipe is cached in the process, and reused during the life time of
999 * that process.
1000 *
1001 */
1002ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd,
1003 splice_direct_actor *actor)
961{ 1004{
962 struct pipe_inode_info *pipe; 1005 struct pipe_inode_info *pipe;
963 long ret, bytes; 1006 long ret, bytes;
964 loff_t out_off;
965 umode_t i_mode; 1007 umode_t i_mode;
966 int i; 1008 size_t len;
1009 int i, flags;
967 1010
968 /* 1011 /*
969 * We require the input being a regular file, as we don't want to 1012 * We require the input being a regular file, as we don't want to
@@ -999,7 +1042,13 @@ long do_splice_direct(struct file *in, loff_t *ppos, struct file *out,
999 */ 1042 */
1000 ret = 0; 1043 ret = 0;
1001 bytes = 0; 1044 bytes = 0;
1002 out_off = 0; 1045 len = sd->total_len;
1046 flags = sd->flags;
1047
1048 /*
1049 * Don't block on output, we have to drain the direct pipe.
1050 */
1051 sd->flags &= ~SPLICE_F_NONBLOCK;
1003 1052
1004 while (len) { 1053 while (len) {
1005 size_t read_len, max_read_len; 1054 size_t read_len, max_read_len;
@@ -1009,19 +1058,19 @@ long do_splice_direct(struct file *in, loff_t *ppos, struct file *out,
1009 */ 1058 */
1010 max_read_len = min(len, (size_t)(PIPE_BUFFERS*PAGE_SIZE)); 1059 max_read_len = min(len, (size_t)(PIPE_BUFFERS*PAGE_SIZE));
1011 1060
1012 ret = do_splice_to(in, ppos, pipe, max_read_len, flags); 1061 ret = do_splice_to(in, &sd->pos, pipe, max_read_len, flags);
1013 if (unlikely(ret < 0)) 1062 if (unlikely(ret < 0))
1014 goto out_release; 1063 goto out_release;
1015 1064
1016 read_len = ret; 1065 read_len = ret;
1066 sd->total_len = read_len;
1017 1067
1018 /* 1068 /*
1019 * NOTE: nonblocking mode only applies to the input. We 1069 * NOTE: nonblocking mode only applies to the input. We
1020 * must not do the output in nonblocking mode as then we 1070 * must not do the output in nonblocking mode as then we
1021 * could get stuck data in the internal pipe: 1071 * could get stuck data in the internal pipe:
1022 */ 1072 */
1023 ret = do_splice_from(pipe, out, &out_off, read_len, 1073 ret = actor(pipe, sd);
1024 flags & ~SPLICE_F_NONBLOCK);
1025 if (unlikely(ret < 0)) 1074 if (unlikely(ret < 0))
1026 goto out_release; 1075 goto out_release;
1027 1076
@@ -1066,6 +1115,48 @@ out_release:
1066 return bytes; 1115 return bytes;
1067 1116
1068 return ret; 1117 return ret;
1118
1119}
1120EXPORT_SYMBOL(splice_direct_to_actor);
1121
1122static int direct_splice_actor(struct pipe_inode_info *pipe,
1123 struct splice_desc *sd)
1124{
1125 struct file *file = sd->u.file;
1126
1127 return do_splice_from(pipe, file, &sd->pos, sd->total_len, sd->flags);
1128}
1129
1130/**
1131 * do_splice_direct - splices data directly between two files
1132 * @in: file to splice from
1133 * @ppos: input file offset
1134 * @out: file to splice to
1135 * @len: number of bytes to splice
1136 * @flags: splice modifier flags
1137 *
1138 * Description:
1139 * For use by do_sendfile(). splice can easily emulate sendfile, but
1140 * doing it in the application would incur an extra system call
1141 * (splice in + splice out, as compared to just sendfile()). So this helper
1142 * can splice directly through a process-private pipe.
1143 *
1144 */
1145long do_splice_direct(struct file *in, loff_t *ppos, struct file *out,
1146 size_t len, unsigned int flags)
1147{
1148 struct splice_desc sd = {
1149 .len = len,
1150 .total_len = len,
1151 .flags = flags,
1152 .pos = *ppos,
1153 .u.file = out,
1154 };
1155 size_t ret;
1156
1157 ret = splice_direct_to_actor(in, &sd, direct_splice_actor);
1158 *ppos = sd.pos;
1159 return ret;
1069} 1160}
1070 1161
1071/* 1162/*
@@ -1248,28 +1339,131 @@ static int get_iovec_page_array(const struct iovec __user *iov,
1248 return error; 1339 return error;
1249} 1340}
1250 1341
1342static int pipe_to_user(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
1343 struct splice_desc *sd)
1344{
1345 char *src;
1346 int ret;
1347
1348 ret = buf->ops->confirm(pipe, buf);
1349 if (unlikely(ret))
1350 return ret;
1351
1352 /*
1353 * See if we can use the atomic maps, by prefaulting in the
1354 * pages and doing an atomic copy
1355 */
1356 if (!fault_in_pages_writeable(sd->u.userptr, sd->len)) {
1357 src = buf->ops->map(pipe, buf, 1);
1358 ret = __copy_to_user_inatomic(sd->u.userptr, src + buf->offset,
1359 sd->len);
1360 buf->ops->unmap(pipe, buf, src);
1361 if (!ret) {
1362 ret = sd->len;
1363 goto out;
1364 }
1365 }
1366
1367 /*
1368 * No dice, use slow non-atomic map and copy
1369 */
1370 src = buf->ops->map(pipe, buf, 0);
1371
1372 ret = sd->len;
1373 if (copy_to_user(sd->u.userptr, src + buf->offset, sd->len))
1374 ret = -EFAULT;
1375
1376out:
1377 if (ret > 0)
1378 sd->u.userptr += ret;
1379 buf->ops->unmap(pipe, buf, src);
1380 return ret;
1381}
1382
1383/*
1384 * For lack of a better implementation, implement vmsplice() to userspace
1385 * as a simple copy of the pipes pages to the user iov.
1386 */
1387static long vmsplice_to_user(struct file *file, const struct iovec __user *iov,
1388 unsigned long nr_segs, unsigned int flags)
1389{
1390 struct pipe_inode_info *pipe;
1391 struct splice_desc sd;
1392 ssize_t size;
1393 int error;
1394 long ret;
1395
1396 pipe = pipe_info(file->f_path.dentry->d_inode);
1397 if (!pipe)
1398 return -EBADF;
1399
1400 if (pipe->inode)
1401 mutex_lock(&pipe->inode->i_mutex);
1402
1403 error = ret = 0;
1404 while (nr_segs) {
1405 void __user *base;
1406 size_t len;
1407
1408 /*
1409 * Get user address base and length for this iovec.
1410 */
1411 error = get_user(base, &iov->iov_base);
1412 if (unlikely(error))
1413 break;
1414 error = get_user(len, &iov->iov_len);
1415 if (unlikely(error))
1416 break;
1417
1418 /*
1419 * Sanity check this iovec. 0 read succeeds.
1420 */
1421 if (unlikely(!len))
1422 break;
1423 if (unlikely(!base)) {
1424 error = -EFAULT;
1425 break;
1426 }
1427
1428 sd.len = 0;
1429 sd.total_len = len;
1430 sd.flags = flags;
1431 sd.u.userptr = base;
1432 sd.pos = 0;
1433
1434 size = __splice_from_pipe(pipe, &sd, pipe_to_user);
1435 if (size < 0) {
1436 if (!ret)
1437 ret = size;
1438
1439 break;
1440 }
1441
1442 ret += size;
1443
1444 if (size < len)
1445 break;
1446
1447 nr_segs--;
1448 iov++;
1449 }
1450
1451 if (pipe->inode)
1452 mutex_unlock(&pipe->inode->i_mutex);
1453
1454 if (!ret)
1455 ret = error;
1456
1457 return ret;
1458}
1459
1251/* 1460/*
1252 * vmsplice splices a user address range into a pipe. It can be thought of 1461 * vmsplice splices a user address range into a pipe. It can be thought of
1253 * as splice-from-memory, where the regular splice is splice-from-file (or 1462 * as splice-from-memory, where the regular splice is splice-from-file (or
1254 * to file). In both cases the output is a pipe, naturally. 1463 * to file). In both cases the output is a pipe, naturally.
1255 *
1256 * Note that vmsplice only supports splicing _from_ user memory to a pipe,
1257 * not the other way around. Splicing from user memory is a simple operation
1258 * that can be supported without any funky alignment restrictions or nasty
1259 * vm tricks. We simply map in the user memory and fill them into a pipe.
1260 * The reverse isn't quite as easy, though. There are two possible solutions
1261 * for that:
1262 *
1263 * - memcpy() the data internally, at which point we might as well just
1264 * do a regular read() on the buffer anyway.
1265 * - Lots of nasty vm tricks, that are neither fast nor flexible (it
1266 * has restriction limitations on both ends of the pipe).
1267 *
1268 * Alas, it isn't here.
1269 *
1270 */ 1464 */
1271static long do_vmsplice(struct file *file, const struct iovec __user *iov, 1465static long vmsplice_to_pipe(struct file *file, const struct iovec __user *iov,
1272 unsigned long nr_segs, unsigned int flags) 1466 unsigned long nr_segs, unsigned int flags)
1273{ 1467{
1274 struct pipe_inode_info *pipe; 1468 struct pipe_inode_info *pipe;
1275 struct page *pages[PIPE_BUFFERS]; 1469 struct page *pages[PIPE_BUFFERS];
@@ -1284,10 +1478,6 @@ static long do_vmsplice(struct file *file, const struct iovec __user *iov,
1284 pipe = pipe_info(file->f_path.dentry->d_inode); 1478 pipe = pipe_info(file->f_path.dentry->d_inode);
1285 if (!pipe) 1479 if (!pipe)
1286 return -EBADF; 1480 return -EBADF;
1287 if (unlikely(nr_segs > UIO_MAXIOV))
1288 return -EINVAL;
1289 else if (unlikely(!nr_segs))
1290 return 0;
1291 1481
1292 spd.nr_pages = get_iovec_page_array(iov, nr_segs, pages, partial, 1482 spd.nr_pages = get_iovec_page_array(iov, nr_segs, pages, partial,
1293 flags & SPLICE_F_GIFT); 1483 flags & SPLICE_F_GIFT);
@@ -1297,6 +1487,22 @@ static long do_vmsplice(struct file *file, const struct iovec __user *iov,
1297 return splice_to_pipe(pipe, &spd); 1487 return splice_to_pipe(pipe, &spd);
1298} 1488}
1299 1489
1490/*
1491 * Note that vmsplice only really supports true splicing _from_ user memory
1492 * to a pipe, not the other way around. Splicing from user memory is a simple
1493 * operation that can be supported without any funky alignment restrictions
1494 * or nasty vm tricks. We simply map in the user memory and fill them into
1495 * a pipe. The reverse isn't quite as easy, though. There are two possible
1496 * solutions for that:
1497 *
1498 * - memcpy() the data internally, at which point we might as well just
1499 * do a regular read() on the buffer anyway.
1500 * - Lots of nasty vm tricks, that are neither fast nor flexible (it
1501 * has restriction limitations on both ends of the pipe).
1502 *
1503 * Currently we punt and implement it as a normal copy, see pipe_to_user().
1504 *
1505 */
1300asmlinkage long sys_vmsplice(int fd, const struct iovec __user *iov, 1506asmlinkage long sys_vmsplice(int fd, const struct iovec __user *iov,
1301 unsigned long nr_segs, unsigned int flags) 1507 unsigned long nr_segs, unsigned int flags)
1302{ 1508{
@@ -1304,11 +1510,18 @@ asmlinkage long sys_vmsplice(int fd, const struct iovec __user *iov,
1304 long error; 1510 long error;
1305 int fput; 1511 int fput;
1306 1512
1513 if (unlikely(nr_segs > UIO_MAXIOV))
1514 return -EINVAL;
1515 else if (unlikely(!nr_segs))
1516 return 0;
1517
1307 error = -EBADF; 1518 error = -EBADF;
1308 file = fget_light(fd, &fput); 1519 file = fget_light(fd, &fput);
1309 if (file) { 1520 if (file) {
1310 if (file->f_mode & FMODE_WRITE) 1521 if (file->f_mode & FMODE_WRITE)
1311 error = do_vmsplice(file, iov, nr_segs, flags); 1522 error = vmsplice_to_pipe(file, iov, nr_segs, flags);
1523 else if (file->f_mode & FMODE_READ)
1524 error = vmsplice_to_user(file, iov, nr_segs, flags);
1312 1525
1313 fput_light(file, fput); 1526 fput_light(file, fput);
1314 } 1527 }
diff --git a/fs/sysv/file.c b/fs/sysv/file.c
index 0732ddb9020b..589be21d884e 100644
--- a/fs/sysv/file.c
+++ b/fs/sysv/file.c
@@ -27,7 +27,7 @@ const struct file_operations sysv_file_operations = {
27 .aio_write = generic_file_aio_write, 27 .aio_write = generic_file_aio_write,
28 .mmap = generic_file_mmap, 28 .mmap = generic_file_mmap,
29 .fsync = sysv_sync_file, 29 .fsync = sysv_sync_file,
30 .sendfile = generic_file_sendfile, 30 .splice_read = generic_file_splice_read,
31}; 31};
32 32
33const struct inode_operations sysv_file_inode_operations = { 33const struct inode_operations sysv_file_inode_operations = {
diff --git a/fs/udf/file.c b/fs/udf/file.c
index 51b5764685e7..df070bee8d4f 100644
--- a/fs/udf/file.c
+++ b/fs/udf/file.c
@@ -261,7 +261,7 @@ const struct file_operations udf_file_operations = {
261 .aio_write = udf_file_aio_write, 261 .aio_write = udf_file_aio_write,
262 .release = udf_release_file, 262 .release = udf_release_file,
263 .fsync = udf_fsync_file, 263 .fsync = udf_fsync_file,
264 .sendfile = generic_file_sendfile, 264 .splice_read = generic_file_splice_read,
265}; 265};
266 266
267const struct inode_operations udf_file_inode_operations = { 267const struct inode_operations udf_file_inode_operations = {
diff --git a/fs/ufs/file.c b/fs/ufs/file.c
index 1e096323bad4..6705d74c6d2d 100644
--- a/fs/ufs/file.c
+++ b/fs/ufs/file.c
@@ -60,5 +60,5 @@ const struct file_operations ufs_file_operations = {
60 .mmap = generic_file_mmap, 60 .mmap = generic_file_mmap,
61 .open = generic_file_open, 61 .open = generic_file_open,
62 .fsync = ufs_sync_file, 62 .fsync = ufs_sync_file,
63 .sendfile = generic_file_sendfile, 63 .splice_read = generic_file_splice_read,
64}; 64};
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c
index cb51dc961355..8c43cd2e237a 100644
--- a/fs/xfs/linux-2.6/xfs_file.c
+++ b/fs/xfs/linux-2.6/xfs_file.c
@@ -124,30 +124,6 @@ xfs_file_aio_write_invis(
124} 124}
125 125
126STATIC ssize_t 126STATIC ssize_t
127xfs_file_sendfile(
128 struct file *filp,
129 loff_t *pos,
130 size_t count,
131 read_actor_t actor,
132 void *target)
133{
134 return bhv_vop_sendfile(vn_from_inode(filp->f_path.dentry->d_inode),
135 filp, pos, 0, count, actor, target, NULL);
136}
137
138STATIC ssize_t
139xfs_file_sendfile_invis(
140 struct file *filp,
141 loff_t *pos,
142 size_t count,
143 read_actor_t actor,
144 void *target)
145{
146 return bhv_vop_sendfile(vn_from_inode(filp->f_path.dentry->d_inode),
147 filp, pos, IO_INVIS, count, actor, target, NULL);
148}
149
150STATIC ssize_t
151xfs_file_splice_read( 127xfs_file_splice_read(
152 struct file *infilp, 128 struct file *infilp,
153 loff_t *ppos, 129 loff_t *ppos,
@@ -452,7 +428,6 @@ const struct file_operations xfs_file_operations = {
452 .write = do_sync_write, 428 .write = do_sync_write,
453 .aio_read = xfs_file_aio_read, 429 .aio_read = xfs_file_aio_read,
454 .aio_write = xfs_file_aio_write, 430 .aio_write = xfs_file_aio_write,
455 .sendfile = xfs_file_sendfile,
456 .splice_read = xfs_file_splice_read, 431 .splice_read = xfs_file_splice_read,
457 .splice_write = xfs_file_splice_write, 432 .splice_write = xfs_file_splice_write,
458 .unlocked_ioctl = xfs_file_ioctl, 433 .unlocked_ioctl = xfs_file_ioctl,
@@ -475,7 +450,6 @@ const struct file_operations xfs_invis_file_operations = {
475 .write = do_sync_write, 450 .write = do_sync_write,
476 .aio_read = xfs_file_aio_read_invis, 451 .aio_read = xfs_file_aio_read_invis,
477 .aio_write = xfs_file_aio_write_invis, 452 .aio_write = xfs_file_aio_write_invis,
478 .sendfile = xfs_file_sendfile_invis,
479 .splice_read = xfs_file_splice_read_invis, 453 .splice_read = xfs_file_splice_read_invis,
480 .splice_write = xfs_file_splice_write_invis, 454 .splice_write = xfs_file_splice_write_invis,
481 .unlocked_ioctl = xfs_file_ioctl_invis, 455 .unlocked_ioctl = xfs_file_ioctl_invis,
diff --git a/fs/xfs/linux-2.6/xfs_linux.h b/fs/xfs/linux-2.6/xfs_linux.h
index 715adad7dd4d..af24a457d3a3 100644
--- a/fs/xfs/linux-2.6/xfs_linux.h
+++ b/fs/xfs/linux-2.6/xfs_linux.h
@@ -101,7 +101,6 @@
101 * Feature macros (disable/enable) 101 * Feature macros (disable/enable)
102 */ 102 */
103#undef HAVE_REFCACHE /* reference cache not needed for NFS in 2.6 */ 103#undef HAVE_REFCACHE /* reference cache not needed for NFS in 2.6 */
104#define HAVE_SENDFILE /* sendfile(2) exists in 2.6, but not in 2.4 */
105#define HAVE_SPLICE /* a splice(2) exists in 2.6, but not in 2.4 */ 104#define HAVE_SPLICE /* a splice(2) exists in 2.6, but not in 2.4 */
106#ifdef CONFIG_SMP 105#ifdef CONFIG_SMP
107#define HAVE_PERCPU_SB /* per cpu superblock counters are a 2.6 feature */ 106#define HAVE_PERCPU_SB /* per cpu superblock counters are a 2.6 feature */
diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c
index ed90403f0ee7..765ec16a6e39 100644
--- a/fs/xfs/linux-2.6/xfs_lrw.c
+++ b/fs/xfs/linux-2.6/xfs_lrw.c
@@ -287,50 +287,6 @@ xfs_read(
287} 287}
288 288
289ssize_t 289ssize_t
290xfs_sendfile(
291 bhv_desc_t *bdp,
292 struct file *filp,
293 loff_t *offset,
294 int ioflags,
295 size_t count,
296 read_actor_t actor,
297 void *target,
298 cred_t *credp)
299{
300 xfs_inode_t *ip = XFS_BHVTOI(bdp);
301 xfs_mount_t *mp = ip->i_mount;
302 ssize_t ret;
303
304 XFS_STATS_INC(xs_read_calls);
305 if (XFS_FORCED_SHUTDOWN(mp))
306 return -EIO;
307
308 xfs_ilock(ip, XFS_IOLOCK_SHARED);
309
310 if (DM_EVENT_ENABLED(BHV_TO_VNODE(bdp)->v_vfsp, ip, DM_EVENT_READ) &&
311 (!(ioflags & IO_INVIS))) {
312 bhv_vrwlock_t locktype = VRWLOCK_READ;
313 int error;
314
315 error = XFS_SEND_DATA(mp, DM_EVENT_READ, BHV_TO_VNODE(bdp),
316 *offset, count,
317 FILP_DELAY_FLAG(filp), &locktype);
318 if (error) {
319 xfs_iunlock(ip, XFS_IOLOCK_SHARED);
320 return -error;
321 }
322 }
323 xfs_rw_enter_trace(XFS_SENDFILE_ENTER, &ip->i_iocore,
324 (void *)(unsigned long)target, count, *offset, ioflags);
325 ret = generic_file_sendfile(filp, offset, count, actor, target);
326 if (ret > 0)
327 XFS_STATS_ADD(xs_read_bytes, ret);
328
329 xfs_iunlock(ip, XFS_IOLOCK_SHARED);
330 return ret;
331}
332
333ssize_t
334xfs_splice_read( 290xfs_splice_read(
335 bhv_desc_t *bdp, 291 bhv_desc_t *bdp,
336 struct file *infilp, 292 struct file *infilp,
diff --git a/fs/xfs/linux-2.6/xfs_lrw.h b/fs/xfs/linux-2.6/xfs_lrw.h
index 7ac51b1d2161..7c60a1eed88b 100644
--- a/fs/xfs/linux-2.6/xfs_lrw.h
+++ b/fs/xfs/linux-2.6/xfs_lrw.h
@@ -90,9 +90,6 @@ extern ssize_t xfs_read(struct bhv_desc *, struct kiocb *,
90extern ssize_t xfs_write(struct bhv_desc *, struct kiocb *, 90extern ssize_t xfs_write(struct bhv_desc *, struct kiocb *,
91 const struct iovec *, unsigned int, 91 const struct iovec *, unsigned int,
92 loff_t *, int, struct cred *); 92 loff_t *, int, struct cred *);
93extern ssize_t xfs_sendfile(struct bhv_desc *, struct file *,
94 loff_t *, int, size_t, read_actor_t,
95 void *, struct cred *);
96extern ssize_t xfs_splice_read(struct bhv_desc *, struct file *, loff_t *, 93extern ssize_t xfs_splice_read(struct bhv_desc *, struct file *, loff_t *,
97 struct pipe_inode_info *, size_t, int, int, 94 struct pipe_inode_info *, size_t, int, int,
98 struct cred *); 95 struct cred *);
diff --git a/fs/xfs/linux-2.6/xfs_vnode.h b/fs/xfs/linux-2.6/xfs_vnode.h
index d1b2d01843d1..013048a92643 100644
--- a/fs/xfs/linux-2.6/xfs_vnode.h
+++ b/fs/xfs/linux-2.6/xfs_vnode.h
@@ -139,9 +139,6 @@ typedef ssize_t (*vop_read_t)(bhv_desc_t *, struct kiocb *,
139typedef ssize_t (*vop_write_t)(bhv_desc_t *, struct kiocb *, 139typedef ssize_t (*vop_write_t)(bhv_desc_t *, struct kiocb *,
140 const struct iovec *, unsigned int, 140 const struct iovec *, unsigned int,
141 loff_t *, int, struct cred *); 141 loff_t *, int, struct cred *);
142typedef ssize_t (*vop_sendfile_t)(bhv_desc_t *, struct file *,
143 loff_t *, int, size_t, read_actor_t,
144 void *, struct cred *);
145typedef ssize_t (*vop_splice_read_t)(bhv_desc_t *, struct file *, loff_t *, 142typedef ssize_t (*vop_splice_read_t)(bhv_desc_t *, struct file *, loff_t *,
146 struct pipe_inode_info *, size_t, int, int, 143 struct pipe_inode_info *, size_t, int, int,
147 struct cred *); 144 struct cred *);
@@ -206,7 +203,6 @@ typedef struct bhv_vnodeops {
206 vop_close_t vop_close; 203 vop_close_t vop_close;
207 vop_read_t vop_read; 204 vop_read_t vop_read;
208 vop_write_t vop_write; 205 vop_write_t vop_write;
209 vop_sendfile_t vop_sendfile;
210 vop_splice_read_t vop_splice_read; 206 vop_splice_read_t vop_splice_read;
211 vop_splice_write_t vop_splice_write; 207 vop_splice_write_t vop_splice_write;
212 vop_ioctl_t vop_ioctl; 208 vop_ioctl_t vop_ioctl;
@@ -254,8 +250,6 @@ typedef struct bhv_vnodeops {
254 VOP(vop_read, vp)(VNHEAD(vp),file,iov,segs,offset,ioflags,cr) 250 VOP(vop_read, vp)(VNHEAD(vp),file,iov,segs,offset,ioflags,cr)
255#define bhv_vop_write(vp,file,iov,segs,offset,ioflags,cr) \ 251#define bhv_vop_write(vp,file,iov,segs,offset,ioflags,cr) \
256 VOP(vop_write, vp)(VNHEAD(vp),file,iov,segs,offset,ioflags,cr) 252 VOP(vop_write, vp)(VNHEAD(vp),file,iov,segs,offset,ioflags,cr)
257#define bhv_vop_sendfile(vp,f,off,ioflags,cnt,act,targ,cr) \
258 VOP(vop_sendfile, vp)(VNHEAD(vp),f,off,ioflags,cnt,act,targ,cr)
259#define bhv_vop_splice_read(vp,f,o,pipe,cnt,fl,iofl,cr) \ 253#define bhv_vop_splice_read(vp,f,o,pipe,cnt,fl,iofl,cr) \
260 VOP(vop_splice_read, vp)(VNHEAD(vp),f,o,pipe,cnt,fl,iofl,cr) 254 VOP(vop_splice_read, vp)(VNHEAD(vp),f,o,pipe,cnt,fl,iofl,cr)
261#define bhv_vop_splice_write(vp,f,o,pipe,cnt,fl,iofl,cr) \ 255#define bhv_vop_splice_write(vp,f,o,pipe,cnt,fl,iofl,cr) \
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index de17aed578f0..70bc82f65311 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -4680,9 +4680,6 @@ bhv_vnodeops_t xfs_vnodeops = {
4680 .vop_open = xfs_open, 4680 .vop_open = xfs_open,
4681 .vop_close = xfs_close, 4681 .vop_close = xfs_close,
4682 .vop_read = xfs_read, 4682 .vop_read = xfs_read,
4683#ifdef HAVE_SENDFILE
4684 .vop_sendfile = xfs_sendfile,
4685#endif
4686#ifdef HAVE_SPLICE 4683#ifdef HAVE_SPLICE
4687 .vop_splice_read = xfs_splice_read, 4684 .vop_splice_read = xfs_splice_read,
4688 .vop_splice_write = xfs_splice_write, 4685 .vop_splice_write = xfs_splice_write,
diff --git a/include/asm-generic/bitops/sched.h b/include/asm-generic/bitops/sched.h
index 815bb0148060..604fab7031a6 100644
--- a/include/asm-generic/bitops/sched.h
+++ b/include/asm-generic/bitops/sched.h
@@ -6,28 +6,23 @@
6 6
7/* 7/*
8 * Every architecture must define this function. It's the fastest 8 * Every architecture must define this function. It's the fastest
9 * way of searching a 140-bit bitmap where the first 100 bits are 9 * way of searching a 100-bit bitmap. It's guaranteed that at least
10 * unlikely to be set. It's guaranteed that at least one of the 140 10 * one of the 100 bits is cleared.
11 * bits is cleared.
12 */ 11 */
13static inline int sched_find_first_bit(const unsigned long *b) 12static inline int sched_find_first_bit(const unsigned long *b)
14{ 13{
15#if BITS_PER_LONG == 64 14#if BITS_PER_LONG == 64
16 if (unlikely(b[0])) 15 if (b[0])
17 return __ffs(b[0]); 16 return __ffs(b[0]);
18 if (likely(b[1])) 17 return __ffs(b[1]) + 64;
19 return __ffs(b[1]) + 64;
20 return __ffs(b[2]) + 128;
21#elif BITS_PER_LONG == 32 18#elif BITS_PER_LONG == 32
22 if (unlikely(b[0])) 19 if (b[0])
23 return __ffs(b[0]); 20 return __ffs(b[0]);
24 if (unlikely(b[1])) 21 if (b[1])
25 return __ffs(b[1]) + 32; 22 return __ffs(b[1]) + 32;
26 if (unlikely(b[2])) 23 if (b[2])
27 return __ffs(b[2]) + 64; 24 return __ffs(b[2]) + 64;
28 if (b[3]) 25 return __ffs(b[3]) + 96;
29 return __ffs(b[3]) + 96;
30 return __ffs(b[4]) + 128;
31#else 26#else
32#error BITS_PER_LONG not defined 27#error BITS_PER_LONG not defined
33#endif 28#endif
diff --git a/include/asm-mips/addrspace.h b/include/asm-mips/addrspace.h
index 964c5eddc21b..0b3ff9c48409 100644
--- a/include/asm-mips/addrspace.h
+++ b/include/asm-mips/addrspace.h
@@ -129,29 +129,12 @@
129#define PHYS_TO_XKPHYS(cm,a) (_CONST64_(0x8000000000000000) | \ 129#define PHYS_TO_XKPHYS(cm,a) (_CONST64_(0x8000000000000000) | \
130 ((cm)<<59) | (a)) 130 ((cm)<<59) | (a))
131 131
132#if defined (CONFIG_CPU_R4300) \ 132/*
133 || defined (CONFIG_CPU_R4X00) \ 133 * The ultimate limited of the 64-bit MIPS architecture: 2 bits for selecting
134 || defined (CONFIG_CPU_R5000) \ 134 * the region, 3 bits for the CCA mode. This leaves 59 bits of which the
135 || defined (CONFIG_CPU_RM7000) \ 135 * R8000 implements most with its 48-bit physical address space.
136 || defined (CONFIG_CPU_RM9000) \ 136 */
137 || defined (CONFIG_CPU_NEVADA) \ 137#define TO_PHYS_MASK _CONST64_(0x07ffffffffffffff) /* 2^^59 - 1 */
138 || defined (CONFIG_CPU_TX49XX) \
139 || defined (CONFIG_CPU_MIPS64)
140#define TO_PHYS_MASK _CONST64_(0x0000000fffffffff) /* 2^^36 - 1 */
141#endif
142
143#if defined (CONFIG_CPU_R8000)
144/* We keep KUSIZE consistent with R4000 for now (2^^40) instead of (2^^48) */
145#define TO_PHYS_MASK _CONST64_(0x000000ffffffffff) /* 2^^40 - 1 */
146#endif
147
148#if defined (CONFIG_CPU_R10000)
149#define TO_PHYS_MASK _CONST64_(0x000000ffffffffff) /* 2^^40 - 1 */
150#endif
151
152#if defined(CONFIG_CPU_SB1) || defined(CONFIG_CPU_SB1A)
153#define TO_PHYS_MASK _CONST64_(0x00000fffffffffff) /* 2^^44 - 1 */
154#endif
155 138
156#ifndef CONFIG_CPU_R8000 139#ifndef CONFIG_CPU_R8000
157 140
diff --git a/include/asm-mips/bootinfo.h b/include/asm-mips/bootinfo.h
index b0c329783ac5..087126a5faf9 100644
--- a/include/asm-mips/bootinfo.h
+++ b/include/asm-mips/bootinfo.h
@@ -109,18 +109,12 @@
109#define MACH_COSINE_ORION 0 109#define MACH_COSINE_ORION 0
110 110
111/* 111/*
112 * Valid machtype for group GALILEO
113 */
114#define MACH_GROUP_GALILEO 11 /* Galileo Eval Boards */
115#define MACH_EV64120A 0 /* EV64120A */
116
117/*
118 * Valid machtype for group MOMENCO 112 * Valid machtype for group MOMENCO
119 */ 113 */
120#define MACH_GROUP_MOMENCO 12 /* Momentum Boards */ 114#define MACH_GROUP_MOMENCO 12 /* Momentum Boards */
121#define MACH_MOMENCO_OCELOT 0 115#define MACH_MOMENCO_OCELOT 0
122#define MACH_MOMENCO_OCELOT_G 1 /* no more supported (may 2007) */ 116#define MACH_MOMENCO_OCELOT_G 1 /* no more supported (may 2007) */
123#define MACH_MOMENCO_OCELOT_C 2 117#define MACH_MOMENCO_OCELOT_C 2 /* no more supported (jun 2007) */
124#define MACH_MOMENCO_JAGUAR_ATX 3 /* no more supported (may 2007) */ 118#define MACH_MOMENCO_JAGUAR_ATX 3 /* no more supported (may 2007) */
125#define MACH_MOMENCO_OCELOT_3 4 119#define MACH_MOMENCO_OCELOT_3 4
126 120
@@ -194,13 +188,6 @@
194#define MACH_HP_LASERJET 1 188#define MACH_HP_LASERJET 1
195 189
196/* 190/*
197 * Valid machtype for group LASAT
198 */
199#define MACH_GROUP_LASAT 21
200#define MACH_LASAT_100 0 /* Masquerade II/SP100/SP50/SP25 */
201#define MACH_LASAT_200 1 /* Masquerade PRO/SP200 */
202
203/*
204 * Valid machtype for group TITAN 191 * Valid machtype for group TITAN
205 */ 192 */
206#define MACH_GROUP_TITAN 22 /* PMC-Sierra Titan */ 193#define MACH_GROUP_TITAN 22 /* PMC-Sierra Titan */
@@ -213,6 +200,27 @@
213#define MACH_GROUP_NEC_EMMA2RH 25 /* NEC EMMA2RH (was 23) */ 200#define MACH_GROUP_NEC_EMMA2RH 25 /* NEC EMMA2RH (was 23) */
214#define MACH_NEC_MARKEINS 0 /* NEC EMMA2RH Mark-eins */ 201#define MACH_NEC_MARKEINS 0 /* NEC EMMA2RH Mark-eins */
215 202
203/*
204 * Valid machtype for group LEMOTE
205 */
206#define MACH_GROUP_LEMOTE 27
207#define MACH_LEMOTE_FULONG 0
208
209/*
210 * Valid machtype for group PMC-MSP
211 */
212#define MACH_GROUP_MSP 26 /* PMC-Sierra MSP boards/CPUs */
213#define MACH_MSP4200_EVAL 0 /* PMC-Sierra MSP4200 Evaluation */
214#define MACH_MSP4200_GW 1 /* PMC-Sierra MSP4200 Gateway demo */
215#define MACH_MSP4200_FPGA 2 /* PMC-Sierra MSP4200 Emulation */
216#define MACH_MSP7120_EVAL 3 /* PMC-Sierra MSP7120 Evaluation */
217#define MACH_MSP7120_GW 4 /* PMC-Sierra MSP7120 Residential GW */
218#define MACH_MSP7120_FPGA 5 /* PMC-Sierra MSP7120 Emulation */
219#define MACH_MSP_OTHER 255 /* PMC-Sierra unknown board type */
220
221#define MACH_GROUP_WINDRIVER 28 /* Windriver boards */
222#define MACH_WRPPMC 1
223
216#define CL_SIZE COMMAND_LINE_SIZE 224#define CL_SIZE COMMAND_LINE_SIZE
217 225
218const char *get_system_type(void); 226const char *get_system_type(void);
diff --git a/include/asm-mips/cacheops.h b/include/asm-mips/cacheops.h
index c4a1ec31ff6a..df7f2deb3b56 100644
--- a/include/asm-mips/cacheops.h
+++ b/include/asm-mips/cacheops.h
@@ -20,7 +20,11 @@
20#define Index_Load_Tag_D 0x05 20#define Index_Load_Tag_D 0x05
21#define Index_Store_Tag_I 0x08 21#define Index_Store_Tag_I 0x08
22#define Index_Store_Tag_D 0x09 22#define Index_Store_Tag_D 0x09
23#if defined(CONFIG_CPU_LOONGSON2)
24#define Hit_Invalidate_I 0x00
25#else
23#define Hit_Invalidate_I 0x10 26#define Hit_Invalidate_I 0x10
27#endif
24#define Hit_Invalidate_D 0x11 28#define Hit_Invalidate_D 0x11
25#define Hit_Writeback_Inv_D 0x15 29#define Hit_Writeback_Inv_D 0x15
26 30
diff --git a/include/asm-mips/cpu-features.h b/include/asm-mips/cpu-features.h
index 5e4bed123b48..d95a83e3e1d7 100644
--- a/include/asm-mips/cpu-features.h
+++ b/include/asm-mips/cpu-features.h
@@ -150,6 +150,10 @@
150#define cpu_has_mipsmt (cpu_data[0].ases & MIPS_ASE_MIPSMT) 150#define cpu_has_mipsmt (cpu_data[0].ases & MIPS_ASE_MIPSMT)
151#endif 151#endif
152 152
153#ifndef cpu_has_userlocal
154#define cpu_has_userlocal (cpu_data[0].options & MIPS_CPU_ULRI)
155#endif
156
153#ifdef CONFIG_32BIT 157#ifdef CONFIG_32BIT
154# ifndef cpu_has_nofpuex 158# ifndef cpu_has_nofpuex
155# define cpu_has_nofpuex (cpu_data[0].options & MIPS_CPU_NOFPUEX) 159# define cpu_has_nofpuex (cpu_data[0].options & MIPS_CPU_NOFPUEX)
diff --git a/include/asm-mips/cpu.h b/include/asm-mips/cpu.h
index 2924069075e0..3857358fb6de 100644
--- a/include/asm-mips/cpu.h
+++ b/include/asm-mips/cpu.h
@@ -89,6 +89,8 @@
89#define PRID_IMP_34K 0x9500 89#define PRID_IMP_34K 0x9500
90#define PRID_IMP_24KE 0x9600 90#define PRID_IMP_24KE 0x9600
91#define PRID_IMP_74K 0x9700 91#define PRID_IMP_74K 0x9700
92#define PRID_IMP_LOONGSON1 0x4200
93#define PRID_IMP_LOONGSON2 0x6300
92 94
93/* 95/*
94 * These are the PRID's for when 23:16 == PRID_COMP_SIBYTE 96 * These are the PRID's for when 23:16 == PRID_COMP_SIBYTE
@@ -107,6 +109,7 @@
107 * Definitions for 7:0 on legacy processors 109 * Definitions for 7:0 on legacy processors
108 */ 110 */
109 111
112#define PRID_REV_MASK 0x00ff
110 113
111#define PRID_REV_TX4927 0x0022 114#define PRID_REV_TX4927 0x0022
112#define PRID_REV_TX4937 0x0030 115#define PRID_REV_TX4937 0x0030
@@ -123,6 +126,7 @@
123#define PRID_REV_VR4122 0x0070 126#define PRID_REV_VR4122 0x0070
124#define PRID_REV_VR4181A 0x0070 /* Same as VR4122 */ 127#define PRID_REV_VR4181A 0x0070 /* Same as VR4122 */
125#define PRID_REV_VR4130 0x0080 128#define PRID_REV_VR4130 0x0080
129#define PRID_REV_34K_V1_0_2 0x0022
126 130
127/* 131/*
128 * Older processors used to encode processor version and revision in two 132 * Older processors used to encode processor version and revision in two
@@ -211,7 +215,10 @@
211#define CPU_SB1A 62 215#define CPU_SB1A 62
212#define CPU_74K 63 216#define CPU_74K 63
213#define CPU_R14000 64 217#define CPU_R14000 64
214#define CPU_LAST 64 218#define CPU_LOONGSON1 65
219#define CPU_LOONGSON2 66
220
221#define CPU_LAST 66
215 222
216/* 223/*
217 * ISA Level encodings 224 * ISA Level encodings
@@ -257,6 +264,7 @@
257#define MIPS_CPU_PREFETCH 0x00080000 /* CPU has usable prefetch */ 264#define MIPS_CPU_PREFETCH 0x00080000 /* CPU has usable prefetch */
258#define MIPS_CPU_VINT 0x00100000 /* CPU supports MIPSR2 vectored interrupts */ 265#define MIPS_CPU_VINT 0x00100000 /* CPU supports MIPSR2 vectored interrupts */
259#define MIPS_CPU_VEIC 0x00200000 /* CPU supports MIPSR2 external interrupt controller mode */ 266#define MIPS_CPU_VEIC 0x00200000 /* CPU supports MIPSR2 external interrupt controller mode */
267#define MIPS_CPU_ULRI 0x00400000 /* CPU has ULRI feature */
260 268
261/* 269/*
262 * CPU ASE encodings 270 * CPU ASE encodings
diff --git a/include/asm-mips/div64.h b/include/asm-mips/div64.h
index 66189f5f6399..716371bd0980 100644
--- a/include/asm-mips/div64.h
+++ b/include/asm-mips/div64.h
@@ -20,7 +20,7 @@
20 */ 20 */
21 21
22#define do_div64_32(res, high, low, base) ({ \ 22#define do_div64_32(res, high, low, base) ({ \
23 unsigned long __quot, __mod; \ 23 unsigned long __quot32, __mod32; \
24 unsigned long __cf, __tmp, __tmp2, __i; \ 24 unsigned long __cf, __tmp, __tmp2, __i; \
25 \ 25 \
26 __asm__(".set push\n\t" \ 26 __asm__(".set push\n\t" \
@@ -48,12 +48,13 @@
48 "bnez %4, 0b\n\t" \ 48 "bnez %4, 0b\n\t" \
49 " srl %5, %1, 0x1f\n\t" \ 49 " srl %5, %1, 0x1f\n\t" \
50 ".set pop" \ 50 ".set pop" \
51 : "=&r" (__mod), "=&r" (__tmp), "=&r" (__quot), "=&r" (__cf), \ 51 : "=&r" (__mod32), "=&r" (__tmp), \
52 "=&r" (__quot32), "=&r" (__cf), \
52 "=&r" (__i), "=&r" (__tmp2) \ 53 "=&r" (__i), "=&r" (__tmp2) \
53 : "Jr" (base), "0" (high), "1" (low)); \ 54 : "Jr" (base), "0" (high), "1" (low)); \
54 \ 55 \
55 (res) = __quot; \ 56 (res) = __quot32; \
56 __mod; }) 57 __mod32; })
57 58
58#define do_div(n, base) ({ \ 59#define do_div(n, base) ({ \
59 unsigned long long __quot; \ 60 unsigned long long __quot; \
diff --git a/include/asm-mips/gpio.h b/include/asm-mips/gpio.h
new file mode 100644
index 000000000000..06e46faf862d
--- /dev/null
+++ b/include/asm-mips/gpio.h
@@ -0,0 +1,6 @@
1#ifndef __ASM_MIPS_GPIO_H
2#define __ASM_MIPS_GPIO_H
3
4#include <gpio.h>
5
6#endif /* __ASM_MIPS_GPIO_H */
diff --git a/include/asm-mips/io.h b/include/asm-mips/io.h
index 92ec2618560c..12bcc1f9fba9 100644
--- a/include/asm-mips/io.h
+++ b/include/asm-mips/io.h
@@ -178,6 +178,11 @@ extern void __iounmap(const volatile void __iomem *addr);
178static inline void __iomem * __ioremap_mode(phys_t offset, unsigned long size, 178static inline void __iomem * __ioremap_mode(phys_t offset, unsigned long size,
179 unsigned long flags) 179 unsigned long flags)
180{ 180{
181 void __iomem *addr = plat_ioremap(offset, size, flags);
182
183 if (addr)
184 return addr;
185
181#define __IS_LOW512(addr) (!((phys_t)(addr) & (phys_t) ~0x1fffffffULL)) 186#define __IS_LOW512(addr) (!((phys_t)(addr) & (phys_t) ~0x1fffffffULL))
182 187
183 if (cpu_has_64bit_addresses) { 188 if (cpu_has_64bit_addresses) {
@@ -282,6 +287,9 @@ static inline void __iomem * __ioremap_mode(phys_t offset, unsigned long size,
282 287
283static inline void iounmap(const volatile void __iomem *addr) 288static inline void iounmap(const volatile void __iomem *addr)
284{ 289{
290 if (plat_iounmap(addr))
291 return;
292
285#define __IS_KSEG1(addr) (((unsigned long)(addr) & ~0x1fffffffUL) == CKSEG1) 293#define __IS_KSEG1(addr) (((unsigned long)(addr) & ~0x1fffffffUL) == CKSEG1)
286 294
287 if (cpu_has_64bit_addresses || 295 if (cpu_has_64bit_addresses ||
diff --git a/include/asm-mips/lasat/ds1603.h b/include/asm-mips/lasat/ds1603.h
deleted file mode 100644
index edcd7544b358..000000000000
--- a/include/asm-mips/lasat/ds1603.h
+++ /dev/null
@@ -1,18 +0,0 @@
1#include <asm/addrspace.h>
2
3/* Lasat 100 */
4#define DS1603_REG_100 (KSEG1ADDR(0x1c810000))
5#define DS1603_RST_100 (1 << 2)
6#define DS1603_CLK_100 (1 << 0)
7#define DS1603_DATA_SHIFT_100 1
8#define DS1603_DATA_100 (1 << DS1603_DATA_SHIFT_100)
9
10/* Lasat 200 */
11#define DS1603_REG_200 (KSEG1ADDR(0x11000000))
12#define DS1603_RST_200 (1 << 3)
13#define DS1603_CLK_200 (1 << 4)
14#define DS1603_DATA_200 (1 << 5)
15
16#define DS1603_DATA_REG_200 (DS1603_REG_200 + 0x10000)
17#define DS1603_DATA_READ_SHIFT_200 9
18#define DS1603_DATA_READ_200 (1 << DS1603_DATA_READ_SHIFT_200)
diff --git a/include/asm-mips/lasat/eeprom.h b/include/asm-mips/lasat/eeprom.h
deleted file mode 100644
index 7b53edd5cd5f..000000000000
--- a/include/asm-mips/lasat/eeprom.h
+++ /dev/null
@@ -1,17 +0,0 @@
1#include <asm/addrspace.h>
2
3/* lasat 100 */
4#define AT93C_REG_100 KSEG1ADDR(0x1c810000)
5#define AT93C_RDATA_REG_100 AT93C_REG_100
6#define AT93C_RDATA_SHIFT_100 4
7#define AT93C_WDATA_SHIFT_100 4
8#define AT93C_CS_M_100 ( 1 << 5 )
9#define AT93C_CLK_M_100 ( 1 << 3 )
10
11/* lasat 200 */
12#define AT93C_REG_200 KSEG1ADDR(0x11000000)
13#define AT93C_RDATA_REG_200 (AT93C_REG_200+0x10000)
14#define AT93C_RDATA_SHIFT_200 8
15#define AT93C_WDATA_SHIFT_200 2
16#define AT93C_CS_M_200 ( 1 << 0 )
17#define AT93C_CLK_M_200 ( 1 << 1 )
diff --git a/include/asm-mips/lasat/head.h b/include/asm-mips/lasat/head.h
deleted file mode 100644
index f5589f31a197..000000000000
--- a/include/asm-mips/lasat/head.h
+++ /dev/null
@@ -1,22 +0,0 @@
1/*
2 * Image header stuff
3 */
4#ifndef _HEAD_H
5#define _HEAD_H
6
7#define LASAT_K_MAGIC0_VAL 0xfedeabba
8#define LASAT_K_MAGIC1_VAL 0x00bedead
9
10#ifndef _LANGUAGE_ASSEMBLY
11#include <linux/types.h>
12struct bootloader_header {
13 u32 magic[2];
14 u32 version;
15 u32 image_start;
16 u32 image_size;
17 u32 kernel_start;
18 u32 kernel_entry;
19};
20#endif
21
22#endif /* _HEAD_H */
diff --git a/include/asm-mips/lasat/lasat.h b/include/asm-mips/lasat/lasat.h
deleted file mode 100644
index 42077e367a5b..000000000000
--- a/include/asm-mips/lasat/lasat.h
+++ /dev/null
@@ -1,253 +0,0 @@
1/*
2 * lasat.h
3 *
4 * Thomas Horsten <thh@lasat.com>
5 * Copyright (C) 2000 LASAT Networks A/S.
6 *
7 * This program is free software; you can distribute it and/or modify it
8 * under the terms of the GNU General Public License (Version 2) as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
19 *
20 * Configuration for LASAT boards, loads the appropriate include files.
21 */
22#ifndef _LASAT_H
23#define _LASAT_H
24
25#ifndef _LANGUAGE_ASSEMBLY
26
27extern struct lasat_misc {
28 volatile u32 *reset_reg;
29 volatile u32 *flash_wp_reg;
30 u32 flash_wp_bit;
31} *lasat_misc;
32
33enum lasat_mtdparts {
34 LASAT_MTD_BOOTLOADER,
35 LASAT_MTD_SERVICE,
36 LASAT_MTD_NORMAL,
37 LASAT_MTD_CONFIG,
38 LASAT_MTD_FS,
39 LASAT_MTD_LAST
40};
41
42/*
43 * The format of the data record in the EEPROM.
44 * See Documentation/LASAT/eeprom.txt for a detailed description
45 * of the fields in this struct, and the LASAT Hardware Configuration
46 * field specification for a detailed description of the config
47 * field.
48 */
49#include <linux/types.h>
50
51#define LASAT_EEPROM_VERSION 7
52struct lasat_eeprom_struct {
53 unsigned int version;
54 unsigned int cfg[3];
55 unsigned char hwaddr[6];
56 unsigned char print_partno[12];
57 unsigned char term0;
58 unsigned char print_serial[14];
59 unsigned char term1;
60 unsigned char prod_partno[12];
61 unsigned char term2;
62 unsigned char prod_serial[14];
63 unsigned char term3;
64 unsigned char passwd_hash[16];
65 unsigned char pwdnull;
66 unsigned char vendid;
67 unsigned char ts_ref;
68 unsigned char ts_signoff;
69 unsigned char reserved[11];
70 unsigned char debugaccess;
71 unsigned short prid;
72 unsigned int serviceflag;
73 unsigned int ipaddr;
74 unsigned int netmask;
75 unsigned int crc32;
76};
77
78struct lasat_eeprom_struct_pre7 {
79 unsigned int version;
80 unsigned int flags[3];
81 unsigned char hwaddr0[6];
82 unsigned char hwaddr1[6];
83 unsigned char print_partno[9];
84 unsigned char term0;
85 unsigned char print_serial[14];
86 unsigned char term1;
87 unsigned char prod_partno[9];
88 unsigned char term2;
89 unsigned char prod_serial[14];
90 unsigned char term3;
91 unsigned char passwd_hash[24];
92 unsigned char pwdnull;
93 unsigned char vendor;
94 unsigned char ts_ref;
95 unsigned char ts_signoff;
96 unsigned char reserved[6];
97 unsigned int writecount;
98 unsigned int ipaddr;
99 unsigned int netmask;
100 unsigned int crc32;
101};
102
103/* Configuration descriptor encoding - see the doc for details */
104
105#define LASAT_W0_DSCTYPE(v) ( ( (v) ) & 0xf )
106#define LASAT_W0_BMID(v) ( ( (v) >> 0x04 ) & 0xf )
107#define LASAT_W0_CPUTYPE(v) ( ( (v) >> 0x08 ) & 0xf )
108#define LASAT_W0_BUSSPEED(v) ( ( (v) >> 0x0c ) & 0xf )
109#define LASAT_W0_CPUCLK(v) ( ( (v) >> 0x10 ) & 0xf )
110#define LASAT_W0_SDRAMBANKSZ(v) ( ( (v) >> 0x14 ) & 0xf )
111#define LASAT_W0_SDRAMBANKS(v) ( ( (v) >> 0x18 ) & 0xf )
112#define LASAT_W0_L2CACHE(v) ( ( (v) >> 0x1c ) & 0xf )
113
114#define LASAT_W1_EDHAC(v) ( ( (v) ) & 0xf )
115#define LASAT_W1_HIFN(v) ( ( (v) >> 0x04 ) & 0x1 )
116#define LASAT_W1_ISDN(v) ( ( (v) >> 0x05 ) & 0x1 )
117#define LASAT_W1_IDE(v) ( ( (v) >> 0x06 ) & 0x1 )
118#define LASAT_W1_HDLC(v) ( ( (v) >> 0x07 ) & 0x1 )
119#define LASAT_W1_USVERSION(v) ( ( (v) >> 0x08 ) & 0x1 )
120#define LASAT_W1_4MACS(v) ( ( (v) >> 0x09 ) & 0x1 )
121#define LASAT_W1_EXTSERIAL(v) ( ( (v) >> 0x0a ) & 0x1 )
122#define LASAT_W1_FLASHSIZE(v) ( ( (v) >> 0x0c ) & 0xf )
123#define LASAT_W1_PCISLOTS(v) ( ( (v) >> 0x10 ) & 0xf )
124#define LASAT_W1_PCI1OPT(v) ( ( (v) >> 0x14 ) & 0xf )
125#define LASAT_W1_PCI2OPT(v) ( ( (v) >> 0x18 ) & 0xf )
126#define LASAT_W1_PCI3OPT(v) ( ( (v) >> 0x1c ) & 0xf )
127
128/* Routines specific to LASAT boards */
129
130#define LASAT_BMID_MASQUERADE2 0
131#define LASAT_BMID_MASQUERADEPRO 1
132#define LASAT_BMID_SAFEPIPE25 2
133#define LASAT_BMID_SAFEPIPE50 3
134#define LASAT_BMID_SAFEPIPE100 4
135#define LASAT_BMID_SAFEPIPE5000 5
136#define LASAT_BMID_SAFEPIPE7000 6
137#define LASAT_BMID_SAFEPIPE1000 7
138//#define LASAT_BMID_SAFEPIPE30 7
139//#define LASAT_BMID_SAFEPIPE5100 8
140//#define LASAT_BMID_SAFEPIPE7100 9
141#define LASAT_BMID_UNKNOWN 0xf
142#define LASAT_MAX_BMID_NAMES 9 // no larger than 15!
143
144#define LASAT_HAS_EDHAC ( 1 << 0 )
145#define LASAT_EDHAC_FAST ( 1 << 1 )
146#define LASAT_HAS_EADI ( 1 << 2 )
147#define LASAT_HAS_HIFN ( 1 << 3 )
148#define LASAT_HAS_ISDN ( 1 << 4 )
149#define LASAT_HAS_LEASEDLINE_IF ( 1 << 5 )
150#define LASAT_HAS_HDC ( 1 << 6 )
151
152#define LASAT_PRID_MASQUERADE2 0
153#define LASAT_PRID_MASQUERADEPRO 1
154#define LASAT_PRID_SAFEPIPE25 2
155#define LASAT_PRID_SAFEPIPE50 3
156#define LASAT_PRID_SAFEPIPE100 4
157#define LASAT_PRID_SAFEPIPE5000 5
158#define LASAT_PRID_SAFEPIPE7000 6
159#define LASAT_PRID_SAFEPIPE30 7
160#define LASAT_PRID_SAFEPIPE5100 8
161#define LASAT_PRID_SAFEPIPE7100 9
162
163#define LASAT_PRID_SAFEPIPE1110 10
164#define LASAT_PRID_SAFEPIPE3020 11
165#define LASAT_PRID_SAFEPIPE3030 12
166#define LASAT_PRID_SAFEPIPE5020 13
167#define LASAT_PRID_SAFEPIPE5030 14
168#define LASAT_PRID_SAFEPIPE1120 15
169#define LASAT_PRID_SAFEPIPE1130 16
170#define LASAT_PRID_SAFEPIPE6010 17
171#define LASAT_PRID_SAFEPIPE6110 18
172#define LASAT_PRID_SAFEPIPE6210 19
173#define LASAT_PRID_SAFEPIPE1020 20
174#define LASAT_PRID_SAFEPIPE1040 21
175#define LASAT_PRID_SAFEPIPE1060 22
176
177struct lasat_info {
178 unsigned int li_cpu_hz;
179 unsigned int li_bus_hz;
180 unsigned int li_bmid;
181 unsigned int li_memsize;
182 unsigned int li_flash_size;
183 unsigned int li_prid;
184 unsigned char li_bmstr[16];
185 unsigned char li_namestr[32];
186 unsigned char li_typestr[16];
187 /* Info on the Flash layout */
188 unsigned int li_flash_base;
189 unsigned long li_flashpart_base[LASAT_MTD_LAST];
190 unsigned long li_flashpart_size[LASAT_MTD_LAST];
191 struct lasat_eeprom_struct li_eeprom_info;
192 unsigned int li_eeprom_upgrade_version;
193 unsigned int li_debugaccess;
194};
195
196extern struct lasat_info lasat_board_info;
197
198static inline unsigned long lasat_flash_partition_start(int partno)
199{
200 if (partno < 0 || partno >= LASAT_MTD_LAST)
201 return 0;
202
203 return lasat_board_info.li_flashpart_base[partno];
204}
205
206static inline unsigned long lasat_flash_partition_size(int partno)
207{
208 if (partno < 0 || partno >= LASAT_MTD_LAST)
209 return 0;
210
211 return lasat_board_info.li_flashpart_size[partno];
212}
213
214/* Called from setup() to initialize the global board_info struct */
215extern int lasat_init_board_info(void);
216
217/* Write the modified EEPROM info struct */
218extern void lasat_write_eeprom_info(void);
219
220#define N_MACHTYPES 2
221/* for calibration of delays */
222
223/* the lasat_ndelay function is necessary because it is used at an
224 * early stage of the boot process where ndelay is not calibrated.
225 * It is used for the bit-banging rtc and eeprom drivers */
226
227#include <asm/delay.h>
228/* calculating with the slowest board with 100 MHz clock */
229#define LASAT_100_DIVIDER 20
230/* All 200's run at 250 MHz clock */
231#define LASAT_200_DIVIDER 8
232
233extern unsigned int lasat_ndelay_divider;
234
235static inline void lasat_ndelay(unsigned int ns)
236{
237 __delay(ns / lasat_ndelay_divider);
238}
239
240#endif /* !defined (_LANGUAGE_ASSEMBLY) */
241
242#define LASAT_SERVICEMODE_MAGIC_1 0xdeadbeef
243#define LASAT_SERVICEMODE_MAGIC_2 0xfedeabba
244
245/* Lasat 100 boards */
246#define LASAT_GT_BASE (KSEG1ADDR(0x14000000))
247
248/* Lasat 200 boards */
249#define Vrc5074_PHYS_BASE 0x1fa00000
250#define Vrc5074_BASE (KSEG1ADDR(Vrc5074_PHYS_BASE))
251#define PCI_WINDOW1 0x1a000000
252
253#endif /* _LASAT_H */
diff --git a/include/asm-mips/lasat/lasatint.h b/include/asm-mips/lasat/lasatint.h
deleted file mode 100644
index 065474feeccc..000000000000
--- a/include/asm-mips/lasat/lasatint.h
+++ /dev/null
@@ -1,12 +0,0 @@
1#define LASATINT_END 16
2
3/* lasat 100 */
4#define LASAT_INT_STATUS_REG_100 (KSEG1ADDR(0x1c880000))
5#define LASAT_INT_MASK_REG_100 (KSEG1ADDR(0x1c890000))
6#define LASATINT_MASK_SHIFT_100 0
7
8/* lasat 200 */
9#define LASAT_INT_STATUS_REG_200 (KSEG1ADDR(0x1104003c))
10#define LASAT_INT_MASK_REG_200 (KSEG1ADDR(0x1104003c))
11#define LASATINT_MASK_SHIFT_200 16
12
diff --git a/include/asm-mips/lasat/picvue.h b/include/asm-mips/lasat/picvue.h
deleted file mode 100644
index 42a492edc40e..000000000000
--- a/include/asm-mips/lasat/picvue.h
+++ /dev/null
@@ -1,15 +0,0 @@
1/* Lasat 100 */
2#define PVC_REG_100 KSEG1ADDR(0x1c820000)
3#define PVC_DATA_SHIFT_100 0
4#define PVC_DATA_M_100 0xFF
5#define PVC_E_100 (1 << 8)
6#define PVC_RW_100 (1 << 9)
7#define PVC_RS_100 (1 << 10)
8
9/* Lasat 200 */
10#define PVC_REG_200 KSEG1ADDR(0x11000000)
11#define PVC_DATA_SHIFT_200 24
12#define PVC_DATA_M_200 (0xFF << PVC_DATA_SHIFT_200)
13#define PVC_E_200 (1 << 16)
14#define PVC_RW_200 (1 << 17)
15#define PVC_RS_200 (1 << 18)
diff --git a/include/asm-mips/lasat/serial.h b/include/asm-mips/lasat/serial.h
deleted file mode 100644
index 9e88c7669c7a..000000000000
--- a/include/asm-mips/lasat/serial.h
+++ /dev/null
@@ -1,13 +0,0 @@
1#include <asm/lasat/lasat.h>
2
3/* Lasat 100 boards serial configuration */
4#define LASAT_BASE_BAUD_100 ( 7372800 / 16 )
5#define LASAT_UART_REGS_BASE_100 0x1c8b0000
6#define LASAT_UART_REGS_SHIFT_100 2
7#define LASATINT_UART_100 8
8
9/* * LASAT 200 boards serial configuration */
10#define LASAT_BASE_BAUD_200 (100000000 / 16 / 12)
11#define LASAT_UART_REGS_BASE_200 (Vrc5074_PHYS_BASE + 0x0300)
12#define LASAT_UART_REGS_SHIFT_200 3
13#define LASATINT_UART_200 13
diff --git a/include/asm-mips/mach-au1x00/au1xxx_gpio.h b/include/asm-mips/mach-au1x00/au1xxx_gpio.h
deleted file mode 100644
index 27911e054ffc..000000000000
--- a/include/asm-mips/mach-au1x00/au1xxx_gpio.h
+++ /dev/null
@@ -1,20 +0,0 @@
1#ifndef __AU1XXX_GPIO_H
2#define __AU1XXX_GPIO_H
3
4void au1xxx_gpio1_set_inputs(void);
5void au1xxx_gpio_tristate(int signal);
6void au1xxx_gpio_write(int signal, int value);
7int au1xxx_gpio_read(int signal);
8
9typedef volatile struct
10{
11 u32 dir;
12 u32 reserved;
13 u32 output;
14 u32 pinstate;
15 u32 inten;
16 u32 enable;
17
18} AU1X00_GPIO2;
19
20#endif //__AU1XXX_GPIO_H
diff --git a/include/asm-mips/mach-au1x00/au1xxx_ide.h b/include/asm-mips/mach-au1x00/au1xxx_ide.h
index 8fcae21adbd5..4663e8b415c9 100644
--- a/include/asm-mips/mach-au1x00/au1xxx_ide.h
+++ b/include/asm-mips/mach-au1x00/au1xxx_ide.h
@@ -88,26 +88,26 @@ static const struct drive_list_entry dma_white_list [] = {
88/* 88/*
89 * Hitachi 89 * Hitachi
90 */ 90 */
91 { "HITACHI_DK14FA-20" , "ALL" }, 91 { "HITACHI_DK14FA-20" , NULL },
92 { "HTS726060M9AT00" , "ALL" }, 92 { "HTS726060M9AT00" , NULL },
93/* 93/*
94 * Maxtor 94 * Maxtor
95 */ 95 */
96 { "Maxtor 6E040L0" , "ALL" }, 96 { "Maxtor 6E040L0" , NULL },
97 { "Maxtor 6Y080P0" , "ALL" }, 97 { "Maxtor 6Y080P0" , NULL },
98 { "Maxtor 6Y160P0" , "ALL" }, 98 { "Maxtor 6Y160P0" , NULL },
99/* 99/*
100 * Seagate 100 * Seagate
101 */ 101 */
102 { "ST3120026A" , "ALL" }, 102 { "ST3120026A" , NULL },
103 { "ST320014A" , "ALL" }, 103 { "ST320014A" , NULL },
104 { "ST94011A" , "ALL" }, 104 { "ST94011A" , NULL },
105 { "ST340016A" , "ALL" }, 105 { "ST340016A" , NULL },
106/* 106/*
107 * Western Digital 107 * Western Digital
108 */ 108 */
109 { "WDC WD400UE-00HCT0" , "ALL" }, 109 { "WDC WD400UE-00HCT0" , NULL },
110 { "WDC WD400JB-00JJC0" , "ALL" }, 110 { "WDC WD400JB-00JJC0" , NULL },
111 { NULL , NULL } 111 { NULL , NULL }
112}; 112};
113 113
@@ -116,9 +116,9 @@ static const struct drive_list_entry dma_black_list [] = {
116/* 116/*
117 * Western Digital 117 * Western Digital
118 */ 118 */
119 { "WDC WD100EB-00CGH0" , "ALL" }, 119 { "WDC WD100EB-00CGH0" , NULL },
120 { "WDC WD200BB-00AUA1" , "ALL" }, 120 { "WDC WD200BB-00AUA1" , NULL },
121 { "WDC AC24300L" , "ALL" }, 121 { "WDC AC24300L" , NULL },
122 { NULL , NULL } 122 { NULL , NULL }
123}; 123};
124#endif 124#endif
diff --git a/include/asm-mips/mach-au1x00/gpio.h b/include/asm-mips/mach-au1x00/gpio.h
new file mode 100644
index 000000000000..2dc61e009a08
--- /dev/null
+++ b/include/asm-mips/mach-au1x00/gpio.h
@@ -0,0 +1,69 @@
1#ifndef _AU1XXX_GPIO_H_
2#define _AU1XXX_GPIO_H_
3
4#include <linux/types.h>
5
6#define AU1XXX_GPIO_BASE 200
7
8struct au1x00_gpio2 {
9 u32 dir;
10 u32 reserved;
11 u32 output;
12 u32 pinstate;
13 u32 inten;
14 u32 enable;
15};
16
17extern int au1xxx_gpio_get_value(unsigned gpio);
18extern void au1xxx_gpio_set_value(unsigned gpio, int value);
19extern int au1xxx_gpio_direction_input(unsigned gpio);
20extern int au1xxx_gpio_direction_output(unsigned gpio, int value);
21
22
23/* Wrappers for the arch-neutral GPIO API */
24
25static inline int gpio_request(unsigned gpio, const char *label)
26{
27 /* Not yet implemented */
28 return 0;
29}
30
31static inline void gpio_free(unsigned gpio)
32{
33 /* Not yet implemented */
34}
35
36static inline int gpio_direction_input(unsigned gpio)
37{
38 return au1xxx_gpio_direction_input(gpio);
39}
40
41static inline int gpio_direction_output(unsigned gpio, int value)
42{
43 return au1xxx_gpio_direction_output(gpio, value);
44}
45
46static inline int gpio_get_value(unsigned gpio)
47{
48 return au1xxx_gpio_get_value(gpio);
49}
50
51static inline void gpio_set_value(unsigned gpio, int value)
52{
53 au1xxx_gpio_set_value(gpio, value);
54}
55
56static inline int gpio_to_irq(unsigned gpio)
57{
58 return gpio;
59}
60
61static inline int irq_to_gpio(unsigned irq)
62{
63 return irq;
64}
65
66/* For cansleep */
67#include <asm-generic/gpio.h>
68
69#endif /* _AU1XXX_GPIO_H_ */
diff --git a/include/asm-mips/mach-au1x00/ioremap.h b/include/asm-mips/mach-au1x00/ioremap.h
index 098fca4289bb..364cea2dc71f 100644
--- a/include/asm-mips/mach-au1x00/ioremap.h
+++ b/include/asm-mips/mach-au1x00/ioremap.h
@@ -28,4 +28,15 @@ static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size)
28 return __fixup_bigphys_addr(phys_addr, size); 28 return __fixup_bigphys_addr(phys_addr, size);
29} 29}
30 30
31static inline void __iomem *plat_ioremap(phys_t offset, unsigned long size,
32 unsigned long flags)
33{
34 return NULL;
35}
36
37static inline int plat_iounmap(const volatile void __iomem *addr)
38{
39 return 0;
40}
41
31#endif /* __ASM_MACH_AU1X00_IOREMAP_H */ 42#endif /* __ASM_MACH_AU1X00_IOREMAP_H */
diff --git a/include/asm-mips/mach-cobalt/cobalt.h b/include/asm-mips/mach-cobalt/cobalt.h
index 684a501c04cf..9c9d2b998ca4 100644
--- a/include/asm-mips/mach-cobalt/cobalt.h
+++ b/include/asm-mips/mach-cobalt/cobalt.h
@@ -30,7 +30,6 @@
30#define COBALT_CPU_IRQ MIPS_CPU_IRQ_BASE 30#define COBALT_CPU_IRQ MIPS_CPU_IRQ_BASE
31 31
32#define COBALT_GALILEO_IRQ (COBALT_CPU_IRQ + 2) 32#define COBALT_GALILEO_IRQ (COBALT_CPU_IRQ + 2)
33#define COBALT_SCC_IRQ (COBALT_CPU_IRQ + 3) /* pre-production has 85C30 */
34#define COBALT_RAQ_SCSI_IRQ (COBALT_CPU_IRQ + 3) 33#define COBALT_RAQ_SCSI_IRQ (COBALT_CPU_IRQ + 3)
35#define COBALT_ETH0_IRQ (COBALT_CPU_IRQ + 3) 34#define COBALT_ETH0_IRQ (COBALT_CPU_IRQ + 3)
36#define COBALT_QUBE1_ETH0_IRQ (COBALT_CPU_IRQ + 4) 35#define COBALT_QUBE1_ETH0_IRQ (COBALT_CPU_IRQ + 4)
@@ -71,10 +70,6 @@
71 70
72extern int cobalt_board_id; 71extern int cobalt_board_id;
73 72
74#define PCI_CFG_SET(devfn,where) \
75 GT_WRITE(GT_PCI0_CFGADDR_OFS, (0x80000000 | (PCI_SLOT (devfn) << 11) | \
76 (PCI_FUNC (devfn) << 8) | (where)))
77
78#define COBALT_LED_PORT (*(volatile unsigned char *) CKSEG1ADDR(0x1c000000)) 73#define COBALT_LED_PORT (*(volatile unsigned char *) CKSEG1ADDR(0x1c000000))
79# define COBALT_LED_BAR_LEFT (1 << 0) /* Qube */ 74# define COBALT_LED_BAR_LEFT (1 << 0) /* Qube */
80# define COBALT_LED_BAR_RIGHT (1 << 1) /* Qube */ 75# define COBALT_LED_BAR_RIGHT (1 << 1) /* Qube */
diff --git a/include/asm-mips/mach-ev64120/mach-gt64120.h b/include/asm-mips/mach-ev64120/mach-gt64120.h
deleted file mode 100644
index 7e272ce57ea3..000000000000
--- a/include/asm-mips/mach-ev64120/mach-gt64120.h
+++ /dev/null
@@ -1,62 +0,0 @@
1/*
2 * This is a direct copy of the ev96100.h file, with a global
3 * search and replace. The numbers are the same.
4 *
5 * The reason I'm duplicating this is so that the 64120/96100
6 * defines won't be confusing in the source code.
7 */
8#ifndef __ASM_GALILEO_BOARDS_MIPS_EV64120_H
9#define __ASM_GALILEO_BOARDS_MIPS_EV64120_H
10
11/*
12 * GT64120 config space base address
13 */
14extern unsigned long gt64120_base;
15
16#define GT64120_BASE (gt64120_base)
17
18/*
19 * PCI Bus allocation
20 */
21#define GT_PCI_MEM_BASE 0x12000000UL
22#define GT_PCI_MEM_SIZE 0x02000000UL
23#define GT_PCI_IO_BASE 0x10000000UL
24#define GT_PCI_IO_SIZE 0x02000000UL
25#define GT_ISA_IO_BASE PCI_IO_BASE
26
27/*
28 * Duart I/O ports.
29 */
30#define EV64120_COM1_BASE_ADDR (0x1d000000 + 0x20)
31#define EV64120_COM2_BASE_ADDR (0x1d000000 + 0x00)
32
33
34/*
35 * EV64120 interrupt controller register base.
36 */
37#define EV64120_ICTRL_REGS_BASE (KSEG1ADDR(0x1f000000))
38
39/*
40 * EV64120 UART register base.
41 */
42#define EV64120_UART0_REGS_BASE (KSEG1ADDR(EV64120_COM1_BASE_ADDR))
43#define EV64120_UART1_REGS_BASE (KSEG1ADDR(EV64120_COM2_BASE_ADDR))
44#define EV64120_BASE_BAUD ( 3686400 / 16 )
45#define EV64120_UART_IRQ 6
46
47/*
48 * PCI interrupts will come in on either the INTA or INTD interrups lines,
49 * which are mapped to the #2 and #5 interrupt pins of the MIPS. On our
50 * boards, they all either come in on IntD or they all come in on IntA, they
51 * aren't mixed. There can be numerous PCI interrupts, so we keep a list of the
52 * "requested" interrupt numbers and go through the list whenever we get an
53 * IntA/D.
54 *
55 * Interrupts < 8 are directly wired to the processor; PCI INTA is 8 and
56 * INTD is 11.
57 */
58#define GT_TIMER 4
59#define GT_INTA 2
60#define GT_INTD 5
61
62#endif /* __ASM_GALILEO_BOARDS_MIPS_EV64120_H */
diff --git a/include/asm-mips/mach-generic/gpio.h b/include/asm-mips/mach-generic/gpio.h
new file mode 100644
index 000000000000..6eaf5efedf3a
--- /dev/null
+++ b/include/asm-mips/mach-generic/gpio.h
@@ -0,0 +1,15 @@
1#ifndef __ASM_MACH_GENERIC_GPIO_H
2#define __ASM_MACH_GENERIC_GPIO_H
3
4int gpio_request(unsigned gpio, const char *label);
5void gpio_free(unsigned gpio);
6int gpio_direction_input(unsigned gpio);
7int gpio_direction_output(unsigned gpio, int value);
8int gpio_get_value(unsigned gpio);
9void gpio_set_value(unsigned gpio, int value);
10int gpio_to_irq(unsigned gpio);
11int irq_to_gpio(unsigned irq);
12
13#include <asm-generic/gpio.h> /* cansleep wrappers */
14
15#endif /* __ASM_MACH_GENERIC_GPIO_H */
diff --git a/include/asm-mips/mach-generic/ioremap.h b/include/asm-mips/mach-generic/ioremap.h
index 9b64ff6e485d..b379938d47f0 100644
--- a/include/asm-mips/mach-generic/ioremap.h
+++ b/include/asm-mips/mach-generic/ioremap.h
@@ -20,4 +20,15 @@ static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size)
20 return phys_addr; 20 return phys_addr;
21} 21}
22 22
23static inline void __iomem *plat_ioremap(phys_t offset, unsigned long size,
24 unsigned long flags)
25{
26 return NULL;
27}
28
29static inline int plat_iounmap(const volatile void __iomem *addr)
30{
31 return 0;
32}
33
23#endif /* __ASM_MACH_GENERIC_IOREMAP_H */ 34#endif /* __ASM_MACH_GENERIC_IOREMAP_H */
diff --git a/include/asm-mips/mach-generic/spaces.h b/include/asm-mips/mach-generic/spaces.h
index 0ae9997bc9a8..c9fa4b14968d 100644
--- a/include/asm-mips/mach-generic/spaces.h
+++ b/include/asm-mips/mach-generic/spaces.h
@@ -10,38 +10,54 @@
10#ifndef _ASM_MACH_GENERIC_SPACES_H 10#ifndef _ASM_MACH_GENERIC_SPACES_H
11#define _ASM_MACH_GENERIC_SPACES_H 11#define _ASM_MACH_GENERIC_SPACES_H
12 12
13#include <linux/const.h>
14
15/*
16 * This gives the physical RAM offset.
17 */
18#ifndef PHYS_OFFSET
19#define PHYS_OFFSET _AC(0, UL)
20#endif
13 21
14#ifdef CONFIG_32BIT 22#ifdef CONFIG_32BIT
15 23
16#define CAC_BASE 0x80000000 24#define CAC_BASE _AC(0x80000000, UL)
17#define IO_BASE 0xa0000000 25#define IO_BASE _AC(0xa0000000, UL)
18#define UNCAC_BASE 0xa0000000 26#define UNCAC_BASE _AC(0xa0000000, UL)
19#define MAP_BASE 0xc0000000
20 27
21/* 28#ifndef MAP_BASE
22 * This handles the memory map. 29#define MAP_BASE _AC(0xc0000000, UL)
23 * We handle pages at KSEG0 for kernels with 32 bit address space. 30#endif
24 */
25#define PAGE_OFFSET 0x80000000UL
26 31
27/* 32/*
28 * Memory above this physical address will be considered highmem. 33 * Memory above this physical address will be considered highmem.
29 */ 34 */
30#ifndef HIGHMEM_START 35#ifndef HIGHMEM_START
31#define HIGHMEM_START 0x20000000UL 36#define HIGHMEM_START _AC(0x20000000, UL)
32#endif 37#endif
33 38
34#endif /* CONFIG_32BIT */ 39#endif /* CONFIG_32BIT */
35 40
36#ifdef CONFIG_64BIT 41#ifdef CONFIG_64BIT
37 42
38/* 43#ifndef CAC_BASE
39 * This handles the memory map.
40 */
41#ifdef CONFIG_DMA_NONCOHERENT 44#ifdef CONFIG_DMA_NONCOHERENT
42#define PAGE_OFFSET 0x9800000000000000UL 45#define CAC_BASE _AC(0x9800000000000000, UL)
43#else 46#else
44#define PAGE_OFFSET 0xa800000000000000UL 47#define CAC_BASE _AC(0xa800000000000000, UL)
48#endif
49#endif
50
51#ifndef IO_BASE
52#define IO_BASE _AC(0x9000000000000000, UL)
53#endif
54
55#ifndef UNCAC_BASE
56#define UNCAC_BASE _AC(0x9000000000000000, UL)
57#endif
58
59#ifndef MAP_BASE
60#define MAP_BASE _AC(0xc000000000000000, UL)
45#endif 61#endif
46 62
47/* 63/*
@@ -50,22 +66,20 @@
50 * in the distant future. Nobody will care for a few years :-) 66 * in the distant future. Nobody will care for a few years :-)
51 */ 67 */
52#ifndef HIGHMEM_START 68#ifndef HIGHMEM_START
53#define HIGHMEM_START (1UL << 59UL) 69#define HIGHMEM_START (_AC(1, UL) << _AC(59, UL))
54#endif 70#endif
55 71
56#ifdef CONFIG_DMA_NONCOHERENT
57#define CAC_BASE 0x9800000000000000UL
58#else
59#define CAC_BASE 0xa800000000000000UL
60#endif
61#define IO_BASE 0x9000000000000000UL
62#define UNCAC_BASE 0x9000000000000000UL
63#define MAP_BASE 0xc000000000000000UL
64
65#define TO_PHYS(x) ( ((x) & TO_PHYS_MASK)) 72#define TO_PHYS(x) ( ((x) & TO_PHYS_MASK))
66#define TO_CAC(x) (CAC_BASE | ((x) & TO_PHYS_MASK)) 73#define TO_CAC(x) (CAC_BASE | ((x) & TO_PHYS_MASK))
67#define TO_UNCAC(x) (UNCAC_BASE | ((x) & TO_PHYS_MASK)) 74#define TO_UNCAC(x) (UNCAC_BASE | ((x) & TO_PHYS_MASK))
68 75
69#endif /* CONFIG_64BIT */ 76#endif /* CONFIG_64BIT */
70 77
78/*
79 * This handles the memory map.
80 */
81#ifndef PAGE_OFFSET
82#define PAGE_OFFSET (CAC_BASE + PHYS_OFFSET)
83#endif
84
71#endif /* __ASM_MACH_GENERIC_SPACES_H */ 85#endif /* __ASM_MACH_GENERIC_SPACES_H */
diff --git a/include/asm-mips/mach-ip22/spaces.h b/include/asm-mips/mach-ip22/spaces.h
index ab20c026fd19..7f9fa6f66059 100644
--- a/include/asm-mips/mach-ip22/spaces.h
+++ b/include/asm-mips/mach-ip22/spaces.h
@@ -11,44 +11,17 @@
11#define _ASM_MACH_IP22_SPACES_H 11#define _ASM_MACH_IP22_SPACES_H
12 12
13 13
14#ifdef CONFIG_32BIT
15
16#define CAC_BASE 0x80000000
17#define IO_BASE 0xa0000000
18#define UNCAC_BASE 0xa0000000
19#define MAP_BASE 0xc0000000
20
21/*
22 * This handles the memory map.
23 * We handle pages at KSEG0 for kernels with 32 bit address space.
24 */
25#define PAGE_OFFSET 0x80000000UL
26
27/*
28 * Memory above this physical address will be considered highmem.
29 */
30#ifndef HIGHMEM_START
31#define HIGHMEM_START 0x20000000UL
32#endif
33
34#endif /* CONFIG_32BIT */
35
36#ifdef CONFIG_64BIT 14#ifdef CONFIG_64BIT
37#define PAGE_OFFSET 0xffffffff80000000UL
38 15
39#ifndef HIGHMEM_START 16#define PAGE_OFFSET 0xffffffff80000000UL
40#define HIGHMEM_START (1UL << 59UL)
41#endif
42 17
43#define CAC_BASE 0xffffffff80000000 18#define CAC_BASE 0xffffffff80000000
44#define IO_BASE 0xffffffffa0000000 19#define IO_BASE 0xffffffffa0000000
45#define UNCAC_BASE 0xffffffffa0000000 20#define UNCAC_BASE 0xffffffffa0000000
46#define MAP_BASE 0xc000000000000000 21#define MAP_BASE 0xc000000000000000
47 22
48#define TO_PHYS(x) ( ((x) & TO_PHYS_MASK))
49#define TO_CAC(x) (CAC_BASE | ((x) & TO_PHYS_MASK))
50#define TO_UNCAC(x) (UNCAC_BASE | ((x) & TO_PHYS_MASK))
51
52#endif /* CONFIG_64BIT */ 23#endif /* CONFIG_64BIT */
53 24
25#include <asm/mach-generic/spaces.h>
26
54#endif /* __ASM_MACH_IP22_SPACES_H */ 27#endif /* __ASM_MACH_IP22_SPACES_H */
diff --git a/include/asm-mips/mach-ip27/spaces.h b/include/asm-mips/mach-ip27/spaces.h
index 45e61785ef42..b18802a0b17e 100644
--- a/include/asm-mips/mach-ip27/spaces.h
+++ b/include/asm-mips/mach-ip27/spaces.h
@@ -14,22 +14,17 @@
14 * IP27 uses the R10000's uncached attribute feature. Attribute 3 selects 14 * IP27 uses the R10000's uncached attribute feature. Attribute 3 selects
15 * uncached memory addressing. 15 * uncached memory addressing.
16 */ 16 */
17#define CAC_BASE 0xa800000000000000
18 17
19#define HSPEC_BASE 0x9000000000000000 18#define HSPEC_BASE 0x9000000000000000
20#define IO_BASE 0x9200000000000000 19#define IO_BASE 0x9200000000000000
21#define MSPEC_BASE 0x9400000000000000 20#define MSPEC_BASE 0x9400000000000000
22#define UNCAC_BASE 0x9600000000000000 21#define UNCAC_BASE 0x9600000000000000
23#define MAP_BASE 0xc000000000000000
24 22
25#define TO_PHYS(x) ( ((x) & TO_PHYS_MASK))
26#define TO_CAC(x) (CAC_BASE | ((x) & TO_PHYS_MASK))
27#define TO_UNCAC(x) (UNCAC_BASE | ((x) & TO_PHYS_MASK))
28#define TO_MSPEC(x) (MSPEC_BASE | ((x) & TO_PHYS_MASK)) 23#define TO_MSPEC(x) (MSPEC_BASE | ((x) & TO_PHYS_MASK))
29#define TO_HSPEC(x) (HSPEC_BASE | ((x) & TO_PHYS_MASK)) 24#define TO_HSPEC(x) (HSPEC_BASE | ((x) & TO_PHYS_MASK))
30 25
31#define PAGE_OFFSET CAC_BASE
32
33#define HIGHMEM_START (~0UL) 26#define HIGHMEM_START (~0UL)
34 27
28#include <asm/mach-generic/spaces.h>
29
35#endif /* _ASM_MACH_IP27_SPACES_H */ 30#endif /* _ASM_MACH_IP27_SPACES_H */
diff --git a/include/asm-mips/mach-ip32/spaces.h b/include/asm-mips/mach-ip32/spaces.h
deleted file mode 100644
index 44abe5c02389..000000000000
--- a/include/asm-mips/mach-ip32/spaces.h
+++ /dev/null
@@ -1,36 +0,0 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 1994 - 1999, 2000, 03, 04, 05 Ralf Baechle (ralf@linux-mips.org)
7 * Copyright (C) 2000, 2002 Maciej W. Rozycki
8 * Copyright (C) 1990, 1999, 2000 Silicon Graphics, Inc.
9 */
10#ifndef _ASM_MACH_IP32_SPACES_H
11#define _ASM_MACH_IP32_SPACES_H
12
13/*
14 * Memory above this physical address will be considered highmem.
15 * Fixme: 59 bits is a fictive number and makes assumptions about processors
16 * in the distant future. Nobody will care for a few years :-)
17 */
18#ifndef HIGHMEM_START
19#define HIGHMEM_START (1UL << 59UL)
20#endif
21
22#define CAC_BASE 0x9800000000000000UL
23#define IO_BASE 0x9000000000000000UL
24#define UNCAC_BASE 0x9000000000000000UL
25#define MAP_BASE 0xc000000000000000UL
26
27#define TO_PHYS(x) ( ((x) & TO_PHYS_MASK))
28#define TO_CAC(x) (CAC_BASE | ((x) & TO_PHYS_MASK))
29#define TO_UNCAC(x) (UNCAC_BASE | ((x) & TO_PHYS_MASK))
30
31/*
32 * This handles the memory map.
33 */
34#define PAGE_OFFSET CAC_BASE
35
36#endif /* __ASM_MACH_IP32_SPACES_H */
diff --git a/include/asm-mips/mach-jmr3927/ioremap.h b/include/asm-mips/mach-jmr3927/ioremap.h
new file mode 100644
index 000000000000..aa131ad7f717
--- /dev/null
+++ b/include/asm-mips/mach-jmr3927/ioremap.h
@@ -0,0 +1,38 @@
1/*
2 * include/asm-mips/mach-jmr3927/ioremap.h
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 */
9#ifndef __ASM_MACH_JMR3927_IOREMAP_H
10#define __ASM_MACH_JMR3927_IOREMAP_H
11
12#include <linux/types.h>
13
14/*
15 * Allow physical addresses to be fixed up to help peripherals located
16 * outside the low 32-bit range -- generic pass-through version.
17 */
18static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size)
19{
20 return phys_addr;
21}
22
23static inline void __iomem *plat_ioremap(phys_t offset, unsigned long size,
24 unsigned long flags)
25{
26#define TXX9_DIRECTMAP_BASE 0xff000000ul
27 if (offset >= TXX9_DIRECTMAP_BASE &&
28 offset < TXX9_DIRECTMAP_BASE + 0xf0000)
29 return (void __iomem *)offset;
30 return NULL;
31}
32
33static inline int plat_iounmap(const volatile void __iomem *addr)
34{
35 return (unsigned long)addr >= TXX9_DIRECTMAP_BASE;
36}
37
38#endif /* __ASM_MACH_JMR3927_IOREMAP_H */
diff --git a/include/asm-mips/mach-lasat/mach-gt64120.h b/include/asm-mips/mach-lasat/mach-gt64120.h
deleted file mode 100644
index 1a9ad45cc135..000000000000
--- a/include/asm-mips/mach-lasat/mach-gt64120.h
+++ /dev/null
@@ -1,27 +0,0 @@
1/*
2 * This is a direct copy of the ev96100.h file, with a global
3 * search and replace. The numbers are the same.
4 *
5 * The reason I'm duplicating this is so that the 64120/96100
6 * defines won't be confusing in the source code.
7 */
8#ifndef _ASM_GT64120_LASAT_GT64120_DEP_H
9#define _ASM_GT64120_LASAT_GT64120_DEP_H
10
11/*
12 * GT64120 config space base address on Lasat 100
13 */
14#define GT64120_BASE (KSEG1ADDR(0x14000000))
15
16/*
17 * PCI Bus allocation
18 *
19 * (Guessing ...)
20 */
21#define GT_PCI_MEM_BASE 0x12000000UL
22#define GT_PCI_MEM_SIZE 0x02000000UL
23#define GT_PCI_IO_BASE 0x10000000UL
24#define GT_PCI_IO_SIZE 0x02000000UL
25#define GT_ISA_IO_BASE PCI_IO_BASE
26
27#endif /* _ASM_GT64120_LASAT_GT64120_DEP_H */
diff --git a/include/asm-mips/mach-lemote/dma-coherence.h b/include/asm-mips/mach-lemote/dma-coherence.h
new file mode 100644
index 000000000000..7e914777ebc4
--- /dev/null
+++ b/include/asm-mips/mach-lemote/dma-coherence.h
@@ -0,0 +1,42 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2006, 07 Ralf Baechle <ralf@linux-mips.org>
7 * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology
8 * Author: Fuxin Zhang, zhangfx@lemote.com
9 *
10 */
11#ifndef __ASM_MACH_LEMOTE_DMA_COHERENCE_H
12#define __ASM_MACH_LEMOTE_DMA_COHERENCE_H
13
14struct device;
15
16static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr,
17 size_t size)
18{
19 return virt_to_phys(addr) | 0x80000000;
20}
21
22static inline dma_addr_t plat_map_dma_mem_page(struct device *dev,
23 struct page *page)
24{
25 return page_to_phys(page) | 0x80000000;
26}
27
28static inline unsigned long plat_dma_addr_to_phys(dma_addr_t dma_addr)
29{
30 return dma_addr & 0x7fffffff;
31}
32
33static inline void plat_unmap_dma_mem(dma_addr_t dma_addr)
34{
35}
36
37static inline int plat_device_is_coherent(struct device *dev)
38{
39 return 0;
40}
41
42#endif /* __ASM_MACH_LEMOTE_DMA_COHERENCE_H */
diff --git a/include/asm-mips/mach-lemote/mc146818rtc.h b/include/asm-mips/mach-lemote/mc146818rtc.h
new file mode 100644
index 000000000000..ed5147e11085
--- /dev/null
+++ b/include/asm-mips/mach-lemote/mc146818rtc.h
@@ -0,0 +1,36 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 1998, 2001, 03, 07 by Ralf Baechle (ralf@linux-mips.org)
7 *
8 * RTC routines for PC style attached Dallas chip.
9 */
10#ifndef __ASM_MACH_LEMOTE_MC146818RTC_H
11#define __ASM_MACH_LEMOTE_MC146818RTC_H
12
13#include <linux/io.h>
14
15#define RTC_PORT(x) (0x70 + (x))
16#define RTC_IRQ 8
17
18static inline unsigned char CMOS_READ(unsigned long addr)
19{
20 outb_p(addr, RTC_PORT(0));
21 return inb_p(RTC_PORT(1));
22}
23
24static inline void CMOS_WRITE(unsigned char data, unsigned long addr)
25{
26 outb_p(addr, RTC_PORT(0));
27 outb_p(data, RTC_PORT(1));
28}
29
30#define RTC_ALWAYS_BCD 0
31
32#ifndef mc146818_decode_year
33#define mc146818_decode_year(year) ((year) < 70 ? (year) + 2000 : (year) + 1970)
34#endif
35
36#endif /* __ASM_MACH_LEMOTE_MC146818RTC_H */
diff --git a/include/asm-mips/mach-mips/kernel-entry-init.h b/include/asm-mips/mach-mips/kernel-entry-init.h
new file mode 100644
index 000000000000..0b793e7bf67e
--- /dev/null
+++ b/include/asm-mips/mach-mips/kernel-entry-init.h
@@ -0,0 +1,52 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Chris Dearman (chris@mips.com)
7 * Copyright (C) 2007 Mips Technologies, Inc.
8 */
9#ifndef __ASM_MACH_MIPS_KERNEL_ENTRY_INIT_H
10#define __ASM_MACH_MIPS_KERNEL_ENTRY_INIT_H
11
12 .macro kernel_entry_setup
13#ifdef CONFIG_MIPS_MT_SMTC
14 mfc0 t0, CP0_CONFIG
15 bgez t0, 9f
16 mfc0 t0, CP0_CONFIG, 1
17 bgez t0, 9f
18 mfc0 t0, CP0_CONFIG, 2
19 bgez t0, 9f
20 mfc0 t0, CP0_CONFIG, 3
21 and t0, 1<<2
22 bnez t0, 0f
239:
24 /* Assume we came from YAMON... */
25 PTR_LA v0, 0x9fc00534 /* YAMON print */
26 lw v0, (v0)
27 move a0, zero
28 PTR_LA a1, nonmt_processor
29 jal v0
30
31 PTR_LA v0, 0x9fc00520 /* YAMON exit */
32 lw v0, (v0)
33 li a0, 1
34 jal v0
35
361: b 1b
37
38 __INITDATA
39nonmt_processor:
40 .asciz "SMTC kernel requires the MT ASE to run\n"
41 __FINIT
420:
43#endif
44 .endm
45
46/*
47 * Do SMP slave processor setup necessary before we can safely execute C code.
48 */
49 .macro smp_slave_setup
50 .endm
51
52#endif /* __ASM_MACH_MIPS_KERNEL_ENTRY_INIT_H */
diff --git a/include/asm-mips/mach-sim/cpu-feature-overrides.h b/include/asm-mips/mach-mipssim/cpu-feature-overrides.h
index 779b02205737..779b02205737 100644
--- a/include/asm-mips/mach-sim/cpu-feature-overrides.h
+++ b/include/asm-mips/mach-mipssim/cpu-feature-overrides.h
diff --git a/include/asm-mips/mach-ocelot3/cpu-feature-overrides.h b/include/asm-mips/mach-ocelot3/cpu-feature-overrides.h
deleted file mode 100644
index 57a12ded0613..000000000000
--- a/include/asm-mips/mach-ocelot3/cpu-feature-overrides.h
+++ /dev/null
@@ -1,48 +0,0 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2004 MontaVista Software Inc.
7 * Author: Manish Lachwani, mlachwani@mvista.com
8 * Copyright (C) 2004 Ralf Baechle
9 */
10#ifndef __ASM_MACH_JA_CPU_FEATURE_OVERRIDES_H
11#define __ASM_MACH_JA_CPU_FEATURE_OVERRIDES_H
12
13/*
14 * Momentum Ocelot-3 is based on Rm7900 processor which
15 * is based on the E9000 core.
16 */
17#define cpu_has_watch 1
18#define cpu_has_mips16 0
19#define cpu_has_divec 0
20#define cpu_has_vce 0
21#define cpu_has_cache_cdex_p 0
22#define cpu_has_cache_cdex_s 0
23#define cpu_has_prefetch 1
24#define cpu_has_mcheck 0
25#define cpu_has_ejtag 0
26
27#define cpu_has_llsc 1
28#define cpu_has_vtag_icache 0
29#define cpu_has_dc_aliases 0
30#define cpu_has_ic_fills_f_dc 0
31#define cpu_has_dsp 0
32#define cpu_icache_snoops_remote_store 0
33
34#define cpu_has_nofpuex 0
35#define cpu_has_64bits 1
36
37#define cpu_has_inclusive_pcaches 0
38
39#define cpu_dcache_line_size() 32
40#define cpu_icache_line_size() 32
41#define cpu_scache_line_size() 32
42
43#define cpu_has_mips32r1 0
44#define cpu_has_mips32r2 0
45#define cpu_has_mips64r1 0
46#define cpu_has_mips64r2 0
47
48#endif /* __ASM_MACH_JA_CPU_FEATURE_OVERRIDES_H */
diff --git a/include/asm-mips/mach-tx49xx/ioremap.h b/include/asm-mips/mach-tx49xx/ioremap.h
new file mode 100644
index 000000000000..88cf546719b8
--- /dev/null
+++ b/include/asm-mips/mach-tx49xx/ioremap.h
@@ -0,0 +1,42 @@
1/*
2 * include/asm-mips/mach-tx49xx/ioremap.h
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 */
9#ifndef __ASM_MACH_TX49XX_IOREMAP_H
10#define __ASM_MACH_TX49XX_IOREMAP_H
11
12#include <linux/types.h>
13
14/*
15 * Allow physical addresses to be fixed up to help peripherals located
16 * outside the low 32-bit range -- generic pass-through version.
17 */
18static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size)
19{
20 return phys_addr;
21}
22
23static inline void __iomem *plat_ioremap(phys_t offset, unsigned long size,
24 unsigned long flags)
25{
26#ifdef CONFIG_64BIT
27#define TXX9_DIRECTMAP_BASE 0xfff000000ul
28#else
29#define TXX9_DIRECTMAP_BASE 0xff000000ul
30#endif
31 if (offset >= TXX9_DIRECTMAP_BASE &&
32 offset < TXX9_DIRECTMAP_BASE + 0x400000)
33 return (void __iomem *)(unsigned long)(int)offset;
34 return NULL;
35}
36
37static inline int plat_iounmap(const volatile void __iomem *addr)
38{
39 return (unsigned long)addr >= (unsigned long)(int)TXX9_DIRECTMAP_BASE;
40}
41
42#endif /* __ASM_MACH_TX49XX_IOREMAP_H */
diff --git a/include/asm-mips/mips-boards/bonito64.h b/include/asm-mips/mips-boards/bonito64.h
index cd7125610100..dc3fc32eedd8 100644
--- a/include/asm-mips/mips-boards/bonito64.h
+++ b/include/asm-mips/mips-boards/bonito64.h
@@ -26,7 +26,12 @@
26/* offsets from base register */ 26/* offsets from base register */
27#define BONITO(x) (x) 27#define BONITO(x) (x)
28 28
29#else /* !__ASSEMBLY__ */ 29#elif defined(CONFIG_LEMOTE_FULONG)
30
31#define BONITO(x) (*(volatile u32 *)((char *)CKSEG1ADDR(BONITO_REG_BASE) + (x)))
32#define BONITO_IRQ_BASE 32
33
34#else
30 35
31/* 36/*
32 * Algorithmics Bonito64 system controller register base. 37 * Algorithmics Bonito64 system controller register base.
diff --git a/include/asm-mips/mipsregs.h b/include/asm-mips/mipsregs.h
index 89c81922d47c..706b3691f57e 100644
--- a/include/asm-mips/mipsregs.h
+++ b/include/asm-mips/mipsregs.h
@@ -7,7 +7,7 @@
7 * Copyright (C) 2000 Silicon Graphics, Inc. 7 * Copyright (C) 2000 Silicon Graphics, Inc.
8 * Modified for further R[236]000 support by Paul M. Antoine, 1996. 8 * Modified for further R[236]000 support by Paul M. Antoine, 1996.
9 * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com 9 * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
10 * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. 10 * Copyright (C) 2000, 07 MIPS Technologies, Inc.
11 * Copyright (C) 2003, 2004 Maciej W. Rozycki 11 * Copyright (C) 2003, 2004 Maciej W. Rozycki
12 */ 12 */
13#ifndef _ASM_MIPSREGS_H 13#ifndef _ASM_MIPSREGS_H
@@ -15,6 +15,7 @@
15 15
16#include <linux/linkage.h> 16#include <linux/linkage.h>
17#include <asm/hazards.h> 17#include <asm/hazards.h>
18#include <asm/war.h>
18 19
19/* 20/*
20 * The following macros are especially useful for __asm__ 21 * The following macros are especially useful for __asm__
@@ -533,9 +534,13 @@
533#define MIPS_CONF3_VEIC (_ULCAST_(1) << 6) 534#define MIPS_CONF3_VEIC (_ULCAST_(1) << 6)
534#define MIPS_CONF3_LPA (_ULCAST_(1) << 7) 535#define MIPS_CONF3_LPA (_ULCAST_(1) << 7)
535#define MIPS_CONF3_DSP (_ULCAST_(1) << 10) 536#define MIPS_CONF3_DSP (_ULCAST_(1) << 10)
537#define MIPS_CONF3_ULRI (_ULCAST_(1) << 13)
536 538
537#define MIPS_CONF7_WII (_ULCAST_(1) << 31) 539#define MIPS_CONF7_WII (_ULCAST_(1) << 31)
538 540
541#define MIPS_CONF7_RPS (_ULCAST_(1) << 2)
542
543
539/* 544/*
540 * Bits in the MIPS32/64 coprocessor 1 (FPU) revision register. 545 * Bits in the MIPS32/64 coprocessor 1 (FPU) revision register.
541 */ 546 */
@@ -772,6 +777,9 @@ do { \
772#define read_c0_context() __read_ulong_c0_register($4, 0) 777#define read_c0_context() __read_ulong_c0_register($4, 0)
773#define write_c0_context(val) __write_ulong_c0_register($4, 0, val) 778#define write_c0_context(val) __write_ulong_c0_register($4, 0, val)
774 779
780#define read_c0_userlocal() __read_ulong_c0_register($4, 2)
781#define write_c0_userlocal(val) __write_ulong_c0_register($4, 2, val)
782
775#define read_c0_pagemask() __read_32bit_c0_register($5, 0) 783#define read_c0_pagemask() __read_32bit_c0_register($5, 0)
776#define write_c0_pagemask(val) __write_32bit_c0_register($5, 0, val) 784#define write_c0_pagemask(val) __write_32bit_c0_register($5, 0, val)
777 785
@@ -1294,10 +1302,39 @@ static inline void tlb_probe(void)
1294 1302
1295static inline void tlb_read(void) 1303static inline void tlb_read(void)
1296{ 1304{
1305#if MIPS34K_MISSED_ITLB_WAR
1306 int res = 0;
1307
1308 __asm__ __volatile__(
1309 " .set push \n"
1310 " .set noreorder \n"
1311 " .set noat \n"
1312 " .set mips32r2 \n"
1313 " .word 0x41610001 # dvpe $1 \n"
1314 " move %0, $1 \n"
1315 " ehb \n"
1316 " .set pop \n"
1317 : "=r" (res));
1318
1319 instruction_hazard();
1320#endif
1321
1297 __asm__ __volatile__( 1322 __asm__ __volatile__(
1298 ".set noreorder\n\t" 1323 ".set noreorder\n\t"
1299 "tlbr\n\t" 1324 "tlbr\n\t"
1300 ".set reorder"); 1325 ".set reorder");
1326
1327#if MIPS34K_MISSED_ITLB_WAR
1328 if ((res & _ULCAST_(1)))
1329 __asm__ __volatile__(
1330 " .set push \n"
1331 " .set noreorder \n"
1332 " .set noat \n"
1333 " .set mips32r2 \n"
1334 " .word 0x41600021 # evpe \n"
1335 " ehb \n"
1336 " .set pop \n");
1337#endif
1301} 1338}
1302 1339
1303static inline void tlb_write_indexed(void) 1340static inline void tlb_write_indexed(void)
diff --git a/include/asm-mips/module.h b/include/asm-mips/module.h
index c5ef324fd69f..de6d09ebbd80 100644
--- a/include/asm-mips/module.h
+++ b/include/asm-mips/module.h
@@ -112,6 +112,8 @@ search_module_dbetables(unsigned long addr)
112#define MODULE_PROC_FAMILY "RM9000 " 112#define MODULE_PROC_FAMILY "RM9000 "
113#elif defined CONFIG_CPU_SB1 113#elif defined CONFIG_CPU_SB1
114#define MODULE_PROC_FAMILY "SB1 " 114#define MODULE_PROC_FAMILY "SB1 "
115#elif defined CONFIG_CPU_LOONGSON2
116#define MODULE_PROC_FAMILY "LOONGSON2 "
115#else 117#else
116#error MODULE_PROC_FAMILY undefined for your processor configuration 118#error MODULE_PROC_FAMILY undefined for your processor configuration
117#endif 119#endif
diff --git a/include/asm-mips/nile4.h b/include/asm-mips/nile4.h
deleted file mode 100644
index c3ca959aa4d9..000000000000
--- a/include/asm-mips/nile4.h
+++ /dev/null
@@ -1,310 +0,0 @@
1/*
2 * asm-mips/nile4.h -- NEC Vrc-5074 Nile 4 definitions
3 *
4 * Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com>
5 * Sony Software Development Center Europe (SDCE), Brussels
6 *
7 * This file is based on the following documentation:
8 *
9 * NEC Vrc 5074 System Controller Data Sheet, June 1998
10 */
11
12#ifndef _ASM_NILE4_H
13#define _ASM_NILE4_H
14
15#define NILE4_BASE 0xbfa00000
16#define NILE4_SIZE 0x00200000 /* 2 MB */
17
18
19 /*
20 * Physical Device Address Registers (PDARs)
21 */
22
23#define NILE4_SDRAM0 0x0000 /* SDRAM Bank 0 [R/W] */
24#define NILE4_SDRAM1 0x0008 /* SDRAM Bank 1 [R/W] */
25#define NILE4_DCS2 0x0010 /* Device Chip-Select 2 [R/W] */
26#define NILE4_DCS3 0x0018 /* Device Chip-Select 3 [R/W] */
27#define NILE4_DCS4 0x0020 /* Device Chip-Select 4 [R/W] */
28#define NILE4_DCS5 0x0028 /* Device Chip-Select 5 [R/W] */
29#define NILE4_DCS6 0x0030 /* Device Chip-Select 6 [R/W] */
30#define NILE4_DCS7 0x0038 /* Device Chip-Select 7 [R/W] */
31#define NILE4_DCS8 0x0040 /* Device Chip-Select 8 [R/W] */
32#define NILE4_PCIW0 0x0060 /* PCI Address Window 0 [R/W] */
33#define NILE4_PCIW1 0x0068 /* PCI Address Window 1 [R/W] */
34#define NILE4_INTCS 0x0070 /* Controller Internal Registers and Devices */
35 /* [R/W] */
36#define NILE4_BOOTCS 0x0078 /* Boot ROM Chip-Select [R/W] */
37
38
39 /*
40 * CPU Interface Registers
41 */
42
43#define NILE4_CPUSTAT 0x0080 /* CPU Status [R/W] */
44#define NILE4_INTCTRL 0x0088 /* Interrupt Control [R/W] */
45#define NILE4_INTSTAT0 0x0090 /* Interrupt Status 0 [R] */
46#define NILE4_INTSTAT1 0x0098 /* Interrupt Status 1 and CPU Interrupt */
47 /* Enable [R/W] */
48#define NILE4_INTCLR 0x00A0 /* Interrupt Clear [R/W] */
49#define NILE4_INTPPES 0x00A8 /* PCI Interrupt Control [R/W] */
50
51
52 /*
53 * Memory-Interface Registers
54 */
55
56#define NILE4_MEMCTRL 0x00C0 /* Memory Control */
57#define NILE4_ACSTIME 0x00C8 /* Memory Access Timing [R/W] */
58#define NILE4_CHKERR 0x00D0 /* Memory Check Error Status [R] */
59
60
61 /*
62 * PCI-Bus Registers
63 */
64
65#define NILE4_PCICTRL 0x00E0 /* PCI Control [R/W] */
66#define NILE4_PCIARB 0x00E8 /* PCI Arbiter [R/W] */
67#define NILE4_PCIINIT0 0x00F0 /* PCI Master (Initiator) 0 [R/W] */
68#define NILE4_PCIINIT1 0x00F8 /* PCI Master (Initiator) 1 [R/W] */
69#define NILE4_PCIERR 0x00B8 /* PCI Error [R/W] */
70
71
72 /*
73 * Local-Bus Registers
74 */
75
76#define NILE4_LCNFG 0x0100 /* Local Bus Configuration [R/W] */
77#define NILE4_LCST2 0x0110 /* Local Bus Chip-Select Timing 2 [R/W] */
78#define NILE4_LCST3 0x0118 /* Local Bus Chip-Select Timing 3 [R/W] */
79#define NILE4_LCST4 0x0120 /* Local Bus Chip-Select Timing 4 [R/W] */
80#define NILE4_LCST5 0x0128 /* Local Bus Chip-Select Timing 5 [R/W] */
81#define NILE4_LCST6 0x0130 /* Local Bus Chip-Select Timing 6 [R/W] */
82#define NILE4_LCST7 0x0138 /* Local Bus Chip-Select Timing 7 [R/W] */
83#define NILE4_LCST8 0x0140 /* Local Bus Chip-Select Timing 8 [R/W] */
84#define NILE4_DCSFN 0x0150 /* Device Chip-Select Muxing and Output */
85 /* Enables [R/W] */
86#define NILE4_DCSIO 0x0158 /* Device Chip-Selects As I/O Bits [R/W] */
87#define NILE4_BCST 0x0178 /* Local Boot Chip-Select Timing [R/W] */
88
89
90 /*
91 * DMA Registers
92 */
93
94#define NILE4_DMACTRL0 0x0180 /* DMA Control 0 [R/W] */
95#define NILE4_DMASRCA0 0x0188 /* DMA Source Address 0 [R/W] */
96#define NILE4_DMADESA0 0x0190 /* DMA Destination Address 0 [R/W] */
97#define NILE4_DMACTRL1 0x0198 /* DMA Control 1 [R/W] */
98#define NILE4_DMASRCA1 0x01A0 /* DMA Source Address 1 [R/W] */
99#define NILE4_DMADESA1 0x01A8 /* DMA Destination Address 1 [R/W] */
100
101
102 /*
103 * Timer Registers
104 */
105
106#define NILE4_T0CTRL 0x01C0 /* SDRAM Refresh Control [R/W] */
107#define NILE4_T0CNTR 0x01C8 /* SDRAM Refresh Counter [R/W] */
108#define NILE4_T1CTRL 0x01D0 /* CPU-Bus Read Time-Out Control [R/W] */
109#define NILE4_T1CNTR 0x01D8 /* CPU-Bus Read Time-Out Counter [R/W] */
110#define NILE4_T2CTRL 0x01E0 /* General-Purpose Timer Control [R/W] */
111#define NILE4_T2CNTR 0x01E8 /* General-Purpose Timer Counter [R/W] */
112#define NILE4_T3CTRL 0x01F0 /* Watchdog Timer Control [R/W] */
113#define NILE4_T3CNTR 0x01F8 /* Watchdog Timer Counter [R/W] */
114
115
116 /*
117 * PCI Configuration Space Registers
118 */
119
120#define NILE4_PCI_BASE 0x0200
121
122#define NILE4_VID 0x0200 /* PCI Vendor ID [R] */
123#define NILE4_DID 0x0202 /* PCI Device ID [R] */
124#define NILE4_PCICMD 0x0204 /* PCI Command [R/W] */
125#define NILE4_PCISTS 0x0206 /* PCI Status [R/W] */
126#define NILE4_REVID 0x0208 /* PCI Revision ID [R] */
127#define NILE4_CLASS 0x0209 /* PCI Class Code [R] */
128#define NILE4_CLSIZ 0x020C /* PCI Cache Line Size [R/W] */
129#define NILE4_MLTIM 0x020D /* PCI Latency Timer [R/W] */
130#define NILE4_HTYPE 0x020E /* PCI Header Type [R] */
131#define NILE4_BIST 0x020F /* BIST [R] (unimplemented) */
132#define NILE4_BARC 0x0210 /* PCI Base Address Register Control [R/W] */
133#define NILE4_BAR0 0x0218 /* PCI Base Address Register 0 [R/W] */
134#define NILE4_BAR1 0x0220 /* PCI Base Address Register 1 [R/W] */
135#define NILE4_CIS 0x0228 /* PCI Cardbus CIS Pointer [R] */
136 /* (unimplemented) */
137#define NILE4_SSVID 0x022C /* PCI Sub-System Vendor ID [R/W] */
138#define NILE4_SSID 0x022E /* PCI Sub-System ID [R/W] */
139#define NILE4_ROM 0x0230 /* Expansion ROM Base Address [R] */
140 /* (unimplemented) */
141#define NILE4_INTLIN 0x023C /* PCI Interrupt Line [R/W] */
142#define NILE4_INTPIN 0x023D /* PCI Interrupt Pin [R] */
143#define NILE4_MINGNT 0x023E /* PCI Min_Gnt [R] (unimplemented) */
144#define NILE4_MAXLAT 0x023F /* PCI Max_Lat [R] (unimplemented) */
145#define NILE4_BAR2 0x0240 /* PCI Base Address Register 2 [R/W] */
146#define NILE4_BAR3 0x0248 /* PCI Base Address Register 3 [R/W] */
147#define NILE4_BAR4 0x0250 /* PCI Base Address Register 4 [R/W] */
148#define NILE4_BAR5 0x0258 /* PCI Base Address Register 5 [R/W] */
149#define NILE4_BAR6 0x0260 /* PCI Base Address Register 6 [R/W] */
150#define NILE4_BAR7 0x0268 /* PCI Base Address Register 7 [R/W] */
151#define NILE4_BAR8 0x0270 /* PCI Base Address Register 8 [R/W] */
152#define NILE4_BARB 0x0278 /* PCI Base Address Register BOOT [R/W] */
153
154
155 /*
156 * Serial-Port Registers
157 */
158
159#define NILE4_UART_BASE 0x0300
160
161#define NILE4_UARTRBR 0x0300 /* UART Receiver Data Buffer [R] */
162#define NILE4_UARTTHR 0x0300 /* UART Transmitter Data Holding [W] */
163#define NILE4_UARTIER 0x0308 /* UART Interrupt Enable [R/W] */
164#define NILE4_UARTDLL 0x0300 /* UART Divisor Latch LSB [R/W] */
165#define NILE4_UARTDLM 0x0308 /* UART Divisor Latch MSB [R/W] */
166#define NILE4_UARTIIR 0x0310 /* UART Interrupt ID [R] */
167#define NILE4_UARTFCR 0x0310 /* UART FIFO Control [W] */
168#define NILE4_UARTLCR 0x0318 /* UART Line Control [R/W] */
169#define NILE4_UARTMCR 0x0320 /* UART Modem Control [R/W] */
170#define NILE4_UARTLSR 0x0328 /* UART Line Status [R/W] */
171#define NILE4_UARTMSR 0x0330 /* UART Modem Status [R/W] */
172#define NILE4_UARTSCR 0x0338 /* UART Scratch [R/W] */
173
174#define NILE4_UART_BASE_BAUD 520833 /* 100 MHz / 12 / 16 */
175
176
177 /*
178 * Interrupt Lines
179 */
180
181#define NILE4_INT_CPCE 0 /* CPU-Interface Parity-Error Interrupt */
182#define NILE4_INT_CNTD 1 /* CPU No-Target Decode Interrupt */
183#define NILE4_INT_MCE 2 /* Memory-Check Error Interrupt */
184#define NILE4_INT_DMA 3 /* DMA Controller Interrupt */
185#define NILE4_INT_UART 4 /* UART Interrupt */
186#define NILE4_INT_WDOG 5 /* Watchdog Timer Interrupt */
187#define NILE4_INT_GPT 6 /* General-Purpose Timer Interrupt */
188#define NILE4_INT_LBRTD 7 /* Local-Bus Ready Timer Interrupt */
189#define NILE4_INT_INTA 8 /* PCI Interrupt Signal INTA# */
190#define NILE4_INT_INTB 9 /* PCI Interrupt Signal INTB# */
191#define NILE4_INT_INTC 10 /* PCI Interrupt Signal INTC# */
192#define NILE4_INT_INTD 11 /* PCI Interrupt Signal INTD# */
193#define NILE4_INT_INTE 12 /* PCI Interrupt Signal INTE# (ISA cascade) */
194#define NILE4_INT_RESV 13 /* Reserved */
195#define NILE4_INT_PCIS 14 /* PCI SERR# Interrupt */
196#define NILE4_INT_PCIE 15 /* PCI Internal Error Interrupt */
197
198
199 /*
200 * Nile 4 Register Access
201 */
202
203static inline void nile4_sync(void)
204{
205 volatile u32 *p = (volatile u32 *)0xbfc00000;
206 (void)(*p);
207}
208
209static inline void nile4_out32(u32 offset, u32 val)
210{
211 *(volatile u32 *)(NILE4_BASE+offset) = val;
212 nile4_sync();
213}
214
215static inline u32 nile4_in32(u32 offset)
216{
217 u32 val = *(volatile u32 *)(NILE4_BASE+offset);
218 nile4_sync();
219 return val;
220}
221
222static inline void nile4_out16(u32 offset, u16 val)
223{
224 *(volatile u16 *)(NILE4_BASE+offset) = val;
225 nile4_sync();
226}
227
228static inline u16 nile4_in16(u32 offset)
229{
230 u16 val = *(volatile u16 *)(NILE4_BASE+offset);
231 nile4_sync();
232 return val;
233}
234
235static inline void nile4_out8(u32 offset, u8 val)
236{
237 *(volatile u8 *)(NILE4_BASE+offset) = val;
238 nile4_sync();
239}
240
241static inline u8 nile4_in8(u32 offset)
242{
243 u8 val = *(volatile u8 *)(NILE4_BASE+offset);
244 nile4_sync();
245 return val;
246}
247
248
249 /*
250 * Physical Device Address Registers
251 */
252
253extern void nile4_set_pdar(u32 pdar, u32 phys, u32 size, int width,
254 int on_memory_bus, int visible);
255
256
257 /*
258 * PCI Master Registers
259 */
260
261#define NILE4_PCICMD_IACK 0 /* PCI Interrupt Acknowledge */
262#define NILE4_PCICMD_IO 1 /* PCI I/O Space */
263#define NILE4_PCICMD_MEM 3 /* PCI Memory Space */
264#define NILE4_PCICMD_CFG 5 /* PCI Configuration Space */
265
266
267 /*
268 * PCI Address Spaces
269 *
270 * Note that these are multiplexed using PCIINIT[01]!
271 */
272
273#define NILE4_PCI_IO_BASE 0xa6000000
274#define NILE4_PCI_MEM_BASE 0xa8000000
275#define NILE4_PCI_CFG_BASE NILE4_PCI_MEM_BASE
276#define NILE4_PCI_IACK_BASE NILE4_PCI_IO_BASE
277
278
279extern void nile4_set_pmr(u32 pmr, u32 type, u32 addr);
280
281
282 /*
283 * Interrupt Programming
284 */
285
286#define NUM_I8259_INTERRUPTS 16
287#define NUM_NILE4_INTERRUPTS 16
288
289#define IRQ_I8259_CASCADE NILE4_INT_INTE
290#define is_i8259_irq(irq) ((irq) < NUM_I8259_INTERRUPTS)
291#define nile4_to_irq(n) ((n)+NUM_I8259_INTERRUPTS)
292#define irq_to_nile4(n) ((n)-NUM_I8259_INTERRUPTS)
293
294extern void nile4_map_irq(int nile4_irq, int cpu_irq);
295extern void nile4_map_irq_all(int cpu_irq);
296extern void nile4_enable_irq(unsigned int nile4_irq);
297extern void nile4_disable_irq(unsigned int nile4_irq);
298extern void nile4_disable_irq_all(void);
299extern u16 nile4_get_irq_stat(int cpu_irq);
300extern void nile4_enable_irq_output(int cpu_irq);
301extern void nile4_disable_irq_output(int cpu_irq);
302extern void nile4_set_pci_irq_polarity(int pci_irq, int high);
303extern void nile4_set_pci_irq_level_or_edge(int pci_irq, int level);
304extern void nile4_clear_irq(int nile4_irq);
305extern void nile4_clear_irq_mask(u32 mask);
306extern u8 nile4_i8259_iack(void);
307extern void nile4_dump_irq_status(void); /* Debug */
308
309#endif
310
diff --git a/include/asm-mips/page.h b/include/asm-mips/page.h
index 5c3239dad0f2..b92dd8c760da 100644
--- a/include/asm-mips/page.h
+++ b/include/asm-mips/page.h
@@ -34,12 +34,8 @@
34 34
35#ifndef __ASSEMBLY__ 35#ifndef __ASSEMBLY__
36 36
37/* 37#include <linux/pfn.h>
38 * This gives the physical RAM offset. 38#include <asm/io.h>
39 */
40#ifndef PHYS_OFFSET
41#define PHYS_OFFSET 0UL
42#endif
43 39
44/* 40/*
45 * It's normally defined only for FLATMEM config but it's 41 * It's normally defined only for FLATMEM config but it's
@@ -48,9 +44,6 @@
48 */ 44 */
49#define ARCH_PFN_OFFSET PFN_UP(PHYS_OFFSET) 45#define ARCH_PFN_OFFSET PFN_UP(PHYS_OFFSET)
50 46
51#include <linux/pfn.h>
52#include <asm/io.h>
53
54extern void clear_page(void * page); 47extern void clear_page(void * page);
55extern void copy_page(void * to, void * from); 48extern void copy_page(void * to, void * from);
56 49
@@ -150,11 +143,15 @@ typedef struct { unsigned long pgprot; } pgprot_t;
150 * __pa()/__va() should be used only during mem init. 143 * __pa()/__va() should be used only during mem init.
151 */ 144 */
152#if defined(CONFIG_64BIT) && !defined(CONFIG_BUILD_ELF64) 145#if defined(CONFIG_64BIT) && !defined(CONFIG_BUILD_ELF64)
153#define __pa_page_offset(x) ((unsigned long)(x) < CKSEG0 ? PAGE_OFFSET : CKSEG0) 146#define __pa(x) \
147({ \
148 unsigned long __x = (unsigned long)(x); \
149 __x < CKSEG0 ? XPHYSADDR(__x) : CPHYSADDR(__x); \
150})
154#else 151#else
155#define __pa_page_offset(x) PAGE_OFFSET 152#define __pa(x) \
153 ((unsigned long)(x) - PAGE_OFFSET + PHYS_OFFSET)
156#endif 154#endif
157#define __pa(x) ((unsigned long)(x) - __pa_page_offset(x) + PHYS_OFFSET)
158#define __va(x) ((void *)((unsigned long)(x) + PAGE_OFFSET - PHYS_OFFSET)) 155#define __va(x) ((void *)((unsigned long)(x) + PAGE_OFFSET - PHYS_OFFSET))
159#define __pa_symbol(x) __pa(RELOC_HIDE((unsigned long)(x),0)) 156#define __pa_symbol(x) __pa(RELOC_HIDE((unsigned long)(x),0))
160 157
diff --git a/include/asm-mips/pci.h b/include/asm-mips/pci.h
index 3eea3ba0fca5..a59d54749eef 100644
--- a/include/asm-mips/pci.h
+++ b/include/asm-mips/pci.h
@@ -56,7 +56,7 @@ extern void register_pci_controller(struct pci_controller *hose);
56/* 56/*
57 * board supplied pci irq fixup routine 57 * board supplied pci irq fixup routine
58 */ 58 */
59extern int pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin); 59extern int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin);
60 60
61 61
62/* Can be used to override the logic in pci_scan_bus for skipping 62/* Can be used to override the logic in pci_scan_bus for skipping
diff --git a/include/asm-mips/pmc-sierra/msp71xx/msp_cic_int.h b/include/asm-mips/pmc-sierra/msp71xx/msp_cic_int.h
new file mode 100644
index 000000000000..c84bcf9570b1
--- /dev/null
+++ b/include/asm-mips/pmc-sierra/msp71xx/msp_cic_int.h
@@ -0,0 +1,151 @@
1/*
2 * Defines for the MSP interrupt controller.
3 *
4 * Copyright (C) 1999 MIPS Technologies, Inc. All rights reserved.
5 * Author: Carsten Langgaard, carstenl@mips.com
6 *
7 * ########################################################################
8 *
9 * This program is free software; you can distribute it and/or modify it
10 * under the terms of the GNU General Public License (Version 2) as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 * for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
21 *
22 * ########################################################################
23 */
24
25#ifndef _MSP_CIC_INT_H
26#define _MSP_CIC_INT_H
27
28/*
29 * The PMC-Sierra CIC interrupts are all centrally managed by the
30 * CIC sub-system.
31 * We attempt to keep the interrupt numbers as consistent as possible
32 * across all of the MSP devices, but some differences will creep in ...
33 * The interrupts which are directly forwarded to the MIPS core interrupts
34 * are assigned interrupts in the range 0-7, interrupts cascaded through
35 * the CIC are assigned interrupts 8-39. The cascade occurs on C_IRQ4
36 * (MSP_INT_CIC). Currently we don't really distinguish between VPE1
37 * and VPE0 (or thread contexts for that matter). Will have to fix.
38 * The PER interrupts are assigned interrupts in the range 40-71.
39*/
40
41
42/*
43 * IRQs directly forwarded to the CPU
44 */
45#define MSP_MIPS_INTBASE 0
46#define MSP_INT_SW0 0 /* IRQ for swint0, C_SW0 */
47#define MSP_INT_SW1 1 /* IRQ for swint1, C_SW1 */
48#define MSP_INT_MAC0 2 /* IRQ for MAC 0, C_IRQ0 */
49#define MSP_INT_MAC1 3 /* IRQ for MAC 1, C_IRQ1 */
50#define MSP_INT_USB 4 /* IRQ for USB, C_IRQ2 */
51#define MSP_INT_SAR 5 /* IRQ for ADSL2+ SAR, C_IRQ3 */
52#define MSP_INT_CIC 6 /* IRQ for CIC block, C_IRQ4 */
53#define MSP_INT_SEC 7 /* IRQ for Sec engine, C_IRQ5 */
54
55/*
56 * IRQs cascaded on CPU interrupt 4 (CAUSE bit 12, C_IRQ4)
57 * These defines should be tied to the register definitions for the CIC
58 * interrupt routine. For now, just use hard-coded values.
59 */
60#define MSP_CIC_INTBASE (MSP_MIPS_INTBASE + 8)
61#define MSP_INT_EXT0 (MSP_CIC_INTBASE + 0)
62 /* External interrupt 0 */
63#define MSP_INT_EXT1 (MSP_CIC_INTBASE + 1)
64 /* External interrupt 1 */
65#define MSP_INT_EXT2 (MSP_CIC_INTBASE + 2)
66 /* External interrupt 2 */
67#define MSP_INT_EXT3 (MSP_CIC_INTBASE + 3)
68 /* External interrupt 3 */
69#define MSP_INT_CPUIF (MSP_CIC_INTBASE + 4)
70 /* CPU interface interrupt */
71#define MSP_INT_EXT4 (MSP_CIC_INTBASE + 5)
72 /* External interrupt 4 */
73#define MSP_INT_CIC_USB (MSP_CIC_INTBASE + 6)
74 /* Cascaded IRQ for USB */
75#define MSP_INT_MBOX (MSP_CIC_INTBASE + 7)
76 /* Sec engine mailbox IRQ */
77#define MSP_INT_EXT5 (MSP_CIC_INTBASE + 8)
78 /* External interrupt 5 */
79#define MSP_INT_TDM (MSP_CIC_INTBASE + 9)
80 /* TDM interrupt */
81#define MSP_INT_CIC_MAC0 (MSP_CIC_INTBASE + 10)
82 /* Cascaded IRQ for MAC 0 */
83#define MSP_INT_CIC_MAC1 (MSP_CIC_INTBASE + 11)
84 /* Cascaded IRQ for MAC 1 */
85#define MSP_INT_CIC_SEC (MSP_CIC_INTBASE + 12)
86 /* Cascaded IRQ for sec engine */
87#define MSP_INT_PER (MSP_CIC_INTBASE + 13)
88 /* Peripheral interrupt */
89#define MSP_INT_TIMER0 (MSP_CIC_INTBASE + 14)
90 /* SLP timer 0 */
91#define MSP_INT_TIMER1 (MSP_CIC_INTBASE + 15)
92 /* SLP timer 1 */
93#define MSP_INT_TIMER2 (MSP_CIC_INTBASE + 16)
94 /* SLP timer 2 */
95#define MSP_INT_VPE0_TIMER (MSP_CIC_INTBASE + 17)
96 /* VPE0 MIPS timer */
97#define MSP_INT_BLKCP (MSP_CIC_INTBASE + 18)
98 /* Block Copy */
99#define MSP_INT_UART0 (MSP_CIC_INTBASE + 19)
100 /* UART 0 */
101#define MSP_INT_PCI (MSP_CIC_INTBASE + 20)
102 /* PCI subsystem */
103#define MSP_INT_EXT6 (MSP_CIC_INTBASE + 21)
104 /* External interrupt 5 */
105#define MSP_INT_PCI_MSI (MSP_CIC_INTBASE + 22)
106 /* PCI Message Signal */
107#define MSP_INT_CIC_SAR (MSP_CIC_INTBASE + 23)
108 /* Cascaded ADSL2+ SAR IRQ */
109#define MSP_INT_DSL (MSP_CIC_INTBASE + 24)
110 /* ADSL2+ IRQ */
111#define MSP_INT_CIC_ERR (MSP_CIC_INTBASE + 25)
112 /* SLP error condition */
113#define MSP_INT_VPE1_TIMER (MSP_CIC_INTBASE + 26)
114 /* VPE1 MIPS timer */
115#define MSP_INT_VPE0_PC (MSP_CIC_INTBASE + 27)
116 /* VPE0 Performance counter */
117#define MSP_INT_VPE1_PC (MSP_CIC_INTBASE + 28)
118 /* VPE1 Performance counter */
119#define MSP_INT_EXT7 (MSP_CIC_INTBASE + 29)
120 /* External interrupt 5 */
121#define MSP_INT_VPE0_SW (MSP_CIC_INTBASE + 30)
122 /* VPE0 Software interrupt */
123#define MSP_INT_VPE1_SW (MSP_CIC_INTBASE + 31)
124 /* VPE0 Software interrupt */
125
126/*
127 * IRQs cascaded on CIC PER interrupt (MSP_INT_PER)
128 */
129#define MSP_PER_INTBASE (MSP_CIC_INTBASE + 32)
130/* Reserved 0-1 */
131#define MSP_INT_UART1 (MSP_PER_INTBASE + 2)
132 /* UART 1 */
133/* Reserved 3-5 */
134#define MSP_INT_2WIRE (MSP_PER_INTBASE + 6)
135 /* 2-wire */
136#define MSP_INT_TM0 (MSP_PER_INTBASE + 7)
137 /* Peripheral timer block out 0 */
138#define MSP_INT_TM1 (MSP_PER_INTBASE + 8)
139 /* Peripheral timer block out 1 */
140/* Reserved 9 */
141#define MSP_INT_SPRX (MSP_PER_INTBASE + 10)
142 /* SPI RX complete */
143#define MSP_INT_SPTX (MSP_PER_INTBASE + 11)
144 /* SPI TX complete */
145#define MSP_INT_GPIO (MSP_PER_INTBASE + 12)
146 /* GPIO */
147#define MSP_INT_PER_ERR (MSP_PER_INTBASE + 13)
148 /* Peripheral error */
149/* Reserved 14-31 */
150
151#endif /* !_MSP_CIC_INT_H */
diff --git a/include/asm-mips/pmc-sierra/msp71xx/msp_int.h b/include/asm-mips/pmc-sierra/msp71xx/msp_int.h
new file mode 100644
index 000000000000..1d9f05474820
--- /dev/null
+++ b/include/asm-mips/pmc-sierra/msp71xx/msp_int.h
@@ -0,0 +1,43 @@
1/*
2 * Defines for the MSP interrupt handlers.
3 *
4 * Copyright (C) 2005, PMC-Sierra, Inc. All rights reserved.
5 * Author: Andrew Hughes, Andrew_Hughes@pmc-sierra.com
6 *
7 * ########################################################################
8 *
9 * This program is free software; you can distribute it and/or modify it
10 * under the terms of the GNU General Public License (Version 2) as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 * for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
21 *
22 * ########################################################################
23 */
24
25#ifndef _MSP_INT_H
26#define _MSP_INT_H
27
28/*
29 * The PMC-Sierra MSP product line has at least two different interrupt
30 * controllers, the SLP register based scheme and the CIC interrupt
31 * controller block mechanism. This file distinguishes between them
32 * so that devices see a uniform interface.
33 */
34
35#if defined(CONFIG_IRQ_MSP_SLP)
36 #include "msp_slp_int.h"
37#elif defined(CONFIG_IRQ_MSP_CIC)
38 #include "msp_cic_int.h"
39#else
40 #error "What sort of interrupt controller does *your* MSP have?"
41#endif
42
43#endif /* !_MSP_INT_H */
diff --git a/include/asm-mips/pmc-sierra/msp71xx/msp_pci.h b/include/asm-mips/pmc-sierra/msp71xx/msp_pci.h
new file mode 100644
index 000000000000..415606903617
--- /dev/null
+++ b/include/asm-mips/pmc-sierra/msp71xx/msp_pci.h
@@ -0,0 +1,205 @@
1/*
2 * Copyright (c) 2000-2006 PMC-Sierra INC.
3 *
4 * This program is free software; you can redistribute it
5 * and/or modify it under the terms of the GNU General
6 * Public License as published by the Free Software
7 * Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 *
10 * This program is distributed in the hope that it will be
11 * useful, but WITHOUT ANY WARRANTY; without even the implied
12 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
13 * PURPOSE. See the GNU General Public License for more
14 * details.
15 *
16 * You should have received a copy of the GNU General Public
17 * License along with this program; if not, write to the Free
18 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA
19 * 02139, USA.
20 *
21 * PMC-SIERRA INC. DISCLAIMS ANY LIABILITY OF ANY KIND
22 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS
23 * SOFTWARE.
24 */
25
26#ifndef _MSP_PCI_H_
27#define _MSP_PCI_H_
28
29#define MSP_HAS_PCI(ID) (((u32)(ID) <= 0x4236) && ((u32)(ID) >= 0x4220))
30
31/*
32 * It is convenient to program the OATRAN register so that
33 * Athena virtual address space and PCI address space are
34 * the same. This is not a requirement, just a convenience.
35 *
36 * The only hard restrictions on the value of OATRAN is that
37 * OATRAN must not be programmed to allow translated memory
38 * addresses to fall within the lowest 512MB of
39 * PCI address space. This region is hardcoded
40 * for use as Athena PCI Host Controller target
41 * access memory space to the Athena's SDRAM.
42 *
43 * Note that OATRAN applies only to memory accesses, not
44 * to I/O accesses.
45 *
46 * To program OATRAN to make Athena virtual address space
47 * and PCI address space have the same values, OATRAN
48 * is to be programmed to 0xB8000000. The top seven
49 * bits of the value mimic the seven bits clipped off
50 * by the PCI Host controller.
51 *
52 * With OATRAN at the said value, when the CPU does
53 * an access to its virtual address at, say 0xB900_5000,
54 * the address appearing on the PCI bus will be
55 * 0xB900_5000.
56 * - Michael Penner
57 */
58#define MSP_PCI_OATRAN 0xB8000000UL
59
60#define MSP_PCI_SPACE_BASE (MSP_PCI_OATRAN + 0x1002000UL)
61#define MSP_PCI_SPACE_SIZE (0x3000000UL - 0x2000)
62#define MSP_PCI_SPACE_END \
63 (MSP_PCI_SPACE_BASE + MSP_PCI_SPACE_SIZE - 1)
64#define MSP_PCI_IOSPACE_BASE (MSP_PCI_OATRAN + 0x1001000UL)
65#define MSP_PCI_IOSPACE_SIZE 0x1000
66#define MSP_PCI_IOSPACE_END \
67 (MSP_PCI_IOSPACE_BASE + MSP_PCI_IOSPACE_SIZE - 1)
68
69/* IRQ for PCI status interrupts */
70#define PCI_STAT_IRQ 20
71
72#define QFLUSH_REG_1 0xB7F40000
73
74typedef volatile unsigned int pcireg;
75typedef void * volatile ppcireg;
76
77struct pci_block_copy
78{
79 pcireg unused1; /* +0x00 */
80 pcireg unused2; /* +0x04 */
81 ppcireg unused3; /* +0x08 */
82 ppcireg unused4; /* +0x0C */
83 pcireg unused5; /* +0x10 */
84 pcireg unused6; /* +0x14 */
85 pcireg unused7; /* +0x18 */
86 ppcireg unused8; /* +0x1C */
87 ppcireg unused9; /* +0x20 */
88 pcireg unusedA; /* +0x24 */
89 ppcireg unusedB; /* +0x28 */
90 ppcireg unusedC; /* +0x2C */
91};
92
93enum
94{
95 config_device_vendor, /* 0 */
96 config_status_command, /* 1 */
97 config_class_revision, /* 2 */
98 config_BIST_header_latency_cache, /* 3 */
99 config_BAR0, /* 4 */
100 config_BAR1, /* 5 */
101 config_BAR2, /* 6 */
102 config_not_used7, /* 7 */
103 config_not_used8, /* 8 */
104 config_not_used9, /* 9 */
105 config_CIS, /* 10 */
106 config_subsystem, /* 11 */
107 config_not_used12, /* 12 */
108 config_capabilities, /* 13 */
109 config_not_used14, /* 14 */
110 config_lat_grant_irq, /* 15 */
111 config_message_control,/* 16 */
112 config_message_addr, /* 17 */
113 config_message_data, /* 18 */
114 config_VPD_addr, /* 19 */
115 config_VPD_data, /* 20 */
116 config_maxregs /* 21 - number of registers */
117};
118
119struct msp_pci_regs
120{
121 pcireg hop_unused_00; /* +0x00 */
122 pcireg hop_unused_04; /* +0x04 */
123 pcireg hop_unused_08; /* +0x08 */
124 pcireg hop_unused_0C; /* +0x0C */
125 pcireg hop_unused_10; /* +0x10 */
126 pcireg hop_unused_14; /* +0x14 */
127 pcireg hop_unused_18; /* +0x18 */
128 pcireg hop_unused_1C; /* +0x1C */
129 pcireg hop_unused_20; /* +0x20 */
130 pcireg hop_unused_24; /* +0x24 */
131 pcireg hop_unused_28; /* +0x28 */
132 pcireg hop_unused_2C; /* +0x2C */
133 pcireg hop_unused_30; /* +0x30 */
134 pcireg hop_unused_34; /* +0x34 */
135 pcireg if_control; /* +0x38 */
136 pcireg oatran; /* +0x3C */
137 pcireg reset_ctl; /* +0x40 */
138 pcireg config_addr; /* +0x44 */
139 pcireg hop_unused_48; /* +0x48 */
140 pcireg msg_signaled_int_status; /* +0x4C */
141 pcireg msg_signaled_int_mask; /* +0x50 */
142 pcireg if_status; /* +0x54 */
143 pcireg if_mask; /* +0x58 */
144 pcireg hop_unused_5C; /* +0x5C */
145 pcireg hop_unused_60; /* +0x60 */
146 pcireg hop_unused_64; /* +0x64 */
147 pcireg hop_unused_68; /* +0x68 */
148 pcireg hop_unused_6C; /* +0x6C */
149 pcireg hop_unused_70; /* +0x70 */
150
151 struct pci_block_copy pci_bc[2] __attribute__((aligned(64)));
152
153 pcireg error_hdr1; /* +0xE0 */
154 pcireg error_hdr2; /* +0xE4 */
155
156 pcireg config[config_maxregs] __attribute__((aligned(256)));
157
158};
159
160#define BPCI_CFGADDR_BUSNUM_SHF 16
161#define BPCI_CFGADDR_FUNCTNUM_SHF 8
162#define BPCI_CFGADDR_REGNUM_SHF 2
163#define BPCI_CFGADDR_ENABLE (1<<31)
164
165#define BPCI_IFCONTROL_RTO (1<<20) /* Retry timeout */
166#define BPCI_IFCONTROL_HCE (1<<16) /* Host configuration enable */
167#define BPCI_IFCONTROL_CTO_SHF 12 /* Shift count for CTO bits */
168#define BPCI_IFCONTROL_SE (1<<5) /* Enable exceptions on errors */
169#define BPCI_IFCONTROL_BIST (1<<4) /* Use BIST in per. mode */
170#define BPCI_IFCONTROL_CAP (1<<3) /* Enable capabilities */
171#define BPCI_IFCONTROL_MMC_SHF 0 /* Shift count for MMC bits */
172
173#define BPCI_IFSTATUS_MGT (1<<8) /* Master Grant timeout */
174#define BPCI_IFSTATUS_MTT (1<<9) /* Master TRDY timeout */
175#define BPCI_IFSTATUS_MRT (1<<10) /* Master retry timeout */
176#define BPCI_IFSTATUS_BC0F (1<<13) /* Block copy 0 fault */
177#define BPCI_IFSTATUS_BC1F (1<<14) /* Block copy 1 fault */
178#define BPCI_IFSTATUS_PCIU (1<<15) /* PCI unable to respond */
179#define BPCI_IFSTATUS_BSIZ (1<<16) /* PCI access with illegal size */
180#define BPCI_IFSTATUS_BADD (1<<17) /* PCI access with illegal addr */
181#define BPCI_IFSTATUS_RTO (1<<18) /* Retry time out */
182#define BPCI_IFSTATUS_SER (1<<19) /* System error */
183#define BPCI_IFSTATUS_PER (1<<20) /* Parity error */
184#define BPCI_IFSTATUS_LCA (1<<21) /* Local CPU abort */
185#define BPCI_IFSTATUS_MEM (1<<22) /* Memory prot. violation */
186#define BPCI_IFSTATUS_ARB (1<<23) /* Arbiter timed out */
187#define BPCI_IFSTATUS_STA (1<<27) /* Signaled target abort */
188#define BPCI_IFSTATUS_TA (1<<28) /* Target abort */
189#define BPCI_IFSTATUS_MA (1<<29) /* Master abort */
190#define BPCI_IFSTATUS_PEI (1<<30) /* Parity error as initiator */
191#define BPCI_IFSTATUS_PET (1<<31) /* Parity error as target */
192
193#define BPCI_RESETCTL_PR (1<<0) /* True if reset asserted */
194#define BPCI_RESETCTL_RT (1<<4) /* Release time */
195#define BPCI_RESETCTL_CT (1<<8) /* Config time */
196#define BPCI_RESETCTL_PE (1<<12) /* PCI enabled */
197#define BPCI_RESETCTL_HM (1<<13) /* PCI host mode */
198#define BPCI_RESETCTL_RI (1<<14) /* PCI reset in */
199
200extern struct msp_pci_regs msp_pci_regs
201 __attribute__((section(".register")));
202extern unsigned long msp_pci_config_space
203 __attribute__((section(".register")));
204
205#endif /* !_MSP_PCI_H_ */
diff --git a/include/asm-mips/pmc-sierra/msp71xx/msp_prom.h b/include/asm-mips/pmc-sierra/msp71xx/msp_prom.h
new file mode 100644
index 000000000000..14ca7dc382a8
--- /dev/null
+++ b/include/asm-mips/pmc-sierra/msp71xx/msp_prom.h
@@ -0,0 +1,176 @@
1/*
2 * MIPS boards bootprom interface for the Linux kernel.
3 *
4 * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
5 * Author: Carsten Langgaard, carstenl@mips.com
6 *
7 * ########################################################################
8 *
9 * This program is free software; you can distribute it and/or modify it
10 * under the terms of the GNU General Public License (Version 2) as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 * for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
21 *
22 * ########################################################################
23 */
24
25#ifndef _ASM_MSP_PROM_H
26#define _ASM_MSP_PROM_H
27
28#include <linux/types.h>
29
30#define DEVICEID "deviceid"
31#define FEATURES "features"
32#define PROM_ENV "prom_env"
33#define PROM_ENV_FILE "/proc/"PROM_ENV
34#define PROM_ENV_SIZE 256
35
36#define CPU_DEVID_FAMILY 0x0000ff00
37#define CPU_DEVID_REVISION 0x000000ff
38
39#define FPGA_IS_POLO(revision) \
40 (((revision >= 0xb0) && (revision < 0xd0)))
41#define FPGA_IS_5000(revision) \
42 ((revision >= 0x80) && (revision <= 0x90))
43#define FPGA_IS_ZEUS(revision) ((revision < 0x7f))
44#define FPGA_IS_DUET(revision) \
45 (((revision >= 0xa0) && (revision < 0xb0)))
46#define FPGA_IS_MSP4200(revision) ((revision >= 0xd0))
47#define FPGA_IS_MSP7100(revision) ((revision >= 0xd0))
48
49#define MACHINE_TYPE_POLO "POLO"
50#define MACHINE_TYPE_DUET "DUET"
51#define MACHINE_TYPE_ZEUS "ZEUS"
52#define MACHINE_TYPE_MSP2000REVB "MSP2000REVB"
53#define MACHINE_TYPE_MSP5000 "MSP5000"
54#define MACHINE_TYPE_MSP4200 "MSP4200"
55#define MACHINE_TYPE_MSP7120 "MSP7120"
56#define MACHINE_TYPE_MSP7130 "MSP7130"
57#define MACHINE_TYPE_OTHER "OTHER"
58
59#define MACHINE_TYPE_POLO_FPGA "POLO-FPGA"
60#define MACHINE_TYPE_DUET_FPGA "DUET-FPGA"
61#define MACHINE_TYPE_ZEUS_FPGA "ZEUS_FPGA"
62#define MACHINE_TYPE_MSP2000REVB_FPGA "MSP2000REVB-FPGA"
63#define MACHINE_TYPE_MSP5000_FPGA "MSP5000-FPGA"
64#define MACHINE_TYPE_MSP4200_FPGA "MSP4200-FPGA"
65#define MACHINE_TYPE_MSP7100_FPGA "MSP7100-FPGA"
66#define MACHINE_TYPE_OTHER_FPGA "OTHER-FPGA"
67
68/* Device Family definitions */
69#define FAMILY_FPGA 0x0000
70#define FAMILY_ZEUS 0x1000
71#define FAMILY_POLO 0x2000
72#define FAMILY_DUET 0x4000
73#define FAMILY_TRIAD 0x5000
74#define FAMILY_MSP4200 0x4200
75#define FAMILY_MSP4200_FPGA 0x4f00
76#define FAMILY_MSP7100 0x7100
77#define FAMILY_MSP7100_FPGA 0x7f00
78
79/* Device Type definitions */
80#define TYPE_MSP7120 0x7120
81#define TYPE_MSP7130 0x7130
82
83#define ENET_KEY 'E'
84#define ENETTXD_KEY 'e'
85#define PCI_KEY 'P'
86#define PCIMUX_KEY 'p'
87#define SEC_KEY 'S'
88#define SPAD_KEY 'D'
89#define TDM_KEY 'T'
90#define ZSP_KEY 'Z'
91
92#define FEATURE_NOEXIST '-'
93#define FEATURE_EXIST '+'
94
95#define ENET_MII 'M'
96#define ENET_RMII 'R'
97
98#define ENETTXD_FALLING 'F'
99#define ENETTXD_RISING 'R'
100
101#define PCI_HOST 'H'
102#define PCI_PERIPHERAL 'P'
103
104#define PCIMUX_FULL 'F'
105#define PCIMUX_SINGLE 'S'
106
107#define SEC_DUET 'D'
108#define SEC_POLO 'P'
109#define SEC_SLOW 'S'
110#define SEC_TRIAD 'T'
111
112#define SPAD_POLO 'P'
113
114#define TDM_DUET 'D' /* DUET TDMs might exist */
115#define TDM_POLO 'P' /* POLO TDMs might exist */
116#define TDM_TRIAD 'T' /* TRIAD TDMs might exist */
117
118#define ZSP_DUET 'D' /* one DUET zsp engine */
119#define ZSP_TRIAD 'T' /* two TRIAD zsp engines */
120
121extern char *prom_getcmdline(void);
122extern char *prom_getenv(char *name);
123extern void prom_init_cmdline(void);
124extern void prom_meminit(void);
125extern void prom_fixup_mem_map(unsigned long start_mem,
126 unsigned long end_mem);
127
128#ifdef CONFIG_MTD_PMC_MSP_RAMROOT
129extern bool get_ramroot(void **start, unsigned long *size);
130#endif
131
132extern int get_ethernet_addr(char *ethaddr_name, char *ethernet_addr);
133extern unsigned long get_deviceid(void);
134extern char identify_enet(unsigned long interface_num);
135extern char identify_enetTxD(unsigned long interface_num);
136extern char identify_pci(void);
137extern char identify_sec(void);
138extern char identify_spad(void);
139extern char identify_sec(void);
140extern char identify_tdm(void);
141extern char identify_zsp(void);
142extern unsigned long identify_family(void);
143extern unsigned long identify_revision(void);
144
145/*
146 * The following macro calls prom_printf and puts the format string
147 * into an init section so it can be reclaimed.
148 */
149#define ppfinit(f, x...) \
150 do { \
151 static char _f[] __initdata = KERN_INFO f; \
152 printk(_f, ## x); \
153 } while (0)
154
155/* Memory descriptor management. */
156#define PROM_MAX_PMEMBLOCKS 7 /* 6 used */
157
158enum yamon_memtypes {
159 yamon_dontuse,
160 yamon_prom,
161 yamon_free,
162};
163
164struct prom_pmemblock {
165 unsigned long base; /* Within KSEG0. */
166 unsigned int size; /* In bytes. */
167 unsigned int type; /* free or prom memory */
168};
169
170extern int prom_argc;
171extern char **prom_argv;
172extern char **prom_envp;
173extern int *prom_vec;
174extern struct prom_pmemblock *prom_getmdesc(void);
175
176#endif /* !_ASM_MSP_PROM_H */
diff --git a/include/asm-mips/pmc-sierra/msp71xx/msp_regops.h b/include/asm-mips/pmc-sierra/msp71xx/msp_regops.h
new file mode 100644
index 000000000000..60a5a38dd5b2
--- /dev/null
+++ b/include/asm-mips/pmc-sierra/msp71xx/msp_regops.h
@@ -0,0 +1,236 @@
1/*
2 * SMP/VPE-safe functions to access "registers" (see note).
3 *
4 * NOTES:
5* - These macros use ll/sc instructions, so it is your responsibility to
6 * ensure these are available on your platform before including this file.
7 * - The MIPS32 spec states that ll/sc results are undefined for uncached
8 * accesses. This means they can't be used on HW registers accessed
9 * through kseg1. Code which requires these macros for this purpose must
10 * front-end the registers with cached memory "registers" and have a single
11 * thread update the actual HW registers.
12 * - A maximum of 2k of code can be inserted between ll and sc. Every
13 * memory accesses between the instructions will increase the chance of
14 * sc failing and having to loop.
15 * - When using custom_read_reg32/custom_write_reg32 only perform the
16 * necessary logical operations on the register value in between these
17 * two calls. All other logic should be performed before the first call.
18 * - There is a bug on the R10000 chips which has a workaround. If you
19 * are affected by this bug, make sure to define the symbol 'R10000_LLSC_WAR'
20 * to be non-zero. If you are using this header from within linux, you may
21 * include <asm/war.h> before including this file to have this defined
22 * appropriately for you.
23 *
24 * Copyright 2005-2007 PMC-Sierra, Inc.
25 *
26 * This program is free software; you can redistribute it and/or modify it
27 * under the terms of the GNU General Public License as published by the
28 * Free Software Foundation; either version 2 of the License, or (at your
29 * option) any later version.
30 *
31 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
32 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
33 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
34 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
35 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
36 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
37 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
38 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
39 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
40 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41 *
42 * You should have received a copy of the GNU General Public License along
43 * with this program; if not, write to the Free Software Foundation, Inc., 675
44 * Mass Ave, Cambridge, MA 02139, USA.
45 */
46
47#ifndef __ASM_REGOPS_H__
48#define __ASM_REGOPS_H__
49
50#include <linux/types.h>
51
52#include <asm/war.h>
53
54#ifndef R10000_LLSC_WAR
55#define R10000_LLSC_WAR 0
56#endif
57
58#if R10000_LLSC_WAR == 1
59#define __beqz "beqzl "
60#else
61#define __beqz "beqz "
62#endif
63
64#ifndef _LINUX_TYPES_H
65typedef unsigned int u32;
66#endif
67
68/*
69 * Sets all the masked bits to the corresponding value bits
70 */
71static inline void set_value_reg32(volatile u32 *const addr,
72 u32 const mask,
73 u32 const value)
74{
75 u32 temp;
76
77 __asm__ __volatile__(
78 " .set push \n"
79 " .set mips3 \n"
80 "1: ll %0, %1 # set_value_reg32 \n"
81 " and %0, %2 \n"
82 " or %0, %3 \n"
83 " sc %0, %1 \n"
84 " "__beqz"%0, 1b \n"
85 " nop \n"
86 " .set pop \n"
87 : "=&r" (temp), "=m" (*addr)
88 : "ir" (~mask), "ir" (value), "m" (*addr));
89}
90
91/*
92 * Sets all the masked bits to '1'
93 */
94static inline void set_reg32(volatile u32 *const addr,
95 u32 const mask)
96{
97 u32 temp;
98
99 __asm__ __volatile__(
100 " .set push \n"
101 " .set mips3 \n"
102 "1: ll %0, %1 # set_reg32 \n"
103 " or %0, %2 \n"
104 " sc %0, %1 \n"
105 " "__beqz"%0, 1b \n"
106 " nop \n"
107 " .set pop \n"
108 : "=&r" (temp), "=m" (*addr)
109 : "ir" (mask), "m" (*addr));
110}
111
112/*
113 * Sets all the masked bits to '0'
114 */
115static inline void clear_reg32(volatile u32 *const addr,
116 u32 const mask)
117{
118 u32 temp;
119
120 __asm__ __volatile__(
121 " .set push \n"
122 " .set mips3 \n"
123 "1: ll %0, %1 # clear_reg32 \n"
124 " and %0, %2 \n"
125 " sc %0, %1 \n"
126 " "__beqz"%0, 1b \n"
127 " nop \n"
128 " .set pop \n"
129 : "=&r" (temp), "=m" (*addr)
130 : "ir" (~mask), "m" (*addr));
131}
132
133/*
134 * Toggles all masked bits from '0' to '1' and '1' to '0'
135 */
136static inline void toggle_reg32(volatile u32 *const addr,
137 u32 const mask)
138{
139 u32 temp;
140
141 __asm__ __volatile__(
142 " .set push \n"
143 " .set mips3 \n"
144 "1: ll %0, %1 # toggle_reg32 \n"
145 " xor %0, %2 \n"
146 " sc %0, %1 \n"
147 " "__beqz"%0, 1b \n"
148 " nop \n"
149 " .set pop \n"
150 : "=&r" (temp), "=m" (*addr)
151 : "ir" (mask), "m" (*addr));
152}
153
154/*
155 * Read all masked bits others are returned as '0'
156 */
157static inline u32 read_reg32(volatile u32 *const addr,
158 u32 const mask)
159{
160 u32 temp;
161
162 __asm__ __volatile__(
163 " .set push \n"
164 " .set noreorder \n"
165 " lw %0, %1 # read \n"
166 " and %0, %2 # mask \n"
167 " .set pop \n"
168 : "=&r" (temp)
169 : "m" (*addr), "ir" (mask));
170
171 return temp;
172}
173
174/*
175 * blocking_read_reg32 - Read address with blocking load
176 *
177 * Uncached writes need to be read back to ensure they reach RAM.
178 * The returned value must be 'used' to prevent from becoming a
179 * non-blocking load.
180 */
181static inline u32 blocking_read_reg32(volatile u32 *const addr)
182{
183 u32 temp;
184
185 __asm__ __volatile__(
186 " .set push \n"
187 " .set noreorder \n"
188 " lw %0, %1 # read \n"
189 " move %0, %0 # block \n"
190 " .set pop \n"
191 : "=&r" (temp)
192 : "m" (*addr));
193
194 return temp;
195}
196
197/*
198 * For special strange cases only:
199 *
200 * If you need custom processing within a ll/sc loop, use the following macros
201 * VERY CAREFULLY:
202 *
203 * u32 tmp; <-- Define a variable to hold the data
204 *
205 * custom_read_reg32(address, tmp); <-- Reads the address and put the value
206 * in the 'tmp' variable given
207 *
208 * From here on out, you are (basicly) atomic, so don't do anything too
209 * fancy!
210 * Also, this code may loop if the end of this block fails to write
211 * everything back safely due do the other CPU, so do NOT do anything
212 * with side-effects!
213 *
214 * custom_write_reg32(address, tmp); <-- Writes back 'tmp' safely.
215 */
216#define custom_read_reg32(address, tmp) \
217 __asm__ __volatile__( \
218 " .set push \n" \
219 " .set mips3 \n" \
220 "1: ll %0, %1 #custom_read_reg32 \n" \
221 " .set pop \n" \
222 : "=r" (tmp), "=m" (*address) \
223 : "m" (*address))
224
225#define custom_write_reg32(address, tmp) \
226 __asm__ __volatile__( \
227 " .set push \n" \
228 " .set mips3 \n" \
229 " sc %0, %1 #custom_write_reg32 \n" \
230 " "__beqz"%0, 1b \n" \
231 " nop \n" \
232 " .set pop \n" \
233 : "=&r" (tmp), "=m" (*address) \
234 : "0" (tmp), "m" (*address))
235
236#endif /* __ASM_REGOPS_H__ */
diff --git a/include/asm-mips/pmc-sierra/msp71xx/msp_regs.h b/include/asm-mips/pmc-sierra/msp71xx/msp_regs.h
new file mode 100644
index 000000000000..0b56f55206c6
--- /dev/null
+++ b/include/asm-mips/pmc-sierra/msp71xx/msp_regs.h
@@ -0,0 +1,667 @@
1/*
2 * Defines for the address space, registers and register configuration
3 * (bit masks, access macros etc) for the PMC-Sierra line of MSP products.
4 * This file contains addess maps for all the devices in the line of
5 * products but only has register definitions and configuration masks for
6 * registers which aren't definitely associated with any device. Things
7 * like clock settings, reset access, the ELB etc. Individual device
8 * drivers will reference the appropriate XXX_BASE value defined here
9 * and have individual registers offset from that.
10 *
11 * Copyright (C) 2005-2007 PMC-Sierra, Inc. All rights reserved.
12 * Author: Andrew Hughes, Andrew_Hughes@pmc-sierra.com
13 *
14 * ########################################################################
15 *
16 * This program is free software; you can distribute it and/or modify it
17 * under the terms of the GNU General Public License (Version 2) as
18 * published by the Free Software Foundation.
19 *
20 * This program is distributed in the hope it will be useful, but WITHOUT
21 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
22 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
23 * for more details.
24 *
25 * You should have received a copy of the GNU General Public License along
26 * with this program; if not, write to the Free Software Foundation, Inc.,
27 * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
28 *
29 * ########################################################################
30 */
31
32#include <asm/addrspace.h>
33#include <linux/types.h>
34
35#ifndef _ASM_MSP_REGS_H
36#define _ASM_MSP_REGS_H
37
38/*
39 ########################################################################
40 # Address space and device base definitions #
41 ########################################################################
42 */
43
44/*
45 ***************************************************************************
46 * System Logic and Peripherals (ELB, UART0, etc) device address space *
47 ***************************************************************************
48 */
49#define MSP_SLP_BASE 0x1c000000
50 /* System Logic and Peripherals */
51#define MSP_RST_BASE (MSP_SLP_BASE + 0x10)
52 /* System reset register base */
53#define MSP_RST_SIZE 0x0C /* System reset register space */
54
55#define MSP_WTIMER_BASE (MSP_SLP_BASE + 0x04C)
56 /* watchdog timer base */
57#define MSP_ITIMER_BASE (MSP_SLP_BASE + 0x054)
58 /* internal timer base */
59#define MSP_UART0_BASE (MSP_SLP_BASE + 0x100)
60 /* UART0 controller base */
61#define MSP_BCPY_CTRL_BASE (MSP_SLP_BASE + 0x120)
62 /* Block Copy controller base */
63#define MSP_BCPY_DESC_BASE (MSP_SLP_BASE + 0x160)
64 /* Block Copy descriptor base */
65
66/*
67 ***************************************************************************
68 * PCI address space *
69 ***************************************************************************
70 */
71#define MSP_PCI_BASE 0x19000000
72
73/*
74 ***************************************************************************
75 * MSbus device address space *
76 ***************************************************************************
77 */
78#define MSP_MSB_BASE 0x18000000
79 /* MSbus address start */
80#define MSP_PER_BASE (MSP_MSB_BASE + 0x400000)
81 /* Peripheral device registers */
82#define MSP_MAC0_BASE (MSP_MSB_BASE + 0x600000)
83 /* MAC A device registers */
84#define MSP_MAC1_BASE (MSP_MSB_BASE + 0x700000)
85 /* MAC B device registers */
86#define MSP_MAC_SIZE 0xE0 /* MAC register space */
87
88#define MSP_SEC_BASE (MSP_MSB_BASE + 0x800000)
89 /* Security Engine registers */
90#define MSP_MAC2_BASE (MSP_MSB_BASE + 0x900000)
91 /* MAC C device registers */
92#define MSP_ADSL2_BASE (MSP_MSB_BASE + 0xA80000)
93 /* ADSL2 device registers */
94#define MSP_USB_BASE (MSP_MSB_BASE + 0xB40000)
95 /* USB device registers */
96#define MSP_USB_BASE_START (MSP_MSB_BASE + 0xB40100)
97 /* USB device registers */
98#define MSP_USB_BASE_END (MSP_MSB_BASE + 0xB401FF)
99 /* USB device registers */
100#define MSP_CPUIF_BASE (MSP_MSB_BASE + 0xC00000)
101 /* CPU interface registers */
102
103/* Devices within the MSbus peripheral block */
104#define MSP_UART1_BASE (MSP_PER_BASE + 0x030)
105 /* UART1 controller base */
106#define MSP_SPI_BASE (MSP_PER_BASE + 0x058)
107 /* SPI/MPI control registers */
108#define MSP_TWI_BASE (MSP_PER_BASE + 0x090)
109 /* Two-wire control registers */
110#define MSP_PTIMER_BASE (MSP_PER_BASE + 0x0F0)
111 /* Programmable timer control */
112
113/*
114 ***************************************************************************
115 * Physical Memory configuration address space *
116 ***************************************************************************
117 */
118#define MSP_MEM_CFG_BASE 0x17f00000
119
120#define MSP_MEM_INDIRECT_CTL_10 0x10
121
122/*
123 * Notes:
124 * 1) The SPI registers are split into two blocks, one offset from the
125 * MSP_SPI_BASE by 0x00 and the other offset from the MSP_SPI_BASE by
126 * 0x68. The SPI driver definitions for the register must be aware
127 * of this.
128 * 2) The block copy engine register are divided into two regions, one
129 * for the control/configuration of the engine proper and one for the
130 * values of the descriptors used in the copy process. These have
131 * different base defines (CTRL_BASE vs DESC_BASE)
132 * 3) These constants are for physical addresses which means that they
133 * work correctly with "ioremap" and friends. This means that device
134 * drivers will need to remap these addresses using ioremap and perhaps
135 * the readw/writew macros. Or they could use the regptr() macro
136 * defined below, but the readw/writew calls are the correct thing.
137 * 4) The UARTs have an additional status register offset from the base
138 * address. This register isn't used in the standard 8250 driver but
139 * may be used in other software. Consult the hardware datasheet for
140 * offset details.
141 * 5) For some unknown reason the security engine (MSP_SEC_BASE) registers
142 * start at an offset of 0x84 from the base address but the block of
143 * registers before this is reserved for the security engine. The
144 * driver will have to be aware of this but it makes the register
145 * definitions line up better with the documentation.
146 */
147
148/*
149 ########################################################################
150 # System register definitions. Not associated with a specific device #
151 ########################################################################
152 */
153
154/*
155 * This macro maps the physical register number into uncached space
156 * and (for C code) casts it into a u32 pointer so it can be dereferenced
157 * Normally these would be accessed with ioremap and readX/writeX, but
158 * these are convenient for a lot of internal kernel code.
159 */
160#ifdef __ASSEMBLER__
161 #define regptr(addr) (KSEG1ADDR(addr))
162#else
163 #define regptr(addr) ((volatile u32 *const)(KSEG1ADDR(addr)))
164#endif
165
166/*
167 ***************************************************************************
168 * System Logic and Peripherals (RESET, ELB, etc) registers *
169 ***************************************************************************
170 */
171
172/* System Control register definitions */
173#define DEV_ID_REG regptr(MSP_SLP_BASE + 0x00)
174 /* Device-ID RO */
175#define FWR_ID_REG regptr(MSP_SLP_BASE + 0x04)
176 /* Firmware-ID Register RW */
177#define SYS_ID_REG0 regptr(MSP_SLP_BASE + 0x08)
178 /* System-ID Register-0 RW */
179#define SYS_ID_REG1 regptr(MSP_SLP_BASE + 0x0C)
180 /* System-ID Register-1 RW */
181
182/* System Reset register definitions */
183#define RST_STS_REG regptr(MSP_SLP_BASE + 0x10)
184 /* System Reset Status RO */
185#define RST_SET_REG regptr(MSP_SLP_BASE + 0x14)
186 /* System Set Reset WO */
187#define RST_CLR_REG regptr(MSP_SLP_BASE + 0x18)
188 /* System Clear Reset WO */
189
190/* System Clock Registers */
191#define PCI_SLP_REG regptr(MSP_SLP_BASE + 0x1C)
192 /* PCI clock generator RW */
193#define URT_SLP_REG regptr(MSP_SLP_BASE + 0x20)
194 /* UART clock generator RW */
195/* reserved (MSP_SLP_BASE + 0x24) */
196/* reserved (MSP_SLP_BASE + 0x28) */
197#define PLL1_SLP_REG regptr(MSP_SLP_BASE + 0x2C)
198 /* PLL1 clock generator RW */
199#define PLL0_SLP_REG regptr(MSP_SLP_BASE + 0x30)
200 /* PLL0 clock generator RW */
201#define MIPS_SLP_REG regptr(MSP_SLP_BASE + 0x34)
202 /* MIPS clock generator RW */
203#define VE_SLP_REG regptr(MSP_SLP_BASE + 0x38)
204 /* Voice Eng clock generator RW */
205/* reserved (MSP_SLP_BASE + 0x3C) */
206#define MSB_SLP_REG regptr(MSP_SLP_BASE + 0x40)
207 /* MS-Bus clock generator RW */
208#define SMAC_SLP_REG regptr(MSP_SLP_BASE + 0x44)
209 /* Sec & MAC clock generator RW */
210#define PERF_SLP_REG regptr(MSP_SLP_BASE + 0x48)
211 /* Per & TDM clock generator RW */
212
213/* Interrupt Controller Registers */
214#define SLP_INT_STS_REG regptr(MSP_SLP_BASE + 0x70)
215 /* Interrupt status register RW */
216#define SLP_INT_MSK_REG regptr(MSP_SLP_BASE + 0x74)
217 /* Interrupt enable/mask RW */
218#define SE_MBOX_REG regptr(MSP_SLP_BASE + 0x78)
219 /* Security Engine mailbox RW */
220#define VE_MBOX_REG regptr(MSP_SLP_BASE + 0x7C)
221 /* Voice Engine mailbox RW */
222
223/* ELB Controller Registers */
224#define CS0_CNFG_REG regptr(MSP_SLP_BASE + 0x80)
225 /* ELB CS0 Configuration Reg */
226#define CS0_ADDR_REG regptr(MSP_SLP_BASE + 0x84)
227 /* ELB CS0 Base Address Reg */
228#define CS0_MASK_REG regptr(MSP_SLP_BASE + 0x88)
229 /* ELB CS0 Mask Register */
230#define CS0_ACCESS_REG regptr(MSP_SLP_BASE + 0x8C)
231 /* ELB CS0 access register */
232
233#define CS1_CNFG_REG regptr(MSP_SLP_BASE + 0x90)
234 /* ELB CS1 Configuration Reg */
235#define CS1_ADDR_REG regptr(MSP_SLP_BASE + 0x94)
236 /* ELB CS1 Base Address Reg */
237#define CS1_MASK_REG regptr(MSP_SLP_BASE + 0x98)
238 /* ELB CS1 Mask Register */
239#define CS1_ACCESS_REG regptr(MSP_SLP_BASE + 0x9C)
240 /* ELB CS1 access register */
241
242#define CS2_CNFG_REG regptr(MSP_SLP_BASE + 0xA0)
243 /* ELB CS2 Configuration Reg */
244#define CS2_ADDR_REG regptr(MSP_SLP_BASE + 0xA4)
245 /* ELB CS2 Base Address Reg */
246#define CS2_MASK_REG regptr(MSP_SLP_BASE + 0xA8)
247 /* ELB CS2 Mask Register */
248#define CS2_ACCESS_REG regptr(MSP_SLP_BASE + 0xAC)
249 /* ELB CS2 access register */
250
251#define CS3_CNFG_REG regptr(MSP_SLP_BASE + 0xB0)
252 /* ELB CS3 Configuration Reg */
253#define CS3_ADDR_REG regptr(MSP_SLP_BASE + 0xB4)
254 /* ELB CS3 Base Address Reg */
255#define CS3_MASK_REG regptr(MSP_SLP_BASE + 0xB8)
256 /* ELB CS3 Mask Register */
257#define CS3_ACCESS_REG regptr(MSP_SLP_BASE + 0xBC)
258 /* ELB CS3 access register */
259
260#define CS4_CNFG_REG regptr(MSP_SLP_BASE + 0xC0)
261 /* ELB CS4 Configuration Reg */
262#define CS4_ADDR_REG regptr(MSP_SLP_BASE + 0xC4)
263 /* ELB CS4 Base Address Reg */
264#define CS4_MASK_REG regptr(MSP_SLP_BASE + 0xC8)
265 /* ELB CS4 Mask Register */
266#define CS4_ACCESS_REG regptr(MSP_SLP_BASE + 0xCC)
267 /* ELB CS4 access register */
268
269#define CS5_CNFG_REG regptr(MSP_SLP_BASE + 0xD0)
270 /* ELB CS5 Configuration Reg */
271#define CS5_ADDR_REG regptr(MSP_SLP_BASE + 0xD4)
272 /* ELB CS5 Base Address Reg */
273#define CS5_MASK_REG regptr(MSP_SLP_BASE + 0xD8)
274 /* ELB CS5 Mask Register */
275#define CS5_ACCESS_REG regptr(MSP_SLP_BASE + 0xDC)
276 /* ELB CS5 access register */
277
278/* reserved 0xE0 - 0xE8 */
279#define ELB_1PC_EN_REG regptr(MSP_SLP_BASE + 0xEC)
280 /* ELB single PC card detect */
281
282/* reserved 0xF0 - 0xF8 */
283#define ELB_CLK_CFG_REG regptr(MSP_SLP_BASE + 0xFC)
284 /* SDRAM read/ELB timing Reg */
285
286/* Extended UART status registers */
287#define UART0_STATUS_REG regptr(MSP_UART0_BASE + 0x0c0)
288 /* UART Status Register 0 */
289#define UART1_STATUS_REG regptr(MSP_UART1_BASE + 0x170)
290 /* UART Status Register 1 */
291
292/* Performance monitoring registers */
293#define PERF_MON_CTRL_REG regptr(MSP_SLP_BASE + 0x140)
294 /* Performance monitor control */
295#define PERF_MON_CLR_REG regptr(MSP_SLP_BASE + 0x144)
296 /* Performance monitor clear */
297#define PERF_MON_CNTH_REG regptr(MSP_SLP_BASE + 0x148)
298 /* Perf monitor counter high */
299#define PERF_MON_CNTL_REG regptr(MSP_SLP_BASE + 0x14C)
300 /* Perf monitor counter low */
301
302/* System control registers */
303#define SYS_CTRL_REG regptr(MSP_SLP_BASE + 0x150)
304 /* System control register */
305#define SYS_ERR1_REG regptr(MSP_SLP_BASE + 0x154)
306 /* System Error status 1 */
307#define SYS_ERR2_REG regptr(MSP_SLP_BASE + 0x158)
308 /* System Error status 2 */
309#define SYS_INT_CFG_REG regptr(MSP_SLP_BASE + 0x15C)
310 /* System Interrupt config */
311
312/* Voice Engine Memory configuration */
313#define VE_MEM_REG regptr(MSP_SLP_BASE + 0x17C)
314 /* Voice engine memory config */
315
316/* CPU/SLP Error Status registers */
317#define CPU_ERR1_REG regptr(MSP_SLP_BASE + 0x180)
318 /* CPU/SLP Error status 1 */
319#define CPU_ERR2_REG regptr(MSP_SLP_BASE + 0x184)
320 /* CPU/SLP Error status 1 */
321
322#define EXTENDED_GPIO_REG regptr(MSP_SLP_BASE + 0x188)
323 /* Extended GPIO register */
324
325/* System Error registers */
326#define SLP_ERR_STS_REG regptr(MSP_SLP_BASE + 0x190)
327 /* Int status for SLP errors */
328#define SLP_ERR_MSK_REG regptr(MSP_SLP_BASE + 0x194)
329 /* Int mask for SLP errors */
330#define SLP_ELB_ERST_REG regptr(MSP_SLP_BASE + 0x198)
331 /* External ELB reset */
332#define SLP_BOOT_STS_REG regptr(MSP_SLP_BASE + 0x19C)
333 /* Boot Status */
334
335/* Extended ELB addressing */
336#define CS0_EXT_ADDR_REG regptr(MSP_SLP_BASE + 0x1A0)
337 /* CS0 Extended address */
338#define CS1_EXT_ADDR_REG regptr(MSP_SLP_BASE + 0x1A4)
339 /* CS1 Extended address */
340#define CS2_EXT_ADDR_REG regptr(MSP_SLP_BASE + 0x1A8)
341 /* CS2 Extended address */
342#define CS3_EXT_ADDR_REG regptr(MSP_SLP_BASE + 0x1AC)
343 /* CS3 Extended address */
344/* reserved 0x1B0 */
345#define CS5_EXT_ADDR_REG regptr(MSP_SLP_BASE + 0x1B4)
346 /* CS5 Extended address */
347
348/* PLL Adjustment registers */
349#define PLL_LOCK_REG regptr(MSP_SLP_BASE + 0x200)
350 /* PLL0 lock status */
351#define PLL_ARST_REG regptr(MSP_SLP_BASE + 0x204)
352 /* PLL Analog reset status */
353#define PLL0_ADJ_REG regptr(MSP_SLP_BASE + 0x208)
354 /* PLL0 Adjustment value */
355#define PLL1_ADJ_REG regptr(MSP_SLP_BASE + 0x20C)
356 /* PLL1 Adjustment value */
357
358/*
359 ***************************************************************************
360 * Peripheral Register definitions *
361 ***************************************************************************
362 */
363
364/* Peripheral status */
365#define PER_CTRL_REG regptr(MSP_PER_BASE + 0x50)
366 /* Peripheral control register */
367#define PER_STS_REG regptr(MSP_PER_BASE + 0x54)
368 /* Peripheral status register */
369
370/* SPI/MPI Registers */
371#define SMPI_TX_SZ_REG regptr(MSP_PER_BASE + 0x58)
372 /* SPI/MPI Tx Size register */
373#define SMPI_RX_SZ_REG regptr(MSP_PER_BASE + 0x5C)
374 /* SPI/MPI Rx Size register */
375#define SMPI_CTL_REG regptr(MSP_PER_BASE + 0x60)
376 /* SPI/MPI Control register */
377#define SMPI_MS_REG regptr(MSP_PER_BASE + 0x64)
378 /* SPI/MPI Chip Select reg */
379#define SMPI_CORE_DATA_REG regptr(MSP_PER_BASE + 0xC0)
380 /* SPI/MPI Core Data reg */
381#define SMPI_CORE_CTRL_REG regptr(MSP_PER_BASE + 0xC4)
382 /* SPI/MPI Core Control reg */
383#define SMPI_CORE_STAT_REG regptr(MSP_PER_BASE + 0xC8)
384 /* SPI/MPI Core Status reg */
385#define SMPI_CORE_SSEL_REG regptr(MSP_PER_BASE + 0xCC)
386 /* SPI/MPI Core Ssel reg */
387#define SMPI_FIFO_REG regptr(MSP_PER_BASE + 0xD0)
388 /* SPI/MPI Data FIFO reg */
389
390/* Peripheral Block Error Registers */
391#define PER_ERR_STS_REG regptr(MSP_PER_BASE + 0x70)
392 /* Error Bit Status Register */
393#define PER_ERR_MSK_REG regptr(MSP_PER_BASE + 0x74)
394 /* Error Bit Mask Register */
395#define PER_HDR1_REG regptr(MSP_PER_BASE + 0x78)
396 /* Error Header 1 Register */
397#define PER_HDR2_REG regptr(MSP_PER_BASE + 0x7C)
398 /* Error Header 2 Register */
399
400/* Peripheral Block Interrupt Registers */
401#define PER_INT_STS_REG regptr(MSP_PER_BASE + 0x80)
402 /* Interrupt status register */
403#define PER_INT_MSK_REG regptr(MSP_PER_BASE + 0x84)
404 /* Interrupt Mask Register */
405#define GPIO_INT_STS_REG regptr(MSP_PER_BASE + 0x88)
406 /* GPIO interrupt status reg */
407#define GPIO_INT_MSK_REG regptr(MSP_PER_BASE + 0x8C)
408 /* GPIO interrupt MASK Reg */
409
410/* POLO GPIO registers */
411#define POLO_GPIO_DAT1_REG regptr(MSP_PER_BASE + 0x0E0)
412 /* Polo GPIO[8:0] data reg */
413#define POLO_GPIO_CFG1_REG regptr(MSP_PER_BASE + 0x0E4)
414 /* Polo GPIO[7:0] config reg */
415#define POLO_GPIO_CFG2_REG regptr(MSP_PER_BASE + 0x0E8)
416 /* Polo GPIO[15:8] config reg */
417#define POLO_GPIO_OD1_REG regptr(MSP_PER_BASE + 0x0EC)
418 /* Polo GPIO[31:0] output drive */
419#define POLO_GPIO_CFG3_REG regptr(MSP_PER_BASE + 0x170)
420 /* Polo GPIO[23:16] config reg */
421#define POLO_GPIO_DAT2_REG regptr(MSP_PER_BASE + 0x174)
422 /* Polo GPIO[15:9] data reg */
423#define POLO_GPIO_DAT3_REG regptr(MSP_PER_BASE + 0x178)
424 /* Polo GPIO[23:16] data reg */
425#define POLO_GPIO_DAT4_REG regptr(MSP_PER_BASE + 0x17C)
426 /* Polo GPIO[31:24] data reg */
427#define POLO_GPIO_DAT5_REG regptr(MSP_PER_BASE + 0x180)
428 /* Polo GPIO[39:32] data reg */
429#define POLO_GPIO_DAT6_REG regptr(MSP_PER_BASE + 0x184)
430 /* Polo GPIO[47:40] data reg */
431#define POLO_GPIO_DAT7_REG regptr(MSP_PER_BASE + 0x188)
432 /* Polo GPIO[54:48] data reg */
433#define POLO_GPIO_CFG4_REG regptr(MSP_PER_BASE + 0x18C)
434 /* Polo GPIO[31:24] config reg */
435#define POLO_GPIO_CFG5_REG regptr(MSP_PER_BASE + 0x190)
436 /* Polo GPIO[39:32] config reg */
437#define POLO_GPIO_CFG6_REG regptr(MSP_PER_BASE + 0x194)
438 /* Polo GPIO[47:40] config reg */
439#define POLO_GPIO_CFG7_REG regptr(MSP_PER_BASE + 0x198)
440 /* Polo GPIO[54:48] config reg */
441#define POLO_GPIO_OD2_REG regptr(MSP_PER_BASE + 0x19C)
442 /* Polo GPIO[54:32] output drive */
443
444/* Generic GPIO registers */
445#define GPIO_DATA1_REG regptr(MSP_PER_BASE + 0x170)
446 /* GPIO[1:0] data register */
447#define GPIO_DATA2_REG regptr(MSP_PER_BASE + 0x174)
448 /* GPIO[5:2] data register */
449#define GPIO_DATA3_REG regptr(MSP_PER_BASE + 0x178)
450 /* GPIO[9:6] data register */
451#define GPIO_DATA4_REG regptr(MSP_PER_BASE + 0x17C)
452 /* GPIO[15:10] data register */
453#define GPIO_CFG1_REG regptr(MSP_PER_BASE + 0x180)
454 /* GPIO[1:0] config register */
455#define GPIO_CFG2_REG regptr(MSP_PER_BASE + 0x184)
456 /* GPIO[5:2] config register */
457#define GPIO_CFG3_REG regptr(MSP_PER_BASE + 0x188)
458 /* GPIO[9:6] config register */
459#define GPIO_CFG4_REG regptr(MSP_PER_BASE + 0x18C)
460 /* GPIO[15:10] config register */
461#define GPIO_OD_REG regptr(MSP_PER_BASE + 0x190)
462 /* GPIO[15:0] output drive */
463
464/*
465 ***************************************************************************
466 * CPU Interface register definitions *
467 ***************************************************************************
468 */
469#define PCI_FLUSH_REG regptr(MSP_CPUIF_BASE + 0x00)
470 /* PCI-SDRAM queue flush trigger */
471#define OCP_ERR1_REG regptr(MSP_CPUIF_BASE + 0x04)
472 /* OCP Error Attribute 1 */
473#define OCP_ERR2_REG regptr(MSP_CPUIF_BASE + 0x08)
474 /* OCP Error Attribute 2 */
475#define OCP_STS_REG regptr(MSP_CPUIF_BASE + 0x0C)
476 /* OCP Error Status */
477#define CPUIF_PM_REG regptr(MSP_CPUIF_BASE + 0x10)
478 /* CPU policy configuration */
479#define CPUIF_CFG_REG regptr(MSP_CPUIF_BASE + 0x10)
480 /* Misc configuration options */
481
482/* Central Interrupt Controller Registers */
483#define MSP_CIC_BASE (MSP_CPUIF_BASE + 0x8000)
484 /* Central Interrupt registers */
485#define CIC_EXT_CFG_REG regptr(MSP_CIC_BASE + 0x00)
486 /* External interrupt config */
487#define CIC_STS_REG regptr(MSP_CIC_BASE + 0x04)
488 /* CIC Interrupt Status */
489#define CIC_VPE0_MSK_REG regptr(MSP_CIC_BASE + 0x08)
490 /* VPE0 Interrupt Mask */
491#define CIC_VPE1_MSK_REG regptr(MSP_CIC_BASE + 0x0C)
492 /* VPE1 Interrupt Mask */
493#define CIC_TC0_MSK_REG regptr(MSP_CIC_BASE + 0x10)
494 /* Thread Context 0 Int Mask */
495#define CIC_TC1_MSK_REG regptr(MSP_CIC_BASE + 0x14)
496 /* Thread Context 1 Int Mask */
497#define CIC_TC2_MSK_REG regptr(MSP_CIC_BASE + 0x18)
498 /* Thread Context 2 Int Mask */
499#define CIC_TC3_MSK_REG regptr(MSP_CIC_BASE + 0x18)
500 /* Thread Context 3 Int Mask */
501#define CIC_TC4_MSK_REG regptr(MSP_CIC_BASE + 0x18)
502 /* Thread Context 4 Int Mask */
503#define CIC_PCIMSI_STS_REG regptr(MSP_CIC_BASE + 0x18)
504#define CIC_PCIMSI_MSK_REG regptr(MSP_CIC_BASE + 0x18)
505#define CIC_PCIFLSH_REG regptr(MSP_CIC_BASE + 0x18)
506#define CIC_VPE0_SWINT_REG regptr(MSP_CIC_BASE + 0x08)
507
508
509/*
510 ***************************************************************************
511 * Memory controller registers *
512 ***************************************************************************
513 */
514#define MEM_CFG1_REG regptr(MSP_MEM_CFG_BASE + 0x00)
515#define MEM_SS_ADDR regptr(MSP_MEM_CFG_BASE + 0x00)
516#define MEM_SS_DATA regptr(MSP_MEM_CFG_BASE + 0x04)
517#define MEM_SS_WRITE regptr(MSP_MEM_CFG_BASE + 0x08)
518
519/*
520 ***************************************************************************
521 * PCI controller registers *
522 ***************************************************************************
523 */
524#define PCI_BASE_REG regptr(MSP_PCI_BASE + 0x00)
525#define PCI_CONFIG_SPACE_REG regptr(MSP_PCI_BASE + 0x800)
526#define PCI_JTAG_DEVID_REG regptr(MSP_SLP_BASE + 0x13c)
527
528/*
529 ########################################################################
530 # Register content & macro definitions #
531 ########################################################################
532 */
533
534/*
535 ***************************************************************************
536 * DEV_ID defines *
537 ***************************************************************************
538 */
539#define DEV_ID_PCI_DIS (1 << 26) /* Set if PCI disabled */
540#define DEV_ID_PCI_HOST (1 << 20) /* Set if PCI host */
541#define DEV_ID_SINGLE_PC (1 << 19) /* Set if single PC Card */
542#define DEV_ID_FAMILY (0xff << 8) /* family ID code */
543#define POLO_ZEUS_SUB_FAMILY (0x7 << 16) /* sub family for Polo/Zeus */
544
545#define MSPFPGA_ID (0x00 << 8) /* you are on your own here */
546#define MSP5000_ID (0x50 << 8)
547#define MSP4F00_ID (0x4f << 8) /* FPGA version of MSP4200 */
548#define MSP4E00_ID (0x4f << 8) /* FPGA version of MSP7120 */
549#define MSP4200_ID (0x42 << 8)
550#define MSP4000_ID (0x40 << 8)
551#define MSP2XXX_ID (0x20 << 8)
552#define MSPZEUS_ID (0x10 << 8)
553
554#define MSP2004_SUB_ID (0x0 << 16)
555#define MSP2005_SUB_ID (0x1 << 16)
556#define MSP2006_SUB_ID (0x1 << 16)
557#define MSP2007_SUB_ID (0x2 << 16)
558#define MSP2010_SUB_ID (0x3 << 16)
559#define MSP2015_SUB_ID (0x4 << 16)
560#define MSP2020_SUB_ID (0x5 << 16)
561#define MSP2100_SUB_ID (0x6 << 16)
562
563/*
564 ***************************************************************************
565 * RESET defines *
566 ***************************************************************************
567 */
568#define MSP_GR_RST (0x01 << 0) /* Global reset bit */
569#define MSP_MR_RST (0x01 << 1) /* MIPS reset bit */
570#define MSP_PD_RST (0x01 << 2) /* PVC DMA reset bit */
571#define MSP_PP_RST (0x01 << 3) /* PVC reset bit */
572/* reserved */
573#define MSP_EA_RST (0x01 << 6) /* Mac A reset bit */
574#define MSP_EB_RST (0x01 << 7) /* Mac B reset bit */
575#define MSP_SE_RST (0x01 << 8) /* Security Eng reset bit */
576#define MSP_PB_RST (0x01 << 9) /* Per block reset bit */
577#define MSP_EC_RST (0x01 << 10) /* Mac C reset bit */
578#define MSP_TW_RST (0x01 << 11) /* TWI reset bit */
579#define MSP_SPI_RST (0x01 << 12) /* SPI/MPI reset bit */
580#define MSP_U1_RST (0x01 << 13) /* UART1 reset bit */
581#define MSP_U0_RST (0x01 << 14) /* UART0 reset bit */
582
583/*
584 ***************************************************************************
585 * UART defines *
586 ***************************************************************************
587 */
588#ifndef CONFIG_MSP_FPGA
589#define MSP_BASE_BAUD 25000000
590#else
591#define MSP_BASE_BAUD 6000000
592#endif
593#define MSP_UART_REG_LEN 0x20
594
595/*
596 ***************************************************************************
597 * ELB defines *
598 ***************************************************************************
599 */
600#define PCCARD_32 0x02 /* Set if is PCCARD 32 (Cardbus) */
601#define SINGLE_PCCARD 0x01 /* Set to enable single PC card */
602
603/*
604 ***************************************************************************
605 * CIC defines *
606 ***************************************************************************
607 */
608
609/* CIC_EXT_CFG_REG */
610#define EXT_INT_POL(eirq) (1 << (eirq + 8))
611#define EXT_INT_EDGE(eirq) (1 << eirq)
612
613#define CIC_EXT_SET_TRIGGER_LEVEL(reg, eirq) (reg &= ~EXT_INT_EDGE(eirq))
614#define CIC_EXT_SET_TRIGGER_EDGE(reg, eirq) (reg |= EXT_INT_EDGE(eirq))
615#define CIC_EXT_SET_ACTIVE_HI(reg, eirq) (reg |= EXT_INT_POL(eirq))
616#define CIC_EXT_SET_ACTIVE_LO(reg, eirq) (reg &= ~EXT_INT_POL(eirq))
617#define CIC_EXT_SET_ACTIVE_RISING CIC_EXT_SET_ACTIVE_HI
618#define CIC_EXT_SET_ACTIVE_FALLING CIC_EXT_SET_ACTIVE_LO
619
620#define CIC_EXT_IS_TRIGGER_LEVEL(reg, eirq) \
621 ((reg & EXT_INT_EDGE(eirq)) == 0)
622#define CIC_EXT_IS_TRIGGER_EDGE(reg, eirq) (reg & EXT_INT_EDGE(eirq))
623#define CIC_EXT_IS_ACTIVE_HI(reg, eirq) (reg & EXT_INT_POL(eirq))
624#define CIC_EXT_IS_ACTIVE_LO(reg, eirq) \
625 ((reg & EXT_INT_POL(eirq)) == 0)
626#define CIC_EXT_IS_ACTIVE_RISING CIC_EXT_IS_ACTIVE_HI
627#define CIC_EXT_IS_ACTIVE_FALLING CIC_EXT_IS_ACTIVE_LO
628
629/*
630 ***************************************************************************
631 * Memory Controller defines *
632 ***************************************************************************
633 */
634
635/* Indirect memory controller registers */
636#define DDRC_CFG(n) (n)
637#define DDRC_DEBUG(n) (0x04 + n)
638#define DDRC_CTL(n) (0x40 + n)
639
640/* Macro to perform DDRC indirect write */
641#define DDRC_INDIRECT_WRITE(reg, mask, value) \
642({ \
643 *MEM_SS_ADDR = (((mask) & 0xf) << 8) | ((reg) & 0xff); \
644 *MEM_SS_DATA = (value); \
645 *MEM_SS_WRITE = 1; \
646})
647
648/*
649 ***************************************************************************
650 * SPI/MPI Mode *
651 ***************************************************************************
652 */
653#define SPI_MPI_RX_BUSY 0x00008000 /* SPI/MPI Receive Busy */
654#define SPI_MPI_FIFO_EMPTY 0x00004000 /* SPI/MPI Fifo Empty */
655#define SPI_MPI_TX_BUSY 0x00002000 /* SPI/MPI Transmit Busy */
656#define SPI_MPI_FIFO_FULL 0x00001000 /* SPI/MPU FIFO full */
657
658/*
659 ***************************************************************************
660 * SPI/MPI Control Register *
661 ***************************************************************************
662 */
663#define SPI_MPI_RX_START 0x00000004 /* Start receive command */
664#define SPI_MPI_FLUSH_Q 0x00000002 /* Flush SPI/MPI Queue */
665#define SPI_MPI_TX_START 0x00000001 /* Start Transmit Command */
666
667#endif /* !_ASM_MSP_REGS_H */
diff --git a/include/asm-mips/pmc-sierra/msp71xx/msp_slp_int.h b/include/asm-mips/pmc-sierra/msp71xx/msp_slp_int.h
new file mode 100644
index 000000000000..96d4c8ce8c83
--- /dev/null
+++ b/include/asm-mips/pmc-sierra/msp71xx/msp_slp_int.h
@@ -0,0 +1,141 @@
1/*
2 * Defines for the MSP interrupt controller.
3 *
4 * Copyright (C) 1999 MIPS Technologies, Inc. All rights reserved.
5 * Author: Carsten Langgaard, carstenl@mips.com
6 *
7 * ########################################################################
8 *
9 * This program is free software; you can distribute it and/or modify it
10 * under the terms of the GNU General Public License (Version 2) as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 * for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
21 *
22 * ########################################################################
23 */
24
25#ifndef _MSP_SLP_INT_H
26#define _MSP_SLP_INT_H
27
28/*
29 * The PMC-Sierra SLP interrupts are arranged in a 3 level cascaded
30 * hierarchical system. The first level are the direct MIPS interrupts
31 * and are assigned the interrupt range 0-7. The second level is the SLM
32 * interrupt controller and is assigned the range 8-39. The third level
33 * comprises the Peripherial block, the PCI block, the PCI MSI block and
34 * the SLP. The PCI interrupts and the SLP errors are handled by the
35 * relevant subsystems so the core interrupt code needs only concern
36 * itself with the Peripheral block. These are assigned interrupts in
37 * the range 40-71.
38 */
39
40/*
41 * IRQs directly connected to CPU
42 */
43#define MSP_MIPS_INTBASE 0
44#define MSP_INT_SW0 0 /* IRQ for swint0, C_SW0 */
45#define MSP_INT_SW1 1 /* IRQ for swint1, C_SW1 */
46#define MSP_INT_MAC0 2 /* IRQ for MAC 0, C_IRQ0 */
47#define MSP_INT_MAC1 3 /* IRQ for MAC 1, C_IRQ1 */
48#define MSP_INT_C_IRQ2 4 /* Wired off, C_IRQ2 */
49#define MSP_INT_VE 5 /* IRQ for Voice Engine, C_IRQ3 */
50#define MSP_INT_SLP 6 /* IRQ for SLM block, C_IRQ4 */
51#define MSP_INT_TIMER 7 /* IRQ for the MIPS timer, C_IRQ5 */
52
53/*
54 * IRQs cascaded on CPU interrupt 4 (CAUSE bit 12, C_IRQ4)
55 * These defines should be tied to the register definition for the SLM
56 * interrupt routine. For now, just use hard-coded values.
57 */
58#define MSP_SLP_INTBASE (MSP_MIPS_INTBASE + 8)
59#define MSP_INT_EXT0 (MSP_SLP_INTBASE + 0)
60 /* External interrupt 0 */
61#define MSP_INT_EXT1 (MSP_SLP_INTBASE + 1)
62 /* External interrupt 1 */
63#define MSP_INT_EXT2 (MSP_SLP_INTBASE + 2)
64 /* External interrupt 2 */
65#define MSP_INT_EXT3 (MSP_SLP_INTBASE + 3)
66 /* External interrupt 3 */
67/* Reserved 4-7 */
68
69/*
70 *************************************************************************
71 * DANGER/DANGER/DANGER/DANGER/DANGER/DANGER/DANGER/DANGER/DANGER/DANGER *
72 * Some MSP produces have this interrupt labelled as Voice and some are *
73 * SEC mbox ... *
74 *************************************************************************
75 */
76#define MSP_INT_SLP_VE (MSP_SLP_INTBASE + 8)
77 /* Cascaded IRQ for Voice Engine*/
78#define MSP_INT_SLP_TDM (MSP_SLP_INTBASE + 9)
79 /* TDM interrupt */
80#define MSP_INT_SLP_MAC0 (MSP_SLP_INTBASE + 10)
81 /* Cascaded IRQ for MAC 0 */
82#define MSP_INT_SLP_MAC1 (MSP_SLP_INTBASE + 11)
83 /* Cascaded IRQ for MAC 1 */
84#define MSP_INT_SEC (MSP_SLP_INTBASE + 12)
85 /* IRQ for security engine */
86#define MSP_INT_PER (MSP_SLP_INTBASE + 13)
87 /* Peripheral interrupt */
88#define MSP_INT_TIMER0 (MSP_SLP_INTBASE + 14)
89 /* SLP timer 0 */
90#define MSP_INT_TIMER1 (MSP_SLP_INTBASE + 15)
91 /* SLP timer 1 */
92#define MSP_INT_TIMER2 (MSP_SLP_INTBASE + 16)
93 /* SLP timer 2 */
94#define MSP_INT_SLP_TIMER (MSP_SLP_INTBASE + 17)
95 /* Cascaded MIPS timer */
96#define MSP_INT_BLKCP (MSP_SLP_INTBASE + 18)
97 /* Block Copy */
98#define MSP_INT_UART0 (MSP_SLP_INTBASE + 19)
99 /* UART 0 */
100#define MSP_INT_PCI (MSP_SLP_INTBASE + 20)
101 /* PCI subsystem */
102#define MSP_INT_PCI_DBELL (MSP_SLP_INTBASE + 21)
103 /* PCI doorbell */
104#define MSP_INT_PCI_MSI (MSP_SLP_INTBASE + 22)
105 /* PCI Message Signal */
106#define MSP_INT_PCI_BC0 (MSP_SLP_INTBASE + 23)
107 /* PCI Block Copy 0 */
108#define MSP_INT_PCI_BC1 (MSP_SLP_INTBASE + 24)
109 /* PCI Block Copy 1 */
110#define MSP_INT_SLP_ERR (MSP_SLP_INTBASE + 25)
111 /* SLP error condition */
112#define MSP_INT_MAC2 (MSP_SLP_INTBASE + 26)
113 /* IRQ for MAC2 */
114/* Reserved 26-31 */
115
116/*
117 * IRQs cascaded on SLP PER interrupt (MSP_INT_PER)
118 */
119#define MSP_PER_INTBASE (MSP_SLP_INTBASE + 32)
120/* Reserved 0-1 */
121#define MSP_INT_UART1 (MSP_PER_INTBASE + 2)
122 /* UART 1 */
123/* Reserved 3-5 */
124#define MSP_INT_2WIRE (MSP_PER_INTBASE + 6)
125 /* 2-wire */
126#define MSP_INT_TM0 (MSP_PER_INTBASE + 7)
127 /* Peripheral timer block out 0 */
128#define MSP_INT_TM1 (MSP_PER_INTBASE + 8)
129 /* Peripheral timer block out 1 */
130/* Reserved 9 */
131#define MSP_INT_SPRX (MSP_PER_INTBASE + 10)
132 /* SPI RX complete */
133#define MSP_INT_SPTX (MSP_PER_INTBASE + 11)
134 /* SPI TX complete */
135#define MSP_INT_GPIO (MSP_PER_INTBASE + 12)
136 /* GPIO */
137#define MSP_INT_PER_ERR (MSP_PER_INTBASE + 13)
138 /* Peripheral error */
139/* Reserved 14-31 */
140
141#endif /* !_MSP_SLP_INT_H */
diff --git a/include/asm-mips/processor.h b/include/asm-mips/processor.h
index 5f80ba71ab92..1d8b9a8ae324 100644
--- a/include/asm-mips/processor.h
+++ b/include/asm-mips/processor.h
@@ -82,10 +82,6 @@ struct mips_fpu_struct {
82 unsigned int fcr31; 82 unsigned int fcr31;
83}; 83};
84 84
85#define INIT_FPU { \
86 {0,} \
87}
88
89#define NUM_DSP_REGS 6 85#define NUM_DSP_REGS 6
90 86
91typedef __u32 dspreg_t; 87typedef __u32 dspreg_t;
@@ -95,8 +91,6 @@ struct mips_dsp_state {
95 unsigned int dspcontrol; 91 unsigned int dspcontrol;
96}; 92};
97 93
98#define INIT_DSP {{0,},}
99
100#define INIT_CPUMASK { \ 94#define INIT_CPUMASK { \
101 {0,} \ 95 {0,} \
102} 96}
@@ -155,41 +149,63 @@ struct thread_struct {
155#define MF_N64 0 149#define MF_N64 0
156 150
157#ifdef CONFIG_MIPS_MT_FPAFF 151#ifdef CONFIG_MIPS_MT_FPAFF
158#define FPAFF_INIT 0, INIT_CPUMASK, 152#define FPAFF_INIT \
153 .emulated_fp = 0, \
154 .user_cpus_allowed = INIT_CPUMASK,
159#else 155#else
160#define FPAFF_INIT 156#define FPAFF_INIT
161#endif /* CONFIG_MIPS_MT_FPAFF */ 157#endif /* CONFIG_MIPS_MT_FPAFF */
162 158
163#define INIT_THREAD { \ 159#define INIT_THREAD { \
164 /* \ 160 /* \
165 * saved main processor registers \ 161 * Saved main processor registers \
166 */ \ 162 */ \
167 0, 0, 0, 0, 0, 0, 0, 0, \ 163 .reg16 = 0, \
168 0, 0, 0, \ 164 .reg17 = 0, \
169 /* \ 165 .reg18 = 0, \
170 * saved cp0 stuff \ 166 .reg19 = 0, \
171 */ \ 167 .reg20 = 0, \
172 0, \ 168 .reg21 = 0, \
173 /* \ 169 .reg22 = 0, \
174 * saved fpu/fpu emulator stuff \ 170 .reg23 = 0, \
175 */ \ 171 .reg29 = 0, \
176 INIT_FPU, \ 172 .reg30 = 0, \
177 /* \ 173 .reg31 = 0, \
178 * fpu affinity state (null if not FPAFF) \ 174 /* \
179 */ \ 175 * Saved cp0 stuff \
180 FPAFF_INIT \ 176 */ \
181 /* \ 177 .cp0_status = 0, \
182 * saved dsp/dsp emulator stuff \ 178 /* \
183 */ \ 179 * Saved FPU/FPU emulator stuff \
184 INIT_DSP, \ 180 */ \
185 /* \ 181 .fpu = { \
186 * Other stuff associated with the process \ 182 .fpr = {0,}, \
187 */ \ 183 .fcr31 = 0, \
188 0, 0, 0, 0, \ 184 }, \
189 /* \ 185 /* \
190 * For now the default is to fix address errors \ 186 * FPU affinity state (null if not FPAFF) \
191 */ \ 187 */ \
192 MF_FIXADE, 0, 0 \ 188 FPAFF_INIT \
189 /* \
190 * Saved DSP stuff \
191 */ \
192 .dsp = { \
193 .dspr = {0, }, \
194 .dspcontrol = 0, \
195 }, \
196 /* \
197 * Other stuff associated with the process \
198 */ \
199 .cp0_badvaddr = 0, \
200 .cp0_baduaddr = 0, \
201 .error_code = 0, \
202 .trap_no = 0, \
203 /* \
204 * For now the default is to fix address errors \
205 */ \
206 .mflags = MF_FIXADE, \
207 .irix_trampoline = 0, \
208 .irix_oldctx = 0, \
193} 209}
194 210
195struct task_struct; 211struct task_struct;
@@ -237,7 +253,7 @@ unsigned long get_wchan(struct task_struct *p);
237 253
238#define ARCH_HAS_PREFETCH 254#define ARCH_HAS_PREFETCH
239 255
240extern inline void prefetch(const void *addr) 256static inline void prefetch(const void *addr)
241{ 257{
242 __asm__ __volatile__( 258 __asm__ __volatile__(
243 " .set mips4 \n" 259 " .set mips4 \n"
diff --git a/include/asm-mips/serial.h b/include/asm-mips/serial.h
index ce51213d84f9..c07ebd8eb9e7 100644
--- a/include/asm-mips/serial.h
+++ b/include/asm-mips/serial.h
@@ -19,159 +19,4 @@
19 */ 19 */
20#define BASE_BAUD (1843200 / 16) 20#define BASE_BAUD (1843200 / 16)
21 21
22/* Standard COM flags (except for COM4, because of the 8514 problem) */
23#ifdef CONFIG_SERIAL_DETECT_IRQ
24#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ)
25#define STD_COM4_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_AUTO_IRQ)
26#else
27#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
28#define STD_COM4_FLAGS ASYNC_BOOT_AUTOCONF
29#endif
30
31#ifdef CONFIG_MACH_JAZZ
32#include <asm/jazz.h>
33
34#ifndef CONFIG_OLIVETTI_M700
35 /* Some Jazz machines seem to have an 8MHz crystal clock but I don't know
36 exactly which ones ... XXX */
37#define JAZZ_BASE_BAUD ( 8000000 / 16 ) /* ( 3072000 / 16) */
38#else
39/* but the M700 isn't such a strange beast */
40#define JAZZ_BASE_BAUD BASE_BAUD
41#endif
42
43#define _JAZZ_SERIAL_INIT(int, base) \
44 { .baud_base = JAZZ_BASE_BAUD, .irq = int, .flags = STD_COM_FLAGS, \
45 .iomem_base = (u8 *) base, .iomem_reg_shift = 0, \
46 .io_type = SERIAL_IO_MEM }
47#define JAZZ_SERIAL_PORT_DEFNS \
48 _JAZZ_SERIAL_INIT(JAZZ_SERIAL1_IRQ, JAZZ_SERIAL1_BASE), \
49 _JAZZ_SERIAL_INIT(JAZZ_SERIAL2_IRQ, JAZZ_SERIAL2_BASE),
50#else
51#define JAZZ_SERIAL_PORT_DEFNS
52#endif
53
54/*
55 * Galileo EV64120 evaluation board
56 */
57#ifdef CONFIG_MIPS_EV64120
58#include <mach-gt64120.h>
59#define EV64120_SERIAL_PORT_DEFNS \
60 { .baud_base = EV64120_BASE_BAUD, .irq = EV64120_UART_IRQ, \
61 .flags = STD_COM_FLAGS, \
62 .iomem_base = EV64120_UART0_REGS_BASE, .iomem_reg_shift = 2, \
63 .io_type = SERIAL_IO_MEM }, \
64 { .baud_base = EV64120_BASE_BAUD, .irq = EV64120_UART_IRQ, \
65 .flags = STD_COM_FLAGS, \
66 .iomem_base = EV64120_UART1_REGS_BASE, .iomem_reg_shift = 2, \
67 .io_type = SERIAL_IO_MEM },
68#else
69#define EV64120_SERIAL_PORT_DEFNS
70#endif
71
72#ifdef CONFIG_HAVE_STD_PC_SERIAL_PORT
73#define STD_SERIAL_PORT_DEFNS \
74 /* UART CLK PORT IRQ FLAGS */ \
75 { 0, BASE_BAUD, 0x3F8, 4, STD_COM_FLAGS }, /* ttyS0 */ \
76 { 0, BASE_BAUD, 0x2F8, 3, STD_COM_FLAGS }, /* ttyS1 */ \
77 { 0, BASE_BAUD, 0x3E8, 4, STD_COM_FLAGS }, /* ttyS2 */ \
78 { 0, BASE_BAUD, 0x2E8, 3, STD_COM4_FLAGS }, /* ttyS3 */
79
80#else /* CONFIG_HAVE_STD_PC_SERIAL_PORTS */
81#define STD_SERIAL_PORT_DEFNS
82#endif /* CONFIG_HAVE_STD_PC_SERIAL_PORTS */
83
84#ifdef CONFIG_MOMENCO_OCELOT_3
85#define OCELOT_3_BASE_BAUD ( 20000000 / 16 )
86#define OCELOT_3_SERIAL_IRQ 6
87#define OCELOT_3_SERIAL_BASE (signed)0xfd000020
88
89#define _OCELOT_3_SERIAL_INIT(int, base) \
90 { .baud_base = OCELOT_3_BASE_BAUD, irq: int, \
91 .flags = STD_COM_FLAGS, \
92 .iomem_base = (u8 *) base, iomem_reg_shift: 2, \
93 io_type: SERIAL_IO_MEM }
94
95#define MOMENCO_OCELOT_3_SERIAL_PORT_DEFNS \
96 _OCELOT_3_SERIAL_INIT(OCELOT_3_SERIAL_IRQ, OCELOT_3_SERIAL_BASE)
97#else
98#define MOMENCO_OCELOT_3_SERIAL_PORT_DEFNS
99#endif
100
101#ifdef CONFIG_MOMENCO_OCELOT
102/* Ordinary NS16552 duart with a 20MHz crystal. */
103#define OCELOT_BASE_BAUD ( 20000000 / 16 )
104
105#define OCELOT_SERIAL1_IRQ 4
106#define OCELOT_SERIAL1_BASE 0xe0001020
107
108#define _OCELOT_SERIAL_INIT(int, base) \
109 { .baud_base = OCELOT_BASE_BAUD, .irq = int, .flags = STD_COM_FLAGS, \
110 .iomem_base = (u8 *) base, .iomem_reg_shift = 2, \
111 .io_type = SERIAL_IO_MEM }
112#define MOMENCO_OCELOT_SERIAL_PORT_DEFNS \
113 _OCELOT_SERIAL_INIT(OCELOT_SERIAL1_IRQ, OCELOT_SERIAL1_BASE)
114#else
115#define MOMENCO_OCELOT_SERIAL_PORT_DEFNS
116#endif
117
118#ifdef CONFIG_MOMENCO_OCELOT_C
119/* Ordinary NS16552 duart with a 20MHz crystal. */
120#define OCELOT_C_BASE_BAUD ( 20000000 / 16 )
121
122#define OCELOT_C_SERIAL1_IRQ 80
123#define OCELOT_C_SERIAL1_BASE 0xfd000020
124
125#define OCELOT_C_SERIAL2_IRQ 81
126#define OCELOT_C_SERIAL2_BASE 0xfd000000
127
128#define _OCELOT_C_SERIAL_INIT(int, base) \
129 { .baud_base = OCELOT_C_BASE_BAUD, \
130 .irq = (int), \
131 .flags = STD_COM_FLAGS, \
132 .iomem_base = (u8 *) base, \
133 .iomem_reg_shift = 2, \
134 .io_type = SERIAL_IO_MEM \
135 }
136#define MOMENCO_OCELOT_C_SERIAL_PORT_DEFNS \
137 _OCELOT_C_SERIAL_INIT(OCELOT_C_SERIAL1_IRQ, OCELOT_C_SERIAL1_BASE), \
138 _OCELOT_C_SERIAL_INIT(OCELOT_C_SERIAL2_IRQ, OCELOT_C_SERIAL2_BASE)
139#else
140#define MOMENCO_OCELOT_C_SERIAL_PORT_DEFNS
141#endif
142
143#ifdef CONFIG_DDB5477
144#include <asm/ddb5xxx/ddb5477.h>
145#define DDB5477_SERIAL_PORT_DEFNS \
146 { .baud_base = BASE_BAUD, .irq = VRC5477_IRQ_UART0, \
147 .flags = STD_COM_FLAGS, .iomem_base = (u8*)0xbfa04200, \
148 .iomem_reg_shift = 3, .io_type = SERIAL_IO_MEM}, \
149 { .baud_base = BASE_BAUD, .irq = VRC5477_IRQ_UART1, \
150 .flags = STD_COM_FLAGS, .iomem_base = (u8*)0xbfa04240, \
151 .iomem_reg_shift = 3, .io_type = SERIAL_IO_MEM},
152#else
153#define DDB5477_SERIAL_PORT_DEFNS
154#endif
155
156#ifdef CONFIG_SGI_IP32
157/*
158 * The IP32 (SGI O2) has standard serial ports (UART 16550A) mapped in memory
159 * They are initialized in ip32_setup
160 */
161#define IP32_SERIAL_PORT_DEFNS \
162 {},{},
163#else
164#define IP32_SERIAL_PORT_DEFNS
165#endif /* CONFIG_SGI_IP32 */
166
167#define SERIAL_PORT_DFNS \
168 DDB5477_SERIAL_PORT_DEFNS \
169 EV64120_SERIAL_PORT_DEFNS \
170 IP32_SERIAL_PORT_DEFNS \
171 JAZZ_SERIAL_PORT_DEFNS \
172 STD_SERIAL_PORT_DEFNS \
173 MOMENCO_OCELOT_C_SERIAL_PORT_DEFNS \
174 MOMENCO_OCELOT_SERIAL_PORT_DEFNS \
175 MOMENCO_OCELOT_3_SERIAL_PORT_DEFNS
176
177#endif /* _ASM_SERIAL_H */ 22#endif /* _ASM_SERIAL_H */
diff --git a/include/asm-mips/smp.h b/include/asm-mips/smp.h
index 1608fd71d6f7..13aef6af422c 100644
--- a/include/asm-mips/smp.h
+++ b/include/asm-mips/smp.h
@@ -49,13 +49,6 @@ extern struct call_data_struct *call_data;
49extern cpumask_t phys_cpu_present_map; 49extern cpumask_t phys_cpu_present_map;
50#define cpu_possible_map phys_cpu_present_map 50#define cpu_possible_map phys_cpu_present_map
51 51
52extern cpumask_t cpu_callout_map;
53/* We don't mark CPUs online until __cpu_up(), so we need another measure */
54static inline int num_booting_cpus(void)
55{
56 return cpus_weight(cpu_callout_map);
57}
58
59/* 52/*
60 * These are defined by the board-specific code. 53 * These are defined by the board-specific code.
61 */ 54 */
diff --git a/include/asm-mips/sni.h b/include/asm-mips/sni.h
index f257509b914f..ddaf36a1e389 100644
--- a/include/asm-mips/sni.h
+++ b/include/asm-mips/sni.h
@@ -146,9 +146,6 @@ extern unsigned int sni_brd_type;
146#define SNI_A20R_IRQ_BASE MIPS_CPU_IRQ_BASE 146#define SNI_A20R_IRQ_BASE MIPS_CPU_IRQ_BASE
147#define SNI_A20R_IRQ_TIMER (SNI_A20R_IRQ_BASE+5) 147#define SNI_A20R_IRQ_TIMER (SNI_A20R_IRQ_BASE+5)
148 148
149#define SNI_DS1216_A20R_BASE 0xbc081ffc
150#define SNI_DS1216_RM200_BASE 0xbcd41ffc
151
152#define SNI_PCIT_INT_REG 0xbfff000c 149#define SNI_PCIT_INT_REG 0xbfff000c
153 150
154#define SNI_PCIT_INT_START 24 151#define SNI_PCIT_INT_START 24
diff --git a/include/asm-mips/system.h b/include/asm-mips/system.h
index bb0b289dbc9e..46bdb3f566f9 100644
--- a/include/asm-mips/system.h
+++ b/include/asm-mips/system.h
@@ -44,7 +44,7 @@ struct task_struct;
44 * different thread. 44 * different thread.
45 */ 45 */
46 46
47#define switch_to(prev,next,last) \ 47#define __mips_mt_fpaff_switch_to(prev) \
48do { \ 48do { \
49 if (cpu_has_fpu && \ 49 if (cpu_has_fpu && \
50 (prev->thread.mflags & MF_FPUBOUND) && \ 50 (prev->thread.mflags & MF_FPUBOUND) && \
@@ -52,24 +52,24 @@ do { \
52 prev->thread.mflags &= ~MF_FPUBOUND; \ 52 prev->thread.mflags &= ~MF_FPUBOUND; \
53 prev->cpus_allowed = prev->thread.user_cpus_allowed; \ 53 prev->cpus_allowed = prev->thread.user_cpus_allowed; \
54 } \ 54 } \
55 if (cpu_has_dsp) \
56 __save_dsp(prev); \
57 next->thread.emulated_fp = 0; \ 55 next->thread.emulated_fp = 0; \
58 (last) = resume(prev, next, task_thread_info(next)); \
59 if (cpu_has_dsp) \
60 __restore_dsp(current); \
61} while(0) 56} while(0)
62 57
63#else 58#else
59#define __mips_mt_fpaff_switch_to(prev) do { (void) (prev); } while (0)
60#endif
61
64#define switch_to(prev,next,last) \ 62#define switch_to(prev,next,last) \
65do { \ 63do { \
64 __mips_mt_fpaff_switch_to(prev); \
66 if (cpu_has_dsp) \ 65 if (cpu_has_dsp) \
67 __save_dsp(prev); \ 66 __save_dsp(prev); \
68 (last) = resume(prev, next, task_thread_info(next)); \ 67 (last) = resume(prev, next, task_thread_info(next)); \
69 if (cpu_has_dsp) \ 68 if (cpu_has_dsp) \
70 __restore_dsp(current); \ 69 __restore_dsp(current); \
70 if (cpu_has_userlocal) \
71 write_c0_userlocal(task_thread_info(current)->tp_value);\
71} while(0) 72} while(0)
72#endif
73 73
74/* 74/*
75 * On SMP systems, when the scheduler does migration-cost autodetection, 75 * On SMP systems, when the scheduler does migration-cost autodetection,
diff --git a/include/asm-mips/tx4938/rbtx4938.h b/include/asm-mips/tx4938/rbtx4938.h
index 0fbedafdcea8..74e7d8061e58 100644
--- a/include/asm-mips/tx4938/rbtx4938.h
+++ b/include/asm-mips/tx4938/rbtx4938.h
@@ -105,12 +105,6 @@
105#define rbtx4938_pcireset_ptr \ 105#define rbtx4938_pcireset_ptr \
106 ((volatile unsigned char *)RBTX4938_PCIRESET_ADDR) 106 ((volatile unsigned char *)RBTX4938_PCIRESET_ADDR)
107 107
108/* SPI */
109#define RBTX4938_SEEPROM1_CHIPID 0
110#define RBTX4938_SEEPROM2_CHIPID 1
111#define RBTX4938_SEEPROM3_CHIPID 2
112#define RBTX4938_SRTC_CHIPID 3
113
114/* 108/*
115 * IRQ mappings 109 * IRQ mappings
116 */ 110 */
diff --git a/include/asm-mips/tx4938/spi.h b/include/asm-mips/tx4938/spi.h
index 0dbbab820a5a..6a60c83e152b 100644
--- a/include/asm-mips/tx4938/spi.h
+++ b/include/asm-mips/tx4938/spi.h
@@ -14,61 +14,7 @@
14#ifndef __ASM_TX_BOARDS_TX4938_SPI_H 14#ifndef __ASM_TX_BOARDS_TX4938_SPI_H
15#define __ASM_TX_BOARDS_TX4938_SPI_H 15#define __ASM_TX_BOARDS_TX4938_SPI_H
16 16
17/* SPI */ 17extern int spi_eeprom_register(int chipid);
18struct spi_dev_desc {
19 unsigned int baud;
20 unsigned short tcss, tcsh, tcsr; /* CS setup/hold/recovery time */
21 unsigned int byteorder:1; /* 0:LSB-First, 1:MSB-First */
22 unsigned int polarity:1; /* 0:High-Active */
23 unsigned int phase:1; /* 0:Sample-Then-Shift */
24};
25
26extern void txx9_spi_init(unsigned long base, int (*cs_func)(int chipid, int on)) __init;
27extern void txx9_spi_irqinit(int irc_irq) __init;
28extern int txx9_spi_io(int chipid, struct spi_dev_desc *desc,
29 unsigned char **inbufs, unsigned int *incounts,
30 unsigned char **outbufs, unsigned int *outcounts,
31 int cansleep);
32extern int spi_eeprom_write_enable(int chipid, int enable);
33extern int spi_eeprom_read_status(int chipid);
34extern int spi_eeprom_read(int chipid, int address, unsigned char *buf, int len); 18extern int spi_eeprom_read(int chipid, int address, unsigned char *buf, int len);
35extern int spi_eeprom_write(int chipid, int address, unsigned char *buf, int len);
36extern void spi_eeprom_proc_create(struct proc_dir_entry *dir, int chipid) __init;
37
38#define TXX9_IMCLK (txx9_gbus_clock / 2)
39
40/*
41* SPI
42*/
43
44/* SPMCR : SPI Master Control */
45#define TXx9_SPMCR_OPMODE 0xc0
46#define TXx9_SPMCR_CONFIG 0x40
47#define TXx9_SPMCR_ACTIVE 0x80
48#define TXx9_SPMCR_SPSTP 0x02
49#define TXx9_SPMCR_BCLR 0x01
50
51/* SPCR0 : SPI Status */
52#define TXx9_SPCR0_TXIFL_MASK 0xc000
53#define TXx9_SPCR0_RXIFL_MASK 0x3000
54#define TXx9_SPCR0_SIDIE 0x0800
55#define TXx9_SPCR0_SOEIE 0x0400
56#define TXx9_SPCR0_RBSIE 0x0200
57#define TXx9_SPCR0_TBSIE 0x0100
58#define TXx9_SPCR0_IFSPSE 0x0010
59#define TXx9_SPCR0_SBOS 0x0004
60#define TXx9_SPCR0_SPHA 0x0002
61#define TXx9_SPCR0_SPOL 0x0001
62
63/* SPSR : SPI Status */
64#define TXx9_SPSR_TBSI 0x8000
65#define TXx9_SPSR_RBSI 0x4000
66#define TXx9_SPSR_TBS_MASK 0x3800
67#define TXx9_SPSR_RBS_MASK 0x0700
68#define TXx9_SPSR_SPOE 0x0080
69#define TXx9_SPSR_IFSD 0x0008
70#define TXx9_SPSR_SIDLE 0x0004
71#define TXx9_SPSR_STRDY 0x0002
72#define TXx9_SPSR_SRRDY 0x0001
73 19
74#endif /* __ASM_TX_BOARDS_TX4938_SPI_H */ 20#endif /* __ASM_TX_BOARDS_TX4938_SPI_H */
diff --git a/include/asm-mips/war.h b/include/asm-mips/war.h
index ec0eeebd8802..9de52a5b0f3d 100644
--- a/include/asm-mips/war.h
+++ b/include/asm-mips/war.h
@@ -169,10 +169,9 @@
169 169
170/* 170/*
171 * On the RM9000 there is a problem which makes the CreateDirtyExclusive 171 * On the RM9000 there is a problem which makes the CreateDirtyExclusive
172 * cache operation unusable on SMP systems. 172 * eache operation unusable on SMP systems.
173 */ 173 */
174#if defined(CONFIG_MOMENCO_JAGUAR_ATX) || defined(CONFIG_PMC_YOSEMITE) || \ 174#if defined(CONFIG_PMC_YOSEMITE) || defined(CONFIG_BASLER_EXCITE)
175 defined(CONFIG_BASLER_EXCITE)
176#define RM9000_CDEX_SMP_WAR 1 175#define RM9000_CDEX_SMP_WAR 1
177#endif 176#endif
178 177
@@ -182,11 +181,10 @@
182 * I-cache line worth of instructions being fetched may case spurious 181 * I-cache line worth of instructions being fetched may case spurious
183 * exceptions. 182 * exceptions.
184 */ 183 */
185#if defined(CONFIG_BASLER_EXCITE) || defined(CONFIG_MOMENCO_JAGUAR_ATX) || \ 184#if defined(CONFIG_BASLER_EXCITE) || defined(CONFIG_MIPS_ATLAS) || \
186 defined(CONFIG_MIPS_ATLAS) || defined(CONFIG_MIPS_MALTA) || \ 185 defined(CONFIG_MIPS_MALTA) || defined(CONFIG_MOMENCO_OCELOT) || \
187 defined(CONFIG_MOMENCO_OCELOT) || defined(CONFIG_MOMENCO_OCELOT_3) || \ 186 defined(CONFIG_PMC_YOSEMITE) || defined(CONFIG_SGI_IP32) || \
188 defined(CONFIG_MOMENCO_OCELOT_C) || defined(CONFIG_PMC_YOSEMITE) || \ 187 defined(CONFIG_WR_PPMC)
189 defined(CONFIG_SGI_IP32) || defined(CONFIG_WR_PPMC)
190#define ICACHE_REFILLS_WORKAROUND_WAR 1 188#define ICACHE_REFILLS_WORKAROUND_WAR 1
191#endif 189#endif
192 190
@@ -200,6 +198,14 @@
200#endif 198#endif
201 199
202/* 200/*
201 * 34K core erratum: "Problems Executing the TLBR Instruction"
202 */
203#if defined(CONFIG_PMC_MSP7120_EVAL) || defined(CONFIG_PMC_MSP7120_GW) || \
204 defined(CONFIG_PMC_MSP7120_FPGA)
205#define MIPS34K_MISSED_ITLB_WAR 1
206#endif
207
208/*
203 * Workarounds default to off 209 * Workarounds default to off
204 */ 210 */
205#ifndef ICACHE_REFILLS_WORKAROUND_WAR 211#ifndef ICACHE_REFILLS_WORKAROUND_WAR
@@ -238,5 +244,8 @@
238#ifndef R10000_LLSC_WAR 244#ifndef R10000_LLSC_WAR
239#define R10000_LLSC_WAR 0 245#define R10000_LLSC_WAR 0
240#endif 246#endif
247#ifndef MIPS34K_MISSED_ITLB_WAR
248#define MIPS34K_MISSED_ITLB_WAR 0
249#endif
241 250
242#endif /* _ASM_WAR_H */ 251#endif /* _ASM_WAR_H */
diff --git a/include/asm-mips/watch.h b/include/asm-mips/watch.h
deleted file mode 100644
index 6aa90cae1114..000000000000
--- a/include/asm-mips/watch.h
+++ /dev/null
@@ -1,35 +0,0 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 1996, 1997, 1998, 2000, 2001 by Ralf Baechle
7 */
8#ifndef _ASM_WATCH_H
9#define _ASM_WATCH_H
10
11#include <linux/linkage.h>
12
13/*
14 * Types of reference for watch_set()
15 */
16enum wref_type {
17 wr_save = 1,
18 wr_load = 2
19};
20
21extern asmlinkage void __watch_set(unsigned long addr, enum wref_type ref);
22extern asmlinkage void __watch_clear(void);
23extern asmlinkage void __watch_reenable(void);
24
25#define watch_set(addr, ref) \
26 if (cpu_has_watch) \
27 __watch_set(addr, ref)
28#define watch_clear() \
29 if (cpu_has_watch) \
30 __watch_clear()
31#define watch_reenable() \
32 if (cpu_has_watch) \
33 __watch_reenable()
34
35#endif /* _ASM_WATCH_H */
diff --git a/include/asm-s390/atomic.h b/include/asm-s390/atomic.h
index c17bdbf22067..ea486952f778 100644
--- a/include/asm-s390/atomic.h
+++ b/include/asm-s390/atomic.h
@@ -24,7 +24,7 @@
24 */ 24 */
25 25
26typedef struct { 26typedef struct {
27 volatile int counter; 27 int counter;
28} __attribute__ ((aligned (4))) atomic_t; 28} __attribute__ ((aligned (4))) atomic_t;
29#define ATOMIC_INIT(i) { (i) } 29#define ATOMIC_INIT(i) { (i) }
30 30
@@ -141,7 +141,7 @@ static __inline__ int atomic_add_unless(atomic_t *v, int a, int u)
141 141
142#ifdef __s390x__ 142#ifdef __s390x__
143typedef struct { 143typedef struct {
144 volatile long long counter; 144 long long counter;
145} __attribute__ ((aligned (8))) atomic64_t; 145} __attribute__ ((aligned (8))) atomic64_t;
146#define ATOMIC64_INIT(i) { (i) } 146#define ATOMIC64_INIT(i) { (i) }
147 147
diff --git a/include/asm-s390/cmb.h b/include/asm-s390/cmb.h
index 241756f80df3..021e7c3223ec 100644
--- a/include/asm-s390/cmb.h
+++ b/include/asm-s390/cmb.h
@@ -88,7 +88,6 @@ extern u64 cmf_read(struct ccw_device *cdev, int index);
88 * any 88 * any
89 **/ 89 **/
90extern int cmf_readall(struct ccw_device *cdev, struct cmbdata*data); 90extern int cmf_readall(struct ccw_device *cdev, struct cmbdata*data);
91extern void cmf_reset(struct ccw_device *cdev);
92 91
93#endif /* __KERNEL__ */ 92#endif /* __KERNEL__ */
94#endif /* S390_CMB_H */ 93#endif /* S390_CMB_H */
diff --git a/include/asm-s390/processor.h b/include/asm-s390/processor.h
index 5cb480af65d5..3b972d4c6b29 100644
--- a/include/asm-s390/processor.h
+++ b/include/asm-s390/processor.h
@@ -357,8 +357,8 @@ extern void (*s390_base_ext_handler_fn)(void);
357/* 357/*
358 * CPU idle notifier chain. 358 * CPU idle notifier chain.
359 */ 359 */
360#define CPU_IDLE 0 360#define S390_CPU_IDLE 0
361#define CPU_NOT_IDLE 1 361#define S390_CPU_NOT_IDLE 1
362 362
363struct notifier_block; 363struct notifier_block;
364int register_idle_notifier(struct notifier_block *nb); 364int register_idle_notifier(struct notifier_block *nb);
diff --git a/include/asm-s390/sclp.h b/include/asm-s390/sclp.h
index 21ed64773210..cb9faf1ea5cf 100644
--- a/include/asm-s390/sclp.h
+++ b/include/asm-s390/sclp.h
@@ -11,29 +11,6 @@
11#include <linux/types.h> 11#include <linux/types.h>
12#include <asm/chpid.h> 12#include <asm/chpid.h>
13 13
14struct sccb_header {
15 u16 length;
16 u8 function_code;
17 u8 control_mask[3];
18 u16 response_code;
19} __attribute__((packed));
20
21#define LOADPARM_LEN 8
22
23struct sclp_readinfo_sccb {
24 struct sccb_header header; /* 0-7 */
25 u16 rnmax; /* 8-9 */
26 u8 rnsize; /* 10 */
27 u8 _reserved0[24 - 11]; /* 11-23 */
28 u8 loadparm[LOADPARM_LEN]; /* 24-31 */
29 u8 _reserved1[91 - 32]; /* 32-90 */
30 u8 flags; /* 91 */
31 u8 _reserved2[100 - 92]; /* 92-99 */
32 u32 rnsize2; /* 100-103 */
33 u64 rnmax2; /* 104-111 */
34 u8 _reserved3[4096 - 112]; /* 112-4095 */
35} __attribute__((packed, aligned(4096)));
36
37#define SCLP_CHP_INFO_MASK_SIZE 32 14#define SCLP_CHP_INFO_MASK_SIZE 32
38 15
39struct sclp_chp_info { 16struct sclp_chp_info {
@@ -42,12 +19,22 @@ struct sclp_chp_info {
42 u8 configured[SCLP_CHP_INFO_MASK_SIZE]; 19 u8 configured[SCLP_CHP_INFO_MASK_SIZE];
43}; 20};
44 21
45extern struct sclp_readinfo_sccb s390_readinfo_sccb; 22#define LOADPARM_LEN 8
46extern void sclp_readinfo_early(void); 23
47extern int sclp_sdias_blk_count(void); 24struct sclp_ipl_info {
48extern int sclp_sdias_copy(void *dest, int blk_num, int nr_blks); 25 int is_valid;
49extern int sclp_chp_configure(struct chp_id chpid); 26 int has_dump;
50extern int sclp_chp_deconfigure(struct chp_id chpid); 27 char loadparm[LOADPARM_LEN];
51extern int sclp_chp_read_info(struct sclp_chp_info *info); 28};
29
30void sclp_readinfo_early(void);
31void sclp_facilities_detect(void);
32unsigned long long sclp_memory_detect(void);
33int sclp_sdias_blk_count(void);
34int sclp_sdias_copy(void *dest, int blk_num, int nr_blks);
35int sclp_chp_configure(struct chp_id chpid);
36int sclp_chp_deconfigure(struct chp_id chpid);
37int sclp_chp_read_info(struct sclp_chp_info *info);
38void sclp_get_ipl_info(struct sclp_ipl_info *info);
52 39
53#endif /* _ASM_S390_SCLP_H */ 40#endif /* _ASM_S390_SCLP_H */
diff --git a/include/asm-s390/sfp-machine.h b/include/asm-s390/sfp-machine.h
index 8ca8c77b2d04..4e16aede4b06 100644
--- a/include/asm-s390/sfp-machine.h
+++ b/include/asm-s390/sfp-machine.h
@@ -27,9 +27,9 @@
27 27
28 28
29#define _FP_W_TYPE_SIZE 32 29#define _FP_W_TYPE_SIZE 32
30#define _FP_W_TYPE unsigned long 30#define _FP_W_TYPE unsigned int
31#define _FP_WS_TYPE signed long 31#define _FP_WS_TYPE signed int
32#define _FP_I_TYPE long 32#define _FP_I_TYPE int
33 33
34#define _FP_MUL_MEAT_S(R,X,Y) \ 34#define _FP_MUL_MEAT_S(R,X,Y) \
35 _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_S,R,X,Y,umul_ppmm) 35 _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_S,R,X,Y,umul_ppmm)
diff --git a/include/asm-s390/sfp-util.h b/include/asm-s390/sfp-util.h
index 8cabcd23d976..0addc6466d95 100644
--- a/include/asm-s390/sfp-util.h
+++ b/include/asm-s390/sfp-util.h
@@ -51,6 +51,16 @@
51 wl = __wl; \ 51 wl = __wl; \
52}) 52})
53 53
54#ifdef __s390x__
55#define udiv_qrnnd(q, r, n1, n0, d) \
56 do { unsigned long __n; \
57 unsigned int __r, __d; \
58 __n = ((unsigned long)(n1) << 32) + n0; \
59 __d = (d); \
60 (q) = __n / __d; \
61 (r) = __n % __d; \
62 } while (0)
63#else
54#define udiv_qrnnd(q, r, n1, n0, d) \ 64#define udiv_qrnnd(q, r, n1, n0, d) \
55 do { unsigned int __r; \ 65 do { unsigned int __r; \
56 (q) = __udiv_qrnnd (&__r, (n1), (n0), (d)); \ 66 (q) = __udiv_qrnnd (&__r, (n1), (n0), (d)); \
@@ -58,6 +68,7 @@
58 } while (0) 68 } while (0)
59extern unsigned long __udiv_qrnnd (unsigned int *, unsigned int, 69extern unsigned long __udiv_qrnnd (unsigned int *, unsigned int,
60 unsigned int , unsigned int); 70 unsigned int , unsigned int);
71#endif
61 72
62#define UDIV_NEEDS_NORMALIZATION 0 73#define UDIV_NEEDS_NORMALIZATION 0
63 74
diff --git a/include/linux/Kbuild b/include/linux/Kbuild
index f317c270d4bf..afae306b177c 100644
--- a/include/linux/Kbuild
+++ b/include/linux/Kbuild
@@ -49,6 +49,7 @@ header-y += consolemap.h
49header-y += const.h 49header-y += const.h
50header-y += cycx_cfm.h 50header-y += cycx_cfm.h
51header-y += dlm_device.h 51header-y += dlm_device.h
52header-y += dlm_netlink.h
52header-y += dm-ioctl.h 53header-y += dm-ioctl.h
53header-y += dn.h 54header-y += dn.h
54header-y += dqblk_v1.h 55header-y += dqblk_v1.h
diff --git a/include/linux/ata.h b/include/linux/ata.h
index 703febb2df31..407dc7e098bc 100644
--- a/include/linux/ata.h
+++ b/include/linux/ata.h
@@ -126,6 +126,7 @@ enum {
126 ATA_REG_IRQ = ATA_REG_NSECT, 126 ATA_REG_IRQ = ATA_REG_NSECT,
127 127
128 /* ATA device commands */ 128 /* ATA device commands */
129 ATA_CMD_DEV_RESET = 0x08, /* ATAPI device reset */
129 ATA_CMD_CHK_POWER = 0xE5, /* check power mode */ 130 ATA_CMD_CHK_POWER = 0xE5, /* check power mode */
130 ATA_CMD_STANDBY = 0xE2, /* place in standby power mode */ 131 ATA_CMD_STANDBY = 0xE2, /* place in standby power mode */
131 ATA_CMD_IDLE = 0xE3, /* place in idle power mode */ 132 ATA_CMD_IDLE = 0xE3, /* place in idle power mode */
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index db5b00a792f5..fae138bd2207 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -868,11 +868,6 @@ void kblockd_flush_work(struct work_struct *work);
868 */ 868 */
869#define buffer_heads_over_limit 0 869#define buffer_heads_over_limit 0
870 870
871static inline long blk_congestion_wait(int rw, long timeout)
872{
873 return io_schedule_timeout(timeout);
874}
875
876static inline long nr_blockdev_pages(void) 871static inline long nr_blockdev_pages(void)
877{ 872{
878 return 0; 873 return 0;
diff --git a/include/linux/dlm.h b/include/linux/dlm.h
index 1b1dcb9a40bb..be9d278761e0 100644
--- a/include/linux/dlm.h
+++ b/include/linux/dlm.h
@@ -2,7 +2,7 @@
2******************************************************************************* 2*******************************************************************************
3** 3**
4** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. 4** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
5** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. 5** Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
6** 6**
7** This copyrighted material is made available to anyone wishing to use, 7** This copyrighted material is made available to anyone wishing to use,
8** modify, copy, or redistribute it subject to the terms and conditions 8** modify, copy, or redistribute it subject to the terms and conditions
@@ -85,7 +85,11 @@
85 * Only relevant to locks originating in userspace. A persistent lock will not 85 * Only relevant to locks originating in userspace. A persistent lock will not
86 * be removed if the process holding the lock exits. 86 * be removed if the process holding the lock exits.
87 * 87 *
88 * DLM_LKF_NODLKWT 88 * DLM_LKF_NODLCKWT
89 *
90 * Do not cancel the lock if it gets into conversion deadlock.
91 * Exclude this lock from being monitored due to DLM_LSFL_TIMEWARN.
92 *
89 * DLM_LKF_NODLCKBLK 93 * DLM_LKF_NODLCKBLK
90 * 94 *
91 * net yet implemented 95 * net yet implemented
@@ -149,6 +153,7 @@
149#define DLM_LKF_ALTPR 0x00008000 153#define DLM_LKF_ALTPR 0x00008000
150#define DLM_LKF_ALTCW 0x00010000 154#define DLM_LKF_ALTCW 0x00010000
151#define DLM_LKF_FORCEUNLOCK 0x00020000 155#define DLM_LKF_FORCEUNLOCK 0x00020000
156#define DLM_LKF_TIMEOUT 0x00040000
152 157
153/* 158/*
154 * Some return codes that are not in errno.h 159 * Some return codes that are not in errno.h
@@ -199,11 +204,12 @@ struct dlm_lksb {
199 char * sb_lvbptr; 204 char * sb_lvbptr;
200}; 205};
201 206
207#define DLM_LSFL_NODIR 0x00000001
208#define DLM_LSFL_TIMEWARN 0x00000002
209#define DLM_LSFL_FS 0x00000004
202 210
203#ifdef __KERNEL__ 211#ifdef __KERNEL__
204 212
205#define DLM_LSFL_NODIR 0x00000001
206
207/* 213/*
208 * dlm_new_lockspace 214 * dlm_new_lockspace
209 * 215 *
diff --git a/include/linux/dlm_device.h b/include/linux/dlm_device.h
index c2735cab2ebf..9642277a152a 100644
--- a/include/linux/dlm_device.h
+++ b/include/linux/dlm_device.h
@@ -2,7 +2,7 @@
2******************************************************************************* 2*******************************************************************************
3** 3**
4** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. 4** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
5** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. 5** Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
6** 6**
7** This copyrighted material is made available to anyone wishing to use, 7** This copyrighted material is made available to anyone wishing to use,
8** modify, copy, or redistribute it subject to the terms and conditions 8** modify, copy, or redistribute it subject to the terms and conditions
@@ -18,21 +18,24 @@
18#define DLM_USER_LVB_LEN 32 18#define DLM_USER_LVB_LEN 32
19 19
20/* Version of the device interface */ 20/* Version of the device interface */
21#define DLM_DEVICE_VERSION_MAJOR 5 21#define DLM_DEVICE_VERSION_MAJOR 6
22#define DLM_DEVICE_VERSION_MINOR 1 22#define DLM_DEVICE_VERSION_MINOR 0
23#define DLM_DEVICE_VERSION_PATCH 0 23#define DLM_DEVICE_VERSION_PATCH 0
24 24
25/* struct passed to the lock write */ 25/* struct passed to the lock write */
26struct dlm_lock_params { 26struct dlm_lock_params {
27 __u8 mode; 27 __u8 mode;
28 __u8 namelen; 28 __u8 namelen;
29 __u16 flags; 29 __u16 unused;
30 __u32 flags;
30 __u32 lkid; 31 __u32 lkid;
31 __u32 parent; 32 __u32 parent;
32 void __user *castparam; 33 __u64 xid;
34 __u64 timeout;
35 void __user *castparam;
33 void __user *castaddr; 36 void __user *castaddr;
34 void __user *bastparam; 37 void __user *bastparam;
35 void __user *bastaddr; 38 void __user *bastaddr;
36 struct dlm_lksb __user *lksb; 39 struct dlm_lksb __user *lksb;
37 char lvb[DLM_USER_LVB_LEN]; 40 char lvb[DLM_USER_LVB_LEN];
38 char name[0]; 41 char name[0];
@@ -62,9 +65,15 @@ struct dlm_write_request {
62 } i; 65 } i;
63}; 66};
64 67
68struct dlm_device_version {
69 __u32 version[3];
70};
71
65/* struct read from the "device" fd, 72/* struct read from the "device" fd,
66 consists mainly of userspace pointers for the library to use */ 73 consists mainly of userspace pointers for the library to use */
74
67struct dlm_lock_result { 75struct dlm_lock_result {
76 __u32 version[3];
68 __u32 length; 77 __u32 length;
69 void __user * user_astaddr; 78 void __user * user_astaddr;
70 void __user * user_astparam; 79 void __user * user_astparam;
@@ -83,6 +92,7 @@ struct dlm_lock_result {
83#define DLM_USER_CREATE_LOCKSPACE 4 92#define DLM_USER_CREATE_LOCKSPACE 4
84#define DLM_USER_REMOVE_LOCKSPACE 5 93#define DLM_USER_REMOVE_LOCKSPACE 5
85#define DLM_USER_PURGE 6 94#define DLM_USER_PURGE 6
95#define DLM_USER_DEADLOCK 7
86 96
87/* Arbitrary length restriction */ 97/* Arbitrary length restriction */
88#define MAX_LS_NAME_LEN 64 98#define MAX_LS_NAME_LEN 64
diff --git a/include/linux/dlm_netlink.h b/include/linux/dlm_netlink.h
new file mode 100644
index 000000000000..19276332707a
--- /dev/null
+++ b/include/linux/dlm_netlink.h
@@ -0,0 +1,56 @@
1/*
2 * Copyright (C) 2007 Red Hat, Inc. All rights reserved.
3 *
4 * This copyrighted material is made available to anyone wishing to use,
5 * modify, copy, or redistribute it subject to the terms and conditions
6 * of the GNU General Public License v.2.
7 */
8
9#ifndef _DLM_NETLINK_H
10#define _DLM_NETLINK_H
11
12enum {
13 DLM_STATUS_WAITING = 1,
14 DLM_STATUS_GRANTED = 2,
15 DLM_STATUS_CONVERT = 3,
16};
17
18#define DLM_LOCK_DATA_VERSION 1
19
20struct dlm_lock_data {
21 uint16_t version;
22 uint32_t lockspace_id;
23 int nodeid;
24 int ownpid;
25 uint32_t id;
26 uint32_t remid;
27 uint64_t xid;
28 int8_t status;
29 int8_t grmode;
30 int8_t rqmode;
31 unsigned long timestamp;
32 int resource_namelen;
33 char resource_name[DLM_RESNAME_MAXLEN];
34};
35
36enum {
37 DLM_CMD_UNSPEC = 0,
38 DLM_CMD_HELLO, /* user->kernel */
39 DLM_CMD_TIMEOUT, /* kernel->user */
40 __DLM_CMD_MAX,
41};
42
43#define DLM_CMD_MAX (__DLM_CMD_MAX - 1)
44
45enum {
46 DLM_TYPE_UNSPEC = 0,
47 DLM_TYPE_LOCK,
48 __DLM_TYPE_MAX,
49};
50
51#define DLM_TYPE_MAX (__DLM_TYPE_MAX - 1)
52
53#define DLM_GENL_VERSION 0x1
54#define DLM_GENL_NAME "DLM"
55
56#endif /* _DLM_NETLINK_H */
diff --git a/include/linux/eeprom_93cx6.h b/include/linux/eeprom_93cx6.h
new file mode 100644
index 000000000000..d774b7778c91
--- /dev/null
+++ b/include/linux/eeprom_93cx6.h
@@ -0,0 +1,72 @@
1/*
2 Copyright (C) 2004 - 2006 rt2x00 SourceForge Project
3 <http://rt2x00.serialmonkey.com>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the
17 Free Software Foundation, Inc.,
18 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20
21/*
22 Module: eeprom_93cx6
23 Abstract: EEPROM reader datastructures for 93cx6 chipsets.
24 Supported chipsets: 93c46 & 93c66.
25 */
26
27/*
28 * EEPROM operation defines.
29 */
30#define PCI_EEPROM_WIDTH_93C46 6
31#define PCI_EEPROM_WIDTH_93C66 8
32#define PCI_EEPROM_WIDTH_OPCODE 3
33#define PCI_EEPROM_WRITE_OPCODE 0x05
34#define PCI_EEPROM_READ_OPCODE 0x06
35#define PCI_EEPROM_EWDS_OPCODE 0x10
36#define PCI_EEPROM_EWEN_OPCODE 0x13
37
38/**
39 * struct eeprom_93cx6 - control structure for setting the commands
40 * for reading the eeprom data.
41 * @data: private pointer for the driver.
42 * @register_read(struct eeprom_93cx6 *eeprom): handler to
43 * read the eeprom register, this function should set all reg_* fields.
44 * @register_write(struct eeprom_93cx6 *eeprom): handler to
45 * write to the eeprom register by using all reg_* fields.
46 * @width: eeprom width, should be one of the PCI_EEPROM_WIDTH_* defines
47 * @reg_data_in: register field to indicate data input
48 * @reg_data_out: register field to indicate data output
49 * @reg_data_clock: register field to set the data clock
50 * @reg_chip_select: register field to set the chip select
51 *
52 * This structure is used for the communication between the driver
53 * and the eeprom_93cx6 handlers for reading the eeprom.
54 */
55struct eeprom_93cx6 {
56 void *data;
57
58 void (*register_read)(struct eeprom_93cx6 *eeprom);
59 void (*register_write)(struct eeprom_93cx6 *eeprom);
60
61 int width;
62
63 char reg_data_in;
64 char reg_data_out;
65 char reg_data_clock;
66 char reg_chip_select;
67};
68
69extern void eeprom_93cx6_read(struct eeprom_93cx6 *eeprom,
70 const u8 word, u16 *data);
71extern void eeprom_93cx6_multiread(struct eeprom_93cx6 *eeprom,
72 const u8 word, __le16 *data, const u16 words);
diff --git a/include/linux/firewire-cdev.h b/include/linux/firewire-cdev.h
index efbe1fda1a22..1a45d6f41b09 100644
--- a/include/linux/firewire-cdev.h
+++ b/include/linux/firewire-cdev.h
@@ -30,16 +30,38 @@
30#define FW_CDEV_EVENT_REQUEST 0x02 30#define FW_CDEV_EVENT_REQUEST 0x02
31#define FW_CDEV_EVENT_ISO_INTERRUPT 0x03 31#define FW_CDEV_EVENT_ISO_INTERRUPT 0x03
32 32
33/* The 'closure' fields are for user space to use. Data passed in the 33/**
34 * 'closure' field for a request will be returned in the corresponding 34 * struct fw_cdev_event_common - Common part of all fw_cdev_event_ types
35 * event. It's a 64-bit type so that it's a fixed size type big 35 * @closure: For arbitrary use by userspace
36 * enough to hold a pointer on all platforms. */ 36 * @type: Discriminates the fw_cdev_event_ types
37 37 *
38 * This struct may be used to access generic members of all fw_cdev_event_
39 * types regardless of the specific type.
40 *
41 * Data passed in the @closure field for a request will be returned in the
42 * corresponding event. It is big enough to hold a pointer on all platforms.
43 * The ioctl used to set @closure depends on the @type of event.
44 */
38struct fw_cdev_event_common { 45struct fw_cdev_event_common {
39 __u64 closure; 46 __u64 closure;
40 __u32 type; 47 __u32 type;
41}; 48};
42 49
50/**
51 * struct fw_cdev_event_bus_reset - Sent when a bus reset occurred
52 * @closure: See &fw_cdev_event_common; set by %FW_CDEV_IOC_GET_INFO ioctl
53 * @type: See &fw_cdev_event_common; always %FW_CDEV_EVENT_BUS_RESET
54 * @node_id: New node ID of this node
55 * @local_node_id: Node ID of the local node, i.e. of the controller
56 * @bm_node_id: Node ID of the bus manager
57 * @irm_node_id: Node ID of the iso resource manager
58 * @root_node_id: Node ID of the root node
59 * @generation: New bus generation
60 *
61 * This event is sent when the bus the device belongs to goes through a bus
62 * reset. It provides information about the new bus configuration, such as
63 * new node ID for this device, new root ID, and others.
64 */
43struct fw_cdev_event_bus_reset { 65struct fw_cdev_event_bus_reset {
44 __u64 closure; 66 __u64 closure;
45 __u32 type; 67 __u32 type;
@@ -51,6 +73,20 @@ struct fw_cdev_event_bus_reset {
51 __u32 generation; 73 __u32 generation;
52}; 74};
53 75
76/**
77 * struct fw_cdev_event_response - Sent when a response packet was received
78 * @closure: See &fw_cdev_event_common;
79 * set by %FW_CDEV_IOC_SEND_REQUEST ioctl
80 * @type: See &fw_cdev_event_common; always %FW_CDEV_EVENT_RESPONSE
81 * @rcode: Response code returned by the remote node
82 * @length: Data length, i.e. the response's payload size in bytes
83 * @data: Payload data, if any
84 *
85 * This event is sent when the stack receives a response to an outgoing request
86 * sent by %FW_CDEV_IOC_SEND_REQUEST ioctl. The payload data for responses
87 * carrying data (read and lock responses) follows immediately and can be
88 * accessed through the @data field.
89 */
54struct fw_cdev_event_response { 90struct fw_cdev_event_response {
55 __u64 closure; 91 __u64 closure;
56 __u32 type; 92 __u32 type;
@@ -59,6 +95,25 @@ struct fw_cdev_event_response {
59 __u32 data[0]; 95 __u32 data[0];
60}; 96};
61 97
98/**
99 * struct fw_cdev_event_request - Sent on incoming request to an address region
100 * @closure: See &fw_cdev_event_common; set by %FW_CDEV_IOC_ALLOCATE ioctl
101 * @type: See &fw_cdev_event_common; always %FW_CDEV_EVENT_REQUEST
102 * @tcode: Transaction code of the incoming request
103 * @offset: The offset into the 48-bit per-node address space
104 * @handle: Reference to the kernel-side pending request
105 * @length: Data length, i.e. the request's payload size in bytes
106 * @data: Incoming data, if any
107 *
108 * This event is sent when the stack receives an incoming request to an address
109 * region registered using the %FW_CDEV_IOC_ALLOCATE ioctl. The request is
110 * guaranteed to be completely contained in the specified region. Userspace is
111 * responsible for sending the response by %FW_CDEV_IOC_SEND_RESPONSE ioctl,
112 * using the same @handle.
113 *
114 * The payload data for requests carrying data (write and lock requests)
115 * follows immediately and can be accessed through the @data field.
116 */
62struct fw_cdev_event_request { 117struct fw_cdev_event_request {
63 __u64 closure; 118 __u64 closure;
64 __u32 type; 119 __u32 type;
@@ -69,14 +124,39 @@ struct fw_cdev_event_request {
69 __u32 data[0]; 124 __u32 data[0];
70}; 125};
71 126
127/**
128 * struct fw_cdev_event_iso_interrupt - Sent when an iso packet was completed
129 * @closure: See &fw_cdev_event_common;
130 * set by %FW_CDEV_CREATE_ISO_CONTEXT ioctl
131 * @type: See &fw_cdev_event_common; always %FW_CDEV_EVENT_ISO_INTERRUPT
132 * @cycle: Cycle counter of the interrupt packet
133 * @header_length: Total length of following headers, in bytes
134 * @header: Stripped headers, if any
135 *
136 * This event is sent when the controller has completed an &fw_cdev_iso_packet
137 * with the %FW_CDEV_ISO_INTERRUPT bit set. In the receive case, the headers
138 * stripped of all packets up until and including the interrupt packet are
139 * returned in the @header field.
140 */
72struct fw_cdev_event_iso_interrupt { 141struct fw_cdev_event_iso_interrupt {
73 __u64 closure; 142 __u64 closure;
74 __u32 type; 143 __u32 type;
75 __u32 cycle; 144 __u32 cycle;
76 __u32 header_length; /* Length in bytes of following headers. */ 145 __u32 header_length;
77 __u32 header[0]; 146 __u32 header[0];
78}; 147};
79 148
149/**
150 * union fw_cdev_event - Convenience union of fw_cdev_event_ types
151 * @common: Valid for all types
152 * @bus_reset: Valid if @common.type == %FW_CDEV_EVENT_BUS_RESET
153 * @response: Valid if @common.type == %FW_CDEV_EVENT_RESPONSE
154 * @request: Valid if @common.type == %FW_CDEV_EVENT_REQUEST
155 * @iso_interrupt: Valid if @common.type == %FW_CDEV_EVENT_ISO_INTERRUPT
156 *
157 * Convenience union for userspace use. Events could be read(2) into a char
158 * buffer and then cast to this union for further processing.
159 */
80union fw_cdev_event { 160union fw_cdev_event {
81 struct fw_cdev_event_common common; 161 struct fw_cdev_event_common common;
82 struct fw_cdev_event_bus_reset bus_reset; 162 struct fw_cdev_event_bus_reset bus_reset;
@@ -105,35 +185,47 @@ union fw_cdev_event {
105 */ 185 */
106#define FW_CDEV_VERSION 1 186#define FW_CDEV_VERSION 1
107 187
188/**
189 * struct fw_cdev_get_info - General purpose information ioctl
190 * @version: The version field is just a running serial number.
191 * We never break backwards compatibility, but may add more
192 * structs and ioctls in later revisions.
193 * @rom_length: If @rom is non-zero, at most rom_length bytes of configuration
194 * ROM will be copied into that user space address. In either
195 * case, @rom_length is updated with the actual length of the
196 * configuration ROM.
197 * @rom: If non-zero, address of a buffer to be filled by a copy of the
198 * local node's configuration ROM
199 * @bus_reset: If non-zero, address of a buffer to be filled by a
200 * &struct fw_cdev_event_bus_reset with the current state
201 * of the bus. This does not cause a bus reset to happen.
202 * @bus_reset_closure: Value of &closure in this and subsequent bus reset events
203 * @card: The index of the card this device belongs to
204 */
108struct fw_cdev_get_info { 205struct fw_cdev_get_info {
109 /* The version field is just a running serial number. We
110 * never break backwards compatibility. Userspace passes in
111 * the version it expects and the kernel passes back the
112 * highest version it can provide. Even if the structs in
113 * this interface are extended in a later version, the kernel
114 * will not copy back more data than what was present in the
115 * interface version userspace expects. */
116 __u32 version; 206 __u32 version;
117
118 /* If non-zero, at most rom_length bytes of config rom will be
119 * copied into that user space address. In either case,
120 * rom_length is updated with the actual length of the config
121 * rom. */
122 __u32 rom_length; 207 __u32 rom_length;
123 __u64 rom; 208 __u64 rom;
124
125 /* If non-zero, a fw_cdev_event_bus_reset struct will be
126 * copied here with the current state of the bus. This does
127 * not cause a bus reset to happen. The value of closure in
128 * this and sub-sequent bus reset events is set to
129 * bus_reset_closure. */
130 __u64 bus_reset; 209 __u64 bus_reset;
131 __u64 bus_reset_closure; 210 __u64 bus_reset_closure;
132
133 /* The index of the card this devices belongs to. */
134 __u32 card; 211 __u32 card;
135}; 212};
136 213
214/**
215 * struct fw_cdev_send_request - Send an asynchronous request packet
216 * @tcode: Transaction code of the request
217 * @length: Length of outgoing payload, in bytes
218 * @offset: 48-bit offset at destination node
219 * @closure: Passed back to userspace in the response event
220 * @data: Userspace pointer to payload
221 * @generation: The bus generation where packet is valid
222 *
223 * Send a request to the device. This ioctl implements all outgoing requests.
224 * Both quadlet and block request specify the payload as a pointer to the data
225 * in the @data field. Once the transaction completes, the kernel writes an
226 * &fw_cdev_event_request event back. The @closure field is passed back to
227 * user space in the response event.
228 */
137struct fw_cdev_send_request { 229struct fw_cdev_send_request {
138 __u32 tcode; 230 __u32 tcode;
139 __u32 length; 231 __u32 length;
@@ -143,6 +235,19 @@ struct fw_cdev_send_request {
143 __u32 generation; 235 __u32 generation;
144}; 236};
145 237
238/**
239 * struct fw_cdev_send_response - Send an asynchronous response packet
240 * @rcode: Response code as determined by the userspace handler
241 * @length: Length of outgoing payload, in bytes
242 * @data: Userspace pointer to payload
243 * @handle: The handle from the &fw_cdev_event_request
244 *
245 * Send a response to an incoming request. By setting up an address range using
246 * the %FW_CDEV_IOC_ALLOCATE ioctl, userspace can listen for incoming requests. An
247 * incoming request will generate an %FW_CDEV_EVENT_REQUEST, and userspace must
248 * send a reply using this ioctl. The event has a handle to the kernel-side
249 * pending transaction, which should be used with this ioctl.
250 */
146struct fw_cdev_send_response { 251struct fw_cdev_send_response {
147 __u32 rcode; 252 __u32 rcode;
148 __u32 length; 253 __u32 length;
@@ -150,6 +255,21 @@ struct fw_cdev_send_response {
150 __u32 handle; 255 __u32 handle;
151}; 256};
152 257
258/**
259 * struct fw_cdev_allocate - Allocate a CSR address range
260 * @offset: Start offset of the address range
261 * @closure: To be passed back to userspace in request events
262 * @length: Length of the address range, in bytes
263 * @handle: Handle to the allocation, written by the kernel
264 *
265 * Allocate an address range in the 48-bit address space on the local node
266 * (the controller). This allows userspace to listen for requests with an
267 * offset within that address range. When the kernel receives a request
268 * within the range, an &fw_cdev_event_request event will be written back.
269 * The @closure field is passed back to userspace in the response event.
270 * The @handle field is an out parameter, returning a handle to the allocated
271 * range to be used for later deallocation of the range.
272 */
153struct fw_cdev_allocate { 273struct fw_cdev_allocate {
154 __u64 offset; 274 __u64 offset;
155 __u64 closure; 275 __u64 closure;
@@ -157,6 +277,11 @@ struct fw_cdev_allocate {
157 __u32 handle; 277 __u32 handle;
158}; 278};
159 279
280/**
281 * struct fw_cdev_deallocate - Free an address range allocation
282 * @handle: Handle to the address range, as returned by the kernel when the
283 * range was allocated
284 */
160struct fw_cdev_deallocate { 285struct fw_cdev_deallocate {
161 __u32 handle; 286 __u32 handle;
162}; 287};
@@ -164,10 +289,41 @@ struct fw_cdev_deallocate {
164#define FW_CDEV_LONG_RESET 0 289#define FW_CDEV_LONG_RESET 0
165#define FW_CDEV_SHORT_RESET 1 290#define FW_CDEV_SHORT_RESET 1
166 291
292/**
293 * struct fw_cdev_initiate_bus_reset - Initiate a bus reset
294 * @type: %FW_CDEV_SHORT_RESET or %FW_CDEV_LONG_RESET
295 *
296 * Initiate a bus reset for the bus this device is on. The bus reset can be
297 * either the original (long) bus reset or the arbitrated (short) bus reset
298 * introduced in 1394a-2000.
299 */
167struct fw_cdev_initiate_bus_reset { 300struct fw_cdev_initiate_bus_reset {
168 __u32 type; 301 __u32 type; /* FW_CDEV_SHORT_RESET or FW_CDEV_LONG_RESET */
169}; 302};
170 303
304/**
305 * struct fw_cdev_add_descriptor - Add contents to the local node's config ROM
306 * @immediate: If non-zero, immediate key to insert before pointer
307 * @key: Upper 8 bits of root directory pointer
308 * @data: Userspace pointer to contents of descriptor block
309 * @length: Length of descriptor block data, in bytes
310 * @handle: Handle to the descriptor, written by the kernel
311 *
312 * Add a descriptor block and optionally a preceding immediate key to the local
313 * node's configuration ROM.
314 *
315 * The @key field specifies the upper 8 bits of the descriptor root directory
316 * pointer and the @data and @length fields specify the contents. The @key
317 * should be of the form 0xXX000000. The offset part of the root directory entry
318 * will be filled in by the kernel.
319 *
320 * If not 0, the @immediate field specifies an immediate key which will be
321 * inserted before the root directory pointer.
322 *
323 * If successful, the kernel adds the descriptor and writes back a handle to the
324 * kernel-side object to be used for later removal of the descriptor block and
325 * immediate key.
326 */
171struct fw_cdev_add_descriptor { 327struct fw_cdev_add_descriptor {
172 __u32 immediate; 328 __u32 immediate;
173 __u32 key; 329 __u32 key;
@@ -176,6 +332,14 @@ struct fw_cdev_add_descriptor {
176 __u32 handle; 332 __u32 handle;
177}; 333};
178 334
335/**
336 * struct fw_cdev_remove_descriptor - Remove contents from the configuration ROM
337 * @handle: Handle to the descriptor, as returned by the kernel when the
338 * descriptor was added
339 *
340 * Remove a descriptor block and accompanying immediate key from the local
341 * node's configuration ROM.
342 */
179struct fw_cdev_remove_descriptor { 343struct fw_cdev_remove_descriptor {
180 __u32 handle; 344 __u32 handle;
181}; 345};
@@ -183,12 +347,24 @@ struct fw_cdev_remove_descriptor {
183#define FW_CDEV_ISO_CONTEXT_TRANSMIT 0 347#define FW_CDEV_ISO_CONTEXT_TRANSMIT 0
184#define FW_CDEV_ISO_CONTEXT_RECEIVE 1 348#define FW_CDEV_ISO_CONTEXT_RECEIVE 1
185 349
186#define FW_CDEV_ISO_CONTEXT_MATCH_TAG0 1 350/**
187#define FW_CDEV_ISO_CONTEXT_MATCH_TAG1 2 351 * struct fw_cdev_create_iso_context - Create a context for isochronous IO
188#define FW_CDEV_ISO_CONTEXT_MATCH_TAG2 4 352 * @type: %FW_CDEV_ISO_CONTEXT_TRANSMIT or %FW_CDEV_ISO_CONTEXT_RECEIVE
189#define FW_CDEV_ISO_CONTEXT_MATCH_TAG3 8 353 * @header_size: Header size to strip for receive contexts
190#define FW_CDEV_ISO_CONTEXT_MATCH_ALL_TAGS 15 354 * @channel: Channel to bind to
191 355 * @speed: Speed to transmit at
356 * @closure: To be returned in &fw_cdev_event_iso_interrupt
357 * @handle: Handle to context, written back by kernel
358 *
359 * Prior to sending or receiving isochronous I/O, a context must be created.
360 * The context records information about the transmit or receive configuration
361 * and typically maps to an underlying hardware resource. A context is set up
362 * for either sending or receiving. It is bound to a specific isochronous
363 * channel.
364 *
365 * If a context was successfully created, the kernel writes back a handle to the
366 * context, which must be passed in for subsequent operations on that context.
367 */
192struct fw_cdev_create_iso_context { 368struct fw_cdev_create_iso_context {
193 __u32 type; 369 __u32 type;
194 __u32 header_size; 370 __u32 header_size;
@@ -201,15 +377,49 @@ struct fw_cdev_create_iso_context {
201#define FW_CDEV_ISO_PAYLOAD_LENGTH(v) (v) 377#define FW_CDEV_ISO_PAYLOAD_LENGTH(v) (v)
202#define FW_CDEV_ISO_INTERRUPT (1 << 16) 378#define FW_CDEV_ISO_INTERRUPT (1 << 16)
203#define FW_CDEV_ISO_SKIP (1 << 17) 379#define FW_CDEV_ISO_SKIP (1 << 17)
380#define FW_CDEV_ISO_SYNC (1 << 17)
204#define FW_CDEV_ISO_TAG(v) ((v) << 18) 381#define FW_CDEV_ISO_TAG(v) ((v) << 18)
205#define FW_CDEV_ISO_SY(v) ((v) << 20) 382#define FW_CDEV_ISO_SY(v) ((v) << 20)
206#define FW_CDEV_ISO_HEADER_LENGTH(v) ((v) << 24) 383#define FW_CDEV_ISO_HEADER_LENGTH(v) ((v) << 24)
207 384
385/**
386 * struct fw_cdev_iso_packet - Isochronous packet
387 * @control: Contains the header length (8 uppermost bits), the sy field
388 * (4 bits), the tag field (2 bits), a sync flag (1 bit),
389 * a skip flag (1 bit), an interrupt flag (1 bit), and the
390 * payload length (16 lowermost bits)
391 * @header: Header and payload
392 *
393 * &struct fw_cdev_iso_packet is used to describe isochronous packet queues.
394 *
395 * Use the FW_CDEV_ISO_ macros to fill in @control. The sy and tag fields are
396 * specified by IEEE 1394a and IEC 61883.
397 *
398 * FIXME - finish this documentation
399 */
208struct fw_cdev_iso_packet { 400struct fw_cdev_iso_packet {
209 __u32 control; 401 __u32 control;
210 __u32 header[0]; 402 __u32 header[0];
211}; 403};
212 404
405/**
406 * struct fw_cdev_queue_iso - Queue isochronous packets for I/O
407 * @packets: Userspace pointer to packet data
408 * @data: Pointer into mmap()'ed payload buffer
409 * @size: Size of packet data in bytes
410 * @handle: Isochronous context handle
411 *
412 * Queue a number of isochronous packets for reception or transmission.
413 * This ioctl takes a pointer to an array of &fw_cdev_iso_packet structs,
414 * which describe how to transmit from or receive into a contiguous region
415 * of a mmap()'ed payload buffer. As part of the packet descriptors,
416 * a series of headers can be supplied, which will be prepended to the
417 * payload during DMA.
418 *
419 * The kernel may or may not queue all packets, but will write back updated
420 * values of the @packets, @data and @size fields, so the ioctl can be
421 * resubmitted easily.
422 */
213struct fw_cdev_queue_iso { 423struct fw_cdev_queue_iso {
214 __u64 packets; 424 __u64 packets;
215 __u64 data; 425 __u64 data;
@@ -217,6 +427,23 @@ struct fw_cdev_queue_iso {
217 __u32 handle; 427 __u32 handle;
218}; 428};
219 429
430#define FW_CDEV_ISO_CONTEXT_MATCH_TAG0 1
431#define FW_CDEV_ISO_CONTEXT_MATCH_TAG1 2
432#define FW_CDEV_ISO_CONTEXT_MATCH_TAG2 4
433#define FW_CDEV_ISO_CONTEXT_MATCH_TAG3 8
434#define FW_CDEV_ISO_CONTEXT_MATCH_ALL_TAGS 15
435
436/**
437 * struct fw_cdev_start_iso - Start an isochronous transmission or reception
438 * @cycle: Cycle in which to start I/O. If @cycle is greater than or
439 * equal to 0, the I/O will start on that cycle.
440 * @sync: Determines the value to wait for for receive packets that have
441 * the %FW_CDEV_ISO_SYNC bit set
442 * @tags: Tag filter bit mask. Only valid for isochronous reception.
443 * Determines the tag values for which packets will be accepted.
444 * Use FW_CDEV_ISO_CONTEXT_MATCH_ macros to set @tags.
445 * @handle: Isochronous context handle within which to transmit or receive
446 */
220struct fw_cdev_start_iso { 447struct fw_cdev_start_iso {
221 __s32 cycle; 448 __s32 cycle;
222 __u32 sync; 449 __u32 sync;
@@ -224,6 +451,10 @@ struct fw_cdev_start_iso {
224 __u32 handle; 451 __u32 handle;
225}; 452};
226 453
454/**
455 * struct fw_cdev_stop_iso - Stop an isochronous transmission or reception
456 * @handle: Handle of isochronous context to stop
457 */
227struct fw_cdev_stop_iso { 458struct fw_cdev_stop_iso {
228 __u32 handle; 459 __u32 handle;
229}; 460};
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 6a41f4cab14c..4f0b3bf5983c 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1054,7 +1054,7 @@ struct block_device_operations {
1054}; 1054};
1055 1055
1056/* 1056/*
1057 * "descriptor" for what we're up to with a read for sendfile(). 1057 * "descriptor" for what we're up to with a read.
1058 * This allows us to use the same read code yet 1058 * This allows us to use the same read code yet
1059 * have multiple different users of the data that 1059 * have multiple different users of the data that
1060 * we read from a file. 1060 * we read from a file.
@@ -1105,7 +1105,6 @@ struct file_operations {
1105 int (*aio_fsync) (struct kiocb *, int datasync); 1105 int (*aio_fsync) (struct kiocb *, int datasync);
1106 int (*fasync) (int, struct file *, int); 1106 int (*fasync) (int, struct file *, int);
1107 int (*lock) (struct file *, int, struct file_lock *); 1107 int (*lock) (struct file *, int, struct file_lock *);
1108 ssize_t (*sendfile) (struct file *, loff_t *, size_t, read_actor_t, void *);
1109 ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int); 1108 ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);
1110 unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long); 1109 unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
1111 int (*check_flags)(int); 1110 int (*check_flags)(int);
@@ -1762,7 +1761,6 @@ extern ssize_t generic_file_buffered_write(struct kiocb *, const struct iovec *,
1762 unsigned long, loff_t, loff_t *, size_t, ssize_t); 1761 unsigned long, loff_t, loff_t *, size_t, ssize_t);
1763extern ssize_t do_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos); 1762extern ssize_t do_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos);
1764extern ssize_t do_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos); 1763extern ssize_t do_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos);
1765extern ssize_t generic_file_sendfile(struct file *, loff_t *, size_t, read_actor_t, void *);
1766extern void do_generic_mapping_read(struct address_space *mapping, 1764extern void do_generic_mapping_read(struct address_space *mapping,
1767 struct file_ra_state *, struct file *, 1765 struct file_ra_state *, struct file *,
1768 loff_t *, read_descriptor_t *, read_actor_t); 1766 loff_t *, read_descriptor_t *, read_actor_t);
@@ -1792,9 +1790,6 @@ extern int nonseekable_open(struct inode * inode, struct file * filp);
1792#ifdef CONFIG_FS_XIP 1790#ifdef CONFIG_FS_XIP
1793extern ssize_t xip_file_read(struct file *filp, char __user *buf, size_t len, 1791extern ssize_t xip_file_read(struct file *filp, char __user *buf, size_t len,
1794 loff_t *ppos); 1792 loff_t *ppos);
1795extern ssize_t xip_file_sendfile(struct file *in_file, loff_t *ppos,
1796 size_t count, read_actor_t actor,
1797 void *target);
1798extern int xip_file_mmap(struct file * file, struct vm_area_struct * vma); 1793extern int xip_file_mmap(struct file * file, struct vm_area_struct * vma);
1799extern ssize_t xip_file_write(struct file *filp, const char __user *buf, 1794extern ssize_t xip_file_write(struct file *filp, const char __user *buf,
1800 size_t len, loff_t *ppos); 1795 size_t len, loff_t *ppos);
diff --git a/include/linux/gfs2_ondisk.h b/include/linux/gfs2_ondisk.h
index 8b7e4c1e32ae..a44a6a078f0a 100644
--- a/include/linux/gfs2_ondisk.h
+++ b/include/linux/gfs2_ondisk.h
@@ -54,18 +54,6 @@ struct gfs2_inum {
54 __be64 no_addr; 54 __be64 no_addr;
55}; 55};
56 56
57struct gfs2_inum_host {
58 __u64 no_formal_ino;
59 __u64 no_addr;
60};
61
62static inline int gfs2_inum_equal(const struct gfs2_inum_host *ino1,
63 const struct gfs2_inum_host *ino2)
64{
65 return ino1->no_formal_ino == ino2->no_formal_ino &&
66 ino1->no_addr == ino2->no_addr;
67}
68
69/* 57/*
70 * Generic metadata head structure 58 * Generic metadata head structure
71 * Every inplace buffer logged in the journal must start with this. 59 * Every inplace buffer logged in the journal must start with this.
@@ -94,12 +82,6 @@ struct gfs2_meta_header {
94 __be32 __pad1; /* Was incarnation number in gfs1 */ 82 __be32 __pad1; /* Was incarnation number in gfs1 */
95}; 83};
96 84
97struct gfs2_meta_header_host {
98 __u32 mh_magic;
99 __u32 mh_type;
100 __u32 mh_format;
101};
102
103/* 85/*
104 * super-block structure 86 * super-block structure
105 * 87 *
@@ -139,23 +121,6 @@ struct gfs2_sb {
139 /* In gfs1, quota and license dinodes followed */ 121 /* In gfs1, quota and license dinodes followed */
140}; 122};
141 123
142struct gfs2_sb_host {
143 struct gfs2_meta_header_host sb_header;
144
145 __u32 sb_fs_format;
146 __u32 sb_multihost_format;
147
148 __u32 sb_bsize;
149 __u32 sb_bsize_shift;
150
151 struct gfs2_inum_host sb_master_dir; /* Was jindex dinode in gfs1 */
152 struct gfs2_inum_host sb_root_dir;
153
154 char sb_lockproto[GFS2_LOCKNAME_LEN];
155 char sb_locktable[GFS2_LOCKNAME_LEN];
156 /* In gfs1, quota and license dinodes followed */
157};
158
159/* 124/*
160 * resource index structure 125 * resource index structure
161 */ 126 */
@@ -173,14 +138,6 @@ struct gfs2_rindex {
173 __u8 ri_reserved[64]; 138 __u8 ri_reserved[64];
174}; 139};
175 140
176struct gfs2_rindex_host {
177 __u64 ri_addr; /* grp block disk address */
178 __u64 ri_data0; /* first data location */
179 __u32 ri_length; /* length of rgrp header in fs blocks */
180 __u32 ri_data; /* num of data blocks in rgrp */
181 __u32 ri_bitbytes; /* number of bytes in data bitmaps */
182};
183
184/* 141/*
185 * resource group header structure 142 * resource group header structure
186 */ 143 */
@@ -212,13 +169,6 @@ struct gfs2_rgrp {
212 __u8 rg_reserved[80]; /* Several fields from gfs1 now reserved */ 169 __u8 rg_reserved[80]; /* Several fields from gfs1 now reserved */
213}; 170};
214 171
215struct gfs2_rgrp_host {
216 __u32 rg_flags;
217 __u32 rg_free;
218 __u32 rg_dinodes;
219 __u64 rg_igeneration;
220};
221
222/* 172/*
223 * quota structure 173 * quota structure
224 */ 174 */
@@ -230,12 +180,6 @@ struct gfs2_quota {
230 __u8 qu_reserved[64]; 180 __u8 qu_reserved[64];
231}; 181};
232 182
233struct gfs2_quota_host {
234 __u64 qu_limit;
235 __u64 qu_warn;
236 __u64 qu_value;
237};
238
239/* 183/*
240 * dinode structure 184 * dinode structure
241 */ 185 */
@@ -315,29 +259,11 @@ struct gfs2_dinode {
315 struct gfs2_inum __pad4; /* Unused even in current gfs1 */ 259 struct gfs2_inum __pad4; /* Unused even in current gfs1 */
316 260
317 __be64 di_eattr; /* extended attribute block number */ 261 __be64 di_eattr; /* extended attribute block number */
262 __be32 di_atime_nsec; /* nsec portion of atime */
263 __be32 di_mtime_nsec; /* nsec portion of mtime */
264 __be32 di_ctime_nsec; /* nsec portion of ctime */
318 265
319 __u8 di_reserved[56]; 266 __u8 di_reserved[44];
320};
321
322struct gfs2_dinode_host {
323 __u64 di_size; /* number of bytes in file */
324 __u64 di_blocks; /* number of blocks in file */
325
326 /* This section varies from gfs1. Padding added to align with
327 * remainder of dinode
328 */
329 __u64 di_goal_meta; /* rgrp to alloc from next */
330 __u64 di_goal_data; /* data block goal */
331 __u64 di_generation; /* generation number for NFS */
332
333 __u32 di_flags; /* GFS2_DIF_... */
334 __u16 di_height; /* height of metadata */
335
336 /* These only apply to directories */
337 __u16 di_depth; /* Number of bits in the table */
338 __u32 di_entries; /* The number of entries in the directory */
339
340 __u64 di_eattr; /* extended attribute block number */
341}; 267};
342 268
343/* 269/*
@@ -414,16 +340,6 @@ struct gfs2_log_header {
414 __be32 lh_hash; 340 __be32 lh_hash;
415}; 341};
416 342
417struct gfs2_log_header_host {
418 struct gfs2_meta_header_host lh_header;
419
420 __u64 lh_sequence; /* Sequence number of this transaction */
421 __u32 lh_flags; /* GFS2_LOG_HEAD_... */
422 __u32 lh_tail; /* Block number of log tail */
423 __u32 lh_blkno;
424 __u32 lh_hash;
425};
426
427/* 343/*
428 * Log type descriptor 344 * Log type descriptor
429 */ 345 */
@@ -464,11 +380,6 @@ struct gfs2_inum_range {
464 __be64 ir_length; 380 __be64 ir_length;
465}; 381};
466 382
467struct gfs2_inum_range_host {
468 __u64 ir_start;
469 __u64 ir_length;
470};
471
472/* 383/*
473 * Statfs change 384 * Statfs change
474 * Describes an change to the pool of free and allocated 385 * Describes an change to the pool of free and allocated
@@ -481,12 +392,6 @@ struct gfs2_statfs_change {
481 __be64 sc_dinodes; 392 __be64 sc_dinodes;
482}; 393};
483 394
484struct gfs2_statfs_change_host {
485 __u64 sc_total;
486 __u64 sc_free;
487 __u64 sc_dinodes;
488};
489
490/* 395/*
491 * Quota change 396 * Quota change
492 * Describes an allocation change for a particular 397 * Describes an allocation change for a particular
@@ -501,39 +406,12 @@ struct gfs2_quota_change {
501 __be32 qc_id; 406 __be32 qc_id;
502}; 407};
503 408
504struct gfs2_quota_change_host { 409struct gfs2_quota_lvb {
505 __u64 qc_change; 410 __be32 qb_magic;
506 __u32 qc_flags; /* GFS2_QCF_... */ 411 __u32 __pad;
507 __u32 qc_id; 412 __be64 qb_limit; /* Hard limit of # blocks to alloc */
413 __be64 qb_warn; /* Warn user when alloc is above this # */
414 __be64 qb_value; /* Current # blocks allocated */
508}; 415};
509 416
510#ifdef __KERNEL__
511/* Translation functions */
512
513extern void gfs2_inum_in(struct gfs2_inum_host *no, const void *buf);
514extern void gfs2_inum_out(const struct gfs2_inum_host *no, void *buf);
515extern void gfs2_sb_in(struct gfs2_sb_host *sb, const void *buf);
516extern void gfs2_rindex_in(struct gfs2_rindex_host *ri, const void *buf);
517extern void gfs2_rindex_out(const struct gfs2_rindex_host *ri, void *buf);
518extern void gfs2_rgrp_in(struct gfs2_rgrp_host *rg, const void *buf);
519extern void gfs2_rgrp_out(const struct gfs2_rgrp_host *rg, void *buf);
520extern void gfs2_quota_in(struct gfs2_quota_host *qu, const void *buf);
521struct gfs2_inode;
522extern void gfs2_dinode_out(const struct gfs2_inode *ip, void *buf);
523extern void gfs2_ea_header_in(struct gfs2_ea_header *ea, const void *buf);
524extern void gfs2_ea_header_out(const struct gfs2_ea_header *ea, void *buf);
525extern void gfs2_log_header_in(struct gfs2_log_header_host *lh, const void *buf);
526extern void gfs2_inum_range_in(struct gfs2_inum_range_host *ir, const void *buf);
527extern void gfs2_inum_range_out(const struct gfs2_inum_range_host *ir, void *buf);
528extern void gfs2_statfs_change_in(struct gfs2_statfs_change_host *sc, const void *buf);
529extern void gfs2_statfs_change_out(const struct gfs2_statfs_change_host *sc, void *buf);
530extern void gfs2_quota_change_in(struct gfs2_quota_change_host *qc, const void *buf);
531
532/* Printing functions */
533
534extern void gfs2_rindex_print(const struct gfs2_rindex_host *ri);
535extern void gfs2_dinode_print(const struct gfs2_inode *ip);
536
537#endif /* __KERNEL__ */
538
539#endif /* __GFS2_ONDISK_DOT_H__ */ 417#endif /* __GFS2_ONDISK_DOT_H__ */
diff --git a/include/linux/gpio_mouse.h b/include/linux/gpio_mouse.h
new file mode 100644
index 000000000000..44ed7aa14d85
--- /dev/null
+++ b/include/linux/gpio_mouse.h
@@ -0,0 +1,61 @@
1/*
2 * Driver for simulating a mouse on GPIO lines.
3 *
4 * Copyright (C) 2007 Atmel Corporation
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#ifndef _GPIO_MOUSE_H
12#define _GPIO_MOUSE_H
13
14#define GPIO_MOUSE_POLARITY_ACT_HIGH 0x00
15#define GPIO_MOUSE_POLARITY_ACT_LOW 0x01
16
17#define GPIO_MOUSE_PIN_UP 0
18#define GPIO_MOUSE_PIN_DOWN 1
19#define GPIO_MOUSE_PIN_LEFT 2
20#define GPIO_MOUSE_PIN_RIGHT 3
21#define GPIO_MOUSE_PIN_BLEFT 4
22#define GPIO_MOUSE_PIN_BMIDDLE 5
23#define GPIO_MOUSE_PIN_BRIGHT 6
24#define GPIO_MOUSE_PIN_MAX 7
25
26/**
27 * struct gpio_mouse_platform_data
28 * @scan_ms: integer in ms specifying the scan periode.
29 * @polarity: Pin polarity, active high or low.
30 * @up: GPIO line for up value.
31 * @down: GPIO line for down value.
32 * @left: GPIO line for left value.
33 * @right: GPIO line for right value.
34 * @bleft: GPIO line for left button.
35 * @bmiddle: GPIO line for middle button.
36 * @bright: GPIO line for right button.
37 *
38 * This struct must be added to the platform_device in the board code.
39 * It is used by the gpio_mouse driver to setup GPIO lines and to
40 * calculate mouse movement.
41 */
42struct gpio_mouse_platform_data {
43 int scan_ms;
44 int polarity;
45
46 union {
47 struct {
48 int up;
49 int down;
50 int left;
51 int right;
52
53 int bleft;
54 int bmiddle;
55 int bright;
56 };
57 int pins[GPIO_MOUSE_PIN_MAX];
58 };
59};
60
61#endif /* _GPIO_MOUSE_H */
diff --git a/include/linux/hardirq.h b/include/linux/hardirq.h
index 7803014f3a11..8d302298a161 100644
--- a/include/linux/hardirq.h
+++ b/include/linux/hardirq.h
@@ -79,6 +79,19 @@
79#endif 79#endif
80 80
81#ifdef CONFIG_PREEMPT 81#ifdef CONFIG_PREEMPT
82# define PREEMPT_CHECK_OFFSET 1
83#else
84# define PREEMPT_CHECK_OFFSET 0
85#endif
86
87/*
88 * Check whether we were atomic before we did preempt_disable():
89 * (used by the scheduler)
90 */
91#define in_atomic_preempt_off() \
92 ((preempt_count() & ~PREEMPT_ACTIVE) != PREEMPT_CHECK_OFFSET)
93
94#ifdef CONFIG_PREEMPT
82# define preemptible() (preempt_count() == 0 && !irqs_disabled()) 95# define preemptible() (preempt_count() == 0 && !irqs_disabled())
83# define IRQ_EXIT_OFFSET (HARDIRQ_OFFSET-1) 96# define IRQ_EXIT_OFFSET (HARDIRQ_OFFSET-1)
84#else 97#else
diff --git a/include/linux/hid.h b/include/linux/hid.h
index 827ee748fd4c..898103b401f1 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -263,19 +263,28 @@ struct hid_item {
263#define HID_QUIRK_2WHEEL_MOUSE_HACK_5 0x00000100 263#define HID_QUIRK_2WHEEL_MOUSE_HACK_5 0x00000100
264#define HID_QUIRK_2WHEEL_MOUSE_HACK_ON 0x00000200 264#define HID_QUIRK_2WHEEL_MOUSE_HACK_ON 0x00000200
265#define HID_QUIRK_MIGHTYMOUSE 0x00000400 265#define HID_QUIRK_MIGHTYMOUSE 0x00000400
266#define HID_QUIRK_CYMOTION 0x00000800 266#define HID_QUIRK_POWERBOOK_HAS_FN 0x00000800
267#define HID_QUIRK_POWERBOOK_HAS_FN 0x00001000 267#define HID_QUIRK_POWERBOOK_FN_ON 0x00001000
268#define HID_QUIRK_POWERBOOK_FN_ON 0x00002000 268#define HID_QUIRK_INVERT_HWHEEL 0x00002000
269#define HID_QUIRK_INVERT_HWHEEL 0x00004000 269#define HID_QUIRK_POWERBOOK_ISO_KEYBOARD 0x00004000
270#define HID_QUIRK_POWERBOOK_ISO_KEYBOARD 0x00008000 270#define HID_QUIRK_BAD_RELATIVE_KEYS 0x00008000
271#define HID_QUIRK_BAD_RELATIVE_KEYS 0x00010000 271#define HID_QUIRK_SKIP_OUTPUT_REPORTS 0x00010000
272#define HID_QUIRK_SKIP_OUTPUT_REPORTS 0x00020000 272#define HID_QUIRK_IGNORE_MOUSE 0x00020000
273#define HID_QUIRK_IGNORE_MOUSE 0x00040000 273#define HID_QUIRK_SONY_PS3_CONTROLLER 0x00040000
274#define HID_QUIRK_SONY_PS3_CONTROLLER 0x00080000 274#define HID_QUIRK_DUPLICATE_USAGES 0x00080000
275#define HID_QUIRK_LOGITECH_DESCRIPTOR 0x00100000 275#define HID_QUIRK_RESET_LEDS 0x00100000
276#define HID_QUIRK_DUPLICATE_USAGES 0x00200000 276#define HID_QUIRK_HIDINPUT 0x00200000
277#define HID_QUIRK_RESET_LEDS 0x00400000 277#define HID_QUIRK_LOGITECH_IGNORE_DOUBLED_WHEEL 0x00400000
278#define HID_QUIRK_SWAPPED_MIN_MAX 0x00800000 278#define HID_QUIRK_LOGITECH_EXPANDED_KEYMAP 0x00800000
279
280/*
281 * Separate quirks for runtime report descriptor fixup
282 */
283
284#define HID_QUIRK_RDESC_CYMOTION 0x00000001
285#define HID_QUIRK_RDESC_LOGITECH 0x00000002
286#define HID_QUIRK_RDESC_SWAPPED_MIN_MAX 0x00000004
287#define HID_QUIRK_RDESC_PETALYNX 0x00000008
279 288
280/* 289/*
281 * This is the global environment of the parser. This information is 290 * This is the global environment of the parser. This information is
@@ -488,6 +497,11 @@ struct hid_descriptor {
488#define IS_INPUT_APPLICATION(a) (((a >= 0x00010000) && (a <= 0x00010008)) || (a == 0x00010080) || (a == 0x000c0001)) 497#define IS_INPUT_APPLICATION(a) (((a >= 0x00010000) && (a <= 0x00010008)) || (a == 0x00010080) || (a == 0x000c0001))
489 498
490/* HID core API */ 499/* HID core API */
500
501#ifdef CONFIG_HID_DEBUG
502extern int hid_debug;
503#endif
504
491extern void hidinput_hid_event(struct hid_device *, struct hid_field *, struct hid_usage *, __s32); 505extern void hidinput_hid_event(struct hid_device *, struct hid_field *, struct hid_usage *, __s32);
492extern void hidinput_report_event(struct hid_device *hid, struct hid_report *report); 506extern void hidinput_report_event(struct hid_device *hid, struct hid_report *report);
493extern int hidinput_connect(struct hid_device *); 507extern int hidinput_connect(struct hid_device *);
@@ -506,6 +520,7 @@ u32 usbhid_lookup_quirk(const u16 idVendor, const u16 idProduct);
506int usbhid_modify_dquirk(const u16 idVendor, const u16 idProduct, const u32 quirks); 520int usbhid_modify_dquirk(const u16 idVendor, const u16 idProduct, const u32 quirks);
507int usbhid_quirks_init(char **quirks_param); 521int usbhid_quirks_init(char **quirks_param);
508void usbhid_quirks_exit(void); 522void usbhid_quirks_exit(void);
523void usbhid_fixup_report_descriptor(const u16, const u16, char *, unsigned, char **);
509 524
510#ifdef CONFIG_HID_FF 525#ifdef CONFIG_HID_FF
511int hid_ff_init(struct hid_device *hid); 526int hid_ff_init(struct hid_device *hid);
@@ -523,14 +538,19 @@ static inline int hid_pidff_init(struct hid_device *hid) { return -ENODEV; }
523#else 538#else
524static inline int hid_ff_init(struct hid_device *hid) { return -1; } 539static inline int hid_ff_init(struct hid_device *hid) { return -1; }
525#endif 540#endif
526#ifdef DEBUG 541
527#define dbg(format, arg...) printk(KERN_DEBUG "%s: " format "\n" , \ 542#ifdef CONFIG_HID_DEBUG
528 __FILE__ , ## arg) 543#define dbg_hid(format, arg...) if (hid_debug) \
544 printk(KERN_DEBUG "%s: " format ,\
545 __FILE__ , ## arg)
546#define dbg_hid_line(format, arg...) if (hid_debug) \
547 printk(format, ## arg)
529#else 548#else
530#define dbg(format, arg...) do {} while (0) 549#define dbg_hid(format, arg...) do {} while (0)
550#define dbg_hid_line dbg_hid
531#endif 551#endif
532 552
533#define err(format, arg...) printk(KERN_ERR "%s: " format "\n" , \ 553#define err_hid(format, arg...) printk(KERN_ERR "%s: " format "\n" , \
534 __FILE__ , ## arg) 554 __FILE__ , ## arg)
535#endif 555#endif
536 556
diff --git a/include/linux/ide.h b/include/linux/ide.h
index 1e365acdd369..19ab25804056 100644
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -25,6 +25,7 @@
25#include <asm/system.h> 25#include <asm/system.h>
26#include <asm/io.h> 26#include <asm/io.h>
27#include <asm/semaphore.h> 27#include <asm/semaphore.h>
28#include <asm/mutex.h>
28 29
29/****************************************************************************** 30/******************************************************************************
30 * IDE driver configuration options (play with these as desired): 31 * IDE driver configuration options (play with these as desired):
@@ -685,6 +686,8 @@ typedef struct hwif_s {
685 u8 mwdma_mask; 686 u8 mwdma_mask;
686 u8 swdma_mask; 687 u8 swdma_mask;
687 688
689 u8 cbl; /* cable type */
690
688 hwif_chipset_t chipset; /* sub-module for tuning.. */ 691 hwif_chipset_t chipset; /* sub-module for tuning.. */
689 692
690 struct pci_dev *pci_dev; /* for pci chipsets */ 693 struct pci_dev *pci_dev; /* for pci chipsets */
@@ -735,8 +738,8 @@ typedef struct hwif_s {
735 void (*ide_dma_clear_irq)(ide_drive_t *drive); 738 void (*ide_dma_clear_irq)(ide_drive_t *drive);
736 void (*dma_host_on)(ide_drive_t *drive); 739 void (*dma_host_on)(ide_drive_t *drive);
737 void (*dma_host_off)(ide_drive_t *drive); 740 void (*dma_host_off)(ide_drive_t *drive);
738 int (*ide_dma_lostirq)(ide_drive_t *drive); 741 void (*dma_lost_irq)(ide_drive_t *drive);
739 int (*ide_dma_timeout)(ide_drive_t *drive); 742 void (*dma_timeout)(ide_drive_t *drive);
740 743
741 void (*OUTB)(u8 addr, unsigned long port); 744 void (*OUTB)(u8 addr, unsigned long port);
742 void (*OUTBSYNC)(ide_drive_t *drive, u8 addr, unsigned long port); 745 void (*OUTBSYNC)(ide_drive_t *drive, u8 addr, unsigned long port);
@@ -791,7 +794,6 @@ typedef struct hwif_s {
791 unsigned sharing_irq: 1; /* 1 = sharing irq with another hwif */ 794 unsigned sharing_irq: 1; /* 1 = sharing irq with another hwif */
792 unsigned reset : 1; /* reset after probe */ 795 unsigned reset : 1; /* reset after probe */
793 unsigned autodma : 1; /* auto-attempt using DMA at boot */ 796 unsigned autodma : 1; /* auto-attempt using DMA at boot */
794 unsigned udma_four : 1; /* 1=ATA-66 capable, 0=default */
795 unsigned no_lba48 : 1; /* 1 = cannot do LBA48 */ 797 unsigned no_lba48 : 1; /* 1 = cannot do LBA48 */
796 unsigned no_lba48_dma : 1; /* 1 = cannot do LBA48 DMA */ 798 unsigned no_lba48_dma : 1; /* 1 = cannot do LBA48 DMA */
797 unsigned auto_poll : 1; /* supports nop auto-poll */ 799 unsigned auto_poll : 1; /* supports nop auto-poll */
@@ -863,7 +865,7 @@ typedef struct hwgroup_s {
863 865
864typedef struct ide_driver_s ide_driver_t; 866typedef struct ide_driver_s ide_driver_t;
865 867
866extern struct semaphore ide_setting_sem; 868extern struct mutex ide_setting_mtx;
867 869
868int set_io_32bit(ide_drive_t *, int); 870int set_io_32bit(ide_drive_t *, int);
869int set_pio_mode(ide_drive_t *, int); 871int set_pio_mode(ide_drive_t *, int);
@@ -1304,8 +1306,8 @@ extern int __ide_dma_check(ide_drive_t *);
1304extern int ide_dma_setup(ide_drive_t *); 1306extern int ide_dma_setup(ide_drive_t *);
1305extern void ide_dma_start(ide_drive_t *); 1307extern void ide_dma_start(ide_drive_t *);
1306extern int __ide_dma_end(ide_drive_t *); 1308extern int __ide_dma_end(ide_drive_t *);
1307extern int __ide_dma_lostirq(ide_drive_t *); 1309extern void ide_dma_lost_irq(ide_drive_t *);
1308extern int __ide_dma_timeout(ide_drive_t *); 1310extern void ide_dma_timeout(ide_drive_t *);
1309#endif /* CONFIG_BLK_DEV_IDEDMA_PCI */ 1311#endif /* CONFIG_BLK_DEV_IDEDMA_PCI */
1310 1312
1311#else 1313#else
@@ -1382,11 +1384,11 @@ extern const ide_pio_timings_t ide_pio_timings[6];
1382 1384
1383 1385
1384extern spinlock_t ide_lock; 1386extern spinlock_t ide_lock;
1385extern struct semaphore ide_cfg_sem; 1387extern struct mutex ide_cfg_mtx;
1386/* 1388/*
1387 * Structure locking: 1389 * Structure locking:
1388 * 1390 *
1389 * ide_cfg_sem and ide_lock together protect changes to 1391 * ide_cfg_mtx and ide_lock together protect changes to
1390 * ide_hwif_t->{next,hwgroup} 1392 * ide_hwif_t->{next,hwgroup}
1391 * ide_drive_t->next 1393 * ide_drive_t->next
1392 * 1394 *
diff --git a/include/linux/input.h b/include/linux/input.h
index d8521c72f69f..18c98b543030 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -981,15 +981,15 @@ struct input_dev {
981 struct mutex mutex; /* serializes open and close operations */ 981 struct mutex mutex; /* serializes open and close operations */
982 unsigned int users; 982 unsigned int users;
983 983
984 struct class_device cdev; 984 struct device dev;
985 union { /* temporarily so while we switching to struct device */ 985 union { /* temporarily so while we switching to struct device */
986 struct device *parent; 986 struct device *dev;
987 } dev; 987 } cdev;
988 988
989 struct list_head h_list; 989 struct list_head h_list;
990 struct list_head node; 990 struct list_head node;
991}; 991};
992#define to_input_dev(d) container_of(d, struct input_dev, cdev) 992#define to_input_dev(d) container_of(d, struct input_dev, dev)
993 993
994/* 994/*
995 * Verify that we are in sync with input_device_id mod_devicetable.h #defines 995 * Verify that we are in sync with input_device_id mod_devicetable.h #defines
@@ -1096,22 +1096,22 @@ struct input_handle {
1096 struct list_head h_node; 1096 struct list_head h_node;
1097}; 1097};
1098 1098
1099#define to_dev(n) container_of(n,struct input_dev,node) 1099#define to_dev(n) container_of(n, struct input_dev, node)
1100#define to_handler(n) container_of(n,struct input_handler,node) 1100#define to_handler(n) container_of(n, struct input_handler, node)
1101#define to_handle(n) container_of(n,struct input_handle,d_node) 1101#define to_handle(n) container_of(n, struct input_handle, d_node)
1102#define to_handle_h(n) container_of(n,struct input_handle,h_node) 1102#define to_handle_h(n) container_of(n, struct input_handle, h_node)
1103 1103
1104struct input_dev *input_allocate_device(void); 1104struct input_dev *input_allocate_device(void);
1105void input_free_device(struct input_dev *dev); 1105void input_free_device(struct input_dev *dev);
1106 1106
1107static inline struct input_dev *input_get_device(struct input_dev *dev) 1107static inline struct input_dev *input_get_device(struct input_dev *dev)
1108{ 1108{
1109 return to_input_dev(class_device_get(&dev->cdev)); 1109 return to_input_dev(get_device(&dev->dev));
1110} 1110}
1111 1111
1112static inline void input_put_device(struct input_dev *dev) 1112static inline void input_put_device(struct input_dev *dev)
1113{ 1113{
1114 class_device_put(&dev->cdev); 1114 put_device(&dev->dev);
1115} 1115}
1116 1116
1117static inline void *input_get_drvdata(struct input_dev *dev) 1117static inline void *input_get_drvdata(struct input_dev *dev)
diff --git a/include/linux/ioprio.h b/include/linux/ioprio.h
index 8e2042b9d471..2eaa142cd061 100644
--- a/include/linux/ioprio.h
+++ b/include/linux/ioprio.h
@@ -47,8 +47,10 @@ enum {
47#define IOPRIO_NORM (4) 47#define IOPRIO_NORM (4)
48static inline int task_ioprio(struct task_struct *task) 48static inline int task_ioprio(struct task_struct *task)
49{ 49{
50 WARN_ON(!ioprio_valid(task->ioprio)); 50 if (ioprio_valid(task->ioprio))
51 return IOPRIO_PRIO_DATA(task->ioprio); 51 return IOPRIO_PRIO_DATA(task->ioprio);
52
53 return IOPRIO_NORM;
52} 54}
53 55
54static inline int task_nice_ioprio(struct task_struct *task) 56static inline int task_nice_ioprio(struct task_struct *task)
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 620da7be07b7..a3df64677ac3 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -116,6 +116,7 @@ static inline struct device *pci_dev_to_dev(struct pci_dev *pdev)
116enum { 116enum {
117 /* various global constants */ 117 /* various global constants */
118 LIBATA_MAX_PRD = ATA_MAX_PRD / 2, 118 LIBATA_MAX_PRD = ATA_MAX_PRD / 2,
119 LIBATA_DUMB_MAX_PRD = ATA_MAX_PRD / 4, /* Worst case */
119 ATA_MAX_PORTS = 8, 120 ATA_MAX_PORTS = 8,
120 ATA_DEF_QUEUE = 1, 121 ATA_DEF_QUEUE = 1,
121 /* tag ATA_MAX_QUEUE - 1 is reserved for internal commands */ 122 /* tag ATA_MAX_QUEUE - 1 is reserved for internal commands */
@@ -136,6 +137,8 @@ enum {
136 ATA_DFLAG_CDB_INTR = (1 << 2), /* device asserts INTRQ when ready for CDB */ 137 ATA_DFLAG_CDB_INTR = (1 << 2), /* device asserts INTRQ when ready for CDB */
137 ATA_DFLAG_NCQ = (1 << 3), /* device supports NCQ */ 138 ATA_DFLAG_NCQ = (1 << 3), /* device supports NCQ */
138 ATA_DFLAG_FLUSH_EXT = (1 << 4), /* do FLUSH_EXT instead of FLUSH */ 139 ATA_DFLAG_FLUSH_EXT = (1 << 4), /* do FLUSH_EXT instead of FLUSH */
140 ATA_DFLAG_ACPI_PENDING = (1 << 5), /* ACPI resume action pending */
141 ATA_DFLAG_ACPI_FAILED = (1 << 6), /* ACPI on devcfg has failed */
139 ATA_DFLAG_CFG_MASK = (1 << 8) - 1, 142 ATA_DFLAG_CFG_MASK = (1 << 8) - 1,
140 143
141 ATA_DFLAG_PIO = (1 << 8), /* device limited to PIO mode */ 144 ATA_DFLAG_PIO = (1 << 8), /* device limited to PIO mode */
@@ -196,6 +199,7 @@ enum {
196 ATA_PFLAG_FLUSH_PORT_TASK = (1 << 16), /* flush port task */ 199 ATA_PFLAG_FLUSH_PORT_TASK = (1 << 16), /* flush port task */
197 ATA_PFLAG_SUSPENDED = (1 << 17), /* port is suspended (power) */ 200 ATA_PFLAG_SUSPENDED = (1 << 17), /* port is suspended (power) */
198 ATA_PFLAG_PM_PENDING = (1 << 18), /* PM operation pending */ 201 ATA_PFLAG_PM_PENDING = (1 << 18), /* PM operation pending */
202 ATA_PFLAG_GTM_VALID = (1 << 19), /* acpi_gtm data valid */
199 203
200 /* struct ata_queued_cmd flags */ 204 /* struct ata_queued_cmd flags */
201 ATA_QCFLAG_ACTIVE = (1 << 0), /* cmd not yet ack'd to scsi lyer */ 205 ATA_QCFLAG_ACTIVE = (1 << 0), /* cmd not yet ack'd to scsi lyer */
@@ -363,6 +367,9 @@ struct ata_host {
363 void *private_data; 367 void *private_data;
364 const struct ata_port_operations *ops; 368 const struct ata_port_operations *ops;
365 unsigned long flags; 369 unsigned long flags;
370#ifdef CONFIG_ATA_ACPI
371 acpi_handle acpi_handle;
372#endif
366 struct ata_port *simplex_claimed; /* channel owning the DMA */ 373 struct ata_port *simplex_claimed; /* channel owning the DMA */
367 struct ata_port *ports[0]; 374 struct ata_port *ports[0];
368}; 375};
@@ -429,6 +436,9 @@ struct ata_device {
429 unsigned int devno; /* 0 or 1 */ 436 unsigned int devno; /* 0 or 1 */
430 unsigned long flags; /* ATA_DFLAG_xxx */ 437 unsigned long flags; /* ATA_DFLAG_xxx */
431 struct scsi_device *sdev; /* attached SCSI device */ 438 struct scsi_device *sdev; /* attached SCSI device */
439#ifdef CONFIG_ATA_ACPI
440 acpi_handle acpi_handle;
441#endif
432 /* n_sector is used as CLEAR_OFFSET, read comment above CLEAR_OFFSET */ 442 /* n_sector is used as CLEAR_OFFSET, read comment above CLEAR_OFFSET */
433 u64 n_sectors; /* size of device, if ATA */ 443 u64 n_sectors; /* size of device, if ATA */
434 unsigned int class; /* ATA_DEV_xxx */ 444 unsigned int class; /* ATA_DEV_xxx */
@@ -457,10 +467,6 @@ struct ata_device {
457 struct ata_ering ering; 467 struct ata_ering ering;
458 int spdn_cnt; 468 int spdn_cnt;
459 unsigned int horkage; /* List of broken features */ 469 unsigned int horkage; /* List of broken features */
460#ifdef CONFIG_ATA_ACPI
461 /* ACPI objects info */
462 acpi_handle obj_handle;
463#endif
464}; 470};
465 471
466/* Offset into struct ata_device. Fields above it are maintained 472/* Offset into struct ata_device. Fields above it are maintained
@@ -489,6 +495,17 @@ struct ata_eh_context {
489 unsigned int did_probe_mask; 495 unsigned int did_probe_mask;
490}; 496};
491 497
498struct ata_acpi_drive
499{
500 u32 pio;
501 u32 dma;
502} __packed;
503
504struct ata_acpi_gtm {
505 struct ata_acpi_drive drive[2];
506 u32 flags;
507} __packed;
508
492struct ata_port { 509struct ata_port {
493 struct Scsi_Host *scsi_host; /* our co-allocated scsi host */ 510 struct Scsi_Host *scsi_host; /* our co-allocated scsi host */
494 const struct ata_port_operations *ops; 511 const struct ata_port_operations *ops;
@@ -549,6 +566,10 @@ struct ata_port {
549 566
550 void *private_data; 567 void *private_data;
551 568
569#ifdef CONFIG_ATA_ACPI
570 acpi_handle acpi_handle;
571 struct ata_acpi_gtm acpi_gtm;
572#endif
552 u8 sector_buf[ATA_SECT_SIZE]; /* owned by EH */ 573 u8 sector_buf[ATA_SECT_SIZE]; /* owned by EH */
553}; 574};
554 575
@@ -758,6 +779,7 @@ extern void ata_data_xfer(struct ata_device *adev, unsigned char *buf,
758 unsigned int buflen, int write_data); 779 unsigned int buflen, int write_data);
759extern void ata_data_xfer_noirq(struct ata_device *adev, unsigned char *buf, 780extern void ata_data_xfer_noirq(struct ata_device *adev, unsigned char *buf,
760 unsigned int buflen, int write_data); 781 unsigned int buflen, int write_data);
782extern void ata_dumb_qc_prep(struct ata_queued_cmd *qc);
761extern void ata_qc_prep(struct ata_queued_cmd *qc); 783extern void ata_qc_prep(struct ata_queued_cmd *qc);
762extern void ata_noop_qc_prep(struct ata_queued_cmd *qc); 784extern void ata_noop_qc_prep(struct ata_queued_cmd *qc);
763extern unsigned int ata_qc_issue_prot(struct ata_queued_cmd *qc); 785extern unsigned int ata_qc_issue_prot(struct ata_queued_cmd *qc);
diff --git a/include/linux/mv643xx.h b/include/linux/mv643xx.h
index c6d4ab86b83c..b021b3a2b65a 100644
--- a/include/linux/mv643xx.h
+++ b/include/linux/mv643xx.h
@@ -13,10 +13,6 @@
13#ifndef __ASM_MV643XX_H 13#ifndef __ASM_MV643XX_H
14#define __ASM_MV643XX_H 14#define __ASM_MV643XX_H
15 15
16#ifdef __mips__
17#include <asm/addrspace.h>
18#include <asm/marvell.h>
19#endif
20#include <asm/types.h> 16#include <asm/types.h>
21 17
22/****************************************/ 18/****************************************/
diff --git a/include/linux/pata_platform.h b/include/linux/pata_platform.h
index 2d5fd647e0e9..5799e8d50623 100644
--- a/include/linux/pata_platform.h
+++ b/include/linux/pata_platform.h
@@ -8,6 +8,11 @@ struct pata_platform_info {
8 * spacing used by ata_std_ports(). 8 * spacing used by ata_std_ports().
9 */ 9 */
10 unsigned int ioport_shift; 10 unsigned int ioport_shift;
11 /*
12 * Indicate platform specific irq types and initial
13 * IRQ flags when call request_irq()
14 */
15 unsigned int irq_flags;
11}; 16};
12 17
13#endif /* __LINUX_PATA_PLATFORM_H */ 18#endif /* __LINUX_PATA_PLATFORM_H */
diff --git a/include/linux/pda_power.h b/include/linux/pda_power.h
new file mode 100644
index 000000000000..1375f15797e7
--- /dev/null
+++ b/include/linux/pda_power.h
@@ -0,0 +1,31 @@
1/*
2 * Common power driver for PDAs and phones with one or two external
3 * power supplies (AC/USB) connected to main and backup batteries,
4 * and optional builtin charger.
5 *
6 * Copyright © 2007 Anton Vorontsov <cbou@mail.ru>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#ifndef __PDA_POWER_H__
14#define __PDA_POWER_H__
15
16#define PDA_POWER_CHARGE_AC (1 << 0)
17#define PDA_POWER_CHARGE_USB (1 << 1)
18
19struct pda_power_pdata {
20 int (*is_ac_online)(void);
21 int (*is_usb_online)(void);
22 void (*set_charge)(int flags);
23
24 char **supplied_to;
25 size_t num_supplicants;
26
27 unsigned int wait_for_status; /* msecs, default is 500 */
28 unsigned int wait_for_charger; /* msecs, default is 500 */
29};
30
31#endif /* __PDA_POWER_H__ */
diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h
index c8884f971228..8e4120285f72 100644
--- a/include/linux/pipe_fs_i.h
+++ b/include/linux/pipe_fs_i.h
@@ -9,13 +9,39 @@
9#define PIPE_BUF_FLAG_ATOMIC 0x02 /* was atomically mapped */ 9#define PIPE_BUF_FLAG_ATOMIC 0x02 /* was atomically mapped */
10#define PIPE_BUF_FLAG_GIFT 0x04 /* page is a gift */ 10#define PIPE_BUF_FLAG_GIFT 0x04 /* page is a gift */
11 11
12/**
13 * struct pipe_buffer - a linux kernel pipe buffer
14 * @page: the page containing the data for the pipe buffer
15 * @offset: offset of data inside the @page
16 * @len: length of data inside the @page
17 * @ops: operations associated with this buffer. See @pipe_buf_operations.
18 * @flags: pipe buffer flags. See above.
19 * @private: private data owned by the ops.
20 **/
12struct pipe_buffer { 21struct pipe_buffer {
13 struct page *page; 22 struct page *page;
14 unsigned int offset, len; 23 unsigned int offset, len;
15 const struct pipe_buf_operations *ops; 24 const struct pipe_buf_operations *ops;
16 unsigned int flags; 25 unsigned int flags;
26 unsigned long private;
17}; 27};
18 28
29/**
30 * struct pipe_inode_info - a linux kernel pipe
31 * @wait: reader/writer wait point in case of empty/full pipe
32 * @nrbufs: the number of non-empty pipe buffers in this pipe
33 * @curbuf: the current pipe buffer entry
34 * @tmp_page: cached released page
35 * @readers: number of current readers of this pipe
36 * @writers: number of current writers of this pipe
37 * @waiting_writers: number of writers blocked waiting for room
38 * @r_counter: reader counter
39 * @w_counter: writer counter
40 * @fasync_readers: reader side fasync
41 * @fasync_writers: writer side fasync
42 * @inode: inode this pipe is attached to
43 * @bufs: the circular array of pipe buffers
44 **/
19struct pipe_inode_info { 45struct pipe_inode_info {
20 wait_queue_head_t wait; 46 wait_queue_head_t wait;
21 unsigned int nrbufs, curbuf; 47 unsigned int nrbufs, curbuf;
@@ -34,22 +60,73 @@ struct pipe_inode_info {
34/* 60/*
35 * Note on the nesting of these functions: 61 * Note on the nesting of these functions:
36 * 62 *
37 * ->pin() 63 * ->confirm()
38 * ->steal() 64 * ->steal()
39 * ... 65 * ...
40 * ->map() 66 * ->map()
41 * ... 67 * ...
42 * ->unmap() 68 * ->unmap()
43 * 69 *
44 * That is, ->map() must be called on a pinned buffer, same goes for ->steal(). 70 * That is, ->map() must be called on a confirmed buffer,
71 * same goes for ->steal(). See below for the meaning of each
72 * operation. Also see kerneldoc in fs/pipe.c for the pipe
73 * and generic variants of these hooks.
45 */ 74 */
46struct pipe_buf_operations { 75struct pipe_buf_operations {
76 /*
77 * This is set to 1, if the generic pipe read/write may coalesce
78 * data into an existing buffer. If this is set to 0, a new pipe
79 * page segment is always used for new data.
80 */
47 int can_merge; 81 int can_merge;
82
83 /*
84 * ->map() returns a virtual address mapping of the pipe buffer.
85 * The last integer flag reflects whether this should be an atomic
86 * mapping or not. The atomic map is faster, however you can't take
87 * page faults before calling ->unmap() again. So if you need to eg
88 * access user data through copy_to/from_user(), then you must get
89 * a non-atomic map. ->map() uses the KM_USER0 atomic slot for
90 * atomic maps, so you can't map more than one pipe_buffer at once
91 * and you have to be careful if mapping another page as source
92 * or destination for a copy (IOW, it has to use something else
93 * than KM_USER0).
94 */
48 void * (*map)(struct pipe_inode_info *, struct pipe_buffer *, int); 95 void * (*map)(struct pipe_inode_info *, struct pipe_buffer *, int);
96
97 /*
98 * Undoes ->map(), finishes the virtual mapping of the pipe buffer.
99 */
49 void (*unmap)(struct pipe_inode_info *, struct pipe_buffer *, void *); 100 void (*unmap)(struct pipe_inode_info *, struct pipe_buffer *, void *);
50 int (*pin)(struct pipe_inode_info *, struct pipe_buffer *); 101
102 /*
103 * ->confirm() verifies that the data in the pipe buffer is there
104 * and that the contents are good. If the pages in the pipe belong
105 * to a file system, we may need to wait for IO completion in this
106 * hook. Returns 0 for good, or a negative error value in case of
107 * error.
108 */
109 int (*confirm)(struct pipe_inode_info *, struct pipe_buffer *);
110
111 /*
112 * When the contents of this pipe buffer has been completely
113 * consumed by a reader, ->release() is called.
114 */
51 void (*release)(struct pipe_inode_info *, struct pipe_buffer *); 115 void (*release)(struct pipe_inode_info *, struct pipe_buffer *);
116
117 /*
118 * Attempt to take ownership of the pipe buffer and its contents.
119 * ->steal() returns 0 for success, in which case the contents
120 * of the pipe (the buf->page) is locked and now completely owned
121 * by the caller. The page may then be transferred to a different
122 * mapping, the most often used case is insertion into different
123 * file address space cache.
124 */
52 int (*steal)(struct pipe_inode_info *, struct pipe_buffer *); 125 int (*steal)(struct pipe_inode_info *, struct pipe_buffer *);
126
127 /*
128 * Get a reference to the pipe buffer.
129 */
53 void (*get)(struct pipe_inode_info *, struct pipe_buffer *); 130 void (*get)(struct pipe_inode_info *, struct pipe_buffer *);
54}; 131};
55 132
@@ -68,39 +145,7 @@ void __free_pipe_info(struct pipe_inode_info *);
68void *generic_pipe_buf_map(struct pipe_inode_info *, struct pipe_buffer *, int); 145void *generic_pipe_buf_map(struct pipe_inode_info *, struct pipe_buffer *, int);
69void generic_pipe_buf_unmap(struct pipe_inode_info *, struct pipe_buffer *, void *); 146void generic_pipe_buf_unmap(struct pipe_inode_info *, struct pipe_buffer *, void *);
70void generic_pipe_buf_get(struct pipe_inode_info *, struct pipe_buffer *); 147void generic_pipe_buf_get(struct pipe_inode_info *, struct pipe_buffer *);
71int generic_pipe_buf_pin(struct pipe_inode_info *, struct pipe_buffer *); 148int generic_pipe_buf_confirm(struct pipe_inode_info *, struct pipe_buffer *);
72int generic_pipe_buf_steal(struct pipe_inode_info *, struct pipe_buffer *); 149int generic_pipe_buf_steal(struct pipe_inode_info *, struct pipe_buffer *);
73 150
74/*
75 * splice is tied to pipes as a transport (at least for now), so we'll just
76 * add the splice flags here.
77 */
78#define SPLICE_F_MOVE (0x01) /* move pages instead of copying */
79#define SPLICE_F_NONBLOCK (0x02) /* don't block on the pipe splicing (but */
80 /* we may still block on the fd we splice */
81 /* from/to, of course */
82#define SPLICE_F_MORE (0x04) /* expect more data */
83#define SPLICE_F_GIFT (0x08) /* pages passed in are a gift */
84
85/*
86 * Passed to the actors
87 */
88struct splice_desc {
89 unsigned int len, total_len; /* current and remaining length */
90 unsigned int flags; /* splice flags */
91 struct file *file; /* file to read/write */
92 loff_t pos; /* file position */
93};
94
95typedef int (splice_actor)(struct pipe_inode_info *, struct pipe_buffer *,
96 struct splice_desc *);
97
98extern ssize_t splice_from_pipe(struct pipe_inode_info *, struct file *,
99 loff_t *, size_t, unsigned int,
100 splice_actor *);
101
102extern ssize_t __splice_from_pipe(struct pipe_inode_info *, struct file *,
103 loff_t *, size_t, unsigned int,
104 splice_actor *);
105
106#endif 151#endif
diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h
new file mode 100644
index 000000000000..606c0957997f
--- /dev/null
+++ b/include/linux/power_supply.h
@@ -0,0 +1,180 @@
1/*
2 * Universal power supply monitor class
3 *
4 * Copyright © 2007 Anton Vorontsov <cbou@mail.ru>
5 * Copyright © 2004 Szabolcs Gyurko
6 * Copyright © 2003 Ian Molton <spyro@f2s.com>
7 *
8 * Modified: 2004, Oct Szabolcs Gyurko
9 *
10 * You may use this code as per GPL version 2
11 */
12
13#ifndef __LINUX_POWER_SUPPLY_H__
14#define __LINUX_POWER_SUPPLY_H__
15
16#include <linux/device.h>
17#include <linux/workqueue.h>
18#include <linux/leds.h>
19
20/*
21 * All voltages, currents, charges, energies, time and temperatures in uV,
22 * µA, µAh, µWh, seconds and tenths of degree Celsius unless otherwise
23 * stated. It's driver's job to convert its raw values to units in which
24 * this class operates.
25 */
26
27/*
28 * For systems where the charger determines the maximum battery capacity
29 * the min and max fields should be used to present these values to user
30 * space. Unused/unknown fields will not appear in sysfs.
31 */
32
33enum {
34 POWER_SUPPLY_STATUS_UNKNOWN = 0,
35 POWER_SUPPLY_STATUS_CHARGING,
36 POWER_SUPPLY_STATUS_DISCHARGING,
37 POWER_SUPPLY_STATUS_NOT_CHARGING,
38 POWER_SUPPLY_STATUS_FULL,
39};
40
41enum {
42 POWER_SUPPLY_HEALTH_UNKNOWN = 0,
43 POWER_SUPPLY_HEALTH_GOOD,
44 POWER_SUPPLY_HEALTH_OVERHEAT,
45 POWER_SUPPLY_HEALTH_DEAD,
46 POWER_SUPPLY_HEALTH_OVERVOLTAGE,
47 POWER_SUPPLY_HEALTH_UNSPEC_FAILURE,
48};
49
50enum {
51 POWER_SUPPLY_TECHNOLOGY_UNKNOWN = 0,
52 POWER_SUPPLY_TECHNOLOGY_NiMH,
53 POWER_SUPPLY_TECHNOLOGY_LION,
54 POWER_SUPPLY_TECHNOLOGY_LIPO,
55 POWER_SUPPLY_TECHNOLOGY_LiFe,
56 POWER_SUPPLY_TECHNOLOGY_NiCd,
57};
58
59enum {
60 POWER_SUPPLY_CAPACITY_LEVEL_UNKNOWN = 0,
61 POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL,
62 POWER_SUPPLY_CAPACITY_LEVEL_LOW,
63 POWER_SUPPLY_CAPACITY_LEVEL_NORMAL,
64 POWER_SUPPLY_CAPACITY_LEVEL_HIGH,
65 POWER_SUPPLY_CAPACITY_LEVEL_FULL,
66};
67
68enum power_supply_property {
69 /* Properties of type `int' */
70 POWER_SUPPLY_PROP_STATUS = 0,
71 POWER_SUPPLY_PROP_HEALTH,
72 POWER_SUPPLY_PROP_PRESENT,
73 POWER_SUPPLY_PROP_ONLINE,
74 POWER_SUPPLY_PROP_TECHNOLOGY,
75 POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
76 POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
77 POWER_SUPPLY_PROP_VOLTAGE_NOW,
78 POWER_SUPPLY_PROP_VOLTAGE_AVG,
79 POWER_SUPPLY_PROP_CURRENT_NOW,
80 POWER_SUPPLY_PROP_CURRENT_AVG,
81 POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
82 POWER_SUPPLY_PROP_CHARGE_EMPTY_DESIGN,
83 POWER_SUPPLY_PROP_CHARGE_FULL,
84 POWER_SUPPLY_PROP_CHARGE_EMPTY,
85 POWER_SUPPLY_PROP_CHARGE_NOW,
86 POWER_SUPPLY_PROP_CHARGE_AVG,
87 POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN,
88 POWER_SUPPLY_PROP_ENERGY_EMPTY_DESIGN,
89 POWER_SUPPLY_PROP_ENERGY_FULL,
90 POWER_SUPPLY_PROP_ENERGY_EMPTY,
91 POWER_SUPPLY_PROP_ENERGY_NOW,
92 POWER_SUPPLY_PROP_ENERGY_AVG,
93 POWER_SUPPLY_PROP_CAPACITY, /* in percents! */
94 POWER_SUPPLY_PROP_CAPACITY_LEVEL,
95 POWER_SUPPLY_PROP_TEMP,
96 POWER_SUPPLY_PROP_TEMP_AMBIENT,
97 POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW,
98 POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG,
99 POWER_SUPPLY_PROP_TIME_TO_FULL_NOW,
100 POWER_SUPPLY_PROP_TIME_TO_FULL_AVG,
101 /* Properties of type `const char *' */
102 POWER_SUPPLY_PROP_MODEL_NAME,
103 POWER_SUPPLY_PROP_MANUFACTURER,
104};
105
106enum power_supply_type {
107 POWER_SUPPLY_TYPE_BATTERY = 0,
108 POWER_SUPPLY_TYPE_UPS,
109 POWER_SUPPLY_TYPE_MAINS,
110 POWER_SUPPLY_TYPE_USB,
111};
112
113union power_supply_propval {
114 int intval;
115 const char *strval;
116};
117
118struct power_supply {
119 const char *name;
120 enum power_supply_type type;
121 enum power_supply_property *properties;
122 size_t num_properties;
123
124 char **supplied_to;
125 size_t num_supplicants;
126
127 int (*get_property)(struct power_supply *psy,
128 enum power_supply_property psp,
129 union power_supply_propval *val);
130 void (*external_power_changed)(struct power_supply *psy);
131
132 /* For APM emulation, think legacy userspace. */
133 int use_for_apm;
134
135 /* private */
136 struct device *dev;
137 struct work_struct changed_work;
138
139#ifdef CONFIG_LEDS_TRIGGERS
140 struct led_trigger *charging_full_trig;
141 char *charging_full_trig_name;
142 struct led_trigger *charging_trig;
143 char *charging_trig_name;
144 struct led_trigger *full_trig;
145 char *full_trig_name;
146 struct led_trigger *online_trig;
147 char *online_trig_name;
148#endif
149};
150
151/*
152 * This is recommended structure to specify static power supply parameters.
153 * Generic one, parametrizable for different power supplies. Power supply
154 * class itself does not use it, but that's what implementing most platform
155 * drivers, should try reuse for consistency.
156 */
157
158struct power_supply_info {
159 const char *name;
160 int technology;
161 int voltage_max_design;
162 int voltage_min_design;
163 int charge_full_design;
164 int charge_empty_design;
165 int energy_full_design;
166 int energy_empty_design;
167 int use_for_apm;
168};
169
170extern void power_supply_changed(struct power_supply *psy);
171extern int power_supply_am_i_supplied(struct power_supply *psy);
172
173extern int power_supply_register(struct device *parent,
174 struct power_supply *psy);
175extern void power_supply_unregister(struct power_supply *psy);
176
177/* For APM emulation, think legacy userspace. */
178extern struct class *power_supply_class;
179
180#endif /* __LINUX_POWER_SUPPLY_H__ */
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 693f0e6c54d4..cfb680585ab8 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -34,6 +34,8 @@
34#define SCHED_FIFO 1 34#define SCHED_FIFO 1
35#define SCHED_RR 2 35#define SCHED_RR 2
36#define SCHED_BATCH 3 36#define SCHED_BATCH 3
37/* SCHED_ISO: reserved but not implemented yet */
38#define SCHED_IDLE 5
37 39
38#ifdef __KERNEL__ 40#ifdef __KERNEL__
39 41
@@ -130,6 +132,26 @@ extern unsigned long nr_active(void);
130extern unsigned long nr_iowait(void); 132extern unsigned long nr_iowait(void);
131extern unsigned long weighted_cpuload(const int cpu); 133extern unsigned long weighted_cpuload(const int cpu);
132 134
135struct seq_file;
136struct cfs_rq;
137#ifdef CONFIG_SCHED_DEBUG
138extern void proc_sched_show_task(struct task_struct *p, struct seq_file *m);
139extern void proc_sched_set_task(struct task_struct *p);
140extern void
141print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq, u64 now);
142#else
143static inline void
144proc_sched_show_task(struct task_struct *p, struct seq_file *m)
145{
146}
147static inline void proc_sched_set_task(struct task_struct *p)
148{
149}
150static inline void
151print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq, u64 now)
152{
153}
154#endif
133 155
134/* 156/*
135 * Task state bitmask. NOTE! These bits are also 157 * Task state bitmask. NOTE! These bits are also
@@ -193,6 +215,7 @@ struct task_struct;
193extern void sched_init(void); 215extern void sched_init(void);
194extern void sched_init_smp(void); 216extern void sched_init_smp(void);
195extern void init_idle(struct task_struct *idle, int cpu); 217extern void init_idle(struct task_struct *idle, int cpu);
218extern void init_idle_bootup_task(struct task_struct *idle);
196 219
197extern cpumask_t nohz_cpu_mask; 220extern cpumask_t nohz_cpu_mask;
198#if defined(CONFIG_SMP) && defined(CONFIG_NO_HZ) 221#if defined(CONFIG_SMP) && defined(CONFIG_NO_HZ)
@@ -479,7 +502,7 @@ struct signal_struct {
479 * from jiffies_to_ns(utime + stime) if sched_clock uses something 502 * from jiffies_to_ns(utime + stime) if sched_clock uses something
480 * other than jiffies.) 503 * other than jiffies.)
481 */ 504 */
482 unsigned long long sched_time; 505 unsigned long long sum_sched_runtime;
483 506
484 /* 507 /*
485 * We don't bother to synchronize most readers of this at all, 508 * We don't bother to synchronize most readers of this at all,
@@ -521,31 +544,6 @@ struct signal_struct {
521#define SIGNAL_STOP_CONTINUED 0x00000004 /* SIGCONT since WCONTINUED reap */ 544#define SIGNAL_STOP_CONTINUED 0x00000004 /* SIGCONT since WCONTINUED reap */
522#define SIGNAL_GROUP_EXIT 0x00000008 /* group exit in progress */ 545#define SIGNAL_GROUP_EXIT 0x00000008 /* group exit in progress */
523 546
524
525/*
526 * Priority of a process goes from 0..MAX_PRIO-1, valid RT
527 * priority is 0..MAX_RT_PRIO-1, and SCHED_NORMAL/SCHED_BATCH
528 * tasks are in the range MAX_RT_PRIO..MAX_PRIO-1. Priority
529 * values are inverted: lower p->prio value means higher priority.
530 *
531 * The MAX_USER_RT_PRIO value allows the actual maximum
532 * RT priority to be separate from the value exported to
533 * user-space. This allows kernel threads to set their
534 * priority to a value higher than any user task. Note:
535 * MAX_RT_PRIO must not be smaller than MAX_USER_RT_PRIO.
536 */
537
538#define MAX_USER_RT_PRIO 100
539#define MAX_RT_PRIO MAX_USER_RT_PRIO
540
541#define MAX_PRIO (MAX_RT_PRIO + 40)
542
543#define rt_prio(prio) unlikely((prio) < MAX_RT_PRIO)
544#define rt_task(p) rt_prio((p)->prio)
545#define batch_task(p) (unlikely((p)->policy == SCHED_BATCH))
546#define is_rt_policy(p) ((p) != SCHED_NORMAL && (p) != SCHED_BATCH)
547#define has_rt_policy(p) unlikely(is_rt_policy((p)->policy))
548
549/* 547/*
550 * Some day this will be a full-fledged user tracking system.. 548 * Some day this will be a full-fledged user tracking system..
551 */ 549 */
@@ -583,13 +581,13 @@ struct reclaim_state;
583#if defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT) 581#if defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT)
584struct sched_info { 582struct sched_info {
585 /* cumulative counters */ 583 /* cumulative counters */
586 unsigned long cpu_time, /* time spent on the cpu */ 584 unsigned long pcnt; /* # of times run on this cpu */
587 run_delay, /* time spent waiting on a runqueue */ 585 unsigned long long cpu_time, /* time spent on the cpu */
588 pcnt; /* # of timeslices run on this cpu */ 586 run_delay; /* time spent waiting on a runqueue */
589 587
590 /* timestamps */ 588 /* timestamps */
591 unsigned long last_arrival, /* when we last ran on a cpu */ 589 unsigned long long last_arrival,/* when we last ran on a cpu */
592 last_queued; /* when we were last queued to run */ 590 last_queued; /* when we were last queued to run */
593}; 591};
594#endif /* defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT) */ 592#endif /* defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT) */
595 593
@@ -639,18 +637,24 @@ static inline int sched_info_on(void)
639#endif 637#endif
640} 638}
641 639
642enum idle_type 640enum cpu_idle_type {
643{ 641 CPU_IDLE,
644 SCHED_IDLE, 642 CPU_NOT_IDLE,
645 NOT_IDLE, 643 CPU_NEWLY_IDLE,
646 NEWLY_IDLE, 644 CPU_MAX_IDLE_TYPES
647 MAX_IDLE_TYPES
648}; 645};
649 646
650/* 647/*
651 * sched-domains (multiprocessor balancing) declarations: 648 * sched-domains (multiprocessor balancing) declarations:
652 */ 649 */
653#define SCHED_LOAD_SCALE 128UL /* increase resolution of load */ 650
651/*
652 * Increase resolution of nice-level calculations:
653 */
654#define SCHED_LOAD_SHIFT 10
655#define SCHED_LOAD_SCALE (1L << SCHED_LOAD_SHIFT)
656
657#define SCHED_LOAD_SCALE_FUZZ (SCHED_LOAD_SCALE >> 5)
654 658
655#ifdef CONFIG_SMP 659#ifdef CONFIG_SMP
656#define SD_LOAD_BALANCE 1 /* Do load balancing on this domain. */ 660#define SD_LOAD_BALANCE 1 /* Do load balancing on this domain. */
@@ -719,14 +723,14 @@ struct sched_domain {
719 723
720#ifdef CONFIG_SCHEDSTATS 724#ifdef CONFIG_SCHEDSTATS
721 /* load_balance() stats */ 725 /* load_balance() stats */
722 unsigned long lb_cnt[MAX_IDLE_TYPES]; 726 unsigned long lb_cnt[CPU_MAX_IDLE_TYPES];
723 unsigned long lb_failed[MAX_IDLE_TYPES]; 727 unsigned long lb_failed[CPU_MAX_IDLE_TYPES];
724 unsigned long lb_balanced[MAX_IDLE_TYPES]; 728 unsigned long lb_balanced[CPU_MAX_IDLE_TYPES];
725 unsigned long lb_imbalance[MAX_IDLE_TYPES]; 729 unsigned long lb_imbalance[CPU_MAX_IDLE_TYPES];
726 unsigned long lb_gained[MAX_IDLE_TYPES]; 730 unsigned long lb_gained[CPU_MAX_IDLE_TYPES];
727 unsigned long lb_hot_gained[MAX_IDLE_TYPES]; 731 unsigned long lb_hot_gained[CPU_MAX_IDLE_TYPES];
728 unsigned long lb_nobusyg[MAX_IDLE_TYPES]; 732 unsigned long lb_nobusyg[CPU_MAX_IDLE_TYPES];
729 unsigned long lb_nobusyq[MAX_IDLE_TYPES]; 733 unsigned long lb_nobusyq[CPU_MAX_IDLE_TYPES];
730 734
731 /* Active load balancing */ 735 /* Active load balancing */
732 unsigned long alb_cnt; 736 unsigned long alb_cnt;
@@ -753,12 +757,6 @@ struct sched_domain {
753extern int partition_sched_domains(cpumask_t *partition1, 757extern int partition_sched_domains(cpumask_t *partition1,
754 cpumask_t *partition2); 758 cpumask_t *partition2);
755 759
756/*
757 * Maximum cache size the migration-costs auto-tuning code will
758 * search from:
759 */
760extern unsigned int max_cache_size;
761
762#endif /* CONFIG_SMP */ 760#endif /* CONFIG_SMP */
763 761
764 762
@@ -809,14 +807,86 @@ struct mempolicy;
809struct pipe_inode_info; 807struct pipe_inode_info;
810struct uts_namespace; 808struct uts_namespace;
811 809
812enum sleep_type { 810struct rq;
813 SLEEP_NORMAL, 811struct sched_domain;
814 SLEEP_NONINTERACTIVE, 812
815 SLEEP_INTERACTIVE, 813struct sched_class {
816 SLEEP_INTERRUPTED, 814 struct sched_class *next;
815
816 void (*enqueue_task) (struct rq *rq, struct task_struct *p,
817 int wakeup, u64 now);
818 void (*dequeue_task) (struct rq *rq, struct task_struct *p,
819 int sleep, u64 now);
820 void (*yield_task) (struct rq *rq, struct task_struct *p);
821
822 void (*check_preempt_curr) (struct rq *rq, struct task_struct *p);
823
824 struct task_struct * (*pick_next_task) (struct rq *rq, u64 now);
825 void (*put_prev_task) (struct rq *rq, struct task_struct *p, u64 now);
826
827 int (*load_balance) (struct rq *this_rq, int this_cpu,
828 struct rq *busiest,
829 unsigned long max_nr_move, unsigned long max_load_move,
830 struct sched_domain *sd, enum cpu_idle_type idle,
831 int *all_pinned, unsigned long *total_load_moved);
832
833 void (*set_curr_task) (struct rq *rq);
834 void (*task_tick) (struct rq *rq, struct task_struct *p);
835 void (*task_new) (struct rq *rq, struct task_struct *p);
817}; 836};
818 837
819struct prio_array; 838struct load_weight {
839 unsigned long weight, inv_weight;
840};
841
842/*
843 * CFS stats for a schedulable entity (task, task-group etc)
844 *
845 * Current field usage histogram:
846 *
847 * 4 se->block_start
848 * 4 se->run_node
849 * 4 se->sleep_start
850 * 4 se->sleep_start_fair
851 * 6 se->load.weight
852 * 7 se->delta_fair
853 * 15 se->wait_runtime
854 */
855struct sched_entity {
856 long wait_runtime;
857 unsigned long delta_fair_run;
858 unsigned long delta_fair_sleep;
859 unsigned long delta_exec;
860 s64 fair_key;
861 struct load_weight load; /* for load-balancing */
862 struct rb_node run_node;
863 unsigned int on_rq;
864
865 u64 wait_start_fair;
866 u64 wait_start;
867 u64 exec_start;
868 u64 sleep_start;
869 u64 sleep_start_fair;
870 u64 block_start;
871 u64 sleep_max;
872 u64 block_max;
873 u64 exec_max;
874 u64 wait_max;
875 u64 last_ran;
876
877 u64 sum_exec_runtime;
878 s64 sum_wait_runtime;
879 s64 sum_sleep_runtime;
880 unsigned long wait_runtime_overruns;
881 unsigned long wait_runtime_underruns;
882#ifdef CONFIG_FAIR_GROUP_SCHED
883 struct sched_entity *parent;
884 /* rq on which this entity is (to be) queued: */
885 struct cfs_rq *cfs_rq;
886 /* rq "owned" by this entity/group: */
887 struct cfs_rq *my_q;
888#endif
889};
820 890
821struct task_struct { 891struct task_struct {
822 volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */ 892 volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */
@@ -832,23 +902,20 @@ struct task_struct {
832 int oncpu; 902 int oncpu;
833#endif 903#endif
834#endif 904#endif
835 int load_weight; /* for niceness load balancing purposes */ 905
836 int prio, static_prio, normal_prio; 906 int prio, static_prio, normal_prio;
837 struct list_head run_list; 907 struct list_head run_list;
838 struct prio_array *array; 908 struct sched_class *sched_class;
909 struct sched_entity se;
839 910
840 unsigned short ioprio; 911 unsigned short ioprio;
841#ifdef CONFIG_BLK_DEV_IO_TRACE 912#ifdef CONFIG_BLK_DEV_IO_TRACE
842 unsigned int btrace_seq; 913 unsigned int btrace_seq;
843#endif 914#endif
844 unsigned long sleep_avg;
845 unsigned long long timestamp, last_ran;
846 unsigned long long sched_time; /* sched_clock time spent running */
847 enum sleep_type sleep_type;
848 915
849 unsigned int policy; 916 unsigned int policy;
850 cpumask_t cpus_allowed; 917 cpumask_t cpus_allowed;
851 unsigned int time_slice, first_time_slice; 918 unsigned int time_slice;
852 919
853#if defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT) 920#if defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT)
854 struct sched_info sched_info; 921 struct sched_info sched_info;
@@ -1078,6 +1145,37 @@ struct task_struct {
1078#endif 1145#endif
1079}; 1146};
1080 1147
1148/*
1149 * Priority of a process goes from 0..MAX_PRIO-1, valid RT
1150 * priority is 0..MAX_RT_PRIO-1, and SCHED_NORMAL/SCHED_BATCH
1151 * tasks are in the range MAX_RT_PRIO..MAX_PRIO-1. Priority
1152 * values are inverted: lower p->prio value means higher priority.
1153 *
1154 * The MAX_USER_RT_PRIO value allows the actual maximum
1155 * RT priority to be separate from the value exported to
1156 * user-space. This allows kernel threads to set their
1157 * priority to a value higher than any user task. Note:
1158 * MAX_RT_PRIO must not be smaller than MAX_USER_RT_PRIO.
1159 */
1160
1161#define MAX_USER_RT_PRIO 100
1162#define MAX_RT_PRIO MAX_USER_RT_PRIO
1163
1164#define MAX_PRIO (MAX_RT_PRIO + 40)
1165#define DEFAULT_PRIO (MAX_RT_PRIO + 20)
1166
1167static inline int rt_prio(int prio)
1168{
1169 if (unlikely(prio < MAX_RT_PRIO))
1170 return 1;
1171 return 0;
1172}
1173
1174static inline int rt_task(struct task_struct *p)
1175{
1176 return rt_prio(p->prio);
1177}
1178
1081static inline pid_t process_group(struct task_struct *tsk) 1179static inline pid_t process_group(struct task_struct *tsk)
1082{ 1180{
1083 return tsk->signal->pgrp; 1181 return tsk->signal->pgrp;
@@ -1223,7 +1321,7 @@ static inline int set_cpus_allowed(struct task_struct *p, cpumask_t new_mask)
1223 1321
1224extern unsigned long long sched_clock(void); 1322extern unsigned long long sched_clock(void);
1225extern unsigned long long 1323extern unsigned long long
1226current_sched_time(const struct task_struct *current_task); 1324task_sched_runtime(struct task_struct *task);
1227 1325
1228/* sched_exec is called by processes performing an exec */ 1326/* sched_exec is called by processes performing an exec */
1229#ifdef CONFIG_SMP 1327#ifdef CONFIG_SMP
@@ -1232,6 +1330,8 @@ extern void sched_exec(void);
1232#define sched_exec() {} 1330#define sched_exec() {}
1233#endif 1331#endif
1234 1332
1333extern void sched_clock_unstable_event(void);
1334
1235#ifdef CONFIG_HOTPLUG_CPU 1335#ifdef CONFIG_HOTPLUG_CPU
1236extern void idle_task_exit(void); 1336extern void idle_task_exit(void);
1237#else 1337#else
@@ -1240,6 +1340,14 @@ static inline void idle_task_exit(void) {}
1240 1340
1241extern void sched_idle_next(void); 1341extern void sched_idle_next(void);
1242 1342
1343extern unsigned int sysctl_sched_granularity;
1344extern unsigned int sysctl_sched_wakeup_granularity;
1345extern unsigned int sysctl_sched_batch_wakeup_granularity;
1346extern unsigned int sysctl_sched_stat_granularity;
1347extern unsigned int sysctl_sched_runtime_limit;
1348extern unsigned int sysctl_sched_child_runs_first;
1349extern unsigned int sysctl_sched_features;
1350
1243#ifdef CONFIG_RT_MUTEXES 1351#ifdef CONFIG_RT_MUTEXES
1244extern int rt_mutex_getprio(struct task_struct *p); 1352extern int rt_mutex_getprio(struct task_struct *p);
1245extern void rt_mutex_setprio(struct task_struct *p, int prio); 1353extern void rt_mutex_setprio(struct task_struct *p, int prio);
@@ -1317,8 +1425,8 @@ extern void FASTCALL(wake_up_new_task(struct task_struct * tsk,
1317#else 1425#else
1318 static inline void kick_process(struct task_struct *tsk) { } 1426 static inline void kick_process(struct task_struct *tsk) { }
1319#endif 1427#endif
1320extern void FASTCALL(sched_fork(struct task_struct * p, int clone_flags)); 1428extern void sched_fork(struct task_struct *p, int clone_flags);
1321extern void FASTCALL(sched_exit(struct task_struct * p)); 1429extern void sched_dead(struct task_struct *p);
1322 1430
1323extern int in_group_p(gid_t); 1431extern int in_group_p(gid_t);
1324extern int in_egroup_p(gid_t); 1432extern int in_egroup_p(gid_t);
@@ -1406,7 +1514,7 @@ extern struct mm_struct * mm_alloc(void);
1406extern void FASTCALL(__mmdrop(struct mm_struct *)); 1514extern void FASTCALL(__mmdrop(struct mm_struct *));
1407static inline void mmdrop(struct mm_struct * mm) 1515static inline void mmdrop(struct mm_struct * mm)
1408{ 1516{
1409 if (atomic_dec_and_test(&mm->mm_count)) 1517 if (unlikely(atomic_dec_and_test(&mm->mm_count)))
1410 __mmdrop(mm); 1518 __mmdrop(mm);
1411} 1519}
1412 1520
@@ -1638,10 +1746,7 @@ static inline unsigned int task_cpu(const struct task_struct *p)
1638 return task_thread_info(p)->cpu; 1746 return task_thread_info(p)->cpu;
1639} 1747}
1640 1748
1641static inline void set_task_cpu(struct task_struct *p, unsigned int cpu) 1749extern void set_task_cpu(struct task_struct *p, unsigned int cpu);
1642{
1643 task_thread_info(p)->cpu = cpu;
1644}
1645 1750
1646#else 1751#else
1647 1752
diff --git a/include/linux/splice.h b/include/linux/splice.h
new file mode 100644
index 000000000000..33e447f98a54
--- /dev/null
+++ b/include/linux/splice.h
@@ -0,0 +1,73 @@
1/*
2 * Function declerations and data structures related to the splice
3 * implementation.
4 *
5 * Copyright (C) 2007 Jens Axboe <jens.axboe@oracle.com>
6 *
7 */
8#ifndef SPLICE_H
9#define SPLICE_H
10
11#include <linux/pipe_fs_i.h>
12
13/*
14 * splice is tied to pipes as a transport (at least for now), so we'll just
15 * add the splice flags here.
16 */
17#define SPLICE_F_MOVE (0x01) /* move pages instead of copying */
18#define SPLICE_F_NONBLOCK (0x02) /* don't block on the pipe splicing (but */
19 /* we may still block on the fd we splice */
20 /* from/to, of course */
21#define SPLICE_F_MORE (0x04) /* expect more data */
22#define SPLICE_F_GIFT (0x08) /* pages passed in are a gift */
23
24/*
25 * Passed to the actors
26 */
27struct splice_desc {
28 unsigned int len, total_len; /* current and remaining length */
29 unsigned int flags; /* splice flags */
30 /*
31 * actor() private data
32 */
33 union {
34 void __user *userptr; /* memory to write to */
35 struct file *file; /* file to read/write */
36 void *data; /* cookie */
37 } u;
38 loff_t pos; /* file position */
39};
40
41struct partial_page {
42 unsigned int offset;
43 unsigned int len;
44 unsigned long private;
45};
46
47/*
48 * Passed to splice_to_pipe
49 */
50struct splice_pipe_desc {
51 struct page **pages; /* page map */
52 struct partial_page *partial; /* pages[] may not be contig */
53 int nr_pages; /* number of pages in map */
54 unsigned int flags; /* splice flags */
55 const struct pipe_buf_operations *ops;/* ops associated with output pipe */
56};
57
58typedef int (splice_actor)(struct pipe_inode_info *, struct pipe_buffer *,
59 struct splice_desc *);
60typedef int (splice_direct_actor)(struct pipe_inode_info *,
61 struct splice_desc *);
62
63extern ssize_t splice_from_pipe(struct pipe_inode_info *, struct file *,
64 loff_t *, size_t, unsigned int,
65 splice_actor *);
66extern ssize_t __splice_from_pipe(struct pipe_inode_info *,
67 struct splice_desc *, splice_actor *);
68extern ssize_t splice_to_pipe(struct pipe_inode_info *,
69 struct splice_pipe_desc *);
70extern ssize_t splice_direct_to_actor(struct file *, struct splice_desc *,
71 splice_direct_actor *);
72
73#endif
diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h
index 4a7ae8ab6eb8..129d50f2225c 100644
--- a/include/linux/sunrpc/svc.h
+++ b/include/linux/sunrpc/svc.h
@@ -253,7 +253,7 @@ struct svc_rqst {
253 * determine what device number 253 * determine what device number
254 * to report (real or virtual) 254 * to report (real or virtual)
255 */ 255 */
256 int rq_sendfile_ok; /* turned off in gss privacy 256 int rq_splice_ok; /* turned off in gss privacy
257 * to prevent encrypting page 257 * to prevent encrypting page
258 * cache pages */ 258 * cache pages */
259 wait_queue_head_t rq_wait; /* synchronization */ 259 wait_queue_head_t rq_wait; /* synchronization */
diff --git a/include/linux/topology.h b/include/linux/topology.h
index a9d1f049cc15..da6c39b2d051 100644
--- a/include/linux/topology.h
+++ b/include/linux/topology.h
@@ -98,7 +98,7 @@
98 .cache_nice_tries = 0, \ 98 .cache_nice_tries = 0, \
99 .busy_idx = 0, \ 99 .busy_idx = 0, \
100 .idle_idx = 0, \ 100 .idle_idx = 0, \
101 .newidle_idx = 1, \ 101 .newidle_idx = 0, \
102 .wake_idx = 0, \ 102 .wake_idx = 0, \
103 .forkexec_idx = 0, \ 103 .forkexec_idx = 0, \
104 .flags = SD_LOAD_BALANCE \ 104 .flags = SD_LOAD_BALANCE \
@@ -128,14 +128,15 @@
128 .imbalance_pct = 125, \ 128 .imbalance_pct = 125, \
129 .cache_nice_tries = 1, \ 129 .cache_nice_tries = 1, \
130 .busy_idx = 2, \ 130 .busy_idx = 2, \
131 .idle_idx = 1, \ 131 .idle_idx = 0, \
132 .newidle_idx = 2, \ 132 .newidle_idx = 0, \
133 .wake_idx = 1, \ 133 .wake_idx = 1, \
134 .forkexec_idx = 1, \ 134 .forkexec_idx = 1, \
135 .flags = SD_LOAD_BALANCE \ 135 .flags = SD_LOAD_BALANCE \
136 | SD_BALANCE_NEWIDLE \ 136 | SD_BALANCE_NEWIDLE \
137 | SD_BALANCE_EXEC \ 137 | SD_BALANCE_EXEC \
138 | SD_WAKE_AFFINE \ 138 | SD_WAKE_AFFINE \
139 | SD_WAKE_IDLE \
139 | SD_SHARE_PKG_RESOURCES\ 140 | SD_SHARE_PKG_RESOURCES\
140 | BALANCE_FOR_MC_POWER, \ 141 | BALANCE_FOR_MC_POWER, \
141 .last_balance = jiffies, \ 142 .last_balance = jiffies, \
@@ -158,14 +159,15 @@
158 .imbalance_pct = 125, \ 159 .imbalance_pct = 125, \
159 .cache_nice_tries = 1, \ 160 .cache_nice_tries = 1, \
160 .busy_idx = 2, \ 161 .busy_idx = 2, \
161 .idle_idx = 1, \ 162 .idle_idx = 0, \
162 .newidle_idx = 2, \ 163 .newidle_idx = 0, \
163 .wake_idx = 1, \ 164 .wake_idx = 1, \
164 .forkexec_idx = 1, \ 165 .forkexec_idx = 1, \
165 .flags = SD_LOAD_BALANCE \ 166 .flags = SD_LOAD_BALANCE \
166 | SD_BALANCE_NEWIDLE \ 167 | SD_BALANCE_NEWIDLE \
167 | SD_BALANCE_EXEC \ 168 | SD_BALANCE_EXEC \
168 | SD_WAKE_AFFINE \ 169 | SD_WAKE_AFFINE \
170 | SD_WAKE_IDLE \
169 | BALANCE_FOR_PKG_POWER,\ 171 | BALANCE_FOR_PKG_POWER,\
170 .last_balance = jiffies, \ 172 .last_balance = jiffies, \
171 .balance_interval = 1, \ 173 .balance_interval = 1, \
diff --git a/include/linux/usb.h b/include/linux/usb.h
index 94bd38a6d947..56aa2ee21f1b 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -729,6 +729,22 @@ static inline int usb_endpoint_is_isoc_out(const struct usb_endpoint_descriptor
729 .bcdDevice_lo = (lo), .bcdDevice_hi = (hi) 729 .bcdDevice_lo = (lo), .bcdDevice_hi = (hi)
730 730
731/** 731/**
732 * USB_DEVICE_INTERFACE_PROTOCOL - macro used to describe a usb
733 * device with a specific interface protocol
734 * @vend: the 16 bit USB Vendor ID
735 * @prod: the 16 bit USB Product ID
736 * @pr: bInterfaceProtocol value
737 *
738 * This macro is used to create a struct usb_device_id that matches a
739 * specific interface protocol of devices.
740 */
741#define USB_DEVICE_INTERFACE_PROTOCOL(vend,prod,pr) \
742 .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_PROTOCOL, \
743 .idVendor = (vend), \
744 .idProduct = (prod), \
745 .bInterfaceProtocol = (pr)
746
747/**
732 * USB_DEVICE_INFO - macro used to describe a class of usb devices 748 * USB_DEVICE_INFO - macro used to describe a class of usb devices
733 * @cl: bDeviceClass value 749 * @cl: bDeviceClass value
734 * @sc: bDeviceSubClass value 750 * @sc: bDeviceSubClass value
diff --git a/include/linux/wait.h b/include/linux/wait.h
index e820d00e1383..0e686280450b 100644
--- a/include/linux/wait.h
+++ b/include/linux/wait.h
@@ -366,15 +366,15 @@ static inline void remove_wait_queue_locked(wait_queue_head_t *q,
366 366
367/* 367/*
368 * These are the old interfaces to sleep waiting for an event. 368 * These are the old interfaces to sleep waiting for an event.
369 * They are racy. DO NOT use them, use the wait_event* interfaces above. 369 * They are racy. DO NOT use them, use the wait_event* interfaces above.
370 * We plan to remove these interfaces during 2.7. 370 * We plan to remove these interfaces.
371 */ 371 */
372extern void FASTCALL(sleep_on(wait_queue_head_t *q)); 372extern void sleep_on(wait_queue_head_t *q);
373extern long FASTCALL(sleep_on_timeout(wait_queue_head_t *q, 373extern long sleep_on_timeout(wait_queue_head_t *q,
374 signed long timeout)); 374 signed long timeout);
375extern void FASTCALL(interruptible_sleep_on(wait_queue_head_t *q)); 375extern void interruptible_sleep_on(wait_queue_head_t *q);
376extern long FASTCALL(interruptible_sleep_on_timeout(wait_queue_head_t *q, 376extern long interruptible_sleep_on_timeout(wait_queue_head_t *q,
377 signed long timeout)); 377 signed long timeout);
378 378
379/* 379/*
380 * Waitqueues which are removed from the waitqueue_head at wakeup time 380 * Waitqueues which are removed from the waitqueue_head at wakeup time
diff --git a/include/net/ax88796.h b/include/net/ax88796.h
new file mode 100644
index 000000000000..ee786a043b3d
--- /dev/null
+++ b/include/net/ax88796.h
@@ -0,0 +1,27 @@
1/* include/net/ax88796.h
2 *
3 * Copyright 2005 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10*/
11
12#ifndef __NET_AX88796_PLAT_H
13#define __NET_AX88796_PLAT_H
14
15#define AXFLG_HAS_EEPROM (1<<0)
16#define AXFLG_MAC_FROMDEV (1<<1) /* device already has MAC */
17
18struct ax_plat_data {
19 unsigned int flags;
20 unsigned char wordlength; /* 1 or 2 */
21 unsigned char dcr_val; /* default value for DCR */
22 unsigned char rcr_val; /* default value for RCR */
23 unsigned char gpoc_val; /* default value for GPOC */
24 u32 *reg_offsets; /* register offsets */
25};
26
27#endif /* __NET_AX88796_PLAT_H */
diff --git a/include/pcmcia/ciscode.h b/include/pcmcia/ciscode.h
index eae7e2e84497..ad6e278ba7f2 100644
--- a/include/pcmcia/ciscode.h
+++ b/include/pcmcia/ciscode.h
@@ -126,4 +126,6 @@
126#define MANFID_POSSIO 0x030c 126#define MANFID_POSSIO 0x030c
127#define PRODID_POSSIO_GCC 0x0003 127#define PRODID_POSSIO_GCC 0x0003
128 128
129#define MANFID_NEC 0x0010
130
129#endif /* _LINUX_CISCODE_H */ 131#endif /* _LINUX_CISCODE_H */
diff --git a/init/Kconfig b/init/Kconfig
index a9e99f8328ff..d9d878a3bb46 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -686,6 +686,4 @@ config STOP_MACHINE
686 Need stop_machine() primitive. 686 Need stop_machine() primitive.
687endmenu 687endmenu
688 688
689menu "Block layer"
690source "block/Kconfig" 689source "block/Kconfig"
691endmenu
diff --git a/init/main.c b/init/main.c
index eb8bdbae4fc7..0eb1c7463fe4 100644
--- a/init/main.c
+++ b/init/main.c
@@ -436,15 +436,16 @@ static void noinline __init_refok rest_init(void)
436 436
437 /* 437 /*
438 * The boot idle thread must execute schedule() 438 * The boot idle thread must execute schedule()
439 * at least one to get things moving: 439 * at least once to get things moving:
440 */ 440 */
441 init_idle_bootup_task(current);
441 preempt_enable_no_resched(); 442 preempt_enable_no_resched();
442 schedule(); 443 schedule();
443 preempt_disable(); 444 preempt_disable();
444 445
445 /* Call into cpu_idle with preempt disabled */ 446 /* Call into cpu_idle with preempt disabled */
446 cpu_idle(); 447 cpu_idle();
447} 448}
448 449
449/* Check for early params. */ 450/* Check for early params. */
450static int __init do_early_param(char *param, char *val) 451static int __init do_early_param(char *param, char *val)
diff --git a/kernel/delayacct.c b/kernel/delayacct.c
index c0148ae992c4..81e697829633 100644
--- a/kernel/delayacct.c
+++ b/kernel/delayacct.c
@@ -99,9 +99,10 @@ void __delayacct_blkio_end(void)
99int __delayacct_add_tsk(struct taskstats *d, struct task_struct *tsk) 99int __delayacct_add_tsk(struct taskstats *d, struct task_struct *tsk)
100{ 100{
101 s64 tmp; 101 s64 tmp;
102 struct timespec ts; 102 unsigned long t1;
103 unsigned long t1,t2,t3; 103 unsigned long long t2, t3;
104 unsigned long flags; 104 unsigned long flags;
105 struct timespec ts;
105 106
106 /* Though tsk->delays accessed later, early exit avoids 107 /* Though tsk->delays accessed later, early exit avoids
107 * unnecessary returning of other data 108 * unnecessary returning of other data
@@ -124,11 +125,10 @@ int __delayacct_add_tsk(struct taskstats *d, struct task_struct *tsk)
124 125
125 d->cpu_count += t1; 126 d->cpu_count += t1;
126 127
127 jiffies_to_timespec(t2, &ts); 128 tmp = (s64)d->cpu_delay_total + t2;
128 tmp = (s64)d->cpu_delay_total + timespec_to_ns(&ts);
129 d->cpu_delay_total = (tmp < (s64)d->cpu_delay_total) ? 0 : tmp; 129 d->cpu_delay_total = (tmp < (s64)d->cpu_delay_total) ? 0 : tmp;
130 130
131 tmp = (s64)d->cpu_run_virtual_total + (s64)jiffies_to_usecs(t3) * 1000; 131 tmp = (s64)d->cpu_run_virtual_total + t3;
132 d->cpu_run_virtual_total = 132 d->cpu_run_virtual_total =
133 (tmp < (s64)d->cpu_run_virtual_total) ? 0 : tmp; 133 (tmp < (s64)d->cpu_run_virtual_total) ? 0 : tmp;
134 134
diff --git a/kernel/exit.c b/kernel/exit.c
index 5c8ecbaa19a5..ca6a11b73023 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -122,9 +122,9 @@ static void __exit_signal(struct task_struct *tsk)
122 sig->maj_flt += tsk->maj_flt; 122 sig->maj_flt += tsk->maj_flt;
123 sig->nvcsw += tsk->nvcsw; 123 sig->nvcsw += tsk->nvcsw;
124 sig->nivcsw += tsk->nivcsw; 124 sig->nivcsw += tsk->nivcsw;
125 sig->sched_time += tsk->sched_time;
126 sig->inblock += task_io_get_inblock(tsk); 125 sig->inblock += task_io_get_inblock(tsk);
127 sig->oublock += task_io_get_oublock(tsk); 126 sig->oublock += task_io_get_oublock(tsk);
127 sig->sum_sched_runtime += tsk->se.sum_exec_runtime;
128 sig = NULL; /* Marker for below. */ 128 sig = NULL; /* Marker for below. */
129 } 129 }
130 130
@@ -182,7 +182,6 @@ repeat:
182 zap_leader = (leader->exit_signal == -1); 182 zap_leader = (leader->exit_signal == -1);
183 } 183 }
184 184
185 sched_exit(p);
186 write_unlock_irq(&tasklist_lock); 185 write_unlock_irq(&tasklist_lock);
187 proc_flush_task(p); 186 proc_flush_task(p);
188 release_thread(p); 187 release_thread(p);
@@ -291,7 +290,7 @@ static void reparent_to_kthreadd(void)
291 /* Set the exit signal to SIGCHLD so we signal init on exit */ 290 /* Set the exit signal to SIGCHLD so we signal init on exit */
292 current->exit_signal = SIGCHLD; 291 current->exit_signal = SIGCHLD;
293 292
294 if (!has_rt_policy(current) && (task_nice(current) < 0)) 293 if (task_nice(current) < 0)
295 set_user_nice(current, 0); 294 set_user_nice(current, 0);
296 /* cpus_allowed? */ 295 /* cpus_allowed? */
297 /* rt_priority? */ 296 /* rt_priority? */
diff --git a/kernel/fork.c b/kernel/fork.c
index 73ad5cda1bcd..da3a155bba0d 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -877,7 +877,7 @@ static inline int copy_signal(unsigned long clone_flags, struct task_struct * ts
877 sig->nvcsw = sig->nivcsw = sig->cnvcsw = sig->cnivcsw = 0; 877 sig->nvcsw = sig->nivcsw = sig->cnvcsw = sig->cnivcsw = 0;
878 sig->min_flt = sig->maj_flt = sig->cmin_flt = sig->cmaj_flt = 0; 878 sig->min_flt = sig->maj_flt = sig->cmin_flt = sig->cmaj_flt = 0;
879 sig->inblock = sig->oublock = sig->cinblock = sig->coublock = 0; 879 sig->inblock = sig->oublock = sig->cinblock = sig->coublock = 0;
880 sig->sched_time = 0; 880 sig->sum_sched_runtime = 0;
881 INIT_LIST_HEAD(&sig->cpu_timers[0]); 881 INIT_LIST_HEAD(&sig->cpu_timers[0]);
882 INIT_LIST_HEAD(&sig->cpu_timers[1]); 882 INIT_LIST_HEAD(&sig->cpu_timers[1]);
883 INIT_LIST_HEAD(&sig->cpu_timers[2]); 883 INIT_LIST_HEAD(&sig->cpu_timers[2]);
@@ -1040,7 +1040,7 @@ static struct task_struct *copy_process(unsigned long clone_flags,
1040 1040
1041 p->utime = cputime_zero; 1041 p->utime = cputime_zero;
1042 p->stime = cputime_zero; 1042 p->stime = cputime_zero;
1043 p->sched_time = 0; 1043
1044#ifdef CONFIG_TASK_XACCT 1044#ifdef CONFIG_TASK_XACCT
1045 p->rchar = 0; /* I/O counter: bytes read */ 1045 p->rchar = 0; /* I/O counter: bytes read */
1046 p->wchar = 0; /* I/O counter: bytes written */ 1046 p->wchar = 0; /* I/O counter: bytes written */
diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c
index 1de710e18373..b53c8fcd9d82 100644
--- a/kernel/posix-cpu-timers.c
+++ b/kernel/posix-cpu-timers.c
@@ -161,7 +161,7 @@ static inline cputime_t virt_ticks(struct task_struct *p)
161} 161}
162static inline unsigned long long sched_ns(struct task_struct *p) 162static inline unsigned long long sched_ns(struct task_struct *p)
163{ 163{
164 return (p == current) ? current_sched_time(p) : p->sched_time; 164 return task_sched_runtime(p);
165} 165}
166 166
167int posix_cpu_clock_getres(const clockid_t which_clock, struct timespec *tp) 167int posix_cpu_clock_getres(const clockid_t which_clock, struct timespec *tp)
@@ -246,10 +246,10 @@ static int cpu_clock_sample_group_locked(unsigned int clock_idx,
246 } while (t != p); 246 } while (t != p);
247 break; 247 break;
248 case CPUCLOCK_SCHED: 248 case CPUCLOCK_SCHED:
249 cpu->sched = p->signal->sched_time; 249 cpu->sched = p->signal->sum_sched_runtime;
250 /* Add in each other live thread. */ 250 /* Add in each other live thread. */
251 while ((t = next_thread(t)) != p) { 251 while ((t = next_thread(t)) != p) {
252 cpu->sched += t->sched_time; 252 cpu->sched += t->se.sum_exec_runtime;
253 } 253 }
254 cpu->sched += sched_ns(p); 254 cpu->sched += sched_ns(p);
255 break; 255 break;
@@ -422,7 +422,7 @@ int posix_cpu_timer_del(struct k_itimer *timer)
422 */ 422 */
423static void cleanup_timers(struct list_head *head, 423static void cleanup_timers(struct list_head *head,
424 cputime_t utime, cputime_t stime, 424 cputime_t utime, cputime_t stime,
425 unsigned long long sched_time) 425 unsigned long long sum_exec_runtime)
426{ 426{
427 struct cpu_timer_list *timer, *next; 427 struct cpu_timer_list *timer, *next;
428 cputime_t ptime = cputime_add(utime, stime); 428 cputime_t ptime = cputime_add(utime, stime);
@@ -451,10 +451,10 @@ static void cleanup_timers(struct list_head *head,
451 ++head; 451 ++head;
452 list_for_each_entry_safe(timer, next, head, entry) { 452 list_for_each_entry_safe(timer, next, head, entry) {
453 list_del_init(&timer->entry); 453 list_del_init(&timer->entry);
454 if (timer->expires.sched < sched_time) { 454 if (timer->expires.sched < sum_exec_runtime) {
455 timer->expires.sched = 0; 455 timer->expires.sched = 0;
456 } else { 456 } else {
457 timer->expires.sched -= sched_time; 457 timer->expires.sched -= sum_exec_runtime;
458 } 458 }
459 } 459 }
460} 460}
@@ -467,7 +467,7 @@ static void cleanup_timers(struct list_head *head,
467void posix_cpu_timers_exit(struct task_struct *tsk) 467void posix_cpu_timers_exit(struct task_struct *tsk)
468{ 468{
469 cleanup_timers(tsk->cpu_timers, 469 cleanup_timers(tsk->cpu_timers,
470 tsk->utime, tsk->stime, tsk->sched_time); 470 tsk->utime, tsk->stime, tsk->se.sum_exec_runtime);
471 471
472} 472}
473void posix_cpu_timers_exit_group(struct task_struct *tsk) 473void posix_cpu_timers_exit_group(struct task_struct *tsk)
@@ -475,7 +475,7 @@ void posix_cpu_timers_exit_group(struct task_struct *tsk)
475 cleanup_timers(tsk->signal->cpu_timers, 475 cleanup_timers(tsk->signal->cpu_timers,
476 cputime_add(tsk->utime, tsk->signal->utime), 476 cputime_add(tsk->utime, tsk->signal->utime),
477 cputime_add(tsk->stime, tsk->signal->stime), 477 cputime_add(tsk->stime, tsk->signal->stime),
478 tsk->sched_time + tsk->signal->sched_time); 478 tsk->se.sum_exec_runtime + tsk->signal->sum_sched_runtime);
479} 479}
480 480
481 481
@@ -536,7 +536,7 @@ static void process_timer_rebalance(struct task_struct *p,
536 nsleft = max_t(unsigned long long, nsleft, 1); 536 nsleft = max_t(unsigned long long, nsleft, 1);
537 do { 537 do {
538 if (likely(!(t->flags & PF_EXITING))) { 538 if (likely(!(t->flags & PF_EXITING))) {
539 ns = t->sched_time + nsleft; 539 ns = t->se.sum_exec_runtime + nsleft;
540 if (t->it_sched_expires == 0 || 540 if (t->it_sched_expires == 0 ||
541 t->it_sched_expires > ns) { 541 t->it_sched_expires > ns) {
542 t->it_sched_expires = ns; 542 t->it_sched_expires = ns;
@@ -1004,7 +1004,7 @@ static void check_thread_timers(struct task_struct *tsk,
1004 struct cpu_timer_list *t = list_first_entry(timers, 1004 struct cpu_timer_list *t = list_first_entry(timers,
1005 struct cpu_timer_list, 1005 struct cpu_timer_list,
1006 entry); 1006 entry);
1007 if (!--maxfire || tsk->sched_time < t->expires.sched) { 1007 if (!--maxfire || tsk->se.sum_exec_runtime < t->expires.sched) {
1008 tsk->it_sched_expires = t->expires.sched; 1008 tsk->it_sched_expires = t->expires.sched;
1009 break; 1009 break;
1010 } 1010 }
@@ -1024,7 +1024,7 @@ static void check_process_timers(struct task_struct *tsk,
1024 int maxfire; 1024 int maxfire;
1025 struct signal_struct *const sig = tsk->signal; 1025 struct signal_struct *const sig = tsk->signal;
1026 cputime_t utime, stime, ptime, virt_expires, prof_expires; 1026 cputime_t utime, stime, ptime, virt_expires, prof_expires;
1027 unsigned long long sched_time, sched_expires; 1027 unsigned long long sum_sched_runtime, sched_expires;
1028 struct task_struct *t; 1028 struct task_struct *t;
1029 struct list_head *timers = sig->cpu_timers; 1029 struct list_head *timers = sig->cpu_timers;
1030 1030
@@ -1044,12 +1044,12 @@ static void check_process_timers(struct task_struct *tsk,
1044 */ 1044 */
1045 utime = sig->utime; 1045 utime = sig->utime;
1046 stime = sig->stime; 1046 stime = sig->stime;
1047 sched_time = sig->sched_time; 1047 sum_sched_runtime = sig->sum_sched_runtime;
1048 t = tsk; 1048 t = tsk;
1049 do { 1049 do {
1050 utime = cputime_add(utime, t->utime); 1050 utime = cputime_add(utime, t->utime);
1051 stime = cputime_add(stime, t->stime); 1051 stime = cputime_add(stime, t->stime);
1052 sched_time += t->sched_time; 1052 sum_sched_runtime += t->se.sum_exec_runtime;
1053 t = next_thread(t); 1053 t = next_thread(t);
1054 } while (t != tsk); 1054 } while (t != tsk);
1055 ptime = cputime_add(utime, stime); 1055 ptime = cputime_add(utime, stime);
@@ -1090,7 +1090,7 @@ static void check_process_timers(struct task_struct *tsk,
1090 struct cpu_timer_list *t = list_first_entry(timers, 1090 struct cpu_timer_list *t = list_first_entry(timers,
1091 struct cpu_timer_list, 1091 struct cpu_timer_list,
1092 entry); 1092 entry);
1093 if (!--maxfire || sched_time < t->expires.sched) { 1093 if (!--maxfire || sum_sched_runtime < t->expires.sched) {
1094 sched_expires = t->expires.sched; 1094 sched_expires = t->expires.sched;
1095 break; 1095 break;
1096 } 1096 }
@@ -1182,7 +1182,7 @@ static void check_process_timers(struct task_struct *tsk,
1182 virt_left = cputime_sub(virt_expires, utime); 1182 virt_left = cputime_sub(virt_expires, utime);
1183 virt_left = cputime_div_non_zero(virt_left, nthreads); 1183 virt_left = cputime_div_non_zero(virt_left, nthreads);
1184 if (sched_expires) { 1184 if (sched_expires) {
1185 sched_left = sched_expires - sched_time; 1185 sched_left = sched_expires - sum_sched_runtime;
1186 do_div(sched_left, nthreads); 1186 do_div(sched_left, nthreads);
1187 sched_left = max_t(unsigned long long, sched_left, 1); 1187 sched_left = max_t(unsigned long long, sched_left, 1);
1188 } else { 1188 } else {
@@ -1208,7 +1208,7 @@ static void check_process_timers(struct task_struct *tsk,
1208 t->it_virt_expires = ticks; 1208 t->it_virt_expires = ticks;
1209 } 1209 }
1210 1210
1211 sched = t->sched_time + sched_left; 1211 sched = t->se.sum_exec_runtime + sched_left;
1212 if (sched_expires && (t->it_sched_expires == 0 || 1212 if (sched_expires && (t->it_sched_expires == 0 ||
1213 t->it_sched_expires > sched)) { 1213 t->it_sched_expires > sched)) {
1214 t->it_sched_expires = sched; 1214 t->it_sched_expires = sched;
@@ -1300,7 +1300,7 @@ void run_posix_cpu_timers(struct task_struct *tsk)
1300 1300
1301 if (UNEXPIRED(prof) && UNEXPIRED(virt) && 1301 if (UNEXPIRED(prof) && UNEXPIRED(virt) &&
1302 (tsk->it_sched_expires == 0 || 1302 (tsk->it_sched_expires == 0 ||
1303 tsk->sched_time < tsk->it_sched_expires)) 1303 tsk->se.sum_exec_runtime < tsk->it_sched_expires))
1304 return; 1304 return;
1305 1305
1306#undef UNEXPIRED 1306#undef UNEXPIRED
diff --git a/kernel/relay.c b/kernel/relay.c
index 95db8c79fe8f..3b299fb3855c 100644
--- a/kernel/relay.c
+++ b/kernel/relay.c
@@ -21,6 +21,7 @@
21#include <linux/vmalloc.h> 21#include <linux/vmalloc.h>
22#include <linux/mm.h> 22#include <linux/mm.h>
23#include <linux/cpu.h> 23#include <linux/cpu.h>
24#include <linux/splice.h>
24 25
25/* list of open channels, for cpu hotplug */ 26/* list of open channels, for cpu hotplug */
26static DEFINE_MUTEX(relay_channels_mutex); 27static DEFINE_MUTEX(relay_channels_mutex);
@@ -121,6 +122,7 @@ static void *relay_alloc_buf(struct rchan_buf *buf, size_t *size)
121 buf->page_array[i] = alloc_page(GFP_KERNEL); 122 buf->page_array[i] = alloc_page(GFP_KERNEL);
122 if (unlikely(!buf->page_array[i])) 123 if (unlikely(!buf->page_array[i]))
123 goto depopulate; 124 goto depopulate;
125 set_page_private(buf->page_array[i], (unsigned long)buf);
124 } 126 }
125 mem = vmap(buf->page_array, n_pages, VM_MAP, PAGE_KERNEL); 127 mem = vmap(buf->page_array, n_pages, VM_MAP, PAGE_KERNEL);
126 if (!mem) 128 if (!mem)
@@ -970,43 +972,6 @@ static int subbuf_read_actor(size_t read_start,
970 return ret; 972 return ret;
971} 973}
972 974
973/*
974 * subbuf_send_actor - send up to one subbuf's worth of data
975 */
976static int subbuf_send_actor(size_t read_start,
977 struct rchan_buf *buf,
978 size_t avail,
979 read_descriptor_t *desc,
980 read_actor_t actor)
981{
982 unsigned long pidx, poff;
983 unsigned int subbuf_pages;
984 int ret = 0;
985
986 subbuf_pages = buf->chan->alloc_size >> PAGE_SHIFT;
987 pidx = (read_start / PAGE_SIZE) % subbuf_pages;
988 poff = read_start & ~PAGE_MASK;
989 while (avail) {
990 struct page *p = buf->page_array[pidx];
991 unsigned int len;
992
993 len = PAGE_SIZE - poff;
994 if (len > avail)
995 len = avail;
996
997 len = actor(desc, p, poff, len);
998 if (desc->error)
999 break;
1000
1001 avail -= len;
1002 ret += len;
1003 poff = 0;
1004 pidx = (pidx + 1) % subbuf_pages;
1005 }
1006
1007 return ret;
1008}
1009
1010typedef int (*subbuf_actor_t) (size_t read_start, 975typedef int (*subbuf_actor_t) (size_t read_start,
1011 struct rchan_buf *buf, 976 struct rchan_buf *buf,
1012 size_t avail, 977 size_t avail,
@@ -1067,19 +1032,159 @@ static ssize_t relay_file_read(struct file *filp,
1067 NULL, &desc); 1032 NULL, &desc);
1068} 1033}
1069 1034
1070static ssize_t relay_file_sendfile(struct file *filp, 1035static void relay_consume_bytes(struct rchan_buf *rbuf, int bytes_consumed)
1071 loff_t *ppos,
1072 size_t count,
1073 read_actor_t actor,
1074 void *target)
1075{ 1036{
1076 read_descriptor_t desc; 1037 rbuf->bytes_consumed += bytes_consumed;
1077 desc.written = 0; 1038
1078 desc.count = count; 1039 if (rbuf->bytes_consumed >= rbuf->chan->subbuf_size) {
1079 desc.arg.data = target; 1040 relay_subbufs_consumed(rbuf->chan, rbuf->cpu, 1);
1080 desc.error = 0; 1041 rbuf->bytes_consumed %= rbuf->chan->subbuf_size;
1081 return relay_file_read_subbufs(filp, ppos, subbuf_send_actor, 1042 }
1082 actor, &desc); 1043}
1044
1045static void relay_pipe_buf_release(struct pipe_inode_info *pipe,
1046 struct pipe_buffer *buf)
1047{
1048 struct rchan_buf *rbuf;
1049
1050 rbuf = (struct rchan_buf *)page_private(buf->page);
1051 relay_consume_bytes(rbuf, buf->private);
1052}
1053
1054static struct pipe_buf_operations relay_pipe_buf_ops = {
1055 .can_merge = 0,
1056 .map = generic_pipe_buf_map,
1057 .unmap = generic_pipe_buf_unmap,
1058 .confirm = generic_pipe_buf_confirm,
1059 .release = relay_pipe_buf_release,
1060 .steal = generic_pipe_buf_steal,
1061 .get = generic_pipe_buf_get,
1062};
1063
1064/**
1065 * subbuf_splice_actor - splice up to one subbuf's worth of data
1066 */
1067static int subbuf_splice_actor(struct file *in,
1068 loff_t *ppos,
1069 struct pipe_inode_info *pipe,
1070 size_t len,
1071 unsigned int flags,
1072 int *nonpad_ret)
1073{
1074 unsigned int pidx, poff, total_len, subbuf_pages, ret;
1075 struct rchan_buf *rbuf = in->private_data;
1076 unsigned int subbuf_size = rbuf->chan->subbuf_size;
1077 size_t read_start = ((size_t)*ppos) % rbuf->chan->alloc_size;
1078 size_t read_subbuf = read_start / subbuf_size;
1079 size_t padding = rbuf->padding[read_subbuf];
1080 size_t nonpad_end = read_subbuf * subbuf_size + subbuf_size - padding;
1081 struct page *pages[PIPE_BUFFERS];
1082 struct partial_page partial[PIPE_BUFFERS];
1083 struct splice_pipe_desc spd = {
1084 .pages = pages,
1085 .nr_pages = 0,
1086 .partial = partial,
1087 .flags = flags,
1088 .ops = &relay_pipe_buf_ops,
1089 };
1090
1091 if (rbuf->subbufs_produced == rbuf->subbufs_consumed)
1092 return 0;
1093
1094 /*
1095 * Adjust read len, if longer than what is available
1096 */
1097 if (len > (subbuf_size - read_start % subbuf_size))
1098 len = subbuf_size - read_start % subbuf_size;
1099
1100 subbuf_pages = rbuf->chan->alloc_size >> PAGE_SHIFT;
1101 pidx = (read_start / PAGE_SIZE) % subbuf_pages;
1102 poff = read_start & ~PAGE_MASK;
1103
1104 for (total_len = 0; spd.nr_pages < subbuf_pages; spd.nr_pages++) {
1105 unsigned int this_len, this_end, private;
1106 unsigned int cur_pos = read_start + total_len;
1107
1108 if (!len)
1109 break;
1110
1111 this_len = min_t(unsigned long, len, PAGE_SIZE - poff);
1112 private = this_len;
1113
1114 spd.pages[spd.nr_pages] = rbuf->page_array[pidx];
1115 spd.partial[spd.nr_pages].offset = poff;
1116
1117 this_end = cur_pos + this_len;
1118 if (this_end >= nonpad_end) {
1119 this_len = nonpad_end - cur_pos;
1120 private = this_len + padding;
1121 }
1122 spd.partial[spd.nr_pages].len = this_len;
1123 spd.partial[spd.nr_pages].private = private;
1124
1125 len -= this_len;
1126 total_len += this_len;
1127 poff = 0;
1128 pidx = (pidx + 1) % subbuf_pages;
1129
1130 if (this_end >= nonpad_end) {
1131 spd.nr_pages++;
1132 break;
1133 }
1134 }
1135
1136 if (!spd.nr_pages)
1137 return 0;
1138
1139 ret = *nonpad_ret = splice_to_pipe(pipe, &spd);
1140 if (ret < 0 || ret < total_len)
1141 return ret;
1142
1143 if (read_start + ret == nonpad_end)
1144 ret += padding;
1145
1146 return ret;
1147}
1148
1149static ssize_t relay_file_splice_read(struct file *in,
1150 loff_t *ppos,
1151 struct pipe_inode_info *pipe,
1152 size_t len,
1153 unsigned int flags)
1154{
1155 ssize_t spliced;
1156 int ret;
1157 int nonpad_ret = 0;
1158
1159 ret = 0;
1160 spliced = 0;
1161
1162 while (len) {
1163 ret = subbuf_splice_actor(in, ppos, pipe, len, flags, &nonpad_ret);
1164 if (ret < 0)
1165 break;
1166 else if (!ret) {
1167 if (spliced)
1168 break;
1169 if (flags & SPLICE_F_NONBLOCK) {
1170 ret = -EAGAIN;
1171 break;
1172 }
1173 }
1174
1175 *ppos += ret;
1176 if (ret > len)
1177 len = 0;
1178 else
1179 len -= ret;
1180 spliced += nonpad_ret;
1181 nonpad_ret = 0;
1182 }
1183
1184 if (spliced)
1185 return spliced;
1186
1187 return ret;
1083} 1188}
1084 1189
1085const struct file_operations relay_file_operations = { 1190const struct file_operations relay_file_operations = {
@@ -1089,7 +1194,7 @@ const struct file_operations relay_file_operations = {
1089 .read = relay_file_read, 1194 .read = relay_file_read,
1090 .llseek = no_llseek, 1195 .llseek = no_llseek,
1091 .release = relay_file_release, 1196 .release = relay_file_release,
1092 .sendfile = relay_file_sendfile, 1197 .splice_read = relay_file_splice_read,
1093}; 1198};
1094EXPORT_SYMBOL_GPL(relay_file_operations); 1199EXPORT_SYMBOL_GPL(relay_file_operations);
1095 1200
diff --git a/kernel/sched.c b/kernel/sched.c
index 50e1a3122699..9fbced64bfee 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -16,13 +16,19 @@
16 * by Davide Libenzi, preemptible kernel bits by Robert Love. 16 * by Davide Libenzi, preemptible kernel bits by Robert Love.
17 * 2003-09-03 Interactivity tuning by Con Kolivas. 17 * 2003-09-03 Interactivity tuning by Con Kolivas.
18 * 2004-04-02 Scheduler domains code by Nick Piggin 18 * 2004-04-02 Scheduler domains code by Nick Piggin
19 * 2007-04-15 Work begun on replacing all interactivity tuning with a
20 * fair scheduling design by Con Kolivas.
21 * 2007-05-05 Load balancing (smp-nice) and other improvements
22 * by Peter Williams
23 * 2007-05-06 Interactivity improvements to CFS by Mike Galbraith
24 * 2007-07-01 Group scheduling enhancements by Srivatsa Vaddagiri
19 */ 25 */
20 26
21#include <linux/mm.h> 27#include <linux/mm.h>
22#include <linux/module.h> 28#include <linux/module.h>
23#include <linux/nmi.h> 29#include <linux/nmi.h>
24#include <linux/init.h> 30#include <linux/init.h>
25#include <asm/uaccess.h> 31#include <linux/uaccess.h>
26#include <linux/highmem.h> 32#include <linux/highmem.h>
27#include <linux/smp_lock.h> 33#include <linux/smp_lock.h>
28#include <asm/mmu_context.h> 34#include <asm/mmu_context.h>
@@ -53,9 +59,9 @@
53#include <linux/kprobes.h> 59#include <linux/kprobes.h>
54#include <linux/delayacct.h> 60#include <linux/delayacct.h>
55#include <linux/reciprocal_div.h> 61#include <linux/reciprocal_div.h>
62#include <linux/unistd.h>
56 63
57#include <asm/tlb.h> 64#include <asm/tlb.h>
58#include <asm/unistd.h>
59 65
60/* 66/*
61 * Scheduler clock - returns current time in nanosec units. 67 * Scheduler clock - returns current time in nanosec units.
@@ -91,6 +97,9 @@ unsigned long long __attribute__((weak)) sched_clock(void)
91#define NS_TO_JIFFIES(TIME) ((TIME) / (1000000000 / HZ)) 97#define NS_TO_JIFFIES(TIME) ((TIME) / (1000000000 / HZ))
92#define JIFFIES_TO_NS(TIME) ((TIME) * (1000000000 / HZ)) 98#define JIFFIES_TO_NS(TIME) ((TIME) * (1000000000 / HZ))
93 99
100#define NICE_0_LOAD SCHED_LOAD_SCALE
101#define NICE_0_SHIFT SCHED_LOAD_SHIFT
102
94/* 103/*
95 * These are the 'tuning knobs' of the scheduler: 104 * These are the 'tuning knobs' of the scheduler:
96 * 105 *
@@ -100,87 +109,6 @@ unsigned long long __attribute__((weak)) sched_clock(void)
100 */ 109 */
101#define MIN_TIMESLICE max(5 * HZ / 1000, 1) 110#define MIN_TIMESLICE max(5 * HZ / 1000, 1)
102#define DEF_TIMESLICE (100 * HZ / 1000) 111#define DEF_TIMESLICE (100 * HZ / 1000)
103#define ON_RUNQUEUE_WEIGHT 30
104#define CHILD_PENALTY 95
105#define PARENT_PENALTY 100
106#define EXIT_WEIGHT 3
107#define PRIO_BONUS_RATIO 25
108#define MAX_BONUS (MAX_USER_PRIO * PRIO_BONUS_RATIO / 100)
109#define INTERACTIVE_DELTA 2
110#define MAX_SLEEP_AVG (DEF_TIMESLICE * MAX_BONUS)
111#define STARVATION_LIMIT (MAX_SLEEP_AVG)
112#define NS_MAX_SLEEP_AVG (JIFFIES_TO_NS(MAX_SLEEP_AVG))
113
114/*
115 * If a task is 'interactive' then we reinsert it in the active
116 * array after it has expired its current timeslice. (it will not
117 * continue to run immediately, it will still roundrobin with
118 * other interactive tasks.)
119 *
120 * This part scales the interactivity limit depending on niceness.
121 *
122 * We scale it linearly, offset by the INTERACTIVE_DELTA delta.
123 * Here are a few examples of different nice levels:
124 *
125 * TASK_INTERACTIVE(-20): [1,1,1,1,1,1,1,1,1,0,0]
126 * TASK_INTERACTIVE(-10): [1,1,1,1,1,1,1,0,0,0,0]
127 * TASK_INTERACTIVE( 0): [1,1,1,1,0,0,0,0,0,0,0]
128 * TASK_INTERACTIVE( 10): [1,1,0,0,0,0,0,0,0,0,0]
129 * TASK_INTERACTIVE( 19): [0,0,0,0,0,0,0,0,0,0,0]
130 *
131 * (the X axis represents the possible -5 ... 0 ... +5 dynamic
132 * priority range a task can explore, a value of '1' means the
133 * task is rated interactive.)
134 *
135 * Ie. nice +19 tasks can never get 'interactive' enough to be
136 * reinserted into the active array. And only heavily CPU-hog nice -20
137 * tasks will be expired. Default nice 0 tasks are somewhere between,
138 * it takes some effort for them to get interactive, but it's not
139 * too hard.
140 */
141
142#define CURRENT_BONUS(p) \
143 (NS_TO_JIFFIES((p)->sleep_avg) * MAX_BONUS / \
144 MAX_SLEEP_AVG)
145
146#define GRANULARITY (10 * HZ / 1000 ? : 1)
147
148#ifdef CONFIG_SMP
149#define TIMESLICE_GRANULARITY(p) (GRANULARITY * \
150 (1 << (((MAX_BONUS - CURRENT_BONUS(p)) ? : 1) - 1)) * \
151 num_online_cpus())
152#else
153#define TIMESLICE_GRANULARITY(p) (GRANULARITY * \
154 (1 << (((MAX_BONUS - CURRENT_BONUS(p)) ? : 1) - 1)))
155#endif
156
157#define SCALE(v1,v1_max,v2_max) \
158 (v1) * (v2_max) / (v1_max)
159
160#define DELTA(p) \
161 (SCALE(TASK_NICE(p) + 20, 40, MAX_BONUS) - 20 * MAX_BONUS / 40 + \
162 INTERACTIVE_DELTA)
163
164#define TASK_INTERACTIVE(p) \
165 ((p)->prio <= (p)->static_prio - DELTA(p))
166
167#define INTERACTIVE_SLEEP(p) \
168 (JIFFIES_TO_NS(MAX_SLEEP_AVG * \
169 (MAX_BONUS / 2 + DELTA((p)) + 1) / MAX_BONUS - 1))
170
171#define TASK_PREEMPTS_CURR(p, rq) \
172 ((p)->prio < (rq)->curr->prio)
173
174#define SCALE_PRIO(x, prio) \
175 max(x * (MAX_PRIO - prio) / (MAX_USER_PRIO / 2), MIN_TIMESLICE)
176
177static unsigned int static_prio_timeslice(int static_prio)
178{
179 if (static_prio < NICE_TO_PRIO(0))
180 return SCALE_PRIO(DEF_TIMESLICE * 4, static_prio);
181 else
182 return SCALE_PRIO(DEF_TIMESLICE, static_prio);
183}
184 112
185#ifdef CONFIG_SMP 113#ifdef CONFIG_SMP
186/* 114/*
@@ -203,28 +131,87 @@ static inline void sg_inc_cpu_power(struct sched_group *sg, u32 val)
203} 131}
204#endif 132#endif
205 133
134#define SCALE_PRIO(x, prio) \
135 max(x * (MAX_PRIO - prio) / (MAX_USER_PRIO / 2), MIN_TIMESLICE)
136
206/* 137/*
207 * task_timeslice() scales user-nice values [ -20 ... 0 ... 19 ] 138 * static_prio_timeslice() scales user-nice values [ -20 ... 0 ... 19 ]
208 * to time slice values: [800ms ... 100ms ... 5ms] 139 * to time slice values: [800ms ... 100ms ... 5ms]
209 *
210 * The higher a thread's priority, the bigger timeslices
211 * it gets during one round of execution. But even the lowest
212 * priority thread gets MIN_TIMESLICE worth of execution time.
213 */ 140 */
141static unsigned int static_prio_timeslice(int static_prio)
142{
143 if (static_prio == NICE_TO_PRIO(19))
144 return 1;
145
146 if (static_prio < NICE_TO_PRIO(0))
147 return SCALE_PRIO(DEF_TIMESLICE * 4, static_prio);
148 else
149 return SCALE_PRIO(DEF_TIMESLICE, static_prio);
150}
151
152static inline int rt_policy(int policy)
153{
154 if (unlikely(policy == SCHED_FIFO) || unlikely(policy == SCHED_RR))
155 return 1;
156 return 0;
157}
214 158
215static inline unsigned int task_timeslice(struct task_struct *p) 159static inline int task_has_rt_policy(struct task_struct *p)
216{ 160{
217 return static_prio_timeslice(p->static_prio); 161 return rt_policy(p->policy);
218} 162}
219 163
220/* 164/*
221 * These are the runqueue data structures: 165 * This is the priority-queue data structure of the RT scheduling class:
222 */ 166 */
167struct rt_prio_array {
168 DECLARE_BITMAP(bitmap, MAX_RT_PRIO+1); /* include 1 bit for delimiter */
169 struct list_head queue[MAX_RT_PRIO];
170};
171
172struct load_stat {
173 struct load_weight load;
174 u64 load_update_start, load_update_last;
175 unsigned long delta_fair, delta_exec, delta_stat;
176};
177
178/* CFS-related fields in a runqueue */
179struct cfs_rq {
180 struct load_weight load;
181 unsigned long nr_running;
182
183 s64 fair_clock;
184 u64 exec_clock;
185 s64 wait_runtime;
186 u64 sleeper_bonus;
187 unsigned long wait_runtime_overruns, wait_runtime_underruns;
188
189 struct rb_root tasks_timeline;
190 struct rb_node *rb_leftmost;
191 struct rb_node *rb_load_balance_curr;
192#ifdef CONFIG_FAIR_GROUP_SCHED
193 /* 'curr' points to currently running entity on this cfs_rq.
194 * It is set to NULL otherwise (i.e when none are currently running).
195 */
196 struct sched_entity *curr;
197 struct rq *rq; /* cpu runqueue to which this cfs_rq is attached */
223 198
224struct prio_array { 199 /* leaf cfs_rqs are those that hold tasks (lowest schedulable entity in
225 unsigned int nr_active; 200 * a hierarchy). Non-leaf lrqs hold other higher schedulable entities
226 DECLARE_BITMAP(bitmap, MAX_PRIO+1); /* include 1 bit for delimiter */ 201 * (like users, containers etc.)
227 struct list_head queue[MAX_PRIO]; 202 *
203 * leaf_cfs_rq_list ties together list of leaf cfs_rq's in a cpu. This
204 * list is used during load balance.
205 */
206 struct list_head leaf_cfs_rq_list; /* Better name : task_cfs_rq_list? */
207#endif
208};
209
210/* Real-Time classes' related field in a runqueue: */
211struct rt_rq {
212 struct rt_prio_array active;
213 int rt_load_balance_idx;
214 struct list_head *rt_load_balance_head, *rt_load_balance_curr;
228}; 215};
229 216
230/* 217/*
@@ -235,22 +222,28 @@ struct prio_array {
235 * acquire operations must be ordered by ascending &runqueue. 222 * acquire operations must be ordered by ascending &runqueue.
236 */ 223 */
237struct rq { 224struct rq {
238 spinlock_t lock; 225 spinlock_t lock; /* runqueue lock */
239 226
240 /* 227 /*
241 * nr_running and cpu_load should be in the same cacheline because 228 * nr_running and cpu_load should be in the same cacheline because
242 * remote CPUs use both these fields when doing load calculation. 229 * remote CPUs use both these fields when doing load calculation.
243 */ 230 */
244 unsigned long nr_running; 231 unsigned long nr_running;
245 unsigned long raw_weighted_load; 232 #define CPU_LOAD_IDX_MAX 5
246#ifdef CONFIG_SMP 233 unsigned long cpu_load[CPU_LOAD_IDX_MAX];
247 unsigned long cpu_load[3];
248 unsigned char idle_at_tick; 234 unsigned char idle_at_tick;
249#ifdef CONFIG_NO_HZ 235#ifdef CONFIG_NO_HZ
250 unsigned char in_nohz_recently; 236 unsigned char in_nohz_recently;
251#endif 237#endif
238 struct load_stat ls; /* capture load from *all* tasks on this cpu */
239 unsigned long nr_load_updates;
240 u64 nr_switches;
241
242 struct cfs_rq cfs;
243#ifdef CONFIG_FAIR_GROUP_SCHED
244 struct list_head leaf_cfs_rq_list; /* list of leaf cfs_rq on this cpu */
252#endif 245#endif
253 unsigned long long nr_switches; 246 struct rt_rq rt;
254 247
255 /* 248 /*
256 * This is part of a global counter where only the total sum 249 * This is part of a global counter where only the total sum
@@ -260,14 +253,18 @@ struct rq {
260 */ 253 */
261 unsigned long nr_uninterruptible; 254 unsigned long nr_uninterruptible;
262 255
263 unsigned long expired_timestamp;
264 /* Cached timestamp set by update_cpu_clock() */
265 unsigned long long most_recent_timestamp;
266 struct task_struct *curr, *idle; 256 struct task_struct *curr, *idle;
267 unsigned long next_balance; 257 unsigned long next_balance;
268 struct mm_struct *prev_mm; 258 struct mm_struct *prev_mm;
269 struct prio_array *active, *expired, arrays[2]; 259
270 int best_expired_prio; 260 u64 clock, prev_clock_raw;
261 s64 clock_max_delta;
262
263 unsigned int clock_warps, clock_overflows;
264 unsigned int clock_unstable_events;
265
266 struct sched_class *load_balance_class;
267
271 atomic_t nr_iowait; 268 atomic_t nr_iowait;
272 269
273#ifdef CONFIG_SMP 270#ifdef CONFIG_SMP
@@ -307,6 +304,11 @@ struct rq {
307static DEFINE_PER_CPU(struct rq, runqueues) ____cacheline_aligned_in_smp; 304static DEFINE_PER_CPU(struct rq, runqueues) ____cacheline_aligned_in_smp;
308static DEFINE_MUTEX(sched_hotcpu_mutex); 305static DEFINE_MUTEX(sched_hotcpu_mutex);
309 306
307static inline void check_preempt_curr(struct rq *rq, struct task_struct *p)
308{
309 rq->curr->sched_class->check_preempt_curr(rq, p);
310}
311
310static inline int cpu_of(struct rq *rq) 312static inline int cpu_of(struct rq *rq)
311{ 313{
312#ifdef CONFIG_SMP 314#ifdef CONFIG_SMP
@@ -317,6 +319,52 @@ static inline int cpu_of(struct rq *rq)
317} 319}
318 320
319/* 321/*
322 * Per-runqueue clock, as finegrained as the platform can give us:
323 */
324static unsigned long long __rq_clock(struct rq *rq)
325{
326 u64 prev_raw = rq->prev_clock_raw;
327 u64 now = sched_clock();
328 s64 delta = now - prev_raw;
329 u64 clock = rq->clock;
330
331 /*
332 * Protect against sched_clock() occasionally going backwards:
333 */
334 if (unlikely(delta < 0)) {
335 clock++;
336 rq->clock_warps++;
337 } else {
338 /*
339 * Catch too large forward jumps too:
340 */
341 if (unlikely(delta > 2*TICK_NSEC)) {
342 clock++;
343 rq->clock_overflows++;
344 } else {
345 if (unlikely(delta > rq->clock_max_delta))
346 rq->clock_max_delta = delta;
347 clock += delta;
348 }
349 }
350
351 rq->prev_clock_raw = now;
352 rq->clock = clock;
353
354 return clock;
355}
356
357static inline unsigned long long rq_clock(struct rq *rq)
358{
359 int this_cpu = smp_processor_id();
360
361 if (this_cpu == cpu_of(rq))
362 return __rq_clock(rq);
363
364 return rq->clock;
365}
366
367/*
320 * The domain tree (rq->sd) is protected by RCU's quiescent state transition. 368 * The domain tree (rq->sd) is protected by RCU's quiescent state transition.
321 * See detach_destroy_domains: synchronize_sched for details. 369 * See detach_destroy_domains: synchronize_sched for details.
322 * 370 *
@@ -331,6 +379,18 @@ static inline int cpu_of(struct rq *rq)
331#define task_rq(p) cpu_rq(task_cpu(p)) 379#define task_rq(p) cpu_rq(task_cpu(p))
332#define cpu_curr(cpu) (cpu_rq(cpu)->curr) 380#define cpu_curr(cpu) (cpu_rq(cpu)->curr)
333 381
382#ifdef CONFIG_FAIR_GROUP_SCHED
383/* Change a task's ->cfs_rq if it moves across CPUs */
384static inline void set_task_cfs_rq(struct task_struct *p)
385{
386 p->se.cfs_rq = &task_rq(p)->cfs;
387}
388#else
389static inline void set_task_cfs_rq(struct task_struct *p)
390{
391}
392#endif
393
334#ifndef prepare_arch_switch 394#ifndef prepare_arch_switch
335# define prepare_arch_switch(next) do { } while (0) 395# define prepare_arch_switch(next) do { } while (0)
336#endif 396#endif
@@ -460,134 +520,6 @@ static inline void task_rq_unlock(struct rq *rq, unsigned long *flags)
460 spin_unlock_irqrestore(&rq->lock, *flags); 520 spin_unlock_irqrestore(&rq->lock, *flags);
461} 521}
462 522
463#ifdef CONFIG_SCHEDSTATS
464/*
465 * bump this up when changing the output format or the meaning of an existing
466 * format, so that tools can adapt (or abort)
467 */
468#define SCHEDSTAT_VERSION 14
469
470static int show_schedstat(struct seq_file *seq, void *v)
471{
472 int cpu;
473
474 seq_printf(seq, "version %d\n", SCHEDSTAT_VERSION);
475 seq_printf(seq, "timestamp %lu\n", jiffies);
476 for_each_online_cpu(cpu) {
477 struct rq *rq = cpu_rq(cpu);
478#ifdef CONFIG_SMP
479 struct sched_domain *sd;
480 int dcnt = 0;
481#endif
482
483 /* runqueue-specific stats */
484 seq_printf(seq,
485 "cpu%d %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu",
486 cpu, rq->yld_both_empty,
487 rq->yld_act_empty, rq->yld_exp_empty, rq->yld_cnt,
488 rq->sched_switch, rq->sched_cnt, rq->sched_goidle,
489 rq->ttwu_cnt, rq->ttwu_local,
490 rq->rq_sched_info.cpu_time,
491 rq->rq_sched_info.run_delay, rq->rq_sched_info.pcnt);
492
493 seq_printf(seq, "\n");
494
495#ifdef CONFIG_SMP
496 /* domain-specific stats */
497 preempt_disable();
498 for_each_domain(cpu, sd) {
499 enum idle_type itype;
500 char mask_str[NR_CPUS];
501
502 cpumask_scnprintf(mask_str, NR_CPUS, sd->span);
503 seq_printf(seq, "domain%d %s", dcnt++, mask_str);
504 for (itype = SCHED_IDLE; itype < MAX_IDLE_TYPES;
505 itype++) {
506 seq_printf(seq, " %lu %lu %lu %lu %lu %lu %lu "
507 "%lu",
508 sd->lb_cnt[itype],
509 sd->lb_balanced[itype],
510 sd->lb_failed[itype],
511 sd->lb_imbalance[itype],
512 sd->lb_gained[itype],
513 sd->lb_hot_gained[itype],
514 sd->lb_nobusyq[itype],
515 sd->lb_nobusyg[itype]);
516 }
517 seq_printf(seq, " %lu %lu %lu %lu %lu %lu %lu %lu %lu"
518 " %lu %lu %lu\n",
519 sd->alb_cnt, sd->alb_failed, sd->alb_pushed,
520 sd->sbe_cnt, sd->sbe_balanced, sd->sbe_pushed,
521 sd->sbf_cnt, sd->sbf_balanced, sd->sbf_pushed,
522 sd->ttwu_wake_remote, sd->ttwu_move_affine,
523 sd->ttwu_move_balance);
524 }
525 preempt_enable();
526#endif
527 }
528 return 0;
529}
530
531static int schedstat_open(struct inode *inode, struct file *file)
532{
533 unsigned int size = PAGE_SIZE * (1 + num_online_cpus() / 32);
534 char *buf = kmalloc(size, GFP_KERNEL);
535 struct seq_file *m;
536 int res;
537
538 if (!buf)
539 return -ENOMEM;
540 res = single_open(file, show_schedstat, NULL);
541 if (!res) {
542 m = file->private_data;
543 m->buf = buf;
544 m->size = size;
545 } else
546 kfree(buf);
547 return res;
548}
549
550const struct file_operations proc_schedstat_operations = {
551 .open = schedstat_open,
552 .read = seq_read,
553 .llseek = seq_lseek,
554 .release = single_release,
555};
556
557/*
558 * Expects runqueue lock to be held for atomicity of update
559 */
560static inline void
561rq_sched_info_arrive(struct rq *rq, unsigned long delta_jiffies)
562{
563 if (rq) {
564 rq->rq_sched_info.run_delay += delta_jiffies;
565 rq->rq_sched_info.pcnt++;
566 }
567}
568
569/*
570 * Expects runqueue lock to be held for atomicity of update
571 */
572static inline void
573rq_sched_info_depart(struct rq *rq, unsigned long delta_jiffies)
574{
575 if (rq)
576 rq->rq_sched_info.cpu_time += delta_jiffies;
577}
578# define schedstat_inc(rq, field) do { (rq)->field++; } while (0)
579# define schedstat_add(rq, field, amt) do { (rq)->field += (amt); } while (0)
580#else /* !CONFIG_SCHEDSTATS */
581static inline void
582rq_sched_info_arrive(struct rq *rq, unsigned long delta_jiffies)
583{}
584static inline void
585rq_sched_info_depart(struct rq *rq, unsigned long delta_jiffies)
586{}
587# define schedstat_inc(rq, field) do { } while (0)
588# define schedstat_add(rq, field, amt) do { } while (0)
589#endif
590
591/* 523/*
592 * this_rq_lock - lock this runqueue and disable interrupts. 524 * this_rq_lock - lock this runqueue and disable interrupts.
593 */ 525 */
@@ -603,177 +535,172 @@ static inline struct rq *this_rq_lock(void)
603 return rq; 535 return rq;
604} 536}
605 537
606#if defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT)
607/* 538/*
608 * Called when a process is dequeued from the active array and given 539 * CPU frequency is/was unstable - start new by setting prev_clock_raw:
609 * the cpu. We should note that with the exception of interactive
610 * tasks, the expired queue will become the active queue after the active
611 * queue is empty, without explicitly dequeuing and requeuing tasks in the
612 * expired queue. (Interactive tasks may be requeued directly to the
613 * active queue, thus delaying tasks in the expired queue from running;
614 * see scheduler_tick()).
615 *
616 * This function is only called from sched_info_arrive(), rather than
617 * dequeue_task(). Even though a task may be queued and dequeued multiple
618 * times as it is shuffled about, we're really interested in knowing how
619 * long it was from the *first* time it was queued to the time that it
620 * finally hit a cpu.
621 */ 540 */
622static inline void sched_info_dequeued(struct task_struct *t) 541void sched_clock_unstable_event(void)
623{ 542{
624 t->sched_info.last_queued = 0; 543 unsigned long flags;
544 struct rq *rq;
545
546 rq = task_rq_lock(current, &flags);
547 rq->prev_clock_raw = sched_clock();
548 rq->clock_unstable_events++;
549 task_rq_unlock(rq, &flags);
625} 550}
626 551
627/* 552/*
628 * Called when a task finally hits the cpu. We can now calculate how 553 * resched_task - mark a task 'to be rescheduled now'.
629 * long it was waiting to run. We also note when it began so that we 554 *
630 * can keep stats on how long its timeslice is. 555 * On UP this means the setting of the need_resched flag, on SMP it
556 * might also involve a cross-CPU call to trigger the scheduler on
557 * the target CPU.
631 */ 558 */
632static void sched_info_arrive(struct task_struct *t) 559#ifdef CONFIG_SMP
560
561#ifndef tsk_is_polling
562#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG)
563#endif
564
565static void resched_task(struct task_struct *p)
633{ 566{
634 unsigned long now = jiffies, delta_jiffies = 0; 567 int cpu;
568
569 assert_spin_locked(&task_rq(p)->lock);
570
571 if (unlikely(test_tsk_thread_flag(p, TIF_NEED_RESCHED)))
572 return;
635 573
636 if (t->sched_info.last_queued) 574 set_tsk_thread_flag(p, TIF_NEED_RESCHED);
637 delta_jiffies = now - t->sched_info.last_queued; 575
638 sched_info_dequeued(t); 576 cpu = task_cpu(p);
639 t->sched_info.run_delay += delta_jiffies; 577 if (cpu == smp_processor_id())
640 t->sched_info.last_arrival = now; 578 return;
641 t->sched_info.pcnt++;
642 579
643 rq_sched_info_arrive(task_rq(t), delta_jiffies); 580 /* NEED_RESCHED must be visible before we test polling */
581 smp_mb();
582 if (!tsk_is_polling(p))
583 smp_send_reschedule(cpu);
644} 584}
645 585
646/* 586static void resched_cpu(int cpu)
647 * Called when a process is queued into either the active or expired
648 * array. The time is noted and later used to determine how long we
649 * had to wait for us to reach the cpu. Since the expired queue will
650 * become the active queue after active queue is empty, without dequeuing
651 * and requeuing any tasks, we are interested in queuing to either. It
652 * is unusual but not impossible for tasks to be dequeued and immediately
653 * requeued in the same or another array: this can happen in sched_yield(),
654 * set_user_nice(), and even load_balance() as it moves tasks from runqueue
655 * to runqueue.
656 *
657 * This function is only called from enqueue_task(), but also only updates
658 * the timestamp if it is already not set. It's assumed that
659 * sched_info_dequeued() will clear that stamp when appropriate.
660 */
661static inline void sched_info_queued(struct task_struct *t)
662{ 587{
663 if (unlikely(sched_info_on())) 588 struct rq *rq = cpu_rq(cpu);
664 if (!t->sched_info.last_queued) 589 unsigned long flags;
665 t->sched_info.last_queued = jiffies; 590
591 if (!spin_trylock_irqsave(&rq->lock, flags))
592 return;
593 resched_task(cpu_curr(cpu));
594 spin_unlock_irqrestore(&rq->lock, flags);
666} 595}
596#else
597static inline void resched_task(struct task_struct *p)
598{
599 assert_spin_locked(&task_rq(p)->lock);
600 set_tsk_need_resched(p);
601}
602#endif
667 603
668/* 604static u64 div64_likely32(u64 divident, unsigned long divisor)
669 * Called when a process ceases being the active-running process, either
670 * voluntarily or involuntarily. Now we can calculate how long we ran.
671 */
672static inline void sched_info_depart(struct task_struct *t)
673{ 605{
674 unsigned long delta_jiffies = jiffies - t->sched_info.last_arrival; 606#if BITS_PER_LONG == 32
607 if (likely(divident <= 0xffffffffULL))
608 return (u32)divident / divisor;
609 do_div(divident, divisor);
675 610
676 t->sched_info.cpu_time += delta_jiffies; 611 return divident;
677 rq_sched_info_depart(task_rq(t), delta_jiffies); 612#else
613 return divident / divisor;
614#endif
678} 615}
679 616
680/* 617#if BITS_PER_LONG == 32
681 * Called when tasks are switched involuntarily due, typically, to expiring 618# define WMULT_CONST (~0UL)
682 * their time slice. (This may also be called when switching to or from 619#else
683 * the idle task.) We are only called when prev != next. 620# define WMULT_CONST (1UL << 32)
684 */ 621#endif
685static inline void 622
686__sched_info_switch(struct task_struct *prev, struct task_struct *next) 623#define WMULT_SHIFT 32
624
625static inline unsigned long
626calc_delta_mine(unsigned long delta_exec, unsigned long weight,
627 struct load_weight *lw)
687{ 628{
688 struct rq *rq = task_rq(prev); 629 u64 tmp;
689 630
631 if (unlikely(!lw->inv_weight))
632 lw->inv_weight = WMULT_CONST / lw->weight;
633
634 tmp = (u64)delta_exec * weight;
690 /* 635 /*
691 * prev now departs the cpu. It's not interesting to record 636 * Check whether we'd overflow the 64-bit multiplication:
692 * stats about how efficient we were at scheduling the idle
693 * process, however.
694 */ 637 */
695 if (prev != rq->idle) 638 if (unlikely(tmp > WMULT_CONST)) {
696 sched_info_depart(prev); 639 tmp = ((tmp >> WMULT_SHIFT/2) * lw->inv_weight)
640 >> (WMULT_SHIFT/2);
641 } else {
642 tmp = (tmp * lw->inv_weight) >> WMULT_SHIFT;
643 }
697 644
698 if (next != rq->idle) 645 return (unsigned long)min(tmp, (u64)sysctl_sched_runtime_limit);
699 sched_info_arrive(next);
700}
701static inline void
702sched_info_switch(struct task_struct *prev, struct task_struct *next)
703{
704 if (unlikely(sched_info_on()))
705 __sched_info_switch(prev, next);
706} 646}
707#else
708#define sched_info_queued(t) do { } while (0)
709#define sched_info_switch(t, next) do { } while (0)
710#endif /* CONFIG_SCHEDSTATS || CONFIG_TASK_DELAY_ACCT */
711 647
712/* 648static inline unsigned long
713 * Adding/removing a task to/from a priority array: 649calc_delta_fair(unsigned long delta_exec, struct load_weight *lw)
714 */
715static void dequeue_task(struct task_struct *p, struct prio_array *array)
716{ 650{
717 array->nr_active--; 651 return calc_delta_mine(delta_exec, NICE_0_LOAD, lw);
718 list_del(&p->run_list);
719 if (list_empty(array->queue + p->prio))
720 __clear_bit(p->prio, array->bitmap);
721} 652}
722 653
723static void enqueue_task(struct task_struct *p, struct prio_array *array) 654static void update_load_add(struct load_weight *lw, unsigned long inc)
724{ 655{
725 sched_info_queued(p); 656 lw->weight += inc;
726 list_add_tail(&p->run_list, array->queue + p->prio); 657 lw->inv_weight = 0;
727 __set_bit(p->prio, array->bitmap);
728 array->nr_active++;
729 p->array = array;
730} 658}
731 659
732/* 660static void update_load_sub(struct load_weight *lw, unsigned long dec)
733 * Put task to the end of the run list without the overhead of dequeue
734 * followed by enqueue.
735 */
736static void requeue_task(struct task_struct *p, struct prio_array *array)
737{ 661{
738 list_move_tail(&p->run_list, array->queue + p->prio); 662 lw->weight -= dec;
663 lw->inv_weight = 0;
739} 664}
740 665
741static inline void 666static void __update_curr_load(struct rq *rq, struct load_stat *ls)
742enqueue_task_head(struct task_struct *p, struct prio_array *array)
743{ 667{
744 list_add(&p->run_list, array->queue + p->prio); 668 if (rq->curr != rq->idle && ls->load.weight) {
745 __set_bit(p->prio, array->bitmap); 669 ls->delta_exec += ls->delta_stat;
746 array->nr_active++; 670 ls->delta_fair += calc_delta_fair(ls->delta_stat, &ls->load);
747 p->array = array; 671 ls->delta_stat = 0;
672 }
748} 673}
749 674
750/* 675/*
751 * __normal_prio - return the priority that is based on the static 676 * Update delta_exec, delta_fair fields for rq.
752 * priority but is modified by bonuses/penalties.
753 * 677 *
754 * We scale the actual sleep average [0 .... MAX_SLEEP_AVG] 678 * delta_fair clock advances at a rate inversely proportional to
755 * into the -5 ... 0 ... +5 bonus/penalty range. 679 * total load (rq->ls.load.weight) on the runqueue, while
680 * delta_exec advances at the same rate as wall-clock (provided
681 * cpu is not idle).
756 * 682 *
757 * We use 25% of the full 0...39 priority range so that: 683 * delta_exec / delta_fair is a measure of the (smoothened) load on this
684 * runqueue over any given interval. This (smoothened) load is used
685 * during load balance.
758 * 686 *
759 * 1) nice +19 interactive tasks do not preempt nice 0 CPU hogs. 687 * This function is called /before/ updating rq->ls.load
760 * 2) nice -20 CPU hogs do not get preempted by nice 0 tasks. 688 * and when switching tasks.
761 *
762 * Both properties are important to certain workloads.
763 */ 689 */
764 690static void update_curr_load(struct rq *rq, u64 now)
765static inline int __normal_prio(struct task_struct *p)
766{ 691{
767 int bonus, prio; 692 struct load_stat *ls = &rq->ls;
768 693 u64 start;
769 bonus = CURRENT_BONUS(p) - MAX_BONUS / 2;
770 694
771 prio = p->static_prio - bonus; 695 start = ls->load_update_start;
772 if (prio < MAX_RT_PRIO) 696 ls->load_update_start = now;
773 prio = MAX_RT_PRIO; 697 ls->delta_stat += now - start;
774 if (prio > MAX_PRIO-1) 698 /*
775 prio = MAX_PRIO-1; 699 * Stagger updates to ls->delta_fair. Very frequent updates
776 return prio; 700 * can be expensive.
701 */
702 if (ls->delta_stat >= sysctl_sched_stat_granularity)
703 __update_curr_load(rq, ls);
777} 704}
778 705
779/* 706/*
@@ -791,53 +718,146 @@ static inline int __normal_prio(struct task_struct *p)
791 * this code will need modification 718 * this code will need modification
792 */ 719 */
793#define TIME_SLICE_NICE_ZERO DEF_TIMESLICE 720#define TIME_SLICE_NICE_ZERO DEF_TIMESLICE
794#define LOAD_WEIGHT(lp) \ 721#define load_weight(lp) \
795 (((lp) * SCHED_LOAD_SCALE) / TIME_SLICE_NICE_ZERO) 722 (((lp) * SCHED_LOAD_SCALE) / TIME_SLICE_NICE_ZERO)
796#define PRIO_TO_LOAD_WEIGHT(prio) \ 723#define PRIO_TO_LOAD_WEIGHT(prio) \
797 LOAD_WEIGHT(static_prio_timeslice(prio)) 724 load_weight(static_prio_timeslice(prio))
798#define RTPRIO_TO_LOAD_WEIGHT(rp) \ 725#define RTPRIO_TO_LOAD_WEIGHT(rp) \
799 (PRIO_TO_LOAD_WEIGHT(MAX_RT_PRIO) + LOAD_WEIGHT(rp)) 726 (PRIO_TO_LOAD_WEIGHT(MAX_RT_PRIO) + load_weight(rp))
800 727
801static void set_load_weight(struct task_struct *p) 728#define WEIGHT_IDLEPRIO 2
802{ 729#define WMULT_IDLEPRIO (1 << 31)
803 if (has_rt_policy(p)) { 730
804#ifdef CONFIG_SMP 731/*
805 if (p == task_rq(p)->migration_thread) 732 * Nice levels are multiplicative, with a gentle 10% change for every
806 /* 733 * nice level changed. I.e. when a CPU-bound task goes from nice 0 to
807 * The migration thread does the actual balancing. 734 * nice 1, it will get ~10% less CPU time than another CPU-bound task
808 * Giving its load any weight will skew balancing 735 * that remained on nice 0.
809 * adversely. 736 *
810 */ 737 * The "10% effect" is relative and cumulative: from _any_ nice level,
811 p->load_weight = 0; 738 * if you go up 1 level, it's -10% CPU usage, if you go down 1 level
812 else 739 * it's +10% CPU usage.
813#endif 740 */
814 p->load_weight = RTPRIO_TO_LOAD_WEIGHT(p->rt_priority); 741static const int prio_to_weight[40] = {
815 } else 742/* -20 */ 88818, 71054, 56843, 45475, 36380, 29104, 23283, 18626, 14901, 11921,
816 p->load_weight = PRIO_TO_LOAD_WEIGHT(p->static_prio); 743/* -10 */ 9537, 7629, 6103, 4883, 3906, 3125, 2500, 2000, 1600, 1280,
817} 744/* 0 */ NICE_0_LOAD /* 1024 */,
745/* 1 */ 819, 655, 524, 419, 336, 268, 215, 172, 137,
746/* 10 */ 110, 87, 70, 56, 45, 36, 29, 23, 18, 15,
747};
748
749static const u32 prio_to_wmult[40] = {
750 48356, 60446, 75558, 94446, 118058, 147573,
751 184467, 230589, 288233, 360285, 450347,
752 562979, 703746, 879575, 1099582, 1374389,
753 717986, 2147483, 2684354, 3355443, 4194304,
754 244160, 6557201, 8196502, 10250518, 12782640,
755 16025997, 19976592, 24970740, 31350126, 39045157,
756 49367440, 61356675, 76695844, 95443717, 119304647,
757 148102320, 186737708, 238609294, 286331153,
758};
818 759
819static inline void 760static inline void
820inc_raw_weighted_load(struct rq *rq, const struct task_struct *p) 761inc_load(struct rq *rq, const struct task_struct *p, u64 now)
821{ 762{
822 rq->raw_weighted_load += p->load_weight; 763 update_curr_load(rq, now);
764 update_load_add(&rq->ls.load, p->se.load.weight);
823} 765}
824 766
825static inline void 767static inline void
826dec_raw_weighted_load(struct rq *rq, const struct task_struct *p) 768dec_load(struct rq *rq, const struct task_struct *p, u64 now)
827{ 769{
828 rq->raw_weighted_load -= p->load_weight; 770 update_curr_load(rq, now);
771 update_load_sub(&rq->ls.load, p->se.load.weight);
829} 772}
830 773
831static inline void inc_nr_running(struct task_struct *p, struct rq *rq) 774static inline void inc_nr_running(struct task_struct *p, struct rq *rq, u64 now)
832{ 775{
833 rq->nr_running++; 776 rq->nr_running++;
834 inc_raw_weighted_load(rq, p); 777 inc_load(rq, p, now);
835} 778}
836 779
837static inline void dec_nr_running(struct task_struct *p, struct rq *rq) 780static inline void dec_nr_running(struct task_struct *p, struct rq *rq, u64 now)
838{ 781{
839 rq->nr_running--; 782 rq->nr_running--;
840 dec_raw_weighted_load(rq, p); 783 dec_load(rq, p, now);
784}
785
786static void activate_task(struct rq *rq, struct task_struct *p, int wakeup);
787
788/*
789 * runqueue iterator, to support SMP load-balancing between different
790 * scheduling classes, without having to expose their internal data
791 * structures to the load-balancing proper:
792 */
793struct rq_iterator {
794 void *arg;
795 struct task_struct *(*start)(void *);
796 struct task_struct *(*next)(void *);
797};
798
799static int balance_tasks(struct rq *this_rq, int this_cpu, struct rq *busiest,
800 unsigned long max_nr_move, unsigned long max_load_move,
801 struct sched_domain *sd, enum cpu_idle_type idle,
802 int *all_pinned, unsigned long *load_moved,
803 int this_best_prio, int best_prio, int best_prio_seen,
804 struct rq_iterator *iterator);
805
806#include "sched_stats.h"
807#include "sched_rt.c"
808#include "sched_fair.c"
809#include "sched_idletask.c"
810#ifdef CONFIG_SCHED_DEBUG
811# include "sched_debug.c"
812#endif
813
814#define sched_class_highest (&rt_sched_class)
815
816static void set_load_weight(struct task_struct *p)
817{
818 task_rq(p)->cfs.wait_runtime -= p->se.wait_runtime;
819 p->se.wait_runtime = 0;
820
821 if (task_has_rt_policy(p)) {
822 p->se.load.weight = prio_to_weight[0] * 2;
823 p->se.load.inv_weight = prio_to_wmult[0] >> 1;
824 return;
825 }
826
827 /*
828 * SCHED_IDLE tasks get minimal weight:
829 */
830 if (p->policy == SCHED_IDLE) {
831 p->se.load.weight = WEIGHT_IDLEPRIO;
832 p->se.load.inv_weight = WMULT_IDLEPRIO;
833 return;
834 }
835
836 p->se.load.weight = prio_to_weight[p->static_prio - MAX_RT_PRIO];
837 p->se.load.inv_weight = prio_to_wmult[p->static_prio - MAX_RT_PRIO];
838}
839
840static void
841enqueue_task(struct rq *rq, struct task_struct *p, int wakeup, u64 now)
842{
843 sched_info_queued(p);
844 p->sched_class->enqueue_task(rq, p, wakeup, now);
845 p->se.on_rq = 1;
846}
847
848static void
849dequeue_task(struct rq *rq, struct task_struct *p, int sleep, u64 now)
850{
851 p->sched_class->dequeue_task(rq, p, sleep, now);
852 p->se.on_rq = 0;
853}
854
855/*
856 * __normal_prio - return the priority that is based on the static prio
857 */
858static inline int __normal_prio(struct task_struct *p)
859{
860 return p->static_prio;
841} 861}
842 862
843/* 863/*
@@ -851,7 +871,7 @@ static inline int normal_prio(struct task_struct *p)
851{ 871{
852 int prio; 872 int prio;
853 873
854 if (has_rt_policy(p)) 874 if (task_has_rt_policy(p))
855 prio = MAX_RT_PRIO-1 - p->rt_priority; 875 prio = MAX_RT_PRIO-1 - p->rt_priority;
856 else 876 else
857 prio = __normal_prio(p); 877 prio = __normal_prio(p);
@@ -879,222 +899,47 @@ static int effective_prio(struct task_struct *p)
879} 899}
880 900
881/* 901/*
882 * __activate_task - move a task to the runqueue. 902 * activate_task - move a task to the runqueue.
883 */
884static void __activate_task(struct task_struct *p, struct rq *rq)
885{
886 struct prio_array *target = rq->active;
887
888 if (batch_task(p))
889 target = rq->expired;
890 enqueue_task(p, target);
891 inc_nr_running(p, rq);
892}
893
894/*
895 * __activate_idle_task - move idle task to the _front_ of runqueue.
896 */
897static inline void __activate_idle_task(struct task_struct *p, struct rq *rq)
898{
899 enqueue_task_head(p, rq->active);
900 inc_nr_running(p, rq);
901}
902
903/*
904 * Recalculate p->normal_prio and p->prio after having slept,
905 * updating the sleep-average too:
906 */ 903 */
907static int recalc_task_prio(struct task_struct *p, unsigned long long now) 904static void activate_task(struct rq *rq, struct task_struct *p, int wakeup)
908{ 905{
909 /* Caller must always ensure 'now >= p->timestamp' */ 906 u64 now = rq_clock(rq);
910 unsigned long sleep_time = now - p->timestamp;
911
912 if (batch_task(p))
913 sleep_time = 0;
914
915 if (likely(sleep_time > 0)) {
916 /*
917 * This ceiling is set to the lowest priority that would allow
918 * a task to be reinserted into the active array on timeslice
919 * completion.
920 */
921 unsigned long ceiling = INTERACTIVE_SLEEP(p);
922
923 if (p->mm && sleep_time > ceiling && p->sleep_avg < ceiling) {
924 /*
925 * Prevents user tasks from achieving best priority
926 * with one single large enough sleep.
927 */
928 p->sleep_avg = ceiling;
929 /*
930 * Using INTERACTIVE_SLEEP() as a ceiling places a
931 * nice(0) task 1ms sleep away from promotion, and
932 * gives it 700ms to round-robin with no chance of
933 * being demoted. This is more than generous, so
934 * mark this sleep as non-interactive to prevent the
935 * on-runqueue bonus logic from intervening should
936 * this task not receive cpu immediately.
937 */
938 p->sleep_type = SLEEP_NONINTERACTIVE;
939 } else {
940 /*
941 * Tasks waking from uninterruptible sleep are
942 * limited in their sleep_avg rise as they
943 * are likely to be waiting on I/O
944 */
945 if (p->sleep_type == SLEEP_NONINTERACTIVE && p->mm) {
946 if (p->sleep_avg >= ceiling)
947 sleep_time = 0;
948 else if (p->sleep_avg + sleep_time >=
949 ceiling) {
950 p->sleep_avg = ceiling;
951 sleep_time = 0;
952 }
953 }
954 907
955 /* 908 if (p->state == TASK_UNINTERRUPTIBLE)
956 * This code gives a bonus to interactive tasks. 909 rq->nr_uninterruptible--;
957 *
958 * The boost works by updating the 'average sleep time'
959 * value here, based on ->timestamp. The more time a
960 * task spends sleeping, the higher the average gets -
961 * and the higher the priority boost gets as well.
962 */
963 p->sleep_avg += sleep_time;
964
965 }
966 if (p->sleep_avg > NS_MAX_SLEEP_AVG)
967 p->sleep_avg = NS_MAX_SLEEP_AVG;
968 }
969 910
970 return effective_prio(p); 911 enqueue_task(rq, p, wakeup, now);
912 inc_nr_running(p, rq, now);
971} 913}
972 914
973/* 915/*
974 * activate_task - move a task to the runqueue and do priority recalculation 916 * activate_idle_task - move idle task to the _front_ of runqueue.
975 *
976 * Update all the scheduling statistics stuff. (sleep average
977 * calculation, priority modifiers, etc.)
978 */ 917 */
979static void activate_task(struct task_struct *p, struct rq *rq, int local) 918static inline void activate_idle_task(struct task_struct *p, struct rq *rq)
980{ 919{
981 unsigned long long now; 920 u64 now = rq_clock(rq);
982 921
983 if (rt_task(p)) 922 if (p->state == TASK_UNINTERRUPTIBLE)
984 goto out; 923 rq->nr_uninterruptible--;
985
986 now = sched_clock();
987#ifdef CONFIG_SMP
988 if (!local) {
989 /* Compensate for drifting sched_clock */
990 struct rq *this_rq = this_rq();
991 now = (now - this_rq->most_recent_timestamp)
992 + rq->most_recent_timestamp;
993 }
994#endif
995
996 /*
997 * Sleep time is in units of nanosecs, so shift by 20 to get a
998 * milliseconds-range estimation of the amount of time that the task
999 * spent sleeping:
1000 */
1001 if (unlikely(prof_on == SLEEP_PROFILING)) {
1002 if (p->state == TASK_UNINTERRUPTIBLE)
1003 profile_hits(SLEEP_PROFILING, (void *)get_wchan(p),
1004 (now - p->timestamp) >> 20);
1005 }
1006
1007 p->prio = recalc_task_prio(p, now);
1008 924
1009 /* 925 enqueue_task(rq, p, 0, now);
1010 * This checks to make sure it's not an uninterruptible task 926 inc_nr_running(p, rq, now);
1011 * that is now waking up.
1012 */
1013 if (p->sleep_type == SLEEP_NORMAL) {
1014 /*
1015 * Tasks which were woken up by interrupts (ie. hw events)
1016 * are most likely of interactive nature. So we give them
1017 * the credit of extending their sleep time to the period
1018 * of time they spend on the runqueue, waiting for execution
1019 * on a CPU, first time around:
1020 */
1021 if (in_interrupt())
1022 p->sleep_type = SLEEP_INTERRUPTED;
1023 else {
1024 /*
1025 * Normal first-time wakeups get a credit too for
1026 * on-runqueue time, but it will be weighted down:
1027 */
1028 p->sleep_type = SLEEP_INTERACTIVE;
1029 }
1030 }
1031 p->timestamp = now;
1032out:
1033 __activate_task(p, rq);
1034} 927}
1035 928
1036/* 929/*
1037 * deactivate_task - remove a task from the runqueue. 930 * deactivate_task - remove a task from the runqueue.
1038 */ 931 */
1039static void deactivate_task(struct task_struct *p, struct rq *rq) 932static void deactivate_task(struct rq *rq, struct task_struct *p, int sleep)
1040{
1041 dec_nr_running(p, rq);
1042 dequeue_task(p, p->array);
1043 p->array = NULL;
1044}
1045
1046/*
1047 * resched_task - mark a task 'to be rescheduled now'.
1048 *
1049 * On UP this means the setting of the need_resched flag, on SMP it
1050 * might also involve a cross-CPU call to trigger the scheduler on
1051 * the target CPU.
1052 */
1053#ifdef CONFIG_SMP
1054
1055#ifndef tsk_is_polling
1056#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG)
1057#endif
1058
1059static void resched_task(struct task_struct *p)
1060{ 933{
1061 int cpu; 934 u64 now = rq_clock(rq);
1062 935
1063 assert_spin_locked(&task_rq(p)->lock); 936 if (p->state == TASK_UNINTERRUPTIBLE)
937 rq->nr_uninterruptible++;
1064 938
1065 if (unlikely(test_tsk_thread_flag(p, TIF_NEED_RESCHED))) 939 dequeue_task(rq, p, sleep, now);
1066 return; 940 dec_nr_running(p, rq, now);
1067
1068 set_tsk_thread_flag(p, TIF_NEED_RESCHED);
1069
1070 cpu = task_cpu(p);
1071 if (cpu == smp_processor_id())
1072 return;
1073
1074 /* NEED_RESCHED must be visible before we test polling */
1075 smp_mb();
1076 if (!tsk_is_polling(p))
1077 smp_send_reschedule(cpu);
1078} 941}
1079 942
1080static void resched_cpu(int cpu)
1081{
1082 struct rq *rq = cpu_rq(cpu);
1083 unsigned long flags;
1084
1085 if (!spin_trylock_irqsave(&rq->lock, flags))
1086 return;
1087 resched_task(cpu_curr(cpu));
1088 spin_unlock_irqrestore(&rq->lock, flags);
1089}
1090#else
1091static inline void resched_task(struct task_struct *p)
1092{
1093 assert_spin_locked(&task_rq(p)->lock);
1094 set_tsk_need_resched(p);
1095}
1096#endif
1097
1098/** 943/**
1099 * task_curr - is this task currently executing on a CPU? 944 * task_curr - is this task currently executing on a CPU?
1100 * @p: the task in question. 945 * @p: the task in question.
@@ -1107,10 +952,42 @@ inline int task_curr(const struct task_struct *p)
1107/* Used instead of source_load when we know the type == 0 */ 952/* Used instead of source_load when we know the type == 0 */
1108unsigned long weighted_cpuload(const int cpu) 953unsigned long weighted_cpuload(const int cpu)
1109{ 954{
1110 return cpu_rq(cpu)->raw_weighted_load; 955 return cpu_rq(cpu)->ls.load.weight;
956}
957
958static inline void __set_task_cpu(struct task_struct *p, unsigned int cpu)
959{
960#ifdef CONFIG_SMP
961 task_thread_info(p)->cpu = cpu;
962 set_task_cfs_rq(p);
963#endif
1111} 964}
1112 965
1113#ifdef CONFIG_SMP 966#ifdef CONFIG_SMP
967
968void set_task_cpu(struct task_struct *p, unsigned int new_cpu)
969{
970 int old_cpu = task_cpu(p);
971 struct rq *old_rq = cpu_rq(old_cpu), *new_rq = cpu_rq(new_cpu);
972 u64 clock_offset, fair_clock_offset;
973
974 clock_offset = old_rq->clock - new_rq->clock;
975 fair_clock_offset = old_rq->cfs.fair_clock -
976 new_rq->cfs.fair_clock;
977 if (p->se.wait_start)
978 p->se.wait_start -= clock_offset;
979 if (p->se.wait_start_fair)
980 p->se.wait_start_fair -= fair_clock_offset;
981 if (p->se.sleep_start)
982 p->se.sleep_start -= clock_offset;
983 if (p->se.block_start)
984 p->se.block_start -= clock_offset;
985 if (p->se.sleep_start_fair)
986 p->se.sleep_start_fair -= fair_clock_offset;
987
988 __set_task_cpu(p, new_cpu);
989}
990
1114struct migration_req { 991struct migration_req {
1115 struct list_head list; 992 struct list_head list;
1116 993
@@ -1133,7 +1010,7 @@ migrate_task(struct task_struct *p, int dest_cpu, struct migration_req *req)
1133 * If the task is not on a runqueue (and not running), then 1010 * If the task is not on a runqueue (and not running), then
1134 * it is sufficient to simply update the task's cpu field. 1011 * it is sufficient to simply update the task's cpu field.
1135 */ 1012 */
1136 if (!p->array && !task_running(rq, p)) { 1013 if (!p->se.on_rq && !task_running(rq, p)) {
1137 set_task_cpu(p, dest_cpu); 1014 set_task_cpu(p, dest_cpu);
1138 return 0; 1015 return 0;
1139 } 1016 }
@@ -1158,9 +1035,8 @@ migrate_task(struct task_struct *p, int dest_cpu, struct migration_req *req)
1158void wait_task_inactive(struct task_struct *p) 1035void wait_task_inactive(struct task_struct *p)
1159{ 1036{
1160 unsigned long flags; 1037 unsigned long flags;
1038 int running, on_rq;
1161 struct rq *rq; 1039 struct rq *rq;
1162 struct prio_array *array;
1163 int running;
1164 1040
1165repeat: 1041repeat:
1166 /* 1042 /*
@@ -1192,7 +1068,7 @@ repeat:
1192 */ 1068 */
1193 rq = task_rq_lock(p, &flags); 1069 rq = task_rq_lock(p, &flags);
1194 running = task_running(rq, p); 1070 running = task_running(rq, p);
1195 array = p->array; 1071 on_rq = p->se.on_rq;
1196 task_rq_unlock(rq, &flags); 1072 task_rq_unlock(rq, &flags);
1197 1073
1198 /* 1074 /*
@@ -1215,7 +1091,7 @@ repeat:
1215 * running right now), it's preempted, and we should 1091 * running right now), it's preempted, and we should
1216 * yield - it could be a while. 1092 * yield - it could be a while.
1217 */ 1093 */
1218 if (unlikely(array)) { 1094 if (unlikely(on_rq)) {
1219 yield(); 1095 yield();
1220 goto repeat; 1096 goto repeat;
1221 } 1097 }
@@ -1261,11 +1137,12 @@ void kick_process(struct task_struct *p)
1261static inline unsigned long source_load(int cpu, int type) 1137static inline unsigned long source_load(int cpu, int type)
1262{ 1138{
1263 struct rq *rq = cpu_rq(cpu); 1139 struct rq *rq = cpu_rq(cpu);
1140 unsigned long total = weighted_cpuload(cpu);
1264 1141
1265 if (type == 0) 1142 if (type == 0)
1266 return rq->raw_weighted_load; 1143 return total;
1267 1144
1268 return min(rq->cpu_load[type-1], rq->raw_weighted_load); 1145 return min(rq->cpu_load[type-1], total);
1269} 1146}
1270 1147
1271/* 1148/*
@@ -1275,11 +1152,12 @@ static inline unsigned long source_load(int cpu, int type)
1275static inline unsigned long target_load(int cpu, int type) 1152static inline unsigned long target_load(int cpu, int type)
1276{ 1153{
1277 struct rq *rq = cpu_rq(cpu); 1154 struct rq *rq = cpu_rq(cpu);
1155 unsigned long total = weighted_cpuload(cpu);
1278 1156
1279 if (type == 0) 1157 if (type == 0)
1280 return rq->raw_weighted_load; 1158 return total;
1281 1159
1282 return max(rq->cpu_load[type-1], rq->raw_weighted_load); 1160 return max(rq->cpu_load[type-1], total);
1283} 1161}
1284 1162
1285/* 1163/*
@@ -1288,9 +1166,10 @@ static inline unsigned long target_load(int cpu, int type)
1288static inline unsigned long cpu_avg_load_per_task(int cpu) 1166static inline unsigned long cpu_avg_load_per_task(int cpu)
1289{ 1167{
1290 struct rq *rq = cpu_rq(cpu); 1168 struct rq *rq = cpu_rq(cpu);
1169 unsigned long total = weighted_cpuload(cpu);
1291 unsigned long n = rq->nr_running; 1170 unsigned long n = rq->nr_running;
1292 1171
1293 return n ? rq->raw_weighted_load / n : SCHED_LOAD_SCALE; 1172 return n ? total / n : SCHED_LOAD_SCALE;
1294} 1173}
1295 1174
1296/* 1175/*
@@ -1392,9 +1271,9 @@ static int sched_balance_self(int cpu, int flag)
1392 struct sched_domain *tmp, *sd = NULL; 1271 struct sched_domain *tmp, *sd = NULL;
1393 1272
1394 for_each_domain(cpu, tmp) { 1273 for_each_domain(cpu, tmp) {
1395 /* 1274 /*
1396 * If power savings logic is enabled for a domain, stop there. 1275 * If power savings logic is enabled for a domain, stop there.
1397 */ 1276 */
1398 if (tmp->flags & SD_POWERSAVINGS_BALANCE) 1277 if (tmp->flags & SD_POWERSAVINGS_BALANCE)
1399 break; 1278 break;
1400 if (tmp->flags & flag) 1279 if (tmp->flags & flag)
@@ -1477,9 +1356,9 @@ static int wake_idle(int cpu, struct task_struct *p)
1477 if (idle_cpu(i)) 1356 if (idle_cpu(i))
1478 return i; 1357 return i;
1479 } 1358 }
1480 } 1359 } else {
1481 else
1482 break; 1360 break;
1361 }
1483 } 1362 }
1484 return cpu; 1363 return cpu;
1485} 1364}
@@ -1521,7 +1400,7 @@ static int try_to_wake_up(struct task_struct *p, unsigned int state, int sync)
1521 if (!(old_state & state)) 1400 if (!(old_state & state))
1522 goto out; 1401 goto out;
1523 1402
1524 if (p->array) 1403 if (p->se.on_rq)
1525 goto out_running; 1404 goto out_running;
1526 1405
1527 cpu = task_cpu(p); 1406 cpu = task_cpu(p);
@@ -1576,11 +1455,11 @@ static int try_to_wake_up(struct task_struct *p, unsigned int state, int sync)
1576 * of the current CPU: 1455 * of the current CPU:
1577 */ 1456 */
1578 if (sync) 1457 if (sync)
1579 tl -= current->load_weight; 1458 tl -= current->se.load.weight;
1580 1459
1581 if ((tl <= load && 1460 if ((tl <= load &&
1582 tl + target_load(cpu, idx) <= tl_per_task) || 1461 tl + target_load(cpu, idx) <= tl_per_task) ||
1583 100*(tl + p->load_weight) <= imbalance*load) { 1462 100*(tl + p->se.load.weight) <= imbalance*load) {
1584 /* 1463 /*
1585 * This domain has SD_WAKE_AFFINE and 1464 * This domain has SD_WAKE_AFFINE and
1586 * p is cache cold in this domain, and 1465 * p is cache cold in this domain, and
@@ -1614,7 +1493,7 @@ out_set_cpu:
1614 old_state = p->state; 1493 old_state = p->state;
1615 if (!(old_state & state)) 1494 if (!(old_state & state))
1616 goto out; 1495 goto out;
1617 if (p->array) 1496 if (p->se.on_rq)
1618 goto out_running; 1497 goto out_running;
1619 1498
1620 this_cpu = smp_processor_id(); 1499 this_cpu = smp_processor_id();
@@ -1623,25 +1502,7 @@ out_set_cpu:
1623 1502
1624out_activate: 1503out_activate:
1625#endif /* CONFIG_SMP */ 1504#endif /* CONFIG_SMP */
1626 if (old_state == TASK_UNINTERRUPTIBLE) { 1505 activate_task(rq, p, 1);
1627 rq->nr_uninterruptible--;
1628 /*
1629 * Tasks on involuntary sleep don't earn
1630 * sleep_avg beyond just interactive state.
1631 */
1632 p->sleep_type = SLEEP_NONINTERACTIVE;
1633 } else
1634
1635 /*
1636 * Tasks that have marked their sleep as noninteractive get
1637 * woken up with their sleep average not weighted in an
1638 * interactive way.
1639 */
1640 if (old_state & TASK_NONINTERACTIVE)
1641 p->sleep_type = SLEEP_NONINTERACTIVE;
1642
1643
1644 activate_task(p, rq, cpu == this_cpu);
1645 /* 1506 /*
1646 * Sync wakeups (i.e. those types of wakeups where the waker 1507 * Sync wakeups (i.e. those types of wakeups where the waker
1647 * has indicated that it will leave the CPU in short order) 1508 * has indicated that it will leave the CPU in short order)
@@ -1650,10 +1511,8 @@ out_activate:
1650 * the waker guarantees that the freshly woken up task is going 1511 * the waker guarantees that the freshly woken up task is going
1651 * to be considered on this CPU.) 1512 * to be considered on this CPU.)
1652 */ 1513 */
1653 if (!sync || cpu != this_cpu) { 1514 if (!sync || cpu != this_cpu)
1654 if (TASK_PREEMPTS_CURR(p, rq)) 1515 check_preempt_curr(rq, p);
1655 resched_task(rq->curr);
1656 }
1657 success = 1; 1516 success = 1;
1658 1517
1659out_running: 1518out_running:
@@ -1676,19 +1535,36 @@ int fastcall wake_up_state(struct task_struct *p, unsigned int state)
1676 return try_to_wake_up(p, state, 0); 1535 return try_to_wake_up(p, state, 0);
1677} 1536}
1678 1537
1679static void task_running_tick(struct rq *rq, struct task_struct *p);
1680/* 1538/*
1681 * Perform scheduler related setup for a newly forked process p. 1539 * Perform scheduler related setup for a newly forked process p.
1682 * p is forked by current. 1540 * p is forked by current.
1683 */ 1541 *
1684void fastcall sched_fork(struct task_struct *p, int clone_flags) 1542 * __sched_fork() is basic setup used by init_idle() too:
1685{ 1543 */
1686 int cpu = get_cpu(); 1544static void __sched_fork(struct task_struct *p)
1545{
1546 p->se.wait_start_fair = 0;
1547 p->se.wait_start = 0;
1548 p->se.exec_start = 0;
1549 p->se.sum_exec_runtime = 0;
1550 p->se.delta_exec = 0;
1551 p->se.delta_fair_run = 0;
1552 p->se.delta_fair_sleep = 0;
1553 p->se.wait_runtime = 0;
1554 p->se.sum_wait_runtime = 0;
1555 p->se.sum_sleep_runtime = 0;
1556 p->se.sleep_start = 0;
1557 p->se.sleep_start_fair = 0;
1558 p->se.block_start = 0;
1559 p->se.sleep_max = 0;
1560 p->se.block_max = 0;
1561 p->se.exec_max = 0;
1562 p->se.wait_max = 0;
1563 p->se.wait_runtime_overruns = 0;
1564 p->se.wait_runtime_underruns = 0;
1687 1565
1688#ifdef CONFIG_SMP 1566 INIT_LIST_HEAD(&p->run_list);
1689 cpu = sched_balance_self(cpu, SD_BALANCE_FORK); 1567 p->se.on_rq = 0;
1690#endif
1691 set_task_cpu(p, cpu);
1692 1568
1693 /* 1569 /*
1694 * We mark the process as running here, but have not actually 1570 * We mark the process as running here, but have not actually
@@ -1697,16 +1573,29 @@ void fastcall sched_fork(struct task_struct *p, int clone_flags)
1697 * event cannot wake it up and insert it on the runqueue either. 1573 * event cannot wake it up and insert it on the runqueue either.
1698 */ 1574 */
1699 p->state = TASK_RUNNING; 1575 p->state = TASK_RUNNING;
1576}
1577
1578/*
1579 * fork()/clone()-time setup:
1580 */
1581void sched_fork(struct task_struct *p, int clone_flags)
1582{
1583 int cpu = get_cpu();
1584
1585 __sched_fork(p);
1586
1587#ifdef CONFIG_SMP
1588 cpu = sched_balance_self(cpu, SD_BALANCE_FORK);
1589#endif
1590 __set_task_cpu(p, cpu);
1700 1591
1701 /* 1592 /*
1702 * Make sure we do not leak PI boosting priority to the child: 1593 * Make sure we do not leak PI boosting priority to the child:
1703 */ 1594 */
1704 p->prio = current->normal_prio; 1595 p->prio = current->normal_prio;
1705 1596
1706 INIT_LIST_HEAD(&p->run_list);
1707 p->array = NULL;
1708#if defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT) 1597#if defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT)
1709 if (unlikely(sched_info_on())) 1598 if (likely(sched_info_on()))
1710 memset(&p->sched_info, 0, sizeof(p->sched_info)); 1599 memset(&p->sched_info, 0, sizeof(p->sched_info));
1711#endif 1600#endif
1712#if defined(CONFIG_SMP) && defined(__ARCH_WANT_UNLOCKED_CTXSW) 1601#if defined(CONFIG_SMP) && defined(__ARCH_WANT_UNLOCKED_CTXSW)
@@ -1716,34 +1605,16 @@ void fastcall sched_fork(struct task_struct *p, int clone_flags)
1716 /* Want to start with kernel preemption disabled. */ 1605 /* Want to start with kernel preemption disabled. */
1717 task_thread_info(p)->preempt_count = 1; 1606 task_thread_info(p)->preempt_count = 1;
1718#endif 1607#endif
1719 /*
1720 * Share the timeslice between parent and child, thus the
1721 * total amount of pending timeslices in the system doesn't change,
1722 * resulting in more scheduling fairness.
1723 */
1724 local_irq_disable();
1725 p->time_slice = (current->time_slice + 1) >> 1;
1726 /*
1727 * The remainder of the first timeslice might be recovered by
1728 * the parent if the child exits early enough.
1729 */
1730 p->first_time_slice = 1;
1731 current->time_slice >>= 1;
1732 p->timestamp = sched_clock();
1733 if (unlikely(!current->time_slice)) {
1734 /*
1735 * This case is rare, it happens when the parent has only
1736 * a single jiffy left from its timeslice. Taking the
1737 * runqueue lock is not a problem.
1738 */
1739 current->time_slice = 1;
1740 task_running_tick(cpu_rq(cpu), current);
1741 }
1742 local_irq_enable();
1743 put_cpu(); 1608 put_cpu();
1744} 1609}
1745 1610
1746/* 1611/*
1612 * After fork, child runs first. (default) If set to 0 then
1613 * parent will (try to) run first.
1614 */
1615unsigned int __read_mostly sysctl_sched_child_runs_first = 1;
1616
1617/*
1747 * wake_up_new_task - wake up a newly created task for the first time. 1618 * wake_up_new_task - wake up a newly created task for the first time.
1748 * 1619 *
1749 * This function will do some initial scheduler statistics housekeeping 1620 * This function will do some initial scheduler statistics housekeeping
@@ -1752,107 +1623,27 @@ void fastcall sched_fork(struct task_struct *p, int clone_flags)
1752 */ 1623 */
1753void fastcall wake_up_new_task(struct task_struct *p, unsigned long clone_flags) 1624void fastcall wake_up_new_task(struct task_struct *p, unsigned long clone_flags)
1754{ 1625{
1755 struct rq *rq, *this_rq;
1756 unsigned long flags; 1626 unsigned long flags;
1757 int this_cpu, cpu; 1627 struct rq *rq;
1628 int this_cpu;
1758 1629
1759 rq = task_rq_lock(p, &flags); 1630 rq = task_rq_lock(p, &flags);
1760 BUG_ON(p->state != TASK_RUNNING); 1631 BUG_ON(p->state != TASK_RUNNING);
1761 this_cpu = smp_processor_id(); 1632 this_cpu = smp_processor_id(); /* parent's CPU */
1762 cpu = task_cpu(p);
1763
1764 /*
1765 * We decrease the sleep average of forking parents
1766 * and children as well, to keep max-interactive tasks
1767 * from forking tasks that are max-interactive. The parent
1768 * (current) is done further down, under its lock.
1769 */
1770 p->sleep_avg = JIFFIES_TO_NS(CURRENT_BONUS(p) *
1771 CHILD_PENALTY / 100 * MAX_SLEEP_AVG / MAX_BONUS);
1772 1633
1773 p->prio = effective_prio(p); 1634 p->prio = effective_prio(p);
1774 1635
1775 if (likely(cpu == this_cpu)) { 1636 if (!sysctl_sched_child_runs_first || (clone_flags & CLONE_VM) ||
1776 if (!(clone_flags & CLONE_VM)) { 1637 task_cpu(p) != this_cpu || !current->se.on_rq) {
1777 /* 1638 activate_task(rq, p, 0);
1778 * The VM isn't cloned, so we're in a good position to
1779 * do child-runs-first in anticipation of an exec. This
1780 * usually avoids a lot of COW overhead.
1781 */
1782 if (unlikely(!current->array))
1783 __activate_task(p, rq);
1784 else {
1785 p->prio = current->prio;
1786 p->normal_prio = current->normal_prio;
1787 list_add_tail(&p->run_list, &current->run_list);
1788 p->array = current->array;
1789 p->array->nr_active++;
1790 inc_nr_running(p, rq);
1791 }
1792 set_need_resched();
1793 } else
1794 /* Run child last */
1795 __activate_task(p, rq);
1796 /*
1797 * We skip the following code due to cpu == this_cpu
1798 *
1799 * task_rq_unlock(rq, &flags);
1800 * this_rq = task_rq_lock(current, &flags);
1801 */
1802 this_rq = rq;
1803 } else { 1639 } else {
1804 this_rq = cpu_rq(this_cpu);
1805
1806 /* 1640 /*
1807 * Not the local CPU - must adjust timestamp. This should 1641 * Let the scheduling class do new task startup
1808 * get optimised away in the !CONFIG_SMP case. 1642 * management (if any):
1809 */ 1643 */
1810 p->timestamp = (p->timestamp - this_rq->most_recent_timestamp) 1644 p->sched_class->task_new(rq, p);
1811 + rq->most_recent_timestamp;
1812 __activate_task(p, rq);
1813 if (TASK_PREEMPTS_CURR(p, rq))
1814 resched_task(rq->curr);
1815
1816 /*
1817 * Parent and child are on different CPUs, now get the
1818 * parent runqueue to update the parent's ->sleep_avg:
1819 */
1820 task_rq_unlock(rq, &flags);
1821 this_rq = task_rq_lock(current, &flags);
1822 }
1823 current->sleep_avg = JIFFIES_TO_NS(CURRENT_BONUS(current) *
1824 PARENT_PENALTY / 100 * MAX_SLEEP_AVG / MAX_BONUS);
1825 task_rq_unlock(this_rq, &flags);
1826}
1827
1828/*
1829 * Potentially available exiting-child timeslices are
1830 * retrieved here - this way the parent does not get
1831 * penalized for creating too many threads.
1832 *
1833 * (this cannot be used to 'generate' timeslices
1834 * artificially, because any timeslice recovered here
1835 * was given away by the parent in the first place.)
1836 */
1837void fastcall sched_exit(struct task_struct *p)
1838{
1839 unsigned long flags;
1840 struct rq *rq;
1841
1842 /*
1843 * If the child was a (relative-) CPU hog then decrease
1844 * the sleep_avg of the parent as well.
1845 */
1846 rq = task_rq_lock(p->parent, &flags);
1847 if (p->first_time_slice && task_cpu(p) == task_cpu(p->parent)) {
1848 p->parent->time_slice += p->time_slice;
1849 if (unlikely(p->parent->time_slice > task_timeslice(p)))
1850 p->parent->time_slice = task_timeslice(p);
1851 } 1645 }
1852 if (p->sleep_avg < p->parent->sleep_avg) 1646 check_preempt_curr(rq, p);
1853 p->parent->sleep_avg = p->parent->sleep_avg /
1854 (EXIT_WEIGHT + 1) * EXIT_WEIGHT + p->sleep_avg /
1855 (EXIT_WEIGHT + 1);
1856 task_rq_unlock(rq, &flags); 1647 task_rq_unlock(rq, &flags);
1857} 1648}
1858 1649
@@ -1917,7 +1708,7 @@ static inline void finish_task_switch(struct rq *rq, struct task_struct *prev)
1917 /* 1708 /*
1918 * Remove function-return probe instances associated with this 1709 * Remove function-return probe instances associated with this
1919 * task and put them back on the free list. 1710 * task and put them back on the free list.
1920 */ 1711 */
1921 kprobe_flush_task(prev); 1712 kprobe_flush_task(prev);
1922 put_task_struct(prev); 1713 put_task_struct(prev);
1923 } 1714 }
@@ -1945,13 +1736,15 @@ asmlinkage void schedule_tail(struct task_struct *prev)
1945 * context_switch - switch to the new MM and the new 1736 * context_switch - switch to the new MM and the new
1946 * thread's register state. 1737 * thread's register state.
1947 */ 1738 */
1948static inline struct task_struct * 1739static inline void
1949context_switch(struct rq *rq, struct task_struct *prev, 1740context_switch(struct rq *rq, struct task_struct *prev,
1950 struct task_struct *next) 1741 struct task_struct *next)
1951{ 1742{
1952 struct mm_struct *mm = next->mm; 1743 struct mm_struct *mm, *oldmm;
1953 struct mm_struct *oldmm = prev->active_mm;
1954 1744
1745 prepare_task_switch(rq, next);
1746 mm = next->mm;
1747 oldmm = prev->active_mm;
1955 /* 1748 /*
1956 * For paravirt, this is coupled with an exit in switch_to to 1749 * For paravirt, this is coupled with an exit in switch_to to
1957 * combine the page table reload and the switch backend into 1750 * combine the page table reload and the switch backend into
@@ -1959,16 +1752,15 @@ context_switch(struct rq *rq, struct task_struct *prev,
1959 */ 1752 */
1960 arch_enter_lazy_cpu_mode(); 1753 arch_enter_lazy_cpu_mode();
1961 1754
1962 if (!mm) { 1755 if (unlikely(!mm)) {
1963 next->active_mm = oldmm; 1756 next->active_mm = oldmm;
1964 atomic_inc(&oldmm->mm_count); 1757 atomic_inc(&oldmm->mm_count);
1965 enter_lazy_tlb(oldmm, next); 1758 enter_lazy_tlb(oldmm, next);
1966 } else 1759 } else
1967 switch_mm(oldmm, mm, next); 1760 switch_mm(oldmm, mm, next);
1968 1761
1969 if (!prev->mm) { 1762 if (unlikely(!prev->mm)) {
1970 prev->active_mm = NULL; 1763 prev->active_mm = NULL;
1971 WARN_ON(rq->prev_mm);
1972 rq->prev_mm = oldmm; 1764 rq->prev_mm = oldmm;
1973 } 1765 }
1974 /* 1766 /*
@@ -1984,7 +1776,13 @@ context_switch(struct rq *rq, struct task_struct *prev,
1984 /* Here we just switch the register state and the stack. */ 1776 /* Here we just switch the register state and the stack. */
1985 switch_to(prev, next, prev); 1777 switch_to(prev, next, prev);
1986 1778
1987 return prev; 1779 barrier();
1780 /*
1781 * this_rq must be evaluated again because prev may have moved
1782 * CPUs since it called schedule(), thus the 'rq' on its stack
1783 * frame will be invalid.
1784 */
1785 finish_task_switch(this_rq(), prev);
1988} 1786}
1989 1787
1990/* 1788/*
@@ -2057,17 +1855,65 @@ unsigned long nr_active(void)
2057 return running + uninterruptible; 1855 return running + uninterruptible;
2058} 1856}
2059 1857
2060#ifdef CONFIG_SMP
2061
2062/* 1858/*
2063 * Is this task likely cache-hot: 1859 * Update rq->cpu_load[] statistics. This function is usually called every
1860 * scheduler tick (TICK_NSEC).
2064 */ 1861 */
2065static inline int 1862static void update_cpu_load(struct rq *this_rq)
2066task_hot(struct task_struct *p, unsigned long long now, struct sched_domain *sd)
2067{ 1863{
2068 return (long long)(now - p->last_ran) < (long long)sd->cache_hot_time; 1864 u64 fair_delta64, exec_delta64, idle_delta64, sample_interval64, tmp64;
1865 unsigned long total_load = this_rq->ls.load.weight;
1866 unsigned long this_load = total_load;
1867 struct load_stat *ls = &this_rq->ls;
1868 u64 now = __rq_clock(this_rq);
1869 int i, scale;
1870
1871 this_rq->nr_load_updates++;
1872 if (unlikely(!(sysctl_sched_features & SCHED_FEAT_PRECISE_CPU_LOAD)))
1873 goto do_avg;
1874
1875 /* Update delta_fair/delta_exec fields first */
1876 update_curr_load(this_rq, now);
1877
1878 fair_delta64 = ls->delta_fair + 1;
1879 ls->delta_fair = 0;
1880
1881 exec_delta64 = ls->delta_exec + 1;
1882 ls->delta_exec = 0;
1883
1884 sample_interval64 = now - ls->load_update_last;
1885 ls->load_update_last = now;
1886
1887 if ((s64)sample_interval64 < (s64)TICK_NSEC)
1888 sample_interval64 = TICK_NSEC;
1889
1890 if (exec_delta64 > sample_interval64)
1891 exec_delta64 = sample_interval64;
1892
1893 idle_delta64 = sample_interval64 - exec_delta64;
1894
1895 tmp64 = div64_64(SCHED_LOAD_SCALE * exec_delta64, fair_delta64);
1896 tmp64 = div64_64(tmp64 * exec_delta64, sample_interval64);
1897
1898 this_load = (unsigned long)tmp64;
1899
1900do_avg:
1901
1902 /* Update our load: */
1903 for (i = 0, scale = 1; i < CPU_LOAD_IDX_MAX; i++, scale += scale) {
1904 unsigned long old_load, new_load;
1905
1906 /* scale is effectively 1 << i now, and >> i divides by scale */
1907
1908 old_load = this_rq->cpu_load[i];
1909 new_load = this_load;
1910
1911 this_rq->cpu_load[i] = (old_load*(scale-1) + new_load) >> i;
1912 }
2069} 1913}
2070 1914
1915#ifdef CONFIG_SMP
1916
2071/* 1917/*
2072 * double_rq_lock - safely lock two runqueues 1918 * double_rq_lock - safely lock two runqueues
2073 * 1919 *
@@ -2184,23 +2030,17 @@ void sched_exec(void)
2184 * pull_task - move a task from a remote runqueue to the local runqueue. 2030 * pull_task - move a task from a remote runqueue to the local runqueue.
2185 * Both runqueues must be locked. 2031 * Both runqueues must be locked.
2186 */ 2032 */
2187static void pull_task(struct rq *src_rq, struct prio_array *src_array, 2033static void pull_task(struct rq *src_rq, struct task_struct *p,
2188 struct task_struct *p, struct rq *this_rq, 2034 struct rq *this_rq, int this_cpu)
2189 struct prio_array *this_array, int this_cpu)
2190{ 2035{
2191 dequeue_task(p, src_array); 2036 deactivate_task(src_rq, p, 0);
2192 dec_nr_running(p, src_rq);
2193 set_task_cpu(p, this_cpu); 2037 set_task_cpu(p, this_cpu);
2194 inc_nr_running(p, this_rq); 2038 activate_task(this_rq, p, 0);
2195 enqueue_task(p, this_array);
2196 p->timestamp = (p->timestamp - src_rq->most_recent_timestamp)
2197 + this_rq->most_recent_timestamp;
2198 /* 2039 /*
2199 * Note that idle threads have a prio of MAX_PRIO, for this test 2040 * Note that idle threads have a prio of MAX_PRIO, for this test
2200 * to be always true for them. 2041 * to be always true for them.
2201 */ 2042 */
2202 if (TASK_PREEMPTS_CURR(p, this_rq)) 2043 check_preempt_curr(this_rq, p);
2203 resched_task(this_rq->curr);
2204} 2044}
2205 2045
2206/* 2046/*
@@ -2208,7 +2048,7 @@ static void pull_task(struct rq *src_rq, struct prio_array *src_array,
2208 */ 2048 */
2209static 2049static
2210int can_migrate_task(struct task_struct *p, struct rq *rq, int this_cpu, 2050int can_migrate_task(struct task_struct *p, struct rq *rq, int this_cpu,
2211 struct sched_domain *sd, enum idle_type idle, 2051 struct sched_domain *sd, enum cpu_idle_type idle,
2212 int *all_pinned) 2052 int *all_pinned)
2213{ 2053{
2214 /* 2054 /*
@@ -2225,132 +2065,67 @@ int can_migrate_task(struct task_struct *p, struct rq *rq, int this_cpu,
2225 return 0; 2065 return 0;
2226 2066
2227 /* 2067 /*
2228 * Aggressive migration if: 2068 * Aggressive migration if too many balance attempts have failed:
2229 * 1) task is cache cold, or
2230 * 2) too many balance attempts have failed.
2231 */ 2069 */
2232 2070 if (sd->nr_balance_failed > sd->cache_nice_tries)
2233 if (sd->nr_balance_failed > sd->cache_nice_tries) {
2234#ifdef CONFIG_SCHEDSTATS
2235 if (task_hot(p, rq->most_recent_timestamp, sd))
2236 schedstat_inc(sd, lb_hot_gained[idle]);
2237#endif
2238 return 1; 2071 return 1;
2239 }
2240 2072
2241 if (task_hot(p, rq->most_recent_timestamp, sd))
2242 return 0;
2243 return 1; 2073 return 1;
2244} 2074}
2245 2075
2246#define rq_best_prio(rq) min((rq)->curr->prio, (rq)->best_expired_prio) 2076static int balance_tasks(struct rq *this_rq, int this_cpu, struct rq *busiest,
2247
2248/*
2249 * move_tasks tries to move up to max_nr_move tasks and max_load_move weighted
2250 * load from busiest to this_rq, as part of a balancing operation within
2251 * "domain". Returns the number of tasks moved.
2252 *
2253 * Called with both runqueues locked.
2254 */
2255static int move_tasks(struct rq *this_rq, int this_cpu, struct rq *busiest,
2256 unsigned long max_nr_move, unsigned long max_load_move, 2077 unsigned long max_nr_move, unsigned long max_load_move,
2257 struct sched_domain *sd, enum idle_type idle, 2078 struct sched_domain *sd, enum cpu_idle_type idle,
2258 int *all_pinned) 2079 int *all_pinned, unsigned long *load_moved,
2080 int this_best_prio, int best_prio, int best_prio_seen,
2081 struct rq_iterator *iterator)
2259{ 2082{
2260 int idx, pulled = 0, pinned = 0, this_best_prio, best_prio, 2083 int pulled = 0, pinned = 0, skip_for_load;
2261 best_prio_seen, skip_for_load; 2084 struct task_struct *p;
2262 struct prio_array *array, *dst_array; 2085 long rem_load_move = max_load_move;
2263 struct list_head *head, *curr;
2264 struct task_struct *tmp;
2265 long rem_load_move;
2266 2086
2267 if (max_nr_move == 0 || max_load_move == 0) 2087 if (max_nr_move == 0 || max_load_move == 0)
2268 goto out; 2088 goto out;
2269 2089
2270 rem_load_move = max_load_move;
2271 pinned = 1; 2090 pinned = 1;
2272 this_best_prio = rq_best_prio(this_rq);
2273 best_prio = rq_best_prio(busiest);
2274 /*
2275 * Enable handling of the case where there is more than one task
2276 * with the best priority. If the current running task is one
2277 * of those with prio==best_prio we know it won't be moved
2278 * and therefore it's safe to override the skip (based on load) of
2279 * any task we find with that prio.
2280 */
2281 best_prio_seen = best_prio == busiest->curr->prio;
2282 2091
2283 /* 2092 /*
2284 * We first consider expired tasks. Those will likely not be 2093 * Start the load-balancing iterator:
2285 * executed in the near future, and they are most likely to
2286 * be cache-cold, thus switching CPUs has the least effect
2287 * on them.
2288 */ 2094 */
2289 if (busiest->expired->nr_active) { 2095 p = iterator->start(iterator->arg);
2290 array = busiest->expired; 2096next:
2291 dst_array = this_rq->expired; 2097 if (!p)
2292 } else {
2293 array = busiest->active;
2294 dst_array = this_rq->active;
2295 }
2296
2297new_array:
2298 /* Start searching at priority 0: */
2299 idx = 0;
2300skip_bitmap:
2301 if (!idx)
2302 idx = sched_find_first_bit(array->bitmap);
2303 else
2304 idx = find_next_bit(array->bitmap, MAX_PRIO, idx);
2305 if (idx >= MAX_PRIO) {
2306 if (array == busiest->expired && busiest->active->nr_active) {
2307 array = busiest->active;
2308 dst_array = this_rq->active;
2309 goto new_array;
2310 }
2311 goto out; 2098 goto out;
2312 }
2313
2314 head = array->queue + idx;
2315 curr = head->prev;
2316skip_queue:
2317 tmp = list_entry(curr, struct task_struct, run_list);
2318
2319 curr = curr->prev;
2320
2321 /* 2099 /*
2322 * To help distribute high priority tasks accross CPUs we don't 2100 * To help distribute high priority tasks accross CPUs we don't
2323 * skip a task if it will be the highest priority task (i.e. smallest 2101 * skip a task if it will be the highest priority task (i.e. smallest
2324 * prio value) on its new queue regardless of its load weight 2102 * prio value) on its new queue regardless of its load weight
2325 */ 2103 */
2326 skip_for_load = tmp->load_weight > rem_load_move; 2104 skip_for_load = (p->se.load.weight >> 1) > rem_load_move +
2327 if (skip_for_load && idx < this_best_prio) 2105 SCHED_LOAD_SCALE_FUZZ;
2328 skip_for_load = !best_prio_seen && idx == best_prio; 2106 if (skip_for_load && p->prio < this_best_prio)
2107 skip_for_load = !best_prio_seen && p->prio == best_prio;
2329 if (skip_for_load || 2108 if (skip_for_load ||
2330 !can_migrate_task(tmp, busiest, this_cpu, sd, idle, &pinned)) { 2109 !can_migrate_task(p, busiest, this_cpu, sd, idle, &pinned)) {
2331 2110
2332 best_prio_seen |= idx == best_prio; 2111 best_prio_seen |= p->prio == best_prio;
2333 if (curr != head) 2112 p = iterator->next(iterator->arg);
2334 goto skip_queue; 2113 goto next;
2335 idx++;
2336 goto skip_bitmap;
2337 } 2114 }
2338 2115
2339 pull_task(busiest, array, tmp, this_rq, dst_array, this_cpu); 2116 pull_task(busiest, p, this_rq, this_cpu);
2340 pulled++; 2117 pulled++;
2341 rem_load_move -= tmp->load_weight; 2118 rem_load_move -= p->se.load.weight;
2342 2119
2343 /* 2120 /*
2344 * We only want to steal up to the prescribed number of tasks 2121 * We only want to steal up to the prescribed number of tasks
2345 * and the prescribed amount of weighted load. 2122 * and the prescribed amount of weighted load.
2346 */ 2123 */
2347 if (pulled < max_nr_move && rem_load_move > 0) { 2124 if (pulled < max_nr_move && rem_load_move > 0) {
2348 if (idx < this_best_prio) 2125 if (p->prio < this_best_prio)
2349 this_best_prio = idx; 2126 this_best_prio = p->prio;
2350 if (curr != head) 2127 p = iterator->next(iterator->arg);
2351 goto skip_queue; 2128 goto next;
2352 idx++;
2353 goto skip_bitmap;
2354 } 2129 }
2355out: 2130out:
2356 /* 2131 /*
@@ -2362,18 +2137,48 @@ out:
2362 2137
2363 if (all_pinned) 2138 if (all_pinned)
2364 *all_pinned = pinned; 2139 *all_pinned = pinned;
2140 *load_moved = max_load_move - rem_load_move;
2365 return pulled; 2141 return pulled;
2366} 2142}
2367 2143
2368/* 2144/*
2145 * move_tasks tries to move up to max_nr_move tasks and max_load_move weighted
2146 * load from busiest to this_rq, as part of a balancing operation within
2147 * "domain". Returns the number of tasks moved.
2148 *
2149 * Called with both runqueues locked.
2150 */
2151static int move_tasks(struct rq *this_rq, int this_cpu, struct rq *busiest,
2152 unsigned long max_nr_move, unsigned long max_load_move,
2153 struct sched_domain *sd, enum cpu_idle_type idle,
2154 int *all_pinned)
2155{
2156 struct sched_class *class = sched_class_highest;
2157 unsigned long load_moved, total_nr_moved = 0, nr_moved;
2158 long rem_load_move = max_load_move;
2159
2160 do {
2161 nr_moved = class->load_balance(this_rq, this_cpu, busiest,
2162 max_nr_move, (unsigned long)rem_load_move,
2163 sd, idle, all_pinned, &load_moved);
2164 total_nr_moved += nr_moved;
2165 max_nr_move -= nr_moved;
2166 rem_load_move -= load_moved;
2167 class = class->next;
2168 } while (class && max_nr_move && rem_load_move > 0);
2169
2170 return total_nr_moved;
2171}
2172
2173/*
2369 * find_busiest_group finds and returns the busiest CPU group within the 2174 * find_busiest_group finds and returns the busiest CPU group within the
2370 * domain. It calculates and returns the amount of weighted load which 2175 * domain. It calculates and returns the amount of weighted load which
2371 * should be moved to restore balance via the imbalance parameter. 2176 * should be moved to restore balance via the imbalance parameter.
2372 */ 2177 */
2373static struct sched_group * 2178static struct sched_group *
2374find_busiest_group(struct sched_domain *sd, int this_cpu, 2179find_busiest_group(struct sched_domain *sd, int this_cpu,
2375 unsigned long *imbalance, enum idle_type idle, int *sd_idle, 2180 unsigned long *imbalance, enum cpu_idle_type idle,
2376 cpumask_t *cpus, int *balance) 2181 int *sd_idle, cpumask_t *cpus, int *balance)
2377{ 2182{
2378 struct sched_group *busiest = NULL, *this = NULL, *group = sd->groups; 2183 struct sched_group *busiest = NULL, *this = NULL, *group = sd->groups;
2379 unsigned long max_load, avg_load, total_load, this_load, total_pwr; 2184 unsigned long max_load, avg_load, total_load, this_load, total_pwr;
@@ -2391,9 +2196,9 @@ find_busiest_group(struct sched_domain *sd, int this_cpu,
2391 max_load = this_load = total_load = total_pwr = 0; 2196 max_load = this_load = total_load = total_pwr = 0;
2392 busiest_load_per_task = busiest_nr_running = 0; 2197 busiest_load_per_task = busiest_nr_running = 0;
2393 this_load_per_task = this_nr_running = 0; 2198 this_load_per_task = this_nr_running = 0;
2394 if (idle == NOT_IDLE) 2199 if (idle == CPU_NOT_IDLE)
2395 load_idx = sd->busy_idx; 2200 load_idx = sd->busy_idx;
2396 else if (idle == NEWLY_IDLE) 2201 else if (idle == CPU_NEWLY_IDLE)
2397 load_idx = sd->newidle_idx; 2202 load_idx = sd->newidle_idx;
2398 else 2203 else
2399 load_idx = sd->idle_idx; 2204 load_idx = sd->idle_idx;
@@ -2437,7 +2242,7 @@ find_busiest_group(struct sched_domain *sd, int this_cpu,
2437 2242
2438 avg_load += load; 2243 avg_load += load;
2439 sum_nr_running += rq->nr_running; 2244 sum_nr_running += rq->nr_running;
2440 sum_weighted_load += rq->raw_weighted_load; 2245 sum_weighted_load += weighted_cpuload(i);
2441 } 2246 }
2442 2247
2443 /* 2248 /*
@@ -2477,8 +2282,9 @@ find_busiest_group(struct sched_domain *sd, int this_cpu,
2477 * Busy processors will not participate in power savings 2282 * Busy processors will not participate in power savings
2478 * balance. 2283 * balance.
2479 */ 2284 */
2480 if (idle == NOT_IDLE || !(sd->flags & SD_POWERSAVINGS_BALANCE)) 2285 if (idle == CPU_NOT_IDLE ||
2481 goto group_next; 2286 !(sd->flags & SD_POWERSAVINGS_BALANCE))
2287 goto group_next;
2482 2288
2483 /* 2289 /*
2484 * If the local group is idle or completely loaded 2290 * If the local group is idle or completely loaded
@@ -2488,42 +2294,42 @@ find_busiest_group(struct sched_domain *sd, int this_cpu,
2488 !this_nr_running)) 2294 !this_nr_running))
2489 power_savings_balance = 0; 2295 power_savings_balance = 0;
2490 2296
2491 /* 2297 /*
2492 * If a group is already running at full capacity or idle, 2298 * If a group is already running at full capacity or idle,
2493 * don't include that group in power savings calculations 2299 * don't include that group in power savings calculations
2494 */ 2300 */
2495 if (!power_savings_balance || sum_nr_running >= group_capacity 2301 if (!power_savings_balance || sum_nr_running >= group_capacity
2496 || !sum_nr_running) 2302 || !sum_nr_running)
2497 goto group_next; 2303 goto group_next;
2498 2304
2499 /* 2305 /*
2500 * Calculate the group which has the least non-idle load. 2306 * Calculate the group which has the least non-idle load.
2501 * This is the group from where we need to pick up the load 2307 * This is the group from where we need to pick up the load
2502 * for saving power 2308 * for saving power
2503 */ 2309 */
2504 if ((sum_nr_running < min_nr_running) || 2310 if ((sum_nr_running < min_nr_running) ||
2505 (sum_nr_running == min_nr_running && 2311 (sum_nr_running == min_nr_running &&
2506 first_cpu(group->cpumask) < 2312 first_cpu(group->cpumask) <
2507 first_cpu(group_min->cpumask))) { 2313 first_cpu(group_min->cpumask))) {
2508 group_min = group; 2314 group_min = group;
2509 min_nr_running = sum_nr_running; 2315 min_nr_running = sum_nr_running;
2510 min_load_per_task = sum_weighted_load / 2316 min_load_per_task = sum_weighted_load /
2511 sum_nr_running; 2317 sum_nr_running;
2512 } 2318 }
2513 2319
2514 /* 2320 /*
2515 * Calculate the group which is almost near its 2321 * Calculate the group which is almost near its
2516 * capacity but still has some space to pick up some load 2322 * capacity but still has some space to pick up some load
2517 * from other group and save more power 2323 * from other group and save more power
2518 */ 2324 */
2519 if (sum_nr_running <= group_capacity - 1) { 2325 if (sum_nr_running <= group_capacity - 1) {
2520 if (sum_nr_running > leader_nr_running || 2326 if (sum_nr_running > leader_nr_running ||
2521 (sum_nr_running == leader_nr_running && 2327 (sum_nr_running == leader_nr_running &&
2522 first_cpu(group->cpumask) > 2328 first_cpu(group->cpumask) >
2523 first_cpu(group_leader->cpumask))) { 2329 first_cpu(group_leader->cpumask))) {
2524 group_leader = group; 2330 group_leader = group;
2525 leader_nr_running = sum_nr_running; 2331 leader_nr_running = sum_nr_running;
2526 } 2332 }
2527 } 2333 }
2528group_next: 2334group_next:
2529#endif 2335#endif
@@ -2578,7 +2384,7 @@ group_next:
2578 * a think about bumping its value to force at least one task to be 2384 * a think about bumping its value to force at least one task to be
2579 * moved 2385 * moved
2580 */ 2386 */
2581 if (*imbalance < busiest_load_per_task) { 2387 if (*imbalance + SCHED_LOAD_SCALE_FUZZ < busiest_load_per_task/2) {
2582 unsigned long tmp, pwr_now, pwr_move; 2388 unsigned long tmp, pwr_now, pwr_move;
2583 unsigned int imbn; 2389 unsigned int imbn;
2584 2390
@@ -2592,7 +2398,8 @@ small_imbalance:
2592 } else 2398 } else
2593 this_load_per_task = SCHED_LOAD_SCALE; 2399 this_load_per_task = SCHED_LOAD_SCALE;
2594 2400
2595 if (max_load - this_load >= busiest_load_per_task * imbn) { 2401 if (max_load - this_load + SCHED_LOAD_SCALE_FUZZ >=
2402 busiest_load_per_task * imbn) {
2596 *imbalance = busiest_load_per_task; 2403 *imbalance = busiest_load_per_task;
2597 return busiest; 2404 return busiest;
2598 } 2405 }
@@ -2639,7 +2446,7 @@ small_imbalance:
2639 2446
2640out_balanced: 2447out_balanced:
2641#if defined(CONFIG_SCHED_MC) || defined(CONFIG_SCHED_SMT) 2448#if defined(CONFIG_SCHED_MC) || defined(CONFIG_SCHED_SMT)
2642 if (idle == NOT_IDLE || !(sd->flags & SD_POWERSAVINGS_BALANCE)) 2449 if (idle == CPU_NOT_IDLE || !(sd->flags & SD_POWERSAVINGS_BALANCE))
2643 goto ret; 2450 goto ret;
2644 2451
2645 if (this == group_leader && group_leader != group_min) { 2452 if (this == group_leader && group_leader != group_min) {
@@ -2656,7 +2463,7 @@ ret:
2656 * find_busiest_queue - find the busiest runqueue among the cpus in group. 2463 * find_busiest_queue - find the busiest runqueue among the cpus in group.
2657 */ 2464 */
2658static struct rq * 2465static struct rq *
2659find_busiest_queue(struct sched_group *group, enum idle_type idle, 2466find_busiest_queue(struct sched_group *group, enum cpu_idle_type idle,
2660 unsigned long imbalance, cpumask_t *cpus) 2467 unsigned long imbalance, cpumask_t *cpus)
2661{ 2468{
2662 struct rq *busiest = NULL, *rq; 2469 struct rq *busiest = NULL, *rq;
@@ -2664,17 +2471,19 @@ find_busiest_queue(struct sched_group *group, enum idle_type idle,
2664 int i; 2471 int i;
2665 2472
2666 for_each_cpu_mask(i, group->cpumask) { 2473 for_each_cpu_mask(i, group->cpumask) {
2474 unsigned long wl;
2667 2475
2668 if (!cpu_isset(i, *cpus)) 2476 if (!cpu_isset(i, *cpus))
2669 continue; 2477 continue;
2670 2478
2671 rq = cpu_rq(i); 2479 rq = cpu_rq(i);
2480 wl = weighted_cpuload(i);
2672 2481
2673 if (rq->nr_running == 1 && rq->raw_weighted_load > imbalance) 2482 if (rq->nr_running == 1 && wl > imbalance)
2674 continue; 2483 continue;
2675 2484
2676 if (rq->raw_weighted_load > max_load) { 2485 if (wl > max_load) {
2677 max_load = rq->raw_weighted_load; 2486 max_load = wl;
2678 busiest = rq; 2487 busiest = rq;
2679 } 2488 }
2680 } 2489 }
@@ -2698,7 +2507,7 @@ static inline unsigned long minus_1_or_zero(unsigned long n)
2698 * tasks if there is an imbalance. 2507 * tasks if there is an imbalance.
2699 */ 2508 */
2700static int load_balance(int this_cpu, struct rq *this_rq, 2509static int load_balance(int this_cpu, struct rq *this_rq,
2701 struct sched_domain *sd, enum idle_type idle, 2510 struct sched_domain *sd, enum cpu_idle_type idle,
2702 int *balance) 2511 int *balance)
2703{ 2512{
2704 int nr_moved, all_pinned = 0, active_balance = 0, sd_idle = 0; 2513 int nr_moved, all_pinned = 0, active_balance = 0, sd_idle = 0;
@@ -2711,10 +2520,10 @@ static int load_balance(int this_cpu, struct rq *this_rq,
2711 /* 2520 /*
2712 * When power savings policy is enabled for the parent domain, idle 2521 * When power savings policy is enabled for the parent domain, idle
2713 * sibling can pick up load irrespective of busy siblings. In this case, 2522 * sibling can pick up load irrespective of busy siblings. In this case,
2714 * let the state of idle sibling percolate up as IDLE, instead of 2523 * let the state of idle sibling percolate up as CPU_IDLE, instead of
2715 * portraying it as NOT_IDLE. 2524 * portraying it as CPU_NOT_IDLE.
2716 */ 2525 */
2717 if (idle != NOT_IDLE && sd->flags & SD_SHARE_CPUPOWER && 2526 if (idle != CPU_NOT_IDLE && sd->flags & SD_SHARE_CPUPOWER &&
2718 !test_sd_parent(sd, SD_POWERSAVINGS_BALANCE)) 2527 !test_sd_parent(sd, SD_POWERSAVINGS_BALANCE))
2719 sd_idle = 1; 2528 sd_idle = 1;
2720 2529
@@ -2848,7 +2657,7 @@ out_one_pinned:
2848 * Check this_cpu to ensure it is balanced within domain. Attempt to move 2657 * Check this_cpu to ensure it is balanced within domain. Attempt to move
2849 * tasks if there is an imbalance. 2658 * tasks if there is an imbalance.
2850 * 2659 *
2851 * Called from schedule when this_rq is about to become idle (NEWLY_IDLE). 2660 * Called from schedule when this_rq is about to become idle (CPU_NEWLY_IDLE).
2852 * this_rq is locked. 2661 * this_rq is locked.
2853 */ 2662 */
2854static int 2663static int
@@ -2865,31 +2674,31 @@ load_balance_newidle(int this_cpu, struct rq *this_rq, struct sched_domain *sd)
2865 * When power savings policy is enabled for the parent domain, idle 2674 * When power savings policy is enabled for the parent domain, idle
2866 * sibling can pick up load irrespective of busy siblings. In this case, 2675 * sibling can pick up load irrespective of busy siblings. In this case,
2867 * let the state of idle sibling percolate up as IDLE, instead of 2676 * let the state of idle sibling percolate up as IDLE, instead of
2868 * portraying it as NOT_IDLE. 2677 * portraying it as CPU_NOT_IDLE.
2869 */ 2678 */
2870 if (sd->flags & SD_SHARE_CPUPOWER && 2679 if (sd->flags & SD_SHARE_CPUPOWER &&
2871 !test_sd_parent(sd, SD_POWERSAVINGS_BALANCE)) 2680 !test_sd_parent(sd, SD_POWERSAVINGS_BALANCE))
2872 sd_idle = 1; 2681 sd_idle = 1;
2873 2682
2874 schedstat_inc(sd, lb_cnt[NEWLY_IDLE]); 2683 schedstat_inc(sd, lb_cnt[CPU_NEWLY_IDLE]);
2875redo: 2684redo:
2876 group = find_busiest_group(sd, this_cpu, &imbalance, NEWLY_IDLE, 2685 group = find_busiest_group(sd, this_cpu, &imbalance, CPU_NEWLY_IDLE,
2877 &sd_idle, &cpus, NULL); 2686 &sd_idle, &cpus, NULL);
2878 if (!group) { 2687 if (!group) {
2879 schedstat_inc(sd, lb_nobusyg[NEWLY_IDLE]); 2688 schedstat_inc(sd, lb_nobusyg[CPU_NEWLY_IDLE]);
2880 goto out_balanced; 2689 goto out_balanced;
2881 } 2690 }
2882 2691
2883 busiest = find_busiest_queue(group, NEWLY_IDLE, imbalance, 2692 busiest = find_busiest_queue(group, CPU_NEWLY_IDLE, imbalance,
2884 &cpus); 2693 &cpus);
2885 if (!busiest) { 2694 if (!busiest) {
2886 schedstat_inc(sd, lb_nobusyq[NEWLY_IDLE]); 2695 schedstat_inc(sd, lb_nobusyq[CPU_NEWLY_IDLE]);
2887 goto out_balanced; 2696 goto out_balanced;
2888 } 2697 }
2889 2698
2890 BUG_ON(busiest == this_rq); 2699 BUG_ON(busiest == this_rq);
2891 2700
2892 schedstat_add(sd, lb_imbalance[NEWLY_IDLE], imbalance); 2701 schedstat_add(sd, lb_imbalance[CPU_NEWLY_IDLE], imbalance);
2893 2702
2894 nr_moved = 0; 2703 nr_moved = 0;
2895 if (busiest->nr_running > 1) { 2704 if (busiest->nr_running > 1) {
@@ -2897,7 +2706,7 @@ redo:
2897 double_lock_balance(this_rq, busiest); 2706 double_lock_balance(this_rq, busiest);
2898 nr_moved = move_tasks(this_rq, this_cpu, busiest, 2707 nr_moved = move_tasks(this_rq, this_cpu, busiest,
2899 minus_1_or_zero(busiest->nr_running), 2708 minus_1_or_zero(busiest->nr_running),
2900 imbalance, sd, NEWLY_IDLE, NULL); 2709 imbalance, sd, CPU_NEWLY_IDLE, NULL);
2901 spin_unlock(&busiest->lock); 2710 spin_unlock(&busiest->lock);
2902 2711
2903 if (!nr_moved) { 2712 if (!nr_moved) {
@@ -2908,7 +2717,7 @@ redo:
2908 } 2717 }
2909 2718
2910 if (!nr_moved) { 2719 if (!nr_moved) {
2911 schedstat_inc(sd, lb_failed[NEWLY_IDLE]); 2720 schedstat_inc(sd, lb_failed[CPU_NEWLY_IDLE]);
2912 if (!sd_idle && sd->flags & SD_SHARE_CPUPOWER && 2721 if (!sd_idle && sd->flags & SD_SHARE_CPUPOWER &&
2913 !test_sd_parent(sd, SD_POWERSAVINGS_BALANCE)) 2722 !test_sd_parent(sd, SD_POWERSAVINGS_BALANCE))
2914 return -1; 2723 return -1;
@@ -2918,7 +2727,7 @@ redo:
2918 return nr_moved; 2727 return nr_moved;
2919 2728
2920out_balanced: 2729out_balanced:
2921 schedstat_inc(sd, lb_balanced[NEWLY_IDLE]); 2730 schedstat_inc(sd, lb_balanced[CPU_NEWLY_IDLE]);
2922 if (!sd_idle && sd->flags & SD_SHARE_CPUPOWER && 2731 if (!sd_idle && sd->flags & SD_SHARE_CPUPOWER &&
2923 !test_sd_parent(sd, SD_POWERSAVINGS_BALANCE)) 2732 !test_sd_parent(sd, SD_POWERSAVINGS_BALANCE))
2924 return -1; 2733 return -1;
@@ -2934,8 +2743,8 @@ out_balanced:
2934static void idle_balance(int this_cpu, struct rq *this_rq) 2743static void idle_balance(int this_cpu, struct rq *this_rq)
2935{ 2744{
2936 struct sched_domain *sd; 2745 struct sched_domain *sd;
2937 int pulled_task = 0; 2746 int pulled_task = -1;
2938 unsigned long next_balance = jiffies + 60 * HZ; 2747 unsigned long next_balance = jiffies + HZ;
2939 2748
2940 for_each_domain(this_cpu, sd) { 2749 for_each_domain(this_cpu, sd) {
2941 unsigned long interval; 2750 unsigned long interval;
@@ -2954,12 +2763,13 @@ static void idle_balance(int this_cpu, struct rq *this_rq)
2954 if (pulled_task) 2763 if (pulled_task)
2955 break; 2764 break;
2956 } 2765 }
2957 if (!pulled_task) 2766 if (pulled_task || time_after(jiffies, this_rq->next_balance)) {
2958 /* 2767 /*
2959 * We are going idle. next_balance may be set based on 2768 * We are going idle. next_balance may be set based on
2960 * a busy processor. So reset next_balance. 2769 * a busy processor. So reset next_balance.
2961 */ 2770 */
2962 this_rq->next_balance = next_balance; 2771 this_rq->next_balance = next_balance;
2772 }
2963} 2773}
2964 2774
2965/* 2775/*
@@ -3003,7 +2813,7 @@ static void active_load_balance(struct rq *busiest_rq, int busiest_cpu)
3003 schedstat_inc(sd, alb_cnt); 2813 schedstat_inc(sd, alb_cnt);
3004 2814
3005 if (move_tasks(target_rq, target_cpu, busiest_rq, 1, 2815 if (move_tasks(target_rq, target_cpu, busiest_rq, 1,
3006 RTPRIO_TO_LOAD_WEIGHT(100), sd, SCHED_IDLE, 2816 RTPRIO_TO_LOAD_WEIGHT(100), sd, CPU_IDLE,
3007 NULL)) 2817 NULL))
3008 schedstat_inc(sd, alb_pushed); 2818 schedstat_inc(sd, alb_pushed);
3009 else 2819 else
@@ -3012,32 +2822,6 @@ static void active_load_balance(struct rq *busiest_rq, int busiest_cpu)
3012 spin_unlock(&target_rq->lock); 2822 spin_unlock(&target_rq->lock);
3013} 2823}
3014 2824
3015static void update_load(struct rq *this_rq)
3016{
3017 unsigned long this_load;
3018 unsigned int i, scale;
3019
3020 this_load = this_rq->raw_weighted_load;
3021
3022 /* Update our load: */
3023 for (i = 0, scale = 1; i < 3; i++, scale += scale) {
3024 unsigned long old_load, new_load;
3025
3026 /* scale is effectively 1 << i now, and >> i divides by scale */
3027
3028 old_load = this_rq->cpu_load[i];
3029 new_load = this_load;
3030 /*
3031 * Round up the averaging division if load is increasing. This
3032 * prevents us from getting stuck on 9 if the load is 10, for
3033 * example.
3034 */
3035 if (new_load > old_load)
3036 new_load += scale-1;
3037 this_rq->cpu_load[i] = (old_load*(scale-1) + new_load) >> i;
3038 }
3039}
3040
3041#ifdef CONFIG_NO_HZ 2825#ifdef CONFIG_NO_HZ
3042static struct { 2826static struct {
3043 atomic_t load_balancer; 2827 atomic_t load_balancer;
@@ -3120,7 +2904,7 @@ static DEFINE_SPINLOCK(balancing);
3120 * 2904 *
3121 * Balancing parameters are set up in arch_init_sched_domains. 2905 * Balancing parameters are set up in arch_init_sched_domains.
3122 */ 2906 */
3123static inline void rebalance_domains(int cpu, enum idle_type idle) 2907static inline void rebalance_domains(int cpu, enum cpu_idle_type idle)
3124{ 2908{
3125 int balance = 1; 2909 int balance = 1;
3126 struct rq *rq = cpu_rq(cpu); 2910 struct rq *rq = cpu_rq(cpu);
@@ -3134,13 +2918,16 @@ static inline void rebalance_domains(int cpu, enum idle_type idle)
3134 continue; 2918 continue;
3135 2919
3136 interval = sd->balance_interval; 2920 interval = sd->balance_interval;
3137 if (idle != SCHED_IDLE) 2921 if (idle != CPU_IDLE)
3138 interval *= sd->busy_factor; 2922 interval *= sd->busy_factor;
3139 2923
3140 /* scale ms to jiffies */ 2924 /* scale ms to jiffies */
3141 interval = msecs_to_jiffies(interval); 2925 interval = msecs_to_jiffies(interval);
3142 if (unlikely(!interval)) 2926 if (unlikely(!interval))
3143 interval = 1; 2927 interval = 1;
2928 if (interval > HZ*NR_CPUS/10)
2929 interval = HZ*NR_CPUS/10;
2930
3144 2931
3145 if (sd->flags & SD_SERIALIZE) { 2932 if (sd->flags & SD_SERIALIZE) {
3146 if (!spin_trylock(&balancing)) 2933 if (!spin_trylock(&balancing))
@@ -3154,7 +2941,7 @@ static inline void rebalance_domains(int cpu, enum idle_type idle)
3154 * longer idle, or one of our SMT siblings is 2941 * longer idle, or one of our SMT siblings is
3155 * not idle. 2942 * not idle.
3156 */ 2943 */
3157 idle = NOT_IDLE; 2944 idle = CPU_NOT_IDLE;
3158 } 2945 }
3159 sd->last_balance = jiffies; 2946 sd->last_balance = jiffies;
3160 } 2947 }
@@ -3182,11 +2969,12 @@ out:
3182 */ 2969 */
3183static void run_rebalance_domains(struct softirq_action *h) 2970static void run_rebalance_domains(struct softirq_action *h)
3184{ 2971{
3185 int local_cpu = smp_processor_id(); 2972 int this_cpu = smp_processor_id();
3186 struct rq *local_rq = cpu_rq(local_cpu); 2973 struct rq *this_rq = cpu_rq(this_cpu);
3187 enum idle_type idle = local_rq->idle_at_tick ? SCHED_IDLE : NOT_IDLE; 2974 enum cpu_idle_type idle = this_rq->idle_at_tick ?
2975 CPU_IDLE : CPU_NOT_IDLE;
3188 2976
3189 rebalance_domains(local_cpu, idle); 2977 rebalance_domains(this_cpu, idle);
3190 2978
3191#ifdef CONFIG_NO_HZ 2979#ifdef CONFIG_NO_HZ
3192 /* 2980 /*
@@ -3194,13 +2982,13 @@ static void run_rebalance_domains(struct softirq_action *h)
3194 * balancing on behalf of the other idle cpus whose ticks are 2982 * balancing on behalf of the other idle cpus whose ticks are
3195 * stopped. 2983 * stopped.
3196 */ 2984 */
3197 if (local_rq->idle_at_tick && 2985 if (this_rq->idle_at_tick &&
3198 atomic_read(&nohz.load_balancer) == local_cpu) { 2986 atomic_read(&nohz.load_balancer) == this_cpu) {
3199 cpumask_t cpus = nohz.cpu_mask; 2987 cpumask_t cpus = nohz.cpu_mask;
3200 struct rq *rq; 2988 struct rq *rq;
3201 int balance_cpu; 2989 int balance_cpu;
3202 2990
3203 cpu_clear(local_cpu, cpus); 2991 cpu_clear(this_cpu, cpus);
3204 for_each_cpu_mask(balance_cpu, cpus) { 2992 for_each_cpu_mask(balance_cpu, cpus) {
3205 /* 2993 /*
3206 * If this cpu gets work to do, stop the load balancing 2994 * If this cpu gets work to do, stop the load balancing
@@ -3213,8 +3001,8 @@ static void run_rebalance_domains(struct softirq_action *h)
3213 rebalance_domains(balance_cpu, SCHED_IDLE); 3001 rebalance_domains(balance_cpu, SCHED_IDLE);
3214 3002
3215 rq = cpu_rq(balance_cpu); 3003 rq = cpu_rq(balance_cpu);
3216 if (time_after(local_rq->next_balance, rq->next_balance)) 3004 if (time_after(this_rq->next_balance, rq->next_balance))
3217 local_rq->next_balance = rq->next_balance; 3005 this_rq->next_balance = rq->next_balance;
3218 } 3006 }
3219 } 3007 }
3220#endif 3008#endif
@@ -3227,9 +3015,8 @@ static void run_rebalance_domains(struct softirq_action *h)
3227 * idle load balancing owner or decide to stop the periodic load balancing, 3015 * idle load balancing owner or decide to stop the periodic load balancing,
3228 * if the whole system is idle. 3016 * if the whole system is idle.
3229 */ 3017 */
3230static inline void trigger_load_balance(int cpu) 3018static inline void trigger_load_balance(struct rq *rq, int cpu)
3231{ 3019{
3232 struct rq *rq = cpu_rq(cpu);
3233#ifdef CONFIG_NO_HZ 3020#ifdef CONFIG_NO_HZ
3234 /* 3021 /*
3235 * If we were in the nohz mode recently and busy at the current 3022 * If we were in the nohz mode recently and busy at the current
@@ -3281,13 +3068,29 @@ static inline void trigger_load_balance(int cpu)
3281 if (time_after_eq(jiffies, rq->next_balance)) 3068 if (time_after_eq(jiffies, rq->next_balance))
3282 raise_softirq(SCHED_SOFTIRQ); 3069 raise_softirq(SCHED_SOFTIRQ);
3283} 3070}
3284#else 3071
3072#else /* CONFIG_SMP */
3073
3285/* 3074/*
3286 * on UP we do not need to balance between CPUs: 3075 * on UP we do not need to balance between CPUs:
3287 */ 3076 */
3288static inline void idle_balance(int cpu, struct rq *rq) 3077static inline void idle_balance(int cpu, struct rq *rq)
3289{ 3078{
3290} 3079}
3080
3081/* Avoid "used but not defined" warning on UP */
3082static int balance_tasks(struct rq *this_rq, int this_cpu, struct rq *busiest,
3083 unsigned long max_nr_move, unsigned long max_load_move,
3084 struct sched_domain *sd, enum cpu_idle_type idle,
3085 int *all_pinned, unsigned long *load_moved,
3086 int this_best_prio, int best_prio, int best_prio_seen,
3087 struct rq_iterator *iterator)
3088{
3089 *load_moved = 0;
3090
3091 return 0;
3092}
3093
3291#endif 3094#endif
3292 3095
3293DEFINE_PER_CPU(struct kernel_stat, kstat); 3096DEFINE_PER_CPU(struct kernel_stat, kstat);
@@ -3295,54 +3098,28 @@ DEFINE_PER_CPU(struct kernel_stat, kstat);
3295EXPORT_PER_CPU_SYMBOL(kstat); 3098EXPORT_PER_CPU_SYMBOL(kstat);
3296 3099
3297/* 3100/*
3298 * This is called on clock ticks and on context switches. 3101 * Return p->sum_exec_runtime plus any more ns on the sched_clock
3299 * Bank in p->sched_time the ns elapsed since the last tick or switch. 3102 * that have not yet been banked in case the task is currently running.
3300 */
3301static inline void
3302update_cpu_clock(struct task_struct *p, struct rq *rq, unsigned long long now)
3303{
3304 p->sched_time += now - p->last_ran;
3305 p->last_ran = rq->most_recent_timestamp = now;
3306}
3307
3308/*
3309 * Return current->sched_time plus any more ns on the sched_clock
3310 * that have not yet been banked.
3311 */ 3103 */
3312unsigned long long current_sched_time(const struct task_struct *p) 3104unsigned long long task_sched_runtime(struct task_struct *p)
3313{ 3105{
3314 unsigned long long ns;
3315 unsigned long flags; 3106 unsigned long flags;
3107 u64 ns, delta_exec;
3108 struct rq *rq;
3316 3109
3317 local_irq_save(flags); 3110 rq = task_rq_lock(p, &flags);
3318 ns = p->sched_time + sched_clock() - p->last_ran; 3111 ns = p->se.sum_exec_runtime;
3319 local_irq_restore(flags); 3112 if (rq->curr == p) {
3113 delta_exec = rq_clock(rq) - p->se.exec_start;
3114 if ((s64)delta_exec > 0)
3115 ns += delta_exec;
3116 }
3117 task_rq_unlock(rq, &flags);
3320 3118
3321 return ns; 3119 return ns;
3322} 3120}
3323 3121
3324/* 3122/*
3325 * We place interactive tasks back into the active array, if possible.
3326 *
3327 * To guarantee that this does not starve expired tasks we ignore the
3328 * interactivity of a task if the first expired task had to wait more
3329 * than a 'reasonable' amount of time. This deadline timeout is
3330 * load-dependent, as the frequency of array switched decreases with
3331 * increasing number of running tasks. We also ignore the interactivity
3332 * if a better static_prio task has expired:
3333 */
3334static inline int expired_starving(struct rq *rq)
3335{
3336 if (rq->curr->static_prio > rq->best_expired_prio)
3337 return 1;
3338 if (!STARVATION_LIMIT || !rq->expired_timestamp)
3339 return 0;
3340 if (jiffies - rq->expired_timestamp > STARVATION_LIMIT * rq->nr_running)
3341 return 1;
3342 return 0;
3343}
3344
3345/*
3346 * Account user cpu time to a process. 3123 * Account user cpu time to a process.
3347 * @p: the process that the cpu time gets accounted to 3124 * @p: the process that the cpu time gets accounted to
3348 * @hardirq_offset: the offset to subtract from hardirq_count() 3125 * @hardirq_offset: the offset to subtract from hardirq_count()
@@ -3415,81 +3192,6 @@ void account_steal_time(struct task_struct *p, cputime_t steal)
3415 cpustat->steal = cputime64_add(cpustat->steal, tmp); 3192 cpustat->steal = cputime64_add(cpustat->steal, tmp);
3416} 3193}
3417 3194
3418static void task_running_tick(struct rq *rq, struct task_struct *p)
3419{
3420 if (p->array != rq->active) {
3421 /* Task has expired but was not scheduled yet */
3422 set_tsk_need_resched(p);
3423 return;
3424 }
3425 spin_lock(&rq->lock);
3426 /*
3427 * The task was running during this tick - update the
3428 * time slice counter. Note: we do not update a thread's
3429 * priority until it either goes to sleep or uses up its
3430 * timeslice. This makes it possible for interactive tasks
3431 * to use up their timeslices at their highest priority levels.
3432 */
3433 if (rt_task(p)) {
3434 /*
3435 * RR tasks need a special form of timeslice management.
3436 * FIFO tasks have no timeslices.
3437 */
3438 if ((p->policy == SCHED_RR) && !--p->time_slice) {
3439 p->time_slice = task_timeslice(p);
3440 p->first_time_slice = 0;
3441 set_tsk_need_resched(p);
3442
3443 /* put it at the end of the queue: */
3444 requeue_task(p, rq->active);
3445 }
3446 goto out_unlock;
3447 }
3448 if (!--p->time_slice) {
3449 dequeue_task(p, rq->active);
3450 set_tsk_need_resched(p);
3451 p->prio = effective_prio(p);
3452 p->time_slice = task_timeslice(p);
3453 p->first_time_slice = 0;
3454
3455 if (!rq->expired_timestamp)
3456 rq->expired_timestamp = jiffies;
3457 if (!TASK_INTERACTIVE(p) || expired_starving(rq)) {
3458 enqueue_task(p, rq->expired);
3459 if (p->static_prio < rq->best_expired_prio)
3460 rq->best_expired_prio = p->static_prio;
3461 } else
3462 enqueue_task(p, rq->active);
3463 } else {
3464 /*
3465 * Prevent a too long timeslice allowing a task to monopolize
3466 * the CPU. We do this by splitting up the timeslice into
3467 * smaller pieces.
3468 *
3469 * Note: this does not mean the task's timeslices expire or
3470 * get lost in any way, they just might be preempted by
3471 * another task of equal priority. (one with higher
3472 * priority would have preempted this task already.) We
3473 * requeue this task to the end of the list on this priority
3474 * level, which is in essence a round-robin of tasks with
3475 * equal priority.
3476 *
3477 * This only applies to tasks in the interactive
3478 * delta range with at least TIMESLICE_GRANULARITY to requeue.
3479 */
3480 if (TASK_INTERACTIVE(p) && !((task_timeslice(p) -
3481 p->time_slice) % TIMESLICE_GRANULARITY(p)) &&
3482 (p->time_slice >= TIMESLICE_GRANULARITY(p)) &&
3483 (p->array == rq->active)) {
3484
3485 requeue_task(p, rq->active);
3486 set_tsk_need_resched(p);
3487 }
3488 }
3489out_unlock:
3490 spin_unlock(&rq->lock);
3491}
3492
3493/* 3195/*
3494 * This function gets called by the timer code, with HZ frequency. 3196 * This function gets called by the timer code, with HZ frequency.
3495 * We call it with interrupts disabled. 3197 * We call it with interrupts disabled.
@@ -3499,20 +3201,19 @@ out_unlock:
3499 */ 3201 */
3500void scheduler_tick(void) 3202void scheduler_tick(void)
3501{ 3203{
3502 unsigned long long now = sched_clock();
3503 struct task_struct *p = current;
3504 int cpu = smp_processor_id(); 3204 int cpu = smp_processor_id();
3505 int idle_at_tick = idle_cpu(cpu);
3506 struct rq *rq = cpu_rq(cpu); 3205 struct rq *rq = cpu_rq(cpu);
3206 struct task_struct *curr = rq->curr;
3507 3207
3508 update_cpu_clock(p, rq, now); 3208 spin_lock(&rq->lock);
3209 if (curr != rq->idle) /* FIXME: needed? */
3210 curr->sched_class->task_tick(rq, curr);
3211 update_cpu_load(rq);
3212 spin_unlock(&rq->lock);
3509 3213
3510 if (!idle_at_tick)
3511 task_running_tick(rq, p);
3512#ifdef CONFIG_SMP 3214#ifdef CONFIG_SMP
3513 update_load(rq); 3215 rq->idle_at_tick = idle_cpu(cpu);
3514 rq->idle_at_tick = idle_at_tick; 3216 trigger_load_balance(rq, cpu);
3515 trigger_load_balance(cpu);
3516#endif 3217#endif
3517} 3218}
3518 3219
@@ -3554,170 +3255,129 @@ EXPORT_SYMBOL(sub_preempt_count);
3554 3255
3555#endif 3256#endif
3556 3257
3557static inline int interactive_sleep(enum sleep_type sleep_type) 3258/*
3259 * Print scheduling while atomic bug:
3260 */
3261static noinline void __schedule_bug(struct task_struct *prev)
3558{ 3262{
3559 return (sleep_type == SLEEP_INTERACTIVE || 3263 printk(KERN_ERR "BUG: scheduling while atomic: %s/0x%08x/%d\n",
3560 sleep_type == SLEEP_INTERRUPTED); 3264 prev->comm, preempt_count(), prev->pid);
3265 debug_show_held_locks(prev);
3266 if (irqs_disabled())
3267 print_irqtrace_events(prev);
3268 dump_stack();
3561} 3269}
3562 3270
3563/* 3271/*
3564 * schedule() is the main scheduler function. 3272 * Various schedule()-time debugging checks and statistics:
3565 */ 3273 */
3566asmlinkage void __sched schedule(void) 3274static inline void schedule_debug(struct task_struct *prev)
3567{ 3275{
3568 struct task_struct *prev, *next;
3569 struct prio_array *array;
3570 struct list_head *queue;
3571 unsigned long long now;
3572 unsigned long run_time;
3573 int cpu, idx, new_prio;
3574 long *switch_count;
3575 struct rq *rq;
3576
3577 /* 3276 /*
3578 * Test if we are atomic. Since do_exit() needs to call into 3277 * Test if we are atomic. Since do_exit() needs to call into
3579 * schedule() atomically, we ignore that path for now. 3278 * schedule() atomically, we ignore that path for now.
3580 * Otherwise, whine if we are scheduling when we should not be. 3279 * Otherwise, whine if we are scheduling when we should not be.
3581 */ 3280 */
3582 if (unlikely(in_atomic() && !current->exit_state)) { 3281 if (unlikely(in_atomic_preempt_off()) && unlikely(!prev->exit_state))
3583 printk(KERN_ERR "BUG: scheduling while atomic: " 3282 __schedule_bug(prev);
3584 "%s/0x%08x/%d\n",
3585 current->comm, preempt_count(), current->pid);
3586 debug_show_held_locks(current);
3587 if (irqs_disabled())
3588 print_irqtrace_events(current);
3589 dump_stack();
3590 }
3591 profile_hit(SCHED_PROFILING, __builtin_return_address(0));
3592 3283
3593need_resched: 3284 profile_hit(SCHED_PROFILING, __builtin_return_address(0));
3594 preempt_disable();
3595 prev = current;
3596 release_kernel_lock(prev);
3597need_resched_nonpreemptible:
3598 rq = this_rq();
3599 3285
3600 /* 3286 schedstat_inc(this_rq(), sched_cnt);
3601 * The idle thread is not allowed to schedule! 3287}
3602 * Remove this check after it has been exercised a bit.
3603 */
3604 if (unlikely(prev == rq->idle) && prev->state != TASK_RUNNING) {
3605 printk(KERN_ERR "bad: scheduling from the idle thread!\n");
3606 dump_stack();
3607 }
3608 3288
3609 schedstat_inc(rq, sched_cnt); 3289/*
3610 now = sched_clock(); 3290 * Pick up the highest-prio task:
3611 if (likely((long long)(now - prev->timestamp) < NS_MAX_SLEEP_AVG)) { 3291 */
3612 run_time = now - prev->timestamp; 3292static inline struct task_struct *
3613 if (unlikely((long long)(now - prev->timestamp) < 0)) 3293pick_next_task(struct rq *rq, struct task_struct *prev, u64 now)
3614 run_time = 0; 3294{
3615 } else 3295 struct sched_class *class;
3616 run_time = NS_MAX_SLEEP_AVG; 3296 struct task_struct *p;
3617 3297
3618 /* 3298 /*
3619 * Tasks charged proportionately less run_time at high sleep_avg to 3299 * Optimization: we know that if all tasks are in
3620 * delay them losing their interactive status 3300 * the fair class we can call that function directly:
3621 */ 3301 */
3622 run_time /= (CURRENT_BONUS(prev) ? : 1); 3302 if (likely(rq->nr_running == rq->cfs.nr_running)) {
3623 3303 p = fair_sched_class.pick_next_task(rq, now);
3624 spin_lock_irq(&rq->lock); 3304 if (likely(p))
3625 3305 return p;
3626 switch_count = &prev->nivcsw;
3627 if (prev->state && !(preempt_count() & PREEMPT_ACTIVE)) {
3628 switch_count = &prev->nvcsw;
3629 if (unlikely((prev->state & TASK_INTERRUPTIBLE) &&
3630 unlikely(signal_pending(prev))))
3631 prev->state = TASK_RUNNING;
3632 else {
3633 if (prev->state == TASK_UNINTERRUPTIBLE)
3634 rq->nr_uninterruptible++;
3635 deactivate_task(prev, rq);
3636 }
3637 }
3638
3639 cpu = smp_processor_id();
3640 if (unlikely(!rq->nr_running)) {
3641 idle_balance(cpu, rq);
3642 if (!rq->nr_running) {
3643 next = rq->idle;
3644 rq->expired_timestamp = 0;
3645 goto switch_tasks;
3646 }
3647 } 3306 }
3648 3307
3649 array = rq->active; 3308 class = sched_class_highest;
3650 if (unlikely(!array->nr_active)) { 3309 for ( ; ; ) {
3310 p = class->pick_next_task(rq, now);
3311 if (p)
3312 return p;
3651 /* 3313 /*
3652 * Switch the active and expired arrays. 3314 * Will never be NULL as the idle class always
3315 * returns a non-NULL p:
3653 */ 3316 */
3654 schedstat_inc(rq, sched_switch); 3317 class = class->next;
3655 rq->active = rq->expired;
3656 rq->expired = array;
3657 array = rq->active;
3658 rq->expired_timestamp = 0;
3659 rq->best_expired_prio = MAX_PRIO;
3660 } 3318 }
3319}
3320
3321/*
3322 * schedule() is the main scheduler function.
3323 */
3324asmlinkage void __sched schedule(void)
3325{
3326 struct task_struct *prev, *next;
3327 long *switch_count;
3328 struct rq *rq;
3329 u64 now;
3330 int cpu;
3661 3331
3662 idx = sched_find_first_bit(array->bitmap); 3332need_resched:
3663 queue = array->queue + idx; 3333 preempt_disable();
3664 next = list_entry(queue->next, struct task_struct, run_list); 3334 cpu = smp_processor_id();
3335 rq = cpu_rq(cpu);
3336 rcu_qsctr_inc(cpu);
3337 prev = rq->curr;
3338 switch_count = &prev->nivcsw;
3665 3339
3666 if (!rt_task(next) && interactive_sleep(next->sleep_type)) { 3340 release_kernel_lock(prev);
3667 unsigned long long delta = now - next->timestamp; 3341need_resched_nonpreemptible:
3668 if (unlikely((long long)(now - next->timestamp) < 0))
3669 delta = 0;
3670 3342
3671 if (next->sleep_type == SLEEP_INTERACTIVE) 3343 schedule_debug(prev);
3672 delta = delta * (ON_RUNQUEUE_WEIGHT * 128 / 100) / 128;
3673 3344
3674 array = next->array; 3345 spin_lock_irq(&rq->lock);
3675 new_prio = recalc_task_prio(next, next->timestamp + delta); 3346 clear_tsk_need_resched(prev);
3676 3347
3677 if (unlikely(next->prio != new_prio)) { 3348 if (prev->state && !(preempt_count() & PREEMPT_ACTIVE)) {
3678 dequeue_task(next, array); 3349 if (unlikely((prev->state & TASK_INTERRUPTIBLE) &&
3679 next->prio = new_prio; 3350 unlikely(signal_pending(prev)))) {
3680 enqueue_task(next, array); 3351 prev->state = TASK_RUNNING;
3352 } else {
3353 deactivate_task(rq, prev, 1);
3681 } 3354 }
3355 switch_count = &prev->nvcsw;
3682 } 3356 }
3683 next->sleep_type = SLEEP_NORMAL;
3684switch_tasks:
3685 if (next == rq->idle)
3686 schedstat_inc(rq, sched_goidle);
3687 prefetch(next);
3688 prefetch_stack(next);
3689 clear_tsk_need_resched(prev);
3690 rcu_qsctr_inc(task_cpu(prev));
3691 3357
3692 update_cpu_clock(prev, rq, now); 3358 if (unlikely(!rq->nr_running))
3359 idle_balance(cpu, rq);
3693 3360
3694 prev->sleep_avg -= run_time; 3361 now = __rq_clock(rq);
3695 if ((long)prev->sleep_avg <= 0) 3362 prev->sched_class->put_prev_task(rq, prev, now);
3696 prev->sleep_avg = 0; 3363 next = pick_next_task(rq, prev, now);
3697 prev->timestamp = prev->last_ran = now;
3698 3364
3699 sched_info_switch(prev, next); 3365 sched_info_switch(prev, next);
3366
3700 if (likely(prev != next)) { 3367 if (likely(prev != next)) {
3701 next->timestamp = next->last_ran = now;
3702 rq->nr_switches++; 3368 rq->nr_switches++;
3703 rq->curr = next; 3369 rq->curr = next;
3704 ++*switch_count; 3370 ++*switch_count;
3705 3371
3706 prepare_task_switch(rq, next); 3372 context_switch(rq, prev, next); /* unlocks the rq */
3707 prev = context_switch(rq, prev, next);
3708 barrier();
3709 /*
3710 * this_rq must be evaluated again because prev may have moved
3711 * CPUs since it called schedule(), thus the 'rq' on its stack
3712 * frame will be invalid.
3713 */
3714 finish_task_switch(this_rq(), prev);
3715 } else 3373 } else
3716 spin_unlock_irq(&rq->lock); 3374 spin_unlock_irq(&rq->lock);
3717 3375
3718 prev = current; 3376 if (unlikely(reacquire_kernel_lock(current) < 0)) {
3719 if (unlikely(reacquire_kernel_lock(prev) < 0)) 3377 cpu = smp_processor_id();
3378 rq = cpu_rq(cpu);
3720 goto need_resched_nonpreemptible; 3379 goto need_resched_nonpreemptible;
3380 }
3721 preempt_enable_no_resched(); 3381 preempt_enable_no_resched();
3722 if (unlikely(test_thread_flag(TIF_NEED_RESCHED))) 3382 if (unlikely(test_thread_flag(TIF_NEED_RESCHED)))
3723 goto need_resched; 3383 goto need_resched;
@@ -4045,74 +3705,85 @@ out:
4045} 3705}
4046EXPORT_SYMBOL(wait_for_completion_interruptible_timeout); 3706EXPORT_SYMBOL(wait_for_completion_interruptible_timeout);
4047 3707
4048 3708static inline void
4049#define SLEEP_ON_VAR \ 3709sleep_on_head(wait_queue_head_t *q, wait_queue_t *wait, unsigned long *flags)
4050 unsigned long flags; \ 3710{
4051 wait_queue_t wait; \ 3711 spin_lock_irqsave(&q->lock, *flags);
4052 init_waitqueue_entry(&wait, current); 3712 __add_wait_queue(q, wait);
4053
4054#define SLEEP_ON_HEAD \
4055 spin_lock_irqsave(&q->lock,flags); \
4056 __add_wait_queue(q, &wait); \
4057 spin_unlock(&q->lock); 3713 spin_unlock(&q->lock);
3714}
4058 3715
4059#define SLEEP_ON_TAIL \ 3716static inline void
4060 spin_lock_irq(&q->lock); \ 3717sleep_on_tail(wait_queue_head_t *q, wait_queue_t *wait, unsigned long *flags)
4061 __remove_wait_queue(q, &wait); \ 3718{
4062 spin_unlock_irqrestore(&q->lock, flags); 3719 spin_lock_irq(&q->lock);
3720 __remove_wait_queue(q, wait);
3721 spin_unlock_irqrestore(&q->lock, *flags);
3722}
4063 3723
4064void fastcall __sched interruptible_sleep_on(wait_queue_head_t *q) 3724void __sched interruptible_sleep_on(wait_queue_head_t *q)
4065{ 3725{
4066 SLEEP_ON_VAR 3726 unsigned long flags;
3727 wait_queue_t wait;
3728
3729 init_waitqueue_entry(&wait, current);
4067 3730
4068 current->state = TASK_INTERRUPTIBLE; 3731 current->state = TASK_INTERRUPTIBLE;
4069 3732
4070 SLEEP_ON_HEAD 3733 sleep_on_head(q, &wait, &flags);
4071 schedule(); 3734 schedule();
4072 SLEEP_ON_TAIL 3735 sleep_on_tail(q, &wait, &flags);
4073} 3736}
4074EXPORT_SYMBOL(interruptible_sleep_on); 3737EXPORT_SYMBOL(interruptible_sleep_on);
4075 3738
4076long fastcall __sched 3739long __sched
4077interruptible_sleep_on_timeout(wait_queue_head_t *q, long timeout) 3740interruptible_sleep_on_timeout(wait_queue_head_t *q, long timeout)
4078{ 3741{
4079 SLEEP_ON_VAR 3742 unsigned long flags;
3743 wait_queue_t wait;
3744
3745 init_waitqueue_entry(&wait, current);
4080 3746
4081 current->state = TASK_INTERRUPTIBLE; 3747 current->state = TASK_INTERRUPTIBLE;
4082 3748
4083 SLEEP_ON_HEAD 3749 sleep_on_head(q, &wait, &flags);
4084 timeout = schedule_timeout(timeout); 3750 timeout = schedule_timeout(timeout);
4085 SLEEP_ON_TAIL 3751 sleep_on_tail(q, &wait, &flags);
4086 3752
4087 return timeout; 3753 return timeout;
4088} 3754}
4089EXPORT_SYMBOL(interruptible_sleep_on_timeout); 3755EXPORT_SYMBOL(interruptible_sleep_on_timeout);
4090 3756
4091void fastcall __sched sleep_on(wait_queue_head_t *q) 3757void __sched sleep_on(wait_queue_head_t *q)
4092{ 3758{
4093 SLEEP_ON_VAR 3759 unsigned long flags;
3760 wait_queue_t wait;
3761
3762 init_waitqueue_entry(&wait, current);
4094 3763
4095 current->state = TASK_UNINTERRUPTIBLE; 3764 current->state = TASK_UNINTERRUPTIBLE;
4096 3765
4097 SLEEP_ON_HEAD 3766 sleep_on_head(q, &wait, &flags);
4098 schedule(); 3767 schedule();
4099 SLEEP_ON_TAIL 3768 sleep_on_tail(q, &wait, &flags);
4100} 3769}
4101EXPORT_SYMBOL(sleep_on); 3770EXPORT_SYMBOL(sleep_on);
4102 3771
4103long fastcall __sched sleep_on_timeout(wait_queue_head_t *q, long timeout) 3772long __sched sleep_on_timeout(wait_queue_head_t *q, long timeout)
4104{ 3773{
4105 SLEEP_ON_VAR 3774 unsigned long flags;
3775 wait_queue_t wait;
3776
3777 init_waitqueue_entry(&wait, current);
4106 3778
4107 current->state = TASK_UNINTERRUPTIBLE; 3779 current->state = TASK_UNINTERRUPTIBLE;
4108 3780
4109 SLEEP_ON_HEAD 3781 sleep_on_head(q, &wait, &flags);
4110 timeout = schedule_timeout(timeout); 3782 timeout = schedule_timeout(timeout);
4111 SLEEP_ON_TAIL 3783 sleep_on_tail(q, &wait, &flags);
4112 3784
4113 return timeout; 3785 return timeout;
4114} 3786}
4115
4116EXPORT_SYMBOL(sleep_on_timeout); 3787EXPORT_SYMBOL(sleep_on_timeout);
4117 3788
4118#ifdef CONFIG_RT_MUTEXES 3789#ifdef CONFIG_RT_MUTEXES
@@ -4129,29 +3800,30 @@ EXPORT_SYMBOL(sleep_on_timeout);
4129 */ 3800 */
4130void rt_mutex_setprio(struct task_struct *p, int prio) 3801void rt_mutex_setprio(struct task_struct *p, int prio)
4131{ 3802{
4132 struct prio_array *array;
4133 unsigned long flags; 3803 unsigned long flags;
3804 int oldprio, on_rq;
4134 struct rq *rq; 3805 struct rq *rq;
4135 int oldprio; 3806 u64 now;
4136 3807
4137 BUG_ON(prio < 0 || prio > MAX_PRIO); 3808 BUG_ON(prio < 0 || prio > MAX_PRIO);
4138 3809
4139 rq = task_rq_lock(p, &flags); 3810 rq = task_rq_lock(p, &flags);
3811 now = rq_clock(rq);
4140 3812
4141 oldprio = p->prio; 3813 oldprio = p->prio;
4142 array = p->array; 3814 on_rq = p->se.on_rq;
4143 if (array) 3815 if (on_rq)
4144 dequeue_task(p, array); 3816 dequeue_task(rq, p, 0, now);
3817
3818 if (rt_prio(prio))
3819 p->sched_class = &rt_sched_class;
3820 else
3821 p->sched_class = &fair_sched_class;
3822
4145 p->prio = prio; 3823 p->prio = prio;
4146 3824
4147 if (array) { 3825 if (on_rq) {
4148 /* 3826 enqueue_task(rq, p, 0, now);
4149 * If changing to an RT priority then queue it
4150 * in the active array!
4151 */
4152 if (rt_task(p))
4153 array = rq->active;
4154 enqueue_task(p, array);
4155 /* 3827 /*
4156 * Reschedule if we are currently running on this runqueue and 3828 * Reschedule if we are currently running on this runqueue and
4157 * our priority decreased, or if we are not currently running on 3829 * our priority decreased, or if we are not currently running on
@@ -4160,8 +3832,9 @@ void rt_mutex_setprio(struct task_struct *p, int prio)
4160 if (task_running(rq, p)) { 3832 if (task_running(rq, p)) {
4161 if (p->prio > oldprio) 3833 if (p->prio > oldprio)
4162 resched_task(rq->curr); 3834 resched_task(rq->curr);
4163 } else if (TASK_PREEMPTS_CURR(p, rq)) 3835 } else {
4164 resched_task(rq->curr); 3836 check_preempt_curr(rq, p);
3837 }
4165 } 3838 }
4166 task_rq_unlock(rq, &flags); 3839 task_rq_unlock(rq, &flags);
4167} 3840}
@@ -4170,10 +3843,10 @@ void rt_mutex_setprio(struct task_struct *p, int prio)
4170 3843
4171void set_user_nice(struct task_struct *p, long nice) 3844void set_user_nice(struct task_struct *p, long nice)
4172{ 3845{
4173 struct prio_array *array; 3846 int old_prio, delta, on_rq;
4174 int old_prio, delta;
4175 unsigned long flags; 3847 unsigned long flags;
4176 struct rq *rq; 3848 struct rq *rq;
3849 u64 now;
4177 3850
4178 if (TASK_NICE(p) == nice || nice < -20 || nice > 19) 3851 if (TASK_NICE(p) == nice || nice < -20 || nice > 19)
4179 return; 3852 return;
@@ -4182,20 +3855,21 @@ void set_user_nice(struct task_struct *p, long nice)
4182 * the task might be in the middle of scheduling on another CPU. 3855 * the task might be in the middle of scheduling on another CPU.
4183 */ 3856 */
4184 rq = task_rq_lock(p, &flags); 3857 rq = task_rq_lock(p, &flags);
3858 now = rq_clock(rq);
4185 /* 3859 /*
4186 * The RT priorities are set via sched_setscheduler(), but we still 3860 * The RT priorities are set via sched_setscheduler(), but we still
4187 * allow the 'normal' nice value to be set - but as expected 3861 * allow the 'normal' nice value to be set - but as expected
4188 * it wont have any effect on scheduling until the task is 3862 * it wont have any effect on scheduling until the task is
4189 * not SCHED_NORMAL/SCHED_BATCH: 3863 * SCHED_FIFO/SCHED_RR:
4190 */ 3864 */
4191 if (has_rt_policy(p)) { 3865 if (task_has_rt_policy(p)) {
4192 p->static_prio = NICE_TO_PRIO(nice); 3866 p->static_prio = NICE_TO_PRIO(nice);
4193 goto out_unlock; 3867 goto out_unlock;
4194 } 3868 }
4195 array = p->array; 3869 on_rq = p->se.on_rq;
4196 if (array) { 3870 if (on_rq) {
4197 dequeue_task(p, array); 3871 dequeue_task(rq, p, 0, now);
4198 dec_raw_weighted_load(rq, p); 3872 dec_load(rq, p, now);
4199 } 3873 }
4200 3874
4201 p->static_prio = NICE_TO_PRIO(nice); 3875 p->static_prio = NICE_TO_PRIO(nice);
@@ -4204,9 +3878,9 @@ void set_user_nice(struct task_struct *p, long nice)
4204 p->prio = effective_prio(p); 3878 p->prio = effective_prio(p);
4205 delta = p->prio - old_prio; 3879 delta = p->prio - old_prio;
4206 3880
4207 if (array) { 3881 if (on_rq) {
4208 enqueue_task(p, array); 3882 enqueue_task(rq, p, 0, now);
4209 inc_raw_weighted_load(rq, p); 3883 inc_load(rq, p, now);
4210 /* 3884 /*
4211 * If the task increased its priority or is running and 3885 * If the task increased its priority or is running and
4212 * lowered its priority, then reschedule its CPU: 3886 * lowered its priority, then reschedule its CPU:
@@ -4326,20 +4000,28 @@ static inline struct task_struct *find_process_by_pid(pid_t pid)
4326} 4000}
4327 4001
4328/* Actually do priority change: must hold rq lock. */ 4002/* Actually do priority change: must hold rq lock. */
4329static void __setscheduler(struct task_struct *p, int policy, int prio) 4003static void
4004__setscheduler(struct rq *rq, struct task_struct *p, int policy, int prio)
4330{ 4005{
4331 BUG_ON(p->array); 4006 BUG_ON(p->se.on_rq);
4332 4007
4333 p->policy = policy; 4008 p->policy = policy;
4009 switch (p->policy) {
4010 case SCHED_NORMAL:
4011 case SCHED_BATCH:
4012 case SCHED_IDLE:
4013 p->sched_class = &fair_sched_class;
4014 break;
4015 case SCHED_FIFO:
4016 case SCHED_RR:
4017 p->sched_class = &rt_sched_class;
4018 break;
4019 }
4020
4334 p->rt_priority = prio; 4021 p->rt_priority = prio;
4335 p->normal_prio = normal_prio(p); 4022 p->normal_prio = normal_prio(p);
4336 /* we are holding p->pi_lock already */ 4023 /* we are holding p->pi_lock already */
4337 p->prio = rt_mutex_getprio(p); 4024 p->prio = rt_mutex_getprio(p);
4338 /*
4339 * SCHED_BATCH tasks are treated as perpetual CPU hogs:
4340 */
4341 if (policy == SCHED_BATCH)
4342 p->sleep_avg = 0;
4343 set_load_weight(p); 4025 set_load_weight(p);
4344} 4026}
4345 4027
@@ -4354,8 +4036,7 @@ static void __setscheduler(struct task_struct *p, int policy, int prio)
4354int sched_setscheduler(struct task_struct *p, int policy, 4036int sched_setscheduler(struct task_struct *p, int policy,
4355 struct sched_param *param) 4037 struct sched_param *param)
4356{ 4038{
4357 int retval, oldprio, oldpolicy = -1; 4039 int retval, oldprio, oldpolicy = -1, on_rq;
4358 struct prio_array *array;
4359 unsigned long flags; 4040 unsigned long flags;
4360 struct rq *rq; 4041 struct rq *rq;
4361 4042
@@ -4366,27 +4047,27 @@ recheck:
4366 if (policy < 0) 4047 if (policy < 0)
4367 policy = oldpolicy = p->policy; 4048 policy = oldpolicy = p->policy;
4368 else if (policy != SCHED_FIFO && policy != SCHED_RR && 4049 else if (policy != SCHED_FIFO && policy != SCHED_RR &&
4369 policy != SCHED_NORMAL && policy != SCHED_BATCH) 4050 policy != SCHED_NORMAL && policy != SCHED_BATCH &&
4051 policy != SCHED_IDLE)
4370 return -EINVAL; 4052 return -EINVAL;
4371 /* 4053 /*
4372 * Valid priorities for SCHED_FIFO and SCHED_RR are 4054 * Valid priorities for SCHED_FIFO and SCHED_RR are
4373 * 1..MAX_USER_RT_PRIO-1, valid priority for SCHED_NORMAL and 4055 * 1..MAX_USER_RT_PRIO-1, valid priority for SCHED_NORMAL,
4374 * SCHED_BATCH is 0. 4056 * SCHED_BATCH and SCHED_IDLE is 0.
4375 */ 4057 */
4376 if (param->sched_priority < 0 || 4058 if (param->sched_priority < 0 ||
4377 (p->mm && param->sched_priority > MAX_USER_RT_PRIO-1) || 4059 (p->mm && param->sched_priority > MAX_USER_RT_PRIO-1) ||
4378 (!p->mm && param->sched_priority > MAX_RT_PRIO-1)) 4060 (!p->mm && param->sched_priority > MAX_RT_PRIO-1))
4379 return -EINVAL; 4061 return -EINVAL;
4380 if (is_rt_policy(policy) != (param->sched_priority != 0)) 4062 if (rt_policy(policy) != (param->sched_priority != 0))
4381 return -EINVAL; 4063 return -EINVAL;
4382 4064
4383 /* 4065 /*
4384 * Allow unprivileged RT tasks to decrease priority: 4066 * Allow unprivileged RT tasks to decrease priority:
4385 */ 4067 */
4386 if (!capable(CAP_SYS_NICE)) { 4068 if (!capable(CAP_SYS_NICE)) {
4387 if (is_rt_policy(policy)) { 4069 if (rt_policy(policy)) {
4388 unsigned long rlim_rtprio; 4070 unsigned long rlim_rtprio;
4389 unsigned long flags;
4390 4071
4391 if (!lock_task_sighand(p, &flags)) 4072 if (!lock_task_sighand(p, &flags))
4392 return -ESRCH; 4073 return -ESRCH;
@@ -4402,6 +4083,12 @@ recheck:
4402 param->sched_priority > rlim_rtprio) 4083 param->sched_priority > rlim_rtprio)
4403 return -EPERM; 4084 return -EPERM;
4404 } 4085 }
4086 /*
4087 * Like positive nice levels, dont allow tasks to
4088 * move out of SCHED_IDLE either:
4089 */
4090 if (p->policy == SCHED_IDLE && policy != SCHED_IDLE)
4091 return -EPERM;
4405 4092
4406 /* can't change other user's priorities */ 4093 /* can't change other user's priorities */
4407 if ((current->euid != p->euid) && 4094 if ((current->euid != p->euid) &&
@@ -4429,13 +4116,13 @@ recheck:
4429 spin_unlock_irqrestore(&p->pi_lock, flags); 4116 spin_unlock_irqrestore(&p->pi_lock, flags);
4430 goto recheck; 4117 goto recheck;
4431 } 4118 }
4432 array = p->array; 4119 on_rq = p->se.on_rq;
4433 if (array) 4120 if (on_rq)
4434 deactivate_task(p, rq); 4121 deactivate_task(rq, p, 0);
4435 oldprio = p->prio; 4122 oldprio = p->prio;
4436 __setscheduler(p, policy, param->sched_priority); 4123 __setscheduler(rq, p, policy, param->sched_priority);
4437 if (array) { 4124 if (on_rq) {
4438 __activate_task(p, rq); 4125 activate_task(rq, p, 0);
4439 /* 4126 /*
4440 * Reschedule if we are currently running on this runqueue and 4127 * Reschedule if we are currently running on this runqueue and
4441 * our priority decreased, or if we are not currently running on 4128 * our priority decreased, or if we are not currently running on
@@ -4444,8 +4131,9 @@ recheck:
4444 if (task_running(rq, p)) { 4131 if (task_running(rq, p)) {
4445 if (p->prio > oldprio) 4132 if (p->prio > oldprio)
4446 resched_task(rq->curr); 4133 resched_task(rq->curr);
4447 } else if (TASK_PREEMPTS_CURR(p, rq)) 4134 } else {
4448 resched_task(rq->curr); 4135 check_preempt_curr(rq, p);
4136 }
4449 } 4137 }
4450 __task_rq_unlock(rq); 4138 __task_rq_unlock(rq);
4451 spin_unlock_irqrestore(&p->pi_lock, flags); 4139 spin_unlock_irqrestore(&p->pi_lock, flags);
@@ -4717,41 +4405,18 @@ asmlinkage long sys_sched_getaffinity(pid_t pid, unsigned int len,
4717/** 4405/**
4718 * sys_sched_yield - yield the current processor to other threads. 4406 * sys_sched_yield - yield the current processor to other threads.
4719 * 4407 *
4720 * This function yields the current CPU by moving the calling thread 4408 * This function yields the current CPU to other tasks. If there are no
4721 * to the expired array. If there are no other threads running on this 4409 * other threads running on this CPU then this function will return.
4722 * CPU then this function will return.
4723 */ 4410 */
4724asmlinkage long sys_sched_yield(void) 4411asmlinkage long sys_sched_yield(void)
4725{ 4412{
4726 struct rq *rq = this_rq_lock(); 4413 struct rq *rq = this_rq_lock();
4727 struct prio_array *array = current->array, *target = rq->expired;
4728 4414
4729 schedstat_inc(rq, yld_cnt); 4415 schedstat_inc(rq, yld_cnt);
4730 /* 4416 if (unlikely(rq->nr_running == 1))
4731 * We implement yielding by moving the task into the expired
4732 * queue.
4733 *
4734 * (special rule: RT tasks will just roundrobin in the active
4735 * array.)
4736 */
4737 if (rt_task(current))
4738 target = rq->active;
4739
4740 if (array->nr_active == 1) {
4741 schedstat_inc(rq, yld_act_empty); 4417 schedstat_inc(rq, yld_act_empty);
4742 if (!rq->expired->nr_active) 4418 else
4743 schedstat_inc(rq, yld_both_empty); 4419 current->sched_class->yield_task(rq, current);
4744 } else if (!rq->expired->nr_active)
4745 schedstat_inc(rq, yld_exp_empty);
4746
4747 if (array != target) {
4748 dequeue_task(current, array);
4749 enqueue_task(current, target);
4750 } else
4751 /*
4752 * requeue_task is cheaper so perform that if possible.
4753 */
4754 requeue_task(current, array);
4755 4420
4756 /* 4421 /*
4757 * Since we are going to call schedule() anyway, there's 4422 * Since we are going to call schedule() anyway, there's
@@ -4902,6 +4567,7 @@ asmlinkage long sys_sched_get_priority_max(int policy)
4902 break; 4567 break;
4903 case SCHED_NORMAL: 4568 case SCHED_NORMAL:
4904 case SCHED_BATCH: 4569 case SCHED_BATCH:
4570 case SCHED_IDLE:
4905 ret = 0; 4571 ret = 0;
4906 break; 4572 break;
4907 } 4573 }
@@ -4926,6 +4592,7 @@ asmlinkage long sys_sched_get_priority_min(int policy)
4926 break; 4592 break;
4927 case SCHED_NORMAL: 4593 case SCHED_NORMAL:
4928 case SCHED_BATCH: 4594 case SCHED_BATCH:
4595 case SCHED_IDLE:
4929 ret = 0; 4596 ret = 0;
4930 } 4597 }
4931 return ret; 4598 return ret;
@@ -4960,7 +4627,7 @@ long sys_sched_rr_get_interval(pid_t pid, struct timespec __user *interval)
4960 goto out_unlock; 4627 goto out_unlock;
4961 4628
4962 jiffies_to_timespec(p->policy == SCHED_FIFO ? 4629 jiffies_to_timespec(p->policy == SCHED_FIFO ?
4963 0 : task_timeslice(p), &t); 4630 0 : static_prio_timeslice(p->static_prio), &t);
4964 read_unlock(&tasklist_lock); 4631 read_unlock(&tasklist_lock);
4965 retval = copy_to_user(interval, &t, sizeof(t)) ? -EFAULT : 0; 4632 retval = copy_to_user(interval, &t, sizeof(t)) ? -EFAULT : 0;
4966out_nounlock: 4633out_nounlock:
@@ -5035,6 +4702,9 @@ void show_state_filter(unsigned long state_filter)
5035 4702
5036 touch_all_softlockup_watchdogs(); 4703 touch_all_softlockup_watchdogs();
5037 4704
4705#ifdef CONFIG_SCHED_DEBUG
4706 sysrq_sched_debug_show();
4707#endif
5038 read_unlock(&tasklist_lock); 4708 read_unlock(&tasklist_lock);
5039 /* 4709 /*
5040 * Only show locks if all tasks are dumped: 4710 * Only show locks if all tasks are dumped:
@@ -5043,6 +4713,11 @@ void show_state_filter(unsigned long state_filter)
5043 debug_show_all_locks(); 4713 debug_show_all_locks();
5044} 4714}
5045 4715
4716void __cpuinit init_idle_bootup_task(struct task_struct *idle)
4717{
4718 idle->sched_class = &idle_sched_class;
4719}
4720
5046/** 4721/**
5047 * init_idle - set up an idle thread for a given CPU 4722 * init_idle - set up an idle thread for a given CPU
5048 * @idle: task in question 4723 * @idle: task in question
@@ -5056,13 +4731,12 @@ void __cpuinit init_idle(struct task_struct *idle, int cpu)
5056 struct rq *rq = cpu_rq(cpu); 4731 struct rq *rq = cpu_rq(cpu);
5057 unsigned long flags; 4732 unsigned long flags;
5058 4733
5059 idle->timestamp = sched_clock(); 4734 __sched_fork(idle);
5060 idle->sleep_avg = 0; 4735 idle->se.exec_start = sched_clock();
5061 idle->array = NULL; 4736
5062 idle->prio = idle->normal_prio = MAX_PRIO; 4737 idle->prio = idle->normal_prio = MAX_PRIO;
5063 idle->state = TASK_RUNNING;
5064 idle->cpus_allowed = cpumask_of_cpu(cpu); 4738 idle->cpus_allowed = cpumask_of_cpu(cpu);
5065 set_task_cpu(idle, cpu); 4739 __set_task_cpu(idle, cpu);
5066 4740
5067 spin_lock_irqsave(&rq->lock, flags); 4741 spin_lock_irqsave(&rq->lock, flags);
5068 rq->curr = rq->idle = idle; 4742 rq->curr = rq->idle = idle;
@@ -5077,6 +4751,10 @@ void __cpuinit init_idle(struct task_struct *idle, int cpu)
5077#else 4751#else
5078 task_thread_info(idle)->preempt_count = 0; 4752 task_thread_info(idle)->preempt_count = 0;
5079#endif 4753#endif
4754 /*
4755 * The idle tasks have their own, simple scheduling class:
4756 */
4757 idle->sched_class = &idle_sched_class;
5080} 4758}
5081 4759
5082/* 4760/*
@@ -5088,6 +4766,28 @@ void __cpuinit init_idle(struct task_struct *idle, int cpu)
5088 */ 4766 */
5089cpumask_t nohz_cpu_mask = CPU_MASK_NONE; 4767cpumask_t nohz_cpu_mask = CPU_MASK_NONE;
5090 4768
4769/*
4770 * Increase the granularity value when there are more CPUs,
4771 * because with more CPUs the 'effective latency' as visible
4772 * to users decreases. But the relationship is not linear,
4773 * so pick a second-best guess by going with the log2 of the
4774 * number of CPUs.
4775 *
4776 * This idea comes from the SD scheduler of Con Kolivas:
4777 */
4778static inline void sched_init_granularity(void)
4779{
4780 unsigned int factor = 1 + ilog2(num_online_cpus());
4781 const unsigned long gran_limit = 10000000;
4782
4783 sysctl_sched_granularity *= factor;
4784 if (sysctl_sched_granularity > gran_limit)
4785 sysctl_sched_granularity = gran_limit;
4786
4787 sysctl_sched_runtime_limit = sysctl_sched_granularity * 4;
4788 sysctl_sched_wakeup_granularity = sysctl_sched_granularity / 2;
4789}
4790
5091#ifdef CONFIG_SMP 4791#ifdef CONFIG_SMP
5092/* 4792/*
5093 * This is how migration works: 4793 * This is how migration works:
@@ -5161,7 +4861,7 @@ EXPORT_SYMBOL_GPL(set_cpus_allowed);
5161static int __migrate_task(struct task_struct *p, int src_cpu, int dest_cpu) 4861static int __migrate_task(struct task_struct *p, int src_cpu, int dest_cpu)
5162{ 4862{
5163 struct rq *rq_dest, *rq_src; 4863 struct rq *rq_dest, *rq_src;
5164 int ret = 0; 4864 int ret = 0, on_rq;
5165 4865
5166 if (unlikely(cpu_is_offline(dest_cpu))) 4866 if (unlikely(cpu_is_offline(dest_cpu)))
5167 return ret; 4867 return ret;
@@ -5177,20 +4877,13 @@ static int __migrate_task(struct task_struct *p, int src_cpu, int dest_cpu)
5177 if (!cpu_isset(dest_cpu, p->cpus_allowed)) 4877 if (!cpu_isset(dest_cpu, p->cpus_allowed))
5178 goto out; 4878 goto out;
5179 4879
4880 on_rq = p->se.on_rq;
4881 if (on_rq)
4882 deactivate_task(rq_src, p, 0);
5180 set_task_cpu(p, dest_cpu); 4883 set_task_cpu(p, dest_cpu);
5181 if (p->array) { 4884 if (on_rq) {
5182 /* 4885 activate_task(rq_dest, p, 0);
5183 * Sync timestamp with rq_dest's before activating. 4886 check_preempt_curr(rq_dest, p);
5184 * The same thing could be achieved by doing this step
5185 * afterwards, and pretending it was a local activate.
5186 * This way is cleaner and logically correct.
5187 */
5188 p->timestamp = p->timestamp - rq_src->most_recent_timestamp
5189 + rq_dest->most_recent_timestamp;
5190 deactivate_task(p, rq_src);
5191 __activate_task(p, rq_dest);
5192 if (TASK_PREEMPTS_CURR(p, rq_dest))
5193 resched_task(rq_dest->curr);
5194 } 4887 }
5195 ret = 1; 4888 ret = 1;
5196out: 4889out:
@@ -5342,7 +5035,8 @@ static void migrate_live_tasks(int src_cpu)
5342 write_unlock_irq(&tasklist_lock); 5035 write_unlock_irq(&tasklist_lock);
5343} 5036}
5344 5037
5345/* Schedules idle task to be the next runnable task on current CPU. 5038/*
5039 * Schedules idle task to be the next runnable task on current CPU.
5346 * It does so by boosting its priority to highest possible and adding it to 5040 * It does so by boosting its priority to highest possible and adding it to
5347 * the _front_ of the runqueue. Used by CPU offline code. 5041 * the _front_ of the runqueue. Used by CPU offline code.
5348 */ 5042 */
@@ -5362,10 +5056,10 @@ void sched_idle_next(void)
5362 */ 5056 */
5363 spin_lock_irqsave(&rq->lock, flags); 5057 spin_lock_irqsave(&rq->lock, flags);
5364 5058
5365 __setscheduler(p, SCHED_FIFO, MAX_RT_PRIO-1); 5059 __setscheduler(rq, p, SCHED_FIFO, MAX_RT_PRIO-1);
5366 5060
5367 /* Add idle task to the _front_ of its priority queue: */ 5061 /* Add idle task to the _front_ of its priority queue: */
5368 __activate_idle_task(p, rq); 5062 activate_idle_task(p, rq);
5369 5063
5370 spin_unlock_irqrestore(&rq->lock, flags); 5064 spin_unlock_irqrestore(&rq->lock, flags);
5371} 5065}
@@ -5415,16 +5109,15 @@ static void migrate_dead(unsigned int dead_cpu, struct task_struct *p)
5415static void migrate_dead_tasks(unsigned int dead_cpu) 5109static void migrate_dead_tasks(unsigned int dead_cpu)
5416{ 5110{
5417 struct rq *rq = cpu_rq(dead_cpu); 5111 struct rq *rq = cpu_rq(dead_cpu);
5418 unsigned int arr, i; 5112 struct task_struct *next;
5419 5113
5420 for (arr = 0; arr < 2; arr++) { 5114 for ( ; ; ) {
5421 for (i = 0; i < MAX_PRIO; i++) { 5115 if (!rq->nr_running)
5422 struct list_head *list = &rq->arrays[arr].queue[i]; 5116 break;
5423 5117 next = pick_next_task(rq, rq->curr, rq_clock(rq));
5424 while (!list_empty(list)) 5118 if (!next)
5425 migrate_dead(dead_cpu, list_entry(list->next, 5119 break;
5426 struct task_struct, run_list)); 5120 migrate_dead(dead_cpu, next);
5427 }
5428 } 5121 }
5429} 5122}
5430#endif /* CONFIG_HOTPLUG_CPU */ 5123#endif /* CONFIG_HOTPLUG_CPU */
@@ -5448,14 +5141,14 @@ migration_call(struct notifier_block *nfb, unsigned long action, void *hcpu)
5448 5141
5449 case CPU_UP_PREPARE: 5142 case CPU_UP_PREPARE:
5450 case CPU_UP_PREPARE_FROZEN: 5143 case CPU_UP_PREPARE_FROZEN:
5451 p = kthread_create(migration_thread, hcpu, "migration/%d",cpu); 5144 p = kthread_create(migration_thread, hcpu, "migration/%d", cpu);
5452 if (IS_ERR(p)) 5145 if (IS_ERR(p))
5453 return NOTIFY_BAD; 5146 return NOTIFY_BAD;
5454 p->flags |= PF_NOFREEZE; 5147 p->flags |= PF_NOFREEZE;
5455 kthread_bind(p, cpu); 5148 kthread_bind(p, cpu);
5456 /* Must be high prio: stop_machine expects to yield to it. */ 5149 /* Must be high prio: stop_machine expects to yield to it. */
5457 rq = task_rq_lock(p, &flags); 5150 rq = task_rq_lock(p, &flags);
5458 __setscheduler(p, SCHED_FIFO, MAX_RT_PRIO-1); 5151 __setscheduler(rq, p, SCHED_FIFO, MAX_RT_PRIO-1);
5459 task_rq_unlock(rq, &flags); 5152 task_rq_unlock(rq, &flags);
5460 cpu_rq(cpu)->migration_thread = p; 5153 cpu_rq(cpu)->migration_thread = p;
5461 break; 5154 break;
@@ -5486,9 +5179,10 @@ migration_call(struct notifier_block *nfb, unsigned long action, void *hcpu)
5486 rq->migration_thread = NULL; 5179 rq->migration_thread = NULL;
5487 /* Idle task back to normal (off runqueue, low prio) */ 5180 /* Idle task back to normal (off runqueue, low prio) */
5488 rq = task_rq_lock(rq->idle, &flags); 5181 rq = task_rq_lock(rq->idle, &flags);
5489 deactivate_task(rq->idle, rq); 5182 deactivate_task(rq, rq->idle, 0);
5490 rq->idle->static_prio = MAX_PRIO; 5183 rq->idle->static_prio = MAX_PRIO;
5491 __setscheduler(rq->idle, SCHED_NORMAL, 0); 5184 __setscheduler(rq, rq->idle, SCHED_NORMAL, 0);
5185 rq->idle->sched_class = &idle_sched_class;
5492 migrate_dead_tasks(cpu); 5186 migrate_dead_tasks(cpu);
5493 task_rq_unlock(rq, &flags); 5187 task_rq_unlock(rq, &flags);
5494 migrate_nr_uninterruptible(rq); 5188 migrate_nr_uninterruptible(rq);
@@ -5797,483 +5491,6 @@ init_sched_build_groups(cpumask_t span, const cpumask_t *cpu_map,
5797 5491
5798#define SD_NODES_PER_DOMAIN 16 5492#define SD_NODES_PER_DOMAIN 16
5799 5493
5800/*
5801 * Self-tuning task migration cost measurement between source and target CPUs.
5802 *
5803 * This is done by measuring the cost of manipulating buffers of varying
5804 * sizes. For a given buffer-size here are the steps that are taken:
5805 *
5806 * 1) the source CPU reads+dirties a shared buffer
5807 * 2) the target CPU reads+dirties the same shared buffer
5808 *
5809 * We measure how long they take, in the following 4 scenarios:
5810 *
5811 * - source: CPU1, target: CPU2 | cost1
5812 * - source: CPU2, target: CPU1 | cost2
5813 * - source: CPU1, target: CPU1 | cost3
5814 * - source: CPU2, target: CPU2 | cost4
5815 *
5816 * We then calculate the cost3+cost4-cost1-cost2 difference - this is
5817 * the cost of migration.
5818 *
5819 * We then start off from a small buffer-size and iterate up to larger
5820 * buffer sizes, in 5% steps - measuring each buffer-size separately, and
5821 * doing a maximum search for the cost. (The maximum cost for a migration
5822 * normally occurs when the working set size is around the effective cache
5823 * size.)
5824 */
5825#define SEARCH_SCOPE 2
5826#define MIN_CACHE_SIZE (64*1024U)
5827#define DEFAULT_CACHE_SIZE (5*1024*1024U)
5828#define ITERATIONS 1
5829#define SIZE_THRESH 130
5830#define COST_THRESH 130
5831
5832/*
5833 * The migration cost is a function of 'domain distance'. Domain
5834 * distance is the number of steps a CPU has to iterate down its
5835 * domain tree to share a domain with the other CPU. The farther
5836 * two CPUs are from each other, the larger the distance gets.
5837 *
5838 * Note that we use the distance only to cache measurement results,
5839 * the distance value is not used numerically otherwise. When two
5840 * CPUs have the same distance it is assumed that the migration
5841 * cost is the same. (this is a simplification but quite practical)
5842 */
5843#define MAX_DOMAIN_DISTANCE 32
5844
5845static unsigned long long migration_cost[MAX_DOMAIN_DISTANCE] =
5846 { [ 0 ... MAX_DOMAIN_DISTANCE-1 ] =
5847/*
5848 * Architectures may override the migration cost and thus avoid
5849 * boot-time calibration. Unit is nanoseconds. Mostly useful for
5850 * virtualized hardware:
5851 */
5852#ifdef CONFIG_DEFAULT_MIGRATION_COST
5853 CONFIG_DEFAULT_MIGRATION_COST
5854#else
5855 -1LL
5856#endif
5857};
5858
5859/*
5860 * Allow override of migration cost - in units of microseconds.
5861 * E.g. migration_cost=1000,2000,3000 will set up a level-1 cost
5862 * of 1 msec, level-2 cost of 2 msecs and level3 cost of 3 msecs:
5863 */
5864static int __init migration_cost_setup(char *str)
5865{
5866 int ints[MAX_DOMAIN_DISTANCE+1], i;
5867
5868 str = get_options(str, ARRAY_SIZE(ints), ints);
5869
5870 printk("#ints: %d\n", ints[0]);
5871 for (i = 1; i <= ints[0]; i++) {
5872 migration_cost[i-1] = (unsigned long long)ints[i]*1000;
5873 printk("migration_cost[%d]: %Ld\n", i-1, migration_cost[i-1]);
5874 }
5875 return 1;
5876}
5877
5878__setup ("migration_cost=", migration_cost_setup);
5879
5880/*
5881 * Global multiplier (divisor) for migration-cutoff values,
5882 * in percentiles. E.g. use a value of 150 to get 1.5 times
5883 * longer cache-hot cutoff times.
5884 *
5885 * (We scale it from 100 to 128 to long long handling easier.)
5886 */
5887
5888#define MIGRATION_FACTOR_SCALE 128
5889
5890static unsigned int migration_factor = MIGRATION_FACTOR_SCALE;
5891
5892static int __init setup_migration_factor(char *str)
5893{
5894 get_option(&str, &migration_factor);
5895 migration_factor = migration_factor * MIGRATION_FACTOR_SCALE / 100;
5896 return 1;
5897}
5898
5899__setup("migration_factor=", setup_migration_factor);
5900
5901/*
5902 * Estimated distance of two CPUs, measured via the number of domains
5903 * we have to pass for the two CPUs to be in the same span:
5904 */
5905static unsigned long domain_distance(int cpu1, int cpu2)
5906{
5907 unsigned long distance = 0;
5908 struct sched_domain *sd;
5909
5910 for_each_domain(cpu1, sd) {
5911 WARN_ON(!cpu_isset(cpu1, sd->span));
5912 if (cpu_isset(cpu2, sd->span))
5913 return distance;
5914 distance++;
5915 }
5916 if (distance >= MAX_DOMAIN_DISTANCE) {
5917 WARN_ON(1);
5918 distance = MAX_DOMAIN_DISTANCE-1;
5919 }
5920
5921 return distance;
5922}
5923
5924static unsigned int migration_debug;
5925
5926static int __init setup_migration_debug(char *str)
5927{
5928 get_option(&str, &migration_debug);
5929 return 1;
5930}
5931
5932__setup("migration_debug=", setup_migration_debug);
5933
5934/*
5935 * Maximum cache-size that the scheduler should try to measure.
5936 * Architectures with larger caches should tune this up during
5937 * bootup. Gets used in the domain-setup code (i.e. during SMP
5938 * bootup).
5939 */
5940unsigned int max_cache_size;
5941
5942static int __init setup_max_cache_size(char *str)
5943{
5944 get_option(&str, &max_cache_size);
5945 return 1;
5946}
5947
5948__setup("max_cache_size=", setup_max_cache_size);
5949
5950/*
5951 * Dirty a big buffer in a hard-to-predict (for the L2 cache) way. This
5952 * is the operation that is timed, so we try to generate unpredictable
5953 * cachemisses that still end up filling the L2 cache:
5954 */
5955static void touch_cache(void *__cache, unsigned long __size)
5956{
5957 unsigned long size = __size / sizeof(long);
5958 unsigned long chunk1 = size / 3;
5959 unsigned long chunk2 = 2 * size / 3;
5960 unsigned long *cache = __cache;
5961 int i;
5962
5963 for (i = 0; i < size/6; i += 8) {
5964 switch (i % 6) {
5965 case 0: cache[i]++;
5966 case 1: cache[size-1-i]++;
5967 case 2: cache[chunk1-i]++;
5968 case 3: cache[chunk1+i]++;
5969 case 4: cache[chunk2-i]++;
5970 case 5: cache[chunk2+i]++;
5971 }
5972 }
5973}
5974
5975/*
5976 * Measure the cache-cost of one task migration. Returns in units of nsec.
5977 */
5978static unsigned long long
5979measure_one(void *cache, unsigned long size, int source, int target)
5980{
5981 cpumask_t mask, saved_mask;
5982 unsigned long long t0, t1, t2, t3, cost;
5983
5984 saved_mask = current->cpus_allowed;
5985
5986 /*
5987 * Flush source caches to RAM and invalidate them:
5988 */
5989 sched_cacheflush();
5990
5991 /*
5992 * Migrate to the source CPU:
5993 */
5994 mask = cpumask_of_cpu(source);
5995 set_cpus_allowed(current, mask);
5996 WARN_ON(smp_processor_id() != source);
5997
5998 /*
5999 * Dirty the working set:
6000 */
6001 t0 = sched_clock();
6002 touch_cache(cache, size);
6003 t1 = sched_clock();
6004
6005 /*
6006 * Migrate to the target CPU, dirty the L2 cache and access
6007 * the shared buffer. (which represents the working set
6008 * of a migrated task.)
6009 */
6010 mask = cpumask_of_cpu(target);
6011 set_cpus_allowed(current, mask);
6012 WARN_ON(smp_processor_id() != target);
6013
6014 t2 = sched_clock();
6015 touch_cache(cache, size);
6016 t3 = sched_clock();
6017
6018 cost = t1-t0 + t3-t2;
6019
6020 if (migration_debug >= 2)
6021 printk("[%d->%d]: %8Ld %8Ld %8Ld => %10Ld.\n",
6022 source, target, t1-t0, t1-t0, t3-t2, cost);
6023 /*
6024 * Flush target caches to RAM and invalidate them:
6025 */
6026 sched_cacheflush();
6027
6028 set_cpus_allowed(current, saved_mask);
6029
6030 return cost;
6031}
6032
6033/*
6034 * Measure a series of task migrations and return the average
6035 * result. Since this code runs early during bootup the system
6036 * is 'undisturbed' and the average latency makes sense.
6037 *
6038 * The algorithm in essence auto-detects the relevant cache-size,
6039 * so it will properly detect different cachesizes for different
6040 * cache-hierarchies, depending on how the CPUs are connected.
6041 *
6042 * Architectures can prime the upper limit of the search range via
6043 * max_cache_size, otherwise the search range defaults to 20MB...64K.
6044 */
6045static unsigned long long
6046measure_cost(int cpu1, int cpu2, void *cache, unsigned int size)
6047{
6048 unsigned long long cost1, cost2;
6049 int i;
6050
6051 /*
6052 * Measure the migration cost of 'size' bytes, over an
6053 * average of 10 runs:
6054 *
6055 * (We perturb the cache size by a small (0..4k)
6056 * value to compensate size/alignment related artifacts.
6057 * We also subtract the cost of the operation done on
6058 * the same CPU.)
6059 */
6060 cost1 = 0;
6061
6062 /*
6063 * dry run, to make sure we start off cache-cold on cpu1,
6064 * and to get any vmalloc pagefaults in advance:
6065 */
6066 measure_one(cache, size, cpu1, cpu2);
6067 for (i = 0; i < ITERATIONS; i++)
6068 cost1 += measure_one(cache, size - i * 1024, cpu1, cpu2);
6069
6070 measure_one(cache, size, cpu2, cpu1);
6071 for (i = 0; i < ITERATIONS; i++)
6072 cost1 += measure_one(cache, size - i * 1024, cpu2, cpu1);
6073
6074 /*
6075 * (We measure the non-migrating [cached] cost on both
6076 * cpu1 and cpu2, to handle CPUs with different speeds)
6077 */
6078 cost2 = 0;
6079
6080 measure_one(cache, size, cpu1, cpu1);
6081 for (i = 0; i < ITERATIONS; i++)
6082 cost2 += measure_one(cache, size - i * 1024, cpu1, cpu1);
6083
6084 measure_one(cache, size, cpu2, cpu2);
6085 for (i = 0; i < ITERATIONS; i++)
6086 cost2 += measure_one(cache, size - i * 1024, cpu2, cpu2);
6087
6088 /*
6089 * Get the per-iteration migration cost:
6090 */
6091 do_div(cost1, 2 * ITERATIONS);
6092 do_div(cost2, 2 * ITERATIONS);
6093
6094 return cost1 - cost2;
6095}
6096
6097static unsigned long long measure_migration_cost(int cpu1, int cpu2)
6098{
6099 unsigned long long max_cost = 0, fluct = 0, avg_fluct = 0;
6100 unsigned int max_size, size, size_found = 0;
6101 long long cost = 0, prev_cost;
6102 void *cache;
6103
6104 /*
6105 * Search from max_cache_size*5 down to 64K - the real relevant
6106 * cachesize has to lie somewhere inbetween.
6107 */
6108 if (max_cache_size) {
6109 max_size = max(max_cache_size * SEARCH_SCOPE, MIN_CACHE_SIZE);
6110 size = max(max_cache_size / SEARCH_SCOPE, MIN_CACHE_SIZE);
6111 } else {
6112 /*
6113 * Since we have no estimation about the relevant
6114 * search range
6115 */
6116 max_size = DEFAULT_CACHE_SIZE * SEARCH_SCOPE;
6117 size = MIN_CACHE_SIZE;
6118 }
6119
6120 if (!cpu_online(cpu1) || !cpu_online(cpu2)) {
6121 printk("cpu %d and %d not both online!\n", cpu1, cpu2);
6122 return 0;
6123 }
6124
6125 /*
6126 * Allocate the working set:
6127 */
6128 cache = vmalloc(max_size);
6129 if (!cache) {
6130 printk("could not vmalloc %d bytes for cache!\n", 2 * max_size);
6131 return 1000000; /* return 1 msec on very small boxen */
6132 }
6133
6134 while (size <= max_size) {
6135 prev_cost = cost;
6136 cost = measure_cost(cpu1, cpu2, cache, size);
6137
6138 /*
6139 * Update the max:
6140 */
6141 if (cost > 0) {
6142 if (max_cost < cost) {
6143 max_cost = cost;
6144 size_found = size;
6145 }
6146 }
6147 /*
6148 * Calculate average fluctuation, we use this to prevent
6149 * noise from triggering an early break out of the loop:
6150 */
6151 fluct = abs(cost - prev_cost);
6152 avg_fluct = (avg_fluct + fluct)/2;
6153
6154 if (migration_debug)
6155 printk("-> [%d][%d][%7d] %3ld.%ld [%3ld.%ld] (%ld): "
6156 "(%8Ld %8Ld)\n",
6157 cpu1, cpu2, size,
6158 (long)cost / 1000000,
6159 ((long)cost / 100000) % 10,
6160 (long)max_cost / 1000000,
6161 ((long)max_cost / 100000) % 10,
6162 domain_distance(cpu1, cpu2),
6163 cost, avg_fluct);
6164
6165 /*
6166 * If we iterated at least 20% past the previous maximum,
6167 * and the cost has dropped by more than 20% already,
6168 * (taking fluctuations into account) then we assume to
6169 * have found the maximum and break out of the loop early:
6170 */
6171 if (size_found && (size*100 > size_found*SIZE_THRESH))
6172 if (cost+avg_fluct <= 0 ||
6173 max_cost*100 > (cost+avg_fluct)*COST_THRESH) {
6174
6175 if (migration_debug)
6176 printk("-> found max.\n");
6177 break;
6178 }
6179 /*
6180 * Increase the cachesize in 10% steps:
6181 */
6182 size = size * 10 / 9;
6183 }
6184
6185 if (migration_debug)
6186 printk("[%d][%d] working set size found: %d, cost: %Ld\n",
6187 cpu1, cpu2, size_found, max_cost);
6188
6189 vfree(cache);
6190
6191 /*
6192 * A task is considered 'cache cold' if at least 2 times
6193 * the worst-case cost of migration has passed.
6194 *
6195 * (this limit is only listened to if the load-balancing
6196 * situation is 'nice' - if there is a large imbalance we
6197 * ignore it for the sake of CPU utilization and
6198 * processing fairness.)
6199 */
6200 return 2 * max_cost * migration_factor / MIGRATION_FACTOR_SCALE;
6201}
6202
6203static void calibrate_migration_costs(const cpumask_t *cpu_map)
6204{
6205 int cpu1 = -1, cpu2 = -1, cpu, orig_cpu = raw_smp_processor_id();
6206 unsigned long j0, j1, distance, max_distance = 0;
6207 struct sched_domain *sd;
6208
6209 j0 = jiffies;
6210
6211 /*
6212 * First pass - calculate the cacheflush times:
6213 */
6214 for_each_cpu_mask(cpu1, *cpu_map) {
6215 for_each_cpu_mask(cpu2, *cpu_map) {
6216 if (cpu1 == cpu2)
6217 continue;
6218 distance = domain_distance(cpu1, cpu2);
6219 max_distance = max(max_distance, distance);
6220 /*
6221 * No result cached yet?
6222 */
6223 if (migration_cost[distance] == -1LL)
6224 migration_cost[distance] =
6225 measure_migration_cost(cpu1, cpu2);
6226 }
6227 }
6228 /*
6229 * Second pass - update the sched domain hierarchy with
6230 * the new cache-hot-time estimations:
6231 */
6232 for_each_cpu_mask(cpu, *cpu_map) {
6233 distance = 0;
6234 for_each_domain(cpu, sd) {
6235 sd->cache_hot_time = migration_cost[distance];
6236 distance++;
6237 }
6238 }
6239 /*
6240 * Print the matrix:
6241 */
6242 if (migration_debug)
6243 printk("migration: max_cache_size: %d, cpu: %d MHz:\n",
6244 max_cache_size,
6245#ifdef CONFIG_X86
6246 cpu_khz/1000
6247#else
6248 -1
6249#endif
6250 );
6251 if (system_state == SYSTEM_BOOTING && num_online_cpus() > 1) {
6252 printk("migration_cost=");
6253 for (distance = 0; distance <= max_distance; distance++) {
6254 if (distance)
6255 printk(",");
6256 printk("%ld", (long)migration_cost[distance] / 1000);
6257 }
6258 printk("\n");
6259 }
6260 j1 = jiffies;
6261 if (migration_debug)
6262 printk("migration: %ld seconds\n", (j1-j0) / HZ);
6263
6264 /*
6265 * Move back to the original CPU. NUMA-Q gets confused
6266 * if we migrate to another quad during bootup.
6267 */
6268 if (raw_smp_processor_id() != orig_cpu) {
6269 cpumask_t mask = cpumask_of_cpu(orig_cpu),
6270 saved_mask = current->cpus_allowed;
6271
6272 set_cpus_allowed(current, mask);
6273 set_cpus_allowed(current, saved_mask);
6274 }
6275}
6276
6277#ifdef CONFIG_NUMA 5494#ifdef CONFIG_NUMA
6278 5495
6279/** 5496/**
@@ -6574,7 +5791,6 @@ static void init_sched_groups_power(int cpu, struct sched_domain *sd)
6574static int build_sched_domains(const cpumask_t *cpu_map) 5791static int build_sched_domains(const cpumask_t *cpu_map)
6575{ 5792{
6576 int i; 5793 int i;
6577 struct sched_domain *sd;
6578#ifdef CONFIG_NUMA 5794#ifdef CONFIG_NUMA
6579 struct sched_group **sched_group_nodes = NULL; 5795 struct sched_group **sched_group_nodes = NULL;
6580 int sd_allnodes = 0; 5796 int sd_allnodes = 0;
@@ -6582,7 +5798,7 @@ static int build_sched_domains(const cpumask_t *cpu_map)
6582 /* 5798 /*
6583 * Allocate the per-node list of sched groups 5799 * Allocate the per-node list of sched groups
6584 */ 5800 */
6585 sched_group_nodes = kzalloc(sizeof(struct sched_group*)*MAX_NUMNODES, 5801 sched_group_nodes = kzalloc(sizeof(struct sched_group *)*MAX_NUMNODES,
6586 GFP_KERNEL); 5802 GFP_KERNEL);
6587 if (!sched_group_nodes) { 5803 if (!sched_group_nodes) {
6588 printk(KERN_WARNING "Can not alloc sched group node list\n"); 5804 printk(KERN_WARNING "Can not alloc sched group node list\n");
@@ -6601,8 +5817,8 @@ static int build_sched_domains(const cpumask_t *cpu_map)
6601 cpus_and(nodemask, nodemask, *cpu_map); 5817 cpus_and(nodemask, nodemask, *cpu_map);
6602 5818
6603#ifdef CONFIG_NUMA 5819#ifdef CONFIG_NUMA
6604 if (cpus_weight(*cpu_map) 5820 if (cpus_weight(*cpu_map) >
6605 > SD_NODES_PER_DOMAIN*cpus_weight(nodemask)) { 5821 SD_NODES_PER_DOMAIN*cpus_weight(nodemask)) {
6606 sd = &per_cpu(allnodes_domains, i); 5822 sd = &per_cpu(allnodes_domains, i);
6607 *sd = SD_ALLNODES_INIT; 5823 *sd = SD_ALLNODES_INIT;
6608 sd->span = *cpu_map; 5824 sd->span = *cpu_map;
@@ -6661,7 +5877,8 @@ static int build_sched_domains(const cpumask_t *cpu_map)
6661 if (i != first_cpu(this_sibling_map)) 5877 if (i != first_cpu(this_sibling_map))
6662 continue; 5878 continue;
6663 5879
6664 init_sched_build_groups(this_sibling_map, cpu_map, &cpu_to_cpu_group); 5880 init_sched_build_groups(this_sibling_map, cpu_map,
5881 &cpu_to_cpu_group);
6665 } 5882 }
6666#endif 5883#endif
6667 5884
@@ -6672,11 +5889,11 @@ static int build_sched_domains(const cpumask_t *cpu_map)
6672 cpus_and(this_core_map, this_core_map, *cpu_map); 5889 cpus_and(this_core_map, this_core_map, *cpu_map);
6673 if (i != first_cpu(this_core_map)) 5890 if (i != first_cpu(this_core_map))
6674 continue; 5891 continue;
6675 init_sched_build_groups(this_core_map, cpu_map, &cpu_to_core_group); 5892 init_sched_build_groups(this_core_map, cpu_map,
5893 &cpu_to_core_group);
6676 } 5894 }
6677#endif 5895#endif
6678 5896
6679
6680 /* Set up physical groups */ 5897 /* Set up physical groups */
6681 for (i = 0; i < MAX_NUMNODES; i++) { 5898 for (i = 0; i < MAX_NUMNODES; i++) {
6682 cpumask_t nodemask = node_to_cpumask(i); 5899 cpumask_t nodemask = node_to_cpumask(i);
@@ -6691,7 +5908,8 @@ static int build_sched_domains(const cpumask_t *cpu_map)
6691#ifdef CONFIG_NUMA 5908#ifdef CONFIG_NUMA
6692 /* Set up node groups */ 5909 /* Set up node groups */
6693 if (sd_allnodes) 5910 if (sd_allnodes)
6694 init_sched_build_groups(*cpu_map, cpu_map, &cpu_to_allnodes_group); 5911 init_sched_build_groups(*cpu_map, cpu_map,
5912 &cpu_to_allnodes_group);
6695 5913
6696 for (i = 0; i < MAX_NUMNODES; i++) { 5914 for (i = 0; i < MAX_NUMNODES; i++) {
6697 /* Set up node groups */ 5915 /* Set up node groups */
@@ -6719,6 +5937,7 @@ static int build_sched_domains(const cpumask_t *cpu_map)
6719 sched_group_nodes[i] = sg; 5937 sched_group_nodes[i] = sg;
6720 for_each_cpu_mask(j, nodemask) { 5938 for_each_cpu_mask(j, nodemask) {
6721 struct sched_domain *sd; 5939 struct sched_domain *sd;
5940
6722 sd = &per_cpu(node_domains, j); 5941 sd = &per_cpu(node_domains, j);
6723 sd->groups = sg; 5942 sd->groups = sg;
6724 } 5943 }
@@ -6763,19 +5982,22 @@ static int build_sched_domains(const cpumask_t *cpu_map)
6763 /* Calculate CPU power for physical packages and nodes */ 5982 /* Calculate CPU power for physical packages and nodes */
6764#ifdef CONFIG_SCHED_SMT 5983#ifdef CONFIG_SCHED_SMT
6765 for_each_cpu_mask(i, *cpu_map) { 5984 for_each_cpu_mask(i, *cpu_map) {
6766 sd = &per_cpu(cpu_domains, i); 5985 struct sched_domain *sd = &per_cpu(cpu_domains, i);
5986
6767 init_sched_groups_power(i, sd); 5987 init_sched_groups_power(i, sd);
6768 } 5988 }
6769#endif 5989#endif
6770#ifdef CONFIG_SCHED_MC 5990#ifdef CONFIG_SCHED_MC
6771 for_each_cpu_mask(i, *cpu_map) { 5991 for_each_cpu_mask(i, *cpu_map) {
6772 sd = &per_cpu(core_domains, i); 5992 struct sched_domain *sd = &per_cpu(core_domains, i);
5993
6773 init_sched_groups_power(i, sd); 5994 init_sched_groups_power(i, sd);
6774 } 5995 }
6775#endif 5996#endif
6776 5997
6777 for_each_cpu_mask(i, *cpu_map) { 5998 for_each_cpu_mask(i, *cpu_map) {
6778 sd = &per_cpu(phys_domains, i); 5999 struct sched_domain *sd = &per_cpu(phys_domains, i);
6000
6779 init_sched_groups_power(i, sd); 6001 init_sched_groups_power(i, sd);
6780 } 6002 }
6781 6003
@@ -6803,10 +6025,6 @@ static int build_sched_domains(const cpumask_t *cpu_map)
6803#endif 6025#endif
6804 cpu_attach_domain(sd, i); 6026 cpu_attach_domain(sd, i);
6805 } 6027 }
6806 /*
6807 * Tune cache-hot values:
6808 */
6809 calibrate_migration_costs(cpu_map);
6810 6028
6811 return 0; 6029 return 0;
6812 6030
@@ -7013,10 +6231,12 @@ void __init sched_init_smp(void)
7013 /* Move init over to a non-isolated CPU */ 6231 /* Move init over to a non-isolated CPU */
7014 if (set_cpus_allowed(current, non_isolated_cpus) < 0) 6232 if (set_cpus_allowed(current, non_isolated_cpus) < 0)
7015 BUG(); 6233 BUG();
6234 sched_init_granularity();
7016} 6235}
7017#else 6236#else
7018void __init sched_init_smp(void) 6237void __init sched_init_smp(void)
7019{ 6238{
6239 sched_init_granularity();
7020} 6240}
7021#endif /* CONFIG_SMP */ 6241#endif /* CONFIG_SMP */
7022 6242
@@ -7030,28 +6250,51 @@ int in_sched_functions(unsigned long addr)
7030 && addr < (unsigned long)__sched_text_end); 6250 && addr < (unsigned long)__sched_text_end);
7031} 6251}
7032 6252
6253static inline void init_cfs_rq(struct cfs_rq *cfs_rq, struct rq *rq)
6254{
6255 cfs_rq->tasks_timeline = RB_ROOT;
6256 cfs_rq->fair_clock = 1;
6257#ifdef CONFIG_FAIR_GROUP_SCHED
6258 cfs_rq->rq = rq;
6259#endif
6260}
6261
7033void __init sched_init(void) 6262void __init sched_init(void)
7034{ 6263{
7035 int i, j, k; 6264 u64 now = sched_clock();
7036 int highest_cpu = 0; 6265 int highest_cpu = 0;
6266 int i, j;
6267
6268 /*
6269 * Link up the scheduling class hierarchy:
6270 */
6271 rt_sched_class.next = &fair_sched_class;
6272 fair_sched_class.next = &idle_sched_class;
6273 idle_sched_class.next = NULL;
7037 6274
7038 for_each_possible_cpu(i) { 6275 for_each_possible_cpu(i) {
7039 struct prio_array *array; 6276 struct rt_prio_array *array;
7040 struct rq *rq; 6277 struct rq *rq;
7041 6278
7042 rq = cpu_rq(i); 6279 rq = cpu_rq(i);
7043 spin_lock_init(&rq->lock); 6280 spin_lock_init(&rq->lock);
7044 lockdep_set_class(&rq->lock, &rq->rq_lock_key); 6281 lockdep_set_class(&rq->lock, &rq->rq_lock_key);
7045 rq->nr_running = 0; 6282 rq->nr_running = 0;
7046 rq->active = rq->arrays; 6283 rq->clock = 1;
7047 rq->expired = rq->arrays + 1; 6284 init_cfs_rq(&rq->cfs, rq);
7048 rq->best_expired_prio = MAX_PRIO; 6285#ifdef CONFIG_FAIR_GROUP_SCHED
6286 INIT_LIST_HEAD(&rq->leaf_cfs_rq_list);
6287 list_add(&rq->cfs.leaf_cfs_rq_list, &rq->leaf_cfs_rq_list);
6288#endif
6289 rq->ls.load_update_last = now;
6290 rq->ls.load_update_start = now;
7049 6291
6292 for (j = 0; j < CPU_LOAD_IDX_MAX; j++)
6293 rq->cpu_load[j] = 0;
7050#ifdef CONFIG_SMP 6294#ifdef CONFIG_SMP
7051 rq->sd = NULL; 6295 rq->sd = NULL;
7052 for (j = 1; j < 3; j++)
7053 rq->cpu_load[j] = 0;
7054 rq->active_balance = 0; 6296 rq->active_balance = 0;
6297 rq->next_balance = jiffies;
7055 rq->push_cpu = 0; 6298 rq->push_cpu = 0;
7056 rq->cpu = i; 6299 rq->cpu = i;
7057 rq->migration_thread = NULL; 6300 rq->migration_thread = NULL;
@@ -7059,16 +6302,14 @@ void __init sched_init(void)
7059#endif 6302#endif
7060 atomic_set(&rq->nr_iowait, 0); 6303 atomic_set(&rq->nr_iowait, 0);
7061 6304
7062 for (j = 0; j < 2; j++) { 6305 array = &rq->rt.active;
7063 array = rq->arrays + j; 6306 for (j = 0; j < MAX_RT_PRIO; j++) {
7064 for (k = 0; k < MAX_PRIO; k++) { 6307 INIT_LIST_HEAD(array->queue + j);
7065 INIT_LIST_HEAD(array->queue + k); 6308 __clear_bit(j, array->bitmap);
7066 __clear_bit(k, array->bitmap);
7067 }
7068 // delimiter for bitsearch
7069 __set_bit(MAX_PRIO, array->bitmap);
7070 } 6309 }
7071 highest_cpu = i; 6310 highest_cpu = i;
6311 /* delimiter for bitsearch: */
6312 __set_bit(MAX_RT_PRIO, array->bitmap);
7072 } 6313 }
7073 6314
7074 set_load_weight(&init_task); 6315 set_load_weight(&init_task);
@@ -7095,6 +6336,10 @@ void __init sched_init(void)
7095 * when this runqueue becomes "idle". 6336 * when this runqueue becomes "idle".
7096 */ 6337 */
7097 init_idle(current, smp_processor_id()); 6338 init_idle(current, smp_processor_id());
6339 /*
6340 * During early bootup we pretend to be a normal task:
6341 */
6342 current->sched_class = &fair_sched_class;
7098} 6343}
7099 6344
7100#ifdef CONFIG_DEBUG_SPINLOCK_SLEEP 6345#ifdef CONFIG_DEBUG_SPINLOCK_SLEEP
@@ -7125,29 +6370,55 @@ EXPORT_SYMBOL(__might_sleep);
7125#ifdef CONFIG_MAGIC_SYSRQ 6370#ifdef CONFIG_MAGIC_SYSRQ
7126void normalize_rt_tasks(void) 6371void normalize_rt_tasks(void)
7127{ 6372{
7128 struct prio_array *array;
7129 struct task_struct *g, *p; 6373 struct task_struct *g, *p;
7130 unsigned long flags; 6374 unsigned long flags;
7131 struct rq *rq; 6375 struct rq *rq;
6376 int on_rq;
7132 6377
7133 read_lock_irq(&tasklist_lock); 6378 read_lock_irq(&tasklist_lock);
7134
7135 do_each_thread(g, p) { 6379 do_each_thread(g, p) {
7136 if (!rt_task(p)) 6380 p->se.fair_key = 0;
6381 p->se.wait_runtime = 0;
6382 p->se.wait_start_fair = 0;
6383 p->se.wait_start = 0;
6384 p->se.exec_start = 0;
6385 p->se.sleep_start = 0;
6386 p->se.sleep_start_fair = 0;
6387 p->se.block_start = 0;
6388 task_rq(p)->cfs.fair_clock = 0;
6389 task_rq(p)->clock = 0;
6390
6391 if (!rt_task(p)) {
6392 /*
6393 * Renice negative nice level userspace
6394 * tasks back to 0:
6395 */
6396 if (TASK_NICE(p) < 0 && p->mm)
6397 set_user_nice(p, 0);
7137 continue; 6398 continue;
6399 }
7138 6400
7139 spin_lock_irqsave(&p->pi_lock, flags); 6401 spin_lock_irqsave(&p->pi_lock, flags);
7140 rq = __task_rq_lock(p); 6402 rq = __task_rq_lock(p);
6403#ifdef CONFIG_SMP
6404 /*
6405 * Do not touch the migration thread:
6406 */
6407 if (p == rq->migration_thread)
6408 goto out_unlock;
6409#endif
7141 6410
7142 array = p->array; 6411 on_rq = p->se.on_rq;
7143 if (array) 6412 if (on_rq)
7144 deactivate_task(p, task_rq(p)); 6413 deactivate_task(task_rq(p), p, 0);
7145 __setscheduler(p, SCHED_NORMAL, 0); 6414 __setscheduler(rq, p, SCHED_NORMAL, 0);
7146 if (array) { 6415 if (on_rq) {
7147 __activate_task(p, task_rq(p)); 6416 activate_task(task_rq(p), p, 0);
7148 resched_task(rq->curr); 6417 resched_task(rq->curr);
7149 } 6418 }
7150 6419#ifdef CONFIG_SMP
6420 out_unlock:
6421#endif
7151 __task_rq_unlock(rq); 6422 __task_rq_unlock(rq);
7152 spin_unlock_irqrestore(&p->pi_lock, flags); 6423 spin_unlock_irqrestore(&p->pi_lock, flags);
7153 } while_each_thread(g, p); 6424 } while_each_thread(g, p);
diff --git a/kernel/sched_debug.c b/kernel/sched_debug.c
new file mode 100644
index 000000000000..1baf87cceb7c
--- /dev/null
+++ b/kernel/sched_debug.c
@@ -0,0 +1,275 @@
1/*
2 * kernel/time/sched_debug.c
3 *
4 * Print the CFS rbtree
5 *
6 * Copyright(C) 2007, Red Hat, Inc., Ingo Molnar
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/proc_fs.h>
14#include <linux/sched.h>
15#include <linux/seq_file.h>
16#include <linux/kallsyms.h>
17#include <linux/utsname.h>
18
19/*
20 * This allows printing both to /proc/sched_debug and
21 * to the console
22 */
23#define SEQ_printf(m, x...) \
24 do { \
25 if (m) \
26 seq_printf(m, x); \
27 else \
28 printk(x); \
29 } while (0)
30
31static void
32print_task(struct seq_file *m, struct rq *rq, struct task_struct *p, u64 now)
33{
34 if (rq->curr == p)
35 SEQ_printf(m, "R");
36 else
37 SEQ_printf(m, " ");
38
39 SEQ_printf(m, "%15s %5d %15Ld %13Ld %13Ld %9Ld %5d "
40 "%15Ld %15Ld %15Ld %15Ld %15Ld\n",
41 p->comm, p->pid,
42 (long long)p->se.fair_key,
43 (long long)(p->se.fair_key - rq->cfs.fair_clock),
44 (long long)p->se.wait_runtime,
45 (long long)(p->nvcsw + p->nivcsw),
46 p->prio,
47 (long long)p->se.sum_exec_runtime,
48 (long long)p->se.sum_wait_runtime,
49 (long long)p->se.sum_sleep_runtime,
50 (long long)p->se.wait_runtime_overruns,
51 (long long)p->se.wait_runtime_underruns);
52}
53
54static void print_rq(struct seq_file *m, struct rq *rq, int rq_cpu, u64 now)
55{
56 struct task_struct *g, *p;
57
58 SEQ_printf(m,
59 "\nrunnable tasks:\n"
60 " task PID tree-key delta waiting"
61 " switches prio"
62 " sum-exec sum-wait sum-sleep"
63 " wait-overrun wait-underrun\n"
64 "------------------------------------------------------------------"
65 "----------------"
66 "------------------------------------------------"
67 "--------------------------------\n");
68
69 read_lock_irq(&tasklist_lock);
70
71 do_each_thread(g, p) {
72 if (!p->se.on_rq || task_cpu(p) != rq_cpu)
73 continue;
74
75 print_task(m, rq, p, now);
76 } while_each_thread(g, p);
77
78 read_unlock_irq(&tasklist_lock);
79}
80
81static void
82print_cfs_rq_runtime_sum(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq)
83{
84 s64 wait_runtime_rq_sum = 0;
85 struct task_struct *p;
86 struct rb_node *curr;
87 unsigned long flags;
88 struct rq *rq = &per_cpu(runqueues, cpu);
89
90 spin_lock_irqsave(&rq->lock, flags);
91 curr = first_fair(cfs_rq);
92 while (curr) {
93 p = rb_entry(curr, struct task_struct, se.run_node);
94 wait_runtime_rq_sum += p->se.wait_runtime;
95
96 curr = rb_next(curr);
97 }
98 spin_unlock_irqrestore(&rq->lock, flags);
99
100 SEQ_printf(m, " .%-30s: %Ld\n", "wait_runtime_rq_sum",
101 (long long)wait_runtime_rq_sum);
102}
103
104void print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq, u64 now)
105{
106 SEQ_printf(m, "\ncfs_rq %p\n", cfs_rq);
107
108#define P(x) \
109 SEQ_printf(m, " .%-30s: %Ld\n", #x, (long long)(cfs_rq->x))
110
111 P(fair_clock);
112 P(exec_clock);
113 P(wait_runtime);
114 P(wait_runtime_overruns);
115 P(wait_runtime_underruns);
116 P(sleeper_bonus);
117#undef P
118
119 print_cfs_rq_runtime_sum(m, cpu, cfs_rq);
120}
121
122static void print_cpu(struct seq_file *m, int cpu, u64 now)
123{
124 struct rq *rq = &per_cpu(runqueues, cpu);
125
126#ifdef CONFIG_X86
127 {
128 unsigned int freq = cpu_khz ? : 1;
129
130 SEQ_printf(m, "\ncpu#%d, %u.%03u MHz\n",
131 cpu, freq / 1000, (freq % 1000));
132 }
133#else
134 SEQ_printf(m, "\ncpu#%d\n", cpu);
135#endif
136
137#define P(x) \
138 SEQ_printf(m, " .%-30s: %Ld\n", #x, (long long)(rq->x))
139
140 P(nr_running);
141 SEQ_printf(m, " .%-30s: %lu\n", "load",
142 rq->ls.load.weight);
143 P(ls.delta_fair);
144 P(ls.delta_exec);
145 P(nr_switches);
146 P(nr_load_updates);
147 P(nr_uninterruptible);
148 SEQ_printf(m, " .%-30s: %lu\n", "jiffies", jiffies);
149 P(next_balance);
150 P(curr->pid);
151 P(clock);
152 P(prev_clock_raw);
153 P(clock_warps);
154 P(clock_overflows);
155 P(clock_unstable_events);
156 P(clock_max_delta);
157 P(cpu_load[0]);
158 P(cpu_load[1]);
159 P(cpu_load[2]);
160 P(cpu_load[3]);
161 P(cpu_load[4]);
162#undef P
163
164 print_cfs_stats(m, cpu, now);
165
166 print_rq(m, rq, cpu, now);
167}
168
169static int sched_debug_show(struct seq_file *m, void *v)
170{
171 u64 now = ktime_to_ns(ktime_get());
172 int cpu;
173
174 SEQ_printf(m, "Sched Debug Version: v0.04, cfs-v20, %s %.*s\n",
175 init_utsname()->release,
176 (int)strcspn(init_utsname()->version, " "),
177 init_utsname()->version);
178
179 SEQ_printf(m, "now at %Lu nsecs\n", (unsigned long long)now);
180
181 for_each_online_cpu(cpu)
182 print_cpu(m, cpu, now);
183
184 SEQ_printf(m, "\n");
185
186 return 0;
187}
188
189void sysrq_sched_debug_show(void)
190{
191 sched_debug_show(NULL, NULL);
192}
193
194static int sched_debug_open(struct inode *inode, struct file *filp)
195{
196 return single_open(filp, sched_debug_show, NULL);
197}
198
199static struct file_operations sched_debug_fops = {
200 .open = sched_debug_open,
201 .read = seq_read,
202 .llseek = seq_lseek,
203 .release = seq_release,
204};
205
206static int __init init_sched_debug_procfs(void)
207{
208 struct proc_dir_entry *pe;
209
210 pe = create_proc_entry("sched_debug", 0644, NULL);
211 if (!pe)
212 return -ENOMEM;
213
214 pe->proc_fops = &sched_debug_fops;
215
216 return 0;
217}
218
219__initcall(init_sched_debug_procfs);
220
221void proc_sched_show_task(struct task_struct *p, struct seq_file *m)
222{
223 unsigned long flags;
224 int num_threads = 1;
225
226 rcu_read_lock();
227 if (lock_task_sighand(p, &flags)) {
228 num_threads = atomic_read(&p->signal->count);
229 unlock_task_sighand(p, &flags);
230 }
231 rcu_read_unlock();
232
233 SEQ_printf(m, "%s (%d, #threads: %d)\n", p->comm, p->pid, num_threads);
234 SEQ_printf(m, "----------------------------------------------\n");
235#define P(F) \
236 SEQ_printf(m, "%-25s:%20Ld\n", #F, (long long)p->F)
237
238 P(se.wait_start);
239 P(se.wait_start_fair);
240 P(se.exec_start);
241 P(se.sleep_start);
242 P(se.sleep_start_fair);
243 P(se.block_start);
244 P(se.sleep_max);
245 P(se.block_max);
246 P(se.exec_max);
247 P(se.wait_max);
248 P(se.wait_runtime);
249 P(se.wait_runtime_overruns);
250 P(se.wait_runtime_underruns);
251 P(se.sum_wait_runtime);
252 P(se.sum_exec_runtime);
253 SEQ_printf(m, "%-25s:%20Ld\n",
254 "nr_switches", (long long)(p->nvcsw + p->nivcsw));
255 P(se.load.weight);
256 P(policy);
257 P(prio);
258#undef P
259
260 {
261 u64 t0, t1;
262
263 t0 = sched_clock();
264 t1 = sched_clock();
265 SEQ_printf(m, "%-25s:%20Ld\n",
266 "clock-delta", (long long)(t1-t0));
267 }
268}
269
270void proc_sched_set_task(struct task_struct *p)
271{
272 p->se.sleep_max = p->se.block_max = p->se.exec_max = p->se.wait_max = 0;
273 p->se.wait_runtime_overruns = p->se.wait_runtime_underruns = 0;
274 p->se.sum_exec_runtime = 0;
275}
diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c
new file mode 100644
index 000000000000..6971db0a7160
--- /dev/null
+++ b/kernel/sched_fair.c
@@ -0,0 +1,1131 @@
1/*
2 * Completely Fair Scheduling (CFS) Class (SCHED_NORMAL/SCHED_BATCH)
3 *
4 * Copyright (C) 2007 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
5 *
6 * Interactivity improvements by Mike Galbraith
7 * (C) 2007 Mike Galbraith <efault@gmx.de>
8 *
9 * Various enhancements by Dmitry Adamushko.
10 * (C) 2007 Dmitry Adamushko <dmitry.adamushko@gmail.com>
11 *
12 * Group scheduling enhancements by Srivatsa Vaddagiri
13 * Copyright IBM Corporation, 2007
14 * Author: Srivatsa Vaddagiri <vatsa@linux.vnet.ibm.com>
15 *
16 * Scaled math optimizations by Thomas Gleixner
17 * Copyright (C) 2007, Thomas Gleixner <tglx@linutronix.de>
18 */
19
20/*
21 * Preemption granularity:
22 * (default: 2 msec, units: nanoseconds)
23 *
24 * NOTE: this granularity value is not the same as the concept of
25 * 'timeslice length' - timeslices in CFS will typically be somewhat
26 * larger than this value. (to see the precise effective timeslice
27 * length of your workload, run vmstat and monitor the context-switches
28 * field)
29 *
30 * On SMP systems the value of this is multiplied by the log2 of the
31 * number of CPUs. (i.e. factor 2x on 2-way systems, 3x on 4-way
32 * systems, 4x on 8-way systems, 5x on 16-way systems, etc.)
33 */
34unsigned int sysctl_sched_granularity __read_mostly = 2000000000ULL/HZ;
35
36/*
37 * SCHED_BATCH wake-up granularity.
38 * (default: 10 msec, units: nanoseconds)
39 *
40 * This option delays the preemption effects of decoupled workloads
41 * and reduces their over-scheduling. Synchronous workloads will still
42 * have immediate wakeup/sleep latencies.
43 */
44unsigned int sysctl_sched_batch_wakeup_granularity __read_mostly =
45 10000000000ULL/HZ;
46
47/*
48 * SCHED_OTHER wake-up granularity.
49 * (default: 1 msec, units: nanoseconds)
50 *
51 * This option delays the preemption effects of decoupled workloads
52 * and reduces their over-scheduling. Synchronous workloads will still
53 * have immediate wakeup/sleep latencies.
54 */
55unsigned int sysctl_sched_wakeup_granularity __read_mostly = 1000000000ULL/HZ;
56
57unsigned int sysctl_sched_stat_granularity __read_mostly;
58
59/*
60 * Initialized in sched_init_granularity():
61 */
62unsigned int sysctl_sched_runtime_limit __read_mostly;
63
64/*
65 * Debugging: various feature bits
66 */
67enum {
68 SCHED_FEAT_FAIR_SLEEPERS = 1,
69 SCHED_FEAT_SLEEPER_AVG = 2,
70 SCHED_FEAT_SLEEPER_LOAD_AVG = 4,
71 SCHED_FEAT_PRECISE_CPU_LOAD = 8,
72 SCHED_FEAT_START_DEBIT = 16,
73 SCHED_FEAT_SKIP_INITIAL = 32,
74};
75
76unsigned int sysctl_sched_features __read_mostly =
77 SCHED_FEAT_FAIR_SLEEPERS *1 |
78 SCHED_FEAT_SLEEPER_AVG *1 |
79 SCHED_FEAT_SLEEPER_LOAD_AVG *1 |
80 SCHED_FEAT_PRECISE_CPU_LOAD *1 |
81 SCHED_FEAT_START_DEBIT *1 |
82 SCHED_FEAT_SKIP_INITIAL *0;
83
84extern struct sched_class fair_sched_class;
85
86/**************************************************************
87 * CFS operations on generic schedulable entities:
88 */
89
90#ifdef CONFIG_FAIR_GROUP_SCHED
91
92/* cpu runqueue to which this cfs_rq is attached */
93static inline struct rq *rq_of(struct cfs_rq *cfs_rq)
94{
95 return cfs_rq->rq;
96}
97
98/* currently running entity (if any) on this cfs_rq */
99static inline struct sched_entity *cfs_rq_curr(struct cfs_rq *cfs_rq)
100{
101 return cfs_rq->curr;
102}
103
104/* An entity is a task if it doesn't "own" a runqueue */
105#define entity_is_task(se) (!se->my_q)
106
107static inline void
108set_cfs_rq_curr(struct cfs_rq *cfs_rq, struct sched_entity *se)
109{
110 cfs_rq->curr = se;
111}
112
113#else /* CONFIG_FAIR_GROUP_SCHED */
114
115static inline struct rq *rq_of(struct cfs_rq *cfs_rq)
116{
117 return container_of(cfs_rq, struct rq, cfs);
118}
119
120static inline struct sched_entity *cfs_rq_curr(struct cfs_rq *cfs_rq)
121{
122 struct rq *rq = rq_of(cfs_rq);
123
124 if (unlikely(rq->curr->sched_class != &fair_sched_class))
125 return NULL;
126
127 return &rq->curr->se;
128}
129
130#define entity_is_task(se) 1
131
132static inline void
133set_cfs_rq_curr(struct cfs_rq *cfs_rq, struct sched_entity *se) { }
134
135#endif /* CONFIG_FAIR_GROUP_SCHED */
136
137static inline struct task_struct *task_of(struct sched_entity *se)
138{
139 return container_of(se, struct task_struct, se);
140}
141
142
143/**************************************************************
144 * Scheduling class tree data structure manipulation methods:
145 */
146
147/*
148 * Enqueue an entity into the rb-tree:
149 */
150static inline void
151__enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se)
152{
153 struct rb_node **link = &cfs_rq->tasks_timeline.rb_node;
154 struct rb_node *parent = NULL;
155 struct sched_entity *entry;
156 s64 key = se->fair_key;
157 int leftmost = 1;
158
159 /*
160 * Find the right place in the rbtree:
161 */
162 while (*link) {
163 parent = *link;
164 entry = rb_entry(parent, struct sched_entity, run_node);
165 /*
166 * We dont care about collisions. Nodes with
167 * the same key stay together.
168 */
169 if (key - entry->fair_key < 0) {
170 link = &parent->rb_left;
171 } else {
172 link = &parent->rb_right;
173 leftmost = 0;
174 }
175 }
176
177 /*
178 * Maintain a cache of leftmost tree entries (it is frequently
179 * used):
180 */
181 if (leftmost)
182 cfs_rq->rb_leftmost = &se->run_node;
183
184 rb_link_node(&se->run_node, parent, link);
185 rb_insert_color(&se->run_node, &cfs_rq->tasks_timeline);
186 update_load_add(&cfs_rq->load, se->load.weight);
187 cfs_rq->nr_running++;
188 se->on_rq = 1;
189}
190
191static inline void
192__dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se)
193{
194 if (cfs_rq->rb_leftmost == &se->run_node)
195 cfs_rq->rb_leftmost = rb_next(&se->run_node);
196 rb_erase(&se->run_node, &cfs_rq->tasks_timeline);
197 update_load_sub(&cfs_rq->load, se->load.weight);
198 cfs_rq->nr_running--;
199 se->on_rq = 0;
200}
201
202static inline struct rb_node *first_fair(struct cfs_rq *cfs_rq)
203{
204 return cfs_rq->rb_leftmost;
205}
206
207static struct sched_entity *__pick_next_entity(struct cfs_rq *cfs_rq)
208{
209 return rb_entry(first_fair(cfs_rq), struct sched_entity, run_node);
210}
211
212/**************************************************************
213 * Scheduling class statistics methods:
214 */
215
216/*
217 * We rescale the rescheduling granularity of tasks according to their
218 * nice level, but only linearly, not exponentially:
219 */
220static long
221niced_granularity(struct sched_entity *curr, unsigned long granularity)
222{
223 u64 tmp;
224
225 /*
226 * Negative nice levels get the same granularity as nice-0:
227 */
228 if (likely(curr->load.weight >= NICE_0_LOAD))
229 return granularity;
230 /*
231 * Positive nice level tasks get linearly finer
232 * granularity:
233 */
234 tmp = curr->load.weight * (u64)granularity;
235
236 /*
237 * It will always fit into 'long':
238 */
239 return (long) (tmp >> NICE_0_SHIFT);
240}
241
242static inline void
243limit_wait_runtime(struct cfs_rq *cfs_rq, struct sched_entity *se)
244{
245 long limit = sysctl_sched_runtime_limit;
246
247 /*
248 * Niced tasks have the same history dynamic range as
249 * non-niced tasks:
250 */
251 if (unlikely(se->wait_runtime > limit)) {
252 se->wait_runtime = limit;
253 schedstat_inc(se, wait_runtime_overruns);
254 schedstat_inc(cfs_rq, wait_runtime_overruns);
255 }
256 if (unlikely(se->wait_runtime < -limit)) {
257 se->wait_runtime = -limit;
258 schedstat_inc(se, wait_runtime_underruns);
259 schedstat_inc(cfs_rq, wait_runtime_underruns);
260 }
261}
262
263static inline void
264__add_wait_runtime(struct cfs_rq *cfs_rq, struct sched_entity *se, long delta)
265{
266 se->wait_runtime += delta;
267 schedstat_add(se, sum_wait_runtime, delta);
268 limit_wait_runtime(cfs_rq, se);
269}
270
271static void
272add_wait_runtime(struct cfs_rq *cfs_rq, struct sched_entity *se, long delta)
273{
274 schedstat_add(cfs_rq, wait_runtime, -se->wait_runtime);
275 __add_wait_runtime(cfs_rq, se, delta);
276 schedstat_add(cfs_rq, wait_runtime, se->wait_runtime);
277}
278
279/*
280 * Update the current task's runtime statistics. Skip current tasks that
281 * are not in our scheduling class.
282 */
283static inline void
284__update_curr(struct cfs_rq *cfs_rq, struct sched_entity *curr, u64 now)
285{
286 unsigned long delta, delta_exec, delta_fair;
287 long delta_mine;
288 struct load_weight *lw = &cfs_rq->load;
289 unsigned long load = lw->weight;
290
291 if (unlikely(!load))
292 return;
293
294 delta_exec = curr->delta_exec;
295#ifdef CONFIG_SCHEDSTATS
296 if (unlikely(delta_exec > curr->exec_max))
297 curr->exec_max = delta_exec;
298#endif
299
300 curr->sum_exec_runtime += delta_exec;
301 cfs_rq->exec_clock += delta_exec;
302
303 delta_fair = calc_delta_fair(delta_exec, lw);
304 delta_mine = calc_delta_mine(delta_exec, curr->load.weight, lw);
305
306 if (cfs_rq->sleeper_bonus > sysctl_sched_stat_granularity) {
307 delta = calc_delta_mine(cfs_rq->sleeper_bonus,
308 curr->load.weight, lw);
309 if (unlikely(delta > cfs_rq->sleeper_bonus))
310 delta = cfs_rq->sleeper_bonus;
311
312 cfs_rq->sleeper_bonus -= delta;
313 delta_mine -= delta;
314 }
315
316 cfs_rq->fair_clock += delta_fair;
317 /*
318 * We executed delta_exec amount of time on the CPU,
319 * but we were only entitled to delta_mine amount of
320 * time during that period (if nr_running == 1 then
321 * the two values are equal)
322 * [Note: delta_mine - delta_exec is negative]:
323 */
324 add_wait_runtime(cfs_rq, curr, delta_mine - delta_exec);
325}
326
327static void update_curr(struct cfs_rq *cfs_rq, u64 now)
328{
329 struct sched_entity *curr = cfs_rq_curr(cfs_rq);
330 unsigned long delta_exec;
331
332 if (unlikely(!curr))
333 return;
334
335 /*
336 * Get the amount of time the current task was running
337 * since the last time we changed load (this cannot
338 * overflow on 32 bits):
339 */
340 delta_exec = (unsigned long)(now - curr->exec_start);
341
342 curr->delta_exec += delta_exec;
343
344 if (unlikely(curr->delta_exec > sysctl_sched_stat_granularity)) {
345 __update_curr(cfs_rq, curr, now);
346 curr->delta_exec = 0;
347 }
348 curr->exec_start = now;
349}
350
351static inline void
352update_stats_wait_start(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now)
353{
354 se->wait_start_fair = cfs_rq->fair_clock;
355 se->wait_start = now;
356}
357
358/*
359 * We calculate fair deltas here, so protect against the random effects
360 * of a multiplication overflow by capping it to the runtime limit:
361 */
362#if BITS_PER_LONG == 32
363static inline unsigned long
364calc_weighted(unsigned long delta, unsigned long weight, int shift)
365{
366 u64 tmp = (u64)delta * weight >> shift;
367
368 if (unlikely(tmp > sysctl_sched_runtime_limit*2))
369 return sysctl_sched_runtime_limit*2;
370 return tmp;
371}
372#else
373static inline unsigned long
374calc_weighted(unsigned long delta, unsigned long weight, int shift)
375{
376 return delta * weight >> shift;
377}
378#endif
379
380/*
381 * Task is being enqueued - update stats:
382 */
383static void
384update_stats_enqueue(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now)
385{
386 s64 key;
387
388 /*
389 * Are we enqueueing a waiting task? (for current tasks
390 * a dequeue/enqueue event is a NOP)
391 */
392 if (se != cfs_rq_curr(cfs_rq))
393 update_stats_wait_start(cfs_rq, se, now);
394 /*
395 * Update the key:
396 */
397 key = cfs_rq->fair_clock;
398
399 /*
400 * Optimize the common nice 0 case:
401 */
402 if (likely(se->load.weight == NICE_0_LOAD)) {
403 key -= se->wait_runtime;
404 } else {
405 u64 tmp;
406
407 if (se->wait_runtime < 0) {
408 tmp = -se->wait_runtime;
409 key += (tmp * se->load.inv_weight) >>
410 (WMULT_SHIFT - NICE_0_SHIFT);
411 } else {
412 tmp = se->wait_runtime;
413 key -= (tmp * se->load.weight) >> NICE_0_SHIFT;
414 }
415 }
416
417 se->fair_key = key;
418}
419
420/*
421 * Note: must be called with a freshly updated rq->fair_clock.
422 */
423static inline void
424__update_stats_wait_end(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now)
425{
426 unsigned long delta_fair = se->delta_fair_run;
427
428#ifdef CONFIG_SCHEDSTATS
429 {
430 s64 delta_wait = now - se->wait_start;
431 if (unlikely(delta_wait > se->wait_max))
432 se->wait_max = delta_wait;
433 }
434#endif
435
436 if (unlikely(se->load.weight != NICE_0_LOAD))
437 delta_fair = calc_weighted(delta_fair, se->load.weight,
438 NICE_0_SHIFT);
439
440 add_wait_runtime(cfs_rq, se, delta_fair);
441}
442
443static void
444update_stats_wait_end(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now)
445{
446 unsigned long delta_fair;
447
448 delta_fair = (unsigned long)min((u64)(2*sysctl_sched_runtime_limit),
449 (u64)(cfs_rq->fair_clock - se->wait_start_fair));
450
451 se->delta_fair_run += delta_fair;
452 if (unlikely(abs(se->delta_fair_run) >=
453 sysctl_sched_stat_granularity)) {
454 __update_stats_wait_end(cfs_rq, se, now);
455 se->delta_fair_run = 0;
456 }
457
458 se->wait_start_fair = 0;
459 se->wait_start = 0;
460}
461
462static inline void
463update_stats_dequeue(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now)
464{
465 update_curr(cfs_rq, now);
466 /*
467 * Mark the end of the wait period if dequeueing a
468 * waiting task:
469 */
470 if (se != cfs_rq_curr(cfs_rq))
471 update_stats_wait_end(cfs_rq, se, now);
472}
473
474/*
475 * We are picking a new current task - update its stats:
476 */
477static inline void
478update_stats_curr_start(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now)
479{
480 /*
481 * We are starting a new run period:
482 */
483 se->exec_start = now;
484}
485
486/*
487 * We are descheduling a task - update its stats:
488 */
489static inline void
490update_stats_curr_end(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now)
491{
492 se->exec_start = 0;
493}
494
495/**************************************************
496 * Scheduling class queueing methods:
497 */
498
499static void
500__enqueue_sleeper(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now)
501{
502 unsigned long load = cfs_rq->load.weight, delta_fair;
503 long prev_runtime;
504
505 if (sysctl_sched_features & SCHED_FEAT_SLEEPER_LOAD_AVG)
506 load = rq_of(cfs_rq)->cpu_load[2];
507
508 delta_fair = se->delta_fair_sleep;
509
510 /*
511 * Fix up delta_fair with the effect of us running
512 * during the whole sleep period:
513 */
514 if (sysctl_sched_features & SCHED_FEAT_SLEEPER_AVG)
515 delta_fair = div64_likely32((u64)delta_fair * load,
516 load + se->load.weight);
517
518 if (unlikely(se->load.weight != NICE_0_LOAD))
519 delta_fair = calc_weighted(delta_fair, se->load.weight,
520 NICE_0_SHIFT);
521
522 prev_runtime = se->wait_runtime;
523 __add_wait_runtime(cfs_rq, se, delta_fair);
524 delta_fair = se->wait_runtime - prev_runtime;
525
526 /*
527 * Track the amount of bonus we've given to sleepers:
528 */
529 cfs_rq->sleeper_bonus += delta_fair;
530
531 schedstat_add(cfs_rq, wait_runtime, se->wait_runtime);
532}
533
534static void
535enqueue_sleeper(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now)
536{
537 struct task_struct *tsk = task_of(se);
538 unsigned long delta_fair;
539
540 if ((entity_is_task(se) && tsk->policy == SCHED_BATCH) ||
541 !(sysctl_sched_features & SCHED_FEAT_FAIR_SLEEPERS))
542 return;
543
544 delta_fair = (unsigned long)min((u64)(2*sysctl_sched_runtime_limit),
545 (u64)(cfs_rq->fair_clock - se->sleep_start_fair));
546
547 se->delta_fair_sleep += delta_fair;
548 if (unlikely(abs(se->delta_fair_sleep) >=
549 sysctl_sched_stat_granularity)) {
550 __enqueue_sleeper(cfs_rq, se, now);
551 se->delta_fair_sleep = 0;
552 }
553
554 se->sleep_start_fair = 0;
555
556#ifdef CONFIG_SCHEDSTATS
557 if (se->sleep_start) {
558 u64 delta = now - se->sleep_start;
559
560 if ((s64)delta < 0)
561 delta = 0;
562
563 if (unlikely(delta > se->sleep_max))
564 se->sleep_max = delta;
565
566 se->sleep_start = 0;
567 se->sum_sleep_runtime += delta;
568 }
569 if (se->block_start) {
570 u64 delta = now - se->block_start;
571
572 if ((s64)delta < 0)
573 delta = 0;
574
575 if (unlikely(delta > se->block_max))
576 se->block_max = delta;
577
578 se->block_start = 0;
579 se->sum_sleep_runtime += delta;
580 }
581#endif
582}
583
584static void
585enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se,
586 int wakeup, u64 now)
587{
588 /*
589 * Update the fair clock.
590 */
591 update_curr(cfs_rq, now);
592
593 if (wakeup)
594 enqueue_sleeper(cfs_rq, se, now);
595
596 update_stats_enqueue(cfs_rq, se, now);
597 __enqueue_entity(cfs_rq, se);
598}
599
600static void
601dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se,
602 int sleep, u64 now)
603{
604 update_stats_dequeue(cfs_rq, se, now);
605 if (sleep) {
606 se->sleep_start_fair = cfs_rq->fair_clock;
607#ifdef CONFIG_SCHEDSTATS
608 if (entity_is_task(se)) {
609 struct task_struct *tsk = task_of(se);
610
611 if (tsk->state & TASK_INTERRUPTIBLE)
612 se->sleep_start = now;
613 if (tsk->state & TASK_UNINTERRUPTIBLE)
614 se->block_start = now;
615 }
616 cfs_rq->wait_runtime -= se->wait_runtime;
617#endif
618 }
619 __dequeue_entity(cfs_rq, se);
620}
621
622/*
623 * Preempt the current task with a newly woken task if needed:
624 */
625static void
626__check_preempt_curr_fair(struct cfs_rq *cfs_rq, struct sched_entity *se,
627 struct sched_entity *curr, unsigned long granularity)
628{
629 s64 __delta = curr->fair_key - se->fair_key;
630
631 /*
632 * Take scheduling granularity into account - do not
633 * preempt the current task unless the best task has
634 * a larger than sched_granularity fairness advantage:
635 */
636 if (__delta > niced_granularity(curr, granularity))
637 resched_task(rq_of(cfs_rq)->curr);
638}
639
640static inline void
641set_next_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now)
642{
643 /*
644 * Any task has to be enqueued before it get to execute on
645 * a CPU. So account for the time it spent waiting on the
646 * runqueue. (note, here we rely on pick_next_task() having
647 * done a put_prev_task_fair() shortly before this, which
648 * updated rq->fair_clock - used by update_stats_wait_end())
649 */
650 update_stats_wait_end(cfs_rq, se, now);
651 update_stats_curr_start(cfs_rq, se, now);
652 set_cfs_rq_curr(cfs_rq, se);
653}
654
655static struct sched_entity *pick_next_entity(struct cfs_rq *cfs_rq, u64 now)
656{
657 struct sched_entity *se = __pick_next_entity(cfs_rq);
658
659 set_next_entity(cfs_rq, se, now);
660
661 return se;
662}
663
664static void
665put_prev_entity(struct cfs_rq *cfs_rq, struct sched_entity *prev, u64 now)
666{
667 /*
668 * If still on the runqueue then deactivate_task()
669 * was not called and update_curr() has to be done:
670 */
671 if (prev->on_rq)
672 update_curr(cfs_rq, now);
673
674 update_stats_curr_end(cfs_rq, prev, now);
675
676 if (prev->on_rq)
677 update_stats_wait_start(cfs_rq, prev, now);
678 set_cfs_rq_curr(cfs_rq, NULL);
679}
680
681static void entity_tick(struct cfs_rq *cfs_rq, struct sched_entity *curr)
682{
683 struct rq *rq = rq_of(cfs_rq);
684 struct sched_entity *next;
685 u64 now = __rq_clock(rq);
686
687 /*
688 * Dequeue and enqueue the task to update its
689 * position within the tree:
690 */
691 dequeue_entity(cfs_rq, curr, 0, now);
692 enqueue_entity(cfs_rq, curr, 0, now);
693
694 /*
695 * Reschedule if another task tops the current one.
696 */
697 next = __pick_next_entity(cfs_rq);
698 if (next == curr)
699 return;
700
701 __check_preempt_curr_fair(cfs_rq, next, curr, sysctl_sched_granularity);
702}
703
704/**************************************************
705 * CFS operations on tasks:
706 */
707
708#ifdef CONFIG_FAIR_GROUP_SCHED
709
710/* Walk up scheduling entities hierarchy */
711#define for_each_sched_entity(se) \
712 for (; se; se = se->parent)
713
714static inline struct cfs_rq *task_cfs_rq(struct task_struct *p)
715{
716 return p->se.cfs_rq;
717}
718
719/* runqueue on which this entity is (to be) queued */
720static inline struct cfs_rq *cfs_rq_of(struct sched_entity *se)
721{
722 return se->cfs_rq;
723}
724
725/* runqueue "owned" by this group */
726static inline struct cfs_rq *group_cfs_rq(struct sched_entity *grp)
727{
728 return grp->my_q;
729}
730
731/* Given a group's cfs_rq on one cpu, return its corresponding cfs_rq on
732 * another cpu ('this_cpu')
733 */
734static inline struct cfs_rq *cpu_cfs_rq(struct cfs_rq *cfs_rq, int this_cpu)
735{
736 /* A later patch will take group into account */
737 return &cpu_rq(this_cpu)->cfs;
738}
739
740/* Iterate thr' all leaf cfs_rq's on a runqueue */
741#define for_each_leaf_cfs_rq(rq, cfs_rq) \
742 list_for_each_entry(cfs_rq, &rq->leaf_cfs_rq_list, leaf_cfs_rq_list)
743
744/* Do the two (enqueued) tasks belong to the same group ? */
745static inline int is_same_group(struct task_struct *curr, struct task_struct *p)
746{
747 if (curr->se.cfs_rq == p->se.cfs_rq)
748 return 1;
749
750 return 0;
751}
752
753#else /* CONFIG_FAIR_GROUP_SCHED */
754
755#define for_each_sched_entity(se) \
756 for (; se; se = NULL)
757
758static inline struct cfs_rq *task_cfs_rq(struct task_struct *p)
759{
760 return &task_rq(p)->cfs;
761}
762
763static inline struct cfs_rq *cfs_rq_of(struct sched_entity *se)
764{
765 struct task_struct *p = task_of(se);
766 struct rq *rq = task_rq(p);
767
768 return &rq->cfs;
769}
770
771/* runqueue "owned" by this group */
772static inline struct cfs_rq *group_cfs_rq(struct sched_entity *grp)
773{
774 return NULL;
775}
776
777static inline struct cfs_rq *cpu_cfs_rq(struct cfs_rq *cfs_rq, int this_cpu)
778{
779 return &cpu_rq(this_cpu)->cfs;
780}
781
782#define for_each_leaf_cfs_rq(rq, cfs_rq) \
783 for (cfs_rq = &rq->cfs; cfs_rq; cfs_rq = NULL)
784
785static inline int is_same_group(struct task_struct *curr, struct task_struct *p)
786{
787 return 1;
788}
789
790#endif /* CONFIG_FAIR_GROUP_SCHED */
791
792/*
793 * The enqueue_task method is called before nr_running is
794 * increased. Here we update the fair scheduling stats and
795 * then put the task into the rbtree:
796 */
797static void
798enqueue_task_fair(struct rq *rq, struct task_struct *p, int wakeup, u64 now)
799{
800 struct cfs_rq *cfs_rq;
801 struct sched_entity *se = &p->se;
802
803 for_each_sched_entity(se) {
804 if (se->on_rq)
805 break;
806 cfs_rq = cfs_rq_of(se);
807 enqueue_entity(cfs_rq, se, wakeup, now);
808 }
809}
810
811/*
812 * The dequeue_task method is called before nr_running is
813 * decreased. We remove the task from the rbtree and
814 * update the fair scheduling stats:
815 */
816static void
817dequeue_task_fair(struct rq *rq, struct task_struct *p, int sleep, u64 now)
818{
819 struct cfs_rq *cfs_rq;
820 struct sched_entity *se = &p->se;
821
822 for_each_sched_entity(se) {
823 cfs_rq = cfs_rq_of(se);
824 dequeue_entity(cfs_rq, se, sleep, now);
825 /* Don't dequeue parent if it has other entities besides us */
826 if (cfs_rq->load.weight)
827 break;
828 }
829}
830
831/*
832 * sched_yield() support is very simple - we dequeue and enqueue
833 */
834static void yield_task_fair(struct rq *rq, struct task_struct *p)
835{
836 struct cfs_rq *cfs_rq = task_cfs_rq(p);
837 u64 now = __rq_clock(rq);
838
839 /*
840 * Dequeue and enqueue the task to update its
841 * position within the tree:
842 */
843 dequeue_entity(cfs_rq, &p->se, 0, now);
844 enqueue_entity(cfs_rq, &p->se, 0, now);
845}
846
847/*
848 * Preempt the current task with a newly woken task if needed:
849 */
850static void check_preempt_curr_fair(struct rq *rq, struct task_struct *p)
851{
852 struct task_struct *curr = rq->curr;
853 struct cfs_rq *cfs_rq = task_cfs_rq(curr);
854 unsigned long gran;
855
856 if (unlikely(rt_prio(p->prio))) {
857 update_curr(cfs_rq, rq_clock(rq));
858 resched_task(curr);
859 return;
860 }
861
862 gran = sysctl_sched_wakeup_granularity;
863 /*
864 * Batch tasks prefer throughput over latency:
865 */
866 if (unlikely(p->policy == SCHED_BATCH))
867 gran = sysctl_sched_batch_wakeup_granularity;
868
869 if (is_same_group(curr, p))
870 __check_preempt_curr_fair(cfs_rq, &p->se, &curr->se, gran);
871}
872
873static struct task_struct *pick_next_task_fair(struct rq *rq, u64 now)
874{
875 struct cfs_rq *cfs_rq = &rq->cfs;
876 struct sched_entity *se;
877
878 if (unlikely(!cfs_rq->nr_running))
879 return NULL;
880
881 do {
882 se = pick_next_entity(cfs_rq, now);
883 cfs_rq = group_cfs_rq(se);
884 } while (cfs_rq);
885
886 return task_of(se);
887}
888
889/*
890 * Account for a descheduled task:
891 */
892static void put_prev_task_fair(struct rq *rq, struct task_struct *prev, u64 now)
893{
894 struct sched_entity *se = &prev->se;
895 struct cfs_rq *cfs_rq;
896
897 for_each_sched_entity(se) {
898 cfs_rq = cfs_rq_of(se);
899 put_prev_entity(cfs_rq, se, now);
900 }
901}
902
903/**************************************************
904 * Fair scheduling class load-balancing methods:
905 */
906
907/*
908 * Load-balancing iterator. Note: while the runqueue stays locked
909 * during the whole iteration, the current task might be
910 * dequeued so the iterator has to be dequeue-safe. Here we
911 * achieve that by always pre-iterating before returning
912 * the current task:
913 */
914static inline struct task_struct *
915__load_balance_iterator(struct cfs_rq *cfs_rq, struct rb_node *curr)
916{
917 struct task_struct *p;
918
919 if (!curr)
920 return NULL;
921
922 p = rb_entry(curr, struct task_struct, se.run_node);
923 cfs_rq->rb_load_balance_curr = rb_next(curr);
924
925 return p;
926}
927
928static struct task_struct *load_balance_start_fair(void *arg)
929{
930 struct cfs_rq *cfs_rq = arg;
931
932 return __load_balance_iterator(cfs_rq, first_fair(cfs_rq));
933}
934
935static struct task_struct *load_balance_next_fair(void *arg)
936{
937 struct cfs_rq *cfs_rq = arg;
938
939 return __load_balance_iterator(cfs_rq, cfs_rq->rb_load_balance_curr);
940}
941
942static int cfs_rq_best_prio(struct cfs_rq *cfs_rq)
943{
944 struct sched_entity *curr;
945 struct task_struct *p;
946
947 if (!cfs_rq->nr_running)
948 return MAX_PRIO;
949
950 curr = __pick_next_entity(cfs_rq);
951 p = task_of(curr);
952
953 return p->prio;
954}
955
956static int
957load_balance_fair(struct rq *this_rq, int this_cpu, struct rq *busiest,
958 unsigned long max_nr_move, unsigned long max_load_move,
959 struct sched_domain *sd, enum cpu_idle_type idle,
960 int *all_pinned, unsigned long *total_load_moved)
961{
962 struct cfs_rq *busy_cfs_rq;
963 unsigned long load_moved, total_nr_moved = 0, nr_moved;
964 long rem_load_move = max_load_move;
965 struct rq_iterator cfs_rq_iterator;
966
967 cfs_rq_iterator.start = load_balance_start_fair;
968 cfs_rq_iterator.next = load_balance_next_fair;
969
970 for_each_leaf_cfs_rq(busiest, busy_cfs_rq) {
971 struct cfs_rq *this_cfs_rq;
972 long imbalance;
973 unsigned long maxload;
974 int this_best_prio, best_prio, best_prio_seen = 0;
975
976 this_cfs_rq = cpu_cfs_rq(busy_cfs_rq, this_cpu);
977
978 imbalance = busy_cfs_rq->load.weight -
979 this_cfs_rq->load.weight;
980 /* Don't pull if this_cfs_rq has more load than busy_cfs_rq */
981 if (imbalance <= 0)
982 continue;
983
984 /* Don't pull more than imbalance/2 */
985 imbalance /= 2;
986 maxload = min(rem_load_move, imbalance);
987
988 this_best_prio = cfs_rq_best_prio(this_cfs_rq);
989 best_prio = cfs_rq_best_prio(busy_cfs_rq);
990
991 /*
992 * Enable handling of the case where there is more than one task
993 * with the best priority. If the current running task is one
994 * of those with prio==best_prio we know it won't be moved
995 * and therefore it's safe to override the skip (based on load)
996 * of any task we find with that prio.
997 */
998 if (cfs_rq_curr(busy_cfs_rq) == &busiest->curr->se)
999 best_prio_seen = 1;
1000
1001 /* pass busy_cfs_rq argument into
1002 * load_balance_[start|next]_fair iterators
1003 */
1004 cfs_rq_iterator.arg = busy_cfs_rq;
1005 nr_moved = balance_tasks(this_rq, this_cpu, busiest,
1006 max_nr_move, maxload, sd, idle, all_pinned,
1007 &load_moved, this_best_prio, best_prio,
1008 best_prio_seen, &cfs_rq_iterator);
1009
1010 total_nr_moved += nr_moved;
1011 max_nr_move -= nr_moved;
1012 rem_load_move -= load_moved;
1013
1014 if (max_nr_move <= 0 || rem_load_move <= 0)
1015 break;
1016 }
1017
1018 *total_load_moved = max_load_move - rem_load_move;
1019
1020 return total_nr_moved;
1021}
1022
1023/*
1024 * scheduler tick hitting a task of our scheduling class:
1025 */
1026static void task_tick_fair(struct rq *rq, struct task_struct *curr)
1027{
1028 struct cfs_rq *cfs_rq;
1029 struct sched_entity *se = &curr->se;
1030
1031 for_each_sched_entity(se) {
1032 cfs_rq = cfs_rq_of(se);
1033 entity_tick(cfs_rq, se);
1034 }
1035}
1036
1037/*
1038 * Share the fairness runtime between parent and child, thus the
1039 * total amount of pressure for CPU stays equal - new tasks
1040 * get a chance to run but frequent forkers are not allowed to
1041 * monopolize the CPU. Note: the parent runqueue is locked,
1042 * the child is not running yet.
1043 */
1044static void task_new_fair(struct rq *rq, struct task_struct *p)
1045{
1046 struct cfs_rq *cfs_rq = task_cfs_rq(p);
1047 struct sched_entity *se = &p->se;
1048 u64 now = rq_clock(rq);
1049
1050 sched_info_queued(p);
1051
1052 update_stats_enqueue(cfs_rq, se, now);
1053 /*
1054 * Child runs first: we let it run before the parent
1055 * until it reschedules once. We set up the key so that
1056 * it will preempt the parent:
1057 */
1058 p->se.fair_key = current->se.fair_key -
1059 niced_granularity(&rq->curr->se, sysctl_sched_granularity) - 1;
1060 /*
1061 * The first wait is dominated by the child-runs-first logic,
1062 * so do not credit it with that waiting time yet:
1063 */
1064 if (sysctl_sched_features & SCHED_FEAT_SKIP_INITIAL)
1065 p->se.wait_start_fair = 0;
1066
1067 /*
1068 * The statistical average of wait_runtime is about
1069 * -granularity/2, so initialize the task with that:
1070 */
1071 if (sysctl_sched_features & SCHED_FEAT_START_DEBIT)
1072 p->se.wait_runtime = -(sysctl_sched_granularity / 2);
1073
1074 __enqueue_entity(cfs_rq, se);
1075 inc_nr_running(p, rq, now);
1076}
1077
1078#ifdef CONFIG_FAIR_GROUP_SCHED
1079/* Account for a task changing its policy or group.
1080 *
1081 * This routine is mostly called to set cfs_rq->curr field when a task
1082 * migrates between groups/classes.
1083 */
1084static void set_curr_task_fair(struct rq *rq)
1085{
1086 struct task_struct *curr = rq->curr;
1087 struct sched_entity *se = &curr->se;
1088 u64 now = rq_clock(rq);
1089 struct cfs_rq *cfs_rq;
1090
1091 for_each_sched_entity(se) {
1092 cfs_rq = cfs_rq_of(se);
1093 set_next_entity(cfs_rq, se, now);
1094 }
1095}
1096#else
1097static void set_curr_task_fair(struct rq *rq)
1098{
1099}
1100#endif
1101
1102/*
1103 * All the scheduling class methods:
1104 */
1105struct sched_class fair_sched_class __read_mostly = {
1106 .enqueue_task = enqueue_task_fair,
1107 .dequeue_task = dequeue_task_fair,
1108 .yield_task = yield_task_fair,
1109
1110 .check_preempt_curr = check_preempt_curr_fair,
1111
1112 .pick_next_task = pick_next_task_fair,
1113 .put_prev_task = put_prev_task_fair,
1114
1115 .load_balance = load_balance_fair,
1116
1117 .set_curr_task = set_curr_task_fair,
1118 .task_tick = task_tick_fair,
1119 .task_new = task_new_fair,
1120};
1121
1122#ifdef CONFIG_SCHED_DEBUG
1123void print_cfs_stats(struct seq_file *m, int cpu, u64 now)
1124{
1125 struct rq *rq = cpu_rq(cpu);
1126 struct cfs_rq *cfs_rq;
1127
1128 for_each_leaf_cfs_rq(rq, cfs_rq)
1129 print_cfs_rq(m, cpu, cfs_rq, now);
1130}
1131#endif
diff --git a/kernel/sched_idletask.c b/kernel/sched_idletask.c
new file mode 100644
index 000000000000..41841e741c4a
--- /dev/null
+++ b/kernel/sched_idletask.c
@@ -0,0 +1,71 @@
1/*
2 * idle-task scheduling class.
3 *
4 * (NOTE: these are not related to SCHED_IDLE tasks which are
5 * handled in sched_fair.c)
6 */
7
8/*
9 * Idle tasks are unconditionally rescheduled:
10 */
11static void check_preempt_curr_idle(struct rq *rq, struct task_struct *p)
12{
13 resched_task(rq->idle);
14}
15
16static struct task_struct *pick_next_task_idle(struct rq *rq, u64 now)
17{
18 schedstat_inc(rq, sched_goidle);
19
20 return rq->idle;
21}
22
23/*
24 * It is not legal to sleep in the idle task - print a warning
25 * message if some code attempts to do it:
26 */
27static void
28dequeue_task_idle(struct rq *rq, struct task_struct *p, int sleep, u64 now)
29{
30 spin_unlock_irq(&rq->lock);
31 printk(KERN_ERR "bad: scheduling from the idle thread!\n");
32 dump_stack();
33 spin_lock_irq(&rq->lock);
34}
35
36static void put_prev_task_idle(struct rq *rq, struct task_struct *prev, u64 now)
37{
38}
39
40static int
41load_balance_idle(struct rq *this_rq, int this_cpu, struct rq *busiest,
42 unsigned long max_nr_move, unsigned long max_load_move,
43 struct sched_domain *sd, enum cpu_idle_type idle,
44 int *all_pinned, unsigned long *total_load_moved)
45{
46 return 0;
47}
48
49static void task_tick_idle(struct rq *rq, struct task_struct *curr)
50{
51}
52
53/*
54 * Simple, special scheduling class for the per-CPU idle tasks:
55 */
56static struct sched_class idle_sched_class __read_mostly = {
57 /* no enqueue/yield_task for idle tasks */
58
59 /* dequeue is not valid, we print a debug message there: */
60 .dequeue_task = dequeue_task_idle,
61
62 .check_preempt_curr = check_preempt_curr_idle,
63
64 .pick_next_task = pick_next_task_idle,
65 .put_prev_task = put_prev_task_idle,
66
67 .load_balance = load_balance_idle,
68
69 .task_tick = task_tick_idle,
70 /* no .task_new for idle tasks */
71};
diff --git a/kernel/sched_rt.c b/kernel/sched_rt.c
new file mode 100644
index 000000000000..1192a2741b99
--- /dev/null
+++ b/kernel/sched_rt.c
@@ -0,0 +1,255 @@
1/*
2 * Real-Time Scheduling Class (mapped to the SCHED_FIFO and SCHED_RR
3 * policies)
4 */
5
6/*
7 * Update the current task's runtime statistics. Skip current tasks that
8 * are not in our scheduling class.
9 */
10static inline void update_curr_rt(struct rq *rq, u64 now)
11{
12 struct task_struct *curr = rq->curr;
13 u64 delta_exec;
14
15 if (!task_has_rt_policy(curr))
16 return;
17
18 delta_exec = now - curr->se.exec_start;
19 if (unlikely((s64)delta_exec < 0))
20 delta_exec = 0;
21 if (unlikely(delta_exec > curr->se.exec_max))
22 curr->se.exec_max = delta_exec;
23
24 curr->se.sum_exec_runtime += delta_exec;
25 curr->se.exec_start = now;
26}
27
28static void
29enqueue_task_rt(struct rq *rq, struct task_struct *p, int wakeup, u64 now)
30{
31 struct rt_prio_array *array = &rq->rt.active;
32
33 list_add_tail(&p->run_list, array->queue + p->prio);
34 __set_bit(p->prio, array->bitmap);
35}
36
37/*
38 * Adding/removing a task to/from a priority array:
39 */
40static void
41dequeue_task_rt(struct rq *rq, struct task_struct *p, int sleep, u64 now)
42{
43 struct rt_prio_array *array = &rq->rt.active;
44
45 update_curr_rt(rq, now);
46
47 list_del(&p->run_list);
48 if (list_empty(array->queue + p->prio))
49 __clear_bit(p->prio, array->bitmap);
50}
51
52/*
53 * Put task to the end of the run list without the overhead of dequeue
54 * followed by enqueue.
55 */
56static void requeue_task_rt(struct rq *rq, struct task_struct *p)
57{
58 struct rt_prio_array *array = &rq->rt.active;
59
60 list_move_tail(&p->run_list, array->queue + p->prio);
61}
62
63static void
64yield_task_rt(struct rq *rq, struct task_struct *p)
65{
66 requeue_task_rt(rq, p);
67}
68
69/*
70 * Preempt the current task with a newly woken task if needed:
71 */
72static void check_preempt_curr_rt(struct rq *rq, struct task_struct *p)
73{
74 if (p->prio < rq->curr->prio)
75 resched_task(rq->curr);
76}
77
78static struct task_struct *pick_next_task_rt(struct rq *rq, u64 now)
79{
80 struct rt_prio_array *array = &rq->rt.active;
81 struct task_struct *next;
82 struct list_head *queue;
83 int idx;
84
85 idx = sched_find_first_bit(array->bitmap);
86 if (idx >= MAX_RT_PRIO)
87 return NULL;
88
89 queue = array->queue + idx;
90 next = list_entry(queue->next, struct task_struct, run_list);
91
92 next->se.exec_start = now;
93
94 return next;
95}
96
97static void put_prev_task_rt(struct rq *rq, struct task_struct *p, u64 now)
98{
99 update_curr_rt(rq, now);
100 p->se.exec_start = 0;
101}
102
103/*
104 * Load-balancing iterator. Note: while the runqueue stays locked
105 * during the whole iteration, the current task might be
106 * dequeued so the iterator has to be dequeue-safe. Here we
107 * achieve that by always pre-iterating before returning
108 * the current task:
109 */
110static struct task_struct *load_balance_start_rt(void *arg)
111{
112 struct rq *rq = arg;
113 struct rt_prio_array *array = &rq->rt.active;
114 struct list_head *head, *curr;
115 struct task_struct *p;
116 int idx;
117
118 idx = sched_find_first_bit(array->bitmap);
119 if (idx >= MAX_RT_PRIO)
120 return NULL;
121
122 head = array->queue + idx;
123 curr = head->prev;
124
125 p = list_entry(curr, struct task_struct, run_list);
126
127 curr = curr->prev;
128
129 rq->rt.rt_load_balance_idx = idx;
130 rq->rt.rt_load_balance_head = head;
131 rq->rt.rt_load_balance_curr = curr;
132
133 return p;
134}
135
136static struct task_struct *load_balance_next_rt(void *arg)
137{
138 struct rq *rq = arg;
139 struct rt_prio_array *array = &rq->rt.active;
140 struct list_head *head, *curr;
141 struct task_struct *p;
142 int idx;
143
144 idx = rq->rt.rt_load_balance_idx;
145 head = rq->rt.rt_load_balance_head;
146 curr = rq->rt.rt_load_balance_curr;
147
148 /*
149 * If we arrived back to the head again then
150 * iterate to the next queue (if any):
151 */
152 if (unlikely(head == curr)) {
153 int next_idx = find_next_bit(array->bitmap, MAX_RT_PRIO, idx+1);
154
155 if (next_idx >= MAX_RT_PRIO)
156 return NULL;
157
158 idx = next_idx;
159 head = array->queue + idx;
160 curr = head->prev;
161
162 rq->rt.rt_load_balance_idx = idx;
163 rq->rt.rt_load_balance_head = head;
164 }
165
166 p = list_entry(curr, struct task_struct, run_list);
167
168 curr = curr->prev;
169
170 rq->rt.rt_load_balance_curr = curr;
171
172 return p;
173}
174
175static int
176load_balance_rt(struct rq *this_rq, int this_cpu, struct rq *busiest,
177 unsigned long max_nr_move, unsigned long max_load_move,
178 struct sched_domain *sd, enum cpu_idle_type idle,
179 int *all_pinned, unsigned long *load_moved)
180{
181 int this_best_prio, best_prio, best_prio_seen = 0;
182 int nr_moved;
183 struct rq_iterator rt_rq_iterator;
184
185 best_prio = sched_find_first_bit(busiest->rt.active.bitmap);
186 this_best_prio = sched_find_first_bit(this_rq->rt.active.bitmap);
187
188 /*
189 * Enable handling of the case where there is more than one task
190 * with the best priority. If the current running task is one
191 * of those with prio==best_prio we know it won't be moved
192 * and therefore it's safe to override the skip (based on load)
193 * of any task we find with that prio.
194 */
195 if (busiest->curr->prio == best_prio)
196 best_prio_seen = 1;
197
198 rt_rq_iterator.start = load_balance_start_rt;
199 rt_rq_iterator.next = load_balance_next_rt;
200 /* pass 'busiest' rq argument into
201 * load_balance_[start|next]_rt iterators
202 */
203 rt_rq_iterator.arg = busiest;
204
205 nr_moved = balance_tasks(this_rq, this_cpu, busiest, max_nr_move,
206 max_load_move, sd, idle, all_pinned, load_moved,
207 this_best_prio, best_prio, best_prio_seen,
208 &rt_rq_iterator);
209
210 return nr_moved;
211}
212
213static void task_tick_rt(struct rq *rq, struct task_struct *p)
214{
215 /*
216 * RR tasks need a special form of timeslice management.
217 * FIFO tasks have no timeslices.
218 */
219 if (p->policy != SCHED_RR)
220 return;
221
222 if (--p->time_slice)
223 return;
224
225 p->time_slice = static_prio_timeslice(p->static_prio);
226 set_tsk_need_resched(p);
227
228 /* put it at the end of the queue: */
229 requeue_task_rt(rq, p);
230}
231
232/*
233 * No parent/child timeslice management necessary for RT tasks,
234 * just activate them:
235 */
236static void task_new_rt(struct rq *rq, struct task_struct *p)
237{
238 activate_task(rq, p, 1);
239}
240
241static struct sched_class rt_sched_class __read_mostly = {
242 .enqueue_task = enqueue_task_rt,
243 .dequeue_task = dequeue_task_rt,
244 .yield_task = yield_task_rt,
245
246 .check_preempt_curr = check_preempt_curr_rt,
247
248 .pick_next_task = pick_next_task_rt,
249 .put_prev_task = put_prev_task_rt,
250
251 .load_balance = load_balance_rt,
252
253 .task_tick = task_tick_rt,
254 .task_new = task_new_rt,
255};
diff --git a/kernel/sched_stats.h b/kernel/sched_stats.h
new file mode 100644
index 000000000000..c63c38f6fa6e
--- /dev/null
+++ b/kernel/sched_stats.h
@@ -0,0 +1,235 @@
1
2#ifdef CONFIG_SCHEDSTATS
3/*
4 * bump this up when changing the output format or the meaning of an existing
5 * format, so that tools can adapt (or abort)
6 */
7#define SCHEDSTAT_VERSION 14
8
9static int show_schedstat(struct seq_file *seq, void *v)
10{
11 int cpu;
12
13 seq_printf(seq, "version %d\n", SCHEDSTAT_VERSION);
14 seq_printf(seq, "timestamp %lu\n", jiffies);
15 for_each_online_cpu(cpu) {
16 struct rq *rq = cpu_rq(cpu);
17#ifdef CONFIG_SMP
18 struct sched_domain *sd;
19 int dcnt = 0;
20#endif
21
22 /* runqueue-specific stats */
23 seq_printf(seq,
24 "cpu%d %lu %lu %lu %lu %lu %lu %lu %lu %lu %llu %llu %lu",
25 cpu, rq->yld_both_empty,
26 rq->yld_act_empty, rq->yld_exp_empty, rq->yld_cnt,
27 rq->sched_switch, rq->sched_cnt, rq->sched_goidle,
28 rq->ttwu_cnt, rq->ttwu_local,
29 rq->rq_sched_info.cpu_time,
30 rq->rq_sched_info.run_delay, rq->rq_sched_info.pcnt);
31
32 seq_printf(seq, "\n");
33
34#ifdef CONFIG_SMP
35 /* domain-specific stats */
36 preempt_disable();
37 for_each_domain(cpu, sd) {
38 enum cpu_idle_type itype;
39 char mask_str[NR_CPUS];
40
41 cpumask_scnprintf(mask_str, NR_CPUS, sd->span);
42 seq_printf(seq, "domain%d %s", dcnt++, mask_str);
43 for (itype = CPU_IDLE; itype < CPU_MAX_IDLE_TYPES;
44 itype++) {
45 seq_printf(seq, " %lu %lu %lu %lu %lu %lu %lu "
46 "%lu",
47 sd->lb_cnt[itype],
48 sd->lb_balanced[itype],
49 sd->lb_failed[itype],
50 sd->lb_imbalance[itype],
51 sd->lb_gained[itype],
52 sd->lb_hot_gained[itype],
53 sd->lb_nobusyq[itype],
54 sd->lb_nobusyg[itype]);
55 }
56 seq_printf(seq, " %lu %lu %lu %lu %lu %lu %lu %lu %lu"
57 " %lu %lu %lu\n",
58 sd->alb_cnt, sd->alb_failed, sd->alb_pushed,
59 sd->sbe_cnt, sd->sbe_balanced, sd->sbe_pushed,
60 sd->sbf_cnt, sd->sbf_balanced, sd->sbf_pushed,
61 sd->ttwu_wake_remote, sd->ttwu_move_affine,
62 sd->ttwu_move_balance);
63 }
64 preempt_enable();
65#endif
66 }
67 return 0;
68}
69
70static int schedstat_open(struct inode *inode, struct file *file)
71{
72 unsigned int size = PAGE_SIZE * (1 + num_online_cpus() / 32);
73 char *buf = kmalloc(size, GFP_KERNEL);
74 struct seq_file *m;
75 int res;
76
77 if (!buf)
78 return -ENOMEM;
79 res = single_open(file, show_schedstat, NULL);
80 if (!res) {
81 m = file->private_data;
82 m->buf = buf;
83 m->size = size;
84 } else
85 kfree(buf);
86 return res;
87}
88
89const struct file_operations proc_schedstat_operations = {
90 .open = schedstat_open,
91 .read = seq_read,
92 .llseek = seq_lseek,
93 .release = single_release,
94};
95
96/*
97 * Expects runqueue lock to be held for atomicity of update
98 */
99static inline void
100rq_sched_info_arrive(struct rq *rq, unsigned long long delta)
101{
102 if (rq) {
103 rq->rq_sched_info.run_delay += delta;
104 rq->rq_sched_info.pcnt++;
105 }
106}
107
108/*
109 * Expects runqueue lock to be held for atomicity of update
110 */
111static inline void
112rq_sched_info_depart(struct rq *rq, unsigned long long delta)
113{
114 if (rq)
115 rq->rq_sched_info.cpu_time += delta;
116}
117# define schedstat_inc(rq, field) do { (rq)->field++; } while (0)
118# define schedstat_add(rq, field, amt) do { (rq)->field += (amt); } while (0)
119#else /* !CONFIG_SCHEDSTATS */
120static inline void
121rq_sched_info_arrive(struct rq *rq, unsigned long long delta)
122{}
123static inline void
124rq_sched_info_depart(struct rq *rq, unsigned long long delta)
125{}
126# define schedstat_inc(rq, field) do { } while (0)
127# define schedstat_add(rq, field, amt) do { } while (0)
128#endif
129
130#if defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT)
131/*
132 * Called when a process is dequeued from the active array and given
133 * the cpu. We should note that with the exception of interactive
134 * tasks, the expired queue will become the active queue after the active
135 * queue is empty, without explicitly dequeuing and requeuing tasks in the
136 * expired queue. (Interactive tasks may be requeued directly to the
137 * active queue, thus delaying tasks in the expired queue from running;
138 * see scheduler_tick()).
139 *
140 * This function is only called from sched_info_arrive(), rather than
141 * dequeue_task(). Even though a task may be queued and dequeued multiple
142 * times as it is shuffled about, we're really interested in knowing how
143 * long it was from the *first* time it was queued to the time that it
144 * finally hit a cpu.
145 */
146static inline void sched_info_dequeued(struct task_struct *t)
147{
148 t->sched_info.last_queued = 0;
149}
150
151/*
152 * Called when a task finally hits the cpu. We can now calculate how
153 * long it was waiting to run. We also note when it began so that we
154 * can keep stats on how long its timeslice is.
155 */
156static void sched_info_arrive(struct task_struct *t)
157{
158 unsigned long long now = sched_clock(), delta = 0;
159
160 if (t->sched_info.last_queued)
161 delta = now - t->sched_info.last_queued;
162 sched_info_dequeued(t);
163 t->sched_info.run_delay += delta;
164 t->sched_info.last_arrival = now;
165 t->sched_info.pcnt++;
166
167 rq_sched_info_arrive(task_rq(t), delta);
168}
169
170/*
171 * Called when a process is queued into either the active or expired
172 * array. The time is noted and later used to determine how long we
173 * had to wait for us to reach the cpu. Since the expired queue will
174 * become the active queue after active queue is empty, without dequeuing
175 * and requeuing any tasks, we are interested in queuing to either. It
176 * is unusual but not impossible for tasks to be dequeued and immediately
177 * requeued in the same or another array: this can happen in sched_yield(),
178 * set_user_nice(), and even load_balance() as it moves tasks from runqueue
179 * to runqueue.
180 *
181 * This function is only called from enqueue_task(), but also only updates
182 * the timestamp if it is already not set. It's assumed that
183 * sched_info_dequeued() will clear that stamp when appropriate.
184 */
185static inline void sched_info_queued(struct task_struct *t)
186{
187 if (unlikely(sched_info_on()))
188 if (!t->sched_info.last_queued)
189 t->sched_info.last_queued = sched_clock();
190}
191
192/*
193 * Called when a process ceases being the active-running process, either
194 * voluntarily or involuntarily. Now we can calculate how long we ran.
195 */
196static inline void sched_info_depart(struct task_struct *t)
197{
198 unsigned long long delta = sched_clock() - t->sched_info.last_arrival;
199
200 t->sched_info.cpu_time += delta;
201 rq_sched_info_depart(task_rq(t), delta);
202}
203
204/*
205 * Called when tasks are switched involuntarily due, typically, to expiring
206 * their time slice. (This may also be called when switching to or from
207 * the idle task.) We are only called when prev != next.
208 */
209static inline void
210__sched_info_switch(struct task_struct *prev, struct task_struct *next)
211{
212 struct rq *rq = task_rq(prev);
213
214 /*
215 * prev now departs the cpu. It's not interesting to record
216 * stats about how efficient we were at scheduling the idle
217 * process, however.
218 */
219 if (prev != rq->idle)
220 sched_info_depart(prev);
221
222 if (next != rq->idle)
223 sched_info_arrive(next);
224}
225static inline void
226sched_info_switch(struct task_struct *prev, struct task_struct *next)
227{
228 if (unlikely(sched_info_on()))
229 __sched_info_switch(prev, next);
230}
231#else
232#define sched_info_queued(t) do { } while (0)
233#define sched_info_switch(t, next) do { } while (0)
234#endif /* CONFIG_SCHEDSTATS || CONFIG_TASK_DELAY_ACCT */
235
diff --git a/kernel/softirq.c b/kernel/softirq.c
index 0b9886a00e74..73217a9e2875 100644
--- a/kernel/softirq.c
+++ b/kernel/softirq.c
@@ -488,7 +488,6 @@ void __init softirq_init(void)
488 488
489static int ksoftirqd(void * __bind_cpu) 489static int ksoftirqd(void * __bind_cpu)
490{ 490{
491 set_user_nice(current, 19);
492 current->flags |= PF_NOFREEZE; 491 current->flags |= PF_NOFREEZE;
493 492
494 set_current_state(TASK_INTERRUPTIBLE); 493 set_current_state(TASK_INTERRUPTIBLE);
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 30ee462ee79f..51f5dac42a00 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -206,7 +206,87 @@ static ctl_table root_table[] = {
206 { .ctl_name = 0 } 206 { .ctl_name = 0 }
207}; 207};
208 208
209#ifdef CONFIG_SCHED_DEBUG
210static unsigned long min_sched_granularity_ns = 100000; /* 100 usecs */
211static unsigned long max_sched_granularity_ns = 1000000000; /* 1 second */
212static unsigned long min_wakeup_granularity_ns; /* 0 usecs */
213static unsigned long max_wakeup_granularity_ns = 1000000000; /* 1 second */
214#endif
215
209static ctl_table kern_table[] = { 216static ctl_table kern_table[] = {
217#ifdef CONFIG_SCHED_DEBUG
218 {
219 .ctl_name = CTL_UNNUMBERED,
220 .procname = "sched_granularity_ns",
221 .data = &sysctl_sched_granularity,
222 .maxlen = sizeof(unsigned int),
223 .mode = 0644,
224 .proc_handler = &proc_dointvec_minmax,
225 .strategy = &sysctl_intvec,
226 .extra1 = &min_sched_granularity_ns,
227 .extra2 = &max_sched_granularity_ns,
228 },
229 {
230 .ctl_name = CTL_UNNUMBERED,
231 .procname = "sched_wakeup_granularity_ns",
232 .data = &sysctl_sched_wakeup_granularity,
233 .maxlen = sizeof(unsigned int),
234 .mode = 0644,
235 .proc_handler = &proc_dointvec_minmax,
236 .strategy = &sysctl_intvec,
237 .extra1 = &min_wakeup_granularity_ns,
238 .extra2 = &max_wakeup_granularity_ns,
239 },
240 {
241 .ctl_name = CTL_UNNUMBERED,
242 .procname = "sched_batch_wakeup_granularity_ns",
243 .data = &sysctl_sched_batch_wakeup_granularity,
244 .maxlen = sizeof(unsigned int),
245 .mode = 0644,
246 .proc_handler = &proc_dointvec_minmax,
247 .strategy = &sysctl_intvec,
248 .extra1 = &min_wakeup_granularity_ns,
249 .extra2 = &max_wakeup_granularity_ns,
250 },
251 {
252 .ctl_name = CTL_UNNUMBERED,
253 .procname = "sched_stat_granularity_ns",
254 .data = &sysctl_sched_stat_granularity,
255 .maxlen = sizeof(unsigned int),
256 .mode = 0644,
257 .proc_handler = &proc_dointvec_minmax,
258 .strategy = &sysctl_intvec,
259 .extra1 = &min_wakeup_granularity_ns,
260 .extra2 = &max_wakeup_granularity_ns,
261 },
262 {
263 .ctl_name = CTL_UNNUMBERED,
264 .procname = "sched_runtime_limit_ns",
265 .data = &sysctl_sched_runtime_limit,
266 .maxlen = sizeof(unsigned int),
267 .mode = 0644,
268 .proc_handler = &proc_dointvec_minmax,
269 .strategy = &sysctl_intvec,
270 .extra1 = &min_sched_granularity_ns,
271 .extra2 = &max_sched_granularity_ns,
272 },
273 {
274 .ctl_name = CTL_UNNUMBERED,
275 .procname = "sched_child_runs_first",
276 .data = &sysctl_sched_child_runs_first,
277 .maxlen = sizeof(unsigned int),
278 .mode = 0644,
279 .proc_handler = &proc_dointvec,
280 },
281 {
282 .ctl_name = CTL_UNNUMBERED,
283 .procname = "sched_features",
284 .data = &sysctl_sched_features,
285 .maxlen = sizeof(unsigned int),
286 .mode = 0644,
287 .proc_handler = &proc_dointvec,
288 },
289#endif
210 { 290 {
211 .ctl_name = KERN_PANIC, 291 .ctl_name = KERN_PANIC,
212 .procname = "panic", 292 .procname = "panic",
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index da95e10cfd70..fab32a286371 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -105,6 +105,15 @@ config DETECT_SOFTLOCKUP
105 can be detected via the NMI-watchdog, on platforms that 105 can be detected via the NMI-watchdog, on platforms that
106 support it.) 106 support it.)
107 107
108config SCHED_DEBUG
109 bool "Collect scheduler debugging info"
110 depends on DEBUG_KERNEL && PROC_FS
111 default y
112 help
113 If you say Y here, the /proc/sched_debug file will be provided
114 that can help debug the scheduler. The runtime overhead of this
115 option is minimal.
116
108config SCHEDSTATS 117config SCHEDSTATS
109 bool "Collect scheduler statistics" 118 bool "Collect scheduler statistics"
110 depends on DEBUG_KERNEL && PROC_FS 119 depends on DEBUG_KERNEL && PROC_FS
diff --git a/mm/filemap.c b/mm/filemap.c
index d1d9814f99dd..c6ebd9f912ab 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -1245,26 +1245,6 @@ int file_send_actor(read_descriptor_t * desc, struct page *page, unsigned long o
1245 return written; 1245 return written;
1246} 1246}
1247 1247
1248ssize_t generic_file_sendfile(struct file *in_file, loff_t *ppos,
1249 size_t count, read_actor_t actor, void *target)
1250{
1251 read_descriptor_t desc;
1252
1253 if (!count)
1254 return 0;
1255
1256 desc.written = 0;
1257 desc.count = count;
1258 desc.arg.data = target;
1259 desc.error = 0;
1260
1261 do_generic_file_read(in_file, ppos, &desc, actor);
1262 if (desc.written)
1263 return desc.written;
1264 return desc.error;
1265}
1266EXPORT_SYMBOL(generic_file_sendfile);
1267
1268static ssize_t 1248static ssize_t
1269do_readahead(struct address_space *mapping, struct file *filp, 1249do_readahead(struct address_space *mapping, struct file *filp,
1270 unsigned long index, unsigned long nr) 1250 unsigned long index, unsigned long nr)
diff --git a/mm/filemap_xip.c b/mm/filemap_xip.c
index fa360e566d88..65ffc321f0c0 100644
--- a/mm/filemap_xip.c
+++ b/mm/filemap_xip.c
@@ -159,28 +159,6 @@ xip_file_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos)
159} 159}
160EXPORT_SYMBOL_GPL(xip_file_read); 160EXPORT_SYMBOL_GPL(xip_file_read);
161 161
162ssize_t
163xip_file_sendfile(struct file *in_file, loff_t *ppos,
164 size_t count, read_actor_t actor, void *target)
165{
166 read_descriptor_t desc;
167
168 if (!count)
169 return 0;
170
171 desc.written = 0;
172 desc.count = count;
173 desc.arg.data = target;
174 desc.error = 0;
175
176 do_xip_mapping_read(in_file->f_mapping, &in_file->f_ra, in_file,
177 ppos, &desc, actor);
178 if (desc.written)
179 return desc.written;
180 return desc.error;
181}
182EXPORT_SYMBOL_GPL(xip_file_sendfile);
183
184/* 162/*
185 * __xip_unmap is invoked from xip_unmap and 163 * __xip_unmap is invoked from xip_unmap and
186 * xip_write 164 * xip_write
diff --git a/mm/shmem.c b/mm/shmem.c
index b6aae2b33393..0493e4d0bcaa 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -1100,9 +1100,9 @@ static int shmem_getpage(struct inode *inode, unsigned long idx,
1100 * Normally, filepage is NULL on entry, and either found 1100 * Normally, filepage is NULL on entry, and either found
1101 * uptodate immediately, or allocated and zeroed, or read 1101 * uptodate immediately, or allocated and zeroed, or read
1102 * in under swappage, which is then assigned to filepage. 1102 * in under swappage, which is then assigned to filepage.
1103 * But shmem_prepare_write passes in a locked filepage, 1103 * But shmem_readpage and shmem_prepare_write pass in a locked
1104 * which may be found not uptodate by other callers too, 1104 * filepage, which may be found not uptodate by other callers
1105 * and may need to be copied from the swappage read in. 1105 * too, and may need to be copied from the swappage read in.
1106 */ 1106 */
1107repeat: 1107repeat:
1108 if (!filepage) 1108 if (!filepage)
@@ -1485,9 +1485,18 @@ static const struct inode_operations shmem_symlink_inode_operations;
1485static const struct inode_operations shmem_symlink_inline_operations; 1485static const struct inode_operations shmem_symlink_inline_operations;
1486 1486
1487/* 1487/*
1488 * Normally tmpfs makes no use of shmem_prepare_write, but it 1488 * Normally tmpfs avoids the use of shmem_readpage and shmem_prepare_write;
1489 * lets a tmpfs file be used read-write below the loop driver. 1489 * but providing them allows a tmpfs file to be used for splice, sendfile, and
1490 * below the loop driver, in the generic fashion that many filesystems support.
1490 */ 1491 */
1492static int shmem_readpage(struct file *file, struct page *page)
1493{
1494 struct inode *inode = page->mapping->host;
1495 int error = shmem_getpage(inode, page->index, &page, SGP_CACHE, NULL);
1496 unlock_page(page);
1497 return error;
1498}
1499
1491static int 1500static int
1492shmem_prepare_write(struct file *file, struct page *page, unsigned offset, unsigned to) 1501shmem_prepare_write(struct file *file, struct page *page, unsigned offset, unsigned to)
1493{ 1502{
@@ -1711,25 +1720,6 @@ static ssize_t shmem_file_read(struct file *filp, char __user *buf, size_t count
1711 return desc.error; 1720 return desc.error;
1712} 1721}
1713 1722
1714static ssize_t shmem_file_sendfile(struct file *in_file, loff_t *ppos,
1715 size_t count, read_actor_t actor, void *target)
1716{
1717 read_descriptor_t desc;
1718
1719 if (!count)
1720 return 0;
1721
1722 desc.written = 0;
1723 desc.count = count;
1724 desc.arg.data = target;
1725 desc.error = 0;
1726
1727 do_shmem_file_read(in_file, ppos, &desc, actor);
1728 if (desc.written)
1729 return desc.written;
1730 return desc.error;
1731}
1732
1733static int shmem_statfs(struct dentry *dentry, struct kstatfs *buf) 1723static int shmem_statfs(struct dentry *dentry, struct kstatfs *buf)
1734{ 1724{
1735 struct shmem_sb_info *sbinfo = SHMEM_SB(dentry->d_sb); 1725 struct shmem_sb_info *sbinfo = SHMEM_SB(dentry->d_sb);
@@ -2386,6 +2376,7 @@ static const struct address_space_operations shmem_aops = {
2386 .writepage = shmem_writepage, 2376 .writepage = shmem_writepage,
2387 .set_page_dirty = __set_page_dirty_no_writeback, 2377 .set_page_dirty = __set_page_dirty_no_writeback,
2388#ifdef CONFIG_TMPFS 2378#ifdef CONFIG_TMPFS
2379 .readpage = shmem_readpage,
2389 .prepare_write = shmem_prepare_write, 2380 .prepare_write = shmem_prepare_write,
2390 .commit_write = simple_commit_write, 2381 .commit_write = simple_commit_write,
2391#endif 2382#endif
@@ -2399,7 +2390,8 @@ static const struct file_operations shmem_file_operations = {
2399 .read = shmem_file_read, 2390 .read = shmem_file_read,
2400 .write = shmem_file_write, 2391 .write = shmem_file_write,
2401 .fsync = simple_sync_file, 2392 .fsync = simple_sync_file,
2402 .sendfile = shmem_file_sendfile, 2393 .splice_read = generic_file_splice_read,
2394 .splice_write = generic_file_splice_write,
2403#endif 2395#endif
2404}; 2396};
2405 2397
diff --git a/net/ieee80211/softmac/ieee80211softmac_module.c b/net/ieee80211/softmac/ieee80211softmac_module.c
index c308756c2f9d..6398e6e67493 100644
--- a/net/ieee80211/softmac/ieee80211softmac_module.c
+++ b/net/ieee80211/softmac/ieee80211softmac_module.c
@@ -456,18 +456,13 @@ void
456ieee80211softmac_add_network_locked(struct ieee80211softmac_device *mac, 456ieee80211softmac_add_network_locked(struct ieee80211softmac_device *mac,
457 struct ieee80211softmac_network *add_net) 457 struct ieee80211softmac_network *add_net)
458{ 458{
459 struct list_head *list_ptr; 459 struct ieee80211softmac_network *softmac_net;
460 struct ieee80211softmac_network *softmac_net = NULL;
461 460
462 list_for_each(list_ptr, &mac->network_list) { 461 list_for_each_entry(softmac_net, &mac->network_list, list) {
463 softmac_net = list_entry(list_ptr, struct ieee80211softmac_network, list);
464 if(!memcmp(softmac_net->bssid, add_net->bssid, ETH_ALEN)) 462 if(!memcmp(softmac_net->bssid, add_net->bssid, ETH_ALEN))
465 break; 463 return;
466 else
467 softmac_net = NULL;
468 } 464 }
469 if(softmac_net == NULL) 465 list_add(&(add_net->list), &mac->network_list);
470 list_add(&(add_net->list), &mac->network_list);
471} 466}
472 467
473/* Add a network to the list, with locking */ 468/* Add a network to the list, with locking */
@@ -506,16 +501,13 @@ struct ieee80211softmac_network *
506ieee80211softmac_get_network_by_bssid_locked(struct ieee80211softmac_device *mac, 501ieee80211softmac_get_network_by_bssid_locked(struct ieee80211softmac_device *mac,
507 u8 *bssid) 502 u8 *bssid)
508{ 503{
509 struct list_head *list_ptr; 504 struct ieee80211softmac_network *softmac_net;
510 struct ieee80211softmac_network *softmac_net = NULL; 505
511 list_for_each(list_ptr, &mac->network_list) { 506 list_for_each_entry(softmac_net, &mac->network_list, list) {
512 softmac_net = list_entry(list_ptr, struct ieee80211softmac_network, list);
513 if(!memcmp(softmac_net->bssid, bssid, ETH_ALEN)) 507 if(!memcmp(softmac_net->bssid, bssid, ETH_ALEN))
514 break; 508 return softmac_net;
515 else
516 softmac_net = NULL;
517 } 509 }
518 return softmac_net; 510 return NULL;
519} 511}
520 512
521/* Get a network from the list by BSSID with locking */ 513/* Get a network from the list by BSSID with locking */
@@ -537,11 +529,9 @@ struct ieee80211softmac_network *
537ieee80211softmac_get_network_by_essid_locked(struct ieee80211softmac_device *mac, 529ieee80211softmac_get_network_by_essid_locked(struct ieee80211softmac_device *mac,
538 struct ieee80211softmac_essid *essid) 530 struct ieee80211softmac_essid *essid)
539{ 531{
540 struct list_head *list_ptr; 532 struct ieee80211softmac_network *softmac_net;
541 struct ieee80211softmac_network *softmac_net = NULL;
542 533
543 list_for_each(list_ptr, &mac->network_list) { 534 list_for_each_entry(softmac_net, &mac->network_list, list) {
544 softmac_net = list_entry(list_ptr, struct ieee80211softmac_network, list);
545 if (softmac_net->essid.len == essid->len && 535 if (softmac_net->essid.len == essid->len &&
546 !memcmp(softmac_net->essid.data, essid->data, essid->len)) 536 !memcmp(softmac_net->essid.data, essid->data, essid->len))
547 return softmac_net; 537 return softmac_net;
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index f96ed76d8fa4..79b79f3de24c 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -2268,6 +2268,9 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event,
2268 break; 2268 break;
2269 case NETDEV_UP: 2269 case NETDEV_UP:
2270 case NETDEV_CHANGE: 2270 case NETDEV_CHANGE:
2271 if (dev->flags & IFF_SLAVE)
2272 break;
2273
2271 if (event == NETDEV_UP) { 2274 if (event == NETDEV_UP) {
2272 if (!netif_carrier_ok(dev)) { 2275 if (!netif_carrier_ok(dev)) {
2273 /* device is not ready yet. */ 2276 /* device is not ready yet. */
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c
index 099a983797da..c094583386fd 100644
--- a/net/sunrpc/auth_gss/svcauth_gss.c
+++ b/net/sunrpc/auth_gss/svcauth_gss.c
@@ -853,7 +853,7 @@ unwrap_priv_data(struct svc_rqst *rqstp, struct xdr_buf *buf, u32 seq, struct gs
853 u32 priv_len, maj_stat; 853 u32 priv_len, maj_stat;
854 int pad, saved_len, remaining_len, offset; 854 int pad, saved_len, remaining_len, offset;
855 855
856 rqstp->rq_sendfile_ok = 0; 856 rqstp->rq_splice_ok = 0;
857 857
858 priv_len = svc_getnl(&buf->head[0]); 858 priv_len = svc_getnl(&buf->head[0]);
859 if (rqstp->rq_deferred) { 859 if (rqstp->rq_deferred) {
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index e673ef993904..55ea6df069de 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -814,7 +814,7 @@ svc_process(struct svc_rqst *rqstp)
814 rqstp->rq_res.tail[0].iov_base = NULL; 814 rqstp->rq_res.tail[0].iov_base = NULL;
815 rqstp->rq_res.tail[0].iov_len = 0; 815 rqstp->rq_res.tail[0].iov_len = 0;
816 /* Will be turned off only in gss privacy case: */ 816 /* Will be turned off only in gss privacy case: */
817 rqstp->rq_sendfile_ok = 1; 817 rqstp->rq_splice_ok = 1;
818 /* tcp needs a space for the record length... */ 818 /* tcp needs a space for the record length... */
819 if (rqstp->rq_prot == IPPROTO_TCP) 819 if (rqstp->rq_prot == IPPROTO_TCP)
820 svc_putnl(resv, 0); 820 svc_putnl(resv, 0);
diff --git a/sound/ppc/beep.c b/sound/ppc/beep.c
index 5f38f670102c..a1aa89f2faf3 100644
--- a/sound/ppc/beep.c
+++ b/sound/ppc/beep.c
@@ -118,7 +118,7 @@ static int snd_pmac_beep_event(struct input_dev *dev, unsigned int type,
118 default: return -1; 118 default: return -1;
119 } 119 }
120 120
121 chip = dev->private; 121 chip = input_get_drvdata(dev);
122 if (! chip || (beep = chip->beep) == NULL) 122 if (! chip || (beep = chip->beep) == NULL)
123 return -1; 123 return -1;
124 124
@@ -239,8 +239,8 @@ int __init snd_pmac_attach_beep(struct snd_pmac *chip)
239 input_dev->evbit[0] = BIT(EV_SND); 239 input_dev->evbit[0] = BIT(EV_SND);
240 input_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE); 240 input_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
241 input_dev->event = snd_pmac_beep_event; 241 input_dev->event = snd_pmac_beep_event;
242 input_dev->private = chip; 242 input_dev->dev.parent = &chip->pdev->dev;
243 input_dev->cdev.dev = &chip->pdev->dev; 243 input_set_drvdata(input_dev, chip);
244 244
245 beep->dev = input_dev; 245 beep->dev = input_dev;
246 beep->buf = dmabuf; 246 beep->buf = dmabuf;
@@ -251,8 +251,8 @@ int __init snd_pmac_attach_beep(struct snd_pmac *chip)
251 err = snd_ctl_add(chip->card, beep_ctl); 251 err = snd_ctl_add(chip->card, beep_ctl);
252 if (err < 0) 252 if (err < 0)
253 goto fail1; 253 goto fail1;
254 254
255 chip->beep = beep; 255 chip->beep = beep;
256 256
257 err = input_register_device(beep->dev); 257 err = input_register_device(beep->dev);
258 if (err) 258 if (err)