From 50efa3f265307c55bcbe575da007b896ae3a44c3 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Tue, 22 Aug 2006 14:42:36 -0400 Subject: [PATCH] --- yaml --- r: 35225 b: refs/heads/master c: 69758820a42da207bdc775d6eccf1f9fb67cd62e h: refs/heads/master i: 35223: df3d7dd6e5f91910a5820b1fff5e1c315e06faf9 v: v3 --- [refs] | 2 +- trunk/CREDITS | 2 +- trunk/Documentation/connector/ucon.c | 206 - trunk/Documentation/cpusets.txt | 6 - .../feature-removal-schedule.txt | 7 - trunk/Documentation/filesystems/00-INDEX | 4 +- trunk/Documentation/filesystems/relay.txt | 479 -- trunk/Documentation/filesystems/relayfs.txt | 442 ++ trunk/Documentation/input/joystick.txt | 1 + trunk/Documentation/kernel-parameters.txt | 2 - .../Documentation/networking/LICENSE.qla3xxx | 46 - .../powerpc/booting-without-of.txt | 6 +- trunk/Documentation/scsi/ChangeLog.megaraid | 123 - trunk/Documentation/sysctl/fs.txt | 20 - trunk/Documentation/sysctl/kernel.txt | 20 + trunk/MAINTAINERS | 15 +- trunk/Makefile | 2 +- trunk/arch/arm/Makefile | 3 +- trunk/arch/arm/common/dmabounce.c | 8 +- trunk/arch/arm/common/sa1111.c | 6 +- trunk/arch/arm/configs/csb337_defconfig | 37 +- trunk/arch/arm/kernel/Makefile | 3 +- trunk/arch/arm/kernel/entry-armv.S | 21 +- trunk/arch/arm/kernel/head.S | 2 +- trunk/arch/arm/kernel/isa.c | 63 +- trunk/arch/arm/mach-footbridge/dc21285.c | 1 + trunk/arch/arm/mach-integrator/pci_v3.c | 2 - trunk/arch/arm/mach-pxa/corgi_ssp.c | 20 +- trunk/arch/arm/mach-pxa/ssp.c | 35 +- trunk/arch/arm/mach-s3c2410/Makefile | 36 +- trunk/arch/arm/mach-s3c2410/dma.c | 243 +- trunk/arch/arm/mach-sa1100/ssp.c | 46 +- trunk/arch/arm/mach-versatile/core.c | 2 +- trunk/arch/arm/mm/Kconfig | 13 +- trunk/arch/arm/mm/flush.c | 26 - trunk/arch/arm/vfp/vfp.h | 18 +- trunk/arch/arm/vfp/vfpdouble.c | 50 +- trunk/arch/arm/vfp/vfphw.S | 10 +- trunk/arch/arm/vfp/vfpmodule.c | 4 +- trunk/arch/arm/vfp/vfpsingle.c | 55 +- trunk/arch/i386/Kconfig | 4 +- trunk/arch/i386/kernel/acpi/boot.c | 2 +- trunk/arch/i386/kernel/acpi/wakeup.S | 5 +- .../i386/kernel/cpu/cpufreq/acpi-cpufreq.c | 9 +- trunk/arch/i386/kernel/head.S | 14 +- trunk/arch/i386/kernel/hpet.c | 2 +- trunk/arch/i386/kernel/irq.c | 5 + trunk/arch/i386/kernel/setup.c | 32 + trunk/arch/i386/kernel/traps.c | 27 +- trunk/arch/i386/pci/common.c | 5 - trunk/arch/i386/pci/init.c | 8 +- trunk/arch/i386/pci/mmconfig.c | 36 +- trunk/arch/i386/pci/pci.h | 3 +- trunk/arch/ia64/Kconfig | 4 +- trunk/arch/ia64/hp/sim/simscsi.c | 3 +- trunk/arch/ia64/kernel/acpi.c | 2 +- trunk/arch/ia64/kernel/topology.c | 6 +- trunk/arch/ia64/sn/kernel/xpc_channel.c | 4 +- trunk/arch/ia64/sn/kernel/xpc_main.c | 28 +- trunk/arch/ia64/sn/kernel/xpc_partition.c | 24 +- trunk/arch/powerpc/Kconfig | 20 +- trunk/arch/powerpc/boot/dts/mpc7448hpc2.dts | 190 - trunk/arch/powerpc/boot/dts/mpc8349emds.dts | 328 -- trunk/arch/powerpc/boot/dts/mpc8540ads.dts | 257 - trunk/arch/powerpc/boot/dts/mpc8541cds.dts | 244 - trunk/arch/powerpc/boot/dts/mpc8548cds.dts | 287 -- trunk/arch/powerpc/boot/dts/mpc8555cds.dts | 244 - ...4x_mds_defconfig => mpc834x_sys_defconfig} | 0 trunk/arch/powerpc/kernel/fpu.S | 5 - trunk/arch/powerpc/kernel/irq.c | 84 +- trunk/arch/powerpc/kernel/legacy_serial.c | 8 +- trunk/arch/powerpc/kernel/pci_64.c | 11 +- trunk/arch/powerpc/kernel/ppc_ksyms.c | 4 + trunk/arch/powerpc/kernel/prom_init.c | 10 +- trunk/arch/powerpc/kernel/prom_parse.c | 30 +- trunk/arch/powerpc/kernel/smp-tbsync.c | 5 +- trunk/arch/powerpc/kernel/time.c | 48 +- trunk/arch/powerpc/kernel/traps.c | 8 +- trunk/arch/powerpc/lib/memcpy_64.S | 11 +- trunk/arch/powerpc/mm/44x_mmu.c | 4 +- trunk/arch/powerpc/mm/hugetlbpage.c | 2 +- .../arch/powerpc/platforms/83xx/mpc834x_itx.c | 49 +- .../arch/powerpc/platforms/83xx/mpc834x_sys.c | 56 +- trunk/arch/powerpc/platforms/83xx/mpc83xx.h | 1 - trunk/arch/powerpc/platforms/83xx/pci.c | 9 - trunk/arch/powerpc/platforms/85xx/Kconfig | 1 + .../arch/powerpc/platforms/85xx/mpc85xx_ads.c | 162 +- .../arch/powerpc/platforms/85xx/mpc85xx_cds.c | 210 +- .../powerpc/platforms/86xx/mpc8641_hpcn.h | 32 + .../powerpc/platforms/86xx/mpc86xx_hpcn.c | 334 +- trunk/arch/powerpc/platforms/86xx/pci.c | 3 +- .../powerpc/platforms/embedded6xx/Kconfig | 1 - .../platforms/embedded6xx/mpc7448_hpc2.c | 75 +- .../powerpc/platforms/powermac/bootx_init.c | 15 +- .../powerpc/platforms/powermac/pfunc_base.c | 2 +- trunk/arch/powerpc/platforms/powermac/pic.c | 6 +- trunk/arch/powerpc/sysdev/Makefile | 4 +- trunk/arch/powerpc/sysdev/fsl_soc.c | 30 +- trunk/arch/powerpc/sysdev/ipic.c | 303 +- trunk/arch/powerpc/sysdev/ipic.h | 23 +- trunk/arch/powerpc/sysdev/mpic.c | 223 +- trunk/arch/powerpc/sysdev/tsi108_dev.c | 10 +- trunk/arch/powerpc/sysdev/tsi108_pci.c | 21 +- trunk/arch/ppc/kernel/smp-tbsync.c | 7 +- trunk/arch/ppc/platforms/85xx/mpc8560_ads.c | 89 - .../ppc/platforms/85xx/mpc85xx_ads_common.h | 19 - trunk/arch/ppc/platforms/mpc8272ads_setup.c | 154 +- trunk/arch/ppc/platforms/mpc866ads_setup.c | 192 +- trunk/arch/ppc/platforms/mpc885ads_setup.c | 175 +- trunk/arch/ppc/platforms/pq2ads_pd.h | 82 + trunk/arch/ppc/syslib/Makefile | 2 +- trunk/arch/ppc/syslib/ipic.c | 646 --- trunk/arch/ppc/syslib/ipic.h | 47 - trunk/arch/ppc/syslib/mpc85xx_devices.c | 89 +- trunk/arch/ppc/syslib/mpc8xx_devices.c | 8 - trunk/arch/ppc/syslib/mpc8xx_sys.c | 6 +- trunk/arch/ppc/syslib/pq2_devices.c | 5 - trunk/arch/ppc/syslib/pq2_sys.c | 3 +- trunk/arch/s390/lib/uaccess.S | 33 +- trunk/arch/s390/lib/uaccess64.S | 35 +- trunk/arch/sparc/kernel/setup.c | 4 +- trunk/arch/sparc/kernel/smp.c | 1 + trunk/arch/sparc/kernel/sun4d_smp.c | 2 +- trunk/arch/sparc/kernel/sun4m_smp.c | 2 + trunk/arch/sparc64/mm/generic.c | 2 - trunk/arch/x86_64/defconfig | 66 +- trunk/arch/x86_64/ia32/ia32_binfmt.c | 57 +- trunk/arch/x86_64/kernel/e820.c | 35 +- trunk/arch/x86_64/kernel/entry.S | 3 - trunk/arch/x86_64/kernel/head.S | 1 - trunk/arch/x86_64/kernel/init_task.c | 5 - trunk/arch/x86_64/kernel/setup.c | 6 +- trunk/arch/x86_64/kernel/setup64.c | 3 +- trunk/arch/x86_64/kernel/traps.c | 30 +- trunk/arch/x86_64/pci/mmconfig.c | 34 +- trunk/arch/xtensa/kernel/ptrace.c | 2 +- trunk/block/cfq-iosched.c | 2 +- trunk/block/elevator.c | 3 +- trunk/block/ll_rw_blk.c | 2 - trunk/drivers/acpi/ac.c | 2 - trunk/drivers/acpi/acpi_memhotplug.c | 8 +- trunk/drivers/acpi/battery.c | 3 - trunk/drivers/acpi/bus.c | 11 +- trunk/drivers/acpi/hotkey.c | 281 +- trunk/drivers/acpi/i2c_ec.c | 2 +- trunk/drivers/acpi/osl.c | 10 - trunk/drivers/acpi/sbs.c | 3 - trunk/drivers/acpi/scan.c | 12 +- trunk/drivers/acpi/utils.c | 2 +- trunk/drivers/base/node.c | 2 +- trunk/drivers/block/floppy.c | 12 +- trunk/drivers/cdrom/gscd.c | 2 +- trunk/drivers/char/drm/radeon_state.c | 9 +- trunk/drivers/char/ipmi/ipmi_msghandler.c | 1 - trunk/drivers/char/moxa.c | 8 +- trunk/drivers/char/synclink_gt.c | 14 +- trunk/drivers/char/tty_io.c | 808 +--- trunk/drivers/char/tty_ioctl.c | 59 +- trunk/drivers/char/vt_ioctl.c | 2 - trunk/drivers/char/watchdog/sbc8360.c | 4 +- trunk/drivers/hwmon/abituguru.c | 99 +- trunk/drivers/i2c/chips/tps65010.c | 12 +- trunk/drivers/ide/pci/sgiioc4.c | 60 +- trunk/drivers/ide/pci/via82cxxx.c | 3 +- trunk/drivers/ieee1394/ohci1394.c | 4 +- trunk/drivers/infiniband/core/cache.c | 3 +- trunk/drivers/infiniband/core/sa_query.c | 3 +- .../infiniband/hw/mthca/mthca_allocator.c | 15 +- .../drivers/infiniband/hw/mthca/mthca_main.c | 6 +- .../infiniband/hw/mthca/mthca_provider.c | 11 +- .../infiniband/hw/mthca/mthca_provider.h | 4 +- trunk/drivers/infiniband/hw/mthca/mthca_qp.c | 54 +- .../drivers/infiniband/ulp/iser/iscsi_iser.c | 22 +- trunk/drivers/input/keyboard/atkbd.c | 2 +- trunk/drivers/input/misc/wistron_btns.c | 16 +- trunk/drivers/input/mouse/psmouse-base.c | 7 + trunk/drivers/isdn/i4l/Kconfig | 1 - trunk/drivers/macintosh/via-pmu-backlight.c | 99 +- trunk/drivers/macintosh/via-pmu.c | 12 - trunk/drivers/md/dm-raid1.c | 4 +- trunk/drivers/md/md.c | 13 - trunk/drivers/md/raid1.c | 64 +- trunk/drivers/message/fusion/mptbase.h | 1 + trunk/drivers/message/fusion/mptfc.c | 92 +- trunk/drivers/mtd/nand/ams-delta.c | 10 +- trunk/drivers/mtd/nand/nand_base.c | 6 +- trunk/drivers/net/3c501.c | 1 + trunk/drivers/net/3c515.c | 3 +- trunk/drivers/net/3c59x.c | 2 +- trunk/drivers/net/8139cp.c | 2 +- trunk/drivers/net/8139too.c | 2 +- trunk/drivers/net/82596.c | 9 +- trunk/drivers/net/8390.c | 10 +- trunk/drivers/net/Kconfig | 74 - trunk/drivers/net/Makefile | 14 +- trunk/drivers/net/ac3200.c | 3 +- trunk/drivers/net/acenic.c | 2 +- trunk/drivers/net/amd8111e.c | 2 +- trunk/drivers/net/appletalk/cops.c | 2 +- trunk/drivers/net/arcnet/com20020-pci.c | 2 +- trunk/drivers/net/at1700.c | 2 +- trunk/drivers/net/b44.c | 2 +- trunk/drivers/net/bnx2.c | 2 +- trunk/drivers/net/cassini.c | 2 +- trunk/drivers/net/chelsio/cxgb2.c | 2 +- trunk/drivers/net/cs89x0.c | 3 +- trunk/drivers/net/defxx.c | 2 +- trunk/drivers/net/dl2k.c | 2 +- trunk/drivers/net/dm9000.c | 14 - trunk/drivers/net/e100.c | 36 +- trunk/drivers/net/e1000/e1000.h | 6 +- trunk/drivers/net/e1000/e1000_ethtool.c | 257 +- trunk/drivers/net/e1000/e1000_hw.c | 1168 +++-- trunk/drivers/net/e1000/e1000_hw.h | 58 +- trunk/drivers/net/e1000/e1000_main.c | 156 +- trunk/drivers/net/e1000/e1000_param.c | 161 +- trunk/drivers/net/e2100.c | 4 +- trunk/drivers/net/eepro.c | 3 +- trunk/drivers/net/eepro100.c | 2 +- trunk/drivers/net/eexpress.c | 2 +- trunk/drivers/net/epic100.c | 2 +- trunk/drivers/net/es3210.c | 3 +- trunk/drivers/net/eth16i.c | 2 +- trunk/drivers/net/fealnx.c | 4 +- trunk/drivers/net/forcedeth.c | 559 +-- trunk/drivers/net/fs_enet/Makefile | 6 +- trunk/drivers/net/fs_enet/fec.h | 42 - trunk/drivers/net/fs_enet/fs_enet-main.c | 207 +- trunk/drivers/net/fs_enet/fs_enet-mii.c | 505 ++ trunk/drivers/net/fs_enet/fs_enet.h | 40 +- trunk/drivers/net/fs_enet/mac-fcc.c | 32 +- trunk/drivers/net/fs_enet/mac-fec.c | 142 +- trunk/drivers/net/fs_enet/mac-scc.c | 4 +- trunk/drivers/net/fs_enet/mii-bitbang.c | 448 +- trunk/drivers/net/fs_enet/mii-fec.c | 243 - trunk/drivers/net/fs_enet/mii-fixed.c | 91 + trunk/drivers/net/hp100.c | 1 + trunk/drivers/net/irda/mcs7780.c | 1 + trunk/drivers/net/irda/w83977af_ir.c | 1 + trunk/drivers/net/ixgb/ixgb.h | 5 +- trunk/drivers/net/ixgb/ixgb_ethtool.c | 6 +- trunk/drivers/net/ixgb/ixgb_hw.c | 11 - trunk/drivers/net/ixgb/ixgb_ids.h | 1 - trunk/drivers/net/ixgb/ixgb_main.c | 152 +- trunk/drivers/net/lance.c | 2 +- trunk/drivers/net/lne390.c | 2 +- trunk/drivers/net/myri10ge/myri10ge.c | 193 +- trunk/drivers/net/myri10ge/myri10ge_mcp.h | 47 +- trunk/drivers/net/natsemi.c | 2 +- trunk/drivers/net/ne2k-pci.c | 2 +- trunk/drivers/net/netx-eth.c | 1 + trunk/drivers/net/ni52.c | 2 +- trunk/drivers/net/ni65.c | 2 +- trunk/drivers/net/ns83820.c | 2 +- trunk/drivers/net/pci-skeleton.c | 2 +- trunk/drivers/net/pcmcia/axnet_cs.c | 3 +- trunk/drivers/net/pcmcia/pcnet_cs.c | 15 +- trunk/drivers/net/pcmcia/xirc2ps_cs.c | 18 +- trunk/drivers/net/pcnet32.c | 27 +- trunk/drivers/net/phy/Kconfig | 17 - trunk/drivers/net/phy/Makefile | 1 - trunk/drivers/net/phy/fixed.c | 358 -- trunk/drivers/net/phy/mdio_bus.c | 1 - trunk/drivers/net/phy/phy_device.c | 51 +- trunk/drivers/net/phy/smsc.c | 1 + trunk/drivers/net/phy/vitesse.c | 1 + trunk/drivers/net/qla3xxx.c | 3537 -------------- trunk/drivers/net/qla3xxx.h | 1194 ----- trunk/drivers/net/r8169.c | 2 +- trunk/drivers/net/rrunner.c | 2 +- trunk/drivers/net/s2io.c | 3 +- trunk/drivers/net/saa9730.c | 2 +- trunk/drivers/net/seeq8005.c | 2 +- trunk/drivers/net/sis190.c | 2 +- trunk/drivers/net/sis900.c | 3 +- trunk/drivers/net/sk98lin/skge.c | 2 +- trunk/drivers/net/skfp/skfddi.c | 2 +- trunk/drivers/net/skge.c | 92 +- trunk/drivers/net/sky2.c | 186 +- trunk/drivers/net/sky2.h | 3 +- trunk/drivers/net/slhc.c | 28 +- trunk/drivers/net/smc911x.c | 3 +- trunk/drivers/net/smc91x.c | 8 +- trunk/drivers/net/smc91x.h | 29 +- trunk/drivers/net/spider_net.c | 12 +- trunk/drivers/net/spider_net.h | 3 - trunk/drivers/net/spider_net_ethtool.c | 13 - trunk/drivers/net/starfire.c | 2 +- trunk/drivers/net/sundance.c | 17 +- trunk/drivers/net/sungem.c | 2 +- trunk/drivers/net/sunlance.c | 27 +- trunk/drivers/net/tc35815.c | 2 +- trunk/drivers/net/tg3.c | 2 +- trunk/drivers/net/tokenring/3c359.c | 2 +- trunk/drivers/net/tokenring/ibmtr.c | 4 +- trunk/drivers/net/tokenring/lanstreamer.c | 2 +- trunk/drivers/net/tokenring/smctr.c | 5 +- trunk/drivers/net/tulip/de2104x.c | 2 +- trunk/drivers/net/tulip/de4x5.c | 2 +- trunk/drivers/net/tulip/dmfe.c | 2 +- trunk/drivers/net/tulip/tulip_core.c | 2 +- trunk/drivers/net/tulip/uli526x.c | 12 +- trunk/drivers/net/tulip/winbond-840.c | 4 +- trunk/drivers/net/tulip/xircom_cb.c | 3 +- trunk/drivers/net/tulip/xircom_tulip_cb.c | 2 +- trunk/drivers/net/typhoon.c | 2 +- trunk/drivers/net/ucc_geth.c | 4278 ----------------- trunk/drivers/net/ucc_geth.h | 1339 ------ trunk/drivers/net/ucc_geth_phy.c | 801 --- trunk/drivers/net/ucc_geth_phy.h | 217 - trunk/drivers/net/via-rhine.c | 92 +- trunk/drivers/net/via-velocity.c | 2 +- trunk/drivers/net/via-velocity.h | 19 + trunk/drivers/net/wan/c101.c | 9 +- trunk/drivers/net/wan/cycx_main.c | 1 + trunk/drivers/net/wan/dlci.c | 1 + trunk/drivers/net/wan/dscc4.c | 2 +- trunk/drivers/net/wan/farsync.c | 2 +- trunk/drivers/net/wan/lmc/lmc_main.c | 2 +- trunk/drivers/net/wan/pc300_drv.c | 2 +- trunk/drivers/net/wan/pci200syn.c | 2 +- trunk/drivers/net/wan/sdla.c | 1 + trunk/drivers/net/wan/wanxl.c | 2 +- trunk/drivers/net/wd.c | 4 +- trunk/drivers/net/wireless/atmel_pci.c | 2 +- trunk/drivers/net/wireless/hostap/hostap_hw.c | 3 - trunk/drivers/net/wireless/ipw2100.c | 2 +- trunk/drivers/net/wireless/ipw2200.c | 2 +- trunk/drivers/net/wireless/orinoco_nortel.c | 2 +- trunk/drivers/net/wireless/orinoco_pci.c | 2 +- trunk/drivers/net/wireless/orinoco_plx.c | 2 +- trunk/drivers/net/wireless/orinoco_tmd.c | 2 +- .../net/wireless/prism54/islpci_hotplug.c | 2 +- trunk/drivers/net/wireless/spectrum_cs.c | 2 +- trunk/drivers/net/wireless/strip.c | 6 +- trunk/drivers/net/yellowfin.c | 2 +- trunk/drivers/pci/hotplug/Kconfig | 2 +- trunk/drivers/pci/hotplug/cpci_hotplug_pci.c | 54 +- trunk/drivers/pci/pci-driver.c | 3 +- trunk/drivers/pci/quirks.c | 60 +- trunk/drivers/rtc/rtc-s3c.c | 124 +- trunk/drivers/s390/block/dasd.c | 192 +- trunk/drivers/s390/block/dasd_devmap.c | 8 +- trunk/drivers/s390/block/dasd_eckd.c | 14 +- trunk/drivers/s390/block/dasd_genhd.c | 10 +- trunk/drivers/s390/cio/ccwgroup.c | 14 +- trunk/drivers/s390/cio/chsc.c | 10 +- trunk/drivers/s390/cio/device.c | 19 +- trunk/drivers/s390/cio/device_fsm.c | 20 +- trunk/drivers/s390/cio/device_pgid.c | 27 +- trunk/drivers/s390/net/qeth_main.c | 8 +- trunk/drivers/s390/scsi/zfcp_aux.c | 120 +- trunk/drivers/s390/scsi/zfcp_ccw.c | 5 - trunk/drivers/s390/scsi/zfcp_def.h | 15 +- trunk/drivers/s390/scsi/zfcp_erp.c | 212 +- trunk/drivers/s390/scsi/zfcp_ext.h | 9 +- trunk/drivers/s390/scsi/zfcp_fsf.c | 122 +- trunk/drivers/s390/scsi/zfcp_qdio.c | 79 +- trunk/drivers/s390/scsi/zfcp_scsi.c | 73 +- trunk/drivers/scsi/ata_piix.c | 84 +- trunk/drivers/scsi/esp.c | 3 +- trunk/drivers/scsi/hptiop.c | 568 ++- trunk/drivers/scsi/ide-scsi.c | 2 +- trunk/drivers/scsi/iscsi_tcp.c | 209 +- trunk/drivers/scsi/iscsi_tcp.h | 2 + trunk/drivers/scsi/libata-core.c | 2 +- trunk/drivers/scsi/libiscsi.c | 214 +- trunk/drivers/scsi/lpfc/lpfc_attr.c | 101 +- trunk/drivers/scsi/lpfc/lpfc_crtn.h | 1 - trunk/drivers/scsi/lpfc/lpfc_ct.c | 13 +- trunk/drivers/scsi/lpfc/lpfc_els.c | 21 +- trunk/drivers/scsi/lpfc/lpfc_hbadisc.c | 15 +- trunk/drivers/scsi/lpfc/lpfc_init.c | 13 +- trunk/drivers/scsi/lpfc/lpfc_mbox.c | 16 - trunk/drivers/scsi/lpfc/lpfc_nportdisc.c | 24 +- trunk/drivers/scsi/lpfc/lpfc_scsi.c | 21 +- trunk/drivers/scsi/lpfc/lpfc_sli.c | 57 +- trunk/drivers/scsi/lpfc/lpfc_sli.h | 20 - trunk/drivers/scsi/lpfc/lpfc_version.h | 2 +- trunk/drivers/scsi/megaraid/mega_common.h | 6 - trunk/drivers/scsi/megaraid/megaraid_ioctl.h | 4 - trunk/drivers/scsi/megaraid/megaraid_mbox.c | 42 +- trunk/drivers/scsi/megaraid/megaraid_mbox.h | 4 +- trunk/drivers/scsi/megaraid/megaraid_mm.c | 2 +- trunk/drivers/scsi/megaraid/megaraid_mm.h | 4 +- trunk/drivers/scsi/pdc_adma.c | 3 +- trunk/drivers/scsi/qla2xxx/qla_def.h | 1 - trunk/drivers/scsi/qla2xxx/qla_init.c | 11 - trunk/drivers/scsi/qla2xxx/qla_iocb.c | 1 - trunk/drivers/scsi/qla2xxx/qla_isr.c | 5 - trunk/drivers/scsi/qla2xxx/qla_os.c | 15 +- trunk/drivers/scsi/qla2xxx/qla_version.h | 4 +- trunk/drivers/scsi/sata_via.c | 117 +- trunk/drivers/scsi/scsi_error.c | 18 +- trunk/drivers/scsi/scsi_transport_iscsi.c | 15 +- trunk/drivers/scsi/sg.c | 8 +- trunk/drivers/scsi/sym53c8xx_2/sym_glue.c | 2 +- trunk/drivers/serial/8250_pci.c | 31 +- trunk/drivers/serial/serial_core.c | 3 - trunk/drivers/serial/sunsab.c | 9 - trunk/drivers/serial/sunzilog.c | 3 - trunk/drivers/usb/gadget/ether.c | 45 +- trunk/drivers/usb/host/uhci-q.c | 4 +- trunk/drivers/usb/input/hid-core.c | 149 +- trunk/drivers/usb/misc/cypress_cy7c63.c | 2 +- trunk/drivers/usb/net/pegasus.h | 3 - trunk/drivers/usb/net/rtl8150.c | 1 - trunk/drivers/usb/serial/pl2303.c | 1 + trunk/drivers/usb/serial/pl2303.h | 4 + trunk/drivers/usb/storage/unusual_devs.h | 26 +- trunk/drivers/video/aty/aty128fb.c | 18 +- trunk/drivers/video/aty/atyfb_base.c | 18 +- trunk/drivers/video/aty/radeon_backlight.c | 4 +- trunk/drivers/video/imacfb.c | 4 +- trunk/drivers/video/matrox/g450_pll.c | 8 - trunk/drivers/video/nvidia/nv_backlight.c | 18 +- trunk/drivers/video/riva/fbdev.c | 18 +- trunk/fs/block_dev.c | 114 +- trunk/fs/cifs/CHANGES | 10 - trunk/fs/cifs/README | 2 +- trunk/fs/cifs/cifsencrypt.c | 3 +- trunk/fs/cifs/cifsfs.c | 6 +- trunk/fs/cifs/cifsfs.h | 2 +- trunk/fs/cifs/cifsglob.h | 18 +- trunk/fs/cifs/cifsproto.h | 4 - trunk/fs/cifs/cifssmb.c | 28 +- trunk/fs/cifs/connect.c | 32 +- trunk/fs/cifs/dir.c | 4 - trunk/fs/cifs/file.c | 97 +- trunk/fs/cifs/netmisc.c | 1 - trunk/fs/cifs/readdir.c | 2 +- trunk/fs/cifs/sess.c | 2 +- trunk/fs/cifs/smberr.h | 1 - trunk/fs/cifs/transport.c | 618 +-- trunk/fs/cifs/xattr.c | 6 +- trunk/fs/eventpoll.c | 4 +- trunk/fs/exec.c | 10 +- trunk/fs/ext2/super.c | 2 +- trunk/fs/ext3/balloc.c | 6 +- trunk/fs/ioprio.c | 30 +- trunk/fs/jbd/commit.c | 6 +- trunk/fs/jbd/journal.c | 92 +- trunk/fs/jbd/transaction.c | 11 +- trunk/fs/lockd/svcsubs.c | 15 +- trunk/fs/minix/inode.c | 13 +- trunk/fs/namei.c | 11 +- trunk/fs/nfs/file.c | 8 +- trunk/fs/nfs/idmap.c | 4 +- trunk/fs/nfs/nfs4proc.c | 29 +- trunk/fs/nfs/nfs4xdr.c | 21 +- trunk/fs/nfs/read.c | 23 +- trunk/fs/partitions/sun.c | 2 +- trunk/fs/proc/proc_misc.c | 2 +- trunk/fs/reiserfs/xattr.c | 2 +- trunk/fs/udf/super.c | 2 +- trunk/fs/udf/truncate.c | 64 +- trunk/fs/ufs/inode.c | 35 +- trunk/fs/ufs/truncate.c | 77 +- trunk/fs/xfs/xfs_bmap.c | 2 +- trunk/include/asm-arm/arch-pxa/ssp.h | 4 +- trunk/include/asm-arm/arch-s3c2410/dma.h | 151 +- trunk/include/asm-arm/arch-s3c2410/regs-rtc.h | 2 +- trunk/include/asm-arm/cacheflush.h | 18 +- trunk/include/asm-arm/hardware/ssp.h | 4 +- trunk/include/asm-arm/io.h | 7 - trunk/include/asm-arm/procinfo.h | 1 - trunk/include/asm-arm/spinlock.h | 16 +- trunk/include/asm-i386/alternative.h | 20 + .../asm-i386/mach-default/mach_mpspec.h | 4 - trunk/include/asm-i386/mmzone.h | 2 +- trunk/include/asm-i386/rwlock.h | 28 +- trunk/include/asm-i386/spinlock.h | 17 +- trunk/include/asm-i386/unistd.h | 4 +- trunk/include/asm-i386/unwind.h | 1 - trunk/include/asm-ia64/sn/sn_sal.h | 6 + trunk/include/asm-ia64/sn/xp.h | 22 +- trunk/include/asm-ia64/sn/xpc.h | 4 +- trunk/include/asm-powerpc/io.h | 7 +- trunk/include/asm-powerpc/ipic.h | 12 +- trunk/include/asm-powerpc/mpc86xx.h | 3 + trunk/include/asm-powerpc/mpic.h | 125 - trunk/include/asm-powerpc/pgalloc.h | 2 +- trunk/include/asm-powerpc/prom.h | 4 +- trunk/include/asm-powerpc/system.h | 9 - trunk/include/asm-powerpc/time.h | 4 + trunk/include/asm-powerpc/tsi108.h | 14 +- trunk/include/asm-powerpc/tsi108_irq.h | 124 - trunk/include/asm-ppc/cpm2.h | 95 - trunk/include/asm-ppc/mpc8260.h | 1 - trunk/include/asm-ppc/mpc8xx.h | 1 - trunk/include/asm-sparc64/pgtable.h | 2 +- trunk/include/asm-x86_64/alternative.h | 21 +- trunk/include/asm-x86_64/processor.h | 6 - trunk/include/asm-x86_64/spinlock.h | 11 +- trunk/include/asm-x86_64/unistd.h | 11 +- trunk/include/asm-x86_64/unwind.h | 1 - trunk/include/linux/compat_ioctl.h | 1 - trunk/include/linux/delayacct.h | 10 +- trunk/include/linux/fs.h | 3 +- trunk/include/linux/fs_enet_pd.h | 50 +- trunk/include/linux/ioprio.h | 23 +- trunk/include/linux/jbd.h | 3 - trunk/include/linux/mmzone.h | 1 - trunk/include/linux/netfilter_bridge.h | 14 +- trunk/include/linux/nfs_xdr.h | 2 +- trunk/include/linux/node.h | 10 +- trunk/include/linux/pci_ids.h | 4 - trunk/include/linux/phy.h | 1 - trunk/include/linux/sched.h | 1 + trunk/include/linux/sunrpc/rpc_pipe_fs.h | 4 +- trunk/include/linux/sunrpc/xprt.h | 2 +- trunk/include/linux/tty.h | 1 - trunk/include/linux/vt.h | 1 - trunk/include/net/sctp/sctp.h | 13 + trunk/include/net/sctp/sm.h | 3 +- trunk/include/scsi/libiscsi.h | 19 +- trunk/include/scsi/scsi_transport_iscsi.h | 4 + trunk/kernel/cpuset.c | 35 +- trunk/kernel/delayacct.c | 16 + trunk/kernel/exit.c | 3 +- trunk/kernel/fork.c | 6 +- trunk/kernel/futex.c | 2 +- trunk/kernel/irq/handle.c | 5 - trunk/kernel/sched.c | 4 +- trunk/kernel/stop_machine.c | 1 + trunk/lib/ts_bm.c | 11 +- trunk/mm/mempolicy.c | 10 +- trunk/mm/mempool.c | 9 +- trunk/mm/swapfile.c | 3 +- trunk/mm/vmstat.c | 151 +- trunk/net/bridge/br_forward.c | 10 +- trunk/net/dccp/ccids/ccid3.c | 153 +- trunk/net/dccp/ccids/ccid3.h | 9 +- trunk/net/dccp/ccids/lib/loss_interval.c | 36 +- trunk/net/dccp/ccids/lib/loss_interval.h | 9 +- trunk/net/dccp/ccids/lib/packet_history.c | 168 +- trunk/net/dccp/ccids/lib/packet_history.h | 17 +- trunk/net/dccp/ccids/lib/tfrc.h | 2 +- trunk/net/dccp/ccids/lib/tfrc_equation.c | 2 +- trunk/net/dccp/dccp.h | 10 +- trunk/net/dccp/options.c | 2 +- trunk/net/ipv4/ip_output.c | 1 - trunk/net/ipv4/netfilter/arp_tables.c | 3 +- trunk/net/ipv4/tcp_cong.c | 2 +- trunk/net/ipv4/tcp_input.c | 9 +- trunk/net/ipv4/tcp_output.c | 1 - trunk/net/ipv6/addrconf.c | 4 +- trunk/net/ipv6/exthdrs.c | 29 +- trunk/net/ipv6/route.c | 4 - trunk/net/ipv6/tcp_ipv6.c | 2 +- trunk/net/netlink/af_netlink.c | 14 +- trunk/net/sctp/sm_make_chunk.c | 30 +- trunk/net/sctp/sm_statefuns.c | 20 +- trunk/net/sctp/socket.c | 20 +- trunk/net/socket.c | 3 +- trunk/net/sunrpc/auth_gss/auth_gss.c | 3 +- trunk/net/sunrpc/clnt.c | 30 +- trunk/net/sunrpc/rpc_pipe.c | 55 +- trunk/sound/oss/Kconfig | 30 +- trunk/sound/pci/ac97/ac97_codec.c | 4 +- 560 files changed, 8008 insertions(+), 25213 deletions(-) delete mode 100644 trunk/Documentation/connector/ucon.c delete mode 100644 trunk/Documentation/filesystems/relay.txt create mode 100644 trunk/Documentation/filesystems/relayfs.txt delete mode 100644 trunk/Documentation/networking/LICENSE.qla3xxx delete mode 100644 trunk/arch/powerpc/boot/dts/mpc7448hpc2.dts delete mode 100644 trunk/arch/powerpc/boot/dts/mpc8349emds.dts delete mode 100644 trunk/arch/powerpc/boot/dts/mpc8540ads.dts delete mode 100644 trunk/arch/powerpc/boot/dts/mpc8541cds.dts delete mode 100644 trunk/arch/powerpc/boot/dts/mpc8548cds.dts delete mode 100644 trunk/arch/powerpc/boot/dts/mpc8555cds.dts rename trunk/arch/powerpc/configs/{mpc834x_mds_defconfig => mpc834x_sys_defconfig} (100%) delete mode 100644 trunk/arch/ppc/syslib/ipic.c delete mode 100644 trunk/arch/ppc/syslib/ipic.h delete mode 100644 trunk/drivers/net/fs_enet/fec.h create mode 100644 trunk/drivers/net/fs_enet/fs_enet-mii.c delete mode 100644 trunk/drivers/net/fs_enet/mii-fec.c create mode 100644 trunk/drivers/net/fs_enet/mii-fixed.c delete mode 100644 trunk/drivers/net/phy/fixed.c delete mode 100644 trunk/drivers/net/qla3xxx.c delete mode 100644 trunk/drivers/net/qla3xxx.h delete mode 100644 trunk/drivers/net/ucc_geth.c delete mode 100644 trunk/drivers/net/ucc_geth.h delete mode 100644 trunk/drivers/net/ucc_geth_phy.c delete mode 100644 trunk/drivers/net/ucc_geth_phy.h delete mode 100644 trunk/include/asm-powerpc/tsi108_irq.h diff --git a/[refs] b/[refs] index ffce7cc0cba9..cf421fa47570 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: f2ad2d9b65963322186a8af2bd2965c734a7badb +refs/heads/master: 69758820a42da207bdc775d6eccf1f9fb67cd62e diff --git a/trunk/CREDITS b/trunk/CREDITS index 0fe904ebb7c7..29be6d1fdf49 100644 --- a/trunk/CREDITS +++ b/trunk/CREDITS @@ -2209,7 +2209,7 @@ S: (address available on request) S: USA N: Ian McDonald -E: ian.mcdonald@jandi.co.nz +E: iam4@cs.waikato.ac.nz E: imcdnzl@gmail.com W: http://wand.net.nz/~iam4 W: http://imcdnzl.blogspot.com diff --git a/trunk/Documentation/connector/ucon.c b/trunk/Documentation/connector/ucon.c deleted file mode 100644 index d738cde2a8d5..000000000000 --- a/trunk/Documentation/connector/ucon.c +++ /dev/null @@ -1,206 +0,0 @@ -/* - * ucon.c - * - * Copyright (c) 2004+ Evgeniy Polyakov - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include - -#include -#include -#include - -#include -#include - -#include - -#include -#include -#include -#include -#include -#include - -#include - -#define DEBUG -#define NETLINK_CONNECTOR 11 - -#ifdef DEBUG -#define ulog(f, a...) fprintf(stdout, f, ##a) -#else -#define ulog(f, a...) do {} while (0) -#endif - -static int need_exit; -static __u32 seq; - -static int netlink_send(int s, struct cn_msg *msg) -{ - struct nlmsghdr *nlh; - unsigned int size; - int err; - char buf[128]; - struct cn_msg *m; - - size = NLMSG_SPACE(sizeof(struct cn_msg) + msg->len); - - nlh = (struct nlmsghdr *)buf; - nlh->nlmsg_seq = seq++; - nlh->nlmsg_pid = getpid(); - nlh->nlmsg_type = NLMSG_DONE; - nlh->nlmsg_len = NLMSG_LENGTH(size - sizeof(*nlh)); - nlh->nlmsg_flags = 0; - - m = NLMSG_DATA(nlh); -#if 0 - ulog("%s: [%08x.%08x] len=%u, seq=%u, ack=%u.\n", - __func__, msg->id.idx, msg->id.val, msg->len, msg->seq, msg->ack); -#endif - memcpy(m, msg, sizeof(*m) + msg->len); - - err = send(s, nlh, size, 0); - if (err == -1) - ulog("Failed to send: %s [%d].\n", - strerror(errno), errno); - - return err; -} - -int main(int argc, char *argv[]) -{ - int s; - char buf[1024]; - int len; - struct nlmsghdr *reply; - struct sockaddr_nl l_local; - struct cn_msg *data; - FILE *out; - time_t tm; - struct pollfd pfd; - - if (argc < 2) - out = stdout; - else { - out = fopen(argv[1], "a+"); - if (!out) { - ulog("Unable to open %s for writing: %s\n", - argv[1], strerror(errno)); - out = stdout; - } - } - - memset(buf, 0, sizeof(buf)); - - s = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR); - if (s == -1) { - perror("socket"); - return -1; - } - - l_local.nl_family = AF_NETLINK; - l_local.nl_groups = 0x123; /* bitmask of requested groups */ - l_local.nl_pid = 0; - - if (bind(s, (struct sockaddr *)&l_local, sizeof(struct sockaddr_nl)) == -1) { - perror("bind"); - close(s); - return -1; - } - -#if 0 - { - int on = 0x57; /* Additional group number */ - setsockopt(s, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP, &on, sizeof(on)); - } -#endif - if (0) { - int i, j; - - memset(buf, 0, sizeof(buf)); - - data = (struct cn_msg *)buf; - - data->id.idx = 0x123; - data->id.val = 0x456; - data->seq = seq++; - data->ack = 0; - data->len = 0; - - for (j=0; j<10; ++j) { - for (i=0; i<1000; ++i) { - len = netlink_send(s, data); - } - - ulog("%d messages have been sent to %08x.%08x.\n", i, data->id.idx, data->id.val); - } - - return 0; - } - - - pfd.fd = s; - - while (!need_exit) { - pfd.events = POLLIN; - pfd.revents = 0; - switch (poll(&pfd, 1, -1)) { - case 0: - need_exit = 1; - break; - case -1: - if (errno != EINTR) { - need_exit = 1; - break; - } - continue; - } - if (need_exit) - break; - - memset(buf, 0, sizeof(buf)); - len = recv(s, buf, sizeof(buf), 0); - if (len == -1) { - perror("recv buf"); - close(s); - return -1; - } - reply = (struct nlmsghdr *)buf; - - switch (reply->nlmsg_type) { - case NLMSG_ERROR: - fprintf(out, "Error message received.\n"); - fflush(out); - break; - case NLMSG_DONE: - data = (struct cn_msg *)NLMSG_DATA(reply); - - time(&tm); - fprintf(out, "%.24s : [%x.%x] [%08u.%08u].\n", - ctime(&tm), data->id.idx, data->id.val, data->seq, data->ack); - fflush(out); - break; - default: - break; - } - } - - close(s); - return 0; -} diff --git a/trunk/Documentation/cpusets.txt b/trunk/Documentation/cpusets.txt index 76b44290c154..159e2a0c3e80 100644 --- a/trunk/Documentation/cpusets.txt +++ b/trunk/Documentation/cpusets.txt @@ -217,12 +217,6 @@ exclusive cpuset. Also, the use of a Linux virtual file system (vfs) to represent the cpuset hierarchy provides for a familiar permission and name space for cpusets, with a minimum of additional kernel code. -The cpus file in the root (top_cpuset) cpuset is read-only. -It automatically tracks the value of cpu_online_map, using a CPU -hotplug notifier. If and when memory nodes can be hotplugged, -we expect to make the mems file in the root cpuset read-only -as well, and have it track the value of node_online_map. - 1.4 What are exclusive cpusets ? -------------------------------- diff --git a/trunk/Documentation/feature-removal-schedule.txt b/trunk/Documentation/feature-removal-schedule.txt index d1cd5f93e028..87851efb0228 100644 --- a/trunk/Documentation/feature-removal-schedule.txt +++ b/trunk/Documentation/feature-removal-schedule.txt @@ -120,13 +120,6 @@ Who: Adrian Bunk --------------------------- -What: drivers depending on OSS_OBSOLETE_DRIVER -When: options in 2.6.20, code in 2.6.22 -Why: OSS drivers with ALSA replacements -Who: Adrian Bunk - ---------------------------- - What: pci_module_init(driver) When: January 2007 Why: Is replaced by pci_register_driver(pci_driver). diff --git a/trunk/Documentation/filesystems/00-INDEX b/trunk/Documentation/filesystems/00-INDEX index 16dec61d7671..66fdc0744fe0 100644 --- a/trunk/Documentation/filesystems/00-INDEX +++ b/trunk/Documentation/filesystems/00-INDEX @@ -62,8 +62,8 @@ ramfs-rootfs-initramfs.txt - info on the 'in memory' filesystems ramfs, rootfs and initramfs. reiser4.txt - info on the Reiser4 filesystem based on dancing tree algorithms. -relay.txt - - info on relay, for efficient streaming from kernel to user space. +relayfs.txt + - info on relayfs, for efficient streaming from kernel to user space. romfs.txt - description of the ROMFS filesystem. smbfs.txt diff --git a/trunk/Documentation/filesystems/relay.txt b/trunk/Documentation/filesystems/relay.txt deleted file mode 100644 index d6788dae0349..000000000000 --- a/trunk/Documentation/filesystems/relay.txt +++ /dev/null @@ -1,479 +0,0 @@ -relay interface (formerly relayfs) -================================== - -The relay interface provides a means for kernel applications to -efficiently log and transfer large quantities of data from the kernel -to userspace via user-defined 'relay channels'. - -A 'relay channel' is a kernel->user data relay mechanism implemented -as a set of per-cpu kernel buffers ('channel buffers'), each -represented as a regular file ('relay file') in user space. Kernel -clients write into the channel buffers using efficient write -functions; these automatically log into the current cpu's channel -buffer. User space applications mmap() or read() from the relay files -and retrieve the data as it becomes available. The relay files -themselves are files created in a host filesystem, e.g. debugfs, and -are associated with the channel buffers using the API described below. - -The format of the data logged into the channel buffers is completely -up to the kernel client; the relay interface does however provide -hooks which allow kernel clients to impose some structure on the -buffer data. The relay interface doesn't implement any form of data -filtering - this also is left to the kernel client. The purpose is to -keep things as simple as possible. - -This document provides an overview of the relay interface API. The -details of the function parameters are documented along with the -functions in the relay interface code - please see that for details. - -Semantics -========= - -Each relay channel has one buffer per CPU, each buffer has one or more -sub-buffers. Messages are written to the first sub-buffer until it is -too full to contain a new message, in which case it it is written to -the next (if available). Messages are never split across sub-buffers. -At this point, userspace can be notified so it empties the first -sub-buffer, while the kernel continues writing to the next. - -When notified that a sub-buffer is full, the kernel knows how many -bytes of it are padding i.e. unused space occurring because a complete -message couldn't fit into a sub-buffer. Userspace can use this -knowledge to copy only valid data. - -After copying it, userspace can notify the kernel that a sub-buffer -has been consumed. - -A relay channel can operate in a mode where it will overwrite data not -yet collected by userspace, and not wait for it to be consumed. - -The relay channel itself does not provide for communication of such -data between userspace and kernel, allowing the kernel side to remain -simple and not impose a single interface on userspace. It does -provide a set of examples and a separate helper though, described -below. - -The read() interface both removes padding and internally consumes the -read sub-buffers; thus in cases where read(2) is being used to drain -the channel buffers, special-purpose communication between kernel and -user isn't necessary for basic operation. - -One of the major goals of the relay interface is to provide a low -overhead mechanism for conveying kernel data to userspace. While the -read() interface is easy to use, it's not as efficient as the mmap() -approach; the example code attempts to make the tradeoff between the -two approaches as small as possible. - -klog and relay-apps example code -================================ - -The relay interface itself is ready to use, but to make things easier, -a couple simple utility functions and a set of examples are provided. - -The relay-apps example tarball, available on the relay sourceforge -site, contains a set of self-contained examples, each consisting of a -pair of .c files containing boilerplate code for each of the user and -kernel sides of a relay application. When combined these two sets of -boilerplate code provide glue to easily stream data to disk, without -having to bother with mundane housekeeping chores. - -The 'klog debugging functions' patch (klog.patch in the relay-apps -tarball) provides a couple of high-level logging functions to the -kernel which allow writing formatted text or raw data to a channel, -regardless of whether a channel to write into exists or not, or even -whether the relay interface is compiled into the kernel or not. These -functions allow you to put unconditional 'trace' statements anywhere -in the kernel or kernel modules; only when there is a 'klog handler' -registered will data actually be logged (see the klog and kleak -examples for details). - -It is of course possible to use the relay interface from scratch, -i.e. without using any of the relay-apps example code or klog, but -you'll have to implement communication between userspace and kernel, -allowing both to convey the state of buffers (full, empty, amount of -padding). The read() interface both removes padding and internally -consumes the read sub-buffers; thus in cases where read(2) is being -used to drain the channel buffers, special-purpose communication -between kernel and user isn't necessary for basic operation. Things -such as buffer-full conditions would still need to be communicated via -some channel though. - -klog and the relay-apps examples can be found in the relay-apps -tarball on http://relayfs.sourceforge.net - -The relay interface user space API -================================== - -The relay interface implements basic file operations for user space -access to relay channel buffer data. Here are the file operations -that are available and some comments regarding their behavior: - -open() enables user to open an _existing_ channel buffer. - -mmap() results in channel buffer being mapped into the caller's - memory space. Note that you can't do a partial mmap - you - must map the entire file, which is NRBUF * SUBBUFSIZE. - -read() read the contents of a channel buffer. The bytes read are - 'consumed' by the reader, i.e. they won't be available - again to subsequent reads. If the channel is being used - in no-overwrite mode (the default), it can be read at any - time even if there's an active kernel writer. If the - channel is being used in overwrite mode and there are - active channel writers, results may be unpredictable - - users should make sure that all logging to the channel has - ended before using read() with overwrite mode. Sub-buffer - padding is automatically removed and will not be seen by - the reader. - -sendfile() transfer data from a channel buffer to an output file - descriptor. Sub-buffer padding is automatically removed - and will not be seen by the reader. - -poll() POLLIN/POLLRDNORM/POLLERR supported. User applications are - notified when sub-buffer boundaries are crossed. - -close() decrements the channel buffer's refcount. When the refcount - reaches 0, i.e. when no process or kernel client has the - buffer open, the channel buffer is freed. - -In order for a user application to make use of relay files, the -host filesystem must be mounted. For example, - - mount -t debugfs debugfs /debug - -NOTE: the host filesystem doesn't need to be mounted for kernel - clients to create or use channels - it only needs to be - mounted when user space applications need access to the buffer - data. - - -The relay interface kernel API -============================== - -Here's a summary of the API the relay interface provides to in-kernel clients: - -TBD(curr. line MT:/API/) - channel management functions: - - relay_open(base_filename, parent, subbuf_size, n_subbufs, - callbacks) - relay_close(chan) - relay_flush(chan) - relay_reset(chan) - - channel management typically called on instigation of userspace: - - relay_subbufs_consumed(chan, cpu, subbufs_consumed) - - write functions: - - relay_write(chan, data, length) - __relay_write(chan, data, length) - relay_reserve(chan, length) - - callbacks: - - subbuf_start(buf, subbuf, prev_subbuf, prev_padding) - buf_mapped(buf, filp) - buf_unmapped(buf, filp) - create_buf_file(filename, parent, mode, buf, is_global) - remove_buf_file(dentry) - - helper functions: - - relay_buf_full(buf) - subbuf_start_reserve(buf, length) - - -Creating a channel ------------------- - -relay_open() is used to create a channel, along with its per-cpu -channel buffers. Each channel buffer will have an associated file -created for it in the host filesystem, which can be and mmapped or -read from in user space. The files are named basename0...basenameN-1 -where N is the number of online cpus, and by default will be created -in the root of the filesystem (if the parent param is NULL). If you -want a directory structure to contain your relay files, you should -create it using the host filesystem's directory creation function, -e.g. debugfs_create_dir(), and pass the parent directory to -relay_open(). Users are responsible for cleaning up any directory -structure they create, when the channel is closed - again the host -filesystem's directory removal functions should be used for that, -e.g. debugfs_remove(). - -In order for a channel to be created and the host filesystem's files -associated with its channel buffers, the user must provide definitions -for two callback functions, create_buf_file() and remove_buf_file(). -create_buf_file() is called once for each per-cpu buffer from -relay_open() and allows the user to create the file which will be used -to represent the corresponding channel buffer. The callback should -return the dentry of the file created to represent the channel buffer. -remove_buf_file() must also be defined; it's responsible for deleting -the file(s) created in create_buf_file() and is called during -relay_close(). - -Here are some typical definitions for these callbacks, in this case -using debugfs: - -/* - * create_buf_file() callback. Creates relay file in debugfs. - */ -static struct dentry *create_buf_file_handler(const char *filename, - struct dentry *parent, - int mode, - struct rchan_buf *buf, - int *is_global) -{ - return debugfs_create_file(filename, mode, parent, buf, - &relay_file_operations); -} - -/* - * remove_buf_file() callback. Removes relay file from debugfs. - */ -static int remove_buf_file_handler(struct dentry *dentry) -{ - debugfs_remove(dentry); - - return 0; -} - -/* - * relay interface callbacks - */ -static struct rchan_callbacks relay_callbacks = -{ - .create_buf_file = create_buf_file_handler, - .remove_buf_file = remove_buf_file_handler, -}; - -And an example relay_open() invocation using them: - - chan = relay_open("cpu", NULL, SUBBUF_SIZE, N_SUBBUFS, &relay_callbacks); - -If the create_buf_file() callback fails, or isn't defined, channel -creation and thus relay_open() will fail. - -The total size of each per-cpu buffer is calculated by multiplying the -number of sub-buffers by the sub-buffer size passed into relay_open(). -The idea behind sub-buffers is that they're basically an extension of -double-buffering to N buffers, and they also allow applications to -easily implement random-access-on-buffer-boundary schemes, which can -be important for some high-volume applications. The number and size -of sub-buffers is completely dependent on the application and even for -the same application, different conditions will warrant different -values for these parameters at different times. Typically, the right -values to use are best decided after some experimentation; in general, -though, it's safe to assume that having only 1 sub-buffer is a bad -idea - you're guaranteed to either overwrite data or lose events -depending on the channel mode being used. - -The create_buf_file() implementation can also be defined in such a way -as to allow the creation of a single 'global' buffer instead of the -default per-cpu set. This can be useful for applications interested -mainly in seeing the relative ordering of system-wide events without -the need to bother with saving explicit timestamps for the purpose of -merging/sorting per-cpu files in a postprocessing step. - -To have relay_open() create a global buffer, the create_buf_file() -implementation should set the value of the is_global outparam to a -non-zero value in addition to creating the file that will be used to -represent the single buffer. In the case of a global buffer, -create_buf_file() and remove_buf_file() will be called only once. The -normal channel-writing functions, e.g. relay_write(), can still be -used - writes from any cpu will transparently end up in the global -buffer - but since it is a global buffer, callers should make sure -they use the proper locking for such a buffer, either by wrapping -writes in a spinlock, or by copying a write function from relay.h and -creating a local version that internally does the proper locking. - -Channel 'modes' ---------------- - -relay channels can be used in either of two modes - 'overwrite' or -'no-overwrite'. The mode is entirely determined by the implementation -of the subbuf_start() callback, as described below. The default if no -subbuf_start() callback is defined is 'no-overwrite' mode. If the -default mode suits your needs, and you plan to use the read() -interface to retrieve channel data, you can ignore the details of this -section, as it pertains mainly to mmap() implementations. - -In 'overwrite' mode, also known as 'flight recorder' mode, writes -continuously cycle around the buffer and will never fail, but will -unconditionally overwrite old data regardless of whether it's actually -been consumed. In no-overwrite mode, writes will fail, i.e. data will -be lost, if the number of unconsumed sub-buffers equals the total -number of sub-buffers in the channel. It should be clear that if -there is no consumer or if the consumer can't consume sub-buffers fast -enough, data will be lost in either case; the only difference is -whether data is lost from the beginning or the end of a buffer. - -As explained above, a relay channel is made of up one or more -per-cpu channel buffers, each implemented as a circular buffer -subdivided into one or more sub-buffers. Messages are written into -the current sub-buffer of the channel's current per-cpu buffer via the -write functions described below. Whenever a message can't fit into -the current sub-buffer, because there's no room left for it, the -client is notified via the subbuf_start() callback that a switch to a -new sub-buffer is about to occur. The client uses this callback to 1) -initialize the next sub-buffer if appropriate 2) finalize the previous -sub-buffer if appropriate and 3) return a boolean value indicating -whether or not to actually move on to the next sub-buffer. - -To implement 'no-overwrite' mode, the userspace client would provide -an implementation of the subbuf_start() callback something like the -following: - -static int subbuf_start(struct rchan_buf *buf, - void *subbuf, - void *prev_subbuf, - unsigned int prev_padding) -{ - if (prev_subbuf) - *((unsigned *)prev_subbuf) = prev_padding; - - if (relay_buf_full(buf)) - return 0; - - subbuf_start_reserve(buf, sizeof(unsigned int)); - - return 1; -} - -If the current buffer is full, i.e. all sub-buffers remain unconsumed, -the callback returns 0 to indicate that the buffer switch should not -occur yet, i.e. until the consumer has had a chance to read the -current set of ready sub-buffers. For the relay_buf_full() function -to make sense, the consumer is reponsible for notifying the relay -interface when sub-buffers have been consumed via -relay_subbufs_consumed(). Any subsequent attempts to write into the -buffer will again invoke the subbuf_start() callback with the same -parameters; only when the consumer has consumed one or more of the -ready sub-buffers will relay_buf_full() return 0, in which case the -buffer switch can continue. - -The implementation of the subbuf_start() callback for 'overwrite' mode -would be very similar: - -static int subbuf_start(struct rchan_buf *buf, - void *subbuf, - void *prev_subbuf, - unsigned int prev_padding) -{ - if (prev_subbuf) - *((unsigned *)prev_subbuf) = prev_padding; - - subbuf_start_reserve(buf, sizeof(unsigned int)); - - return 1; -} - -In this case, the relay_buf_full() check is meaningless and the -callback always returns 1, causing the buffer switch to occur -unconditionally. It's also meaningless for the client to use the -relay_subbufs_consumed() function in this mode, as it's never -consulted. - -The default subbuf_start() implementation, used if the client doesn't -define any callbacks, or doesn't define the subbuf_start() callback, -implements the simplest possible 'no-overwrite' mode, i.e. it does -nothing but return 0. - -Header information can be reserved at the beginning of each sub-buffer -by calling the subbuf_start_reserve() helper function from within the -subbuf_start() callback. This reserved area can be used to store -whatever information the client wants. In the example above, room is -reserved in each sub-buffer to store the padding count for that -sub-buffer. This is filled in for the previous sub-buffer in the -subbuf_start() implementation; the padding value for the previous -sub-buffer is passed into the subbuf_start() callback along with a -pointer to the previous sub-buffer, since the padding value isn't -known until a sub-buffer is filled. The subbuf_start() callback is -also called for the first sub-buffer when the channel is opened, to -give the client a chance to reserve space in it. In this case the -previous sub-buffer pointer passed into the callback will be NULL, so -the client should check the value of the prev_subbuf pointer before -writing into the previous sub-buffer. - -Writing to a channel --------------------- - -Kernel clients write data into the current cpu's channel buffer using -relay_write() or __relay_write(). relay_write() is the main logging -function - it uses local_irqsave() to protect the buffer and should be -used if you might be logging from interrupt context. If you know -you'll never be logging from interrupt context, you can use -__relay_write(), which only disables preemption. These functions -don't return a value, so you can't determine whether or not they -failed - the assumption is that you wouldn't want to check a return -value in the fast logging path anyway, and that they'll always succeed -unless the buffer is full and no-overwrite mode is being used, in -which case you can detect a failed write in the subbuf_start() -callback by calling the relay_buf_full() helper function. - -relay_reserve() is used to reserve a slot in a channel buffer which -can be written to later. This would typically be used in applications -that need to write directly into a channel buffer without having to -stage data in a temporary buffer beforehand. Because the actual write -may not happen immediately after the slot is reserved, applications -using relay_reserve() can keep a count of the number of bytes actually -written, either in space reserved in the sub-buffers themselves or as -a separate array. See the 'reserve' example in the relay-apps tarball -at http://relayfs.sourceforge.net for an example of how this can be -done. Because the write is under control of the client and is -separated from the reserve, relay_reserve() doesn't protect the buffer -at all - it's up to the client to provide the appropriate -synchronization when using relay_reserve(). - -Closing a channel ------------------ - -The client calls relay_close() when it's finished using the channel. -The channel and its associated buffers are destroyed when there are no -longer any references to any of the channel buffers. relay_flush() -forces a sub-buffer switch on all the channel buffers, and can be used -to finalize and process the last sub-buffers before the channel is -closed. - -Misc ----- - -Some applications may want to keep a channel around and re-use it -rather than open and close a new channel for each use. relay_reset() -can be used for this purpose - it resets a channel to its initial -state without reallocating channel buffer memory or destroying -existing mappings. It should however only be called when it's safe to -do so, i.e. when the channel isn't currently being written to. - -Finally, there are a couple of utility callbacks that can be used for -different purposes. buf_mapped() is called whenever a channel buffer -is mmapped from user space and buf_unmapped() is called when it's -unmapped. The client can use this notification to trigger actions -within the kernel application, such as enabling/disabling logging to -the channel. - - -Resources -========= - -For news, example code, mailing list, etc. see the relay interface homepage: - - http://relayfs.sourceforge.net - - -Credits -======= - -The ideas and specs for the relay interface came about as a result of -discussions on tracing involving the following: - -Michel Dagenais -Richard Moore -Bob Wisniewski -Karim Yaghmour -Tom Zanussi - -Also thanks to Hubertus Franke for a lot of useful suggestions and bug -reports. diff --git a/trunk/Documentation/filesystems/relayfs.txt b/trunk/Documentation/filesystems/relayfs.txt new file mode 100644 index 000000000000..5832377b7340 --- /dev/null +++ b/trunk/Documentation/filesystems/relayfs.txt @@ -0,0 +1,442 @@ + +relayfs - a high-speed data relay filesystem +============================================ + +relayfs is a filesystem designed to provide an efficient mechanism for +tools and facilities to relay large and potentially sustained streams +of data from kernel space to user space. + +The main abstraction of relayfs is the 'channel'. A channel consists +of a set of per-cpu kernel buffers each represented by a file in the +relayfs filesystem. Kernel clients write into a channel using +efficient write functions which automatically log to the current cpu's +channel buffer. User space applications mmap() the per-cpu files and +retrieve the data as it becomes available. + +The format of the data logged into the channel buffers is completely +up to the relayfs client; relayfs does however provide hooks which +allow clients to impose some structure on the buffer data. Nor does +relayfs implement any form of data filtering - this also is left to +the client. The purpose is to keep relayfs as simple as possible. + +This document provides an overview of the relayfs API. The details of +the function parameters are documented along with the functions in the +filesystem code - please see that for details. + +Semantics +========= + +Each relayfs channel has one buffer per CPU, each buffer has one or +more sub-buffers. Messages are written to the first sub-buffer until +it is too full to contain a new message, in which case it it is +written to the next (if available). Messages are never split across +sub-buffers. At this point, userspace can be notified so it empties +the first sub-buffer, while the kernel continues writing to the next. + +When notified that a sub-buffer is full, the kernel knows how many +bytes of it are padding i.e. unused. Userspace can use this knowledge +to copy only valid data. + +After copying it, userspace can notify the kernel that a sub-buffer +has been consumed. + +relayfs can operate in a mode where it will overwrite data not yet +collected by userspace, and not wait for it to consume it. + +relayfs itself does not provide for communication of such data between +userspace and kernel, allowing the kernel side to remain simple and +not impose a single interface on userspace. It does provide a set of +examples and a separate helper though, described below. + +klog and relay-apps example code +================================ + +relayfs itself is ready to use, but to make things easier, a couple +simple utility functions and a set of examples are provided. + +The relay-apps example tarball, available on the relayfs sourceforge +site, contains a set of self-contained examples, each consisting of a +pair of .c files containing boilerplate code for each of the user and +kernel sides of a relayfs application; combined these two sets of +boilerplate code provide glue to easily stream data to disk, without +having to bother with mundane housekeeping chores. + +The 'klog debugging functions' patch (klog.patch in the relay-apps +tarball) provides a couple of high-level logging functions to the +kernel which allow writing formatted text or raw data to a channel, +regardless of whether a channel to write into exists or not, or +whether relayfs is compiled into the kernel or is configured as a +module. These functions allow you to put unconditional 'trace' +statements anywhere in the kernel or kernel modules; only when there +is a 'klog handler' registered will data actually be logged (see the +klog and kleak examples for details). + +It is of course possible to use relayfs from scratch i.e. without +using any of the relay-apps example code or klog, but you'll have to +implement communication between userspace and kernel, allowing both to +convey the state of buffers (full, empty, amount of padding). + +klog and the relay-apps examples can be found in the relay-apps +tarball on http://relayfs.sourceforge.net + + +The relayfs user space API +========================== + +relayfs implements basic file operations for user space access to +relayfs channel buffer data. Here are the file operations that are +available and some comments regarding their behavior: + +open() enables user to open an _existing_ buffer. + +mmap() results in channel buffer being mapped into the caller's + memory space. Note that you can't do a partial mmap - you must + map the entire file, which is NRBUF * SUBBUFSIZE. + +read() read the contents of a channel buffer. The bytes read are + 'consumed' by the reader i.e. they won't be available again + to subsequent reads. If the channel is being used in + no-overwrite mode (the default), it can be read at any time + even if there's an active kernel writer. If the channel is + being used in overwrite mode and there are active channel + writers, results may be unpredictable - users should make + sure that all logging to the channel has ended before using + read() with overwrite mode. + +poll() POLLIN/POLLRDNORM/POLLERR supported. User applications are + notified when sub-buffer boundaries are crossed. + +close() decrements the channel buffer's refcount. When the refcount + reaches 0 i.e. when no process or kernel client has the buffer + open, the channel buffer is freed. + + +In order for a user application to make use of relayfs files, the +relayfs filesystem must be mounted. For example, + + mount -t relayfs relayfs /mnt/relay + +NOTE: relayfs doesn't need to be mounted for kernel clients to create + or use channels - it only needs to be mounted when user space + applications need access to the buffer data. + + +The relayfs kernel API +====================== + +Here's a summary of the API relayfs provides to in-kernel clients: + + + channel management functions: + + relay_open(base_filename, parent, subbuf_size, n_subbufs, + callbacks) + relay_close(chan) + relay_flush(chan) + relay_reset(chan) + relayfs_create_dir(name, parent) + relayfs_remove_dir(dentry) + relayfs_create_file(name, parent, mode, fops, data) + relayfs_remove_file(dentry) + + channel management typically called on instigation of userspace: + + relay_subbufs_consumed(chan, cpu, subbufs_consumed) + + write functions: + + relay_write(chan, data, length) + __relay_write(chan, data, length) + relay_reserve(chan, length) + + callbacks: + + subbuf_start(buf, subbuf, prev_subbuf, prev_padding) + buf_mapped(buf, filp) + buf_unmapped(buf, filp) + create_buf_file(filename, parent, mode, buf, is_global) + remove_buf_file(dentry) + + helper functions: + + relay_buf_full(buf) + subbuf_start_reserve(buf, length) + + +Creating a channel +------------------ + +relay_open() is used to create a channel, along with its per-cpu +channel buffers. Each channel buffer will have an associated file +created for it in the relayfs filesystem, which can be opened and +mmapped from user space if desired. The files are named +basename0...basenameN-1 where N is the number of online cpus, and by +default will be created in the root of the filesystem. If you want a +directory structure to contain your relayfs files, you can create it +with relayfs_create_dir() and pass the parent directory to +relay_open(). Clients are responsible for cleaning up any directory +structure they create when the channel is closed - use +relayfs_remove_dir() for that. + +The total size of each per-cpu buffer is calculated by multiplying the +number of sub-buffers by the sub-buffer size passed into relay_open(). +The idea behind sub-buffers is that they're basically an extension of +double-buffering to N buffers, and they also allow applications to +easily implement random-access-on-buffer-boundary schemes, which can +be important for some high-volume applications. The number and size +of sub-buffers is completely dependent on the application and even for +the same application, different conditions will warrant different +values for these parameters at different times. Typically, the right +values to use are best decided after some experimentation; in general, +though, it's safe to assume that having only 1 sub-buffer is a bad +idea - you're guaranteed to either overwrite data or lose events +depending on the channel mode being used. + +Channel 'modes' +--------------- + +relayfs channels can be used in either of two modes - 'overwrite' or +'no-overwrite'. The mode is entirely determined by the implementation +of the subbuf_start() callback, as described below. In 'overwrite' +mode, also known as 'flight recorder' mode, writes continuously cycle +around the buffer and will never fail, but will unconditionally +overwrite old data regardless of whether it's actually been consumed. +In no-overwrite mode, writes will fail i.e. data will be lost, if the +number of unconsumed sub-buffers equals the total number of +sub-buffers in the channel. It should be clear that if there is no +consumer or if the consumer can't consume sub-buffers fast enought, +data will be lost in either case; the only difference is whether data +is lost from the beginning or the end of a buffer. + +As explained above, a relayfs channel is made of up one or more +per-cpu channel buffers, each implemented as a circular buffer +subdivided into one or more sub-buffers. Messages are written into +the current sub-buffer of the channel's current per-cpu buffer via the +write functions described below. Whenever a message can't fit into +the current sub-buffer, because there's no room left for it, the +client is notified via the subbuf_start() callback that a switch to a +new sub-buffer is about to occur. The client uses this callback to 1) +initialize the next sub-buffer if appropriate 2) finalize the previous +sub-buffer if appropriate and 3) return a boolean value indicating +whether or not to actually go ahead with the sub-buffer switch. + +To implement 'no-overwrite' mode, the userspace client would provide +an implementation of the subbuf_start() callback something like the +following: + +static int subbuf_start(struct rchan_buf *buf, + void *subbuf, + void *prev_subbuf, + unsigned int prev_padding) +{ + if (prev_subbuf) + *((unsigned *)prev_subbuf) = prev_padding; + + if (relay_buf_full(buf)) + return 0; + + subbuf_start_reserve(buf, sizeof(unsigned int)); + + return 1; +} + +If the current buffer is full i.e. all sub-buffers remain unconsumed, +the callback returns 0 to indicate that the buffer switch should not +occur yet i.e. until the consumer has had a chance to read the current +set of ready sub-buffers. For the relay_buf_full() function to make +sense, the consumer is reponsible for notifying relayfs when +sub-buffers have been consumed via relay_subbufs_consumed(). Any +subsequent attempts to write into the buffer will again invoke the +subbuf_start() callback with the same parameters; only when the +consumer has consumed one or more of the ready sub-buffers will +relay_buf_full() return 0, in which case the buffer switch can +continue. + +The implementation of the subbuf_start() callback for 'overwrite' mode +would be very similar: + +static int subbuf_start(struct rchan_buf *buf, + void *subbuf, + void *prev_subbuf, + unsigned int prev_padding) +{ + if (prev_subbuf) + *((unsigned *)prev_subbuf) = prev_padding; + + subbuf_start_reserve(buf, sizeof(unsigned int)); + + return 1; +} + +In this case, the relay_buf_full() check is meaningless and the +callback always returns 1, causing the buffer switch to occur +unconditionally. It's also meaningless for the client to use the +relay_subbufs_consumed() function in this mode, as it's never +consulted. + +The default subbuf_start() implementation, used if the client doesn't +define any callbacks, or doesn't define the subbuf_start() callback, +implements the simplest possible 'no-overwrite' mode i.e. it does +nothing but return 0. + +Header information can be reserved at the beginning of each sub-buffer +by calling the subbuf_start_reserve() helper function from within the +subbuf_start() callback. This reserved area can be used to store +whatever information the client wants. In the example above, room is +reserved in each sub-buffer to store the padding count for that +sub-buffer. This is filled in for the previous sub-buffer in the +subbuf_start() implementation; the padding value for the previous +sub-buffer is passed into the subbuf_start() callback along with a +pointer to the previous sub-buffer, since the padding value isn't +known until a sub-buffer is filled. The subbuf_start() callback is +also called for the first sub-buffer when the channel is opened, to +give the client a chance to reserve space in it. In this case the +previous sub-buffer pointer passed into the callback will be NULL, so +the client should check the value of the prev_subbuf pointer before +writing into the previous sub-buffer. + +Writing to a channel +-------------------- + +kernel clients write data into the current cpu's channel buffer using +relay_write() or __relay_write(). relay_write() is the main logging +function - it uses local_irqsave() to protect the buffer and should be +used if you might be logging from interrupt context. If you know +you'll never be logging from interrupt context, you can use +__relay_write(), which only disables preemption. These functions +don't return a value, so you can't determine whether or not they +failed - the assumption is that you wouldn't want to check a return +value in the fast logging path anyway, and that they'll always succeed +unless the buffer is full and no-overwrite mode is being used, in +which case you can detect a failed write in the subbuf_start() +callback by calling the relay_buf_full() helper function. + +relay_reserve() is used to reserve a slot in a channel buffer which +can be written to later. This would typically be used in applications +that need to write directly into a channel buffer without having to +stage data in a temporary buffer beforehand. Because the actual write +may not happen immediately after the slot is reserved, applications +using relay_reserve() can keep a count of the number of bytes actually +written, either in space reserved in the sub-buffers themselves or as +a separate array. See the 'reserve' example in the relay-apps tarball +at http://relayfs.sourceforge.net for an example of how this can be +done. Because the write is under control of the client and is +separated from the reserve, relay_reserve() doesn't protect the buffer +at all - it's up to the client to provide the appropriate +synchronization when using relay_reserve(). + +Closing a channel +----------------- + +The client calls relay_close() when it's finished using the channel. +The channel and its associated buffers are destroyed when there are no +longer any references to any of the channel buffers. relay_flush() +forces a sub-buffer switch on all the channel buffers, and can be used +to finalize and process the last sub-buffers before the channel is +closed. + +Creating non-relay files +------------------------ + +relay_open() automatically creates files in the relayfs filesystem to +represent the per-cpu kernel buffers; it's often useful for +applications to be able to create their own files alongside the relay +files in the relayfs filesystem as well e.g. 'control' files much like +those created in /proc or debugfs for similar purposes, used to +communicate control information between the kernel and user sides of a +relayfs application. For this purpose the relayfs_create_file() and +relayfs_remove_file() API functions exist. For relayfs_create_file(), +the caller passes in a set of user-defined file operations to be used +for the file and an optional void * to a user-specified data item, +which will be accessible via inode->u.generic_ip (see the relay-apps +tarball for examples). The file_operations are a required parameter +to relayfs_create_file() and thus the semantics of these files are +completely defined by the caller. + +See the relay-apps tarball at http://relayfs.sourceforge.net for +examples of how these non-relay files are meant to be used. + +Creating relay files in other filesystems +----------------------------------------- + +By default of course, relay_open() creates relay files in the relayfs +filesystem. Because relay_file_operations is exported, however, it's +also possible to create and use relay files in other pseudo-filesytems +such as debugfs. + +For this purpose, two callback functions are provided, +create_buf_file() and remove_buf_file(). create_buf_file() is called +once for each per-cpu buffer from relay_open() to allow the client to +create a file to be used to represent the corresponding buffer; if +this callback is not defined, the default implementation will create +and return a file in the relayfs filesystem to represent the buffer. +The callback should return the dentry of the file created to represent +the relay buffer. Note that the parent directory passed to +relay_open() (and passed along to the callback), if specified, must +exist in the same filesystem the new relay file is created in. If +create_buf_file() is defined, remove_buf_file() must also be defined; +it's responsible for deleting the file(s) created in create_buf_file() +and is called during relay_close(). + +The create_buf_file() implementation can also be defined in such a way +as to allow the creation of a single 'global' buffer instead of the +default per-cpu set. This can be useful for applications interested +mainly in seeing the relative ordering of system-wide events without +the need to bother with saving explicit timestamps for the purpose of +merging/sorting per-cpu files in a postprocessing step. + +To have relay_open() create a global buffer, the create_buf_file() +implementation should set the value of the is_global outparam to a +non-zero value in addition to creating the file that will be used to +represent the single buffer. In the case of a global buffer, +create_buf_file() and remove_buf_file() will be called only once. The +normal channel-writing functions e.g. relay_write() can still be used +- writes from any cpu will transparently end up in the global buffer - +but since it is a global buffer, callers should make sure they use the +proper locking for such a buffer, either by wrapping writes in a +spinlock, or by copying a write function from relayfs_fs.h and +creating a local version that internally does the proper locking. + +See the 'exported-relayfile' examples in the relay-apps tarball for +examples of creating and using relay files in debugfs. + +Misc +---- + +Some applications may want to keep a channel around and re-use it +rather than open and close a new channel for each use. relay_reset() +can be used for this purpose - it resets a channel to its initial +state without reallocating channel buffer memory or destroying +existing mappings. It should however only be called when it's safe to +do so i.e. when the channel isn't currently being written to. + +Finally, there are a couple of utility callbacks that can be used for +different purposes. buf_mapped() is called whenever a channel buffer +is mmapped from user space and buf_unmapped() is called when it's +unmapped. The client can use this notification to trigger actions +within the kernel application, such as enabling/disabling logging to +the channel. + + +Resources +========= + +For news, example code, mailing list, etc. see the relayfs homepage: + + http://relayfs.sourceforge.net + + +Credits +======= + +The ideas and specs for relayfs came about as a result of discussions +on tracing involving the following: + +Michel Dagenais +Richard Moore +Bob Wisniewski +Karim Yaghmour +Tom Zanussi + +Also thanks to Hubertus Franke for a lot of useful suggestions and bug +reports. diff --git a/trunk/Documentation/input/joystick.txt b/trunk/Documentation/input/joystick.txt index 841c353297e6..d53b857a3710 100644 --- a/trunk/Documentation/input/joystick.txt +++ b/trunk/Documentation/input/joystick.txt @@ -39,6 +39,7 @@ them. Bug reports and success stories are also welcome. The input project website is at: + http://www.suse.cz/development/input/ http://atrey.karlin.mff.cuni.cz/~vojtech/input/ There is also a mailing list for the driver at: diff --git a/trunk/Documentation/kernel-parameters.txt b/trunk/Documentation/kernel-parameters.txt index 7947cede8712..b50595a0550f 100644 --- a/trunk/Documentation/kernel-parameters.txt +++ b/trunk/Documentation/kernel-parameters.txt @@ -1183,8 +1183,6 @@ running once the system is up. Mechanism 2. nommconf [IA-32,X86_64] Disable use of MMCONFIG for PCI Configuration - mmconf [IA-32,X86_64] Force MMCONFIG. This is useful - to override the builtin blacklist. nomsi [MSI] If the PCI_MSI kernel config parameter is enabled, this kernel boot option can be used to disable the use of MSI interrupts system-wide. diff --git a/trunk/Documentation/networking/LICENSE.qla3xxx b/trunk/Documentation/networking/LICENSE.qla3xxx deleted file mode 100644 index 2f2077e34d81..000000000000 --- a/trunk/Documentation/networking/LICENSE.qla3xxx +++ /dev/null @@ -1,46 +0,0 @@ -Copyright (c) 2003-2006 QLogic Corporation -QLogic Linux Networking HBA Driver - -This program includes a device driver for Linux 2.6 that may be -distributed with QLogic hardware specific firmware binary file. -You may modify and redistribute the device driver code under the -GNU General Public License as published by the Free Software -Foundation (version 2 or a later version). - -You may redistribute the hardware specific firmware binary file -under the following terms: - - 1. Redistribution of source code (only if applicable), - must retain the above copyright notice, this list of - conditions and the following disclaimer. - - 2. Redistribution in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - - 3. The name of QLogic Corporation may not be used to - endorse or promote products derived from this software - without specific prior written permission - -REGARDLESS OF WHAT LICENSING MECHANISM IS USED OR APPLICABLE, -THIS PROGRAM IS PROVIDED BY QLOGIC CORPORATION "AS IS'' AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR -BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED -TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -USER ACKNOWLEDGES AND AGREES THAT USE OF THIS PROGRAM WILL NOT -CREATE OR GIVE GROUNDS FOR A LICENSE BY IMPLICATION, ESTOPPEL, OR -OTHERWISE IN ANY INTELLECTUAL PROPERTY RIGHTS (PATENT, COPYRIGHT, -TRADE SECRET, MASK WORK, OR OTHER PROPRIETARY RIGHT) EMBODIED IN -ANY OTHER QLOGIC HARDWARE OR SOFTWARE EITHER SOLELY OR IN -COMBINATION WITH THIS PROGRAM. - diff --git a/trunk/Documentation/powerpc/booting-without-of.txt b/trunk/Documentation/powerpc/booting-without-of.txt index 5c0ba235f5a5..8c48b8a27b9c 100644 --- a/trunk/Documentation/powerpc/booting-without-of.txt +++ b/trunk/Documentation/powerpc/booting-without-of.txt @@ -1136,10 +1136,10 @@ Sense and level information should be encoded as follows: Devices connected to openPIC-compatible controllers should encode sense and polarity as follows: - 0 = low to high edge sensitive type enabled + 0 = high to low edge sensitive type enabled 1 = active low level sensitive type enabled - 2 = active high level sensitive type enabled - 3 = high to low edge sensitive type enabled + 2 = low to high edge sensitive type enabled + 3 = active high level sensitive type enabled ISA PIC interrupt controllers should adhere to the ISA PIC encodings listed below: diff --git a/trunk/Documentation/scsi/ChangeLog.megaraid b/trunk/Documentation/scsi/ChangeLog.megaraid index a056bbe67c7e..c173806c91fa 100644 --- a/trunk/Documentation/scsi/ChangeLog.megaraid +++ b/trunk/Documentation/scsi/ChangeLog.megaraid @@ -1,126 +1,3 @@ -Release Date : Fri May 19 09:31:45 EST 2006 - Seokmann Ju -Current Version : 2.20.4.9 (scsi module), 2.20.2.6 (cmm module) -Older Version : 2.20.4.8 (scsi module), 2.20.2.6 (cmm module) - -1. Fixed a bug in megaraid_init_mbox(). - Customer reported "garbage in file on x86_64 platform". - Root Cause: the driver registered controllers as 64-bit DMA capable - for those which are not support it. - Fix: Made change in the function inserting identification machanism - identifying 64-bit DMA capable controllers. - - > -----Original Message----- - > From: Vasily Averin [mailto:vvs@sw.ru] - > Sent: Thursday, May 04, 2006 2:49 PM - > To: linux-scsi@vger.kernel.org; Kolli, Neela; Mukker, Atul; - > Ju, Seokmann; Bagalkote, Sreenivas; - > James.Bottomley@SteelEye.com; devel@openvz.org - > Subject: megaraid_mbox: garbage in file - > - > Hello all, - > - > I've investigated customers claim on the unstable work of - > their node and found a - > strange effect: reading from some files leads to the - > "attempt to access beyond end of device" messages. - > - > I've checked filesystem, memory on the node, motherboard BIOS - > version, but it - > does not help and issue still has been reproduced by simple - > file reading. - > - > Reproducer is simple: - > - > echo 0xffffffff >/proc/sys/dev/scsi/logging_level ; - > cat /vz/private/101/root/etc/ld.so.cache >/tmp/ttt ; - > echo 0 >/proc/sys/dev/scsi/logging - > - > It leads to the following messages in dmesg - > - > sd_init_command: disk=sda, block=871769260, count=26 - > sda : block=871769260 - > sda : reading 26/26 512 byte blocks. - > scsi_add_timer: scmd: f79ed980, time: 7500, (c02b1420) - > sd 0:1:0:0: send 0xf79ed980 sd 0:1:0:0: - > command: Read (10): 28 00 33 f6 24 ac 00 00 1a 00 - > buffer = 0xf7cfb540, bufflen = 13312, done = 0xc0366b40, - > queuecommand 0xc0344010 - > leaving scsi_dispatch_cmnd() - > scsi_delete_timer: scmd: f79ed980, rtn: 1 - > sd 0:1:0:0: done 0xf79ed980 SUCCESS 0 sd 0:1:0:0: - > command: Read (10): 28 00 33 f6 24 ac 00 00 1a 00 - > scsi host busy 1 failed 0 - > sd 0:1:0:0: Notifying upper driver of completion (result 0) - > sd_rw_intr: sda: res=0x0 - > 26 sectors total, 13312 bytes done. - > use_sg is 4 - > attempt to access beyond end of device - > sda6: rw=0, want=1044134458, limit=951401367 - > Buffer I/O error on device sda6, logical block 522067228 - > attempt to access beyond end of device - -2. When INQUIRY with EVPD bit set issued to the MegaRAID controller, - system memory gets corrupted. - Root Cause: MegaRAID F/W handle the INQUIRY with EVPD bit set - incorrectly. - Fix: MegaRAID F/W has fixed the problem and being process of release, - soon. Meanwhile, driver will filter out the request. - -3. One of member in the data structure of the driver leads unaligne - issue on 64-bit platform. - Customer reporeted "kernel unaligned access addrss" issue when - application communicates with MegaRAID HBA driver. - Root Cause: in uioc_t structure, one of member had misaligned and it - led system to display the error message. - Fix: A patch submitted to community from following folk. - - > -----Original Message----- - > From: linux-scsi-owner@vger.kernel.org - > [mailto:linux-scsi-owner@vger.kernel.org] On Behalf Of Sakurai Hiroomi - > Sent: Wednesday, July 12, 2006 4:20 AM - > To: linux-scsi@vger.kernel.org; linux-kernel@vger.kernel.org - > Subject: Re: Help: strange messages from kernel on IA64 platform - > - > Hi, - > - > I saw same message. - > - > When GAM(Global Array Manager) is started, The following - > message output. - > kernel: kernel unaligned access to 0xe0000001fe1080d4, - > ip=0xa000000200053371 - > - > The uioc structure used by ioctl is defined by packed, - > the allignment of each member are disturbed. - > In a 64 bit structure, the allignment of member doesn't fit 64 bit - > boundary. this causes this messages. - > In a 32 bit structure, we don't see the message because the allinment - > of member fit 32 bit boundary even if packed is specified. - > - > patch - > I Add 32 bit dummy member to fit 64 bit boundary. I tested. - > We confirmed this patch fix the problem by IA64 server. - > - > ************************************************************** - > **************** - > --- linux-2.6.9/drivers/scsi/megaraid/megaraid_ioctl.h.orig - > 2006-04-03 17:13:03.000000000 +0900 - > +++ linux-2.6.9/drivers/scsi/megaraid/megaraid_ioctl.h - > 2006-04-03 17:14:09.000000000 +0900 - > @@ -132,6 +132,10 @@ - > /* Driver Data: */ - > void __user * user_data; - > uint32_t user_data_len; - > + - > + /* 64bit alignment */ - > + uint32_t pad_0xBC; - > + - > mraid_passthru_t __user *user_pthru; - > - > mraid_passthru_t *pthru32; - > ************************************************************** - > **************** - Release Date : Mon Apr 11 12:27:22 EST 2006 - Seokmann Ju Current Version : 2.20.4.8 (scsi module), 2.20.2.6 (cmm module) Older Version : 2.20.4.7 (scsi module), 2.20.2.6 (cmm module) diff --git a/trunk/Documentation/sysctl/fs.txt b/trunk/Documentation/sysctl/fs.txt index 5c3a51905969..0b62c62142cf 100644 --- a/trunk/Documentation/sysctl/fs.txt +++ b/trunk/Documentation/sysctl/fs.txt @@ -25,7 +25,6 @@ Currently, these files are in /proc/sys/fs: - inode-state - overflowuid - overflowgid -- suid_dumpable - super-max - super-nr @@ -132,25 +131,6 @@ The default is 65534. ============================================================== -suid_dumpable: - -This value can be used to query and set the core dump mode for setuid -or otherwise protected/tainted binaries. The modes are - -0 - (default) - traditional behaviour. Any process which has changed - privilege levels or is execute only will not be dumped -1 - (debug) - all processes dump core when possible. The core dump is - owned by the current user and no security is applied. This is - intended for system debugging situations only. Ptrace is unchecked. -2 - (suidsafe) - any binary which normally would not be dumped is dumped - readable by root only. This allows the end user to remove - such a dump but not access it directly. For security reasons - core dumps in this mode will not overwrite one another or - other files. This mode is appropriate when adminstrators are - attempting to debug problems in a normal environment. - -============================================================== - super-max & super-nr: These numbers control the maximum number of superblocks, and diff --git a/trunk/Documentation/sysctl/kernel.txt b/trunk/Documentation/sysctl/kernel.txt index 89bf8c20a586..7345c338080a 100644 --- a/trunk/Documentation/sysctl/kernel.txt +++ b/trunk/Documentation/sysctl/kernel.txt @@ -50,6 +50,7 @@ show up in /proc/sys/kernel: - shmmax [ sysv ipc ] - shmmni - stop-a [ SPARC only ] +- suid_dumpable - sysrq ==> Documentation/sysrq.txt - tainted - threads-max @@ -309,6 +310,25 @@ kernel. This value defaults to SHMMAX. ============================================================== +suid_dumpable: + +This value can be used to query and set the core dump mode for setuid +or otherwise protected/tainted binaries. The modes are + +0 - (default) - traditional behaviour. Any process which has changed + privilege levels or is execute only will not be dumped +1 - (debug) - all processes dump core when possible. The core dump is + owned by the current user and no security is applied. This is + intended for system debugging situations only. Ptrace is unchecked. +2 - (suidsafe) - any binary which normally would not be dumped is dumped + readable by root only. This allows the end user to remove + such a dump but not access it directly. For security reasons + core dumps in this mode will not overwrite one another or + other files. This mode is appropriate when adminstrators are + attempting to debug problems in a normal environment. + +============================================================== + tainted: Non-zero if the kernel has been tainted. Numeric values, which diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index 6c399b872e3a..dbcf1d272769 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -889,12 +889,6 @@ M: rdunlap@xenotime.net T: git http://tali.admingilde.org/git/linux-docbook.git S: Maintained -DOCKING STATION DRIVER -P: Kristen Carlson Accardi -M: kristen.c.accardi@intel.com -L: linux-acpi@vger.kernel.org -S: Maintained - DOUBLETALK DRIVER P: James R. Van Zandt M: jrv@vanzandt.mv.com @@ -2366,12 +2360,6 @@ M: linux-driver@qlogic.com L: linux-scsi@vger.kernel.org S: Supported -QLOGIC QLA3XXX NETWORK DRIVER -P: Ron Mercer -M: linux-driver@qlogic.com -L: netdev@vger.kernel.org -S: Supported - QNX4 FILESYSTEM P: Anders Larsen M: al@alarsen.net @@ -3314,11 +3302,10 @@ S: Maintained XFS FILESYSTEM P: Silicon Graphics Inc -P: Tim Shimmin, David Chatterton M: xfs-masters@oss.sgi.com +M: nathans@sgi.com L: xfs@oss.sgi.com W: http://oss.sgi.com/projects/xfs -T: git git://oss.sgi.com:8090/xfs/xfs-2.6 S: Supported X86 3-LEVEL PAGING (PAE) SUPPORT diff --git a/trunk/Makefile b/trunk/Makefile index c9ed7b42873a..8406d02c6385 100644 --- a/trunk/Makefile +++ b/trunk/Makefile @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 18 -EXTRAVERSION = -rc6 +EXTRAVERSION = -rc4 NAME=Crazed Snow-Weasel # *DOCUMENTATION* diff --git a/trunk/arch/arm/Makefile b/trunk/arch/arm/Makefile index 92873cdee31f..3345c6d0fd1e 100644 --- a/trunk/arch/arm/Makefile +++ b/trunk/arch/arm/Makefile @@ -47,8 +47,7 @@ comma = , # testing for a specific architecture or later rather impossible. arch-$(CONFIG_CPU_32v6) :=-D__LINUX_ARM_ARCH__=6 $(call cc-option,-march=armv6,-march=armv5t -Wa$(comma)-march=armv6) arch-$(CONFIG_CPU_32v6K) :=-D__LINUX_ARM_ARCH__=6 $(call cc-option,-march=armv6k,-march=armv5t -Wa$(comma)-march=armv6k) -arch-$(CONFIG_CPU_32v5) :=-D__LINUX_ARM_ARCH__=5 $(call cc-option,-march=armv5te,-march=armv4t) -arch-$(CONFIG_CPU_32v4T) :=-D__LINUX_ARM_ARCH__=4 -march=armv4t +arch-$(CONFIG_CPU_32v5) :=-D__LINUX_ARM_ARCH__=5 $(call cc-option,-march=armv5te,-march=armv4) arch-$(CONFIG_CPU_32v4) :=-D__LINUX_ARM_ARCH__=4 -march=armv4 arch-$(CONFIG_CPU_32v3) :=-D__LINUX_ARM_ARCH__=3 -march=armv3 diff --git a/trunk/arch/arm/common/dmabounce.c b/trunk/arch/arm/common/dmabounce.c index 028bdc9228fb..5b7c26395b44 100644 --- a/trunk/arch/arm/common/dmabounce.c +++ b/trunk/arch/arm/common/dmabounce.c @@ -179,19 +179,17 @@ alloc_safe_buffer(struct dmabounce_device_info *device_info, void *ptr, static inline struct safe_buffer * find_safe_buffer(struct dmabounce_device_info *device_info, dma_addr_t safe_dma_addr) { - struct safe_buffer *b, *rb = NULL; + struct safe_buffer *b = NULL; unsigned long flags; read_lock_irqsave(&device_info->lock, flags); list_for_each_entry(b, &device_info->safe_buffers, node) - if (b->safe_dma_addr == safe_dma_addr) { - rb = b; + if (b->safe_dma_addr == safe_dma_addr) break; - } read_unlock_irqrestore(&device_info->lock, flags); - return rb; + return b; } static inline void diff --git a/trunk/arch/arm/common/sa1111.c b/trunk/arch/arm/common/sa1111.c index 29818bd3248f..a331c12cead9 100644 --- a/trunk/arch/arm/common/sa1111.c +++ b/trunk/arch/arm/common/sa1111.c @@ -618,7 +618,7 @@ __sa1111_probe(struct device *me, struct resource *mem, int irq) { struct sa1111 *sachip; unsigned long id; - unsigned int has_devs; + unsigned int has_devs, val; int i, ret = -ENODEV; sachip = kzalloc(sizeof(struct sa1111), GFP_KERNEL); @@ -669,9 +669,6 @@ __sa1111_probe(struct device *me, struct resource *mem, int irq) sa1111_wake(sachip); #ifdef CONFIG_ARCH_SA1100 - { - unsigned int val; - /* * The SDRAM configuration of the SA1110 and the SA1111 must * match. This is very important to ensure that SA1111 accesses @@ -695,7 +692,6 @@ __sa1111_probe(struct device *me, struct resource *mem, int irq) * Enable the SA1110 memory bus request and grant signals. */ sa1110_mb_enable(); - } #endif /* diff --git a/trunk/arch/arm/configs/csb337_defconfig b/trunk/arch/arm/configs/csb337_defconfig index cf3fa5cb26e4..3594155a8137 100644 --- a/trunk/arch/arm/configs/csb337_defconfig +++ b/trunk/arch/arm/configs/csb337_defconfig @@ -621,8 +621,9 @@ CONFIG_AT91_WATCHDOG=y # USB-based Watchdog Cards # # CONFIG_USBPCWATCHDOG is not set -# CONFIG_HW_RANDOM is not set # CONFIG_NVRAM is not set +CONFIG_RTC=y +# CONFIG_AT91_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set @@ -955,41 +956,9 @@ CONFIG_USB_AT91=y CONFIG_MMC=y # CONFIG_MMC_DEBUG is not set CONFIG_MMC_BLOCK=y +# CONFIG_MMC_WBSD is not set CONFIG_MMC_AT91RM9200=y -# -# Real Time Clock -# -CONFIG_RTC_LIB=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_HCTOSYS=y -CONFIG_RTC_HCTOSYS_DEVICE="rtc1" - -# -# RTC interfaces -# -# CONFIG_RTC_INTF_SYSFS is not set -CONFIG_RTC_INTF_PROC=y -CONFIG_RTC_INTF_DEV=y -# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set - -# -# RTC drivers -# -# CONFIG_RTC_DRV_X1205 is not set -CONFIG_RTC_DRV_DS1307=y -# CONFIG_RTC_DRV_DS1553 is not set -# CONFIG_RTC_DRV_ISL1208 is not set -# CONFIG_RTC_DRV_DS1672 is not set -# CONFIG_RTC_DRV_DS1742 is not set -# CONFIG_RTC_DRV_PCF8563 is not set -# CONFIG_RTC_DRV_PCF8583 is not set -# CONFIG_RTC_DRV_RS5C372 is not set -# CONFIG_RTC_DRV_M48T86 is not set -CONFIG_RTC_DRV_AT91=y -# CONFIG_RTC_DRV_TEST is not set -# CONFIG_RTC_DRV_V3020 is not set - # # File systems # diff --git a/trunk/arch/arm/kernel/Makefile b/trunk/arch/arm/kernel/Makefile index 1320a0efca73..f0c0cdb1c183 100644 --- a/trunk/arch/arm/kernel/Makefile +++ b/trunk/arch/arm/kernel/Makefile @@ -13,11 +13,12 @@ obj-y := compat.o entry-armv.o entry-common.o irq.o \ obj-$(CONFIG_APM) += apm.o obj-$(CONFIG_ISA_DMA_API) += dma.o obj-$(CONFIG_ARCH_ACORN) += ecard.o +obj-$(CONFIG_FOOTBRIDGE) += isa.o obj-$(CONFIG_FIQ) += fiq.o obj-$(CONFIG_MODULES) += armksyms.o module.o obj-$(CONFIG_ARTHUR) += arthur.o obj-$(CONFIG_ISA_DMA) += dma-isa.o -obj-$(CONFIG_PCI) += bios32.o isa.o +obj-$(CONFIG_PCI) += bios32.o obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_OABI_COMPAT) += sys_oabi-compat.o diff --git a/trunk/arch/arm/kernel/entry-armv.S b/trunk/arch/arm/kernel/entry-armv.S index de4e33137901..7ea5f01dfc7b 100644 --- a/trunk/arch/arm/kernel/entry-armv.S +++ b/trunk/arch/arm/kernel/entry-armv.S @@ -634,14 +634,6 @@ ENTRY(__switch_to) * purpose. */ - .macro usr_ret, reg -#ifdef CONFIG_ARM_THUMB - bx \reg -#else - mov pc, \reg -#endif - .endm - .align 5 .globl __kuser_helper_start __kuser_helper_start: @@ -683,7 +675,7 @@ __kuser_memory_barrier: @ 0xffff0fa0 #if __LINUX_ARM_ARCH__ >= 6 && defined(CONFIG_SMP) mcr p15, 0, r0, c7, c10, 5 @ dmb #endif - usr_ret lr + mov pc, lr .align 5 @@ -786,7 +778,7 @@ __kuser_cmpxchg: @ 0xffff0fc0 mov r0, #-1 adds r0, r0, #0 #endif - usr_ret lr + mov pc, lr #else @@ -800,7 +792,7 @@ __kuser_cmpxchg: @ 0xffff0fc0 #ifdef CONFIG_SMP mcr p15, 0, r0, c7, c10, 5 @ dmb #endif - usr_ret lr + mov pc, lr #endif @@ -842,11 +834,16 @@ __kuser_cmpxchg: @ 0xffff0fc0 __kuser_get_tls: @ 0xffff0fe0 #if !defined(CONFIG_HAS_TLS_REG) && !defined(CONFIG_TLS_REG_EMUL) + ldr r0, [pc, #(16 - 8)] @ TLS stored at 0xffff0ff0 + mov pc, lr + #else + mrc p15, 0, r0, c13, c0, 3 @ read TLS register + mov pc, lr + #endif - usr_ret lr .rep 5 .word 0 @ pad up to __kuser_helper_version diff --git a/trunk/arch/arm/kernel/head.S b/trunk/arch/arm/kernel/head.S index 5365d4e5949e..4fe386eea4b4 100644 --- a/trunk/arch/arm/kernel/head.S +++ b/trunk/arch/arm/kernel/head.S @@ -118,7 +118,7 @@ ENTRY(secondary_startup) sub r4, r4, r5 @ mmu has been enabled ldr r4, [r7, r4] @ get secondary_data.pgdir adr lr, __enable_mmu @ return address - add pc, r10, #PROCINFO_INITFUNC @ initialise processor + add pc, r10, #12 @ initialise processor @ (return control reg) /* diff --git a/trunk/arch/arm/kernel/isa.c b/trunk/arch/arm/kernel/isa.c index 54bbd9fe255c..685c3e591a7e 100644 --- a/trunk/arch/arm/kernel/isa.c +++ b/trunk/arch/arm/kernel/isa.c @@ -3,14 +3,21 @@ * * Copyright (C) 1999 Phil Blundell * + * ISA shared memory and I/O port support + */ + +/* * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. - * - * ISA shared memory and I/O port support, and is required to support - * iopl, inb, outb and friends in userspace via glibc emulation. */ + +/* + * Nothing about this is actually ARM specific. One day we could move + * it into kernel/resource.c or some place like that. + */ + #include #include #include @@ -20,49 +27,21 @@ static unsigned int isa_membase, isa_portbase, isa_portshift; static ctl_table ctl_isa_vars[4] = { - { - .ctl_name = BUS_ISA_MEM_BASE, - .procname = "membase", - .data = &isa_membase, - .maxlen = sizeof(isa_membase), - .mode = 0444, - .proc_handler = &proc_dointvec, - }, { - .ctl_name = BUS_ISA_PORT_BASE, - .procname = "portbase", - .data = &isa_portbase, - .maxlen = sizeof(isa_portbase), - .mode = 0444, - .proc_handler = &proc_dointvec, - }, { - .ctl_name = BUS_ISA_PORT_SHIFT, - .procname = "portshift", - .data = &isa_portshift, - .maxlen = sizeof(isa_portshift), - .mode = 0444, - .proc_handler = &proc_dointvec, - }, {0} + {BUS_ISA_MEM_BASE, "membase", &isa_membase, + sizeof(isa_membase), 0444, NULL, &proc_dointvec}, + {BUS_ISA_PORT_BASE, "portbase", &isa_portbase, + sizeof(isa_portbase), 0444, NULL, &proc_dointvec}, + {BUS_ISA_PORT_SHIFT, "portshift", &isa_portshift, + sizeof(isa_portshift), 0444, NULL, &proc_dointvec}, + {0} }; static struct ctl_table_header *isa_sysctl_header; -static ctl_table ctl_isa[2] = { - { - .ctl_name = CTL_BUS_ISA, - .procname = "isa", - .mode = 0555, - .child = ctl_isa_vars, - }, {0} -}; - -static ctl_table ctl_bus[2] = { - { - .ctl_name = CTL_BUS, - .procname = "bus", - .mode = 0555, - .child = ctl_isa, - }, {0} -}; +static ctl_table ctl_isa[2] = {{CTL_BUS_ISA, "isa", NULL, 0, 0555, ctl_isa_vars}, + {0}}; +static ctl_table ctl_bus[2] = {{CTL_BUS, "bus", NULL, 0, 0555, ctl_isa}, + {0}}; void __init register_isa_ports(unsigned int membase, unsigned int portbase, unsigned int portshift) diff --git a/trunk/arch/arm/mach-footbridge/dc21285.c b/trunk/arch/arm/mach-footbridge/dc21285.c index 823e25d4547e..607ed1f5b3f8 100644 --- a/trunk/arch/arm/mach-footbridge/dc21285.c +++ b/trunk/arch/arm/mach-footbridge/dc21285.c @@ -35,6 +35,7 @@ extern int setup_arm_irq(int, struct irqaction *); extern void pcibios_report_status(u_int status_mask, int warn); +extern void register_isa_ports(unsigned int, unsigned int, unsigned int); static unsigned long dc21285_base_address(struct pci_bus *bus, unsigned int devfn) diff --git a/trunk/arch/arm/mach-integrator/pci_v3.c b/trunk/arch/arm/mach-integrator/pci_v3.c index 4418f6d7572d..f9043592e299 100644 --- a/trunk/arch/arm/mach-integrator/pci_v3.c +++ b/trunk/arch/arm/mach-integrator/pci_v3.c @@ -600,6 +600,4 @@ void __init pci_v3_postinit(void) printk(KERN_ERR "PCI: unable to grab local bus timeout " "interrupt: %d\n", ret); #endif - - register_isa_ports(PHYS_PCI_MEM_BASE, PHYS_PCI_IO_BASE, 0); } diff --git a/trunk/arch/arm/mach-pxa/corgi_ssp.c b/trunk/arch/arm/mach-pxa/corgi_ssp.c index ff6b4ee037f5..f9421318cb7a 100644 --- a/trunk/arch/arm/mach-pxa/corgi_ssp.c +++ b/trunk/arch/arm/mach-pxa/corgi_ssp.c @@ -47,15 +47,14 @@ static struct corgissp_machinfo *ssp_machinfo; */ unsigned long corgi_ssp_ads7846_putget(ulong data) { - unsigned long flag; - u32 ret = 0; + unsigned long ret,flag; spin_lock_irqsave(&corgi_ssp_lock, flag); if (ssp_machinfo->cs_ads7846 >= 0) GPCR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846); ssp_write_word(&corgi_ssp_dev,data); - ssp_read_word(&corgi_ssp_dev, &ret); + ret = ssp_read_word(&corgi_ssp_dev); if (ssp_machinfo->cs_ads7846 >= 0) GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846); @@ -89,9 +88,7 @@ void corgi_ssp_ads7846_put(ulong data) unsigned long corgi_ssp_ads7846_get(void) { - u32 ret = 0; - ssp_read_word(&corgi_ssp_dev, &ret); - return ret; + return ssp_read_word(&corgi_ssp_dev); } EXPORT_SYMBOL(corgi_ssp_ads7846_putget); @@ -107,7 +104,6 @@ EXPORT_SYMBOL(corgi_ssp_ads7846_get); unsigned long corgi_ssp_dac_put(ulong data) { unsigned long flag, sscr1 = SSCR1_SPH; - u32 tmp; spin_lock_irqsave(&corgi_ssp_lock, flag); @@ -122,7 +118,7 @@ unsigned long corgi_ssp_dac_put(ulong data) GPCR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon); ssp_write_word(&corgi_ssp_dev,data); /* Read null data back from device to prevent SSP overflow */ - ssp_read_word(&corgi_ssp_dev, &tmp); + ssp_read_word(&corgi_ssp_dev); if (ssp_machinfo->cs_lcdcon >= 0) GPSR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon); @@ -154,7 +150,7 @@ EXPORT_SYMBOL(corgi_ssp_blduty_set); int corgi_ssp_max1111_get(ulong data) { unsigned long flag; - long voltage = 0, voltage1 = 0, voltage2 = 0; + int voltage,voltage1,voltage2; spin_lock_irqsave(&corgi_ssp_lock, flag); if (ssp_machinfo->cs_max1111 >= 0) @@ -167,15 +163,15 @@ int corgi_ssp_max1111_get(ulong data) /* TB1/RB1 */ ssp_write_word(&corgi_ssp_dev,data); - ssp_read_word(&corgi_ssp_dev, (u32*)&voltage1); /* null read */ + ssp_read_word(&corgi_ssp_dev); /* null read */ /* TB12/RB2 */ ssp_write_word(&corgi_ssp_dev,0); - ssp_read_word(&corgi_ssp_dev, (u32*)&voltage1); + voltage1=ssp_read_word(&corgi_ssp_dev); /* TB13/RB3*/ ssp_write_word(&corgi_ssp_dev,0); - ssp_read_word(&corgi_ssp_dev, (u32*)&voltage2); + voltage2=ssp_read_word(&corgi_ssp_dev); ssp_disable(&corgi_ssp_dev); ssp_config(&corgi_ssp_dev, (SSCR0_National | (SSCR0_DSS & 0x0b )), 0, 0, SSCR0_SerClkDiv(ssp_machinfo->clk_ads7846)); diff --git a/trunk/arch/arm/mach-pxa/ssp.c b/trunk/arch/arm/mach-pxa/ssp.c index 1fddfeaa630d..93096befd017 100644 --- a/trunk/arch/arm/mach-pxa/ssp.c +++ b/trunk/arch/arm/mach-pxa/ssp.c @@ -40,8 +40,6 @@ #define PXA_SSP_PORTS 3 -#define TIMEOUT 100000 - struct ssp_info_ { int irq; u32 clock; @@ -94,18 +92,13 @@ static irqreturn_t ssp_interrupt(int irq, void *dev_id, struct pt_regs *regs) * The caller is expected to perform the necessary locking. * * Returns: - * %-ETIMEDOUT timeout occurred + * %-ETIMEDOUT timeout occurred (for future) * 0 success */ int ssp_write_word(struct ssp_dev *dev, u32 data) { - int timeout = TIMEOUT; - - while (!(SSSR_P(dev->port) & SSSR_TNF)) { - if (!--timeout) - return -ETIMEDOUT; + while (!(SSSR_P(dev->port) & SSSR_TNF)) cpu_relax(); - } SSDR_P(dev->port) = data; @@ -124,21 +117,15 @@ int ssp_write_word(struct ssp_dev *dev, u32 data) * The caller is expected to perform the necessary locking. * * Returns: - * %-ETIMEDOUT timeout occurred + * %-ETIMEDOUT timeout occurred (for future) * 32-bit data success */ -int ssp_read_word(struct ssp_dev *dev, u32 *data) +int ssp_read_word(struct ssp_dev *dev) { - int timeout = TIMEOUT; - - while (!(SSSR_P(dev->port) & SSSR_RNE)) { - if (!--timeout) - return -ETIMEDOUT; + while (!(SSSR_P(dev->port) & SSSR_RNE)) cpu_relax(); - } - *data = SSDR_P(dev->port); - return 0; + return SSDR_P(dev->port); } /** @@ -149,21 +136,13 @@ int ssp_read_word(struct ssp_dev *dev, u32 *data) * * The caller is expected to perform the necessary locking. */ -int ssp_flush(struct ssp_dev *dev) +void ssp_flush(struct ssp_dev *dev) { - int timeout = TIMEOUT * 2; - do { while (SSSR_P(dev->port) & SSSR_RNE) { - if (!--timeout) - return -ETIMEDOUT; (void) SSDR_P(dev->port); } - if (!--timeout) - return -ETIMEDOUT; } while (SSSR_P(dev->port) & SSSR_BSY); - - return 0; } /** diff --git a/trunk/arch/arm/mach-s3c2410/Makefile b/trunk/arch/arm/mach-s3c2410/Makefile index 273e05f2b8de..0c7938645df6 100644 --- a/trunk/arch/arm/mach-s3c2410/Makefile +++ b/trunk/arch/arm/mach-s3c2410/Makefile @@ -10,47 +10,45 @@ obj-m := obj-n := obj- := -# DMA -obj-$(CONFIG_S3C2410_DMA) += dma.o - # S3C2400 support files -obj-$(CONFIG_CPU_S3C2400) += s3c2400-gpio.o +obj-$(CONFIG_CPU_S3C2400) += s3c2400-gpio.o # S3C2410 support files -obj-$(CONFIG_CPU_S3C2410) += s3c2410.o -obj-$(CONFIG_CPU_S3C2410) += s3c2410-gpio.o +obj-$(CONFIG_CPU_S3C2410) += s3c2410.o +obj-$(CONFIG_CPU_S3C2410) += s3c2410-gpio.o +obj-$(CONFIG_S3C2410_DMA) += dma.o # Power Management support -obj-$(CONFIG_PM) += pm.o sleep.o -obj-$(CONFIG_PM_SIMTEC) += pm-simtec.o +obj-$(CONFIG_PM) += pm.o sleep.o +obj-$(CONFIG_PM_SIMTEC) += pm-simtec.o # S3C2412 support -obj-$(CONFIG_CPU_S3C2412) += s3c2412.o -obj-$(CONFIG_CPU_S3C2412) += s3c2412-clock.o +obj-$(CONFIG_CPU_S3C2412) += s3c2412.o +obj-$(CONFIG_CPU_S3C2412) += s3c2412-clock.o # # S3C244X support -obj-$(CONFIG_CPU_S3C244X) += s3c244x.o -obj-$(CONFIG_CPU_S3C244X) += s3c244x-irq.o +obj-$(CONFIG_CPU_S3C244X) += s3c244x.o +obj-$(CONFIG_CPU_S3C244X) += s3c244x-irq.o # Clock control -obj-$(CONFIG_S3C2410_CLOCK) += s3c2410-clock.o +obj-$(CONFIG_S3C2410_CLOCK) += s3c2410-clock.o # S3C2440 support -obj-$(CONFIG_CPU_S3C2440) += s3c2440.o s3c2440-dsc.o -obj-$(CONFIG_CPU_S3C2440) += s3c2440-irq.o -obj-$(CONFIG_CPU_S3C2440) += s3c2440-clock.o -obj-$(CONFIG_CPU_S3C2440) += s3c2410-gpio.o +obj-$(CONFIG_CPU_S3C2440) += s3c2440.o s3c2440-dsc.o +obj-$(CONFIG_CPU_S3C2440) += s3c2440-irq.o +obj-$(CONFIG_CPU_S3C2440) += s3c2440-clock.o +obj-$(CONFIG_CPU_S3C2440) += s3c2410-gpio.o # S3C2442 support -obj-$(CONFIG_CPU_S3C2442) += s3c2442.o -obj-$(CONFIG_CPU_S3C2442) += s3c2442-clock.o +obj-$(CONFIG_CPU_S3C2442) += s3c2442.o +obj-$(CONFIG_CPU_S3C2442) += s3c2442-clock.o # bast extras diff --git a/trunk/arch/arm/mach-s3c2410/dma.c b/trunk/arch/arm/mach-s3c2410/dma.c index cc92a7b2db88..094cc52745c5 100644 --- a/trunk/arch/arm/mach-s3c2410/dma.c +++ b/trunk/arch/arm/mach-s3c2410/dma.c @@ -60,7 +60,7 @@ static void __iomem *dma_base; static kmem_cache_t *dma_kmem; /* dma channel state information */ -struct s3c2410_dma_chan s3c2410_chans[S3C2410_DMA_CHANNELS]; +s3c2410_dma_chan_t s3c2410_chans[S3C2410_DMA_CHANNELS]; /* debugging functions */ @@ -74,7 +74,7 @@ struct s3c2410_dma_chan s3c2410_chans[S3C2410_DMA_CHANNELS]; #define dma_wrreg(chan, reg, val) writel((val), (chan)->regs + (reg)) #else static inline void -dma_wrreg(struct s3c2410_dma_chan *chan, int reg, unsigned long val) +dma_wrreg(s3c2410_dma_chan_t *chan, int reg, unsigned long val) { pr_debug("writing %08x to register %08x\n",(unsigned int)val,reg); writel(val, dma_regaddr(chan, reg)); @@ -102,7 +102,7 @@ struct s3c2410_dma_regstate { */ static void -dmadbg_capture(struct s3c2410_dma_chan *chan, struct s3c2410_dma_regstate *regs) +dmadbg_capture(s3c2410_dma_chan_t *chan, struct s3c2410_dma_regstate *regs) { regs->dcsrc = dma_rdreg(chan, S3C2410_DMA_DCSRC); regs->disrc = dma_rdreg(chan, S3C2410_DMA_DISRC); @@ -112,7 +112,7 @@ dmadbg_capture(struct s3c2410_dma_chan *chan, struct s3c2410_dma_regstate *regs) } static void -dmadbg_dumpregs(const char *fname, int line, struct s3c2410_dma_chan *chan, +dmadbg_showregs(const char *fname, int line, s3c2410_dma_chan_t *chan, struct s3c2410_dma_regstate *regs) { printk(KERN_DEBUG "dma%d: %s:%d: DCSRC=%08lx, DISRC=%08lx, DSTAT=%08lx DMT=%02lx, DCON=%08lx\n", @@ -122,7 +122,7 @@ dmadbg_dumpregs(const char *fname, int line, struct s3c2410_dma_chan *chan, } static void -dmadbg_showchan(const char *fname, int line, struct s3c2410_dma_chan *chan) +dmadbg_showchan(const char *fname, int line, s3c2410_dma_chan_t *chan) { struct s3c2410_dma_regstate state; @@ -132,16 +132,7 @@ dmadbg_showchan(const char *fname, int line, struct s3c2410_dma_chan *chan) chan->number, fname, line, chan->load_state, chan->curr, chan->next, chan->end); - dmadbg_dumpregs(fname, line, chan, &state); -} - -static void -dmadbg_showregs(const char *fname, int line, struct s3c2410_dma_chan *chan) -{ - struct s3c2410_dma_regstate state; - - dmadbg_capture(chan, &state); - dmadbg_dumpregs(fname, line, chan, &state); + dmadbg_showregs(fname, line, chan, &state); } #define dbg_showregs(chan) dmadbg_showregs(__FUNCTION__, __LINE__, (chan)) @@ -164,7 +155,7 @@ dmadbg_showregs(const char *fname, int line, struct s3c2410_dma_chan *chan) */ static void -s3c2410_dma_stats_timeout(struct s3c2410_dma_stats *stats, int val) +s3c2410_dma_stats_timeout(s3c2410_dma_stats_t *stats, int val) { if (stats == NULL) return; @@ -183,7 +174,7 @@ s3c2410_dma_stats_timeout(struct s3c2410_dma_stats *stats, int val) */ static int -s3c2410_dma_waitforload(struct s3c2410_dma_chan *chan, int line) +s3c2410_dma_waitforload(s3c2410_dma_chan_t *chan, int line) { int timeout = chan->load_timeout; int took; @@ -230,8 +221,8 @@ s3c2410_dma_waitforload(struct s3c2410_dma_chan *chan, int line) */ static inline int -s3c2410_dma_loadbuffer(struct s3c2410_dma_chan *chan, - struct s3c2410_dma_buf *buf) +s3c2410_dma_loadbuffer(s3c2410_dma_chan_t *chan, + s3c2410_dma_buf_t *buf) { unsigned long reload; @@ -262,14 +253,10 @@ s3c2410_dma_loadbuffer(struct s3c2410_dma_chan *chan, buf->next); reload = (buf->next == NULL) ? S3C2410_DCON_NORELOAD : 0; } else { - //pr_debug("load_state is %d => autoreload\n", chan->load_state); + pr_debug("load_state is %d => autoreload\n", chan->load_state); reload = S3C2410_DCON_AUTORELOAD; } - if ((buf->data & 0xf0000000) != 0x30000000) { - dmawarn("dmaload: buffer is %p\n", (void *)buf->data); - } - writel(buf->data, chan->addr_reg); dma_wrreg(chan, S3C2410_DMA_DCON, @@ -304,7 +291,7 @@ s3c2410_dma_loadbuffer(struct s3c2410_dma_chan *chan, */ static void -s3c2410_dma_call_op(struct s3c2410_dma_chan *chan, enum s3c2410_chan_op op) +s3c2410_dma_call_op(s3c2410_dma_chan_t *chan, s3c2410_chan_op_t op) { if (chan->op_fn != NULL) { (chan->op_fn)(chan, op); @@ -318,8 +305,8 @@ s3c2410_dma_call_op(struct s3c2410_dma_chan *chan, enum s3c2410_chan_op op) */ static inline void -s3c2410_dma_buffdone(struct s3c2410_dma_chan *chan, struct s3c2410_dma_buf *buf, - enum s3c2410_dma_buffresult result) +s3c2410_dma_buffdone(s3c2410_dma_chan_t *chan, s3c2410_dma_buf_t *buf, + s3c2410_dma_buffresult_t result) { pr_debug("callback_fn=%p, buf=%p, id=%p, size=%d, result=%d\n", chan->callback_fn, buf, buf->id, buf->size, result); @@ -334,7 +321,7 @@ s3c2410_dma_buffdone(struct s3c2410_dma_chan *chan, struct s3c2410_dma_buf *buf, * start a dma channel going */ -static int s3c2410_dma_start(struct s3c2410_dma_chan *chan) +static int s3c2410_dma_start(s3c2410_dma_chan_t *chan) { unsigned long tmp; unsigned long flags; @@ -383,7 +370,7 @@ static int s3c2410_dma_start(struct s3c2410_dma_chan *chan) tmp |= S3C2410_DMASKTRIG_ON; dma_wrreg(chan, S3C2410_DMA_DMASKTRIG, tmp); - pr_debug("dma%d: %08lx to DMASKTRIG\n", chan->number, tmp); + pr_debug("wrote %08lx to DMASKTRIG\n", tmp); #if 0 /* the dma buffer loads should take care of clearing the AUTO @@ -397,30 +384,7 @@ static int s3c2410_dma_start(struct s3c2410_dma_chan *chan) dbg_showchan(chan); - /* if we've only loaded one buffer onto the channel, then chec - * to see if we have another, and if so, try and load it so when - * the first buffer is finished, the new one will be loaded onto - * the channel */ - - if (chan->next != NULL) { - if (chan->load_state == S3C2410_DMALOAD_1LOADED) { - - if (s3c2410_dma_waitforload(chan, __LINE__) == 0) { - pr_debug("%s: buff not yet loaded, no more todo\n", - __FUNCTION__); - } else { - chan->load_state = S3C2410_DMALOAD_1RUNNING; - s3c2410_dma_loadbuffer(chan, chan->next); - } - - } else if (chan->load_state == S3C2410_DMALOAD_1RUNNING) { - s3c2410_dma_loadbuffer(chan, chan->next); - } - } - - local_irq_restore(flags); - return 0; } @@ -430,7 +394,7 @@ static int s3c2410_dma_start(struct s3c2410_dma_chan *chan) */ static int -s3c2410_dma_canload(struct s3c2410_dma_chan *chan) +s3c2410_dma_canload(s3c2410_dma_chan_t *chan) { if (chan->load_state == S3C2410_DMALOAD_NONE || chan->load_state == S3C2410_DMALOAD_1RUNNING) @@ -460,8 +424,8 @@ s3c2410_dma_canload(struct s3c2410_dma_chan *chan) int s3c2410_dma_enqueue(unsigned int channel, void *id, dma_addr_t data, int size) { - struct s3c2410_dma_chan *chan = &s3c2410_chans[channel]; - struct s3c2410_dma_buf *buf; + s3c2410_dma_chan_t *chan = &s3c2410_chans[channel]; + s3c2410_dma_buf_t *buf; unsigned long flags; check_channel(channel); @@ -472,11 +436,12 @@ int s3c2410_dma_enqueue(unsigned int channel, void *id, buf = kmem_cache_alloc(dma_kmem, GFP_ATOMIC); if (buf == NULL) { pr_debug("%s: out of memory (%ld alloc)\n", - __FUNCTION__, (long)sizeof(*buf)); + __FUNCTION__, sizeof(*buf)); return -ENOMEM; } - //pr_debug("%s: new buffer %p\n", __FUNCTION__, buf); + pr_debug("%s: new buffer %p\n", __FUNCTION__, buf); + //dbg_showchan(chan); buf->next = NULL; @@ -540,7 +505,7 @@ int s3c2410_dma_enqueue(unsigned int channel, void *id, EXPORT_SYMBOL(s3c2410_dma_enqueue); static inline void -s3c2410_dma_freebuf(struct s3c2410_dma_buf *buf) +s3c2410_dma_freebuf(s3c2410_dma_buf_t *buf) { int magicok = (buf->magic == BUF_MAGIC); @@ -560,7 +525,7 @@ s3c2410_dma_freebuf(struct s3c2410_dma_buf *buf) */ static inline void -s3c2410_dma_lastxfer(struct s3c2410_dma_chan *chan) +s3c2410_dma_lastxfer(s3c2410_dma_chan_t *chan) { pr_debug("dma%d: s3c2410_dma_lastxfer: load_state %d\n", chan->number, chan->load_state); @@ -572,20 +537,14 @@ s3c2410_dma_lastxfer(struct s3c2410_dma_chan *chan) case S3C2410_DMALOAD_1LOADED: if (s3c2410_dma_waitforload(chan, __LINE__) == 0) { /* flag error? */ - printk(KERN_ERR "dma%d: timeout waiting for load (%s)\n", - chan->number, __FUNCTION__); + printk(KERN_ERR "dma%d: timeout waiting for load\n", + chan->number); return; } break; - case S3C2410_DMALOAD_1LOADED_1RUNNING: - /* I belive in this case we do not have anything to do - * until the next buffer comes along, and we turn off the - * reload */ - return; - default: - pr_debug("dma%d: lastxfer: unhandled load_state %d with no next\n", + pr_debug("dma%d: lastxfer: unhandled load_state %d with no next", chan->number, chan->load_state); return; @@ -601,8 +560,8 @@ s3c2410_dma_lastxfer(struct s3c2410_dma_chan *chan) static irqreturn_t s3c2410_dma_irq(int irq, void *devpw, struct pt_regs *regs) { - struct s3c2410_dma_chan *chan = (struct s3c2410_dma_chan *)devpw; - struct s3c2410_dma_buf *buf; + s3c2410_dma_chan_t *chan = (s3c2410_dma_chan_t *)devpw; + s3c2410_dma_buf_t *buf; buf = chan->curr; @@ -670,14 +629,7 @@ s3c2410_dma_irq(int irq, void *devpw, struct pt_regs *regs) } else { } - /* only reload if the channel is still running... our buffer done - * routine may have altered the state by requesting the dma channel - * to stop or shutdown... */ - - /* todo: check that when the channel is shut-down from inside this - * function, we cope with unsetting reload, etc */ - - if (chan->next != NULL && chan->state != S3C2410_DMA_IDLE) { + if (chan->next != NULL) { unsigned long flags; switch (chan->load_state) { @@ -692,8 +644,8 @@ s3c2410_dma_irq(int irq, void *devpw, struct pt_regs *regs) case S3C2410_DMALOAD_1LOADED: if (s3c2410_dma_waitforload(chan, __LINE__) == 0) { /* flag error? */ - printk(KERN_ERR "dma%d: timeout waiting for load (%s)\n", - chan->number, __FUNCTION__); + printk(KERN_ERR "dma%d: timeout waiting for load\n", + chan->number); return IRQ_HANDLED; } @@ -726,15 +678,17 @@ s3c2410_dma_irq(int irq, void *devpw, struct pt_regs *regs) return IRQ_HANDLED; } + + /* s3c2410_request_dma * * get control of an dma channel */ -int s3c2410_dma_request(unsigned int channel, struct s3c2410_dma_client *client, +int s3c2410_dma_request(unsigned int channel, s3c2410_dma_client_t *client, void *dev) { - struct s3c2410_dma_chan *chan = &s3c2410_chans[channel]; + s3c2410_dma_chan_t *chan = &s3c2410_chans[channel]; unsigned long flags; int err; @@ -764,17 +718,11 @@ int s3c2410_dma_request(unsigned int channel, struct s3c2410_dma_client *client, pr_debug("dma%d: %s : requesting irq %d\n", channel, __FUNCTION__, chan->irq); - chan->irq_claimed = 1; - local_irq_restore(flags); - err = request_irq(chan->irq, s3c2410_dma_irq, IRQF_DISABLED, client->name, (void *)chan); - local_irq_save(flags); - if (err) { chan->in_use = 0; - chan->irq_claimed = 0; local_irq_restore(flags); printk(KERN_ERR "%s: cannot get IRQ %d for DMA %d\n", @@ -782,6 +730,7 @@ int s3c2410_dma_request(unsigned int channel, struct s3c2410_dma_client *client, return err; } + chan->irq_claimed = 1; chan->irq_enabled = 1; } @@ -807,9 +756,9 @@ EXPORT_SYMBOL(s3c2410_dma_request); * allowed to go through. */ -int s3c2410_dma_free(dmach_t channel, struct s3c2410_dma_client *client) +int s3c2410_dma_free(dmach_t channel, s3c2410_dma_client_t *client) { - struct s3c2410_dma_chan *chan = &s3c2410_chans[channel]; + s3c2410_dma_chan_t *chan = &s3c2410_chans[channel]; unsigned long flags; check_channel(channel); @@ -846,7 +795,7 @@ int s3c2410_dma_free(dmach_t channel, struct s3c2410_dma_client *client) EXPORT_SYMBOL(s3c2410_dma_free); -static int s3c2410_dma_dostop(struct s3c2410_dma_chan *chan) +static int s3c2410_dma_dostop(s3c2410_dma_chan_t *chan) { unsigned long tmp; unsigned long flags; @@ -861,7 +810,6 @@ static int s3c2410_dma_dostop(struct s3c2410_dma_chan *chan) tmp = dma_rdreg(chan, S3C2410_DMA_DMASKTRIG); tmp |= S3C2410_DMASKTRIG_STOP; - //tmp &= ~S3C2410_DMASKTRIG_ON; dma_wrreg(chan, S3C2410_DMA_DMASKTRIG, tmp); #if 0 @@ -871,7 +819,6 @@ static int s3c2410_dma_dostop(struct s3c2410_dma_chan *chan) dma_wrreg(chan, S3C2410_DMA_DCON, tmp); #endif - /* should stop do this, or should we wait for flush? */ chan->state = S3C2410_DMA_IDLE; chan->load_state = S3C2410_DMALOAD_NONE; @@ -880,35 +827,17 @@ static int s3c2410_dma_dostop(struct s3c2410_dma_chan *chan) return 0; } -void s3c2410_dma_waitforstop(struct s3c2410_dma_chan *chan) -{ - unsigned long tmp; - unsigned int timeout = 0x10000; - - while (timeout-- > 0) { - tmp = dma_rdreg(chan, S3C2410_DMA_DMASKTRIG); - - if (!(tmp & S3C2410_DMASKTRIG_ON)) - return; - } - - pr_debug("dma%d: failed to stop?\n", chan->number); -} - - /* s3c2410_dma_flush * * stop the channel, and remove all current and pending transfers */ -static int s3c2410_dma_flush(struct s3c2410_dma_chan *chan) +static int s3c2410_dma_flush(s3c2410_dma_chan_t *chan) { - struct s3c2410_dma_buf *buf, *next; + s3c2410_dma_buf_t *buf, *next; unsigned long flags; - pr_debug("%s: chan %p (%d)\n", __FUNCTION__, chan, chan->number); - - dbg_showchan(chan); + pr_debug("%s:\n", __FUNCTION__); local_irq_save(flags); @@ -935,69 +864,16 @@ static int s3c2410_dma_flush(struct s3c2410_dma_chan *chan) } } - dbg_showregs(chan); - - s3c2410_dma_waitforstop(chan); - -#if 0 - /* should also clear interrupts, according to WinCE BSP */ - { - unsigned long tmp; - - tmp = dma_rdreg(chan, S3C2410_DMA_DCON); - tmp |= S3C2410_DCON_NORELOAD; - dma_wrreg(chan, S3C2410_DMA_DCON, tmp); - } -#endif - - dbg_showregs(chan); - local_irq_restore(flags); return 0; } -int -s3c2410_dma_started(struct s3c2410_dma_chan *chan) -{ - unsigned long flags; - - local_irq_save(flags); - - dbg_showchan(chan); - - /* if we've only loaded one buffer onto the channel, then chec - * to see if we have another, and if so, try and load it so when - * the first buffer is finished, the new one will be loaded onto - * the channel */ - - if (chan->next != NULL) { - if (chan->load_state == S3C2410_DMALOAD_1LOADED) { - - if (s3c2410_dma_waitforload(chan, __LINE__) == 0) { - pr_debug("%s: buff not yet loaded, no more todo\n", - __FUNCTION__); - } else { - chan->load_state = S3C2410_DMALOAD_1RUNNING; - s3c2410_dma_loadbuffer(chan, chan->next); - } - - } else if (chan->load_state == S3C2410_DMALOAD_1RUNNING) { - s3c2410_dma_loadbuffer(chan, chan->next); - } - } - - - local_irq_restore(flags); - - return 0; - -} int -s3c2410_dma_ctrl(dmach_t channel, enum s3c2410_chan_op op) +s3c2410_dma_ctrl(dmach_t channel, s3c2410_chan_op_t op) { - struct s3c2410_dma_chan *chan = &s3c2410_chans[channel]; + s3c2410_dma_chan_t *chan = &s3c2410_chans[channel]; check_channel(channel); @@ -1009,15 +885,14 @@ s3c2410_dma_ctrl(dmach_t channel, enum s3c2410_chan_op op) return s3c2410_dma_dostop(chan); case S3C2410_DMAOP_PAUSE: + return -ENOENT; + case S3C2410_DMAOP_RESUME: return -ENOENT; case S3C2410_DMAOP_FLUSH: return s3c2410_dma_flush(chan); - case S3C2410_DMAOP_STARTED: - return s3c2410_dma_started(chan); - case S3C2410_DMAOP_TIMEOUT: return 0; @@ -1046,7 +921,7 @@ int s3c2410_dma_config(dmach_t channel, int xferunit, int dcon) { - struct s3c2410_dma_chan *chan = &s3c2410_chans[channel]; + s3c2410_dma_chan_t *chan = &s3c2410_chans[channel]; pr_debug("%s: chan=%d, xfer_unit=%d, dcon=%08x\n", __FUNCTION__, channel, xferunit, dcon); @@ -1086,7 +961,7 @@ EXPORT_SYMBOL(s3c2410_dma_config); int s3c2410_dma_setflags(dmach_t channel, unsigned int flags) { - struct s3c2410_dma_chan *chan = &s3c2410_chans[channel]; + s3c2410_dma_chan_t *chan = &s3c2410_chans[channel]; check_channel(channel); @@ -1106,7 +981,7 @@ EXPORT_SYMBOL(s3c2410_dma_setflags); int s3c2410_dma_set_opfn(dmach_t channel, s3c2410_dma_opfn_t rtn) { - struct s3c2410_dma_chan *chan = &s3c2410_chans[channel]; + s3c2410_dma_chan_t *chan = &s3c2410_chans[channel]; check_channel(channel); @@ -1121,7 +996,7 @@ EXPORT_SYMBOL(s3c2410_dma_set_opfn); int s3c2410_dma_set_buffdone_fn(dmach_t channel, s3c2410_dma_cbfn_t rtn) { - struct s3c2410_dma_chan *chan = &s3c2410_chans[channel]; + s3c2410_dma_chan_t *chan = &s3c2410_chans[channel]; check_channel(channel); @@ -1149,11 +1024,11 @@ EXPORT_SYMBOL(s3c2410_dma_set_buffdone_fn); */ int s3c2410_dma_devconfig(int channel, - enum s3c2410_dmasrc source, + s3c2410_dmasrc_t source, int hwcfg, unsigned long devaddr) { - struct s3c2410_dma_chan *chan = &s3c2410_chans[channel]; + s3c2410_dma_chan_t *chan = &s3c2410_chans[channel]; check_channel(channel); @@ -1200,7 +1075,7 @@ EXPORT_SYMBOL(s3c2410_dma_devconfig); int s3c2410_dma_getposition(dmach_t channel, dma_addr_t *src, dma_addr_t *dst) { - struct s3c2410_dma_chan *chan = &s3c2410_chans[channel]; + s3c2410_dma_chan_t *chan = &s3c2410_chans[channel]; check_channel(channel); @@ -1222,7 +1097,7 @@ EXPORT_SYMBOL(s3c2410_dma_getposition); static int s3c2410_dma_suspend(struct sys_device *dev, pm_message_t state) { - struct s3c2410_dma_chan *cp = container_of(dev, struct s3c2410_dma_chan, dev); + s3c2410_dma_chan_t *cp = container_of(dev, s3c2410_dma_chan_t, dev); printk(KERN_DEBUG "suspending dma channel %d\n", cp->number); @@ -1262,7 +1137,7 @@ static struct sysdev_class dma_sysclass = { static void s3c2410_dma_cache_ctor(void *p, kmem_cache_t *c, unsigned long f) { - memset(p, 0, sizeof(struct s3c2410_dma_buf)); + memset(p, 0, sizeof(s3c2410_dma_buf_t)); } @@ -1270,7 +1145,7 @@ static void s3c2410_dma_cache_ctor(void *p, kmem_cache_t *c, unsigned long f) static int __init s3c2410_init_dma(void) { - struct s3c2410_dma_chan *cp; + s3c2410_dma_chan_t *cp; int channel; int ret; @@ -1288,7 +1163,7 @@ static int __init s3c2410_init_dma(void) goto err; } - dma_kmem = kmem_cache_create("dma_desc", sizeof(struct s3c2410_dma_buf), 0, + dma_kmem = kmem_cache_create("dma_desc", sizeof(s3c2410_dma_buf_t), 0, SLAB_HWCACHE_ALIGN, s3c2410_dma_cache_ctor, NULL); @@ -1301,7 +1176,7 @@ static int __init s3c2410_init_dma(void) for (channel = 0; channel < S3C2410_DMA_CHANNELS; channel++) { cp = &s3c2410_chans[channel]; - memset(cp, 0, sizeof(struct s3c2410_dma_chan)); + memset(cp, 0, sizeof(s3c2410_dma_chan_t)); /* dma channel irqs are in order.. */ cp->number = channel; diff --git a/trunk/arch/arm/mach-sa1100/ssp.c b/trunk/arch/arm/mach-sa1100/ssp.c index 5eba5fbbb561..1604dadf27fc 100644 --- a/trunk/arch/arm/mach-sa1100/ssp.c +++ b/trunk/arch/arm/mach-sa1100/ssp.c @@ -23,8 +23,6 @@ #include #include -#define TIMEOUT 100000 - static irqreturn_t ssp_interrupt(int irq, void *dev_id, struct pt_regs *regs) { unsigned int status = Ser4SSSR; @@ -49,27 +47,18 @@ static irqreturn_t ssp_interrupt(int irq, void *dev_id, struct pt_regs *regs) * The caller is expected to perform the necessary locking. * * Returns: - * %-ETIMEDOUT timeout occurred + * %-ETIMEDOUT timeout occurred (for future) * 0 success */ int ssp_write_word(u16 data) { - int timeout = TIMEOUT; - - while (!(Ser4SSSR & SSSR_TNF)) { - if (!--timeout) - return -ETIMEDOUT; + while (!(Ser4SSSR & SSSR_TNF)) cpu_relax(); - } Ser4SSDR = data; - timeout = TIMEOUT; - while (!(Ser4SSSR & SSSR_BSY)) { - if (!--timeout) - return -ETIMEDOUT; + while (!(Ser4SSSR & SSSR_BSY)) cpu_relax(); - } return 0; } @@ -86,22 +75,15 @@ int ssp_write_word(u16 data) * The caller is expected to perform the necessary locking. * * Returns: - * %-ETIMEDOUT timeout occurred + * %-ETIMEDOUT timeout occurred (for future) * 16-bit data success */ -int ssp_read_word(u16 *data) +int ssp_read_word(void) { - int timeout = TIMEOUT; - - while (!(Ser4SSSR & SSSR_RNE)) { - if (!--timeout) - return -ETIMEDOUT; + while (!(Ser4SSSR & SSSR_RNE)) cpu_relax(); - } - - *data = (u16)Ser4SSDR; - return 0; + return Ser4SSDR; } /** @@ -111,26 +93,14 @@ int ssp_read_word(u16 *data) * is empty. * * The caller is expected to perform the necessary locking. - * - * Returns: - * %-ETIMEDOUT timeout occurred - * 0 success */ -int ssp_flush(void) +void ssp_flush(void) { - int timeout = TIMEOUT * 2; - do { while (Ser4SSSR & SSSR_RNE) { - if (!--timeout) - return -ETIMEDOUT; (void) Ser4SSDR; } - if (!--timeout) - return -ETIMEDOUT; } while (Ser4SSSR & SSSR_BSY); - - return 0; } /** diff --git a/trunk/arch/arm/mach-versatile/core.c b/trunk/arch/arm/mach-versatile/core.c index f2bbef07b1e4..c4e3f8c68479 100644 --- a/trunk/arch/arm/mach-versatile/core.c +++ b/trunk/arch/arm/mach-versatile/core.c @@ -285,7 +285,7 @@ static struct flash_platform_data versatile_flash_data = { static struct resource versatile_flash_resource = { .start = VERSATILE_FLASH_BASE, - .end = VERSATILE_FLASH_BASE + VERSATILE_FLASH_SIZE - 1, + .end = VERSATILE_FLASH_BASE + VERSATILE_FLASH_SIZE, .flags = IORESOURCE_MEM, }; diff --git a/trunk/arch/arm/mm/Kconfig b/trunk/arch/arm/mm/Kconfig index b4f220dd5eb8..5f80f184cd32 100644 --- a/trunk/arch/arm/mm/Kconfig +++ b/trunk/arch/arm/mm/Kconfig @@ -46,7 +46,7 @@ config CPU_ARM710 config CPU_ARM720T bool "Support ARM720T processor" if !ARCH_CLPS711X && !ARCH_L7200 && !ARCH_CDB89712 && ARCH_INTEGRATOR default y if ARCH_CLPS711X || ARCH_L7200 || ARCH_CDB89712 || ARCH_H720X - select CPU_32v4T + select CPU_32v4 select CPU_ABRT_LV4T select CPU_CACHE_V4 select CPU_CACHE_VIVT @@ -64,7 +64,7 @@ config CPU_ARM920T bool "Support ARM920T processor" depends on ARCH_EP93XX || ARCH_INTEGRATOR || CPU_S3C2410 || CPU_S3C2440 || CPU_S3C2442 || ARCH_IMX || ARCH_AAEC2000 || ARCH_AT91RM9200 default y if CPU_S3C2410 || CPU_S3C2440 || CPU_S3C2442 || ARCH_AT91RM9200 - select CPU_32v4T + select CPU_32v4 select CPU_ABRT_EV4T select CPU_CACHE_V4WT select CPU_CACHE_VIVT @@ -85,7 +85,7 @@ config CPU_ARM922T bool "Support ARM922T processor" if ARCH_INTEGRATOR depends on ARCH_LH7A40X || ARCH_INTEGRATOR default y if ARCH_LH7A40X - select CPU_32v4T + select CPU_32v4 select CPU_ABRT_EV4T select CPU_CACHE_V4WT select CPU_CACHE_VIVT @@ -104,7 +104,7 @@ config CPU_ARM925T bool "Support ARM925T processor" if ARCH_OMAP1 depends on ARCH_OMAP15XX default y if ARCH_OMAP15XX - select CPU_32v4T + select CPU_32v4 select CPU_ABRT_EV4T select CPU_CACHE_V4WT select CPU_CACHE_VIVT @@ -285,11 +285,6 @@ config CPU_32v4 select TLS_REG_EMUL if SMP || !MMU select NEEDS_SYSCALL_FOR_CMPXCHG if SMP -config CPU_32v4T - bool - select TLS_REG_EMUL if SMP || !MMU - select NEEDS_SYSCALL_FOR_CMPXCHG if SMP - config CPU_32v5 bool select TLS_REG_EMUL if SMP || !MMU diff --git a/trunk/arch/arm/mm/flush.c b/trunk/arch/arm/mm/flush.c index d438ce41cdd5..b103e56806bd 100644 --- a/trunk/arch/arm/mm/flush.c +++ b/trunk/arch/arm/mm/flush.c @@ -87,32 +87,6 @@ void flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr, unsig if (cache_is_vipt_aliasing()) flush_pfn_alias(pfn, user_addr); } - -void flush_ptrace_access(struct vm_area_struct *vma, struct page *page, - unsigned long uaddr, void *kaddr, - unsigned long len, int write) -{ - if (cache_is_vivt()) { - if (cpu_isset(smp_processor_id(), vma->vm_mm->cpu_vm_mask)) { - unsigned long addr = (unsigned long)kaddr; - __cpuc_coherent_kern_range(addr, addr + len); - } - return; - } - - if (cache_is_vipt_aliasing()) { - flush_pfn_alias(page_to_pfn(page), uaddr); - return; - } - - /* VIPT non-aliasing cache */ - if (cpu_isset(smp_processor_id(), vma->vm_mm->cpu_vm_mask) && - vma->vm_flags | VM_EXEC) { - unsigned long addr = (unsigned long)kaddr; - /* only flushing the kernel mapping on non-aliasing VIPT */ - __cpuc_coherent_kern_range(addr, addr + len); - } -} #else #define flush_pfn_alias(pfn,vaddr) do { } while (0) #endif diff --git a/trunk/arch/arm/vfp/vfp.h b/trunk/arch/arm/vfp/vfp.h index 96fdf30f6a3b..4b97950984e9 100644 --- a/trunk/arch/arm/vfp/vfp.h +++ b/trunk/arch/arm/vfp/vfp.h @@ -156,7 +156,7 @@ struct vfp_single { }; extern s32 vfp_get_float(unsigned int reg); -extern void vfp_put_float(s32 val, unsigned int reg); +extern void vfp_put_float(unsigned int reg, s32 val); /* * VFP_SINGLE_MANTISSA_BITS - number of bits in the mantissa @@ -267,7 +267,7 @@ struct vfp_double { */ #define VFP_REG_ZERO 16 extern u64 vfp_get_double(unsigned int reg); -extern void vfp_put_double(u64 val, unsigned int reg); +extern void vfp_put_double(unsigned int reg, u64 val); #define VFP_DOUBLE_MANTISSA_BITS (52) #define VFP_DOUBLE_EXPONENT_BITS (11) @@ -341,17 +341,15 @@ static inline int vfp_double_type(struct vfp_double *s) u32 vfp_double_normaliseround(int dd, struct vfp_double *vd, u32 fpscr, u32 exceptions, const char *func); +/* + * System registers + */ +extern u32 vfp_get_sys(unsigned int reg); +extern void vfp_put_sys(unsigned int reg, u32 val); + u32 vfp_estimate_sqrt_significand(u32 exponent, u32 significand); /* * A special flag to tell the normalisation code not to normalise. */ #define VFP_NAN_FLAG 0x100 - -/* - * A bit pattern used to indicate the initial (unset) value of the - * exception mask, in case nothing handles an instruction. This - * doesn't include the NAN flag, which get masked out before - * we check for an error. - */ -#define VFP_EXCEPTION_ERROR ((u32)-1 & ~VFP_NAN_FLAG) diff --git a/trunk/arch/arm/vfp/vfpdouble.c b/trunk/arch/arm/vfp/vfpdouble.c index add48e36c2dc..009038c8113e 100644 --- a/trunk/arch/arm/vfp/vfpdouble.c +++ b/trunk/arch/arm/vfp/vfpdouble.c @@ -195,7 +195,7 @@ u32 vfp_double_normaliseround(int dd, struct vfp_double *vd, u32 fpscr, u32 exce s64 d = vfp_double_pack(vd); pr_debug("VFP: %s: d(d%d)=%016llx exceptions=%08x\n", func, dd, d, exceptions); - vfp_put_double(d, dd); + vfp_put_double(dd, d); } return exceptions; } @@ -250,19 +250,19 @@ vfp_propagate_nan(struct vfp_double *vdd, struct vfp_double *vdn, */ static u32 vfp_double_fabs(int dd, int unused, int dm, u32 fpscr) { - vfp_put_double(vfp_double_packed_abs(vfp_get_double(dm)), dd); + vfp_put_double(dd, vfp_double_packed_abs(vfp_get_double(dm))); return 0; } static u32 vfp_double_fcpy(int dd, int unused, int dm, u32 fpscr) { - vfp_put_double(vfp_get_double(dm), dd); + vfp_put_double(dd, vfp_get_double(dm)); return 0; } static u32 vfp_double_fneg(int dd, int unused, int dm, u32 fpscr) { - vfp_put_double(vfp_double_packed_negate(vfp_get_double(dm)), dd); + vfp_put_double(dd, vfp_double_packed_negate(vfp_get_double(dm))); return 0; } @@ -287,7 +287,7 @@ static u32 vfp_double_fsqrt(int dd, int unused, int dm, u32 fpscr) vdp = &vfp_double_default_qnan; ret = FPSCR_IOC; } - vfp_put_double(vfp_double_pack(vdp), dd); + vfp_put_double(dd, vfp_double_pack(vdp)); return ret; } @@ -465,7 +465,7 @@ static u32 vfp_double_fcvts(int sd, int unused, int dm, u32 fpscr) */ if (tm & (VFP_INFINITY|VFP_NAN)) { vsd.exponent = 255; - if (tm == VFP_QNAN) + if (tm & VFP_NAN) vsd.significand |= VFP_SINGLE_SIGNIFICAND_QNAN; goto pack_nan; } else if (tm & VFP_ZERO) @@ -476,7 +476,7 @@ static u32 vfp_double_fcvts(int sd, int unused, int dm, u32 fpscr) return vfp_single_normaliseround(sd, &vsd, fpscr, exceptions, "fcvts"); pack_nan: - vfp_put_float(vfp_single_pack(&vsd), sd); + vfp_put_float(sd, vfp_single_pack(&vsd)); return exceptions; } @@ -573,7 +573,7 @@ static u32 vfp_double_ftoui(int sd, int unused, int dm, u32 fpscr) pr_debug("VFP: ftoui: d(s%d)=%08x exceptions=%08x\n", sd, d, exceptions); - vfp_put_float(d, sd); + vfp_put_float(sd, d); return exceptions; } @@ -648,7 +648,7 @@ static u32 vfp_double_ftosi(int sd, int unused, int dm, u32 fpscr) pr_debug("VFP: ftosi: d(s%d)=%08x exceptions=%08x\n", sd, d, exceptions); - vfp_put_float((s32)d, sd); + vfp_put_float(sd, (s32)d); return exceptions; } @@ -1084,7 +1084,7 @@ static u32 vfp_double_fdiv(int dd, int dn, int dm, u32 fpscr) vdn_nan: exceptions = vfp_propagate_nan(&vdd, &vdn, &vdm, fpscr); pack: - vfp_put_double(vfp_double_pack(&vdd), dd); + vfp_put_double(dd, vfp_double_pack(&vdd)); return exceptions; vdm_nan: @@ -1104,7 +1104,7 @@ static u32 vfp_double_fdiv(int dd, int dn, int dm, u32 fpscr) goto pack; invalid: - vfp_put_double(vfp_double_pack(&vfp_double_default_qnan), dd); + vfp_put_double(dd, vfp_double_pack(&vfp_double_default_qnan)); return FPSCR_IOC; } @@ -1127,7 +1127,7 @@ u32 vfp_double_cpdo(u32 inst, u32 fpscr) { u32 op = inst & FOP_MASK; u32 exceptions = 0; - unsigned int dest; + unsigned int dd = vfp_get_dd(inst); unsigned int dn = vfp_get_dn(inst); unsigned int dm = vfp_get_dm(inst); unsigned int vecitr, veclen, vecstride; @@ -1136,21 +1136,11 @@ u32 vfp_double_cpdo(u32 inst, u32 fpscr) veclen = fpscr & FPSCR_LENGTH_MASK; vecstride = (1 + ((fpscr & FPSCR_STRIDE_MASK) == FPSCR_STRIDE_MASK)) * 2; - /* - * fcvtds takes an sN register number as destination, not dN. - * It also always operates on scalars. - */ - if ((inst & FEXT_MASK) == FEXT_FCVT) { - veclen = 0; - dest = vfp_get_sd(inst); - } else - dest = vfp_get_dd(inst); - /* * If destination bank is zero, vector length is always '1'. * ARM DDI0100F C5.1.3, C5.3.2. */ - if (FREG_BANK(dest) == 0) + if (FREG_BANK(dd) == 0) veclen = 0; pr_debug("VFP: vecstride=%u veclen=%u\n", vecstride, @@ -1163,20 +1153,16 @@ u32 vfp_double_cpdo(u32 inst, u32 fpscr) for (vecitr = 0; vecitr <= veclen; vecitr += 1 << FPSCR_LENGTH_BIT) { u32 except; - if (op == FOP_EXT && (inst & FEXT_MASK) == FEXT_FCVT) - pr_debug("VFP: itr%d (s%u) = op[%u] (d%u)\n", - vecitr >> FPSCR_LENGTH_BIT, - dest, dn, dm); - else if (op == FOP_EXT) + if (op == FOP_EXT) pr_debug("VFP: itr%d (d%u) = op[%u] (d%u)\n", vecitr >> FPSCR_LENGTH_BIT, - dest, dn, dm); + dd, dn, dm); else pr_debug("VFP: itr%d (d%u) = (d%u) op[%u] (d%u)\n", vecitr >> FPSCR_LENGTH_BIT, - dest, dn, FOP_TO_IDX(op), dm); + dd, dn, FOP_TO_IDX(op), dm); - except = fop(dest, dn, dm, fpscr); + except = fop(dd, dn, dm, fpscr); pr_debug("VFP: itr%d: exceptions=%08x\n", vecitr >> FPSCR_LENGTH_BIT, except); @@ -1194,7 +1180,7 @@ u32 vfp_double_cpdo(u32 inst, u32 fpscr) * we encounter an exception. We continue. */ - dest = FREG_BANK(dest) + ((FREG_IDX(dest) + vecstride) & 6); + dd = FREG_BANK(dd) + ((FREG_IDX(dd) + vecstride) & 6); dn = FREG_BANK(dn) + ((FREG_IDX(dn) + vecstride) & 6); if (FREG_BANK(dm) != 0) dm = FREG_BANK(dm) + ((FREG_IDX(dm) + vecstride) & 6); diff --git a/trunk/arch/arm/vfp/vfphw.S b/trunk/arch/arm/vfp/vfphw.S index e51e6679c402..eb683cd77163 100644 --- a/trunk/arch/arm/vfp/vfphw.S +++ b/trunk/arch/arm/vfp/vfphw.S @@ -178,12 +178,12 @@ vfp_get_float: .globl vfp_put_float vfp_put_float: - add pc, pc, r1, lsl #3 + add pc, pc, r0, lsl #3 mov r0, r0 .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 - mcr p10, 0, r0, c\dr, c0, 0 @ fmsr r0, s0 + mcr p10, 0, r1, c\dr, c0, 0 @ fmsr r0, s0 mov pc, lr - mcr p10, 0, r0, c\dr, c0, 4 @ fmsr r0, s1 + mcr p10, 0, r1, c\dr, c0, 4 @ fmsr r0, s1 mov pc, lr .endr @@ -203,9 +203,9 @@ vfp_get_double: .globl vfp_put_double vfp_put_double: - add pc, pc, r2, lsl #3 + add pc, pc, r0, lsl #3 mov r0, r0 .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 - fmdrr d\dr, r0, r1 + fmdrr d\dr, r1, r2 mov pc, lr .endr diff --git a/trunk/arch/arm/vfp/vfpmodule.c b/trunk/arch/arm/vfp/vfpmodule.c index 4178f6cc3d37..9d265d5e748c 100644 --- a/trunk/arch/arm/vfp/vfpmodule.c +++ b/trunk/arch/arm/vfp/vfpmodule.c @@ -131,7 +131,7 @@ static void vfp_raise_exceptions(u32 exceptions, u32 inst, u32 fpscr, struct pt_ pr_debug("VFP: raising exceptions %08x\n", exceptions); - if (exceptions == VFP_EXCEPTION_ERROR) { + if (exceptions == (u32)-1) { vfp_panic("unhandled bounce"); vfp_raise_sigfpe(0, regs); return; @@ -170,7 +170,7 @@ static void vfp_raise_exceptions(u32 exceptions, u32 inst, u32 fpscr, struct pt_ */ static u32 vfp_emulate_instruction(u32 inst, u32 fpscr, struct pt_regs *regs) { - u32 exceptions = VFP_EXCEPTION_ERROR; + u32 exceptions = (u32)-1; pr_debug("VFP: emulate: INST=0x%08x SCR=0x%08x\n", inst, fpscr); diff --git a/trunk/arch/arm/vfp/vfpsingle.c b/trunk/arch/arm/vfp/vfpsingle.c index 8f6c179cafbe..dae2c2f46052 100644 --- a/trunk/arch/arm/vfp/vfpsingle.c +++ b/trunk/arch/arm/vfp/vfpsingle.c @@ -200,7 +200,7 @@ u32 vfp_single_normaliseround(int sd, struct vfp_single *vs, u32 fpscr, u32 exce s32 d = vfp_single_pack(vs); pr_debug("VFP: %s: d(s%d)=%08x exceptions=%08x\n", func, sd, d, exceptions); - vfp_put_float(d, sd); + vfp_put_float(sd, d); } return exceptions; @@ -257,19 +257,19 @@ vfp_propagate_nan(struct vfp_single *vsd, struct vfp_single *vsn, */ static u32 vfp_single_fabs(int sd, int unused, s32 m, u32 fpscr) { - vfp_put_float(vfp_single_packed_abs(m), sd); + vfp_put_float(sd, vfp_single_packed_abs(m)); return 0; } static u32 vfp_single_fcpy(int sd, int unused, s32 m, u32 fpscr) { - vfp_put_float(m, sd); + vfp_put_float(sd, m); return 0; } static u32 vfp_single_fneg(int sd, int unused, s32 m, u32 fpscr) { - vfp_put_float(vfp_single_packed_negate(m), sd); + vfp_put_float(sd, vfp_single_packed_negate(m)); return 0; } @@ -333,7 +333,7 @@ static u32 vfp_single_fsqrt(int sd, int unused, s32 m, u32 fpscr) vsp = &vfp_single_default_qnan; ret = FPSCR_IOC; } - vfp_put_float(vfp_single_pack(vsp), sd); + vfp_put_float(sd, vfp_single_pack(vsp)); return ret; } @@ -506,7 +506,7 @@ static u32 vfp_single_fcvtd(int dd, int unused, s32 m, u32 fpscr) */ if (tm & (VFP_INFINITY|VFP_NAN)) { vdd.exponent = 2047; - if (tm == VFP_QNAN) + if (tm & VFP_NAN) vdd.significand |= VFP_DOUBLE_SIGNIFICAND_QNAN; goto pack_nan; } else if (tm & VFP_ZERO) @@ -514,10 +514,14 @@ static u32 vfp_single_fcvtd(int dd, int unused, s32 m, u32 fpscr) else vdd.exponent = vsm.exponent + (1023 - 127); + /* + * Technically, if bit 0 of dd is set, this is an invalid + * instruction. However, we ignore this for efficiency. + */ return vfp_double_normaliseround(dd, &vdd, fpscr, exceptions, "fcvtd"); pack_nan: - vfp_put_double(vfp_double_pack(&vdd), dd); + vfp_put_double(dd, vfp_double_pack(&vdd)); return exceptions; } @@ -613,7 +617,7 @@ static u32 vfp_single_ftoui(int sd, int unused, s32 m, u32 fpscr) pr_debug("VFP: ftoui: d(s%d)=%08x exceptions=%08x\n", sd, d, exceptions); - vfp_put_float(d, sd); + vfp_put_float(sd, d); return exceptions; } @@ -692,7 +696,7 @@ static u32 vfp_single_ftosi(int sd, int unused, s32 m, u32 fpscr) pr_debug("VFP: ftosi: d(s%d)=%08x exceptions=%08x\n", sd, d, exceptions); - vfp_put_float((s32)d, sd); + vfp_put_float(sd, (s32)d); return exceptions; } @@ -1127,7 +1131,7 @@ static u32 vfp_single_fdiv(int sd, int sn, s32 m, u32 fpscr) vsn_nan: exceptions = vfp_propagate_nan(&vsd, &vsn, &vsm, fpscr); pack: - vfp_put_float(vfp_single_pack(&vsd), sd); + vfp_put_float(sd, vfp_single_pack(&vsd)); return exceptions; vsm_nan: @@ -1147,7 +1151,7 @@ static u32 vfp_single_fdiv(int sd, int sn, s32 m, u32 fpscr) goto pack; invalid: - vfp_put_float(vfp_single_pack(&vfp_single_default_qnan), sd); + vfp_put_float(sd, vfp_single_pack(&vfp_single_default_qnan)); return FPSCR_IOC; } @@ -1170,7 +1174,7 @@ u32 vfp_single_cpdo(u32 inst, u32 fpscr) { u32 op = inst & FOP_MASK; u32 exceptions = 0; - unsigned int dest; + unsigned int sd = vfp_get_sd(inst); unsigned int sn = vfp_get_sn(inst); unsigned int sm = vfp_get_sm(inst); unsigned int vecitr, veclen, vecstride; @@ -1179,23 +1183,11 @@ u32 vfp_single_cpdo(u32 inst, u32 fpscr) veclen = fpscr & FPSCR_LENGTH_MASK; vecstride = 1 + ((fpscr & FPSCR_STRIDE_MASK) == FPSCR_STRIDE_MASK); - /* - * fcvtsd takes a dN register number as destination, not sN. - * Technically, if bit 0 of dd is set, this is an invalid - * instruction. However, we ignore this for efficiency. - * It also only operates on scalars. - */ - if ((inst & FEXT_MASK) == FEXT_FCVT) { - veclen = 0; - dest = vfp_get_dd(inst); - } else - dest = vfp_get_sd(inst); - /* * If destination bank is zero, vector length is always '1'. * ARM DDI0100F C5.1.3, C5.3.2. */ - if (FREG_BANK(dest) == 0) + if (FREG_BANK(sd) == 0) veclen = 0; pr_debug("VFP: vecstride=%u veclen=%u\n", vecstride, @@ -1209,18 +1201,15 @@ u32 vfp_single_cpdo(u32 inst, u32 fpscr) s32 m = vfp_get_float(sm); u32 except; - if (op == FOP_EXT && (inst & FEXT_MASK) == FEXT_FCVT) - pr_debug("VFP: itr%d (d%u) = op[%u] (s%u=%08x)\n", - vecitr >> FPSCR_LENGTH_BIT, dest, sn, sm, m); - else if (op == FOP_EXT) + if (op == FOP_EXT) pr_debug("VFP: itr%d (s%u) = op[%u] (s%u=%08x)\n", - vecitr >> FPSCR_LENGTH_BIT, dest, sn, sm, m); + vecitr >> FPSCR_LENGTH_BIT, sd, sn, sm, m); else pr_debug("VFP: itr%d (s%u) = (s%u) op[%u] (s%u=%08x)\n", - vecitr >> FPSCR_LENGTH_BIT, dest, sn, + vecitr >> FPSCR_LENGTH_BIT, sd, sn, FOP_TO_IDX(op), sm, m); - except = fop(dest, sn, m, fpscr); + except = fop(sd, sn, m, fpscr); pr_debug("VFP: itr%d: exceptions=%08x\n", vecitr >> FPSCR_LENGTH_BIT, except); @@ -1238,7 +1227,7 @@ u32 vfp_single_cpdo(u32 inst, u32 fpscr) * we encounter an exception. We continue. */ - dest = FREG_BANK(dest) + ((FREG_IDX(dest) + vecstride) & 7); + sd = FREG_BANK(sd) + ((FREG_IDX(sd) + vecstride) & 7); sn = FREG_BANK(sn) + ((FREG_IDX(sn) + vecstride) & 7); if (FREG_BANK(sm) != 0) sm = FREG_BANK(sm) + ((FREG_IDX(sm) + vecstride) & 7); diff --git a/trunk/arch/i386/Kconfig b/trunk/arch/i386/Kconfig index b2751eadbc56..f71fb4a029cb 100644 --- a/trunk/arch/i386/Kconfig +++ b/trunk/arch/i386/Kconfig @@ -142,7 +142,6 @@ config X86_SUMMIT In particular, it is needed for the x440. If you don't have one of these computers, you should say N here. - If you want to build a NUMA kernel, you must select ACPI. config X86_BIGSMP bool "Support for other sub-arch SMP systems with more than 8 CPUs" @@ -170,7 +169,6 @@ config X86_GENERICARCH help This option compiles in the Summit, bigsmp, ES7000, default subarchitectures. It is intended for a generic binary kernel. - If you want a NUMA kernel, select ACPI. We need SRAT for NUMA. config X86_ES7000 bool "Support for Unisys ES7000 IA32 series" @@ -544,7 +542,7 @@ config X86_PAE # Common NUMA Features config NUMA bool "Numa Memory Allocation and Scheduler Support" - depends on SMP && HIGHMEM64G && (X86_NUMAQ || (X86_SUMMIT || X86_GENERICARCH) && ACPI) + depends on SMP && HIGHMEM64G && (X86_NUMAQ || X86_GENERICARCH || (X86_SUMMIT && ACPI)) default n if X86_PC default y if (X86_NUMAQ || X86_SUMMIT) diff --git a/trunk/arch/i386/kernel/acpi/boot.c b/trunk/arch/i386/kernel/acpi/boot.c index ee003bc0e8b1..0db6387025ca 100644 --- a/trunk/arch/i386/kernel/acpi/boot.c +++ b/trunk/arch/i386/kernel/acpi/boot.c @@ -59,7 +59,7 @@ static inline int gsi_irq_sharing(int gsi) { return gsi; } #define BAD_MADT_ENTRY(entry, end) ( \ (!entry) || (unsigned long)entry + sizeof(*entry) > end || \ - ((acpi_table_entry_header *)entry)->length < sizeof(*entry)) + ((acpi_table_entry_header *)entry)->length != sizeof(*entry)) #define PREFIX "ACPI: " diff --git a/trunk/arch/i386/kernel/acpi/wakeup.S b/trunk/arch/i386/kernel/acpi/wakeup.S index b781b38131c0..9f408eee4e6f 100644 --- a/trunk/arch/i386/kernel/acpi/wakeup.S +++ b/trunk/arch/i386/kernel/acpi/wakeup.S @@ -292,10 +292,7 @@ ENTRY(do_suspend_lowlevel) pushl $3 call acpi_enter_sleep_state addl $4, %esp - -# In case of S3 failure, we'll emerge here. Jump -# to ret_point to recover - jmp ret_point + ret .p2align 4,,7 ret_point: call restore_registers diff --git a/trunk/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c b/trunk/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c index e6ea00edcb54..efb41e81351c 100644 --- a/trunk/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c +++ b/trunk/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c @@ -567,11 +567,16 @@ static struct cpufreq_driver acpi_cpufreq_driver = { static int __init acpi_cpufreq_init (void) { + int result = 0; + dprintk("acpi_cpufreq_init\n"); - acpi_cpufreq_early_init_acpi(); + result = acpi_cpufreq_early_init_acpi(); - return cpufreq_register_driver(&acpi_cpufreq_driver); + if (!result) + result = cpufreq_register_driver(&acpi_cpufreq_driver); + + return (result); } diff --git a/trunk/arch/i386/kernel/head.S b/trunk/arch/i386/kernel/head.S index a6b8bd89aa27..eb79aa2fa8bb 100644 --- a/trunk/arch/i386/kernel/head.S +++ b/trunk/arch/i386/kernel/head.S @@ -317,14 +317,20 @@ is386: movl $2,%ecx # set MP movl %eax,%gs lldt %ax cld # gcc2 wants the direction flag cleared at all times - pushl %eax # fake return address #ifdef CONFIG_SMP movb ready, %cl movb $1, ready - cmpb $0,%cl # the first CPU calls start_kernel - jne initialize_secondary # all other CPUs call initialize_secondary + cmpb $0,%cl + je 1f # the first CPU calls start_kernel + # all other CPUs call initialize_secondary + call initialize_secondary + jmp L6 +1: #endif /* CONFIG_SMP */ - jmp start_kernel + call start_kernel +L6: + jmp L6 # main should never return here, but + # just in case, we know what happens. /* * We depend on ET to be correct. This checks for 287/387. diff --git a/trunk/arch/i386/kernel/hpet.c b/trunk/arch/i386/kernel/hpet.c index 17647a530b2f..c6737c35815d 100644 --- a/trunk/arch/i386/kernel/hpet.c +++ b/trunk/arch/i386/kernel/hpet.c @@ -35,7 +35,7 @@ static int __init init_hpet_clocksource(void) void __iomem* hpet_base; u64 tmp; - if (!is_hpet_enabled()) + if (!hpet_address) return -ENODEV; /* calculate the hpet address: */ diff --git a/trunk/arch/i386/kernel/irq.c b/trunk/arch/i386/kernel/irq.c index 5fe547cd8f9f..6cb529f60dcc 100644 --- a/trunk/arch/i386/kernel/irq.c +++ b/trunk/arch/i386/kernel/irq.c @@ -82,6 +82,10 @@ fastcall unsigned int do_IRQ(struct pt_regs *regs) } #endif + if (!irq_desc[irq].handle_irq) { + __do_IRQ(irq, regs); + goto out_exit; + } #ifdef CONFIG_4KSTACKS curctx = (union irq_ctx *) current_thread_info(); @@ -121,6 +125,7 @@ fastcall unsigned int do_IRQ(struct pt_regs *regs) #endif __do_IRQ(irq, regs); +out_exit: irq_exit(); return 1; diff --git a/trunk/arch/i386/kernel/setup.c b/trunk/arch/i386/kernel/setup.c index 345ffb7d904d..f1682206d304 100644 --- a/trunk/arch/i386/kernel/setup.c +++ b/trunk/arch/i386/kernel/setup.c @@ -956,6 +956,38 @@ efi_memory_present_wrapper(unsigned long start, unsigned long end, void *arg) return 0; } + /* + * This function checks if the entire range is mapped with type. + * + * Note: this function only works correct if the e820 table is sorted and + * not-overlapping, which is the case + */ +int __init +e820_all_mapped(unsigned long s, unsigned long e, unsigned type) +{ + u64 start = s; + u64 end = e; + int i; + for (i = 0; i < e820.nr_map; i++) { + struct e820entry *ei = &e820.map[i]; + if (type && ei->type != type) + continue; + /* is the region (part) in overlap with the current region ?*/ + if (ei->addr >= end || ei->addr + ei->size <= start) + continue; + /* if the region is at the beginning of we move + * start to the end of the region since it's ok until there + */ + if (ei->addr <= start) + start = ei->addr + ei->size; + /* if start is now at or beyond end, we're done, full + * coverage */ + if (start >= end) + return 1; /* we're done */ + } + return 0; +} + /* * Find the highest page frame number we have available */ diff --git a/trunk/arch/i386/kernel/traps.c b/trunk/arch/i386/kernel/traps.c index 7e9edafffd8a..82e0fd02af1c 100644 --- a/trunk/arch/i386/kernel/traps.c +++ b/trunk/arch/i386/kernel/traps.c @@ -92,11 +92,7 @@ asmlinkage void spurious_interrupt_bug(void); asmlinkage void machine_check(void); static int kstack_depth_to_print = 24; -#ifdef CONFIG_STACK_UNWIND static int call_trace = 1; -#else -#define call_trace (-1) -#endif ATOMIC_NOTIFIER_HEAD(i386die_chain); int register_die_notifier(struct notifier_block *nb) @@ -191,21 +187,22 @@ static void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, if (unwind_init_blocked(&info, task) == 0) unw_ret = show_trace_unwind(&info, log_lvl); } - if (unw_ret > 0) { - if (call_trace == 1 && !arch_unw_user_mode(&info)) { - print_symbol("DWARF2 unwinder stuck at %s\n", - UNW_PC(&info)); - if (UNW_SP(&info) >= PAGE_OFFSET) { - printk("Leftover inexact backtrace:\n"); + if (unw_ret > 0 && !arch_unw_user_mode(&info)) { +#ifdef CONFIG_STACK_UNWIND + print_symbol("DWARF2 unwinder stuck at %s\n", + UNW_PC(&info)); + if (call_trace == 1) { + printk("Leftover inexact backtrace:\n"); + if (UNW_SP(&info)) stack = (void *)UNW_SP(&info); - } else - printk("Full inexact backtrace again:\n"); - } else if (call_trace >= 1) + } else if (call_trace > 1) return; else printk("Full inexact backtrace again:\n"); - } else +#else printk("Inexact backtrace:\n"); +#endif + } } if (task == current) { @@ -1244,7 +1241,6 @@ static int __init kstack_setup(char *s) } __setup("kstack=", kstack_setup); -#ifdef CONFIG_STACK_UNWIND static int __init call_trace_setup(char *s) { if (strcmp(s, "old") == 0) @@ -1258,4 +1254,3 @@ static int __init call_trace_setup(char *s) return 1; } __setup("call_trace=", call_trace_setup); -#endif diff --git a/trunk/arch/i386/pci/common.c b/trunk/arch/i386/pci/common.c index 1220dd828ce3..0a362e3aeac5 100644 --- a/trunk/arch/i386/pci/common.c +++ b/trunk/arch/i386/pci/common.c @@ -237,11 +237,6 @@ char * __devinit pcibios_setup(char *str) pci_probe &= ~PCI_PROBE_MMCONF; return NULL; } - /* override DMI blacklist */ - else if (!strcmp(str, "mmconf")) { - pci_probe |= PCI_PROBE_MMCONF_FORCE; - return NULL; - } #endif else if (!strcmp(str, "noacpi")) { acpi_noirq_set(); diff --git a/trunk/arch/i386/pci/init.c b/trunk/arch/i386/pci/init.c index 51087a9d9172..c7650a7e0b07 100644 --- a/trunk/arch/i386/pci/init.c +++ b/trunk/arch/i386/pci/init.c @@ -14,12 +14,8 @@ static __init int pci_access_init(void) #ifdef CONFIG_PCI_BIOS pci_pcbios_init(); #endif - /* - * don't check for raw_pci_ops here because we want pcbios as last - * fallback, yet it's needed to run first to set pcibios_last_bus - * in case legacy PCI probing is used. otherwise detecting peer busses - * fails. - */ + if (raw_pci_ops) + return 0; #ifdef CONFIG_PCI_DIRECT pci_direct_init(); #endif diff --git a/trunk/arch/i386/pci/mmconfig.c b/trunk/arch/i386/pci/mmconfig.c index ef5a2faa7d82..e545b0992c48 100644 --- a/trunk/arch/i386/pci/mmconfig.c +++ b/trunk/arch/i386/pci/mmconfig.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include "pci.h" @@ -179,7 +178,7 @@ static __init void unreachable_devices(void) pci_exp_set_dev_base(addr, k, PCI_DEVFN(i, 0)); if (addr == 0 || readl((u32 __iomem *)mmcfg_virt_addr) != val1) { - set_bit(i + 32*k, fallback_slots); + set_bit(i, fallback_slots); printk(KERN_NOTICE "PCI: No mmconfig possible on %x:%x\n", k, i); } @@ -188,31 +187,9 @@ static __init void unreachable_devices(void) } } -static int disable_mcfg(struct dmi_system_id *d) -{ - printk("PCI: %s detected. Disabling MCFG.\n", d->ident); - pci_probe &= ~PCI_PROBE_MMCONF; - return 0; -} - -static struct dmi_system_id __initdata dmi_bad_mcfg[] = { - /* Has broken MCFG table that makes the system hang when used */ - { - .callback = disable_mcfg, - .ident = "Intel D3C5105 SDV", - .matches = { - DMI_MATCH(DMI_BIOS_VENDOR, "Intel"), - DMI_MATCH(DMI_BOARD_NAME, "D26928"), - }, - }, - {} -}; - void __init pci_mmcfg_init(void) { - dmi_check_system(dmi_bad_mcfg); - - if ((pci_probe & (PCI_PROBE_MMCONF_FORCE|PCI_PROBE_MMCONF)) == 0) + if ((pci_probe & PCI_PROBE_MMCONF) == 0) return; acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg); @@ -221,6 +198,15 @@ void __init pci_mmcfg_init(void) (pci_mmcfg_config[0].base_address == 0)) return; + if (!e820_all_mapped(pci_mmcfg_config[0].base_address, + pci_mmcfg_config[0].base_address + MMCONFIG_APER_MIN, + E820_RESERVED)) { + printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %x is not E820-reserved\n", + pci_mmcfg_config[0].base_address); + printk(KERN_ERR "PCI: Not using MMCONFIG.\n"); + return; + } + printk(KERN_INFO "PCI: Using MMCONFIG\n"); raw_pci_ops = &pci_mmcfg; pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF; diff --git a/trunk/arch/i386/pci/pci.h b/trunk/arch/i386/pci/pci.h index 49a849b3a241..bf4e79335388 100644 --- a/trunk/arch/i386/pci/pci.h +++ b/trunk/arch/i386/pci/pci.h @@ -16,8 +16,7 @@ #define PCI_PROBE_CONF1 0x0002 #define PCI_PROBE_CONF2 0x0004 #define PCI_PROBE_MMCONF 0x0008 -#define PCI_PROBE_MMCONF_FORCE 0x0010 -#define PCI_PROBE_MASK 0x00ff +#define PCI_PROBE_MASK 0x000f #define PCI_NO_SORT 0x0100 #define PCI_BIOS_SORT 0x0200 diff --git a/trunk/arch/ia64/Kconfig b/trunk/arch/ia64/Kconfig index 674de8943478..47de9ee6bcd6 100644 --- a/trunk/arch/ia64/Kconfig +++ b/trunk/arch/ia64/Kconfig @@ -258,7 +258,7 @@ config NR_CPUS int "Maximum number of CPUs (2-1024)" range 2 1024 depends on SMP - default "1024" + default "64" help You should set this to the number of CPUs in your system, but keep in mind that a kernel compiled for, e.g., 2 CPUs will boot but @@ -354,7 +354,7 @@ config NUMA config NODES_SHIFT int "Max num nodes shift(3-10)" range 3 10 - default "10" + default "8" depends on NEED_MULTIPLE_NODES help This option specifies the maximum number of nodes in your SSI system. diff --git a/trunk/arch/ia64/hp/sim/simscsi.c b/trunk/arch/ia64/hp/sim/simscsi.c index 8f0a16a79a67..8a4f0d0d17a3 100644 --- a/trunk/arch/ia64/hp/sim/simscsi.c +++ b/trunk/arch/ia64/hp/sim/simscsi.c @@ -244,8 +244,7 @@ static void simscsi_fillresult(struct scsi_cmnd *sc, char *buf, unsigned len) if (scatterlen == 0) memcpy(sc->request_buffer, buf, len); - else for (slp = (struct scatterlist *)sc->request_buffer; - scatterlen-- > 0 && len > 0; slp++) { + else for (slp = (struct scatterlist *)sc->request_buffer; scatterlen-- > 0 && len > 0; slp++) { unsigned thislen = min(len, slp->length); memcpy(page_address(slp->page) + slp->offset, buf, thislen); diff --git a/trunk/arch/ia64/kernel/acpi.c b/trunk/arch/ia64/kernel/acpi.c index 0176556aeecc..99761b81db44 100644 --- a/trunk/arch/ia64/kernel/acpi.c +++ b/trunk/arch/ia64/kernel/acpi.c @@ -55,7 +55,7 @@ #define BAD_MADT_ENTRY(entry, end) ( \ (!entry) || (unsigned long)entry + sizeof(*entry) > end || \ - ((acpi_table_entry_header *)entry)->length < sizeof(*entry)) + ((acpi_table_entry_header *)entry)->length != sizeof(*entry)) #define PREFIX "ACPI: " diff --git a/trunk/arch/ia64/kernel/topology.c b/trunk/arch/ia64/kernel/topology.c index f648c610b10c..d24fa393b182 100644 --- a/trunk/arch/ia64/kernel/topology.c +++ b/trunk/arch/ia64/kernel/topology.c @@ -67,8 +67,10 @@ static int __init topology_init(void) #endif sysfs_cpus = kzalloc(sizeof(struct ia64_cpu) * NR_CPUS, GFP_KERNEL); - if (!sysfs_cpus) - panic("kzalloc in topology_init failed - NR_CPUS too big?"); + if (!sysfs_cpus) { + err = -ENOMEM; + goto out; + } for_each_present_cpu(i) { if((err = arch_register_cpu(i))) diff --git a/trunk/arch/ia64/sn/kernel/xpc_channel.c b/trunk/arch/ia64/sn/kernel/xpc_channel.c index 1f3540826e68..c2f69f7942af 100644 --- a/trunk/arch/ia64/sn/kernel/xpc_channel.c +++ b/trunk/arch/ia64/sn/kernel/xpc_channel.c @@ -279,8 +279,8 @@ xpc_pull_remote_cachelines(struct xpc_partition *part, void *dst, return part->reason; } - bte_ret = xp_bte_copy((u64) src, (u64) dst, (u64) cnt, - (BTE_NORMAL | BTE_WACQUIRE), NULL); + bte_ret = xp_bte_copy((u64) src, (u64) ia64_tpa((u64) dst), + (u64) cnt, (BTE_NORMAL | BTE_WACQUIRE), NULL); if (bte_ret == BTE_SUCCESS) { return xpcSuccess; } diff --git a/trunk/arch/ia64/sn/kernel/xpc_main.c b/trunk/arch/ia64/sn/kernel/xpc_main.c index 4d026f9dd98b..5e8e59efb347 100644 --- a/trunk/arch/ia64/sn/kernel/xpc_main.c +++ b/trunk/arch/ia64/sn/kernel/xpc_main.c @@ -1052,8 +1052,6 @@ xpc_do_exit(enum xpc_retval reason) if (xpc_sysctl) { unregister_sysctl_table(xpc_sysctl); } - - kfree(xpc_remote_copy_buffer_base); } @@ -1214,20 +1212,24 @@ xpc_init(void) partid_t partid; struct xpc_partition *part; pid_t pid; - size_t buf_size; if (!ia64_platform_is("sn2")) { return -ENODEV; } - - buf_size = max(XPC_RP_VARS_SIZE, - XPC_RP_HEADER_SIZE + XP_NASID_MASK_BYTES); - xpc_remote_copy_buffer = xpc_kmalloc_cacheline_aligned(buf_size, - GFP_KERNEL, &xpc_remote_copy_buffer_base); - if (xpc_remote_copy_buffer == NULL) - return -ENOMEM; + /* + * xpc_remote_copy_buffer is used as a temporary buffer for bte_copy'ng + * various portions of a partition's reserved page. Its size is based + * on the size of the reserved page header and part_nasids mask. So we + * need to ensure that the other items will fit as well. + */ + if (XPC_RP_VARS_SIZE > XPC_RP_HEADER_SIZE + XP_NASID_MASK_BYTES) { + dev_err(xpc_part, "xpc_remote_copy_buffer is not big enough\n"); + return -EPERM; + } + DBUG_ON((u64) xpc_remote_copy_buffer != + L1_CACHE_ALIGN((u64) xpc_remote_copy_buffer)); snprintf(xpc_part->bus_id, BUS_ID_SIZE, "part"); snprintf(xpc_chan->bus_id, BUS_ID_SIZE, "chan"); @@ -1291,8 +1293,6 @@ xpc_init(void) if (xpc_sysctl) { unregister_sysctl_table(xpc_sysctl); } - - kfree(xpc_remote_copy_buffer_base); return -EBUSY; } @@ -1311,8 +1311,6 @@ xpc_init(void) if (xpc_sysctl) { unregister_sysctl_table(xpc_sysctl); } - - kfree(xpc_remote_copy_buffer_base); return -EBUSY; } @@ -1364,8 +1362,6 @@ xpc_init(void) if (xpc_sysctl) { unregister_sysctl_table(xpc_sysctl); } - - kfree(xpc_remote_copy_buffer_base); return -EBUSY; } diff --git a/trunk/arch/ia64/sn/kernel/xpc_partition.c b/trunk/arch/ia64/sn/kernel/xpc_partition.c index 57c723f5cba4..2a89cfce4954 100644 --- a/trunk/arch/ia64/sn/kernel/xpc_partition.c +++ b/trunk/arch/ia64/sn/kernel/xpc_partition.c @@ -71,15 +71,19 @@ struct xpc_partition xpc_partitions[XP_MAX_PARTITIONS + 1]; * Generic buffer used to store a local copy of portions of a remote * partition's reserved page (either its header and part_nasids mask, * or its vars). + * + * xpc_discovery runs only once and is a seperate thread that is + * very likely going to be processing in parallel with receiving + * interrupts. */ -char *xpc_remote_copy_buffer; -void *xpc_remote_copy_buffer_base; +char ____cacheline_aligned xpc_remote_copy_buffer[XPC_RP_HEADER_SIZE + + XP_NASID_MASK_BYTES]; /* * Guarantee that the kmalloc'd memory is cacheline aligned. */ -void * +static void * xpc_kmalloc_cacheline_aligned(size_t size, gfp_t flags, void **base) { /* see if kmalloc will give us cachline aligned memory by default */ @@ -144,7 +148,7 @@ xpc_get_rsvd_page_pa(int nasid) } } - bte_res = xp_bte_copy(rp_pa, buf, buf_len, + bte_res = xp_bte_copy(rp_pa, ia64_tpa(buf), buf_len, (BTE_NOTIFY | BTE_WACQUIRE), NULL); if (bte_res != BTE_SUCCESS) { dev_dbg(xpc_part, "xp_bte_copy failed %i\n", bte_res); @@ -443,7 +447,7 @@ xpc_check_remote_hb(void) /* pull the remote_hb cache line */ bres = xp_bte_copy(part->remote_vars_pa, - (u64) remote_vars, + ia64_tpa((u64) remote_vars), XPC_RP_VARS_SIZE, (BTE_NOTIFY | BTE_WACQUIRE), NULL); if (bres != BTE_SUCCESS) { @@ -494,7 +498,8 @@ xpc_get_remote_rp(int nasid, u64 *discovered_nasids, /* pull over the reserved page header and part_nasids mask */ - bres = xp_bte_copy(*remote_rp_pa, (u64) remote_rp, + + bres = xp_bte_copy(*remote_rp_pa, ia64_tpa((u64) remote_rp), XPC_RP_HEADER_SIZE + xp_nasid_mask_bytes, (BTE_NOTIFY | BTE_WACQUIRE), NULL); if (bres != BTE_SUCCESS) { @@ -549,8 +554,11 @@ xpc_get_remote_vars(u64 remote_vars_pa, struct xpc_vars *remote_vars) return xpcVarsNotSet; } + /* pull over the cross partition variables */ - bres = xp_bte_copy(remote_vars_pa, (u64) remote_vars, XPC_RP_VARS_SIZE, + + bres = xp_bte_copy(remote_vars_pa, ia64_tpa((u64) remote_vars), + XPC_RP_VARS_SIZE, (BTE_NOTIFY | BTE_WACQUIRE), NULL); if (bres != BTE_SUCCESS) { return xpc_map_bte_errors(bres); @@ -1231,7 +1239,7 @@ xpc_initiate_partid_to_nasids(partid_t partid, void *nasid_mask) part_nasid_pa = (u64) XPC_RP_PART_NASIDS(part->remote_rp_pa); - bte_res = xp_bte_copy(part_nasid_pa, (u64) nasid_mask, + bte_res = xp_bte_copy(part_nasid_pa, ia64_tpa((u64) nasid_mask), xp_nasid_mask_bytes, (BTE_NOTIFY | BTE_WACQUIRE), NULL); return xpc_map_bte_errors(bte_res); diff --git a/trunk/arch/powerpc/Kconfig b/trunk/arch/powerpc/Kconfig index 4d4b6fb156e1..abb325eb8f75 100644 --- a/trunk/arch/powerpc/Kconfig +++ b/trunk/arch/powerpc/Kconfig @@ -354,7 +354,6 @@ endchoice config PPC_PSERIES depends on PPC_MULTIPLATFORM && PPC64 bool "IBM pSeries & new (POWER5-based) iSeries" - select MPIC select PPC_I8259 select PPC_RTAS select RTAS_ERROR_LOGGING @@ -364,7 +363,6 @@ config PPC_PSERIES config PPC_CHRP bool "Common Hardware Reference Platform (CHRP) based machines" depends on PPC_MULTIPLATFORM && PPC32 - select MPIC select PPC_I8259 select PPC_INDIRECT_PCI select PPC_RTAS @@ -375,7 +373,6 @@ config PPC_CHRP config PPC_PMAC bool "Apple PowerMac based machines" depends on PPC_MULTIPLATFORM - select MPIC select PPC_INDIRECT_PCI if PPC32 select PPC_MPC106 if PPC32 default y @@ -383,7 +380,6 @@ config PPC_PMAC config PPC_PMAC64 bool depends on PPC_PMAC && POWER4 - select MPIC select U3_DART select MPIC_BROKEN_U3 select GENERIC_TBSYNC @@ -393,7 +389,6 @@ config PPC_PMAC64 config PPC_PREP bool "PowerPC Reference Platform (PReP) based machines" depends on PPC_MULTIPLATFORM && PPC32 && BROKEN - select MPIC select PPC_I8259 select PPC_INDIRECT_PCI select PPC_UDBG_16550 @@ -402,7 +397,6 @@ config PPC_PREP config PPC_MAPLE depends on PPC_MULTIPLATFORM && PPC64 bool "Maple 970FX Evaluation Board" - select MPIC select U3_DART select MPIC_BROKEN_U3 select GENERIC_TBSYNC @@ -445,6 +439,12 @@ config U3_DART depends on PPC_MULTIPLATFORM && PPC64 default n +config MPIC + depends on PPC_PSERIES || PPC_PMAC || PPC_MAPLE || PPC_CHRP \ + || MPC7448HPC2 + bool + default y + config PPC_RTAS bool default n @@ -812,14 +812,6 @@ config GENERIC_ISA_DMA depends on PPC64 || POWER4 || 6xx && !CPM2 default y -config MPIC - bool - default n - -config MPIC_WEIRD - bool - default n - config PPC_I8259 bool default n diff --git a/trunk/arch/powerpc/boot/dts/mpc7448hpc2.dts b/trunk/arch/powerpc/boot/dts/mpc7448hpc2.dts deleted file mode 100644 index d7b985e6bd2f..000000000000 --- a/trunk/arch/powerpc/boot/dts/mpc7448hpc2.dts +++ /dev/null @@ -1,190 +0,0 @@ -/* - * MPC7448HPC2 (Taiga) board Device Tree Source - * - * Copyright 2006 Freescale Semiconductor Inc. - * 2006 Roy Zang . - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - - -/ { - model = "mpc7448hpc2"; - compatible = "mpc74xx"; - #address-cells = <1>; - #size-cells = <1>; - linux,phandle = <100>; - - cpus { - #cpus = <1>; - #address-cells = <1>; - #size-cells =<0>; - linux,phandle = <200>; - - PowerPC,7448@0 { - device_type = "cpu"; - reg = <0>; - d-cache-line-size = <20>; // 32 bytes - i-cache-line-size = <20>; // 32 bytes - d-cache-size = <8000>; // L1, 32K bytes - i-cache-size = <8000>; // L1, 32K bytes - timebase-frequency = <0>; // 33 MHz, from uboot - clock-frequency = <0>; // From U-Boot - bus-frequency = <0>; // From U-Boot - 32-bit; - linux,phandle = <201>; - linux,boot-cpu; - }; - }; - - memory { - device_type = "memory"; - linux,phandle = <300>; - reg = <00000000 20000000 // DDR2 512M at 0 - >; - }; - - tsi108@c0000000 { - #address-cells = <1>; - #size-cells = <1>; - #interrupt-cells = <2>; - device_type = "tsi-bridge"; - ranges = <00000000 c0000000 00010000>; - reg = ; - bus-frequency = <0>; - - i2c@7000 { - interrupt-parent = <7400>; - interrupts = ; - reg = <7000 400>; - device_type = "i2c"; - compatible = "tsi-i2c"; - }; - - mdio@6000 { - device_type = "mdio"; - compatible = "tsi-ethernet"; - - ethernet-phy@6000 { - linux,phandle = <6000>; - interrupt-parent = <7400>; - interrupts = <2 1>; - reg = <6000 50>; - phy-id = <8>; - device_type = "ethernet-phy"; - }; - - ethernet-phy@6400 { - linux,phandle = <6400>; - interrupt-parent = <7400>; - interrupts = <2 1>; - reg = <6000 50>; - phy-id = <9>; - device_type = "ethernet-phy"; - }; - - }; - - ethernet@6200 { - #size-cells = <0>; - device_type = "network"; - model = "TSI-ETH"; - compatible = "tsi-ethernet"; - reg = <6000 200>; - address = [ 00 06 D2 00 00 01 ]; - interrupts = <10 2>; - interrupt-parent = <7400>; - phy-handle = <6000>; - }; - - ethernet@6600 { - #address-cells = <1>; - #size-cells = <0>; - device_type = "network"; - model = "TSI-ETH"; - compatible = "tsi-ethernet"; - reg = <6400 200>; - address = [ 00 06 D2 00 00 02 ]; - interrupts = <11 2>; - interrupt-parent = <7400>; - phy-handle = <6400>; - }; - - serial@7808 { - device_type = "serial"; - compatible = "ns16550"; - reg = <7808 200>; - clock-frequency = <3f6b5a00>; - interrupts = ; - interrupt-parent = <7400>; - }; - - serial@7c08 { - device_type = "serial"; - compatible = "ns16550"; - reg = <7c08 200>; - clock-frequency = <3f6b5a00>; - interrupts = ; - interrupt-parent = <7400>; - }; - - pic@7400 { - linux,phandle = <7400>; - clock-frequency = <0>; - interrupt-controller; - #address-cells = <0>; - #interrupt-cells = <2>; - reg = <7400 400>; - built-in; - compatible = "chrp,open-pic"; - device_type = "open-pic"; - big-endian; - }; - pci@1000 { - compatible = "tsi10x"; - device_type = "pci"; - linux,phandle = <1000>; - #interrupt-cells = <1>; - #size-cells = <2>; - #address-cells = <3>; - reg = <1000 1000>; - bus-range = <0 0>; - ranges = <02000000 0 e0000000 e0000000 0 1A000000 - 01000000 0 00000000 fa000000 0 00010000>; - clock-frequency = <7f28154>; - interrupt-parent = <7400>; - interrupts = <17 2>; - interrupt-map-mask = ; - interrupt-map = < - - /* IDSEL 0x11 */ - 0800 0 0 1 7400 24 0 - 0800 0 0 2 7400 25 0 - 0800 0 0 3 7400 26 0 - 0800 0 0 4 7400 27 0 - - /* IDSEL 0x12 */ - 1000 0 0 1 7400 25 0 - 1000 0 0 2 7400 26 0 - 1000 0 0 3 7400 27 0 - 1000 0 0 4 7400 24 0 - - /* IDSEL 0x13 */ - 1800 0 0 1 7400 26 0 - 1800 0 0 2 7400 27 0 - 1800 0 0 3 7400 24 0 - 1800 0 0 4 7400 25 0 - - /* IDSEL 0x14 */ - 2000 0 0 1 7400 27 0 - 2000 0 0 2 7400 24 0 - 2000 0 0 3 7400 25 0 - 2000 0 0 4 7400 26 0 - >; - }; - }; - -}; diff --git a/trunk/arch/powerpc/boot/dts/mpc8349emds.dts b/trunk/arch/powerpc/boot/dts/mpc8349emds.dts deleted file mode 100644 index 12f5dbf3055f..000000000000 --- a/trunk/arch/powerpc/boot/dts/mpc8349emds.dts +++ /dev/null @@ -1,328 +0,0 @@ -/* - * MPC8349E MDS Device Tree Source - * - * Copyright 2005, 2006 Freescale Semiconductor Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -/ { - model = "MPC8349EMDS"; - compatible = "MPC834xMDS"; - #address-cells = <1>; - #size-cells = <1>; - - cpus { - #cpus = <1>; - #address-cells = <1>; - #size-cells = <0>; - - PowerPC,8349@0 { - device_type = "cpu"; - reg = <0>; - d-cache-line-size = <20>; // 32 bytes - i-cache-line-size = <20>; // 32 bytes - d-cache-size = <8000>; // L1, 32K - i-cache-size = <8000>; // L1, 32K - timebase-frequency = <0>; // from bootloader - bus-frequency = <0>; // from bootloader - clock-frequency = <0>; // from bootloader - 32-bit; - }; - }; - - memory { - device_type = "memory"; - reg = <00000000 10000000>; // 256MB at 0 - }; - - soc8349@e0000000 { - #address-cells = <1>; - #size-cells = <1>; - #interrupt-cells = <2>; - device_type = "soc"; - ranges = <0 e0000000 00100000>; - reg = ; - bus-frequency = <0>; - - wdt@200 { - device_type = "watchdog"; - compatible = "mpc83xx_wdt"; - reg = <200 100>; - }; - - i2c@3000 { - device_type = "i2c"; - compatible = "fsl-i2c"; - reg = <3000 100>; - interrupts = ; - interrupt-parent = <700>; - dfsrr; - }; - - i2c@3100 { - device_type = "i2c"; - compatible = "fsl-i2c"; - reg = <3100 100>; - interrupts = ; - interrupt-parent = <700>; - dfsrr; - }; - - spi@7000 { - device_type = "spi"; - compatible = "mpc83xx_spi"; - reg = <7000 1000>; - interrupts = <10 8>; - interrupt-parent = <700>; - mode = <0>; - }; - - /* phy type (ULPI or SERIAL) are only types supportted for MPH */ - /* port = 0 or 1 */ - usb@22000 { - device_type = "usb"; - compatible = "fsl-usb2-mph"; - reg = <22000 1000>; - #address-cells = <1>; - #size-cells = <0>; - interrupt-parent = <700>; - interrupts = <27 2>; - phy_type = "ulpi"; - port1; - }; - /* phy type (ULPI, UTMI, UTMI_WIDE, SERIAL) */ - usb@23000 { - device_type = "usb"; - compatible = "fsl-usb2-dr"; - reg = <23000 1000>; - #address-cells = <1>; - #size-cells = <0>; - interrupt-parent = <700>; - interrupts = <26 2>; - phy_type = "ulpi"; - }; - - mdio@24520 { - device_type = "mdio"; - compatible = "gianfar"; - reg = <24520 20>; - #address-cells = <1>; - #size-cells = <0>; - linux,phandle = <24520>; - ethernet-phy@0 { - linux,phandle = <2452000>; - interrupt-parent = <700>; - interrupts = <11 2>; - reg = <0>; - device_type = "ethernet-phy"; - }; - ethernet-phy@1 { - linux,phandle = <2452001>; - interrupt-parent = <700>; - interrupts = <12 2>; - reg = <1>; - device_type = "ethernet-phy"; - }; - }; - - ethernet@24000 { - device_type = "network"; - model = "TSEC"; - compatible = "gianfar"; - reg = <24000 1000>; - address = [ 00 00 00 00 00 00 ]; - local-mac-address = [ 00 00 00 00 00 00 ]; - interrupts = <20 8 21 8 22 8>; - interrupt-parent = <700>; - phy-handle = <2452000>; - }; - - ethernet@25000 { - #address-cells = <1>; - #size-cells = <0>; - device_type = "network"; - model = "TSEC"; - compatible = "gianfar"; - reg = <25000 1000>; - address = [ 00 00 00 00 00 00 ]; - local-mac-address = [ 00 00 00 00 00 00 ]; - interrupts = <23 8 24 8 25 8>; - interrupt-parent = <700>; - phy-handle = <2452001>; - }; - - serial@4500 { - device_type = "serial"; - compatible = "ns16550"; - reg = <4500 100>; - clock-frequency = <0>; - interrupts = <9 8>; - interrupt-parent = <700>; - }; - - serial@4600 { - device_type = "serial"; - compatible = "ns16550"; - reg = <4600 100>; - clock-frequency = <0>; - interrupts = ; - interrupt-parent = <700>; - }; - - pci@8500 { - interrupt-map-mask = ; - interrupt-map = < - - /* IDSEL 0x11 */ - 8800 0 0 1 700 14 8 - 8800 0 0 2 700 15 8 - 8800 0 0 3 700 16 8 - 8800 0 0 4 700 17 8 - - /* IDSEL 0x12 */ - 9000 0 0 1 700 16 8 - 9000 0 0 2 700 17 8 - 9000 0 0 3 700 14 8 - 9000 0 0 4 700 15 8 - - /* IDSEL 0x13 */ - 9800 0 0 1 700 17 8 - 9800 0 0 2 700 14 8 - 9800 0 0 3 700 15 8 - 9800 0 0 4 700 16 8 - - /* IDSEL 0x15 */ - a800 0 0 1 700 14 8 - a800 0 0 2 700 15 8 - a800 0 0 3 700 16 8 - a800 0 0 4 700 17 8 - - /* IDSEL 0x16 */ - b000 0 0 1 700 17 8 - b000 0 0 2 700 14 8 - b000 0 0 3 700 15 8 - b000 0 0 4 700 16 8 - - /* IDSEL 0x17 */ - b800 0 0 1 700 16 8 - b800 0 0 2 700 17 8 - b800 0 0 3 700 14 8 - b800 0 0 4 700 15 8 - - /* IDSEL 0x18 */ - b000 0 0 1 700 15 8 - b000 0 0 2 700 16 8 - b000 0 0 3 700 17 8 - b000 0 0 4 700 14 8>; - interrupt-parent = <700>; - interrupts = <42 8>; - bus-range = <0 0>; - ranges = <02000000 0 a0000000 a0000000 0 10000000 - 42000000 0 80000000 80000000 0 10000000 - 01000000 0 00000000 e2000000 0 00100000>; - clock-frequency = <3f940aa>; - #interrupt-cells = <1>; - #size-cells = <2>; - #address-cells = <3>; - reg = <8500 100>; - compatible = "83xx"; - device_type = "pci"; - }; - - pci@8600 { - interrupt-map-mask = ; - interrupt-map = < - - /* IDSEL 0x11 */ - 8800 0 0 1 700 14 8 - 8800 0 0 2 700 15 8 - 8800 0 0 3 700 16 8 - 8800 0 0 4 700 17 8 - - /* IDSEL 0x12 */ - 9000 0 0 1 700 16 8 - 9000 0 0 2 700 17 8 - 9000 0 0 3 700 14 8 - 9000 0 0 4 700 15 8 - - /* IDSEL 0x13 */ - 9800 0 0 1 700 17 8 - 9800 0 0 2 700 14 8 - 9800 0 0 3 700 15 8 - 9800 0 0 4 700 16 8 - - /* IDSEL 0x15 */ - a800 0 0 1 700 14 8 - a800 0 0 2 700 15 8 - a800 0 0 3 700 16 8 - a800 0 0 4 700 17 8 - - /* IDSEL 0x16 */ - b000 0 0 1 700 17 8 - b000 0 0 2 700 14 8 - b000 0 0 3 700 15 8 - b000 0 0 4 700 16 8 - - /* IDSEL 0x17 */ - b800 0 0 1 700 16 8 - b800 0 0 2 700 17 8 - b800 0 0 3 700 14 8 - b800 0 0 4 700 15 8 - - /* IDSEL 0x18 */ - b000 0 0 1 700 15 8 - b000 0 0 2 700 16 8 - b000 0 0 3 700 17 8 - b000 0 0 4 700 14 8>; - interrupt-parent = <700>; - interrupts = <42 8>; - bus-range = <0 0>; - ranges = <02000000 0 b0000000 b0000000 0 10000000 - 42000000 0 90000000 90000000 0 10000000 - 01000000 0 00000000 e2100000 0 00100000>; - clock-frequency = <3f940aa>; - #interrupt-cells = <1>; - #size-cells = <2>; - #address-cells = <3>; - reg = <8600 100>; - compatible = "83xx"; - device_type = "pci"; - }; - - /* May need to remove if on a part without crypto engine */ - crypto@30000 { - device_type = "crypto"; - model = "SEC2"; - compatible = "talitos"; - reg = <30000 10000>; - interrupts = ; - interrupt-parent = <700>; - num-channels = <4>; - channel-fifo-len = <18>; - exec-units-mask = <0000007e>; - /* desc mask is for rev2.0, - * we need runtime fixup for >2.0 */ - descriptor-types-mask = <01010ebf>; - }; - - /* IPIC - * interrupts cell = - * sense values match linux IORESOURCE_IRQ_* defines: - * sense == 8: Level, low assertion - * sense == 2: Edge, high-to-low change - */ - pic@700 { - linux,phandle = <700>; - interrupt-controller; - #address-cells = <0>; - #interrupt-cells = <2>; - reg = <700 100>; - built-in; - device_type = "ipic"; - }; - }; -}; diff --git a/trunk/arch/powerpc/boot/dts/mpc8540ads.dts b/trunk/arch/powerpc/boot/dts/mpc8540ads.dts deleted file mode 100644 index 5f41c1f7a5f3..000000000000 --- a/trunk/arch/powerpc/boot/dts/mpc8540ads.dts +++ /dev/null @@ -1,257 +0,0 @@ -/* - * MPC8540 ADS Device Tree Source - * - * Copyright 2006 Freescale Semiconductor Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - - -/ { - model = "MPC8540ADS"; - compatible = "MPC85xxADS"; - #address-cells = <1>; - #size-cells = <1>; - linux,phandle = <100>; - - cpus { - #cpus = <1>; - #address-cells = <1>; - #size-cells = <0>; - linux,phandle = <200>; - - PowerPC,8540@0 { - device_type = "cpu"; - reg = <0>; - d-cache-line-size = <20>; // 32 bytes - i-cache-line-size = <20>; // 32 bytes - d-cache-size = <8000>; // L1, 32K - i-cache-size = <8000>; // L1, 32K - timebase-frequency = <0>; // 33 MHz, from uboot - bus-frequency = <0>; // 166 MHz - clock-frequency = <0>; // 825 MHz, from uboot - 32-bit; - linux,phandle = <201>; - }; - }; - - memory { - device_type = "memory"; - linux,phandle = <300>; - reg = <00000000 08000000>; // 128M at 0x0 - }; - - soc8540@e0000000 { - #address-cells = <1>; - #size-cells = <1>; - #interrupt-cells = <2>; - device_type = "soc"; - ranges = <0 e0000000 00100000>; - reg = ; // CCSRBAR 1M - bus-frequency = <0>; - - i2c@3000 { - device_type = "i2c"; - compatible = "fsl-i2c"; - reg = <3000 100>; - interrupts = <1b 2>; - interrupt-parent = <40000>; - dfsrr; - }; - - mdio@24520 { - #address-cells = <1>; - #size-cells = <0>; - device_type = "mdio"; - compatible = "gianfar"; - reg = <24520 20>; - linux,phandle = <24520>; - ethernet-phy@0 { - linux,phandle = <2452000>; - interrupt-parent = <40000>; - interrupts = <35 1>; - reg = <0>; - device_type = "ethernet-phy"; - }; - ethernet-phy@1 { - linux,phandle = <2452001>; - interrupt-parent = <40000>; - interrupts = <35 1>; - reg = <1>; - device_type = "ethernet-phy"; - }; - ethernet-phy@3 { - linux,phandle = <2452003>; - interrupt-parent = <40000>; - interrupts = <37 1>; - reg = <3>; - device_type = "ethernet-phy"; - }; - }; - - ethernet@24000 { - #address-cells = <1>; - #size-cells = <0>; - device_type = "network"; - model = "TSEC"; - compatible = "gianfar"; - reg = <24000 1000>; - address = [ 00 E0 0C 00 73 00 ]; - local-mac-address = [ 00 E0 0C 00 73 00 ]; - interrupts = ; - interrupt-parent = <40000>; - phy-handle = <2452000>; - }; - - ethernet@25000 { - #address-cells = <1>; - #size-cells = <0>; - device_type = "network"; - model = "TSEC"; - compatible = "gianfar"; - reg = <25000 1000>; - address = [ 00 E0 0C 00 73 01 ]; - local-mac-address = [ 00 E0 0C 00 73 01 ]; - interrupts = <13 2 14 2 18 2>; - interrupt-parent = <40000>; - phy-handle = <2452001>; - }; - - ethernet@26000 { - #address-cells = <1>; - #size-cells = <0>; - device_type = "network"; - model = "FEC"; - compatible = "gianfar"; - reg = <26000 1000>; - address = [ 00 E0 0C 00 73 02 ]; - local-mac-address = [ 00 E0 0C 00 73 02 ]; - interrupts = <19 2>; - interrupt-parent = <40000>; - phy-handle = <2452003>; - }; - - serial@4500 { - device_type = "serial"; - compatible = "ns16550"; - reg = <4500 100>; // reg base, size - clock-frequency = <0>; // should we fill in in uboot? - interrupts = <1a 2>; - interrupt-parent = <40000>; - }; - - serial@4600 { - device_type = "serial"; - compatible = "ns16550"; - reg = <4600 100>; // reg base, size - clock-frequency = <0>; // should we fill in in uboot? - interrupts = <1a 2>; - interrupt-parent = <40000>; - }; - pci@8000 { - linux,phandle = <8000>; - interrupt-map-mask = ; - interrupt-map = < - - /* IDSEL 0x02 */ - 1000 0 0 1 40000 31 1 - 1000 0 0 2 40000 32 1 - 1000 0 0 3 40000 33 1 - 1000 0 0 4 40000 34 1 - - /* IDSEL 0x03 */ - 1800 0 0 1 40000 34 1 - 1800 0 0 2 40000 31 1 - 1800 0 0 3 40000 32 1 - 1800 0 0 4 40000 33 1 - - /* IDSEL 0x04 */ - 2000 0 0 1 40000 33 1 - 2000 0 0 2 40000 34 1 - 2000 0 0 3 40000 31 1 - 2000 0 0 4 40000 32 1 - - /* IDSEL 0x05 */ - 2800 0 0 1 40000 32 1 - 2800 0 0 2 40000 33 1 - 2800 0 0 3 40000 34 1 - 2800 0 0 4 40000 31 1 - - /* IDSEL 0x0c */ - 6000 0 0 1 40000 31 1 - 6000 0 0 2 40000 32 1 - 6000 0 0 3 40000 33 1 - 6000 0 0 4 40000 34 1 - - /* IDSEL 0x0d */ - 6800 0 0 1 40000 34 1 - 6800 0 0 2 40000 31 1 - 6800 0 0 3 40000 32 1 - 6800 0 0 4 40000 33 1 - - /* IDSEL 0x0e */ - 7000 0 0 1 40000 33 1 - 7000 0 0 2 40000 34 1 - 7000 0 0 3 40000 31 1 - 7000 0 0 4 40000 32 1 - - /* IDSEL 0x0f */ - 7800 0 0 1 40000 32 1 - 7800 0 0 2 40000 33 1 - 7800 0 0 3 40000 34 1 - 7800 0 0 4 40000 31 1 - - /* IDSEL 0x12 */ - 9000 0 0 1 40000 31 1 - 9000 0 0 2 40000 32 1 - 9000 0 0 3 40000 33 1 - 9000 0 0 4 40000 34 1 - - /* IDSEL 0x13 */ - 9800 0 0 1 40000 34 1 - 9800 0 0 2 40000 31 1 - 9800 0 0 3 40000 32 1 - 9800 0 0 4 40000 33 1 - - /* IDSEL 0x14 */ - a000 0 0 1 40000 33 1 - a000 0 0 2 40000 34 1 - a000 0 0 3 40000 31 1 - a000 0 0 4 40000 32 1 - - /* IDSEL 0x15 */ - a800 0 0 1 40000 32 1 - a800 0 0 2 40000 33 1 - a800 0 0 3 40000 34 1 - a800 0 0 4 40000 31 1>; - interrupt-parent = <40000>; - interrupts = <08 2>; - bus-range = <0 0>; - ranges = <02000000 0 80000000 80000000 0 20000000 - 01000000 0 00000000 e2000000 0 00100000>; - clock-frequency = <3f940aa>; - #interrupt-cells = <1>; - #size-cells = <2>; - #address-cells = <3>; - reg = <8000 1000>; - compatible = "85xx"; - device_type = "pci"; - }; - - pic@40000 { - linux,phandle = <40000>; - clock-frequency = <0>; - interrupt-controller; - #address-cells = <0>; - #interrupt-cells = <2>; - reg = <40000 40000>; - built-in; - compatible = "chrp,open-pic"; - device_type = "open-pic"; - big-endian; - }; - }; -}; diff --git a/trunk/arch/powerpc/boot/dts/mpc8541cds.dts b/trunk/arch/powerpc/boot/dts/mpc8541cds.dts deleted file mode 100644 index 7be0bc659e1c..000000000000 --- a/trunk/arch/powerpc/boot/dts/mpc8541cds.dts +++ /dev/null @@ -1,244 +0,0 @@ -/* - * MPC8541 CDS Device Tree Source - * - * Copyright 2006 Freescale Semiconductor Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - - -/ { - model = "MPC8541CDS"; - compatible = "MPC85xxCDS"; - #address-cells = <1>; - #size-cells = <1>; - linux,phandle = <100>; - - cpus { - #cpus = <1>; - #address-cells = <1>; - #size-cells = <0>; - linux,phandle = <200>; - - PowerPC,8541@0 { - device_type = "cpu"; - reg = <0>; - d-cache-line-size = <20>; // 32 bytes - i-cache-line-size = <20>; // 32 bytes - d-cache-size = <8000>; // L1, 32K - i-cache-size = <8000>; // L1, 32K - timebase-frequency = <0>; // 33 MHz, from uboot - bus-frequency = <0>; // 166 MHz - clock-frequency = <0>; // 825 MHz, from uboot - 32-bit; - linux,phandle = <201>; - }; - }; - - memory { - device_type = "memory"; - linux,phandle = <300>; - reg = <00000000 08000000>; // 128M at 0x0 - }; - - soc8541@e0000000 { - #address-cells = <1>; - #size-cells = <1>; - #interrupt-cells = <2>; - device_type = "soc"; - ranges = <0 e0000000 00100000>; - reg = ; // CCSRBAR 1M - bus-frequency = <0>; - - i2c@3000 { - device_type = "i2c"; - compatible = "fsl-i2c"; - reg = <3000 100>; - interrupts = <1b 2>; - interrupt-parent = <40000>; - dfsrr; - }; - - mdio@24520 { - #address-cells = <1>; - #size-cells = <0>; - device_type = "mdio"; - compatible = "gianfar"; - reg = <24520 20>; - linux,phandle = <24520>; - ethernet-phy@0 { - linux,phandle = <2452000>; - interrupt-parent = <40000>; - interrupts = <35 0>; - reg = <0>; - device_type = "ethernet-phy"; - }; - ethernet-phy@1 { - linux,phandle = <2452001>; - interrupt-parent = <40000>; - interrupts = <35 0>; - reg = <1>; - device_type = "ethernet-phy"; - }; - }; - - ethernet@24000 { - #address-cells = <1>; - #size-cells = <0>; - device_type = "network"; - model = "TSEC"; - compatible = "gianfar"; - reg = <24000 1000>; - local-mac-address = [ 00 E0 0C 00 73 00 ]; - interrupts = ; - interrupt-parent = <40000>; - phy-handle = <2452000>; - }; - - ethernet@25000 { - #address-cells = <1>; - #size-cells = <0>; - device_type = "network"; - model = "TSEC"; - compatible = "gianfar"; - reg = <25000 1000>; - local-mac-address = [ 00 E0 0C 00 73 01 ]; - interrupts = <13 2 14 2 18 2>; - interrupt-parent = <40000>; - phy-handle = <2452001>; - }; - - serial@4500 { - device_type = "serial"; - compatible = "ns16550"; - reg = <4500 100>; // reg base, size - clock-frequency = <0>; // should we fill in in uboot? - interrupts = <1a 2>; - interrupt-parent = <40000>; - }; - - serial@4600 { - device_type = "serial"; - compatible = "ns16550"; - reg = <4600 100>; // reg base, size - clock-frequency = <0>; // should we fill in in uboot? - interrupts = <1a 2>; - interrupt-parent = <40000>; - }; - - pci@8000 { - linux,phandle = <8000>; - interrupt-map-mask = <1f800 0 0 7>; - interrupt-map = < - - /* IDSEL 0x10 */ - 08000 0 0 1 40000 30 1 - 08000 0 0 2 40000 31 1 - 08000 0 0 3 40000 32 1 - 08000 0 0 4 40000 33 1 - - /* IDSEL 0x11 */ - 08800 0 0 1 40000 30 1 - 08800 0 0 2 40000 31 1 - 08800 0 0 3 40000 32 1 - 08800 0 0 4 40000 33 1 - - /* IDSEL 0x12 (Slot 1) */ - 09000 0 0 1 40000 30 1 - 09000 0 0 2 40000 31 1 - 09000 0 0 3 40000 32 1 - 09000 0 0 4 40000 33 1 - - /* IDSEL 0x13 (Slot 2) */ - 09800 0 0 1 40000 31 1 - 09800 0 0 2 40000 32 1 - 09800 0 0 3 40000 33 1 - 09800 0 0 4 40000 30 1 - - /* IDSEL 0x14 (Slot 3) */ - 0a000 0 0 1 40000 32 1 - 0a000 0 0 2 40000 33 1 - 0a000 0 0 3 40000 30 1 - 0a000 0 0 4 40000 31 1 - - /* IDSEL 0x15 (Slot 4) */ - 0a800 0 0 1 40000 33 1 - 0a800 0 0 2 40000 30 1 - 0a800 0 0 3 40000 31 1 - 0a800 0 0 4 40000 32 1 - - /* Bus 1 (Tundra Bridge) */ - /* IDSEL 0x12 (ISA bridge) */ - 19000 0 0 1 40000 30 1 - 19000 0 0 2 40000 31 1 - 19000 0 0 3 40000 32 1 - 19000 0 0 4 40000 33 1>; - interrupt-parent = <40000>; - interrupts = <08 2>; - bus-range = <0 0>; - ranges = <02000000 0 80000000 80000000 0 20000000 - 01000000 0 00000000 e2000000 0 00100000>; - clock-frequency = <3f940aa>; - #interrupt-cells = <1>; - #size-cells = <2>; - #address-cells = <3>; - reg = <8000 1000>; - compatible = "85xx"; - device_type = "pci"; - - i8259@19000 { - clock-frequency = <0>; - interrupt-controller; - device_type = "interrupt-controller"; - reg = <19000 0 0 0 1>; - #address-cells = <0>; - #interrupt-cells = <2>; - built-in; - compatible = "chrp,iic"; - big-endian; - interrupts = <1>; - interrupt-parent = <8000>; - }; - }; - - pci@9000 { - linux,phandle = <9000>; - interrupt-map-mask = ; - interrupt-map = < - - /* IDSEL 0x15 */ - a800 0 0 1 40000 3b 1 - a800 0 0 2 40000 3b 1 - a800 0 0 3 40000 3b 1 - a800 0 0 4 40000 3b 1>; - interrupt-parent = <40000>; - interrupts = <09 2>; - bus-range = <0 0>; - ranges = <02000000 0 a0000000 a0000000 0 20000000 - 01000000 0 00000000 e3000000 0 00100000>; - clock-frequency = <3f940aa>; - #interrupt-cells = <1>; - #size-cells = <2>; - #address-cells = <3>; - reg = <9000 1000>; - compatible = "85xx"; - device_type = "pci"; - }; - - pic@40000 { - linux,phandle = <40000>; - clock-frequency = <0>; - interrupt-controller; - #address-cells = <0>; - #interrupt-cells = <2>; - reg = <40000 40000>; - built-in; - compatible = "chrp,open-pic"; - device_type = "open-pic"; - big-endian; - }; - }; -}; diff --git a/trunk/arch/powerpc/boot/dts/mpc8548cds.dts b/trunk/arch/powerpc/boot/dts/mpc8548cds.dts deleted file mode 100644 index 893d7957c174..000000000000 --- a/trunk/arch/powerpc/boot/dts/mpc8548cds.dts +++ /dev/null @@ -1,287 +0,0 @@ -/* - * MPC8555 CDS Device Tree Source - * - * Copyright 2006 Freescale Semiconductor Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - - -/ { - model = "MPC8548CDS"; - compatible = "MPC85xxCDS"; - #address-cells = <1>; - #size-cells = <1>; - linux,phandle = <100>; - - cpus { - #cpus = <1>; - #address-cells = <1>; - #size-cells = <0>; - linux,phandle = <200>; - - PowerPC,8548@0 { - device_type = "cpu"; - reg = <0>; - d-cache-line-size = <20>; // 32 bytes - i-cache-line-size = <20>; // 32 bytes - d-cache-size = <8000>; // L1, 32K - i-cache-size = <8000>; // L1, 32K - timebase-frequency = <0>; // 33 MHz, from uboot - bus-frequency = <0>; // 166 MHz - clock-frequency = <0>; // 825 MHz, from uboot - 32-bit; - linux,phandle = <201>; - }; - }; - - memory { - device_type = "memory"; - linux,phandle = <300>; - reg = <00000000 08000000>; // 128M at 0x0 - }; - - soc8548@e0000000 { - #address-cells = <1>; - #size-cells = <1>; - #interrupt-cells = <2>; - device_type = "soc"; - ranges = <0 e0000000 00100000>; - reg = ; // CCSRBAR 1M - bus-frequency = <0>; - - i2c@3000 { - device_type = "i2c"; - compatible = "fsl-i2c"; - reg = <3000 100>; - interrupts = <1b 2>; - interrupt-parent = <40000>; - dfsrr; - }; - - mdio@24520 { - #address-cells = <1>; - #size-cells = <0>; - device_type = "mdio"; - compatible = "gianfar"; - reg = <24520 20>; - linux,phandle = <24520>; - ethernet-phy@0 { - linux,phandle = <2452000>; - interrupt-parent = <40000>; - interrupts = <35 0>; - reg = <0>; - device_type = "ethernet-phy"; - }; - ethernet-phy@1 { - linux,phandle = <2452001>; - interrupt-parent = <40000>; - interrupts = <35 0>; - reg = <1>; - device_type = "ethernet-phy"; - }; - - ethernet-phy@2 { - linux,phandle = <2452002>; - interrupt-parent = <40000>; - interrupts = <35 0>; - reg = <2>; - device_type = "ethernet-phy"; - }; - ethernet-phy@3 { - linux,phandle = <2452003>; - interrupt-parent = <40000>; - interrupts = <35 0>; - reg = <3>; - device_type = "ethernet-phy"; - }; - }; - - ethernet@24000 { - #address-cells = <1>; - #size-cells = <0>; - device_type = "network"; - model = "eTSEC"; - compatible = "gianfar"; - reg = <24000 1000>; - local-mac-address = [ 00 E0 0C 00 73 00 ]; - interrupts = ; - interrupt-parent = <40000>; - phy-handle = <2452000>; - }; - - ethernet@25000 { - #address-cells = <1>; - #size-cells = <0>; - device_type = "network"; - model = "eTSEC"; - compatible = "gianfar"; - reg = <25000 1000>; - local-mac-address = [ 00 E0 0C 00 73 01 ]; - interrupts = <13 2 14 2 18 2>; - interrupt-parent = <40000>; - phy-handle = <2452001>; - }; - - ethernet@26000 { - #address-cells = <1>; - #size-cells = <0>; - device_type = "network"; - model = "eTSEC"; - compatible = "gianfar"; - reg = <26000 1000>; - local-mac-address = [ 00 E0 0C 00 73 02 ]; - interrupts = ; - interrupt-parent = <40000>; - phy-handle = <2452001>; - }; - -/* eTSEC 4 is currently broken - ethernet@27000 { - #address-cells = <1>; - #size-cells = <0>; - device_type = "network"; - model = "eTSEC"; - compatible = "gianfar"; - reg = <27000 1000>; - local-mac-address = [ 00 E0 0C 00 73 03 ]; - interrupts = <15 2 16 2 17 2>; - interrupt-parent = <40000>; - phy-handle = <2452001>; - }; - */ - - serial@4500 { - device_type = "serial"; - compatible = "ns16550"; - reg = <4500 100>; // reg base, size - clock-frequency = <0>; // should we fill in in uboot? - interrupts = <1a 2>; - interrupt-parent = <40000>; - }; - - serial@4600 { - device_type = "serial"; - compatible = "ns16550"; - reg = <4600 100>; // reg base, size - clock-frequency = <0>; // should we fill in in uboot? - interrupts = <1a 2>; - interrupt-parent = <40000>; - }; - - pci@8000 { - linux,phandle = <8000>; - interrupt-map-mask = <1f800 0 0 7>; - interrupt-map = < - - /* IDSEL 0x10 */ - 08000 0 0 1 40000 30 1 - 08000 0 0 2 40000 31 1 - 08000 0 0 3 40000 32 1 - 08000 0 0 4 40000 33 1 - - /* IDSEL 0x11 */ - 08800 0 0 1 40000 30 1 - 08800 0 0 2 40000 31 1 - 08800 0 0 3 40000 32 1 - 08800 0 0 4 40000 33 1 - - /* IDSEL 0x12 (Slot 1) */ - 09000 0 0 1 40000 30 1 - 09000 0 0 2 40000 31 1 - 09000 0 0 3 40000 32 1 - 09000 0 0 4 40000 33 1 - - /* IDSEL 0x13 (Slot 2) */ - 09800 0 0 1 40000 31 1 - 09800 0 0 2 40000 32 1 - 09800 0 0 3 40000 33 1 - 09800 0 0 4 40000 30 1 - - /* IDSEL 0x14 (Slot 3) */ - 0a000 0 0 1 40000 32 1 - 0a000 0 0 2 40000 33 1 - 0a000 0 0 3 40000 30 1 - 0a000 0 0 4 40000 31 1 - - /* IDSEL 0x15 (Slot 4) */ - 0a800 0 0 1 40000 33 1 - 0a800 0 0 2 40000 30 1 - 0a800 0 0 3 40000 31 1 - 0a800 0 0 4 40000 32 1 - - /* Bus 1 (Tundra Bridge) */ - /* IDSEL 0x12 (ISA bridge) */ - 19000 0 0 1 40000 30 1 - 19000 0 0 2 40000 31 1 - 19000 0 0 3 40000 32 1 - 19000 0 0 4 40000 33 1>; - interrupt-parent = <40000>; - interrupts = <08 2>; - bus-range = <0 0>; - ranges = <02000000 0 80000000 80000000 0 20000000 - 01000000 0 00000000 e2000000 0 00100000>; - clock-frequency = <3f940aa>; - #interrupt-cells = <1>; - #size-cells = <2>; - #address-cells = <3>; - reg = <8000 1000>; - compatible = "85xx"; - device_type = "pci"; - - i8259@19000 { - clock-frequency = <0>; - interrupt-controller; - device_type = "interrupt-controller"; - reg = <19000 0 0 0 1>; - #address-cells = <0>; - #interrupt-cells = <2>; - built-in; - compatible = "chrp,iic"; - big-endian; - interrupts = <1>; - interrupt-parent = <8000>; - }; - }; - - pci@9000 { - linux,phandle = <9000>; - interrupt-map-mask = ; - interrupt-map = < - - /* IDSEL 0x15 */ - a800 0 0 1 40000 3b 1 - a800 0 0 2 40000 3b 1 - a800 0 0 3 40000 3b 1 - a800 0 0 4 40000 3b 1>; - interrupt-parent = <40000>; - interrupts = <09 2>; - bus-range = <0 0>; - ranges = <02000000 0 a0000000 a0000000 0 20000000 - 01000000 0 00000000 e3000000 0 00100000>; - clock-frequency = <3f940aa>; - #interrupt-cells = <1>; - #size-cells = <2>; - #address-cells = <3>; - reg = <9000 1000>; - compatible = "85xx"; - device_type = "pci"; - }; - - pic@40000 { - linux,phandle = <40000>; - clock-frequency = <0>; - interrupt-controller; - #address-cells = <0>; - #interrupt-cells = <2>; - reg = <40000 40000>; - built-in; - compatible = "chrp,open-pic"; - device_type = "open-pic"; - big-endian; - }; - }; -}; diff --git a/trunk/arch/powerpc/boot/dts/mpc8555cds.dts b/trunk/arch/powerpc/boot/dts/mpc8555cds.dts deleted file mode 100644 index 118f5a887651..000000000000 --- a/trunk/arch/powerpc/boot/dts/mpc8555cds.dts +++ /dev/null @@ -1,244 +0,0 @@ -/* - * MPC8555 CDS Device Tree Source - * - * Copyright 2006 Freescale Semiconductor Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - - -/ { - model = "MPC8555CDS"; - compatible = "MPC85xxCDS"; - #address-cells = <1>; - #size-cells = <1>; - linux,phandle = <100>; - - cpus { - #cpus = <1>; - #address-cells = <1>; - #size-cells = <0>; - linux,phandle = <200>; - - PowerPC,8555@0 { - device_type = "cpu"; - reg = <0>; - d-cache-line-size = <20>; // 32 bytes - i-cache-line-size = <20>; // 32 bytes - d-cache-size = <8000>; // L1, 32K - i-cache-size = <8000>; // L1, 32K - timebase-frequency = <0>; // 33 MHz, from uboot - bus-frequency = <0>; // 166 MHz - clock-frequency = <0>; // 825 MHz, from uboot - 32-bit; - linux,phandle = <201>; - }; - }; - - memory { - device_type = "memory"; - linux,phandle = <300>; - reg = <00000000 08000000>; // 128M at 0x0 - }; - - soc8555@e0000000 { - #address-cells = <1>; - #size-cells = <1>; - #interrupt-cells = <2>; - device_type = "soc"; - ranges = <0 e0000000 00100000>; - reg = ; // CCSRBAR 1M - bus-frequency = <0>; - - i2c@3000 { - device_type = "i2c"; - compatible = "fsl-i2c"; - reg = <3000 100>; - interrupts = <1b 2>; - interrupt-parent = <40000>; - dfsrr; - }; - - mdio@24520 { - #address-cells = <1>; - #size-cells = <0>; - device_type = "mdio"; - compatible = "gianfar"; - reg = <24520 20>; - linux,phandle = <24520>; - ethernet-phy@0 { - linux,phandle = <2452000>; - interrupt-parent = <40000>; - interrupts = <35 0>; - reg = <0>; - device_type = "ethernet-phy"; - }; - ethernet-phy@1 { - linux,phandle = <2452001>; - interrupt-parent = <40000>; - interrupts = <35 0>; - reg = <1>; - device_type = "ethernet-phy"; - }; - }; - - ethernet@24000 { - #address-cells = <1>; - #size-cells = <0>; - device_type = "network"; - model = "TSEC"; - compatible = "gianfar"; - reg = <24000 1000>; - local-mac-address = [ 00 E0 0C 00 73 00 ]; - interrupts = <0d 2 0e 2 12 2>; - interrupt-parent = <40000>; - phy-handle = <2452000>; - }; - - ethernet@25000 { - #address-cells = <1>; - #size-cells = <0>; - device_type = "network"; - model = "TSEC"; - compatible = "gianfar"; - reg = <25000 1000>; - local-mac-address = [ 00 E0 0C 00 73 01 ]; - interrupts = <13 2 14 2 18 2>; - interrupt-parent = <40000>; - phy-handle = <2452001>; - }; - - serial@4500 { - device_type = "serial"; - compatible = "ns16550"; - reg = <4500 100>; // reg base, size - clock-frequency = <0>; // should we fill in in uboot? - interrupts = <1a 2>; - interrupt-parent = <40000>; - }; - - serial@4600 { - device_type = "serial"; - compatible = "ns16550"; - reg = <4600 100>; // reg base, size - clock-frequency = <0>; // should we fill in in uboot? - interrupts = <1a 2>; - interrupt-parent = <40000>; - }; - - pci@8000 { - linux,phandle = <8000>; - interrupt-map-mask = <1f800 0 0 7>; - interrupt-map = < - - /* IDSEL 0x10 */ - 08000 0 0 1 40000 30 1 - 08000 0 0 2 40000 31 1 - 08000 0 0 3 40000 32 1 - 08000 0 0 4 40000 33 1 - - /* IDSEL 0x11 */ - 08800 0 0 1 40000 30 1 - 08800 0 0 2 40000 31 1 - 08800 0 0 3 40000 32 1 - 08800 0 0 4 40000 33 1 - - /* IDSEL 0x12 (Slot 1) */ - 09000 0 0 1 40000 30 1 - 09000 0 0 2 40000 31 1 - 09000 0 0 3 40000 32 1 - 09000 0 0 4 40000 33 1 - - /* IDSEL 0x13 (Slot 2) */ - 09800 0 0 1 40000 31 1 - 09800 0 0 2 40000 32 1 - 09800 0 0 3 40000 33 1 - 09800 0 0 4 40000 30 1 - - /* IDSEL 0x14 (Slot 3) */ - 0a000 0 0 1 40000 32 1 - 0a000 0 0 2 40000 33 1 - 0a000 0 0 3 40000 30 1 - 0a000 0 0 4 40000 31 1 - - /* IDSEL 0x15 (Slot 4) */ - 0a800 0 0 1 40000 33 1 - 0a800 0 0 2 40000 30 1 - 0a800 0 0 3 40000 31 1 - 0a800 0 0 4 40000 32 1 - - /* Bus 1 (Tundra Bridge) */ - /* IDSEL 0x12 (ISA bridge) */ - 19000 0 0 1 40000 30 1 - 19000 0 0 2 40000 31 1 - 19000 0 0 3 40000 32 1 - 19000 0 0 4 40000 33 1>; - interrupt-parent = <40000>; - interrupts = <08 2>; - bus-range = <0 0>; - ranges = <02000000 0 80000000 80000000 0 20000000 - 01000000 0 00000000 e2000000 0 00100000>; - clock-frequency = <3f940aa>; - #interrupt-cells = <1>; - #size-cells = <2>; - #address-cells = <3>; - reg = <8000 1000>; - compatible = "85xx"; - device_type = "pci"; - - i8259@19000 { - clock-frequency = <0>; - interrupt-controller; - device_type = "interrupt-controller"; - reg = <19000 0 0 0 1>; - #address-cells = <0>; - #interrupt-cells = <2>; - built-in; - compatible = "chrp,iic"; - big-endian; - interrupts = <1>; - interrupt-parent = <8000>; - }; - }; - - pci@9000 { - linux,phandle = <9000>; - interrupt-map-mask = ; - interrupt-map = < - - /* IDSEL 0x15 */ - a800 0 0 1 40000 3b 1 - a800 0 0 2 40000 3b 1 - a800 0 0 3 40000 3b 1 - a800 0 0 4 40000 3b 1>; - interrupt-parent = <40000>; - interrupts = <09 2>; - bus-range = <0 0>; - ranges = <02000000 0 a0000000 a0000000 0 20000000 - 01000000 0 00000000 e3000000 0 00100000>; - clock-frequency = <3f940aa>; - #interrupt-cells = <1>; - #size-cells = <2>; - #address-cells = <3>; - reg = <9000 1000>; - compatible = "85xx"; - device_type = "pci"; - }; - - pic@40000 { - linux,phandle = <40000>; - clock-frequency = <0>; - interrupt-controller; - #address-cells = <0>; - #interrupt-cells = <2>; - reg = <40000 40000>; - built-in; - compatible = "chrp,open-pic"; - device_type = "open-pic"; - big-endian; - }; - }; -}; diff --git a/trunk/arch/powerpc/configs/mpc834x_mds_defconfig b/trunk/arch/powerpc/configs/mpc834x_sys_defconfig similarity index 100% rename from trunk/arch/powerpc/configs/mpc834x_mds_defconfig rename to trunk/arch/powerpc/configs/mpc834x_sys_defconfig diff --git a/trunk/arch/powerpc/kernel/fpu.S b/trunk/arch/powerpc/kernel/fpu.S index 821e152e093c..7e2c9fe44ac1 100644 --- a/trunk/arch/powerpc/kernel/fpu.S +++ b/trunk/arch/powerpc/kernel/fpu.S @@ -2,11 +2,6 @@ * FPU support code, moved here from head.S so that it can be used * by chips which use other head-whatever.S files. * - * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) - * Copyright (C) 1996 Cort Dougan - * Copyright (C) 1996 Paul Mackerras. - * Copyright (C) 1997 Dan Malek (dmalek@jlc.net). - * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version diff --git a/trunk/arch/powerpc/kernel/irq.c b/trunk/arch/powerpc/kernel/irq.c index 12c5971d6565..7ee685433319 100644 --- a/trunk/arch/powerpc/kernel/irq.c +++ b/trunk/arch/powerpc/kernel/irq.c @@ -322,8 +322,7 @@ EXPORT_SYMBOL(do_softirq); static LIST_HEAD(irq_hosts); static spinlock_t irq_big_lock = SPIN_LOCK_UNLOCKED; -static DEFINE_PER_CPU(unsigned int, irq_radix_reader); -static unsigned int irq_radix_writer; + struct irq_map_entry irq_map[NR_IRQS]; static unsigned int irq_virq_count = NR_IRQS; static struct irq_host *irq_default_host; @@ -456,58 +455,6 @@ void irq_set_virq_count(unsigned int count) irq_virq_count = count; } -/* radix tree not lockless safe ! we use a brlock-type mecanism - * for now, until we can use a lockless radix tree - */ -static void irq_radix_wrlock(unsigned long *flags) -{ - unsigned int cpu, ok; - - spin_lock_irqsave(&irq_big_lock, *flags); - irq_radix_writer = 1; - smp_mb(); - do { - barrier(); - ok = 1; - for_each_possible_cpu(cpu) { - if (per_cpu(irq_radix_reader, cpu)) { - ok = 0; - break; - } - } - if (!ok) - cpu_relax(); - } while(!ok); -} - -static void irq_radix_wrunlock(unsigned long flags) -{ - smp_wmb(); - irq_radix_writer = 0; - spin_unlock_irqrestore(&irq_big_lock, flags); -} - -static void irq_radix_rdlock(unsigned long *flags) -{ - local_irq_save(*flags); - __get_cpu_var(irq_radix_reader) = 1; - smp_mb(); - if (likely(irq_radix_writer == 0)) - return; - __get_cpu_var(irq_radix_reader) = 0; - smp_wmb(); - spin_lock(&irq_big_lock); - __get_cpu_var(irq_radix_reader) = 1; - spin_unlock(&irq_big_lock); -} - -static void irq_radix_rdunlock(unsigned long flags) -{ - __get_cpu_var(irq_radix_reader) = 0; - local_irq_restore(flags); -} - - unsigned int irq_create_mapping(struct irq_host *host, irq_hw_number_t hwirq) { @@ -657,9 +604,13 @@ void irq_dispose_mapping(unsigned int virq) /* Check if radix tree allocated yet */ if (host->revmap_data.tree.gfp_mask == 0) break; - irq_radix_wrlock(&flags); + /* XXX radix tree not safe ! remove lock whem it becomes safe + * and use some RCU sync to make sure everything is ok before we + * can re-use that map entry + */ + spin_lock_irqsave(&irq_big_lock, flags); radix_tree_delete(&host->revmap_data.tree, hwirq); - irq_radix_wrunlock(flags); + spin_unlock_irqrestore(&irq_big_lock, flags); break; } @@ -726,24 +677,25 @@ unsigned int irq_radix_revmap(struct irq_host *host, if (tree->gfp_mask == 0) return irq_find_mapping(host, hwirq); + /* XXX Current radix trees are NOT SMP safe !!! Remove that lock + * when that is fixed (when Nick's patch gets in + */ + spin_lock_irqsave(&irq_big_lock, flags); + /* Now try to resolve */ - irq_radix_rdlock(&flags); ptr = radix_tree_lookup(tree, hwirq); - irq_radix_rdunlock(flags); - /* Found it, return */ if (ptr) { virq = ptr - irq_map; - return virq; + goto bail; } /* If not there, try to insert it */ virq = irq_find_mapping(host, hwirq); - if (virq != NO_IRQ) { - irq_radix_wrlock(&flags); + if (virq != NO_IRQ) radix_tree_insert(tree, hwirq, &irq_map[virq]); - irq_radix_wrunlock(flags); - } + bail: + spin_unlock_irqrestore(&irq_big_lock, flags); return virq; } @@ -854,12 +806,12 @@ static int irq_late_init(void) struct irq_host *h; unsigned long flags; - irq_radix_wrlock(&flags); + spin_lock_irqsave(&irq_big_lock, flags); list_for_each_entry(h, &irq_hosts, link) { if (h->revmap_type == IRQ_HOST_MAP_TREE) INIT_RADIX_TREE(&h->revmap_data.tree, GFP_ATOMIC); } - irq_radix_wrunlock(flags); + spin_unlock_irqrestore(&irq_big_lock, flags); return 0; } diff --git a/trunk/arch/powerpc/kernel/legacy_serial.c b/trunk/arch/powerpc/kernel/legacy_serial.c index 40a39291861f..359ab89748e0 100644 --- a/trunk/arch/powerpc/kernel/legacy_serial.c +++ b/trunk/arch/powerpc/kernel/legacy_serial.c @@ -115,7 +115,6 @@ static int __init add_legacy_soc_port(struct device_node *np, u64 addr; u32 *addrp; upf_t flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ; - struct device_node *tsi = of_get_parent(np); /* We only support ports that have a clock frequency properly * encoded in the device-tree. @@ -135,10 +134,7 @@ static int __init add_legacy_soc_port(struct device_node *np, /* Add port, irq will be dealt with later. We passed a translated * IO port value. It will be fixed up later along with the irq */ - if (tsi && !strcmp(tsi->type, "tsi-bridge")) - return add_legacy_port(np, -1, UPIO_TSI, addr, addr, NO_IRQ, flags, 0); - else - return add_legacy_port(np, -1, UPIO_MEM, addr, addr, NO_IRQ, flags, 0); + return add_legacy_port(np, -1, UPIO_MEM, addr, addr, NO_IRQ, flags, 0); } static int __init add_legacy_isa_port(struct device_node *np, @@ -468,7 +464,7 @@ static int __init serial_dev_init(void) fixup_port_irq(i, np, port); if (port->iotype == UPIO_PORT) fixup_port_pio(i, np, port); - if ((port->iotype == UPIO_MEM) || (port->iotype == UPIO_TSI)) + if (port->iotype == UPIO_MEM) fixup_port_mmio(i, np, port); } diff --git a/trunk/arch/powerpc/kernel/pci_64.c b/trunk/arch/powerpc/kernel/pci_64.c index 138134c8c17d..2fce7738e9e2 100644 --- a/trunk/arch/powerpc/kernel/pci_64.c +++ b/trunk/arch/powerpc/kernel/pci_64.c @@ -1289,9 +1289,6 @@ int pci_read_irq_line(struct pci_dev *pci_dev) DBG("Try to map irq for %s...\n", pci_name(pci_dev)); -#ifdef DEBUG - memset(&oirq, 0xff, sizeof(oirq)); -#endif /* Try to get a mapping from the device-tree */ if (of_irq_map_pci(pci_dev, &oirq)) { u8 line, pin; @@ -1317,9 +1314,8 @@ int pci_read_irq_line(struct pci_dev *pci_dev) if (virq != NO_IRQ) set_irq_type(virq, IRQ_TYPE_LEVEL_LOW); } else { - DBG(" -> got one, spec %d cells (0x%08x 0x%08x...) on %s\n", - oirq.size, oirq.specifier[0], oirq.specifier[1], - oirq.controller->full_name); + DBG(" -> got one, spec %d cells (0x%08x...) on %s\n", + oirq.size, oirq.specifier[0], oirq.controller->full_name); virq = irq_create_of_mapping(oirq.controller, oirq.specifier, oirq.size); @@ -1328,9 +1324,6 @@ int pci_read_irq_line(struct pci_dev *pci_dev) DBG(" -> failed to map !\n"); return -1; } - - DBG(" -> mapped to linux irq %d\n", virq); - pci_dev->irq = virq; pci_write_config_byte(pci_dev, PCI_INTERRUPT_LINE, virq); diff --git a/trunk/arch/powerpc/kernel/ppc_ksyms.c b/trunk/arch/powerpc/kernel/ppc_ksyms.c index 39d3bfcabcd2..f6a05f090b25 100644 --- a/trunk/arch/powerpc/kernel/ppc_ksyms.c +++ b/trunk/arch/powerpc/kernel/ppc_ksyms.c @@ -126,6 +126,10 @@ EXPORT_SYMBOL(pci_bus_mem_base_phys); EXPORT_SYMBOL(pci_bus_to_hose); #endif /* CONFIG_PCI */ +#ifdef CONFIG_NOT_COHERENT_CACHE +EXPORT_SYMBOL(flush_dcache_all); +#endif + EXPORT_SYMBOL(start_thread); EXPORT_SYMBOL(kernel_thread); diff --git a/trunk/arch/powerpc/kernel/prom_init.c b/trunk/arch/powerpc/kernel/prom_init.c index 4394e545f9f7..462bced40c12 100644 --- a/trunk/arch/powerpc/kernel/prom_init.c +++ b/trunk/arch/powerpc/kernel/prom_init.c @@ -646,13 +646,13 @@ static unsigned char ibm_architecture_vec[] = { 5 - 1, /* 5 option vectors */ /* option vector 1: processor architectures supported */ - 3 - 2, /* length */ + 3 - 1, /* length */ 0, /* don't ignore, don't halt */ OV1_PPC_2_00 | OV1_PPC_2_01 | OV1_PPC_2_02 | OV1_PPC_2_03 | OV1_PPC_2_04 | OV1_PPC_2_05, /* option vector 2: Open Firmware options supported */ - 34 - 2, /* length */ + 34 - 1, /* length */ OV2_REAL_MODE, 0, 0, W(0xffffffff), /* real_base */ @@ -666,16 +666,16 @@ static unsigned char ibm_architecture_vec[] = { 48, /* max log_2(hash table size) */ /* option vector 3: processor options supported */ - 3 - 2, /* length */ + 3 - 1, /* length */ 0, /* don't ignore, don't halt */ OV3_FP | OV3_VMX, /* option vector 4: IBM PAPR implementation */ - 2 - 2, /* length */ + 2 - 1, /* length */ 0, /* don't halt */ /* option vector 5: PAPR/OF options */ - 3 - 2, /* length */ + 3 - 1, /* length */ 0, /* don't ignore, don't halt */ OV5_LPAR | OV5_SPLPAR | OV5_LARGE_PAGES, }; diff --git a/trunk/arch/powerpc/kernel/prom_parse.c b/trunk/arch/powerpc/kernel/prom_parse.c index a10825a5dfe6..6a7e997c401d 100644 --- a/trunk/arch/powerpc/kernel/prom_parse.c +++ b/trunk/arch/powerpc/kernel/prom_parse.c @@ -598,6 +598,11 @@ static struct device_node *of_irq_find_parent(struct device_node *child) return p; } +static u8 of_irq_pci_swizzle(u8 slot, u8 pin) +{ + return (((pin - 1) + slot) % 4) + 1; +} + /* This doesn't need to be called if you don't have any special workaround * flags to pass */ @@ -639,17 +644,14 @@ void of_irq_map_init(unsigned int flags) } -int of_irq_map_raw(struct device_node *parent, u32 *intspec, u32 ointsize, - u32 *addr, struct of_irq *out_irq) +int of_irq_map_raw(struct device_node *parent, u32 *intspec, u32 *addr, + struct of_irq *out_irq) { struct device_node *ipar, *tnode, *old = NULL, *newpar = NULL; u32 *tmp, *imap, *imask; u32 intsize = 1, addrsize, newintsize = 0, newaddrsize = 0; int imaplen, match, i; - DBG("of_irq_map_raw: par=%s,intspec=[0x%08x 0x%08x...],ointsize=%d\n", - parent->full_name, intspec[0], intspec[1], ointsize); - ipar = of_node_get(parent); /* First get the #interrupt-cells property of the current cursor @@ -673,9 +675,6 @@ int of_irq_map_raw(struct device_node *parent, u32 *intspec, u32 ointsize, DBG("of_irq_map_raw: ipar=%s, size=%d\n", ipar->full_name, intsize); - if (ointsize != intsize) - return -EINVAL; - /* Look for this #address-cells. We have to implement the old linux * trick of looking for the parent here as some device-trees rely on it */ @@ -881,26 +880,17 @@ int of_irq_map_one(struct device_node *device, int index, struct of_irq *out_irq } intsize = *tmp; - DBG(" intsize=%d intlen=%d\n", intsize, intlen); - /* Check index */ if ((index + 1) * intsize > intlen) return -EINVAL; /* Get new specifier and map it */ - res = of_irq_map_raw(p, intspec + index * intsize, intsize, - addr, out_irq); + res = of_irq_map_raw(p, intspec + index * intsize, addr, out_irq); of_node_put(p); return res; } EXPORT_SYMBOL_GPL(of_irq_map_one); -#ifdef CONFIG_PCI -static u8 of_irq_pci_swizzle(u8 slot, u8 pin) -{ - return (((pin - 1) + slot) % 4) + 1; -} - int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq) { struct device_node *dn, *ppnode; @@ -974,7 +964,7 @@ int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq) laddr[0] = (pdev->bus->number << 16) | (pdev->devfn << 8); laddr[1] = laddr[2] = 0; - return of_irq_map_raw(ppnode, &lspec, 1, laddr, out_irq); + return of_irq_map_raw(ppnode, &lspec, laddr, out_irq); } EXPORT_SYMBOL_GPL(of_irq_map_pci); -#endif /* CONFIG_PCI */ + diff --git a/trunk/arch/powerpc/kernel/smp-tbsync.c b/trunk/arch/powerpc/kernel/smp-tbsync.c index de59c6c31a5b..f19e2e0e61e7 100644 --- a/trunk/arch/powerpc/kernel/smp-tbsync.c +++ b/trunk/arch/powerpc/kernel/smp-tbsync.c @@ -45,9 +45,8 @@ void __devinit smp_generic_take_timebase(void) { int cmd; u64 tb; - unsigned long flags; - local_irq_save(flags); + local_irq_disable(); while (!running) barrier(); rmb(); @@ -71,7 +70,7 @@ void __devinit smp_generic_take_timebase(void) set_tb(tb >> 32, tb & 0xfffffffful); enter_contest(tbsync->mark, -1); } - local_irq_restore(flags); + local_irq_enable(); } static int __devinit start_contest(int cmd, long offset, int num) diff --git a/trunk/arch/powerpc/kernel/time.c b/trunk/arch/powerpc/kernel/time.c index a124499e65d9..774c0a3c5019 100644 --- a/trunk/arch/powerpc/kernel/time.c +++ b/trunk/arch/powerpc/kernel/time.c @@ -125,8 +125,15 @@ static long timezone_offset; unsigned long ppc_proc_freq; unsigned long ppc_tb_freq; -static u64 tb_last_jiffy __cacheline_aligned_in_smp; -static DEFINE_PER_CPU(u64, last_jiffy); +u64 tb_last_jiffy __cacheline_aligned_in_smp; +unsigned long tb_last_stamp; + +/* + * Note that on ppc32 this only stores the bottom 32 bits of + * the timebase value, but that's enough to tell when a jiffy + * has passed. + */ +DEFINE_PER_CPU(unsigned long, last_jiffy); #ifdef CONFIG_VIRT_CPU_ACCOUNTING /* @@ -410,7 +417,7 @@ static __inline__ void timer_check_rtc(void) /* * This version of gettimeofday has microsecond resolution. */ -static inline void __do_gettimeofday(struct timeval *tv) +static inline void __do_gettimeofday(struct timeval *tv, u64 tb_val) { unsigned long sec, usec; u64 tb_ticks, xsec; @@ -424,12 +431,7 @@ static inline void __do_gettimeofday(struct timeval *tv) * without a divide (and in fact, without a multiply) */ temp_varp = do_gtod.varp; - - /* Sampling the time base must be done after loading - * do_gtod.varp in order to avoid racing with update_gtod. - */ - data_barrier(temp_varp); - tb_ticks = get_tb() - temp_varp->tb_orig_stamp; + tb_ticks = tb_val - temp_varp->tb_orig_stamp; temp_tb_to_xs = temp_varp->tb_to_xs; temp_stamp_xsec = temp_varp->stamp_xsec; xsec = temp_stamp_xsec + mulhdu(tb_ticks, temp_tb_to_xs); @@ -451,7 +453,7 @@ void do_gettimeofday(struct timeval *tv) do { seq = read_seqbegin_irqsave(&xtime_lock, flags); sec = xtime.tv_sec; - nsec = xtime.tv_nsec + tb_ticks_since(tb_last_jiffy); + nsec = xtime.tv_nsec + tb_ticks_since(tb_last_stamp); } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); usec = nsec / 1000; while (usec >= 1000000) { @@ -462,7 +464,7 @@ void do_gettimeofday(struct timeval *tv) tv->tv_usec = usec; return; } - __do_gettimeofday(tv); + __do_gettimeofday(tv, get_tb()); } EXPORT_SYMBOL(do_gettimeofday); @@ -648,7 +650,6 @@ void timer_interrupt(struct pt_regs * regs) int next_dec; int cpu = smp_processor_id(); unsigned long ticks; - u64 tb_next_jiffy; #ifdef CONFIG_PPC32 if (atomic_read(&ppc_n_lost_interrupts) != 0) @@ -690,13 +691,11 @@ void timer_interrupt(struct pt_regs * regs) continue; write_seqlock(&xtime_lock); - tb_next_jiffy = tb_last_jiffy + tb_ticks_per_jiffy; - if (per_cpu(last_jiffy, cpu) >= tb_next_jiffy) { - tb_last_jiffy = tb_next_jiffy; - do_timer(regs); - timer_recalc_offset(tb_last_jiffy); - timer_check_rtc(); - } + tb_last_jiffy += tb_ticks_per_jiffy; + tb_last_stamp = per_cpu(last_jiffy, cpu); + do_timer(regs); + timer_recalc_offset(tb_last_jiffy); + timer_check_rtc(); write_sequnlock(&xtime_lock); } @@ -741,7 +740,7 @@ void __init smp_space_timers(unsigned int max_cpus) int i; unsigned long half = tb_ticks_per_jiffy / 2; unsigned long offset = tb_ticks_per_jiffy / max_cpus; - u64 previous_tb = per_cpu(last_jiffy, boot_cpuid); + unsigned long previous_tb = per_cpu(last_jiffy, boot_cpuid); /* make sure tb > per_cpu(last_jiffy, cpu) for all cpus always */ previous_tb -= tb_ticks_per_jiffy; @@ -822,7 +821,7 @@ int do_settimeofday(struct timespec *tv) * and therefore the (jiffies - wall_jiffies) computation * has been removed. */ - tb_delta = tb_ticks_since(tb_last_jiffy); + tb_delta = tb_ticks_since(tb_last_stamp); tb_delta = mulhdu(tb_delta, do_gtod.varp->tb_to_xs); /* in xsec */ new_nsec -= SCALE_XSEC(tb_delta, 1000000000); @@ -942,7 +941,8 @@ void __init time_init(void) if (__USE_RTC()) { /* 601 processor: dec counts down by 128 every 128ns */ ppc_tb_freq = 1000000000; - tb_last_jiffy = get_rtcl(); + tb_last_stamp = get_rtcl(); + tb_last_jiffy = tb_last_stamp; } else { /* Normal PowerPC with timebase register */ ppc_md.calibrate_decr(); @@ -950,7 +950,7 @@ void __init time_init(void) ppc_tb_freq / 1000000, ppc_tb_freq % 1000000); printk(KERN_DEBUG "time_init: processor frequency = %lu.%.6lu MHz\n", ppc_proc_freq / 1000000, ppc_proc_freq % 1000000); - tb_last_jiffy = get_tb(); + tb_last_stamp = tb_last_jiffy = get_tb(); } tb_ticks_per_jiffy = ppc_tb_freq / HZ; @@ -1027,7 +1027,7 @@ void __init time_init(void) do_gtod.varp = &do_gtod.vars[0]; do_gtod.var_idx = 0; do_gtod.varp->tb_orig_stamp = tb_last_jiffy; - __get_cpu_var(last_jiffy) = tb_last_jiffy; + __get_cpu_var(last_jiffy) = tb_last_stamp; do_gtod.varp->stamp_xsec = (u64) xtime.tv_sec * XSEC_PER_SEC; do_gtod.tb_ticks_per_sec = tb_ticks_per_sec; do_gtod.varp->tb_to_xs = tb_to_xs; diff --git a/trunk/arch/powerpc/kernel/traps.c b/trunk/arch/powerpc/kernel/traps.c index 9b352bd0a460..e4d1713e8aea 100644 --- a/trunk/arch/powerpc/kernel/traps.c +++ b/trunk/arch/powerpc/kernel/traps.c @@ -585,14 +585,14 @@ static void parse_fpe(struct pt_regs *regs) #define INST_MFSPR_PVR_MASK 0xfc1fffff #define INST_DCBA 0x7c0005ec -#define INST_DCBA_MASK 0xfc0007fe +#define INST_DCBA_MASK 0x7c0007fe #define INST_MCRXR 0x7c000400 -#define INST_MCRXR_MASK 0xfc0007fe +#define INST_MCRXR_MASK 0x7c0007fe #define INST_STRING 0x7c00042a -#define INST_STRING_MASK 0xfc0007fe -#define INST_STRING_GEN_MASK 0xfc00067e +#define INST_STRING_MASK 0x7c0007fe +#define INST_STRING_GEN_MASK 0x7c00067e #define INST_LSWI 0x7c0004aa #define INST_LSWX 0x7c00042a #define INST_STSWI 0x7c0005aa diff --git a/trunk/arch/powerpc/lib/memcpy_64.S b/trunk/arch/powerpc/lib/memcpy_64.S index 7173ba98f427..fd66acfd3e3e 100644 --- a/trunk/arch/powerpc/lib/memcpy_64.S +++ b/trunk/arch/powerpc/lib/memcpy_64.S @@ -11,7 +11,6 @@ .align 7 _GLOBAL(memcpy) - std r3,48(r1) /* save destination pointer for return value */ mtcrf 0x01,r5 cmpldi cr1,r5,16 neg r6,r3 # LS 3 bits = # bytes to 8-byte dest bdry @@ -39,7 +38,7 @@ _GLOBAL(memcpy) stdu r9,16(r3) bdnz 1b 3: std r8,8(r3) - beq 3f + beqlr addi r3,r3,16 ld r9,8(r4) .Ldo_tail: @@ -54,8 +53,7 @@ _GLOBAL(memcpy) 2: bf cr7*4+3,3f rotldi r9,r9,8 stb r9,0(r3) -3: ld r3,48(r1) /* return dest pointer */ - blr +3: blr .Lsrc_unaligned: srdi r6,r5,3 @@ -117,7 +115,7 @@ _GLOBAL(memcpy) 5: srd r12,r9,r11 or r12,r8,r12 std r12,24(r3) - beq 4f + beqlr cmpwi cr1,r5,8 addi r3,r3,32 sld r9,r9,r10 @@ -169,5 +167,4 @@ _GLOBAL(memcpy) 3: bf cr7*4+3,4f lbz r0,0(r4) stb r0,0(r3) -4: ld r3,48(r1) /* return dest pointer */ - blr +4: blr diff --git a/trunk/arch/powerpc/mm/44x_mmu.c b/trunk/arch/powerpc/mm/44x_mmu.c index 0a0a0487b334..376829ed2211 100644 --- a/trunk/arch/powerpc/mm/44x_mmu.c +++ b/trunk/arch/powerpc/mm/44x_mmu.c @@ -103,7 +103,7 @@ unsigned long __init mmu_mapin_ram(void) /* Determine number of entries necessary to cover lowmem */ pinned_tlbs = (unsigned int) - (_ALIGN(total_lowmem, PPC_PIN_SIZE) >> PPC44x_PIN_SHIFT); + (_ALIGN(total_lowmem, PPC44x_PIN_SIZE) >> PPC44x_PIN_SHIFT); /* Write upper watermark to save location */ tlb_44x_hwater = PPC44x_LOW_SLOT - pinned_tlbs; @@ -111,7 +111,7 @@ unsigned long __init mmu_mapin_ram(void) /* If necessary, set additional pinned TLBs */ if (pinned_tlbs > 1) for (i = (PPC44x_LOW_SLOT-(pinned_tlbs-1)); i < PPC44x_LOW_SLOT; i++) { - unsigned int phys_addr = (PPC44x_LOW_SLOT-i) * PPC_PIN_SIZE; + unsigned int phys_addr = (PPC44x_LOW_SLOT-i) * PPC44x_PIN_SIZE; ppc44x_pin_tlb(i, phys_addr+PAGE_OFFSET, phys_addr); } diff --git a/trunk/arch/powerpc/mm/hugetlbpage.c b/trunk/arch/powerpc/mm/hugetlbpage.c index 5615acc29527..266b8b2ceac9 100644 --- a/trunk/arch/powerpc/mm/hugetlbpage.c +++ b/trunk/arch/powerpc/mm/hugetlbpage.c @@ -153,7 +153,7 @@ static void free_hugepte_range(struct mmu_gather *tlb, hugepd_t *hpdp) hpdp->pd = 0; tlb->need_flush = 1; pgtable_free_tlb(tlb, pgtable_free_cache(hugepte, HUGEPTE_CACHE_NUM, - PGF_CACHENUM_MASK)); + HUGEPTE_TABLE_SIZE-1)); } #ifdef CONFIG_PPC_64K_PAGES diff --git a/trunk/arch/powerpc/platforms/83xx/mpc834x_itx.c b/trunk/arch/powerpc/platforms/83xx/mpc834x_itx.c index cf3967a66fb5..b46305645d38 100644 --- a/trunk/arch/powerpc/platforms/83xx/mpc834x_itx.c +++ b/trunk/arch/powerpc/platforms/83xx/mpc834x_itx.c @@ -46,6 +46,26 @@ unsigned long isa_io_base = 0; unsigned long isa_mem_base = 0; #endif +#ifdef CONFIG_PCI +static int +mpc83xx_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) +{ + static char pci_irq_table[][4] = + /* + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ + { + {PIRQB, PIRQC, PIRQD, PIRQA}, /* idsel 0x0e */ + {PIRQA, PIRQB, PIRQC, PIRQD}, /* idsel 0x0f */ + {PIRQC, PIRQD, PIRQA, PIRQB}, /* idsel 0x10 */ + }; + + const long min_idsel = 0x0e, max_idsel = 0x10, irqs_per_slot = 4; + return PCI_IRQ_TABLE_LOOKUP; +} +#endif /* CONFIG_PCI */ + /* ************************************************************************ * * Setup the architecture @@ -72,6 +92,8 @@ static void __init mpc834x_itx_setup_arch(void) for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;) add_bridge(np); + ppc_md.pci_swizzle = common_swizzle; + ppc_md.pci_map_irq = mpc83xx_map_irq; ppc_md.pci_exclude_device = mpc83xx_exclude_device; #endif @@ -84,13 +106,25 @@ static void __init mpc834x_itx_setup_arch(void) void __init mpc834x_itx_init_IRQ(void) { - struct device_node *np; - - np = of_find_node_by_type(NULL, "ipic"); - if (!np) - return; + u8 senses[8] = { + 0, /* EXT 0 */ + IRQ_SENSE_LEVEL, /* EXT 1 */ + IRQ_SENSE_LEVEL, /* EXT 2 */ + 0, /* EXT 3 */ +#ifdef CONFIG_PCI + IRQ_SENSE_LEVEL, /* EXT 4 */ + IRQ_SENSE_LEVEL, /* EXT 5 */ + IRQ_SENSE_LEVEL, /* EXT 6 */ + IRQ_SENSE_LEVEL, /* EXT 7 */ +#else + 0, /* EXT 4 */ + 0, /* EXT 5 */ + 0, /* EXT 6 */ + 0, /* EXT 7 */ +#endif + }; - ipic_init(np, 0); + ipic_init(get_immrbase() + 0x00700, 0, 0, senses, 8); /* Initialize the default interrupt mapping priorities, * in case the boot rom changed something on us. @@ -119,7 +153,4 @@ define_machine(mpc834x_itx) { .time_init = mpc83xx_time_init, .calibrate_decr = generic_calibrate_decr, .progress = udbg_progress, -#ifdef CONFIG_PCI - .pcibios_fixup = mpc83xx_pcibios_fixup, -#endif }; diff --git a/trunk/arch/powerpc/platforms/83xx/mpc834x_sys.c b/trunk/arch/powerpc/platforms/83xx/mpc834x_sys.c index 32df239d1c48..3e1c16eb4a63 100644 --- a/trunk/arch/powerpc/platforms/83xx/mpc834x_sys.c +++ b/trunk/arch/powerpc/platforms/83xx/mpc834x_sys.c @@ -43,6 +43,33 @@ unsigned long isa_io_base = 0; unsigned long isa_mem_base = 0; #endif +#ifdef CONFIG_PCI +static int +mpc83xx_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) +{ + static char pci_irq_table[][4] = + /* + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ + { + {PIRQA, PIRQB, PIRQC, PIRQD}, /* idsel 0x11 */ + {PIRQC, PIRQD, PIRQA, PIRQB}, /* idsel 0x12 */ + {PIRQD, PIRQA, PIRQB, PIRQC}, /* idsel 0x13 */ + {0, 0, 0, 0}, + {PIRQA, PIRQB, PIRQC, PIRQD}, /* idsel 0x15 */ + {PIRQD, PIRQA, PIRQB, PIRQC}, /* idsel 0x16 */ + {PIRQC, PIRQD, PIRQA, PIRQB}, /* idsel 0x17 */ + {PIRQB, PIRQC, PIRQD, PIRQA}, /* idsel 0x18 */ + {0, 0, 0, 0}, /* idsel 0x19 */ + {0, 0, 0, 0}, /* idsel 0x20 */ + }; + + const long min_idsel = 0x11, max_idsel = 0x20, irqs_per_slot = 4; + return PCI_IRQ_TABLE_LOOKUP; +} +#endif /* CONFIG_PCI */ + /* ************************************************************************ * * Setup the architecture @@ -69,6 +96,8 @@ static void __init mpc834x_sys_setup_arch(void) for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;) add_bridge(np); + ppc_md.pci_swizzle = common_swizzle; + ppc_md.pci_map_irq = mpc83xx_map_irq; ppc_md.pci_exclude_device = mpc83xx_exclude_device; #endif @@ -81,13 +110,25 @@ static void __init mpc834x_sys_setup_arch(void) void __init mpc834x_sys_init_IRQ(void) { - struct device_node *np; - - np = of_find_node_by_type(NULL, "ipic"); - if (!np) - return; + u8 senses[8] = { + 0, /* EXT 0 */ + IRQ_SENSE_LEVEL, /* EXT 1 */ + IRQ_SENSE_LEVEL, /* EXT 2 */ + 0, /* EXT 3 */ +#ifdef CONFIG_PCI + IRQ_SENSE_LEVEL, /* EXT 4 */ + IRQ_SENSE_LEVEL, /* EXT 5 */ + IRQ_SENSE_LEVEL, /* EXT 6 */ + IRQ_SENSE_LEVEL, /* EXT 7 */ +#else + 0, /* EXT 4 */ + 0, /* EXT 5 */ + 0, /* EXT 6 */ + 0, /* EXT 7 */ +#endif + }; - ipic_init(np, 0); + ipic_init(get_immrbase() + 0x00700, 0, 0, senses, 8); /* Initialize the default interrupt mapping priorities, * in case the boot rom changed something on us. @@ -137,7 +178,4 @@ define_machine(mpc834x_sys) { .time_init = mpc83xx_time_init, .calibrate_decr = generic_calibrate_decr, .progress = udbg_progress, -#ifdef CONFIG_PCI - .pcibios_fixup = mpc83xx_pcibios_fixup, -#endif }; diff --git a/trunk/arch/powerpc/platforms/83xx/mpc83xx.h b/trunk/arch/powerpc/platforms/83xx/mpc83xx.h index 2c82bca9bfbb..01cae106912b 100644 --- a/trunk/arch/powerpc/platforms/83xx/mpc83xx.h +++ b/trunk/arch/powerpc/platforms/83xx/mpc83xx.h @@ -11,7 +11,6 @@ extern int add_bridge(struct device_node *dev); extern int mpc83xx_exclude_device(u_char bus, u_char devfn); -extern void mpc83xx_pcibios_fixup(void); extern void mpc83xx_restart(char *cmd); extern long mpc83xx_time_init(void); diff --git a/trunk/arch/powerpc/platforms/83xx/pci.c b/trunk/arch/powerpc/platforms/83xx/pci.c index 5d84a9ccd103..3b5e563c279f 100644 --- a/trunk/arch/powerpc/platforms/83xx/pci.c +++ b/trunk/arch/powerpc/platforms/83xx/pci.c @@ -45,15 +45,6 @@ int mpc83xx_exclude_device(u_char bus, u_char devfn) return PCIBIOS_SUCCESSFUL; } -void __init mpc83xx_pcibios_fixup(void) -{ - struct pci_dev *dev = NULL; - - /* map all the PCI irqs */ - for_each_pci_dev(dev) - pci_read_irq_line(dev); -} - int __init add_bridge(struct device_node *dev) { int len; diff --git a/trunk/arch/powerpc/platforms/85xx/Kconfig b/trunk/arch/powerpc/platforms/85xx/Kconfig index c3268d9877e4..454fc53289ab 100644 --- a/trunk/arch/powerpc/platforms/85xx/Kconfig +++ b/trunk/arch/powerpc/platforms/85xx/Kconfig @@ -14,6 +14,7 @@ config MPC8540_ADS config MPC85xx_CDS bool "Freescale MPC85xx CDS" select DEFAULT_UIMAGE + select PPC_I8259 if PCI help This option enables support for the MPC85xx CDS board diff --git a/trunk/arch/powerpc/platforms/85xx/mpc85xx_ads.c b/trunk/arch/powerpc/platforms/85xx/mpc85xx_ads.c index 9d2acfbbeccd..06a497676c99 100644 --- a/trunk/arch/powerpc/platforms/85xx/mpc85xx_ads.c +++ b/trunk/arch/powerpc/platforms/85xx/mpc85xx_ads.c @@ -37,7 +37,79 @@ unsigned long isa_io_base = 0; unsigned long isa_mem_base = 0; #endif +/* + * Internal interrupts are all Level Sensitive, and Positive Polarity + * + * Note: Likely, this table and the following function should be + * obtained and derived from the OF Device Tree. + */ +static u_char mpc85xx_ads_openpic_initsenses[] __initdata = { + MPC85XX_INTERNAL_IRQ_SENSES, + 0x0, /* External 0: */ +#if defined(CONFIG_PCI) + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Ext 1: PCI slot 0 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Ext 2: PCI slot 1 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Ext 3: PCI slot 2 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Ext 4: PCI slot 3 */ +#else + 0x0, /* External 1: */ + 0x0, /* External 2: */ + 0x0, /* External 3: */ + 0x0, /* External 4: */ +#endif + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 5: PHY */ + 0x0, /* External 6: */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 7: PHY */ + 0x0, /* External 8: */ + 0x0, /* External 9: */ + 0x0, /* External 10: */ + 0x0, /* External 11: */ +}; + #ifdef CONFIG_PCI +/* + * interrupt routing + */ + +int +mpc85xx_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) +{ + static char pci_irq_table[][4] = + /* + * This is little evil, but works around the fact + * that revA boards have IDSEL starting at 18 + * and others boards (older) start at 12 + * + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ + { + {PIRQA, PIRQB, PIRQC, PIRQD}, /* IDSEL 2 */ + {PIRQD, PIRQA, PIRQB, PIRQC}, + {PIRQC, PIRQD, PIRQA, PIRQB}, + {PIRQB, PIRQC, PIRQD, PIRQA}, /* IDSEL 5 */ + {0, 0, 0, 0}, /* -- */ + {0, 0, 0, 0}, /* -- */ + {0, 0, 0, 0}, /* -- */ + {0, 0, 0, 0}, /* -- */ + {0, 0, 0, 0}, /* -- */ + {0, 0, 0, 0}, /* -- */ + {PIRQA, PIRQB, PIRQC, PIRQD}, /* IDSEL 12 */ + {PIRQD, PIRQA, PIRQB, PIRQC}, + {PIRQC, PIRQD, PIRQA, PIRQB}, + {PIRQB, PIRQC, PIRQD, PIRQA}, /* IDSEL 15 */ + {0, 0, 0, 0}, /* -- */ + {0, 0, 0, 0}, /* -- */ + {PIRQA, PIRQB, PIRQC, PIRQD}, /* IDSEL 18 */ + {PIRQD, PIRQA, PIRQB, PIRQC}, + {PIRQC, PIRQD, PIRQA, PIRQB}, + {PIRQB, PIRQC, PIRQD, PIRQA}, /* IDSEL 21 */ + }; + + const long min_idsel = 2, max_idsel = 21, irqs_per_slot = 4; + return PCI_IRQ_TABLE_LOOKUP; +} + int mpc85xx_exclude_device(u_char bus, u_char devfn) { @@ -47,63 +119,44 @@ mpc85xx_exclude_device(u_char bus, u_char devfn) return PCIBIOS_SUCCESSFUL; } -void __init -mpc85xx_pcibios_fixup(void) -{ - struct pci_dev *dev = NULL; - - for_each_pci_dev(dev) - pci_read_irq_line(dev); -} #endif /* CONFIG_PCI */ void __init mpc85xx_ads_pic_init(void) { - struct mpic *mpic; - struct resource r; - struct device_node *np = NULL; - - np = of_find_node_by_type(np, "open-pic"); - - if (np == NULL) { - printk(KERN_ERR "Could not find open-pic node\n"); - return; - } - - if(of_address_to_resource(np, 0, &r)) { - printk(KERN_ERR "Could not map mpic register space\n"); - of_node_put(np); - return; - } - - mpic = mpic_alloc(np, r.start, - MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, - 4, 0, " OpenPIC "); - BUG_ON(mpic == NULL); - of_node_put(np); - - mpic_assign_isu(mpic, 0, r.start + 0x10200); - mpic_assign_isu(mpic, 1, r.start + 0x10280); - mpic_assign_isu(mpic, 2, r.start + 0x10300); - mpic_assign_isu(mpic, 3, r.start + 0x10380); - mpic_assign_isu(mpic, 4, r.start + 0x10400); - mpic_assign_isu(mpic, 5, r.start + 0x10480); - mpic_assign_isu(mpic, 6, r.start + 0x10500); - mpic_assign_isu(mpic, 7, r.start + 0x10580); - - /* Unused on this platform (leave room for 8548) */ - mpic_assign_isu(mpic, 8, r.start + 0x10600); - mpic_assign_isu(mpic, 9, r.start + 0x10680); - mpic_assign_isu(mpic, 10, r.start + 0x10700); - mpic_assign_isu(mpic, 11, r.start + 0x10780); - - /* External Interrupts */ - mpic_assign_isu(mpic, 12, r.start + 0x10000); - mpic_assign_isu(mpic, 13, r.start + 0x10080); - mpic_assign_isu(mpic, 14, r.start + 0x10100); - - mpic_init(mpic); + struct mpic *mpic1; + phys_addr_t OpenPIC_PAddr; + + /* Determine the Physical Address of the OpenPIC regs */ + OpenPIC_PAddr = get_immrbase() + MPC85xx_OPENPIC_OFFSET; + + mpic1 = mpic_alloc(OpenPIC_PAddr, + MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, + 4, MPC85xx_OPENPIC_IRQ_OFFSET, 0, 250, + mpc85xx_ads_openpic_initsenses, + sizeof(mpc85xx_ads_openpic_initsenses), + " OpenPIC "); + BUG_ON(mpic1 == NULL); + mpic_assign_isu(mpic1, 0, OpenPIC_PAddr + 0x10200); + mpic_assign_isu(mpic1, 1, OpenPIC_PAddr + 0x10280); + mpic_assign_isu(mpic1, 2, OpenPIC_PAddr + 0x10300); + mpic_assign_isu(mpic1, 3, OpenPIC_PAddr + 0x10380); + mpic_assign_isu(mpic1, 4, OpenPIC_PAddr + 0x10400); + mpic_assign_isu(mpic1, 5, OpenPIC_PAddr + 0x10480); + mpic_assign_isu(mpic1, 6, OpenPIC_PAddr + 0x10500); + mpic_assign_isu(mpic1, 7, OpenPIC_PAddr + 0x10580); + + /* dummy mappings to get to 48 */ + mpic_assign_isu(mpic1, 8, OpenPIC_PAddr + 0x10600); + mpic_assign_isu(mpic1, 9, OpenPIC_PAddr + 0x10680); + mpic_assign_isu(mpic1, 10, OpenPIC_PAddr + 0x10700); + mpic_assign_isu(mpic1, 11, OpenPIC_PAddr + 0x10780); + + /* External ints */ + mpic_assign_isu(mpic1, 12, OpenPIC_PAddr + 0x10000); + mpic_assign_isu(mpic1, 13, OpenPIC_PAddr + 0x10080); + mpic_assign_isu(mpic1, 14, OpenPIC_PAddr + 0x10100); + mpic_init(mpic1); } /* @@ -112,9 +165,7 @@ void __init mpc85xx_ads_pic_init(void) static void __init mpc85xx_ads_setup_arch(void) { struct device_node *cpu; -#ifdef CONFIG_PCI struct device_node *np; -#endif if (ppc_md.progress) ppc_md.progress("mpc85xx_ads_setup_arch()", 0); @@ -135,7 +186,8 @@ static void __init mpc85xx_ads_setup_arch(void) for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;) add_bridge(np); - ppc_md.pcibios_fixup = mpc85xx_pcibios_fixup; + ppc_md.pci_swizzle = common_swizzle; + ppc_md.pci_map_irq = mpc85xx_map_irq; ppc_md.pci_exclude_device = mpc85xx_exclude_device; #endif diff --git a/trunk/arch/powerpc/platforms/85xx/mpc85xx_cds.c b/trunk/arch/powerpc/platforms/85xx/mpc85xx_cds.c index 1d357d32a29f..18e6e11f7020 100644 --- a/trunk/arch/powerpc/platforms/85xx/mpc85xx_cds.c +++ b/trunk/arch/powerpc/platforms/85xx/mpc85xx_cds.c @@ -57,8 +57,94 @@ unsigned long isa_mem_base = 0; static int cds_pci_slot = 2; static volatile u8 *cadmus; +/* + * Internal interrupts are all Level Sensitive, and Positive Polarity + * + * Note: Likely, this table and the following function should be + * obtained and derived from the OF Device Tree. + */ +static u_char mpc85xx_cds_openpic_initsenses[] __initdata = { + MPC85XX_INTERNAL_IRQ_SENSES, +#if defined(CONFIG_PCI) + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Ext 0: PCI slot 0 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Ext 1: PCI slot 1 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Ext 2: PCI slot 2 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Ext 3: PCI slot 3 */ +#else + 0x0, /* External 0: */ + 0x0, /* External 1: */ + 0x0, /* External 2: */ + 0x0, /* External 3: */ +#endif + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 5: PHY */ + 0x0, /* External 6: */ + 0x0, /* External 7: */ + 0x0, /* External 8: */ + 0x0, /* External 9: */ + 0x0, /* External 10: */ +#ifdef CONFIG_PCI + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Ext 11: PCI2 slot 0 */ +#else + 0x0, /* External 11: */ +#endif +}; + #ifdef CONFIG_PCI +/* + * interrupt routing + */ +int +mpc85xx_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) +{ + struct pci_controller *hose = pci_bus_to_hose(dev->bus->number); + + if (!hose->index) + { + /* Handle PCI1 interrupts */ + char pci_irq_table[][4] = + /* + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ + + /* Note IRQ assignment for slots is based on which slot the elysium is + * in -- in this setup elysium is in slot #2 (this PIRQA as first + * interrupt on slot */ + { + { 0, 1, 2, 3 }, /* 16 - PMC */ + { 0, 1, 2, 3 }, /* 17 P2P (Tsi320) */ + { 0, 1, 2, 3 }, /* 18 - Slot 1 */ + { 1, 2, 3, 0 }, /* 19 - Slot 2 */ + { 2, 3, 0, 1 }, /* 20 - Slot 3 */ + { 3, 0, 1, 2 }, /* 21 - Slot 4 */ + }; + + const long min_idsel = 16, max_idsel = 21, irqs_per_slot = 4; + int i, j; + + for (i = 0; i < 6; i++) + for (j = 0; j < 4; j++) + pci_irq_table[i][j] = + ((pci_irq_table[i][j] + 5 - + cds_pci_slot) & 0x3) + PIRQ0A; + + return PCI_IRQ_TABLE_LOOKUP; + } else { + /* Handle PCI2 interrupts (if we have one) */ + char pci_irq_table[][4] = + { + /* + * We only have one slot and one interrupt + * going to PIRQA - PIRQD */ + { PIRQ1A, PIRQ1A, PIRQ1A, PIRQ1A }, /* 21 - slot 0 */ + }; + + const long min_idsel = 21, max_idsel = 21, irqs_per_slot = 4; + + return PCI_IRQ_TABLE_LOOKUP; + } +} #define ARCADIA_HOST_BRIDGE_IDSEL 17 #define ARCADIA_2ND_BRIDGE_IDSEL 3 @@ -124,104 +210,50 @@ mpc85xx_cds_pcibios_fixup(void) pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 11); pci_dev_put(dev); } - - /* Now map all the PCI irqs */ - dev = NULL; - for_each_pci_dev(dev) - pci_read_irq_line(dev); -} - -#ifdef CONFIG_PPC_I8259 -#warning The i8259 PIC support is currently broken -static void mpc85xx_8259_cascade(unsigned int irq, struct - irq_desc *desc, struct pt_regs *regs) -{ - unsigned int cascade_irq = i8259_irq(regs); - - if (cascade_irq != NO_IRQ) - generic_handle_irq(cascade_irq, regs); - - desc->chip->eoi(irq); } -#endif /* PPC_I8259 */ #endif /* CONFIG_PCI */ void __init mpc85xx_cds_pic_init(void) { - struct mpic *mpic; - struct resource r; - struct device_node *np = NULL; - struct device_node *cascade_node = NULL; - int cascade_irq; + struct mpic *mpic1; + phys_addr_t OpenPIC_PAddr; - np = of_find_node_by_type(np, "open-pic"); - - if (np == NULL) { - printk(KERN_ERR "Could not find open-pic node\n"); - return; - } + /* Determine the Physical Address of the OpenPIC regs */ + OpenPIC_PAddr = get_immrbase() + MPC85xx_OPENPIC_OFFSET; - if (of_address_to_resource(np, 0, &r)) { - printk(KERN_ERR "Failed to map mpic register space\n"); - of_node_put(np); - return; - } - - mpic = mpic_alloc(np, r.start, + mpic1 = mpic_alloc(OpenPIC_PAddr, MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, - 4, 0, " OpenPIC "); - BUG_ON(mpic == NULL); - - /* Return the mpic node */ - of_node_put(np); - - mpic_assign_isu(mpic, 0, r.start + 0x10200); - mpic_assign_isu(mpic, 1, r.start + 0x10280); - mpic_assign_isu(mpic, 2, r.start + 0x10300); - mpic_assign_isu(mpic, 3, r.start + 0x10380); - mpic_assign_isu(mpic, 4, r.start + 0x10400); - mpic_assign_isu(mpic, 5, r.start + 0x10480); - mpic_assign_isu(mpic, 6, r.start + 0x10500); - mpic_assign_isu(mpic, 7, r.start + 0x10580); - - /* Used only for 8548 so far, but no harm in - * allocating them for everyone */ - mpic_assign_isu(mpic, 8, r.start + 0x10600); - mpic_assign_isu(mpic, 9, r.start + 0x10680); - mpic_assign_isu(mpic, 10, r.start + 0x10700); - mpic_assign_isu(mpic, 11, r.start + 0x10780); - - /* External Interrupts */ - mpic_assign_isu(mpic, 12, r.start + 0x10000); - mpic_assign_isu(mpic, 13, r.start + 0x10080); - mpic_assign_isu(mpic, 14, r.start + 0x10100); - - mpic_init(mpic); - -#ifdef CONFIG_PPC_I8259 - /* Initialize the i8259 controller */ - for_each_node_by_type(np, "interrupt-controller") - if (device_is_compatible(np, "chrp,iic")) { - cascade_node = np; - break; - } - - if (cascade_node == NULL) { - printk(KERN_DEBUG "Could not find i8259 PIC\n"); - return; - } + 4, MPC85xx_OPENPIC_IRQ_OFFSET, 0, 250, + mpc85xx_cds_openpic_initsenses, + sizeof(mpc85xx_cds_openpic_initsenses), " OpenPIC "); + BUG_ON(mpic1 == NULL); + mpic_assign_isu(mpic1, 0, OpenPIC_PAddr + 0x10200); + mpic_assign_isu(mpic1, 1, OpenPIC_PAddr + 0x10280); + mpic_assign_isu(mpic1, 2, OpenPIC_PAddr + 0x10300); + mpic_assign_isu(mpic1, 3, OpenPIC_PAddr + 0x10380); + mpic_assign_isu(mpic1, 4, OpenPIC_PAddr + 0x10400); + mpic_assign_isu(mpic1, 5, OpenPIC_PAddr + 0x10480); + mpic_assign_isu(mpic1, 6, OpenPIC_PAddr + 0x10500); + mpic_assign_isu(mpic1, 7, OpenPIC_PAddr + 0x10580); + + /* dummy mappings to get to 48 */ + mpic_assign_isu(mpic1, 8, OpenPIC_PAddr + 0x10600); + mpic_assign_isu(mpic1, 9, OpenPIC_PAddr + 0x10680); + mpic_assign_isu(mpic1, 10, OpenPIC_PAddr + 0x10700); + mpic_assign_isu(mpic1, 11, OpenPIC_PAddr + 0x10780); + + /* External ints */ + mpic_assign_isu(mpic1, 12, OpenPIC_PAddr + 0x10000); + mpic_assign_isu(mpic1, 13, OpenPIC_PAddr + 0x10080); + mpic_assign_isu(mpic1, 14, OpenPIC_PAddr + 0x10100); + + mpic_init(mpic1); - cascade_irq = irq_of_parse_and_map(cascade_node, 0); - if (cascade_irq == NO_IRQ) { - printk(KERN_ERR "Failed to map cascade interrupt\n"); - return; - } - - i8259_init(cascade_node, 0); - of_node_put(cascade_node); +#ifdef CONFIG_PCI + mpic_setup_cascade(PIRQ0A, i8259_irq_cascade, NULL); - set_irq_chained_handler(cascade_irq, mpc85xx_8259_cascade); -#endif /* CONFIG_PPC_I8259 */ + i8259_init(0,0); +#endif } @@ -266,6 +298,8 @@ mpc85xx_cds_setup_arch(void) add_bridge(np); ppc_md.pcibios_fixup = mpc85xx_cds_pcibios_fixup; + ppc_md.pci_swizzle = common_swizzle; + ppc_md.pci_map_irq = mpc85xx_map_irq; ppc_md.pci_exclude_device = mpc85xx_exclude_device; #endif diff --git a/trunk/arch/powerpc/platforms/86xx/mpc8641_hpcn.h b/trunk/arch/powerpc/platforms/86xx/mpc8641_hpcn.h index 41e554c4af94..5d2bcf78cef7 100644 --- a/trunk/arch/powerpc/platforms/86xx/mpc8641_hpcn.h +++ b/trunk/arch/powerpc/platforms/86xx/mpc8641_hpcn.h @@ -16,6 +16,38 @@ #include +/* PCI interrupt controller */ +#define PIRQA 3 +#define PIRQB 4 +#define PIRQC 5 +#define PIRQD 6 +#define PIRQ7 7 +#define PIRQE 9 +#define PIRQF 10 +#define PIRQG 11 +#define PIRQH 12 + +/* PCI-Express memory map */ +#define MPC86XX_PCIE_LOWER_IO 0x00000000 +#define MPC86XX_PCIE_UPPER_IO 0x00ffffff + +#define MPC86XX_PCIE_LOWER_MEM 0x80000000 +#define MPC86XX_PCIE_UPPER_MEM 0x9fffffff + +#define MPC86XX_PCIE_IO_BASE 0xe2000000 +#define MPC86XX_PCIE_MEM_OFFSET 0x00000000 + +#define MPC86XX_PCIE_IO_SIZE 0x01000000 + +#define PCIE1_CFG_ADDR_OFFSET (0x8000) +#define PCIE1_CFG_DATA_OFFSET (0x8004) + +#define PCIE2_CFG_ADDR_OFFSET (0x9000) +#define PCIE2_CFG_DATA_OFFSET (0x9004) + +#define MPC86xx_PCIE_OFFSET PCIE1_CFG_ADDR_OFFSET +#define MPC86xx_PCIE_SIZE (0x1000) + #define MPC86XX_RSTCR_OFFSET (0xe00b0) /* Reset Control Register */ #endif /* __MPC8641_HPCN_H__ */ diff --git a/trunk/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c b/trunk/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c index 0b1b52168bb7..ebae73eb0063 100644 --- a/trunk/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c +++ b/trunk/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c @@ -37,14 +37,6 @@ #include "mpc86xx.h" #include "mpc8641_hpcn.h" -#undef DEBUG - -#ifdef DEBUG -#define DBG(fmt...) do { printk(KERN_ERR fmt); } while(0) -#else -#define DBG(fmt...) do { } while(0) -#endif - #ifndef CONFIG_PCI unsigned long isa_io_base = 0; unsigned long isa_mem_base = 0; @@ -52,219 +44,205 @@ unsigned long pci_dram_offset = 0; #endif -#ifdef CONFIG_PCI -static void mpc86xx_8259_cascade(unsigned int irq, struct irq_desc *desc, - struct pt_regs *regs) -{ - unsigned int cascade_irq = i8259_irq(regs); - if (cascade_irq != NO_IRQ) - generic_handle_irq(cascade_irq, regs); - desc->chip->eoi(irq); -} -#endif /* CONFIG_PCI */ +/* + * Internal interrupts are all Level Sensitive, and Positive Polarity + */ + +static u_char mpc86xx_hpcn_openpic_initsenses[] __initdata = { + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 0: Reserved */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 1: MCM */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 2: DDR DRAM */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 3: LBIU */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 4: DMA 0 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 5: DMA 1 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 6: DMA 2 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 7: DMA 3 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 8: PCIE1 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 9: PCIE2 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 10: Reserved */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 11: Reserved */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 12: DUART2 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 13: TSEC 1 Transmit */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 14: TSEC 1 Receive */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 15: TSEC 3 transmit */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 16: TSEC 3 receive */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 17: TSEC 3 error */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 18: TSEC 1 Receive/Transmit Error */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 19: TSEC 2 Transmit */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 20: TSEC 2 Receive */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 21: TSEC 4 transmit */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 22: TSEC 4 receive */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 23: TSEC 4 error */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 24: TSEC 2 Receive/Transmit Error */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 25: Unused */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 26: DUART1 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 27: I2C */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 28: Performance Monitor */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 29: Unused */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 30: Unused */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 31: Unused */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 32: SRIO error/write-port unit */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 33: SRIO outbound doorbell */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 34: SRIO inbound doorbell */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 35: Unused */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 36: Unused */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 37: SRIO outbound message unit 1 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 38: SRIO inbound message unit 1 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 39: SRIO outbound message unit 2 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 40: SRIO inbound message unit 2 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 41: Unused */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 42: Unused */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 43: Unused */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 44: Unused */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 45: Unused */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 46: Unused */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 47: Unused */ + 0x0, /* External 0: */ + 0x0, /* External 1: */ + 0x0, /* External 2: */ + 0x0, /* External 3: */ + 0x0, /* External 4: */ + 0x0, /* External 5: */ + 0x0, /* External 6: */ + 0x0, /* External 7: */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 8: Pixis FPGA */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* External 9: ULI 8259 INTR Cascade */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 10: Quad ETH PHY */ + 0x0, /* External 11: */ + 0x0, + 0x0, + 0x0, + 0x0, +}; + void __init mpc86xx_hpcn_init_irq(void) { struct mpic *mpic1; - struct device_node *np; - struct resource res; -#ifdef CONFIG_PCI - struct device_node *cascade_node = NULL; - int cascade_irq; -#endif + phys_addr_t openpic_paddr; - /* Determine PIC address. */ - np = of_find_node_by_type(NULL, "open-pic"); - if (np == NULL) - return; - of_address_to_resource(np, 0, &res); + /* Determine the Physical Address of the OpenPIC regs */ + openpic_paddr = get_immrbase() + MPC86xx_OPENPIC_OFFSET; /* Alloc mpic structure and per isu has 16 INT entries. */ - mpic1 = mpic_alloc(np, res.start, + mpic1 = mpic_alloc(openpic_paddr, MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, - 16, NR_IRQS - 4, + 16, MPC86xx_OPENPIC_IRQ_OFFSET, 0, 250, + mpc86xx_hpcn_openpic_initsenses, + sizeof(mpc86xx_hpcn_openpic_initsenses), " MPIC "); BUG_ON(mpic1 == NULL); - mpic_assign_isu(mpic1, 0, res.start + 0x10000); - /* 48 Internal Interrupts */ - mpic_assign_isu(mpic1, 1, res.start + 0x10200); - mpic_assign_isu(mpic1, 2, res.start + 0x10400); - mpic_assign_isu(mpic1, 3, res.start + 0x10600); + mpic_assign_isu(mpic1, 0, openpic_paddr + 0x10200); + mpic_assign_isu(mpic1, 1, openpic_paddr + 0x10400); + mpic_assign_isu(mpic1, 2, openpic_paddr + 0x10600); - /* 16 External interrupts - * Moving them from [0 - 15] to [64 - 79] - */ - mpic_assign_isu(mpic1, 4, res.start + 0x10000); + /* 16 External interrupts */ + mpic_assign_isu(mpic1, 3, openpic_paddr + 0x10000); mpic_init(mpic1); #ifdef CONFIG_PCI - /* Initialize i8259 controller */ - for_each_node_by_type(np, "interrupt-controller") - if (device_is_compatible(np, "chrp,iic")) { - cascade_node = np; - break; - } - if (cascade_node == NULL) { - printk(KERN_DEBUG "mpc86xxhpcn: no ISA interrupt controller\n"); - return; - } - - cascade_irq = irq_of_parse_and_map(cascade_node, 0); - if (cascade_irq == NO_IRQ) { - printk(KERN_ERR "mpc86xxhpcn: failed to map cascade interrupt"); - return; - } - DBG("mpc86xxhpcn: cascade mapped to irq %d\n", cascade_irq); - - i8259_init(cascade_node, 0); - set_irq_chained_handler(cascade_irq, mpc86xx_8259_cascade); + mpic_setup_cascade(MPC86xx_IRQ_EXT9, i8259_irq_cascade, NULL); + i8259_init(0, I8259_OFFSET); #endif } -#ifdef CONFIG_PCI -enum pirq{PIRQA = 8, PIRQB, PIRQC, PIRQD, PIRQE, PIRQF, PIRQG, PIRQH}; -const unsigned char uli1575_irq_route_table[16] = { - 0, /* 0: Reserved */ - 0x8, /* 1: 0b1000 */ - 0, /* 2: Reserved */ - 0x2, /* 3: 0b0010 */ - 0x4, /* 4: 0b0100 */ - 0x5, /* 5: 0b0101 */ - 0x7, /* 6: 0b0111 */ - 0x6, /* 7: 0b0110 */ - 0, /* 8: Reserved */ - 0x1, /* 9: 0b0001 */ - 0x3, /* 10: 0b0011 */ - 0x9, /* 11: 0b1001 */ - 0xb, /* 12: 0b1011 */ - 0, /* 13: Reserved */ - 0xd, /* 14, 0b1101 */ - 0xf, /* 15, 0b1111 */ -}; -static int __devinit -get_pci_irq_from_of(struct pci_controller *hose, int slot, int pin) +#ifdef CONFIG_PCI +/* + * interrupt routing + */ + +int +mpc86xx_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) { - struct of_irq oirq; - u32 laddr[3]; - struct device_node *hosenode = hose ? hose->arch_data : NULL; - - if (!hosenode) return -EINVAL; - - laddr[0] = (hose->first_busno << 16) | (PCI_DEVFN(slot, 0) << 8); - laddr[1] = laddr[2] = 0; - of_irq_map_raw(hosenode, &pin, laddr, &oirq); - DBG("mpc86xx_hpcn: pci irq addr %x, slot %d, pin %d, irq %d\n", - laddr[0], slot, pin, oirq.specifier[0]); - return oirq.specifier[0]; + static char pci_irq_table[][4] = { + /* + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ + {PIRQA, PIRQB, PIRQC, PIRQD}, /* IDSEL 17 -- PCI Slot 1 */ + {PIRQB, PIRQC, PIRQD, PIRQA}, /* IDSEL 18 -- PCI Slot 2 */ + {0, 0, 0, 0}, /* IDSEL 19 */ + {0, 0, 0, 0}, /* IDSEL 20 */ + {0, 0, 0, 0}, /* IDSEL 21 */ + {0, 0, 0, 0}, /* IDSEL 22 */ + {0, 0, 0, 0}, /* IDSEL 23 */ + {0, 0, 0, 0}, /* IDSEL 24 */ + {0, 0, 0, 0}, /* IDSEL 25 */ + {PIRQD, PIRQA, PIRQB, PIRQC}, /* IDSEL 26 -- PCI Bridge*/ + {PIRQC, 0, 0, 0}, /* IDSEL 27 -- LAN */ + {PIRQE, PIRQF, PIRQH, PIRQ7}, /* IDSEL 28 -- USB 1.1 */ + {PIRQE, PIRQF, PIRQG, 0}, /* IDSEL 29 -- Audio & Modem */ + {PIRQH, 0, 0, 0}, /* IDSEL 30 -- LPC & PMU*/ + {PIRQD, 0, 0, 0}, /* IDSEL 31 -- ATA */ + }; + + const long min_idsel = 17, max_idsel = 31, irqs_per_slot = 4; + return PCI_IRQ_TABLE_LOOKUP + I8259_OFFSET; } -static void __devinit quirk_uli1575(struct pci_dev *dev) +static void __devinit quirk_ali1575(struct pci_dev *dev) { unsigned short temp; - struct pci_controller *hose = pci_bus_to_host(dev->bus); - unsigned char irq2pin[16]; - unsigned long pirq_map_word = 0; - u32 irq; - int i; - - /* - * ULI1575 interrupts route setup - */ - memset(irq2pin, 0, 16); /* Initialize default value 0 */ - - /* - * PIRQA -> PIRQD mapping read from OF-tree - * - * interrupts for PCI slot0 -- PIRQA / PIRQB / PIRQC / PIRQD - * PCI slot1 -- PIRQB / PIRQC / PIRQD / PIRQA - */ - for (i = 0; i < 4; i++){ - irq = get_pci_irq_from_of(hose, 17, i + 1); - if (irq > 0 && irq < 16) - irq2pin[irq] = PIRQA + i; - else - printk(KERN_WARNING "ULI1575 device" - "(slot %d, pin %d) irq %d is invalid.\n", - 17, i, irq); - } /* - * PIRQE -> PIRQF mapping set manually + * ALI1575 interrupts route table setup: * * IRQ pin IRQ# + * PIRQA ---- 3 + * PIRQB ---- 4 + * PIRQC ---- 5 + * PIRQD ---- 6 * PIRQE ---- 9 * PIRQF ---- 10 * PIRQG ---- 11 * PIRQH ---- 12 + * + * interrupts for PCI slot0 -- PIRQA / PIRQB / PIRQC / PIRQD + * PCI slot1 -- PIRQB / PIRQC / PIRQD / PIRQA */ - for (i = 0; i < 4; i++) irq2pin[i + 9] = PIRQE + i; - - /* Set IRQ-PIRQ Mapping to ULI1575 */ - for (i = 0; i < 16; i++) - if (irq2pin[i]) - pirq_map_word |= (uli1575_irq_route_table[i] & 0xf) - << ((irq2pin[i] - PIRQA) * 4); - - /* ULI1575 IRQ mapping conf register default value is 0xb9317542 */ - DBG("Setup ULI1575 IRQ mapping configuration register value = 0x%x\n", - pirq_map_word); - pci_write_config_dword(dev, 0x48, pirq_map_word); - -#define ULI1575_SET_DEV_IRQ(slot, pin, reg) \ - do { \ - int irq; \ - irq = get_pci_irq_from_of(hose, slot, pin); \ - if (irq > 0 && irq < 16) \ - pci_write_config_byte(dev, reg, irq2pin[irq]); \ - else \ - printk(KERN_WARNING "ULI1575 device" \ - "(slot %d, pin %d) irq %d is invalid.\n", \ - slot, pin, irq); \ - } while(0) + pci_write_config_dword(dev, 0x48, 0xb9317542); - /* USB 1.1 OHCI controller 1, slot 28, pin 1 */ - ULI1575_SET_DEV_IRQ(28, 1, 0x86); + /* USB 1.1 OHCI controller 1, interrupt: PIRQE */ + pci_write_config_byte(dev, 0x86, 0x0c); - /* USB 1.1 OHCI controller 2, slot 28, pin 2 */ - ULI1575_SET_DEV_IRQ(28, 2, 0x87); + /* USB 1.1 OHCI controller 2, interrupt: PIRQF */ + pci_write_config_byte(dev, 0x87, 0x0d); - /* USB 1.1 OHCI controller 3, slot 28, pin 3 */ - ULI1575_SET_DEV_IRQ(28, 3, 0x88); + /* USB 1.1 OHCI controller 3, interrupt: PIRQH */ + pci_write_config_byte(dev, 0x88, 0x0f); - /* USB 2.0 controller, slot 28, pin 4 */ - irq = get_pci_irq_from_of(hose, 28, 4); - if (irq >= 0 && irq <=15) - pci_write_config_dword(dev, 0x74, uli1575_irq_route_table[irq]); + /* USB 2.0 controller, interrupt: PIRQ7 */ + pci_write_config_byte(dev, 0x74, 0x06); - /* Audio controller, slot 29, pin 1 */ - ULI1575_SET_DEV_IRQ(29, 1, 0x8a); + /* Audio controller, interrupt: PIRQE */ + pci_write_config_byte(dev, 0x8a, 0x0c); - /* Modem controller, slot 29, pin 2 */ - ULI1575_SET_DEV_IRQ(29, 2, 0x8b); + /* Modem controller, interrupt: PIRQF */ + pci_write_config_byte(dev, 0x8b, 0x0d); - /* HD audio controller, slot 29, pin 3 */ - ULI1575_SET_DEV_IRQ(29, 3, 0x8c); + /* HD audio controller, interrupt: PIRQG */ + pci_write_config_byte(dev, 0x8c, 0x0e); - /* SMB interrupt: slot 30, pin 1 */ - ULI1575_SET_DEV_IRQ(30, 1, 0x8e); + /* Serial ATA interrupt: PIRQD */ + pci_write_config_byte(dev, 0x8d, 0x0b); - /* PMU ACPI SCI interrupt: slot 30, pin 2 */ - ULI1575_SET_DEV_IRQ(30, 2, 0x8f); + /* SMB interrupt: PIRQH */ + pci_write_config_byte(dev, 0x8e, 0x0f); - /* Serial ATA interrupt: slot 31, pin 1 */ - ULI1575_SET_DEV_IRQ(31, 1, 0x8d); + /* PMU ACPI SCI interrupt: PIRQH */ + pci_write_config_byte(dev, 0x8f, 0x0f); /* Primary PATA IDE IRQ: 14 * Secondary PATA IDE IRQ: 15 */ - pci_write_config_byte(dev, 0x44, 0x30 | uli1575_irq_route_table[14]); - pci_write_config_byte(dev, 0x75, uli1575_irq_route_table[15]); + pci_write_config_byte(dev, 0x44, 0x3d); + pci_write_config_byte(dev, 0x75, 0x0f); /* Set IRQ14 and IRQ15 to legacy IRQs */ pci_read_config_word(dev, 0x46, &temp); @@ -286,8 +264,6 @@ static void __devinit quirk_uli1575(struct pci_dev *dev) */ outb(0xfa, 0x4d0); outb(0x1e, 0x4d1); - -#undef ULI1575_SET_DEV_IRQ } static void __devinit quirk_uli5288(struct pci_dev *dev) @@ -330,7 +306,7 @@ static void __devinit early_uli5249(struct pci_dev *dev) dev->class |= 0x1; } -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x1575, quirk_uli1575); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x1575, quirk_ali1575); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x5288, quirk_uli5288); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x5229, quirk_uli5229); DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_AL, 0x5249, early_uli5249); @@ -361,6 +337,8 @@ mpc86xx_hpcn_setup_arch(void) for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;) add_bridge(np); + ppc_md.pci_swizzle = common_swizzle; + ppc_md.pci_map_irq = mpc86xx_map_irq; ppc_md.pci_exclude_device = mpc86xx_exclude_device; #endif @@ -399,15 +377,6 @@ mpc86xx_hpcn_show_cpuinfo(struct seq_file *m) } -void __init mpc86xx_hpcn_pcibios_fixup(void) -{ - struct pci_dev *dev = NULL; - - for_each_pci_dev(dev) - pci_read_irq_line(dev); -} - - /* * Called very early, device-tree isn't unflattened */ @@ -462,7 +431,6 @@ define_machine(mpc86xx_hpcn) { .setup_arch = mpc86xx_hpcn_setup_arch, .init_IRQ = mpc86xx_hpcn_init_irq, .show_cpuinfo = mpc86xx_hpcn_show_cpuinfo, - .pcibios_fixup = mpc86xx_hpcn_pcibios_fixup, .get_irq = mpic_get_irq, .restart = mpc86xx_restart, .time_init = mpc86xx_time_init, diff --git a/trunk/arch/powerpc/platforms/86xx/pci.c b/trunk/arch/powerpc/platforms/86xx/pci.c index a8c8f0a44055..bc5139043112 100644 --- a/trunk/arch/powerpc/platforms/86xx/pci.c +++ b/trunk/arch/powerpc/platforms/86xx/pci.c @@ -188,8 +188,7 @@ int __init add_bridge(struct device_node *dev) printk(KERN_INFO "Found MPC86xx PCIE host bridge at 0x%08lx. " "Firmware bus number: %d->%d\n", - (unsigned long) rsrc.start, - hose->first_busno, hose->last_busno); + rsrc.start, hose->first_busno, hose->last_busno); DBG(" ->Hose at 0x%p, cfg_addr=0x%p,cfg_data=0x%p\n", hose, hose->cfg_addr, hose->cfg_data); diff --git a/trunk/arch/powerpc/platforms/embedded6xx/Kconfig b/trunk/arch/powerpc/platforms/embedded6xx/Kconfig index 234a861870a8..ba07a9a7c039 100644 --- a/trunk/arch/powerpc/platforms/embedded6xx/Kconfig +++ b/trunk/arch/powerpc/platforms/embedded6xx/Kconfig @@ -80,7 +80,6 @@ config MPC7448HPC2 select DEFAULT_UIMAGE select PPC_UDBG_16550 select MPIC - select MPIC_WEIRD help Select MPC7448HPC2 if configuring for Freescale MPC7448HPC2 (Taiga) platform diff --git a/trunk/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c b/trunk/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c index 5d393eb94935..d7a4fc7ca238 100644 --- a/trunk/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c +++ b/trunk/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c @@ -1,7 +1,7 @@ /* * mpc7448_hpc2.c * - * Board setup routines for the Freescale mpc7448hpc2(taiga) platform + * Board setup routines for the Freescale Taiga platform * * Author: Jacob Pan * jacob.pan@freescale.com @@ -12,10 +12,10 @@ * * Copyright 2004-2006 Freescale Semiconductor, Inc. * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. + * This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. */ #include @@ -62,8 +62,43 @@ pci_dram_offset = MPC7448_HPC2_PCI_MEM_OFFSET; extern int tsi108_setup_pci(struct device_node *dev); extern void _nmask_and_or_msr(unsigned long nmask, unsigned long or_val); extern void tsi108_pci_int_init(void); -extern void tsi108_irq_cascade(unsigned int irq, struct irq_desc *desc, - struct pt_regs *regs); +extern int tsi108_irq_cascade(struct pt_regs *regs, void *unused); + +/* + * Define all of the IRQ senses and polarities. Taken from the + * mpc7448hpc manual. + * Note: Likely, this table and the following function should be + * obtained and derived from the OF Device Tree. + */ + +static u_char mpc7448_hpc2_pic_initsenses[] __initdata = { + /* External on-board sources */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* INT[0] XINT0 from FPGA */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* INT[1] XINT1 from FPGA */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* INT[2] PHY_INT from both GIGE */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* INT[3] RESERVED */ + /* Internal Tsi108/109 interrupt sources */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* Reserved IRQ */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* Reserved IRQ */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* Reserved IRQ */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* Reserved IRQ */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* DMA0 */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* DMA1 */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* DMA2 */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* DMA3 */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* UART0 */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* UART1 */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* I2C */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* GPIO */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* GIGE0 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* GIGE1 */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* Reserved IRQ */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* HLP */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* SDC */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* Processor IF */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* Reserved IRQ */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* PCI/X block */ +}; int mpc7448_hpc2_exclude_device(u_char bus, u_char devfn) { @@ -194,8 +229,6 @@ static void __init mpc7448_hpc2_init_IRQ(void) { struct mpic *mpic; phys_addr_t mpic_paddr = 0; - unsigned int cascade_pci_irq; - struct device_node *tsi_pci; struct device_node *tsi_pic; tsi_pic = of_find_node_by_type(NULL, "open-pic"); @@ -213,31 +246,24 @@ static void __init mpc7448_hpc2_init_IRQ(void) DBG("%s: tsi108pic phys_addr = 0x%x\n", __FUNCTION__, (u32) mpic_paddr); - mpic = mpic_alloc(tsi_pic, mpic_paddr, + mpic = mpic_alloc(mpic_paddr, MPIC_PRIMARY | MPIC_BIG_ENDIAN | MPIC_WANTS_RESET | - MPIC_SPV_EOI | MPIC_NO_PTHROU_DIS | MPIC_REGSET_TSI108, + MPIC_SPV_EOI | MPIC_MOD_ID(MPIC_ID_TSI108), 0, /* num_sources used */ + TSI108_IRQ_BASE, 0, /* num_sources used */ - "Tsi108_PIC"); + NR_IRQS - 4 /* XXXX */, + mpc7448_hpc2_pic_initsenses, + sizeof(mpc7448_hpc2_pic_initsenses), "Tsi108_PIC"); BUG_ON(mpic == NULL); /* XXXX */ - mpic_init(mpic); - - tsi_pci = of_find_node_by_type(NULL, "pci"); - if (tsi_pci == 0) { - printk("%s: No tsi108 pci node found !\n", __FUNCTION__); - return; - } - - cascade_pci_irq = irq_of_parse_and_map(tsi_pci, 0); - set_irq_data(cascade_pci_irq, mpic); - set_irq_chained_handler(cascade_pci_irq, tsi108_irq_cascade); + mpic_init(mpic); + mpic_setup_cascade(IRQ_TSI108_PCI, tsi108_irq_cascade, mpic); tsi108_pci_int_init(); /* Configure MPIC outputs to CPU0 */ tsi108_write_reg(TSI108_MPIC_OFFSET + 0x30c, 0); - of_node_put(tsi_pic); } void mpc7448_hpc2_show_cpuinfo(struct seq_file *m) @@ -294,7 +320,6 @@ static int mpc7448_machine_check_exception(struct pt_regs *regs) return 0; } - define_machine(mpc7448_hpc2){ .name = "MPC7448 HPC2", .probe = mpc7448_hpc2_probe, diff --git a/trunk/arch/powerpc/platforms/powermac/bootx_init.c b/trunk/arch/powerpc/platforms/powermac/bootx_init.c index 9d73d0234c5d..6a026c733f6a 100644 --- a/trunk/arch/powerpc/platforms/powermac/bootx_init.c +++ b/trunk/arch/powerpc/platforms/powermac/bootx_init.c @@ -411,15 +411,8 @@ static unsigned long __init bootx_flatten_dt(unsigned long start) DBG("End of boot params: %x\n", mem_end); rsvmap[0] = mem_start; rsvmap[1] = mem_end; - if (bootx_info->ramDisk) { - rsvmap[2] = ((unsigned long)bootx_info) + bootx_info->ramDisk; - rsvmap[3] = rsvmap[2] + bootx_info->ramDiskSize; - rsvmap[4] = 0; - rsvmap[5] = 0; - } else { - rsvmap[2] = 0; - rsvmap[3] = 0; - } + rsvmap[2] = 0; + rsvmap[3] = 0; return (unsigned long)hdr; } @@ -550,12 +543,12 @@ void __init bootx_init(unsigned long r3, unsigned long r4) */ if (bi->version < 5) { space = bi->deviceTreeOffset + bi->deviceTreeSize; - if (bi->ramDisk >= space) + if (bi->ramDisk) space = bi->ramDisk + bi->ramDiskSize; } else space = bi->totalParamsSize; - bootx_printf("Total space used by parameters & ramdisk: 0x%x \n", space); + bootx_printf("Total space used by parameters & ramdisk: %x \n", space); /* New BootX will have flushed all TLBs and enters kernel with * MMU switched OFF, so this should not be useful anymore. diff --git a/trunk/arch/powerpc/platforms/powermac/pfunc_base.c b/trunk/arch/powerpc/platforms/powermac/pfunc_base.c index aacfa59595d1..6d66359ec8c8 100644 --- a/trunk/arch/powerpc/platforms/powermac/pfunc_base.c +++ b/trunk/arch/powerpc/platforms/powermac/pfunc_base.c @@ -256,7 +256,7 @@ static struct pmf_handlers macio_mmio_handlers = { .write_reg32 = macio_do_write_reg32, .read_reg32 = macio_do_read_reg32, .write_reg8 = macio_do_write_reg8, - .read_reg8 = macio_do_read_reg8, + .read_reg32 = macio_do_read_reg8, .read_reg32_msrx = macio_do_read_reg32_msrx, .read_reg8_msrx = macio_do_read_reg8_msrx, .write_reg32_slm = macio_do_write_reg32_slm, diff --git a/trunk/arch/powerpc/platforms/powermac/pic.c b/trunk/arch/powerpc/platforms/powermac/pic.c index 39f7ddb554ea..060789e31c67 100644 --- a/trunk/arch/powerpc/platforms/powermac/pic.c +++ b/trunk/arch/powerpc/platforms/powermac/pic.c @@ -87,8 +87,8 @@ static void __pmac_retrigger(unsigned int irq_nr) static void pmac_mask_and_ack_irq(unsigned int virq) { unsigned int src = irq_map[virq].hwirq; - unsigned long bit = 1UL << (src & 0x1f); - int i = src >> 5; + unsigned long bit = 1UL << (virq & 0x1f); + int i = virq >> 5; unsigned long flags; spin_lock_irqsave(&pmac_pic_lock, flags); @@ -175,7 +175,7 @@ static void pmac_mask_irq(unsigned int virq) spin_lock_irqsave(&pmac_pic_lock, flags); __clear_bit(src, ppc_cached_irq_mask); - __pmac_set_irq_mask(src, 1); + __pmac_set_irq_mask(src, 0); spin_unlock_irqrestore(&pmac_pic_lock, flags); } diff --git a/trunk/arch/powerpc/sysdev/Makefile b/trunk/arch/powerpc/sysdev/Makefile index e5e999ea891a..cebfae242602 100644 --- a/trunk/arch/powerpc/sysdev/Makefile +++ b/trunk/arch/powerpc/sysdev/Makefile @@ -9,11 +9,11 @@ obj-$(CONFIG_BOOKE) += dcr.o obj-$(CONFIG_40x) += dcr.o obj-$(CONFIG_U3_DART) += dart_iommu.o obj-$(CONFIG_MMIO_NVRAM) += mmio_nvram.o +obj-$(CONFIG_PPC_83xx) += ipic.o obj-$(CONFIG_FSL_SOC) += fsl_soc.o obj-$(CONFIG_PPC_TODC) += todc.o obj-$(CONFIG_TSI108_BRIDGE) += tsi108_pci.o tsi108_dev.o ifeq ($(CONFIG_PPC_MERGE),y) obj-$(CONFIG_PPC_I8259) += i8259.o -obj-$(CONFIG_PPC_83xx) += ipic.o -endif + endif diff --git a/trunk/arch/powerpc/sysdev/fsl_soc.c b/trunk/arch/powerpc/sysdev/fsl_soc.c index ef10bcf2d943..12b65609c072 100644 --- a/trunk/arch/powerpc/sysdev/fsl_soc.c +++ b/trunk/arch/powerpc/sysdev/fsl_soc.c @@ -85,8 +85,11 @@ static int __init gfar_mdio_of_init(void) mdio_data.irq[k] = -1; while ((child = of_get_next_child(np, child)) != NULL) { - u32 *id = get_property(child, "reg", NULL); - mdio_data.irq[*id] = irq_of_parse_and_map(child, 0); + if (child->n_intrs) { + u32 *id = + (u32 *) get_property(child, "reg", NULL); + mdio_data.irq[*id] = child->intrs[0].line; + } } ret = @@ -128,7 +131,6 @@ static int __init gfar_of_init(void) char *model; void *mac_addr; phandle *ph; - int n_res = 1; memset(r, 0, sizeof(r)); memset(&gfar_data, 0, sizeof(gfar_data)); @@ -137,7 +139,8 @@ static int __init gfar_of_init(void) if (ret) goto err; - r[1].start = r[1].end = irq_of_parse_and_map(np, 0); + r[1].start = np->intrs[0].line; + r[1].end = np->intrs[0].line; r[1].flags = IORESOURCE_IRQ; model = get_property(np, "model", NULL); @@ -147,19 +150,19 @@ static int __init gfar_of_init(void) r[1].name = gfar_tx_intr; r[2].name = gfar_rx_intr; - r[2].start = r[2].end = irq_of_parse_and_map(np, 1); + r[2].start = np->intrs[1].line; + r[2].end = np->intrs[1].line; r[2].flags = IORESOURCE_IRQ; r[3].name = gfar_err_intr; - r[3].start = r[3].end = irq_of_parse_and_map(np, 2); + r[3].start = np->intrs[2].line; + r[3].end = np->intrs[2].line; r[3].flags = IORESOURCE_IRQ; - - n_res += 2; } gfar_dev = platform_device_register_simple("fsl-gianfar", i, &r[0], - n_res + 1); + np->n_intrs + 1); if (IS_ERR(gfar_dev)) { ret = PTR_ERR(gfar_dev); @@ -256,7 +259,8 @@ static int __init fsl_i2c_of_init(void) if (ret) goto err; - r[1].start = r[1].end = irq_of_parse_and_map(np, 0); + r[1].start = np->intrs[0].line; + r[1].end = np->intrs[0].line; r[1].flags = IORESOURCE_IRQ; i2c_dev = platform_device_register_simple("fsl-i2c", i, r, 2); @@ -392,7 +396,8 @@ static int __init fsl_usb_of_init(void) if (ret) goto err; - r[1].start = r[1].end = irq_of_parse_and_map(np, 0); + r[1].start = np->intrs[0].line; + r[1].end = np->intrs[0].line; r[1].flags = IORESOURCE_IRQ; usb_dev_mph = @@ -440,7 +445,8 @@ static int __init fsl_usb_of_init(void) if (ret) goto unreg_mph; - r[1].start = r[1].end = irq_of_parse_and_map(np, 0); + r[1].start = np->intrs[0].line; + r[1].end = np->intrs[0].line; r[1].flags = IORESOURCE_IRQ; usb_dev_dr = diff --git a/trunk/arch/powerpc/sysdev/ipic.c b/trunk/arch/powerpc/sysdev/ipic.c index 70e707785d49..46801f5ec03f 100644 --- a/trunk/arch/powerpc/sysdev/ipic.c +++ b/trunk/arch/powerpc/sysdev/ipic.c @@ -19,18 +19,15 @@ #include #include #include -#include -#include -#include #include #include -#include #include +#include #include "ipic.h" +static struct ipic p_ipic; static struct ipic * primary_ipic; -static DEFINE_SPINLOCK(ipic_lock); static struct ipic_info ipic_info[] = { [9] = { @@ -376,220 +373,74 @@ static inline void ipic_write(volatile u32 __iomem *base, unsigned int reg, u32 out_be32(base + (reg >> 2), value); } -static inline struct ipic * ipic_from_irq(unsigned int virq) +static inline struct ipic * ipic_from_irq(unsigned int irq) { return primary_ipic; } -#define ipic_irq_to_hw(virq) ((unsigned int)irq_map[virq].hwirq) - -static void ipic_unmask_irq(unsigned int virq) +static void ipic_enable_irq(unsigned int irq) { - struct ipic *ipic = ipic_from_irq(virq); - unsigned int src = ipic_irq_to_hw(virq); - unsigned long flags; + struct ipic *ipic = ipic_from_irq(irq); + unsigned int src = irq - ipic->irq_offset; u32 temp; - spin_lock_irqsave(&ipic_lock, flags); - temp = ipic_read(ipic->regs, ipic_info[src].mask); temp |= (1 << (31 - ipic_info[src].bit)); ipic_write(ipic->regs, ipic_info[src].mask, temp); - - spin_unlock_irqrestore(&ipic_lock, flags); } -static void ipic_mask_irq(unsigned int virq) +static void ipic_disable_irq(unsigned int irq) { - struct ipic *ipic = ipic_from_irq(virq); - unsigned int src = ipic_irq_to_hw(virq); - unsigned long flags; + struct ipic *ipic = ipic_from_irq(irq); + unsigned int src = irq - ipic->irq_offset; u32 temp; - spin_lock_irqsave(&ipic_lock, flags); - temp = ipic_read(ipic->regs, ipic_info[src].mask); temp &= ~(1 << (31 - ipic_info[src].bit)); ipic_write(ipic->regs, ipic_info[src].mask, temp); - - spin_unlock_irqrestore(&ipic_lock, flags); } -static void ipic_ack_irq(unsigned int virq) +static void ipic_disable_irq_and_ack(unsigned int irq) { - struct ipic *ipic = ipic_from_irq(virq); - unsigned int src = ipic_irq_to_hw(virq); - unsigned long flags; + struct ipic *ipic = ipic_from_irq(irq); + unsigned int src = irq - ipic->irq_offset; u32 temp; - spin_lock_irqsave(&ipic_lock, flags); + ipic_disable_irq(irq); temp = ipic_read(ipic->regs, ipic_info[src].pend); temp |= (1 << (31 - ipic_info[src].bit)); ipic_write(ipic->regs, ipic_info[src].pend, temp); - - spin_unlock_irqrestore(&ipic_lock, flags); } -static void ipic_mask_irq_and_ack(unsigned int virq) +static void ipic_end_irq(unsigned int irq) { - struct ipic *ipic = ipic_from_irq(virq); - unsigned int src = ipic_irq_to_hw(virq); - unsigned long flags; - u32 temp; - - spin_lock_irqsave(&ipic_lock, flags); - - temp = ipic_read(ipic->regs, ipic_info[src].mask); - temp &= ~(1 << (31 - ipic_info[src].bit)); - ipic_write(ipic->regs, ipic_info[src].mask, temp); - - temp = ipic_read(ipic->regs, ipic_info[src].pend); - temp |= (1 << (31 - ipic_info[src].bit)); - ipic_write(ipic->regs, ipic_info[src].pend, temp); - - spin_unlock_irqrestore(&ipic_lock, flags); + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + ipic_enable_irq(irq); } -static int ipic_set_irq_type(unsigned int virq, unsigned int flow_type) -{ - struct ipic *ipic = ipic_from_irq(virq); - unsigned int src = ipic_irq_to_hw(virq); - struct irq_desc *desc = get_irq_desc(virq); - unsigned int vold, vnew, edibit; - - if (flow_type == IRQ_TYPE_NONE) - flow_type = IRQ_TYPE_LEVEL_LOW; - - /* ipic supports only low assertion and high-to-low change senses - */ - if (!(flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_EDGE_FALLING))) { - printk(KERN_ERR "ipic: sense type 0x%x not supported\n", - flow_type); - return -EINVAL; - } - - desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL); - desc->status |= flow_type & IRQ_TYPE_SENSE_MASK; - if (flow_type & IRQ_TYPE_LEVEL_LOW) { - desc->status |= IRQ_LEVEL; - set_irq_handler(virq, handle_level_irq); - } else { - set_irq_handler(virq, handle_edge_irq); - } - - /* only EXT IRQ senses are programmable on ipic - * internal IRQ senses are LEVEL_LOW - */ - if (src == IPIC_IRQ_EXT0) - edibit = 15; - else - if (src >= IPIC_IRQ_EXT1 && src <= IPIC_IRQ_EXT7) - edibit = (14 - (src - IPIC_IRQ_EXT1)); - else - return (flow_type & IRQ_TYPE_LEVEL_LOW) ? 0 : -EINVAL; - - vold = ipic_read(ipic->regs, IPIC_SECNR); - if ((flow_type & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_FALLING) { - vnew = vold | (1 << edibit); - } else { - vnew = vold & ~(1 << edibit); - } - if (vold != vnew) - ipic_write(ipic->regs, IPIC_SECNR, vnew); - return 0; -} - -static struct irq_chip ipic_irq_chip = { - .typename = " IPIC ", - .unmask = ipic_unmask_irq, - .mask = ipic_mask_irq, - .mask_ack = ipic_mask_irq_and_ack, - .ack = ipic_ack_irq, - .set_type = ipic_set_irq_type, -}; - -static int ipic_host_match(struct irq_host *h, struct device_node *node) -{ - struct ipic *ipic = h->host_data; - - /* Exact match, unless ipic node is NULL */ - return ipic->of_node == NULL || ipic->of_node == node; -} - -static int ipic_host_map(struct irq_host *h, unsigned int virq, - irq_hw_number_t hw) -{ - struct ipic *ipic = h->host_data; - struct irq_chip *chip; - - /* Default chip */ - chip = &ipic->hc_irq; - - set_irq_chip_data(virq, ipic); - set_irq_chip_and_handler(virq, chip, handle_level_irq); - - /* Set default irq type */ - set_irq_type(virq, IRQ_TYPE_NONE); - - return 0; -} - -static int ipic_host_xlate(struct irq_host *h, struct device_node *ct, - u32 *intspec, unsigned int intsize, - irq_hw_number_t *out_hwirq, unsigned int *out_flags) - -{ - /* interrupt sense values coming from the device tree equal either - * LEVEL_LOW (low assertion) or EDGE_FALLING (high-to-low change) - */ - *out_hwirq = intspec[0]; - if (intsize > 1) - *out_flags = intspec[1]; - else - *out_flags = IRQ_TYPE_NONE; - return 0; -} - -static struct irq_host_ops ipic_host_ops = { - .match = ipic_host_match, - .map = ipic_host_map, - .xlate = ipic_host_xlate, +struct hw_interrupt_type ipic = { + .typename = " IPIC ", + .enable = ipic_enable_irq, + .disable = ipic_disable_irq, + .ack = ipic_disable_irq_and_ack, + .end = ipic_end_irq, }; -void __init ipic_init(struct device_node *node, - unsigned int flags) +void __init ipic_init(phys_addr_t phys_addr, + unsigned int flags, + unsigned int irq_offset, + unsigned char *senses, + unsigned int senses_count) { - struct ipic *ipic; - struct resource res; - u32 temp = 0, ret; - - ipic = alloc_bootmem(sizeof(struct ipic)); - if (ipic == NULL) - return; - - memset(ipic, 0, sizeof(struct ipic)); - ipic->of_node = node ? of_node_get(node) : NULL; - - ipic->irqhost = irq_alloc_host(IRQ_HOST_MAP_LINEAR, - NR_IPIC_INTS, - &ipic_host_ops, 0); - if (ipic->irqhost == NULL) { - of_node_put(node); - return; - } - - ret = of_address_to_resource(node, 0, &res); - if (ret) - return; + u32 i, temp = 0; - ipic->regs = ioremap(res.start, res.end - res.start + 1); + primary_ipic = &p_ipic; + primary_ipic->regs = ioremap(phys_addr, MPC83xx_IPIC_SIZE); - ipic->irqhost->host_data = ipic; - ipic->hc_irq = ipic_irq_chip; + primary_ipic->irq_offset = irq_offset; - /* init hw */ - ipic_write(ipic->regs, IPIC_SICNR, 0x0); + ipic_write(primary_ipic->regs, IPIC_SICNR, 0x0); /* default priority scheme is grouped. If spread mode is required * configure SICFR accordingly */ @@ -602,35 +453,49 @@ void __init ipic_init(struct device_node *node, if (flags & IPIC_SPREADMODE_MIX_B) temp |= SICFR_MPSB; - ipic_write(ipic->regs, IPIC_SICNR, temp); + ipic_write(primary_ipic->regs, IPIC_SICNR, temp); /* handle MCP route */ temp = 0; if (flags & IPIC_DISABLE_MCP_OUT) temp = SERCR_MCPR; - ipic_write(ipic->regs, IPIC_SERCR, temp); + ipic_write(primary_ipic->regs, IPIC_SERCR, temp); /* handle routing of IRQ0 to MCP */ - temp = ipic_read(ipic->regs, IPIC_SEMSR); + temp = ipic_read(primary_ipic->regs, IPIC_SEMSR); if (flags & IPIC_IRQ0_MCP) temp |= SEMSR_SIRQ0; else temp &= ~SEMSR_SIRQ0; - ipic_write(ipic->regs, IPIC_SEMSR, temp); + ipic_write(primary_ipic->regs, IPIC_SEMSR, temp); - primary_ipic = ipic; - irq_set_default_host(primary_ipic->irqhost); + for (i = 0 ; i < NR_IPIC_INTS ; i++) { + irq_desc[i+irq_offset].chip = &ipic; + irq_desc[i+irq_offset].status = IRQ_LEVEL; + } - printk ("IPIC (%d IRQ sources) at %p\n", NR_IPIC_INTS, - primary_ipic->regs); + temp = 0; + for (i = 0 ; i < senses_count ; i++) { + if ((senses[i] & IRQ_SENSE_MASK) == IRQ_SENSE_EDGE) { + temp |= 1 << (15 - i); + if (i != 0) + irq_desc[i + irq_offset + MPC83xx_IRQ_EXT1 - 1].status = 0; + else + irq_desc[irq_offset + MPC83xx_IRQ_EXT0].status = 0; + } + } + ipic_write(primary_ipic->regs, IPIC_SECNR, temp); + + printk ("IPIC (%d IRQ sources, %d External IRQs) at %p\n", NR_IPIC_INTS, + senses_count, primary_ipic->regs); } -int ipic_set_priority(unsigned int virq, unsigned int priority) +int ipic_set_priority(unsigned int irq, unsigned int priority) { - struct ipic *ipic = ipic_from_irq(virq); - unsigned int src = ipic_irq_to_hw(virq); + struct ipic *ipic = ipic_from_irq(irq); + unsigned int src = irq - ipic->irq_offset; u32 temp; if (priority > 7) @@ -655,10 +520,10 @@ int ipic_set_priority(unsigned int virq, unsigned int priority) return 0; } -void ipic_set_highest_priority(unsigned int virq) +void ipic_set_highest_priority(unsigned int irq) { - struct ipic *ipic = ipic_from_irq(virq); - unsigned int src = ipic_irq_to_hw(virq); + struct ipic *ipic = ipic_from_irq(irq); + unsigned int src = irq - ipic->irq_offset; u32 temp; temp = ipic_read(ipic->regs, IPIC_SICFR); @@ -672,10 +537,37 @@ void ipic_set_highest_priority(unsigned int virq) void ipic_set_default_priority(void) { - ipic_write(primary_ipic->regs, IPIC_SIPRR_A, IPIC_SIPRR_A_DEFAULT); - ipic_write(primary_ipic->regs, IPIC_SIPRR_D, IPIC_SIPRR_D_DEFAULT); - ipic_write(primary_ipic->regs, IPIC_SMPRR_A, IPIC_SMPRR_A_DEFAULT); - ipic_write(primary_ipic->regs, IPIC_SMPRR_B, IPIC_SMPRR_B_DEFAULT); + ipic_set_priority(MPC83xx_IRQ_TSEC1_TX, 0); + ipic_set_priority(MPC83xx_IRQ_TSEC1_RX, 1); + ipic_set_priority(MPC83xx_IRQ_TSEC1_ERROR, 2); + ipic_set_priority(MPC83xx_IRQ_TSEC2_TX, 3); + ipic_set_priority(MPC83xx_IRQ_TSEC2_RX, 4); + ipic_set_priority(MPC83xx_IRQ_TSEC2_ERROR, 5); + ipic_set_priority(MPC83xx_IRQ_USB2_DR, 6); + ipic_set_priority(MPC83xx_IRQ_USB2_MPH, 7); + + ipic_set_priority(MPC83xx_IRQ_UART1, 0); + ipic_set_priority(MPC83xx_IRQ_UART2, 1); + ipic_set_priority(MPC83xx_IRQ_SEC2, 2); + ipic_set_priority(MPC83xx_IRQ_IIC1, 5); + ipic_set_priority(MPC83xx_IRQ_IIC2, 6); + ipic_set_priority(MPC83xx_IRQ_SPI, 7); + ipic_set_priority(MPC83xx_IRQ_RTC_SEC, 0); + ipic_set_priority(MPC83xx_IRQ_PIT, 1); + ipic_set_priority(MPC83xx_IRQ_PCI1, 2); + ipic_set_priority(MPC83xx_IRQ_PCI2, 3); + ipic_set_priority(MPC83xx_IRQ_EXT0, 4); + ipic_set_priority(MPC83xx_IRQ_EXT1, 5); + ipic_set_priority(MPC83xx_IRQ_EXT2, 6); + ipic_set_priority(MPC83xx_IRQ_EXT3, 7); + ipic_set_priority(MPC83xx_IRQ_RTC_ALR, 0); + ipic_set_priority(MPC83xx_IRQ_MU, 1); + ipic_set_priority(MPC83xx_IRQ_SBA, 2); + ipic_set_priority(MPC83xx_IRQ_DMA, 3); + ipic_set_priority(MPC83xx_IRQ_EXT4, 4); + ipic_set_priority(MPC83xx_IRQ_EXT5, 5); + ipic_set_priority(MPC83xx_IRQ_EXT6, 6); + ipic_set_priority(MPC83xx_IRQ_EXT7, 7); } void ipic_enable_mcp(enum ipic_mcp_irq mcp_irq) @@ -708,20 +600,17 @@ void ipic_clear_mcp_status(u32 mask) ipic_write(primary_ipic->regs, IPIC_SERMR, mask); } -/* Return an interrupt vector or NO_IRQ if no interrupt is pending. */ -unsigned int ipic_get_irq(struct pt_regs *regs) +/* Return an interrupt vector or -1 if no interrupt is pending. */ +int ipic_get_irq(struct pt_regs *regs) { int irq; - BUG_ON(primary_ipic == NULL); - -#define IPIC_SIVCR_VECTOR_MASK 0x7f - irq = ipic_read(primary_ipic->regs, IPIC_SIVCR) & IPIC_SIVCR_VECTOR_MASK; + irq = ipic_read(primary_ipic->regs, IPIC_SIVCR) & 0x7f; if (irq == 0) /* 0 --> no irq is pending */ - return NO_IRQ; + irq = -1; - return irq_linear_revmap(primary_ipic->irqhost, irq); + return irq; } static struct sysdev_class ipic_sysclass = { diff --git a/trunk/arch/powerpc/sysdev/ipic.h b/trunk/arch/powerpc/sysdev/ipic.h index c28e589877eb..a60c9d18bb7f 100644 --- a/trunk/arch/powerpc/sysdev/ipic.h +++ b/trunk/arch/powerpc/sysdev/ipic.h @@ -15,18 +15,7 @@ #include -#define NR_IPIC_INTS 128 - -/* External IRQS */ -#define IPIC_IRQ_EXT0 48 -#define IPIC_IRQ_EXT1 17 -#define IPIC_IRQ_EXT7 23 - -/* Default Priority Registers */ -#define IPIC_SIPRR_A_DEFAULT 0x05309770 -#define IPIC_SIPRR_D_DEFAULT 0x05309770 -#define IPIC_SMPRR_A_DEFAULT 0x05309770 -#define IPIC_SMPRR_B_DEFAULT 0x05309770 +#define MPC83xx_IPIC_SIZE (0x00100) /* System Global Interrupt Configuration Register */ #define SICFR_IPSA 0x00010000 @@ -42,15 +31,7 @@ struct ipic { volatile u32 __iomem *regs; - - /* The remapper for this IPIC */ - struct irq_host *irqhost; - - /* The "linux" controller struct */ - struct irq_chip hc_irq; - - /* The device node of the interrupt controller */ - struct device_node *of_node; + unsigned int irq_offset; }; struct ipic_info { diff --git a/trunk/arch/powerpc/sysdev/mpic.c b/trunk/arch/powerpc/sysdev/mpic.c index b604926401f5..6e0281afa6c3 100644 --- a/trunk/arch/powerpc/sysdev/mpic.c +++ b/trunk/arch/powerpc/sysdev/mpic.c @@ -54,94 +54,6 @@ static DEFINE_SPINLOCK(mpic_lock); #endif #endif -#ifdef CONFIG_MPIC_WEIRD -static u32 mpic_infos[][MPIC_IDX_END] = { - [0] = { /* Original OpenPIC compatible MPIC */ - MPIC_GREG_BASE, - MPIC_GREG_FEATURE_0, - MPIC_GREG_GLOBAL_CONF_0, - MPIC_GREG_VENDOR_ID, - MPIC_GREG_IPI_VECTOR_PRI_0, - MPIC_GREG_IPI_STRIDE, - MPIC_GREG_SPURIOUS, - MPIC_GREG_TIMER_FREQ, - - MPIC_TIMER_BASE, - MPIC_TIMER_STRIDE, - MPIC_TIMER_CURRENT_CNT, - MPIC_TIMER_BASE_CNT, - MPIC_TIMER_VECTOR_PRI, - MPIC_TIMER_DESTINATION, - - MPIC_CPU_BASE, - MPIC_CPU_STRIDE, - MPIC_CPU_IPI_DISPATCH_0, - MPIC_CPU_IPI_DISPATCH_STRIDE, - MPIC_CPU_CURRENT_TASK_PRI, - MPIC_CPU_WHOAMI, - MPIC_CPU_INTACK, - MPIC_CPU_EOI, - - MPIC_IRQ_BASE, - MPIC_IRQ_STRIDE, - MPIC_IRQ_VECTOR_PRI, - MPIC_VECPRI_VECTOR_MASK, - MPIC_VECPRI_POLARITY_POSITIVE, - MPIC_VECPRI_POLARITY_NEGATIVE, - MPIC_VECPRI_SENSE_LEVEL, - MPIC_VECPRI_SENSE_EDGE, - MPIC_VECPRI_POLARITY_MASK, - MPIC_VECPRI_SENSE_MASK, - MPIC_IRQ_DESTINATION - }, - [1] = { /* Tsi108/109 PIC */ - TSI108_GREG_BASE, - TSI108_GREG_FEATURE_0, - TSI108_GREG_GLOBAL_CONF_0, - TSI108_GREG_VENDOR_ID, - TSI108_GREG_IPI_VECTOR_PRI_0, - TSI108_GREG_IPI_STRIDE, - TSI108_GREG_SPURIOUS, - TSI108_GREG_TIMER_FREQ, - - TSI108_TIMER_BASE, - TSI108_TIMER_STRIDE, - TSI108_TIMER_CURRENT_CNT, - TSI108_TIMER_BASE_CNT, - TSI108_TIMER_VECTOR_PRI, - TSI108_TIMER_DESTINATION, - - TSI108_CPU_BASE, - TSI108_CPU_STRIDE, - TSI108_CPU_IPI_DISPATCH_0, - TSI108_CPU_IPI_DISPATCH_STRIDE, - TSI108_CPU_CURRENT_TASK_PRI, - TSI108_CPU_WHOAMI, - TSI108_CPU_INTACK, - TSI108_CPU_EOI, - - TSI108_IRQ_BASE, - TSI108_IRQ_STRIDE, - TSI108_IRQ_VECTOR_PRI, - TSI108_VECPRI_VECTOR_MASK, - TSI108_VECPRI_POLARITY_POSITIVE, - TSI108_VECPRI_POLARITY_NEGATIVE, - TSI108_VECPRI_SENSE_LEVEL, - TSI108_VECPRI_SENSE_EDGE, - TSI108_VECPRI_POLARITY_MASK, - TSI108_VECPRI_SENSE_MASK, - TSI108_IRQ_DESTINATION - }, -}; - -#define MPIC_INFO(name) mpic->hw_set[MPIC_IDX_##name] - -#else /* CONFIG_MPIC_WEIRD */ - -#define MPIC_INFO(name) MPIC_##name - -#endif /* CONFIG_MPIC_WEIRD */ - /* * Register accessor functions */ @@ -168,8 +80,7 @@ static inline void _mpic_write(unsigned int be, volatile u32 __iomem *base, static inline u32 _mpic_ipi_read(struct mpic *mpic, unsigned int ipi) { unsigned int be = (mpic->flags & MPIC_BIG_ENDIAN) != 0; - unsigned int offset = MPIC_INFO(GREG_IPI_VECTOR_PRI_0) + - (ipi * MPIC_INFO(GREG_IPI_STRIDE)); + unsigned int offset = MPIC_GREG_IPI_VECTOR_PRI_0 + (ipi * 0x10); if (mpic->flags & MPIC_BROKEN_IPI) be = !be; @@ -178,8 +89,7 @@ static inline u32 _mpic_ipi_read(struct mpic *mpic, unsigned int ipi) static inline void _mpic_ipi_write(struct mpic *mpic, unsigned int ipi, u32 value) { - unsigned int offset = MPIC_INFO(GREG_IPI_VECTOR_PRI_0) + - (ipi * MPIC_INFO(GREG_IPI_STRIDE)); + unsigned int offset = MPIC_GREG_IPI_VECTOR_PRI_0 + (ipi * 0x10); _mpic_write(mpic->flags & MPIC_BIG_ENDIAN, mpic->gregs, offset, value); } @@ -210,7 +120,7 @@ static inline u32 _mpic_irq_read(struct mpic *mpic, unsigned int src_no, unsigne unsigned int idx = src_no & mpic->isu_mask; return _mpic_read(mpic->flags & MPIC_BIG_ENDIAN, mpic->isus[isu], - reg + (idx * MPIC_INFO(IRQ_STRIDE))); + reg + (idx * MPIC_IRQ_STRIDE)); } static inline void _mpic_irq_write(struct mpic *mpic, unsigned int src_no, @@ -220,7 +130,7 @@ static inline void _mpic_irq_write(struct mpic *mpic, unsigned int src_no, unsigned int idx = src_no & mpic->isu_mask; _mpic_write(mpic->flags & MPIC_BIG_ENDIAN, mpic->isus[isu], - reg + (idx * MPIC_INFO(IRQ_STRIDE)), value); + reg + (idx * MPIC_IRQ_STRIDE), value); } #define mpic_read(b,r) _mpic_read(mpic->flags & MPIC_BIG_ENDIAN,(b),(r)) @@ -246,8 +156,8 @@ static void __init mpic_test_broken_ipi(struct mpic *mpic) { u32 r; - mpic_write(mpic->gregs, MPIC_INFO(GREG_IPI_VECTOR_PRI_0), MPIC_VECPRI_MASK); - r = mpic_read(mpic->gregs, MPIC_INFO(GREG_IPI_VECTOR_PRI_0)); + mpic_write(mpic->gregs, MPIC_GREG_IPI_VECTOR_PRI_0, MPIC_VECPRI_MASK); + r = mpic_read(mpic->gregs, MPIC_GREG_IPI_VECTOR_PRI_0); if (r == le32_to_cpu(MPIC_VECPRI_MASK)) { printk(KERN_INFO "mpic: Detected reversed IPI registers\n"); @@ -484,8 +394,8 @@ static inline struct mpic * mpic_from_irq(unsigned int irq) /* Send an EOI */ static inline void mpic_eoi(struct mpic *mpic) { - mpic_cpu_write(MPIC_INFO(CPU_EOI), 0); - (void)mpic_cpu_read(MPIC_INFO(CPU_WHOAMI)); + mpic_cpu_write(MPIC_CPU_EOI, 0); + (void)mpic_cpu_read(MPIC_CPU_WHOAMI); } #ifdef CONFIG_SMP @@ -509,8 +419,8 @@ static void mpic_unmask_irq(unsigned int irq) DBG("%p: %s: enable_irq: %d (src %d)\n", mpic, mpic->name, irq, src); - mpic_irq_write(src, MPIC_INFO(IRQ_VECTOR_PRI), - mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) & + mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI, + mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) & ~MPIC_VECPRI_MASK); /* make sure mask gets to controller before we return to user */ do { @@ -518,7 +428,7 @@ static void mpic_unmask_irq(unsigned int irq) printk(KERN_ERR "mpic_enable_irq timeout\n"); break; } - } while(mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) & MPIC_VECPRI_MASK); + } while(mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) & MPIC_VECPRI_MASK); } static void mpic_mask_irq(unsigned int irq) @@ -529,8 +439,8 @@ static void mpic_mask_irq(unsigned int irq) DBG("%s: disable_irq: %d (src %d)\n", mpic->name, irq, src); - mpic_irq_write(src, MPIC_INFO(IRQ_VECTOR_PRI), - mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) | + mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI, + mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) | MPIC_VECPRI_MASK); /* make sure mask gets to controller before we return to user */ @@ -539,7 +449,7 @@ static void mpic_mask_irq(unsigned int irq) printk(KERN_ERR "mpic_enable_irq timeout\n"); break; } - } while(!(mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) & MPIC_VECPRI_MASK)); + } while(!(mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) & MPIC_VECPRI_MASK)); } static void mpic_end_irq(unsigned int irq) @@ -650,28 +560,24 @@ static void mpic_set_affinity(unsigned int irq, cpumask_t cpumask) cpus_and(tmp, cpumask, cpu_online_map); - mpic_irq_write(src, MPIC_INFO(IRQ_DESTINATION), + mpic_irq_write(src, MPIC_IRQ_DESTINATION, mpic_physmask(cpus_addr(tmp)[0])); } -static unsigned int mpic_type_to_vecpri(struct mpic *mpic, unsigned int type) +static unsigned int mpic_type_to_vecpri(unsigned int type) { /* Now convert sense value */ switch(type & IRQ_TYPE_SENSE_MASK) { case IRQ_TYPE_EDGE_RISING: - return MPIC_INFO(VECPRI_SENSE_EDGE) | - MPIC_INFO(VECPRI_POLARITY_POSITIVE); + return MPIC_VECPRI_SENSE_EDGE | MPIC_VECPRI_POLARITY_POSITIVE; case IRQ_TYPE_EDGE_FALLING: case IRQ_TYPE_EDGE_BOTH: - return MPIC_INFO(VECPRI_SENSE_EDGE) | - MPIC_INFO(VECPRI_POLARITY_NEGATIVE); + return MPIC_VECPRI_SENSE_EDGE | MPIC_VECPRI_POLARITY_NEGATIVE; case IRQ_TYPE_LEVEL_HIGH: - return MPIC_INFO(VECPRI_SENSE_LEVEL) | - MPIC_INFO(VECPRI_POLARITY_POSITIVE); + return MPIC_VECPRI_SENSE_LEVEL | MPIC_VECPRI_POLARITY_POSITIVE; case IRQ_TYPE_LEVEL_LOW: default: - return MPIC_INFO(VECPRI_SENSE_LEVEL) | - MPIC_INFO(VECPRI_POLARITY_NEGATIVE); + return MPIC_VECPRI_SENSE_LEVEL | MPIC_VECPRI_POLARITY_NEGATIVE; } } @@ -703,14 +609,13 @@ static int mpic_set_irq_type(unsigned int virq, unsigned int flow_type) vecpri = MPIC_VECPRI_POLARITY_POSITIVE | MPIC_VECPRI_SENSE_EDGE; else - vecpri = mpic_type_to_vecpri(mpic, flow_type); + vecpri = mpic_type_to_vecpri(flow_type); - vold = mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)); - vnew = vold & ~(MPIC_INFO(VECPRI_POLARITY_MASK) | - MPIC_INFO(VECPRI_SENSE_MASK)); + vold = mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI); + vnew = vold & ~(MPIC_VECPRI_POLARITY_MASK | MPIC_VECPRI_SENSE_MASK); vnew |= vecpri; if (vold != vnew) - mpic_irq_write(src, MPIC_INFO(IRQ_VECTOR_PRI), vnew); + mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI, vnew); return 0; } @@ -893,22 +798,17 @@ struct mpic * __init mpic_alloc(struct device_node *node, mpic->irq_count = irq_count; mpic->num_sources = 0; /* so far */ -#ifdef CONFIG_MPIC_WEIRD - mpic->hw_set = mpic_infos[MPIC_GET_REGSET(flags)]; -#endif - /* Map the global registers */ - mpic->gregs = ioremap(phys_addr + MPIC_INFO(GREG_BASE), 0x1000); - mpic->tmregs = mpic->gregs + - ((MPIC_INFO(TIMER_BASE) - MPIC_INFO(GREG_BASE)) >> 2); + mpic->gregs = ioremap(phys_addr + MPIC_GREG_BASE, 0x1000); + mpic->tmregs = mpic->gregs + ((MPIC_TIMER_BASE - MPIC_GREG_BASE) >> 2); BUG_ON(mpic->gregs == NULL); /* Reset */ if (flags & MPIC_WANTS_RESET) { - mpic_write(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0), - mpic_read(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0)) + mpic_write(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0, + mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0) | MPIC_GREG_GCONF_RESET); - while( mpic_read(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0)) + while( mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0) & MPIC_GREG_GCONF_RESET) mb(); } @@ -917,7 +817,7 @@ struct mpic * __init mpic_alloc(struct device_node *node, * MPICs, num sources as well. On ISU MPICs, sources are counted * as ISUs are added */ - reg = mpic_read(mpic->gregs, MPIC_INFO(GREG_FEATURE_0)); + reg = mpic_read(mpic->gregs, MPIC_GREG_FEATURE_0); mpic->num_cpus = ((reg & MPIC_GREG_FEATURE_LAST_CPU_MASK) >> MPIC_GREG_FEATURE_LAST_CPU_SHIFT) + 1; if (isu_size == 0) @@ -926,16 +826,16 @@ struct mpic * __init mpic_alloc(struct device_node *node, /* Map the per-CPU registers */ for (i = 0; i < mpic->num_cpus; i++) { - mpic->cpuregs[i] = ioremap(phys_addr + MPIC_INFO(CPU_BASE) + - i * MPIC_INFO(CPU_STRIDE), 0x1000); + mpic->cpuregs[i] = ioremap(phys_addr + MPIC_CPU_BASE + + i * MPIC_CPU_STRIDE, 0x1000); BUG_ON(mpic->cpuregs[i] == NULL); } /* Initialize main ISU if none provided */ if (mpic->isu_size == 0) { mpic->isu_size = mpic->num_sources; - mpic->isus[0] = ioremap(phys_addr + MPIC_INFO(IRQ_BASE), - MPIC_INFO(IRQ_STRIDE) * mpic->isu_size); + mpic->isus[0] = ioremap(phys_addr + MPIC_IRQ_BASE, + MPIC_IRQ_STRIDE * mpic->isu_size); BUG_ON(mpic->isus[0] == NULL); } mpic->isu_shift = 1 + __ilog2(mpic->isu_size - 1); @@ -979,8 +879,7 @@ void __init mpic_assign_isu(struct mpic *mpic, unsigned int isu_num, BUG_ON(isu_num >= MPIC_MAX_ISU); - mpic->isus[isu_num] = ioremap(phys_addr, - MPIC_INFO(IRQ_STRIDE) * mpic->isu_size); + mpic->isus[isu_num] = ioremap(phys_addr, MPIC_IRQ_STRIDE * mpic->isu_size); if ((isu_first + mpic->isu_size) > mpic->num_sources) mpic->num_sources = isu_first + mpic->isu_size; } @@ -1005,16 +904,14 @@ void __init mpic_init(struct mpic *mpic) printk(KERN_INFO "mpic: Initializing for %d sources\n", mpic->num_sources); /* Set current processor priority to max */ - mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0xf); + mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, 0xf); /* Initialize timers: just disable them all */ for (i = 0; i < 4; i++) { mpic_write(mpic->tmregs, - i * MPIC_INFO(TIMER_STRIDE) + - MPIC_INFO(TIMER_DESTINATION), 0); + i * MPIC_TIMER_STRIDE + MPIC_TIMER_DESTINATION, 0); mpic_write(mpic->tmregs, - i * MPIC_INFO(TIMER_STRIDE) + - MPIC_INFO(TIMER_VECTOR_PRI), + i * MPIC_TIMER_STRIDE + MPIC_TIMER_VECTOR_PRI, MPIC_VECPRI_MASK | (MPIC_VEC_TIMER_0 + i)); } @@ -1043,22 +940,21 @@ void __init mpic_init(struct mpic *mpic) (8 << MPIC_VECPRI_PRIORITY_SHIFT); /* init hw */ - mpic_irq_write(i, MPIC_INFO(IRQ_VECTOR_PRI), vecpri); - mpic_irq_write(i, MPIC_INFO(IRQ_DESTINATION), + mpic_irq_write(i, MPIC_IRQ_VECTOR_PRI, vecpri); + mpic_irq_write(i, MPIC_IRQ_DESTINATION, 1 << hard_smp_processor_id()); } /* Init spurrious vector */ - mpic_write(mpic->gregs, MPIC_INFO(GREG_SPURIOUS), MPIC_VEC_SPURRIOUS); + mpic_write(mpic->gregs, MPIC_GREG_SPURIOUS, MPIC_VEC_SPURRIOUS); - /* Disable 8259 passthrough, if supported */ - if (!(mpic->flags & MPIC_NO_PTHROU_DIS)) - mpic_write(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0), - mpic_read(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0)) - | MPIC_GREG_GCONF_8259_PTHROU_DIS); + /* Disable 8259 passthrough */ + mpic_write(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0, + mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0) + | MPIC_GREG_GCONF_8259_PTHROU_DIS); /* Set current processor priority to 0 */ - mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0); + mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, 0); } void __init mpic_set_clk_ratio(struct mpic *mpic, u32 clock_ratio) @@ -1101,9 +997,9 @@ void mpic_irq_set_priority(unsigned int irq, unsigned int pri) mpic_ipi_write(src - MPIC_VEC_IPI_0, reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT)); } else { - reg = mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) + reg = mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) & ~MPIC_VECPRI_PRIORITY_MASK; - mpic_irq_write(src, MPIC_INFO(IRQ_VECTOR_PRI), + mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI, reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT)); } spin_unlock_irqrestore(&mpic_lock, flags); @@ -1121,7 +1017,7 @@ unsigned int mpic_irq_get_priority(unsigned int irq) if (is_ipi) reg = mpic_ipi_read(src = MPIC_VEC_IPI_0); else - reg = mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)); + reg = mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI); spin_unlock_irqrestore(&mpic_lock, flags); return (reg & MPIC_VECPRI_PRIORITY_MASK) >> MPIC_VECPRI_PRIORITY_SHIFT; } @@ -1147,12 +1043,12 @@ void mpic_setup_this_cpu(void) */ if (distribute_irqs) { for (i = 0; i < mpic->num_sources ; i++) - mpic_irq_write(i, MPIC_INFO(IRQ_DESTINATION), - mpic_irq_read(i, MPIC_INFO(IRQ_DESTINATION)) | msk); + mpic_irq_write(i, MPIC_IRQ_DESTINATION, + mpic_irq_read(i, MPIC_IRQ_DESTINATION) | msk); } /* Set current processor priority to 0 */ - mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0); + mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, 0); spin_unlock_irqrestore(&mpic_lock, flags); #endif /* CONFIG_SMP */ @@ -1162,7 +1058,7 @@ int mpic_cpu_get_priority(void) { struct mpic *mpic = mpic_primary; - return mpic_cpu_read(MPIC_INFO(CPU_CURRENT_TASK_PRI)); + return mpic_cpu_read(MPIC_CPU_CURRENT_TASK_PRI); } void mpic_cpu_set_priority(int prio) @@ -1170,7 +1066,7 @@ void mpic_cpu_set_priority(int prio) struct mpic *mpic = mpic_primary; prio &= MPIC_CPU_TASKPRI_MASK; - mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), prio); + mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, prio); } /* @@ -1192,11 +1088,11 @@ void mpic_teardown_this_cpu(int secondary) /* let the mpic know we don't want intrs. */ for (i = 0; i < mpic->num_sources ; i++) - mpic_irq_write(i, MPIC_INFO(IRQ_DESTINATION), - mpic_irq_read(i, MPIC_INFO(IRQ_DESTINATION)) & ~msk); + mpic_irq_write(i, MPIC_IRQ_DESTINATION, + mpic_irq_read(i, MPIC_IRQ_DESTINATION) & ~msk); /* Set current processor priority to max */ - mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0xf); + mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, 0xf); spin_unlock_irqrestore(&mpic_lock, flags); } @@ -1212,8 +1108,7 @@ void mpic_send_ipi(unsigned int ipi_no, unsigned int cpu_mask) DBG("%s: send_ipi(ipi_no: %d)\n", mpic->name, ipi_no); #endif - mpic_cpu_write(MPIC_INFO(CPU_IPI_DISPATCH_0) + - ipi_no * MPIC_INFO(CPU_IPI_DISPATCH_STRIDE), + mpic_cpu_write(MPIC_CPU_IPI_DISPATCH_0 + ipi_no * 0x10, mpic_physmask(cpu_mask & cpus_addr(cpu_online_map)[0])); } @@ -1221,7 +1116,7 @@ unsigned int mpic_get_one_irq(struct mpic *mpic, struct pt_regs *regs) { u32 src; - src = mpic_cpu_read(MPIC_INFO(CPU_INTACK)) & MPIC_INFO(VECPRI_VECTOR_MASK); + src = mpic_cpu_read(MPIC_CPU_INTACK) & MPIC_VECPRI_VECTOR_MASK; #ifdef DEBUG_LOW DBG("%s: get_one_irq(): %d\n", mpic->name, src); #endif diff --git a/trunk/arch/powerpc/sysdev/tsi108_dev.c b/trunk/arch/powerpc/sysdev/tsi108_dev.c index f3038461d4c0..26a0cc820cde 100644 --- a/trunk/arch/powerpc/sysdev/tsi108_dev.c +++ b/trunk/arch/powerpc/sysdev/tsi108_dev.c @@ -93,15 +93,13 @@ static int __init tsi108_eth_of_init(void) goto err; r[1].name = "tx"; - r[1].start = irq_of_parse_and_map(np, 0); - r[1].end = irq_of_parse_and_map(np, 0); + r[1].start = np->intrs[0].line; + r[1].end = np->intrs[0].line; r[1].flags = IORESOURCE_IRQ; - DBG("%s: name:start->end = %s:0x%lx-> 0x%lx\n", - __FUNCTION__,r[1].name, r[1].start, r[1].end); tsi_eth_dev = platform_device_register_simple("tsi-ethernet", i, &r[0], - 1); + np->n_intrs + 1); if (IS_ERR(tsi_eth_dev)) { ret = PTR_ERR(tsi_eth_dev); @@ -129,7 +127,7 @@ static int __init tsi108_eth_of_init(void) tsi_eth_data.regs = r[0].start; tsi_eth_data.phyregs = res.start; tsi_eth_data.phy = *phy_id; - tsi_eth_data.irq_num = irq_of_parse_and_map(np, 0); + tsi_eth_data.irq_num = np->intrs[0].line; of_node_put(phy); ret = platform_device_add_data(tsi_eth_dev, &tsi_eth_data, diff --git a/trunk/arch/powerpc/sysdev/tsi108_pci.c b/trunk/arch/powerpc/sysdev/tsi108_pci.c index 2ab06ed3ae73..3265d54c82ed 100644 --- a/trunk/arch/powerpc/sysdev/tsi108_pci.c +++ b/trunk/arch/powerpc/sysdev/tsi108_pci.c @@ -26,6 +26,7 @@ #include #include + #include #include #include @@ -227,7 +228,7 @@ int __init tsi108_setup_pci(struct device_node *dev) (hose)->ops = &tsi108_direct_pci_ops; - printk(KERN_INFO "Found tsi108 PCI host bridge at 0x%08x. " + printk(KERN_INFO "Found tsi108 PCI host bridge at 0x%08lx. " "Firmware bus number: %d->%d\n", rsrc.start, hose->first_busno, hose->last_busno); @@ -277,7 +278,7 @@ static void init_pci_source(void) mb(); } -static inline unsigned int get_pci_source(void) +static inline int get_pci_source(void) { u_int temp = 0; int irq = -1; @@ -370,12 +371,12 @@ static void tsi108_pci_irq_end(u_int irq) * Interrupt controller descriptor for cascaded PCI interrupt controller. */ -static struct irq_chip tsi108_pci_irq = { +struct hw_interrupt_type tsi108_pci_irq = { .typename = "tsi108_PCI_int", - .mask = tsi108_pci_irq_disable, + .enable = tsi108_pci_irq_enable, + .disable = tsi108_pci_irq_disable, .ack = tsi108_pci_irq_ack, .end = tsi108_pci_irq_end, - .unmask = tsi108_pci_irq_enable, }; /* @@ -398,18 +399,14 @@ void __init tsi108_pci_int_init(void) DBG("Tsi108_pci_int_init: initializing PCI interrupts\n"); for (i = 0; i < NUM_PCI_IRQS; i++) { - irq_desc[i + IRQ_PCI_INTAD_BASE].chip = &tsi108_pci_irq; + irq_desc[i + IRQ_PCI_INTAD_BASE].handler = &tsi108_pci_irq; irq_desc[i + IRQ_PCI_INTAD_BASE].status |= IRQ_LEVEL; } init_pci_source(); } -void tsi108_irq_cascade(unsigned int irq, struct irq_desc *desc, - struct pt_regs *regs) +int tsi108_irq_cascade(struct pt_regs *regs, void *unused) { - unsigned int cascade_irq = get_pci_source(); - if (cascade_irq != NO_IRQ) - generic_handle_irq(cascade_irq, regs); - desc->chip->eoi(irq); + return get_pci_source(); } diff --git a/trunk/arch/ppc/kernel/smp-tbsync.c b/trunk/arch/ppc/kernel/smp-tbsync.c index d0cf3f86931d..1576758debaf 100644 --- a/trunk/arch/ppc/kernel/smp-tbsync.c +++ b/trunk/arch/ppc/kernel/smp-tbsync.c @@ -47,9 +47,8 @@ void __devinit smp_generic_take_timebase( void ) { int cmd, tbl, tbu; - unsigned long flags; - local_irq_save(flags); + local_irq_disable(); while( !running ) ; rmb(); @@ -65,7 +64,7 @@ smp_generic_take_timebase( void ) tbu = tbsync->tbu; tbsync->ack = 0; if( cmd == kExit ) - break; + return; if( cmd == kSetAndTest ) { while( tbsync->handshake ) @@ -78,7 +77,7 @@ smp_generic_take_timebase( void ) } enter_contest( tbsync->mark, -1 ); } - local_irq_restore(flags); + local_irq_enable(); } static int __devinit diff --git a/trunk/arch/ppc/platforms/85xx/mpc8560_ads.c b/trunk/arch/ppc/platforms/85xx/mpc8560_ads.c index 94badafe4ef1..d90cd24d018e 100644 --- a/trunk/arch/ppc/platforms/85xx/mpc8560_ads.c +++ b/trunk/arch/ppc/platforms/85xx/mpc8560_ads.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include @@ -59,71 +58,6 @@ * Setup the architecture * */ -static void init_fcc_ioports(void) -{ - struct immap *immap; - struct io_port *io; - u32 tempval; - - immap = cpm2_immr; - - io = &immap->im_ioport; - /* FCC2/3 are on the ports B/C. */ - tempval = in_be32(&io->iop_pdirb); - tempval &= ~PB2_DIRB0; - tempval |= PB2_DIRB1; - out_be32(&io->iop_pdirb, tempval); - - tempval = in_be32(&io->iop_psorb); - tempval &= ~PB2_PSORB0; - tempval |= PB2_PSORB1; - out_be32(&io->iop_psorb, tempval); - - tempval = in_be32(&io->iop_pparb); - tempval |= (PB2_DIRB0 | PB2_DIRB1); - out_be32(&io->iop_pparb, tempval); - - tempval = in_be32(&io->iop_pdirb); - tempval &= ~PB3_DIRB0; - tempval |= PB3_DIRB1; - out_be32(&io->iop_pdirb, tempval); - - tempval = in_be32(&io->iop_psorb); - tempval &= ~PB3_PSORB0; - tempval |= PB3_PSORB1; - out_be32(&io->iop_psorb, tempval); - - tempval = in_be32(&io->iop_pparb); - tempval |= (PB3_DIRB0 | PB3_DIRB1); - out_be32(&io->iop_pparb, tempval); - - tempval = in_be32(&io->iop_pdirc); - tempval |= PC3_DIRC1; - out_be32(&io->iop_pdirc, tempval); - - tempval = in_be32(&io->iop_pparc); - tempval |= PC3_DIRC1; - out_be32(&io->iop_pparc, tempval); - - /* Port C has clocks...... */ - tempval = in_be32(&io->iop_psorc); - tempval &= ~(CLK_TRX); - out_be32(&io->iop_psorc, tempval); - - tempval = in_be32(&io->iop_pdirc); - tempval &= ~(CLK_TRX); - out_be32(&io->iop_pdirc, tempval); - tempval = in_be32(&io->iop_pparc); - tempval |= (CLK_TRX); - out_be32(&io->iop_pparc, tempval); - - /* Configure Serial Interface clock routing. - * First, clear all FCC bits to zero, - * then set the ones we want. - */ - immap->im_cpmux.cmx_fcr &= ~(CPMUX_CLK_MASK); - immap->im_cpmux.cmx_fcr |= CPMUX_CLK_ROUTE; -} static void __init mpc8560ads_setup_arch(void) @@ -132,7 +66,6 @@ mpc8560ads_setup_arch(void) unsigned int freq; struct gianfar_platform_data *pdata; struct gianfar_mdio_data *mdata; - struct fs_platform_info *fpi; cpm2_reset(); @@ -177,28 +110,6 @@ mpc8560ads_setup_arch(void) memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6); } - init_fcc_ioports(); - ppc_sys_device_remove(MPC85xx_CPM_FCC1); - - fpi = (struct fs_platform_info *) ppc_sys_get_pdata(MPC85xx_CPM_FCC2); - if (fpi) { - memcpy(fpi->macaddr, binfo->bi_enet2addr, 6); - fpi->bus_id = "0:02"; - fpi->phy_addr = 2; - fpi->dpram_offset = (u32)cpm2_immr->im_dprambase; - fpi->fcc_regs_c = (u32)&cpm2_immr->im_fcc_c[1]; - } - - fpi = (struct fs_platform_info *) ppc_sys_get_pdata(MPC85xx_CPM_FCC3); - if (fpi) { - memcpy(fpi->macaddr, binfo->bi_enet2addr, 6); - fpi->macaddr[5] += 1; - fpi->bus_id = "0:03"; - fpi->phy_addr = 3; - fpi->dpram_offset = (u32)cpm2_immr->im_dprambase; - fpi->fcc_regs_c = (u32)&cpm2_immr->im_fcc_c[2]; - } - #ifdef CONFIG_BLK_DEV_INITRD if (initrd_start) ROOT_DEV = Root_RAM0; diff --git a/trunk/arch/ppc/platforms/85xx/mpc85xx_ads_common.h b/trunk/arch/ppc/platforms/85xx/mpc85xx_ads_common.h index c8c322fe3680..abf32281655d 100644 --- a/trunk/arch/ppc/platforms/85xx/mpc85xx_ads_common.h +++ b/trunk/arch/ppc/platforms/85xx/mpc85xx_ads_common.h @@ -45,23 +45,4 @@ extern void mpc85xx_ads_map_io(void) __init; #define MPC85XX_PCI1_IO_SIZE 0x01000000 -/* FCC1 Clock Source Configuration. These can be - * redefined in the board specific file. - * Can only choose from CLK9-12 */ -#define F1_RXCLK 12 -#define F1_TXCLK 11 - -/* FCC2 Clock Source Configuration. These can be - * redefined in the board specific file. - * Can only choose from CLK13-16 */ -#define F2_RXCLK 13 -#define F2_TXCLK 14 - -/* FCC3 Clock Source Configuration. These can be - * redefined in the board specific file. - * Can only choose from CLK13-16 */ -#define F3_RXCLK 15 -#define F3_TXCLK 16 - - #endif /* __MACH_MPC85XX_ADS_H__ */ diff --git a/trunk/arch/ppc/platforms/mpc8272ads_setup.c b/trunk/arch/ppc/platforms/mpc8272ads_setup.c index 2a35fe2b9b96..abb7154de2c7 100644 --- a/trunk/arch/ppc/platforms/mpc8272ads_setup.c +++ b/trunk/arch/ppc/platforms/mpc8272ads_setup.c @@ -56,51 +56,64 @@ static struct fs_uart_platform_info mpc8272_uart_pdata[] = { }, }; -static struct fs_mii_bb_platform_info m82xx_mii_bb_pdata = { - .mdio_dat.bit = 18, - .mdio_dir.bit = 18, - .mdc_dat.bit = 19, - .delay = 1, +static struct fs_mii_bus_info mii_bus_info = { + .method = fsmii_bitbang, + .id = 0, + .i.bitbang = { + .mdio_port = fsiop_portc, + .mdio_bit = 18, + .mdc_port = fsiop_portc, + .mdc_bit = 19, + .delay = 1, + }, }; -static struct fs_platform_info mpc82xx_enet_pdata[] = { - [fsid_fcc1] = { - .fs_no = fsid_fcc1, - .cp_page = CPM_CR_FCC1_PAGE, - .cp_block = CPM_CR_FCC1_SBLOCK, - - .clk_trx = (PC_F1RXCLK | PC_F1TXCLK), - .clk_route = CMX1_CLK_ROUTE, - .clk_mask = CMX1_CLK_MASK, - .init_ioports = init_fcc1_ioports, - - .mem_offset = FCC1_MEM_OFFSET, - - .rx_ring = 32, - .tx_ring = 32, - .rx_copybreak = 240, - .use_napi = 0, - .napi_weight = 17, - .bus_id = "0:00", - }, - [fsid_fcc2] = { - .fs_no = fsid_fcc2, - .cp_page = CPM_CR_FCC2_PAGE, - .cp_block = CPM_CR_FCC2_SBLOCK, - .clk_trx = (PC_F2RXCLK | PC_F2TXCLK), - .clk_route = CMX2_CLK_ROUTE, - .clk_mask = CMX2_CLK_MASK, - .init_ioports = init_fcc2_ioports, - - .mem_offset = FCC2_MEM_OFFSET, - - .rx_ring = 32, - .tx_ring = 32, - .rx_copybreak = 240, - .use_napi = 0, - .napi_weight = 17, - .bus_id = "0:03", - }, +static struct fs_platform_info mpc82xx_fcc1_pdata = { + .fs_no = fsid_fcc1, + .cp_page = CPM_CR_FCC1_PAGE, + .cp_block = CPM_CR_FCC1_SBLOCK, + .clk_trx = (PC_F1RXCLK | PC_F1TXCLK), + .clk_route = CMX1_CLK_ROUTE, + .clk_mask = CMX1_CLK_MASK, + .init_ioports = init_fcc1_ioports, + + .phy_addr = 0, +#ifdef PHY_INTERRUPT + .phy_irq = PHY_INTERRUPT, +#else + .phy_irq = -1; +#endif + .mem_offset = FCC1_MEM_OFFSET, + .bus_info = &mii_bus_info, + .rx_ring = 32, + .tx_ring = 32, + .rx_copybreak = 240, + .use_napi = 0, + .napi_weight = 17, +}; + +static struct fs_platform_info mpc82xx_fcc2_pdata = { + .fs_no = fsid_fcc2, + .cp_page = CPM_CR_FCC2_PAGE, + .cp_block = CPM_CR_FCC2_SBLOCK, + .clk_trx = (PC_F2RXCLK | PC_F2TXCLK), + .clk_route = CMX2_CLK_ROUTE, + .clk_mask = CMX2_CLK_MASK, + .init_ioports = init_fcc2_ioports, + + .phy_addr = 3, +#ifdef PHY_INTERRUPT + .phy_irq = PHY_INTERRUPT, +#else + .phy_irq = -1; +#endif + .mem_offset = FCC2_MEM_OFFSET, + .bus_info = &mii_bus_info, + .rx_ring = 32, + .tx_ring = 32, + .rx_copybreak = 240, + .use_napi = 0, + .napi_weight = 17, }; static void init_fcc1_ioports(void) @@ -196,21 +209,20 @@ static void __init mpc8272ads_fixup_enet_pdata(struct platform_device *pdev, bd_t* bi = (void*)__res; int fs_no = fsid_fcc1+pdev->id-1; - if(fs_no > ARRAY_SIZE(mpc82xx_enet_pdata)) { - return; + mpc82xx_fcc1_pdata.dpram_offset = mpc82xx_fcc2_pdata.dpram_offset = (u32)cpm2_immr->im_dprambase; + mpc82xx_fcc1_pdata.fcc_regs_c = mpc82xx_fcc2_pdata.fcc_regs_c = (u32)cpm2_immr->im_fcc_c; + + switch(fs_no) { + case fsid_fcc1: + memcpy(&mpc82xx_fcc1_pdata.macaddr,bi->bi_enetaddr,6); + pdev->dev.platform_data = &mpc82xx_fcc1_pdata; + break; + case fsid_fcc2: + memcpy(&mpc82xx_fcc2_pdata.macaddr,bi->bi_enetaddr,6); + mpc82xx_fcc2_pdata.macaddr[5] ^= 1; + pdev->dev.platform_data = &mpc82xx_fcc2_pdata; + break; } - - mpc82xx_enet_pdata[fs_no].dpram_offset= - (u32)cpm2_immr->im_dprambase; - mpc82xx_enet_pdata[fs_no].fcc_regs_c = - (u32)cpm2_immr->im_fcc_c; - memcpy(&mpc82xx_enet_pdata[fs_no].macaddr,bi->bi_enetaddr,6); - - /* prevent dup mac */ - if(fs_no == fsid_fcc2) - mpc82xx_enet_pdata[fs_no].macaddr[5] ^= 1; - - pdev->dev.platform_data = &mpc82xx_enet_pdata[fs_no]; } static void mpc8272ads_fixup_uart_pdata(struct platform_device *pdev, @@ -262,29 +274,6 @@ static void init_scc4_uart_ioports(void) iounmap(immap); } -static void __init mpc8272ads_fixup_mdio_pdata(struct platform_device *pdev, - int idx) -{ - m82xx_mii_bb_pdata.irq[0] = PHY_INTERRUPT; - m82xx_mii_bb_pdata.irq[1] = -1; - m82xx_mii_bb_pdata.irq[2] = -1; - m82xx_mii_bb_pdata.irq[3] = PHY_INTERRUPT; - m82xx_mii_bb_pdata.irq[31] = -1; - - - m82xx_mii_bb_pdata.mdio_dat.offset = - (u32)&cpm2_immr->im_ioport.iop_pdatc; - - m82xx_mii_bb_pdata.mdio_dir.offset = - (u32)&cpm2_immr->im_ioport.iop_pdirc; - - m82xx_mii_bb_pdata.mdc_dat.offset = - (u32)&cpm2_immr->im_ioport.iop_pdatc; - - - pdev->dev.platform_data = &m82xx_mii_bb_pdata; -} - static int mpc8272ads_platform_notify(struct device *dev) { static const struct platform_notify_dev_map dev_map[] = { @@ -296,10 +285,6 @@ static int mpc8272ads_platform_notify(struct device *dev) .bus_id = "fsl-cpm-scc:uart", .rtn = mpc8272ads_fixup_uart_pdata, }, - { - .bus_id = "fsl-bb-mdio", - .rtn = mpc8272ads_fixup_mdio_pdata, - }, { .bus_id = NULL } @@ -334,7 +319,6 @@ int __init mpc8272ads_init(void) ppc_sys_device_enable(MPC82xx_CPM_SCC4); #endif - ppc_sys_device_enable(MPC82xx_MDIO_BB); return 0; } diff --git a/trunk/arch/ppc/platforms/mpc866ads_setup.c b/trunk/arch/ppc/platforms/mpc866ads_setup.c index e12cece4c9fd..f19b6167c770 100644 --- a/trunk/arch/ppc/platforms/mpc866ads_setup.c +++ b/trunk/arch/ppc/platforms/mpc866ads_setup.c @@ -1,10 +1,10 @@ -/*arch/ppc/platforms/mpc866ads-setup.c +/*arch/ppc/platforms/mpc885ads-setup.c * - * Platform setup for the Freescale mpc866ads board + * Platform setup for the Freescale mpc885ads board * * Vitaly Bordug * - * Copyright 2005-2006 MontaVista Software Inc. + * Copyright 2005 MontaVista Software Inc. * * This file is licensed under the terms of the GNU General Public License * version 2. This program is licensed "as is" without any warranty of any @@ -42,36 +42,49 @@ static void setup_scc1_ioports(void); static void setup_smc1_ioports(void); static void setup_smc2_ioports(void); -static struct fs_mii_fec_platform_info mpc8xx_mdio_fec_pdata; +static struct fs_mii_bus_info fec_mii_bus_info = { + .method = fsmii_fec, + .id = 0, +}; + +static struct fs_mii_bus_info scc_mii_bus_info = { + .method = fsmii_fixed, + .id = 0, + .i.fixed.speed = 10, + .i.fixed.duplex = 0, +}; -static struct fs_mii_fec_platform_info mpc8xx_mdio_fec_pdata; +static struct fs_platform_info mpc8xx_fec_pdata[] = { + { + .rx_ring = 128, + .tx_ring = 16, + .rx_copybreak = 240, -static struct fs_platform_info mpc8xx_enet_pdata[] = { - [fsid_fec1] = { - .rx_ring = 128, - .tx_ring = 16, - .rx_copybreak = 240, + .use_napi = 1, + .napi_weight = 17, - .use_napi = 1, - .napi_weight = 17, + .phy_addr = 15, + .phy_irq = -1, - .init_ioports = setup_fec1_ioports, + .use_rmii = 0, - .bus_id = "0:0f", - .has_phy = 1, - }, - [fsid_scc1] = { - .rx_ring = 64, - .tx_ring = 8, - .rx_copybreak = 240, - .use_napi = 1, - .napi_weight = 17, + .bus_info = &fec_mii_bus_info, + } +}; +static struct fs_platform_info mpc8xx_scc_pdata = { + .rx_ring = 64, + .tx_ring = 8, + .rx_copybreak = 240, - .init_ioports = setup_scc1_ioports, + .use_napi = 1, + .napi_weight = 17, + + .phy_addr = -1, + .phy_irq = -1, + + .bus_info = &scc_mii_bus_info, - .bus_id = "fixed@100:1", - }, }; static struct fs_uart_platform_info mpc866_uart_pdata[] = { @@ -194,6 +207,63 @@ static void setup_scc1_ioports(void) } +static void mpc866ads_fixup_enet_pdata(struct platform_device *pdev, int fs_no) +{ + struct fs_platform_info *fpi = pdev->dev.platform_data; + + volatile cpm8xx_t *cp; + bd_t *bd = (bd_t *) __res; + char *e; + int i; + + /* Get pointer to Communication Processor */ + cp = cpmp; + switch (fs_no) { + case fsid_fec1: + fpi = &mpc8xx_fec_pdata[0]; + fpi->init_ioports = &setup_fec1_ioports; + + break; + case fsid_scc1: + fpi = &mpc8xx_scc_pdata; + fpi->init_ioports = &setup_scc1_ioports; + + break; + default: + printk(KERN_WARNING"Device %s is not supported!\n", pdev->name); + return; + } + + pdev->dev.platform_data = fpi; + fpi->fs_no = fs_no; + + e = (unsigned char *)&bd->bi_enetaddr; + for (i = 0; i < 6; i++) + fpi->macaddr[i] = *e++; + + fpi->macaddr[5 - pdev->id]++; + +} + +static void mpc866ads_fixup_fec_enet_pdata(struct platform_device *pdev, + int idx) +{ + /* This is for FEC devices only */ + if (!pdev || !pdev->name || (!strstr(pdev->name, "fsl-cpm-fec"))) + return; + mpc866ads_fixup_enet_pdata(pdev, fsid_fec1 + pdev->id - 1); +} + +static void mpc866ads_fixup_scc_enet_pdata(struct platform_device *pdev, + int idx) +{ + /* This is for SCC devices only */ + if (!pdev || !pdev->name || (!strstr(pdev->name, "fsl-cpm-scc"))) + return; + + mpc866ads_fixup_enet_pdata(pdev, fsid_scc1 + pdev->id - 1); +} + static void setup_smc1_ioports(void) { immap_t *immap = (immap_t *) IMAP_ADDR; @@ -245,56 +315,6 @@ static void setup_smc2_ioports(void) } -static int ma_count = 0; - -static void mpc866ads_fixup_enet_pdata(struct platform_device *pdev, int fs_no) -{ - struct fs_platform_info *fpi; - - volatile cpm8xx_t *cp; - bd_t *bd = (bd_t *) __res; - char *e; - int i; - - /* Get pointer to Communication Processor */ - cp = cpmp; - - if(fs_no > ARRAY_SIZE(mpc8xx_enet_pdata)) { - printk(KERN_ERR"No network-suitable #%d device on bus", fs_no); - return; - } - - - fpi = &mpc8xx_enet_pdata[fs_no]; - fpi->fs_no = fs_no; - pdev->dev.platform_data = fpi; - - e = (unsigned char *)&bd->bi_enetaddr; - for (i = 0; i < 6; i++) - fpi->macaddr[i] = *e++; - - fpi->macaddr[5] += ma_count++; -} - -static void mpc866ads_fixup_fec_enet_pdata(struct platform_device *pdev, - int idx) -{ - /* This is for FEC devices only */ - if (!pdev || !pdev->name || (!strstr(pdev->name, "fsl-cpm-fec"))) - return; - mpc866ads_fixup_enet_pdata(pdev, fsid_fec1 + pdev->id - 1); -} - -static void mpc866ads_fixup_scc_enet_pdata(struct platform_device *pdev, - int idx) -{ - /* This is for SCC devices only */ - if (!pdev || !pdev->name || (!strstr(pdev->name, "fsl-cpm-scc"))) - return; - - mpc866ads_fixup_enet_pdata(pdev, fsid_scc1 + pdev->id - 1); -} - static void __init mpc866ads_fixup_uart_pdata(struct platform_device *pdev, int idx) { @@ -339,9 +359,6 @@ static int mpc866ads_platform_notify(struct device *dev) int __init mpc866ads_init(void) { - bd_t *bd = (bd_t *) __res; - struct fs_mii_fec_platform_info* fmpi; - printk(KERN_NOTICE "mpc866ads: Init\n"); platform_notify = mpc866ads_platform_notify; @@ -349,20 +366,11 @@ int __init mpc866ads_init(void) ppc_sys_device_initfunc(); ppc_sys_device_disable_all(); -#ifdef CONFIG_MPC8xx_SECOND_ETH_SCC1 +#ifdef MPC8xx_SECOND_ETH_SCC1 ppc_sys_device_enable(MPC8xx_CPM_SCC1); #endif ppc_sys_device_enable(MPC8xx_CPM_FEC1); - ppc_sys_device_enable(MPC8xx_MDIO_FEC); - - fmpi = ppc_sys_platform_devices[MPC8xx_MDIO_FEC].dev.platform_data = - &mpc8xx_mdio_fec_pdata; - - fmpi->mii_speed = ((((bd->bi_intfreq + 4999999) / 2500000) / 2) & 0x3F) << 1; - /* No PHY interrupt line here */ - fmpi->irq[0xf] = -1; - /* Since either of the uarts could be used as console, they need to ready */ #ifdef CONFIG_SERIAL_CPM_SMC1 ppc_sys_device_enable(MPC8xx_CPM_SMC1); @@ -373,14 +381,6 @@ int __init mpc866ads_init(void) ppc_sys_device_enable(MPC8xx_CPM_SMC2); ppc_sys_device_setfunc(MPC8xx_CPM_SMC2, PPC_SYS_FUNC_UART); #endif - ppc_sys_device_enable(MPC8xx_MDIO_FEC); - - fmpi = ppc_sys_platform_devices[MPC8xx_MDIO_FEC].dev.platform_data = - &mpc8xx_mdio_fec_pdata; - - fmpi->mii_speed = ((((bd->bi_intfreq + 4999999) / 2500000) / 2) & 0x3F) << 1; - /* No PHY interrupt line here */ - fmpi->irq[0xf] = -1; return 0; } diff --git a/trunk/arch/ppc/platforms/mpc885ads_setup.c b/trunk/arch/ppc/platforms/mpc885ads_setup.c index 5dfa4e6c2af0..c1fc4a16fea9 100644 --- a/trunk/arch/ppc/platforms/mpc885ads_setup.c +++ b/trunk/arch/ppc/platforms/mpc885ads_setup.c @@ -38,10 +38,7 @@ extern unsigned char __res[]; static void setup_smc1_ioports(void); static void setup_smc2_ioports(void); -static struct fs_mii_fec_platform_info mpc8xx_mdio_fec_pdata; -static void setup_fec1_ioports(void); -static void setup_fec2_ioports(void); -static void setup_scc3_ioports(void); +static void __init mpc885ads_scc_phy_init(char); static struct fs_uart_platform_info mpc885_uart_pdata[] = { [fsid_smc1_uart] = { @@ -64,8 +61,23 @@ static struct fs_uart_platform_info mpc885_uart_pdata[] = { }, }; -static struct fs_platform_info mpc8xx_enet_pdata[] = { - [fsid_fec1] = { +static struct fs_mii_bus_info fec_mii_bus_info = { + .method = fsmii_fec, + .id = 0, +}; + +static struct fs_mii_bus_info scc_mii_bus_info = { +#ifdef CONFIG_SCC_ENET_8xx_FIXED + .method = fsmii_fixed, +#else + .method = fsmii_fec, +#endif + + .id = 0, +}; + +static struct fs_platform_info mpc8xx_fec_pdata[] = { + { .rx_ring = 128, .tx_ring = 16, .rx_copybreak = 240, @@ -73,12 +85,11 @@ static struct fs_platform_info mpc8xx_enet_pdata[] = { .use_napi = 1, .napi_weight = 17, - .init_ioports = setup_fec1_ioports, + .phy_addr = 0, + .phy_irq = SIU_IRQ7, - .bus_id = "0:00", - .has_phy = 1, - }, - [fsid_fec2] = { + .bus_info = &fec_mii_bus_info, + }, { .rx_ring = 128, .tx_ring = 16, .rx_copybreak = 240, @@ -86,32 +97,35 @@ static struct fs_platform_info mpc8xx_enet_pdata[] = { .use_napi = 1, .napi_weight = 17, - .init_ioports = setup_fec2_ioports, + .phy_addr = 1, + .phy_irq = SIU_IRQ7, + + .bus_info = &fec_mii_bus_info, + } +}; - .bus_id = "0:01", - .has_phy = 1, - }, - [fsid_scc3] = { - .rx_ring = 64, - .tx_ring = 8, - .rx_copybreak = 240, +static struct fs_platform_info mpc8xx_scc_pdata = { + .rx_ring = 64, + .tx_ring = 8, + .rx_copybreak = 240, - .use_napi = 1, - .napi_weight = 17, + .use_napi = 1, + .napi_weight = 17, - .init_ioports = setup_scc3_ioports, -#ifdef CONFIG_FIXED_MII_10_FDX - .bus_id = "fixed@100:1", + .phy_addr = 2, +#ifdef CONFIG_MPC8xx_SCC_ENET_FIXED + .phy_irq = -1, #else - .bus_id = "0:02", - #endif - }, + .phy_irq = SIU_IRQ7, +#endif + + .bus_info = &scc_mii_bus_info, }; void __init board_init(void) { - cpm8xx_t *cp = cpmp; - unsigned int *bcsr_io; + volatile cpm8xx_t *cp = cpmp; + unsigned int *bcsr_io; #ifdef CONFIG_FS_ENET immap_t *immap = (immap_t *) IMAP_ADDR; @@ -150,14 +164,6 @@ void __init board_init(void) /* use MDC for MII (common) */ setbits16(&immap->im_ioport.iop_pdpar, 0x0080); clrbits16(&immap->im_ioport.iop_pddir, 0x0080); - bcsr_io = ioremap(BCSR5, sizeof(unsigned long)); - clrbits32(bcsr_io,BCSR5_MII1_EN); - clrbits32(bcsr_io,BCSR5_MII1_RST); -#ifdef CONFIG_MPC8xx_SECOND_ETH_FEC2 - clrbits32(bcsr_io,BCSR5_MII2_EN); - clrbits32(bcsr_io,BCSR5_MII2_RST); -#endif - iounmap(bcsr_io); #endif } @@ -188,8 +194,8 @@ static void setup_fec2_ioports(void) /* configure FEC2 pins */ setbits32(&immap->im_cpm.cp_pepar, 0x0003fffc); setbits32(&immap->im_cpm.cp_pedir, 0x0003fffc); - clrbits32(&immap->im_cpm.cp_peso, 0x000087fc); setbits32(&immap->im_cpm.cp_peso, 0x00037800); + clrbits32(&immap->im_cpm.cp_peso, 0x000087fc); clrbits32(&immap->im_cpm.cp_cptr, 0x00000080); } @@ -207,8 +213,6 @@ static void setup_scc3_ioports(void) /* Enable the PHY. */ - clrbits32(bcsr_io+4, BCSR4_ETH10_RST); - udelay(1000); setbits32(bcsr_io+4, BCSR4_ETH10_RST); /* Configure port A pins for Txd and Rxd. */ @@ -250,38 +254,37 @@ static void setup_scc3_ioports(void) clrbits32(&immap->im_cpm.cp_pedir, PE_ENET_TENA); setbits32(&immap->im_cpm.cp_peso, PE_ENET_TENA); - setbits32(bcsr_io+4, BCSR1_ETHEN); + setbits32(bcsr_io+1, BCSR1_ETHEN); iounmap(bcsr_io); } -static int mac_count = 0; - static void mpc885ads_fixup_enet_pdata(struct platform_device *pdev, int fs_no) { - struct fs_platform_info *fpi; + struct fs_platform_info *fpi = pdev->dev.platform_data; + + volatile cpm8xx_t *cp; bd_t *bd = (bd_t *) __res; char *e; int i; - if(fs_no > ARRAY_SIZE(mpc8xx_enet_pdata)) { - printk(KERN_ERR"No network-suitable #%d device on bus", fs_no); - return; - } - - fpi = &mpc8xx_enet_pdata[fs_no]; - + /* Get pointer to Communication Processor */ + cp = cpmp; switch (fs_no) { case fsid_fec1: + fpi = &mpc8xx_fec_pdata[0]; fpi->init_ioports = &setup_fec1_ioports; break; case fsid_fec2: + fpi = &mpc8xx_fec_pdata[1]; fpi->init_ioports = &setup_fec2_ioports; break; case fsid_scc3: + fpi = &mpc8xx_scc_pdata; fpi->init_ioports = &setup_scc3_ioports; + mpc885ads_scc_phy_init(fpi->phy_addr); break; default: - printk(KERN_WARNING "Device %s is not supported!\n", pdev->name); + printk(KERN_WARNING"Device %s is not supported!\n", pdev->name); return; } @@ -292,7 +295,7 @@ static void mpc885ads_fixup_enet_pdata(struct platform_device *pdev, int fs_no) for (i = 0; i < 6; i++) fpi->macaddr[i] = *e++; - fpi->macaddr[5] += mac_count++; + fpi->macaddr[5 - pdev->id]++; } @@ -315,6 +318,58 @@ static void __init mpc885ads_fixup_scc_enet_pdata(struct platform_device *pdev, mpc885ads_fixup_enet_pdata(pdev, fsid_scc1 + pdev->id - 1); } +/* SCC ethernet controller does not have MII management channel. FEC1 MII + * channel is used to communicate with the 10Mbit PHY. + */ + +#define MII_ECNTRL_PINMUX 0x4 +#define FEC_ECNTRL_PINMUX 0x00000004 +#define FEC_RCNTRL_MII_MODE 0x00000004 + +/* Make MII read/write commands. + */ +#define mk_mii_write(REG, VAL, PHY_ADDR) (0x50020000 | (((REG) & 0x1f) << 18) | \ + ((VAL) & 0xffff) | ((PHY_ADDR) << 23)) + +static void mpc885ads_scc_phy_init(char phy_addr) +{ + volatile immap_t *immap; + volatile fec_t *fecp; + bd_t *bd; + + bd = (bd_t *) __res; + immap = (immap_t *) IMAP_ADDR; /* pointer to internal registers */ + fecp = &(immap->im_cpm.cp_fec); + + /* Enable MII pins of the FEC1 + */ + setbits16(&immap->im_ioport.iop_pdpar, 0x0080); + clrbits16(&immap->im_ioport.iop_pddir, 0x0080); + /* Set MII speed to 2.5 MHz + */ + out_be32(&fecp->fec_mii_speed, + ((((bd->bi_intfreq + 4999999) / 2500000) / 2) & 0x3F) << 1); + + /* Enable FEC pin MUX + */ + setbits32(&fecp->fec_ecntrl, MII_ECNTRL_PINMUX); + setbits32(&fecp->fec_r_cntrl, FEC_RCNTRL_MII_MODE); + + out_be32(&fecp->fec_mii_data, + mk_mii_write(MII_BMCR, BMCR_ISOLATE, phy_addr)); + udelay(100); + out_be32(&fecp->fec_mii_data, + mk_mii_write(MII_ADVERTISE, + ADVERTISE_10HALF | ADVERTISE_CSMA, phy_addr)); + udelay(100); + + /* Disable FEC MII settings + */ + clrbits32(&fecp->fec_ecntrl, MII_ECNTRL_PINMUX); + clrbits32(&fecp->fec_r_cntrl, FEC_RCNTRL_MII_MODE); + out_be32(&fecp->fec_mii_speed, 0); +} + static void setup_smc1_ioports(void) { immap_t *immap = (immap_t *) IMAP_ADDR; @@ -407,9 +462,6 @@ static int mpc885ads_platform_notify(struct device *dev) int __init mpc885ads_init(void) { - struct fs_mii_fec_platform_info* fmpi; - bd_t *bd = (bd_t *) __res; - printk(KERN_NOTICE "mpc885ads: Init\n"); platform_notify = mpc885ads_platform_notify; @@ -419,17 +471,8 @@ int __init mpc885ads_init(void) ppc_sys_device_enable(MPC8xx_CPM_FEC1); - ppc_sys_device_enable(MPC8xx_MDIO_FEC); - fmpi = ppc_sys_platform_devices[MPC8xx_MDIO_FEC].dev.platform_data = - &mpc8xx_mdio_fec_pdata; - - fmpi->mii_speed = ((((bd->bi_intfreq + 4999999) / 2500000) / 2) & 0x3F) << 1; - - /* No PHY interrupt line here */ - fmpi->irq[0xf] = SIU_IRQ7; - #ifdef CONFIG_MPC8xx_SECOND_ETH_SCC3 - ppc_sys_device_enable(MPC8xx_CPM_SCC3); + ppc_sys_device_enable(MPC8xx_CPM_SCC1); #endif #ifdef CONFIG_MPC8xx_SECOND_ETH_FEC2 diff --git a/trunk/arch/ppc/platforms/pq2ads_pd.h b/trunk/arch/ppc/platforms/pq2ads_pd.h index 672483df8079..8f14a43eafec 100644 --- a/trunk/arch/ppc/platforms/pq2ads_pd.h +++ b/trunk/arch/ppc/platforms/pq2ads_pd.h @@ -29,4 +29,86 @@ #define F3_RXCLK 13 #define F3_TXCLK 14 +/* Automatically generates register configurations */ +#define PC_CLK(x) ((uint)(1<<(x-1))) /* FCC CLK I/O ports */ + +#define CMXFCR_RF1CS(x) ((uint)((x-5)<<27)) /* FCC1 Receive Clock Source */ +#define CMXFCR_TF1CS(x) ((uint)((x-5)<<24)) /* FCC1 Transmit Clock Source */ +#define CMXFCR_RF2CS(x) ((uint)((x-9)<<19)) /* FCC2 Receive Clock Source */ +#define CMXFCR_TF2CS(x) ((uint)((x-9)<<16)) /* FCC2 Transmit Clock Source */ +#define CMXFCR_RF3CS(x) ((uint)((x-9)<<11)) /* FCC3 Receive Clock Source */ +#define CMXFCR_TF3CS(x) ((uint)((x-9)<<8)) /* FCC3 Transmit Clock Source */ + +#define PC_F1RXCLK PC_CLK(F1_RXCLK) +#define PC_F1TXCLK PC_CLK(F1_TXCLK) +#define CMX1_CLK_ROUTE (CMXFCR_RF1CS(F1_RXCLK) | CMXFCR_TF1CS(F1_TXCLK)) +#define CMX1_CLK_MASK ((uint)0xff000000) + +#define PC_F2RXCLK PC_CLK(F2_RXCLK) +#define PC_F2TXCLK PC_CLK(F2_TXCLK) +#define CMX2_CLK_ROUTE (CMXFCR_RF2CS(F2_RXCLK) | CMXFCR_TF2CS(F2_TXCLK)) +#define CMX2_CLK_MASK ((uint)0x00ff0000) + +#define PC_F3RXCLK PC_CLK(F3_RXCLK) +#define PC_F3TXCLK PC_CLK(F3_TXCLK) +#define CMX3_CLK_ROUTE (CMXFCR_RF3CS(F3_RXCLK) | CMXFCR_TF3CS(F3_TXCLK)) +#define CMX3_CLK_MASK ((uint)0x0000ff00) + +/* I/O Pin assignment for FCC1. I don't yet know the best way to do this, + * but there is little variation among the choices. + */ +#define PA1_COL 0x00000001U +#define PA1_CRS 0x00000002U +#define PA1_TXER 0x00000004U +#define PA1_TXEN 0x00000008U +#define PA1_RXDV 0x00000010U +#define PA1_RXER 0x00000020U +#define PA1_TXDAT 0x00003c00U +#define PA1_RXDAT 0x0003c000U +#define PA1_PSORA0 (PA1_RXDAT | PA1_TXDAT) +#define PA1_PSORA1 (PA1_COL | PA1_CRS | PA1_TXER | PA1_TXEN | \ + PA1_RXDV | PA1_RXER) +#define PA1_DIRA0 (PA1_RXDAT | PA1_CRS | PA1_COL | PA1_RXER | PA1_RXDV) +#define PA1_DIRA1 (PA1_TXDAT | PA1_TXEN | PA1_TXER) + + +/* I/O Pin assignment for FCC2. I don't yet know the best way to do this, + * but there is little variation among the choices. + */ +#define PB2_TXER 0x00000001U +#define PB2_RXDV 0x00000002U +#define PB2_TXEN 0x00000004U +#define PB2_RXER 0x00000008U +#define PB2_COL 0x00000010U +#define PB2_CRS 0x00000020U +#define PB2_TXDAT 0x000003c0U +#define PB2_RXDAT 0x00003c00U +#define PB2_PSORB0 (PB2_RXDAT | PB2_TXDAT | PB2_CRS | PB2_COL | \ + PB2_RXER | PB2_RXDV | PB2_TXER) +#define PB2_PSORB1 (PB2_TXEN) +#define PB2_DIRB0 (PB2_RXDAT | PB2_CRS | PB2_COL | PB2_RXER | PB2_RXDV) +#define PB2_DIRB1 (PB2_TXDAT | PB2_TXEN | PB2_TXER) + + +/* I/O Pin assignment for FCC3. I don't yet know the best way to do this, + * but there is little variation among the choices. + */ +#define PB3_RXDV 0x00004000U +#define PB3_RXER 0x00008000U +#define PB3_TXER 0x00010000U +#define PB3_TXEN 0x00020000U +#define PB3_COL 0x00040000U +#define PB3_CRS 0x00080000U +#define PB3_TXDAT 0x0f000000U +#define PB3_RXDAT 0x00f00000U +#define PB3_PSORB0 (PB3_RXDAT | PB3_TXDAT | PB3_CRS | PB3_COL | \ + PB3_RXER | PB3_RXDV | PB3_TXER | PB3_TXEN) +#define PB3_PSORB1 0 +#define PB3_DIRB0 (PB3_RXDAT | PB3_CRS | PB3_COL | PB3_RXER | PB3_RXDV) +#define PB3_DIRB1 (PB3_TXDAT | PB3_TXEN | PB3_TXER) + +#define FCC_MEM_OFFSET(x) (CPM_FCC_SPECIAL_BASE + (x*128)) +#define FCC1_MEM_OFFSET FCC_MEM_OFFSET(0) +#define FCC2_MEM_OFFSET FCC_MEM_OFFSET(1) + #endif diff --git a/trunk/arch/ppc/syslib/Makefile b/trunk/arch/ppc/syslib/Makefile index dca23f2ef851..2497bbc07e76 100644 --- a/trunk/arch/ppc/syslib/Makefile +++ b/trunk/arch/ppc/syslib/Makefile @@ -93,7 +93,7 @@ obj-$(CONFIG_PCI) += pci_auto.o endif obj-$(CONFIG_RAPIDIO) += ppc85xx_rio.o obj-$(CONFIG_83xx) += ppc83xx_setup.o ppc_sys.o \ - mpc83xx_sys.o mpc83xx_devices.o ipic.o + mpc83xx_sys.o mpc83xx_devices.o ifeq ($(CONFIG_83xx),y) obj-$(CONFIG_PCI) += pci_auto.o endif diff --git a/trunk/arch/ppc/syslib/ipic.c b/trunk/arch/ppc/syslib/ipic.c deleted file mode 100644 index 46801f5ec03f..000000000000 --- a/trunk/arch/ppc/syslib/ipic.c +++ /dev/null @@ -1,646 +0,0 @@ -/* - * include/asm-ppc/ipic.c - * - * IPIC routines implementations. - * - * Copyright 2005 Freescale Semiconductor, Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "ipic.h" - -static struct ipic p_ipic; -static struct ipic * primary_ipic; - -static struct ipic_info ipic_info[] = { - [9] = { - .pend = IPIC_SIPNR_H, - .mask = IPIC_SIMSR_H, - .prio = IPIC_SIPRR_D, - .force = IPIC_SIFCR_H, - .bit = 24, - .prio_mask = 0, - }, - [10] = { - .pend = IPIC_SIPNR_H, - .mask = IPIC_SIMSR_H, - .prio = IPIC_SIPRR_D, - .force = IPIC_SIFCR_H, - .bit = 25, - .prio_mask = 1, - }, - [11] = { - .pend = IPIC_SIPNR_H, - .mask = IPIC_SIMSR_H, - .prio = IPIC_SIPRR_D, - .force = IPIC_SIFCR_H, - .bit = 26, - .prio_mask = 2, - }, - [14] = { - .pend = IPIC_SIPNR_H, - .mask = IPIC_SIMSR_H, - .prio = IPIC_SIPRR_D, - .force = IPIC_SIFCR_H, - .bit = 29, - .prio_mask = 5, - }, - [15] = { - .pend = IPIC_SIPNR_H, - .mask = IPIC_SIMSR_H, - .prio = IPIC_SIPRR_D, - .force = IPIC_SIFCR_H, - .bit = 30, - .prio_mask = 6, - }, - [16] = { - .pend = IPIC_SIPNR_H, - .mask = IPIC_SIMSR_H, - .prio = IPIC_SIPRR_D, - .force = IPIC_SIFCR_H, - .bit = 31, - .prio_mask = 7, - }, - [17] = { - .pend = IPIC_SEPNR, - .mask = IPIC_SEMSR, - .prio = IPIC_SMPRR_A, - .force = IPIC_SEFCR, - .bit = 1, - .prio_mask = 5, - }, - [18] = { - .pend = IPIC_SEPNR, - .mask = IPIC_SEMSR, - .prio = IPIC_SMPRR_A, - .force = IPIC_SEFCR, - .bit = 2, - .prio_mask = 6, - }, - [19] = { - .pend = IPIC_SEPNR, - .mask = IPIC_SEMSR, - .prio = IPIC_SMPRR_A, - .force = IPIC_SEFCR, - .bit = 3, - .prio_mask = 7, - }, - [20] = { - .pend = IPIC_SEPNR, - .mask = IPIC_SEMSR, - .prio = IPIC_SMPRR_B, - .force = IPIC_SEFCR, - .bit = 4, - .prio_mask = 4, - }, - [21] = { - .pend = IPIC_SEPNR, - .mask = IPIC_SEMSR, - .prio = IPIC_SMPRR_B, - .force = IPIC_SEFCR, - .bit = 5, - .prio_mask = 5, - }, - [22] = { - .pend = IPIC_SEPNR, - .mask = IPIC_SEMSR, - .prio = IPIC_SMPRR_B, - .force = IPIC_SEFCR, - .bit = 6, - .prio_mask = 6, - }, - [23] = { - .pend = IPIC_SEPNR, - .mask = IPIC_SEMSR, - .prio = IPIC_SMPRR_B, - .force = IPIC_SEFCR, - .bit = 7, - .prio_mask = 7, - }, - [32] = { - .pend = IPIC_SIPNR_H, - .mask = IPIC_SIMSR_H, - .prio = IPIC_SIPRR_A, - .force = IPIC_SIFCR_H, - .bit = 0, - .prio_mask = 0, - }, - [33] = { - .pend = IPIC_SIPNR_H, - .mask = IPIC_SIMSR_H, - .prio = IPIC_SIPRR_A, - .force = IPIC_SIFCR_H, - .bit = 1, - .prio_mask = 1, - }, - [34] = { - .pend = IPIC_SIPNR_H, - .mask = IPIC_SIMSR_H, - .prio = IPIC_SIPRR_A, - .force = IPIC_SIFCR_H, - .bit = 2, - .prio_mask = 2, - }, - [35] = { - .pend = IPIC_SIPNR_H, - .mask = IPIC_SIMSR_H, - .prio = IPIC_SIPRR_A, - .force = IPIC_SIFCR_H, - .bit = 3, - .prio_mask = 3, - }, - [36] = { - .pend = IPIC_SIPNR_H, - .mask = IPIC_SIMSR_H, - .prio = IPIC_SIPRR_A, - .force = IPIC_SIFCR_H, - .bit = 4, - .prio_mask = 4, - }, - [37] = { - .pend = IPIC_SIPNR_H, - .mask = IPIC_SIMSR_H, - .prio = IPIC_SIPRR_A, - .force = IPIC_SIFCR_H, - .bit = 5, - .prio_mask = 5, - }, - [38] = { - .pend = IPIC_SIPNR_H, - .mask = IPIC_SIMSR_H, - .prio = IPIC_SIPRR_A, - .force = IPIC_SIFCR_H, - .bit = 6, - .prio_mask = 6, - }, - [39] = { - .pend = IPIC_SIPNR_H, - .mask = IPIC_SIMSR_H, - .prio = IPIC_SIPRR_A, - .force = IPIC_SIFCR_H, - .bit = 7, - .prio_mask = 7, - }, - [48] = { - .pend = IPIC_SEPNR, - .mask = IPIC_SEMSR, - .prio = IPIC_SMPRR_A, - .force = IPIC_SEFCR, - .bit = 0, - .prio_mask = 4, - }, - [64] = { - .pend = IPIC_SIPNR_H, - .mask = IPIC_SIMSR_L, - .prio = IPIC_SMPRR_A, - .force = IPIC_SIFCR_L, - .bit = 0, - .prio_mask = 0, - }, - [65] = { - .pend = IPIC_SIPNR_H, - .mask = IPIC_SIMSR_L, - .prio = IPIC_SMPRR_A, - .force = IPIC_SIFCR_L, - .bit = 1, - .prio_mask = 1, - }, - [66] = { - .pend = IPIC_SIPNR_H, - .mask = IPIC_SIMSR_L, - .prio = IPIC_SMPRR_A, - .force = IPIC_SIFCR_L, - .bit = 2, - .prio_mask = 2, - }, - [67] = { - .pend = IPIC_SIPNR_H, - .mask = IPIC_SIMSR_L, - .prio = IPIC_SMPRR_A, - .force = IPIC_SIFCR_L, - .bit = 3, - .prio_mask = 3, - }, - [68] = { - .pend = IPIC_SIPNR_H, - .mask = IPIC_SIMSR_L, - .prio = IPIC_SMPRR_B, - .force = IPIC_SIFCR_L, - .bit = 4, - .prio_mask = 0, - }, - [69] = { - .pend = IPIC_SIPNR_H, - .mask = IPIC_SIMSR_L, - .prio = IPIC_SMPRR_B, - .force = IPIC_SIFCR_L, - .bit = 5, - .prio_mask = 1, - }, - [70] = { - .pend = IPIC_SIPNR_H, - .mask = IPIC_SIMSR_L, - .prio = IPIC_SMPRR_B, - .force = IPIC_SIFCR_L, - .bit = 6, - .prio_mask = 2, - }, - [71] = { - .pend = IPIC_SIPNR_H, - .mask = IPIC_SIMSR_L, - .prio = IPIC_SMPRR_B, - .force = IPIC_SIFCR_L, - .bit = 7, - .prio_mask = 3, - }, - [72] = { - .pend = IPIC_SIPNR_H, - .mask = IPIC_SIMSR_L, - .prio = 0, - .force = IPIC_SIFCR_L, - .bit = 8, - }, - [73] = { - .pend = IPIC_SIPNR_H, - .mask = IPIC_SIMSR_L, - .prio = 0, - .force = IPIC_SIFCR_L, - .bit = 9, - }, - [74] = { - .pend = IPIC_SIPNR_H, - .mask = IPIC_SIMSR_L, - .prio = 0, - .force = IPIC_SIFCR_L, - .bit = 10, - }, - [75] = { - .pend = IPIC_SIPNR_H, - .mask = IPIC_SIMSR_L, - .prio = 0, - .force = IPIC_SIFCR_L, - .bit = 11, - }, - [76] = { - .pend = IPIC_SIPNR_H, - .mask = IPIC_SIMSR_L, - .prio = 0, - .force = IPIC_SIFCR_L, - .bit = 12, - }, - [77] = { - .pend = IPIC_SIPNR_H, - .mask = IPIC_SIMSR_L, - .prio = 0, - .force = IPIC_SIFCR_L, - .bit = 13, - }, - [78] = { - .pend = IPIC_SIPNR_H, - .mask = IPIC_SIMSR_L, - .prio = 0, - .force = IPIC_SIFCR_L, - .bit = 14, - }, - [79] = { - .pend = IPIC_SIPNR_H, - .mask = IPIC_SIMSR_L, - .prio = 0, - .force = IPIC_SIFCR_L, - .bit = 15, - }, - [80] = { - .pend = IPIC_SIPNR_H, - .mask = IPIC_SIMSR_L, - .prio = 0, - .force = IPIC_SIFCR_L, - .bit = 16, - }, - [84] = { - .pend = IPIC_SIPNR_H, - .mask = IPIC_SIMSR_L, - .prio = 0, - .force = IPIC_SIFCR_L, - .bit = 20, - }, - [85] = { - .pend = IPIC_SIPNR_H, - .mask = IPIC_SIMSR_L, - .prio = 0, - .force = IPIC_SIFCR_L, - .bit = 21, - }, - [90] = { - .pend = IPIC_SIPNR_H, - .mask = IPIC_SIMSR_L, - .prio = 0, - .force = IPIC_SIFCR_L, - .bit = 26, - }, - [91] = { - .pend = IPIC_SIPNR_H, - .mask = IPIC_SIMSR_L, - .prio = 0, - .force = IPIC_SIFCR_L, - .bit = 27, - }, -}; - -static inline u32 ipic_read(volatile u32 __iomem *base, unsigned int reg) -{ - return in_be32(base + (reg >> 2)); -} - -static inline void ipic_write(volatile u32 __iomem *base, unsigned int reg, u32 value) -{ - out_be32(base + (reg >> 2), value); -} - -static inline struct ipic * ipic_from_irq(unsigned int irq) -{ - return primary_ipic; -} - -static void ipic_enable_irq(unsigned int irq) -{ - struct ipic *ipic = ipic_from_irq(irq); - unsigned int src = irq - ipic->irq_offset; - u32 temp; - - temp = ipic_read(ipic->regs, ipic_info[src].mask); - temp |= (1 << (31 - ipic_info[src].bit)); - ipic_write(ipic->regs, ipic_info[src].mask, temp); -} - -static void ipic_disable_irq(unsigned int irq) -{ - struct ipic *ipic = ipic_from_irq(irq); - unsigned int src = irq - ipic->irq_offset; - u32 temp; - - temp = ipic_read(ipic->regs, ipic_info[src].mask); - temp &= ~(1 << (31 - ipic_info[src].bit)); - ipic_write(ipic->regs, ipic_info[src].mask, temp); -} - -static void ipic_disable_irq_and_ack(unsigned int irq) -{ - struct ipic *ipic = ipic_from_irq(irq); - unsigned int src = irq - ipic->irq_offset; - u32 temp; - - ipic_disable_irq(irq); - - temp = ipic_read(ipic->regs, ipic_info[src].pend); - temp |= (1 << (31 - ipic_info[src].bit)); - ipic_write(ipic->regs, ipic_info[src].pend, temp); -} - -static void ipic_end_irq(unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) - ipic_enable_irq(irq); -} - -struct hw_interrupt_type ipic = { - .typename = " IPIC ", - .enable = ipic_enable_irq, - .disable = ipic_disable_irq, - .ack = ipic_disable_irq_and_ack, - .end = ipic_end_irq, -}; - -void __init ipic_init(phys_addr_t phys_addr, - unsigned int flags, - unsigned int irq_offset, - unsigned char *senses, - unsigned int senses_count) -{ - u32 i, temp = 0; - - primary_ipic = &p_ipic; - primary_ipic->regs = ioremap(phys_addr, MPC83xx_IPIC_SIZE); - - primary_ipic->irq_offset = irq_offset; - - ipic_write(primary_ipic->regs, IPIC_SICNR, 0x0); - - /* default priority scheme is grouped. If spread mode is required - * configure SICFR accordingly */ - if (flags & IPIC_SPREADMODE_GRP_A) - temp |= SICFR_IPSA; - if (flags & IPIC_SPREADMODE_GRP_D) - temp |= SICFR_IPSD; - if (flags & IPIC_SPREADMODE_MIX_A) - temp |= SICFR_MPSA; - if (flags & IPIC_SPREADMODE_MIX_B) - temp |= SICFR_MPSB; - - ipic_write(primary_ipic->regs, IPIC_SICNR, temp); - - /* handle MCP route */ - temp = 0; - if (flags & IPIC_DISABLE_MCP_OUT) - temp = SERCR_MCPR; - ipic_write(primary_ipic->regs, IPIC_SERCR, temp); - - /* handle routing of IRQ0 to MCP */ - temp = ipic_read(primary_ipic->regs, IPIC_SEMSR); - - if (flags & IPIC_IRQ0_MCP) - temp |= SEMSR_SIRQ0; - else - temp &= ~SEMSR_SIRQ0; - - ipic_write(primary_ipic->regs, IPIC_SEMSR, temp); - - for (i = 0 ; i < NR_IPIC_INTS ; i++) { - irq_desc[i+irq_offset].chip = &ipic; - irq_desc[i+irq_offset].status = IRQ_LEVEL; - } - - temp = 0; - for (i = 0 ; i < senses_count ; i++) { - if ((senses[i] & IRQ_SENSE_MASK) == IRQ_SENSE_EDGE) { - temp |= 1 << (15 - i); - if (i != 0) - irq_desc[i + irq_offset + MPC83xx_IRQ_EXT1 - 1].status = 0; - else - irq_desc[irq_offset + MPC83xx_IRQ_EXT0].status = 0; - } - } - ipic_write(primary_ipic->regs, IPIC_SECNR, temp); - - printk ("IPIC (%d IRQ sources, %d External IRQs) at %p\n", NR_IPIC_INTS, - senses_count, primary_ipic->regs); -} - -int ipic_set_priority(unsigned int irq, unsigned int priority) -{ - struct ipic *ipic = ipic_from_irq(irq); - unsigned int src = irq - ipic->irq_offset; - u32 temp; - - if (priority > 7) - return -EINVAL; - if (src > 127) - return -EINVAL; - if (ipic_info[src].prio == 0) - return -EINVAL; - - temp = ipic_read(ipic->regs, ipic_info[src].prio); - - if (priority < 4) { - temp &= ~(0x7 << (20 + (3 - priority) * 3)); - temp |= ipic_info[src].prio_mask << (20 + (3 - priority) * 3); - } else { - temp &= ~(0x7 << (4 + (7 - priority) * 3)); - temp |= ipic_info[src].prio_mask << (4 + (7 - priority) * 3); - } - - ipic_write(ipic->regs, ipic_info[src].prio, temp); - - return 0; -} - -void ipic_set_highest_priority(unsigned int irq) -{ - struct ipic *ipic = ipic_from_irq(irq); - unsigned int src = irq - ipic->irq_offset; - u32 temp; - - temp = ipic_read(ipic->regs, IPIC_SICFR); - - /* clear and set HPI */ - temp &= 0x7f000000; - temp |= (src & 0x7f) << 24; - - ipic_write(ipic->regs, IPIC_SICFR, temp); -} - -void ipic_set_default_priority(void) -{ - ipic_set_priority(MPC83xx_IRQ_TSEC1_TX, 0); - ipic_set_priority(MPC83xx_IRQ_TSEC1_RX, 1); - ipic_set_priority(MPC83xx_IRQ_TSEC1_ERROR, 2); - ipic_set_priority(MPC83xx_IRQ_TSEC2_TX, 3); - ipic_set_priority(MPC83xx_IRQ_TSEC2_RX, 4); - ipic_set_priority(MPC83xx_IRQ_TSEC2_ERROR, 5); - ipic_set_priority(MPC83xx_IRQ_USB2_DR, 6); - ipic_set_priority(MPC83xx_IRQ_USB2_MPH, 7); - - ipic_set_priority(MPC83xx_IRQ_UART1, 0); - ipic_set_priority(MPC83xx_IRQ_UART2, 1); - ipic_set_priority(MPC83xx_IRQ_SEC2, 2); - ipic_set_priority(MPC83xx_IRQ_IIC1, 5); - ipic_set_priority(MPC83xx_IRQ_IIC2, 6); - ipic_set_priority(MPC83xx_IRQ_SPI, 7); - ipic_set_priority(MPC83xx_IRQ_RTC_SEC, 0); - ipic_set_priority(MPC83xx_IRQ_PIT, 1); - ipic_set_priority(MPC83xx_IRQ_PCI1, 2); - ipic_set_priority(MPC83xx_IRQ_PCI2, 3); - ipic_set_priority(MPC83xx_IRQ_EXT0, 4); - ipic_set_priority(MPC83xx_IRQ_EXT1, 5); - ipic_set_priority(MPC83xx_IRQ_EXT2, 6); - ipic_set_priority(MPC83xx_IRQ_EXT3, 7); - ipic_set_priority(MPC83xx_IRQ_RTC_ALR, 0); - ipic_set_priority(MPC83xx_IRQ_MU, 1); - ipic_set_priority(MPC83xx_IRQ_SBA, 2); - ipic_set_priority(MPC83xx_IRQ_DMA, 3); - ipic_set_priority(MPC83xx_IRQ_EXT4, 4); - ipic_set_priority(MPC83xx_IRQ_EXT5, 5); - ipic_set_priority(MPC83xx_IRQ_EXT6, 6); - ipic_set_priority(MPC83xx_IRQ_EXT7, 7); -} - -void ipic_enable_mcp(enum ipic_mcp_irq mcp_irq) -{ - struct ipic *ipic = primary_ipic; - u32 temp; - - temp = ipic_read(ipic->regs, IPIC_SERMR); - temp |= (1 << (31 - mcp_irq)); - ipic_write(ipic->regs, IPIC_SERMR, temp); -} - -void ipic_disable_mcp(enum ipic_mcp_irq mcp_irq) -{ - struct ipic *ipic = primary_ipic; - u32 temp; - - temp = ipic_read(ipic->regs, IPIC_SERMR); - temp &= (1 << (31 - mcp_irq)); - ipic_write(ipic->regs, IPIC_SERMR, temp); -} - -u32 ipic_get_mcp_status(void) -{ - return ipic_read(primary_ipic->regs, IPIC_SERMR); -} - -void ipic_clear_mcp_status(u32 mask) -{ - ipic_write(primary_ipic->regs, IPIC_SERMR, mask); -} - -/* Return an interrupt vector or -1 if no interrupt is pending. */ -int ipic_get_irq(struct pt_regs *regs) -{ - int irq; - - irq = ipic_read(primary_ipic->regs, IPIC_SIVCR) & 0x7f; - - if (irq == 0) /* 0 --> no irq is pending */ - irq = -1; - - return irq; -} - -static struct sysdev_class ipic_sysclass = { - set_kset_name("ipic"), -}; - -static struct sys_device device_ipic = { - .id = 0, - .cls = &ipic_sysclass, -}; - -static int __init init_ipic_sysfs(void) -{ - int rc; - - if (!primary_ipic->regs) - return -ENODEV; - printk(KERN_DEBUG "Registering ipic with sysfs...\n"); - - rc = sysdev_class_register(&ipic_sysclass); - if (rc) { - printk(KERN_ERR "Failed registering ipic sys class\n"); - return -ENODEV; - } - rc = sysdev_register(&device_ipic); - if (rc) { - printk(KERN_ERR "Failed registering ipic sys device\n"); - return -ENODEV; - } - return 0; -} - -subsys_initcall(init_ipic_sysfs); diff --git a/trunk/arch/ppc/syslib/ipic.h b/trunk/arch/ppc/syslib/ipic.h deleted file mode 100644 index a60c9d18bb7f..000000000000 --- a/trunk/arch/ppc/syslib/ipic.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * IPIC private definitions and structure. - * - * Maintainer: Kumar Gala - * - * Copyright 2005 Freescale Semiconductor, Inc - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ -#ifndef __IPIC_H__ -#define __IPIC_H__ - -#include - -#define MPC83xx_IPIC_SIZE (0x00100) - -/* System Global Interrupt Configuration Register */ -#define SICFR_IPSA 0x00010000 -#define SICFR_IPSD 0x00080000 -#define SICFR_MPSA 0x00200000 -#define SICFR_MPSB 0x00400000 - -/* System External Interrupt Mask Register */ -#define SEMSR_SIRQ0 0x00008000 - -/* System Error Control Register */ -#define SERCR_MCPR 0x00000001 - -struct ipic { - volatile u32 __iomem *regs; - unsigned int irq_offset; -}; - -struct ipic_info { - u8 pend; /* pending register offset from base */ - u8 mask; /* mask register offset from base */ - u8 prio; /* priority register offset from base */ - u8 force; /* force register offset from base */ - u8 bit; /* register bit position (as per doc) - bit mask = 1 << (31 - bit) */ - u8 prio_mask; /* priority mask value */ -}; - -#endif /* __IPIC_H__ */ diff --git a/trunk/arch/ppc/syslib/mpc85xx_devices.c b/trunk/arch/ppc/syslib/mpc85xx_devices.c index 325136e5aee0..7735336f5b8f 100644 --- a/trunk/arch/ppc/syslib/mpc85xx_devices.c +++ b/trunk/arch/ppc/syslib/mpc85xx_devices.c @@ -16,11 +16,9 @@ #include #include #include -#include #include #include #include -#include /* We use offsets for IORESOURCE_MEM since we do not know at compile time * what CCSRBAR is, will get fixed up by mach_mpc85xx_fixup @@ -84,60 +82,6 @@ static struct fsl_i2c_platform_data mpc85xx_fsl_i2c2_pdata = { .device_flags = FSL_I2C_DEV_SEPARATE_DFSRR, }; -static struct fs_platform_info mpc85xx_fcc1_pdata = { - .fs_no = fsid_fcc1, - .cp_page = CPM_CR_FCC1_PAGE, - .cp_block = CPM_CR_FCC1_SBLOCK, - - .rx_ring = 32, - .tx_ring = 32, - .rx_copybreak = 240, - .use_napi = 0, - .napi_weight = 17, - - .clk_mask = CMX1_CLK_MASK, - .clk_route = CMX1_CLK_ROUTE, - .clk_trx = (PC_F1RXCLK | PC_F1TXCLK), - - .mem_offset = FCC1_MEM_OFFSET, -}; - -static struct fs_platform_info mpc85xx_fcc2_pdata = { - .fs_no = fsid_fcc2, - .cp_page = CPM_CR_FCC2_PAGE, - .cp_block = CPM_CR_FCC2_SBLOCK, - - .rx_ring = 32, - .tx_ring = 32, - .rx_copybreak = 240, - .use_napi = 0, - .napi_weight = 17, - - .clk_mask = CMX2_CLK_MASK, - .clk_route = CMX2_CLK_ROUTE, - .clk_trx = (PC_F2RXCLK | PC_F2TXCLK), - - .mem_offset = FCC2_MEM_OFFSET, -}; - -static struct fs_platform_info mpc85xx_fcc3_pdata = { - .fs_no = fsid_fcc3, - .cp_page = CPM_CR_FCC3_PAGE, - .cp_block = CPM_CR_FCC3_SBLOCK, - - .rx_ring = 32, - .tx_ring = 32, - .rx_copybreak = 240, - .use_napi = 0, - .napi_weight = 17, - - .clk_mask = CMX3_CLK_MASK, - .clk_route = CMX3_CLK_ROUTE, - .clk_trx = (PC_F3RXCLK | PC_F3TXCLK), - - .mem_offset = FCC3_MEM_OFFSET, -}; - static struct plat_serial8250_port serial_platform_data[] = { [0] = { .mapbase = 0x4500, @@ -374,27 +318,18 @@ struct platform_device ppc_sys_platform_devices[] = { [MPC85xx_CPM_FCC1] = { .name = "fsl-cpm-fcc", .id = 1, - .num_resources = 4, - .dev.platform_data = &mpc85xx_fcc1_pdata, + .num_resources = 3, .resource = (struct resource[]) { { - .name = "fcc_regs", .start = 0x91300, .end = 0x9131F, .flags = IORESOURCE_MEM, }, { - .name = "fcc_regs_c", .start = 0x91380, .end = 0x9139F, .flags = IORESOURCE_MEM, }, - { - .name = "fcc_pram", - .start = 0x88400, - .end = 0x884ff, - .flags = IORESOURCE_MEM, - }, { .start = SIU_INT_FCC1, .end = SIU_INT_FCC1, @@ -405,27 +340,18 @@ struct platform_device ppc_sys_platform_devices[] = { [MPC85xx_CPM_FCC2] = { .name = "fsl-cpm-fcc", .id = 2, - .num_resources = 4, - .dev.platform_data = &mpc85xx_fcc2_pdata, + .num_resources = 3, .resource = (struct resource[]) { { - .name = "fcc_regs", .start = 0x91320, .end = 0x9133F, .flags = IORESOURCE_MEM, }, { - .name = "fcc_regs_c", .start = 0x913A0, .end = 0x913CF, .flags = IORESOURCE_MEM, }, - { - .name = "fcc_pram", - .start = 0x88500, - .end = 0x885ff, - .flags = IORESOURCE_MEM, - }, { .start = SIU_INT_FCC2, .end = SIU_INT_FCC2, @@ -436,27 +362,18 @@ struct platform_device ppc_sys_platform_devices[] = { [MPC85xx_CPM_FCC3] = { .name = "fsl-cpm-fcc", .id = 3, - .num_resources = 4, - .dev.platform_data = &mpc85xx_fcc3_pdata, + .num_resources = 3, .resource = (struct resource[]) { { - .name = "fcc_regs", .start = 0x91340, .end = 0x9135F, .flags = IORESOURCE_MEM, }, { - .name = "fcc_regs_c", .start = 0x913D0, .end = 0x913FF, .flags = IORESOURCE_MEM, }, - { - .name = "fcc_pram", - .start = 0x88600, - .end = 0x886ff, - .flags = IORESOURCE_MEM, - }, { .start = SIU_INT_FCC3, .end = SIU_INT_FCC3, diff --git a/trunk/arch/ppc/syslib/mpc8xx_devices.c b/trunk/arch/ppc/syslib/mpc8xx_devices.c index cf5ab47487a7..6f536383866e 100644 --- a/trunk/arch/ppc/syslib/mpc8xx_devices.c +++ b/trunk/arch/ppc/syslib/mpc8xx_devices.c @@ -218,14 +218,6 @@ struct platform_device ppc_sys_platform_devices[] = { }, }, }, - - [MPC8xx_MDIO_FEC] = { - .name = "fsl-cpm-fec-mdio", - .id = 0, - .num_resources = 0, - - }, - }; static int __init mach_mpc8xx_fixup(struct platform_device *pdev) diff --git a/trunk/arch/ppc/syslib/mpc8xx_sys.c b/trunk/arch/ppc/syslib/mpc8xx_sys.c index 18ba1d7ff9f1..eee213284855 100644 --- a/trunk/arch/ppc/syslib/mpc8xx_sys.c +++ b/trunk/arch/ppc/syslib/mpc8xx_sys.c @@ -22,7 +22,7 @@ struct ppc_sys_spec ppc_sys_specs[] = { .ppc_sys_name = "MPC86X", .mask = 0xFFFFFFFF, .value = 0x00000000, - .num_devices = 8, + .num_devices = 7, .device_list = (enum ppc_sys_devices[]) { MPC8xx_CPM_FEC1, @@ -32,14 +32,13 @@ struct ppc_sys_spec ppc_sys_specs[] = { MPC8xx_CPM_SCC4, MPC8xx_CPM_SMC1, MPC8xx_CPM_SMC2, - MPC8xx_MDIO_FEC, }, }, { .ppc_sys_name = "MPC885", .mask = 0xFFFFFFFF, .value = 0x00000000, - .num_devices = 9, + .num_devices = 8, .device_list = (enum ppc_sys_devices[]) { MPC8xx_CPM_FEC1, @@ -50,7 +49,6 @@ struct ppc_sys_spec ppc_sys_specs[] = { MPC8xx_CPM_SCC4, MPC8xx_CPM_SMC1, MPC8xx_CPM_SMC2, - MPC8xx_MDIO_FEC, }, }, { /* default match */ diff --git a/trunk/arch/ppc/syslib/pq2_devices.c b/trunk/arch/ppc/syslib/pq2_devices.c index fefbc217a56d..8692d00c08c4 100644 --- a/trunk/arch/ppc/syslib/pq2_devices.c +++ b/trunk/arch/ppc/syslib/pq2_devices.c @@ -369,11 +369,6 @@ struct platform_device ppc_sys_platform_devices[] = { }, }, }, - [MPC82xx_MDIO_BB] = { - .name = "fsl-bb-mdio", - .id = 0, - .num_resources = 0, - }, }; static int __init mach_mpc82xx_fixup(struct platform_device *pdev) diff --git a/trunk/arch/ppc/syslib/pq2_sys.c b/trunk/arch/ppc/syslib/pq2_sys.c index f52600c0db20..fee8948162b9 100644 --- a/trunk/arch/ppc/syslib/pq2_sys.c +++ b/trunk/arch/ppc/syslib/pq2_sys.c @@ -139,14 +139,13 @@ struct ppc_sys_spec ppc_sys_specs[] = { .ppc_sys_name = "8272", .mask = 0x0000ff00, .value = 0x00000c00, - .num_devices = 13, + .num_devices = 12, .device_list = (enum ppc_sys_devices[]) { MPC82xx_CPM_FCC1, MPC82xx_CPM_FCC2, MPC82xx_CPM_SCC1, MPC82xx_CPM_SCC2, MPC82xx_CPM_SCC3, MPC82xx_CPM_SCC4, MPC82xx_CPM_SMC1, MPC82xx_CPM_SMC2, MPC82xx_CPM_SPI, MPC82xx_CPM_I2C, MPC82xx_CPM_USB, MPC82xx_SEC1, - MPC82xx_MDIO_BB, }, }, /* below is a list of the 8280 family of processors */ diff --git a/trunk/arch/s390/lib/uaccess.S b/trunk/arch/s390/lib/uaccess.S index 837275284d9f..5d59e2625048 100644 --- a/trunk/arch/s390/lib/uaccess.S +++ b/trunk/arch/s390/lib/uaccess.S @@ -88,31 +88,30 @@ __copy_to_user_asm: .globl __copy_in_user_asm # %r2 = from, %r3 = n, %r4 = to __copy_in_user_asm: - ahi %r3,-1 - jo 6f sacf 256 - bras %r1,4f -0: ahi %r3,257 -1: mvc 0(1,%r4),0(%r2) + bras 1,1f + mvc 0(1,%r4),0(%r2) +0: mvc 0(256,%r4),0(%r2) + la %r2,256(%r2) + la %r4,256(%r4) +1: ahi %r3,-256 + jnm 0b +2: ex %r3,0(%r1) + sacf 0 + slr %r2,%r2 + br 14 +3: mvc 0(1,%r4),0(%r2) la %r2,1(%r2) la %r4,1(%r4) ahi %r3,-1 - jnz 1b -2: lr %r2,%r3 - br %r14 -3: mvc 0(256,%r4),0(%r2) - la %r2,256(%r2) - la %r4,256(%r4) -4: ahi %r3,-256 jnm 3b -5: ex %r3,4(%r1) +4: lr %r2,%r3 sacf 0 -6: slr %r2,%r2 br %r14 .section __ex_table,"a" - .long 1b,2b - .long 3b,0b - .long 5b,0b + .long 0b,3b + .long 2b,3b + .long 3b,4b .previous .align 4 diff --git a/trunk/arch/s390/lib/uaccess64.S b/trunk/arch/s390/lib/uaccess64.S index 1f755be22f92..19b41a33c230 100644 --- a/trunk/arch/s390/lib/uaccess64.S +++ b/trunk/arch/s390/lib/uaccess64.S @@ -88,31 +88,30 @@ __copy_to_user_asm: .globl __copy_in_user_asm # %r2 = from, %r3 = n, %r4 = to __copy_in_user_asm: - aghi %r3,-1 - jo 6f sacf 256 - bras %r1,4f -0: aghi %r3,257 -1: mvc 0(1,%r4),0(%r2) + bras 1,1f + mvc 0(1,%r4),0(%r2) +0: mvc 0(256,%r4),0(%r2) + la %r2,256(%r2) + la %r4,256(%r4) +1: aghi %r3,-256 + jnm 0b +2: ex %r3,0(%r1) + sacf 0 + slgr %r2,%r2 + br 14 +3: mvc 0(1,%r4),0(%r2) la %r2,1(%r2) la %r4,1(%r4) aghi %r3,-1 - jnz 1b -2: lgr %r2,%r3 - br %r14 -3: mvc 0(256,%r4),0(%r2) - la %r2,256(%r2) - la %r4,256(%r4) -4: aghi %r3,-256 jnm 3b -5: ex %r3,4(%r1) +4: lgr %r2,%r3 sacf 0 -6: slgr %r2,%r2 - br 14 + br %r14 .section __ex_table,"a" - .quad 1b,2b - .quad 3b,0b - .quad 5b,0b + .quad 0b,3b + .quad 2b,3b + .quad 3b,4b .previous .align 4 diff --git a/trunk/arch/sparc/kernel/setup.c b/trunk/arch/sparc/kernel/setup.c index 0251cab4708b..35488d6c7457 100644 --- a/trunk/arch/sparc/kernel/setup.c +++ b/trunk/arch/sparc/kernel/setup.c @@ -348,9 +348,9 @@ void __init setup_arch(char **cmdline_p) init_mm.context = (unsigned long) NO_CONTEXT; init_task.thread.kregs = &fake_swapper_regs; - paging_init(); - smp_setup_cpu_possible_map(); + + paging_init(); } static int __init set_preferred_console(void) diff --git a/trunk/arch/sparc/kernel/smp.c b/trunk/arch/sparc/kernel/smp.c index 276f22881d0f..e311ade1b490 100644 --- a/trunk/arch/sparc/kernel/smp.c +++ b/trunk/arch/sparc/kernel/smp.c @@ -34,6 +34,7 @@ #include #include +volatile int smp_processors_ready = 0; int smp_num_cpus = 1; volatile unsigned long cpu_callin_map[NR_CPUS] __initdata = {0,}; unsigned char boot_cpu_id = 0; diff --git a/trunk/arch/sparc/kernel/sun4d_smp.c b/trunk/arch/sparc/kernel/sun4d_smp.c index 3ff4edd32815..ba843f6a2832 100644 --- a/trunk/arch/sparc/kernel/sun4d_smp.c +++ b/trunk/arch/sparc/kernel/sun4d_smp.c @@ -42,7 +42,7 @@ extern ctxd_t *srmmu_ctx_table_phys; extern void calibrate_delay(void); -static volatile int smp_processors_ready = 0; +extern volatile int smp_processors_ready; static int smp_highest_cpu; extern volatile unsigned long cpu_callin_map[NR_CPUS]; extern cpuinfo_sparc cpu_data[NR_CPUS]; diff --git a/trunk/arch/sparc/kernel/sun4m_smp.c b/trunk/arch/sparc/kernel/sun4m_smp.c index 7d4a649138f6..3b32096134aa 100644 --- a/trunk/arch/sparc/kernel/sun4m_smp.c +++ b/trunk/arch/sparc/kernel/sun4m_smp.c @@ -39,6 +39,7 @@ extern ctxd_t *srmmu_ctx_table_phys; extern void calibrate_delay(void); +extern volatile int smp_processors_ready; extern volatile unsigned long cpu_callin_map[NR_CPUS]; extern unsigned char boot_cpu_id; @@ -216,6 +217,7 @@ void __init smp4m_smp_done(void) } /* Ok, they are spinning and ready to go. */ + smp_processors_ready = 1; } /* At each hardware IRQ, we get this called to forward IRQ reception diff --git a/trunk/arch/sparc64/mm/generic.c b/trunk/arch/sparc64/mm/generic.c index af9d81db0b38..8cb06205d265 100644 --- a/trunk/arch/sparc64/mm/generic.c +++ b/trunk/arch/sparc64/mm/generic.c @@ -69,8 +69,6 @@ static inline void io_remap_pte_range(struct mm_struct *mm, pte_t * pte, } else offset += PAGE_SIZE; - if (pte_write(entry)) - entry = pte_mkdirty(entry); do { BUG_ON(!pte_none(*pte)); set_pte_at(mm, address, pte, entry); diff --git a/trunk/arch/x86_64/defconfig b/trunk/arch/x86_64/defconfig index 5fb970715941..840d5d93d5cc 100644 --- a/trunk/arch/x86_64/defconfig +++ b/trunk/arch/x86_64/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.18-rc4 -# Thu Aug 24 21:05:55 2006 +# Linux kernel version: 2.6.18-rc2 +# Tue Jul 18 17:13:20 2006 # CONFIG_X86_64=y CONFIG_64BIT=y @@ -201,7 +201,7 @@ CONFIG_ACPI_THERMAL=y CONFIG_ACPI_NUMA=y # CONFIG_ACPI_ASUS is not set # CONFIG_ACPI_IBM is not set -# CONFIG_ACPI_TOSHIBA is not set +CONFIG_ACPI_TOSHIBA=y CONFIG_ACPI_BLACKLIST_YEAR=0 # CONFIG_ACPI_DEBUG is not set CONFIG_ACPI_EC=y @@ -216,7 +216,7 @@ CONFIG_ACPI_CONTAINER=y # CONFIG_CPU_FREQ=y CONFIG_CPU_FREQ_TABLE=y -CONFIG_CPU_FREQ_DEBUG=y +# CONFIG_CPU_FREQ_DEBUG is not set CONFIG_CPU_FREQ_STAT=y # CONFIG_CPU_FREQ_STAT_DETAILS is not set CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y @@ -495,9 +495,8 @@ CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y # CONFIG_CHR_DEV_ST is not set # CONFIG_CHR_DEV_OSST is not set -CONFIG_BLK_DEV_SR=y -# CONFIG_BLK_DEV_SR_VENDOR is not set -CONFIG_CHR_DEV_SG=y +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set # CONFIG_CHR_DEV_SCH is not set # @@ -513,7 +512,7 @@ CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_SPI_ATTRS=y CONFIG_SCSI_FC_ATTRS=y # CONFIG_SCSI_ISCSI_ATTRS is not set -CONFIG_SCSI_SAS_ATTRS=y +# CONFIG_SCSI_SAS_ATTRS is not set # # SCSI low-level drivers @@ -539,7 +538,7 @@ CONFIG_MEGARAID_MAILBOX=y CONFIG_MEGARAID_SAS=y CONFIG_SCSI_SATA=y CONFIG_SCSI_SATA_AHCI=y -CONFIG_SCSI_SATA_SVW=y +# CONFIG_SCSI_SATA_SVW is not set CONFIG_SCSI_ATA_PIIX=y # CONFIG_SCSI_SATA_MV is not set CONFIG_SCSI_SATA_NV=y @@ -590,7 +589,7 @@ CONFIG_BLK_DEV_DM=y CONFIG_FUSION=y CONFIG_FUSION_SPI=y # CONFIG_FUSION_FC is not set -CONFIG_FUSION_SAS=y +# CONFIG_FUSION_SAS is not set CONFIG_FUSION_MAX_SGE=128 # CONFIG_FUSION_CTL is not set @@ -676,7 +675,7 @@ CONFIG_NET_PCI=y # CONFIG_PCNET32 is not set # CONFIG_AMD8111_ETH is not set # CONFIG_ADAPTEC_STARFIRE is not set -CONFIG_B44=y +# CONFIG_B44 is not set CONFIG_FORCEDETH=y # CONFIG_DGRS is not set # CONFIG_EEPRO100 is not set @@ -713,7 +712,7 @@ CONFIG_E1000=y # CONFIG_SK98LIN is not set # CONFIG_VIA_VELOCITY is not set CONFIG_TIGON3=y -CONFIG_BNX2=y +# CONFIG_BNX2 is not set # # Ethernet (10000 Mbit) @@ -843,7 +842,44 @@ CONFIG_LEGACY_PTY_COUNT=256 # # Watchdog Cards # -# CONFIG_WATCHDOG is not set +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +CONFIG_SOFT_WATCHDOG=y +# CONFIG_ACQUIRE_WDT is not set +# CONFIG_ADVANTECH_WDT is not set +# CONFIG_ALIM1535_WDT is not set +# CONFIG_ALIM7101_WDT is not set +# CONFIG_SC520_WDT is not set +# CONFIG_EUROTECH_WDT is not set +# CONFIG_IB700_WDT is not set +# CONFIG_IBMASR is not set +# CONFIG_WAFER_WDT is not set +# CONFIG_I6300ESB_WDT is not set +# CONFIG_I8XX_TCO is not set +# CONFIG_SC1200_WDT is not set +# CONFIG_60XX_WDT is not set +# CONFIG_SBC8360_WDT is not set +# CONFIG_CPU5_WDT is not set +# CONFIG_W83627HF_WDT is not set +# CONFIG_W83877F_WDT is not set +# CONFIG_W83977F_WDT is not set +# CONFIG_MACHZ_WDT is not set +# CONFIG_SBC_EPX_C3_WATCHDOG is not set + +# +# PCI-based Watchdog Cards +# +# CONFIG_PCIPCWATCHDOG is not set +# CONFIG_WDTPCI is not set + +# +# USB-based Watchdog Cards +# +# CONFIG_USBPCWATCHDOG is not set CONFIG_HW_RANDOM=y CONFIG_HW_RANDOM_INTEL=y CONFIG_HW_RANDOM_AMD=y @@ -1020,7 +1056,6 @@ CONFIG_VGACON_SOFT_SCROLLBACK=y CONFIG_VGACON_SOFT_SCROLLBACK_SIZE=256 CONFIG_VIDEO_SELECT=y CONFIG_DUMMY_CONSOLE=y -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # # Sound @@ -1266,7 +1301,7 @@ CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y # CONFIG_QUOTA is not set CONFIG_DNOTIFY=y -# CONFIG_AUTOFS_FS is not set +CONFIG_AUTOFS_FS=y CONFIG_AUTOFS4_FS=y # CONFIG_FUSE_FS is not set @@ -1459,5 +1494,4 @@ CONFIG_DEBUG_STACKOVERFLOW=y # CONFIG_CRC16 is not set CONFIG_CRC32=y # CONFIG_LIBCRC32C is not set -CONFIG_ZLIB_INFLATE=y CONFIG_PLIST=y diff --git a/trunk/arch/x86_64/ia32/ia32_binfmt.c b/trunk/arch/x86_64/ia32/ia32_binfmt.c index 2fd5a67fd435..a9dc0f3b5b51 100644 --- a/trunk/arch/x86_64/ia32/ia32_binfmt.c +++ b/trunk/arch/x86_64/ia32/ia32_binfmt.c @@ -73,44 +73,39 @@ typedef elf_greg_t elf_gregset_t[ELF_NGREG]; * Dumping its extra ELF program headers includes all the other information * a debugger needs to easily find how the vsyscall DSO was being used. */ -#define ELF_CORE_EXTRA_PHDRS (find_vma(current->mm, VSYSCALL32_BASE) ? \ - (VSYSCALL32_EHDR->e_phnum) : 0) +#define ELF_CORE_EXTRA_PHDRS (VSYSCALL32_EHDR->e_phnum) #define ELF_CORE_WRITE_EXTRA_PHDRS \ do { \ - if (find_vma(current->mm, VSYSCALL32_BASE)) { \ - const struct elf32_phdr *const vsyscall_phdrs = \ - (const struct elf32_phdr *) (VSYSCALL32_BASE \ - + VSYSCALL32_EHDR->e_phoff);\ - int i; \ - Elf32_Off ofs = 0; \ - for (i = 0; i < VSYSCALL32_EHDR->e_phnum; ++i) { \ - struct elf32_phdr phdr = vsyscall_phdrs[i]; \ - if (phdr.p_type == PT_LOAD) { \ - BUG_ON(ofs != 0); \ - ofs = phdr.p_offset = offset; \ - phdr.p_memsz = PAGE_ALIGN(phdr.p_memsz); \ - phdr.p_filesz = phdr.p_memsz; \ - offset += phdr.p_filesz; \ - } \ - else \ - phdr.p_offset += ofs; \ - phdr.p_paddr = 0; /* match other core phdrs */ \ - DUMP_WRITE(&phdr, sizeof(phdr)); \ + const struct elf32_phdr *const vsyscall_phdrs = \ + (const struct elf32_phdr *) (VSYSCALL32_BASE \ + + VSYSCALL32_EHDR->e_phoff); \ + int i; \ + Elf32_Off ofs = 0; \ + for (i = 0; i < VSYSCALL32_EHDR->e_phnum; ++i) { \ + struct elf32_phdr phdr = vsyscall_phdrs[i]; \ + if (phdr.p_type == PT_LOAD) { \ + BUG_ON(ofs != 0); \ + ofs = phdr.p_offset = offset; \ + phdr.p_memsz = PAGE_ALIGN(phdr.p_memsz); \ + phdr.p_filesz = phdr.p_memsz; \ + offset += phdr.p_filesz; \ } \ + else \ + phdr.p_offset += ofs; \ + phdr.p_paddr = 0; /* match other core phdrs */ \ + DUMP_WRITE(&phdr, sizeof(phdr)); \ } \ } while (0) #define ELF_CORE_WRITE_EXTRA_DATA \ do { \ - if (find_vma(current->mm, VSYSCALL32_BASE)) { \ - const struct elf32_phdr *const vsyscall_phdrs = \ - (const struct elf32_phdr *) (VSYSCALL32_BASE \ - + VSYSCALL32_EHDR->e_phoff); \ - int i; \ - for (i = 0; i < VSYSCALL32_EHDR->e_phnum; ++i) { \ - if (vsyscall_phdrs[i].p_type == PT_LOAD) \ - DUMP_WRITE((void *) (u64) vsyscall_phdrs[i].p_vaddr,\ - PAGE_ALIGN(vsyscall_phdrs[i].p_memsz)); \ - } \ + const struct elf32_phdr *const vsyscall_phdrs = \ + (const struct elf32_phdr *) (VSYSCALL32_BASE \ + + VSYSCALL32_EHDR->e_phoff); \ + int i; \ + for (i = 0; i < VSYSCALL32_EHDR->e_phnum; ++i) { \ + if (vsyscall_phdrs[i].p_type == PT_LOAD) \ + DUMP_WRITE((void *) (u64) vsyscall_phdrs[i].p_vaddr, \ + PAGE_ALIGN(vsyscall_phdrs[i].p_memsz)); \ } \ } while (0) diff --git a/trunk/arch/x86_64/kernel/e820.c b/trunk/arch/x86_64/kernel/e820.c index 764bf23c7103..e56c2adf57a4 100644 --- a/trunk/arch/x86_64/kernel/e820.c +++ b/trunk/arch/x86_64/kernel/e820.c @@ -71,11 +71,7 @@ static inline int bad_addr(unsigned long *addrp, unsigned long size) #endif /* kernel code + 640k memory hole (later should not be needed, but be paranoid for now) */ - if (last >= 640*1024 && addr < 1024*1024) { - *addrp = 1024*1024; - return 1; - } - if (last >= __pa_symbol(&_text) && last < __pa_symbol(&_end)) { + if (last >= 640*1024 && addr < __pa_symbol(&_end)) { *addrp = __pa_symbol(&_end); return 1; } @@ -108,6 +104,35 @@ e820_any_mapped(unsigned long start, unsigned long end, unsigned type) return 0; } +/* + * This function checks if the entire range is mapped with type. + * + * Note: this function only works correct if the e820 table is sorted and + * not-overlapping, which is the case + */ +int __init e820_all_mapped(unsigned long start, unsigned long end, unsigned type) +{ + int i; + for (i = 0; i < e820.nr_map; i++) { + struct e820entry *ei = &e820.map[i]; + if (type && ei->type != type) + continue; + /* is the region (part) in overlap with the current region ?*/ + if (ei->addr >= end || ei->addr + ei->size <= start) + continue; + + /* if the region is at the beginning of we move + * start to the end of the region since it's ok until there + */ + if (ei->addr <= start) + start = ei->addr + ei->size; + /* if start is now at or beyond end, we're done, full coverage */ + if (start >= end) + return 1; /* we're done */ + } + return 0; +} + /* * Find a free area in a specific range. */ diff --git a/trunk/arch/x86_64/kernel/entry.S b/trunk/arch/x86_64/kernel/entry.S index aa8d8939abc1..6f810424df44 100644 --- a/trunk/arch/x86_64/kernel/entry.S +++ b/trunk/arch/x86_64/kernel/entry.S @@ -973,8 +973,6 @@ ENTRY(kernel_thread) ENDPROC(kernel_thread) child_rip: - pushq $0 # fake return address - CFI_STARTPROC /* * Here we are in the child and the registers are set as they were * at kernel_thread() invocation in the parent. @@ -985,7 +983,6 @@ child_rip: # exit xorl %edi, %edi call do_exit - CFI_ENDPROC ENDPROC(child_rip) /* diff --git a/trunk/arch/x86_64/kernel/head.S b/trunk/arch/x86_64/kernel/head.S index c9739ca81d06..6df05e6034fa 100644 --- a/trunk/arch/x86_64/kernel/head.S +++ b/trunk/arch/x86_64/kernel/head.S @@ -191,7 +191,6 @@ startup_64: * jump */ movq initial_code(%rip),%rax - pushq $0 # fake return address jmp *%rax /* SMP bootup changes these two */ diff --git a/trunk/arch/x86_64/kernel/init_task.c b/trunk/arch/x86_64/kernel/init_task.c index 3dc5854ba21e..ce31d904d601 100644 --- a/trunk/arch/x86_64/kernel/init_task.c +++ b/trunk/arch/x86_64/kernel/init_task.c @@ -46,9 +46,4 @@ EXPORT_SYMBOL(init_task); */ DEFINE_PER_CPU(struct tss_struct, init_tss) ____cacheline_internodealigned_in_smp = INIT_TSS; -/* Copies of the original ist values from the tss are only accessed during - * debugging, no special alignment required. - */ -DEFINE_PER_CPU(struct orig_ist, orig_ist); - #define ALIGN_TO_4K __attribute__((section(".data.init_task"))) diff --git a/trunk/arch/x86_64/kernel/setup.c b/trunk/arch/x86_64/kernel/setup.c index 34afad704824..8a099ff1f8bc 100644 --- a/trunk/arch/x86_64/kernel/setup.c +++ b/trunk/arch/x86_64/kernel/setup.c @@ -521,6 +521,8 @@ static void discover_ebda(void) void __init setup_arch(char **cmdline_p) { + unsigned long kernel_end; + ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV); screen_info = SCREEN_INFO; edid_info = EDID_INFO; @@ -594,8 +596,8 @@ void __init setup_arch(char **cmdline_p) (table_end - table_start) << PAGE_SHIFT); /* reserve kernel */ - reserve_bootmem_generic(__pa_symbol(&_text), - __pa_symbol(&_end) - __pa_symbol(&_text)); + kernel_end = round_up(__pa_symbol(&_end),PAGE_SIZE); + reserve_bootmem_generic(HIGH_MEMORY, kernel_end - HIGH_MEMORY); /* * reserve physical page 0 - it's a special BIOS page on many boxes, diff --git a/trunk/arch/x86_64/kernel/setup64.c b/trunk/arch/x86_64/kernel/setup64.c index 417de564456e..6fe58a634b5f 100644 --- a/trunk/arch/x86_64/kernel/setup64.c +++ b/trunk/arch/x86_64/kernel/setup64.c @@ -189,7 +189,6 @@ void __cpuinit cpu_init (void) { int cpu = stack_smp_processor_id(); struct tss_struct *t = &per_cpu(init_tss, cpu); - struct orig_ist *orig_ist = &per_cpu(orig_ist, cpu); unsigned long v; char *estacks = NULL; struct task_struct *me; @@ -257,7 +256,7 @@ void __cpuinit cpu_init (void) estacks += EXCEPTION_STKSZ; break; } - orig_ist->ist[v] = t->ist[v] = (unsigned long)estacks; + t->ist[v] = (unsigned long)estacks; } t->io_bitmap_base = offsetof(struct tss_struct, io_bitmap); diff --git a/trunk/arch/x86_64/kernel/traps.c b/trunk/arch/x86_64/kernel/traps.c index b1249774d1e8..14052f089814 100644 --- a/trunk/arch/x86_64/kernel/traps.c +++ b/trunk/arch/x86_64/kernel/traps.c @@ -107,11 +107,7 @@ static inline void preempt_conditional_cli(struct pt_regs *regs) } static int kstack_depth_to_print = 12; -#ifdef CONFIG_STACK_UNWIND static int call_trace = 1; -#else -#define call_trace (-1) -#endif #ifdef CONFIG_KALLSYMS # include @@ -178,7 +174,7 @@ static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack, break; #endif default: - end = per_cpu(orig_ist, cpu).ist[k]; + end = per_cpu(init_tss, cpu).ist[k]; break; } /* @@ -278,21 +274,21 @@ void show_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long * s if (unwind_init_blocked(&info, tsk) == 0) unw_ret = show_trace_unwind(&info, NULL); } - if (unw_ret > 0) { - if (call_trace == 1 && !arch_unw_user_mode(&info)) { - print_symbol("DWARF2 unwinder stuck at %s\n", - UNW_PC(&info)); - if ((long)UNW_SP(&info) < 0) { - printk("Leftover inexact backtrace:\n"); - stack = (unsigned long *)UNW_SP(&info); - } else - printk("Full inexact backtrace again:\n"); - } else if (call_trace >= 1) + if (unw_ret > 0 && !arch_unw_user_mode(&info)) { +#ifdef CONFIG_STACK_UNWIND + unsigned long rip = info.regs.rip; + print_symbol("DWARF2 unwinder stuck at %s\n", rip); + if (call_trace == 1) { + printk("Leftover inexact backtrace:\n"); + stack = (unsigned long *)info.regs.rsp; + } else if (call_trace > 1) return; else printk("Full inexact backtrace again:\n"); - } else +#else printk("Inexact backtrace:\n"); +#endif + } } /* @@ -1124,7 +1120,6 @@ static int __init kstack_setup(char *s) } __setup("kstack=", kstack_setup); -#ifdef CONFIG_STACK_UNWIND static int __init call_trace_setup(char *s) { if (strcmp(s, "old") == 0) @@ -1138,4 +1133,3 @@ static int __init call_trace_setup(char *s) return 1; } __setup("call_trace=", call_trace_setup); -#endif diff --git a/trunk/arch/x86_64/pci/mmconfig.c b/trunk/arch/x86_64/pci/mmconfig.c index 2d48a7941d48..3c55c76c6fd5 100644 --- a/trunk/arch/x86_64/pci/mmconfig.c +++ b/trunk/arch/x86_64/pci/mmconfig.c @@ -9,7 +9,6 @@ #include #include #include -#include #include #include "pci.h" @@ -165,33 +164,11 @@ static __init void unreachable_devices(void) } } -static int disable_mcfg(struct dmi_system_id *d) -{ - printk("PCI: %s detected. Disabling MCFG.\n", d->ident); - pci_probe &= ~PCI_PROBE_MMCONF; - return 0; -} - -static struct dmi_system_id __initdata dmi_bad_mcfg[] = { - /* Has broken MCFG table that makes the system hang when used */ - { - .callback = disable_mcfg, - .ident = "Intel D3C5105 SDV", - .matches = { - DMI_MATCH(DMI_BIOS_VENDOR, "Intel"), - DMI_MATCH(DMI_BOARD_NAME, "D26928"), - }, - }, - {} -}; - void __init pci_mmcfg_init(void) { int i; - dmi_check_system(dmi_bad_mcfg); - - if ((pci_probe & (PCI_PROBE_MMCONF|PCI_PROBE_MMCONF_FORCE)) == 0) + if ((pci_probe & PCI_PROBE_MMCONF) == 0) return; acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg); @@ -200,6 +177,15 @@ void __init pci_mmcfg_init(void) (pci_mmcfg_config[0].base_address == 0)) return; + if (!e820_all_mapped(pci_mmcfg_config[0].base_address, + pci_mmcfg_config[0].base_address + MMCONFIG_APER_MIN, + E820_RESERVED)) { + printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %x is not E820-reserved\n", + pci_mmcfg_config[0].base_address); + printk(KERN_ERR "PCI: Not using MMCONFIG.\n"); + return; + } + /* RED-PEN i386 doesn't do _nocache right now */ pci_mmcfg_virt = kmalloc(sizeof(*pci_mmcfg_virt) * pci_mmcfg_config_num, GFP_KERNEL); if (pci_mmcfg_virt == NULL) { diff --git a/trunk/arch/xtensa/kernel/ptrace.c b/trunk/arch/xtensa/kernel/ptrace.c index 9aea23cc0dc5..5064d9383963 100644 --- a/trunk/arch/xtensa/kernel/ptrace.c +++ b/trunk/arch/xtensa/kernel/ptrace.c @@ -212,7 +212,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) */ case PTRACE_KILL: ret = 0; - if (child->exit_state == EXIT_ZOMBIE) /* already dead */ + if (child->state == EXIT_ZOMBIE) /* already dead */ break; child->exit_code = SIGKILL; child->ptrace &= ~PT_SINGLESTEP; diff --git a/trunk/block/cfq-iosched.c b/trunk/block/cfq-iosched.c index 3a3aee08ec5f..aae3123bf3ee 100644 --- a/trunk/block/cfq-iosched.c +++ b/trunk/block/cfq-iosched.c @@ -1561,7 +1561,7 @@ cfq_cic_link(struct cfq_data *cfqd, struct io_context *ioc, /* ->key must be copied to avoid race with cfq_exit_queue() */ k = __cic->key; if (unlikely(!k)) { - cfq_drop_dead_cic(ioc, __cic); + cfq_drop_dead_cic(ioc, cic); goto restart; } diff --git a/trunk/block/elevator.c b/trunk/block/elevator.c index 9b72dc7c8a5c..bc7baeec0d10 100644 --- a/trunk/block/elevator.c +++ b/trunk/block/elevator.c @@ -765,8 +765,7 @@ void elv_unregister(struct elevator_type *e) read_lock(&tasklist_lock); do_each_thread(g, p) { task_lock(p); - if (p->io_context) - e->ops.trim(p->io_context); + e->ops.trim(p->io_context); task_unlock(p); } while_each_thread(g, p); read_unlock(&tasklist_lock); diff --git a/trunk/block/ll_rw_blk.c b/trunk/block/ll_rw_blk.c index ddd9253f9d55..61d6b3c65b66 100644 --- a/trunk/block/ll_rw_blk.c +++ b/trunk/block/ll_rw_blk.c @@ -3628,8 +3628,6 @@ struct io_context *current_io_context(gfp_t gfp_flags) ret->nr_batch_requests = 0; /* because this is 0 */ ret->aic = NULL; ret->cic_root.rb_node = NULL; - /* make sure set_task_ioprio() sees the settings above */ - smp_wmb(); tsk->io_context = ret; } diff --git a/trunk/drivers/acpi/ac.c b/trunk/drivers/acpi/ac.c index 11abc7bf777e..96309b9660da 100644 --- a/trunk/drivers/acpi/ac.c +++ b/trunk/drivers/acpi/ac.c @@ -285,8 +285,6 @@ static int __init acpi_ac_init(void) { int result; - if (acpi_disabled) - return -ENODEV; acpi_ac_dir = acpi_lock_ac_dir(); if (!acpi_ac_dir) diff --git a/trunk/drivers/acpi/acpi_memhotplug.c b/trunk/drivers/acpi/acpi_memhotplug.c index 1dda370f402b..b0d4b147b19e 100644 --- a/trunk/drivers/acpi/acpi_memhotplug.c +++ b/trunk/drivers/acpi/acpi_memhotplug.c @@ -484,8 +484,10 @@ acpi_memory_register_notify_handler(acpi_handle handle, status = is_memory_device(handle); - if (ACPI_FAILURE(status)) + if (ACPI_FAILURE(status)){ + ACPI_EXCEPTION((AE_INFO, status, "handle is no memory device")); return AE_OK; /* continue */ + } status = acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, acpi_memory_device_notify, NULL); @@ -501,8 +503,10 @@ acpi_memory_deregister_notify_handler(acpi_handle handle, status = is_memory_device(handle); - if (ACPI_FAILURE(status)) + if (ACPI_FAILURE(status)){ + ACPI_EXCEPTION((AE_INFO, status, "handle is no memory device")); return AE_OK; /* continue */ + } status = acpi_remove_notify_handler(handle, ACPI_SYSTEM_NOTIFY, diff --git a/trunk/drivers/acpi/battery.c b/trunk/drivers/acpi/battery.c index 9810e2a55d0a..6e5221707d97 100644 --- a/trunk/drivers/acpi/battery.c +++ b/trunk/drivers/acpi/battery.c @@ -757,9 +757,6 @@ static int __init acpi_battery_init(void) { int result; - if (acpi_disabled) - return -ENODEV; - acpi_battery_dir = acpi_lock_battery_dir(); if (!acpi_battery_dir) return -ENODEV; diff --git a/trunk/drivers/acpi/bus.c b/trunk/drivers/acpi/bus.c index 279c4bac92e5..b2977695e120 100644 --- a/trunk/drivers/acpi/bus.c +++ b/trunk/drivers/acpi/bus.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include @@ -69,8 +68,7 @@ int acpi_bus_get_device(acpi_handle handle, struct acpi_device **device) status = acpi_get_data(handle, acpi_bus_data_handler, (void **)device); if (ACPI_FAILURE(status) || !*device) { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No context for object [%p]\n", - handle)); + ACPI_EXCEPTION((AE_INFO, status, "No context for object [%p]", handle)); return -ENODEV; } @@ -194,7 +192,7 @@ int acpi_bus_set_power(acpi_handle handle, int state) /* Make sure this is a valid target state */ if (!device->flags.power_manageable) { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device `[%s]' is not power manageable\n", + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device `[%s]' is not power manageable", device->kobj.name)); return -ENODEV; } @@ -740,10 +738,7 @@ static int __init acpi_init(void) return -ENODEV; } - result = firmware_register(&acpi_subsys); - if (result < 0) - printk(KERN_WARNING "%s: firmware_register error: %d\n", - __FUNCTION__, result); + firmware_register(&acpi_subsys); result = acpi_bus_init(); diff --git a/trunk/drivers/acpi/hotkey.c b/trunk/drivers/acpi/hotkey.c index 1ba2db671865..32c9d88fd196 100644 --- a/trunk/drivers/acpi/hotkey.c +++ b/trunk/drivers/acpi/hotkey.c @@ -91,14 +91,6 @@ enum { HK_EVENT_ENTERRING_S5, }; -enum conf_entry_enum { - bus_handle = 0, - bus_method = 1, - action_handle = 2, - method = 3, - LAST_CONF_ENTRY -}; - /* procdir we use */ static struct proc_dir_entry *hotkey_proc_dir; static struct proc_dir_entry *hotkey_config; @@ -252,15 +244,19 @@ static int hotkey_info_open_fs(struct inode *inode, struct file *file) static char *format_result(union acpi_object *object) { - char *buf; + char *buf = NULL; + + buf = (char *)kmalloc(RESULT_STR_LEN, GFP_KERNEL); + if (buf) + memset(buf, 0, RESULT_STR_LEN); + else + goto do_fail; - buf = kzalloc(RESULT_STR_LEN, GFP_KERNEL); - if (!buf) - return NULL; /* Now, just support integer type */ if (object->type == ACPI_TYPE_INTEGER) sprintf(buf, "%d\n", (u32) object->integer.value); - return buf; + do_fail: + return (buf); } static int hotkey_polling_seq_show(struct seq_file *seq, void *offset) @@ -490,102 +486,98 @@ static void free_hotkey_device(union acpi_hotkey *key) static void free_hotkey_buffer(union acpi_hotkey *key) { - /* key would never be null, action method could be */ kfree(key->event_hotkey.action_method); } static void free_poll_hotkey_buffer(union acpi_hotkey *key) { - /* key would never be null, others could be*/ kfree(key->poll_hotkey.action_method); kfree(key->poll_hotkey.poll_method); kfree(key->poll_hotkey.poll_result); } static int -init_hotkey_device(union acpi_hotkey *key, char **config_entry, - int std_num, int external_num) +init_hotkey_device(union acpi_hotkey *key, char *bus_str, char *action_str, + char *method, int std_num, int external_num) { acpi_handle tmp_handle; acpi_status status = AE_OK; + if (std_num < 0 || IS_POLL(std_num) || !key) goto do_fail; - if (!config_entry[bus_handle] || !config_entry[action_handle] - || !config_entry[method]) + if (!bus_str || !action_str || !method) goto do_fail; key->link.hotkey_type = ACPI_HOTKEY_EVENT; key->link.hotkey_standard_num = std_num; key->event_hotkey.flag = 0; - key->event_hotkey.action_method = config_entry[method]; + key->event_hotkey.action_method = method; - status = acpi_get_handle(NULL, config_entry[bus_handle], - &(key->event_hotkey.bus_handle)); + status = + acpi_get_handle(NULL, bus_str, &(key->event_hotkey.bus_handle)); if (ACPI_FAILURE(status)) - goto do_fail_zero; + goto do_fail; key->event_hotkey.external_hotkey_num = external_num; - status = acpi_get_handle(NULL, config_entry[action_handle], + status = + acpi_get_handle(NULL, action_str, &(key->event_hotkey.action_handle)); if (ACPI_FAILURE(status)) - goto do_fail_zero; + goto do_fail; status = acpi_get_handle(key->event_hotkey.action_handle, - config_entry[method], &tmp_handle); + method, &tmp_handle); if (ACPI_FAILURE(status)) - goto do_fail_zero; + goto do_fail; return AE_OK; -do_fail_zero: - key->event_hotkey.action_method = NULL; -do_fail: + do_fail: return -ENODEV; } static int -init_poll_hotkey_device(union acpi_hotkey *key, char **config_entry, - int std_num) +init_poll_hotkey_device(union acpi_hotkey *key, + char *poll_str, + char *poll_method, + char *action_str, char *action_method, int std_num) { acpi_status status = AE_OK; acpi_handle tmp_handle; + if (std_num < 0 || IS_EVENT(std_num) || !key) goto do_fail; - if (!config_entry[bus_handle] ||!config_entry[bus_method] || - !config_entry[action_handle] || !config_entry[method]) + + if (!poll_str || !poll_method || !action_str || !action_method) goto do_fail; key->link.hotkey_type = ACPI_HOTKEY_POLLING; key->link.hotkey_standard_num = std_num; key->poll_hotkey.flag = 0; - key->poll_hotkey.poll_method = config_entry[bus_method]; - key->poll_hotkey.action_method = config_entry[method]; + key->poll_hotkey.poll_method = poll_method; + key->poll_hotkey.action_method = action_method; - status = acpi_get_handle(NULL, config_entry[bus_handle], - &(key->poll_hotkey.poll_handle)); + status = + acpi_get_handle(NULL, poll_str, &(key->poll_hotkey.poll_handle)); if (ACPI_FAILURE(status)) - goto do_fail_zero; + goto do_fail; status = acpi_get_handle(key->poll_hotkey.poll_handle, - config_entry[bus_method], &tmp_handle); + poll_method, &tmp_handle); if (ACPI_FAILURE(status)) - goto do_fail_zero; + goto do_fail; status = - acpi_get_handle(NULL, config_entry[action_handle], + acpi_get_handle(NULL, action_str, &(key->poll_hotkey.action_handle)); if (ACPI_FAILURE(status)) - goto do_fail_zero; + goto do_fail; status = acpi_get_handle(key->poll_hotkey.action_handle, - config_entry[method], &tmp_handle); + action_method, &tmp_handle); if (ACPI_FAILURE(status)) - goto do_fail_zero; + goto do_fail; key->poll_hotkey.poll_result = (union acpi_object *)kmalloc(sizeof(union acpi_object), GFP_KERNEL); if (!key->poll_hotkey.poll_result) - goto do_fail_zero; + goto do_fail; return AE_OK; - -do_fail_zero: - key->poll_hotkey.poll_method = NULL; - key->poll_hotkey.action_method = NULL; -do_fail: + do_fail: return -ENODEV; } @@ -660,18 +652,17 @@ static int hotkey_poll_config_seq_show(struct seq_file *seq, void *offset) } static int -get_parms(char *config_record, int *cmd, char **config_entry, - int *internal_event_num, int *external_event_num) +get_parms(char *config_record, + int *cmd, + char **bus_handle, + char **bus_method, + char **action_handle, + char **method, int *internal_event_num, int *external_event_num) { -/* the format of *config_record = - * "1:\d+:*" : "cmd:internal_event_num" - * "\d+:\w+:\w+:\w+:\w+:\d+:\d+" : - * "cmd:bus_handle:bus_method:action_handle:method:internal_event_num:external_event_num" - */ char *tmp, *tmp1, count; - int i; sscanf(config_record, "%d", cmd); + if (*cmd == 1) { if (sscanf(config_record, "%d:%d", cmd, internal_event_num) != 2) @@ -683,27 +674,59 @@ get_parms(char *config_record, int *cmd, char **config_entry, if (!tmp) goto do_fail; tmp++; - for (i = 0; i < LAST_CONF_ENTRY; i++) { - tmp1 = strchr(tmp, ':'); - if (!tmp1) { - goto do_fail; - } - count = tmp1 - tmp; - config_entry[i] = kzalloc(count + 1, GFP_KERNEL); - if (!config_entry[i]) - goto handle_failure; - strncpy(config_entry[i], tmp, count); - tmp = tmp1 + 1; - } - if (sscanf(tmp, "%d:%d", internal_event_num, external_event_num) <= 0) - goto handle_failure; - if (!IS_OTHERS(*internal_event_num)) { - return 6; - } -handle_failure: - while (i-- > 0) - kfree(config_entry[i]); -do_fail: + tmp1 = strchr(tmp, ':'); + if (!tmp1) + goto do_fail; + + count = tmp1 - tmp; + *bus_handle = (char *)kmalloc(count + 1, GFP_KERNEL); + if (!*bus_handle) + goto do_fail; + strncpy(*bus_handle, tmp, count); + *(*bus_handle + count) = 0; + + tmp = tmp1; + tmp++; + tmp1 = strchr(tmp, ':'); + if (!tmp1) + goto do_fail; + count = tmp1 - tmp; + *bus_method = (char *)kmalloc(count + 1, GFP_KERNEL); + if (!*bus_method) + goto do_fail; + strncpy(*bus_method, tmp, count); + *(*bus_method + count) = 0; + + tmp = tmp1; + tmp++; + tmp1 = strchr(tmp, ':'); + if (!tmp1) + goto do_fail; + count = tmp1 - tmp; + *action_handle = (char *)kmalloc(count + 1, GFP_KERNEL); + if (!*action_handle) + goto do_fail; + strncpy(*action_handle, tmp, count); + *(*action_handle + count) = 0; + + tmp = tmp1; + tmp++; + tmp1 = strchr(tmp, ':'); + if (!tmp1) + goto do_fail; + count = tmp1 - tmp; + *method = (char *)kmalloc(count + 1, GFP_KERNEL); + if (!*method) + goto do_fail; + strncpy(*method, tmp, count); + *(*method + count) = 0; + + if (sscanf(tmp1 + 1, "%d:%d", internal_event_num, external_event_num) <= + 0) + goto do_fail; + + return 6; + do_fail: return -1; } @@ -713,34 +736,50 @@ static ssize_t hotkey_write_config(struct file *file, size_t count, loff_t * data) { char *config_record = NULL; - char *config_entry[LAST_CONF_ENTRY]; + char *bus_handle = NULL; + char *bus_method = NULL; + char *action_handle = NULL; + char *method = NULL; int cmd, internal_event_num, external_event_num; int ret = 0; - union acpi_hotkey *key = kzalloc(sizeof(union acpi_hotkey), GFP_KERNEL); + union acpi_hotkey *key = NULL; - if (!key) - return -ENOMEM; - config_record = kzalloc(count + 1, GFP_KERNEL); - if (!config_record) { - kfree(key); + config_record = (char *)kmalloc(count + 1, GFP_KERNEL); + if (!config_record) return -ENOMEM; - } if (copy_from_user(config_record, buffer, count)) { kfree(config_record); - kfree(key); printk(KERN_ERR PREFIX "Invalid data\n"); return -EINVAL; } - ret = get_parms(config_record, &cmd, config_entry, - &internal_event_num, &external_event_num); + config_record[count] = 0; + + ret = get_parms(config_record, + &cmd, + &bus_handle, + &bus_method, + &action_handle, + &method, &internal_event_num, &external_event_num); + kfree(config_record); + if (IS_OTHERS(internal_event_num)) + goto do_fail; if (ret != 6) { + do_fail: + kfree(bus_handle); + kfree(bus_method); + kfree(action_handle); + kfree(method); printk(KERN_ERR PREFIX "Invalid data format ret=%d\n", ret); return -EINVAL; } + key = kmalloc(sizeof(union acpi_hotkey), GFP_KERNEL); + if (!key) + goto do_fail; + memset(key, 0, sizeof(union acpi_hotkey)); if (cmd == 1) { union acpi_hotkey *tmp = NULL; tmp = get_hotkey_by_event(&global_hotkey_list, @@ -752,19 +791,34 @@ static ssize_t hotkey_write_config(struct file *file, goto cont_cmd; } if (IS_EVENT(internal_event_num)) { - if (init_hotkey_device(key, config_entry, - internal_event_num, external_event_num)) - goto init_hotkey_fail; - } else { - if (init_poll_hotkey_device(key, config_entry, - internal_event_num)) - goto init_poll_hotkey_fail; + kfree(bus_method); + ret = init_hotkey_device(key, bus_handle, action_handle, method, + internal_event_num, + external_event_num); + } else + ret = init_poll_hotkey_device(key, bus_handle, bus_method, + action_handle, method, + internal_event_num); + if (ret) { + kfree(bus_handle); + kfree(action_handle); + if (IS_EVENT(internal_event_num)) + free_hotkey_buffer(key); + else + free_poll_hotkey_buffer(key); + kfree(key); + printk(KERN_ERR PREFIX "Invalid hotkey\n"); + return -EINVAL; } -cont_cmd: + + cont_cmd: + kfree(bus_handle); + kfree(action_handle); + switch (cmd) { case 0: - if (get_hotkey_by_event(&global_hotkey_list, - key->link.hotkey_standard_num)) + if (get_hotkey_by_event + (&global_hotkey_list, key->link.hotkey_standard_num)) goto fail_out; else hotkey_add(key); @@ -773,7 +827,6 @@ static ssize_t hotkey_write_config(struct file *file, hotkey_remove(key); break; case 2: - /* key is kfree()ed if matched*/ if (hotkey_update(key)) goto fail_out; break; @@ -782,22 +835,11 @@ static ssize_t hotkey_write_config(struct file *file, break; } return count; - -init_poll_hotkey_fail: /* failed init_poll_hotkey_device */ - kfree(config_entry[bus_method]); - config_entry[bus_method] = NULL; -init_hotkey_fail: /* failed init_hotkey_device */ - kfree(config_entry[method]); -fail_out: - kfree(config_entry[bus_handle]); - kfree(config_entry[action_handle]); - /* No double free since elements =NULL for error cases */ - if (IS_EVENT(internal_event_num)) { - if (config_entry[bus_method]) - kfree(config_entry[bus_method]); - free_hotkey_buffer(key); /* frees [method] */ - } else - free_poll_hotkey_buffer(key); /* frees [bus_method]+[method] */ + fail_out: + if (IS_EVENT(internal_event_num)) + free_hotkey_buffer(key); + else + free_poll_hotkey_buffer(key); kfree(key); printk(KERN_ERR PREFIX "invalid key\n"); return -EINVAL; @@ -881,9 +923,10 @@ static ssize_t hotkey_execute_aml_method(struct file *file, union acpi_hotkey *key; - arg = kzalloc(count + 1, GFP_KERNEL); + arg = (char *)kmalloc(count + 1, GFP_KERNEL); if (!arg) return -ENOMEM; + arg[count] = 0; if (copy_from_user(arg, buffer, count)) { kfree(arg); diff --git a/trunk/drivers/acpi/i2c_ec.c b/trunk/drivers/acpi/i2c_ec.c index 6809c283ec58..84239d51dc0c 100644 --- a/trunk/drivers/acpi/i2c_ec.c +++ b/trunk/drivers/acpi/i2c_ec.c @@ -330,7 +330,7 @@ static int acpi_ec_hc_add(struct acpi_device *device) status = acpi_evaluate_integer(ec_hc->handle, "_EC", NULL, &val); if (ACPI_FAILURE(status)) { ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Error obtaining _EC\n")); - kfree(ec_hc); + kfree(ec_hc->smbus); kfree(smbus); return -EIO; } diff --git a/trunk/drivers/acpi/osl.c b/trunk/drivers/acpi/osl.c index 507f051d1cef..b7d1514cd199 100644 --- a/trunk/drivers/acpi/osl.c +++ b/trunk/drivers/acpi/osl.c @@ -746,16 +746,6 @@ acpi_status acpi_os_wait_semaphore(acpi_handle handle, u32 units, u16 timeout) ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Waiting for semaphore[%p|%d|%d]\n", handle, units, timeout)); - /* - * This can be called during resume with interrupts off. - * Like boot-time, we should be single threaded and will - * always get the lock if we try -- timeout or not. - * If this doesn't succeed, then we will oops courtesy of - * might_sleep() in down(). - */ - if (!down_trylock(sem)) - return AE_OK; - switch (timeout) { /* * No Wait: diff --git a/trunk/drivers/acpi/sbs.c b/trunk/drivers/acpi/sbs.c index 62bef0b3b614..db7b350a5035 100644 --- a/trunk/drivers/acpi/sbs.c +++ b/trunk/drivers/acpi/sbs.c @@ -1714,9 +1714,6 @@ static int __init acpi_sbs_init(void) { int result = 0; - if (acpi_disabled) - return -ENODEV; - init_MUTEX(&sbs_sem); if (capacity_mode != DEF_CAPACITY_UNIT diff --git a/trunk/drivers/acpi/scan.c b/trunk/drivers/acpi/scan.c index 698a1540e303..5fcb50c7b778 100644 --- a/trunk/drivers/acpi/scan.c +++ b/trunk/drivers/acpi/scan.c @@ -4,7 +4,6 @@ #include #include -#include #include #include @@ -114,8 +113,6 @@ static struct kset acpi_namespace_kset = { static void acpi_device_register(struct acpi_device *device, struct acpi_device *parent) { - int err; - /* * Linkage * ------- @@ -141,10 +138,7 @@ static void acpi_device_register(struct acpi_device *device, device->kobj.parent = &parent->kobj; device->kobj.ktype = &ktype_acpi_ns; device->kobj.kset = &acpi_namespace_kset; - err = kobject_register(&device->kobj); - if (err < 0) - printk(KERN_WARNING "%s: kobject_register error: %d\n", - __FUNCTION__, err); + kobject_register(&device->kobj); create_sysfs_device_files(device); } @@ -1456,9 +1450,7 @@ static int __init acpi_scan_init(void) if (acpi_disabled) return 0; - result = kset_register(&acpi_namespace_kset); - if (result < 0) - printk(KERN_ERR PREFIX "kset_register error: %d\n", result); + kset_register(&acpi_namespace_kset); result = bus_register(&acpi_bus_type); if (result) { diff --git a/trunk/drivers/acpi/utils.c b/trunk/drivers/acpi/utils.c index d0d84c43a9d4..f48227f4c8c9 100644 --- a/trunk/drivers/acpi/utils.c +++ b/trunk/drivers/acpi/utils.c @@ -262,7 +262,7 @@ acpi_evaluate_integer(acpi_handle handle, if (!data) return AE_BAD_PARAMETER; - element = kmalloc(sizeof(union acpi_object), irqs_disabled() ? GFP_ATOMIC: GFP_KERNEL); + element = kmalloc(sizeof(union acpi_object), GFP_KERNEL); if (!element) return AE_NO_MEMORY; diff --git a/trunk/drivers/base/node.c b/trunk/drivers/base/node.c index e9b0957f15d1..d7de1753e094 100644 --- a/trunk/drivers/base/node.c +++ b/trunk/drivers/base/node.c @@ -64,7 +64,7 @@ static ssize_t node_read_meminfo(struct sys_device * dev, char * buf) "Node %d Mapped: %8lu kB\n" "Node %d AnonPages: %8lu kB\n" "Node %d PageTables: %8lu kB\n" - "Node %d NFS_Unstable: %8lu kB\n" + "Node %d NFS Unstable: %8lu kB\n" "Node %d Bounce: %8lu kB\n" "Node %d Slab: %8lu kB\n", nid, K(i.totalram), diff --git a/trunk/drivers/block/floppy.c b/trunk/drivers/block/floppy.c index ad1d7065a1b2..5109fa37c662 100644 --- a/trunk/drivers/block/floppy.c +++ b/trunk/drivers/block/floppy.c @@ -4177,11 +4177,6 @@ static int __init floppy_init(void) int i, unit, drive; int err, dr; -#if defined(CONFIG_PPC_MERGE) - if (check_legacy_ioport(FDC1)) - return -ENODEV; -#endif - raw_cmd = NULL; for (dr = 0; dr < N_DRIVE; dr++) { @@ -4239,6 +4234,13 @@ static int __init floppy_init(void) } use_virtual_dma = can_use_virtual_dma & 1; +#if defined(CONFIG_PPC_MERGE) + if (check_legacy_ioport(FDC1)) { + del_timer(&fd_timeout); + err = -ENODEV; + goto out_unreg_region; + } +#endif fdc_state[0].address = FDC1; if (fdc_state[0].address == -1) { del_timer(&fd_timeout); diff --git a/trunk/drivers/cdrom/gscd.c b/trunk/drivers/cdrom/gscd.c index fa7082489765..b6ee50a2916d 100644 --- a/trunk/drivers/cdrom/gscd.c +++ b/trunk/drivers/cdrom/gscd.c @@ -266,7 +266,7 @@ static void __do_gscd_request(unsigned long dummy) goto out; if (req->cmd != READ) { - printk("GSCD: bad cmd %u\n", rq_data_dir(req)); + printk("GSCD: bad cmd %lu\n", rq_data_dir(req)); end_request(req, 0); goto repeat; } diff --git a/trunk/drivers/char/drm/radeon_state.c b/trunk/drivers/char/drm/radeon_state.c index 39a7f685e3fd..5bb2234a9094 100644 --- a/trunk/drivers/char/drm/radeon_state.c +++ b/trunk/drivers/char/drm/radeon_state.c @@ -175,14 +175,6 @@ static __inline__ int radeon_check_and_fixup_packets(drm_radeon_private_t * } break; - case R200_EMIT_VAP_CTL:{ - RING_LOCALS; - BEGIN_RING(2); - OUT_RING_REG(RADEON_SE_TCL_STATE_FLUSH, 0); - ADVANCE_RING(); - } - break; - case RADEON_EMIT_RB3D_COLORPITCH: case RADEON_EMIT_RE_LINE_PATTERN: case RADEON_EMIT_SE_LINE_WIDTH: @@ -210,6 +202,7 @@ static __inline__ int radeon_check_and_fixup_packets(drm_radeon_private_t * case R200_EMIT_TCL_LIGHT_MODEL_CTL_0: case R200_EMIT_TFACTOR_0: case R200_EMIT_VTX_FMT_0: + case R200_EMIT_VAP_CTL: case R200_EMIT_MATRIX_SELECT_0: case R200_EMIT_TEX_PROC_CTL_2: case R200_EMIT_TCL_UCP_VERT_BLEND_CTL: diff --git a/trunk/drivers/char/ipmi/ipmi_msghandler.c b/trunk/drivers/char/ipmi/ipmi_msghandler.c index 843d34c8627c..0aa5d608fe6f 100644 --- a/trunk/drivers/char/ipmi/ipmi_msghandler.c +++ b/trunk/drivers/char/ipmi/ipmi_msghandler.c @@ -3428,7 +3428,6 @@ struct ipmi_recv_msg *ipmi_alloc_recv_msg(void) rv = kmalloc(sizeof(struct ipmi_recv_msg), GFP_ATOMIC); if (rv) { - rv->user = NULL; rv->done = free_recv_msg; atomic_inc(&recv_msg_inuse_count); } diff --git a/trunk/drivers/char/moxa.c b/trunk/drivers/char/moxa.c index a369dd6877d8..4ea7bd5f4f56 100644 --- a/trunk/drivers/char/moxa.c +++ b/trunk/drivers/char/moxa.c @@ -142,7 +142,6 @@ typedef struct _moxa_board_conf { static moxa_board_conf moxa_boards[MAX_BOARDS]; static void __iomem *moxaBaseAddr[MAX_BOARDS]; -static int loadstat[MAX_BOARDS]; struct moxa_str { int type; @@ -1689,8 +1688,6 @@ int MoxaDriverPoll(void) if (moxaCard == 0) return (-1); for (card = 0; card < MAX_BOARDS; card++) { - if (loadstat[card] == 0) - continue; if ((ports = moxa_boards[card].numPorts) == 0) continue; if (readb(moxaIntPend[card]) == 0xff) { @@ -2906,7 +2903,6 @@ static int moxaloadcode(int cardno, unsigned char __user *tmp, int len) } break; } - loadstat[cardno] = 1; return (0); } @@ -2924,7 +2920,7 @@ static int moxaloadc218(int cardno, void __iomem *baseAddr, int len) len1 = len >> 1; ptr = (ushort *) moxaBuff; for (i = 0; i < len1; i++) - usum += le16_to_cpu(*(ptr + i)); + usum += *(ptr + i); retry = 0; do { len1 = len >> 1; @@ -2996,7 +2992,7 @@ static int moxaloadc320(int cardno, void __iomem *baseAddr, int len, int *numPor wlen = len >> 1; uptr = (ushort *) moxaBuff; for (i = 0; i < wlen; i++) - usum += le16_to_cpu(uptr[i]); + usum += uptr[i]; retry = 0; j = 0; do { diff --git a/trunk/drivers/char/synclink_gt.c b/trunk/drivers/char/synclink_gt.c index 2f07b085536b..b2dbbdb1bf81 100644 --- a/trunk/drivers/char/synclink_gt.c +++ b/trunk/drivers/char/synclink_gt.c @@ -391,8 +391,8 @@ static MGSL_PARAMS default_params = { #define DESC_LIST_SIZE 4096 #define MASK_PARITY BIT1 -#define MASK_FRAMING BIT0 -#define MASK_BREAK BIT14 +#define MASK_FRAMING BIT2 +#define MASK_BREAK BIT3 #define MASK_OVERRUN BIT4 #define GSR 0x00 /* global status */ @@ -1800,17 +1800,17 @@ static void rx_async(struct slgt_info *info) stat = 0; - if ((status = *(p+1) & (BIT1 + BIT0))) { - if (status & BIT1) + if ((status = *(p+1) & (BIT9 + BIT8))) { + if (status & BIT9) icount->parity++; - else if (status & BIT0) + else if (status & BIT8) icount->frame++; /* discard char if tty control flags say so */ if (status & info->ignore_status_mask) continue; - if (status & BIT1) + if (status & BIT9) stat = TTY_PARITY; - else if (status & BIT0) + else if (status & BIT8) stat = TTY_FRAME; } if (tty) { diff --git a/trunk/drivers/char/tty_io.c b/trunk/drivers/char/tty_io.c index bb0d9199e994..bfdb90242a90 100644 --- a/trunk/drivers/char/tty_io.c +++ b/trunk/drivers/char/tty_io.c @@ -153,15 +153,6 @@ int tty_ioctl(struct inode * inode, struct file * file, static int tty_fasync(int fd, struct file * filp, int on); static void release_mem(struct tty_struct *tty, int idx); -/** - * alloc_tty_struct - allocate a tty object - * - * Return a new empty tty structure. The data fields have not - * been initialized in any way but has been zeroed - * - * Locking: none - * FIXME: use kzalloc - */ static struct tty_struct *alloc_tty_struct(void) { @@ -175,15 +166,6 @@ static struct tty_struct *alloc_tty_struct(void) static void tty_buffer_free_all(struct tty_struct *); -/** - * free_tty_struct - free a disused tty - * @tty: tty struct to free - * - * Free the write buffers, tty queue and tty memory itself. - * - * Locking: none. Must be called after tty is definitely unused - */ - static inline void free_tty_struct(struct tty_struct *tty) { kfree(tty->write_buf); @@ -193,17 +175,6 @@ static inline void free_tty_struct(struct tty_struct *tty) #define TTY_NUMBER(tty) ((tty)->index + (tty)->driver->name_base) -/** - * tty_name - return tty naming - * @tty: tty structure - * @buf: buffer for output - * - * Convert a tty structure into a name. The name reflects the kernel - * naming policy and if udev is in use may not reflect user space - * - * Locking: none - */ - char *tty_name(struct tty_struct *tty, char *buf) { if (!tty) /* Hmm. NULL pointer. That's fun. */ @@ -264,28 +235,6 @@ static int check_tty_count(struct tty_struct *tty, const char *routine) * Tty buffer allocation management */ - -/** - * tty_buffer_free_all - free buffers used by a tty - * @tty: tty to free from - * - * Remove all the buffers pending on a tty whether queued with data - * or in the free ring. Must be called when the tty is no longer in use - * - * Locking: none - */ - - -/** - * tty_buffer_free_all - free buffers used by a tty - * @tty: tty to free from - * - * Remove all the buffers pending on a tty whether queued with data - * or in the free ring. Must be called when the tty is no longer in use - * - * Locking: none - */ - static void tty_buffer_free_all(struct tty_struct *tty) { struct tty_buffer *thead; @@ -298,47 +247,19 @@ static void tty_buffer_free_all(struct tty_struct *tty) kfree(thead); } tty->buf.tail = NULL; - tty->buf.memory_used = 0; } -/** - * tty_buffer_init - prepare a tty buffer structure - * @tty: tty to initialise - * - * Set up the initial state of the buffer management for a tty device. - * Must be called before the other tty buffer functions are used. - * - * Locking: none - */ - static void tty_buffer_init(struct tty_struct *tty) { spin_lock_init(&tty->buf.lock); tty->buf.head = NULL; tty->buf.tail = NULL; tty->buf.free = NULL; - tty->buf.memory_used = 0; } -/** - * tty_buffer_alloc - allocate a tty buffer - * @tty: tty device - * @size: desired size (characters) - * - * Allocate a new tty buffer to hold the desired number of characters. - * Return NULL if out of memory or the allocation would exceed the - * per device queue - * - * Locking: Caller must hold tty->buf.lock - */ - -static struct tty_buffer *tty_buffer_alloc(struct tty_struct *tty, size_t size) +static struct tty_buffer *tty_buffer_alloc(size_t size) { - struct tty_buffer *p; - - if (tty->buf.memory_used + size > 65536) - return NULL; - p = kmalloc(sizeof(struct tty_buffer) + 2 * size, GFP_ATOMIC); + struct tty_buffer *p = kmalloc(sizeof(struct tty_buffer) + 2 * size, GFP_ATOMIC); if(p == NULL) return NULL; p->used = 0; @@ -348,27 +269,17 @@ static struct tty_buffer *tty_buffer_alloc(struct tty_struct *tty, size_t size) p->read = 0; p->char_buf_ptr = (char *)(p->data); p->flag_buf_ptr = (unsigned char *)p->char_buf_ptr + size; - tty->buf.memory_used += size; +/* printk("Flip create %p\n", p); */ return p; } -/** - * tty_buffer_free - free a tty buffer - * @tty: tty owning the buffer - * @b: the buffer to free - * - * Free a tty buffer, or add it to the free list according to our - * internal strategy - * - * Locking: Caller must hold tty->buf.lock - */ +/* Must be called with the tty_read lock held. This needs to acquire strategy + code to decide if we should kfree or relink a given expired buffer */ static void tty_buffer_free(struct tty_struct *tty, struct tty_buffer *b) { /* Dumb strategy for now - should keep some stats */ - tty->buf.memory_used -= b->size; - WARN_ON(tty->buf.memory_used < 0); - +/* printk("Flip dispose %p\n", b); */ if(b->size >= 512) kfree(b); else { @@ -377,18 +288,6 @@ static void tty_buffer_free(struct tty_struct *tty, struct tty_buffer *b) } } -/** - * tty_buffer_find - find a free tty buffer - * @tty: tty owning the buffer - * @size: characters wanted - * - * Locate an existing suitable tty buffer or if we are lacking one then - * allocate a new one. We round our buffers off in 256 character chunks - * to get better allocation behaviour. - * - * Locking: Caller must hold tty->buf.lock - */ - static struct tty_buffer *tty_buffer_find(struct tty_struct *tty, size_t size) { struct tty_buffer **tbh = &tty->buf.free; @@ -400,28 +299,20 @@ static struct tty_buffer *tty_buffer_find(struct tty_struct *tty, size_t size) t->used = 0; t->commit = 0; t->read = 0; - tty->buf.memory_used += t->size; + /* DEBUG ONLY */ +/* memset(t->data, '*', size); */ +/* printk("Flip recycle %p\n", t); */ return t; } tbh = &((*tbh)->next); } /* Round the buffer size out */ size = (size + 0xFF) & ~ 0xFF; - return tty_buffer_alloc(tty, size); + return tty_buffer_alloc(size); /* Should possibly check if this fails for the largest buffer we have queued and recycle that ? */ } -/** - * tty_buffer_request_room - grow tty buffer if needed - * @tty: tty structure - * @size: size desired - * - * Make at least size bytes of linear space available for the tty - * buffer. If we fail return the size we managed to find. - * - * Locking: Takes tty->buf.lock - */ int tty_buffer_request_room(struct tty_struct *tty, size_t size) { struct tty_buffer *b, *n; @@ -456,18 +347,6 @@ int tty_buffer_request_room(struct tty_struct *tty, size_t size) } EXPORT_SYMBOL_GPL(tty_buffer_request_room); -/** - * tty_insert_flip_string - Add characters to the tty buffer - * @tty: tty structure - * @chars: characters - * @size: size - * - * Queue a series of bytes to the tty buffering. All the characters - * passed are marked as without error. Returns the number added. - * - * Locking: Called functions may take tty->buf.lock - */ - int tty_insert_flip_string(struct tty_struct *tty, const unsigned char *chars, size_t size) { @@ -491,20 +370,6 @@ int tty_insert_flip_string(struct tty_struct *tty, const unsigned char *chars, } EXPORT_SYMBOL(tty_insert_flip_string); -/** - * tty_insert_flip_string_flags - Add characters to the tty buffer - * @tty: tty structure - * @chars: characters - * @flags: flag bytes - * @size: size - * - * Queue a series of bytes to the tty buffering. For each character - * the flags array indicates the status of the character. Returns the - * number added. - * - * Locking: Called functions may take tty->buf.lock - */ - int tty_insert_flip_string_flags(struct tty_struct *tty, const unsigned char *chars, const char *flags, size_t size) { @@ -529,17 +394,6 @@ int tty_insert_flip_string_flags(struct tty_struct *tty, } EXPORT_SYMBOL(tty_insert_flip_string_flags); -/** - * tty_schedule_flip - push characters to ldisc - * @tty: tty to push from - * - * Takes any pending buffers and transfers their ownership to the - * ldisc side of the queue. It then schedules those characters for - * processing by the line discipline. - * - * Locking: Takes tty->buf.lock - */ - void tty_schedule_flip(struct tty_struct *tty) { unsigned long flags; @@ -551,19 +405,12 @@ void tty_schedule_flip(struct tty_struct *tty) } EXPORT_SYMBOL(tty_schedule_flip); -/** - * tty_prepare_flip_string - make room for characters - * @tty: tty - * @chars: return pointer for character write area - * @size: desired size - * +/* * Prepare a block of space in the buffer for data. Returns the length * available and buffer pointer to the space which is now allocated and * accounted for as ready for normal characters. This is used for drivers * that need their own block copy routines into the buffer. There is no * guarantee the buffer is a DMA target! - * - * Locking: May call functions taking tty->buf.lock */ int tty_prepare_flip_string(struct tty_struct *tty, unsigned char **chars, size_t size) @@ -580,20 +427,12 @@ int tty_prepare_flip_string(struct tty_struct *tty, unsigned char **chars, size_ EXPORT_SYMBOL_GPL(tty_prepare_flip_string); -/** - * tty_prepare_flip_string_flags - make room for characters - * @tty: tty - * @chars: return pointer for character write area - * @flags: return pointer for status flag write area - * @size: desired size - * +/* * Prepare a block of space in the buffer for data. Returns the length * available and buffer pointer to the space which is now allocated and * accounted for as ready for characters. This is used for drivers * that need their own block copy routines into the buffer. There is no * guarantee the buffer is a DMA target! - * - * Locking: May call functions taking tty->buf.lock */ int tty_prepare_flip_string_flags(struct tty_struct *tty, unsigned char **chars, char **flags, size_t size) @@ -612,16 +451,10 @@ EXPORT_SYMBOL_GPL(tty_prepare_flip_string_flags); -/** - * tty_set_termios_ldisc - set ldisc field - * @tty: tty structure - * @num: line discipline number - * +/* * This is probably overkill for real world processors but * they are not on hot paths so a little discipline won't do * any harm. - * - * Locking: takes termios_sem */ static void tty_set_termios_ldisc(struct tty_struct *tty, int num) @@ -641,19 +474,6 @@ static DEFINE_SPINLOCK(tty_ldisc_lock); static DECLARE_WAIT_QUEUE_HEAD(tty_ldisc_wait); static struct tty_ldisc tty_ldiscs[NR_LDISCS]; /* line disc dispatch table */ -/** - * tty_register_ldisc - install a line discipline - * @disc: ldisc number - * @new_ldisc: pointer to the ldisc object - * - * Installs a new line discipline into the kernel. The discipline - * is set up as unreferenced and then made available to the kernel - * from this point onwards. - * - * Locking: - * takes tty_ldisc_lock to guard against ldisc races - */ - int tty_register_ldisc(int disc, struct tty_ldisc *new_ldisc) { unsigned long flags; @@ -673,18 +493,6 @@ int tty_register_ldisc(int disc, struct tty_ldisc *new_ldisc) } EXPORT_SYMBOL(tty_register_ldisc); -/** - * tty_unregister_ldisc - unload a line discipline - * @disc: ldisc number - * @new_ldisc: pointer to the ldisc object - * - * Remove a line discipline from the kernel providing it is not - * currently in use. - * - * Locking: - * takes tty_ldisc_lock to guard against ldisc races - */ - int tty_unregister_ldisc(int disc) { unsigned long flags; @@ -704,19 +512,6 @@ int tty_unregister_ldisc(int disc) } EXPORT_SYMBOL(tty_unregister_ldisc); -/** - * tty_ldisc_get - take a reference to an ldisc - * @disc: ldisc number - * - * Takes a reference to a line discipline. Deals with refcounts and - * module locking counts. Returns NULL if the discipline is not available. - * Returns a pointer to the discipline and bumps the ref count if it is - * available - * - * Locking: - * takes tty_ldisc_lock to guard against ldisc races - */ - struct tty_ldisc *tty_ldisc_get(int disc) { unsigned long flags; @@ -745,17 +540,6 @@ struct tty_ldisc *tty_ldisc_get(int disc) EXPORT_SYMBOL_GPL(tty_ldisc_get); -/** - * tty_ldisc_put - drop ldisc reference - * @disc: ldisc number - * - * Drop a reference to a line discipline. Manage refcounts and - * module usage counts - * - * Locking: - * takes tty_ldisc_lock to guard against ldisc races - */ - void tty_ldisc_put(int disc) { struct tty_ldisc *ld; @@ -773,19 +557,6 @@ void tty_ldisc_put(int disc) EXPORT_SYMBOL_GPL(tty_ldisc_put); -/** - * tty_ldisc_assign - set ldisc on a tty - * @tty: tty to assign - * @ld: line discipline - * - * Install an instance of a line discipline into a tty structure. The - * ldisc must have a reference count above zero to ensure it remains/ - * The tty instance refcount starts at zero. - * - * Locking: - * Caller must hold references - */ - static void tty_ldisc_assign(struct tty_struct *tty, struct tty_ldisc *ld) { tty->ldisc = *ld; @@ -800,8 +571,6 @@ static void tty_ldisc_assign(struct tty_struct *tty, struct tty_ldisc *ld) * the tty ldisc. Return 0 on failure or 1 on success. This is * used to implement both the waiting and non waiting versions * of tty_ldisc_ref - * - * Locking: takes tty_ldisc_lock */ static int tty_ldisc_try(struct tty_struct *tty) @@ -833,8 +602,6 @@ static int tty_ldisc_try(struct tty_struct *tty) * must also be careful not to hold other locks that will deadlock * against a discipline change, such as an existing ldisc reference * (which we check for) - * - * Locking: call functions take tty_ldisc_lock */ struct tty_ldisc *tty_ldisc_ref_wait(struct tty_struct *tty) @@ -855,8 +622,6 @@ EXPORT_SYMBOL_GPL(tty_ldisc_ref_wait); * Dereference the line discipline for the terminal and take a * reference to it. If the line discipline is in flux then * return NULL. Can be called from IRQ and timer functions. - * - * Locking: called functions take tty_ldisc_lock */ struct tty_ldisc *tty_ldisc_ref(struct tty_struct *tty) @@ -874,8 +639,6 @@ EXPORT_SYMBOL_GPL(tty_ldisc_ref); * * Undoes the effect of tty_ldisc_ref or tty_ldisc_ref_wait. May * be called in IRQ context. - * - * Locking: takes tty_ldisc_lock */ void tty_ldisc_deref(struct tty_ldisc *ld) @@ -920,9 +683,6 @@ static void tty_ldisc_enable(struct tty_struct *tty) * * Set the discipline of a tty line. Must be called from a process * context. - * - * Locking: takes tty_ldisc_lock. - * called functions take termios_sem */ static int tty_set_ldisc(struct tty_struct *tty, int ldisc) @@ -1086,17 +846,9 @@ static int tty_set_ldisc(struct tty_struct *tty, int ldisc) return retval; } -/** - * get_tty_driver - find device of a tty - * @dev_t: device identifier - * @index: returns the index of the tty - * - * This routine returns a tty driver structure, given a device number - * and also passes back the index number. - * - * Locking: caller must hold tty_mutex +/* + * This routine returns a tty driver structure, given a device number */ - static struct tty_driver *get_tty_driver(dev_t device, int *index) { struct tty_driver *p; @@ -1111,17 +863,11 @@ static struct tty_driver *get_tty_driver(dev_t device, int *index) return NULL; } -/** - * tty_check_change - check for POSIX terminal changes - * @tty: tty to check - * - * If we try to write to, or set the state of, a terminal and we're - * not in the foreground, send a SIGTTOU. If the signal is blocked or - * ignored, go ahead and perform the operation. (POSIX 7.2) - * - * Locking: none +/* + * If we try to write to, or set the state of, a terminal and we're + * not in the foreground, send a SIGTTOU. If the signal is blocked or + * ignored, go ahead and perform the operation. (POSIX 7.2) */ - int tty_check_change(struct tty_struct * tty) { if (current->signal->tty != tty) @@ -1259,27 +1005,10 @@ void tty_ldisc_flush(struct tty_struct *tty) EXPORT_SYMBOL_GPL(tty_ldisc_flush); -/** - * do_tty_hangup - actual handler for hangup events - * @data: tty device - * - * This can be called by the "eventd" kernel thread. That is process - * synchronous but doesn't hold any locks, so we need to make sure we - * have the appropriate locks for what we're doing. - * - * The hangup event clears any pending redirections onto the hung up - * device. It ensures future writes will error and it does the needed - * line discipline hangup and signal delivery. The tty object itself - * remains intact. - * - * Locking: - * BKL - * redirect lock for undoing redirection - * file list lock for manipulating list of ttys - * tty_ldisc_lock from called functions - * termios_sem resetting termios data - * tasklist_lock to walk task list for hangup event - * +/* + * This can be called by the "eventd" kernel thread. That is process synchronous, + * but doesn't hold any locks, so we need to make sure we have the appropriate + * locks for what we're doing.. */ static void do_tty_hangup(void *data) { @@ -1404,14 +1133,6 @@ static void do_tty_hangup(void *data) fput(f); } -/** - * tty_hangup - trigger a hangup event - * @tty: tty to hangup - * - * A carrier loss (virtual or otherwise) has occurred on this like - * schedule a hangup sequence to run after this event. - */ - void tty_hangup(struct tty_struct * tty) { #ifdef TTY_DEBUG_HANGUP @@ -1424,15 +1145,6 @@ void tty_hangup(struct tty_struct * tty) EXPORT_SYMBOL(tty_hangup); -/** - * tty_vhangup - process vhangup - * @tty: tty to hangup - * - * The user has asked via system call for the terminal to be hung up. - * We do this synchronously so that when the syscall returns the process - * is complete. That guarantee is neccessary for security reasons. - */ - void tty_vhangup(struct tty_struct * tty) { #ifdef TTY_DEBUG_HANGUP @@ -1444,14 +1156,6 @@ void tty_vhangup(struct tty_struct * tty) } EXPORT_SYMBOL(tty_vhangup); -/** - * tty_hung_up_p - was tty hung up - * @filp: file pointer of tty - * - * Return true if the tty has been subject to a vhangup or a carrier - * loss - */ - int tty_hung_up_p(struct file * filp) { return (filp->f_op == &hung_up_tty_fops); @@ -1459,28 +1163,19 @@ int tty_hung_up_p(struct file * filp) EXPORT_SYMBOL(tty_hung_up_p); -/** - * disassociate_ctty - disconnect controlling tty - * @on_exit: true if exiting so need to "hang up" the session - * - * This function is typically called only by the session leader, when - * it wants to disassociate itself from its controlling tty. +/* + * This function is typically called only by the session leader, when + * it wants to disassociate itself from its controlling tty. * - * It performs the following functions: + * It performs the following functions: * (1) Sends a SIGHUP and SIGCONT to the foreground process group * (2) Clears the tty from being controlling the session * (3) Clears the controlling tty for all processes in the * session group. * - * The argument on_exit is set to 1 if called when a process is - * exiting; it is 0 if called by the ioctl TIOCNOTTY. - * - * Locking: tty_mutex is taken to protect current->signal->tty - * BKL is taken for hysterical raisins - * Tasklist lock is taken (under tty_mutex) to walk process - * lists for the session. + * The argument on_exit is set to 1 if called when a process is + * exiting; it is 0 if called by the ioctl TIOCNOTTY. */ - void disassociate_ctty(int on_exit) { struct tty_struct *tty; @@ -1527,25 +1222,6 @@ void disassociate_ctty(int on_exit) unlock_kernel(); } - -/** - * stop_tty - propogate flow control - * @tty: tty to stop - * - * Perform flow control to the driver. For PTY/TTY pairs we - * must also propogate the TIOCKPKT status. May be called - * on an already stopped device and will not re-call the driver - * method. - * - * This functionality is used by both the line disciplines for - * halting incoming flow and by the driver. It may therefore be - * called from any context, may be under the tty atomic_write_lock - * but not always. - * - * Locking: - * Broken. Relies on BKL which is unsafe here. - */ - void stop_tty(struct tty_struct *tty) { if (tty->stopped) @@ -1562,19 +1238,6 @@ void stop_tty(struct tty_struct *tty) EXPORT_SYMBOL(stop_tty); -/** - * start_tty - propogate flow control - * @tty: tty to start - * - * Start a tty that has been stopped if at all possible. Perform - * any neccessary wakeups and propogate the TIOCPKT status. If this - * is the tty was previous stopped and is being started then the - * driver start method is invoked and the line discipline woken. - * - * Locking: - * Broken. Relies on BKL which is unsafe here. - */ - void start_tty(struct tty_struct *tty) { if (!tty->stopped || tty->flow_stopped) @@ -1595,23 +1258,6 @@ void start_tty(struct tty_struct *tty) EXPORT_SYMBOL(start_tty); -/** - * tty_read - read method for tty device files - * @file: pointer to tty file - * @buf: user buffer - * @count: size of user buffer - * @ppos: unused - * - * Perform the read system call function on this terminal device. Checks - * for hung up devices before calling the line discipline method. - * - * Locking: - * Locks the line discipline internally while needed - * For historical reasons the line discipline read method is - * invoked under the BKL. This will go away in time so do not rely on it - * in new code. Multiple read calls may be outstanding in parallel. - */ - static ssize_t tty_read(struct file * file, char __user * buf, size_t count, loff_t *ppos) { @@ -1656,7 +1302,6 @@ static inline ssize_t do_tty_write( ssize_t ret = 0, written = 0; unsigned int chunk; - /* FIXME: O_NDELAY ... */ if (mutex_lock_interruptible(&tty->atomic_write_lock)) { return -ERESTARTSYS; } @@ -1673,9 +1318,6 @@ static inline ssize_t do_tty_write( * layer has problems with bigger chunks. It will * claim to be able to handle more characters than * it actually does. - * - * FIXME: This can probably go away now except that 64K chunks - * are too likely to fail unless switched to vmalloc... */ chunk = 2048; if (test_bit(TTY_NO_WRITE_SPLIT, &tty->flags)) @@ -1733,24 +1375,6 @@ static inline ssize_t do_tty_write( } -/** - * tty_write - write method for tty device file - * @file: tty file pointer - * @buf: user data to write - * @count: bytes to write - * @ppos: unused - * - * Write data to a tty device via the line discipline. - * - * Locking: - * Locks the line discipline as required - * Writes to the tty driver are serialized by the atomic_write_lock - * and are then processed in chunks to the device. The line discipline - * write method will not be involked in parallel for each device - * The line discipline write method is called under the big - * kernel lock for historical reasons. New code should not rely on this. - */ - static ssize_t tty_write(struct file * file, const char __user * buf, size_t count, loff_t *ppos) { @@ -1798,18 +1422,7 @@ ssize_t redirected_tty_write(struct file * file, const char __user * buf, size_t static char ptychar[] = "pqrstuvwxyzabcde"; -/** - * pty_line_name - generate name for a pty - * @driver: the tty driver in use - * @index: the minor number - * @p: output buffer of at least 6 bytes - * - * Generate a name from a driver reference and write it to the output - * buffer. - * - * Locking: None - */ -static void pty_line_name(struct tty_driver *driver, int index, char *p) +static inline void pty_line_name(struct tty_driver *driver, int index, char *p) { int i = index + driver->name_base; /* ->name is initialized to "ttyp", but "tty" is expected */ @@ -1818,53 +1431,24 @@ static void pty_line_name(struct tty_driver *driver, int index, char *p) ptychar[i >> 4 & 0xf], i & 0xf); } -/** - * pty_line_name - generate name for a tty - * @driver: the tty driver in use - * @index: the minor number - * @p: output buffer of at least 7 bytes - * - * Generate a name from a driver reference and write it to the output - * buffer. - * - * Locking: None - */ -static void tty_line_name(struct tty_driver *driver, int index, char *p) +static inline void tty_line_name(struct tty_driver *driver, int index, char *p) { sprintf(p, "%s%d", driver->name, index + driver->name_base); } -/** - * init_dev - initialise a tty device - * @driver: tty driver we are opening a device on - * @idx: device index - * @tty: returned tty structure - * - * Prepare a tty device. This may not be a "new" clean device but - * could also be an active device. The pty drivers require special - * handling because of this. - * - * Locking: - * The function is called under the tty_mutex, which - * protects us from the tty struct or driver itself going away. - * - * On exit the tty device has the line discipline attached and - * a reference count of 1. If a pair was created for pty/tty use - * and the other was a pty master then it too has a reference count of 1. - * +/* * WSH 06/09/97: Rewritten to remove races and properly clean up after a * failed open. The new code protects the open with a mutex, so it's * really quite straightforward. The mutex locking can probably be * relaxed for the (most common) case of reopening a tty. */ - static int init_dev(struct tty_driver *driver, int idx, struct tty_struct **ret_tty) { struct tty_struct *tty, *o_tty; struct termios *tp, **tp_loc, *o_tp, **o_tp_loc; struct termios *ltp, **ltp_loc, *o_ltp, **o_ltp_loc; - int retval = 0; + int retval=0; /* check whether we're reopening an existing tty */ if (driver->flags & TTY_DRIVER_DEVPTS_MEM) { @@ -2078,20 +1662,10 @@ static int init_dev(struct tty_driver *driver, int idx, goto end_init; } -/** - * release_mem - release tty structure memory - * - * Releases memory associated with a tty structure, and clears out the - * driver table slots. This function is called when a device is no longer - * in use. It also gets called when setup of a device fails. - * - * Locking: - * tty_mutex - sometimes only - * takes the file list lock internally when working on the list - * of ttys that the driver keeps. - * FIXME: should we require tty_mutex is held here ?? +/* + * Releases memory associated with a tty structure, and clears out the + * driver table slots. */ - static void release_mem(struct tty_struct *tty, int idx) { struct tty_struct *o_tty; @@ -2432,27 +2006,18 @@ static void release_dev(struct file * filp) } -/** - * tty_open - open a tty device - * @inode: inode of device file - * @filp: file pointer to tty - * - * tty_open and tty_release keep up the tty count that contains the - * number of opens done on a tty. We cannot use the inode-count, as - * different inodes might point to the same tty. - * - * Open-counting is needed for pty masters, as well as for keeping - * track of serial lines: DTR is dropped when the last close happens. - * (This is not done solely through tty->count, now. - Ted 1/27/92) +/* + * tty_open and tty_release keep up the tty count that contains the + * number of opens done on a tty. We cannot use the inode-count, as + * different inodes might point to the same tty. * - * The termios state of a pty is reset on first open so that - * settings don't persist across reuse. + * Open-counting is needed for pty masters, as well as for keeping + * track of serial lines: DTR is dropped when the last close happens. + * (This is not done solely through tty->count, now. - Ted 1/27/92) * - * Locking: tty_mutex protects current->signal->tty, get_tty_driver and - * init_dev work. tty->count should protect the rest. - * task_lock is held to update task details for sessions + * The termios state of a pty is reset on first open so that + * settings don't persist across reuse. */ - static int tty_open(struct inode * inode, struct file * filp) { struct tty_struct *tty; @@ -2567,18 +2132,6 @@ static int tty_open(struct inode * inode, struct file * filp) } #ifdef CONFIG_UNIX98_PTYS -/** - * ptmx_open - open a unix 98 pty master - * @inode: inode of device file - * @filp: file pointer to tty - * - * Allocate a unix98 pty master device from the ptmx driver. - * - * Locking: tty_mutex protects theinit_dev work. tty->count should - protect the rest. - * allocated_ptys_lock handles the list of free pty numbers - */ - static int ptmx_open(struct inode * inode, struct file * filp) { struct tty_struct *tty; @@ -2638,18 +2191,6 @@ static int ptmx_open(struct inode * inode, struct file * filp) } #endif -/** - * tty_release - vfs callback for close - * @inode: inode of tty - * @filp: file pointer for handle to tty - * - * Called the last time each file handle is closed that references - * this tty. There may however be several such references. - * - * Locking: - * Takes bkl. See release_dev - */ - static int tty_release(struct inode * inode, struct file * filp) { lock_kernel(); @@ -2658,18 +2199,7 @@ static int tty_release(struct inode * inode, struct file * filp) return 0; } -/** - * tty_poll - check tty status - * @filp: file being polled - * @wait: poll wait structures to update - * - * Call the line discipline polling method to obtain the poll - * status of the device. - * - * Locking: locks called line discipline but ldisc poll method - * may be re-entered freely by other callers. - */ - +/* No kernel lock held - fine */ static unsigned int tty_poll(struct file * filp, poll_table * wait) { struct tty_struct * tty; @@ -2713,21 +2243,6 @@ static int tty_fasync(int fd, struct file * filp, int on) return 0; } -/** - * tiocsti - fake input character - * @tty: tty to fake input into - * @p: pointer to character - * - * Fake input to a tty device. Does the neccessary locking and - * input management. - * - * FIXME: does not honour flow control ?? - * - * Locking: - * Called functions take tty_ldisc_lock - * current->signal->tty check is safe without locks - */ - static int tiocsti(struct tty_struct *tty, char __user *p) { char ch, mbz = 0; @@ -2743,18 +2258,6 @@ static int tiocsti(struct tty_struct *tty, char __user *p) return 0; } -/** - * tiocgwinsz - implement window query ioctl - * @tty; tty - * @arg: user buffer for result - * - * Copies the kernel idea of the window size into the user buffer. No - * locking is done. - * - * FIXME: Returning random values racing a window size set is wrong - * should lock here against that - */ - static int tiocgwinsz(struct tty_struct *tty, struct winsize __user * arg) { if (copy_to_user(arg, &tty->winsize, sizeof(*arg))) @@ -2762,24 +2265,6 @@ static int tiocgwinsz(struct tty_struct *tty, struct winsize __user * arg) return 0; } -/** - * tiocswinsz - implement window size set ioctl - * @tty; tty - * @arg: user buffer for result - * - * Copies the user idea of the window size to the kernel. Traditionally - * this is just advisory information but for the Linux console it - * actually has driver level meaning and triggers a VC resize. - * - * Locking: - * The console_sem is used to ensure we do not try and resize - * the console twice at once. - * FIXME: Two racing size sets may leave the console and kernel - * parameters disagreeing. Is this exploitable ? - * FIXME: Random values racing a window size get is wrong - * should lock here against that - */ - static int tiocswinsz(struct tty_struct *tty, struct tty_struct *real_tty, struct winsize __user * arg) { @@ -2809,15 +2294,6 @@ static int tiocswinsz(struct tty_struct *tty, struct tty_struct *real_tty, return 0; } -/** - * tioccons - allow admin to move logical console - * @file: the file to become console - * - * Allow the adminstrator to move the redirected console device - * - * Locking: uses redirect_lock to guard the redirect information - */ - static int tioccons(struct file *file) { if (!capable(CAP_SYS_ADMIN)) @@ -2843,17 +2319,6 @@ static int tioccons(struct file *file) return 0; } -/** - * fionbio - non blocking ioctl - * @file: file to set blocking value - * @p: user parameter - * - * Historical tty interfaces had a blocking control ioctl before - * the generic functionality existed. This piece of history is preserved - * in the expected tty API of posix OS's. - * - * Locking: none, the open fle handle ensures it won't go away. - */ static int fionbio(struct file *file, int __user *p) { @@ -2869,23 +2334,6 @@ static int fionbio(struct file *file, int __user *p) return 0; } -/** - * tiocsctty - set controlling tty - * @tty: tty structure - * @arg: user argument - * - * This ioctl is used to manage job control. It permits a session - * leader to set this tty as the controlling tty for the session. - * - * Locking: - * Takes tasklist lock internally to walk sessions - * Takes task_lock() when updating signal->tty - * - * FIXME: tty_mutex is needed to protect signal->tty references. - * FIXME: why task_lock on the signal->tty reference ?? - * - */ - static int tiocsctty(struct tty_struct *tty, int arg) { struct task_struct *p; @@ -2926,18 +2374,6 @@ static int tiocsctty(struct tty_struct *tty, int arg) return 0; } -/** - * tiocgpgrp - get process group - * @tty: tty passed by user - * @real_tty: tty side of the tty pased by the user if a pty else the tty - * @p: returned pid - * - * Obtain the process group of the tty. If there is no process group - * return an error. - * - * Locking: none. Reference to ->signal->tty is safe. - */ - static int tiocgpgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p) { /* @@ -2949,20 +2385,6 @@ static int tiocgpgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t return put_user(real_tty->pgrp, p); } -/** - * tiocspgrp - attempt to set process group - * @tty: tty passed by user - * @real_tty: tty side device matching tty passed by user - * @p: pid pointer - * - * Set the process group of the tty to the session passed. Only - * permitted where the tty session is our session. - * - * Locking: None - * - * FIXME: current->signal->tty referencing is unsafe. - */ - static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p) { pid_t pgrp; @@ -2986,18 +2408,6 @@ static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t return 0; } -/** - * tiocgsid - get session id - * @tty: tty passed by user - * @real_tty: tty side of the tty pased by the user if a pty else the tty - * @p: pointer to returned session id - * - * Obtain the session id of the tty. If there is no session - * return an error. - * - * Locking: none. Reference to ->signal->tty is safe. - */ - static int tiocgsid(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p) { /* @@ -3011,16 +2421,6 @@ static int tiocgsid(struct tty_struct *tty, struct tty_struct *real_tty, pid_t _ return put_user(real_tty->session, p); } -/** - * tiocsetd - set line discipline - * @tty: tty device - * @p: pointer to user data - * - * Set the line discipline according to user request. - * - * Locking: see tty_set_ldisc, this function is just a helper - */ - static int tiocsetd(struct tty_struct *tty, int __user *p) { int ldisc; @@ -3030,21 +2430,6 @@ static int tiocsetd(struct tty_struct *tty, int __user *p) return tty_set_ldisc(tty, ldisc); } -/** - * send_break - performed time break - * @tty: device to break on - * @duration: timeout in mS - * - * Perform a timed break on hardware that lacks its own driver level - * timed break functionality. - * - * Locking: - * None - * - * FIXME: - * What if two overlap - */ - static int send_break(struct tty_struct *tty, unsigned int duration) { tty->driver->break_ctl(tty, -1); @@ -3057,19 +2442,8 @@ static int send_break(struct tty_struct *tty, unsigned int duration) return 0; } -/** - * tiocmget - get modem status - * @tty: tty device - * @file: user file pointer - * @p: pointer to result - * - * Obtain the modem status bits from the tty driver if the feature - * is supported. Return -EINVAL if it is not available. - * - * Locking: none (up to the driver) - */ - -static int tty_tiocmget(struct tty_struct *tty, struct file *file, int __user *p) +static int +tty_tiocmget(struct tty_struct *tty, struct file *file, int __user *p) { int retval = -EINVAL; @@ -3082,20 +2456,8 @@ static int tty_tiocmget(struct tty_struct *tty, struct file *file, int __user *p return retval; } -/** - * tiocmset - set modem status - * @tty: tty device - * @file: user file pointer - * @cmd: command - clear bits, set bits or set all - * @p: pointer to desired bits - * - * Set the modem status bits from the tty driver if the feature - * is supported. Return -EINVAL if it is not available. - * - * Locking: none (up to the driver) - */ - -static int tty_tiocmset(struct tty_struct *tty, struct file *file, unsigned int cmd, +static int +tty_tiocmset(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned __user *p) { int retval = -EINVAL; @@ -3211,7 +2573,6 @@ int tty_ioctl(struct inode * inode, struct file * file, clear_bit(TTY_EXCLUSIVE, &tty->flags); return 0; case TIOCNOTTY: - /* FIXME: taks lock or tty_mutex ? */ if (current->signal->tty != tty) return -ENOTTY; if (current->signal->leader) @@ -3392,16 +2753,9 @@ void do_SAK(struct tty_struct *tty) EXPORT_SYMBOL(do_SAK); -/** - * flush_to_ldisc - * @private_: tty structure passed from work queue. - * - * This routine is called out of the software interrupt to flush data - * from the buffer chain to the line discipline. - * - * Locking: holds tty->buf.lock to guard buffer list. Drops the lock - * while invoking the line discipline receive_buf method. The - * receive_buf method is single threaded for each tty instance. +/* + * This routine is called out of the software interrupt to flush data + * from the buffer chain to the line discipline. */ static void flush_to_ldisc(void *private_) @@ -3477,8 +2831,6 @@ static int n_baud_table = ARRAY_SIZE(baud_table); * Convert termios baud rate data into a speed. This should be called * with the termios lock held if this termios is a terminal termios * structure. May change the termios data. - * - * Locking: none */ int tty_termios_baud_rate(struct termios *termios) @@ -3507,8 +2859,6 @@ EXPORT_SYMBOL(tty_termios_baud_rate); * Returns the baud rate as an integer for this terminal. The * termios lock must be held by the caller and the terminal bit * flags may be updated. - * - * Locking: none */ int tty_get_baud_rate(struct tty_struct *tty) @@ -3538,8 +2888,6 @@ EXPORT_SYMBOL(tty_get_baud_rate); * * In the event of the queue being busy for flipping the work will be * held off and retried later. - * - * Locking: tty buffer lock. Driver locks in low latency mode. */ void tty_flip_buffer_push(struct tty_struct *tty) @@ -3559,16 +2907,9 @@ void tty_flip_buffer_push(struct tty_struct *tty) EXPORT_SYMBOL(tty_flip_buffer_push); -/** - * initialize_tty_struct - * @tty: tty to initialize - * - * This subroutine initializes a tty structure that has been newly - * allocated. - * - * Locking: none - tty in question must not be exposed at this point +/* + * This subroutine initializes a tty structure. */ - static void initialize_tty_struct(struct tty_struct *tty) { memset(tty, 0, sizeof(struct tty_struct)); @@ -3594,7 +2935,6 @@ static void initialize_tty_struct(struct tty_struct *tty) /* * The default put_char routine if the driver did not define one. */ - static void tty_default_put_char(struct tty_struct *tty, unsigned char ch) { tty->driver->write(tty, &ch, 1); @@ -3603,23 +2943,19 @@ static void tty_default_put_char(struct tty_struct *tty, unsigned char ch) static struct class *tty_class; /** - * tty_register_device - register a tty device - * @driver: the tty driver that describes the tty device - * @index: the index in the tty driver for this tty device - * @device: a struct device that is associated with this tty device. - * This field is optional, if there is no known struct device - * for this tty device it can be set to NULL safely. + * tty_register_device - register a tty device + * @driver: the tty driver that describes the tty device + * @index: the index in the tty driver for this tty device + * @device: a struct device that is associated with this tty device. + * This field is optional, if there is no known struct device for this + * tty device it can be set to NULL safely. * - * Returns a pointer to the class device (or ERR_PTR(-EFOO) on error). + * Returns a pointer to the class device (or ERR_PTR(-EFOO) on error). * - * This call is required to be made to register an individual tty device - * if the tty driver's flags have the TTY_DRIVER_DYNAMIC_DEV bit set. If - * that bit is not set, this function should not be called by a tty - * driver. - * - * Locking: ?? + * This call is required to be made to register an individual tty device if + * the tty driver's flags have the TTY_DRIVER_DYNAMIC_DEV bit set. If that + * bit is not set, this function should not be called by a tty driver. */ - struct class_device *tty_register_device(struct tty_driver *driver, unsigned index, struct device *device) { @@ -3641,16 +2977,13 @@ struct class_device *tty_register_device(struct tty_driver *driver, } /** - * tty_unregister_device - unregister a tty device - * @driver: the tty driver that describes the tty device - * @index: the index in the tty driver for this tty device + * tty_unregister_device - unregister a tty device + * @driver: the tty driver that describes the tty device + * @index: the index in the tty driver for this tty device * - * If a tty device is registered with a call to tty_register_device() then - * this function must be called when the tty device is gone. - * - * Locking: ?? + * If a tty device is registered with a call to tty_register_device() then + * this function must be made when the tty device is gone. */ - void tty_unregister_device(struct tty_driver *driver, unsigned index) { class_device_destroy(tty_class, MKDEV(driver->major, driver->minor_start) + index); @@ -3761,6 +3094,7 @@ int tty_register_driver(struct tty_driver *driver) driver->cdev.owner = driver->owner; error = cdev_add(&driver->cdev, dev, driver->num); if (error) { + cdev_del(&driver->cdev); unregister_chrdev_region(dev, driver->num); driver->ttys = NULL; driver->termios = driver->termios_locked = NULL; diff --git a/trunk/drivers/char/tty_ioctl.c b/trunk/drivers/char/tty_ioctl.c index 4ad47d321bd4..f19cf9d7792d 100644 --- a/trunk/drivers/char/tty_ioctl.c +++ b/trunk/drivers/char/tty_ioctl.c @@ -36,18 +36,6 @@ #define TERMIOS_WAIT 2 #define TERMIOS_TERMIO 4 - -/** - * tty_wait_until_sent - wait for I/O to finish - * @tty: tty we are waiting for - * @timeout: how long we will wait - * - * Wait for characters pending in a tty driver to hit the wire, or - * for a timeout to occur (eg due to flow control) - * - * Locking: none - */ - void tty_wait_until_sent(struct tty_struct * tty, long timeout) { DECLARE_WAITQUEUE(wait, current); @@ -106,18 +94,6 @@ static void unset_locked_termios(struct termios *termios, old->c_cc[i] : termios->c_cc[i]; } -/** - * change_termios - update termios values - * @tty: tty to update - * @new_termios: desired new value - * - * Perform updates to the termios values set on this terminal. There - * is a bit of layering violation here with n_tty in terms of the - * internal knowledge of this function. - * - * Locking: termios_sem - */ - static void change_termios(struct tty_struct * tty, struct termios * new_termios) { int canon_change; @@ -179,19 +155,6 @@ static void change_termios(struct tty_struct * tty, struct termios * new_termios up(&tty->termios_sem); } -/** - * set_termios - set termios values for a tty - * @tty: terminal device - * @arg: user data - * @opt: option information - * - * Helper function to prepare termios data and run neccessary other - * functions before using change_termios to do the actual changes. - * - * Locking: - * Called functions take ldisc and termios_sem locks - */ - static int set_termios(struct tty_struct * tty, void __user *arg, int opt) { struct termios tmp_termios; @@ -321,17 +284,6 @@ static void set_sgflags(struct termios * termios, int flags) } } -/** - * set_sgttyb - set legacy terminal values - * @tty: tty structure - * @sgttyb: pointer to old style terminal structure - * - * Updates a terminal from the legacy BSD style terminal information - * structure. - * - * Locking: termios_sem - */ - static int set_sgttyb(struct tty_struct * tty, struct sgttyb __user * sgttyb) { int retval; @@ -417,16 +369,9 @@ static int set_ltchars(struct tty_struct * tty, struct ltchars __user * ltchars) } #endif -/** - * send_prio_char - send priority character - * - * Send a high priority character to the tty even if stopped - * - * Locking: none - * - * FIXME: overlapping calls with start/stop tty lose state of tty +/* + * Send a high priority character to the tty. */ - static void send_prio_char(struct tty_struct *tty, char ch) { int was_stopped = tty->stopped; diff --git a/trunk/drivers/char/vt_ioctl.c b/trunk/drivers/char/vt_ioctl.c index a5628a8b6620..eccffaf26faa 100644 --- a/trunk/drivers/char/vt_ioctl.c +++ b/trunk/drivers/char/vt_ioctl.c @@ -1011,8 +1011,6 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, return -EPERM; vt_dont_switch = 0; return 0; - case VT_GETHIFONTMASK: - return put_user(vc->vc_hi_font_mask, (unsigned short __user *)arg); default: return -ENOIOCTLCMD; } diff --git a/trunk/drivers/char/watchdog/sbc8360.c b/trunk/drivers/char/watchdog/sbc8360.c index 41fc6f80c493..1035be5b5019 100644 --- a/trunk/drivers/char/watchdog/sbc8360.c +++ b/trunk/drivers/char/watchdog/sbc8360.c @@ -200,7 +200,7 @@ static int wd_margin = 0xB; static int wd_multiplier = 2; static int nowayout = WATCHDOG_NOWAYOUT; -module_param(timeout, int, 0); +module_param(timeout, int, 27); MODULE_PARM_DESC(timeout, "Index into timeout table (0-63) (default=27 (60s))"); module_param(nowayout, int, 0); MODULE_PARM_DESC(nowayout, @@ -407,7 +407,7 @@ module_exit(sbc8360_exit); MODULE_AUTHOR("Ian E. Morgan "); MODULE_DESCRIPTION("SBC8360 watchdog driver"); MODULE_LICENSE("GPL"); -MODULE_VERSION("1.01"); +MODULE_VERSION("1.0"); MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); /* end of sbc8360.c */ diff --git a/trunk/drivers/hwmon/abituguru.c b/trunk/drivers/hwmon/abituguru.c index 35ad1b032726..cc15c4f2e9ec 100644 --- a/trunk/drivers/hwmon/abituguru.c +++ b/trunk/drivers/hwmon/abituguru.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include @@ -65,17 +64,17 @@ #define ABIT_UGURU_IN_SENSOR 0 #define ABIT_UGURU_TEMP_SENSOR 1 #define ABIT_UGURU_NC 2 -/* In many cases we need to wait for the uGuru to reach a certain status, most - of the time it will reach this status within 30 - 90 ISA reads, and thus we - can best busy wait. This define gives the total amount of reads to try. */ -#define ABIT_UGURU_WAIT_TIMEOUT 125 -/* However sometimes older versions of the uGuru seem to be distracted and they - do not respond for a long time. To handle this we sleep before each of the - last ABIT_UGURU_WAIT_TIMEOUT_SLEEP tries. */ -#define ABIT_UGURU_WAIT_TIMEOUT_SLEEP 5 +/* Timeouts / Retries, if these turn out to need a lot of fiddling we could + convert them to params. */ +/* 250 was determined by trial and error, 200 works most of the time, but not + always. I assume this is cpu-speed independent, since the ISA-bus and not + the CPU should be the bottleneck. Note that 250 sometimes is still not + enough (only reported on AN7 mb) this is handled by a higher layer. */ +#define ABIT_UGURU_WAIT_TIMEOUT 250 /* Normally all expected status in abituguru_ready, are reported after the - first read, but sometimes not and we need to poll. */ -#define ABIT_UGURU_READY_TIMEOUT 5 + first read, but sometimes not and we need to poll, 5 polls was not enough + 50 sofar is. */ +#define ABIT_UGURU_READY_TIMEOUT 50 /* Maximum 3 retries on timedout reads/writes, delay 200 ms before retrying */ #define ABIT_UGURU_MAX_RETRIES 3 #define ABIT_UGURU_RETRY_DELAY (HZ/5) @@ -227,10 +226,6 @@ static int abituguru_wait(struct abituguru_data *data, u8 state) timeout--; if (timeout == 0) return -EBUSY; - /* sleep a bit before our last few tries, see the comment on - this where ABIT_UGURU_WAIT_TIMEOUT_SLEEP is defined. */ - if (timeout <= ABIT_UGURU_WAIT_TIMEOUT_SLEEP) - msleep(0); } return 0; } @@ -261,7 +256,6 @@ static int abituguru_ready(struct abituguru_data *data) "CMD reg does not hold 0xAC after ready command\n"); return -EIO; } - msleep(0); } /* After this the ABIT_UGURU_DATA port should contain @@ -274,7 +268,6 @@ static int abituguru_ready(struct abituguru_data *data) "state != more input after ready command\n"); return -EIO; } - msleep(0); } data->uguru_ready = 1; @@ -338,8 +331,7 @@ static int abituguru_read(struct abituguru_data *data, /* And read the data */ for (i = 0; i < count; i++) { if (abituguru_wait(data, ABIT_UGURU_STATUS_READ)) { - ABIT_UGURU_DEBUG(retries ? 1 : 3, - "timeout exceeded waiting for " + ABIT_UGURU_DEBUG(1, "timeout exceeded waiting for " "read state (bank: %d, sensor: %d)\n", (int)bank_addr, (int)sensor_addr); break; @@ -358,9 +350,7 @@ static int abituguru_read(struct abituguru_data *data, static int abituguru_write(struct abituguru_data *data, u8 bank_addr, u8 sensor_addr, u8 *buf, int count) { - /* We use the ready timeout as we have to wait for 0xAC just like the - ready function */ - int i, timeout = ABIT_UGURU_READY_TIMEOUT; + int i; /* Send the address */ i = abituguru_send_address(data, bank_addr, sensor_addr, @@ -380,8 +370,7 @@ static int abituguru_write(struct abituguru_data *data, } /* Now we need to wait till the chip is ready to be read again, - so that we can read 0xAC as confirmation that our write has - succeeded. */ + don't ask why */ if (abituguru_wait(data, ABIT_UGURU_STATUS_READ)) { ABIT_UGURU_DEBUG(1, "timeout exceeded waiting for read state " "after write (bank: %d, sensor: %d)\n", (int)bank_addr, @@ -390,15 +379,11 @@ static int abituguru_write(struct abituguru_data *data, } /* Cmd port MUST be read now and should contain 0xAC */ - while (inb_p(data->addr + ABIT_UGURU_CMD) != 0xAC) { - timeout--; - if (timeout == 0) { - ABIT_UGURU_DEBUG(1, "CMD reg does not hold 0xAC after " - "write (bank: %d, sensor: %d)\n", - (int)bank_addr, (int)sensor_addr); - return -EIO; - } - msleep(0); + if (inb_p(data->addr + ABIT_UGURU_CMD) != 0xAC) { + ABIT_UGURU_DEBUG(1, "CMD reg does not hold 0xAC after write " + "(bank: %d, sensor: %d)\n", (int)bank_addr, + (int)sensor_addr); + return -EIO; } /* Last put the chip back in ready state */ @@ -418,7 +403,7 @@ abituguru_detect_bank1_sensor_type(struct abituguru_data *data, u8 sensor_addr) { u8 val, buf[3]; - int i, ret = -ENODEV; /* error is the most common used retval :| */ + int ret = ABIT_UGURU_NC; /* If overriden by the user return the user selected type */ if (bank1_types[sensor_addr] >= ABIT_UGURU_IN_SENSOR && @@ -454,7 +439,7 @@ abituguru_detect_bank1_sensor_type(struct abituguru_data *data, buf[2] = 250; if (abituguru_write(data, ABIT_UGURU_SENSOR_BANK1 + 2, sensor_addr, buf, 3) != 3) - goto abituguru_detect_bank1_sensor_type_exit; + return -ENODEV; /* Now we need 20 ms to give the uguru time to read the sensors and raise a voltage alarm */ set_current_state(TASK_UNINTERRUPTIBLE); @@ -462,16 +447,21 @@ abituguru_detect_bank1_sensor_type(struct abituguru_data *data, /* Check for alarm and check the alarm is a volt low alarm. */ if (abituguru_read(data, ABIT_UGURU_ALARM_BANK, 0, buf, 3, ABIT_UGURU_MAX_RETRIES) != 3) - goto abituguru_detect_bank1_sensor_type_exit; + return -ENODEV; if (buf[sensor_addr/8] & (0x01 << (sensor_addr % 8))) { if (abituguru_read(data, ABIT_UGURU_SENSOR_BANK1 + 1, sensor_addr, buf, 3, ABIT_UGURU_MAX_RETRIES) != 3) - goto abituguru_detect_bank1_sensor_type_exit; + return -ENODEV; if (buf[0] & ABIT_UGURU_VOLT_LOW_ALARM_FLAG) { + /* Restore original settings */ + if (abituguru_write(data, ABIT_UGURU_SENSOR_BANK1 + 2, + sensor_addr, + data->bank1_settings[sensor_addr], + 3) != 3) + return -ENODEV; ABIT_UGURU_DEBUG(2, " found volt sensor\n"); - ret = ABIT_UGURU_IN_SENSOR; - goto abituguru_detect_bank1_sensor_type_exit; + return ABIT_UGURU_IN_SENSOR; } else ABIT_UGURU_DEBUG(2, " alarm raised during volt " "sensor test, but volt low flag not set\n"); @@ -487,7 +477,7 @@ abituguru_detect_bank1_sensor_type(struct abituguru_data *data, buf[2] = 10; if (abituguru_write(data, ABIT_UGURU_SENSOR_BANK1 + 2, sensor_addr, buf, 3) != 3) - goto abituguru_detect_bank1_sensor_type_exit; + return -ENODEV; /* Now we need 50 ms to give the uguru time to read the sensors and raise a temp alarm */ set_current_state(TASK_UNINTERRUPTIBLE); @@ -495,16 +485,15 @@ abituguru_detect_bank1_sensor_type(struct abituguru_data *data, /* Check for alarm and check the alarm is a temp high alarm. */ if (abituguru_read(data, ABIT_UGURU_ALARM_BANK, 0, buf, 3, ABIT_UGURU_MAX_RETRIES) != 3) - goto abituguru_detect_bank1_sensor_type_exit; + return -ENODEV; if (buf[sensor_addr/8] & (0x01 << (sensor_addr % 8))) { if (abituguru_read(data, ABIT_UGURU_SENSOR_BANK1 + 1, sensor_addr, buf, 3, ABIT_UGURU_MAX_RETRIES) != 3) - goto abituguru_detect_bank1_sensor_type_exit; + return -ENODEV; if (buf[0] & ABIT_UGURU_TEMP_HIGH_ALARM_FLAG) { - ABIT_UGURU_DEBUG(2, " found temp sensor\n"); ret = ABIT_UGURU_TEMP_SENSOR; - goto abituguru_detect_bank1_sensor_type_exit; + ABIT_UGURU_DEBUG(2, " found temp sensor\n"); } else ABIT_UGURU_DEBUG(2, " alarm raised during temp " "sensor test, but temp high flag not set\n"); @@ -512,23 +501,11 @@ abituguru_detect_bank1_sensor_type(struct abituguru_data *data, ABIT_UGURU_DEBUG(2, " alarm not raised during temp sensor " "test\n"); - ret = ABIT_UGURU_NC; -abituguru_detect_bank1_sensor_type_exit: - /* Restore original settings, failing here is really BAD, it has been - reported that some BIOS-es hang when entering the uGuru menu with - invalid settings present in the uGuru, so we try this 3 times. */ - for (i = 0; i < 3; i++) - if (abituguru_write(data, ABIT_UGURU_SENSOR_BANK1 + 2, - sensor_addr, data->bank1_settings[sensor_addr], - 3) == 3) - break; - if (i == 3) { - printk(KERN_ERR ABIT_UGURU_NAME - ": Fatal error could not restore original settings. " - "This should never happen please report this to the " - "abituguru maintainer (see MAINTAINERS)\n"); + /* Restore original settings */ + if (abituguru_write(data, ABIT_UGURU_SENSOR_BANK1 + 2, sensor_addr, + data->bank1_settings[sensor_addr], 3) != 3) return -ENODEV; - } + return ret; } @@ -1328,7 +1305,7 @@ static struct abituguru_data *abituguru_update_device(struct device *dev) data->update_timeouts = 0; LEAVE_UPDATE: /* handle timeout condition */ - if (!success && (err == -EBUSY || err >= 0)) { + if (err == -EBUSY) { /* No overflow please */ if (data->update_timeouts < 255u) data->update_timeouts++; diff --git a/trunk/drivers/i2c/chips/tps65010.c b/trunk/drivers/i2c/chips/tps65010.c index 0be6fd6a267d..e7e27049fbfa 100644 --- a/trunk/drivers/i2c/chips/tps65010.c +++ b/trunk/drivers/i2c/chips/tps65010.c @@ -43,12 +43,13 @@ /*-------------------------------------------------------------------------*/ #define DRIVER_VERSION "2 May 2005" -#define DRIVER_NAME (tps65010_driver.driver.name) +#define DRIVER_NAME (tps65010_driver.name) MODULE_DESCRIPTION("TPS6501x Power Management Driver"); MODULE_LICENSE("GPL"); static unsigned short normal_i2c[] = { 0x48, /* 0x49, */ I2C_CLIENT_END }; +static unsigned short normal_i2c_range[] = { I2C_CLIENT_END }; I2C_CLIENT_INSMOD; @@ -99,7 +100,7 @@ struct tps65010 { /* not currently tracking GPIO state */ }; -#define POWER_POLL_DELAY msecs_to_jiffies(5000) +#define POWER_POLL_DELAY msecs_to_jiffies(800) /*-------------------------------------------------------------------------*/ @@ -519,11 +520,8 @@ tps65010_probe(struct i2c_adapter *bus, int address, int kind) goto fail1; } - /* the IRQ is active low, but many gpio lines can't support that - * so this driver can use falling-edge triggers instead. - */ - irqflags = IRQF_SAMPLE_RANDOM; #ifdef CONFIG_ARM + irqflags = IRQF_SAMPLE_RANDOM | IRQF_TRIGGER_LOW; if (machine_is_omap_h2()) { tps->model = TPS65010; omap_cfg_reg(W4_GPIO58); @@ -545,6 +543,8 @@ tps65010_probe(struct i2c_adapter *bus, int address, int kind) // FIXME set up this board's IRQ ... } +#else + irqflags = IRQF_SAMPLE_RANDOM; #endif if (tps->irq > 0) { diff --git a/trunk/drivers/ide/pci/sgiioc4.c b/trunk/drivers/ide/pci/sgiioc4.c index d8a0d87df734..e125032bb403 100644 --- a/trunk/drivers/ide/pci/sgiioc4.c +++ b/trunk/drivers/ide/pci/sgiioc4.c @@ -367,13 +367,12 @@ sgiioc4_INB(unsigned long port) static void __devinit ide_dma_sgiioc4(ide_hwif_t * hwif, unsigned long dma_base) { - void __iomem *virt_dma_base; int num_ports = sizeof (ioc4_dma_regs_t); printk(KERN_INFO "%s: BM-DMA at 0x%04lx-0x%04lx\n", hwif->name, dma_base, dma_base + num_ports - 1); - if (!request_mem_region(dma_base, num_ports, hwif->name)) { + if (!request_region(dma_base, num_ports, hwif->name)) { printk(KERN_ERR "%s(%s) -- ERROR, Addresses 0x%p to 0x%p " "ALREADY in use\n", @@ -382,21 +381,13 @@ ide_dma_sgiioc4(ide_hwif_t * hwif, unsigned long dma_base) goto dma_alloc_failure; } - virt_dma_base = ioremap(dma_base, num_ports); - if (virt_dma_base == NULL) { - printk(KERN_ERR - "%s(%s) -- ERROR, Unable to map addresses 0x%lx to 0x%lx\n", - __FUNCTION__, hwif->name, dma_base, dma_base + num_ports - 1); - goto dma_remap_failure; - } - hwif->dma_base = (unsigned long) virt_dma_base; - + hwif->dma_base = dma_base; hwif->dmatable_cpu = pci_alloc_consistent(hwif->pci_dev, IOC4_PRD_ENTRIES * IOC4_PRD_BYTES, &hwif->dmatable_dma); if (!hwif->dmatable_cpu) - goto dma_pci_alloc_failure; + goto dma_alloc_failure; hwif->sg_max_nents = IOC4_PRD_ENTRIES; @@ -420,12 +411,6 @@ ide_dma_sgiioc4(ide_hwif_t * hwif, unsigned long dma_base) printk(KERN_INFO "Changing from DMA to PIO mode for Drive %s\n", hwif->name); -dma_pci_alloc_failure: - iounmap(virt_dma_base); - -dma_remap_failure: - release_mem_region(dma_base, num_ports); - dma_alloc_failure: /* Disable DMA because we couldnot allocate any DMA maps */ hwif->autodma = 0; @@ -622,15 +607,18 @@ ide_init_sgiioc4(ide_hwif_t * hwif) hwif->ide_dma_lostirq = &sgiioc4_ide_dma_lostirq; hwif->ide_dma_timeout = &__ide_dma_timeout; + /* + * The IOC4 uses MMIO rather than Port IO. + * It also needs special workarounds for INB. + */ + default_hwif_mmiops(hwif); hwif->INB = &sgiioc4_INB; } static int __devinit sgiioc4_ide_setup_pci_device(struct pci_dev *dev, ide_pci_device_t * d) { - unsigned long cmd_base, dma_base, irqport; - unsigned long bar0, cmd_phys_base, ctl; - void __iomem *virt_base; + unsigned long base, ctl, dma_base, irqport; ide_hwif_t *hwif; int h; @@ -648,32 +636,23 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev, ide_pci_device_t * d) } /* Get the CmdBlk and CtrlBlk Base Registers */ - bar0 = pci_resource_start(dev, 0); - virt_base = ioremap(bar0, pci_resource_len(dev, 0)); - if (virt_base == NULL) { - printk(KERN_ERR "%s: Unable to remap BAR 0 address: 0x%lx\n", - d->name, bar0); - return -ENOMEM; - } - cmd_base = (unsigned long) virt_base + IOC4_CMD_OFFSET; - ctl = (unsigned long) virt_base + IOC4_CTRL_OFFSET; - irqport = (unsigned long) virt_base + IOC4_INTR_OFFSET; + base = pci_resource_start(dev, 0) + IOC4_CMD_OFFSET; + ctl = pci_resource_start(dev, 0) + IOC4_CTRL_OFFSET; + irqport = pci_resource_start(dev, 0) + IOC4_INTR_OFFSET; dma_base = pci_resource_start(dev, 0) + IOC4_DMA_OFFSET; - cmd_phys_base = bar0 + IOC4_CMD_OFFSET; - if (!request_mem_region(cmd_phys_base, IOC4_CMD_CTL_BLK_SIZE, - hwif->name)) { + if (!request_region(base, IOC4_CMD_CTL_BLK_SIZE, hwif->name)) { printk(KERN_ERR - "%s : %s -- ERROR, Addresses " + "%s : %s -- ERROR, Port Addresses " "0x%p to 0x%p ALREADY in use\n", - __FUNCTION__, hwif->name, (void *) cmd_phys_base, - (void *) cmd_phys_base + IOC4_CMD_CTL_BLK_SIZE); + __FUNCTION__, hwif->name, (void *) base, + (void *) base + IOC4_CMD_CTL_BLK_SIZE); return -ENOMEM; } - if (hwif->io_ports[IDE_DATA_OFFSET] != cmd_base) { + if (hwif->io_ports[IDE_DATA_OFFSET] != base) { /* Initialize the IO registers */ - sgiioc4_init_hwif_ports(&hwif->hw, cmd_base, ctl, irqport); + sgiioc4_init_hwif_ports(&hwif->hw, base, ctl, irqport); memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof (hwif->io_ports)); hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET]; @@ -686,9 +665,6 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev, ide_pci_device_t * d) hwif->cds = (struct ide_pci_device_s *) d; hwif->gendev.parent = &dev->dev;/* setup proper ancestral information */ - /* The IOC4 uses MMIO rather than Port IO. */ - default_hwif_mmiops(hwif); - /* Initializing chipset IRQ Registers */ hwif->OUTL(0x03, irqport + IOC4_INTR_SET * 4); diff --git a/trunk/drivers/ide/pci/via82cxxx.c b/trunk/drivers/ide/pci/via82cxxx.c index 9b7589e8e93e..afdaee3c15c9 100644 --- a/trunk/drivers/ide/pci/via82cxxx.c +++ b/trunk/drivers/ide/pci/via82cxxx.c @@ -6,7 +6,7 @@ * * vt82c576, vt82c586, vt82c586a, vt82c586b, vt82c596a, vt82c596b, * vt82c686, vt82c686a, vt82c686b, vt8231, vt8233, vt8233c, vt8233a, - * vt8235, vt8237, vt8237a + * vt8235, vt8237 * * Copyright (c) 2000-2002 Vojtech Pavlik * @@ -81,7 +81,6 @@ static struct via_isa_bridge { { "vt6410", PCI_DEVICE_ID_VIA_6410, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, { "vt8251", PCI_DEVICE_ID_VIA_8251, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, { "vt8237", PCI_DEVICE_ID_VIA_8237, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, - { "vt8237a", PCI_DEVICE_ID_VIA_8237A, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, { "vt8235", PCI_DEVICE_ID_VIA_8235, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, { "vt8233a", PCI_DEVICE_ID_VIA_8233A, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, { "vt8233c", PCI_DEVICE_ID_VIA_8233C_0, 0x00, 0x2f, VIA_UDMA_100 }, diff --git a/trunk/drivers/ieee1394/ohci1394.c b/trunk/drivers/ieee1394/ohci1394.c index 448df2773377..d4bad6704bbe 100644 --- a/trunk/drivers/ieee1394/ohci1394.c +++ b/trunk/drivers/ieee1394/ohci1394.c @@ -3552,8 +3552,6 @@ static int ohci1394_pci_resume (struct pci_dev *pdev) static int ohci1394_pci_suspend (struct pci_dev *pdev, pm_message_t state) { - pci_save_state(pdev); - #ifdef CONFIG_PPC_PMAC if (machine_is(powermac)) { struct device_node *of_node; @@ -3565,6 +3563,8 @@ static int ohci1394_pci_suspend (struct pci_dev *pdev, pm_message_t state) } #endif + pci_save_state(pdev); + return 0; } diff --git a/trunk/drivers/infiniband/core/cache.c b/trunk/drivers/infiniband/core/cache.c index 75313ade2e0d..e05ca2cdc73f 100644 --- a/trunk/drivers/infiniband/core/cache.c +++ b/trunk/drivers/infiniband/core/cache.c @@ -301,8 +301,7 @@ static void ib_cache_event(struct ib_event_handler *handler, event->event == IB_EVENT_PORT_ACTIVE || event->event == IB_EVENT_LID_CHANGE || event->event == IB_EVENT_PKEY_CHANGE || - event->event == IB_EVENT_SM_CHANGE || - event->event == IB_EVENT_CLIENT_REREGISTER) { + event->event == IB_EVENT_SM_CHANGE) { work = kmalloc(sizeof *work, GFP_ATOMIC); if (work) { INIT_WORK(&work->work, ib_cache_task, work); diff --git a/trunk/drivers/infiniband/core/sa_query.c b/trunk/drivers/infiniband/core/sa_query.c index d6b84226bba7..aeda484ffd82 100644 --- a/trunk/drivers/infiniband/core/sa_query.c +++ b/trunk/drivers/infiniband/core/sa_query.c @@ -405,8 +405,7 @@ static void ib_sa_event(struct ib_event_handler *handler, struct ib_event *event event->event == IB_EVENT_PORT_ACTIVE || event->event == IB_EVENT_LID_CHANGE || event->event == IB_EVENT_PKEY_CHANGE || - event->event == IB_EVENT_SM_CHANGE || - event->event == IB_EVENT_CLIENT_REREGISTER) { + event->event == IB_EVENT_SM_CHANGE) { struct ib_sa_device *sa_dev; sa_dev = container_of(handler, typeof(*sa_dev), event_handler); diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_allocator.c b/trunk/drivers/infiniband/hw/mthca/mthca_allocator.c index f930e55b58fc..25157f57a6d0 100644 --- a/trunk/drivers/infiniband/hw/mthca/mthca_allocator.c +++ b/trunk/drivers/infiniband/hw/mthca/mthca_allocator.c @@ -41,11 +41,9 @@ /* Trivial bitmap-based allocator */ u32 mthca_alloc(struct mthca_alloc *alloc) { - unsigned long flags; u32 obj; - spin_lock_irqsave(&alloc->lock, flags); - + spin_lock(&alloc->lock); obj = find_next_zero_bit(alloc->table, alloc->max, alloc->last); if (obj >= alloc->max) { alloc->top = (alloc->top + alloc->max) & alloc->mask; @@ -58,24 +56,19 @@ u32 mthca_alloc(struct mthca_alloc *alloc) } else obj = -1; - spin_unlock_irqrestore(&alloc->lock, flags); + spin_unlock(&alloc->lock); return obj; } void mthca_free(struct mthca_alloc *alloc, u32 obj) { - unsigned long flags; - obj &= alloc->max - 1; - - spin_lock_irqsave(&alloc->lock, flags); - + spin_lock(&alloc->lock); clear_bit(obj, alloc->table); alloc->last = min(alloc->last, obj); alloc->top = (alloc->top + alloc->max) & alloc->mask; - - spin_unlock_irqrestore(&alloc->lock, flags); + spin_unlock(&alloc->lock); } int mthca_alloc_init(struct mthca_alloc *alloc, u32 num, u32 mask, diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_main.c b/trunk/drivers/infiniband/hw/mthca/mthca_main.c index 7b82c1907f04..557cde3a4563 100644 --- a/trunk/drivers/infiniband/hw/mthca/mthca_main.c +++ b/trunk/drivers/infiniband/hw/mthca/mthca_main.c @@ -967,12 +967,12 @@ static struct { } mthca_hca_table[] = { [TAVOR] = { .latest_fw = MTHCA_FW_VER(3, 4, 0), .flags = 0 }, - [ARBEL_COMPAT] = { .latest_fw = MTHCA_FW_VER(4, 7, 600), + [ARBEL_COMPAT] = { .latest_fw = MTHCA_FW_VER(4, 7, 400), .flags = MTHCA_FLAG_PCIE }, - [ARBEL_NATIVE] = { .latest_fw = MTHCA_FW_VER(5, 1, 400), + [ARBEL_NATIVE] = { .latest_fw = MTHCA_FW_VER(5, 1, 0), .flags = MTHCA_FLAG_MEMFREE | MTHCA_FLAG_PCIE }, - [SINAI] = { .latest_fw = MTHCA_FW_VER(1, 1, 0), + [SINAI] = { .latest_fw = MTHCA_FW_VER(1, 0, 800), .flags = MTHCA_FLAG_MEMFREE | MTHCA_FLAG_PCIE | MTHCA_FLAG_SINAI_OPT } diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_provider.c b/trunk/drivers/infiniband/hw/mthca/mthca_provider.c index 265b1d1c4a62..230ae21db8fd 100644 --- a/trunk/drivers/infiniband/hw/mthca/mthca_provider.c +++ b/trunk/drivers/infiniband/hw/mthca/mthca_provider.c @@ -1287,7 +1287,11 @@ int mthca_register_device(struct mthca_dev *dev) (1ull << IB_USER_VERBS_CMD_MODIFY_QP) | (1ull << IB_USER_VERBS_CMD_DESTROY_QP) | (1ull << IB_USER_VERBS_CMD_ATTACH_MCAST) | - (1ull << IB_USER_VERBS_CMD_DETACH_MCAST); + (1ull << IB_USER_VERBS_CMD_DETACH_MCAST) | + (1ull << IB_USER_VERBS_CMD_CREATE_SRQ) | + (1ull << IB_USER_VERBS_CMD_MODIFY_SRQ) | + (1ull << IB_USER_VERBS_CMD_QUERY_SRQ) | + (1ull << IB_USER_VERBS_CMD_DESTROY_SRQ); dev->ib_dev.node_type = IB_NODE_CA; dev->ib_dev.phys_port_cnt = dev->limits.num_ports; dev->ib_dev.dma_device = &dev->pdev->dev; @@ -1312,11 +1316,6 @@ int mthca_register_device(struct mthca_dev *dev) dev->ib_dev.modify_srq = mthca_modify_srq; dev->ib_dev.query_srq = mthca_query_srq; dev->ib_dev.destroy_srq = mthca_destroy_srq; - dev->ib_dev.uverbs_cmd_mask |= - (1ull << IB_USER_VERBS_CMD_CREATE_SRQ) | - (1ull << IB_USER_VERBS_CMD_MODIFY_SRQ) | - (1ull << IB_USER_VERBS_CMD_QUERY_SRQ) | - (1ull << IB_USER_VERBS_CMD_DESTROY_SRQ); if (mthca_is_memfree(dev)) dev->ib_dev.post_srq_recv = mthca_arbel_post_srq_recv; diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_provider.h b/trunk/drivers/infiniband/hw/mthca/mthca_provider.h index 9a5bece3fa5c..8de2887ba15c 100644 --- a/trunk/drivers/infiniband/hw/mthca/mthca_provider.h +++ b/trunk/drivers/infiniband/hw/mthca/mthca_provider.h @@ -136,8 +136,8 @@ struct mthca_ah { * We have one global lock that protects dev->cq/qp_table. Each * struct mthca_cq/qp also has its own lock. An individual qp lock * may be taken inside of an individual cq lock. Both cqs attached to - * a qp may be locked, with the cq with the lower cqn locked first. - * No other nesting should be done. + * a qp may be locked, with the send cq locked first. No other + * nesting should be done. * * Each struct mthca_cq/qp also has an ref count, protected by the * corresponding table lock. The pointer from the cq/qp_table to the diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_qp.c b/trunk/drivers/infiniband/hw/mthca/mthca_qp.c index 2e8f6f36e0a5..cd8b6721ac9c 100644 --- a/trunk/drivers/infiniband/hw/mthca/mthca_qp.c +++ b/trunk/drivers/infiniband/hw/mthca/mthca_qp.c @@ -99,10 +99,6 @@ enum { MTHCA_QP_BIT_RSC = 1 << 3 }; -enum { - MTHCA_SEND_DOORBELL_FENCE = 1 << 5 -}; - struct mthca_qp_path { __be32 port_pkey; u8 rnr_retry; @@ -1263,32 +1259,6 @@ int mthca_alloc_qp(struct mthca_dev *dev, return 0; } -static void mthca_lock_cqs(struct mthca_cq *send_cq, struct mthca_cq *recv_cq) -{ - if (send_cq == recv_cq) - spin_lock_irq(&send_cq->lock); - else if (send_cq->cqn < recv_cq->cqn) { - spin_lock_irq(&send_cq->lock); - spin_lock_nested(&recv_cq->lock, SINGLE_DEPTH_NESTING); - } else { - spin_lock_irq(&recv_cq->lock); - spin_lock_nested(&send_cq->lock, SINGLE_DEPTH_NESTING); - } -} - -static void mthca_unlock_cqs(struct mthca_cq *send_cq, struct mthca_cq *recv_cq) -{ - if (send_cq == recv_cq) - spin_unlock_irq(&send_cq->lock); - else if (send_cq->cqn < recv_cq->cqn) { - spin_unlock(&recv_cq->lock); - spin_unlock_irq(&send_cq->lock); - } else { - spin_unlock(&send_cq->lock); - spin_unlock_irq(&recv_cq->lock); - } -} - int mthca_alloc_sqp(struct mthca_dev *dev, struct mthca_pd *pd, struct mthca_cq *send_cq, @@ -1341,13 +1311,17 @@ int mthca_alloc_sqp(struct mthca_dev *dev, * Lock CQs here, so that CQ polling code can do QP lookup * without taking a lock. */ - mthca_lock_cqs(send_cq, recv_cq); + spin_lock_irq(&send_cq->lock); + if (send_cq != recv_cq) + spin_lock(&recv_cq->lock); spin_lock(&dev->qp_table.lock); mthca_array_clear(&dev->qp_table.qp, mqpn); spin_unlock(&dev->qp_table.lock); - mthca_unlock_cqs(send_cq, recv_cq); + if (send_cq != recv_cq) + spin_unlock(&recv_cq->lock); + spin_unlock_irq(&send_cq->lock); err_out: dma_free_coherent(&dev->pdev->dev, sqp->header_buf_size, @@ -1381,7 +1355,9 @@ void mthca_free_qp(struct mthca_dev *dev, * Lock CQs here, so that CQ polling code can do QP lookup * without taking a lock. */ - mthca_lock_cqs(send_cq, recv_cq); + spin_lock_irq(&send_cq->lock); + if (send_cq != recv_cq) + spin_lock(&recv_cq->lock); spin_lock(&dev->qp_table.lock); mthca_array_clear(&dev->qp_table.qp, @@ -1389,7 +1365,9 @@ void mthca_free_qp(struct mthca_dev *dev, --qp->refcount; spin_unlock(&dev->qp_table.lock); - mthca_unlock_cqs(send_cq, recv_cq); + if (send_cq != recv_cq) + spin_unlock(&recv_cq->lock); + spin_unlock_irq(&send_cq->lock); wait_event(qp->wait, !get_qp_refcount(dev, qp)); @@ -1524,7 +1502,7 @@ int mthca_tavor_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, int i; int size; int size0 = 0; - u32 f0; + u32 f0 = 0; int ind; u8 op0 = 0; @@ -1708,8 +1686,6 @@ int mthca_tavor_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, if (!size0) { size0 = size; op0 = mthca_opcode[wr->opcode]; - f0 = wr->send_flags & IB_SEND_FENCE ? - MTHCA_SEND_DOORBELL_FENCE : 0; } ++ind; @@ -1867,7 +1843,7 @@ int mthca_arbel_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, int i; int size; int size0 = 0; - u32 f0; + u32 f0 = 0; int ind; u8 op0 = 0; @@ -2075,8 +2051,6 @@ int mthca_arbel_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, if (!size0) { size0 = size; op0 = mthca_opcode[wr->opcode]; - f0 = wr->send_flags & IB_SEND_FENCE ? - MTHCA_SEND_DOORBELL_FENCE : 0; } ++ind; diff --git a/trunk/drivers/infiniband/ulp/iser/iscsi_iser.c b/trunk/drivers/infiniband/ulp/iser/iscsi_iser.c index 1437d7ee3b19..34b0da5cfa0a 100644 --- a/trunk/drivers/infiniband/ulp/iser/iscsi_iser.c +++ b/trunk/drivers/infiniband/ulp/iser/iscsi_iser.c @@ -378,6 +378,21 @@ iscsi_iser_conn_start(struct iscsi_cls_conn *cls_conn) return iser_conn_set_full_featured_mode(conn); } +static void +iscsi_iser_conn_terminate(struct iscsi_conn *conn) +{ + struct iscsi_iser_conn *iser_conn = conn->dd_data; + struct iser_conn *ib_conn = iser_conn->ib_conn; + + BUG_ON(!ib_conn); + /* starts conn teardown process, waits until all previously * + * posted buffers get flushed, deallocates all conn resources */ + iser_conn_terminate(ib_conn); + iser_conn->ib_conn = NULL; + conn->recv_lock = NULL; +} + + static struct iscsi_transport iscsi_iser_transport; static struct iscsi_cls_session * @@ -540,13 +555,13 @@ iscsi_iser_ep_poll(__u64 ep_handle, int timeout_ms) static void iscsi_iser_ep_disconnect(__u64 ep_handle) { - struct iser_conn *ib_conn; + struct iser_conn *ib_conn = iscsi_iser_ib_conn_lookup(ep_handle); - ib_conn = iscsi_iser_ib_conn_lookup(ep_handle); if (!ib_conn) return; iser_err("ib conn %p state %d\n",ib_conn, ib_conn->state); + iser_conn_terminate(ib_conn); } @@ -599,6 +614,9 @@ static struct iscsi_transport iscsi_iser_transport = { .get_session_param = iscsi_session_get_param, .start_conn = iscsi_iser_conn_start, .stop_conn = iscsi_conn_stop, + /* these are called as part of conn recovery */ + .suspend_conn_recv = NULL, /* FIXME is/how this relvant to iser? */ + .terminate_conn = iscsi_iser_conn_terminate, /* IO */ .send_pdu = iscsi_conn_send_pdu, .get_stats = iscsi_iser_conn_get_stats, diff --git a/trunk/drivers/input/keyboard/atkbd.c b/trunk/drivers/input/keyboard/atkbd.c index a86afd0a5ef1..6bfa0cf4b1d2 100644 --- a/trunk/drivers/input/keyboard/atkbd.c +++ b/trunk/drivers/input/keyboard/atkbd.c @@ -498,7 +498,7 @@ static int atkbd_set_repeat_rate(struct atkbd *atkbd) i++; dev->rep[REP_PERIOD] = period[i]; - while (j < ARRAY_SIZE(delay) - 1 && delay[j] < dev->rep[REP_DELAY]) + while (j < ARRAY_SIZE(period) - 1 && delay[j] < dev->rep[REP_DELAY]) j++; dev->rep[REP_DELAY] = delay[j]; diff --git a/trunk/drivers/input/misc/wistron_btns.c b/trunk/drivers/input/misc/wistron_btns.c index de0f46dd9692..a8efc1af36cb 100644 --- a/trunk/drivers/input/misc/wistron_btns.c +++ b/trunk/drivers/input/misc/wistron_btns.c @@ -259,11 +259,11 @@ static int __init dmi_matched(struct dmi_system_id *dmi) return 1; } -static struct key_entry keymap_empty[] = { +static struct key_entry keymap_empty[] __initdata = { { KE_END, 0 } }; -static struct key_entry keymap_fs_amilo_pro_v2000[] = { +static struct key_entry keymap_fs_amilo_pro_v2000[] __initdata = { { KE_KEY, 0x01, KEY_HELP }, { KE_KEY, 0x11, KEY_PROG1 }, { KE_KEY, 0x12, KEY_PROG2 }, @@ -273,7 +273,7 @@ static struct key_entry keymap_fs_amilo_pro_v2000[] = { { KE_END, 0 } }; -static struct key_entry keymap_fujitsu_n3510[] = { +static struct key_entry keymap_fujitsu_n3510[] __initdata = { { KE_KEY, 0x11, KEY_PROG1 }, { KE_KEY, 0x12, KEY_PROG2 }, { KE_KEY, 0x36, KEY_WWW }, @@ -285,7 +285,7 @@ static struct key_entry keymap_fujitsu_n3510[] = { { KE_END, 0 } }; -static struct key_entry keymap_wistron_ms2111[] = { +static struct key_entry keymap_wistron_ms2111[] __initdata = { { KE_KEY, 0x11, KEY_PROG1 }, { KE_KEY, 0x12, KEY_PROG2 }, { KE_KEY, 0x13, KEY_PROG3 }, @@ -294,7 +294,7 @@ static struct key_entry keymap_wistron_ms2111[] = { { KE_END, 0 } }; -static struct key_entry keymap_wistron_ms2141[] = { +static struct key_entry keymap_wistron_ms2141[] __initdata = { { KE_KEY, 0x11, KEY_PROG1 }, { KE_KEY, 0x12, KEY_PROG2 }, { KE_WIFI, 0x30, 0 }, @@ -307,7 +307,7 @@ static struct key_entry keymap_wistron_ms2141[] = { { KE_END, 0 } }; -static struct key_entry keymap_acer_aspire_1500[] = { +static struct key_entry keymap_acer_aspire_1500[] __initdata = { { KE_KEY, 0x11, KEY_PROG1 }, { KE_KEY, 0x12, KEY_PROG2 }, { KE_WIFI, 0x30, 0 }, @@ -317,7 +317,7 @@ static struct key_entry keymap_acer_aspire_1500[] = { { KE_END, 0 } }; -static struct key_entry keymap_acer_travelmate_240[] = { +static struct key_entry keymap_acer_travelmate_240[] __initdata = { { KE_KEY, 0x31, KEY_MAIL }, { KE_KEY, 0x36, KEY_WWW }, { KE_KEY, 0x11, KEY_PROG1 }, @@ -327,7 +327,7 @@ static struct key_entry keymap_acer_travelmate_240[] = { { KE_END, 0 } }; -static struct key_entry keymap_aopen_1559as[] = { +static struct key_entry keymap_aopen_1559as[] __initdata = { { KE_KEY, 0x01, KEY_HELP }, { KE_KEY, 0x06, KEY_PROG3 }, { KE_KEY, 0x11, KEY_PROG1 }, diff --git a/trunk/drivers/input/mouse/psmouse-base.c b/trunk/drivers/input/mouse/psmouse-base.c index 343afa38f4c2..8bc9f51ae6c2 100644 --- a/trunk/drivers/input/mouse/psmouse-base.c +++ b/trunk/drivers/input/mouse/psmouse-base.c @@ -485,6 +485,13 @@ static int im_explorer_detect(struct psmouse *psmouse, int set_properties) param[0] = 40; ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE); + param[0] = 200; + ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE); + param[0] = 200; + ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE); + param[0] = 60; + ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE); + if (set_properties) { set_bit(BTN_MIDDLE, psmouse->dev->keybit); set_bit(REL_WHEEL, psmouse->dev->relbit); diff --git a/trunk/drivers/isdn/i4l/Kconfig b/trunk/drivers/isdn/i4l/Kconfig index 3ef567b99c74..a4f7288a1fc8 100644 --- a/trunk/drivers/isdn/i4l/Kconfig +++ b/trunk/drivers/isdn/i4l/Kconfig @@ -5,7 +5,6 @@ config ISDN_PPP bool "Support synchronous PPP" depends on INET - select SLHC help Over digital connections such as ISDN, there is no need to synchronize sender and recipient's clocks with start and stop bits diff --git a/trunk/drivers/macintosh/via-pmu-backlight.c b/trunk/drivers/macintosh/via-pmu-backlight.c index a82f313d9dc9..d3f8d75bcbb4 100644 --- a/trunk/drivers/macintosh/via-pmu-backlight.c +++ b/trunk/drivers/macintosh/via-pmu-backlight.c @@ -18,48 +18,17 @@ static struct backlight_properties pmu_backlight_data; static spinlock_t pmu_backlight_lock; static int sleeping; -static u8 bl_curve[FB_BACKLIGHT_LEVELS]; -static void pmu_backlight_init_curve(u8 off, u8 min, u8 max) -{ - unsigned int i, flat, count, range = (max - min); - - bl_curve[0] = off; - - for (flat = 1; flat < (FB_BACKLIGHT_LEVELS / 16); ++flat) - bl_curve[flat] = min; - - count = FB_BACKLIGHT_LEVELS * 15 / 16; - for (i = 0; i < count; ++i) - bl_curve[flat + i] = min + (range * (i + 1) / count); -} - -static int pmu_backlight_curve_lookup(int value) -{ - int level = (FB_BACKLIGHT_LEVELS - 1); - int i, max = 0; - - /* Look for biggest value */ - for (i = 0; i < FB_BACKLIGHT_LEVELS; i++) - max = max((int)bl_curve[i], max); - - /* Look for nearest value */ - for (i = 0; i < FB_BACKLIGHT_LEVELS; i++) { - int diff = abs(bl_curve[i] - value); - if (diff < max) { - max = diff; - level = i; - } - } - return level; -} - -static int pmu_backlight_get_level_brightness(int level) +static int pmu_backlight_get_level_brightness(struct fb_info *info, + int level) { int pmulevel; /* Get and convert the value */ - pmulevel = bl_curve[level] * FB_BACKLIGHT_MAX / MAX_PMU_LEVEL; + mutex_lock(&info->bl_mutex); + pmulevel = info->bl_curve[level] * FB_BACKLIGHT_MAX / MAX_PMU_LEVEL; + mutex_unlock(&info->bl_mutex); + if (pmulevel < 0) pmulevel = 0; else if (pmulevel > MAX_PMU_LEVEL) @@ -70,6 +39,7 @@ static int pmu_backlight_get_level_brightness(int level) static int pmu_backlight_update_status(struct backlight_device *bd) { + struct fb_info *info = class_get_devdata(&bd->class_dev); struct adb_request req; unsigned long flags; int level = bd->props->brightness; @@ -85,7 +55,7 @@ static int pmu_backlight_update_status(struct backlight_device *bd) level = 0; if (level > 0) { - int pmulevel = pmu_backlight_get_level_brightness(level); + int pmulevel = pmu_backlight_get_level_brightness(info, level); pmu_request(&req, NULL, 2, PMU_BACKLIGHT_BRIGHT, pmulevel); pmu_wait_complete(&req); @@ -118,19 +88,35 @@ static struct backlight_properties pmu_backlight_data = { }; #ifdef CONFIG_PM -void pmu_backlight_set_sleep(int sleep) +static int pmu_backlight_sleep_call(struct pmu_sleep_notifier *self, int when) { unsigned long flags; spin_lock_irqsave(&pmu_backlight_lock, flags); - sleeping = sleep; + + switch (when) { + case PBOOK_SLEEP_REQUEST: + sleeping = 1; + break; + case PBOOK_WAKE: + sleeping = 0; + break; + } + spin_unlock_irqrestore(&pmu_backlight_lock, flags); + + return PBOOK_SLEEP_OK; } -#endif /* CONFIG_PM */ + +static struct pmu_sleep_notifier pmu_backlight_sleep_notif = { + .notifier_call = pmu_backlight_sleep_call, +}; +#endif void __init pmu_backlight_init() { struct backlight_device *bd; + struct fb_info *info; char name[10]; int level, autosave; @@ -145,14 +131,27 @@ void __init pmu_backlight_init() !machine_is_compatible("PowerBook1,1")) return; - snprintf(name, sizeof(name), "pmubl"); + /* Actually, this is a hack, but I don't know of a better way + * to get the first framebuffer device. + */ + info = registered_fb[0]; + if (!info) { + printk("pmubl: No framebuffer found\n"); + goto error; + } + + snprintf(name, sizeof(name), "pmubl%d", info->node); - bd = backlight_device_register(name, NULL, &pmu_backlight_data); + bd = backlight_device_register(name, info, &pmu_backlight_data); if (IS_ERR(bd)) { printk("pmubl: Backlight registration failed\n"); goto error; } - pmu_backlight_init_curve(0x7F, 0x46, 0x0E); + + mutex_lock(&info->bl_mutex); + info->bl_dev = bd; + fb_bl_default_curve(info, 0x7F, 0x46, 0x0E); + mutex_unlock(&info->bl_mutex); level = pmu_backlight_data.max_brightness; @@ -162,22 +161,28 @@ void __init pmu_backlight_init() pmu_request(&req, NULL, 2, 0xd9, 0); pmu_wait_complete(&req); - level = pmu_backlight_curve_lookup( + mutex_lock(&info->bl_mutex); + level = pmac_backlight_curve_lookup(info, (req.reply[0] >> 4) * pmu_backlight_data.max_brightness / 15); + mutex_unlock(&info->bl_mutex); } - down(&bd->sem); + up(&bd->sem); bd->props->brightness = level; bd->props->power = FB_BLANK_UNBLANK; bd->props->update_status(bd); - up(&bd->sem); + down(&bd->sem); mutex_lock(&pmac_backlight_mutex); if (!pmac_backlight) pmac_backlight = bd; mutex_unlock(&pmac_backlight_mutex); +#ifdef CONFIG_PM + pmu_register_sleep_notifier(&pmu_backlight_sleep_notif); +#endif + printk("pmubl: Backlight initialized (%s)\n", name); return; diff --git a/trunk/drivers/macintosh/via-pmu.c b/trunk/drivers/macintosh/via-pmu.c index 14610a63f580..ea386801e215 100644 --- a/trunk/drivers/macintosh/via-pmu.c +++ b/trunk/drivers/macintosh/via-pmu.c @@ -1995,8 +1995,6 @@ restore_via_state(void) out_8(&via[IER], IER_SET | SR_INT | CB1_INT); } -extern void pmu_backlight_set_sleep(int sleep); - static int pmac_suspend_devices(void) { @@ -2034,11 +2032,6 @@ pmac_suspend_devices(void) return -EBUSY; } -#ifdef CONFIG_PMAC_BACKLIGHT - /* Tell backlight code not to muck around with the chip anymore */ - pmu_backlight_set_sleep(1); -#endif - /* Call platform functions marked "on sleep" */ pmac_pfunc_i2c_suspend(); pmac_pfunc_base_suspend(); @@ -2097,11 +2090,6 @@ pmac_wakeup_devices(void) { mdelay(100); -#ifdef CONFIG_PMAC_BACKLIGHT - /* Tell backlight code it can use the chip again */ - pmu_backlight_set_sleep(0); -#endif - /* Power back up system devices (including the PIC) */ device_power_up(); diff --git a/trunk/drivers/md/dm-raid1.c b/trunk/drivers/md/dm-raid1.c index c54de989eb00..be48cedf986b 100644 --- a/trunk/drivers/md/dm-raid1.c +++ b/trunk/drivers/md/dm-raid1.c @@ -255,9 +255,7 @@ static struct region *__rh_alloc(struct region_hash *rh, region_t region) struct region *reg, *nreg; read_unlock(&rh->hash_lock); - nreg = mempool_alloc(rh->region_pool, GFP_ATOMIC); - if (unlikely(!nreg)) - nreg = kmalloc(sizeof(struct region), GFP_NOIO); + nreg = mempool_alloc(rh->region_pool, GFP_NOIO); nreg->state = rh->log->type->in_sync(rh->log, region, 1) ? RH_CLEAN : RH_NOSYNC; nreg->rh = rh; diff --git a/trunk/drivers/md/md.c b/trunk/drivers/md/md.c index 8dbab2ef3885..b6d16022a53e 100644 --- a/trunk/drivers/md/md.c +++ b/trunk/drivers/md/md.c @@ -1597,19 +1597,6 @@ void md_update_sb(mddev_t * mddev) repeat: spin_lock_irq(&mddev->write_lock); - - if (mddev->degraded && mddev->sb_dirty == 3) - /* If the array is degraded, then skipping spares is both - * dangerous and fairly pointless. - * Dangerous because a device that was removed from the array - * might have a event_count that still looks up-to-date, - * so it can be re-added without a resync. - * Pointless because if there are any spares to skip, - * then a recovery will happen and soon that array won't - * be degraded any more and the spare can go back to sleep then. - */ - mddev->sb_dirty = 1; - sync_req = mddev->in_sync; mddev->utime = get_seconds(); if (mddev->sb_dirty == 3) diff --git a/trunk/drivers/md/raid1.c b/trunk/drivers/md/raid1.c index 3b4d69c05623..1efe22a2d041 100644 --- a/trunk/drivers/md/raid1.c +++ b/trunk/drivers/md/raid1.c @@ -930,13 +930,10 @@ static void status(struct seq_file *seq, mddev_t *mddev) seq_printf(seq, " [%d/%d] [", conf->raid_disks, conf->working_disks); - rcu_read_lock(); - for (i = 0; i < conf->raid_disks; i++) { - mdk_rdev_t *rdev = rcu_dereference(conf->mirrors[i].rdev); + for (i = 0; i < conf->raid_disks; i++) seq_printf(seq, "%s", - rdev && test_bit(In_sync, &rdev->flags) ? "U" : "_"); - } - rcu_read_unlock(); + conf->mirrors[i].rdev && + test_bit(In_sync, &conf->mirrors[i].rdev->flags) ? "U" : "_"); seq_printf(seq, "]"); } @@ -978,6 +975,7 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev) static void print_conf(conf_t *conf) { int i; + mirror_info_t *tmp; printk("RAID1 conf printout:\n"); if (!conf) { @@ -987,17 +985,14 @@ static void print_conf(conf_t *conf) printk(" --- wd:%d rd:%d\n", conf->working_disks, conf->raid_disks); - rcu_read_lock(); for (i = 0; i < conf->raid_disks; i++) { char b[BDEVNAME_SIZE]; - mdk_rdev_t *rdev = rcu_dereference(conf->mirrors[i].rdev); - if (rdev) + tmp = conf->mirrors + i; + if (tmp->rdev) printk(" disk %d, wo:%d, o:%d, dev:%s\n", - i, !test_bit(In_sync, &rdev->flags), - !test_bit(Faulty, &rdev->flags), - bdevname(rdev->bdev,b)); + i, !test_bit(In_sync, &tmp->rdev->flags), !test_bit(Faulty, &tmp->rdev->flags), + bdevname(tmp->rdev->bdev,b)); } - rcu_read_unlock(); } static void close_sync(conf_t *conf) @@ -1013,20 +1008,20 @@ static int raid1_spare_active(mddev_t *mddev) { int i; conf_t *conf = mddev->private; + mirror_info_t *tmp; /* * Find all failed disks within the RAID1 configuration - * and mark them readable. - * Called under mddev lock, so rcu protection not needed. + * and mark them readable */ for (i = 0; i < conf->raid_disks; i++) { - mdk_rdev_t *rdev = conf->mirrors[i].rdev; - if (rdev - && !test_bit(Faulty, &rdev->flags) - && !test_bit(In_sync, &rdev->flags)) { + tmp = conf->mirrors + i; + if (tmp->rdev + && !test_bit(Faulty, &tmp->rdev->flags) + && !test_bit(In_sync, &tmp->rdev->flags)) { conf->working_disks++; mddev->degraded--; - set_bit(In_sync, &rdev->flags); + set_bit(In_sync, &tmp->rdev->flags); } } @@ -1242,7 +1237,7 @@ static void sync_request_write(mddev_t *mddev, r1bio_t *r1_bio) /* ouch - failed to read all of that. * Try some synchronous reads of other devices to get * good data, much like with normal read errors. Only - * read into the pages we already have so we don't + * read into the pages we already have so they we don't * need to re-issue the read request. * We don't need to freeze the array, because being in an * active sync request, there is no normal IO, and @@ -1262,10 +1257,6 @@ static void sync_request_write(mddev_t *mddev, r1bio_t *r1_bio) s = PAGE_SIZE >> 9; do { if (r1_bio->bios[d]->bi_end_io == end_sync_read) { - /* No rcu protection needed here devices - * can only be removed when no resync is - * active, and resync is currently active - */ rdev = conf->mirrors[d].rdev; if (sync_page_io(rdev->bdev, sect + rdev->data_offset, @@ -1472,11 +1463,6 @@ static void raid1d(mddev_t *mddev) s = PAGE_SIZE >> 9; do { - /* Note: no rcu protection needed here - * as this is synchronous in the raid1d thread - * which is the thread that might remove - * a device. If raid1d ever becomes multi-threaded.... - */ rdev = conf->mirrors[d].rdev; if (rdev && test_bit(In_sync, &rdev->flags) && @@ -1500,6 +1486,7 @@ static void raid1d(mddev_t *mddev) d = conf->raid_disks; d--; rdev = conf->mirrors[d].rdev; + atomic_add(s, &rdev->corrected_errors); if (rdev && test_bit(In_sync, &rdev->flags)) { if (sync_page_io(rdev->bdev, @@ -1522,11 +1509,9 @@ static void raid1d(mddev_t *mddev) s<<9, conf->tmppage, READ) == 0) /* Well, this device is dead */ md_error(mddev, rdev); - else { - atomic_add(s, &rdev->corrected_errors); + else printk(KERN_INFO "raid1:%s: read error corrected (%d sectors at %llu on %s)\n", mdname(mddev), s, (unsigned long long)(sect + rdev->data_offset), bdevname(rdev->bdev, b)); - } } } } else { @@ -1640,16 +1625,15 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i return 0; } + /* before building a request, check if we can skip these blocks.. + * This call the bitmap_start_sync doesn't actually record anything + */ if (mddev->bitmap == NULL && mddev->recovery_cp == MaxSector && - !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery) && conf->fullsync == 0) { *skipped = 1; return max_sector - sector_nr; } - /* before building a request, check if we can skip these blocks.. - * This call the bitmap_start_sync doesn't actually record anything - */ if (!bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, 1) && !conf->fullsync && !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) { /* We can skip this block, and probably several more */ @@ -1802,17 +1786,19 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i for (i=0; iraid_disks; i++) { bio = r1_bio->bios[i]; if (bio->bi_end_io == end_sync_read) { - md_sync_acct(bio->bi_bdev, nr_sectors); + md_sync_acct(conf->mirrors[i].rdev->bdev, nr_sectors); generic_make_request(bio); } } } else { atomic_set(&r1_bio->remaining, 1); bio = r1_bio->bios[r1_bio->read_disk]; - md_sync_acct(bio->bi_bdev, nr_sectors); + md_sync_acct(conf->mirrors[r1_bio->read_disk].rdev->bdev, + nr_sectors); generic_make_request(bio); } + return nr_sectors; } diff --git a/trunk/drivers/message/fusion/mptbase.h b/trunk/drivers/message/fusion/mptbase.h index c537d71c18e4..d4cb144ab402 100644 --- a/trunk/drivers/message/fusion/mptbase.h +++ b/trunk/drivers/message/fusion/mptbase.h @@ -640,6 +640,7 @@ typedef struct _MPT_ADAPTER struct work_struct fc_setup_reset_work; struct list_head fc_rports; spinlock_t fc_rescan_work_lock; + int fc_rescan_work_count; struct work_struct fc_rescan_work; char fc_rescan_work_q_name[KOBJ_NAME_LEN]; struct workqueue_struct *fc_rescan_work_q; diff --git a/trunk/drivers/message/fusion/mptfc.c b/trunk/drivers/message/fusion/mptfc.c index 85696f34c310..90da7d63b08e 100644 --- a/trunk/drivers/message/fusion/mptfc.c +++ b/trunk/drivers/message/fusion/mptfc.c @@ -669,10 +669,7 @@ mptfc_GetFcPortPage0(MPT_ADAPTER *ioc, int portnum) * if still doing discovery, * hang loose a while until finished */ - if ((pp0dest->PortState == MPI_FCPORTPAGE0_PORTSTATE_UNKNOWN) || - (pp0dest->PortState == MPI_FCPORTPAGE0_PORTSTATE_ONLINE && - (pp0dest->Flags & MPI_FCPORTPAGE0_FLAGS_ATTACH_TYPE_MASK) - == MPI_FCPORTPAGE0_FLAGS_ATTACH_NO_INIT)) { + if (pp0dest->PortState == MPI_FCPORTPAGE0_PORTSTATE_UNKNOWN) { if (count-- > 0) { msleep(100); goto try_again; @@ -898,45 +895,59 @@ mptfc_rescan_devices(void *arg) { MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg; int ii; + int work_to_do; u64 pn; + unsigned long flags; struct mptfc_rport_info *ri; - /* start by tagging all ports as missing */ - list_for_each_entry(ri, &ioc->fc_rports, list) { - if (ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED) { - ri->flags |= MPT_RPORT_INFO_FLAGS_MISSING; + do { + /* start by tagging all ports as missing */ + list_for_each_entry(ri, &ioc->fc_rports, list) { + if (ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED) { + ri->flags |= MPT_RPORT_INFO_FLAGS_MISSING; + } } - } - /* - * now rescan devices known to adapter, - * will reregister existing rports - */ - for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) { - (void) mptfc_GetFcPortPage0(ioc, ii); - mptfc_init_host_attr(ioc, ii); /* refresh */ - mptfc_GetFcDevPage0(ioc, ii, mptfc_register_dev); - } + /* + * now rescan devices known to adapter, + * will reregister existing rports + */ + for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) { + (void) mptfc_GetFcPortPage0(ioc, ii); + mptfc_init_host_attr(ioc,ii); /* refresh */ + mptfc_GetFcDevPage0(ioc,ii,mptfc_register_dev); + } - /* delete devices still missing */ - list_for_each_entry(ri, &ioc->fc_rports, list) { - /* if newly missing, delete it */ - if (ri->flags & MPT_RPORT_INFO_FLAGS_MISSING) { + /* delete devices still missing */ + list_for_each_entry(ri, &ioc->fc_rports, list) { + /* if newly missing, delete it */ + if (ri->flags & MPT_RPORT_INFO_FLAGS_MISSING) { - ri->flags &= ~(MPT_RPORT_INFO_FLAGS_REGISTERED| - MPT_RPORT_INFO_FLAGS_MISSING); - fc_remote_port_delete(ri->rport); /* won't sleep */ - ri->rport = NULL; + ri->flags &= ~(MPT_RPORT_INFO_FLAGS_REGISTERED| + MPT_RPORT_INFO_FLAGS_MISSING); + fc_remote_port_delete(ri->rport); /* won't sleep */ + ri->rport = NULL; - pn = (u64)ri->pg0.WWPN.High << 32 | - (u64)ri->pg0.WWPN.Low; - dfcprintk ((MYIOC_s_INFO_FMT - "mptfc_rescan.%d: %llx deleted\n", - ioc->name, - ioc->sh->host_no, - (unsigned long long)pn)); + pn = (u64)ri->pg0.WWPN.High << 32 | + (u64)ri->pg0.WWPN.Low; + dfcprintk ((MYIOC_s_INFO_FMT + "mptfc_rescan.%d: %llx deleted\n", + ioc->name, + ioc->sh->host_no, + (unsigned long long)pn)); + } } - } + + /* + * allow multiple passes as target state + * might have changed during scan + */ + spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags); + if (ioc->fc_rescan_work_count > 2) /* only need one more */ + ioc->fc_rescan_work_count = 2; + work_to_do = --ioc->fc_rescan_work_count; + spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags); + } while (work_to_do); } static int @@ -1148,6 +1159,7 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id) * by doing it via the workqueue, some locking is eliminated */ + ioc->fc_rescan_work_count = 1; queue_work(ioc->fc_rescan_work_q, &ioc->fc_rescan_work); flush_workqueue(ioc->fc_rescan_work_q); @@ -1190,8 +1202,10 @@ mptfc_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply) case MPI_EVENT_RESCAN: spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags); if (ioc->fc_rescan_work_q) { - queue_work(ioc->fc_rescan_work_q, - &ioc->fc_rescan_work); + if (ioc->fc_rescan_work_count++ == 0) { + queue_work(ioc->fc_rescan_work_q, + &ioc->fc_rescan_work); + } } spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags); break; @@ -1234,8 +1248,10 @@ mptfc_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) mptfc_SetFcPortPage1_defaults(ioc); spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags); if (ioc->fc_rescan_work_q) { - queue_work(ioc->fc_rescan_work_q, - &ioc->fc_rescan_work); + if (ioc->fc_rescan_work_count++ == 0) { + queue_work(ioc->fc_rescan_work_q, + &ioc->fc_rescan_work); + } } spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags); } diff --git a/trunk/drivers/mtd/nand/ams-delta.c b/trunk/drivers/mtd/nand/ams-delta.c index a0ba07c36ee9..d7897dc6b3c8 100644 --- a/trunk/drivers/mtd/nand/ams-delta.c +++ b/trunk/drivers/mtd/nand/ams-delta.c @@ -130,13 +130,11 @@ static void ams_delta_hwcontrol(struct mtd_info *mtd, int cmd, if (ctrl & NAND_CTRL_CHANGE) { unsigned long bits; - bits = (~ctrl & NAND_NCE) ? AMS_DELTA_LATCH2_NAND_NCE : 0; - bits |= (ctrl & NAND_CLE) ? AMS_DELTA_LATCH2_NAND_CLE : 0; - bits |= (ctrl & NAND_ALE) ? AMS_DELTA_LATCH2_NAND_ALE : 0; + bits = (~ctrl & NAND_NCE) << 2; + bits |= (ctrl & NAND_CLE) << 7; + bits |= (ctrl & NAND_ALE) << 6; - ams_delta_latch2_write(AMS_DELTA_LATCH2_NAND_CLE | - AMS_DELTA_LATCH2_NAND_ALE | - AMS_DELTA_LATCH2_NAND_NCE, bits); + ams_delta_latch2_write(0xC2, bits); } if (cmd != NAND_CMD_NONE) diff --git a/trunk/drivers/mtd/nand/nand_base.c b/trunk/drivers/mtd/nand/nand_base.c index c8cbc00243fe..62b861304e03 100644 --- a/trunk/drivers/mtd/nand/nand_base.c +++ b/trunk/drivers/mtd/nand/nand_base.c @@ -1093,10 +1093,9 @@ static int nand_read(struct mtd_info *mtd, loff_t from, size_t len, ret = nand_do_read_ops(mtd, from, &chip->ops); - *retlen = chip->ops.retlen; - nand_release_device(mtd); + *retlen = chip->ops.retlen; return ret; } @@ -1692,10 +1691,9 @@ static int nand_write(struct mtd_info *mtd, loff_t to, size_t len, ret = nand_do_write_ops(mtd, to, &chip->ops); - *retlen = chip->ops.retlen; - nand_release_device(mtd); + *retlen = chip->ops.retlen; return ret; } diff --git a/trunk/drivers/net/3c501.c b/trunk/drivers/net/3c501.c index d7b115a35962..07136ec423bd 100644 --- a/trunk/drivers/net/3c501.c +++ b/trunk/drivers/net/3c501.c @@ -120,6 +120,7 @@ static const char version[] = #include #include #include +#include /* for CONFIG_IP_MULTICAST */ #include #include #include diff --git a/trunk/drivers/net/3c515.c b/trunk/drivers/net/3c515.c index aedfddf20cb3..4532b17e40ea 100644 --- a/trunk/drivers/net/3c515.c +++ b/trunk/drivers/net/3c515.c @@ -1003,8 +1003,7 @@ static int corkscrew_start_xmit(struct sk_buff *skb, /* Calculate the next Tx descriptor entry. */ int entry = vp->cur_tx % TX_RING_SIZE; struct boom_tx_desc *prev_entry; - unsigned long flags; - int i; + unsigned long flags, i; if (vp->tx_full) /* No room to transmit with */ return 1; diff --git a/trunk/drivers/net/3c59x.c b/trunk/drivers/net/3c59x.c index 7c23813bb097..80e8ca013e44 100644 --- a/trunk/drivers/net/3c59x.c +++ b/trunk/drivers/net/3c59x.c @@ -3169,7 +3169,7 @@ static int __init vortex_init(void) { int pci_rc, eisa_rc; - pci_rc = pci_register_driver(&vortex_driver); + pci_rc = pci_module_init(&vortex_driver); eisa_rc = vortex_eisa_init(); if (pci_rc == 0) diff --git a/trunk/drivers/net/8139cp.c b/trunk/drivers/net/8139cp.c index 4c2e76326c4a..1428bb7715af 100644 --- a/trunk/drivers/net/8139cp.c +++ b/trunk/drivers/net/8139cp.c @@ -2098,7 +2098,7 @@ static int __init cp_init (void) #ifdef MODULE printk("%s", version); #endif - return pci_register_driver(&cp_driver); + return pci_module_init (&cp_driver); } static void __exit cp_exit (void) diff --git a/trunk/drivers/net/8139too.c b/trunk/drivers/net/8139too.c index 2a707747ed8e..e4f4eaff7679 100644 --- a/trunk/drivers/net/8139too.c +++ b/trunk/drivers/net/8139too.c @@ -2629,7 +2629,7 @@ static int __init rtl8139_init_module (void) printk (KERN_INFO RTL8139_DRIVER_NAME "\n"); #endif - return pci_register_driver(&rtl8139_pci_driver); + return pci_module_init (&rtl8139_pci_driver); } diff --git a/trunk/drivers/net/82596.c b/trunk/drivers/net/82596.c index 257d3bce3993..7e2ca9571467 100644 --- a/trunk/drivers/net/82596.c +++ b/trunk/drivers/net/82596.c @@ -899,7 +899,7 @@ static inline int i596_rx(struct net_device *dev) } -static void i596_cleanup_cmd(struct net_device *dev, struct i596_private *lp) +static inline void i596_cleanup_cmd(struct net_device *dev, struct i596_private *lp) { struct i596_cmd *ptr; @@ -932,8 +932,7 @@ static void i596_cleanup_cmd(struct net_device *dev, struct i596_private *lp) lp->scb.cmd = I596_NULL; } -static void i596_reset(struct net_device *dev, struct i596_private *lp, - int ioaddr) +static inline void i596_reset(struct net_device *dev, struct i596_private *lp, int ioaddr) { unsigned long flags; @@ -1579,7 +1578,7 @@ static int debug = -1; module_param(debug, int, 0); MODULE_PARM_DESC(debug, "i82596 debug mask"); -int __init init_module(void) +int init_module(void) { if (debug >= 0) i596_debug = debug; @@ -1589,7 +1588,7 @@ int __init init_module(void) return 0; } -void __exit cleanup_module(void) +void cleanup_module(void) { unregister_netdev(dev_82596); #ifdef __mc68000__ diff --git a/trunk/drivers/net/8390.c b/trunk/drivers/net/8390.c index 3eb7048684a6..d2935ae39814 100644 --- a/trunk/drivers/net/8390.c +++ b/trunk/drivers/net/8390.c @@ -299,7 +299,7 @@ static int ei_start_xmit(struct sk_buff *skb, struct net_device *dev) * Slow phase with lock held. */ - disable_irq_nosync_lockdep(dev->irq); + disable_irq_nosync(dev->irq); spin_lock(&ei_local->page_lock); @@ -338,7 +338,7 @@ static int ei_start_xmit(struct sk_buff *skb, struct net_device *dev) netif_stop_queue(dev); outb_p(ENISR_ALL, e8390_base + EN0_IMR); spin_unlock(&ei_local->page_lock); - enable_irq_lockdep(dev->irq); + enable_irq(dev->irq); ei_local->stat.tx_errors++; return 1; } @@ -379,7 +379,7 @@ static int ei_start_xmit(struct sk_buff *skb, struct net_device *dev) outb_p(ENISR_ALL, e8390_base + EN0_IMR); spin_unlock(&ei_local->page_lock); - enable_irq_lockdep(dev->irq); + enable_irq(dev->irq); dev_kfree_skb (skb); ei_local->stat.tx_bytes += send_length; @@ -505,9 +505,9 @@ irqreturn_t ei_interrupt(int irq, void *dev_id, struct pt_regs * regs) #ifdef CONFIG_NET_POLL_CONTROLLER void ei_poll(struct net_device *dev) { - disable_irq_lockdep(dev->irq); + disable_irq(dev->irq); ei_interrupt(dev->irq, dev, NULL); - enable_irq_lockdep(dev->irq); + enable_irq(dev->irq); } #endif diff --git a/trunk/drivers/net/Kconfig b/trunk/drivers/net/Kconfig index 6f388d9e9bea..39189903e355 100644 --- a/trunk/drivers/net/Kconfig +++ b/trunk/drivers/net/Kconfig @@ -1411,22 +1411,6 @@ config FORCEDETH . The module will be called forcedeth. -config FORCEDETH_NAPI - bool "Use Rx and Tx Polling (NAPI) (EXPERIMENTAL)" - depends on FORCEDETH && EXPERIMENTAL - help - NAPI is a new driver API designed to reduce CPU and interrupt load - when the driver is receiving lots of packets from the card. It is - still somewhat experimental and thus not yet enabled by default. - - If your estimated Rx load is 10kpps or more, or if the card will be - deployed on potentially unfriendly networks (e.g. in a firewall), - then say Y here. - - See for more - information. - - If in doubt, say N. config CS89x0 tristate "CS89x0 support" @@ -1740,20 +1724,6 @@ config VIA_RHINE_MMIO If unsure, say Y. -config VIA_RHINE_NAPI - bool "Use Rx Polling (NAPI)" - depends on VIA_RHINE - help - NAPI is a new driver API designed to reduce CPU and interrupt load - when the driver is receiving lots of packets from the card. - - If your estimated Rx load is 10kpps or more, or if the card will be - deployed on potentially unfriendly networks (e.g. in a firewall), - then say Y here. - - See for more - information. - config LAN_SAA9730 bool "Philips SAA9730 Ethernet support (EXPERIMENTAL)" depends on NET_PCI && EXPERIMENTAL && MIPS @@ -2249,33 +2219,6 @@ config GFAR_NAPI bool "NAPI Support" depends on GIANFAR -config UCC_GETH - tristate "Freescale QE UCC GETH" - depends on QUICC_ENGINE && UCC_FAST - help - This driver supports the Gigabit Ethernet mode of QE UCC. - QE can be found on MPC836x CPUs. - -config UGETH_NAPI - bool "NAPI Support" - depends on UCC_GETH - -config UGETH_MAGIC_PACKET - bool "Magic Packet detection support" - depends on UCC_GETH - -config UGETH_FILTERING - bool "Mac address filtering support" - depends on UCC_GETH - -config UGETH_TX_ON_DEMOND - bool "Transmit on Demond support" - depends on UCC_GETH - -config UGETH_HAS_GIGA - bool - depends on UCC_GETH && MPC836x - config MV643XX_ETH tristate "MV-643XX Ethernet support" depends on MOMENCO_OCELOT_C || MOMENCO_JAGUAR_ATX || MV64360 || MOMENCO_OCELOT_3 || PPC_MULTIPLATFORM @@ -2306,15 +2249,6 @@ config MV643XX_ETH_2 This enables support for Port 2 of the Marvell MV643XX Gigabit Ethernet. -config QLA3XXX - tristate "QLogic QLA3XXX Network Driver Support" - depends on PCI - help - This driver supports QLogic ISP3XXX gigabit Ethernet cards. - - To compile this driver as a module, choose M here: the module - will be called qla3xxx. - endmenu # @@ -2575,7 +2509,6 @@ config PLIP config PPP tristate "PPP (point-to-point protocol) support" - select SLHC ---help--- PPP (Point to Point Protocol) is a newer and better SLIP. It serves the same purpose: sending Internet traffic over telephone (and other @@ -2756,7 +2689,6 @@ config SLIP config SLIP_COMPRESSED bool "CSLIP compressed headers" depends on SLIP - select SLHC ---help--- This protocol is faster than SLIP because it uses compression on the TCP/IP headers (not on the data itself), but it has to be supported @@ -2769,12 +2701,6 @@ config SLIP_COMPRESSED , explains how to configure CSLIP. This won't enlarge your kernel. -config SLHC - tristate - help - This option enables Van Jacobsen serial line header compression - routines. - config SLIP_SMART bool "Keepalive and linefill" depends on SLIP diff --git a/trunk/drivers/net/Makefile b/trunk/drivers/net/Makefile index 6ff17649c0fc..c91e95126f78 100644 --- a/trunk/drivers/net/Makefile +++ b/trunk/drivers/net/Makefile @@ -2,6 +2,10 @@ # Makefile for the Linux network (ethercard) device drivers. # +ifeq ($(CONFIG_ISDN_PPP),y) + obj-$(CONFIG_ISDN) += slhc.o +endif + obj-$(CONFIG_E1000) += e1000/ obj-$(CONFIG_IBM_EMAC) += ibm_emac/ obj-$(CONFIG_IXGB) += ixgb/ @@ -14,9 +18,6 @@ gianfar_driver-objs := gianfar.o \ gianfar_mii.o \ gianfar_sysfs.o -obj-$(CONFIG_UCC_GETH) += ucc_geth_driver.o -ucc_geth_driver-objs := ucc_geth.o ucc_geth_phy.o - # # link order important here # @@ -109,9 +110,8 @@ obj-$(CONFIG_FORCEDETH) += forcedeth.o obj-$(CONFIG_NE_H8300) += ne-h8300.o 8390.o obj-$(CONFIG_MV643XX_ETH) += mv643xx_eth.o -obj-$(CONFIG_QLA3XXX) += qla3xxx.o -obj-$(CONFIG_PPP) += ppp_generic.o +obj-$(CONFIG_PPP) += ppp_generic.o slhc.o obj-$(CONFIG_PPP_ASYNC) += ppp_async.o obj-$(CONFIG_PPP_SYNC_TTY) += ppp_synctty.o obj-$(CONFIG_PPP_DEFLATE) += ppp_deflate.o @@ -120,7 +120,9 @@ obj-$(CONFIG_PPP_MPPE) += ppp_mppe.o obj-$(CONFIG_PPPOE) += pppox.o pppoe.o obj-$(CONFIG_SLIP) += slip.o -obj-$(CONFIG_SLHC) += slhc.o +ifeq ($(CONFIG_SLIP_COMPRESSED),y) + obj-$(CONFIG_SLIP) += slhc.o +endif obj-$(CONFIG_DUMMY) += dummy.o obj-$(CONFIG_IFB) += ifb.o diff --git a/trunk/drivers/net/ac3200.c b/trunk/drivers/net/ac3200.c index 0fbbcb75af69..7952dc6d77e3 100644 --- a/trunk/drivers/net/ac3200.c +++ b/trunk/drivers/net/ac3200.c @@ -370,7 +370,8 @@ MODULE_PARM_DESC(mem, "Memory base address(es)"); MODULE_DESCRIPTION("Ansel AC3200 EISA ethernet driver"); MODULE_LICENSE("GPL"); -int __init init_module(void) +int +init_module(void) { struct net_device *dev; int this_dev, found = 0; diff --git a/trunk/drivers/net/acenic.c b/trunk/drivers/net/acenic.c index c0f3574b470b..1c01e9b3d07c 100644 --- a/trunk/drivers/net/acenic.c +++ b/trunk/drivers/net/acenic.c @@ -725,7 +725,7 @@ static struct pci_driver acenic_pci_driver = { static int __init acenic_init(void) { - return pci_register_driver(&acenic_pci_driver); + return pci_module_init(&acenic_pci_driver); } static void __exit acenic_exit(void) diff --git a/trunk/drivers/net/amd8111e.c b/trunk/drivers/net/amd8111e.c index 2ef8e554263b..ed322a76980d 100644 --- a/trunk/drivers/net/amd8111e.c +++ b/trunk/drivers/net/amd8111e.c @@ -2158,7 +2158,7 @@ static struct pci_driver amd8111e_driver = { static int __init amd8111e_init(void) { - return pci_register_driver(&amd8111e_driver); + return pci_module_init(&amd8111e_driver); } static void __exit amd8111e_cleanup(void) diff --git a/trunk/drivers/net/appletalk/cops.c b/trunk/drivers/net/appletalk/cops.c index ae7f828344d9..1d01ac0000e4 100644 --- a/trunk/drivers/net/appletalk/cops.c +++ b/trunk/drivers/net/appletalk/cops.c @@ -1030,7 +1030,7 @@ module_param(io, int, 0); module_param(irq, int, 0); module_param(board_type, int, 0); -int __init init_module(void) +int init_module(void) { if (io == 0) printk(KERN_WARNING "%s: You shouldn't autoprobe with insmod\n", diff --git a/trunk/drivers/net/arcnet/com20020-pci.c b/trunk/drivers/net/arcnet/com20020-pci.c index fc256c197cd6..979a33df0a8c 100644 --- a/trunk/drivers/net/arcnet/com20020-pci.c +++ b/trunk/drivers/net/arcnet/com20020-pci.c @@ -177,7 +177,7 @@ static struct pci_driver com20020pci_driver = { static int __init com20020pci_init(void) { BUGLVL(D_NORMAL) printk(VERSION); - return pci_register_driver(&com20020pci_driver); + return pci_module_init(&com20020pci_driver); } static void __exit com20020pci_cleanup(void) diff --git a/trunk/drivers/net/at1700.c b/trunk/drivers/net/at1700.c index 4ca061c2d5b2..5d7929c79bce 100644 --- a/trunk/drivers/net/at1700.c +++ b/trunk/drivers/net/at1700.c @@ -901,7 +901,7 @@ MODULE_PARM_DESC(io, "AT1700/FMV18X I/O base address"); MODULE_PARM_DESC(irq, "AT1700/FMV18X IRQ number"); MODULE_PARM_DESC(net_debug, "AT1700/FMV18X debug level (0-6)"); -int __init init_module(void) +int init_module(void) { if (io == 0) printk("at1700: You should not use auto-probing with insmod!\n"); diff --git a/trunk/drivers/net/b44.c b/trunk/drivers/net/b44.c index 17eb2912971d..bea0fc0ede2f 100644 --- a/trunk/drivers/net/b44.c +++ b/trunk/drivers/net/b44.c @@ -2354,7 +2354,7 @@ static int __init b44_init(void) dma_desc_align_mask = ~(dma_desc_align_size - 1); dma_desc_sync_size = max_t(unsigned int, dma_desc_align_size, sizeof(struct dma_desc)); - return pci_register_driver(&b44_driver); + return pci_module_init(&b44_driver); } static void __exit b44_cleanup(void) diff --git a/trunk/drivers/net/bnx2.c b/trunk/drivers/net/bnx2.c index 654b903985cd..652eb05a6c2d 100644 --- a/trunk/drivers/net/bnx2.c +++ b/trunk/drivers/net/bnx2.c @@ -6016,7 +6016,7 @@ static struct pci_driver bnx2_pci_driver = { static int __init bnx2_init(void) { - return pci_register_driver(&bnx2_pci_driver); + return pci_module_init(&bnx2_pci_driver); } static void __exit bnx2_cleanup(void) diff --git a/trunk/drivers/net/cassini.c b/trunk/drivers/net/cassini.c index 26040abfef62..a31544ccb3c4 100644 --- a/trunk/drivers/net/cassini.c +++ b/trunk/drivers/net/cassini.c @@ -5245,7 +5245,7 @@ static int __init cas_init(void) else link_transition_timeout = 0; - return pci_register_driver(&cas_driver); + return pci_module_init(&cas_driver); } static void __exit cas_cleanup(void) diff --git a/trunk/drivers/net/chelsio/cxgb2.c b/trunk/drivers/net/chelsio/cxgb2.c index b6de184e4699..e67872433e92 100644 --- a/trunk/drivers/net/chelsio/cxgb2.c +++ b/trunk/drivers/net/chelsio/cxgb2.c @@ -1243,7 +1243,7 @@ static struct pci_driver driver = { static int __init t1_init_module(void) { - return pci_register_driver(&driver); + return pci_module_init(&driver); } static void __exit t1_cleanup_module(void) diff --git a/trunk/drivers/net/cs89x0.c b/trunk/drivers/net/cs89x0.c index 2dcca79b1f6a..47eecce35fa4 100644 --- a/trunk/drivers/net/cs89x0.c +++ b/trunk/drivers/net/cs89x0.c @@ -1905,7 +1905,8 @@ MODULE_LICENSE("GPL"); */ -int __init init_module(void) +int +init_module(void) { struct net_device *dev = alloc_etherdev(sizeof(struct net_local)); struct net_local *lp; diff --git a/trunk/drivers/net/defxx.c b/trunk/drivers/net/defxx.c index 7d06dedbfb26..91cc8cbdd440 100644 --- a/trunk/drivers/net/defxx.c +++ b/trunk/drivers/net/defxx.c @@ -3444,7 +3444,7 @@ static int __init dfx_init(void) { int rc_pci, rc_eisa; - rc_pci = pci_register_driver(&dfx_driver); + rc_pci = pci_module_init(&dfx_driver); if (rc_pci >= 0) dfx_have_pci = 1; rc_eisa = dfx_eisa_init(); diff --git a/trunk/drivers/net/dl2k.c b/trunk/drivers/net/dl2k.c index a572c2970564..402961e68c89 100644 --- a/trunk/drivers/net/dl2k.c +++ b/trunk/drivers/net/dl2k.c @@ -1815,7 +1815,7 @@ static struct pci_driver rio_driver = { static int __init rio_init (void) { - return pci_register_driver(&rio_driver); + return pci_module_init (&rio_driver); } static void __exit diff --git a/trunk/drivers/net/dm9000.c b/trunk/drivers/net/dm9000.c index 3d76fa144c4f..1b758b707134 100644 --- a/trunk/drivers/net/dm9000.c +++ b/trunk/drivers/net/dm9000.c @@ -339,17 +339,6 @@ static void dm9000_timeout(struct net_device *dev) spin_unlock_irqrestore(&db->lock,flags); } -#ifdef CONFIG_NET_POLL_CONTROLLER -/* - *Used by netconsole - */ -static void dm9000_poll_controller(struct net_device *dev) -{ - disable_irq(dev->irq); - dm9000_interrupt(dev->irq,dev,NULL); - enable_irq(dev->irq); -} -#endif /* dm9000_release_board * @@ -549,9 +538,6 @@ dm9000_probe(struct platform_device *pdev) ndev->stop = &dm9000_stop; ndev->get_stats = &dm9000_get_stats; ndev->set_multicast_list = &dm9000_hash_table; -#ifdef CONFIG_NET_POLL_CONTROLLER - ndev->poll_controller = &dm9000_poll_controller; -#endif #ifdef DM9000_PROGRAM_EEPROM program_eeprom(db); diff --git a/trunk/drivers/net/e100.c b/trunk/drivers/net/e100.c index 47d970896a5c..91ef5f2fd768 100644 --- a/trunk/drivers/net/e100.c +++ b/trunk/drivers/net/e100.c @@ -1,7 +1,7 @@ /******************************************************************************* - Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved. + Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free @@ -158,10 +158,10 @@ #define DRV_NAME "e100" -#define DRV_EXT "-NAPI" -#define DRV_VERSION "3.5.16-k2"DRV_EXT +#define DRV_EXT "-NAPI" +#define DRV_VERSION "3.5.10-k2"DRV_EXT #define DRV_DESCRIPTION "Intel(R) PRO/100 Network Driver" -#define DRV_COPYRIGHT "Copyright(c) 1999-2006 Intel Corporation" +#define DRV_COPYRIGHT "Copyright(c) 1999-2005 Intel Corporation" #define PFX DRV_NAME ": " #define E100_WATCHDOG_PERIOD (2 * HZ) @@ -173,11 +173,8 @@ MODULE_LICENSE("GPL"); MODULE_VERSION(DRV_VERSION); static int debug = 3; -static int eeprom_bad_csum_allow = 0; module_param(debug, int, 0); -module_param(eeprom_bad_csum_allow, int, 0); MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)"); -MODULE_PARM_DESC(eeprom_bad_csum_allow, "Allow bad eeprom checksums"); #define DPRINTK(nlevel, klevel, fmt, args...) \ (void)((NETIF_MSG_##nlevel & nic->msg_enable) && \ printk(KERN_##klevel PFX "%s: %s: " fmt, nic->netdev->name, \ @@ -759,8 +756,7 @@ static int e100_eeprom_load(struct nic *nic) checksum = le16_to_cpu(0xBABA - checksum); if(checksum != nic->eeprom[nic->eeprom_wc - 1]) { DPRINTK(PROBE, ERR, "EEPROM corrupted\n"); - if (!eeprom_bad_csum_allow) - return -EAGAIN; + return -EAGAIN; } return 0; @@ -1395,11 +1391,15 @@ static int e100_phy_init(struct nic *nic) } if((nic->mac >= mac_82550_D102) || ((nic->flags & ich) && - (mdio_read(netdev, nic->mii.phy_id, MII_TPISTATUS) & 0x8000) && - !(nic->eeprom[eeprom_cnfg_mdix] & eeprom_mdix_enabled))) { - /* enable/disable MDI/MDI-X auto-switching. */ - mdio_write(netdev, nic->mii.phy_id, MII_NCONFIG, - nic->mii.force_media ? 0 : NCONFIG_AUTO_SWITCH); + (mdio_read(netdev, nic->mii.phy_id, MII_TPISTATUS) & 0x8000))) { + /* enable/disable MDI/MDI-X auto-switching. + MDI/MDI-X auto-switching is disabled for 82551ER/QM chips */ + if((nic->mac == mac_82551_E) || (nic->mac == mac_82551_F) || + (nic->mac == mac_82551_10) || (nic->mii.force_media) || + !(nic->eeprom[eeprom_cnfg_mdix] & eeprom_mdix_enabled)) + mdio_write(netdev, nic->mii.phy_id, MII_NCONFIG, 0); + else + mdio_write(netdev, nic->mii.phy_id, MII_NCONFIG, NCONFIG_AUTO_SWITCH); } return 0; @@ -1763,10 +1763,11 @@ static inline void e100_start_receiver(struct nic *nic, struct rx *rx) #define RFD_BUF_LEN (sizeof(struct rfd) + VLAN_ETH_FRAME_LEN) static int e100_rx_alloc_skb(struct nic *nic, struct rx *rx) { - if(!(rx->skb = netdev_alloc_skb(nic->netdev, RFD_BUF_LEN + NET_IP_ALIGN))) + if(!(rx->skb = dev_alloc_skb(RFD_BUF_LEN + NET_IP_ALIGN))) return -ENOMEM; /* Align, init, and map the RFD. */ + rx->skb->dev = nic->netdev; skb_reserve(rx->skb, NET_IP_ALIGN); memcpy(rx->skb->data, &nic->blank_rfd, sizeof(struct rfd)); rx->dma_addr = pci_map_single(nic->pdev, rx->skb->data, @@ -2142,7 +2143,7 @@ static int e100_loopback_test(struct nic *nic, enum loopback loopback_mode) e100_start_receiver(nic, NULL); - if(!(skb = netdev_alloc_skb(nic->netdev, ETH_DATA_LEN))) { + if(!(skb = dev_alloc_skb(ETH_DATA_LEN))) { err = -ENOMEM; goto err_loopback_none; } @@ -2794,7 +2795,6 @@ static pci_ers_result_t e100_io_error_detected(struct pci_dev *pdev, pci_channel /* Detach; put netif into state similar to hotplug unplug. */ netif_poll_enable(netdev); netif_device_detach(netdev); - pci_disable_device(pdev); /* Request a slot reset. */ return PCI_ERS_RESULT_NEED_RESET; @@ -2873,7 +2873,7 @@ static int __init e100_init_module(void) printk(KERN_INFO PFX "%s, %s\n", DRV_DESCRIPTION, DRV_VERSION); printk(KERN_INFO PFX "%s\n", DRV_COPYRIGHT); } - return pci_register_driver(&e100_driver); + return pci_module_init(&e100_driver); } static void __exit e100_cleanup_module(void) diff --git a/trunk/drivers/net/e1000/e1000.h b/trunk/drivers/net/e1000/e1000.h index 98afa9c2057e..d304297c496c 100644 --- a/trunk/drivers/net/e1000/e1000.h +++ b/trunk/drivers/net/e1000/e1000.h @@ -242,10 +242,12 @@ struct e1000_adapter { struct timer_list watchdog_timer; struct timer_list phy_info_timer; struct vlan_group *vlgrp; - uint16_t mng_vlan_id; + uint16_t mng_vlan_id; uint32_t bd_number; uint32_t rx_buffer_len; + uint32_t part_num; uint32_t wol; + uint32_t ksp3_port_a; uint32_t smartspeed; uint32_t en_mng_pt; uint16_t link_speed; @@ -340,9 +342,7 @@ struct e1000_adapter { boolean_t tso_force; #endif boolean_t smart_power_down; /* phy smart power down */ - boolean_t quad_port_a; unsigned long flags; - uint32_t eeprom_wol; }; enum e1000_state_t { diff --git a/trunk/drivers/net/e1000/e1000_ethtool.c b/trunk/drivers/net/e1000/e1000_ethtool.c index 3fccffdb27b5..88a82ba88f57 100644 --- a/trunk/drivers/net/e1000/e1000_ethtool.c +++ b/trunk/drivers/net/e1000/e1000_ethtool.c @@ -183,9 +183,6 @@ e1000_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) return -EINVAL; } - while (test_and_set_bit(__E1000_RESETTING, &adapter->flags)) - msleep(1); - if (ecmd->autoneg == AUTONEG_ENABLE) { hw->autoneg = 1; if (hw->media_type == e1000_media_type_fiber) @@ -202,20 +199,16 @@ e1000_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) ADVERTISED_TP; ecmd->advertising = hw->autoneg_advertised; } else - if (e1000_set_spd_dplx(adapter, ecmd->speed + ecmd->duplex)) { - clear_bit(__E1000_RESETTING, &adapter->flags); + if (e1000_set_spd_dplx(adapter, ecmd->speed + ecmd->duplex)) return -EINVAL; - } /* reset the link */ - if (netif_running(adapter->netdev)) { - e1000_down(adapter); - e1000_up(adapter); - } else + if (netif_running(adapter->netdev)) + e1000_reinit_locked(adapter); + else e1000_reset(adapter); - clear_bit(__E1000_RESETTING, &adapter->flags); return 0; } @@ -245,13 +238,9 @@ e1000_set_pauseparam(struct net_device *netdev, { struct e1000_adapter *adapter = netdev_priv(netdev); struct e1000_hw *hw = &adapter->hw; - int retval = 0; adapter->fc_autoneg = pause->autoneg; - while (test_and_set_bit(__E1000_RESETTING, &adapter->flags)) - msleep(1); - if (pause->rx_pause && pause->tx_pause) hw->fc = e1000_fc_full; else if (pause->rx_pause && !pause->tx_pause) @@ -264,17 +253,15 @@ e1000_set_pauseparam(struct net_device *netdev, hw->original_fc = hw->fc; if (adapter->fc_autoneg == AUTONEG_ENABLE) { - if (netif_running(adapter->netdev)) { - e1000_down(adapter); - e1000_up(adapter); - } else + if (netif_running(adapter->netdev)) + e1000_reinit_locked(adapter); + else e1000_reset(adapter); } else - retval = ((hw->media_type == e1000_media_type_fiber) ? - e1000_setup_link(hw) : e1000_force_mac_fc(hw)); + return ((hw->media_type == e1000_media_type_fiber) ? + e1000_setup_link(hw) : e1000_force_mac_fc(hw)); - clear_bit(__E1000_RESETTING, &adapter->flags); - return retval; + return 0; } static uint32_t @@ -428,12 +415,12 @@ e1000_get_regs(struct net_device *netdev, regs_buff[23] = regs_buff[18]; /* mdix mode */ e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT, 0x0); } else { - e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data); + e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data); regs_buff[13] = (uint32_t)phy_data; /* cable length */ regs_buff[14] = 0; /* Dummy (to align w/ IGP phy reg dump) */ regs_buff[15] = 0; /* Dummy (to align w/ IGP phy reg dump) */ regs_buff[16] = 0; /* Dummy (to align w/ IGP phy reg dump) */ - e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data); + e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data); regs_buff[17] = (uint32_t)phy_data; /* extended 10bt distance */ regs_buff[18] = regs_buff[13]; /* cable polarity */ regs_buff[19] = 0; /* Dummy (to align w/ IGP phy reg dump) */ @@ -709,6 +696,7 @@ e1000_set_ringparam(struct net_device *netdev, } clear_bit(__E1000_RESETTING, &adapter->flags); + return 0; err_setup_tx: e1000_free_all_rx_resources(adapter); @@ -893,17 +881,16 @@ e1000_intr_test(struct e1000_adapter *adapter, uint64_t *data) *data = 0; - /* NOTE: we don't test MSI interrupts here, yet */ /* Hook up test interrupt handler just for this test */ if (!request_irq(irq, &e1000_test_intr, IRQF_PROBE_SHARED, - netdev->name, netdev)) - shared_int = FALSE; - else if (request_irq(irq, &e1000_test_intr, IRQF_SHARED, - netdev->name, netdev)) { + netdev->name, netdev)) { + shared_int = FALSE; + } else if (request_irq(irq, &e1000_test_intr, IRQF_SHARED, + netdev->name, netdev)){ *data = 1; return -1; } - DPRINTK(HW, INFO, "testing %s interrupt\n", + DPRINTK(PROBE,INFO, "testing %s interrupt\n", (shared_int ? "shared" : "unshared")); /* Disable all the interrupts */ @@ -1269,10 +1256,11 @@ e1000_integrated_phy_loopback(struct e1000_adapter *adapter) e1000_write_phy_reg(&adapter->hw, PHY_CTRL, 0x9140); /* autoneg off */ e1000_write_phy_reg(&adapter->hw, PHY_CTRL, 0x8140); - } else if (adapter->hw.phy_type == e1000_phy_gg82563) + } else if (adapter->hw.phy_type == e1000_phy_gg82563) { e1000_write_phy_reg(&adapter->hw, GG82563_PHY_KMRN_MODE_CTRL, 0x1CC); + } ctrl_reg = E1000_READ_REG(&adapter->hw, CTRL); @@ -1300,9 +1288,9 @@ e1000_integrated_phy_loopback(struct e1000_adapter *adapter) } if (adapter->hw.media_type == e1000_media_type_copper && - adapter->hw.phy_type == e1000_phy_m88) + adapter->hw.phy_type == e1000_phy_m88) { ctrl_reg |= E1000_CTRL_ILOS; /* Invert Loss of Signal */ - else { + } else { /* Set the ILOS bit on the fiber Nic is half * duplex link is detected. */ stat_reg = E1000_READ_REG(&adapter->hw, STATUS); @@ -1438,10 +1426,11 @@ e1000_loopback_cleanup(struct e1000_adapter *adapter) case e1000_82546_rev_3: default: hw->autoneg = TRUE; - if (hw->phy_type == e1000_phy_gg82563) + if (hw->phy_type == e1000_phy_gg82563) { e1000_write_phy_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, 0x180); + } e1000_read_phy_reg(hw, PHY_CTRL, &phy_reg); if (phy_reg & MII_CR_LOOPBACK) { phy_reg &= ~MII_CR_LOOPBACK; @@ -1601,8 +1590,6 @@ e1000_diag_test_count(struct net_device *netdev) return E1000_TEST_LEN; } -extern void e1000_power_up_phy(struct e1000_adapter *); - static void e1000_diag_test(struct net_device *netdev, struct ethtool_test *eth_test, uint64_t *data) @@ -1619,8 +1606,6 @@ e1000_diag_test(struct net_device *netdev, uint8_t forced_speed_duplex = adapter->hw.forced_speed_duplex; uint8_t autoneg = adapter->hw.autoneg; - DPRINTK(HW, INFO, "offline testing starting\n"); - /* Link test performed before hardware reset so autoneg doesn't * interfere with test result */ if (e1000_link_test(adapter, &data[4])) @@ -1644,8 +1629,6 @@ e1000_diag_test(struct net_device *netdev, eth_test->flags |= ETH_TEST_FL_FAILED; e1000_reset(adapter); - /* make sure the phy is powered up */ - e1000_power_up_phy(adapter); if (e1000_loopback_test(adapter, &data[3])) eth_test->flags |= ETH_TEST_FL_FAILED; @@ -1659,7 +1642,6 @@ e1000_diag_test(struct net_device *netdev, if (if_running) dev_open(netdev); } else { - DPRINTK(HW, INFO, "online testing starting\n"); /* Online tests */ if (e1000_link_test(adapter, &data[4])) eth_test->flags |= ETH_TEST_FL_FAILED; @@ -1675,12 +1657,14 @@ e1000_diag_test(struct net_device *netdev, msleep_interruptible(4 * 1000); } -static int e1000_wol_exclusion(struct e1000_adapter *adapter, struct ethtool_wolinfo *wol) +static void +e1000_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) { + struct e1000_adapter *adapter = netdev_priv(netdev); struct e1000_hw *hw = &adapter->hw; - int retval = 1; /* fail by default */ - switch (hw->device_id) { + switch (adapter->hw.device_id) { + case E1000_DEV_ID_82542: case E1000_DEV_ID_82543GC_FIBER: case E1000_DEV_ID_82543GC_COPPER: case E1000_DEV_ID_82544EI_FIBER: @@ -1688,87 +1672,52 @@ static int e1000_wol_exclusion(struct e1000_adapter *adapter, struct ethtool_wol case E1000_DEV_ID_82545EM_FIBER: case E1000_DEV_ID_82545EM_COPPER: case E1000_DEV_ID_82546GB_QUAD_COPPER: - case E1000_DEV_ID_82546GB_PCIE: - /* these don't support WoL at all */ wol->supported = 0; - break; + wol->wolopts = 0; + return; + + case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3: + /* device id 10B5 port-A supports wol */ + if (!adapter->ksp3_port_a) { + wol->supported = 0; + return; + } + /* KSP3 does not suppport UCAST wake-ups for any interface */ + wol->supported = WAKE_MCAST | WAKE_BCAST | WAKE_MAGIC; + + if (adapter->wol & E1000_WUFC_EX) + DPRINTK(DRV, ERR, "Interface does not support " + "directed (unicast) frame wake-up packets\n"); + wol->wolopts = 0; + goto do_defaults; + case E1000_DEV_ID_82546EB_FIBER: case E1000_DEV_ID_82546GB_FIBER: case E1000_DEV_ID_82571EB_FIBER: - case E1000_DEV_ID_82571EB_SERDES: - case E1000_DEV_ID_82571EB_COPPER: - /* Wake events not supported on port B */ + /* Wake events only supported on port A for dual fiber */ if (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1) { wol->supported = 0; - break; - } - /* return success for non excluded adapter ports */ - retval = 0; - break; - case E1000_DEV_ID_82571EB_QUAD_COPPER: - case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3: - /* quad port adapters only support WoL on port A */ - if (!adapter->quad_port_a) { - wol->supported = 0; - break; + wol->wolopts = 0; + return; } - /* return success for non excluded adapter ports */ - retval = 0; - break; - default: - /* dual port cards only support WoL on port A from now on - * unless it was enabled in the eeprom for port B - * so exclude FUNC_1 ports from having WoL enabled */ - if (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1 && - !adapter->eeprom_wol) { - wol->supported = 0; - break; - } - - retval = 0; - } - - return retval; -} - -static void -e1000_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) -{ - struct e1000_adapter *adapter = netdev_priv(netdev); - - wol->supported = WAKE_UCAST | WAKE_MCAST | - WAKE_BCAST | WAKE_MAGIC; - wol->wolopts = 0; - - /* this function will set ->supported = 0 and return 1 if wol is not - * supported by this hardware */ - if (e1000_wol_exclusion(adapter, wol)) - return; + /* Fall Through */ - /* apply any specific unsupported masks here */ - switch (adapter->hw.device_id) { - case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3: - /* KSP3 does not suppport UCAST wake-ups */ - wol->supported &= ~WAKE_UCAST; + default: + wol->supported = WAKE_UCAST | WAKE_MCAST | + WAKE_BCAST | WAKE_MAGIC; + wol->wolopts = 0; +do_defaults: if (adapter->wol & E1000_WUFC_EX) - DPRINTK(DRV, ERR, "Interface does not support " - "directed (unicast) frame wake-up packets\n"); - break; - default: - break; + wol->wolopts |= WAKE_UCAST; + if (adapter->wol & E1000_WUFC_MC) + wol->wolopts |= WAKE_MCAST; + if (adapter->wol & E1000_WUFC_BC) + wol->wolopts |= WAKE_BCAST; + if (adapter->wol & E1000_WUFC_MAG) + wol->wolopts |= WAKE_MAGIC; + return; } - - if (adapter->wol & E1000_WUFC_EX) - wol->wolopts |= WAKE_UCAST; - if (adapter->wol & E1000_WUFC_MC) - wol->wolopts |= WAKE_MCAST; - if (adapter->wol & E1000_WUFC_BC) - wol->wolopts |= WAKE_BCAST; - if (adapter->wol & E1000_WUFC_MAG) - wol->wolopts |= WAKE_MAGIC; - - return; } static int @@ -1777,35 +1726,51 @@ e1000_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) struct e1000_adapter *adapter = netdev_priv(netdev); struct e1000_hw *hw = &adapter->hw; - if (wol->wolopts & (WAKE_PHY | WAKE_ARP | WAKE_MAGICSECURE)) - return -EOPNOTSUPP; - - if (e1000_wol_exclusion(adapter, wol)) + switch (adapter->hw.device_id) { + case E1000_DEV_ID_82542: + case E1000_DEV_ID_82543GC_FIBER: + case E1000_DEV_ID_82543GC_COPPER: + case E1000_DEV_ID_82544EI_FIBER: + case E1000_DEV_ID_82546EB_QUAD_COPPER: + case E1000_DEV_ID_82546GB_QUAD_COPPER: + case E1000_DEV_ID_82545EM_FIBER: + case E1000_DEV_ID_82545EM_COPPER: return wol->wolopts ? -EOPNOTSUPP : 0; - switch (hw->device_id) { case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3: + /* device id 10B5 port-A supports wol */ + if (!adapter->ksp3_port_a) + return wol->wolopts ? -EOPNOTSUPP : 0; + if (wol->wolopts & WAKE_UCAST) { DPRINTK(DRV, ERR, "Interface does not support " "directed (unicast) frame wake-up packets\n"); return -EOPNOTSUPP; } - break; + + case E1000_DEV_ID_82546EB_FIBER: + case E1000_DEV_ID_82546GB_FIBER: + case E1000_DEV_ID_82571EB_FIBER: + /* Wake events only supported on port A for dual fiber */ + if (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1) + return wol->wolopts ? -EOPNOTSUPP : 0; + /* Fall Through */ + default: - break; - } + if (wol->wolopts & (WAKE_PHY | WAKE_ARP | WAKE_MAGICSECURE)) + return -EOPNOTSUPP; - /* these settings will always override what we currently have */ - adapter->wol = 0; + adapter->wol = 0; - if (wol->wolopts & WAKE_UCAST) - adapter->wol |= E1000_WUFC_EX; - if (wol->wolopts & WAKE_MCAST) - adapter->wol |= E1000_WUFC_MC; - if (wol->wolopts & WAKE_BCAST) - adapter->wol |= E1000_WUFC_BC; - if (wol->wolopts & WAKE_MAGIC) - adapter->wol |= E1000_WUFC_MAG; + if (wol->wolopts & WAKE_UCAST) + adapter->wol |= E1000_WUFC_EX; + if (wol->wolopts & WAKE_MCAST) + adapter->wol |= E1000_WUFC_MC; + if (wol->wolopts & WAKE_BCAST) + adapter->wol |= E1000_WUFC_BC; + if (wol->wolopts & WAKE_MAGIC) + adapter->wol |= E1000_WUFC_MAG; + } return 0; } @@ -1930,8 +1895,8 @@ static struct ethtool_ops e1000_ethtool_ops = { .get_regs = e1000_get_regs, .get_wol = e1000_get_wol, .set_wol = e1000_set_wol, - .get_msglevel = e1000_get_msglevel, - .set_msglevel = e1000_set_msglevel, + .get_msglevel = e1000_get_msglevel, + .set_msglevel = e1000_set_msglevel, .nway_reset = e1000_nway_reset, .get_link = ethtool_op_get_link, .get_eeprom_len = e1000_get_eeprom_len, @@ -1939,17 +1904,17 @@ static struct ethtool_ops e1000_ethtool_ops = { .set_eeprom = e1000_set_eeprom, .get_ringparam = e1000_get_ringparam, .set_ringparam = e1000_set_ringparam, - .get_pauseparam = e1000_get_pauseparam, - .set_pauseparam = e1000_set_pauseparam, - .get_rx_csum = e1000_get_rx_csum, - .set_rx_csum = e1000_set_rx_csum, - .get_tx_csum = e1000_get_tx_csum, - .set_tx_csum = e1000_set_tx_csum, - .get_sg = ethtool_op_get_sg, - .set_sg = ethtool_op_set_sg, + .get_pauseparam = e1000_get_pauseparam, + .set_pauseparam = e1000_set_pauseparam, + .get_rx_csum = e1000_get_rx_csum, + .set_rx_csum = e1000_set_rx_csum, + .get_tx_csum = e1000_get_tx_csum, + .set_tx_csum = e1000_set_tx_csum, + .get_sg = ethtool_op_get_sg, + .set_sg = ethtool_op_set_sg, #ifdef NETIF_F_TSO - .get_tso = ethtool_op_get_tso, - .set_tso = e1000_set_tso, + .get_tso = ethtool_op_get_tso, + .set_tso = e1000_set_tso, #endif .self_test_count = e1000_diag_test_count, .self_test = e1000_diag_test, @@ -1957,7 +1922,7 @@ static struct ethtool_ops e1000_ethtool_ops = { .phys_id = e1000_phys_id, .get_stats_count = e1000_get_stats_count, .get_ethtool_stats = e1000_get_ethtool_stats, - .get_perm_addr = ethtool_op_get_perm_addr, + .get_perm_addr = ethtool_op_get_perm_addr, }; void e1000_set_ethtool_ops(struct net_device *netdev) diff --git a/trunk/drivers/net/e1000/e1000_hw.c b/trunk/drivers/net/e1000/e1000_hw.c index 4b54c489f819..583518ae49ce 100644 --- a/trunk/drivers/net/e1000/e1000_hw.c +++ b/trunk/drivers/net/e1000/e1000_hw.c @@ -31,7 +31,6 @@ * Shared functions for accessing and configuring the MAC */ - #include "e1000_hw.h" static int32_t e1000_set_phy_type(struct e1000_hw *hw); @@ -106,33 +105,6 @@ static int32_t e1000_configure_kmrn_for_10_100(struct e1000_hw *hw, uint16_t duplex); static int32_t e1000_configure_kmrn_for_1000(struct e1000_hw *hw); -static int32_t e1000_erase_ich8_4k_segment(struct e1000_hw *hw, - uint32_t segment); -static int32_t e1000_get_software_flag(struct e1000_hw *hw); -static int32_t e1000_get_software_semaphore(struct e1000_hw *hw); -static int32_t e1000_init_lcd_from_nvm(struct e1000_hw *hw); -static int32_t e1000_kumeran_lock_loss_workaround(struct e1000_hw *hw); -static int32_t e1000_read_eeprom_ich8(struct e1000_hw *hw, uint16_t offset, - uint16_t words, uint16_t *data); -static int32_t e1000_read_ich8_byte(struct e1000_hw *hw, uint32_t index, - uint8_t* data); -static int32_t e1000_read_ich8_word(struct e1000_hw *hw, uint32_t index, - uint16_t *data); -static int32_t e1000_read_kmrn_reg(struct e1000_hw *hw, uint32_t reg_addr, - uint16_t *data); -static void e1000_release_software_flag(struct e1000_hw *hw); -static void e1000_release_software_semaphore(struct e1000_hw *hw); -static int32_t e1000_set_pci_ex_no_snoop(struct e1000_hw *hw, - uint32_t no_snoop); -static int32_t e1000_verify_write_ich8_byte(struct e1000_hw *hw, - uint32_t index, uint8_t byte); -static int32_t e1000_write_eeprom_ich8(struct e1000_hw *hw, uint16_t offset, - uint16_t words, uint16_t *data); -static int32_t e1000_write_ich8_byte(struct e1000_hw *hw, uint32_t index, - uint8_t data); -static int32_t e1000_write_kmrn_reg(struct e1000_hw *hw, uint32_t reg_addr, - uint16_t data); - /* IGP cable length table */ static const uint16_t e1000_igp_cable_length_table[IGP01E1000_AGC_LENGTH_TABLE_SIZE] = @@ -167,10 +139,10 @@ e1000_set_phy_type(struct e1000_hw *hw) { DEBUGFUNC("e1000_set_phy_type"); - if (hw->mac_type == e1000_undefined) + if(hw->mac_type == e1000_undefined) return -E1000_ERR_PHY_TYPE; - switch (hw->phy_id) { + switch(hw->phy_id) { case M88E1000_E_PHY_ID: case M88E1000_I_PHY_ID: case M88E1011_I_PHY_ID: @@ -178,10 +150,10 @@ e1000_set_phy_type(struct e1000_hw *hw) hw->phy_type = e1000_phy_m88; break; case IGP01E1000_I_PHY_ID: - if (hw->mac_type == e1000_82541 || - hw->mac_type == e1000_82541_rev_2 || - hw->mac_type == e1000_82547 || - hw->mac_type == e1000_82547_rev_2) { + if(hw->mac_type == e1000_82541 || + hw->mac_type == e1000_82541_rev_2 || + hw->mac_type == e1000_82547 || + hw->mac_type == e1000_82547_rev_2) { hw->phy_type = e1000_phy_igp; break; } @@ -208,7 +180,6 @@ e1000_set_phy_type(struct e1000_hw *hw) return E1000_SUCCESS; } - /****************************************************************************** * IGP phy init script - initializes the GbE PHY * @@ -222,7 +193,7 @@ e1000_phy_init_script(struct e1000_hw *hw) DEBUGFUNC("e1000_phy_init_script"); - if (hw->phy_init_script) { + if(hw->phy_init_script) { msec_delay(20); /* Save off the current value of register 0x2F5B to be restored at @@ -238,7 +209,7 @@ e1000_phy_init_script(struct e1000_hw *hw) msec_delay(5); - switch (hw->mac_type) { + switch(hw->mac_type) { case e1000_82541: case e1000_82547: e1000_write_phy_reg(hw, 0x1F95, 0x0001); @@ -275,22 +246,22 @@ e1000_phy_init_script(struct e1000_hw *hw) /* Now enable the transmitter */ e1000_write_phy_reg(hw, 0x2F5B, phy_saved_data); - if (hw->mac_type == e1000_82547) { + if(hw->mac_type == e1000_82547) { uint16_t fused, fine, coarse; /* Move to analog registers page */ e1000_read_phy_reg(hw, IGP01E1000_ANALOG_SPARE_FUSE_STATUS, &fused); - if (!(fused & IGP01E1000_ANALOG_SPARE_FUSE_ENABLED)) { + if(!(fused & IGP01E1000_ANALOG_SPARE_FUSE_ENABLED)) { e1000_read_phy_reg(hw, IGP01E1000_ANALOG_FUSE_STATUS, &fused); fine = fused & IGP01E1000_ANALOG_FUSE_FINE_MASK; coarse = fused & IGP01E1000_ANALOG_FUSE_COARSE_MASK; - if (coarse > IGP01E1000_ANALOG_FUSE_COARSE_THRESH) { + if(coarse > IGP01E1000_ANALOG_FUSE_COARSE_THRESH) { coarse -= IGP01E1000_ANALOG_FUSE_COARSE_10; fine -= IGP01E1000_ANALOG_FUSE_FINE_1; - } else if (coarse == IGP01E1000_ANALOG_FUSE_COARSE_THRESH) + } else if(coarse == IGP01E1000_ANALOG_FUSE_COARSE_THRESH) fine -= IGP01E1000_ANALOG_FUSE_FINE_10; fused = (fused & IGP01E1000_ANALOG_FUSE_POLY_MASK) | @@ -389,7 +360,6 @@ e1000_set_mac_type(struct e1000_hw *hw) case E1000_DEV_ID_82571EB_COPPER: case E1000_DEV_ID_82571EB_FIBER: case E1000_DEV_ID_82571EB_SERDES: - case E1000_DEV_ID_82571EB_QUAD_COPPER: hw->mac_type = e1000_82571; break; case E1000_DEV_ID_82572EI_COPPER: @@ -421,7 +391,7 @@ e1000_set_mac_type(struct e1000_hw *hw) return -E1000_ERR_MAC_TYPE; } - switch (hw->mac_type) { + switch(hw->mac_type) { case e1000_ich8lan: hw->swfwhw_semaphore_present = TRUE; hw->asf_firmware_present = TRUE; @@ -459,7 +429,7 @@ e1000_set_media_type(struct e1000_hw *hw) DEBUGFUNC("e1000_set_media_type"); - if (hw->mac_type != e1000_82543) { + if(hw->mac_type != e1000_82543) { /* tbi_compatibility is only valid on 82543 */ hw->tbi_compatibility_en = FALSE; } @@ -519,16 +489,16 @@ e1000_reset_hw(struct e1000_hw *hw) DEBUGFUNC("e1000_reset_hw"); /* For 82542 (rev 2.0), disable MWI before issuing a device reset */ - if (hw->mac_type == e1000_82542_rev2_0) { + if(hw->mac_type == e1000_82542_rev2_0) { DEBUGOUT("Disabling MWI on 82542 rev 2.0\n"); e1000_pci_clear_mwi(hw); } - if (hw->bus_type == e1000_bus_type_pci_express) { + if(hw->bus_type == e1000_bus_type_pci_express) { /* Prevent the PCI-E bus from sticking if there is no TLP connection * on the last TLP read/write transaction when MAC is reset. */ - if (e1000_disable_pciex_master(hw) != E1000_SUCCESS) { + if(e1000_disable_pciex_master(hw) != E1000_SUCCESS) { DEBUGOUT("PCI-E Master disable polling has failed.\n"); } } @@ -556,14 +526,14 @@ e1000_reset_hw(struct e1000_hw *hw) ctrl = E1000_READ_REG(hw, CTRL); /* Must reset the PHY before resetting the MAC */ - if ((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) { + if((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) { E1000_WRITE_REG(hw, CTRL, (ctrl | E1000_CTRL_PHY_RST)); msec_delay(5); } /* Must acquire the MDIO ownership before MAC reset. * Ownership defaults to firmware after a reset. */ - if (hw->mac_type == e1000_82573) { + if(hw->mac_type == e1000_82573) { timeout = 10; extcnf_ctrl = E1000_READ_REG(hw, EXTCNF_CTRL); @@ -573,14 +543,14 @@ e1000_reset_hw(struct e1000_hw *hw) E1000_WRITE_REG(hw, EXTCNF_CTRL, extcnf_ctrl); extcnf_ctrl = E1000_READ_REG(hw, EXTCNF_CTRL); - if (extcnf_ctrl & E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP) + if(extcnf_ctrl & E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP) break; else extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP; msec_delay(2); timeout--; - } while (timeout); + } while(timeout); } /* Workaround for ICH8 bit corruption issue in FIFO memory */ @@ -598,7 +568,7 @@ e1000_reset_hw(struct e1000_hw *hw) */ DEBUGOUT("Issuing a global reset to MAC\n"); - switch (hw->mac_type) { + switch(hw->mac_type) { case e1000_82544: case e1000_82540: case e1000_82545: @@ -637,7 +607,7 @@ e1000_reset_hw(struct e1000_hw *hw) * device. Later controllers reload the EEPROM automatically, so just wait * for reload to complete. */ - switch (hw->mac_type) { + switch(hw->mac_type) { case e1000_82542_rev2_0: case e1000_82542_rev2_1: case e1000_82543: @@ -672,7 +642,7 @@ e1000_reset_hw(struct e1000_hw *hw) case e1000_ich8lan: case e1000_80003es2lan: ret_val = e1000_get_auto_rd_done(hw); - if (ret_val) + if(ret_val) /* We don't want to continue accessing MAC registers. */ return ret_val; break; @@ -683,13 +653,13 @@ e1000_reset_hw(struct e1000_hw *hw) } /* Disable HW ARPs on ASF enabled adapters */ - if (hw->mac_type >= e1000_82540 && hw->mac_type <= e1000_82547_rev_2) { + if(hw->mac_type >= e1000_82540 && hw->mac_type <= e1000_82547_rev_2) { manc = E1000_READ_REG(hw, MANC); manc &= ~(E1000_MANC_ARP_EN); E1000_WRITE_REG(hw, MANC, manc); } - if ((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) { + if((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) { e1000_phy_init_script(hw); /* Configure activity LED after PHY reset */ @@ -707,8 +677,8 @@ e1000_reset_hw(struct e1000_hw *hw) icr = E1000_READ_REG(hw, ICR); /* If MWI was previously enabled, reenable it. */ - if (hw->mac_type == e1000_82542_rev2_0) { - if (hw->pci_cmd_word & CMD_MEM_WRT_INVALIDATE) + if(hw->mac_type == e1000_82542_rev2_0) { + if(hw->pci_cmd_word & CMD_MEM_WRT_INVALIDATE) e1000_pci_set_mwi(hw); } @@ -748,20 +718,9 @@ e1000_init_hw(struct e1000_hw *hw) DEBUGFUNC("e1000_init_hw"); - /* force full DMA clock frequency for 10/100 on ICH8 A0-B0 */ - if (hw->mac_type == e1000_ich8lan) { - reg_data = E1000_READ_REG(hw, TARC0); - reg_data |= 0x30000000; - E1000_WRITE_REG(hw, TARC0, reg_data); - - reg_data = E1000_READ_REG(hw, STATUS); - reg_data &= ~0x80000000; - E1000_WRITE_REG(hw, STATUS, reg_data); - } - /* Initialize Identification LED */ ret_val = e1000_id_led_init(hw); - if (ret_val) { + if(ret_val) { DEBUGOUT("Error Initializing Identification LED\n"); return ret_val; } @@ -779,7 +738,7 @@ e1000_init_hw(struct e1000_hw *hw) } /* For 82542 (rev 2.0), disable MWI and put the receiver into reset */ - if (hw->mac_type == e1000_82542_rev2_0) { + if(hw->mac_type == e1000_82542_rev2_0) { DEBUGOUT("Disabling MWI on 82542 rev 2.0\n"); e1000_pci_clear_mwi(hw); E1000_WRITE_REG(hw, RCTL, E1000_RCTL_RST); @@ -793,11 +752,11 @@ e1000_init_hw(struct e1000_hw *hw) e1000_init_rx_addrs(hw); /* For 82542 (rev 2.0), take the receiver out of reset and enable MWI */ - if (hw->mac_type == e1000_82542_rev2_0) { + if(hw->mac_type == e1000_82542_rev2_0) { E1000_WRITE_REG(hw, RCTL, 0); E1000_WRITE_FLUSH(hw); msec_delay(1); - if (hw->pci_cmd_word & CMD_MEM_WRT_INVALIDATE) + if(hw->pci_cmd_word & CMD_MEM_WRT_INVALIDATE) e1000_pci_set_mwi(hw); } @@ -806,7 +765,7 @@ e1000_init_hw(struct e1000_hw *hw) mta_size = E1000_MC_TBL_SIZE; if (hw->mac_type == e1000_ich8lan) mta_size = E1000_MC_TBL_SIZE_ICH8LAN; - for (i = 0; i < mta_size; i++) { + for(i = 0; i < mta_size; i++) { E1000_WRITE_REG_ARRAY(hw, MTA, i, 0); /* use write flush to prevent Memory Write Block (MWB) from * occuring when accessing our register space */ @@ -818,18 +777,18 @@ e1000_init_hw(struct e1000_hw *hw) * gives equal priority to transmits and receives. Valid only on * 82542 and 82543 silicon. */ - if (hw->dma_fairness && hw->mac_type <= e1000_82543) { + if(hw->dma_fairness && hw->mac_type <= e1000_82543) { ctrl = E1000_READ_REG(hw, CTRL); E1000_WRITE_REG(hw, CTRL, ctrl | E1000_CTRL_PRIOR); } - switch (hw->mac_type) { + switch(hw->mac_type) { case e1000_82545_rev_3: case e1000_82546_rev_3: break; default: /* Workaround for PCI-X problem when BIOS sets MMRBC incorrectly. */ - if (hw->bus_type == e1000_bus_type_pcix) { + if(hw->bus_type == e1000_bus_type_pcix) { e1000_read_pci_cfg(hw, PCIX_COMMAND_REGISTER, &pcix_cmd_word); e1000_read_pci_cfg(hw, PCIX_STATUS_REGISTER_HI, &pcix_stat_hi_word); @@ -837,9 +796,9 @@ e1000_init_hw(struct e1000_hw *hw) PCIX_COMMAND_MMRBC_SHIFT; stat_mmrbc = (pcix_stat_hi_word & PCIX_STATUS_HI_MMRBC_MASK) >> PCIX_STATUS_HI_MMRBC_SHIFT; - if (stat_mmrbc == PCIX_STATUS_HI_MMRBC_4K) + if(stat_mmrbc == PCIX_STATUS_HI_MMRBC_4K) stat_mmrbc = PCIX_STATUS_HI_MMRBC_2K; - if (cmd_mmrbc > stat_mmrbc) { + if(cmd_mmrbc > stat_mmrbc) { pcix_cmd_word &= ~PCIX_COMMAND_MMRBC_MASK; pcix_cmd_word |= stat_mmrbc << PCIX_COMMAND_MMRBC_SHIFT; e1000_write_pci_cfg(hw, PCIX_COMMAND_REGISTER, @@ -857,7 +816,7 @@ e1000_init_hw(struct e1000_hw *hw) ret_val = e1000_setup_link(hw); /* Set the transmit descriptor write-back policy */ - if (hw->mac_type > e1000_82544) { + if(hw->mac_type > e1000_82544) { ctrl = E1000_READ_REG(hw, TXDCTL); ctrl = (ctrl & ~E1000_TXDCTL_WTHRESH) | E1000_TXDCTL_FULL_TX_DESC_WB; switch (hw->mac_type) { @@ -908,13 +867,14 @@ e1000_init_hw(struct e1000_hw *hw) case e1000_ich8lan: ctrl = E1000_READ_REG(hw, TXDCTL1); ctrl = (ctrl & ~E1000_TXDCTL_WTHRESH) | E1000_TXDCTL_FULL_TX_DESC_WB; - if (hw->mac_type >= e1000_82571) + if(hw->mac_type >= e1000_82571) ctrl |= E1000_TXDCTL_COUNT_DESC; E1000_WRITE_REG(hw, TXDCTL1, ctrl); break; } + if (hw->mac_type == e1000_82573) { uint32_t gcr = E1000_READ_REG(hw, GCR); gcr |= E1000_GCR_L1_ACT_WITHOUT_L0S_RX; @@ -958,10 +918,10 @@ e1000_adjust_serdes_amplitude(struct e1000_hw *hw) DEBUGFUNC("e1000_adjust_serdes_amplitude"); - if (hw->media_type != e1000_media_type_internal_serdes) + if(hw->media_type != e1000_media_type_internal_serdes) return E1000_SUCCESS; - switch (hw->mac_type) { + switch(hw->mac_type) { case e1000_82545_rev_3: case e1000_82546_rev_3: break; @@ -974,11 +934,11 @@ e1000_adjust_serdes_amplitude(struct e1000_hw *hw) return ret_val; } - if (eeprom_data != EEPROM_RESERVED_WORD) { + if(eeprom_data != EEPROM_RESERVED_WORD) { /* Adjust SERDES output amplitude only. */ eeprom_data &= EEPROM_SERDES_AMPLITUDE_MASK; ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_EXT_CTRL, eeprom_data); - if (ret_val) + if(ret_val) return ret_val; } @@ -1046,10 +1006,10 @@ e1000_setup_link(struct e1000_hw *hw) * in case we get disconnected and then reconnected into a different * hub or switch with different Flow Control capabilities. */ - if (hw->mac_type == e1000_82542_rev2_0) + if(hw->mac_type == e1000_82542_rev2_0) hw->fc &= (~e1000_fc_tx_pause); - if ((hw->mac_type < e1000_82543) && (hw->report_tx_early == 1)) + if((hw->mac_type < e1000_82543) && (hw->report_tx_early == 1)) hw->fc &= (~e1000_fc_rx_pause); hw->original_fc = hw->fc; @@ -1064,12 +1024,12 @@ e1000_setup_link(struct e1000_hw *hw) * or e1000_phy_setup() is called. */ if (hw->mac_type == e1000_82543) { - ret_val = e1000_read_eeprom(hw, EEPROM_INIT_CONTROL2_REG, - 1, &eeprom_data); - if (ret_val) { - DEBUGOUT("EEPROM Read Error\n"); - return -E1000_ERR_EEPROM; - } + ret_val = e1000_read_eeprom(hw, EEPROM_INIT_CONTROL2_REG, + 1, &eeprom_data); + if (ret_val) { + DEBUGOUT("EEPROM Read Error\n"); + return -E1000_ERR_EEPROM; + } ctrl_ext = ((eeprom_data & EEPROM_WORD0F_SWPDIO_EXT) << SWDPIO__EXT_SHIFT); E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext); @@ -1102,14 +1062,14 @@ e1000_setup_link(struct e1000_hw *hw) * ability to transmit pause frames in not enabled, then these * registers will be set to 0. */ - if (!(hw->fc & e1000_fc_tx_pause)) { + if(!(hw->fc & e1000_fc_tx_pause)) { E1000_WRITE_REG(hw, FCRTL, 0); E1000_WRITE_REG(hw, FCRTH, 0); } else { /* We need to set up the Receive Threshold high and low water marks * as well as (optionally) enabling the transmission of XON frames. */ - if (hw->fc_send_xon) { + if(hw->fc_send_xon) { E1000_WRITE_REG(hw, FCRTL, (hw->fc_low_water | E1000_FCRTL_XONE)); E1000_WRITE_REG(hw, FCRTH, hw->fc_high_water); } else { @@ -1156,11 +1116,11 @@ e1000_setup_fiber_serdes_link(struct e1000_hw *hw) * the EEPROM. */ ctrl = E1000_READ_REG(hw, CTRL); - if (hw->media_type == e1000_media_type_fiber) + if(hw->media_type == e1000_media_type_fiber) signal = (hw->mac_type > e1000_82544) ? E1000_CTRL_SWDPIN1 : 0; ret_val = e1000_adjust_serdes_amplitude(hw); - if (ret_val) + if(ret_val) return ret_val; /* Take the link out of reset */ @@ -1168,7 +1128,7 @@ e1000_setup_fiber_serdes_link(struct e1000_hw *hw) /* Adjust VCO speed to improve BER performance */ ret_val = e1000_set_vco_speed(hw); - if (ret_val) + if(ret_val) return ret_val; e1000_config_collision_dist(hw); @@ -1239,15 +1199,15 @@ e1000_setup_fiber_serdes_link(struct e1000_hw *hw) * less than 500 milliseconds even if the other end is doing it in SW). * For internal serdes, we just assume a signal is present, then poll. */ - if (hw->media_type == e1000_media_type_internal_serdes || + if(hw->media_type == e1000_media_type_internal_serdes || (E1000_READ_REG(hw, CTRL) & E1000_CTRL_SWDPIN1) == signal) { DEBUGOUT("Looking for Link\n"); - for (i = 0; i < (LINK_UP_TIMEOUT / 10); i++) { + for(i = 0; i < (LINK_UP_TIMEOUT / 10); i++) { msec_delay(10); status = E1000_READ_REG(hw, STATUS); - if (status & E1000_STATUS_LU) break; + if(status & E1000_STATUS_LU) break; } - if (i == (LINK_UP_TIMEOUT / 10)) { + if(i == (LINK_UP_TIMEOUT / 10)) { DEBUGOUT("Never got a valid link from auto-neg!!!\n"); hw->autoneg_failed = 1; /* AutoNeg failed to achieve a link, so we'll call @@ -1256,7 +1216,7 @@ e1000_setup_fiber_serdes_link(struct e1000_hw *hw) * non-autonegotiating link partners. */ ret_val = e1000_check_for_link(hw); - if (ret_val) { + if(ret_val) { DEBUGOUT("Error while checking for link\n"); return ret_val; } @@ -1290,7 +1250,7 @@ e1000_copper_link_preconfig(struct e1000_hw *hw) * the PHY speed and duplex configuration is. In addition, we need to * perform a hardware reset on the PHY to take it out of reset. */ - if (hw->mac_type > e1000_82543) { + if(hw->mac_type > e1000_82543) { ctrl |= E1000_CTRL_SLU; ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX); E1000_WRITE_REG(hw, CTRL, ctrl); @@ -1298,13 +1258,13 @@ e1000_copper_link_preconfig(struct e1000_hw *hw) ctrl |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX | E1000_CTRL_SLU); E1000_WRITE_REG(hw, CTRL, ctrl); ret_val = e1000_phy_hw_reset(hw); - if (ret_val) + if(ret_val) return ret_val; } /* Make sure we have a valid PHY */ ret_val = e1000_detect_gig_phy(hw); - if (ret_val) { + if(ret_val) { DEBUGOUT("Error, did not detect valid phy.\n"); return ret_val; } @@ -1312,19 +1272,19 @@ e1000_copper_link_preconfig(struct e1000_hw *hw) /* Set PHY to class A mode (if necessary) */ ret_val = e1000_set_phy_mode(hw); - if (ret_val) + if(ret_val) return ret_val; - if ((hw->mac_type == e1000_82545_rev_3) || + if((hw->mac_type == e1000_82545_rev_3) || (hw->mac_type == e1000_82546_rev_3)) { ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data); phy_data |= 0x00000008; ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data); } - if (hw->mac_type <= e1000_82543 || - hw->mac_type == e1000_82541 || hw->mac_type == e1000_82547 || - hw->mac_type == e1000_82541_rev_2 || hw->mac_type == e1000_82547_rev_2) + if(hw->mac_type <= e1000_82543 || + hw->mac_type == e1000_82541 || hw->mac_type == e1000_82547 || + hw->mac_type == e1000_82541_rev_2 || hw->mac_type == e1000_82547_rev_2) hw->phy_reset_disable = FALSE; return E1000_SUCCESS; @@ -1354,7 +1314,7 @@ e1000_copper_link_igp_setup(struct e1000_hw *hw) return ret_val; } - /* Wait 15ms for MAC to configure PHY from eeprom settings */ + /* Wait 10ms for MAC to configure PHY from eeprom settings */ msec_delay(15); if (hw->mac_type != e1000_ich8lan) { /* Configure activity LED after PHY reset */ @@ -1364,14 +1324,11 @@ e1000_copper_link_igp_setup(struct e1000_hw *hw) E1000_WRITE_REG(hw, LEDCTL, led_ctrl); } - /* The NVM settings will configure LPLU in D3 for IGP2 and IGP3 PHYs */ - if (hw->phy_type == e1000_phy_igp) { - /* disable lplu d3 during driver init */ - ret_val = e1000_set_d3_lplu_state(hw, FALSE); - if (ret_val) { - DEBUGOUT("Error Disabling LPLU D3\n"); - return ret_val; - } + /* disable lplu d3 during driver init */ + ret_val = e1000_set_d3_lplu_state(hw, FALSE); + if (ret_val) { + DEBUGOUT("Error Disabling LPLU D3\n"); + return ret_val; } /* disable lplu d0 during driver init */ @@ -1409,45 +1366,45 @@ e1000_copper_link_igp_setup(struct e1000_hw *hw) } } ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, phy_data); - if (ret_val) + if(ret_val) return ret_val; /* set auto-master slave resolution settings */ - if (hw->autoneg) { + if(hw->autoneg) { e1000_ms_type phy_ms_setting = hw->master_slave; - if (hw->ffe_config_state == e1000_ffe_config_active) + if(hw->ffe_config_state == e1000_ffe_config_active) hw->ffe_config_state = e1000_ffe_config_enabled; - if (hw->dsp_config_state == e1000_dsp_config_activated) + if(hw->dsp_config_state == e1000_dsp_config_activated) hw->dsp_config_state = e1000_dsp_config_enabled; /* when autonegotiation advertisment is only 1000Mbps then we * should disable SmartSpeed and enable Auto MasterSlave * resolution as hardware default. */ - if (hw->autoneg_advertised == ADVERTISE_1000_FULL) { + if(hw->autoneg_advertised == ADVERTISE_1000_FULL) { /* Disable SmartSpeed */ - ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, - &phy_data); - if (ret_val) + ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, &phy_data); + if(ret_val) return ret_val; phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED; - ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, - phy_data); - if (ret_val) + ret_val = e1000_write_phy_reg(hw, + IGP01E1000_PHY_PORT_CONFIG, + phy_data); + if(ret_val) return ret_val; /* Set auto Master/Slave resolution process */ ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_data); - if (ret_val) + if(ret_val) return ret_val; phy_data &= ~CR_1000T_MS_ENABLE; ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL, phy_data); - if (ret_val) + if(ret_val) return ret_val; } ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_data); - if (ret_val) + if(ret_val) return ret_val; /* load defaults for future use */ @@ -1471,7 +1428,7 @@ e1000_copper_link_igp_setup(struct e1000_hw *hw) break; } ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL, phy_data); - if (ret_val) + if(ret_val) return ret_val; } @@ -1492,12 +1449,12 @@ e1000_copper_link_ggp_setup(struct e1000_hw *hw) DEBUGFUNC("e1000_copper_link_ggp_setup"); - if (!hw->phy_reset_disable) { + if(!hw->phy_reset_disable) { /* Enable CRS on TX for half-duplex operation. */ ret_val = e1000_read_phy_reg(hw, GG82563_PHY_MAC_SPEC_CTRL, &phy_data); - if (ret_val) + if(ret_val) return ret_val; phy_data |= GG82563_MSCR_ASSERT_CRS_ON_TX; @@ -1506,7 +1463,7 @@ e1000_copper_link_ggp_setup(struct e1000_hw *hw) ret_val = e1000_write_phy_reg(hw, GG82563_PHY_MAC_SPEC_CTRL, phy_data); - if (ret_val) + if(ret_val) return ret_val; /* Options: @@ -1517,7 +1474,7 @@ e1000_copper_link_ggp_setup(struct e1000_hw *hw) * 3 - Auto for 1000Base-T only (MDI-X for 10/100Base-T modes) */ ret_val = e1000_read_phy_reg(hw, GG82563_PHY_SPEC_CTRL, &phy_data); - if (ret_val) + if(ret_val) return ret_val; phy_data &= ~GG82563_PSCR_CROSSOVER_MODE_MASK; @@ -1542,11 +1499,11 @@ e1000_copper_link_ggp_setup(struct e1000_hw *hw) * 1 - Enabled */ phy_data &= ~GG82563_PSCR_POLARITY_REVERSAL_DISABLE; - if (hw->disable_polarity_correction == 1) + if(hw->disable_polarity_correction == 1) phy_data |= GG82563_PSCR_POLARITY_REVERSAL_DISABLE; ret_val = e1000_write_phy_reg(hw, GG82563_PHY_SPEC_CTRL, phy_data); - if (ret_val) + if(ret_val) return ret_val; /* SW Reset the PHY so all changes take effect */ @@ -1602,9 +1559,9 @@ e1000_copper_link_ggp_setup(struct e1000_hw *hw) return ret_val; phy_data &= ~GG82563_KMCR_PASS_FALSE_CARRIER; + ret_val = e1000_write_phy_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, phy_data); - if (ret_val) return ret_val; } @@ -1639,12 +1596,12 @@ e1000_copper_link_mgp_setup(struct e1000_hw *hw) DEBUGFUNC("e1000_copper_link_mgp_setup"); - if (hw->phy_reset_disable) + if(hw->phy_reset_disable) return E1000_SUCCESS; /* Enable CRS on TX. This must be set for half-duplex operation. */ ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data); - if (ret_val) + if(ret_val) return ret_val; phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX; @@ -1681,7 +1638,7 @@ e1000_copper_link_mgp_setup(struct e1000_hw *hw) * 1 - Enabled */ phy_data &= ~M88E1000_PSCR_POLARITY_REVERSAL; - if (hw->disable_polarity_correction == 1) + if(hw->disable_polarity_correction == 1) phy_data |= M88E1000_PSCR_POLARITY_REVERSAL; ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data); if (ret_val) @@ -1721,7 +1678,7 @@ e1000_copper_link_mgp_setup(struct e1000_hw *hw) /* SW Reset the PHY so all changes take effect */ ret_val = e1000_phy_reset(hw); - if (ret_val) { + if(ret_val) { DEBUGOUT("Error Resetting the PHY\n"); return ret_val; } @@ -1751,7 +1708,7 @@ e1000_copper_link_autoneg(struct e1000_hw *hw) /* If autoneg_advertised is zero, we assume it was not defaulted * by the calling code so we set to advertise full capability. */ - if (hw->autoneg_advertised == 0) + if(hw->autoneg_advertised == 0) hw->autoneg_advertised = AUTONEG_ADVERTISE_SPEED_DEFAULT; /* IFE phy only supports 10/100 */ @@ -1760,7 +1717,7 @@ e1000_copper_link_autoneg(struct e1000_hw *hw) DEBUGOUT("Reconfiguring auto-neg advertisement params\n"); ret_val = e1000_phy_setup_autoneg(hw); - if (ret_val) { + if(ret_val) { DEBUGOUT("Error Setting up Auto-Negotiation\n"); return ret_val; } @@ -1770,20 +1727,20 @@ e1000_copper_link_autoneg(struct e1000_hw *hw) * the Auto Neg Restart bit in the PHY control register. */ ret_val = e1000_read_phy_reg(hw, PHY_CTRL, &phy_data); - if (ret_val) + if(ret_val) return ret_val; phy_data |= (MII_CR_AUTO_NEG_EN | MII_CR_RESTART_AUTO_NEG); ret_val = e1000_write_phy_reg(hw, PHY_CTRL, phy_data); - if (ret_val) + if(ret_val) return ret_val; /* Does the user want to wait for Auto-Neg to complete here, or * check at a later time (for example, callback routine). */ - if (hw->wait_autoneg_complete) { + if(hw->wait_autoneg_complete) { ret_val = e1000_wait_autoneg(hw); - if (ret_val) { + if(ret_val) { DEBUGOUT("Error while waiting for autoneg to complete\n"); return ret_val; } @@ -1794,6 +1751,7 @@ e1000_copper_link_autoneg(struct e1000_hw *hw) return E1000_SUCCESS; } + /****************************************************************************** * Config the MAC and the PHY after link is up. * 1) Set up the MAC to the current PHY speed/duplex @@ -1812,25 +1770,25 @@ e1000_copper_link_postconfig(struct e1000_hw *hw) int32_t ret_val; DEBUGFUNC("e1000_copper_link_postconfig"); - if (hw->mac_type >= e1000_82544) { + if(hw->mac_type >= e1000_82544) { e1000_config_collision_dist(hw); } else { ret_val = e1000_config_mac_to_phy(hw); - if (ret_val) { + if(ret_val) { DEBUGOUT("Error configuring MAC to PHY settings\n"); return ret_val; } } ret_val = e1000_config_fc_after_link_up(hw); - if (ret_val) { + if(ret_val) { DEBUGOUT("Error Configuring Flow Control\n"); return ret_val; } /* Config DSP to improve Giga link quality */ - if (hw->phy_type == e1000_phy_igp) { + if(hw->phy_type == e1000_phy_igp) { ret_val = e1000_config_dsp_after_link_change(hw, TRUE); - if (ret_val) { + if(ret_val) { DEBUGOUT("Error Configuring DSP after link up\n"); return ret_val; } @@ -1876,7 +1834,7 @@ e1000_setup_copper_link(struct e1000_hw *hw) /* Check if it is a valid PHY and set PHY mode if necessary. */ ret_val = e1000_copper_link_preconfig(hw); - if (ret_val) + if(ret_val) return ret_val; switch (hw->mac_type) { @@ -1897,30 +1855,30 @@ e1000_setup_copper_link(struct e1000_hw *hw) hw->phy_type == e1000_phy_igp_3 || hw->phy_type == e1000_phy_igp_2) { ret_val = e1000_copper_link_igp_setup(hw); - if (ret_val) + if(ret_val) return ret_val; } else if (hw->phy_type == e1000_phy_m88) { ret_val = e1000_copper_link_mgp_setup(hw); - if (ret_val) + if(ret_val) return ret_val; } else if (hw->phy_type == e1000_phy_gg82563) { ret_val = e1000_copper_link_ggp_setup(hw); - if (ret_val) + if(ret_val) return ret_val; } - if (hw->autoneg) { + if(hw->autoneg) { /* Setup autoneg and flow control advertisement * and perform autonegotiation */ ret_val = e1000_copper_link_autoneg(hw); - if (ret_val) + if(ret_val) return ret_val; } else { /* PHY will be set to 10H, 10F, 100H,or 100F * depending on value from forced_speed_duplex. */ DEBUGOUT("Forcing speed and duplex\n"); ret_val = e1000_phy_force_speed_duplex(hw); - if (ret_val) { + if(ret_val) { DEBUGOUT("Error Forcing Speed and Duplex\n"); return ret_val; } @@ -1929,18 +1887,18 @@ e1000_setup_copper_link(struct e1000_hw *hw) /* Check link status. Wait up to 100 microseconds for link to become * valid. */ - for (i = 0; i < 10; i++) { + for(i = 0; i < 10; i++) { ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data); - if (ret_val) + if(ret_val) return ret_val; ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data); - if (ret_val) + if(ret_val) return ret_val; - if (phy_data & MII_SR_LINK_STATUS) { + if(phy_data & MII_SR_LINK_STATUS) { /* Config the MAC and PHY after link is up */ ret_val = e1000_copper_link_postconfig(hw); - if (ret_val) + if(ret_val) return ret_val; DEBUGOUT("Valid link established!!!\n"); @@ -2042,7 +2000,7 @@ e1000_phy_setup_autoneg(struct e1000_hw *hw) /* Read the MII Auto-Neg Advertisement Register (Address 4). */ ret_val = e1000_read_phy_reg(hw, PHY_AUTONEG_ADV, &mii_autoneg_adv_reg); - if (ret_val) + if(ret_val) return ret_val; if (hw->phy_type != e1000_phy_ife) { @@ -2070,36 +2028,36 @@ e1000_phy_setup_autoneg(struct e1000_hw *hw) DEBUGOUT1("autoneg_advertised %x\n", hw->autoneg_advertised); /* Do we want to advertise 10 Mb Half Duplex? */ - if (hw->autoneg_advertised & ADVERTISE_10_HALF) { + if(hw->autoneg_advertised & ADVERTISE_10_HALF) { DEBUGOUT("Advertise 10mb Half duplex\n"); mii_autoneg_adv_reg |= NWAY_AR_10T_HD_CAPS; } /* Do we want to advertise 10 Mb Full Duplex? */ - if (hw->autoneg_advertised & ADVERTISE_10_FULL) { + if(hw->autoneg_advertised & ADVERTISE_10_FULL) { DEBUGOUT("Advertise 10mb Full duplex\n"); mii_autoneg_adv_reg |= NWAY_AR_10T_FD_CAPS; } /* Do we want to advertise 100 Mb Half Duplex? */ - if (hw->autoneg_advertised & ADVERTISE_100_HALF) { + if(hw->autoneg_advertised & ADVERTISE_100_HALF) { DEBUGOUT("Advertise 100mb Half duplex\n"); mii_autoneg_adv_reg |= NWAY_AR_100TX_HD_CAPS; } /* Do we want to advertise 100 Mb Full Duplex? */ - if (hw->autoneg_advertised & ADVERTISE_100_FULL) { + if(hw->autoneg_advertised & ADVERTISE_100_FULL) { DEBUGOUT("Advertise 100mb Full duplex\n"); mii_autoneg_adv_reg |= NWAY_AR_100TX_FD_CAPS; } /* We do not allow the Phy to advertise 1000 Mb Half Duplex */ - if (hw->autoneg_advertised & ADVERTISE_1000_HALF) { + if(hw->autoneg_advertised & ADVERTISE_1000_HALF) { DEBUGOUT("Advertise 1000mb Half duplex requested, request denied!\n"); } /* Do we want to advertise 1000 Mb Full Duplex? */ - if (hw->autoneg_advertised & ADVERTISE_1000_FULL) { + if(hw->autoneg_advertised & ADVERTISE_1000_FULL) { DEBUGOUT("Advertise 1000mb Full duplex\n"); mii_1000t_ctrl_reg |= CR_1000T_FD_CAPS; if (hw->phy_type == e1000_phy_ife) { @@ -2161,7 +2119,7 @@ e1000_phy_setup_autoneg(struct e1000_hw *hw) } ret_val = e1000_write_phy_reg(hw, PHY_AUTONEG_ADV, mii_autoneg_adv_reg); - if (ret_val) + if(ret_val) return ret_val; DEBUGOUT1("Auto-Neg Advertising %x\n", mii_autoneg_adv_reg); @@ -2209,7 +2167,7 @@ e1000_phy_force_speed_duplex(struct e1000_hw *hw) /* Read the MII Control Register. */ ret_val = e1000_read_phy_reg(hw, PHY_CTRL, &mii_ctrl_reg); - if (ret_val) + if(ret_val) return ret_val; /* We need to disable autoneg in order to force link and duplex. */ @@ -2217,8 +2175,8 @@ e1000_phy_force_speed_duplex(struct e1000_hw *hw) mii_ctrl_reg &= ~MII_CR_AUTO_NEG_EN; /* Are we forcing Full or Half Duplex? */ - if (hw->forced_speed_duplex == e1000_100_full || - hw->forced_speed_duplex == e1000_10_full) { + if(hw->forced_speed_duplex == e1000_100_full || + hw->forced_speed_duplex == e1000_10_full) { /* We want to force full duplex so we SET the full duplex bits in the * Device and MII Control Registers. */ @@ -2235,7 +2193,7 @@ e1000_phy_force_speed_duplex(struct e1000_hw *hw) } /* Are we forcing 100Mbps??? */ - if (hw->forced_speed_duplex == e1000_100_full || + if(hw->forced_speed_duplex == e1000_100_full || hw->forced_speed_duplex == e1000_100_half) { /* Set the 100Mb bit and turn off the 1000Mb and 10Mb bits. */ ctrl |= E1000_CTRL_SPD_100; @@ -2258,7 +2216,7 @@ e1000_phy_force_speed_duplex(struct e1000_hw *hw) if ((hw->phy_type == e1000_phy_m88) || (hw->phy_type == e1000_phy_gg82563)) { ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data); - if (ret_val) + if(ret_val) return ret_val; /* Clear Auto-Crossover to force MDI manually. M88E1000 requires MDI @@ -2266,7 +2224,7 @@ e1000_phy_force_speed_duplex(struct e1000_hw *hw) */ phy_data &= ~M88E1000_PSCR_AUTO_X_MODE; ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data); - if (ret_val) + if(ret_val) return ret_val; DEBUGOUT1("M88E1000 PSCR: %x \n", phy_data); @@ -2290,20 +2248,20 @@ e1000_phy_force_speed_duplex(struct e1000_hw *hw) * forced whenever speed or duplex are forced. */ ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, &phy_data); - if (ret_val) + if(ret_val) return ret_val; phy_data &= ~IGP01E1000_PSCR_AUTO_MDIX; phy_data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX; ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, phy_data); - if (ret_val) + if(ret_val) return ret_val; } /* Write back the modified PHY MII control register. */ ret_val = e1000_write_phy_reg(hw, PHY_CTRL, mii_ctrl_reg); - if (ret_val) + if(ret_val) return ret_val; udelay(1); @@ -2315,50 +2273,50 @@ e1000_phy_force_speed_duplex(struct e1000_hw *hw) * only if the user has set wait_autoneg_complete to 1, which is * the default. */ - if (hw->wait_autoneg_complete) { + if(hw->wait_autoneg_complete) { /* We will wait for autoneg to complete. */ DEBUGOUT("Waiting for forced speed/duplex link.\n"); mii_status_reg = 0; /* We will wait for autoneg to complete or 4.5 seconds to expire. */ - for (i = PHY_FORCE_TIME; i > 0; i--) { + for(i = PHY_FORCE_TIME; i > 0; i--) { /* Read the MII Status Register and wait for Auto-Neg Complete bit * to be set. */ ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg); - if (ret_val) + if(ret_val) return ret_val; ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg); - if (ret_val) + if(ret_val) return ret_val; - if (mii_status_reg & MII_SR_LINK_STATUS) break; + if(mii_status_reg & MII_SR_LINK_STATUS) break; msec_delay(100); } - if ((i == 0) && + if((i == 0) && ((hw->phy_type == e1000_phy_m88) || (hw->phy_type == e1000_phy_gg82563))) { /* We didn't get link. Reset the DSP and wait again for link. */ ret_val = e1000_phy_reset_dsp(hw); - if (ret_val) { + if(ret_val) { DEBUGOUT("Error Resetting PHY DSP\n"); return ret_val; } } /* This loop will early-out if the link condition has been met. */ - for (i = PHY_FORCE_TIME; i > 0; i--) { - if (mii_status_reg & MII_SR_LINK_STATUS) break; + for(i = PHY_FORCE_TIME; i > 0; i--) { + if(mii_status_reg & MII_SR_LINK_STATUS) break; msec_delay(100); /* Read the MII Status Register and wait for Auto-Neg Complete bit * to be set. */ ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg); - if (ret_val) + if(ret_val) return ret_val; ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg); - if (ret_val) + if(ret_val) return ret_val; } } @@ -2369,31 +2327,32 @@ e1000_phy_force_speed_duplex(struct e1000_hw *hw) * defaults back to a 2.5MHz clock when the PHY is reset. */ ret_val = e1000_read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data); - if (ret_val) + if(ret_val) return ret_val; phy_data |= M88E1000_EPSCR_TX_CLK_25; ret_val = e1000_write_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, phy_data); - if (ret_val) + if(ret_val) return ret_val; /* In addition, because of the s/w reset above, we need to enable CRS on * TX. This must be set for both full and half duplex operation. */ ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data); - if (ret_val) + if(ret_val) return ret_val; phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX; ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data); - if (ret_val) + if(ret_val) return ret_val; - if ((hw->mac_type == e1000_82544 || hw->mac_type == e1000_82543) && - (!hw->autoneg) && (hw->forced_speed_duplex == e1000_10_full || - hw->forced_speed_duplex == e1000_10_half)) { + if((hw->mac_type == e1000_82544 || hw->mac_type == e1000_82543) && + (!hw->autoneg) && + (hw->forced_speed_duplex == e1000_10_full || + hw->forced_speed_duplex == e1000_10_half)) { ret_val = e1000_polarity_reversal_workaround(hw); - if (ret_val) + if(ret_val) return ret_val; } } else if (hw->phy_type == e1000_phy_gg82563) { @@ -2484,10 +2443,10 @@ e1000_config_mac_to_phy(struct e1000_hw *hw) * registers depending on negotiated values. */ ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data); - if (ret_val) + if(ret_val) return ret_val; - if (phy_data & M88E1000_PSSR_DPLX) + if(phy_data & M88E1000_PSSR_DPLX) ctrl |= E1000_CTRL_FD; else ctrl &= ~E1000_CTRL_FD; @@ -2497,9 +2456,9 @@ e1000_config_mac_to_phy(struct e1000_hw *hw) /* Set up speed in the Device Control register depending on * negotiated values. */ - if ((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_1000MBS) + if((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_1000MBS) ctrl |= E1000_CTRL_SPD_1000; - else if ((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_100MBS) + else if((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_100MBS) ctrl |= E1000_CTRL_SPD_100; /* Write the configured values back to the Device Control Reg. */ @@ -2567,7 +2526,7 @@ e1000_force_mac_fc(struct e1000_hw *hw) } /* Disable TX Flow Control for 82542 (rev 2.0) */ - if (hw->mac_type == e1000_82542_rev2_0) + if(hw->mac_type == e1000_82542_rev2_0) ctrl &= (~E1000_CTRL_TFCE); E1000_WRITE_REG(hw, CTRL, ctrl); @@ -2601,12 +2560,11 @@ e1000_config_fc_after_link_up(struct e1000_hw *hw) * so we had to force link. In this case, we need to force the * configuration of the MAC to match the "fc" parameter. */ - if (((hw->media_type == e1000_media_type_fiber) && (hw->autoneg_failed)) || - ((hw->media_type == e1000_media_type_internal_serdes) && - (hw->autoneg_failed)) || - ((hw->media_type == e1000_media_type_copper) && (!hw->autoneg))) { + if(((hw->media_type == e1000_media_type_fiber) && (hw->autoneg_failed)) || + ((hw->media_type == e1000_media_type_internal_serdes) && (hw->autoneg_failed)) || + ((hw->media_type == e1000_media_type_copper) && (!hw->autoneg))) { ret_val = e1000_force_mac_fc(hw); - if (ret_val) { + if(ret_val) { DEBUGOUT("Error forcing flow control settings\n"); return ret_val; } @@ -2617,19 +2575,19 @@ e1000_config_fc_after_link_up(struct e1000_hw *hw) * has completed, and if so, how the PHY and link partner has * flow control configured. */ - if ((hw->media_type == e1000_media_type_copper) && hw->autoneg) { + if((hw->media_type == e1000_media_type_copper) && hw->autoneg) { /* Read the MII Status Register and check to see if AutoNeg * has completed. We read this twice because this reg has * some "sticky" (latched) bits. */ ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg); - if (ret_val) + if(ret_val) return ret_val; ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg); - if (ret_val) + if(ret_val) return ret_val; - if (mii_status_reg & MII_SR_AUTONEG_COMPLETE) { + if(mii_status_reg & MII_SR_AUTONEG_COMPLETE) { /* The AutoNeg process has completed, so we now need to * read both the Auto Negotiation Advertisement Register * (Address 4) and the Auto_Negotiation Base Page Ability @@ -2638,11 +2596,11 @@ e1000_config_fc_after_link_up(struct e1000_hw *hw) */ ret_val = e1000_read_phy_reg(hw, PHY_AUTONEG_ADV, &mii_nway_adv_reg); - if (ret_val) + if(ret_val) return ret_val; ret_val = e1000_read_phy_reg(hw, PHY_LP_ABILITY, &mii_nway_lp_ability_reg); - if (ret_val) + if(ret_val) return ret_val; /* Two bits in the Auto Negotiation Advertisement Register @@ -2679,15 +2637,15 @@ e1000_config_fc_after_link_up(struct e1000_hw *hw) * 1 | DC | 1 | DC | e1000_fc_full * */ - if ((mii_nway_adv_reg & NWAY_AR_PAUSE) && - (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE)) { + if((mii_nway_adv_reg & NWAY_AR_PAUSE) && + (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE)) { /* Now we need to check if the user selected RX ONLY * of pause frames. In this case, we had to advertise * FULL flow control because we could not advertise RX * ONLY. Hence, we must now check to see if we need to * turn OFF the TRANSMISSION of PAUSE frames. */ - if (hw->original_fc == e1000_fc_full) { + if(hw->original_fc == e1000_fc_full) { hw->fc = e1000_fc_full; DEBUGOUT("Flow Control = FULL.\n"); } else { @@ -2703,10 +2661,10 @@ e1000_config_fc_after_link_up(struct e1000_hw *hw) * 0 | 1 | 1 | 1 | e1000_fc_tx_pause * */ - else if (!(mii_nway_adv_reg & NWAY_AR_PAUSE) && - (mii_nway_adv_reg & NWAY_AR_ASM_DIR) && - (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) && - (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) { + else if(!(mii_nway_adv_reg & NWAY_AR_PAUSE) && + (mii_nway_adv_reg & NWAY_AR_ASM_DIR) && + (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) && + (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) { hw->fc = e1000_fc_tx_pause; DEBUGOUT("Flow Control = TX PAUSE frames only.\n"); } @@ -2718,10 +2676,10 @@ e1000_config_fc_after_link_up(struct e1000_hw *hw) * 1 | 1 | 0 | 1 | e1000_fc_rx_pause * */ - else if ((mii_nway_adv_reg & NWAY_AR_PAUSE) && - (mii_nway_adv_reg & NWAY_AR_ASM_DIR) && - !(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) && - (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) { + else if((mii_nway_adv_reg & NWAY_AR_PAUSE) && + (mii_nway_adv_reg & NWAY_AR_ASM_DIR) && + !(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) && + (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) { hw->fc = e1000_fc_rx_pause; DEBUGOUT("Flow Control = RX PAUSE frames only.\n"); } @@ -2745,9 +2703,9 @@ e1000_config_fc_after_link_up(struct e1000_hw *hw) * be asked to delay transmission of packets than asking * our link partner to pause transmission of frames. */ - else if ((hw->original_fc == e1000_fc_none || - hw->original_fc == e1000_fc_tx_pause) || - hw->fc_strict_ieee) { + else if((hw->original_fc == e1000_fc_none || + hw->original_fc == e1000_fc_tx_pause) || + hw->fc_strict_ieee) { hw->fc = e1000_fc_none; DEBUGOUT("Flow Control = NONE.\n"); } else { @@ -2760,19 +2718,19 @@ e1000_config_fc_after_link_up(struct e1000_hw *hw) * enabled per IEEE 802.3 spec. */ ret_val = e1000_get_speed_and_duplex(hw, &speed, &duplex); - if (ret_val) { + if(ret_val) { DEBUGOUT("Error getting link speed and duplex\n"); return ret_val; } - if (duplex == HALF_DUPLEX) + if(duplex == HALF_DUPLEX) hw->fc = e1000_fc_none; /* Now we call a subroutine to actually force the MAC * controller to use the correct flow control settings. */ ret_val = e1000_force_mac_fc(hw); - if (ret_val) { + if(ret_val) { DEBUGOUT("Error forcing flow control settings\n"); return ret_val; } @@ -2811,13 +2769,13 @@ e1000_check_for_link(struct e1000_hw *hw) * set when the optics detect a signal. On older adapters, it will be * cleared when there is a signal. This applies to fiber media only. */ - if ((hw->media_type == e1000_media_type_fiber) || - (hw->media_type == e1000_media_type_internal_serdes)) { + if((hw->media_type == e1000_media_type_fiber) || + (hw->media_type == e1000_media_type_internal_serdes)) { rxcw = E1000_READ_REG(hw, RXCW); - if (hw->media_type == e1000_media_type_fiber) { + if(hw->media_type == e1000_media_type_fiber) { signal = (hw->mac_type > e1000_82544) ? E1000_CTRL_SWDPIN1 : 0; - if (status & E1000_STATUS_LU) + if(status & E1000_STATUS_LU) hw->get_link_status = FALSE; } } @@ -2828,20 +2786,20 @@ e1000_check_for_link(struct e1000_hw *hw) * receive a Link Status Change interrupt or we have Rx Sequence * Errors. */ - if ((hw->media_type == e1000_media_type_copper) && hw->get_link_status) { + if((hw->media_type == e1000_media_type_copper) && hw->get_link_status) { /* First we want to see if the MII Status Register reports * link. If so, then we want to get the current speed/duplex * of the PHY. * Read the register twice since the link bit is sticky. */ ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data); - if (ret_val) + if(ret_val) return ret_val; ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data); - if (ret_val) + if(ret_val) return ret_val; - if (phy_data & MII_SR_LINK_STATUS) { + if(phy_data & MII_SR_LINK_STATUS) { hw->get_link_status = FALSE; /* Check if there was DownShift, must be checked immediately after * link-up */ @@ -2855,10 +2813,10 @@ e1000_check_for_link(struct e1000_hw *hw) * happen due to the execution of this workaround. */ - if ((hw->mac_type == e1000_82544 || hw->mac_type == e1000_82543) && - (!hw->autoneg) && - (hw->forced_speed_duplex == e1000_10_full || - hw->forced_speed_duplex == e1000_10_half)) { + if((hw->mac_type == e1000_82544 || hw->mac_type == e1000_82543) && + (!hw->autoneg) && + (hw->forced_speed_duplex == e1000_10_full || + hw->forced_speed_duplex == e1000_10_half)) { E1000_WRITE_REG(hw, IMC, 0xffffffff); ret_val = e1000_polarity_reversal_workaround(hw); icr = E1000_READ_REG(hw, ICR); @@ -2875,7 +2833,7 @@ e1000_check_for_link(struct e1000_hw *hw) /* If we are forcing speed/duplex, then we simply return since * we have already determined whether we have link or not. */ - if (!hw->autoneg) return -E1000_ERR_CONFIG; + if(!hw->autoneg) return -E1000_ERR_CONFIG; /* optimize the dsp settings for the igp phy */ e1000_config_dsp_after_link_change(hw, TRUE); @@ -2888,11 +2846,11 @@ e1000_check_for_link(struct e1000_hw *hw) * speed/duplex on the MAC to the current PHY speed/duplex * settings. */ - if (hw->mac_type >= e1000_82544) + if(hw->mac_type >= e1000_82544) e1000_config_collision_dist(hw); else { ret_val = e1000_config_mac_to_phy(hw); - if (ret_val) { + if(ret_val) { DEBUGOUT("Error configuring MAC to PHY settings\n"); return ret_val; } @@ -2903,7 +2861,7 @@ e1000_check_for_link(struct e1000_hw *hw) * have had to re-autoneg with a different link partner. */ ret_val = e1000_config_fc_after_link_up(hw); - if (ret_val) { + if(ret_val) { DEBUGOUT("Error configuring flow control\n"); return ret_val; } @@ -2915,7 +2873,7 @@ e1000_check_for_link(struct e1000_hw *hw) * at gigabit speed, then TBI compatibility is not needed. If we are * at gigabit speed, we turn on TBI compatibility. */ - if (hw->tbi_compatibility_en) { + if(hw->tbi_compatibility_en) { uint16_t speed, duplex; ret_val = e1000_get_speed_and_duplex(hw, &speed, &duplex); if (ret_val) { @@ -2926,7 +2884,7 @@ e1000_check_for_link(struct e1000_hw *hw) /* If link speed is not set to gigabit speed, we do not need * to enable TBI compatibility. */ - if (hw->tbi_compatibility_on) { + if(hw->tbi_compatibility_on) { /* If we previously were in the mode, turn it off. */ rctl = E1000_READ_REG(hw, RCTL); rctl &= ~E1000_RCTL_SBP; @@ -2939,7 +2897,7 @@ e1000_check_for_link(struct e1000_hw *hw) * packets. Some frames have an additional byte on the end and * will look like CRC errors to to the hardware. */ - if (!hw->tbi_compatibility_on) { + if(!hw->tbi_compatibility_on) { hw->tbi_compatibility_on = TRUE; rctl = E1000_READ_REG(hw, RCTL); rctl |= E1000_RCTL_SBP; @@ -2955,12 +2913,12 @@ e1000_check_for_link(struct e1000_hw *hw) * auto-negotiation time to complete, in case the cable was just plugged * in. The autoneg_failed flag does this. */ - else if ((((hw->media_type == e1000_media_type_fiber) && + else if((((hw->media_type == e1000_media_type_fiber) && ((ctrl & E1000_CTRL_SWDPIN1) == signal)) || - (hw->media_type == e1000_media_type_internal_serdes)) && - (!(status & E1000_STATUS_LU)) && - (!(rxcw & E1000_RXCW_C))) { - if (hw->autoneg_failed == 0) { + (hw->media_type == e1000_media_type_internal_serdes)) && + (!(status & E1000_STATUS_LU)) && + (!(rxcw & E1000_RXCW_C))) { + if(hw->autoneg_failed == 0) { hw->autoneg_failed = 1; return 0; } @@ -2976,7 +2934,7 @@ e1000_check_for_link(struct e1000_hw *hw) /* Configure Flow Control after forcing link up. */ ret_val = e1000_config_fc_after_link_up(hw); - if (ret_val) { + if(ret_val) { DEBUGOUT("Error configuring flow control\n"); return ret_val; } @@ -2986,9 +2944,9 @@ e1000_check_for_link(struct e1000_hw *hw) * Device Control register in an attempt to auto-negotiate with our link * partner. */ - else if (((hw->media_type == e1000_media_type_fiber) || - (hw->media_type == e1000_media_type_internal_serdes)) && - (ctrl & E1000_CTRL_SLU) && (rxcw & E1000_RXCW_C)) { + else if(((hw->media_type == e1000_media_type_fiber) || + (hw->media_type == e1000_media_type_internal_serdes)) && + (ctrl & E1000_CTRL_SLU) && (rxcw & E1000_RXCW_C)) { DEBUGOUT("RXing /C/, enable AutoNeg and stop forcing link.\n"); E1000_WRITE_REG(hw, TXCW, hw->txcw); E1000_WRITE_REG(hw, CTRL, (ctrl & ~E1000_CTRL_SLU)); @@ -2998,12 +2956,12 @@ e1000_check_for_link(struct e1000_hw *hw) /* If we force link for non-auto-negotiation switch, check link status * based on MAC synchronization for internal serdes media type. */ - else if ((hw->media_type == e1000_media_type_internal_serdes) && - !(E1000_TXCW_ANE & E1000_READ_REG(hw, TXCW))) { + else if((hw->media_type == e1000_media_type_internal_serdes) && + !(E1000_TXCW_ANE & E1000_READ_REG(hw, TXCW))) { /* SYNCH bit and IV bit are sticky. */ udelay(10); - if (E1000_RXCW_SYNCH & E1000_READ_REG(hw, RXCW)) { - if (!(rxcw & E1000_RXCW_IV)) { + if(E1000_RXCW_SYNCH & E1000_READ_REG(hw, RXCW)) { + if(!(rxcw & E1000_RXCW_IV)) { hw->serdes_link_down = FALSE; DEBUGOUT("SERDES: Link is up.\n"); } @@ -3012,8 +2970,8 @@ e1000_check_for_link(struct e1000_hw *hw) DEBUGOUT("SERDES: Link is down.\n"); } } - if ((hw->media_type == e1000_media_type_internal_serdes) && - (E1000_TXCW_ANE & E1000_READ_REG(hw, TXCW))) { + if((hw->media_type == e1000_media_type_internal_serdes) && + (E1000_TXCW_ANE & E1000_READ_REG(hw, TXCW))) { hw->serdes_link_down = !(E1000_STATUS_LU & E1000_READ_REG(hw, STATUS)); } return E1000_SUCCESS; @@ -3037,12 +2995,12 @@ e1000_get_speed_and_duplex(struct e1000_hw *hw, DEBUGFUNC("e1000_get_speed_and_duplex"); - if (hw->mac_type >= e1000_82543) { + if(hw->mac_type >= e1000_82543) { status = E1000_READ_REG(hw, STATUS); - if (status & E1000_STATUS_SPEED_1000) { + if(status & E1000_STATUS_SPEED_1000) { *speed = SPEED_1000; DEBUGOUT("1000 Mbs, "); - } else if (status & E1000_STATUS_SPEED_100) { + } else if(status & E1000_STATUS_SPEED_100) { *speed = SPEED_100; DEBUGOUT("100 Mbs, "); } else { @@ -3050,7 +3008,7 @@ e1000_get_speed_and_duplex(struct e1000_hw *hw, DEBUGOUT("10 Mbs, "); } - if (status & E1000_STATUS_FD) { + if(status & E1000_STATUS_FD) { *duplex = FULL_DUPLEX; DEBUGOUT("Full Duplex\n"); } else { @@ -3067,18 +3025,18 @@ e1000_get_speed_and_duplex(struct e1000_hw *hw, * if it is operating at half duplex. Here we set the duplex settings to * match the duplex in the link partner's capabilities. */ - if (hw->phy_type == e1000_phy_igp && hw->speed_downgraded) { + if(hw->phy_type == e1000_phy_igp && hw->speed_downgraded) { ret_val = e1000_read_phy_reg(hw, PHY_AUTONEG_EXP, &phy_data); - if (ret_val) + if(ret_val) return ret_val; - if (!(phy_data & NWAY_ER_LP_NWAY_CAPS)) + if(!(phy_data & NWAY_ER_LP_NWAY_CAPS)) *duplex = HALF_DUPLEX; else { ret_val = e1000_read_phy_reg(hw, PHY_LP_ABILITY, &phy_data); - if (ret_val) + if(ret_val) return ret_val; - if ((*speed == SPEED_100 && !(phy_data & NWAY_LPAR_100TX_FD_CAPS)) || + if((*speed == SPEED_100 && !(phy_data & NWAY_LPAR_100TX_FD_CAPS)) || (*speed == SPEED_10 && !(phy_data & NWAY_LPAR_10T_FD_CAPS))) *duplex = HALF_DUPLEX; } @@ -3119,17 +3077,17 @@ e1000_wait_autoneg(struct e1000_hw *hw) DEBUGOUT("Waiting for Auto-Neg to complete.\n"); /* We will wait for autoneg to complete or 4.5 seconds to expire. */ - for (i = PHY_AUTO_NEG_TIME; i > 0; i--) { + for(i = PHY_AUTO_NEG_TIME; i > 0; i--) { /* Read the MII Status Register and wait for Auto-Neg * Complete bit to be set. */ ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data); - if (ret_val) + if(ret_val) return ret_val; ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data); - if (ret_val) + if(ret_val) return ret_val; - if (phy_data & MII_SR_AUTONEG_COMPLETE) { + if(phy_data & MII_SR_AUTONEG_COMPLETE) { return E1000_SUCCESS; } msec_delay(100); @@ -3202,16 +3160,14 @@ e1000_shift_out_mdi_bits(struct e1000_hw *hw, /* Set MDIO_DIR and MDC_DIR direction bits to be used as output pins. */ ctrl |= (E1000_CTRL_MDIO_DIR | E1000_CTRL_MDC_DIR); - while (mask) { + while(mask) { /* A "1" is shifted out to the PHY by setting the MDIO bit to "1" and * then raising and lowering the Management Data Clock. A "0" is * shifted out to the PHY by setting the MDIO bit to "0" and then * raising and lowering the clock. */ - if (data & mask) - ctrl |= E1000_CTRL_MDIO; - else - ctrl &= ~E1000_CTRL_MDIO; + if(data & mask) ctrl |= E1000_CTRL_MDIO; + else ctrl &= ~E1000_CTRL_MDIO; E1000_WRITE_REG(hw, CTRL, ctrl); E1000_WRITE_FLUSH(hw); @@ -3262,13 +3218,12 @@ e1000_shift_in_mdi_bits(struct e1000_hw *hw) e1000_raise_mdi_clk(hw, &ctrl); e1000_lower_mdi_clk(hw, &ctrl); - for (data = 0, i = 0; i < 16; i++) { + for(data = 0, i = 0; i < 16; i++) { data = data << 1; e1000_raise_mdi_clk(hw, &ctrl); ctrl = E1000_READ_REG(hw, CTRL); /* Check to see if we shifted in a "1". */ - if (ctrl & E1000_CTRL_MDIO) - data |= 1; + if(ctrl & E1000_CTRL_MDIO) data |= 1; e1000_lower_mdi_clk(hw, &ctrl); } @@ -3278,7 +3233,7 @@ e1000_shift_in_mdi_bits(struct e1000_hw *hw) return data; } -static int32_t +int32_t e1000_swfw_sync_acquire(struct e1000_hw *hw, uint16_t mask) { uint32_t swfw_sync = 0; @@ -3294,7 +3249,7 @@ e1000_swfw_sync_acquire(struct e1000_hw *hw, uint16_t mask) if (!hw->swfw_sync_present) return e1000_get_hw_eeprom_semaphore(hw); - while (timeout) { + while(timeout) { if (e1000_get_hw_eeprom_semaphore(hw)) return -E1000_ERR_SWFW_SYNC; @@ -3322,7 +3277,7 @@ e1000_swfw_sync_acquire(struct e1000_hw *hw, uint16_t mask) return E1000_SUCCESS; } -static void +void e1000_swfw_sync_release(struct e1000_hw *hw, uint16_t mask) { uint32_t swfw_sync; @@ -3383,7 +3338,7 @@ e1000_read_phy_reg(struct e1000_hw *hw, (reg_addr > MAX_PHY_MULTI_PAGE_REG)) { ret_val = e1000_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT, (uint16_t)reg_addr); - if (ret_val) { + if(ret_val) { e1000_swfw_sync_release(hw, swfw); return ret_val; } @@ -3428,12 +3383,12 @@ e1000_read_phy_reg_ex(struct e1000_hw *hw, DEBUGFUNC("e1000_read_phy_reg_ex"); - if (reg_addr > MAX_PHY_REG_ADDRESS) { + if(reg_addr > MAX_PHY_REG_ADDRESS) { DEBUGOUT1("PHY Address %d is out of range\n", reg_addr); return -E1000_ERR_PARAM; } - if (hw->mac_type > e1000_82543) { + if(hw->mac_type > e1000_82543) { /* Set up Op-code, Phy Address, and register address in the MDI * Control register. The MAC will take care of interfacing with the * PHY to retrieve the desired data. @@ -3445,16 +3400,16 @@ e1000_read_phy_reg_ex(struct e1000_hw *hw, E1000_WRITE_REG(hw, MDIC, mdic); /* Poll the ready bit to see if the MDI read completed */ - for (i = 0; i < 64; i++) { + for(i = 0; i < 64; i++) { udelay(50); mdic = E1000_READ_REG(hw, MDIC); - if (mdic & E1000_MDIC_READY) break; + if(mdic & E1000_MDIC_READY) break; } - if (!(mdic & E1000_MDIC_READY)) { + if(!(mdic & E1000_MDIC_READY)) { DEBUGOUT("MDI Read did not complete\n"); return -E1000_ERR_PHY; } - if (mdic & E1000_MDIC_ERROR) { + if(mdic & E1000_MDIC_ERROR) { DEBUGOUT("MDI Error\n"); return -E1000_ERR_PHY; } @@ -3523,7 +3478,7 @@ e1000_write_phy_reg(struct e1000_hw *hw, (reg_addr > MAX_PHY_MULTI_PAGE_REG)) { ret_val = e1000_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT, (uint16_t)reg_addr); - if (ret_val) { + if(ret_val) { e1000_swfw_sync_release(hw, swfw); return ret_val; } @@ -3568,12 +3523,12 @@ e1000_write_phy_reg_ex(struct e1000_hw *hw, DEBUGFUNC("e1000_write_phy_reg_ex"); - if (reg_addr > MAX_PHY_REG_ADDRESS) { + if(reg_addr > MAX_PHY_REG_ADDRESS) { DEBUGOUT1("PHY Address %d is out of range\n", reg_addr); return -E1000_ERR_PARAM; } - if (hw->mac_type > e1000_82543) { + if(hw->mac_type > e1000_82543) { /* Set up Op-code, Phy Address, register address, and data intended * for the PHY register in the MDI Control register. The MAC will take * care of interfacing with the PHY to send the desired data. @@ -3586,12 +3541,12 @@ e1000_write_phy_reg_ex(struct e1000_hw *hw, E1000_WRITE_REG(hw, MDIC, mdic); /* Poll the ready bit to see if the MDI read completed */ - for (i = 0; i < 641; i++) { + for(i = 0; i < 640; i++) { udelay(5); mdic = E1000_READ_REG(hw, MDIC); - if (mdic & E1000_MDIC_READY) break; + if(mdic & E1000_MDIC_READY) break; } - if (!(mdic & E1000_MDIC_READY)) { + if(!(mdic & E1000_MDIC_READY)) { DEBUGOUT("MDI Write did not complete\n"); return -E1000_ERR_PHY; } @@ -3620,7 +3575,7 @@ e1000_write_phy_reg_ex(struct e1000_hw *hw, return E1000_SUCCESS; } -static int32_t +int32_t e1000_read_kmrn_reg(struct e1000_hw *hw, uint32_t reg_addr, uint16_t *data) @@ -3653,7 +3608,7 @@ e1000_read_kmrn_reg(struct e1000_hw *hw, return E1000_SUCCESS; } -static int32_t +int32_t e1000_write_kmrn_reg(struct e1000_hw *hw, uint32_t reg_addr, uint16_t data) @@ -3703,7 +3658,7 @@ e1000_phy_hw_reset(struct e1000_hw *hw) DEBUGOUT("Resetting Phy...\n"); - if (hw->mac_type > e1000_82543) { + if(hw->mac_type > e1000_82543) { if ((hw->mac_type == e1000_80003es2lan) && (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1)) { swfw = E1000_SWFW_PHY1_SM; @@ -3751,7 +3706,7 @@ e1000_phy_hw_reset(struct e1000_hw *hw) } udelay(150); - if ((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) { + if((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) { /* Configure activity LED after PHY reset */ led_ctrl = E1000_READ_REG(hw, LEDCTL); led_ctrl &= IGP_ACTIVITY_LED_MASK; @@ -3761,13 +3716,14 @@ e1000_phy_hw_reset(struct e1000_hw *hw) /* Wait for FW to finish PHY configuration. */ ret_val = e1000_get_phy_cfg_done(hw); - if (ret_val != E1000_SUCCESS) - return ret_val; e1000_release_software_semaphore(hw); - if ((hw->mac_type == e1000_ich8lan) && (hw->phy_type == e1000_phy_igp_3)) - ret_val = e1000_init_lcd_from_nvm(hw); - + if ((hw->mac_type == e1000_ich8lan) && + (hw->phy_type == e1000_phy_igp_3)) { + ret_val = e1000_init_lcd_from_nvm(hw); + if (ret_val) + return ret_val; + } return ret_val; } @@ -3798,25 +3754,25 @@ e1000_phy_reset(struct e1000_hw *hw) case e1000_82572: case e1000_ich8lan: ret_val = e1000_phy_hw_reset(hw); - if (ret_val) + if(ret_val) return ret_val; break; default: ret_val = e1000_read_phy_reg(hw, PHY_CTRL, &phy_data); - if (ret_val) + if(ret_val) return ret_val; phy_data |= MII_CR_RESET; ret_val = e1000_write_phy_reg(hw, PHY_CTRL, phy_data); - if (ret_val) + if(ret_val) return ret_val; udelay(1); break; } - if (hw->phy_type == e1000_phy_igp || hw->phy_type == e1000_phy_igp_2) + if(hw->phy_type == e1000_phy_igp || hw->phy_type == e1000_phy_igp_2) e1000_phy_init_script(hw); return E1000_SUCCESS; @@ -3883,7 +3839,7 @@ e1000_phy_powerdown_workaround(struct e1000_hw *hw) * * hw - struct containing variables accessed by shared code ******************************************************************************/ -static int32_t +int32_t e1000_kumeran_lock_loss_workaround(struct e1000_hw *hw) { int32_t ret_val; @@ -3894,8 +3850,8 @@ e1000_kumeran_lock_loss_workaround(struct e1000_hw *hw) if (hw->kmrn_lock_loss_workaround_disabled) return E1000_SUCCESS; - /* Make sure link is up before proceeding. If not just return. - * Attempting this while link is negotiating fouled up link + /* Make sure link is up before proceeding. If not just return. + * Attempting this while link is negotiating fouls up link * stability */ ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data); ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data); @@ -3972,34 +3928,34 @@ e1000_detect_gig_phy(struct e1000_hw *hw) hw->phy_id = (uint32_t) (phy_id_high << 16); udelay(20); ret_val = e1000_read_phy_reg(hw, PHY_ID2, &phy_id_low); - if (ret_val) + if(ret_val) return ret_val; hw->phy_id |= (uint32_t) (phy_id_low & PHY_REVISION_MASK); hw->phy_revision = (uint32_t) phy_id_low & ~PHY_REVISION_MASK; - switch (hw->mac_type) { + switch(hw->mac_type) { case e1000_82543: - if (hw->phy_id == M88E1000_E_PHY_ID) match = TRUE; + if(hw->phy_id == M88E1000_E_PHY_ID) match = TRUE; break; case e1000_82544: - if (hw->phy_id == M88E1000_I_PHY_ID) match = TRUE; + if(hw->phy_id == M88E1000_I_PHY_ID) match = TRUE; break; case e1000_82540: case e1000_82545: case e1000_82545_rev_3: case e1000_82546: case e1000_82546_rev_3: - if (hw->phy_id == M88E1011_I_PHY_ID) match = TRUE; + if(hw->phy_id == M88E1011_I_PHY_ID) match = TRUE; break; case e1000_82541: case e1000_82541_rev_2: case e1000_82547: case e1000_82547_rev_2: - if (hw->phy_id == IGP01E1000_I_PHY_ID) match = TRUE; + if(hw->phy_id == IGP01E1000_I_PHY_ID) match = TRUE; break; case e1000_82573: - if (hw->phy_id == M88E1111_I_PHY_ID) match = TRUE; + if(hw->phy_id == M88E1111_I_PHY_ID) match = TRUE; break; case e1000_80003es2lan: if (hw->phy_id == GG82563_E_PHY_ID) match = TRUE; @@ -4038,14 +3994,14 @@ e1000_phy_reset_dsp(struct e1000_hw *hw) do { if (hw->phy_type != e1000_phy_gg82563) { ret_val = e1000_write_phy_reg(hw, 29, 0x001d); - if (ret_val) break; + if(ret_val) break; } ret_val = e1000_write_phy_reg(hw, 30, 0x00c1); - if (ret_val) break; + if(ret_val) break; ret_val = e1000_write_phy_reg(hw, 30, 0x0000); - if (ret_val) break; + if(ret_val) break; ret_val = E1000_SUCCESS; - } while (0); + } while(0); return ret_val; } @@ -4056,7 +4012,7 @@ e1000_phy_reset_dsp(struct e1000_hw *hw) * hw - Struct containing variables accessed by shared code * phy_info - PHY information structure ******************************************************************************/ -int32_t +static int32_t e1000_phy_igp_get_info(struct e1000_hw *hw, struct e1000_phy_info *phy_info) { @@ -4077,23 +4033,23 @@ e1000_phy_igp_get_info(struct e1000_hw *hw, /* Check polarity status */ ret_val = e1000_check_polarity(hw, &polarity); - if (ret_val) + if(ret_val) return ret_val; phy_info->cable_polarity = polarity; ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS, &phy_data); - if (ret_val) + if(ret_val) return ret_val; phy_info->mdix_mode = (phy_data & IGP01E1000_PSSR_MDIX) >> IGP01E1000_PSSR_MDIX_SHIFT; - if ((phy_data & IGP01E1000_PSSR_SPEED_MASK) == + if((phy_data & IGP01E1000_PSSR_SPEED_MASK) == IGP01E1000_PSSR_SPEED_1000MBPS) { /* Local/Remote Receiver Information are only valid at 1000 Mbps */ ret_val = e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_data); - if (ret_val) + if(ret_val) return ret_val; phy_info->local_rx = (phy_data & SR_1000T_LOCAL_RX_STATUS) >> @@ -4103,19 +4059,19 @@ e1000_phy_igp_get_info(struct e1000_hw *hw, /* Get cable length */ ret_val = e1000_get_cable_length(hw, &min_length, &max_length); - if (ret_val) + if(ret_val) return ret_val; /* Translate to old method */ average = (max_length + min_length) / 2; - if (average <= e1000_igp_cable_length_50) + if(average <= e1000_igp_cable_length_50) phy_info->cable_length = e1000_cable_length_50; - else if (average <= e1000_igp_cable_length_80) + else if(average <= e1000_igp_cable_length_80) phy_info->cable_length = e1000_cable_length_50_80; - else if (average <= e1000_igp_cable_length_110) + else if(average <= e1000_igp_cable_length_110) phy_info->cable_length = e1000_cable_length_80_110; - else if (average <= e1000_igp_cable_length_140) + else if(average <= e1000_igp_cable_length_140) phy_info->cable_length = e1000_cable_length_110_140; else phy_info->cable_length = e1000_cable_length_140; @@ -4130,7 +4086,7 @@ e1000_phy_igp_get_info(struct e1000_hw *hw, * hw - Struct containing variables accessed by shared code * phy_info - PHY information structure ******************************************************************************/ -static int32_t +int32_t e1000_phy_ife_get_info(struct e1000_hw *hw, struct e1000_phy_info *phy_info) { @@ -4191,7 +4147,7 @@ e1000_phy_m88_get_info(struct e1000_hw *hw, phy_info->downshift = (e1000_downshift)hw->speed_downgraded; ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data); - if (ret_val) + if(ret_val) return ret_val; phy_info->extended_10bt_distance = @@ -4203,12 +4159,12 @@ e1000_phy_m88_get_info(struct e1000_hw *hw, /* Check polarity status */ ret_val = e1000_check_polarity(hw, &polarity); - if (ret_val) + if(ret_val) return ret_val; phy_info->cable_polarity = polarity; ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data); - if (ret_val) + if(ret_val) return ret_val; phy_info->mdix_mode = (phy_data & M88E1000_PSSR_MDIX) >> @@ -4231,7 +4187,7 @@ e1000_phy_m88_get_info(struct e1000_hw *hw, } ret_val = e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_data); - if (ret_val) + if(ret_val) return ret_val; phy_info->local_rx = (phy_data & SR_1000T_LOCAL_RX_STATUS) >> @@ -4268,20 +4224,20 @@ e1000_phy_get_info(struct e1000_hw *hw, phy_info->local_rx = e1000_1000t_rx_status_undefined; phy_info->remote_rx = e1000_1000t_rx_status_undefined; - if (hw->media_type != e1000_media_type_copper) { + if(hw->media_type != e1000_media_type_copper) { DEBUGOUT("PHY info is only valid for copper media\n"); return -E1000_ERR_CONFIG; } ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data); - if (ret_val) + if(ret_val) return ret_val; ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data); - if (ret_val) + if(ret_val) return ret_val; - if ((phy_data & MII_SR_LINK_STATUS) != MII_SR_LINK_STATUS) { + if((phy_data & MII_SR_LINK_STATUS) != MII_SR_LINK_STATUS) { DEBUGOUT("PHY info is only valid if link is up\n"); return -E1000_ERR_CONFIG; } @@ -4301,7 +4257,7 @@ e1000_validate_mdi_setting(struct e1000_hw *hw) { DEBUGFUNC("e1000_validate_mdi_settings"); - if (!hw->autoneg && (hw->mdix == 0 || hw->mdix == 3)) { + if(!hw->autoneg && (hw->mdix == 0 || hw->mdix == 3)) { DEBUGOUT("Invalid MDI setting detected\n"); hw->mdix = 1; return -E1000_ERR_CONFIG; @@ -4348,7 +4304,7 @@ e1000_init_eeprom_params(struct e1000_hw *hw) eeprom->type = e1000_eeprom_microwire; eeprom->opcode_bits = 3; eeprom->delay_usec = 50; - if (eecd & E1000_EECD_SIZE) { + if(eecd & E1000_EECD_SIZE) { eeprom->word_size = 256; eeprom->address_bits = 8; } else { @@ -4416,7 +4372,7 @@ e1000_init_eeprom_params(struct e1000_hw *hw) } eeprom->use_eerd = TRUE; eeprom->use_eewr = TRUE; - if (e1000_is_onboard_nvm_eeprom(hw) == FALSE) { + if(e1000_is_onboard_nvm_eeprom(hw) == FALSE) { eeprom->type = e1000_eeprom_flash; eeprom->word_size = 2048; @@ -4477,17 +4433,17 @@ e1000_init_eeprom_params(struct e1000_hw *hw) /* eeprom_size will be an enum [0..8] that maps to eeprom sizes 128B to * 32KB (incremented by powers of 2). */ - if (hw->mac_type <= e1000_82547_rev_2) { + if(hw->mac_type <= e1000_82547_rev_2) { /* Set to default value for initial eeprom read. */ eeprom->word_size = 64; ret_val = e1000_read_eeprom(hw, EEPROM_CFG, 1, &eeprom_size); - if (ret_val) + if(ret_val) return ret_val; eeprom_size = (eeprom_size & EEPROM_SIZE_MASK) >> EEPROM_SIZE_SHIFT; /* 256B eeprom size was not supported in earlier hardware, so we * bump eeprom_size up one to ensure that "1" (which maps to 256B) * is never the result used in the shifting logic below. */ - if (eeprom_size) + if(eeprom_size) eeprom_size++; } else { eeprom_size = (uint16_t)((eecd & E1000_EECD_SIZE_EX_MASK) >> @@ -4572,7 +4528,7 @@ e1000_shift_out_ee_bits(struct e1000_hw *hw, */ eecd &= ~E1000_EECD_DI; - if (data & mask) + if(data & mask) eecd |= E1000_EECD_DI; E1000_WRITE_REG(hw, EECD, eecd); @@ -4585,7 +4541,7 @@ e1000_shift_out_ee_bits(struct e1000_hw *hw, mask = mask >> 1; - } while (mask); + } while(mask); /* We leave the "DI" bit set to "0" when we leave this routine. */ eecd &= ~E1000_EECD_DI; @@ -4617,14 +4573,14 @@ e1000_shift_in_ee_bits(struct e1000_hw *hw, eecd &= ~(E1000_EECD_DO | E1000_EECD_DI); data = 0; - for (i = 0; i < count; i++) { + for(i = 0; i < count; i++) { data = data << 1; e1000_raise_ee_clk(hw, &eecd); eecd = E1000_READ_REG(hw, EECD); eecd &= ~(E1000_EECD_DI); - if (eecd & E1000_EECD_DO) + if(eecd & E1000_EECD_DO) data |= 1; e1000_lower_ee_clk(hw, &eecd); @@ -4655,17 +4611,17 @@ e1000_acquire_eeprom(struct e1000_hw *hw) if (hw->mac_type != e1000_82573) { /* Request EEPROM Access */ - if (hw->mac_type > e1000_82544) { + if(hw->mac_type > e1000_82544) { eecd |= E1000_EECD_REQ; E1000_WRITE_REG(hw, EECD, eecd); eecd = E1000_READ_REG(hw, EECD); - while ((!(eecd & E1000_EECD_GNT)) && + while((!(eecd & E1000_EECD_GNT)) && (i < E1000_EEPROM_GRANT_ATTEMPTS)) { i++; udelay(5); eecd = E1000_READ_REG(hw, EECD); } - if (!(eecd & E1000_EECD_GNT)) { + if(!(eecd & E1000_EECD_GNT)) { eecd &= ~E1000_EECD_REQ; E1000_WRITE_REG(hw, EECD, eecd); DEBUGOUT("Could not acquire EEPROM grant\n"); @@ -4708,7 +4664,7 @@ e1000_standby_eeprom(struct e1000_hw *hw) eecd = E1000_READ_REG(hw, EECD); - if (eeprom->type == e1000_eeprom_microwire) { + if(eeprom->type == e1000_eeprom_microwire) { eecd &= ~(E1000_EECD_CS | E1000_EECD_SK); E1000_WRITE_REG(hw, EECD, eecd); E1000_WRITE_FLUSH(hw); @@ -4731,7 +4687,7 @@ e1000_standby_eeprom(struct e1000_hw *hw) E1000_WRITE_REG(hw, EECD, eecd); E1000_WRITE_FLUSH(hw); udelay(eeprom->delay_usec); - } else if (eeprom->type == e1000_eeprom_spi) { + } else if(eeprom->type == e1000_eeprom_spi) { /* Toggle CS to flush commands */ eecd |= E1000_EECD_CS; E1000_WRITE_REG(hw, EECD, eecd); @@ -4765,7 +4721,7 @@ e1000_release_eeprom(struct e1000_hw *hw) E1000_WRITE_REG(hw, EECD, eecd); udelay(hw->eeprom.delay_usec); - } else if (hw->eeprom.type == e1000_eeprom_microwire) { + } else if(hw->eeprom.type == e1000_eeprom_microwire) { /* cleanup eeprom */ /* CS on Microwire is active-high */ @@ -4787,7 +4743,7 @@ e1000_release_eeprom(struct e1000_hw *hw) } /* Stop requesting EEPROM access */ - if (hw->mac_type > e1000_82544) { + if(hw->mac_type > e1000_82544) { eecd &= ~E1000_EECD_REQ; E1000_WRITE_REG(hw, EECD, eecd); } @@ -4825,12 +4781,12 @@ e1000_spi_eeprom_ready(struct e1000_hw *hw) retry_count += 5; e1000_standby_eeprom(hw); - } while (retry_count < EEPROM_MAX_RETRY_SPI); + } while(retry_count < EEPROM_MAX_RETRY_SPI); /* ATMEL SPI write time could vary from 0-20mSec on 3.3V devices (and * only 0-5mSec on 5V devices) */ - if (retry_count >= EEPROM_MAX_RETRY_SPI) { + if(retry_count >= EEPROM_MAX_RETRY_SPI) { DEBUGOUT("SPI EEPROM Status error\n"); return -E1000_ERR_EEPROM; } @@ -4861,7 +4817,7 @@ e1000_read_eeprom(struct e1000_hw *hw, /* A check for invalid values: offset too large, too many words, and not * enough words. */ - if ((offset >= eeprom->word_size) || (words > eeprom->word_size - offset) || + if((offset >= eeprom->word_size) || (words > eeprom->word_size - offset) || (words == 0)) { DEBUGOUT("\"words\" parameter out of bounds\n"); return -E1000_ERR_EEPROM; @@ -4869,7 +4825,7 @@ e1000_read_eeprom(struct e1000_hw *hw, /* FLASH reads without acquiring the semaphore are safe */ if (e1000_is_onboard_nvm_eeprom(hw) == TRUE && - hw->eeprom.use_eerd == FALSE) { + hw->eeprom.use_eerd == FALSE) { switch (hw->mac_type) { case e1000_80003es2lan: break; @@ -4896,7 +4852,7 @@ e1000_read_eeprom(struct e1000_hw *hw, uint16_t word_in; uint8_t read_opcode = EEPROM_READ_OPCODE_SPI; - if (e1000_spi_eeprom_ready(hw)) { + if(e1000_spi_eeprom_ready(hw)) { e1000_release_eeprom(hw); return -E1000_ERR_EEPROM; } @@ -4904,7 +4860,7 @@ e1000_read_eeprom(struct e1000_hw *hw, e1000_standby_eeprom(hw); /* Some SPI eeproms use the 8th address bit embedded in the opcode */ - if ((eeprom->address_bits == 8) && (offset >= 128)) + if((eeprom->address_bits == 8) && (offset >= 128)) read_opcode |= EEPROM_A8_OPCODE_SPI; /* Send the READ command (opcode + addr) */ @@ -4920,7 +4876,7 @@ e1000_read_eeprom(struct e1000_hw *hw, word_in = e1000_shift_in_ee_bits(hw, 16); data[i] = (word_in >> 8) | (word_in << 8); } - } else if (eeprom->type == e1000_eeprom_microwire) { + } else if(eeprom->type == e1000_eeprom_microwire) { for (i = 0; i < words; i++) { /* Send the READ command (opcode + addr) */ e1000_shift_out_ee_bits(hw, EEPROM_READ_OPCODE_MICROWIRE, @@ -4965,7 +4921,7 @@ e1000_read_eeprom_eerd(struct e1000_hw *hw, E1000_WRITE_REG(hw, EERD, eerd); error = e1000_poll_eerd_eewr_done(hw, E1000_EEPROM_POLL_READ); - if (error) { + if(error) { break; } data[i] = (E1000_READ_REG(hw, EERD) >> E1000_EEPROM_RW_REG_DATA); @@ -5002,7 +4958,7 @@ e1000_write_eeprom_eewr(struct e1000_hw *hw, E1000_EEPROM_RW_REG_START; error = e1000_poll_eerd_eewr_done(hw, E1000_EEPROM_POLL_WRITE); - if (error) { + if(error) { break; } @@ -5010,7 +4966,7 @@ e1000_write_eeprom_eewr(struct e1000_hw *hw, error = e1000_poll_eerd_eewr_done(hw, E1000_EEPROM_POLL_WRITE); - if (error) { + if(error) { break; } } @@ -5031,13 +4987,13 @@ e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int eerd) uint32_t i, reg = 0; int32_t done = E1000_ERR_EEPROM; - for (i = 0; i < attempts; i++) { - if (eerd == E1000_EEPROM_POLL_READ) + for(i = 0; i < attempts; i++) { + if(eerd == E1000_EEPROM_POLL_READ) reg = E1000_READ_REG(hw, EERD); else reg = E1000_READ_REG(hw, EEWR); - if (reg & E1000_EEPROM_RW_REG_DONE) { + if(reg & E1000_EEPROM_RW_REG_DONE) { done = E1000_SUCCESS; break; } @@ -5069,7 +5025,7 @@ e1000_is_onboard_nvm_eeprom(struct e1000_hw *hw) eecd = ((eecd >> 15) & 0x03); /* If both bits are set, device is Flash type */ - if (eecd == 0x03) { + if(eecd == 0x03) { return FALSE; } } @@ -5134,7 +5090,7 @@ e1000_validate_eeprom_checksum(struct e1000_hw *hw) checksum += eeprom_data; } - if (checksum == (uint16_t) EEPROM_SUM) + if(checksum == (uint16_t) EEPROM_SUM) return E1000_SUCCESS; else { DEBUGOUT("EEPROM Checksum Invalid\n"); @@ -5159,15 +5115,15 @@ e1000_update_eeprom_checksum(struct e1000_hw *hw) DEBUGFUNC("e1000_update_eeprom_checksum"); - for (i = 0; i < EEPROM_CHECKSUM_REG; i++) { - if (e1000_read_eeprom(hw, i, 1, &eeprom_data) < 0) { + for(i = 0; i < EEPROM_CHECKSUM_REG; i++) { + if(e1000_read_eeprom(hw, i, 1, &eeprom_data) < 0) { DEBUGOUT("EEPROM Read Error\n"); return -E1000_ERR_EEPROM; } checksum += eeprom_data; } checksum = (uint16_t) EEPROM_SUM - checksum; - if (e1000_write_eeprom(hw, EEPROM_CHECKSUM_REG, 1, &checksum) < 0) { + if(e1000_write_eeprom(hw, EEPROM_CHECKSUM_REG, 1, &checksum) < 0) { DEBUGOUT("EEPROM Write Error\n"); return -E1000_ERR_EEPROM; } else if (hw->eeprom.type == e1000_eeprom_flash) { @@ -5209,14 +5165,14 @@ e1000_write_eeprom(struct e1000_hw *hw, /* A check for invalid values: offset too large, too many words, and not * enough words. */ - if ((offset >= eeprom->word_size) || (words > eeprom->word_size - offset) || + if((offset >= eeprom->word_size) || (words > eeprom->word_size - offset) || (words == 0)) { DEBUGOUT("\"words\" parameter out of bounds\n"); return -E1000_ERR_EEPROM; } /* 82573 writes only through eewr */ - if (eeprom->use_eewr == TRUE) + if(eeprom->use_eewr == TRUE) return e1000_write_eeprom_eewr(hw, offset, words, data); if (eeprom->type == e1000_eeprom_ich8) @@ -5226,7 +5182,7 @@ e1000_write_eeprom(struct e1000_hw *hw, if (e1000_acquire_eeprom(hw) != E1000_SUCCESS) return -E1000_ERR_EEPROM; - if (eeprom->type == e1000_eeprom_microwire) { + if(eeprom->type == e1000_eeprom_microwire) { status = e1000_write_eeprom_microwire(hw, offset, words, data); } else { status = e1000_write_eeprom_spi(hw, offset, words, data); @@ -5262,7 +5218,7 @@ e1000_write_eeprom_spi(struct e1000_hw *hw, while (widx < words) { uint8_t write_opcode = EEPROM_WRITE_OPCODE_SPI; - if (e1000_spi_eeprom_ready(hw)) return -E1000_ERR_EEPROM; + if(e1000_spi_eeprom_ready(hw)) return -E1000_ERR_EEPROM; e1000_standby_eeprom(hw); @@ -5273,7 +5229,7 @@ e1000_write_eeprom_spi(struct e1000_hw *hw, e1000_standby_eeprom(hw); /* Some SPI eeproms use the 8th address bit embedded in the opcode */ - if ((eeprom->address_bits == 8) && (offset >= 128)) + if((eeprom->address_bits == 8) && (offset >= 128)) write_opcode |= EEPROM_A8_OPCODE_SPI; /* Send the Write command (8-bit opcode + addr) */ @@ -5295,7 +5251,7 @@ e1000_write_eeprom_spi(struct e1000_hw *hw, * operation, while the smaller eeproms are capable of an 8-byte * PAGE WRITE operation. Break the inner loop to pass new address */ - if ((((offset + widx)*2) % eeprom->page_size) == 0) { + if((((offset + widx)*2) % eeprom->page_size) == 0) { e1000_standby_eeprom(hw); break; } @@ -5361,12 +5317,12 @@ e1000_write_eeprom_microwire(struct e1000_hw *hw, * signal that the command has been completed by raising the DO signal. * If DO does not go high in 10 milliseconds, then error out. */ - for (i = 0; i < 200; i++) { + for(i = 0; i < 200; i++) { eecd = E1000_READ_REG(hw, EECD); - if (eecd & E1000_EECD_DO) break; + if(eecd & E1000_EECD_DO) break; udelay(50); } - if (i == 200) { + if(i == 200) { DEBUGOUT("EEPROM Write did not complete\n"); return -E1000_ERR_EEPROM; } @@ -5556,6 +5512,40 @@ e1000_commit_shadow_ram(struct e1000_hw *hw) return error; } +/****************************************************************************** + * Reads the adapter's part number from the EEPROM + * + * hw - Struct containing variables accessed by shared code + * part_num - Adapter's part number + *****************************************************************************/ +int32_t +e1000_read_part_num(struct e1000_hw *hw, + uint32_t *part_num) +{ + uint16_t offset = EEPROM_PBA_BYTE_1; + uint16_t eeprom_data; + + DEBUGFUNC("e1000_read_part_num"); + + /* Get word 0 from EEPROM */ + if(e1000_read_eeprom(hw, offset, 1, &eeprom_data) < 0) { + DEBUGOUT("EEPROM Read Error\n"); + return -E1000_ERR_EEPROM; + } + /* Save word 0 in upper half of part_num */ + *part_num = (uint32_t) (eeprom_data << 16); + + /* Get word 1 from EEPROM */ + if(e1000_read_eeprom(hw, ++offset, 1, &eeprom_data) < 0) { + DEBUGOUT("EEPROM Read Error\n"); + return -E1000_ERR_EEPROM; + } + /* Save word 1 in lower half of part_num */ + *part_num |= eeprom_data; + + return E1000_SUCCESS; +} + /****************************************************************************** * Reads the adapter's MAC address from the EEPROM and inverts the LSB for the * second function of dual function devices @@ -5570,9 +5560,9 @@ e1000_read_mac_addr(struct e1000_hw * hw) DEBUGFUNC("e1000_read_mac_addr"); - for (i = 0; i < NODE_ADDRESS_SIZE; i += 2) { + for(i = 0; i < NODE_ADDRESS_SIZE; i += 2) { offset = i >> 1; - if (e1000_read_eeprom(hw, offset, 1, &eeprom_data) < 0) { + if(e1000_read_eeprom(hw, offset, 1, &eeprom_data) < 0) { DEBUGOUT("EEPROM Read Error\n"); return -E1000_ERR_EEPROM; } @@ -5587,12 +5577,12 @@ e1000_read_mac_addr(struct e1000_hw * hw) case e1000_82546_rev_3: case e1000_82571: case e1000_80003es2lan: - if (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1) + if(E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1) hw->perm_mac_addr[5] ^= 0x01; break; } - for (i = 0; i < NODE_ADDRESS_SIZE; i++) + for(i = 0; i < NODE_ADDRESS_SIZE; i++) hw->mac_addr[i] = hw->perm_mac_addr[i]; return E1000_SUCCESS; } @@ -5631,7 +5621,7 @@ e1000_init_rx_addrs(struct e1000_hw *hw) /* Zero out the other 15 receive addresses. */ DEBUGOUT("Clearing RAR[1-15]\n"); - for (i = 1; i < rar_num; i++) { + for(i = 1; i < rar_num; i++) { E1000_WRITE_REG_ARRAY(hw, RA, (i << 1), 0); E1000_WRITE_FLUSH(hw); E1000_WRITE_REG_ARRAY(hw, RA, ((i << 1) + 1), 0); @@ -5653,7 +5643,6 @@ e1000_init_rx_addrs(struct e1000_hw *hw) * for the first 15 multicast addresses, and hashes the rest into the * multicast table. *****************************************************************************/ -#if 0 void e1000_mc_addr_list_update(struct e1000_hw *hw, uint8_t *mc_addr_list, @@ -5682,7 +5671,7 @@ e1000_mc_addr_list_update(struct e1000_hw *hw, if ((hw->mac_type == e1000_82571) && (hw->laa_is_present == TRUE)) num_rar_entry -= 1; - for (i = rar_used_count; i < num_rar_entry; i++) { + for(i = rar_used_count; i < num_rar_entry; i++) { E1000_WRITE_REG_ARRAY(hw, RA, (i << 1), 0); E1000_WRITE_FLUSH(hw); E1000_WRITE_REG_ARRAY(hw, RA, ((i << 1) + 1), 0); @@ -5694,13 +5683,13 @@ e1000_mc_addr_list_update(struct e1000_hw *hw, num_mta_entry = E1000_NUM_MTA_REGISTERS; if (hw->mac_type == e1000_ich8lan) num_mta_entry = E1000_NUM_MTA_REGISTERS_ICH8LAN; - for (i = 0; i < num_mta_entry; i++) { + for(i = 0; i < num_mta_entry; i++) { E1000_WRITE_REG_ARRAY(hw, MTA, i, 0); E1000_WRITE_FLUSH(hw); } /* Add the new addresses */ - for (i = 0; i < mc_addr_count; i++) { + for(i = 0; i < mc_addr_count; i++) { DEBUGOUT(" Adding the multicast addresses:\n"); DEBUGOUT7(" MC Addr #%d =%.2X %.2X %.2X %.2X %.2X %.2X\n", i, mc_addr_list[i * (ETH_LENGTH_OF_ADDRESS + pad)], @@ -5730,7 +5719,6 @@ e1000_mc_addr_list_update(struct e1000_hw *hw, } DEBUGOUT("MC Update Complete\n"); } -#endif /* 0 */ /****************************************************************************** * Hashes an address to determine its location in the multicast table @@ -5832,7 +5820,7 @@ e1000_mta_set(struct e1000_hw *hw, * in the MTA, save off the previous entry before writing and * restore the old value after writing. */ - if ((hw->mac_type == e1000_82544) && ((hash_reg & 0x1) == 1)) { + if((hw->mac_type == e1000_82544) && ((hash_reg & 0x1) == 1)) { temp = E1000_READ_REG_ARRAY(hw, MTA, (hash_reg - 1)); E1000_WRITE_REG_ARRAY(hw, MTA, hash_reg, mta); E1000_WRITE_FLUSH(hw); @@ -5982,7 +5970,7 @@ e1000_id_led_init(struct e1000_hw * hw) DEBUGFUNC("e1000_id_led_init"); - if (hw->mac_type < e1000_82540) { + if(hw->mac_type < e1000_82540) { /* Nothing to do */ return E1000_SUCCESS; } @@ -5992,7 +5980,7 @@ e1000_id_led_init(struct e1000_hw * hw) hw->ledctl_mode1 = hw->ledctl_default; hw->ledctl_mode2 = hw->ledctl_default; - if (e1000_read_eeprom(hw, EEPROM_ID_LED_SETTINGS, 1, &eeprom_data) < 0) { + if(e1000_read_eeprom(hw, EEPROM_ID_LED_SETTINGS, 1, &eeprom_data) < 0) { DEBUGOUT("EEPROM Read Error\n"); return -E1000_ERR_EEPROM; } @@ -6009,7 +5997,7 @@ e1000_id_led_init(struct e1000_hw * hw) } for (i = 0; i < 4; i++) { temp = (eeprom_data >> (i << 2)) & led_mask; - switch (temp) { + switch(temp) { case ID_LED_ON1_DEF2: case ID_LED_ON1_ON2: case ID_LED_ON1_OFF2: @@ -6026,7 +6014,7 @@ e1000_id_led_init(struct e1000_hw * hw) /* Do nothing */ break; } - switch (temp) { + switch(temp) { case ID_LED_DEF1_ON2: case ID_LED_ON1_ON2: case ID_LED_OFF1_ON2: @@ -6060,7 +6048,7 @@ e1000_setup_led(struct e1000_hw *hw) DEBUGFUNC("e1000_setup_led"); - switch (hw->mac_type) { + switch(hw->mac_type) { case e1000_82542_rev2_0: case e1000_82542_rev2_1: case e1000_82543: @@ -6074,16 +6062,16 @@ e1000_setup_led(struct e1000_hw *hw) /* Turn off PHY Smart Power Down (if enabled) */ ret_val = e1000_read_phy_reg(hw, IGP01E1000_GMII_FIFO, &hw->phy_spd_default); - if (ret_val) + if(ret_val) return ret_val; ret_val = e1000_write_phy_reg(hw, IGP01E1000_GMII_FIFO, (uint16_t)(hw->phy_spd_default & ~IGP01E1000_GMII_SPD)); - if (ret_val) + if(ret_val) return ret_val; /* Fall Through */ default: - if (hw->media_type == e1000_media_type_fiber) { + if(hw->media_type == e1000_media_type_fiber) { ledctl = E1000_READ_REG(hw, LEDCTL); /* Save current LEDCTL settings */ hw->ledctl_default = ledctl; @@ -6094,7 +6082,7 @@ e1000_setup_led(struct e1000_hw *hw) ledctl |= (E1000_LEDCTL_MODE_LED_OFF << E1000_LEDCTL_LED0_MODE_SHIFT); E1000_WRITE_REG(hw, LEDCTL, ledctl); - } else if (hw->media_type == e1000_media_type_copper) + } else if(hw->media_type == e1000_media_type_copper) E1000_WRITE_REG(hw, LEDCTL, hw->ledctl_mode1); break; } @@ -6102,7 +6090,6 @@ e1000_setup_led(struct e1000_hw *hw) return E1000_SUCCESS; } - /****************************************************************************** * Used on 82571 and later Si that has LED blink bits. * Callers must use their own timer and should have already called @@ -6153,7 +6140,7 @@ e1000_cleanup_led(struct e1000_hw *hw) DEBUGFUNC("e1000_cleanup_led"); - switch (hw->mac_type) { + switch(hw->mac_type) { case e1000_82542_rev2_0: case e1000_82542_rev2_1: case e1000_82543: @@ -6167,7 +6154,7 @@ e1000_cleanup_led(struct e1000_hw *hw) /* Turn on PHY Smart Power Down (if previously enabled) */ ret_val = e1000_write_phy_reg(hw, IGP01E1000_GMII_FIFO, hw->phy_spd_default); - if (ret_val) + if(ret_val) return ret_val; /* Fall Through */ default: @@ -6195,7 +6182,7 @@ e1000_led_on(struct e1000_hw *hw) DEBUGFUNC("e1000_led_on"); - switch (hw->mac_type) { + switch(hw->mac_type) { case e1000_82542_rev2_0: case e1000_82542_rev2_1: case e1000_82543: @@ -6204,7 +6191,7 @@ e1000_led_on(struct e1000_hw *hw) ctrl |= E1000_CTRL_SWDPIO0; break; case e1000_82544: - if (hw->media_type == e1000_media_type_fiber) { + if(hw->media_type == e1000_media_type_fiber) { /* Set SW Defineable Pin 0 to turn on the LED */ ctrl |= E1000_CTRL_SWDPIN0; ctrl |= E1000_CTRL_SWDPIO0; @@ -6215,7 +6202,7 @@ e1000_led_on(struct e1000_hw *hw) } break; default: - if (hw->media_type == e1000_media_type_fiber) { + if(hw->media_type == e1000_media_type_fiber) { /* Clear SW Defineable Pin 0 to turn on the LED */ ctrl &= ~E1000_CTRL_SWDPIN0; ctrl |= E1000_CTRL_SWDPIO0; @@ -6246,7 +6233,7 @@ e1000_led_off(struct e1000_hw *hw) DEBUGFUNC("e1000_led_off"); - switch (hw->mac_type) { + switch(hw->mac_type) { case e1000_82542_rev2_0: case e1000_82542_rev2_1: case e1000_82543: @@ -6255,7 +6242,7 @@ e1000_led_off(struct e1000_hw *hw) ctrl |= E1000_CTRL_SWDPIO0; break; case e1000_82544: - if (hw->media_type == e1000_media_type_fiber) { + if(hw->media_type == e1000_media_type_fiber) { /* Clear SW Defineable Pin 0 to turn off the LED */ ctrl &= ~E1000_CTRL_SWDPIN0; ctrl |= E1000_CTRL_SWDPIO0; @@ -6266,7 +6253,7 @@ e1000_led_off(struct e1000_hw *hw) } break; default: - if (hw->media_type == e1000_media_type_fiber) { + if(hw->media_type == e1000_media_type_fiber) { /* Set SW Defineable Pin 0 to turn off the LED */ ctrl |= E1000_CTRL_SWDPIN0; ctrl |= E1000_CTRL_SWDPIO0; @@ -6290,7 +6277,7 @@ e1000_led_off(struct e1000_hw *hw) * * hw - Struct containing variables accessed by shared code *****************************************************************************/ -void +static void e1000_clear_hw_cntrs(struct e1000_hw *hw) { volatile uint32_t temp; @@ -6353,7 +6340,7 @@ e1000_clear_hw_cntrs(struct e1000_hw *hw) temp = E1000_READ_REG(hw, MPTC); temp = E1000_READ_REG(hw, BPTC); - if (hw->mac_type < e1000_82543) return; + if(hw->mac_type < e1000_82543) return; temp = E1000_READ_REG(hw, ALGNERRC); temp = E1000_READ_REG(hw, RXERRC); @@ -6362,13 +6349,13 @@ e1000_clear_hw_cntrs(struct e1000_hw *hw) temp = E1000_READ_REG(hw, TSCTC); temp = E1000_READ_REG(hw, TSCTFC); - if (hw->mac_type <= e1000_82544) return; + if(hw->mac_type <= e1000_82544) return; temp = E1000_READ_REG(hw, MGTPRC); temp = E1000_READ_REG(hw, MGTPDC); temp = E1000_READ_REG(hw, MGTPTC); - if (hw->mac_type <= e1000_82547_rev_2) return; + if(hw->mac_type <= e1000_82547_rev_2) return; temp = E1000_READ_REG(hw, IAC); temp = E1000_READ_REG(hw, ICRXOC); @@ -6399,8 +6386,8 @@ e1000_reset_adaptive(struct e1000_hw *hw) { DEBUGFUNC("e1000_reset_adaptive"); - if (hw->adaptive_ifs) { - if (!hw->ifs_params_forced) { + if(hw->adaptive_ifs) { + if(!hw->ifs_params_forced) { hw->current_ifs_val = 0; hw->ifs_min_val = IFS_MIN; hw->ifs_max_val = IFS_MAX; @@ -6427,12 +6414,12 @@ e1000_update_adaptive(struct e1000_hw *hw) { DEBUGFUNC("e1000_update_adaptive"); - if (hw->adaptive_ifs) { - if ((hw->collision_delta * hw->ifs_ratio) > hw->tx_packet_delta) { - if (hw->tx_packet_delta > MIN_NUM_XMITS) { + if(hw->adaptive_ifs) { + if((hw->collision_delta * hw->ifs_ratio) > hw->tx_packet_delta) { + if(hw->tx_packet_delta > MIN_NUM_XMITS) { hw->in_ifs_mode = TRUE; - if (hw->current_ifs_val < hw->ifs_max_val) { - if (hw->current_ifs_val == 0) + if(hw->current_ifs_val < hw->ifs_max_val) { + if(hw->current_ifs_val == 0) hw->current_ifs_val = hw->ifs_min_val; else hw->current_ifs_val += hw->ifs_step_size; @@ -6440,7 +6427,7 @@ e1000_update_adaptive(struct e1000_hw *hw) } } } else { - if (hw->in_ifs_mode && (hw->tx_packet_delta <= MIN_NUM_XMITS)) { + if(hw->in_ifs_mode && (hw->tx_packet_delta <= MIN_NUM_XMITS)) { hw->current_ifs_val = 0; hw->in_ifs_mode = FALSE; E1000_WRITE_REG(hw, AIT, 0); @@ -6487,46 +6474,46 @@ e1000_tbi_adjust_stats(struct e1000_hw *hw, * This could be simplified if all environments supported * 64-bit integers. */ - if (carry_bit && ((stats->gorcl & 0x80000000) == 0)) + if(carry_bit && ((stats->gorcl & 0x80000000) == 0)) stats->gorch++; /* Is this a broadcast or multicast? Check broadcast first, * since the test for a multicast frame will test positive on * a broadcast frame. */ - if ((mac_addr[0] == (uint8_t) 0xff) && (mac_addr[1] == (uint8_t) 0xff)) + if((mac_addr[0] == (uint8_t) 0xff) && (mac_addr[1] == (uint8_t) 0xff)) /* Broadcast packet */ stats->bprc++; - else if (*mac_addr & 0x01) + else if(*mac_addr & 0x01) /* Multicast packet */ stats->mprc++; - if (frame_len == hw->max_frame_size) { + if(frame_len == hw->max_frame_size) { /* In this case, the hardware has overcounted the number of * oversize frames. */ - if (stats->roc > 0) + if(stats->roc > 0) stats->roc--; } /* Adjust the bin counters when the extra byte put the frame in the * wrong bin. Remember that the frame_len was adjusted above. */ - if (frame_len == 64) { + if(frame_len == 64) { stats->prc64++; stats->prc127--; - } else if (frame_len == 127) { + } else if(frame_len == 127) { stats->prc127++; stats->prc255--; - } else if (frame_len == 255) { + } else if(frame_len == 255) { stats->prc255++; stats->prc511--; - } else if (frame_len == 511) { + } else if(frame_len == 511) { stats->prc511++; stats->prc1023--; - } else if (frame_len == 1023) { + } else if(frame_len == 1023) { stats->prc1023++; stats->prc1522--; - } else if (frame_len == 1522) { + } else if(frame_len == 1522) { stats->prc1522++; } } @@ -6566,10 +6553,10 @@ e1000_get_bus_info(struct e1000_hw *hw) hw->bus_type = (status & E1000_STATUS_PCIX_MODE) ? e1000_bus_type_pcix : e1000_bus_type_pci; - if (hw->device_id == E1000_DEV_ID_82546EB_QUAD_COPPER) { + if(hw->device_id == E1000_DEV_ID_82546EB_QUAD_COPPER) { hw->bus_speed = (hw->bus_type == e1000_bus_type_pci) ? e1000_bus_speed_66 : e1000_bus_speed_120; - } else if (hw->bus_type == e1000_bus_type_pci) { + } else if(hw->bus_type == e1000_bus_type_pci) { hw->bus_speed = (status & E1000_STATUS_PCI66) ? e1000_bus_speed_66 : e1000_bus_speed_33; } else { @@ -6600,7 +6587,6 @@ e1000_get_bus_info(struct e1000_hw *hw) * hw - Struct containing variables accessed by shared code * offset - offset to read from *****************************************************************************/ -#if 0 uint32_t e1000_read_reg_io(struct e1000_hw *hw, uint32_t offset) @@ -6611,7 +6597,6 @@ e1000_read_reg_io(struct e1000_hw *hw, e1000_io_write(hw, io_addr, offset); return e1000_io_read(hw, io_data); } -#endif /* 0 */ /****************************************************************************** * Writes a value to one of the devices registers using port I/O (as opposed to @@ -6664,11 +6649,11 @@ e1000_get_cable_length(struct e1000_hw *hw, *min_length = *max_length = 0; /* Use old method for Phy older than IGP */ - if (hw->phy_type == e1000_phy_m88) { + if(hw->phy_type == e1000_phy_m88) { ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data); - if (ret_val) + if(ret_val) return ret_val; cable_length = (phy_data & M88E1000_PSSR_CABLE_LENGTH) >> M88E1000_PSSR_CABLE_LENGTH_SHIFT; @@ -6727,7 +6712,7 @@ e1000_get_cable_length(struct e1000_hw *hw, return -E1000_ERR_PHY; break; } - } else if (hw->phy_type == e1000_phy_igp) { /* For IGP PHY */ + } else if(hw->phy_type == e1000_phy_igp) { /* For IGP PHY */ uint16_t cur_agc_value; uint16_t min_agc_value = IGP01E1000_AGC_LENGTH_TABLE_SIZE; uint16_t agc_reg_array[IGP01E1000_PHY_CHANNEL_NUM] = @@ -6736,10 +6721,10 @@ e1000_get_cable_length(struct e1000_hw *hw, IGP01E1000_PHY_AGC_C, IGP01E1000_PHY_AGC_D}; /* Read the AGC registers for all channels */ - for (i = 0; i < IGP01E1000_PHY_CHANNEL_NUM; i++) { + for(i = 0; i < IGP01E1000_PHY_CHANNEL_NUM; i++) { ret_val = e1000_read_phy_reg(hw, agc_reg_array[i], &phy_data); - if (ret_val) + if(ret_val) return ret_val; cur_agc_value = phy_data >> IGP01E1000_AGC_LENGTH_SHIFT; @@ -6789,7 +6774,7 @@ e1000_get_cable_length(struct e1000_hw *hw, if (ret_val) return ret_val; - /* Getting bits 15:9, which represent the combination of course and + /* Getting bits 15:9, which represent the combination of course and * fine gain values. The result is a number that can be put into * the lookup table to obtain the approximate cable length. */ cur_agc_index = (phy_data >> IGP02E1000_AGC_LENGTH_SHIFT) & @@ -6854,7 +6839,7 @@ e1000_check_polarity(struct e1000_hw *hw, /* return the Polarity bit in the Status register. */ ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data); - if (ret_val) + if(ret_val) return ret_val; *polarity = (phy_data & M88E1000_PSSR_REV_POLARITY) >> M88E1000_PSSR_REV_POLARITY_SHIFT; @@ -6864,18 +6849,18 @@ e1000_check_polarity(struct e1000_hw *hw, /* Read the Status register to check the speed */ ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS, &phy_data); - if (ret_val) + if(ret_val) return ret_val; /* If speed is 1000 Mbps, must read the IGP01E1000_PHY_PCS_INIT_REG to * find the polarity status */ - if ((phy_data & IGP01E1000_PSSR_SPEED_MASK) == + if((phy_data & IGP01E1000_PSSR_SPEED_MASK) == IGP01E1000_PSSR_SPEED_1000MBPS) { /* Read the GIG initialization PCS register (0x00B4) */ ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PCS_INIT_REG, &phy_data); - if (ret_val) + if(ret_val) return ret_val; /* Check the polarity bits */ @@ -6924,7 +6909,7 @@ e1000_check_downshift(struct e1000_hw *hw) hw->phy_type == e1000_phy_igp_2) { ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_LINK_HEALTH, &phy_data); - if (ret_val) + if(ret_val) return ret_val; hw->speed_downgraded = (phy_data & IGP01E1000_PLHR_SS_DOWNGRADE) ? 1 : 0; @@ -6932,7 +6917,7 @@ e1000_check_downshift(struct e1000_hw *hw) (hw->phy_type == e1000_phy_gg82563)) { ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data); - if (ret_val) + if(ret_val) return ret_val; hw->speed_downgraded = (phy_data & M88E1000_PSSR_DOWNSHIFT) >> @@ -6972,42 +6957,42 @@ e1000_config_dsp_after_link_change(struct e1000_hw *hw, DEBUGFUNC("e1000_config_dsp_after_link_change"); - if (hw->phy_type != e1000_phy_igp) + if(hw->phy_type != e1000_phy_igp) return E1000_SUCCESS; - if (link_up) { + if(link_up) { ret_val = e1000_get_speed_and_duplex(hw, &speed, &duplex); - if (ret_val) { + if(ret_val) { DEBUGOUT("Error getting link speed and duplex\n"); return ret_val; } - if (speed == SPEED_1000) { + if(speed == SPEED_1000) { ret_val = e1000_get_cable_length(hw, &min_length, &max_length); if (ret_val) return ret_val; - if ((hw->dsp_config_state == e1000_dsp_config_enabled) && + if((hw->dsp_config_state == e1000_dsp_config_enabled) && min_length >= e1000_igp_cable_length_50) { - for (i = 0; i < IGP01E1000_PHY_CHANNEL_NUM; i++) { + for(i = 0; i < IGP01E1000_PHY_CHANNEL_NUM; i++) { ret_val = e1000_read_phy_reg(hw, dsp_reg_array[i], &phy_data); - if (ret_val) + if(ret_val) return ret_val; phy_data &= ~IGP01E1000_PHY_EDAC_MU_INDEX; ret_val = e1000_write_phy_reg(hw, dsp_reg_array[i], phy_data); - if (ret_val) + if(ret_val) return ret_val; } hw->dsp_config_state = e1000_dsp_config_activated; } - if ((hw->ffe_config_state == e1000_ffe_config_enabled) && + if((hw->ffe_config_state == e1000_ffe_config_enabled) && (min_length < e1000_igp_cable_length_50)) { uint16_t ffe_idle_err_timeout = FFE_IDLE_ERR_COUNT_TIMEOUT_20; @@ -7016,70 +7001,70 @@ e1000_config_dsp_after_link_change(struct e1000_hw *hw, /* clear previous idle error counts */ ret_val = e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_data); - if (ret_val) + if(ret_val) return ret_val; - for (i = 0; i < ffe_idle_err_timeout; i++) { + for(i = 0; i < ffe_idle_err_timeout; i++) { udelay(1000); ret_val = e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_data); - if (ret_val) + if(ret_val) return ret_val; idle_errs += (phy_data & SR_1000T_IDLE_ERROR_CNT); - if (idle_errs > SR_1000T_PHY_EXCESSIVE_IDLE_ERR_COUNT) { + if(idle_errs > SR_1000T_PHY_EXCESSIVE_IDLE_ERR_COUNT) { hw->ffe_config_state = e1000_ffe_config_active; ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_DSP_FFE, IGP01E1000_PHY_DSP_FFE_CM_CP); - if (ret_val) + if(ret_val) return ret_val; break; } - if (idle_errs) + if(idle_errs) ffe_idle_err_timeout = FFE_IDLE_ERR_COUNT_TIMEOUT_100; } } } } else { - if (hw->dsp_config_state == e1000_dsp_config_activated) { + if(hw->dsp_config_state == e1000_dsp_config_activated) { /* Save off the current value of register 0x2F5B to be restored at * the end of the routines. */ ret_val = e1000_read_phy_reg(hw, 0x2F5B, &phy_saved_data); - if (ret_val) + if(ret_val) return ret_val; /* Disable the PHY transmitter */ ret_val = e1000_write_phy_reg(hw, 0x2F5B, 0x0003); - if (ret_val) + if(ret_val) return ret_val; msec_delay_irq(20); ret_val = e1000_write_phy_reg(hw, 0x0000, IGP01E1000_IEEE_FORCE_GIGA); - if (ret_val) + if(ret_val) return ret_val; - for (i = 0; i < IGP01E1000_PHY_CHANNEL_NUM; i++) { + for(i = 0; i < IGP01E1000_PHY_CHANNEL_NUM; i++) { ret_val = e1000_read_phy_reg(hw, dsp_reg_array[i], &phy_data); - if (ret_val) + if(ret_val) return ret_val; phy_data &= ~IGP01E1000_PHY_EDAC_MU_INDEX; phy_data |= IGP01E1000_PHY_EDAC_SIGN_EXT_9_BITS; ret_val = e1000_write_phy_reg(hw,dsp_reg_array[i], phy_data); - if (ret_val) + if(ret_val) return ret_val; } ret_val = e1000_write_phy_reg(hw, 0x0000, IGP01E1000_IEEE_RESTART_AUTONEG); - if (ret_val) + if(ret_val) return ret_val; msec_delay_irq(20); @@ -7087,40 +7072,40 @@ e1000_config_dsp_after_link_change(struct e1000_hw *hw, /* Now enable the transmitter */ ret_val = e1000_write_phy_reg(hw, 0x2F5B, phy_saved_data); - if (ret_val) + if(ret_val) return ret_val; hw->dsp_config_state = e1000_dsp_config_enabled; } - if (hw->ffe_config_state == e1000_ffe_config_active) { + if(hw->ffe_config_state == e1000_ffe_config_active) { /* Save off the current value of register 0x2F5B to be restored at * the end of the routines. */ ret_val = e1000_read_phy_reg(hw, 0x2F5B, &phy_saved_data); - if (ret_val) + if(ret_val) return ret_val; /* Disable the PHY transmitter */ ret_val = e1000_write_phy_reg(hw, 0x2F5B, 0x0003); - if (ret_val) + if(ret_val) return ret_val; msec_delay_irq(20); ret_val = e1000_write_phy_reg(hw, 0x0000, IGP01E1000_IEEE_FORCE_GIGA); - if (ret_val) + if(ret_val) return ret_val; ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_DSP_FFE, IGP01E1000_PHY_DSP_FFE_DEFAULT); - if (ret_val) + if(ret_val) return ret_val; ret_val = e1000_write_phy_reg(hw, 0x0000, IGP01E1000_IEEE_RESTART_AUTONEG); - if (ret_val) + if(ret_val) return ret_val; msec_delay_irq(20); @@ -7128,7 +7113,7 @@ e1000_config_dsp_after_link_change(struct e1000_hw *hw, /* Now enable the transmitter */ ret_val = e1000_write_phy_reg(hw, 0x2F5B, phy_saved_data); - if (ret_val) + if(ret_val) return ret_val; hw->ffe_config_state = e1000_ffe_config_enabled; @@ -7153,20 +7138,20 @@ e1000_set_phy_mode(struct e1000_hw *hw) DEBUGFUNC("e1000_set_phy_mode"); - if ((hw->mac_type == e1000_82545_rev_3) && - (hw->media_type == e1000_media_type_copper)) { + if((hw->mac_type == e1000_82545_rev_3) && + (hw->media_type == e1000_media_type_copper)) { ret_val = e1000_read_eeprom(hw, EEPROM_PHY_CLASS_WORD, 1, &eeprom_data); - if (ret_val) { + if(ret_val) { return ret_val; } - if ((eeprom_data != EEPROM_RESERVED_WORD) && - (eeprom_data & EEPROM_PHY_CLASS_A)) { + if((eeprom_data != EEPROM_RESERVED_WORD) && + (eeprom_data & EEPROM_PHY_CLASS_A)) { ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x000B); - if (ret_val) + if(ret_val) return ret_val; ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0x8104); - if (ret_val) + if(ret_val) return ret_val; hw->phy_reset_disable = FALSE; @@ -7217,16 +7202,16 @@ e1000_set_d3_lplu_state(struct e1000_hw *hw, phy_ctrl = E1000_READ_REG(hw, PHY_CTRL); } else { ret_val = e1000_read_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, &phy_data); - if (ret_val) + if(ret_val) return ret_val; } - if (!active) { - if (hw->mac_type == e1000_82541_rev_2 || - hw->mac_type == e1000_82547_rev_2) { + if(!active) { + if(hw->mac_type == e1000_82541_rev_2 || + hw->mac_type == e1000_82547_rev_2) { phy_data &= ~IGP01E1000_GMII_FLEX_SPD; ret_val = e1000_write_phy_reg(hw, IGP01E1000_GMII_FIFO, phy_data); - if (ret_val) + if(ret_val) return ret_val; } else { if (hw->mac_type == e1000_ich8lan) { @@ -7248,13 +7233,13 @@ e1000_set_d3_lplu_state(struct e1000_hw *hw, if (hw->smart_speed == e1000_smart_speed_on) { ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, &phy_data); - if (ret_val) + if(ret_val) return ret_val; phy_data |= IGP01E1000_PSCFR_SMART_SPEED; ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, phy_data); - if (ret_val) + if(ret_val) return ret_val; } else if (hw->smart_speed == e1000_smart_speed_off) { ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, @@ -7265,19 +7250,19 @@ e1000_set_d3_lplu_state(struct e1000_hw *hw, phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED; ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, phy_data); - if (ret_val) + if(ret_val) return ret_val; } - } else if ((hw->autoneg_advertised == AUTONEG_ADVERTISE_SPEED_DEFAULT) || - (hw->autoneg_advertised == AUTONEG_ADVERTISE_10_ALL ) || - (hw->autoneg_advertised == AUTONEG_ADVERTISE_10_100_ALL)) { + } else if((hw->autoneg_advertised == AUTONEG_ADVERTISE_SPEED_DEFAULT) || + (hw->autoneg_advertised == AUTONEG_ADVERTISE_10_ALL ) || + (hw->autoneg_advertised == AUTONEG_ADVERTISE_10_100_ALL)) { - if (hw->mac_type == e1000_82541_rev_2 || + if(hw->mac_type == e1000_82541_rev_2 || hw->mac_type == e1000_82547_rev_2) { phy_data |= IGP01E1000_GMII_FLEX_SPD; ret_val = e1000_write_phy_reg(hw, IGP01E1000_GMII_FIFO, phy_data); - if (ret_val) + if(ret_val) return ret_val; } else { if (hw->mac_type == e1000_ich8lan) { @@ -7294,12 +7279,12 @@ e1000_set_d3_lplu_state(struct e1000_hw *hw, /* When LPLU is enabled we should disable SmartSpeed */ ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, &phy_data); - if (ret_val) + if(ret_val) return ret_val; phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED; ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, phy_data); - if (ret_val) + if(ret_val) return ret_val; } @@ -7329,14 +7314,14 @@ e1000_set_d0_lplu_state(struct e1000_hw *hw, uint16_t phy_data; DEBUGFUNC("e1000_set_d0_lplu_state"); - if (hw->mac_type <= e1000_82547_rev_2) + if(hw->mac_type <= e1000_82547_rev_2) return E1000_SUCCESS; if (hw->mac_type == e1000_ich8lan) { phy_ctrl = E1000_READ_REG(hw, PHY_CTRL); } else { ret_val = e1000_read_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, &phy_data); - if (ret_val) + if(ret_val) return ret_val; } @@ -7358,13 +7343,13 @@ e1000_set_d0_lplu_state(struct e1000_hw *hw, if (hw->smart_speed == e1000_smart_speed_on) { ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, &phy_data); - if (ret_val) + if(ret_val) return ret_val; phy_data |= IGP01E1000_PSCFR_SMART_SPEED; ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, phy_data); - if (ret_val) + if(ret_val) return ret_val; } else if (hw->smart_speed == e1000_smart_speed_off) { ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, @@ -7375,7 +7360,7 @@ e1000_set_d0_lplu_state(struct e1000_hw *hw, phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED; ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, phy_data); - if (ret_val) + if(ret_val) return ret_val; } @@ -7394,12 +7379,12 @@ e1000_set_d0_lplu_state(struct e1000_hw *hw, /* When LPLU is enabled we should disable SmartSpeed */ ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, &phy_data); - if (ret_val) + if(ret_val) return ret_val; phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED; ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, phy_data); - if (ret_val) + if(ret_val) return ret_val; } @@ -7420,7 +7405,7 @@ e1000_set_vco_speed(struct e1000_hw *hw) DEBUGFUNC("e1000_set_vco_speed"); - switch (hw->mac_type) { + switch(hw->mac_type) { case e1000_82545_rev_3: case e1000_82546_rev_3: break; @@ -7431,39 +7416,39 @@ e1000_set_vco_speed(struct e1000_hw *hw) /* Set PHY register 30, page 5, bit 8 to 0 */ ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, &default_page); - if (ret_val) + if(ret_val) return ret_val; ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0005); - if (ret_val) + if(ret_val) return ret_val; ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, &phy_data); - if (ret_val) + if(ret_val) return ret_val; phy_data &= ~M88E1000_PHY_VCO_REG_BIT8; ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, phy_data); - if (ret_val) + if(ret_val) return ret_val; /* Set PHY register 30, page 4, bit 11 to 1 */ ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0004); - if (ret_val) + if(ret_val) return ret_val; ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, &phy_data); - if (ret_val) + if(ret_val) return ret_val; phy_data |= M88E1000_PHY_VCO_REG_BIT11; ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, phy_data); - if (ret_val) + if(ret_val) return ret_val; ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, default_page); - if (ret_val) + if(ret_val) return ret_val; return E1000_SUCCESS; @@ -7542,7 +7527,7 @@ e1000_mng_host_if_write(struct e1000_hw * hw, uint8_t *buffer, { uint8_t *tmp; uint8_t *bufptr = buffer; - uint32_t data = 0; + uint32_t data; uint16_t remaining, i, j, prev_bytes; /* sum = only sum of the data and it is not checksum */ @@ -7622,7 +7607,7 @@ e1000_mng_write_cmd_header(struct e1000_hw * hw, buffer = (uint8_t *) hdr; i = length; - while (i--) + while(i--) sum += buffer[i]; hdr->checksum = 0 - sum; @@ -7645,7 +7630,8 @@ e1000_mng_write_cmd_header(struct e1000_hw * hw, * returns - E1000_SUCCESS for success. ****************************************************************************/ static int32_t -e1000_mng_write_commit(struct e1000_hw * hw) +e1000_mng_write_commit( + struct e1000_hw * hw) { uint32_t hicr; @@ -7817,31 +7803,31 @@ e1000_polarity_reversal_workaround(struct e1000_hw *hw) /* Disable the transmitter on the PHY */ ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0019); - if (ret_val) + if(ret_val) return ret_val; ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xFFFF); - if (ret_val) + if(ret_val) return ret_val; ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0000); - if (ret_val) + if(ret_val) return ret_val; /* This loop will early-out if the NO link condition has been met. */ - for (i = PHY_FORCE_TIME; i > 0; i--) { + for(i = PHY_FORCE_TIME; i > 0; i--) { /* Read the MII Status Register and wait for Link Status bit * to be clear. */ ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg); - if (ret_val) + if(ret_val) return ret_val; ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg); - if (ret_val) + if(ret_val) return ret_val; - if ((mii_status_reg & ~MII_SR_LINK_STATUS) == 0) break; + if((mii_status_reg & ~MII_SR_LINK_STATUS) == 0) break; msec_delay_irq(100); } @@ -7851,40 +7837,40 @@ e1000_polarity_reversal_workaround(struct e1000_hw *hw) /* Now we will re-enable th transmitter on the PHY */ ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0019); - if (ret_val) + if(ret_val) return ret_val; msec_delay_irq(50); ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xFFF0); - if (ret_val) + if(ret_val) return ret_val; msec_delay_irq(50); ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xFF00); - if (ret_val) + if(ret_val) return ret_val; msec_delay_irq(50); ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0x0000); - if (ret_val) + if(ret_val) return ret_val; ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0000); - if (ret_val) + if(ret_val) return ret_val; /* This loop will early-out if the link condition has been met. */ - for (i = PHY_FORCE_TIME; i > 0; i--) { + for(i = PHY_FORCE_TIME; i > 0; i--) { /* Read the MII Status Register and wait for Link Status bit * to be set. */ ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg); - if (ret_val) + if(ret_val) return ret_val; ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg); - if (ret_val) + if(ret_val) return ret_val; - if (mii_status_reg & MII_SR_LINK_STATUS) break; + if(mii_status_reg & MII_SR_LINK_STATUS) break; msec_delay_irq(100); } return E1000_SUCCESS; @@ -7923,7 +7909,6 @@ e1000_set_pci_express_master_disable(struct e1000_hw *hw) * returns: - none. * ***************************************************************************/ -#if 0 void e1000_enable_pciex_master(struct e1000_hw *hw) { @@ -7938,7 +7923,6 @@ e1000_enable_pciex_master(struct e1000_hw *hw) ctrl &= ~E1000_CTRL_GIO_MASTER_DISABLE; E1000_WRITE_REG(hw, CTRL, ctrl); } -#endif /* 0 */ /******************************************************************************* * @@ -7963,15 +7947,15 @@ e1000_disable_pciex_master(struct e1000_hw *hw) e1000_set_pci_express_master_disable(hw); - while (timeout) { - if (!(E1000_READ_REG(hw, STATUS) & E1000_STATUS_GIO_MASTER_ENABLE)) + while(timeout) { + if(!(E1000_READ_REG(hw, STATUS) & E1000_STATUS_GIO_MASTER_ENABLE)) break; else udelay(100); timeout--; } - if (!timeout) { + if(!timeout) { DEBUGOUT("Master requests are pending.\n"); return -E1000_ERR_MASTER_REQUESTS_PENDING; } @@ -8012,7 +7996,7 @@ e1000_get_auto_rd_done(struct e1000_hw *hw) timeout--; } - if (!timeout) { + if(!timeout) { DEBUGOUT("Auto read by HW from EEPROM has not completed.\n"); return -E1000_ERR_RESET; } @@ -8093,7 +8077,7 @@ e1000_get_hw_eeprom_semaphore(struct e1000_hw *hw) DEBUGFUNC("e1000_get_hw_eeprom_semaphore"); - if (!hw->eeprom_semaphore_present) + if(!hw->eeprom_semaphore_present) return E1000_SUCCESS; if (hw->mac_type == e1000_80003es2lan) { @@ -8104,20 +8088,20 @@ e1000_get_hw_eeprom_semaphore(struct e1000_hw *hw) /* Get the FW semaphore. */ timeout = hw->eeprom.word_size + 1; - while (timeout) { + while(timeout) { swsm = E1000_READ_REG(hw, SWSM); swsm |= E1000_SWSM_SWESMBI; E1000_WRITE_REG(hw, SWSM, swsm); /* if we managed to set the bit we got the semaphore. */ swsm = E1000_READ_REG(hw, SWSM); - if (swsm & E1000_SWSM_SWESMBI) + if(swsm & E1000_SWSM_SWESMBI) break; udelay(50); timeout--; } - if (!timeout) { + if(!timeout) { /* Release semaphores */ e1000_put_hw_eeprom_semaphore(hw); DEBUGOUT("Driver can't access the Eeprom - SWESMBI bit is set.\n"); @@ -8142,7 +8126,7 @@ e1000_put_hw_eeprom_semaphore(struct e1000_hw *hw) DEBUGFUNC("e1000_put_hw_eeprom_semaphore"); - if (!hw->eeprom_semaphore_present) + if(!hw->eeprom_semaphore_present) return; swsm = E1000_READ_REG(hw, SWSM); @@ -8164,7 +8148,7 @@ e1000_put_hw_eeprom_semaphore(struct e1000_hw *hw) * E1000_SUCCESS at any other case. * ***************************************************************************/ -static int32_t +int32_t e1000_get_software_semaphore(struct e1000_hw *hw) { int32_t timeout = hw->eeprom.word_size + 1; @@ -8175,16 +8159,16 @@ e1000_get_software_semaphore(struct e1000_hw *hw) if (hw->mac_type != e1000_80003es2lan) return E1000_SUCCESS; - while (timeout) { + while(timeout) { swsm = E1000_READ_REG(hw, SWSM); /* If SMBI bit cleared, it is now set and we hold the semaphore */ - if (!(swsm & E1000_SWSM_SMBI)) + if(!(swsm & E1000_SWSM_SMBI)) break; msec_delay_irq(1); timeout--; } - if (!timeout) { + if(!timeout) { DEBUGOUT("Driver can't access device - SMBI bit is set.\n"); return -E1000_ERR_RESET; } @@ -8199,7 +8183,7 @@ e1000_get_software_semaphore(struct e1000_hw *hw) * hw: Struct containing variables accessed by shared code * ***************************************************************************/ -static void +void e1000_release_software_semaphore(struct e1000_hw *hw) { uint32_t swsm; @@ -8260,7 +8244,7 @@ e1000_arc_subsystem_valid(struct e1000_hw *hw) case e1000_82573: case e1000_80003es2lan: fwsm = E1000_READ_REG(hw, FWSM); - if ((fwsm & E1000_FWSM_MODE_MASK) != 0) + if((fwsm & E1000_FWSM_MODE_MASK) != 0) return TRUE; break; case e1000_ich8lan: @@ -8281,7 +8265,7 @@ e1000_arc_subsystem_valid(struct e1000_hw *hw) * returns: E1000_SUCCESS * *****************************************************************************/ -static int32_t +int32_t e1000_set_pci_ex_no_snoop(struct e1000_hw *hw, uint32_t no_snoop) { uint32_t gcr_reg = 0; @@ -8322,7 +8306,7 @@ e1000_set_pci_ex_no_snoop(struct e1000_hw *hw, uint32_t no_snoop) * hw: Struct containing variables accessed by shared code * ***************************************************************************/ -static int32_t +int32_t e1000_get_software_flag(struct e1000_hw *hw) { int32_t timeout = PHY_CFG_TIMEOUT; @@ -8361,7 +8345,7 @@ e1000_get_software_flag(struct e1000_hw *hw) * hw: Struct containing variables accessed by shared code * ***************************************************************************/ -static void +void e1000_release_software_flag(struct e1000_hw *hw) { uint32_t extcnf_ctrl; @@ -8385,7 +8369,6 @@ e1000_release_software_flag(struct e1000_hw *hw) * hw: Struct containing variables accessed by shared code * ***************************************************************************/ -#if 0 int32_t e1000_ife_disable_dynamic_power_down(struct e1000_hw *hw) { @@ -8405,7 +8388,6 @@ e1000_ife_disable_dynamic_power_down(struct e1000_hw *hw) return ret_val; } -#endif /* 0 */ /*************************************************************************** * @@ -8415,7 +8397,6 @@ e1000_ife_disable_dynamic_power_down(struct e1000_hw *hw) * hw: Struct containing variables accessed by shared code * ***************************************************************************/ -#if 0 int32_t e1000_ife_enable_dynamic_power_down(struct e1000_hw *hw) { @@ -8435,7 +8416,6 @@ e1000_ife_enable_dynamic_power_down(struct e1000_hw *hw) return ret_val; } -#endif /* 0 */ /****************************************************************************** * Reads a 16 bit word or words from the EEPROM using the ICH8's flash access @@ -8446,7 +8426,7 @@ e1000_ife_enable_dynamic_power_down(struct e1000_hw *hw) * data - word read from the EEPROM * words - number of words to read *****************************************************************************/ -static int32_t +int32_t e1000_read_eeprom_ich8(struct e1000_hw *hw, uint16_t offset, uint16_t words, uint16_t *data) { @@ -8502,7 +8482,7 @@ e1000_read_eeprom_ich8(struct e1000_hw *hw, uint16_t offset, uint16_t words, * words - number of words to write * data - words to write to the EEPROM *****************************************************************************/ -static int32_t +int32_t e1000_write_eeprom_ich8(struct e1000_hw *hw, uint16_t offset, uint16_t words, uint16_t *data) { @@ -8549,7 +8529,7 @@ e1000_write_eeprom_ich8(struct e1000_hw *hw, uint16_t offset, uint16_t words, * * hw - The pointer to the hw structure ****************************************************************************/ -static int32_t +int32_t e1000_ich8_cycle_init(struct e1000_hw *hw) { union ich8_hws_flash_status hsfsts; @@ -8616,7 +8596,7 @@ e1000_ich8_cycle_init(struct e1000_hw *hw) * * hw - The pointer to the hw structure ****************************************************************************/ -static int32_t +int32_t e1000_ich8_flash_cycle(struct e1000_hw *hw, uint32_t timeout) { union ich8_hws_flash_ctrl hsflctl; @@ -8651,7 +8631,7 @@ e1000_ich8_flash_cycle(struct e1000_hw *hw, uint32_t timeout) * size - Size of data to read, 1=byte 2=word * data - Pointer to the word to store the value read. *****************************************************************************/ -static int32_t +int32_t e1000_read_ich8_data(struct e1000_hw *hw, uint32_t index, uint32_t size, uint16_t* data) { @@ -8730,7 +8710,7 @@ e1000_read_ich8_data(struct e1000_hw *hw, uint32_t index, * size - Size of data to read, 1=byte 2=word * data - The byte(s) to write to the NVM. *****************************************************************************/ -static int32_t +int32_t e1000_write_ich8_data(struct e1000_hw *hw, uint32_t index, uint32_t size, uint16_t data) { @@ -8805,7 +8785,7 @@ e1000_write_ich8_data(struct e1000_hw *hw, uint32_t index, uint32_t size, * index - The index of the byte to read. * data - Pointer to a byte to store the value read. *****************************************************************************/ -static int32_t +int32_t e1000_read_ich8_byte(struct e1000_hw *hw, uint32_t index, uint8_t* data) { int32_t status = E1000_SUCCESS; @@ -8828,7 +8808,7 @@ e1000_read_ich8_byte(struct e1000_hw *hw, uint32_t index, uint8_t* data) * index - The index of the byte to write. * byte - The byte to write to the NVM. *****************************************************************************/ -static int32_t +int32_t e1000_verify_write_ich8_byte(struct e1000_hw *hw, uint32_t index, uint8_t byte) { int32_t error = E1000_SUCCESS; @@ -8859,7 +8839,7 @@ e1000_verify_write_ich8_byte(struct e1000_hw *hw, uint32_t index, uint8_t byte) * index - The index of the byte to read. * data - The byte to write to the NVM. *****************************************************************************/ -static int32_t +int32_t e1000_write_ich8_byte(struct e1000_hw *hw, uint32_t index, uint8_t data) { int32_t status = E1000_SUCCESS; @@ -8877,7 +8857,7 @@ e1000_write_ich8_byte(struct e1000_hw *hw, uint32_t index, uint8_t data) * index - The starting byte index of the word to read. * data - Pointer to a word to store the value read. *****************************************************************************/ -static int32_t +int32_t e1000_read_ich8_word(struct e1000_hw *hw, uint32_t index, uint16_t *data) { int32_t status = E1000_SUCCESS; @@ -8892,7 +8872,6 @@ e1000_read_ich8_word(struct e1000_hw *hw, uint32_t index, uint16_t *data) * index - The starting byte index of the word to read. * data - The word to write to the NVM. *****************************************************************************/ -#if 0 int32_t e1000_write_ich8_word(struct e1000_hw *hw, uint32_t index, uint16_t data) { @@ -8900,7 +8879,6 @@ e1000_write_ich8_word(struct e1000_hw *hw, uint32_t index, uint16_t data) status = e1000_write_ich8_data(hw, index, 2, data); return status; } -#endif /* 0 */ /****************************************************************************** * Erases the bank specified. Each bank is a 4k block. Segments are 0 based. @@ -8909,7 +8887,7 @@ e1000_write_ich8_word(struct e1000_hw *hw, uint32_t index, uint16_t data) * hw - pointer to e1000_hw structure * segment - 0 for first segment, 1 for second segment, etc. *****************************************************************************/ -static int32_t +int32_t e1000_erase_ich8_4k_segment(struct e1000_hw *hw, uint32_t segment) { union ich8_hws_flash_status hsfsts; @@ -9006,7 +8984,6 @@ e1000_erase_ich8_4k_segment(struct e1000_hw *hw, uint32_t segment) * hw: Struct containing variables accessed by shared code * *****************************************************************************/ -#if 0 int32_t e1000_duplex_reversal(struct e1000_hw *hw) { @@ -9035,9 +9012,8 @@ e1000_duplex_reversal(struct e1000_hw *hw) return ret_val; } -#endif /* 0 */ -static int32_t +int32_t e1000_init_lcd_from_nvm_config_region(struct e1000_hw *hw, uint32_t cnf_base_addr, uint32_t cnf_size) { @@ -9071,7 +9047,7 @@ e1000_init_lcd_from_nvm_config_region(struct e1000_hw *hw, } -static int32_t +int32_t e1000_init_lcd_from_nvm(struct e1000_hw *hw) { uint32_t reg_data, cnf_base_addr, cnf_size, ret_val, loop; diff --git a/trunk/drivers/net/e1000/e1000_hw.h b/trunk/drivers/net/e1000/e1000_hw.h index a170e96251f6..f9341e3276b3 100644 --- a/trunk/drivers/net/e1000/e1000_hw.h +++ b/trunk/drivers/net/e1000/e1000_hw.h @@ -323,8 +323,13 @@ int32_t e1000_write_phy_reg(struct e1000_hw *hw, uint32_t reg_addr, uint16_t dat int32_t e1000_phy_hw_reset(struct e1000_hw *hw); int32_t e1000_phy_reset(struct e1000_hw *hw); void e1000_phy_powerdown_workaround(struct e1000_hw *hw); +int32_t e1000_kumeran_lock_loss_workaround(struct e1000_hw *hw); +int32_t e1000_init_lcd_from_nvm_config_region(struct e1000_hw *hw, uint32_t cnf_base_addr, uint32_t cnf_size); +int32_t e1000_init_lcd_from_nvm(struct e1000_hw *hw); int32_t e1000_phy_get_info(struct e1000_hw *hw, struct e1000_phy_info *phy_info); int32_t e1000_validate_mdi_setting(struct e1000_hw *hw); +int32_t e1000_read_kmrn_reg(struct e1000_hw *hw, uint32_t reg_addr, uint16_t *data); +int32_t e1000_write_kmrn_reg(struct e1000_hw *hw, uint32_t reg_addr, uint16_t data); /* EEPROM Functions */ int32_t e1000_init_eeprom_params(struct e1000_hw *hw); @@ -336,9 +341,9 @@ uint32_t e1000_enable_mng_pass_thru(struct e1000_hw *hw); #define E1000_HI_MAX_MNG_DATA_LENGTH 0x6F8 /* Host Interface data length */ #define E1000_MNG_DHCP_COMMAND_TIMEOUT 10 /* Time in ms to process MNG command */ -#define E1000_MNG_DHCP_COOKIE_OFFSET 0x6F0 /* Cookie offset */ -#define E1000_MNG_DHCP_COOKIE_LENGTH 0x10 /* Cookie length */ -#define E1000_MNG_IAMT_MODE 0x3 +#define E1000_MNG_DHCP_COOKIE_OFFSET 0x6F0 /* Cookie offset */ +#define E1000_MNG_DHCP_COOKIE_LENGTH 0x10 /* Cookie length */ +#define E1000_MNG_IAMT_MODE 0x3 #define E1000_MNG_ICH_IAMT_MODE 0x2 #define E1000_IAMT_SIGNATURE 0x544D4149 /* Intel(R) Active Management Technology signature */ @@ -385,7 +390,7 @@ struct e1000_host_mng_dhcp_cookie{ #endif int32_t e1000_mng_write_dhcp_info(struct e1000_hw *hw, uint8_t *buffer, - uint16_t length); + uint16_t length); boolean_t e1000_check_mng_mode(struct e1000_hw *hw); boolean_t e1000_enable_tx_pkt_filtering(struct e1000_hw *hw); @@ -395,8 +400,13 @@ int32_t e1000_update_eeprom_checksum(struct e1000_hw *hw); int32_t e1000_write_eeprom(struct e1000_hw *hw, uint16_t reg, uint16_t words, uint16_t *data); int32_t e1000_read_part_num(struct e1000_hw *hw, uint32_t * part_num); int32_t e1000_read_mac_addr(struct e1000_hw * hw); +int32_t e1000_swfw_sync_acquire(struct e1000_hw *hw, uint16_t mask); +void e1000_swfw_sync_release(struct e1000_hw *hw, uint16_t mask); +void e1000_release_software_flag(struct e1000_hw *hw); +int32_t e1000_get_software_flag(struct e1000_hw *hw); /* Filters (multicast, vlan, receive) */ +void e1000_mc_addr_list_update(struct e1000_hw *hw, uint8_t * mc_addr_list, uint32_t mc_addr_count, uint32_t pad, uint32_t rar_used_count); uint32_t e1000_hash_mc_addr(struct e1000_hw *hw, uint8_t * mc_addr); void e1000_mta_set(struct e1000_hw *hw, uint32_t hash_value); void e1000_rar_set(struct e1000_hw *hw, uint8_t * mc_addr, uint32_t rar_index); @@ -421,9 +431,31 @@ void e1000_pci_clear_mwi(struct e1000_hw *hw); void e1000_read_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t * value); void e1000_write_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t * value); /* Port I/O is only supported on 82544 and newer */ +uint32_t e1000_io_read(struct e1000_hw *hw, unsigned long port); +uint32_t e1000_read_reg_io(struct e1000_hw *hw, uint32_t offset); void e1000_io_write(struct e1000_hw *hw, unsigned long port, uint32_t value); +void e1000_enable_pciex_master(struct e1000_hw *hw); int32_t e1000_disable_pciex_master(struct e1000_hw *hw); +int32_t e1000_get_software_semaphore(struct e1000_hw *hw); +void e1000_release_software_semaphore(struct e1000_hw *hw); int32_t e1000_check_phy_reset_block(struct e1000_hw *hw); +int32_t e1000_set_pci_ex_no_snoop(struct e1000_hw *hw, uint32_t no_snoop); + +int32_t e1000_read_ich8_byte(struct e1000_hw *hw, uint32_t index, + uint8_t *data); +int32_t e1000_verify_write_ich8_byte(struct e1000_hw *hw, uint32_t index, + uint8_t byte); +int32_t e1000_write_ich8_byte(struct e1000_hw *hw, uint32_t index, + uint8_t byte); +int32_t e1000_read_ich8_word(struct e1000_hw *hw, uint32_t index, + uint16_t *data); +int32_t e1000_read_ich8_data(struct e1000_hw *hw, uint32_t index, + uint32_t size, uint16_t *data); +int32_t e1000_read_eeprom_ich8(struct e1000_hw *hw, uint16_t offset, + uint16_t words, uint16_t *data); +int32_t e1000_write_eeprom_ich8(struct e1000_hw *hw, uint16_t offset, + uint16_t words, uint16_t *data); +int32_t e1000_erase_ich8_4k_segment(struct e1000_hw *hw, uint32_t segment); #define E1000_READ_REG_IO(a, reg) \ @@ -470,7 +502,6 @@ int32_t e1000_check_phy_reset_block(struct e1000_hw *hw); #define E1000_DEV_ID_82571EB_COPPER 0x105E #define E1000_DEV_ID_82571EB_FIBER 0x105F #define E1000_DEV_ID_82571EB_SERDES 0x1060 -#define E1000_DEV_ID_82571EB_QUAD_COPPER 0x10A4 #define E1000_DEV_ID_82572EI_COPPER 0x107D #define E1000_DEV_ID_82572EI_FIBER 0x107E #define E1000_DEV_ID_82572EI_SERDES 0x107F @@ -524,7 +555,7 @@ int32_t e1000_check_phy_reset_block(struct e1000_hw *hw); /* 802.1q VLAN Packet Sizes */ -#define VLAN_TAG_SIZE 4 /* 802.3ac tag (not DMAed) */ +#define VLAN_TAG_SIZE 4 /* 802.3ac tag (not DMAed) */ /* Ethertype field values */ #define ETHERNET_IEEE_VLAN_TYPE 0x8100 /* 802.3ac packet */ @@ -698,7 +729,6 @@ union e1000_rx_desc_packet_split { E1000_RXDEXT_STATERR_CXE | \ E1000_RXDEXT_STATERR_RXE) - /* Transmit Descriptor */ struct e1000_tx_desc { uint64_t buffer_addr; /* Address of the descriptor's data buffer */ @@ -2088,7 +2118,7 @@ struct e1000_hw { #define E1000_MANC_EN_IP_ADDR_FILTER 0x00400000 /* Enable IP address * filtering */ #define E1000_MANC_EN_XSUM_FILTER 0x00800000 /* Enable checksum filtering */ -#define E1000_MANC_BR_EN 0x01000000 /* Enable broadcast filtering */ +#define E1000_MANC_BR_EN 0x01000000 /* Enable broadcast filtering */ #define E1000_MANC_SMB_REQ 0x01000000 /* SMBus Request */ #define E1000_MANC_SMB_GNT 0x02000000 /* SMBus Grant */ #define E1000_MANC_SMB_CLK_IN 0x04000000 /* SMBus Clock In */ @@ -2174,7 +2204,7 @@ struct e1000_host_command_info { #define E1000_MDALIGN 4096 -/* PCI-Ex registers*/ +/* PCI-Ex registers */ /* PCI-Ex Control Register */ #define E1000_GCR_RXD_NO_SNOOP 0x00000001 @@ -2226,7 +2256,7 @@ struct e1000_host_command_info { #define EEPROM_EWDS_OPCODE_MICROWIRE 0x10 /* EEPROM erast/write disable */ /* EEPROM Commands - SPI */ -#define EEPROM_MAX_RETRY_SPI 5000 /* Max wait of 5ms, for RDY signal */ +#define EEPROM_MAX_RETRY_SPI 5000 /* Max wait of 5ms, for RDY signal */ #define EEPROM_READ_OPCODE_SPI 0x03 /* EEPROM read opcode */ #define EEPROM_WRITE_OPCODE_SPI 0x02 /* EEPROM write opcode */ #define EEPROM_A8_OPCODE_SPI 0x08 /* opcode bit-3 = address bit-8 */ @@ -3084,10 +3114,10 @@ struct e1000_host_command_info { /* DSP Distance Register (Page 5, Register 26) */ #define GG82563_DSPD_CABLE_LENGTH 0x0007 /* 0 = <50M; - 1 = 50-80M; - 2 = 80-110M; - 3 = 110-140M; - 4 = >140M */ + 1 = 50-80M; + 2 = 80-110M; + 3 = 110-140M; + 4 = >140M */ /* Kumeran Mode Control Register (Page 193, Register 16) */ #define GG82563_KMCR_PHY_LEDS_EN 0x0020 /* 1=PHY LEDs, 0=Kumeran Inband LEDs */ diff --git a/trunk/drivers/net/e1000/e1000_main.c b/trunk/drivers/net/e1000/e1000_main.c index 1d7c99947e92..627f224d78bc 100644 --- a/trunk/drivers/net/e1000/e1000_main.c +++ b/trunk/drivers/net/e1000/e1000_main.c @@ -36,7 +36,7 @@ static char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver"; #else #define DRIVERNAPI "-NAPI" #endif -#define DRV_VERSION "7.2.7-k2"DRIVERNAPI +#define DRV_VERSION "7.1.9-k4"DRIVERNAPI char e1000_driver_version[] = DRV_VERSION; static char e1000_copyright[] = "Copyright (c) 1999-2006 Intel Corporation."; @@ -48,6 +48,7 @@ static char e1000_copyright[] = "Copyright (c) 1999-2006 Intel Corporation."; * {PCI_DEVICE(PCI_VENDOR_ID_INTEL, device_id)} */ static struct pci_device_id e1000_pci_tbl[] = { + INTEL_E1000_ETHERNET_DEVICE(0x1000), INTEL_E1000_ETHERNET_DEVICE(0x1001), INTEL_E1000_ETHERNET_DEVICE(0x1004), INTEL_E1000_ETHERNET_DEVICE(0x1008), @@ -98,7 +99,6 @@ static struct pci_device_id e1000_pci_tbl[] = { INTEL_E1000_ETHERNET_DEVICE(0x1098), INTEL_E1000_ETHERNET_DEVICE(0x1099), INTEL_E1000_ETHERNET_DEVICE(0x109A), - INTEL_E1000_ETHERNET_DEVICE(0x10A4), INTEL_E1000_ETHERNET_DEVICE(0x10B5), INTEL_E1000_ETHERNET_DEVICE(0x10B9), INTEL_E1000_ETHERNET_DEVICE(0x10BA), @@ -245,7 +245,7 @@ e1000_init_module(void) printk(KERN_INFO "%s\n", e1000_copyright); - ret = pci_register_driver(&e1000_driver); + ret = pci_module_init(&e1000_driver); return ret; } @@ -485,7 +485,7 @@ e1000_up(struct e1000_adapter *adapter) * **/ -void e1000_power_up_phy(struct e1000_adapter *adapter) +static void e1000_power_up_phy(struct e1000_adapter *adapter) { uint16_t mii_reg = 0; @@ -682,9 +682,9 @@ e1000_probe(struct pci_dev *pdev, unsigned long flash_start, flash_len; static int cards_found = 0; - static int global_quad_port_a = 0; /* global ksp3 port a indication */ + static int e1000_ksp3_port_a = 0; /* global ksp3 port a indication */ int i, err, pci_using_dac; - uint16_t eeprom_data = 0; + uint16_t eeprom_data; uint16_t eeprom_apme_mask = E1000_EEPROM_APME; if ((err = pci_enable_device(pdev))) return err; @@ -696,20 +696,21 @@ e1000_probe(struct pci_dev *pdev, if ((err = pci_set_dma_mask(pdev, DMA_32BIT_MASK)) && (err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK))) { E1000_ERR("No usable DMA configuration, aborting\n"); - goto err_dma; + return err; } pci_using_dac = 0; } if ((err = pci_request_regions(pdev, e1000_driver_name))) - goto err_pci_reg; + return err; pci_set_master(pdev); - err = -ENOMEM; netdev = alloc_etherdev(sizeof(struct e1000_adapter)); - if (!netdev) + if (!netdev) { + err = -ENOMEM; goto err_alloc_etherdev; + } SET_MODULE_OWNER(netdev); SET_NETDEV_DEV(netdev, &pdev->dev); @@ -724,10 +725,11 @@ e1000_probe(struct pci_dev *pdev, mmio_start = pci_resource_start(pdev, BAR_0); mmio_len = pci_resource_len(pdev, BAR_0); - err = -EIO; adapter->hw.hw_addr = ioremap(mmio_start, mmio_len); - if (!adapter->hw.hw_addr) + if (!adapter->hw.hw_addr) { + err = -EIO; goto err_ioremap; + } for (i = BAR_1; i <= BAR_5; i++) { if (pci_resource_len(pdev, i) == 0) @@ -772,7 +774,6 @@ e1000_probe(struct pci_dev *pdev, if ((err = e1000_sw_init(adapter))) goto err_sw_init; - err = -EIO; /* Flash BAR mapping must happen after e1000_sw_init * because it depends on mac_type */ if ((adapter->hw.mac_type == e1000_ich8lan) && @@ -780,13 +781,24 @@ e1000_probe(struct pci_dev *pdev, flash_start = pci_resource_start(pdev, 1); flash_len = pci_resource_len(pdev, 1); adapter->hw.flash_address = ioremap(flash_start, flash_len); - if (!adapter->hw.flash_address) + if (!adapter->hw.flash_address) { + err = -EIO; goto err_flashmap; + } } - if (e1000_check_phy_reset_block(&adapter->hw)) + if ((err = e1000_check_phy_reset_block(&adapter->hw))) DPRINTK(PROBE, INFO, "PHY reset is blocked due to SOL/IDER session.\n"); + /* if ksp3, indicate if it's port a being setup */ + if (pdev->device == E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3 && + e1000_ksp3_port_a == 0) + adapter->ksp3_port_a = 1; + e1000_ksp3_port_a++; + /* Reset for multiple KP3 adapters */ + if (e1000_ksp3_port_a == 4) + e1000_ksp3_port_a = 0; + if (adapter->hw.mac_type >= e1000_82543) { netdev->features = NETIF_F_SG | NETIF_F_HW_CSUM | @@ -818,7 +830,7 @@ e1000_probe(struct pci_dev *pdev, if (e1000_init_eeprom_params(&adapter->hw)) { E1000_ERR("EEPROM initialization failed\n"); - goto err_eeprom; + return -EIO; } /* before reading the EEPROM, reset the controller to @@ -830,6 +842,7 @@ e1000_probe(struct pci_dev *pdev, if (e1000_validate_eeprom_checksum(&adapter->hw) < 0) { DPRINTK(PROBE, ERR, "The EEPROM Checksum Is Not Valid\n"); + err = -EIO; goto err_eeprom; } @@ -842,9 +855,12 @@ e1000_probe(struct pci_dev *pdev, if (!is_valid_ether_addr(netdev->perm_addr)) { DPRINTK(PROBE, ERR, "Invalid MAC Address\n"); + err = -EIO; goto err_eeprom; } + e1000_read_part_num(&adapter->hw, &(adapter->part_num)); + e1000_get_bus_info(&adapter->hw); init_timer(&adapter->tx_fifo_stall_timer); @@ -905,38 +921,7 @@ e1000_probe(struct pci_dev *pdev, break; } if (eeprom_data & eeprom_apme_mask) - adapter->eeprom_wol |= E1000_WUFC_MAG; - - /* now that we have the eeprom settings, apply the special cases - * where the eeprom may be wrong or the board simply won't support - * wake on lan on a particular port */ - switch (pdev->device) { - case E1000_DEV_ID_82546GB_PCIE: - adapter->eeprom_wol = 0; - break; - case E1000_DEV_ID_82546EB_FIBER: - case E1000_DEV_ID_82546GB_FIBER: - case E1000_DEV_ID_82571EB_FIBER: - /* Wake events only supported on port A for dual fiber - * regardless of eeprom setting */ - if (E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_FUNC_1) - adapter->eeprom_wol = 0; - break; - case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3: - case E1000_DEV_ID_82571EB_QUAD_COPPER: - /* if quad port adapter, disable WoL on all but port A */ - if (global_quad_port_a != 0) - adapter->eeprom_wol = 0; - else - adapter->quad_port_a = 1; - /* Reset for multiple quad port adapters */ - if (++global_quad_port_a == 4) - global_quad_port_a = 0; - break; - } - - /* initialize the wol settings based on the eeprom settings */ - adapter->wol = adapter->eeprom_wol; + adapter->wol |= E1000_WUFC_MAG; /* print bus type/speed/width info */ { @@ -979,33 +964,16 @@ e1000_probe(struct pci_dev *pdev, return 0; err_register: - e1000_release_hw_control(adapter); -err_eeprom: - if (!e1000_check_phy_reset_block(&adapter->hw)) - e1000_phy_hw_reset(&adapter->hw); - if (adapter->hw.flash_address) iounmap(adapter->hw.flash_address); err_flashmap: -#ifdef CONFIG_E1000_NAPI - for (i = 0; i < adapter->num_rx_queues; i++) - dev_put(&adapter->polling_netdev[i]); -#endif - - kfree(adapter->tx_ring); - kfree(adapter->rx_ring); -#ifdef CONFIG_E1000_NAPI - kfree(adapter->polling_netdev); -#endif err_sw_init: +err_eeprom: iounmap(adapter->hw.hw_addr); err_ioremap: free_netdev(netdev); err_alloc_etherdev: pci_release_regions(pdev); -err_pci_reg: -err_dma: - pci_disable_device(pdev); return err; } @@ -1240,7 +1208,7 @@ e1000_open(struct net_device *netdev) err = e1000_request_irq(adapter); if (err) - goto err_req_irq; + goto err_up; e1000_power_up_phy(adapter); @@ -1261,9 +1229,6 @@ e1000_open(struct net_device *netdev) return E1000_SUCCESS; err_up: - e1000_power_down_phy(adapter); - e1000_free_irq(adapter); -err_req_irq: e1000_free_all_rx_resources(adapter); err_setup_rx: e1000_free_all_tx_resources(adapter); @@ -1416,6 +1381,10 @@ e1000_setup_tx_resources(struct e1000_adapter *adapter, * (Descriptors) for all queues * @adapter: board private structure * + * If this function returns with an error, then it's possible one or + * more of the rings is populated (while the rest are not). It is the + * callers duty to clean those orphaned rings. + * * Return 0 on success, negative on failure **/ @@ -1429,9 +1398,6 @@ e1000_setup_all_tx_resources(struct e1000_adapter *adapter) if (err) { DPRINTK(PROBE, ERR, "Allocation for Tx Queue %u failed\n", i); - for (i-- ; i >= 0; i--) - e1000_free_tx_resources(adapter, - &adapter->tx_ring[i]); break; } } @@ -1533,6 +1499,8 @@ e1000_configure_tx(struct e1000_adapter *adapter) } else if (hw->mac_type == e1000_80003es2lan) { tarc = E1000_READ_REG(hw, TARC0); tarc |= 1; + if (hw->media_type == e1000_media_type_internal_serdes) + tarc |= (1 << 20); E1000_WRITE_REG(hw, TARC0, tarc); tarc = E1000_READ_REG(hw, TARC1); tarc |= 1; @@ -1671,6 +1639,10 @@ e1000_setup_rx_resources(struct e1000_adapter *adapter, * (Descriptors) for all queues * @adapter: board private structure * + * If this function returns with an error, then it's possible one or + * more of the rings is populated (while the rest are not). It is the + * callers duty to clean those orphaned rings. + * * Return 0 on success, negative on failure **/ @@ -1684,9 +1656,6 @@ e1000_setup_all_rx_resources(struct e1000_adapter *adapter) if (err) { DPRINTK(PROBE, ERR, "Allocation for Rx Queue %u failed\n", i); - for (i-- ; i >= 0; i--) - e1000_free_rx_resources(adapter, - &adapter->rx_ring[i]); break; } } @@ -2473,9 +2442,10 @@ e1000_watchdog(unsigned long data) * disable receives in the ISR and * reset device here in the watchdog */ - if (adapter->hw.mac_type == e1000_80003es2lan) + if (adapter->hw.mac_type == e1000_80003es2lan) { /* reset device */ schedule_work(&adapter->reset_task); + } } e1000_smartspeed(adapter); @@ -2575,7 +2545,7 @@ e1000_tso(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring, cmd_length = E1000_TXD_CMD_IP; ipcse = skb->h.raw - skb->data - 1; #ifdef NETIF_F_TSO_IPV6 - } else if (skb->protocol == htons(ETH_P_IPV6)) { + } else if (skb->protocol == ntohs(ETH_P_IPV6)) { skb->nh.ipv6h->payload_len = 0; skb->h.th->check = ~csum_ipv6_magic(&skb->nh.ipv6h->saddr, @@ -3710,7 +3680,7 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter, E1000_DBG("%s: Receive packet consumed multiple" " buffers\n", netdev->name); /* recycle */ - buffer_info->skb = skb; + buffer_info-> skb = skb; goto next_desc; } @@ -3741,6 +3711,7 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter, netdev_alloc_skb(netdev, length + NET_IP_ALIGN); if (new_skb) { skb_reserve(new_skb, NET_IP_ALIGN); + new_skb->dev = netdev; memcpy(new_skb->data - NET_IP_ALIGN, skb->data - NET_IP_ALIGN, length + NET_IP_ALIGN); @@ -4007,13 +3978,13 @@ e1000_alloc_rx_buffers(struct e1000_adapter *adapter, buffer_info = &rx_ring->buffer_info[i]; while (cleaned_count--) { - skb = buffer_info->skb; - if (skb) { + if (!(skb = buffer_info->skb)) + skb = netdev_alloc_skb(netdev, bufsz); + else { skb_trim(skb, 0); goto map_skb; } - skb = netdev_alloc_skb(netdev, bufsz); if (unlikely(!skb)) { /* Better luck next round */ adapter->alloc_rx_buff_failed++; @@ -4038,10 +4009,10 @@ e1000_alloc_rx_buffers(struct e1000_adapter *adapter, dev_kfree_skb(skb); dev_kfree_skb(oldskb); break; /* while !buffer_info->skb */ + } else { + /* Use new allocation */ + dev_kfree_skb(oldskb); } - - /* Use new allocation */ - dev_kfree_skb(oldskb); } /* Make buffer alignment 2 beyond a 16 byte boundary * this will result in a 16 byte aligned IP header after @@ -4049,6 +4020,8 @@ e1000_alloc_rx_buffers(struct e1000_adapter *adapter, */ skb_reserve(skb, NET_IP_ALIGN); + skb->dev = netdev; + buffer_info->skb = skb; buffer_info->length = adapter->rx_buffer_len; map_skb: @@ -4162,6 +4135,8 @@ e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter, */ skb_reserve(skb, NET_IP_ALIGN); + skb->dev = netdev; + buffer_info->skb = skb; buffer_info->length = adapter->rx_ps_bsize0; buffer_info->dma = pci_map_single(pdev, skb->data, @@ -4411,13 +4386,11 @@ e1000_write_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t *value) pci_write_config_word(adapter->pdev, reg, *value); } -#if 0 uint32_t e1000_io_read(struct e1000_hw *hw, unsigned long port) { return inl(port); } -#endif /* 0 */ void e1000_io_write(struct e1000_hw *hw, unsigned long port, uint32_t value) @@ -4653,7 +4626,7 @@ e1000_suspend(struct pci_dev *pdev, pm_message_t state) e1000_set_multi(netdev); /* turn on all-multi mode if wake on multicast is enabled */ - if (wufc & E1000_WUFC_MC) { + if (adapter->wol & E1000_WUFC_MC) { rctl = E1000_READ_REG(&adapter->hw, RCTL); rctl |= E1000_RCTL_MPE; E1000_WRITE_REG(&adapter->hw, RCTL, rctl); @@ -4725,14 +4698,11 @@ e1000_resume(struct pci_dev *pdev) { struct net_device *netdev = pci_get_drvdata(pdev); struct e1000_adapter *adapter = netdev_priv(netdev); - uint32_t manc, err; + uint32_t manc, ret_val; pci_set_power_state(pdev, PCI_D0); e1000_pci_restore_state(adapter); - if ((err = pci_enable_device(pdev))) { - printk(KERN_ERR "e1000: Cannot enable PCI device from suspend\n"); - return err; - } + ret_val = pci_enable_device(pdev); pci_set_master(pdev); pci_enable_wake(pdev, PCI_D3hot, 0); diff --git a/trunk/drivers/net/e1000/e1000_param.c b/trunk/drivers/net/e1000/e1000_param.c index 212842738972..0ef413172c68 100644 --- a/trunk/drivers/net/e1000/e1000_param.c +++ b/trunk/drivers/net/e1000/e1000_param.c @@ -324,6 +324,7 @@ e1000_check_options(struct e1000_adapter *adapter) DPRINTK(PROBE, NOTICE, "Warning: no configuration for board #%i\n", bd); DPRINTK(PROBE, NOTICE, "Using defaults for all values\n"); + bd = E1000_MAX_NIC; } { /* Transmit Descriptor Count */ @@ -341,14 +342,9 @@ e1000_check_options(struct e1000_adapter *adapter) opt.arg.r.max = mac_type < e1000_82544 ? E1000_MAX_TXD : E1000_MAX_82544_TXD; - if (num_TxDescriptors > bd) { - tx_ring->count = TxDescriptors[bd]; - e1000_validate_option(&tx_ring->count, &opt, adapter); - E1000_ROUNDUP(tx_ring->count, - REQ_TX_DESCRIPTOR_MULTIPLE); - } else { - tx_ring->count = opt.def; - } + tx_ring->count = TxDescriptors[bd]; + e1000_validate_option(&tx_ring->count, &opt, adapter); + E1000_ROUNDUP(tx_ring->count, REQ_TX_DESCRIPTOR_MULTIPLE); for (i = 0; i < adapter->num_tx_queues; i++) tx_ring[i].count = tx_ring->count; } @@ -367,14 +363,9 @@ e1000_check_options(struct e1000_adapter *adapter) opt.arg.r.max = mac_type < e1000_82544 ? E1000_MAX_RXD : E1000_MAX_82544_RXD; - if (num_RxDescriptors > bd) { - rx_ring->count = RxDescriptors[bd]; - e1000_validate_option(&rx_ring->count, &opt, adapter); - E1000_ROUNDUP(rx_ring->count, - REQ_RX_DESCRIPTOR_MULTIPLE); - } else { - rx_ring->count = opt.def; - } + rx_ring->count = RxDescriptors[bd]; + e1000_validate_option(&rx_ring->count, &opt, adapter); + E1000_ROUNDUP(rx_ring->count, REQ_RX_DESCRIPTOR_MULTIPLE); for (i = 0; i < adapter->num_rx_queues; i++) rx_ring[i].count = rx_ring->count; } @@ -386,13 +377,9 @@ e1000_check_options(struct e1000_adapter *adapter) .def = OPTION_ENABLED }; - if (num_XsumRX > bd) { - int rx_csum = XsumRX[bd]; - e1000_validate_option(&rx_csum, &opt, adapter); - adapter->rx_csum = rx_csum; - } else { - adapter->rx_csum = opt.def; - } + int rx_csum = XsumRX[bd]; + e1000_validate_option(&rx_csum, &opt, adapter); + adapter->rx_csum = rx_csum; } { /* Flow Control */ @@ -412,13 +399,9 @@ e1000_check_options(struct e1000_adapter *adapter) .p = fc_list }} }; - if (num_FlowControl > bd) { - int fc = FlowControl[bd]; - e1000_validate_option(&fc, &opt, adapter); - adapter->hw.fc = adapter->hw.original_fc = fc; - } else { - adapter->hw.fc = adapter->hw.original_fc = opt.def; - } + int fc = FlowControl[bd]; + e1000_validate_option(&fc, &opt, adapter); + adapter->hw.fc = adapter->hw.original_fc = fc; } { /* Transmit Interrupt Delay */ struct e1000_option opt = { @@ -430,13 +413,8 @@ e1000_check_options(struct e1000_adapter *adapter) .max = MAX_TXDELAY }} }; - if (num_TxIntDelay > bd) { - adapter->tx_int_delay = TxIntDelay[bd]; - e1000_validate_option(&adapter->tx_int_delay, &opt, - adapter); - } else { - adapter->tx_int_delay = opt.def; - } + adapter->tx_int_delay = TxIntDelay[bd]; + e1000_validate_option(&adapter->tx_int_delay, &opt, adapter); } { /* Transmit Absolute Interrupt Delay */ struct e1000_option opt = { @@ -448,13 +426,9 @@ e1000_check_options(struct e1000_adapter *adapter) .max = MAX_TXABSDELAY }} }; - if (num_TxAbsIntDelay > bd) { - adapter->tx_abs_int_delay = TxAbsIntDelay[bd]; - e1000_validate_option(&adapter->tx_abs_int_delay, &opt, - adapter); - } else { - adapter->tx_abs_int_delay = opt.def; - } + adapter->tx_abs_int_delay = TxAbsIntDelay[bd]; + e1000_validate_option(&adapter->tx_abs_int_delay, &opt, + adapter); } { /* Receive Interrupt Delay */ struct e1000_option opt = { @@ -466,13 +440,8 @@ e1000_check_options(struct e1000_adapter *adapter) .max = MAX_RXDELAY }} }; - if (num_RxIntDelay > bd) { - adapter->rx_int_delay = RxIntDelay[bd]; - e1000_validate_option(&adapter->rx_int_delay, &opt, - adapter); - } else { - adapter->rx_int_delay = opt.def; - } + adapter->rx_int_delay = RxIntDelay[bd]; + e1000_validate_option(&adapter->rx_int_delay, &opt, adapter); } { /* Receive Absolute Interrupt Delay */ struct e1000_option opt = { @@ -484,13 +453,9 @@ e1000_check_options(struct e1000_adapter *adapter) .max = MAX_RXABSDELAY }} }; - if (num_RxAbsIntDelay > bd) { - adapter->rx_abs_int_delay = RxAbsIntDelay[bd]; - e1000_validate_option(&adapter->rx_abs_int_delay, &opt, - adapter); - } else { - adapter->rx_abs_int_delay = opt.def; - } + adapter->rx_abs_int_delay = RxAbsIntDelay[bd]; + e1000_validate_option(&adapter->rx_abs_int_delay, &opt, + adapter); } { /* Interrupt Throttling Rate */ struct e1000_option opt = { @@ -502,24 +467,18 @@ e1000_check_options(struct e1000_adapter *adapter) .max = MAX_ITR }} }; - if (num_InterruptThrottleRate > bd) { - adapter->itr = InterruptThrottleRate[bd]; - switch (adapter->itr) { - case 0: - DPRINTK(PROBE, INFO, "%s turned off\n", - opt.name); - break; - case 1: - DPRINTK(PROBE, INFO, "%s set to dynamic mode\n", - opt.name); - break; - default: - e1000_validate_option(&adapter->itr, &opt, - adapter); - break; - } - } else { - adapter->itr = opt.def; + adapter->itr = InterruptThrottleRate[bd]; + switch (adapter->itr) { + case 0: + DPRINTK(PROBE, INFO, "%s turned off\n", opt.name); + break; + case 1: + DPRINTK(PROBE, INFO, "%s set to dynamic mode\n", + opt.name); + break; + default: + e1000_validate_option(&adapter->itr, &opt, adapter); + break; } } { /* Smart Power Down */ @@ -530,13 +489,9 @@ e1000_check_options(struct e1000_adapter *adapter) .def = OPTION_DISABLED }; - if (num_SmartPowerDownEnable > bd) { - int spd = SmartPowerDownEnable[bd]; - e1000_validate_option(&spd, &opt, adapter); - adapter->smart_power_down = spd; - } else { - adapter->smart_power_down = opt.def; - } + int spd = SmartPowerDownEnable[bd]; + e1000_validate_option(&spd, &opt, adapter); + adapter->smart_power_down = spd; } { /* Kumeran Lock Loss Workaround */ struct e1000_option opt = { @@ -546,13 +501,9 @@ e1000_check_options(struct e1000_adapter *adapter) .def = OPTION_ENABLED }; - if (num_KumeranLockLoss > bd) { int kmrn_lock_loss = KumeranLockLoss[bd]; e1000_validate_option(&kmrn_lock_loss, &opt, adapter); adapter->hw.kmrn_lock_loss_workaround_disabled = !kmrn_lock_loss; - } else { - adapter->hw.kmrn_lock_loss_workaround_disabled = !opt.def; - } } switch (adapter->hw.media_type) { @@ -579,17 +530,18 @@ static void __devinit e1000_check_fiber_options(struct e1000_adapter *adapter) { int bd = adapter->bd_number; - if (num_Speed > bd) { + bd = bd > E1000_MAX_NIC ? E1000_MAX_NIC : bd; + if ((Speed[bd] != OPTION_UNSET)) { DPRINTK(PROBE, INFO, "Speed not valid for fiber adapters, " "parameter ignored\n"); } - if (num_Duplex > bd) { + if ((Duplex[bd] != OPTION_UNSET)) { DPRINTK(PROBE, INFO, "Duplex not valid for fiber adapters, " "parameter ignored\n"); } - if ((num_AutoNeg > bd) && (AutoNeg[bd] != 0x20)) { + if ((AutoNeg[bd] != OPTION_UNSET) && (AutoNeg[bd] != 0x20)) { DPRINTK(PROBE, INFO, "AutoNeg other than 1000/Full is " "not valid for fiber adapters, " "parameter ignored\n"); @@ -608,6 +560,7 @@ e1000_check_copper_options(struct e1000_adapter *adapter) { int speed, dplx, an; int bd = adapter->bd_number; + bd = bd > E1000_MAX_NIC ? E1000_MAX_NIC : bd; { /* Speed */ struct e1000_opt_list speed_list[] = {{ 0, "" }, @@ -624,12 +577,8 @@ e1000_check_copper_options(struct e1000_adapter *adapter) .p = speed_list }} }; - if (num_Speed > bd) { - speed = Speed[bd]; - e1000_validate_option(&speed, &opt, adapter); - } else { - speed = opt.def; - } + speed = Speed[bd]; + e1000_validate_option(&speed, &opt, adapter); } { /* Duplex */ struct e1000_opt_list dplx_list[] = {{ 0, "" }, @@ -651,15 +600,11 @@ e1000_check_copper_options(struct e1000_adapter *adapter) "Speed/Duplex/AutoNeg parameter ignored.\n"); return; } - if (num_Duplex > bd) { - dplx = Duplex[bd]; - e1000_validate_option(&dplx, &opt, adapter); - } else { - dplx = opt.def; - } + dplx = Duplex[bd]; + e1000_validate_option(&dplx, &opt, adapter); } - if ((num_AutoNeg > bd) && (speed != 0 || dplx != 0)) { + if (AutoNeg[bd] != OPTION_UNSET && (speed != 0 || dplx != 0)) { DPRINTK(PROBE, INFO, "AutoNeg specified along with Speed or Duplex, " "parameter ignored\n"); @@ -708,19 +653,15 @@ e1000_check_copper_options(struct e1000_adapter *adapter) .p = an_list }} }; - if (num_AutoNeg > bd) { - an = AutoNeg[bd]; - e1000_validate_option(&an, &opt, adapter); - } else { - an = opt.def; - } + an = AutoNeg[bd]; + e1000_validate_option(&an, &opt, adapter); adapter->hw.autoneg_advertised = an; } switch (speed + dplx) { case 0: adapter->hw.autoneg = adapter->fc_autoneg = 1; - if ((num_Speed > bd) && (speed != 0 || dplx != 0)) + if (Speed[bd] != OPTION_UNSET || Duplex[bd] != OPTION_UNSET) DPRINTK(PROBE, INFO, "Speed and duplex autonegotiation enabled\n"); break; diff --git a/trunk/drivers/net/e2100.c b/trunk/drivers/net/e2100.c index e4e733a380e3..e5c5cd2a2712 100644 --- a/trunk/drivers/net/e2100.c +++ b/trunk/drivers/net/e2100.c @@ -425,8 +425,8 @@ MODULE_LICENSE("GPL"); /* This is set up so that only a single autoprobe takes place per call. ISA device autoprobes on a running machine are not recommended. */ - -int __init init_module(void) +int +init_module(void) { struct net_device *dev; int this_dev, found = 0; diff --git a/trunk/drivers/net/eepro.c b/trunk/drivers/net/eepro.c index 8dc61d65dd23..20d31430c74f 100644 --- a/trunk/drivers/net/eepro.c +++ b/trunk/drivers/net/eepro.c @@ -1807,7 +1807,8 @@ MODULE_PARM_DESC(irq, "EtherExpress Pro/10 IRQ number(s)"); MODULE_PARM_DESC(mem, "EtherExpress Pro/10 Rx buffer size(es) in kB (3-29)"); MODULE_PARM_DESC(autodetect, "EtherExpress Pro/10 force board(s) detection (0-1)"); -int __init init_module(void) +int +init_module(void) { struct net_device *dev; int i; diff --git a/trunk/drivers/net/eepro100.c b/trunk/drivers/net/eepro100.c index a3d515def109..e445988c92ee 100644 --- a/trunk/drivers/net/eepro100.c +++ b/trunk/drivers/net/eepro100.c @@ -2385,7 +2385,7 @@ static int __init eepro100_init_module(void) #ifdef MODULE printk(version); #endif - return pci_register_driver(&eepro100_driver); + return pci_module_init(&eepro100_driver); } static void __exit eepro100_cleanup_module(void) diff --git a/trunk/drivers/net/eexpress.c b/trunk/drivers/net/eexpress.c index 0701c1d810ca..33291bcf6d4c 100644 --- a/trunk/drivers/net/eexpress.c +++ b/trunk/drivers/net/eexpress.c @@ -1698,7 +1698,7 @@ MODULE_LICENSE("GPL"); * are specified, we verify and then use them. If no parameters are given, we * autoprobe for one card only. */ -int __init init_module(void) +int init_module(void) { struct net_device *dev; int this_dev, found = 0; diff --git a/trunk/drivers/net/epic100.c b/trunk/drivers/net/epic100.c index 25c4619d842e..a67650ccf084 100644 --- a/trunk/drivers/net/epic100.c +++ b/trunk/drivers/net/epic100.c @@ -1604,7 +1604,7 @@ static int __init epic_init (void) version, version2, version3); #endif - return pci_register_driver(&epic_driver); + return pci_module_init (&epic_driver); } diff --git a/trunk/drivers/net/es3210.c b/trunk/drivers/net/es3210.c index fd7b32a24ea4..6b0ab1eac3fb 100644 --- a/trunk/drivers/net/es3210.c +++ b/trunk/drivers/net/es3210.c @@ -421,7 +421,8 @@ MODULE_PARM_DESC(mem, "memory base address(es)"); MODULE_DESCRIPTION("Racal-Interlan ES3210 EISA ethernet driver"); MODULE_LICENSE("GPL"); -int __init init_module(void) +int +init_module(void) { struct net_device *dev; int this_dev, found = 0; diff --git a/trunk/drivers/net/eth16i.c b/trunk/drivers/net/eth16i.c index ca42efa9143c..4bf76f86d8e9 100644 --- a/trunk/drivers/net/eth16i.c +++ b/trunk/drivers/net/eth16i.c @@ -1434,7 +1434,7 @@ MODULE_PARM_DESC(mediatype, "eth16i media type of interface(s) (bnc,tp,dix,auto, module_param(debug, int, 0); MODULE_PARM_DESC(debug, "eth16i debug level (0-6)"); -int __init init_module(void) +int init_module(void) { int this_dev, found = 0; struct net_device *dev; diff --git a/trunk/drivers/net/fealnx.c b/trunk/drivers/net/fealnx.c index a2121faa610f..97d34fee8c1f 100644 --- a/trunk/drivers/net/fealnx.c +++ b/trunk/drivers/net/fealnx.c @@ -92,7 +92,7 @@ static int full_duplex[MAX_UNITS] = { -1, -1, -1, -1, -1, -1, -1, -1 }; #include /* These identify the driver base version and may not be removed. */ -static char version[] = +static char version[] __devinitdata = KERN_INFO DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE "\n"; @@ -1984,7 +1984,7 @@ static int __init fealnx_init(void) printk(version); #endif - return pci_register_driver(&fealnx_driver); + return pci_module_init(&fealnx_driver); } static void __exit fealnx_exit(void) diff --git a/trunk/drivers/net/forcedeth.c b/trunk/drivers/net/forcedeth.c index e90d27b78121..11b8f1b43dd5 100644 --- a/trunk/drivers/net/forcedeth.c +++ b/trunk/drivers/net/forcedeth.c @@ -109,7 +109,6 @@ * 0.54: 21 Mar 2006: Fix spin locks for multi irqs and cleanup. * 0.55: 22 Mar 2006: Add flow control (pause frame). * 0.56: 22 Mar 2006: Additional ethtool config and moduleparam support. - * 0.57: 14 May 2006: Mac address set in probe/remove and order corrections. * * Known bugs: * We suspect that on some hardware no TX done interrupts are generated. @@ -121,12 +120,7 @@ * DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few * superfluous timer interrupts from the nic. */ -#ifdef CONFIG_FORCEDETH_NAPI -#define DRIVERNAPI "-NAPI" -#else -#define DRIVERNAPI -#endif -#define FORCEDETH_VERSION "0.57" +#define FORCEDETH_VERSION "0.56" #define DRV_NAME "forcedeth" #include @@ -268,8 +262,7 @@ enum { NvRegRingSizes = 0x108, #define NVREG_RINGSZ_TXSHIFT 0 #define NVREG_RINGSZ_RXSHIFT 16 - NvRegTransmitPoll = 0x10c, -#define NVREG_TRANSMITPOLL_MAC_ADDR_REV 0x00008000 + NvRegUnknownTransmitterReg = 0x10c, NvRegLinkSpeed = 0x110, #define NVREG_LINKSPEED_FORCE 0x10000 #define NVREG_LINKSPEED_10 1000 @@ -388,21 +381,21 @@ enum { /* Big endian: should work, but is untested */ struct ring_desc { - __le32 buf; - __le32 flaglen; + u32 PacketBuffer; + u32 FlagLen; }; struct ring_desc_ex { - __le32 bufhigh; - __le32 buflow; - __le32 txvlan; - __le32 flaglen; + u32 PacketBufferHigh; + u32 PacketBufferLow; + u32 TxVlan; + u32 FlagLen; }; -union ring_type { +typedef union _ring_type { struct ring_desc* orig; struct ring_desc_ex* ex; -}; +} ring_type; #define FLAG_MASK_V1 0xffff0000 #define FLAG_MASK_V2 0xffffc000 @@ -543,9 +536,6 @@ union ring_type { #define PHYID1_OUI_SHFT 6 #define PHYID2_OUI_MASK 0xfc00 #define PHYID2_OUI_SHFT 10 -#define PHYID2_MODEL_MASK 0x03f0 -#define PHY_MODEL_MARVELL_E3016 0x220 -#define PHY_MARVELL_E3016_INITMASK 0x0300 #define PHY_INIT1 0x0f000 #define PHY_INIT2 0x0e00 #define PHY_INIT3 0x01000 @@ -663,8 +653,8 @@ static const struct nv_ethtool_str nv_etests_str[] = { }; struct register_test { - __le32 reg; - __le32 mask; + u32 reg; + u32 mask; }; static const struct register_test nv_registers_test[] = { @@ -704,7 +694,6 @@ struct fe_priv { int phyaddr; int wolenabled; unsigned int phy_oui; - unsigned int phy_model; u16 gigabit; int intr_test; @@ -718,14 +707,13 @@ struct fe_priv { u32 vlanctl_bits; u32 driver_data; u32 register_size; - int rx_csum; void __iomem *base; /* rx specific fields. * Locking: Within irq hander or disable_irq+spin_lock(&np->lock); */ - union ring_type rx_ring; + ring_type rx_ring; unsigned int cur_rx, refill_rx; struct sk_buff **rx_skbuff; dma_addr_t *rx_dma; @@ -745,7 +733,7 @@ struct fe_priv { /* * tx specific fields. */ - union ring_type tx_ring; + ring_type tx_ring; unsigned int next_tx, nic_tx; struct sk_buff **tx_skbuff; dma_addr_t *tx_dma; @@ -838,13 +826,13 @@ static inline void pci_push(u8 __iomem *base) static inline u32 nv_descr_getlength(struct ring_desc *prd, u32 v) { - return le32_to_cpu(prd->flaglen) + return le32_to_cpu(prd->FlagLen) & ((v == DESC_VER_1) ? LEN_MASK_V1 : LEN_MASK_V2); } static inline u32 nv_descr_getlength_ex(struct ring_desc_ex *prd, u32 v) { - return le32_to_cpu(prd->flaglen) & LEN_MASK_V2; + return le32_to_cpu(prd->FlagLen) & LEN_MASK_V2; } static int reg_delay(struct net_device *dev, int offset, u32 mask, u32 target, @@ -897,7 +885,7 @@ static void free_rings(struct net_device *dev) struct fe_priv *np = get_nvpriv(dev); if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) { - if (np->rx_ring.orig) + if(np->rx_ring.orig) pci_free_consistent(np->pci_dev, sizeof(struct ring_desc) * (np->rx_ring_size + np->tx_ring_size), np->rx_ring.orig, np->ring_addr); } else { @@ -1032,13 +1020,14 @@ static int mii_rw(struct net_device *dev, int addr, int miireg, int value) return retval; } -static int phy_reset(struct net_device *dev, u32 bmcr_setup) +static int phy_reset(struct net_device *dev) { struct fe_priv *np = netdev_priv(dev); u32 miicontrol; unsigned int tries = 0; - miicontrol = BMCR_RESET | bmcr_setup; + miicontrol = mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ); + miicontrol |= BMCR_RESET; if (mii_rw(dev, np->phyaddr, MII_BMCR, miicontrol)) { return -1; } @@ -1063,16 +1052,6 @@ static int phy_init(struct net_device *dev) u8 __iomem *base = get_hwbase(dev); u32 phyinterface, phy_reserved, mii_status, mii_control, mii_control_1000,reg; - /* phy errata for E3016 phy */ - if (np->phy_model == PHY_MODEL_MARVELL_E3016) { - reg = mii_rw(dev, np->phyaddr, MII_NCONFIG, MII_READ); - reg &= ~PHY_MARVELL_E3016_INITMASK; - if (mii_rw(dev, np->phyaddr, MII_NCONFIG, reg)) { - printk(KERN_INFO "%s: phy write to errata reg failed.\n", pci_name(np->pci_dev)); - return PHY_ERROR; - } - } - /* set advertise register */ reg = mii_rw(dev, np->phyaddr, MII_ADVERTISE, MII_READ); reg |= (ADVERTISE_10HALF|ADVERTISE_10FULL|ADVERTISE_100HALF|ADVERTISE_100FULL|ADVERTISE_PAUSE_ASYM|ADVERTISE_PAUSE_CAP); @@ -1103,13 +1082,8 @@ static int phy_init(struct net_device *dev) else np->gigabit = 0; - mii_control = mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ); - mii_control |= BMCR_ANENABLE; - - /* reset the phy - * (certain phys need bmcr to be setup with reset) - */ - if (phy_reset(dev, mii_control)) { + /* reset the phy */ + if (phy_reset(dev)) { printk(KERN_INFO "%s: phy reset failed\n", pci_name(np->pci_dev)); return PHY_ERROR; } @@ -1204,7 +1178,7 @@ static void nv_stop_tx(struct net_device *dev) KERN_INFO "nv_stop_tx: TransmitterStatus remained busy"); udelay(NV_TXSTOP_DELAY2); - writel(readl(base + NvRegTransmitPoll) & NVREG_TRANSMITPOLL_MAC_ADDR_REV, base + NvRegTransmitPoll); + writel(0, base + NvRegUnknownTransmitterReg); } static void nv_txrx_reset(struct net_device *dev) @@ -1284,14 +1258,14 @@ static int nv_alloc_rx(struct net_device *dev) np->rx_dma[nr] = pci_map_single(np->pci_dev, skb->data, skb->end-skb->data, PCI_DMA_FROMDEVICE); if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) { - np->rx_ring.orig[nr].buf = cpu_to_le32(np->rx_dma[nr]); + np->rx_ring.orig[nr].PacketBuffer = cpu_to_le32(np->rx_dma[nr]); wmb(); - np->rx_ring.orig[nr].flaglen = cpu_to_le32(np->rx_buf_sz | NV_RX_AVAIL); + np->rx_ring.orig[nr].FlagLen = cpu_to_le32(np->rx_buf_sz | NV_RX_AVAIL); } else { - np->rx_ring.ex[nr].bufhigh = cpu_to_le64(np->rx_dma[nr]) >> 32; - np->rx_ring.ex[nr].buflow = cpu_to_le64(np->rx_dma[nr]) & 0x0FFFFFFFF; + np->rx_ring.ex[nr].PacketBufferHigh = cpu_to_le64(np->rx_dma[nr]) >> 32; + np->rx_ring.ex[nr].PacketBufferLow = cpu_to_le64(np->rx_dma[nr]) & 0x0FFFFFFFF; wmb(); - np->rx_ring.ex[nr].flaglen = cpu_to_le32(np->rx_buf_sz | NV_RX2_AVAIL); + np->rx_ring.ex[nr].FlagLen = cpu_to_le32(np->rx_buf_sz | NV_RX2_AVAIL); } dprintk(KERN_DEBUG "%s: nv_alloc_rx: Packet %d marked as Available\n", dev->name, refill_rx); @@ -1303,16 +1277,6 @@ static int nv_alloc_rx(struct net_device *dev) return 0; } -/* If rx bufs are exhausted called after 50ms to attempt to refresh */ -#ifdef CONFIG_FORCEDETH_NAPI -static void nv_do_rx_refill(unsigned long data) -{ - struct net_device *dev = (struct net_device *) data; - - /* Just reschedule NAPI rx processing */ - netif_rx_schedule(dev); -} -#else static void nv_do_rx_refill(unsigned long data) { struct net_device *dev = (struct net_device *) data; @@ -1341,7 +1305,6 @@ static void nv_do_rx_refill(unsigned long data) enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector); } } -#endif static void nv_init_rx(struct net_device *dev) { @@ -1352,9 +1315,9 @@ static void nv_init_rx(struct net_device *dev) np->refill_rx = 0; for (i = 0; i < np->rx_ring_size; i++) if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) - np->rx_ring.orig[i].flaglen = 0; + np->rx_ring.orig[i].FlagLen = 0; else - np->rx_ring.ex[i].flaglen = 0; + np->rx_ring.ex[i].FlagLen = 0; } static void nv_init_tx(struct net_device *dev) @@ -1365,9 +1328,9 @@ static void nv_init_tx(struct net_device *dev) np->next_tx = np->nic_tx = 0; for (i = 0; i < np->tx_ring_size; i++) { if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) - np->tx_ring.orig[i].flaglen = 0; + np->tx_ring.orig[i].FlagLen = 0; else - np->tx_ring.ex[i].flaglen = 0; + np->tx_ring.ex[i].FlagLen = 0; np->tx_skbuff[i] = NULL; np->tx_dma[i] = 0; } @@ -1410,9 +1373,9 @@ static void nv_drain_tx(struct net_device *dev) for (i = 0; i < np->tx_ring_size; i++) { if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) - np->tx_ring.orig[i].flaglen = 0; + np->tx_ring.orig[i].FlagLen = 0; else - np->tx_ring.ex[i].flaglen = 0; + np->tx_ring.ex[i].FlagLen = 0; if (nv_release_txskb(dev, i)) np->stats.tx_dropped++; } @@ -1424,9 +1387,9 @@ static void nv_drain_rx(struct net_device *dev) int i; for (i = 0; i < np->rx_ring_size; i++) { if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) - np->rx_ring.orig[i].flaglen = 0; + np->rx_ring.orig[i].FlagLen = 0; else - np->rx_ring.ex[i].flaglen = 0; + np->rx_ring.ex[i].FlagLen = 0; wmb(); if (np->rx_skbuff[i]) { pci_unmap_single(np->pci_dev, np->rx_dma[i], @@ -1487,17 +1450,17 @@ static int nv_start_xmit(struct sk_buff *skb, struct net_device *dev) np->tx_dma_len[nr] = bcnt; if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) { - np->tx_ring.orig[nr].buf = cpu_to_le32(np->tx_dma[nr]); - np->tx_ring.orig[nr].flaglen = cpu_to_le32((bcnt-1) | tx_flags); + np->tx_ring.orig[nr].PacketBuffer = cpu_to_le32(np->tx_dma[nr]); + np->tx_ring.orig[nr].FlagLen = cpu_to_le32((bcnt-1) | tx_flags); } else { - np->tx_ring.ex[nr].bufhigh = cpu_to_le64(np->tx_dma[nr]) >> 32; - np->tx_ring.ex[nr].buflow = cpu_to_le64(np->tx_dma[nr]) & 0x0FFFFFFFF; - np->tx_ring.ex[nr].flaglen = cpu_to_le32((bcnt-1) | tx_flags); + np->tx_ring.ex[nr].PacketBufferHigh = cpu_to_le64(np->tx_dma[nr]) >> 32; + np->tx_ring.ex[nr].PacketBufferLow = cpu_to_le64(np->tx_dma[nr]) & 0x0FFFFFFFF; + np->tx_ring.ex[nr].FlagLen = cpu_to_le32((bcnt-1) | tx_flags); } tx_flags = np->tx_flags; offset += bcnt; size -= bcnt; - } while (size); + } while(size); /* setup the fragments */ for (i = 0; i < fragments; i++) { @@ -1514,12 +1477,12 @@ static int nv_start_xmit(struct sk_buff *skb, struct net_device *dev) np->tx_dma_len[nr] = bcnt; if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) { - np->tx_ring.orig[nr].buf = cpu_to_le32(np->tx_dma[nr]); - np->tx_ring.orig[nr].flaglen = cpu_to_le32((bcnt-1) | tx_flags); + np->tx_ring.orig[nr].PacketBuffer = cpu_to_le32(np->tx_dma[nr]); + np->tx_ring.orig[nr].FlagLen = cpu_to_le32((bcnt-1) | tx_flags); } else { - np->tx_ring.ex[nr].bufhigh = cpu_to_le64(np->tx_dma[nr]) >> 32; - np->tx_ring.ex[nr].buflow = cpu_to_le64(np->tx_dma[nr]) & 0x0FFFFFFFF; - np->tx_ring.ex[nr].flaglen = cpu_to_le32((bcnt-1) | tx_flags); + np->tx_ring.ex[nr].PacketBufferHigh = cpu_to_le64(np->tx_dma[nr]) >> 32; + np->tx_ring.ex[nr].PacketBufferLow = cpu_to_le64(np->tx_dma[nr]) & 0x0FFFFFFFF; + np->tx_ring.ex[nr].FlagLen = cpu_to_le32((bcnt-1) | tx_flags); } offset += bcnt; size -= bcnt; @@ -1528,9 +1491,9 @@ static int nv_start_xmit(struct sk_buff *skb, struct net_device *dev) /* set last fragment flag */ if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) { - np->tx_ring.orig[nr].flaglen |= cpu_to_le32(tx_flags_extra); + np->tx_ring.orig[nr].FlagLen |= cpu_to_le32(tx_flags_extra); } else { - np->tx_ring.ex[nr].flaglen |= cpu_to_le32(tx_flags_extra); + np->tx_ring.ex[nr].FlagLen |= cpu_to_le32(tx_flags_extra); } np->tx_skbuff[nr] = skb; @@ -1549,10 +1512,10 @@ static int nv_start_xmit(struct sk_buff *skb, struct net_device *dev) /* set tx flags */ if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) { - np->tx_ring.orig[start_nr].flaglen |= cpu_to_le32(tx_flags | tx_flags_extra); + np->tx_ring.orig[start_nr].FlagLen |= cpu_to_le32(tx_flags | tx_flags_extra); } else { - np->tx_ring.ex[start_nr].txvlan = cpu_to_le32(tx_flags_vlan); - np->tx_ring.ex[start_nr].flaglen |= cpu_to_le32(tx_flags | tx_flags_extra); + np->tx_ring.ex[start_nr].TxVlan = cpu_to_le32(tx_flags_vlan); + np->tx_ring.ex[start_nr].FlagLen |= cpu_to_le32(tx_flags | tx_flags_extra); } dprintk(KERN_DEBUG "%s: nv_start_xmit: packet %d (entries %d) queued for transmission. tx_flags_extra: %x\n", @@ -1584,7 +1547,7 @@ static int nv_start_xmit(struct sk_buff *skb, struct net_device *dev) static void nv_tx_done(struct net_device *dev) { struct fe_priv *np = netdev_priv(dev); - u32 flags; + u32 Flags; unsigned int i; struct sk_buff *skb; @@ -1592,22 +1555,22 @@ static void nv_tx_done(struct net_device *dev) i = np->nic_tx % np->tx_ring_size; if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) - flags = le32_to_cpu(np->tx_ring.orig[i].flaglen); + Flags = le32_to_cpu(np->tx_ring.orig[i].FlagLen); else - flags = le32_to_cpu(np->tx_ring.ex[i].flaglen); + Flags = le32_to_cpu(np->tx_ring.ex[i].FlagLen); - dprintk(KERN_DEBUG "%s: nv_tx_done: looking at packet %d, flags 0x%x.\n", - dev->name, np->nic_tx, flags); - if (flags & NV_TX_VALID) + dprintk(KERN_DEBUG "%s: nv_tx_done: looking at packet %d, Flags 0x%x.\n", + dev->name, np->nic_tx, Flags); + if (Flags & NV_TX_VALID) break; if (np->desc_ver == DESC_VER_1) { - if (flags & NV_TX_LASTPACKET) { + if (Flags & NV_TX_LASTPACKET) { skb = np->tx_skbuff[i]; - if (flags & (NV_TX_RETRYERROR|NV_TX_CARRIERLOST|NV_TX_LATECOLLISION| + if (Flags & (NV_TX_RETRYERROR|NV_TX_CARRIERLOST|NV_TX_LATECOLLISION| NV_TX_UNDERFLOW|NV_TX_ERROR)) { - if (flags & NV_TX_UNDERFLOW) + if (Flags & NV_TX_UNDERFLOW) np->stats.tx_fifo_errors++; - if (flags & NV_TX_CARRIERLOST) + if (Flags & NV_TX_CARRIERLOST) np->stats.tx_carrier_errors++; np->stats.tx_errors++; } else { @@ -1616,13 +1579,13 @@ static void nv_tx_done(struct net_device *dev) } } } else { - if (flags & NV_TX2_LASTPACKET) { + if (Flags & NV_TX2_LASTPACKET) { skb = np->tx_skbuff[i]; - if (flags & (NV_TX2_RETRYERROR|NV_TX2_CARRIERLOST|NV_TX2_LATECOLLISION| + if (Flags & (NV_TX2_RETRYERROR|NV_TX2_CARRIERLOST|NV_TX2_LATECOLLISION| NV_TX2_UNDERFLOW|NV_TX2_ERROR)) { - if (flags & NV_TX2_UNDERFLOW) + if (Flags & NV_TX2_UNDERFLOW) np->stats.tx_fifo_errors++; - if (flags & NV_TX2_CARRIERLOST) + if (Flags & NV_TX2_CARRIERLOST) np->stats.tx_carrier_errors++; np->stats.tx_errors++; } else { @@ -1675,29 +1638,29 @@ static void nv_tx_timeout(struct net_device *dev) if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) { printk(KERN_INFO "%03x: %08x %08x // %08x %08x // %08x %08x // %08x %08x\n", i, - le32_to_cpu(np->tx_ring.orig[i].buf), - le32_to_cpu(np->tx_ring.orig[i].flaglen), - le32_to_cpu(np->tx_ring.orig[i+1].buf), - le32_to_cpu(np->tx_ring.orig[i+1].flaglen), - le32_to_cpu(np->tx_ring.orig[i+2].buf), - le32_to_cpu(np->tx_ring.orig[i+2].flaglen), - le32_to_cpu(np->tx_ring.orig[i+3].buf), - le32_to_cpu(np->tx_ring.orig[i+3].flaglen)); + le32_to_cpu(np->tx_ring.orig[i].PacketBuffer), + le32_to_cpu(np->tx_ring.orig[i].FlagLen), + le32_to_cpu(np->tx_ring.orig[i+1].PacketBuffer), + le32_to_cpu(np->tx_ring.orig[i+1].FlagLen), + le32_to_cpu(np->tx_ring.orig[i+2].PacketBuffer), + le32_to_cpu(np->tx_ring.orig[i+2].FlagLen), + le32_to_cpu(np->tx_ring.orig[i+3].PacketBuffer), + le32_to_cpu(np->tx_ring.orig[i+3].FlagLen)); } else { printk(KERN_INFO "%03x: %08x %08x %08x // %08x %08x %08x // %08x %08x %08x // %08x %08x %08x\n", i, - le32_to_cpu(np->tx_ring.ex[i].bufhigh), - le32_to_cpu(np->tx_ring.ex[i].buflow), - le32_to_cpu(np->tx_ring.ex[i].flaglen), - le32_to_cpu(np->tx_ring.ex[i+1].bufhigh), - le32_to_cpu(np->tx_ring.ex[i+1].buflow), - le32_to_cpu(np->tx_ring.ex[i+1].flaglen), - le32_to_cpu(np->tx_ring.ex[i+2].bufhigh), - le32_to_cpu(np->tx_ring.ex[i+2].buflow), - le32_to_cpu(np->tx_ring.ex[i+2].flaglen), - le32_to_cpu(np->tx_ring.ex[i+3].bufhigh), - le32_to_cpu(np->tx_ring.ex[i+3].buflow), - le32_to_cpu(np->tx_ring.ex[i+3].flaglen)); + le32_to_cpu(np->tx_ring.ex[i].PacketBufferHigh), + le32_to_cpu(np->tx_ring.ex[i].PacketBufferLow), + le32_to_cpu(np->tx_ring.ex[i].FlagLen), + le32_to_cpu(np->tx_ring.ex[i+1].PacketBufferHigh), + le32_to_cpu(np->tx_ring.ex[i+1].PacketBufferLow), + le32_to_cpu(np->tx_ring.ex[i+1].FlagLen), + le32_to_cpu(np->tx_ring.ex[i+2].PacketBufferHigh), + le32_to_cpu(np->tx_ring.ex[i+2].PacketBufferLow), + le32_to_cpu(np->tx_ring.ex[i+2].FlagLen), + le32_to_cpu(np->tx_ring.ex[i+3].PacketBufferHigh), + le32_to_cpu(np->tx_ring.ex[i+3].PacketBufferLow), + le32_to_cpu(np->tx_ring.ex[i+3].FlagLen)); } } } @@ -1734,7 +1697,7 @@ static int nv_getlen(struct net_device *dev, void *packet, int datalen) int protolen; /* length as stored in the proto field */ /* 1) calculate len according to header */ - if ( ((struct vlan_ethhdr *)packet)->h_vlan_proto == htons(ETH_P_8021Q)) { + if ( ((struct vlan_ethhdr *)packet)->h_vlan_proto == __constant_htons(ETH_P_8021Q)) { protolen = ntohs( ((struct vlan_ethhdr *)packet)->h_vlan_encapsulated_proto ); hdrlen = VLAN_HLEN; } else { @@ -1777,14 +1740,13 @@ static int nv_getlen(struct net_device *dev, void *packet, int datalen) } } -static int nv_rx_process(struct net_device *dev, int limit) +static void nv_rx_process(struct net_device *dev) { struct fe_priv *np = netdev_priv(dev); - u32 flags; + u32 Flags; u32 vlanflags = 0; - int count; - for (count = 0; count < limit; ++count) { + for (;;) { struct sk_buff *skb; int len; int i; @@ -1793,18 +1755,18 @@ static int nv_rx_process(struct net_device *dev, int limit) i = np->cur_rx % np->rx_ring_size; if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) { - flags = le32_to_cpu(np->rx_ring.orig[i].flaglen); + Flags = le32_to_cpu(np->rx_ring.orig[i].FlagLen); len = nv_descr_getlength(&np->rx_ring.orig[i], np->desc_ver); } else { - flags = le32_to_cpu(np->rx_ring.ex[i].flaglen); + Flags = le32_to_cpu(np->rx_ring.ex[i].FlagLen); len = nv_descr_getlength_ex(&np->rx_ring.ex[i], np->desc_ver); - vlanflags = le32_to_cpu(np->rx_ring.ex[i].buflow); + vlanflags = le32_to_cpu(np->rx_ring.ex[i].PacketBufferLow); } - dprintk(KERN_DEBUG "%s: nv_rx_process: looking at packet %d, flags 0x%x.\n", - dev->name, np->cur_rx, flags); + dprintk(KERN_DEBUG "%s: nv_rx_process: looking at packet %d, Flags 0x%x.\n", + dev->name, np->cur_rx, Flags); - if (flags & NV_RX_AVAIL) + if (Flags & NV_RX_AVAIL) break; /* still owned by hardware, */ /* @@ -1818,7 +1780,7 @@ static int nv_rx_process(struct net_device *dev, int limit) { int j; - dprintk(KERN_DEBUG "Dumping packet (flags 0x%x).",flags); + dprintk(KERN_DEBUG "Dumping packet (flags 0x%x).",Flags); for (j=0; j<64; j++) { if ((j%16) == 0) dprintk("\n%03x:", j); @@ -1828,30 +1790,30 @@ static int nv_rx_process(struct net_device *dev, int limit) } /* look at what we actually got: */ if (np->desc_ver == DESC_VER_1) { - if (!(flags & NV_RX_DESCRIPTORVALID)) + if (!(Flags & NV_RX_DESCRIPTORVALID)) goto next_pkt; - if (flags & NV_RX_ERROR) { - if (flags & NV_RX_MISSEDFRAME) { + if (Flags & NV_RX_ERROR) { + if (Flags & NV_RX_MISSEDFRAME) { np->stats.rx_missed_errors++; np->stats.rx_errors++; goto next_pkt; } - if (flags & (NV_RX_ERROR1|NV_RX_ERROR2|NV_RX_ERROR3)) { + if (Flags & (NV_RX_ERROR1|NV_RX_ERROR2|NV_RX_ERROR3)) { np->stats.rx_errors++; goto next_pkt; } - if (flags & NV_RX_CRCERR) { + if (Flags & NV_RX_CRCERR) { np->stats.rx_crc_errors++; np->stats.rx_errors++; goto next_pkt; } - if (flags & NV_RX_OVERFLOW) { + if (Flags & NV_RX_OVERFLOW) { np->stats.rx_over_errors++; np->stats.rx_errors++; goto next_pkt; } - if (flags & NV_RX_ERROR4) { + if (Flags & NV_RX_ERROR4) { len = nv_getlen(dev, np->rx_skbuff[i]->data, len); if (len < 0) { np->stats.rx_errors++; @@ -1859,32 +1821,32 @@ static int nv_rx_process(struct net_device *dev, int limit) } } /* framing errors are soft errors. */ - if (flags & NV_RX_FRAMINGERR) { - if (flags & NV_RX_SUBSTRACT1) { + if (Flags & NV_RX_FRAMINGERR) { + if (Flags & NV_RX_SUBSTRACT1) { len--; } } } } else { - if (!(flags & NV_RX2_DESCRIPTORVALID)) + if (!(Flags & NV_RX2_DESCRIPTORVALID)) goto next_pkt; - if (flags & NV_RX2_ERROR) { - if (flags & (NV_RX2_ERROR1|NV_RX2_ERROR2|NV_RX2_ERROR3)) { + if (Flags & NV_RX2_ERROR) { + if (Flags & (NV_RX2_ERROR1|NV_RX2_ERROR2|NV_RX2_ERROR3)) { np->stats.rx_errors++; goto next_pkt; } - if (flags & NV_RX2_CRCERR) { + if (Flags & NV_RX2_CRCERR) { np->stats.rx_crc_errors++; np->stats.rx_errors++; goto next_pkt; } - if (flags & NV_RX2_OVERFLOW) { + if (Flags & NV_RX2_OVERFLOW) { np->stats.rx_over_errors++; np->stats.rx_errors++; goto next_pkt; } - if (flags & NV_RX2_ERROR4) { + if (Flags & NV_RX2_ERROR4) { len = nv_getlen(dev, np->rx_skbuff[i]->data, len); if (len < 0) { np->stats.rx_errors++; @@ -1892,17 +1854,17 @@ static int nv_rx_process(struct net_device *dev, int limit) } } /* framing errors are soft errors */ - if (flags & NV_RX2_FRAMINGERR) { - if (flags & NV_RX2_SUBSTRACT1) { + if (Flags & NV_RX2_FRAMINGERR) { + if (Flags & NV_RX2_SUBSTRACT1) { len--; } } } - if (np->rx_csum) { - flags &= NV_RX2_CHECKSUMMASK; - if (flags == NV_RX2_CHECKSUMOK1 || - flags == NV_RX2_CHECKSUMOK2 || - flags == NV_RX2_CHECKSUMOK3) { + if (np->txrxctl_bits & NVREG_TXRXCTL_RXCHECK) { + Flags &= NV_RX2_CHECKSUMMASK; + if (Flags == NV_RX2_CHECKSUMOK1 || + Flags == NV_RX2_CHECKSUMOK2 || + Flags == NV_RX2_CHECKSUMOK3) { dprintk(KERN_DEBUG "%s: hw checksum hit!.\n", dev->name); np->rx_skbuff[i]->ip_summed = CHECKSUM_UNNECESSARY; } else { @@ -1918,27 +1880,17 @@ static int nv_rx_process(struct net_device *dev, int limit) skb->protocol = eth_type_trans(skb, dev); dprintk(KERN_DEBUG "%s: nv_rx_process: packet %d with %d bytes, proto %d accepted.\n", dev->name, np->cur_rx, len, skb->protocol); -#ifdef CONFIG_FORCEDETH_NAPI - if (np->vlangrp && (vlanflags & NV_RX3_VLAN_TAG_PRESENT)) - vlan_hwaccel_receive_skb(skb, np->vlangrp, - vlanflags & NV_RX3_VLAN_TAG_MASK); - else - netif_receive_skb(skb); -#else - if (np->vlangrp && (vlanflags & NV_RX3_VLAN_TAG_PRESENT)) - vlan_hwaccel_rx(skb, np->vlangrp, - vlanflags & NV_RX3_VLAN_TAG_MASK); - else + if (np->vlangrp && (vlanflags & NV_RX3_VLAN_TAG_PRESENT)) { + vlan_hwaccel_rx(skb, np->vlangrp, vlanflags & NV_RX3_VLAN_TAG_MASK); + } else { netif_rx(skb); -#endif + } dev->last_rx = jiffies; np->stats.rx_packets++; np->stats.rx_bytes += len; next_pkt: np->cur_rx++; } - - return count; } static void set_bufsize(struct net_device *dev) @@ -2038,7 +1990,7 @@ static int nv_set_mac_address(struct net_device *dev, void *addr) struct fe_priv *np = netdev_priv(dev); struct sockaddr *macaddr = (struct sockaddr*)addr; - if (!is_valid_ether_addr(macaddr->sa_data)) + if(!is_valid_ether_addr(macaddr->sa_data)) return -EADDRNOTAVAIL; /* synchronized against open : rtnl_lock() held by caller */ @@ -2331,20 +2283,20 @@ static int nv_update_linkspeed(struct net_device *dev) lpa_pause = lpa & (LPA_PAUSE_CAP| LPA_PAUSE_ASYM); switch (adv_pause) { - case ADVERTISE_PAUSE_CAP: + case (ADVERTISE_PAUSE_CAP): if (lpa_pause & LPA_PAUSE_CAP) { pause_flags |= NV_PAUSEFRAME_RX_ENABLE; if (np->pause_flags & NV_PAUSEFRAME_TX_REQ) pause_flags |= NV_PAUSEFRAME_TX_ENABLE; } break; - case ADVERTISE_PAUSE_ASYM: + case (ADVERTISE_PAUSE_ASYM): if (lpa_pause == (LPA_PAUSE_CAP| LPA_PAUSE_ASYM)) { pause_flags |= NV_PAUSEFRAME_TX_ENABLE; } break; - case ADVERTISE_PAUSE_CAP| ADVERTISE_PAUSE_ASYM: + case (ADVERTISE_PAUSE_CAP| ADVERTISE_PAUSE_ASYM): if (lpa_pause & LPA_PAUSE_CAP) { pause_flags |= NV_PAUSEFRAME_RX_ENABLE; @@ -2424,6 +2376,14 @@ static irqreturn_t nv_nic_irq(int foo, void *data, struct pt_regs *regs) nv_tx_done(dev); spin_unlock(&np->lock); + nv_rx_process(dev); + if (nv_alloc_rx(dev)) { + spin_lock(&np->lock); + if (!np->in_shutdown) + mod_timer(&np->oom_kick, jiffies + OOM_REFILL); + spin_unlock(&np->lock); + } + if (events & NVREG_IRQ_LINK) { spin_lock(&np->lock); nv_link_irq(dev); @@ -2443,29 +2403,6 @@ static irqreturn_t nv_nic_irq(int foo, void *data, struct pt_regs *regs) printk(KERN_DEBUG "%s: received irq with unknown events 0x%x. Please report\n", dev->name, events); } -#ifdef CONFIG_FORCEDETH_NAPI - if (events & NVREG_IRQ_RX_ALL) { - netif_rx_schedule(dev); - - /* Disable furthur receive irq's */ - spin_lock(&np->lock); - np->irqmask &= ~NVREG_IRQ_RX_ALL; - - if (np->msi_flags & NV_MSI_X_ENABLED) - writel(NVREG_IRQ_RX_ALL, base + NvRegIrqMask); - else - writel(np->irqmask, base + NvRegIrqMask); - spin_unlock(&np->lock); - } -#else - nv_rx_process(dev, dev->weight); - if (nv_alloc_rx(dev)) { - spin_lock(&np->lock); - if (!np->in_shutdown) - mod_timer(&np->oom_kick, jiffies + OOM_REFILL); - spin_unlock(&np->lock); - } -#endif if (i > max_interrupt_work) { spin_lock(&np->lock); /* disable interrupts on the nic */ @@ -2537,63 +2474,6 @@ static irqreturn_t nv_nic_irq_tx(int foo, void *data, struct pt_regs *regs) return IRQ_RETVAL(i); } -#ifdef CONFIG_FORCEDETH_NAPI -static int nv_napi_poll(struct net_device *dev, int *budget) -{ - int pkts, limit = min(*budget, dev->quota); - struct fe_priv *np = netdev_priv(dev); - u8 __iomem *base = get_hwbase(dev); - - pkts = nv_rx_process(dev, limit); - - if (nv_alloc_rx(dev)) { - spin_lock_irq(&np->lock); - if (!np->in_shutdown) - mod_timer(&np->oom_kick, jiffies + OOM_REFILL); - spin_unlock_irq(&np->lock); - } - - if (pkts < limit) { - /* all done, no more packets present */ - netif_rx_complete(dev); - - /* re-enable receive interrupts */ - spin_lock_irq(&np->lock); - np->irqmask |= NVREG_IRQ_RX_ALL; - if (np->msi_flags & NV_MSI_X_ENABLED) - writel(NVREG_IRQ_RX_ALL, base + NvRegIrqMask); - else - writel(np->irqmask, base + NvRegIrqMask); - spin_unlock_irq(&np->lock); - return 0; - } else { - /* used up our quantum, so reschedule */ - dev->quota -= pkts; - *budget -= pkts; - return 1; - } -} -#endif - -#ifdef CONFIG_FORCEDETH_NAPI -static irqreturn_t nv_nic_irq_rx(int foo, void *data, struct pt_regs *regs) -{ - struct net_device *dev = (struct net_device *) data; - u8 __iomem *base = get_hwbase(dev); - u32 events; - - events = readl(base + NvRegMSIXIrqStatus) & NVREG_IRQ_RX_ALL; - writel(NVREG_IRQ_RX_ALL, base + NvRegMSIXIrqStatus); - - if (events) { - netif_rx_schedule(dev); - /* disable receive interrupts on the nic */ - writel(NVREG_IRQ_RX_ALL, base + NvRegIrqMask); - pci_push(base); - } - return IRQ_HANDLED; -} -#else static irqreturn_t nv_nic_irq_rx(int foo, void *data, struct pt_regs *regs) { struct net_device *dev = (struct net_device *) data; @@ -2612,7 +2492,7 @@ static irqreturn_t nv_nic_irq_rx(int foo, void *data, struct pt_regs *regs) if (!(events & np->irqmask)) break; - nv_rx_process(dev, dev->weight); + nv_rx_process(dev); if (nv_alloc_rx(dev)) { spin_lock_irq(&np->lock); if (!np->in_shutdown) @@ -2634,12 +2514,12 @@ static irqreturn_t nv_nic_irq_rx(int foo, void *data, struct pt_regs *regs) spin_unlock_irq(&np->lock); break; } + } dprintk(KERN_DEBUG "%s: nv_nic_irq_rx completed\n", dev->name); return IRQ_RETVAL(i); } -#endif static irqreturn_t nv_nic_irq_other(int foo, void *data, struct pt_regs *regs) { @@ -3177,18 +3057,9 @@ static int nv_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) if (netif_running(dev)) printk(KERN_INFO "%s: link down.\n", dev->name); bmcr = mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ); - if (np->phy_model == PHY_MODEL_MARVELL_E3016) { - bmcr |= BMCR_ANENABLE; - /* reset the phy in order for settings to stick, - * and cause autoneg to start */ - if (phy_reset(dev, bmcr)) { - printk(KERN_INFO "%s: phy reset failed\n", dev->name); - return -EINVAL; - } - } else { - bmcr |= (BMCR_ANENABLE | BMCR_ANRESTART); - mii_rw(dev, np->phyaddr, MII_BMCR, bmcr); - } + bmcr |= (BMCR_ANENABLE | BMCR_ANRESTART); + mii_rw(dev, np->phyaddr, MII_BMCR, bmcr); + } else { int adv, bmcr; @@ -3228,19 +3099,17 @@ static int nv_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) bmcr |= BMCR_FULLDPLX; if (np->fixed_mode & (ADVERTISE_100HALF|ADVERTISE_100FULL)) bmcr |= BMCR_SPEED100; + mii_rw(dev, np->phyaddr, MII_BMCR, bmcr); if (np->phy_oui == PHY_OUI_MARVELL) { - /* reset the phy in order for forced mode settings to stick */ - if (phy_reset(dev, bmcr)) { + /* reset the phy */ + if (phy_reset(dev)) { printk(KERN_INFO "%s: phy reset failed\n", dev->name); return -EINVAL; } - } else { - mii_rw(dev, np->phyaddr, MII_BMCR, bmcr); - if (netif_running(dev)) { - /* Wait a bit and then reconfigure the nic. */ - udelay(10); - nv_linkchange(dev); - } + } else if (netif_running(dev)) { + /* Wait a bit and then reconfigure the nic. */ + udelay(10); + nv_linkchange(dev); } } @@ -3297,17 +3166,8 @@ static int nv_nway_reset(struct net_device *dev) } bmcr = mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ); - if (np->phy_model == PHY_MODEL_MARVELL_E3016) { - bmcr |= BMCR_ANENABLE; - /* reset the phy in order for settings to stick*/ - if (phy_reset(dev, bmcr)) { - printk(KERN_INFO "%s: phy reset failed\n", dev->name); - return -EINVAL; - } - } else { - bmcr |= (BMCR_ANENABLE | BMCR_ANRESTART); - mii_rw(dev, np->phyaddr, MII_BMCR, bmcr); - } + bmcr |= (BMCR_ANENABLE | BMCR_ANRESTART); + mii_rw(dev, np->phyaddr, MII_BMCR, bmcr); if (netif_running(dev)) { nv_start_rx(dev); @@ -3385,7 +3245,7 @@ static int nv_set_ringparam(struct net_device *dev, struct ethtool_ringparam* ri if (!rxtx_ring || !rx_skbuff || !rx_dma || !tx_skbuff || !tx_dma || !tx_dma_len) { /* fall back to old rings */ if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) { - if (rxtx_ring) + if(rxtx_ring) pci_free_consistent(np->pci_dev, sizeof(struct ring_desc) * (ring->rx_pending + ring->tx_pending), rxtx_ring, ring_addr); } else { @@ -3558,7 +3418,7 @@ static int nv_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam* static u32 nv_get_rx_csum(struct net_device *dev) { struct fe_priv *np = netdev_priv(dev); - return (np->rx_csum) != 0; + return (np->txrxctl_bits & NVREG_TXRXCTL_RXCHECK) != 0; } static int nv_set_rx_csum(struct net_device *dev, u32 data) @@ -3568,15 +3428,22 @@ static int nv_set_rx_csum(struct net_device *dev, u32 data) int retcode = 0; if (np->driver_data & DEV_HAS_CHECKSUM) { + + if (((np->txrxctl_bits & NVREG_TXRXCTL_RXCHECK) && data) || + (!(np->txrxctl_bits & NVREG_TXRXCTL_RXCHECK) && !data)) { + /* already set or unset */ + return 0; + } + if (data) { - np->rx_csum = 1; np->txrxctl_bits |= NVREG_TXRXCTL_RXCHECK; + } else if (!(np->vlanctl_bits & NVREG_VLANCONTROL_ENABLE)) { + np->txrxctl_bits &= ~NVREG_TXRXCTL_RXCHECK; } else { - np->rx_csum = 0; - /* vlan is dependent on rx checksum offload */ - if (!(np->vlanctl_bits & NVREG_VLANCONTROL_ENABLE)) - np->txrxctl_bits &= ~NVREG_TXRXCTL_RXCHECK; + printk(KERN_INFO "Can not disable rx checksum if vlan is enabled\n"); + return -EINVAL; } + if (netif_running(dev)) { spin_lock_irq(&np->lock); writel(np->txrxctl_bits, base + NvRegTxRxControl); @@ -3614,7 +3481,7 @@ static int nv_get_stats_count(struct net_device *dev) struct fe_priv *np = netdev_priv(dev); if (np->driver_data & DEV_HAS_STATISTICS) - return sizeof(struct nv_ethtool_stats)/sizeof(u64); + return (sizeof(struct nv_ethtool_stats)/sizeof(u64)); else return 0; } @@ -3752,7 +3619,7 @@ static int nv_loopback_test(struct net_device *dev) struct sk_buff *tx_skb, *rx_skb; dma_addr_t test_dma_addr; u32 tx_flags_extra = (np->desc_ver == DESC_VER_1 ? NV_TX_LASTPACKET : NV_TX2_LASTPACKET); - u32 flags; + u32 Flags; int len, i, pkt_len; u8 *pkt_data; u32 filter_flags = 0; @@ -3796,12 +3663,12 @@ static int nv_loopback_test(struct net_device *dev) tx_skb->end-tx_skb->data, PCI_DMA_FROMDEVICE); if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) { - np->tx_ring.orig[0].buf = cpu_to_le32(test_dma_addr); - np->tx_ring.orig[0].flaglen = cpu_to_le32((pkt_len-1) | np->tx_flags | tx_flags_extra); + np->tx_ring.orig[0].PacketBuffer = cpu_to_le32(test_dma_addr); + np->tx_ring.orig[0].FlagLen = cpu_to_le32((pkt_len-1) | np->tx_flags | tx_flags_extra); } else { - np->tx_ring.ex[0].bufhigh = cpu_to_le64(test_dma_addr) >> 32; - np->tx_ring.ex[0].buflow = cpu_to_le64(test_dma_addr) & 0x0FFFFFFFF; - np->tx_ring.ex[0].flaglen = cpu_to_le32((pkt_len-1) | np->tx_flags | tx_flags_extra); + np->tx_ring.ex[0].PacketBufferHigh = cpu_to_le64(test_dma_addr) >> 32; + np->tx_ring.ex[0].PacketBufferLow = cpu_to_le64(test_dma_addr) & 0x0FFFFFFFF; + np->tx_ring.ex[0].FlagLen = cpu_to_le32((pkt_len-1) | np->tx_flags | tx_flags_extra); } writel(NVREG_TXRXCTL_KICK|np->txrxctl_bits, get_hwbase(dev) + NvRegTxRxControl); pci_push(get_hwbase(dev)); @@ -3810,21 +3677,21 @@ static int nv_loopback_test(struct net_device *dev) /* check for rx of the packet */ if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) { - flags = le32_to_cpu(np->rx_ring.orig[0].flaglen); + Flags = le32_to_cpu(np->rx_ring.orig[0].FlagLen); len = nv_descr_getlength(&np->rx_ring.orig[0], np->desc_ver); } else { - flags = le32_to_cpu(np->rx_ring.ex[0].flaglen); + Flags = le32_to_cpu(np->rx_ring.ex[0].FlagLen); len = nv_descr_getlength_ex(&np->rx_ring.ex[0], np->desc_ver); } - if (flags & NV_RX_AVAIL) { + if (Flags & NV_RX_AVAIL) { ret = 0; } else if (np->desc_ver == DESC_VER_1) { - if (flags & NV_RX_ERROR) + if (Flags & NV_RX_ERROR) ret = 0; } else { - if (flags & NV_RX2_ERROR) { + if (Flags & NV_RX2_ERROR) { ret = 0; } } @@ -3886,7 +3753,6 @@ static void nv_self_test(struct net_device *dev, struct ethtool_test *test, u64 if (test->flags & ETH_TEST_FL_OFFLINE) { if (netif_running(dev)) { netif_stop_queue(dev); - netif_poll_disable(dev); netif_tx_lock_bh(dev); spin_lock_irq(&np->lock); nv_disable_hw_interrupts(dev, np->irqmask); @@ -3945,7 +3811,6 @@ static void nv_self_test(struct net_device *dev, struct ethtool_test *test, u64 nv_start_rx(dev); nv_start_tx(dev); netif_start_queue(dev); - netif_poll_enable(dev); nv_enable_hw_interrupts(dev, np->irqmask); } } @@ -4030,9 +3895,10 @@ static int nv_open(struct net_device *dev) dprintk(KERN_DEBUG "nv_open: begin\n"); - /* erase previous misconfiguration */ + /* 1) erase previous misconfiguration */ if (np->driver_data & DEV_HAS_POWER_CNTRL) nv_mac_reset(dev); + /* 4.1-1: stop adapter: ignored, 4.3 seems to be overkill */ writel(NVREG_MCASTADDRA_FORCE, base + NvRegMulticastAddrA); writel(0, base + NvRegMulticastAddrB); writel(0, base + NvRegMulticastMaskA); @@ -4047,22 +3913,26 @@ static int nv_open(struct net_device *dev) if (np->pause_flags & NV_PAUSEFRAME_TX_CAPABLE) writel(NVREG_TX_PAUSEFRAME_DISABLE, base + NvRegTxPauseFrame); - /* initialize descriptor rings */ + /* 2) initialize descriptor rings */ set_bufsize(dev); oom = nv_init_ring(dev); writel(0, base + NvRegLinkSpeed); - writel(readl(base + NvRegTransmitPoll) & NVREG_TRANSMITPOLL_MAC_ADDR_REV, base + NvRegTransmitPoll); + writel(0, base + NvRegUnknownTransmitterReg); nv_txrx_reset(dev); writel(0, base + NvRegUnknownSetupReg6); np->in_shutdown = 0; - /* give hw rings */ + /* 3) set mac address */ + nv_copy_mac_to_hw(dev); + + /* 4) give hw rings */ setup_hw_rings(dev, NV_SETUP_RX_RING | NV_SETUP_TX_RING); writel( ((np->rx_ring_size-1) << NVREG_RINGSZ_RXSHIFT) + ((np->tx_ring_size-1) << NVREG_RINGSZ_TXSHIFT), base + NvRegRingSizes); + /* 5) continue setup */ writel(np->linkspeed, base + NvRegLinkSpeed); if (np->desc_ver == DESC_VER_1) writel(NVREG_TX_WM_DESC1_DEFAULT, base + NvRegTxWatermark); @@ -4080,6 +3950,7 @@ static int nv_open(struct net_device *dev) writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus); writel(NVREG_MIISTAT_MASK2, base + NvRegMIIStatus); + /* 6) continue setup */ writel(NVREG_MISC1_FORCE | NVREG_MISC1_HD, base + NvRegMisc1); writel(readl(base + NvRegTransmitterStatus), base + NvRegTransmitterStatus); writel(NVREG_PFF_ALWAYS, base + NvRegPacketFilterFlags); @@ -4149,8 +4020,6 @@ static int nv_open(struct net_device *dev) nv_start_rx(dev); nv_start_tx(dev); netif_start_queue(dev); - netif_poll_enable(dev); - if (ret) { netif_carrier_on(dev); } else { @@ -4180,7 +4049,6 @@ static int nv_close(struct net_device *dev) spin_lock_irq(&np->lock); np->in_shutdown = 1; spin_unlock_irq(&np->lock); - netif_poll_disable(dev); synchronize_irq(dev->irq); del_timer_sync(&np->oom_kick); @@ -4208,6 +4076,12 @@ static int nv_close(struct net_device *dev) if (np->wolenabled) nv_start_rx(dev); + /* special op: write back the misordered MAC address - otherwise + * the next nv_probe would see a wrong address. + */ + writel(np->orig_mac[0], base + NvRegMacAddrA); + writel(np->orig_mac[1], base + NvRegMacAddrB); + /* FIXME: power down nic */ return 0; @@ -4220,7 +4094,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i unsigned long addr; u8 __iomem *base; int err, i; - u32 powerstate, txreg; + u32 powerstate; dev = alloc_etherdev(sizeof(struct fe_priv)); err = -ENOMEM; @@ -4316,7 +4190,6 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i np->pkt_limit = NV_PKTLIMIT_2; if (id->driver_data & DEV_HAS_CHECKSUM) { - np->rx_csum = 1; np->txrxctl_bits |= NVREG_TXRXCTL_RXCHECK; dev->features |= NETIF_F_HW_CSUM | NETIF_F_SG; #ifdef NETIF_F_TSO @@ -4396,10 +4269,6 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i dev->set_multicast_list = nv_set_multicast; #ifdef CONFIG_NET_POLL_CONTROLLER dev->poll_controller = nv_poll_controller; -#endif - dev->weight = 64; -#ifdef CONFIG_FORCEDETH_NAPI - dev->poll = nv_napi_poll; #endif SET_ETHTOOL_OPS(dev, &ops); dev->tx_timeout = nv_tx_timeout; @@ -4412,30 +4281,12 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i np->orig_mac[0] = readl(base + NvRegMacAddrA); np->orig_mac[1] = readl(base + NvRegMacAddrB); - /* check the workaround bit for correct mac address order */ - txreg = readl(base + NvRegTransmitPoll); - if (txreg & NVREG_TRANSMITPOLL_MAC_ADDR_REV) { - /* mac address is already in correct order */ - dev->dev_addr[0] = (np->orig_mac[0] >> 0) & 0xff; - dev->dev_addr[1] = (np->orig_mac[0] >> 8) & 0xff; - dev->dev_addr[2] = (np->orig_mac[0] >> 16) & 0xff; - dev->dev_addr[3] = (np->orig_mac[0] >> 24) & 0xff; - dev->dev_addr[4] = (np->orig_mac[1] >> 0) & 0xff; - dev->dev_addr[5] = (np->orig_mac[1] >> 8) & 0xff; - } else { - /* need to reverse mac address to correct order */ - dev->dev_addr[0] = (np->orig_mac[1] >> 8) & 0xff; - dev->dev_addr[1] = (np->orig_mac[1] >> 0) & 0xff; - dev->dev_addr[2] = (np->orig_mac[0] >> 24) & 0xff; - dev->dev_addr[3] = (np->orig_mac[0] >> 16) & 0xff; - dev->dev_addr[4] = (np->orig_mac[0] >> 8) & 0xff; - dev->dev_addr[5] = (np->orig_mac[0] >> 0) & 0xff; - /* set permanent address to be correct aswell */ - np->orig_mac[0] = (dev->dev_addr[0] << 0) + (dev->dev_addr[1] << 8) + - (dev->dev_addr[2] << 16) + (dev->dev_addr[3] << 24); - np->orig_mac[1] = (dev->dev_addr[4] << 0) + (dev->dev_addr[5] << 8); - writel(txreg|NVREG_TRANSMITPOLL_MAC_ADDR_REV, base + NvRegTransmitPoll); - } + dev->dev_addr[0] = (np->orig_mac[1] >> 8) & 0xff; + dev->dev_addr[1] = (np->orig_mac[1] >> 0) & 0xff; + dev->dev_addr[2] = (np->orig_mac[0] >> 24) & 0xff; + dev->dev_addr[3] = (np->orig_mac[0] >> 16) & 0xff; + dev->dev_addr[4] = (np->orig_mac[0] >> 8) & 0xff; + dev->dev_addr[5] = (np->orig_mac[0] >> 0) & 0xff; memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len); if (!is_valid_ether_addr(dev->perm_addr)) { @@ -4458,9 +4309,6 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); - /* set mac address */ - nv_copy_mac_to_hw(dev); - /* disable WOL */ writel(0, base + NvRegWakeUpFlags); np->wolenabled = 0; @@ -4521,7 +4369,6 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i if (id2 < 0 || id2 == 0xffff) continue; - np->phy_model = id2 & PHYID2_MODEL_MASK; id1 = (id1 & PHYID1_OUI_MASK) << PHYID1_OUI_SHFT; id2 = (id2 & PHYID2_OUI_MASK) >> PHYID2_OUI_SHFT; dprintk(KERN_DEBUG "%s: open: Found PHY %04x:%04x at address %d.\n", @@ -4574,17 +4421,9 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i static void __devexit nv_remove(struct pci_dev *pci_dev) { struct net_device *dev = pci_get_drvdata(pci_dev); - struct fe_priv *np = netdev_priv(dev); - u8 __iomem *base = get_hwbase(dev); unregister_netdev(dev); - /* special op: write back the misordered MAC address - otherwise - * the next nv_probe would see a wrong address. - */ - writel(np->orig_mac[0], base + NvRegMacAddrA); - writel(np->orig_mac[1], base + NvRegMacAddrB); - /* free all structures */ free_rings(dev); iounmap(get_hwbase(dev)); @@ -4701,7 +4540,7 @@ static struct pci_driver driver = { static int __init init_nic(void) { printk(KERN_INFO "forcedeth.c: Reverse Engineered nForce ethernet driver. Version %s.\n", FORCEDETH_VERSION); - return pci_register_driver(&driver); + return pci_module_init(&driver); } static void __exit exit_nic(void) diff --git a/trunk/drivers/net/fs_enet/Makefile b/trunk/drivers/net/fs_enet/Makefile index 02d4dc18ba69..d6dd3f2fb43e 100644 --- a/trunk/drivers/net/fs_enet/Makefile +++ b/trunk/drivers/net/fs_enet/Makefile @@ -4,7 +4,7 @@ obj-$(CONFIG_FS_ENET) += fs_enet.o -obj-$(CONFIG_8xx) += mac-fec.o mac-scc.o mii-fec.o -obj-$(CONFIG_CPM2) += mac-fcc.o mii-bitbang.o +obj-$(CONFIG_8xx) += mac-fec.o mac-scc.o +obj-$(CONFIG_8260) += mac-fcc.o -fs_enet-objs := fs_enet-main.o +fs_enet-objs := fs_enet-main.o fs_enet-mii.o mii-bitbang.o mii-fixed.o diff --git a/trunk/drivers/net/fs_enet/fec.h b/trunk/drivers/net/fs_enet/fec.h deleted file mode 100644 index e980527e2b99..000000000000 --- a/trunk/drivers/net/fs_enet/fec.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef FS_ENET_FEC_H -#define FS_ENET_FEC_H - -/* CRC polynomium used by the FEC for the multicast group filtering */ -#define FEC_CRC_POLY 0x04C11DB7 - -#define FEC_MAX_MULTICAST_ADDRS 64 - -/* Interrupt events/masks. -*/ -#define FEC_ENET_HBERR 0x80000000U /* Heartbeat error */ -#define FEC_ENET_BABR 0x40000000U /* Babbling receiver */ -#define FEC_ENET_BABT 0x20000000U /* Babbling transmitter */ -#define FEC_ENET_GRA 0x10000000U /* Graceful stop complete */ -#define FEC_ENET_TXF 0x08000000U /* Full frame transmitted */ -#define FEC_ENET_TXB 0x04000000U /* A buffer was transmitted */ -#define FEC_ENET_RXF 0x02000000U /* Full frame received */ -#define FEC_ENET_RXB 0x01000000U /* A buffer was received */ -#define FEC_ENET_MII 0x00800000U /* MII interrupt */ -#define FEC_ENET_EBERR 0x00400000U /* SDMA bus error */ - -#define FEC_ECNTRL_PINMUX 0x00000004 -#define FEC_ECNTRL_ETHER_EN 0x00000002 -#define FEC_ECNTRL_RESET 0x00000001 - -#define FEC_RCNTRL_BC_REJ 0x00000010 -#define FEC_RCNTRL_PROM 0x00000008 -#define FEC_RCNTRL_MII_MODE 0x00000004 -#define FEC_RCNTRL_DRT 0x00000002 -#define FEC_RCNTRL_LOOP 0x00000001 - -#define FEC_TCNTRL_FDEN 0x00000004 -#define FEC_TCNTRL_HBC 0x00000002 -#define FEC_TCNTRL_GTS 0x00000001 - - - -/* - * Delay to wait for FEC reset command to complete (in us) - */ -#define FEC_RESET_DELAY 50 -#endif diff --git a/trunk/drivers/net/fs_enet/fs_enet-main.c b/trunk/drivers/net/fs_enet/fs_enet-main.c index df62506a1787..f6abff5846b3 100644 --- a/trunk/drivers/net/fs_enet/fs_enet-main.c +++ b/trunk/drivers/net/fs_enet/fs_enet-main.c @@ -37,7 +37,6 @@ #include #include #include -#include #include #include @@ -683,6 +682,35 @@ static void fs_free_irq(struct net_device *dev, int irq) (*fep->ops->post_free_irq)(dev, irq); } +/**********************************************************************************/ + +/* This interrupt occurs when the PHY detects a link change. */ +static irqreturn_t +fs_mii_link_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + struct net_device *dev = dev_id; + struct fs_enet_private *fep; + const struct fs_platform_info *fpi; + + fep = netdev_priv(dev); + fpi = fep->fpi; + + /* + * Acknowledge the interrupt if possible. If we have not + * found the PHY yet we can't process or acknowledge the + * interrupt now. Instead we ignore this interrupt for now, + * which we can do since it is edge triggered. It will be + * acknowledged later by fs_enet_open(). + */ + if (!fep->phy) + return IRQ_NONE; + + fs_mii_ack_int(dev); + fs_mii_link_status_change_check(dev, 0); + + return IRQ_HANDLED; +} + static void fs_timeout(struct net_device *dev) { struct fs_enet_private *fep = netdev_priv(dev); @@ -694,13 +722,10 @@ static void fs_timeout(struct net_device *dev) spin_lock_irqsave(&fep->lock, flags); if (dev->flags & IFF_UP) { - phy_stop(fep->phydev); (*fep->ops->stop)(dev); (*fep->ops->restart)(dev); - phy_start(fep->phydev); } - phy_start(fep->phydev); wake = fep->tx_free && !(CBDR_SC(fep->cur_tx) & BD_ENET_TX_READY); spin_unlock_irqrestore(&fep->lock, flags); @@ -708,112 +733,35 @@ static void fs_timeout(struct net_device *dev) netif_wake_queue(dev); } -/*----------------------------------------------------------------------------- - * generic link-change handler - should be sufficient for most cases - *-----------------------------------------------------------------------------*/ -static void generic_adjust_link(struct net_device *dev) -{ - struct fs_enet_private *fep = netdev_priv(dev); - struct phy_device *phydev = fep->phydev; - int new_state = 0; - - if (phydev->link) { - - /* adjust to duplex mode */ - if (phydev->duplex != fep->oldduplex){ - new_state = 1; - fep->oldduplex = phydev->duplex; - } - - if (phydev->speed != fep->oldspeed) { - new_state = 1; - fep->oldspeed = phydev->speed; - } - - if (!fep->oldlink) { - new_state = 1; - fep->oldlink = 1; - netif_schedule(dev); - netif_carrier_on(dev); - netif_start_queue(dev); - } - - if (new_state) - fep->ops->restart(dev); - - } else if (fep->oldlink) { - new_state = 1; - fep->oldlink = 0; - fep->oldspeed = 0; - fep->oldduplex = -1; - netif_carrier_off(dev); - netif_stop_queue(dev); - } - - if (new_state && netif_msg_link(fep)) - phy_print_status(phydev); -} - - -static void fs_adjust_link(struct net_device *dev) -{ - struct fs_enet_private *fep = netdev_priv(dev); - unsigned long flags; - - spin_lock_irqsave(&fep->lock, flags); - - if(fep->ops->adjust_link) - fep->ops->adjust_link(dev); - else - generic_adjust_link(dev); - - spin_unlock_irqrestore(&fep->lock, flags); -} - -static int fs_init_phy(struct net_device *dev) -{ - struct fs_enet_private *fep = netdev_priv(dev); - struct phy_device *phydev; - - fep->oldlink = 0; - fep->oldspeed = 0; - fep->oldduplex = -1; - if(fep->fpi->bus_id) - phydev = phy_connect(dev, fep->fpi->bus_id, &fs_adjust_link, 0); - else { - printk("No phy bus ID specified in BSP code\n"); - return -EINVAL; - } - if (IS_ERR(phydev)) { - printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name); - return PTR_ERR(phydev); - } - - fep->phydev = phydev; - - return 0; -} - - static int fs_enet_open(struct net_device *dev) { struct fs_enet_private *fep = netdev_priv(dev); + const struct fs_platform_info *fpi = fep->fpi; int r; - int err; /* Install our interrupt handler. */ r = fs_request_irq(dev, fep->interrupt, "fs_enet-mac", fs_enet_interrupt); if (r != 0) { printk(KERN_ERR DRV_MODULE_NAME - ": %s Could not allocate FS_ENET IRQ!", dev->name); + ": %s Could not allocate FEC IRQ!", dev->name); return -EINVAL; } - err = fs_init_phy(dev); - if(err) - return err; + /* Install our phy interrupt handler */ + if (fpi->phy_irq != -1) { + + r = fs_request_irq(dev, fpi->phy_irq, "fs_enet-phy", fs_mii_link_interrupt); + if (r != 0) { + printk(KERN_ERR DRV_MODULE_NAME + ": %s Could not allocate PHY IRQ!", dev->name); + fs_free_irq(dev, fep->interrupt); + return -EINVAL; + } + } - phy_start(fep->phydev); + fs_mii_startup(dev); + netif_carrier_off(dev); + fs_mii_link_status_change_check(dev, 1); return 0; } @@ -821,19 +769,20 @@ static int fs_enet_open(struct net_device *dev) static int fs_enet_close(struct net_device *dev) { struct fs_enet_private *fep = netdev_priv(dev); + const struct fs_platform_info *fpi = fep->fpi; unsigned long flags; netif_stop_queue(dev); netif_carrier_off(dev); - phy_stop(fep->phydev); + fs_mii_shutdown(dev); spin_lock_irqsave(&fep->lock, flags); (*fep->ops->stop)(dev); spin_unlock_irqrestore(&fep->lock, flags); /* release any irqs */ - phy_disconnect(fep->phydev); - fep->phydev = NULL; + if (fpi->phy_irq != -1) + fs_free_irq(dev, fpi->phy_irq); fs_free_irq(dev, fep->interrupt); return 0; @@ -881,19 +830,33 @@ static void fs_get_regs(struct net_device *dev, struct ethtool_regs *regs, static int fs_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) { struct fs_enet_private *fep = netdev_priv(dev); - return phy_ethtool_gset(fep->phydev, cmd); + unsigned long flags; + int rc; + + spin_lock_irqsave(&fep->lock, flags); + rc = mii_ethtool_gset(&fep->mii_if, cmd); + spin_unlock_irqrestore(&fep->lock, flags); + + return rc; } static int fs_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) { struct fs_enet_private *fep = netdev_priv(dev); - phy_ethtool_sset(fep->phydev, cmd); - return 0; + unsigned long flags; + int rc; + + spin_lock_irqsave(&fep->lock, flags); + rc = mii_ethtool_sset(&fep->mii_if, cmd); + spin_unlock_irqrestore(&fep->lock, flags); + + return rc; } static int fs_nway_reset(struct net_device *dev) { - return 0; + struct fs_enet_private *fep = netdev_priv(dev); + return mii_nway_restart(&fep->mii_if); } static u32 fs_get_msglevel(struct net_device *dev) @@ -935,7 +898,7 @@ static int fs_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) return -EINVAL; spin_lock_irqsave(&fep->lock, flags); - rc = phy_mii_ioctl(fep->phydev, mii, cmd); + rc = generic_mii_ioctl(&fep->mii_if, mii, cmd, NULL); spin_unlock_irqrestore(&fep->lock, flags); return rc; } @@ -1067,6 +1030,12 @@ static struct net_device *fs_init_instance(struct device *dev, } registered = 1; + err = fs_mii_connect(ndev); + if (err != 0) { + printk(KERN_ERR DRV_MODULE_NAME + ": %s fs_mii_connect failed.\n", ndev->name); + goto err; + } return ndev; @@ -1104,6 +1073,8 @@ static int fs_cleanup_instance(struct net_device *ndev) fpi = fep->fpi; + fs_mii_disconnect(ndev); + unregister_netdev(ndev); dma_free_coherent(fep->dev, (fpi->tx_ring + fpi->rx_ring) * sizeof(cbd_t), @@ -1225,39 +1196,17 @@ static int __init fs_init(void) r = setup_immap(); if (r != 0) return r; - -#ifdef CONFIG_FS_ENET_HAS_FCC - /* let's insert mii stuff */ - r = fs_enet_mdio_bb_init(); - - if (r != 0) { - printk(KERN_ERR DRV_MODULE_NAME - "BB PHY init failed.\n"); - return r; - } - r = driver_register(&fs_enet_fcc_driver); + r = driver_register(&fs_enet_fec_driver); if (r != 0) goto err; -#endif -#ifdef CONFIG_FS_ENET_HAS_FEC - r = fs_enet_mdio_fec_init(); - if (r != 0) { - printk(KERN_ERR DRV_MODULE_NAME - "FEC PHY init failed.\n"); - return r; - } - - r = driver_register(&fs_enet_fec_driver); + r = driver_register(&fs_enet_fcc_driver); if (r != 0) goto err; -#endif -#ifdef CONFIG_FS_ENET_HAS_SCC r = driver_register(&fs_enet_scc_driver); if (r != 0) goto err; -#endif return 0; err: diff --git a/trunk/drivers/net/fs_enet/fs_enet-mii.c b/trunk/drivers/net/fs_enet/fs_enet-mii.c new file mode 100644 index 000000000000..b7e6e21725cb --- /dev/null +++ b/trunk/drivers/net/fs_enet/fs_enet-mii.c @@ -0,0 +1,505 @@ +/* + * Combined Ethernet driver for Motorola MPC8xx and MPC82xx. + * + * Copyright (c) 2003 Intracom S.A. + * by Pantelis Antoniou + * + * 2005 (c) MontaVista Software, Inc. + * Vitaly Bordug + * + * Heavily based on original FEC driver by Dan Malek + * and modifications by Joakim Tjernlund + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "fs_enet.h" + +/*************************************************/ + +/* + * Generic PHY support. + * Should work for all PHYs, but link change is detected by polling + */ + +static void generic_timer_callback(unsigned long data) +{ + struct net_device *dev = (struct net_device *)data; + struct fs_enet_private *fep = netdev_priv(dev); + + fep->phy_timer_list.expires = jiffies + HZ / 2; + + add_timer(&fep->phy_timer_list); + + fs_mii_link_status_change_check(dev, 0); +} + +static void generic_startup(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + + fep->phy_timer_list.expires = jiffies + HZ / 2; /* every 500ms */ + fep->phy_timer_list.data = (unsigned long)dev; + fep->phy_timer_list.function = generic_timer_callback; + add_timer(&fep->phy_timer_list); +} + +static void generic_shutdown(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + + del_timer_sync(&fep->phy_timer_list); +} + +/* ------------------------------------------------------------------------- */ +/* The Davicom DM9161 is used on the NETTA board */ + +/* register definitions */ + +#define MII_DM9161_ANAR 4 /* Aux. Config Register */ +#define MII_DM9161_ACR 16 /* Aux. Config Register */ +#define MII_DM9161_ACSR 17 /* Aux. Config/Status Register */ +#define MII_DM9161_10TCSR 18 /* 10BaseT Config/Status Reg. */ +#define MII_DM9161_INTR 21 /* Interrupt Register */ +#define MII_DM9161_RECR 22 /* Receive Error Counter Reg. */ +#define MII_DM9161_DISCR 23 /* Disconnect Counter Register */ + +static void dm9161_startup(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + + fs_mii_write(dev, fep->mii_if.phy_id, MII_DM9161_INTR, 0x0000); + /* Start autonegotiation */ + fs_mii_write(dev, fep->mii_if.phy_id, MII_BMCR, 0x1200); + + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(HZ*8); +} + +static void dm9161_ack_int(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + + fs_mii_read(dev, fep->mii_if.phy_id, MII_DM9161_INTR); +} + +static void dm9161_shutdown(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + + fs_mii_write(dev, fep->mii_if.phy_id, MII_DM9161_INTR, 0x0f00); +} + +/**********************************************************************************/ + +static const struct phy_info phy_info[] = { + { + .id = 0x00181b88, + .name = "DM9161", + .startup = dm9161_startup, + .ack_int = dm9161_ack_int, + .shutdown = dm9161_shutdown, + }, { + .id = 0, + .name = "GENERIC", + .startup = generic_startup, + .shutdown = generic_shutdown, + }, +}; + +/**********************************************************************************/ + +static int phy_id_detect(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + const struct fs_platform_info *fpi = fep->fpi; + struct fs_enet_mii_bus *bus = fep->mii_bus; + int i, r, start, end, phytype, physubtype; + const struct phy_info *phy; + int phy_hwid, phy_id; + + phy_hwid = -1; + fep->phy = NULL; + + /* auto-detect? */ + if (fpi->phy_addr == -1) { + start = 1; + end = 32; + } else { /* direct */ + start = fpi->phy_addr; + end = start + 1; + } + + for (phy_id = start; phy_id < end; phy_id++) { + /* skip already used phy addresses on this bus */ + if (bus->usage_map & (1 << phy_id)) + continue; + r = fs_mii_read(dev, phy_id, MII_PHYSID1); + if (r == -1 || (phytype = (r & 0xffff)) == 0xffff) + continue; + r = fs_mii_read(dev, phy_id, MII_PHYSID2); + if (r == -1 || (physubtype = (r & 0xffff)) == 0xffff) + continue; + phy_hwid = (phytype << 16) | physubtype; + if (phy_hwid != -1) + break; + } + + if (phy_hwid == -1) { + printk(KERN_ERR DRV_MODULE_NAME + ": %s No PHY detected! range=0x%02x-0x%02x\n", + dev->name, start, end); + return -1; + } + + for (i = 0, phy = phy_info; i < ARRAY_SIZE(phy_info); i++, phy++) + if (phy->id == (phy_hwid >> 4) || phy->id == 0) + break; + + if (i >= ARRAY_SIZE(phy_info)) { + printk(KERN_ERR DRV_MODULE_NAME + ": %s PHY id 0x%08x is not supported!\n", + dev->name, phy_hwid); + return -1; + } + + fep->phy = phy; + + /* mark this address as used */ + bus->usage_map |= (1 << phy_id); + + printk(KERN_INFO DRV_MODULE_NAME + ": %s Phy @ 0x%x, type %s (0x%08x)%s\n", + dev->name, phy_id, fep->phy->name, phy_hwid, + fpi->phy_addr == -1 ? " (auto-detected)" : ""); + + return phy_id; +} + +void fs_mii_startup(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + + if (fep->phy->startup) + (*fep->phy->startup) (dev); +} + +void fs_mii_shutdown(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + + if (fep->phy->shutdown) + (*fep->phy->shutdown) (dev); +} + +void fs_mii_ack_int(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + + if (fep->phy->ack_int) + (*fep->phy->ack_int) (dev); +} + +#define MII_LINK 0x0001 +#define MII_HALF 0x0002 +#define MII_FULL 0x0004 +#define MII_BASE4 0x0008 +#define MII_10M 0x0010 +#define MII_100M 0x0020 +#define MII_1G 0x0040 +#define MII_10G 0x0080 + +/* return full mii info at one gulp, with a usable form */ +static unsigned int mii_full_status(struct mii_if_info *mii) +{ + unsigned int status; + int bmsr, adv, lpa, neg; + struct fs_enet_private* fep = netdev_priv(mii->dev); + + /* first, a dummy read, needed to latch some MII phys */ + (void)mii->mdio_read(mii->dev, mii->phy_id, MII_BMSR); + bmsr = mii->mdio_read(mii->dev, mii->phy_id, MII_BMSR); + + /* no link */ + if ((bmsr & BMSR_LSTATUS) == 0) + return 0; + + status = MII_LINK; + + /* Lets look what ANEG says if it's supported - otherwize we shall + take the right values from the platform info*/ + if(!mii->force_media) { + /* autoneg not completed; don't bother */ + if ((bmsr & BMSR_ANEGCOMPLETE) == 0) + return 0; + + adv = (*mii->mdio_read)(mii->dev, mii->phy_id, MII_ADVERTISE); + lpa = (*mii->mdio_read)(mii->dev, mii->phy_id, MII_LPA); + + neg = lpa & adv; + } else { + neg = fep->fpi->bus_info->lpa; + } + + if (neg & LPA_100FULL) + status |= MII_FULL | MII_100M; + else if (neg & LPA_100BASE4) + status |= MII_FULL | MII_BASE4 | MII_100M; + else if (neg & LPA_100HALF) + status |= MII_HALF | MII_100M; + else if (neg & LPA_10FULL) + status |= MII_FULL | MII_10M; + else + status |= MII_HALF | MII_10M; + + return status; +} + +void fs_mii_link_status_change_check(struct net_device *dev, int init_media) +{ + struct fs_enet_private *fep = netdev_priv(dev); + struct mii_if_info *mii = &fep->mii_if; + unsigned int mii_status; + int ok_to_print, link, duplex, speed; + unsigned long flags; + + ok_to_print = netif_msg_link(fep); + + mii_status = mii_full_status(mii); + + if (!init_media && mii_status == fep->last_mii_status) + return; + + fep->last_mii_status = mii_status; + + link = !!(mii_status & MII_LINK); + duplex = !!(mii_status & MII_FULL); + speed = (mii_status & MII_100M) ? 100 : 10; + + if (link == 0) { + netif_carrier_off(mii->dev); + netif_stop_queue(dev); + if (!init_media) { + spin_lock_irqsave(&fep->lock, flags); + (*fep->ops->stop)(dev); + spin_unlock_irqrestore(&fep->lock, flags); + } + + if (ok_to_print) + printk(KERN_INFO "%s: link down\n", mii->dev->name); + + } else { + + mii->full_duplex = duplex; + + netif_carrier_on(mii->dev); + + spin_lock_irqsave(&fep->lock, flags); + fep->duplex = duplex; + fep->speed = speed; + (*fep->ops->restart)(dev); + spin_unlock_irqrestore(&fep->lock, flags); + + netif_start_queue(dev); + + if (ok_to_print) + printk(KERN_INFO "%s: link up, %dMbps, %s-duplex\n", + dev->name, speed, duplex ? "full" : "half"); + } +} + +/**********************************************************************************/ + +int fs_mii_read(struct net_device *dev, int phy_id, int location) +{ + struct fs_enet_private *fep = netdev_priv(dev); + struct fs_enet_mii_bus *bus = fep->mii_bus; + + unsigned long flags; + int ret; + + spin_lock_irqsave(&bus->mii_lock, flags); + ret = (*bus->mii_read)(bus, phy_id, location); + spin_unlock_irqrestore(&bus->mii_lock, flags); + + return ret; +} + +void fs_mii_write(struct net_device *dev, int phy_id, int location, int value) +{ + struct fs_enet_private *fep = netdev_priv(dev); + struct fs_enet_mii_bus *bus = fep->mii_bus; + unsigned long flags; + + spin_lock_irqsave(&bus->mii_lock, flags); + (*bus->mii_write)(bus, phy_id, location, value); + spin_unlock_irqrestore(&bus->mii_lock, flags); +} + +/*****************************************************************************/ + +/* list of all registered mii buses */ +static LIST_HEAD(fs_mii_bus_list); + +static struct fs_enet_mii_bus *lookup_bus(int method, int id) +{ + struct list_head *ptr; + struct fs_enet_mii_bus *bus; + + list_for_each(ptr, &fs_mii_bus_list) { + bus = list_entry(ptr, struct fs_enet_mii_bus, list); + if (bus->bus_info->method == method && + bus->bus_info->id == id) + return bus; + } + return NULL; +} + +static struct fs_enet_mii_bus *create_bus(const struct fs_mii_bus_info *bi) +{ + struct fs_enet_mii_bus *bus; + int ret = 0; + + bus = kmalloc(sizeof(*bus), GFP_KERNEL); + if (bus == NULL) { + ret = -ENOMEM; + goto err; + } + memset(bus, 0, sizeof(*bus)); + spin_lock_init(&bus->mii_lock); + bus->bus_info = bi; + bus->refs = 0; + bus->usage_map = 0; + + /* perform initialization */ + switch (bi->method) { + + case fsmii_fixed: + ret = fs_mii_fixed_init(bus); + if (ret != 0) + goto err; + break; + + case fsmii_bitbang: + ret = fs_mii_bitbang_init(bus); + if (ret != 0) + goto err; + break; +#ifdef CONFIG_FS_ENET_HAS_FEC + case fsmii_fec: + ret = fs_mii_fec_init(bus); + if (ret != 0) + goto err; + break; +#endif + default: + ret = -EINVAL; + goto err; + } + + list_add(&bus->list, &fs_mii_bus_list); + + return bus; + +err: + kfree(bus); + return ERR_PTR(ret); +} + +static void destroy_bus(struct fs_enet_mii_bus *bus) +{ + /* remove from bus list */ + list_del(&bus->list); + + /* nothing more needed */ + kfree(bus); +} + +int fs_mii_connect(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + const struct fs_platform_info *fpi = fep->fpi; + struct fs_enet_mii_bus *bus = NULL; + + /* check method validity */ + switch (fpi->bus_info->method) { + case fsmii_fixed: + case fsmii_bitbang: + break; +#ifdef CONFIG_FS_ENET_HAS_FEC + case fsmii_fec: + break; +#endif + default: + printk(KERN_ERR DRV_MODULE_NAME + ": %s Unknown MII bus method (%d)!\n", + dev->name, fpi->bus_info->method); + return -EINVAL; + } + + bus = lookup_bus(fpi->bus_info->method, fpi->bus_info->id); + + /* if not found create new bus */ + if (bus == NULL) { + bus = create_bus(fpi->bus_info); + if (IS_ERR(bus)) { + printk(KERN_ERR DRV_MODULE_NAME + ": %s MII bus creation failure!\n", dev->name); + return PTR_ERR(bus); + } + } + + bus->refs++; + + fep->mii_bus = bus; + + fep->mii_if.dev = dev; + fep->mii_if.phy_id_mask = 0x1f; + fep->mii_if.reg_num_mask = 0x1f; + fep->mii_if.mdio_read = fs_mii_read; + fep->mii_if.mdio_write = fs_mii_write; + fep->mii_if.force_media = fpi->bus_info->disable_aneg; + fep->mii_if.phy_id = phy_id_detect(dev); + + return 0; +} + +void fs_mii_disconnect(struct net_device *dev) +{ + struct fs_enet_private *fep = netdev_priv(dev); + struct fs_enet_mii_bus *bus = NULL; + + bus = fep->mii_bus; + fep->mii_bus = NULL; + + if (--bus->refs <= 0) + destroy_bus(bus); +} diff --git a/trunk/drivers/net/fs_enet/fs_enet.h b/trunk/drivers/net/fs_enet/fs_enet.h index 95022c005f75..e7ec96c964a9 100644 --- a/trunk/drivers/net/fs_enet/fs_enet.h +++ b/trunk/drivers/net/fs_enet/fs_enet.h @@ -5,7 +5,6 @@ #include #include #include -#include #include @@ -13,30 +12,12 @@ #ifdef CONFIG_CPM1 #include - -struct fec_info { - fec_t* fecp; - u32 mii_speed; -}; #endif #ifdef CONFIG_CPM2 #include #endif -/* This is used to operate with pins. - Note that the actual port size may - be different; cpm(s) handle it OK */ -struct bb_info { - u8 mdio_dat_msk; - u8 mdio_dir_msk; - u8 *mdio_dir; - u8 *mdio_dat; - u8 mdc_msk; - u8 *mdc_dat; - int delay; -}; - /* hw driver ops */ struct fs_ops { int (*setup_data)(struct net_device *dev); @@ -44,7 +25,6 @@ struct fs_ops { void (*free_bd)(struct net_device *dev); void (*cleanup_data)(struct net_device *dev); void (*set_multicast_list)(struct net_device *dev); - void (*adjust_link)(struct net_device *dev); void (*restart)(struct net_device *dev); void (*stop)(struct net_device *dev); void (*pre_request_irq)(struct net_device *dev, int irq); @@ -120,6 +100,10 @@ struct fs_enet_mii_bus { }; }; +int fs_mii_bitbang_init(struct fs_enet_mii_bus *bus); +int fs_mii_fixed_init(struct fs_enet_mii_bus *bus); +int fs_mii_fec_init(struct fs_enet_mii_bus *bus); + struct fs_enet_private { struct device *dev; /* pointer back to the device (must be initialized first) */ spinlock_t lock; /* during all ops except TX pckt processing */ @@ -146,8 +130,7 @@ struct fs_enet_private { struct fs_enet_mii_bus *mii_bus; int interrupt; - struct phy_device *phydev; - int oldduplex, oldspeed, oldlink; /* current settings */ + int duplex, speed; /* current settings */ /* event masks */ u32 ev_napi_rx; /* mask of NAPI rx events */ @@ -185,9 +168,15 @@ struct fs_enet_private { }; /***************************************************************************/ -int fs_enet_mdio_bb_init(void); -int fs_mii_fixed_init(struct fs_enet_mii_bus *bus); -int fs_enet_mdio_fec_init(void); + +int fs_mii_read(struct net_device *dev, int phy_id, int location); +void fs_mii_write(struct net_device *dev, int phy_id, int location, int value); + +void fs_mii_startup(struct net_device *dev); +void fs_mii_shutdown(struct net_device *dev); +void fs_mii_ack_int(struct net_device *dev); + +void fs_mii_link_status_change_check(struct net_device *dev, int init_media); void fs_init_bds(struct net_device *dev); void fs_cleanup_bds(struct net_device *dev); @@ -205,6 +194,7 @@ int fs_enet_platform_init(void); void fs_enet_platform_cleanup(void); /***************************************************************************/ + /* buffer descriptor access macros */ /* access macros */ diff --git a/trunk/drivers/net/fs_enet/mac-fcc.c b/trunk/drivers/net/fs_enet/mac-fcc.c index 1ff2597b8495..64e20982c1fe 100644 --- a/trunk/drivers/net/fs_enet/mac-fcc.c +++ b/trunk/drivers/net/fs_enet/mac-fcc.c @@ -34,7 +34,6 @@ #include #include #include -#include #include #include @@ -123,32 +122,22 @@ static int do_pd_setup(struct fs_enet_private *fep) /* Attach the memory for the FCC Parameter RAM */ r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "fcc_pram"); - fep->fcc.ep = (void *)ioremap(r->start, r->end - r->start + 1); + fep->fcc.ep = (void *)r->start; + if (fep->fcc.ep == NULL) return -EINVAL; r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "fcc_regs"); - fep->fcc.fccp = (void *)ioremap(r->start, r->end - r->start + 1); + fep->fcc.fccp = (void *)r->start; + if (fep->fcc.fccp == NULL) return -EINVAL; - if (fep->fpi->fcc_regs_c) { - - fep->fcc.fcccp = (void *)fep->fpi->fcc_regs_c; - } else { - r = platform_get_resource_byname(pdev, IORESOURCE_MEM, - "fcc_regs_c"); - fep->fcc.fcccp = (void *)ioremap(r->start, - r->end - r->start + 1); - } + fep->fcc.fcccp = (void *)fep->fpi->fcc_regs_c; if (fep->fcc.fcccp == NULL) return -EINVAL; - fep->fcc.mem = (void *)fep->fpi->mem_offset; - if (fep->fcc.mem == NULL) - return -EINVAL; - return 0; } @@ -166,6 +155,8 @@ static int setup_data(struct net_device *dev) if ((unsigned int)fep->fcc.idx >= 3) /* max 3 FCCs */ return -EINVAL; + fep->fcc.mem = (void *)fpi->mem_offset; + if (do_pd_setup(fep) != 0) return -EINVAL; @@ -403,7 +394,7 @@ static void restart(struct net_device *dev) /* adjust to speed (for RMII mode) */ if (fpi->use_rmii) { - if (fep->phydev->speed == 100) + if (fep->speed == 100) C8(fcccp, fcc_gfemr, 0x20); else S8(fcccp, fcc_gfemr, 0x20); @@ -429,7 +420,7 @@ static void restart(struct net_device *dev) S32(fccp, fcc_fpsmr, FCC_PSMR_RMII); /* adjust to duplex mode */ - if (fep->phydev->duplex) + if (fep->duplex) S32(fccp, fcc_fpsmr, FCC_PSMR_FDE | FCC_PSMR_LPB); else C32(fccp, fcc_fpsmr, FCC_PSMR_FDE | FCC_PSMR_LPB); @@ -495,10 +486,7 @@ static void rx_bd_done(struct net_device *dev) static void tx_kickstart(struct net_device *dev) { - struct fs_enet_private *fep = netdev_priv(dev); - fcc_t *fccp = fep->fcc.fccp; - - S32(fccp, fcc_ftodr, 0x80); + /* nothing */ } static u32 get_int_events(struct net_device *dev) diff --git a/trunk/drivers/net/fs_enet/mac-fec.c b/trunk/drivers/net/fs_enet/mac-fec.c index c2c5fd419bd0..e09547077529 100644 --- a/trunk/drivers/net/fs_enet/mac-fec.c +++ b/trunk/drivers/net/fs_enet/mac-fec.c @@ -46,7 +46,6 @@ #endif #include "fs_enet.h" -#include "fec.h" /*************************************************/ @@ -76,8 +75,50 @@ /* clear bits */ #define FC(_fecp, _reg, _v) FW(_fecp, _reg, FR(_fecp, _reg) & ~(_v)) + +/* CRC polynomium used by the FEC for the multicast group filtering */ +#define FEC_CRC_POLY 0x04C11DB7 + +#define FEC_MAX_MULTICAST_ADDRS 64 + +/* Interrupt events/masks. +*/ +#define FEC_ENET_HBERR 0x80000000U /* Heartbeat error */ +#define FEC_ENET_BABR 0x40000000U /* Babbling receiver */ +#define FEC_ENET_BABT 0x20000000U /* Babbling transmitter */ +#define FEC_ENET_GRA 0x10000000U /* Graceful stop complete */ +#define FEC_ENET_TXF 0x08000000U /* Full frame transmitted */ +#define FEC_ENET_TXB 0x04000000U /* A buffer was transmitted */ +#define FEC_ENET_RXF 0x02000000U /* Full frame received */ +#define FEC_ENET_RXB 0x01000000U /* A buffer was received */ +#define FEC_ENET_MII 0x00800000U /* MII interrupt */ +#define FEC_ENET_EBERR 0x00400000U /* SDMA bus error */ + +#define FEC_ECNTRL_PINMUX 0x00000004 +#define FEC_ECNTRL_ETHER_EN 0x00000002 +#define FEC_ECNTRL_RESET 0x00000001 + +#define FEC_RCNTRL_BC_REJ 0x00000010 +#define FEC_RCNTRL_PROM 0x00000008 +#define FEC_RCNTRL_MII_MODE 0x00000004 +#define FEC_RCNTRL_DRT 0x00000002 +#define FEC_RCNTRL_LOOP 0x00000001 + +#define FEC_TCNTRL_FDEN 0x00000004 +#define FEC_TCNTRL_HBC 0x00000002 +#define FEC_TCNTRL_GTS 0x00000001 + + +/* Make MII read/write commands for the FEC. +*/ +#define mk_mii_read(REG) (0x60020000 | ((REG & 0x1f) << 18)) +#define mk_mii_write(REG, VAL) (0x50020000 | ((REG & 0x1f) << 18) | (VAL & 0xffff)) +#define mk_mii_end 0 + +#define FEC_MII_LOOPS 10000 + /* - * Delay to wait for FEC reset command to complete (in us) + * Delay to wait for FEC reset command to complete (in us) */ #define FEC_RESET_DELAY 50 @@ -262,15 +303,13 @@ static void restart(struct net_device *dev) int r; u32 addrhi, addrlo; - struct mii_bus* mii = fep->phydev->bus; - struct fec_info* fec_inf = mii->priv; - r = whack_reset(fep->fec.fecp); if (r != 0) printk(KERN_ERR DRV_MODULE_NAME ": %s FEC Reset FAILED!\n", dev->name); + /* - * Set station address. + * Set station address. */ addrhi = ((u32) dev->dev_addr[0] << 24) | ((u32) dev->dev_addr[1] << 16) | @@ -311,12 +350,12 @@ static void restart(struct net_device *dev) FW(fecp, fun_code, 0x78000000); /* - * Set MII speed. + * Set MII speed. */ - FW(fecp, mii_speed, fec_inf->mii_speed); + FW(fecp, mii_speed, fep->mii_bus->fec.mii_speed); /* - * Clear any outstanding interrupt. + * Clear any outstanding interrupt. */ FW(fecp, ievent, 0xffc0); FW(fecp, ivec, (fep->interrupt / 2) << 29); @@ -351,12 +390,11 @@ static void restart(struct net_device *dev) } #endif - FW(fecp, r_cntrl, FEC_RCNTRL_MII_MODE); /* MII enable */ /* - * adjust to duplex mode + * adjust to duplex mode */ - if (fep->phydev->duplex) { + if (fep->duplex) { FC(fecp, r_cntrl, FEC_RCNTRL_DRT); FS(fecp, x_cntrl, FEC_TCNTRL_FDEN); /* FD enable */ } else { @@ -380,11 +418,9 @@ static void restart(struct net_device *dev) static void stop(struct net_device *dev) { struct fs_enet_private *fep = netdev_priv(dev); - const struct fs_platform_info *fpi = fep->fpi; fec_t *fecp = fep->fec.fecp; - - struct fec_info* feci= fep->phydev->bus->priv; - + struct fs_enet_mii_bus *bus = fep->mii_bus; + const struct fs_mii_bus_info *bi = bus->bus_info; int i; if ((FR(fecp, ecntrl) & FEC_ECNTRL_ETHER_EN) == 0) @@ -408,11 +444,11 @@ static void stop(struct net_device *dev) fs_cleanup_bds(dev); /* shut down FEC1? that's where the mii bus is */ - if (fpi->has_phy) { + if (fep->fec.idx == 0 && bus->refs > 1 && bi->method == fsmii_fec) { FS(fecp, r_cntrl, FEC_RCNTRL_MII_MODE); /* MII enable */ FS(fecp, ecntrl, FEC_ECNTRL_PINMUX | FEC_ECNTRL_ETHER_EN); FW(fecp, ievent, FEC_ENET_MII); - FW(fecp, mii_speed, feci->mii_speed); + FW(fecp, mii_speed, bus->fec.mii_speed); } } @@ -547,3 +583,73 @@ const struct fs_ops fs_fec_ops = { .free_bd = free_bd, }; +/***********************************************************************/ + +static int mii_read(struct fs_enet_mii_bus *bus, int phy_id, int location) +{ + fec_t *fecp = bus->fec.fecp; + int i, ret = -1; + + if ((FR(fecp, r_cntrl) & FEC_RCNTRL_MII_MODE) == 0) + BUG(); + + /* Add PHY address to register command. */ + FW(fecp, mii_data, (phy_id << 23) | mk_mii_read(location)); + + for (i = 0; i < FEC_MII_LOOPS; i++) + if ((FR(fecp, ievent) & FEC_ENET_MII) != 0) + break; + + if (i < FEC_MII_LOOPS) { + FW(fecp, ievent, FEC_ENET_MII); + ret = FR(fecp, mii_data) & 0xffff; + } + + return ret; +} + +static void mii_write(struct fs_enet_mii_bus *bus, int phy_id, int location, int value) +{ + fec_t *fecp = bus->fec.fecp; + int i; + + /* this must never happen */ + if ((FR(fecp, r_cntrl) & FEC_RCNTRL_MII_MODE) == 0) + BUG(); + + /* Add PHY address to register command. */ + FW(fecp, mii_data, (phy_id << 23) | mk_mii_write(location, value)); + + for (i = 0; i < FEC_MII_LOOPS; i++) + if ((FR(fecp, ievent) & FEC_ENET_MII) != 0) + break; + + if (i < FEC_MII_LOOPS) + FW(fecp, ievent, FEC_ENET_MII); +} + +int fs_mii_fec_init(struct fs_enet_mii_bus *bus) +{ + bd_t *bd = (bd_t *)__res; + const struct fs_mii_bus_info *bi = bus->bus_info; + fec_t *fecp; + + if (bi->id != 0) + return -1; + + bus->fec.fecp = &((immap_t *)fs_enet_immap)->im_cpm.cp_fec; + bus->fec.mii_speed = ((((bd->bi_intfreq + 4999999) / 2500000) / 2) + & 0x3F) << 1; + + fecp = bus->fec.fecp; + + FS(fecp, r_cntrl, FEC_RCNTRL_MII_MODE); /* MII enable */ + FS(fecp, ecntrl, FEC_ECNTRL_PINMUX | FEC_ECNTRL_ETHER_EN); + FW(fecp, ievent, FEC_ENET_MII); + FW(fecp, mii_speed, bus->fec.mii_speed); + + bus->mii_read = mii_read; + bus->mii_write = mii_write; + + return 0; +} diff --git a/trunk/drivers/net/fs_enet/mac-scc.c b/trunk/drivers/net/fs_enet/mac-scc.c index 95ec5872c507..eaa24fab645f 100644 --- a/trunk/drivers/net/fs_enet/mac-scc.c +++ b/trunk/drivers/net/fs_enet/mac-scc.c @@ -369,7 +369,7 @@ static void restart(struct net_device *dev) W16(sccp, scc_psmr, SCC_PSMR_ENCRC | SCC_PSMR_NIB22); /* Set full duplex mode if needed */ - if (fep->phydev->duplex) + if (fep->duplex) S16(sccp, scc_psmr, SCC_PSMR_LPB | SCC_PSMR_FDE); S32(sccp, scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT); @@ -500,8 +500,6 @@ static void tx_restart(struct net_device *dev) scc_cr_cmd(fep, CPM_CR_RESTART_TX); } - - /*************************************************************************/ const struct fs_ops fs_scc_ops = { diff --git a/trunk/drivers/net/fs_enet/mii-bitbang.c b/trunk/drivers/net/fs_enet/mii-bitbang.c index 0b9b8b5c847c..48f9cf83ab6f 100644 --- a/trunk/drivers/net/fs_enet/mii-bitbang.c +++ b/trunk/drivers/net/fs_enet/mii-bitbang.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include @@ -41,25 +40,129 @@ #include "fs_enet.h" -static int bitbang_prep_bit(u8 **datp, u8 *mskp, - struct fs_mii_bit *mii_bit) +#ifdef CONFIG_8xx +static int bitbang_prep_bit(u8 **dirp, u8 **datp, u8 *mskp, int port, int bit) { - void *dat; + immap_t *im = (immap_t *)fs_enet_immap; + void *dir, *dat, *ppar; int adv; u8 msk; - dat = (void*) mii_bit->offset; + switch (port) { + case fsiop_porta: + dir = &im->im_ioport.iop_padir; + dat = &im->im_ioport.iop_padat; + ppar = &im->im_ioport.iop_papar; + break; + + case fsiop_portb: + dir = &im->im_cpm.cp_pbdir; + dat = &im->im_cpm.cp_pbdat; + ppar = &im->im_cpm.cp_pbpar; + break; + + case fsiop_portc: + dir = &im->im_ioport.iop_pcdir; + dat = &im->im_ioport.iop_pcdat; + ppar = &im->im_ioport.iop_pcpar; + break; + + case fsiop_portd: + dir = &im->im_ioport.iop_pddir; + dat = &im->im_ioport.iop_pddat; + ppar = &im->im_ioport.iop_pdpar; + break; + + case fsiop_porte: + dir = &im->im_cpm.cp_pedir; + dat = &im->im_cpm.cp_pedat; + ppar = &im->im_cpm.cp_pepar; + break; + + default: + printk(KERN_ERR DRV_MODULE_NAME + "Illegal port value %d!\n", port); + return -EINVAL; + } + + adv = bit >> 3; + dir = (char *)dir + adv; + dat = (char *)dat + adv; + ppar = (char *)ppar + adv; + + msk = 1 << (7 - (bit & 7)); + if ((in_8(ppar) & msk) != 0) { + printk(KERN_ERR DRV_MODULE_NAME + "pin %d on port %d is not general purpose!\n", bit, port); + return -EINVAL; + } + + *dirp = dir; + *datp = dat; + *mskp = msk; + + return 0; +} +#endif + +#ifdef CONFIG_8260 +static int bitbang_prep_bit(u8 **dirp, u8 **datp, u8 *mskp, int port, int bit) +{ + iop_cpm2_t *io = &((cpm2_map_t *)fs_enet_immap)->im_ioport; + void *dir, *dat, *ppar; + int adv; + u8 msk; + + switch (port) { + case fsiop_porta: + dir = &io->iop_pdira; + dat = &io->iop_pdata; + ppar = &io->iop_ppara; + break; + + case fsiop_portb: + dir = &io->iop_pdirb; + dat = &io->iop_pdatb; + ppar = &io->iop_pparb; + break; + + case fsiop_portc: + dir = &io->iop_pdirc; + dat = &io->iop_pdatc; + ppar = &io->iop_pparc; + break; + + case fsiop_portd: + dir = &io->iop_pdird; + dat = &io->iop_pdatd; + ppar = &io->iop_ppard; + break; + + default: + printk(KERN_ERR DRV_MODULE_NAME + "Illegal port value %d!\n", port); + return -EINVAL; + } - adv = mii_bit->bit >> 3; + adv = bit >> 3; + dir = (char *)dir + adv; dat = (char *)dat + adv; + ppar = (char *)ppar + adv; - msk = 1 << (7 - (mii_bit->bit & 7)); + msk = 1 << (7 - (bit & 7)); + if ((in_8(ppar) & msk) != 0) { + printk(KERN_ERR DRV_MODULE_NAME + "pin %d on port %d is not general purpose!\n", bit, port); + return -EINVAL; + } + *dirp = dir; *datp = dat; *mskp = msk; return 0; } +#endif static inline void bb_set(u8 *p, u8 m) { @@ -76,44 +179,44 @@ static inline int bb_read(u8 *p, u8 m) return (in_8(p) & m) != 0; } -static inline void mdio_active(struct bb_info *bitbang) +static inline void mdio_active(struct fs_enet_mii_bus *bus) { - bb_set(bitbang->mdio_dir, bitbang->mdio_dir_msk); + bb_set(bus->bitbang.mdio_dir, bus->bitbang.mdio_msk); } -static inline void mdio_tristate(struct bb_info *bitbang ) +static inline void mdio_tristate(struct fs_enet_mii_bus *bus) { - bb_clr(bitbang->mdio_dir, bitbang->mdio_dir_msk); + bb_clr(bus->bitbang.mdio_dir, bus->bitbang.mdio_msk); } -static inline int mdio_read(struct bb_info *bitbang ) +static inline int mdio_read(struct fs_enet_mii_bus *bus) { - return bb_read(bitbang->mdio_dat, bitbang->mdio_dat_msk); + return bb_read(bus->bitbang.mdio_dat, bus->bitbang.mdio_msk); } -static inline void mdio(struct bb_info *bitbang , int what) +static inline void mdio(struct fs_enet_mii_bus *bus, int what) { if (what) - bb_set(bitbang->mdio_dat, bitbang->mdio_dat_msk); + bb_set(bus->bitbang.mdio_dat, bus->bitbang.mdio_msk); else - bb_clr(bitbang->mdio_dat, bitbang->mdio_dat_msk); + bb_clr(bus->bitbang.mdio_dat, bus->bitbang.mdio_msk); } -static inline void mdc(struct bb_info *bitbang , int what) +static inline void mdc(struct fs_enet_mii_bus *bus, int what) { if (what) - bb_set(bitbang->mdc_dat, bitbang->mdc_msk); + bb_set(bus->bitbang.mdc_dat, bus->bitbang.mdc_msk); else - bb_clr(bitbang->mdc_dat, bitbang->mdc_msk); + bb_clr(bus->bitbang.mdc_dat, bus->bitbang.mdc_msk); } -static inline void mii_delay(struct bb_info *bitbang ) +static inline void mii_delay(struct fs_enet_mii_bus *bus) { - udelay(bitbang->delay); + udelay(bus->bus_info->i.bitbang.delay); } /* Utility to send the preamble, address, and register (common to read and write). */ -static void bitbang_pre(struct bb_info *bitbang , int read, u8 addr, u8 reg) +static void bitbang_pre(struct fs_enet_mii_bus *bus, int read, u8 addr, u8 reg) { int j; @@ -125,284 +228,177 @@ static void bitbang_pre(struct bb_info *bitbang , int read, u8 addr, u8 reg) * but it is safer and will be much more robust. */ - mdio_active(bitbang); - mdio(bitbang, 1); + mdio_active(bus); + mdio(bus, 1); for (j = 0; j < 32; j++) { - mdc(bitbang, 0); - mii_delay(bitbang); - mdc(bitbang, 1); - mii_delay(bitbang); + mdc(bus, 0); + mii_delay(bus); + mdc(bus, 1); + mii_delay(bus); } /* send the start bit (01) and the read opcode (10) or write (10) */ - mdc(bitbang, 0); - mdio(bitbang, 0); - mii_delay(bitbang); - mdc(bitbang, 1); - mii_delay(bitbang); - mdc(bitbang, 0); - mdio(bitbang, 1); - mii_delay(bitbang); - mdc(bitbang, 1); - mii_delay(bitbang); - mdc(bitbang, 0); - mdio(bitbang, read); - mii_delay(bitbang); - mdc(bitbang, 1); - mii_delay(bitbang); - mdc(bitbang, 0); - mdio(bitbang, !read); - mii_delay(bitbang); - mdc(bitbang, 1); - mii_delay(bitbang); + mdc(bus, 0); + mdio(bus, 0); + mii_delay(bus); + mdc(bus, 1); + mii_delay(bus); + mdc(bus, 0); + mdio(bus, 1); + mii_delay(bus); + mdc(bus, 1); + mii_delay(bus); + mdc(bus, 0); + mdio(bus, read); + mii_delay(bus); + mdc(bus, 1); + mii_delay(bus); + mdc(bus, 0); + mdio(bus, !read); + mii_delay(bus); + mdc(bus, 1); + mii_delay(bus); /* send the PHY address */ for (j = 0; j < 5; j++) { - mdc(bitbang, 0); - mdio(bitbang, (addr & 0x10) != 0); - mii_delay(bitbang); - mdc(bitbang, 1); - mii_delay(bitbang); + mdc(bus, 0); + mdio(bus, (addr & 0x10) != 0); + mii_delay(bus); + mdc(bus, 1); + mii_delay(bus); addr <<= 1; } /* send the register address */ for (j = 0; j < 5; j++) { - mdc(bitbang, 0); - mdio(bitbang, (reg & 0x10) != 0); - mii_delay(bitbang); - mdc(bitbang, 1); - mii_delay(bitbang); + mdc(bus, 0); + mdio(bus, (reg & 0x10) != 0); + mii_delay(bus); + mdc(bus, 1); + mii_delay(bus); reg <<= 1; } } -static int fs_enet_mii_bb_read(struct mii_bus *bus , int phy_id, int location) +static int mii_read(struct fs_enet_mii_bus *bus, int phy_id, int location) { u16 rdreg; int ret, j; u8 addr = phy_id & 0xff; u8 reg = location & 0xff; - struct bb_info* bitbang = bus->priv; - bitbang_pre(bitbang, 1, addr, reg); + bitbang_pre(bus, 1, addr, reg); /* tri-state our MDIO I/O pin so we can read */ - mdc(bitbang, 0); - mdio_tristate(bitbang); - mii_delay(bitbang); - mdc(bitbang, 1); - mii_delay(bitbang); + mdc(bus, 0); + mdio_tristate(bus); + mii_delay(bus); + mdc(bus, 1); + mii_delay(bus); /* check the turnaround bit: the PHY should be driving it to zero */ - if (mdio_read(bitbang) != 0) { + if (mdio_read(bus) != 0) { /* PHY didn't drive TA low */ for (j = 0; j < 32; j++) { - mdc(bitbang, 0); - mii_delay(bitbang); - mdc(bitbang, 1); - mii_delay(bitbang); + mdc(bus, 0); + mii_delay(bus); + mdc(bus, 1); + mii_delay(bus); } ret = -1; goto out; } - mdc(bitbang, 0); - mii_delay(bitbang); + mdc(bus, 0); + mii_delay(bus); /* read 16 bits of register data, MSB first */ rdreg = 0; for (j = 0; j < 16; j++) { - mdc(bitbang, 1); - mii_delay(bitbang); + mdc(bus, 1); + mii_delay(bus); rdreg <<= 1; - rdreg |= mdio_read(bitbang); - mdc(bitbang, 0); - mii_delay(bitbang); + rdreg |= mdio_read(bus); + mdc(bus, 0); + mii_delay(bus); } - mdc(bitbang, 1); - mii_delay(bitbang); - mdc(bitbang, 0); - mii_delay(bitbang); - mdc(bitbang, 1); - mii_delay(bitbang); + mdc(bus, 1); + mii_delay(bus); + mdc(bus, 0); + mii_delay(bus); + mdc(bus, 1); + mii_delay(bus); ret = rdreg; out: return ret; } -static int fs_enet_mii_bb_write(struct mii_bus *bus, int phy_id, int location, u16 val) +static void mii_write(struct fs_enet_mii_bus *bus, int phy_id, int location, int val) { int j; - struct bb_info* bitbang = bus->priv; - u8 addr = phy_id & 0xff; u8 reg = location & 0xff; u16 value = val & 0xffff; - bitbang_pre(bitbang, 0, addr, reg); + bitbang_pre(bus, 0, addr, reg); /* send the turnaround (10) */ - mdc(bitbang, 0); - mdio(bitbang, 1); - mii_delay(bitbang); - mdc(bitbang, 1); - mii_delay(bitbang); - mdc(bitbang, 0); - mdio(bitbang, 0); - mii_delay(bitbang); - mdc(bitbang, 1); - mii_delay(bitbang); + mdc(bus, 0); + mdio(bus, 1); + mii_delay(bus); + mdc(bus, 1); + mii_delay(bus); + mdc(bus, 0); + mdio(bus, 0); + mii_delay(bus); + mdc(bus, 1); + mii_delay(bus); /* write 16 bits of register data, MSB first */ for (j = 0; j < 16; j++) { - mdc(bitbang, 0); - mdio(bitbang, (value & 0x8000) != 0); - mii_delay(bitbang); - mdc(bitbang, 1); - mii_delay(bitbang); + mdc(bus, 0); + mdio(bus, (value & 0x8000) != 0); + mii_delay(bus); + mdc(bus, 1); + mii_delay(bus); value <<= 1; } /* * Tri-state the MDIO line. */ - mdio_tristate(bitbang); - mdc(bitbang, 0); - mii_delay(bitbang); - mdc(bitbang, 1); - mii_delay(bitbang); - return 0; + mdio_tristate(bus); + mdc(bus, 0); + mii_delay(bus); + mdc(bus, 1); + mii_delay(bus); } -static int fs_enet_mii_bb_reset(struct mii_bus *bus) -{ - /*nothing here - dunno how to reset it*/ - return 0; -} - -static int fs_mii_bitbang_init(struct bb_info *bitbang, struct fs_mii_bb_platform_info* fmpi) +int fs_mii_bitbang_init(struct fs_enet_mii_bus *bus) { + const struct fs_mii_bus_info *bi = bus->bus_info; int r; - bitbang->delay = fmpi->delay; - - r = bitbang_prep_bit(&bitbang->mdio_dir, - &bitbang->mdio_dir_msk, - &fmpi->mdio_dir); + r = bitbang_prep_bit(&bus->bitbang.mdio_dir, + &bus->bitbang.mdio_dat, + &bus->bitbang.mdio_msk, + bi->i.bitbang.mdio_port, + bi->i.bitbang.mdio_bit); if (r != 0) return r; - r = bitbang_prep_bit(&bitbang->mdio_dat, - &bitbang->mdio_dat_msk, - &fmpi->mdio_dat); + r = bitbang_prep_bit(&bus->bitbang.mdc_dir, + &bus->bitbang.mdc_dat, + &bus->bitbang.mdc_msk, + bi->i.bitbang.mdc_port, + bi->i.bitbang.mdc_bit); if (r != 0) return r; - r = bitbang_prep_bit(&bitbang->mdc_dat, - &bitbang->mdc_msk, - &fmpi->mdc_dat); - if (r != 0) - return r; + bus->mii_read = mii_read; + bus->mii_write = mii_write; return 0; } - - -static int __devinit fs_enet_mdio_probe(struct device *dev) -{ - struct platform_device *pdev = to_platform_device(dev); - struct fs_mii_bb_platform_info *pdata; - struct mii_bus *new_bus; - struct bb_info *bitbang; - int err = 0; - - if (NULL == dev) - return -EINVAL; - - new_bus = kzalloc(sizeof(struct mii_bus), GFP_KERNEL); - - if (NULL == new_bus) - return -ENOMEM; - - bitbang = kzalloc(sizeof(struct bb_info), GFP_KERNEL); - - if (NULL == bitbang) - return -ENOMEM; - - new_bus->name = "BB MII Bus", - new_bus->read = &fs_enet_mii_bb_read, - new_bus->write = &fs_enet_mii_bb_write, - new_bus->reset = &fs_enet_mii_bb_reset, - new_bus->id = pdev->id; - - new_bus->phy_mask = ~0x9; - pdata = (struct fs_mii_bb_platform_info *)pdev->dev.platform_data; - - if (NULL == pdata) { - printk(KERN_ERR "gfar mdio %d: Missing platform data!\n", pdev->id); - return -ENODEV; - } - - /*set up workspace*/ - fs_mii_bitbang_init(bitbang, pdata); - - new_bus->priv = bitbang; - - new_bus->irq = pdata->irq; - - new_bus->dev = dev; - dev_set_drvdata(dev, new_bus); - - err = mdiobus_register(new_bus); - - if (0 != err) { - printk (KERN_ERR "%s: Cannot register as MDIO bus\n", - new_bus->name); - goto bus_register_fail; - } - - return 0; - -bus_register_fail: - kfree(bitbang); - kfree(new_bus); - - return err; -} - - -static int fs_enet_mdio_remove(struct device *dev) -{ - struct mii_bus *bus = dev_get_drvdata(dev); - - mdiobus_unregister(bus); - - dev_set_drvdata(dev, NULL); - - iounmap((void *) (&bus->priv)); - bus->priv = NULL; - kfree(bus); - - return 0; -} - -static struct device_driver fs_enet_bb_mdio_driver = { - .name = "fsl-bb-mdio", - .bus = &platform_bus_type, - .probe = fs_enet_mdio_probe, - .remove = fs_enet_mdio_remove, -}; - -int fs_enet_mdio_bb_init(void) -{ - return driver_register(&fs_enet_bb_mdio_driver); -} - -void fs_enet_mdio_bb_exit(void) -{ - driver_unregister(&fs_enet_bb_mdio_driver); -} - diff --git a/trunk/drivers/net/fs_enet/mii-fec.c b/trunk/drivers/net/fs_enet/mii-fec.c deleted file mode 100644 index 1328e10caa35..000000000000 --- a/trunk/drivers/net/fs_enet/mii-fec.c +++ /dev/null @@ -1,243 +0,0 @@ -/* - * Combined Ethernet driver for Motorola MPC8xx and MPC82xx. - * - * Copyright (c) 2003 Intracom S.A. - * by Pantelis Antoniou - * - * 2005 (c) MontaVista Software, Inc. - * Vitaly Bordug - * - * This file is licensed under the terms of the GNU General Public License - * version 2. This program is licensed "as is" without any warranty of any - * kind, whether express or implied. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "fs_enet.h" -#include "fec.h" - -/* Make MII read/write commands for the FEC. -*/ -#define mk_mii_read(REG) (0x60020000 | ((REG & 0x1f) << 18)) -#define mk_mii_write(REG, VAL) (0x50020000 | ((REG & 0x1f) << 18) | (VAL & 0xffff)) -#define mk_mii_end 0 - -#define FEC_MII_LOOPS 10000 - -static int match_has_phy (struct device *dev, void* data) -{ - struct platform_device* pdev = container_of(dev, struct platform_device, dev); - struct fs_platform_info* fpi; - if(strcmp(pdev->name, (char*)data)) - { - return 0; - } - - fpi = pdev->dev.platform_data; - if((fpi)&&(fpi->has_phy)) - return 1; - return 0; -} - -static int fs_mii_fec_init(struct fec_info* fec, struct fs_mii_fec_platform_info *fmpi) -{ - struct resource *r; - fec_t *fecp; - char* name = "fsl-cpm-fec"; - - /* we need fec in order to be useful */ - struct platform_device *fec_pdev = - container_of(bus_find_device(&platform_bus_type, NULL, name, match_has_phy), - struct platform_device, dev); - - if(fec_pdev == NULL) { - printk(KERN_ERR"Unable to find PHY for %s", name); - return -ENODEV; - } - - r = platform_get_resource_byname(fec_pdev, IORESOURCE_MEM, "regs"); - - fec->fecp = fecp = (fec_t*)ioremap(r->start,sizeof(fec_t)); - fec->mii_speed = fmpi->mii_speed; - - setbits32(&fecp->fec_r_cntrl, FEC_RCNTRL_MII_MODE); /* MII enable */ - setbits32(&fecp->fec_ecntrl, FEC_ECNTRL_PINMUX | FEC_ECNTRL_ETHER_EN); - out_be32(&fecp->fec_ievent, FEC_ENET_MII); - out_be32(&fecp->fec_mii_speed, fec->mii_speed); - - return 0; -} - -static int fs_enet_fec_mii_read(struct mii_bus *bus , int phy_id, int location) -{ - struct fec_info* fec = bus->priv; - fec_t *fecp = fec->fecp; - int i, ret = -1; - - if ((in_be32(&fecp->fec_r_cntrl) & FEC_RCNTRL_MII_MODE) == 0) - BUG(); - - /* Add PHY address to register command. */ - out_be32(&fecp->fec_mii_data, (phy_id << 23) | mk_mii_read(location)); - - for (i = 0; i < FEC_MII_LOOPS; i++) - if ((in_be32(&fecp->fec_ievent) & FEC_ENET_MII) != 0) - break; - - if (i < FEC_MII_LOOPS) { - out_be32(&fecp->fec_ievent, FEC_ENET_MII); - ret = in_be32(&fecp->fec_mii_data) & 0xffff; - } - - return ret; - -} - -static int fs_enet_fec_mii_write(struct mii_bus *bus, int phy_id, int location, u16 val) -{ - struct fec_info* fec = bus->priv; - fec_t *fecp = fec->fecp; - int i; - - /* this must never happen */ - if ((in_be32(&fecp->fec_r_cntrl) & FEC_RCNTRL_MII_MODE) == 0) - BUG(); - - /* Add PHY address to register command. */ - out_be32(&fecp->fec_mii_data, (phy_id << 23) | mk_mii_write(location, val)); - - for (i = 0; i < FEC_MII_LOOPS; i++) - if ((in_be32(&fecp->fec_ievent) & FEC_ENET_MII) != 0) - break; - - if (i < FEC_MII_LOOPS) - out_be32(&fecp->fec_ievent, FEC_ENET_MII); - - return 0; - -} - -static int fs_enet_fec_mii_reset(struct mii_bus *bus) -{ - /* nothing here - for now */ - return 0; -} - -static int __devinit fs_enet_fec_mdio_probe(struct device *dev) -{ - struct platform_device *pdev = to_platform_device(dev); - struct fs_mii_fec_platform_info *pdata; - struct mii_bus *new_bus; - struct fec_info *fec; - int err = 0; - if (NULL == dev) - return -EINVAL; - new_bus = kzalloc(sizeof(struct mii_bus), GFP_KERNEL); - - if (NULL == new_bus) - return -ENOMEM; - - fec = kzalloc(sizeof(struct fec_info), GFP_KERNEL); - - if (NULL == fec) - return -ENOMEM; - - new_bus->name = "FEC MII Bus", - new_bus->read = &fs_enet_fec_mii_read, - new_bus->write = &fs_enet_fec_mii_write, - new_bus->reset = &fs_enet_fec_mii_reset, - new_bus->id = pdev->id; - - pdata = (struct fs_mii_fec_platform_info *)pdev->dev.platform_data; - - if (NULL == pdata) { - printk(KERN_ERR "fs_enet FEC mdio %d: Missing platform data!\n", pdev->id); - return -ENODEV; - } - - /*set up workspace*/ - - fs_mii_fec_init(fec, pdata); - new_bus->priv = fec; - - new_bus->irq = pdata->irq; - - new_bus->dev = dev; - dev_set_drvdata(dev, new_bus); - - err = mdiobus_register(new_bus); - - if (0 != err) { - printk (KERN_ERR "%s: Cannot register as MDIO bus\n", - new_bus->name); - goto bus_register_fail; - } - - return 0; - -bus_register_fail: - kfree(new_bus); - - return err; -} - - -static int fs_enet_fec_mdio_remove(struct device *dev) -{ - struct mii_bus *bus = dev_get_drvdata(dev); - - mdiobus_unregister(bus); - - dev_set_drvdata(dev, NULL); - kfree(bus->priv); - - bus->priv = NULL; - kfree(bus); - - return 0; -} - -static struct device_driver fs_enet_fec_mdio_driver = { - .name = "fsl-cpm-fec-mdio", - .bus = &platform_bus_type, - .probe = fs_enet_fec_mdio_probe, - .remove = fs_enet_fec_mdio_remove, -}; - -int fs_enet_mdio_fec_init(void) -{ - return driver_register(&fs_enet_fec_mdio_driver); -} - -void fs_enet_mdio_fec_exit(void) -{ - driver_unregister(&fs_enet_fec_mdio_driver); -} - diff --git a/trunk/drivers/net/fs_enet/mii-fixed.c b/trunk/drivers/net/fs_enet/mii-fixed.c new file mode 100644 index 000000000000..ae4a9c3bb393 --- /dev/null +++ b/trunk/drivers/net/fs_enet/mii-fixed.c @@ -0,0 +1,91 @@ +/* + * Combined Ethernet driver for Motorola MPC8xx and MPC82xx. + * + * Copyright (c) 2003 Intracom S.A. + * by Pantelis Antoniou + * + * 2005 (c) MontaVista Software, Inc. + * Vitaly Bordug + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "fs_enet.h" + +static const u16 mii_regs[7] = { + 0x3100, + 0x786d, + 0x0fff, + 0x0fff, + 0x01e1, + 0x45e1, + 0x0003, +}; + +static int mii_read(struct fs_enet_mii_bus *bus, int phy_id, int location) +{ + int ret = 0; + + if ((unsigned int)location >= ARRAY_SIZE(mii_regs)) + return -1; + + if (location != 5) + ret = mii_regs[location]; + else + ret = bus->fixed.lpa; + + return ret; +} + +static void mii_write(struct fs_enet_mii_bus *bus, int phy_id, int location, int val) +{ + /* do nothing */ +} + +int fs_mii_fixed_init(struct fs_enet_mii_bus *bus) +{ + const struct fs_mii_bus_info *bi = bus->bus_info; + + bus->fixed.lpa = 0x45e1; /* default 100Mb, full duplex */ + + /* if speed is fixed at 10Mb, remove 100Mb modes */ + if (bi->i.fixed.speed == 10) + bus->fixed.lpa &= ~LPA_100; + + /* if duplex is half, remove full duplex modes */ + if (bi->i.fixed.duplex == 0) + bus->fixed.lpa &= ~LPA_DUPLEX; + + bus->mii_read = mii_read; + bus->mii_write = mii_write; + + return 0; +} diff --git a/trunk/drivers/net/hp100.c b/trunk/drivers/net/hp100.c index ff5a67d619bb..e7d9bf330287 100644 --- a/trunk/drivers/net/hp100.c +++ b/trunk/drivers/net/hp100.c @@ -111,6 +111,7 @@ #include #include #include +#include /* for CONFIG_PCI */ #include #include #include diff --git a/trunk/drivers/net/irda/mcs7780.c b/trunk/drivers/net/irda/mcs7780.c index 415ba8dc94ce..47f6f64d604c 100644 --- a/trunk/drivers/net/irda/mcs7780.c +++ b/trunk/drivers/net/irda/mcs7780.c @@ -45,6 +45,7 @@ #include #include +#include #include #include #include diff --git a/trunk/drivers/net/irda/w83977af_ir.c b/trunk/drivers/net/irda/w83977af_ir.c index b69776e00951..0ea65c4c6f85 100644 --- a/trunk/drivers/net/irda/w83977af_ir.c +++ b/trunk/drivers/net/irda/w83977af_ir.c @@ -40,6 +40,7 @@ ********************************************************************/ #include +#include #include #include #include diff --git a/trunk/drivers/net/ixgb/ixgb.h b/trunk/drivers/net/ixgb/ixgb.h index a51604b3651f..82b67af54c94 100644 --- a/trunk/drivers/net/ixgb/ixgb.h +++ b/trunk/drivers/net/ixgb/ixgb.h @@ -110,6 +110,9 @@ struct ixgb_adapter; #define IXGB_RXBUFFER_8192 8192 #define IXGB_RXBUFFER_16384 16384 +/* How many Tx Descriptors do we need to call netif_wake_queue? */ +#define IXGB_TX_QUEUE_WAKE 16 + /* How many Rx Buffers do we bundle into one write to the hardware ? */ #define IXGB_RX_BUFFER_WRITE 4 /* Must be power of 2 */ @@ -170,7 +173,7 @@ struct ixgb_adapter { unsigned long led_status; /* TX */ - struct ixgb_desc_ring tx_ring ____cacheline_aligned_in_smp; + struct ixgb_desc_ring tx_ring; unsigned long timeo_start; uint32_t tx_cmd_type; uint64_t hw_csum_tx_good; diff --git a/trunk/drivers/net/ixgb/ixgb_ethtool.c b/trunk/drivers/net/ixgb/ixgb_ethtool.c index ba621083830a..cf19b898ba9b 100644 --- a/trunk/drivers/net/ixgb/ixgb_ethtool.c +++ b/trunk/drivers/net/ixgb/ixgb_ethtool.c @@ -654,7 +654,11 @@ ixgb_phys_id(struct net_device *netdev, uint32_t data) mod_timer(&adapter->blink_timer, jiffies); - msleep_interruptible(data * 1000); + if (data) + schedule_timeout_interruptible(data * HZ); + else + schedule_timeout_interruptible(MAX_SCHEDULE_TIMEOUT); + del_timer_sync(&adapter->blink_timer); ixgb_led_off(&adapter->hw); clear_bit(IXGB_LED_ON, &adapter->led_status); diff --git a/trunk/drivers/net/ixgb/ixgb_hw.c b/trunk/drivers/net/ixgb/ixgb_hw.c index 2b1515574faf..f7fa10e47fa2 100644 --- a/trunk/drivers/net/ixgb/ixgb_hw.c +++ b/trunk/drivers/net/ixgb/ixgb_hw.c @@ -236,17 +236,6 @@ ixgb_identify_phy(struct ixgb_hw *hw) DEBUGOUT("Identified G6104 optics\n"); phy_type = ixgb_phy_type_g6104; break; - case IXGB_DEVICE_ID_82597EX_CX4: - DEBUGOUT("Identified CX4\n"); - xpak_vendor = ixgb_identify_xpak_vendor(hw); - if (xpak_vendor == ixgb_xpak_vendor_intel) { - DEBUGOUT("Identified TXN17201 optics\n"); - phy_type = ixgb_phy_type_txn17201; - } else { - DEBUGOUT("Identified G6005 optics\n"); - phy_type = ixgb_phy_type_g6005; - } - break; default: DEBUGOUT("Unknown physical layer module\n"); phy_type = ixgb_phy_type_unknown; diff --git a/trunk/drivers/net/ixgb/ixgb_ids.h b/trunk/drivers/net/ixgb/ixgb_ids.h index 9fd61189b4b2..40a085f94c7b 100644 --- a/trunk/drivers/net/ixgb/ixgb_ids.h +++ b/trunk/drivers/net/ixgb/ixgb_ids.h @@ -45,7 +45,6 @@ #define IXGB_DEVICE_ID_82597EX_CX4 0x109E #define IXGB_SUBDEVICE_ID_A00C 0xA00C -#define IXGB_SUBDEVICE_ID_A01C 0xA01C #endif /* #ifndef _IXGB_IDS_H_ */ /* End of File */ diff --git a/trunk/drivers/net/ixgb/ixgb_main.c b/trunk/drivers/net/ixgb/ixgb_main.c index e36dee1dd333..7bbd447289b5 100644 --- a/trunk/drivers/net/ixgb/ixgb_main.c +++ b/trunk/drivers/net/ixgb/ixgb_main.c @@ -36,7 +36,7 @@ static char ixgb_driver_string[] = "Intel(R) PRO/10GbE Network Driver"; #else #define DRIVERNAPI "-NAPI" #endif -#define DRV_VERSION "1.0.112-k2"DRIVERNAPI +#define DRV_VERSION "1.0.109-k2"DRIVERNAPI char ixgb_driver_version[] = DRV_VERSION; static char ixgb_copyright[] = "Copyright (c) 1999-2006 Intel Corporation."; @@ -118,26 +118,15 @@ static void ixgb_restore_vlan(struct ixgb_adapter *adapter); static void ixgb_netpoll(struct net_device *dev); #endif -static pci_ers_result_t ixgb_io_error_detected (struct pci_dev *pdev, - enum pci_channel_state state); -static pci_ers_result_t ixgb_io_slot_reset (struct pci_dev *pdev); -static void ixgb_io_resume (struct pci_dev *pdev); - /* Exported from other modules */ -extern void ixgb_check_options(struct ixgb_adapter *adapter); -static struct pci_error_handlers ixgb_err_handler = { - .error_detected = ixgb_io_error_detected, - .slot_reset = ixgb_io_slot_reset, - .resume = ixgb_io_resume, -}; +extern void ixgb_check_options(struct ixgb_adapter *adapter); static struct pci_driver ixgb_driver = { .name = ixgb_driver_name, .id_table = ixgb_pci_tbl, .probe = ixgb_probe, .remove = __devexit_p(ixgb_remove), - .err_handler = &ixgb_err_handler }; MODULE_AUTHOR("Intel Corporation, "); @@ -151,12 +140,12 @@ module_param(debug, int, 0); MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)"); /* some defines for controlling descriptor fetches in h/w */ -#define RXDCTL_WTHRESH_DEFAULT 15 /* chip writes back at this many or RXT0 */ -#define RXDCTL_PTHRESH_DEFAULT 0 /* chip considers prefech below - * this */ -#define RXDCTL_HTHRESH_DEFAULT 0 /* chip will only prefetch if tail - * is pushed this many descriptors - * from head */ +#define RXDCTL_WTHRESH_DEFAULT 16 /* chip writes back at this many or RXT0 */ +#define RXDCTL_PTHRESH_DEFAULT 0 /* chip considers prefech below + * this */ +#define RXDCTL_HTHRESH_DEFAULT 0 /* chip will only prefetch if tail + * is pushed this many descriptors + * from head */ /** * ixgb_init_module - Driver Registration Routine @@ -173,7 +162,7 @@ ixgb_init_module(void) printk(KERN_INFO "%s\n", ixgb_copyright); - return pci_register_driver(&ixgb_driver); + return pci_module_init(&ixgb_driver); } module_init(ixgb_init_module); @@ -1185,7 +1174,6 @@ ixgb_tso(struct ixgb_adapter *adapter, struct sk_buff *skb) int err; if (likely(skb_is_gso(skb))) { - struct ixgb_buffer *buffer_info; if (skb_header_cloned(skb)) { err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC); if (err) @@ -1208,8 +1196,6 @@ ixgb_tso(struct ixgb_adapter *adapter, struct sk_buff *skb) i = adapter->tx_ring.next_to_use; context_desc = IXGB_CONTEXT_DESC(adapter->tx_ring, i); - buffer_info = &adapter->tx_ring.buffer_info[i]; - WARN_ON(buffer_info->dma != 0); context_desc->ipcss = ipcss; context_desc->ipcso = ipcso; @@ -1247,14 +1233,11 @@ ixgb_tx_csum(struct ixgb_adapter *adapter, struct sk_buff *skb) uint8_t css, cso; if(likely(skb->ip_summed == CHECKSUM_HW)) { - struct ixgb_buffer *buffer_info; css = skb->h.raw - skb->data; cso = (skb->h.raw + skb->csum) - skb->data; i = adapter->tx_ring.next_to_use; context_desc = IXGB_CONTEXT_DESC(adapter->tx_ring, i); - buffer_info = &adapter->tx_ring.buffer_info[i]; - WARN_ON(buffer_info->dma != 0); context_desc->tucss = css; context_desc->tucso = cso; @@ -1300,7 +1283,6 @@ ixgb_tx_map(struct ixgb_adapter *adapter, struct sk_buff *skb, buffer_info = &tx_ring->buffer_info[i]; size = min(len, IXGB_MAX_DATA_PER_TXD); buffer_info->length = size; - WARN_ON(buffer_info->dma != 0); buffer_info->dma = pci_map_single(adapter->pdev, skb->data + offset, @@ -1561,11 +1543,6 @@ void ixgb_update_stats(struct ixgb_adapter *adapter) { struct net_device *netdev = adapter->netdev; - struct pci_dev *pdev = adapter->pdev; - - /* Prevent stats update while adapter is being reset */ - if (pdev->error_state && pdev->error_state != pci_channel_io_normal) - return; if((netdev->flags & IFF_PROMISC) || (netdev->flags & IFF_ALLMULTI) || (netdev->mc_count > IXGB_MAX_NUM_MULTICAST_ADDRESSES)) { @@ -1810,7 +1787,7 @@ ixgb_clean_tx_irq(struct ixgb_adapter *adapter) if (unlikely(netif_queue_stopped(netdev))) { spin_lock(&adapter->tx_lock); if (netif_queue_stopped(netdev) && netif_carrier_ok(netdev) && - (IXGB_DESC_UNUSED(tx_ring) >= DESC_NEEDED)) + (IXGB_DESC_UNUSED(tx_ring) > IXGB_TX_QUEUE_WAKE)) netif_wake_queue(netdev); spin_unlock(&adapter->tx_lock); } @@ -1971,9 +1948,10 @@ ixgb_clean_rx_irq(struct ixgb_adapter *adapter) #define IXGB_CB_LENGTH 256 if (length < IXGB_CB_LENGTH) { struct sk_buff *new_skb = - netdev_alloc_skb(netdev, length + NET_IP_ALIGN); + dev_alloc_skb(length + NET_IP_ALIGN); if (new_skb) { skb_reserve(new_skb, NET_IP_ALIGN); + new_skb->dev = netdev; memcpy(new_skb->data - NET_IP_ALIGN, skb->data - NET_IP_ALIGN, length + NET_IP_ALIGN); @@ -2053,14 +2031,14 @@ ixgb_alloc_rx_buffers(struct ixgb_adapter *adapter) /* leave three descriptors unused */ while(--cleancount > 2) { /* recycle! its good for you */ - skb = buffer_info->skb; - if (skb) { + if (!(skb = buffer_info->skb)) + skb = dev_alloc_skb(adapter->rx_buffer_len + + NET_IP_ALIGN); + else { skb_trim(skb, 0); goto map_skb; } - skb = netdev_alloc_skb(netdev, adapter->rx_buffer_len - + NET_IP_ALIGN); if (unlikely(!skb)) { /* Better luck next round */ adapter->alloc_rx_buff_failed++; @@ -2073,6 +2051,8 @@ ixgb_alloc_rx_buffers(struct ixgb_adapter *adapter) */ skb_reserve(skb, NET_IP_ALIGN); + skb->dev = netdev; + buffer_info->skb = skb; buffer_info->length = adapter->rx_buffer_len; map_skb: @@ -2210,7 +2190,7 @@ ixgb_restore_vlan(struct ixgb_adapter *adapter) static void ixgb_netpoll(struct net_device *dev) { - struct ixgb_adapter *adapter = netdev_priv(dev); + struct ixgb_adapter *adapter = dev->priv; disable_irq(adapter->pdev->irq); ixgb_intr(adapter->pdev->irq, dev, NULL); @@ -2218,98 +2198,4 @@ static void ixgb_netpoll(struct net_device *dev) } #endif -/** - * ixgb_io_error_detected() - called when PCI error is detected - * @pdev pointer to pci device with error - * @state pci channel state after error - * - * This callback is called by the PCI subsystem whenever - * a PCI bus error is detected. - */ -static pci_ers_result_t ixgb_io_error_detected (struct pci_dev *pdev, - enum pci_channel_state state) -{ - struct net_device *netdev = pci_get_drvdata(pdev); - struct ixgb_adapter *adapter = netdev->priv; - - if(netif_running(netdev)) - ixgb_down(adapter, TRUE); - - pci_disable_device(pdev); - - /* Request a slot reset. */ - return PCI_ERS_RESULT_NEED_RESET; -} - -/** - * ixgb_io_slot_reset - called after the pci bus has been reset. - * @pdev pointer to pci device with error - * - * This callback is called after the PCI buss has been reset. - * Basically, this tries to restart the card from scratch. - * This is a shortened version of the device probe/discovery code, - * it resembles the first-half of the ixgb_probe() routine. - */ -static pci_ers_result_t ixgb_io_slot_reset (struct pci_dev *pdev) -{ - struct net_device *netdev = pci_get_drvdata(pdev); - struct ixgb_adapter *adapter = netdev->priv; - - if(pci_enable_device(pdev)) { - DPRINTK(PROBE, ERR, "Cannot re-enable PCI device after reset.\n"); - return PCI_ERS_RESULT_DISCONNECT; - } - - /* Perform card reset only on one instance of the card */ - if (0 != PCI_FUNC (pdev->devfn)) - return PCI_ERS_RESULT_RECOVERED; - - pci_set_master(pdev); - - netif_carrier_off(netdev); - netif_stop_queue(netdev); - ixgb_reset(adapter); - - /* Make sure the EEPROM is good */ - if(!ixgb_validate_eeprom_checksum(&adapter->hw)) { - DPRINTK(PROBE, ERR, "After reset, the EEPROM checksum is not valid.\n"); - return PCI_ERS_RESULT_DISCONNECT; - } - ixgb_get_ee_mac_addr(&adapter->hw, netdev->dev_addr); - memcpy(netdev->perm_addr, netdev->dev_addr, netdev->addr_len); - - if(!is_valid_ether_addr(netdev->perm_addr)) { - DPRINTK(PROBE, ERR, "After reset, invalid MAC address.\n"); - return PCI_ERS_RESULT_DISCONNECT; - } - - return PCI_ERS_RESULT_RECOVERED; -} - -/** - * ixgb_io_resume - called when its OK to resume normal operations - * @pdev pointer to pci device with error - * - * The error recovery driver tells us that its OK to resume - * normal operation. Implementation resembles the second-half - * of the ixgb_probe() routine. - */ -static void ixgb_io_resume (struct pci_dev *pdev) -{ - struct net_device *netdev = pci_get_drvdata(pdev); - struct ixgb_adapter *adapter = netdev->priv; - - pci_set_master(pdev); - - if(netif_running(netdev)) { - if(ixgb_up(adapter)) { - printk ("ixgb: can't bring device back up after reset\n"); - return; - } - } - - netif_device_attach(netdev); - mod_timer(&adapter->watchdog_timer, jiffies); -} - /* ixgb_main.c */ diff --git a/trunk/drivers/net/lance.c b/trunk/drivers/net/lance.c index 5b4dbfe5fb77..c1c3452c90ca 100644 --- a/trunk/drivers/net/lance.c +++ b/trunk/drivers/net/lance.c @@ -326,7 +326,7 @@ MODULE_PARM_DESC(dma, "LANCE/PCnet ISA DMA channel (ignored for some devices)"); MODULE_PARM_DESC(irq, "LANCE/PCnet IRQ number (ignored for some devices)"); MODULE_PARM_DESC(lance_debug, "LANCE/PCnet debug level (0-7)"); -int __init init_module(void) +int init_module(void) { struct net_device *dev; int this_dev, found = 0; diff --git a/trunk/drivers/net/lne390.c b/trunk/drivers/net/lne390.c index c0ec7f6abcb2..646e89fc3562 100644 --- a/trunk/drivers/net/lne390.c +++ b/trunk/drivers/net/lne390.c @@ -406,7 +406,7 @@ MODULE_PARM_DESC(mem, "memory base address(es)"); MODULE_DESCRIPTION("Mylex LNE390A/B EISA Ethernet driver"); MODULE_LICENSE("GPL"); -int __init init_module(void) +int init_module(void) { struct net_device *dev; int this_dev, found = 0; diff --git a/trunk/drivers/net/myri10ge/myri10ge.c b/trunk/drivers/net/myri10ge/myri10ge.c index e2346e8a4d52..9bdd43ab3573 100644 --- a/trunk/drivers/net/myri10ge/myri10ge.c +++ b/trunk/drivers/net/myri10ge/myri10ge.c @@ -187,14 +187,11 @@ struct myri10ge_priv { u8 mac_addr[6]; /* eeprom mac address */ unsigned long serial_number; int vendor_specific_offset; - int fw_multicast_support; u32 devctl; u16 msi_flags; u32 read_dma; u32 write_dma; u32 read_write_dma; - u32 link_changes; - u32 msg_enable; }; static char *myri10ge_fw_unaligned = "myri10ge_ethp_z8e.dat"; @@ -260,12 +257,6 @@ module_param(myri10ge_max_irq_loops, int, S_IRUGO); MODULE_PARM_DESC(myri10ge_max_irq_loops, "Set stuck legacy IRQ detection threshold\n"); -#define MYRI10GE_MSG_DEFAULT NETIF_MSG_LINK - -static int myri10ge_debug = -1; /* defaults above */ -module_param(myri10ge_debug, int, 0); -MODULE_PARM_DESC(myri10ge_debug, "Debug level (0=none,...,16=all)"); - #define MYRI10GE_FW_OFFSET 1024*1024 #define MYRI10GE_HIGHPART_TO_U32(X) \ (sizeof (X) == 8) ? ((u32)((u64)(X) >> 32)) : (0) @@ -280,7 +271,7 @@ myri10ge_send_cmd(struct myri10ge_priv *mgp, u32 cmd, struct mcp_cmd *buf; char buf_bytes[sizeof(*buf) + 8]; struct mcp_cmd_response *response = mgp->cmd; - char __iomem *cmd_addr = mgp->sram + MXGEFW_ETH_CMD; + char __iomem *cmd_addr = mgp->sram + MXGEFW_CMD_OFFSET; u32 dma_low, dma_high, result, value; int sleep_total = 0; @@ -329,8 +320,6 @@ myri10ge_send_cmd(struct myri10ge_priv *mgp, u32 cmd, if (result == 0) { data->data0 = value; return 0; - } else if (result == MXGEFW_CMD_UNKNOWN) { - return -ENOSYS; } else { dev_err(&mgp->pdev->dev, "command %d failed, result = %d\n", @@ -415,7 +404,7 @@ static void myri10ge_dummy_rdma(struct myri10ge_priv *mgp, int enable) buf[4] = htonl(dma_low); /* dummy addr LSW */ buf[5] = htonl(enable); /* enable? */ - submit = mgp->sram + MXGEFW_BOOT_DUMMY_RDMA; + submit = mgp->sram + 0xfc01c0; myri10ge_pio_copy(submit, &buf, sizeof(buf)); for (i = 0; mgp->cmd->data != MYRI10GE_NO_CONFIRM_DATA && i < 20; i++) @@ -611,7 +600,7 @@ static int myri10ge_load_firmware(struct myri10ge_priv *mgp) buf[5] = htonl(8); /* where to copy to */ buf[6] = htonl(0); /* where to jump to */ - submit = mgp->sram + MXGEFW_BOOT_HANDOFF; + submit = mgp->sram + 0xfc0000; myri10ge_pio_copy(submit, &buf, sizeof(buf)); mb(); @@ -775,7 +764,6 @@ static int myri10ge_reset(struct myri10ge_priv *mgp) mgp->rx_small.cnt = 0; mgp->rx_done.idx = 0; mgp->rx_done.cnt = 0; - mgp->link_changes = 0; status = myri10ge_update_mac_address(mgp, mgp->dev->dev_addr); myri10ge_change_promisc(mgp, 0, 0); myri10ge_change_pause(mgp, mgp->pause); @@ -810,13 +798,12 @@ myri10ge_submit_8rx(struct mcp_kreq_ether_recv __iomem * dst, * pages directly and building a fraglist in the near future. */ -static inline struct sk_buff *myri10ge_alloc_big(struct net_device *dev, - int bytes) +static inline struct sk_buff *myri10ge_alloc_big(int bytes) { struct sk_buff *skb; unsigned long data, roundup; - skb = netdev_alloc_skb(dev, bytes + 4096 + MXGEFW_PAD); + skb = dev_alloc_skb(bytes + 4096 + MXGEFW_PAD); if (skb == NULL) return NULL; @@ -834,13 +821,12 @@ static inline struct sk_buff *myri10ge_alloc_big(struct net_device *dev, /* Allocate 2x as much space as required and use whichever portion * does not cross a 4KB boundary */ -static inline struct sk_buff *myri10ge_alloc_small_safe(struct net_device *dev, - unsigned int bytes) +static inline struct sk_buff *myri10ge_alloc_small_safe(unsigned int bytes) { struct sk_buff *skb; unsigned long data, boundary; - skb = netdev_alloc_skb(dev, 2 * (bytes + MXGEFW_PAD) - 1); + skb = dev_alloc_skb(2 * (bytes + MXGEFW_PAD) - 1); if (unlikely(skb == NULL)) return NULL; @@ -861,13 +847,12 @@ static inline struct sk_buff *myri10ge_alloc_small_safe(struct net_device *dev, /* Allocate just enough space, and verify that the allocated * space does not cross a 4KB boundary */ -static inline struct sk_buff *myri10ge_alloc_small(struct net_device *dev, - int bytes) +static inline struct sk_buff *myri10ge_alloc_small(int bytes) { struct sk_buff *skb; unsigned long roundup, data, end; - skb = netdev_alloc_skb(dev, bytes + 16 + MXGEFW_PAD); + skb = dev_alloc_skb(bytes + 16 + MXGEFW_PAD); if (unlikely(skb == NULL)) return NULL; @@ -883,17 +868,15 @@ static inline struct sk_buff *myri10ge_alloc_small(struct net_device *dev, "myri10ge_alloc_small: small skb crossed 4KB boundary\n"); myri10ge_skb_cross_4k = 1; dev_kfree_skb_any(skb); - skb = myri10ge_alloc_small_safe(dev, bytes); + skb = myri10ge_alloc_small_safe(bytes); } return skb; } static inline int -myri10ge_getbuf(struct myri10ge_rx_buf *rx, struct myri10ge_priv *mgp, - int bytes, int idx) +myri10ge_getbuf(struct myri10ge_rx_buf *rx, struct pci_dev *pdev, int bytes, + int idx) { - struct net_device *dev = mgp->dev; - struct pci_dev *pdev = mgp->pdev; struct sk_buff *skb; dma_addr_t bus; int len, retval = 0; @@ -901,11 +884,11 @@ myri10ge_getbuf(struct myri10ge_rx_buf *rx, struct myri10ge_priv *mgp, bytes += VLAN_HLEN; /* account for 802.1q vlan tag */ if ((bytes + MXGEFW_PAD) > (4096 - 16) /* linux overhead */ ) - skb = myri10ge_alloc_big(dev, bytes); + skb = myri10ge_alloc_big(bytes); else if (myri10ge_skb_cross_4k) - skb = myri10ge_alloc_small_safe(dev, bytes); + skb = myri10ge_alloc_small_safe(bytes); else - skb = myri10ge_alloc_small(dev, bytes); + skb = myri10ge_alloc_small(bytes); if (unlikely(skb == NULL)) { rx->alloc_fail++; @@ -968,7 +951,7 @@ myri10ge_rx_done(struct myri10ge_priv *mgp, struct myri10ge_rx_buf *rx, unmap_len = pci_unmap_len(&rx->info[idx], len); /* try to replace the received skb */ - if (myri10ge_getbuf(rx, mgp, bytes, idx)) { + if (myri10ge_getbuf(rx, mgp->pdev, bytes, idx)) { /* drop the frame -- the old skbuf is re-cycled */ mgp->stats.rx_dropped += 1; return 0; @@ -985,6 +968,7 @@ myri10ge_rx_done(struct myri10ge_priv *mgp, struct myri10ge_rx_buf *rx, skb_put(skb, len); skb->protocol = eth_type_trans(skb, mgp->dev); + skb->dev = mgp->dev; if (mgp->csum_flag) { if ((skb->protocol == ntohs(ETH_P_IP)) || (skb->protocol == ntohs(ETH_P_IPV6))) { @@ -1097,19 +1081,13 @@ static inline void myri10ge_check_statblock(struct myri10ge_priv *mgp) if (mgp->link_state != stats->link_up) { mgp->link_state = stats->link_up; if (mgp->link_state) { - if (netif_msg_link(mgp)) - printk(KERN_INFO - "myri10ge: %s: link up\n", - mgp->dev->name); + printk(KERN_INFO "myri10ge: %s: link up\n", + mgp->dev->name); netif_carrier_on(mgp->dev); - mgp->link_changes++; } else { - if (netif_msg_link(mgp)) - printk(KERN_INFO - "myri10ge: %s: link down\n", - mgp->dev->name); + printk(KERN_INFO "myri10ge: %s: link down\n", + mgp->dev->name); netif_carrier_off(mgp->dev); - mgp->link_changes++; } } if (mgp->rdma_tags_available != @@ -1311,8 +1289,7 @@ static const char myri10ge_gstrings_stats[][ETH_GSTRING_LEN] = { "serial_number", "tx_pkt_start", "tx_pkt_done", "tx_req", "tx_done", "rx_small_cnt", "rx_big_cnt", "wake_queue", "stop_queue", "watchdog_resets", "tx_linearized", - "link_changes", "link_up", "dropped_link_overflow", - "dropped_link_error_or_filtered", "dropped_multicast_filtered", + "link_up", "dropped_link_overflow", "dropped_link_error_or_filtered", "dropped_runt", "dropped_overrun", "dropped_no_small_buffer", "dropped_no_big_buffer" }; @@ -1364,31 +1341,16 @@ myri10ge_get_ethtool_stats(struct net_device *netdev, data[i++] = (unsigned int)mgp->stop_queue; data[i++] = (unsigned int)mgp->watchdog_resets; data[i++] = (unsigned int)mgp->tx_linearized; - data[i++] = (unsigned int)mgp->link_changes; data[i++] = (unsigned int)ntohl(mgp->fw_stats->link_up); data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_link_overflow); data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_link_error_or_filtered); - data[i++] = - (unsigned int)ntohl(mgp->fw_stats->dropped_multicast_filtered); data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_runt); data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_overrun); data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_no_small_buffer); data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_no_big_buffer); } -static void myri10ge_set_msglevel(struct net_device *netdev, u32 value) -{ - struct myri10ge_priv *mgp = netdev_priv(netdev); - mgp->msg_enable = value; -} - -static u32 myri10ge_get_msglevel(struct net_device *netdev) -{ - struct myri10ge_priv *mgp = netdev_priv(netdev); - return mgp->msg_enable; -} - static struct ethtool_ops myri10ge_ethtool_ops = { .get_settings = myri10ge_get_settings, .get_drvinfo = myri10ge_get_drvinfo, @@ -1409,9 +1371,7 @@ static struct ethtool_ops myri10ge_ethtool_ops = { #endif .get_strings = myri10ge_get_strings, .get_stats_count = myri10ge_get_stats_count, - .get_ethtool_stats = myri10ge_get_ethtool_stats, - .set_msglevel = myri10ge_set_msglevel, - .get_msglevel = myri10ge_get_msglevel + .get_ethtool_stats = myri10ge_get_ethtool_stats }; static int myri10ge_allocate_rings(struct net_device *dev) @@ -1479,7 +1439,7 @@ static int myri10ge_allocate_rings(struct net_device *dev) /* Fill the receive rings */ for (i = 0; i <= mgp->rx_small.mask; i++) { - status = myri10ge_getbuf(&mgp->rx_small, mgp, + status = myri10ge_getbuf(&mgp->rx_small, mgp->pdev, mgp->small_bytes, i); if (status) { printk(KERN_ERR @@ -1491,7 +1451,8 @@ static int myri10ge_allocate_rings(struct net_device *dev) for (i = 0; i <= mgp->rx_big.mask; i++) { status = - myri10ge_getbuf(&mgp->rx_big, mgp, dev->mtu + ETH_HLEN, i); + myri10ge_getbuf(&mgp->rx_big, mgp->pdev, + dev->mtu + ETH_HLEN, i); if (status) { printk(KERN_ERR "myri10ge: %s: alloced only %d big bufs\n", @@ -1687,11 +1648,9 @@ static int myri10ge_open(struct net_device *dev) } if (mgp->mtrr >= 0) { - mgp->tx.wc_fifo = (u8 __iomem *) mgp->sram + MXGEFW_ETH_SEND_4; - mgp->rx_small.wc_fifo = - (u8 __iomem *) mgp->sram + MXGEFW_ETH_RECV_SMALL; - mgp->rx_big.wc_fifo = - (u8 __iomem *) mgp->sram + MXGEFW_ETH_RECV_BIG; + mgp->tx.wc_fifo = (u8 __iomem *) mgp->sram + 0x200000; + mgp->rx_small.wc_fifo = (u8 __iomem *) mgp->sram + 0x300000; + mgp->rx_big.wc_fifo = (u8 __iomem *) mgp->sram + 0x340000; } else { mgp->tx.wc_fifo = NULL; mgp->rx_small.wc_fifo = NULL; @@ -1727,21 +1686,7 @@ static int myri10ge_open(struct net_device *dev) cmd.data0 = MYRI10GE_LOWPART_TO_U32(mgp->fw_stats_bus); cmd.data1 = MYRI10GE_HIGHPART_TO_U32(mgp->fw_stats_bus); - cmd.data2 = sizeof(struct mcp_irq_data); - status = myri10ge_send_cmd(mgp, MXGEFW_CMD_SET_STATS_DMA_V2, &cmd, 0); - if (status == -ENOSYS) { - dma_addr_t bus = mgp->fw_stats_bus; - bus += offsetof(struct mcp_irq_data, send_done_count); - cmd.data0 = MYRI10GE_LOWPART_TO_U32(bus); - cmd.data1 = MYRI10GE_HIGHPART_TO_U32(bus); - status = myri10ge_send_cmd(mgp, - MXGEFW_CMD_SET_STATS_DMA_OBSOLETE, - &cmd, 0); - /* Firmware cannot support multicast without STATS_DMA_V2 */ - mgp->fw_multicast_support = 0; - } else { - mgp->fw_multicast_support = 1; - } + status = myri10ge_send_cmd(mgp, MXGEFW_CMD_SET_STATS_DMA, &cmd, 0); if (status) { printk(KERN_ERR "myri10ge: %s: Couldn't set stats DMA\n", dev->name); @@ -1896,8 +1841,7 @@ myri10ge_submit_req_wc(struct myri10ge_tx_buf *tx, if (cnt > 0) { /* pad it to 64 bytes. The src is 64 bytes bigger than it * needs to be so that we don't overrun it */ - myri10ge_pio_copy(tx->wc_fifo + MXGEFW_ETH_SEND_OFFSET(cnt), - src, 64); + myri10ge_pio_copy(tx->wc_fifo + (cnt << 18), src, 64); mb(); } } @@ -2196,81 +2140,9 @@ static struct net_device_stats *myri10ge_get_stats(struct net_device *dev) static void myri10ge_set_multicast_list(struct net_device *dev) { - struct myri10ge_cmd cmd; - struct myri10ge_priv *mgp; - struct dev_mc_list *mc_list; - int err; - - mgp = netdev_priv(dev); /* can be called from atomic contexts, * pass 1 to force atomicity in myri10ge_send_cmd() */ - myri10ge_change_promisc(mgp, dev->flags & IFF_PROMISC, 1); - - /* This firmware is known to not support multicast */ - if (!mgp->fw_multicast_support) - return; - - /* Disable multicast filtering */ - - err = myri10ge_send_cmd(mgp, MXGEFW_ENABLE_ALLMULTI, &cmd, 1); - if (err != 0) { - printk(KERN_ERR "myri10ge: %s: Failed MXGEFW_ENABLE_ALLMULTI," - " error status: %d\n", dev->name, err); - goto abort; - } - - if (dev->flags & IFF_ALLMULTI) { - /* request to disable multicast filtering, so quit here */ - return; - } - - /* Flush the filters */ - - err = myri10ge_send_cmd(mgp, MXGEFW_LEAVE_ALL_MULTICAST_GROUPS, - &cmd, 1); - if (err != 0) { - printk(KERN_ERR - "myri10ge: %s: Failed MXGEFW_LEAVE_ALL_MULTICAST_GROUPS" - ", error status: %d\n", dev->name, err); - goto abort; - } - - /* Walk the multicast list, and add each address */ - for (mc_list = dev->mc_list; mc_list != NULL; mc_list = mc_list->next) { - memcpy(&cmd.data0, &mc_list->dmi_addr, 4); - memcpy(&cmd.data1, ((char *)&mc_list->dmi_addr) + 4, 2); - cmd.data0 = htonl(cmd.data0); - cmd.data1 = htonl(cmd.data1); - err = myri10ge_send_cmd(mgp, MXGEFW_JOIN_MULTICAST_GROUP, - &cmd, 1); - - if (err != 0) { - printk(KERN_ERR "myri10ge: %s: Failed " - "MXGEFW_JOIN_MULTICAST_GROUP, error status:" - "%d\t", dev->name, err); - printk(KERN_ERR "MAC %02x:%02x:%02x:%02x:%02x:%02x\n", - ((unsigned char *)&mc_list->dmi_addr)[0], - ((unsigned char *)&mc_list->dmi_addr)[1], - ((unsigned char *)&mc_list->dmi_addr)[2], - ((unsigned char *)&mc_list->dmi_addr)[3], - ((unsigned char *)&mc_list->dmi_addr)[4], - ((unsigned char *)&mc_list->dmi_addr)[5] - ); - goto abort; - } - } - /* Enable multicast filtering */ - err = myri10ge_send_cmd(mgp, MXGEFW_DISABLE_ALLMULTI, &cmd, 1); - if (err != 0) { - printk(KERN_ERR "myri10ge: %s: Failed MXGEFW_DISABLE_ALLMULTI," - "error status: %d\n", dev->name, err); - goto abort; - } - - return; - -abort: - return; + myri10ge_change_promisc(netdev_priv(dev), dev->flags & IFF_PROMISC, 1); } static int myri10ge_set_mac_address(struct net_device *dev, void *addr) @@ -2709,7 +2581,6 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) mgp->csum_flag = MXGEFW_FLAGS_CKSUM; mgp->pause = myri10ge_flow_control; mgp->intr_coal_delay = myri10ge_intr_coal_delay; - mgp->msg_enable = netif_msg_init(myri10ge_debug, MYRI10GE_MSG_DEFAULT); init_waitqueue_head(&mgp->down_wq); if (pci_enable_device(pdev)) { diff --git a/trunk/drivers/net/myri10ge/myri10ge_mcp.h b/trunk/drivers/net/myri10ge/myri10ge_mcp.h index 9519ae7cd5ec..0a6cae6cb186 100644 --- a/trunk/drivers/net/myri10ge/myri10ge_mcp.h +++ b/trunk/drivers/net/myri10ge/myri10ge_mcp.h @@ -91,19 +91,7 @@ struct mcp_kreq_ether_recv { /* Commands */ -#define MXGEFW_BOOT_HANDOFF 0xfc0000 -#define MXGEFW_BOOT_DUMMY_RDMA 0xfc01c0 - -#define MXGEFW_ETH_CMD 0xf80000 -#define MXGEFW_ETH_SEND_4 0x200000 -#define MXGEFW_ETH_SEND_1 0x240000 -#define MXGEFW_ETH_SEND_2 0x280000 -#define MXGEFW_ETH_SEND_3 0x2c0000 -#define MXGEFW_ETH_RECV_SMALL 0x300000 -#define MXGEFW_ETH_RECV_BIG 0x340000 - -#define MXGEFW_ETH_SEND(n) (0x200000 + (((n) & 0x03) * 0x40000)) -#define MXGEFW_ETH_SEND_OFFSET(n) (MXGEFW_ETH_SEND(n) - MXGEFW_ETH_SEND_4) +#define MXGEFW_CMD_OFFSET 0xf80000 enum myri10ge_mcp_cmd_type { MXGEFW_CMD_NONE = 0, @@ -166,7 +154,7 @@ enum myri10ge_mcp_cmd_type { MXGEFW_CMD_SET_MTU, MXGEFW_CMD_GET_INTR_COAL_DELAY_OFFSET, /* in microseconds */ MXGEFW_CMD_SET_STATS_INTERVAL, /* in microseconds */ - MXGEFW_CMD_SET_STATS_DMA_OBSOLETE, /* replaced by SET_STATS_DMA_V2 */ + MXGEFW_CMD_SET_STATS_DMA, MXGEFW_ENABLE_PROMISC, MXGEFW_DISABLE_PROMISC, @@ -180,26 +168,7 @@ enum myri10ge_mcp_cmd_type { * data2 = RDMA length (MSH), WDMA length (LSH) * command return data = repetitions (MSH), 0.5-ms ticks (LSH) */ - MXGEFW_DMA_TEST, - - MXGEFW_ENABLE_ALLMULTI, - MXGEFW_DISABLE_ALLMULTI, - - /* returns MXGEFW_CMD_ERROR_MULTICAST - * if there is no room in the cache - * data0,MSH(data1) = multicast group address */ - MXGEFW_JOIN_MULTICAST_GROUP, - /* returns MXGEFW_CMD_ERROR_MULTICAST - * if the address is not in the cache, - * or is equal to FF-FF-FF-FF-FF-FF - * data0,MSH(data1) = multicast group address */ - MXGEFW_LEAVE_MULTICAST_GROUP, - MXGEFW_LEAVE_ALL_MULTICAST_GROUPS, - - MXGEFW_CMD_SET_STATS_DMA_V2, - /* data0, data1 = bus addr, - * data2 = sizeof(struct mcp_irq_data) from driver point of view, allows - * adding new stuff to mcp_irq_data without changing the ABI */ + MXGEFW_DMA_TEST }; enum myri10ge_mcp_cmd_status { @@ -211,17 +180,11 @@ enum myri10ge_mcp_cmd_status { MXGEFW_CMD_ERROR_CLOSED, MXGEFW_CMD_ERROR_HASH_ERROR, MXGEFW_CMD_ERROR_BAD_PORT, - MXGEFW_CMD_ERROR_RESOURCES, - MXGEFW_CMD_ERROR_MULTICAST + MXGEFW_CMD_ERROR_RESOURCES }; -#define MXGEFW_OLD_IRQ_DATA_LEN 40 - +/* 40 Bytes */ struct mcp_irq_data { - /* add new counters at the beginning */ - u32 future_use[5]; - u32 dropped_multicast_filtered; - /* 40 Bytes */ u32 send_done_count; u32 link_up; diff --git a/trunk/drivers/net/natsemi.c b/trunk/drivers/net/natsemi.c index 9510030feeb4..db0475a1102f 100644 --- a/trunk/drivers/net/natsemi.c +++ b/trunk/drivers/net/natsemi.c @@ -3246,7 +3246,7 @@ static int __init natsemi_init_mod (void) printk(version); #endif - return pci_register_driver(&natsemi_driver); + return pci_module_init (&natsemi_driver); } static void __exit natsemi_exit_mod (void) diff --git a/trunk/drivers/net/ne2k-pci.c b/trunk/drivers/net/ne2k-pci.c index 654b477b570a..34bdba9eec79 100644 --- a/trunk/drivers/net/ne2k-pci.c +++ b/trunk/drivers/net/ne2k-pci.c @@ -702,7 +702,7 @@ static int __init ne2k_pci_init(void) #ifdef MODULE printk(version); #endif - return pci_register_driver(&ne2k_driver); + return pci_module_init (&ne2k_driver); } diff --git a/trunk/drivers/net/netx-eth.c b/trunk/drivers/net/netx-eth.c index 30ed9a5a40e0..b1311ae82675 100644 --- a/trunk/drivers/net/netx-eth.c +++ b/trunk/drivers/net/netx-eth.c @@ -17,6 +17,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include #include #include #include diff --git a/trunk/drivers/net/ni52.c b/trunk/drivers/net/ni52.c index 4d52ecf8af56..fa854c8fde75 100644 --- a/trunk/drivers/net/ni52.c +++ b/trunk/drivers/net/ni52.c @@ -1323,7 +1323,7 @@ MODULE_PARM_DESC(irq, "NI5210 IRQ number,required"); MODULE_PARM_DESC(memstart, "NI5210 memory base address,required"); MODULE_PARM_DESC(memend, "NI5210 memory end address,required"); -int __init init_module(void) +int init_module(void) { if(io <= 0x0 || !memend || !memstart || irq < 2) { printk("ni52: Autoprobing not allowed for modules.\nni52: Set symbols 'io' 'irq' 'memstart' and 'memend'\n"); diff --git a/trunk/drivers/net/ni65.c b/trunk/drivers/net/ni65.c index 810cc572f5f7..bb42ff218484 100644 --- a/trunk/drivers/net/ni65.c +++ b/trunk/drivers/net/ni65.c @@ -1253,7 +1253,7 @@ MODULE_PARM_DESC(irq, "ni6510 IRQ number (ignored for some cards)"); MODULE_PARM_DESC(io, "ni6510 I/O base address"); MODULE_PARM_DESC(dma, "ni6510 ISA DMA channel (ignored for some cards)"); -int __init init_module(void) +int init_module(void) { dev_ni65 = ni65_probe(-1); return IS_ERR(dev_ni65) ? PTR_ERR(dev_ni65) : 0; diff --git a/trunk/drivers/net/ns83820.c b/trunk/drivers/net/ns83820.c index 0dedd34804c3..0e76859c90a2 100644 --- a/trunk/drivers/net/ns83820.c +++ b/trunk/drivers/net/ns83820.c @@ -2178,7 +2178,7 @@ static struct pci_driver driver = { static int __init ns83820_init(void) { printk(KERN_INFO "ns83820.c: National Semiconductor DP83820 10/100/1000 driver.\n"); - return pci_register_driver(&driver); + return pci_module_init(&driver); } static void __exit ns83820_exit(void) diff --git a/trunk/drivers/net/pci-skeleton.c b/trunk/drivers/net/pci-skeleton.c index e6347620529e..e0e293964042 100644 --- a/trunk/drivers/net/pci-skeleton.c +++ b/trunk/drivers/net/pci-skeleton.c @@ -1963,7 +1963,7 @@ static int __init netdrv_init_module (void) #ifdef MODULE printk(version); #endif - return pci_register_driver(&netdrv_pci_driver); + return pci_module_init (&netdrv_pci_driver); } diff --git a/trunk/drivers/net/pcmcia/axnet_cs.c b/trunk/drivers/net/pcmcia/axnet_cs.c index c54f6a7ebf31..297e9f805366 100644 --- a/trunk/drivers/net/pcmcia/axnet_cs.c +++ b/trunk/drivers/net/pcmcia/axnet_cs.c @@ -771,7 +771,6 @@ static struct pcmcia_device_id axnet_ids[] = { PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0309), PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1106), PCMCIA_DEVICE_MANF_CARD(0x8a01, 0xc1ab), - PCMCIA_DEVICE_MANF_CARD(0x021b, 0x0202), PCMCIA_DEVICE_PROD_ID12("AmbiCom,Inc.", "Fast Ethernet PC Card(AMB8110)", 0x49b020a7, 0x119cc9fc), PCMCIA_DEVICE_PROD_ID124("Fast Ethernet", "16-bit PC Card", "AX88190", 0xb4be14e3, 0x9a12eb6a, 0xab9be5ef), PCMCIA_DEVICE_PROD_ID12("ASIX", "AX88190", 0x0959823b, 0xab9be5ef), @@ -787,6 +786,8 @@ static struct pcmcia_device_id axnet_ids[] = { PCMCIA_DEVICE_PROD_ID12("PCMCIA", "FastEtherCard", 0x281f1c5d, 0x7ef26116), PCMCIA_DEVICE_PROD_ID12("PCMCIA", "FEP501", 0x281f1c5d, 0x2e272058), PCMCIA_DEVICE_PROD_ID14("Network Everywhere", "AX88190", 0x820a67b6, 0xab9be5ef), + /* this is not specific enough */ + /* PCMCIA_DEVICE_MANF_CARD(0x021b, 0x0202), */ PCMCIA_DEVICE_NULL, }; MODULE_DEVICE_TABLE(pcmcia, axnet_ids); diff --git a/trunk/drivers/net/pcmcia/pcnet_cs.c b/trunk/drivers/net/pcmcia/pcnet_cs.c index cc0dcc9bf636..0ecebfc31f07 100644 --- a/trunk/drivers/net/pcmcia/pcnet_cs.c +++ b/trunk/drivers/net/pcmcia/pcnet_cs.c @@ -654,8 +654,11 @@ static int pcnet_config(struct pcmcia_device *link) SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); if (info->flags & (IS_DL10019|IS_DL10022)) { + u_char id = inb(dev->base_addr + 0x1a); dev->do_ioctl = &ei_ioctl; mii_phy_probe(dev); + if ((id == 0x30) && !info->pna_phy && (info->eth_phy == 4)) + info->eth_phy = 0; } link->dev_node = &info->node; @@ -818,6 +821,15 @@ static void mdio_write(kio_addr_t addr, int phy_id, int loc, int value) } } +static void mdio_reset(kio_addr_t addr, int phy_id) +{ + outb_p(0x08, addr); + outb_p(0x0c, addr); + outb_p(0x08, addr); + outb_p(0x0c, addr); + outb_p(0x00, addr); +} + /*====================================================================== EEPROM access routines for DL10019 and DL10022 based cards @@ -930,8 +942,7 @@ static void set_misc_reg(struct net_device *dev) } if (info->flags & IS_DL10022) { if (info->flags & HAS_MII) { - /* Advertise 100F, 100H, 10F, 10H */ - mdio_write(nic_base + DLINK_GPIO, info->eth_phy, 4, 0x01e1); + mdio_reset(nic_base + DLINK_GPIO, info->eth_phy); /* Restart MII autonegotiation */ mdio_write(nic_base + DLINK_GPIO, info->eth_phy, 0, 0x0000); mdio_write(nic_base + DLINK_GPIO, info->eth_phy, 0, 0x1200); diff --git a/trunk/drivers/net/pcmcia/xirc2ps_cs.c b/trunk/drivers/net/pcmcia/xirc2ps_cs.c index 4122bb46f5ff..9bae77ce1314 100644 --- a/trunk/drivers/net/pcmcia/xirc2ps_cs.c +++ b/trunk/drivers/net/pcmcia/xirc2ps_cs.c @@ -345,7 +345,6 @@ typedef struct local_info_t { void __iomem *dingo_ccr; /* only used for CEM56 cards */ unsigned last_ptr_value; /* last packets transmitted value */ const char *manf_str; - struct work_struct tx_timeout_task; } local_info_t; /**************** @@ -353,7 +352,6 @@ typedef struct local_info_t { */ static int do_start_xmit(struct sk_buff *skb, struct net_device *dev); static void do_tx_timeout(struct net_device *dev); -static void xirc2ps_tx_timeout_task(void *data); static struct net_device_stats *do_get_stats(struct net_device *dev); static void set_addresses(struct net_device *dev); static void set_multicast_list(struct net_device *dev); @@ -591,7 +589,6 @@ xirc2ps_probe(struct pcmcia_device *link) #ifdef HAVE_TX_TIMEOUT dev->tx_timeout = do_tx_timeout; dev->watchdog_timeo = TX_TIMEOUT; - INIT_WORK(&local->tx_timeout_task, xirc2ps_tx_timeout_task, dev); #endif return xirc2ps_config(link); @@ -1344,24 +1341,17 @@ xirc2ps_interrupt(int irq, void *dev_id, struct pt_regs *regs) /*====================================================================*/ static void -xirc2ps_tx_timeout_task(void *data) +do_tx_timeout(struct net_device *dev) { - struct net_device *dev = data; + local_info_t *lp = netdev_priv(dev); + printk(KERN_NOTICE "%s: transmit timed out\n", dev->name); + lp->stats.tx_errors++; /* reset the card */ do_reset(dev,1); dev->trans_start = jiffies; netif_wake_queue(dev); } -static void -do_tx_timeout(struct net_device *dev) -{ - local_info_t *lp = netdev_priv(dev); - lp->stats.tx_errors++; - printk(KERN_NOTICE "%s: transmit timed out\n", dev->name); - schedule_work(&lp->tx_timeout_task); -} - static int do_start_xmit(struct sk_buff *skb, struct net_device *dev) { diff --git a/trunk/drivers/net/pcnet32.c b/trunk/drivers/net/pcnet32.c index 5e26fe806e21..4daafe303358 100644 --- a/trunk/drivers/net/pcnet32.c +++ b/trunk/drivers/net/pcnet32.c @@ -202,8 +202,6 @@ static int homepna[MAX_UNITS]; #define CSR15 15 #define PCNET32_MC_FILTER 8 -#define PCNET32_79C970A 0x2621 - /* The PCNET32 Rx and Tx ring descriptors. */ struct pcnet32_rx_head { u32 base; @@ -291,7 +289,6 @@ struct pcnet32_private { /* each bit indicates an available PHY */ u32 phymask; - unsigned short chip_version; /* which variant this is */ }; static int pcnet32_probe_pci(struct pci_dev *, const struct pci_device_id *); @@ -727,11 +724,9 @@ static u32 pcnet32_get_link(struct net_device *dev) spin_lock_irqsave(&lp->lock, flags); if (lp->mii) { r = mii_link_ok(&lp->mii_if); - } else if (lp->chip_version >= PCNET32_79C970A) { + } else { ulong ioaddr = dev->base_addr; /* card base I/O address */ r = (lp->a.read_bcr(ioaddr, 4) != 0xc0); - } else { /* can not detect link on really old chips */ - r = 1; } spin_unlock_irqrestore(&lp->lock, flags); @@ -1096,10 +1091,6 @@ static int pcnet32_suspend(struct net_device *dev, unsigned long *flags, ulong ioaddr = dev->base_addr; int ticks; - /* really old chips have to be stopped. */ - if (lp->chip_version < PCNET32_79C970A) - return 0; - /* set SUSPEND (SPND) - CSR5 bit 0 */ csr5 = a->read_csr(ioaddr, CSR5); a->write_csr(ioaddr, CSR5, csr5 | CSR5_SUSPEND); @@ -1538,7 +1529,6 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev) lp->mii_if.reg_num_mask = 0x1f; lp->dxsuflo = dxsuflo; lp->mii = mii; - lp->chip_version = chip_version; lp->msg_enable = pcnet32_debug; if ((cards_found >= MAX_UNITS) || (options[cards_found] > sizeof(options_mapping))) @@ -1849,7 +1839,10 @@ static int pcnet32_open(struct net_device *dev) val |= 2; } else if (lp->options & PCNET32_PORT_ASEL) { /* workaround of xSeries250, turn on for 79C975 only */ - if (lp->chip_version == 0x2627) + i = ((lp->a.read_csr(ioaddr, 88) | + (lp->a. + read_csr(ioaddr, 89) << 16)) >> 12) & 0xffff; + if (i == 0x2627) val |= 3; } lp->a.write_bcr(ioaddr, 9, val); @@ -1993,11 +1986,9 @@ static int pcnet32_open(struct net_device *dev) netif_start_queue(dev); - if (lp->chip_version >= PCNET32_79C970A) { - /* Print the link status and start the watchdog */ - pcnet32_check_media(dev, 1); - mod_timer(&(lp->watchdog_timer), PCNET32_WATCHDOG_TIMEOUT); - } + /* Print the link status and start the watchdog */ + pcnet32_check_media(dev, 1); + mod_timer(&(lp->watchdog_timer), PCNET32_WATCHDOG_TIMEOUT); i = 0; while (i++ < 100) @@ -2978,7 +2969,7 @@ static int __init pcnet32_init_module(void) tx_start = tx_start_pt; /* find the PCI devices */ - if (!pci_register_driver(&pcnet32_driver)) + if (!pci_module_init(&pcnet32_driver)) pcnet32_have_pci = 1; /* should we find any remaining VLbus devices ? */ diff --git a/trunk/drivers/net/phy/Kconfig b/trunk/drivers/net/phy/Kconfig index b79ec0d7480f..2ba6d3a40e2e 100644 --- a/trunk/drivers/net/phy/Kconfig +++ b/trunk/drivers/net/phy/Kconfig @@ -56,22 +56,5 @@ config SMSC_PHY ---help--- Currently supports the LAN83C185 PHY -config FIXED_PHY - tristate "Drivers for PHY emulation on fixed speed/link" - depends on PHYLIB - ---help--- - Adds the driver to PHY layer to cover the boards that do not have any PHY bound, - but with the ability to manipulate with speed/link in software. The relavant MII - speed/duplex parameters could be effectively handled in user-specified fuction. - Currently tested with mpc866ads. - -config FIXED_MII_10_FDX - bool "Emulation for 10M Fdx fixed PHY behavior" - depends on FIXED_PHY - -config FIXED_MII_100_FDX - bool "Emulation for 100M Fdx fixed PHY behavior" - depends on FIXED_PHY - endmenu diff --git a/trunk/drivers/net/phy/Makefile b/trunk/drivers/net/phy/Makefile index 320f8323123f..a00e61942525 100644 --- a/trunk/drivers/net/phy/Makefile +++ b/trunk/drivers/net/phy/Makefile @@ -10,4 +10,3 @@ obj-$(CONFIG_LXT_PHY) += lxt.o obj-$(CONFIG_QSEMI_PHY) += qsemi.o obj-$(CONFIG_SMSC_PHY) += smsc.o obj-$(CONFIG_VITESSE_PHY) += vitesse.o -obj-$(CONFIG_FIXED_PHY) += fixed.o diff --git a/trunk/drivers/net/phy/fixed.c b/trunk/drivers/net/phy/fixed.c deleted file mode 100644 index 341036df4710..000000000000 --- a/trunk/drivers/net/phy/fixed.c +++ /dev/null @@ -1,358 +0,0 @@ -/* - * drivers/net/phy/fixed.c - * - * Driver for fixed PHYs, when transceiver is able to operate in one fixed mode. - * - * Author: Vitaly Bordug - * - * Copyright (c) 2006 MontaVista Software, Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#define MII_REGS_NUM 7 - -/* - The idea is to emulate normal phy behavior by responding with - pre-defined values to mii BMCR read, so that read_status hook could - take all the needed info. -*/ - -struct fixed_phy_status { - u8 link; - u16 speed; - u8 duplex; -}; - -/*----------------------------------------------------------------------------- - * Private information hoder for mii_bus - *-----------------------------------------------------------------------------*/ -struct fixed_info { - u16 *regs; - u8 regs_num; - struct fixed_phy_status phy_status; - struct phy_device *phydev; /* pointer to the container */ - /* link & speed cb */ - int(*link_update)(struct net_device*, struct fixed_phy_status*); - -}; - -/*----------------------------------------------------------------------------- - * If something weird is required to be done with link/speed, - * network driver is able to assign a function to implement this. - * May be useful for PHY's that need to be software-driven. - *-----------------------------------------------------------------------------*/ -int fixed_mdio_set_link_update(struct phy_device* phydev, - int(*link_update)(struct net_device*, struct fixed_phy_status*)) -{ - struct fixed_info *fixed; - - if(link_update == NULL) - return -EINVAL; - - if(phydev) { - if(phydev->bus) { - fixed = phydev->bus->priv; - fixed->link_update = link_update; - return 0; - } - } - return -EINVAL; -} -EXPORT_SYMBOL(fixed_mdio_set_link_update); - -/*----------------------------------------------------------------------------- - * This is used for updating internal mii regs from the status - *-----------------------------------------------------------------------------*/ -static int fixed_mdio_update_regs(struct fixed_info *fixed) -{ - u16 *regs = fixed->regs; - u16 bmsr = 0; - u16 bmcr = 0; - - if(!regs) { - printk(KERN_ERR "%s: regs not set up", __FUNCTION__); - return -EINVAL; - } - - if(fixed->phy_status.link) - bmsr |= BMSR_LSTATUS; - - if(fixed->phy_status.duplex) { - bmcr |= BMCR_FULLDPLX; - - switch ( fixed->phy_status.speed ) { - case 100: - bmsr |= BMSR_100FULL; - bmcr |= BMCR_SPEED100; - break; - - case 10: - bmsr |= BMSR_10FULL; - break; - } - } else { - switch ( fixed->phy_status.speed ) { - case 100: - bmsr |= BMSR_100HALF; - bmcr |= BMCR_SPEED100; - break; - - case 10: - bmsr |= BMSR_100HALF; - break; - } - } - - regs[MII_BMCR] = bmcr; - regs[MII_BMSR] = bmsr | 0x800; /*we are always capable of 10 hdx*/ - - return 0; -} - -static int fixed_mii_read(struct mii_bus *bus, int phy_id, int location) -{ - struct fixed_info *fixed = bus->priv; - - /* if user has registered link update callback, use it */ - if(fixed->phydev) - if(fixed->phydev->attached_dev) { - if(fixed->link_update) { - fixed->link_update(fixed->phydev->attached_dev, - &fixed->phy_status); - fixed_mdio_update_regs(fixed); - } - } - - if ((unsigned int)location >= fixed->regs_num) - return -1; - return fixed->regs[location]; -} - -static int fixed_mii_write(struct mii_bus *bus, int phy_id, int location, u16 val) -{ - /* do nothing for now*/ - return 0; -} - -static int fixed_mii_reset(struct mii_bus *bus) -{ - /*nothing here - no way/need to reset it*/ - return 0; -} - -static int fixed_config_aneg(struct phy_device *phydev) -{ - /* :TODO:03/13/2006 09:45:37 PM:: - The full autoneg funcionality can be emulated, - but no need to have anything here for now - */ - return 0; -} - -/*----------------------------------------------------------------------------- - * the manual bind will do the magic - with phy_id_mask == 0 - * match will never return true... - *-----------------------------------------------------------------------------*/ -static struct phy_driver fixed_mdio_driver = { - .name = "Fixed PHY", - .features = PHY_BASIC_FEATURES, - .config_aneg = fixed_config_aneg, - .read_status = genphy_read_status, - .driver = { .owner = THIS_MODULE,}, -}; - -/*----------------------------------------------------------------------------- - * This func is used to create all the necessary stuff, bind - * the fixed phy driver and register all it on the mdio_bus_type. - * speed is either 10 or 100, duplex is boolean. - * number is used to create multiple fixed PHYs, so that several devices can - * utilize them simultaneously. - *-----------------------------------------------------------------------------*/ -static int fixed_mdio_register_device(int number, int speed, int duplex) -{ - struct mii_bus *new_bus; - struct fixed_info *fixed; - struct phy_device *phydev; - int err = 0; - - struct device* dev = kzalloc(sizeof(struct device), GFP_KERNEL); - - if (NULL == dev) - return -ENOMEM; - - new_bus = kzalloc(sizeof(struct mii_bus), GFP_KERNEL); - - if (NULL == new_bus) { - kfree(dev); - return -ENOMEM; - } - fixed = kzalloc(sizeof(struct fixed_info), GFP_KERNEL); - - if (NULL == fixed) { - kfree(dev); - kfree(new_bus); - return -ENOMEM; - } - - fixed->regs = kzalloc(MII_REGS_NUM*sizeof(int), GFP_KERNEL); - fixed->regs_num = MII_REGS_NUM; - fixed->phy_status.speed = speed; - fixed->phy_status.duplex = duplex; - fixed->phy_status.link = 1; - - new_bus->name = "Fixed MII Bus", - new_bus->read = &fixed_mii_read, - new_bus->write = &fixed_mii_write, - new_bus->reset = &fixed_mii_reset, - - /*set up workspace*/ - fixed_mdio_update_regs(fixed); - new_bus->priv = fixed; - - new_bus->dev = dev; - dev_set_drvdata(dev, new_bus); - - /* create phy_device and register it on the mdio bus */ - phydev = phy_device_create(new_bus, 0, 0); - - /* - Put the phydev pointer into the fixed pack so that bus read/write code could - be able to access for instance attached netdev. Well it doesn't have to do - so, only in case of utilizing user-specified link-update... - */ - fixed->phydev = phydev; - - if(NULL == phydev) { - err = -ENOMEM; - goto device_create_fail; - } - - phydev->irq = -1; - phydev->dev.bus = &mdio_bus_type; - - if(number) - snprintf(phydev->dev.bus_id, BUS_ID_SIZE, - "fixed_%d@%d:%d", number, speed, duplex); - else - snprintf(phydev->dev.bus_id, BUS_ID_SIZE, - "fixed@%d:%d", speed, duplex); - phydev->bus = new_bus; - - err = device_register(&phydev->dev); - if(err) { - printk(KERN_ERR "Phy %s failed to register\n", - phydev->dev.bus_id); - goto bus_register_fail; - } - - /* - the mdio bus has phy_id match... In order not to do it - artificially, we are binding the driver here by hand; - it will be the same for all the fixed phys anyway. - */ - down_write(&phydev->dev.bus->subsys.rwsem); - - phydev->dev.driver = &fixed_mdio_driver.driver; - - err = phydev->dev.driver->probe(&phydev->dev); - if(err < 0) { - printk(KERN_ERR "Phy %s: problems with fixed driver\n",phydev->dev.bus_id); - up_write(&phydev->dev.bus->subsys.rwsem); - goto probe_fail; - } - - device_bind_driver(&phydev->dev); - up_write(&phydev->dev.bus->subsys.rwsem); - - return 0; - -probe_fail: - device_unregister(&phydev->dev); -bus_register_fail: - kfree(phydev); -device_create_fail: - kfree(dev); - kfree(new_bus); - kfree(fixed); - - return err; -} - - -MODULE_DESCRIPTION("Fixed PHY device & driver for PAL"); -MODULE_AUTHOR("Vitaly Bordug"); -MODULE_LICENSE("GPL"); - -static int __init fixed_init(void) -{ - int ret; - int duplex = 0; - - /* register on the bus... Not expected to be matched with anything there... */ - phy_driver_register(&fixed_mdio_driver); - - /* So let the fun begin... - We will create several mdio devices here, and will bound the upper - driver to them. - - Then the external software can lookup the phy bus by searching - fixed@speed:duplex, e.g. fixed@100:1, to be connected to the - virtual 100M Fdx phy. - - In case several virtual PHYs required, the bus_id will be in form - fixed_@:, which make it able even to define - driver-specific link control callback, if for instance PHY is completely - SW-driven. - - */ - -#ifdef CONFIG_FIXED_MII_DUPLEX - duplex = 1; -#endif - -#ifdef CONFIG_FIXED_MII_100_FDX - fixed_mdio_register_device(0, 100, 1); -#endif - -#ifdef CONFIX_FIXED_MII_10_FDX - fixed_mdio_register_device(0, 10, 1); -#endif - return 0; -} - -static void __exit fixed_exit(void) -{ - phy_driver_unregister(&fixed_mdio_driver); - /* :WARNING:02/18/2006 04:32:40 AM:: Cleanup all the created stuff */ -} - -module_init(fixed_init); -module_exit(fixed_exit); diff --git a/trunk/drivers/net/phy/mdio_bus.c b/trunk/drivers/net/phy/mdio_bus.c index cf6660c93ffa..1dde390c164d 100644 --- a/trunk/drivers/net/phy/mdio_bus.c +++ b/trunk/drivers/net/phy/mdio_bus.c @@ -159,7 +159,6 @@ struct bus_type mdio_bus_type = { .suspend = mdio_bus_suspend, .resume = mdio_bus_resume, }; -EXPORT_SYMBOL(mdio_bus_type); int __init mdio_bus_init(void) { diff --git a/trunk/drivers/net/phy/phy_device.c b/trunk/drivers/net/phy/phy_device.c index 2d1ecfdc80db..1bc1e032c5d6 100644 --- a/trunk/drivers/net/phy/phy_device.c +++ b/trunk/drivers/net/phy/phy_device.c @@ -45,35 +45,6 @@ static struct phy_driver genphy_driver; extern int mdio_bus_init(void); extern void mdio_bus_exit(void); -struct phy_device* phy_device_create(struct mii_bus *bus, int addr, int phy_id) -{ - struct phy_device *dev; - /* We allocate the device, and initialize the - * default values */ - dev = kcalloc(1, sizeof(*dev), GFP_KERNEL); - - if (NULL == dev) - return (struct phy_device*) PTR_ERR((void*)-ENOMEM); - - dev->speed = 0; - dev->duplex = -1; - dev->pause = dev->asym_pause = 0; - dev->link = 1; - - dev->autoneg = AUTONEG_ENABLE; - - dev->addr = addr; - dev->phy_id = phy_id; - dev->bus = bus; - - dev->state = PHY_DOWN; - - spin_lock_init(&dev->lock); - - return dev; -} -EXPORT_SYMBOL(phy_device_create); - /* get_phy_device * * description: Reads the ID registers of the PHY at addr on the @@ -107,7 +78,27 @@ struct phy_device * get_phy_device(struct mii_bus *bus, int addr) if (0xffffffff == phy_id) return NULL; - dev = phy_device_create(bus, addr, phy_id); + /* Otherwise, we allocate the device, and initialize the + * default values */ + dev = kcalloc(1, sizeof(*dev), GFP_KERNEL); + + if (NULL == dev) + return ERR_PTR(-ENOMEM); + + dev->speed = 0; + dev->duplex = -1; + dev->pause = dev->asym_pause = 0; + dev->link = 1; + + dev->autoneg = AUTONEG_ENABLE; + + dev->addr = addr; + dev->phy_id = phy_id; + dev->bus = bus; + + dev->state = PHY_DOWN; + + spin_lock_init(&dev->lock); return dev; } diff --git a/trunk/drivers/net/phy/smsc.c b/trunk/drivers/net/phy/smsc.c index b1d8ed40ad98..25e31fb5cb31 100644 --- a/trunk/drivers/net/phy/smsc.c +++ b/trunk/drivers/net/phy/smsc.c @@ -14,6 +14,7 @@ * */ +#include #include #include #include diff --git a/trunk/drivers/net/phy/vitesse.c b/trunk/drivers/net/phy/vitesse.c index 792716beb052..ffd215d9a9be 100644 --- a/trunk/drivers/net/phy/vitesse.c +++ b/trunk/drivers/net/phy/vitesse.c @@ -12,6 +12,7 @@ * */ +#include #include #include #include diff --git a/trunk/drivers/net/qla3xxx.c b/trunk/drivers/net/qla3xxx.c deleted file mode 100644 index c729aeeb4696..000000000000 --- a/trunk/drivers/net/qla3xxx.c +++ /dev/null @@ -1,3537 +0,0 @@ -/* - * QLogic QLA3xxx NIC HBA Driver - * Copyright (c) 2003-2006 QLogic Corporation - * - * See LICENSE.qla3xxx for copyright and licensing details. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "qla3xxx.h" - -#define DRV_NAME "qla3xxx" -#define DRV_STRING "QLogic ISP3XXX Network Driver" -#define DRV_VERSION "v2.02.00-k36" -#define PFX DRV_NAME " " - -static const char ql3xxx_driver_name[] = DRV_NAME; -static const char ql3xxx_driver_version[] = DRV_VERSION; - -MODULE_AUTHOR("QLogic Corporation"); -MODULE_DESCRIPTION("QLogic ISP3XXX Network Driver " DRV_VERSION " "); -MODULE_LICENSE("GPL"); -MODULE_VERSION(DRV_VERSION); - -static const u32 default_msg - = NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK - | NETIF_MSG_IFUP | NETIF_MSG_IFDOWN; - -static int debug = -1; /* defaults above */ -module_param(debug, int, 0); -MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)"); - -static int msi; -module_param(msi, int, 0); -MODULE_PARM_DESC(msi, "Turn on Message Signaled Interrupts."); - -static struct pci_device_id ql3xxx_pci_tbl[] __devinitdata = { - {PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, QL3022_DEVICE_ID)}, - /* required last entry */ - {0,} -}; - -MODULE_DEVICE_TABLE(pci, ql3xxx_pci_tbl); - -/* - * Caller must take hw_lock. - */ -static int ql_sem_spinlock(struct ql3_adapter *qdev, - u32 sem_mask, u32 sem_bits) -{ - struct ql3xxx_port_registers __iomem *port_regs = qdev->mem_map_registers; - u32 value; - unsigned int seconds = 3; - - do { - writel((sem_mask | sem_bits), - &port_regs->CommonRegs.semaphoreReg); - value = readl(&port_regs->CommonRegs.semaphoreReg); - if ((value & (sem_mask >> 16)) == sem_bits) - return 0; - ssleep(1); - } while(--seconds); - return -1; -} - -static void ql_sem_unlock(struct ql3_adapter *qdev, u32 sem_mask) -{ - struct ql3xxx_port_registers __iomem *port_regs = qdev->mem_map_registers; - writel(sem_mask, &port_regs->CommonRegs.semaphoreReg); - readl(&port_regs->CommonRegs.semaphoreReg); -} - -static int ql_sem_lock(struct ql3_adapter *qdev, u32 sem_mask, u32 sem_bits) -{ - struct ql3xxx_port_registers __iomem *port_regs = qdev->mem_map_registers; - u32 value; - - writel((sem_mask | sem_bits), &port_regs->CommonRegs.semaphoreReg); - value = readl(&port_regs->CommonRegs.semaphoreReg); - return ((value & (sem_mask >> 16)) == sem_bits); -} - -/* - * Caller holds hw_lock. - */ -static int ql_wait_for_drvr_lock(struct ql3_adapter *qdev) -{ - int i = 0; - - while (1) { - if (!ql_sem_lock(qdev, - QL_DRVR_SEM_MASK, - (QL_RESOURCE_BITS_BASE_CODE | (qdev->mac_index) - * 2) << 1)) { - if (i < 10) { - ssleep(1); - i++; - } else { - printk(KERN_ERR PFX "%s: Timed out waiting for " - "driver lock...\n", - qdev->ndev->name); - return 0; - } - } else { - printk(KERN_DEBUG PFX - "%s: driver lock acquired.\n", - qdev->ndev->name); - return 1; - } - } -} - -static void ql_set_register_page(struct ql3_adapter *qdev, u32 page) -{ - struct ql3xxx_port_registers __iomem *port_regs = qdev->mem_map_registers; - - writel(((ISP_CONTROL_NP_MASK << 16) | page), - &port_regs->CommonRegs.ispControlStatus); - readl(&port_regs->CommonRegs.ispControlStatus); - qdev->current_page = page; -} - -static u32 ql_read_common_reg_l(struct ql3_adapter *qdev, - u32 __iomem * reg) -{ - u32 value; - unsigned long hw_flags; - - spin_lock_irqsave(&qdev->hw_lock, hw_flags); - value = readl(reg); - spin_unlock_irqrestore(&qdev->hw_lock, hw_flags); - - return value; -} - -static u32 ql_read_common_reg(struct ql3_adapter *qdev, - u32 __iomem * reg) -{ - return readl(reg); -} - -static u32 ql_read_page0_reg_l(struct ql3_adapter *qdev, u32 __iomem *reg) -{ - u32 value; - unsigned long hw_flags; - - spin_lock_irqsave(&qdev->hw_lock, hw_flags); - - if (qdev->current_page != 0) - ql_set_register_page(qdev,0); - value = readl(reg); - - spin_unlock_irqrestore(&qdev->hw_lock, hw_flags); - return value; -} - -static u32 ql_read_page0_reg(struct ql3_adapter *qdev, u32 __iomem *reg) -{ - if (qdev->current_page != 0) - ql_set_register_page(qdev,0); - return readl(reg); -} - -static void ql_write_common_reg_l(struct ql3_adapter *qdev, - u32 * reg, u32 value) -{ - unsigned long hw_flags; - - spin_lock_irqsave(&qdev->hw_lock, hw_flags); - writel(value, (u32 *) reg); - readl(reg); - spin_unlock_irqrestore(&qdev->hw_lock, hw_flags); - return; -} - -static void ql_write_common_reg(struct ql3_adapter *qdev, - u32 * reg, u32 value) -{ - writel(value, (u32 *) reg); - readl(reg); - return; -} - -static void ql_write_page0_reg(struct ql3_adapter *qdev, - u32 * reg, u32 value) -{ - if (qdev->current_page != 0) - ql_set_register_page(qdev,0); - writel(value, (u32 *) reg); - readl(reg); - return; -} - -/* - * Caller holds hw_lock. Only called during init. - */ -static void ql_write_page1_reg(struct ql3_adapter *qdev, - u32 * reg, u32 value) -{ - if (qdev->current_page != 1) - ql_set_register_page(qdev,1); - writel(value, (u32 *) reg); - readl(reg); - return; -} - -/* - * Caller holds hw_lock. Only called during init. - */ -static void ql_write_page2_reg(struct ql3_adapter *qdev, - u32 * reg, u32 value) -{ - if (qdev->current_page != 2) - ql_set_register_page(qdev,2); - writel(value, (u32 *) reg); - readl(reg); - return; -} - -static void ql_disable_interrupts(struct ql3_adapter *qdev) -{ - struct ql3xxx_port_registers __iomem *port_regs = qdev->mem_map_registers; - - ql_write_common_reg_l(qdev, &port_regs->CommonRegs.ispInterruptMaskReg, - (ISP_IMR_ENABLE_INT << 16)); - -} - -static void ql_enable_interrupts(struct ql3_adapter *qdev) -{ - struct ql3xxx_port_registers __iomem *port_regs = qdev->mem_map_registers; - - ql_write_common_reg_l(qdev, &port_regs->CommonRegs.ispInterruptMaskReg, - ((0xff << 16) | ISP_IMR_ENABLE_INT)); - -} - -static void ql_release_to_lrg_buf_free_list(struct ql3_adapter *qdev, - struct ql_rcv_buf_cb *lrg_buf_cb) -{ - u64 map; - lrg_buf_cb->next = NULL; - - if (qdev->lrg_buf_free_tail == NULL) { /* The list is empty */ - qdev->lrg_buf_free_head = qdev->lrg_buf_free_tail = lrg_buf_cb; - } else { - qdev->lrg_buf_free_tail->next = lrg_buf_cb; - qdev->lrg_buf_free_tail = lrg_buf_cb; - } - - if (!lrg_buf_cb->skb) { - lrg_buf_cb->skb = dev_alloc_skb(qdev->lrg_buffer_len); - if (unlikely(!lrg_buf_cb->skb)) { - printk(KERN_ERR PFX "%s: failed dev_alloc_skb().\n", - qdev->ndev->name); - qdev->lrg_buf_skb_check++; - } else { - /* - * We save some space to copy the ethhdr from first - * buffer - */ - skb_reserve(lrg_buf_cb->skb, QL_HEADER_SPACE); - map = pci_map_single(qdev->pdev, - lrg_buf_cb->skb->data, - qdev->lrg_buffer_len - - QL_HEADER_SPACE, - PCI_DMA_FROMDEVICE); - lrg_buf_cb->buf_phy_addr_low = - cpu_to_le32(LS_64BITS(map)); - lrg_buf_cb->buf_phy_addr_high = - cpu_to_le32(MS_64BITS(map)); - pci_unmap_addr_set(lrg_buf_cb, mapaddr, map); - pci_unmap_len_set(lrg_buf_cb, maplen, - qdev->lrg_buffer_len - - QL_HEADER_SPACE); - } - } - - qdev->lrg_buf_free_count++; -} - -static struct ql_rcv_buf_cb *ql_get_from_lrg_buf_free_list(struct ql3_adapter - *qdev) -{ - struct ql_rcv_buf_cb *lrg_buf_cb; - - if ((lrg_buf_cb = qdev->lrg_buf_free_head) != NULL) { - if ((qdev->lrg_buf_free_head = lrg_buf_cb->next) == NULL) - qdev->lrg_buf_free_tail = NULL; - qdev->lrg_buf_free_count--; - } - - return lrg_buf_cb; -} - -static u32 addrBits = EEPROM_NO_ADDR_BITS; -static u32 dataBits = EEPROM_NO_DATA_BITS; - -static void fm93c56a_deselect(struct ql3_adapter *qdev); -static void eeprom_readword(struct ql3_adapter *qdev, u32 eepromAddr, - unsigned short *value); - -/* - * Caller holds hw_lock. - */ -static void fm93c56a_select(struct ql3_adapter *qdev) -{ - struct ql3xxx_port_registers __iomem *port_regs = - qdev->mem_map_registers; - - qdev->eeprom_cmd_data = AUBURN_EEPROM_CS_1; - ql_write_common_reg(qdev, &port_regs->CommonRegs.serialPortInterfaceReg, - ISP_NVRAM_MASK | qdev->eeprom_cmd_data); - ql_write_common_reg(qdev, &port_regs->CommonRegs.serialPortInterfaceReg, - ((ISP_NVRAM_MASK << 16) | qdev->eeprom_cmd_data)); -} - -/* - * Caller holds hw_lock. - */ -static void fm93c56a_cmd(struct ql3_adapter *qdev, u32 cmd, u32 eepromAddr) -{ - int i; - u32 mask; - u32 dataBit; - u32 previousBit; - struct ql3xxx_port_registers __iomem *port_regs = - qdev->mem_map_registers; - - /* Clock in a zero, then do the start bit */ - ql_write_common_reg(qdev, &port_regs->CommonRegs.serialPortInterfaceReg, - ISP_NVRAM_MASK | qdev->eeprom_cmd_data | - AUBURN_EEPROM_DO_1); - ql_write_common_reg(qdev, &port_regs->CommonRegs.serialPortInterfaceReg, - ISP_NVRAM_MASK | qdev-> - eeprom_cmd_data | AUBURN_EEPROM_DO_1 | - AUBURN_EEPROM_CLK_RISE); - ql_write_common_reg(qdev, &port_regs->CommonRegs.serialPortInterfaceReg, - ISP_NVRAM_MASK | qdev-> - eeprom_cmd_data | AUBURN_EEPROM_DO_1 | - AUBURN_EEPROM_CLK_FALL); - - mask = 1 << (FM93C56A_CMD_BITS - 1); - /* Force the previous data bit to be different */ - previousBit = 0xffff; - for (i = 0; i < FM93C56A_CMD_BITS; i++) { - dataBit = - (cmd & mask) ? AUBURN_EEPROM_DO_1 : AUBURN_EEPROM_DO_0; - if (previousBit != dataBit) { - /* - * If the bit changed, then change the DO state to - * match - */ - ql_write_common_reg(qdev, - &port_regs->CommonRegs. - serialPortInterfaceReg, - ISP_NVRAM_MASK | qdev-> - eeprom_cmd_data | dataBit); - previousBit = dataBit; - } - ql_write_common_reg(qdev, - &port_regs->CommonRegs. - serialPortInterfaceReg, - ISP_NVRAM_MASK | qdev-> - eeprom_cmd_data | dataBit | - AUBURN_EEPROM_CLK_RISE); - ql_write_common_reg(qdev, - &port_regs->CommonRegs. - serialPortInterfaceReg, - ISP_NVRAM_MASK | qdev-> - eeprom_cmd_data | dataBit | - AUBURN_EEPROM_CLK_FALL); - cmd = cmd << 1; - } - - mask = 1 << (addrBits - 1); - /* Force the previous data bit to be different */ - previousBit = 0xffff; - for (i = 0; i < addrBits; i++) { - dataBit = - (eepromAddr & mask) ? AUBURN_EEPROM_DO_1 : - AUBURN_EEPROM_DO_0; - if (previousBit != dataBit) { - /* - * If the bit changed, then change the DO state to - * match - */ - ql_write_common_reg(qdev, - &port_regs->CommonRegs. - serialPortInterfaceReg, - ISP_NVRAM_MASK | qdev-> - eeprom_cmd_data | dataBit); - previousBit = dataBit; - } - ql_write_common_reg(qdev, - &port_regs->CommonRegs. - serialPortInterfaceReg, - ISP_NVRAM_MASK | qdev-> - eeprom_cmd_data | dataBit | - AUBURN_EEPROM_CLK_RISE); - ql_write_common_reg(qdev, - &port_regs->CommonRegs. - serialPortInterfaceReg, - ISP_NVRAM_MASK | qdev-> - eeprom_cmd_data | dataBit | - AUBURN_EEPROM_CLK_FALL); - eepromAddr = eepromAddr << 1; - } -} - -/* - * Caller holds hw_lock. - */ -static void fm93c56a_deselect(struct ql3_adapter *qdev) -{ - struct ql3xxx_port_registers __iomem *port_regs = - qdev->mem_map_registers; - qdev->eeprom_cmd_data = AUBURN_EEPROM_CS_0; - ql_write_common_reg(qdev, &port_regs->CommonRegs.serialPortInterfaceReg, - ISP_NVRAM_MASK | qdev->eeprom_cmd_data); -} - -/* - * Caller holds hw_lock. - */ -static void fm93c56a_datain(struct ql3_adapter *qdev, unsigned short *value) -{ - int i; - u32 data = 0; - u32 dataBit; - struct ql3xxx_port_registers __iomem *port_regs = - qdev->mem_map_registers; - - /* Read the data bits */ - /* The first bit is a dummy. Clock right over it. */ - for (i = 0; i < dataBits; i++) { - ql_write_common_reg(qdev, - &port_regs->CommonRegs. - serialPortInterfaceReg, - ISP_NVRAM_MASK | qdev->eeprom_cmd_data | - AUBURN_EEPROM_CLK_RISE); - ql_write_common_reg(qdev, - &port_regs->CommonRegs. - serialPortInterfaceReg, - ISP_NVRAM_MASK | qdev->eeprom_cmd_data | - AUBURN_EEPROM_CLK_FALL); - dataBit = - (ql_read_common_reg - (qdev, - &port_regs->CommonRegs. - serialPortInterfaceReg) & AUBURN_EEPROM_DI_1) ? 1 : 0; - data = (data << 1) | dataBit; - } - *value = (u16) data; -} - -/* - * Caller holds hw_lock. - */ -static void eeprom_readword(struct ql3_adapter *qdev, - u32 eepromAddr, unsigned short *value) -{ - fm93c56a_select(qdev); - fm93c56a_cmd(qdev, (int)FM93C56A_READ, eepromAddr); - fm93c56a_datain(qdev, value); - fm93c56a_deselect(qdev); -} - -static void ql_swap_mac_addr(u8 * macAddress) -{ -#ifdef __BIG_ENDIAN - u8 temp; - temp = macAddress[0]; - macAddress[0] = macAddress[1]; - macAddress[1] = temp; - temp = macAddress[2]; - macAddress[2] = macAddress[3]; - macAddress[3] = temp; - temp = macAddress[4]; - macAddress[4] = macAddress[5]; - macAddress[5] = temp; -#endif -} - -static int ql_get_nvram_params(struct ql3_adapter *qdev) -{ - u16 *pEEPROMData; - u16 checksum = 0; - u32 index; - unsigned long hw_flags; - - spin_lock_irqsave(&qdev->hw_lock, hw_flags); - - pEEPROMData = (u16 *) & qdev->nvram_data; - qdev->eeprom_cmd_data = 0; - if(ql_sem_spinlock(qdev, QL_NVRAM_SEM_MASK, - (QL_RESOURCE_BITS_BASE_CODE | (qdev->mac_index) * - 2) << 10)) { - printk(KERN_ERR PFX"%s: Failed ql_sem_spinlock().\n", - __func__); - spin_unlock_irqrestore(&qdev->hw_lock, hw_flags); - return -1; - } - - for (index = 0; index < EEPROM_SIZE; index++) { - eeprom_readword(qdev, index, pEEPROMData); - checksum += *pEEPROMData; - pEEPROMData++; - } - ql_sem_unlock(qdev, QL_NVRAM_SEM_MASK); - - if (checksum != 0) { - printk(KERN_ERR PFX "%s: checksum should be zero, is %x!!\n", - qdev->ndev->name, checksum); - spin_unlock_irqrestore(&qdev->hw_lock, hw_flags); - return -1; - } - - /* - * We have a problem with endianness for the MAC addresses - * and the two 8-bit values version, and numPorts. We - * have to swap them on big endian systems. - */ - ql_swap_mac_addr(qdev->nvram_data.funcCfg_fn0.macAddress); - ql_swap_mac_addr(qdev->nvram_data.funcCfg_fn1.macAddress); - ql_swap_mac_addr(qdev->nvram_data.funcCfg_fn2.macAddress); - ql_swap_mac_addr(qdev->nvram_data.funcCfg_fn3.macAddress); - pEEPROMData = (u16 *) & qdev->nvram_data.version; - *pEEPROMData = le16_to_cpu(*pEEPROMData); - - spin_unlock_irqrestore(&qdev->hw_lock, hw_flags); - return checksum; -} - -static const u32 PHYAddr[2] = { - PORT0_PHY_ADDRESS, PORT1_PHY_ADDRESS -}; - -static int ql_wait_for_mii_ready(struct ql3_adapter *qdev) -{ - struct ql3xxx_port_registers __iomem *port_regs = - qdev->mem_map_registers; - u32 temp; - int count = 1000; - - while (count) { - temp = ql_read_page0_reg(qdev, &port_regs->macMIIStatusReg); - if (!(temp & MAC_MII_STATUS_BSY)) - return 0; - udelay(10); - count--; - } - return -1; -} - -static void ql_mii_enable_scan_mode(struct ql3_adapter *qdev) -{ - struct ql3xxx_port_registers __iomem *port_regs = - qdev->mem_map_registers; - u32 scanControl; - - if (qdev->numPorts > 1) { - /* Auto scan will cycle through multiple ports */ - scanControl = MAC_MII_CONTROL_AS | MAC_MII_CONTROL_SC; - } else { - scanControl = MAC_MII_CONTROL_SC; - } - - /* - * Scan register 1 of PHY/PETBI, - * Set up to scan both devices - * The autoscan starts from the first register, completes - * the last one before rolling over to the first - */ - ql_write_page0_reg(qdev, &port_regs->macMIIMgmtAddrReg, - PHYAddr[0] | MII_SCAN_REGISTER); - - ql_write_page0_reg(qdev, &port_regs->macMIIMgmtControlReg, - (scanControl) | - ((MAC_MII_CONTROL_SC | MAC_MII_CONTROL_AS) << 16)); -} - -static u8 ql_mii_disable_scan_mode(struct ql3_adapter *qdev) -{ - u8 ret; - struct ql3xxx_port_registers __iomem *port_regs = - qdev->mem_map_registers; - - /* See if scan mode is enabled before we turn it off */ - if (ql_read_page0_reg(qdev, &port_regs->macMIIMgmtControlReg) & - (MAC_MII_CONTROL_AS | MAC_MII_CONTROL_SC)) { - /* Scan is enabled */ - ret = 1; - } else { - /* Scan is disabled */ - ret = 0; - } - - /* - * When disabling scan mode you must first change the MII register - * address - */ - ql_write_page0_reg(qdev, &port_regs->macMIIMgmtAddrReg, - PHYAddr[0] | MII_SCAN_REGISTER); - - ql_write_page0_reg(qdev, &port_regs->macMIIMgmtControlReg, - ((MAC_MII_CONTROL_SC | MAC_MII_CONTROL_AS | - MAC_MII_CONTROL_RC) << 16)); - - return ret; -} - -static int ql_mii_write_reg_ex(struct ql3_adapter *qdev, - u16 regAddr, u16 value, u32 mac_index) -{ - struct ql3xxx_port_registers __iomem *port_regs = - qdev->mem_map_registers; - u8 scanWasEnabled; - - scanWasEnabled = ql_mii_disable_scan_mode(qdev); - - if (ql_wait_for_mii_ready(qdev)) { - if (netif_msg_link(qdev)) - printk(KERN_WARNING PFX - "%s Timed out waiting for management port to " - "get free before issuing command.\n", - qdev->ndev->name); - return -1; - } - - ql_write_page0_reg(qdev, &port_regs->macMIIMgmtAddrReg, - PHYAddr[mac_index] | regAddr); - - ql_write_page0_reg(qdev, &port_regs->macMIIMgmtDataReg, value); - - /* Wait for write to complete 9/10/04 SJP */ - if (ql_wait_for_mii_ready(qdev)) { - if (netif_msg_link(qdev)) - printk(KERN_WARNING PFX - "%s: Timed out waiting for management port to" - "get free before issuing command.\n", - qdev->ndev->name); - return -1; - } - - if (scanWasEnabled) - ql_mii_enable_scan_mode(qdev); - - return 0; -} - -static int ql_mii_read_reg_ex(struct ql3_adapter *qdev, u16 regAddr, - u16 * value, u32 mac_index) -{ - struct ql3xxx_port_registers __iomem *port_regs = - qdev->mem_map_registers; - u8 scanWasEnabled; - u32 temp; - - scanWasEnabled = ql_mii_disable_scan_mode(qdev); - - if (ql_wait_for_mii_ready(qdev)) { - if (netif_msg_link(qdev)) - printk(KERN_WARNING PFX - "%s: Timed out waiting for management port to " - "get free before issuing command.\n", - qdev->ndev->name); - return -1; - } - - ql_write_page0_reg(qdev, &port_regs->macMIIMgmtAddrReg, - PHYAddr[mac_index] | regAddr); - - ql_write_page0_reg(qdev, &port_regs->macMIIMgmtControlReg, - (MAC_MII_CONTROL_RC << 16)); - - ql_write_page0_reg(qdev, &port_regs->macMIIMgmtControlReg, - (MAC_MII_CONTROL_RC << 16) | MAC_MII_CONTROL_RC); - - /* Wait for the read to complete */ - if (ql_wait_for_mii_ready(qdev)) { - if (netif_msg_link(qdev)) - printk(KERN_WARNING PFX - "%s: Timed out waiting for management port to " - "get free after issuing command.\n", - qdev->ndev->name); - return -1; - } - - temp = ql_read_page0_reg(qdev, &port_regs->macMIIMgmtDataReg); - *value = (u16) temp; - - if (scanWasEnabled) - ql_mii_enable_scan_mode(qdev); - - return 0; -} - -static int ql_mii_write_reg(struct ql3_adapter *qdev, u16 regAddr, u16 value) -{ - struct ql3xxx_port_registers __iomem *port_regs = - qdev->mem_map_registers; - - ql_mii_disable_scan_mode(qdev); - - if (ql_wait_for_mii_ready(qdev)) { - if (netif_msg_link(qdev)) - printk(KERN_WARNING PFX - "%s: Timed out waiting for management port to " - "get free before issuing command.\n", - qdev->ndev->name); - return -1; - } - - ql_write_page0_reg(qdev, &port_regs->macMIIMgmtAddrReg, - qdev->PHYAddr | regAddr); - - ql_write_page0_reg(qdev, &port_regs->macMIIMgmtDataReg, value); - - /* Wait for write to complete. */ - if (ql_wait_for_mii_ready(qdev)) { - if (netif_msg_link(qdev)) - printk(KERN_WARNING PFX - "%s: Timed out waiting for management port to " - "get free before issuing command.\n", - qdev->ndev->name); - return -1; - } - - ql_mii_enable_scan_mode(qdev); - - return 0; -} - -static int ql_mii_read_reg(struct ql3_adapter *qdev, u16 regAddr, u16 *value) -{ - u32 temp; - struct ql3xxx_port_registers __iomem *port_regs = - qdev->mem_map_registers; - - ql_mii_disable_scan_mode(qdev); - - if (ql_wait_for_mii_ready(qdev)) { - if (netif_msg_link(qdev)) - printk(KERN_WARNING PFX - "%s: Timed out waiting for management port to " - "get free before issuing command.\n", - qdev->ndev->name); - return -1; - } - - ql_write_page0_reg(qdev, &port_regs->macMIIMgmtAddrReg, - qdev->PHYAddr | regAddr); - - ql_write_page0_reg(qdev, &port_regs->macMIIMgmtControlReg, - (MAC_MII_CONTROL_RC << 16)); - - ql_write_page0_reg(qdev, &port_regs->macMIIMgmtControlReg, - (MAC_MII_CONTROL_RC << 16) | MAC_MII_CONTROL_RC); - - /* Wait for the read to complete */ - if (ql_wait_for_mii_ready(qdev)) { - if (netif_msg_link(qdev)) - printk(KERN_WARNING PFX - "%s: Timed out waiting for management port to " - "get free before issuing command.\n", - qdev->ndev->name); - return -1; - } - - temp = ql_read_page0_reg(qdev, &port_regs->macMIIMgmtDataReg); - *value = (u16) temp; - - ql_mii_enable_scan_mode(qdev); - - return 0; -} - -static void ql_petbi_reset(struct ql3_adapter *qdev) -{ - ql_mii_write_reg(qdev, PETBI_CONTROL_REG, PETBI_CTRL_SOFT_RESET); -} - -static void ql_petbi_start_neg(struct ql3_adapter *qdev) -{ - u16 reg; - - /* Enable Auto-negotiation sense */ - ql_mii_read_reg(qdev, PETBI_TBI_CTRL, ®); - reg |= PETBI_TBI_AUTO_SENSE; - ql_mii_write_reg(qdev, PETBI_TBI_CTRL, reg); - - ql_mii_write_reg(qdev, PETBI_NEG_ADVER, - PETBI_NEG_PAUSE | PETBI_NEG_DUPLEX); - - ql_mii_write_reg(qdev, PETBI_CONTROL_REG, - PETBI_CTRL_AUTO_NEG | PETBI_CTRL_RESTART_NEG | - PETBI_CTRL_FULL_DUPLEX | PETBI_CTRL_SPEED_1000); - -} - -static void ql_petbi_reset_ex(struct ql3_adapter *qdev, u32 mac_index) -{ - ql_mii_write_reg_ex(qdev, PETBI_CONTROL_REG, PETBI_CTRL_SOFT_RESET, - mac_index); -} - -static void ql_petbi_start_neg_ex(struct ql3_adapter *qdev, u32 mac_index) -{ - u16 reg; - - /* Enable Auto-negotiation sense */ - ql_mii_read_reg_ex(qdev, PETBI_TBI_CTRL, ®, mac_index); - reg |= PETBI_TBI_AUTO_SENSE; - ql_mii_write_reg_ex(qdev, PETBI_TBI_CTRL, reg, mac_index); - - ql_mii_write_reg_ex(qdev, PETBI_NEG_ADVER, - PETBI_NEG_PAUSE | PETBI_NEG_DUPLEX, mac_index); - - ql_mii_write_reg_ex(qdev, PETBI_CONTROL_REG, - PETBI_CTRL_AUTO_NEG | PETBI_CTRL_RESTART_NEG | - PETBI_CTRL_FULL_DUPLEX | PETBI_CTRL_SPEED_1000, - mac_index); -} - -static void ql_petbi_init(struct ql3_adapter *qdev) -{ - ql_petbi_reset(qdev); - ql_petbi_start_neg(qdev); -} - -static void ql_petbi_init_ex(struct ql3_adapter *qdev, u32 mac_index) -{ - ql_petbi_reset_ex(qdev, mac_index); - ql_petbi_start_neg_ex(qdev, mac_index); -} - -static int ql_is_petbi_neg_pause(struct ql3_adapter *qdev) -{ - u16 reg; - - if (ql_mii_read_reg(qdev, PETBI_NEG_PARTNER, ®) < 0) - return 0; - - return (reg & PETBI_NEG_PAUSE_MASK) == PETBI_NEG_PAUSE; -} - -static int ql_phy_get_speed(struct ql3_adapter *qdev) -{ - u16 reg; - - if (ql_mii_read_reg(qdev, AUX_CONTROL_STATUS, ®) < 0) - return 0; - - reg = (((reg & 0x18) >> 3) & 3); - - if (reg == 2) - return SPEED_1000; - else if (reg == 1) - return SPEED_100; - else if (reg == 0) - return SPEED_10; - else - return -1; -} - -static int ql_is_full_dup(struct ql3_adapter *qdev) -{ - u16 reg; - - if (ql_mii_read_reg(qdev, AUX_CONTROL_STATUS, ®) < 0) - return 0; - - return (reg & PHY_AUX_DUPLEX_STAT) != 0; -} - -static int ql_is_phy_neg_pause(struct ql3_adapter *qdev) -{ - u16 reg; - - if (ql_mii_read_reg(qdev, PHY_NEG_PARTNER, ®) < 0) - return 0; - - return (reg & PHY_NEG_PAUSE) != 0; -} - -/* - * Caller holds hw_lock. - */ -static void ql_mac_enable(struct ql3_adapter *qdev, u32 enable) -{ - struct ql3xxx_port_registers __iomem *port_regs = - qdev->mem_map_registers; - u32 value; - - if (enable) - value = (MAC_CONFIG_REG_PE | (MAC_CONFIG_REG_PE << 16)); - else - value = (MAC_CONFIG_REG_PE << 16); - - if (qdev->mac_index) - ql_write_page0_reg(qdev, &port_regs->mac1ConfigReg, value); - else - ql_write_page0_reg(qdev, &port_regs->mac0ConfigReg, value); -} - -/* - * Caller holds hw_lock. - */ -static void ql_mac_cfg_soft_reset(struct ql3_adapter *qdev, u32 enable) -{ - struct ql3xxx_port_registers __iomem *port_regs = - qdev->mem_map_registers; - u32 value; - - if (enable) - value = (MAC_CONFIG_REG_SR | (MAC_CONFIG_REG_SR << 16)); - else - value = (MAC_CONFIG_REG_SR << 16); - - if (qdev->mac_index) - ql_write_page0_reg(qdev, &port_regs->mac1ConfigReg, value); - else - ql_write_page0_reg(qdev, &port_regs->mac0ConfigReg, value); -} - -/* - * Caller holds hw_lock. - */ -static void ql_mac_cfg_gig(struct ql3_adapter *qdev, u32 enable) -{ - struct ql3xxx_port_registers __iomem *port_regs = - qdev->mem_map_registers; - u32 value; - - if (enable) - value = (MAC_CONFIG_REG_GM | (MAC_CONFIG_REG_GM << 16)); - else - value = (MAC_CONFIG_REG_GM << 16); - - if (qdev->mac_index) - ql_write_page0_reg(qdev, &port_regs->mac1ConfigReg, value); - else - ql_write_page0_reg(qdev, &port_regs->mac0ConfigReg, value); -} - -/* - * Caller holds hw_lock. - */ -static void ql_mac_cfg_full_dup(struct ql3_adapter *qdev, u32 enable) -{ - struct ql3xxx_port_registers __iomem *port_regs = - qdev->mem_map_registers; - u32 value; - - if (enable) - value = (MAC_CONFIG_REG_FD | (MAC_CONFIG_REG_FD << 16)); - else - value = (MAC_CONFIG_REG_FD << 16); - - if (qdev->mac_index) - ql_write_page0_reg(qdev, &port_regs->mac1ConfigReg, value); - else - ql_write_page0_reg(qdev, &port_regs->mac0ConfigReg, value); -} - -/* - * Caller holds hw_lock. - */ -static void ql_mac_cfg_pause(struct ql3_adapter *qdev, u32 enable) -{ - struct ql3xxx_port_registers __iomem *port_regs = - qdev->mem_map_registers; - u32 value; - - if (enable) - value = - ((MAC_CONFIG_REG_TF | MAC_CONFIG_REG_RF) | - ((MAC_CONFIG_REG_TF | MAC_CONFIG_REG_RF) << 16)); - else - value = ((MAC_CONFIG_REG_TF | MAC_CONFIG_REG_RF) << 16); - - if (qdev->mac_index) - ql_write_page0_reg(qdev, &port_regs->mac1ConfigReg, value); - else - ql_write_page0_reg(qdev, &port_regs->mac0ConfigReg, value); -} - -/* - * Caller holds hw_lock. - */ -static int ql_is_fiber(struct ql3_adapter *qdev) -{ - struct ql3xxx_port_registers __iomem *port_regs = - qdev->mem_map_registers; - u32 bitToCheck = 0; - u32 temp; - - switch (qdev->mac_index) { - case 0: - bitToCheck = PORT_STATUS_SM0; - break; - case 1: - bitToCheck = PORT_STATUS_SM1; - break; - } - - temp = ql_read_page0_reg(qdev, &port_regs->portStatus); - return (temp & bitToCheck) != 0; -} - -static int ql_is_auto_cfg(struct ql3_adapter *qdev) -{ - u16 reg; - ql_mii_read_reg(qdev, 0x00, ®); - return (reg & 0x1000) != 0; -} - -/* - * Caller holds hw_lock. - */ -static int ql_is_auto_neg_complete(struct ql3_adapter *qdev) -{ - struct ql3xxx_port_registers __iomem *port_regs = - qdev->mem_map_registers; - u32 bitToCheck = 0; - u32 temp; - - switch (qdev->mac_index) { - case 0: - bitToCheck = PORT_STATUS_AC0; - break; - case 1: - bitToCheck = PORT_STATUS_AC1; - break; - } - - temp = ql_read_page0_reg(qdev, &port_regs->portStatus); - if (temp & bitToCheck) { - if (netif_msg_link(qdev)) - printk(KERN_INFO PFX - "%s: Auto-Negotiate complete.\n", - qdev->ndev->name); - return 1; - } else { - if (netif_msg_link(qdev)) - printk(KERN_WARNING PFX - "%s: Auto-Negotiate incomplete.\n", - qdev->ndev->name); - return 0; - } -} - -/* - * ql_is_neg_pause() returns 1 if pause was negotiated to be on - */ -static int ql_is_neg_pause(struct ql3_adapter *qdev) -{ - if (ql_is_fiber(qdev)) - return ql_is_petbi_neg_pause(qdev); - else - return ql_is_phy_neg_pause(qdev); -} - -static int ql_auto_neg_error(struct ql3_adapter *qdev) -{ - struct ql3xxx_port_registers __iomem *port_regs = - qdev->mem_map_registers; - u32 bitToCheck = 0; - u32 temp; - - switch (qdev->mac_index) { - case 0: - bitToCheck = PORT_STATUS_AE0; - break; - case 1: - bitToCheck = PORT_STATUS_AE1; - break; - } - temp = ql_read_page0_reg(qdev, &port_regs->portStatus); - return (temp & bitToCheck) != 0; -} - -static u32 ql_get_link_speed(struct ql3_adapter *qdev) -{ - if (ql_is_fiber(qdev)) - return SPEED_1000; - else - return ql_phy_get_speed(qdev); -} - -static int ql_is_link_full_dup(struct ql3_adapter *qdev) -{ - if (ql_is_fiber(qdev)) - return 1; - else - return ql_is_full_dup(qdev); -} - -/* - * Caller holds hw_lock. - */ -static int ql_link_down_detect(struct ql3_adapter *qdev) -{ - struct ql3xxx_port_registers __iomem *port_regs = - qdev->mem_map_registers; - u32 bitToCheck = 0; - u32 temp; - - switch (qdev->mac_index) { - case 0: - bitToCheck = ISP_CONTROL_LINK_DN_0; - break; - case 1: - bitToCheck = ISP_CONTROL_LINK_DN_1; - break; - } - - temp = - ql_read_common_reg(qdev, &port_regs->CommonRegs.ispControlStatus); - return (temp & bitToCheck) != 0; -} - -/* - * Caller holds hw_lock. - */ -static int ql_link_down_detect_clear(struct ql3_adapter *qdev) -{ - struct ql3xxx_port_registers __iomem *port_regs = - qdev->mem_map_registers; - - switch (qdev->mac_index) { - case 0: - ql_write_common_reg(qdev, - &port_regs->CommonRegs.ispControlStatus, - (ISP_CONTROL_LINK_DN_0) | - (ISP_CONTROL_LINK_DN_0 << 16)); - break; - - case 1: - ql_write_common_reg(qdev, - &port_regs->CommonRegs.ispControlStatus, - (ISP_CONTROL_LINK_DN_1) | - (ISP_CONTROL_LINK_DN_1 << 16)); - break; - - default: - return 1; - } - - return 0; -} - -/* - * Caller holds hw_lock. - */ -static int ql_this_adapter_controls_port(struct ql3_adapter *qdev, - u32 mac_index) -{ - struct ql3xxx_port_registers __iomem *port_regs = - qdev->mem_map_registers; - u32 bitToCheck = 0; - u32 temp; - - switch (mac_index) { - case 0: - bitToCheck = PORT_STATUS_F1_ENABLED; - break; - case 1: - bitToCheck = PORT_STATUS_F3_ENABLED; - break; - default: - break; - } - - temp = ql_read_page0_reg(qdev, &port_regs->portStatus); - if (temp & bitToCheck) { - if (netif_msg_link(qdev)) - printk(KERN_DEBUG PFX - "%s: is not link master.\n", qdev->ndev->name); - return 0; - } else { - if (netif_msg_link(qdev)) - printk(KERN_DEBUG PFX - "%s: is link master.\n", qdev->ndev->name); - return 1; - } -} - -static void ql_phy_reset_ex(struct ql3_adapter *qdev, u32 mac_index) -{ - ql_mii_write_reg_ex(qdev, CONTROL_REG, PHY_CTRL_SOFT_RESET, mac_index); -} - -static void ql_phy_start_neg_ex(struct ql3_adapter *qdev, u32 mac_index) -{ - u16 reg; - - ql_mii_write_reg_ex(qdev, PHY_NEG_ADVER, - PHY_NEG_PAUSE | PHY_NEG_ADV_SPEED | 1, mac_index); - - ql_mii_read_reg_ex(qdev, CONTROL_REG, ®, mac_index); - ql_mii_write_reg_ex(qdev, CONTROL_REG, reg | PHY_CTRL_RESTART_NEG, - mac_index); -} - -static void ql_phy_init_ex(struct ql3_adapter *qdev, u32 mac_index) -{ - ql_phy_reset_ex(qdev, mac_index); - ql_phy_start_neg_ex(qdev, mac_index); -} - -/* - * Caller holds hw_lock. - */ -static u32 ql_get_link_state(struct ql3_adapter *qdev) -{ - struct ql3xxx_port_registers __iomem *port_regs = - qdev->mem_map_registers; - u32 bitToCheck = 0; - u32 temp, linkState; - - switch (qdev->mac_index) { - case 0: - bitToCheck = PORT_STATUS_UP0; - break; - case 1: - bitToCheck = PORT_STATUS_UP1; - break; - } - temp = ql_read_page0_reg(qdev, &port_regs->portStatus); - if (temp & bitToCheck) { - linkState = LS_UP; - } else { - linkState = LS_DOWN; - if (netif_msg_link(qdev)) - printk(KERN_WARNING PFX - "%s: Link is down.\n", qdev->ndev->name); - } - return linkState; -} - -static int ql_port_start(struct ql3_adapter *qdev) -{ - if(ql_sem_spinlock(qdev, QL_PHY_GIO_SEM_MASK, - (QL_RESOURCE_BITS_BASE_CODE | (qdev->mac_index) * - 2) << 7)) - return -1; - - if (ql_is_fiber(qdev)) { - ql_petbi_init(qdev); - } else { - /* Copper port */ - ql_phy_init_ex(qdev, qdev->mac_index); - } - - ql_sem_unlock(qdev, QL_PHY_GIO_SEM_MASK); - return 0; -} - -static int ql_finish_auto_neg(struct ql3_adapter *qdev) -{ - - if(ql_sem_spinlock(qdev, QL_PHY_GIO_SEM_MASK, - (QL_RESOURCE_BITS_BASE_CODE | (qdev->mac_index) * - 2) << 7)) - return -1; - - if (!ql_auto_neg_error(qdev)) { - if (test_bit(QL_LINK_MASTER,&qdev->flags)) { - /* configure the MAC */ - if (netif_msg_link(qdev)) - printk(KERN_DEBUG PFX - "%s: Configuring link.\n", - qdev->ndev-> - name); - ql_mac_cfg_soft_reset(qdev, 1); - ql_mac_cfg_gig(qdev, - (ql_get_link_speed - (qdev) == - SPEED_1000)); - ql_mac_cfg_full_dup(qdev, - ql_is_link_full_dup - (qdev)); - ql_mac_cfg_pause(qdev, - ql_is_neg_pause - (qdev)); - ql_mac_cfg_soft_reset(qdev, 0); - - /* enable the MAC */ - if (netif_msg_link(qdev)) - printk(KERN_DEBUG PFX - "%s: Enabling mac.\n", - qdev->ndev-> - name); - ql_mac_enable(qdev, 1); - } - - if (netif_msg_link(qdev)) - printk(KERN_DEBUG PFX - "%s: Change port_link_state LS_DOWN to LS_UP.\n", - qdev->ndev->name); - qdev->port_link_state = LS_UP; - netif_start_queue(qdev->ndev); - netif_carrier_on(qdev->ndev); - if (netif_msg_link(qdev)) - printk(KERN_INFO PFX - "%s: Link is up at %d Mbps, %s duplex.\n", - qdev->ndev->name, - ql_get_link_speed(qdev), - ql_is_link_full_dup(qdev) - ? "full" : "half"); - - } else { /* Remote error detected */ - - if (test_bit(QL_LINK_MASTER,&qdev->flags)) { - if (netif_msg_link(qdev)) - printk(KERN_DEBUG PFX - "%s: Remote error detected. " - "Calling ql_port_start().\n", - qdev->ndev-> - name); - /* - * ql_port_start() is shared code and needs - * to lock the PHY on it's own. - */ - ql_sem_unlock(qdev, QL_PHY_GIO_SEM_MASK); - if(ql_port_start(qdev)) {/* Restart port */ - return -1; - } else - return 0; - } - } - ql_sem_unlock(qdev, QL_PHY_GIO_SEM_MASK); - return 0; -} - -static void ql_link_state_machine(struct ql3_adapter *qdev) -{ - u32 curr_link_state; - unsigned long hw_flags; - - spin_lock_irqsave(&qdev->hw_lock, hw_flags); - - curr_link_state = ql_get_link_state(qdev); - - if (test_bit(QL_RESET_ACTIVE,&qdev->flags)) { - if (netif_msg_link(qdev)) - printk(KERN_INFO PFX - "%s: Reset in progress, skip processing link " - "state.\n", qdev->ndev->name); - return; - } - - switch (qdev->port_link_state) { - default: - if (test_bit(QL_LINK_MASTER,&qdev->flags)) { - ql_port_start(qdev); - } - qdev->port_link_state = LS_DOWN; - /* Fall Through */ - - case LS_DOWN: - if (netif_msg_link(qdev)) - printk(KERN_DEBUG PFX - "%s: port_link_state = LS_DOWN.\n", - qdev->ndev->name); - if (curr_link_state == LS_UP) { - if (netif_msg_link(qdev)) - printk(KERN_DEBUG PFX - "%s: curr_link_state = LS_UP.\n", - qdev->ndev->name); - if (ql_is_auto_neg_complete(qdev)) - ql_finish_auto_neg(qdev); - - if (qdev->port_link_state == LS_UP) - ql_link_down_detect_clear(qdev); - - } - break; - - case LS_UP: - /* - * See if the link is currently down or went down and came - * back up - */ - if ((curr_link_state == LS_DOWN) || ql_link_down_detect(qdev)) { - if (netif_msg_link(qdev)) - printk(KERN_INFO PFX "%s: Link is down.\n", - qdev->ndev->name); - qdev->port_link_state = LS_DOWN; - } - break; - } - spin_unlock_irqrestore(&qdev->hw_lock, hw_flags); -} - -/* - * Caller must take hw_lock and QL_PHY_GIO_SEM. - */ -static void ql_get_phy_owner(struct ql3_adapter *qdev) -{ - if (ql_this_adapter_controls_port(qdev, qdev->mac_index)) - set_bit(QL_LINK_MASTER,&qdev->flags); - else - clear_bit(QL_LINK_MASTER,&qdev->flags); -} - -/* - * Caller must take hw_lock and QL_PHY_GIO_SEM. - */ -static void ql_init_scan_mode(struct ql3_adapter *qdev) -{ - ql_mii_enable_scan_mode(qdev); - - if (test_bit(QL_LINK_OPTICAL,&qdev->flags)) { - if (ql_this_adapter_controls_port(qdev, qdev->mac_index)) - ql_petbi_init_ex(qdev, qdev->mac_index); - } else { - if (ql_this_adapter_controls_port(qdev, qdev->mac_index)) - ql_phy_init_ex(qdev, qdev->mac_index); - } -} - -/* - * MII_Setup needs to be called before taking the PHY out of reset so that the - * management interface clock speed can be set properly. It would be better if - * we had a way to disable MDC until after the PHY is out of reset, but we - * don't have that capability. - */ -static int ql_mii_setup(struct ql3_adapter *qdev) -{ - u32 reg; - struct ql3xxx_port_registers __iomem *port_regs = - qdev->mem_map_registers; - - if(ql_sem_spinlock(qdev, QL_PHY_GIO_SEM_MASK, - (QL_RESOURCE_BITS_BASE_CODE | (qdev->mac_index) * - 2) << 7)) - return -1; - - /* Divide 125MHz clock by 28 to meet PHY timing requirements */ - reg = MAC_MII_CONTROL_CLK_SEL_DIV28; - - ql_write_page0_reg(qdev, &port_regs->macMIIMgmtControlReg, - reg | ((MAC_MII_CONTROL_CLK_SEL_MASK) << 16)); - - ql_sem_unlock(qdev, QL_PHY_GIO_SEM_MASK); - return 0; -} - -static u32 ql_supported_modes(struct ql3_adapter *qdev) -{ - u32 supported; - - if (test_bit(QL_LINK_OPTICAL,&qdev->flags)) { - supported = SUPPORTED_1000baseT_Full | SUPPORTED_FIBRE - | SUPPORTED_Autoneg; - } else { - supported = SUPPORTED_10baseT_Half - | SUPPORTED_10baseT_Full - | SUPPORTED_100baseT_Half - | SUPPORTED_100baseT_Full - | SUPPORTED_1000baseT_Half - | SUPPORTED_1000baseT_Full - | SUPPORTED_Autoneg | SUPPORTED_TP; - } - - return supported; -} - -static int ql_get_auto_cfg_status(struct ql3_adapter *qdev) -{ - int status; - unsigned long hw_flags; - spin_lock_irqsave(&qdev->hw_lock, hw_flags); - if(ql_sem_spinlock(qdev, QL_PHY_GIO_SEM_MASK, - (QL_RESOURCE_BITS_BASE_CODE | (qdev->mac_index) * - 2) << 7)) - return 0; - status = ql_is_auto_cfg(qdev); - ql_sem_unlock(qdev, QL_PHY_GIO_SEM_MASK); - spin_unlock_irqrestore(&qdev->hw_lock, hw_flags); - return status; -} - -static u32 ql_get_speed(struct ql3_adapter *qdev) -{ - u32 status; - unsigned long hw_flags; - spin_lock_irqsave(&qdev->hw_lock, hw_flags); - if(ql_sem_spinlock(qdev, QL_PHY_GIO_SEM_MASK, - (QL_RESOURCE_BITS_BASE_CODE | (qdev->mac_index) * - 2) << 7)) - return 0; - status = ql_get_link_speed(qdev); - ql_sem_unlock(qdev, QL_PHY_GIO_SEM_MASK); - spin_unlock_irqrestore(&qdev->hw_lock, hw_flags); - return status; -} - -static int ql_get_full_dup(struct ql3_adapter *qdev) -{ - int status; - unsigned long hw_flags; - spin_lock_irqsave(&qdev->hw_lock, hw_flags); - if(ql_sem_spinlock(qdev, QL_PHY_GIO_SEM_MASK, - (QL_RESOURCE_BITS_BASE_CODE | (qdev->mac_index) * - 2) << 7)) - return 0; - status = ql_is_link_full_dup(qdev); - ql_sem_unlock(qdev, QL_PHY_GIO_SEM_MASK); - spin_unlock_irqrestore(&qdev->hw_lock, hw_flags); - return status; -} - - -static int ql_get_settings(struct net_device *ndev, struct ethtool_cmd *ecmd) -{ - struct ql3_adapter *qdev = netdev_priv(ndev); - - ecmd->transceiver = XCVR_INTERNAL; - ecmd->supported = ql_supported_modes(qdev); - - if (test_bit(QL_LINK_OPTICAL,&qdev->flags)) { - ecmd->port = PORT_FIBRE; - } else { - ecmd->port = PORT_TP; - ecmd->phy_address = qdev->PHYAddr; - } - ecmd->advertising = ql_supported_modes(qdev); - ecmd->autoneg = ql_get_auto_cfg_status(qdev); - ecmd->speed = ql_get_speed(qdev); - ecmd->duplex = ql_get_full_dup(qdev); - return 0; -} - -static void ql_get_drvinfo(struct net_device *ndev, - struct ethtool_drvinfo *drvinfo) -{ - struct ql3_adapter *qdev = netdev_priv(ndev); - strncpy(drvinfo->driver, ql3xxx_driver_name, 32); - strncpy(drvinfo->version, ql3xxx_driver_version, 32); - strncpy(drvinfo->fw_version, "N/A", 32); - strncpy(drvinfo->bus_info, pci_name(qdev->pdev), 32); - drvinfo->n_stats = 0; - drvinfo->testinfo_len = 0; - drvinfo->regdump_len = 0; - drvinfo->eedump_len = 0; -} - -static u32 ql_get_msglevel(struct net_device *ndev) -{ - struct ql3_adapter *qdev = netdev_priv(ndev); - return qdev->msg_enable; -} - -static void ql_set_msglevel(struct net_device *ndev, u32 value) -{ - struct ql3_adapter *qdev = netdev_priv(ndev); - qdev->msg_enable = value; -} - -static struct ethtool_ops ql3xxx_ethtool_ops = { - .get_settings = ql_get_settings, - .get_drvinfo = ql_get_drvinfo, - .get_perm_addr = ethtool_op_get_perm_addr, - .get_link = ethtool_op_get_link, - .get_msglevel = ql_get_msglevel, - .set_msglevel = ql_set_msglevel, -}; - -static int ql_populate_free_queue(struct ql3_adapter *qdev) -{ - struct ql_rcv_buf_cb *lrg_buf_cb = qdev->lrg_buf_free_head; - u64 map; - - while (lrg_buf_cb) { - if (!lrg_buf_cb->skb) { - lrg_buf_cb->skb = dev_alloc_skb(qdev->lrg_buffer_len); - if (unlikely(!lrg_buf_cb->skb)) { - printk(KERN_DEBUG PFX - "%s: Failed dev_alloc_skb().\n", - qdev->ndev->name); - break; - } else { - /* - * We save some space to copy the ethhdr from - * first buffer - */ - skb_reserve(lrg_buf_cb->skb, QL_HEADER_SPACE); - map = pci_map_single(qdev->pdev, - lrg_buf_cb->skb->data, - qdev->lrg_buffer_len - - QL_HEADER_SPACE, - PCI_DMA_FROMDEVICE); - lrg_buf_cb->buf_phy_addr_low = - cpu_to_le32(LS_64BITS(map)); - lrg_buf_cb->buf_phy_addr_high = - cpu_to_le32(MS_64BITS(map)); - pci_unmap_addr_set(lrg_buf_cb, mapaddr, map); - pci_unmap_len_set(lrg_buf_cb, maplen, - qdev->lrg_buffer_len - - QL_HEADER_SPACE); - --qdev->lrg_buf_skb_check; - if (!qdev->lrg_buf_skb_check) - return 1; - } - } - lrg_buf_cb = lrg_buf_cb->next; - } - return 0; -} - -/* - * Caller holds hw_lock. - */ -static void ql_update_lrg_bufq_prod_index(struct ql3_adapter *qdev) -{ - struct bufq_addr_element *lrg_buf_q_ele; - int i; - struct ql_rcv_buf_cb *lrg_buf_cb; - struct ql3xxx_port_registers __iomem *port_regs = qdev->mem_map_registers; - - if ((qdev->lrg_buf_free_count >= 8) - && (qdev->lrg_buf_release_cnt >= 16)) { - - if (qdev->lrg_buf_skb_check) - if (!ql_populate_free_queue(qdev)) - return; - - lrg_buf_q_ele = qdev->lrg_buf_next_free; - - while ((qdev->lrg_buf_release_cnt >= 16) - && (qdev->lrg_buf_free_count >= 8)) { - - for (i = 0; i < 8; i++) { - lrg_buf_cb = - ql_get_from_lrg_buf_free_list(qdev); - lrg_buf_q_ele->addr_high = - lrg_buf_cb->buf_phy_addr_high; - lrg_buf_q_ele->addr_low = - lrg_buf_cb->buf_phy_addr_low; - lrg_buf_q_ele++; - - qdev->lrg_buf_release_cnt--; - } - - qdev->lrg_buf_q_producer_index++; - - if (qdev->lrg_buf_q_producer_index == NUM_LBUFQ_ENTRIES) - qdev->lrg_buf_q_producer_index = 0; - - if (qdev->lrg_buf_q_producer_index == - (NUM_LBUFQ_ENTRIES - 1)) { - lrg_buf_q_ele = qdev->lrg_buf_q_virt_addr; - } - } - - qdev->lrg_buf_next_free = lrg_buf_q_ele; - - ql_write_common_reg(qdev, - (u32 *) & port_regs->CommonRegs. - rxLargeQProducerIndex, - qdev->lrg_buf_q_producer_index); - } -} - -static void ql_process_mac_tx_intr(struct ql3_adapter *qdev, - struct ob_mac_iocb_rsp *mac_rsp) -{ - struct ql_tx_buf_cb *tx_cb; - - tx_cb = &qdev->tx_buf[mac_rsp->transaction_id]; - pci_unmap_single(qdev->pdev, - pci_unmap_addr(tx_cb, mapaddr), - pci_unmap_len(tx_cb, maplen), PCI_DMA_TODEVICE); - dev_kfree_skb_irq(tx_cb->skb); - qdev->stats.tx_packets++; - qdev->stats.tx_bytes += tx_cb->skb->len; - tx_cb->skb = NULL; - atomic_inc(&qdev->tx_count); -} - -static void ql_process_mac_rx_intr(struct ql3_adapter *qdev, - struct ib_mac_iocb_rsp *ib_mac_rsp_ptr) -{ - long int offset; - u32 lrg_buf_phy_addr_low = 0; - struct ql_rcv_buf_cb *lrg_buf_cb1 = NULL; - struct ql_rcv_buf_cb *lrg_buf_cb2 = NULL; - u32 *curr_ial_ptr; - struct sk_buff *skb; - u16 length = le16_to_cpu(ib_mac_rsp_ptr->length); - - /* - * Get the inbound address list (small buffer). - */ - offset = qdev->small_buf_index * QL_SMALL_BUFFER_SIZE; - if (++qdev->small_buf_index == NUM_SMALL_BUFFERS) - qdev->small_buf_index = 0; - - curr_ial_ptr = (u32 *) (qdev->small_buf_virt_addr + offset); - qdev->last_rsp_offset = qdev->small_buf_phy_addr_low + offset; - qdev->small_buf_release_cnt++; - - /* start of first buffer */ - lrg_buf_phy_addr_low = le32_to_cpu(*curr_ial_ptr); - lrg_buf_cb1 = &qdev->lrg_buf[qdev->lrg_buf_index]; - qdev->lrg_buf_release_cnt++; - if (++qdev->lrg_buf_index == NUM_LARGE_BUFFERS) - qdev->lrg_buf_index = 0; - curr_ial_ptr++; /* 64-bit pointers require two incs. */ - curr_ial_ptr++; - - /* start of second buffer */ - lrg_buf_phy_addr_low = le32_to_cpu(*curr_ial_ptr); - lrg_buf_cb2 = &qdev->lrg_buf[qdev->lrg_buf_index]; - - /* - * Second buffer gets sent up the stack. - */ - qdev->lrg_buf_release_cnt++; - if (++qdev->lrg_buf_index == NUM_LARGE_BUFFERS) - qdev->lrg_buf_index = 0; - skb = lrg_buf_cb2->skb; - - qdev->stats.rx_packets++; - qdev->stats.rx_bytes += length; - - skb_put(skb, length); - pci_unmap_single(qdev->pdev, - pci_unmap_addr(lrg_buf_cb2, mapaddr), - pci_unmap_len(lrg_buf_cb2, maplen), - PCI_DMA_FROMDEVICE); - prefetch(skb->data); - skb->dev = qdev->ndev; - skb->ip_summed = CHECKSUM_NONE; - skb->protocol = eth_type_trans(skb, qdev->ndev); - - netif_receive_skb(skb); - qdev->ndev->last_rx = jiffies; - lrg_buf_cb2->skb = NULL; - - ql_release_to_lrg_buf_free_list(qdev, lrg_buf_cb1); - ql_release_to_lrg_buf_free_list(qdev, lrg_buf_cb2); -} - -static void ql_process_macip_rx_intr(struct ql3_adapter *qdev, - struct ib_ip_iocb_rsp *ib_ip_rsp_ptr) -{ - long int offset; - u32 lrg_buf_phy_addr_low = 0; - struct ql_rcv_buf_cb *lrg_buf_cb1 = NULL; - struct ql_rcv_buf_cb *lrg_buf_cb2 = NULL; - u32 *curr_ial_ptr; - struct sk_buff *skb1, *skb2; - struct net_device *ndev = qdev->ndev; - u16 length = le16_to_cpu(ib_ip_rsp_ptr->length); - u16 size = 0; - - /* - * Get the inbound address list (small buffer). - */ - - offset = qdev->small_buf_index * QL_SMALL_BUFFER_SIZE; - if (++qdev->small_buf_index == NUM_SMALL_BUFFERS) - qdev->small_buf_index = 0; - curr_ial_ptr = (u32 *) (qdev->small_buf_virt_addr + offset); - qdev->last_rsp_offset = qdev->small_buf_phy_addr_low + offset; - qdev->small_buf_release_cnt++; - - /* start of first buffer */ - lrg_buf_phy_addr_low = le32_to_cpu(*curr_ial_ptr); - lrg_buf_cb1 = &qdev->lrg_buf[qdev->lrg_buf_index]; - - qdev->lrg_buf_release_cnt++; - if (++qdev->lrg_buf_index == NUM_LARGE_BUFFERS) - qdev->lrg_buf_index = 0; - skb1 = lrg_buf_cb1->skb; - curr_ial_ptr++; /* 64-bit pointers require two incs. */ - curr_ial_ptr++; - - /* start of second buffer */ - lrg_buf_phy_addr_low = le32_to_cpu(*curr_ial_ptr); - lrg_buf_cb2 = &qdev->lrg_buf[qdev->lrg_buf_index]; - skb2 = lrg_buf_cb2->skb; - qdev->lrg_buf_release_cnt++; - if (++qdev->lrg_buf_index == NUM_LARGE_BUFFERS) - qdev->lrg_buf_index = 0; - - qdev->stats.rx_packets++; - qdev->stats.rx_bytes += length; - - /* - * Copy the ethhdr from first buffer to second. This - * is necessary for IP completions. - */ - if (*((u16 *) skb1->data) != 0xFFFF) - size = VLAN_ETH_HLEN; - else - size = ETH_HLEN; - - skb_put(skb2, length); /* Just the second buffer length here. */ - pci_unmap_single(qdev->pdev, - pci_unmap_addr(lrg_buf_cb2, mapaddr), - pci_unmap_len(lrg_buf_cb2, maplen), - PCI_DMA_FROMDEVICE); - prefetch(skb2->data); - - memcpy(skb_push(skb2, size), skb1->data + VLAN_ID_LEN, size); - skb2->dev = qdev->ndev; - skb2->ip_summed = CHECKSUM_NONE; - skb2->protocol = eth_type_trans(skb2, qdev->ndev); - - netif_receive_skb(skb2); - ndev->last_rx = jiffies; - lrg_buf_cb2->skb = NULL; - - ql_release_to_lrg_buf_free_list(qdev, lrg_buf_cb1); - ql_release_to_lrg_buf_free_list(qdev, lrg_buf_cb2); -} - -static int ql_tx_rx_clean(struct ql3_adapter *qdev, - int *tx_cleaned, int *rx_cleaned, int work_to_do) -{ - struct ql3xxx_port_registers __iomem *port_regs = qdev->mem_map_registers; - struct net_rsp_iocb *net_rsp; - struct net_device *ndev = qdev->ndev; - unsigned long hw_flags; - - /* While there are entries in the completion queue. */ - while ((cpu_to_le32(*(qdev->prsp_producer_index)) != - qdev->rsp_consumer_index) && (*rx_cleaned < work_to_do)) { - - net_rsp = qdev->rsp_current; - switch (net_rsp->opcode) { - - case OPCODE_OB_MAC_IOCB_FN0: - case OPCODE_OB_MAC_IOCB_FN2: - ql_process_mac_tx_intr(qdev, (struct ob_mac_iocb_rsp *) - net_rsp); - (*tx_cleaned)++; - break; - - case OPCODE_IB_MAC_IOCB: - ql_process_mac_rx_intr(qdev, (struct ib_mac_iocb_rsp *) - net_rsp); - (*rx_cleaned)++; - break; - - case OPCODE_IB_IP_IOCB: - ql_process_macip_rx_intr(qdev, (struct ib_ip_iocb_rsp *) - net_rsp); - (*rx_cleaned)++; - break; - default: - { - u32 *tmp = (u32 *) net_rsp; - printk(KERN_ERR PFX - "%s: Hit default case, not " - "handled!\n" - " dropping the packet, opcode = " - "%x.\n", - ndev->name, net_rsp->opcode); - printk(KERN_ERR PFX - "0x%08lx 0x%08lx 0x%08lx 0x%08lx \n", - (unsigned long int)tmp[0], - (unsigned long int)tmp[1], - (unsigned long int)tmp[2], - (unsigned long int)tmp[3]); - } - } - - qdev->rsp_consumer_index++; - - if (qdev->rsp_consumer_index == NUM_RSP_Q_ENTRIES) { - qdev->rsp_consumer_index = 0; - qdev->rsp_current = qdev->rsp_q_virt_addr; - } else { - qdev->rsp_current++; - } - } - - spin_lock_irqsave(&qdev->hw_lock, hw_flags); - - ql_update_lrg_bufq_prod_index(qdev); - - if (qdev->small_buf_release_cnt >= 16) { - while (qdev->small_buf_release_cnt >= 16) { - qdev->small_buf_q_producer_index++; - - if (qdev->small_buf_q_producer_index == - NUM_SBUFQ_ENTRIES) - qdev->small_buf_q_producer_index = 0; - qdev->small_buf_release_cnt -= 8; - } - - ql_write_common_reg(qdev, - (u32 *) & port_regs->CommonRegs. - rxSmallQProducerIndex, - qdev->small_buf_q_producer_index); - } - - ql_write_common_reg(qdev, - (u32 *) & port_regs->CommonRegs.rspQConsumerIndex, - qdev->rsp_consumer_index); - spin_unlock_irqrestore(&qdev->hw_lock, hw_flags); - - if (unlikely(netif_queue_stopped(qdev->ndev))) { - if (netif_queue_stopped(qdev->ndev) && - (atomic_read(&qdev->tx_count) > (NUM_REQ_Q_ENTRIES / 4))) - netif_wake_queue(qdev->ndev); - } - - return *tx_cleaned + *rx_cleaned; -} - -static int ql_poll(struct net_device *ndev, int *budget) -{ - struct ql3_adapter *qdev = netdev_priv(ndev); - int work_to_do = min(*budget, ndev->quota); - int rx_cleaned = 0, tx_cleaned = 0; - - if (!netif_carrier_ok(ndev)) - goto quit_polling; - - ql_tx_rx_clean(qdev, &tx_cleaned, &rx_cleaned, work_to_do); - *budget -= rx_cleaned; - ndev->quota -= rx_cleaned; - - if ((!tx_cleaned && !rx_cleaned) || !netif_running(ndev)) { -quit_polling: - netif_rx_complete(ndev); - ql_enable_interrupts(qdev); - return 0; - } - return 1; -} - -static irqreturn_t ql3xxx_isr(int irq, void *dev_id, struct pt_regs *regs) -{ - - struct net_device *ndev = dev_id; - struct ql3_adapter *qdev = netdev_priv(ndev); - struct ql3xxx_port_registers __iomem *port_regs = qdev->mem_map_registers; - u32 value; - int handled = 1; - u32 var; - - port_regs = qdev->mem_map_registers; - - value = - ql_read_common_reg_l(qdev, &port_regs->CommonRegs.ispControlStatus); - - if (value & (ISP_CONTROL_FE | ISP_CONTROL_RI)) { - spin_lock(&qdev->adapter_lock); - netif_stop_queue(qdev->ndev); - netif_carrier_off(qdev->ndev); - ql_disable_interrupts(qdev); - qdev->port_link_state = LS_DOWN; - set_bit(QL_RESET_ACTIVE,&qdev->flags) ; - - if (value & ISP_CONTROL_FE) { - /* - * Chip Fatal Error. - */ - var = - ql_read_page0_reg_l(qdev, - &port_regs->PortFatalErrStatus); - printk(KERN_WARNING PFX - "%s: Resetting chip. PortFatalErrStatus " - "register = 0x%x\n", ndev->name, var); - set_bit(QL_RESET_START,&qdev->flags) ; - } else { - /* - * Soft Reset Requested. - */ - set_bit(QL_RESET_PER_SCSI,&qdev->flags) ; - printk(KERN_ERR PFX - "%s: Another function issued a reset to the " - "chip. ISR value = %x.\n", ndev->name, value); - } - queue_work(qdev->workqueue, &qdev->reset_work); - spin_unlock(&qdev->adapter_lock); - } else if (value & ISP_IMR_DISABLE_CMPL_INT) { - ql_disable_interrupts(qdev); - if (likely(netif_rx_schedule_prep(ndev))) - __netif_rx_schedule(ndev); - else - ql_enable_interrupts(qdev); - } else { - return IRQ_NONE; - } - - return IRQ_RETVAL(handled); -} - -static int ql3xxx_send(struct sk_buff *skb, struct net_device *ndev) -{ - struct ql3_adapter *qdev = (struct ql3_adapter *)netdev_priv(ndev); - struct ql3xxx_port_registers __iomem *port_regs = qdev->mem_map_registers; - struct ql_tx_buf_cb *tx_cb; - struct ob_mac_iocb_req *mac_iocb_ptr; - u64 map; - - if (unlikely(atomic_read(&qdev->tx_count) < 2)) { - if (!netif_queue_stopped(ndev)) - netif_stop_queue(ndev); - return NETDEV_TX_BUSY; - } - tx_cb = &qdev->tx_buf[qdev->req_producer_index] ; - mac_iocb_ptr = tx_cb->queue_entry; - memset((void *)mac_iocb_ptr, 0, sizeof(struct ob_mac_iocb_req)); - mac_iocb_ptr->opcode = qdev->mac_ob_opcode; - mac_iocb_ptr->flags |= qdev->mb_bit_mask; - mac_iocb_ptr->transaction_id = qdev->req_producer_index; - mac_iocb_ptr->data_len = cpu_to_le16((u16) skb->len); - tx_cb->skb = skb; - map = pci_map_single(qdev->pdev, skb->data, skb->len, PCI_DMA_TODEVICE); - mac_iocb_ptr->buf_addr0_low = cpu_to_le32(LS_64BITS(map)); - mac_iocb_ptr->buf_addr0_high = cpu_to_le32(MS_64BITS(map)); - mac_iocb_ptr->buf_0_len = cpu_to_le32(skb->len | OB_MAC_IOCB_REQ_E); - pci_unmap_addr_set(tx_cb, mapaddr, map); - pci_unmap_len_set(tx_cb, maplen, skb->len); - atomic_dec(&qdev->tx_count); - - qdev->req_producer_index++; - if (qdev->req_producer_index == NUM_REQ_Q_ENTRIES) - qdev->req_producer_index = 0; - wmb(); - ql_write_common_reg_l(qdev, - (u32 *) & port_regs->CommonRegs.reqQProducerIndex, - qdev->req_producer_index); - - ndev->trans_start = jiffies; - if (netif_msg_tx_queued(qdev)) - printk(KERN_DEBUG PFX "%s: tx queued, slot %d, len %d\n", - ndev->name, qdev->req_producer_index, skb->len); - - return NETDEV_TX_OK; -} -static int ql_alloc_net_req_rsp_queues(struct ql3_adapter *qdev) -{ - qdev->req_q_size = - (u32) (NUM_REQ_Q_ENTRIES * sizeof(struct ob_mac_iocb_req)); - - qdev->req_q_virt_addr = - pci_alloc_consistent(qdev->pdev, - (size_t) qdev->req_q_size, - &qdev->req_q_phy_addr); - - if ((qdev->req_q_virt_addr == NULL) || - LS_64BITS(qdev->req_q_phy_addr) & (qdev->req_q_size - 1)) { - printk(KERN_ERR PFX "%s: reqQ failed.\n", - qdev->ndev->name); - return -ENOMEM; - } - - qdev->rsp_q_size = NUM_RSP_Q_ENTRIES * sizeof(struct net_rsp_iocb); - - qdev->rsp_q_virt_addr = - pci_alloc_consistent(qdev->pdev, - (size_t) qdev->rsp_q_size, - &qdev->rsp_q_phy_addr); - - if ((qdev->rsp_q_virt_addr == NULL) || - LS_64BITS(qdev->rsp_q_phy_addr) & (qdev->rsp_q_size - 1)) { - printk(KERN_ERR PFX - "%s: rspQ allocation failed\n", - qdev->ndev->name); - pci_free_consistent(qdev->pdev, (size_t) qdev->req_q_size, - qdev->req_q_virt_addr, - qdev->req_q_phy_addr); - return -ENOMEM; - } - - set_bit(QL_ALLOC_REQ_RSP_Q_DONE,&qdev->flags); - - return 0; -} - -static void ql_free_net_req_rsp_queues(struct ql3_adapter *qdev) -{ - if (!test_bit(QL_ALLOC_REQ_RSP_Q_DONE,&qdev->flags)) { - printk(KERN_INFO PFX - "%s: Already done.\n", qdev->ndev->name); - return; - } - - pci_free_consistent(qdev->pdev, - qdev->req_q_size, - qdev->req_q_virt_addr, qdev->req_q_phy_addr); - - qdev->req_q_virt_addr = NULL; - - pci_free_consistent(qdev->pdev, - qdev->rsp_q_size, - qdev->rsp_q_virt_addr, qdev->rsp_q_phy_addr); - - qdev->rsp_q_virt_addr = NULL; - - clear_bit(QL_ALLOC_REQ_RSP_Q_DONE,&qdev->flags); -} - -static int ql_alloc_buffer_queues(struct ql3_adapter *qdev) -{ - /* Create Large Buffer Queue */ - qdev->lrg_buf_q_size = - NUM_LBUFQ_ENTRIES * sizeof(struct lrg_buf_q_entry); - if (qdev->lrg_buf_q_size < PAGE_SIZE) - qdev->lrg_buf_q_alloc_size = PAGE_SIZE; - else - qdev->lrg_buf_q_alloc_size = qdev->lrg_buf_q_size * 2; - - qdev->lrg_buf_q_alloc_virt_addr = - pci_alloc_consistent(qdev->pdev, - qdev->lrg_buf_q_alloc_size, - &qdev->lrg_buf_q_alloc_phy_addr); - - if (qdev->lrg_buf_q_alloc_virt_addr == NULL) { - printk(KERN_ERR PFX - "%s: lBufQ failed\n", qdev->ndev->name); - return -ENOMEM; - } - qdev->lrg_buf_q_virt_addr = qdev->lrg_buf_q_alloc_virt_addr; - qdev->lrg_buf_q_phy_addr = qdev->lrg_buf_q_alloc_phy_addr; - - /* Create Small Buffer Queue */ - qdev->small_buf_q_size = - NUM_SBUFQ_ENTRIES * sizeof(struct lrg_buf_q_entry); - if (qdev->small_buf_q_size < PAGE_SIZE) - qdev->small_buf_q_alloc_size = PAGE_SIZE; - else - qdev->small_buf_q_alloc_size = qdev->small_buf_q_size * 2; - - qdev->small_buf_q_alloc_virt_addr = - pci_alloc_consistent(qdev->pdev, - qdev->small_buf_q_alloc_size, - &qdev->small_buf_q_alloc_phy_addr); - - if (qdev->small_buf_q_alloc_virt_addr == NULL) { - printk(KERN_ERR PFX - "%s: Small Buffer Queue allocation failed.\n", - qdev->ndev->name); - pci_free_consistent(qdev->pdev, qdev->lrg_buf_q_alloc_size, - qdev->lrg_buf_q_alloc_virt_addr, - qdev->lrg_buf_q_alloc_phy_addr); - return -ENOMEM; - } - - qdev->small_buf_q_virt_addr = qdev->small_buf_q_alloc_virt_addr; - qdev->small_buf_q_phy_addr = qdev->small_buf_q_alloc_phy_addr; - set_bit(QL_ALLOC_BUFQS_DONE,&qdev->flags); - return 0; -} - -static void ql_free_buffer_queues(struct ql3_adapter *qdev) -{ - if (!test_bit(QL_ALLOC_BUFQS_DONE,&qdev->flags)) { - printk(KERN_INFO PFX - "%s: Already done.\n", qdev->ndev->name); - return; - } - - pci_free_consistent(qdev->pdev, - qdev->lrg_buf_q_alloc_size, - qdev->lrg_buf_q_alloc_virt_addr, - qdev->lrg_buf_q_alloc_phy_addr); - - qdev->lrg_buf_q_virt_addr = NULL; - - pci_free_consistent(qdev->pdev, - qdev->small_buf_q_alloc_size, - qdev->small_buf_q_alloc_virt_addr, - qdev->small_buf_q_alloc_phy_addr); - - qdev->small_buf_q_virt_addr = NULL; - - clear_bit(QL_ALLOC_BUFQS_DONE,&qdev->flags); -} - -static int ql_alloc_small_buffers(struct ql3_adapter *qdev) -{ - int i; - struct bufq_addr_element *small_buf_q_entry; - - /* Currently we allocate on one of memory and use it for smallbuffers */ - qdev->small_buf_total_size = - (QL_ADDR_ELE_PER_BUFQ_ENTRY * NUM_SBUFQ_ENTRIES * - QL_SMALL_BUFFER_SIZE); - - qdev->small_buf_virt_addr = - pci_alloc_consistent(qdev->pdev, - qdev->small_buf_total_size, - &qdev->small_buf_phy_addr); - - if (qdev->small_buf_virt_addr == NULL) { - printk(KERN_ERR PFX - "%s: Failed to get small buffer memory.\n", - qdev->ndev->name); - return -ENOMEM; - } - - qdev->small_buf_phy_addr_low = LS_64BITS(qdev->small_buf_phy_addr); - qdev->small_buf_phy_addr_high = MS_64BITS(qdev->small_buf_phy_addr); - - small_buf_q_entry = qdev->small_buf_q_virt_addr; - - qdev->last_rsp_offset = qdev->small_buf_phy_addr_low; - - /* Initialize the small buffer queue. */ - for (i = 0; i < (QL_ADDR_ELE_PER_BUFQ_ENTRY * NUM_SBUFQ_ENTRIES); i++) { - small_buf_q_entry->addr_high = - cpu_to_le32(qdev->small_buf_phy_addr_high); - small_buf_q_entry->addr_low = - cpu_to_le32(qdev->small_buf_phy_addr_low + - (i * QL_SMALL_BUFFER_SIZE)); - small_buf_q_entry++; - } - qdev->small_buf_index = 0; - set_bit(QL_ALLOC_SMALL_BUF_DONE,&qdev->flags); - return 0; -} - -static void ql_free_small_buffers(struct ql3_adapter *qdev) -{ - if (!test_bit(QL_ALLOC_SMALL_BUF_DONE,&qdev->flags)) { - printk(KERN_INFO PFX - "%s: Already done.\n", qdev->ndev->name); - return; - } - if (qdev->small_buf_virt_addr != NULL) { - pci_free_consistent(qdev->pdev, - qdev->small_buf_total_size, - qdev->small_buf_virt_addr, - qdev->small_buf_phy_addr); - - qdev->small_buf_virt_addr = NULL; - } -} - -static void ql_free_large_buffers(struct ql3_adapter *qdev) -{ - int i = 0; - struct ql_rcv_buf_cb *lrg_buf_cb; - - for (i = 0; i < NUM_LARGE_BUFFERS; i++) { - lrg_buf_cb = &qdev->lrg_buf[i]; - if (lrg_buf_cb->skb) { - dev_kfree_skb(lrg_buf_cb->skb); - pci_unmap_single(qdev->pdev, - pci_unmap_addr(lrg_buf_cb, mapaddr), - pci_unmap_len(lrg_buf_cb, maplen), - PCI_DMA_FROMDEVICE); - memset(lrg_buf_cb, 0, sizeof(struct ql_rcv_buf_cb)); - } else { - break; - } - } -} - -static void ql_init_large_buffers(struct ql3_adapter *qdev) -{ - int i; - struct ql_rcv_buf_cb *lrg_buf_cb; - struct bufq_addr_element *buf_addr_ele = qdev->lrg_buf_q_virt_addr; - - for (i = 0; i < NUM_LARGE_BUFFERS; i++) { - lrg_buf_cb = &qdev->lrg_buf[i]; - buf_addr_ele->addr_high = lrg_buf_cb->buf_phy_addr_high; - buf_addr_ele->addr_low = lrg_buf_cb->buf_phy_addr_low; - buf_addr_ele++; - } - qdev->lrg_buf_index = 0; - qdev->lrg_buf_skb_check = 0; -} - -static int ql_alloc_large_buffers(struct ql3_adapter *qdev) -{ - int i; - struct ql_rcv_buf_cb *lrg_buf_cb; - struct sk_buff *skb; - u64 map; - - for (i = 0; i < NUM_LARGE_BUFFERS; i++) { - skb = dev_alloc_skb(qdev->lrg_buffer_len); - if (unlikely(!skb)) { - /* Better luck next round */ - printk(KERN_ERR PFX - "%s: large buff alloc failed, " - "for %d bytes at index %d.\n", - qdev->ndev->name, - qdev->lrg_buffer_len * 2, i); - ql_free_large_buffers(qdev); - return -ENOMEM; - } else { - - lrg_buf_cb = &qdev->lrg_buf[i]; - memset(lrg_buf_cb, 0, sizeof(struct ql_rcv_buf_cb)); - lrg_buf_cb->index = i; - lrg_buf_cb->skb = skb; - /* - * We save some space to copy the ethhdr from first - * buffer - */ - skb_reserve(skb, QL_HEADER_SPACE); - map = pci_map_single(qdev->pdev, - skb->data, - qdev->lrg_buffer_len - - QL_HEADER_SPACE, - PCI_DMA_FROMDEVICE); - pci_unmap_addr_set(lrg_buf_cb, mapaddr, map); - pci_unmap_len_set(lrg_buf_cb, maplen, - qdev->lrg_buffer_len - - QL_HEADER_SPACE); - lrg_buf_cb->buf_phy_addr_low = - cpu_to_le32(LS_64BITS(map)); - lrg_buf_cb->buf_phy_addr_high = - cpu_to_le32(MS_64BITS(map)); - } - } - return 0; -} - -static void ql_create_send_free_list(struct ql3_adapter *qdev) -{ - struct ql_tx_buf_cb *tx_cb; - int i; - struct ob_mac_iocb_req *req_q_curr = - qdev->req_q_virt_addr; - - /* Create free list of transmit buffers */ - for (i = 0; i < NUM_REQ_Q_ENTRIES; i++) { - tx_cb = &qdev->tx_buf[i]; - tx_cb->skb = NULL; - tx_cb->queue_entry = req_q_curr; - req_q_curr++; - } -} - -static int ql_alloc_mem_resources(struct ql3_adapter *qdev) -{ - if (qdev->ndev->mtu == NORMAL_MTU_SIZE) - qdev->lrg_buffer_len = NORMAL_MTU_SIZE; - else if (qdev->ndev->mtu == JUMBO_MTU_SIZE) { - qdev->lrg_buffer_len = JUMBO_MTU_SIZE; - } else { - printk(KERN_ERR PFX - "%s: Invalid mtu size. Only 1500 and 9000 are accepted.\n", - qdev->ndev->name); - return -ENOMEM; - } - qdev->lrg_buffer_len += VLAN_ETH_HLEN + VLAN_ID_LEN + QL_HEADER_SPACE; - qdev->max_frame_size = - (qdev->lrg_buffer_len - QL_HEADER_SPACE) + ETHERNET_CRC_SIZE; - - /* - * First allocate a page of shared memory and use it for shadow - * locations of Network Request Queue Consumer Address Register and - * Network Completion Queue Producer Index Register - */ - qdev->shadow_reg_virt_addr = - pci_alloc_consistent(qdev->pdev, - PAGE_SIZE, &qdev->shadow_reg_phy_addr); - - if (qdev->shadow_reg_virt_addr != NULL) { - qdev->preq_consumer_index = (u16 *) qdev->shadow_reg_virt_addr; - qdev->req_consumer_index_phy_addr_high = - MS_64BITS(qdev->shadow_reg_phy_addr); - qdev->req_consumer_index_phy_addr_low = - LS_64BITS(qdev->shadow_reg_phy_addr); - - qdev->prsp_producer_index = - (u32 *) (((u8 *) qdev->preq_consumer_index) + 8); - qdev->rsp_producer_index_phy_addr_high = - qdev->req_consumer_index_phy_addr_high; - qdev->rsp_producer_index_phy_addr_low = - qdev->req_consumer_index_phy_addr_low + 8; - } else { - printk(KERN_ERR PFX - "%s: shadowReg Alloc failed.\n", qdev->ndev->name); - return -ENOMEM; - } - - if (ql_alloc_net_req_rsp_queues(qdev) != 0) { - printk(KERN_ERR PFX - "%s: ql_alloc_net_req_rsp_queues failed.\n", - qdev->ndev->name); - goto err_req_rsp; - } - - if (ql_alloc_buffer_queues(qdev) != 0) { - printk(KERN_ERR PFX - "%s: ql_alloc_buffer_queues failed.\n", - qdev->ndev->name); - goto err_buffer_queues; - } - - if (ql_alloc_small_buffers(qdev) != 0) { - printk(KERN_ERR PFX - "%s: ql_alloc_small_buffers failed\n", qdev->ndev->name); - goto err_small_buffers; - } - - if (ql_alloc_large_buffers(qdev) != 0) { - printk(KERN_ERR PFX - "%s: ql_alloc_large_buffers failed\n", qdev->ndev->name); - goto err_small_buffers; - } - - /* Initialize the large buffer queue. */ - ql_init_large_buffers(qdev); - ql_create_send_free_list(qdev); - - qdev->rsp_current = qdev->rsp_q_virt_addr; - - return 0; - -err_small_buffers: - ql_free_buffer_queues(qdev); -err_buffer_queues: - ql_free_net_req_rsp_queues(qdev); -err_req_rsp: - pci_free_consistent(qdev->pdev, - PAGE_SIZE, - qdev->shadow_reg_virt_addr, - qdev->shadow_reg_phy_addr); - - return -ENOMEM; -} - -static void ql_free_mem_resources(struct ql3_adapter *qdev) -{ - ql_free_large_buffers(qdev); - ql_free_small_buffers(qdev); - ql_free_buffer_queues(qdev); - ql_free_net_req_rsp_queues(qdev); - if (qdev->shadow_reg_virt_addr != NULL) { - pci_free_consistent(qdev->pdev, - PAGE_SIZE, - qdev->shadow_reg_virt_addr, - qdev->shadow_reg_phy_addr); - qdev->shadow_reg_virt_addr = NULL; - } -} - -static int ql_init_misc_registers(struct ql3_adapter *qdev) -{ - struct ql3xxx_local_ram_registers *local_ram = - (struct ql3xxx_local_ram_registers *)qdev->mem_map_registers; - - if(ql_sem_spinlock(qdev, QL_DDR_RAM_SEM_MASK, - (QL_RESOURCE_BITS_BASE_CODE | (qdev->mac_index) * - 2) << 4)) - return -1; - - ql_write_page2_reg(qdev, - &local_ram->bufletSize, qdev->nvram_data.bufletSize); - - ql_write_page2_reg(qdev, - &local_ram->maxBufletCount, - qdev->nvram_data.bufletCount); - - ql_write_page2_reg(qdev, - &local_ram->freeBufletThresholdLow, - (qdev->nvram_data.tcpWindowThreshold25 << 16) | - (qdev->nvram_data.tcpWindowThreshold0)); - - ql_write_page2_reg(qdev, - &local_ram->freeBufletThresholdHigh, - qdev->nvram_data.tcpWindowThreshold50); - - ql_write_page2_reg(qdev, - &local_ram->ipHashTableBase, - (qdev->nvram_data.ipHashTableBaseHi << 16) | - qdev->nvram_data.ipHashTableBaseLo); - ql_write_page2_reg(qdev, - &local_ram->ipHashTableCount, - qdev->nvram_data.ipHashTableSize); - ql_write_page2_reg(qdev, - &local_ram->tcpHashTableBase, - (qdev->nvram_data.tcpHashTableBaseHi << 16) | - qdev->nvram_data.tcpHashTableBaseLo); - ql_write_page2_reg(qdev, - &local_ram->tcpHashTableCount, - qdev->nvram_data.tcpHashTableSize); - ql_write_page2_reg(qdev, - &local_ram->ncbBase, - (qdev->nvram_data.ncbTableBaseHi << 16) | - qdev->nvram_data.ncbTableBaseLo); - ql_write_page2_reg(qdev, - &local_ram->maxNcbCount, - qdev->nvram_data.ncbTableSize); - ql_write_page2_reg(qdev, - &local_ram->drbBase, - (qdev->nvram_data.drbTableBaseHi << 16) | - qdev->nvram_data.drbTableBaseLo); - ql_write_page2_reg(qdev, - &local_ram->maxDrbCount, - qdev->nvram_data.drbTableSize); - ql_sem_unlock(qdev, QL_DDR_RAM_SEM_MASK); - return 0; -} - -static int ql_adapter_initialize(struct ql3_adapter *qdev) -{ - u32 value; - struct ql3xxx_port_registers __iomem *port_regs = qdev->mem_map_registers; - struct ql3xxx_host_memory_registers __iomem *hmem_regs = - (struct ql3xxx_host_memory_registers *)port_regs; - u32 delay = 10; - int status = 0; - - if(ql_mii_setup(qdev)) - return -1; - - /* Bring out PHY out of reset */ - ql_write_common_reg(qdev, &port_regs->CommonRegs.serialPortInterfaceReg, - (ISP_SERIAL_PORT_IF_WE | - (ISP_SERIAL_PORT_IF_WE << 16))); - - qdev->port_link_state = LS_DOWN; - netif_carrier_off(qdev->ndev); - - /* V2 chip fix for ARS-39168. */ - ql_write_common_reg(qdev, &port_regs->CommonRegs.serialPortInterfaceReg, - (ISP_SERIAL_PORT_IF_SDE | - (ISP_SERIAL_PORT_IF_SDE << 16))); - - /* Request Queue Registers */ - *((u32 *) (qdev->preq_consumer_index)) = 0; - atomic_set(&qdev->tx_count,NUM_REQ_Q_ENTRIES); - qdev->req_producer_index = 0; - - ql_write_page1_reg(qdev, - &hmem_regs->reqConsumerIndexAddrHigh, - qdev->req_consumer_index_phy_addr_high); - ql_write_page1_reg(qdev, - &hmem_regs->reqConsumerIndexAddrLow, - qdev->req_consumer_index_phy_addr_low); - - ql_write_page1_reg(qdev, - &hmem_regs->reqBaseAddrHigh, - MS_64BITS(qdev->req_q_phy_addr)); - ql_write_page1_reg(qdev, - &hmem_regs->reqBaseAddrLow, - LS_64BITS(qdev->req_q_phy_addr)); - ql_write_page1_reg(qdev, &hmem_regs->reqLength, NUM_REQ_Q_ENTRIES); - - /* Response Queue Registers */ - *((u16 *) (qdev->prsp_producer_index)) = 0; - qdev->rsp_consumer_index = 0; - qdev->rsp_current = qdev->rsp_q_virt_addr; - - ql_write_page1_reg(qdev, - &hmem_regs->rspProducerIndexAddrHigh, - qdev->rsp_producer_index_phy_addr_high); - - ql_write_page1_reg(qdev, - &hmem_regs->rspProducerIndexAddrLow, - qdev->rsp_producer_index_phy_addr_low); - - ql_write_page1_reg(qdev, - &hmem_regs->rspBaseAddrHigh, - MS_64BITS(qdev->rsp_q_phy_addr)); - - ql_write_page1_reg(qdev, - &hmem_regs->rspBaseAddrLow, - LS_64BITS(qdev->rsp_q_phy_addr)); - - ql_write_page1_reg(qdev, &hmem_regs->rspLength, NUM_RSP_Q_ENTRIES); - - /* Large Buffer Queue */ - ql_write_page1_reg(qdev, - &hmem_regs->rxLargeQBaseAddrHigh, - MS_64BITS(qdev->lrg_buf_q_phy_addr)); - - ql_write_page1_reg(qdev, - &hmem_regs->rxLargeQBaseAddrLow, - LS_64BITS(qdev->lrg_buf_q_phy_addr)); - - ql_write_page1_reg(qdev, &hmem_regs->rxLargeQLength, NUM_LBUFQ_ENTRIES); - - ql_write_page1_reg(qdev, - &hmem_regs->rxLargeBufferLength, - qdev->lrg_buffer_len); - - /* Small Buffer Queue */ - ql_write_page1_reg(qdev, - &hmem_regs->rxSmallQBaseAddrHigh, - MS_64BITS(qdev->small_buf_q_phy_addr)); - - ql_write_page1_reg(qdev, - &hmem_regs->rxSmallQBaseAddrLow, - LS_64BITS(qdev->small_buf_q_phy_addr)); - - ql_write_page1_reg(qdev, &hmem_regs->rxSmallQLength, NUM_SBUFQ_ENTRIES); - ql_write_page1_reg(qdev, - &hmem_regs->rxSmallBufferLength, - QL_SMALL_BUFFER_SIZE); - - qdev->small_buf_q_producer_index = NUM_SBUFQ_ENTRIES - 1; - qdev->small_buf_release_cnt = 8; - qdev->lrg_buf_q_producer_index = NUM_LBUFQ_ENTRIES - 1; - qdev->lrg_buf_release_cnt = 8; - qdev->lrg_buf_next_free = - (struct bufq_addr_element *)qdev->lrg_buf_q_virt_addr; - qdev->small_buf_index = 0; - qdev->lrg_buf_index = 0; - qdev->lrg_buf_free_count = 0; - qdev->lrg_buf_free_head = NULL; - qdev->lrg_buf_free_tail = NULL; - - ql_write_common_reg(qdev, - (u32 *) & port_regs->CommonRegs. - rxSmallQProducerIndex, - qdev->small_buf_q_producer_index); - ql_write_common_reg(qdev, - (u32 *) & port_regs->CommonRegs. - rxLargeQProducerIndex, - qdev->lrg_buf_q_producer_index); - - /* - * Find out if the chip has already been initialized. If it has, then - * we skip some of the initialization. - */ - clear_bit(QL_LINK_MASTER, &qdev->flags); - value = ql_read_page0_reg(qdev, &port_regs->portStatus); - if ((value & PORT_STATUS_IC) == 0) { - - /* Chip has not been configured yet, so let it rip. */ - if(ql_init_misc_registers(qdev)) { - status = -1; - goto out; - } - - if (qdev->mac_index) - ql_write_page0_reg(qdev, - &port_regs->mac1MaxFrameLengthReg, - qdev->max_frame_size); - else - ql_write_page0_reg(qdev, - &port_regs->mac0MaxFrameLengthReg, - qdev->max_frame_size); - - value = qdev->nvram_data.tcpMaxWindowSize; - ql_write_page0_reg(qdev, &port_regs->tcpMaxWindow, value); - - value = (0xFFFF << 16) | qdev->nvram_data.extHwConfig; - - if(ql_sem_spinlock(qdev, QL_FLASH_SEM_MASK, - (QL_RESOURCE_BITS_BASE_CODE | (qdev->mac_index) - * 2) << 13)) { - status = -1; - goto out; - } - ql_write_page0_reg(qdev, &port_regs->ExternalHWConfig, value); - ql_write_page0_reg(qdev, &port_regs->InternalChipConfig, - (((INTERNAL_CHIP_SD | INTERNAL_CHIP_WE) << - 16) | (INTERNAL_CHIP_SD | - INTERNAL_CHIP_WE))); - ql_sem_unlock(qdev, QL_FLASH_SEM_MASK); - } - - - if(ql_sem_spinlock(qdev, QL_PHY_GIO_SEM_MASK, - (QL_RESOURCE_BITS_BASE_CODE | (qdev->mac_index) * - 2) << 7)) { - status = -1; - goto out; - } - - ql_init_scan_mode(qdev); - ql_get_phy_owner(qdev); - - /* Load the MAC Configuration */ - - /* Program lower 32 bits of the MAC address */ - ql_write_page0_reg(qdev, &port_regs->macAddrIndirectPtrReg, - (MAC_ADDR_INDIRECT_PTR_REG_RP_MASK << 16)); - ql_write_page0_reg(qdev, &port_regs->macAddrDataReg, - ((qdev->ndev->dev_addr[2] << 24) - | (qdev->ndev->dev_addr[3] << 16) - | (qdev->ndev->dev_addr[4] << 8) - | qdev->ndev->dev_addr[5])); - - /* Program top 16 bits of the MAC address */ - ql_write_page0_reg(qdev, &port_regs->macAddrIndirectPtrReg, - ((MAC_ADDR_INDIRECT_PTR_REG_RP_MASK << 16) | 1)); - ql_write_page0_reg(qdev, &port_regs->macAddrDataReg, - ((qdev->ndev->dev_addr[0] << 8) - | qdev->ndev->dev_addr[1])); - - /* Enable Primary MAC */ - ql_write_page0_reg(qdev, &port_regs->macAddrIndirectPtrReg, - ((MAC_ADDR_INDIRECT_PTR_REG_PE << 16) | - MAC_ADDR_INDIRECT_PTR_REG_PE)); - - /* Clear Primary and Secondary IP addresses */ - ql_write_page0_reg(qdev, &port_regs->ipAddrIndexReg, - ((IP_ADDR_INDEX_REG_MASK << 16) | - (qdev->mac_index << 2))); - ql_write_page0_reg(qdev, &port_regs->ipAddrDataReg, 0); - - ql_write_page0_reg(qdev, &port_regs->ipAddrIndexReg, - ((IP_ADDR_INDEX_REG_MASK << 16) | - ((qdev->mac_index << 2) + 1))); - ql_write_page0_reg(qdev, &port_regs->ipAddrDataReg, 0); - - ql_sem_unlock(qdev, QL_PHY_GIO_SEM_MASK); - - /* Indicate Configuration Complete */ - ql_write_page0_reg(qdev, - &port_regs->portControl, - ((PORT_CONTROL_CC << 16) | PORT_CONTROL_CC)); - - do { - value = ql_read_page0_reg(qdev, &port_regs->portStatus); - if (value & PORT_STATUS_IC) - break; - msleep(500); - } while (--delay); - - if (delay == 0) { - printk(KERN_ERR PFX - "%s: Hw Initialization timeout.\n", qdev->ndev->name); - status = -1; - goto out; - } - - /* Enable Ethernet Function */ - value = - (PORT_CONTROL_EF | PORT_CONTROL_ET | PORT_CONTROL_EI | - PORT_CONTROL_HH); - ql_write_page0_reg(qdev, &port_regs->portControl, - ((value << 16) | value)); - -out: - return status; -} - -/* - * Caller holds hw_lock. - */ -static int ql_adapter_reset(struct ql3_adapter *qdev) -{ - struct ql3xxx_port_registers __iomem *port_regs = qdev->mem_map_registers; - int status = 0; - u16 value; - int max_wait_time; - - set_bit(QL_RESET_ACTIVE, &qdev->flags); - clear_bit(QL_RESET_DONE, &qdev->flags); - - /* - * Issue soft reset to chip. - */ - printk(KERN_DEBUG PFX - "%s: Issue soft reset to chip.\n", - qdev->ndev->name); - ql_write_common_reg(qdev, - (u32 *) & port_regs->CommonRegs.ispControlStatus, - ((ISP_CONTROL_SR << 16) | ISP_CONTROL_SR)); - - /* Wait 3 seconds for reset to complete. */ - printk(KERN_DEBUG PFX - "%s: Wait 10 milliseconds for reset to complete.\n", - qdev->ndev->name); - - /* Wait until the firmware tells us the Soft Reset is done */ - max_wait_time = 5; - do { - value = - ql_read_common_reg(qdev, - &port_regs->CommonRegs.ispControlStatus); - if ((value & ISP_CONTROL_SR) == 0) - break; - - ssleep(1); - } while ((--max_wait_time)); - - /* - * Also, make sure that the Network Reset Interrupt bit has been - * cleared after the soft reset has taken place. - */ - value = - ql_read_common_reg(qdev, &port_regs->CommonRegs.ispControlStatus); - if (value & ISP_CONTROL_RI) { - printk(KERN_DEBUG PFX - "ql_adapter_reset: clearing RI after reset.\n"); - ql_write_common_reg(qdev, - (u32 *) & port_regs->CommonRegs. - ispControlStatus, - ((ISP_CONTROL_RI << 16) | ISP_CONTROL_RI)); - } - - if (max_wait_time == 0) { - /* Issue Force Soft Reset */ - ql_write_common_reg(qdev, - (u32 *) & port_regs->CommonRegs. - ispControlStatus, - ((ISP_CONTROL_FSR << 16) | - ISP_CONTROL_FSR)); - /* - * Wait until the firmware tells us the Force Soft Reset is - * done - */ - max_wait_time = 5; - do { - value = - ql_read_common_reg(qdev, - &port_regs->CommonRegs. - ispControlStatus); - if ((value & ISP_CONTROL_FSR) == 0) { - break; - } - ssleep(1); - } while ((--max_wait_time)); - } - if (max_wait_time == 0) - status = 1; - - clear_bit(QL_RESET_ACTIVE, &qdev->flags); - set_bit(QL_RESET_DONE, &qdev->flags); - return status; -} - -static void ql_set_mac_info(struct ql3_adapter *qdev) -{ - struct ql3xxx_port_registers __iomem *port_regs = qdev->mem_map_registers; - u32 value, port_status; - u8 func_number; - - /* Get the function number */ - value = - ql_read_common_reg_l(qdev, &port_regs->CommonRegs.ispControlStatus); - func_number = (u8) ((value >> 4) & OPCODE_FUNC_ID_MASK); - port_status = ql_read_page0_reg(qdev, &port_regs->portStatus); - switch (value & ISP_CONTROL_FN_MASK) { - case ISP_CONTROL_FN0_NET: - qdev->mac_index = 0; - qdev->mac_ob_opcode = OUTBOUND_MAC_IOCB | func_number; - qdev->tcp_ob_opcode = OUTBOUND_TCP_IOCB | func_number; - qdev->update_ob_opcode = UPDATE_NCB_IOCB | func_number; - qdev->mb_bit_mask = FN0_MA_BITS_MASK; - qdev->PHYAddr = PORT0_PHY_ADDRESS; - if (port_status & PORT_STATUS_SM0) - set_bit(QL_LINK_OPTICAL,&qdev->flags); - else - clear_bit(QL_LINK_OPTICAL,&qdev->flags); - break; - - case ISP_CONTROL_FN1_NET: - qdev->mac_index = 1; - qdev->mac_ob_opcode = OUTBOUND_MAC_IOCB | func_number; - qdev->tcp_ob_opcode = OUTBOUND_TCP_IOCB | func_number; - qdev->update_ob_opcode = UPDATE_NCB_IOCB | func_number; - qdev->mb_bit_mask = FN1_MA_BITS_MASK; - qdev->PHYAddr = PORT1_PHY_ADDRESS; - if (port_status & PORT_STATUS_SM1) - set_bit(QL_LINK_OPTICAL,&qdev->flags); - else - clear_bit(QL_LINK_OPTICAL,&qdev->flags); - break; - - case ISP_CONTROL_FN0_SCSI: - case ISP_CONTROL_FN1_SCSI: - default: - printk(KERN_DEBUG PFX - "%s: Invalid function number, ispControlStatus = 0x%x\n", - qdev->ndev->name,value); - break; - } - qdev->numPorts = qdev->nvram_data.numPorts; -} - -static void ql_display_dev_info(struct net_device *ndev) -{ - struct ql3_adapter *qdev = (struct ql3_adapter *)netdev_priv(ndev); - struct pci_dev *pdev = qdev->pdev; - - printk(KERN_INFO PFX - "\n%s Adapter %d RevisionID %d found on PCI slot %d.\n", - DRV_NAME, qdev->index, qdev->chip_rev_id, qdev->pci_slot); - printk(KERN_INFO PFX - "%s Interface.\n", - test_bit(QL_LINK_OPTICAL,&qdev->flags) ? "OPTICAL" : "COPPER"); - - /* - * Print PCI bus width/type. - */ - printk(KERN_INFO PFX - "Bus interface is %s %s.\n", - ((qdev->pci_width == 64) ? "64-bit" : "32-bit"), - ((qdev->pci_x) ? "PCI-X" : "PCI")); - - printk(KERN_INFO PFX - "mem IO base address adjusted = 0x%p\n", - qdev->mem_map_registers); - printk(KERN_INFO PFX "Interrupt number = %d\n", pdev->irq); - - if (netif_msg_probe(qdev)) - printk(KERN_INFO PFX - "%s: MAC address %02x:%02x:%02x:%02x:%02x:%02x\n", - ndev->name, ndev->dev_addr[0], ndev->dev_addr[1], - ndev->dev_addr[2], ndev->dev_addr[3], ndev->dev_addr[4], - ndev->dev_addr[5]); -} - -static int ql_adapter_down(struct ql3_adapter *qdev, int do_reset) -{ - struct net_device *ndev = qdev->ndev; - int retval = 0; - - netif_stop_queue(ndev); - netif_carrier_off(ndev); - - clear_bit(QL_ADAPTER_UP,&qdev->flags); - clear_bit(QL_LINK_MASTER,&qdev->flags); - - ql_disable_interrupts(qdev); - - free_irq(qdev->pdev->irq, ndev); - - if (qdev->msi && test_bit(QL_MSI_ENABLED,&qdev->flags)) { - printk(KERN_INFO PFX - "%s: calling pci_disable_msi().\n", qdev->ndev->name); - clear_bit(QL_MSI_ENABLED,&qdev->flags); - pci_disable_msi(qdev->pdev); - } - - del_timer_sync(&qdev->adapter_timer); - - netif_poll_disable(ndev); - - if (do_reset) { - int soft_reset; - unsigned long hw_flags; - - spin_lock_irqsave(&qdev->hw_lock, hw_flags); - if (ql_wait_for_drvr_lock(qdev)) { - if ((soft_reset = ql_adapter_reset(qdev))) { - printk(KERN_ERR PFX - "%s: ql_adapter_reset(%d) FAILED!\n", - ndev->name, qdev->index); - } - printk(KERN_ERR PFX - "%s: Releaseing driver lock via chip reset.\n",ndev->name); - } else { - printk(KERN_ERR PFX - "%s: Could not acquire driver lock to do " - "reset!\n", ndev->name); - retval = -1; - } - spin_unlock_irqrestore(&qdev->hw_lock, hw_flags); - } - ql_free_mem_resources(qdev); - return retval; -} - -static int ql_adapter_up(struct ql3_adapter *qdev) -{ - struct net_device *ndev = qdev->ndev; - int err; - unsigned long irq_flags = SA_SAMPLE_RANDOM | SA_SHIRQ; - unsigned long hw_flags; - - if (ql_alloc_mem_resources(qdev)) { - printk(KERN_ERR PFX - "%s Unable to allocate buffers.\n", ndev->name); - return -ENOMEM; - } - - if (qdev->msi) { - if (pci_enable_msi(qdev->pdev)) { - printk(KERN_ERR PFX - "%s: User requested MSI, but MSI failed to " - "initialize. Continuing without MSI.\n", - qdev->ndev->name); - qdev->msi = 0; - } else { - printk(KERN_INFO PFX "%s: MSI Enabled...\n", qdev->ndev->name); - set_bit(QL_MSI_ENABLED,&qdev->flags); - irq_flags &= ~SA_SHIRQ; - } - } - - if ((err = request_irq(qdev->pdev->irq, - ql3xxx_isr, - irq_flags, ndev->name, ndev))) { - printk(KERN_ERR PFX - "%s: Failed to reserve interrupt %d already in use.\n", - ndev->name, qdev->pdev->irq); - goto err_irq; - } - - spin_lock_irqsave(&qdev->hw_lock, hw_flags); - - if ((err = ql_wait_for_drvr_lock(qdev))) { - if ((err = ql_adapter_initialize(qdev))) { - printk(KERN_ERR PFX - "%s: Unable to initialize adapter.\n", - ndev->name); - goto err_init; - } - printk(KERN_ERR PFX - "%s: Releaseing driver lock.\n",ndev->name); - ql_sem_unlock(qdev, QL_DRVR_SEM_MASK); - } else { - printk(KERN_ERR PFX - "%s: Could not aquire driver lock.\n", - ndev->name); - goto err_lock; - } - - spin_unlock_irqrestore(&qdev->hw_lock, hw_flags); - - set_bit(QL_ADAPTER_UP,&qdev->flags); - - mod_timer(&qdev->adapter_timer, jiffies + HZ * 1); - - netif_poll_enable(ndev); - ql_enable_interrupts(qdev); - return 0; - -err_init: - ql_sem_unlock(qdev, QL_DRVR_SEM_MASK); -err_lock: - free_irq(qdev->pdev->irq, ndev); -err_irq: - if (qdev->msi && test_bit(QL_MSI_ENABLED,&qdev->flags)) { - printk(KERN_INFO PFX - "%s: calling pci_disable_msi().\n", - qdev->ndev->name); - clear_bit(QL_MSI_ENABLED,&qdev->flags); - pci_disable_msi(qdev->pdev); - } - return err; -} - -static int ql_cycle_adapter(struct ql3_adapter *qdev, int reset) -{ - if( ql_adapter_down(qdev,reset) || ql_adapter_up(qdev)) { - printk(KERN_ERR PFX - "%s: Driver up/down cycle failed, " - "closing device\n",qdev->ndev->name); - dev_close(qdev->ndev); - return -1; - } - return 0; -} - -static int ql3xxx_close(struct net_device *ndev) -{ - struct ql3_adapter *qdev = netdev_priv(ndev); - - /* - * Wait for device to recover from a reset. - * (Rarely happens, but possible.) - */ - while (!test_bit(QL_ADAPTER_UP,&qdev->flags)) - msleep(50); - - ql_adapter_down(qdev,QL_DO_RESET); - return 0; -} - -static int ql3xxx_open(struct net_device *ndev) -{ - struct ql3_adapter *qdev = netdev_priv(ndev); - return (ql_adapter_up(qdev)); -} - -static struct net_device_stats *ql3xxx_get_stats(struct net_device *dev) -{ - struct ql3_adapter *qdev = (struct ql3_adapter *)dev->priv; - return &qdev->stats; -} - -static int ql3xxx_change_mtu(struct net_device *ndev, int new_mtu) -{ - struct ql3_adapter *qdev = netdev_priv(ndev); - printk(KERN_ERR PFX "%s: new mtu size = %d.\n", ndev->name, new_mtu); - if (new_mtu != NORMAL_MTU_SIZE && new_mtu != JUMBO_MTU_SIZE) { - printk(KERN_ERR PFX - "%s: mtu size of %d is not valid. Use exactly %d or " - "%d.\n", ndev->name, new_mtu, NORMAL_MTU_SIZE, - JUMBO_MTU_SIZE); - return -EINVAL; - } - - if (!netif_running(ndev)) { - ndev->mtu = new_mtu; - return 0; - } - - ndev->mtu = new_mtu; - return ql_cycle_adapter(qdev,QL_DO_RESET); -} - -static void ql3xxx_set_multicast_list(struct net_device *ndev) -{ - /* - * We are manually parsing the list in the net_device structure. - */ - return; -} - -static int ql3xxx_set_mac_address(struct net_device *ndev, void *p) -{ - struct ql3_adapter *qdev = (struct ql3_adapter *)netdev_priv(ndev); - struct ql3xxx_port_registers __iomem *port_regs = - qdev->mem_map_registers; - struct sockaddr *addr = p; - unsigned long hw_flags; - - if (netif_running(ndev)) - return -EBUSY; - - if (!is_valid_ether_addr(addr->sa_data)) - return -EADDRNOTAVAIL; - - memcpy(ndev->dev_addr, addr->sa_data, ndev->addr_len); - - spin_lock_irqsave(&qdev->hw_lock, hw_flags); - /* Program lower 32 bits of the MAC address */ - ql_write_page0_reg(qdev, &port_regs->macAddrIndirectPtrReg, - (MAC_ADDR_INDIRECT_PTR_REG_RP_MASK << 16)); - ql_write_page0_reg(qdev, &port_regs->macAddrDataReg, - ((ndev->dev_addr[2] << 24) | (ndev-> - dev_addr[3] << 16) | - (ndev->dev_addr[4] << 8) | ndev->dev_addr[5])); - - /* Program top 16 bits of the MAC address */ - ql_write_page0_reg(qdev, &port_regs->macAddrIndirectPtrReg, - ((MAC_ADDR_INDIRECT_PTR_REG_RP_MASK << 16) | 1)); - ql_write_page0_reg(qdev, &port_regs->macAddrDataReg, - ((ndev->dev_addr[0] << 8) | ndev->dev_addr[1])); - spin_unlock_irqrestore(&qdev->hw_lock, hw_flags); - - return 0; -} - -static void ql3xxx_tx_timeout(struct net_device *ndev) -{ - struct ql3_adapter *qdev = (struct ql3_adapter *)netdev_priv(ndev); - - printk(KERN_ERR PFX "%s: Resetting...\n", ndev->name); - /* - * Stop the queues, we've got a problem. - */ - netif_stop_queue(ndev); - - /* - * Wake up the worker to process this event. - */ - queue_work(qdev->workqueue, &qdev->tx_timeout_work); -} - -static void ql_reset_work(struct ql3_adapter *qdev) -{ - struct net_device *ndev = qdev->ndev; - u32 value; - struct ql_tx_buf_cb *tx_cb; - int max_wait_time, i; - struct ql3xxx_port_registers __iomem *port_regs = qdev->mem_map_registers; - unsigned long hw_flags; - - if (test_bit((QL_RESET_PER_SCSI | QL_RESET_START),&qdev->flags)) { - clear_bit(QL_LINK_MASTER,&qdev->flags); - - /* - * Loop through the active list and return the skb. - */ - for (i = 0; i < NUM_REQ_Q_ENTRIES; i++) { - tx_cb = &qdev->tx_buf[i]; - if (tx_cb->skb) { - - printk(KERN_DEBUG PFX - "%s: Freeing lost SKB.\n", - qdev->ndev->name); - pci_unmap_single(qdev->pdev, - pci_unmap_addr(tx_cb, mapaddr), - pci_unmap_len(tx_cb, maplen), PCI_DMA_TODEVICE); - dev_kfree_skb(tx_cb->skb); - tx_cb->skb = NULL; - } - } - - printk(KERN_ERR PFX - "%s: Clearing NRI after reset.\n", qdev->ndev->name); - spin_lock_irqsave(&qdev->hw_lock, hw_flags); - ql_write_common_reg(qdev, - &port_regs->CommonRegs. - ispControlStatus, - ((ISP_CONTROL_RI << 16) | ISP_CONTROL_RI)); - /* - * Wait the for Soft Reset to Complete. - */ - max_wait_time = 10; - do { - value = ql_read_common_reg(qdev, - &port_regs->CommonRegs. - - ispControlStatus); - if ((value & ISP_CONTROL_SR) == 0) { - printk(KERN_DEBUG PFX - "%s: reset completed.\n", - qdev->ndev->name); - break; - } - - if (value & ISP_CONTROL_RI) { - printk(KERN_DEBUG PFX - "%s: clearing NRI after reset.\n", - qdev->ndev->name); - ql_write_common_reg(qdev, - (u32 *) & - port_regs-> - CommonRegs. - ispControlStatus, - ((ISP_CONTROL_RI << - 16) | ISP_CONTROL_RI)); - } - - ssleep(1); - } while (--max_wait_time); - spin_unlock_irqrestore(&qdev->hw_lock, hw_flags); - - if (value & ISP_CONTROL_SR) { - - /* - * Set the reset flags and clear the board again. - * Nothing else to do... - */ - printk(KERN_ERR PFX - "%s: Timed out waiting for reset to " - "complete.\n", ndev->name); - printk(KERN_ERR PFX - "%s: Do a reset.\n", ndev->name); - clear_bit(QL_RESET_PER_SCSI,&qdev->flags); - clear_bit(QL_RESET_START,&qdev->flags); - ql_cycle_adapter(qdev,QL_DO_RESET); - return; - } - - clear_bit(QL_RESET_ACTIVE,&qdev->flags); - clear_bit(QL_RESET_PER_SCSI,&qdev->flags); - clear_bit(QL_RESET_START,&qdev->flags); - ql_cycle_adapter(qdev,QL_NO_RESET); - } -} - -static void ql_tx_timeout_work(struct ql3_adapter *qdev) -{ - ql_cycle_adapter(qdev,QL_DO_RESET); -} - -static void ql_get_board_info(struct ql3_adapter *qdev) -{ - struct ql3xxx_port_registers __iomem *port_regs = qdev->mem_map_registers; - u32 value; - - value = ql_read_page0_reg_l(qdev, &port_regs->portStatus); - - qdev->chip_rev_id = ((value & PORT_STATUS_REV_ID_MASK) >> 12); - if (value & PORT_STATUS_64) - qdev->pci_width = 64; - else - qdev->pci_width = 32; - if (value & PORT_STATUS_X) - qdev->pci_x = 1; - else - qdev->pci_x = 0; - qdev->pci_slot = (u8) PCI_SLOT(qdev->pdev->devfn); -} - -static void ql3xxx_timer(unsigned long ptr) -{ - struct ql3_adapter *qdev = (struct ql3_adapter *)ptr; - - if (test_bit(QL_RESET_ACTIVE,&qdev->flags)) { - printk(KERN_DEBUG PFX - "%s: Reset in progress.\n", - qdev->ndev->name); - goto end; - } - - ql_link_state_machine(qdev); - - /* Restart timer on 2 second interval. */ -end: - mod_timer(&qdev->adapter_timer, jiffies + HZ * 1); -} - -static int __devinit ql3xxx_probe(struct pci_dev *pdev, - const struct pci_device_id *pci_entry) -{ - struct net_device *ndev = NULL; - struct ql3_adapter *qdev = NULL; - static int cards_found = 0; - int pci_using_dac, err; - - err = pci_enable_device(pdev); - if (err) { - printk(KERN_ERR PFX "%s cannot enable PCI device\n", - pci_name(pdev)); - goto err_out; - } - - err = pci_request_regions(pdev, DRV_NAME); - if (err) { - printk(KERN_ERR PFX "%s cannot obtain PCI resources\n", - pci_name(pdev)); - goto err_out_disable_pdev; - } - - pci_set_master(pdev); - - if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) { - pci_using_dac = 1; - err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK); - } else if (!(err = pci_set_dma_mask(pdev, DMA_32BIT_MASK))) { - pci_using_dac = 0; - err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK); - } - - if (err) { - printk(KERN_ERR PFX "%s no usable DMA configuration\n", - pci_name(pdev)); - goto err_out_free_regions; - } - - ndev = alloc_etherdev(sizeof(struct ql3_adapter)); - if (!ndev) - goto err_out_free_regions; - - SET_MODULE_OWNER(ndev); - SET_NETDEV_DEV(ndev, &pdev->dev); - - ndev->features = NETIF_F_LLTX; - if (pci_using_dac) - ndev->features |= NETIF_F_HIGHDMA; - - pci_set_drvdata(pdev, ndev); - - qdev = netdev_priv(ndev); - qdev->index = cards_found; - qdev->ndev = ndev; - qdev->pdev = pdev; - qdev->port_link_state = LS_DOWN; - if (msi) - qdev->msi = 1; - - qdev->msg_enable = netif_msg_init(debug, default_msg); - - qdev->mem_map_registers = - ioremap_nocache(pci_resource_start(pdev, 1), - pci_resource_len(qdev->pdev, 1)); - if (!qdev->mem_map_registers) { - printk(KERN_ERR PFX "%s: cannot map device registers\n", - pci_name(pdev)); - goto err_out_free_ndev; - } - - spin_lock_init(&qdev->adapter_lock); - spin_lock_init(&qdev->hw_lock); - - /* Set driver entry points */ - ndev->open = ql3xxx_open; - ndev->hard_start_xmit = ql3xxx_send; - ndev->stop = ql3xxx_close; - ndev->get_stats = ql3xxx_get_stats; - ndev->change_mtu = ql3xxx_change_mtu; - ndev->set_multicast_list = ql3xxx_set_multicast_list; - SET_ETHTOOL_OPS(ndev, &ql3xxx_ethtool_ops); - ndev->set_mac_address = ql3xxx_set_mac_address; - ndev->tx_timeout = ql3xxx_tx_timeout; - ndev->watchdog_timeo = 5 * HZ; - - ndev->poll = &ql_poll; - ndev->weight = 64; - - ndev->irq = pdev->irq; - - /* make sure the EEPROM is good */ - if (ql_get_nvram_params(qdev)) { - printk(KERN_ALERT PFX - "ql3xxx_probe: Adapter #%d, Invalid NVRAM parameters.\n", - qdev->index); - goto err_out_iounmap; - } - - ql_set_mac_info(qdev); - - /* Validate and set parameters */ - if (qdev->mac_index) { - memcpy(ndev->dev_addr, &qdev->nvram_data.funcCfg_fn2.macAddress, - ETH_ALEN); - } else { - memcpy(ndev->dev_addr, &qdev->nvram_data.funcCfg_fn0.macAddress, - ETH_ALEN); - } - memcpy(ndev->perm_addr, ndev->dev_addr, ndev->addr_len); - - ndev->tx_queue_len = NUM_REQ_Q_ENTRIES; - - /* Turn off support for multicasting */ - ndev->flags &= ~IFF_MULTICAST; - - /* Record PCI bus information. */ - ql_get_board_info(qdev); - - /* - * Set the Maximum Memory Read Byte Count value. We do this to handle - * jumbo frames. - */ - if (qdev->pci_x) { - pci_write_config_word(pdev, (int)0x4e, (u16) 0x0036); - } - - err = register_netdev(ndev); - if (err) { - printk(KERN_ERR PFX "%s: cannot register net device\n", - pci_name(pdev)); - goto err_out_iounmap; - } - - /* we're going to reset, so assume we have no link for now */ - - netif_carrier_off(ndev); - netif_stop_queue(ndev); - - qdev->workqueue = create_singlethread_workqueue(ndev->name); - INIT_WORK(&qdev->reset_work, (void (*)(void *))ql_reset_work, qdev); - INIT_WORK(&qdev->tx_timeout_work, - (void (*)(void *))ql_tx_timeout_work, qdev); - - init_timer(&qdev->adapter_timer); - qdev->adapter_timer.function = ql3xxx_timer; - qdev->adapter_timer.expires = jiffies + HZ * 2; /* two second delay */ - qdev->adapter_timer.data = (unsigned long)qdev; - - if(!cards_found) { - printk(KERN_ALERT PFX "%s\n", DRV_STRING); - printk(KERN_ALERT PFX "Driver name: %s, Version: %s.\n", - DRV_NAME, DRV_VERSION); - } - ql_display_dev_info(ndev); - - cards_found++; - return 0; - -err_out_iounmap: - iounmap(qdev->mem_map_registers); -err_out_free_ndev: - free_netdev(ndev); -err_out_free_regions: - pci_release_regions(pdev); -err_out_disable_pdev: - pci_disable_device(pdev); - pci_set_drvdata(pdev, NULL); -err_out: - return err; -} - -static void __devexit ql3xxx_remove(struct pci_dev *pdev) -{ - struct net_device *ndev = pci_get_drvdata(pdev); - struct ql3_adapter *qdev = netdev_priv(ndev); - - unregister_netdev(ndev); - qdev = netdev_priv(ndev); - - ql_disable_interrupts(qdev); - - if (qdev->workqueue) { - cancel_delayed_work(&qdev->reset_work); - cancel_delayed_work(&qdev->tx_timeout_work); - destroy_workqueue(qdev->workqueue); - qdev->workqueue = NULL; - } - - iounmap((void *)qdev->mmap_virt_base); - pci_release_regions(pdev); - pci_set_drvdata(pdev, NULL); - free_netdev(ndev); -} - -static struct pci_driver ql3xxx_driver = { - - .name = DRV_NAME, - .id_table = ql3xxx_pci_tbl, - .probe = ql3xxx_probe, - .remove = __devexit_p(ql3xxx_remove), -}; - -static int __init ql3xxx_init_module(void) -{ - return pci_register_driver(&ql3xxx_driver); -} - -static void __exit ql3xxx_exit(void) -{ - pci_unregister_driver(&ql3xxx_driver); -} - -module_init(ql3xxx_init_module); -module_exit(ql3xxx_exit); diff --git a/trunk/drivers/net/qla3xxx.h b/trunk/drivers/net/qla3xxx.h deleted file mode 100644 index 9492cee6b083..000000000000 --- a/trunk/drivers/net/qla3xxx.h +++ /dev/null @@ -1,1194 +0,0 @@ -/* - * QLogic QLA3xxx NIC HBA Driver - * Copyright (c) 2003-2006 QLogic Corporation - * - * See LICENSE.qla3xxx for copyright and licensing details. - */ -#ifndef _QLA3XXX_H_ -#define _QLA3XXX_H_ - -/* - * IOCB Definitions... - */ -#pragma pack(1) - -#define OPCODE_OB_MAC_IOCB_FN0 0x01 -#define OPCODE_OB_MAC_IOCB_FN2 0x21 -#define OPCODE_OB_TCP_IOCB_FN0 0x03 -#define OPCODE_OB_TCP_IOCB_FN2 0x23 -#define OPCODE_UPDATE_NCB_IOCB_FN0 0x00 -#define OPCODE_UPDATE_NCB_IOCB_FN2 0x20 - -#define OPCODE_UPDATE_NCB_IOCB 0xF0 -#define OPCODE_IB_MAC_IOCB 0xF9 -#define OPCODE_IB_IP_IOCB 0xFA -#define OPCODE_IB_TCP_IOCB 0xFB -#define OPCODE_DUMP_PROTO_IOCB 0xFE -#define OPCODE_BUFFER_ALERT_IOCB 0xFB - -#define OPCODE_FUNC_ID_MASK 0x30 -#define OUTBOUND_MAC_IOCB 0x01 /* plus function bits */ -#define OUTBOUND_TCP_IOCB 0x03 /* plus function bits */ -#define UPDATE_NCB_IOCB 0x00 /* plus function bits */ - -#define FN0_MA_BITS_MASK 0x00 -#define FN1_MA_BITS_MASK 0x80 - -struct ob_mac_iocb_req { - u8 opcode; - u8 flags; -#define OB_MAC_IOCB_REQ_MA 0xC0 -#define OB_MAC_IOCB_REQ_F 0x20 -#define OB_MAC_IOCB_REQ_X 0x10 -#define OB_MAC_IOCB_REQ_D 0x02 -#define OB_MAC_IOCB_REQ_I 0x01 - __le16 reserved0; - - __le32 transaction_id; - __le16 data_len; - __le16 reserved1; - __le32 reserved2; - __le32 reserved3; - __le32 buf_addr0_low; - __le32 buf_addr0_high; - __le32 buf_0_len; - __le32 buf_addr1_low; - __le32 buf_addr1_high; - __le32 buf_1_len; - __le32 buf_addr2_low; - __le32 buf_addr2_high; - __le32 buf_2_len; - __le32 reserved4; - __le32 reserved5; -}; -/* - * The following constants define control bits for buffer - * length fields for all IOCB's. - */ -#define OB_MAC_IOCB_REQ_E 0x80000000 /* Last valid buffer in list. */ -#define OB_MAC_IOCB_REQ_C 0x40000000 /* points to an OAL. (continuation) */ -#define OB_MAC_IOCB_REQ_L 0x20000000 /* Auburn local address pointer. */ -#define OB_MAC_IOCB_REQ_R 0x10000000 /* 32-bit address pointer. */ - -struct ob_mac_iocb_rsp { - u8 opcode; - u8 flags; -#define OB_MAC_IOCB_RSP_P 0x08 -#define OB_MAC_IOCB_RSP_S 0x02 -#define OB_MAC_IOCB_RSP_I 0x01 - - __le16 reserved0; - __le32 transaction_id; - __le32 reserved1; - __le32 reserved2; -}; - -struct ib_mac_iocb_rsp { - u8 opcode; - u8 flags; -#define IB_MAC_IOCB_RSP_S 0x80 -#define IB_MAC_IOCB_RSP_H1 0x40 -#define IB_MAC_IOCB_RSP_H0 0x20 -#define IB_MAC_IOCB_RSP_B 0x10 -#define IB_MAC_IOCB_RSP_M 0x08 -#define IB_MAC_IOCB_RSP_MA 0x07 - - __le16 length; - __le32 reserved; - __le32 ial_low; - __le32 ial_high; - -}; - -struct ob_ip_iocb_req { - u8 opcode; - __le16 flags; -#define OB_IP_IOCB_REQ_O 0x100 -#define OB_IP_IOCB_REQ_H 0x008 -#define OB_IP_IOCB_REQ_U 0x004 -#define OB_IP_IOCB_REQ_D 0x002 -#define OB_IP_IOCB_REQ_I 0x001 - - u8 reserved0; - - __le32 transaction_id; - __le16 data_len; - __le16 reserved1; - __le32 hncb_ptr_low; - __le32 hncb_ptr_high; - __le32 buf_addr0_low; - __le32 buf_addr0_high; - __le32 buf_0_len; - __le32 buf_addr1_low; - __le32 buf_addr1_high; - __le32 buf_1_len; - __le32 buf_addr2_low; - __le32 buf_addr2_high; - __le32 buf_2_len; - __le32 reserved2; - __le32 reserved3; -}; - -/* defines for BufferLength fields above */ -#define OB_IP_IOCB_REQ_E 0x80000000 -#define OB_IP_IOCB_REQ_C 0x40000000 -#define OB_IP_IOCB_REQ_L 0x20000000 -#define OB_IP_IOCB_REQ_R 0x10000000 - -struct ob_ip_iocb_rsp { - u8 opcode; - u8 flags; -#define OB_MAC_IOCB_RSP_E 0x08 -#define OB_MAC_IOCB_RSP_L 0x04 -#define OB_MAC_IOCB_RSP_S 0x02 -#define OB_MAC_IOCB_RSP_I 0x01 - - __le16 reserved0; - __le32 transaction_id; - __le32 reserved1; - __le32 reserved2; -}; - -struct ob_tcp_iocb_req { - u8 opcode; - - u8 flags0; -#define OB_TCP_IOCB_REQ_P 0x80 -#define OB_TCP_IOCB_REQ_CI 0x20 -#define OB_TCP_IOCB_REQ_H 0x10 -#define OB_TCP_IOCB_REQ_LN 0x08 -#define OB_TCP_IOCB_REQ_K 0x04 -#define OB_TCP_IOCB_REQ_D 0x02 -#define OB_TCP_IOCB_REQ_I 0x01 - - u8 flags1; -#define OB_TCP_IOCB_REQ_OSM 0x40 -#define OB_TCP_IOCB_REQ_URG 0x20 -#define OB_TCP_IOCB_REQ_ACK 0x10 -#define OB_TCP_IOCB_REQ_PSH 0x08 -#define OB_TCP_IOCB_REQ_RST 0x04 -#define OB_TCP_IOCB_REQ_SYN 0x02 -#define OB_TCP_IOCB_REQ_FIN 0x01 - - u8 options_len; -#define OB_TCP_IOCB_REQ_OMASK 0xF0 -#define OB_TCP_IOCB_REQ_SHIFT 4 - - __le32 transaction_id; - __le32 data_len; - __le32 hncb_ptr_low; - __le32 hncb_ptr_high; - __le32 buf_addr0_low; - __le32 buf_addr0_high; - __le32 buf_0_len; - __le32 buf_addr1_low; - __le32 buf_addr1_high; - __le32 buf_1_len; - __le32 buf_addr2_low; - __le32 buf_addr2_high; - __le32 buf_2_len; - __le32 time_stamp; - __le32 reserved1; -}; - -struct ob_tcp_iocb_rsp { - u8 opcode; - - u8 flags0; -#define OB_TCP_IOCB_RSP_C 0x20 -#define OB_TCP_IOCB_RSP_H 0x10 -#define OB_TCP_IOCB_RSP_LN 0x08 -#define OB_TCP_IOCB_RSP_K 0x04 -#define OB_TCP_IOCB_RSP_D 0x02 -#define OB_TCP_IOCB_RSP_I 0x01 - - u8 flags1; -#define OB_TCP_IOCB_RSP_E 0x10 -#define OB_TCP_IOCB_RSP_W 0x08 -#define OB_TCP_IOCB_RSP_P 0x04 -#define OB_TCP_IOCB_RSP_T 0x02 -#define OB_TCP_IOCB_RSP_F 0x01 - - u8 state; -#define OB_TCP_IOCB_RSP_SMASK 0xF0 -#define OB_TCP_IOCB_RSP_SHIFT 4 - - __le32 transaction_id; - __le32 local_ncb_ptr; - __le32 reserved0; -}; - -struct ib_ip_iocb_rsp { - u8 opcode; - u8 flags; -#define IB_IP_IOCB_RSP_S 0x80 -#define IB_IP_IOCB_RSP_H1 0x40 -#define IB_IP_IOCB_RSP_H0 0x20 -#define IB_IP_IOCB_RSP_B 0x10 -#define IB_IP_IOCB_RSP_M 0x08 -#define IB_IP_IOCB_RSP_MA 0x07 - - __le16 length; - __le16 checksum; - __le16 reserved; -#define IB_IP_IOCB_RSP_R 0x01 - __le32 ial_low; - __le32 ial_high; -}; - -struct ib_tcp_iocb_rsp { - u8 opcode; - u8 flags; -#define IB_TCP_IOCB_RSP_P 0x80 -#define IB_TCP_IOCB_RSP_T 0x40 -#define IB_TCP_IOCB_RSP_D 0x20 -#define IB_TCP_IOCB_RSP_N 0x10 -#define IB_TCP_IOCB_RSP_IP 0x03 -#define IB_TCP_FLAG_MASK 0xf0 -#define IB_TCP_FLAG_IOCB_SYN 0x00 - -#define TCP_IB_RSP_FLAGS(x) (x->flags & ~IB_TCP_FLAG_MASK) - - __le16 length; - __le32 hncb_ref_num; - __le32 ial_low; - __le32 ial_high; -}; - -struct net_rsp_iocb { - u8 opcode; - u8 flags; - __le16 reserved0; - __le32 reserved[3]; -}; -#pragma pack() - -/* - * Register Definitions... - */ -#define PORT0_PHY_ADDRESS 0x1e00 -#define PORT1_PHY_ADDRESS 0x1f00 - -#define ETHERNET_CRC_SIZE 4 - -#define MII_SCAN_REGISTER 0x00000001 - -/* 32-bit ispControlStatus */ -enum { - ISP_CONTROL_NP_MASK = 0x0003, - ISP_CONTROL_NP_PCSR = 0x0000, - ISP_CONTROL_NP_HMCR = 0x0001, - ISP_CONTROL_NP_LRAMCR = 0x0002, - ISP_CONTROL_NP_PSR = 0x0003, - ISP_CONTROL_RI = 0x0008, - ISP_CONTROL_CI = 0x0010, - ISP_CONTROL_PI = 0x0020, - ISP_CONTROL_IN = 0x0040, - ISP_CONTROL_BE = 0x0080, - ISP_CONTROL_FN_MASK = 0x0700, - ISP_CONTROL_FN0_NET = 0x0400, - ISP_CONTROL_FN0_SCSI = 0x0500, - ISP_CONTROL_FN1_NET = 0x0600, - ISP_CONTROL_FN1_SCSI = 0x0700, - ISP_CONTROL_LINK_DN_0 = 0x0800, - ISP_CONTROL_LINK_DN_1 = 0x1000, - ISP_CONTROL_FSR = 0x2000, - ISP_CONTROL_FE = 0x4000, - ISP_CONTROL_SR = 0x8000, -}; - -/* 32-bit ispInterruptMaskReg */ -enum { - ISP_IMR_ENABLE_INT = 0x0004, - ISP_IMR_DISABLE_RESET_INT = 0x0008, - ISP_IMR_DISABLE_CMPL_INT = 0x0010, - ISP_IMR_DISABLE_PROC_INT = 0x0020, -}; - -/* 32-bit serialPortInterfaceReg */ -enum { - ISP_SERIAL_PORT_IF_CLK = 0x0001, - ISP_SERIAL_PORT_IF_CS = 0x0002, - ISP_SERIAL_PORT_IF_D0 = 0x0004, - ISP_SERIAL_PORT_IF_DI = 0x0008, - ISP_NVRAM_MASK = (0x000F << 16), - ISP_SERIAL_PORT_IF_WE = 0x0010, - ISP_SERIAL_PORT_IF_NVR_MASK = 0x001F, - ISP_SERIAL_PORT_IF_SCI = 0x0400, - ISP_SERIAL_PORT_IF_SC0 = 0x0800, - ISP_SERIAL_PORT_IF_SCE = 0x1000, - ISP_SERIAL_PORT_IF_SDI = 0x2000, - ISP_SERIAL_PORT_IF_SDO = 0x4000, - ISP_SERIAL_PORT_IF_SDE = 0x8000, - ISP_SERIAL_PORT_IF_I2C_MASK = 0xFC00, -}; - -/* semaphoreReg */ -enum { - QL_RESOURCE_MASK_BASE_CODE = 0x7, - QL_RESOURCE_BITS_BASE_CODE = 0x4, - QL_DRVR_SEM_BITS = (QL_RESOURCE_BITS_BASE_CODE << 1), - QL_DDR_RAM_SEM_BITS = (QL_RESOURCE_BITS_BASE_CODE << 4), - QL_PHY_GIO_SEM_BITS = (QL_RESOURCE_BITS_BASE_CODE << 7), - QL_NVRAM_SEM_BITS = (QL_RESOURCE_BITS_BASE_CODE << 10), - QL_FLASH_SEM_BITS = (QL_RESOURCE_BITS_BASE_CODE << 13), - QL_DRVR_SEM_MASK = (QL_RESOURCE_MASK_BASE_CODE << (1 + 16)), - QL_DDR_RAM_SEM_MASK = (QL_RESOURCE_MASK_BASE_CODE << (4 + 16)), - QL_PHY_GIO_SEM_MASK = (QL_RESOURCE_MASK_BASE_CODE << (7 + 16)), - QL_NVRAM_SEM_MASK = (QL_RESOURCE_MASK_BASE_CODE << (10 + 16)), - QL_FLASH_SEM_MASK = (QL_RESOURCE_MASK_BASE_CODE << (13 + 16)), -}; - - /* - * QL3XXX memory-mapped registers - * QL3XXX has 4 "pages" of registers, each page occupying - * 256 bytes. Each page has a "common" area at the start and then - * page-specific registers after that. - */ -struct ql3xxx_common_registers { - u32 MB0; /* Offset 0x00 */ - u32 MB1; /* Offset 0x04 */ - u32 MB2; /* Offset 0x08 */ - u32 MB3; /* Offset 0x0c */ - u32 MB4; /* Offset 0x10 */ - u32 MB5; /* Offset 0x14 */ - u32 MB6; /* Offset 0x18 */ - u32 MB7; /* Offset 0x1c */ - u32 flashBiosAddr; - u32 flashBiosData; - u32 ispControlStatus; - u32 ispInterruptMaskReg; - u32 serialPortInterfaceReg; - u32 semaphoreReg; - u32 reqQProducerIndex; - u32 rspQConsumerIndex; - - u32 rxLargeQProducerIndex; - u32 rxSmallQProducerIndex; - u32 arcMadiCommand; - u32 arcMadiData; -}; - -enum { - EXT_HW_CONFIG_SP_MASK = 0x0006, - EXT_HW_CONFIG_SP_NONE = 0x0000, - EXT_HW_CONFIG_SP_BYTE_PARITY = 0x0002, - EXT_HW_CONFIG_SP_ECC = 0x0004, - EXT_HW_CONFIG_SP_ECCx = 0x0006, - EXT_HW_CONFIG_SIZE_MASK = 0x0060, - EXT_HW_CONFIG_SIZE_128M = 0x0000, - EXT_HW_CONFIG_SIZE_256M = 0x0020, - EXT_HW_CONFIG_SIZE_512M = 0x0040, - EXT_HW_CONFIG_SIZE_INVALID = 0x0060, - EXT_HW_CONFIG_PD = 0x0080, - EXT_HW_CONFIG_FW = 0x0200, - EXT_HW_CONFIG_US = 0x0400, - EXT_HW_CONFIG_DCS_MASK = 0x1800, - EXT_HW_CONFIG_DCS_9MA = 0x0000, - EXT_HW_CONFIG_DCS_15MA = 0x0800, - EXT_HW_CONFIG_DCS_18MA = 0x1000, - EXT_HW_CONFIG_DCS_24MA = 0x1800, - EXT_HW_CONFIG_DDS_MASK = 0x6000, - EXT_HW_CONFIG_DDS_9MA = 0x0000, - EXT_HW_CONFIG_DDS_15MA = 0x2000, - EXT_HW_CONFIG_DDS_18MA = 0x4000, - EXT_HW_CONFIG_DDS_24MA = 0x6000, -}; - -/* InternalChipConfig */ -enum { - INTERNAL_CHIP_DM = 0x0001, - INTERNAL_CHIP_SD = 0x0002, - INTERNAL_CHIP_RAP_MASK = 0x000C, - INTERNAL_CHIP_RAP_RR = 0x0000, - INTERNAL_CHIP_RAP_NRM = 0x0004, - INTERNAL_CHIP_RAP_ERM = 0x0008, - INTERNAL_CHIP_RAP_ERMx = 0x000C, - INTERNAL_CHIP_WE = 0x0010, - INTERNAL_CHIP_EF = 0x0020, - INTERNAL_CHIP_FR = 0x0040, - INTERNAL_CHIP_FW = 0x0080, - INTERNAL_CHIP_FI = 0x0100, - INTERNAL_CHIP_FT = 0x0200, -}; - -/* portControl */ -enum { - PORT_CONTROL_DS = 0x0001, - PORT_CONTROL_HH = 0x0002, - PORT_CONTROL_EI = 0x0004, - PORT_CONTROL_ET = 0x0008, - PORT_CONTROL_EF = 0x0010, - PORT_CONTROL_DRM = 0x0020, - PORT_CONTROL_RLB = 0x0040, - PORT_CONTROL_RCB = 0x0080, - PORT_CONTROL_MAC = 0x0100, - PORT_CONTROL_IPV = 0x0200, - PORT_CONTROL_IFP = 0x0400, - PORT_CONTROL_ITP = 0x0800, - PORT_CONTROL_FI = 0x1000, - PORT_CONTROL_DFP = 0x2000, - PORT_CONTROL_OI = 0x4000, - PORT_CONTROL_CC = 0x8000, -}; - -/* portStatus */ -enum { - PORT_STATUS_SM0 = 0x0001, - PORT_STATUS_SM1 = 0x0002, - PORT_STATUS_X = 0x0008, - PORT_STATUS_DL = 0x0080, - PORT_STATUS_IC = 0x0200, - PORT_STATUS_MRC = 0x0400, - PORT_STATUS_NL = 0x0800, - PORT_STATUS_REV_ID_MASK = 0x7000, - PORT_STATUS_REV_ID_1 = 0x1000, - PORT_STATUS_REV_ID_2 = 0x2000, - PORT_STATUS_REV_ID_3 = 0x3000, - PORT_STATUS_64 = 0x8000, - PORT_STATUS_UP0 = 0x10000, - PORT_STATUS_AC0 = 0x20000, - PORT_STATUS_AE0 = 0x40000, - PORT_STATUS_UP1 = 0x100000, - PORT_STATUS_AC1 = 0x200000, - PORT_STATUS_AE1 = 0x400000, - PORT_STATUS_F0_ENABLED = 0x1000000, - PORT_STATUS_F1_ENABLED = 0x2000000, - PORT_STATUS_F2_ENABLED = 0x4000000, - PORT_STATUS_F3_ENABLED = 0x8000000, -}; - -/* macMIIMgmtControlReg */ -enum { - MAC_ADDR_INDIRECT_PTR_REG_RP_MASK = 0x0003, - MAC_ADDR_INDIRECT_PTR_REG_RP_PRI_LWR = 0x0000, - MAC_ADDR_INDIRECT_PTR_REG_RP_PRI_UPR = 0x0001, - MAC_ADDR_INDIRECT_PTR_REG_RP_SEC_LWR = 0x0002, - MAC_ADDR_INDIRECT_PTR_REG_RP_SEC_UPR = 0x0003, - MAC_ADDR_INDIRECT_PTR_REG_PR = 0x0008, - MAC_ADDR_INDIRECT_PTR_REG_SS = 0x0010, - MAC_ADDR_INDIRECT_PTR_REG_SE = 0x0020, - MAC_ADDR_INDIRECT_PTR_REG_SP = 0x0040, - MAC_ADDR_INDIRECT_PTR_REG_PE = 0x0080, -}; - -/* macMIIMgmtControlReg */ -enum { - MAC_MII_CONTROL_RC = 0x0001, - MAC_MII_CONTROL_SC = 0x0002, - MAC_MII_CONTROL_AS = 0x0004, - MAC_MII_CONTROL_NP = 0x0008, - MAC_MII_CONTROL_CLK_SEL_MASK = 0x0070, - MAC_MII_CONTROL_CLK_SEL_DIV2 = 0x0000, - MAC_MII_CONTROL_CLK_SEL_DIV4 = 0x0010, - MAC_MII_CONTROL_CLK_SEL_DIV6 = 0x0020, - MAC_MII_CONTROL_CLK_SEL_DIV8 = 0x0030, - MAC_MII_CONTROL_CLK_SEL_DIV10 = 0x0040, - MAC_MII_CONTROL_CLK_SEL_DIV14 = 0x0050, - MAC_MII_CONTROL_CLK_SEL_DIV20 = 0x0060, - MAC_MII_CONTROL_CLK_SEL_DIV28 = 0x0070, - MAC_MII_CONTROL_RM = 0x8000, -}; - -/* macMIIStatusReg */ -enum { - MAC_MII_STATUS_BSY = 0x0001, - MAC_MII_STATUS_SC = 0x0002, - MAC_MII_STATUS_NV = 0x0004, -}; - -enum { - MAC_CONFIG_REG_PE = 0x0001, - MAC_CONFIG_REG_TF = 0x0002, - MAC_CONFIG_REG_RF = 0x0004, - MAC_CONFIG_REG_FD = 0x0008, - MAC_CONFIG_REG_GM = 0x0010, - MAC_CONFIG_REG_LB = 0x0020, - MAC_CONFIG_REG_SR = 0x8000, -}; - -enum { - MAC_HALF_DUPLEX_REG_ED = 0x10000, - MAC_HALF_DUPLEX_REG_NB = 0x20000, - MAC_HALF_DUPLEX_REG_BNB = 0x40000, - MAC_HALF_DUPLEX_REG_ALT = 0x80000, -}; - -enum { - IP_ADDR_INDEX_REG_MASK = 0x000f, - IP_ADDR_INDEX_REG_FUNC_0_PRI = 0x0000, - IP_ADDR_INDEX_REG_FUNC_0_SEC = 0x0001, - IP_ADDR_INDEX_REG_FUNC_1_PRI = 0x0002, - IP_ADDR_INDEX_REG_FUNC_1_SEC = 0x0003, - IP_ADDR_INDEX_REG_FUNC_2_PRI = 0x0004, - IP_ADDR_INDEX_REG_FUNC_2_SEC = 0x0005, - IP_ADDR_INDEX_REG_FUNC_3_PRI = 0x0006, - IP_ADDR_INDEX_REG_FUNC_3_SEC = 0x0007, -}; - -enum { - PROBE_MUX_ADDR_REG_MUX_SEL_MASK = 0x003f, - PROBE_MUX_ADDR_REG_SYSCLK = 0x0000, - PROBE_MUX_ADDR_REG_PCICLK = 0x0040, - PROBE_MUX_ADDR_REG_NRXCLK = 0x0080, - PROBE_MUX_ADDR_REG_CPUCLK = 0x00C0, - PROBE_MUX_ADDR_REG_MODULE_SEL_MASK = 0x3f00, - PROBE_MUX_ADDR_REG_UP = 0x4000, - PROBE_MUX_ADDR_REG_RE = 0x8000, -}; - -enum { - STATISTICS_INDEX_REG_MASK = 0x01ff, - STATISTICS_INDEX_REG_MAC0_TX_FRAME = 0x0000, - STATISTICS_INDEX_REG_MAC0_TX_BYTES = 0x0001, - STATISTICS_INDEX_REG_MAC0_TX_STAT1 = 0x0002, - STATISTICS_INDEX_REG_MAC0_TX_STAT2 = 0x0003, - STATISTICS_INDEX_REG_MAC0_TX_STAT3 = 0x0004, - STATISTICS_INDEX_REG_MAC0_TX_STAT4 = 0x0005, - STATISTICS_INDEX_REG_MAC0_TX_STAT5 = 0x0006, - STATISTICS_INDEX_REG_MAC0_RX_FRAME = 0x0007, - STATISTICS_INDEX_REG_MAC0_RX_BYTES = 0x0008, - STATISTICS_INDEX_REG_MAC0_RX_STAT1 = 0x0009, - STATISTICS_INDEX_REG_MAC0_RX_STAT2 = 0x000a, - STATISTICS_INDEX_REG_MAC0_RX_STAT3 = 0x000b, - STATISTICS_INDEX_REG_MAC0_RX_ERR_CRC = 0x000c, - STATISTICS_INDEX_REG_MAC0_RX_ERR_ENC = 0x000d, - STATISTICS_INDEX_REG_MAC0_RX_ERR_LEN = 0x000e, - STATISTICS_INDEX_REG_MAC0_RX_STAT4 = 0x000f, - STATISTICS_INDEX_REG_MAC1_TX_FRAME = 0x0010, - STATISTICS_INDEX_REG_MAC1_TX_BYTES = 0x0011, - STATISTICS_INDEX_REG_MAC1_TX_STAT1 = 0x0012, - STATISTICS_INDEX_REG_MAC1_TX_STAT2 = 0x0013, - STATISTICS_INDEX_REG_MAC1_TX_STAT3 = 0x0014, - STATISTICS_INDEX_REG_MAC1_TX_STAT4 = 0x0015, - STATISTICS_INDEX_REG_MAC1_TX_STAT5 = 0x0016, - STATISTICS_INDEX_REG_MAC1_RX_FRAME = 0x0017, - STATISTICS_INDEX_REG_MAC1_RX_BYTES = 0x0018, - STATISTICS_INDEX_REG_MAC1_RX_STAT1 = 0x0019, - STATISTICS_INDEX_REG_MAC1_RX_STAT2 = 0x001a, - STATISTICS_INDEX_REG_MAC1_RX_STAT3 = 0x001b, - STATISTICS_INDEX_REG_MAC1_RX_ERR_CRC = 0x001c, - STATISTICS_INDEX_REG_MAC1_RX_ERR_ENC = 0x001d, - STATISTICS_INDEX_REG_MAC1_RX_ERR_LEN = 0x001e, - STATISTICS_INDEX_REG_MAC1_RX_STAT4 = 0x001f, - STATISTICS_INDEX_REG_IP_TX_PKTS = 0x0020, - STATISTICS_INDEX_REG_IP_TX_BYTES = 0x0021, - STATISTICS_INDEX_REG_IP_TX_FRAG = 0x0022, - STATISTICS_INDEX_REG_IP_RX_PKTS = 0x0023, - STATISTICS_INDEX_REG_IP_RX_BYTES = 0x0024, - STATISTICS_INDEX_REG_IP_RX_FRAG = 0x0025, - STATISTICS_INDEX_REG_IP_DGRM_REASSEMBLY = 0x0026, - STATISTICS_INDEX_REG_IP_V6_RX_PKTS = 0x0027, - STATISTICS_INDEX_REG_IP_RX_PKTERR = 0x0028, - STATISTICS_INDEX_REG_IP_REASSEMBLY_ERR = 0x0029, - STATISTICS_INDEX_REG_TCP_TX_SEG = 0x0030, - STATISTICS_INDEX_REG_TCP_TX_BYTES = 0x0031, - STATISTICS_INDEX_REG_TCP_RX_SEG = 0x0032, - STATISTICS_INDEX_REG_TCP_RX_BYTES = 0x0033, - STATISTICS_INDEX_REG_TCP_TIMER_EXP = 0x0034, - STATISTICS_INDEX_REG_TCP_RX_ACK = 0x0035, - STATISTICS_INDEX_REG_TCP_TX_ACK = 0x0036, - STATISTICS_INDEX_REG_TCP_RX_ERR = 0x0037, - STATISTICS_INDEX_REG_TCP_RX_WIN_PROBE = 0x0038, - STATISTICS_INDEX_REG_TCP_ECC_ERR_CORR = 0x003f, -}; - -enum { - PORT_FATAL_ERROR_STATUS_OFB_RE_MAC0 = 0x00000001, - PORT_FATAL_ERROR_STATUS_OFB_RE_MAC1 = 0x00000002, - PORT_FATAL_ERROR_STATUS_OFB_WE = 0x00000004, - PORT_FATAL_ERROR_STATUS_IFB_RE = 0x00000008, - PORT_FATAL_ERROR_STATUS_IFB_WE_MAC0 = 0x00000010, - PORT_FATAL_ERROR_STATUS_IFB_WE_MAC1 = 0x00000020, - PORT_FATAL_ERROR_STATUS_ODE_RE = 0x00000040, - PORT_FATAL_ERROR_STATUS_ODE_WE = 0x00000080, - PORT_FATAL_ERROR_STATUS_IDE_RE = 0x00000100, - PORT_FATAL_ERROR_STATUS_IDE_WE = 0x00000200, - PORT_FATAL_ERROR_STATUS_SDE_RE = 0x00000400, - PORT_FATAL_ERROR_STATUS_SDE_WE = 0x00000800, - PORT_FATAL_ERROR_STATUS_BLE = 0x00001000, - PORT_FATAL_ERROR_STATUS_SPE = 0x00002000, - PORT_FATAL_ERROR_STATUS_EP0 = 0x00004000, - PORT_FATAL_ERROR_STATUS_EP1 = 0x00008000, - PORT_FATAL_ERROR_STATUS_ICE = 0x00010000, - PORT_FATAL_ERROR_STATUS_ILE = 0x00020000, - PORT_FATAL_ERROR_STATUS_OPE = 0x00040000, - PORT_FATAL_ERROR_STATUS_TA = 0x00080000, - PORT_FATAL_ERROR_STATUS_MA = 0x00100000, - PORT_FATAL_ERROR_STATUS_SCE = 0x00200000, - PORT_FATAL_ERROR_STATUS_RPE = 0x00400000, - PORT_FATAL_ERROR_STATUS_MPE = 0x00800000, - PORT_FATAL_ERROR_STATUS_OCE = 0x01000000, -}; - -/* - * port control and status page - page 0 - */ - -struct ql3xxx_port_registers { - struct ql3xxx_common_registers CommonRegs; - - u32 ExternalHWConfig; - u32 InternalChipConfig; - u32 portControl; - u32 portStatus; - u32 macAddrIndirectPtrReg; - u32 macAddrDataReg; - u32 macMIIMgmtControlReg; - u32 macMIIMgmtAddrReg; - u32 macMIIMgmtDataReg; - u32 macMIIStatusReg; - u32 mac0ConfigReg; - u32 mac0IpgIfgReg; - u32 mac0HalfDuplexReg; - u32 mac0MaxFrameLengthReg; - u32 mac0PauseThresholdReg; - u32 mac1ConfigReg; - u32 mac1IpgIfgReg; - u32 mac1HalfDuplexReg; - u32 mac1MaxFrameLengthReg; - u32 mac1PauseThresholdReg; - u32 ipAddrIndexReg; - u32 ipAddrDataReg; - u32 ipReassemblyTimeout; - u32 tcpMaxWindow; - u32 currentTcpTimestamp[2]; - u32 internalRamRWAddrReg; - u32 internalRamWDataReg; - u32 reclaimedBufferAddrRegLow; - u32 reclaimedBufferAddrRegHigh; - u32 reserved[2]; - u32 fpgaRevID; - u32 localRamAddr; - u32 localRamDataAutoIncr; - u32 localRamDataNonIncr; - u32 gpOutput; - u32 gpInput; - u32 probeMuxAddr; - u32 probeMuxData; - u32 statisticsIndexReg; - u32 statisticsReadDataRegAutoIncr; - u32 statisticsReadDataRegNoIncr; - u32 PortFatalErrStatus; -}; - -/* - * port host memory config page - page 1 - */ -struct ql3xxx_host_memory_registers { - struct ql3xxx_common_registers CommonRegs; - - u32 reserved[12]; - - /* Network Request Queue */ - u32 reqConsumerIndex; - u32 reqConsumerIndexAddrLow; - u32 reqConsumerIndexAddrHigh; - u32 reqBaseAddrLow; - u32 reqBaseAddrHigh; - u32 reqLength; - - /* Network Completion Queue */ - u32 rspProducerIndex; - u32 rspProducerIndexAddrLow; - u32 rspProducerIndexAddrHigh; - u32 rspBaseAddrLow; - u32 rspBaseAddrHigh; - u32 rspLength; - - /* RX Large Buffer Queue */ - u32 rxLargeQConsumerIndex; - u32 rxLargeQBaseAddrLow; - u32 rxLargeQBaseAddrHigh; - u32 rxLargeQLength; - u32 rxLargeBufferLength; - - /* RX Small Buffer Queue */ - u32 rxSmallQConsumerIndex; - u32 rxSmallQBaseAddrLow; - u32 rxSmallQBaseAddrHigh; - u32 rxSmallQLength; - u32 rxSmallBufferLength; - -}; - -/* - * port local RAM page - page 2 - */ -struct ql3xxx_local_ram_registers { - struct ql3xxx_common_registers CommonRegs; - u32 bufletSize; - u32 maxBufletCount; - u32 currentBufletCount; - u32 reserved; - u32 freeBufletThresholdLow; - u32 freeBufletThresholdHigh; - u32 ipHashTableBase; - u32 ipHashTableCount; - u32 tcpHashTableBase; - u32 tcpHashTableCount; - u32 ncbBase; - u32 maxNcbCount; - u32 currentNcbCount; - u32 drbBase; - u32 maxDrbCount; - u32 currentDrbCount; -}; - -/* - * definitions for Semaphore bits in Semaphore/Serial NVRAM interface register - */ - -#define LS_64BITS(x) (u32)(0xffffffff & ((u64)x)) -#define MS_64BITS(x) (u32)(0xffffffff & (((u64)x)>>16>>16) ) - -/* - * I/O register - */ - -enum { - CONTROL_REG = 0, - STATUS_REG = 1, - PHY_STAT_LINK_UP = 0x0004, - PHY_CTRL_LOOPBACK = 0x4000, - - PETBI_CONTROL_REG = 0x00, - PETBI_CTRL_SOFT_RESET = 0x8000, - PETBI_CTRL_AUTO_NEG = 0x1000, - PETBI_CTRL_RESTART_NEG = 0x0200, - PETBI_CTRL_FULL_DUPLEX = 0x0100, - PETBI_CTRL_SPEED_1000 = 0x0040, - - PETBI_STATUS_REG = 0x01, - PETBI_STAT_NEG_DONE = 0x0020, - PETBI_STAT_LINK_UP = 0x0004, - - PETBI_NEG_ADVER = 0x04, - PETBI_NEG_PAUSE = 0x0080, - PETBI_NEG_PAUSE_MASK = 0x0180, - PETBI_NEG_DUPLEX = 0x0020, - PETBI_NEG_DUPLEX_MASK = 0x0060, - - PETBI_NEG_PARTNER = 0x05, - PETBI_NEG_ERROR_MASK = 0x3000, - - PETBI_EXPANSION_REG = 0x06, - PETBI_EXP_PAGE_RX = 0x0002, - - PETBI_TBI_CTRL = 0x11, - PETBI_TBI_RESET = 0x8000, - PETBI_TBI_AUTO_SENSE = 0x0100, - PETBI_TBI_SERDES_MODE = 0x0010, - PETBI_TBI_SERDES_WRAP = 0x0002, - - AUX_CONTROL_STATUS = 0x1c, - PHY_AUX_NEG_DONE = 0x8000, - PHY_NEG_PARTNER = 5, - PHY_AUX_DUPLEX_STAT = 0x0020, - PHY_AUX_SPEED_STAT = 0x0018, - PHY_AUX_NO_HW_STRAP = 0x0004, - PHY_AUX_RESET_STICK = 0x0002, - PHY_NEG_PAUSE = 0x0400, - PHY_CTRL_SOFT_RESET = 0x8000, - PHY_NEG_ADVER = 4, - PHY_NEG_ADV_SPEED = 0x01e0, - PHY_CTRL_RESTART_NEG = 0x0200, -}; -enum { -/* AM29LV Flash definitions */ - FM93C56A_START = 0x1, -/* Commands */ - FM93C56A_READ = 0x2, - FM93C56A_WEN = 0x0, - FM93C56A_WRITE = 0x1, - FM93C56A_WRITE_ALL = 0x0, - FM93C56A_WDS = 0x0, - FM93C56A_ERASE = 0x3, - FM93C56A_ERASE_ALL = 0x0, -/* Command Extentions */ - FM93C56A_WEN_EXT = 0x3, - FM93C56A_WRITE_ALL_EXT = 0x1, - FM93C56A_WDS_EXT = 0x0, - FM93C56A_ERASE_ALL_EXT = 0x2, -/* Special Bits */ - FM93C56A_READ_DUMMY_BITS = 1, - FM93C56A_READY = 0, - FM93C56A_BUSY = 1, - FM93C56A_CMD_BITS = 2, -/* AM29LV Flash definitions */ - FM93C56A_SIZE_8 = 0x100, - FM93C56A_SIZE_16 = 0x80, - FM93C66A_SIZE_8 = 0x200, - FM93C66A_SIZE_16 = 0x100, - FM93C86A_SIZE_16 = 0x400, -/* Address Bits */ - FM93C56A_NO_ADDR_BITS_16 = 8, - FM93C56A_NO_ADDR_BITS_8 = 9, - FM93C86A_NO_ADDR_BITS_16 = 10, -/* Data Bits */ - FM93C56A_DATA_BITS_16 = 16, - FM93C56A_DATA_BITS_8 = 8, -}; -enum { -/* Auburn Bits */ - AUBURN_EEPROM_DI = 0x8, - AUBURN_EEPROM_DI_0 = 0x0, - AUBURN_EEPROM_DI_1 = 0x8, - AUBURN_EEPROM_DO = 0x4, - AUBURN_EEPROM_DO_0 = 0x0, - AUBURN_EEPROM_DO_1 = 0x4, - AUBURN_EEPROM_CS = 0x2, - AUBURN_EEPROM_CS_0 = 0x0, - AUBURN_EEPROM_CS_1 = 0x2, - AUBURN_EEPROM_CLK_RISE = 0x1, - AUBURN_EEPROM_CLK_FALL = 0x0, -}; -enum {EEPROM_SIZE = FM93C86A_SIZE_16, - EEPROM_NO_ADDR_BITS = FM93C86A_NO_ADDR_BITS_16, - EEPROM_NO_DATA_BITS = FM93C56A_DATA_BITS_16, -}; - -/* - * MAC Config data structure - */ - struct eeprom_port_cfg { - u16 etherMtu_mac; - u16 pauseThreshold_mac; - u16 resumeThreshold_mac; - u16 portConfiguration; -#define PORT_CONFIG_AUTO_NEG_ENABLED 0x8000 -#define PORT_CONFIG_SYM_PAUSE_ENABLED 0x4000 -#define PORT_CONFIG_FULL_DUPLEX_ENABLED 0x2000 -#define PORT_CONFIG_HALF_DUPLEX_ENABLED 0x1000 -#define PORT_CONFIG_1000MB_SPEED 0x0400 -#define PORT_CONFIG_100MB_SPEED 0x0200 -#define PORT_CONFIG_10MB_SPEED 0x0100 -#define PORT_CONFIG_LINK_SPEED_MASK 0x0F00 - u16 reserved[12]; - -}; - -/* - * BIOS data structure - */ -struct eeprom_bios_cfg { - u16 SpinDlyEn:1, disBios:1, EnMemMap:1, EnSelectBoot:1, Reserved:12; - - u8 bootID0:7, boodID0Valid:1; - u8 bootLun0[8]; - - u8 bootID1:7, boodID1Valid:1; - u8 bootLun1[8]; - - u16 MaxLunsTrgt; - u8 reserved[10]; -}; - -/* - * Function Specific Data structure - */ -struct eeprom_function_cfg { - u8 reserved[30]; - u8 macAddress[6]; - u8 macAddressSecondary[6]; - - u16 subsysVendorId; - u16 subsysDeviceId; -}; - -/* - * EEPROM format - */ -struct eeprom_data { - u8 asicId[4]; - u8 version; - u8 numPorts; - u16 boardId; - -#define EEPROM_BOARDID_STR_SIZE 16 -#define EEPROM_SERIAL_NUM_SIZE 16 - - u8 boardIdStr[16]; - u8 serialNumber[16]; - u16 extHwConfig; - struct eeprom_port_cfg macCfg_port0; - struct eeprom_port_cfg macCfg_port1; - u16 bufletSize; - u16 bufletCount; - u16 tcpWindowThreshold50; - u16 tcpWindowThreshold25; - u16 tcpWindowThreshold0; - u16 ipHashTableBaseHi; - u16 ipHashTableBaseLo; - u16 ipHashTableSize; - u16 tcpHashTableBaseHi; - u16 tcpHashTableBaseLo; - u16 tcpHashTableSize; - u16 ncbTableBaseHi; - u16 ncbTableBaseLo; - u16 ncbTableSize; - u16 drbTableBaseHi; - u16 drbTableBaseLo; - u16 drbTableSize; - u16 reserved_142[4]; - u16 ipReassemblyTimeout; - u16 tcpMaxWindowSize; - u16 ipSecurity; -#define IPSEC_CONFIG_PRESENT 0x0001 - u8 reserved_156[294]; - u16 qDebug[8]; - struct eeprom_function_cfg funcCfg_fn0; - u16 reserved_510; - u8 oemSpace[432]; - struct eeprom_bios_cfg biosCfg_fn1; - struct eeprom_function_cfg funcCfg_fn1; - u16 reserved_1022; - u8 reserved_1024[464]; - struct eeprom_function_cfg funcCfg_fn2; - u16 reserved_1534; - u8 reserved_1536[432]; - struct eeprom_bios_cfg biosCfg_fn3; - struct eeprom_function_cfg funcCfg_fn3; - u16 checksum; -}; - -/* - * General definitions... - */ - -/* - * Below are a number compiler switches for controlling driver behavior. - * Some are not supported under certain conditions and are notated as such. - */ - -#define QL3XXX_VENDOR_ID 0x1077 -#define QL3022_DEVICE_ID 0x3022 - -/* MTU & Frame Size stuff */ -#define NORMAL_MTU_SIZE ETH_DATA_LEN -#define JUMBO_MTU_SIZE 9000 -#define VLAN_ID_LEN 2 - -/* Request Queue Related Definitions */ -#define NUM_REQ_Q_ENTRIES 256 /* so that 64 * 64 = 4096 (1 page) */ - -/* Response Queue Related Definitions */ -#define NUM_RSP_Q_ENTRIES 256 /* so that 256 * 16 = 4096 (1 page) */ - -/* Transmit and Receive Buffers */ -#define NUM_LBUFQ_ENTRIES 128 -#define NUM_SBUFQ_ENTRIES 64 -#define QL_SMALL_BUFFER_SIZE 32 -#define QL_ADDR_ELE_PER_BUFQ_ENTRY \ -(sizeof(struct lrg_buf_q_entry) / sizeof(struct bufq_addr_element)) - /* Each send has at least control block. This is how many we keep. */ -#define NUM_SMALL_BUFFERS NUM_SBUFQ_ENTRIES * QL_ADDR_ELE_PER_BUFQ_ENTRY -#define NUM_LARGE_BUFFERS NUM_LBUFQ_ENTRIES * QL_ADDR_ELE_PER_BUFQ_ENTRY -#define QL_HEADER_SPACE 32 /* make header space at top of skb. */ -/* - * Large & Small Buffers for Receives - */ -struct lrg_buf_q_entry { - - u32 addr0_lower; -#define IAL_LAST_ENTRY 0x00000001 -#define IAL_CONT_ENTRY 0x00000002 -#define IAL_FLAG_MASK 0x00000003 - u32 addr0_upper; - u32 addr1_lower; - u32 addr1_upper; - u32 addr2_lower; - u32 addr2_upper; - u32 addr3_lower; - u32 addr3_upper; - u32 addr4_lower; - u32 addr4_upper; - u32 addr5_lower; - u32 addr5_upper; - u32 addr6_lower; - u32 addr6_upper; - u32 addr7_lower; - u32 addr7_upper; - -}; - -struct bufq_addr_element { - u32 addr_low; - u32 addr_high; -}; - -#define QL_NO_RESET 0 -#define QL_DO_RESET 1 - -enum link_state_t { - LS_UNKNOWN = 0, - LS_DOWN, - LS_DEGRADE, - LS_RECOVER, - LS_UP, -}; - -struct ql_rcv_buf_cb { - struct ql_rcv_buf_cb *next; - struct sk_buff *skb; - DECLARE_PCI_UNMAP_ADDR(mapaddr); - DECLARE_PCI_UNMAP_LEN(maplen); - __le32 buf_phy_addr_low; - __le32 buf_phy_addr_high; - int index; -}; - -struct ql_tx_buf_cb { - struct sk_buff *skb; - struct ob_mac_iocb_req *queue_entry ; - DECLARE_PCI_UNMAP_ADDR(mapaddr); - DECLARE_PCI_UNMAP_LEN(maplen); -}; - -/* definitions for type field */ -#define QL_BUF_TYPE_MACIOCB 0x01 -#define QL_BUF_TYPE_IPIOCB 0x02 -#define QL_BUF_TYPE_TCPIOCB 0x03 - -/* qdev->flags definitions. */ -enum { QL_RESET_DONE = 1, /* Reset finished. */ - QL_RESET_ACTIVE = 2, /* Waiting for reset to finish. */ - QL_RESET_START = 3, /* Please reset the chip. */ - QL_RESET_PER_SCSI = 4, /* SCSI driver requests reset. */ - QL_TX_TIMEOUT = 5, /* Timeout in progress. */ - QL_LINK_MASTER = 6, /* This driver controls the link. */ - QL_ADAPTER_UP = 7, /* Adapter has been brought up. */ - QL_THREAD_UP = 8, /* This flag is available. */ - QL_LINK_UP = 9, /* Link Status. */ - QL_ALLOC_REQ_RSP_Q_DONE = 10, - QL_ALLOC_BUFQS_DONE = 11, - QL_ALLOC_SMALL_BUF_DONE = 12, - QL_LINK_OPTICAL = 13, - QL_MSI_ENABLED = 14, -}; - -/* - * ql3_adapter - The main Adapter structure definition. - * This structure has all fields relevant to the hardware. - */ - -struct ql3_adapter { - u32 reserved_00; - unsigned long flags; - - /* PCI Configuration information for this device */ - struct pci_dev *pdev; - struct net_device *ndev; /* Parent NET device */ - - /* Hardware information */ - u8 chip_rev_id; - u8 pci_slot; - u8 pci_width; - u8 pci_x; - u32 msi; - int index; - struct timer_list adapter_timer; /* timer used for various functions */ - - spinlock_t adapter_lock; - spinlock_t hw_lock; - - /* PCI Bus Relative Register Addresses */ - u8 *mmap_virt_base; /* stores return value from ioremap() */ - struct ql3xxx_port_registers __iomem *mem_map_registers; - u32 current_page; /* tracks current register page */ - - u32 msg_enable; - u8 reserved_01[2]; - u8 reserved_02[2]; - - /* Page for Shadow Registers */ - void *shadow_reg_virt_addr; - dma_addr_t shadow_reg_phy_addr; - - /* Net Request Queue */ - u32 req_q_size; - u32 reserved_03; - struct ob_mac_iocb_req *req_q_virt_addr; - dma_addr_t req_q_phy_addr; - u16 req_producer_index; - u16 reserved_04; - u16 *preq_consumer_index; - u32 req_consumer_index_phy_addr_high; - u32 req_consumer_index_phy_addr_low; - atomic_t tx_count; - struct ql_tx_buf_cb tx_buf[NUM_REQ_Q_ENTRIES]; - - /* Net Response Queue */ - u32 rsp_q_size; - u32 eeprom_cmd_data; - struct net_rsp_iocb *rsp_q_virt_addr; - dma_addr_t rsp_q_phy_addr; - struct net_rsp_iocb *rsp_current; - u16 rsp_consumer_index; - u16 reserved_06; - u32 *prsp_producer_index; - u32 rsp_producer_index_phy_addr_high; - u32 rsp_producer_index_phy_addr_low; - - /* Large Buffer Queue */ - u32 lrg_buf_q_alloc_size; - u32 lrg_buf_q_size; - void *lrg_buf_q_alloc_virt_addr; - void *lrg_buf_q_virt_addr; - dma_addr_t lrg_buf_q_alloc_phy_addr; - dma_addr_t lrg_buf_q_phy_addr; - u32 lrg_buf_q_producer_index; - u32 lrg_buf_release_cnt; - struct bufq_addr_element *lrg_buf_next_free; - - /* Large (Receive) Buffers */ - struct ql_rcv_buf_cb lrg_buf[NUM_LARGE_BUFFERS]; - struct ql_rcv_buf_cb *lrg_buf_free_head; - struct ql_rcv_buf_cb *lrg_buf_free_tail; - u32 lrg_buf_free_count; - u32 lrg_buffer_len; - u32 lrg_buf_index; - u32 lrg_buf_skb_check; - - /* Small Buffer Queue */ - u32 small_buf_q_alloc_size; - u32 small_buf_q_size; - u32 small_buf_q_producer_index; - void *small_buf_q_alloc_virt_addr; - void *small_buf_q_virt_addr; - dma_addr_t small_buf_q_alloc_phy_addr; - dma_addr_t small_buf_q_phy_addr; - u32 small_buf_index; - - /* Small (Receive) Buffers */ - void *small_buf_virt_addr; - dma_addr_t small_buf_phy_addr; - u32 small_buf_phy_addr_low; - u32 small_buf_phy_addr_high; - u32 small_buf_release_cnt; - u32 small_buf_total_size; - - /* ISR related, saves status for DPC. */ - u32 control_status; - - struct eeprom_data nvram_data; - struct timer_list ioctl_timer; - u32 port_link_state; - u32 last_rsp_offset; - - /* 4022 specific */ - u32 mac_index; /* Driver's MAC number can be 0 or 1 for first and second networking functions respectively */ - u32 PHYAddr; /* Address of PHY 0x1e00 Port 0 and 0x1f00 Port 1 */ - u32 mac_ob_opcode; /* Opcode to use on mac transmission */ - u32 tcp_ob_opcode; /* Opcode to use on tcp transmission */ - u32 update_ob_opcode; /* Opcode to use for updating NCB */ - u32 mb_bit_mask; /* MA Bits mask to use on transmission */ - u32 numPorts; - struct net_device_stats stats; - struct workqueue_struct *workqueue; - struct work_struct reset_work; - struct work_struct tx_timeout_work; - u32 max_frame_size; -}; - -#endif /* _QLA3XXX_H_ */ diff --git a/trunk/drivers/net/r8169.c b/trunk/drivers/net/r8169.c index 5722a5638ffc..4c2f575faad7 100644 --- a/trunk/drivers/net/r8169.c +++ b/trunk/drivers/net/r8169.c @@ -2809,7 +2809,7 @@ static struct pci_driver rtl8169_pci_driver = { static int __init rtl8169_init_module(void) { - return pci_register_driver(&rtl8169_pci_driver); + return pci_module_init(&rtl8169_pci_driver); } static void __exit diff --git a/trunk/drivers/net/rrunner.c b/trunk/drivers/net/rrunner.c index 31bcdad54716..c3ed734cbe39 100644 --- a/trunk/drivers/net/rrunner.c +++ b/trunk/drivers/net/rrunner.c @@ -1736,7 +1736,7 @@ static struct pci_driver rr_driver = { static int __init rr_init_module(void) { - return pci_register_driver(&rr_driver); + return pci_module_init(&rr_driver); } static void __exit rr_cleanup_module(void) diff --git a/trunk/drivers/net/s2io.c b/trunk/drivers/net/s2io.c index c16f9156c98a..132ed32bce1a 100644 --- a/trunk/drivers/net/s2io.c +++ b/trunk/drivers/net/s2io.c @@ -71,7 +71,6 @@ #include #include #include -#include /* local include */ #include "s2io.h" @@ -7233,7 +7232,7 @@ static void __devexit s2io_rem_nic(struct pci_dev *pdev) int __init s2io_starter(void) { - return pci_register_driver(&s2io_driver); + return pci_module_init(&s2io_driver); } /** diff --git a/trunk/drivers/net/saa9730.c b/trunk/drivers/net/saa9730.c index c479b07be788..b2acedbefa8f 100644 --- a/trunk/drivers/net/saa9730.c +++ b/trunk/drivers/net/saa9730.c @@ -1131,7 +1131,7 @@ static struct pci_driver saa9730_driver = { static int __init saa9730_init(void) { - return pci_register_driver(&saa9730_driver); + return pci_module_init(&saa9730_driver); } static void __exit saa9730_cleanup(void) diff --git a/trunk/drivers/net/seeq8005.c b/trunk/drivers/net/seeq8005.c index 01392bca0223..efd0f235020f 100644 --- a/trunk/drivers/net/seeq8005.c +++ b/trunk/drivers/net/seeq8005.c @@ -742,7 +742,7 @@ module_param(irq, int, 0); MODULE_PARM_DESC(io, "SEEQ 8005 I/O base address"); MODULE_PARM_DESC(irq, "SEEQ 8005 IRQ number"); -int __init init_module(void) +int init_module(void) { dev_seeq = seeq8005_probe(-1); if (IS_ERR(dev_seeq)) diff --git a/trunk/drivers/net/sis190.c b/trunk/drivers/net/sis190.c index 16e30d523fc5..df0cbebb3277 100644 --- a/trunk/drivers/net/sis190.c +++ b/trunk/drivers/net/sis190.c @@ -1871,7 +1871,7 @@ static struct pci_driver sis190_pci_driver = { static int __init sis190_init_module(void) { - return pci_register_driver(&sis190_pci_driver); + return pci_module_init(&sis190_pci_driver); } static void __exit sis190_cleanup_module(void) diff --git a/trunk/drivers/net/sis900.c b/trunk/drivers/net/sis900.c index 6af50286349d..29ee7ffedfff 100644 --- a/trunk/drivers/net/sis900.c +++ b/trunk/drivers/net/sis900.c @@ -134,7 +134,6 @@ static const struct mii_chip_info { { "AMD 79C901 10BASE-T PHY", 0x0000, 0x6B70, LAN }, { "AMD 79C901 HomePNA PHY", 0x0000, 0x6B90, HOME}, { "ICS LAN PHY", 0x0015, 0xF440, LAN }, - { "ICS LAN PHY", 0x0143, 0xBC70, LAN }, { "NS 83851 PHY", 0x2000, 0x5C20, MIX }, { "NS 83847 PHY", 0x2000, 0x5C30, MIX }, { "Realtek RTL8201 PHY", 0x0000, 0x8200, LAN }, @@ -2496,7 +2495,7 @@ static int __init sis900_init_module(void) printk(version); #endif - return pci_register_driver(&sis900_pci_driver); + return pci_module_init(&sis900_pci_driver); } static void __exit sis900_cleanup_module(void) diff --git a/trunk/drivers/net/sk98lin/skge.c b/trunk/drivers/net/sk98lin/skge.c index 49e76c7f10da..ee62845d3ac9 100644 --- a/trunk/drivers/net/sk98lin/skge.c +++ b/trunk/drivers/net/sk98lin/skge.c @@ -5133,7 +5133,7 @@ static struct pci_driver skge_driver = { static int __init skge_init(void) { - return pci_register_driver(&skge_driver); + return pci_module_init(&skge_driver); } static void __exit skge_exit(void) diff --git a/trunk/drivers/net/skfp/skfddi.c b/trunk/drivers/net/skfp/skfddi.c index 8e4d18440a56..b5714a60237d 100644 --- a/trunk/drivers/net/skfp/skfddi.c +++ b/trunk/drivers/net/skfp/skfddi.c @@ -2280,7 +2280,7 @@ static struct pci_driver skfddi_pci_driver = { static int __init skfd_init(void) { - return pci_register_driver(&skfddi_pci_driver); + return pci_module_init(&skfddi_pci_driver); } static void __exit skfd_exit(void) diff --git a/trunk/drivers/net/skge.c b/trunk/drivers/net/skge.c index a1fc04365e07..7de9a07b2ac2 100644 --- a/trunk/drivers/net/skge.c +++ b/trunk/drivers/net/skge.c @@ -43,7 +43,7 @@ #include "skge.h" #define DRV_NAME "skge" -#define DRV_VERSION "1.7" +#define DRV_VERSION "1.6" #define PFX DRV_NAME " " #define DEFAULT_TX_RING_SIZE 128 @@ -827,8 +827,7 @@ static int skge_rx_fill(struct skge_port *skge) do { struct sk_buff *skb; - skb = __dev_alloc_skb(skge->rx_buf_size + NET_IP_ALIGN, - GFP_KERNEL); + skb = alloc_skb(skge->rx_buf_size + NET_IP_ALIGN, GFP_KERNEL); if (!skb) return -ENOMEM; @@ -2212,7 +2211,6 @@ static int skge_up(struct net_device *dev) skge_write8(hw, Q_ADDR(rxqaddr[port], Q_CSR), CSR_START | CSR_IRQ_CL_F); skge_led(skge, LED_MODE_ON); - netif_poll_enable(dev); return 0; free_rx_ring: @@ -2281,7 +2279,6 @@ static int skge_down(struct net_device *dev) skge_led(skge, LED_MODE_OFF); - netif_poll_disable(dev); skge_tx_clean(skge); skge_rx_clean(skge); @@ -2610,7 +2607,7 @@ static inline struct sk_buff *skge_rx_get(struct skge_port *skge, goto error; if (len < RX_COPY_THRESHOLD) { - skb = dev_alloc_skb(len + 2); + skb = alloc_skb(len + 2, GFP_ATOMIC); if (!skb) goto resubmit; @@ -2625,7 +2622,7 @@ static inline struct sk_buff *skge_rx_get(struct skge_port *skge, skge_rx_reuse(e, skge->rx_buf_size); } else { struct sk_buff *nskb; - nskb = dev_alloc_skb(skge->rx_buf_size + NET_IP_ALIGN); + nskb = alloc_skb(skge->rx_buf_size + NET_IP_ALIGN, GFP_ATOMIC); if (!nskb) goto resubmit; @@ -2748,7 +2745,7 @@ static int skge_poll(struct net_device *dev, int *budget) spin_lock_irq(&hw->hw_lock); hw->intr_mask |= rxirqmask[skge->port]; skge_write32(hw, B0_IMSK, hw->intr_mask); - skge_read32(hw, B0_IMSK); + mmiowb(); spin_unlock_irq(&hw->hw_lock); return 0; @@ -2882,7 +2879,6 @@ static void skge_extirq(void *arg) spin_lock_irq(&hw->hw_lock); hw->intr_mask |= IS_EXT_REG; skge_write32(hw, B0_IMSK, hw->intr_mask); - skge_read32(hw, B0_IMSK); spin_unlock_irq(&hw->hw_lock); } @@ -2957,7 +2953,6 @@ static irqreturn_t skge_intr(int irq, void *dev_id, struct pt_regs *regs) skge_error_irq(hw); skge_write32(hw, B0_IMSK, hw->intr_mask); - skge_read32(hw, B0_IMSK); spin_unlock(&hw->hw_lock); return IRQ_HANDLED; @@ -3109,6 +3104,7 @@ static int skge_reset(struct skge_hw *hw) else hw->ram_size = t8 * 4096; + spin_lock_init(&hw->hw_lock); hw->intr_mask = IS_HW_ERR | IS_EXT_REG | IS_PORT_1; if (hw->ports > 1) hw->intr_mask |= IS_PORT_2; @@ -3334,7 +3330,6 @@ static int __devinit skge_probe(struct pci_dev *pdev, hw->pdev = pdev; mutex_init(&hw->phy_mutex); INIT_WORK(&hw->phy_work, skge_extirq, hw); - spin_lock_init(&hw->hw_lock); hw->regs = ioremap_nocache(pci_resource_start(pdev, 0), 0x4000); if (!hw->regs) { @@ -3343,16 +3338,23 @@ static int __devinit skge_probe(struct pci_dev *pdev, goto err_out_free_hw; } + err = request_irq(pdev->irq, skge_intr, IRQF_SHARED, DRV_NAME, hw); + if (err) { + printk(KERN_ERR PFX "%s: cannot assign irq %d\n", + pci_name(pdev), pdev->irq); + goto err_out_iounmap; + } + pci_set_drvdata(pdev, hw); + err = skge_reset(hw); if (err) - goto err_out_iounmap; + goto err_out_free_irq; printk(KERN_INFO PFX DRV_VERSION " addr 0x%llx irq %d chip %s rev %d\n", (unsigned long long)pci_resource_start(pdev, 0), pdev->irq, skge_board_name(hw), hw->chip_rev); - dev = skge_devinit(hw, 0, using_dac); - if (!dev) + if ((dev = skge_devinit(hw, 0, using_dac)) == NULL) goto err_out_led_off; if (!is_valid_ether_addr(dev->dev_addr)) { @@ -3362,6 +3364,7 @@ static int __devinit skge_probe(struct pci_dev *pdev, goto err_out_free_netdev; } + err = register_netdev(dev); if (err) { printk(KERN_ERR PFX "%s: cannot register net device\n", @@ -3369,12 +3372,6 @@ static int __devinit skge_probe(struct pci_dev *pdev, goto err_out_free_netdev; } - err = request_irq(pdev->irq, skge_intr, IRQF_SHARED, dev->name, hw); - if (err) { - printk(KERN_ERR PFX "%s: cannot assign irq %d\n", - dev->name, pdev->irq); - goto err_out_unregister; - } skge_show_addr(dev); if (hw->ports > 1 && (dev1 = skge_devinit(hw, 1, using_dac))) { @@ -3387,16 +3384,15 @@ static int __devinit skge_probe(struct pci_dev *pdev, free_netdev(dev1); } } - pci_set_drvdata(pdev, hw); return 0; -err_out_unregister: - unregister_netdev(dev); err_out_free_netdev: free_netdev(dev); err_out_led_off: skge_write16(hw, B0_LED, LED_STAT_OFF); +err_out_free_irq: + free_irq(pdev->irq, hw); err_out_iounmap: iounmap(hw->regs); err_out_free_hw: @@ -3426,7 +3422,6 @@ static void __devexit skge_remove(struct pci_dev *pdev) spin_lock_irq(&hw->hw_lock); hw->intr_mask = 0; skge_write32(hw, B0_IMSK, 0); - skge_read32(hw, B0_IMSK); spin_unlock_irq(&hw->hw_lock); skge_write16(hw, B0_LED, LED_STAT_OFF); @@ -3452,25 +3447,26 @@ static int skge_suspend(struct pci_dev *pdev, pm_message_t state) struct skge_hw *hw = pci_get_drvdata(pdev); int i, wol = 0; - pci_save_state(pdev); - for (i = 0; i < hw->ports; i++) { + for (i = 0; i < 2; i++) { struct net_device *dev = hw->dev[i]; - if (netif_running(dev)) { + if (dev) { struct skge_port *skge = netdev_priv(dev); - - netif_carrier_off(dev); - if (skge->wol) - netif_stop_queue(dev); - else - skge_down(dev); + if (netif_running(dev)) { + netif_carrier_off(dev); + if (skge->wol) + netif_stop_queue(dev); + else + skge_down(dev); + } + netif_device_detach(dev); wol |= skge->wol; } - netif_device_detach(dev); } - skge_write32(hw, B0_IMSK, 0); + pci_save_state(pdev); pci_enable_wake(pdev, pci_choose_state(pdev, state), wol); + pci_disable_device(pdev); pci_set_power_state(pdev, pci_choose_state(pdev, state)); return 0; @@ -3479,33 +3475,23 @@ static int skge_suspend(struct pci_dev *pdev, pm_message_t state) static int skge_resume(struct pci_dev *pdev) { struct skge_hw *hw = pci_get_drvdata(pdev); - int i, err; + int i; pci_set_power_state(pdev, PCI_D0); pci_restore_state(pdev); pci_enable_wake(pdev, PCI_D0, 0); - err = skge_reset(hw); - if (err) - goto out; + skge_reset(hw); - for (i = 0; i < hw->ports; i++) { + for (i = 0; i < 2; i++) { struct net_device *dev = hw->dev[i]; - - netif_device_attach(dev); - if (netif_running(dev)) { - err = skge_up(dev); - - if (err) { - printk(KERN_ERR PFX "%s: could not up: %d\n", - dev->name, err); + if (dev) { + netif_device_attach(dev); + if (netif_running(dev) && skge_up(dev)) dev_close(dev); - goto out; - } } } -out: - return err; + return 0; } #endif @@ -3522,7 +3508,7 @@ static struct pci_driver skge_driver = { static int __init skge_init_module(void) { - return pci_register_driver(&skge_driver); + return pci_module_init(&skge_driver); } static void __exit skge_cleanup_module(void) diff --git a/trunk/drivers/net/sky2.c b/trunk/drivers/net/sky2.c index f37fe8fabe7b..de91609ca112 100644 --- a/trunk/drivers/net/sky2.c +++ b/trunk/drivers/net/sky2.c @@ -50,7 +50,7 @@ #include "sky2.h" #define DRV_NAME "sky2" -#define DRV_VERSION "1.7" +#define DRV_VERSION "1.5" #define PFX DRV_NAME " " /* @@ -121,11 +121,6 @@ static const struct pci_device_id sky2_id_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4361) }, { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4362) }, { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4363) }, - { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4364) }, - { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4365) }, - { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4366) }, - { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4367) }, - { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4368) }, { 0 } }; @@ -195,6 +190,7 @@ static u16 gm_phy_read(struct sky2_hw *hw, unsigned port, u16 reg) static void sky2_set_power_state(struct sky2_hw *hw, pci_power_t state) { u16 power_control; + u32 reg1; int vaux; pr_debug("sky2_set_power_state %d\n", state); @@ -227,9 +223,18 @@ static void sky2_set_power_state(struct sky2_hw *hw, pci_power_t state) else sky2_write8(hw, B2_Y2_CLK_GATE, 0); - if (hw->chip_id == CHIP_ID_YUKON_EC_U) { - u32 reg1; + /* Turn off phy power saving */ + reg1 = sky2_pci_read32(hw, PCI_DEV_REG1); + reg1 &= ~(PCI_Y2_PHY1_POWD | PCI_Y2_PHY2_POWD); + + /* looks like this XL is back asswards .. */ + if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > 1) { + reg1 |= PCI_Y2_PHY1_COMA; + if (hw->ports > 1) + reg1 |= PCI_Y2_PHY2_COMA; + } + if (hw->chip_id == CHIP_ID_YUKON_EC_U) { sky2_pci_write32(hw, PCI_DEV_REG3, 0); reg1 = sky2_pci_read32(hw, PCI_DEV_REG4); reg1 &= P_ASPM_CONTROL_MSK; @@ -237,10 +242,22 @@ static void sky2_set_power_state(struct sky2_hw *hw, pci_power_t state) sky2_pci_write32(hw, PCI_DEV_REG5, 0); } + sky2_pci_write32(hw, PCI_DEV_REG1, reg1); + udelay(100); + break; case PCI_D3hot: case PCI_D3cold: + /* Turn on phy power saving */ + reg1 = sky2_pci_read32(hw, PCI_DEV_REG1); + if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > 1) + reg1 &= ~(PCI_Y2_PHY1_POWD | PCI_Y2_PHY2_POWD); + else + reg1 |= (PCI_Y2_PHY1_POWD | PCI_Y2_PHY2_POWD); + sky2_pci_write32(hw, PCI_DEV_REG1, reg1); + udelay(100); + if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > 1) sky2_write8(hw, B2_Y2_CLK_GATE, 0); else @@ -264,7 +281,7 @@ static void sky2_set_power_state(struct sky2_hw *hw, pci_power_t state) sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); } -static void sky2_gmac_reset(struct sky2_hw *hw, unsigned port) +static void sky2_phy_reset(struct sky2_hw *hw, unsigned port) { u16 reg; @@ -512,29 +529,6 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port) gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_DEF_MSK); } -static void sky2_phy_power(struct sky2_hw *hw, unsigned port, int onoff) -{ - u32 reg1; - static const u32 phy_power[] - = { PCI_Y2_PHY1_POWD, PCI_Y2_PHY2_POWD }; - - /* looks like this XL is back asswards .. */ - if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > 1) - onoff = !onoff; - - reg1 = sky2_pci_read32(hw, PCI_DEV_REG1); - - if (onoff) - /* Turn off phy power saving */ - reg1 &= ~phy_power[port]; - else - reg1 |= phy_power[port]; - - sky2_pci_write32(hw, PCI_DEV_REG1, reg1); - sky2_pci_read32(hw, PCI_DEV_REG1); - udelay(100); -} - /* Force a renegotiation */ static void sky2_phy_reinit(struct sky2_port *sky2) { @@ -767,10 +761,9 @@ static inline struct sky2_tx_le *get_tx_le(struct sky2_port *sky2) /* Update chip's next pointer */ static inline void sky2_put_idx(struct sky2_hw *hw, unsigned q, u16 idx) { - q = Y2_QADDR(q, PREF_UNIT_PUT_IDX); wmb(); - sky2_write16(hw, q, idx); - sky2_read16(hw, q); + sky2_write16(hw, Y2_QADDR(q, PREF_UNIT_PUT_IDX), idx); + mmiowb(); } @@ -957,16 +950,14 @@ static void sky2_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) /* * It appears the hardware has a bug in the FIFO logic that * cause it to hang if the FIFO gets overrun and the receive buffer - * is not 64 byte aligned. The buffer returned from netdev_alloc_skb is - * aligned except if slab debugging is enabled. + * is not aligned. ALso alloc_skb() won't align properly if slab + * debugging is enabled. */ -static inline struct sk_buff *sky2_alloc_skb(struct net_device *dev, - unsigned int length, - gfp_t gfp_mask) +static inline struct sk_buff *sky2_alloc_skb(unsigned int size, gfp_t gfp_mask) { struct sk_buff *skb; - skb = __netdev_alloc_skb(dev, length + RX_SKB_ALIGN, gfp_mask); + skb = alloc_skb(size + RX_SKB_ALIGN, gfp_mask); if (likely(skb)) { unsigned long p = (unsigned long) skb->data; skb_reserve(skb, ALIGN(p, RX_SKB_ALIGN) - p); @@ -1002,8 +993,7 @@ static int sky2_rx_start(struct sky2_port *sky2) for (i = 0; i < sky2->rx_pending; i++) { struct ring_info *re = sky2->rx_ring + i; - re->skb = sky2_alloc_skb(sky2->netdev, sky2->rx_bufsize, - GFP_KERNEL); + re->skb = sky2_alloc_skb(sky2->rx_bufsize, GFP_KERNEL); if (!re->skb) goto nomem; @@ -1091,8 +1081,6 @@ static int sky2_up(struct net_device *dev) if (!sky2->rx_ring) goto err_out; - sky2_phy_power(hw, port, 1); - sky2_mac_init(hw, port); /* Determine available ram buffer space (in 4K blocks). @@ -1197,6 +1185,7 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev) struct sky2_tx_le *le = NULL; struct tx_ring_info *re; unsigned i, len; + int avail; dma_addr_t mapping; u32 addr64; u16 mss; @@ -1246,18 +1235,25 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev) /* Check for TCP Segmentation Offload */ mss = skb_shinfo(skb)->gso_size; if (mss != 0) { + /* just drop the packet if non-linear expansion fails */ + if (skb_header_cloned(skb) && + pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) { + dev_kfree_skb(skb); + goto out_unlock; + } + mss += ((skb->h.th->doff - 5) * 4); /* TCP options */ mss += (skb->nh.iph->ihl * 4) + sizeof(struct tcphdr); mss += ETH_HLEN; + } - if (mss != sky2->tx_last_mss) { - le = get_tx_le(sky2); - le->tx.tso.size = cpu_to_le16(mss); - le->tx.tso.rsvd = 0; - le->opcode = OP_LRGLEN | HW_OWNER; - le->ctrl = 0; - sky2->tx_last_mss = mss; - } + if (mss != sky2->tx_last_mss) { + le = get_tx_le(sky2); + le->tx.tso.size = cpu_to_le16(mss); + le->tx.tso.rsvd = 0; + le->opcode = OP_LRGLEN | HW_OWNER; + le->ctrl = 0; + sky2->tx_last_mss = mss; } ctrl = 0; @@ -1285,17 +1281,12 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev) if (skb->nh.iph->protocol == IPPROTO_UDP) ctrl |= UDPTCP; - if (hdr != sky2->tx_csum_start || offset != sky2->tx_csum_offset) { - sky2->tx_csum_start = hdr; - sky2->tx_csum_offset = offset; - - le = get_tx_le(sky2); - le->tx.csum.start = cpu_to_le16(hdr); - le->tx.csum.offset = cpu_to_le16(offset); - le->length = 0; /* initial checksum value */ - le->ctrl = 1; /* one packet */ - le->opcode = OP_TCPLISW | HW_OWNER; - } + le = get_tx_le(sky2); + le->tx.csum.start = cpu_to_le16(hdr); + le->tx.csum.offset = cpu_to_le16(offset); + le->length = 0; /* initial checksum value */ + le->ctrl = 1; /* one packet */ + le->opcode = OP_TCPLISW | HW_OWNER; } le = get_tx_le(sky2); @@ -1330,18 +1321,23 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev) le->opcode = OP_BUFFER | HW_OWNER; fre = sky2->tx_ring - + RING_NEXT((re - sky2->tx_ring) + i, TX_RING_SIZE); + + RING_NEXT((re - sky2->tx_ring) + i, TX_RING_SIZE); pci_unmap_addr_set(fre, mapaddr, mapping); } re->idx = sky2->tx_prod; le->ctrl |= EOP; - if (tx_avail(sky2) <= MAX_SKB_TX_LE) - netif_stop_queue(dev); + avail = tx_avail(sky2); + if (mss != 0 || avail < TX_MIN_PENDING) { + le->ctrl |= FRC_STAT; + if (avail <= MAX_SKB_TX_LE) + netif_stop_queue(dev); + } sky2_put_idx(hw, txqaddr[sky2->port], sky2->tx_prod); +out_unlock: spin_unlock(&sky2->tx_lock); dev->trans_start = jiffies; @@ -1426,7 +1422,7 @@ static int sky2_down(struct net_device *dev) /* Stop more packets from being queued */ netif_stop_queue(dev); - sky2_gmac_reset(hw, port); + sky2_phy_reset(hw, port); /* Stop transmitter */ sky2_write32(hw, Q_ADDR(txqaddr[port], Q_CSR), BMU_STOP); @@ -1474,8 +1470,6 @@ static int sky2_down(struct net_device *dev) imask &= ~portirq_msk[port]; sky2_write32(hw, B0_IMSK, imask); - sky2_phy_power(hw, port, 0); - /* turn off LED's */ sky2_write16(hw, B0_Y2LED, LED_STAT_OFF); @@ -1839,16 +1833,15 @@ static int sky2_change_mtu(struct net_device *dev, int new_mtu) * For small packets or errors, just reuse existing skb. * For larger packets, get new buffer. */ -static struct sk_buff *sky2_receive(struct net_device *dev, +static struct sk_buff *sky2_receive(struct sky2_port *sky2, u16 length, u32 status) { - struct sky2_port *sky2 = netdev_priv(dev); struct ring_info *re = sky2->rx_ring + sky2->rx_next; struct sk_buff *skb = NULL; if (unlikely(netif_msg_rx_status(sky2))) printk(KERN_DEBUG PFX "%s: rx slot %u status 0x%x len %d\n", - dev->name, sky2->rx_next, status, length); + sky2->netdev->name, sky2->rx_next, status, length); sky2->rx_next = (sky2->rx_next + 1) % sky2->rx_pending; prefetch(sky2->rx_ring + sky2->rx_next); @@ -1859,11 +1852,11 @@ static struct sk_buff *sky2_receive(struct net_device *dev, if (!(status & GMR_FS_RX_OK)) goto resubmit; - if (length > dev->mtu + ETH_HLEN) + if (length > sky2->netdev->mtu + ETH_HLEN) goto oversize; if (length < copybreak) { - skb = netdev_alloc_skb(dev, length + 2); + skb = alloc_skb(length + 2, GFP_ATOMIC); if (!skb) goto resubmit; @@ -1878,7 +1871,7 @@ static struct sk_buff *sky2_receive(struct net_device *dev, } else { struct sk_buff *nskb; - nskb = sky2_alloc_skb(dev, sky2->rx_bufsize, GFP_ATOMIC); + nskb = sky2_alloc_skb(sky2->rx_bufsize, GFP_ATOMIC); if (!nskb) goto resubmit; @@ -1908,7 +1901,7 @@ static struct sk_buff *sky2_receive(struct net_device *dev, if (netif_msg_rx_err(sky2) && net_ratelimit()) printk(KERN_INFO PFX "%s: rx error, status 0x%x length %d\n", - dev->name, status, length); + sky2->netdev->name, status, length); if (status & (GMR_FS_LONG_ERR | GMR_FS_UN_SIZE)) sky2->net_stats.rx_length_errors++; @@ -1934,6 +1927,12 @@ static inline void sky2_tx_done(struct net_device *dev, u16 last) } } +/* Is status ring empty or is there more to do? */ +static inline int sky2_more_work(const struct sky2_hw *hw) +{ + return (hw->st_idx != sky2_read16(hw, STAT_PUT_IDX)); +} + /* Process status response ring */ static int sky2_status_intr(struct sky2_hw *hw, int to_do) { @@ -1962,10 +1961,11 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do) switch (le->opcode & ~HW_OWNER) { case OP_RXSTAT: - skb = sky2_receive(dev, length, status); + skb = sky2_receive(sky2, length, status); if (!skb) break; + skb->dev = dev; skb->protocol = eth_type_trans(skb, dev); dev->last_rx = jiffies; @@ -2023,9 +2023,6 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do) } } - /* Fully processed status ring so clear irq */ - sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ); - exit_loop: if (buf_write[0]) { sky2 = netdev_priv(hw->dev[0]); @@ -2235,16 +2232,19 @@ static int sky2_poll(struct net_device *dev0, int *budget) sky2_descriptor_error(hw, 1, "transmit", Y2_IS_CHK_TXA2); work_done = sky2_status_intr(hw, work_limit); - if (work_done < work_limit) { - netif_rx_complete(dev0); + *budget -= work_done; + dev0->quota -= work_done; - sky2_read32(hw, B0_Y2_SP_LISR); - return 0; - } else { - *budget -= work_done; - dev0->quota -= work_done; + if (status & Y2_IS_STAT_BMU) + sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ); + + if (sky2_more_work(hw)) return 1; - } + + netif_rx_complete(dev0); + + sky2_read32(hw, B0_Y2_SP_LISR); + return 0; } static irqreturn_t sky2_intr(int irq, void *dev_id, struct pt_regs *regs) @@ -2410,7 +2410,7 @@ static int sky2_reset(struct sky2_hw *hw) sky2_write32(hw, B0_HWE_IMSK, Y2_HWE_ALL_MASK); for (i = 0; i < hw->ports; i++) - sky2_gmac_reset(hw, i); + sky2_phy_reset(hw, i); memset(hw->st_le, 0, STATUS_LE_BYTES); hw->st_idx = 0; @@ -3201,8 +3201,6 @@ static int __devinit sky2_test_msi(struct sky2_hw *hw) struct pci_dev *pdev = hw->pdev; int err; - init_waitqueue_head (&hw->msi_wait); - sky2_write32(hw, B0_IMSK, Y2_IS_IRQ_SW); err = request_irq(pdev->irq, sky2_test_intr, IRQF_SHARED, DRV_NAME, hw); @@ -3212,8 +3210,10 @@ static int __devinit sky2_test_msi(struct sky2_hw *hw) return err; } + init_waitqueue_head (&hw->msi_wait); + sky2_write8(hw, B0_CTST, CS_ST_SW_IRQ); - sky2_read8(hw, B0_CTST); + wmb(); wait_event_timeout(hw->msi_wait, hw->msi_detected, HZ/10); diff --git a/trunk/drivers/net/sky2.h b/trunk/drivers/net/sky2.h index fa8af9f503e4..2db8d19b22d1 100644 --- a/trunk/drivers/net/sky2.h +++ b/trunk/drivers/net/sky2.h @@ -1748,6 +1748,7 @@ enum { INIT_SUM= 1<<3, LOCK_SUM= 1<<4, INS_VLAN= 1<<5, + FRC_STAT= 1<<6, EOP = 1<<7, }; @@ -1843,8 +1844,6 @@ struct sky2_port { u32 tx_addr64; u16 tx_pending; u16 tx_last_mss; - u16 tx_csum_start; - u16 tx_csum_offset; struct ring_info *rx_ring ____cacheline_aligned_in_smp; struct sky2_rx_le *rx_le; diff --git a/trunk/drivers/net/slhc.c b/trunk/drivers/net/slhc.c index 9a540e2092b9..3a1b7131681c 100644 --- a/trunk/drivers/net/slhc.c +++ b/trunk/drivers/net/slhc.c @@ -94,23 +94,27 @@ slhc_init(int rslots, int tslots) register struct cstate *ts; struct slcompress *comp; - comp = kzalloc(sizeof(struct slcompress), GFP_KERNEL); + comp = (struct slcompress *)kmalloc(sizeof(struct slcompress), + GFP_KERNEL); if (! comp) goto out_fail; + memset(comp, 0, sizeof(struct slcompress)); if ( rslots > 0 && rslots < 256 ) { size_t rsize = rslots * sizeof(struct cstate); - comp->rstate = kzalloc(rsize, GFP_KERNEL); + comp->rstate = (struct cstate *) kmalloc(rsize, GFP_KERNEL); if (! comp->rstate) goto out_free; + memset(comp->rstate, 0, rsize); comp->rslot_limit = rslots - 1; } if ( tslots > 0 && tslots < 256 ) { size_t tsize = tslots * sizeof(struct cstate); - comp->tstate = kzalloc(tsize, GFP_KERNEL); + comp->tstate = (struct cstate *) kmalloc(tsize, GFP_KERNEL); if (! comp->tstate) goto out_free2; + memset(comp->tstate, 0, tsize); comp->tslot_limit = tslots - 1; } @@ -137,9 +141,9 @@ slhc_init(int rslots, int tslots) return comp; out_free2: - kfree(comp->rstate); + kfree((unsigned char *)comp->rstate); out_free: - kfree(comp); + kfree((unsigned char *)comp); out_fail: return NULL; } @@ -696,6 +700,20 @@ EXPORT_SYMBOL(slhc_compress); EXPORT_SYMBOL(slhc_uncompress); EXPORT_SYMBOL(slhc_toss); +#ifdef MODULE + +int init_module(void) +{ + printk(KERN_INFO "CSLIP: code copyright 1989 Regents of the University of California\n"); + return 0; +} + +void cleanup_module(void) +{ + return; +} + +#endif /* MODULE */ #else /* CONFIG_INET */ diff --git a/trunk/drivers/net/smc911x.c b/trunk/drivers/net/smc911x.c index 4438fe8c9499..d37bd860b336 100644 --- a/trunk/drivers/net/smc911x.c +++ b/trunk/drivers/net/smc911x.c @@ -55,6 +55,8 @@ static const char version[] = ) #endif + +#include #include #include #include @@ -1090,7 +1092,6 @@ static irqreturn_t smc911x_interrupt(int irq, void *dev_id, struct pt_regs *regs /* Spurious interrupt check */ if ((SMC_GET_IRQ_CFG() & (INT_CFG_IRQ_INT_ | INT_CFG_IRQ_EN_)) != (INT_CFG_IRQ_INT_ | INT_CFG_IRQ_EN_)) { - spin_unlock_irqrestore(&lp->lock, flags); return IRQ_NONE; } diff --git a/trunk/drivers/net/smc91x.c b/trunk/drivers/net/smc91x.c index cf62373b808b..3d8dcb6c8758 100644 --- a/trunk/drivers/net/smc91x.c +++ b/trunk/drivers/net/smc91x.c @@ -321,12 +321,12 @@ static void smc_reset(struct net_device *dev) DBG(2, "%s: %s\n", dev->name, __FUNCTION__); /* Disable all interrupts, block TX tasklet */ - spin_lock_irq(&lp->lock); + spin_lock(&lp->lock); SMC_SELECT_BANK(2); SMC_SET_INT_MASK(0); pending_skb = lp->pending_tx_skb; lp->pending_tx_skb = NULL; - spin_unlock_irq(&lp->lock); + spin_unlock(&lp->lock); /* free any pending tx skb */ if (pending_skb) { @@ -448,12 +448,12 @@ static void smc_shutdown(struct net_device *dev) DBG(2, "%s: %s\n", CARDNAME, __FUNCTION__); /* no more interrupts for me */ - spin_lock_irq(&lp->lock); + spin_lock(&lp->lock); SMC_SELECT_BANK(2); SMC_SET_INT_MASK(0); pending_skb = lp->pending_tx_skb; lp->pending_tx_skb = NULL; - spin_unlock_irq(&lp->lock); + spin_unlock(&lp->lock); if (pending_skb) dev_kfree_skb(pending_skb); diff --git a/trunk/drivers/net/smc91x.h b/trunk/drivers/net/smc91x.h index 7aa7fbac8224..4ec4b4d23ae5 100644 --- a/trunk/drivers/net/smc91x.h +++ b/trunk/drivers/net/smc91x.h @@ -136,9 +136,14 @@ #define SMC_CAN_USE_32BIT 0 #define SMC_IO_SHIFT 0 #define SMC_NOWAIT 1 +#define SMC_USE_PXA_DMA 1 +#define SMC_inb(a, r) readb((a) + (r)) #define SMC_inw(a, r) readw((a) + (r)) +#define SMC_inl(a, r) readl((a) + (r)) +#define SMC_outb(v, a, r) writeb(v, (a) + (r)) #define SMC_outw(v, a, r) writew(v, (a) + (r)) +#define SMC_outl(v, a, r) writel(v, (a) + (r)) #define SMC_insw(a, r, p, l) readsw((a) + (r), p, l) #define SMC_outsw(a, r, p, l) writesw((a) + (r), p, l) @@ -184,10 +189,16 @@ SMC_outw(u16 val, void __iomem *ioaddr, int reg) #define SMC_IO_SHIFT 0 #define SMC_NOWAIT 1 +#define SMC_inb(a, r) readb((a) + (r)) +#define SMC_outb(v, a, r) writeb(v, (a) + (r)) #define SMC_inw(a, r) readw((a) + (r)) #define SMC_outw(v, a, r) writew(v, (a) + (r)) #define SMC_insw(a, r, p, l) readsw((a) + (r), p, l) #define SMC_outsw(a, r, p, l) writesw((a) + (r), p, l) +#define SMC_inl(a, r) readl((a) + (r)) +#define SMC_outl(v, a, r) writel(v, (a) + (r)) +#define SMC_insl(a, r, p, l) readsl((a) + (r), p, l) +#define SMC_outsl(a, r, p, l) writesl((a) + (r), p, l) #include #include @@ -361,24 +372,6 @@ static inline void LPD7_SMC_outsw (unsigned char* a, int r, #define SMC_IRQ_FLAGS (0) -#elif defined(CONFIG_ARCH_VERSATILE) - -#define SMC_CAN_USE_8BIT 1 -#define SMC_CAN_USE_16BIT 1 -#define SMC_CAN_USE_32BIT 1 -#define SMC_NOWAIT 1 - -#define SMC_inb(a, r) readb((a) + (r)) -#define SMC_inw(a, r) readw((a) + (r)) -#define SMC_inl(a, r) readl((a) + (r)) -#define SMC_outb(v, a, r) writeb(v, (a) + (r)) -#define SMC_outw(v, a, r) writew(v, (a) + (r)) -#define SMC_outl(v, a, r) writel(v, (a) + (r)) -#define SMC_insl(a, r, p, l) readsl((a) + (r), p, l) -#define SMC_outsl(a, r, p, l) writesl((a) + (r), p, l) - -#define SMC_IRQ_FLAGS (0) - #else #define SMC_CAN_USE_8BIT 1 diff --git a/trunk/drivers/net/spider_net.c b/trunk/drivers/net/spider_net.c index 88907218457a..647f62e9707d 100644 --- a/trunk/drivers/net/spider_net.c +++ b/trunk/drivers/net/spider_net.c @@ -1611,12 +1611,13 @@ spider_net_open(struct net_device *netdev) int result; result = -ENOMEM; - if (spider_net_init_chain(card, &card->tx_chain, card->descr, - PCI_DMA_TODEVICE, card->tx_desc)) + if (spider_net_init_chain(card, &card->tx_chain, + card->descr, + PCI_DMA_TODEVICE, tx_descriptors)) goto alloc_tx_failed; if (spider_net_init_chain(card, &card->rx_chain, - card->descr + card->rx_desc, - PCI_DMA_FROMDEVICE, card->rx_desc)) + card->descr + tx_descriptors, + PCI_DMA_FROMDEVICE, rx_descriptors)) goto alloc_rx_failed; /* allocate rx skbs */ @@ -2004,9 +2005,6 @@ spider_net_setup_netdev(struct spider_net_card *card) card->options.rx_csum = SPIDER_NET_RX_CSUM_DEFAULT; - card->tx_desc = tx_descriptors; - card->rx_desc = rx_descriptors; - spider_net_setup_netdev_ops(netdev); netdev->features = NETIF_F_HW_CSUM | NETIF_F_LLTX; diff --git a/trunk/drivers/net/spider_net.h b/trunk/drivers/net/spider_net.h index 30407cdf0892..f6dcf180ae3d 100644 --- a/trunk/drivers/net/spider_net.h +++ b/trunk/drivers/net/spider_net.h @@ -440,9 +440,6 @@ struct spider_net_card { /* for ethtool */ int msg_enable; - int rx_desc; - int tx_desc; - struct spider_net_descr descr[0]; }; diff --git a/trunk/drivers/net/spider_net_ethtool.c b/trunk/drivers/net/spider_net_ethtool.c index 02209222b8c9..a5bb0b7633af 100644 --- a/trunk/drivers/net/spider_net_ethtool.c +++ b/trunk/drivers/net/spider_net_ethtool.c @@ -130,18 +130,6 @@ spider_net_ethtool_set_tx_csum(struct net_device *netdev, uint32_t data) return 0; } -static void -spider_net_ethtool_get_ringparam(struct net_device *netdev, - struct ethtool_ringparam *ering) -{ - struct spider_net_card *card = netdev->priv; - - ering->tx_max_pending = SPIDER_NET_TX_DESCRIPTORS_MAX; - ering->tx_pending = card->tx_desc; - ering->rx_max_pending = SPIDER_NET_RX_DESCRIPTORS_MAX; - ering->rx_pending = card->rx_desc; -} - struct ethtool_ops spider_net_ethtool_ops = { .get_settings = spider_net_ethtool_get_settings, .get_drvinfo = spider_net_ethtool_get_drvinfo, @@ -153,6 +141,5 @@ struct ethtool_ops spider_net_ethtool_ops = { .set_rx_csum = spider_net_ethtool_set_rx_csum, .get_tx_csum = spider_net_ethtool_get_tx_csum, .set_tx_csum = spider_net_ethtool_set_tx_csum, - .get_ringparam = spider_net_ethtool_get_ringparam, }; diff --git a/trunk/drivers/net/starfire.c b/trunk/drivers/net/starfire.c index 8e1f6206b7d0..c0a62b00ffc8 100644 --- a/trunk/drivers/net/starfire.c +++ b/trunk/drivers/net/starfire.c @@ -2053,7 +2053,7 @@ static int __init starfire_init (void) return -ENODEV; } - return pci_register_driver(&starfire_driver); + return pci_module_init (&starfire_driver); } diff --git a/trunk/drivers/net/sundance.c b/trunk/drivers/net/sundance.c index c243a80f4006..ac17377b3e9f 100644 --- a/trunk/drivers/net/sundance.c +++ b/trunk/drivers/net/sundance.c @@ -17,8 +17,6 @@ Support and updates available at http://www.scyld.com/network/sundance.html [link no longer provides useful info -jgarzik] - Archives of the mailing list are still available at - http://www.beowulf.org/pipermail/netdrivers/ */ @@ -109,7 +107,7 @@ static char *media[MAX_UNITS]; #endif /* These identify the driver base version and may not be removed. */ -static char version[] = +static char version[] __devinitdata = KERN_INFO DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " Written by Donald Becker\n" KERN_INFO " http://www.scyld.com/network/sundance.html\n"; @@ -648,7 +646,7 @@ static int __devinit sundance_probe1 (struct pci_dev *pdev, /* Reset the chip to erase previous misconfiguration. */ if (netif_msg_hw(np)) printk("ASIC Control is %x.\n", ioread32(ioaddr + ASICCtrl)); - sundance_reset(dev, 0x00ff << 16); + iowrite16(0x00ff, ioaddr + ASICCtrl + 2); if (netif_msg_hw(np)) printk("ASIC Control is now %x.\n", ioread32(ioaddr + ASICCtrl)); @@ -1077,8 +1075,13 @@ reset_tx (struct net_device *dev) /* Reset tx logic, TxListPtr will be cleaned */ iowrite16 (TxDisable, ioaddr + MACCtrl1); - sundance_reset(dev, (NetworkReset|FIFOReset|DMAReset|TxReset) << 16); - + iowrite16 (TxReset | DMAReset | FIFOReset | NetworkReset, + ioaddr + ASICCtrl + 2); + for (i=50; i > 0; i--) { + if ((ioread16(ioaddr + ASICCtrl + 2) & ResetBusy) == 0) + break; + mdelay(1); + } /* free all tx skbuff */ for (i = 0; i < TX_RING_SIZE; i++) { skb = np->tx_skbuff[i]; @@ -1733,7 +1736,7 @@ static int __init sundance_init(void) #ifdef MODULE printk(version); #endif - return pci_register_driver(&sundance_driver); + return pci_module_init(&sundance_driver); } static void __exit sundance_exit(void) diff --git a/trunk/drivers/net/sungem.c b/trunk/drivers/net/sungem.c index 1a441a8a2add..b70bbd748978 100644 --- a/trunk/drivers/net/sungem.c +++ b/trunk/drivers/net/sungem.c @@ -3194,7 +3194,7 @@ static struct pci_driver gem_driver = { static int __init gem_init(void) { - return pci_register_driver(&gem_driver); + return pci_module_init(&gem_driver); } static void __exit gem_cleanup(void) diff --git a/trunk/drivers/net/sunlance.c b/trunk/drivers/net/sunlance.c index ec0413609f36..0e3fdf7c6dd3 100644 --- a/trunk/drivers/net/sunlance.c +++ b/trunk/drivers/net/sunlance.c @@ -1566,21 +1566,20 @@ static int __exit sunlance_sun4_remove(void) static int __devinit sunlance_sbus_probe(struct of_device *dev, const struct of_device_id *match) { struct sbus_dev *sdev = to_sbus_device(&dev->dev); + struct device_node *dp = dev->node; int err; - if (sdev->parent) { - struct of_device *parent = &sdev->parent->ofdev; + if (!strcmp(dp->name, "le")) { + err = sparc_lance_probe_one(sdev, NULL, NULL); + } else if (!strcmp(dp->name, "ledma")) { + struct sbus_dma *ledma = find_ledma(sdev); - if (!strcmp(parent->node->name, "ledma")) { - struct sbus_dma *ledma = find_ledma(to_sbus_device(&parent->dev)); + err = sparc_lance_probe_one(sdev->child, ledma, NULL); + } else { + BUG_ON(strcmp(dp->name, "lebuffer")); - err = sparc_lance_probe_one(sdev, ledma, NULL); - } else if (!strcmp(parent->node->name, "lebuffer")) { - err = sparc_lance_probe_one(sdev, NULL, to_sbus_device(&parent->dev)); - } else - err = sparc_lance_probe_one(sdev, NULL, NULL); - } else - err = sparc_lance_probe_one(sdev, NULL, NULL); + err = sparc_lance_probe_one(sdev->child, NULL, sdev); + } return err; } @@ -1605,6 +1604,12 @@ static struct of_device_id sunlance_sbus_match[] = { { .name = "le", }, + { + .name = "ledma", + }, + { + .name = "lebuffer", + }, {}, }; diff --git a/trunk/drivers/net/tc35815.c b/trunk/drivers/net/tc35815.c index 39460fa916fe..8b53ded66d37 100644 --- a/trunk/drivers/net/tc35815.c +++ b/trunk/drivers/net/tc35815.c @@ -1725,7 +1725,7 @@ static struct pci_driver tc35815_driver = { static int __init tc35815_init_module(void) { - return pci_register_driver(&tc35815_driver); + return pci_module_init(&tc35815_driver); } static void __exit tc35815_cleanup_module(void) diff --git a/trunk/drivers/net/tg3.c b/trunk/drivers/net/tg3.c index d6e2a6869f28..eafabb253f08 100644 --- a/trunk/drivers/net/tg3.c +++ b/trunk/drivers/net/tg3.c @@ -11819,7 +11819,7 @@ static struct pci_driver tg3_driver = { static int __init tg3_init(void) { - return pci_register_driver(&tg3_driver); + return pci_module_init(&tg3_driver); } static void __exit tg3_cleanup(void) diff --git a/trunk/drivers/net/tokenring/3c359.c b/trunk/drivers/net/tokenring/3c359.c index 412390ba142e..465921e3874c 100644 --- a/trunk/drivers/net/tokenring/3c359.c +++ b/trunk/drivers/net/tokenring/3c359.c @@ -1815,7 +1815,7 @@ static struct pci_driver xl_3c359_driver = { static int __init xl_pci_init (void) { - return pci_register_driver(&xl_3c359_driver); + return pci_module_init (&xl_3c359_driver); } diff --git a/trunk/drivers/net/tokenring/ibmtr.c b/trunk/drivers/net/tokenring/ibmtr.c index 4470025ff7f8..9f491563944e 100644 --- a/trunk/drivers/net/tokenring/ibmtr.c +++ b/trunk/drivers/net/tokenring/ibmtr.c @@ -140,7 +140,7 @@ in the event that chatty debug messages are desired - jjs 12/30/98 */ /* version and credits */ #ifndef PCMCIA -static char version[] __devinitdata = +static char version[] __initdata = "\nibmtr.c: v1.3.57 8/ 7/94 Peter De Schrijver and Mark Swanson\n" " v2.1.125 10/20/98 Paul Norton \n" " v2.2.0 12/30/98 Joel Sloan \n" @@ -216,7 +216,7 @@ static int __devinitdata turbo_irq[IBMTR_MAX_ADAPTERS] = {0}; static int __devinitdata turbo_searched = 0; #ifndef PCMCIA -static __u32 ibmtr_mem_base __devinitdata = 0xd0000; +static __u32 ibmtr_mem_base __initdata = 0xd0000; #endif static void __devinit PrtChanID(char *pcid, short stride) diff --git a/trunk/drivers/net/tokenring/lanstreamer.c b/trunk/drivers/net/tokenring/lanstreamer.c index 0d66700c6ced..28d968ffd5d0 100644 --- a/trunk/drivers/net/tokenring/lanstreamer.c +++ b/trunk/drivers/net/tokenring/lanstreamer.c @@ -1998,7 +1998,7 @@ static struct pci_driver streamer_pci_driver = { }; static int __init streamer_init_module(void) { - return pci_register_driver(&streamer_pci_driver); + return pci_module_init(&streamer_pci_driver); } static void __exit streamer_cleanup_module(void) { diff --git a/trunk/drivers/net/tokenring/smctr.c b/trunk/drivers/net/tokenring/smctr.c index 85a7f797d343..cd2e0251e2bc 100644 --- a/trunk/drivers/net/tokenring/smctr.c +++ b/trunk/drivers/net/tokenring/smctr.c @@ -5666,7 +5666,7 @@ module_param_array(io, int, NULL, 0); module_param_array(irq, int, NULL, 0); module_param(ringspeed, int, 0); -static struct net_device * __init setup_card(int n) +static struct net_device *setup_card(int n) { struct net_device *dev = alloc_trdev(sizeof(struct net_local)); int err; @@ -5696,8 +5696,9 @@ static struct net_device * __init setup_card(int n) free_netdev(dev); return ERR_PTR(err); } + -int __init init_module(void) +int init_module(void) { int i, found = 0; struct net_device *dev; diff --git a/trunk/drivers/net/tulip/de2104x.c b/trunk/drivers/net/tulip/de2104x.c index 350a73e99a85..d05c5aa254ee 100644 --- a/trunk/drivers/net/tulip/de2104x.c +++ b/trunk/drivers/net/tulip/de2104x.c @@ -2172,7 +2172,7 @@ static int __init de_init (void) #ifdef MODULE printk("%s", version); #endif - return pci_register_driver(&de_driver); + return pci_module_init (&de_driver); } static void __exit de_exit (void) diff --git a/trunk/drivers/net/tulip/de4x5.c b/trunk/drivers/net/tulip/de4x5.c index e661d0a9cc64..75ff14a55239 100644 --- a/trunk/drivers/net/tulip/de4x5.c +++ b/trunk/drivers/net/tulip/de4x5.c @@ -5754,7 +5754,7 @@ static int __init de4x5_module_init (void) int err = 0; #ifdef CONFIG_PCI - err = pci_register_driver(&de4x5_pci_driver); + err = pci_module_init (&de4x5_pci_driver); #endif #ifdef CONFIG_EISA err |= eisa_driver_register (&de4x5_eisa_driver); diff --git a/trunk/drivers/net/tulip/dmfe.c b/trunk/drivers/net/tulip/dmfe.c index 66dade556821..4e5b0f2acc39 100644 --- a/trunk/drivers/net/tulip/dmfe.c +++ b/trunk/drivers/net/tulip/dmfe.c @@ -2039,7 +2039,7 @@ static int __init dmfe_init_module(void) if (HPNA_NoiseFloor > 15) HPNA_NoiseFloor = 0; - rc = pci_register_driver(&dmfe_driver); + rc = pci_module_init(&dmfe_driver); if (rc < 0) return rc; diff --git a/trunk/drivers/net/tulip/tulip_core.c b/trunk/drivers/net/tulip/tulip_core.c index e1987ec493c2..7351831f57ce 100644 --- a/trunk/drivers/net/tulip/tulip_core.c +++ b/trunk/drivers/net/tulip/tulip_core.c @@ -1849,7 +1849,7 @@ static int __init tulip_init (void) tulip_max_interrupt_work = max_interrupt_work; /* probe for and init boards */ - return pci_register_driver(&tulip_driver); + return pci_module_init (&tulip_driver); } diff --git a/trunk/drivers/net/tulip/uli526x.c b/trunk/drivers/net/tulip/uli526x.c index c4c720e2d4c3..fd64b2b3e99c 100644 --- a/trunk/drivers/net/tulip/uli526x.c +++ b/trunk/drivers/net/tulip/uli526x.c @@ -1702,6 +1702,7 @@ MODULE_PARM_DESC(mode, "ULi M5261/M5263: Bit 0: 10/100Mbps, bit 2: duplex, bit 8 static int __init uli526x_init_module(void) { + int rc; printk(version); printed_version = 1; @@ -1713,19 +1714,22 @@ static int __init uli526x_init_module(void) if (cr6set) uli526x_cr6_user_set = cr6set; - switch (mode) { + switch(mode) { case ULI526X_10MHF: case ULI526X_100MHF: case ULI526X_10MFD: case ULI526X_100MFD: uli526x_media_mode = mode; break; - default: - uli526x_media_mode = ULI526X_AUTO; + default:uli526x_media_mode = ULI526X_AUTO; break; } - return pci_register_driver(&uli526x_driver); + rc = pci_module_init(&uli526x_driver); + if (rc < 0) + return rc; + + return 0; } diff --git a/trunk/drivers/net/tulip/winbond-840.c b/trunk/drivers/net/tulip/winbond-840.c index 6b82d1498223..7f414815cc62 100644 --- a/trunk/drivers/net/tulip/winbond-840.c +++ b/trunk/drivers/net/tulip/winbond-840.c @@ -138,7 +138,7 @@ static int full_duplex[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1}; #include /* These identify the driver base version and may not be removed. */ -static char version[] = +static char version[] __devinitdata = KERN_INFO DRV_NAME ".c:v" DRV_VERSION " (2.4 port) " DRV_RELDATE " Donald Becker \n" KERN_INFO " http://www.scyld.com/network/drivers.html\n"; @@ -1689,7 +1689,7 @@ static struct pci_driver w840_driver = { static int __init w840_init(void) { printk(version); - return pci_register_driver(&w840_driver); + return pci_module_init(&w840_driver); } static void __exit w840_exit(void) diff --git a/trunk/drivers/net/tulip/xircom_cb.c b/trunk/drivers/net/tulip/xircom_cb.c index cf43390d2c80..f874e4f6ccf6 100644 --- a/trunk/drivers/net/tulip/xircom_cb.c +++ b/trunk/drivers/net/tulip/xircom_cb.c @@ -1264,7 +1264,8 @@ static void investigate_write_descriptor(struct net_device *dev, struct xircom_p static int __init xircom_init(void) { - return pci_register_driver(&xircom_ops); + pci_register_driver(&xircom_ops); + return 0; } static void __exit xircom_exit(void) diff --git a/trunk/drivers/net/tulip/xircom_tulip_cb.c b/trunk/drivers/net/tulip/xircom_tulip_cb.c index d797b7b2e35f..17ca7dc42e6f 100644 --- a/trunk/drivers/net/tulip/xircom_tulip_cb.c +++ b/trunk/drivers/net/tulip/xircom_tulip_cb.c @@ -1707,7 +1707,7 @@ static int __init xircom_init(void) #ifdef MODULE printk(version); #endif - return pci_register_driver(&xircom_driver); + return pci_module_init(&xircom_driver); } diff --git a/trunk/drivers/net/typhoon.c b/trunk/drivers/net/typhoon.c index 1014461178cc..4103c37172f9 100644 --- a/trunk/drivers/net/typhoon.c +++ b/trunk/drivers/net/typhoon.c @@ -2660,7 +2660,7 @@ static struct pci_driver typhoon_driver = { static int __init typhoon_init(void) { - return pci_register_driver(&typhoon_driver); + return pci_module_init(&typhoon_driver); } static void __exit diff --git a/trunk/drivers/net/ucc_geth.c b/trunk/drivers/net/ucc_geth.c deleted file mode 100644 index 47f49ef72bdc..000000000000 --- a/trunk/drivers/net/ucc_geth.c +++ /dev/null @@ -1,4278 +0,0 @@ -/* - * Copyright (C) Freescale Semicondutor, Inc. 2006. All rights reserved. - * - * Author: Shlomi Gridish - * - * Description: - * QE UCC Gigabit Ethernet Driver - * - * Changelog: - * Jul 6, 2006 Li Yang - * - Rearrange code and style fixes - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "ucc_geth.h" -#include "ucc_geth_phy.h" - -#undef DEBUG - -#define DRV_DESC "QE UCC Gigabit Ethernet Controller version:June 20, 2006" -#define DRV_NAME "ucc_geth" - -#define ugeth_printk(level, format, arg...) \ - printk(level format "\n", ## arg) - -#define ugeth_dbg(format, arg...) \ - ugeth_printk(KERN_DEBUG , format , ## arg) -#define ugeth_err(format, arg...) \ - ugeth_printk(KERN_ERR , format , ## arg) -#define ugeth_info(format, arg...) \ - ugeth_printk(KERN_INFO , format , ## arg) -#define ugeth_warn(format, arg...) \ - ugeth_printk(KERN_WARNING , format , ## arg) - -#ifdef UGETH_VERBOSE_DEBUG -#define ugeth_vdbg ugeth_dbg -#else -#define ugeth_vdbg(fmt, args...) do { } while (0) -#endif /* UGETH_VERBOSE_DEBUG */ - -static DEFINE_SPINLOCK(ugeth_lock); - -static ucc_geth_info_t ugeth_primary_info = { - .uf_info = { - .bd_mem_part = MEM_PART_SYSTEM, - .rtsm = UCC_FAST_SEND_IDLES_BETWEEN_FRAMES, - .max_rx_buf_length = 1536, -/* FIXME: should be changed in run time for 1G and 100M */ -#ifdef CONFIG_UGETH_HAS_GIGA - .urfs = UCC_GETH_URFS_GIGA_INIT, - .urfet = UCC_GETH_URFET_GIGA_INIT, - .urfset = UCC_GETH_URFSET_GIGA_INIT, - .utfs = UCC_GETH_UTFS_GIGA_INIT, - .utfet = UCC_GETH_UTFET_GIGA_INIT, - .utftt = UCC_GETH_UTFTT_GIGA_INIT, -#else - .urfs = UCC_GETH_URFS_INIT, - .urfet = UCC_GETH_URFET_INIT, - .urfset = UCC_GETH_URFSET_INIT, - .utfs = UCC_GETH_UTFS_INIT, - .utfet = UCC_GETH_UTFET_INIT, - .utftt = UCC_GETH_UTFTT_INIT, -#endif - .ufpt = 256, - .mode = UCC_FAST_PROTOCOL_MODE_ETHERNET, - .ttx_trx = UCC_FAST_GUMR_TRANSPARENT_TTX_TRX_NORMAL, - .tenc = UCC_FAST_TX_ENCODING_NRZ, - .renc = UCC_FAST_RX_ENCODING_NRZ, - .tcrc = UCC_FAST_16_BIT_CRC, - .synl = UCC_FAST_SYNC_LEN_NOT_USED, - }, - .numQueuesTx = 1, - .numQueuesRx = 1, - .extendedFilteringChainPointer = ((uint32_t) NULL), - .typeorlen = 3072 /*1536 */ , - .nonBackToBackIfgPart1 = 0x40, - .nonBackToBackIfgPart2 = 0x60, - .miminumInterFrameGapEnforcement = 0x50, - .backToBackInterFrameGap = 0x60, - .mblinterval = 128, - .nortsrbytetime = 5, - .fracsiz = 1, - .strictpriorityq = 0xff, - .altBebTruncation = 0xa, - .excessDefer = 1, - .maxRetransmission = 0xf, - .collisionWindow = 0x37, - .receiveFlowControl = 1, - .maxGroupAddrInHash = 4, - .maxIndAddrInHash = 4, - .prel = 7, - .maxFrameLength = 1518, - .minFrameLength = 64, - .maxD1Length = 1520, - .maxD2Length = 1520, - .vlantype = 0x8100, - .ecamptr = ((uint32_t) NULL), - .eventRegMask = UCCE_OTHER, - .pausePeriod = 0xf000, - .interruptcoalescingmaxvalue = {1, 1, 1, 1, 1, 1, 1, 1}, - .bdRingLenTx = { - TX_BD_RING_LEN, - TX_BD_RING_LEN, - TX_BD_RING_LEN, - TX_BD_RING_LEN, - TX_BD_RING_LEN, - TX_BD_RING_LEN, - TX_BD_RING_LEN, - TX_BD_RING_LEN}, - - .bdRingLenRx = { - RX_BD_RING_LEN, - RX_BD_RING_LEN, - RX_BD_RING_LEN, - RX_BD_RING_LEN, - RX_BD_RING_LEN, - RX_BD_RING_LEN, - RX_BD_RING_LEN, - RX_BD_RING_LEN}, - - .numStationAddresses = UCC_GETH_NUM_OF_STATION_ADDRESSES_1, - .largestexternallookupkeysize = - QE_FLTR_LARGEST_EXTERNAL_TABLE_LOOKUP_KEY_SIZE_NONE, - .statisticsMode = UCC_GETH_STATISTICS_GATHERING_MODE_NONE, - .vlanOperationTagged = UCC_GETH_VLAN_OPERATION_TAGGED_NOP, - .vlanOperationNonTagged = UCC_GETH_VLAN_OPERATION_NON_TAGGED_NOP, - .rxQoSMode = UCC_GETH_QOS_MODE_DEFAULT, - .aufc = UPSMR_AUTOMATIC_FLOW_CONTROL_MODE_NONE, - .padAndCrc = MACCFG2_PAD_AND_CRC_MODE_PAD_AND_CRC, - .numThreadsTx = UCC_GETH_NUM_OF_THREADS_4, - .numThreadsRx = UCC_GETH_NUM_OF_THREADS_4, - .riscTx = QE_RISC_ALLOCATION_RISC1_AND_RISC2, - .riscRx = QE_RISC_ALLOCATION_RISC1_AND_RISC2, -}; - -static ucc_geth_info_t ugeth_info[8]; - -#ifdef DEBUG -static void mem_disp(u8 *addr, int size) -{ - u8 *i; - int size16Aling = (size >> 4) << 4; - int size4Aling = (size >> 2) << 2; - int notAlign = 0; - if (size % 16) - notAlign = 1; - - for (i = addr; (u32) i < (u32) addr + size16Aling; i += 16) - printk("0x%08x: %08x %08x %08x %08x\r\n", - (u32) i, - *((u32 *) (i)), - *((u32 *) (i + 4)), - *((u32 *) (i + 8)), *((u32 *) (i + 12))); - if (notAlign == 1) - printk("0x%08x: ", (u32) i); - for (; (u32) i < (u32) addr + size4Aling; i += 4) - printk("%08x ", *((u32 *) (i))); - for (; (u32) i < (u32) addr + size; i++) - printk("%02x", *((u8 *) (i))); - if (notAlign == 1) - printk("\r\n"); -} -#endif /* DEBUG */ - -#ifdef CONFIG_UGETH_FILTERING -static void enqueue(struct list_head *node, struct list_head *lh) -{ - unsigned long flags; - - spin_lock_irqsave(ugeth_lock, flags); - list_add_tail(node, lh); - spin_unlock_irqrestore(ugeth_lock, flags); -} -#endif /* CONFIG_UGETH_FILTERING */ - -static struct list_head *dequeue(struct list_head *lh) -{ - unsigned long flags; - - spin_lock_irqsave(ugeth_lock, flags); - if (!list_empty(lh)) { - struct list_head *node = lh->next; - list_del(node); - spin_unlock_irqrestore(ugeth_lock, flags); - return node; - } else { - spin_unlock_irqrestore(ugeth_lock, flags); - return NULL; - } -} - -static int get_interface_details(enet_interface_e enet_interface, - enet_speed_e *speed, - int *r10m, - int *rmm, - int *rpm, - int *tbi, int *limited_to_full_duplex) -{ - /* Analyze enet_interface according to Interface Mode - Configuration table */ - switch (enet_interface) { - case ENET_10_MII: - *speed = ENET_SPEED_10BT; - break; - case ENET_10_RMII: - *speed = ENET_SPEED_10BT; - *r10m = 1; - *rmm = 1; - break; - case ENET_10_RGMII: - *speed = ENET_SPEED_10BT; - *rpm = 1; - *r10m = 1; - *limited_to_full_duplex = 1; - break; - case ENET_100_MII: - *speed = ENET_SPEED_100BT; - break; - case ENET_100_RMII: - *speed = ENET_SPEED_100BT; - *rmm = 1; - break; - case ENET_100_RGMII: - *speed = ENET_SPEED_100BT; - *rpm = 1; - *limited_to_full_duplex = 1; - break; - case ENET_1000_GMII: - *speed = ENET_SPEED_1000BT; - *limited_to_full_duplex = 1; - break; - case ENET_1000_RGMII: - *speed = ENET_SPEED_1000BT; - *rpm = 1; - *limited_to_full_duplex = 1; - break; - case ENET_1000_TBI: - *speed = ENET_SPEED_1000BT; - *tbi = 1; - *limited_to_full_duplex = 1; - break; - case ENET_1000_RTBI: - *speed = ENET_SPEED_1000BT; - *rpm = 1; - *tbi = 1; - *limited_to_full_duplex = 1; - break; - default: - return -EINVAL; - break; - } - - return 0; -} - -static struct sk_buff *get_new_skb(ucc_geth_private_t *ugeth, u8 *bd) -{ - struct sk_buff *skb = NULL; - - skb = dev_alloc_skb(ugeth->ug_info->uf_info.max_rx_buf_length + - UCC_GETH_RX_DATA_BUF_ALIGNMENT); - - if (skb == NULL) - return NULL; - - /* We need the data buffer to be aligned properly. We will reserve - * as many bytes as needed to align the data properly - */ - skb_reserve(skb, - UCC_GETH_RX_DATA_BUF_ALIGNMENT - - (((unsigned)skb->data) & (UCC_GETH_RX_DATA_BUF_ALIGNMENT - - 1))); - - skb->dev = ugeth->dev; - - BD_BUFFER_SET(bd, - dma_map_single(NULL, - skb->data, - ugeth->ug_info->uf_info.max_rx_buf_length + - UCC_GETH_RX_DATA_BUF_ALIGNMENT, - DMA_FROM_DEVICE)); - - BD_STATUS_AND_LENGTH_SET(bd, - (R_E | R_I | - (BD_STATUS_AND_LENGTH(bd) & R_W))); - - return skb; -} - -static int rx_bd_buffer_set(ucc_geth_private_t *ugeth, u8 rxQ) -{ - u8 *bd; - u32 bd_status; - struct sk_buff *skb; - int i; - - bd = ugeth->p_rx_bd_ring[rxQ]; - i = 0; - - do { - bd_status = BD_STATUS_AND_LENGTH(bd); - skb = get_new_skb(ugeth, bd); - - if (!skb) /* If can not allocate data buffer, - abort. Cleanup will be elsewhere */ - return -ENOMEM; - - ugeth->rx_skbuff[rxQ][i] = skb; - - /* advance the BD pointer */ - bd += UCC_GETH_SIZE_OF_BD; - i++; - } while (!(bd_status & R_W)); - - return 0; -} - -static int fill_init_enet_entries(ucc_geth_private_t *ugeth, - volatile u32 *p_start, - u8 num_entries, - u32 thread_size, - u32 thread_alignment, - qe_risc_allocation_e risc, - int skip_page_for_first_entry) -{ - u32 init_enet_offset; - u8 i; - int snum; - - for (i = 0; i < num_entries; i++) { - if ((snum = qe_get_snum()) < 0) { - ugeth_err("fill_init_enet_entries: Can not get SNUM."); - return snum; - } - if ((i == 0) && skip_page_for_first_entry) - /* First entry of Rx does not have page */ - init_enet_offset = 0; - else { - init_enet_offset = - qe_muram_alloc(thread_size, thread_alignment); - if (IS_MURAM_ERR(init_enet_offset)) { - ugeth_err - ("fill_init_enet_entries: Can not allocate DPRAM memory."); - qe_put_snum((u8) snum); - return -ENOMEM; - } - } - *(p_start++) = - ((u8) snum << ENET_INIT_PARAM_SNUM_SHIFT) | init_enet_offset - | risc; - } - - return 0; -} - -static int return_init_enet_entries(ucc_geth_private_t *ugeth, - volatile u32 *p_start, - u8 num_entries, - qe_risc_allocation_e risc, - int skip_page_for_first_entry) -{ - u32 init_enet_offset; - u8 i; - int snum; - - for (i = 0; i < num_entries; i++) { - /* Check that this entry was actually valid -- - needed in case failed in allocations */ - if ((*p_start & ENET_INIT_PARAM_RISC_MASK) == risc) { - snum = - (u32) (*p_start & ENET_INIT_PARAM_SNUM_MASK) >> - ENET_INIT_PARAM_SNUM_SHIFT; - qe_put_snum((u8) snum); - if (!((i == 0) && skip_page_for_first_entry)) { - /* First entry of Rx does not have page */ - init_enet_offset = - (in_be32(p_start) & - ENET_INIT_PARAM_PTR_MASK); - qe_muram_free(init_enet_offset); - } - *(p_start++) = 0; /* Just for cosmetics */ - } - } - - return 0; -} - -#ifdef DEBUG -static int dump_init_enet_entries(ucc_geth_private_t *ugeth, - volatile u32 *p_start, - u8 num_entries, - u32 thread_size, - qe_risc_allocation_e risc, - int skip_page_for_first_entry) -{ - u32 init_enet_offset; - u8 i; - int snum; - - for (i = 0; i < num_entries; i++) { - /* Check that this entry was actually valid -- - needed in case failed in allocations */ - if ((*p_start & ENET_INIT_PARAM_RISC_MASK) == risc) { - snum = - (u32) (*p_start & ENET_INIT_PARAM_SNUM_MASK) >> - ENET_INIT_PARAM_SNUM_SHIFT; - qe_put_snum((u8) snum); - if (!((i == 0) && skip_page_for_first_entry)) { - /* First entry of Rx does not have page */ - init_enet_offset = - (in_be32(p_start) & - ENET_INIT_PARAM_PTR_MASK); - ugeth_info("Init enet entry %d:", i); - ugeth_info("Base address: 0x%08x", - (u32) - qe_muram_addr(init_enet_offset)); - mem_disp(qe_muram_addr(init_enet_offset), - thread_size); - } - p_start++; - } - } - - return 0; -} -#endif - -#ifdef CONFIG_UGETH_FILTERING -static enet_addr_container_t *get_enet_addr_container(void) -{ - enet_addr_container_t *enet_addr_cont; - - /* allocate memory */ - enet_addr_cont = kmalloc(sizeof(enet_addr_container_t), GFP_KERNEL); - if (!enet_addr_cont) { - ugeth_err("%s: No memory for enet_addr_container_t object.", - __FUNCTION__); - return NULL; - } - - return enet_addr_cont; -} -#endif /* CONFIG_UGETH_FILTERING */ - -static void put_enet_addr_container(enet_addr_container_t *enet_addr_cont) -{ - kfree(enet_addr_cont); -} - -#ifdef CONFIG_UGETH_FILTERING -static int hw_add_addr_in_paddr(ucc_geth_private_t *ugeth, - enet_addr_t *p_enet_addr, u8 paddr_num) -{ - ucc_geth_82xx_address_filtering_pram_t *p_82xx_addr_filt; - - if (!(paddr_num < NUM_OF_PADDRS)) { - ugeth_warn("%s: Illagel paddr_num.", __FUNCTION__); - return -EINVAL; - } - - p_82xx_addr_filt = - (ucc_geth_82xx_address_filtering_pram_t *) ugeth->p_rx_glbl_pram-> - addressfiltering; - - /* Ethernet frames are defined in Little Endian mode, */ - /* therefore to insert the address we reverse the bytes. */ - out_be16(&p_82xx_addr_filt->paddr[paddr_num].h, - (u16) (((u16) (((u16) ((*p_enet_addr)[5])) << 8)) | - (u16) (*p_enet_addr)[4])); - out_be16(&p_82xx_addr_filt->paddr[paddr_num].m, - (u16) (((u16) (((u16) ((*p_enet_addr)[3])) << 8)) | - (u16) (*p_enet_addr)[2])); - out_be16(&p_82xx_addr_filt->paddr[paddr_num].l, - (u16) (((u16) (((u16) ((*p_enet_addr)[1])) << 8)) | - (u16) (*p_enet_addr)[0])); - - return 0; -} -#endif /* CONFIG_UGETH_FILTERING */ - -static int hw_clear_addr_in_paddr(ucc_geth_private_t *ugeth, u8 paddr_num) -{ - ucc_geth_82xx_address_filtering_pram_t *p_82xx_addr_filt; - - if (!(paddr_num < NUM_OF_PADDRS)) { - ugeth_warn("%s: Illagel paddr_num.", __FUNCTION__); - return -EINVAL; - } - - p_82xx_addr_filt = - (ucc_geth_82xx_address_filtering_pram_t *) ugeth->p_rx_glbl_pram-> - addressfiltering; - - /* Writing address ff.ff.ff.ff.ff.ff disables address - recognition for this register */ - out_be16(&p_82xx_addr_filt->paddr[paddr_num].h, 0xffff); - out_be16(&p_82xx_addr_filt->paddr[paddr_num].m, 0xffff); - out_be16(&p_82xx_addr_filt->paddr[paddr_num].l, 0xffff); - - return 0; -} - -static void hw_add_addr_in_hash(ucc_geth_private_t *ugeth, - enet_addr_t *p_enet_addr) -{ - ucc_geth_82xx_address_filtering_pram_t *p_82xx_addr_filt; - u32 cecr_subblock; - - p_82xx_addr_filt = - (ucc_geth_82xx_address_filtering_pram_t *) ugeth->p_rx_glbl_pram-> - addressfiltering; - - cecr_subblock = - ucc_fast_get_qe_cr_subblock(ugeth->ug_info->uf_info.ucc_num); - - /* Ethernet frames are defined in Little Endian mode, - therefor to insert */ - /* the address to the hash (Big Endian mode), we reverse the bytes.*/ - out_be16(&p_82xx_addr_filt->taddr.h, - (u16) (((u16) (((u16) ((*p_enet_addr)[5])) << 8)) | - (u16) (*p_enet_addr)[4])); - out_be16(&p_82xx_addr_filt->taddr.m, - (u16) (((u16) (((u16) ((*p_enet_addr)[3])) << 8)) | - (u16) (*p_enet_addr)[2])); - out_be16(&p_82xx_addr_filt->taddr.l, - (u16) (((u16) (((u16) ((*p_enet_addr)[1])) << 8)) | - (u16) (*p_enet_addr)[0])); - - qe_issue_cmd(QE_SET_GROUP_ADDRESS, cecr_subblock, - (u8) QE_CR_PROTOCOL_ETHERNET, 0); -} - -#ifdef CONFIG_UGETH_MAGIC_PACKET -static void magic_packet_detection_enable(ucc_geth_private_t *ugeth) -{ - ucc_fast_private_t *uccf; - ucc_geth_t *ug_regs; - u32 maccfg2, uccm; - - uccf = ugeth->uccf; - ug_regs = ugeth->ug_regs; - - /* Enable interrupts for magic packet detection */ - uccm = in_be32(uccf->p_uccm); - uccm |= UCCE_MPD; - out_be32(uccf->p_uccm, uccm); - - /* Enable magic packet detection */ - maccfg2 = in_be32(&ug_regs->maccfg2); - maccfg2 |= MACCFG2_MPE; - out_be32(&ug_regs->maccfg2, maccfg2); -} - -static void magic_packet_detection_disable(ucc_geth_private_t *ugeth) -{ - ucc_fast_private_t *uccf; - ucc_geth_t *ug_regs; - u32 maccfg2, uccm; - - uccf = ugeth->uccf; - ug_regs = ugeth->ug_regs; - - /* Disable interrupts for magic packet detection */ - uccm = in_be32(uccf->p_uccm); - uccm &= ~UCCE_MPD; - out_be32(uccf->p_uccm, uccm); - - /* Disable magic packet detection */ - maccfg2 = in_be32(&ug_regs->maccfg2); - maccfg2 &= ~MACCFG2_MPE; - out_be32(&ug_regs->maccfg2, maccfg2); -} -#endif /* MAGIC_PACKET */ - -static inline int compare_addr(enet_addr_t *addr1, enet_addr_t *addr2) -{ - return memcmp(addr1, addr2, ENET_NUM_OCTETS_PER_ADDRESS); -} - -#ifdef DEBUG -static void get_statistics(ucc_geth_private_t *ugeth, - ucc_geth_tx_firmware_statistics_t * - tx_firmware_statistics, - ucc_geth_rx_firmware_statistics_t * - rx_firmware_statistics, - ucc_geth_hardware_statistics_t *hardware_statistics) -{ - ucc_fast_t *uf_regs; - ucc_geth_t *ug_regs; - ucc_geth_tx_firmware_statistics_pram_t *p_tx_fw_statistics_pram; - ucc_geth_rx_firmware_statistics_pram_t *p_rx_fw_statistics_pram; - - ug_regs = ugeth->ug_regs; - uf_regs = (ucc_fast_t *) ug_regs; - p_tx_fw_statistics_pram = ugeth->p_tx_fw_statistics_pram; - p_rx_fw_statistics_pram = ugeth->p_rx_fw_statistics_pram; - - /* Tx firmware only if user handed pointer and driver actually - gathers Tx firmware statistics */ - if (tx_firmware_statistics && p_tx_fw_statistics_pram) { - tx_firmware_statistics->sicoltx = - in_be32(&p_tx_fw_statistics_pram->sicoltx); - tx_firmware_statistics->mulcoltx = - in_be32(&p_tx_fw_statistics_pram->mulcoltx); - tx_firmware_statistics->latecoltxfr = - in_be32(&p_tx_fw_statistics_pram->latecoltxfr); - tx_firmware_statistics->frabortduecol = - in_be32(&p_tx_fw_statistics_pram->frabortduecol); - tx_firmware_statistics->frlostinmactxer = - in_be32(&p_tx_fw_statistics_pram->frlostinmactxer); - tx_firmware_statistics->carriersenseertx = - in_be32(&p_tx_fw_statistics_pram->carriersenseertx); - tx_firmware_statistics->frtxok = - in_be32(&p_tx_fw_statistics_pram->frtxok); - tx_firmware_statistics->txfrexcessivedefer = - in_be32(&p_tx_fw_statistics_pram->txfrexcessivedefer); - tx_firmware_statistics->txpkts256 = - in_be32(&p_tx_fw_statistics_pram->txpkts256); - tx_firmware_statistics->txpkts512 = - in_be32(&p_tx_fw_statistics_pram->txpkts512); - tx_firmware_statistics->txpkts1024 = - in_be32(&p_tx_fw_statistics_pram->txpkts1024); - tx_firmware_statistics->txpktsjumbo = - in_be32(&p_tx_fw_statistics_pram->txpktsjumbo); - } - - /* Rx firmware only if user handed pointer and driver actually - * gathers Rx firmware statistics */ - if (rx_firmware_statistics && p_rx_fw_statistics_pram) { - int i; - rx_firmware_statistics->frrxfcser = - in_be32(&p_rx_fw_statistics_pram->frrxfcser); - rx_firmware_statistics->fraligner = - in_be32(&p_rx_fw_statistics_pram->fraligner); - rx_firmware_statistics->inrangelenrxer = - in_be32(&p_rx_fw_statistics_pram->inrangelenrxer); - rx_firmware_statistics->outrangelenrxer = - in_be32(&p_rx_fw_statistics_pram->outrangelenrxer); - rx_firmware_statistics->frtoolong = - in_be32(&p_rx_fw_statistics_pram->frtoolong); - rx_firmware_statistics->runt = - in_be32(&p_rx_fw_statistics_pram->runt); - rx_firmware_statistics->verylongevent = - in_be32(&p_rx_fw_statistics_pram->verylongevent); - rx_firmware_statistics->symbolerror = - in_be32(&p_rx_fw_statistics_pram->symbolerror); - rx_firmware_statistics->dropbsy = - in_be32(&p_rx_fw_statistics_pram->dropbsy); - for (i = 0; i < 0x8; i++) - rx_firmware_statistics->res0[i] = - p_rx_fw_statistics_pram->res0[i]; - rx_firmware_statistics->mismatchdrop = - in_be32(&p_rx_fw_statistics_pram->mismatchdrop); - rx_firmware_statistics->underpkts = - in_be32(&p_rx_fw_statistics_pram->underpkts); - rx_firmware_statistics->pkts256 = - in_be32(&p_rx_fw_statistics_pram->pkts256); - rx_firmware_statistics->pkts512 = - in_be32(&p_rx_fw_statistics_pram->pkts512); - rx_firmware_statistics->pkts1024 = - in_be32(&p_rx_fw_statistics_pram->pkts1024); - rx_firmware_statistics->pktsjumbo = - in_be32(&p_rx_fw_statistics_pram->pktsjumbo); - rx_firmware_statistics->frlossinmacer = - in_be32(&p_rx_fw_statistics_pram->frlossinmacer); - rx_firmware_statistics->pausefr = - in_be32(&p_rx_fw_statistics_pram->pausefr); - for (i = 0; i < 0x4; i++) - rx_firmware_statistics->res1[i] = - p_rx_fw_statistics_pram->res1[i]; - rx_firmware_statistics->removevlan = - in_be32(&p_rx_fw_statistics_pram->removevlan); - rx_firmware_statistics->replacevlan = - in_be32(&p_rx_fw_statistics_pram->replacevlan); - rx_firmware_statistics->insertvlan = - in_be32(&p_rx_fw_statistics_pram->insertvlan); - } - - /* Hardware only if user handed pointer and driver actually - gathers hardware statistics */ - if (hardware_statistics && (in_be32(&uf_regs->upsmr) & UPSMR_HSE)) { - hardware_statistics->tx64 = in_be32(&ug_regs->tx64); - hardware_statistics->tx127 = in_be32(&ug_regs->tx127); - hardware_statistics->tx255 = in_be32(&ug_regs->tx255); - hardware_statistics->rx64 = in_be32(&ug_regs->rx64); - hardware_statistics->rx127 = in_be32(&ug_regs->rx127); - hardware_statistics->rx255 = in_be32(&ug_regs->rx255); - hardware_statistics->txok = in_be32(&ug_regs->txok); - hardware_statistics->txcf = in_be16(&ug_regs->txcf); - hardware_statistics->tmca = in_be32(&ug_regs->tmca); - hardware_statistics->tbca = in_be32(&ug_regs->tbca); - hardware_statistics->rxfok = in_be32(&ug_regs->rxfok); - hardware_statistics->rxbok = in_be32(&ug_regs->rxbok); - hardware_statistics->rbyt = in_be32(&ug_regs->rbyt); - hardware_statistics->rmca = in_be32(&ug_regs->rmca); - hardware_statistics->rbca = in_be32(&ug_regs->rbca); - } -} - -static void dump_bds(ucc_geth_private_t *ugeth) -{ - int i; - int length; - - for (i = 0; i < ugeth->ug_info->numQueuesTx; i++) { - if (ugeth->p_tx_bd_ring[i]) { - length = - (ugeth->ug_info->bdRingLenTx[i] * - UCC_GETH_SIZE_OF_BD); - ugeth_info("TX BDs[%d]", i); - mem_disp(ugeth->p_tx_bd_ring[i], length); - } - } - for (i = 0; i < ugeth->ug_info->numQueuesRx; i++) { - if (ugeth->p_rx_bd_ring[i]) { - length = - (ugeth->ug_info->bdRingLenRx[i] * - UCC_GETH_SIZE_OF_BD); - ugeth_info("RX BDs[%d]", i); - mem_disp(ugeth->p_rx_bd_ring[i], length); - } - } -} - -static void dump_regs(ucc_geth_private_t *ugeth) -{ - int i; - - ugeth_info("UCC%d Geth registers:", ugeth->ug_info->uf_info.ucc_num); - ugeth_info("Base address: 0x%08x", (u32) ugeth->ug_regs); - - ugeth_info("maccfg1 : addr - 0x%08x, val - 0x%08x", - (u32) & ugeth->ug_regs->maccfg1, - in_be32(&ugeth->ug_regs->maccfg1)); - ugeth_info("maccfg2 : addr - 0x%08x, val - 0x%08x", - (u32) & ugeth->ug_regs->maccfg2, - in_be32(&ugeth->ug_regs->maccfg2)); - ugeth_info("ipgifg : addr - 0x%08x, val - 0x%08x", - (u32) & ugeth->ug_regs->ipgifg, - in_be32(&ugeth->ug_regs->ipgifg)); - ugeth_info("hafdup : addr - 0x%08x, val - 0x%08x", - (u32) & ugeth->ug_regs->hafdup, - in_be32(&ugeth->ug_regs->hafdup)); - ugeth_info("miimcfg : addr - 0x%08x, val - 0x%08x", - (u32) & ugeth->ug_regs->miimng.miimcfg, - in_be32(&ugeth->ug_regs->miimng.miimcfg)); - ugeth_info("miimcom : addr - 0x%08x, val - 0x%08x", - (u32) & ugeth->ug_regs->miimng.miimcom, - in_be32(&ugeth->ug_regs->miimng.miimcom)); - ugeth_info("miimadd : addr - 0x%08x, val - 0x%08x", - (u32) & ugeth->ug_regs->miimng.miimadd, - in_be32(&ugeth->ug_regs->miimng.miimadd)); - ugeth_info("miimcon : addr - 0x%08x, val - 0x%08x", - (u32) & ugeth->ug_regs->miimng.miimcon, - in_be32(&ugeth->ug_regs->miimng.miimcon)); - ugeth_info("miimstat : addr - 0x%08x, val - 0x%08x", - (u32) & ugeth->ug_regs->miimng.miimstat, - in_be32(&ugeth->ug_regs->miimng.miimstat)); - ugeth_info("miimmind : addr - 0x%08x, val - 0x%08x", - (u32) & ugeth->ug_regs->miimng.miimind, - in_be32(&ugeth->ug_regs->miimng.miimind)); - ugeth_info("ifctl : addr - 0x%08x, val - 0x%08x", - (u32) & ugeth->ug_regs->ifctl, - in_be32(&ugeth->ug_regs->ifctl)); - ugeth_info("ifstat : addr - 0x%08x, val - 0x%08x", - (u32) & ugeth->ug_regs->ifstat, - in_be32(&ugeth->ug_regs->ifstat)); - ugeth_info("macstnaddr1: addr - 0x%08x, val - 0x%08x", - (u32) & ugeth->ug_regs->macstnaddr1, - in_be32(&ugeth->ug_regs->macstnaddr1)); - ugeth_info("macstnaddr2: addr - 0x%08x, val - 0x%08x", - (u32) & ugeth->ug_regs->macstnaddr2, - in_be32(&ugeth->ug_regs->macstnaddr2)); - ugeth_info("uempr : addr - 0x%08x, val - 0x%08x", - (u32) & ugeth->ug_regs->uempr, - in_be32(&ugeth->ug_regs->uempr)); - ugeth_info("utbipar : addr - 0x%08x, val - 0x%08x", - (u32) & ugeth->ug_regs->utbipar, - in_be32(&ugeth->ug_regs->utbipar)); - ugeth_info("uescr : addr - 0x%08x, val - 0x%04x", - (u32) & ugeth->ug_regs->uescr, - in_be16(&ugeth->ug_regs->uescr)); - ugeth_info("tx64 : addr - 0x%08x, val - 0x%08x", - (u32) & ugeth->ug_regs->tx64, - in_be32(&ugeth->ug_regs->tx64)); - ugeth_info("tx127 : addr - 0x%08x, val - 0x%08x", - (u32) & ugeth->ug_regs->tx127, - in_be32(&ugeth->ug_regs->tx127)); - ugeth_info("tx255 : addr - 0x%08x, val - 0x%08x", - (u32) & ugeth->ug_regs->tx255, - in_be32(&ugeth->ug_regs->tx255)); - ugeth_info("rx64 : addr - 0x%08x, val - 0x%08x", - (u32) & ugeth->ug_regs->rx64, - in_be32(&ugeth->ug_regs->rx64)); - ugeth_info("rx127 : addr - 0x%08x, val - 0x%08x", - (u32) & ugeth->ug_regs->rx127, - in_be32(&ugeth->ug_regs->rx127)); - ugeth_info("rx255 : addr - 0x%08x, val - 0x%08x", - (u32) & ugeth->ug_regs->rx255, - in_be32(&ugeth->ug_regs->rx255)); - ugeth_info("txok : addr - 0x%08x, val - 0x%08x", - (u32) & ugeth->ug_regs->txok, - in_be32(&ugeth->ug_regs->txok)); - ugeth_info("txcf : addr - 0x%08x, val - 0x%04x", - (u32) & ugeth->ug_regs->txcf, - in_be16(&ugeth->ug_regs->txcf)); - ugeth_info("tmca : addr - 0x%08x, val - 0x%08x", - (u32) & ugeth->ug_regs->tmca, - in_be32(&ugeth->ug_regs->tmca)); - ugeth_info("tbca : addr - 0x%08x, val - 0x%08x", - (u32) & ugeth->ug_regs->tbca, - in_be32(&ugeth->ug_regs->tbca)); - ugeth_info("rxfok : addr - 0x%08x, val - 0x%08x", - (u32) & ugeth->ug_regs->rxfok, - in_be32(&ugeth->ug_regs->rxfok)); - ugeth_info("rxbok : addr - 0x%08x, val - 0x%08x", - (u32) & ugeth->ug_regs->rxbok, - in_be32(&ugeth->ug_regs->rxbok)); - ugeth_info("rbyt : addr - 0x%08x, val - 0x%08x", - (u32) & ugeth->ug_regs->rbyt, - in_be32(&ugeth->ug_regs->rbyt)); - ugeth_info("rmca : addr - 0x%08x, val - 0x%08x", - (u32) & ugeth->ug_regs->rmca, - in_be32(&ugeth->ug_regs->rmca)); - ugeth_info("rbca : addr - 0x%08x, val - 0x%08x", - (u32) & ugeth->ug_regs->rbca, - in_be32(&ugeth->ug_regs->rbca)); - ugeth_info("scar : addr - 0x%08x, val - 0x%08x", - (u32) & ugeth->ug_regs->scar, - in_be32(&ugeth->ug_regs->scar)); - ugeth_info("scam : addr - 0x%08x, val - 0x%08x", - (u32) & ugeth->ug_regs->scam, - in_be32(&ugeth->ug_regs->scam)); - - if (ugeth->p_thread_data_tx) { - int numThreadsTxNumerical; - switch (ugeth->ug_info->numThreadsTx) { - case UCC_GETH_NUM_OF_THREADS_1: - numThreadsTxNumerical = 1; - break; - case UCC_GETH_NUM_OF_THREADS_2: - numThreadsTxNumerical = 2; - break; - case UCC_GETH_NUM_OF_THREADS_4: - numThreadsTxNumerical = 4; - break; - case UCC_GETH_NUM_OF_THREADS_6: - numThreadsTxNumerical = 6; - break; - case UCC_GETH_NUM_OF_THREADS_8: - numThreadsTxNumerical = 8; - break; - default: - numThreadsTxNumerical = 0; - break; - } - - ugeth_info("Thread data TXs:"); - ugeth_info("Base address: 0x%08x", - (u32) ugeth->p_thread_data_tx); - for (i = 0; i < numThreadsTxNumerical; i++) { - ugeth_info("Thread data TX[%d]:", i); - ugeth_info("Base address: 0x%08x", - (u32) & ugeth->p_thread_data_tx[i]); - mem_disp((u8 *) & ugeth->p_thread_data_tx[i], - sizeof(ucc_geth_thread_data_tx_t)); - } - } - if (ugeth->p_thread_data_rx) { - int numThreadsRxNumerical; - switch (ugeth->ug_info->numThreadsRx) { - case UCC_GETH_NUM_OF_THREADS_1: - numThreadsRxNumerical = 1; - break; - case UCC_GETH_NUM_OF_THREADS_2: - numThreadsRxNumerical = 2; - break; - case UCC_GETH_NUM_OF_THREADS_4: - numThreadsRxNumerical = 4; - break; - case UCC_GETH_NUM_OF_THREADS_6: - numThreadsRxNumerical = 6; - break; - case UCC_GETH_NUM_OF_THREADS_8: - numThreadsRxNumerical = 8; - break; - default: - numThreadsRxNumerical = 0; - break; - } - - ugeth_info("Thread data RX:"); - ugeth_info("Base address: 0x%08x", - (u32) ugeth->p_thread_data_rx); - for (i = 0; i < numThreadsRxNumerical; i++) { - ugeth_info("Thread data RX[%d]:", i); - ugeth_info("Base address: 0x%08x", - (u32) & ugeth->p_thread_data_rx[i]); - mem_disp((u8 *) & ugeth->p_thread_data_rx[i], - sizeof(ucc_geth_thread_data_rx_t)); - } - } - if (ugeth->p_exf_glbl_param) { - ugeth_info("EXF global param:"); - ugeth_info("Base address: 0x%08x", - (u32) ugeth->p_exf_glbl_param); - mem_disp((u8 *) ugeth->p_exf_glbl_param, - sizeof(*ugeth->p_exf_glbl_param)); - } - if (ugeth->p_tx_glbl_pram) { - ugeth_info("TX global param:"); - ugeth_info("Base address: 0x%08x", (u32) ugeth->p_tx_glbl_pram); - ugeth_info("temoder : addr - 0x%08x, val - 0x%04x", - (u32) & ugeth->p_tx_glbl_pram->temoder, - in_be16(&ugeth->p_tx_glbl_pram->temoder)); - ugeth_info("sqptr : addr - 0x%08x, val - 0x%08x", - (u32) & ugeth->p_tx_glbl_pram->sqptr, - in_be32(&ugeth->p_tx_glbl_pram->sqptr)); - ugeth_info("schedulerbasepointer: addr - 0x%08x, val - 0x%08x", - (u32) & ugeth->p_tx_glbl_pram->schedulerbasepointer, - in_be32(&ugeth->p_tx_glbl_pram-> - schedulerbasepointer)); - ugeth_info("txrmonbaseptr: addr - 0x%08x, val - 0x%08x", - (u32) & ugeth->p_tx_glbl_pram->txrmonbaseptr, - in_be32(&ugeth->p_tx_glbl_pram->txrmonbaseptr)); - ugeth_info("tstate : addr - 0x%08x, val - 0x%08x", - (u32) & ugeth->p_tx_glbl_pram->tstate, - in_be32(&ugeth->p_tx_glbl_pram->tstate)); - ugeth_info("iphoffset[0] : addr - 0x%08x, val - 0x%02x", - (u32) & ugeth->p_tx_glbl_pram->iphoffset[0], - ugeth->p_tx_glbl_pram->iphoffset[0]); - ugeth_info("iphoffset[1] : addr - 0x%08x, val - 0x%02x", - (u32) & ugeth->p_tx_glbl_pram->iphoffset[1], - ugeth->p_tx_glbl_pram->iphoffset[1]); - ugeth_info("iphoffset[2] : addr - 0x%08x, val - 0x%02x", - (u32) & ugeth->p_tx_glbl_pram->iphoffset[2], - ugeth->p_tx_glbl_pram->iphoffset[2]); - ugeth_info("iphoffset[3] : addr - 0x%08x, val - 0x%02x", - (u32) & ugeth->p_tx_glbl_pram->iphoffset[3], - ugeth->p_tx_glbl_pram->iphoffset[3]); - ugeth_info("iphoffset[4] : addr - 0x%08x, val - 0x%02x", - (u32) & ugeth->p_tx_glbl_pram->iphoffset[4], - ugeth->p_tx_glbl_pram->iphoffset[4]); - ugeth_info("iphoffset[5] : addr - 0x%08x, val - 0x%02x", - (u32) & ugeth->p_tx_glbl_pram->iphoffset[5], - ugeth->p_tx_glbl_pram->iphoffset[5]); - ugeth_info("iphoffset[6] : addr - 0x%08x, val - 0x%02x", - (u32) & ugeth->p_tx_glbl_pram->iphoffset[6], - ugeth->p_tx_glbl_pram->iphoffset[6]); - ugeth_info("iphoffset[7] : addr - 0x%08x, val - 0x%02x", - (u32) & ugeth->p_tx_glbl_pram->iphoffset[7], - ugeth->p_tx_glbl_pram->iphoffset[7]); - ugeth_info("vtagtable[0] : addr - 0x%08x, val - 0x%08x", - (u32) & ugeth->p_tx_glbl_pram->vtagtable[0], - in_be32(&ugeth->p_tx_glbl_pram->vtagtable[0])); - ugeth_info("vtagtable[1] : addr - 0x%08x, val - 0x%08x", - (u32) & ugeth->p_tx_glbl_pram->vtagtable[1], - in_be32(&ugeth->p_tx_glbl_pram->vtagtable[1])); - ugeth_info("vtagtable[2] : addr - 0x%08x, val - 0x%08x", - (u32) & ugeth->p_tx_glbl_pram->vtagtable[2], - in_be32(&ugeth->p_tx_glbl_pram->vtagtable[2])); - ugeth_info("vtagtable[3] : addr - 0x%08x, val - 0x%08x", - (u32) & ugeth->p_tx_glbl_pram->vtagtable[3], - in_be32(&ugeth->p_tx_glbl_pram->vtagtable[3])); - ugeth_info("vtagtable[4] : addr - 0x%08x, val - 0x%08x", - (u32) & ugeth->p_tx_glbl_pram->vtagtable[4], - in_be32(&ugeth->p_tx_glbl_pram->vtagtable[4])); - ugeth_info("vtagtable[5] : addr - 0x%08x, val - 0x%08x", - (u32) & ugeth->p_tx_glbl_pram->vtagtable[5], - in_be32(&ugeth->p_tx_glbl_pram->vtagtable[5])); - ugeth_info("vtagtable[6] : addr - 0x%08x, val - 0x%08x", - (u32) & ugeth->p_tx_glbl_pram->vtagtable[6], - in_be32(&ugeth->p_tx_glbl_pram->vtagtable[6])); - ugeth_info("vtagtable[7] : addr - 0x%08x, val - 0x%08x", - (u32) & ugeth->p_tx_glbl_pram->vtagtable[7], - in_be32(&ugeth->p_tx_glbl_pram->vtagtable[7])); - ugeth_info("tqptr : addr - 0x%08x, val - 0x%08x", - (u32) & ugeth->p_tx_glbl_pram->tqptr, - in_be32(&ugeth->p_tx_glbl_pram->tqptr)); - } - if (ugeth->p_rx_glbl_pram) { - ugeth_info("RX global param:"); - ugeth_info("Base address: 0x%08x", (u32) ugeth->p_rx_glbl_pram); - ugeth_info("remoder : addr - 0x%08x, val - 0x%08x", - (u32) & ugeth->p_rx_glbl_pram->remoder, - in_be32(&ugeth->p_rx_glbl_pram->remoder)); - ugeth_info("rqptr : addr - 0x%08x, val - 0x%08x", - (u32) & ugeth->p_rx_glbl_pram->rqptr, - in_be32(&ugeth->p_rx_glbl_pram->rqptr)); - ugeth_info("typeorlen : addr - 0x%08x, val - 0x%04x", - (u32) & ugeth->p_rx_glbl_pram->typeorlen, - in_be16(&ugeth->p_rx_glbl_pram->typeorlen)); - ugeth_info("rxgstpack : addr - 0x%08x, val - 0x%02x", - (u32) & ugeth->p_rx_glbl_pram->rxgstpack, - ugeth->p_rx_glbl_pram->rxgstpack); - ugeth_info("rxrmonbaseptr : addr - 0x%08x, val - 0x%08x", - (u32) & ugeth->p_rx_glbl_pram->rxrmonbaseptr, - in_be32(&ugeth->p_rx_glbl_pram->rxrmonbaseptr)); - ugeth_info("intcoalescingptr: addr - 0x%08x, val - 0x%08x", - (u32) & ugeth->p_rx_glbl_pram->intcoalescingptr, - in_be32(&ugeth->p_rx_glbl_pram->intcoalescingptr)); - ugeth_info("rstate : addr - 0x%08x, val - 0x%02x", - (u32) & ugeth->p_rx_glbl_pram->rstate, - ugeth->p_rx_glbl_pram->rstate); - ugeth_info("mrblr : addr - 0x%08x, val - 0x%04x", - (u32) & ugeth->p_rx_glbl_pram->mrblr, - in_be16(&ugeth->p_rx_glbl_pram->mrblr)); - ugeth_info("rbdqptr : addr - 0x%08x, val - 0x%08x", - (u32) & ugeth->p_rx_glbl_pram->rbdqptr, - in_be32(&ugeth->p_rx_glbl_pram->rbdqptr)); - ugeth_info("mflr : addr - 0x%08x, val - 0x%04x", - (u32) & ugeth->p_rx_glbl_pram->mflr, - in_be16(&ugeth->p_rx_glbl_pram->mflr)); - ugeth_info("minflr : addr - 0x%08x, val - 0x%04x", - (u32) & ugeth->p_rx_glbl_pram->minflr, - in_be16(&ugeth->p_rx_glbl_pram->minflr)); - ugeth_info("maxd1 : addr - 0x%08x, val - 0x%04x", - (u32) & ugeth->p_rx_glbl_pram->maxd1, - in_be16(&ugeth->p_rx_glbl_pram->maxd1)); - ugeth_info("maxd2 : addr - 0x%08x, val - 0x%04x", - (u32) & ugeth->p_rx_glbl_pram->maxd2, - in_be16(&ugeth->p_rx_glbl_pram->maxd2)); - ugeth_info("ecamptr : addr - 0x%08x, val - 0x%08x", - (u32) & ugeth->p_rx_glbl_pram->ecamptr, - in_be32(&ugeth->p_rx_glbl_pram->ecamptr)); - ugeth_info("l2qt : addr - 0x%08x, val - 0x%08x", - (u32) & ugeth->p_rx_glbl_pram->l2qt, - in_be32(&ugeth->p_rx_glbl_pram->l2qt)); - ugeth_info("l3qt[0] : addr - 0x%08x, val - 0x%08x", - (u32) & ugeth->p_rx_glbl_pram->l3qt[0], - in_be32(&ugeth->p_rx_glbl_pram->l3qt[0])); - ugeth_info("l3qt[1] : addr - 0x%08x, val - 0x%08x", - (u32) & ugeth->p_rx_glbl_pram->l3qt[1], - in_be32(&ugeth->p_rx_glbl_pram->l3qt[1])); - ugeth_info("l3qt[2] : addr - 0x%08x, val - 0x%08x", - (u32) & ugeth->p_rx_glbl_pram->l3qt[2], - in_be32(&ugeth->p_rx_glbl_pram->l3qt[2])); - ugeth_info("l3qt[3] : addr - 0x%08x, val - 0x%08x", - (u32) & ugeth->p_rx_glbl_pram->l3qt[3], - in_be32(&ugeth->p_rx_glbl_pram->l3qt[3])); - ugeth_info("l3qt[4] : addr - 0x%08x, val - 0x%08x", - (u32) & ugeth->p_rx_glbl_pram->l3qt[4], - in_be32(&ugeth->p_rx_glbl_pram->l3qt[4])); - ugeth_info("l3qt[5] : addr - 0x%08x, val - 0x%08x", - (u32) & ugeth->p_rx_glbl_pram->l3qt[5], - in_be32(&ugeth->p_rx_glbl_pram->l3qt[5])); - ugeth_info("l3qt[6] : addr - 0x%08x, val - 0x%08x", - (u32) & ugeth->p_rx_glbl_pram->l3qt[6], - in_be32(&ugeth->p_rx_glbl_pram->l3qt[6])); - ugeth_info("l3qt[7] : addr - 0x%08x, val - 0x%08x", - (u32) & ugeth->p_rx_glbl_pram->l3qt[7], - in_be32(&ugeth->p_rx_glbl_pram->l3qt[7])); - ugeth_info("vlantype : addr - 0x%08x, val - 0x%04x", - (u32) & ugeth->p_rx_glbl_pram->vlantype, - in_be16(&ugeth->p_rx_glbl_pram->vlantype)); - ugeth_info("vlantci : addr - 0x%08x, val - 0x%04x", - (u32) & ugeth->p_rx_glbl_pram->vlantci, - in_be16(&ugeth->p_rx_glbl_pram->vlantci)); - for (i = 0; i < 64; i++) - ugeth_info - ("addressfiltering[%d]: addr - 0x%08x, val - 0x%02x", - i, - (u32) & ugeth->p_rx_glbl_pram->addressfiltering[i], - ugeth->p_rx_glbl_pram->addressfiltering[i]); - ugeth_info("exfGlobalParam : addr - 0x%08x, val - 0x%08x", - (u32) & ugeth->p_rx_glbl_pram->exfGlobalParam, - in_be32(&ugeth->p_rx_glbl_pram->exfGlobalParam)); - } - if (ugeth->p_send_q_mem_reg) { - ugeth_info("Send Q memory registers:"); - ugeth_info("Base address: 0x%08x", - (u32) ugeth->p_send_q_mem_reg); - for (i = 0; i < ugeth->ug_info->numQueuesTx; i++) { - ugeth_info("SQQD[%d]:", i); - ugeth_info("Base address: 0x%08x", - (u32) & ugeth->p_send_q_mem_reg->sqqd[i]); - mem_disp((u8 *) & ugeth->p_send_q_mem_reg->sqqd[i], - sizeof(ucc_geth_send_queue_qd_t)); - } - } - if (ugeth->p_scheduler) { - ugeth_info("Scheduler:"); - ugeth_info("Base address: 0x%08x", (u32) ugeth->p_scheduler); - mem_disp((u8 *) ugeth->p_scheduler, - sizeof(*ugeth->p_scheduler)); - } - if (ugeth->p_tx_fw_statistics_pram) { - ugeth_info("TX FW statistics pram:"); - ugeth_info("Base address: 0x%08x", - (u32) ugeth->p_tx_fw_statistics_pram); - mem_disp((u8 *) ugeth->p_tx_fw_statistics_pram, - sizeof(*ugeth->p_tx_fw_statistics_pram)); - } - if (ugeth->p_rx_fw_statistics_pram) { - ugeth_info("RX FW statistics pram:"); - ugeth_info("Base address: 0x%08x", - (u32) ugeth->p_rx_fw_statistics_pram); - mem_disp((u8 *) ugeth->p_rx_fw_statistics_pram, - sizeof(*ugeth->p_rx_fw_statistics_pram)); - } - if (ugeth->p_rx_irq_coalescing_tbl) { - ugeth_info("RX IRQ coalescing tables:"); - ugeth_info("Base address: 0x%08x", - (u32) ugeth->p_rx_irq_coalescing_tbl); - for (i = 0; i < ugeth->ug_info->numQueuesRx; i++) { - ugeth_info("RX IRQ coalescing table entry[%d]:", i); - ugeth_info("Base address: 0x%08x", - (u32) & ugeth->p_rx_irq_coalescing_tbl-> - coalescingentry[i]); - ugeth_info - ("interruptcoalescingmaxvalue: addr - 0x%08x, val - 0x%08x", - (u32) & ugeth->p_rx_irq_coalescing_tbl-> - coalescingentry[i].interruptcoalescingmaxvalue, - in_be32(&ugeth->p_rx_irq_coalescing_tbl-> - coalescingentry[i]. - interruptcoalescingmaxvalue)); - ugeth_info - ("interruptcoalescingcounter : addr - 0x%08x, val - 0x%08x", - (u32) & ugeth->p_rx_irq_coalescing_tbl-> - coalescingentry[i].interruptcoalescingcounter, - in_be32(&ugeth->p_rx_irq_coalescing_tbl-> - coalescingentry[i]. - interruptcoalescingcounter)); - } - } - if (ugeth->p_rx_bd_qs_tbl) { - ugeth_info("RX BD QS tables:"); - ugeth_info("Base address: 0x%08x", (u32) ugeth->p_rx_bd_qs_tbl); - for (i = 0; i < ugeth->ug_info->numQueuesRx; i++) { - ugeth_info("RX BD QS table[%d]:", i); - ugeth_info("Base address: 0x%08x", - (u32) & ugeth->p_rx_bd_qs_tbl[i]); - ugeth_info - ("bdbaseptr : addr - 0x%08x, val - 0x%08x", - (u32) & ugeth->p_rx_bd_qs_tbl[i].bdbaseptr, - in_be32(&ugeth->p_rx_bd_qs_tbl[i].bdbaseptr)); - ugeth_info - ("bdptr : addr - 0x%08x, val - 0x%08x", - (u32) & ugeth->p_rx_bd_qs_tbl[i].bdptr, - in_be32(&ugeth->p_rx_bd_qs_tbl[i].bdptr)); - ugeth_info - ("externalbdbaseptr: addr - 0x%08x, val - 0x%08x", - (u32) & ugeth->p_rx_bd_qs_tbl[i].externalbdbaseptr, - in_be32(&ugeth->p_rx_bd_qs_tbl[i]. - externalbdbaseptr)); - ugeth_info - ("externalbdptr : addr - 0x%08x, val - 0x%08x", - (u32) & ugeth->p_rx_bd_qs_tbl[i].externalbdptr, - in_be32(&ugeth->p_rx_bd_qs_tbl[i].externalbdptr)); - ugeth_info("ucode RX Prefetched BDs:"); - ugeth_info("Base address: 0x%08x", - (u32) - qe_muram_addr(in_be32 - (&ugeth->p_rx_bd_qs_tbl[i]. - bdbaseptr))); - mem_disp((u8 *) - qe_muram_addr(in_be32 - (&ugeth->p_rx_bd_qs_tbl[i]. - bdbaseptr)), - sizeof(ucc_geth_rx_prefetched_bds_t)); - } - } - if (ugeth->p_init_enet_param_shadow) { - int size; - ugeth_info("Init enet param shadow:"); - ugeth_info("Base address: 0x%08x", - (u32) ugeth->p_init_enet_param_shadow); - mem_disp((u8 *) ugeth->p_init_enet_param_shadow, - sizeof(*ugeth->p_init_enet_param_shadow)); - - size = sizeof(ucc_geth_thread_rx_pram_t); - if (ugeth->ug_info->rxExtendedFiltering) { - size += - THREAD_RX_PRAM_ADDITIONAL_FOR_EXTENDED_FILTERING; - if (ugeth->ug_info->largestexternallookupkeysize == - QE_FLTR_TABLE_LOOKUP_KEY_SIZE_8_BYTES) - size += - THREAD_RX_PRAM_ADDITIONAL_FOR_EXTENDED_FILTERING_8; - if (ugeth->ug_info->largestexternallookupkeysize == - QE_FLTR_TABLE_LOOKUP_KEY_SIZE_16_BYTES) - size += - THREAD_RX_PRAM_ADDITIONAL_FOR_EXTENDED_FILTERING_16; - } - - dump_init_enet_entries(ugeth, - &(ugeth->p_init_enet_param_shadow-> - txthread[0]), - ENET_INIT_PARAM_MAX_ENTRIES_TX, - sizeof(ucc_geth_thread_tx_pram_t), - ugeth->ug_info->riscTx, 0); - dump_init_enet_entries(ugeth, - &(ugeth->p_init_enet_param_shadow-> - rxthread[0]), - ENET_INIT_PARAM_MAX_ENTRIES_RX, size, - ugeth->ug_info->riscRx, 1); - } -} -#endif /* DEBUG */ - -static void init_default_reg_vals(volatile u32 *upsmr_register, - volatile u32 *maccfg1_register, - volatile u32 *maccfg2_register) -{ - out_be32(upsmr_register, UCC_GETH_UPSMR_INIT); - out_be32(maccfg1_register, UCC_GETH_MACCFG1_INIT); - out_be32(maccfg2_register, UCC_GETH_MACCFG2_INIT); -} - -static int init_half_duplex_params(int alt_beb, - int back_pressure_no_backoff, - int no_backoff, - int excess_defer, - u8 alt_beb_truncation, - u8 max_retransmissions, - u8 collision_window, - volatile u32 *hafdup_register) -{ - u32 value = 0; - - if ((alt_beb_truncation > HALFDUP_ALT_BEB_TRUNCATION_MAX) || - (max_retransmissions > HALFDUP_MAX_RETRANSMISSION_MAX) || - (collision_window > HALFDUP_COLLISION_WINDOW_MAX)) - return -EINVAL; - - value = (u32) (alt_beb_truncation << HALFDUP_ALT_BEB_TRUNCATION_SHIFT); - - if (alt_beb) - value |= HALFDUP_ALT_BEB; - if (back_pressure_no_backoff) - value |= HALFDUP_BACK_PRESSURE_NO_BACKOFF; - if (no_backoff) - value |= HALFDUP_NO_BACKOFF; - if (excess_defer) - value |= HALFDUP_EXCESSIVE_DEFER; - - value |= (max_retransmissions << HALFDUP_MAX_RETRANSMISSION_SHIFT); - - value |= collision_window; - - out_be32(hafdup_register, value); - return 0; -} - -static int init_inter_frame_gap_params(u8 non_btb_cs_ipg, - u8 non_btb_ipg, - u8 min_ifg, - u8 btb_ipg, - volatile u32 *ipgifg_register) -{ - u32 value = 0; - - /* Non-Back-to-back IPG part 1 should be <= Non-Back-to-back - IPG part 2 */ - if (non_btb_cs_ipg > non_btb_ipg) - return -EINVAL; - - if ((non_btb_cs_ipg > IPGIFG_NON_BACK_TO_BACK_IFG_PART1_MAX) || - (non_btb_ipg > IPGIFG_NON_BACK_TO_BACK_IFG_PART2_MAX) || - /*(min_ifg > IPGIFG_MINIMUM_IFG_ENFORCEMENT_MAX) || */ - (btb_ipg > IPGIFG_BACK_TO_BACK_IFG_MAX)) - return -EINVAL; - - value |= - ((non_btb_cs_ipg << IPGIFG_NON_BACK_TO_BACK_IFG_PART1_SHIFT) & - IPGIFG_NBTB_CS_IPG_MASK); - value |= - ((non_btb_ipg << IPGIFG_NON_BACK_TO_BACK_IFG_PART2_SHIFT) & - IPGIFG_NBTB_IPG_MASK); - value |= - ((min_ifg << IPGIFG_MINIMUM_IFG_ENFORCEMENT_SHIFT) & - IPGIFG_MIN_IFG_MASK); - value |= (btb_ipg & IPGIFG_BTB_IPG_MASK); - - out_be32(ipgifg_register, value); - return 0; -} - -static int init_flow_control_params(u32 automatic_flow_control_mode, - int rx_flow_control_enable, - int tx_flow_control_enable, - u16 pause_period, - u16 extension_field, - volatile u32 *upsmr_register, - volatile u32 *uempr_register, - volatile u32 *maccfg1_register) -{ - u32 value = 0; - - /* Set UEMPR register */ - value = (u32) pause_period << UEMPR_PAUSE_TIME_VALUE_SHIFT; - value |= (u32) extension_field << UEMPR_EXTENDED_PAUSE_TIME_VALUE_SHIFT; - out_be32(uempr_register, value); - - /* Set UPSMR register */ - value = in_be32(upsmr_register); - value |= automatic_flow_control_mode; - out_be32(upsmr_register, value); - - value = in_be32(maccfg1_register); - if (rx_flow_control_enable) - value |= MACCFG1_FLOW_RX; - if (tx_flow_control_enable) - value |= MACCFG1_FLOW_TX; - out_be32(maccfg1_register, value); - - return 0; -} - -static int init_hw_statistics_gathering_mode(int enable_hardware_statistics, - int auto_zero_hardware_statistics, - volatile u32 *upsmr_register, - volatile u16 *uescr_register) -{ - u32 upsmr_value = 0; - u16 uescr_value = 0; - /* Enable hardware statistics gathering if requested */ - if (enable_hardware_statistics) { - upsmr_value = in_be32(upsmr_register); - upsmr_value |= UPSMR_HSE; - out_be32(upsmr_register, upsmr_value); - } - - /* Clear hardware statistics counters */ - uescr_value = in_be16(uescr_register); - uescr_value |= UESCR_CLRCNT; - /* Automatically zero hardware statistics counters on read, - if requested */ - if (auto_zero_hardware_statistics) - uescr_value |= UESCR_AUTOZ; - out_be16(uescr_register, uescr_value); - - return 0; -} - -static int init_firmware_statistics_gathering_mode(int - enable_tx_firmware_statistics, - int enable_rx_firmware_statistics, - volatile u32 *tx_rmon_base_ptr, - u32 tx_firmware_statistics_structure_address, - volatile u32 *rx_rmon_base_ptr, - u32 rx_firmware_statistics_structure_address, - volatile u16 *temoder_register, - volatile u32 *remoder_register) -{ - /* Note: this function does not check if */ - /* the parameters it receives are NULL */ - u16 temoder_value; - u32 remoder_value; - - if (enable_tx_firmware_statistics) { - out_be32(tx_rmon_base_ptr, - tx_firmware_statistics_structure_address); - temoder_value = in_be16(temoder_register); - temoder_value |= TEMODER_TX_RMON_STATISTICS_ENABLE; - out_be16(temoder_register, temoder_value); - } - - if (enable_rx_firmware_statistics) { - out_be32(rx_rmon_base_ptr, - rx_firmware_statistics_structure_address); - remoder_value = in_be32(remoder_register); - remoder_value |= REMODER_RX_RMON_STATISTICS_ENABLE; - out_be32(remoder_register, remoder_value); - } - - return 0; -} - -static int init_mac_station_addr_regs(u8 address_byte_0, - u8 address_byte_1, - u8 address_byte_2, - u8 address_byte_3, - u8 address_byte_4, - u8 address_byte_5, - volatile u32 *macstnaddr1_register, - volatile u32 *macstnaddr2_register) -{ - u32 value = 0; - - /* Example: for a station address of 0x12345678ABCD, */ - /* 0x12 is byte 0, 0x34 is byte 1 and so on and 0xCD is byte 5 */ - - /* MACSTNADDR1 Register: */ - - /* 0 7 8 15 */ - /* station address byte 5 station address byte 4 */ - /* 16 23 24 31 */ - /* station address byte 3 station address byte 2 */ - value |= (u32) ((address_byte_2 << 0) & 0x000000FF); - value |= (u32) ((address_byte_3 << 8) & 0x0000FF00); - value |= (u32) ((address_byte_4 << 16) & 0x00FF0000); - value |= (u32) ((address_byte_5 << 24) & 0xFF000000); - - out_be32(macstnaddr1_register, value); - - /* MACSTNADDR2 Register: */ - - /* 0 7 8 15 */ - /* station address byte 1 station address byte 0 */ - /* 16 23 24 31 */ - /* reserved reserved */ - value = 0; - value |= (u32) ((address_byte_0 << 16) & 0x00FF0000); - value |= (u32) ((address_byte_1 << 24) & 0xFF000000); - - out_be32(macstnaddr2_register, value); - - return 0; -} - -static int init_mac_duplex_mode(int full_duplex, - int limited_to_full_duplex, - volatile u32 *maccfg2_register) -{ - u32 value = 0; - - /* some interfaces must work in full duplex mode */ - if ((full_duplex == 0) && (limited_to_full_duplex == 1)) - return -EINVAL; - - value = in_be32(maccfg2_register); - - if (full_duplex) - value |= MACCFG2_FDX; - else - value &= ~MACCFG2_FDX; - - out_be32(maccfg2_register, value); - return 0; -} - -static int init_check_frame_length_mode(int length_check, - volatile u32 *maccfg2_register) -{ - u32 value = 0; - - value = in_be32(maccfg2_register); - - if (length_check) - value |= MACCFG2_LC; - else - value &= ~MACCFG2_LC; - - out_be32(maccfg2_register, value); - return 0; -} - -static int init_preamble_length(u8 preamble_length, - volatile u32 *maccfg2_register) -{ - u32 value = 0; - - if ((preamble_length < 3) || (preamble_length > 7)) - return -EINVAL; - - value = in_be32(maccfg2_register); - value &= ~MACCFG2_PREL_MASK; - value |= (preamble_length << MACCFG2_PREL_SHIFT); - out_be32(maccfg2_register, value); - return 0; -} - -static int init_mii_management_configuration(int reset_mgmt, - int preamble_supress, - volatile u32 *miimcfg_register, - volatile u32 *miimind_register) -{ - unsigned int timeout = PHY_INIT_TIMEOUT; - u32 value = 0; - - value = in_be32(miimcfg_register); - if (reset_mgmt) { - value |= MIIMCFG_RESET_MANAGEMENT; - out_be32(miimcfg_register, value); - } - - value = 0; - - if (preamble_supress) - value |= MIIMCFG_NO_PREAMBLE; - - value |= UCC_GETH_MIIMCFG_MNGMNT_CLC_DIV_INIT; - out_be32(miimcfg_register, value); - - /* Wait until the bus is free */ - while ((in_be32(miimind_register) & MIIMIND_BUSY) && timeout--) - cpu_relax(); - - if (timeout <= 0) { - ugeth_err("%s: The MII Bus is stuck!", __FUNCTION__); - return -ETIMEDOUT; - } - - return 0; -} - -static int init_rx_parameters(int reject_broadcast, - int receive_short_frames, - int promiscuous, volatile u32 *upsmr_register) -{ - u32 value = 0; - - value = in_be32(upsmr_register); - - if (reject_broadcast) - value |= UPSMR_BRO; - else - value &= ~UPSMR_BRO; - - if (receive_short_frames) - value |= UPSMR_RSH; - else - value &= ~UPSMR_RSH; - - if (promiscuous) - value |= UPSMR_PRO; - else - value &= ~UPSMR_PRO; - - out_be32(upsmr_register, value); - - return 0; -} - -static int init_max_rx_buff_len(u16 max_rx_buf_len, - volatile u16 *mrblr_register) -{ - /* max_rx_buf_len value must be a multiple of 128 */ - if ((max_rx_buf_len == 0) - || (max_rx_buf_len % UCC_GETH_MRBLR_ALIGNMENT)) - return -EINVAL; - - out_be16(mrblr_register, max_rx_buf_len); - return 0; -} - -static int init_min_frame_len(u16 min_frame_length, - volatile u16 *minflr_register, - volatile u16 *mrblr_register) -{ - u16 mrblr_value = 0; - - mrblr_value = in_be16(mrblr_register); - if (min_frame_length >= (mrblr_value - 4)) - return -EINVAL; - - out_be16(minflr_register, min_frame_length); - return 0; -} - -static int adjust_enet_interface(ucc_geth_private_t *ugeth) -{ - ucc_geth_info_t *ug_info; - ucc_geth_t *ug_regs; - ucc_fast_t *uf_regs; - enet_speed_e speed; - int ret_val, rpm = 0, tbi = 0, r10m = 0, rmm = - 0, limited_to_full_duplex = 0; - u32 upsmr, maccfg2, utbipar, tbiBaseAddress; - u16 value; - - ugeth_vdbg("%s: IN", __FUNCTION__); - - ug_info = ugeth->ug_info; - ug_regs = ugeth->ug_regs; - uf_regs = ugeth->uccf->uf_regs; - - /* Analyze enet_interface according to Interface Mode Configuration - table */ - ret_val = - get_interface_details(ug_info->enet_interface, &speed, &r10m, &rmm, - &rpm, &tbi, &limited_to_full_duplex); - if (ret_val != 0) { - ugeth_err - ("%s: half duplex not supported in requested configuration.", - __FUNCTION__); - return ret_val; - } - - /* Set MACCFG2 */ - maccfg2 = in_be32(&ug_regs->maccfg2); - maccfg2 &= ~MACCFG2_INTERFACE_MODE_MASK; - if ((speed == ENET_SPEED_10BT) || (speed == ENET_SPEED_100BT)) - maccfg2 |= MACCFG2_INTERFACE_MODE_NIBBLE; - else if (speed == ENET_SPEED_1000BT) - maccfg2 |= MACCFG2_INTERFACE_MODE_BYTE; - maccfg2 |= ug_info->padAndCrc; - out_be32(&ug_regs->maccfg2, maccfg2); - - /* Set UPSMR */ - upsmr = in_be32(&uf_regs->upsmr); - upsmr &= ~(UPSMR_RPM | UPSMR_R10M | UPSMR_TBIM | UPSMR_RMM); - if (rpm) - upsmr |= UPSMR_RPM; - if (r10m) - upsmr |= UPSMR_R10M; - if (tbi) - upsmr |= UPSMR_TBIM; - if (rmm) - upsmr |= UPSMR_RMM; - out_be32(&uf_regs->upsmr, upsmr); - - /* Set UTBIPAR */ - utbipar = in_be32(&ug_regs->utbipar); - utbipar &= ~UTBIPAR_PHY_ADDRESS_MASK; - if (tbi) - utbipar |= - (ug_info->phy_address + - ugeth->ug_info->uf_info. - ucc_num) << UTBIPAR_PHY_ADDRESS_SHIFT; - else - utbipar |= - (0x10 + - ugeth->ug_info->uf_info. - ucc_num) << UTBIPAR_PHY_ADDRESS_SHIFT; - out_be32(&ug_regs->utbipar, utbipar); - - /* Disable autonegotiation in tbi mode, because by default it - comes up in autonegotiation mode. */ - /* Note that this depends on proper setting in utbipar register. */ - if (tbi) { - tbiBaseAddress = in_be32(&ug_regs->utbipar); - tbiBaseAddress &= UTBIPAR_PHY_ADDRESS_MASK; - tbiBaseAddress >>= UTBIPAR_PHY_ADDRESS_SHIFT; - value = - ugeth->mii_info->mdio_read(ugeth->dev, (u8) tbiBaseAddress, - ENET_TBI_MII_CR); - value &= ~0x1000; /* Turn off autonegotiation */ - ugeth->mii_info->mdio_write(ugeth->dev, (u8) tbiBaseAddress, - ENET_TBI_MII_CR, value); - } - - ret_val = init_mac_duplex_mode(1, - limited_to_full_duplex, - &ug_regs->maccfg2); - if (ret_val != 0) { - ugeth_err - ("%s: half duplex not supported in requested configuration.", - __FUNCTION__); - return ret_val; - } - - init_check_frame_length_mode(ug_info->lengthCheckRx, &ug_regs->maccfg2); - - ret_val = init_preamble_length(ug_info->prel, &ug_regs->maccfg2); - if (ret_val != 0) { - ugeth_err - ("%s: Preamble length must be between 3 and 7 inclusive.", - __FUNCTION__); - return ret_val; - } - - return 0; -} - -/* Called every time the controller might need to be made - * aware of new link state. The PHY code conveys this - * information through variables in the ugeth structure, and this - * function converts those variables into the appropriate - * register values, and can bring down the device if needed. - */ -static void adjust_link(struct net_device *dev) -{ - ucc_geth_private_t *ugeth = netdev_priv(dev); - ucc_geth_t *ug_regs; - u32 tempval; - struct ugeth_mii_info *mii_info = ugeth->mii_info; - - ug_regs = ugeth->ug_regs; - - if (mii_info->link) { - /* Now we make sure that we can be in full duplex mode. - * If not, we operate in half-duplex mode. */ - if (mii_info->duplex != ugeth->oldduplex) { - if (!(mii_info->duplex)) { - tempval = in_be32(&ug_regs->maccfg2); - tempval &= ~(MACCFG2_FDX); - out_be32(&ug_regs->maccfg2, tempval); - - ugeth_info("%s: Half Duplex", dev->name); - } else { - tempval = in_be32(&ug_regs->maccfg2); - tempval |= MACCFG2_FDX; - out_be32(&ug_regs->maccfg2, tempval); - - ugeth_info("%s: Full Duplex", dev->name); - } - - ugeth->oldduplex = mii_info->duplex; - } - - if (mii_info->speed != ugeth->oldspeed) { - switch (mii_info->speed) { - case 1000: -#ifdef CONFIG_MPC836x -/* FIXME: This code is for 100Mbs BUG fixing, -remove this when it is fixed!!! */ - if (ugeth->ug_info->enet_interface == - ENET_1000_GMII) - /* Run the commands which initialize the PHY */ - { - tempval = - (u32) mii_info->mdio_read(ugeth-> - dev, mii_info->mii_id, 0x1b); - tempval |= 0x000f; - mii_info->mdio_write(ugeth->dev, - mii_info->mii_id, 0x1b, - (u16) tempval); - tempval = - (u32) mii_info->mdio_read(ugeth-> - dev, mii_info->mii_id, - MII_BMCR); - mii_info->mdio_write(ugeth->dev, - mii_info->mii_id, MII_BMCR, - (u16) (tempval | BMCR_RESET)); - } else if (ugeth->ug_info->enet_interface == - ENET_1000_RGMII) - /* Run the commands which initialize the PHY */ - { - tempval = - (u32) mii_info->mdio_read(ugeth-> - dev, mii_info->mii_id, 0x1b); - tempval = (tempval & ~0x000f) | 0x000b; - mii_info->mdio_write(ugeth->dev, - mii_info->mii_id, 0x1b, - (u16) tempval); - tempval = - (u32) mii_info->mdio_read(ugeth-> - dev, mii_info->mii_id, - MII_BMCR); - mii_info->mdio_write(ugeth->dev, - mii_info->mii_id, MII_BMCR, - (u16) (tempval | BMCR_RESET)); - } - msleep(4000); -#endif /* CONFIG_MPC8360 */ - adjust_enet_interface(ugeth); - break; - case 100: - case 10: -#ifdef CONFIG_MPC836x -/* FIXME: This code is for 100Mbs BUG fixing, -remove this lines when it will be fixed!!! */ - ugeth->ug_info->enet_interface = ENET_100_RGMII; - tempval = - (u32) mii_info->mdio_read(ugeth->dev, - mii_info->mii_id, - 0x1b); - tempval = (tempval & ~0x000f) | 0x000b; - mii_info->mdio_write(ugeth->dev, - mii_info->mii_id, 0x1b, - (u16) tempval); - tempval = - (u32) mii_info->mdio_read(ugeth->dev, - mii_info->mii_id, - MII_BMCR); - mii_info->mdio_write(ugeth->dev, - mii_info->mii_id, MII_BMCR, - (u16) (tempval | - BMCR_RESET)); - msleep(4000); -#endif /* CONFIG_MPC8360 */ - adjust_enet_interface(ugeth); - break; - default: - ugeth_warn - ("%s: Ack! Speed (%d) is not 10/100/1000!", - dev->name, mii_info->speed); - break; - } - - ugeth_info("%s: Speed %dBT", dev->name, - mii_info->speed); - - ugeth->oldspeed = mii_info->speed; - } - - if (!ugeth->oldlink) { - ugeth_info("%s: Link is up", dev->name); - ugeth->oldlink = 1; - netif_carrier_on(dev); - netif_schedule(dev); - } - } else { - if (ugeth->oldlink) { - ugeth_info("%s: Link is down", dev->name); - ugeth->oldlink = 0; - ugeth->oldspeed = 0; - ugeth->oldduplex = -1; - netif_carrier_off(dev); - } - } -} - -/* Configure the PHY for dev. - * returns 0 if success. -1 if failure - */ -static int init_phy(struct net_device *dev) -{ - ucc_geth_private_t *ugeth = netdev_priv(dev); - struct phy_info *curphy; - ucc_mii_mng_t *mii_regs; - struct ugeth_mii_info *mii_info; - int err; - - mii_regs = &ugeth->ug_regs->miimng; - - ugeth->oldlink = 0; - ugeth->oldspeed = 0; - ugeth->oldduplex = -1; - - mii_info = kmalloc(sizeof(struct ugeth_mii_info), GFP_KERNEL); - - if (NULL == mii_info) { - ugeth_err("%s: Could not allocate mii_info", dev->name); - return -ENOMEM; - } - - mii_info->mii_regs = mii_regs; - mii_info->speed = SPEED_1000; - mii_info->duplex = DUPLEX_FULL; - mii_info->pause = 0; - mii_info->link = 0; - - mii_info->advertising = (ADVERTISED_10baseT_Half | - ADVERTISED_10baseT_Full | - ADVERTISED_100baseT_Half | - ADVERTISED_100baseT_Full | - ADVERTISED_1000baseT_Full); - mii_info->autoneg = 1; - - mii_info->mii_id = ugeth->ug_info->phy_address; - - mii_info->dev = dev; - - mii_info->mdio_read = &read_phy_reg; - mii_info->mdio_write = &write_phy_reg; - - ugeth->mii_info = mii_info; - - spin_lock_irq(&ugeth->lock); - - /* Set this UCC to be the master of the MII managment */ - ucc_set_qe_mux_mii_mng(ugeth->ug_info->uf_info.ucc_num); - - if (init_mii_management_configuration(1, - ugeth->ug_info-> - miiPreambleSupress, - &mii_regs->miimcfg, - &mii_regs->miimind)) { - ugeth_err("%s: The MII Bus is stuck!", dev->name); - err = -1; - goto bus_fail; - } - - spin_unlock_irq(&ugeth->lock); - - /* get info for this PHY */ - curphy = get_phy_info(ugeth->mii_info); - - if (curphy == NULL) { - ugeth_err("%s: No PHY found", dev->name); - err = -1; - goto no_phy; - } - - mii_info->phyinfo = curphy; - - /* Run the commands which initialize the PHY */ - if (curphy->init) { - err = curphy->init(ugeth->mii_info); - if (err) - goto phy_init_fail; - } - - return 0; - - phy_init_fail: - no_phy: - bus_fail: - kfree(mii_info); - - return err; -} - -#ifdef CONFIG_UGETH_TX_ON_DEMOND -static int ugeth_transmit_on_demand(ucc_geth_private_t *ugeth) -{ - ucc_fast_transmit_on_demand(ugeth->uccf); - - return 0; -} -#endif - -static int ugeth_graceful_stop_tx(ucc_geth_private_t *ugeth) -{ - ucc_fast_private_t *uccf; - u32 cecr_subblock; - u32 temp; - - uccf = ugeth->uccf; - - /* Mask GRACEFUL STOP TX interrupt bit and clear it */ - temp = in_be32(uccf->p_uccm); - temp &= ~UCCE_GRA; - out_be32(uccf->p_uccm, temp); - out_be32(uccf->p_ucce, UCCE_GRA); /* clear by writing 1 */ - - /* Issue host command */ - cecr_subblock = - ucc_fast_get_qe_cr_subblock(ugeth->ug_info->uf_info.ucc_num); - qe_issue_cmd(QE_GRACEFUL_STOP_TX, cecr_subblock, - (u8) QE_CR_PROTOCOL_ETHERNET, 0); - - /* Wait for command to complete */ - do { - temp = in_be32(uccf->p_ucce); - } while (!(temp & UCCE_GRA)); - - uccf->stopped_tx = 1; - - return 0; -} - -static int ugeth_graceful_stop_rx(ucc_geth_private_t * ugeth) -{ - ucc_fast_private_t *uccf; - u32 cecr_subblock; - u8 temp; - - uccf = ugeth->uccf; - - /* Clear acknowledge bit */ - temp = ugeth->p_rx_glbl_pram->rxgstpack; - temp &= ~GRACEFUL_STOP_ACKNOWLEDGE_RX; - ugeth->p_rx_glbl_pram->rxgstpack = temp; - - /* Keep issuing command and checking acknowledge bit until - it is asserted, according to spec */ - do { - /* Issue host command */ - cecr_subblock = - ucc_fast_get_qe_cr_subblock(ugeth->ug_info->uf_info. - ucc_num); - qe_issue_cmd(QE_GRACEFUL_STOP_RX, cecr_subblock, - (u8) QE_CR_PROTOCOL_ETHERNET, 0); - - temp = ugeth->p_rx_glbl_pram->rxgstpack; - } while (!(temp & GRACEFUL_STOP_ACKNOWLEDGE_RX)); - - uccf->stopped_rx = 1; - - return 0; -} - -static int ugeth_restart_tx(ucc_geth_private_t *ugeth) -{ - ucc_fast_private_t *uccf; - u32 cecr_subblock; - - uccf = ugeth->uccf; - - cecr_subblock = - ucc_fast_get_qe_cr_subblock(ugeth->ug_info->uf_info.ucc_num); - qe_issue_cmd(QE_RESTART_TX, cecr_subblock, (u8) QE_CR_PROTOCOL_ETHERNET, - 0); - uccf->stopped_tx = 0; - - return 0; -} - -static int ugeth_restart_rx(ucc_geth_private_t *ugeth) -{ - ucc_fast_private_t *uccf; - u32 cecr_subblock; - - uccf = ugeth->uccf; - - cecr_subblock = - ucc_fast_get_qe_cr_subblock(ugeth->ug_info->uf_info.ucc_num); - qe_issue_cmd(QE_RESTART_RX, cecr_subblock, (u8) QE_CR_PROTOCOL_ETHERNET, - 0); - uccf->stopped_rx = 0; - - return 0; -} - -static int ugeth_enable(ucc_geth_private_t *ugeth, comm_dir_e mode) -{ - ucc_fast_private_t *uccf; - int enabled_tx, enabled_rx; - - uccf = ugeth->uccf; - - /* check if the UCC number is in range. */ - if (ugeth->ug_info->uf_info.ucc_num >= UCC_MAX_NUM) { - ugeth_err("%s: ucc_num out of range.", __FUNCTION__); - return -EINVAL; - } - - enabled_tx = uccf->enabled_tx; - enabled_rx = uccf->enabled_rx; - - /* Get Tx and Rx going again, in case this channel was actively - disabled. */ - if ((mode & COMM_DIR_TX) && (!enabled_tx) && uccf->stopped_tx) - ugeth_restart_tx(ugeth); - if ((mode & COMM_DIR_RX) && (!enabled_rx) && uccf->stopped_rx) - ugeth_restart_rx(ugeth); - - ucc_fast_enable(uccf, mode); /* OK to do even if not disabled */ - - return 0; - -} - -static int ugeth_disable(ucc_geth_private_t * ugeth, comm_dir_e mode) -{ - ucc_fast_private_t *uccf; - - uccf = ugeth->uccf; - - /* check if the UCC number is in range. */ - if (ugeth->ug_info->uf_info.ucc_num >= UCC_MAX_NUM) { - ugeth_err("%s: ucc_num out of range.", __FUNCTION__); - return -EINVAL; - } - - /* Stop any transmissions */ - if ((mode & COMM_DIR_TX) && uccf->enabled_tx && !uccf->stopped_tx) - ugeth_graceful_stop_tx(ugeth); - - /* Stop any receptions */ - if ((mode & COMM_DIR_RX) && uccf->enabled_rx && !uccf->stopped_rx) - ugeth_graceful_stop_rx(ugeth); - - ucc_fast_disable(ugeth->uccf, mode); /* OK to do even if not enabled */ - - return 0; -} - -static void ugeth_dump_regs(ucc_geth_private_t *ugeth) -{ -#ifdef DEBUG - ucc_fast_dump_regs(ugeth->uccf); - dump_regs(ugeth); - dump_bds(ugeth); -#endif -} - -#ifdef CONFIG_UGETH_FILTERING -static int ugeth_ext_filtering_serialize_tad(ucc_geth_tad_params_t * - p_UccGethTadParams, - qe_fltr_tad_t *qe_fltr_tad) -{ - u16 temp; - - /* Zero serialized TAD */ - memset(qe_fltr_tad, 0, QE_FLTR_TAD_SIZE); - - qe_fltr_tad->serialized[0] |= UCC_GETH_TAD_V; /* Must have this */ - if (p_UccGethTadParams->rx_non_dynamic_extended_features_mode || - (p_UccGethTadParams->vtag_op != UCC_GETH_VLAN_OPERATION_TAGGED_NOP) - || (p_UccGethTadParams->vnontag_op != - UCC_GETH_VLAN_OPERATION_NON_TAGGED_NOP) - ) - qe_fltr_tad->serialized[0] |= UCC_GETH_TAD_EF; - if (p_UccGethTadParams->reject_frame) - qe_fltr_tad->serialized[0] |= UCC_GETH_TAD_REJ; - temp = - (u16) (((u16) p_UccGethTadParams-> - vtag_op) << UCC_GETH_TAD_VTAG_OP_SHIFT); - qe_fltr_tad->serialized[0] |= (u8) (temp >> 8); /* upper bits */ - - qe_fltr_tad->serialized[1] |= (u8) (temp & 0x00ff); /* lower bits */ - if (p_UccGethTadParams->vnontag_op == - UCC_GETH_VLAN_OPERATION_NON_TAGGED_Q_TAG_INSERT) - qe_fltr_tad->serialized[1] |= UCC_GETH_TAD_V_NON_VTAG_OP; - qe_fltr_tad->serialized[1] |= - p_UccGethTadParams->rqos << UCC_GETH_TAD_RQOS_SHIFT; - - qe_fltr_tad->serialized[2] |= - p_UccGethTadParams->vpri << UCC_GETH_TAD_V_PRIORITY_SHIFT; - /* upper bits */ - qe_fltr_tad->serialized[2] |= (u8) (p_UccGethTadParams->vid >> 8); - /* lower bits */ - qe_fltr_tad->serialized[3] |= (u8) (p_UccGethTadParams->vid & 0x00ff); - - return 0; -} - -static enet_addr_container_t - *ugeth_82xx_filtering_get_match_addr_in_hash(ucc_geth_private_t *ugeth, - enet_addr_t *p_enet_addr) -{ - enet_addr_container_t *enet_addr_cont; - struct list_head *p_lh; - u16 i, num; - int32_t j; - u8 *p_counter; - - if ((*p_enet_addr)[0] & ENET_GROUP_ADDR) { - p_lh = &ugeth->group_hash_q; - p_counter = &(ugeth->numGroupAddrInHash); - } else { - p_lh = &ugeth->ind_hash_q; - p_counter = &(ugeth->numIndAddrInHash); - } - - if (!p_lh) - return NULL; - - num = *p_counter; - - for (i = 0; i < num; i++) { - enet_addr_cont = - (enet_addr_container_t *) - ENET_ADDR_CONT_ENTRY(dequeue(p_lh)); - for (j = ENET_NUM_OCTETS_PER_ADDRESS - 1; j >= 0; j--) { - if ((*p_enet_addr)[j] != (enet_addr_cont->address)[j]) - break; - if (j == 0) - return enet_addr_cont; /* Found */ - } - enqueue(p_lh, &enet_addr_cont->node); /* Put it back */ - } - return NULL; -} - -static int ugeth_82xx_filtering_add_addr_in_hash(ucc_geth_private_t *ugeth, - enet_addr_t *p_enet_addr) -{ - ucc_geth_enet_address_recognition_location_e location; - enet_addr_container_t *enet_addr_cont; - struct list_head *p_lh; - u8 i; - u32 limit; - u8 *p_counter; - - if ((*p_enet_addr)[0] & ENET_GROUP_ADDR) { - p_lh = &ugeth->group_hash_q; - limit = ugeth->ug_info->maxGroupAddrInHash; - location = - UCC_GETH_ENET_ADDRESS_RECOGNITION_LOCATION_GROUP_HASH; - p_counter = &(ugeth->numGroupAddrInHash); - } else { - p_lh = &ugeth->ind_hash_q; - limit = ugeth->ug_info->maxIndAddrInHash; - location = - UCC_GETH_ENET_ADDRESS_RECOGNITION_LOCATION_INDIVIDUAL_HASH; - p_counter = &(ugeth->numIndAddrInHash); - } - - if ((enet_addr_cont = - ugeth_82xx_filtering_get_match_addr_in_hash(ugeth, p_enet_addr))) { - list_add(p_lh, &enet_addr_cont->node); /* Put it back */ - return 0; - } - if ((!p_lh) || (!(*p_counter < limit))) - return -EBUSY; - if (!(enet_addr_cont = get_enet_addr_container())) - return -ENOMEM; - for (i = 0; i < ENET_NUM_OCTETS_PER_ADDRESS; i++) - (enet_addr_cont->address)[i] = (*p_enet_addr)[i]; - enet_addr_cont->location = location; - enqueue(p_lh, &enet_addr_cont->node); /* Put it back */ - ++(*p_counter); - - hw_add_addr_in_hash(ugeth, &(enet_addr_cont->address)); - - return 0; -} - -static int ugeth_82xx_filtering_clear_addr_in_hash(ucc_geth_private_t *ugeth, - enet_addr_t *p_enet_addr) -{ - ucc_geth_82xx_address_filtering_pram_t *p_82xx_addr_filt; - enet_addr_container_t *enet_addr_cont; - ucc_fast_private_t *uccf; - comm_dir_e comm_dir; - u16 i, num; - struct list_head *p_lh; - u32 *addr_h, *addr_l; - u8 *p_counter; - - uccf = ugeth->uccf; - - p_82xx_addr_filt = - (ucc_geth_82xx_address_filtering_pram_t *) ugeth->p_rx_glbl_pram-> - addressfiltering; - - if (! - (enet_addr_cont = - ugeth_82xx_filtering_get_match_addr_in_hash(ugeth, p_enet_addr))) - return -ENOENT; - - /* It's been found and removed from the CQ. */ - /* Now destroy its container */ - put_enet_addr_container(enet_addr_cont); - - if ((*p_enet_addr)[0] & ENET_GROUP_ADDR) { - addr_h = &(p_82xx_addr_filt->gaddr_h); - addr_l = &(p_82xx_addr_filt->gaddr_l); - p_lh = &ugeth->group_hash_q; - p_counter = &(ugeth->numGroupAddrInHash); - } else { - addr_h = &(p_82xx_addr_filt->iaddr_h); - addr_l = &(p_82xx_addr_filt->iaddr_l); - p_lh = &ugeth->ind_hash_q; - p_counter = &(ugeth->numIndAddrInHash); - } - - comm_dir = 0; - if (uccf->enabled_tx) - comm_dir |= COMM_DIR_TX; - if (uccf->enabled_rx) - comm_dir |= COMM_DIR_RX; - if (comm_dir) - ugeth_disable(ugeth, comm_dir); - - /* Clear the hash table. */ - out_be32(addr_h, 0x00000000); - out_be32(addr_l, 0x00000000); - - /* Add all remaining CQ elements back into hash */ - num = --(*p_counter); - for (i = 0; i < num; i++) { - enet_addr_cont = - (enet_addr_container_t *) - ENET_ADDR_CONT_ENTRY(dequeue(p_lh)); - hw_add_addr_in_hash(ugeth, &(enet_addr_cont->address)); - enqueue(p_lh, &enet_addr_cont->node); /* Put it back */ - } - - if (comm_dir) - ugeth_enable(ugeth, comm_dir); - - return 0; -} -#endif /* CONFIG_UGETH_FILTERING */ - -static int ugeth_82xx_filtering_clear_all_addr_in_hash(ucc_geth_private_t * - ugeth, - enet_addr_type_e - enet_addr_type) -{ - ucc_geth_82xx_address_filtering_pram_t *p_82xx_addr_filt; - ucc_fast_private_t *uccf; - comm_dir_e comm_dir; - struct list_head *p_lh; - u16 i, num; - u32 *addr_h, *addr_l; - u8 *p_counter; - - uccf = ugeth->uccf; - - p_82xx_addr_filt = - (ucc_geth_82xx_address_filtering_pram_t *) ugeth->p_rx_glbl_pram-> - addressfiltering; - - if (enet_addr_type == ENET_ADDR_TYPE_GROUP) { - addr_h = &(p_82xx_addr_filt->gaddr_h); - addr_l = &(p_82xx_addr_filt->gaddr_l); - p_lh = &ugeth->group_hash_q; - p_counter = &(ugeth->numGroupAddrInHash); - } else if (enet_addr_type == ENET_ADDR_TYPE_INDIVIDUAL) { - addr_h = &(p_82xx_addr_filt->iaddr_h); - addr_l = &(p_82xx_addr_filt->iaddr_l); - p_lh = &ugeth->ind_hash_q; - p_counter = &(ugeth->numIndAddrInHash); - } else - return -EINVAL; - - comm_dir = 0; - if (uccf->enabled_tx) - comm_dir |= COMM_DIR_TX; - if (uccf->enabled_rx) - comm_dir |= COMM_DIR_RX; - if (comm_dir) - ugeth_disable(ugeth, comm_dir); - - /* Clear the hash table. */ - out_be32(addr_h, 0x00000000); - out_be32(addr_l, 0x00000000); - - if (!p_lh) - return 0; - - num = *p_counter; - - /* Delete all remaining CQ elements */ - for (i = 0; i < num; i++) - put_enet_addr_container(ENET_ADDR_CONT_ENTRY(dequeue(p_lh))); - - *p_counter = 0; - - if (comm_dir) - ugeth_enable(ugeth, comm_dir); - - return 0; -} - -#ifdef CONFIG_UGETH_FILTERING -static int ugeth_82xx_filtering_add_addr_in_paddr(ucc_geth_private_t *ugeth, - enet_addr_t *p_enet_addr, - u8 paddr_num) -{ - int i; - - if ((*p_enet_addr)[0] & ENET_GROUP_ADDR) - ugeth_warn - ("%s: multicast address added to paddr will have no " - "effect - is this what you wanted?", - __FUNCTION__); - - ugeth->indAddrRegUsed[paddr_num] = 1; /* mark this paddr as used */ - /* store address in our database */ - for (i = 0; i < ENET_NUM_OCTETS_PER_ADDRESS; i++) - ugeth->paddr[paddr_num][i] = (*p_enet_addr)[i]; - /* put in hardware */ - return hw_add_addr_in_paddr(ugeth, p_enet_addr, paddr_num); -} -#endif /* CONFIG_UGETH_FILTERING */ - -static int ugeth_82xx_filtering_clear_addr_in_paddr(ucc_geth_private_t *ugeth, - u8 paddr_num) -{ - ugeth->indAddrRegUsed[paddr_num] = 0; /* mark this paddr as not used */ - return hw_clear_addr_in_paddr(ugeth, paddr_num);/* clear in hardware */ -} - -static void ucc_geth_memclean(ucc_geth_private_t *ugeth) -{ - u16 i, j; - u8 *bd; - - if (!ugeth) - return; - - if (ugeth->uccf) - ucc_fast_free(ugeth->uccf); - - if (ugeth->p_thread_data_tx) { - qe_muram_free(ugeth->thread_dat_tx_offset); - ugeth->p_thread_data_tx = NULL; - } - if (ugeth->p_thread_data_rx) { - qe_muram_free(ugeth->thread_dat_rx_offset); - ugeth->p_thread_data_rx = NULL; - } - if (ugeth->p_exf_glbl_param) { - qe_muram_free(ugeth->exf_glbl_param_offset); - ugeth->p_exf_glbl_param = NULL; - } - if (ugeth->p_rx_glbl_pram) { - qe_muram_free(ugeth->rx_glbl_pram_offset); - ugeth->p_rx_glbl_pram = NULL; - } - if (ugeth->p_tx_glbl_pram) { - qe_muram_free(ugeth->tx_glbl_pram_offset); - ugeth->p_tx_glbl_pram = NULL; - } - if (ugeth->p_send_q_mem_reg) { - qe_muram_free(ugeth->send_q_mem_reg_offset); - ugeth->p_send_q_mem_reg = NULL; - } - if (ugeth->p_scheduler) { - qe_muram_free(ugeth->scheduler_offset); - ugeth->p_scheduler = NULL; - } - if (ugeth->p_tx_fw_statistics_pram) { - qe_muram_free(ugeth->tx_fw_statistics_pram_offset); - ugeth->p_tx_fw_statistics_pram = NULL; - } - if (ugeth->p_rx_fw_statistics_pram) { - qe_muram_free(ugeth->rx_fw_statistics_pram_offset); - ugeth->p_rx_fw_statistics_pram = NULL; - } - if (ugeth->p_rx_irq_coalescing_tbl) { - qe_muram_free(ugeth->rx_irq_coalescing_tbl_offset); - ugeth->p_rx_irq_coalescing_tbl = NULL; - } - if (ugeth->p_rx_bd_qs_tbl) { - qe_muram_free(ugeth->rx_bd_qs_tbl_offset); - ugeth->p_rx_bd_qs_tbl = NULL; - } - if (ugeth->p_init_enet_param_shadow) { - return_init_enet_entries(ugeth, - &(ugeth->p_init_enet_param_shadow-> - rxthread[0]), - ENET_INIT_PARAM_MAX_ENTRIES_RX, - ugeth->ug_info->riscRx, 1); - return_init_enet_entries(ugeth, - &(ugeth->p_init_enet_param_shadow-> - txthread[0]), - ENET_INIT_PARAM_MAX_ENTRIES_TX, - ugeth->ug_info->riscTx, 0); - kfree(ugeth->p_init_enet_param_shadow); - ugeth->p_init_enet_param_shadow = NULL; - } - for (i = 0; i < ugeth->ug_info->numQueuesTx; i++) { - bd = ugeth->p_tx_bd_ring[i]; - for (j = 0; j < ugeth->ug_info->bdRingLenTx[i]; j++) { - if (ugeth->tx_skbuff[i][j]) { - dma_unmap_single(NULL, - BD_BUFFER_ARG(bd), - (BD_STATUS_AND_LENGTH(bd) & - BD_LENGTH_MASK), - DMA_TO_DEVICE); - dev_kfree_skb_any(ugeth->tx_skbuff[i][j]); - ugeth->tx_skbuff[i][j] = NULL; - } - } - - kfree(ugeth->tx_skbuff[i]); - - if (ugeth->p_tx_bd_ring[i]) { - if (ugeth->ug_info->uf_info.bd_mem_part == - MEM_PART_SYSTEM) - kfree((void *)ugeth->tx_bd_ring_offset[i]); - else if (ugeth->ug_info->uf_info.bd_mem_part == - MEM_PART_MURAM) - qe_muram_free(ugeth->tx_bd_ring_offset[i]); - ugeth->p_tx_bd_ring[i] = NULL; - } - } - for (i = 0; i < ugeth->ug_info->numQueuesRx; i++) { - if (ugeth->p_rx_bd_ring[i]) { - /* Return existing data buffers in ring */ - bd = ugeth->p_rx_bd_ring[i]; - for (j = 0; j < ugeth->ug_info->bdRingLenRx[i]; j++) { - if (ugeth->rx_skbuff[i][j]) { - dma_unmap_single(NULL, BD_BUFFER(bd), - ugeth->ug_info-> - uf_info. - max_rx_buf_length + - UCC_GETH_RX_DATA_BUF_ALIGNMENT, - DMA_FROM_DEVICE); - - dev_kfree_skb_any(ugeth-> - rx_skbuff[i][j]); - ugeth->rx_skbuff[i][j] = NULL; - } - bd += UCC_GETH_SIZE_OF_BD; - } - - kfree(ugeth->rx_skbuff[i]); - - if (ugeth->ug_info->uf_info.bd_mem_part == - MEM_PART_SYSTEM) - kfree((void *)ugeth->rx_bd_ring_offset[i]); - else if (ugeth->ug_info->uf_info.bd_mem_part == - MEM_PART_MURAM) - qe_muram_free(ugeth->rx_bd_ring_offset[i]); - ugeth->p_rx_bd_ring[i] = NULL; - } - } - while (!list_empty(&ugeth->group_hash_q)) - put_enet_addr_container(ENET_ADDR_CONT_ENTRY - (dequeue(&ugeth->group_hash_q))); - while (!list_empty(&ugeth->ind_hash_q)) - put_enet_addr_container(ENET_ADDR_CONT_ENTRY - (dequeue(&ugeth->ind_hash_q))); - -} - -static void ucc_geth_set_multi(struct net_device *dev) -{ - ucc_geth_private_t *ugeth; - struct dev_mc_list *dmi; - ucc_fast_t *uf_regs; - ucc_geth_82xx_address_filtering_pram_t *p_82xx_addr_filt; - enet_addr_t tempaddr; - u8 *mcptr, *tdptr; - int i, j; - - ugeth = netdev_priv(dev); - - uf_regs = ugeth->uccf->uf_regs; - - if (dev->flags & IFF_PROMISC) { - - /* Log any net taps. */ - printk("%s: Promiscuous mode enabled.\n", dev->name); - uf_regs->upsmr |= UPSMR_PRO; - - } else { - - uf_regs->upsmr &= ~UPSMR_PRO; - - p_82xx_addr_filt = - (ucc_geth_82xx_address_filtering_pram_t *) ugeth-> - p_rx_glbl_pram->addressfiltering; - - if (dev->flags & IFF_ALLMULTI) { - /* Catch all multicast addresses, so set the - * filter to all 1's. - */ - out_be32(&p_82xx_addr_filt->gaddr_h, 0xffffffff); - out_be32(&p_82xx_addr_filt->gaddr_l, 0xffffffff); - } else { - /* Clear filter and add the addresses in the list. - */ - out_be32(&p_82xx_addr_filt->gaddr_h, 0x0); - out_be32(&p_82xx_addr_filt->gaddr_l, 0x0); - - dmi = dev->mc_list; - - for (i = 0; i < dev->mc_count; i++, dmi = dmi->next) { - - /* Only support group multicast for now. - */ - if (!(dmi->dmi_addr[0] & 1)) - continue; - - /* The address in dmi_addr is LSB first, - * and taddr is MSB first. We have to - * copy bytes MSB first from dmi_addr. - */ - mcptr = (u8 *) dmi->dmi_addr + 5; - tdptr = (u8 *) & tempaddr; - for (j = 0; j < 6; j++) - *tdptr++ = *mcptr--; - - /* Ask CPM to run CRC and set bit in - * filter mask. - */ - hw_add_addr_in_hash(ugeth, &tempaddr); - - } - } - } -} - -static void ucc_geth_stop(ucc_geth_private_t *ugeth) -{ - ucc_geth_t *ug_regs = ugeth->ug_regs; - u32 tempval; - - ugeth_vdbg("%s: IN", __FUNCTION__); - - /* Disable the controller */ - ugeth_disable(ugeth, COMM_DIR_RX_AND_TX); - - /* Tell the kernel the link is down */ - ugeth->mii_info->link = 0; - adjust_link(ugeth->dev); - - /* Mask all interrupts */ - out_be32(ugeth->uccf->p_ucce, 0x00000000); - - /* Clear all interrupts */ - out_be32(ugeth->uccf->p_ucce, 0xffffffff); - - /* Disable Rx and Tx */ - tempval = in_be32(&ug_regs->maccfg1); - tempval &= ~(MACCFG1_ENABLE_RX | MACCFG1_ENABLE_TX); - out_be32(&ug_regs->maccfg1, tempval); - - if (ugeth->ug_info->board_flags & FSL_UGETH_BRD_HAS_PHY_INTR) { - /* Clear any pending interrupts */ - mii_clear_phy_interrupt(ugeth->mii_info); - - /* Disable PHY Interrupts */ - mii_configure_phy_interrupt(ugeth->mii_info, - MII_INTERRUPT_DISABLED); - } - - free_irq(ugeth->ug_info->uf_info.irq, ugeth->dev); - - if (ugeth->ug_info->board_flags & FSL_UGETH_BRD_HAS_PHY_INTR) { - free_irq(ugeth->ug_info->phy_interrupt, ugeth->dev); - } else { - del_timer_sync(&ugeth->phy_info_timer); - } - - ucc_geth_memclean(ugeth); -} - -static int ucc_geth_startup(ucc_geth_private_t *ugeth) -{ - ucc_geth_82xx_address_filtering_pram_t *p_82xx_addr_filt; - ucc_geth_init_pram_t *p_init_enet_pram; - ucc_fast_private_t *uccf; - ucc_geth_info_t *ug_info; - ucc_fast_info_t *uf_info; - ucc_fast_t *uf_regs; - ucc_geth_t *ug_regs; - int ret_val = -EINVAL; - u32 remoder = UCC_GETH_REMODER_INIT; - u32 init_enet_pram_offset, cecr_subblock, command, maccfg1; - u32 ifstat, i, j, size, l2qt, l3qt, length; - u16 temoder = UCC_GETH_TEMODER_INIT; - u16 test; - u8 function_code = 0; - u8 *bd, *endOfRing; - u8 numThreadsRxNumerical, numThreadsTxNumerical; - - ugeth_vdbg("%s: IN", __FUNCTION__); - - ug_info = ugeth->ug_info; - uf_info = &ug_info->uf_info; - - if (!((uf_info->bd_mem_part == MEM_PART_SYSTEM) || - (uf_info->bd_mem_part == MEM_PART_MURAM))) { - ugeth_err("%s: Bad memory partition value.", __FUNCTION__); - return -EINVAL; - } - - /* Rx BD lengths */ - for (i = 0; i < ug_info->numQueuesRx; i++) { - if ((ug_info->bdRingLenRx[i] < UCC_GETH_RX_BD_RING_SIZE_MIN) || - (ug_info->bdRingLenRx[i] % - UCC_GETH_RX_BD_RING_SIZE_ALIGNMENT)) { - ugeth_err - ("%s: Rx BD ring length must be multiple of 4," - " no smaller than 8.", __FUNCTION__); - return -EINVAL; - } - } - - /* Tx BD lengths */ - for (i = 0; i < ug_info->numQueuesTx; i++) { - if (ug_info->bdRingLenTx[i] < UCC_GETH_TX_BD_RING_SIZE_MIN) { - ugeth_err - ("%s: Tx BD ring length must be no smaller than 2.", - __FUNCTION__); - return -EINVAL; - } - } - - /* mrblr */ - if ((uf_info->max_rx_buf_length == 0) || - (uf_info->max_rx_buf_length % UCC_GETH_MRBLR_ALIGNMENT)) { - ugeth_err - ("%s: max_rx_buf_length must be non-zero multiple of 128.", - __FUNCTION__); - return -EINVAL; - } - - /* num Tx queues */ - if (ug_info->numQueuesTx > NUM_TX_QUEUES) { - ugeth_err("%s: number of tx queues too large.", __FUNCTION__); - return -EINVAL; - } - - /* num Rx queues */ - if (ug_info->numQueuesRx > NUM_RX_QUEUES) { - ugeth_err("%s: number of rx queues too large.", __FUNCTION__); - return -EINVAL; - } - - /* l2qt */ - for (i = 0; i < UCC_GETH_VLAN_PRIORITY_MAX; i++) { - if (ug_info->l2qt[i] >= ug_info->numQueuesRx) { - ugeth_err - ("%s: VLAN priority table entry must not be" - " larger than number of Rx queues.", - __FUNCTION__); - return -EINVAL; - } - } - - /* l3qt */ - for (i = 0; i < UCC_GETH_IP_PRIORITY_MAX; i++) { - if (ug_info->l3qt[i] >= ug_info->numQueuesRx) { - ugeth_err - ("%s: IP priority table entry must not be" - " larger than number of Rx queues.", - __FUNCTION__); - return -EINVAL; - } - } - - if (ug_info->cam && !ug_info->ecamptr) { - ugeth_err("%s: If cam mode is chosen, must supply cam ptr.", - __FUNCTION__); - return -EINVAL; - } - - if ((ug_info->numStationAddresses != - UCC_GETH_NUM_OF_STATION_ADDRESSES_1) - && ug_info->rxExtendedFiltering) { - ugeth_err("%s: Number of station addresses greater than 1 " - "not allowed in extended parsing mode.", - __FUNCTION__); - return -EINVAL; - } - - /* Generate uccm_mask for receive */ - uf_info->uccm_mask = ug_info->eventRegMask & UCCE_OTHER;/* Errors */ - for (i = 0; i < ug_info->numQueuesRx; i++) - uf_info->uccm_mask |= (UCCE_RXBF_SINGLE_MASK << i); - - for (i = 0; i < ug_info->numQueuesTx; i++) - uf_info->uccm_mask |= (UCCE_TXBF_SINGLE_MASK << i); - /* Initialize the general fast UCC block. */ - if (ucc_fast_init(uf_info, &uccf)) { - ugeth_err("%s: Failed to init uccf.", __FUNCTION__); - ucc_geth_memclean(ugeth); - return -ENOMEM; - } - ugeth->uccf = uccf; - - switch (ug_info->numThreadsRx) { - case UCC_GETH_NUM_OF_THREADS_1: - numThreadsRxNumerical = 1; - break; - case UCC_GETH_NUM_OF_THREADS_2: - numThreadsRxNumerical = 2; - break; - case UCC_GETH_NUM_OF_THREADS_4: - numThreadsRxNumerical = 4; - break; - case UCC_GETH_NUM_OF_THREADS_6: - numThreadsRxNumerical = 6; - break; - case UCC_GETH_NUM_OF_THREADS_8: - numThreadsRxNumerical = 8; - break; - default: - ugeth_err("%s: Bad number of Rx threads value.", __FUNCTION__); - ucc_geth_memclean(ugeth); - return -EINVAL; - break; - } - - switch (ug_info->numThreadsTx) { - case UCC_GETH_NUM_OF_THREADS_1: - numThreadsTxNumerical = 1; - break; - case UCC_GETH_NUM_OF_THREADS_2: - numThreadsTxNumerical = 2; - break; - case UCC_GETH_NUM_OF_THREADS_4: - numThreadsTxNumerical = 4; - break; - case UCC_GETH_NUM_OF_THREADS_6: - numThreadsTxNumerical = 6; - break; - case UCC_GETH_NUM_OF_THREADS_8: - numThreadsTxNumerical = 8; - break; - default: - ugeth_err("%s: Bad number of Tx threads value.", __FUNCTION__); - ucc_geth_memclean(ugeth); - return -EINVAL; - break; - } - - /* Calculate rx_extended_features */ - ugeth->rx_non_dynamic_extended_features = ug_info->ipCheckSumCheck || - ug_info->ipAddressAlignment || - (ug_info->numStationAddresses != - UCC_GETH_NUM_OF_STATION_ADDRESSES_1); - - ugeth->rx_extended_features = ugeth->rx_non_dynamic_extended_features || - (ug_info->vlanOperationTagged != UCC_GETH_VLAN_OPERATION_TAGGED_NOP) - || (ug_info->vlanOperationNonTagged != - UCC_GETH_VLAN_OPERATION_NON_TAGGED_NOP); - - uf_regs = uccf->uf_regs; - ug_regs = (ucc_geth_t *) (uccf->uf_regs); - ugeth->ug_regs = ug_regs; - - init_default_reg_vals(&uf_regs->upsmr, - &ug_regs->maccfg1, &ug_regs->maccfg2); - - /* Set UPSMR */ - /* For more details see the hardware spec. */ - init_rx_parameters(ug_info->bro, - ug_info->rsh, ug_info->pro, &uf_regs->upsmr); - - /* We're going to ignore other registers for now, */ - /* except as needed to get up and running */ - - /* Set MACCFG1 */ - /* For more details see the hardware spec. */ - init_flow_control_params(ug_info->aufc, - ug_info->receiveFlowControl, - 1, - ug_info->pausePeriod, - ug_info->extensionField, - &uf_regs->upsmr, - &ug_regs->uempr, &ug_regs->maccfg1); - - maccfg1 = in_be32(&ug_regs->maccfg1); - maccfg1 |= MACCFG1_ENABLE_RX; - maccfg1 |= MACCFG1_ENABLE_TX; - out_be32(&ug_regs->maccfg1, maccfg1); - - /* Set IPGIFG */ - /* For more details see the hardware spec. */ - ret_val = init_inter_frame_gap_params(ug_info->nonBackToBackIfgPart1, - ug_info->nonBackToBackIfgPart2, - ug_info-> - miminumInterFrameGapEnforcement, - ug_info->backToBackInterFrameGap, - &ug_regs->ipgifg); - if (ret_val != 0) { - ugeth_err("%s: IPGIFG initialization parameter too large.", - __FUNCTION__); - ucc_geth_memclean(ugeth); - return ret_val; - } - - /* Set HAFDUP */ - /* For more details see the hardware spec. */ - ret_val = init_half_duplex_params(ug_info->altBeb, - ug_info->backPressureNoBackoff, - ug_info->noBackoff, - ug_info->excessDefer, - ug_info->altBebTruncation, - ug_info->maxRetransmission, - ug_info->collisionWindow, - &ug_regs->hafdup); - if (ret_val != 0) { - ugeth_err("%s: Half Duplex initialization parameter too large.", - __FUNCTION__); - ucc_geth_memclean(ugeth); - return ret_val; - } - - /* Set IFSTAT */ - /* For more details see the hardware spec. */ - /* Read only - resets upon read */ - ifstat = in_be32(&ug_regs->ifstat); - - /* Clear UEMPR */ - /* For more details see the hardware spec. */ - out_be32(&ug_regs->uempr, 0); - - /* Set UESCR */ - /* For more details see the hardware spec. */ - init_hw_statistics_gathering_mode((ug_info->statisticsMode & - UCC_GETH_STATISTICS_GATHERING_MODE_HARDWARE), - 0, &uf_regs->upsmr, &ug_regs->uescr); - - /* Allocate Tx bds */ - for (j = 0; j < ug_info->numQueuesTx; j++) { - /* Allocate in multiple of - UCC_GETH_TX_BD_RING_SIZE_MEMORY_ALIGNMENT, - according to spec */ - length = ((ug_info->bdRingLenTx[j] * UCC_GETH_SIZE_OF_BD) - / UCC_GETH_TX_BD_RING_SIZE_MEMORY_ALIGNMENT) - * UCC_GETH_TX_BD_RING_SIZE_MEMORY_ALIGNMENT; - if ((ug_info->bdRingLenTx[j] * UCC_GETH_SIZE_OF_BD) % - UCC_GETH_TX_BD_RING_SIZE_MEMORY_ALIGNMENT) - length += UCC_GETH_TX_BD_RING_SIZE_MEMORY_ALIGNMENT; - if (uf_info->bd_mem_part == MEM_PART_SYSTEM) { - u32 align = 4; - if (UCC_GETH_TX_BD_RING_ALIGNMENT > 4) - align = UCC_GETH_TX_BD_RING_ALIGNMENT; - ugeth->tx_bd_ring_offset[j] = - (u32) (kmalloc((u32) (length + align), - GFP_KERNEL)); - if (ugeth->tx_bd_ring_offset[j] != 0) - ugeth->p_tx_bd_ring[j] = - (void*)((ugeth->tx_bd_ring_offset[j] + - align) & ~(align - 1)); - } else if (uf_info->bd_mem_part == MEM_PART_MURAM) { - ugeth->tx_bd_ring_offset[j] = - qe_muram_alloc(length, - UCC_GETH_TX_BD_RING_ALIGNMENT); - if (!IS_MURAM_ERR(ugeth->tx_bd_ring_offset[j])) - ugeth->p_tx_bd_ring[j] = - (u8 *) qe_muram_addr(ugeth-> - tx_bd_ring_offset[j]); - } - if (!ugeth->p_tx_bd_ring[j]) { - ugeth_err - ("%s: Can not allocate memory for Tx bd rings.", - __FUNCTION__); - ucc_geth_memclean(ugeth); - return -ENOMEM; - } - /* Zero unused end of bd ring, according to spec */ - memset(ugeth->p_tx_bd_ring[j] + - ug_info->bdRingLenTx[j] * UCC_GETH_SIZE_OF_BD, 0, - length - ug_info->bdRingLenTx[j] * UCC_GETH_SIZE_OF_BD); - } - - /* Allocate Rx bds */ - for (j = 0; j < ug_info->numQueuesRx; j++) { - length = ug_info->bdRingLenRx[j] * UCC_GETH_SIZE_OF_BD; - if (uf_info->bd_mem_part == MEM_PART_SYSTEM) { - u32 align = 4; - if (UCC_GETH_RX_BD_RING_ALIGNMENT > 4) - align = UCC_GETH_RX_BD_RING_ALIGNMENT; - ugeth->rx_bd_ring_offset[j] = - (u32) (kmalloc((u32) (length + align), GFP_KERNEL)); - if (ugeth->rx_bd_ring_offset[j] != 0) - ugeth->p_rx_bd_ring[j] = - (void*)((ugeth->rx_bd_ring_offset[j] + - align) & ~(align - 1)); - } else if (uf_info->bd_mem_part == MEM_PART_MURAM) { - ugeth->rx_bd_ring_offset[j] = - qe_muram_alloc(length, - UCC_GETH_RX_BD_RING_ALIGNMENT); - if (!IS_MURAM_ERR(ugeth->rx_bd_ring_offset[j])) - ugeth->p_rx_bd_ring[j] = - (u8 *) qe_muram_addr(ugeth-> - rx_bd_ring_offset[j]); - } - if (!ugeth->p_rx_bd_ring[j]) { - ugeth_err - ("%s: Can not allocate memory for Rx bd rings.", - __FUNCTION__); - ucc_geth_memclean(ugeth); - return -ENOMEM; - } - } - - /* Init Tx bds */ - for (j = 0; j < ug_info->numQueuesTx; j++) { - /* Setup the skbuff rings */ - ugeth->tx_skbuff[j] = - (struct sk_buff **)kmalloc(sizeof(struct sk_buff *) * - ugeth->ug_info->bdRingLenTx[j], - GFP_KERNEL); - - if (ugeth->tx_skbuff[j] == NULL) { - ugeth_err("%s: Could not allocate tx_skbuff", - __FUNCTION__); - ucc_geth_memclean(ugeth); - return -ENOMEM; - } - - for (i = 0; i < ugeth->ug_info->bdRingLenTx[j]; i++) - ugeth->tx_skbuff[j][i] = NULL; - - ugeth->skb_curtx[j] = ugeth->skb_dirtytx[j] = 0; - bd = ugeth->confBd[j] = ugeth->txBd[j] = ugeth->p_tx_bd_ring[j]; - for (i = 0; i < ug_info->bdRingLenTx[j]; i++) { - BD_BUFFER_CLEAR(bd); - BD_STATUS_AND_LENGTH_SET(bd, 0); - bd += UCC_GETH_SIZE_OF_BD; - } - bd -= UCC_GETH_SIZE_OF_BD; - BD_STATUS_AND_LENGTH_SET(bd, T_W);/* for last BD set Wrap bit */ - } - - /* Init Rx bds */ - for (j = 0; j < ug_info->numQueuesRx; j++) { - /* Setup the skbuff rings */ - ugeth->rx_skbuff[j] = - (struct sk_buff **)kmalloc(sizeof(struct sk_buff *) * - ugeth->ug_info->bdRingLenRx[j], - GFP_KERNEL); - - if (ugeth->rx_skbuff[j] == NULL) { - ugeth_err("%s: Could not allocate rx_skbuff", - __FUNCTION__); - ucc_geth_memclean(ugeth); - return -ENOMEM; - } - - for (i = 0; i < ugeth->ug_info->bdRingLenRx[j]; i++) - ugeth->rx_skbuff[j][i] = NULL; - - ugeth->skb_currx[j] = 0; - bd = ugeth->rxBd[j] = ugeth->p_rx_bd_ring[j]; - for (i = 0; i < ug_info->bdRingLenRx[j]; i++) { - BD_STATUS_AND_LENGTH_SET(bd, R_I); - BD_BUFFER_CLEAR(bd); - bd += UCC_GETH_SIZE_OF_BD; - } - bd -= UCC_GETH_SIZE_OF_BD; - BD_STATUS_AND_LENGTH_SET(bd, R_W);/* for last BD set Wrap bit */ - } - - /* - * Global PRAM - */ - /* Tx global PRAM */ - /* Allocate global tx parameter RAM page */ - ugeth->tx_glbl_pram_offset = - qe_muram_alloc(sizeof(ucc_geth_tx_global_pram_t), - UCC_GETH_TX_GLOBAL_PRAM_ALIGNMENT); - if (IS_MURAM_ERR(ugeth->tx_glbl_pram_offset)) { - ugeth_err - ("%s: Can not allocate DPRAM memory for p_tx_glbl_pram.", - __FUNCTION__); - ucc_geth_memclean(ugeth); - return -ENOMEM; - } - ugeth->p_tx_glbl_pram = - (ucc_geth_tx_global_pram_t *) qe_muram_addr(ugeth-> - tx_glbl_pram_offset); - /* Zero out p_tx_glbl_pram */ - memset(ugeth->p_tx_glbl_pram, 0, sizeof(ucc_geth_tx_global_pram_t)); - - /* Fill global PRAM */ - - /* TQPTR */ - /* Size varies with number of Tx threads */ - ugeth->thread_dat_tx_offset = - qe_muram_alloc(numThreadsTxNumerical * - sizeof(ucc_geth_thread_data_tx_t) + - 32 * (numThreadsTxNumerical == 1), - UCC_GETH_THREAD_DATA_ALIGNMENT); - if (IS_MURAM_ERR(ugeth->thread_dat_tx_offset)) { - ugeth_err - ("%s: Can not allocate DPRAM memory for p_thread_data_tx.", - __FUNCTION__); - ucc_geth_memclean(ugeth); - return -ENOMEM; - } - - ugeth->p_thread_data_tx = - (ucc_geth_thread_data_tx_t *) qe_muram_addr(ugeth-> - thread_dat_tx_offset); - out_be32(&ugeth->p_tx_glbl_pram->tqptr, ugeth->thread_dat_tx_offset); - - /* vtagtable */ - for (i = 0; i < UCC_GETH_TX_VTAG_TABLE_ENTRY_MAX; i++) - out_be32(&ugeth->p_tx_glbl_pram->vtagtable[i], - ug_info->vtagtable[i]); - - /* iphoffset */ - for (i = 0; i < TX_IP_OFFSET_ENTRY_MAX; i++) - ugeth->p_tx_glbl_pram->iphoffset[i] = ug_info->iphoffset[i]; - - /* SQPTR */ - /* Size varies with number of Tx queues */ - ugeth->send_q_mem_reg_offset = - qe_muram_alloc(ug_info->numQueuesTx * - sizeof(ucc_geth_send_queue_qd_t), - UCC_GETH_SEND_QUEUE_QUEUE_DESCRIPTOR_ALIGNMENT); - if (IS_MURAM_ERR(ugeth->send_q_mem_reg_offset)) { - ugeth_err - ("%s: Can not allocate DPRAM memory for p_send_q_mem_reg.", - __FUNCTION__); - ucc_geth_memclean(ugeth); - return -ENOMEM; - } - - ugeth->p_send_q_mem_reg = - (ucc_geth_send_queue_mem_region_t *) qe_muram_addr(ugeth-> - send_q_mem_reg_offset); - out_be32(&ugeth->p_tx_glbl_pram->sqptr, ugeth->send_q_mem_reg_offset); - - /* Setup the table */ - /* Assume BD rings are already established */ - for (i = 0; i < ug_info->numQueuesTx; i++) { - endOfRing = - ugeth->p_tx_bd_ring[i] + (ug_info->bdRingLenTx[i] - - 1) * UCC_GETH_SIZE_OF_BD; - if (ugeth->ug_info->uf_info.bd_mem_part == MEM_PART_SYSTEM) { - out_be32(&ugeth->p_send_q_mem_reg->sqqd[i].bd_ring_base, - (u32) virt_to_phys(ugeth->p_tx_bd_ring[i])); - out_be32(&ugeth->p_send_q_mem_reg->sqqd[i]. - last_bd_completed_address, - (u32) virt_to_phys(endOfRing)); - } else if (ugeth->ug_info->uf_info.bd_mem_part == - MEM_PART_MURAM) { - out_be32(&ugeth->p_send_q_mem_reg->sqqd[i].bd_ring_base, - (u32) immrbar_virt_to_phys(ugeth-> - p_tx_bd_ring[i])); - out_be32(&ugeth->p_send_q_mem_reg->sqqd[i]. - last_bd_completed_address, - (u32) immrbar_virt_to_phys(endOfRing)); - } - } - - /* schedulerbasepointer */ - - if (ug_info->numQueuesTx > 1) { - /* scheduler exists only if more than 1 tx queue */ - ugeth->scheduler_offset = - qe_muram_alloc(sizeof(ucc_geth_scheduler_t), - UCC_GETH_SCHEDULER_ALIGNMENT); - if (IS_MURAM_ERR(ugeth->scheduler_offset)) { - ugeth_err - ("%s: Can not allocate DPRAM memory for p_scheduler.", - __FUNCTION__); - ucc_geth_memclean(ugeth); - return -ENOMEM; - } - - ugeth->p_scheduler = - (ucc_geth_scheduler_t *) qe_muram_addr(ugeth-> - scheduler_offset); - out_be32(&ugeth->p_tx_glbl_pram->schedulerbasepointer, - ugeth->scheduler_offset); - /* Zero out p_scheduler */ - memset(ugeth->p_scheduler, 0, sizeof(ucc_geth_scheduler_t)); - - /* Set values in scheduler */ - out_be32(&ugeth->p_scheduler->mblinterval, - ug_info->mblinterval); - out_be16(&ugeth->p_scheduler->nortsrbytetime, - ug_info->nortsrbytetime); - ugeth->p_scheduler->fracsiz = ug_info->fracsiz; - ugeth->p_scheduler->strictpriorityq = ug_info->strictpriorityq; - ugeth->p_scheduler->txasap = ug_info->txasap; - ugeth->p_scheduler->extrabw = ug_info->extrabw; - for (i = 0; i < NUM_TX_QUEUES; i++) - ugeth->p_scheduler->weightfactor[i] = - ug_info->weightfactor[i]; - - /* Set pointers to cpucount registers in scheduler */ - ugeth->p_cpucount[0] = &(ugeth->p_scheduler->cpucount0); - ugeth->p_cpucount[1] = &(ugeth->p_scheduler->cpucount1); - ugeth->p_cpucount[2] = &(ugeth->p_scheduler->cpucount2); - ugeth->p_cpucount[3] = &(ugeth->p_scheduler->cpucount3); - ugeth->p_cpucount[4] = &(ugeth->p_scheduler->cpucount4); - ugeth->p_cpucount[5] = &(ugeth->p_scheduler->cpucount5); - ugeth->p_cpucount[6] = &(ugeth->p_scheduler->cpucount6); - ugeth->p_cpucount[7] = &(ugeth->p_scheduler->cpucount7); - } - - /* schedulerbasepointer */ - /* TxRMON_PTR (statistics) */ - if (ug_info-> - statisticsMode & UCC_GETH_STATISTICS_GATHERING_MODE_FIRMWARE_TX) { - ugeth->tx_fw_statistics_pram_offset = - qe_muram_alloc(sizeof - (ucc_geth_tx_firmware_statistics_pram_t), - UCC_GETH_TX_STATISTICS_ALIGNMENT); - if (IS_MURAM_ERR(ugeth->tx_fw_statistics_pram_offset)) { - ugeth_err - ("%s: Can not allocate DPRAM memory for" - " p_tx_fw_statistics_pram.", __FUNCTION__); - ucc_geth_memclean(ugeth); - return -ENOMEM; - } - ugeth->p_tx_fw_statistics_pram = - (ucc_geth_tx_firmware_statistics_pram_t *) - qe_muram_addr(ugeth->tx_fw_statistics_pram_offset); - /* Zero out p_tx_fw_statistics_pram */ - memset(ugeth->p_tx_fw_statistics_pram, - 0, sizeof(ucc_geth_tx_firmware_statistics_pram_t)); - } - - /* temoder */ - /* Already has speed set */ - - if (ug_info->numQueuesTx > 1) - temoder |= TEMODER_SCHEDULER_ENABLE; - if (ug_info->ipCheckSumGenerate) - temoder |= TEMODER_IP_CHECKSUM_GENERATE; - temoder |= ((ug_info->numQueuesTx - 1) << TEMODER_NUM_OF_QUEUES_SHIFT); - out_be16(&ugeth->p_tx_glbl_pram->temoder, temoder); - - test = in_be16(&ugeth->p_tx_glbl_pram->temoder); - - /* Function code register value to be used later */ - function_code = QE_BMR_BYTE_ORDER_BO_MOT | UCC_FAST_FUNCTION_CODE_GBL; - /* Required for QE */ - - /* function code register */ - out_be32(&ugeth->p_tx_glbl_pram->tstate, ((u32) function_code) << 24); - - /* Rx global PRAM */ - /* Allocate global rx parameter RAM page */ - ugeth->rx_glbl_pram_offset = - qe_muram_alloc(sizeof(ucc_geth_rx_global_pram_t), - UCC_GETH_RX_GLOBAL_PRAM_ALIGNMENT); - if (IS_MURAM_ERR(ugeth->rx_glbl_pram_offset)) { - ugeth_err - ("%s: Can not allocate DPRAM memory for p_rx_glbl_pram.", - __FUNCTION__); - ucc_geth_memclean(ugeth); - return -ENOMEM; - } - ugeth->p_rx_glbl_pram = - (ucc_geth_rx_global_pram_t *) qe_muram_addr(ugeth-> - rx_glbl_pram_offset); - /* Zero out p_rx_glbl_pram */ - memset(ugeth->p_rx_glbl_pram, 0, sizeof(ucc_geth_rx_global_pram_t)); - - /* Fill global PRAM */ - - /* RQPTR */ - /* Size varies with number of Rx threads */ - ugeth->thread_dat_rx_offset = - qe_muram_alloc(numThreadsRxNumerical * - sizeof(ucc_geth_thread_data_rx_t), - UCC_GETH_THREAD_DATA_ALIGNMENT); - if (IS_MURAM_ERR(ugeth->thread_dat_rx_offset)) { - ugeth_err - ("%s: Can not allocate DPRAM memory for p_thread_data_rx.", - __FUNCTION__); - ucc_geth_memclean(ugeth); - return -ENOMEM; - } - - ugeth->p_thread_data_rx = - (ucc_geth_thread_data_rx_t *) qe_muram_addr(ugeth-> - thread_dat_rx_offset); - out_be32(&ugeth->p_rx_glbl_pram->rqptr, ugeth->thread_dat_rx_offset); - - /* typeorlen */ - out_be16(&ugeth->p_rx_glbl_pram->typeorlen, ug_info->typeorlen); - - /* rxrmonbaseptr (statistics) */ - if (ug_info-> - statisticsMode & UCC_GETH_STATISTICS_GATHERING_MODE_FIRMWARE_RX) { - ugeth->rx_fw_statistics_pram_offset = - qe_muram_alloc(sizeof - (ucc_geth_rx_firmware_statistics_pram_t), - UCC_GETH_RX_STATISTICS_ALIGNMENT); - if (IS_MURAM_ERR(ugeth->rx_fw_statistics_pram_offset)) { - ugeth_err - ("%s: Can not allocate DPRAM memory for" - " p_rx_fw_statistics_pram.", __FUNCTION__); - ucc_geth_memclean(ugeth); - return -ENOMEM; - } - ugeth->p_rx_fw_statistics_pram = - (ucc_geth_rx_firmware_statistics_pram_t *) - qe_muram_addr(ugeth->rx_fw_statistics_pram_offset); - /* Zero out p_rx_fw_statistics_pram */ - memset(ugeth->p_rx_fw_statistics_pram, 0, - sizeof(ucc_geth_rx_firmware_statistics_pram_t)); - } - - /* intCoalescingPtr */ - - /* Size varies with number of Rx queues */ - ugeth->rx_irq_coalescing_tbl_offset = - qe_muram_alloc(ug_info->numQueuesRx * - sizeof(ucc_geth_rx_interrupt_coalescing_entry_t), - UCC_GETH_RX_INTERRUPT_COALESCING_ALIGNMENT); - if (IS_MURAM_ERR(ugeth->rx_irq_coalescing_tbl_offset)) { - ugeth_err - ("%s: Can not allocate DPRAM memory for" - " p_rx_irq_coalescing_tbl.", __FUNCTION__); - ucc_geth_memclean(ugeth); - return -ENOMEM; - } - - ugeth->p_rx_irq_coalescing_tbl = - (ucc_geth_rx_interrupt_coalescing_table_t *) - qe_muram_addr(ugeth->rx_irq_coalescing_tbl_offset); - out_be32(&ugeth->p_rx_glbl_pram->intcoalescingptr, - ugeth->rx_irq_coalescing_tbl_offset); - - /* Fill interrupt coalescing table */ - for (i = 0; i < ug_info->numQueuesRx; i++) { - out_be32(&ugeth->p_rx_irq_coalescing_tbl->coalescingentry[i]. - interruptcoalescingmaxvalue, - ug_info->interruptcoalescingmaxvalue[i]); - out_be32(&ugeth->p_rx_irq_coalescing_tbl->coalescingentry[i]. - interruptcoalescingcounter, - ug_info->interruptcoalescingmaxvalue[i]); - } - - /* MRBLR */ - init_max_rx_buff_len(uf_info->max_rx_buf_length, - &ugeth->p_rx_glbl_pram->mrblr); - /* MFLR */ - out_be16(&ugeth->p_rx_glbl_pram->mflr, ug_info->maxFrameLength); - /* MINFLR */ - init_min_frame_len(ug_info->minFrameLength, - &ugeth->p_rx_glbl_pram->minflr, - &ugeth->p_rx_glbl_pram->mrblr); - /* MAXD1 */ - out_be16(&ugeth->p_rx_glbl_pram->maxd1, ug_info->maxD1Length); - /* MAXD2 */ - out_be16(&ugeth->p_rx_glbl_pram->maxd2, ug_info->maxD2Length); - - /* l2qt */ - l2qt = 0; - for (i = 0; i < UCC_GETH_VLAN_PRIORITY_MAX; i++) - l2qt |= (ug_info->l2qt[i] << (28 - 4 * i)); - out_be32(&ugeth->p_rx_glbl_pram->l2qt, l2qt); - - /* l3qt */ - for (j = 0; j < UCC_GETH_IP_PRIORITY_MAX; j += 8) { - l3qt = 0; - for (i = 0; i < 8; i++) - l3qt |= (ug_info->l3qt[j + i] << (28 - 4 * i)); - out_be32(&ugeth->p_rx_glbl_pram->l3qt[j], l3qt); - } - - /* vlantype */ - out_be16(&ugeth->p_rx_glbl_pram->vlantype, ug_info->vlantype); - - /* vlantci */ - out_be16(&ugeth->p_rx_glbl_pram->vlantci, ug_info->vlantci); - - /* ecamptr */ - out_be32(&ugeth->p_rx_glbl_pram->ecamptr, ug_info->ecamptr); - - /* RBDQPTR */ - /* Size varies with number of Rx queues */ - ugeth->rx_bd_qs_tbl_offset = - qe_muram_alloc(ug_info->numQueuesRx * - (sizeof(ucc_geth_rx_bd_queues_entry_t) + - sizeof(ucc_geth_rx_prefetched_bds_t)), - UCC_GETH_RX_BD_QUEUES_ALIGNMENT); - if (IS_MURAM_ERR(ugeth->rx_bd_qs_tbl_offset)) { - ugeth_err - ("%s: Can not allocate DPRAM memory for p_rx_bd_qs_tbl.", - __FUNCTION__); - ucc_geth_memclean(ugeth); - return -ENOMEM; - } - - ugeth->p_rx_bd_qs_tbl = - (ucc_geth_rx_bd_queues_entry_t *) qe_muram_addr(ugeth-> - rx_bd_qs_tbl_offset); - out_be32(&ugeth->p_rx_glbl_pram->rbdqptr, ugeth->rx_bd_qs_tbl_offset); - /* Zero out p_rx_bd_qs_tbl */ - memset(ugeth->p_rx_bd_qs_tbl, - 0, - ug_info->numQueuesRx * (sizeof(ucc_geth_rx_bd_queues_entry_t) + - sizeof(ucc_geth_rx_prefetched_bds_t))); - - /* Setup the table */ - /* Assume BD rings are already established */ - for (i = 0; i < ug_info->numQueuesRx; i++) { - if (ugeth->ug_info->uf_info.bd_mem_part == MEM_PART_SYSTEM) { - out_be32(&ugeth->p_rx_bd_qs_tbl[i].externalbdbaseptr, - (u32) virt_to_phys(ugeth->p_rx_bd_ring[i])); - } else if (ugeth->ug_info->uf_info.bd_mem_part == - MEM_PART_MURAM) { - out_be32(&ugeth->p_rx_bd_qs_tbl[i].externalbdbaseptr, - (u32) immrbar_virt_to_phys(ugeth-> - p_rx_bd_ring[i])); - } - /* rest of fields handled by QE */ - } - - /* remoder */ - /* Already has speed set */ - - if (ugeth->rx_extended_features) - remoder |= REMODER_RX_EXTENDED_FEATURES; - if (ug_info->rxExtendedFiltering) - remoder |= REMODER_RX_EXTENDED_FILTERING; - if (ug_info->dynamicMaxFrameLength) - remoder |= REMODER_DYNAMIC_MAX_FRAME_LENGTH; - if (ug_info->dynamicMinFrameLength) - remoder |= REMODER_DYNAMIC_MIN_FRAME_LENGTH; - remoder |= - ug_info->vlanOperationTagged << REMODER_VLAN_OPERATION_TAGGED_SHIFT; - remoder |= - ug_info-> - vlanOperationNonTagged << REMODER_VLAN_OPERATION_NON_TAGGED_SHIFT; - remoder |= ug_info->rxQoSMode << REMODER_RX_QOS_MODE_SHIFT; - remoder |= ((ug_info->numQueuesRx - 1) << REMODER_NUM_OF_QUEUES_SHIFT); - if (ug_info->ipCheckSumCheck) - remoder |= REMODER_IP_CHECKSUM_CHECK; - if (ug_info->ipAddressAlignment) - remoder |= REMODER_IP_ADDRESS_ALIGNMENT; - out_be32(&ugeth->p_rx_glbl_pram->remoder, remoder); - - /* Note that this function must be called */ - /* ONLY AFTER p_tx_fw_statistics_pram */ - /* andp_UccGethRxFirmwareStatisticsPram are allocated ! */ - init_firmware_statistics_gathering_mode((ug_info-> - statisticsMode & - UCC_GETH_STATISTICS_GATHERING_MODE_FIRMWARE_TX), - (ug_info->statisticsMode & - UCC_GETH_STATISTICS_GATHERING_MODE_FIRMWARE_RX), - &ugeth->p_tx_glbl_pram->txrmonbaseptr, - ugeth->tx_fw_statistics_pram_offset, - &ugeth->p_rx_glbl_pram->rxrmonbaseptr, - ugeth->rx_fw_statistics_pram_offset, - &ugeth->p_tx_glbl_pram->temoder, - &ugeth->p_rx_glbl_pram->remoder); - - /* function code register */ - ugeth->p_rx_glbl_pram->rstate = function_code; - - /* initialize extended filtering */ - if (ug_info->rxExtendedFiltering) { - if (!ug_info->extendedFilteringChainPointer) { - ugeth_err("%s: Null Extended Filtering Chain Pointer.", - __FUNCTION__); - ucc_geth_memclean(ugeth); - return -EINVAL; - } - - /* Allocate memory for extended filtering Mode Global - Parameters */ - ugeth->exf_glbl_param_offset = - qe_muram_alloc(sizeof(ucc_geth_exf_global_pram_t), - UCC_GETH_RX_EXTENDED_FILTERING_GLOBAL_PARAMETERS_ALIGNMENT); - if (IS_MURAM_ERR(ugeth->exf_glbl_param_offset)) { - ugeth_err - ("%s: Can not allocate DPRAM memory for" - " p_exf_glbl_param.", __FUNCTION__); - ucc_geth_memclean(ugeth); - return -ENOMEM; - } - - ugeth->p_exf_glbl_param = - (ucc_geth_exf_global_pram_t *) qe_muram_addr(ugeth-> - exf_glbl_param_offset); - out_be32(&ugeth->p_rx_glbl_pram->exfGlobalParam, - ugeth->exf_glbl_param_offset); - out_be32(&ugeth->p_exf_glbl_param->l2pcdptr, - (u32) ug_info->extendedFilteringChainPointer); - - } else { /* initialize 82xx style address filtering */ - - /* Init individual address recognition registers to disabled */ - - for (j = 0; j < NUM_OF_PADDRS; j++) - ugeth_82xx_filtering_clear_addr_in_paddr(ugeth, (u8) j); - - /* Create CQs for hash tables */ - if (ug_info->maxGroupAddrInHash > 0) { - INIT_LIST_HEAD(&ugeth->group_hash_q); - } - if (ug_info->maxIndAddrInHash > 0) { - INIT_LIST_HEAD(&ugeth->ind_hash_q); - } - p_82xx_addr_filt = - (ucc_geth_82xx_address_filtering_pram_t *) ugeth-> - p_rx_glbl_pram->addressfiltering; - - ugeth_82xx_filtering_clear_all_addr_in_hash(ugeth, - ENET_ADDR_TYPE_GROUP); - ugeth_82xx_filtering_clear_all_addr_in_hash(ugeth, - ENET_ADDR_TYPE_INDIVIDUAL); - } - - /* - * Initialize UCC at QE level - */ - - command = QE_INIT_TX_RX; - - /* Allocate shadow InitEnet command parameter structure. - * This is needed because after the InitEnet command is executed, - * the structure in DPRAM is released, because DPRAM is a premium - * resource. - * This shadow structure keeps a copy of what was done so that the - * allocated resources can be released when the channel is freed. - */ - if (!(ugeth->p_init_enet_param_shadow = - (ucc_geth_init_pram_t *) kmalloc(sizeof(ucc_geth_init_pram_t), - GFP_KERNEL))) { - ugeth_err - ("%s: Can not allocate memory for" - " p_UccInitEnetParamShadows.", __FUNCTION__); - ucc_geth_memclean(ugeth); - return -ENOMEM; - } - /* Zero out *p_init_enet_param_shadow */ - memset((char *)ugeth->p_init_enet_param_shadow, - 0, sizeof(ucc_geth_init_pram_t)); - - /* Fill shadow InitEnet command parameter structure */ - - ugeth->p_init_enet_param_shadow->resinit1 = - ENET_INIT_PARAM_MAGIC_RES_INIT1; - ugeth->p_init_enet_param_shadow->resinit2 = - ENET_INIT_PARAM_MAGIC_RES_INIT2; - ugeth->p_init_enet_param_shadow->resinit3 = - ENET_INIT_PARAM_MAGIC_RES_INIT3; - ugeth->p_init_enet_param_shadow->resinit4 = - ENET_INIT_PARAM_MAGIC_RES_INIT4; - ugeth->p_init_enet_param_shadow->resinit5 = - ENET_INIT_PARAM_MAGIC_RES_INIT5; - ugeth->p_init_enet_param_shadow->rgftgfrxglobal |= - ((u32) ug_info->numThreadsRx) << ENET_INIT_PARAM_RGF_SHIFT; - ugeth->p_init_enet_param_shadow->rgftgfrxglobal |= - ((u32) ug_info->numThreadsTx) << ENET_INIT_PARAM_TGF_SHIFT; - - ugeth->p_init_enet_param_shadow->rgftgfrxglobal |= - ugeth->rx_glbl_pram_offset | ug_info->riscRx; - if ((ug_info->largestexternallookupkeysize != - QE_FLTR_LARGEST_EXTERNAL_TABLE_LOOKUP_KEY_SIZE_NONE) - && (ug_info->largestexternallookupkeysize != - QE_FLTR_LARGEST_EXTERNAL_TABLE_LOOKUP_KEY_SIZE_8_BYTES) - && (ug_info->largestexternallookupkeysize != - QE_FLTR_LARGEST_EXTERNAL_TABLE_LOOKUP_KEY_SIZE_16_BYTES)) { - ugeth_err("%s: Invalid largest External Lookup Key Size.", - __FUNCTION__); - ucc_geth_memclean(ugeth); - return -EINVAL; - } - ugeth->p_init_enet_param_shadow->largestexternallookupkeysize = - ug_info->largestexternallookupkeysize; - size = sizeof(ucc_geth_thread_rx_pram_t); - if (ug_info->rxExtendedFiltering) { - size += THREAD_RX_PRAM_ADDITIONAL_FOR_EXTENDED_FILTERING; - if (ug_info->largestexternallookupkeysize == - QE_FLTR_TABLE_LOOKUP_KEY_SIZE_8_BYTES) - size += - THREAD_RX_PRAM_ADDITIONAL_FOR_EXTENDED_FILTERING_8; - if (ug_info->largestexternallookupkeysize == - QE_FLTR_TABLE_LOOKUP_KEY_SIZE_16_BYTES) - size += - THREAD_RX_PRAM_ADDITIONAL_FOR_EXTENDED_FILTERING_16; - } - - if ((ret_val = fill_init_enet_entries(ugeth, &(ugeth-> - p_init_enet_param_shadow->rxthread[0]), - (u8) (numThreadsRxNumerical + 1) - /* Rx needs one extra for terminator */ - , size, UCC_GETH_THREAD_RX_PRAM_ALIGNMENT, - ug_info->riscRx, 1)) != 0) { - ugeth_err("%s: Can not fill p_init_enet_param_shadow.", - __FUNCTION__); - ucc_geth_memclean(ugeth); - return ret_val; - } - - ugeth->p_init_enet_param_shadow->txglobal = - ugeth->tx_glbl_pram_offset | ug_info->riscTx; - if ((ret_val = - fill_init_enet_entries(ugeth, - &(ugeth->p_init_enet_param_shadow-> - txthread[0]), numThreadsTxNumerical, - sizeof(ucc_geth_thread_tx_pram_t), - UCC_GETH_THREAD_TX_PRAM_ALIGNMENT, - ug_info->riscTx, 0)) != 0) { - ugeth_err("%s: Can not fill p_init_enet_param_shadow.", - __FUNCTION__); - ucc_geth_memclean(ugeth); - return ret_val; - } - - /* Load Rx bds with buffers */ - for (i = 0; i < ug_info->numQueuesRx; i++) { - if ((ret_val = rx_bd_buffer_set(ugeth, (u8) i)) != 0) { - ugeth_err("%s: Can not fill Rx bds with buffers.", - __FUNCTION__); - ucc_geth_memclean(ugeth); - return ret_val; - } - } - - /* Allocate InitEnet command parameter structure */ - init_enet_pram_offset = qe_muram_alloc(sizeof(ucc_geth_init_pram_t), 4); - if (IS_MURAM_ERR(init_enet_pram_offset)) { - ugeth_err - ("%s: Can not allocate DPRAM memory for p_init_enet_pram.", - __FUNCTION__); - ucc_geth_memclean(ugeth); - return -ENOMEM; - } - p_init_enet_pram = - (ucc_geth_init_pram_t *) qe_muram_addr(init_enet_pram_offset); - - /* Copy shadow InitEnet command parameter structure into PRAM */ - p_init_enet_pram->resinit1 = ugeth->p_init_enet_param_shadow->resinit1; - p_init_enet_pram->resinit2 = ugeth->p_init_enet_param_shadow->resinit2; - p_init_enet_pram->resinit3 = ugeth->p_init_enet_param_shadow->resinit3; - p_init_enet_pram->resinit4 = ugeth->p_init_enet_param_shadow->resinit4; - out_be16(&p_init_enet_pram->resinit5, - ugeth->p_init_enet_param_shadow->resinit5); - p_init_enet_pram->largestexternallookupkeysize = - ugeth->p_init_enet_param_shadow->largestexternallookupkeysize; - out_be32(&p_init_enet_pram->rgftgfrxglobal, - ugeth->p_init_enet_param_shadow->rgftgfrxglobal); - for (i = 0; i < ENET_INIT_PARAM_MAX_ENTRIES_RX; i++) - out_be32(&p_init_enet_pram->rxthread[i], - ugeth->p_init_enet_param_shadow->rxthread[i]); - out_be32(&p_init_enet_pram->txglobal, - ugeth->p_init_enet_param_shadow->txglobal); - for (i = 0; i < ENET_INIT_PARAM_MAX_ENTRIES_TX; i++) - out_be32(&p_init_enet_pram->txthread[i], - ugeth->p_init_enet_param_shadow->txthread[i]); - - /* Issue QE command */ - cecr_subblock = - ucc_fast_get_qe_cr_subblock(ugeth->ug_info->uf_info.ucc_num); - qe_issue_cmd(command, cecr_subblock, (u8) QE_CR_PROTOCOL_ETHERNET, - init_enet_pram_offset); - - /* Free InitEnet command parameter */ - qe_muram_free(init_enet_pram_offset); - - return 0; -} - -/* returns a net_device_stats structure pointer */ -static struct net_device_stats *ucc_geth_get_stats(struct net_device *dev) -{ - ucc_geth_private_t *ugeth = netdev_priv(dev); - - return &(ugeth->stats); -} - -/* ucc_geth_timeout gets called when a packet has not been - * transmitted after a set amount of time. - * For now, assume that clearing out all the structures, and - * starting over will fix the problem. */ -static void ucc_geth_timeout(struct net_device *dev) -{ - ucc_geth_private_t *ugeth = netdev_priv(dev); - - ugeth_vdbg("%s: IN", __FUNCTION__); - - ugeth->stats.tx_errors++; - - ugeth_dump_regs(ugeth); - - if (dev->flags & IFF_UP) { - ucc_geth_stop(ugeth); - ucc_geth_startup(ugeth); - } - - netif_schedule(dev); -} - -/* This is called by the kernel when a frame is ready for transmission. */ -/* It is pointed to by the dev->hard_start_xmit function pointer */ -static int ucc_geth_start_xmit(struct sk_buff *skb, struct net_device *dev) -{ - ucc_geth_private_t *ugeth = netdev_priv(dev); - u8 *bd; /* BD pointer */ - u32 bd_status; - u8 txQ = 0; - - ugeth_vdbg("%s: IN", __FUNCTION__); - - spin_lock_irq(&ugeth->lock); - - ugeth->stats.tx_bytes += skb->len; - - /* Start from the next BD that should be filled */ - bd = ugeth->txBd[txQ]; - bd_status = BD_STATUS_AND_LENGTH(bd); - /* Save the skb pointer so we can free it later */ - ugeth->tx_skbuff[txQ][ugeth->skb_curtx[txQ]] = skb; - - /* Update the current skb pointer (wrapping if this was the last) */ - ugeth->skb_curtx[txQ] = - (ugeth->skb_curtx[txQ] + - 1) & TX_RING_MOD_MASK(ugeth->ug_info->bdRingLenTx[txQ]); - - /* set up the buffer descriptor */ - BD_BUFFER_SET(bd, - dma_map_single(NULL, skb->data, skb->len, DMA_TO_DEVICE)); - - //printk(KERN_DEBUG"skb->data is 0x%x\n",skb->data); - - bd_status = (bd_status & T_W) | T_R | T_I | T_L | skb->len; - - BD_STATUS_AND_LENGTH_SET(bd, bd_status); - - dev->trans_start = jiffies; - - /* Move to next BD in the ring */ - if (!(bd_status & T_W)) - ugeth->txBd[txQ] = bd + UCC_GETH_SIZE_OF_BD; - else - ugeth->txBd[txQ] = ugeth->p_tx_bd_ring[txQ]; - - /* If the next BD still needs to be cleaned up, then the bds - are full. We need to tell the kernel to stop sending us stuff. */ - if (bd == ugeth->confBd[txQ]) { - if (!netif_queue_stopped(dev)) - netif_stop_queue(dev); - } - - if (ugeth->p_scheduler) { - ugeth->cpucount[txQ]++; - /* Indicate to QE that there are more Tx bds ready for - transmission */ - /* This is done by writing a running counter of the bd - count to the scheduler PRAM. */ - out_be16(ugeth->p_cpucount[txQ], ugeth->cpucount[txQ]); - } - - spin_unlock_irq(&ugeth->lock); - - return 0; -} - -static int ucc_geth_rx(ucc_geth_private_t *ugeth, u8 rxQ, int rx_work_limit) -{ - struct sk_buff *skb; - u8 *bd; - u16 length, howmany = 0; - u32 bd_status; - u8 *bdBuffer; - - ugeth_vdbg("%s: IN", __FUNCTION__); - - spin_lock(&ugeth->lock); - /* collect received buffers */ - bd = ugeth->rxBd[rxQ]; - - bd_status = BD_STATUS_AND_LENGTH(bd); - - /* while there are received buffers and BD is full (~R_E) */ - while (!((bd_status & (R_E)) || (--rx_work_limit < 0))) { - bdBuffer = (u8 *) BD_BUFFER(bd); - length = (u16) ((bd_status & BD_LENGTH_MASK) - 4); - skb = ugeth->rx_skbuff[rxQ][ugeth->skb_currx[rxQ]]; - - /* determine whether buffer is first, last, first and last - (single buffer frame) or middle (not first and not last) */ - if (!skb || - (!(bd_status & (R_F | R_L))) || - (bd_status & R_ERRORS_FATAL)) { - ugeth_vdbg("%s, %d: ERROR!!! skb - 0x%08x", - __FUNCTION__, __LINE__, (u32) skb); - if (skb) - dev_kfree_skb_any(skb); - - ugeth->rx_skbuff[rxQ][ugeth->skb_currx[rxQ]] = NULL; - ugeth->stats.rx_dropped++; - } else { - ugeth->stats.rx_packets++; - howmany++; - - /* Prep the skb for the packet */ - skb_put(skb, length); - - /* Tell the skb what kind of packet this is */ - skb->protocol = eth_type_trans(skb, ugeth->dev); - - ugeth->stats.rx_bytes += length; - /* Send the packet up the stack */ -#ifdef CONFIG_UGETH_NAPI - netif_receive_skb(skb); -#else - netif_rx(skb); -#endif /* CONFIG_UGETH_NAPI */ - } - - ugeth->dev->last_rx = jiffies; - - skb = get_new_skb(ugeth, bd); - if (!skb) { - ugeth_warn("%s: No Rx Data Buffer", __FUNCTION__); - spin_unlock(&ugeth->lock); - ugeth->stats.rx_dropped++; - break; - } - - ugeth->rx_skbuff[rxQ][ugeth->skb_currx[rxQ]] = skb; - - /* update to point at the next skb */ - ugeth->skb_currx[rxQ] = - (ugeth->skb_currx[rxQ] + - 1) & RX_RING_MOD_MASK(ugeth->ug_info->bdRingLenRx[rxQ]); - - if (bd_status & R_W) - bd = ugeth->p_rx_bd_ring[rxQ]; - else - bd += UCC_GETH_SIZE_OF_BD; - - bd_status = BD_STATUS_AND_LENGTH(bd); - } - - ugeth->rxBd[rxQ] = bd; - spin_unlock(&ugeth->lock); - return howmany; -} - -static int ucc_geth_tx(struct net_device *dev, u8 txQ) -{ - /* Start from the next BD that should be filled */ - ucc_geth_private_t *ugeth = netdev_priv(dev); - u8 *bd; /* BD pointer */ - u32 bd_status; - - bd = ugeth->confBd[txQ]; - bd_status = BD_STATUS_AND_LENGTH(bd); - - /* Normal processing. */ - while ((bd_status & T_R) == 0) { - /* BD contains already transmitted buffer. */ - /* Handle the transmitted buffer and release */ - /* the BD to be used with the current frame */ - - if ((bd = ugeth->txBd[txQ]) && (netif_queue_stopped(dev) == 0)) - break; - - ugeth->stats.tx_packets++; - - /* Free the sk buffer associated with this TxBD */ - dev_kfree_skb_irq(ugeth-> - tx_skbuff[txQ][ugeth->skb_dirtytx[txQ]]); - ugeth->tx_skbuff[txQ][ugeth->skb_dirtytx[txQ]] = NULL; - ugeth->skb_dirtytx[txQ] = - (ugeth->skb_dirtytx[txQ] + - 1) & TX_RING_MOD_MASK(ugeth->ug_info->bdRingLenTx[txQ]); - - /* We freed a buffer, so now we can restart transmission */ - if (netif_queue_stopped(dev)) - netif_wake_queue(dev); - - /* Advance the confirmation BD pointer */ - if (!(bd_status & T_W)) - ugeth->confBd[txQ] += UCC_GETH_SIZE_OF_BD; - else - ugeth->confBd[txQ] = ugeth->p_tx_bd_ring[txQ]; - } - return 0; -} - -#ifdef CONFIG_UGETH_NAPI -static int ucc_geth_poll(struct net_device *dev, int *budget) -{ - ucc_geth_private_t *ugeth = netdev_priv(dev); - int howmany; - int rx_work_limit = *budget; - u8 rxQ = 0; - - if (rx_work_limit > dev->quota) - rx_work_limit = dev->quota; - - howmany = ucc_geth_rx(ugeth, rxQ, rx_work_limit); - - dev->quota -= howmany; - rx_work_limit -= howmany; - *budget -= howmany; - - if (rx_work_limit >= 0) - netif_rx_complete(dev); - - return (rx_work_limit < 0) ? 1 : 0; -} -#endif /* CONFIG_UGETH_NAPI */ - -static irqreturn_t ucc_geth_irq_handler(int irq, void *info, - struct pt_regs *regs) -{ - struct net_device *dev = (struct net_device *)info; - ucc_geth_private_t *ugeth = netdev_priv(dev); - ucc_fast_private_t *uccf; - ucc_geth_info_t *ug_info; - register u32 ucce = 0; - register u32 bit_mask = UCCE_RXBF_SINGLE_MASK; - register u32 tx_mask = UCCE_TXBF_SINGLE_MASK; - register u8 i; - - ugeth_vdbg("%s: IN", __FUNCTION__); - - if (!ugeth) - return IRQ_NONE; - - uccf = ugeth->uccf; - ug_info = ugeth->ug_info; - - do { - ucce |= (u32) (in_be32(uccf->p_ucce) & in_be32(uccf->p_uccm)); - - /* clear event bits for next time */ - /* Side effect here is to mask ucce variable - for future processing below. */ - out_be32(uccf->p_ucce, ucce); /* Clear with ones, - but only bits in UCCM */ - - /* We ignore Tx interrupts because Tx confirmation is - done inside Tx routine */ - - for (i = 0; i < ug_info->numQueuesRx; i++) { - if (ucce & bit_mask) - ucc_geth_rx(ugeth, i, - (int)ugeth->ug_info-> - bdRingLenRx[i]); - ucce &= ~bit_mask; - bit_mask <<= 1; - } - - for (i = 0; i < ug_info->numQueuesTx; i++) { - if (ucce & tx_mask) - ucc_geth_tx(dev, i); - ucce &= ~tx_mask; - tx_mask <<= 1; - } - - /* Exceptions */ - if (ucce & UCCE_BSY) { - ugeth_vdbg("Got BUSY irq!!!!"); - ugeth->stats.rx_errors++; - ucce &= ~UCCE_BSY; - } - if (ucce & UCCE_OTHER) { - ugeth_vdbg("Got frame with error (ucce - 0x%08x)!!!!", - ucce); - ugeth->stats.rx_errors++; - ucce &= ~ucce; - } - } - while (ucce); - - return IRQ_HANDLED; -} - -static irqreturn_t phy_interrupt(int irq, void *dev_id, struct pt_regs *regs) -{ - struct net_device *dev = (struct net_device *)dev_id; - ucc_geth_private_t *ugeth = netdev_priv(dev); - - ugeth_vdbg("%s: IN", __FUNCTION__); - - /* Clear the interrupt */ - mii_clear_phy_interrupt(ugeth->mii_info); - - /* Disable PHY interrupts */ - mii_configure_phy_interrupt(ugeth->mii_info, MII_INTERRUPT_DISABLED); - - /* Schedule the phy change */ - schedule_work(&ugeth->tq); - - return IRQ_HANDLED; -} - -/* Scheduled by the phy_interrupt/timer to handle PHY changes */ -static void ugeth_phy_change(void *data) -{ - struct net_device *dev = (struct net_device *)data; - ucc_geth_private_t *ugeth = netdev_priv(dev); - ucc_geth_t *ug_regs; - int result = 0; - - ugeth_vdbg("%s: IN", __FUNCTION__); - - ug_regs = ugeth->ug_regs; - - /* Delay to give the PHY a chance to change the - * register state */ - msleep(1); - - /* Update the link, speed, duplex */ - result = ugeth->mii_info->phyinfo->read_status(ugeth->mii_info); - - /* Adjust the known status as long as the link - * isn't still coming up */ - if ((0 == result) || (ugeth->mii_info->link == 0)) - adjust_link(dev); - - /* Reenable interrupts, if needed */ - if (ugeth->ug_info->board_flags & FSL_UGETH_BRD_HAS_PHY_INTR) - mii_configure_phy_interrupt(ugeth->mii_info, - MII_INTERRUPT_ENABLED); -} - -/* Called every so often on systems that don't interrupt - * the core for PHY changes */ -static void ugeth_phy_timer(unsigned long data) -{ - struct net_device *dev = (struct net_device *)data; - ucc_geth_private_t *ugeth = netdev_priv(dev); - - schedule_work(&ugeth->tq); - - mod_timer(&ugeth->phy_info_timer, jiffies + PHY_CHANGE_TIME * HZ); -} - -/* Keep trying aneg for some time - * If, after GFAR_AN_TIMEOUT seconds, it has not - * finished, we switch to forced. - * Either way, once the process has completed, we either - * request the interrupt, or switch the timer over to - * using ugeth_phy_timer to check status */ -static void ugeth_phy_startup_timer(unsigned long data) -{ - struct ugeth_mii_info *mii_info = (struct ugeth_mii_info *)data; - ucc_geth_private_t *ugeth = netdev_priv(mii_info->dev); - static int secondary = UGETH_AN_TIMEOUT; - int result; - - /* Configure the Auto-negotiation */ - result = mii_info->phyinfo->config_aneg(mii_info); - - /* If autonegotiation failed to start, and - * we haven't timed out, reset the timer, and return */ - if (result && secondary--) { - mod_timer(&ugeth->phy_info_timer, jiffies + HZ); - return; - } else if (result) { - /* Couldn't start autonegotiation. - * Try switching to forced */ - mii_info->autoneg = 0; - result = mii_info->phyinfo->config_aneg(mii_info); - - /* Forcing failed! Give up */ - if (result) { - ugeth_err("%s: Forcing failed!", mii_info->dev->name); - return; - } - } - - /* Kill the timer so it can be restarted */ - del_timer_sync(&ugeth->phy_info_timer); - - /* Grab the PHY interrupt, if necessary/possible */ - if (ugeth->ug_info->board_flags & FSL_UGETH_BRD_HAS_PHY_INTR) { - if (request_irq(ugeth->ug_info->phy_interrupt, - phy_interrupt, - SA_SHIRQ, "phy_interrupt", mii_info->dev) < 0) { - ugeth_err("%s: Can't get IRQ %d (PHY)", - mii_info->dev->name, - ugeth->ug_info->phy_interrupt); - } else { - mii_configure_phy_interrupt(ugeth->mii_info, - MII_INTERRUPT_ENABLED); - return; - } - } - - /* Start the timer again, this time in order to - * handle a change in status */ - init_timer(&ugeth->phy_info_timer); - ugeth->phy_info_timer.function = &ugeth_phy_timer; - ugeth->phy_info_timer.data = (unsigned long)mii_info->dev; - mod_timer(&ugeth->phy_info_timer, jiffies + PHY_CHANGE_TIME * HZ); -} - -/* Called when something needs to use the ethernet device */ -/* Returns 0 for success. */ -static int ucc_geth_open(struct net_device *dev) -{ - ucc_geth_private_t *ugeth = netdev_priv(dev); - int err; - - ugeth_vdbg("%s: IN", __FUNCTION__); - - /* Test station address */ - if (dev->dev_addr[0] & ENET_GROUP_ADDR) { - ugeth_err("%s: Multicast address used for station address" - " - is this what you wanted?", __FUNCTION__); - return -EINVAL; - } - - err = ucc_geth_startup(ugeth); - if (err) { - ugeth_err("%s: Cannot configure net device, aborting.", - dev->name); - return err; - } - - err = adjust_enet_interface(ugeth); - if (err) { - ugeth_err("%s: Cannot configure net device, aborting.", - dev->name); - return err; - } - - /* Set MACSTNADDR1, MACSTNADDR2 */ - /* For more details see the hardware spec. */ - init_mac_station_addr_regs(dev->dev_addr[0], - dev->dev_addr[1], - dev->dev_addr[2], - dev->dev_addr[3], - dev->dev_addr[4], - dev->dev_addr[5], - &ugeth->ug_regs->macstnaddr1, - &ugeth->ug_regs->macstnaddr2); - - err = init_phy(dev); - if (err) { - ugeth_err("%s: Cannot initialzie PHY, aborting.", dev->name); - return err; - } -#ifndef CONFIG_UGETH_NAPI - err = - request_irq(ugeth->ug_info->uf_info.irq, ucc_geth_irq_handler, 0, - "UCC Geth", dev); - if (err) { - ugeth_err("%s: Cannot get IRQ for net device, aborting.", - dev->name); - ucc_geth_stop(ugeth); - return err; - } -#endif /* CONFIG_UGETH_NAPI */ - - /* Set up the PHY change work queue */ - INIT_WORK(&ugeth->tq, ugeth_phy_change, dev); - - init_timer(&ugeth->phy_info_timer); - ugeth->phy_info_timer.function = &ugeth_phy_startup_timer; - ugeth->phy_info_timer.data = (unsigned long)ugeth->mii_info; - mod_timer(&ugeth->phy_info_timer, jiffies + HZ); - - err = ugeth_enable(ugeth, COMM_DIR_RX_AND_TX); - if (err) { - ugeth_err("%s: Cannot enable net device, aborting.", dev->name); - ucc_geth_stop(ugeth); - return err; - } - - netif_start_queue(dev); - - return err; -} - -/* Stops the kernel queue, and halts the controller */ -static int ucc_geth_close(struct net_device *dev) -{ - ucc_geth_private_t *ugeth = netdev_priv(dev); - - ugeth_vdbg("%s: IN", __FUNCTION__); - - ucc_geth_stop(ugeth); - - /* Shutdown the PHY */ - if (ugeth->mii_info->phyinfo->close) - ugeth->mii_info->phyinfo->close(ugeth->mii_info); - - kfree(ugeth->mii_info); - - netif_stop_queue(dev); - - return 0; -} - -struct ethtool_ops ucc_geth_ethtool_ops = { - .get_settings = NULL, - .get_drvinfo = NULL, - .get_regs_len = NULL, - .get_regs = NULL, - .get_link = NULL, - .get_coalesce = NULL, - .set_coalesce = NULL, - .get_ringparam = NULL, - .set_ringparam = NULL, - .get_strings = NULL, - .get_stats_count = NULL, - .get_ethtool_stats = NULL, -}; - -static int ucc_geth_probe(struct device *device) -{ - struct platform_device *pdev = to_platform_device(device); - struct ucc_geth_platform_data *ugeth_pdata; - struct net_device *dev = NULL; - struct ucc_geth_private *ugeth = NULL; - struct ucc_geth_info *ug_info; - int err; - static int mii_mng_configured = 0; - - ugeth_vdbg("%s: IN", __FUNCTION__); - - ugeth_pdata = (struct ucc_geth_platform_data *)pdev->dev.platform_data; - - ug_info = &ugeth_info[pdev->id]; - ug_info->uf_info.ucc_num = pdev->id; - ug_info->uf_info.rx_clock = ugeth_pdata->rx_clock; - ug_info->uf_info.tx_clock = ugeth_pdata->tx_clock; - ug_info->uf_info.regs = ugeth_pdata->phy_reg_addr; - ug_info->uf_info.irq = platform_get_irq(pdev, 0); - ug_info->phy_address = ugeth_pdata->phy_id; - ug_info->enet_interface = ugeth_pdata->phy_interface; - ug_info->board_flags = ugeth_pdata->board_flags; - ug_info->phy_interrupt = ugeth_pdata->phy_interrupt; - - printk(KERN_INFO "ucc_geth: UCC%1d at 0x%8x (irq = %d) \n", - ug_info->uf_info.ucc_num + 1, ug_info->uf_info.regs, - ug_info->uf_info.irq); - - if (ug_info == NULL) { - ugeth_err("%s: [%d] Missing additional data!", __FUNCTION__, - pdev->id); - return -ENODEV; - } - - if (!mii_mng_configured) { - ucc_set_qe_mux_mii_mng(ug_info->uf_info.ucc_num); - mii_mng_configured = 1; - } - - /* Create an ethernet device instance */ - dev = alloc_etherdev(sizeof(*ugeth)); - - if (dev == NULL) - return -ENOMEM; - - ugeth = netdev_priv(dev); - spin_lock_init(&ugeth->lock); - - dev_set_drvdata(device, dev); - - /* Set the dev->base_addr to the gfar reg region */ - dev->base_addr = (unsigned long)(ug_info->uf_info.regs); - - SET_MODULE_OWNER(dev); - SET_NETDEV_DEV(dev, device); - - /* Fill in the dev structure */ - dev->open = ucc_geth_open; - dev->hard_start_xmit = ucc_geth_start_xmit; - dev->tx_timeout = ucc_geth_timeout; - dev->watchdog_timeo = TX_TIMEOUT; -#ifdef CONFIG_UGETH_NAPI - dev->poll = ucc_geth_poll; - dev->weight = UCC_GETH_DEV_WEIGHT; -#endif /* CONFIG_UGETH_NAPI */ - dev->stop = ucc_geth_close; - dev->get_stats = ucc_geth_get_stats; -// dev->change_mtu = ucc_geth_change_mtu; - dev->mtu = 1500; - dev->set_multicast_list = ucc_geth_set_multi; - dev->ethtool_ops = &ucc_geth_ethtool_ops; - - err = register_netdev(dev); - if (err) { - ugeth_err("%s: Cannot register net device, aborting.", - dev->name); - free_netdev(dev); - return err; - } - - ugeth->ug_info = ug_info; - ugeth->dev = dev; - memcpy(dev->dev_addr, ugeth_pdata->mac_addr, 6); - - return 0; -} - -static int ucc_geth_remove(struct device *device) -{ - struct net_device *dev = dev_get_drvdata(device); - struct ucc_geth_private *ugeth = netdev_priv(dev); - - dev_set_drvdata(device, NULL); - ucc_geth_memclean(ugeth); - free_netdev(dev); - - return 0; -} - -/* Structure for a device driver */ -static struct device_driver ucc_geth_driver = { - .name = DRV_NAME, - .bus = &platform_bus_type, - .probe = ucc_geth_probe, - .remove = ucc_geth_remove, -}; - -static int __init ucc_geth_init(void) -{ - int i; - printk(KERN_INFO "ucc_geth: " DRV_DESC "\n"); - for (i = 0; i < 8; i++) - memcpy(&(ugeth_info[i]), &ugeth_primary_info, - sizeof(ugeth_primary_info)); - - return driver_register(&ucc_geth_driver); -} - -static void __exit ucc_geth_exit(void) -{ - driver_unregister(&ucc_geth_driver); -} - -module_init(ucc_geth_init); -module_exit(ucc_geth_exit); - -MODULE_AUTHOR("Freescale Semiconductor, Inc"); -MODULE_DESCRIPTION(DRV_DESC); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/net/ucc_geth.h b/trunk/drivers/net/ucc_geth.h deleted file mode 100644 index 005965f5dd9b..000000000000 --- a/trunk/drivers/net/ucc_geth.h +++ /dev/null @@ -1,1339 +0,0 @@ -/* - * Copyright (C) Freescale Semicondutor, Inc. 2006. All rights reserved. - * - * Author: Shlomi Gridish - * - * Description: - * Internal header file for UCC Gigabit Ethernet unit routines. - * - * Changelog: - * Jun 28, 2006 Li Yang - * - Rearrange code and style fixes - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ -#ifndef __UCC_GETH_H__ -#define __UCC_GETH_H__ - -#include -#include -#include - -#include -#include - -#include -#include - -#define NUM_TX_QUEUES 8 -#define NUM_RX_QUEUES 8 -#define NUM_BDS_IN_PREFETCHED_BDS 4 -#define TX_IP_OFFSET_ENTRY_MAX 8 -#define NUM_OF_PADDRS 4 -#define ENET_INIT_PARAM_MAX_ENTRIES_RX 9 -#define ENET_INIT_PARAM_MAX_ENTRIES_TX 8 - -typedef struct ucc_mii_mng { - u32 miimcfg; /* MII management configuration reg */ - u32 miimcom; /* MII management command reg */ - u32 miimadd; /* MII management address reg */ - u32 miimcon; /* MII management control reg */ - u32 miimstat; /* MII management status reg */ - u32 miimind; /* MII management indication reg */ -} __attribute__ ((packed)) ucc_mii_mng_t; - -typedef struct ucc_geth { - ucc_fast_t uccf; - - u32 maccfg1; /* mac configuration reg. 1 */ - u32 maccfg2; /* mac configuration reg. 2 */ - u32 ipgifg; /* interframe gap reg. */ - u32 hafdup; /* half-duplex reg. */ - u8 res1[0x10]; - ucc_mii_mng_t miimng; /* MII management structure */ - u32 ifctl; /* interface control reg */ - u32 ifstat; /* interface statux reg */ - u32 macstnaddr1; /* mac station address part 1 reg */ - u32 macstnaddr2; /* mac station address part 2 reg */ - u8 res2[0x8]; - u32 uempr; /* UCC Ethernet Mac parameter reg */ - u32 utbipar; /* UCC tbi address reg */ - u16 uescr; /* UCC Ethernet statistics control reg */ - u8 res3[0x180 - 0x15A]; - u32 tx64; /* Total number of frames (including bad - frames) transmitted that were exactly of the - minimal length (64 for un tagged, 68 for - tagged, or with length exactly equal to the - parameter MINLength */ - u32 tx127; /* Total number of frames (including bad - frames) transmitted that were between - MINLength (Including FCS length==4) and 127 - octets */ - u32 tx255; /* Total number of frames (including bad - frames) transmitted that were between 128 - (Including FCS length==4) and 255 octets */ - u32 rx64; /* Total number of frames received including - bad frames that were exactly of the mninimal - length (64 bytes) */ - u32 rx127; /* Total number of frames (including bad - frames) received that were between MINLength - (Including FCS length==4) and 127 octets */ - u32 rx255; /* Total number of frames (including bad - frames) received that were between 128 - (Including FCS length==4) and 255 octets */ - u32 txok; /* Total number of octets residing in frames - that where involved in succesfull - transmission */ - u16 txcf; /* Total number of PAUSE control frames - transmitted by this MAC */ - u8 res4[0x2]; - u32 tmca; /* Total number of frames that were transmitted - succesfully with the group address bit set - that are not broadcast frames */ - u32 tbca; /* Total number of frames transmitted - succesfully that had destination address - field equal to the broadcast address */ - u32 rxfok; /* Total number of frames received OK */ - u32 rxbok; /* Total number of octets received OK */ - u32 rbyt; /* Total number of octets received including - octets in bad frames. Must be implemented in - HW because it includes octets in frames that - never even reach the UCC */ - u32 rmca; /* Total number of frames that were received - succesfully with the group address bit set - that are not broadcast frames */ - u32 rbca; /* Total number of frames received succesfully - that had destination address equal to the - broadcast address */ - u32 scar; /* Statistics carry register */ - u32 scam; /* Statistics caryy mask register */ - u8 res5[0x200 - 0x1c4]; -} __attribute__ ((packed)) ucc_geth_t; - -/* UCC GETH TEMODR Register */ -#define TEMODER_TX_RMON_STATISTICS_ENABLE 0x0100 /* enable Tx statistics - */ -#define TEMODER_SCHEDULER_ENABLE 0x2000 /* enable scheduler */ -#define TEMODER_IP_CHECKSUM_GENERATE 0x0400 /* generate IPv4 - checksums */ -#define TEMODER_PERFORMANCE_OPTIMIZATION_MODE1 0x0200 /* enable performance - optimization - enhancement (mode1) */ -#define TEMODER_RMON_STATISTICS 0x0100 /* enable tx statistics - */ -#define TEMODER_NUM_OF_QUEUES_SHIFT (15-15) /* Number of queues << - shift */ - -/* UCC GETH TEMODR Register */ -#define REMODER_RX_RMON_STATISTICS_ENABLE 0x00001000 /* enable Rx - statistics */ -#define REMODER_RX_EXTENDED_FEATURES 0x80000000 /* enable - extended - features */ -#define REMODER_VLAN_OPERATION_TAGGED_SHIFT (31-9 ) /* vlan operation - tagged << shift */ -#define REMODER_VLAN_OPERATION_NON_TAGGED_SHIFT (31-10) /* vlan operation non - tagged << shift */ -#define REMODER_RX_QOS_MODE_SHIFT (31-15) /* rx QoS mode << shift - */ -#define REMODER_RMON_STATISTICS 0x00001000 /* enable rx - statistics */ -#define REMODER_RX_EXTENDED_FILTERING 0x00000800 /* extended - filtering - vs. - mpc82xx-like - filtering */ -#define REMODER_NUM_OF_QUEUES_SHIFT (31-23) /* Number of queues << - shift */ -#define REMODER_DYNAMIC_MAX_FRAME_LENGTH 0x00000008 /* enable - dynamic max - frame length - */ -#define REMODER_DYNAMIC_MIN_FRAME_LENGTH 0x00000004 /* enable - dynamic min - frame length - */ -#define REMODER_IP_CHECKSUM_CHECK 0x00000002 /* check IPv4 - checksums */ -#define REMODER_IP_ADDRESS_ALIGNMENT 0x00000001 /* align ip - address to - 4-byte - boundary */ - -/* UCC GETH Event Register */ -#define UCCE_MPD 0x80000000 /* Magic packet - detection */ -#define UCCE_SCAR 0x40000000 -#define UCCE_GRA 0x20000000 /* Tx graceful - stop - complete */ -#define UCCE_CBPR 0x10000000 -#define UCCE_BSY 0x08000000 -#define UCCE_RXC 0x04000000 -#define UCCE_TXC 0x02000000 -#define UCCE_TXE 0x01000000 -#define UCCE_TXB7 0x00800000 -#define UCCE_TXB6 0x00400000 -#define UCCE_TXB5 0x00200000 -#define UCCE_TXB4 0x00100000 -#define UCCE_TXB3 0x00080000 -#define UCCE_TXB2 0x00040000 -#define UCCE_TXB1 0x00020000 -#define UCCE_TXB0 0x00010000 -#define UCCE_RXB7 0x00008000 -#define UCCE_RXB6 0x00004000 -#define UCCE_RXB5 0x00002000 -#define UCCE_RXB4 0x00001000 -#define UCCE_RXB3 0x00000800 -#define UCCE_RXB2 0x00000400 -#define UCCE_RXB1 0x00000200 -#define UCCE_RXB0 0x00000100 -#define UCCE_RXF7 0x00000080 -#define UCCE_RXF6 0x00000040 -#define UCCE_RXF5 0x00000020 -#define UCCE_RXF4 0x00000010 -#define UCCE_RXF3 0x00000008 -#define UCCE_RXF2 0x00000004 -#define UCCE_RXF1 0x00000002 -#define UCCE_RXF0 0x00000001 - -#define UCCE_RXBF_SINGLE_MASK (UCCE_RXF0) -#define UCCE_TXBF_SINGLE_MASK (UCCE_TXB0) - -#define UCCE_TXB (UCCE_TXB7 | UCCE_TXB6 | UCCE_TXB5 | UCCE_TXB4 |\ - UCCE_TXB3 | UCCE_TXB2 | UCCE_TXB1 | UCCE_TXB0) -#define UCCE_RXB (UCCE_RXB7 | UCCE_RXB6 | UCCE_RXB5 | UCCE_RXB4 |\ - UCCE_RXB3 | UCCE_RXB2 | UCCE_RXB1 | UCCE_RXB0) -#define UCCE_RXF (UCCE_RXF7 | UCCE_RXF6 | UCCE_RXF5 | UCCE_RXF4 |\ - UCCE_RXF3 | UCCE_RXF2 | UCCE_RXF1 | UCCE_RXF0) -#define UCCE_OTHER (UCCE_SCAR | UCCE_GRA | UCCE_CBPR | UCCE_BSY |\ - UCCE_RXC | UCCE_TXC | UCCE_TXE) - -/* UCC GETH UPSMR (Protocol Specific Mode Register) */ -#define UPSMR_ECM 0x04000000 /* Enable CAM - Miss or - Enable - Filtering - Miss */ -#define UPSMR_HSE 0x02000000 /* Hardware - Statistics - Enable */ -#define UPSMR_PRO 0x00400000 /* Promiscuous*/ -#define UPSMR_CAP 0x00200000 /* CAM polarity - */ -#define UPSMR_RSH 0x00100000 /* Receive - Short Frames - */ -#define UPSMR_RPM 0x00080000 /* Reduced Pin - Mode - interfaces */ -#define UPSMR_R10M 0x00040000 /* RGMII/RMII - 10 Mode */ -#define UPSMR_RLPB 0x00020000 /* RMII - Loopback - Mode */ -#define UPSMR_TBIM 0x00010000 /* Ten-bit - Interface - Mode */ -#define UPSMR_RMM 0x00001000 /* RMII/RGMII - Mode */ -#define UPSMR_CAM 0x00000400 /* CAM Address - Matching */ -#define UPSMR_BRO 0x00000200 /* Broadcast - Address */ -#define UPSMR_RES1 0x00002000 /* Reserved - feild - must - be 1 */ - -/* UCC GETH MACCFG1 (MAC Configuration 1 Register) */ -#define MACCFG1_FLOW_RX 0x00000020 /* Flow Control - Rx */ -#define MACCFG1_FLOW_TX 0x00000010 /* Flow Control - Tx */ -#define MACCFG1_ENABLE_SYNCHED_RX 0x00000008 /* Rx Enable - synchronized - to Rx stream - */ -#define MACCFG1_ENABLE_RX 0x00000004 /* Enable Rx */ -#define MACCFG1_ENABLE_SYNCHED_TX 0x00000002 /* Tx Enable - synchronized - to Tx stream - */ -#define MACCFG1_ENABLE_TX 0x00000001 /* Enable Tx */ - -/* UCC GETH MACCFG2 (MAC Configuration 2 Register) */ -#define MACCFG2_PREL_SHIFT (31 - 19) /* Preamble - Length << - shift */ -#define MACCFG2_PREL_MASK 0x0000f000 /* Preamble - Length mask */ -#define MACCFG2_SRP 0x00000080 /* Soft Receive - Preamble */ -#define MACCFG2_STP 0x00000040 /* Soft - Transmit - Preamble */ -#define MACCFG2_RESERVED_1 0x00000020 /* Reserved - - must be set - to 1 */ -#define MACCFG2_LC 0x00000010 /* Length Check - */ -#define MACCFG2_MPE 0x00000008 /* Magic packet - detect */ -#define MACCFG2_FDX 0x00000001 /* Full Duplex */ -#define MACCFG2_FDX_MASK 0x00000001 /* Full Duplex - mask */ -#define MACCFG2_PAD_CRC 0x00000004 -#define MACCFG2_CRC_EN 0x00000002 -#define MACCFG2_PAD_AND_CRC_MODE_NONE 0x00000000 /* Neither - Padding - short frames - nor CRC */ -#define MACCFG2_PAD_AND_CRC_MODE_CRC_ONLY 0x00000002 /* Append CRC - only */ -#define MACCFG2_PAD_AND_CRC_MODE_PAD_AND_CRC 0x00000004 -#define MACCFG2_INTERFACE_MODE_NIBBLE 0x00000100 /* nibble mode - (MII/RMII/RGMII - 10/100bps) */ -#define MACCFG2_INTERFACE_MODE_BYTE 0x00000200 /* byte mode - (GMII/TBI/RTB/RGMII - 1000bps ) */ -#define MACCFG2_INTERFACE_MODE_MASK 0x00000300 /* mask - covering all - relevant - bits */ - -/* UCC GETH IPGIFG (Inter-frame Gap / Inter-Frame Gap Register) */ -#define IPGIFG_NON_BACK_TO_BACK_IFG_PART1_SHIFT (31 - 7) /* Non - back-to-back - inter frame - gap part 1. - << shift */ -#define IPGIFG_NON_BACK_TO_BACK_IFG_PART2_SHIFT (31 - 15) /* Non - back-to-back - inter frame - gap part 2. - << shift */ -#define IPGIFG_MINIMUM_IFG_ENFORCEMENT_SHIFT (31 - 23) /* Mimimum IFG - Enforcement - << shift */ -#define IPGIFG_BACK_TO_BACK_IFG_SHIFT (31 - 31) /* back-to-back - inter frame - gap << shift - */ -#define IPGIFG_NON_BACK_TO_BACK_IFG_PART1_MAX 127 /* Non back-to-back - inter frame gap part - 1. max val */ -#define IPGIFG_NON_BACK_TO_BACK_IFG_PART2_MAX 127 /* Non back-to-back - inter frame gap part - 2. max val */ -#define IPGIFG_MINIMUM_IFG_ENFORCEMENT_MAX 255 /* Mimimum IFG - Enforcement max val */ -#define IPGIFG_BACK_TO_BACK_IFG_MAX 127 /* back-to-back inter - frame gap max val */ -#define IPGIFG_NBTB_CS_IPG_MASK 0x7F000000 -#define IPGIFG_NBTB_IPG_MASK 0x007F0000 -#define IPGIFG_MIN_IFG_MASK 0x0000FF00 -#define IPGIFG_BTB_IPG_MASK 0x0000007F - -/* UCC GETH HAFDUP (Half Duplex Register) */ -#define HALFDUP_ALT_BEB_TRUNCATION_SHIFT (31 - 11) /* Alternate - Binary - Exponential - Backoff - Truncation - << shift */ -#define HALFDUP_ALT_BEB_TRUNCATION_MAX 0xf /* Alternate Binary - Exponential Backoff - Truncation max val */ -#define HALFDUP_ALT_BEB 0x00080000 /* Alternate - Binary - Exponential - Backoff */ -#define HALFDUP_BACK_PRESSURE_NO_BACKOFF 0x00040000 /* Back - pressure no - backoff */ -#define HALFDUP_NO_BACKOFF 0x00020000 /* No Backoff */ -#define HALFDUP_EXCESSIVE_DEFER 0x00010000 /* Excessive - Defer */ -#define HALFDUP_MAX_RETRANSMISSION_SHIFT (31 - 19) /* Maximum - Retransmission - << shift */ -#define HALFDUP_MAX_RETRANSMISSION_MAX 0xf /* Maximum - Retransmission max - val */ -#define HALFDUP_COLLISION_WINDOW_SHIFT (31 - 31) /* Collision - Window << - shift */ -#define HALFDUP_COLLISION_WINDOW_MAX 0x3f /* Collision Window max - val */ -#define HALFDUP_ALT_BEB_TR_MASK 0x00F00000 -#define HALFDUP_RETRANS_MASK 0x0000F000 -#define HALFDUP_COL_WINDOW_MASK 0x0000003F - -/* UCC GETH UCCS (Ethernet Status Register) */ -#define UCCS_BPR 0x02 /* Back pressure (in - half duplex mode) */ -#define UCCS_PAU 0x02 /* Pause state (in full - duplex mode) */ -#define UCCS_MPD 0x01 /* Magic Packet - Detected */ - -/* UCC GETH MIIMCFG (MII Management Configuration Register) */ -#define MIIMCFG_RESET_MANAGEMENT 0x80000000 /* Reset - management */ -#define MIIMCFG_NO_PREAMBLE 0x00000010 /* Preamble - suppress */ -#define MIIMCFG_CLOCK_DIVIDE_SHIFT (31 - 31) /* clock divide - << shift */ -#define MIIMCFG_CLOCK_DIVIDE_MAX 0xf /* clock divide max val - */ -#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_2 0x00000000 /* divide by 2 */ -#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_4 0x00000001 /* divide by 4 */ -#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_6 0x00000002 /* divide by 6 */ -#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_8 0x00000003 /* divide by 8 */ -#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_10 0x00000004 /* divide by 10 - */ -#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_14 0x00000005 /* divide by 14 - */ -#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_16 0x00000008 /* divide by 16 - */ -#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_20 0x00000006 /* divide by 20 - */ -#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_28 0x00000007 /* divide by 28 - */ -#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_32 0x00000009 /* divide by 32 - */ -#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_48 0x0000000a /* divide by 48 - */ -#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_64 0x0000000b /* divide by 64 - */ -#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_80 0x0000000c /* divide by 80 - */ -#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_112 0x0000000d /* divide by - 112 */ -#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_160 0x0000000e /* divide by - 160 */ -#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_224 0x0000000f /* divide by - 224 */ - -/* UCC GETH MIIMCOM (MII Management Command Register) */ -#define MIIMCOM_SCAN_CYCLE 0x00000002 /* Scan cycle */ -#define MIIMCOM_READ_CYCLE 0x00000001 /* Read cycle */ - -/* UCC GETH MIIMADD (MII Management Address Register) */ -#define MIIMADD_PHY_ADDRESS_SHIFT (31 - 23) /* PHY Address - << shift */ -#define MIIMADD_PHY_REGISTER_SHIFT (31 - 31) /* PHY Register - << shift */ - -/* UCC GETH MIIMCON (MII Management Control Register) */ -#define MIIMCON_PHY_CONTROL_SHIFT (31 - 31) /* PHY Control - << shift */ -#define MIIMCON_PHY_STATUS_SHIFT (31 - 31) /* PHY Status - << shift */ - -/* UCC GETH MIIMIND (MII Management Indicator Register) */ -#define MIIMIND_NOT_VALID 0x00000004 /* Not valid */ -#define MIIMIND_SCAN 0x00000002 /* Scan in - progress */ -#define MIIMIND_BUSY 0x00000001 - -/* UCC GETH IFSTAT (Interface Status Register) */ -#define IFSTAT_EXCESS_DEFER 0x00000200 /* Excessive - transmission - defer */ - -/* UCC GETH MACSTNADDR1 (Station Address Part 1 Register) */ -#define MACSTNADDR1_OCTET_6_SHIFT (31 - 7) /* Station - address 6th - octet << - shift */ -#define MACSTNADDR1_OCTET_5_SHIFT (31 - 15) /* Station - address 5th - octet << - shift */ -#define MACSTNADDR1_OCTET_4_SHIFT (31 - 23) /* Station - address 4th - octet << - shift */ -#define MACSTNADDR1_OCTET_3_SHIFT (31 - 31) /* Station - address 3rd - octet << - shift */ - -/* UCC GETH MACSTNADDR2 (Station Address Part 2 Register) */ -#define MACSTNADDR2_OCTET_2_SHIFT (31 - 7) /* Station - address 2nd - octet << - shift */ -#define MACSTNADDR2_OCTET_1_SHIFT (31 - 15) /* Station - address 1st - octet << - shift */ - -/* UCC GETH UEMPR (Ethernet Mac Parameter Register) */ -#define UEMPR_PAUSE_TIME_VALUE_SHIFT (31 - 15) /* Pause time - value << - shift */ -#define UEMPR_EXTENDED_PAUSE_TIME_VALUE_SHIFT (31 - 31) /* Extended - pause time - value << - shift */ - -/* UCC GETH UTBIPAR (Ten Bit Interface Physical Address Register) */ -#define UTBIPAR_PHY_ADDRESS_SHIFT (31 - 31) /* Phy address - << shift */ -#define UTBIPAR_PHY_ADDRESS_MASK 0x0000001f /* Phy address - mask */ - -/* UCC GETH UESCR (Ethernet Statistics Control Register) */ -#define UESCR_AUTOZ 0x8000 /* Automatically zero - addressed - statistical counter - values */ -#define UESCR_CLRCNT 0x4000 /* Clear all statistics - counters */ -#define UESCR_MAXCOV_SHIFT (15 - 7) /* Max - Coalescing - Value << - shift */ -#define UESCR_SCOV_SHIFT (15 - 15) /* Status - Coalescing - Value << - shift */ - -/* UCC GETH UDSR (Data Synchronization Register) */ -#define UDSR_MAGIC 0x067E - -typedef struct ucc_geth_thread_data_tx { - u8 res0[104]; -} __attribute__ ((packed)) ucc_geth_thread_data_tx_t; - -typedef struct ucc_geth_thread_data_rx { - u8 res0[40]; -} __attribute__ ((packed)) ucc_geth_thread_data_rx_t; - -/* Send Queue Queue-Descriptor */ -typedef struct ucc_geth_send_queue_qd { - u32 bd_ring_base; /* pointer to BD ring base address */ - u8 res0[0x8]; - u32 last_bd_completed_address;/* initialize to last entry in BD ring */ - u8 res1[0x30]; -} __attribute__ ((packed)) ucc_geth_send_queue_qd_t; - -typedef struct ucc_geth_send_queue_mem_region { - ucc_geth_send_queue_qd_t sqqd[NUM_TX_QUEUES]; -} __attribute__ ((packed)) ucc_geth_send_queue_mem_region_t; - -typedef struct ucc_geth_thread_tx_pram { - u8 res0[64]; -} __attribute__ ((packed)) ucc_geth_thread_tx_pram_t; - -typedef struct ucc_geth_thread_rx_pram { - u8 res0[128]; -} __attribute__ ((packed)) ucc_geth_thread_rx_pram_t; - -#define THREAD_RX_PRAM_ADDITIONAL_FOR_EXTENDED_FILTERING 64 -#define THREAD_RX_PRAM_ADDITIONAL_FOR_EXTENDED_FILTERING_8 64 -#define THREAD_RX_PRAM_ADDITIONAL_FOR_EXTENDED_FILTERING_16 96 - -typedef struct ucc_geth_scheduler { - u16 cpucount0; /* CPU packet counter */ - u16 cpucount1; /* CPU packet counter */ - u16 cecount0; /* QE packet counter */ - u16 cecount1; /* QE packet counter */ - u16 cpucount2; /* CPU packet counter */ - u16 cpucount3; /* CPU packet counter */ - u16 cecount2; /* QE packet counter */ - u16 cecount3; /* QE packet counter */ - u16 cpucount4; /* CPU packet counter */ - u16 cpucount5; /* CPU packet counter */ - u16 cecount4; /* QE packet counter */ - u16 cecount5; /* QE packet counter */ - u16 cpucount6; /* CPU packet counter */ - u16 cpucount7; /* CPU packet counter */ - u16 cecount6; /* QE packet counter */ - u16 cecount7; /* QE packet counter */ - u32 weightstatus[NUM_TX_QUEUES]; /* accumulated weight factor */ - u32 rtsrshadow; /* temporary variable handled by QE */ - u32 time; /* temporary variable handled by QE */ - u32 ttl; /* temporary variable handled by QE */ - u32 mblinterval; /* max burst length interval */ - u16 nortsrbytetime; /* normalized value of byte time in tsr units */ - u8 fracsiz; /* radix 2 log value of denom. of - NorTSRByteTime */ - u8 res0[1]; - u8 strictpriorityq; /* Strict Priority Mask register */ - u8 txasap; /* Transmit ASAP register */ - u8 extrabw; /* Extra BandWidth register */ - u8 oldwfqmask; /* temporary variable handled by QE */ - u8 weightfactor[NUM_TX_QUEUES]; - /**< weight factor for queues */ - u32 minw; /* temporary variable handled by QE */ - u8 res1[0x70 - 0x64]; -} __attribute__ ((packed)) ucc_geth_scheduler_t; - -typedef struct ucc_geth_tx_firmware_statistics_pram { - u32 sicoltx; /* single collision */ - u32 mulcoltx; /* multiple collision */ - u32 latecoltxfr; /* late collision */ - u32 frabortduecol; /* frames aborted due to transmit collision */ - u32 frlostinmactxer; /* frames lost due to internal MAC error - transmission that are not counted on any - other counter */ - u32 carriersenseertx; /* carrier sense error */ - u32 frtxok; /* frames transmitted OK */ - u32 txfrexcessivedefer; /* frames with defferal time greater than - specified threshold */ - u32 txpkts256; /* total packets (including bad) between 256 - and 511 octets */ - u32 txpkts512; /* total packets (including bad) between 512 - and 1023 octets */ - u32 txpkts1024; /* total packets (including bad) between 1024 - and 1518 octets */ - u32 txpktsjumbo; /* total packets (including bad) between 1024 - and MAXLength octets */ -} __attribute__ ((packed)) ucc_geth_tx_firmware_statistics_pram_t; - -typedef struct ucc_geth_rx_firmware_statistics_pram { - u32 frrxfcser; /* frames with crc error */ - u32 fraligner; /* frames with alignment error */ - u32 inrangelenrxer; /* in range length error */ - u32 outrangelenrxer; /* out of range length error */ - u32 frtoolong; /* frame too long */ - u32 runt; /* runt */ - u32 verylongevent; /* very long event */ - u32 symbolerror; /* symbol error */ - u32 dropbsy; /* drop because of BD not ready */ - u8 res0[0x8]; - u32 mismatchdrop; /* drop because of MAC filtering (e.g. address - or type mismatch) */ - u32 underpkts; /* total frames less than 64 octets */ - u32 pkts256; /* total frames (including bad) between 256 and - 511 octets */ - u32 pkts512; /* total frames (including bad) between 512 and - 1023 octets */ - u32 pkts1024; /* total frames (including bad) between 1024 - and 1518 octets */ - u32 pktsjumbo; /* total frames (including bad) between 1024 - and MAXLength octets */ - u32 frlossinmacer; /* frames lost because of internal MAC error - that is not counted in any other counter */ - u32 pausefr; /* pause frames */ - u8 res1[0x4]; - u32 removevlan; /* total frames that had their VLAN tag removed - */ - u32 replacevlan; /* total frames that had their VLAN tag - replaced */ - u32 insertvlan; /* total frames that had their VLAN tag - inserted */ -} __attribute__ ((packed)) ucc_geth_rx_firmware_statistics_pram_t; - -typedef struct ucc_geth_rx_interrupt_coalescing_entry { - u32 interruptcoalescingmaxvalue; /* interrupt coalescing max - value */ - u32 interruptcoalescingcounter; /* interrupt coalescing counter, - initialize to - interruptcoalescingmaxvalue */ -} __attribute__ ((packed)) ucc_geth_rx_interrupt_coalescing_entry_t; - -typedef struct ucc_geth_rx_interrupt_coalescing_table { - ucc_geth_rx_interrupt_coalescing_entry_t coalescingentry[NUM_RX_QUEUES]; - /**< interrupt coalescing entry */ -} __attribute__ ((packed)) ucc_geth_rx_interrupt_coalescing_table_t; - -typedef struct ucc_geth_rx_prefetched_bds { - qe_bd_t bd[NUM_BDS_IN_PREFETCHED_BDS]; /* prefetched bd */ -} __attribute__ ((packed)) ucc_geth_rx_prefetched_bds_t; - -typedef struct ucc_geth_rx_bd_queues_entry { - u32 bdbaseptr; /* BD base pointer */ - u32 bdptr; /* BD pointer */ - u32 externalbdbaseptr; /* external BD base pointer */ - u32 externalbdptr; /* external BD pointer */ -} __attribute__ ((packed)) ucc_geth_rx_bd_queues_entry_t; - -typedef struct ucc_geth_tx_global_pram { - u16 temoder; - u8 res0[0x38 - 0x02]; - u32 sqptr; /* a base pointer to send queue memory region */ - u32 schedulerbasepointer; /* a base pointer to scheduler memory - region */ - u32 txrmonbaseptr; /* base pointer to Tx RMON statistics counter */ - u32 tstate; /* tx internal state. High byte contains - function code */ - u8 iphoffset[TX_IP_OFFSET_ENTRY_MAX]; - u32 vtagtable[0x8]; /* 8 4-byte VLAN tags */ - u32 tqptr; /* a base pointer to the Tx Queues Memory - Region */ - u8 res2[0x80 - 0x74]; -} __attribute__ ((packed)) ucc_geth_tx_global_pram_t; - -/* structure representing Extended Filtering Global Parameters in PRAM */ -typedef struct ucc_geth_exf_global_pram { - u32 l2pcdptr; /* individual address filter, high */ - u8 res0[0x10 - 0x04]; -} __attribute__ ((packed)) ucc_geth_exf_global_pram_t; - -typedef struct ucc_geth_rx_global_pram { - u32 remoder; /* ethernet mode reg. */ - u32 rqptr; /* base pointer to the Rx Queues Memory Region*/ - u32 res0[0x1]; - u8 res1[0x20 - 0xC]; - u16 typeorlen; /* cutoff point less than which, type/len field - is considered length */ - u8 res2[0x1]; - u8 rxgstpack; /* acknowledgement on GRACEFUL STOP RX command*/ - u32 rxrmonbaseptr; /* base pointer to Rx RMON statistics counter */ - u8 res3[0x30 - 0x28]; - u32 intcoalescingptr; /* Interrupt coalescing table pointer */ - u8 res4[0x36 - 0x34]; - u8 rstate; /* rx internal state. High byte contains - function code */ - u8 res5[0x46 - 0x37]; - u16 mrblr; /* max receive buffer length reg. */ - u32 rbdqptr; /* base pointer to RxBD parameter table - description */ - u16 mflr; /* max frame length reg. */ - u16 minflr; /* min frame length reg. */ - u16 maxd1; /* max dma1 length reg. */ - u16 maxd2; /* max dma2 length reg. */ - u32 ecamptr; /* external CAM address */ - u32 l2qt; /* VLAN priority mapping table. */ - u32 l3qt[0x8]; /* IP priority mapping table. */ - u16 vlantype; /* vlan type */ - u16 vlantci; /* default vlan tci */ - u8 addressfiltering[64]; /* address filtering data structure */ - u32 exfGlobalParam; /* base address for extended filtering global - parameters */ - u8 res6[0x100 - 0xC4]; /* Initialize to zero */ -} __attribute__ ((packed)) ucc_geth_rx_global_pram_t; - -#define GRACEFUL_STOP_ACKNOWLEDGE_RX 0x01 - -/* structure representing InitEnet command */ -typedef struct ucc_geth_init_pram { - u8 resinit1; - u8 resinit2; - u8 resinit3; - u8 resinit4; - u16 resinit5; - u8 res1[0x1]; - u8 largestexternallookupkeysize; - u32 rgftgfrxglobal; - u32 rxthread[ENET_INIT_PARAM_MAX_ENTRIES_RX]; /* rx threads */ - u8 res2[0x38 - 0x30]; - u32 txglobal; /* tx global */ - u32 txthread[ENET_INIT_PARAM_MAX_ENTRIES_TX]; /* tx threads */ - u8 res3[0x1]; -} __attribute__ ((packed)) ucc_geth_init_pram_t; - -#define ENET_INIT_PARAM_RGF_SHIFT (32 - 4) -#define ENET_INIT_PARAM_TGF_SHIFT (32 - 8) - -#define ENET_INIT_PARAM_RISC_MASK 0x0000003f -#define ENET_INIT_PARAM_PTR_MASK 0x00ffffc0 -#define ENET_INIT_PARAM_SNUM_MASK 0xff000000 -#define ENET_INIT_PARAM_SNUM_SHIFT 24 - -#define ENET_INIT_PARAM_MAGIC_RES_INIT1 0x06 -#define ENET_INIT_PARAM_MAGIC_RES_INIT2 0x30 -#define ENET_INIT_PARAM_MAGIC_RES_INIT3 0xff -#define ENET_INIT_PARAM_MAGIC_RES_INIT4 0x00 -#define ENET_INIT_PARAM_MAGIC_RES_INIT5 0x0400 - -/* structure representing 82xx Address Filtering Enet Address in PRAM */ -typedef struct ucc_geth_82xx_enet_address { - u8 res1[0x2]; - u16 h; /* address (MSB) */ - u16 m; /* address */ - u16 l; /* address (LSB) */ -} __attribute__ ((packed)) ucc_geth_82xx_enet_address_t; - -/* structure representing 82xx Address Filtering PRAM */ -typedef struct ucc_geth_82xx_address_filtering_pram { - u32 iaddr_h; /* individual address filter, high */ - u32 iaddr_l; /* individual address filter, low */ - u32 gaddr_h; /* group address filter, high */ - u32 gaddr_l; /* group address filter, low */ - ucc_geth_82xx_enet_address_t taddr; - ucc_geth_82xx_enet_address_t paddr[NUM_OF_PADDRS]; - u8 res0[0x40 - 0x38]; -} __attribute__ ((packed)) ucc_geth_82xx_address_filtering_pram_t; - -/* GETH Tx firmware statistics structure, used when calling - UCC_GETH_GetStatistics. */ -typedef struct ucc_geth_tx_firmware_statistics { - u32 sicoltx; /* single collision */ - u32 mulcoltx; /* multiple collision */ - u32 latecoltxfr; /* late collision */ - u32 frabortduecol; /* frames aborted due to transmit collision */ - u32 frlostinmactxer; /* frames lost due to internal MAC error - transmission that are not counted on any - other counter */ - u32 carriersenseertx; /* carrier sense error */ - u32 frtxok; /* frames transmitted OK */ - u32 txfrexcessivedefer; /* frames with defferal time greater than - specified threshold */ - u32 txpkts256; /* total packets (including bad) between 256 - and 511 octets */ - u32 txpkts512; /* total packets (including bad) between 512 - and 1023 octets */ - u32 txpkts1024; /* total packets (including bad) between 1024 - and 1518 octets */ - u32 txpktsjumbo; /* total packets (including bad) between 1024 - and MAXLength octets */ -} __attribute__ ((packed)) ucc_geth_tx_firmware_statistics_t; - -/* GETH Rx firmware statistics structure, used when calling - UCC_GETH_GetStatistics. */ -typedef struct ucc_geth_rx_firmware_statistics { - u32 frrxfcser; /* frames with crc error */ - u32 fraligner; /* frames with alignment error */ - u32 inrangelenrxer; /* in range length error */ - u32 outrangelenrxer; /* out of range length error */ - u32 frtoolong; /* frame too long */ - u32 runt; /* runt */ - u32 verylongevent; /* very long event */ - u32 symbolerror; /* symbol error */ - u32 dropbsy; /* drop because of BD not ready */ - u8 res0[0x8]; - u32 mismatchdrop; /* drop because of MAC filtering (e.g. address - or type mismatch) */ - u32 underpkts; /* total frames less than 64 octets */ - u32 pkts256; /* total frames (including bad) between 256 and - 511 octets */ - u32 pkts512; /* total frames (including bad) between 512 and - 1023 octets */ - u32 pkts1024; /* total frames (including bad) between 1024 - and 1518 octets */ - u32 pktsjumbo; /* total frames (including bad) between 1024 - and MAXLength octets */ - u32 frlossinmacer; /* frames lost because of internal MAC error - that is not counted in any other counter */ - u32 pausefr; /* pause frames */ - u8 res1[0x4]; - u32 removevlan; /* total frames that had their VLAN tag removed - */ - u32 replacevlan; /* total frames that had their VLAN tag - replaced */ - u32 insertvlan; /* total frames that had their VLAN tag - inserted */ -} __attribute__ ((packed)) ucc_geth_rx_firmware_statistics_t; - -/* GETH hardware statistics structure, used when calling - UCC_GETH_GetStatistics. */ -typedef struct ucc_geth_hardware_statistics { - u32 tx64; /* Total number of frames (including bad - frames) transmitted that were exactly of the - minimal length (64 for un tagged, 68 for - tagged, or with length exactly equal to the - parameter MINLength */ - u32 tx127; /* Total number of frames (including bad - frames) transmitted that were between - MINLength (Including FCS length==4) and 127 - octets */ - u32 tx255; /* Total number of frames (including bad - frames) transmitted that were between 128 - (Including FCS length==4) and 255 octets */ - u32 rx64; /* Total number of frames received including - bad frames that were exactly of the mninimal - length (64 bytes) */ - u32 rx127; /* Total number of frames (including bad - frames) received that were between MINLength - (Including FCS length==4) and 127 octets */ - u32 rx255; /* Total number of frames (including bad - frames) received that were between 128 - (Including FCS length==4) and 255 octets */ - u32 txok; /* Total number of octets residing in frames - that where involved in succesfull - transmission */ - u16 txcf; /* Total number of PAUSE control frames - transmitted by this MAC */ - u32 tmca; /* Total number of frames that were transmitted - succesfully with the group address bit set - that are not broadcast frames */ - u32 tbca; /* Total number of frames transmitted - succesfully that had destination address - field equal to the broadcast address */ - u32 rxfok; /* Total number of frames received OK */ - u32 rxbok; /* Total number of octets received OK */ - u32 rbyt; /* Total number of octets received including - octets in bad frames. Must be implemented in - HW because it includes octets in frames that - never even reach the UCC */ - u32 rmca; /* Total number of frames that were received - succesfully with the group address bit set - that are not broadcast frames */ - u32 rbca; /* Total number of frames received succesfully - that had destination address equal to the - broadcast address */ -} __attribute__ ((packed)) ucc_geth_hardware_statistics_t; - -/* UCC GETH Tx errors returned via TxConf callback */ -#define TX_ERRORS_DEF 0x0200 -#define TX_ERRORS_EXDEF 0x0100 -#define TX_ERRORS_LC 0x0080 -#define TX_ERRORS_RL 0x0040 -#define TX_ERRORS_RC_MASK 0x003C -#define TX_ERRORS_RC_SHIFT 2 -#define TX_ERRORS_UN 0x0002 -#define TX_ERRORS_CSL 0x0001 - -/* UCC GETH Rx errors returned via RxStore callback */ -#define RX_ERRORS_CMR 0x0200 -#define RX_ERRORS_M 0x0100 -#define RX_ERRORS_BC 0x0080 -#define RX_ERRORS_MC 0x0040 - -/* Transmit BD. These are in addition to values defined in uccf. */ -#define T_VID 0x003c0000 /* insert VLAN id index mask. */ -#define T_DEF (((u32) TX_ERRORS_DEF ) << 16) -#define T_EXDEF (((u32) TX_ERRORS_EXDEF ) << 16) -#define T_LC (((u32) TX_ERRORS_LC ) << 16) -#define T_RL (((u32) TX_ERRORS_RL ) << 16) -#define T_RC_MASK (((u32) TX_ERRORS_RC_MASK ) << 16) -#define T_UN (((u32) TX_ERRORS_UN ) << 16) -#define T_CSL (((u32) TX_ERRORS_CSL ) << 16) -#define T_ERRORS_REPORT (T_DEF | T_EXDEF | T_LC | T_RL | T_RC_MASK \ - | T_UN | T_CSL) /* transmit errors to report */ - -/* Receive BD. These are in addition to values defined in uccf. */ -#define R_LG 0x00200000 /* Frame length violation. */ -#define R_NO 0x00100000 /* Non-octet aligned frame. */ -#define R_SH 0x00080000 /* Short frame. */ -#define R_CR 0x00040000 /* CRC error. */ -#define R_OV 0x00020000 /* Overrun. */ -#define R_IPCH 0x00010000 /* IP checksum check failed. */ -#define R_CMR (((u32) RX_ERRORS_CMR ) << 16) -#define R_M (((u32) RX_ERRORS_M ) << 16) -#define R_BC (((u32) RX_ERRORS_BC ) << 16) -#define R_MC (((u32) RX_ERRORS_MC ) << 16) -#define R_ERRORS_REPORT (R_CMR | R_M | R_BC | R_MC) /* receive errors to - report */ -#define R_ERRORS_FATAL (R_LG | R_NO | R_SH | R_CR | \ - R_OV | R_IPCH) /* receive errors to discard */ - -/* Alignments */ -#define UCC_GETH_RX_GLOBAL_PRAM_ALIGNMENT 256 -#define UCC_GETH_TX_GLOBAL_PRAM_ALIGNMENT 128 -#define UCC_GETH_THREAD_RX_PRAM_ALIGNMENT 128 -#define UCC_GETH_THREAD_TX_PRAM_ALIGNMENT 64 -#define UCC_GETH_THREAD_DATA_ALIGNMENT 256 /* spec gives values - based on num of - threads, but always - using the maximum is - easier */ -#define UCC_GETH_SEND_QUEUE_QUEUE_DESCRIPTOR_ALIGNMENT 32 -#define UCC_GETH_SCHEDULER_ALIGNMENT 4 /* This is a guess */ -#define UCC_GETH_TX_STATISTICS_ALIGNMENT 4 /* This is a guess */ -#define UCC_GETH_RX_STATISTICS_ALIGNMENT 4 /* This is a guess */ -#define UCC_GETH_RX_INTERRUPT_COALESCING_ALIGNMENT 4 /* This is a - guess */ -#define UCC_GETH_RX_BD_QUEUES_ALIGNMENT 8 /* This is a guess */ -#define UCC_GETH_RX_PREFETCHED_BDS_ALIGNMENT 128 /* This is a guess */ -#define UCC_GETH_RX_EXTENDED_FILTERING_GLOBAL_PARAMETERS_ALIGNMENT 4 /* This - is a - guess - */ -#define UCC_GETH_RX_BD_RING_ALIGNMENT 32 -#define UCC_GETH_TX_BD_RING_ALIGNMENT 32 -#define UCC_GETH_MRBLR_ALIGNMENT 128 -#define UCC_GETH_RX_BD_RING_SIZE_ALIGNMENT 4 -#define UCC_GETH_TX_BD_RING_SIZE_MEMORY_ALIGNMENT 32 -#define UCC_GETH_RX_DATA_BUF_ALIGNMENT 64 - -#define UCC_GETH_TAD_EF 0x80 -#define UCC_GETH_TAD_V 0x40 -#define UCC_GETH_TAD_REJ 0x20 -#define UCC_GETH_TAD_VTAG_OP_RIGHT_SHIFT 2 -#define UCC_GETH_TAD_VTAG_OP_SHIFT 6 -#define UCC_GETH_TAD_V_NON_VTAG_OP 0x20 -#define UCC_GETH_TAD_RQOS_SHIFT 0 -#define UCC_GETH_TAD_V_PRIORITY_SHIFT 5 -#define UCC_GETH_TAD_CFI 0x10 - -#define UCC_GETH_VLAN_PRIORITY_MAX 8 -#define UCC_GETH_IP_PRIORITY_MAX 64 -#define UCC_GETH_TX_VTAG_TABLE_ENTRY_MAX 8 -#define UCC_GETH_RX_BD_RING_SIZE_MIN 8 -#define UCC_GETH_TX_BD_RING_SIZE_MIN 2 - -#define UCC_GETH_SIZE_OF_BD QE_SIZEOF_BD - -/* Driver definitions */ -#define TX_BD_RING_LEN 0x10 -#define RX_BD_RING_LEN 0x10 -#define UCC_GETH_DEV_WEIGHT TX_BD_RING_LEN - -#define TX_RING_MOD_MASK(size) (size-1) -#define RX_RING_MOD_MASK(size) (size-1) - -#define ENET_NUM_OCTETS_PER_ADDRESS 6 -#define ENET_GROUP_ADDR 0x01 /* Group address mask - for ethernet - addresses */ - -#define TX_TIMEOUT (1*HZ) -#define SKB_ALLOC_TIMEOUT 100000 -#define PHY_INIT_TIMEOUT 100000 -#define PHY_CHANGE_TIME 2 - -/* Fast Ethernet (10/100 Mbps) */ -#define UCC_GETH_URFS_INIT 512 /* Rx virtual FIFO size - */ -#define UCC_GETH_URFET_INIT 256 /* 1/2 urfs */ -#define UCC_GETH_URFSET_INIT 384 /* 3/4 urfs */ -#define UCC_GETH_UTFS_INIT 512 /* Tx virtual FIFO size - */ -#define UCC_GETH_UTFET_INIT 256 /* 1/2 utfs */ -#define UCC_GETH_UTFTT_INIT 128 -/* Gigabit Ethernet (1000 Mbps) */ -#define UCC_GETH_URFS_GIGA_INIT 4096/*2048*/ /* Rx virtual - FIFO size */ -#define UCC_GETH_URFET_GIGA_INIT 2048/*1024*/ /* 1/2 urfs */ -#define UCC_GETH_URFSET_GIGA_INIT 3072/*1536*/ /* 3/4 urfs */ -#define UCC_GETH_UTFS_GIGA_INIT 8192/*2048*/ /* Tx virtual - FIFO size */ -#define UCC_GETH_UTFET_GIGA_INIT 4096/*1024*/ /* 1/2 utfs */ -#define UCC_GETH_UTFTT_GIGA_INIT 0x400/*0x40*/ /* */ - -#define UCC_GETH_REMODER_INIT 0 /* bits that must be - set */ -#define UCC_GETH_TEMODER_INIT 0xC000 /* bits that must */ -#define UCC_GETH_UPSMR_INIT (UPSMR_RES1) /* Start value - for this - register */ -#define UCC_GETH_MACCFG1_INIT 0 -#define UCC_GETH_MACCFG2_INIT (MACCFG2_RESERVED_1) -#define UCC_GETH_MIIMCFG_MNGMNT_CLC_DIV_INIT \ - (MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_112) - -/* Ethernet speed */ -typedef enum enet_speed { - ENET_SPEED_10BT, /* 10 Base T */ - ENET_SPEED_100BT, /* 100 Base T */ - ENET_SPEED_1000BT /* 1000 Base T */ -} enet_speed_e; - -/* Ethernet Address Type. */ -typedef enum enet_addr_type { - ENET_ADDR_TYPE_INDIVIDUAL, - ENET_ADDR_TYPE_GROUP, - ENET_ADDR_TYPE_BROADCAST -} enet_addr_type_e; - -/* TBI / MII Set Register */ -typedef enum enet_tbi_mii_reg { - ENET_TBI_MII_CR = 0x00, /* Control (CR ) */ - ENET_TBI_MII_SR = 0x01, /* Status (SR ) */ - ENET_TBI_MII_ANA = 0x04, /* AN advertisement (ANA ) */ - ENET_TBI_MII_ANLPBPA = 0x05, /* AN link partner base page ability - (ANLPBPA) */ - ENET_TBI_MII_ANEX = 0x06, /* AN expansion (ANEX ) */ - ENET_TBI_MII_ANNPT = 0x07, /* AN next page transmit (ANNPT ) */ - ENET_TBI_MII_ANLPANP = 0x08, /* AN link partner ability next page - (ANLPANP) */ - ENET_TBI_MII_EXST = 0x0F, /* Extended status (EXST ) */ - ENET_TBI_MII_JD = 0x10, /* Jitter diagnostics (JD ) */ - ENET_TBI_MII_TBICON = 0x11 /* TBI control (TBICON ) */ -} enet_tbi_mii_reg_e; - -/* UCC GETH 82xx Ethernet Address Recognition Location */ -typedef enum ucc_geth_enet_address_recognition_location { - UCC_GETH_ENET_ADDRESS_RECOGNITION_LOCATION_STATION_ADDRESS,/* station - address */ - UCC_GETH_ENET_ADDRESS_RECOGNITION_LOCATION_PADDR_FIRST, /* additional - station - address - paddr1 */ - UCC_GETH_ENET_ADDRESS_RECOGNITION_LOCATION_PADDR2, /* additional - station - address - paddr2 */ - UCC_GETH_ENET_ADDRESS_RECOGNITION_LOCATION_PADDR3, /* additional - station - address - paddr3 */ - UCC_GETH_ENET_ADDRESS_RECOGNITION_LOCATION_PADDR_LAST, /* additional - station - address - paddr4 */ - UCC_GETH_ENET_ADDRESS_RECOGNITION_LOCATION_GROUP_HASH, /* group hash */ - UCC_GETH_ENET_ADDRESS_RECOGNITION_LOCATION_INDIVIDUAL_HASH /* individual - hash */ -} ucc_geth_enet_address_recognition_location_e; - -/* UCC GETH vlan operation tagged */ -typedef enum ucc_geth_vlan_operation_tagged { - UCC_GETH_VLAN_OPERATION_TAGGED_NOP = 0x0, /* Tagged - nop */ - UCC_GETH_VLAN_OPERATION_TAGGED_REPLACE_VID_PORTION_OF_Q_TAG - = 0x1, /* Tagged - replace vid portion of q tag */ - UCC_GETH_VLAN_OPERATION_TAGGED_IF_VID0_REPLACE_VID_WITH_DEFAULT_VALUE - = 0x2, /* Tagged - if vid0 replace vid with default value */ - UCC_GETH_VLAN_OPERATION_TAGGED_EXTRACT_Q_TAG_FROM_FRAME - = 0x3 /* Tagged - extract q tag from frame */ -} ucc_geth_vlan_operation_tagged_e; - -/* UCC GETH vlan operation non-tagged */ -typedef enum ucc_geth_vlan_operation_non_tagged { - UCC_GETH_VLAN_OPERATION_NON_TAGGED_NOP = 0x0, /* Non tagged - nop */ - UCC_GETH_VLAN_OPERATION_NON_TAGGED_Q_TAG_INSERT = 0x1 /* Non tagged - - q tag insert - */ -} ucc_geth_vlan_operation_non_tagged_e; - -/* UCC GETH Rx Quality of Service Mode */ -typedef enum ucc_geth_qos_mode { - UCC_GETH_QOS_MODE_DEFAULT = 0x0, /* default queue */ - UCC_GETH_QOS_MODE_QUEUE_NUM_FROM_L2_CRITERIA = 0x1, /* queue - determined - by L2 - criteria */ - UCC_GETH_QOS_MODE_QUEUE_NUM_FROM_L3_CRITERIA = 0x2 /* queue - determined - by L3 - criteria */ -} ucc_geth_qos_mode_e; - -/* UCC GETH Statistics Gathering Mode - These are bit flags, 'or' them together - for combined functionality */ -typedef enum ucc_geth_statistics_gathering_mode { - UCC_GETH_STATISTICS_GATHERING_MODE_NONE = 0x00000000, /* No - statistics - gathering */ - UCC_GETH_STATISTICS_GATHERING_MODE_HARDWARE = 0x00000001,/* Enable - hardware - statistics - gathering - */ - UCC_GETH_STATISTICS_GATHERING_MODE_FIRMWARE_TX = 0x00000004,/*Enable - firmware - tx - statistics - gathering - */ - UCC_GETH_STATISTICS_GATHERING_MODE_FIRMWARE_RX = 0x00000008/* Enable - firmware - rx - statistics - gathering - */ -} ucc_geth_statistics_gathering_mode_e; - -/* UCC GETH Pad and CRC Mode - Note, Padding without CRC is not possible */ -typedef enum ucc_geth_maccfg2_pad_and_crc_mode { - UCC_GETH_PAD_AND_CRC_MODE_NONE - = MACCFG2_PAD_AND_CRC_MODE_NONE, /* Neither Padding - short frames - nor CRC */ - UCC_GETH_PAD_AND_CRC_MODE_CRC_ONLY - = MACCFG2_PAD_AND_CRC_MODE_CRC_ONLY, /* Append - CRC only */ - UCC_GETH_PAD_AND_CRC_MODE_PAD_AND_CRC = - MACCFG2_PAD_AND_CRC_MODE_PAD_AND_CRC -} ucc_geth_maccfg2_pad_and_crc_mode_e; - -/* UCC GETH upsmr Flow Control Mode */ -typedef enum ucc_geth_flow_control_mode { - UPSMR_AUTOMATIC_FLOW_CONTROL_MODE_NONE = 0x00000000, /* No automatic - flow control - */ - UPSMR_AUTOMATIC_FLOW_CONTROL_MODE_PAUSE_WHEN_EMERGENCY - = 0x00004000 /* Send pause frame when RxFIFO reaches its - emergency threshold */ -} ucc_geth_flow_control_mode_e; - -/* UCC GETH number of threads */ -typedef enum ucc_geth_num_of_threads { - UCC_GETH_NUM_OF_THREADS_1 = 0x1, /* 1 */ - UCC_GETH_NUM_OF_THREADS_2 = 0x2, /* 2 */ - UCC_GETH_NUM_OF_THREADS_4 = 0x0, /* 4 */ - UCC_GETH_NUM_OF_THREADS_6 = 0x3, /* 6 */ - UCC_GETH_NUM_OF_THREADS_8 = 0x4 /* 8 */ -} ucc_geth_num_of_threads_e; - -/* UCC GETH number of station addresses */ -typedef enum ucc_geth_num_of_station_addresses { - UCC_GETH_NUM_OF_STATION_ADDRESSES_1, /* 1 */ - UCC_GETH_NUM_OF_STATION_ADDRESSES_5 /* 5 */ -} ucc_geth_num_of_station_addresses_e; - -typedef u8 enet_addr_t[ENET_NUM_OCTETS_PER_ADDRESS]; - -/* UCC GETH 82xx Ethernet Address Container */ -typedef struct enet_addr_container { - enet_addr_t address; /* ethernet address */ - ucc_geth_enet_address_recognition_location_e location; /* location in - 82xx address - recognition - hardware */ - struct list_head node; -} enet_addr_container_t; - -#define ENET_ADDR_CONT_ENTRY(ptr) list_entry(ptr, enet_addr_container_t, node) - -/* UCC GETH Termination Action Descriptor (TAD) structure. */ -typedef struct ucc_geth_tad_params { - int rx_non_dynamic_extended_features_mode; - int reject_frame; - ucc_geth_vlan_operation_tagged_e vtag_op; - ucc_geth_vlan_operation_non_tagged_e vnontag_op; - ucc_geth_qos_mode_e rqos; - u8 vpri; - u16 vid; -} ucc_geth_tad_params_t; - -/* GETH protocol initialization structure */ -typedef struct ucc_geth_info { - ucc_fast_info_t uf_info; - u8 numQueuesTx; - u8 numQueuesRx; - int ipCheckSumCheck; - int ipCheckSumGenerate; - int rxExtendedFiltering; - u32 extendedFilteringChainPointer; - u16 typeorlen; - int dynamicMaxFrameLength; - int dynamicMinFrameLength; - u8 nonBackToBackIfgPart1; - u8 nonBackToBackIfgPart2; - u8 miminumInterFrameGapEnforcement; - u8 backToBackInterFrameGap; - int ipAddressAlignment; - int lengthCheckRx; - u32 mblinterval; - u16 nortsrbytetime; - u8 fracsiz; - u8 strictpriorityq; - u8 txasap; - u8 extrabw; - int miiPreambleSupress; - u8 altBebTruncation; - int altBeb; - int backPressureNoBackoff; - int noBackoff; - int excessDefer; - u8 maxRetransmission; - u8 collisionWindow; - int pro; - int cap; - int rsh; - int rlpb; - int cam; - int bro; - int ecm; - int receiveFlowControl; - u8 maxGroupAddrInHash; - u8 maxIndAddrInHash; - u8 prel; - u16 maxFrameLength; - u16 minFrameLength; - u16 maxD1Length; - u16 maxD2Length; - u16 vlantype; - u16 vlantci; - u32 ecamptr; - u32 eventRegMask; - u16 pausePeriod; - u16 extensionField; - u8 phy_address; - u32 board_flags; - u32 phy_interrupt; - u8 weightfactor[NUM_TX_QUEUES]; - u8 interruptcoalescingmaxvalue[NUM_RX_QUEUES]; - u8 l2qt[UCC_GETH_VLAN_PRIORITY_MAX]; - u8 l3qt[UCC_GETH_IP_PRIORITY_MAX]; - u32 vtagtable[UCC_GETH_TX_VTAG_TABLE_ENTRY_MAX]; - u8 iphoffset[TX_IP_OFFSET_ENTRY_MAX]; - u16 bdRingLenTx[NUM_TX_QUEUES]; - u16 bdRingLenRx[NUM_RX_QUEUES]; - enet_interface_e enet_interface; - ucc_geth_num_of_station_addresses_e numStationAddresses; - qe_fltr_largest_external_tbl_lookup_key_size_e - largestexternallookupkeysize; - ucc_geth_statistics_gathering_mode_e statisticsMode; - ucc_geth_vlan_operation_tagged_e vlanOperationTagged; - ucc_geth_vlan_operation_non_tagged_e vlanOperationNonTagged; - ucc_geth_qos_mode_e rxQoSMode; - ucc_geth_flow_control_mode_e aufc; - ucc_geth_maccfg2_pad_and_crc_mode_e padAndCrc; - ucc_geth_num_of_threads_e numThreadsTx; - ucc_geth_num_of_threads_e numThreadsRx; - qe_risc_allocation_e riscTx; - qe_risc_allocation_e riscRx; -} ucc_geth_info_t; - -/* structure representing UCC GETH */ -typedef struct ucc_geth_private { - ucc_geth_info_t *ug_info; - ucc_fast_private_t *uccf; - struct net_device *dev; - struct net_device_stats stats; /* linux network statistics */ - ucc_geth_t *ug_regs; - ucc_geth_init_pram_t *p_init_enet_param_shadow; - ucc_geth_exf_global_pram_t *p_exf_glbl_param; - u32 exf_glbl_param_offset; - ucc_geth_rx_global_pram_t *p_rx_glbl_pram; - u32 rx_glbl_pram_offset; - ucc_geth_tx_global_pram_t *p_tx_glbl_pram; - u32 tx_glbl_pram_offset; - ucc_geth_send_queue_mem_region_t *p_send_q_mem_reg; - u32 send_q_mem_reg_offset; - ucc_geth_thread_data_tx_t *p_thread_data_tx; - u32 thread_dat_tx_offset; - ucc_geth_thread_data_rx_t *p_thread_data_rx; - u32 thread_dat_rx_offset; - ucc_geth_scheduler_t *p_scheduler; - u32 scheduler_offset; - ucc_geth_tx_firmware_statistics_pram_t *p_tx_fw_statistics_pram; - u32 tx_fw_statistics_pram_offset; - ucc_geth_rx_firmware_statistics_pram_t *p_rx_fw_statistics_pram; - u32 rx_fw_statistics_pram_offset; - ucc_geth_rx_interrupt_coalescing_table_t *p_rx_irq_coalescing_tbl; - u32 rx_irq_coalescing_tbl_offset; - ucc_geth_rx_bd_queues_entry_t *p_rx_bd_qs_tbl; - u32 rx_bd_qs_tbl_offset; - u8 *p_tx_bd_ring[NUM_TX_QUEUES]; - u32 tx_bd_ring_offset[NUM_TX_QUEUES]; - u8 *p_rx_bd_ring[NUM_RX_QUEUES]; - u32 rx_bd_ring_offset[NUM_RX_QUEUES]; - u8 *confBd[NUM_TX_QUEUES]; - u8 *txBd[NUM_TX_QUEUES]; - u8 *rxBd[NUM_RX_QUEUES]; - int badFrame[NUM_RX_QUEUES]; - u16 cpucount[NUM_TX_QUEUES]; - volatile u16 *p_cpucount[NUM_TX_QUEUES]; - int indAddrRegUsed[NUM_OF_PADDRS]; - enet_addr_t paddr[NUM_OF_PADDRS]; - u8 numGroupAddrInHash; - u8 numIndAddrInHash; - u8 numIndAddrInReg; - int rx_extended_features; - int rx_non_dynamic_extended_features; - struct list_head conf_skbs; - struct list_head group_hash_q; - struct list_head ind_hash_q; - u32 saved_uccm; - spinlock_t lock; - /* pointers to arrays of skbuffs for tx and rx */ - struct sk_buff **tx_skbuff[NUM_TX_QUEUES]; - struct sk_buff **rx_skbuff[NUM_RX_QUEUES]; - /* indices pointing to the next free sbk in skb arrays */ - u16 skb_curtx[NUM_TX_QUEUES]; - u16 skb_currx[NUM_RX_QUEUES]; - /* index of the first skb which hasn't been transmitted yet. */ - u16 skb_dirtytx[NUM_TX_QUEUES]; - - struct work_struct tq; - struct timer_list phy_info_timer; - struct ugeth_mii_info *mii_info; - int oldspeed; - int oldduplex; - int oldlink; -} ucc_geth_private_t; - -#endif /* __UCC_GETH_H__ */ diff --git a/trunk/drivers/net/ucc_geth_phy.c b/trunk/drivers/net/ucc_geth_phy.c deleted file mode 100644 index f91028c5386d..000000000000 --- a/trunk/drivers/net/ucc_geth_phy.c +++ /dev/null @@ -1,801 +0,0 @@ -/* - * Copyright (C) Freescale Semicondutor, Inc. 2006. All rights reserved. - * - * Author: Shlomi Gridish - * - * Description: - * UCC GETH Driver -- PHY handling - * - * Changelog: - * Jun 28, 2006 Li Yang - * - Rearrange code and style fixes - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "ucc_geth.h" -#include "ucc_geth_phy.h" -#include - -#define ugphy_printk(level, format, arg...) \ - printk(level format "\n", ## arg) - -#define ugphy_dbg(format, arg...) \ - ugphy_printk(KERN_DEBUG, format , ## arg) -#define ugphy_err(format, arg...) \ - ugphy_printk(KERN_ERR, format , ## arg) -#define ugphy_info(format, arg...) \ - ugphy_printk(KERN_INFO, format , ## arg) -#define ugphy_warn(format, arg...) \ - ugphy_printk(KERN_WARNING, format , ## arg) - -#ifdef UGETH_VERBOSE_DEBUG -#define ugphy_vdbg ugphy_dbg -#else -#define ugphy_vdbg(fmt, args...) do { } while (0) -#endif /* UGETH_VERBOSE_DEBUG */ - -static void config_genmii_advert(struct ugeth_mii_info *mii_info); -static void genmii_setup_forced(struct ugeth_mii_info *mii_info); -static void genmii_restart_aneg(struct ugeth_mii_info *mii_info); -static int gbit_config_aneg(struct ugeth_mii_info *mii_info); -static int genmii_config_aneg(struct ugeth_mii_info *mii_info); -static int genmii_update_link(struct ugeth_mii_info *mii_info); -static int genmii_read_status(struct ugeth_mii_info *mii_info); -u16 phy_read(struct ugeth_mii_info *mii_info, u16 regnum); -void phy_write(struct ugeth_mii_info *mii_info, u16 regnum, u16 val); - -static u8 *bcsr_regs = NULL; - -/* Write value to the PHY for this device to the register at regnum, */ -/* waiting until the write is done before it returns. All PHY */ -/* configuration has to be done through the TSEC1 MIIM regs */ -void write_phy_reg(struct net_device *dev, int mii_id, int regnum, int value) -{ - ucc_geth_private_t *ugeth = netdev_priv(dev); - ucc_mii_mng_t *mii_regs; - enet_tbi_mii_reg_e mii_reg = (enet_tbi_mii_reg_e) regnum; - u32 tmp_reg; - - ugphy_vdbg("%s: IN", __FUNCTION__); - - spin_lock_irq(&ugeth->lock); - - mii_regs = ugeth->mii_info->mii_regs; - - /* Set this UCC to be the master of the MII managment */ - ucc_set_qe_mux_mii_mng(ugeth->ug_info->uf_info.ucc_num); - - /* Stop the MII management read cycle */ - out_be32(&mii_regs->miimcom, 0); - /* Setting up the MII Mangement Address Register */ - tmp_reg = ((u32) mii_id << MIIMADD_PHY_ADDRESS_SHIFT) | mii_reg; - out_be32(&mii_regs->miimadd, tmp_reg); - - /* Setting up the MII Mangement Control Register with the value */ - out_be32(&mii_regs->miimcon, (u32) value); - - /* Wait till MII management write is complete */ - while ((in_be32(&mii_regs->miimind)) & MIIMIND_BUSY) - cpu_relax(); - - spin_unlock_irq(&ugeth->lock); - - udelay(10000); -} - -/* Reads from register regnum in the PHY for device dev, */ -/* returning the value. Clears miimcom first. All PHY */ -/* configuration has to be done through the TSEC1 MIIM regs */ -int read_phy_reg(struct net_device *dev, int mii_id, int regnum) -{ - ucc_geth_private_t *ugeth = netdev_priv(dev); - ucc_mii_mng_t *mii_regs; - enet_tbi_mii_reg_e mii_reg = (enet_tbi_mii_reg_e) regnum; - u32 tmp_reg; - u16 value; - - ugphy_vdbg("%s: IN", __FUNCTION__); - - spin_lock_irq(&ugeth->lock); - - mii_regs = ugeth->mii_info->mii_regs; - - /* Setting up the MII Mangement Address Register */ - tmp_reg = ((u32) mii_id << MIIMADD_PHY_ADDRESS_SHIFT) | mii_reg; - out_be32(&mii_regs->miimadd, tmp_reg); - - /* Perform an MII management read cycle */ - out_be32(&mii_regs->miimcom, MIIMCOM_READ_CYCLE); - - /* Wait till MII management write is complete */ - while ((in_be32(&mii_regs->miimind)) & MIIMIND_BUSY) - cpu_relax(); - - udelay(10000); - - /* Read MII management status */ - value = (u16) in_be32(&mii_regs->miimstat); - out_be32(&mii_regs->miimcom, 0); - if (value == 0xffff) - ugphy_warn("read wrong value : mii_id %d,mii_reg %d, base %08x", - mii_id, mii_reg, (u32) & (mii_regs->miimcfg)); - - spin_unlock_irq(&ugeth->lock); - - return (value); -} - -void mii_clear_phy_interrupt(struct ugeth_mii_info *mii_info) -{ - ugphy_vdbg("%s: IN", __FUNCTION__); - - if (mii_info->phyinfo->ack_interrupt) - mii_info->phyinfo->ack_interrupt(mii_info); -} - -void mii_configure_phy_interrupt(struct ugeth_mii_info *mii_info, - u32 interrupts) -{ - ugphy_vdbg("%s: IN", __FUNCTION__); - - mii_info->interrupts = interrupts; - if (mii_info->phyinfo->config_intr) - mii_info->phyinfo->config_intr(mii_info); -} - -/* Writes MII_ADVERTISE with the appropriate values, after - * sanitizing advertise to make sure only supported features - * are advertised - */ -static void config_genmii_advert(struct ugeth_mii_info *mii_info) -{ - u32 advertise; - u16 adv; - - ugphy_vdbg("%s: IN", __FUNCTION__); - - /* Only allow advertising what this PHY supports */ - mii_info->advertising &= mii_info->phyinfo->features; - advertise = mii_info->advertising; - - /* Setup standard advertisement */ - adv = phy_read(mii_info, MII_ADVERTISE); - adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4); - if (advertise & ADVERTISED_10baseT_Half) - adv |= ADVERTISE_10HALF; - if (advertise & ADVERTISED_10baseT_Full) - adv |= ADVERTISE_10FULL; - if (advertise & ADVERTISED_100baseT_Half) - adv |= ADVERTISE_100HALF; - if (advertise & ADVERTISED_100baseT_Full) - adv |= ADVERTISE_100FULL; - phy_write(mii_info, MII_ADVERTISE, adv); -} - -static void genmii_setup_forced(struct ugeth_mii_info *mii_info) -{ - u16 ctrl; - u32 features = mii_info->phyinfo->features; - - ugphy_vdbg("%s: IN", __FUNCTION__); - - ctrl = phy_read(mii_info, MII_BMCR); - - ctrl &= - ~(BMCR_FULLDPLX | BMCR_SPEED100 | BMCR_SPEED1000 | BMCR_ANENABLE); - ctrl |= BMCR_RESET; - - switch (mii_info->speed) { - case SPEED_1000: - if (features & (SUPPORTED_1000baseT_Half - | SUPPORTED_1000baseT_Full)) { - ctrl |= BMCR_SPEED1000; - break; - } - mii_info->speed = SPEED_100; - case SPEED_100: - if (features & (SUPPORTED_100baseT_Half - | SUPPORTED_100baseT_Full)) { - ctrl |= BMCR_SPEED100; - break; - } - mii_info->speed = SPEED_10; - case SPEED_10: - if (features & (SUPPORTED_10baseT_Half - | SUPPORTED_10baseT_Full)) - break; - default: /* Unsupported speed! */ - ugphy_err("%s: Bad speed!", mii_info->dev->name); - break; - } - - phy_write(mii_info, MII_BMCR, ctrl); -} - -/* Enable and Restart Autonegotiation */ -static void genmii_restart_aneg(struct ugeth_mii_info *mii_info) -{ - u16 ctl; - - ugphy_vdbg("%s: IN", __FUNCTION__); - - ctl = phy_read(mii_info, MII_BMCR); - ctl |= (BMCR_ANENABLE | BMCR_ANRESTART); - phy_write(mii_info, MII_BMCR, ctl); -} - -static int gbit_config_aneg(struct ugeth_mii_info *mii_info) -{ - u16 adv; - u32 advertise; - - ugphy_vdbg("%s: IN", __FUNCTION__); - - if (mii_info->autoneg) { - /* Configure the ADVERTISE register */ - config_genmii_advert(mii_info); - advertise = mii_info->advertising; - - adv = phy_read(mii_info, MII_1000BASETCONTROL); - adv &= ~(MII_1000BASETCONTROL_FULLDUPLEXCAP | - MII_1000BASETCONTROL_HALFDUPLEXCAP); - if (advertise & SUPPORTED_1000baseT_Half) - adv |= MII_1000BASETCONTROL_HALFDUPLEXCAP; - if (advertise & SUPPORTED_1000baseT_Full) - adv |= MII_1000BASETCONTROL_FULLDUPLEXCAP; - phy_write(mii_info, MII_1000BASETCONTROL, adv); - - /* Start/Restart aneg */ - genmii_restart_aneg(mii_info); - } else - genmii_setup_forced(mii_info); - - return 0; -} - -static int genmii_config_aneg(struct ugeth_mii_info *mii_info) -{ - ugphy_vdbg("%s: IN", __FUNCTION__); - - if (mii_info->autoneg) { - config_genmii_advert(mii_info); - genmii_restart_aneg(mii_info); - } else - genmii_setup_forced(mii_info); - - return 0; -} - -static int genmii_update_link(struct ugeth_mii_info *mii_info) -{ - u16 status; - - ugphy_vdbg("%s: IN", __FUNCTION__); - - /* Do a fake read */ - phy_read(mii_info, MII_BMSR); - - /* Read link and autonegotiation status */ - status = phy_read(mii_info, MII_BMSR); - if ((status & BMSR_LSTATUS) == 0) - mii_info->link = 0; - else - mii_info->link = 1; - - /* If we are autonegotiating, and not done, - * return an error */ - if (mii_info->autoneg && !(status & BMSR_ANEGCOMPLETE)) - return -EAGAIN; - - return 0; -} - -static int genmii_read_status(struct ugeth_mii_info *mii_info) -{ - u16 status; - int err; - - ugphy_vdbg("%s: IN", __FUNCTION__); - - /* Update the link, but return if there - * was an error */ - err = genmii_update_link(mii_info); - if (err) - return err; - - if (mii_info->autoneg) { - status = phy_read(mii_info, MII_LPA); - - if (status & (LPA_10FULL | LPA_100FULL)) - mii_info->duplex = DUPLEX_FULL; - else - mii_info->duplex = DUPLEX_HALF; - if (status & (LPA_100FULL | LPA_100HALF)) - mii_info->speed = SPEED_100; - else - mii_info->speed = SPEED_10; - mii_info->pause = 0; - } - /* On non-aneg, we assume what we put in BMCR is the speed, - * though magic-aneg shouldn't prevent this case from occurring - */ - - return 0; -} - -static int marvell_init(struct ugeth_mii_info *mii_info) -{ - ugphy_vdbg("%s: IN", __FUNCTION__); - - phy_write(mii_info, 0x14, 0x0cd2); - phy_write(mii_info, MII_BMCR, - phy_read(mii_info, MII_BMCR) | BMCR_RESET); - msleep(4000); - - return 0; -} - -static int marvell_config_aneg(struct ugeth_mii_info *mii_info) -{ - ugphy_vdbg("%s: IN", __FUNCTION__); - - /* The Marvell PHY has an errata which requires - * that certain registers get written in order - * to restart autonegotiation */ - phy_write(mii_info, MII_BMCR, BMCR_RESET); - - phy_write(mii_info, 0x1d, 0x1f); - phy_write(mii_info, 0x1e, 0x200c); - phy_write(mii_info, 0x1d, 0x5); - phy_write(mii_info, 0x1e, 0); - phy_write(mii_info, 0x1e, 0x100); - - gbit_config_aneg(mii_info); - - return 0; -} - -static int marvell_read_status(struct ugeth_mii_info *mii_info) -{ - u16 status; - int err; - - ugphy_vdbg("%s: IN", __FUNCTION__); - - /* Update the link, but return if there - * was an error */ - err = genmii_update_link(mii_info); - if (err) - return err; - - /* If the link is up, read the speed and duplex */ - /* If we aren't autonegotiating, assume speeds - * are as set */ - if (mii_info->autoneg && mii_info->link) { - int speed; - status = phy_read(mii_info, MII_M1011_PHY_SPEC_STATUS); - - /* Get the duplexity */ - if (status & MII_M1011_PHY_SPEC_STATUS_FULLDUPLEX) - mii_info->duplex = DUPLEX_FULL; - else - mii_info->duplex = DUPLEX_HALF; - - /* Get the speed */ - speed = status & MII_M1011_PHY_SPEC_STATUS_SPD_MASK; - switch (speed) { - case MII_M1011_PHY_SPEC_STATUS_1000: - mii_info->speed = SPEED_1000; - break; - case MII_M1011_PHY_SPEC_STATUS_100: - mii_info->speed = SPEED_100; - break; - default: - mii_info->speed = SPEED_10; - break; - } - mii_info->pause = 0; - } - - return 0; -} - -static int marvell_ack_interrupt(struct ugeth_mii_info *mii_info) -{ - ugphy_vdbg("%s: IN", __FUNCTION__); - - /* Clear the interrupts by reading the reg */ - phy_read(mii_info, MII_M1011_IEVENT); - - return 0; -} - -static int marvell_config_intr(struct ugeth_mii_info *mii_info) -{ - ugphy_vdbg("%s: IN", __FUNCTION__); - - if (mii_info->interrupts == MII_INTERRUPT_ENABLED) - phy_write(mii_info, MII_M1011_IMASK, MII_M1011_IMASK_INIT); - else - phy_write(mii_info, MII_M1011_IMASK, MII_M1011_IMASK_CLEAR); - - return 0; -} - -static int cis820x_init(struct ugeth_mii_info *mii_info) -{ - ugphy_vdbg("%s: IN", __FUNCTION__); - - phy_write(mii_info, MII_CIS8201_AUX_CONSTAT, - MII_CIS8201_AUXCONSTAT_INIT); - phy_write(mii_info, MII_CIS8201_EXT_CON1, MII_CIS8201_EXTCON1_INIT); - - return 0; -} - -static int cis820x_read_status(struct ugeth_mii_info *mii_info) -{ - u16 status; - int err; - - ugphy_vdbg("%s: IN", __FUNCTION__); - - /* Update the link, but return if there - * was an error */ - err = genmii_update_link(mii_info); - if (err) - return err; - - /* If the link is up, read the speed and duplex */ - /* If we aren't autonegotiating, assume speeds - * are as set */ - if (mii_info->autoneg && mii_info->link) { - int speed; - - status = phy_read(mii_info, MII_CIS8201_AUX_CONSTAT); - if (status & MII_CIS8201_AUXCONSTAT_DUPLEX) - mii_info->duplex = DUPLEX_FULL; - else - mii_info->duplex = DUPLEX_HALF; - - speed = status & MII_CIS8201_AUXCONSTAT_SPEED; - - switch (speed) { - case MII_CIS8201_AUXCONSTAT_GBIT: - mii_info->speed = SPEED_1000; - break; - case MII_CIS8201_AUXCONSTAT_100: - mii_info->speed = SPEED_100; - break; - default: - mii_info->speed = SPEED_10; - break; - } - } - - return 0; -} - -static int cis820x_ack_interrupt(struct ugeth_mii_info *mii_info) -{ - ugphy_vdbg("%s: IN", __FUNCTION__); - - phy_read(mii_info, MII_CIS8201_ISTAT); - - return 0; -} - -static int cis820x_config_intr(struct ugeth_mii_info *mii_info) -{ - ugphy_vdbg("%s: IN", __FUNCTION__); - - if (mii_info->interrupts == MII_INTERRUPT_ENABLED) - phy_write(mii_info, MII_CIS8201_IMASK, MII_CIS8201_IMASK_MASK); - else - phy_write(mii_info, MII_CIS8201_IMASK, 0); - - return 0; -} - -#define DM9161_DELAY 10 - -static int dm9161_read_status(struct ugeth_mii_info *mii_info) -{ - u16 status; - int err; - - ugphy_vdbg("%s: IN", __FUNCTION__); - - /* Update the link, but return if there - * was an error */ - err = genmii_update_link(mii_info); - if (err) - return err; - - /* If the link is up, read the speed and duplex */ - /* If we aren't autonegotiating, assume speeds - * are as set */ - if (mii_info->autoneg && mii_info->link) { - status = phy_read(mii_info, MII_DM9161_SCSR); - if (status & (MII_DM9161_SCSR_100F | MII_DM9161_SCSR_100H)) - mii_info->speed = SPEED_100; - else - mii_info->speed = SPEED_10; - - if (status & (MII_DM9161_SCSR_100F | MII_DM9161_SCSR_10F)) - mii_info->duplex = DUPLEX_FULL; - else - mii_info->duplex = DUPLEX_HALF; - } - - return 0; -} - -static int dm9161_config_aneg(struct ugeth_mii_info *mii_info) -{ - struct dm9161_private *priv = mii_info->priv; - - ugphy_vdbg("%s: IN", __FUNCTION__); - - if (0 == priv->resetdone) - return -EAGAIN; - - return 0; -} - -static void dm9161_timer(unsigned long data) -{ - struct ugeth_mii_info *mii_info = (struct ugeth_mii_info *)data; - struct dm9161_private *priv = mii_info->priv; - u16 status = phy_read(mii_info, MII_BMSR); - - ugphy_vdbg("%s: IN", __FUNCTION__); - - if (status & BMSR_ANEGCOMPLETE) { - priv->resetdone = 1; - } else - mod_timer(&priv->timer, jiffies + DM9161_DELAY * HZ); -} - -static int dm9161_init(struct ugeth_mii_info *mii_info) -{ - struct dm9161_private *priv; - - ugphy_vdbg("%s: IN", __FUNCTION__); - - /* Allocate the private data structure */ - priv = kmalloc(sizeof(struct dm9161_private), GFP_KERNEL); - - if (NULL == priv) - return -ENOMEM; - - mii_info->priv = priv; - - /* Reset is not done yet */ - priv->resetdone = 0; - - phy_write(mii_info, MII_BMCR, - phy_read(mii_info, MII_BMCR) | BMCR_RESET); - - phy_write(mii_info, MII_BMCR, - phy_read(mii_info, MII_BMCR) & ~BMCR_ISOLATE); - - config_genmii_advert(mii_info); - /* Start/Restart aneg */ - genmii_config_aneg(mii_info); - - /* Start a timer for DM9161_DELAY seconds to wait - * for the PHY to be ready */ - init_timer(&priv->timer); - priv->timer.function = &dm9161_timer; - priv->timer.data = (unsigned long)mii_info; - mod_timer(&priv->timer, jiffies + DM9161_DELAY * HZ); - - return 0; -} - -static void dm9161_close(struct ugeth_mii_info *mii_info) -{ - struct dm9161_private *priv = mii_info->priv; - - ugphy_vdbg("%s: IN", __FUNCTION__); - - del_timer_sync(&priv->timer); - kfree(priv); -} - -static int dm9161_ack_interrupt(struct ugeth_mii_info *mii_info) -{ -/* FIXME: This lines are for BUG fixing in the mpc8325. -Remove this from here when it's fixed */ - if (bcsr_regs == NULL) - bcsr_regs = (u8 *) ioremap(BCSR_PHYS_ADDR, BCSR_SIZE); - bcsr_regs[14] |= 0x40; - ugphy_vdbg("%s: IN", __FUNCTION__); - - /* Clear the interrupts by reading the reg */ - phy_read(mii_info, MII_DM9161_INTR); - - - return 0; -} - -static int dm9161_config_intr(struct ugeth_mii_info *mii_info) -{ -/* FIXME: This lines are for BUG fixing in the mpc8325. -Remove this from here when it's fixed */ - if (bcsr_regs == NULL) { - bcsr_regs = (u8 *) ioremap(BCSR_PHYS_ADDR, BCSR_SIZE); - bcsr_regs[14] &= ~0x40; - } - ugphy_vdbg("%s: IN", __FUNCTION__); - - if (mii_info->interrupts == MII_INTERRUPT_ENABLED) - phy_write(mii_info, MII_DM9161_INTR, MII_DM9161_INTR_INIT); - else - phy_write(mii_info, MII_DM9161_INTR, MII_DM9161_INTR_STOP); - - return 0; -} - -/* Cicada 820x */ -static struct phy_info phy_info_cis820x = { - .phy_id = 0x000fc440, - .name = "Cicada Cis8204", - .phy_id_mask = 0x000fffc0, - .features = MII_GBIT_FEATURES, - .init = &cis820x_init, - .config_aneg = &gbit_config_aneg, - .read_status = &cis820x_read_status, - .ack_interrupt = &cis820x_ack_interrupt, - .config_intr = &cis820x_config_intr, -}; - -static struct phy_info phy_info_dm9161 = { - .phy_id = 0x0181b880, - .phy_id_mask = 0x0ffffff0, - .name = "Davicom DM9161E", - .init = dm9161_init, - .config_aneg = dm9161_config_aneg, - .read_status = dm9161_read_status, - .close = dm9161_close, -}; - -static struct phy_info phy_info_dm9161a = { - .phy_id = 0x0181b8a0, - .phy_id_mask = 0x0ffffff0, - .name = "Davicom DM9161A", - .features = MII_BASIC_FEATURES, - .init = dm9161_init, - .config_aneg = dm9161_config_aneg, - .read_status = dm9161_read_status, - .ack_interrupt = dm9161_ack_interrupt, - .config_intr = dm9161_config_intr, - .close = dm9161_close, -}; - -static struct phy_info phy_info_marvell = { - .phy_id = 0x01410c00, - .phy_id_mask = 0xffffff00, - .name = "Marvell 88E11x1", - .features = MII_GBIT_FEATURES, - .init = &marvell_init, - .config_aneg = &marvell_config_aneg, - .read_status = &marvell_read_status, - .ack_interrupt = &marvell_ack_interrupt, - .config_intr = &marvell_config_intr, -}; - -static struct phy_info phy_info_genmii = { - .phy_id = 0x00000000, - .phy_id_mask = 0x00000000, - .name = "Generic MII", - .features = MII_BASIC_FEATURES, - .config_aneg = genmii_config_aneg, - .read_status = genmii_read_status, -}; - -static struct phy_info *phy_info[] = { - &phy_info_cis820x, - &phy_info_marvell, - &phy_info_dm9161, - &phy_info_dm9161a, - &phy_info_genmii, - NULL -}; - -u16 phy_read(struct ugeth_mii_info *mii_info, u16 regnum) -{ - u16 retval; - unsigned long flags; - - ugphy_vdbg("%s: IN", __FUNCTION__); - - spin_lock_irqsave(&mii_info->mdio_lock, flags); - retval = mii_info->mdio_read(mii_info->dev, mii_info->mii_id, regnum); - spin_unlock_irqrestore(&mii_info->mdio_lock, flags); - - return retval; -} - -void phy_write(struct ugeth_mii_info *mii_info, u16 regnum, u16 val) -{ - unsigned long flags; - - ugphy_vdbg("%s: IN", __FUNCTION__); - - spin_lock_irqsave(&mii_info->mdio_lock, flags); - mii_info->mdio_write(mii_info->dev, mii_info->mii_id, regnum, val); - spin_unlock_irqrestore(&mii_info->mdio_lock, flags); -} - -/* Use the PHY ID registers to determine what type of PHY is attached - * to device dev. return a struct phy_info structure describing that PHY - */ -struct phy_info *get_phy_info(struct ugeth_mii_info *mii_info) -{ - u16 phy_reg; - u32 phy_ID; - int i; - struct phy_info *theInfo = NULL; - struct net_device *dev = mii_info->dev; - - ugphy_vdbg("%s: IN", __FUNCTION__); - - /* Grab the bits from PHYIR1, and put them in the upper half */ - phy_reg = phy_read(mii_info, MII_PHYSID1); - phy_ID = (phy_reg & 0xffff) << 16; - - /* Grab the bits from PHYIR2, and put them in the lower half */ - phy_reg = phy_read(mii_info, MII_PHYSID2); - phy_ID |= (phy_reg & 0xffff); - - /* loop through all the known PHY types, and find one that */ - /* matches the ID we read from the PHY. */ - for (i = 0; phy_info[i]; i++) - if (phy_info[i]->phy_id == (phy_ID & phy_info[i]->phy_id_mask)){ - theInfo = phy_info[i]; - break; - } - - /* This shouldn't happen, as we have generic PHY support */ - if (theInfo == NULL) { - ugphy_info("%s: PHY id %x is not supported!", dev->name, - phy_ID); - return NULL; - } else { - ugphy_info("%s: PHY is %s (%x)", dev->name, theInfo->name, - phy_ID); - } - - return theInfo; -} diff --git a/trunk/drivers/net/ucc_geth_phy.h b/trunk/drivers/net/ucc_geth_phy.h deleted file mode 100644 index 2f98b8f1bb0a..000000000000 --- a/trunk/drivers/net/ucc_geth_phy.h +++ /dev/null @@ -1,217 +0,0 @@ -/* - * Copyright (C) Freescale Semicondutor, Inc. 2006. All rights reserved. - * - * Author: Shlomi Gridish - * - * Description: - * UCC GETH Driver -- PHY handling - * - * Changelog: - * Jun 28, 2006 Li Yang - * - Rearrange code and style fixes - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - */ -#ifndef __UCC_GETH_PHY_H__ -#define __UCC_GETH_PHY_H__ - -#define MII_end ((u32)-2) -#define MII_read ((u32)-1) - -#define MIIMIND_BUSY 0x00000001 -#define MIIMIND_NOTVALID 0x00000004 - -#define UGETH_AN_TIMEOUT 2000 - -/* 1000BT control (Marvell & BCM54xx at least) */ -#define MII_1000BASETCONTROL 0x09 -#define MII_1000BASETCONTROL_FULLDUPLEXCAP 0x0200 -#define MII_1000BASETCONTROL_HALFDUPLEXCAP 0x0100 - -/* Cicada Extended Control Register 1 */ -#define MII_CIS8201_EXT_CON1 0x17 -#define MII_CIS8201_EXTCON1_INIT 0x0000 - -/* Cicada Interrupt Mask Register */ -#define MII_CIS8201_IMASK 0x19 -#define MII_CIS8201_IMASK_IEN 0x8000 -#define MII_CIS8201_IMASK_SPEED 0x4000 -#define MII_CIS8201_IMASK_LINK 0x2000 -#define MII_CIS8201_IMASK_DUPLEX 0x1000 -#define MII_CIS8201_IMASK_MASK 0xf000 - -/* Cicada Interrupt Status Register */ -#define MII_CIS8201_ISTAT 0x1a -#define MII_CIS8201_ISTAT_STATUS 0x8000 -#define MII_CIS8201_ISTAT_SPEED 0x4000 -#define MII_CIS8201_ISTAT_LINK 0x2000 -#define MII_CIS8201_ISTAT_DUPLEX 0x1000 - -/* Cicada Auxiliary Control/Status Register */ -#define MII_CIS8201_AUX_CONSTAT 0x1c -#define MII_CIS8201_AUXCONSTAT_INIT 0x0004 -#define MII_CIS8201_AUXCONSTAT_DUPLEX 0x0020 -#define MII_CIS8201_AUXCONSTAT_SPEED 0x0018 -#define MII_CIS8201_AUXCONSTAT_GBIT 0x0010 -#define MII_CIS8201_AUXCONSTAT_100 0x0008 - -/* 88E1011 PHY Status Register */ -#define MII_M1011_PHY_SPEC_STATUS 0x11 -#define MII_M1011_PHY_SPEC_STATUS_1000 0x8000 -#define MII_M1011_PHY_SPEC_STATUS_100 0x4000 -#define MII_M1011_PHY_SPEC_STATUS_SPD_MASK 0xc000 -#define MII_M1011_PHY_SPEC_STATUS_FULLDUPLEX 0x2000 -#define MII_M1011_PHY_SPEC_STATUS_RESOLVED 0x0800 -#define MII_M1011_PHY_SPEC_STATUS_LINK 0x0400 - -#define MII_M1011_IEVENT 0x13 -#define MII_M1011_IEVENT_CLEAR 0x0000 - -#define MII_M1011_IMASK 0x12 -#define MII_M1011_IMASK_INIT 0x6400 -#define MII_M1011_IMASK_CLEAR 0x0000 - -#define MII_DM9161_SCR 0x10 -#define MII_DM9161_SCR_INIT 0x0610 - -/* DM9161 Specified Configuration and Status Register */ -#define MII_DM9161_SCSR 0x11 -#define MII_DM9161_SCSR_100F 0x8000 -#define MII_DM9161_SCSR_100H 0x4000 -#define MII_DM9161_SCSR_10F 0x2000 -#define MII_DM9161_SCSR_10H 0x1000 - -/* DM9161 Interrupt Register */ -#define MII_DM9161_INTR 0x15 -#define MII_DM9161_INTR_PEND 0x8000 -#define MII_DM9161_INTR_DPLX_MASK 0x0800 -#define MII_DM9161_INTR_SPD_MASK 0x0400 -#define MII_DM9161_INTR_LINK_MASK 0x0200 -#define MII_DM9161_INTR_MASK 0x0100 -#define MII_DM9161_INTR_DPLX_CHANGE 0x0010 -#define MII_DM9161_INTR_SPD_CHANGE 0x0008 -#define MII_DM9161_INTR_LINK_CHANGE 0x0004 -#define MII_DM9161_INTR_INIT 0x0000 -#define MII_DM9161_INTR_STOP \ -(MII_DM9161_INTR_DPLX_MASK | MII_DM9161_INTR_SPD_MASK \ - | MII_DM9161_INTR_LINK_MASK | MII_DM9161_INTR_MASK) - -/* DM9161 10BT Configuration/Status */ -#define MII_DM9161_10BTCSR 0x12 -#define MII_DM9161_10BTCSR_INIT 0x7800 - -#define MII_BASIC_FEATURES (SUPPORTED_10baseT_Half | \ - SUPPORTED_10baseT_Full | \ - SUPPORTED_100baseT_Half | \ - SUPPORTED_100baseT_Full | \ - SUPPORTED_Autoneg | \ - SUPPORTED_TP | \ - SUPPORTED_MII) - -#define MII_GBIT_FEATURES (MII_BASIC_FEATURES | \ - SUPPORTED_1000baseT_Half | \ - SUPPORTED_1000baseT_Full) - -#define MII_READ_COMMAND 0x00000001 - -#define MII_INTERRUPT_DISABLED 0x0 -#define MII_INTERRUPT_ENABLED 0x1 -/* Taken from mii_if_info and sungem_phy.h */ -struct ugeth_mii_info { - /* Information about the PHY type */ - /* And management functions */ - struct phy_info *phyinfo; - - ucc_mii_mng_t *mii_regs; - - /* forced speed & duplex (no autoneg) - * partner speed & duplex & pause (autoneg) - */ - int speed; - int duplex; - int pause; - - /* The most recently read link state */ - int link; - - /* Enabled Interrupts */ - u32 interrupts; - - u32 advertising; - int autoneg; - int mii_id; - - /* private data pointer */ - /* For use by PHYs to maintain extra state */ - void *priv; - - /* Provided by host chip */ - struct net_device *dev; - - /* A lock to ensure that only one thing can read/write - * the MDIO bus at a time */ - spinlock_t mdio_lock; - - /* Provided by ethernet driver */ - int (*mdio_read) (struct net_device * dev, int mii_id, int reg); - void (*mdio_write) (struct net_device * dev, int mii_id, int reg, - int val); -}; - -/* struct phy_info: a structure which defines attributes for a PHY - * - * id will contain a number which represents the PHY. During - * startup, the driver will poll the PHY to find out what its - * UID--as defined by registers 2 and 3--is. The 32-bit result - * gotten from the PHY will be ANDed with phy_id_mask to - * discard any bits which may change based on revision numbers - * unimportant to functionality - * - * There are 6 commands which take a ugeth_mii_info structure. - * Each PHY must declare config_aneg, and read_status. - */ -struct phy_info { - u32 phy_id; - char *name; - unsigned int phy_id_mask; - u32 features; - - /* Called to initialize the PHY */ - int (*init) (struct ugeth_mii_info * mii_info); - - /* Called to suspend the PHY for power */ - int (*suspend) (struct ugeth_mii_info * mii_info); - - /* Reconfigures autonegotiation (or disables it) */ - int (*config_aneg) (struct ugeth_mii_info * mii_info); - - /* Determines the negotiated speed and duplex */ - int (*read_status) (struct ugeth_mii_info * mii_info); - - /* Clears any pending interrupts */ - int (*ack_interrupt) (struct ugeth_mii_info * mii_info); - - /* Enables or disables interrupts */ - int (*config_intr) (struct ugeth_mii_info * mii_info); - - /* Clears up any memory if needed */ - void (*close) (struct ugeth_mii_info * mii_info); -}; - -struct phy_info *get_phy_info(struct ugeth_mii_info *mii_info); -void write_phy_reg(struct net_device *dev, int mii_id, int regnum, int value); -int read_phy_reg(struct net_device *dev, int mii_id, int regnum); -void mii_clear_phy_interrupt(struct ugeth_mii_info *mii_info); -void mii_configure_phy_interrupt(struct ugeth_mii_info *mii_info, - u32 interrupts); - -struct dm9161_private { - struct timer_list timer; - int resetdone; -}; - -#endif /* __UCC_GETH_PHY_H__ */ diff --git a/trunk/drivers/net/via-rhine.c b/trunk/drivers/net/via-rhine.c index efeb10b9c61b..d3d0ec970318 100644 --- a/trunk/drivers/net/via-rhine.c +++ b/trunk/drivers/net/via-rhine.c @@ -30,8 +30,8 @@ */ #define DRV_NAME "via-rhine" -#define DRV_VERSION "1.4.1" -#define DRV_RELDATE "July-24-2006" +#define DRV_VERSION "1.4.0" +#define DRV_RELDATE "June-27-2006" /* A few user-configurable values. @@ -44,10 +44,6 @@ static int max_interrupt_work = 20; Setting to > 1518 effectively disables this feature. */ static int rx_copybreak; -/* Work-around for broken BIOSes: they are unable to get the chip back out of - power state D3 so PXE booting fails. bootparam(7): via-rhine.avoid_D3=1 */ -static int avoid_D3; - /* * In case you are looking for 'options[]' or 'full_duplex[]', they * are gone. Use ethtool(8) instead. @@ -67,11 +63,7 @@ static const int multicast_filter_limit = 32; There are no ill effects from too-large receive rings. */ #define TX_RING_SIZE 16 #define TX_QUEUE_LEN 10 /* Limit ring entries actually used. */ -#ifdef CONFIG_VIA_RHINE_NAPI -#define RX_RING_SIZE 64 -#else #define RX_RING_SIZE 16 -#endif /* Operational parameters that usually are not changed. */ @@ -124,11 +116,9 @@ MODULE_LICENSE("GPL"); module_param(max_interrupt_work, int, 0); module_param(debug, int, 0); module_param(rx_copybreak, int, 0); -module_param(avoid_D3, bool, 0); MODULE_PARM_DESC(max_interrupt_work, "VIA Rhine maximum events handled per interrupt"); MODULE_PARM_DESC(debug, "VIA Rhine debug level (0-7)"); MODULE_PARM_DESC(rx_copybreak, "VIA Rhine copy breakpoint for copy-only-tiny-frames"); -MODULE_PARM_DESC(avoid_D3, "Avoid power state D3 (work-around for broken BIOSes)"); /* Theory of Operation @@ -406,7 +396,7 @@ static void rhine_tx_timeout(struct net_device *dev); static int rhine_start_tx(struct sk_buff *skb, struct net_device *dev); static irqreturn_t rhine_interrupt(int irq, void *dev_instance, struct pt_regs *regs); static void rhine_tx(struct net_device *dev); -static int rhine_rx(struct net_device *dev, int limit); +static void rhine_rx(struct net_device *dev); static void rhine_error(struct net_device *dev, int intr_status); static void rhine_set_rx_mode(struct net_device *dev); static struct net_device_stats *rhine_get_stats(struct net_device *dev); @@ -574,32 +564,6 @@ static void rhine_poll(struct net_device *dev) } #endif -#ifdef CONFIG_VIA_RHINE_NAPI -static int rhine_napipoll(struct net_device *dev, int *budget) -{ - struct rhine_private *rp = netdev_priv(dev); - void __iomem *ioaddr = rp->base; - int done, limit = min(dev->quota, *budget); - - done = rhine_rx(dev, limit); - *budget -= done; - dev->quota -= done; - - if (done < limit) { - netif_rx_complete(dev); - - iowrite16(IntrRxDone | IntrRxErr | IntrRxEmpty| IntrRxOverflow | - IntrRxDropped | IntrRxNoBuf | IntrTxAborted | - IntrTxDone | IntrTxError | IntrTxUnderrun | - IntrPCIErr | IntrStatsMax | IntrLinkChange, - ioaddr + IntrEnable); - return 0; - } - else - return 1; -} -#endif - static void rhine_hw_init(struct net_device *dev, long pioaddr) { struct rhine_private *rp = netdev_priv(dev); @@ -779,10 +743,6 @@ static int __devinit rhine_init_one(struct pci_dev *pdev, dev->watchdog_timeo = TX_TIMEOUT; #ifdef CONFIG_NET_POLL_CONTROLLER dev->poll_controller = rhine_poll; -#endif -#ifdef CONFIG_VIA_RHINE_NAPI - dev->poll = rhine_napipoll; - dev->weight = 64; #endif if (rp->quirks & rqRhineI) dev->features |= NETIF_F_SG|NETIF_F_HW_CSUM; @@ -829,9 +789,6 @@ static int __devinit rhine_init_one(struct pci_dev *pdev, } } rp->mii_if.phy_id = phy_id; - if (debug > 1 && avoid_D3) - printk(KERN_INFO "%s: No D3 power state at shutdown.\n", - dev->name); return 0; @@ -1057,8 +1014,6 @@ static void init_registers(struct net_device *dev) rhine_set_rx_mode(dev); - netif_poll_enable(dev); - /* Enable interrupts by setting the interrupt mask. */ iowrite16(IntrRxDone | IntrRxErr | IntrRxEmpty| IntrRxOverflow | IntrRxDropped | IntrRxNoBuf | IntrTxAborted | @@ -1313,18 +1268,8 @@ static irqreturn_t rhine_interrupt(int irq, void *dev_instance, struct pt_regs * dev->name, intr_status); if (intr_status & (IntrRxDone | IntrRxErr | IntrRxDropped | - IntrRxWakeUp | IntrRxEmpty | IntrRxNoBuf)) { -#ifdef CONFIG_VIA_RHINE_NAPI - iowrite16(IntrTxAborted | - IntrTxDone | IntrTxError | IntrTxUnderrun | - IntrPCIErr | IntrStatsMax | IntrLinkChange, - ioaddr + IntrEnable); - - netif_rx_schedule(dev); -#else - rhine_rx(dev, RX_RING_SIZE); -#endif - } + IntrRxWakeUp | IntrRxEmpty | IntrRxNoBuf)) + rhine_rx(dev); if (intr_status & (IntrTxErrSummary | IntrTxDone)) { if (intr_status & IntrTxErrSummary) { @@ -1422,12 +1367,13 @@ static void rhine_tx(struct net_device *dev) spin_unlock(&rp->lock); } -/* Process up to limit frames from receive ring */ -static int rhine_rx(struct net_device *dev, int limit) +/* This routine is logically part of the interrupt handler, but isolated + for clarity and better register allocation. */ +static void rhine_rx(struct net_device *dev) { struct rhine_private *rp = netdev_priv(dev); - int count; int entry = rp->cur_rx % RX_RING_SIZE; + int boguscnt = rp->dirty_rx + RX_RING_SIZE - rp->cur_rx; if (debug > 4) { printk(KERN_DEBUG "%s: rhine_rx(), entry %d status %8.8x.\n", @@ -1436,18 +1382,16 @@ static int rhine_rx(struct net_device *dev, int limit) } /* If EOP is set on the next entry, it's a new packet. Send it up. */ - for (count = 0; count < limit; ++count) { + while (!(rp->rx_head_desc->rx_status & cpu_to_le32(DescOwn))) { struct rx_desc *desc = rp->rx_head_desc; u32 desc_status = le32_to_cpu(desc->rx_status); int data_size = desc_status >> 16; - if (desc_status & DescOwn) - break; - if (debug > 4) printk(KERN_DEBUG "rhine_rx() status is %8.8x.\n", desc_status); - + if (--boguscnt < 0) + break; if ((desc_status & (RxWholePkt | RxErr)) != RxWholePkt) { if ((desc_status & RxWholePkt) != RxWholePkt) { printk(KERN_WARNING "%s: Oversized Ethernet " @@ -1516,11 +1460,7 @@ static int rhine_rx(struct net_device *dev, int limit) PCI_DMA_FROMDEVICE); } skb->protocol = eth_type_trans(skb, dev); -#ifdef CONFIG_VIA_RHINE_NAPI - netif_receive_skb(skb); -#else netif_rx(skb); -#endif dev->last_rx = jiffies; rp->stats.rx_bytes += pkt_len; rp->stats.rx_packets++; @@ -1547,8 +1487,6 @@ static int rhine_rx(struct net_device *dev, int limit) } rp->rx_ring[entry].rx_status = cpu_to_le32(DescOwn); } - - return count; } /* @@ -1838,7 +1776,6 @@ static int rhine_close(struct net_device *dev) spin_lock_irq(&rp->lock); netif_stop_queue(dev); - netif_poll_disable(dev); if (debug > 1) printk(KERN_DEBUG "%s: Shutting down ethercard, " @@ -1920,8 +1857,7 @@ static void rhine_shutdown (struct pci_dev *pdev) } /* Hit power state D3 (sleep) */ - if (!avoid_D3) - iowrite8(ioread8(ioaddr + StickyHW) | 0x03, ioaddr + StickyHW); + iowrite8(ioread8(ioaddr + StickyHW) | 0x03, ioaddr + StickyHW); /* TODO: Check use of pci_enable_wake() */ @@ -2005,7 +1941,7 @@ static int __init rhine_init(void) #ifdef MODULE printk(version); #endif - return pci_register_driver(&rhine_driver); + return pci_module_init(&rhine_driver); } diff --git a/trunk/drivers/net/via-velocity.c b/trunk/drivers/net/via-velocity.c index e266db1518e7..aa9cd92f46b2 100644 --- a/trunk/drivers/net/via-velocity.c +++ b/trunk/drivers/net/via-velocity.c @@ -2250,7 +2250,7 @@ static int __init velocity_init_module(void) int ret; velocity_register_notifier(); - ret = pci_register_driver(&velocity_driver); + ret = pci_module_init(&velocity_driver); if (ret < 0) velocity_unregister_notifier(); return ret; diff --git a/trunk/drivers/net/via-velocity.h b/trunk/drivers/net/via-velocity.h index 4665ef2c63df..496c3d597444 100644 --- a/trunk/drivers/net/via-velocity.h +++ b/trunk/drivers/net/via-velocity.h @@ -262,6 +262,25 @@ struct velocity_rd_info { dma_addr_t skb_dma; }; +/** + * alloc_rd_info - allocate an rd info block + * + * Alocate and initialize a receive info structure used for keeping + * track of kernel side information related to each receive + * descriptor we are using + */ + +static inline struct velocity_rd_info *alloc_rd_info(void) +{ + struct velocity_rd_info *ptr; + if ((ptr = kmalloc(sizeof(struct velocity_rd_info), GFP_ATOMIC)) == NULL) + return NULL; + else { + memset(ptr, 0, sizeof(struct velocity_rd_info)); + return ptr; + } +} + /* * Used to track transmit side buffers. */ diff --git a/trunk/drivers/net/wan/c101.c b/trunk/drivers/net/wan/c101.c index 6b63b350cd52..435e91ec4620 100644 --- a/trunk/drivers/net/wan/c101.c +++ b/trunk/drivers/net/wan/c101.c @@ -118,7 +118,7 @@ static inline void openwin(card_t *card, u8 page) static inline void set_carrier(port_t *port) { - if (!(sca_in(MSCI1_OFFSET + ST3, port) & ST3_DCD)) + if (!sca_in(MSCI1_OFFSET + ST3, port) & ST3_DCD) netif_carrier_on(port_to_dev(port)); else netif_carrier_off(port_to_dev(port)); @@ -127,10 +127,10 @@ static inline void set_carrier(port_t *port) static void sca_msci_intr(port_t *port) { - u8 stat = sca_in(MSCI0_OFFSET + ST1, port); /* read MSCI ST1 status */ + u8 stat = sca_in(MSCI1_OFFSET + ST1, port); /* read MSCI ST1 status */ - /* Reset MSCI TX underrun and CDCD (ignored) status bit */ - sca_out(stat & (ST1_UDRN | ST1_CDCD), MSCI0_OFFSET + ST1, port); + /* Reset MSCI TX underrun status bit */ + sca_out(stat & ST1_UDRN, MSCI0_OFFSET + ST1, port); if (stat & ST1_UDRN) { struct net_device_stats *stats = hdlc_stats(port_to_dev(port)); @@ -138,7 +138,6 @@ static void sca_msci_intr(port_t *port) stats->tx_fifo_errors++; } - stat = sca_in(MSCI1_OFFSET + ST1, port); /* read MSCI1 ST1 status */ /* Reset MSCI CDCD status bit - uses ch#2 DCD input */ sca_out(stat & ST1_CDCD, MSCI1_OFFSET + ST1, port); diff --git a/trunk/drivers/net/wan/cycx_main.c b/trunk/drivers/net/wan/cycx_main.c index a5e7ce1bd16a..430b1f630fb4 100644 --- a/trunk/drivers/net/wan/cycx_main.c +++ b/trunk/drivers/net/wan/cycx_main.c @@ -40,6 +40,7 @@ * 1998/08/08 acme Initial version. */ +#include /* OS configuration options */ #include /* offsetof(), etc. */ #include /* return codes */ #include /* inline memset(), etc. */ diff --git a/trunk/drivers/net/wan/dlci.c b/trunk/drivers/net/wan/dlci.c index 736987559432..6e1ec5bf22fc 100644 --- a/trunk/drivers/net/wan/dlci.c +++ b/trunk/drivers/net/wan/dlci.c @@ -28,6 +28,7 @@ * 2 of the License, or (at your option) any later version. */ +#include /* for CONFIG_DLCI_COUNT */ #include #include #include diff --git a/trunk/drivers/net/wan/dscc4.c b/trunk/drivers/net/wan/dscc4.c index af4d4155905b..684af4316ffd 100644 --- a/trunk/drivers/net/wan/dscc4.c +++ b/trunk/drivers/net/wan/dscc4.c @@ -2062,7 +2062,7 @@ static struct pci_driver dscc4_driver = { static int __init dscc4_init_module(void) { - return pci_register_driver(&dscc4_driver); + return pci_module_init(&dscc4_driver); } static void __exit dscc4_cleanup_module(void) diff --git a/trunk/drivers/net/wan/farsync.c b/trunk/drivers/net/wan/farsync.c index 564351aafa41..3705db04a343 100644 --- a/trunk/drivers/net/wan/farsync.c +++ b/trunk/drivers/net/wan/farsync.c @@ -2697,7 +2697,7 @@ fst_init(void) for (i = 0; i < FST_MAX_CARDS; i++) fst_card_array[i] = NULL; spin_lock_init(&fst_work_q_lock); - return pci_register_driver(&fst_driver); + return pci_module_init(&fst_driver); } static void __exit diff --git a/trunk/drivers/net/wan/lmc/lmc_main.c b/trunk/drivers/net/wan/lmc/lmc_main.c index 7b5d81deb028..39f44241a728 100644 --- a/trunk/drivers/net/wan/lmc/lmc_main.c +++ b/trunk/drivers/net/wan/lmc/lmc_main.c @@ -1790,7 +1790,7 @@ static struct pci_driver lmc_driver = { static int __init init_lmc(void) { - return pci_register_driver(&lmc_driver); + return pci_module_init(&lmc_driver); } static void __exit exit_lmc(void) diff --git a/trunk/drivers/net/wan/pc300_drv.c b/trunk/drivers/net/wan/pc300_drv.c index 56e69403d178..567effff4a3e 100644 --- a/trunk/drivers/net/wan/pc300_drv.c +++ b/trunk/drivers/net/wan/pc300_drv.c @@ -3677,7 +3677,7 @@ static struct pci_driver cpc_driver = { static int __init cpc_init(void) { - return pci_register_driver(&cpc_driver); + return pci_module_init(&cpc_driver); } static void __exit cpc_cleanup_module(void) diff --git a/trunk/drivers/net/wan/pci200syn.c b/trunk/drivers/net/wan/pci200syn.c index a6b9c33b68e4..4df61fa3214b 100644 --- a/trunk/drivers/net/wan/pci200syn.c +++ b/trunk/drivers/net/wan/pci200syn.c @@ -476,7 +476,7 @@ static int __init pci200_init_module(void) printk(KERN_ERR "pci200syn: Invalid PCI clock frequency\n"); return -EINVAL; } - return pci_register_driver(&pci200_pci_driver); + return pci_module_init(&pci200_pci_driver); } diff --git a/trunk/drivers/net/wan/sdla.c b/trunk/drivers/net/wan/sdla.c index 0ba018f8382b..7628c2d81f45 100644 --- a/trunk/drivers/net/wan/sdla.c +++ b/trunk/drivers/net/wan/sdla.c @@ -32,6 +32,7 @@ * 2 of the License, or (at your option) any later version. */ +#include /* for CONFIG_DLCI_MAX */ #include #include #include diff --git a/trunk/drivers/net/wan/wanxl.c b/trunk/drivers/net/wan/wanxl.c index ec68f7dfd93f..b2031dfc4bb1 100644 --- a/trunk/drivers/net/wan/wanxl.c +++ b/trunk/drivers/net/wan/wanxl.c @@ -837,7 +837,7 @@ static int __init wanxl_init_module(void) #ifdef MODULE printk(KERN_INFO "%s\n", version); #endif - return pci_register_driver(&wanxl_pci_driver); + return pci_module_init(&wanxl_pci_driver); } static void __exit wanxl_cleanup_module(void) diff --git a/trunk/drivers/net/wd.c b/trunk/drivers/net/wd.c index b1ba1872f315..7caa8dc88a58 100644 --- a/trunk/drivers/net/wd.c +++ b/trunk/drivers/net/wd.c @@ -500,8 +500,8 @@ MODULE_LICENSE("GPL"); /* This is set up so that only a single autoprobe takes place per call. ISA device autoprobes on a running machine are not recommended. */ - -int __init init_module(void) +int +init_module(void) { struct net_device *dev; int this_dev, found = 0; diff --git a/trunk/drivers/net/wireless/atmel_pci.c b/trunk/drivers/net/wireless/atmel_pci.c index 3bfa791c323d..d425c3cefded 100644 --- a/trunk/drivers/net/wireless/atmel_pci.c +++ b/trunk/drivers/net/wireless/atmel_pci.c @@ -76,7 +76,7 @@ static void __devexit atmel_pci_remove(struct pci_dev *pdev) static int __init atmel_init_module(void) { - return pci_register_driver(&atmel_driver); + return pci_module_init(&atmel_driver); } static void __exit atmel_cleanup_module(void) diff --git a/trunk/drivers/net/wireless/hostap/hostap_hw.c b/trunk/drivers/net/wireless/hostap/hostap_hw.c index d500012fdc7a..dafaa5ff5aa6 100644 --- a/trunk/drivers/net/wireless/hostap/hostap_hw.c +++ b/trunk/drivers/net/wireless/hostap/hostap_hw.c @@ -1042,9 +1042,6 @@ static int prism2_reset_port(struct net_device *dev) dev->name, local->fragm_threshold); } - /* Some firmwares lose antenna selection settings on reset */ - (void) hostap_set_antsel(local); - return res; } diff --git a/trunk/drivers/net/wireless/ipw2100.c b/trunk/drivers/net/wireless/ipw2100.c index 5f8ccf48061a..e955db435b30 100644 --- a/trunk/drivers/net/wireless/ipw2100.c +++ b/trunk/drivers/net/wireless/ipw2100.c @@ -6531,7 +6531,7 @@ static int __init ipw2100_init(void) printk(KERN_INFO DRV_NAME ": %s, %s\n", DRV_DESCRIPTION, DRV_VERSION); printk(KERN_INFO DRV_NAME ": %s\n", DRV_COPYRIGHT); - ret = pci_register_driver(&ipw2100_pci_driver); + ret = pci_module_init(&ipw2100_pci_driver); #ifdef CONFIG_IPW2100_DEBUG ipw2100_debug_level = debug; diff --git a/trunk/drivers/net/wireless/ipw2200.c b/trunk/drivers/net/wireless/ipw2200.c index a72f3e1e991b..758459e72f3d 100644 --- a/trunk/drivers/net/wireless/ipw2200.c +++ b/trunk/drivers/net/wireless/ipw2200.c @@ -11753,7 +11753,7 @@ static int __init ipw_init(void) printk(KERN_INFO DRV_NAME ": " DRV_DESCRIPTION ", " DRV_VERSION "\n"); printk(KERN_INFO DRV_NAME ": " DRV_COPYRIGHT "\n"); - ret = pci_register_driver(&ipw_driver); + ret = pci_module_init(&ipw_driver); if (ret) { IPW_ERROR("Unable to initialize PCI module\n"); return ret; diff --git a/trunk/drivers/net/wireless/orinoco_nortel.c b/trunk/drivers/net/wireless/orinoco_nortel.c index eaf3d13b851c..bf05b907747e 100644 --- a/trunk/drivers/net/wireless/orinoco_nortel.c +++ b/trunk/drivers/net/wireless/orinoco_nortel.c @@ -304,7 +304,7 @@ MODULE_LICENSE("Dual MPL/GPL"); static int __init orinoco_nortel_init(void) { printk(KERN_DEBUG "%s\n", version); - return pci_register_driver(&orinoco_nortel_driver); + return pci_module_init(&orinoco_nortel_driver); } static void __exit orinoco_nortel_exit(void) diff --git a/trunk/drivers/net/wireless/orinoco_pci.c b/trunk/drivers/net/wireless/orinoco_pci.c index 97a8b4ff32bd..1759c543fbee 100644 --- a/trunk/drivers/net/wireless/orinoco_pci.c +++ b/trunk/drivers/net/wireless/orinoco_pci.c @@ -244,7 +244,7 @@ MODULE_LICENSE("Dual MPL/GPL"); static int __init orinoco_pci_init(void) { printk(KERN_DEBUG "%s\n", version); - return pci_register_driver(&orinoco_pci_driver); + return pci_module_init(&orinoco_pci_driver); } static void __exit orinoco_pci_exit(void) diff --git a/trunk/drivers/net/wireless/orinoco_plx.c b/trunk/drivers/net/wireless/orinoco_plx.c index 31162ac25a92..7f006f624171 100644 --- a/trunk/drivers/net/wireless/orinoco_plx.c +++ b/trunk/drivers/net/wireless/orinoco_plx.c @@ -351,7 +351,7 @@ MODULE_LICENSE("Dual MPL/GPL"); static int __init orinoco_plx_init(void) { printk(KERN_DEBUG "%s\n", version); - return pci_register_driver(&orinoco_plx_driver); + return pci_module_init(&orinoco_plx_driver); } static void __exit orinoco_plx_exit(void) diff --git a/trunk/drivers/net/wireless/orinoco_tmd.c b/trunk/drivers/net/wireless/orinoco_tmd.c index 7c7b960c91df..0831721e4d6c 100644 --- a/trunk/drivers/net/wireless/orinoco_tmd.c +++ b/trunk/drivers/net/wireless/orinoco_tmd.c @@ -228,7 +228,7 @@ MODULE_LICENSE("Dual MPL/GPL"); static int __init orinoco_tmd_init(void) { printk(KERN_DEBUG "%s\n", version); - return pci_register_driver(&orinoco_tmd_driver); + return pci_module_init(&orinoco_tmd_driver); } static void __exit orinoco_tmd_exit(void) diff --git a/trunk/drivers/net/wireless/prism54/islpci_hotplug.c b/trunk/drivers/net/wireless/prism54/islpci_hotplug.c index f692dccf0d07..09fc17a0f029 100644 --- a/trunk/drivers/net/wireless/prism54/islpci_hotplug.c +++ b/trunk/drivers/net/wireless/prism54/islpci_hotplug.c @@ -313,7 +313,7 @@ prism54_module_init(void) __bug_on_wrong_struct_sizes (); - return pci_register_driver(&prism54_driver); + return pci_module_init(&prism54_driver); } /* by the time prism54_module_exit() terminates, as a postcondition diff --git a/trunk/drivers/net/wireless/spectrum_cs.c b/trunk/drivers/net/wireless/spectrum_cs.c index bcc7038130f6..7f78b7801fb3 100644 --- a/trunk/drivers/net/wireless/spectrum_cs.c +++ b/trunk/drivers/net/wireless/spectrum_cs.c @@ -242,7 +242,7 @@ spectrum_reset(struct pcmcia_device *link, int idle) u_int save_cor; /* Doing it if hardware is gone is guaranteed crash */ - if (!pcmcia_dev_present(link)) + if (pcmcia_dev_present(link)) return -ENODEV; /* Save original COR value */ diff --git a/trunk/drivers/net/wireless/strip.c b/trunk/drivers/net/wireless/strip.c index ccaf28e8db0a..fd31885c6844 100644 --- a/trunk/drivers/net/wireless/strip.c +++ b/trunk/drivers/net/wireless/strip.c @@ -467,7 +467,6 @@ static int arp_query(unsigned char *haddr, u32 paddr, struct net_device *dev) { struct neighbour *neighbor_entry; - int ret = 0; neighbor_entry = neigh_lookup(&arp_tbl, &paddr, dev); @@ -475,11 +474,10 @@ static int arp_query(unsigned char *haddr, u32 paddr, neighbor_entry->used = jiffies; if (neighbor_entry->nud_state & NUD_VALID) { memcpy(haddr, neighbor_entry->ha, dev->addr_len); - ret = 1; + return 1; } - neigh_release(neighbor_entry); } - return ret; + return 0; } static void DumpData(char *msg, struct strip *strip_info, __u8 * ptr, diff --git a/trunk/drivers/net/yellowfin.c b/trunk/drivers/net/yellowfin.c index b6b247433709..8459a18254a4 100644 --- a/trunk/drivers/net/yellowfin.c +++ b/trunk/drivers/net/yellowfin.c @@ -1434,7 +1434,7 @@ static int __init yellowfin_init (void) #ifdef MODULE printk(version); #endif - return pci_register_driver(&yellowfin_driver); + return pci_module_init (&yellowfin_driver); } diff --git a/trunk/drivers/pci/hotplug/Kconfig b/trunk/drivers/pci/hotplug/Kconfig index 8a60f391ffcf..3c148eaf2f4d 100644 --- a/trunk/drivers/pci/hotplug/Kconfig +++ b/trunk/drivers/pci/hotplug/Kconfig @@ -76,7 +76,7 @@ config HOTPLUG_PCI_IBM config HOTPLUG_PCI_ACPI tristate "ACPI PCI Hotplug driver" - depends on (!ACPI_DOCK && ACPI && HOTPLUG_PCI) || (ACPI_DOCK && HOTPLUG_PCI) + depends on ACPI_DOCK && HOTPLUG_PCI help Say Y here if you have a system that supports PCI Hotplug using ACPI. diff --git a/trunk/drivers/pci/hotplug/cpci_hotplug_pci.c b/trunk/drivers/pci/hotplug/cpci_hotplug_pci.c index 4afcaffd031c..02be74caa89f 100644 --- a/trunk/drivers/pci/hotplug/cpci_hotplug_pci.c +++ b/trunk/drivers/pci/hotplug/cpci_hotplug_pci.c @@ -254,8 +254,8 @@ int cpci_led_off(struct slot* slot) int cpci_configure_slot(struct slot* slot) { - struct pci_bus *parent; - int fn; + unsigned char busnr; + struct pci_bus *child; dbg("%s - enter", __FUNCTION__); @@ -276,53 +276,23 @@ int cpci_configure_slot(struct slot* slot) */ n = pci_scan_slot(slot->bus, slot->devfn); dbg("%s: pci_scan_slot returned %d", __FUNCTION__, n); + if (n > 0) + pci_bus_add_devices(slot->bus); slot->dev = pci_get_slot(slot->bus, slot->devfn); if (slot->dev == NULL) { err("Could not find PCI device for slot %02x", slot->number); - return -ENODEV; + return 1; } } - parent = slot->dev->bus; - - for (fn = 0; fn < 8; fn++) { - struct pci_dev *dev; - - dev = pci_get_slot(parent, PCI_DEVFN(PCI_SLOT(slot->devfn), fn)); - if (!dev) - continue; - if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) || - (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) { - /* Find an unused bus number for the new bridge */ - struct pci_bus *child; - unsigned char busnr, start = parent->secondary; - unsigned char end = parent->subordinate; - - for (busnr = start; busnr <= end; busnr++) { - if (!pci_find_bus(pci_domain_nr(parent), - busnr)) - break; - } - if (busnr >= end) { - err("No free bus for hot-added bridge\n"); - pci_dev_put(dev); - continue; - } - child = pci_add_new_bus(parent, dev, busnr); - if (!child) { - err("Cannot add new bus for %s\n", - pci_name(dev)); - pci_dev_put(dev); - continue; - } - child->subordinate = pci_do_scan_bus(child); - pci_bus_size_bridges(child); - } - pci_dev_put(dev); + + if (slot->dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { + pci_read_config_byte(slot->dev, PCI_SECONDARY_BUS, &busnr); + child = pci_add_new_bus(slot->dev->bus, slot->dev, busnr); + pci_do_scan_bus(child); + pci_bus_size_bridges(child); } - pci_bus_assign_resources(parent); - pci_bus_add_devices(parent); - pci_enable_bridges(parent); + pci_bus_assign_resources(slot->dev->bus); dbg("%s - exit", __FUNCTION__); return 0; diff --git a/trunk/drivers/pci/pci-driver.c b/trunk/drivers/pci/pci-driver.c index 474e9cd0e9e4..10e1a905c144 100644 --- a/trunk/drivers/pci/pci-driver.c +++ b/trunk/drivers/pci/pci-driver.c @@ -139,8 +139,9 @@ const struct pci_device_id *pci_match_id(const struct pci_device_id *ids, /** * pci_match_device - Tell if a PCI device structure has a matching * PCI device id structure - * @drv: the PCI driver to match against + * @ids: array of PCI device id structures to search in * @dev: the PCI device structure to match against + * @drv: the PCI driver to match against * * Used by a driver to check whether a PCI device present in the * system is in its list of supported devices. Returns the matching diff --git a/trunk/drivers/pci/quirks.c b/trunk/drivers/pci/quirks.c index 17e709e7d72a..fb08bc951ac0 100644 --- a/trunk/drivers/pci/quirks.c +++ b/trunk/drivers/pci/quirks.c @@ -438,7 +438,6 @@ static void __devinit quirk_ich6_lpc_acpi(struct pci_dev *dev) pci_read_config_dword(dev, 0x48, ®ion); quirk_io_region(dev, region, 64, PCI_BRIDGE_RESOURCES+1, "ICH6 GPIO"); } -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_0, quirk_ich6_lpc_acpi ); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, quirk_ich6_lpc_acpi ); /* @@ -667,7 +666,6 @@ DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_0, quirk_vi DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, quirk_via_irq); DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_2, quirk_via_irq); DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3, quirk_via_irq); -DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235_USB_2, quirk_via_irq); DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, quirk_via_irq); DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4, quirk_via_irq); DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_5, quirk_via_irq); @@ -1093,6 +1091,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0, asu DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12, asus_hides_smbus_lpc ); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12, asus_hides_smbus_lpc ); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, asus_hides_smbus_lpc ); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, asus_hides_smbus_lpc ); static void __init asus_hides_smbus_lpc_ich6(struct pci_dev *dev) { @@ -1519,63 +1518,6 @@ static void __devinit quirk_netmos(struct pci_dev *dev) } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NETMOS, PCI_ANY_ID, quirk_netmos); -static void __devinit quirk_e100_interrupt(struct pci_dev *dev) -{ - u16 command; - u32 bar; - u8 __iomem *csr; - u8 cmd_hi; - - switch (dev->device) { - /* PCI IDs taken from drivers/net/e100.c */ - case 0x1029: - case 0x1030 ... 0x1034: - case 0x1038 ... 0x103E: - case 0x1050 ... 0x1057: - case 0x1059: - case 0x1064 ... 0x106B: - case 0x1091 ... 0x1095: - case 0x1209: - case 0x1229: - case 0x2449: - case 0x2459: - case 0x245D: - case 0x27DC: - break; - default: - return; - } - - /* - * Some firmware hands off the e100 with interrupts enabled, - * which can cause a flood of interrupts if packets are - * received before the driver attaches to the device. So - * disable all e100 interrupts here. The driver will - * re-enable them when it's ready. - */ - pci_read_config_word(dev, PCI_COMMAND, &command); - pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &bar); - - if (!(command & PCI_COMMAND_MEMORY) || !bar) - return; - - csr = ioremap(bar, 8); - if (!csr) { - printk(KERN_WARNING "PCI: Can't map %s e100 registers\n", - pci_name(dev)); - return; - } - - cmd_hi = readb(csr + 3); - if (cmd_hi == 0) { - printk(KERN_WARNING "PCI: Firmware left %s e100 interrupts " - "enabled, disabling\n", pci_name(dev)); - writeb(1, csr + 3); - } - - iounmap(csr); -} -DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, quirk_e100_interrupt); static void __devinit fixup_rev1_53c810(struct pci_dev* dev) { diff --git a/trunk/drivers/rtc/rtc-s3c.c b/trunk/drivers/rtc/rtc-s3c.c index 2c7de79c83b9..d6d1bff52b8e 100644 --- a/trunk/drivers/rtc/rtc-s3c.c +++ b/trunk/drivers/rtc/rtc-s3c.c @@ -69,12 +69,12 @@ static void s3c_rtc_setaie(int to) pr_debug("%s: aie=%d\n", __FUNCTION__, to); - tmp = readb(s3c_rtc_base + S3C2410_RTCALM) & ~S3C2410_RTCALM_ALMEN; + tmp = readb(S3C2410_RTCALM) & ~S3C2410_RTCALM_ALMEN; if (to) tmp |= S3C2410_RTCALM_ALMEN; - writeb(tmp, s3c_rtc_base + S3C2410_RTCALM); + writeb(tmp, S3C2410_RTCALM); } static void s3c_rtc_setpie(int to) @@ -84,12 +84,12 @@ static void s3c_rtc_setpie(int to) pr_debug("%s: pie=%d\n", __FUNCTION__, to); spin_lock_irq(&s3c_rtc_pie_lock); - tmp = readb(s3c_rtc_base + S3C2410_TICNT) & ~S3C2410_TICNT_ENABLE; + tmp = readb(S3C2410_TICNT) & ~S3C2410_TICNT_ENABLE; if (to) tmp |= S3C2410_TICNT_ENABLE; - writeb(tmp, s3c_rtc_base + S3C2410_TICNT); + writeb(tmp, S3C2410_TICNT); spin_unlock_irq(&s3c_rtc_pie_lock); } @@ -98,13 +98,13 @@ static void s3c_rtc_setfreq(int freq) unsigned int tmp; spin_lock_irq(&s3c_rtc_pie_lock); - tmp = readb(s3c_rtc_base + S3C2410_TICNT) & S3C2410_TICNT_ENABLE; + tmp = readb(S3C2410_TICNT) & S3C2410_TICNT_ENABLE; s3c_rtc_freq = freq; tmp |= (128 / freq)-1; - writeb(tmp, s3c_rtc_base + S3C2410_TICNT); + writeb(tmp, S3C2410_TICNT); spin_unlock_irq(&s3c_rtc_pie_lock); } @@ -113,15 +113,14 @@ static void s3c_rtc_setfreq(int freq) static int s3c_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm) { unsigned int have_retried = 0; - void __iomem *base = s3c_rtc_base; retry_get_time: - rtc_tm->tm_min = readb(base + S3C2410_RTCMIN); - rtc_tm->tm_hour = readb(base + S3C2410_RTCHOUR); - rtc_tm->tm_mday = readb(base + S3C2410_RTCDATE); - rtc_tm->tm_mon = readb(base + S3C2410_RTCMON); - rtc_tm->tm_year = readb(base + S3C2410_RTCYEAR); - rtc_tm->tm_sec = readb(base + S3C2410_RTCSEC); + rtc_tm->tm_min = readb(S3C2410_RTCMIN); + rtc_tm->tm_hour = readb(S3C2410_RTCHOUR); + rtc_tm->tm_mday = readb(S3C2410_RTCDATE); + rtc_tm->tm_mon = readb(S3C2410_RTCMON); + rtc_tm->tm_year = readb(S3C2410_RTCYEAR); + rtc_tm->tm_sec = readb(S3C2410_RTCSEC); /* the only way to work out wether the system was mid-update * when we read it is to check the second counter, and if it @@ -152,26 +151,17 @@ static int s3c_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm) static int s3c_rtc_settime(struct device *dev, struct rtc_time *tm) { - void __iomem *base = s3c_rtc_base; - int year = tm->tm_year - 100; + /* the rtc gets round the y2k problem by just not supporting it */ - pr_debug("set time %02d.%02d.%02d %02d/%02d/%02d\n", - tm->tm_year, tm->tm_mon, tm->tm_mday, - tm->tm_hour, tm->tm_min, tm->tm_sec); - - /* we get around y2k by simply not supporting it */ - - if (year < 0 || year >= 100) { - dev_err(dev, "rtc only supports 100 years\n"); + if (tm->tm_year < 100) return -EINVAL; - } - writeb(BIN2BCD(tm->tm_sec), base + S3C2410_RTCSEC); - writeb(BIN2BCD(tm->tm_min), base + S3C2410_RTCMIN); - writeb(BIN2BCD(tm->tm_hour), base + S3C2410_RTCHOUR); - writeb(BIN2BCD(tm->tm_mday), base + S3C2410_RTCDATE); - writeb(BIN2BCD(tm->tm_mon + 1), base + S3C2410_RTCMON); - writeb(BIN2BCD(year), base + S3C2410_RTCYEAR); + writeb(BIN2BCD(tm->tm_sec), S3C2410_RTCSEC); + writeb(BIN2BCD(tm->tm_min), S3C2410_RTCMIN); + writeb(BIN2BCD(tm->tm_hour), S3C2410_RTCHOUR); + writeb(BIN2BCD(tm->tm_mday), S3C2410_RTCDATE); + writeb(BIN2BCD(tm->tm_mon + 1), S3C2410_RTCMON); + writeb(BIN2BCD(tm->tm_year - 100), S3C2410_RTCYEAR); return 0; } @@ -179,17 +169,16 @@ static int s3c_rtc_settime(struct device *dev, struct rtc_time *tm) static int s3c_rtc_getalarm(struct device *dev, struct rtc_wkalrm *alrm) { struct rtc_time *alm_tm = &alrm->time; - void __iomem *base = s3c_rtc_base; unsigned int alm_en; - alm_tm->tm_sec = readb(base + S3C2410_ALMSEC); - alm_tm->tm_min = readb(base + S3C2410_ALMMIN); - alm_tm->tm_hour = readb(base + S3C2410_ALMHOUR); - alm_tm->tm_mon = readb(base + S3C2410_ALMMON); - alm_tm->tm_mday = readb(base + S3C2410_ALMDATE); - alm_tm->tm_year = readb(base + S3C2410_ALMYEAR); + alm_tm->tm_sec = readb(S3C2410_ALMSEC); + alm_tm->tm_min = readb(S3C2410_ALMMIN); + alm_tm->tm_hour = readb(S3C2410_ALMHOUR); + alm_tm->tm_mon = readb(S3C2410_ALMMON); + alm_tm->tm_mday = readb(S3C2410_ALMDATE); + alm_tm->tm_year = readb(S3C2410_ALMYEAR); - alm_en = readb(base + S3C2410_RTCALM); + alm_en = readb(S3C2410_RTCALM); pr_debug("read alarm %02x %02x.%02x.%02x %02x/%02x/%02x\n", alm_en, @@ -237,7 +226,6 @@ static int s3c_rtc_getalarm(struct device *dev, struct rtc_wkalrm *alrm) static int s3c_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) { struct rtc_time *tm = &alrm->time; - void __iomem *base = s3c_rtc_base; unsigned int alrm_en; pr_debug("s3c_rtc_setalarm: %d, %02x/%02x/%02x %02x.%02x.%02x\n", @@ -246,32 +234,32 @@ static int s3c_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) tm->tm_hour & 0xff, tm->tm_min & 0xff, tm->tm_sec); - alrm_en = readb(base + S3C2410_RTCALM) & S3C2410_RTCALM_ALMEN; - writeb(0x00, base + S3C2410_RTCALM); + alrm_en = readb(S3C2410_RTCALM) & S3C2410_RTCALM_ALMEN; + writeb(0x00, S3C2410_RTCALM); if (tm->tm_sec < 60 && tm->tm_sec >= 0) { alrm_en |= S3C2410_RTCALM_SECEN; - writeb(BIN2BCD(tm->tm_sec), base + S3C2410_ALMSEC); + writeb(BIN2BCD(tm->tm_sec), S3C2410_ALMSEC); } if (tm->tm_min < 60 && tm->tm_min >= 0) { alrm_en |= S3C2410_RTCALM_MINEN; - writeb(BIN2BCD(tm->tm_min), base + S3C2410_ALMMIN); + writeb(BIN2BCD(tm->tm_min), S3C2410_ALMMIN); } if (tm->tm_hour < 24 && tm->tm_hour >= 0) { alrm_en |= S3C2410_RTCALM_HOUREN; - writeb(BIN2BCD(tm->tm_hour), base + S3C2410_ALMHOUR); + writeb(BIN2BCD(tm->tm_hour), S3C2410_ALMHOUR); } pr_debug("setting S3C2410_RTCALM to %08x\n", alrm_en); - writeb(alrm_en, base + S3C2410_RTCALM); + writeb(alrm_en, S3C2410_RTCALM); if (0) { - alrm_en = readb(base + S3C2410_RTCALM); + alrm_en = readb(S3C2410_RTCALM); alrm_en &= ~S3C2410_RTCALM_ALMEN; - writeb(alrm_en, base + S3C2410_RTCALM); + writeb(alrm_en, S3C2410_RTCALM); disable_irq_wake(s3c_rtc_alarmno); } @@ -331,8 +319,8 @@ static int s3c_rtc_ioctl(struct device *dev, static int s3c_rtc_proc(struct device *dev, struct seq_file *seq) { - unsigned int rtcalm = readb(s3c_rtc_base + S3C2410_RTCALM); - unsigned int ticnt = readb(s3c_rtc_base + S3C2410_TICNT); + unsigned int rtcalm = readb(S3C2410_RTCALM); + unsigned int ticnt = readb (S3C2410_TICNT); seq_printf(seq, "alarm_IRQ\t: %s\n", (rtcalm & S3C2410_RTCALM_ALMEN) ? "yes" : "no" ); @@ -399,40 +387,39 @@ static struct rtc_class_ops s3c_rtcops = { static void s3c_rtc_enable(struct platform_device *pdev, int en) { - void __iomem *base = s3c_rtc_base; unsigned int tmp; if (s3c_rtc_base == NULL) return; if (!en) { - tmp = readb(base + S3C2410_RTCCON); - writeb(tmp & ~S3C2410_RTCCON_RTCEN, base + S3C2410_RTCCON); + tmp = readb(S3C2410_RTCCON); + writeb(tmp & ~S3C2410_RTCCON_RTCEN, S3C2410_RTCCON); - tmp = readb(base + S3C2410_TICNT); - writeb(tmp & ~S3C2410_TICNT_ENABLE, base + S3C2410_TICNT); + tmp = readb(S3C2410_TICNT); + writeb(tmp & ~S3C2410_TICNT_ENABLE, S3C2410_TICNT); } else { /* re-enable the device, and check it is ok */ - if ((readb(base+S3C2410_RTCCON) & S3C2410_RTCCON_RTCEN) == 0){ + if ((readb(S3C2410_RTCCON) & S3C2410_RTCCON_RTCEN) == 0){ dev_info(&pdev->dev, "rtc disabled, re-enabling\n"); - tmp = readb(base + S3C2410_RTCCON); - writeb(tmp|S3C2410_RTCCON_RTCEN, base+S3C2410_RTCCON); + tmp = readb(S3C2410_RTCCON); + writeb(tmp | S3C2410_RTCCON_RTCEN , S3C2410_RTCCON); } - if ((readb(base + S3C2410_RTCCON) & S3C2410_RTCCON_CNTSEL)){ + if ((readb(S3C2410_RTCCON) & S3C2410_RTCCON_CNTSEL)){ dev_info(&pdev->dev, "removing RTCCON_CNTSEL\n"); - tmp = readb(base + S3C2410_RTCCON); - writeb(tmp& ~S3C2410_RTCCON_CNTSEL, base+S3C2410_RTCCON); + tmp = readb(S3C2410_RTCCON); + writeb(tmp& ~S3C2410_RTCCON_CNTSEL , S3C2410_RTCCON); } - if ((readb(base + S3C2410_RTCCON) & S3C2410_RTCCON_CLKRST)){ + if ((readb(S3C2410_RTCCON) & S3C2410_RTCCON_CLKRST)){ dev_info(&pdev->dev, "removing RTCCON_CLKRST\n"); - tmp = readb(base + S3C2410_RTCCON); - writeb(tmp & ~S3C2410_RTCCON_CLKRST, base+S3C2410_RTCCON); + tmp = readb(S3C2410_RTCCON); + writeb(tmp & ~S3C2410_RTCCON_CLKRST, S3C2410_RTCCON); } } } @@ -488,8 +475,8 @@ static int s3c_rtc_probe(struct platform_device *pdev) } s3c_rtc_mem = request_mem_region(res->start, - res->end-res->start+1, - pdev->name); + res->end-res->start+1, + pdev->name); if (s3c_rtc_mem == NULL) { dev_err(&pdev->dev, "failed to reserve memory region\n"); @@ -508,8 +495,7 @@ static int s3c_rtc_probe(struct platform_device *pdev) s3c_rtc_enable(pdev, 1); - pr_debug("s3c2410_rtc: RTCCON=%02x\n", - readb(s3c_rtc_base + S3C2410_RTCCON)); + pr_debug("s3c2410_rtc: RTCCON=%02x\n", readb(S3C2410_RTCCON)); s3c_rtc_setfreq(s3c_rtc_freq); @@ -557,7 +543,7 @@ static int s3c_rtc_suspend(struct platform_device *pdev, pm_message_t state) /* save TICNT for anyone using periodic interrupts */ - ticnt_save = readb(s3c_rtc_base + S3C2410_TICNT); + ticnt_save = readb(S3C2410_TICNT); /* calculate time delta for suspend */ @@ -581,7 +567,7 @@ static int s3c_rtc_resume(struct platform_device *pdev) rtc_tm_to_time(&tm, &time.tv_sec); restore_time_delta(&s3c_rtc_delta, &time); - writeb(ticnt_save, s3c_rtc_base + S3C2410_TICNT); + writeb(ticnt_save, S3C2410_TICNT); return 0; } #else diff --git a/trunk/drivers/s390/block/dasd.c b/trunk/drivers/s390/block/dasd.c index 25c1ef6dfd44..d8e9b95f0a1a 100644 --- a/trunk/drivers/s390/block/dasd.c +++ b/trunk/drivers/s390/block/dasd.c @@ -52,7 +52,7 @@ static void dasd_setup_queue(struct dasd_device * device); static void dasd_free_queue(struct dasd_device * device); static void dasd_flush_request_queue(struct dasd_device *); static void dasd_int_handler(struct ccw_device *, unsigned long, struct irb *); -static int dasd_flush_ccw_queue(struct dasd_device *, int); +static void dasd_flush_ccw_queue(struct dasd_device *, int); static void dasd_tasklet(struct dasd_device *); static void do_kick_device(void *data); @@ -60,7 +60,6 @@ static void do_kick_device(void *data); * SECTION: Operations on the device structure. */ static wait_queue_head_t dasd_init_waitq; -static wait_queue_head_t dasd_flush_wq; /* * Allocate memory for a new device structure. @@ -122,7 +121,7 @@ dasd_free_device(struct dasd_device *device) /* * Make a new device known to the system. */ -static int +static inline int dasd_state_new_to_known(struct dasd_device *device) { int rc; @@ -146,7 +145,7 @@ dasd_state_new_to_known(struct dasd_device *device) /* * Let the system forget about a device. */ -static int +static inline void dasd_state_known_to_new(struct dasd_device * device) { /* Disable extended error reporting for this device. */ @@ -164,13 +163,12 @@ dasd_state_known_to_new(struct dasd_device * device) /* Give up reference we took in dasd_state_new_to_known. */ dasd_put_device(device); - return 0; } /* * Request the irq line for the device. */ -static int +static inline int dasd_state_known_to_basic(struct dasd_device * device) { int rc; @@ -194,23 +192,17 @@ dasd_state_known_to_basic(struct dasd_device * device) /* * Release the irq line for the device. Terminate any running i/o. */ -static int +static inline void dasd_state_basic_to_known(struct dasd_device * device) { - int rc; - dasd_gendisk_free(device); - rc = dasd_flush_ccw_queue(device, 1); - if (rc) - return rc; - + dasd_flush_ccw_queue(device, 1); DBF_DEV_EVENT(DBF_EMERG, device, "%p debug area deleted", device); if (device->debug_area != NULL) { debug_unregister(device->debug_area); device->debug_area = NULL; } device->state = DASD_STATE_KNOWN; - return 0; } /* @@ -227,7 +219,7 @@ dasd_state_basic_to_known(struct dasd_device * device) * In case the analysis returns an error, the device setup is stopped * (a fake disk was already added to allow formatting). */ -static int +static inline int dasd_state_basic_to_ready(struct dasd_device * device) { int rc; @@ -255,31 +247,25 @@ dasd_state_basic_to_ready(struct dasd_device * device) * Forget format information. Check if the target level is basic * and if it is create fake disk for formatting. */ -static int +static inline void dasd_state_ready_to_basic(struct dasd_device * device) { - int rc; - - rc = dasd_flush_ccw_queue(device, 0); - if (rc) - return rc; + dasd_flush_ccw_queue(device, 0); dasd_destroy_partitions(device); dasd_flush_request_queue(device); device->blocks = 0; device->bp_block = 0; device->s2b_shift = 0; device->state = DASD_STATE_BASIC; - return 0; } /* * Back to basic. */ -static int +static inline void dasd_state_unfmt_to_basic(struct dasd_device * device) { device->state = DASD_STATE_BASIC; - return 0; } /* @@ -287,7 +273,7 @@ dasd_state_unfmt_to_basic(struct dasd_device * device) * the requeueing of requests from the linux request queue to the * ccw queue. */ -static int +static inline int dasd_state_ready_to_online(struct dasd_device * device) { device->state = DASD_STATE_ONLINE; @@ -298,17 +284,16 @@ dasd_state_ready_to_online(struct dasd_device * device) /* * Stop the requeueing of requests again. */ -static int +static inline void dasd_state_online_to_ready(struct dasd_device * device) { device->state = DASD_STATE_READY; - return 0; } /* * Device startup state changes. */ -static int +static inline int dasd_increase_state(struct dasd_device *device) { int rc; @@ -344,37 +329,30 @@ dasd_increase_state(struct dasd_device *device) /* * Device shutdown state changes. */ -static int +static inline int dasd_decrease_state(struct dasd_device *device) { - int rc; - - rc = 0; if (device->state == DASD_STATE_ONLINE && device->target <= DASD_STATE_READY) - rc = dasd_state_online_to_ready(device); + dasd_state_online_to_ready(device); - if (!rc && - device->state == DASD_STATE_READY && + if (device->state == DASD_STATE_READY && device->target <= DASD_STATE_BASIC) - rc = dasd_state_ready_to_basic(device); + dasd_state_ready_to_basic(device); - if (!rc && - device->state == DASD_STATE_UNFMT && + if (device->state == DASD_STATE_UNFMT && device->target <= DASD_STATE_BASIC) - rc = dasd_state_unfmt_to_basic(device); + dasd_state_unfmt_to_basic(device); - if (!rc && - device->state == DASD_STATE_BASIC && + if (device->state == DASD_STATE_BASIC && device->target <= DASD_STATE_KNOWN) - rc = dasd_state_basic_to_known(device); + dasd_state_basic_to_known(device); - if (!rc && - device->state == DASD_STATE_KNOWN && + if (device->state == DASD_STATE_KNOWN && device->target <= DASD_STATE_NEW) - rc = dasd_state_known_to_new(device); + dasd_state_known_to_new(device); - return rc; + return 0; } /* @@ -723,7 +701,6 @@ dasd_term_IO(struct dasd_ccw_req * cqr) cqr->retries--; cqr->status = DASD_CQR_CLEAR; cqr->stopclk = get_clock(); - cqr->starttime = 0; DBF_DEV_EVENT(DBF_DEBUG, device, "terminate cqr %p successful", cqr); @@ -1001,7 +978,6 @@ dasd_int_handler(struct ccw_device *cdev, unsigned long intparm, irb->scsw.fctl & SCSW_FCTL_CLEAR_FUNC) { cqr->status = DASD_CQR_QUEUED; dasd_clear_timer(device); - wake_up(&dasd_flush_wq); dasd_schedule_bh(device); return; } @@ -1265,10 +1241,6 @@ __dasd_check_expire(struct dasd_device * device) cqr = list_entry(device->ccw_queue.next, struct dasd_ccw_req, list); if (cqr->status == DASD_CQR_IN_IO && cqr->expires != 0) { if (time_after_eq(jiffies, cqr->expires + cqr->starttime)) { - DEV_MESSAGE(KERN_ERR, device, - "internal error - timeout (%is) expired " - "for cqr %p (%i retries left)", - (cqr->expires/HZ), cqr, cqr->retries); if (device->discipline->term_IO(cqr) != 0) /* Hmpf, try again in 1/10 sec */ dasd_set_timer(device, 10); @@ -1313,100 +1285,46 @@ __dasd_start_head(struct dasd_device * device) dasd_set_timer(device, 50); } -static inline int -_wait_for_clear(struct dasd_ccw_req *cqr) -{ - return (cqr->status == DASD_CQR_QUEUED); -} - /* - * Remove all requests from the ccw queue (all = '1') or only block device - * requests in case all = '0'. - * Take care of the erp-chain (chained via cqr->refers) and remove either - * the whole erp-chain or none of the erp-requests. - * If a request is currently running, term_IO is called and the request - * is re-queued. Prior to removing the terminated request we need to wait - * for the clear-interrupt. - * In case termination is not possible we stop processing and just finishing - * the already moved requests. + * Remove requests from the ccw queue. */ -static int +static void dasd_flush_ccw_queue(struct dasd_device * device, int all) { - struct dasd_ccw_req *cqr, *orig, *n; - int rc, i; - struct list_head flush_queue; + struct list_head *l, *n; + struct dasd_ccw_req *cqr; INIT_LIST_HEAD(&flush_queue); spin_lock_irq(get_ccwdev_lock(device->cdev)); - rc = 0; -restart: - list_for_each_entry_safe(cqr, n, &device->ccw_queue, list) { - /* get original request of erp request-chain */ - for (orig = cqr; orig->refers != NULL; orig = orig->refers); - + list_for_each_safe(l, n, &device->ccw_queue) { + cqr = list_entry(l, struct dasd_ccw_req, list); /* Flush all request or only block device requests? */ - if (all == 0 && cqr->callback != dasd_end_request_cb && - orig->callback != dasd_end_request_cb) { + if (all == 0 && cqr->callback == dasd_end_request_cb) continue; - } - /* Check status and move request to flush_queue */ - switch (cqr->status) { - case DASD_CQR_IN_IO: - rc = device->discipline->term_IO(cqr); - if (rc) { - /* unable to terminate requeust */ - DEV_MESSAGE(KERN_ERR, device, - "dasd flush ccw_queue is unable " - " to terminate request %p", - cqr); - /* stop flush processing */ - goto finished; - } - break; - case DASD_CQR_QUEUED: - case DASD_CQR_ERROR: - /* set request to FAILED */ - cqr->stopclk = get_clock(); - cqr->status = DASD_CQR_FAILED; - break; - default: /* do not touch the others */ - break; - } - /* Rechain request (including erp chain) */ - for (i = 0; cqr != NULL; cqr = cqr->refers, i++) { - cqr->endclk = get_clock(); - list_move_tail(&cqr->list, &flush_queue); - } - if (i > 1) - /* moved more than one request - need to restart */ - goto restart; - } - -finished: - spin_unlock_irq(get_ccwdev_lock(device->cdev)); - /* Now call the callback function of flushed requests */ -restart_cb: - list_for_each_entry_safe(cqr, n, &flush_queue, list) { - if (cqr->status == DASD_CQR_CLEAR) { - /* wait for clear interrupt! */ - wait_event(dasd_flush_wq, _wait_for_clear(cqr)); + if (cqr->status == DASD_CQR_IN_IO) + device->discipline->term_IO(cqr); + if (cqr->status != DASD_CQR_DONE || + cqr->status != DASD_CQR_FAILED) { cqr->status = DASD_CQR_FAILED; + cqr->stopclk = get_clock(); } /* Process finished ERP request. */ if (cqr->refers) { __dasd_process_erp(device, cqr); - /* restart list_for_xx loop since dasd_process_erp - * might remove multiple elements */ - goto restart_cb; + continue; } - /* call the callback function */ + /* Rechain request on device request queue */ cqr->endclk = get_clock(); + list_move_tail(&cqr->list, &flush_queue); + } + spin_unlock_irq(get_ccwdev_lock(device->cdev)); + /* Now call the callback function of flushed requests */ + list_for_each_safe(l, n, &flush_queue) { + cqr = list_entry(l, struct dasd_ccw_req, list); if (cqr->callback != NULL) (cqr->callback)(cqr, cqr->callback_data); } - return rc; } /* @@ -1592,8 +1510,10 @@ dasd_sleep_on_interruptible(struct dasd_ccw_req * cqr) if (device->discipline->term_IO) { cqr->retries = -1; device->discipline->term_IO(cqr); - /* wait (non-interruptible) for final status - * because signal ist still pending */ + /*nished = + * wait (non-interruptible) for final status + * because signal ist still pending + */ spin_unlock_irq(get_ccwdev_lock(device->cdev)); wait_event(wait_q, _wait_for_wakeup(cqr)); spin_lock_irq(get_ccwdev_lock(device->cdev)); @@ -1626,11 +1546,19 @@ static inline int _dasd_term_running_cqr(struct dasd_device *device) { struct dasd_ccw_req *cqr; + int rc; if (list_empty(&device->ccw_queue)) return 0; cqr = list_entry(device->ccw_queue.next, struct dasd_ccw_req, list); - return device->discipline->term_IO(cqr); + rc = device->discipline->term_IO(cqr); + if (rc == 0) { + /* termination successful */ + cqr->status = DASD_CQR_QUEUED; + cqr->startclk = cqr->stopclk = 0; + cqr->starttime = 0; + } + return rc; } int @@ -1798,7 +1726,10 @@ dasd_flush_request_queue(struct dasd_device * device) return; spin_lock_irq(&device->request_queue_lock); - while ((req = elv_next_request(device->request_queue))) { + while (!list_empty(&device->request_queue->queue_head)) { + req = elv_next_request(device->request_queue); + if (req == NULL) + break; blkdev_dequeue_request(req); dasd_end_request(req, 0); } @@ -2160,7 +2091,6 @@ dasd_init(void) int rc; init_waitqueue_head(&dasd_init_waitq); - init_waitqueue_head(&dasd_flush_wq); /* register 'common' DASD debug area, used for all DBF_XXX calls */ dasd_debug_area = debug_register("dasd", 1, 2, 8 * sizeof (long)); diff --git a/trunk/drivers/s390/block/dasd_devmap.c b/trunk/drivers/s390/block/dasd_devmap.c index 9af02c79ce8a..9d0c6e1a0e66 100644 --- a/trunk/drivers/s390/block/dasd_devmap.c +++ b/trunk/drivers/s390/block/dasd_devmap.c @@ -54,11 +54,11 @@ struct dasd_devmap { */ struct dasd_server_ssid_map { struct list_head list; - struct system_id { + struct server_id { char vendor[4]; char serial[15]; - __u16 ssid; } sid; + __u16 ssid; }; static struct list_head dasd_server_ssid_list; @@ -904,14 +904,14 @@ dasd_set_uid(struct ccw_device *cdev, struct dasd_uid *uid) return -ENOMEM; strncpy(srv->sid.vendor, uid->vendor, sizeof(srv->sid.vendor) - 1); strncpy(srv->sid.serial, uid->serial, sizeof(srv->sid.serial) - 1); - srv->sid.ssid = uid->ssid; + srv->ssid = uid->ssid; /* server is already contained ? */ spin_lock(&dasd_devmap_lock); devmap->uid = *uid; list_for_each_entry(tmp, &dasd_server_ssid_list, list) { if (!memcmp(&srv->sid, &tmp->sid, - sizeof(struct system_id))) { + sizeof(struct dasd_server_ssid_map))) { kfree(srv); srv = NULL; break; diff --git a/trunk/drivers/s390/block/dasd_eckd.c b/trunk/drivers/s390/block/dasd_eckd.c index b7a7fac3f7c3..957ed5db98e4 100644 --- a/trunk/drivers/s390/block/dasd_eckd.c +++ b/trunk/drivers/s390/block/dasd_eckd.c @@ -607,7 +607,7 @@ dasd_eckd_psf_ssc(struct dasd_device *device) * Valide storage server of current device. */ static int -dasd_eckd_validate_server(struct dasd_device *device, struct dasd_uid *uid) +dasd_eckd_validate_server(struct dasd_device *device) { int rc; @@ -616,11 +616,11 @@ dasd_eckd_validate_server(struct dasd_device *device, struct dasd_uid *uid) return 0; rc = dasd_eckd_psf_ssc(device); - /* may be requested feature is not available on server, - * therefore just report error and go ahead */ - DEV_MESSAGE(KERN_INFO, device, - "PSF-SSC on storage subsystem %s.%s.%04x returned rc=%d", - uid->vendor, uid->serial, uid->ssid, rc); + if (rc) + /* may be requested feature is not available on server, + * therefore just report error and go ahead */ + DEV_MESSAGE(KERN_INFO, device, + "Perform Subsystem Function returned rc=%d", rc); /* RE-Read Configuration Data */ return dasd_eckd_read_conf(device); } @@ -666,7 +666,7 @@ dasd_eckd_check_characteristics(struct dasd_device *device) return rc; rc = dasd_set_uid(device->cdev, &uid); if (rc == 1) /* new server found */ - rc = dasd_eckd_validate_server(device, &uid); + rc = dasd_eckd_validate_server(device); if (rc) return rc; diff --git a/trunk/drivers/s390/block/dasd_genhd.c b/trunk/drivers/s390/block/dasd_genhd.c index d163632101d2..4c272b70f41a 100644 --- a/trunk/drivers/s390/block/dasd_genhd.c +++ b/trunk/drivers/s390/block/dasd_genhd.c @@ -83,12 +83,10 @@ dasd_gendisk_alloc(struct dasd_device *device) void dasd_gendisk_free(struct dasd_device *device) { - if (device->gdp) { - del_gendisk(device->gdp); - device->gdp->queue = NULL; - put_disk(device->gdp); - device->gdp = NULL; - } + del_gendisk(device->gdp); + device->gdp->queue = NULL; + put_disk(device->gdp); + device->gdp = NULL; } /* diff --git a/trunk/drivers/s390/cio/ccwgroup.c b/trunk/drivers/s390/cio/ccwgroup.c index 38954f5cd14c..3cba6c9fab11 100644 --- a/trunk/drivers/s390/cio/ccwgroup.c +++ b/trunk/drivers/s390/cio/ccwgroup.c @@ -183,9 +183,11 @@ ccwgroup_create(struct device *root, gdev->creator_id = creator_id; gdev->count = argc; - gdev->dev.bus = &ccwgroup_bus_type; - gdev->dev.parent = root; - gdev->dev.release = ccwgroup_release; + gdev->dev = (struct device ) { + .bus = &ccwgroup_bus_type, + .parent = root, + .release = ccwgroup_release, + }; snprintf (gdev->dev.bus_id, BUS_ID_SIZE, "%s", gdev->cdev[0]->dev.bus_id); @@ -389,8 +391,10 @@ int ccwgroup_driver_register (struct ccwgroup_driver *cdriver) { /* register our new driver with the core */ - cdriver->driver.bus = &ccwgroup_bus_type; - cdriver->driver.name = cdriver->name; + cdriver->driver = (struct device_driver) { + .bus = &ccwgroup_bus_type, + .name = cdriver->name, + }; return driver_register(&cdriver->driver); } diff --git a/trunk/drivers/s390/cio/chsc.c b/trunk/drivers/s390/cio/chsc.c index c28444af0919..61ce3f1d5228 100644 --- a/trunk/drivers/s390/cio/chsc.c +++ b/trunk/drivers/s390/cio/chsc.c @@ -238,6 +238,8 @@ s390_subchannel_remove_chpid(struct device *dev, void *data) /* Check for single path devices. */ if (sch->schib.pmcw.pim == 0x80) goto out_unreg; + if (sch->vpm == mask) + goto out_unreg; if ((sch->schib.scsw.actl & SCSW_ACTL_DEVACT) && (sch->schib.scsw.actl & SCSW_ACTL_SCHACT) && @@ -256,8 +258,6 @@ s390_subchannel_remove_chpid(struct device *dev, void *data) /* trigger path verification. */ if (sch->driver && sch->driver->verify) sch->driver->verify(&sch->dev); - else if (sch->vpm == mask) - goto out_unreg; out_unlock: spin_unlock_irq(&sch->lock); return 0; @@ -1391,8 +1391,10 @@ new_channel_path(int chpid) /* fill in status, etc. */ chp->id = chpid; chp->state = 1; - chp->dev.parent = &css[0]->device; - chp->dev.release = chp_release; + chp->dev = (struct device) { + .parent = &css[0]->device, + .release = chp_release, + }; snprintf(chp->dev.bus_id, BUS_ID_SIZE, "chp0.%x", chpid); /* Obtain channel path description and fill it in. */ diff --git a/trunk/drivers/s390/cio/device.c b/trunk/drivers/s390/cio/device.c index 646da5640401..585fa04233c3 100644 --- a/trunk/drivers/s390/cio/device.c +++ b/trunk/drivers/s390/cio/device.c @@ -556,11 +556,12 @@ get_disc_ccwdev_by_devno(unsigned int devno, unsigned int ssid, struct ccw_device *sibling) { struct device *dev; - struct match_data data; + struct match_data data = { + .devno = devno, + .ssid = ssid, + .sibling = sibling, + }; - data.devno = devno; - data.ssid = ssid; - data.sibling = sibling; dev = bus_find_device(&ccw_bus_type, NULL, &data, match_devno); return dev ? to_ccwdev(dev) : NULL; @@ -834,8 +835,10 @@ io_subchannel_probe (struct subchannel *sch) return -ENOMEM; } atomic_set(&cdev->private->onoff, 0); - cdev->dev.parent = &sch->dev; - cdev->dev.release = ccw_device_release; + cdev->dev = (struct device) { + .parent = &sch->dev, + .release = ccw_device_release, + }; INIT_LIST_HEAD(&cdev->private->kick_work.entry); /* Do first half of device_register. */ device_initialize(&cdev->dev); @@ -974,7 +977,9 @@ ccw_device_console_enable (struct ccw_device *cdev, struct subchannel *sch) int rc; /* Initialize the ccw_device structure. */ - cdev->dev.parent= &sch->dev; + cdev->dev = (struct device) { + .parent = &sch->dev, + }; rc = io_subchannel_recog(cdev, sch); if (rc) return rc; diff --git a/trunk/drivers/s390/cio/device_fsm.c b/trunk/drivers/s390/cio/device_fsm.c index 35e162ba6d54..6d91c2eb205b 100644 --- a/trunk/drivers/s390/cio/device_fsm.c +++ b/trunk/drivers/s390/cio/device_fsm.c @@ -267,10 +267,12 @@ ccw_device_recog_done(struct ccw_device *cdev, int state) notify = 1; } /* fill out sense information */ - cdev->id.cu_type = cdev->private->senseid.cu_type; - cdev->id.cu_model = cdev->private->senseid.cu_model; - cdev->id.dev_type = cdev->private->senseid.dev_type; - cdev->id.dev_model = cdev->private->senseid.dev_model; + cdev->id = (struct ccw_device_id) { + .cu_type = cdev->private->senseid.cu_type, + .cu_model = cdev->private->senseid.cu_model, + .dev_type = cdev->private->senseid.dev_type, + .dev_model = cdev->private->senseid.dev_model, + }; if (notify) { cdev->private->state = DEV_STATE_OFFLINE; if (same_dev) { @@ -564,10 +566,12 @@ ccw_device_verify_done(struct ccw_device *cdev, int err) /* Deliver fake irb to device driver, if needed. */ if (cdev->private->flags.fake_irb) { memset(&cdev->private->irb, 0, sizeof(struct irb)); - cdev->private->irb.scsw.cc = 1; - cdev->private->irb.scsw.fctl = SCSW_FCTL_START_FUNC; - cdev->private->irb.scsw.actl = SCSW_ACTL_START_PEND; - cdev->private->irb.scsw.stctl = SCSW_STCTL_STATUS_PEND; + cdev->private->irb.scsw = (struct scsw) { + .cc = 1, + .fctl = SCSW_FCTL_START_FUNC, + .actl = SCSW_ACTL_START_PEND, + .stctl = SCSW_STCTL_STATUS_PEND, + }; cdev->private->flags.fake_irb = 0; if (cdev->handler) cdev->handler(cdev, cdev->private->intparm, diff --git a/trunk/drivers/s390/cio/device_pgid.c b/trunk/drivers/s390/cio/device_pgid.c index 1693a102dcfe..32610fd8868e 100644 --- a/trunk/drivers/s390/cio/device_pgid.c +++ b/trunk/drivers/s390/cio/device_pgid.c @@ -23,21 +23,6 @@ #include "device.h" #include "ioasm.h" -/* - * Helper function called from interrupt context to decide whether an - * operation should be tried again. - */ -static int __ccw_device_should_retry(struct scsw *scsw) -{ - /* CC is only valid if start function bit is set. */ - if ((scsw->fctl & SCSW_FCTL_START_FUNC) && scsw->cc == 1) - return 1; - /* No more activity. For sense and set PGID we stubbornly try again. */ - if (!scsw->actl) - return 1; - return 0; -} - /* * Start Sense Path Group ID helper function. Used in ccw_device_recog * and ccw_device_sense_pgid. @@ -170,10 +155,10 @@ ccw_device_sense_pgid_irq(struct ccw_device *cdev, enum dev_event dev_event) int ret; irb = (struct irb *) __LC_IRB; - + /* Retry sense pgid for cc=1. */ if (irb->scsw.stctl == (SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) { - if (__ccw_device_should_retry(&irb->scsw)) { + if (irb->scsw.cc == 1) { ret = __ccw_device_sense_pgid_start(cdev); if (ret && ret != -EBUSY) ccw_device_sense_pgid_done(cdev, ret); @@ -406,10 +391,10 @@ ccw_device_verify_irq(struct ccw_device *cdev, enum dev_event dev_event) int ret; irb = (struct irb *) __LC_IRB; - + /* Retry set pgid for cc=1. */ if (irb->scsw.stctl == (SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) { - if (__ccw_device_should_retry(&irb->scsw)) + if (irb->scsw.cc == 1) __ccw_device_verify_start(cdev); return; } @@ -509,10 +494,10 @@ ccw_device_disband_irq(struct ccw_device *cdev, enum dev_event dev_event) int ret; irb = (struct irb *) __LC_IRB; - + /* Retry set pgid for cc=1. */ if (irb->scsw.stctl == (SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) { - if (__ccw_device_should_retry(&irb->scsw)) + if (irb->scsw.cc == 1) __ccw_device_disband_start(cdev); return; } diff --git a/trunk/drivers/s390/net/qeth_main.c b/trunk/drivers/s390/net/qeth_main.c index e1327b8fce00..5fff1f93973a 100644 --- a/trunk/drivers/s390/net/qeth_main.c +++ b/trunk/drivers/s390/net/qeth_main.c @@ -8510,9 +8510,9 @@ static int qeth_ipv6_init(void) { qeth_old_arp_constructor = arp_tbl.constructor; - write_lock_bh(&arp_tbl.lock); + write_lock(&arp_tbl.lock); arp_tbl.constructor = qeth_arp_constructor; - write_unlock_bh(&arp_tbl.lock); + write_unlock(&arp_tbl.lock); arp_direct_ops = (struct neigh_ops*) kmalloc(sizeof(struct neigh_ops), GFP_KERNEL); @@ -8528,9 +8528,9 @@ qeth_ipv6_init(void) static void qeth_ipv6_uninit(void) { - write_lock_bh(&arp_tbl.lock); + write_lock(&arp_tbl.lock); arp_tbl.constructor = qeth_old_arp_constructor; - write_unlock_bh(&arp_tbl.lock); + write_unlock(&arp_tbl.lock); kfree(arp_direct_ops); } #endif /* CONFIG_QETH_IPV6 */ diff --git a/trunk/drivers/s390/scsi/zfcp_aux.c b/trunk/drivers/s390/scsi/zfcp_aux.c index adc9d8f2c28f..9cd789b8acd4 100644 --- a/trunk/drivers/s390/scsi/zfcp_aux.c +++ b/trunk/drivers/s390/scsi/zfcp_aux.c @@ -112,105 +112,6 @@ _zfcp_hex_dump(char *addr, int count) printk("\n"); } - -/****************************************************************/ -/****** Functions to handle the request ID hash table ********/ -/****************************************************************/ - -#define ZFCP_LOG_AREA ZFCP_LOG_AREA_FSF - -static int zfcp_reqlist_init(struct zfcp_adapter *adapter) -{ - int i; - - adapter->req_list = kcalloc(REQUEST_LIST_SIZE, sizeof(struct list_head), - GFP_KERNEL); - - if (!adapter->req_list) - return -ENOMEM; - - for (i=0; ireq_list[i]); - - return 0; -} - -static void zfcp_reqlist_free(struct zfcp_adapter *adapter) -{ - struct zfcp_fsf_req *request, *tmp; - unsigned int i; - - for (i=0; ireq_list[i])) - continue; - - list_for_each_entry_safe(request, tmp, - &adapter->req_list[i], list) - list_del(&request->list); - } - - kfree(adapter->req_list); -} - -void zfcp_reqlist_add(struct zfcp_adapter *adapter, - struct zfcp_fsf_req *fsf_req) -{ - unsigned int i; - - i = fsf_req->req_id % REQUEST_LIST_SIZE; - list_add_tail(&fsf_req->list, &adapter->req_list[i]); -} - -void zfcp_reqlist_remove(struct zfcp_adapter *adapter, unsigned long req_id) -{ - struct zfcp_fsf_req *request, *tmp; - unsigned int i, counter; - u64 dbg_tmp[2]; - - i = req_id % REQUEST_LIST_SIZE; - BUG_ON(list_empty(&adapter->req_list[i])); - - counter = 0; - list_for_each_entry_safe(request, tmp, &adapter->req_list[i], list) { - if (request->req_id == req_id) { - dbg_tmp[0] = (u64) atomic_read(&adapter->reqs_active); - dbg_tmp[1] = (u64) counter; - debug_event(adapter->erp_dbf, 4, (void *) dbg_tmp, 16); - list_del(&request->list); - break; - } - counter++; - } -} - -struct zfcp_fsf_req *zfcp_reqlist_ismember(struct zfcp_adapter *adapter, - unsigned long req_id) -{ - struct zfcp_fsf_req *request, *tmp; - unsigned int i; - - i = req_id % REQUEST_LIST_SIZE; - - list_for_each_entry_safe(request, tmp, &adapter->req_list[i], list) - if (request->req_id == req_id) - return request; - - return NULL; -} - -int zfcp_reqlist_isempty(struct zfcp_adapter *adapter) -{ - unsigned int i; - - for (i=0; ireq_list[i])) - return 0; - - return 1; -} - -#undef ZFCP_LOG_AREA - /****************************************************************/ /************** Uncategorised Functions *************************/ /****************************************************************/ @@ -1060,12 +961,8 @@ zfcp_adapter_enqueue(struct ccw_device *ccw_device) INIT_LIST_HEAD(&adapter->port_remove_lh); /* initialize list of fsf requests */ - spin_lock_init(&adapter->req_list_lock); - retval = zfcp_reqlist_init(adapter); - if (retval) { - ZFCP_LOG_INFO("request list initialization failed\n"); - goto failed_low_mem_buffers; - } + spin_lock_init(&adapter->fsf_req_list_lock); + INIT_LIST_HEAD(&adapter->fsf_req_list_head); /* initialize debug locks */ @@ -1144,6 +1041,8 @@ zfcp_adapter_enqueue(struct ccw_device *ccw_device) * !0 - struct zfcp_adapter data structure could not be removed * (e.g. still used) * locks: adapter list write lock is assumed to be held by caller + * adapter->fsf_req_list_lock is taken and released within this + * function and must not be held on entry */ void zfcp_adapter_dequeue(struct zfcp_adapter *adapter) @@ -1155,14 +1054,14 @@ zfcp_adapter_dequeue(struct zfcp_adapter *adapter) zfcp_sysfs_adapter_remove_files(&adapter->ccw_device->dev); dev_set_drvdata(&adapter->ccw_device->dev, NULL); /* sanity check: no pending FSF requests */ - spin_lock_irqsave(&adapter->req_list_lock, flags); - retval = zfcp_reqlist_isempty(adapter); - spin_unlock_irqrestore(&adapter->req_list_lock, flags); - if (!retval) { + spin_lock_irqsave(&adapter->fsf_req_list_lock, flags); + retval = !list_empty(&adapter->fsf_req_list_head); + spin_unlock_irqrestore(&adapter->fsf_req_list_lock, flags); + if (retval) { ZFCP_LOG_NORMAL("bug: adapter %s (%p) still in use, " "%i requests outstanding\n", zfcp_get_busid_by_adapter(adapter), adapter, - atomic_read(&adapter->reqs_active)); + atomic_read(&adapter->fsf_reqs_active)); retval = -EBUSY; goto out; } @@ -1188,7 +1087,6 @@ zfcp_adapter_dequeue(struct zfcp_adapter *adapter) zfcp_free_low_mem_buffers(adapter); /* free memory of adapter data structure and queues */ zfcp_qdio_free_queues(adapter); - zfcp_reqlist_free(adapter); kfree(adapter->fc_stats); kfree(adapter->stats_reset_data); ZFCP_LOG_TRACE("freeing adapter structure\n"); diff --git a/trunk/drivers/s390/scsi/zfcp_ccw.c b/trunk/drivers/s390/scsi/zfcp_ccw.c index fdabadeaa9ee..57d8e4bfb8d9 100644 --- a/trunk/drivers/s390/scsi/zfcp_ccw.c +++ b/trunk/drivers/s390/scsi/zfcp_ccw.c @@ -164,11 +164,6 @@ zfcp_ccw_set_online(struct ccw_device *ccw_device) retval = zfcp_adapter_scsi_register(adapter); if (retval) goto out_scsi_register; - - /* initialize request counter */ - BUG_ON(!zfcp_reqlist_isempty(adapter)); - adapter->req_no = 0; - zfcp_erp_modify_adapter_status(adapter, ZFCP_STATUS_COMMON_RUNNING, ZFCP_SET); zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED); diff --git a/trunk/drivers/s390/scsi/zfcp_def.h b/trunk/drivers/s390/scsi/zfcp_def.h index 94d1b74db356..2df512a18e2c 100644 --- a/trunk/drivers/s390/scsi/zfcp_def.h +++ b/trunk/drivers/s390/scsi/zfcp_def.h @@ -52,7 +52,7 @@ /********************* GENERAL DEFINES *********************************/ /* zfcp version number, it consists of major, minor, and patch-level number */ -#define ZFCP_VERSION "4.8.0" +#define ZFCP_VERSION "4.7.0" /** * zfcp_sg_to_address - determine kernel address from struct scatterlist @@ -80,7 +80,7 @@ zfcp_address_to_sg(void *address, struct scatterlist *list) #define REQUEST_LIST_SIZE 128 /********************* SCSI SPECIFIC DEFINES *********************************/ -#define ZFCP_SCSI_ER_TIMEOUT (10*HZ) +#define ZFCP_SCSI_ER_TIMEOUT (100*HZ) /********************* CIO/QDIO SPECIFIC DEFINES *****************************/ @@ -886,11 +886,11 @@ struct zfcp_adapter { struct list_head port_remove_lh; /* head of ports to be removed */ u32 ports; /* number of remote ports */ - struct timer_list scsi_er_timer; /* SCSI err recovery watch */ - atomic_t reqs_active; /* # active FSF reqs */ - unsigned long req_no; /* unique FSF req number */ - struct list_head *req_list; /* list of pending reqs */ - spinlock_t req_list_lock; /* request list lock */ + struct timer_list scsi_er_timer; /* SCSI err recovery watch */ + struct list_head fsf_req_list_head; /* head of FSF req list */ + spinlock_t fsf_req_list_lock; /* lock for ops on list of + FSF requests */ + atomic_t fsf_reqs_active; /* # active FSF reqs */ struct zfcp_qdio_queue request_queue; /* request queue */ u32 fsf_req_seq_no; /* FSF cmnd seq number */ wait_queue_head_t request_wq; /* can be used to wait for @@ -986,7 +986,6 @@ struct zfcp_unit { /* FSF request */ struct zfcp_fsf_req { struct list_head list; /* list of FSF requests */ - unsigned long req_id; /* unique request ID */ struct zfcp_adapter *adapter; /* adapter request belongs to */ u8 sbal_number; /* nr of SBALs free for use */ u8 sbal_first; /* first SBAL for this request */ diff --git a/trunk/drivers/s390/scsi/zfcp_erp.c b/trunk/drivers/s390/scsi/zfcp_erp.c index 7f60b6fdf724..8ec8da0beaa8 100644 --- a/trunk/drivers/s390/scsi/zfcp_erp.c +++ b/trunk/drivers/s390/scsi/zfcp_erp.c @@ -64,8 +64,8 @@ static int zfcp_erp_strategy_check_action(struct zfcp_erp_action *, int); static int zfcp_erp_adapter_strategy(struct zfcp_erp_action *); static int zfcp_erp_adapter_strategy_generic(struct zfcp_erp_action *, int); static int zfcp_erp_adapter_strategy_close(struct zfcp_erp_action *); -static void zfcp_erp_adapter_strategy_close_qdio(struct zfcp_erp_action *); -static void zfcp_erp_adapter_strategy_close_fsf(struct zfcp_erp_action *); +static int zfcp_erp_adapter_strategy_close_qdio(struct zfcp_erp_action *); +static int zfcp_erp_adapter_strategy_close_fsf(struct zfcp_erp_action *); static int zfcp_erp_adapter_strategy_open(struct zfcp_erp_action *); static int zfcp_erp_adapter_strategy_open_qdio(struct zfcp_erp_action *); static int zfcp_erp_adapter_strategy_open_fsf(struct zfcp_erp_action *); @@ -93,9 +93,10 @@ static int zfcp_erp_unit_strategy_clearstati(struct zfcp_unit *); static int zfcp_erp_unit_strategy_close(struct zfcp_erp_action *); static int zfcp_erp_unit_strategy_open(struct zfcp_erp_action *); -static void zfcp_erp_action_dismiss_port(struct zfcp_port *); -static void zfcp_erp_action_dismiss_unit(struct zfcp_unit *); -static void zfcp_erp_action_dismiss(struct zfcp_erp_action *); +static int zfcp_erp_action_dismiss_adapter(struct zfcp_adapter *); +static int zfcp_erp_action_dismiss_port(struct zfcp_port *); +static int zfcp_erp_action_dismiss_unit(struct zfcp_unit *); +static int zfcp_erp_action_dismiss(struct zfcp_erp_action *); static int zfcp_erp_action_enqueue(int, struct zfcp_adapter *, struct zfcp_port *, struct zfcp_unit *); @@ -134,39 +135,29 @@ zfcp_fsf_request_timeout_handler(unsigned long data) zfcp_erp_adapter_reopen(adapter, 0); } -/** - * zfcp_fsf_scsi_er_timeout_handler - timeout handler for scsi eh tasks - * - * This function needs to be called whenever a SCSI error recovery - * action (abort/reset) does not return. Re-opening the adapter means - * that the abort/reset command can be returned by zfcp. It won't complete - * via the adapter anymore (because qdio queues are closed). If ERP is - * already running on this adapter it will be stopped. +/* + * function: zfcp_fsf_scsi_er_timeout_handler + * + * purpose: This function needs to be called whenever a SCSI error recovery + * action (abort/reset) does not return. + * Re-opening the adapter means that the command can be returned + * by zfcp (it is guarranteed that it does not return via the + * adapter anymore). The buffer can then be used again. + * + * returns: sod all */ -void zfcp_fsf_scsi_er_timeout_handler(unsigned long data) +void +zfcp_fsf_scsi_er_timeout_handler(unsigned long data) { struct zfcp_adapter *adapter = (struct zfcp_adapter *) data; - unsigned long flags; ZFCP_LOG_NORMAL("warning: SCSI error recovery timed out. " "Restarting all operations on the adapter %s\n", zfcp_get_busid_by_adapter(adapter)); debug_text_event(adapter->erp_dbf, 1, "eh_lmem_tout"); - - write_lock_irqsave(&adapter->erp_lock, flags); - if (atomic_test_mask(ZFCP_STATUS_ADAPTER_ERP_PENDING, - &adapter->status)) { - zfcp_erp_modify_adapter_status(adapter, - ZFCP_STATUS_COMMON_UNBLOCKED|ZFCP_STATUS_COMMON_OPEN, - ZFCP_CLEAR); - zfcp_erp_action_dismiss_adapter(adapter); - write_unlock_irqrestore(&adapter->erp_lock, flags); - /* dismiss all pending requests including requests for ERP */ - zfcp_fsf_req_dismiss_all(adapter); - adapter->fsf_req_seq_no = 0; - } else - write_unlock_irqrestore(&adapter->erp_lock, flags); zfcp_erp_adapter_reopen(adapter, 0); + + return; } /* @@ -679,10 +670,17 @@ zfcp_erp_unit_reopen(struct zfcp_unit *unit, int clear_mask) return retval; } -/** - * zfcp_erp_adapter_block - mark adapter as blocked, block scsi requests +/* + * function: + * + * purpose: disable I/O, + * return any open requests and clean them up, + * aim: no pending and incoming I/O + * + * returns: */ -static void zfcp_erp_adapter_block(struct zfcp_adapter *adapter, int clear_mask) +static void +zfcp_erp_adapter_block(struct zfcp_adapter *adapter, int clear_mask) { debug_text_event(adapter->erp_dbf, 6, "a_bl"); zfcp_erp_modify_adapter_status(adapter, @@ -690,10 +688,15 @@ static void zfcp_erp_adapter_block(struct zfcp_adapter *adapter, int clear_mask) clear_mask, ZFCP_CLEAR); } -/** - * zfcp_erp_adapter_unblock - mark adapter as unblocked, allow scsi requests +/* + * function: + * + * purpose: enable I/O + * + * returns: */ -static void zfcp_erp_adapter_unblock(struct zfcp_adapter *adapter) +static void +zfcp_erp_adapter_unblock(struct zfcp_adapter *adapter) { debug_text_event(adapter->erp_dbf, 6, "a_ubl"); atomic_set_mask(ZFCP_STATUS_COMMON_UNBLOCKED, &adapter->status); @@ -845,16 +848,18 @@ zfcp_erp_strategy_check_fsfreq(struct zfcp_erp_action *erp_action) struct zfcp_adapter *adapter = erp_action->adapter; if (erp_action->fsf_req) { - /* take lock to ensure that request is not deleted meanwhile */ - spin_lock(&adapter->req_list_lock); - if ((!zfcp_reqlist_ismember(adapter, - erp_action->fsf_req->req_id)) && - (fsf_req->erp_action == erp_action)) { + /* take lock to ensure that request is not being deleted meanwhile */ + spin_lock(&adapter->fsf_req_list_lock); + /* check whether fsf req does still exist */ + list_for_each_entry(fsf_req, &adapter->fsf_req_list_head, list) + if (fsf_req == erp_action->fsf_req) + break; + if (fsf_req && (fsf_req->erp_action == erp_action)) { /* fsf_req still exists */ debug_text_event(adapter->erp_dbf, 3, "a_ca_req"); debug_event(adapter->erp_dbf, 3, &fsf_req, sizeof (unsigned long)); - /* dismiss fsf_req of timed out/dismissed erp_action */ + /* dismiss fsf_req of timed out or dismissed erp_action */ if (erp_action->status & (ZFCP_STATUS_ERP_DISMISSED | ZFCP_STATUS_ERP_TIMEDOUT)) { debug_text_event(adapter->erp_dbf, 3, @@ -887,22 +892,30 @@ zfcp_erp_strategy_check_fsfreq(struct zfcp_erp_action *erp_action) */ erp_action->fsf_req = NULL; } - spin_unlock(&adapter->req_list_lock); + spin_unlock(&adapter->fsf_req_list_lock); } else debug_text_event(adapter->erp_dbf, 3, "a_ca_noreq"); return retval; } -/** - * zfcp_erp_async_handler_nolock - complete erp_action +/* + * purpose: generic handler for asynchronous events related to erp_action events + * (normal completion, time-out, dismissing, retry after + * low memory condition) + * + * note: deletion of timer is not required (e.g. in case of a time-out), + * but a second try does no harm, + * we leave it in here to allow for greater simplification * - * Used for normal completion, time-out, dismissal and failure after - * low memory condition. + * returns: 0 - there was an action to handle + * !0 - otherwise */ -static void zfcp_erp_async_handler_nolock(struct zfcp_erp_action *erp_action, - unsigned long set_mask) +static int +zfcp_erp_async_handler_nolock(struct zfcp_erp_action *erp_action, + unsigned long set_mask) { + int retval; struct zfcp_adapter *adapter = erp_action->adapter; if (zfcp_erp_action_exists(erp_action) == ZFCP_ERP_ACTION_RUNNING) { @@ -913,26 +926,43 @@ static void zfcp_erp_async_handler_nolock(struct zfcp_erp_action *erp_action, del_timer(&erp_action->timer); erp_action->status |= set_mask; zfcp_erp_action_ready(erp_action); + retval = 0; } else { /* action is ready or gone - nothing to do */ debug_text_event(adapter->erp_dbf, 3, "a_asyh_gone"); debug_event(adapter->erp_dbf, 3, &erp_action->action, sizeof (int)); + retval = 1; } + + return retval; } -/** - * zfcp_erp_async_handler - wrapper for erp_async_handler_nolock w/ locking +/* + * purpose: generic handler for asynchronous events related to erp_action + * events (normal completion, time-out, dismissing, retry after + * low memory condition) + * + * note: deletion of timer is not required (e.g. in case of a time-out), + * but a second try does no harm, + * we leave it in here to allow for greater simplification + * + * returns: 0 - there was an action to handle + * !0 - otherwise */ -void zfcp_erp_async_handler(struct zfcp_erp_action *erp_action, - unsigned long set_mask) +int +zfcp_erp_async_handler(struct zfcp_erp_action *erp_action, + unsigned long set_mask) { struct zfcp_adapter *adapter = erp_action->adapter; unsigned long flags; + int retval; write_lock_irqsave(&adapter->erp_lock, flags); - zfcp_erp_async_handler_nolock(erp_action, set_mask); + retval = zfcp_erp_async_handler_nolock(erp_action, set_mask); write_unlock_irqrestore(&adapter->erp_lock, flags); + + return retval; } /* @@ -969,15 +999,17 @@ zfcp_erp_timeout_handler(unsigned long data) zfcp_erp_async_handler(erp_action, ZFCP_STATUS_ERP_TIMEDOUT); } -/** - * zfcp_erp_action_dismiss - dismiss an erp_action +/* + * purpose: is called for an erp_action which needs to be ended + * though not being done, + * this is usually required if an higher is generated, + * action gets an appropriate flag and will be processed + * accordingly * - * adapter->erp_lock must be held - * - * Dismissal of an erp_action is usually required if an erp_action of - * higher priority is generated. + * locks: erp_lock held (thus we need to call another handler variant) */ -static void zfcp_erp_action_dismiss(struct zfcp_erp_action *erp_action) +static int +zfcp_erp_action_dismiss(struct zfcp_erp_action *erp_action) { struct zfcp_adapter *adapter = erp_action->adapter; @@ -985,6 +1017,8 @@ static void zfcp_erp_action_dismiss(struct zfcp_erp_action *erp_action) debug_event(adapter->erp_dbf, 2, &erp_action->action, sizeof (int)); zfcp_erp_async_handler_nolock(erp_action, ZFCP_STATUS_ERP_DISMISSED); + + return 0; } int @@ -2040,12 +2074,18 @@ zfcp_erp_adapter_strategy_open_qdio(struct zfcp_erp_action *erp_action) return retval; } -/** - * zfcp_erp_adapter_strategy_close_qdio - close qdio queues for an adapter +/* + * function: zfcp_qdio_cleanup + * + * purpose: cleans up QDIO operation for the specified adapter + * + * returns: 0 - successful cleanup + * !0 - failed cleanup */ -static void +int zfcp_erp_adapter_strategy_close_qdio(struct zfcp_erp_action *erp_action) { + int retval = ZFCP_ERP_SUCCEEDED; int first_used; int used_count; struct zfcp_adapter *adapter = erp_action->adapter; @@ -2054,13 +2094,15 @@ zfcp_erp_adapter_strategy_close_qdio(struct zfcp_erp_action *erp_action) ZFCP_LOG_DEBUG("error: attempt to shut down inactive QDIO " "queues on adapter %s\n", zfcp_get_busid_by_adapter(adapter)); - return; + retval = ZFCP_ERP_FAILED; + goto out; } /* * Get queue_lock and clear QDIOUP flag. Thus it's guaranteed that * do_QDIO won't be called while qdio_shutdown is in progress. */ + write_lock_irq(&adapter->request_queue.queue_lock); atomic_clear_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status); write_unlock_irq(&adapter->request_queue.queue_lock); @@ -2092,6 +2134,8 @@ zfcp_erp_adapter_strategy_close_qdio(struct zfcp_erp_action *erp_action) adapter->request_queue.free_index = 0; atomic_set(&adapter->request_queue.free_count, 0); adapter->request_queue.distance_from_int = 0; + out: + return retval; } static int @@ -2214,11 +2258,11 @@ zfcp_erp_adapter_strategy_open_fsf_xport(struct zfcp_erp_action *erp_action) "%s)\n", zfcp_get_busid_by_adapter(adapter)); ret = ZFCP_ERP_FAILED; } - - /* don't treat as error for the sake of compatibility */ - if (!atomic_test_mask(ZFCP_STATUS_ADAPTER_XPORT_OK, &adapter->status)) - ZFCP_LOG_INFO("warning: exchange port data failed (adapter " + if (!atomic_test_mask(ZFCP_STATUS_ADAPTER_XPORT_OK, &adapter->status)) { + ZFCP_LOG_INFO("error: exchange port data failed (adapter " "%s\n", zfcp_get_busid_by_adapter(adapter)); + ret = ZFCP_ERP_FAILED; + } return ret; } @@ -2248,12 +2292,18 @@ zfcp_erp_adapter_strategy_open_fsf_statusread(struct zfcp_erp_action return retval; } -/** - * zfcp_erp_adapter_strategy_close_fsf - stop FSF operations for an adapter +/* + * function: zfcp_fsf_cleanup + * + * purpose: cleanup FSF operation for specified adapter + * + * returns: 0 - FSF operation successfully cleaned up + * !0 - failed to cleanup FSF operation for this adapter */ -static void +static int zfcp_erp_adapter_strategy_close_fsf(struct zfcp_erp_action *erp_action) { + int retval = ZFCP_ERP_SUCCEEDED; struct zfcp_adapter *adapter = erp_action->adapter; /* @@ -2267,6 +2317,8 @@ zfcp_erp_adapter_strategy_close_fsf(struct zfcp_erp_action *erp_action) /* all ports and units are closed */ zfcp_erp_modify_adapter_status(adapter, ZFCP_STATUS_COMMON_OPEN, ZFCP_CLEAR); + + return retval; } /* @@ -3241,8 +3293,10 @@ zfcp_erp_action_cleanup(int action, struct zfcp_adapter *adapter, } -void zfcp_erp_action_dismiss_adapter(struct zfcp_adapter *adapter) +static int +zfcp_erp_action_dismiss_adapter(struct zfcp_adapter *adapter) { + int retval = 0; struct zfcp_port *port; debug_text_event(adapter->erp_dbf, 5, "a_actab"); @@ -3251,10 +3305,14 @@ void zfcp_erp_action_dismiss_adapter(struct zfcp_adapter *adapter) else list_for_each_entry(port, &adapter->port_list_head, list) zfcp_erp_action_dismiss_port(port); + + return retval; } -static void zfcp_erp_action_dismiss_port(struct zfcp_port *port) +static int +zfcp_erp_action_dismiss_port(struct zfcp_port *port) { + int retval = 0; struct zfcp_unit *unit; struct zfcp_adapter *adapter = port->adapter; @@ -3265,16 +3323,22 @@ static void zfcp_erp_action_dismiss_port(struct zfcp_port *port) else list_for_each_entry(unit, &port->unit_list_head, list) zfcp_erp_action_dismiss_unit(unit); + + return retval; } -static void zfcp_erp_action_dismiss_unit(struct zfcp_unit *unit) +static int +zfcp_erp_action_dismiss_unit(struct zfcp_unit *unit) { + int retval = 0; struct zfcp_adapter *adapter = unit->port->adapter; debug_text_event(adapter->erp_dbf, 5, "u_actab"); debug_event(adapter->erp_dbf, 5, &unit->fcp_lun, sizeof (fcp_lun_t)); if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &unit->status)) zfcp_erp_action_dismiss(&unit->erp_action); + + return retval; } static inline void diff --git a/trunk/drivers/s390/scsi/zfcp_ext.h b/trunk/drivers/s390/scsi/zfcp_ext.h index 146d7a2b4c4a..d02366004cdd 100644 --- a/trunk/drivers/s390/scsi/zfcp_ext.h +++ b/trunk/drivers/s390/scsi/zfcp_ext.h @@ -63,6 +63,7 @@ extern int zfcp_qdio_allocate_queues(struct zfcp_adapter *); extern void zfcp_qdio_free_queues(struct zfcp_adapter *); extern int zfcp_qdio_determine_pci(struct zfcp_qdio_queue *, struct zfcp_fsf_req *); +extern int zfcp_qdio_reqid_check(struct zfcp_adapter *, void *); extern volatile struct qdio_buffer_element *zfcp_qdio_sbale_req (struct zfcp_fsf_req *, int, int); @@ -139,7 +140,6 @@ extern void zfcp_erp_modify_adapter_status(struct zfcp_adapter *, u32, int); extern int zfcp_erp_adapter_reopen(struct zfcp_adapter *, int); extern int zfcp_erp_adapter_shutdown(struct zfcp_adapter *, int); extern void zfcp_erp_adapter_failed(struct zfcp_adapter *); -extern void zfcp_erp_action_dismiss_adapter(struct zfcp_adapter *); extern void zfcp_erp_modify_port_status(struct zfcp_port *, u32, int); extern int zfcp_erp_port_reopen(struct zfcp_port *, int); @@ -156,7 +156,7 @@ extern void zfcp_erp_unit_failed(struct zfcp_unit *); extern int zfcp_erp_thread_setup(struct zfcp_adapter *); extern int zfcp_erp_thread_kill(struct zfcp_adapter *); extern int zfcp_erp_wait(struct zfcp_adapter *); -extern void zfcp_erp_async_handler(struct zfcp_erp_action *, unsigned long); +extern int zfcp_erp_async_handler(struct zfcp_erp_action *, unsigned long); extern int zfcp_test_link(struct zfcp_port *); @@ -190,10 +190,5 @@ extern void zfcp_scsi_dbf_event_abort(const char *, struct zfcp_adapter *, struct zfcp_fsf_req *); extern void zfcp_scsi_dbf_event_devreset(const char *, u8, struct zfcp_unit *, struct scsi_cmnd *); -extern void zfcp_reqlist_add(struct zfcp_adapter *, struct zfcp_fsf_req *); -extern void zfcp_reqlist_remove(struct zfcp_adapter *, unsigned long); -extern struct zfcp_fsf_req *zfcp_reqlist_ismember(struct zfcp_adapter *, - unsigned long); -extern int zfcp_reqlist_isempty(struct zfcp_adapter *); #endif /* ZFCP_EXT_H */ diff --git a/trunk/drivers/s390/scsi/zfcp_fsf.c b/trunk/drivers/s390/scsi/zfcp_fsf.c index ff2eacf5ec8c..31db2b06faba 100644 --- a/trunk/drivers/s390/scsi/zfcp_fsf.c +++ b/trunk/drivers/s390/scsi/zfcp_fsf.c @@ -49,6 +49,7 @@ static int zfcp_fsf_fsfstatus_qual_eval(struct zfcp_fsf_req *); static void zfcp_fsf_link_down_info_eval(struct zfcp_adapter *, struct fsf_link_down_info *); static int zfcp_fsf_req_dispatch(struct zfcp_fsf_req *); +static void zfcp_fsf_req_dismiss(struct zfcp_fsf_req *); /* association between FSF command and FSF QTCB type */ static u32 fsf_qtcb_type[] = { @@ -145,50 +146,49 @@ zfcp_fsf_req_free(struct zfcp_fsf_req *fsf_req) kfree(fsf_req); } -/** - * zfcp_fsf_req_dismiss - dismiss a single fsf request +/* + * function: + * + * purpose: + * + * returns: + * + * note: qdio queues shall be down (no ongoing inbound processing) */ -static void zfcp_fsf_req_dismiss(struct zfcp_adapter *adapter, - struct zfcp_fsf_req *fsf_req, - unsigned int counter) +int +zfcp_fsf_req_dismiss_all(struct zfcp_adapter *adapter) { - u64 dbg_tmp[2]; + struct zfcp_fsf_req *fsf_req, *tmp; + unsigned long flags; + LIST_HEAD(remove_queue); - dbg_tmp[0] = (u64) atomic_read(&adapter->reqs_active); - dbg_tmp[1] = (u64) counter; - debug_event(adapter->erp_dbf, 4, (void *) dbg_tmp, 16); - list_del(&fsf_req->list); - fsf_req->status |= ZFCP_STATUS_FSFREQ_DISMISSED; - zfcp_fsf_req_complete(fsf_req); -} + spin_lock_irqsave(&adapter->fsf_req_list_lock, flags); + list_splice_init(&adapter->fsf_req_list_head, &remove_queue); + atomic_set(&adapter->fsf_reqs_active, 0); + spin_unlock_irqrestore(&adapter->fsf_req_list_lock, flags); -/** - * zfcp_fsf_req_dismiss_all - dismiss all remaining fsf requests - */ -int zfcp_fsf_req_dismiss_all(struct zfcp_adapter *adapter) -{ - struct zfcp_fsf_req *request, *tmp; - unsigned long flags; - unsigned int i, counter; - - spin_lock_irqsave(&adapter->req_list_lock, flags); - atomic_set(&adapter->reqs_active, 0); - for (i=0; ireq_list[i])) - continue; - - counter = 0; - list_for_each_entry_safe(request, tmp, - &adapter->req_list[i], list) { - zfcp_fsf_req_dismiss(adapter, request, counter); - counter++; - } + list_for_each_entry_safe(fsf_req, tmp, &remove_queue, list) { + list_del(&fsf_req->list); + zfcp_fsf_req_dismiss(fsf_req); } - spin_unlock_irqrestore(&adapter->req_list_lock, flags); return 0; } +/* + * function: + * + * purpose: + * + * returns: + */ +static void +zfcp_fsf_req_dismiss(struct zfcp_fsf_req *fsf_req) +{ + fsf_req->status |= ZFCP_STATUS_FSFREQ_DISMISSED; + zfcp_fsf_req_complete(fsf_req); +} + /* * function: zfcp_fsf_req_complete * @@ -4592,14 +4592,12 @@ static inline void zfcp_fsf_req_qtcb_init(struct zfcp_fsf_req *fsf_req) { if (likely(fsf_req->qtcb != NULL)) { - fsf_req->qtcb->prefix.req_seq_no = - fsf_req->adapter->fsf_req_seq_no; - fsf_req->qtcb->prefix.req_id = fsf_req->req_id; + fsf_req->qtcb->prefix.req_seq_no = fsf_req->adapter->fsf_req_seq_no; + fsf_req->qtcb->prefix.req_id = (unsigned long)fsf_req; fsf_req->qtcb->prefix.ulp_info = ZFCP_ULP_INFO_VERSION; - fsf_req->qtcb->prefix.qtcb_type = - fsf_qtcb_type[fsf_req->fsf_command]; + fsf_req->qtcb->prefix.qtcb_type = fsf_qtcb_type[fsf_req->fsf_command]; fsf_req->qtcb->prefix.qtcb_version = ZFCP_QTCB_VERSION; - fsf_req->qtcb->header.req_handle = fsf_req->req_id; + fsf_req->qtcb->header.req_handle = (unsigned long)fsf_req; fsf_req->qtcb->header.fsf_command = fsf_req->fsf_command; } } @@ -4656,7 +4654,6 @@ zfcp_fsf_req_create(struct zfcp_adapter *adapter, u32 fsf_cmd, int req_flags, { volatile struct qdio_buffer_element *sbale; struct zfcp_fsf_req *fsf_req = NULL; - unsigned long flags; int ret = 0; struct zfcp_qdio_queue *req_queue = &adapter->request_queue; @@ -4671,12 +4668,6 @@ zfcp_fsf_req_create(struct zfcp_adapter *adapter, u32 fsf_cmd, int req_flags, fsf_req->adapter = adapter; fsf_req->fsf_command = fsf_cmd; - INIT_LIST_HEAD(&fsf_req->list); - - /* unique request id */ - spin_lock_irqsave(&adapter->req_list_lock, flags); - fsf_req->req_id = adapter->req_no++; - spin_unlock_irqrestore(&adapter->req_list_lock, flags); zfcp_fsf_req_qtcb_init(fsf_req); @@ -4716,7 +4707,7 @@ zfcp_fsf_req_create(struct zfcp_adapter *adapter, u32 fsf_cmd, int req_flags, sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_curr, 0); /* setup common SBALE fields */ - sbale[0].addr = (void *) fsf_req->req_id; + sbale[0].addr = fsf_req; sbale[0].flags |= SBAL_FLAGS0_COMMAND; if (likely(fsf_req->qtcb != NULL)) { sbale[1].addr = (void *) fsf_req->qtcb; @@ -4756,7 +4747,7 @@ zfcp_fsf_req_send(struct zfcp_fsf_req *fsf_req, struct timer_list *timer) volatile struct qdio_buffer_element *sbale; int inc_seq_no; int new_distance_from_int; - u64 dbg_tmp[2]; + unsigned long flags; int retval = 0; adapter = fsf_req->adapter; @@ -4770,10 +4761,10 @@ zfcp_fsf_req_send(struct zfcp_fsf_req *fsf_req, struct timer_list *timer) ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_TRACE, (char *) sbale[1].addr, sbale[1].length); - /* put allocated FSF request into hash table */ - spin_lock(&adapter->req_list_lock); - zfcp_reqlist_add(adapter, fsf_req); - spin_unlock(&adapter->req_list_lock); + /* put allocated FSF request at list tail */ + spin_lock_irqsave(&adapter->fsf_req_list_lock, flags); + list_add_tail(&fsf_req->list, &adapter->fsf_req_list_head); + spin_unlock_irqrestore(&adapter->fsf_req_list_lock, flags); inc_seq_no = (fsf_req->qtcb != NULL); @@ -4812,10 +4803,6 @@ zfcp_fsf_req_send(struct zfcp_fsf_req *fsf_req, struct timer_list *timer) QDIO_FLAG_SYNC_OUTPUT, 0, fsf_req->sbal_first, fsf_req->sbal_number, NULL); - dbg_tmp[0] = (unsigned long) sbale[0].addr; - dbg_tmp[1] = (u64) retval; - debug_event(adapter->erp_dbf, 4, (void *) dbg_tmp, 16); - if (unlikely(retval)) { /* Queues are down..... */ retval = -EIO; @@ -4825,17 +4812,22 @@ zfcp_fsf_req_send(struct zfcp_fsf_req *fsf_req, struct timer_list *timer) */ if (timer) del_timer(timer); - spin_lock(&adapter->req_list_lock); - zfcp_reqlist_remove(adapter, fsf_req->req_id); - spin_unlock(&adapter->req_list_lock); - /* undo changes in request queue made for this request */ + spin_lock_irqsave(&adapter->fsf_req_list_lock, flags); + list_del(&fsf_req->list); + spin_unlock_irqrestore(&adapter->fsf_req_list_lock, flags); + /* + * adjust the number of free SBALs in request queue as well as + * position of first one + */ zfcp_qdio_zero_sbals(req_queue->buffer, fsf_req->sbal_first, fsf_req->sbal_number); atomic_add(fsf_req->sbal_number, &req_queue->free_count); - req_queue->free_index -= fsf_req->sbal_number; + req_queue->free_index -= fsf_req->sbal_number; /* increase */ req_queue->free_index += QDIO_MAX_BUFFERS_PER_Q; req_queue->free_index %= QDIO_MAX_BUFFERS_PER_Q; /* wrap */ - zfcp_erp_adapter_reopen(adapter, 0); + ZFCP_LOG_DEBUG + ("error: do_QDIO failed. Buffers could not be enqueued " + "to request queue.\n"); } else { req_queue->distance_from_int = new_distance_from_int; /* @@ -4851,7 +4843,7 @@ zfcp_fsf_req_send(struct zfcp_fsf_req *fsf_req, struct timer_list *timer) adapter->fsf_req_seq_no++; /* count FSF requests pending */ - atomic_inc(&adapter->reqs_active); + atomic_inc(&adapter->fsf_reqs_active); } return retval; } diff --git a/trunk/drivers/s390/scsi/zfcp_qdio.c b/trunk/drivers/s390/scsi/zfcp_qdio.c index dbd9f48e863e..49ea5add4abc 100644 --- a/trunk/drivers/s390/scsi/zfcp_qdio.c +++ b/trunk/drivers/s390/scsi/zfcp_qdio.c @@ -282,37 +282,6 @@ zfcp_qdio_request_handler(struct ccw_device *ccw_device, return; } -/** - * zfcp_qdio_reqid_check - checks for valid reqids or unsolicited status - */ -static int zfcp_qdio_reqid_check(struct zfcp_adapter *adapter, - unsigned long req_id) -{ - struct zfcp_fsf_req *fsf_req; - unsigned long flags; - - debug_long_event(adapter->erp_dbf, 4, req_id); - - spin_lock_irqsave(&adapter->req_list_lock, flags); - fsf_req = zfcp_reqlist_ismember(adapter, req_id); - - if (!fsf_req) { - spin_unlock_irqrestore(&adapter->req_list_lock, flags); - ZFCP_LOG_NORMAL("error: unknown request id (%ld).\n", req_id); - zfcp_erp_adapter_reopen(adapter, 0); - return -EINVAL; - } - - zfcp_reqlist_remove(adapter, req_id); - atomic_dec(&adapter->reqs_active); - spin_unlock_irqrestore(&adapter->req_list_lock, flags); - - /* finish the FSF request */ - zfcp_fsf_req_complete(fsf_req); - - return 0; -} - /* * function: zfcp_qdio_response_handler * @@ -375,7 +344,7 @@ zfcp_qdio_response_handler(struct ccw_device *ccw_device, /* look for QDIO request identifiers in SB */ buffere = &buffer->element[buffere_index]; retval = zfcp_qdio_reqid_check(adapter, - (unsigned long) buffere->addr); + (void *) buffere->addr); if (retval) { ZFCP_LOG_NORMAL("bug: unexpected inbound " @@ -446,6 +415,52 @@ zfcp_qdio_response_handler(struct ccw_device *ccw_device, return; } +/* + * function: zfcp_qdio_reqid_check + * + * purpose: checks for valid reqids or unsolicited status + * + * returns: 0 - valid request id or unsolicited status + * !0 - otherwise + */ +int +zfcp_qdio_reqid_check(struct zfcp_adapter *adapter, void *sbale_addr) +{ + struct zfcp_fsf_req *fsf_req; + unsigned long flags; + + /* invalid (per convention used in this driver) */ + if (unlikely(!sbale_addr)) { + ZFCP_LOG_NORMAL("bug: invalid reqid\n"); + return -EINVAL; + } + + /* valid request id and thus (hopefully :) valid fsf_req address */ + fsf_req = (struct zfcp_fsf_req *) sbale_addr; + + /* serialize with zfcp_fsf_req_dismiss_all */ + spin_lock_irqsave(&adapter->fsf_req_list_lock, flags); + if (list_empty(&adapter->fsf_req_list_head)) { + spin_unlock_irqrestore(&adapter->fsf_req_list_lock, flags); + return 0; + } + list_del(&fsf_req->list); + atomic_dec(&adapter->fsf_reqs_active); + spin_unlock_irqrestore(&adapter->fsf_req_list_lock, flags); + + if (unlikely(adapter != fsf_req->adapter)) { + ZFCP_LOG_NORMAL("bug: invalid reqid (fsf_req=%p, " + "fsf_req->adapter=%p, adapter=%p)\n", + fsf_req, fsf_req->adapter, adapter); + return -EINVAL; + } + + /* finish the FSF request */ + zfcp_fsf_req_complete(fsf_req); + + return 0; +} + /** * zfcp_qdio_sbale_get - return pointer to SBALE of qdio_queue * @queue: queue from which SBALE should be returned diff --git a/trunk/drivers/s390/scsi/zfcp_scsi.c b/trunk/drivers/s390/scsi/zfcp_scsi.c index 1bb55086db9f..671f4a6a5d18 100644 --- a/trunk/drivers/s390/scsi/zfcp_scsi.c +++ b/trunk/drivers/s390/scsi/zfcp_scsi.c @@ -30,6 +30,7 @@ static int zfcp_scsi_queuecommand(struct scsi_cmnd *, void (*done) (struct scsi_cmnd *)); static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *); static int zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *); +static int zfcp_scsi_eh_bus_reset_handler(struct scsi_cmnd *); static int zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *); static int zfcp_task_management_function(struct zfcp_unit *, u8, struct scsi_cmnd *); @@ -45,22 +46,30 @@ struct zfcp_data zfcp_data = { .scsi_host_template = { .name = ZFCP_NAME, .proc_name = "zfcp", + .proc_info = NULL, + .detect = NULL, .slave_alloc = zfcp_scsi_slave_alloc, .slave_configure = zfcp_scsi_slave_configure, .slave_destroy = zfcp_scsi_slave_destroy, .queuecommand = zfcp_scsi_queuecommand, .eh_abort_handler = zfcp_scsi_eh_abort_handler, .eh_device_reset_handler = zfcp_scsi_eh_device_reset_handler, - .eh_bus_reset_handler = zfcp_scsi_eh_host_reset_handler, + .eh_bus_reset_handler = zfcp_scsi_eh_bus_reset_handler, .eh_host_reset_handler = zfcp_scsi_eh_host_reset_handler, .can_queue = 4096, .this_id = -1, + /* + * FIXME: + * one less? can zfcp_create_sbale cope with it? + */ .sg_tablesize = ZFCP_MAX_SBALES_PER_REQ, .cmd_per_lun = 1, + .unchecked_isa_dma = 0, .use_clustering = 1, .sdev_attrs = zfcp_sysfs_sdev_attrs, }, .driver_version = ZFCP_VERSION, + /* rest initialised with zeros */ }; /* Find start of Response Information in FCP response unit*/ @@ -167,14 +176,8 @@ zfcp_scsi_slave_alloc(struct scsi_device *sdp) return retval; } -/** - * zfcp_scsi_slave_destroy - called when scsi device is removed - * - * Remove reference to associated scsi device for an zfcp_unit. - * Mark zfcp_unit as failed. The scsi device might be deleted via sysfs - * or a scan for this device might have failed. - */ -static void zfcp_scsi_slave_destroy(struct scsi_device *sdpnt) +static void +zfcp_scsi_slave_destroy(struct scsi_device *sdpnt) { struct zfcp_unit *unit = (struct zfcp_unit *) sdpnt->hostdata; @@ -182,7 +185,6 @@ static void zfcp_scsi_slave_destroy(struct scsi_device *sdpnt) atomic_clear_mask(ZFCP_STATUS_UNIT_REGISTERED, &unit->status); sdpnt->hostdata = NULL; unit->device = NULL; - zfcp_erp_unit_failed(unit); zfcp_unit_put(unit); } else { ZFCP_LOG_NORMAL("bug: no unit associated with SCSI device at " @@ -547,38 +549,35 @@ zfcp_task_management_function(struct zfcp_unit *unit, u8 tm_flags, } /** - * zfcp_scsi_eh_host_reset_handler - handler for host and bus reset - * - * If ERP is already running it will be stopped. + * zfcp_scsi_eh_bus_reset_handler - reset bus (reopen adapter) */ -int zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *scpnt) +int +zfcp_scsi_eh_bus_reset_handler(struct scsi_cmnd *scpnt) { - struct zfcp_unit *unit; - struct zfcp_adapter *adapter; - unsigned long flags; - - unit = (struct zfcp_unit*) scpnt->device->hostdata; - adapter = unit->port->adapter; + struct zfcp_unit *unit = (struct zfcp_unit*) scpnt->device->hostdata; + struct zfcp_adapter *adapter = unit->port->adapter; - ZFCP_LOG_NORMAL("host/bus reset because of problems with " + ZFCP_LOG_NORMAL("bus reset because of problems with " "unit 0x%016Lx\n", unit->fcp_lun); + zfcp_erp_adapter_reopen(adapter, 0); + zfcp_erp_wait(adapter); - write_lock_irqsave(&adapter->erp_lock, flags); - if (atomic_test_mask(ZFCP_STATUS_ADAPTER_ERP_PENDING, - &adapter->status)) { - zfcp_erp_modify_adapter_status(adapter, - ZFCP_STATUS_COMMON_UNBLOCKED|ZFCP_STATUS_COMMON_OPEN, - ZFCP_CLEAR); - zfcp_erp_action_dismiss_adapter(adapter); - write_unlock_irqrestore(&adapter->erp_lock, flags); - zfcp_fsf_req_dismiss_all(adapter); - adapter->fsf_req_seq_no = 0; - zfcp_erp_adapter_reopen(adapter, 0); - } else { - write_unlock_irqrestore(&adapter->erp_lock, flags); - zfcp_erp_adapter_reopen(adapter, 0); - zfcp_erp_wait(adapter); - } + return SUCCESS; +} + +/** + * zfcp_scsi_eh_host_reset_handler - reset host (reopen adapter) + */ +int +zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *scpnt) +{ + struct zfcp_unit *unit = (struct zfcp_unit*) scpnt->device->hostdata; + struct zfcp_adapter *adapter = unit->port->adapter; + + ZFCP_LOG_NORMAL("host reset because of problems with " + "unit 0x%016Lx\n", unit->fcp_lun); + zfcp_erp_adapter_reopen(adapter, 0); + zfcp_erp_wait(adapter); return SUCCESS; } diff --git a/trunk/drivers/scsi/ata_piix.c b/trunk/drivers/scsi/ata_piix.c index 2d20caf377f5..5e8afc876980 100644 --- a/trunk/drivers/scsi/ata_piix.c +++ b/trunk/drivers/scsi/ata_piix.c @@ -390,8 +390,7 @@ static struct ata_port_info piix_port_info[] = { /* ich5_sata */ { .sht = &piix_sht, - .host_flags = ATA_FLAG_SATA | PIIX_FLAG_CHECKINTR | - PIIX_FLAG_IGNORE_PCS, + .host_flags = ATA_FLAG_SATA | PIIX_FLAG_CHECKINTR, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ .udma_mask = 0x7f, /* udma0-6 */ @@ -468,11 +467,6 @@ MODULE_LICENSE("GPL"); MODULE_DEVICE_TABLE(pci, piix_pci_tbl); MODULE_VERSION(DRV_VERSION); -static int force_pcs = 0; -module_param(force_pcs, int, 0444); -MODULE_PARM_DESC(force_pcs, "force honoring or ignoring PCS to work around " - "device mis-detection (0=default, 1=ignore PCS, 2=honor PCS)"); - /** * piix_pata_cbl_detect - Probe host controller cable detect info * @ap: Port for which cable detect info is desired @@ -537,25 +531,27 @@ static void piix_pata_error_handler(struct ata_port *ap) } /** - * piix_sata_present_mask - determine present mask for SATA host controller + * piix_sata_prereset - prereset for SATA host controller * @ap: Target port * - * Reads SATA PCI device's PCI config register Port Configuration - * and Status (PCS) to determine port and device availability. + * Reads and configures SATA PCI device's PCI config register + * Port Configuration and Status (PCS) to determine port and + * device availability. Return -ENODEV to skip reset if no + * device is present. * * LOCKING: * None (inherited from caller). * * RETURNS: - * determined present_mask + * 0 if device is present, -ENODEV otherwise. */ -static unsigned int piix_sata_present_mask(struct ata_port *ap) +static int piix_sata_prereset(struct ata_port *ap) { struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); struct piix_host_priv *hpriv = ap->host_set->private_data; const unsigned int *map = hpriv->map; int base = 2 * ap->hard_port_no; - unsigned int present_mask = 0; + unsigned int present = 0; int port, i; u16 pcs; @@ -568,52 +564,24 @@ static unsigned int piix_sata_present_mask(struct ata_port *ap) continue; if ((ap->flags & PIIX_FLAG_IGNORE_PCS) || (pcs & 1 << (hpriv->map_db->present_shift + port))) - present_mask |= 1 << i; + present = 1; } - DPRINTK("ata%u: LEAVE, pcs=0x%x present_mask=0x%x\n", - ap->id, pcs, present_mask); - - return present_mask; -} - -/** - * piix_sata_softreset - reset SATA host port via ATA SRST - * @ap: port to reset - * @classes: resulting classes of attached devices - * - * Reset SATA host port via ATA SRST. On controllers with - * reliable PCS present bits, the bits are used to determine - * device presence. - * - * LOCKING: - * Kernel thread context (may sleep) - * - * RETURNS: - * 0 on success, -errno otherwise. - */ -static int piix_sata_softreset(struct ata_port *ap, unsigned int *classes) -{ - unsigned int present_mask; - int i, rc; - - present_mask = piix_sata_present_mask(ap); - - rc = ata_std_softreset(ap, classes); - if (rc) - return rc; + DPRINTK("ata%u: LEAVE, pcs=0x%x present=0x%x\n", + ap->id, pcs, present); - for (i = 0; i < ATA_MAX_DEVICES; i++) { - if (!(present_mask & (1 << i))) - classes[i] = ATA_DEV_NONE; + if (!present) { + ata_port_printk(ap, KERN_INFO, "SATA port has no device.\n"); + ap->eh_context.i.action &= ~ATA_EH_RESET_MASK; + return 0; } - return 0; + return ata_std_prereset(ap); } static void piix_sata_error_handler(struct ata_port *ap) { - ata_bmdma_drive_eh(ap, ata_std_prereset, piix_sata_softreset, NULL, + ata_bmdma_drive_eh(ap, piix_sata_prereset, ata_std_softreset, NULL, ata_std_postreset); } @@ -817,7 +785,6 @@ static int __devinit piix_check_450nx_errata(struct pci_dev *ata_dev) } static void __devinit piix_init_pcs(struct pci_dev *pdev, - struct ata_port_info *pinfo, const struct piix_map_db *map_db) { u16 pcs, new_pcs; @@ -831,18 +798,6 @@ static void __devinit piix_init_pcs(struct pci_dev *pdev, pci_write_config_word(pdev, ICH5_PCS, new_pcs); msleep(150); } - - if (force_pcs == 1) { - dev_printk(KERN_INFO, &pdev->dev, - "force ignoring PCS (0x%x)\n", new_pcs); - pinfo[0].host_flags |= PIIX_FLAG_IGNORE_PCS; - pinfo[1].host_flags |= PIIX_FLAG_IGNORE_PCS; - } else if (force_pcs == 2) { - dev_printk(KERN_INFO, &pdev->dev, - "force honoring PCS (0x%x)\n", new_pcs); - pinfo[0].host_flags &= ~PIIX_FLAG_IGNORE_PCS; - pinfo[1].host_flags &= ~PIIX_FLAG_IGNORE_PCS; - } } static void __devinit piix_init_sata_map(struct pci_dev *pdev, @@ -951,8 +906,7 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) if (host_flags & ATA_FLAG_SATA) { piix_init_sata_map(pdev, port_info, piix_map_db_table[ent->driver_data]); - piix_init_pcs(pdev, port_info, - piix_map_db_table[ent->driver_data]); + piix_init_pcs(pdev, piix_map_db_table[ent->driver_data]); } /* On ICH5, some BIOSen disable the interrupt using the diff --git a/trunk/drivers/scsi/esp.c b/trunk/drivers/scsi/esp.c index 5630868c1b25..98bd22714d0d 100644 --- a/trunk/drivers/scsi/esp.c +++ b/trunk/drivers/scsi/esp.c @@ -1146,7 +1146,7 @@ static struct sbus_dev sun4_esp_dev; static int __init esp_sun4_probe(struct scsi_host_template *tpnt) { if (sun4_esp_physaddr) { - memset(&sun4_esp_dev, 0, sizeof(sun4_esp_dev)); + memset(&sun4_esp_dev, 0, sizeof(esp_dev)); sun4_esp_dev.reg_addrs[0].phys_addr = sun4_esp_physaddr; sun4_esp_dev.irqs[0] = 4; sun4_esp_dev.resource[0].start = sun4_esp_physaddr; @@ -1162,7 +1162,6 @@ static int __init esp_sun4_probe(struct scsi_host_template *tpnt) static int __devexit esp_sun4_remove(void) { - struct of_device *dev = &sun4_esp_dev.ofdev; struct esp *esp = dev_get_drvdata(&dev->dev); return esp_remove_common(esp); diff --git a/trunk/drivers/scsi/hptiop.c b/trunk/drivers/scsi/hptiop.c index bcb3444f1dcf..ab2f8b267908 100644 --- a/trunk/drivers/scsi/hptiop.c +++ b/trunk/drivers/scsi/hptiop.c @@ -45,6 +45,10 @@ static char driver_name[] = "hptiop"; static const char driver_name_long[] = "RocketRAID 3xxx SATA Controller driver"; static const char driver_ver[] = "v1.0 (060426)"; +static DEFINE_SPINLOCK(hptiop_hba_list_lock); +static LIST_HEAD(hptiop_hba_list); +static int hptiop_cdev_major = -1; + static void hptiop_host_request_callback(struct hptiop_hba *hba, u32 tag); static void hptiop_iop_request_callback(struct hptiop_hba *hba, u32 tag); static void hptiop_message_callback(struct hptiop_hba *hba, u32 msg); @@ -573,7 +577,7 @@ static int hptiop_reset_hba(struct hptiop_hba *hba) if (atomic_xchg(&hba->resetting, 1) == 0) { atomic_inc(&hba->reset_count); writel(IOPMU_INBOUND_MSG0_RESET, - &hba->iop->inbound_msgaddr0); + &hba->iop->outbound_msgaddr0); hptiop_pci_posting_flush(hba->iop); } @@ -616,11 +620,532 @@ static int hptiop_adjust_disk_queue_depth(struct scsi_device *sdev, return queue_depth; } +struct hptiop_getinfo { + char __user *buffer; + loff_t buflength; + loff_t bufoffset; + loff_t buffillen; + loff_t filpos; +}; + +static void hptiop_copy_mem_info(struct hptiop_getinfo *pinfo, + char *data, int datalen) +{ + if (pinfo->filpos < pinfo->bufoffset) { + if (pinfo->filpos + datalen <= pinfo->bufoffset) { + pinfo->filpos += datalen; + return; + } else { + data += (pinfo->bufoffset - pinfo->filpos); + datalen -= (pinfo->bufoffset - pinfo->filpos); + pinfo->filpos = pinfo->bufoffset; + } + } + + pinfo->filpos += datalen; + if (pinfo->buffillen == pinfo->buflength) + return; + + if (pinfo->buflength - pinfo->buffillen < datalen) + datalen = pinfo->buflength - pinfo->buffillen; + + if (copy_to_user(pinfo->buffer + pinfo->buffillen, data, datalen)) + return; + + pinfo->buffillen += datalen; +} + +static int hptiop_copy_info(struct hptiop_getinfo *pinfo, char *fmt, ...) +{ + va_list args; + char buf[128]; + int len; + + va_start(args, fmt); + len = vsnprintf(buf, sizeof(buf), fmt, args); + va_end(args); + hptiop_copy_mem_info(pinfo, buf, len); + return len; +} + +static void hptiop_ioctl_done(struct hpt_ioctl_k *arg) +{ + arg->done = NULL; + wake_up(&arg->hba->ioctl_wq); +} + +static void hptiop_do_ioctl(struct hpt_ioctl_k *arg) +{ + struct hptiop_hba *hba = arg->hba; + u32 val; + struct hpt_iop_request_ioctl_command __iomem *req; + int ioctl_retry = 0; + + dprintk("scsi%d: hptiop_do_ioctl\n", hba->host->host_no); + + /* + * check (in + out) buff size from application. + * outbuf must be dword aligned. + */ + if (((arg->inbuf_size + 3) & ~3) + arg->outbuf_size > + hba->max_request_size + - sizeof(struct hpt_iop_request_header) + - 4 * sizeof(u32)) { + dprintk("scsi%d: ioctl buf size (%d/%d) is too large\n", + hba->host->host_no, + arg->inbuf_size, arg->outbuf_size); + arg->result = HPT_IOCTL_RESULT_FAILED; + return; + } + +retry: + spin_lock_irq(hba->host->host_lock); + + val = readl(&hba->iop->inbound_queue); + if (val == IOPMU_QUEUE_EMPTY) { + spin_unlock_irq(hba->host->host_lock); + dprintk("scsi%d: no free req for ioctl\n", hba->host->host_no); + arg->result = -1; + return; + } + + req = (struct hpt_iop_request_ioctl_command __iomem *) + ((unsigned long)hba->iop + val); + + writel(HPT_CTL_CODE_LINUX_TO_IOP(arg->ioctl_code), + &req->ioctl_code); + writel(arg->inbuf_size, &req->inbuf_size); + writel(arg->outbuf_size, &req->outbuf_size); + + /* + * use the buffer on the IOP local memory first, then copy it + * back to host. + * the caller's request buffer shoudl be little-endian. + */ + if (arg->inbuf_size) + memcpy_toio(req->buf, arg->inbuf, arg->inbuf_size); + + /* correct the controller ID for IOP */ + if ((arg->ioctl_code == HPT_IOCTL_GET_CHANNEL_INFO || + arg->ioctl_code == HPT_IOCTL_GET_CONTROLLER_INFO_V2 || + arg->ioctl_code == HPT_IOCTL_GET_CONTROLLER_INFO) + && arg->inbuf_size >= sizeof(u32)) + writel(0, req->buf); + + writel(IOP_REQUEST_TYPE_IOCTL_COMMAND, &req->header.type); + writel(0, &req->header.flags); + writel(offsetof(struct hpt_iop_request_ioctl_command, buf) + + arg->inbuf_size, &req->header.size); + writel((u32)(unsigned long)arg, &req->header.context); + writel(BITS_PER_LONG > 32 ? (u32)((unsigned long)arg>>32) : 0, + &req->header.context_hi32); + writel(IOP_RESULT_PENDING, &req->header.result); + + arg->result = HPT_IOCTL_RESULT_FAILED; + arg->done = hptiop_ioctl_done; + + writel(val, &hba->iop->inbound_queue); + hptiop_pci_posting_flush(hba->iop); + + spin_unlock_irq(hba->host->host_lock); + + wait_event_timeout(hba->ioctl_wq, arg->done == NULL, 60 * HZ); + + if (arg->done != NULL) { + hptiop_reset_hba(hba); + if (ioctl_retry++ < 3) + goto retry; + } + + dprintk("hpt_iop_ioctl %x result %d\n", + arg->ioctl_code, arg->result); +} + +static int __hpt_do_ioctl(struct hptiop_hba *hba, u32 code, void *inbuf, + u32 insize, void *outbuf, u32 outsize) +{ + struct hpt_ioctl_k arg; + arg.hba = hba; + arg.ioctl_code = code; + arg.inbuf = inbuf; + arg.outbuf = outbuf; + arg.inbuf_size = insize; + arg.outbuf_size = outsize; + arg.bytes_returned = NULL; + hptiop_do_ioctl(&arg); + return arg.result; +} + +static inline int hpt_id_valid(__le32 id) +{ + return id != 0 && id != cpu_to_le32(0xffffffff); +} + +static int hptiop_get_controller_info(struct hptiop_hba *hba, + struct hpt_controller_info *pinfo) +{ + int id = 0; + + return __hpt_do_ioctl(hba, HPT_IOCTL_GET_CONTROLLER_INFO, + &id, sizeof(int), pinfo, sizeof(*pinfo)); +} + + +static int hptiop_get_channel_info(struct hptiop_hba *hba, int bus, + struct hpt_channel_info *pinfo) +{ + u32 ids[2]; + + ids[0] = 0; + ids[1] = bus; + return __hpt_do_ioctl(hba, HPT_IOCTL_GET_CHANNEL_INFO, + ids, sizeof(ids), pinfo, sizeof(*pinfo)); + +} + +static int hptiop_get_logical_devices(struct hptiop_hba *hba, + __le32 *pids, int maxcount) +{ + int i; + u32 count = maxcount - 1; + + if (__hpt_do_ioctl(hba, HPT_IOCTL_GET_LOGICAL_DEVICES, + &count, sizeof(u32), + pids, sizeof(u32) * maxcount)) + return -1; + + maxcount = le32_to_cpu(pids[0]); + for (i = 0; i < maxcount; i++) + pids[i] = pids[i+1]; + + return maxcount; +} + +static int hptiop_get_device_info_v3(struct hptiop_hba *hba, __le32 id, + struct hpt_logical_device_info_v3 *pinfo) +{ + return __hpt_do_ioctl(hba, HPT_IOCTL_GET_DEVICE_INFO_V3, + &id, sizeof(u32), + pinfo, sizeof(*pinfo)); +} + +static const char *get_array_status(struct hpt_logical_device_info_v3 *devinfo) +{ + static char s[64]; + u32 flags = le32_to_cpu(devinfo->u.array.flags); + u32 trans_prog = le32_to_cpu(devinfo->u.array.transforming_progress); + u32 reb_prog = le32_to_cpu(devinfo->u.array.rebuilding_progress); + + if (flags & ARRAY_FLAG_DISABLED) + return "Disabled"; + else if (flags & ARRAY_FLAG_TRANSFORMING) + sprintf(s, "Expanding/Migrating %d.%d%%%s%s", + trans_prog / 100, + trans_prog % 100, + (flags & (ARRAY_FLAG_NEEDBUILDING|ARRAY_FLAG_BROKEN))? + ", Critical" : "", + ((flags & ARRAY_FLAG_NEEDINITIALIZING) && + !(flags & ARRAY_FLAG_REBUILDING) && + !(flags & ARRAY_FLAG_INITIALIZING))? + ", Unintialized" : ""); + else if ((flags & ARRAY_FLAG_BROKEN) && + devinfo->u.array.array_type != AT_RAID6) + return "Critical"; + else if (flags & ARRAY_FLAG_REBUILDING) + sprintf(s, + (flags & ARRAY_FLAG_NEEDINITIALIZING)? + "%sBackground initializing %d.%d%%" : + "%sRebuilding %d.%d%%", + (flags & ARRAY_FLAG_BROKEN)? "Critical, " : "", + reb_prog / 100, + reb_prog % 100); + else if (flags & ARRAY_FLAG_VERIFYING) + sprintf(s, "%sVerifying %d.%d%%", + (flags & ARRAY_FLAG_BROKEN)? "Critical, " : "", + reb_prog / 100, + reb_prog % 100); + else if (flags & ARRAY_FLAG_INITIALIZING) + sprintf(s, "%sForground initializing %d.%d%%", + (flags & ARRAY_FLAG_BROKEN)? "Critical, " : "", + reb_prog / 100, + reb_prog % 100); + else if (flags & ARRAY_FLAG_NEEDTRANSFORM) + sprintf(s,"%s%s%s", "Need Expanding/Migrating", + (flags & ARRAY_FLAG_BROKEN)? "Critical, " : "", + ((flags & ARRAY_FLAG_NEEDINITIALIZING) && + !(flags & ARRAY_FLAG_REBUILDING) && + !(flags & ARRAY_FLAG_INITIALIZING))? + ", Unintialized" : ""); + else if (flags & ARRAY_FLAG_NEEDINITIALIZING && + !(flags & ARRAY_FLAG_REBUILDING) && + !(flags & ARRAY_FLAG_INITIALIZING)) + sprintf(s,"%sUninitialized", + (flags & ARRAY_FLAG_BROKEN)? "Critical, " : ""); + else if ((flags & ARRAY_FLAG_NEEDBUILDING) || + (flags & ARRAY_FLAG_BROKEN)) + return "Critical"; + else + return "Normal"; + return s; +} + +static void hptiop_dump_devinfo(struct hptiop_hba *hba, + struct hptiop_getinfo *pinfo, __le32 id, int indent) +{ + struct hpt_logical_device_info_v3 devinfo; + int i; + u64 capacity; + + for (i = 0; i < indent; i++) + hptiop_copy_info(pinfo, "\t"); + + if (hptiop_get_device_info_v3(hba, id, &devinfo)) { + hptiop_copy_info(pinfo, "unknown\n"); + return; + } + + switch (devinfo.type) { + + case LDT_DEVICE: { + struct hd_driveid *driveid; + u32 flags = le32_to_cpu(devinfo.u.device.flags); + + driveid = (struct hd_driveid *)devinfo.u.device.ident; + /* model[] is 40 chars long, but we just want 20 chars here */ + driveid->model[20] = 0; + + if (indent) + if (flags & DEVICE_FLAG_DISABLED) + hptiop_copy_info(pinfo,"Missing\n"); + else + hptiop_copy_info(pinfo, "CH%d %s\n", + devinfo.u.device.path_id + 1, + driveid->model); + else { + capacity = le64_to_cpu(devinfo.capacity) * 512; + do_div(capacity, 1000000); + hptiop_copy_info(pinfo, + "CH%d %s, %lluMB, %s %s%s%s%s\n", + devinfo.u.device.path_id + 1, + driveid->model, + capacity, + (flags & DEVICE_FLAG_DISABLED)? + "Disabled" : "Normal", + devinfo.u.device.read_ahead_enabled? + "[RA]" : "", + devinfo.u.device.write_cache_enabled? + "[WC]" : "", + devinfo.u.device.TCQ_enabled? + "[TCQ]" : "", + devinfo.u.device.NCQ_enabled? + "[NCQ]" : "" + ); + } + break; + } + + case LDT_ARRAY: + if (devinfo.target_id != INVALID_TARGET_ID) + hptiop_copy_info(pinfo, "[DISK %d_%d] ", + devinfo.vbus_id, devinfo.target_id); + + capacity = le64_to_cpu(devinfo.capacity) * 512; + do_div(capacity, 1000000); + hptiop_copy_info(pinfo, "%s (%s), %lluMB, %s\n", + devinfo.u.array.name, + devinfo.u.array.array_type==AT_RAID0? "RAID0" : + devinfo.u.array.array_type==AT_RAID1? "RAID1" : + devinfo.u.array.array_type==AT_RAID5? "RAID5" : + devinfo.u.array.array_type==AT_RAID6? "RAID6" : + devinfo.u.array.array_type==AT_JBOD? "JBOD" : + "unknown", + capacity, + get_array_status(&devinfo)); + for (i = 0; i < devinfo.u.array.ndisk; i++) { + if (hpt_id_valid(devinfo.u.array.members[i])) { + if (cpu_to_le16(1<private_data; + struct hptiop_getinfo info; + int i, j, ndev; + struct hpt_controller_info con_info; + struct hpt_channel_info chan_info; + __le32 ids[32]; + + info.buffer = buf; + info.buflength = count; + info.bufoffset = ppos ? *ppos : 0; + info.filpos = 0; + info.buffillen = 0; + + if (hptiop_get_controller_info(hba, &con_info)) + return -EIO; + + for (i = 0; i < con_info.num_buses; i++) { + if (hptiop_get_channel_info(hba, i, &chan_info) == 0) { + if (hpt_id_valid(chan_info.devices[0])) + hptiop_dump_devinfo(hba, &info, + chan_info.devices[0], 0); + if (hpt_id_valid(chan_info.devices[1])) + hptiop_dump_devinfo(hba, &info, + chan_info.devices[1], 0); + } + } + + ndev = hptiop_get_logical_devices(hba, ids, + sizeof(ids) / sizeof(ids[0])); + + /* + * if hptiop_get_logical_devices fails, ndev==-1 and it just + * output nothing here + */ + for (j = 0; j < ndev; j++) + hptiop_dump_devinfo(hba, &info, ids[j], 0); + + if (ppos) + *ppos += info.buffillen; + + return info.buffillen; +} + +static int hptiop_cdev_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct hptiop_hba *hba = file->private_data; + struct hpt_ioctl_u ioctl_u; + struct hpt_ioctl_k ioctl_k; + u32 bytes_returned; + int err = -EINVAL; + + if (copy_from_user(&ioctl_u, + (void __user *)arg, sizeof(struct hpt_ioctl_u))) + return -EINVAL; + + if (ioctl_u.magic != HPT_IOCTL_MAGIC) + return -EINVAL; + + ioctl_k.ioctl_code = ioctl_u.ioctl_code; + ioctl_k.inbuf = NULL; + ioctl_k.inbuf_size = ioctl_u.inbuf_size; + ioctl_k.outbuf = NULL; + ioctl_k.outbuf_size = ioctl_u.outbuf_size; + ioctl_k.hba = hba; + ioctl_k.bytes_returned = &bytes_returned; + + /* verify user buffer */ + if ((ioctl_k.inbuf_size && !access_ok(VERIFY_READ, + ioctl_u.inbuf, ioctl_k.inbuf_size)) || + (ioctl_k.outbuf_size && !access_ok(VERIFY_WRITE, + ioctl_u.outbuf, ioctl_k.outbuf_size)) || + (ioctl_u.bytes_returned && !access_ok(VERIFY_WRITE, + ioctl_u.bytes_returned, sizeof(u32))) || + ioctl_k.inbuf_size + ioctl_k.outbuf_size > 0x10000) { + + dprintk("scsi%d: got bad user address\n", hba->host->host_no); + return -EINVAL; + } + + /* map buffer to kernel. */ + if (ioctl_k.inbuf_size) { + ioctl_k.inbuf = kmalloc(ioctl_k.inbuf_size, GFP_KERNEL); + if (!ioctl_k.inbuf) { + dprintk("scsi%d: fail to alloc inbuf\n", + hba->host->host_no); + err = -ENOMEM; + goto err_exit; + } + + if (copy_from_user(ioctl_k.inbuf, + ioctl_u.inbuf, ioctl_k.inbuf_size)) { + goto err_exit; + } + } + + if (ioctl_k.outbuf_size) { + ioctl_k.outbuf = kmalloc(ioctl_k.outbuf_size, GFP_KERNEL); + if (!ioctl_k.outbuf) { + dprintk("scsi%d: fail to alloc outbuf\n", + hba->host->host_no); + err = -ENOMEM; + goto err_exit; + } + } + + hptiop_do_ioctl(&ioctl_k); + + if (ioctl_k.result == HPT_IOCTL_RESULT_OK) { + if (ioctl_k.outbuf_size && + copy_to_user(ioctl_u.outbuf, + ioctl_k.outbuf, ioctl_k.outbuf_size)) + goto err_exit; + + if (ioctl_u.bytes_returned && + copy_to_user(ioctl_u.bytes_returned, + &bytes_returned, sizeof(u32))) + goto err_exit; + + err = 0; + } + +err_exit: + kfree(ioctl_k.inbuf); + kfree(ioctl_k.outbuf); + + return err; +} + +static int hptiop_cdev_open(struct inode *inode, struct file *file) +{ + struct hptiop_hba *hba; + unsigned i = 0, minor = iminor(inode); + int ret = -ENODEV; + + spin_lock(&hptiop_hba_list_lock); + list_for_each_entry(hba, &hptiop_hba_list, link) { + if (i == minor) { + file->private_data = hba; + ret = 0; + goto out; + } + i++; + } + +out: + spin_unlock(&hptiop_hba_list_lock); + return ret; +} + +static struct file_operations hptiop_cdev_fops = { + .owner = THIS_MODULE, + .read = hptiop_cdev_read, + .ioctl = hptiop_cdev_ioctl, + .open = hptiop_cdev_open, +}; + static ssize_t hptiop_show_fw_version(struct class_device *class_dev, char *buf) { struct Scsi_Host *host = class_to_shost(class_dev); @@ -771,13 +1296,19 @@ static int __devinit hptiop_probe(struct pci_dev *pcidev, goto unmap_pci_bar; } + if (scsi_add_host(host, &pcidev->dev)) { + printk(KERN_ERR "scsi%d: scsi_add_host failed\n", + hba->host->host_no); + goto unmap_pci_bar; + } + pci_set_drvdata(pcidev, host); if (request_irq(pcidev->irq, hptiop_intr, IRQF_SHARED, driver_name, hba)) { printk(KERN_ERR "scsi%d: request irq %d failed\n", hba->host->host_no, pcidev->irq); - goto unmap_pci_bar; + goto remove_scsi_host; } /* Allocate request mem */ @@ -824,12 +1355,9 @@ static int __devinit hptiop_probe(struct pci_dev *pcidev, if (hptiop_initialize_iop(hba)) goto free_request_mem; - if (scsi_add_host(host, &pcidev->dev)) { - printk(KERN_ERR "scsi%d: scsi_add_host failed\n", - hba->host->host_no); - goto free_request_mem; - } - + spin_lock(&hptiop_hba_list_lock); + list_add_tail(&hba->link, &hptiop_hba_list); + spin_unlock(&hptiop_hba_list_lock); scsi_scan_host(host); @@ -844,6 +1372,9 @@ static int __devinit hptiop_probe(struct pci_dev *pcidev, free_request_irq: free_irq(hba->pcidev->irq, hba); +remove_scsi_host: + scsi_remove_host(host); + unmap_pci_bar: iounmap(hba->iop); @@ -891,6 +1422,10 @@ static void hptiop_remove(struct pci_dev *pcidev) scsi_remove_host(host); + spin_lock(&hptiop_hba_list_lock); + list_del_init(&hba->link); + spin_unlock(&hptiop_hba_list_lock); + hptiop_shutdown(pcidev); free_irq(hba->pcidev->irq, hba); @@ -927,12 +1462,27 @@ static struct pci_driver hptiop_pci_driver = { static int __init hptiop_module_init(void) { + int error; + printk(KERN_INFO "%s %s\n", driver_name_long, driver_ver); - return pci_register_driver(&hptiop_pci_driver); + + error = pci_register_driver(&hptiop_pci_driver); + if (error < 0) + return error; + + hptiop_cdev_major = register_chrdev(0, "hptiop", &hptiop_cdev_fops); + if (hptiop_cdev_major < 0) { + printk(KERN_WARNING "unable to register hptiop device.\n"); + return hptiop_cdev_major; + } + + return 0; } static void __exit hptiop_module_exit(void) { + dprintk("hptiop_module_exit\n"); + unregister_chrdev(hptiop_cdev_major, "hptiop"); pci_unregister_driver(&hptiop_pci_driver); } diff --git a/trunk/drivers/scsi/ide-scsi.c b/trunk/drivers/scsi/ide-scsi.c index 94d1de55607f..f7b5d7372d26 100644 --- a/trunk/drivers/scsi/ide-scsi.c +++ b/trunk/drivers/scsi/ide-scsi.c @@ -517,7 +517,7 @@ static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive) /* No more interrupts */ if (test_bit(IDESCSI_LOG_CMD, &scsi->log)) printk (KERN_INFO "Packet command completed, %d bytes transferred\n", pc->actually_transferred); - local_irq_enable_in_hardirq(); + local_irq_enable(); if (status.b.check) rq->errors++; idescsi_end_request (drive, 1, 0); diff --git a/trunk/drivers/scsi/iscsi_tcp.c b/trunk/drivers/scsi/iscsi_tcp.c index 058f094f945a..848fb2aa4ca3 100644 --- a/trunk/drivers/scsi/iscsi_tcp.c +++ b/trunk/drivers/scsi/iscsi_tcp.c @@ -43,10 +43,13 @@ #include "iscsi_tcp.h" +#define ISCSI_TCP_VERSION "1.0-595" + MODULE_AUTHOR("Dmitry Yusupov , " "Alex Aizman "); MODULE_DESCRIPTION("iSCSI/TCP data-path"); MODULE_LICENSE("GPL"); +MODULE_VERSION(ISCSI_TCP_VERSION); /* #define DEBUG_TCP */ #define DEBUG_ASSERT @@ -182,19 +185,11 @@ iscsi_hdr_extract(struct iscsi_tcp_conn *tcp_conn) * must be called with session lock */ static void -iscsi_tcp_cleanup_ctask(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) +__iscsi_ctask_cleanup(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) { struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; - struct iscsi_r2t_info *r2t; struct scsi_cmnd *sc; - /* flush ctask's r2t queues */ - while (__kfifo_get(tcp_ctask->r2tqueue, (void*)&r2t, sizeof(void*))) { - __kfifo_put(tcp_ctask->r2tpool.queue, (void*)&r2t, - sizeof(void*)); - debug_scsi("iscsi_tcp_cleanup_ctask pending r2t dropped\n"); - } - sc = ctask->sc; if (unlikely(!sc)) return; @@ -379,7 +374,6 @@ iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) spin_unlock(&session->lock); return 0; } - rc = __kfifo_get(tcp_ctask->r2tpool.queue, (void*)&r2t, sizeof(void*)); BUG_ON(!rc); @@ -405,7 +399,7 @@ iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) tcp_ctask->exp_r2tsn = r2tsn + 1; tcp_ctask->xmstate |= XMSTATE_SOL_HDR; __kfifo_put(tcp_ctask->r2tqueue, (void*)&r2t, sizeof(void*)); - list_move_tail(&ctask->running, &conn->xmitqueue); + __kfifo_put(conn->xmitqueue, (void*)&ctask, sizeof(void*)); scsi_queue_work(session->host, &conn->xmitwork); conn->r2t_pdus_cnt++; @@ -483,8 +477,6 @@ iscsi_tcp_hdr_recv(struct iscsi_conn *conn) case ISCSI_OP_SCSI_DATA_IN: tcp_conn->in.ctask = session->cmds[itt]; rc = iscsi_data_rsp(conn, tcp_conn->in.ctask); - if (rc) - return rc; /* fall through */ case ISCSI_OP_SCSI_CMD_RSP: tcp_conn->in.ctask = session->cmds[itt]; @@ -492,7 +484,7 @@ iscsi_tcp_hdr_recv(struct iscsi_conn *conn) goto copy_hdr; spin_lock(&session->lock); - iscsi_tcp_cleanup_ctask(conn, tcp_conn->in.ctask); + __iscsi_ctask_cleanup(conn, tcp_conn->in.ctask); rc = __iscsi_complete_pdu(conn, hdr, NULL, 0); spin_unlock(&session->lock); break; @@ -508,28 +500,13 @@ iscsi_tcp_hdr_recv(struct iscsi_conn *conn) break; case ISCSI_OP_LOGIN_RSP: case ISCSI_OP_TEXT_RSP: + case ISCSI_OP_LOGOUT_RSP: + case ISCSI_OP_NOOP_IN: case ISCSI_OP_REJECT: case ISCSI_OP_ASYNC_EVENT: - /* - * It is possible that we could get a PDU with a buffer larger - * than 8K, but there are no targets that currently do this. - * For now we fail until we find a vendor that needs it - */ - if (DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH < - tcp_conn->in.datalen) { - printk(KERN_ERR "iscsi_tcp: received buffer of len %u " - "but conn buffer is only %u (opcode %0x)\n", - tcp_conn->in.datalen, - DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH, opcode); - rc = ISCSI_ERR_PROTO; - break; - } - if (tcp_conn->in.datalen) goto copy_hdr; /* fall through */ - case ISCSI_OP_LOGOUT_RSP: - case ISCSI_OP_NOOP_IN: case ISCSI_OP_SCSI_TMFUNC_RSP: rc = iscsi_complete_pdu(conn, hdr, NULL, 0); break; @@ -546,7 +523,7 @@ iscsi_tcp_hdr_recv(struct iscsi_conn *conn) * skbs to complete the command then we have to copy the header * for later use */ - if (tcp_conn->in.zero_copy_hdr && tcp_conn->in.copy <= + if (tcp_conn->in.zero_copy_hdr && tcp_conn->in.copy < (tcp_conn->in.datalen + tcp_conn->in.padding + (conn->datadgst_en ? 4 : 0))) { debug_tcp("Copying header for later use. in.copy %d in.datalen" @@ -637,9 +614,9 @@ iscsi_ctask_copy(struct iscsi_tcp_conn *tcp_conn, struct iscsi_cmd_task *ctask, * byte counters. **/ static inline int -iscsi_tcp_copy(struct iscsi_conn *conn) +iscsi_tcp_copy(struct iscsi_tcp_conn *tcp_conn) { - struct iscsi_tcp_conn *tcp_conn = conn->dd_data; + void *buf = tcp_conn->data; int buf_size = tcp_conn->in.datalen; int buf_left = buf_size - tcp_conn->data_copied; int size = min(tcp_conn->in.copy, buf_left); @@ -650,7 +627,7 @@ iscsi_tcp_copy(struct iscsi_conn *conn) BUG_ON(size <= 0); rc = skb_copy_bits(tcp_conn->in.skb, tcp_conn->in.offset, - (char*)conn->data + tcp_conn->data_copied, size); + (char*)buf + tcp_conn->data_copied, size); BUG_ON(rc); tcp_conn->in.offset += size; @@ -768,11 +745,10 @@ static int iscsi_scsi_data_in(struct iscsi_conn *conn) done: /* check for non-exceptional status */ if (tcp_conn->in.hdr->flags & ISCSI_FLAG_DATA_STATUS) { - debug_scsi("done [sc %lx res %d itt 0x%x flags 0x%x]\n", - (long)sc, sc->result, ctask->itt, - tcp_conn->in.hdr->flags); + debug_scsi("done [sc %lx res %d itt 0x%x]\n", + (long)sc, sc->result, ctask->itt); spin_lock(&conn->session->lock); - iscsi_tcp_cleanup_ctask(conn, ctask); + __iscsi_ctask_cleanup(conn, ctask); __iscsi_complete_pdu(conn, tcp_conn->in.hdr, NULL, 0); spin_unlock(&conn->session->lock); } @@ -793,25 +769,26 @@ iscsi_data_recv(struct iscsi_conn *conn) break; case ISCSI_OP_SCSI_CMD_RSP: spin_lock(&conn->session->lock); - iscsi_tcp_cleanup_ctask(conn, tcp_conn->in.ctask); + __iscsi_ctask_cleanup(conn, tcp_conn->in.ctask); spin_unlock(&conn->session->lock); case ISCSI_OP_TEXT_RSP: case ISCSI_OP_LOGIN_RSP: + case ISCSI_OP_NOOP_IN: case ISCSI_OP_ASYNC_EVENT: case ISCSI_OP_REJECT: /* * Collect data segment to the connection's data * placeholder */ - if (iscsi_tcp_copy(conn)) { + if (iscsi_tcp_copy(tcp_conn)) { rc = -EAGAIN; goto exit; } - rc = iscsi_complete_pdu(conn, tcp_conn->in.hdr, conn->data, + rc = iscsi_complete_pdu(conn, tcp_conn->in.hdr, tcp_conn->data, tcp_conn->in.datalen); if (!rc && conn->datadgst_en && opcode != ISCSI_OP_LOGIN_RSP) - iscsi_recv_digest_update(tcp_conn, conn->data, + iscsi_recv_digest_update(tcp_conn, tcp_conn->data, tcp_conn->in.datalen); break; default: @@ -866,7 +843,7 @@ iscsi_tcp_data_recv(read_descriptor_t *rd_desc, struct sk_buff *skb, if (rc == -EAGAIN) goto nomore; else { - iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); + iscsi_conn_failure(conn, rc); return 0; } } @@ -920,7 +897,7 @@ iscsi_tcp_data_recv(read_descriptor_t *rd_desc, struct sk_buff *skb, if (rc) { if (rc == -EAGAIN) goto again; - iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); + iscsi_conn_failure(conn, rc); return 0; } tcp_conn->in.copy -= tcp_conn->in.padding; @@ -1051,8 +1028,9 @@ iscsi_conn_set_callbacks(struct iscsi_conn *conn) } static void -iscsi_conn_restore_callbacks(struct iscsi_tcp_conn *tcp_conn) +iscsi_conn_restore_callbacks(struct iscsi_conn *conn) { + struct iscsi_tcp_conn *tcp_conn = conn->dd_data; struct sock *sk = tcp_conn->sock->sk; /* restore socket callbacks, see also: iscsi_conn_set_callbacks() */ @@ -1330,7 +1308,7 @@ iscsi_tcp_cmd_init(struct iscsi_cmd_task *ctask) ctask->imm_count - ctask->unsol_count; - debug_scsi("cmd [itt 0x%x total %d imm %d imm_data %d " + debug_scsi("cmd [itt %x total %d imm %d imm_data %d " "r2t_data %d]\n", ctask->itt, ctask->total_length, ctask->imm_count, ctask->unsol_count, tcp_ctask->r2t_data_count); @@ -1658,7 +1636,7 @@ handle_xmstate_sol_data(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) } solicit_again: /* - * send Data-Out within this R2T sequence. + * send Data-Out whitnin this R2T sequence. */ if (!r2t->data_count) goto data_out_done; @@ -1753,7 +1731,7 @@ handle_xmstate_w_pad(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; struct iscsi_tcp_conn *tcp_conn = conn->dd_data; struct iscsi_data_task *dtask = tcp_ctask->dtask; - int sent = 0, rc; + int sent, rc; tcp_ctask->xmstate &= ~XMSTATE_W_PAD; iscsi_buf_init_iov(&tcp_ctask->sendbuf, (char*)&tcp_ctask->pad, @@ -1922,31 +1900,26 @@ iscsi_tcp_conn_create(struct iscsi_cls_session *cls_session, uint32_t conn_idx) tcp_conn->in_progress = IN_PROGRESS_WAIT_HEADER; /* initial operational parameters */ tcp_conn->hdr_size = sizeof(struct iscsi_hdr); + tcp_conn->data_size = DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH; + + /* allocate initial PDU receive place holder */ + if (tcp_conn->data_size <= PAGE_SIZE) + tcp_conn->data = kmalloc(tcp_conn->data_size, GFP_KERNEL); + else + tcp_conn->data = (void*)__get_free_pages(GFP_KERNEL, + get_order(tcp_conn->data_size)); + if (!tcp_conn->data) + goto max_recv_dlenght_alloc_fail; return cls_conn; +max_recv_dlenght_alloc_fail: + kfree(tcp_conn); tcp_conn_alloc_fail: iscsi_conn_teardown(cls_conn); return NULL; } -static void -iscsi_tcp_release_conn(struct iscsi_conn *conn) -{ - struct iscsi_tcp_conn *tcp_conn = conn->dd_data; - - if (!tcp_conn->sock) - return; - - sock_hold(tcp_conn->sock->sk); - iscsi_conn_restore_callbacks(tcp_conn); - sock_put(tcp_conn->sock->sk); - - sock_release(tcp_conn->sock); - tcp_conn->sock = NULL; - conn->recv_lock = NULL; -} - static void iscsi_tcp_conn_destroy(struct iscsi_cls_conn *cls_conn) { @@ -1957,7 +1930,6 @@ iscsi_tcp_conn_destroy(struct iscsi_cls_conn *cls_conn) if (conn->hdrdgst_en || conn->datadgst_en) digest = 1; - iscsi_tcp_release_conn(conn); iscsi_conn_teardown(cls_conn); /* now free tcp_conn */ @@ -1972,18 +1944,15 @@ iscsi_tcp_conn_destroy(struct iscsi_cls_conn *cls_conn) crypto_free_tfm(tcp_conn->data_rx_tfm); } + /* free conn->data, size = MaxRecvDataSegmentLength */ + if (tcp_conn->data_size <= PAGE_SIZE) + kfree(tcp_conn->data); + else + free_pages((unsigned long)tcp_conn->data, + get_order(tcp_conn->data_size)); kfree(tcp_conn); } -static void -iscsi_tcp_conn_stop(struct iscsi_cls_conn *cls_conn, int flag) -{ - struct iscsi_conn *conn = cls_conn->dd_data; - - iscsi_conn_stop(cls_conn, flag); - iscsi_tcp_release_conn(conn); -} - static int iscsi_tcp_conn_bind(struct iscsi_cls_session *cls_session, struct iscsi_cls_conn *cls_conn, uint64_t transport_eph, @@ -2032,6 +2001,52 @@ iscsi_tcp_conn_bind(struct iscsi_cls_session *cls_session, return 0; } +static void +iscsi_tcp_cleanup_ctask(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) +{ + struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; + struct iscsi_r2t_info *r2t; + + /* flush ctask's r2t queues */ + while (__kfifo_get(tcp_ctask->r2tqueue, (void*)&r2t, sizeof(void*))) + __kfifo_put(tcp_ctask->r2tpool.queue, (void*)&r2t, + sizeof(void*)); + + __iscsi_ctask_cleanup(conn, ctask); +} + +static void +iscsi_tcp_suspend_conn_rx(struct iscsi_conn *conn) +{ + struct iscsi_tcp_conn *tcp_conn = conn->dd_data; + struct sock *sk; + + if (!tcp_conn->sock) + return; + + sk = tcp_conn->sock->sk; + write_lock_bh(&sk->sk_callback_lock); + set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_rx); + write_unlock_bh(&sk->sk_callback_lock); +} + +static void +iscsi_tcp_terminate_conn(struct iscsi_conn *conn) +{ + struct iscsi_tcp_conn *tcp_conn = conn->dd_data; + + if (!tcp_conn->sock) + return; + + sock_hold(tcp_conn->sock->sk); + iscsi_conn_restore_callbacks(conn); + sock_put(tcp_conn->sock->sk); + + sock_release(tcp_conn->sock); + tcp_conn->sock = NULL; + conn->recv_lock = NULL; +} + /* called with host lock */ static void iscsi_tcp_mgmt_init(struct iscsi_conn *conn, struct iscsi_mgmt_task *mtask, @@ -2042,7 +2057,6 @@ iscsi_tcp_mgmt_init(struct iscsi_conn *conn, struct iscsi_mgmt_task *mtask, iscsi_buf_init_iov(&tcp_mtask->headbuf, (char*)mtask->hdr, sizeof(struct iscsi_hdr)); tcp_mtask->xmstate = XMSTATE_IMM_HDR; - tcp_mtask->sent = 0; if (mtask->data_count) iscsi_buf_init_iov(&tcp_mtask->sendbuf, (char*)mtask->data, @@ -2124,6 +2138,39 @@ iscsi_conn_set_param(struct iscsi_cls_conn *cls_conn, enum iscsi_param param, int value; switch(param) { + case ISCSI_PARAM_MAX_RECV_DLENGTH: { + char *saveptr = tcp_conn->data; + gfp_t flags = GFP_KERNEL; + + sscanf(buf, "%d", &value); + if (tcp_conn->data_size >= value) { + iscsi_set_param(cls_conn, param, buf, buflen); + break; + } + + spin_lock_bh(&session->lock); + if (conn->stop_stage == STOP_CONN_RECOVER) + flags = GFP_ATOMIC; + spin_unlock_bh(&session->lock); + + if (value <= PAGE_SIZE) + tcp_conn->data = kmalloc(value, flags); + else + tcp_conn->data = (void*)__get_free_pages(flags, + get_order(value)); + if (tcp_conn->data == NULL) { + tcp_conn->data = saveptr; + return -ENOMEM; + } + if (tcp_conn->data_size <= PAGE_SIZE) + kfree(saveptr); + else + free_pages((unsigned long)saveptr, + get_order(tcp_conn->data_size)); + iscsi_set_param(cls_conn, param, buf, buflen); + tcp_conn->data_size = value; + break; + } case ISCSI_PARAM_HDRDGST_EN: iscsi_set_param(cls_conn, param, buf, buflen); tcp_conn->hdr_size = sizeof(struct iscsi_hdr); @@ -2314,7 +2361,8 @@ static void iscsi_tcp_session_destroy(struct iscsi_cls_session *cls_session) } static struct scsi_host_template iscsi_sht = { - .name = "iSCSI Initiator over TCP/IP", + .name = "iSCSI Initiator over TCP/IP, v" + ISCSI_TCP_VERSION, .queuecommand = iscsi_queuecommand, .change_queue_depth = iscsi_change_queue_depth, .can_queue = ISCSI_XMIT_CMDS_MAX - 1, @@ -2366,7 +2414,10 @@ static struct iscsi_transport iscsi_tcp_transport = { .get_conn_param = iscsi_tcp_conn_get_param, .get_session_param = iscsi_session_get_param, .start_conn = iscsi_conn_start, - .stop_conn = iscsi_tcp_conn_stop, + .stop_conn = iscsi_conn_stop, + /* these are called as part of conn recovery */ + .suspend_conn_recv = iscsi_tcp_suspend_conn_rx, + .terminate_conn = iscsi_tcp_terminate_conn, /* IO */ .send_pdu = iscsi_conn_send_pdu, .get_stats = iscsi_conn_get_stats, diff --git a/trunk/drivers/scsi/iscsi_tcp.h b/trunk/drivers/scsi/iscsi_tcp.h index 6a4ee704e46e..808302832e68 100644 --- a/trunk/drivers/scsi/iscsi_tcp.h +++ b/trunk/drivers/scsi/iscsi_tcp.h @@ -78,6 +78,8 @@ struct iscsi_tcp_conn { char hdrext[4*sizeof(__u16) + sizeof(__u32)]; int data_copied; + char *data; /* data placeholder */ + int data_size; /* actual recv_dlength */ int stop_stage; /* conn_stop() flag: * * stop to recover, * * stop to terminate */ diff --git a/trunk/drivers/scsi/libata-core.c b/trunk/drivers/scsi/libata-core.c index 73dd6c8deede..16fc2dd8f2f7 100644 --- a/trunk/drivers/scsi/libata-core.c +++ b/trunk/drivers/scsi/libata-core.c @@ -2746,7 +2746,7 @@ int sata_std_hardreset(struct ata_port *ap, unsigned int *class) if ((rc = sata_scr_read(ap, SCR_CONTROL, &scontrol))) return rc; - scontrol = (scontrol & 0x0f0) | 0x304; + scontrol = (scontrol & 0x0f0) | 0x302; if ((rc = sata_scr_write(ap, SCR_CONTROL, scontrol))) return rc; diff --git a/trunk/drivers/scsi/libiscsi.c b/trunk/drivers/scsi/libiscsi.c index 5884cd26d53a..7e6e031cc41b 100644 --- a/trunk/drivers/scsi/libiscsi.c +++ b/trunk/drivers/scsi/libiscsi.c @@ -189,7 +189,6 @@ static void iscsi_complete_command(struct iscsi_session *session, { struct scsi_cmnd *sc = ctask->sc; - ctask->state = ISCSI_TASK_COMPLETED; ctask->sc = NULL; list_del_init(&ctask->running); __kfifo_put(session->cmdpool.queue, (void*)&ctask, sizeof(void*)); @@ -276,25 +275,6 @@ static int iscsi_scsi_cmd_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr, return rc; } -static void iscsi_tmf_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr) -{ - struct iscsi_tm_rsp *tmf = (struct iscsi_tm_rsp *)hdr; - - conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1; - conn->tmfrsp_pdus_cnt++; - - if (conn->tmabort_state != TMABORT_INITIAL) - return; - - if (tmf->response == ISCSI_TMF_RSP_COMPLETE) - conn->tmabort_state = TMABORT_SUCCESS; - else if (tmf->response == ISCSI_TMF_RSP_NO_TASK) - conn->tmabort_state = TMABORT_NOT_FOUND; - else - conn->tmabort_state = TMABORT_FAILED; - wake_up(&conn->ehwait); -} - /** * __iscsi_complete_pdu - complete pdu * @conn: iscsi conn @@ -360,10 +340,6 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, switch(opcode) { case ISCSI_OP_LOGOUT_RSP: - if (datalen) { - rc = ISCSI_ERR_PROTO; - break; - } conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1; /* fall through */ case ISCSI_OP_LOGIN_RSP: @@ -372,8 +348,7 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, * login related PDU's exp_statsn is handled in * userspace */ - if (iscsi_recv_pdu(conn->cls_conn, hdr, data, datalen)) - rc = ISCSI_ERR_CONN_FAILED; + rc = iscsi_recv_pdu(conn->cls_conn, hdr, data, datalen); list_del(&mtask->running); if (conn->login_mtask != mtask) __kfifo_put(session->mgmtpool.queue, @@ -385,17 +360,25 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, break; } - iscsi_tmf_rsp(conn, hdr); + conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1; + conn->tmfrsp_pdus_cnt++; + if (conn->tmabort_state == TMABORT_INITIAL) { + conn->tmabort_state = + ((struct iscsi_tm_rsp *)hdr)-> + response == ISCSI_TMF_RSP_COMPLETE ? + TMABORT_SUCCESS:TMABORT_FAILED; + /* unblock eh_abort() */ + wake_up(&conn->ehwait); + } break; case ISCSI_OP_NOOP_IN: - if (hdr->ttt != ISCSI_RESERVED_TAG || datalen) { + if (hdr->ttt != ISCSI_RESERVED_TAG) { rc = ISCSI_ERR_PROTO; break; } conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1; - if (iscsi_recv_pdu(conn->cls_conn, hdr, data, datalen)) - rc = ISCSI_ERR_CONN_FAILED; + rc = iscsi_recv_pdu(conn->cls_conn, hdr, data, datalen); list_del(&mtask->running); if (conn->login_mtask != mtask) __kfifo_put(session->mgmtpool.queue, @@ -408,21 +391,14 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, } else if (itt == ISCSI_RESERVED_TAG) { switch(opcode) { case ISCSI_OP_NOOP_IN: - if (datalen) { - rc = ISCSI_ERR_PROTO; - break; - } - - rc = iscsi_check_assign_cmdsn(session, + if (!datalen) { + rc = iscsi_check_assign_cmdsn(session, (struct iscsi_nopin*)hdr); - if (rc) - break; - - if (hdr->ttt == ISCSI_RESERVED_TAG) - break; - - if (iscsi_recv_pdu(conn->cls_conn, hdr, NULL, 0)) - rc = ISCSI_ERR_CONN_FAILED; + if (!rc && hdr->ttt != ISCSI_RESERVED_TAG) + rc = iscsi_recv_pdu(conn->cls_conn, + hdr, NULL, 0); + } else + rc = ISCSI_ERR_PROTO; break; case ISCSI_OP_REJECT: /* we need sth like iscsi_reject_rsp()*/ @@ -592,24 +568,20 @@ static int iscsi_data_xmit(struct iscsi_conn *conn) } /* process command queue */ - spin_lock_bh(&conn->session->lock); - while (!list_empty(&conn->xmitqueue)) { + while (__kfifo_get(conn->xmitqueue, (void*)&conn->ctask, + sizeof(void*))) { /* * iscsi tcp may readd the task to the xmitqueue to send * write data */ - conn->ctask = list_entry(conn->xmitqueue.next, - struct iscsi_cmd_task, running); - conn->ctask->state = ISCSI_TASK_RUNNING; - list_move_tail(conn->xmitqueue.next, &conn->run_list); + spin_lock_bh(&conn->session->lock); + if (list_empty(&conn->ctask->running)) + list_add_tail(&conn->ctask->running, &conn->run_list); spin_unlock_bh(&conn->session->lock); - rc = tt->xmit_cmd_task(conn, conn->ctask); if (rc) goto again; - spin_lock_bh(&conn->session->lock); } - spin_unlock_bh(&conn->session->lock); /* done with this ctask */ conn->ctask = NULL; @@ -719,7 +691,6 @@ int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)) sc->SCp.phase = session->age; sc->SCp.ptr = (char *)ctask; - ctask->state = ISCSI_TASK_PENDING; ctask->mtask = NULL; ctask->conn = conn; ctask->sc = sc; @@ -729,7 +700,7 @@ int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)) session->tt->init_cmd_task(ctask); - list_add_tail(&ctask->running, &conn->xmitqueue); + __kfifo_put(conn->xmitqueue, (void*)&ctask, sizeof(void*)); debug_scsi( "ctask enq [%s cid %d sc %lx itt 0x%x len %d cmdsn %d win %d]\n", sc->sc_data_direction == DMA_TO_DEVICE ? "write" : "read", @@ -1006,28 +977,32 @@ static int iscsi_exec_abort_task(struct scsi_cmnd *sc, /* * xmit mutex and session lock must be held */ -static struct iscsi_mgmt_task * -iscsi_remove_mgmt_task(struct kfifo *fifo, uint32_t itt) -{ - int i, nr_tasks = __kfifo_len(fifo) / sizeof(void*); - struct iscsi_mgmt_task *task; - - debug_scsi("searching %d tasks\n", nr_tasks); - - for (i = 0; i < nr_tasks; i++) { - __kfifo_get(fifo, (void*)&task, sizeof(void*)); - debug_scsi("check task %u\n", task->itt); - - if (task->itt == itt) { - debug_scsi("matched task\n"); - return task; - } - - __kfifo_put(fifo, (void*)&task, sizeof(void*)); - } - return NULL; +#define iscsi_remove_task(tasktype) \ +static struct iscsi_##tasktype * \ +iscsi_remove_##tasktype(struct kfifo *fifo, uint32_t itt) \ +{ \ + int i, nr_tasks = __kfifo_len(fifo) / sizeof(void*); \ + struct iscsi_##tasktype *task; \ + \ + debug_scsi("searching %d tasks\n", nr_tasks); \ + \ + for (i = 0; i < nr_tasks; i++) { \ + __kfifo_get(fifo, (void*)&task, sizeof(void*)); \ + debug_scsi("check task %u\n", task->itt); \ + \ + if (task->itt == itt) { \ + debug_scsi("matched task\n"); \ + return task; \ + } \ + \ + __kfifo_put(fifo, (void*)&task, sizeof(void*)); \ + } \ + return NULL; \ } +iscsi_remove_task(mgmt_task); +iscsi_remove_task(cmd_task); + static int iscsi_ctask_mtask_cleanup(struct iscsi_cmd_task *ctask) { struct iscsi_conn *conn = ctask->conn; @@ -1052,13 +1027,12 @@ static void fail_command(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask, { struct scsi_cmnd *sc; - sc = ctask->sc; - if (!sc) - return; - conn->session->tt->cleanup_cmd_task(conn, ctask); iscsi_ctask_mtask_cleanup(ctask); + sc = ctask->sc; + if (!sc) + return; sc->result = err; sc->resid = sc->request_bufflen; iscsi_complete_command(conn->session, ctask); @@ -1069,6 +1043,7 @@ int iscsi_eh_abort(struct scsi_cmnd *sc) struct iscsi_cmd_task *ctask = (struct iscsi_cmd_task *)sc->SCp.ptr; struct iscsi_conn *conn = ctask->conn; struct iscsi_session *session = conn->session; + struct iscsi_cmd_task *pending_ctask; int rc; conn->eh_abort_cnt++; @@ -1086,11 +1061,8 @@ int iscsi_eh_abort(struct scsi_cmnd *sc) goto failed; /* ctask completed before time out */ - if (!ctask->sc) { - spin_unlock_bh(&session->lock); - debug_scsi("sc completed while abort in progress\n"); - goto success_rel_mutex; - } + if (!ctask->sc) + goto success; /* what should we do here ? */ if (conn->ctask == ctask) { @@ -1099,8 +1071,17 @@ int iscsi_eh_abort(struct scsi_cmnd *sc) goto failed; } - if (ctask->state == ISCSI_TASK_PENDING) - goto success_cleanup; + /* check for the easy pending cmd abort */ + pending_ctask = iscsi_remove_cmd_task(conn->xmitqueue, ctask->itt); + if (pending_ctask) { + /* iscsi_tcp queues write transfers on the xmitqueue */ + if (list_empty(&pending_ctask->running)) { + debug_scsi("found pending task\n"); + goto success; + } else + __kfifo_put(conn->xmitqueue, (void*)&pending_ctask, + sizeof(void*)); + } conn->tmabort_state = TMABORT_INITIAL; @@ -1108,31 +1089,25 @@ int iscsi_eh_abort(struct scsi_cmnd *sc) rc = iscsi_exec_abort_task(sc, ctask); spin_lock_bh(&session->lock); + iscsi_ctask_mtask_cleanup(ctask); if (rc || sc->SCp.phase != session->age || session->state != ISCSI_STATE_LOGGED_IN) goto failed; - iscsi_ctask_mtask_cleanup(ctask); - switch (conn->tmabort_state) { - case TMABORT_SUCCESS: - goto success_cleanup; - case TMABORT_NOT_FOUND: - if (!ctask->sc) { - /* ctask completed before tmf abort response */ - spin_unlock_bh(&session->lock); - debug_scsi("sc completed while abort in progress\n"); - goto success_rel_mutex; - } - /* fall through */ - default: - /* timedout or failed */ + /* ctask completed before tmf abort response */ + if (!ctask->sc) { + debug_scsi("sc completed while abort in progress\n"); + goto success; + } + + if (conn->tmabort_state != TMABORT_SUCCESS) { spin_unlock_bh(&session->lock); iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); spin_lock_bh(&session->lock); goto failed; } -success_cleanup: +success: debug_scsi("abort success [sc %lx itt 0x%x]\n", (long)sc, ctask->itt); spin_unlock_bh(&session->lock); @@ -1146,7 +1121,6 @@ int iscsi_eh_abort(struct scsi_cmnd *sc) spin_unlock(&session->lock); write_unlock_bh(conn->recv_lock); -success_rel_mutex: mutex_unlock(&conn->xmitmutex); return SUCCESS; @@ -1289,7 +1263,6 @@ iscsi_session_setup(struct iscsi_transport *iscsit, if (cmd_task_size) ctask->dd_data = &ctask[1]; ctask->itt = cmd_i; - INIT_LIST_HEAD(&ctask->running); } spin_lock_init(&session->lock); @@ -1309,7 +1282,6 @@ iscsi_session_setup(struct iscsi_transport *iscsit, if (mgmt_task_size) mtask->dd_data = &mtask[1]; mtask->itt = ISCSI_MGMT_ITT_OFFSET + cmd_i; - INIT_LIST_HEAD(&mtask->running); } if (scsi_add_host(shost, NULL)) @@ -1350,18 +1322,15 @@ void iscsi_session_teardown(struct iscsi_cls_session *cls_session) { struct Scsi_Host *shost = iscsi_session_to_shost(cls_session); struct iscsi_session *session = iscsi_hostdata(shost->hostdata); - struct module *owner = cls_session->transport->owner; scsi_remove_host(shost); iscsi_pool_free(&session->mgmtpool, (void**)session->mgmt_cmds); iscsi_pool_free(&session->cmdpool, (void**)session->cmds); - kfree(session->targetname); - iscsi_destroy_session(cls_session); scsi_host_put(shost); - module_put(owner); + module_put(cls_session->transport->owner); } EXPORT_SYMBOL_GPL(iscsi_session_teardown); @@ -1392,7 +1361,12 @@ iscsi_conn_setup(struct iscsi_cls_session *cls_session, uint32_t conn_idx) conn->tmabort_state = TMABORT_INITIAL; INIT_LIST_HEAD(&conn->run_list); INIT_LIST_HEAD(&conn->mgmt_run_list); - INIT_LIST_HEAD(&conn->xmitqueue); + + /* initialize general xmit PDU commands queue */ + conn->xmitqueue = kfifo_alloc(session->cmds_max * sizeof(void*), + GFP_KERNEL, NULL); + if (conn->xmitqueue == ERR_PTR(-ENOMEM)) + goto xmitqueue_alloc_fail; /* initialize general immediate & non-immediate PDU commands queue */ conn->immqueue = kfifo_alloc(session->mgmtpool_max * sizeof(void*), @@ -1420,7 +1394,7 @@ iscsi_conn_setup(struct iscsi_cls_session *cls_session, uint32_t conn_idx) data = kmalloc(DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH, GFP_KERNEL); if (!data) goto login_mtask_data_alloc_fail; - conn->login_mtask->data = conn->data = data; + conn->login_mtask->data = data; init_timer(&conn->tmabort_timer); mutex_init(&conn->xmitmutex); @@ -1436,6 +1410,8 @@ iscsi_conn_setup(struct iscsi_cls_session *cls_session, uint32_t conn_idx) mgmtqueue_alloc_fail: kfifo_free(conn->immqueue); immqueue_alloc_fail: + kfifo_free(conn->xmitqueue); +xmitqueue_alloc_fail: iscsi_destroy_conn(cls_conn); return NULL; } @@ -1456,6 +1432,12 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn) set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx); mutex_lock(&conn->xmitmutex); + if (conn->c_stage == ISCSI_CONN_INITIAL_STAGE) { + if (session->tt->suspend_conn_recv) + session->tt->suspend_conn_recv(conn); + + session->tt->terminate_conn(conn); + } spin_lock_bh(&session->lock); conn->c_stage = ISCSI_CONN_CLEANUP_WAIT; @@ -1492,8 +1474,7 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn) } spin_lock_bh(&session->lock); - kfree(conn->data); - kfree(conn->persistent_address); + kfree(conn->login_mtask->data); __kfifo_put(session->mgmtpool.queue, (void*)&conn->login_mtask, sizeof(void*)); list_del(&conn->item); @@ -1508,6 +1489,7 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn) session->cmdsn = session->max_cmdsn = session->exp_cmdsn = 1; spin_unlock_bh(&session->lock); + kfifo_free(conn->xmitqueue); kfifo_free(conn->immqueue); kfifo_free(conn->mgmtqueue); @@ -1590,7 +1572,7 @@ static void fail_all_commands(struct iscsi_conn *conn) struct iscsi_cmd_task *ctask, *tmp; /* flush pending */ - list_for_each_entry_safe(ctask, tmp, &conn->xmitqueue, running) { + while (__kfifo_get(conn->xmitqueue, (void*)&ctask, sizeof(void*))) { debug_scsi("failing pending sc %p itt 0x%x\n", ctask->sc, ctask->itt); fail_command(conn, ctask, DID_BUS_BUSY << 16); @@ -1633,9 +1615,8 @@ static void iscsi_start_session_recovery(struct iscsi_session *session, set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx); spin_unlock_bh(&session->lock); - write_lock_bh(conn->recv_lock); - set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_rx); - write_unlock_bh(conn->recv_lock); + if (session->tt->suspend_conn_recv) + session->tt->suspend_conn_recv(conn); mutex_lock(&conn->xmitmutex); /* @@ -1654,6 +1635,7 @@ static void iscsi_start_session_recovery(struct iscsi_session *session, } } + session->tt->terminate_conn(conn); /* * flush queues. */ diff --git a/trunk/drivers/scsi/lpfc/lpfc_attr.c b/trunk/drivers/scsi/lpfc/lpfc_attr.c index d384c16f4a87..5c68cdd8736f 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_attr.c +++ b/trunk/drivers/scsi/lpfc/lpfc_attr.c @@ -222,7 +222,7 @@ lpfc_issue_lip(struct Scsi_Host *host) pmboxq->mb.mbxCommand = MBX_DOWN_LINK; pmboxq->mb.mbxOwner = OWN_HOST; - mbxstatus = lpfc_sli_issue_mbox_wait(phba, pmboxq, LPFC_MBOX_TMO * 2); + mbxstatus = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2); if ((mbxstatus == MBX_SUCCESS) && (pmboxq->mb.mbxStatus == 0)) { memset((void *)pmboxq, 0, sizeof (LPFC_MBOXQ_t)); @@ -884,7 +884,7 @@ sysfs_mbox_write(struct kobject *kobj, char *buf, loff_t off, size_t count) phba->sysfs_mbox.mbox == NULL ) { sysfs_mbox_idle(phba); spin_unlock_irq(host->host_lock); - return -EAGAIN; + return -EINVAL; } } @@ -1000,15 +1000,14 @@ sysfs_mbox_read(struct kobject *kobj, char *buf, loff_t off, size_t count) spin_unlock_irq(phba->host->host_lock); rc = lpfc_sli_issue_mbox_wait (phba, phba->sysfs_mbox.mbox, - lpfc_mbox_tmo_val(phba, - phba->sysfs_mbox.mbox->mb.mbxCommand) * HZ); + phba->fc_ratov * 2); spin_lock_irq(phba->host->host_lock); } if (rc != MBX_SUCCESS) { sysfs_mbox_idle(phba); spin_unlock_irq(host->host_lock); - return (rc == MBX_TIMEOUT) ? -ETIME : -ENODEV; + return -ENODEV; } phba->sysfs_mbox.state = SMBOX_READING; } @@ -1017,7 +1016,7 @@ sysfs_mbox_read(struct kobject *kobj, char *buf, loff_t off, size_t count) printk(KERN_WARNING "mbox_read: Bad State\n"); sysfs_mbox_idle(phba); spin_unlock_irq(host->host_lock); - return -EAGAIN; + return -EINVAL; } memcpy(buf, (uint8_t *) & phba->sysfs_mbox.mbox->mb + off, count); @@ -1211,10 +1210,8 @@ lpfc_get_stats(struct Scsi_Host *shost) struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata; struct lpfc_sli *psli = &phba->sli; struct fc_host_statistics *hs = &phba->link_stats; - struct lpfc_lnk_stat * lso = &psli->lnk_stat_offsets; LPFC_MBOXQ_t *pmboxq; MAILBOX_t *pmb; - unsigned long seconds; int rc = 0; pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); @@ -1275,103 +1272,22 @@ lpfc_get_stats(struct Scsi_Host *shost) hs->invalid_crc_count = pmb->un.varRdLnk.crcCnt; hs->error_frames = pmb->un.varRdLnk.crcCnt; - hs->link_failure_count -= lso->link_failure_count; - hs->loss_of_sync_count -= lso->loss_of_sync_count; - hs->loss_of_signal_count -= lso->loss_of_signal_count; - hs->prim_seq_protocol_err_count -= lso->prim_seq_protocol_err_count; - hs->invalid_tx_word_count -= lso->invalid_tx_word_count; - hs->invalid_crc_count -= lso->invalid_crc_count; - hs->error_frames -= lso->error_frames; - if (phba->fc_topology == TOPOLOGY_LOOP) { hs->lip_count = (phba->fc_eventTag >> 1); - hs->lip_count -= lso->link_events; hs->nos_count = -1; } else { hs->lip_count = -1; hs->nos_count = (phba->fc_eventTag >> 1); - hs->nos_count -= lso->link_events; } hs->dumped_frames = -1; - seconds = get_seconds(); - if (seconds < psli->stats_start) - hs->seconds_since_last_reset = seconds + - ((unsigned long)-1 - psli->stats_start); - else - hs->seconds_since_last_reset = seconds - psli->stats_start; +/* FIX ME */ + /*hs->SecondsSinceLastReset = (jiffies - lpfc_loadtime) / HZ;*/ return hs; } -static void -lpfc_reset_stats(struct Scsi_Host *shost) -{ - struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata; - struct lpfc_sli *psli = &phba->sli; - struct lpfc_lnk_stat * lso = &psli->lnk_stat_offsets; - LPFC_MBOXQ_t *pmboxq; - MAILBOX_t *pmb; - int rc = 0; - - pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); - if (!pmboxq) - return; - memset(pmboxq, 0, sizeof(LPFC_MBOXQ_t)); - - pmb = &pmboxq->mb; - pmb->mbxCommand = MBX_READ_STATUS; - pmb->mbxOwner = OWN_HOST; - pmb->un.varWords[0] = 0x1; /* reset request */ - pmboxq->context1 = NULL; - - if ((phba->fc_flag & FC_OFFLINE_MODE) || - (!(psli->sli_flag & LPFC_SLI2_ACTIVE))) - rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL); - else - rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2); - - if (rc != MBX_SUCCESS) { - if (rc == MBX_TIMEOUT) - pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl; - else - mempool_free(pmboxq, phba->mbox_mem_pool); - return; - } - - memset(pmboxq, 0, sizeof(LPFC_MBOXQ_t)); - pmb->mbxCommand = MBX_READ_LNK_STAT; - pmb->mbxOwner = OWN_HOST; - pmboxq->context1 = NULL; - - if ((phba->fc_flag & FC_OFFLINE_MODE) || - (!(psli->sli_flag & LPFC_SLI2_ACTIVE))) - rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL); - else - rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2); - - if (rc != MBX_SUCCESS) { - if (rc == MBX_TIMEOUT) - pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl; - else - mempool_free( pmboxq, phba->mbox_mem_pool); - return; - } - - lso->link_failure_count = pmb->un.varRdLnk.linkFailureCnt; - lso->loss_of_sync_count = pmb->un.varRdLnk.lossSyncCnt; - lso->loss_of_signal_count = pmb->un.varRdLnk.lossSignalCnt; - lso->prim_seq_protocol_err_count = pmb->un.varRdLnk.primSeqErrCnt; - lso->invalid_tx_word_count = pmb->un.varRdLnk.invalidXmitWord; - lso->invalid_crc_count = pmb->un.varRdLnk.crcCnt; - lso->error_frames = pmb->un.varRdLnk.crcCnt; - lso->link_events = (phba->fc_eventTag >> 1); - - psli->stats_start = get_seconds(); - - return; -} /* * The LPFC driver treats linkdown handling as target loss events so there @@ -1515,7 +1431,8 @@ struct fc_function_template lpfc_transport_functions = { */ .get_fc_host_stats = lpfc_get_stats, - .reset_fc_host_stats = lpfc_reset_stats, + + /* the LPFC driver doesn't support resetting stats yet */ .dd_fcrport_size = sizeof(struct lpfc_rport_data), .show_rport_maxframe_size = 1, diff --git a/trunk/drivers/scsi/lpfc/lpfc_crtn.h b/trunk/drivers/scsi/lpfc/lpfc_crtn.h index 2a176467f71b..517e9e4dd461 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_crtn.h +++ b/trunk/drivers/scsi/lpfc/lpfc_crtn.h @@ -127,7 +127,6 @@ void lpfc_config_port(struct lpfc_hba *, LPFC_MBOXQ_t *); void lpfc_kill_board(struct lpfc_hba *, LPFC_MBOXQ_t *); void lpfc_mbox_put(struct lpfc_hba *, LPFC_MBOXQ_t *); LPFC_MBOXQ_t *lpfc_mbox_get(struct lpfc_hba *); -int lpfc_mbox_tmo_val(struct lpfc_hba *, int); int lpfc_mem_alloc(struct lpfc_hba *); void lpfc_mem_free(struct lpfc_hba *); diff --git a/trunk/drivers/scsi/lpfc/lpfc_ct.c b/trunk/drivers/scsi/lpfc/lpfc_ct.c index bbb7310210b0..b65ee57af53e 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_ct.c +++ b/trunk/drivers/scsi/lpfc/lpfc_ct.c @@ -131,7 +131,6 @@ lpfc_ct_unsol_event(struct lpfc_hba * phba, } ct_unsol_event_exit_piocbq: - list_del(&head); if (pmbuf) { list_for_each_entry_safe(matp, next_matp, &pmbuf->list, list) { lpfc_mbuf_free(phba, matp->virt, matp->phys); @@ -482,7 +481,7 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, if (CTrsp->CommandResponse.bits.CmdRsp == be16_to_cpu(SLI_CT_RESPONSE_FS_ACC)) { lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, - "%d:0208 NameServer Rsp " + "%d:0239 NameServer Rsp " "Data: x%x\n", phba->brd_no, phba->fc_flag); @@ -589,9 +588,13 @@ lpfc_get_hba_sym_node_name(struct lpfc_hba * phba, uint8_t * symbp) lpfc_decode_firmware_rev(phba, fwrev, 0); - sprintf(symbp, "Emulex %s FV%s DV%s", phba->ModelName, - fwrev, lpfc_release_version); - return; + if (phba->Port[0]) { + sprintf(symbp, "Emulex %s Port %s FV%s DV%s", phba->ModelName, + phba->Port, fwrev, lpfc_release_version); + } else { + sprintf(symbp, "Emulex %s FV%s DV%s", phba->ModelName, + fwrev, lpfc_release_version); + } } /* diff --git a/trunk/drivers/scsi/lpfc/lpfc_els.c b/trunk/drivers/scsi/lpfc/lpfc_els.c index 3567de613162..b89f6cb641e6 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_els.c +++ b/trunk/drivers/scsi/lpfc/lpfc_els.c @@ -1848,12 +1848,9 @@ static void lpfc_cmpl_els_acc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, struct lpfc_iocbq * rspiocb) { - IOCB_t *irsp; struct lpfc_nodelist *ndlp; LPFC_MBOXQ_t *mbox = NULL; - irsp = &rspiocb->iocb; - ndlp = (struct lpfc_nodelist *) cmdiocb->context1; if (cmdiocb->context_un.mbox) mbox = cmdiocb->context_un.mbox; @@ -1896,15 +1893,9 @@ lpfc_cmpl_els_acc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, mempool_free( mbox, phba->mbox_mem_pool); } else { mempool_free( mbox, phba->mbox_mem_pool); - /* Do not call NO_LIST for lpfc_els_abort'ed ELS cmds */ - if (!((irsp->ulpStatus == IOSTAT_LOCAL_REJECT) && - ((irsp->un.ulpWord[4] == IOERR_SLI_ABORTED) || - (irsp->un.ulpWord[4] == IOERR_LINK_DOWN) || - (irsp->un.ulpWord[4] == IOERR_SLI_DOWN)))) { - if (ndlp->nlp_flag & NLP_ACC_REGLOGIN) { - lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); - ndlp = NULL; - } + if (ndlp->nlp_flag & NLP_ACC_REGLOGIN) { + lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); + ndlp = NULL; } } } @@ -2848,7 +2839,7 @@ lpfc_els_rsp_rps_acc(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) /* Xmit ELS RPS ACC response tag */ lpfc_printf_log(phba, KERN_INFO, LOG_ELS, - "%d:0118 Xmit ELS RPS ACC response tag x%x " + "%d:0128 Xmit ELS RPS ACC response tag x%x " "Data: x%x x%x x%x x%x x%x\n", phba->brd_no, elsiocb->iocb.ulpIoTag, @@ -2957,7 +2948,7 @@ lpfc_els_rsp_rpl_acc(struct lpfc_hba * phba, uint16_t cmdsize, /* Xmit ELS RPL ACC response tag */ lpfc_printf_log(phba, KERN_INFO, LOG_ELS, - "%d:0120 Xmit ELS RPL ACC response tag x%x " + "%d:0128 Xmit ELS RPL ACC response tag x%x " "Data: x%x x%x x%x x%x x%x\n", phba->brd_no, elsiocb->iocb.ulpIoTag, @@ -3118,7 +3109,7 @@ lpfc_els_rcv_fan(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, struct lpfc_nodelist *ndlp, *next_ndlp; /* FAN received */ - lpfc_printf_log(phba, KERN_INFO, LOG_ELS, "%d:0265 FAN received\n", + lpfc_printf_log(phba, KERN_INFO, LOG_ELS, "%d:265 FAN received\n", phba->brd_no); icmd = &cmdiocb->iocb; diff --git a/trunk/drivers/scsi/lpfc/lpfc_hbadisc.c b/trunk/drivers/scsi/lpfc/lpfc_hbadisc.c index b2f1552f1848..4d6cf990c4fc 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/trunk/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -1557,8 +1557,6 @@ lpfc_freenode(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) mb->mbox_cmpl = lpfc_sli_def_mbox_cmpl; } } - - spin_lock_irq(phba->host->host_lock); list_for_each_entry_safe(mb, nextmb, &phba->sli.mboxq, list) { if ((mb->mb.mbxCommand == MBX_REG_LOGIN64) && (ndlp == (struct lpfc_nodelist *) mb->context2)) { @@ -1571,7 +1569,6 @@ lpfc_freenode(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) mempool_free(mb, phba->mbox_mem_pool); } } - spin_unlock_irq(phba->host->host_lock); lpfc_els_abort(phba,ndlp,0); spin_lock_irq(phba->host->host_lock); @@ -1785,7 +1782,7 @@ lpfc_findnode_did(struct lpfc_hba * phba, uint32_t order, uint32_t did) /* LOG change to REGLOGIN */ /* FIND node DID reglogin */ lpfc_printf_log(phba, KERN_INFO, LOG_NODE, - "%d:0901 FIND node DID reglogin" + "%d:0931 FIND node DID reglogin" " Data: x%p x%x x%x x%x\n", phba->brd_no, ndlp, ndlp->nlp_DID, @@ -1808,7 +1805,7 @@ lpfc_findnode_did(struct lpfc_hba * phba, uint32_t order, uint32_t did) /* LOG change to PRLI */ /* FIND node DID prli */ lpfc_printf_log(phba, KERN_INFO, LOG_NODE, - "%d:0902 FIND node DID prli " + "%d:0931 FIND node DID prli " "Data: x%p x%x x%x x%x\n", phba->brd_no, ndlp, ndlp->nlp_DID, @@ -1831,7 +1828,7 @@ lpfc_findnode_did(struct lpfc_hba * phba, uint32_t order, uint32_t did) /* LOG change to NPR */ /* FIND node DID npr */ lpfc_printf_log(phba, KERN_INFO, LOG_NODE, - "%d:0903 FIND node DID npr " + "%d:0931 FIND node DID npr " "Data: x%p x%x x%x x%x\n", phba->brd_no, ndlp, ndlp->nlp_DID, @@ -1854,7 +1851,7 @@ lpfc_findnode_did(struct lpfc_hba * phba, uint32_t order, uint32_t did) /* LOG change to UNUSED */ /* FIND node DID unused */ lpfc_printf_log(phba, KERN_INFO, LOG_NODE, - "%d:0905 FIND node DID unused " + "%d:0931 FIND node DID unused " "Data: x%p x%x x%x x%x\n", phba->brd_no, ndlp, ndlp->nlp_DID, @@ -2338,7 +2335,7 @@ lpfc_disc_timeout_handler(struct lpfc_hba *phba) initlinkmbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); if (!initlinkmbox) { lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, - "%d:0206 Device Discovery " + "%d:0226 Device Discovery " "completion error\n", phba->brd_no); phba->hba_state = LPFC_HBA_ERROR; @@ -2368,7 +2365,7 @@ lpfc_disc_timeout_handler(struct lpfc_hba *phba) if (!clearlambox) { clrlaerr = 1; lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, - "%d:0207 Device Discovery " + "%d:0226 Device Discovery " "completion error\n", phba->brd_no); phba->hba_state = LPFC_HBA_ERROR; diff --git a/trunk/drivers/scsi/lpfc/lpfc_init.c b/trunk/drivers/scsi/lpfc/lpfc_init.c index f6948ffe689a..ef47b824cbed 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_init.c +++ b/trunk/drivers/scsi/lpfc/lpfc_init.c @@ -1379,7 +1379,6 @@ lpfc_offline(struct lpfc_hba * phba) /* stop all timers associated with this hba */ lpfc_stop_timer(phba); phba->work_hba_events = 0; - phba->work_ha = 0; lpfc_printf_log(phba, KERN_WARNING, @@ -1617,11 +1616,7 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) goto out_free_iocbq; } - /* - * Set initial can_queue value since 0 is no longer supported and - * scsi_add_host will fail. This will be adjusted later based on the - * max xri value determined in hba setup. - */ + /* We can rely on a queue depth attribute only after SLI HBA setup */ host->can_queue = phba->cfg_hba_queue_depth - 10; /* Tell the midlayer we support 16 byte commands */ @@ -1661,12 +1656,6 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) goto out_free_irq; } - /* - * hba setup may have changed the hba_queue_depth so we need to adjust - * the value of can_queue. - */ - host->can_queue = phba->cfg_hba_queue_depth - 10; - lpfc_discovery_wait(phba); if (phba->cfg_poll & DISABLE_FCP_RING_INT) { diff --git a/trunk/drivers/scsi/lpfc/lpfc_mbox.c b/trunk/drivers/scsi/lpfc/lpfc_mbox.c index 4d016c2a1b26..e42f22aaf71b 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_mbox.c +++ b/trunk/drivers/scsi/lpfc/lpfc_mbox.c @@ -651,19 +651,3 @@ lpfc_mbox_get(struct lpfc_hba * phba) return mbq; } - -int -lpfc_mbox_tmo_val(struct lpfc_hba *phba, int cmd) -{ - switch (cmd) { - case MBX_WRITE_NV: /* 0x03 */ - case MBX_UPDATE_CFG: /* 0x1B */ - case MBX_DOWN_LOAD: /* 0x1C */ - case MBX_DEL_LD_ENTRY: /* 0x1D */ - case MBX_LOAD_AREA: /* 0x81 */ - case MBX_FLASH_WR_ULA: /* 0x98 */ - case MBX_LOAD_EXP_ROM: /* 0x9C */ - return LPFC_MBOX_TMO_FLASH_CMD; - } - return LPFC_MBOX_TMO; -} diff --git a/trunk/drivers/scsi/lpfc/lpfc_nportdisc.c b/trunk/drivers/scsi/lpfc/lpfc_nportdisc.c index 20449a8dd53d..bd0b0e293d63 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/trunk/drivers/scsi/lpfc/lpfc_nportdisc.c @@ -179,7 +179,7 @@ lpfc_els_abort(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, /* Abort outstanding I/O on NPort */ lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, - "%d:0205 Abort outstanding I/O on NPort x%x " + "%d:0201 Abort outstanding I/O on NPort x%x " "Data: x%x x%x x%x\n", phba->brd_no, ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi); @@ -393,20 +393,6 @@ lpfc_rcv_plogi(struct lpfc_hba * phba, mbox->context2 = ndlp; ndlp->nlp_flag |= (NLP_ACC_REGLOGIN | NLP_RCV_PLOGI); - /* - * If there is an outstanding PLOGI issued, abort it before - * sending ACC rsp for received PLOGI. If pending plogi - * is not canceled here, the plogi will be rejected by - * remote port and will be retried. On a configuration with - * single discovery thread, this will cause a huge delay in - * discovery. Also this will cause multiple state machines - * running in parallel for this node. - */ - if (ndlp->nlp_state == NLP_STE_PLOGI_ISSUE) { - /* software abort outstanding PLOGI */ - lpfc_els_abort(phba, ndlp, 1); - } - lpfc_els_rsp_acc(phba, ELS_CMD_PLOGI, cmdiocb, ndlp, mbox, 0); return 1; @@ -1615,13 +1601,7 @@ lpfc_rcv_padisc_npr_node(struct lpfc_hba * phba, lpfc_rcv_padisc(phba, ndlp, cmdiocb); - /* - * Do not start discovery if discovery is about to start - * or discovery in progress for this node. Starting discovery - * here will affect the counting of discovery threads. - */ - if ((!(ndlp->nlp_flag & NLP_DELAY_TMO)) && - (ndlp->nlp_flag & NLP_NPR_2B_DISC)){ + if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) { if (ndlp->nlp_flag & NLP_NPR_ADISC) { ndlp->nlp_prev_state = NLP_STE_NPR_NODE; ndlp->nlp_state = NLP_STE_ADISC_ISSUE; diff --git a/trunk/drivers/scsi/lpfc/lpfc_scsi.c b/trunk/drivers/scsi/lpfc/lpfc_scsi.c index a8816a8738f8..a760a44173df 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_scsi.c +++ b/trunk/drivers/scsi/lpfc/lpfc_scsi.c @@ -21,7 +21,6 @@ #include #include -#include #include #include @@ -842,21 +841,6 @@ lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *)) return 0; } -static void -lpfc_block_error_handler(struct scsi_cmnd *cmnd) -{ - struct Scsi_Host *shost = cmnd->device->host; - struct fc_rport *rport = starget_to_rport(scsi_target(cmnd->device)); - - spin_lock_irq(shost->host_lock); - while (rport->port_state == FC_PORTSTATE_BLOCKED) { - spin_unlock_irq(shost->host_lock); - msleep(1000); - spin_lock_irq(shost->host_lock); - } - spin_unlock_irq(shost->host_lock); - return; -} static int lpfc_abort_handler(struct scsi_cmnd *cmnd) @@ -871,7 +855,6 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd) unsigned int loop_count = 0; int ret = SUCCESS; - lpfc_block_error_handler(cmnd); spin_lock_irq(shost->host_lock); lpfc_cmd = (struct lpfc_scsi_buf *)cmnd->host_scribble; @@ -974,7 +957,6 @@ lpfc_reset_lun_handler(struct scsi_cmnd *cmnd) int ret = FAILED; int cnt, loopcnt; - lpfc_block_error_handler(cmnd); spin_lock_irq(shost->host_lock); /* * If target is not in a MAPPED state, delay the reset until @@ -1091,7 +1073,6 @@ lpfc_reset_bus_handler(struct scsi_cmnd *cmnd) int cnt, loopcnt; struct lpfc_scsi_buf * lpfc_cmd; - lpfc_block_error_handler(cmnd); spin_lock_irq(shost->host_lock); lpfc_cmd = lpfc_get_scsi_buf(phba); @@ -1123,7 +1104,7 @@ lpfc_reset_bus_handler(struct scsi_cmnd *cmnd) ndlp->rport->dd_data); if (ret != SUCCESS) { lpfc_printf_log(phba, KERN_ERR, LOG_FCP, - "%d:0700 Bus Reset on target %d failed\n", + "%d:0713 Bus Reset on target %d failed\n", phba->brd_no, i); err_count++; } diff --git a/trunk/drivers/scsi/lpfc/lpfc_sli.c b/trunk/drivers/scsi/lpfc/lpfc_sli.c index 70f4d5a1348e..350a625fa224 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_sli.c +++ b/trunk/drivers/scsi/lpfc/lpfc_sli.c @@ -320,8 +320,7 @@ lpfc_sli_next_iotag(struct lpfc_hba * phba, struct lpfc_iocbq * iocbq) kfree(old_arr); return iotag; } - } else - spin_unlock_irq(phba->host->host_lock); + } lpfc_printf_log(phba, KERN_ERR,LOG_SLI, "%d:0318 Failed to allocate IOTAG.last IOTAG is %d\n", @@ -970,11 +969,9 @@ void lpfc_sli_poll_fcp_ring(struct lpfc_hba * phba) * resources need to be recovered. */ if (unlikely(irsp->ulpCommand == CMD_XRI_ABORTED_CX)) { - lpfc_printf_log(phba, KERN_INFO, LOG_SLI, - "%d:0314 IOCB cmd 0x%x" - " processed. Skipping" - " completion", phba->brd_no, - irsp->ulpCommand); + printk(KERN_INFO "%s: IOCB cmd 0x%x processed." + " Skipping completion\n", __FUNCTION__, + irsp->ulpCommand); break; } @@ -1107,7 +1104,7 @@ lpfc_sli_handle_fast_ring_event(struct lpfc_hba * phba, if (unlikely(irsp->ulpStatus)) { /* Rsp ring error: IOCB */ lpfc_printf_log(phba, KERN_WARNING, LOG_SLI, - "%d:0336 Rsp Ring %d error: IOCB Data: " + "%d:0326 Rsp Ring %d error: IOCB Data: " "x%x x%x x%x x%x x%x x%x x%x x%x\n", phba->brd_no, pring->ringno, irsp->un.ulpWord[0], irsp->un.ulpWord[1], @@ -1125,11 +1122,9 @@ lpfc_sli_handle_fast_ring_event(struct lpfc_hba * phba, * resources need to be recovered. */ if (unlikely(irsp->ulpCommand == CMD_XRI_ABORTED_CX)) { - lpfc_printf_log(phba, KERN_INFO, LOG_SLI, - "%d:0333 IOCB cmd 0x%x" - " processed. Skipping" - " completion\n", phba->brd_no, - irsp->ulpCommand); + printk(KERN_INFO "%s: IOCB cmd 0x%x processed. " + "Skipping completion\n", __FUNCTION__, + irsp->ulpCommand); break; } @@ -1160,7 +1155,7 @@ lpfc_sli_handle_fast_ring_event(struct lpfc_hba * phba, } else { /* Unknown IOCB command */ lpfc_printf_log(phba, KERN_ERR, LOG_SLI, - "%d:0334 Unknown IOCB command " + "%d:0321 Unknown IOCB command " "Data: x%x, x%x x%x x%x x%x\n", phba->brd_no, type, irsp->ulpCommand, irsp->ulpStatus, irsp->ulpIoTag, @@ -1243,7 +1238,7 @@ lpfc_sli_handle_slow_ring_event(struct lpfc_hba * phba, lpfc_printf_log(phba, KERN_ERR, LOG_SLI, - "%d:0303 Ring %d handler: portRspPut %d " + "%d:0312 Ring %d handler: portRspPut %d " "is bigger then rsp ring %d\n", phba->brd_no, pring->ringno, portRspPut, portRspMax); @@ -1388,7 +1383,7 @@ lpfc_sli_handle_slow_ring_event(struct lpfc_hba * phba, lpfc_printf_log(phba, KERN_ERR, LOG_SLI, - "%d:0335 Unknown IOCB command " + "%d:0321 Unknown IOCB command " "Data: x%x x%x x%x x%x\n", phba->brd_no, irsp->ulpCommand, @@ -1404,11 +1399,11 @@ lpfc_sli_handle_slow_ring_event(struct lpfc_hba * phba, next_iocb, &saveq->list, list) { - list_del(&rspiocbp->list); lpfc_sli_release_iocbq(phba, rspiocbp); } } + lpfc_sli_release_iocbq(phba, saveq); } } @@ -1716,13 +1711,15 @@ lpfc_sli_brdreset(struct lpfc_hba * phba) phba->fc_myDID = 0; phba->fc_prevDID = 0; + psli->sli_flag = 0; + /* Turn off parity checking and serr during the physical reset */ pci_read_config_word(phba->pcidev, PCI_COMMAND, &cfg_value); pci_write_config_word(phba->pcidev, PCI_COMMAND, (cfg_value & ~(PCI_COMMAND_PARITY | PCI_COMMAND_SERR))); - psli->sli_flag &= ~(LPFC_SLI2_ACTIVE | LPFC_PROCESS_LA); + psli->sli_flag &= ~LPFC_SLI2_ACTIVE; /* Now toggle INITFF bit in the Host Control Register */ writel(HC_INITFF, phba->HCregaddr); mdelay(1); @@ -1763,7 +1760,7 @@ lpfc_sli_brdrestart(struct lpfc_hba * phba) /* Restart HBA */ lpfc_printf_log(phba, KERN_INFO, LOG_SLI, - "%d:0337 Restart HBA Data: x%x x%x\n", phba->brd_no, + "%d:0328 Restart HBA Data: x%x x%x\n", phba->brd_no, phba->hba_state, psli->sli_flag); word0 = 0; @@ -1795,9 +1792,6 @@ lpfc_sli_brdrestart(struct lpfc_hba * phba) spin_unlock_irq(phba->host->host_lock); - memset(&psli->lnk_stat_offsets, 0, sizeof(psli->lnk_stat_offsets)); - psli->stats_start = get_seconds(); - if (skip_post) mdelay(100); else @@ -1908,9 +1902,6 @@ lpfc_sli_hba_setup(struct lpfc_hba * phba) } while (resetcount < 2 && !done) { - spin_lock_irq(phba->host->host_lock); - phba->sli.sli_flag |= LPFC_SLI_MBOX_ACTIVE; - spin_unlock_irq(phba->host->host_lock); phba->hba_state = LPFC_STATE_UNKNOWN; lpfc_sli_brdrestart(phba); msleep(2500); @@ -1918,9 +1909,6 @@ lpfc_sli_hba_setup(struct lpfc_hba * phba) if (rc) break; - spin_lock_irq(phba->host->host_lock); - phba->sli.sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; - spin_unlock_irq(phba->host->host_lock); resetcount++; /* Call pre CONFIG_PORT mailbox command initialization. A value of 0 @@ -2206,8 +2194,7 @@ lpfc_sli_issue_mbox(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmbox, uint32_t flag) return (MBX_NOT_FINISHED); } /* timeout active mbox command */ - mod_timer(&psli->mbox_tmo, (jiffies + - (HZ * lpfc_mbox_tmo_val(phba, mb->mbxCommand)))); + mod_timer(&psli->mbox_tmo, jiffies + HZ * LPFC_MBOX_TMO); } /* Mailbox cmd issue */ @@ -2267,6 +2254,7 @@ lpfc_sli_issue_mbox(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmbox, uint32_t flag) break; case MBX_POLL: + i = 0; psli->mbox_active = NULL; if (psli->sli_flag & LPFC_SLI2_ACTIVE) { /* First read mbox status word */ @@ -2280,14 +2268,11 @@ lpfc_sli_issue_mbox(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmbox, uint32_t flag) /* Read the HBA Host Attention Register */ ha_copy = readl(phba->HAregaddr); - i = lpfc_mbox_tmo_val(phba, mb->mbxCommand); - i *= 1000; /* Convert to ms */ - /* Wait for command to complete */ while (((word0 & OWN_CHIP) == OWN_CHIP) || (!(ha_copy & HA_MBATT) && (phba->hba_state > LPFC_WARM_START))) { - if (i-- <= 0) { + if (i++ >= 100) { psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; spin_unlock_irqrestore(phba->host->host_lock, drvr_flag); @@ -2305,7 +2290,7 @@ lpfc_sli_issue_mbox(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmbox, uint32_t flag) /* Can be in interrupt context, do not sleep */ /* (or might be called with interrupts disabled) */ - mdelay(1); + mdelay(i); spin_lock_irqsave(phba->host->host_lock, drvr_flag); @@ -3020,7 +3005,7 @@ lpfc_sli_issue_iocb_wait(struct lpfc_hba * phba, if (timeleft == 0) { lpfc_printf_log(phba, KERN_ERR, LOG_SLI, - "%d:0338 IOCB wait timeout error - no " + "%d:0329 IOCB wait timeout error - no " "wake response Data x%x\n", phba->brd_no, timeout); retval = IOCB_TIMEDOUT; diff --git a/trunk/drivers/scsi/lpfc/lpfc_sli.h b/trunk/drivers/scsi/lpfc/lpfc_sli.h index e26de6809358..d8ef0d2894d4 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_sli.h +++ b/trunk/drivers/scsi/lpfc/lpfc_sli.h @@ -172,18 +172,6 @@ struct lpfc_sli_stat { uint32_t mbox_busy; /* Mailbox cmd busy */ }; -/* Structure to store link status values when port stats are reset */ -struct lpfc_lnk_stat { - uint32_t link_failure_count; - uint32_t loss_of_sync_count; - uint32_t loss_of_signal_count; - uint32_t prim_seq_protocol_err_count; - uint32_t invalid_tx_word_count; - uint32_t invalid_crc_count; - uint32_t error_frames; - uint32_t link_events; -}; - /* Structure used to hold SLI information */ struct lpfc_sli { uint32_t num_rings; @@ -213,8 +201,6 @@ struct lpfc_sli { struct lpfc_iocbq ** iocbq_lookup; /* array to lookup IOCB by IOTAG */ size_t iocbq_lookup_len; /* current lengs of the array */ uint16_t last_iotag; /* last allocated IOTAG */ - unsigned long stats_start; /* in seconds */ - struct lpfc_lnk_stat lnk_stat_offsets; }; /* Given a pointer to the start of the ring, and the slot number of @@ -225,9 +211,3 @@ struct lpfc_sli { #define LPFC_MBOX_TMO 30 /* Sec tmo for outstanding mbox command */ -#define LPFC_MBOX_TMO_FLASH_CMD 300 /* Sec tmo for outstanding FLASH write - * or erase cmds. This is especially - * long because of the potential of - * multiple flash erases that can be - * spawned. - */ diff --git a/trunk/drivers/scsi/lpfc/lpfc_version.h b/trunk/drivers/scsi/lpfc/lpfc_version.h index c7091ea29f3f..10e89c6ae823 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_version.h +++ b/trunk/drivers/scsi/lpfc/lpfc_version.h @@ -18,7 +18,7 @@ * included with this package. * *******************************************************************/ -#define LPFC_DRIVER_VERSION "8.1.9" +#define LPFC_DRIVER_VERSION "8.1.7" #define LPFC_DRIVER_NAME "lpfc" diff --git a/trunk/drivers/scsi/megaraid/mega_common.h b/trunk/drivers/scsi/megaraid/mega_common.h index 8cd0bd1d0f7c..4675343228ad 100644 --- a/trunk/drivers/scsi/megaraid/mega_common.h +++ b/trunk/drivers/scsi/megaraid/mega_common.h @@ -37,12 +37,6 @@ #define LSI_MAX_CHANNELS 16 #define LSI_MAX_LOGICAL_DRIVES_64LD (64+1) -#define HBA_SIGNATURE_64_BIT 0x299 -#define PCI_CONF_AMISIG64 0xa4 - -#define MEGA_SCSI_INQ_EVPD 1 -#define MEGA_INVALID_FIELD_IN_CDB 0x24 - /** * scb_t - scsi command control block diff --git a/trunk/drivers/scsi/megaraid/megaraid_ioctl.h b/trunk/drivers/scsi/megaraid/megaraid_ioctl.h index b8aa34202ec3..bdaee144a1c3 100644 --- a/trunk/drivers/scsi/megaraid/megaraid_ioctl.h +++ b/trunk/drivers/scsi/megaraid/megaraid_ioctl.h @@ -132,10 +132,6 @@ typedef struct uioc { /* Driver Data: */ void __user * user_data; uint32_t user_data_len; - - /* 64bit alignment */ - uint32_t pad_for_64bit_align; - mraid_passthru_t __user *user_pthru; mraid_passthru_t *pthru32; diff --git a/trunk/drivers/scsi/megaraid/megaraid_mbox.c b/trunk/drivers/scsi/megaraid/megaraid_mbox.c index cd982c877da0..92715130ac09 100644 --- a/trunk/drivers/scsi/megaraid/megaraid_mbox.c +++ b/trunk/drivers/scsi/megaraid/megaraid_mbox.c @@ -10,7 +10,7 @@ * 2 of the License, or (at your option) any later version. * * FILE : megaraid_mbox.c - * Version : v2.20.4.9 (Jul 16 2006) + * Version : v2.20.4.8 (Apr 11 2006) * * Authors: * Atul Mukker @@ -720,7 +720,6 @@ megaraid_init_mbox(adapter_t *adapter) struct pci_dev *pdev; mraid_device_t *raid_dev; int i; - uint32_t magic64; adapter->ito = MBOX_TIMEOUT; @@ -864,33 +863,12 @@ megaraid_init_mbox(adapter_t *adapter) // Set the DMA mask to 64-bit. All supported controllers as capable of // DMA in this range - pci_read_config_dword(adapter->pdev, PCI_CONF_AMISIG64, &magic64); - - if (((magic64 == HBA_SIGNATURE_64_BIT) && - ((adapter->pdev->subsystem_device != - PCI_SUBSYS_ID_MEGARAID_SATA_150_6) || - (adapter->pdev->subsystem_device != - PCI_SUBSYS_ID_MEGARAID_SATA_150_4))) || - (adapter->pdev->vendor == PCI_VENDOR_ID_LSI_LOGIC && - adapter->pdev->device == PCI_DEVICE_ID_VERDE) || - (adapter->pdev->vendor == PCI_VENDOR_ID_LSI_LOGIC && - adapter->pdev->device == PCI_DEVICE_ID_DOBSON) || - (adapter->pdev->vendor == PCI_VENDOR_ID_LSI_LOGIC && - adapter->pdev->device == PCI_DEVICE_ID_LINDSAY) || - (adapter->pdev->vendor == PCI_VENDOR_ID_DELL && - adapter->pdev->device == PCI_DEVICE_ID_PERC4_DI_EVERGLADES) || - (adapter->pdev->vendor == PCI_VENDOR_ID_DELL && - adapter->pdev->device == PCI_DEVICE_ID_PERC4E_DI_KOBUK)) { - if (pci_set_dma_mask(adapter->pdev, DMA_64BIT_MASK)) { - con_log(CL_ANN, (KERN_WARNING - "megaraid: DMA mask for 64-bit failed\n")); + if (pci_set_dma_mask(adapter->pdev, DMA_64BIT_MASK) != 0) { - if (pci_set_dma_mask (adapter->pdev, DMA_32BIT_MASK)) { - con_log(CL_ANN, (KERN_WARNING - "megaraid: 32-bit DMA mask failed\n")); - goto out_free_sysfs_res; - } - } + con_log(CL_ANN, (KERN_WARNING + "megaraid: could not set DMA mask for 64-bit.\n")); + + goto out_free_sysfs_res; } // setup tasklet for DPC @@ -1644,14 +1622,6 @@ megaraid_mbox_build_cmd(adapter_t *adapter, struct scsi_cmnd *scp, int *busy) rdev->last_disp |= (1L << SCP2CHANNEL(scp)); } - if (scp->cmnd[1] & MEGA_SCSI_INQ_EVPD) { - scp->sense_buffer[0] = 0x70; - scp->sense_buffer[2] = ILLEGAL_REQUEST; - scp->sense_buffer[12] = MEGA_INVALID_FIELD_IN_CDB; - scp->result = CHECK_CONDITION << 1; - return NULL; - } - /* Fall through */ case READ_CAPACITY: diff --git a/trunk/drivers/scsi/megaraid/megaraid_mbox.h b/trunk/drivers/scsi/megaraid/megaraid_mbox.h index 2b5a3285f799..868fb0ec93e7 100644 --- a/trunk/drivers/scsi/megaraid/megaraid_mbox.h +++ b/trunk/drivers/scsi/megaraid/megaraid_mbox.h @@ -21,8 +21,8 @@ #include "megaraid_ioctl.h" -#define MEGARAID_VERSION "2.20.4.9" -#define MEGARAID_EXT_VERSION "(Release Date: Sun Jul 16 12:27:22 EST 2006)" +#define MEGARAID_VERSION "2.20.4.8" +#define MEGARAID_EXT_VERSION "(Release Date: Mon Apr 11 12:27:22 EST 2006)" /* diff --git a/trunk/drivers/scsi/megaraid/megaraid_mm.c b/trunk/drivers/scsi/megaraid/megaraid_mm.c index d85b9a8f1b8d..e8f534fb336b 100644 --- a/trunk/drivers/scsi/megaraid/megaraid_mm.c +++ b/trunk/drivers/scsi/megaraid/megaraid_mm.c @@ -10,7 +10,7 @@ * 2 of the License, or (at your option) any later version. * * FILE : megaraid_mm.c - * Version : v2.20.2.7 (Jul 16 2006) + * Version : v2.20.2.6 (Mar 7 2005) * * Common management module */ diff --git a/trunk/drivers/scsi/megaraid/megaraid_mm.h b/trunk/drivers/scsi/megaraid/megaraid_mm.h index c8762b2b8ed1..3d9e67d6849d 100644 --- a/trunk/drivers/scsi/megaraid/megaraid_mm.h +++ b/trunk/drivers/scsi/megaraid/megaraid_mm.h @@ -27,9 +27,9 @@ #include "megaraid_ioctl.h" -#define LSI_COMMON_MOD_VERSION "2.20.2.7" +#define LSI_COMMON_MOD_VERSION "2.20.2.6" #define LSI_COMMON_MOD_EXT_VERSION \ - "(Release Date: Sun Jul 16 00:01:03 EST 2006)" + "(Release Date: Mon Mar 7 00:01:03 EST 2005)" #define LSI_DBGLVL dbglevel diff --git a/trunk/drivers/scsi/pdc_adma.c b/trunk/drivers/scsi/pdc_adma.c index efc8fff1d250..d1f38c32aa15 100644 --- a/trunk/drivers/scsi/pdc_adma.c +++ b/trunk/drivers/scsi/pdc_adma.c @@ -183,8 +183,7 @@ static struct ata_port_info adma_port_info[] = { { .sht = &adma_ata_sht, .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST | - ATA_FLAG_NO_LEGACY | ATA_FLAG_MMIO | - ATA_FLAG_PIO_POLLING, + ATA_FLAG_NO_LEGACY | ATA_FLAG_MMIO, .pio_mask = 0x10, /* pio4 */ .udma_mask = 0x1f, /* udma0-4 */ .port_ops = &adma_ata_ops, diff --git a/trunk/drivers/scsi/qla2xxx/qla_def.h b/trunk/drivers/scsi/qla2xxx/qla_def.h index 0930260aec2c..139ea0e27fd7 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_def.h +++ b/trunk/drivers/scsi/qla2xxx/qla_def.h @@ -487,7 +487,6 @@ typedef struct { #define MBA_IP_RCV_BUFFER_EMPTY 0x8026 /* IP receive buffer queue empty. */ #define MBA_IP_HDR_DATA_SPLIT 0x8027 /* IP header/data splitting feature */ /* used. */ -#define MBA_TRACE_NOTIFICATION 0x8028 /* Trace/Diagnostic notification. */ #define MBA_POINT_TO_POINT 0x8030 /* Point to point mode. */ #define MBA_CMPLT_1_16BIT 0x8031 /* Completion 1 16bit IOSB. */ #define MBA_CMPLT_2_16BIT 0x8032 /* Completion 2 16bit IOSB. */ diff --git a/trunk/drivers/scsi/qla2xxx/qla_init.c b/trunk/drivers/scsi/qla2xxx/qla_init.c index 859649160caa..9758dba95542 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_init.c +++ b/trunk/drivers/scsi/qla2xxx/qla_init.c @@ -3063,7 +3063,6 @@ qla2x00_update_fcports(scsi_qla_host_t *ha) int qla2x00_abort_isp(scsi_qla_host_t *ha) { - int rval; unsigned long flags = 0; uint16_t cnt; srb_t *sp; @@ -3120,16 +3119,6 @@ qla2x00_abort_isp(scsi_qla_host_t *ha) ha->isp_abort_cnt = 0; clear_bit(ISP_ABORT_RETRY, &ha->dpc_flags); - - if (ha->eft) { - rval = qla2x00_trace_control(ha, TC_ENABLE, - ha->eft_dma, EFT_NUM_BUFFERS); - if (rval) { - qla_printk(KERN_WARNING, ha, - "Unable to reinitialize EFT " - "(%d).\n", rval); - } - } } else { /* failed the ISP abort */ ha->flags.online = 1; if (test_bit(ISP_ABORT_RETRY, &ha->dpc_flags)) { diff --git a/trunk/drivers/scsi/qla2xxx/qla_iocb.c b/trunk/drivers/scsi/qla2xxx/qla_iocb.c index c5b3c610a32a..2b60a27eff0b 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_iocb.c +++ b/trunk/drivers/scsi/qla2xxx/qla_iocb.c @@ -471,7 +471,6 @@ __qla2x00_marker(scsi_qla_host_t *ha, uint16_t loop_id, uint16_t lun, mrk24->nport_handle = cpu_to_le16(loop_id); mrk24->lun[1] = LSB(lun); mrk24->lun[2] = MSB(lun); - host_to_fcp_swap(mrk24->lun, sizeof(mrk24->lun)); } else { SET_TARGET_ID(ha, mrk->target, loop_id); mrk->lun = cpu_to_le16(lun); diff --git a/trunk/drivers/scsi/qla2xxx/qla_isr.c b/trunk/drivers/scsi/qla2xxx/qla_isr.c index de0613135f70..795bf15b1b8f 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_isr.c +++ b/trunk/drivers/scsi/qla2xxx/qla_isr.c @@ -587,11 +587,6 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) DEBUG2(printk("scsi(%ld): Discard RND Frame -- %04x %04x " "%04x.\n", ha->host_no, mb[1], mb[2], mb[3])); break; - - case MBA_TRACE_NOTIFICATION: - DEBUG2(printk("scsi(%ld): Trace Notification -- %04x %04x.\n", - ha->host_no, mb[1], mb[2])); - break; } } diff --git a/trunk/drivers/scsi/qla2xxx/qla_os.c b/trunk/drivers/scsi/qla2xxx/qla_os.c index 65cbe2f5eea2..ec7ebb6037e6 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_os.c +++ b/trunk/drivers/scsi/qla2xxx/qla_os.c @@ -744,6 +744,7 @@ qla2xxx_eh_device_reset(struct scsi_cmnd *cmd) { scsi_qla_host_t *ha = to_qla_host(cmd->device->host); fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata; + srb_t *sp; int ret; unsigned int id, lun; unsigned long serial; @@ -754,7 +755,8 @@ qla2xxx_eh_device_reset(struct scsi_cmnd *cmd) lun = cmd->device->lun; serial = cmd->serial_number; - if (!fcport) + sp = (srb_t *) CMD_SP(cmd); + if (!sp || !fcport) return ret; qla_printk(KERN_INFO, ha, @@ -873,6 +875,7 @@ qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd) { scsi_qla_host_t *ha = to_qla_host(cmd->device->host); fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata; + srb_t *sp; int ret; unsigned int id, lun; unsigned long serial; @@ -883,7 +886,8 @@ qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd) lun = cmd->device->lun; serial = cmd->serial_number; - if (!fcport) + sp = (srb_t *) CMD_SP(cmd); + if (!sp || !fcport) return ret; qla_printk(KERN_INFO, ha, @@ -932,6 +936,7 @@ qla2xxx_eh_host_reset(struct scsi_cmnd *cmd) { scsi_qla_host_t *ha = to_qla_host(cmd->device->host); fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata; + srb_t *sp; int ret; unsigned int id, lun; unsigned long serial; @@ -942,7 +947,8 @@ qla2xxx_eh_host_reset(struct scsi_cmnd *cmd) lun = cmd->device->lun; serial = cmd->serial_number; - if (!fcport) + sp = (srb_t *) CMD_SP(cmd); + if (!sp || !fcport) return ret; qla_printk(KERN_INFO, ha, @@ -2238,6 +2244,9 @@ qla2x00_do_dpc(void *data) next_loopid = 0; list_for_each_entry(fcport, &ha->fcports, list) { + if (fcport->port_type != FCT_TARGET) + continue; + /* * If the port is not ONLINE then try to login * to it if we haven't run out of retries. diff --git a/trunk/drivers/scsi/qla2xxx/qla_version.h b/trunk/drivers/scsi/qla2xxx/qla_version.h index 971259032ef7..d2d683440659 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_version.h +++ b/trunk/drivers/scsi/qla2xxx/qla_version.h @@ -7,9 +7,9 @@ /* * Driver version */ -#define QLA2XXX_VERSION "8.01.07-k1" +#define QLA2XXX_VERSION "8.01.05-k3" #define QLA_DRIVER_MAJOR_VER 8 #define QLA_DRIVER_MINOR_VER 1 -#define QLA_DRIVER_PATCH_VER 7 +#define QLA_DRIVER_PATCH_VER 5 #define QLA_DRIVER_BETA_VER 0 diff --git a/trunk/drivers/scsi/sata_via.c b/trunk/drivers/scsi/sata_via.c index 01d40369a8a5..03baec2191bf 100644 --- a/trunk/drivers/scsi/sata_via.c +++ b/trunk/drivers/scsi/sata_via.c @@ -74,7 +74,6 @@ enum { static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); static u32 svia_scr_read (struct ata_port *ap, unsigned int sc_reg); static void svia_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); -static void vt6420_error_handler(struct ata_port *ap); static const struct pci_device_id svia_pci_tbl[] = { { 0x1106, 0x3149, PCI_ANY_ID, PCI_ANY_ID, 0, 0, vt6420 }, @@ -108,38 +107,7 @@ static struct scsi_host_template svia_sht = { .bios_param = ata_std_bios_param, }; -static const struct ata_port_operations vt6420_sata_ops = { - .port_disable = ata_port_disable, - - .tf_load = ata_tf_load, - .tf_read = ata_tf_read, - .check_status = ata_check_status, - .exec_command = ata_exec_command, - .dev_select = ata_std_dev_select, - - .bmdma_setup = ata_bmdma_setup, - .bmdma_start = ata_bmdma_start, - .bmdma_stop = ata_bmdma_stop, - .bmdma_status = ata_bmdma_status, - - .qc_prep = ata_qc_prep, - .qc_issue = ata_qc_issue_prot, - .data_xfer = ata_pio_data_xfer, - - .freeze = ata_bmdma_freeze, - .thaw = ata_bmdma_thaw, - .error_handler = vt6420_error_handler, - .post_internal_cmd = ata_bmdma_post_internal_cmd, - - .irq_handler = ata_interrupt, - .irq_clear = ata_bmdma_irq_clear, - - .port_start = ata_port_start, - .port_stop = ata_port_stop, - .host_stop = ata_host_stop, -}; - -static const struct ata_port_operations vt6421_sata_ops = { +static const struct ata_port_operations svia_sata_ops = { .port_disable = ata_port_disable, .tf_load = ata_tf_load, @@ -173,13 +141,13 @@ static const struct ata_port_operations vt6421_sata_ops = { .host_stop = ata_host_stop, }; -static struct ata_port_info vt6420_port_info = { +static struct ata_port_info svia_port_info = { .sht = &svia_sht, .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY, .pio_mask = 0x1f, .mwdma_mask = 0x07, .udma_mask = 0x7f, - .port_ops = &vt6420_sata_ops, + .port_ops = &svia_sata_ops, }; MODULE_AUTHOR("Jeff Garzik"); @@ -202,81 +170,6 @@ static void svia_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val) outl(val, ap->ioaddr.scr_addr + (4 * sc_reg)); } -/** - * vt6420_prereset - prereset for vt6420 - * @ap: target ATA port - * - * SCR registers on vt6420 are pieces of shit and may hang the - * whole machine completely if accessed with the wrong timing. - * To avoid such catastrophe, vt6420 doesn't provide generic SCR - * access operations, but uses SStatus and SControl only during - * boot probing in controlled way. - * - * As the old (pre EH update) probing code is proven to work, we - * strictly follow the access pattern. - * - * LOCKING: - * Kernel thread context (may sleep) - * - * RETURNS: - * 0 on success, -errno otherwise. - */ -static int vt6420_prereset(struct ata_port *ap) -{ - struct ata_eh_context *ehc = &ap->eh_context; - unsigned long timeout = jiffies + (HZ * 5); - u32 sstatus, scontrol; - int online; - - /* don't do any SCR stuff if we're not loading */ - if (!ATA_PFLAG_LOADING) - goto skip_scr; - - /* Resume phy. This is the old resume sequence from - * __sata_phy_reset(). - */ - svia_scr_write(ap, SCR_CONTROL, 0x300); - svia_scr_read(ap, SCR_CONTROL); /* flush */ - - /* wait for phy to become ready, if necessary */ - do { - msleep(200); - if ((svia_scr_read(ap, SCR_STATUS) & 0xf) != 1) - break; - } while (time_before(jiffies, timeout)); - - /* open code sata_print_link_status() */ - sstatus = svia_scr_read(ap, SCR_STATUS); - scontrol = svia_scr_read(ap, SCR_CONTROL); - - online = (sstatus & 0xf) == 0x3; - - ata_port_printk(ap, KERN_INFO, - "SATA link %s 1.5 Gbps (SStatus %X SControl %X)\n", - online ? "up" : "down", sstatus, scontrol); - - /* SStatus is read one more time */ - svia_scr_read(ap, SCR_STATUS); - - if (!online) { - /* tell EH to bail */ - ehc->i.action &= ~ATA_EH_RESET_MASK; - return 0; - } - - skip_scr: - /* wait for !BSY */ - ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT); - - return 0; -} - -static void vt6420_error_handler(struct ata_port *ap) -{ - return ata_bmdma_drive_eh(ap, vt6420_prereset, ata_std_softreset, - NULL, ata_std_postreset); -} - static const unsigned int svia_bar_sizes[] = { 8, 4, 8, 4, 16, 256 }; @@ -317,7 +210,7 @@ static void vt6421_init_addrs(struct ata_probe_ent *probe_ent, static struct ata_probe_ent *vt6420_init_probe_ent(struct pci_dev *pdev) { struct ata_probe_ent *probe_ent; - struct ata_port_info *ppi = &vt6420_port_info; + struct ata_port_info *ppi = &svia_port_info; probe_ent = ata_pci_init_native_mode(pdev, &ppi, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY); if (!probe_ent) @@ -346,7 +239,7 @@ static struct ata_probe_ent *vt6421_init_probe_ent(struct pci_dev *pdev) probe_ent->sht = &svia_sht; probe_ent->host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY; - probe_ent->port_ops = &vt6421_sata_ops; + probe_ent->port_ops = &svia_sata_ops; probe_ent->n_ports = N_PORTS; probe_ent->irq = pdev->irq; probe_ent->irq_flags = IRQF_SHARED; diff --git a/trunk/drivers/scsi/scsi_error.c b/trunk/drivers/scsi/scsi_error.c index a8ed5a22009d..6a5b731bd5ba 100644 --- a/trunk/drivers/scsi/scsi_error.c +++ b/trunk/drivers/scsi/scsi_error.c @@ -460,8 +460,7 @@ static void scsi_eh_done(struct scsi_cmnd *scmd) * Return value: * SUCCESS or FAILED or NEEDS_RETRY **/ -static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd, - int cmnd_size, int timeout, int copy_sense) +static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, int timeout, int copy_sense) { struct scsi_device *sdev = scmd->device; struct Scsi_Host *shost = sdev->host; @@ -491,9 +490,6 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd, old_cmd_len = scmd->cmd_len; old_use_sg = scmd->use_sg; - memset(scmd->cmnd, 0, sizeof(scmd->cmnd)); - memcpy(scmd->cmnd, cmnd, cmnd_size); - if (copy_sense) { int gfp_mask = GFP_ATOMIC; @@ -614,7 +610,8 @@ static int scsi_request_sense(struct scsi_cmnd *scmd) static unsigned char generic_sense[6] = {REQUEST_SENSE, 0, 0, 0, 252, 0}; - return scsi_send_eh_cmnd(scmd, generic_sense, 6, SENSE_TIMEOUT, 1); + memcpy(scmd->cmnd, generic_sense, sizeof(generic_sense)); + return scsi_send_eh_cmnd(scmd, SENSE_TIMEOUT, 1); } /** @@ -739,7 +736,10 @@ static int scsi_eh_tur(struct scsi_cmnd *scmd) int retry_cnt = 1, rtn; retry_tur: - rtn = scsi_send_eh_cmnd(scmd, tur_command, 6, SENSE_TIMEOUT, 0); + memcpy(scmd->cmnd, tur_command, sizeof(tur_command)); + + + rtn = scsi_send_eh_cmnd(scmd, SENSE_TIMEOUT, 0); SCSI_LOG_ERROR_RECOVERY(3, printk("%s: scmd %p rtn %x\n", __FUNCTION__, scmd, rtn)); @@ -839,8 +839,8 @@ static int scsi_eh_try_stu(struct scsi_cmnd *scmd) if (scmd->device->allow_restart) { int rtn; - rtn = scsi_send_eh_cmnd(scmd, stu_command, 6, - START_UNIT_TIMEOUT, 0); + memcpy(scmd->cmnd, stu_command, sizeof(stu_command)); + rtn = scsi_send_eh_cmnd(scmd, START_UNIT_TIMEOUT, 0); if (rtn == SUCCESS) return 0; } diff --git a/trunk/drivers/scsi/scsi_transport_iscsi.c b/trunk/drivers/scsi/scsi_transport_iscsi.c index 2ecd14188574..7b9e8fa1a4e0 100644 --- a/trunk/drivers/scsi/scsi_transport_iscsi.c +++ b/trunk/drivers/scsi/scsi_transport_iscsi.c @@ -34,7 +34,6 @@ #define ISCSI_SESSION_ATTRS 11 #define ISCSI_CONN_ATTRS 11 #define ISCSI_HOST_ATTRS 0 -#define ISCSI_TRANSPORT_VERSION "1.1-646" struct iscsi_internal { int daemon_pid; @@ -635,13 +634,13 @@ mempool_zone_get_skb(struct mempool_zone *zone) } static int -iscsi_broadcast_skb(struct mempool_zone *zone, struct sk_buff *skb, gfp_t gfp) +iscsi_broadcast_skb(struct mempool_zone *zone, struct sk_buff *skb) { unsigned long flags; int rc; skb_get(skb); - rc = netlink_broadcast(nls, skb, 0, 1, gfp); + rc = netlink_broadcast(nls, skb, 0, 1, GFP_KERNEL); if (rc < 0) { mempool_free(skb, zone->pool); printk(KERN_ERR "iscsi: can not broadcast skb (%d)\n", rc); @@ -750,7 +749,7 @@ void iscsi_conn_error(struct iscsi_cls_conn *conn, enum iscsi_err error) ev->r.connerror.cid = conn->cid; ev->r.connerror.sid = iscsi_conn_get_sid(conn); - iscsi_broadcast_skb(conn->z_error, skb, GFP_ATOMIC); + iscsi_broadcast_skb(conn->z_error, skb); dev_printk(KERN_INFO, &conn->dev, "iscsi: detected conn error (%d)\n", error); @@ -896,7 +895,7 @@ int iscsi_if_destroy_session_done(struct iscsi_cls_conn *conn) * this will occur if the daemon is not up, so we just warn * the user and when the daemon is restarted it will handle it */ - rc = iscsi_broadcast_skb(conn->z_pdu, skb, GFP_KERNEL); + rc = iscsi_broadcast_skb(conn->z_pdu, skb); if (rc < 0) dev_printk(KERN_ERR, &conn->dev, "Cannot notify userspace of " "session destruction event. Check iscsi daemon\n"); @@ -959,7 +958,7 @@ int iscsi_if_create_session_done(struct iscsi_cls_conn *conn) * this will occur if the daemon is not up, so we just warn * the user and when the daemon is restarted it will handle it */ - rc = iscsi_broadcast_skb(conn->z_pdu, skb, GFP_KERNEL); + rc = iscsi_broadcast_skb(conn->z_pdu, skb); if (rc < 0) dev_printk(KERN_ERR, &conn->dev, "Cannot notify userspace of " "session creation event. Check iscsi daemon\n"); @@ -1614,9 +1613,6 @@ static __init int iscsi_transport_init(void) { int err; - printk(KERN_INFO "Loading iSCSI transport class v%s.", - ISCSI_TRANSPORT_VERSION); - err = class_register(&iscsi_transport_class); if (err) return err; @@ -1682,4 +1678,3 @@ MODULE_AUTHOR("Mike Christie , " "Alex Aizman "); MODULE_DESCRIPTION("iSCSI Transport Interface"); MODULE_LICENSE("GPL"); -MODULE_VERSION(ISCSI_TRANSPORT_VERSION); diff --git a/trunk/drivers/scsi/sg.c b/trunk/drivers/scsi/sg.c index 34f9343ed0af..65eef33846bb 100644 --- a/trunk/drivers/scsi/sg.c +++ b/trunk/drivers/scsi/sg.c @@ -18,8 +18,8 @@ * */ -static int sg_version_num = 30534; /* 2 digits for each component */ -#define SG_VERSION_STR "3.5.34" +static int sg_version_num = 30533; /* 2 digits for each component */ +#define SG_VERSION_STR "3.5.33" /* * D. P. Gilbert (dgilbert@interlog.com, dougg@triode.net.au), notes: @@ -60,7 +60,7 @@ static int sg_version_num = 30534; /* 2 digits for each component */ #ifdef CONFIG_SCSI_PROC_FS #include -static char *sg_version_date = "20060818"; +static char *sg_version_date = "20050908"; static int sg_proc_init(void); static void sg_proc_cleanup(void); @@ -1164,7 +1164,7 @@ sg_vma_nopage(struct vm_area_struct *vma, unsigned long addr, int *type) len = vma->vm_end - sa; len = (len < sg->length) ? len : sg->length; if (offset < len) { - page = virt_to_page(page_address(sg->page) + offset); + page = sg->page; get_page(page); /* increment page count */ break; } diff --git a/trunk/drivers/scsi/sym53c8xx_2/sym_glue.c b/trunk/drivers/scsi/sym53c8xx_2/sym_glue.c index 739d3ef46a40..8c505076c0eb 100644 --- a/trunk/drivers/scsi/sym53c8xx_2/sym_glue.c +++ b/trunk/drivers/scsi/sym53c8xx_2/sym_glue.c @@ -2084,7 +2084,7 @@ static struct pci_device_id sym2_id_table[] __devinitdata = { { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_NCR_53C860, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_53C1510, - PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_SCSI<<8, 0xffff00, 0UL }, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_NCR_53C896, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_NCR_53C895, diff --git a/trunk/drivers/serial/8250_pci.c b/trunk/drivers/serial/8250_pci.c index 851e4839d6d9..a1d322f8a16c 100644 --- a/trunk/drivers/serial/8250_pci.c +++ b/trunk/drivers/serial/8250_pci.c @@ -458,11 +458,11 @@ static int pci_siig_setup(struct serial_private *priv, * growing *huge*, we use this function to collapse some 70 entries * in the PCI table into one, for sanity's and compactness's sake. */ -static const unsigned short timedia_single_port[] = { +static unsigned short timedia_single_port[] = { 0x4025, 0x4027, 0x4028, 0x5025, 0x5027, 0 }; -static const unsigned short timedia_dual_port[] = { +static unsigned short timedia_dual_port[] = { 0x0002, 0x4036, 0x4037, 0x4038, 0x4078, 0x4079, 0x4085, 0x4088, 0x4089, 0x5037, 0x5078, 0x5079, 0x5085, 0x6079, 0x7079, 0x8079, 0x8137, 0x8138, 0x8237, 0x8238, 0x9079, @@ -470,34 +470,35 @@ static const unsigned short timedia_dual_port[] = { 0xD079, 0 }; -static const unsigned short timedia_quad_port[] = { +static unsigned short timedia_quad_port[] = { 0x4055, 0x4056, 0x4095, 0x4096, 0x5056, 0x8156, 0x8157, 0x8256, 0x8257, 0x9056, 0x9156, 0x9157, 0x9158, 0x9159, 0x9256, 0x9257, 0xA056, 0xA157, 0xA158, 0xA159, 0xB056, 0xB157, 0 }; -static const unsigned short timedia_eight_port[] = { +static unsigned short timedia_eight_port[] = { 0x4065, 0x4066, 0x5065, 0x5066, 0x8166, 0x9066, 0x9166, 0x9167, 0x9168, 0xA066, 0xA167, 0xA168, 0 }; static const struct timedia_struct { int num; - const unsigned short *ids; + unsigned short *ids; } timedia_data[] = { { 1, timedia_single_port }, { 2, timedia_dual_port }, { 4, timedia_quad_port }, - { 8, timedia_eight_port } + { 8, timedia_eight_port }, + { 0, NULL } }; static int pci_timedia_init(struct pci_dev *dev) { - const unsigned short *ids; + unsigned short *ids; int i, j; - for (i = 0; i < ARRAY_SIZE(timedia_data); i++) { + for (i = 0; timedia_data[i].num; i++) { ids = timedia_data[i].ids; for (j = 0; ids[j]; j++) if (dev->subsystem_device == ids[j]) @@ -935,7 +936,6 @@ enum pci_board_num_t { pbn_b1_8_1382400, pbn_b2_1_115200, - pbn_b2_2_115200, pbn_b2_8_115200, pbn_b2_1_460800, @@ -1243,12 +1243,6 @@ static struct pciserial_board pci_boards[] __devinitdata = { .base_baud = 115200, .uart_offset = 8, }, - [pbn_b2_2_115200] = { - .flags = FL_BASE2, - .num_ports = 2, - .base_baud = 115200, - .uart_offset = 8, - }, [pbn_b2_8_115200] = { .flags = FL_BASE2, .num_ports = 8, @@ -2345,13 +2339,6 @@ static struct pci_device_id serial_pci_tbl[] = { PCI_ANY_ID, PCI_ANY_ID, 0, 0, pbn_b0_1_115200 }, - /* - * IntaShield IS-200 - */ - { PCI_VENDOR_ID_INTASHIELD, PCI_DEVICE_ID_INTASHIELD_IS200, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, /* 135a.0811 */ - pbn_b2_2_115200 }, - /* * These entries match devices with class COMMUNICATION_SERIAL, * COMMUNICATION_MODEM or COMMUNICATION_MULTISERIAL diff --git a/trunk/drivers/serial/serial_core.c b/trunk/drivers/serial/serial_core.c index 372e47f7d596..80ef7d482756 100644 --- a/trunk/drivers/serial/serial_core.c +++ b/trunk/drivers/serial/serial_core.c @@ -2377,9 +2377,6 @@ int uart_match_port(struct uart_port *port1, struct uart_port *port2) return (port1->iobase == port2->iobase) && (port1->hub6 == port2->hub6); case UPIO_MEM: - case UPIO_MEM32: - case UPIO_AU: - case UPIO_TSI: return (port1->mapbase == port2->mapbase); } return 0; diff --git a/trunk/drivers/serial/sunsab.c b/trunk/drivers/serial/sunsab.c index cfe20f730436..dc673e1b6fd9 100644 --- a/trunk/drivers/serial/sunsab.c +++ b/trunk/drivers/serial/sunsab.c @@ -886,15 +886,6 @@ static int sunsab_console_setup(struct console *con, char *options) unsigned long flags; unsigned int baud, quot; - /* - * The console framework calls us for each and every port - * registered. Defer the console setup until the requested - * port has been properly discovered. A bit of a hack, - * though... - */ - if (up->port.type != PORT_SUNSAB) - return -1; - printk("Console: ttyS%d (SAB82532)\n", (sunsab_reg.minor - 64) + con->index); diff --git a/trunk/drivers/serial/sunzilog.c b/trunk/drivers/serial/sunzilog.c index d34f336d53d8..47bc3d57e019 100644 --- a/trunk/drivers/serial/sunzilog.c +++ b/trunk/drivers/serial/sunzilog.c @@ -1146,9 +1146,6 @@ static int __init sunzilog_console_setup(struct console *con, char *options) unsigned long flags; int baud, brg; - if (up->port.type != PORT_SUNZILOG) - return -1; - printk(KERN_INFO "Console: ttyS%d (SunZilog zs%d)\n", (sunzilog_reg.minor - 64) + con->index, con->index); diff --git a/trunk/drivers/usb/gadget/ether.c b/trunk/drivers/usb/gadget/ether.c index 30299c620d97..4fe1bec1c255 100644 --- a/trunk/drivers/usb/gadget/ether.c +++ b/trunk/drivers/usb/gadget/ether.c @@ -117,8 +117,6 @@ struct eth_dev { struct usb_ep *in_ep, *out_ep, *status_ep; const struct usb_endpoint_descriptor *in, *out, *status; - - spinlock_t req_lock; struct list_head tx_reqs, rx_reqs; struct net_device *net; @@ -1068,31 +1066,21 @@ static void eth_reset_config (struct eth_dev *dev) */ if (dev->in) { usb_ep_disable (dev->in_ep); - spin_lock(&dev->req_lock); while (likely (!list_empty (&dev->tx_reqs))) { req = container_of (dev->tx_reqs.next, struct usb_request, list); list_del (&req->list); - - spin_unlock(&dev->req_lock); usb_ep_free_request (dev->in_ep, req); - spin_lock(&dev->req_lock); } - spin_unlock(&dev->req_lock); } if (dev->out) { usb_ep_disable (dev->out_ep); - spin_lock(&dev->req_lock); while (likely (!list_empty (&dev->rx_reqs))) { req = container_of (dev->rx_reqs.next, struct usb_request, list); list_del (&req->list); - - spin_unlock(&dev->req_lock); usb_ep_free_request (dev->out_ep, req); - spin_lock(&dev->req_lock); } - spin_unlock(&dev->req_lock); } if (dev->status) { @@ -1671,9 +1659,9 @@ rx_submit (struct eth_dev *dev, struct usb_request *req, gfp_t gfp_flags) if (retval) { DEBUG (dev, "rx submit --> %d\n", retval); dev_kfree_skb_any (skb); - spin_lock(&dev->req_lock); + spin_lock (&dev->lock); list_add (&req->list, &dev->rx_reqs); - spin_unlock(&dev->req_lock); + spin_unlock (&dev->lock); } return retval; } @@ -1742,9 +1730,8 @@ static void rx_complete (struct usb_ep *ep, struct usb_request *req) dev_kfree_skb_any (skb); if (!netif_running (dev->net)) { clean: - spin_lock(&dev->req_lock); + /* nobody reading rx_reqs, so no dev->lock */ list_add (&req->list, &dev->rx_reqs); - spin_unlock(&dev->req_lock); req = NULL; } if (req) @@ -1795,18 +1782,15 @@ static int alloc_requests (struct eth_dev *dev, unsigned n, gfp_t gfp_flags) { int status; - spin_lock(&dev->req_lock); status = prealloc (&dev->tx_reqs, dev->in_ep, n, gfp_flags); if (status < 0) goto fail; status = prealloc (&dev->rx_reqs, dev->out_ep, n, gfp_flags); if (status < 0) goto fail; - goto done; + return 0; fail: DEBUG (dev, "can't alloc requests\n"); -done: - spin_unlock(&dev->req_lock); return status; } @@ -1816,21 +1800,21 @@ static void rx_fill (struct eth_dev *dev, gfp_t gfp_flags) unsigned long flags; /* fill unused rxq slots with some skb */ - spin_lock_irqsave(&dev->req_lock, flags); + spin_lock_irqsave (&dev->lock, flags); while (!list_empty (&dev->rx_reqs)) { req = container_of (dev->rx_reqs.next, struct usb_request, list); list_del_init (&req->list); - spin_unlock_irqrestore(&dev->req_lock, flags); + spin_unlock_irqrestore (&dev->lock, flags); if (rx_submit (dev, req, gfp_flags) < 0) { defer_kevent (dev, WORK_RX_MEMORY); return; } - spin_lock_irqsave(&dev->req_lock, flags); + spin_lock_irqsave (&dev->lock, flags); } - spin_unlock_irqrestore(&dev->req_lock, flags); + spin_unlock_irqrestore (&dev->lock, flags); } static void eth_work (void *_dev) @@ -1864,9 +1848,9 @@ static void tx_complete (struct usb_ep *ep, struct usb_request *req) } dev->stats.tx_packets++; - spin_lock(&dev->req_lock); + spin_lock (&dev->lock); list_add (&req->list, &dev->tx_reqs); - spin_unlock(&dev->req_lock); + spin_unlock (&dev->lock); dev_kfree_skb_any (skb); atomic_dec (&dev->tx_qlen); @@ -1912,12 +1896,12 @@ static int eth_start_xmit (struct sk_buff *skb, struct net_device *net) /* ignores USB_CDC_PACKET_TYPE_DIRECTED */ } - spin_lock_irqsave(&dev->req_lock, flags); + spin_lock_irqsave (&dev->lock, flags); req = container_of (dev->tx_reqs.next, struct usb_request, list); list_del (&req->list); if (list_empty (&dev->tx_reqs)) netif_stop_queue (net); - spin_unlock_irqrestore(&dev->req_lock, flags); + spin_unlock_irqrestore (&dev->lock, flags); /* no buffer copies needed, unless the network stack did it * or the hardware can't use skb buffers. @@ -1971,11 +1955,11 @@ static int eth_start_xmit (struct sk_buff *skb, struct net_device *net) drop: dev->stats.tx_dropped++; dev_kfree_skb_any (skb); - spin_lock_irqsave(&dev->req_lock, flags); + spin_lock_irqsave (&dev->lock, flags); if (list_empty (&dev->tx_reqs)) netif_start_queue (net); list_add (&req->list, &dev->tx_reqs); - spin_unlock_irqrestore(&dev->req_lock, flags); + spin_unlock_irqrestore (&dev->lock, flags); } return 0; } @@ -2394,7 +2378,6 @@ eth_bind (struct usb_gadget *gadget) return status; dev = netdev_priv(net); spin_lock_init (&dev->lock); - spin_lock_init (&dev->req_lock); INIT_WORK (&dev->work, eth_work, dev); INIT_LIST_HEAD (&dev->tx_reqs); INIT_LIST_HEAD (&dev->rx_reqs); diff --git a/trunk/drivers/usb/host/uhci-q.c b/trunk/drivers/usb/host/uhci-q.c index 431e8f31f1a9..66c3f61bc9d1 100644 --- a/trunk/drivers/usb/host/uhci-q.c +++ b/trunk/drivers/usb/host/uhci-q.c @@ -372,7 +372,7 @@ static void uhci_fixup_toggles(struct uhci_qh *qh, int skip_first) * need to change any toggles in this URB */ td = list_entry(urbp->td_list.next, struct uhci_td, list); if (toggle > 1 || uhci_toggle(td_token(td)) == toggle) { - td = list_entry(urbp->td_list.prev, struct uhci_td, + td = list_entry(urbp->td_list.next, struct uhci_td, list); toggle = uhci_toggle(td_token(td)) ^ 1; @@ -1348,7 +1348,7 @@ static void uhci_scan_qh(struct uhci_hcd *uhci, struct uhci_qh *qh, } uhci_giveback_urb(uhci, qh, urb, regs); - if (status < 0 && qh->type != USB_ENDPOINT_XFER_ISOC) + if (status < 0) break; } diff --git a/trunk/drivers/usb/input/hid-core.c b/trunk/drivers/usb/input/hid-core.c index acb24c6219d9..8ea9c915fbf9 100644 --- a/trunk/drivers/usb/input/hid-core.c +++ b/trunk/drivers/usb/input/hid-core.c @@ -1411,54 +1411,17 @@ void hid_init_reports(struct hid_device *hid) warn("timeout initializing reports"); } -#define USB_VENDOR_ID_GTCO 0x078c -#define USB_DEVICE_ID_GTCO_90 0x0090 -#define USB_DEVICE_ID_GTCO_100 0x0100 -#define USB_DEVICE_ID_GTCO_101 0x0101 -#define USB_DEVICE_ID_GTCO_103 0x0103 -#define USB_DEVICE_ID_GTCO_104 0x0104 -#define USB_DEVICE_ID_GTCO_105 0x0105 -#define USB_DEVICE_ID_GTCO_106 0x0106 -#define USB_DEVICE_ID_GTCO_107 0x0107 -#define USB_DEVICE_ID_GTCO_108 0x0108 -#define USB_DEVICE_ID_GTCO_200 0x0200 -#define USB_DEVICE_ID_GTCO_201 0x0201 -#define USB_DEVICE_ID_GTCO_202 0x0202 -#define USB_DEVICE_ID_GTCO_203 0x0203 -#define USB_DEVICE_ID_GTCO_204 0x0204 -#define USB_DEVICE_ID_GTCO_205 0x0205 -#define USB_DEVICE_ID_GTCO_206 0x0206 -#define USB_DEVICE_ID_GTCO_207 0x0207 -#define USB_DEVICE_ID_GTCO_300 0x0300 -#define USB_DEVICE_ID_GTCO_301 0x0301 -#define USB_DEVICE_ID_GTCO_302 0x0302 -#define USB_DEVICE_ID_GTCO_303 0x0303 -#define USB_DEVICE_ID_GTCO_304 0x0304 -#define USB_DEVICE_ID_GTCO_305 0x0305 -#define USB_DEVICE_ID_GTCO_306 0x0306 -#define USB_DEVICE_ID_GTCO_307 0x0307 -#define USB_DEVICE_ID_GTCO_308 0x0308 -#define USB_DEVICE_ID_GTCO_309 0x0309 -#define USB_DEVICE_ID_GTCO_400 0x0400 -#define USB_DEVICE_ID_GTCO_401 0x0401 -#define USB_DEVICE_ID_GTCO_402 0x0402 -#define USB_DEVICE_ID_GTCO_403 0x0403 -#define USB_DEVICE_ID_GTCO_404 0x0404 -#define USB_DEVICE_ID_GTCO_404 0x0405 -#define USB_DEVICE_ID_GTCO_500 0x0500 -#define USB_DEVICE_ID_GTCO_501 0x0501 -#define USB_DEVICE_ID_GTCO_502 0x0502 -#define USB_DEVICE_ID_GTCO_503 0x0503 -#define USB_DEVICE_ID_GTCO_504 0x0504 -#define USB_DEVICE_ID_GTCO_1000 0x1000 -#define USB_DEVICE_ID_GTCO_1001 0x1001 -#define USB_DEVICE_ID_GTCO_1002 0x1002 -#define USB_DEVICE_ID_GTCO_1003 0x1003 -#define USB_DEVICE_ID_GTCO_1004 0x1004 -#define USB_DEVICE_ID_GTCO_1005 0x1005 -#define USB_DEVICE_ID_GTCO_1006 0x1006 - #define USB_VENDOR_ID_WACOM 0x056a +#define USB_DEVICE_ID_WACOM_PENPARTNER 0x0000 +#define USB_DEVICE_ID_WACOM_GRAPHIRE 0x0010 +#define USB_DEVICE_ID_WACOM_INTUOS 0x0020 +#define USB_DEVICE_ID_WACOM_PL 0x0030 +#define USB_DEVICE_ID_WACOM_INTUOS2 0x0040 +#define USB_DEVICE_ID_WACOM_VOLITO 0x0060 +#define USB_DEVICE_ID_WACOM_PTU 0x0003 +#define USB_DEVICE_ID_WACOM_INTUOS3 0x00B0 +#define USB_DEVICE_ID_WACOM_CINTIQ 0x003F +#define USB_DEVICE_ID_WACOM_DTF 0x00C0 #define USB_VENDOR_ID_ACECAD 0x0460 #define USB_DEVICE_ID_ACECAD_FLAIR 0x0004 @@ -1625,51 +1588,6 @@ static const struct hid_blacklist { { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_0_8_8_IF_KIT, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_POWERMATE, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_SOUNDKNOB, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_90, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_100, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_101, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_103, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_104, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_105, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_106, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_107, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_108, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_200, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_201, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_202, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_203, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_204, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_205, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_206, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_207, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_300, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_301, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_302, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_303, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_304, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_305, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_306, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_307, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_308, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_309, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_400, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_401, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_402, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_403, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_404, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_404, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_500, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_501, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_502, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_503, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_504, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1000, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1001, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1002, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1003, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1004, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1005, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1006, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_KBGEAR, USB_DEVICE_ID_KBGEAR_JAMSTUDIO, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_CASSY, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_POCKETCASSY, HID_QUIRK_IGNORE }, @@ -1699,6 +1617,49 @@ static const struct hid_blacklist { { USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_GOTEMP, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_SKIP, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_CYCLOPS, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PENPARTNER, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE + 1, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE + 2, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE + 3, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE + 4, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS + 1, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS + 2, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS + 3, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS + 4, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PL, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PL + 1, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PL + 2, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PL + 3, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PL + 4, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PL + 5, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PL + 7, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PL + 8, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PL + 9, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 1, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 2, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 3, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 4, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 5, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 7, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_VOLITO, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_VOLITO + 1, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_VOLITO + 2, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_VOLITO + 3, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_VOLITO + 4, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE + 5, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE + 6, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PTU, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS3, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS3 + 1, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS3 + 2, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS3 + 3, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS3 + 4, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS3 + 5, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_CINTIQ, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_DTF, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_DTF + 3, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_4_PHIDGETSERVO_20, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_1_PHIDGETSERVO_20, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_YEALINK, USB_DEVICE_ID_YEALINK_P1K_P4K_B2K, HID_QUIRK_IGNORE }, @@ -1817,10 +1778,6 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf) char *rdesc; int n, len, insize = 0; - /* Ignore all Wacom devices */ - if (dev->descriptor.idVendor == USB_VENDOR_ID_WACOM) - return NULL; - for (n = 0; hid_blacklist[n].idVendor; n++) if ((hid_blacklist[n].idVendor == le16_to_cpu(dev->descriptor.idVendor)) && (hid_blacklist[n].idProduct == le16_to_cpu(dev->descriptor.idProduct))) diff --git a/trunk/drivers/usb/misc/cypress_cy7c63.c b/trunk/drivers/usb/misc/cypress_cy7c63.c index 9c46746d5d00..a4062a6adbb8 100644 --- a/trunk/drivers/usb/misc/cypress_cy7c63.c +++ b/trunk/drivers/usb/misc/cypress_cy7c63.c @@ -208,7 +208,7 @@ static int cypress_probe(struct usb_interface *interface, /* allocate memory for our device state and initialize it */ dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (dev == NULL) { - dev_err(&interface->dev, "Out of memory!\n"); + dev_err(&dev->udev->dev, "Out of memory!\n"); goto error; } diff --git a/trunk/drivers/usb/net/pegasus.h b/trunk/drivers/usb/net/pegasus.h index 006438069b66..a54752ce1493 100644 --- a/trunk/drivers/usb/net/pegasus.h +++ b/trunk/drivers/usb/net/pegasus.h @@ -131,7 +131,6 @@ struct usb_eth_dev { #define VENDOR_COREGA 0x07aa #define VENDOR_DLINK 0x2001 #define VENDOR_ELCON 0x0db7 -#define VENDOR_ELECOM 0x056e #define VENDOR_ELSA 0x05cc #define VENDOR_GIGABYTE 0x1044 #define VENDOR_HAWKING 0x0e66 @@ -234,8 +233,6 @@ PEGASUS_DEV( "D-Link DSB-650", VENDOR_DLINK, 0xabc1, DEFAULT_GPIO_RESET ) PEGASUS_DEV( "GOLDPFEIL USB Adapter", VENDOR_ELCON, 0x0002, DEFAULT_GPIO_RESET | PEGASUS_II | HAS_HOME_PNA ) -PEGASUS_DEV( "ELECOM USB Ethernet LD-USB20", VENDOR_ELECOM, 0x4010, - DEFAULT_GPIO_RESET | PEGASUS_II ) PEGASUS_DEV( "EasiDock Ethernet", VENDOR_MOBILITY, 0x0304, DEFAULT_GPIO_RESET ) PEGASUS_DEV( "Elsa Micolink USB2Ethernet", VENDOR_ELSA, 0x3000, diff --git a/trunk/drivers/usb/net/rtl8150.c b/trunk/drivers/usb/net/rtl8150.c index a72685b96061..bd09232ce13c 100644 --- a/trunk/drivers/usb/net/rtl8150.c +++ b/trunk/drivers/usb/net/rtl8150.c @@ -972,7 +972,6 @@ static void rtl8150_disconnect(struct usb_interface *intf) if (dev) { set_bit(RTL8150_UNPLUG, &dev->flags); tasklet_disable(&dev->tl); - tasklet_kill(&dev->tl); unregister_netdev(dev->netdev); unlink_all_urbs(dev); free_all_urbs(dev); diff --git a/trunk/drivers/usb/serial/pl2303.c b/trunk/drivers/usb/serial/pl2303.c index 65e4d046951a..efbbc0adb89a 100644 --- a/trunk/drivers/usb/serial/pl2303.c +++ b/trunk/drivers/usb/serial/pl2303.c @@ -79,6 +79,7 @@ static struct usb_device_id id_table [] = { { USB_DEVICE(SAGEM_VENDOR_ID, SAGEM_PRODUCT_ID) }, { USB_DEVICE(LEADTEK_VENDOR_ID, LEADTEK_9531_PRODUCT_ID) }, { USB_DEVICE(SPEEDDRAGON_VENDOR_ID, SPEEDDRAGON_PRODUCT_ID) }, + { USB_DEVICE(OTI_VENDOR_ID, OTI_PRODUCT_ID) }, { USB_DEVICE(DATAPILOT_U2_VENDOR_ID, DATAPILOT_U2_PRODUCT_ID) }, { USB_DEVICE(BELKIN_VENDOR_ID, BELKIN_PRODUCT_ID) }, { } /* Terminating entry */ diff --git a/trunk/drivers/usb/serial/pl2303.h b/trunk/drivers/usb/serial/pl2303.h index 55195e76eb6f..a692ac66ca6c 100644 --- a/trunk/drivers/usb/serial/pl2303.h +++ b/trunk/drivers/usb/serial/pl2303.h @@ -82,6 +82,10 @@ #define SPEEDDRAGON_VENDOR_ID 0x0e55 #define SPEEDDRAGON_PRODUCT_ID 0x110b +/* Ours Technology Inc DKU-5 clone, chipset: Prolific Technology Inc */ +#define OTI_VENDOR_ID 0x0ea0 +#define OTI_PRODUCT_ID 0x6858 + /* DATAPILOT Universal-2 Phone Cable */ #define DATAPILOT_U2_VENDOR_ID 0x0731 #define DATAPILOT_U2_PRODUCT_ID 0x2003 diff --git a/trunk/drivers/usb/storage/unusual_devs.h b/trunk/drivers/usb/storage/unusual_devs.h index b130e170b4a8..fd158e063c06 100644 --- a/trunk/drivers/usb/storage/unusual_devs.h +++ b/trunk/drivers/usb/storage/unusual_devs.h @@ -241,6 +241,16 @@ UNUSUAL_DEV( 0x0482, 0x0103, 0x0100, 0x0100, "Finecam S5", US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_FIX_INQUIRY), +/* Patch for Kyocera Finecam L3 + * Submitted by Michael Krauth + * and Alessandro Fracchetti + */ +UNUSUAL_DEV( 0x0482, 0x0105, 0x0100, 0x0100, + "Kyocera", + "Finecam L3", + US_SC_SCSI, US_PR_BULK, NULL, + US_FL_FIX_INQUIRY), + /* Reported by Paul Stewart * This entry is needed because the device reports Sub=ff */ UNUSUAL_DEV( 0x04a4, 0x0004, 0x0001, 0x0001, @@ -589,13 +599,6 @@ UNUSUAL_DEV( 0x054c, 0x0099, 0x0000, 0x9999, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_FIX_INQUIRY ), -/* floppy reports multiple luns */ -UNUSUAL_DEV( 0x055d, 0x2020, 0x0000, 0x0210, - "SAMSUNG", - "SFD-321U [FW 0C]", - US_SC_DEVICE, US_PR_DEVICE, NULL, - US_FL_SINGLE_LUN ), - UNUSUAL_DEV( 0x057b, 0x0000, 0x0000, 0x0299, "Y-E Data", @@ -1254,18 +1257,11 @@ UNUSUAL_DEV( 0x0fce, 0xd008, 0x0000, 0x0000, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_NO_WP_DETECT ), -/* Reported by Emmanuel Vasilakis */ -UNUSUAL_DEV( 0x0fce, 0xe031, 0x0000, 0x0000, - "Sony Ericsson", - "M600i", - US_SC_DEVICE, US_PR_DEVICE, NULL, - US_FL_FIX_CAPACITY ), - /* Reported by Kevin Cernekee * Tested on hardware version 1.10. * Entry is needed only for the initializer function override. */ -UNUSUAL_DEV( 0x1019, 0x0c55, 0x0110, 0x0110, +UNUSUAL_DEV( 0x1019, 0x0c55, 0x0000, 0x9999, "Desknote", "UCR-61S2B", US_SC_DEVICE, US_PR_DEVICE, usb_stor_ucr61s2b_init, diff --git a/trunk/drivers/video/aty/aty128fb.c b/trunk/drivers/video/aty/aty128fb.c index 276a21530b95..3e827e04a2aa 100644 --- a/trunk/drivers/video/aty/aty128fb.c +++ b/trunk/drivers/video/aty/aty128fb.c @@ -1801,14 +1801,10 @@ static struct backlight_properties aty128_bl_data = { static void aty128_bl_set_power(struct fb_info *info, int power) { mutex_lock(&info->bl_mutex); - - if (info->bl_dev) { - down(&info->bl_dev->sem); - info->bl_dev->props->power = power; - __aty128_bl_update_status(info->bl_dev); - up(&info->bl_dev->sem); - } - + up(&info->bl_dev->sem); + info->bl_dev->props->power = power; + __aty128_bl_update_status(info->bl_dev); + down(&info->bl_dev->sem); mutex_unlock(&info->bl_mutex); } @@ -1832,7 +1828,7 @@ static void aty128_bl_init(struct aty128fb_par *par) bd = backlight_device_register(name, par, &aty128_bl_data); if (IS_ERR(bd)) { info->bl_dev = NULL; - printk(KERN_WARNING "aty128: Backlight registration failed\n"); + printk("aty128: Backlight registration failed\n"); goto error; } @@ -1843,11 +1839,11 @@ static void aty128_bl_init(struct aty128fb_par *par) 219 * FB_BACKLIGHT_MAX / MAX_LEVEL); mutex_unlock(&info->bl_mutex); - down(&bd->sem); + up(&bd->sem); bd->props->brightness = aty128_bl_data.max_brightness; bd->props->power = FB_BLANK_UNBLANK; bd->props->update_status(bd); - up(&bd->sem); + down(&bd->sem); #ifdef CONFIG_PMAC_BACKLIGHT mutex_lock(&pmac_backlight_mutex); diff --git a/trunk/drivers/video/aty/atyfb_base.c b/trunk/drivers/video/aty/atyfb_base.c index 19a71f045784..053ff63365b7 100644 --- a/trunk/drivers/video/aty/atyfb_base.c +++ b/trunk/drivers/video/aty/atyfb_base.c @@ -2200,14 +2200,10 @@ static struct backlight_properties aty_bl_data = { static void aty_bl_set_power(struct fb_info *info, int power) { mutex_lock(&info->bl_mutex); - - if (info->bl_dev) { - down(&info->bl_dev->sem); - info->bl_dev->props->power = power; - __aty_bl_update_status(info->bl_dev); - up(&info->bl_dev->sem); - } - + up(&info->bl_dev->sem); + info->bl_dev->props->power = power; + __aty_bl_update_status(info->bl_dev); + down(&info->bl_dev->sem); mutex_unlock(&info->bl_mutex); } @@ -2227,7 +2223,7 @@ static void aty_bl_init(struct atyfb_par *par) bd = backlight_device_register(name, par, &aty_bl_data); if (IS_ERR(bd)) { info->bl_dev = NULL; - printk(KERN_WARNING "aty: Backlight registration failed\n"); + printk("aty: Backlight registration failed\n"); goto error; } @@ -2238,11 +2234,11 @@ static void aty_bl_init(struct atyfb_par *par) 0xFF * FB_BACKLIGHT_MAX / MAX_LEVEL); mutex_unlock(&info->bl_mutex); - down(&bd->sem); + up(&bd->sem); bd->props->brightness = aty_bl_data.max_brightness; bd->props->power = FB_BLANK_UNBLANK; bd->props->update_status(bd); - up(&bd->sem); + down(&bd->sem); #ifdef CONFIG_PMAC_BACKLIGHT mutex_lock(&pmac_backlight_mutex); diff --git a/trunk/drivers/video/aty/radeon_backlight.c b/trunk/drivers/video/aty/radeon_backlight.c index 585eb7b9e636..1755dddf1899 100644 --- a/trunk/drivers/video/aty/radeon_backlight.c +++ b/trunk/drivers/video/aty/radeon_backlight.c @@ -195,11 +195,11 @@ void radeonfb_bl_init(struct radeonfb_info *rinfo) 217 * FB_BACKLIGHT_MAX / MAX_RADEON_LEVEL); mutex_unlock(&rinfo->info->bl_mutex); - down(&bd->sem); + up(&bd->sem); bd->props->brightness = radeon_bl_data.max_brightness; bd->props->power = FB_BLANK_UNBLANK; bd->props->update_status(bd); - up(&bd->sem); + down(&bd->sem); #ifdef CONFIG_PMAC_BACKLIGHT mutex_lock(&pmac_backlight_mutex); diff --git a/trunk/drivers/video/imacfb.c b/trunk/drivers/video/imacfb.c index 18ea4a549105..b485bece5fc9 100644 --- a/trunk/drivers/video/imacfb.c +++ b/trunk/drivers/video/imacfb.c @@ -71,10 +71,10 @@ static int set_system(struct dmi_system_id *id) static struct dmi_system_id __initdata dmi_system_table[] = { { set_system, "iMac4,1", { DMI_MATCH(DMI_BIOS_VENDOR,"Apple Computer, Inc."), - DMI_MATCH(DMI_PRODUCT_NAME,"iMac4,1") }, (void*)M_I17}, + DMI_MATCH(DMI_BIOS_VERSION,"iMac4,1") }, (void*)M_I17}, { set_system, "MacBookPro1,1", { DMI_MATCH(DMI_BIOS_VENDOR,"Apple Computer, Inc."), - DMI_MATCH(DMI_PRODUCT_NAME,"MacBookPro1,1") }, (void*)M_I17}, + DMI_MATCH(DMI_BIOS_VERSION,"MacBookPro1,1") }, (void*)M_I17}, { set_system, "MacBook1,1", { DMI_MATCH(DMI_BIOS_VENDOR,"Apple Computer, Inc."), DMI_MATCH(DMI_PRODUCT_NAME,"MacBook1,1")}, (void *)M_MACBOOK}, diff --git a/trunk/drivers/video/matrox/g450_pll.c b/trunk/drivers/video/matrox/g450_pll.c index 7c76e079ca7d..440272ad10e7 100644 --- a/trunk/drivers/video/matrox/g450_pll.c +++ b/trunk/drivers/video/matrox/g450_pll.c @@ -331,15 +331,7 @@ static int __g450_setclk(WPMINFO unsigned int fout, unsigned int pll, tmp |= M1064_XPIXCLKCTRL_PLL_UP; } matroxfb_DAC_out(PMINFO M1064_XPIXCLKCTRL, tmp); -#ifdef __powerpc__ - /* This is necessary to avoid jitter on PowerPC - * (OpenFirmware) systems, but apparently - * introduces jitter, at least on a x86-64 - * using DVI. - * A simple workaround is disable for non-PPC. - */ matroxfb_DAC_out(PMINFO M1064_XDVICLKCTRL, 0); -#endif /* __powerpc__ */ matroxfb_DAC_out(PMINFO M1064_XPWRCTRL, xpwrctrl); matroxfb_DAC_unlock_irqrestore(flags); diff --git a/trunk/drivers/video/nvidia/nv_backlight.c b/trunk/drivers/video/nvidia/nv_backlight.c index 5b75ae4e9457..b45f577094ac 100644 --- a/trunk/drivers/video/nvidia/nv_backlight.c +++ b/trunk/drivers/video/nvidia/nv_backlight.c @@ -113,14 +113,10 @@ static struct backlight_properties nvidia_bl_data = { void nvidia_bl_set_power(struct fb_info *info, int power) { mutex_lock(&info->bl_mutex); - - if (info->bl_dev) { - down(&info->bl_dev->sem); - info->bl_dev->props->power = power; - __nvidia_bl_update_status(info->bl_dev); - up(&info->bl_dev->sem); - } - + up(&info->bl_dev->sem); + info->bl_dev->props->power = power; + __nvidia_bl_update_status(info->bl_dev); + down(&info->bl_dev->sem); mutex_unlock(&info->bl_mutex); } @@ -144,7 +140,7 @@ void nvidia_bl_init(struct nvidia_par *par) bd = backlight_device_register(name, par, &nvidia_bl_data); if (IS_ERR(bd)) { info->bl_dev = NULL; - printk(KERN_WARNING "nvidia: Backlight registration failed\n"); + printk("nvidia: Backlight registration failed\n"); goto error; } @@ -155,11 +151,11 @@ void nvidia_bl_init(struct nvidia_par *par) 0x534 * FB_BACKLIGHT_MAX / MAX_LEVEL); mutex_unlock(&info->bl_mutex); - down(&bd->sem); + up(&bd->sem); bd->props->brightness = nvidia_bl_data.max_brightness; bd->props->power = FB_BLANK_UNBLANK; bd->props->update_status(bd); - up(&bd->sem); + down(&bd->sem); #ifdef CONFIG_PMAC_BACKLIGHT mutex_lock(&pmac_backlight_mutex); diff --git a/trunk/drivers/video/riva/fbdev.c b/trunk/drivers/video/riva/fbdev.c index 8ddb47a56b07..76fc9d355eb7 100644 --- a/trunk/drivers/video/riva/fbdev.c +++ b/trunk/drivers/video/riva/fbdev.c @@ -355,14 +355,10 @@ static struct backlight_properties riva_bl_data = { static void riva_bl_set_power(struct fb_info *info, int power) { mutex_lock(&info->bl_mutex); - - if (info->bl_dev) { - down(&info->bl_dev->sem); - info->bl_dev->props->power = power; - __riva_bl_update_status(info->bl_dev); - up(&info->bl_dev->sem); - } - + up(&info->bl_dev->sem); + info->bl_dev->props->power = power; + __riva_bl_update_status(info->bl_dev); + down(&info->bl_dev->sem); mutex_unlock(&info->bl_mutex); } @@ -386,7 +382,7 @@ static void riva_bl_init(struct riva_par *par) bd = backlight_device_register(name, par, &riva_bl_data); if (IS_ERR(bd)) { info->bl_dev = NULL; - printk(KERN_WARNING "riva: Backlight registration failed\n"); + printk("riva: Backlight registration failed\n"); goto error; } @@ -397,11 +393,11 @@ static void riva_bl_init(struct riva_par *par) 0x534 * FB_BACKLIGHT_MAX / MAX_LEVEL); mutex_unlock(&info->bl_mutex); - down(&bd->sem); + up(&bd->sem); bd->props->brightness = riva_bl_data.max_brightness; bd->props->power = FB_BLANK_UNBLANK; bd->props->update_status(bd); - up(&bd->sem); + down(&bd->sem); #ifdef CONFIG_PMAC_BACKLIGHT mutex_lock(&pmac_backlight_mutex); diff --git a/trunk/fs/block_dev.c b/trunk/fs/block_dev.c index 045f98854f14..37534573960b 100644 --- a/trunk/fs/block_dev.c +++ b/trunk/fs/block_dev.c @@ -884,61 +884,6 @@ void bd_set_size(struct block_device *bdev, loff_t size) } EXPORT_SYMBOL(bd_set_size); -static int __blkdev_put(struct block_device *bdev, unsigned int subclass) -{ - int ret = 0; - struct inode *bd_inode = bdev->bd_inode; - struct gendisk *disk = bdev->bd_disk; - - mutex_lock_nested(&bdev->bd_mutex, subclass); - lock_kernel(); - if (!--bdev->bd_openers) { - sync_blockdev(bdev); - kill_bdev(bdev); - } - if (bdev->bd_contains == bdev) { - if (disk->fops->release) - ret = disk->fops->release(bd_inode, NULL); - } else { - mutex_lock_nested(&bdev->bd_contains->bd_mutex, - subclass + 1); - bdev->bd_contains->bd_part_count--; - mutex_unlock(&bdev->bd_contains->bd_mutex); - } - if (!bdev->bd_openers) { - struct module *owner = disk->fops->owner; - - put_disk(disk); - module_put(owner); - - if (bdev->bd_contains != bdev) { - kobject_put(&bdev->bd_part->kobj); - bdev->bd_part = NULL; - } - bdev->bd_disk = NULL; - bdev->bd_inode->i_data.backing_dev_info = &default_backing_dev_info; - if (bdev != bdev->bd_contains) - __blkdev_put(bdev->bd_contains, subclass + 1); - bdev->bd_contains = NULL; - } - unlock_kernel(); - mutex_unlock(&bdev->bd_mutex); - bdput(bdev); - return ret; -} - -int blkdev_put(struct block_device *bdev) -{ - return __blkdev_put(bdev, BD_MUTEX_NORMAL); -} -EXPORT_SYMBOL(blkdev_put); - -int blkdev_put_partition(struct block_device *bdev) -{ - return __blkdev_put(bdev, BD_MUTEX_PARTITION); -} -EXPORT_SYMBOL(blkdev_put_partition); - static int blkdev_get_whole(struct block_device *bdev, mode_t mode, unsigned flags); @@ -1035,7 +980,7 @@ do_open(struct block_device *bdev, struct file *file, unsigned int subclass) bdev->bd_disk = NULL; bdev->bd_inode->i_data.backing_dev_info = &default_backing_dev_info; if (bdev != bdev->bd_contains) - __blkdev_put(bdev->bd_contains, BD_MUTEX_WHOLE); + blkdev_put(bdev->bd_contains); bdev->bd_contains = NULL; put_disk(disk); module_put(owner); @@ -1134,6 +1079,63 @@ static int blkdev_open(struct inode * inode, struct file * filp) return res; } +static int __blkdev_put(struct block_device *bdev, unsigned int subclass) +{ + int ret = 0; + struct inode *bd_inode = bdev->bd_inode; + struct gendisk *disk = bdev->bd_disk; + + mutex_lock_nested(&bdev->bd_mutex, subclass); + lock_kernel(); + if (!--bdev->bd_openers) { + sync_blockdev(bdev); + kill_bdev(bdev); + } + if (bdev->bd_contains == bdev) { + if (disk->fops->release) + ret = disk->fops->release(bd_inode, NULL); + } else { + mutex_lock_nested(&bdev->bd_contains->bd_mutex, + subclass + 1); + bdev->bd_contains->bd_part_count--; + mutex_unlock(&bdev->bd_contains->bd_mutex); + } + if (!bdev->bd_openers) { + struct module *owner = disk->fops->owner; + + put_disk(disk); + module_put(owner); + + if (bdev->bd_contains != bdev) { + kobject_put(&bdev->bd_part->kobj); + bdev->bd_part = NULL; + } + bdev->bd_disk = NULL; + bdev->bd_inode->i_data.backing_dev_info = &default_backing_dev_info; + if (bdev != bdev->bd_contains) + __blkdev_put(bdev->bd_contains, subclass + 1); + bdev->bd_contains = NULL; + } + unlock_kernel(); + mutex_unlock(&bdev->bd_mutex); + bdput(bdev); + return ret; +} + +int blkdev_put(struct block_device *bdev) +{ + return __blkdev_put(bdev, BD_MUTEX_NORMAL); +} + +EXPORT_SYMBOL(blkdev_put); + +int blkdev_put_partition(struct block_device *bdev) +{ + return __blkdev_put(bdev, BD_MUTEX_PARTITION); +} + +EXPORT_SYMBOL(blkdev_put_partition); + static int blkdev_close(struct inode * inode, struct file * filp) { struct block_device *bdev = I_BDEV(filp->f_mapping->host); diff --git a/trunk/fs/cifs/CHANGES b/trunk/fs/cifs/CHANGES index 0feb3bd49cb8..a61d17ed1827 100644 --- a/trunk/fs/cifs/CHANGES +++ b/trunk/fs/cifs/CHANGES @@ -1,13 +1,3 @@ -Version 1.45 ------------- -Do not time out lockw calls when using posix extensions. Do not -time out requests if server still responding reasonably fast -on requests on other threads. Improve POSIX locking emulation, -(lock cancel now works, and unlock of merged range works even -to Windows servers now). Fix oops on mount to lanman servers -(win9x, os/2 etc.) when null password. Do not send listxattr -(SMB to query all EAs) if nouser_xattr specified. - Version 1.44 ------------ Rewritten sessionsetup support, including support for legacy SMB diff --git a/trunk/fs/cifs/README b/trunk/fs/cifs/README index 5f0e1bd64fee..7986d0d97ace 100644 --- a/trunk/fs/cifs/README +++ b/trunk/fs/cifs/README @@ -408,7 +408,7 @@ A partial list of the supported mount options follows: user_xattr Allow getting and setting user xattrs as OS/2 EAs (extended attributes) to the server (default) e.g. via setfattr and getfattr utilities. - nouser_xattr Do not allow getfattr/setfattr to get/set/list xattrs + nouser_xattr Do not allow getfattr/setfattr to get/set xattrs mapchars Translate six of the seven reserved characters (not backslash) *?<>|: to the remap range (above 0xF000), which also diff --git a/trunk/fs/cifs/cifsencrypt.c b/trunk/fs/cifs/cifsencrypt.c index 4bc250b2d9fc..a89efaf78a26 100644 --- a/trunk/fs/cifs/cifsencrypt.c +++ b/trunk/fs/cifs/cifsencrypt.c @@ -277,8 +277,7 @@ void calc_lanman_hash(struct cifsSesInfo * ses, char * lnm_session_key) return; memset(password_with_pad, 0, CIFS_ENCPWD_SIZE); - if(ses->password) - strncpy(password_with_pad, ses->password, CIFS_ENCPWD_SIZE); + strncpy(password_with_pad, ses->password, CIFS_ENCPWD_SIZE); if((ses->server->secMode & SECMODE_PW_ENCRYPT) == 0) if(extended_security & CIFSSEC_MAY_PLNTXT) { diff --git a/trunk/fs/cifs/cifsfs.c b/trunk/fs/cifs/cifsfs.c index 3cd750029be2..c28ede599946 100644 --- a/trunk/fs/cifs/cifsfs.c +++ b/trunk/fs/cifs/cifsfs.c @@ -402,6 +402,7 @@ static struct quotactl_ops cifs_quotactl_ops = { }; #endif +#ifdef CONFIG_CIFS_EXPERIMENTAL static void cifs_umount_begin(struct vfsmount * vfsmnt, int flags) { struct cifs_sb_info *cifs_sb; @@ -421,7 +422,7 @@ static void cifs_umount_begin(struct vfsmount * vfsmnt, int flags) tcon->tidStatus = CifsExiting; up(&tcon->tconSem); - /* cancel_brl_requests(tcon); */ /* BB mark all brl mids as exiting */ + /* cancel_brl_requests(tcon); */ /* cancel_notify_requests(tcon); */ if(tcon->ses && tcon->ses->server) { @@ -437,6 +438,7 @@ static void cifs_umount_begin(struct vfsmount * vfsmnt, int flags) return; } +#endif static int cifs_remount(struct super_block *sb, int *flags, char *data) { @@ -455,7 +457,9 @@ struct super_operations cifs_super_ops = { unless later we add lazy close of inodes or unless the kernel forgets to call us with the same number of releases (closes) as opens */ .show_options = cifs_show_options, +#ifdef CONFIG_CIFS_EXPERIMENTAL .umount_begin = cifs_umount_begin, +#endif .remount_fs = cifs_remount, }; diff --git a/trunk/fs/cifs/cifsfs.h b/trunk/fs/cifs/cifsfs.h index 39ee8ef3bdeb..8f75c6f24701 100644 --- a/trunk/fs/cifs/cifsfs.h +++ b/trunk/fs/cifs/cifsfs.h @@ -100,5 +100,5 @@ extern ssize_t cifs_getxattr(struct dentry *, const char *, void *, size_t); extern ssize_t cifs_listxattr(struct dentry *, char *, size_t); extern int cifs_ioctl (struct inode * inode, struct file * filep, unsigned int command, unsigned long arg); -#define CIFS_VERSION "1.45" +#define CIFS_VERSION "1.44" #endif /* _CIFSFS_H */ diff --git a/trunk/fs/cifs/cifsglob.h b/trunk/fs/cifs/cifsglob.h index b24006c47df1..6d7cf5f3bc0b 100644 --- a/trunk/fs/cifs/cifsglob.h +++ b/trunk/fs/cifs/cifsglob.h @@ -3,7 +3,6 @@ * * Copyright (C) International Business Machines Corp., 2002,2006 * Author(s): Steve French (sfrench@us.ibm.com) - * Jeremy Allison (jra@samba.org) * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published @@ -159,8 +158,7 @@ struct TCP_Server_Info { /* 16th byte of RFC1001 workstation name is always null */ char workstation_RFC1001_name[SERVER_NAME_LEN_WITH_NULL]; __u32 sequence_number; /* needed for CIFS PDU signature */ - char mac_signing_key[CIFS_SESS_KEY_SIZE + 16]; - unsigned long lstrp; /* when we got last response from this server */ + char mac_signing_key[CIFS_SESS_KEY_SIZE + 16]; }; /* @@ -268,14 +266,14 @@ struct cifsTconInfo { }; /* - * This info hangs off the cifsFileInfo structure, pointed to by llist. - * This is used to track byte stream locks on the file + * This info hangs off the cifsFileInfo structure. This is used to track + * byte stream locks on the file */ struct cifsLockInfo { - struct list_head llist; /* pointer to next cifsLockInfo */ - __u64 offset; - __u64 length; - __u8 type; + struct cifsLockInfo *next; + int start; + int length; + int type; }; /* @@ -306,8 +304,6 @@ struct cifsFileInfo { /* lock scope id (0 if none) */ struct file * pfile; /* needed for writepage */ struct inode * pInode; /* needed for oplock break */ - struct semaphore lock_sem; - struct list_head llist; /* list of byte range locks we have. */ unsigned closePend:1; /* file is marked to close */ unsigned invalidHandle:1; /* file closed via session abend */ atomic_t wrtPending; /* handle in use - defer close */ diff --git a/trunk/fs/cifs/cifsproto.h b/trunk/fs/cifs/cifsproto.h index b35c55c3c8bb..a5ddc62d6fe6 100644 --- a/trunk/fs/cifs/cifsproto.h +++ b/trunk/fs/cifs/cifsproto.h @@ -50,10 +50,6 @@ extern int SendReceive(const unsigned int /* xid */ , struct cifsSesInfo *, extern int SendReceive2(const unsigned int /* xid */ , struct cifsSesInfo *, struct kvec *, int /* nvec to send */, int * /* type of buf returned */ , const int long_op); -extern int SendReceiveBlockingLock(const unsigned int /* xid */ , struct cifsTconInfo *, - struct smb_hdr * /* input */ , - struct smb_hdr * /* out */ , - int * /* bytes returned */); extern int checkSMBhdr(struct smb_hdr *smb, __u16 mid); extern int checkSMB(struct smb_hdr *smb, __u16 mid, int length); extern int is_valid_oplock_break(struct smb_hdr *smb, struct TCP_Server_Info *); diff --git a/trunk/fs/cifs/cifssmb.c b/trunk/fs/cifs/cifssmb.c index 075d8fb3d376..19678c575dfc 100644 --- a/trunk/fs/cifs/cifssmb.c +++ b/trunk/fs/cifs/cifssmb.c @@ -477,7 +477,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) /* BB get server time for time conversions and add code to use it and timezone since this is not UTC */ - if (rsp->EncryptionKeyLength == cpu_to_le16(CIFS_CRYPTO_KEY_SIZE)) { + if (rsp->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) { memcpy(server->cryptKey, rsp->EncryptionKey, CIFS_CRYPTO_KEY_SIZE); } else if (server->secMode & SECMODE_PW_ENCRYPT) { @@ -1460,13 +1460,8 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon, pSMB->hdr.smb_buf_length += count; pSMB->ByteCount = cpu_to_le16(count); - if (waitFlag) { - rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB, - (struct smb_hdr *) pSMBr, &bytes_returned); - } else { - rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, + rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, timeout); - } cifs_stats_inc(&tcon->num_locks); if (rc) { cFYI(1, ("Send error in Lock = %d", rc)); @@ -1489,7 +1484,6 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon, char *data_offset; struct cifs_posix_lock *parm_data; int rc = 0; - int timeout = 0; int bytes_returned = 0; __u16 params, param_offset, offset, byte_count, count; @@ -1509,6 +1503,7 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon, pSMB->MaxSetupCount = 0; pSMB->Reserved = 0; pSMB->Flags = 0; + pSMB->Timeout = 0; pSMB->Reserved2 = 0; param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4; offset = param_offset + params; @@ -1534,13 +1529,8 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon, (((char *) &pSMB->hdr.Protocol) + offset); parm_data->lock_type = cpu_to_le16(lock_type); - if(waitFlag) { - timeout = 3; /* blocking operation, no timeout */ + if(waitFlag) parm_data->lock_flags = cpu_to_le16(1); - pSMB->Timeout = cpu_to_le32(-1); - } else - pSMB->Timeout = 0; - parm_data->pid = cpu_to_le32(current->tgid); parm_data->start = cpu_to_le64(pLockData->fl_start); parm_data->length = cpu_to_le64(len); /* normalize negative numbers */ @@ -1551,14 +1541,8 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon, pSMB->Reserved4 = 0; pSMB->hdr.smb_buf_length += byte_count; pSMB->ByteCount = cpu_to_le16(byte_count); - if (waitFlag) { - rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB, - (struct smb_hdr *) pSMBr, &bytes_returned); - } else { - rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, - (struct smb_hdr *) pSMBr, &bytes_returned, timeout); - } - + rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, + (struct smb_hdr *) pSMBr, &bytes_returned, 0); if (rc) { cFYI(1, ("Send error in Posix Lock = %d", rc)); } else if (get_flag) { diff --git a/trunk/fs/cifs/connect.c b/trunk/fs/cifs/connect.c index 5d394c726860..876eb9ef85fe 100644 --- a/trunk/fs/cifs/connect.c +++ b/trunk/fs/cifs/connect.c @@ -182,7 +182,6 @@ cifs_reconnect(struct TCP_Server_Info *server) while ((server->tcpStatus != CifsExiting) && (server->tcpStatus != CifsGood)) { - try_to_freeze(); if(server->protocolType == IPV6) { rc = ipv6_connect(&server->addr.sockAddr6,&server->ssocket); } else { @@ -613,10 +612,6 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) #ifdef CONFIG_CIFS_STATS2 mid_entry->when_received = jiffies; #endif - /* so we do not time out requests to server - which is still responding (since server could - be busy but not dead) */ - server->lstrp = jiffies; break; } } @@ -1271,35 +1266,33 @@ find_unc(__be32 new_target_ip_addr, char *uncName, char *userName) read_lock(&GlobalSMBSeslock); list_for_each(tmp, &GlobalTreeConnectionList) { - cFYI(1, ("Next tcon")); + cFYI(1, ("Next tcon - ")); tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList); if (tcon->ses) { if (tcon->ses->server) { cFYI(1, - ("old ip addr: %x == new ip %x ?", + (" old ip addr: %x == new ip %x ?", tcon->ses->server->addr.sockAddr.sin_addr. s_addr, new_target_ip_addr)); if (tcon->ses->server->addr.sockAddr.sin_addr. s_addr == new_target_ip_addr) { - /* BB lock tcon, server and tcp session and increment use count here? */ + /* BB lock tcon and server and tcp session and increment use count here? */ /* found a match on the TCP session */ /* BB check if reconnection needed */ - cFYI(1,("IP match, old UNC: %s new: %s", + cFYI(1,("Matched ip, old UNC: %s == new: %s ?", tcon->treeName, uncName)); if (strncmp (tcon->treeName, uncName, MAX_TREE_SIZE) == 0) { cFYI(1, - ("and old usr: %s new: %s", + ("Matched UNC, old user: %s == new: %s ?", tcon->treeName, uncName)); if (strncmp (tcon->ses->userName, userName, MAX_USERNAME_SIZE) == 0) { read_unlock(&GlobalSMBSeslock); - /* matched smb session - (user name */ - return tcon; + return tcon;/* also matched user (smb session)*/ } } } @@ -1976,18 +1969,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, } cFYI(1,("Negotiate caps 0x%x",(int)cap)); -#ifdef CONFIG_CIFS_DEBUG2 - if(cap & CIFS_UNIX_FCNTL_CAP) - cFYI(1,("FCNTL cap")); - if(cap & CIFS_UNIX_EXTATTR_CAP) - cFYI(1,("EXTATTR cap")); - if(cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) - cFYI(1,("POSIX path cap")); - if(cap & CIFS_UNIX_XATTR_CAP) - cFYI(1,("XATTR cap")); - if(cap & CIFS_UNIX_POSIX_ACL_CAP) - cFYI(1,("POSIX ACL cap")); -#endif /* CIFS_DEBUG2 */ + if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) { cFYI(1,("setting capabilities failed")); } diff --git a/trunk/fs/cifs/dir.c b/trunk/fs/cifs/dir.c index 914239d53634..ba4cbe9b0684 100644 --- a/trunk/fs/cifs/dir.c +++ b/trunk/fs/cifs/dir.c @@ -267,10 +267,6 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, pCifsFile->invalidHandle = FALSE; pCifsFile->closePend = FALSE; init_MUTEX(&pCifsFile->fh_sem); - init_MUTEX(&pCifsFile->lock_sem); - INIT_LIST_HEAD(&pCifsFile->llist); - atomic_set(&pCifsFile->wrtPending,0); - /* set the following in open now pCifsFile->pfile = file; */ write_lock(&GlobalSMBSeslock); diff --git a/trunk/fs/cifs/file.c b/trunk/fs/cifs/file.c index e9c5ba9084fc..944d2b9e092d 100644 --- a/trunk/fs/cifs/file.c +++ b/trunk/fs/cifs/file.c @@ -5,7 +5,6 @@ * * Copyright (C) International Business Machines Corp., 2002,2003 * Author(s): Steve French (sfrench@us.ibm.com) - * Jeremy Allison (jra@samba.org) * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published @@ -48,8 +47,6 @@ static inline struct cifsFileInfo *cifs_init_private( private_data->netfid = netfid; private_data->pid = current->tgid; init_MUTEX(&private_data->fh_sem); - init_MUTEX(&private_data->lock_sem); - INIT_LIST_HEAD(&private_data->llist); private_data->pfile = file; /* needed for writepage */ private_data->pInode = inode; private_data->invalidHandle = FALSE; @@ -476,8 +473,6 @@ int cifs_close(struct inode *inode, struct file *file) cifs_sb = CIFS_SB(inode->i_sb); pTcon = cifs_sb->tcon; if (pSMBFile) { - struct cifsLockInfo *li, *tmp; - pSMBFile->closePend = TRUE; if (pTcon) { /* no sense reconnecting to close a file that is @@ -501,16 +496,6 @@ int cifs_close(struct inode *inode, struct file *file) pSMBFile->netfid); } } - - /* Delete any outstanding lock records. - We'll lose them when the file is closed anyway. */ - down(&pSMBFile->lock_sem); - list_for_each_entry_safe(li, tmp, &pSMBFile->llist, llist) { - list_del(&li->llist); - kfree(li); - } - up(&pSMBFile->lock_sem); - write_lock(&GlobalSMBSeslock); list_del(&pSMBFile->flist); list_del(&pSMBFile->tlist); @@ -585,21 +570,6 @@ int cifs_closedir(struct inode *inode, struct file *file) return rc; } -static int store_file_lock(struct cifsFileInfo *fid, __u64 len, - __u64 offset, __u8 lockType) -{ - struct cifsLockInfo *li = kmalloc(sizeof(struct cifsLockInfo), GFP_KERNEL); - if (li == NULL) - return -ENOMEM; - li->offset = offset; - li->length = len; - li->type = lockType; - down(&fid->lock_sem); - list_add(&li->llist, &fid->llist); - up(&fid->lock_sem); - return 0; -} - int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) { int rc, xid; @@ -611,7 +581,6 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) struct cifsTconInfo *pTcon; __u16 netfid; __u8 lockType = LOCKING_ANDX_LARGE_FILES; - int posix_locking; length = 1 + pfLock->fl_end - pfLock->fl_start; rc = -EACCES; @@ -670,14 +639,15 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) } netfid = ((struct cifsFileInfo *)file->private_data)->netfid; - posix_locking = (cifs_sb->tcon->ses->capabilities & CAP_UNIX) && - (CIFS_UNIX_FCNTL_CAP & le64_to_cpu(cifs_sb->tcon->fsUnixInfo.Capability)); /* BB add code here to normalize offset and length to account for negative length which we can not accept over the wire */ if (IS_GETLK(cmd)) { - if(posix_locking) { + if(experimEnabled && + (cifs_sb->tcon->ses->capabilities & CAP_UNIX) && + (CIFS_UNIX_FCNTL_CAP & + le64_to_cpu(cifs_sb->tcon->fsUnixInfo.Capability))) { int posix_lock_type; if(lockType & LOCKING_ANDX_SHARED_LOCK) posix_lock_type = CIFS_RDLCK; @@ -713,15 +683,10 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) FreeXid(xid); return rc; } - - if (!numLock && !numUnlock) { - /* if no lock or unlock then nothing - to do since we do not know what it is */ - FreeXid(xid); - return -EOPNOTSUPP; - } - - if (posix_locking) { + if (experimEnabled && + (cifs_sb->tcon->ses->capabilities & CAP_UNIX) && + (CIFS_UNIX_FCNTL_CAP & + le64_to_cpu(cifs_sb->tcon->fsUnixInfo.Capability))) { int posix_lock_type; if(lockType & LOCKING_ANDX_SHARED_LOCK) posix_lock_type = CIFS_RDLCK; @@ -730,46 +695,18 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) if(numUnlock == 1) posix_lock_type = CIFS_UNLCK; - + else if(numLock == 0) { + /* if no lock or unlock then nothing + to do since we do not know what it is */ + FreeXid(xid); + return -EOPNOTSUPP; + } rc = CIFSSMBPosixLock(xid, pTcon, netfid, 0 /* set */, length, pfLock, posix_lock_type, wait_flag); - } else { - struct cifsFileInfo *fid = (struct cifsFileInfo *)file->private_data; - - if (numLock) { - rc = CIFSSMBLock(xid, pTcon, netfid, length, pfLock->fl_start, - 0, numLock, lockType, wait_flag); - - if (rc == 0) { - /* For Windows locks we must store them. */ - rc = store_file_lock(fid, length, - pfLock->fl_start, lockType); - } - } else if (numUnlock) { - /* For each stored lock that this unlock overlaps - completely, unlock it. */ - int stored_rc = 0; - struct cifsLockInfo *li, *tmp; - - down(&fid->lock_sem); - list_for_each_entry_safe(li, tmp, &fid->llist, llist) { - if (pfLock->fl_start <= li->offset && - length >= li->length) { - stored_rc = CIFSSMBLock(xid, pTcon, netfid, - li->length, li->offset, - 1, 0, li->type, FALSE); - if (stored_rc) - rc = stored_rc; - - list_del(&li->llist); - kfree(li); - } - } - up(&fid->lock_sem); - } - } - + } else + rc = CIFSSMBLock(xid, pTcon, netfid, length, pfLock->fl_start, + numUnlock, numLock, lockType, wait_flag); if (pfLock->fl_flags & FL_POSIX) posix_lock_file_wait(file, pfLock); FreeXid(xid); diff --git a/trunk/fs/cifs/netmisc.c b/trunk/fs/cifs/netmisc.c index ce87550e918f..b66eff5dc624 100644 --- a/trunk/fs/cifs/netmisc.c +++ b/trunk/fs/cifs/netmisc.c @@ -72,7 +72,6 @@ static const struct smb_to_posix_error mapping_table_ERRDOS[] = { {ERRinvlevel,-EOPNOTSUPP}, {ERRdirnotempty, -ENOTEMPTY}, {ERRnotlocked, -ENOLCK}, - {ERRcancelviolation, -ENOLCK}, {ERRalreadyexists, -EEXIST}, {ERRmoredata, -EOVERFLOW}, {ERReasnotsupported,-EOPNOTSUPP}, diff --git a/trunk/fs/cifs/readdir.c b/trunk/fs/cifs/readdir.c index 105761e3ba0e..03bbcb377913 100644 --- a/trunk/fs/cifs/readdir.c +++ b/trunk/fs/cifs/readdir.c @@ -556,7 +556,7 @@ static int cifs_entry_is_dot(char *current_entry, struct cifsFileInfo *cfile) FIND_FILE_STANDARD_INFO * pFindData = (FIND_FILE_STANDARD_INFO *)current_entry; filename = &pFindData->FileName[0]; - len = pFindData->FileNameLength; + len = le32_to_cpu(pFindData->FileNameLength); } else { cFYI(1,("Unknown findfirst level %d",cfile->srch_inf.info_level)); } diff --git a/trunk/fs/cifs/sess.c b/trunk/fs/cifs/sess.c index d1705ab8136e..7202d534ef0b 100644 --- a/trunk/fs/cifs/sess.c +++ b/trunk/fs/cifs/sess.c @@ -372,7 +372,7 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time, /* no capabilities flags in old lanman negotiation */ - pSMB->old_req.PasswordLength = cpu_to_le16(CIFS_SESS_KEY_SIZE); + pSMB->old_req.PasswordLength = CIFS_SESS_KEY_SIZE; /* BB calculate hash with password */ /* and copy into bcc */ diff --git a/trunk/fs/cifs/smberr.h b/trunk/fs/cifs/smberr.h index 212c3c296409..cd41c67ff8d3 100644 --- a/trunk/fs/cifs/smberr.h +++ b/trunk/fs/cifs/smberr.h @@ -95,7 +95,6 @@ #define ERRinvlevel 124 #define ERRdirnotempty 145 #define ERRnotlocked 158 -#define ERRcancelviolation 173 #define ERRalreadyexists 183 #define ERRbadpipe 230 #define ERRpipebusy 231 diff --git a/trunk/fs/cifs/transport.c b/trunk/fs/cifs/transport.c index 48d47b46b1fb..17ba329e2b3d 100644 --- a/trunk/fs/cifs/transport.c +++ b/trunk/fs/cifs/transport.c @@ -3,8 +3,7 @@ * * Copyright (C) International Business Machines Corp., 2002,2005 * Author(s): Steve French (sfrench@us.ibm.com) - * Jeremy Allison (jra@samba.org) 2006. - * + * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation; either version 2.1 of the License, or @@ -37,7 +36,7 @@ extern mempool_t *cifs_mid_poolp; extern kmem_cache_t *cifs_oplock_cachep; static struct mid_q_entry * -AllocMidQEntry(const struct smb_hdr *smb_buffer, struct cifsSesInfo *ses) +AllocMidQEntry(struct smb_hdr *smb_buffer, struct cifsSesInfo *ses) { struct mid_q_entry *temp; @@ -204,10 +203,6 @@ smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer, rc = 0; } - /* Don't want to modify the buffer as a - side effect of this call. */ - smb_buffer->smb_buf_length = smb_buf_length; - return rc; } @@ -222,7 +217,6 @@ smb_send2(struct socket *ssocket, struct kvec *iov, int n_vec, unsigned int len = iov[0].iov_len; unsigned int total_len; int first_vec = 0; - unsigned int smb_buf_length = smb_buffer->smb_buf_length; if(ssocket == NULL) return -ENOTSOCK; /* BB eventually add reconnect code here */ @@ -299,15 +293,36 @@ smb_send2(struct socket *ssocket, struct kvec *iov, int n_vec, } else rc = 0; - /* Don't want to modify the buffer as a - side effect of this call. */ - smb_buffer->smb_buf_length = smb_buf_length; - return rc; } -static int wait_for_free_request(struct cifsSesInfo *ses, const int long_op) +int +SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, + struct kvec *iov, int n_vec, int * pRespBufType /* ret */, + const int long_op) { + int rc = 0; + unsigned int receive_len; + unsigned long timeout; + struct mid_q_entry *midQ; + struct smb_hdr *in_buf = iov[0].iov_base; + + *pRespBufType = CIFS_NO_BUFFER; /* no response buf yet */ + + if ((ses == NULL) || (ses->server == NULL)) { + cifs_small_buf_release(in_buf); + cERROR(1,("Null session")); + return -EIO; + } + + if(ses->server->tcpStatus == CifsExiting) { + cifs_small_buf_release(in_buf); + return -ENOENT; + } + + /* Ensure that we do not send more than 50 overlapping requests + to the same server. We may make this configurable later or + use ses->maxReq */ if(long_op == -1) { /* oplock breaks must not be held up */ atomic_inc(&ses->server->inFlight); @@ -330,140 +345,53 @@ static int wait_for_free_request(struct cifsSesInfo *ses, const int long_op) } else { if(ses->server->tcpStatus == CifsExiting) { spin_unlock(&GlobalMid_Lock); + cifs_small_buf_release(in_buf); return -ENOENT; } - /* can not count locking commands against total since - they are allowed to block on server */ + /* can not count locking commands against total since + they are allowed to block on server */ + if(long_op < 3) { /* update # of requests on the wire to server */ - if (long_op < 3) atomic_inc(&ses->server->inFlight); + } spin_unlock(&GlobalMid_Lock); break; } } } - return 0; -} + /* make sure that we sign in the same order that we send on this socket + and avoid races inside tcp sendmsg code that could cause corruption + of smb data */ + + down(&ses->server->tcpSem); -static int allocate_mid(struct cifsSesInfo *ses, struct smb_hdr *in_buf, - struct mid_q_entry **ppmidQ) -{ if (ses->server->tcpStatus == CifsExiting) { - return -ENOENT; + rc = -ENOENT; + goto out_unlock2; } else if (ses->server->tcpStatus == CifsNeedReconnect) { cFYI(1,("tcp session dead - return to caller to retry")); - return -EAGAIN; + rc = -EAGAIN; + goto out_unlock2; } else if (ses->status != CifsGood) { /* check if SMB session is bad because we are setting it up */ if((in_buf->Command != SMB_COM_SESSION_SETUP_ANDX) && (in_buf->Command != SMB_COM_NEGOTIATE)) { - return -EAGAIN; + rc = -EAGAIN; + goto out_unlock2; } /* else ok - we are setting up session */ } - *ppmidQ = AllocMidQEntry(in_buf, ses); - if (*ppmidQ == NULL) { - return -ENOMEM; - } - return 0; -} - -static int wait_for_response(struct cifsSesInfo *ses, - struct mid_q_entry *midQ, - unsigned long timeout, - unsigned long time_to_wait) -{ - unsigned long curr_timeout; - - for (;;) { - curr_timeout = timeout + jiffies; - wait_event(ses->server->response_q, - (!(midQ->midState == MID_REQUEST_SUBMITTED)) || - time_after(jiffies, curr_timeout) || - ((ses->server->tcpStatus != CifsGood) && - (ses->server->tcpStatus != CifsNew))); - - if (time_after(jiffies, curr_timeout) && - (midQ->midState == MID_REQUEST_SUBMITTED) && - ((ses->server->tcpStatus == CifsGood) || - (ses->server->tcpStatus == CifsNew))) { - - unsigned long lrt; - - /* We timed out. Is the server still - sending replies ? */ - spin_lock(&GlobalMid_Lock); - lrt = ses->server->lstrp; - spin_unlock(&GlobalMid_Lock); - - /* Calculate time_to_wait past last receive time. - Although we prefer not to time out if the - server is still responding - we will time - out if the server takes more than 15 (or 45 - or 180) seconds to respond to this request - and has not responded to any request from - other threads on the client within 10 seconds */ - lrt += time_to_wait; - if (time_after(jiffies, lrt)) { - /* No replies for time_to_wait. */ - cERROR(1,("server not responding")); - return -1; - } - } else { - return 0; - } - } -} - -int -SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, - struct kvec *iov, int n_vec, int * pRespBufType /* ret */, - const int long_op) -{ - int rc = 0; - unsigned int receive_len; - unsigned long timeout; - struct mid_q_entry *midQ; - struct smb_hdr *in_buf = iov[0].iov_base; - - *pRespBufType = CIFS_NO_BUFFER; /* no response buf yet */ - - if ((ses == NULL) || (ses->server == NULL)) { - cifs_small_buf_release(in_buf); - cERROR(1,("Null session")); - return -EIO; - } - - if(ses->server->tcpStatus == CifsExiting) { - cifs_small_buf_release(in_buf); - return -ENOENT; - } - - /* Ensure that we do not send more than 50 overlapping requests - to the same server. We may make this configurable later or - use ses->maxReq */ - - rc = wait_for_free_request(ses, long_op); - if (rc) { - cifs_small_buf_release(in_buf); - return rc; - } - - /* make sure that we sign in the same order that we send on this socket - and avoid races inside tcp sendmsg code that could cause corruption - of smb data */ - - down(&ses->server->tcpSem); - - rc = allocate_mid(ses, in_buf, &midQ); - if (rc) { + midQ = AllocMidQEntry(in_buf, ses); + if (midQ == NULL) { up(&ses->server->tcpSem); cifs_small_buf_release(in_buf); - /* Update # of requests on wire to server */ - atomic_dec(&ses->server->inFlight); - wake_up(&ses->server->request_q); - return rc; + /* If not lock req, update # of requests on wire to server */ + if(long_op < 3) { + atomic_dec(&ses->server->inFlight); + wake_up(&ses->server->request_q); + } + return -ENOMEM; } rc = cifs_sign_smb2(iov, n_vec, ses->server, &midQ->sequence_number); @@ -478,23 +406,32 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, atomic_dec(&ses->server->inSend); midQ->when_sent = jiffies; #endif - - up(&ses->server->tcpSem); - cifs_small_buf_release(in_buf); - - if(rc < 0) - goto out; + if(rc < 0) { + DeleteMidQEntry(midQ); + up(&ses->server->tcpSem); + cifs_small_buf_release(in_buf); + /* If not lock req, update # of requests on wire to server */ + if(long_op < 3) { + atomic_dec(&ses->server->inFlight); + wake_up(&ses->server->request_q); + } + return rc; + } else { + up(&ses->server->tcpSem); + cifs_small_buf_release(in_buf); + } if (long_op == -1) - goto out; + goto cifs_no_response_exit2; else if (long_op == 2) /* writes past end of file can take loong time */ timeout = 180 * HZ; else if (long_op == 1) timeout = 45 * HZ; /* should be greater than servers oplock break timeout (about 43 seconds) */ - else + else if (long_op > 2) { + timeout = MAX_SCHEDULE_TIMEOUT; + } else timeout = 15 * HZ; - /* wait for 15 seconds or until woken up due to response arriving or due to last connection to this server being unmounted */ if (signal_pending(current)) { @@ -504,7 +441,19 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, } /* No user interrupts in wait - wreaks havoc with performance */ - wait_for_response(ses, midQ, timeout, 10 * HZ); + if(timeout != MAX_SCHEDULE_TIMEOUT) { + timeout += jiffies; + wait_event(ses->server->response_q, + (!(midQ->midState & MID_REQUEST_SUBMITTED)) || + time_after(jiffies, timeout) || + ((ses->server->tcpStatus != CifsGood) && + (ses->server->tcpStatus != CifsNew))); + } else { + wait_event(ses->server->response_q, + (!(midQ->midState & MID_REQUEST_SUBMITTED)) || + ((ses->server->tcpStatus != CifsGood) && + (ses->server->tcpStatus != CifsNew))); + } spin_lock(&GlobalMid_Lock); if (midQ->resp_buf) { @@ -532,9 +481,11 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, } spin_unlock(&GlobalMid_Lock); DeleteMidQEntry(midQ); - /* Update # of requests on wire to server */ - atomic_dec(&ses->server->inFlight); - wake_up(&ses->server->request_q); + /* If not lock req, update # of requests on wire to server */ + if(long_op < 3) { + atomic_dec(&ses->server->inFlight); + wake_up(&ses->server->request_q); + } return rc; } @@ -585,12 +536,24 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, cFYI(1,("Bad MID state?")); } } +cifs_no_response_exit2: + DeleteMidQEntry(midQ); + + if(long_op < 3) { + atomic_dec(&ses->server->inFlight); + wake_up(&ses->server->request_q); + } -out: + return rc; - DeleteMidQEntry(midQ); - atomic_dec(&ses->server->inFlight); - wake_up(&ses->server->request_q); +out_unlock2: + up(&ses->server->tcpSem); + cifs_small_buf_release(in_buf); + /* If not lock req, update # of requests on wire to server */ + if(long_op < 3) { + atomic_dec(&ses->server->inFlight); + wake_up(&ses->server->request_q); + } return rc; } @@ -620,34 +583,85 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses, /* Ensure that we do not send more than 50 overlapping requests to the same server. We may make this configurable later or use ses->maxReq */ + if(long_op == -1) { + /* oplock breaks must not be held up */ + atomic_inc(&ses->server->inFlight); + } else { + spin_lock(&GlobalMid_Lock); + while(1) { + if(atomic_read(&ses->server->inFlight) >= + cifs_max_pending){ + spin_unlock(&GlobalMid_Lock); +#ifdef CONFIG_CIFS_STATS2 + atomic_inc(&ses->server->num_waiters); +#endif + wait_event(ses->server->request_q, + atomic_read(&ses->server->inFlight) + < cifs_max_pending); +#ifdef CONFIG_CIFS_STATS2 + atomic_dec(&ses->server->num_waiters); +#endif + spin_lock(&GlobalMid_Lock); + } else { + if(ses->server->tcpStatus == CifsExiting) { + spin_unlock(&GlobalMid_Lock); + return -ENOENT; + } - rc = wait_for_free_request(ses, long_op); - if (rc) - return rc; - + /* can not count locking commands against total since + they are allowed to block on server */ + + if(long_op < 3) { + /* update # of requests on the wire to server */ + atomic_inc(&ses->server->inFlight); + } + spin_unlock(&GlobalMid_Lock); + break; + } + } + } /* make sure that we sign in the same order that we send on this socket and avoid races inside tcp sendmsg code that could cause corruption of smb data */ down(&ses->server->tcpSem); - rc = allocate_mid(ses, in_buf, &midQ); - if (rc) { + if (ses->server->tcpStatus == CifsExiting) { + rc = -ENOENT; + goto out_unlock; + } else if (ses->server->tcpStatus == CifsNeedReconnect) { + cFYI(1,("tcp session dead - return to caller to retry")); + rc = -EAGAIN; + goto out_unlock; + } else if (ses->status != CifsGood) { + /* check if SMB session is bad because we are setting it up */ + if((in_buf->Command != SMB_COM_SESSION_SETUP_ANDX) && + (in_buf->Command != SMB_COM_NEGOTIATE)) { + rc = -EAGAIN; + goto out_unlock; + } /* else ok - we are setting up session */ + } + midQ = AllocMidQEntry(in_buf, ses); + if (midQ == NULL) { up(&ses->server->tcpSem); - /* Update # of requests on wire to server */ - atomic_dec(&ses->server->inFlight); - wake_up(&ses->server->request_q); - return rc; + /* If not lock req, update # of requests on wire to server */ + if(long_op < 3) { + atomic_dec(&ses->server->inFlight); + wake_up(&ses->server->request_q); + } + return -ENOMEM; } if (in_buf->smb_buf_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) { + up(&ses->server->tcpSem); cERROR(1, ("Illegal length, greater than maximum frame, %d", in_buf->smb_buf_length)); DeleteMidQEntry(midQ); - up(&ses->server->tcpSem); - /* Update # of requests on wire to server */ - atomic_dec(&ses->server->inFlight); - wake_up(&ses->server->request_q); + /* If not lock req, update # of requests on wire to server */ + if(long_op < 3) { + atomic_dec(&ses->server->inFlight); + wake_up(&ses->server->request_q); + } return -EIO; } @@ -663,19 +677,27 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses, atomic_dec(&ses->server->inSend); midQ->when_sent = jiffies; #endif - up(&ses->server->tcpSem); - - if(rc < 0) - goto out; - + if(rc < 0) { + DeleteMidQEntry(midQ); + up(&ses->server->tcpSem); + /* If not lock req, update # of requests on wire to server */ + if(long_op < 3) { + atomic_dec(&ses->server->inFlight); + wake_up(&ses->server->request_q); + } + return rc; + } else + up(&ses->server->tcpSem); if (long_op == -1) - goto out; + goto cifs_no_response_exit; else if (long_op == 2) /* writes past end of file can take loong time */ timeout = 180 * HZ; else if (long_op == 1) timeout = 45 * HZ; /* should be greater than servers oplock break timeout (about 43 seconds) */ - else + else if (long_op > 2) { + timeout = MAX_SCHEDULE_TIMEOUT; + } else timeout = 15 * HZ; /* wait for 15 seconds or until woken up due to response arriving or due to last connection to this server being unmounted */ @@ -686,7 +708,19 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses, } /* No user interrupts in wait - wreaks havoc with performance */ - wait_for_response(ses, midQ, timeout, 10 * HZ); + if(timeout != MAX_SCHEDULE_TIMEOUT) { + timeout += jiffies; + wait_event(ses->server->response_q, + (!(midQ->midState & MID_REQUEST_SUBMITTED)) || + time_after(jiffies, timeout) || + ((ses->server->tcpStatus != CifsGood) && + (ses->server->tcpStatus != CifsNew))); + } else { + wait_event(ses->server->response_q, + (!(midQ->midState & MID_REQUEST_SUBMITTED)) || + ((ses->server->tcpStatus != CifsGood) && + (ses->server->tcpStatus != CifsNew))); + } spin_lock(&GlobalMid_Lock); if (midQ->resp_buf) { @@ -714,9 +748,11 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses, } spin_unlock(&GlobalMid_Lock); DeleteMidQEntry(midQ); - /* Update # of requests on wire to server */ - atomic_dec(&ses->server->inFlight); - wake_up(&ses->server->request_q); + /* If not lock req, update # of requests on wire to server */ + if(long_op < 3) { + atomic_dec(&ses->server->inFlight); + wake_up(&ses->server->request_q); + } return rc; } @@ -763,253 +799,23 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses, cERROR(1,("Bad MID state?")); } } - -out: - +cifs_no_response_exit: DeleteMidQEntry(midQ); - atomic_dec(&ses->server->inFlight); - wake_up(&ses->server->request_q); - - return rc; -} - -/* Send an NT_CANCEL SMB to cause the POSIX blocking lock to return. */ - -static int -send_nt_cancel(struct cifsTconInfo *tcon, struct smb_hdr *in_buf, - struct mid_q_entry *midQ) -{ - int rc = 0; - struct cifsSesInfo *ses = tcon->ses; - __u16 mid = in_buf->Mid; - - header_assemble(in_buf, SMB_COM_NT_CANCEL, tcon, 0); - in_buf->Mid = mid; - down(&ses->server->tcpSem); - rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number); - if (rc) { - up(&ses->server->tcpSem); - return rc; - } - rc = smb_send(ses->server->ssocket, in_buf, in_buf->smb_buf_length, - (struct sockaddr *) &(ses->server->addr.sockAddr)); - up(&ses->server->tcpSem); - return rc; -} - -/* We send a LOCKINGX_CANCEL_LOCK to cause the Windows - blocking lock to return. */ - -static int -send_lock_cancel(const unsigned int xid, struct cifsTconInfo *tcon, - struct smb_hdr *in_buf, - struct smb_hdr *out_buf) -{ - int bytes_returned; - struct cifsSesInfo *ses = tcon->ses; - LOCK_REQ *pSMB = (LOCK_REQ *)in_buf; - - /* We just modify the current in_buf to change - the type of lock from LOCKING_ANDX_SHARED_LOCK - or LOCKING_ANDX_EXCLUSIVE_LOCK to - LOCKING_ANDX_CANCEL_LOCK. */ - - pSMB->LockType = LOCKING_ANDX_CANCEL_LOCK|LOCKING_ANDX_LARGE_FILES; - pSMB->Timeout = 0; - pSMB->hdr.Mid = GetNextMid(ses->server); - - return SendReceive(xid, ses, in_buf, out_buf, - &bytes_returned, 0); -} -int -SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon, - struct smb_hdr *in_buf, struct smb_hdr *out_buf, - int *pbytes_returned) -{ - int rc = 0; - int rstart = 0; - unsigned int receive_len; - struct mid_q_entry *midQ; - struct cifsSesInfo *ses; - - if (tcon == NULL || tcon->ses == NULL) { - cERROR(1,("Null smb session")); - return -EIO; - } - ses = tcon->ses; - - if(ses->server == NULL) { - cERROR(1,("Null tcp session")); - return -EIO; - } - - if(ses->server->tcpStatus == CifsExiting) - return -ENOENT; - - /* Ensure that we do not send more than 50 overlapping requests - to the same server. We may make this configurable later or - use ses->maxReq */ - - rc = wait_for_free_request(ses, 3); - if (rc) - return rc; - - /* make sure that we sign in the same order that we send on this socket - and avoid races inside tcp sendmsg code that could cause corruption - of smb data */ - - down(&ses->server->tcpSem); - - rc = allocate_mid(ses, in_buf, &midQ); - if (rc) { - up(&ses->server->tcpSem); - return rc; - } - - if (in_buf->smb_buf_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) { - up(&ses->server->tcpSem); - cERROR(1, ("Illegal length, greater than maximum frame, %d", - in_buf->smb_buf_length)); - DeleteMidQEntry(midQ); - return -EIO; + if(long_op < 3) { + atomic_dec(&ses->server->inFlight); + wake_up(&ses->server->request_q); } - rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number); + return rc; - midQ->midState = MID_REQUEST_SUBMITTED; -#ifdef CONFIG_CIFS_STATS2 - atomic_inc(&ses->server->inSend); -#endif - rc = smb_send(ses->server->ssocket, in_buf, in_buf->smb_buf_length, - (struct sockaddr *) &(ses->server->addr.sockAddr)); -#ifdef CONFIG_CIFS_STATS2 - atomic_dec(&ses->server->inSend); - midQ->when_sent = jiffies; -#endif +out_unlock: up(&ses->server->tcpSem); - - if(rc < 0) { - DeleteMidQEntry(midQ); - return rc; - } - - /* Wait for a reply - allow signals to interrupt. */ - rc = wait_event_interruptible(ses->server->response_q, - (!(midQ->midState == MID_REQUEST_SUBMITTED)) || - ((ses->server->tcpStatus != CifsGood) && - (ses->server->tcpStatus != CifsNew))); - - /* Were we interrupted by a signal ? */ - if ((rc == -ERESTARTSYS) && - (midQ->midState == MID_REQUEST_SUBMITTED) && - ((ses->server->tcpStatus == CifsGood) || - (ses->server->tcpStatus == CifsNew))) { - - if (in_buf->Command == SMB_COM_TRANSACTION2) { - /* POSIX lock. We send a NT_CANCEL SMB to cause the - blocking lock to return. */ - - rc = send_nt_cancel(tcon, in_buf, midQ); - if (rc) { - DeleteMidQEntry(midQ); - return rc; - } - } else { - /* Windows lock. We send a LOCKINGX_CANCEL_LOCK - to cause the blocking lock to return. */ - - rc = send_lock_cancel(xid, tcon, in_buf, out_buf); - - /* If we get -ENOLCK back the lock may have - already been removed. Don't exit in this case. */ - if (rc && rc != -ENOLCK) { - DeleteMidQEntry(midQ); - return rc; - } - } - - /* Wait 5 seconds for the response. */ - if (wait_for_response(ses, midQ, 5 * HZ, 5 * HZ)==0) { - /* We got the response - restart system call. */ - rstart = 1; - } - } - - spin_lock(&GlobalMid_Lock); - if (midQ->resp_buf) { - spin_unlock(&GlobalMid_Lock); - receive_len = midQ->resp_buf->smb_buf_length; - } else { - cERROR(1,("No response for cmd %d mid %d", - midQ->command, midQ->mid)); - if(midQ->midState == MID_REQUEST_SUBMITTED) { - if(ses->server->tcpStatus == CifsExiting) - rc = -EHOSTDOWN; - else { - ses->server->tcpStatus = CifsNeedReconnect; - midQ->midState = MID_RETRY_NEEDED; - } - } - - if (rc != -EHOSTDOWN) { - if(midQ->midState == MID_RETRY_NEEDED) { - rc = -EAGAIN; - cFYI(1,("marking request for retry")); - } else { - rc = -EIO; - } - } - spin_unlock(&GlobalMid_Lock); - DeleteMidQEntry(midQ); - return rc; + /* If not lock req, update # of requests on wire to server */ + if(long_op < 3) { + atomic_dec(&ses->server->inFlight); + wake_up(&ses->server->request_q); } - - if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) { - cERROR(1, ("Frame too large received. Length: %d Xid: %d", - receive_len, xid)); - rc = -EIO; - } else { /* rcvd frame is ok */ - - if (midQ->resp_buf && out_buf - && (midQ->midState == MID_RESPONSE_RECEIVED)) { - out_buf->smb_buf_length = receive_len; - memcpy((char *)out_buf + 4, - (char *)midQ->resp_buf + 4, - receive_len); - - dump_smb(out_buf, 92); - /* convert the length into a more usable form */ - if((receive_len > 24) && - (ses->server->secMode & (SECMODE_SIGN_REQUIRED | - SECMODE_SIGN_ENABLED))) { - rc = cifs_verify_signature(out_buf, - ses->server->mac_signing_key, - midQ->sequence_number+1); - if(rc) { - cERROR(1,("Unexpected SMB signature")); - /* BB FIXME add code to kill session */ - } - } - - *pbytes_returned = out_buf->smb_buf_length; - - /* BB special case reconnect tid and uid here? */ - rc = map_smb_to_linux_error(out_buf); - /* convert ByteCount if necessary */ - if (receive_len >= - sizeof (struct smb_hdr) - - 4 /* do not count RFC1001 header */ + - (2 * out_buf->WordCount) + 2 /* bcc */ ) - BCC(out_buf) = le16_to_cpu(BCC_LE(out_buf)); - } else { - rc = -EIO; - cERROR(1,("Bad MID state?")); - } - } - DeleteMidQEntry(midQ); - if (rstart && rc == -EACCES) - return -ERESTARTSYS; return rc; } diff --git a/trunk/fs/cifs/xattr.c b/trunk/fs/cifs/xattr.c index 067648b7179b..7754d641775e 100644 --- a/trunk/fs/cifs/xattr.c +++ b/trunk/fs/cifs/xattr.c @@ -330,15 +330,11 @@ ssize_t cifs_listxattr(struct dentry * direntry, char * data, size_t buf_size) sb = direntry->d_inode->i_sb; if(sb == NULL) return -EIO; + xid = GetXid(); cifs_sb = CIFS_SB(sb); pTcon = cifs_sb->tcon; - if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR) - return -EOPNOTSUPP; - - xid = GetXid(); - full_path = build_path_from_dentry(direntry); if(full_path == NULL) { FreeXid(xid); diff --git a/trunk/fs/eventpoll.c b/trunk/fs/eventpoll.c index 3a3567433b92..19ffb043abbc 100644 --- a/trunk/fs/eventpoll.c +++ b/trunk/fs/eventpoll.c @@ -1168,7 +1168,7 @@ static int ep_unlink(struct eventpoll *ep, struct epitem *epi) eexit_1: DNPRINTK(3, (KERN_INFO "[%p] eventpoll: ep_unlink(%p, %p) = %d\n", - current, ep, epi->ffd.file, error)); + current, ep, epi->file, error)); return error; } @@ -1236,7 +1236,7 @@ static int ep_poll_callback(wait_queue_t *wait, unsigned mode, int sync, void *k struct eventpoll *ep = epi->ep; DNPRINTK(3, (KERN_INFO "[%p] eventpoll: poll_callback(%p) epi=%p ep=%p\n", - current, epi->ffd.file, epi, ep)); + current, epi->file, epi, ep)); write_lock_irqsave(&ep->lock, flags); diff --git a/trunk/fs/exec.c b/trunk/fs/exec.c index 54135df2a966..8344ba73a2a6 100644 --- a/trunk/fs/exec.c +++ b/trunk/fs/exec.c @@ -486,6 +486,8 @@ struct file *open_exec(const char *name) if (!(nd.mnt->mnt_flags & MNT_NOEXEC) && S_ISREG(inode->i_mode)) { int err = vfs_permission(&nd, MAY_EXEC); + if (!err && !(inode->i_mode & 0111)) + err = -EACCES; file = ERR_PTR(err); if (!err) { file = nameidata_to_filp(&nd, O_RDONLY); @@ -751,7 +753,7 @@ static int de_thread(struct task_struct *tsk) write_lock_irq(&tasklist_lock); spin_lock(&oldsighand->siglock); - spin_lock_nested(&newsighand->siglock, SINGLE_DEPTH_NESTING); + spin_lock(&newsighand->siglock); rcu_assign_pointer(current->sighand, newsighand); recalc_sigpending(); @@ -920,6 +922,12 @@ int prepare_binprm(struct linux_binprm *bprm) int retval; mode = inode->i_mode; + /* + * Check execute perms again - if the caller has CAP_DAC_OVERRIDE, + * generic_permission lets a non-executable through + */ + if (!(mode & 0111)) /* with at least _one_ execute bit set */ + return -EACCES; if (bprm->file->f_op == NULL) return -EACCES; diff --git a/trunk/fs/ext2/super.c b/trunk/fs/ext2/super.c index 681dea8f9532..f2702cda9779 100644 --- a/trunk/fs/ext2/super.c +++ b/trunk/fs/ext2/super.c @@ -775,7 +775,7 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent) if (EXT2_INODE_SIZE(sb) == 0) goto cantfind_ext2; sbi->s_inodes_per_block = sb->s_blocksize / EXT2_INODE_SIZE(sb); - if (sbi->s_inodes_per_block == 0 || sbi->s_inodes_per_group == 0) + if (sbi->s_inodes_per_block == 0) goto cantfind_ext2; sbi->s_itb_per_group = sbi->s_inodes_per_group / sbi->s_inodes_per_block; diff --git a/trunk/fs/ext3/balloc.c b/trunk/fs/ext3/balloc.c index 063d994bda0b..a504a40d6d29 100644 --- a/trunk/fs/ext3/balloc.c +++ b/trunk/fs/ext3/balloc.c @@ -1269,12 +1269,12 @@ ext3_fsblk_t ext3_new_blocks(handle_t *handle, struct inode *inode, goal = le32_to_cpu(es->s_first_data_block); group_no = (goal - le32_to_cpu(es->s_first_data_block)) / EXT3_BLOCKS_PER_GROUP(sb); - goal_group = group_no; -retry_alloc: gdp = ext3_get_group_desc(sb, group_no, &gdp_bh); if (!gdp) goto io_error; + goal_group = group_no; +retry: free_blocks = le16_to_cpu(gdp->bg_free_blocks_count); /* * if there is not enough free blocks to make a new resevation @@ -1349,7 +1349,7 @@ ext3_fsblk_t ext3_new_blocks(handle_t *handle, struct inode *inode, if (my_rsv) { my_rsv = NULL; group_no = goal_group; - goto retry_alloc; + goto retry; } /* No space left on the device */ *errp = -ENOSPC; diff --git a/trunk/fs/ioprio.c b/trunk/fs/ioprio.c index 78b1deae3fa2..93aa5715f224 100644 --- a/trunk/fs/ioprio.c +++ b/trunk/fs/ioprio.c @@ -44,9 +44,6 @@ static int set_task_ioprio(struct task_struct *task, int ioprio) task->ioprio = ioprio; ioc = task->io_context; - /* see wmb() in current_io_context() */ - smp_read_barrier_depends(); - if (ioc && ioc->set_ioprio) ioc->set_ioprio(ioc, ioprio); @@ -114,9 +111,9 @@ asmlinkage long sys_ioprio_set(int which, int who, int ioprio) continue; ret = set_task_ioprio(p, ioprio); if (ret) - goto free_uid; + break; } while_each_thread(g, p); -free_uid: + if (who) free_uid(user); break; @@ -140,29 +137,6 @@ static int get_task_ioprio(struct task_struct *p) return ret; } -int ioprio_best(unsigned short aprio, unsigned short bprio) -{ - unsigned short aclass = IOPRIO_PRIO_CLASS(aprio); - unsigned short bclass = IOPRIO_PRIO_CLASS(bprio); - - if (!ioprio_valid(aprio)) - return bprio; - if (!ioprio_valid(bprio)) - return aprio; - - if (aclass == IOPRIO_CLASS_NONE) - aclass = IOPRIO_CLASS_BE; - if (bclass == IOPRIO_CLASS_NONE) - bclass = IOPRIO_CLASS_BE; - - if (aclass == bclass) - return min(aprio, bprio); - if (aclass > bclass) - return bprio; - else - return aprio; -} - asmlinkage long sys_ioprio_get(int which, int who) { struct task_struct *g, *p; diff --git a/trunk/fs/jbd/commit.c b/trunk/fs/jbd/commit.c index 42da60784311..0971814c38b8 100644 --- a/trunk/fs/jbd/commit.c +++ b/trunk/fs/jbd/commit.c @@ -261,7 +261,7 @@ void journal_commit_transaction(journal_t *journal) struct buffer_head *bh = jh2bh(jh); jbd_lock_bh_state(bh); - jbd_slab_free(jh->b_committed_data, bh->b_size); + kfree(jh->b_committed_data); jh->b_committed_data = NULL; jbd_unlock_bh_state(bh); } @@ -745,14 +745,14 @@ void journal_commit_transaction(journal_t *journal) * Otherwise, we can just throw away the frozen data now. */ if (jh->b_committed_data) { - jbd_slab_free(jh->b_committed_data, bh->b_size); + kfree(jh->b_committed_data); jh->b_committed_data = NULL; if (jh->b_frozen_data) { jh->b_committed_data = jh->b_frozen_data; jh->b_frozen_data = NULL; } } else if (jh->b_frozen_data) { - jbd_slab_free(jh->b_frozen_data, bh->b_size); + kfree(jh->b_frozen_data); jh->b_frozen_data = NULL; } diff --git a/trunk/fs/jbd/journal.c b/trunk/fs/jbd/journal.c index f66724ce443a..8c9b28dff119 100644 --- a/trunk/fs/jbd/journal.c +++ b/trunk/fs/jbd/journal.c @@ -84,7 +84,6 @@ EXPORT_SYMBOL(journal_force_commit); static int journal_convert_superblock_v1(journal_t *, journal_superblock_t *); static void __journal_abort_soft (journal_t *journal, int errno); -static int journal_create_jbd_slab(size_t slab_size); /* * Helper function used to manage commit timeouts @@ -329,10 +328,10 @@ int journal_write_metadata_buffer(transaction_t *transaction, char *tmp; jbd_unlock_bh_state(bh_in); - tmp = jbd_slab_alloc(bh_in->b_size, GFP_NOFS); + tmp = jbd_rep_kmalloc(bh_in->b_size, GFP_NOFS); jbd_lock_bh_state(bh_in); if (jh_in->b_frozen_data) { - jbd_slab_free(tmp, bh_in->b_size); + kfree(tmp); goto repeat; } @@ -1070,17 +1069,17 @@ static int load_superblock(journal_t *journal) int journal_load(journal_t *journal) { int err; - journal_superblock_t *sb; err = load_superblock(journal); if (err) return err; - sb = journal->j_superblock; /* If this is a V2 superblock, then we have to check the * features flags on it. */ if (journal->j_format_version >= 2) { + journal_superblock_t *sb = journal->j_superblock; + if ((sb->s_feature_ro_compat & ~cpu_to_be32(JFS_KNOWN_ROCOMPAT_FEATURES)) || (sb->s_feature_incompat & @@ -1091,13 +1090,6 @@ int journal_load(journal_t *journal) } } - /* - * Create a slab for this blocksize - */ - err = journal_create_jbd_slab(cpu_to_be32(sb->s_blocksize)); - if (err) - return err; - /* Let the recovery code check whether it needs to recover any * data from the journal. */ if (journal_recover(journal)) @@ -1619,77 +1611,6 @@ void * __jbd_kmalloc (const char *where, size_t size, gfp_t flags, int retry) return kmalloc(size, flags | (retry ? __GFP_NOFAIL : 0)); } -/* - * jbd slab management: create 1k, 2k, 4k, 8k slabs as needed - * and allocate frozen and commit buffers from these slabs. - * - * Reason for doing this is to avoid, SLAB_DEBUG - since it could - * cause bh to cross page boundary. - */ - -#define JBD_MAX_SLABS 5 -#define JBD_SLAB_INDEX(size) (size >> 11) - -static kmem_cache_t *jbd_slab[JBD_MAX_SLABS]; -static const char *jbd_slab_names[JBD_MAX_SLABS] = { - "jbd_1k", "jbd_2k", "jbd_4k", NULL, "jbd_8k" -}; - -static void journal_destroy_jbd_slabs(void) -{ - int i; - - for (i = 0; i < JBD_MAX_SLABS; i++) { - if (jbd_slab[i]) - kmem_cache_destroy(jbd_slab[i]); - jbd_slab[i] = NULL; - } -} - -static int journal_create_jbd_slab(size_t slab_size) -{ - int i = JBD_SLAB_INDEX(slab_size); - - BUG_ON(i >= JBD_MAX_SLABS); - - /* - * Check if we already have a slab created for this size - */ - if (jbd_slab[i]) - return 0; - - /* - * Create a slab and force alignment to be same as slabsize - - * this will make sure that allocations won't cross the page - * boundary. - */ - jbd_slab[i] = kmem_cache_create(jbd_slab_names[i], - slab_size, slab_size, 0, NULL, NULL); - if (!jbd_slab[i]) { - printk(KERN_EMERG "JBD: no memory for jbd_slab cache\n"); - return -ENOMEM; - } - return 0; -} - -void * jbd_slab_alloc(size_t size, gfp_t flags) -{ - int idx; - - idx = JBD_SLAB_INDEX(size); - BUG_ON(jbd_slab[idx] == NULL); - return kmem_cache_alloc(jbd_slab[idx], flags | __GFP_NOFAIL); -} - -void jbd_slab_free(void *ptr, size_t size) -{ - int idx; - - idx = JBD_SLAB_INDEX(size); - BUG_ON(jbd_slab[idx] == NULL); - kmem_cache_free(jbd_slab[idx], ptr); -} - /* * Journal_head storage management */ @@ -1878,13 +1799,13 @@ static void __journal_remove_journal_head(struct buffer_head *bh) printk(KERN_WARNING "%s: freeing " "b_frozen_data\n", __FUNCTION__); - jbd_slab_free(jh->b_frozen_data, bh->b_size); + kfree(jh->b_frozen_data); } if (jh->b_committed_data) { printk(KERN_WARNING "%s: freeing " "b_committed_data\n", __FUNCTION__); - jbd_slab_free(jh->b_committed_data, bh->b_size); + kfree(jh->b_committed_data); } bh->b_private = NULL; jh->b_bh = NULL; /* debug, really */ @@ -2040,7 +1961,6 @@ static void journal_destroy_caches(void) journal_destroy_revoke_caches(); journal_destroy_journal_head_cache(); journal_destroy_handle_cache(); - journal_destroy_jbd_slabs(); } static int __init journal_init(void) diff --git a/trunk/fs/jbd/transaction.c b/trunk/fs/jbd/transaction.c index f5169a96260e..508b2ea91f43 100644 --- a/trunk/fs/jbd/transaction.c +++ b/trunk/fs/jbd/transaction.c @@ -666,9 +666,8 @@ do_get_write_access(handle_t *handle, struct journal_head *jh, if (!frozen_buffer) { JBUFFER_TRACE(jh, "allocate memory for buffer"); jbd_unlock_bh_state(bh); - frozen_buffer = - jbd_slab_alloc(jh2bh(jh)->b_size, - GFP_NOFS); + frozen_buffer = jbd_kmalloc(jh2bh(jh)->b_size, + GFP_NOFS); if (!frozen_buffer) { printk(KERN_EMERG "%s: OOM for frozen_buffer\n", @@ -727,7 +726,7 @@ do_get_write_access(handle_t *handle, struct journal_head *jh, out: if (unlikely(frozen_buffer)) /* It's usually NULL */ - jbd_slab_free(frozen_buffer, bh->b_size); + kfree(frozen_buffer); JBUFFER_TRACE(jh, "exit"); return error; @@ -880,7 +879,7 @@ int journal_get_undo_access(handle_t *handle, struct buffer_head *bh) repeat: if (!jh->b_committed_data) { - committed_data = jbd_slab_alloc(jh2bh(jh)->b_size, GFP_NOFS); + committed_data = jbd_kmalloc(jh2bh(jh)->b_size, GFP_NOFS); if (!committed_data) { printk(KERN_EMERG "%s: No memory for committed data\n", __FUNCTION__); @@ -907,7 +906,7 @@ int journal_get_undo_access(handle_t *handle, struct buffer_head *bh) out: journal_put_journal_head(jh); if (unlikely(committed_data)) - jbd_slab_free(committed_data, bh->b_size); + kfree(committed_data); return err; } diff --git a/trunk/fs/lockd/svcsubs.c b/trunk/fs/lockd/svcsubs.c index 01b4db9e5466..2a4df9b3779a 100644 --- a/trunk/fs/lockd/svcsubs.c +++ b/trunk/fs/lockd/svcsubs.c @@ -237,22 +237,19 @@ static int nlm_traverse_files(struct nlm_host *host, int action) { struct nlm_file *file, **fp; - int i, ret = 0; + int i; mutex_lock(&nlm_file_mutex); for (i = 0; i < FILE_NRHASH; i++) { fp = nlm_files + i; while ((file = *fp) != NULL) { - file->f_count++; - mutex_unlock(&nlm_file_mutex); - /* Traverse locks, blocks and shares of this file * and update file->f_locks count */ - if (nlm_inspect_file(host, file, action)) - ret = 1; + if (nlm_inspect_file(host, file, action)) { + mutex_unlock(&nlm_file_mutex); + return 1; + } - mutex_lock(&nlm_file_mutex); - file->f_count--; /* No more references to this file. Let go of it. */ if (!file->f_blocks && !file->f_locks && !file->f_shares && !file->f_count) { @@ -265,7 +262,7 @@ nlm_traverse_files(struct nlm_host *host, int action) } } mutex_unlock(&nlm_file_mutex); - return ret; + return 0; } /* diff --git a/trunk/fs/minix/inode.c b/trunk/fs/minix/inode.c index 330ff9fc7cf0..9ea91c5eeb7b 100644 --- a/trunk/fs/minix/inode.c +++ b/trunk/fs/minix/inode.c @@ -204,8 +204,6 @@ static int minix_fill_super(struct super_block *s, void *data, int silent) /* * Allocate the buffer map to keep the superblock small. */ - if (sbi->s_imap_blocks == 0 || sbi->s_zmap_blocks == 0) - goto out_illegal_sb; i = (sbi->s_imap_blocks + sbi->s_zmap_blocks) * sizeof(bh); map = kmalloc(i, GFP_KERNEL); if (!map) @@ -265,7 +263,7 @@ static int minix_fill_super(struct super_block *s, void *data, int silent) out_no_bitmap: printk("MINIX-fs: bad superblock or unable to read bitmaps\n"); -out_freemap: + out_freemap: for (i = 0; i < sbi->s_imap_blocks; i++) brelse(sbi->s_imap[i]); for (i = 0; i < sbi->s_zmap_blocks; i++) @@ -278,16 +276,11 @@ static int minix_fill_super(struct super_block *s, void *data, int silent) printk("MINIX-fs: can't allocate map\n"); goto out_release; -out_illegal_sb: - if (!silent) - printk("MINIX-fs: bad superblock\n"); - goto out_release; - out_no_fs: if (!silent) printk("VFS: Can't find a Minix or Minix V2 filesystem " "on device %s\n", s->s_id); -out_release: + out_release: brelse(bh); goto out; @@ -297,7 +290,7 @@ static int minix_fill_super(struct super_block *s, void *data, int silent) out_bad_sb: printk("MINIX-fs: unable to read superblock\n"); -out: + out: s->s_fs_info = NULL; kfree(sbi); return -EINVAL; diff --git a/trunk/fs/namei.c b/trunk/fs/namei.c index 432d6bc6fab0..55a131230f94 100644 --- a/trunk/fs/namei.c +++ b/trunk/fs/namei.c @@ -227,10 +227,10 @@ int generic_permission(struct inode *inode, int mask, int permission(struct inode *inode, int mask, struct nameidata *nd) { - umode_t mode = inode->i_mode; int retval, submask; if (mask & MAY_WRITE) { + umode_t mode = inode->i_mode; /* * Nobody gets write access to a read-only fs. @@ -247,13 +247,6 @@ int permission(struct inode *inode, int mask, struct nameidata *nd) } - /* - * MAY_EXEC on regular files requires special handling: We override - * filesystem execute permissions if the mode bits aren't set. - */ - if ((mask & MAY_EXEC) && S_ISREG(mode) && !(mode & S_IXUGO)) - return -EACCES; - /* Ordinary permission routines do not understand MAY_APPEND. */ submask = mask & ~MAY_APPEND; if (inode->i_op && inode->i_op->permission) @@ -1774,8 +1767,6 @@ struct dentry *lookup_create(struct nameidata *nd, int is_dir) if (nd->last_type != LAST_NORM) goto fail; nd->flags &= ~LOOKUP_PARENT; - nd->flags |= LOOKUP_CREATE; - nd->intent.open.flags = O_EXCL; /* * Do the final lookup. diff --git a/trunk/fs/nfs/file.c b/trunk/fs/nfs/file.c index 48e892880d5b..cc2b874ad5a4 100644 --- a/trunk/fs/nfs/file.c +++ b/trunk/fs/nfs/file.c @@ -312,13 +312,7 @@ static void nfs_invalidate_page(struct page *page, unsigned long offset) static int nfs_release_page(struct page *page, gfp_t gfp) { - if (gfp & __GFP_FS) - return !nfs_wb_page(page->mapping->host, page); - else - /* - * Avoid deadlock on nfs_wait_on_request(). - */ - return 0; + return !nfs_wb_page(page->mapping->host, page); } const struct address_space_operations nfs_file_aops = { diff --git a/trunk/fs/nfs/idmap.c b/trunk/fs/nfs/idmap.c index 07a5dd57646e..b81e7ed3c902 100644 --- a/trunk/fs/nfs/idmap.c +++ b/trunk/fs/nfs/idmap.c @@ -130,7 +130,9 @@ nfs_idmap_delete(struct nfs4_client *clp) if (!idmap) return; - rpc_unlink(idmap->idmap_dentry); + dput(idmap->idmap_dentry); + idmap->idmap_dentry = NULL; + rpc_unlink(idmap->idmap_path); clp->cl_idmap = NULL; kfree(idmap); } diff --git a/trunk/fs/nfs/nfs4proc.c b/trunk/fs/nfs/nfs4proc.c index 153898e1331f..e6ee97f19d81 100644 --- a/trunk/fs/nfs/nfs4proc.c +++ b/trunk/fs/nfs/nfs4proc.c @@ -2668,7 +2668,7 @@ static void nfs4_write_cached_acl(struct inode *inode, const char *buf, size_t a nfs4_set_cached_acl(inode, acl); } -static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t buflen) +static inline ssize_t nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t buflen) { struct page *pages[NFS4ACL_MAXPAGES]; struct nfs_getaclargs args = { @@ -2721,19 +2721,6 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu return ret; } -static ssize_t nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t buflen) -{ - struct nfs4_exception exception = { }; - ssize_t ret; - do { - ret = __nfs4_get_acl_uncached(inode, buf, buflen); - if (ret >= 0) - break; - ret = nfs4_handle_exception(NFS_SERVER(inode), ret, &exception); - } while (exception.retry); - return ret; -} - static ssize_t nfs4_proc_get_acl(struct inode *inode, void *buf, size_t buflen) { struct nfs_server *server = NFS_SERVER(inode); @@ -2750,7 +2737,7 @@ static ssize_t nfs4_proc_get_acl(struct inode *inode, void *buf, size_t buflen) return nfs4_get_acl_uncached(inode, buf, buflen); } -static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflen) +static int nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflen) { struct nfs_server *server = NFS_SERVER(inode); struct page *pages[NFS4ACL_MAXPAGES]; @@ -2776,18 +2763,6 @@ static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t bufl return ret; } -static int nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflen) -{ - struct nfs4_exception exception = { }; - int err; - do { - err = nfs4_handle_exception(NFS_SERVER(inode), - __nfs4_proc_set_acl(inode, buf, buflen), - &exception); - } while (exception.retry); - return err; -} - static int nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server) { diff --git a/trunk/fs/nfs/nfs4xdr.c b/trunk/fs/nfs/nfs4xdr.c index 730ec8fb31c6..1750d996f49f 100644 --- a/trunk/fs/nfs/nfs4xdr.c +++ b/trunk/fs/nfs/nfs4xdr.c @@ -3355,7 +3355,7 @@ static int decode_readdir(struct xdr_stream *xdr, struct rpc_rqst *req, struct n struct kvec *iov = rcvbuf->head; unsigned int nr, pglen = rcvbuf->page_len; uint32_t *end, *entry, *p, *kaddr; - uint32_t len, attrlen, xlen; + uint32_t len, attrlen; int hdrlen, recvd, status; status = decode_op_hdr(xdr, OP_READDIR); @@ -3377,10 +3377,10 @@ static int decode_readdir(struct xdr_stream *xdr, struct rpc_rqst *req, struct n BUG_ON(pglen + readdir->pgbase > PAGE_CACHE_SIZE); kaddr = p = (uint32_t *) kmap_atomic(page, KM_USER0); - end = p + ((pglen + readdir->pgbase) >> 2); + end = (uint32_t *) ((char *)p + pglen + readdir->pgbase); entry = p; for (nr = 0; *p++; nr++) { - if (end - p < 3) + if (p + 3 > end) goto short_pkt; dprintk("cookie = %Lu, ", *((unsigned long long *)p)); p += 2; /* cookie */ @@ -3389,19 +3389,18 @@ static int decode_readdir(struct xdr_stream *xdr, struct rpc_rqst *req, struct n printk(KERN_WARNING "NFS: giant filename in readdir (len 0x%x)\n", len); goto err_unmap; } - xlen = XDR_QUADLEN(len); - if (end - p < xlen + 1) - goto short_pkt; dprintk("filename = %*s\n", len, (char *)p); - p += xlen; - len = ntohl(*p++); /* bitmap length */ - if (end - p < len + 1) + p += XDR_QUADLEN(len); + if (p + 1 > end) goto short_pkt; + len = ntohl(*p++); /* bitmap length */ p += len; - attrlen = XDR_QUADLEN(ntohl(*p++)); - if (end - p < attrlen + 2) + if (p + 1 > end) goto short_pkt; + attrlen = XDR_QUADLEN(ntohl(*p++)); p += attrlen; /* attributes */ + if (p + 2 > end) + goto short_pkt; entry = p; } if (!nr && (entry[0] != 0 || entry[1] == 0)) diff --git a/trunk/fs/nfs/read.c b/trunk/fs/nfs/read.c index da9cf11c326f..65c0c5b32351 100644 --- a/trunk/fs/nfs/read.c +++ b/trunk/fs/nfs/read.c @@ -116,17 +116,10 @@ static void nfs_readpage_truncate_uninitialised_page(struct nfs_read_data *data) pages = &data->args.pages[base >> PAGE_CACHE_SHIFT]; base &= ~PAGE_CACHE_MASK; pglen = PAGE_CACHE_SIZE - base; - for (;;) { - if (remainder <= pglen) { - memclear_highpage_flush(*pages, base, remainder); - break; - } + if (pglen < remainder) memclear_highpage_flush(*pages, base, pglen); - pages++; - remainder -= pglen; - pglen = PAGE_CACHE_SIZE; - base = 0; - } + else + memclear_highpage_flush(*pages, base, remainder); } /* @@ -483,8 +476,6 @@ static void nfs_readpage_set_pages_uptodate(struct nfs_read_data *data) unsigned int base = data->args.pgbase; struct page **pages; - if (data->res.eof) - count = data->args.count; if (unlikely(count == 0)) return; pages = &data->args.pages[base >> PAGE_CACHE_SHIFT]; @@ -492,7 +483,11 @@ static void nfs_readpage_set_pages_uptodate(struct nfs_read_data *data) count += base; for (;count >= PAGE_CACHE_SIZE; count -= PAGE_CACHE_SIZE, pages++) SetPageUptodate(*pages); - if (count != 0) + /* + * Was this an eof or a short read? If the latter, don't mark the page + * as uptodate yet. + */ + if (count > 0 && (data->res.eof || data->args.count == data->res.count)) SetPageUptodate(*pages); } @@ -507,8 +502,6 @@ static void nfs_readpage_set_pages_error(struct nfs_read_data *data) count += base; for (;count >= PAGE_CACHE_SIZE; count -= PAGE_CACHE_SIZE, pages++) SetPageError(*pages); - if (count != 0) - SetPageError(*pages); } /* diff --git a/trunk/fs/partitions/sun.c b/trunk/fs/partitions/sun.c index 0a5927c806ca..abe91ca03edf 100644 --- a/trunk/fs/partitions/sun.c +++ b/trunk/fs/partitions/sun.c @@ -74,7 +74,7 @@ int sun_partition(struct parsed_partitions *state, struct block_device *bdev) spc = be16_to_cpu(label->ntrks) * be16_to_cpu(label->nsect); for (i = 0; i < 8; i++, p++) { unsigned long st_sector; - unsigned int num_sectors; + int num_sectors; st_sector = be32_to_cpu(p->start_cylinder) * spc; num_sectors = be32_to_cpu(p->num_sectors); diff --git a/trunk/fs/proc/proc_misc.c b/trunk/fs/proc/proc_misc.c index 942156225447..9f2cfc30f9cf 100644 --- a/trunk/fs/proc/proc_misc.c +++ b/trunk/fs/proc/proc_misc.c @@ -169,7 +169,7 @@ static int meminfo_read_proc(char *page, char **start, off_t off, "Mapped: %8lu kB\n" "Slab: %8lu kB\n" "PageTables: %8lu kB\n" - "NFS_Unstable: %8lu kB\n" + "NFS Unstable: %8lu kB\n" "Bounce: %8lu kB\n" "CommitLimit: %8lu kB\n" "Committed_AS: %8lu kB\n" diff --git a/trunk/fs/reiserfs/xattr.c b/trunk/fs/reiserfs/xattr.c index d935fb9394e3..39fedaa88a0c 100644 --- a/trunk/fs/reiserfs/xattr.c +++ b/trunk/fs/reiserfs/xattr.c @@ -424,7 +424,7 @@ int xattr_readdir(struct file *file, filldir_t filler, void *buf) int res = -ENOTDIR; if (!file->f_op || !file->f_op->readdir) goto out; - mutex_lock_nested(&inode->i_mutex, I_MUTEX_XATTR); + mutex_lock(&inode->i_mutex); // down(&inode->i_zombie); res = -ENOENT; if (!IS_DEADDIR(inode)) { diff --git a/trunk/fs/udf/super.c b/trunk/fs/udf/super.c index fcce1a21a51b..7de172efa084 100644 --- a/trunk/fs/udf/super.c +++ b/trunk/fs/udf/super.c @@ -1659,7 +1659,7 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) iput(inode); goto error_out; } - sb->s_maxbytes = 1<<30; + sb->s_maxbytes = MAX_LFS_FILESIZE; return 0; error_out: diff --git a/trunk/fs/udf/truncate.c b/trunk/fs/udf/truncate.c index 0abd66ce36ea..e1b0e8cfecb4 100644 --- a/trunk/fs/udf/truncate.c +++ b/trunk/fs/udf/truncate.c @@ -239,51 +239,37 @@ void udf_truncate_extents(struct inode * inode) { if (offset) { - /* - * OK, there is not extent covering inode->i_size and - * no extent above inode->i_size => truncate is - * extending the file by 'offset'. - */ - if ((!bh && extoffset == udf_file_entry_alloc_offset(inode)) || - (bh && extoffset == sizeof(struct allocExtDesc))) { - /* File has no extents at all! */ - memset(&eloc, 0x00, sizeof(kernel_lb_addr)); - elen = EXT_NOT_RECORDED_NOT_ALLOCATED | offset; - udf_add_aext(inode, &bloc, &extoffset, eloc, elen, &bh, 1); + extoffset -= adsize; + etype = udf_next_aext(inode, &bloc, &extoffset, &eloc, &elen, &bh, 1); + if (etype == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30)) + { + extoffset -= adsize; + elen = EXT_NOT_RECORDED_NOT_ALLOCATED | (elen + offset); + udf_write_aext(inode, bloc, &extoffset, eloc, elen, bh, 0); } - else { + else if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30)) + { + kernel_lb_addr neloc = { 0, 0 }; extoffset -= adsize; - etype = udf_next_aext(inode, &bloc, &extoffset, &eloc, &elen, &bh, 1); - if (etype == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30)) - { - extoffset -= adsize; - elen = EXT_NOT_RECORDED_NOT_ALLOCATED | (elen + offset); - udf_write_aext(inode, bloc, &extoffset, eloc, elen, bh, 0); - } - else if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30)) + nelen = EXT_NOT_RECORDED_NOT_ALLOCATED | + ((elen + offset + inode->i_sb->s_blocksize - 1) & + ~(inode->i_sb->s_blocksize - 1)); + udf_write_aext(inode, bloc, &extoffset, neloc, nelen, bh, 1); + udf_add_aext(inode, &bloc, &extoffset, eloc, (etype << 30) | elen, &bh, 1); + } + else + { + if (elen & (inode->i_sb->s_blocksize - 1)) { - kernel_lb_addr neloc = { 0, 0 }; extoffset -= adsize; - nelen = EXT_NOT_RECORDED_NOT_ALLOCATED | - ((elen + offset + inode->i_sb->s_blocksize - 1) & + elen = EXT_RECORDED_ALLOCATED | + ((elen + inode->i_sb->s_blocksize - 1) & ~(inode->i_sb->s_blocksize - 1)); - udf_write_aext(inode, bloc, &extoffset, neloc, nelen, bh, 1); - udf_add_aext(inode, &bloc, &extoffset, eloc, (etype << 30) | elen, &bh, 1); - } - else - { - if (elen & (inode->i_sb->s_blocksize - 1)) - { - extoffset -= adsize; - elen = EXT_RECORDED_ALLOCATED | - ((elen + inode->i_sb->s_blocksize - 1) & - ~(inode->i_sb->s_blocksize - 1)); - udf_write_aext(inode, bloc, &extoffset, eloc, elen, bh, 1); - } - memset(&eloc, 0x00, sizeof(kernel_lb_addr)); - elen = EXT_NOT_RECORDED_NOT_ALLOCATED | offset; - udf_add_aext(inode, &bloc, &extoffset, eloc, elen, &bh, 1); + udf_write_aext(inode, bloc, &extoffset, eloc, elen, bh, 1); } + memset(&eloc, 0x00, sizeof(kernel_lb_addr)); + elen = EXT_NOT_RECORDED_NOT_ALLOCATED | offset; + udf_add_aext(inode, &bloc, &extoffset, eloc, elen, &bh, 1); } } } diff --git a/trunk/fs/ufs/inode.c b/trunk/fs/ufs/inode.c index 30c6e8a9446c..e7c8615beb65 100644 --- a/trunk/fs/ufs/inode.c +++ b/trunk/fs/ufs/inode.c @@ -169,20 +169,18 @@ static void ufs_clear_frag(struct inode *inode, struct buffer_head *bh) static struct buffer_head * ufs_clear_frags(struct inode *inode, sector_t beg, - unsigned int n, sector_t want) + unsigned int n) { - struct buffer_head *res = NULL, *bh; + struct buffer_head *res, *bh; sector_t end = beg + n; - for (; beg < end; ++beg) { + res = sb_getblk(inode->i_sb, beg); + ufs_clear_frag(inode, res); + for (++beg; beg < end; ++beg) { bh = sb_getblk(inode->i_sb, beg); ufs_clear_frag(inode, bh); - if (want != beg) - brelse(bh); - else - res = bh; + brelse(bh); } - BUG_ON(!res); return res; } @@ -267,9 +265,7 @@ ufs_inode_getfrag(struct inode *inode, unsigned int fragment, lastfrag = ufsi->i_lastfrag; } - tmp = fs32_to_cpu(sb, ufsi->i_u1.i_data[lastblock]); - if (tmp) - goal = tmp + uspi->s_fpb; + goal = fs32_to_cpu(sb, ufsi->i_u1.i_data[lastblock]) + uspi->s_fpb; tmp = ufs_new_fragments (inode, p, fragment - blockoff, goal, required + blockoff, err, locked_page); @@ -281,15 +277,13 @@ ufs_inode_getfrag(struct inode *inode, unsigned int fragment, tmp = ufs_new_fragments(inode, p, fragment - (blockoff - lastblockoff), fs32_to_cpu(sb, *p), required + (blockoff - lastblockoff), err, locked_page); - } else /* (lastblock > block) */ { + } /* * We will allocate new block before last allocated block */ - if (block) { - tmp = fs32_to_cpu(sb, ufsi->i_u1.i_data[block-1]); - if (tmp) - goal = tmp + uspi->s_fpb; - } + else /* (lastblock > block) */ { + if (lastblock && (tmp = fs32_to_cpu(sb, ufsi->i_u1.i_data[lastblock-1]))) + goal = tmp + uspi->s_fpb; tmp = ufs_new_fragments(inode, p, fragment - blockoff, goal, uspi->s_fpb, err, locked_page); } @@ -302,7 +296,7 @@ ufs_inode_getfrag(struct inode *inode, unsigned int fragment, } if (!phys) { - result = ufs_clear_frags(inode, tmp, required, tmp + blockoff); + result = ufs_clear_frags(inode, tmp + blockoff, required); } else { *phys = tmp + blockoff; result = NULL; @@ -389,7 +383,7 @@ ufs_inode_getblock(struct inode *inode, struct buffer_head *bh, } } - if (block && (tmp = fs32_to_cpu(sb, ((__fs32*)bh->b_data)[block-1]))) + if (block && (tmp = fs32_to_cpu(sb, ((__fs32*)bh->b_data)[block-1]) + uspi->s_fpb)) goal = tmp + uspi->s_fpb; else goal = bh->b_blocknr + uspi->s_fpb; @@ -403,8 +397,7 @@ ufs_inode_getblock(struct inode *inode, struct buffer_head *bh, if (!phys) { - result = ufs_clear_frags(inode, tmp, uspi->s_fpb, - tmp + blockoff); + result = ufs_clear_frags(inode, tmp + blockoff, uspi->s_fpb); } else { *phys = tmp + blockoff; *new = 1; diff --git a/trunk/fs/ufs/truncate.c b/trunk/fs/ufs/truncate.c index ea11d04c41a0..c9b55872079b 100644 --- a/trunk/fs/ufs/truncate.c +++ b/trunk/fs/ufs/truncate.c @@ -375,15 +375,17 @@ static int ufs_alloc_lastblock(struct inode *inode) int err = 0; struct address_space *mapping = inode->i_mapping; struct ufs_sb_private_info *uspi = UFS_SB(inode->i_sb)->s_uspi; + struct ufs_inode_info *ufsi = UFS_I(inode); unsigned lastfrag, i, end; struct page *lastpage; struct buffer_head *bh; lastfrag = (i_size_read(inode) + uspi->s_fsize - 1) >> uspi->s_fshift; - if (!lastfrag) + if (!lastfrag) { + ufsi->i_lastfrag = 0; goto out; - + } lastfrag--; lastpage = ufs_get_locked_page(mapping, lastfrag >> @@ -398,25 +400,25 @@ static int ufs_alloc_lastblock(struct inode *inode) for (i = 0; i < end; ++i) bh = bh->b_this_page; - - err = ufs_getfrag_block(inode, lastfrag, bh, 1); - - if (unlikely(err)) - goto out_unlock; - - if (buffer_new(bh)) { - clear_buffer_new(bh); - unmap_underlying_metadata(bh->b_bdev, - bh->b_blocknr); - /* - * we do not zeroize fragment, because of - * if it maped to hole, it already contains zeroes - */ - set_buffer_uptodate(bh); - mark_buffer_dirty(bh); - set_page_dirty(lastpage); + if (!buffer_mapped(bh)) { + err = ufs_getfrag_block(inode, lastfrag, bh, 1); + + if (unlikely(err)) + goto out_unlock; + + if (buffer_new(bh)) { + clear_buffer_new(bh); + unmap_underlying_metadata(bh->b_bdev, + bh->b_blocknr); + /* + * we do not zeroize fragment, because of + * if it maped to hole, it already contains zeroes + */ + set_buffer_uptodate(bh); + mark_buffer_dirty(bh); + set_page_dirty(lastpage); + } } - out_unlock: ufs_put_locked_page(lastpage); out: @@ -438,11 +440,23 @@ int ufs_truncate(struct inode *inode, loff_t old_i_size) if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) return -EPERM; - err = ufs_alloc_lastblock(inode); + if (inode->i_size > old_i_size) { + /* + * if we expand file we should care about + * allocation of block for last byte first of all + */ + err = ufs_alloc_lastblock(inode); - if (err) { - i_size_write(inode, old_i_size); - goto out; + if (err) { + i_size_write(inode, old_i_size); + goto out; + } + /* + * go away, because of we expand file, and we do not + * need free blocks, and zeroizes page + */ + lock_kernel(); + goto almost_end; } block_truncate_page(inode->i_mapping, inode->i_size, ufs_getfrag_block); @@ -463,8 +477,21 @@ int ufs_truncate(struct inode *inode, loff_t old_i_size) yield(); } + if (inode->i_size < old_i_size) { + /* + * now we should have enough space + * to allocate block for last byte + */ + err = ufs_alloc_lastblock(inode); + if (err) + /* + * looks like all the same - we have no space, + * but we truncate file already + */ + inode->i_size = (ufsi->i_lastfrag - 1) * uspi->s_fsize; + } +almost_end: inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC; - ufsi->i_lastfrag = DIRECT_FRAGMENT; unlock_kernel(); mark_inode_dirty(inode); out: diff --git a/trunk/fs/xfs/xfs_bmap.c b/trunk/fs/xfs/xfs_bmap.c index bf46fae303af..3a6137539064 100644 --- a/trunk/fs/xfs/xfs_bmap.c +++ b/trunk/fs/xfs/xfs_bmap.c @@ -4993,7 +4993,7 @@ xfs_bmapi( bma.firstblock = *firstblock; bma.alen = alen; bma.off = aoff; - bma.conv = !!(flags & XFS_BMAPI_CONVERT); + bma.conv = (flags & XFS_BMAPI_CONVERT); bma.wasdel = wasdelay; bma.minlen = minlen; bma.low = flist->xbf_low; diff --git a/trunk/include/asm-arm/arch-pxa/ssp.h b/trunk/include/asm-arm/arch-pxa/ssp.h index ea200551a75f..949878c0d908 100644 --- a/trunk/include/asm-arm/arch-pxa/ssp.h +++ b/trunk/include/asm-arm/arch-pxa/ssp.h @@ -40,8 +40,8 @@ struct ssp_dev { }; int ssp_write_word(struct ssp_dev *dev, u32 data); -int ssp_read_word(struct ssp_dev *dev, u32 *data); -int ssp_flush(struct ssp_dev *dev); +int ssp_read_word(struct ssp_dev *dev); +void ssp_flush(struct ssp_dev *dev); void ssp_enable(struct ssp_dev *dev); void ssp_disable(struct ssp_dev *dev); void ssp_save_state(struct ssp_dev *dev, struct ssp_state *ssp); diff --git a/trunk/include/asm-arm/arch-s3c2410/dma.h b/trunk/include/asm-arm/arch-s3c2410/dma.h index 3661e465b0a5..72964f9b8414 100644 --- a/trunk/include/asm-arm/arch-s3c2410/dma.h +++ b/trunk/include/asm-arm/arch-s3c2410/dma.h @@ -1,13 +1,18 @@ -/* linux/include/asm-arm/arch-s3c2410/dma.h +/* linux/include/asm-arm/arch-bast/dma.h * - * Copyright (C) 2003,2004,2006 Simtec Electronics + * Copyright (C) 2003,2004 Simtec Electronics * Ben Dooks * - * Samsung S3C241XX DMA support + * Samsung S3C2410X DMA support * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. + * + * Changelog: + * ??-May-2003 BJD Created file + * ??-Jun-2003 BJD Added more dma functionality to go with arch + * 10-Nov-2004 BJD Added sys_device support */ #ifndef __ASM_ARCH_DMA_H @@ -16,26 +21,28 @@ #include #include "hardware.h" + /* * This is the maximum DMA address(physical address) that can be DMAd to. * */ -#define MAX_DMA_ADDRESS 0x40000000 +#define MAX_DMA_ADDRESS 0x20000000 #define MAX_DMA_TRANSFER_SIZE 0x100000 /* Data Unit is half word */ + /* we have 4 dma channels */ #define S3C2410_DMA_CHANNELS (4) /* types */ -enum s3c2410_dma_state { +typedef enum { S3C2410_DMA_IDLE, S3C2410_DMA_RUNNING, S3C2410_DMA_PAUSED -}; +} s3c2410_dma_state_t; -/* enum s3c2410_dma_loadst +/* s3c2410_dma_loadst_t * * This represents the state of the DMA engine, wrt to the loaded / running * transfers. Since we don't have any way of knowing exactly the state of @@ -63,40 +70,44 @@ enum s3c2410_dma_state { * currently running. */ -enum s3c2410_dma_loadst { +typedef enum { S3C2410_DMALOAD_NONE, S3C2410_DMALOAD_1LOADED, S3C2410_DMALOAD_1RUNNING, S3C2410_DMALOAD_1LOADED_1RUNNING, -}; +} s3c2410_dma_loadst_t; -enum s3c2410_dma_buffresult { +typedef enum { S3C2410_RES_OK, S3C2410_RES_ERR, S3C2410_RES_ABORT -}; +} s3c2410_dma_buffresult_t; -enum s3c2410_dmasrc { - S3C2410_DMASRC_HW, /* source is memory */ - S3C2410_DMASRC_MEM /* source is hardware */ + +typedef enum s3c2410_dmasrc_e s3c2410_dmasrc_t; + +enum s3c2410_dmasrc_e { + S3C2410_DMASRC_HW, /* source is memory */ + S3C2410_DMASRC_MEM /* source is hardware */ }; -/* enum s3c2410_chan_op +/* enum s3c2410_chan_op_e * * operation codes passed to the DMA code by the user, and also used * to inform the current channel owner of any changes to the system state */ -enum s3c2410_chan_op { +enum s3c2410_chan_op_e { S3C2410_DMAOP_START, S3C2410_DMAOP_STOP, S3C2410_DMAOP_PAUSE, S3C2410_DMAOP_RESUME, S3C2410_DMAOP_FLUSH, - S3C2410_DMAOP_TIMEOUT, /* internal signal to handler */ - S3C2410_DMAOP_STARTED, /* indicate channel started */ + S3C2410_DMAOP_TIMEOUT, /* internal signal to handler */ }; +typedef enum s3c2410_chan_op_e s3c2410_chan_op_t; + /* flags */ #define S3C2410_DMAF_SLOW (1<<0) /* slow, so don't worry about @@ -105,100 +116,104 @@ enum s3c2410_chan_op { /* dma buffer */ +typedef struct s3c2410_dma_buf_s s3c2410_dma_buf_t; + struct s3c2410_dma_client { char *name; }; +typedef struct s3c2410_dma_client s3c2410_dma_client_t; + /* s3c2410_dma_buf_s * * internally used buffer structure to describe a queued or running * buffer. */ -struct s3c2410_dma_buf; -struct s3c2410_dma_buf { - struct s3c2410_dma_buf *next; - int magic; /* magic */ - int size; /* buffer size in bytes */ - dma_addr_t data; /* start of DMA data */ - dma_addr_t ptr; /* where the DMA got to [1] */ - void *id; /* client's id */ +struct s3c2410_dma_buf_s { + s3c2410_dma_buf_t *next; + int magic; /* magic */ + int size; /* buffer size in bytes */ + dma_addr_t data; /* start of DMA data */ + dma_addr_t ptr; /* where the DMA got to [1] */ + void *id; /* client's id */ }; /* [1] is this updated for both recv/send modes? */ -struct s3c2410_dma_chan; +typedef struct s3c2410_dma_chan_s s3c2410_dma_chan_t; /* s3c2410_dma_cbfn_t * * buffer callback routine type */ -typedef void (*s3c2410_dma_cbfn_t)(struct s3c2410_dma_chan *, - void *buf, int size, - enum s3c2410_dma_buffresult result); +typedef void (*s3c2410_dma_cbfn_t)(s3c2410_dma_chan_t *, void *buf, int size, + s3c2410_dma_buffresult_t result); -typedef int (*s3c2410_dma_opfn_t)(struct s3c2410_dma_chan *, - enum s3c2410_chan_op ); +typedef int (*s3c2410_dma_opfn_t)(s3c2410_dma_chan_t *, + s3c2410_chan_op_t ); -struct s3c2410_dma_stats { - unsigned long loads; - unsigned long timeout_longest; - unsigned long timeout_shortest; - unsigned long timeout_avg; - unsigned long timeout_failed; +struct s3c2410_dma_stats_s { + unsigned long loads; + unsigned long timeout_longest; + unsigned long timeout_shortest; + unsigned long timeout_avg; + unsigned long timeout_failed; }; -/* struct s3c2410_dma_chan +typedef struct s3c2410_dma_stats_s s3c2410_dma_stats_t; + +/* struct s3c2410_dma_chan_s * * full state information for each DMA channel */ -struct s3c2410_dma_chan { +struct s3c2410_dma_chan_s { /* channel state flags and information */ - unsigned char number; /* number of this dma channel */ - unsigned char in_use; /* channel allocated */ - unsigned char irq_claimed; /* irq claimed for channel */ - unsigned char irq_enabled; /* irq enabled for channel */ - unsigned char xfer_unit; /* size of an transfer */ + unsigned char number; /* number of this dma channel */ + unsigned char in_use; /* channel allocated */ + unsigned char irq_claimed; /* irq claimed for channel */ + unsigned char irq_enabled; /* irq enabled for channel */ + unsigned char xfer_unit; /* size of an transfer */ /* channel state */ - enum s3c2410_dma_state state; - enum s3c2410_dma_loadst load_state; - struct s3c2410_dma_client *client; + s3c2410_dma_state_t state; + s3c2410_dma_loadst_t load_state; + s3c2410_dma_client_t *client; /* channel configuration */ - enum s3c2410_dmasrc source; - unsigned long dev_addr; - unsigned long load_timeout; - unsigned int flags; /* channel flags */ + s3c2410_dmasrc_t source; + unsigned long dev_addr; + unsigned long load_timeout; + unsigned int flags; /* channel flags */ /* channel's hardware position and configuration */ - void __iomem *regs; /* channels registers */ - void __iomem *addr_reg; /* data address register */ - unsigned int irq; /* channel irq */ - unsigned long dcon; /* default value of DCON */ + void __iomem *regs; /* channels registers */ + void __iomem *addr_reg; /* data address register */ + unsigned int irq; /* channel irq */ + unsigned long dcon; /* default value of DCON */ /* driver handles */ - s3c2410_dma_cbfn_t callback_fn; /* buffer done callback */ - s3c2410_dma_opfn_t op_fn; /* channel op callback */ + s3c2410_dma_cbfn_t callback_fn; /* buffer done callback */ + s3c2410_dma_opfn_t op_fn; /* channel operation callback */ /* stats gathering */ - struct s3c2410_dma_stats *stats; - struct s3c2410_dma_stats stats_store; + s3c2410_dma_stats_t *stats; + s3c2410_dma_stats_t stats_store; /* buffer list and information */ - struct s3c2410_dma_buf *curr; /* current dma buffer */ - struct s3c2410_dma_buf *next; /* next buffer to load */ - struct s3c2410_dma_buf *end; /* end of queue */ + s3c2410_dma_buf_t *curr; /* current dma buffer */ + s3c2410_dma_buf_t *next; /* next buffer to load */ + s3c2410_dma_buf_t *end; /* end of queue */ /* system device */ struct sys_device dev; }; /* the currently allocated channel information */ -extern struct s3c2410_dma_chan s3c2410_chans[]; +extern s3c2410_dma_chan_t s3c2410_chans[]; /* note, we don't really use dma_device_t at the moment */ typedef unsigned long dma_device_t; @@ -211,7 +226,7 @@ typedef unsigned long dma_device_t; */ extern int s3c2410_dma_request(dmach_t channel, - struct s3c2410_dma_client *, void *dev); + s3c2410_dma_client_t *, void *dev); /* s3c2410_dma_ctrl @@ -219,7 +234,7 @@ extern int s3c2410_dma_request(dmach_t channel, * change the state of the dma channel */ -extern int s3c2410_dma_ctrl(dmach_t channel, enum s3c2410_chan_op op); +extern int s3c2410_dma_ctrl(dmach_t channel, s3c2410_chan_op_t op); /* s3c2410_dma_setflags * @@ -234,7 +249,7 @@ extern int s3c2410_dma_setflags(dmach_t channel, * free the dma channel (will also abort any outstanding operations) */ -extern int s3c2410_dma_free(dmach_t channel, struct s3c2410_dma_client *); +extern int s3c2410_dma_free(dmach_t channel, s3c2410_dma_client_t *); /* s3c2410_dma_enqueue * @@ -258,7 +273,7 @@ extern int s3c2410_dma_config(dmach_t channel, int xferunit, int dcon); * configure the device we're talking to */ -extern int s3c2410_dma_devconfig(int channel, enum s3c2410_dmasrc source, +extern int s3c2410_dma_devconfig(int channel, s3c2410_dmasrc_t source, int hwcfg, unsigned long devaddr); /* s3c2410_dma_getposition diff --git a/trunk/include/asm-arm/arch-s3c2410/regs-rtc.h b/trunk/include/asm-arm/arch-s3c2410/regs-rtc.h index 0fbec07bb6b8..228983f89bc8 100644 --- a/trunk/include/asm-arm/arch-s3c2410/regs-rtc.h +++ b/trunk/include/asm-arm/arch-s3c2410/regs-rtc.h @@ -18,7 +18,7 @@ #ifndef __ASM_ARCH_REGS_RTC_H #define __ASM_ARCH_REGS_RTC_H __FILE__ -#define S3C2410_RTCREG(x) (x) +#define S3C2410_RTCREG(x) ((x) + S3C24XX_VA_RTC) #define S3C2410_RTCCON S3C2410_RTCREG(0x40) #define S3C2410_RTCCON_RTCEN (1<<0) diff --git a/trunk/include/asm-arm/cacheflush.h b/trunk/include/asm-arm/cacheflush.h index e4a2569c636c..fe0c744e0266 100644 --- a/trunk/include/asm-arm/cacheflush.h +++ b/trunk/include/asm-arm/cacheflush.h @@ -247,12 +247,14 @@ extern void dmac_flush_range(unsigned long, unsigned long); */ #define copy_to_user_page(vma, page, vaddr, dst, src, len) \ do { \ + flush_cache_page(vma, vaddr, page_to_pfn(page));\ memcpy(dst, src, len); \ - flush_ptrace_access(vma, page, vaddr, dst, len, 1);\ + flush_dcache_page(page); \ } while (0) #define copy_from_user_page(vma, page, vaddr, dst, src, len) \ do { \ + flush_cache_page(vma, vaddr, page_to_pfn(page));\ memcpy(dst, src, len); \ } while (0) @@ -283,24 +285,10 @@ flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr, unsigned l __cpuc_flush_user_range(addr, addr + PAGE_SIZE, vma->vm_flags); } } - -static inline void -flush_ptrace_access(struct vm_area_struct *vma, struct page *page, - unsigned long uaddr, void *kaddr, - unsigned long len, int write) -{ - if (cpu_isset(smp_processor_id(), vma->vm_mm->cpu_vm_mask)) { - unsigned long addr = (unsigned long)kaddr; - __cpuc_coherent_kern_range(addr, addr + len); - } -} #else extern void flush_cache_mm(struct mm_struct *mm); extern void flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end); extern void flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr, unsigned long pfn); -extern void flush_ptrace_access(struct vm_area_struct *vma, struct page *page, - unsigned long uaddr, void *kaddr, - unsigned long len, int write); #endif /* diff --git a/trunk/include/asm-arm/hardware/ssp.h b/trunk/include/asm-arm/hardware/ssp.h index 3b42e181997c..28aa11b769cd 100644 --- a/trunk/include/asm-arm/hardware/ssp.h +++ b/trunk/include/asm-arm/hardware/ssp.h @@ -16,8 +16,8 @@ struct ssp_state { }; int ssp_write_word(u16 data); -int ssp_read_word(u16 *data); -int ssp_flush(void); +int ssp_read_word(void); +void ssp_flush(void); void ssp_enable(void); void ssp_disable(void); void ssp_save_state(struct ssp_state *ssp); diff --git a/trunk/include/asm-arm/io.h b/trunk/include/asm-arm/io.h index bf7b9dea30f1..b3479fc1cc8f 100644 --- a/trunk/include/asm-arm/io.h +++ b/trunk/include/asm-arm/io.h @@ -291,12 +291,5 @@ extern void pci_iounmap(struct pci_dev *dev, void __iomem *addr); */ #define xlate_dev_kmem_ptr(p) p -/* - * Register ISA memory and port locations for glibc iopl/inb/outb - * emulation. - */ -extern void register_isa_ports(unsigned int mmio, unsigned int io, - unsigned int io_shift); - #endif /* __KERNEL__ */ #endif /* __ASM_ARM_IO_H */ diff --git a/trunk/include/asm-arm/procinfo.h b/trunk/include/asm-arm/procinfo.h index 91a31adfa8a8..edb7b6502fcf 100644 --- a/trunk/include/asm-arm/procinfo.h +++ b/trunk/include/asm-arm/procinfo.h @@ -55,6 +55,5 @@ extern unsigned int elf_hwcap; #define HWCAP_VFP 64 #define HWCAP_EDSP 128 #define HWCAP_JAVA 256 -#define HWCAP_IWMMXT 512 #endif diff --git a/trunk/include/asm-arm/spinlock.h b/trunk/include/asm-arm/spinlock.h index e2f1d75171df..406ca97a8ab2 100644 --- a/trunk/include/asm-arm/spinlock.h +++ b/trunk/include/asm-arm/spinlock.h @@ -199,21 +199,7 @@ static inline void __raw_read_unlock(raw_rwlock_t *rw) : "cc"); } -static inline int __raw_read_trylock(raw_rwlock_t *rw) -{ - unsigned long tmp tmp2 = 1; - - __asm__ __volatile__( -"1: ldrex %0, [%2]\n" -" adds %0, %0, #1\n" -" strexpl %1, %0, [%2]\n" - : "=&r" (tmp), "+r" (tmp2) - : "r" (&rw->lock) - : "cc"); - - smp_mb(); - return tmp2 == 0; -} +#define __raw_read_trylock(lock) generic__raw_read_trylock(lock) /* read_can_lock - would read_trylock() succeed? */ #define __raw_read_can_lock(x) ((x)->lock < 0x80000000) diff --git a/trunk/include/asm-i386/alternative.h b/trunk/include/asm-i386/alternative.h index b01a7ec409ce..96adbabec740 100644 --- a/trunk/include/asm-i386/alternative.h +++ b/trunk/include/asm-i386/alternative.h @@ -88,6 +88,9 @@ static inline void alternatives_smp_switch(int smp) {} /* * Alternative inline assembly for SMP. * + * alternative_smp() takes two versions (SMP first, UP second) and is + * for more complex stuff such as spinlocks. + * * The LOCK_PREFIX macro defined here replaces the LOCK and * LOCK_PREFIX macros used everywhere in the source tree. * @@ -107,6 +110,21 @@ static inline void alternatives_smp_switch(int smp) {} */ #ifdef CONFIG_SMP +#define alternative_smp(smpinstr, upinstr, args...) \ + asm volatile ("661:\n\t" smpinstr "\n662:\n" \ + ".section .smp_altinstructions,\"a\"\n" \ + " .align 4\n" \ + " .long 661b\n" /* label */ \ + " .long 663f\n" /* new instruction */ \ + " .byte 0x68\n" /* X86_FEATURE_UP */ \ + " .byte 662b-661b\n" /* sourcelen */ \ + " .byte 664f-663f\n" /* replacementlen */ \ + ".previous\n" \ + ".section .smp_altinstr_replacement,\"awx\"\n" \ + "663:\n\t" upinstr "\n" /* replacement */ \ + "664:\n\t.fill 662b-661b,1,0x42\n" /* space for original */ \ + ".previous" : args) + #define LOCK_PREFIX \ ".section .smp_locks,\"a\"\n" \ " .align 4\n" \ @@ -115,6 +133,8 @@ static inline void alternatives_smp_switch(int smp) {} "661:\n\tlock; " #else /* ! CONFIG_SMP */ +#define alternative_smp(smpinstr, upinstr, args...) \ + asm volatile (upinstr : args) #define LOCK_PREFIX "" #endif diff --git a/trunk/include/asm-i386/mach-default/mach_mpspec.h b/trunk/include/asm-i386/mach-default/mach_mpspec.h index 51c9a9775932..6b5dadcf1d0e 100644 --- a/trunk/include/asm-i386/mach-default/mach_mpspec.h +++ b/trunk/include/asm-i386/mach-default/mach_mpspec.h @@ -3,10 +3,6 @@ #define MAX_IRQ_SOURCES 256 -#if CONFIG_BASE_SMALL == 0 -#define MAX_MP_BUSSES 256 -#else #define MAX_MP_BUSSES 32 -#endif #endif /* __ASM_MACH_MPSPEC_H */ diff --git a/trunk/include/asm-i386/mmzone.h b/trunk/include/asm-i386/mmzone.h index 22cb07cc8f32..e33e9f9e4c66 100644 --- a/trunk/include/asm-i386/mmzone.h +++ b/trunk/include/asm-i386/mmzone.h @@ -14,7 +14,7 @@ extern struct pglist_data *node_data[]; #ifdef CONFIG_X86_NUMAQ #include -#elif defined(CONFIG_ACPI_SRAT)/* summit or generic arch */ +#else /* summit or generic arch */ #include #endif diff --git a/trunk/include/asm-i386/rwlock.h b/trunk/include/asm-i386/rwlock.h index 87c069ccba08..96b0bef2ea56 100644 --- a/trunk/include/asm-i386/rwlock.h +++ b/trunk/include/asm-i386/rwlock.h @@ -21,21 +21,23 @@ #define RW_LOCK_BIAS_STR "0x01000000" #define __build_read_lock_ptr(rw, helper) \ - asm volatile(LOCK_PREFIX " subl $1,(%0)\n\t" \ + alternative_smp("lock; subl $1,(%0)\n\t" \ "jns 1f\n" \ "call " helper "\n\t" \ - "1:\n" \ - ::"a" (rw) : "memory") + "1:\n", \ + "subl $1,(%0)\n\t", \ + :"a" (rw) : "memory") #define __build_read_lock_const(rw, helper) \ - asm volatile(LOCK_PREFIX " subl $1,%0\n\t" \ + alternative_smp("lock; subl $1,%0\n\t" \ "jns 1f\n" \ "pushl %%eax\n\t" \ "leal %0,%%eax\n\t" \ "call " helper "\n\t" \ "popl %%eax\n\t" \ - "1:\n" \ - :"+m" (*(volatile int *)rw) : : "memory") + "1:\n", \ + "subl $1,%0\n\t", \ + "+m" (*(volatile int *)rw) : : "memory") #define __build_read_lock(rw, helper) do { \ if (__builtin_constant_p(rw)) \ @@ -45,21 +47,23 @@ } while (0) #define __build_write_lock_ptr(rw, helper) \ - asm volatile(LOCK_PREFIX " subl $" RW_LOCK_BIAS_STR ",(%0)\n\t" \ + alternative_smp("lock; subl $" RW_LOCK_BIAS_STR ",(%0)\n\t" \ "jz 1f\n" \ "call " helper "\n\t" \ - "1:\n" \ - ::"a" (rw) : "memory") + "1:\n", \ + "subl $" RW_LOCK_BIAS_STR ",(%0)\n\t", \ + :"a" (rw) : "memory") #define __build_write_lock_const(rw, helper) \ - asm volatile(LOCK_PREFIX " subl $" RW_LOCK_BIAS_STR ",%0\n\t" \ + alternative_smp("lock; subl $" RW_LOCK_BIAS_STR ",%0\n\t" \ "jz 1f\n" \ "pushl %%eax\n\t" \ "leal %0,%%eax\n\t" \ "call " helper "\n\t" \ "popl %%eax\n\t" \ - "1:\n" \ - :"+m" (*(volatile int *)rw) : : "memory") + "1:\n", \ + "subl $" RW_LOCK_BIAS_STR ",%0\n\t", \ + "+m" (*(volatile int *)rw) : : "memory") #define __build_write_lock(rw, helper) do { \ if (__builtin_constant_p(rw)) \ diff --git a/trunk/include/asm-i386/spinlock.h b/trunk/include/asm-i386/spinlock.h index d1020363c41a..d816c62a7a1d 100644 --- a/trunk/include/asm-i386/spinlock.h +++ b/trunk/include/asm-i386/spinlock.h @@ -22,7 +22,7 @@ #define __raw_spin_lock_string \ "\n1:\t" \ - LOCK_PREFIX " ; decb %0\n\t" \ + "lock ; decb %0\n\t" \ "jns 3f\n" \ "2:\t" \ "rep;nop\n\t" \ @@ -38,7 +38,7 @@ */ #define __raw_spin_lock_string_flags \ "\n1:\t" \ - LOCK_PREFIX " ; decb %0\n\t" \ + "lock ; decb %0\n\t" \ "jns 5f\n" \ "2:\t" \ "testl $0x200, %1\n\t" \ @@ -57,9 +57,15 @@ "jmp 4b\n" \ "5:\n\t" +#define __raw_spin_lock_string_up \ + "\n\tdecb %0" + static inline void __raw_spin_lock(raw_spinlock_t *lock) { - asm(__raw_spin_lock_string : "+m" (lock->slock) : : "memory"); + alternative_smp( + __raw_spin_lock_string, + __raw_spin_lock_string_up, + "+m" (lock->slock) : : "memory"); } /* @@ -70,7 +76,10 @@ static inline void __raw_spin_lock(raw_spinlock_t *lock) #ifndef CONFIG_PROVE_LOCKING static inline void __raw_spin_lock_flags(raw_spinlock_t *lock, unsigned long flags) { - asm(__raw_spin_lock_string_flags : "+m" (lock->slock) : "r" (flags) : "memory"); + alternative_smp( + __raw_spin_lock_string_flags, + __raw_spin_lock_string_up, + "+m" (lock->slock) : "r" (flags) : "memory"); } #endif diff --git a/trunk/include/asm-i386/unistd.h b/trunk/include/asm-i386/unistd.h index d983b74e4d9f..fc1c8ddae149 100644 --- a/trunk/include/asm-i386/unistd.h +++ b/trunk/include/asm-i386/unistd.h @@ -324,6 +324,8 @@ #define __NR_vmsplice 316 #define __NR_move_pages 317 +#ifdef __KERNEL__ + #define NR_syscalls 318 /* @@ -423,8 +425,6 @@ __asm__ volatile ("push %%ebp ; push %%ebx ; movl 4(%2),%%ebp ; " \ __syscall_return(type,__res); \ } -#ifdef __KERNEL__ - #define __ARCH_WANT_IPC_PARSE_VERSION #define __ARCH_WANT_OLD_READDIR #define __ARCH_WANT_OLD_STAT diff --git a/trunk/include/asm-i386/unwind.h b/trunk/include/asm-i386/unwind.h index 4c1a0b968569..69f0f1df6722 100644 --- a/trunk/include/asm-i386/unwind.h +++ b/trunk/include/asm-i386/unwind.h @@ -87,7 +87,6 @@ static inline int arch_unw_user_mode(const struct unwind_frame_info *info) #else #define UNW_PC(frame) ((void)(frame), 0) -#define UNW_SP(frame) ((void)(frame), 0) static inline int arch_unw_user_mode(const void *info) { diff --git a/trunk/include/asm-ia64/sn/sn_sal.h b/trunk/include/asm-ia64/sn/sn_sal.h index ba826b3f75bb..bd4452bda357 100644 --- a/trunk/include/asm-ia64/sn/sn_sal.h +++ b/trunk/include/asm-ia64/sn/sn_sal.h @@ -706,9 +706,12 @@ static inline int sn_change_memprotect(u64 paddr, u64 len, u64 perms, u64 *nasid_array) { struct ia64_sal_retval ret_stuff; + unsigned long irq_flags; + local_irq_save(irq_flags); ia64_sal_oemcall_nolock(&ret_stuff, SN_SAL_MEMPROTECT, paddr, len, (u64)nasid_array, perms, 0, 0, 0); + local_irq_restore(irq_flags); return ret_stuff.status; } #define SN_MEMPROT_ACCESS_CLASS_0 0x14a080 @@ -1140,9 +1143,12 @@ static inline int sn_inject_error(u64 paddr, u64 *data, u64 *ecc) { struct ia64_sal_retval ret_stuff; + unsigned long irq_flags; + local_irq_save(irq_flags); ia64_sal_oemcall_nolock(&ret_stuff, SN_SAL_INJECT_ERROR, paddr, (u64)data, (u64)ecc, 0, 0, 0, 0); + local_irq_restore(irq_flags); return ret_stuff.status; } diff --git a/trunk/include/asm-ia64/sn/xp.h b/trunk/include/asm-ia64/sn/xp.h index 6f807e0193b7..9bd2f9bf329b 100644 --- a/trunk/include/asm-ia64/sn/xp.h +++ b/trunk/include/asm-ia64/sn/xp.h @@ -60,37 +60,23 @@ * the bte_copy() once in the hope that the failure was due to a temporary * aberration (i.e., the link going down temporarily). * - * src - physical address of the source of the transfer. - * vdst - virtual address of the destination of the transfer. - * len - number of bytes to transfer from source to destination. - * mode - see bte_copy() for definition. - * notification - see bte_copy() for definition. + * See bte_copy for definition of the input parameters. * * Note: xp_bte_copy() should never be called while holding a spinlock. */ static inline bte_result_t -xp_bte_copy(u64 src, u64 vdst, u64 len, u64 mode, void *notification) +xp_bte_copy(u64 src, u64 dest, u64 len, u64 mode, void *notification) { bte_result_t ret; - u64 pdst = ia64_tpa(vdst); - /* - * Ensure that the physically mapped memory is contiguous. - * - * We do this by ensuring that the memory is from region 7 only. - * If the need should arise to use memory from one of the other - * regions, then modify the BUG_ON() statement to ensure that the - * memory from that region is always physically contiguous. - */ - BUG_ON(REGION_NUMBER(vdst) != RGN_KERNEL); + ret = bte_copy(src, dest, len, mode, notification); - ret = bte_copy(src, pdst, len, mode, notification); if (ret != BTE_SUCCESS) { if (!in_interrupt()) { cond_resched(); } - ret = bte_copy(src, pdst, len, mode, notification); + ret = bte_copy(src, dest, len, mode, notification); } return ret; diff --git a/trunk/include/asm-ia64/sn/xpc.h b/trunk/include/asm-ia64/sn/xpc.h index 35e1386f37ab..b72af597878d 100644 --- a/trunk/include/asm-ia64/sn/xpc.h +++ b/trunk/include/asm-ia64/sn/xpc.h @@ -683,9 +683,7 @@ extern struct xpc_vars *xpc_vars; extern struct xpc_rsvd_page *xpc_rsvd_page; extern struct xpc_vars_part *xpc_vars_part; extern struct xpc_partition xpc_partitions[XP_MAX_PARTITIONS + 1]; -extern char *xpc_remote_copy_buffer; -extern void *xpc_remote_copy_buffer_base; -extern void *xpc_kmalloc_cacheline_aligned(size_t, gfp_t, void **); +extern char xpc_remote_copy_buffer[]; extern struct xpc_rsvd_page *xpc_rsvd_page_init(void); extern void xpc_allow_IPI_ops(void); extern void xpc_restrict_IPI_ops(void); diff --git a/trunk/include/asm-powerpc/io.h b/trunk/include/asm-powerpc/io.h index 36c4c34bf565..a9496f34b048 100644 --- a/trunk/include/asm-powerpc/io.h +++ b/trunk/include/asm-powerpc/io.h @@ -72,9 +72,6 @@ extern unsigned long pci_io_base; * Neither do the standard versions now, these are just here * for older code. */ -#define insb(port, buf, ns) _insb((u8 __iomem *)((port)+pci_io_base), (buf), (ns)) -#define insw(port, buf, ns) _insw_ns((u8 __iomem *)((port)+pci_io_base), (buf), (ns)) -#define insl(port, buf, nl) _insl_ns((u8 __iomem *)((port)+pci_io_base), (buf), (nl)) #define insw_ns(port, buf, ns) _insw_ns((u16 __iomem *)((port)+pci_io_base), (buf), (ns)) #define insl_ns(port, buf, nl) _insl_ns((u32 __iomem *)((port)+pci_io_base), (buf), (nl)) #else @@ -140,12 +137,12 @@ static inline void __raw_writeq(unsigned long v, volatile void __iomem *addr) #define insw_ns(port, buf, ns) eeh_insw_ns((port), (buf), (ns)) #define insl_ns(port, buf, nl) eeh_insl_ns((port), (buf), (nl)) -#endif - #define outsb(port, buf, ns) _outsb((u8 __iomem *)((port)+pci_io_base), (buf), (ns)) #define outsw(port, buf, ns) _outsw_ns((u16 __iomem *)((port)+pci_io_base), (buf), (ns)) #define outsl(port, buf, nl) _outsl_ns((u32 __iomem *)((port)+pci_io_base), (buf), (nl)) +#endif + #define readb_relaxed(addr) readb(addr) #define readw_relaxed(addr) readw(addr) #define readl_relaxed(addr) readl(addr) diff --git a/trunk/include/asm-powerpc/ipic.h b/trunk/include/asm-powerpc/ipic.h index 53079ec3a515..0fe396a2b666 100644 --- a/trunk/include/asm-powerpc/ipic.h +++ b/trunk/include/asm-powerpc/ipic.h @@ -69,6 +69,9 @@ enum ipic_mcp_irq { IPIC_MCP_MU = 7, }; +extern void ipic_init(phys_addr_t phys_addr, unsigned int flags, + unsigned int irq_offset, + unsigned char *senses, unsigned int senses_count); extern int ipic_set_priority(unsigned int irq, unsigned int priority); extern void ipic_set_highest_priority(unsigned int irq); extern void ipic_set_default_priority(void); @@ -76,16 +79,7 @@ extern void ipic_enable_mcp(enum ipic_mcp_irq mcp_irq); extern void ipic_disable_mcp(enum ipic_mcp_irq mcp_irq); extern u32 ipic_get_mcp_status(void); extern void ipic_clear_mcp_status(u32 mask); - -#ifdef CONFIG_PPC_MERGE -extern void ipic_init(struct device_node *node, unsigned int flags); -extern unsigned int ipic_get_irq(struct pt_regs *regs); -#else -extern void ipic_init(phys_addr_t phys_addr, unsigned int flags, - unsigned int irq_offset, - unsigned char *senses, unsigned int senses_count); extern int ipic_get_irq(struct pt_regs *regs); -#endif #endif /* __ASM_IPIC_H__ */ #endif /* __KERNEL__ */ diff --git a/trunk/include/asm-powerpc/mpc86xx.h b/trunk/include/asm-powerpc/mpc86xx.h index b85df45b1a84..f260382739fa 100644 --- a/trunk/include/asm-powerpc/mpc86xx.h +++ b/trunk/include/asm-powerpc/mpc86xx.h @@ -23,6 +23,8 @@ #define _ISA_MEM_BASE isa_mem_base #ifdef CONFIG_PCI #define PCI_DRAM_OFFSET pci_dram_offset +#else +#define PCI_DRAM_OFFSET 0 #endif #define CPU0_BOOT_RELEASE 0x01000000 @@ -31,6 +33,7 @@ #define MCM_PORT_CONFIG_OFFSET 0x1010 /* Offset from CCSRBAR */ +#define MPC86xx_OPENPIC_OFFSET (0x40000) #define MPC86xx_MCM_OFFSET (0x00000) #define MPC86xx_MCM_SIZE (0x02000) diff --git a/trunk/include/asm-powerpc/mpic.h b/trunk/include/asm-powerpc/mpic.h index a9f9604b9eff..eb241c99c457 100644 --- a/trunk/include/asm-powerpc/mpic.h +++ b/trunk/include/asm-powerpc/mpic.h @@ -41,7 +41,6 @@ #define MPIC_GREG_IPI_VECTOR_PRI_1 0x000b0 #define MPIC_GREG_IPI_VECTOR_PRI_2 0x000c0 #define MPIC_GREG_IPI_VECTOR_PRI_3 0x000d0 -#define MPIC_GREG_IPI_STRIDE 0x10 #define MPIC_GREG_SPURIOUS 0x000e0 #define MPIC_GREG_TIMER_FREQ 0x000f0 @@ -69,7 +68,6 @@ #define MPIC_CPU_IPI_DISPATCH_1 0x00050 #define MPIC_CPU_IPI_DISPATCH_2 0x00060 #define MPIC_CPU_IPI_DISPATCH_3 0x00070 -#define MPIC_CPU_IPI_DISPATCH_STRIDE 0x00010 #define MPIC_CPU_CURRENT_TASK_PRI 0x00080 #define MPIC_CPU_TASKPRI_MASK 0x0000000f #define MPIC_CPU_WHOAMI 0x00090 @@ -116,103 +114,6 @@ #define MPIC_VEC_TIMER_1 248 #define MPIC_VEC_TIMER_0 247 -/* - * Tsi108 implementation of MPIC has many differences from the original one - */ - -/* - * Global registers - */ - -#define TSI108_GREG_BASE 0x00000 -#define TSI108_GREG_FEATURE_0 0x00000 -#define TSI108_GREG_GLOBAL_CONF_0 0x00004 -#define TSI108_GREG_VENDOR_ID 0x0000c -#define TSI108_GREG_IPI_VECTOR_PRI_0 0x00204 /* Doorbell 0 */ -#define TSI108_GREG_IPI_STRIDE 0x0c -#define TSI108_GREG_SPURIOUS 0x00010 -#define TSI108_GREG_TIMER_FREQ 0x00014 - -/* - * Timer registers - */ -#define TSI108_TIMER_BASE 0x0030 -#define TSI108_TIMER_STRIDE 0x10 -#define TSI108_TIMER_CURRENT_CNT 0x00000 -#define TSI108_TIMER_BASE_CNT 0x00004 -#define TSI108_TIMER_VECTOR_PRI 0x00008 -#define TSI108_TIMER_DESTINATION 0x0000c - -/* - * Per-Processor registers - */ -#define TSI108_CPU_BASE 0x00300 -#define TSI108_CPU_STRIDE 0x00040 -#define TSI108_CPU_IPI_DISPATCH_0 0x00200 -#define TSI108_CPU_IPI_DISPATCH_STRIDE 0x00000 -#define TSI108_CPU_CURRENT_TASK_PRI 0x00000 -#define TSI108_CPU_WHOAMI 0xffffffff -#define TSI108_CPU_INTACK 0x00004 -#define TSI108_CPU_EOI 0x00008 - -/* - * Per-source registers - */ -#define TSI108_IRQ_BASE 0x00100 -#define TSI108_IRQ_STRIDE 0x00008 -#define TSI108_IRQ_VECTOR_PRI 0x00000 -#define TSI108_VECPRI_VECTOR_MASK 0x000000ff -#define TSI108_VECPRI_POLARITY_POSITIVE 0x01000000 -#define TSI108_VECPRI_POLARITY_NEGATIVE 0x00000000 -#define TSI108_VECPRI_SENSE_LEVEL 0x02000000 -#define TSI108_VECPRI_SENSE_EDGE 0x00000000 -#define TSI108_VECPRI_POLARITY_MASK 0x01000000 -#define TSI108_VECPRI_SENSE_MASK 0x02000000 -#define TSI108_IRQ_DESTINATION 0x00004 - -/* weird mpic register indices and mask bits in the HW info array */ -enum { - MPIC_IDX_GREG_BASE = 0, - MPIC_IDX_GREG_FEATURE_0, - MPIC_IDX_GREG_GLOBAL_CONF_0, - MPIC_IDX_GREG_VENDOR_ID, - MPIC_IDX_GREG_IPI_VECTOR_PRI_0, - MPIC_IDX_GREG_IPI_STRIDE, - MPIC_IDX_GREG_SPURIOUS, - MPIC_IDX_GREG_TIMER_FREQ, - - MPIC_IDX_TIMER_BASE, - MPIC_IDX_TIMER_STRIDE, - MPIC_IDX_TIMER_CURRENT_CNT, - MPIC_IDX_TIMER_BASE_CNT, - MPIC_IDX_TIMER_VECTOR_PRI, - MPIC_IDX_TIMER_DESTINATION, - - MPIC_IDX_CPU_BASE, - MPIC_IDX_CPU_STRIDE, - MPIC_IDX_CPU_IPI_DISPATCH_0, - MPIC_IDX_CPU_IPI_DISPATCH_STRIDE, - MPIC_IDX_CPU_CURRENT_TASK_PRI, - MPIC_IDX_CPU_WHOAMI, - MPIC_IDX_CPU_INTACK, - MPIC_IDX_CPU_EOI, - - MPIC_IDX_IRQ_BASE, - MPIC_IDX_IRQ_STRIDE, - MPIC_IDX_IRQ_VECTOR_PRI, - - MPIC_IDX_VECPRI_VECTOR_MASK, - MPIC_IDX_VECPRI_POLARITY_POSITIVE, - MPIC_IDX_VECPRI_POLARITY_NEGATIVE, - MPIC_IDX_VECPRI_SENSE_LEVEL, - MPIC_IDX_VECPRI_SENSE_EDGE, - MPIC_IDX_VECPRI_POLARITY_MASK, - MPIC_IDX_VECPRI_SENSE_MASK, - MPIC_IDX_IRQ_DESTINATION, - MPIC_IDX_END -}; - - #ifdef CONFIG_MPIC_BROKEN_U3 /* Fixup table entry */ struct mpic_irq_fixup @@ -270,29 +171,15 @@ struct mpic volatile u32 __iomem *cpuregs[MPIC_MAX_CPUS]; volatile u32 __iomem *isus[MPIC_MAX_ISU]; -#ifdef CONFIG_MPIC_WEIRD - /* Pointer to HW info array */ - u32 *hw_set; -#endif - /* link */ struct mpic *next; }; -/* - * MPIC flags (passed to mpic_alloc) - * - * The top 4 bits contain an MPIC bhw id that is used to index the - * register offsets and some masks when CONFIG_MPIC_WEIRD is set. - * Note setting any ID (leaving those bits to 0) means standard MPIC - */ - /* This is the primary controller, only that one has IPIs and * has afinity control. A non-primary MPIC always uses CPU0 * registers only */ #define MPIC_PRIMARY 0x00000001 - /* Set this for a big-endian MPIC */ #define MPIC_BIG_ENDIAN 0x00000002 /* Broken U3 MPIC */ @@ -301,18 +188,6 @@ struct mpic #define MPIC_BROKEN_IPI 0x00000008 /* MPIC wants a reset */ #define MPIC_WANTS_RESET 0x00000010 -/* Spurious vector requires EOI */ -#define MPIC_SPV_EOI 0x00000020 -/* No passthrough disable */ -#define MPIC_NO_PTHROU_DIS 0x00000040 - -/* MPIC HW modification ID */ -#define MPIC_REGSET_MASK 0xf0000000 -#define MPIC_REGSET(val) (((val) & 0xf ) << 28) -#define MPIC_GET_REGSET(flags) (((flags) >> 28) & 0xf) - -#define MPIC_REGSET_STANDARD MPIC_REGSET(0) /* Original MPIC */ -#define MPIC_REGSET_TSI108 MPIC_REGSET(1) /* Tsi108/109 PIC */ /* Allocate the controller structure and setup the linux irq descs * for the range if interrupts passed in. No HW initialization is diff --git a/trunk/include/asm-powerpc/pgalloc.h b/trunk/include/asm-powerpc/pgalloc.h index ae63db7b3e7d..9f0917c68659 100644 --- a/trunk/include/asm-powerpc/pgalloc.h +++ b/trunk/include/asm-powerpc/pgalloc.h @@ -117,7 +117,7 @@ static inline void pte_free(struct page *ptepage) pte_free_kernel(page_address(ptepage)); } -#define PGF_CACHENUM_MASK 0x3 +#define PGF_CACHENUM_MASK 0xf typedef struct pgtable_free { unsigned long val; diff --git a/trunk/include/asm-powerpc/prom.h b/trunk/include/asm-powerpc/prom.h index d0fa1b9aed35..b095a285c84b 100644 --- a/trunk/include/asm-powerpc/prom.h +++ b/trunk/include/asm-powerpc/prom.h @@ -276,7 +276,6 @@ extern void of_irq_map_init(unsigned int flags); * of_irq_map_raw - Low level interrupt tree parsing * @parent: the device interrupt parent * @intspec: interrupt specifier ("interrupts" property of the device) - * @ointsize: size of the passed in interrupt specifier * @addr: address specifier (start of "reg" property of the device) * @out_irq: structure of_irq filled by this function * @@ -289,8 +288,7 @@ extern void of_irq_map_init(unsigned int flags); * */ -extern int of_irq_map_raw(struct device_node *parent, u32 *intspec, - u32 ointsize, u32 *addr, +extern int of_irq_map_raw(struct device_node *parent, u32 *intspec, u32 *addr, struct of_irq *out_irq); diff --git a/trunk/include/asm-powerpc/system.h b/trunk/include/asm-powerpc/system.h index 4c9f5229e833..7307aa775671 100644 --- a/trunk/include/asm-powerpc/system.h +++ b/trunk/include/asm-powerpc/system.h @@ -53,15 +53,6 @@ #define smp_read_barrier_depends() do { } while(0) #endif /* CONFIG_SMP */ -/* - * This is a barrier which prevents following instructions from being - * started until the value of the argument x is known. For example, if - * x is a variable loaded from memory, this prevents following - * instructions from being executed until the load has been performed. - */ -#define data_barrier(x) \ - asm volatile("twi 0,%0,0; isync" : : "r" (x) : "memory"); - struct task_struct; struct pt_regs; diff --git a/trunk/include/asm-powerpc/time.h b/trunk/include/asm-powerpc/time.h index 5785ac4737b5..dcde4410348d 100644 --- a/trunk/include/asm-powerpc/time.h +++ b/trunk/include/asm-powerpc/time.h @@ -30,6 +30,10 @@ extern unsigned long tb_ticks_per_usec; extern unsigned long tb_ticks_per_sec; extern u64 tb_to_xs; extern unsigned tb_to_us; +extern unsigned long tb_last_stamp; +extern u64 tb_last_jiffy; + +DECLARE_PER_CPU(unsigned long, last_jiffy); struct rtc_time; extern void to_tm(int tim, struct rtc_time * tm); diff --git a/trunk/include/asm-powerpc/tsi108.h b/trunk/include/asm-powerpc/tsi108.h index 2c702d35a7cf..c4c278d72f71 100644 --- a/trunk/include/asm-powerpc/tsi108.h +++ b/trunk/include/asm-powerpc/tsi108.h @@ -1,18 +1,16 @@ /* + * include/asm-ppc/tsi108.h + * * common routine and memory layout for Tundra TSI108(Grendel) host bridge * memory controller. * * Author: Jacob Pan (jacob.pan@freescale.com) * Alex Bounine (alexandreb@tundra.com) - * - * Copyright 2004-2006 Freescale Semiconductor, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. + * 2004 (c) Freescale Semiconductor Inc. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. */ - #ifndef __PPC_KERNEL_TSI108_H #define __PPC_KERNEL_TSI108_H diff --git a/trunk/include/asm-powerpc/tsi108_irq.h b/trunk/include/asm-powerpc/tsi108_irq.h deleted file mode 100644 index 3e4d04effa57..000000000000 --- a/trunk/include/asm-powerpc/tsi108_irq.h +++ /dev/null @@ -1,124 +0,0 @@ -/* - * (C) Copyright 2005 Tundra Semiconductor Corp. - * Alex Bounine, -#include struct alt_instr { u8 *instr; /* original instruction */ @@ -103,6 +102,9 @@ static inline void alternatives_smp_switch(int smp) {} /* * Alternative inline assembly for SMP. * + * alternative_smp() takes two versions (SMP first, UP second) and is + * for more complex stuff such as spinlocks. + * * The LOCK_PREFIX macro defined here replaces the LOCK and * LOCK_PREFIX macros used everywhere in the source tree. * @@ -122,6 +124,21 @@ static inline void alternatives_smp_switch(int smp) {} */ #ifdef CONFIG_SMP +#define alternative_smp(smpinstr, upinstr, args...) \ + asm volatile ("661:\n\t" smpinstr "\n662:\n" \ + ".section .smp_altinstructions,\"a\"\n" \ + " .align 8\n" \ + " .quad 661b\n" /* label */ \ + " .quad 663f\n" /* new instruction */ \ + " .byte 0x66\n" /* X86_FEATURE_UP */ \ + " .byte 662b-661b\n" /* sourcelen */ \ + " .byte 664f-663f\n" /* replacementlen */ \ + ".previous\n" \ + ".section .smp_altinstr_replacement,\"awx\"\n" \ + "663:\n\t" upinstr "\n" /* replacement */ \ + "664:\n\t.fill 662b-661b,1,0x42\n" /* space for original */ \ + ".previous" : args) + #define LOCK_PREFIX \ ".section .smp_locks,\"a\"\n" \ " .align 8\n" \ @@ -130,6 +147,8 @@ static inline void alternatives_smp_switch(int smp) {} "661:\n\tlock; " #else /* ! CONFIG_SMP */ +#define alternative_smp(smpinstr, upinstr, args...) \ + asm volatile (upinstr : args) #define LOCK_PREFIX "" #endif diff --git a/trunk/include/asm-x86_64/processor.h b/trunk/include/asm-x86_64/processor.h index de9c3147ee4c..3b3c1217fe61 100644 --- a/trunk/include/asm-x86_64/processor.h +++ b/trunk/include/asm-x86_64/processor.h @@ -232,14 +232,8 @@ struct tss_struct { unsigned long io_bitmap[IO_BITMAP_LONGS + 1]; } __attribute__((packed)) ____cacheline_aligned; - extern struct cpuinfo_x86 boot_cpu_data; DECLARE_PER_CPU(struct tss_struct,init_tss); -/* Save the original ist values for checking stack pointers during debugging */ -struct orig_ist { - unsigned long ist[7]; -}; -DECLARE_PER_CPU(struct orig_ist, orig_ist); #ifdef CONFIG_X86_VSMP #define ARCH_MIN_TASKALIGN (1 << INTERNODE_CACHE_SHIFT) diff --git a/trunk/include/asm-x86_64/spinlock.h b/trunk/include/asm-x86_64/spinlock.h index 248a79f0eaff..8d3421996f94 100644 --- a/trunk/include/asm-x86_64/spinlock.h +++ b/trunk/include/asm-x86_64/spinlock.h @@ -21,7 +21,7 @@ #define __raw_spin_lock_string \ "\n1:\t" \ - LOCK_PREFIX " ; decl %0\n\t" \ + "lock ; decl %0\n\t" \ "js 2f\n" \ LOCK_SECTION_START("") \ "2:\t" \ @@ -40,7 +40,10 @@ static inline void __raw_spin_lock(raw_spinlock_t *lock) { - asm volatile(__raw_spin_lock_string : "=m" (lock->slock) : : "memory"); + alternative_smp( + __raw_spin_lock_string, + __raw_spin_lock_string_up, + "=m" (lock->slock) : : "memory"); } #define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock) @@ -122,12 +125,12 @@ static inline int __raw_write_trylock(raw_rwlock_t *lock) static inline void __raw_read_unlock(raw_rwlock_t *rw) { - asm volatile(LOCK_PREFIX " ; incl %0" :"=m" (rw->lock) : : "memory"); + asm volatile("lock ; incl %0" :"=m" (rw->lock) : : "memory"); } static inline void __raw_write_unlock(raw_rwlock_t *rw) { - asm volatile(LOCK_PREFIX " ; addl $" RW_LOCK_BIAS_STR ",%0" + asm volatile("lock ; addl $" RW_LOCK_BIAS_STR ",%0" : "=m" (rw->lock) : : "memory"); } diff --git a/trunk/include/asm-x86_64/unistd.h b/trunk/include/asm-x86_64/unistd.h index 2d89d309a2a8..94387c915e53 100644 --- a/trunk/include/asm-x86_64/unistd.h +++ b/trunk/include/asm-x86_64/unistd.h @@ -620,6 +620,8 @@ __SYSCALL(__NR_vmsplice, sys_vmsplice) #define __NR_move_pages 279 __SYSCALL(__NR_move_pages, sys_move_pages) +#ifdef __KERNEL__ + #define __NR_syscall_max __NR_move_pages #ifndef __NO_STUBS @@ -744,8 +746,6 @@ __syscall_return(type,__res); \ #else /* __KERNEL_SYSCALLS__ */ -#ifdef __KERNEL__ - #include #include @@ -838,9 +838,9 @@ asmlinkage long sys_rt_sigaction(int sig, struct sigaction __user *oact, size_t sigsetsize); -#endif +#endif /* __ASSEMBLY__ */ -#endif +#endif /* __NO_STUBS */ /* * "Conditional" syscalls @@ -850,6 +850,5 @@ asmlinkage long sys_rt_sigaction(int sig, */ #define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall") -#endif - +#endif /* __KERNEL__ */ #endif diff --git a/trunk/include/asm-x86_64/unwind.h b/trunk/include/asm-x86_64/unwind.h index 1f6e9bfb569e..f3e7124effe3 100644 --- a/trunk/include/asm-x86_64/unwind.h +++ b/trunk/include/asm-x86_64/unwind.h @@ -95,7 +95,6 @@ static inline int arch_unw_user_mode(const struct unwind_frame_info *info) #else #define UNW_PC(frame) ((void)(frame), 0) -#define UNW_SP(frame) ((void)(frame), 0) static inline int arch_unw_user_mode(const void *info) { diff --git a/trunk/include/linux/compat_ioctl.h b/trunk/include/linux/compat_ioctl.h index bea0255196c4..269d000bb2a3 100644 --- a/trunk/include/linux/compat_ioctl.h +++ b/trunk/include/linux/compat_ioctl.h @@ -216,7 +216,6 @@ COMPATIBLE_IOCTL(VT_RESIZE) COMPATIBLE_IOCTL(VT_RESIZEX) COMPATIBLE_IOCTL(VT_LOCKSWITCH) COMPATIBLE_IOCTL(VT_UNLOCKSWITCH) -COMPATIBLE_IOCTL(VT_GETHIFONTMASK) /* Little p (/dev/rtc, /dev/envctrl, etc.) */ COMPATIBLE_IOCTL(RTC_AIE_ON) COMPATIBLE_IOCTL(RTC_AIE_OFF) diff --git a/trunk/include/linux/delayacct.h b/trunk/include/linux/delayacct.h index 561e2a77805c..11487b6e7127 100644 --- a/trunk/include/linux/delayacct.h +++ b/trunk/include/linux/delayacct.h @@ -59,14 +59,10 @@ static inline void delayacct_tsk_init(struct task_struct *tsk) __delayacct_tsk_init(tsk); } -/* Free tsk->delays. Called from bad fork and __put_task_struct - * where there's no risk of tsk->delays being accessed elsewhere - */ -static inline void delayacct_tsk_free(struct task_struct *tsk) +static inline void delayacct_tsk_exit(struct task_struct *tsk) { if (tsk->delays) - kmem_cache_free(delayacct_cache, tsk->delays); - tsk->delays = NULL; + __delayacct_tsk_exit(tsk); } static inline void delayacct_blkio_start(void) @@ -105,7 +101,7 @@ static inline void delayacct_init(void) {} static inline void delayacct_tsk_init(struct task_struct *tsk) {} -static inline void delayacct_tsk_free(struct task_struct *tsk) +static inline void delayacct_tsk_exit(struct task_struct *tsk) {} static inline void delayacct_blkio_start(void) {} diff --git a/trunk/include/linux/fs.h b/trunk/include/linux/fs.h index 555bc195c420..25610205c90d 100644 --- a/trunk/include/linux/fs.h +++ b/trunk/include/linux/fs.h @@ -570,14 +570,13 @@ struct inode { * 3: quota file * * The locking order between these classes is - * parent -> child -> normal -> xattr -> quota + * parent -> child -> normal -> quota */ enum inode_i_mutex_lock_class { I_MUTEX_NORMAL, I_MUTEX_PARENT, I_MUTEX_CHILD, - I_MUTEX_XATTR, I_MUTEX_QUOTA }; diff --git a/trunk/include/linux/fs_enet_pd.h b/trunk/include/linux/fs_enet_pd.h index 74ed35a00a94..783c476b8674 100644 --- a/trunk/include/linux/fs_enet_pd.h +++ b/trunk/include/linux/fs_enet_pd.h @@ -69,21 +69,34 @@ enum fs_ioport { fsiop_porte, }; -struct fs_mii_bit { - u32 offset; - u8 bit; - u8 polarity; -}; -struct fs_mii_bb_platform_info { - struct fs_mii_bit mdio_dir; - struct fs_mii_bit mdio_dat; - struct fs_mii_bit mdc_dat; - int mdio_port; /* port & bit for MDIO */ - int mdio_bit; - int mdc_port; /* port & bit for MDC */ - int mdc_bit; - int delay; /* delay in us */ - int irq[32]; /* irqs per phy's */ +struct fs_mii_bus_info { + int method; /* mii method */ + int id; /* the id of the mii_bus */ + int disable_aneg; /* if the controller needs to negothiate speed & duplex */ + int lpa; /* the default board-specific vallues will be applied otherwise */ + + union { + struct { + int duplex; + int speed; + } fixed; + + struct { + /* nothing */ + } fec; + + struct { + /* nothing */ + } scc; + + struct { + int mdio_port; /* port & bit for MDIO */ + int mdio_bit; + int mdc_port; /* port & bit for MDC */ + int mdc_bit; + int delay; /* delay in us */ + } bitbang; + } i; }; struct fs_platform_info { @@ -106,7 +119,6 @@ struct fs_platform_info { u32 device_flags; int phy_addr; /* the phy address (-1 no phy) */ - const char* bus_id; int phy_irq; /* the phy irq (if it exists) */ const struct fs_mii_bus_info *bus_info; @@ -118,10 +130,6 @@ struct fs_platform_info { int napi_weight; /* NAPI weight */ int use_rmii; /* use RMII mode */ - int has_phy; /* if the network is phy container as well...*/ -}; -struct fs_mii_fec_platform_info { - u32 irq[32]; - u32 mii_speed; }; + #endif diff --git a/trunk/include/linux/ioprio.h b/trunk/include/linux/ioprio.h index 8e2042b9d471..88d5961f7a3f 100644 --- a/trunk/include/linux/ioprio.h +++ b/trunk/include/linux/ioprio.h @@ -59,6 +59,27 @@ static inline int task_nice_ioprio(struct task_struct *task) /* * For inheritance, return the highest of the two given priorities */ -extern int ioprio_best(unsigned short aprio, unsigned short bprio); +static inline int ioprio_best(unsigned short aprio, unsigned short bprio) +{ + unsigned short aclass = IOPRIO_PRIO_CLASS(aprio); + unsigned short bclass = IOPRIO_PRIO_CLASS(bprio); + + if (!ioprio_valid(aprio)) + return bprio; + if (!ioprio_valid(bprio)) + return aprio; + + if (aclass == IOPRIO_CLASS_NONE) + aclass = IOPRIO_CLASS_BE; + if (bclass == IOPRIO_CLASS_NONE) + bclass = IOPRIO_CLASS_BE; + + if (aclass == bclass) + return min(aprio, bprio); + if (aclass > bclass) + return bprio; + else + return aprio; +} #endif diff --git a/trunk/include/linux/jbd.h b/trunk/include/linux/jbd.h index a04c154c5207..20eb34403d0c 100644 --- a/trunk/include/linux/jbd.h +++ b/trunk/include/linux/jbd.h @@ -72,9 +72,6 @@ extern int journal_enable_debug; #endif extern void * __jbd_kmalloc (const char *where, size_t size, gfp_t flags, int retry); -extern void * jbd_slab_alloc(size_t size, gfp_t flags); -extern void jbd_slab_free(void *ptr, size_t size); - #define jbd_kmalloc(size, flags) \ __jbd_kmalloc(__FUNCTION__, (size), (flags), journal_oom_retry) #define jbd_rep_kmalloc(size, flags) \ diff --git a/trunk/include/linux/mmzone.h b/trunk/include/linux/mmzone.h index f45163c528e8..656b588a9f96 100644 --- a/trunk/include/linux/mmzone.h +++ b/trunk/include/linux/mmzone.h @@ -77,7 +77,6 @@ struct per_cpu_pages { struct per_cpu_pageset { struct per_cpu_pages pcp[2]; /* 0: hot. 1: cold */ #ifdef CONFIG_SMP - s8 stat_threshold; s8 vm_stat_diff[NR_VM_ZONE_STAT_ITEMS]; #endif } ____cacheline_aligned_in_smp; diff --git a/trunk/include/linux/netfilter_bridge.h b/trunk/include/linux/netfilter_bridge.h index 427c67ff89e9..10c13dc4665b 100644 --- a/trunk/include/linux/netfilter_bridge.h +++ b/trunk/include/linux/netfilter_bridge.h @@ -48,25 +48,15 @@ enum nf_br_hook_priorities { /* Only used in br_forward.c */ static inline -int nf_bridge_maybe_copy_header(struct sk_buff *skb) +void nf_bridge_maybe_copy_header(struct sk_buff *skb) { - int err; - if (skb->nf_bridge) { if (skb->protocol == __constant_htons(ETH_P_8021Q)) { - err = skb_cow(skb, 18); - if (err) - return err; memcpy(skb->data - 18, skb->nf_bridge->data, 18); skb_push(skb, 4); - } else { - err = skb_cow(skb, 16); - if (err) - return err; + } else memcpy(skb->data - 16, skb->nf_bridge->data, 16); - } } - return 0; } /* This is called by the IP fragmenting code and it ensures there is diff --git a/trunk/include/linux/nfs_xdr.h b/trunk/include/linux/nfs_xdr.h index db9cbf68e12b..2d3fb6416d91 100644 --- a/trunk/include/linux/nfs_xdr.h +++ b/trunk/include/linux/nfs_xdr.h @@ -659,7 +659,7 @@ struct nfs4_rename_res { struct nfs4_setclientid { const nfs4_verifier * sc_verifier; /* request */ unsigned int sc_name_len; - char sc_name[48]; /* request */ + char sc_name[32]; /* request */ u32 sc_prog; /* request */ unsigned int sc_netid_len; char sc_netid[4]; /* request */ diff --git a/trunk/include/linux/node.h b/trunk/include/linux/node.h index bc001bc225c3..81dcec84cd8f 100644 --- a/trunk/include/linux/node.h +++ b/trunk/include/linux/node.h @@ -30,20 +30,12 @@ extern struct node node_devices[]; extern int register_node(struct node *, int, struct node *); extern void unregister_node(struct node *node); -#ifdef CONFIG_NUMA extern int register_one_node(int nid); extern void unregister_one_node(int nid); +#ifdef CONFIG_NUMA extern int register_cpu_under_node(unsigned int cpu, unsigned int nid); extern int unregister_cpu_under_node(unsigned int cpu, unsigned int nid); #else -static inline int register_one_node(int nid) -{ - return 0; -} -static inline int unregister_one_node(int nid) -{ - return 0; -} static inline int register_cpu_under_node(unsigned int cpu, unsigned int nid) { return 0; diff --git a/trunk/include/linux/pci_ids.h b/trunk/include/linux/pci_ids.h index c91164ea3dec..4eae06b08cf2 100644 --- a/trunk/include/linux/pci_ids.h +++ b/trunk/include/linux/pci_ids.h @@ -1292,7 +1292,6 @@ #define PCI_DEVICE_ID_VIA_8367_0 0x3099 #define PCI_DEVICE_ID_VIA_8653_0 0x3101 #define PCI_DEVICE_ID_VIA_8622 0x3102 -#define PCI_DEVICE_ID_VIA_8235_USB_2 0x3104 #define PCI_DEVICE_ID_VIA_8233C_0 0x3109 #define PCI_DEVICE_ID_VIA_8361 0x3112 #define PCI_DEVICE_ID_VIA_XM266 0x3116 @@ -1727,9 +1726,6 @@ #define PCI_VENDOR_ID_DOMEX 0x134a #define PCI_DEVICE_ID_DOMEX_DMX3191D 0x0001 -#define PCI_VENDOR_ID_INTASHIELD 0x135a -#define PCI_DEVICE_ID_INTASHIELD_IS200 0x0d80 - #define PCI_VENDOR_ID_QUATECH 0x135C #define PCI_DEVICE_ID_QUATECH_QSC100 0x0010 #define PCI_DEVICE_ID_QUATECH_DSC100 0x0020 diff --git a/trunk/include/linux/phy.h b/trunk/include/linux/phy.h index 9447a57ee8a9..331521a10a2d 100644 --- a/trunk/include/linux/phy.h +++ b/trunk/include/linux/phy.h @@ -378,7 +378,6 @@ int phy_mii_ioctl(struct phy_device *phydev, struct mii_ioctl_data *mii_data, int cmd); int phy_start_interrupts(struct phy_device *phydev); void phy_print_status(struct phy_device *phydev); -struct phy_device* phy_device_create(struct mii_bus *bus, int addr, int phy_id); extern struct bus_type mdio_bus_type; #endif /* __PHY_H */ diff --git a/trunk/include/linux/sched.h b/trunk/include/linux/sched.h index 34ed0d99b1bd..6674fc1e51bf 100644 --- a/trunk/include/linux/sched.h +++ b/trunk/include/linux/sched.h @@ -994,6 +994,7 @@ struct task_struct { */ struct pipe_inode_info *splice_pipe; #ifdef CONFIG_TASK_DELAY_ACCT + spinlock_t delays_lock; struct task_delay_info *delays; #endif }; diff --git a/trunk/include/linux/sunrpc/rpc_pipe_fs.h b/trunk/include/linux/sunrpc/rpc_pipe_fs.h index a481472c9484..2c2189cb30aa 100644 --- a/trunk/include/linux/sunrpc/rpc_pipe_fs.h +++ b/trunk/include/linux/sunrpc/rpc_pipe_fs.h @@ -42,9 +42,9 @@ RPC_I(struct inode *inode) extern int rpc_queue_upcall(struct inode *, struct rpc_pipe_msg *); extern struct dentry *rpc_mkdir(char *, struct rpc_clnt *); -extern int rpc_rmdir(struct dentry *); +extern int rpc_rmdir(char *); extern struct dentry *rpc_mkpipe(char *, void *, struct rpc_pipe_ops *, int flags); -extern int rpc_unlink(struct dentry *); +extern int rpc_unlink(char *); extern struct vfsmount *rpc_get_mount(void); extern void rpc_put_mount(void); diff --git a/trunk/include/linux/sunrpc/xprt.h b/trunk/include/linux/sunrpc/xprt.h index 3a0cca255b76..840e47a4ccc5 100644 --- a/trunk/include/linux/sunrpc/xprt.h +++ b/trunk/include/linux/sunrpc/xprt.h @@ -37,7 +37,7 @@ extern unsigned int xprt_max_resvport; #define RPC_MIN_RESVPORT (1U) #define RPC_MAX_RESVPORT (65535U) -#define RPC_DEF_MIN_RESVPORT (665U) +#define RPC_DEF_MIN_RESVPORT (650U) #define RPC_DEF_MAX_RESVPORT (1023U) /* diff --git a/trunk/include/linux/tty.h b/trunk/include/linux/tty.h index 04827ca65781..e421d5e34818 100644 --- a/trunk/include/linux/tty.h +++ b/trunk/include/linux/tty.h @@ -59,7 +59,6 @@ struct tty_bufhead { struct tty_buffer *head; /* Queue head */ struct tty_buffer *tail; /* Active buffer */ struct tty_buffer *free; /* Free queue head */ - int memory_used; /* Buffer space used excluding free queue */ }; /* * The pty uses char_buf and flag_buf as a contiguous buffer diff --git a/trunk/include/linux/vt.h b/trunk/include/linux/vt.h index ba806e8711be..8ab334a48222 100644 --- a/trunk/include/linux/vt.h +++ b/trunk/include/linux/vt.h @@ -60,6 +60,5 @@ struct vt_consize { #define VT_RESIZEX 0x560A /* set kernel's idea of screensize + more */ #define VT_LOCKSWITCH 0x560B /* disallow vt switching */ #define VT_UNLOCKSWITCH 0x560C /* allow vt switching */ -#define VT_GETHIFONTMASK 0x560D /* return hi font mask */ #endif /* _LINUX_VT_H */ diff --git a/trunk/include/net/sctp/sctp.h b/trunk/include/net/sctp/sctp.h index 92eae0e0f3f1..a9663b49ea54 100644 --- a/trunk/include/net/sctp/sctp.h +++ b/trunk/include/net/sctp/sctp.h @@ -404,6 +404,19 @@ static inline int sctp_list_single_entry(struct list_head *head) return ((head->next != head) && (head->next == head->prev)); } +/* Calculate the size (in bytes) occupied by the data of an iovec. */ +static inline size_t get_user_iov_size(struct iovec *iov, int iovlen) +{ + size_t retval = 0; + + for (; iovlen > 0; --iovlen) { + retval += iov->iov_len; + iov++; + } + + return retval; +} + /* Generate a random jitter in the range of -50% ~ +50% of input RTO. */ static inline __s32 sctp_jitter(__u32 rto) { diff --git a/trunk/include/net/sctp/sm.h b/trunk/include/net/sctp/sm.h index de313de4fefe..1eac3d0eb7a9 100644 --- a/trunk/include/net/sctp/sm.h +++ b/trunk/include/net/sctp/sm.h @@ -221,7 +221,8 @@ struct sctp_chunk *sctp_make_abort_no_data(const struct sctp_association *, const struct sctp_chunk *, __u32 tsn); struct sctp_chunk *sctp_make_abort_user(const struct sctp_association *, - const struct msghdr *, size_t msg_len); + const struct sctp_chunk *, + const struct msghdr *); struct sctp_chunk *sctp_make_abort_violation(const struct sctp_association *, const struct sctp_chunk *, const __u8 *, diff --git a/trunk/include/scsi/libiscsi.h b/trunk/include/scsi/libiscsi.h index 41904f611d12..ba2760802ded 100644 --- a/trunk/include/scsi/libiscsi.h +++ b/trunk/include/scsi/libiscsi.h @@ -60,7 +60,6 @@ struct iscsi_nopin; #define TMABORT_SUCCESS 0x1 #define TMABORT_FAILED 0x2 #define TMABORT_TIMEDOUT 0x3 -#define TMABORT_NOT_FOUND 0x4 /* Connection suspend "bit" */ #define ISCSI_SUSPEND_BIT 1 @@ -84,12 +83,6 @@ struct iscsi_mgmt_task { struct list_head running; }; -enum { - ISCSI_TASK_COMPLETED, - ISCSI_TASK_PENDING, - ISCSI_TASK_RUNNING, -}; - struct iscsi_cmd_task { /* * Becuae LLDs allocate their hdr differently, this is a pointer to @@ -108,8 +101,6 @@ struct iscsi_cmd_task { struct iscsi_conn *conn; /* used connection */ struct iscsi_mgmt_task *mtask; /* tmf mtask in progr */ - /* state set/tested under session->lock */ - int state; struct list_head running; /* running cmd list */ void *dd_data; /* driver/transport data */ }; @@ -135,14 +126,6 @@ struct iscsi_conn { int id; /* CID */ struct list_head item; /* maintains list of conns */ int c_stage; /* connection state */ - /* - * Preallocated buffer for pdus that have data but do not - * originate from scsi-ml. We never have two pdus using the - * buffer at the same time. It is only allocated to - * the default max recv size because the pdus we support - * should always fit in this buffer - */ - char *data; struct iscsi_mgmt_task *login_mtask; /* mtask used for login/text */ struct iscsi_mgmt_task *mtask; /* xmit mtask in progress */ struct iscsi_cmd_task *ctask; /* xmit ctask in progress */ @@ -151,7 +134,7 @@ struct iscsi_conn { struct kfifo *immqueue; /* immediate xmit queue */ struct kfifo *mgmtqueue; /* mgmt (control) xmit queue */ struct list_head mgmt_run_list; /* list of control tasks */ - struct list_head xmitqueue; /* data-path cmd queue */ + struct kfifo *xmitqueue; /* data-path cmd queue */ struct list_head run_list; /* list of cmds in progress */ struct work_struct xmitwork; /* per-conn. xmit workqueue */ /* diff --git a/trunk/include/scsi/scsi_transport_iscsi.h b/trunk/include/scsi/scsi_transport_iscsi.h index 39e833260bd0..5a3df1d7085f 100644 --- a/trunk/include/scsi/scsi_transport_iscsi.h +++ b/trunk/include/scsi/scsi_transport_iscsi.h @@ -57,6 +57,8 @@ struct sockaddr; * @stop_conn: suspend/recover/terminate connection * @send_pdu: send iSCSI PDU, Login, Logout, NOP-Out, Reject, Text. * @session_recovery_timedout: notify LLD a block during recovery timed out + * @suspend_conn_recv: susepend the recv side of the connection + * @termincate_conn: destroy socket connection. Called with mutex lock. * @init_cmd_task: Initialize a iscsi_cmd_task and any internal structs. * Called from queuecommand with session lock held. * @init_mgmt_task: Initialize a iscsi_mgmt_task and any internal structs. @@ -110,6 +112,8 @@ struct iscsi_transport { char *data, uint32_t data_size); void (*get_stats) (struct iscsi_cls_conn *conn, struct iscsi_stats *stats); + void (*suspend_conn_recv) (struct iscsi_conn *conn); + void (*terminate_conn) (struct iscsi_conn *conn); void (*init_cmd_task) (struct iscsi_cmd_task *ctask); void (*init_mgmt_task) (struct iscsi_conn *conn, struct iscsi_mgmt_task *mtask, diff --git a/trunk/kernel/cpuset.c b/trunk/kernel/cpuset.c index 4ea6f0dc2fc5..1a649f2bb9bb 100644 --- a/trunk/kernel/cpuset.c +++ b/trunk/kernel/cpuset.c @@ -816,10 +816,6 @@ static int update_cpumask(struct cpuset *cs, char *buf) struct cpuset trialcs; int retval, cpus_unchanged; - /* top_cpuset.cpus_allowed tracks cpu_online_map; it's read-only */ - if (cs == &top_cpuset) - return -EACCES; - trialcs = *cs; retval = cpulist_parse(buf, trialcs.cpus_allowed); if (retval < 0) @@ -2037,33 +2033,6 @@ int __init cpuset_init(void) return err; } -/* - * The top_cpuset tracks what CPUs and Memory Nodes are online, - * period. This is necessary in order to make cpusets transparent - * (of no affect) on systems that are actively using CPU hotplug - * but making no active use of cpusets. - * - * This handles CPU hotplug (cpuhp) events. If someday Memory - * Nodes can be hotplugged (dynamically changing node_online_map) - * then we should handle that too, perhaps in a similar way. - */ - -#ifdef CONFIG_HOTPLUG_CPU -static int cpuset_handle_cpuhp(struct notifier_block *nb, - unsigned long phase, void *cpu) -{ - mutex_lock(&manage_mutex); - mutex_lock(&callback_mutex); - - top_cpuset.cpus_allowed = cpu_online_map; - - mutex_unlock(&callback_mutex); - mutex_unlock(&manage_mutex); - - return 0; -} -#endif - /** * cpuset_init_smp - initialize cpus_allowed * @@ -2074,8 +2043,6 @@ void __init cpuset_init_smp(void) { top_cpuset.cpus_allowed = cpu_online_map; top_cpuset.mems_allowed = node_online_map; - - hotcpu_notifier(cpuset_handle_cpuhp, 0); } /** @@ -2420,7 +2387,7 @@ EXPORT_SYMBOL_GPL(cpuset_mem_spread_node); int cpuset_excl_nodes_overlap(const struct task_struct *p) { const struct cpuset *cs1, *cs2; /* my and p's cpuset ancestors */ - int overlap = 1; /* do cpusets overlap? */ + int overlap = 0; /* do cpusets overlap? */ task_lock(current); if (current->flags & PF_EXITING) { diff --git a/trunk/kernel/delayacct.c b/trunk/kernel/delayacct.c index 36752f124c6a..57ca3730205d 100644 --- a/trunk/kernel/delayacct.c +++ b/trunk/kernel/delayacct.c @@ -41,11 +41,24 @@ void delayacct_init(void) void __delayacct_tsk_init(struct task_struct *tsk) { + spin_lock_init(&tsk->delays_lock); + /* No need to acquire tsk->delays_lock for allocation here unless + __delayacct_tsk_init called after tsk is attached to tasklist + */ tsk->delays = kmem_cache_zalloc(delayacct_cache, SLAB_KERNEL); if (tsk->delays) spin_lock_init(&tsk->delays->lock); } +void __delayacct_tsk_exit(struct task_struct *tsk) +{ + struct task_delay_info *delays = tsk->delays; + spin_lock(&tsk->delays_lock); + tsk->delays = NULL; + spin_unlock(&tsk->delays_lock); + kmem_cache_free(delayacct_cache, delays); +} + /* * Start accounting for a delay statistic using * its starting timestamp (@start) @@ -105,6 +118,8 @@ int __delayacct_add_tsk(struct taskstats *d, struct task_struct *tsk) struct timespec ts; unsigned long t1,t2,t3; + spin_lock(&tsk->delays_lock); + /* Though tsk->delays accessed later, early exit avoids * unnecessary returning of other data */ @@ -146,6 +161,7 @@ int __delayacct_add_tsk(struct taskstats *d, struct task_struct *tsk) spin_unlock(&tsk->delays->lock); done: + spin_unlock(&tsk->delays_lock); return 0; } diff --git a/trunk/kernel/exit.c b/trunk/kernel/exit.c index d891883420f7..dba194a8d416 100644 --- a/trunk/kernel/exit.c +++ b/trunk/kernel/exit.c @@ -908,6 +908,7 @@ fastcall NORET_TYPE void do_exit(long code) audit_free(tsk); taskstats_exit_send(tsk, tidstats, group_dead, mycpu); taskstats_exit_free(tidstats); + delayacct_tsk_exit(tsk); exit_mm(tsk); @@ -1053,7 +1054,7 @@ static int eligible_child(pid_t pid, int options, struct task_struct *p) * Do not consider thread group leaders that are * in a non-empty thread group: */ - if (delay_group_leader(p)) + if (current->tgid != p->tgid && delay_group_leader(p)) return 2; if (security_task_wait(p)) diff --git a/trunk/kernel/fork.c b/trunk/kernel/fork.c index f9b014e3e700..aa36c43783cc 100644 --- a/trunk/kernel/fork.c +++ b/trunk/kernel/fork.c @@ -117,7 +117,6 @@ void __put_task_struct(struct task_struct *tsk) security_task_free(tsk); free_uid(tsk->user); put_group_info(tsk->group_info); - delayacct_tsk_free(tsk); if (!profile_handoff_task(tsk)) free_task(tsk); @@ -1012,7 +1011,7 @@ static struct task_struct *copy_process(unsigned long clone_flags, retval = -EFAULT; if (clone_flags & CLONE_PARENT_SETTID) if (put_user(p->pid, parent_tidptr)) - goto bad_fork_cleanup_delays_binfmt; + goto bad_fork_cleanup; INIT_LIST_HEAD(&p->children); INIT_LIST_HEAD(&p->sibling); @@ -1278,8 +1277,7 @@ static struct task_struct *copy_process(unsigned long clone_flags, bad_fork_cleanup_cpuset: #endif cpuset_exit(p); -bad_fork_cleanup_delays_binfmt: - delayacct_tsk_free(p); +bad_fork_cleanup: if (p->binfmt) module_put(p->binfmt->module); bad_fork_cleanup_put_domain: diff --git a/trunk/kernel/futex.c b/trunk/kernel/futex.c index b9b8aea5389e..d4633c588f33 100644 --- a/trunk/kernel/futex.c +++ b/trunk/kernel/futex.c @@ -397,7 +397,7 @@ static struct task_struct * futex_find_get_task(pid_t pid) p = NULL; goto out_unlock; } - if (p->exit_state != 0) { + if (p->state == EXIT_ZOMBIE || p->exit_state == EXIT_ZOMBIE) { p = NULL; goto out_unlock; } diff --git a/trunk/kernel/irq/handle.c b/trunk/kernel/irq/handle.c index 48a53f68af96..fc4e906aedbd 100644 --- a/trunk/kernel/irq/handle.c +++ b/trunk/kernel/irq/handle.c @@ -20,11 +20,6 @@ /** * handle_bad_irq - handle spurious and unhandled irqs - * @irq: the interrupt number - * @desc: description of the interrupt - * @regs: pointer to a register structure - * - * Handles spurious and unhandled IRQ's. It also prints a debugmessage. */ void fastcall handle_bad_irq(unsigned int irq, struct irq_desc *desc, struct pt_regs *regs) diff --git a/trunk/kernel/sched.c b/trunk/kernel/sched.c index a234fbee1238..a2be2d055299 100644 --- a/trunk/kernel/sched.c +++ b/trunk/kernel/sched.c @@ -4162,8 +4162,10 @@ do_sched_setscheduler(pid_t pid, int policy, struct sched_param __user *param) read_unlock_irq(&tasklist_lock); return -ESRCH; } - retval = sched_setscheduler(p, policy, &lparam); + get_task_struct(p); read_unlock_irq(&tasklist_lock); + retval = sched_setscheduler(p, policy, &lparam); + put_task_struct(p); return retval; } diff --git a/trunk/kernel/stop_machine.c b/trunk/kernel/stop_machine.c index 51cacd111dbd..dcfb5d731466 100644 --- a/trunk/kernel/stop_machine.c +++ b/trunk/kernel/stop_machine.c @@ -111,6 +111,7 @@ static int stop_machine(void) /* If some failed, kill them all. */ if (ret < 0) { stopmachine_set_state(STOPMACHINE_EXIT); + up(&stopmachine_mutex); return ret; } diff --git a/trunk/lib/ts_bm.c b/trunk/lib/ts_bm.c index d90822c378a4..0110e4414805 100644 --- a/trunk/lib/ts_bm.c +++ b/trunk/lib/ts_bm.c @@ -111,14 +111,15 @@ static int subpattern(u8 *pattern, int i, int j, int g) return ret; } -static void compute_prefix_tbl(struct ts_bm *bm) +static void compute_prefix_tbl(struct ts_bm *bm, const u8 *pattern, + unsigned int len) { int i, j, g; for (i = 0; i < ASIZE; i++) - bm->bad_shift[i] = bm->patlen; - for (i = 0; i < bm->patlen - 1; i++) - bm->bad_shift[bm->pattern[i]] = bm->patlen - 1 - i; + bm->bad_shift[i] = len; + for (i = 0; i < len - 1; i++) + bm->bad_shift[pattern[i]] = len - 1 - i; /* Compute the good shift array, used to match reocurrences * of a subpattern */ @@ -149,8 +150,8 @@ static struct ts_config *bm_init(const void *pattern, unsigned int len, bm = ts_config_priv(conf); bm->patlen = len; bm->pattern = (u8 *) bm->good_shift + prefix_tbl_len; + compute_prefix_tbl(bm, pattern, len); memcpy(bm->pattern, pattern, len); - compute_prefix_tbl(bm); return conf; } diff --git a/trunk/mm/mempolicy.c b/trunk/mm/mempolicy.c index a9963ceddd65..e07e27e846a2 100644 --- a/trunk/mm/mempolicy.c +++ b/trunk/mm/mempolicy.c @@ -1176,15 +1176,7 @@ static inline unsigned interleave_nid(struct mempolicy *pol, if (vma) { unsigned long off; - /* - * for small pages, there is no difference between - * shift and PAGE_SHIFT, so the bit-shift is safe. - * for huge pages, since vm_pgoff is in units of small - * pages, we need to shift off the always 0 bits to get - * a useful offset. - */ - BUG_ON(shift < PAGE_SHIFT); - off = vma->vm_pgoff >> (shift - PAGE_SHIFT); + off = vma->vm_pgoff; off += (addr - vma->vm_start) >> shift; return offset_il_node(pol, vma, off); } else diff --git a/trunk/mm/mempool.c b/trunk/mm/mempool.c index ccd8cb8cd41f..fe6e05289cc5 100644 --- a/trunk/mm/mempool.c +++ b/trunk/mm/mempool.c @@ -238,13 +238,8 @@ void * mempool_alloc(mempool_t *pool, gfp_t gfp_mask) init_wait(&wait); prepare_to_wait(&pool->wait, &wait, TASK_UNINTERRUPTIBLE); smp_mb(); - if (!pool->curr_nr) { - /* - * FIXME: this should be io_schedule(). The timeout is there - * as a workaround for some DM problems in 2.6.18. - */ - io_schedule_timeout(5*HZ); - } + if (!pool->curr_nr) + io_schedule(); finish_wait(&pool->wait, &wait); goto repeat_alloc; diff --git a/trunk/mm/swapfile.c b/trunk/mm/swapfile.c index f1f5ec783781..e70d6c6d6fee 100644 --- a/trunk/mm/swapfile.c +++ b/trunk/mm/swapfile.c @@ -442,12 +442,11 @@ int swap_type_of(dev_t device) if (!(swap_info[i].flags & SWP_WRITEOK)) continue; - if (!device) { spin_unlock(&swap_lock); return i; } - inode = swap_info[i].swap_file->f_dentry->d_inode; + inode = swap_info->swap_file->f_dentry->d_inode; if (S_ISBLK(inode->i_mode) && device == MKDEV(imajor(inode), iminor(inode))) { spin_unlock(&swap_lock); diff --git a/trunk/mm/vmstat.c b/trunk/mm/vmstat.c index c1b5f4106b38..dfdf24133901 100644 --- a/trunk/mm/vmstat.c +++ b/trunk/mm/vmstat.c @@ -12,7 +12,6 @@ #include #include #include -#include void __get_zone_counts(unsigned long *active, unsigned long *inactive, unsigned long *free, struct pglist_data *pgdat) @@ -115,72 +114,17 @@ EXPORT_SYMBOL(vm_stat); #ifdef CONFIG_SMP -static int calculate_threshold(struct zone *zone) -{ - int threshold; - int mem; /* memory in 128 MB units */ - - /* - * The threshold scales with the number of processors and the amount - * of memory per zone. More memory means that we can defer updates for - * longer, more processors could lead to more contention. - * fls() is used to have a cheap way of logarithmic scaling. - * - * Some sample thresholds: - * - * Threshold Processors (fls) Zonesize fls(mem+1) - * ------------------------------------------------------------------ - * 8 1 1 0.9-1 GB 4 - * 16 2 2 0.9-1 GB 4 - * 20 2 2 1-2 GB 5 - * 24 2 2 2-4 GB 6 - * 28 2 2 4-8 GB 7 - * 32 2 2 8-16 GB 8 - * 4 2 2 <128M 1 - * 30 4 3 2-4 GB 5 - * 48 4 3 8-16 GB 8 - * 32 8 4 1-2 GB 4 - * 32 8 4 0.9-1GB 4 - * 10 16 5 <128M 1 - * 40 16 5 900M 4 - * 70 64 7 2-4 GB 5 - * 84 64 7 4-8 GB 6 - * 108 512 9 4-8 GB 6 - * 125 1024 10 8-16 GB 8 - * 125 1024 10 16-32 GB 9 - */ - - mem = zone->present_pages >> (27 - PAGE_SHIFT); - - threshold = 2 * fls(num_online_cpus()) * (1 + fls(mem)); - - /* - * Maximum threshold is 125 - */ - threshold = min(125, threshold); - - return threshold; -} +#define STAT_THRESHOLD 32 /* - * Refresh the thresholds for each zone. + * Determine pointer to currently valid differential byte given a zone and + * the item number. + * + * Preemption must be off */ -static void refresh_zone_stat_thresholds(void) +static inline s8 *diff_pointer(struct zone *zone, enum zone_stat_item item) { - struct zone *zone; - int cpu; - int threshold; - - for_each_zone(zone) { - - if (!zone->present_pages) - continue; - - threshold = calculate_threshold(zone); - - for_each_online_cpu(cpu) - zone_pcp(zone, cpu)->stat_threshold = threshold; - } + return &zone_pcp(zone, smp_processor_id())->vm_stat_diff[item]; } /* @@ -189,16 +133,17 @@ static void refresh_zone_stat_thresholds(void) void __mod_zone_page_state(struct zone *zone, enum zone_stat_item item, int delta) { - struct per_cpu_pageset *pcp = zone_pcp(zone, smp_processor_id()); - s8 *p = pcp->vm_stat_diff + item; + s8 *p; long x; + p = diff_pointer(zone, item); x = delta + *p; - if (unlikely(x > pcp->stat_threshold || x < -pcp->stat_threshold)) { + if (unlikely(x > STAT_THRESHOLD || x < -STAT_THRESHOLD)) { zone_page_state_add(x, zone, item); x = 0; } + *p = x; } EXPORT_SYMBOL(__mod_zone_page_state); @@ -227,12 +172,10 @@ EXPORT_SYMBOL(mod_zone_page_state); * No overflow check is necessary and therefore the differential can be * incremented or decremented in place which may allow the compilers to * generate better code. + * * The increment or decrement is known and therefore one boundary check can * be omitted. * - * NOTE: These functions are very performance sensitive. Change only - * with care. - * * Some processors have inc/dec instructions that are atomic vs an interrupt. * However, the code must first determine the differential location in a zone * based on the processor number and then inc/dec the counter. There is no @@ -242,16 +185,13 @@ EXPORT_SYMBOL(mod_zone_page_state); */ static void __inc_zone_state(struct zone *zone, enum zone_stat_item item) { - struct per_cpu_pageset *pcp = zone_pcp(zone, smp_processor_id()); - s8 *p = pcp->vm_stat_diff + item; + s8 *p = diff_pointer(zone, item); (*p)++; - if (unlikely(*p > pcp->stat_threshold)) { - int overstep = pcp->stat_threshold / 2; - - zone_page_state_add(*p + overstep, zone, item); - *p = -overstep; + if (unlikely(*p > STAT_THRESHOLD)) { + zone_page_state_add(*p, zone, item); + *p = 0; } } @@ -264,16 +204,13 @@ EXPORT_SYMBOL(__inc_zone_page_state); void __dec_zone_page_state(struct page *page, enum zone_stat_item item) { struct zone *zone = page_zone(page); - struct per_cpu_pageset *pcp = zone_pcp(zone, smp_processor_id()); - s8 *p = pcp->vm_stat_diff + item; + s8 *p = diff_pointer(zone, item); (*p)--; - if (unlikely(*p < - pcp->stat_threshold)) { - int overstep = pcp->stat_threshold / 2; - - zone_page_state_add(*p - overstep, zone, item); - *p = overstep; + if (unlikely(*p < -STAT_THRESHOLD)) { + zone_page_state_add(*p, zone, item); + *p = 0; } } EXPORT_SYMBOL(__dec_zone_page_state); @@ -302,9 +239,19 @@ EXPORT_SYMBOL(inc_zone_page_state); void dec_zone_page_state(struct page *page, enum zone_stat_item item) { unsigned long flags; + struct zone *zone; + s8 *p; + zone = page_zone(page); local_irq_save(flags); - __dec_zone_page_state(page, item); + p = diff_pointer(zone, item); + + (*p)--; + + if (unlikely(*p < -STAT_THRESHOLD)) { + zone_page_state_add(*p, zone, item); + *p = 0; + } local_irq_restore(flags); } EXPORT_SYMBOL(dec_zone_page_state); @@ -578,10 +525,6 @@ static int zoneinfo_show(struct seq_file *m, void *arg) pageset->pcp[j].high, pageset->pcp[j].batch); } -#ifdef CONFIG_SMP - seq_printf(m, "\n vm stats threshold: %d", - pageset->stat_threshold); -#endif } seq_printf(m, "\n all_unreclaimable: %u" @@ -670,35 +613,3 @@ struct seq_operations vmstat_op = { #endif /* CONFIG_PROC_FS */ -#ifdef CONFIG_SMP -/* - * Use the cpu notifier to insure that the thresholds are recalculated - * when necessary. - */ -static int __cpuinit vmstat_cpuup_callback(struct notifier_block *nfb, - unsigned long action, - void *hcpu) -{ - switch (action) { - case CPU_UP_PREPARE: - case CPU_UP_CANCELED: - case CPU_DEAD: - refresh_zone_stat_thresholds(); - break; - default: - break; - } - return NOTIFY_OK; -} - -static struct notifier_block __cpuinitdata vmstat_notifier = - { &vmstat_cpuup_callback, NULL, 0 }; - -int __init setup_vmstat(void) -{ - refresh_zone_stat_thresholds(); - register_cpu_notifier(&vmstat_notifier); - return 0; -} -module_init(setup_vmstat) -#endif diff --git a/trunk/net/bridge/br_forward.c b/trunk/net/bridge/br_forward.c index 864fbbc7b24d..6ccd32b30809 100644 --- a/trunk/net/bridge/br_forward.c +++ b/trunk/net/bridge/br_forward.c @@ -40,15 +40,11 @@ int br_dev_queue_push_xmit(struct sk_buff *skb) else { #ifdef CONFIG_BRIDGE_NETFILTER /* ip_refrag calls ip_fragment, doesn't copy the MAC header. */ - if (nf_bridge_maybe_copy_header(skb)) - kfree_skb(skb); - else + nf_bridge_maybe_copy_header(skb); #endif - { - skb_push(skb, ETH_HLEN); + skb_push(skb, ETH_HLEN); - dev_queue_xmit(skb); - } + dev_queue_xmit(skb); } return 0; diff --git a/trunk/net/dccp/ccids/ccid3.c b/trunk/net/dccp/ccids/ccid3.c index 090bc39e8199..c39bff706cfc 100644 --- a/trunk/net/dccp/ccids/ccid3.c +++ b/trunk/net/dccp/ccids/ccid3.c @@ -2,7 +2,7 @@ * net/dccp/ccids/ccid3.c * * Copyright (c) 2005 The University of Waikato, Hamilton, New Zealand. - * Copyright (c) 2005-6 Ian McDonald + * Copyright (c) 2005-6 Ian McDonald * * An implementation of the DCCP protocol * @@ -342,8 +342,6 @@ static int ccid3_hc_tx_send_packet(struct sock *sk, new_packet->dccphtx_ccval = DCCP_SKB_CB(skb)->dccpd_ccval = hctx->ccid3hctx_last_win_count; - timeval_add_usecs(&hctx->ccid3hctx_t_nom, - hctx->ccid3hctx_t_ipi); } out: return rc; @@ -415,8 +413,7 @@ static void ccid3_hc_tx_packet_sent(struct sock *sk, int more, int len) case TFRC_SSTATE_NO_FBACK: case TFRC_SSTATE_FBACK: if (len > 0) { - timeval_sub_usecs(&hctx->ccid3hctx_t_nom, - hctx->ccid3hctx_t_ipi); + hctx->ccid3hctx_t_nom = now; ccid3_calc_new_t_ipi(hctx); ccid3_calc_new_delta(hctx); timeval_add_usecs(&hctx->ccid3hctx_t_nom, @@ -760,7 +757,8 @@ static void ccid3_hc_rx_send_feedback(struct sock *sk) } hcrx->ccid3hcrx_tstamp_last_feedback = now; - hcrx->ccid3hcrx_ccval_last_counter = packet->dccphrx_ccval; + hcrx->ccid3hcrx_last_counter = packet->dccphrx_ccval; + hcrx->ccid3hcrx_seqno_last_counter = packet->dccphrx_seqno; hcrx->ccid3hcrx_bytes_recv = 0; /* Convert to multiples of 10us */ @@ -784,7 +782,7 @@ static int ccid3_hc_rx_insert_options(struct sock *sk, struct sk_buff *skb) if (!(sk->sk_state == DCCP_OPEN || sk->sk_state == DCCP_PARTOPEN)) return 0; - DCCP_SKB_CB(skb)->dccpd_ccval = hcrx->ccid3hcrx_ccval_last_counter; + DCCP_SKB_CB(skb)->dccpd_ccval = hcrx->ccid3hcrx_last_counter; if (dccp_packet_without_ack(skb)) return 0; @@ -856,11 +854,6 @@ static u32 ccid3_hc_rx_calc_first_li(struct sock *sk) interval = 1; } found: - if (!tail) { - LIMIT_NETDEBUG(KERN_WARNING "%s: tail is null\n", - __FUNCTION__); - return ~0; - } rtt = timeval_delta(&tstamp, &tail->dccphrx_tstamp) * 4 / interval; ccid3_pr_debug("%s, sk=%p, approximated RTT to %uus\n", dccp_role(sk), sk, rtt); @@ -871,20 +864,9 @@ static u32 ccid3_hc_rx_calc_first_li(struct sock *sk) delta = timeval_delta(&tstamp, &hcrx->ccid3hcrx_tstamp_last_feedback); x_recv = usecs_div(hcrx->ccid3hcrx_bytes_recv, delta); - if (x_recv == 0) - x_recv = hcrx->ccid3hcrx_x_recv; - tmp1 = (u64)x_recv * (u64)rtt; do_div(tmp1,10000000); tmp2 = (u32)tmp1; - - if (!tmp2) { - LIMIT_NETDEBUG(KERN_WARNING "tmp2 = 0 " - "%s: x_recv = %u, rtt =%u\n", - __FUNCTION__, x_recv, rtt); - return ~0; - } - fval = (hcrx->ccid3hcrx_s * 100000) / tmp2; /* do not alter order above or you will get overflow on 32 bit */ p = tfrc_calc_x_reverse_lookup(fval); @@ -900,101 +882,31 @@ static u32 ccid3_hc_rx_calc_first_li(struct sock *sk) static void ccid3_hc_rx_update_li(struct sock *sk, u64 seq_loss, u8 win_loss) { struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk); - struct dccp_li_hist_entry *next, *head; - u64 seq_temp; - if (list_empty(&hcrx->ccid3hcrx_li_hist)) { - if (!dccp_li_hist_interval_new(ccid3_li_hist, - &hcrx->ccid3hcrx_li_hist, seq_loss, win_loss)) - return; + if (seq_loss != DCCP_MAX_SEQNO + 1 && + list_empty(&hcrx->ccid3hcrx_li_hist)) { + struct dccp_li_hist_entry *li_tail; - next = (struct dccp_li_hist_entry *) - hcrx->ccid3hcrx_li_hist.next; - next->dccplih_interval = ccid3_hc_rx_calc_first_li(sk); - } else { - struct dccp_li_hist_entry *entry; - struct list_head *tail; - - head = (struct dccp_li_hist_entry *) - hcrx->ccid3hcrx_li_hist.next; - /* FIXME win count check removed as was wrong */ - /* should make this check with receive history */ - /* and compare there as per section 10.2 of RFC4342 */ - - /* new loss event detected */ - /* calculate last interval length */ - seq_temp = dccp_delta_seqno(head->dccplih_seqno, seq_loss); - entry = dccp_li_hist_entry_new(ccid3_li_hist, SLAB_ATOMIC); - - if (entry == NULL) { - printk(KERN_CRIT "%s: out of memory\n",__FUNCTION__); - dump_stack(); + li_tail = dccp_li_hist_interval_new(ccid3_li_hist, + &hcrx->ccid3hcrx_li_hist, + seq_loss, win_loss); + if (li_tail == NULL) return; - } - - list_add(&entry->dccplih_node, &hcrx->ccid3hcrx_li_hist); - - tail = hcrx->ccid3hcrx_li_hist.prev; - list_del(tail); - kmem_cache_free(ccid3_li_hist->dccplih_slab, tail); - - /* Create the newest interval */ - entry->dccplih_seqno = seq_loss; - entry->dccplih_interval = seq_temp; - entry->dccplih_win_count = win_loss; - } + li_tail->dccplih_interval = ccid3_hc_rx_calc_first_li(sk); + } else + LIMIT_NETDEBUG(KERN_WARNING "%s: FIXME: find end of " + "interval\n", __FUNCTION__); } -static int ccid3_hc_rx_detect_loss(struct sock *sk, - struct dccp_rx_hist_entry *packet) +static void ccid3_hc_rx_detect_loss(struct sock *sk) { struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk); - struct dccp_rx_hist_entry *rx_hist = dccp_rx_hist_head(&hcrx->ccid3hcrx_hist); - u64 seqno = packet->dccphrx_seqno; - u64 tmp_seqno; - int loss = 0; - u8 ccval; - - - tmp_seqno = hcrx->ccid3hcrx_seqno_nonloss; - - if (!rx_hist || - follows48(packet->dccphrx_seqno, hcrx->ccid3hcrx_seqno_nonloss)) { - hcrx->ccid3hcrx_seqno_nonloss = seqno; - hcrx->ccid3hcrx_ccval_nonloss = packet->dccphrx_ccval; - goto detect_out; - } - + u8 win_loss; + const u64 seq_loss = dccp_rx_hist_detect_loss(&hcrx->ccid3hcrx_hist, + &hcrx->ccid3hcrx_li_hist, + &win_loss); - while (dccp_delta_seqno(hcrx->ccid3hcrx_seqno_nonloss, seqno) - > TFRC_RECV_NUM_LATE_LOSS) { - loss = 1; - ccid3_hc_rx_update_li(sk, hcrx->ccid3hcrx_seqno_nonloss, - hcrx->ccid3hcrx_ccval_nonloss); - tmp_seqno = hcrx->ccid3hcrx_seqno_nonloss; - dccp_inc_seqno(&tmp_seqno); - hcrx->ccid3hcrx_seqno_nonloss = tmp_seqno; - dccp_inc_seqno(&tmp_seqno); - while (dccp_rx_hist_find_entry(&hcrx->ccid3hcrx_hist, - tmp_seqno, &ccval)) { - hcrx->ccid3hcrx_seqno_nonloss = tmp_seqno; - hcrx->ccid3hcrx_ccval_nonloss = ccval; - dccp_inc_seqno(&tmp_seqno); - } - } - - /* FIXME - this code could be simplified with above while */ - /* but works at moment */ - if (follows48(packet->dccphrx_seqno, hcrx->ccid3hcrx_seqno_nonloss)) { - hcrx->ccid3hcrx_seqno_nonloss = seqno; - hcrx->ccid3hcrx_ccval_nonloss = packet->dccphrx_ccval; - } - -detect_out: - dccp_rx_hist_add_packet(ccid3_rx_hist, &hcrx->ccid3hcrx_hist, - &hcrx->ccid3hcrx_li_hist, packet, - hcrx->ccid3hcrx_seqno_nonloss); - return loss; + ccid3_hc_rx_update_li(sk, seq_loss, win_loss); } static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb) @@ -1004,8 +916,8 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb) struct dccp_rx_hist_entry *packet; struct timeval now; u8 win_count; - u32 p_prev, rtt_prev, r_sample, t_elapsed; - int loss; + u32 p_prev, r_sample, t_elapsed; + int ins; BUG_ON(hcrx == NULL || !(hcrx->ccid3hcrx_state == TFRC_RSTATE_NO_DATA || @@ -1020,7 +932,7 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb) case DCCP_PKT_DATAACK: if (opt_recv->dccpor_timestamp_echo == 0) break; - rtt_prev = hcrx->ccid3hcrx_rtt; + p_prev = hcrx->ccid3hcrx_rtt; dccp_timestamp(sk, &now); timeval_sub_usecs(&now, opt_recv->dccpor_timestamp_echo * 10); r_sample = timeval_usecs(&now); @@ -1039,8 +951,8 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb) hcrx->ccid3hcrx_rtt = (hcrx->ccid3hcrx_rtt * 9) / 10 + r_sample / 10; - if (rtt_prev != hcrx->ccid3hcrx_rtt) - ccid3_pr_debug("%s, New RTT=%uus, elapsed time=%u\n", + if (p_prev != hcrx->ccid3hcrx_rtt) + ccid3_pr_debug("%s, New RTT=%luus, elapsed time=%u\n", dccp_role(sk), hcrx->ccid3hcrx_rtt, opt_recv->dccpor_elapsed_time); break; @@ -1061,7 +973,8 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb) win_count = packet->dccphrx_ccval; - loss = ccid3_hc_rx_detect_loss(sk, packet); + ins = dccp_rx_hist_add_packet(ccid3_rx_hist, &hcrx->ccid3hcrx_hist, + &hcrx->ccid3hcrx_li_hist, packet); if (DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_ACK) return; @@ -1078,7 +991,7 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb) case TFRC_RSTATE_DATA: hcrx->ccid3hcrx_bytes_recv += skb->len - dccp_hdr(skb)->dccph_doff * 4; - if (loss) + if (ins != 0) break; dccp_timestamp(sk, &now); @@ -1099,6 +1012,7 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb) ccid3_pr_debug("%s, sk=%p(%s), data loss! Reacting...\n", dccp_role(sk), sk, dccp_state_name(sk->sk_state)); + ccid3_hc_rx_detect_loss(sk); p_prev = hcrx->ccid3hcrx_p; /* Calculate loss event rate */ @@ -1108,9 +1022,6 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb) /* Scaling up by 1000000 as fixed decimal */ if (i_mean != 0) hcrx->ccid3hcrx_p = 1000000 / i_mean; - } else { - printk(KERN_CRIT "%s: empty loss hist\n",__FUNCTION__); - dump_stack(); } if (hcrx->ccid3hcrx_p > p_prev) { @@ -1319,7 +1230,7 @@ static __exit void ccid3_module_exit(void) } module_exit(ccid3_module_exit); -MODULE_AUTHOR("Ian McDonald , " +MODULE_AUTHOR("Ian McDonald , " "Arnaldo Carvalho de Melo "); MODULE_DESCRIPTION("DCCP TFRC CCID3 CCID"); MODULE_LICENSE("GPL"); diff --git a/trunk/net/dccp/ccids/ccid3.h b/trunk/net/dccp/ccids/ccid3.h index 0a2cb7536d26..5ade4f668b22 100644 --- a/trunk/net/dccp/ccids/ccid3.h +++ b/trunk/net/dccp/ccids/ccid3.h @@ -1,13 +1,13 @@ /* * net/dccp/ccids/ccid3.h * - * Copyright (c) 2005-6 The University of Waikato, Hamilton, New Zealand. + * Copyright (c) 2005 The University of Waikato, Hamilton, New Zealand. * * An implementation of the DCCP protocol * * This code has been developed by the University of Waikato WAND * research group. For further information please see http://www.wand.net.nz/ - * or e-mail Ian McDonald - ian.mcdonald@jandi.co.nz + * or e-mail Ian McDonald - iam4@cs.waikato.ac.nz * * This code also uses code from Lulea University, rereleased as GPL by its * authors: @@ -120,10 +120,9 @@ struct ccid3_hc_rx_sock { #define ccid3hcrx_x_recv ccid3hcrx_tfrc.tfrcrx_x_recv #define ccid3hcrx_rtt ccid3hcrx_tfrc.tfrcrx_rtt #define ccid3hcrx_p ccid3hcrx_tfrc.tfrcrx_p - u64 ccid3hcrx_seqno_nonloss:48, - ccid3hcrx_ccval_nonloss:4, + u64 ccid3hcrx_seqno_last_counter:48, ccid3hcrx_state:8, - ccid3hcrx_ccval_last_counter:4; + ccid3hcrx_last_counter:4; u32 ccid3hcrx_bytes_recv; struct timeval ccid3hcrx_tstamp_last_feedback; struct timeval ccid3hcrx_tstamp_last_ack; diff --git a/trunk/net/dccp/ccids/lib/loss_interval.c b/trunk/net/dccp/ccids/lib/loss_interval.c index 906c81ab9d4f..5d7b7d864385 100644 --- a/trunk/net/dccp/ccids/lib/loss_interval.c +++ b/trunk/net/dccp/ccids/lib/loss_interval.c @@ -2,7 +2,7 @@ * net/dccp/ccids/lib/loss_interval.c * * Copyright (c) 2005 The University of Waikato, Hamilton, New Zealand. - * Copyright (c) 2005-6 Ian McDonald + * Copyright (c) 2005 Ian McDonald * Copyright (c) 2005 Arnaldo Carvalho de Melo * * This program is free software; you can redistribute it and/or modify @@ -12,7 +12,6 @@ */ #include -#include #include "loss_interval.h" @@ -91,13 +90,13 @@ u32 dccp_li_hist_calc_i_mean(struct list_head *list) u32 w_tot = 0; list_for_each_entry_safe(li_entry, li_next, list, dccplih_node) { - if (li_entry->dccplih_interval != ~0) { + if (i < DCCP_LI_HIST_IVAL_F_LENGTH) { i_tot0 += li_entry->dccplih_interval * dccp_li_hist_w[i]; w_tot += dccp_li_hist_w[i]; - if (i != 0) - i_tot1 += li_entry->dccplih_interval * dccp_li_hist_w[i - 1]; } + if (i != 0) + i_tot1 += li_entry->dccplih_interval * dccp_li_hist_w[i - 1]; if (++i > DCCP_LI_HIST_IVAL_F_LENGTH) break; @@ -108,36 +107,37 @@ u32 dccp_li_hist_calc_i_mean(struct list_head *list) i_tot = max(i_tot0, i_tot1); - if (!w_tot) { - LIMIT_NETDEBUG(KERN_WARNING "%s: w_tot = 0\n", __FUNCTION__); - return 1; - } + /* FIXME: Why do we do this? -Ian McDonald */ + if (i_tot * 4 < w_tot) + i_tot = w_tot * 4; - return i_tot / w_tot; + return i_tot * 4 / w_tot; } EXPORT_SYMBOL_GPL(dccp_li_hist_calc_i_mean); -int dccp_li_hist_interval_new(struct dccp_li_hist *hist, - struct list_head *list, const u64 seq_loss, const u8 win_loss) +struct dccp_li_hist_entry *dccp_li_hist_interval_new(struct dccp_li_hist *hist, + struct list_head *list, + const u64 seq_loss, + const u8 win_loss) { - struct dccp_li_hist_entry *entry; + struct dccp_li_hist_entry *tail = NULL, *entry; int i; - for (i = 0; i < DCCP_LI_HIST_IVAL_F_LENGTH; i++) { + for (i = 0; i <= DCCP_LI_HIST_IVAL_F_LENGTH; ++i) { entry = dccp_li_hist_entry_new(hist, SLAB_ATOMIC); if (entry == NULL) { dccp_li_hist_purge(hist, list); - dump_stack(); - return 0; + return NULL; } - entry->dccplih_interval = ~0; + if (tail == NULL) + tail = entry; list_add(&entry->dccplih_node, list); } entry->dccplih_seqno = seq_loss; entry->dccplih_win_count = win_loss; - return 1; + return tail; } EXPORT_SYMBOL_GPL(dccp_li_hist_interval_new); diff --git a/trunk/net/dccp/ccids/lib/loss_interval.h b/trunk/net/dccp/ccids/lib/loss_interval.h index 0ae85f0340b2..43bf78269d1d 100644 --- a/trunk/net/dccp/ccids/lib/loss_interval.h +++ b/trunk/net/dccp/ccids/lib/loss_interval.h @@ -4,7 +4,7 @@ * net/dccp/ccids/lib/loss_interval.h * * Copyright (c) 2005 The University of Waikato, Hamilton, New Zealand. - * Copyright (c) 2005 Ian McDonald + * Copyright (c) 2005 Ian McDonald * Copyright (c) 2005 Arnaldo Carvalho de Melo * * This program is free software; you can redistribute it and/or modify it @@ -52,6 +52,9 @@ extern void dccp_li_hist_purge(struct dccp_li_hist *hist, extern u32 dccp_li_hist_calc_i_mean(struct list_head *list); -extern int dccp_li_hist_interval_new(struct dccp_li_hist *hist, - struct list_head *list, const u64 seq_loss, const u8 win_loss); +extern struct dccp_li_hist_entry * + dccp_li_hist_interval_new(struct dccp_li_hist *hist, + struct list_head *list, + const u64 seq_loss, + const u8 win_loss); #endif /* _DCCP_LI_HIST_ */ diff --git a/trunk/net/dccp/ccids/lib/packet_history.c b/trunk/net/dccp/ccids/lib/packet_history.c index b876c9c81c65..ad98d6a322eb 100644 --- a/trunk/net/dccp/ccids/lib/packet_history.c +++ b/trunk/net/dccp/ccids/lib/packet_history.c @@ -1,13 +1,13 @@ /* - * net/dccp/packet_history.c + * net/dccp/packet_history.h * - * Copyright (c) 2005-6 The University of Waikato, Hamilton, New Zealand. + * Copyright (c) 2005 The University of Waikato, Hamilton, New Zealand. * * An implementation of the DCCP protocol * * This code has been developed by the University of Waikato WAND * research group. For further information please see http://www.wand.net.nz/ - * or e-mail Ian McDonald - ian.mcdonald@jandi.co.nz + * or e-mail Ian McDonald - iam4@cs.waikato.ac.nz * * This code also uses code from Lulea University, rereleased as GPL by its * authors: @@ -112,27 +112,64 @@ struct dccp_rx_hist_entry * EXPORT_SYMBOL_GPL(dccp_rx_hist_find_data_packet); -void dccp_rx_hist_add_packet(struct dccp_rx_hist *hist, +int dccp_rx_hist_add_packet(struct dccp_rx_hist *hist, struct list_head *rx_list, struct list_head *li_list, - struct dccp_rx_hist_entry *packet, - u64 nonloss_seqno) + struct dccp_rx_hist_entry *packet) { - struct dccp_rx_hist_entry *entry, *next; + struct dccp_rx_hist_entry *entry, *next, *iter; u8 num_later = 0; - list_add(&packet->dccphrx_node, rx_list); + iter = dccp_rx_hist_head(rx_list); + if (iter == NULL) + dccp_rx_hist_add_entry(rx_list, packet); + else { + const u64 seqno = packet->dccphrx_seqno; + + if (after48(seqno, iter->dccphrx_seqno)) + dccp_rx_hist_add_entry(rx_list, packet); + else { + if (dccp_rx_hist_entry_data_packet(iter)) + num_later = 1; + + list_for_each_entry_continue(iter, rx_list, + dccphrx_node) { + if (after48(seqno, iter->dccphrx_seqno)) { + dccp_rx_hist_add_entry(&iter->dccphrx_node, + packet); + goto trim_history; + } + + if (dccp_rx_hist_entry_data_packet(iter)) + num_later++; + if (num_later == TFRC_RECV_NUM_LATE_LOSS) { + dccp_rx_hist_entry_delete(hist, packet); + return 1; + } + } + + if (num_later < TFRC_RECV_NUM_LATE_LOSS) + dccp_rx_hist_add_entry(rx_list, packet); + /* + * FIXME: else what? should we destroy the packet + * like above? + */ + } + } + +trim_history: + /* + * Trim history (remove all packets after the NUM_LATE_LOSS + 1 + * data packets) + */ num_later = TFRC_RECV_NUM_LATE_LOSS + 1; if (!list_empty(li_list)) { list_for_each_entry_safe(entry, next, rx_list, dccphrx_node) { if (num_later == 0) { - if (after48(nonloss_seqno, - entry->dccphrx_seqno)) { - list_del_init(&entry->dccphrx_node); - dccp_rx_hist_entry_delete(hist, entry); - } + list_del_init(&entry->dccphrx_node); + dccp_rx_hist_entry_delete(hist, entry); } else if (dccp_rx_hist_entry_data_packet(entry)) --num_later; } @@ -180,10 +217,94 @@ void dccp_rx_hist_add_packet(struct dccp_rx_hist *hist, --num_later; } } + + return 0; } EXPORT_SYMBOL_GPL(dccp_rx_hist_add_packet); +u64 dccp_rx_hist_detect_loss(struct list_head *rx_list, + struct list_head *li_list, u8 *win_loss) +{ + struct dccp_rx_hist_entry *entry, *next, *packet; + struct dccp_rx_hist_entry *a_loss = NULL; + struct dccp_rx_hist_entry *b_loss = NULL; + u64 seq_loss = DCCP_MAX_SEQNO + 1; + u8 num_later = TFRC_RECV_NUM_LATE_LOSS; + + list_for_each_entry_safe(entry, next, rx_list, dccphrx_node) { + if (num_later == 0) { + b_loss = entry; + break; + } else if (dccp_rx_hist_entry_data_packet(entry)) + --num_later; + } + + if (b_loss == NULL) + goto out; + + num_later = 1; + list_for_each_entry_safe_continue(entry, next, rx_list, dccphrx_node) { + if (num_later == 0) { + a_loss = entry; + break; + } else if (dccp_rx_hist_entry_data_packet(entry)) + --num_later; + } + + if (a_loss == NULL) { + if (list_empty(li_list)) { + /* no loss event have occured yet */ + LIMIT_NETDEBUG("%s: TODO: find a lost data packet by " + "comparing to initial seqno\n", + __FUNCTION__); + goto out; + } else { + LIMIT_NETDEBUG("%s: Less than 4 data pkts in history!", + __FUNCTION__); + goto out; + } + } + + /* Locate a lost data packet */ + entry = packet = b_loss; + list_for_each_entry_safe_continue(entry, next, rx_list, dccphrx_node) { + u64 delta = dccp_delta_seqno(entry->dccphrx_seqno, + packet->dccphrx_seqno); + + if (delta != 0) { + if (dccp_rx_hist_entry_data_packet(packet)) + --delta; + /* + * FIXME: check this, probably this % usage is because + * in earlier drafts the ndp count was just 8 bits + * long, but now it cam be up to 24 bits long. + */ +#if 0 + if (delta % DCCP_NDP_LIMIT != + (packet->dccphrx_ndp - + entry->dccphrx_ndp) % DCCP_NDP_LIMIT) +#endif + if (delta != packet->dccphrx_ndp - entry->dccphrx_ndp) { + seq_loss = entry->dccphrx_seqno; + dccp_inc_seqno(&seq_loss); + } + } + packet = entry; + if (packet == a_loss) + break; + } +out: + if (seq_loss != DCCP_MAX_SEQNO + 1) + *win_loss = a_loss->dccphrx_ccval; + else + *win_loss = 0; /* Paranoia */ + + return seq_loss; +} + +EXPORT_SYMBOL_GPL(dccp_rx_hist_detect_loss); + struct dccp_tx_hist *dccp_tx_hist_new(const char *name) { struct dccp_tx_hist *hist = kmalloc(sizeof(*hist), GFP_ATOMIC); @@ -244,25 +365,6 @@ struct dccp_tx_hist_entry * EXPORT_SYMBOL_GPL(dccp_tx_hist_find_entry); -int dccp_rx_hist_find_entry(const struct list_head *list, const u64 seq, - u8 *ccval) -{ - struct dccp_rx_hist_entry *packet = NULL, *entry; - - list_for_each_entry(entry, list, dccphrx_node) - if (entry->dccphrx_seqno == seq) { - packet = entry; - break; - } - - if (packet) - *ccval = packet->dccphrx_ccval; - - return packet != NULL; -} - -EXPORT_SYMBOL_GPL(dccp_rx_hist_find_entry); - void dccp_tx_hist_purge_older(struct dccp_tx_hist *hist, struct list_head *list, struct dccp_tx_hist_entry *packet) @@ -289,7 +391,7 @@ void dccp_tx_hist_purge(struct dccp_tx_hist *hist, struct list_head *list) EXPORT_SYMBOL_GPL(dccp_tx_hist_purge); -MODULE_AUTHOR("Ian McDonald , " +MODULE_AUTHOR("Ian McDonald , " "Arnaldo Carvalho de Melo "); MODULE_DESCRIPTION("DCCP TFRC library"); MODULE_LICENSE("GPL"); diff --git a/trunk/net/dccp/ccids/lib/packet_history.h b/trunk/net/dccp/ccids/lib/packet_history.h index 067cf1c85a37..673c209e4e85 100644 --- a/trunk/net/dccp/ccids/lib/packet_history.h +++ b/trunk/net/dccp/ccids/lib/packet_history.h @@ -1,13 +1,13 @@ /* * net/dccp/packet_history.h * - * Copyright (c) 2005-6 The University of Waikato, Hamilton, New Zealand. + * Copyright (c) 2005 The University of Waikato, Hamilton, New Zealand. * * An implementation of the DCCP protocol * * This code has been developed by the University of Waikato WAND * research group. For further information please see http://www.wand.net.nz/ - * or e-mail Ian McDonald - ian.mcdonald@jandi.co.nz + * or e-mail Ian McDonald - iam4@cs.waikato.ac.nz * * This code also uses code from Lulea University, rereleased as GPL by its * authors: @@ -106,8 +106,6 @@ static inline void dccp_tx_hist_entry_delete(struct dccp_tx_hist *hist, extern struct dccp_tx_hist_entry * dccp_tx_hist_find_entry(const struct list_head *list, const u64 seq); -extern int dccp_rx_hist_find_entry(const struct list_head *list, const u64 seq, - u8 *ccval); static inline void dccp_tx_hist_add_entry(struct list_head *list, struct dccp_tx_hist_entry *entry) @@ -166,6 +164,12 @@ static inline void dccp_rx_hist_entry_delete(struct dccp_rx_hist *hist, extern void dccp_rx_hist_purge(struct dccp_rx_hist *hist, struct list_head *list); +static inline void dccp_rx_hist_add_entry(struct list_head *list, + struct dccp_rx_hist_entry *entry) +{ + list_add(&entry->dccphrx_node, list); +} + static inline struct dccp_rx_hist_entry * dccp_rx_hist_head(struct list_head *list) { @@ -184,11 +188,10 @@ static inline int entry->dccphrx_type == DCCP_PKT_DATAACK; } -extern void dccp_rx_hist_add_packet(struct dccp_rx_hist *hist, +extern int dccp_rx_hist_add_packet(struct dccp_rx_hist *hist, struct list_head *rx_list, struct list_head *li_list, - struct dccp_rx_hist_entry *packet, - u64 nonloss_seqno); + struct dccp_rx_hist_entry *packet); extern u64 dccp_rx_hist_detect_loss(struct list_head *rx_list, struct list_head *li_list, u8 *win_loss); diff --git a/trunk/net/dccp/ccids/lib/tfrc.h b/trunk/net/dccp/ccids/lib/tfrc.h index 45f30f59ea2a..130c4c40cfe3 100644 --- a/trunk/net/dccp/ccids/lib/tfrc.h +++ b/trunk/net/dccp/ccids/lib/tfrc.h @@ -4,7 +4,7 @@ * net/dccp/ccids/lib/tfrc.h * * Copyright (c) 2005 The University of Waikato, Hamilton, New Zealand. - * Copyright (c) 2005 Ian McDonald + * Copyright (c) 2005 Ian McDonald * Copyright (c) 2005 Arnaldo Carvalho de Melo * Copyright (c) 2003 Nils-Erik Mattsson, Joacim Haggmark, Magnus Erixzon * diff --git a/trunk/net/dccp/ccids/lib/tfrc_equation.c b/trunk/net/dccp/ccids/lib/tfrc_equation.c index 44076e0c6591..4fd2ebebf5a0 100644 --- a/trunk/net/dccp/ccids/lib/tfrc_equation.c +++ b/trunk/net/dccp/ccids/lib/tfrc_equation.c @@ -2,7 +2,7 @@ * net/dccp/ccids/lib/tfrc_equation.c * * Copyright (c) 2005 The University of Waikato, Hamilton, New Zealand. - * Copyright (c) 2005 Ian McDonald + * Copyright (c) 2005 Ian McDonald * Copyright (c) 2005 Arnaldo Carvalho de Melo * Copyright (c) 2003 Nils-Erik Mattsson, Joacim Haggmark, Magnus Erixzon * diff --git a/trunk/net/dccp/dccp.h b/trunk/net/dccp/dccp.h index a5c5475724c0..d00a2f4ee5dd 100644 --- a/trunk/net/dccp/dccp.h +++ b/trunk/net/dccp/dccp.h @@ -5,7 +5,7 @@ * * An implementation of the DCCP protocol * Copyright (c) 2005 Arnaldo Carvalho de Melo - * Copyright (c) 2005-6 Ian McDonald + * Copyright (c) 2005 Ian McDonald * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as @@ -81,14 +81,6 @@ static inline u64 max48(const u64 seq1, const u64 seq2) return after48(seq1, seq2) ? seq1 : seq2; } -/* is seq1 next seqno after seq2 */ -static inline int follows48(const u64 seq1, const u64 seq2) -{ - int diff = (seq1 & 0xFFFF) - (seq2 & 0xFFFF); - - return diff==1; -} - enum { DCCP_MIB_NUM = 0, DCCP_MIB_ACTIVEOPENS, /* ActiveOpens */ diff --git a/trunk/net/dccp/options.c b/trunk/net/dccp/options.c index 07a34696ac97..daf72bb671f0 100644 --- a/trunk/net/dccp/options.c +++ b/trunk/net/dccp/options.c @@ -4,7 +4,7 @@ * An implementation of the DCCP protocol * Copyright (c) 2005 Aristeu Sergio Rozanski Filho * Copyright (c) 2005 Arnaldo Carvalho de Melo - * Copyright (c) 2005 Ian McDonald + * Copyright (c) 2005 Ian McDonald * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/trunk/net/ipv4/ip_output.c b/trunk/net/ipv4/ip_output.c index a2ede167e045..4c20f5546893 100644 --- a/trunk/net/ipv4/ip_output.c +++ b/trunk/net/ipv4/ip_output.c @@ -440,7 +440,6 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*)) iph = skb->nh.iph; if (unlikely((iph->frag_off & htons(IP_DF)) && !skb->local_df)) { - IP_INC_STATS(IPSTATS_MIB_FRAGFAILS); icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(dst_mtu(&rt->u.dst))); kfree_skb(skb); diff --git a/trunk/net/ipv4/netfilter/arp_tables.c b/trunk/net/ipv4/netfilter/arp_tables.c index 8d1d7a6e72a5..df4854cf598b 100644 --- a/trunk/net/ipv4/netfilter/arp_tables.c +++ b/trunk/net/ipv4/netfilter/arp_tables.c @@ -236,7 +236,7 @@ unsigned int arpt_do_table(struct sk_buff **pskb, struct arpt_entry *e, *back; const char *indev, *outdev; void *table_base; - struct xt_table_info *private; + struct xt_table_info *private = table->private; /* ARP header, plus 2 device addresses, plus 2 IP addresses. */ if (!pskb_may_pull((*pskb), (sizeof(struct arphdr) + @@ -248,7 +248,6 @@ unsigned int arpt_do_table(struct sk_buff **pskb, outdev = out ? out->name : nulldevname; read_lock_bh(&table->lock); - private = table->private; table_base = (void *)private->entries[smp_processor_id()]; e = get_entry(table_base, private->hook_entry[hook]); back = get_entry(table_base, private->underflow[hook]); diff --git a/trunk/net/ipv4/tcp_cong.c b/trunk/net/ipv4/tcp_cong.c index 7ff2e4273a7c..5765f9d03174 100644 --- a/trunk/net/ipv4/tcp_cong.c +++ b/trunk/net/ipv4/tcp_cong.c @@ -189,7 +189,7 @@ void tcp_slow_start(struct tcp_sock *tp) return; /* We MAY increase by 2 if discovered delayed ack */ - if (sysctl_tcp_abc > 1 && tp->bytes_acked >= 2*tp->mss_cache) { + if (sysctl_tcp_abc > 1 && tp->bytes_acked > 2*tp->mss_cache) { if (tp->snd_cwnd < tp->snd_cwnd_clamp) tp->snd_cwnd++; } diff --git a/trunk/net/ipv4/tcp_input.c b/trunk/net/ipv4/tcp_input.c index 111ff39a08c5..104af5d5bcbc 100644 --- a/trunk/net/ipv4/tcp_input.c +++ b/trunk/net/ipv4/tcp_input.c @@ -2505,13 +2505,8 @@ static int tcp_ack(struct sock *sk, struct sk_buff *skb, int flag) if (before(ack, prior_snd_una)) goto old_ack; - if (sysctl_tcp_abc) { - if (icsk->icsk_ca_state < TCP_CA_CWR) - tp->bytes_acked += ack - prior_snd_una; - else if (icsk->icsk_ca_state == TCP_CA_Loss) - /* we assume just one segment left network */ - tp->bytes_acked += min(ack - prior_snd_una, tp->mss_cache); - } + if (sysctl_tcp_abc && icsk->icsk_ca_state < TCP_CA_CWR) + tp->bytes_acked += ack - prior_snd_una; if (!(flag&FLAG_SLOWPATH) && after(ack, prior_snd_una)) { /* Window is constant, pure forward advance. diff --git a/trunk/net/ipv4/tcp_output.c b/trunk/net/ipv4/tcp_output.c index b4f3ffe1b3b4..507adefbc17c 100644 --- a/trunk/net/ipv4/tcp_output.c +++ b/trunk/net/ipv4/tcp_output.c @@ -201,7 +201,6 @@ void tcp_select_initial_window(int __space, __u32 mss, * See RFC1323 for an explanation of the limit to 14 */ space = max_t(u32, sysctl_tcp_rmem[2], sysctl_rmem_max); - space = min_t(u32, space, *window_clamp); while (space > 65535 && (*rcv_wscale) < 14) { space >>= 1; (*rcv_wscale)++; diff --git a/trunk/net/ipv6/addrconf.c b/trunk/net/ipv6/addrconf.c index c7852b38e03e..0c5042e7380d 100644 --- a/trunk/net/ipv6/addrconf.c +++ b/trunk/net/ipv6/addrconf.c @@ -578,8 +578,6 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr, int pfxlen, ifa->flags = flags | IFA_F_TENTATIVE; ifa->cstamp = ifa->tstamp = jiffies; - ifa->rt = rt; - ifa->idev = idev; in6_dev_hold(idev); /* For caller */ @@ -605,6 +603,8 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr, int pfxlen, } #endif + ifa->rt = rt; + in6_ifa_hold(ifa); write_unlock(&idev->lock); out2: diff --git a/trunk/net/ipv6/exthdrs.c b/trunk/net/ipv6/exthdrs.c index 86dac106873b..9d0ee7f0eeb5 100644 --- a/trunk/net/ipv6/exthdrs.c +++ b/trunk/net/ipv6/exthdrs.c @@ -635,17 +635,14 @@ ipv6_renew_options(struct sock *sk, struct ipv6_txoptions *opt, struct ipv6_txoptions *opt2; int err; - if (opt) { - if (newtype != IPV6_HOPOPTS && opt->hopopt) - tot_len += CMSG_ALIGN(ipv6_optlen(opt->hopopt)); - if (newtype != IPV6_RTHDRDSTOPTS && opt->dst0opt) - tot_len += CMSG_ALIGN(ipv6_optlen(opt->dst0opt)); - if (newtype != IPV6_RTHDR && opt->srcrt) - tot_len += CMSG_ALIGN(ipv6_optlen(opt->srcrt)); - if (newtype != IPV6_DSTOPTS && opt->dst1opt) - tot_len += CMSG_ALIGN(ipv6_optlen(opt->dst1opt)); - } - + if (newtype != IPV6_HOPOPTS && opt->hopopt) + tot_len += CMSG_ALIGN(ipv6_optlen(opt->hopopt)); + if (newtype != IPV6_RTHDRDSTOPTS && opt->dst0opt) + tot_len += CMSG_ALIGN(ipv6_optlen(opt->dst0opt)); + if (newtype != IPV6_RTHDR && opt->srcrt) + tot_len += CMSG_ALIGN(ipv6_optlen(opt->srcrt)); + if (newtype != IPV6_DSTOPTS && opt->dst1opt) + tot_len += CMSG_ALIGN(ipv6_optlen(opt->dst1opt)); if (newopt && newoptlen) tot_len += CMSG_ALIGN(newoptlen); @@ -662,25 +659,25 @@ ipv6_renew_options(struct sock *sk, struct ipv6_txoptions *opt, opt2->tot_len = tot_len; p = (char *)(opt2 + 1); - err = ipv6_renew_option(opt ? opt->hopopt : NULL, newopt, newoptlen, + err = ipv6_renew_option(opt->hopopt, newopt, newoptlen, newtype != IPV6_HOPOPTS, &opt2->hopopt, &p); if (err) goto out; - err = ipv6_renew_option(opt ? opt->dst0opt : NULL, newopt, newoptlen, + err = ipv6_renew_option(opt->dst0opt, newopt, newoptlen, newtype != IPV6_RTHDRDSTOPTS, &opt2->dst0opt, &p); if (err) goto out; - err = ipv6_renew_option(opt ? opt->srcrt : NULL, newopt, newoptlen, + err = ipv6_renew_option(opt->srcrt, newopt, newoptlen, newtype != IPV6_RTHDR, - (struct ipv6_opt_hdr **)&opt2->srcrt, &p); + (struct ipv6_opt_hdr **)opt2->srcrt, &p); if (err) goto out; - err = ipv6_renew_option(opt ? opt->dst1opt : NULL, newopt, newoptlen, + err = ipv6_renew_option(opt->dst1opt, newopt, newoptlen, newtype != IPV6_DSTOPTS, &opt2->dst1opt, &p); if (err) diff --git a/trunk/net/ipv6/route.c b/trunk/net/ipv6/route.c index d9baca062d24..4b163711f3a8 100644 --- a/trunk/net/ipv6/route.c +++ b/trunk/net/ipv6/route.c @@ -1532,10 +1532,6 @@ int ipv6_route_ioctl(unsigned int cmd, void __user *arg) static int ip6_pkt_discard(struct sk_buff *skb) { - int type = ipv6_addr_type(&skb->nh.ipv6h->daddr); - if (type == IPV6_ADDR_ANY || type == IPV6_ADDR_RESERVED) - IP6_INC_STATS(IPSTATS_MIB_INADDRERRORS); - IP6_INC_STATS(IPSTATS_MIB_OUTNOROUTES); icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_NOROUTE, 0, skb->dev); kfree_skb(skb); diff --git a/trunk/net/ipv6/tcp_ipv6.c b/trunk/net/ipv6/tcp_ipv6.c index 802a1a6b1037..b843a650be71 100644 --- a/trunk/net/ipv6/tcp_ipv6.c +++ b/trunk/net/ipv6/tcp_ipv6.c @@ -944,7 +944,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, * comment in that function for the gory details. -acme */ - newsk->sk_gso_type = SKB_GSO_TCPV6; + sk->sk_gso_type = SKB_GSO_TCPV6; __ip6_dst_store(newsk, dst, NULL); newtcp6sk = (struct tcp6_sock *)newsk; diff --git a/trunk/net/netlink/af_netlink.c b/trunk/net/netlink/af_netlink.c index 8b85036ba8e3..b85c1f9f1288 100644 --- a/trunk/net/netlink/af_netlink.c +++ b/trunk/net/netlink/af_netlink.c @@ -1273,7 +1273,8 @@ netlink_kernel_create(int unit, unsigned int groups, struct netlink_sock *nlk; unsigned long *listeners = NULL; - BUG_ON(!nl_table); + if (!nl_table) + return NULL; if (unit<0 || unit>=MAX_LINKS) return NULL; @@ -1744,8 +1745,11 @@ static int __init netlink_proto_init(void) netlink_skb_parms_too_large(); nl_table = kcalloc(MAX_LINKS, sizeof(*nl_table), GFP_KERNEL); - if (!nl_table) - goto panic; + if (!nl_table) { +enomem: + printk(KERN_CRIT "netlink_init: Cannot allocate nl_table\n"); + return -ENOMEM; + } if (num_physpages >= (128 * 1024)) max = num_physpages >> (21 - PAGE_SHIFT); @@ -1765,7 +1769,7 @@ static int __init netlink_proto_init(void) nl_pid_hash_free(nl_table[i].hash.table, 1 * sizeof(*hash->table)); kfree(nl_table); - goto panic; + goto enomem; } memset(hash->table, 0, 1 * sizeof(*hash->table)); hash->max_shift = order; @@ -1782,8 +1786,6 @@ static int __init netlink_proto_init(void) rtnetlink_init(); out: return err; -panic: - panic("netlink_init: Cannot allocate nl_table\n"); } core_initcall(netlink_proto_init); diff --git a/trunk/net/sctp/sm_make_chunk.c b/trunk/net/sctp/sm_make_chunk.c index 17b509282cf2..4f11f5858209 100644 --- a/trunk/net/sctp/sm_make_chunk.c +++ b/trunk/net/sctp/sm_make_chunk.c @@ -806,26 +806,38 @@ struct sctp_chunk *sctp_make_abort_no_data( /* Helper to create ABORT with a SCTP_ERROR_USER_ABORT error. */ struct sctp_chunk *sctp_make_abort_user(const struct sctp_association *asoc, - const struct msghdr *msg, - size_t paylen) + const struct sctp_chunk *chunk, + const struct msghdr *msg) { struct sctp_chunk *retval; - void *payload = NULL; - int err; + void *payload = NULL, *payoff; + size_t paylen = 0; + struct iovec *iov = NULL; + int iovlen = 0; + + if (msg) { + iov = msg->msg_iov; + iovlen = msg->msg_iovlen; + paylen = get_user_iov_size(iov, iovlen); + } - retval = sctp_make_abort(asoc, NULL, sizeof(sctp_errhdr_t) + paylen); + retval = sctp_make_abort(asoc, chunk, sizeof(sctp_errhdr_t) + paylen); if (!retval) goto err_chunk; if (paylen) { /* Put the msg_iov together into payload. */ - payload = kmalloc(paylen, GFP_KERNEL); + payload = kmalloc(paylen, GFP_ATOMIC); if (!payload) goto err_payload; + payoff = payload; - err = memcpy_fromiovec(payload, msg->msg_iov, paylen); - if (err < 0) - goto err_copy; + for (; iovlen > 0; --iovlen) { + if (copy_from_user(payoff, iov->iov_base,iov->iov_len)) + goto err_copy; + payoff += iov->iov_len; + iov++; + } } sctp_init_cause(retval, SCTP_ERROR_USER_ABORT, payload, paylen); diff --git a/trunk/net/sctp/sm_statefuns.c b/trunk/net/sctp/sm_statefuns.c index 5b5ae7958322..ead3f1b0ea3d 100644 --- a/trunk/net/sctp/sm_statefuns.c +++ b/trunk/net/sctp/sm_statefuns.c @@ -4031,12 +4031,18 @@ sctp_disposition_t sctp_sf_do_9_1_prm_abort( * from its upper layer, but retransmits data to the far end * if necessary to fill gaps. */ - struct sctp_chunk *abort = arg; + struct msghdr *msg = arg; + struct sctp_chunk *abort; sctp_disposition_t retval; retval = SCTP_DISPOSITION_CONSUME; - sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort)); + /* Generate ABORT chunk to send the peer. */ + abort = sctp_make_abort_user(asoc, NULL, msg); + if (!abort) + retval = SCTP_DISPOSITION_NOMEM; + else + sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort)); /* Even if we can't send the ABORT due to low memory delete the * TCB. This is a departure from our typical NOMEM handling. @@ -4160,7 +4166,8 @@ sctp_disposition_t sctp_sf_cookie_wait_prm_abort( void *arg, sctp_cmd_seq_t *commands) { - struct sctp_chunk *abort = arg; + struct msghdr *msg = arg; + struct sctp_chunk *abort; sctp_disposition_t retval; /* Stop T1-init timer */ @@ -4168,7 +4175,12 @@ sctp_disposition_t sctp_sf_cookie_wait_prm_abort( SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT)); retval = SCTP_DISPOSITION_CONSUME; - sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort)); + /* Generate ABORT chunk to send the peer */ + abort = sctp_make_abort_user(asoc, NULL, msg); + if (!abort) + retval = SCTP_DISPOSITION_NOMEM; + else + sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort)); sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE, SCTP_STATE(SCTP_STATE_CLOSED)); diff --git a/trunk/net/sctp/socket.c b/trunk/net/sctp/socket.c index dab15949958e..54722e622e6d 100644 --- a/trunk/net/sctp/socket.c +++ b/trunk/net/sctp/socket.c @@ -1289,13 +1289,9 @@ SCTP_STATIC void sctp_close(struct sock *sk, long timeout) } } - if (sock_flag(sk, SOCK_LINGER) && !sk->sk_lingertime) { - struct sctp_chunk *chunk; - - chunk = sctp_make_abort_user(asoc, NULL, 0); - if (chunk) - sctp_primitive_ABORT(asoc, chunk); - } else + if (sock_flag(sk, SOCK_LINGER) && !sk->sk_lingertime) + sctp_primitive_ABORT(asoc, NULL); + else sctp_primitive_SHUTDOWN(asoc, NULL); } @@ -1524,16 +1520,8 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk, goto out_unlock; } if (sinfo_flags & SCTP_ABORT) { - struct sctp_chunk *chunk; - - chunk = sctp_make_abort_user(asoc, msg, msg_len); - if (!chunk) { - err = -ENOMEM; - goto out_unlock; - } - SCTP_DEBUG_PRINTK("Aborting association: %p\n", asoc); - sctp_primitive_ABORT(asoc, chunk); + sctp_primitive_ABORT(asoc, msg); err = 0; goto out_unlock; } diff --git a/trunk/net/socket.c b/trunk/net/socket.c index 6d261bf206fc..b4848ce0d6ac 100644 --- a/trunk/net/socket.c +++ b/trunk/net/socket.c @@ -1178,8 +1178,7 @@ static int __sock_create(int family, int type, int protocol, struct socket **res */ if (!(sock = sock_alloc())) { - if (net_ratelimit()) - printk(KERN_WARNING "socket: no more sockets\n"); + printk(KERN_WARNING "socket: no more sockets\n"); err = -ENFILE; /* Not exactly a match, but its the closest posix thing */ goto out; diff --git a/trunk/net/sunrpc/auth_gss/auth_gss.c b/trunk/net/sunrpc/auth_gss/auth_gss.c index ef1cf5b476c8..4a9aa9393b97 100644 --- a/trunk/net/sunrpc/auth_gss/auth_gss.c +++ b/trunk/net/sunrpc/auth_gss/auth_gss.c @@ -718,7 +718,8 @@ gss_destroy(struct rpc_auth *auth) auth, auth->au_flavor); gss_auth = container_of(auth, struct gss_auth, rpc_auth); - rpc_unlink(gss_auth->dentry); + rpc_unlink(gss_auth->path); + dput(gss_auth->dentry); gss_auth->dentry = NULL; gss_mech_put(gss_auth->mech); diff --git a/trunk/net/sunrpc/clnt.c b/trunk/net/sunrpc/clnt.c index 3e19d321067a..d6409e757219 100644 --- a/trunk/net/sunrpc/clnt.c +++ b/trunk/net/sunrpc/clnt.c @@ -183,7 +183,8 @@ rpc_new_client(struct rpc_xprt *xprt, char *servname, out_no_auth: if (!IS_ERR(clnt->cl_dentry)) { - rpc_rmdir(clnt->cl_dentry); + rpc_rmdir(clnt->cl_pathname); + dput(clnt->cl_dentry); rpc_put_mount(); } out_no_path: @@ -250,8 +251,10 @@ rpc_clone_client(struct rpc_clnt *clnt) new->cl_autobind = 0; new->cl_oneshot = 0; new->cl_dead = 0; - if (!IS_ERR(new->cl_dentry)) + if (!IS_ERR(new->cl_dentry)) { dget(new->cl_dentry); + rpc_get_mount(); + } rpc_init_rtt(&new->cl_rtt_default, clnt->cl_xprt->timeout.to_initval); if (new->cl_auth) atomic_inc(&new->cl_auth->au_count); @@ -314,15 +317,11 @@ rpc_destroy_client(struct rpc_clnt *clnt) clnt->cl_auth = NULL; } if (clnt->cl_parent != clnt) { - if (!IS_ERR(clnt->cl_dentry)) - dput(clnt->cl_dentry); rpc_destroy_client(clnt->cl_parent); goto out_free; } - if (!IS_ERR(clnt->cl_dentry)) { - rpc_rmdir(clnt->cl_dentry); - rpc_put_mount(); - } + if (clnt->cl_pathname[0]) + rpc_rmdir(clnt->cl_pathname); if (clnt->cl_xprt) { xprt_destroy(clnt->cl_xprt); clnt->cl_xprt = NULL; @@ -332,6 +331,10 @@ rpc_destroy_client(struct rpc_clnt *clnt) out_free: rpc_free_iostats(clnt->cl_metrics); clnt->cl_metrics = NULL; + if (!IS_ERR(clnt->cl_dentry)) { + dput(clnt->cl_dentry); + rpc_put_mount(); + } kfree(clnt); return 0; } @@ -1181,17 +1184,6 @@ call_verify(struct rpc_task *task) u32 *p = iov->iov_base, n; int error = -EACCES; - if ((task->tk_rqstp->rq_rcv_buf.len & 3) != 0) { - /* RFC-1014 says that the representation of XDR data must be a - * multiple of four bytes - * - if it isn't pointer subtraction in the NFS client may give - * undefined results - */ - printk(KERN_WARNING - "call_verify: XDR representation not a multiple of" - " 4 bytes: 0x%x\n", task->tk_rqstp->rq_rcv_buf.len); - goto out_eio; - } if ((len -= 3) < 0) goto out_overflow; p += 1; /* skip XID */ diff --git a/trunk/net/sunrpc/rpc_pipe.c b/trunk/net/sunrpc/rpc_pipe.c index 0b1a1ac8a4bc..a3bd2db2e024 100644 --- a/trunk/net/sunrpc/rpc_pipe.c +++ b/trunk/net/sunrpc/rpc_pipe.c @@ -539,7 +539,6 @@ rpc_depopulate(struct dentry *parent) rpc_close_pipes(dentry->d_inode); simple_unlink(dir, dentry); } - inode_dir_notify(dir, DN_DELETE); dput(dentry); } while (n); goto repeat; @@ -611,8 +610,8 @@ __rpc_rmdir(struct inode *dir, struct dentry *dentry) int error; shrink_dcache_parent(dentry); - if (d_unhashed(dentry)) - return 0; + if (dentry->d_inode) + rpc_close_pipes(dentry->d_inode); if ((error = simple_rmdir(dir, dentry)) != 0) return error; if (!error) { @@ -685,20 +684,28 @@ rpc_mkdir(char *path, struct rpc_clnt *rpc_client) } int -rpc_rmdir(struct dentry *dentry) +rpc_rmdir(char *path) { - struct dentry *parent; + struct nameidata nd; + struct dentry *dentry; struct inode *dir; int error; - parent = dget_parent(dentry); - dir = parent->d_inode; + if ((error = rpc_lookup_parent(path, &nd)) != 0) + return error; + dir = nd.dentry->d_inode; mutex_lock_nested(&dir->i_mutex, I_MUTEX_PARENT); + dentry = lookup_one_len(nd.last.name, nd.dentry, nd.last.len); + if (IS_ERR(dentry)) { + error = PTR_ERR(dentry); + goto out_release; + } rpc_depopulate(dentry); error = __rpc_rmdir(dir, dentry); dput(dentry); +out_release: mutex_unlock(&dir->i_mutex); - dput(parent); + rpc_release_path(&nd); return error; } @@ -739,26 +746,32 @@ rpc_mkpipe(char *path, void *private, struct rpc_pipe_ops *ops, int flags) } int -rpc_unlink(struct dentry *dentry) +rpc_unlink(char *path) { - struct dentry *parent; + struct nameidata nd; + struct dentry *dentry; struct inode *dir; - int error = 0; + int error; - parent = dget_parent(dentry); - dir = parent->d_inode; + if ((error = rpc_lookup_parent(path, &nd)) != 0) + return error; + dir = nd.dentry->d_inode; mutex_lock_nested(&dir->i_mutex, I_MUTEX_PARENT); - if (!d_unhashed(dentry)) { - d_drop(dentry); - if (dentry->d_inode) { - rpc_close_pipes(dentry->d_inode); - error = simple_unlink(dir, dentry); - } - inode_dir_notify(dir, DN_DELETE); + dentry = lookup_one_len(nd.last.name, nd.dentry, nd.last.len); + if (IS_ERR(dentry)) { + error = PTR_ERR(dentry); + goto out_release; + } + d_drop(dentry); + if (dentry->d_inode) { + rpc_close_pipes(dentry->d_inode); + error = simple_unlink(dir, dentry); } dput(dentry); + inode_dir_notify(dir, DN_DELETE); +out_release: mutex_unlock(&dir->i_mutex); - dput(parent); + rpc_release_path(&nd); return error; } diff --git a/trunk/sound/oss/Kconfig b/trunk/sound/oss/Kconfig index 97e38b665587..1b7c3dfc2b41 100644 --- a/trunk/sound/oss/Kconfig +++ b/trunk/sound/oss/Kconfig @@ -5,20 +5,6 @@ # # Prompt user for primary drivers. -config OSS_OBSOLETE_DRIVER - bool "Obsolete OSS drivers" - depends on SOUND_PRIME - help - This option enables support for obsolete OSS drivers that - are scheduled for removal in the near future since there - are ALSA drivers for the same hardware. - - Please contact Adrian Bunk if you had to - say Y here because your soundcard is not properly supported - by ALSA. - - If unsure, say N. - config SOUND_BT878 tristate "BT878 audio dma" depends on SOUND_PRIME && PCI @@ -37,7 +23,7 @@ config SOUND_BT878 config SOUND_EMU10K1 tristate "Creative SBLive! (EMU10K1)" - depends on SOUND_PRIME && PCI && OSS_OBSOLETE_DRIVER + depends on SOUND_PRIME && PCI ---help--- Say Y or M if you have a PCI sound card using the EMU10K1 chipset, such as the Creative SBLive!, SB PCI512 or Emu-APS. @@ -63,7 +49,7 @@ config MIDI_EMU10K1 config SOUND_FUSION tristate "Crystal SoundFusion (CS4280/461x)" - depends on SOUND_PRIME && PCI && OSS_OBSOLETE_DRIVER + depends on SOUND_PRIME && PCI help This module drives the Crystal SoundFusion devices (CS4280/46xx series) when wired as native sound drivers with AC97 codecs. If @@ -454,7 +440,7 @@ config SOUND_DMAP config SOUND_AD1816 tristate "AD1816(A) based cards (EXPERIMENTAL)" - depends on EXPERIMENTAL && SOUND_OSS && OSS_OBSOLETE_DRIVER + depends on EXPERIMENTAL && SOUND_OSS help Say M here if you have a sound card based on the Analog Devices AD1816(A) chip. @@ -464,21 +450,21 @@ config SOUND_AD1816 config SOUND_AD1889 tristate "AD1889 based cards (AD1819 codec) (EXPERIMENTAL)" - depends on EXPERIMENTAL && SOUND_OSS && PCI && OSS_OBSOLETE_DRIVER + depends on EXPERIMENTAL && SOUND_OSS && PCI help Say M here if you have a sound card based on the Analog Devices AD1889 chip. config SOUND_ADLIB tristate "Adlib Cards" - depends on SOUND_OSS && OSS_OBSOLETE_DRIVER + depends on SOUND_OSS help Includes ASB 64 4D. Information on programming AdLib cards is available at . config SOUND_ACI_MIXER tristate "ACI mixer (miroSOUND PCM1-pro/PCM12/PCM20)" - depends on SOUND_OSS && OSS_OBSOLETE_DRIVER + depends on SOUND_OSS ---help--- ACI (Audio Command Interface) is a protocol used to communicate with the microcontroller on some sound cards produced by miro and @@ -600,7 +586,7 @@ config SOUND_MPU401 config SOUND_NM256 tristate "NM256AV/NM256ZX audio support" - depends on SOUND_OSS && OSS_OBSOLETE_DRIVER + depends on SOUND_OSS help Say M here to include audio support for the NeoMagic 256AV/256ZX chipsets. These are the audio chipsets found in the Sony @@ -720,7 +706,7 @@ config SOUND_YM3812 config SOUND_OPL3SA2 tristate "Yamaha OPL3-SA2 and SA3 based PnP cards" - depends on SOUND_OSS && OSS_OBSOLETE_DRIVER + depends on SOUND_OSS help Say Y or M if you have a card based on one of these Yamaha sound chipsets or the "SAx", which is actually a SA3. Read diff --git a/trunk/sound/pci/ac97/ac97_codec.c b/trunk/sound/pci/ac97/ac97_codec.c index 51e83d7a839a..0abf2808d59f 100644 --- a/trunk/sound/pci/ac97/ac97_codec.c +++ b/trunk/sound/pci/ac97/ac97_codec.c @@ -573,7 +573,7 @@ AC97_SINGLE("PC Speaker Playback Volume", AC97_PC_BEEP, 1, 15, 1) }; static const struct snd_kcontrol_new snd_ac97_controls_mic_boost = - AC97_SINGLE("Mic Boost (+20dB)", AC97_MIC, 6, 1, 0); + AC97_SINGLE("Mic Boost (+20dB) Switch", AC97_MIC, 6, 1, 0); static const char* std_rec_sel[] = {"Mic", "CD", "Video", "Aux", "Line", "Mix", "Mix Mono", "Phone"}; @@ -615,7 +615,7 @@ AC97_SINGLE("Simulated Stereo Enhancement", AC97_GENERAL_PURPOSE, 14, 1, 0), AC97_SINGLE("3D Control - Switch", AC97_GENERAL_PURPOSE, 13, 1, 0), AC97_SINGLE("Loudness (bass boost)", AC97_GENERAL_PURPOSE, 12, 1, 0), AC97_ENUM("Mono Output Select", std_enum[2]), -AC97_ENUM("Mic Select", std_enum[3]), +AC97_ENUM("Mic Select Capture Switch", std_enum[3]), AC97_SINGLE("ADC/DAC Loopback", AC97_GENERAL_PURPOSE, 7, 1, 0) };