From 4e76c8a9fa413ccc09d3f7f664183dcce3555d57 Mon Sep 17 00:00:00 2001 From: Marc Fiuczynski Date: Thu, 19 Oct 2006 02:13:07 +0000 Subject: [PATCH] Merge to Fedora kernel-2.6.17-1.2187_FC5 patched with stable patch-2.6.17.13-vs2.0.2.1.diff --- .config | 2703 ++++++++++----- .config.old | 1609 ++++++--- Documentation/networking/netdevices.txt | 8 +- MAINTAINERS | 8 + arch/i386/Kconfig | 95 +- arch/i386/Kconfig.cpu | 2 +- arch/i386/Kconfig.debug | 1 + arch/i386/Makefile | 24 + arch/i386/kernel/Makefile | 22 +- arch/i386/kernel/acpi/Makefile | 4 + arch/i386/kernel/asm-offsets.c | 9 +- arch/i386/kernel/cpu/Makefile | 5 + arch/i386/kernel/cpu/cpufreq/powernow-k7.c | 1 - arch/i386/kernel/cpu/cpufreq/powernow-k8.c | 2 +- arch/i386/kernel/cpu/mtrr/Makefile | 7 + arch/i386/kernel/entry.S | 10 +- arch/i386/kernel/irq.c | 4 +- arch/i386/kernel/reboot.c | 8 - arch/i386/kernel/sysenter.c | 32 +- arch/i386/kernel/traps.c | 9 +- arch/i386/kernel/vm86.c | 12 + arch/i386/mm/Makefile | 8 + arch/i386/mm/pageattr.c | 2 +- arch/i386/mm/pgtable.c | 12 + arch/i386/oprofile/Makefile | 4 + arch/i386/pci/Makefile | 9 + arch/i386/pci/mmconfig.c | 9 +- arch/i386/power/Makefile | 4 +- arch/ia64/Kconfig | 3 + arch/ia64/kernel/sys_ia64.c | 28 +- arch/ia64/sn/kernel/xpc_channel.c | 4 +- arch/ia64/sn/kernel/xpc_main.c | 28 +- arch/ia64/sn/kernel/xpc_partition.c | 24 +- arch/powerpc/Kconfig | 3 + arch/powerpc/kernel/cpu_setup_power4.S | 2 + arch/powerpc/kernel/crash.c | 13 + arch/powerpc/platforms/pseries/xics.c | 25 +- arch/sparc/kernel/sys_sparc.c | 27 +- arch/sparc64/kernel/sys_sparc.c | 36 +- arch/sparc64/mm/generic.c | 2 + arch/um/kernel/physmem.c | 4 +- arch/x86_64/Kconfig | 64 +- arch/x86_64/Makefile | 20 + arch/x86_64/ia32/Makefile | 20 +- arch/x86_64/ia32/vsyscall-sigreturn.S | 2 +- arch/x86_64/kernel/Makefile | 19 +- arch/x86_64/kernel/acpi/Makefile | 1 + arch/x86_64/kernel/asm-offsets.c | 2 + arch/x86_64/kernel/entry.S | 2 +- arch/x86_64/kernel/init_task.c | 3 + arch/x86_64/kernel/irq.c | 4 +- arch/x86_64/kernel/pmtimer.c | 2 + arch/x86_64/kernel/setup.c | 2 +- arch/x86_64/kernel/setup64.c | 23 +- arch/x86_64/kernel/smp.c | 4 +- arch/x86_64/mm/Makefile | 10 + arch/x86_64/oprofile/Makefile | 5 +- arch/x86_64/pci/Makefile | 12 + arch/x86_64/pci/mmconfig.c | 13 +- block/elevator.c | 3 +- block/ll_rw_blk.c | 2 +- configs/kernel-2.6.17-i586.config | 28 +- configs/kernel-2.6.17-i686-smp.config | 20 +- configs/kernel-2.6.17-i686.config | 20 +- drivers/Makefile | 1 + drivers/acpi/Kconfig | 3 +- drivers/acpi/namespace/nsxfeval.c | 5 +- drivers/block/aoe/aoenet.c | 3 +- drivers/cdrom/cdrom.c | 2 +- drivers/char/mem.c | 38 +- drivers/char/tpm/tpm_tis.c | 1 + drivers/char/tty_io.c | 34 +- drivers/firmware/Kconfig | 2 +- drivers/i2c/busses/scx200_acb.c | 20 +- drivers/i2c/i2c-core.c | 4 +- drivers/ide/ide-lib.c | 8 +- drivers/ide/pci/via82cxxx.c | 3 +- drivers/ieee1394/ohci1394.c | 4 +- drivers/ieee1394/sbp2.c | 3 + drivers/infiniband/hw/mthca/mthca_reset.c | 59 + .../infiniband/ulp/ipoib/ipoib_multicast.c | 6 +- drivers/md/dm-exception-store.c | 65 +- drivers/md/dm-ioctl.c | 34 +- drivers/md/dm-mpath.c | 3 +- drivers/md/dm-raid1.c | 67 +- drivers/md/dm-snap.c | 6 +- drivers/md/dm.c | 101 +- drivers/md/raid1.c | 4 +- drivers/media/dvb/bt8xx/dvb-bt8xx.c | 10 + drivers/media/dvb/bt8xx/dvb-bt8xx.h | 1 + drivers/media/dvb/dvb-core/dvb_frontend.c | 14 +- drivers/media/dvb/dvb-core/dvb_net.c | 4 +- drivers/media/dvb/frontends/dvb-pll.c | 10 +- drivers/media/dvb/ttpci/budget-av.c | 24 +- drivers/media/dvb/ttpci/budget.c | 6 - drivers/media/video/Kconfig | 6 +- drivers/media/video/stradis.c | 1 - drivers/net/8139cp.c | 2 +- drivers/net/bnx2.c | 8 +- drivers/net/bonding/bond_main.c | 9 +- drivers/net/chelsio/sge.c | 4 +- drivers/net/e1000/e1000_hw.c | 1 + drivers/net/e1000/e1000_hw.h | 1 + drivers/net/e1000/e1000_main.c | 11 +- drivers/net/forcedeth.c | 26 +- drivers/net/hamradio/6pack.c | 8 +- drivers/net/hamradio/mkiss.c | 8 +- drivers/net/ifb.c | 10 +- drivers/net/irda/vlsi_ir.c | 2 +- drivers/net/ixgb/ixgb_main.c | 4 +- drivers/net/loopback.c | 4 +- drivers/net/mv643xx_eth.c | 2 +- drivers/net/natsemi.c | 4 +- drivers/net/r8169.c | 2 +- drivers/net/s2io.c | 16 +- drivers/net/sky2.c | 114 +- drivers/net/sky2.h | 17 +- drivers/net/tg3.c | 16 +- drivers/net/tg3.h | 1 + drivers/net/tulip/winbond-840.c | 9 +- drivers/net/typhoon.c | 6 +- drivers/net/via-velocity.c | 16 +- drivers/net/wireless/orinoco.c | 4 +- drivers/net/wireless/spectrum_cs.c | 2 +- drivers/oprofile/buffer_sync.c | 66 +- drivers/oprofile/cpu_buffer.c | 51 +- drivers/oprofile/cpu_buffer.h | 9 +- drivers/oprofile/event_buffer.h | 7 +- drivers/oprofile/oprof.c | 34 +- drivers/oprofile/oprof.h | 7 +- drivers/oprofile/oprofile_files.c | 205 +- drivers/pci/Kconfig | 1 + drivers/pci/quirks.c | 2 +- drivers/pnp/resource.c | 3 +- drivers/s390/net/qeth_eddp.c | 12 +- drivers/s390/net/qeth_main.c | 8 +- drivers/s390/net/qeth_tso.h | 2 +- drivers/scsi/Makefile | 2 +- drivers/scsi/iscsi_tcp.c | 3006 +++++++++++------ drivers/scsi/iscsi_tcp.h | 190 +- drivers/scsi/scsi_ioctl.c | 5 +- drivers/scsi/scsi_transport_iscsi.c | 705 ++-- drivers/serial/8250.c | 42 +- drivers/serial/Kconfig | 2 + drivers/serial/serial_core.c | 12 +- drivers/usb/host/uhci-q.c | 8 +- drivers/usb/serial/ftdi_sio.c | 84 +- drivers/usb/storage/unusual_devs.h | 12 +- drivers/usb/storage/usb.c | 18 +- drivers/video/Kconfig | 2 +- drivers/video/console/softcursor.c | 6 +- drivers/xen/Makefile | 16 +- drivers/xen/balloon/balloon.c | 749 ++-- drivers/xen/blkback/Makefile | 3 +- drivers/xen/blkback/blkback.c | 1079 +++--- drivers/xen/blkback/common.h | 176 +- drivers/xen/blkback/interface.c | 352 +- drivers/xen/blkback/vbd.c | 338 +- drivers/xen/blkfront/Makefile | 4 +- drivers/xen/blkfront/blkfront.c | 1951 ++++------- drivers/xen/blkfront/block.h | 119 +- drivers/xen/blkfront/vbd.c | 635 ++-- drivers/xen/blktap/Makefile | 4 +- drivers/xen/blktap/blktap.c | 1473 +++++++- drivers/xen/console/Makefile | 2 +- drivers/xen/console/console.c | 1009 +++--- drivers/xen/evtchn/evtchn.c | 654 ++-- drivers/xen/netback/Makefile | 5 +- drivers/xen/netback/common.h | 175 +- drivers/xen/netback/interface.c | 617 ++-- drivers/xen/netback/netback.c | 1806 ++++++---- drivers/xen/netfront/Makefile | 4 +- drivers/xen/netfront/netfront.c | 2687 +++++++++------ drivers/xen/privcmd/Makefile | 2 +- drivers/xen/privcmd/privcmd.c | 394 ++- fs/Kconfig | 1 + fs/befs/linuxvfs.c | 11 +- fs/binfmt_elf.c | 15 +- fs/buffer.c | 7 +- fs/ext2/super.c | 41 + fs/ext3/inode.c | 19 +- fs/ext3/namei.c | 15 +- fs/ext3/super.c | 40 + fs/file.c | 4 +- fs/locks.c | 6 +- fs/namei.c | 8 +- fs/proc/base.c | 35 +- fs/splice.c | 230 +- fs/udf/super.c | 2 +- fs/udf/truncate.c | 64 +- fs/xfs/xfs_dir2_node.c | 2 +- include/asm-generic/mman.h | 6 + include/asm-i386/apic.h | 2 + include/asm-i386/desc.h | 2 +- include/asm-i386/fixmap.h | 4 +- include/asm-i386/mach-default/mach_traps.h | 12 + include/asm-i386/page.h | 2 +- include/asm-i386/pgtable-2level-defs.h | 2 + include/asm-i386/pgtable-3level-defs.h | 2 + include/asm-i386/spinlock.h | 2 +- include/asm-ia64/mman.h | 8 + include/asm-ia64/sn/xp.h | 22 +- include/asm-ia64/sn/xpc.h | 4 +- include/asm-s390/futex.h | 5 +- include/asm-sparc/mman.h | 6 + include/asm-sparc64/mman.h | 6 + include/asm-sparc64/sfp-machine.h | 2 +- include/asm-um/page.h | 2 +- include/asm-x86_64/apic.h | 2 + include/asm-x86_64/hw_irq.h | 2 +- include/asm-x86_64/ipi.h | 2 + include/asm-x86_64/pgtable.h | 2 +- include/linux/autoconf.h | 2703 ++++++++++----- include/linux/ethtool.h | 2 + include/linux/ext3_fs.h | 9 + include/linux/gfp.h | 6 +- include/linux/highmem.h | 6 + include/linux/idr.h | 1 + include/linux/interrupt.h | 6 + include/linux/mm.h | 10 + include/linux/netdevice.h | 74 +- include/linux/netfilter_bridge.h | 16 +- include/linux/oprofile.h | 11 + include/linux/pci_ids.h | 5 +- include/linux/pfn.h | 2 +- include/linux/skbuff.h | 97 +- include/linux/tty.h | 2 - include/net/pkt_sched.h | 7 +- include/net/protocol.h | 3 + include/net/sctp/sctp.h | 13 - include/net/sctp/sm.h | 3 +- include/net/sock.h | 4 + include/net/tcp.h | 7 +- include/scsi/iscsi_if.h | 128 +- include/scsi/iscsi_proto.h | 2 + include/scsi/scsi_transport_iscsi.h | 119 +- include/sound/initval.h | 3 +- kernel/Kconfig.preempt | 1 + kernel/fork.c | 3 + kernel/futex.c | 1 + kernel/irq/manage.c | 26 +- kernel/irq/spurious.c | 3 +- kernel/sched.c | 25 +- kernel/stop_machine.c | 1 - kernel/timer.c | 60 +- lib/Makefile | 3 + lib/idr.c | 43 + lib/spinlock_debug.c | 10 +- lib/ts_bm.c | 11 +- mm/Kconfig | 8 +- mm/filemap.c | 34 +- mm/filemap.h | 4 +- mm/highmem.c | 11 + mm/memory.c | 119 +- mm/mmap.c | 17 +- mm/page_alloc.c | 11 +- mm/pdflush.c | 15 +- mm/swapfile.c | 3 +- net/8021q/vlan.c | 8 +- net/atm/clip.c | 8 +- net/bridge/br_device.c | 8 +- net/bridge/br_forward.c | 12 +- net/bridge/br_if.c | 23 +- net/bridge/br_netfilter.c | 7 +- net/bridge/netfilter/ebt_ulog.c | 3 + net/core/dev.c | 289 +- net/core/dev_mcast.c | 28 +- net/core/dst.c | 3 +- net/core/ethtool.c | 39 +- net/core/netpoll.c | 9 +- net/core/pktgen.c | 12 +- net/core/rtnetlink.c | 15 +- net/core/skbuff.c | 285 +- net/decnet/dn_nsp_in.c | 3 +- net/decnet/dn_route.c | 3 +- net/decnet/dn_rules.c | 3 +- net/ieee80211/Kconfig | 1 + net/ipv4/af_inet.c | 87 + net/ipv4/fib_rules.c | 4 +- net/ipv4/fib_semantics.c | 12 +- net/ipv4/ip_output.c | 22 +- net/ipv4/ipcomp.c | 11 +- net/ipv4/netfilter/arp_tables.c | 3 +- net/ipv4/netfilter/ip_conntrack_helper_h323.c | 2 +- net/ipv4/netfilter/ip_nat_proto_tcp.c | 7 +- net/ipv4/netfilter/ip_nat_proto_udp.c | 10 +- net/ipv4/netfilter/ip_tables.c | 3 +- net/ipv4/netfilter/ipt_ULOG.c | 5 + net/ipv4/route.c | 2 +- net/ipv4/tcp.c | 86 +- net/ipv4/tcp_input.c | 2 +- net/ipv4/tcp_ipv4.c | 18 + net/ipv4/tcp_output.c | 48 +- net/ipv4/xfrm4_output.c | 60 +- net/ipv6/addrconf.c | 2 + net/ipv6/exthdrs.c | 29 +- net/ipv6/ip6_output.c | 9 +- net/ipv6/ipcomp6.c | 11 +- net/ipv6/xfrm6_output.c | 39 +- net/ipx/af_ipx.c | 3 +- net/netfilter/nfnetlink_log.c | 3 + net/sched/act_api.c | 18 +- net/sched/sch_generic.c | 66 +- net/sched/sch_teql.c | 9 +- net/sctp/sm_make_chunk.c | 30 +- net/sctp/sm_statefuns.c | 20 +- net/sctp/socket.c | 20 +- net/sunrpc/cache.c | 6 +- scripts/basic/.docproc.cmd | 17 +- scripts/basic/.fixdep.cmd | 16 +- scripts/basic/.split-include.cmd | 12 +- scripts/basic/docproc | Bin 19832 -> 13404 bytes scripts/basic/fixdep | Bin 15691 -> 8881 bytes scripts/basic/split-include | Bin 14592 -> 7891 bytes scripts/kconfig/.conf.cmd | 2 +- scripts/kconfig/.conf.o.cmd | 32 +- scripts/kconfig/.kxgettext.o.cmd | 10 +- scripts/kconfig/.mconf.o.cmd | 24 +- scripts/kconfig/.zconf.tab.o.cmd | 31 +- scripts/kconfig/conf | Bin 20591 -> 67464 bytes scripts/kconfig/conf.o | Bin 10348 -> 11136 bytes scripts/kconfig/kxgettext.o | Bin 2324 -> 2416 bytes scripts/kconfig/lex.zconf.c | 1805 ++-------- scripts/kconfig/mconf.o | Bin 20532 -> 29292 bytes scripts/kconfig/zconf.tab.c | 1182 +++---- scripts/kconfig/zconf.tab.o | Bin 95696 -> 66344 bytes sound/core/oss/pcm_oss.c | 2 + sound/core/timer.c | 5 +- sound/isa/cs423x/Makefile | 1 + sound/pci/Kconfig | 14 +- sound/pci/au88x0/au88x0_mpu401.c | 2 +- sound/pci/fm801.c | 2 +- sound/pci/hda/hda_intel.c | 4 +- sound/pci/hda/patch_analog.c | 19 +- sound/pci/hda/patch_realtek.c | 2 +- sound/pci/hda/patch_sigmatel.c | 8 +- sound/pci/rme9652/hdsp.c | 5 +- 337 files changed, 19517 insertions(+), 14046 deletions(-) diff --git a/.config b/.config index de7e3e791..409409530 100644 --- a/.config +++ b/.config @@ -1,40 +1,61 @@ # # Automatically generated make config: don't edit +# Linux kernel version: 2.6.17.13 +# Wed Oct 18 17:15:54 2006 # +CONFIG_X86_32=y +CONFIG_SEMAPHORE_SLEEPERS=y CONFIG_X86=y CONFIG_MMU=y -CONFIG_UID16=y CONFIG_GENERIC_ISA_DMA=y +CONFIG_GENERIC_IOMAP=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_ARCH_MAY_HAVE_PC_FDC=y +CONFIG_DMI=y # # Code maturity level options # CONFIG_EXPERIMENTAL=y -CONFIG_CLEAN_COMPILE=y -CONFIG_STANDALONE=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 # # General setup # +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y CONFIG_BSD_PROCESS_ACCT=y +# CONFIG_BSD_PROCESS_ACCT_V3 is not set CONFIG_SYSCTL=y -# CONFIG_AUDIT is not set -CONFIG_LOG_BUF_SHIFT=17 -CONFIG_HOTPLUG=y +CONFIG_AUDIT=y +CONFIG_AUDITSYSCALL=y # CONFIG_IKCONFIG is not set +CONFIG_RELAY=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_UID16=y +CONFIG_VM86=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y # CONFIG_EMBEDDED is not set CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set +CONFIG_KALLSYMS_EXTRA_PASS=y +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y -CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SHMEM=y +CONFIG_SLAB=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 +# CONFIG_SLOB is not set +CONFIG_OBSOLETE_INTERMODULE=m # # Loadable module support @@ -42,24 +63,46 @@ CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set -CONFIG_OBSOLETE_MODPARM=y -# CONFIG_MODVERSIONS is not set +CONFIG_MODVERSIONS=y +CONFIG_MODULE_SRCVERSION_ALL=y +CONFIG_MODULE_SIG=y +# CONFIG_MODULE_SIG_FORCE is not set CONFIG_KMOD=y -CONFIG_STOP_MACHINE=y + +# +# Block layer +# +CONFIG_LBD=y +CONFIG_BLK_DEV_IO_TRACE=y +CONFIG_LSF=y + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" # # Processor type and features # -# CONFIG_X86_PC is not set +# CONFIG_SMP is not set +CONFIG_X86_PC=y +# CONFIG_X86_XEN is not set # CONFIG_X86_ELAN is not set # CONFIG_X86_VOYAGER is not set # CONFIG_X86_NUMAQ is not set # CONFIG_X86_SUMMIT is not set # CONFIG_X86_BIGSMP is not set # CONFIG_X86_VISWS is not set -CONFIG_X86_GENERICARCH=y +# CONFIG_X86_GENERICARCH is not set # CONFIG_X86_ES7000 is not set -CONFIG_X86_CYCLONE_TIMER=y # CONFIG_M386 is not set # CONFIG_M486 is not set # CONFIG_M586 is not set @@ -74,9 +117,12 @@ CONFIG_M686=y # CONFIG_MK7 is not set # CONFIG_MK8 is not set # CONFIG_MCRUSOE is not set +# CONFIG_MEFFICEON is not set # CONFIG_MWINCHIPC6 is not set # CONFIG_MWINCHIP2 is not set # CONFIG_MWINCHIP3D is not set +# CONFIG_MGEODEGX1 is not set +# CONFIG_MGEODE_LX is not set # CONFIG_MCYRIXIII is not set # CONFIG_MVIAC3_2 is not set CONFIG_X86_GENERIC=y @@ -84,85 +130,111 @@ CONFIG_X86_CMPXCHG=y CONFIG_X86_XADD=y CONFIG_X86_L1_CACHE_SHIFT=7 CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_X86_PPRO_FENCE=y CONFIG_X86_WP_WORKS_OK=y CONFIG_X86_INVLPG=y CONFIG_X86_BSWAP=y CONFIG_X86_POPAD_OK=y +CONFIG_X86_CMPXCHG64=y CONFIG_X86_GOOD_APIC=y CONFIG_X86_INTEL_USERCOPY=y CONFIG_X86_USE_PPRO_CHECKSUM=y -CONFIG_X86_4G=y -CONFIG_X86_SWITCH_PAGETABLES=y -CONFIG_X86_4G_VM_LAYOUT=y -CONFIG_X86_UACCESS_INDIRECT=y -CONFIG_X86_HIGH_ENTRY=y +CONFIG_X86_TSC=y CONFIG_HPET_TIMER=y CONFIG_HPET_EMULATE_RTC=y -CONFIG_SMP=y -CONFIG_NR_CPUS=32 -CONFIG_SCHED_SMT=y +# CONFIG_PREEMPT_NONE is not set +CONFIG_PREEMPT_VOLUNTARY=y # CONFIG_PREEMPT is not set +CONFIG_X86_UP_APIC=y +CONFIG_X86_UP_IOAPIC=y CONFIG_X86_LOCAL_APIC=y CONFIG_X86_IO_APIC=y -CONFIG_X86_TSC=y CONFIG_X86_MCE=y # CONFIG_X86_MCE_NONFATAL is not set CONFIG_X86_MCE_P4THERMAL=y CONFIG_TOSHIBA=m CONFIG_I8K=m +# CONFIG_X86_REBOOTFIXUPS is not set CONFIG_MICROCODE=m CONFIG_X86_MSR=m CONFIG_X86_CPUID=m +# CONFIG_SWIOTLB is not set # # Firmware Drivers # CONFIG_EDD=m +CONFIG_EFI_VARS=y +CONFIG_DELL_RBU=m +CONFIG_DCDBAS=m # CONFIG_NOHIGHMEM is not set -# CONFIG_HIGHMEM4G is not set -CONFIG_HIGHMEM64G=y +CONFIG_HIGHMEM4G=y +# CONFIG_HIGHMEM64G is not set +CONFIG_PAGE_OFFSET=0xC0000000 CONFIG_HIGHMEM=y -CONFIG_X86_PAE=y -# CONFIG_NUMA is not set +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_SPARSEMEM_STATIC=y +CONFIG_SPLIT_PTLOCK_CPUS=4096 CONFIG_HIGHPTE=y # CONFIG_MATH_EMULATION is not set CONFIG_MTRR=y -# CONFIG_EFI is not set -# CONFIG_IRQBALANCE is not set -CONFIG_HAVE_DEC_LOCK=y +CONFIG_EFI=y +CONFIG_BOOT_IOREMAP=y CONFIG_REGPARM=y +# CONFIG_SECCOMP is not set +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_1000 is not set +CONFIG_HZ=250 +CONFIG_KEXEC=y +# CONFIG_CRASH_DUMP is not set +CONFIG_PHYSICAL_START=0x400000 +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y # # Power management options (ACPI, APM) # CONFIG_PM=y -# CONFIG_SOFTWARE_SUSPEND is not set -# CONFIG_PM_DISK is not set +CONFIG_PM_LEGACY=y +CONFIG_PM_DEBUG=y +CONFIG_SOFTWARE_SUSPEND=y +CONFIG_PM_STD_PARTITION="" # # ACPI (Advanced Configuration and Power Interface) Support # CONFIG_ACPI=y -CONFIG_ACPI_BOOT=y -CONFIG_ACPI_INTERPRETER=y CONFIG_ACPI_SLEEP=y CONFIG_ACPI_SLEEP_PROC_FS=y +# CONFIG_ACPI_SLEEP_PROC_SLEEP is not set CONFIG_ACPI_AC=m CONFIG_ACPI_BATTERY=m CONFIG_ACPI_BUTTON=m +CONFIG_ACPI_VIDEO=m +# CONFIG_ACPI_HOTKEY is not set CONFIG_ACPI_FAN=y CONFIG_ACPI_PROCESSOR=y CONFIG_ACPI_THERMAL=y CONFIG_ACPI_ASUS=m +CONFIG_ACPI_IBM=m +CONFIG_ACPI_IBM_DOCK=y CONFIG_ACPI_TOSHIBA=m +CONFIG_ACPI_BLACKLIST_YEAR=1999 # CONFIG_ACPI_DEBUG is not set -CONFIG_ACPI_BUS=y CONFIG_ACPI_EC=y CONFIG_ACPI_POWER=y -CONFIG_ACPI_PCI=y CONFIG_ACPI_SYSTEM=y CONFIG_X86_PM_TIMER=y +# CONFIG_ACPI_CONTAINER is not set # # APM (Advanced Power Management) BIOS Support @@ -180,34 +252,43 @@ CONFIG_APM_RTC_IS_GMT=y # CPU Frequency scaling # CONFIG_CPU_FREQ=y -# CONFIG_CPU_FREQ_PROC_INTF is not set +CONFIG_CPU_FREQ_TABLE=y +CONFIG_CPU_FREQ_DEBUG=y +CONFIG_CPU_FREQ_STAT=m +CONFIG_CPU_FREQ_STAT_DETAILS=y # CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y CONFIG_CPU_FREQ_GOV_PERFORMANCE=y CONFIG_CPU_FREQ_GOV_POWERSAVE=m CONFIG_CPU_FREQ_GOV_USERSPACE=y -# CONFIG_CPU_FREQ_24_API is not set -CONFIG_CPU_FREQ_TABLE=y +CONFIG_CPU_FREQ_GOV_ONDEMAND=m +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m # # CPUFreq processor drivers # CONFIG_X86_ACPI_CPUFREQ=m -# CONFIG_X86_ACPI_CPUFREQ_PROC_INTF is not set -CONFIG_X86_POWERNOW_K6=m +# CONFIG_X86_POWERNOW_K6 is not set CONFIG_X86_POWERNOW_K7=y -CONFIG_X86_POWERNOW_K8=m +CONFIG_X86_POWERNOW_K7_ACPI=y +CONFIG_X86_POWERNOW_K8=y +CONFIG_X86_POWERNOW_K8_ACPI=y # CONFIG_X86_GX_SUSPMOD is not set CONFIG_X86_SPEEDSTEP_CENTRINO=y -CONFIG_X86_SPEEDSTEP_CENTRINO_TABLE=y CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI=y +CONFIG_X86_SPEEDSTEP_CENTRINO_TABLE=y CONFIG_X86_SPEEDSTEP_ICH=y -CONFIG_X86_SPEEDSTEP_SMI=m +CONFIG_X86_SPEEDSTEP_SMI=y CONFIG_X86_P4_CLOCKMOD=m +# CONFIG_X86_CPUFREQ_NFORCE2 is not set +CONFIG_X86_LONGRUN=y + +# +# shared options +# +# CONFIG_X86_ACPI_CPUFREQ_PROC_INTF is not set CONFIG_X86_SPEEDSTEP_LIB=y # CONFIG_X86_SPEEDSTEP_RELAXED_CAP_CHECK is not set -CONFIG_X86_LONGRUN=y -# CONFIG_X86_LONGHAUL is not set # # Bus options (PCI, PCMCIA, EISA, MCA, ISA) @@ -216,810 +297,1029 @@ CONFIG_PCI=y # CONFIG_PCI_GOBIOS is not set # CONFIG_PCI_GOMMCONFIG is not set # CONFIG_PCI_GODIRECT is not set +# CONFIG_PCI_GOXEN_FE is not set CONFIG_PCI_GOANY=y CONFIG_PCI_BIOS=y CONFIG_PCI_DIRECT=y CONFIG_PCI_MMCONFIG=y -CONFIG_PCI_USE_VECTOR=y -CONFIG_PCI_LEGACY_PROC=y -# CONFIG_PCI_NAMES is not set +CONFIG_PCIEPORTBUS=y +CONFIG_HOTPLUG_PCI_PCIE=m +# CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE is not set +CONFIG_PCI_MSI=y +# CONFIG_PCI_DEBUG is not set +CONFIG_ISA_DMA_API=y CONFIG_ISA=y # CONFIG_EISA is not set # CONFIG_MCA is not set # CONFIG_SCx200 is not set # -# PCMCIA/CardBus support +# PCCARD (PCMCIA/CardBus) support # -CONFIG_PCMCIA=m +CONFIG_PCCARD=y # CONFIG_PCMCIA_DEBUG is not set -CONFIG_YENTA=m +CONFIG_PCMCIA=y +CONFIG_PCMCIA_LOAD_CIS=y +CONFIG_PCMCIA_IOCTL=y CONFIG_CARDBUS=y + +# +# PC-card bridges +# +CONFIG_YENTA=y +CONFIG_YENTA_O2=y +CONFIG_YENTA_RICOH=y +CONFIG_YENTA_TI=y +CONFIG_YENTA_ENE_TUNE=y +CONFIG_YENTA_TOSHIBA=y +CONFIG_PD6729=m CONFIG_I82092=m -CONFIG_I82365=m -CONFIG_TCIC=m +# CONFIG_I82365 is not set +# CONFIG_TCIC is not set CONFIG_PCMCIA_PROBE=y +CONFIG_PCCARD_NONSTATIC=y # # PCI Hotplug Support # CONFIG_HOTPLUG_PCI=y -# CONFIG_HOTPLUG_PCI_FAKE is not set +CONFIG_HOTPLUG_PCI_FAKE=m CONFIG_HOTPLUG_PCI_COMPAQ=m # CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set CONFIG_HOTPLUG_PCI_IBM=m -# CONFIG_HOTPLUG_PCI_ACPI is not set +CONFIG_HOTPLUG_PCI_ACPI=m +CONFIG_HOTPLUG_PCI_ACPI_IBM=m # CONFIG_HOTPLUG_PCI_CPCI is not set -CONFIG_HOTPLUG_PCI_PCIE=m -CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE=y -CONFIG_HOTPLUG_PCI_SHPC=m -CONFIG_HOTPLUG_PCI_SHPC_POLL_EVENT_MODE=y +# CONFIG_HOTPLUG_PCI_SHPC is not set # # Executable file formats # CONFIG_BINFMT_ELF=y # CONFIG_BINFMT_AOUT is not set -CONFIG_BINFMT_MISC=m +CONFIG_BINFMT_MISC=y # -# Device Drivers +# Networking # +CONFIG_NET=y # -# Generic Driver Options +# Networking options # -CONFIG_FW_LOADER=y -# CONFIG_DEBUG_DRIVER is not set +# CONFIG_NETDEBUG is not set +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_UNIX=y +CONFIG_XFRM=y +CONFIG_XFRM_USER=y +CONFIG_NET_KEY=m +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_ASK_IP_FIB_HASH=y +# CONFIG_IP_FIB_TRIE is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_ROUTE_FWMARK=y +CONFIG_IP_ROUTE_MULTIPATH=y +# CONFIG_IP_ROUTE_MULTIPATH_CACHED is not set +CONFIG_IP_ROUTE_VERBOSE=y +# CONFIG_IP_PNP is not set +CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE=m +CONFIG_NET_IPGRE_BROADCAST=y +CONFIG_IP_MROUTE=y +CONFIG_IP_PIMSM_V1=y +CONFIG_IP_PIMSM_V2=y +# CONFIG_ARPD is not set +CONFIG_SYN_COOKIES=y +CONFIG_INET_AH=m +CONFIG_INET_ESP=m +CONFIG_INET_IPCOMP=m +CONFIG_INET_XFRM_TUNNEL=m +CONFIG_INET_TUNNEL=m +CONFIG_INET_DIAG=m +CONFIG_INET_TCP_DIAG=m +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_BIC=y # -# Memory Technology Devices (MTD) +# IP: Virtual Server Configuration # -CONFIG_MTD=m -# CONFIG_MTD_DEBUG is not set -CONFIG_MTD_PARTITIONS=m -CONFIG_MTD_CONCAT=m -CONFIG_MTD_REDBOOT_PARTS=m -CONFIG_MTD_CMDLINE_PARTS=m +CONFIG_IP_VS=m +# CONFIG_IP_VS_DEBUG is not set +CONFIG_IP_VS_TAB_BITS=12 # -# User Modules And Translation Layers +# IPVS transport protocol load balancing support # -CONFIG_MTD_CHAR=m -CONFIG_MTD_BLOCK=m -CONFIG_MTD_BLOCK_RO=m -CONFIG_FTL=m -CONFIG_NFTL=m -CONFIG_NFTL_RW=y -CONFIG_INFTL=m +CONFIG_IP_VS_PROTO_TCP=y +CONFIG_IP_VS_PROTO_UDP=y +CONFIG_IP_VS_PROTO_ESP=y +CONFIG_IP_VS_PROTO_AH=y # -# RAM/ROM/Flash chip drivers +# IPVS scheduler # -CONFIG_MTD_CFI=m -CONFIG_MTD_JEDECPROBE=m -CONFIG_MTD_GEN_PROBE=m -# CONFIG_MTD_CFI_ADV_OPTIONS is not set -CONFIG_MTD_CFI_INTELEXT=m -CONFIG_MTD_CFI_AMDSTD=m -CONFIG_MTD_CFI_STAA=m -CONFIG_MTD_RAM=m -CONFIG_MTD_ROM=m -CONFIG_MTD_ABSENT=m -# CONFIG_MTD_OBSOLETE_CHIPS is not set +CONFIG_IP_VS_RR=m +CONFIG_IP_VS_WRR=m +CONFIG_IP_VS_LC=m +CONFIG_IP_VS_WLC=m +CONFIG_IP_VS_LBLC=m +CONFIG_IP_VS_LBLCR=m +CONFIG_IP_VS_DH=m +CONFIG_IP_VS_SH=m +CONFIG_IP_VS_SED=m +CONFIG_IP_VS_NQ=m # -# Mapping drivers for chip access +# IPVS application helper # -CONFIG_MTD_COMPLEX_MAPPINGS=y -# CONFIG_MTD_PHYSMAP is not set -# CONFIG_MTD_PNC2000 is not set -CONFIG_MTD_SC520CDP=m -CONFIG_MTD_NETSC520=m -CONFIG_MTD_SBC_GXX=m -CONFIG_MTD_ELAN_104NC=m -CONFIG_MTD_SCx200_DOCFLASH=m -CONFIG_MTD_AMD76XROM=m -CONFIG_MTD_ICH2ROM=m -CONFIG_MTD_SCB2_FLASH=m -# CONFIG_MTD_NETtel is not set -# CONFIG_MTD_DILNETPC is not set -CONFIG_MTD_L440GX=m -CONFIG_MTD_PCI=m +CONFIG_IP_VS_FTP=m +CONFIG_IPV6=m +CONFIG_IPV6_PRIVACY=y +CONFIG_IPV6_ROUTER_PREF=y +CONFIG_IPV6_ROUTE_INFO=y +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_IPCOMP=m +CONFIG_INET6_XFRM_TUNNEL=m +CONFIG_INET6_TUNNEL=m +CONFIG_IPV6_TUNNEL=m +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_BRIDGE_NETFILTER=y # -# Self-contained MTD device drivers +# Core Netfilter Configuration +# +CONFIG_NETFILTER_NETLINK=m +CONFIG_NETFILTER_NETLINK_QUEUE=m +CONFIG_NETFILTER_NETLINK_LOG=m +CONFIG_NETFILTER_XTABLES=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +CONFIG_NETFILTER_XT_TARGET_CONNMARK=m +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_NETFILTER_XT_TARGET_NOTRACK=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNMARK=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_DCCP=m +CONFIG_NETFILTER_XT_MATCH_ESP=m +CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_LENGTH=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_SCTP=m +CONFIG_NETFILTER_XT_MATCH_STATE=m +CONFIG_NETFILTER_XT_MATCH_STRING=m +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m + # -CONFIG_MTD_PMC551=m -# CONFIG_MTD_PMC551_BUGFIX is not set -# CONFIG_MTD_PMC551_DEBUG is not set -# CONFIG_MTD_SLRAM is not set -CONFIG_MTD_MTDRAM=m -CONFIG_MTDRAM_TOTAL_SIZE=4096 -CONFIG_MTDRAM_ERASE_SIZE=128 -# CONFIG_MTD_BLKMTD is not set +# IP: Netfilter Configuration +# +CONFIG_IP_NF_CONNTRACK=m +CONFIG_IP_NF_CT_ACCT=y +CONFIG_IP_NF_CONNTRACK_MARK=y +CONFIG_IP_NF_CONNTRACK_EVENTS=y +CONFIG_IP_NF_CONNTRACK_NETLINK=m +CONFIG_IP_NF_CT_PROTO_SCTP=m +CONFIG_IP_NF_FTP=m +CONFIG_IP_NF_IRC=m +CONFIG_IP_NF_NETBIOS_NS=m +CONFIG_IP_NF_TFTP=m +CONFIG_IP_NF_AMANDA=m +CONFIG_IP_NF_PPTP=m +CONFIG_IP_NF_H323=m +CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_IPRANGE=m +CONFIG_IP_NF_MATCH_TOS=m +CONFIG_IP_NF_MATCH_RECENT=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_DSCP=m +CONFIG_IP_NF_MATCH_AH=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_MATCH_OWNER=m +CONFIG_IP_NF_MATCH_ADDRTYPE=m +CONFIG_IP_NF_MATCH_HASHLIMIT=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_IP_NF_TARGET_TCPMSS=m +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_SAME=m +CONFIG_IP_NF_NAT_SNMP_BASIC=m +CONFIG_IP_NF_NAT_IRC=m +CONFIG_IP_NF_NAT_FTP=m +CONFIG_IP_NF_NAT_TFTP=m +CONFIG_IP_NF_NAT_AMANDA=m +CONFIG_IP_NF_NAT_PPTP=m +CONFIG_IP_NF_NAT_H323=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_TARGET_TOS=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_DSCP=m +CONFIG_IP_NF_TARGET_TTL=m +CONFIG_IP_NF_TARGET_CLUSTERIP=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARP_MANGLE=m # -# Disk-On-Chip Device Drivers +# IPv6: Netfilter Configuration (EXPERIMENTAL) # -CONFIG_MTD_DOC2000=m -# CONFIG_MTD_DOC2001 is not set -CONFIG_MTD_DOC2001PLUS=m -CONFIG_MTD_DOCPROBE=m -# CONFIG_MTD_DOCPROBE_ADVANCED is not set -CONFIG_MTD_DOCPROBE_ADDRESS=0 +CONFIG_IP6_NF_QUEUE=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_OWNER=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_TARGET_HL=m +CONFIG_IP6_NF_RAW=m # -# NAND Flash Device Drivers +# DECnet: Netfilter Configuration # -CONFIG_MTD_NAND=m -# CONFIG_MTD_NAND_VERIFY_WRITE is not set -CONFIG_MTD_NAND_IDS=m +# CONFIG_DECNET_NF_GRABULATOR is not set # -# Parallel port support +# Bridge: Netfilter Configuration # -CONFIG_PARPORT=m -CONFIG_PARPORT_PC=m -CONFIG_PARPORT_PC_CML1=m -CONFIG_PARPORT_SERIAL=m -# CONFIG_PARPORT_PC_FIFO is not set -# CONFIG_PARPORT_PC_SUPERIO is not set -CONFIG_PARPORT_PC_PCMCIA=m -# CONFIG_PARPORT_OTHER is not set -CONFIG_PARPORT_1284=y +CONFIG_BRIDGE_NF_EBTABLES=m +CONFIG_BRIDGE_EBT_BROUTE=m +CONFIG_BRIDGE_EBT_T_FILTER=m +CONFIG_BRIDGE_EBT_T_NAT=m +CONFIG_BRIDGE_EBT_802_3=m +CONFIG_BRIDGE_EBT_AMONG=m +CONFIG_BRIDGE_EBT_ARP=m +CONFIG_BRIDGE_EBT_IP=m +CONFIG_BRIDGE_EBT_LIMIT=m +CONFIG_BRIDGE_EBT_MARK=m +CONFIG_BRIDGE_EBT_PKTTYPE=m +CONFIG_BRIDGE_EBT_STP=m +CONFIG_BRIDGE_EBT_VLAN=m +CONFIG_BRIDGE_EBT_ARPREPLY=m +CONFIG_BRIDGE_EBT_DNAT=m +CONFIG_BRIDGE_EBT_MARK_T=m +CONFIG_BRIDGE_EBT_REDIRECT=m +CONFIG_BRIDGE_EBT_SNAT=m +CONFIG_BRIDGE_EBT_LOG=m +CONFIG_BRIDGE_EBT_ULOG=m # -# Plug and Play support +# DCCP Configuration (EXPERIMENTAL) # -CONFIG_PNP=y -# CONFIG_PNP_DEBUG is not set +CONFIG_IP_DCCP=m +CONFIG_INET_DCCP_DIAG=m +CONFIG_IP_DCCP_ACKVEC=y # -# Protocols +# DCCP CCIDs Configuration (EXPERIMENTAL) # -CONFIG_ISAPNP=y -# CONFIG_PNPBIOS is not set +CONFIG_IP_DCCP_CCID2=m +CONFIG_IP_DCCP_CCID3=m +CONFIG_IP_DCCP_TFRC_LIB=m # -# Block devices +# DCCP Kernel Hacking # -CONFIG_BLK_DEV_FD=m -# CONFIG_BLK_DEV_XD is not set -# CONFIG_PARIDE is not set -CONFIG_BLK_CPQ_DA=m -CONFIG_BLK_CPQ_CISS_DA=m -CONFIG_CISS_SCSI_TAPE=y -CONFIG_BLK_DEV_DAC960=m -CONFIG_BLK_DEV_UMEM=m -CONFIG_BLK_DEV_LOOP=m -CONFIG_BLK_DEV_CRYPTOLOOP=m -CONFIG_BLK_DEV_NBD=m -CONFIG_BLK_DEV_CARMEL=m -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_SIZE=16384 -CONFIG_BLK_DEV_INITRD=y -CONFIG_LBD=y +# CONFIG_IP_DCCP_DEBUG is not set # -# ATA/ATAPI/MFM/RLL support +# SCTP Configuration (EXPERIMENTAL) # -CONFIG_IDE=y -CONFIG_BLK_DEV_IDE=y +CONFIG_IP_SCTP=m +# CONFIG_SCTP_DBG_MSG is not set +# CONFIG_SCTP_DBG_OBJCNT is not set +# CONFIG_SCTP_HMAC_NONE is not set +# CONFIG_SCTP_HMAC_SHA1 is not set +CONFIG_SCTP_HMAC_MD5=y # -# Please see Documentation/ide.txt for help/info on IDE drives +# TIPC Configuration (EXPERIMENTAL) # -# CONFIG_BLK_DEV_HD_IDE is not set -CONFIG_BLK_DEV_IDEDISK=y -CONFIG_IDEDISK_MULTI_MODE=y -# CONFIG_IDEDISK_STROKE is not set -CONFIG_BLK_DEV_IDECS=m -CONFIG_BLK_DEV_IDECD=y -CONFIG_BLK_DEV_IDETAPE=m -CONFIG_BLK_DEV_IDEFLOPPY=y -# CONFIG_BLK_DEV_IDESCSI is not set -# CONFIG_IDE_TASK_IOCTL is not set -# CONFIG_IDE_TASKFILE_IO is not set +CONFIG_TIPC=m +# CONFIG_TIPC_ADVANCED is not set +# CONFIG_TIPC_DEBUG is not set +CONFIG_ATM=m +CONFIG_ATM_CLIP=m +# CONFIG_ATM_CLIP_NO_ICMP is not set +CONFIG_ATM_LANE=m +# CONFIG_ATM_MPOA is not set +CONFIG_ATM_BR2684=m +# CONFIG_ATM_BR2684_IPFILTER is not set +CONFIG_BRIDGE=m +CONFIG_VLAN_8021Q=m +CONFIG_DECNET=m +CONFIG_DECNET_ROUTER=y +CONFIG_DECNET_ROUTE_FWMARK=y +CONFIG_LLC=y +# CONFIG_LLC2 is not set +CONFIG_IPX=m +# CONFIG_IPX_INTERN is not set +CONFIG_ATALK=m +CONFIG_DEV_APPLETALK=y +# CONFIG_LTPC is not set +# CONFIG_COPS is not set +CONFIG_IPDDP=m +CONFIG_IPDDP_ENCAP=y +CONFIG_IPDDP_DECAP=y +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +CONFIG_NET_DIVERT=y +# CONFIG_ECONET is not set +CONFIG_WAN_ROUTER=m # -# IDE chipset support/bugfixes +# QoS and/or fair queueing # -CONFIG_IDE_GENERIC=y -# CONFIG_BLK_DEV_CMD640 is not set -CONFIG_BLK_DEV_IDEPNP=y -CONFIG_BLK_DEV_IDEPCI=y -CONFIG_IDEPCI_SHARE_IRQ=y -# CONFIG_BLK_DEV_OFFBOARD is not set -CONFIG_BLK_DEV_GENERIC=y -# CONFIG_BLK_DEV_OPTI621 is not set -CONFIG_BLK_DEV_RZ1000=y -CONFIG_BLK_DEV_IDEDMA_PCI=y -# CONFIG_BLK_DEV_IDEDMA_FORCED is not set -CONFIG_IDEDMA_PCI_AUTO=y -# CONFIG_IDEDMA_ONLYDISK is not set -CONFIG_BLK_DEV_ADMA=y -CONFIG_BLK_DEV_AEC62XX=y -CONFIG_BLK_DEV_ALI15X3=y -# CONFIG_WDC_ALI15X3 is not set -CONFIG_BLK_DEV_AMD74XX=y -CONFIG_BLK_DEV_ATIIXP=y -CONFIG_BLK_DEV_CMD64X=y -CONFIG_BLK_DEV_TRIFLEX=y -CONFIG_BLK_DEV_CY82C693=y -CONFIG_BLK_DEV_CS5520=y -CONFIG_BLK_DEV_CS5530=y -CONFIG_BLK_DEV_HPT34X=y -# CONFIG_HPT34X_AUTODMA is not set -CONFIG_BLK_DEV_HPT366=y -# CONFIG_BLK_DEV_SC1200 is not set -CONFIG_BLK_DEV_PIIX=y -# CONFIG_BLK_DEV_NS87415 is not set -CONFIG_BLK_DEV_PDC202XX_OLD=y -# CONFIG_PDC202XX_BURST is not set -CONFIG_BLK_DEV_PDC202XX_NEW=y -CONFIG_PDC202XX_FORCE=y -CONFIG_BLK_DEV_SVWKS=y -CONFIG_BLK_DEV_SIIMAGE=y -CONFIG_BLK_DEV_SIS5513=y -CONFIG_BLK_DEV_SLC90E66=y -# CONFIG_BLK_DEV_TRM290 is not set -CONFIG_BLK_DEV_VIA82CXXX=y -# CONFIG_IDE_ARM is not set -# CONFIG_IDE_CHIPSETS is not set -CONFIG_BLK_DEV_IDEDMA=y -# CONFIG_IDEDMA_IVB is not set -CONFIG_IDEDMA_AUTO=y -# CONFIG_BLK_DEV_HD is not set +CONFIG_NET_SCHED=y +# CONFIG_NET_SCH_CLK_JIFFIES is not set +CONFIG_NET_SCH_CLK_GETTIMEOFDAY=y +# CONFIG_NET_SCH_CLK_CPU is not set # -# SCSI device support +# Queueing/Scheduling # -CONFIG_SCSI=m -CONFIG_SCSI_PROC_FS=y +CONFIG_NET_SCH_CBQ=m +CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_HFSC=m +CONFIG_NET_SCH_ATM=m +CONFIG_NET_SCH_PRIO=m +CONFIG_NET_SCH_RED=m +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_TEQL=m +CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_GRED=m +CONFIG_NET_SCH_DSMARK=m +CONFIG_NET_SCH_NETEM=m +CONFIG_NET_SCH_INGRESS=m # -# SCSI support type (disk, tape, CD-ROM) +# Classification # -CONFIG_BLK_DEV_SD=m -CONFIG_CHR_DEV_ST=m -CONFIG_CHR_DEV_OSST=m -CONFIG_BLK_DEV_SR=m -CONFIG_BLK_DEV_SR_VENDOR=y -CONFIG_CHR_DEV_SG=m +CONFIG_NET_CLS=y +CONFIG_NET_CLS_BASIC=m +CONFIG_NET_CLS_TCINDEX=m +CONFIG_NET_CLS_ROUTE4=m +CONFIG_NET_CLS_ROUTE=y +CONFIG_NET_CLS_FW=m +CONFIG_NET_CLS_U32=m +CONFIG_CLS_U32_PERF=y +CONFIG_CLS_U32_MARK=y +CONFIG_NET_CLS_RSVP=m +CONFIG_NET_CLS_RSVP6=m +CONFIG_NET_EMATCH=y +CONFIG_NET_EMATCH_STACK=32 +CONFIG_NET_EMATCH_CMP=m +CONFIG_NET_EMATCH_NBYTE=m +CONFIG_NET_EMATCH_U32=m +CONFIG_NET_EMATCH_META=m +CONFIG_NET_EMATCH_TEXT=m +# CONFIG_NET_CLS_ACT is not set +CONFIG_NET_CLS_POLICE=y +CONFIG_NET_CLS_IND=y +CONFIG_NET_ESTIMATOR=y # -# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# Network testing # -# CONFIG_SCSI_MULTI_LUN is not set -CONFIG_SCSI_CONSTANTS=y -CONFIG_SCSI_LOGGING=y +CONFIG_NET_PKTGEN=m +# CONFIG_HAMRADIO is not set +CONFIG_IRDA=m # -# SCSI Transport Attributes +# IrDA protocols # -CONFIG_SCSI_SPI_ATTRS=m -CONFIG_SCSI_FC_ATTRS=m +CONFIG_IRLAN=m +CONFIG_IRNET=m +CONFIG_IRCOMM=m +# CONFIG_IRDA_ULTRA is not set # -# SCSI low-level drivers +# IrDA options # -CONFIG_BLK_DEV_3W_XXXX_RAID=m -# CONFIG_SCSI_7000FASST is not set -CONFIG_SCSI_ACARD=m -CONFIG_SCSI_AHA152X=m -CONFIG_SCSI_AHA1542=m -CONFIG_SCSI_AACRAID=m -CONFIG_SCSI_AIC7XXX=m -CONFIG_AIC7XXX_CMDS_PER_DEVICE=4 -CONFIG_AIC7XXX_RESET_DELAY_MS=15000 -# CONFIG_AIC7XXX_BUILD_FIRMWARE is not set -# CONFIG_AIC7XXX_DEBUG_ENABLE is not set -CONFIG_AIC7XXX_DEBUG_MASK=0 -# CONFIG_AIC7XXX_REG_PRETTY_PRINT is not set -CONFIG_SCSI_AIC7XXX_OLD=m -CONFIG_SCSI_AIC79XX=m -CONFIG_AIC79XX_CMDS_PER_DEVICE=4 -CONFIG_AIC79XX_RESET_DELAY_MS=15000 -# CONFIG_AIC79XX_BUILD_FIRMWARE is not set -# CONFIG_AIC79XX_ENABLE_RD_STRM is not set -# CONFIG_AIC79XX_DEBUG_ENABLE is not set -CONFIG_AIC79XX_DEBUG_MASK=0 -# CONFIG_AIC79XX_REG_PRETTY_PRINT is not set -# CONFIG_SCSI_DPT_I2O is not set -CONFIG_SCSI_ADVANSYS=m -CONFIG_SCSI_IN2000=m -CONFIG_SCSI_MEGARAID=m -CONFIG_SCSI_SATA=y -CONFIG_SCSI_SATA_SVW=m -CONFIG_SCSI_ATA_PIIX=m -CONFIG_SCSI_SATA_PROMISE=m -CONFIG_SCSI_SATA_SX4=m -CONFIG_SCSI_SATA_SIL=m -CONFIG_SCSI_SATA_SIS=m -CONFIG_SCSI_SATA_VIA=m -CONFIG_SCSI_SATA_VITESSE=m -CONFIG_SCSI_BUSLOGIC=m -# CONFIG_SCSI_OMIT_FLASHPOINT is not set -# CONFIG_SCSI_CPQFCTS is not set -# CONFIG_SCSI_DMX3191D is not set -# CONFIG_SCSI_DTC3280 is not set -# CONFIG_SCSI_EATA is not set -# CONFIG_SCSI_EATA_PIO is not set -CONFIG_SCSI_FUTURE_DOMAIN=m -CONFIG_SCSI_GDTH=m -# CONFIG_SCSI_GENERIC_NCR5380 is not set -# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set -CONFIG_SCSI_IPS=m -CONFIG_SCSI_INIA100=m -CONFIG_SCSI_PPA=m -CONFIG_SCSI_IMM=m -# CONFIG_SCSI_IZIP_EPP16 is not set -# CONFIG_SCSI_IZIP_SLOW_CTR is not set -# CONFIG_SCSI_NCR53C406A is not set -CONFIG_SCSI_SYM53C8XX_2=m -CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1 -CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 -CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 -# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set -# CONFIG_SCSI_IPR is not set -# CONFIG_SCSI_PAS16 is not set -# CONFIG_SCSI_PSI240I is not set -CONFIG_SCSI_QLOGIC_FAS=m -CONFIG_SCSI_QLOGIC_ISP=m -# CONFIG_SCSI_QLOGIC_FC is not set -CONFIG_SCSI_QLOGIC_1280=m -CONFIG_SCSI_QLA2XXX=m -CONFIG_SCSI_QLA21XX=m -CONFIG_SCSI_QLA22XX=m -CONFIG_SCSI_QLA2300=m -CONFIG_SCSI_QLA2322=m -CONFIG_SCSI_QLA6312=m -CONFIG_SCSI_QLA6322=m -# CONFIG_SCSI_SYM53C416 is not set -# CONFIG_SCSI_DC395x is not set -CONFIG_SCSI_DC390T=m -# CONFIG_SCSI_T128 is not set -# CONFIG_SCSI_U14_34F is not set -# CONFIG_SCSI_ULTRASTOR is not set -# CONFIG_SCSI_NSP32 is not set -# CONFIG_SCSI_DEBUG is not set +CONFIG_IRDA_CACHE_LAST_LSAP=y +CONFIG_IRDA_FAST_RR=y +# CONFIG_IRDA_DEBUG is not set # -# PCMCIA SCSI adapter support +# Infrared-port device drivers # -CONFIG_PCMCIA_AHA152X=m -CONFIG_PCMCIA_FDOMAIN=m -CONFIG_PCMCIA_NINJA_SCSI=m -CONFIG_PCMCIA_QLOGIC=m -CONFIG_PCMCIA_SYM53C500=m # -# Old CD-ROM drivers (not SCSI, not IDE) +# SIR device drivers # -# CONFIG_CD_NO_IDESCSI is not set +CONFIG_IRTTY_SIR=m # -# Multi-device support (RAID and LVM) +# Dongle support # -CONFIG_MD=y -CONFIG_BLK_DEV_MD=y -CONFIG_MD_LINEAR=m -CONFIG_MD_RAID0=m -CONFIG_MD_RAID1=m -CONFIG_MD_RAID5=m -CONFIG_MD_RAID6=m -CONFIG_MD_MULTIPATH=m -CONFIG_BLK_DEV_DM=m -CONFIG_DM_CRYPT=m +CONFIG_DONGLE=y +CONFIG_ESI_DONGLE=m +CONFIG_ACTISYS_DONGLE=m +CONFIG_TEKRAM_DONGLE=m +CONFIG_TOIM3232_DONGLE=m +CONFIG_LITELINK_DONGLE=m +CONFIG_MA600_DONGLE=m +CONFIG_GIRBIL_DONGLE=m +CONFIG_MCP2120_DONGLE=m +CONFIG_OLD_BELKIN_DONGLE=m +CONFIG_ACT200L_DONGLE=m # -# Fusion MPT device support +# Old SIR device drivers # -CONFIG_FUSION=m -CONFIG_FUSION_MAX_SGE=40 -# CONFIG_FUSION_ISENSE is not set -CONFIG_FUSION_CTL=m -CONFIG_FUSION_LAN=m +CONFIG_IRPORT_SIR=m # -# IEEE 1394 (FireWire) support +# Old Serial dongle support # -CONFIG_IEEE1394=m +# CONFIG_DONGLE_OLD is not set # -# Subsystem Options +# FIR device drivers # -# CONFIG_IEEE1394_VERBOSEDEBUG is not set -CONFIG_IEEE1394_OUI_DB=y -# CONFIG_IEEE1394_EXTRA_CONFIG_ROMS is not set +CONFIG_USB_IRDA=m +CONFIG_SIGMATEL_FIR=m +CONFIG_NSC_FIR=m +CONFIG_WINBOND_FIR=m +CONFIG_TOSHIBA_FIR=m +CONFIG_SMC_IRCC_FIR=m +CONFIG_ALI_FIR=m +CONFIG_VLSI_FIR=m +CONFIG_VIA_FIR=m +CONFIG_BT=m +CONFIG_BT_L2CAP=m +CONFIG_BT_SCO=m +CONFIG_BT_RFCOMM=m +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_BNEP=m +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_CMTP=m +CONFIG_BT_HIDP=m # -# Device Drivers +# Bluetooth device drivers # -# CONFIG_IEEE1394_PCILYNX is not set -CONFIG_IEEE1394_OHCI1394=m +CONFIG_BT_HCIUSB=m +CONFIG_BT_HCIUSB_SCO=y +CONFIG_BT_HCIUART=m +CONFIG_BT_HCIUART_H4=y +CONFIG_BT_HCIUART_BCSP=y +CONFIG_BT_HCIBCM203X=m +CONFIG_BT_HCIBPA10X=m +CONFIG_BT_HCIBFUSB=m +CONFIG_BT_HCIDTL1=m +CONFIG_BT_HCIBT3C=m +CONFIG_BT_HCIBLUECARD=m +CONFIG_BT_HCIBTUART=m +CONFIG_BT_HCIVHCI=m +CONFIG_IEEE80211=m +# CONFIG_IEEE80211_DEBUG is not set +CONFIG_IEEE80211_CRYPT_WEP=m +CONFIG_IEEE80211_CRYPT_CCMP=m +CONFIG_IEEE80211_CRYPT_TKIP=m +CONFIG_IEEE80211_SOFTMAC=m +CONFIG_IEEE80211_SOFTMAC_DEBUG=y +CONFIG_TUX=m # -# Protocol Drivers +# TUX options # -CONFIG_IEEE1394_VIDEO1394=m -CONFIG_IEEE1394_SBP2=m -# CONFIG_IEEE1394_SBP2_PHYS_DMA is not set -# CONFIG_IEEE1394_ETH1394 is not set -CONFIG_IEEE1394_DV1394=m -CONFIG_IEEE1394_RAWIO=m -CONFIG_IEEE1394_CMP=m -CONFIG_IEEE1394_AMDTP=m +CONFIG_TUX_EXTCGI=y +CONFIG_TUX_EXTENDED_LOG=y +# CONFIG_TUX_DEBUG is not set +CONFIG_WIRELESS_EXT=y # -# I2O device support +# Device Drivers # -CONFIG_I2O=m -CONFIG_I2O_CONFIG=m -CONFIG_I2O_BLOCK=m -CONFIG_I2O_SCSI=m -CONFIG_I2O_PROC=m # -# Networking support +# Generic Driver Options # -CONFIG_NET=y +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +# CONFIG_DEBUG_DRIVER is not set # -# Networking options +# Connector - unified userspace <-> kernelspace linker # -CONFIG_PACKET=y -CONFIG_PACKET_MMAP=y -CONFIG_NETLINK_DEV=y -CONFIG_UNIX=y -CONFIG_NET_KEY=m -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -CONFIG_IP_ADVANCED_ROUTER=y -CONFIG_IP_MULTIPLE_TABLES=y -CONFIG_IP_ROUTE_FWMARK=y -CONFIG_IP_ROUTE_NAT=y -CONFIG_IP_ROUTE_MULTIPATH=y -CONFIG_IP_ROUTE_TOS=y -CONFIG_IP_ROUTE_VERBOSE=y -# CONFIG_IP_PNP is not set -CONFIG_NET_IPIP=m -CONFIG_NET_IPGRE=m -CONFIG_NET_IPGRE_BROADCAST=y -CONFIG_IP_MROUTE=y -CONFIG_IP_PIMSM_V1=y -CONFIG_IP_PIMSM_V2=y -# CONFIG_ARPD is not set -CONFIG_SYN_COOKIES=y -CONFIG_INET_AH=m -CONFIG_INET_ESP=m -CONFIG_INET_IPCOMP=m +CONFIG_CONNECTOR=m # -# IP: Virtual Server Configuration +# Memory Technology Devices (MTD) # -CONFIG_IP_VS=m -# CONFIG_IP_VS_DEBUG is not set -CONFIG_IP_VS_TAB_BITS=12 +CONFIG_MTD=m +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_CONCAT=m +CONFIG_MTD_PARTITIONS=y +CONFIG_MTD_REDBOOT_PARTS=m +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set +# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set +CONFIG_MTD_CMDLINE_PARTS=y # -# IPVS transport protocol load balancing support +# User Modules And Translation Layers # -CONFIG_IP_VS_PROTO_TCP=y -CONFIG_IP_VS_PROTO_UDP=y -CONFIG_IP_VS_PROTO_ESP=y -CONFIG_IP_VS_PROTO_AH=y +CONFIG_MTD_CHAR=m +CONFIG_MTD_BLOCK=m +CONFIG_MTD_BLOCK_RO=m +CONFIG_FTL=m +CONFIG_NFTL=m +CONFIG_NFTL_RW=y +CONFIG_INFTL=m +CONFIG_RFD_FTL=m # -# IPVS scheduler +# RAM/ROM/Flash chip drivers # -CONFIG_IP_VS_RR=m -CONFIG_IP_VS_WRR=m -CONFIG_IP_VS_LC=m -CONFIG_IP_VS_WLC=m -CONFIG_IP_VS_LBLC=m -CONFIG_IP_VS_LBLCR=m -CONFIG_IP_VS_DH=m -CONFIG_IP_VS_SH=m -CONFIG_IP_VS_SED=m -CONFIG_IP_VS_NQ=m +CONFIG_MTD_CFI=m +CONFIG_MTD_JEDECPROBE=m +CONFIG_MTD_GEN_PROBE=m +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=m +CONFIG_MTD_CFI_AMDSTD=m +CONFIG_MTD_CFI_STAA=m +CONFIG_MTD_CFI_UTIL=m +CONFIG_MTD_RAM=m +CONFIG_MTD_ROM=m +CONFIG_MTD_ABSENT=m +# CONFIG_MTD_OBSOLETE_CHIPS is not set # -# IPVS application helper +# Mapping drivers for chip access # -CONFIG_IP_VS_FTP=m -CONFIG_IPV6=m -CONFIG_IPV6_PRIVACY=y -CONFIG_INET6_AH=m -CONFIG_INET6_ESP=m -CONFIG_INET6_IPCOMP=m -CONFIG_IPV6_TUNNEL=m -CONFIG_NETFILTER=y -# CONFIG_NETFILTER_DEBUG is not set -CONFIG_BRIDGE_NETFILTER=y +CONFIG_MTD_COMPLEX_MAPPINGS=y +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_PNC2000 is not set +CONFIG_MTD_SC520CDP=m +CONFIG_MTD_NETSC520=m +CONFIG_MTD_TS5500=m +# CONFIG_MTD_SBC_GXX is not set +# CONFIG_MTD_AMD76XROM is not set +# CONFIG_MTD_ICHXROM is not set +CONFIG_MTD_SCB2_FLASH=m +# CONFIG_MTD_NETtel is not set +# CONFIG_MTD_DILNETPC is not set +# CONFIG_MTD_L440GX is not set +CONFIG_MTD_PCI=m +# CONFIG_MTD_PLATRAM is not set # -# IP: Netfilter Configuration +# Self-contained MTD device drivers # -CONFIG_IP_NF_CONNTRACK=m -CONFIG_IP_NF_FTP=m -CONFIG_IP_NF_IRC=m -CONFIG_IP_NF_TFTP=m -CONFIG_IP_NF_AMANDA=m -CONFIG_IP_NF_QUEUE=m -CONFIG_IP_NF_IPTABLES=m -CONFIG_IP_NF_MATCH_LIMIT=m -CONFIG_IP_NF_MATCH_IPRANGE=m -CONFIG_IP_NF_MATCH_MAC=m -CONFIG_IP_NF_MATCH_PKTTYPE=m -CONFIG_IP_NF_MATCH_MARK=m -CONFIG_IP_NF_MATCH_MULTIPORT=m -CONFIG_IP_NF_MATCH_TOS=m -CONFIG_IP_NF_MATCH_RECENT=m -CONFIG_IP_NF_MATCH_ECN=m -CONFIG_IP_NF_MATCH_DSCP=m -CONFIG_IP_NF_MATCH_AH_ESP=m -CONFIG_IP_NF_MATCH_LENGTH=m -CONFIG_IP_NF_MATCH_TTL=m -CONFIG_IP_NF_MATCH_TCPMSS=m -CONFIG_IP_NF_MATCH_HELPER=m -CONFIG_IP_NF_MATCH_STATE=m -CONFIG_IP_NF_MATCH_CONNTRACK=m -CONFIG_IP_NF_MATCH_OWNER=m -CONFIG_IP_NF_MATCH_PHYSDEV=m -CONFIG_IP_NF_FILTER=m -CONFIG_IP_NF_TARGET_REJECT=m -CONFIG_IP_NF_NAT=m -CONFIG_IP_NF_NAT_NEEDED=y -CONFIG_IP_NF_TARGET_MASQUERADE=m -CONFIG_IP_NF_TARGET_REDIRECT=m -CONFIG_IP_NF_TARGET_NETMAP=m -CONFIG_IP_NF_TARGET_SAME=m -CONFIG_IP_NF_NAT_LOCAL=y -CONFIG_IP_NF_NAT_SNMP_BASIC=m -CONFIG_IP_NF_NAT_IRC=m -CONFIG_IP_NF_NAT_FTP=m -CONFIG_IP_NF_NAT_TFTP=m -CONFIG_IP_NF_NAT_AMANDA=m -CONFIG_IP_NF_MANGLE=m -CONFIG_IP_NF_TARGET_TOS=m -CONFIG_IP_NF_TARGET_ECN=m -CONFIG_IP_NF_TARGET_DSCP=m -CONFIG_IP_NF_TARGET_MARK=m -CONFIG_IP_NF_TARGET_CLASSIFY=m -CONFIG_IP_NF_TARGET_LOG=m -CONFIG_IP_NF_TARGET_ULOG=m -CONFIG_IP_NF_TARGET_TCPMSS=m -CONFIG_IP_NF_ARPTABLES=m -CONFIG_IP_NF_ARPFILTER=m -CONFIG_IP_NF_ARP_MANGLE=m -# CONFIG_IP_NF_COMPAT_IPCHAINS is not set -# CONFIG_IP_NF_COMPAT_IPFWADM is not set -CONFIG_IP_NF_TARGET_NOTRACK=m -CONFIG_IP_NF_RAW=m +CONFIG_MTD_PMC551=m +# CONFIG_MTD_PMC551_BUGFIX is not set +# CONFIG_MTD_PMC551_DEBUG is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +CONFIG_MTD_MTDRAM=m +CONFIG_MTDRAM_TOTAL_SIZE=4096 +CONFIG_MTDRAM_ERASE_SIZE=128 +CONFIG_MTD_BLOCK2MTD=m # -# IPv6: Netfilter Configuration +# Disk-On-Chip Device Drivers # -# CONFIG_IP6_NF_QUEUE is not set -CONFIG_IP6_NF_IPTABLES=m -CONFIG_IP6_NF_MATCH_LIMIT=m -CONFIG_IP6_NF_MATCH_MAC=m -CONFIG_IP6_NF_MATCH_RT=m -CONFIG_IP6_NF_MATCH_OPTS=m -CONFIG_IP6_NF_MATCH_FRAG=m -CONFIG_IP6_NF_MATCH_HL=m -CONFIG_IP6_NF_MATCH_MULTIPORT=m -CONFIG_IP6_NF_MATCH_OWNER=m -CONFIG_IP6_NF_MATCH_MARK=m -CONFIG_IP6_NF_MATCH_IPV6HEADER=m -CONFIG_IP6_NF_MATCH_AHESP=m -CONFIG_IP6_NF_MATCH_LENGTH=m -CONFIG_IP6_NF_MATCH_EUI64=m -CONFIG_IP6_NF_FILTER=m -CONFIG_IP6_NF_TARGET_LOG=m -CONFIG_IP6_NF_MANGLE=m -CONFIG_IP6_NF_TARGET_MARK=m -CONFIG_IP6_NF_RAW=m +CONFIG_MTD_DOC2000=m +# CONFIG_MTD_DOC2001 is not set +CONFIG_MTD_DOC2001PLUS=m +CONFIG_MTD_DOCPROBE=m +CONFIG_MTD_DOCECC=m +# CONFIG_MTD_DOCPROBE_ADVANCED is not set +CONFIG_MTD_DOCPROBE_ADDRESS=0 + +# +# NAND Flash Device Drivers +# +CONFIG_MTD_NAND=m +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +CONFIG_MTD_NAND_IDS=m +# CONFIG_MTD_NAND_DISKONCHIP is not set +CONFIG_MTD_NAND_NANDSIM=m + +# +# OneNAND Flash Device Drivers +# +# CONFIG_MTD_ONENAND is not set + +# +# Parallel port support +# +CONFIG_PARPORT=m +CONFIG_PARPORT_PC=m +CONFIG_PARPORT_SERIAL=m +# CONFIG_PARPORT_PC_FIFO is not set +# CONFIG_PARPORT_PC_SUPERIO is not set +CONFIG_PARPORT_PC_PCMCIA=m +CONFIG_PARPORT_NOT_PC=y +# CONFIG_PARPORT_GSC is not set +CONFIG_PARPORT_1284=y + +# +# Plug and Play support +# +CONFIG_PNP=y +# CONFIG_PNP_DEBUG is not set + +# +# Protocols +# +CONFIG_ISAPNP=y +# CONFIG_PNPBIOS is not set +CONFIG_PNPACPI=y + +# +# Block devices +# +CONFIG_BLK_DEV_FD=m +# CONFIG_BLK_DEV_XD is not set +CONFIG_PARIDE=m +CONFIG_PARIDE_PARPORT=m + +# +# Parallel IDE high-level drivers +# +CONFIG_PARIDE_PD=m +CONFIG_PARIDE_PCD=m +CONFIG_PARIDE_PF=m +CONFIG_PARIDE_PT=m +CONFIG_PARIDE_PG=m + +# +# Parallel IDE protocol modules +# +CONFIG_PARIDE_ATEN=m +CONFIG_PARIDE_BPCK=m +CONFIG_PARIDE_BPCK6=m +CONFIG_PARIDE_COMM=m +CONFIG_PARIDE_DSTR=m +CONFIG_PARIDE_FIT2=m +CONFIG_PARIDE_FIT3=m +CONFIG_PARIDE_EPAT=m +CONFIG_PARIDE_EPATC8=y +CONFIG_PARIDE_EPIA=m +CONFIG_PARIDE_FRIQ=m +CONFIG_PARIDE_FRPW=m +CONFIG_PARIDE_KBIC=m +CONFIG_PARIDE_KTTI=m +CONFIG_PARIDE_ON20=m +CONFIG_PARIDE_ON26=m +CONFIG_BLK_CPQ_DA=m +CONFIG_BLK_CPQ_CISS_DA=m +CONFIG_CISS_SCSI_TAPE=y +CONFIG_BLK_DEV_DAC960=m +CONFIG_BLK_DEV_UMEM=m +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=m +CONFIG_BLK_DEV_CRYPTOLOOP=m +CONFIG_BLK_DEV_NBD=m +CONFIG_BLK_DEV_SX8=m +CONFIG_BLK_DEV_UB=m +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=16384 +CONFIG_BLK_DEV_INITRD=y +CONFIG_CDROM_PKTCDVD=m +CONFIG_CDROM_PKTCDVD_BUFFERS=8 +# CONFIG_CDROM_PKTCDVD_WCACHE is not set +CONFIG_ATA_OVER_ETH=m + +# +# ATA/ATAPI/MFM/RLL support +# +CONFIG_IDE=y +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_IDE_SATA is not set +# CONFIG_BLK_DEV_HD_IDE is not set +CONFIG_BLK_DEV_IDEDISK=y +CONFIG_IDEDISK_MULTI_MODE=y +CONFIG_BLK_DEV_IDECS=m +CONFIG_BLK_DEV_IDECD=y +# CONFIG_BLK_DEV_IDETAPE is not set +CONFIG_BLK_DEV_IDEFLOPPY=y +CONFIG_BLK_DEV_IDESCSI=m +CONFIG_IDE_TASK_IOCTL=y + +# +# IDE chipset support/bugfixes +# +CONFIG_IDE_GENERIC=y +CONFIG_BLK_DEV_CMD640=y +CONFIG_BLK_DEV_CMD640_ENHANCED=y +CONFIG_BLK_DEV_IDEPNP=y +CONFIG_BLK_DEV_IDEPCI=y +CONFIG_IDEPCI_SHARE_IRQ=y +# CONFIG_BLK_DEV_OFFBOARD is not set +CONFIG_BLK_DEV_GENERIC=y +# CONFIG_BLK_DEV_OPTI621 is not set +CONFIG_BLK_DEV_RZ1000=y +CONFIG_BLK_DEV_IDEDMA_PCI=y +# CONFIG_BLK_DEV_IDEDMA_FORCED is not set +CONFIG_IDEDMA_PCI_AUTO=y +# CONFIG_IDEDMA_ONLYDISK is not set +CONFIG_BLK_DEV_AEC62XX=y +CONFIG_BLK_DEV_ALI15X3=y +# CONFIG_WDC_ALI15X3 is not set +CONFIG_BLK_DEV_AMD74XX=y +CONFIG_BLK_DEV_ATIIXP=y +CONFIG_BLK_DEV_CMD64X=y +CONFIG_BLK_DEV_TRIFLEX=y +CONFIG_BLK_DEV_CY82C693=y +CONFIG_BLK_DEV_CS5520=y +CONFIG_BLK_DEV_CS5530=y +CONFIG_BLK_DEV_CS5535=y +CONFIG_BLK_DEV_HPT34X=y +# CONFIG_HPT34X_AUTODMA is not set +CONFIG_BLK_DEV_HPT366=y +# CONFIG_BLK_DEV_SC1200 is not set +CONFIG_BLK_DEV_PIIX=y +CONFIG_BLK_DEV_IT821X=y +# CONFIG_BLK_DEV_NS87415 is not set +CONFIG_BLK_DEV_PDC202XX_OLD=y +# CONFIG_PDC202XX_BURST is not set +CONFIG_BLK_DEV_PDC202XX_NEW=y +CONFIG_BLK_DEV_SVWKS=y +CONFIG_BLK_DEV_SIIMAGE=y +CONFIG_BLK_DEV_SIS5513=y +CONFIG_BLK_DEV_SLC90E66=y +# CONFIG_BLK_DEV_TRM290 is not set +CONFIG_BLK_DEV_VIA82CXXX=y +# CONFIG_IDE_ARM is not set +# CONFIG_IDE_CHIPSETS is not set +CONFIG_BLK_DEV_IDEDMA=y +# CONFIG_IDEDMA_IVB is not set +CONFIG_IDEDMA_AUTO=y +# CONFIG_BLK_DEV_HD is not set # -# Bridge: Netfilter Configuration +# SCSI device support # -CONFIG_BRIDGE_NF_EBTABLES=m -CONFIG_BRIDGE_EBT_BROUTE=m -CONFIG_BRIDGE_EBT_T_FILTER=m -CONFIG_BRIDGE_EBT_T_NAT=m -CONFIG_BRIDGE_EBT_802_3=m -CONFIG_BRIDGE_EBT_AMONG=m -CONFIG_BRIDGE_EBT_ARP=m -CONFIG_BRIDGE_EBT_IP=m -CONFIG_BRIDGE_EBT_LIMIT=m -CONFIG_BRIDGE_EBT_MARK=m -CONFIG_BRIDGE_EBT_PKTTYPE=m -CONFIG_BRIDGE_EBT_STP=m -CONFIG_BRIDGE_EBT_VLAN=m -CONFIG_BRIDGE_EBT_ARPREPLY=m -CONFIG_BRIDGE_EBT_DNAT=m -CONFIG_BRIDGE_EBT_MARK_T=m -CONFIG_BRIDGE_EBT_REDIRECT=m -CONFIG_BRIDGE_EBT_SNAT=m -CONFIG_BRIDGE_EBT_LOG=m -CONFIG_XFRM=y -CONFIG_XFRM_USER=y +CONFIG_RAID_ATTRS=m +CONFIG_SCSI=m +CONFIG_SCSI_PROC_FS=y # -# SCTP Configuration (EXPERIMENTAL) +# SCSI support type (disk, tape, CD-ROM) # -CONFIG_IP_SCTP=m -# CONFIG_SCTP_DBG_MSG is not set -# CONFIG_SCTP_DBG_OBJCNT is not set -# CONFIG_SCTP_HMAC_NONE is not set -# CONFIG_SCTP_HMAC_SHA1 is not set -CONFIG_SCTP_HMAC_MD5=y -# CONFIG_ATM is not set -CONFIG_BRIDGE=m -CONFIG_VLAN_8021Q=m -# CONFIG_DECNET is not set -CONFIG_LLC=m -# CONFIG_LLC2 is not set -CONFIG_IPX=m -# CONFIG_IPX_INTERN is not set -CONFIG_ATALK=m -CONFIG_DEV_APPLETALK=y -CONFIG_LTPC=m -CONFIG_COPS=m -CONFIG_COPS_DAYNA=y -CONFIG_COPS_TANGENT=y -CONFIG_IPDDP=m -CONFIG_IPDDP_ENCAP=y -CONFIG_IPDDP_DECAP=y -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -CONFIG_NET_DIVERT=y -# CONFIG_ECONET is not set -CONFIG_WAN_ROUTER=m -# CONFIG_NET_FASTROUTE is not set -# CONFIG_NET_HW_FLOWCONTROL is not set +CONFIG_BLK_DEV_SD=m +CONFIG_CHR_DEV_ST=m +CONFIG_CHR_DEV_OSST=m +CONFIG_BLK_DEV_SR=m +CONFIG_BLK_DEV_SR_VENDOR=y +CONFIG_CHR_DEV_SG=m +CONFIG_CHR_DEV_SCH=m # -# QoS and/or fair queueing +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs # -CONFIG_NET_SCHED=y -CONFIG_NET_SCH_CBQ=m -CONFIG_NET_SCH_HTB=m -CONFIG_NET_SCH_HFSC=m -CONFIG_NET_SCH_CSZ=m -CONFIG_NET_SCH_PRIO=m -CONFIG_NET_SCH_RED=m -CONFIG_NET_SCH_SFQ=m -CONFIG_NET_SCH_TEQL=m -CONFIG_NET_SCH_TBF=m -CONFIG_NET_SCH_GRED=m -CONFIG_NET_SCH_DSMARK=m -CONFIG_NET_SCH_DELAY=m -CONFIG_NET_SCH_INGRESS=m -CONFIG_NET_QOS=y -CONFIG_NET_ESTIMATOR=y -CONFIG_NET_CLS=y -CONFIG_NET_CLS_TCINDEX=m -CONFIG_NET_CLS_ROUTE4=m -CONFIG_NET_CLS_ROUTE=y -CONFIG_NET_CLS_FW=m -CONFIG_NET_CLS_U32=m -CONFIG_NET_CLS_RSVP=m -CONFIG_NET_CLS_RSVP6=m -CONFIG_NET_CLS_POLICE=y +CONFIG_SCSI_MULTI_LUN=y +CONFIG_SCSI_CONSTANTS=y +CONFIG_SCSI_LOGGING=y # -# Network testing +# SCSI Transport Attributes # -# CONFIG_NET_PKTGEN is not set -CONFIG_NETPOLL=y -# CONFIG_NETPOLL_RX is not set -# CONFIG_NETPOLL_TRAP is not set -CONFIG_NET_POLL_CONTROLLER=y -# CONFIG_HAMRADIO is not set -CONFIG_IRDA=m +CONFIG_SCSI_SPI_ATTRS=m +CONFIG_SCSI_FC_ATTRS=m +CONFIG_SCSI_ISCSI_ATTRS=m +CONFIG_SCSI_SAS_ATTRS=m # -# IrDA protocols +# SCSI low-level drivers # -CONFIG_IRLAN=m -CONFIG_IRNET=m -CONFIG_IRCOMM=m -# CONFIG_IRDA_ULTRA is not set +CONFIG_ISCSI_TCP=m +CONFIG_BLK_DEV_3W_XXXX_RAID=m +CONFIG_SCSI_3W_9XXX=m +# CONFIG_SCSI_7000FASST is not set +CONFIG_SCSI_ACARD=m +CONFIG_SCSI_AHA152X=m +CONFIG_SCSI_AHA1542=m +CONFIG_SCSI_AACRAID=m +CONFIG_SCSI_AIC7XXX=m +CONFIG_AIC7XXX_CMDS_PER_DEVICE=4 +CONFIG_AIC7XXX_RESET_DELAY_MS=15000 +# CONFIG_AIC7XXX_DEBUG_ENABLE is not set +CONFIG_AIC7XXX_DEBUG_MASK=0 +# CONFIG_AIC7XXX_REG_PRETTY_PRINT is not set +CONFIG_SCSI_AIC7XXX_OLD=m +CONFIG_SCSI_AIC79XX=m +CONFIG_AIC79XX_CMDS_PER_DEVICE=4 +CONFIG_AIC79XX_RESET_DELAY_MS=15000 +# CONFIG_AIC79XX_ENABLE_RD_STRM is not set +# CONFIG_AIC79XX_DEBUG_ENABLE is not set +CONFIG_AIC79XX_DEBUG_MASK=0 +# CONFIG_AIC79XX_REG_PRETTY_PRINT is not set +# CONFIG_SCSI_DPT_I2O is not set +CONFIG_SCSI_ADVANSYS=m +# CONFIG_SCSI_IN2000 is not set +CONFIG_MEGARAID_NEWGEN=y +CONFIG_MEGARAID_MM=m +CONFIG_MEGARAID_MAILBOX=m +CONFIG_MEGARAID_LEGACY=m +CONFIG_MEGARAID_SAS=m +CONFIG_SCSI_SATA=m +CONFIG_SCSI_SATA_AHCI=m +CONFIG_SCSI_SATA_SVW=m +CONFIG_SCSI_ATA_PIIX=m +CONFIG_SCSI_SATA_MV=m +CONFIG_SCSI_SATA_NV=m +CONFIG_SCSI_PDC_ADMA=m +CONFIG_SCSI_SATA_QSTOR=m +CONFIG_SCSI_SATA_PROMISE=m +CONFIG_SCSI_SATA_SX4=m +CONFIG_SCSI_SATA_SIL=m +CONFIG_SCSI_SATA_SIL24=m +CONFIG_SCSI_SATA_SIS=m +CONFIG_SCSI_SATA_ULI=m +CONFIG_SCSI_SATA_VIA=m +CONFIG_SCSI_SATA_VITESSE=m +CONFIG_SCSI_SATA_INTEL_COMBINED=y +CONFIG_SCSI_BUSLOGIC=m +# CONFIG_SCSI_OMIT_FLASHPOINT is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_DTC3280 is not set +# CONFIG_SCSI_EATA is not set +CONFIG_SCSI_FUTURE_DOMAIN=m +CONFIG_SCSI_GDTH=m +# CONFIG_SCSI_GENERIC_NCR5380 is not set +# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set +CONFIG_SCSI_IPS=m +CONFIG_SCSI_INITIO=m +CONFIG_SCSI_INIA100=m +CONFIG_SCSI_PPA=m +CONFIG_SCSI_IMM=m +# CONFIG_SCSI_IZIP_EPP16 is not set +# CONFIG_SCSI_IZIP_SLOW_CTR is not set +# CONFIG_SCSI_NCR53C406A is not set +CONFIG_SCSI_SYM53C8XX_2=m +CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1 +CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 +CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 +CONFIG_SCSI_SYM53C8XX_MMIO=y +# CONFIG_SCSI_IPR is not set +# CONFIG_SCSI_PAS16 is not set +# CONFIG_SCSI_PSI240I is not set +# CONFIG_SCSI_QLOGIC_FAS is not set +CONFIG_SCSI_QLOGIC_1280=m +CONFIG_SCSI_QLA_FC=m +CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE=y +CONFIG_SCSI_QLA21XX=m +CONFIG_SCSI_QLA22XX=m +CONFIG_SCSI_QLA2300=m +CONFIG_SCSI_QLA2322=m +CONFIG_SCSI_QLA24XX=m +CONFIG_SCSI_LPFC=m +# CONFIG_SCSI_SYM53C416 is not set +CONFIG_SCSI_DC395x=m +CONFIG_SCSI_DC390T=m +# CONFIG_SCSI_T128 is not set +# CONFIG_SCSI_U14_34F is not set +# CONFIG_SCSI_ULTRASTOR is not set +# CONFIG_SCSI_NSP32 is not set +# CONFIG_SCSI_DEBUG is not set # -# IrDA options +# PCMCIA SCSI adapter support # -CONFIG_IRDA_CACHE_LAST_LSAP=y -CONFIG_IRDA_FAST_RR=y -# CONFIG_IRDA_DEBUG is not set +CONFIG_PCMCIA_AHA152X=m +CONFIG_PCMCIA_FDOMAIN=m +CONFIG_PCMCIA_NINJA_SCSI=m +CONFIG_PCMCIA_QLOGIC=m +CONFIG_PCMCIA_SYM53C500=m # -# Infrared-port device drivers +# Old CD-ROM drivers (not SCSI, not IDE) # +# CONFIG_CD_NO_IDESCSI is not set # -# SIR device drivers +# Multi-device support (RAID and LVM) # -CONFIG_IRTTY_SIR=m +CONFIG_MD=y +CONFIG_BLK_DEV_MD=y +CONFIG_MD_LINEAR=m +CONFIG_MD_RAID0=m +CONFIG_MD_RAID1=m +CONFIG_MD_RAID10=m +CONFIG_MD_RAID5=m +CONFIG_MD_RAID5_RESHAPE=y +CONFIG_MD_RAID6=m +CONFIG_MD_MULTIPATH=m +CONFIG_MD_FAULTY=m +CONFIG_BLK_DEV_DM=m +CONFIG_DM_CRYPT=m +CONFIG_DM_SNAPSHOT=m +CONFIG_DM_MIRROR=m +CONFIG_DM_ZERO=m +CONFIG_DM_MULTIPATH=m +CONFIG_DM_MULTIPATH_EMC=m # -# Dongle support +# Fusion MPT device support # -CONFIG_DONGLE=y -CONFIG_ESI_DONGLE=m -CONFIG_ACTISYS_DONGLE=m -CONFIG_TEKRAM_DONGLE=m -CONFIG_LITELINK_DONGLE=m -CONFIG_MA600_DONGLE=m -CONFIG_GIRBIL_DONGLE=m -CONFIG_MCP2120_DONGLE=m -CONFIG_OLD_BELKIN_DONGLE=m -CONFIG_ACT200L_DONGLE=m +CONFIG_FUSION=y +CONFIG_FUSION_SPI=m +CONFIG_FUSION_FC=m +CONFIG_FUSION_SAS=m +CONFIG_FUSION_MAX_SGE=40 +CONFIG_FUSION_CTL=m +CONFIG_FUSION_LAN=m # -# Old SIR device drivers +# IEEE 1394 (FireWire) support # +CONFIG_IEEE1394=m # -# Old Serial dongle support +# Subsystem Options # +# CONFIG_IEEE1394_VERBOSEDEBUG is not set +CONFIG_IEEE1394_OUI_DB=y +CONFIG_IEEE1394_EXTRA_CONFIG_ROMS=y +CONFIG_IEEE1394_CONFIG_ROM_IP1394=y +# CONFIG_IEEE1394_EXPORT_FULL_API is not set # -# FIR device drivers +# Device Drivers # -CONFIG_USB_IRDA=m -CONFIG_SIGMATEL_FIR=m -CONFIG_NSC_FIR=m -# CONFIG_WINBOND_FIR is not set -# CONFIG_TOSHIBA_FIR is not set -# CONFIG_SMC_IRCC_FIR is not set -# CONFIG_ALI_FIR is not set -# CONFIG_VLSI_FIR is not set -# CONFIG_VIA_FIR is not set -CONFIG_BT=m -CONFIG_BT_L2CAP=m -CONFIG_BT_SCO=m -CONFIG_BT_RFCOMM=m -CONFIG_BT_RFCOMM_TTY=y -CONFIG_BT_BNEP=m -CONFIG_BT_BNEP_MC_FILTER=y -CONFIG_BT_BNEP_PROTO_FILTER=y -CONFIG_BT_CMTP=m +CONFIG_IEEE1394_PCILYNX=m +CONFIG_IEEE1394_OHCI1394=m # -# Bluetooth device drivers +# Protocol Drivers # -CONFIG_BT_HCIUSB=m -CONFIG_BT_HCIUSB_SCO=y -CONFIG_BT_HCIUART=m -CONFIG_BT_HCIUART_H4=y -CONFIG_BT_HCIUART_BCSP=y -CONFIG_BT_HCIUART_BCSP_TXCRC=y -CONFIG_BT_HCIBCM203X=m -CONFIG_BT_HCIBFUSB=m -CONFIG_BT_HCIDTL1=m -CONFIG_BT_HCIBT3C=m -CONFIG_BT_HCIBLUECARD=m -CONFIG_BT_HCIBTUART=m -CONFIG_BT_HCIVHCI=m -CONFIG_TUX=m +CONFIG_IEEE1394_VIDEO1394=m +CONFIG_IEEE1394_SBP2=m +# CONFIG_IEEE1394_SBP2_PHYS_DMA is not set +CONFIG_IEEE1394_ETH1394=m +CONFIG_IEEE1394_DV1394=m +CONFIG_IEEE1394_RAWIO=m # -# TUX options +# I2O device support +# +CONFIG_I2O=m +# CONFIG_I2O_LCT_NOTIFY_ON_CHANGES is not set +CONFIG_I2O_EXT_ADAPTEC=y +CONFIG_I2O_CONFIG=m +CONFIG_I2O_CONFIG_OLD_IOCTL=y +CONFIG_I2O_BUS=m +CONFIG_I2O_BLOCK=m +CONFIG_I2O_SCSI=m +CONFIG_I2O_PROC=m + +# +# Network device support # -CONFIG_TUX_EXTCGI=y -# CONFIG_TUX_EXTENDED_LOG is not set -# CONFIG_TUX_DEBUG is not set CONFIG_NETDEVICES=y CONFIG_DUMMY=m CONFIG_BONDING=m CONFIG_EQUALIZER=m CONFIG_TUN=m -CONFIG_ETHERTAP=m CONFIG_NET_SB1000=m # @@ -1027,6 +1327,20 @@ CONFIG_NET_SB1000=m # # CONFIG_ARCNET is not set +# +# PHY device support +# +CONFIG_PHYLIB=m + +# +# MII PHY device drivers +# +CONFIG_MARVELL_PHY=m +CONFIG_DAVICOM_PHY=m +CONFIG_QSEMI_PHY=m +CONFIG_LXT_PHY=m +CONFIG_CICADA_PHY=m + # # Ethernet (10 or 100Mbit) # @@ -1034,23 +1348,22 @@ CONFIG_NET_ETHERNET=y CONFIG_MII=m CONFIG_HAPPYMEAL=m CONFIG_SUNGEM=m +CONFIG_CASSINI=m CONFIG_NET_VENDOR_3COM=y -CONFIG_EL1=m -CONFIG_EL2=m -CONFIG_ELPLUS=m -CONFIG_EL16=m +# CONFIG_EL1 is not set +# CONFIG_EL2 is not set +# CONFIG_ELPLUS is not set +# CONFIG_EL16 is not set CONFIG_EL3=m -CONFIG_3C515=m +# CONFIG_3C515 is not set CONFIG_VORTEX=m CONFIG_TYPHOON=m -CONFIG_LANCE=m +# CONFIG_LANCE is not set CONFIG_NET_VENDOR_SMC=y -CONFIG_WD80x3=m +# CONFIG_WD80x3 is not set CONFIG_ULTRA=m -CONFIG_SMC9194=m -CONFIG_NET_VENDOR_RACAL=y -CONFIG_NI52=m -CONFIG_NI65=m +# CONFIG_SMC9194 is not set +# CONFIG_NET_VENDOR_RACAL is not set # # Tulip family network device support @@ -1064,34 +1377,44 @@ CONFIG_TULIP_MMIO=y CONFIG_DE4X5=m CONFIG_WINBOND_840=m CONFIG_DM9102=m +CONFIG_ULI526X=m CONFIG_PCMCIA_XIRCOM=m +# CONFIG_PCMCIA_XIRTULIP is not set # CONFIG_AT1700 is not set -CONFIG_DEPCA=m +# CONFIG_DEPCA is not set CONFIG_HP100=m -# CONFIG_NET_ISA is not set +CONFIG_NET_ISA=y +# CONFIG_E2100 is not set +CONFIG_EWRK3=m +# CONFIG_EEXPRESS is not set +# CONFIG_EEXPRESS_PRO is not set +# CONFIG_HPLAN_PLUS is not set +# CONFIG_HPLAN is not set +# CONFIG_LP486E is not set +# CONFIG_ETH16I is not set CONFIG_NE2000=m +# CONFIG_ZNET is not set +# CONFIG_SEEQ8005 is not set CONFIG_NET_PCI=y CONFIG_PCNET32=m CONFIG_AMD8111_ETH=m CONFIG_AMD8111E_NAPI=y CONFIG_ADAPTEC_STARFIRE=m CONFIG_ADAPTEC_STARFIRE_NAPI=y -CONFIG_AC3200=m -CONFIG_APRICOT=m +# CONFIG_AC3200 is not set +# CONFIG_APRICOT is not set CONFIG_B44=m CONFIG_FORCEDETH=m -CONFIG_CS89x0=m +# CONFIG_CS89x0 is not set CONFIG_DGRS=m -CONFIG_EEPRO100=m -# CONFIG_EEPRO100_PIO is not set +# CONFIG_EEPRO100 is not set CONFIG_E100=m -CONFIG_E100_NAPI=y CONFIG_FEALNX=m CONFIG_NATSEMI=m CONFIG_NE2K_PCI=m CONFIG_8139CP=m CONFIG_8139TOO=m -CONFIG_8139TOO_PIO=y +# CONFIG_8139TOO_PIO is not set # CONFIG_8139TOO_TUNE_TWISTER is not set CONFIG_8139TOO_8129=y # CONFIG_8139_OLD_RX_RESET is not set @@ -1108,20 +1431,32 @@ CONFIG_DE600=m CONFIG_DE620=m # -# Gigabit Ethernet (1000/10000 Mbit) +# Ethernet (1000 Mbit) # -CONFIG_NET_GIGE=y CONFIG_ACENIC=m # CONFIG_ACENIC_OMIT_TIGON_I is not set CONFIG_DL2K=m CONFIG_E1000=m CONFIG_E1000_NAPI=y +# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set CONFIG_NS83820=m CONFIG_HAMACHI=m CONFIG_YELLOWFIN=m CONFIG_R8169=m -CONFIG_SK98LIN=m +CONFIG_R8169_NAPI=y +CONFIG_R8169_VLAN=y +CONFIG_SIS190=m +CONFIG_SKGE=m +CONFIG_SKY2=m +# CONFIG_SK98LIN is not set +CONFIG_VIA_VELOCITY=m CONFIG_TIGON3=m +CONFIG_BNX2=m + +# +# Ethernet (10000 Mbit) +# +CONFIG_CHELSIO_T1=m CONFIG_IXGB=m CONFIG_IXGB_NAPI=y CONFIG_S2IO=m @@ -1130,19 +1465,26 @@ CONFIG_S2IO_NAPI=y # # Token Ring devices # -# CONFIG_TR is not set +CONFIG_TR=y +# CONFIG_IBMTR is not set +CONFIG_IBMOL=m +CONFIG_IBMLS=m +CONFIG_3C359=m +# CONFIG_TMS380TR is not set +# CONFIG_SMCTR is not set # # Wireless LAN (non-hamradio) # CONFIG_NET_RADIO=y +CONFIG_NET_WIRELESS_RTNETLINK=y # # Obsolete Wireless cards support (pre-802.11) # # CONFIG_STRIP is not set # CONFIG_ARLAN is not set -CONFIG_WAVELAN=m +# CONFIG_WAVELAN is not set CONFIG_PCMCIA_WAVELAN=m CONFIG_PCMCIA_NETWAVE=m @@ -1154,10 +1496,18 @@ CONFIG_PCMCIA_NETWAVE=m # # Wireless 802.11b ISA/PCI cards support # +CONFIG_IPW2100=m +CONFIG_IPW2100_MONITOR=y +# CONFIG_IPW2100_DEBUG is not set +CONFIG_IPW2200=m +CONFIG_IPW2200_MONITOR=y +CONFIG_IPW_QOS=y +# CONFIG_IPW2200_DEBUG is not set CONFIG_AIRO=m CONFIG_HERMES=m CONFIG_PLX_HERMES=m CONFIG_TMD_HERMES=m +CONFIG_NORTEL_HERMES=m CONFIG_PCI_HERMES=m CONFIG_ATMEL=m CONFIG_PCI_ATMEL=m @@ -1166,6 +1516,7 @@ CONFIG_PCI_ATMEL=m # Wireless 802.11b Pcmcia/Cardbus cards support # CONFIG_PCMCIA_HERMES=m +CONFIG_PCMCIA_SPECTRUM=m CONFIG_AIRO_CS=m CONFIG_PCMCIA_ATMEL=m CONFIG_PCMCIA_WL3501=m @@ -1174,6 +1525,19 @@ CONFIG_PCMCIA_WL3501=m # Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support # CONFIG_PRISM54=m +CONFIG_HOSTAP=m +CONFIG_HOSTAP_FIRMWARE=y +CONFIG_HOSTAP_FIRMWARE_NVRAM=y +CONFIG_HOSTAP_PLX=m +CONFIG_HOSTAP_PCI=m +CONFIG_HOSTAP_CS=m +CONFIG_BCM43XX=m +CONFIG_BCM43XX_DEBUG=y +CONFIG_BCM43XX_DMA=y +CONFIG_BCM43XX_PIO=y +CONFIG_BCM43XX_DMA_AND_PIO_MODE=y +# CONFIG_BCM43XX_DMA_MODE is not set +# CONFIG_BCM43XX_PIO_MODE is not set CONFIG_NET_WIRELESS=y # @@ -1188,11 +1552,40 @@ CONFIG_PCMCIA_NMCLAN=m CONFIG_PCMCIA_SMC91C92=m CONFIG_PCMCIA_XIRC2PS=m CONFIG_PCMCIA_AXNET=m +CONFIG_PCMCIA_IBMTR=m # # Wan interfaces # # CONFIG_WAN is not set + +# +# ATM drivers +# +# CONFIG_ATM_DUMMY is not set +CONFIG_ATM_TCP=m +CONFIG_ATM_LANAI=m +CONFIG_ATM_ENI=m +# CONFIG_ATM_ENI_DEBUG is not set +# CONFIG_ATM_ENI_TUNE_BURST is not set +CONFIG_ATM_FIRESTREAM=m +# CONFIG_ATM_ZATM is not set +CONFIG_ATM_NICSTAR=m +# CONFIG_ATM_NICSTAR_USE_SUNI is not set +# CONFIG_ATM_NICSTAR_USE_IDT77105 is not set +CONFIG_ATM_IDT77252=m +# CONFIG_ATM_IDT77252_DEBUG is not set +# CONFIG_ATM_IDT77252_RCV_ALL is not set +CONFIG_ATM_IDT77252_USE_SUNI=y +CONFIG_ATM_AMBASSADOR=m +# CONFIG_ATM_AMBASSADOR_DEBUG is not set +CONFIG_ATM_HORIZON=m +# CONFIG_ATM_HORIZON_DEBUG is not set +# CONFIG_ATM_IA is not set +CONFIG_ATM_FORE200E_MAYBE=m +# CONFIG_ATM_FORE200E_PCA is not set +CONFIG_ATM_HE=m +# CONFIG_ATM_HE_USE_SUNI is not set CONFIG_FDDI=y # CONFIG_DEFXX is not set CONFIG_SKFP=m @@ -1205,11 +1598,20 @@ CONFIG_PPP_ASYNC=m CONFIG_PPP_SYNC_TTY=m CONFIG_PPP_DEFLATE=m # CONFIG_PPP_BSDCOMP is not set +CONFIG_PPP_MPPE=m CONFIG_PPPOE=m -# CONFIG_SLIP is not set +CONFIG_PPPOATM=m +CONFIG_SLIP=m +CONFIG_SLIP_COMPRESSED=y +CONFIG_SLIP_SMART=y +# CONFIG_SLIP_MODE_SLIP6 is not set CONFIG_NET_FC=y # CONFIG_SHAPER is not set CONFIG_NETCONSOLE=m +CONFIG_NETPOLL=y +# CONFIG_NETPOLL_RX is not set +CONFIG_NETPOLL_TRAP=y +CONFIG_NET_POLL_CONTROLLER=y # # ISDN subsystem @@ -1231,6 +1633,8 @@ CONFIG_ISDN_TTY_FAX=y # # ISDN feature submodules # +CONFIG_ISDN_DRV_LOOP=m +CONFIG_ISDN_DIVERSION=m # # ISDN4Linux hardware drivers @@ -1256,27 +1660,27 @@ CONFIG_HISAX_MAX_CARDS=8 # # HiSax supported cards # -CONFIG_HISAX_16_0=y +# CONFIG_HISAX_16_0 is not set CONFIG_HISAX_16_3=y CONFIG_HISAX_TELESPCI=y CONFIG_HISAX_S0BOX=y -CONFIG_HISAX_AVM_A1=y +# CONFIG_HISAX_AVM_A1 is not set CONFIG_HISAX_FRITZPCI=y CONFIG_HISAX_AVM_A1_PCMCIA=y CONFIG_HISAX_ELSA=y -CONFIG_HISAX_IX1MICROR2=y +# CONFIG_HISAX_IX1MICROR2 is not set CONFIG_HISAX_DIEHLDIVA=y -CONFIG_HISAX_ASUSCOM=y -CONFIG_HISAX_TELEINT=y -CONFIG_HISAX_HFCS=y +# CONFIG_HISAX_ASUSCOM is not set +# CONFIG_HISAX_TELEINT is not set +# CONFIG_HISAX_HFCS is not set CONFIG_HISAX_SEDLBAUER=y -CONFIG_HISAX_SPORTSTER=y -CONFIG_HISAX_MIC=y +# CONFIG_HISAX_SPORTSTER is not set +# CONFIG_HISAX_MIC is not set CONFIG_HISAX_NETJET=y CONFIG_HISAX_NETJET_U=y CONFIG_HISAX_NICCY=y -CONFIG_HISAX_ISURF=y -CONFIG_HISAX_HSTSAPHIR=y +# CONFIG_HISAX_ISURF is not set +# CONFIG_HISAX_HSTSAPHIR is not set CONFIG_HISAX_BKM_A4T=y CONFIG_HISAX_SCT_QUADRO=y CONFIG_HISAX_GAZEL=y @@ -1298,18 +1702,29 @@ CONFIG_HISAX_TELES_CS=m # HiSax sub driver modules # CONFIG_HISAX_ST5481=m -CONFIG_HISAX_HFCUSB=m +# CONFIG_HISAX_HFCUSB is not set +CONFIG_HISAX_HFC4S8S=m CONFIG_HISAX_FRITZ_PCIPNP=m CONFIG_HISAX_HDLC=y # # Active cards # -CONFIG_ISDN_DRV_ICN=m -CONFIG_ISDN_DRV_PCBIT=m -CONFIG_ISDN_DRV_SC=m -CONFIG_ISDN_DRV_ACT2000=m -CONFIG_ISDN_DRV_TPAM=m +# CONFIG_ISDN_DRV_ICN is not set +# CONFIG_ISDN_DRV_PCBIT is not set +# CONFIG_ISDN_DRV_SC is not set +# CONFIG_ISDN_DRV_ACT2000 is not set +CONFIG_HYSDN=m +CONFIG_HYSDN_CAPI=y + +# +# Siemens Gigaset +# +CONFIG_ISDN_DRV_GIGASET=m +CONFIG_GIGASET_BASE=m +CONFIG_GIGASET_M105=m +# CONFIG_GIGASET_DEBUG is not set +# CONFIG_GIGASET_UNDOCREQ is not set # # CAPI subsystem @@ -1330,6 +1745,14 @@ CONFIG_ISDN_CAPI_CAPIDRV=m # Active AVM cards # CONFIG_CAPI_AVM=y +# CONFIG_ISDN_DRV_AVMB1_B1ISA is not set +CONFIG_ISDN_DRV_AVMB1_B1PCI=m +CONFIG_ISDN_DRV_AVMB1_B1PCIV4=y +# CONFIG_ISDN_DRV_AVMB1_T1ISA is not set +CONFIG_ISDN_DRV_AVMB1_B1PCMCIA=m +CONFIG_ISDN_DRV_AVMB1_AVM_CS=m +CONFIG_ISDN_DRV_AVMB1_T1PCI=m +CONFIG_ISDN_DRV_AVMB1_C4=m # # Active Eicon DIVA Server cards @@ -1364,24 +1787,6 @@ CONFIG_INPUT_JOYDEV=m CONFIG_INPUT_EVDEV=y # CONFIG_INPUT_EVBUG is not set -# -# Input I/O drivers -# -CONFIG_GAMEPORT=m -CONFIG_SOUND_GAMEPORT=m -CONFIG_GAMEPORT_NS558=m -CONFIG_GAMEPORT_L4=m -CONFIG_GAMEPORT_EMU10K1=m -CONFIG_GAMEPORT_VORTEX=m -CONFIG_GAMEPORT_FM801=m -CONFIG_GAMEPORT_CS461x=m -CONFIG_SERIO=y -CONFIG_SERIO_I8042=y -CONFIG_SERIO_SERPORT=y -# CONFIG_SERIO_CT82C710 is not set -# CONFIG_SERIO_PARKBD is not set -# CONFIG_SERIO_PCIPS2 is not set - # # Input Device Drivers # @@ -1394,10 +1799,9 @@ CONFIG_KEYBOARD_ATKBD=y CONFIG_INPUT_MOUSE=y CONFIG_MOUSE_PS2=y CONFIG_MOUSE_SERIAL=m -CONFIG_MOUSE_INPORT=m -CONFIG_MOUSE_ATIXL=y -CONFIG_MOUSE_LOGIBM=m -CONFIG_MOUSE_PC110PAD=m +# CONFIG_MOUSE_INPORT is not set +# CONFIG_MOUSE_LOGIBM is not set +# CONFIG_MOUSE_PC110PAD is not set CONFIG_MOUSE_VSXXXAA=m CONFIG_INPUT_JOYSTICK=y CONFIG_JOYSTICK_ANALOG=m @@ -1419,16 +1823,37 @@ CONFIG_JOYSTICK_MAGELLAN=m CONFIG_JOYSTICK_SPACEORB=m CONFIG_JOYSTICK_SPACEBALL=m CONFIG_JOYSTICK_STINGER=m -CONFIG_JOYSTICK_TWIDDLER=m +CONFIG_JOYSTICK_TWIDJOY=m CONFIG_JOYSTICK_DB9=m CONFIG_JOYSTICK_GAMECON=m CONFIG_JOYSTICK_TURBOGRAFX=m -# CONFIG_INPUT_JOYDUMP is not set +CONFIG_JOYSTICK_JOYDUMP=m CONFIG_INPUT_TOUCHSCREEN=y CONFIG_TOUCHSCREEN_GUNZE=m +CONFIG_TOUCHSCREEN_ELO=m +CONFIG_TOUCHSCREEN_MTOUCH=m +CONFIG_TOUCHSCREEN_MK712=m CONFIG_INPUT_MISC=y CONFIG_INPUT_PCSPKR=m -# CONFIG_INPUT_UINPUT is not set +CONFIG_INPUT_WISTRON_BTNS=m +CONFIG_INPUT_UINPUT=m + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_I8042=y +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_CT82C710 is not set +# CONFIG_SERIO_PARKBD is not set +# CONFIG_SERIO_PCIPS2 is not set +CONFIG_SERIO_LIBPS2=y +CONFIG_SERIO_RAW=m +CONFIG_GAMEPORT=m +CONFIG_GAMEPORT_NS558=m +CONFIG_GAMEPORT_L4=m +CONFIG_GAMEPORT_EMU10K1=m +CONFIG_GAMEPORT_FM801=m # # Character devices @@ -1437,33 +1862,50 @@ CONFIG_VT=y CONFIG_VT_CONSOLE=y CONFIG_HW_CONSOLE=y CONFIG_SERIAL_NONSTANDARD=y +# CONFIG_COMPUTONE is not set CONFIG_ROCKETPORT=m # CONFIG_CYCLADES is not set +# CONFIG_DIGIEPCA is not set +# CONFIG_ESPSERIAL is not set +# CONFIG_MOXA_INTELLIO is not set +# CONFIG_MOXA_SMARTIO is not set +# CONFIG_ISI is not set CONFIG_SYNCLINK=m CONFIG_SYNCLINKMP=m +# CONFIG_SYNCLINK_GT is not set CONFIG_N_HDLC=m -CONFIG_STALDRV=y +# CONFIG_RISCOM8 is not set +# CONFIG_SPECIALIX is not set +# CONFIG_SX is not set +# CONFIG_RIO is not set +# CONFIG_STALDRV is not set # # Serial drivers # CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_PCI=y +CONFIG_SERIAL_8250_PNP=y CONFIG_SERIAL_8250_CS=m -# CONFIG_SERIAL_8250_ACPI is not set -CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_NR_UARTS=32 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 CONFIG_SERIAL_8250_EXTENDED=y -# CONFIG_SERIAL_8250_MANY_PORTS is not set +CONFIG_SERIAL_8250_MANY_PORTS=y CONFIG_SERIAL_8250_SHARE_IRQ=y CONFIG_SERIAL_8250_DETECT_IRQ=y -CONFIG_SERIAL_8250_MULTIPORT=y CONFIG_SERIAL_8250_RSA=y +# CONFIG_SERIAL_8250_FOURPORT is not set +# CONFIG_SERIAL_8250_ACCENT is not set +# CONFIG_SERIAL_8250_BOCA is not set +# CONFIG_SERIAL_8250_HUB6 is not set # # Non-8250 serial port support # CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_JSM is not set CONFIG_UNIX98_PTYS=y # CONFIG_LEGACY_PTYS is not set CONFIG_CRASH=m @@ -1471,7 +1913,6 @@ CONFIG_PRINTER=m CONFIG_LP_CONSOLE=y CONFIG_PPDEV=m CONFIG_TIPAR=m -# CONFIG_QIC02_TAPE is not set # # IPMI @@ -1481,6 +1922,7 @@ CONFIG_IPMI_HANDLER=m CONFIG_IPMI_DEVICE_INTERFACE=m CONFIG_IPMI_SI=m CONFIG_IPMI_WATCHDOG=m +CONFIG_IPMI_POWEROFF=m # # Watchdog Cards @@ -1492,30 +1934,33 @@ CONFIG_WATCHDOG=y # Watchdog Device Drivers # CONFIG_SOFT_WATCHDOG=m -CONFIG_ACQUIRE_WDT=m -CONFIG_ADVANTECH_WDT=m +# CONFIG_ACQUIRE_WDT is not set +# CONFIG_ADVANTECH_WDT is not set CONFIG_ALIM1535_WDT=m CONFIG_ALIM7101_WDT=m -CONFIG_SC520_WDT=m -CONFIG_EUROTECH_WDT=m -CONFIG_IB700_WDT=m -CONFIG_WAFER_WDT=m +# CONFIG_SC520_WDT is not set +# CONFIG_EUROTECH_WDT is not set +# CONFIG_IB700_WDT is not set +CONFIG_IBMASR=m +# CONFIG_WAFER_WDT is not set +CONFIG_I6300ESB_WDT=m CONFIG_I8XX_TCO=m -CONFIG_SC1200_WDT=m -# CONFIG_SCx200_WDT is not set +# CONFIG_SC1200_WDT is not set # CONFIG_60XX_WDT is not set -CONFIG_CPU5_WDT=m +# CONFIG_SBC8360_WDT is not set +# CONFIG_CPU5_WDT is not set CONFIG_W83627HF_WDT=m CONFIG_W83877F_WDT=m +CONFIG_W83977F_WDT=m CONFIG_MACHZ_WDT=m +# CONFIG_SBC_EPX_C3_WATCHDOG is not set # # ISA-based Watchdog Cards # -CONFIG_PCWATCHDOG=m +# CONFIG_PCWATCHDOG is not set # CONFIG_MIXCOMWD is not set -CONFIG_WDT=m -# CONFIG_WDT_501 is not set +# CONFIG_WDT is not set # # PCI-based Watchdog Cards @@ -1529,7 +1974,7 @@ CONFIG_WDT_501_PCI=y # CONFIG_USBPCWATCHDOG=m CONFIG_HW_RANDOM=m -CONFIG_NVRAM=m +CONFIG_NVRAM=y CONFIG_RTC=y CONFIG_DTLK=m CONFIG_R3964=m @@ -1539,36 +1984,50 @@ CONFIG_SONYPI=m # # Ftape, the floppy tape device driver # +# CONFIG_FTAPE is not set CONFIG_AGP=y CONFIG_AGP_ALI=y CONFIG_AGP_ATI=y CONFIG_AGP_AMD=y CONFIG_AGP_AMD64=y CONFIG_AGP_INTEL=y -CONFIG_AGP_INTEL_MCH=y CONFIG_AGP_NVIDIA=y CONFIG_AGP_SIS=y CONFIG_AGP_SWORKS=y CONFIG_AGP_VIA=y CONFIG_AGP_EFFICEON=y -CONFIG_DRM=y +CONFIG_DRM=m CONFIG_DRM_TDFX=m -CONFIG_DRM_GAMMA=m CONFIG_DRM_R128=m CONFIG_DRM_RADEON=m CONFIG_DRM_I810=m CONFIG_DRM_I830=m +CONFIG_DRM_I915=m CONFIG_DRM_MGA=m CONFIG_DRM_SIS=m +CONFIG_DRM_VIA=m +CONFIG_DRM_SAVAGE=m # # PCMCIA character devices # CONFIG_SYNCLINK_CS=m +CONFIG_CARDMAN_4000=m +CONFIG_CARDMAN_4040=m CONFIG_MWAVE=m +CONFIG_CS5535_GPIO=m # CONFIG_RAW_DRIVER is not set +CONFIG_HPET=y +# CONFIG_HPET_RTC_IRQ is not set +# CONFIG_HPET_MMAP is not set CONFIG_HANGCHECK_TIMER=m +# +# TPM devices +# +# CONFIG_TCG_TPM is not set +# CONFIG_TELCLOCK is not set + # # I2C support # @@ -1580,6 +2039,7 @@ CONFIG_I2C_CHARDEV=m # CONFIG_I2C_ALGOBIT=m CONFIG_I2C_ALGOPCF=m +CONFIG_I2C_ALGOPCA=m # # I2C Hardware Bus support @@ -1588,57 +2048,112 @@ CONFIG_I2C_ALI1535=m CONFIG_I2C_ALI1563=m CONFIG_I2C_ALI15X3=m CONFIG_I2C_AMD756=m +CONFIG_I2C_AMD756_S4882=m CONFIG_I2C_AMD8111=m +# CONFIG_I2C_ELEKTOR is not set CONFIG_I2C_I801=m CONFIG_I2C_I810=m +CONFIG_I2C_PIIX4=m CONFIG_I2C_ISA=m CONFIG_I2C_NFORCE2=m -# CONFIG_I2C_PARPORT is not set -# CONFIG_I2C_PARPORT_LIGHT is not set -CONFIG_I2C_PIIX4=m +CONFIG_I2C_PARPORT=m +CONFIG_I2C_PARPORT_LIGHT=m CONFIG_I2C_PROSAVAGE=m CONFIG_I2C_SAVAGE4=m # CONFIG_SCx200_ACB is not set CONFIG_I2C_SIS5595=m CONFIG_I2C_SIS630=m CONFIG_I2C_SIS96X=m +CONFIG_I2C_STUB=m CONFIG_I2C_VIA=m CONFIG_I2C_VIAPRO=m CONFIG_I2C_VOODOO3=m +CONFIG_I2C_PCA_ISA=m + +# +# Miscellaneous I2C Chip support +# +CONFIG_SENSORS_DS1337=m +CONFIG_SENSORS_DS1374=m +CONFIG_SENSORS_EEPROM=m +CONFIG_SENSORS_PCF8574=m +CONFIG_SENSORS_PCA9539=m +CONFIG_SENSORS_PCF8591=m +CONFIG_SENSORS_MAX6875=m +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set + +# +# SPI support +# +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set + +# +# Dallas's 1-wire bus +# +CONFIG_W1=m + +# +# 1-wire Bus Masters +# +CONFIG_W1_MASTER_MATROX=m +CONFIG_W1_MASTER_DS9490=m +CONFIG_W1_MASTER_DS9490_BRIDGE=m +CONFIG_W1_MASTER_DS2482=m + +# +# 1-wire Slaves +# +CONFIG_W1_SLAVE_THERM=m +CONFIG_W1_SLAVE_SMEM=m +CONFIG_W1_SLAVE_DS2433=m # -# Hardware Sensors Chip support +# Hardware Monitoring support # -CONFIG_I2C_SENSOR=m +CONFIG_HWMON=m +CONFIG_HWMON_VID=m CONFIG_SENSORS_ADM1021=m +CONFIG_SENSORS_ADM1025=m +CONFIG_SENSORS_ADM1026=m +CONFIG_SENSORS_ADM1031=m +CONFIG_SENSORS_ADM9240=m CONFIG_SENSORS_ASB100=m +CONFIG_SENSORS_ATXP1=m CONFIG_SENSORS_DS1621=m +CONFIG_SENSORS_F71805F=m CONFIG_SENSORS_FSCHER=m +CONFIG_SENSORS_FSCPOS=m CONFIG_SENSORS_GL518SM=m +CONFIG_SENSORS_GL520SM=m CONFIG_SENSORS_IT87=m +CONFIG_SENSORS_LM63=m CONFIG_SENSORS_LM75=m +CONFIG_SENSORS_LM77=m CONFIG_SENSORS_LM78=m CONFIG_SENSORS_LM80=m CONFIG_SENSORS_LM83=m CONFIG_SENSORS_LM85=m +CONFIG_SENSORS_LM87=m CONFIG_SENSORS_LM90=m +CONFIG_SENSORS_LM92=m CONFIG_SENSORS_MAX1619=m +CONFIG_SENSORS_PC87360=m +CONFIG_SENSORS_SIS5595=m +CONFIG_SENSORS_SMSC47M1=m +CONFIG_SENSORS_SMSC47B397=m CONFIG_SENSORS_VIA686A=m +CONFIG_SENSORS_VT8231=m CONFIG_SENSORS_W83781D=m +CONFIG_SENSORS_W83792D=m CONFIG_SENSORS_W83L785TS=m CONFIG_SENSORS_W83627HF=m - -# -# Other I2C Chip support -# -CONFIG_SENSORS_EEPROM=m -CONFIG_SENSORS_PCF8574=m -CONFIG_SENSORS_PCF8591=m -CONFIG_SENSORS_RTC8564=m -# CONFIG_I2C_DEBUG_CORE is not set -# CONFIG_I2C_DEBUG_ALGO is not set -# CONFIG_I2C_DEBUG_BUS is not set -# CONFIG_I2C_DEBUG_CHIP is not set +CONFIG_SENSORS_W83627EHF=m +CONFIG_SENSORS_HDAPS=m +# CONFIG_HWMON_DEBUG_CHIP is not set # # Misc devices @@ -1649,22 +2164,30 @@ CONFIG_IBM_ASM=m # Multimedia devices # CONFIG_VIDEO_DEV=m +CONFIG_VIDEO_V4L1=y +CONFIG_VIDEO_V4L1_COMPAT=y +CONFIG_VIDEO_V4L2=m # -# Video For Linux +# Video Capture Adapters # # -# Video Adapters +# Video Capture Adapters # +# CONFIG_VIDEO_ADV_DEBUG is not set +# CONFIG_VIDEO_VIVI is not set CONFIG_VIDEO_BT848=m -CONFIG_VIDEO_PMS=m +CONFIG_VIDEO_BT848_DVB=y +CONFIG_VIDEO_SAA6588=m +# CONFIG_VIDEO_PMS is not set CONFIG_VIDEO_BWQCAM=m CONFIG_VIDEO_CQCAM=m CONFIG_VIDEO_W9966=m CONFIG_VIDEO_CPIA=m CONFIG_VIDEO_CPIA_PP=m CONFIG_VIDEO_CPIA_USB=m +CONFIG_VIDEO_CPIA2=m CONFIG_VIDEO_SAA5246A=m CONFIG_VIDEO_SAA5249=m CONFIG_TUNER_3036=m @@ -1675,95 +2198,262 @@ CONFIG_VIDEO_ZORAN_DC10=m CONFIG_VIDEO_ZORAN_DC30=m CONFIG_VIDEO_ZORAN_LML33=m CONFIG_VIDEO_ZORAN_LML33R10=m +CONFIG_VIDEO_MEYE=m CONFIG_VIDEO_SAA7134=m +CONFIG_VIDEO_SAA7134_ALSA=m +CONFIG_VIDEO_SAA7134_DVB=m +CONFIG_VIDEO_SAA7134_DVB_ALL_FRONTENDS=y CONFIG_VIDEO_MXB=m CONFIG_VIDEO_DPC=m CONFIG_VIDEO_HEXIUM_ORION=m CONFIG_VIDEO_HEXIUM_GEMINI=m +CONFIG_VIDEO_CX88_VP3054=m CONFIG_VIDEO_CX88=m +CONFIG_VIDEO_CX88_ALSA=m +CONFIG_VIDEO_CX88_DVB=m +CONFIG_VIDEO_CX88_DVB_ALL_FRONTENDS=y +CONFIG_VIDEO_OVCAMCHIP=m + +# +# Encoders and Decoders +# +CONFIG_VIDEO_MSP3400=m +CONFIG_VIDEO_CS53L32A=m +CONFIG_VIDEO_WM8775=m +CONFIG_VIDEO_WM8739=m +CONFIG_VIDEO_CX25840=m +CONFIG_VIDEO_SAA711X=m +CONFIG_VIDEO_SAA7127=m +CONFIG_VIDEO_UPD64031A=m +CONFIG_VIDEO_UPD64083=m + +# +# V4L USB devices +# +CONFIG_VIDEO_EM28XX=m +CONFIG_USB_DSBR=m +CONFIG_VIDEO_USBVIDEO=m +CONFIG_USB_VICAM=m +CONFIG_USB_IBMCAM=m +CONFIG_USB_KONICAWC=m +CONFIG_USB_ET61X251=m +CONFIG_USB_OV511=m +CONFIG_USB_SE401=m +CONFIG_USB_SN9C102=m +CONFIG_USB_STV680=m +CONFIG_USB_W9968CF=m +CONFIG_USB_ZC0301=m +CONFIG_USB_PWC=m # # Radio Adapters # -CONFIG_RADIO_CADET=m -CONFIG_RADIO_RTRACK=m -CONFIG_RADIO_RTRACK2=m -CONFIG_RADIO_AZTECH=m -CONFIG_RADIO_GEMTEK=m +# CONFIG_RADIO_CADET is not set +# CONFIG_RADIO_RTRACK is not set +# CONFIG_RADIO_RTRACK2 is not set +# CONFIG_RADIO_AZTECH is not set +# CONFIG_RADIO_GEMTEK is not set CONFIG_RADIO_GEMTEK_PCI=m CONFIG_RADIO_MAXIRADIO=m CONFIG_RADIO_MAESTRO=m -CONFIG_RADIO_SF16FMI=m -CONFIG_RADIO_SF16FMR2=m -CONFIG_RADIO_TERRATEC=m -CONFIG_RADIO_TRUST=m -CONFIG_RADIO_TYPHOON=m -CONFIG_RADIO_TYPHOON_PROC_FS=y -CONFIG_RADIO_ZOLTRIX=m +# CONFIG_RADIO_SF16FMI is not set +# CONFIG_RADIO_SF16FMR2 is not set +# CONFIG_RADIO_TERRATEC is not set +# CONFIG_RADIO_TRUST is not set +# CONFIG_RADIO_TYPHOON is not set +# CONFIG_RADIO_ZOLTRIX is not set # # Digital Video Broadcasting Devices # -# CONFIG_DVB is not set +CONFIG_DVB=y +CONFIG_DVB_CORE=m + +# +# Supported SAA7146 based PCI Adapters +# +CONFIG_DVB_AV7110=m +CONFIG_DVB_AV7110_OSD=y +CONFIG_DVB_BUDGET=m +CONFIG_DVB_BUDGET_CI=m +CONFIG_DVB_BUDGET_AV=m +CONFIG_DVB_BUDGET_PATCH=m + +# +# Supported USB Adapters +# +CONFIG_DVB_USB=m +# CONFIG_DVB_USB_DEBUG is not set +CONFIG_DVB_USB_A800=m +CONFIG_DVB_USB_DIBUSB_MB=m +# CONFIG_DVB_USB_DIBUSB_MB_FAULTY is not set +CONFIG_DVB_USB_DIBUSB_MC=m +CONFIG_DVB_USB_UMT_010=m +CONFIG_DVB_USB_CXUSB=m +CONFIG_DVB_USB_DIGITV=m +CONFIG_DVB_USB_VP7045=m +CONFIG_DVB_USB_VP702X=m +CONFIG_DVB_USB_NOVA_T_USB2=m +CONFIG_DVB_USB_DTT200U=m +CONFIG_DVB_TTUSB_BUDGET=m +CONFIG_DVB_TTUSB_DEC=m +CONFIG_DVB_CINERGYT2=m +CONFIG_DVB_CINERGYT2_TUNING=y +CONFIG_DVB_CINERGYT2_STREAM_URB_COUNT=32 +CONFIG_DVB_CINERGYT2_STREAM_BUF_SIZE=512 +CONFIG_DVB_CINERGYT2_QUERY_INTERVAL=250 +CONFIG_DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE=y +CONFIG_DVB_CINERGYT2_RC_QUERY_INTERVAL=100 + +# +# Supported FlexCopII (B2C2) Adapters +# +CONFIG_DVB_B2C2_FLEXCOP=m +CONFIG_DVB_B2C2_FLEXCOP_PCI=m +CONFIG_DVB_B2C2_FLEXCOP_USB=m +# CONFIG_DVB_B2C2_FLEXCOP_DEBUG is not set + +# +# Supported BT878 Adapters +# +CONFIG_DVB_BT8XX=m + +# +# Supported Pluto2 Adapters +# +CONFIG_DVB_PLUTO2=m + +# +# Supported DVB Frontends +# + +# +# Customise DVB Frontends +# + +# +# DVB-S (satellite) frontends +# +CONFIG_DVB_STV0299=m +CONFIG_DVB_CX24110=m +CONFIG_DVB_CX24123=m +CONFIG_DVB_TDA8083=m +CONFIG_DVB_MT312=m +CONFIG_DVB_VES1X93=m +CONFIG_DVB_S5H1420=m + +# +# DVB-T (terrestrial) frontends +# +CONFIG_DVB_SP8870=m +CONFIG_DVB_SP887X=m +CONFIG_DVB_CX22700=m +CONFIG_DVB_CX22702=m +CONFIG_DVB_L64781=m +CONFIG_DVB_TDA1004X=m +CONFIG_DVB_NXT6000=m +CONFIG_DVB_MT352=m +CONFIG_DVB_ZL10353=m +CONFIG_DVB_DIB3000MB=m +CONFIG_DVB_DIB3000MC=m + +# +# DVB-C (cable) frontends +# +CONFIG_DVB_VES1820=m +CONFIG_DVB_TDA10021=m +CONFIG_DVB_STV0297=m + +# +# ATSC (North American/Korean Terresterial DTV) frontends +# +CONFIG_DVB_NXT200X=m +CONFIG_DVB_OR51211=m +CONFIG_DVB_OR51132=m +CONFIG_DVB_BCM3510=m +CONFIG_DVB_LGDT330X=m CONFIG_VIDEO_SAA7146=m CONFIG_VIDEO_SAA7146_VV=m CONFIG_VIDEO_VIDEOBUF=m CONFIG_VIDEO_TUNER=m CONFIG_VIDEO_BUF=m +CONFIG_VIDEO_BUF_DVB=m CONFIG_VIDEO_BTCX=m CONFIG_VIDEO_IR=m +CONFIG_VIDEO_TVEEPROM=m +CONFIG_USB_DABUSB=m # # Graphics support # CONFIG_FB=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_FIRMWARE_EDID is not set +CONFIG_FB_MODE_HELPERS=y +CONFIG_FB_TILEBLITTING=y +CONFIG_FB_CIRRUS=m # CONFIG_FB_PM2 is not set # CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_ARC is not set # CONFIG_FB_ASILIANT is not set # CONFIG_FB_IMSTT is not set CONFIG_FB_VGA16=m CONFIG_FB_VESA=y CONFIG_VIDEO_SELECT=y -CONFIG_FB_HGA=m -CONFIG_FB_HGA_ACCEL=y +# CONFIG_FB_HGA is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_NVIDIA is not set CONFIG_FB_RIVA=m +# CONFIG_FB_RIVA_I2C is not set +# CONFIG_FB_RIVA_DEBUG is not set CONFIG_FB_I810=m CONFIG_FB_I810_GTF=y +CONFIG_FB_I810_I2C=y +CONFIG_FB_INTEL=m +# CONFIG_FB_INTEL_DEBUG is not set CONFIG_FB_MATROX=m CONFIG_FB_MATROX_MILLENIUM=y CONFIG_FB_MATROX_MYSTIQUE=y -CONFIG_FB_MATROX_G450=y -CONFIG_FB_MATROX_G100=y +CONFIG_FB_MATROX_G=y CONFIG_FB_MATROX_I2C=m CONFIG_FB_MATROX_MAVEN=m CONFIG_FB_MATROX_MULTIHEAD=y -# CONFIG_FB_RADEON_OLD is not set CONFIG_FB_RADEON=m CONFIG_FB_RADEON_I2C=y # CONFIG_FB_RADEON_DEBUG is not set CONFIG_FB_ATY128=m CONFIG_FB_ATY=m CONFIG_FB_ATY_CT=y +CONFIG_FB_ATY_GENERIC_LCD=y CONFIG_FB_ATY_GX=y -# CONFIG_FB_ATY_XL_INIT is not set +CONFIG_FB_SAVAGE=m +CONFIG_FB_SAVAGE_I2C=y +CONFIG_FB_SAVAGE_ACCEL=y # CONFIG_FB_SIS is not set CONFIG_FB_NEOMAGIC=m CONFIG_FB_KYRO=m CONFIG_FB_3DFX=m CONFIG_FB_3DFX_ACCEL=y CONFIG_FB_VOODOO1=m +CONFIG_FB_CYBLA=m CONFIG_FB_TRIDENT=m CONFIG_FB_TRIDENT_ACCEL=y +# CONFIG_FB_GEODE is not set # CONFIG_FB_VIRTUAL is not set # # Console display driver support # CONFIG_VGA_CONSOLE=y -CONFIG_MDA_CONSOLE=m +CONFIG_VGACON_SOFT_SCROLLBACK=y +CONFIG_VGACON_SOFT_SCROLLBACK_SIZE=64 +# CONFIG_MDA_CONSOLE is not set CONFIG_DUMMY_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE=y -CONFIG_PCI_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y # CONFIG_FONTS is not set CONFIG_FONT_8x8=y CONFIG_FONT_8x16=y @@ -1775,6 +2465,11 @@ CONFIG_LOGO=y # CONFIG_LOGO_LINUX_MONO is not set # CONFIG_LOGO_LINUX_VGA16 is not set CONFIG_LOGO_LINUX_CLUT224=y +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_BACKLIGHT_CLASS_DEVICE=m +CONFIG_BACKLIGHT_DEVICE=y +CONFIG_LCD_CLASS_DEVICE=m +CONFIG_LCD_DEVICE=y # # Sound @@ -1794,8 +2489,13 @@ CONFIG_SND_SEQ_DUMMY=m CONFIG_SND_OSSEMUL=y CONFIG_SND_MIXER_OSS=m CONFIG_SND_PCM_OSS=m +CONFIG_SND_PCM_OSS_PLUGINS=y CONFIG_SND_SEQUENCER_OSS=y CONFIG_SND_RTCTIMER=m +CONFIG_SND_SEQ_RTCTIMER_DEFAULT=y +CONFIG_SND_DYNAMIC_MINORS=y +# CONFIG_SND_SUPPORT_OLD_API is not set +CONFIG_SND_VERBOSE_PROCFS=y # CONFIG_SND_VERBOSE_PRINTK is not set # CONFIG_SND_DEBUG is not set @@ -1806,6 +2506,8 @@ CONFIG_SND_MPU401_UART=m CONFIG_SND_OPL3_LIB=m CONFIG_SND_OPL4_LIB=m CONFIG_SND_VX_LIB=m +CONFIG_SND_AC97_CODEC=m +CONFIG_SND_AC97_BUS=m CONFIG_SND_DUMMY=m CONFIG_SND_VIRMIDI=m CONFIG_SND_MTPAV=m @@ -1815,87 +2517,102 @@ CONFIG_SND_MPU401=m # # ISA devices # -CONFIG_SND_AD1816A=m -CONFIG_SND_AD1848=m -CONFIG_SND_CS4231=m -CONFIG_SND_CS4232=m +CONFIG_SND_CS4231_LIB=m +CONFIG_SND_ADLIB=m +# CONFIG_SND_AD1816A is not set +# CONFIG_SND_AD1848 is not set +# CONFIG_SND_ALS100 is not set +# CONFIG_SND_AZT2320 is not set +# CONFIG_SND_CMI8330 is not set +# CONFIG_SND_CS4231 is not set +# CONFIG_SND_CS4232 is not set CONFIG_SND_CS4236=m -CONFIG_SND_ES968=m -CONFIG_SND_ES1688=m +# CONFIG_SND_DT019X is not set +# CONFIG_SND_ES968 is not set +# CONFIG_SND_ES1688 is not set CONFIG_SND_ES18XX=m -CONFIG_SND_GUSCLASSIC=m -CONFIG_SND_GUSEXTREME=m -CONFIG_SND_GUSMAX=m -CONFIG_SND_INTERWAVE=m -CONFIG_SND_INTERWAVE_STB=m -CONFIG_SND_OPTI92X_AD1848=m -CONFIG_SND_OPTI92X_CS4231=m -CONFIG_SND_OPTI93X=m -CONFIG_SND_SB8=m +# CONFIG_SND_GUSCLASSIC is not set +# CONFIG_SND_GUSEXTREME is not set +# CONFIG_SND_GUSMAX is not set +# CONFIG_SND_INTERWAVE is not set +# CONFIG_SND_INTERWAVE_STB is not set +CONFIG_SND_OPL3SA2=m +# CONFIG_SND_OPTI92X_AD1848 is not set +# CONFIG_SND_OPTI92X_CS4231 is not set +# CONFIG_SND_OPTI93X is not set +CONFIG_SND_MIRO=m +# CONFIG_SND_SB8 is not set CONFIG_SND_SB16=m CONFIG_SND_SBAWE=m -CONFIG_SND_SB16_CSP=y +# CONFIG_SND_SB16_CSP is not set +# CONFIG_SND_SGALAXY is not set +# CONFIG_SND_SSCAPE is not set # CONFIG_SND_WAVEFRONT is not set -CONFIG_SND_ALS100=m -CONFIG_SND_AZT2320=m -CONFIG_SND_CMI8330=m -CONFIG_SND_DT019X=m -CONFIG_SND_OPL3SA2=m -CONFIG_SND_SGALAXY=m -CONFIG_SND_SSCAPE=m # # PCI devices # -CONFIG_SND_AC97_CODEC=m +CONFIG_SND_AD1889=m +CONFIG_SND_ALS300=m +CONFIG_SND_ALS4000=m CONFIG_SND_ALI5451=m CONFIG_SND_ATIIXP=m +CONFIG_SND_ATIIXP_MODEM=m CONFIG_SND_AU8810=m CONFIG_SND_AU8820=m CONFIG_SND_AU8830=m CONFIG_SND_AZT3328=m CONFIG_SND_BT87X=m +# CONFIG_SND_BT87X_OVERCLOCK is not set +CONFIG_SND_CA0106=m +CONFIG_SND_CMIPCI=m +CONFIG_SND_CS4281=m CONFIG_SND_CS46XX=m CONFIG_SND_CS46XX_NEW_DSP=y -CONFIG_SND_CS4281=m +CONFIG_SND_CS5535AUDIO=m CONFIG_SND_EMU10K1=m -CONFIG_SND_KORG1212=m -CONFIG_SND_MIXART=m -CONFIG_SND_NM256=m -CONFIG_SND_RME32=m -CONFIG_SND_RME96=m -CONFIG_SND_RME9652=m -CONFIG_SND_HDSP=m -CONFIG_SND_TRIDENT=m -CONFIG_SND_YMFPCI=m -CONFIG_SND_ALS4000=m -CONFIG_SND_CMIPCI=m +CONFIG_SND_EMU10K1X=m CONFIG_SND_ENS1370=m CONFIG_SND_ENS1371=m CONFIG_SND_ES1938=m CONFIG_SND_ES1968=m -CONFIG_SND_MAESTRO3=m CONFIG_SND_FM801=m +CONFIG_SND_FM801_TEA575X_BOOL=y CONFIG_SND_FM801_TEA575X=m +CONFIG_SND_HDA_INTEL=m +CONFIG_SND_HDSP=m +CONFIG_SND_HDSPM=m CONFIG_SND_ICE1712=m CONFIG_SND_ICE1724=m CONFIG_SND_INTEL8X0=m CONFIG_SND_INTEL8X0M=m +CONFIG_SND_KORG1212=m +CONFIG_SND_MAESTRO3=m +CONFIG_SND_MIXART=m +CONFIG_SND_NM256=m +CONFIG_SND_PCXHR=m +CONFIG_SND_RIPTIDE=m +CONFIG_SND_RME32=m +CONFIG_SND_RME96=m +CONFIG_SND_RME9652=m CONFIG_SND_SONICVIBES=m +CONFIG_SND_TRIDENT=m CONFIG_SND_VIA82XX=m +CONFIG_SND_VIA82XX_MODEM=m CONFIG_SND_VX222=m +CONFIG_SND_YMFPCI=m # -# ALSA USB devices +# USB devices # CONFIG_SND_USB_AUDIO=m +CONFIG_SND_USB_USX2Y=m # # PCMCIA devices # # CONFIG_SND_VXPOCKET is not set -# CONFIG_SND_VXP440 is not set -CONFIG_SND_PDAUDIOCF=m +# CONFIG_SND_PDAUDIOCF is not set # # Open Sound System @@ -1905,6 +2622,9 @@ CONFIG_SND_PDAUDIOCF=m # # USB support # +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARCH_HAS_EHCI=y CONFIG_USB=y # CONFIG_USB_DEBUG is not set @@ -1914,6 +2634,8 @@ CONFIG_USB=y CONFIG_USB_DEVICEFS=y # CONFIG_USB_BANDWIDTH is not set # CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_SUSPEND is not set +# CONFIG_USB_OTG is not set # # USB Host Controller Drivers @@ -1921,36 +2643,46 @@ CONFIG_USB_DEVICEFS=y CONFIG_USB_EHCI_HCD=m CONFIG_USB_EHCI_SPLIT_ISO=y CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_ISP116X_HCD=m CONFIG_USB_OHCI_HCD=m +# CONFIG_USB_OHCI_BIG_ENDIAN is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y CONFIG_USB_UHCI_HCD=m +CONFIG_USB_SL811_HCD=m +CONFIG_USB_SL811_CS=m # # USB Device Class drivers # -CONFIG_USB_AUDIO=m +CONFIG_USB_ACM=m +CONFIG_USB_PRINTER=m # -# USB Bluetooth TTY can only be used with disabled Bluetooth subsystem +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# may also be needed; see USB_STORAGE Help for more information # -CONFIG_USB_MIDI=m -CONFIG_USB_ACM=m -CONFIG_USB_PRINTER=m CONFIG_USB_STORAGE=m # CONFIG_USB_STORAGE_DEBUG is not set CONFIG_USB_STORAGE_DATAFAB=y CONFIG_USB_STORAGE_FREECOM=y CONFIG_USB_STORAGE_ISD200=y CONFIG_USB_STORAGE_DPCM=y -CONFIG_USB_STORAGE_HP8200e=y +CONFIG_USB_STORAGE_USBAT=y CONFIG_USB_STORAGE_SDDR09=y CONFIG_USB_STORAGE_SDDR55=y CONFIG_USB_STORAGE_JUMPSHOT=y +CONFIG_USB_STORAGE_ALAUDA=y +CONFIG_USB_LIBUSUAL=y # -# USB Human Interface Devices (HID) +# USB Input Devices # CONFIG_USB_HID=y CONFIG_USB_HIDINPUT=y +# CONFIG_USB_HIDINPUT_POWERBOOK is not set CONFIG_HID_FF=y CONFIG_HID_PID=y CONFIG_LOGITECH_FF=y @@ -1958,64 +2690,50 @@ CONFIG_THRUSTMASTER_FF=y CONFIG_USB_HIDDEV=y CONFIG_USB_AIPTEK=m CONFIG_USB_WACOM=m +CONFIG_USB_ACECAD=m CONFIG_USB_KBTAB=m CONFIG_USB_POWERMATE=m -CONFIG_USB_MTOUCH=m -CONFIG_USB_EGALAX=m +CONFIG_USB_TOUCHSCREEN=m +CONFIG_USB_TOUCHSCREEN_EGALAX=y +CONFIG_USB_TOUCHSCREEN_PANJIT=y +CONFIG_USB_TOUCHSCREEN_3M=y +CONFIG_USB_TOUCHSCREEN_ITM=y +# CONFIG_USB_YEALINK is not set CONFIG_USB_XPAD=m CONFIG_USB_ATI_REMOTE=m +CONFIG_USB_ATI_REMOTE2=m +CONFIG_USB_KEYSPAN_REMOTE=m +CONFIG_USB_APPLETOUCH=m # # USB Imaging devices # CONFIG_USB_MDC800=m CONFIG_USB_MICROTEK=m -CONFIG_USB_HPUSBSCSI=m - -# -# USB Multimedia devices -# -CONFIG_USB_DABUSB=m -CONFIG_USB_VICAM=m -CONFIG_USB_DSBR=m -CONFIG_USB_IBMCAM=m -CONFIG_USB_KONICAWC=m -CONFIG_USB_OV511=m -CONFIG_USB_SE401=m -CONFIG_USB_STV680=m -CONFIG_USB_W9968CF=m # -# USB Network adaptors +# USB Network Adapters # CONFIG_USB_CATC=m CONFIG_USB_KAWETH=m CONFIG_USB_PEGASUS=m CONFIG_USB_RTL8150=m CONFIG_USB_USBNET=m - -# -# USB Host-to-Host Cables -# +CONFIG_USB_NET_AX8817X=m +CONFIG_USB_NET_CDCETHER=m +CONFIG_USB_NET_GL620A=m +CONFIG_USB_NET_NET1080=m +CONFIG_USB_NET_PLUSB=m +CONFIG_USB_NET_RNDIS_HOST=m +CONFIG_USB_NET_CDC_SUBSET=m CONFIG_USB_ALI_M5632=y CONFIG_USB_AN2720=y CONFIG_USB_BELKIN=y -CONFIG_USB_GENESYS=y -CONFIG_USB_NET1080=y -CONFIG_USB_PL2301=y - -# -# Intelligent USB Devices/Gadgets -# CONFIG_USB_ARMLINUX=y CONFIG_USB_EPSON2888=y -CONFIG_USB_ZAURUS=y -CONFIG_USB_CDCETHER=y - -# -# USB Network Adapters -# -CONFIG_USB_AX8817X=y +CONFIG_USB_NET_ZAURUS=m +CONFIG_USB_ZD1201=m +CONFIG_USB_MON=y # # USB port drivers @@ -2027,15 +2745,24 @@ CONFIG_USB_USS720=m # CONFIG_USB_SERIAL=m CONFIG_USB_SERIAL_GENERIC=y +CONFIG_USB_SERIAL_AIRPRIME=m +CONFIG_USB_SERIAL_ANYDATA=m +CONFIG_USB_SERIAL_ARK3116=m CONFIG_USB_SERIAL_BELKIN=m +CONFIG_USB_SERIAL_WHITEHEAT=m CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m +CONFIG_USB_SERIAL_CP2101=m +CONFIG_USB_SERIAL_CYPRESS_M8=m CONFIG_USB_SERIAL_EMPEG=m CONFIG_USB_SERIAL_FTDI_SIO=m +CONFIG_USB_SERIAL_FUNSOFT=m CONFIG_USB_SERIAL_VISOR=m CONFIG_USB_SERIAL_IPAQ=m CONFIG_USB_SERIAL_IR=m CONFIG_USB_SERIAL_EDGEPORT=m CONFIG_USB_SERIAL_EDGEPORT_TI=m +CONFIG_USB_SERIAL_GARMIN=m +CONFIG_USB_SERIAL_IPW=m CONFIG_USB_SERIAL_KEYSPAN_PDA=m CONFIG_USB_SERIAL_KEYSPAN=m CONFIG_USB_SERIAL_KEYSPAN_MPR=y @@ -2053,11 +2780,15 @@ CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y CONFIG_USB_SERIAL_KLSI=m CONFIG_USB_SERIAL_KOBIL_SCT=m CONFIG_USB_SERIAL_MCT_U232=m +CONFIG_USB_SERIAL_NAVMAN=m CONFIG_USB_SERIAL_PL2303=m +CONFIG_USB_SERIAL_HP4X=m CONFIG_USB_SERIAL_SAFE=m CONFIG_USB_SERIAL_SAFE_PADDED=y +CONFIG_USB_SERIAL_TI=m CONFIG_USB_SERIAL_CYBERJACK=m CONFIG_USB_SERIAL_XIRCOM=m +CONFIG_USB_SERIAL_OPTION=m CONFIG_USB_SERIAL_OMNINET=m CONFIG_USB_EZUSB=y @@ -2065,22 +2796,111 @@ CONFIG_USB_EZUSB=y # USB Miscellaneous drivers # CONFIG_USB_EMI62=m -# CONFIG_USB_EMI26 is not set -CONFIG_USB_TIGL=m +CONFIG_USB_EMI26=m CONFIG_USB_AUERSWALD=m CONFIG_USB_RIO500=m CONFIG_USB_LEGOTOWER=m CONFIG_USB_LCD=m CONFIG_USB_LED=m # CONFIG_USB_CYTHERM is not set +CONFIG_USB_PHIDGETKIT=m CONFIG_USB_PHIDGETSERVO=m +CONFIG_USB_IDMOUSE=m +CONFIG_USB_SISUSBVGA=m +CONFIG_USB_SISUSBVGA_CON=y +CONFIG_USB_LD=m CONFIG_USB_TEST=m +# +# USB DSL modem support +# +CONFIG_USB_ATM=m +CONFIG_USB_SPEEDTOUCH=m +CONFIG_USB_CXACRU=m +CONFIG_USB_UEAGLEATM=m +CONFIG_USB_XUSBATM=m + # # USB Gadget Support # # CONFIG_USB_GADGET is not set +# +# MMC/SD Card support +# +CONFIG_MMC=m +# CONFIG_MMC_DEBUG is not set +CONFIG_MMC_BLOCK=m +CONFIG_MMC_SDHCI=m +CONFIG_MMC_WBSD=m + +# +# LED devices +# +# CONFIG_NEW_LEDS is not set + +# +# LED drivers +# + +# +# LED Triggers +# + +# +# InfiniBand support +# +CONFIG_INFINIBAND=m +CONFIG_INFINIBAND_USER_MAD=m +CONFIG_INFINIBAND_USER_ACCESS=m +CONFIG_INFINIBAND_MTHCA=m +CONFIG_INFINIBAND_MTHCA_DEBUG=y +CONFIG_INFINIBAND_IPOIB=m +CONFIG_INFINIBAND_IPOIB_DEBUG=y +CONFIG_INFINIBAND_IPOIB_DEBUG_DATA=y +CONFIG_INFINIBAND_SRP=m + +# +# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) +# +CONFIG_EDAC=y + +# +# Reporting subsystems +# +# CONFIG_EDAC_DEBUG is not set +CONFIG_EDAC_MM_EDAC=m +CONFIG_EDAC_AMD76X=m +CONFIG_EDAC_E7XXX=m +CONFIG_EDAC_E752X=m +CONFIG_EDAC_I82875P=m +CONFIG_EDAC_I82860=m +CONFIG_EDAC_R82600=m +CONFIG_EDAC_POLL=y + +# +# Real Time Clock +# +CONFIG_RTC_LIB=m +CONFIG_RTC_CLASS=m + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=m +CONFIG_RTC_INTF_PROC=m +CONFIG_RTC_INTF_DEV=m + +# +# RTC drivers +# +CONFIG_RTC_DRV_X1205=m +CONFIG_RTC_DRV_DS1672=m +CONFIG_RTC_DRV_PCF8563=m +CONFIG_RTC_DRV_RS5C372=m +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_TEST is not set + # # File systems # @@ -2088,6 +2908,8 @@ CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y CONFIG_EXT2_FS_POSIX_ACL=y CONFIG_EXT2_FS_SECURITY=y +CONFIG_EXT2_FS_XIP=y +CONFIG_FS_XIP=y CONFIG_EXT3_FS=m CONFIG_EXT3_FS_XATTR=y CONFIG_EXT3_FS_POSIX_ACL=y @@ -2103,22 +2925,28 @@ CONFIG_REISERFS_FS_POSIX_ACL=y CONFIG_REISERFS_FS_SECURITY=y CONFIG_JFS_FS=m CONFIG_JFS_POSIX_ACL=y +CONFIG_JFS_SECURITY=y # CONFIG_JFS_DEBUG is not set # CONFIG_JFS_STATISTICS is not set CONFIG_FS_POSIX_ACL=y CONFIG_XFS_FS=m -# CONFIG_XFS_RT is not set +CONFIG_XFS_EXPORT=y CONFIG_XFS_QUOTA=y CONFIG_XFS_SECURITY=y CONFIG_XFS_POSIX_ACL=y +# CONFIG_XFS_RT is not set +CONFIG_OCFS2_FS=m CONFIG_MINIX_FS=m CONFIG_ROMFS_FS=m +CONFIG_INOTIFY=y CONFIG_QUOTA=y # CONFIG_QFMT_V1 is not set CONFIG_QFMT_V2=y CONFIG_QUOTACTL=y +CONFIG_DNOTIFY=y CONFIG_AUTOFS_FS=m CONFIG_AUTOFS4_FS=m +CONFIG_FUSE_FS=m # # CD-ROM/DVD Filesystems @@ -2128,6 +2956,7 @@ CONFIG_JOLIET=y CONFIG_ZISOFS=y CONFIG_ZISOFS_FS=y CONFIG_UDF_FS=m +CONFIG_UDF_NLS=y # # DOS/FAT/NT Filesystems @@ -2135,6 +2964,8 @@ CONFIG_UDF_FS=m CONFIG_FAT_FS=m CONFIG_MSDOS_FS=m CONFIG_VFAT_FS=m +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="ascii" # CONFIG_NTFS_FS is not set # @@ -2143,13 +2974,11 @@ CONFIG_VFAT_FS=m CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_SYSFS=y -# CONFIG_DEVFS_FS is not set -CONFIG_DEVPTS_FS_XATTR=y -CONFIG_DEVPTS_FS_SECURITY=y CONFIG_TMPFS=y CONFIG_HUGETLBFS=y CONFIG_HUGETLB_PAGE=y CONFIG_RAMFS=y +CONFIG_CONFIGFS_FS=m # # Miscellaneous filesystems @@ -2165,37 +2994,52 @@ CONFIG_EFS_FS=m # CONFIG_JFFS_FS is not set CONFIG_JFFS2_FS=m CONFIG_JFFS2_FS_DEBUG=0 -CONFIG_JFFS2_FS_NAND=y +CONFIG_JFFS2_FS_WRITEBUFFER=y +CONFIG_JFFS2_SUMMARY=y +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set CONFIG_CRAMFS=m +CONFIG_SQUASHFS=m +# CONFIG_SQUASHFS_EMBEDDED is not set +CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 +# CONFIG_SQUASHFS_VMALLOC is not set CONFIG_VXFS_FS=m # CONFIG_HPFS_FS is not set CONFIG_QNX4FS_FS=m -# CONFIG_QNX4FS_RW is not set CONFIG_SYSV_FS=m CONFIG_UFS_FS=m -# CONFIG_UFS_FS_WRITE is not set # # Network File Systems # CONFIG_NFS_FS=m CONFIG_NFS_V3=y +CONFIG_NFS_V3_ACL=y CONFIG_NFS_V4=y CONFIG_NFS_DIRECTIO=y CONFIG_NFSD=m +CONFIG_NFSD_V2_ACL=y CONFIG_NFSD_V3=y +CONFIG_NFSD_V3_ACL=y CONFIG_NFSD_V4=y CONFIG_NFSD_TCP=y CONFIG_LOCKD=m CONFIG_LOCKD_V4=y CONFIG_EXPORTFS=m +CONFIG_NFS_ACL_SUPPORT=m +CONFIG_NFS_COMMON=y CONFIG_SUNRPC=m CONFIG_SUNRPC_GSS=m CONFIG_RPCSEC_GSS_KRB5=m -CONFIG_SMB_FS=m -# CONFIG_SMB_NLS_DEFAULT is not set +CONFIG_RPCSEC_GSS_SPKM3=m +# CONFIG_SMB_FS is not set CONFIG_CIFS=m # CONFIG_CIFS_STATS is not set +CONFIG_CIFS_XATTR=y +CONFIG_CIFS_POSIX=y +# CONFIG_CIFS_EXPERIMENTAL is not set CONFIG_NCP_FS=m CONFIG_NCPFS_PACKET_SIGNING=y CONFIG_NCPFS_IOCTL_LOCKING=y @@ -2205,8 +3049,10 @@ CONFIG_NCPFS_OS2_NS=y CONFIG_NCPFS_SMALLDOS=y CONFIG_NCPFS_NLS=y CONFIG_NCPFS_EXTRAS=y -# CONFIG_CODA_FS is not set +CONFIG_CODA_FS=m +# CONFIG_CODA_FS_OLD_API is not set # CONFIG_AFS_FS is not set +CONFIG_9P_FS=m # # Partition Types @@ -2214,7 +3060,7 @@ CONFIG_NCPFS_EXTRAS=y CONFIG_PARTITION_ADVANCED=y # CONFIG_ACORN_PARTITION is not set CONFIG_OSF_PARTITION=y -# CONFIG_AMIGA_PARTITION is not set +CONFIG_AMIGA_PARTITION=y # CONFIG_ATARI_PARTITION is not set CONFIG_MAC_PARTITION=y CONFIG_MSDOS_PARTITION=y @@ -2223,10 +3069,10 @@ CONFIG_MINIX_SUBPARTITION=y CONFIG_SOLARIS_X86_PARTITION=y CONFIG_UNIXWARE_DISKLABEL=y # CONFIG_LDM_PARTITION is not set -# CONFIG_NEC98_PARTITION is not set CONFIG_SGI_PARTITION=y # CONFIG_ULTRIX_PARTITION is not set CONFIG_SUN_PARTITION=y +CONFIG_KARMA_PARTITION=y CONFIG_EFI_PARTITION=y # @@ -2234,7 +3080,7 @@ CONFIG_EFI_PARTITION=y # CONFIG_NLS=y CONFIG_NLS_DEFAULT="utf8" -CONFIG_NLS_CODEPAGE_437=m +CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_CODEPAGE_737=m CONFIG_NLS_CODEPAGE_775=m CONFIG_NLS_CODEPAGE_850=m @@ -2257,6 +3103,7 @@ CONFIG_NLS_CODEPAGE_874=m CONFIG_NLS_ISO8859_8=m CONFIG_NLS_CODEPAGE_1250=m CONFIG_NLS_CODEPAGE_1251=m +CONFIG_NLS_ASCII=y CONFIG_NLS_ISO8859_1=m CONFIG_NLS_ISO8859_2=m CONFIG_NLS_ISO8859_3=m @@ -2273,41 +3120,68 @@ CONFIG_NLS_KOI8_U=m CONFIG_NLS_UTF8=m # -# Profiling support +# Instrumentation Support # CONFIG_PROFILING=y CONFIG_OPROFILE=m +CONFIG_KPROBES=y # # Kernel hacking # +# CONFIG_PRINTK_TIME is not set +CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_KERNEL=y -CONFIG_EARLY_PRINTK=y -CONFIG_DEBUG_STACKOVERFLOW=y -# CONFIG_DEBUG_STACK_USAGE is not set +CONFIG_LOG_BUF_SHIFT=17 +CONFIG_DETECT_SOFTLOCKUP=y +CONFIG_SCHEDSTATS=y # CONFIG_DEBUG_SLAB is not set -CONFIG_MAGIC_SYSRQ=y -# CONFIG_DEBUG_SPINLOCK is not set -# CONFIG_DEBUG_PAGEALLOC is not set -# CONFIG_DEBUG_HIGHMEM is not set -CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_MUTEXES=y +CONFIG_DEBUG_SPINLOCK=y CONFIG_DEBUG_SPINLOCK_SLEEP=y +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_HIGHMEM=y +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_FS=y +CONFIG_DEBUG_VM=y # CONFIG_FRAME_POINTER is not set +CONFIG_UNWIND_INFO=y +# CONFIG_FORCED_INLINING is not set +CONFIG_BOOT_DELAY=y +# CONFIG_RCU_TORTURE_TEST is not set +CONFIG_EARLY_PRINTK=y +CONFIG_DEBUG_STACKOVERFLOW=y +CONFIG_DEBUG_STACK_USAGE=y +CONFIG_STACK_BACKTRACE_COLS=2 + +# +# Page alloc debug is incompatible with Software Suspend on i386 +# +CONFIG_DEBUG_RODATA=y +CONFIG_4KSTACKS=y CONFIG_X86_FIND_SMP_CONFIG=y CONFIG_X86_MPPARSE=y +CONFIG_DOUBLEFAULT=y # # Security options # +CONFIG_KEYS=y +CONFIG_KEYS_DEBUG_PROC_KEYS=y CONFIG_SECURITY=y CONFIG_SECURITY_NETWORK=y +CONFIG_SECURITY_NETWORK_XFRM=y CONFIG_SECURITY_CAPABILITIES=y # CONFIG_SECURITY_ROOTPLUG is not set +# CONFIG_SECURITY_SECLVL is not set CONFIG_SECURITY_SELINUX=y CONFIG_SECURITY_SELINUX_BOOTPARAM=y +CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=1 CONFIG_SECURITY_SELINUX_DISABLE=y CONFIG_SECURITY_SELINUX_DEVELOP=y -# CONFIG_SECURITY_SELINUX_MLS is not set +CONFIG_SECURITY_SELINUX_AVC_STATS=y +CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1 # # Cryptographic options @@ -2317,32 +3191,51 @@ CONFIG_CRYPTO_HMAC=y CONFIG_CRYPTO_NULL=m CONFIG_CRYPTO_MD4=m CONFIG_CRYPTO_MD5=y -CONFIG_CRYPTO_SHA1=m +CONFIG_CRYPTO_SHA1=y CONFIG_CRYPTO_SHA256=m CONFIG_CRYPTO_SHA512=m +CONFIG_CRYPTO_WP512=m +CONFIG_CRYPTO_TGR192=m CONFIG_CRYPTO_DES=m CONFIG_CRYPTO_BLOWFISH=m CONFIG_CRYPTO_TWOFISH=m CONFIG_CRYPTO_SERPENT=m CONFIG_CRYPTO_AES=m +CONFIG_CRYPTO_AES_586=m CONFIG_CRYPTO_CAST5=m CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_TEA=m CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_KHAZAD=m +CONFIG_CRYPTO_ANUBIS=m CONFIG_CRYPTO_DEFLATE=m CONFIG_CRYPTO_MICHAEL_MIC=m CONFIG_CRYPTO_CRC32C=m # CONFIG_CRYPTO_TEST is not set +CONFIG_CRYPTO_SIGNATURE=y +CONFIG_CRYPTO_SIGNATURE_DSA=y +CONFIG_CRYPTO_MPILIB=y + +# +# Hardware crypto devices +# +CONFIG_CRYPTO_DEV_PADLOCK=m +CONFIG_CRYPTO_DEV_PADLOCK_AES=y # # Library routines # +CONFIG_CRC_CCITT=m +CONFIG_CRC16=m CONFIG_CRC32=y CONFIG_LIBCRC32C=m CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=m -CONFIG_X86_SMP=y -CONFIG_X86_HT=y +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_KMP=m +CONFIG_TEXTSEARCH_BM=m +CONFIG_TEXTSEARCH_FSM=m +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y CONFIG_X86_BIOS_REBOOT=y -CONFIG_X86_TRAMPOLINE=y -CONFIG_X86_STD_RESOURCES=y -CONFIG_PC=y +CONFIG_KTIME_SCALAR=y diff --git a/.config.old b/.config.old index a1d48d7b8..8a7fee71e 100644 --- a/.config.old +++ b/.config.old @@ -1,44 +1,45 @@ +# i386 # # Automatically generated make config: don't edit # CONFIG_MMU=y -CONFIG_UID16=y -CONFIG_GENERIC_ISA_DMA=y -CONFIG_SMP=y -# CONFIG_HOTPLUG_CPU is not set -CONFIG_SCHED_SMT=y - +# CONFIG_SMP is not set +CONFIG_HOTPLUG_CPU=y +CONFIG_LOCALVERSION="" +# CONFIG_CRASH_DUMP is not set # # Code maturity level options # CONFIG_EXPERIMENTAL=y -CONFIG_CLEAN_COMPILE=y CONFIG_STANDALONE=y - +CONFIG_PREVENT_FIRMWARE_BUILD=y # # General setup # +# CONFIG_LOCALVERSION_AUTO is not set CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_BSD_PROCESS_ACCT=y +# CONFIG_BSD_PROCESS_ACCT_V3 is not set CONFIG_SYSCTL=y CONFIG_LOG_BUF_SHIFT=17 # CONFIG_IKCONFIG is not set # CONFIG_EMBEDDED is not set CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set +CONFIG_KALLSYMS_EXTRA_PASS=y CONFIG_FUTEX=y CONFIG_EPOLL=y CONFIG_IOSCHED_NOOP=y CONFIG_IOSCHED_AS=y CONFIG_IOSCHED_DEADLINE=y -# CONFIG_NUMA is not set -# CONFIG_PREEMPT is not set -# CONFIG_IRQBALANCE is not set +CONFIG_IOSCHED_CFQ=y +CONFIG_DEFAULT_CFQ=y CONFIG_POSIX_MQUEUE=y -CONFIG_EDD=m -# CONFIG_SMBIOS is not set -CONFIG_IRQSTACKS=y +# CONFIG_PREEMPT_NONE is not set +CONFIG_PREEMPT_VOLUNTARY=y +# CONFIG_PREEMPT is not set +CONFIG_PREEMPT_BKL=y # # Loadable module support @@ -47,107 +48,67 @@ CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set CONFIG_OBSOLETE_MODPARM=y -# CONFIG_MODVERSIONS is not set +CONFIG_MODVERSIONS=y +CONFIG_MODULE_SRCVERSION_ALL=y CONFIG_KMOD=y - -# -# Power management options (ACPI, APM) -# -CONFIG_PM=y -# CONFIG_SOFTWARE_SUSPEND is not set -# CONFIG_PM_DISK is not set - -# -# ACPI (Advanced Configuration and Power Interface) Support -# -CONFIG_ACPI=y -CONFIG_ACPI_BOOT=y -CONFIG_ACPI_INTERPRETER=y -CONFIG_ACPI_SLEEP=y -CONFIG_ACPI_AC=m -CONFIG_ACPI_BATTERY=m -CONFIG_ACPI_BUTTON=m -CONFIG_ACPI_FAN=y -CONFIG_ACPI_PROCESSOR=y -CONFIG_ACPI_THERMAL=y -CONFIG_ACPI_ASUS=m -CONFIG_ACPI_TOSHIBA=m -# CONFIG_ACPI_DEBUG is not set -CONFIG_ACPI_BUS=y -CONFIG_ACPI_EC=y -CONFIG_ACPI_POWER=y -CONFIG_ACPI_PCI=y -CONFIG_ACPI_SYSTEM=y -CONFIG_ACPI_NUMA=y - -# -# CPU Frequency scaling -# -CONFIG_CPU_FREQ=y -# CONFIG_CPU_FREQ_PROC_INTF is not set -# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set -CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y -CONFIG_CPU_FREQ_GOV_PERFORMANCE=y -CONFIG_CPU_FREQ_GOV_POWERSAVE=m -CONFIG_CPU_FREQ_GOV_USERSPACE=m -# CONFIG_CPU_FREQ_24_API is not set -CONFIG_CPU_FREQ_TABLE=y - +CONFIG_MODULE_SIG=y +# CONFIG_MODULE_SIG_FORCE is not set # # Bus options (PCI, PCMCIA, EISA, MCA, ISA) # CONFIG_PCI=y -# CONFIG_PCI_GOBIOS is not set -# CONFIG_PCI_GOMMCONFIG is not set -# CONFIG_PCI_GODIRECT is not set -CONFIG_PCI_GOANY=y -CONFIG_PCI_BIOS=y -CONFIG_PCI_DIRECT=y -CONFIG_PCI_MMCONFIG=y +# CONFIG_PCI_DEBUG is not set +CONFIG_PCI_MSI=y CONFIG_PCI_LEGACY_PROC=y -# CONFIG_PCI_NAMES is not set -CONFIG_PCI_USE_VECTOR=y +CONFIG_PCIEPORTBUS=y +CONFIG_HOTPLUG_PCI_PCIE=m +CONFIG_HOTPLUG_PCI_FAKE=m +# CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE is not set CONFIG_ISA=y # CONFIG_EISA is not set # CONFIG_MCA is not set # CONFIG_SCx200 is not set CONFIG_HOTPLUG=y +# CONFIG_DEBUG_KOBJECT is not set # # PCMCIA/CardBus support # -CONFIG_PCMCIA=m +CONFIG_PCMCIA=y +CONFIG_PCMCIA_LOAD_CIS=y # CONFIG_PCMCIA_DEBUG is not set CONFIG_YENTA=y CONFIG_CARDBUS=y CONFIG_I82092=m -CONFIG_I82365=m -CONFIG_TCIC=m -CONFIG_PCMCIA_PROBE=y - -# -# PCI Hotplug Support -# -CONFIG_HOTPLUG_PCI=y -# CONFIG_HOTPLUG_PCI_FAKE is not set -CONFIG_HOTPLUG_PCI_COMPAQ=m -# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set -CONFIG_HOTPLUG_PCI_IBM=m -# CONFIG_HOTPLUG_PCI_ACPI is not set -# CONFIG_HOTPLUG_PCI_CPCI is not set -CONFIG_HOTPLUG_PCI_PCIE=m -CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE=y -CONFIG_HOTPLUG_PCI_SHPC=m -CONFIG_HOTPLUG_PCI_SHPC_POLL_EVENT_MODE=y -# CONFIG_HOTPLUG_PCI_SHPC_PHPRM_LEGACY is not set +CONFIG_PD6729=m +CONFIG_PCMCIA_IOCTL=y + +CONFIG_PCCARD=y +CONFIG_MMC=m +# CONFIG_MMC_DEBUG is not set +CONFIG_MMC_BLOCK=y +CONFIG_MMC_WBSD=y +CONFIG_MMC_SDHCI=m + +CONFIG_INFINIBAND=m +CONFIG_INFINIBAND_MTHCA=m +# CONFIG_INFINIBAND_MTHCA_DEBUG is not set +CONFIG_INFINIBAND_IPOIB=m +CONFIG_INFINIBAND_IPOIB_DEBUG=y +CONFIG_INFINIBAND_IPOIB_DEBUG_DATA=y +CONFIG_INFINIBAND_SRP=m +CONFIG_INFINIBAND_USER_MAD=m +CONFIG_INFINIBAND_USER_ACCESS=m +CONFIG_IPATH_CORE=m +CONFIG_INFINIBAND_IPATH=m # # Executable file formats # CONFIG_BINFMT_ELF=y # CONFIG_BINFMT_AOUT is not set -CONFIG_BINFMT_MISC=m +CONFIG_BINFMT_MISC=y # # Device Drivers @@ -158,26 +119,28 @@ CONFIG_BINFMT_MISC=m # CONFIG_FW_LOADER=y +# CONFIG_SPI is not set + # # Memory Technology Devices (MTD) # CONFIG_MTD=m # CONFIG_MTD_DEBUG is not set -CONFIG_MTD_PARTITIONS=m +CONFIG_MTD_PARTITIONS=y CONFIG_MTD_CONCAT=m -CONFIG_MTD_REDBOOT_PARTS=m -CONFIG_MTD_CMDLINE_PARTS=m - +CONFIG_MTD_CMDLINE_PARTS=y # # User Modules And Translation Layers # CONFIG_MTD_CHAR=m CONFIG_MTD_BLOCK=m CONFIG_MTD_BLOCK_RO=m +CONFIG_MTD_BLOCK2MTD=m CONFIG_FTL=m CONFIG_NFTL=m CONFIG_NFTL_RW=y CONFIG_INFTL=m +CONFIG_RFD_FTL=m # # RAM/ROM/Flash chip drivers @@ -202,16 +165,15 @@ CONFIG_MTD_COMPLEX_MAPPINGS=y # CONFIG_MTD_PNC2000 is not set CONFIG_MTD_SC520CDP=m CONFIG_MTD_NETSC520=m -CONFIG_MTD_SBC_GXX=m -CONFIG_MTD_ELAN_104NC=m +# CONFIG_MTD_SBC_GXX is not set CONFIG_MTD_SCx200_DOCFLASH=m -CONFIG_MTD_AMD76XROM=m -CONFIG_MTD_ICH2ROM=m +# CONFIG_MTD_AMD76XROM is not set CONFIG_MTD_SCB2_FLASH=m # CONFIG_MTD_NETtel is not set # CONFIG_MTD_DILNETPC is not set -CONFIG_MTD_L440GX=m +# CONFIG_MTD_L440GX is not set CONFIG_MTD_PCI=m +CONFIG_MTD_TS5500=m # # Self-contained MTD device drivers @@ -241,18 +203,32 @@ CONFIG_MTD_DOCPROBE_ADDRESS=0 CONFIG_MTD_NAND=m # CONFIG_MTD_NAND_VERIFY_WRITE is not set CONFIG_MTD_NAND_IDS=m +CONFIG_MTD_NAND_NANDSIM=m +# CONFIG_MTD_ONENAND is not set + +CONFIG_MTD_REDBOOT_PARTS=m +# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set +# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +CONFIG_MTD_CFI_AMDSTD_RETRY=3 +# CONFIG_MTD_XIP is not set +# CONFIG_MTD_ICHXROM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_NAND_DISKONCHIP is not set +# CONFIG_MTD_PLATRAM is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_FS_WRITEBUFFER=y +CONFIG_JFFS2_SUMMARY=y # # Parallel port support # CONFIG_PARPORT=m CONFIG_PARPORT_PC=m -CONFIG_PARPORT_PC_CML1=m CONFIG_PARPORT_SERIAL=m # CONFIG_PARPORT_PC_FIFO is not set # CONFIG_PARPORT_PC_SUPERIO is not set CONFIG_PARPORT_PC_PCMCIA=m -# CONFIG_PARPORT_OTHER is not set CONFIG_PARPORT_1284=y # @@ -266,13 +242,37 @@ CONFIG_PNP=y # CONFIG_ISAPNP=y # CONFIG_PNPBIOS is not set +# CONFIG_ACPI_CONTAINER is not set +# CONFIG_ACPI_SLEEP_PROC_SLEEP is not set +# CONFIG_ACPI_HOTKEY is not set # # Block devices # CONFIG_BLK_DEV_FD=m # CONFIG_BLK_DEV_XD is not set -# CONFIG_PARIDE is not set +CONFIG_PARIDE=m +CONFIG_PARIDE_PD=m +CONFIG_PARIDE_PCD=m +CONFIG_PARIDE_PF=m +CONFIG_PARIDE_PT=m +CONFIG_PARIDE_PG=m +CONFIG_PARIDE_ATEN=m +CONFIG_PARIDE_BPCK=m +CONFIG_PARIDE_BPCK6=m +CONFIG_PARIDE_COMM=m +CONFIG_PARIDE_DSTR=m +CONFIG_PARIDE_FIT2=m +CONFIG_PARIDE_FIT3=m +CONFIG_PARIDE_EPAT=m +CONFIG_PARIDE_EPATC8=y +CONFIG_PARIDE_EPIA=m +CONFIG_PARIDE_FRIQ=m +CONFIG_PARIDE_FRPW=m +CONFIG_PARIDE_KBIC=m +CONFIG_PARIDE_KTTI=m +CONFIG_PARIDE_ON20=m +CONFIG_PARIDE_ON26=m CONFIG_BLK_CPQ_DA=m CONFIG_BLK_CPQ_CISS_DA=m CONFIG_CISS_SCSI_TAPE=y @@ -282,12 +282,13 @@ CONFIG_BLK_DEV_LOOP=m CONFIG_BLK_DEV_CRYPTOLOOP=m CONFIG_BLK_DEV_NBD=m CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=16384 CONFIG_BLK_DEV_INITRD=y CONFIG_BLK_DEV_ATIIXP=y CONFIG_LBD=y -# CONFIG_DCSSBLK is not set - +CONFIG_BLK_DEV_IO_TRACE=y +CONFIG_LSF=y # # ATA/ATAPI/MFM/RLL support @@ -304,20 +305,19 @@ CONFIG_BLK_DEV_IDE=y # CONFIG_BLK_DEV_HD_IDE is not set CONFIG_BLK_DEV_IDEDISK=y CONFIG_IDEDISK_MULTI_MODE=y -# CONFIG_IDEDISK_STROKE is not set CONFIG_BLK_DEV_IDECS=m CONFIG_BLK_DEV_IDECD=y -CONFIG_BLK_DEV_IDETAPE=m +# CONFIG_BLK_DEV_IDETAPE is not set CONFIG_BLK_DEV_IDEFLOPPY=y -# CONFIG_BLK_DEV_IDESCSI is not set -# CONFIG_IDE_TASK_IOCTL is not set -# CONFIG_IDE_TASKFILE_IO is not set +CONFIG_BLK_DEV_IDESCSI=m +CONFIG_IDE_TASK_IOCTL=y +# CONFIG_BLK_DEV_IDE_SATA is not set # # IDE chipset support/bugfixes # -# CONFIG_BLK_DEV_CMD640 is not set -# CONFIG_BLK_DEV_CMD640_ENHANCED is not set +CONFIG_BLK_DEV_CMD640=y +CONFIG_BLK_DEV_CMD640_ENHANCED=y CONFIG_BLK_DEV_IDEPNP=y CONFIG_BLK_DEV_IDEPCI=y CONFIG_IDEPCI_SHARE_IRQ=y @@ -326,11 +326,9 @@ CONFIG_BLK_DEV_GENERIC=y # CONFIG_BLK_DEV_OPTI621 is not set CONFIG_BLK_DEV_RZ1000=y CONFIG_BLK_DEV_IDEDMA_PCI=y -# CONFIG_BLK_DEV_IDE_TCQ is not set # CONFIG_BLK_DEV_IDEDMA_FORCED is not set CONFIG_IDEDMA_PCI_AUTO=y # CONFIG_IDEDMA_ONLYDISK is not set -CONFIG_BLK_DEV_ADMA=y CONFIG_BLK_DEV_AEC62XX=y CONFIG_BLK_DEV_ALI15X3=y # CONFIG_WDC_ALI15X3 is not set @@ -340,15 +338,16 @@ CONFIG_BLK_DEV_TRIFLEX=y CONFIG_BLK_DEV_CY82C693=y CONFIG_BLK_DEV_CS5520=y CONFIG_BLK_DEV_CS5530=y +CONFIG_BLK_DEV_CS5535=y CONFIG_BLK_DEV_HPT34X=y CONFIG_BLK_DEV_HPT366=y +CONFIG_BLK_DEV_IT821X=y # CONFIG_BLK_DEV_SC1200 is not set CONFIG_BLK_DEV_PIIX=y # CONFIG_BLK_DEV_NS87415 is not set CONFIG_BLK_DEV_PDC202XX_OLD=y # CONFIG_PDC202XX_BURST is not set CONFIG_BLK_DEV_PDC202XX_NEW=y -CONFIG_PDC202XX_FORCE=y CONFIG_BLK_DEV_SVWKS=y CONFIG_BLK_DEV_SIIMAGE=y CONFIG_BLK_DEV_SIS5513=y @@ -359,7 +358,6 @@ CONFIG_BLK_DEV_VIA82CXXX=y CONFIG_BLK_DEV_IDEDMA=y # CONFIG_IDEDMA_IVB is not set CONFIG_IDEDMA_AUTO=y -# CONFIG_DMA_NONPCI is not set # CONFIG_BLK_DEV_HD is not set # @@ -377,25 +375,29 @@ CONFIG_CHR_DEV_OSST=m CONFIG_BLK_DEV_SR=m CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=m +CONFIG_CHR_DEV_SCH=m # # Some SCSI devices (e.g. CD jukebox) support multiple LUNs # -# CONFIG_SCSI_MULTI_LUN is not set -CONFIG_SCSI_REPORT_LUNS=y +CONFIG_SCSI_MULTI_LUN=y CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_LOGGING=y -CONFIG_SCSI_SPI_ATTRS=y -CONFIG_SCSI_FC_ATTRS=y +CONFIG_SCSI_SPI_ATTRS=m +CONFIG_SCSI_FC_ATTRS=m +CONFIG_SCSI_ISCSI_ATTRS=m +CONFIG_SCSI_SAS_ATTRS=m +CONFIG_RAID_ATTRS=m + +CONFIG_ISCSI_TCP=m # # SCSI low-level drivers # CONFIG_BLK_DEV_3W_XXXX_RAID=m +CONFIG_SCSI_3W_9XXX=m # CONFIG_SCSI_7000FASST is not set CONFIG_SCSI_ACARD=m -CONFIG_SCSI_AHA152X=m -CONFIG_SCSI_AHA1542=m CONFIG_SCSI_AACRAID=m CONFIG_SCSI_AIC7XXX=m CONFIG_AIC7XXX_CMDS_PER_DEVICE=4 @@ -415,66 +417,68 @@ CONFIG_AIC79XX_RESET_DELAY_MS=15000 CONFIG_AIC79XX_DEBUG_MASK=0 # CONFIG_AIC79XX_REG_PRETTY_PRINT is not set CONFIG_SCSI_ADVANSYS=m -CONFIG_SCSI_IN2000=m -CONFIG_SCSI_MEGARAID=m +CONFIG_MEGARAID_NEWGEN=y +CONFIG_MEGARAID_MM=m +CONFIG_MEGARAID_MAILBOX=m +CONFIG_MEGARAID_LEGACY=m +CONFIG_MEGARAID_SAS=m CONFIG_SCSI_SATA=y CONFIG_SCSI_SATA_SVW=m CONFIG_SCSI_ATA_PIIX=m CONFIG_SCSI_SATA_PROMISE=m CONFIG_SCSI_SATA_VIA=m -CONFIG_BLK_DEV_CARMEL=m +CONFIG_BLK_DEV_SX8=m CONFIG_SCSI_SATA_VITESSE=m CONFIG_SCSI_SATA_SIL=m CONFIG_SCSI_SATA_SIS=m CONFIG_SCSI_SATA_SX4=m +CONFIG_SCSI_SATA_NV=m +CONFIG_SCSI_SATA_AHCI=m +CONFIG_SCSI_SATA_ULI=m +CONFIG_SCSI_SATA_QSTOR=m +CONFIG_SCSI_SATA_MV=m +CONFIG_SCSI_SATA_SIL24=m +CONFIG_SCSI_PDC_ADMA=m CONFIG_SCSI_BUSLOGIC=m +CONFIG_SCSI_INITIO=m # CONFIG_SCSI_OMIT_FLASHPOINT is not set -# CONFIG_SCSI_CPQFCTS is not set # CONFIG_SCSI_DMX3191D is not set -# CONFIG_SCSI_DTC3280 is not set # CONFIG_SCSI_EATA is not set # CONFIG_SCSI_EATA_PIO is not set CONFIG_SCSI_FUTURE_DOMAIN=m CONFIG_SCSI_GDTH=m -# CONFIG_SCSI_GENERIC_NCR5380 is not set -# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set CONFIG_SCSI_IPS=m CONFIG_SCSI_INIA100=m CONFIG_SCSI_PPA=m CONFIG_SCSI_IMM=m # CONFIG_SCSI_IZIP_EPP16 is not set # CONFIG_SCSI_IZIP_SLOW_CTR is not set -# CONFIG_SCSI_NCR53C406A is not set CONFIG_SCSI_SYM53C8XX_2=m CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1 CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 +CONFIG_SCSI_SYM53C8XX_MMIO=y # CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set -# CONFIG_SCSI_PAS16 is not set -# CONFIG_SCSI_PSI240I is not set -CONFIG_SCSI_QLOGIC_FAS=m -CONFIG_SCSI_QLOGIC_ISP=m # CONFIG_SCSI_QLOGIC_FC is not set # CONFIG_SCSI_QLOGIC_FC_FIRMWARE is not set CONFIG_SCSI_QLOGIC_1280=m -# CONFIG_SCSI_SYM53C416 is not set -# CONFIG_SCSI_DC395x is not set -# CONFIG_SCSI_T128 is not set -# CONFIG_SCSI_U14_34F is not set -# CONFIG_SCSI_ULTRASTOR is not set +CONFIG_SCSI_DC395x=m # CONFIG_SCSI_NSP32 is not set # CONFIG_SCSI_DEBUG is not set CONFIG_SCSI_DC390T=m -CONFIG_SCSI_QLA2XXX=m +CONFIG_SCSI_QLA_FC=m +# FIXME: Turn off for FC6 - Move to external firmware loader. +CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE=y CONFIG_SCSI_QLA21XX=m CONFIG_SCSI_QLA22XX=m CONFIG_SCSI_QLA2300=m CONFIG_SCSI_QLA2322=m +CONFIG_SCSI_QLA24XX=m CONFIG_SCSI_QLA6312=m -CONFIG_SCSI_QLA6322=m # CONFIG_SCSI_IPR is not set # CONFIG_SCSI_DPT_I2O is not set +CONFIG_SCSI_LPFC=m # # PCMCIA SCSI adapter support @@ -486,11 +490,6 @@ CONFIG_PCMCIA_QLOGIC=m CONFIG_PCMCIA_SYM53C500=m -# -# Old CD-ROM drivers (not SCSI, not IDE) -# -# CONFIG_CD_NO_IDESCSI is not set - # # Multi-device support (RAID and LVM) # @@ -500,19 +499,28 @@ CONFIG_MD_LINEAR=m CONFIG_MD_RAID0=m CONFIG_MD_RAID1=m CONFIG_MD_RAID5=m +CONFIG_MD_RAID5_RESHAPE=y CONFIG_MD_RAID6=m +CONFIG_MD_RAID10=m CONFIG_MD_MULTIPATH=m +CONFIG_MD_FAULTY=m CONFIG_BLK_DEV_DM=m +CONFIG_DM_SNAPSHOT=m +CONFIG_DM_MIRROR=m +CONFIG_DM_ZERO=m CONFIG_DM_CRYPT=m +CONFIG_DM_MULTIPATH=m +CONFIG_DM_MULTIPATH_EMC=m # # Fusion MPT device support # -CONFIG_FUSION=m +CONFIG_FUSION_SPI=m +CONFIG_FUSION_FC=m CONFIG_FUSION_MAX_SGE=40 -# CONFIG_FUSION_ISENSE is not set CONFIG_FUSION_CTL=m CONFIG_FUSION_LAN=m +CONFIG_FUSION_SAS=m # # IEEE 1394 (FireWire) support (EXPERIMENTAL) @@ -528,7 +536,7 @@ CONFIG_IEEE1394_OUI_DB=y # # Device Drivers # -# CONFIG_IEEE1394_PCILYNX is not set +CONFIG_IEEE1394_PCILYNX=m CONFIG_IEEE1394_OHCI1394=m # @@ -537,45 +545,48 @@ CONFIG_IEEE1394_OHCI1394=m CONFIG_IEEE1394_VIDEO1394=m CONFIG_IEEE1394_SBP2=m # CONFIG_IEEE1394_SBP2_PHYS_DMA is not set -# CONFIG_IEEE1394_ETH1394 is not set +CONFIG_IEEE1394_ETH1394=m CONFIG_IEEE1394_DV1394=m CONFIG_IEEE1394_RAWIO=m -CONFIG_IEEE1394_CMP=m -CONFIG_IEEE1394_AMDTP=m -# CONFIG_IEEE1394_EXTRA_CONFIG_ROMS is not set +CONFIG_IEEE1394_EXTRA_CONFIG_ROMS=y +CONFIG_IEEE1394_CONFIG_ROM_IP1394=y +# CONFIG_IEEE1394_EXPORT_FULL_API is not set # # I2O device support # CONFIG_I2O=m -CONFIG_I2O_PCI=m -CONFIG_I2O_BLOCK=m -CONFIG_I2O_SCSI=m -CONFIG_I2O_PROC=m -CONFIG_I2O_CONFIG=y +# CONFIG_I2O_LCT_NOTIFY_ON_CHANGES is not set # # Networking support # CONFIG_NET=y +# CONFIG_NETDEBUG is not set + +# CONFIG_TCP_CONG_ADVANCED is not set # # Networking options # CONFIG_PACKET=y CONFIG_PACKET_MMAP=y -CONFIG_NETLINK_DEV=y CONFIG_UNIX=y CONFIG_NET_KEY=m CONFIG_INET=y +CONFIG_INET_TUNNEL=m +CONFIG_INET_DIAG=m CONFIG_IP_MULTICAST=y CONFIG_IP_ADVANCED_ROUTER=y CONFIG_IP_MULTIPLE_TABLES=y CONFIG_IP_ROUTE_FWMARK=y -CONFIG_IP_ROUTE_NAT=y CONFIG_IP_ROUTE_MULTIPATH=y -CONFIG_IP_ROUTE_TOS=y CONFIG_IP_ROUTE_VERBOSE=y +# CONFIG_IP_ROUTE_MULTIPATH_CACHED is not set +CONFIG_IP_ROUTE_MULTIPATH_RR=m +CONFIG_IP_ROUTE_MULTIPATH_RANDOM=m +CONFIG_IP_ROUTE_MULTIPATH_WRANDOM=m +CONFIG_IP_ROUTE_MULTIPATH_DRR=m # CONFIG_IP_PNP is not set CONFIG_NET_IPIP=m CONFIG_NET_IPGRE=m @@ -590,7 +601,8 @@ CONFIG_INET_ESP=m CONFIG_INET_IPCOMP=m CONFIG_NETCONSOLE=m # CONFIG_NETPOLL_RX is not set -# CONFIG_NETPOLL_TRAP is not set +CONFIG_NETPOLL_TRAP=y +CONFIG_NET_POLL_CONTROLLER=y # # IP: Virtual Server Configuration @@ -614,16 +626,50 @@ CONFIG_IP_VS_SED=m CONFIG_IP_VS_NQ=m CONFIG_IP_VS_FTP=m - CONFIG_IPV6=m CONFIG_IPV6_PRIVACY=y +CONFIG_IPV6_ROUTER_PREF=y +CONFIG_IPV6_ROUTE_INFO=y CONFIG_INET6_AH=m CONFIG_INET6_ESP=m CONFIG_INET6_IPCOMP=m CONFIG_IPV6_TUNNEL=m -# CONFIG_DECNET is not set +CONFIG_DECNET=m +CONFIG_DECNET_ROUTER=y +CONFIG_DECNET_ROUTE_FWMARK=y +# CONFIG_DECNET_NF_GRABULATOR is not set CONFIG_BRIDGE=m CONFIG_NETFILTER=y +CONFIG_NETFILTER_NETLINK=m +CONFIG_NETFILTER_NETLINK_QUEUE=m +CONFIG_NETFILTER_NETLINK_LOG=m +CONFIG_NETFILTER_XTABLES=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +CONFIG_NETFILTER_XT_TARGET_CONNMARK=m +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_NETFILTER_XT_TARGET_NOTRACK=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNMARK=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_DCCP=m +CONFIG_NETFILTER_XT_MATCH_ESP=m +CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_LENGTH=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_SCTP=m +CONFIG_NETFILTER_XT_MATCH_STATE=m +CONFIG_NETFILTER_XT_MATCH_STRING=m +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m + # CONFIG_NETFILTER_DEBUG is not set CONFIG_BRIDGE_NETFILTER=y @@ -631,85 +677,82 @@ CONFIG_BRIDGE_NETFILTER=y # IP: Netfilter Configuration # CONFIG_IP_NF_CONNTRACK=m -CONFIG_IP_NF_FTP=m -CONFIG_IP_NF_IRC=m -CONFIG_IP_NF_TFTP=m -CONFIG_IP_NF_AMANDA=m -CONFIG_IP_NF_QUEUE=m -CONFIG_IP_NF_RAW=m -CONFIG_IP_NF_IPTABLES=m -CONFIG_IP_NF_MATCH_LIMIT=m +CONFIG_IP_NF_CONNTRACK_MARK=y +CONFIG_IP_NF_CONNTRACK_EVENTS=y +CONFIG_IP_NF_CONNTRACK_NETLINK=m +CONFIG_IP_NF_MATCH_ADDRTYPE=m +CONFIG_IP_NF_MATCH_AH=m +CONFIG_IP_NF_MATCH_AH_ESP=m +CONFIG_IP_NF_MATCH_DSCP=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_HASHLIMIT=m CONFIG_IP_NF_MATCH_IPRANGE=m -CONFIG_IP_NF_MATCH_MAC=m -CONFIG_IP_NF_MATCH_PKTTYPE=m -CONFIG_IP_NF_MATCH_MARK=m CONFIG_IP_NF_MATCH_MULTIPORT=m -CONFIG_IP_NF_MATCH_TOS=m +CONFIG_IP_NF_MATCH_OWNER=m +CONFIG_IP_NF_MATCH_POLICY=m CONFIG_IP_NF_MATCH_RECENT=m -CONFIG_IP_NF_MATCH_ECN=m -CONFIG_IP_NF_MATCH_DSCP=m -CONFIG_IP_NF_MATCH_AH_ESP=m -CONFIG_IP_NF_MATCH_LENGTH=m +CONFIG_IP_NF_MATCH_TOS=m CONFIG_IP_NF_MATCH_TTL=m -CONFIG_IP_NF_MATCH_TCPMSS=m -CONFIG_IP_NF_MATCH_HELPER=m -CONFIG_IP_NF_MATCH_STATE=m -CONFIG_IP_NF_MATCH_CONNTRACK=m -CONFIG_IP_NF_MATCH_OWNER=m -CONFIG_IP_NF_MATCH_PHYSDEV=m -CONFIG_IP_NF_FILTER=m -CONFIG_IP_NF_TARGET_REJECT=m -CONFIG_IP_NF_NAT=m -CONFIG_IP_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_CLUSTERIP=m CONFIG_IP_NF_TARGET_MASQUERADE=m CONFIG_IP_NF_TARGET_REDIRECT=m CONFIG_IP_NF_TARGET_NETMAP=m CONFIG_IP_NF_TARGET_SAME=m -CONFIG_IP_NF_TARGET_NOTRACK=m -CONFIG_IP_NF_NAT_LOCAL=y -CONFIG_IP_NF_NAT_SNMP_BASIC=m -CONFIG_IP_NF_NAT_IRC=m -CONFIG_IP_NF_NAT_FTP=m -CONFIG_IP_NF_NAT_TFTP=m -CONFIG_IP_NF_NAT_AMANDA=m -CONFIG_IP_NF_MANGLE=m CONFIG_IP_NF_TARGET_TOS=m CONFIG_IP_NF_TARGET_ECN=m CONFIG_IP_NF_TARGET_DSCP=m -CONFIG_IP_NF_TARGET_MARK=m -CONFIG_IP_NF_TARGET_CLASSIFY=m CONFIG_IP_NF_TARGET_LOG=m CONFIG_IP_NF_TARGET_ULOG=m CONFIG_IP_NF_TARGET_TCPMSS=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_TTL=m +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_NAT_NEEDED=y +CONFIG_IP_NF_NAT_SNMP_BASIC=m +CONFIG_IP_NF_NAT_IRC=m +CONFIG_IP_NF_NAT_FTP=m +CONFIG_IP_NF_NAT_TFTP=m +CONFIG_IP_NF_NAT_AMANDA=m +CONFIG_IP_NF_MANGLE=m CONFIG_IP_NF_ARPTABLES=m CONFIG_IP_NF_ARPFILTER=m CONFIG_IP_NF_ARP_MANGLE=m -# CONFIG_IP_NF_COMPAT_IPCHAINS is not set -# CONFIG_IP_NF_COMPAT_IPFWADM is not set +CONFIG_IP_NF_CT_ACCT=y +CONFIG_IP_NF_CT_PROTO_SCTP=m +CONFIG_IP_NF_FTP=m +CONFIG_IP_NF_IRC=m +CONFIG_IP_NF_TFTP=m +CONFIG_IP_NF_AMANDA=m +CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_NETBIOS_NS=m +CONFIG_IP_NF_PPTP=m +CONFIG_IP_NF_H323=m # # IPv6: Netfilter Configuration # -# CONFIG_IP6_NF_QUEUE is not set +CONFIG_IP6_NF_QUEUE=m CONFIG_IP6_NF_IPTABLES=m -CONFIG_IP6_NF_MATCH_LIMIT=m -CONFIG_IP6_NF_MATCH_MAC=m -CONFIG_IP6_NF_MATCH_RT=m -CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_AHESP=m +CONFIG_IP6_NF_MATCH_EUI64=m CONFIG_IP6_NF_MATCH_FRAG=m CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m CONFIG_IP6_NF_MATCH_MULTIPORT=m +CONFIG_IP6_NF_MATCH_OPTS=m CONFIG_IP6_NF_MATCH_OWNER=m -CONFIG_IP6_NF_MATCH_MARK=m -CONFIG_IP6_NF_MATCH_IPV6HEADER=m -CONFIG_IP6_NF_MATCH_AHESP=m -CONFIG_IP6_NF_MATCH_LENGTH=m -CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_MATCH_POLICY=m CONFIG_IP6_NF_FILTER=m -CONFIG_IP6_NF_TARGET_LOG=m CONFIG_IP6_NF_MANGLE=m -CONFIG_IP6_NF_TARGET_MARK=m CONFIG_IP6_NF_RAW=m +CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_IP6_NF_TARGET_HL=m # # Bridge: Netfilter Configuration @@ -733,6 +776,7 @@ CONFIG_BRIDGE_EBT_MARK_T=m CONFIG_BRIDGE_EBT_REDIRECT=m CONFIG_BRIDGE_EBT_SNAT=m CONFIG_BRIDGE_EBT_LOG=m +CONFIG_BRIDGE_EBT_ULOG=m CONFIG_XFRM=y CONFIG_XFRM_USER=y @@ -745,7 +789,7 @@ CONFIG_IP_SCTP=m # CONFIG_SCTP_HMAC_NONE is not set # CONFIG_SCTP_HMAC_SHA1 is not set CONFIG_SCTP_HMAC_MD5=y -# CONFIG_ATM is not set +CONFIG_ATM=m CONFIG_VLAN_8021Q=m CONFIG_LLC=m # CONFIG_LLC2 is not set @@ -753,10 +797,6 @@ CONFIG_IPX=m # CONFIG_IPX_INTERN is not set CONFIG_ATALK=m CONFIG_DEV_APPLETALK=y -CONFIG_LTPC=m -CONFIG_COPS=m -CONFIG_COPS_DAYNA=y -CONFIG_COPS_TANGENT=y CONFIG_IPDDP=m CONFIG_IPDDP_ENCAP=y CONFIG_IPDDP_DECAP=y @@ -765,8 +805,18 @@ CONFIG_IPDDP_DECAP=y CONFIG_NET_DIVERT=y # CONFIG_ECONET is not set CONFIG_WAN_ROUTER=m -# CONFIG_NET_FASTROUTE is not set -# CONFIG_NET_HW_FLOWCONTROL is not set +CONFIG_IP_DCCP=m +CONFIG_IP_DCCP_CCID2=m +CONFIG_IP_DCCP_CCID3=m +# CONFIG_IP_DCCP_DEBUG is not set +CONFIG_IP_DCCP_UNLOAD_HACK=y + +# +# TIPC Configuration (EXPERIMENTAL) +# +CONFIG_TIPC=m +# CONFIG_TIPC_ADVANCED is not set +# CONFIG_TIPC_DEBUG is not set # # QoS and/or fair queueing @@ -774,7 +824,6 @@ CONFIG_WAN_ROUTER=m CONFIG_NET_SCHED=y CONFIG_NET_SCH_CBQ=m CONFIG_NET_SCH_HTB=m -CONFIG_NET_SCH_CSZ=m CONFIG_NET_SCH_PRIO=m CONFIG_NET_SCH_RED=m CONFIG_NET_SCH_SFQ=m @@ -784,9 +833,7 @@ CONFIG_NET_SCH_GRED=m CONFIG_NET_SCH_DSMARK=m CONFIG_NET_SCH_INGRESS=m CONFIG_NET_SCH_HFSC=m -CONFIG_NET_SCH_DELAY=m - -CONFIG_NET_QOS=y +CONFIG_NET_SCH_NETEM=m CONFIG_NET_ESTIMATOR=y CONFIG_NET_CLS=y CONFIG_NET_CLS_TCINDEX=m @@ -794,14 +841,27 @@ CONFIG_NET_CLS_ROUTE4=m CONFIG_NET_CLS_ROUTE=y CONFIG_NET_CLS_FW=m CONFIG_NET_CLS_U32=m +CONFIG_CLS_U32_MARK=y CONFIG_NET_CLS_RSVP=m CONFIG_NET_CLS_RSVP6=m CONFIG_NET_CLS_POLICE=y +# CONFIG_NET_ACT_POLICE is not set +CONFIG_CLS_U32_PERF=y +CONFIG_NET_CLS_IND=y +# CONFIG_NET_CLS_ACT is not set +CONFIG_NET_CLS_BASIC=m +CONFIG_NET_EMATCH=y +CONFIG_NET_EMATCH_STACK=32 +CONFIG_NET_EMATCH_CMP=m +CONFIG_NET_EMATCH_NBYTE=m +CONFIG_NET_EMATCH_U32=m +CONFIG_NET_EMATCH_META=m +CONFIG_NET_EMATCH_TEXT=m # # Network testing # -# CONFIG_NET_PKTGEN is not set +CONFIG_NET_PKTGEN=m CONFIG_NETDEVICES=y # @@ -812,33 +872,64 @@ CONFIG_DUMMY=m CONFIG_BONDING=m CONFIG_EQUALIZER=m CONFIG_TUN=m -CONFIG_ETHERTAP=m CONFIG_NET_SB1000=m +# +# ATM +# +# CONFIG_ATM_DUMMY is not set +CONFIG_ATM_CLIP=m +CONFIG_ATM_LANE=m +CONFIG_ATM_BR2684=m +CONFIG_NET_SCH_ATM=m +CONFIG_ATM_TCP=m +CONFIG_ATM_LANAI=m +CONFIG_ATM_ENI=m +CONFIG_ATM_FIRESTREAM=m +# CONFIG_ATM_ZATM is not set +CONFIG_ATM_IDT77252=m +CONFIG_ATM_AMBASSADOR=m +CONFIG_ATM_HORIZON=m +CONFIG_ATM_FORE200E_MAYBE=m +CONFIG_ATM_HE=m +CONFIG_PPPOATM=m +CONFIG_ATM_NICSTAR=m +# CONFIG_ATM_IA is not set + + +# CONFIG_ATM_CLIP_NO_ICMP is not set +# CONFIG_ATM_MPOA is not set +# CONFIG_ATM_BR2684_IPFILTER is not set +# CONFIG_ATM_ENI_DEBUG is not set +# CONFIG_ATM_ENI_TUNE_BURST is not set +# CONFIG_ATM_ZATM_DEBUG is not set +# CONFIG_ATM_IDT77252_DEBUG is not set +# CONFIG_ATM_IDT77252_RCV_ALL is not set +# CONFIG_ATM_AMBASSADOR_DEBUG is not set +# CONFIG_ATM_HORIZON_DEBUG is not set +# CONFIG_ATM_FORE200E_PCA is not set +# CONFIG_ATM_HE_USE_SUNI is not set +# CONFIG_ATM_NICSTAR_USE_SUNI is not set +# CONFIG_ATM_NICSTAR_USE_IDT77105 is not set +# CONFIG_ATM_IA_DEBUG is not set + + # # Ethernet (10 or 100Mbit) # CONFIG_NET_ETHERNET=y +CONFIG_PHYLIB=m +CONFIG_MARVELL_PHY=m +CONFIG_DAVICOM_PHY=m +CONFIG_QSEMI_PHY=m +CONFIG_LXT_PHY=m +CONFIG_CICADA_PHY=m CONFIG_MII=m CONFIG_HAPPYMEAL=m CONFIG_SUNGEM=m CONFIG_NET_VENDOR_3COM=y -CONFIG_EL1=m -CONFIG_EL2=m -CONFIG_ELPLUS=m -CONFIG_EL16=m -CONFIG_EL3=m -CONFIG_3C515=m CONFIG_VORTEX=m CONFIG_TYPHOON=m -CONFIG_LANCE=m -CONFIG_NET_VENDOR_SMC=y -CONFIG_WD80x3=m -CONFIG_ULTRA=m -CONFIG_SMC9194=m -CONFIG_NET_VENDOR_RACAL=y -CONFIG_NI52=m -CONFIG_NI65=m # # Tulip family network device support @@ -847,7 +938,6 @@ CONFIG_NET_TULIP=y CONFIG_DE2104X=m CONFIG_TULIP=m # CONFIG_TULIP_NAPI is not set - # CONFIG_TULIP_MWI is not set CONFIG_TULIP_MMIO=y # CONFIG_NI5010 is not set @@ -856,21 +946,8 @@ CONFIG_DE4X5=m CONFIG_WINBOND_840=m CONFIG_DM9102=m CONFIG_PCMCIA_XIRCOM=m -# CONFIG_AT1700 is not set -CONFIG_DEPCA=m +CONFIG_ULI526X=m CONFIG_HP100=m -# CONFIG_NET_ISA is not set -# CONFIG_EWRK3 is not set -CONFIG_E2100=m -CONFIG_EEXPRESS=m -CONFIG_EEXPRESS_PRO=m -CONFIG_HPLAN_PLUS=m -CONFIG_HPLAN=m -CONFIG_LP486E=m -CONFIG_ETH16I=m -CONFIG_NE2000=m -CONFIG_ZNET=m -CONFIG_SEEQ8005=m CONFIG_LNE390=m CONFIG_NE3210=m CONFIG_ES3210=m @@ -880,53 +957,56 @@ CONFIG_AMD8111_ETH=m CONFIG_AMD8111E_NAPI=y CONFIG_ADAPTEC_STARFIRE=m CONFIG_ADAPTEC_STARFIRE_NAPI=y -CONFIG_AC3200=m -CONFIG_APRICOT=m CONFIG_B44=m -CONFIG_CS89x0=m +CONFIG_BNX2=m CONFIG_DGRS=m -CONFIG_EEPRO100=m -# CONFIG_EEPRO100_PIO is not set +# CONFIG_EEPRO100 is not set CONFIG_E100=m -CONFIG_E100_NAPI=y CONFIG_FEALNX=m CONFIG_FORCEDETH=m CONFIG_NATSEMI=m CONFIG_NE2K_PCI=m CONFIG_8139CP=m CONFIG_8139TOO=m -CONFIG_8139TOO_PIO=y +# CONFIG_8139TOO_PIO is not set # CONFIG_8139TOO_TUNE_TWISTER is not set CONFIG_8139TOO_8129=y # CONFIG_8139_OLD_RX_RESET is not set -CONFIG_8139_RXBUF_IDX=2 CONFIG_SIS900=m +CONFIG_SIS190=m CONFIG_EPIC100=m CONFIG_SUNDANCE=m # CONFIG_SUNDANCE_MMIO is not set CONFIG_TLAN=m CONFIG_VIA_RHINE=m CONFIG_VIA_RHINE_MMIO=y +CONFIG_VIA_VELOCITY=m CONFIG_NET_POCKET=y CONFIG_ATP=m CONFIG_DE600=m CONFIG_DE620=m +CONFIG_CASSINI=m +# CONFIG_FEC_8XX is not set # # Ethernet (1000 Mbit) # -CONFIG_NET_GIGE=y CONFIG_ACENIC=m # CONFIG_ACENIC_OMIT_TIGON_I is not set CONFIG_DL2K=m CONFIG_E1000=m CONFIG_E1000_NAPI=y +# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set CONFIG_NS83820=m CONFIG_HAMACHI=m CONFIG_YELLOWFIN=m CONFIG_R8169=m -CONFIG_SK98LIN=m +CONFIG_R8169_NAPI=y +CONFIG_R8169_VLAN=y +# CONFIG_SK98LIN is not set +CONFIG_SKGE=m CONFIG_TIGON3=m +CONFIG_SKY2=m # # Ethernet (10000 Mbit) @@ -935,6 +1015,8 @@ CONFIG_IXGB=m CONFIG_IXGB_NAPI=y CONFIG_S2IO=m CONFIG_S2IO_NAPI=y +CONFIG_CHELSIO_T1=m + CONFIG_FDDI=y # CONFIG_DEFXX is not set CONFIG_SKFP=m @@ -949,7 +1031,11 @@ CONFIG_PPP_DEFLATE=m CONFIG_IPPP_FILTER=y # CONFIG_PPP_BSDCOMP is not set CONFIG_PPPOE=m -# CONFIG_SLIP is not set +CONFIG_PPP_MPPE=m +CONFIG_SLIP=m +CONFIG_SLIP_COMPRESSED=y +CONFIG_SLIP_SMART=y +# CONFIG_SLIP_MODE_SLIP6 is not set # # Wireless LAN (non-hamradio) @@ -961,7 +1047,6 @@ CONFIG_NET_RADIO=y # # CONFIG_STRIP is not set # CONFIG_ARLAN is not set -CONFIG_WAVELAN=m CONFIG_PCMCIA_WAVELAN=m CONFIG_PCMCIA_NETWAVE=m @@ -973,31 +1058,62 @@ CONFIG_PCMCIA_NETWAVE=m # # Wireless 802.11b ISA/PCI cards support # +CONFIG_IEEE80211=m +# CONFIG_IEEE80211_DEBUG is not set +CONFIG_IEEE80211_CRYPT_WEP=m +CONFIG_IEEE80211_CRYPT_CCMP=m +CONFIG_IEEE80211_CRYPT_TKIP=m +CONFIG_IEEE80211_SOFTMAC=m +CONFIG_IEEE80211_SOFTMAC_DEBUG=y +CONFIG_IPW2100=m +CONFIG_IPW2200=m +# CONFIG_IPW2100_DEBUG is not set +# CONFIG_IPW2200_DEBUG is not set CONFIG_AIRO=m CONFIG_HERMES=m CONFIG_PLX_HERMES=m CONFIG_TMD_HERMES=m +CONFIG_NORTEL_HERMES=m CONFIG_PCI_HERMES=m CONFIG_ATMEL=m CONFIG_PCI_ATMEL=m CONFIG_PRISM54=m +CONFIG_BCM43XX=m +CONFIG_BCM43XX_DEBUG=y # # Wireless 802.11b Pcmcia/Cardbus cards support # CONFIG_PCMCIA_HERMES=m +CONFIG_PCMCIA_SPECTRUM=m CONFIG_AIRO_CS=m CONFIG_PCMCIA_ATMEL=m CONFIG_PCMCIA_WL3501=m CONFIG_NET_WIRELESS=y +CONFIG_NET_WIRELESS_RTNETLINK=y + +CONFIG_HOSTAP=m +CONFIG_HOSTAP_PCI=m +CONFIG_HOSTAP_PLX=m +CONFIG_HOSTAP_FIRMWARE=y +CONFIG_HOSTAP_FIRMWARE_NVRAM=y +CONFIG_HOSTAP_CS=m # # Token Ring devices # -# CONFIG_TR is not set +CONFIG_TR=y +CONFIG_IBMOL=m +CONFIG_3C359=m +# Broken with gcc4.1 +# CONFIG_TMS380TR is not set +CONFIG_TMSPCI=m +CONFIG_ABYSS=m +CONFIG_IBMLS=m +CONFIG_PCMCIA_IBMTR=m + CONFIG_NET_FC=y -CONFIG_RCPCI=m # CONFIG_SHAPER is not set # @@ -1039,6 +1155,7 @@ CONFIG_DONGLE=y CONFIG_ESI_DONGLE=m CONFIG_ACTISYS_DONGLE=m CONFIG_TEKRAM_DONGLE=m +CONFIG_TOIM3232_DONGLE=m CONFIG_IRPORT_SIR=m # CONFIG_DONGLE_OLD is not set CONFIG_LITELINK_DONGLE=m @@ -1051,14 +1168,12 @@ CONFIG_ACT200L_DONGLE=m CONFIG_USB_IRDA=m CONFIG_NSC_FIR=m CONFIG_SIGMATEL_FIR=m -# CONFIG_WINBOND_FIR is not set -# CONFIG_TOSHIBA_FIR is not set -# CONFIG_SMC_IRCC_FIR is not set -# CONFIG_ALI_FIR is not set -# CONFIG_VLSI_FIR is not set -# CONFIG_VIA_FIR is not set - - +CONFIG_WINBOND_FIR=m +CONFIG_TOSHIBA_FIR=m +CONFIG_SMC_IRCC_FIR=m +CONFIG_ALI_FIR=m +CONFIG_VLSI_FIR=m +CONFIG_VIA_FIR=m # # Bluetooth support @@ -1072,6 +1187,7 @@ CONFIG_BT_RFCOMM_TTY=y CONFIG_BT_BNEP=m CONFIG_BT_BNEP_MC_FILTER=y CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_HIDP=m # # Bluetooth device drivers @@ -1080,7 +1196,6 @@ CONFIG_BT_HCIUSB=m CONFIG_BT_HCIUART=m CONFIG_BT_HCIUART_H4=y CONFIG_BT_HCIUART_BCSP=y -CONFIG_BT_HCIUART_BCSP_TXCRC=y CONFIG_BT_HCIDTL1=m CONFIG_BT_HCIBT3C=m CONFIG_BT_HCIBLUECARD=m @@ -1089,11 +1204,7 @@ CONFIG_BT_HCIVHCI=m CONFIG_BT_HCIUSB_SCO=y CONFIG_BT_HCIBCM203X=m CONFIG_BT_HCIBFUSB=m -CONFIG_BT_CMTP=m -CONFIG_BT_HCIUSB_SCO=m -CONFIG_BT_HCIBCM203X=m -CONFIG_BT_HCIBFUSB=m -CONFIG_USB_BLUETOOTH_TTY=m +CONFIG_BT_HCIBPA10X=m # # ISDN subsystem @@ -1101,9 +1212,7 @@ CONFIG_USB_BLUETOOTH_TTY=m CONFIG_ISDN=m CONFIG_ISDN_I4L=m -CONFIG_ISDN_DRV_AVMB1_B1ISA=m CONFIG_ISDN_DRV_AVMB1_B1PCI=m -CONFIG_ISDN_DRV_AVMB1_T1ISA=m CONFIG_ISDN_DRV_AVMB1_B1PCMCIA=m CONFIG_ISDN_DRV_AVMB1_T1PCI=m CONFIG_ISDN_DRV_AVMB1_C4=m @@ -1118,41 +1227,27 @@ CONFIG_DE_AOC=y CONFIG_ISDN_AUDIO=y CONFIG_ISDN_DRV_HISAX=m -CONFIG_ISDN_DRV_ICN=m -CONFIG_ISDN_DRV_PCBIT=m -CONFIG_ISDN_DRV_SC=m -CONFIG_ISDN_DRV_ACT2000=m -CONFIG_ISDN_DRV_TPAM=m CONFIG_ISDN_DRV_AVMB1_B1PCIV4=y CONFIG_ISDN_DRV_AVMB1_AVM_CS=m CONFIG_ISDN_CAPI_CAPIDRV=m +CONFIG_ISDN_DIVERSION=m CONFIG_HISAX_EURO=y CONFIG_HISAX_1TR6=y CONFIG_HISAX_NI1=y CONFIG_HISAX_MAX_CARDS=8 -CONFIG_HISAX_16_0=y CONFIG_HISAX_16_3=y CONFIG_HISAX_TELESPCI=y CONFIG_HISAX_S0BOX=y -CONFIG_HISAX_AVM_A1=y CONFIG_HISAX_FRITZPCI=y CONFIG_HISAX_AVM_A1_PCMCIA=y CONFIG_HISAX_ELSA=y -CONFIG_HISAX_IX1MICROR2=y CONFIG_HISAX_DIEHLDIVA=y -CONFIG_HISAX_ASUSCOM=y -CONFIG_HISAX_TELEINT=y -CONFIG_HISAX_HFCS=y CONFIG_HISAX_SEDLBAUER=y -CONFIG_HISAX_SPORTSTER=y -CONFIG_HISAX_MIC=y CONFIG_HISAX_NETJET=y CONFIG_HISAX_NETJET_U=y CONFIG_HISAX_NICCY=y -CONFIG_HISAX_ISURF=y -CONFIG_HISAX_HSTSAPHIR=y CONFIG_HISAX_BKM_A4T=y CONFIG_HISAX_SCT_QUADRO=y CONFIG_HISAX_GAZEL=y @@ -1163,7 +1258,7 @@ CONFIG_HISAX_ENTERNOW_PCI=y # CONFIG_HISAX_DEBUG is not set CONFIG_HISAX_AVM_A1_CS=m CONFIG_HISAX_ST5481=m -CONFIG_HISAX_HFCUSB=m +# CONFIG_HISAX_HFCUSB is not set CONFIG_HISAX_FRITZ_PCIPNP=m CONFIG_HISAX_NO_SENDCOMPLETE=y CONFIG_HISAX_NO_LLC=y @@ -1171,6 +1266,7 @@ CONFIG_HISAX_NO_KEYPAD=y CONFIG_HISAX_SEDLBAUER_CS=m CONFIG_HISAX_ELSA_CS=m CONFIG_HISAX_TELES_CS=m +CONFIG_HISAX_HFC4S8S=m CONFIG_ISDN_DRV_LOOP=m CONFIG_HYSDN=m @@ -1207,6 +1303,12 @@ CONFIG_ISDN_DIVAS_DIVACAPI=m CONFIG_ISDN_DIVAS_USERIDI=m CONFIG_ISDN_DIVAS_MAINT=m +CONFIG_ISDN_DRV_GIGASET=m +CONFIG_GIGASET_BASE=m +CONFIG_GIGASET_M105=m +# CONFIG_GIGASET_DEBUG is not set +# CONFIG_GIGASET_UNDOCREQ is not set + # # Telephony Support # @@ -1233,16 +1335,15 @@ CONFIG_INPUT_EVDEV=y # Input I/O drivers # CONFIG_GAMEPORT=m -CONFIG_SOUND_GAMEPORT=m CONFIG_GAMEPORT_NS558=m CONFIG_GAMEPORT_L4=m CONFIG_GAMEPORT_EMU10K1=m -CONFIG_GAMEPORT_VORTEX=m CONFIG_GAMEPORT_FM801=m -CONFIG_GAMEPORT_CS461x=m CONFIG_SERIO=y CONFIG_SERIO_I8042=y CONFIG_SERIO_SERPORT=y +CONFIG_SERIO_RAW=m + # CONFIG_SERIO_CT82C710 is not set # CONFIG_SERIO_PARKBD is not set # CONFIG_SERIO_PCIPS2 is not set @@ -1259,10 +1360,6 @@ CONFIG_KEYBOARD_ATKBD=y CONFIG_INPUT_MOUSE=y CONFIG_MOUSE_PS2=y CONFIG_MOUSE_SERIAL=m -CONFIG_MOUSE_INPORT=m -CONFIG_MOUSE_ATIXL=y -CONFIG_MOUSE_LOGIBM=m -CONFIG_MOUSE_PC110PAD=m CONFIG_MOUSE_VSXXXAA=m CONFIG_INPUT_JOYSTICK=y CONFIG_JOYSTICK_ANALOG=m @@ -1284,16 +1381,20 @@ CONFIG_JOYSTICK_MAGELLAN=m CONFIG_JOYSTICK_SPACEORB=m CONFIG_JOYSTICK_SPACEBALL=m CONFIG_JOYSTICK_STINGER=m -CONFIG_JOYSTICK_TWIDDLER=m CONFIG_JOYSTICK_DB9=m CONFIG_JOYSTICK_GAMECON=m CONFIG_JOYSTICK_TURBOGRAFX=m -# CONFIG_INPUT_JOYDUMP is not set +CONFIG_JOYSTICK_JOYDUMP=m +CONFIG_JOYSTICK_TWIDJOY=m CONFIG_INPUT_TOUCHSCREEN=y CONFIG_TOUCHSCREEN_GUNZE=m +CONFIG_TOUCHSCREEN_ELO=m +CONFIG_TOUCHSCREEN_MTOUCH=m +CONFIG_TOUCHSCREEN_MK712=m CONFIG_INPUT_MISC=y CONFIG_INPUT_PCSPKR=m -# CONFIG_INPUT_UINPUT is not set +CONFIG_INPUT_UINPUT=m +CONFIG_INPUT_WISTRON_BTNS=m # # Character devices @@ -1305,10 +1406,16 @@ CONFIG_SERIAL_NONSTANDARD=y CONFIG_ROCKETPORT=m CONFIG_SYNCLINK=m CONFIG_SYNCLINKMP=m +# CONFIG_SYNCLINK_GT is not set CONFIG_N_HDLC=m -CONFIG_STALDRV=y +# CONFIG_STALDRV is not set # CONFIG_FTAPE is not set CONFIG_IBM_ASM=m +# CONFIG_TCG_TPM is not set +# CONFIG_TCG_NSC is not set +# CONFIG_TCG_ATMEL is not set +CONFIG_TCG_INFINEON=m +# CONFIG_TELCLOCK is not set # # Serial drivers @@ -1317,17 +1424,16 @@ CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_CS=m # CONFIG_SERIAL_8250_ACPI is not set -CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_NR_UARTS=32 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 CONFIG_SERIAL_8250_EXTENDED=y -# CONFIG_SERIAL_8250_MANY_PORTS is not set +CONFIG_SERIAL_8250_MANY_PORTS=y CONFIG_SERIAL_8250_SHARE_IRQ=y CONFIG_SERIAL_8250_DETECT_IRQ=y -CONFIG_SERIAL_8250_MULTIPORT=y CONFIG_SERIAL_8250_RSA=y # CONFIG_COMPUTONE is not set # CONFIG_CYCLADES is not set # CONFIG_DIGIEPCA is not set -# CONFIG_DIGI is not set # CONFIG_ESPSERIAL is not set # CONFIG_MOXA_INTELLIO is not set # CONFIG_MOXA_SMARTIO is not set @@ -1338,6 +1444,7 @@ CONFIG_SERIAL_8250_RSA=y # CONFIG_RIO is not set # CONFIG_STALLION is not set # CONFIG_ISTALLION is not set +# CONFIG_SERIAL_JSM is not set # # Non-8250 serial port support @@ -1345,7 +1452,6 @@ CONFIG_SERIAL_8250_RSA=y CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y CONFIG_UNIX98_PTYS=y -CONFIG_UNIX98_PTY_COUNT=2048 # CONFIG_LEGACY_PTYS is not set CONFIG_PRINTER=m CONFIG_LP_CONSOLE=y @@ -1368,69 +1474,102 @@ CONFIG_I2C_ALGOPCF=m # # I2C Hardware Bus support # + +CONFIG_I2C_NFORCE2=m +CONFIG_I2C_PROSAVAGE=m +CONFIG_I2C_SAVAGE4=m +CONFIG_I2C_VOODOO3=m CONFIG_I2C_ALI1535=m +CONFIG_I2C_ALI1563=m CONFIG_I2C_ALI15X3=m CONFIG_I2C_AMD756=m +CONFIG_I2C_AMD756_S4882=m CONFIG_I2C_AMD8111=m CONFIG_I2C_I801=m CONFIG_I2C_I810=m -CONFIG_I2C_ISA=m -CONFIG_I2C_NFORCE2=m CONFIG_I2C_PIIX4=m -CONFIG_I2C_PROSAVAGE=m -CONFIG_I2C_SAVAGE4=m # CONFIG_SCx200_ACB is not set CONFIG_I2C_SIS5595=m CONFIG_I2C_SIS630=m CONFIG_I2C_SIS96X=m CONFIG_I2C_VIA=m CONFIG_I2C_VIAPRO=m -CONFIG_I2C_VOODOO3=m + # CONFIG_I2C_ELEKTOR is not set CONFIG_I2C_PARPORT=m CONFIG_I2C_PARPORT_LIGHT=m # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_BUS is not set # CONFIG_I2C_DEBUG_CHIP is not set -# CONFIG_I2C_PARPORT is not set -CONFIG_I2C_ALI1563=m -# CONFIG_I2C_PARPORT_LIGHT is not set - - +CONFIG_I2C_ALGOPCA=m +CONFIG_I2C_PCA_ISA=m +CONFIG_I2C_STUB=m # # I2C Hardware Sensors Chip support # -CONFIG_I2C_SENSOR=m CONFIG_SENSORS_ADM1021=m +CONFIG_SENSORS_ADM1025=m +CONFIG_SENSORS_ADM1026=m +CONFIG_SENSORS_ADM1031=m +CONFIG_SENSORS_ADM9240=m +CONFIG_SENSORS_ATXP1=m +CONFIG_SENSORS_ASB100=m +CONFIG_SENSORS_DS1621=m +CONFIG_SENSORS_DS1337=m +CONFIG_SENSORS_DS1374=m CONFIG_SENSORS_EEPROM=m +CONFIG_SENSORS_FSCHER=m +CONFIG_SENSORS_FSCPOS=m +CONFIG_SENSORS_F71805F=m +CONFIG_SENSORS_GL518SM=m +CONFIG_SENSORS_GL520SM=m +CONFIG_SENSORS_HDAPS=m CONFIG_SENSORS_IT87=m +CONFIG_SENSORS_LM63=m CONFIG_SENSORS_LM75=m +CONFIG_SENSORS_LM77=m CONFIG_SENSORS_LM78=m CONFIG_SENSORS_LM80=m CONFIG_SENSORS_LM83=m CONFIG_SENSORS_LM85=m -CONFIG_SENSORS_VIA686A=m -CONFIG_SENSORS_W83781D=m -CONFIG_SENSORS_ASB100=m +CONFIG_SENSORS_LM87=m CONFIG_SENSORS_LM90=m -CONFIG_SENSORS_W83L785TS=m -CONFIG_SENSORS_FSCHER=m -CONFIG_SENSORS_GL518SM=m -CONFIG_SENSORS_DS1621=m -CONFIG_SENSORS_W83627HF=m +CONFIG_SENSORS_LM92=m +CONFIG_SENSORS_MAX1619=m +CONFIG_SENSORS_MAX6875=m +CONFIG_SENSORS_PC87360=m +CONFIG_SENSORS_PCA9539=m CONFIG_SENSORS_PCF8574=m CONFIG_SENSORS_PCF8591=m CONFIG_SENSORS_RTC8564=m -CONFIG_SENSORS_MAX1619=m +CONFIG_SENSORS_SIS5595=m +CONFIG_SENSORS_SMSC47M1=m +CONFIG_SENSORS_SMSC47B397=m +CONFIG_SENSORS_VIA686A=m +CONFIG_SENSORS_VT8231=m +CONFIG_SENSORS_W83627HF=m +CONFIG_SENSORS_W83781D=m +CONFIG_SENSORS_W83L785TS=m +CONFIG_SENSORS_W83627EHF=m +CONFIG_SENSORS_W83792D=m +CONFIG_RTC_X1205_I2C=m + +CONFIG_W1=m +CONFIG_W1_DS2433_CRC=y + +CONFIG_W1_MASTER_MATROX=m +CONFIG_W1_MASTER_DS9490=m +CONFIG_W1_MASTER_DS9490_BRIDGE=m +CONFIG_W1_MASTER_DS2482=m +CONFIG_W1_SLAVE_THERM=m +CONFIG_W1_SLAVE_SMEM=m +CONFIG_W1_SLAVE_DS2433=m # # Mice # -CONFIG_BUSMOUSE=m -# CONFIG_QIC02_TAPE is not set -CONFIG_CRASH=m # # IPMI @@ -1438,9 +1577,9 @@ CONFIG_CRASH=m CONFIG_IPMI_HANDLER=m # CONFIG_IPMI_PANIC_EVENT is not set CONFIG_IPMI_DEVICE_INTERFACE=m -CONFIG_IPMI_KCS=m CONFIG_IPMI_WATCHDOG=m CONFIG_IPMI_SI=m +CONFIG_IPMI_POWEROFF=m # # Watchdog Cards @@ -1448,15 +1587,13 @@ CONFIG_IPMI_SI=m CONFIG_WATCHDOG=y # CONFIG_WATCHDOG_NOWAYOUT is not set CONFIG_SOFT_WATCHDOG=m -CONFIG_WDT=m # CONFIG_WDT_501 is not set CONFIG_WDTPCI=m CONFIG_WDT_501_PCI=y -CONFIG_PCWATCHDOG=m -CONFIG_ACQUIRE_WDT=m -CONFIG_ADVANTECH_WDT=m -CONFIG_EUROTECH_WDT=m -CONFIG_IB700_WDT=m +# CONFIG_ACQUIRE_WDT is not set +# CONFIG_ADVANTECH_WDT is not set +# CONFIG_EUROTECH_WDT is not set +# CONFIG_IB700_WDT is not set CONFIG_I8XX_TCO=m # CONFIG_MIXCOMWD is not set # CONFIG_SCx200_WDT is not set @@ -1464,20 +1601,36 @@ CONFIG_I8XX_TCO=m CONFIG_W83877F_WDT=m CONFIG_W83627HF_WDT=m CONFIG_MACHZ_WDT=m -CONFIG_SC520_WDT=m -CONFIG_AMD7XX_TCO=m +# CONFIG_SC520_WDT is not set CONFIG_ALIM7101_WDT=m CONFIG_ALIM1535_WDT=m -CONFIG_SC1200_WDT=m -CONFIG_WAFER_WDT=m -CONFIG_CPU5_WDT=m +# CONFIG_SC1200_WDT is not set +# CONFIG_WAFER_WDT is not set +# CONFIG_CPU5_WDT is not set +CONFIG_I6300ESB_WDT=m +# CONFIG_SBC8360_WDT is not set +CONFIG_W83977F_WDT=m CONFIG_PCIPCWATCHDOG=m CONFIG_USBPCWATCHDOG=m - +# CONFIG_SBC_EPX_C3_WATCHDOG is not set CONFIG_HW_RANDOM=m -CONFIG_NVRAM=m +CONFIG_NVRAM=y CONFIG_RTC=y +CONFIG_RTC_CLASS=m +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +CONFIG_RTC_INTF_SYSFS=m +CONFIG_RTC_INTF_PROC=m +CONFIG_RTC_INTF_DEV=m +CONFIG_RTC_DRV_X1205=m +CONFIG_RTC_DRV_DS1672=m +CONFIG_RTC_DRV_PCF8563=m +CONFIG_RTC_DRV_RS5C372=m +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_EP93XX is not set +# CONFIG_RTC_DRV_SA1100 is not set +# CONFIG_RTC_DRV_TEST is not set CONFIG_DTLK=m CONFIG_R3964=m # CONFIG_APPLICOM is not set @@ -1492,29 +1645,30 @@ CONFIG_AGP_ATI=y CONFIG_AGP_AMD=y CONFIG_AGP_AMD64=y CONFIG_AGP_INTEL=y -CONFIG_AGP_INTEL_MCH=y CONFIG_AGP_NVIDIA=y CONFIG_AGP_SIS=y CONFIG_AGP_SWORKS=y CONFIG_AGP_VIA=y CONFIG_AGP_EFFICEON=y -CONFIG_DRM=y +CONFIG_DRM=m CONFIG_DRM_TDFX=m -CONFIG_DRM_GAMMA=m CONFIG_DRM_R128=m CONFIG_DRM_RADEON=m CONFIG_DRM_I810=m CONFIG_DRM_I830=m CONFIG_DRM_MGA=m CONFIG_DRM_SIS=m - +CONFIG_DRM_SAVAGE=m +CONFIG_DRM_I915=m +CONFIG_DRM_VIA=m # # PCMCIA character devices # CONFIG_SYNCLINK_CS=m - +CONFIG_CARDMAN_4000=m +CONFIG_CARDMAN_4040=m CONFIG_MWAVE=m # CONFIG_RAW_DRIVER is not set @@ -1525,6 +1679,10 @@ CONFIG_HANGCHECK_TIMER=m # Multimedia devices # CONFIG_VIDEO_DEV=m +# CONFIG_VIDEO_ADV_DEBUG is not set +CONFIG_VIDEO_V4L1=y +CONFIG_VIDEO_V4L1_COMPAT=y +# CONFIG_VIDEO_VIVI is not set # # Video For Linux @@ -1533,59 +1691,65 @@ CONFIG_VIDEO_DEV=m # # Video Adapters # +CONFIG_VIDEO_AUDIO_DECODER=m CONFIG_VIDEO_BT848=m -CONFIG_VIDEO_PMS=m +CONFIG_VIDEO_BT848_DVB=y CONFIG_VIDEO_BWQCAM=m -CONFIG_VIDEO_CQCAM=m -CONFIG_VIDEO_W9966=m CONFIG_VIDEO_CPIA=m CONFIG_VIDEO_CPIA_PP=m CONFIG_VIDEO_CPIA_USB=m +CONFIG_VIDEO_CPIA2=m +CONFIG_VIDEO_CQCAM=m +CONFIG_VIDEO_CS53L32A=m +CONFIG_VIDEO_CX25840=m +CONFIG_VIDEO_CX88=m +CONFIG_VIDEO_CX88_DVB=m +CONFIG_VIDEO_CX88_DVB_ALL_FRONTENDS=y +CONFIG_VIDEO_CX88_ALSA=m +CONFIG_VIDEO_DECODER=m +CONFIG_VIDEO_DPC=m +CONFIG_VIDEO_EM28XX=m +CONFIG_VIDEO_HEXIUM_ORION=m +CONFIG_VIDEO_HEXIUM_GEMINI=m +CONFIG_VIDEO_MEYE=m +CONFIG_VIDEO_MXB=m +CONFIG_VIDEO_OVCAMCHIP=m +CONFIG_VIDEO_SAA5246A=m CONFIG_VIDEO_SAA5249=m -CONFIG_TUNER_3036=m +CONFIG_VIDEO_SAA6588=m +CONFIG_VIDEO_SAA7127=m +CONFIG_VIDEO_SAA7134=m +CONFIG_VIDEO_SAA7134_ALSA=m +CONFIG_VIDEO_SAA7134_DVB=m +CONFIG_VIDEO_SAA7134_DVB_ALL_FRONTENDS=y CONFIG_VIDEO_STRADIS=m -CONFIG_VIDEO_ZORAN=m +CONFIG_VIDEO_UPD64031A=m +CONFIG_VIDEO_UPD64083=m +CONFIG_VIDEO_W9966=m +CONFIG_VIDEO_WM8775=m +CONFIG_VIDEO_WM8739=m CONFIG_VIDEO_ZORAN=m CONFIG_VIDEO_ZORAN_BUZ=m CONFIG_VIDEO_ZORAN_DC10=m CONFIG_VIDEO_ZORAN_DC30=m CONFIG_VIDEO_ZORAN_LML33=m CONFIG_VIDEO_ZORAN_LML33R10=m -CONFIG_VIDEO_MEYE=m -CONFIG_VIDEO_SAA7134=m -CONFIG_VIDEO_MXB=m -CONFIG_VIDEO_DPC=m -CONFIG_VIDEO_HEXIUM_ORION=m -CONFIG_VIDEO_HEXIUM_GEMINI=m -CONFIG_VIDEO_CX88=m -CONFIG_VIDEO_SAA5246A=m +CONFIG_TUNER_3036=m # # Radio Adapters # -CONFIG_RADIO_CADET=m -CONFIG_RADIO_RTRACK=m -CONFIG_RADIO_RTRACK2=m -CONFIG_RADIO_AZTECH=m -CONFIG_RADIO_GEMTEK=m CONFIG_RADIO_GEMTEK_PCI=m CONFIG_RADIO_MAXIRADIO=m CONFIG_RADIO_MAESTRO=m CONFIG_RADIO_MIROPCM20=m CONFIG_RADIO_MIROPCM20_RDS=m -CONFIG_RADIO_SF16FMI=m -CONFIG_RADIO_SF16FMR2=m -CONFIG_RADIO_TERRATEC=m -CONFIG_RADIO_TRUST=m -CONFIG_RADIO_TYPHOON=m -CONFIG_RADIO_TYPHOON_PROC_FS=y -CONFIG_RADIO_ZOLTRIX=m # # Digital Video Broadcasting Devices # -# CONFIG_DVB is not set +CONFIG_DVB=y CONFIG_DVB_CORE=m # @@ -1593,19 +1757,13 @@ CONFIG_DVB_CORE=m # CONFIG_DVB_STV0299=m # CONFIG_DVB_SP887X is not set -# CONFIG_DVB_ALPS_TDLB7 is not set -CONFIG_DVB_ALPS_TDMB7=m -CONFIG_DVB_ATMEL_AT76C651=m CONFIG_DVB_CX24110=m -CONFIG_DVB_GRUNDIG_29504_491=m -CONFIG_DVB_GRUNDIG_29504_401=m CONFIG_DVB_MT312=m CONFIG_DVB_VES1820=m CONFIG_DVB_VES1X93=m -CONFIG_DVB_TWINHAN_DST=m CONFIG_DVB_TTUSB_DEC=m CONFIG_DVB_BT8XX=m -# CONFIG_DVB_TDA1004X is not set +CONFIG_DVB_TDA1004X=m CONFIG_DVB_NXT6000=m # @@ -1627,7 +1785,43 @@ CONFIG_DVB_TTUSB_BUDGET=m # # Supported FlexCopII (B2C2) Adapters # -CONFIG_DVB_B2C2_SKYSTAR=m +CONFIG_DVB_CINERGYT2=m +CONFIG_DVB_B2C2_FLEXCOP=m +CONFIG_DVB_B2C2_FLEXCOP_PCI=m +CONFIG_DVB_B2C2_FLEXCOP_USB=m +# CONFIG_DVB_B2C2_FLEXCOP_DEBUG is not set +CONFIG_DVB_CX22700=m +CONFIG_DVB_CX22702=m +CONFIG_DVB_DIB3000MB=m +CONFIG_DVB_DIB3000MC=m +CONFIG_DVB_CINERGYT2_TUNING=y +CONFIG_DVB_CINERGYT2_STREAM_URB_COUNT=32 +CONFIG_DVB_CINERGYT2_STREAM_BUF_SIZE=512 +CONFIG_DVB_CINERGYT2_QUERY_INTERVAL=250 +CONFIG_DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE=y +CONFIG_DVB_CINERGYT2_RC_QUERY_INTERVAL=100 +CONFIG_DVB_OR51132=m +CONFIG_DVB_USB=m +# CONFIG_DVB_USB_DEBUG is not set +CONFIG_DVB_USB_A800=m +CONFIG_DVB_USB_DIBUSB_MB=m +# CONFIG_DVB_USB_DIBUSB_MB_FAULTY is not set +CONFIG_DVB_USB_DIBUSB_MC=m +CONFIG_DVB_USB_UMT_010=m +CONFIG_DVB_USB_DIGITV=m +CONFIG_DVB_USB_VP7045=m +CONFIG_DVB_USB_NOVA_T_USB2=m +CONFIG_DVB_USB_DTT200U=m +CONFIG_DVB_USB_CXUSB=m +CONFIG_DVB_USB_VP702X=m +CONFIG_DVB_PLUTO2=m +CONFIG_DVB_LGDT330X=m + +CONFIG_DVB_S5H1420=m +CONFIG_DVB_SP8870=m +CONFIG_DVB_L64781=m +CONFIG_DVB_TDA10021=m + CONFIG_VIDEO_SAA7146=m CONFIG_VIDEO_SAA7146_VV=m CONFIG_VIDEO_VIDEOBUF=m @@ -1644,15 +1838,17 @@ CONFIG_FB=y CONFIG_FB_VGA16=m CONFIG_FB_VESA=y CONFIG_VIDEO_SELECT=y -CONFIG_FB_HGA=m +# CONFIG_FB_HGA is not set CONFIG_FB_RIVA=m +# CONFIG_FB_RIVA_DEBUG is not set +# CONFIG_FB_RIVA_I2C is not set CONFIG_FB_I810=m CONFIG_FB_I810_GTF=y +CONFIG_FB_I810_I2C=y CONFIG_FB_MATROX=m CONFIG_FB_MATROX_MILLENIUM=y CONFIG_FB_MATROX_MYSTIQUE=y -CONFIG_FB_MATROX_G450=y -CONFIG_FB_MATROX_G100=y +CONFIG_FB_MATROX_G=y CONFIG_FB_MATROX_I2C=m CONFIG_FB_MATROX_MAVEN=m CONFIG_FB_MATROX_MULTIHEAD=y @@ -1664,7 +1860,6 @@ CONFIG_FB_ATY128=m CONFIG_FB_ATY=m CONFIG_FB_ATY_CT=y CONFIG_FB_ATY_GX=y -# CONFIG_FB_ATY_XL_INIT is not set # CONFIG_FB_SIS is not set CONFIG_FB_SIS_300=y CONFIG_FB_SIS_315=y @@ -1677,17 +1872,35 @@ CONFIG_FB_KYRO=m # CONFIG_FB_PM2 is not set # CONFIG_FB_PM2_FIFO_DISCONNECT is not set # CONFIG_FB_ASILIANT is not set -CONFIG_FB_HGA_ACCEL=y CONFIG_FB_3DFX_ACCEL=y CONFIG_FB_TRIDENT_ACCEL=y +CONFIG_FB_CIRRUS=m +CONFIG_FB_TILEBLITTING=y +# CONFIG_FB_ARC is not set +CONFIG_FB_INTEL=m +# CONFIG_FB_INTEL_DEBUG is not set +CONFIG_FB_ATY_GENERIC_LCD=y +CONFIG_FB_SAVAGE=m +CONFIG_FB_SAVAGE_I2C=y +CONFIG_FB_SAVAGE_ACCEL=y +# 2.6.12-rc1-bk2 = Nvidia fb crashes. +# CONFIG_FB_NVIDIA is not set +CONFIG_FB_NVIDIA_I2C=y +# CONFIG_FB_GEODE is not set +# CONFIG_FB_S1D13XXX is not set +CONFIG_FB_CYBLA=m +# CONFIG_FB_FIRMWARE_EDID is not set # # Console display driver support # CONFIG_VGA_CONSOLE=y -CONFIG_MDA_CONSOLE=m +CONFIG_VGACON_SOFT_SCROLLBACK=y +CONFIG_VGACON_SOFT_SCROLLBACK_SIZE=64 +# CONFIG_MDA_CONSOLE is not set CONFIG_DUMMY_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y # CONFIG_FONTS is not set @@ -1708,16 +1921,20 @@ CONFIG_SOUND=m # Advanced Linux Sound Architecture # CONFIG_SND=m +CONFIG_SND_VERBOSE_PROCFS=y CONFIG_SND_SEQUENCER=m CONFIG_SND_SEQ_DUMMY=m +CONFIG_SND_SEQUENCER_OSS=y +CONFIG_SND_SEQ_RTCTIMER_DEFAULT=y CONFIG_SND_OSSEMUL=y CONFIG_SND_MIXER_OSS=m CONFIG_SND_PCM_OSS=m -CONFIG_SND_SEQUENCER_OSS=y +CONFIG_SND_PCM_OSS_PLUGINS=y CONFIG_SND_RTCTIMER=m # CONFIG_SND_VERBOSE_PRINTK is not set # CONFIG_SND_DEBUG is not set -CONFIG_SND_BIT32_EMUL=y +CONFIG_SND_DYNAMIC_MINORS=y +# CONFIG_SND_SUPPORT_OLD_API is not set # # Generic devices @@ -1731,34 +1948,8 @@ CONFIG_SND_MPU401=m # # ISA devices # -CONFIG_SND_AD1816A=m -CONFIG_SND_AD1848=m -CONFIG_SND_CS4231=m -CONFIG_SND_CS4232=m -CONFIG_SND_CS4236=m -CONFIG_SND_ES968=m -CONFIG_SND_ES1688=m -CONFIG_SND_ES18XX=m -CONFIG_SND_GUSCLASSIC=m -CONFIG_SND_GUSEXTREME=m -CONFIG_SND_GUSMAX=m -CONFIG_SND_INTERWAVE=m -CONFIG_SND_INTERWAVE_STB=m -CONFIG_SND_OPTI92X_AD1848=m -CONFIG_SND_OPTI92X_CS4231=m -CONFIG_SND_OPTI93X=m -CONFIG_SND_SB8=m -CONFIG_SND_SB16=m -CONFIG_SND_SBAWE=m -CONFIG_SND_SB16_CSP=y +CONFIG_SND_AD1889=m # CONFIG_SND_WAVEFRONT is not set -CONFIG_SND_ALS100=m -CONFIG_SND_AZT2320=m -CONFIG_SND_CMI8330=m -CONFIG_SND_DT019X=m -CONFIG_SND_OPL3SA2=m -CONFIG_SND_SGALAXY=m -CONFIG_SND_SSCAPE=m # # PCI devices @@ -1768,10 +1959,14 @@ CONFIG_SND_AZT3328=m CONFIG_SND_CS46XX=m CONFIG_SND_CS46XX_NEW_DSP=y CONFIG_SND_CS4281=m +CONFIG_SND_CS5535AUDIO=m CONFIG_SND_EMU10K1=m +CONFIG_SND_EMU10K1X=m +CONFIG_SND_CA0106=m CONFIG_SND_KORG1212=m CONFIG_SND_NM256=m CONFIG_SND_RME32=m +CONFIG_SND_PCXHR=m CONFIG_SND_RME96=m CONFIG_SND_RME9652=m CONFIG_SND_HDSP=m @@ -1790,28 +1985,36 @@ CONFIG_SND_ICE1724=m CONFIG_SND_INTEL8X0=m CONFIG_SND_SONICVIBES=m CONFIG_SND_VIA82XX=m +CONFIG_SND_VIA82XX_MODEM=m CONFIG_SND_VX222=m CONFIG_SND_BT87X=m +# CONFIG_SND_BT87X_OVERCLOCK is not set CONFIG_SND_ATIIXP=m +CONFIG_SND_ATIIXP_MODEM=m CONFIG_SND_AU8810=m CONFIG_SND_AU8820=m CONFIG_SND_AU8830=m CONFIG_SND_MIXART=m CONFIG_SND_FM801_TEA575X=m +CONFIG_SND_FM801_TEA575X_BOOL=y CONFIG_SND_INTEL8X0M=m -CONFIG_SND_PDAUDIOCF=m - +CONFIG_SND_HDA_INTEL=m +CONFIG_SND_HDSPM=m +CONFIG_SND_ADLIB=m +CONFIG_SND_MIRO=m +CONFIG_SND_ALS300=m +CONFIG_SND_RIPTIDE=m # # ALSA USB devices # CONFIG_SND_USB_AUDIO=m +CONFIG_SND_USB_USX2Y=m # # PCMCIA devices # # CONFIG_SND_VXPOCKET is not set -# CONFIG_SND_VXP440 is not set # # Open Sound System @@ -1832,6 +2035,7 @@ CONFIG_USB=y CONFIG_USB_DEVICEFS=y # CONFIG_USB_BANDWIDTH is not set # CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_SUSPEND is not set # # USB Host Controller Drivers @@ -1841,11 +2045,13 @@ CONFIG_USB_EHCI_SPLIT_ISO=y CONFIG_USB_EHCI_ROOT_HUB_TT=y CONFIG_USB_OHCI_HCD=m CONFIG_USB_UHCI_HCD=m +CONFIG_USB_SL811_CS=m # # USB Device Class drivers # -CONFIG_USB_AUDIO=m +# CONFIG_USB_AUDIO is not set +# CONFIG_OBSOLETE_OSS_USB_DRIVER is not set # # USB Bluetooth TTY can only be used with disabled Bluetooth subsystem @@ -1853,16 +2059,20 @@ CONFIG_USB_AUDIO=m CONFIG_USB_MIDI=m CONFIG_USB_ACM=m CONFIG_USB_PRINTER=m +CONFIG_BLK_DEV_UB=m CONFIG_USB_STORAGE=m # CONFIG_USB_STORAGE_DEBUG is not set CONFIG_USB_STORAGE_DATAFAB=y CONFIG_USB_STORAGE_FREECOM=y CONFIG_USB_STORAGE_ISD200=y CONFIG_USB_STORAGE_DPCM=y -CONFIG_USB_STORAGE_HP8200e=y CONFIG_USB_STORAGE_SDDR09=y CONFIG_USB_STORAGE_SDDR55=y CONFIG_USB_STORAGE_JUMPSHOT=y +CONFIG_USB_STORAGE_USBAT=y +CONFIG_USB_STORAGE_ONETOUCH=y +CONFIG_USB_STORAGE_ALAUDA=y +CONFIG_USB_LIBUSUAL=y # # USB Human Interface Devices (HID) @@ -1874,6 +2084,7 @@ CONFIG_HID_PID=y CONFIG_LOGITECH_FF=y CONFIG_THRUSTMASTER_FF=y CONFIG_USB_HIDDEV=y +CONFIG_USB_IDMOUSE=m # # USB HID Boot Protocol drivers @@ -1881,7 +2092,9 @@ CONFIG_USB_HIDDEV=y # CONFIG_USB_KBD is not set # CONFIG_USB_MOUSE is not set CONFIG_USB_AIPTEK=m + CONFIG_USB_WACOM=m + CONFIG_USB_KBTAB=m CONFIG_USB_POWERMATE=m CONFIG_USB_XPAD=m @@ -1891,7 +2104,6 @@ CONFIG_USB_XPAD=m # CONFIG_USB_MDC800=m CONFIG_USB_MICROTEK=m -CONFIG_USB_HPUSBSCSI=m # # USB Multimedia devices @@ -1899,12 +2111,13 @@ CONFIG_USB_HPUSBSCSI=m CONFIG_USB_DABUSB=m CONFIG_USB_VICAM=m CONFIG_USB_DSBR=m +CONFIG_USB_ET61X251=m CONFIG_USB_IBMCAM=m CONFIG_USB_KONICAWC=m CONFIG_USB_OV511=m -CONFIG_USB_PWC=m CONFIG_USB_SE401=m CONFIG_USB_STV680=m +CONFIG_USB_SN9C102=m # # USB Network adaptors @@ -1914,28 +2127,29 @@ CONFIG_USB_KAWETH=m CONFIG_USB_PEGASUS=m CONFIG_USB_RTL8150=m CONFIG_USB_USBNET=m +CONFIG_USB_SPEEDTOUCH=m +# Has dumb detection, which gets loaded for every hid device. +# CONFIG_USB_YEALINK is not set +CONFIG_USB_ZD1201=m +CONFIG_USB_NET_AX8817X=m +CONFIG_USB_NET_GL620A=m +CONFIG_USB_NET_NET1080=m +CONFIG_USB_NET_PLUSB=m +CONFIG_USB_NET_RNDIS_HOST=m +CONFIG_USB_NET_CDC_SUBSET=m +CONFIG_USB_NET_ZAURUS=m # # USB Host-to-Host Cables # CONFIG_USB_AN2720=y CONFIG_USB_BELKIN=y -CONFIG_USB_GENESYS=y -CONFIG_USB_NET1080=y -CONFIG_USB_PL2301=y # # Intelligent USB Devices/Gadgets # CONFIG_USB_ARMLINUX=y CONFIG_USB_EPSON2888=y -CONFIG_USB_ZAURUS=y -CONFIG_USB_CDCETHER=y - -# -# USB Network Adapters -# -CONFIG_USB_AX8817X=y # # USB port drivers @@ -1947,15 +2161,24 @@ CONFIG_USB_USS720=m # CONFIG_USB_SERIAL=m CONFIG_USB_SERIAL_GENERIC=y +CONFIG_USB_SERIAL_AIRPRIME=m +CONFIG_USB_SERIAL_ANYDATA=m +CONFIG_USB_SERIAL_ARK3116=m CONFIG_USB_SERIAL_BELKIN=m +CONFIG_USB_SERIAL_CP2101=m +CONFIG_USB_SERIAL_CYPRESS_M8=m +CONFIG_USB_SERIAL_CYBERJACK=m CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m +CONFIG_USB_SERIAL_EDGEPORT=m +CONFIG_USB_SERIAL_EDGEPORT_TI=m CONFIG_USB_SERIAL_EMPEG=m CONFIG_USB_SERIAL_FTDI_SIO=m -CONFIG_USB_SERIAL_VISOR=m +CONFIG_USB_SERIAL_FUNSOFT=m +CONFIG_USB_SERIAL_GARMIN=m +CONFIG_USB_SERIAL_HP4X=m CONFIG_USB_SERIAL_IPAQ=m +CONFIG_USB_SERIAL_IPW=m CONFIG_USB_SERIAL_IR=m -CONFIG_USB_SERIAL_EDGEPORT=m -CONFIG_USB_SERIAL_EDGEPORT_TI=m CONFIG_USB_SERIAL_KEYSPAN_PDA=m CONFIG_USB_SERIAL_KEYSPAN=m CONFIG_USB_SERIAL_KEYSPAN_MPR=y @@ -1973,13 +2196,17 @@ CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y CONFIG_USB_SERIAL_KLSI=m CONFIG_USB_SERIAL_KOBIL_SCT=m CONFIG_USB_SERIAL_MCT_U232=m +CONFIG_USB_SERIAL_NAVMAN=m +CONFIG_USB_SERIAL_OPTION=y +CONFIG_USB_SERIAL_OMNINET=m CONFIG_USB_SERIAL_PL2303=m CONFIG_USB_SERIAL_SAFE=m CONFIG_USB_SERIAL_SAFE_PADDED=y -CONFIG_USB_SERIAL_CYBERJACK=m -CONFIG_USB_SERIAL_XIRCOM=m -CONFIG_USB_SERIAL_OMNINET=m +CONFIG_USB_SERIAL_TI=m +CONFIG_USB_SERIAL_VISOR=m CONFIG_USB_SERIAL_WHITEHEAT=m +CONFIG_USB_SERIAL_XIRCOM=m + CONFIG_USB_EZUSB=y CONFIG_USB_EMI62=m CONFIG_USB_LED=m @@ -1989,30 +2216,45 @@ CONFIG_USB_G_SERIAL=m # # USB Miscellaneous drivers # -# CONFIG_USB_EMI26 is not set -CONFIG_USB_TIGL=m +CONFIG_USB_EMI26=m CONFIG_USB_AUERSWALD=m CONFIG_USB_RIO500=m -CONFIG_USB_BRLVGER=m CONFIG_USB_LCD=m CONFIG_USB_TEST=m # CONFIG_USB_GADGET is not set # CONFIG_USB_GADGET_PXA2XX is not set # CONFIG_USB_GADGET_GOKU is not set -# CONFIG_USB_GADGET_SA1100 is not set CONFIG_USB_ZERO=m CONFIG_USB_ETH=m -CONFIG_USB_GADGETFS=m +# CONFIG_USB_GADGETFS is not set CONFIG_USB_W9968CF=m +CONFIG_USB_ZC0301=m +CONFIG_USB_PWC=m CONFIG_USB_LEGOTOWER=m CONFIG_USB_FILE_STORAGE=m # CONFIG_USB_FILE_STORAGE_TEST is not set -CONFIG_USB_MTOUCH=m CONFIG_USB_ATI_REMOTE=m +CONFIG_USB_ATI_REMOTE2=m CONFIG_USB_ALI_M5632=y # CONFIG_USB_CYTHERM is not set -CONFIG_USB_EGALAX=m CONFIG_USB_PHIDGETSERVO=m +CONFIG_USB_SL811_HCD=m +CONFIG_USB_PHIDGETKIT=m +CONFIG_USB_MON=y +CONFIG_USB_SISUSBVGA=m +CONFIG_USB_SISUSBVGA_CON=y +CONFIG_USB_ISP116X_HCD=m +CONFIG_USB_ACECAD=m +CONFIG_USB_ATM=m +CONFIG_USB_CXACRU=m +CONFIG_USB_XUSBATM=m +CONFIG_USB_UEAGLEATM=m +CONFIG_USB_KEYSPAN_REMOTE=m +CONFIG_USB_LD=m +CONFIG_USB_APPLETOUCH=m + +CONFIG_USB_TOUCHSCREEN=m + # # File systems @@ -2021,6 +2263,7 @@ CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y CONFIG_EXT2_FS_POSIX_ACL=y CONFIG_EXT2_FS_SECURITY=y +CONFIG_EXT2_FS_XIP=y CONFIG_EXT3_FS=m CONFIG_EXT3_FS_XATTR=y CONFIG_EXT3_FS_POSIX_ACL=y @@ -2038,6 +2281,7 @@ CONFIG_JFS_FS=m # CONFIG_JFS_DEBUG is not set # CONFIG_JFS_STATISTICS is not set CONFIG_JFS_POSIX_ACL=y +CONFIG_JFS_SECURITY=y CONFIG_XFS_FS=m # CONFIG_XFS_RT is not set CONFIG_XFS_QUOTA=y @@ -2067,6 +2311,8 @@ CONFIG_UDF_FS=m CONFIG_FAT_FS=m CONFIG_MSDOS_FS=m CONFIG_VFAT_FS=m +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="ascii" # CONFIG_NTFS_FS is not set # @@ -2074,13 +2320,11 @@ CONFIG_VFAT_FS=m # CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y -# CONFIG_DEVFS_FS is not set -CONFIG_DEVPTS_FS_XATTR=y -CONFIG_DEVPTS_FS_SECURITY=y CONFIG_TMPFS=y CONFIG_HUGETLBFS=y CONFIG_HUGETLB_PAGE=y CONFIG_RAMFS=y +CONFIG_DEBUG_FS=y # # Miscellaneous filesystems @@ -2097,8 +2341,9 @@ CONFIG_EFS_FS=m # CONFIG_JFFS_FS is not set CONFIG_JFFS2_FS=m CONFIG_JFFS2_FS_DEBUG=0 -CONFIG_JFFS2_FS_NAND=y CONFIG_CRAMFS=m +CONFIG_SQUASHFS=m +# CONFIG_SQUASHFS_EMBEDDED is not set CONFIG_VXFS_FS=m # CONFIG_HPFS_FS is not set CONFIG_QNX4FS_FS=m @@ -2106,16 +2351,20 @@ CONFIG_QNX4FS_FS=m CONFIG_SYSV_FS=m CONFIG_UFS_FS=m # CONFIG_UFS_FS_WRITE is not set +CONFIG_9P_FS=m +CONFIG_FUSE_FS=m # # Network File Systems # CONFIG_NFS_FS=m CONFIG_NFS_V3=y +CONFIG_NFS_V3_ACL=y CONFIG_NFS_V4=y CONFIG_NFS_DIRECTIO=y CONFIG_NFSD=m CONFIG_NFSD_V3=y +CONFIG_NFSD_V3_ACL=y CONFIG_NFSD_V4=y CONFIG_NFSD_TCP=y CONFIG_LOCKD=m @@ -2124,10 +2373,14 @@ CONFIG_EXPORTFS=m CONFIG_SUNRPC=m CONFIG_SUNRPC_GSS=m CONFIG_RPCSEC_GSS_KRB5=m -CONFIG_SMB_FS=m +CONFIG_RPCSEC_GSS_SPKM3=m +# CONFIG_SMB_FS is not set # CONFIG_SMB_NLS_DEFAULT is not set CONFIG_CIFS=m # CONFIG_CIFS_STATS is not set +# CONFIG_CIFS_EXPERIMENTAL is not set +CONFIG_CIFS_XATTR=y +CONFIG_CIFS_POSIX=y CONFIG_NCP_FS=m CONFIG_NCPFS_PACKET_SIGNING=y CONFIG_NCPFS_IOCTL_LOCKING=y @@ -2137,18 +2390,21 @@ CONFIG_NCPFS_OS2_NS=y CONFIG_NCPFS_SMALLDOS=y CONFIG_NCPFS_NLS=y CONFIG_NCPFS_EXTRAS=y -# CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set +CONFIG_CODA_FS=m +# CONFIG_CODA_FS_OLD_API is not set # CONFIG_AFS_FS is not set # CONFIG_RXRPC is not set +CONFIG_OCFS2_FS=m +CONFIG_CONFIGFS_FS=m + # # Partition Types # CONFIG_PARTITION_ADVANCED=y # CONFIG_ACORN_PARTITION is not set CONFIG_OSF_PARTITION=y -# CONFIG_AMIGA_PARTITION is not set +CONFIG_AMIGA_PARTITION=y # CONFIG_ATARI_PARTITION is not set CONFIG_MAC_PARTITION=y CONFIG_MSDOS_PARTITION=y @@ -2157,18 +2413,19 @@ CONFIG_MINIX_SUBPARTITION=y CONFIG_SOLARIS_X86_PARTITION=y CONFIG_UNIXWARE_DISKLABEL=y # CONFIG_LDM_PARTITION is not set -# CONFIG_NEC98_PARTITION is not set CONFIG_SGI_PARTITION=y # CONFIG_ULTRIX_PARTITION is not set CONFIG_SUN_PARTITION=y CONFIG_EFI_PARTITION=y +CONFIG_KARMA_PARTITION=y + CONFIG_NLS=y # # Native Language Support # CONFIG_NLS_DEFAULT="utf8" -CONFIG_NLS_CODEPAGE_437=m +CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_CODEPAGE_737=m CONFIG_NLS_CODEPAGE_775=m CONFIG_NLS_CODEPAGE_850=m @@ -2205,6 +2462,7 @@ CONFIG_NLS_ISO8859_15=m CONFIG_NLS_KOI8_R=m CONFIG_NLS_KOI8_U=m CONFIG_NLS_UTF8=m +CONFIG_NLS_ASCII=y # # Profiling support @@ -2212,46 +2470,54 @@ CONFIG_NLS_UTF8=m CONFIG_PROFILING=y CONFIG_OPROFILE=m -# -# Tux -# -CONFIG_TUX=m -CONFIG_TUX_EXTCGI=y -# CONFIG_TUX_EXTENDED_LOG is not set -# CONFIG_TUX_DEBUG is not set - - # # Kernel hacking # CONFIG_DEBUG_KERNEL=y -CONFIG_DEBUG_STACKOVERFLOW=y -# CONFIG_DEBUG_SLAB is not set CONFIG_MAGIC_SYSRQ=y -# CONFIG_DEBUG_SPINLOCK is not set -# CONFIG_DEBUG_PAGEALLOC is not set -# CONFIG_DEBUG_HIGHMEM is not set CONFIG_DEBUG_INFO=y -CONFIG_DEBUG_SPINLOCK_SLEEP=y # CONFIG_FRAME_POINTER is not set CONFIG_CC_OPTIMIZE_FOR_SIZE=y -# CONFIG_DEBUG_STACK_USAGE is not set # CONFIG_DEBUG_DRIVER is not set +# CONFIG_RCU_TORTURE_TEST is not set +# Turn off these debug options for production kernels. +# CONFIG_DEBUG_SLAB is not set +CONFIG_DEBUG_MUTEXES=y +CONFIG_DEBUG_VM=y + +# These debug options are deliberatly left on. +# They aren't that much of a performance impact, and the value +# from getting out-of-tree modules fixed is worth the trade-off. +CONFIG_DEBUG_HIGHMEM=y +CONFIG_DEBUG_SPINLOCK=y +CONFIG_DEBUG_SPINLOCK_SLEEP=y +CONFIG_BOOT_DELAY=y +CONFIG_DEBUG_SLAB_LEAK=y + +CONFIG_KGDB=y +# CONFIG_KGDB_CONSOLE is not set +CONFIG_KGDBOE=m +# CONFIG_KGDB_SIMPLE_SERIAL is not set +CONFIG_KGDB_8250_CONF_STRING="" # # Security options # CONFIG_SECURITY=y CONFIG_SECURITY_NETWORK=y +CONFIG_SECURITY_NETWORK_XFRM=y CONFIG_SECURITY_CAPABILITIES=y # CONFIG_SECURITY_ROOTPLUG is not set CONFIG_SECURITY_SELINUX=y CONFIG_SECURITY_SELINUX_BOOTPARAM=y CONFIG_SECURITY_SELINUX_DISABLE=y CONFIG_SECURITY_SELINUX_DEVELOP=y -# CONFIG_SECURITY_SELINUX_MLS is not set -# CONFIG_AUDIT is not set +CONFIG_SECURITY_SELINUX_AVC_STATS=y +CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=1 +CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1 +# CONFIG_SECURITY_SECLVL is not set +CONFIG_AUDIT=y CONFIG_AUDITSYSCALL=y # @@ -2262,7 +2528,7 @@ CONFIG_CRYPTO_HMAC=y CONFIG_CRYPTO_NULL=m CONFIG_CRYPTO_MD4=m CONFIG_CRYPTO_MD5=m -CONFIG_CRYPTO_SHA1=m +CONFIG_CRYPTO_SHA1=y CONFIG_CRYPTO_SHA256=m CONFIG_CRYPTO_SHA512=m CONFIG_CRYPTO_DES=m @@ -2278,22 +2544,225 @@ CONFIG_CRYPTO_MICHAEL_MIC=m # CONFIG_CRYPTO_TEST is not set CONFIG_LIBCRC32C=m CONFIG_CRYPTO_CRC32C=m +CONFIG_CRYPTO_SIGNATURE_DSA=y +CONFIG_CRYPTO_MPILIB=y +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_KHAZAD=m +CONFIG_CRYPTO_WP512=m +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_TGR192=m # # Library routines # +CONFIG_CRC16=m CONFIG_CRC32=m +CONFIG_CRC_CCITT=m + CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=m -CONFIG_PC=y + +CONFIG_INITRAMFS_SOURCE="" +CONFIG_KEYS=y +CONFIG_KEYS_DEBUG_PROC_KEYS=y +CONFIG_CDROM_PKTCDVD=m +CONFIG_CDROM_PKTCDVD_BUFFERS=8 +# CONFIG_CDROM_PKTCDVD_WCACHE is not set + +CONFIG_ATA_OVER_ETH=m +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_BACKLIGHT_CLASS_DEVICE=m +CONFIG_BACKLIGHT_DEVICE=y +CONFIG_LCD_CLASS_DEVICE=m +CONFIG_LCD_DEVICE=y + +CONFIG_NETDUMP=m +CONFIG_DISKDUMP=m + +CONFIG_SCHEDSTATS=y + +CONFIG_TUX=m +CONFIG_TUX_EXTCGI=y +CONFIG_TUX_EXTENDED_LOG=y +# CONFIG_TUX_DEBUG is not set + +CONFIG_CPUSETS=y +CONFIG_RELAY=y +# CONFIG_SECCOMP is not set +# CONFIG_PRINTK_TIME is not set + +CONFIG_DETECT_SOFTLOCKUP=y + +CONFIG_KEXEC=y + +CONFIG_HWMON=m +# CONFIG_HWMON_DEBUG_CHIP is not set +CONFIG_INOTIFY=y + +CONFIG_CONNECTOR=m + +CONFIG_IBMASR=m + +CONFIG_PM_LEGACY=y + +CONFIG_CRASH=m + +## BEGIN ISA Junk. + +# CONFIG_I82365 is not set +# CONFIG_TCIC is not set +# CONFIG_PCMCIA_PROBE is not set +# CONFIG_LTPC is not set +# CONFIG_COPS is not set + +CONFIG_SCSI_AHA152X=m +CONFIG_SCSI_AHA1542=m +# CONFIG_SCSI_IN2000 is not set +# CONFIG_SCSI_DTC3280 is not set +# CONFIG_SCSI_GENERIC_NCR5380 is not set +# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set +# CONFIG_SCSI_NCR53C406A is not set +# CONFIG_SCSI_PAS16 is not set +# CONFIG_SCSI_PSI240I is not set +# CONFIG_SCSI_QLOGIC_FAS is not set +# CONFIG_SCSI_SYM53C416 is not set +# CONFIG_SCSI_T128 is not set +# CONFIG_SCSI_U14_34F is not set +# CONFIG_SCSI_ULTRASTOR is not set +# CONFIG_CD_NO_IDESCSI is not set + +# CONFIG_EL1 is not set +# CONFIG_EL2 is not set +# CONFIG_ELPLUS is not set +# CONFIG_EL16 is not set +CONFIG_EL3=m +# CONFIG_3C515 is not set +# CONFIG_LANCE is not set +CONFIG_NET_VENDOR_SMC=y +# CONFIG_WD80x3 is not set +CONFIG_ULTRA=m +# CONFIG_SMC9194 is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_NI52 is not set +# CONFIG_NI65 is not set +# CONFIG_AT1700 is not set +# CONFIG_DEPCA is not set +CONFIG_NET_ISA=y +CONFIG_NE2000=m +# CONFIG_E2100 is not set +CONFIG_EWRK3=m +# CONFIG_EEXPRESS is not set +# CONFIG_EEXPRESS_PRO is not set +# CONFIG_HPLAN_PLUS is not set +# CONFIG_HPLAN is not set +# CONFIG_LP486E is not set +# CONFIG_ETH16I is not set +# CONFIG_ZNET is not set +# CONFIG_SEEQ8005 is not set +# CONFIG_AC3200 is not set +# CONFIG_APRICOT is not set +# CONFIG_CS89x0 is not set +# CONFIG_IBMTR is not set +# CONFIG_SKISA is not set +# CONFIG_PROTEON is not set +# CONFIG_SMCTR is not set +# CONFIG_WAVELAN is not set +# CONFIG_HISAX_16_0 is not set +# CONFIG_HISAX_AVM_A1 is not set +# CONFIG_HISAX_IX1MICROR2 is not set +# CONFIG_HISAX_ASUSCOM is not set +# CONFIG_HISAX_TELEINT is not set +# CONFIG_HISAX_HFCS is not set +# CONFIG_HISAX_SPORTSTER is not set +# CONFIG_HISAX_MIC is not set +# CONFIG_HISAX_ISURF is not set +# CONFIG_HISAX_HSTSAPHIR is not set +# CONFIG_ISDN_DRV_ICN is not set +# CONFIG_ISDN_DRV_PCBIT is not set +# CONFIG_ISDN_DRV_SC is not set +# CONFIG_ISDN_DRV_ACT2000 is not set +# CONFIG_ISDN_DRV_AVMB1_B1ISA is not set +# CONFIG_ISDN_DRV_AVMB1_T1ISA is not set + +# CONFIG_MOUSE_INPORT is not set +# CONFIG_MOUSE_ATIXL is not set +# CONFIG_MOUSE_LOGIBM is not set +# CONFIG_MOUSE_PC110PAD is not set + +# CONFIG_SERIAL_8250_FOURPORT is not set +# CONFIG_SERIAL_8250_ACCENT is not set +# CONFIG_SERIAL_8250_BOCA is not set +# CONFIG_SERIAL_8250_HUB6 is not set + +# CONFIG_PCWATCHDOG is not set +# CONFIG_WDT is not set + +# CONFIG_VIDEO_PMS is not set +# CONFIG_RADIO_CADET is not set +# CONFIG_RADIO_RTRACK is not set +# CONFIG_RADIO_RTRACK2 is not set +# CONFIG_RADIO_AZTECH is not set +# CONFIG_RADIO_GEMTEK is not set +# CONFIG_RADIO_SF16FMI is not set +# CONFIG_RADIO_SF16FMR2 is not set +# CONFIG_RADIO_TERRATEC is not set +# CONFIG_RADIO_TRUST is not set +# CONFIG_RADIO_TYPHOON is not set +# CONFIG_RADIO_ZOLTRIX is not set + +# CONFIG_SND_OPL4_LIB is not set +# CONFIG_SND_AD1848_LIB is not set +# CONFIG_SND_AD1816A is not set +# CONFIG_SND_AD1848 is not set +# CONFIG_SND_CS4231 is not set +# CONFIG_SND_CS4232 is not set +CONFIG_SND_CS4231_LIB=m +CONFIG_SND_CS4236=m +# CONFIG_SND_ES968 is not set +# CONFIG_SND_ES1688 is not set +CONFIG_SND_ES18XX=m +# CONFIG_SND_GUS_SYNTH is not set +# CONFIG_SND_GUSCLASSIC is not set +# CONFIG_SND_GUSEXTREME is not set +# CONFIG_SND_GUSMAX is not set +# CONFIG_SND_INTERWAVE is not set +# CONFIG_SND_INTERWAVE_STB is not set +# CONFIG_SND_OPTI92X_AD1848 is not set +# CONFIG_SND_OPTI92X_CS4231 is not set +# CONFIG_SND_OPTI93X is not set +# CONFIG_SND_SB8 is not set +CONFIG_SND_SB16=m +CONFIG_SND_SBAWE=m +# CONFIG_SND_SB16_CSP is not set +# CONFIG_SND_ALS100 is not set +# CONFIG_SND_AZT2320 is not set +# CONFIG_SND_CMI8330 is not set +# CONFIG_SND_DT019X is not set +CONFIG_SND_OPL3SA2=m +# CONFIG_SND_SGALAXY is not set +# CONFIG_SND_SSCAPE is not set +# CONFIG_SND_PDAUDIOCF is not set + +## END of ISA options. + +# FIXME: This needs to be made to depend on PPC +# CONFIG_USB_HIDINPUT_POWERBOOK is not set + +CONFIG_UNWIND_INFO=y +# CONFIG_FORCED_INLINING is not set + +CONFIG_MIGRATION=y +# CONFIG_NEW_LEDS is not set + +CONFIG_UID16=y # CONFIG_X86_PC is not set +CONFIG_X86_GENERICARCH=y # CONFIG_X86_ELAN is not set # CONFIG_X86_VOYAGER is not set # CONFIG_X86_NUMAQ is not set # CONFIG_X86_SUMMIT is not set # CONFIG_X86_BIGSMP is not set # CONFIG_X86_VISWS is not set -CONFIG_X86_GENERICARCH=y # CONFIG_X86_ES7000 is not set # CONFIG_M386 is not set # CONFIG_M486 is not set @@ -2327,9 +2796,11 @@ CONFIG_X86_POPAD_OK=y CONFIG_X86_GOOD_APIC=y CONFIG_X86_INTEL_USERCOPY=y CONFIG_X86_USE_PPRO_CHECKSUM=y +CONFIG_HPET=y CONFIG_HPET_TIMER=y CONFIG_HPET_EMULATE_RTC=y -CONFIG_NR_CPUS=32 +# CONFIG_HPET_RTC_IRQ is not set +# CONFIG_HPET_MMAP is not set CONFIG_X86_LOCAL_APIC=y CONFIG_X86_IO_APIC=y CONFIG_X86_TSC=y @@ -2343,32 +2814,41 @@ CONFIG_MICROCODE=m CONFIG_X86_MSR=m CONFIG_X86_CPUID=m CONFIG_EDD=m -# CONFIG_NOHIGHMEM is not set -CONFIG_HIGHMEM4G=y -CONFIG_HIGHMEM64G=y -# CONFIG_HIGHMEM64G is not set +# CONFIG_NUMA is not set CONFIG_HIGHMEM=y CONFIG_HIGHPTE=y # CONFIG_MATH_EMULATION is not set CONFIG_MTRR=y -CONFIG_HAVE_DEC_LOCK=y -# CONFIG_X86_UP_APIC is not set +CONFIG_X86_UP_APIC=y +CONFIG_X86_UP_IOAPIC=y CONFIG_X86_PM_TIMER=y -CONFIG_X86_4G=y -# CONFIG_EFI is not set +CONFIG_EFI=y +CONFIG_EFI_VARS=y +CONFIG_EFI_PCDP=y +CONFIG_EFI_RTC=y CONFIG_REGPARM=y # CONFIG_PCI_GOBIOS is not set # CONFIG_PCI_GODIRECT is not set +# CONFIG_PCI_GOMMCONFIG is not set CONFIG_PCI_GOANY=y -CONFIG_MDA_CONSOLE=m +CONFIG_ROCKETPORT=m CONFIG_SYNCLINK_CS=m CONFIG_SYNCLINK=m CONFIG_SYNCLINKMP=m CONFIG_HP100=m CONFIG_PCMCIA_FDOMAIN=m CONFIG_SCSI_FUTURE_DOMAIN=m -CONFIG_CRASH=m +CONFIG_SCSI_ADVANSYS=m +CONFIG_CAPI_EICON=y CONFIG_I2O=m +CONFIG_I2O_BLOCK=m +CONFIG_I2O_SCSI=m +CONFIG_I2O_PROC=m +CONFIG_I2O_CONFIG=y +CONFIG_I2O_EXT_ADAPTEC=y +CONFIG_I2O_EXT_ADAPTEC_DMA64=y +CONFIG_I2O_CONFIG_OLD_IOCTL=y +CONFIG_I2O_BUS=m CONFIG_APM=y # CONFIG_APM_IGNORE_USER_SUSPEND is not set # CONFIG_APM_DO_ENABLE is not set @@ -2379,37 +2859,142 @@ CONFIG_APM_RTC_IS_GMT=y # CONFIG_APM_REAL_MODE_POWER_OFF is not set CONFIG_X86_FIND_SMP_CONFIG=y CONFIG_X86_MPPARSE=y -CONFIG_4KSTACKS=y +CONFIG_ACPI=y +CONFIG_ACPI_SLEEP=y +CONFIG_ACPI_AC=m +CONFIG_ACPI_BATTERY=m +CONFIG_ACPI_BUTTON=m +CONFIG_ACPI_FAN=y +CONFIG_ACPI_PROCESSOR=y +CONFIG_ACPI_THERMAL=y +CONFIG_ACPI_ASUS=m +CONFIG_ACPI_TOSHIBA=m +# CONFIG_ACPI_DEBUG is not set +CONFIG_ACPI_EC=y +CONFIG_ACPI_POWER=y +CONFIG_ACPI_SYSTEM=y +CONFIG_ACPI_NUMA=y +CONFIG_ACPI_BLACKLIST_YEAR=1999 +CONFIG_ACPI_VIDEO=m +CONFIG_ACPI_IBM=m +CONFIG_PNPACPI=y +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_DEBUG=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=m +CONFIG_CPU_FREQ_GOV_USERSPACE=m +CONFIG_CPU_FREQ_GOV_ONDEMAND=m +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m +CONFIG_CPU_FREQ_TABLE=y +CONFIG_CPU_FREQ_STAT=m +CONFIG_CPU_FREQ_STAT_DETAILS=y CONFIG_X86_ACPI_CPUFREQ=m # CONFIG_X86_ACPI_CPUFREQ_PROC_INTF is not set -CONFIG_X86_POWERNOW_K6=m +# CONFIG_X86_POWERNOW_K6 is not set CONFIG_X86_POWERNOW_K7=y -CONFIG_X86_POWERNOW_K8=m +CONFIG_X86_POWERNOW_K8=y # CONFIG_X86_GX_SUSPMOD is not set CONFIG_X86_SPEEDSTEP_CENTRINO=y CONFIG_X86_SPEEDSTEP_ICH=y -CONFIG_X86_SPEEDSTEP_SMI=m +CONFIG_X86_SPEEDSTEP_SMI=y CONFIG_X86_SPEEDSTEP_LIB=y CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI=y +CONFIG_X86_SPEEDSTEP_CENTRINO_TABLE=y # CONFIG_X86_SPEEDSTEP_RELAXED_CAP_CHECK is not set CONFIG_X86_P4_CLOCKMOD=m CONFIG_X86_LONGRUN=y # CONFIG_X86_LONGHAUL is not set +# CONFIG_X86_CPUFREQ_NFORCE2 is not set CONFIG_X86_SMP=y CONFIG_X86_HT=y CONFIG_X86_BIOS_REBOOT=y CONFIG_X86_TRAMPOLINE=y -CONFIG_TUX=m -CONFIG_NVRAM=m +CONFIG_NVRAM=y CONFIG_IBM_ASM=m -CONFIG_M686=y -# CONFIG_NOHIGHMEM is not set -CONFIG_HIGHMEM64G=y +CONFIG_CRYPTO_AES_586=m +CONFIG_CRYPTO_DEV_PADLOCK=m +CONFIG_CRYPTO_DEV_PADLOCK_AES=y +CONFIG_GENERIC_ISA_DMA=y +CONFIG_SCHED_SMT=y +# CONFIG_IRQBALANCE is not set +CONFIG_SOFTWARE_SUSPEND=y +CONFIG_PM_DEBUG=y +CONFIG_PM_STD_PARTITION="" +CONFIG_DEBUG_RODATA=y +CONFIG_DEBUG_STACKOVERFLOW=y +CONFIG_DEBUG_STACK_USAGE=y +CONFIG_STACK_BACKTRACE_COLS=2 +CONFIG_4KSTACKS=y +CONFIG_KPROBES=y +# CONFIG_DEBUG_PAGEALLOC is not set +CONFIG_PCI_DIRECT=y +CONFIG_PCI_MMCONFIG=y +CONFIG_PCI_BIOS=y CONFIG_HOTPLUG_PCI=y CONFIG_HOTPLUG_PCI_COMPAQ=m +# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set CONFIG_HOTPLUG_PCI_IBM=m +CONFIG_HOTPLUG_PCI_ACPI=m +CONFIG_HOTPLUG_PCI_ACPI_IBM=m +CONFIG_ACPI_IBM_DOCK=y +# CONFIG_HOTPLUG_PCI_CPCI is not set +CONFIG_HOTPLUG_PCI_PCIE=m +# CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE is not set +# CONFIG_HOTPLUG_PCI_SHPC is not set +# CONFIG_HOTPLUG_PCI_SHPC_POLL_EVENT_MODE is not set +# CONFIG_HOTPLUG_PCI_SHPC_PHPRM_LEGACY is not set +CONFIG_PM=y +CONFIG_IEEE80211=m +# CONFIG_IEEE80211_DEBUG is not set +CONFIG_IEEE80211_CRYPT_CCMP=m +CONFIG_IEEE80211_CRYPT_TKIP=m +CONFIG_IPW2100=m +CONFIG_IPW2100_MONITOR=y +CONFIG_IPW2200=m +CONFIG_IPW2200_MONITOR=y +CONFIG_IPW_QOS=y +CONFIG_BLK_DEV_AMD74XX=y +CONFIG_I2C_ALI1535=m +CONFIG_I2C_ALI15X3=m +CONFIG_I2C_ALI1563=m +CONFIG_I2C_AMD756=m +CONFIG_I2C_AMD756_S4882=m +CONFIG_I2C_AMD8111=m +CONFIG_I2C_I801=m +CONFIG_I2C_I810=m +CONFIG_I2C_ISA=m +CONFIG_I2C_NFORCE2=m +CONFIG_I2C_PIIX4=m +CONFIG_I2C_PROSAVAGE=m +CONFIG_I2C_SAVAGE4=m +# CONFIG_SCx200_ACB is not set +CONFIG_I2C_SIS5595=m +CONFIG_I2C_SIS630=m +CONFIG_I2C_SIS96X=m +CONFIG_I2C_VIA=m +CONFIG_I2C_VIAPRO=m +CONFIG_I2C_VOODOO3=m +# CONFIG_X86_REBOOTFIXUPS is not set +CONFIG_PHYSICAL_START=0x400000 +CONFIG_DELL_RBU=m +CONFIG_DCDBAS=m +CONFIG_CS5535_GPIO=m +CONFIG_EDAC=y +# CONFIG_EDAC_DEBUG is not set +CONFIG_EDAC_MM_EDAC=m +CONFIG_EDAC_AMD76X=m +CONFIG_EDAC_E7XXX=m +CONFIG_EDAC_E752X=m +CONFIG_EDAC_I82875P=m +CONFIG_EDAC_I82860=m +CONFIG_EDAC_R82600=m +CONFIG_SCHED_MC=y +CONFIG_SND_ES18XX=m +CONFIG_TCG_INFINEON=m +CONFIG_M686=y +# CONFIG_SMP is not set +# CONFIG_NOHIGHMEM is not set +CONFIG_HIGHMEM4G=y # CONFIG_HIGHMEM64G is not set -# CONFIG_EWRK3 is not set -CONFIG_NR_CPUS=32 -# CONFIG_X86_PC is not set -CONFIG_X86_GENERICARCH=y diff --git a/Documentation/networking/netdevices.txt b/Documentation/networking/netdevices.txt index 3c0a5ba61..847cedb23 100644 --- a/Documentation/networking/netdevices.txt +++ b/Documentation/networking/netdevices.txt @@ -42,9 +42,9 @@ dev->get_stats: Context: nominally process, but don't sleep inside an rwlock dev->hard_start_xmit: - Synchronization: dev->xmit_lock spinlock. + Synchronization: netif_tx_lock spinlock. When the driver sets NETIF_F_LLTX in dev->features this will be - called without holding xmit_lock. In this case the driver + called without holding netif_tx_lock. In this case the driver has to lock by itself when needed. It is recommended to use a try lock for this and return -1 when the spin lock fails. The locking there should also properly protect against @@ -62,12 +62,12 @@ dev->hard_start_xmit: Only valid when NETIF_F_LLTX is set. dev->tx_timeout: - Synchronization: dev->xmit_lock spinlock. + Synchronization: netif_tx_lock spinlock. Context: BHs disabled Notes: netif_queue_stopped() is guaranteed true dev->set_multicast_list: - Synchronization: dev->xmit_lock spinlock. + Synchronization: netif_tx_lock spinlock. Context: BHs disabled dev->poll: diff --git a/MAINTAINERS b/MAINTAINERS index c3c584240..6a1bb87d8 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2572,6 +2572,14 @@ M: dbrownell@users.sourceforge.net L: spi-devel-general@lists.sourceforge.net S: Maintained +STABLE BRANCH: +P: Greg Kroah-Hartman +M: greg@kroah.com +P: Chris Wright +M: chrisw@sous-sol.org +L: stable@kernel.org +S: Maintained + TPM DEVICE DRIVER P: Kylene Hall M: kjhall@us.ibm.com diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig index 03f53c27e..d75fa4047 100644 --- a/arch/i386/Kconfig +++ b/arch/i386/Kconfig @@ -91,6 +91,15 @@ config X86_PC help Choose this option if your computer is a standard PC or compatible. +config X86_XEN + bool "Xen-compatible" + select X86_UP_APIC if !SMP && XEN_PRIVILEGED_GUEST + select X86_UP_IOAPIC if !SMP && XEN_PRIVILEGED_GUEST + select SWIOTLB + help + Choose this option if you plan to run this kernel on top of the + Xen Hypervisor. + config X86_ELAN bool "AMD Elan" help @@ -193,6 +202,7 @@ source "arch/i386/Kconfig.cpu" config HPET_TIMER bool "HPET Timer Support" + depends on !X86_XEN help This enables the use of the HPET for the kernel's internal timer. HPET is the next generation timer replacing legacy 8254s. @@ -223,7 +233,7 @@ config NR_CPUS config SCHED_SMT bool "SMT (Hyperthreading) scheduler support" - depends on SMP + depends on SMP && !X86_XEN default off help SMT scheduler support improves the CPU scheduler's decision making @@ -233,7 +243,7 @@ config SCHED_SMT config SCHED_MC bool "Multi-core scheduler support" - depends on SMP + depends on SMP && !X86_XEN default y help Multi-core scheduler support improves the CPU scheduler's decision @@ -244,7 +254,7 @@ source "kernel/Kconfig.preempt" config X86_UP_APIC bool "Local APIC support on uniprocessors" - depends on !SMP && !(X86_VISWS || X86_VOYAGER) + depends on !SMP && !(X86_VISWS || X86_VOYAGER || XEN_UNPRIVILEGED_GUEST) help A local APIC (Advanced Programmable Interrupt Controller) is an integrated interrupt controller in the CPU. If you have a single-CPU @@ -269,12 +279,12 @@ config X86_UP_IOAPIC config X86_LOCAL_APIC bool - depends on X86_UP_APIC || ((X86_VISWS || SMP) && !X86_VOYAGER) + depends on X86_UP_APIC || ((X86_VISWS || SMP) && !(X86_VOYAGER || XEN_UNPRIVILEGED_GUEST)) default y config X86_IO_APIC bool - depends on X86_UP_IOAPIC || (SMP && !(X86_VISWS || X86_VOYAGER)) + depends on X86_UP_IOAPIC || (SMP && !(X86_VISWS || X86_VOYAGER || XEN_UNPRIVILEGED_GUEST)) default y config X86_VISWS_APIC @@ -282,9 +292,14 @@ config X86_VISWS_APIC depends on X86_VISWS default y +config X86_TSC + bool + depends on (MWINCHIP3D || MWINCHIP2 || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MGEODEGX1) && !X86_NUMAQ && !X86_XEN + default y + config X86_MCE bool "Machine Check Exception" - depends on !X86_VOYAGER + depends on !(X86_VOYAGER || X86_XEN) ---help--- Machine Check Exception support allows the processor to notify the kernel if it detects a problem (e.g. overheating, component failure). @@ -374,6 +389,7 @@ config X86_REBOOTFIXUPS config MICROCODE tristate "/dev/cpu/microcode - Intel IA32 CPU microcode support" + depends on !XEN_UNPRIVILEGED_GUEST ---help--- If you say Y here and also to "/dev file system support" in the 'File systems' section, you will be able to update the microcode on @@ -391,6 +407,7 @@ config MICROCODE config X86_MSR tristate "/dev/cpu/*/msr - Model-specific register support" + depends on !X86_XEN help This device gives privileged processes access to the x86 Model-Specific Registers (MSRs). It is a character device with @@ -406,6 +423,10 @@ config X86_CPUID with major 203 and minors 0 to 31 for /dev/cpu/0/cpuid to /dev/cpu/31/cpuid. +config SWIOTLB + bool + default n + source "drivers/firmware/Kconfig" choice @@ -578,7 +599,7 @@ config HAVE_ARCH_EARLY_PFN_TO_NID config HIGHPTE bool "Allocate 3rd-level pagetables from highmem" - depends on HIGHMEM4G || HIGHMEM64G + depends on (HIGHMEM4G || HIGHMEM64G) && !X86_XEN help The VM uses one page table entry for each page of physical memory. For systems with a lot of RAM, this can be wasteful of precious @@ -587,6 +608,7 @@ config HIGHPTE config MATH_EMULATION bool "Math emulation" + depends on !X86_XEN ---help--- Linux can emulate a math coprocessor (used for floating point operations) if you don't have one. 486DX and Pentium processors have @@ -612,6 +634,8 @@ config MATH_EMULATION config MTRR bool "MTRR (Memory Type Range Register) support" + depends on !XEN_UNPRIVILEGED_GUEST + default y if X86_XEN ---help--- On Intel P6 family processors (Pentium Pro, Pentium II and later) the Memory Type Range Registers (MTRRs) may be used to control @@ -646,7 +670,7 @@ config MTRR config EFI bool "Boot from EFI support (EXPERIMENTAL)" - depends on ACPI + depends on ACPI && !X86_XEN default n ---help--- This enables the the kernel to boot on EFI platforms using @@ -664,7 +688,7 @@ config EFI config IRQBALANCE bool "Enable kernel irq balancing" - depends on SMP && X86_IO_APIC + depends on SMP && X86_IO_APIC && !X86_XEN default y help The default yes will allow the kernel to do irq load balancing. @@ -712,7 +736,7 @@ source kernel/Kconfig.hz config KEXEC bool "kexec system call (EXPERIMENTAL)" - depends on EXPERIMENTAL + depends on EXPERIMENTAL && !X86_XEN help kexec is a system call that implements the ability to shutdown your current kernel, and to start another kernel. It is like a reboot @@ -765,20 +789,25 @@ config HOTPLUG_CPU endmenu +config ARCH_ENABLE_MEMORY_HOTPLUG + def_bool y + depends on HIGHMEM menu "Power management options (ACPI, APM)" - depends on !X86_VOYAGER + depends on !(X86_VOYAGER || XEN_UNPRIVILEGED_GUEST) +if !X86_XEN source kernel/power/Kconfig +endif source "drivers/acpi/Kconfig" menu "APM (Advanced Power Management) BIOS Support" -depends on PM && !X86_VISWS +depends on PM && !(X86_VISWS || X86_XEN) config APM tristate "APM (Advanced Power Management) BIOS support" - depends on PM + depends on PM && PM_LEGACY ---help--- APM is a BIOS specification for saving power using several different techniques. This is mostly useful for battery powered laptops with @@ -963,6 +992,7 @@ choice config PCI_GOBIOS bool "BIOS" + depends on !X86_XEN config PCI_GOMMCONFIG bool "MMConfig" @@ -970,6 +1000,13 @@ config PCI_GOMMCONFIG config PCI_GODIRECT bool "Direct" +config PCI_GOXEN_FE + bool "Xen PCI Frontend" + depends on X86_XEN + help + The PCI device frontend driver allows the kernel to import arbitrary + PCI devices from a PCI backend to support PCI driver domains. + config PCI_GOANY bool "Any" @@ -977,7 +1014,7 @@ endchoice config PCI_BIOS bool - depends on !X86_VISWS && PCI && (PCI_GOBIOS || PCI_GOANY) + depends on !(X86_VISWS || X86_XEN) && PCI && (PCI_GOBIOS || PCI_GOANY) default y config PCI_DIRECT @@ -990,6 +1027,18 @@ config PCI_MMCONFIG depends on PCI && ACPI && (PCI_GOMMCONFIG || PCI_GOANY) default y +config XEN_PCIDEV_FRONTEND + bool + depends on PCI && X86_XEN && (PCI_GOXEN_FE || PCI_GOANY) + default y + +config XEN_PCIDEV_FE_DEBUG + bool "Xen PCI Frontend Debugging" + depends on XEN_PCIDEV_FRONTEND + default n + help + Enables some debug statements within the PCI Frontend. + source "drivers/pci/pcie/Kconfig" source "drivers/pci/Kconfig" @@ -1000,7 +1049,7 @@ config ISA_DMA_API config ISA bool "ISA support" - depends on !(X86_VOYAGER || X86_VISWS) + depends on !(X86_VOYAGER || X86_VISWS || X86_XEN) help Find out whether you have ISA slots on your motherboard. ISA is the name of a bus system, i.e. the way the CPU talks to the other stuff @@ -1027,7 +1076,7 @@ config EISA source "drivers/eisa/Kconfig" config MCA - bool "MCA support" if !(X86_VISWS || X86_VOYAGER) + bool "MCA support" if !(X86_VISWS || X86_VOYAGER || X86_XEN) default y if X86_VOYAGER help MicroChannel Architecture is found in some IBM PS/2 machines and @@ -1091,6 +1140,8 @@ source "security/Kconfig" source "crypto/Kconfig" +source "drivers/xen/Kconfig" + source "lib/Kconfig" # @@ -1116,7 +1167,7 @@ config X86_SMP config X86_HT bool - depends on SMP && !(X86_VISWS || X86_VOYAGER) + depends on SMP && !(X86_VISWS || X86_VOYAGER || X86_XEN) default y config X86_BIOS_REBOOT @@ -1129,6 +1180,16 @@ config X86_TRAMPOLINE depends on X86_SMP || (X86_VOYAGER && SMP) default y +config X86_NO_TSS + bool + depends on X86_XEN + default y + +config X86_NO_IDT + bool + depends on X86_XEN + default y + config KTIME_SCALAR bool default y diff --git a/arch/i386/Kconfig.cpu b/arch/i386/Kconfig.cpu index eb130482b..f90d8d0df 100644 --- a/arch/i386/Kconfig.cpu +++ b/arch/i386/Kconfig.cpu @@ -251,7 +251,7 @@ config X86_PPRO_FENCE config X86_F00F_BUG bool - depends on M586MMX || M586TSC || M586 || M486 || M386 + depends on (M586MMX || M586TSC || M586 || M486 || M386) && !X86_NO_IDT default y config X86_WP_WORKS_OK diff --git a/arch/i386/Kconfig.debug b/arch/i386/Kconfig.debug index c92191b1f..fb28fe741 100644 --- a/arch/i386/Kconfig.debug +++ b/arch/i386/Kconfig.debug @@ -84,6 +84,7 @@ config X86_MPPARSE config DOUBLEFAULT default y bool "Enable doublefault exception handler" if EMBEDDED + depends on !X86_NO_TSS help This option allows trapping of rare doublefault exceptions that would otherwise cause a system to silently reboot. Disabling this diff --git a/arch/i386/Makefile b/arch/i386/Makefile index 94e0fafb4..53b7343aa 100644 --- a/arch/i386/Makefile +++ b/arch/i386/Makefile @@ -48,6 +48,11 @@ CFLAGS += $(shell if [ $(call cc-version) -lt 0400 ] ; then echo $(call cc-op CFLAGS += $(cflags-y) +cppflags-$(CONFIG_XEN) += \ + -D__XEN_INTERFACE_VERSION__=$(CONFIG_XEN_INTERFACE_VERSION) + +CPPFLAGS += $(cppflags-y) + # Default subarch .c files mcore-y := mach-default @@ -71,6 +76,10 @@ mcore-$(CONFIG_X86_BIGSMP) := mach-default mflags-$(CONFIG_X86_SUMMIT) := -Iinclude/asm-i386/mach-summit mcore-$(CONFIG_X86_SUMMIT) := mach-default +# Xen subarch support +mflags-$(CONFIG_X86_XEN) := -Iinclude/asm-i386/mach-xen +mcore-$(CONFIG_X86_XEN) := mach-xen + # generic subarchitecture mflags-$(CONFIG_X86_GENERICARCH) := -Iinclude/asm-i386/mach-generic mcore-$(CONFIG_X86_GENERICARCH) := mach-default @@ -105,6 +114,19 @@ boot := arch/i386/boot PHONY += zImage bzImage compressed zlilo bzlilo \ zdisk bzdisk fdimage fdimage144 fdimage288 isoimage install +ifdef CONFIG_XEN +CPPFLAGS := -Iinclude$(if $(KBUILD_SRC),2)/asm/mach-xen $(CPPFLAGS) +head-y := arch/i386/kernel/head-xen.o arch/i386/kernel/init_task-xen.o +boot := arch/i386/boot-xen +.PHONY: vmlinuz +all: vmlinuz + +vmlinuz: vmlinux + $(Q)$(MAKE) $(build)=$(boot) $@ + +install: + $(Q)$(MAKE) $(build)=$(boot) XENGUEST=$(XENGUEST) $@ +else all: bzImage # KBUILD_IMAGE specify target image being built @@ -127,6 +149,7 @@ fdimage fdimage144 fdimage288 isoimage: vmlinux install: $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) install +endif archclean: $(Q)$(MAKE) $(clean)=arch/i386/boot @@ -145,3 +168,4 @@ endef CLEAN_FILES += arch/$(ARCH)/boot/fdimage \ arch/$(ARCH)/boot/image.iso \ arch/$(ARCH)/boot/mtools.conf +CLEAN_FILES += vmlinuz vmlinux-stripped diff --git a/arch/i386/kernel/Makefile b/arch/i386/kernel/Makefile index 96fb8a020..ddaa19d89 100644 --- a/arch/i386/kernel/Makefile +++ b/arch/i386/kernel/Makefile @@ -42,6 +42,12 @@ EXTRA_AFLAGS := -traditional obj-$(CONFIG_SCx200) += scx200.o +ifdef CONFIG_XEN +vsyscall_note := vsyscall-note-xen.o +else +vsyscall_note := vsyscall-note.o +endif + # vsyscall.o contains the vsyscall DSO images as __initdata. # We must build both images before we can assemble it. # Note: kbuild does not track this dependency due to usage of .incbin @@ -62,7 +68,7 @@ SYSCFLAGS_vsyscall-int80.so = $(vsyscall-flags) $(obj)/vsyscall-int80.so $(obj)/vsyscall-sysenter.so: \ $(obj)/vsyscall-%.so: $(src)/vsyscall.lds \ - $(obj)/vsyscall-%.o $(obj)/vsyscall-note.o FORCE + $(obj)/vsyscall-%.o $(obj)/$(vsyscall_note) FORCE $(call if_changed,syscall) # We also create a special relocatable object that should mirror the symbol @@ -74,5 +80,17 @@ $(obj)/built-in.o: ld_flags += -R $(obj)/vsyscall-syms.o SYSCFLAGS_vsyscall-syms.o = -r $(obj)/vsyscall-syms.o: $(src)/vsyscall.lds \ - $(obj)/vsyscall-sysenter.o $(obj)/vsyscall-note.o FORCE + $(obj)/vsyscall-sysenter.o $(obj)/$(vsyscall_note) FORCE $(call if_changed,syscall) + +ifdef CONFIG_XEN +include $(srctree)/scripts/Makefile.xen + +obj-y += fixup.o +microcode-$(subst m,y,$(CONFIG_MICROCODE)) := microcode-xen.o +n-obj-xen := i8259.o timers/ reboot.o smpboot.o trampoline.o + +obj-y := $(call filterxen, $(obj-y), $(n-obj-xen)) +obj-y := $(call cherrypickxen, $(obj-y)) +extra-y := $(call cherrypickxen, $(extra-y)) +endif diff --git a/arch/i386/kernel/acpi/Makefile b/arch/i386/kernel/acpi/Makefile index 7e9ac9935..fa783e6f9 100644 --- a/arch/i386/kernel/acpi/Makefile +++ b/arch/i386/kernel/acpi/Makefile @@ -6,3 +6,7 @@ ifneq ($(CONFIG_ACPI_PROCESSOR),) obj-y += cstate.o processor.o endif +ifdef CONFIG_XEN +include $(srctree)/scripts/Makefile.xen +obj-y := $(call cherrypickxen, $(obj-y), $(src)) +endif diff --git a/arch/i386/kernel/asm-offsets.c b/arch/i386/kernel/asm-offsets.c index ac3f4e5ec..c6b52aa8d 100644 --- a/arch/i386/kernel/asm-offsets.c +++ b/arch/i386/kernel/asm-offsets.c @@ -13,6 +13,7 @@ #include #include #include +#include #define DEFINE(sym, val) \ asm volatile("\n->" #sym " %0 " #val : : "i" (val)) @@ -64,10 +65,14 @@ void foo(void) OFFSET(pbe_orig_address, pbe, orig_address); OFFSET(pbe_next, pbe, next); +#ifndef CONFIG_X86_NO_TSS /* Offset from the sysenter stack to tss.esp0 */ - DEFINE(TSS_sysenter_esp0, offsetof(struct tss_struct, esp0) - + DEFINE(SYSENTER_stack_esp0, offsetof(struct tss_struct, esp0) - sizeof(struct tss_struct)); +#else + /* sysenter stack points directly to esp0 */ + DEFINE(SYSENTER_stack_esp0, 0); +#endif DEFINE(PAGE_SIZE_asm, PAGE_SIZE); - DEFINE(VSYSCALL_BASE, __fix_to_virt(FIX_VSYSCALL)); } diff --git a/arch/i386/kernel/cpu/Makefile b/arch/i386/kernel/cpu/Makefile index 010aecfff..753f1d770 100644 --- a/arch/i386/kernel/cpu/Makefile +++ b/arch/i386/kernel/cpu/Makefile @@ -17,3 +17,8 @@ obj-$(CONFIG_X86_MCE) += mcheck/ obj-$(CONFIG_MTRR) += mtrr/ obj-$(CONFIG_CPU_FREQ) += cpufreq/ + +ifdef CONFIG_XEN +include $(srctree)/scripts/Makefile.xen +obj-y := $(call cherrypickxen, $(obj-y), $(src)) +endif diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k7.c b/arch/i386/kernel/cpu/cpufreq/powernow-k7.c index da2db31d4..a748409b7 100644 --- a/arch/i386/kernel/cpu/cpufreq/powernow-k7.c +++ b/arch/i386/kernel/cpu/cpufreq/powernow-k7.c @@ -581,7 +581,6 @@ static int __init powernow_cpu_init (struct cpufreq_policy *policy) rdmsrl (MSR_K7_FID_VID_STATUS, fidvidstatus.val); - /* recalibrate cpu_khz */ recalibrate_cpu_khz(); fsb = (10 * cpu_khz) / fid_codes[fidvidstatus.bits.CFID]; diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c index 71fffa174..2ea3c6cac 100644 --- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c +++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c @@ -1008,7 +1008,7 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) * an UP version, and is deprecated by AMD. */ - if ((num_online_cpus() != 1) || (num_possible_cpus() != 1)) { + if (num_online_cpus() != 1) { printk(KERN_ERR PFX "MP systems not supported by PSB BIOS structure\n"); kfree(data); return -ENODEV; diff --git a/arch/i386/kernel/cpu/mtrr/Makefile b/arch/i386/kernel/cpu/mtrr/Makefile index a25b701ab..06df4feee 100644 --- a/arch/i386/kernel/cpu/mtrr/Makefile +++ b/arch/i386/kernel/cpu/mtrr/Makefile @@ -3,3 +3,10 @@ obj-y += amd.o obj-y += cyrix.o obj-y += centaur.o +ifdef CONFIG_XEN +include $(srctree)/scripts/Makefile.xen +n-obj-xen := generic.o state.o amd.o cyrix.o centaur.o + +obj-y := $(call filterxen, $(obj-y), $(n-obj-xen)) +obj-y := $(call cherrypickxen, $(obj-y)) +endif diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S index 840d990b8..eed41e6dd 100644 --- a/arch/i386/kernel/entry.S +++ b/arch/i386/kernel/entry.S @@ -177,7 +177,7 @@ need_resched: # sysenter call handler stub ENTRY(sysenter_entry) - movl TSS_sysenter_esp0(%esp),%esp + movl SYSENTER_stack_esp0(%esp),%esp sysenter_past_esp: sti pushl $(__USER_DS) @@ -414,7 +414,7 @@ vector=0 ENTRY(irq_entries_start) .rept NR_IRQS ALIGN -1: pushl $vector-256 +1: pushl $~(vector) jmp common_interrupt .data .long 1b @@ -431,7 +431,7 @@ common_interrupt: #define BUILD_INTERRUPT(name, nr) \ ENTRY(name) \ - pushl $nr-256; \ + pushl $~(nr); \ SAVE_ALL \ movl %esp,%eax; \ call smp_/**/name; \ @@ -500,7 +500,7 @@ device_not_available_emulate: * that sets up the real kernel stack. Check here, since we can't * allow the wrong stack to be used. * - * "TSS_sysenter_esp0+12" is because the NMI/debug handler will have + * "SYSENTER_stack_esp0+12" is because the NMI/debug handler will have * already pushed 3 words if it hits on the sysenter instruction: * eflags, cs and eip. * @@ -512,7 +512,7 @@ device_not_available_emulate: cmpw $__KERNEL_CS,4(%esp); \ jne ok; \ label: \ - movl TSS_sysenter_esp0+offset(%esp),%esp; \ + movl SYSENTER_stack_esp0+offset(%esp),%esp; \ pushfl; \ pushl $__KERNEL_CS; \ pushl $sysenter_past_esp diff --git a/arch/i386/kernel/irq.c b/arch/i386/kernel/irq.c index f3a9c78c4..2904a6686 100644 --- a/arch/i386/kernel/irq.c +++ b/arch/i386/kernel/irq.c @@ -53,8 +53,8 @@ static union irq_ctx *softirq_ctx[NR_CPUS]; */ fastcall unsigned int do_IRQ(struct pt_regs *regs) { - /* high bits used in ret_from_ code */ - int irq = regs->orig_eax & 0xff; + /* high bit used in ret_from_ code */ + int irq = ~regs->orig_eax; #ifdef CONFIG_4KSTACKS union irq_ctx *curctx, *irqctx; u32 *isp; diff --git a/arch/i386/kernel/reboot.c b/arch/i386/kernel/reboot.c index 4163865dd..d20724297 100644 --- a/arch/i386/kernel/reboot.c +++ b/arch/i386/kernel/reboot.c @@ -120,14 +120,6 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq"), }, }, - { /* HP laptops have weird reboot issues */ - .callback = set_bios_reboot, - .ident = "HP Laptop", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), - DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq"), - }, - }, { } }; diff --git a/arch/i386/kernel/sysenter.c b/arch/i386/kernel/sysenter.c index ec4959f74..b97719aa4 100644 --- a/arch/i386/kernel/sysenter.c +++ b/arch/i386/kernel/sysenter.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -21,10 +22,15 @@ #include #include +#ifdef CONFIG_XEN +#include +#endif + extern asmlinkage void sysenter_entry(void); void enable_sep_cpu(void) { +#ifndef CONFIG_X86_NO_TSS int cpu = get_cpu(); struct tss_struct *tss = &per_cpu(init_tss, cpu); @@ -39,6 +45,7 @@ void enable_sep_cpu(void) wrmsr(MSR_IA32_SYSENTER_ESP, tss->esp1, 0); wrmsr(MSR_IA32_SYSENTER_EIP, (unsigned long) sysenter_entry, 0); put_cpu(); +#endif } /* @@ -47,7 +54,6 @@ void enable_sep_cpu(void) */ extern const char vsyscall_int80_start, vsyscall_int80_end; extern const char vsyscall_sysenter_start, vsyscall_sysenter_end; - static struct page *sysenter_pages[2]; int __init sysenter_setup(void) @@ -56,16 +62,28 @@ int __init sysenter_setup(void) sysenter_pages[0] = virt_to_page(page); - if (!boot_cpu_has(X86_FEATURE_SEP)) { +#ifdef CONFIG_XEN + if (boot_cpu_has(X86_FEATURE_SEP)) { + struct callback_register sysenter = { + .type = CALLBACKTYPE_sysenter, + .address = { __KERNEL_CS, (unsigned long)sysenter_entry }, + }; + + if (HYPERVISOR_callback_op(CALLBACKOP_register, &sysenter) < 0) + clear_bit(X86_FEATURE_SEP, boot_cpu_data.x86_capability); + } +#endif + + if (boot_cpu_has(X86_FEATURE_SEP)) { memcpy(page, - &vsyscall_int80_start, - &vsyscall_int80_end - &vsyscall_int80_start); + &vsyscall_sysenter_start, + &vsyscall_sysenter_end - &vsyscall_sysenter_start); return 0; } memcpy(page, - &vsyscall_sysenter_start, - &vsyscall_sysenter_end - &vsyscall_sysenter_start); + &vsyscall_int80_start, + &vsyscall_int80_end - &vsyscall_int80_start); return 0; } @@ -130,6 +148,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, return err; } +#ifndef CONFIG_XEN int in_gate_area_no_task(unsigned long addr) { return 0; @@ -144,3 +163,4 @@ struct vm_area_struct *get_gate_vma(struct task_struct *tsk) { return NULL; } +#endif diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index 0b9d741f8..5b65cb842 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c @@ -705,18 +705,11 @@ static void mem_parity_error(unsigned char reason, struct pt_regs * regs) static void io_check_error(unsigned char reason, struct pt_regs * regs) { - unsigned long i; - printk(KERN_EMERG "NMI: IOCK error (debug interrupt?)\n"); show_registers(regs); /* Re-enable the IOCK line, wait for a few seconds */ - reason = (reason & 0xf) | 8; - outb(reason, 0x61); - i = 2000; - while (--i) udelay(1000); - reason &= ~8; - outb(reason, 0x61); + clear_io_check_error(reason); } static void unknown_nmi_error(unsigned char reason, struct pt_regs * regs) diff --git a/arch/i386/kernel/vm86.c b/arch/i386/kernel/vm86.c index 00e0118e7..c0adee5da 100644 --- a/arch/i386/kernel/vm86.c +++ b/arch/i386/kernel/vm86.c @@ -98,7 +98,9 @@ struct pt_regs * FASTCALL(save_v86_state(struct kernel_vm86_regs * regs)); struct pt_regs * fastcall save_v86_state(struct kernel_vm86_regs * regs) { +#ifndef CONFIG_X86_NO_TSS struct tss_struct *tss; +#endif struct pt_regs *ret; unsigned long tmp; @@ -123,12 +125,16 @@ struct pt_regs * fastcall save_v86_state(struct kernel_vm86_regs * regs) do_exit(SIGSEGV); } +#ifndef CONFIG_X86_NO_TSS tss = &per_cpu(init_tss, get_cpu()); +#endif current->thread.esp0 = current->thread.saved_esp0; current->thread.sysenter_cs = __KERNEL_CS; load_esp0(tss, ¤t->thread); current->thread.saved_esp0 = 0; +#ifndef CONFIG_X86_NO_TSS put_cpu(); +#endif loadsegment(fs, current->thread.saved_fs); loadsegment(gs, current->thread.saved_gs); @@ -252,7 +258,9 @@ out: static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk) { +#ifndef CONFIG_X86_NO_TSS struct tss_struct *tss; +#endif long eax; /* * make sure the vm86() system call doesn't try to do anything silly @@ -297,12 +305,16 @@ static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk savesegment(fs, tsk->thread.saved_fs); savesegment(gs, tsk->thread.saved_gs); +#ifndef CONFIG_X86_NO_TSS tss = &per_cpu(init_tss, get_cpu()); +#endif tsk->thread.esp0 = (unsigned long) &info->VM86_TSS_ESP0; if (cpu_has_sep) tsk->thread.sysenter_cs = 0; load_esp0(tss, &tsk->thread); +#ifndef CONFIG_X86_NO_TSS put_cpu(); +#endif tsk->thread.screen_bitmap = info->screen_bitmap; if (info->flags & VM86_SCREEN_BITMAP) diff --git a/arch/i386/mm/Makefile b/arch/i386/mm/Makefile index 80908b5aa..2b33b2003 100644 --- a/arch/i386/mm/Makefile +++ b/arch/i386/mm/Makefile @@ -8,3 +8,11 @@ obj-$(CONFIG_NUMA) += discontig.o obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o obj-$(CONFIG_HIGHMEM) += highmem.o obj-$(CONFIG_BOOT_IOREMAP) += boot_ioremap.o + +ifdef CONFIG_XEN +include $(srctree)/scripts/Makefile.xen + +obj-y += hypervisor.o + +obj-y := $(call cherrypickxen, $(obj-y)) +endif diff --git a/arch/i386/mm/pageattr.c b/arch/i386/mm/pageattr.c index 92c3d9f0e..a00267a5b 100644 --- a/arch/i386/mm/pageattr.c +++ b/arch/i386/mm/pageattr.c @@ -85,7 +85,7 @@ static void set_pmd_pte(pte_t *kpte, unsigned long address, pte_t pte) unsigned long flags; set_pte_atomic(kpte, pte); /* change init_mm */ - if (PTRS_PER_PMD > 1) + if (HAVE_SHARED_KERNEL_PMD) return; spin_lock_irqsave(&pgd_lock, flags); diff --git a/arch/i386/mm/pgtable.c b/arch/i386/mm/pgtable.c index 2889567e2..de8d18774 100644 --- a/arch/i386/mm/pgtable.c +++ b/arch/i386/mm/pgtable.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -138,6 +139,10 @@ void set_pmd_pfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags) __flush_tlb_one(vaddr); } +static int nr_fixmaps = 0; +unsigned long __FIXADDR_TOP = 0xfffff000; +EXPORT_SYMBOL(__FIXADDR_TOP); + void __set_fixmap (enum fixed_addresses idx, unsigned long phys, pgprot_t flags) { unsigned long address = __fix_to_virt(idx); @@ -147,6 +152,13 @@ void __set_fixmap (enum fixed_addresses idx, unsigned long phys, pgprot_t flags) return; } set_pte_pfn(address, phys >> PAGE_SHIFT, flags); + nr_fixmaps++; +} + +void set_fixaddr_top(unsigned long top) +{ + BUG_ON(nr_fixmaps > 0); + __FIXADDR_TOP = top - PAGE_SIZE; } pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) diff --git a/arch/i386/oprofile/Makefile b/arch/i386/oprofile/Makefile index 30f3eb366..e596c39c0 100644 --- a/arch/i386/oprofile/Makefile +++ b/arch/i386/oprofile/Makefile @@ -6,7 +6,11 @@ DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \ oprofilefs.o oprofile_stats.o \ timer_int.o ) +ifdef CONFIG_XEN +oprofile-y := $(DRIVER_OBJS) xenoprof.o +else oprofile-y := $(DRIVER_OBJS) init.o backtrace.o oprofile-$(CONFIG_X86_LOCAL_APIC) += nmi_int.o op_model_athlon.o \ op_model_ppro.o op_model_p4.o oprofile-$(CONFIG_X86_IO_APIC) += nmi_timer_int.o +endif diff --git a/arch/i386/pci/Makefile b/arch/i386/pci/Makefile index 62ad75c57..4447f397f 100644 --- a/arch/i386/pci/Makefile +++ b/arch/i386/pci/Makefile @@ -4,6 +4,10 @@ obj-$(CONFIG_PCI_BIOS) += pcbios.o obj-$(CONFIG_PCI_MMCONFIG) += mmconfig.o direct.o obj-$(CONFIG_PCI_DIRECT) += direct.o +# pcifront should be after pcbios.o, mmconfig.o, and direct.o as it should only +# take over if direct access to the PCI bus is unavailable +obj-$(CONFIG_XEN_PCIDEV_FRONTEND) += pcifront.o + pci-y := fixup.o pci-$(CONFIG_ACPI) += acpi.o pci-y += legacy.o irq.o @@ -12,3 +16,8 @@ pci-$(CONFIG_X86_VISWS) := visws.o fixup.o pci-$(CONFIG_X86_NUMAQ) := numa.o irq.o obj-y += $(pci-y) common.o + +ifdef CONFIG_XEN +include $(srctree)/scripts/Makefile.xen +obj-y := $(call cherrypickxen, $(obj-y)) +endif diff --git a/arch/i386/pci/mmconfig.c b/arch/i386/pci/mmconfig.c index 6b1ea0c9a..e545b0992 100644 --- a/arch/i386/pci/mmconfig.c +++ b/arch/i386/pci/mmconfig.c @@ -15,7 +15,9 @@ #include #include "pci.h" -#define MMCONFIG_APER_SIZE (256*1024*1024) +/* aperture is up to 256MB but BIOS may reserve less */ +#define MMCONFIG_APER_MIN (2 * 1024*1024) +#define MMCONFIG_APER_MAX (256 * 1024*1024) /* Assume systems with more busses have correct MCFG */ #define MAX_CHECK_BUS 16 @@ -197,9 +199,10 @@ void __init pci_mmcfg_init(void) return; if (!e820_all_mapped(pci_mmcfg_config[0].base_address, - pci_mmcfg_config[0].base_address + MMCONFIG_APER_SIZE, + pci_mmcfg_config[0].base_address + MMCONFIG_APER_MIN, E820_RESERVED)) { - printk(KERN_ERR "PCI: BIOS Bug: MCFG area is not E820-reserved\n"); + 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; } diff --git a/arch/i386/power/Makefile b/arch/i386/power/Makefile index 8cfa4e8a7..e74fee667 100644 --- a/arch/i386/power/Makefile +++ b/arch/i386/power/Makefile @@ -1,2 +1,4 @@ -obj-$(CONFIG_PM) += cpu.o +obj-$(CONFIG_PM_LEGACY) += cpu.o +obj-$(CONFIG_SOFTWARE_SUSPEND) += cpu.o +obj-$(CONFIG_ACPI_SLEEP) += cpu.o obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index 67a905304..1e3ad1ecc 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig @@ -270,6 +270,9 @@ config HOTPLUG_CPU can be controlled through /sys/devices/system/cpu/cpu#. Say N if you want to disable CPU hotplug. +config ARCH_ENABLE_MEMORY_HOTPLUG + def_bool y + config SCHED_SMT bool "SMT scheduler support" depends on SMP diff --git a/arch/ia64/kernel/sys_ia64.c b/arch/ia64/kernel/sys_ia64.c index c7b943f10..3edefc8f6 100644 --- a/arch/ia64/kernel/sys_ia64.c +++ b/arch/ia64/kernel/sys_ia64.c @@ -164,10 +164,25 @@ sys_pipe (void) return retval; } +int ia64_map_check_rgn(unsigned long addr, unsigned long len, + unsigned long flags) +{ + unsigned long roff; + + /* + * Don't permit mappings into unmapped space, the virtual page table + * of a region, or across a region boundary. Note: RGN_MAP_LIMIT is + * equal to 2^n-PAGE_SIZE (for some integer n <= 61) and len > 0. + */ + roff = REGION_OFFSET(addr); + if ((len > RGN_MAP_LIMIT) || (roff > (RGN_MAP_LIMIT - len))) + return -EINVAL; + return 0; +} + static inline unsigned long do_mmap2 (unsigned long addr, unsigned long len, int prot, int flags, int fd, unsigned long pgoff) { - unsigned long roff; struct file *file = NULL; flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); @@ -189,17 +204,6 @@ do_mmap2 (unsigned long addr, unsigned long len, int prot, int flags, int fd, un goto out; } - /* - * Don't permit mappings into unmapped space, the virtual page table of a region, - * or across a region boundary. Note: RGN_MAP_LIMIT is equal to 2^n-PAGE_SIZE - * (for some integer n <= 61) and len > 0. - */ - roff = REGION_OFFSET(addr); - if ((len > RGN_MAP_LIMIT) || (roff > (RGN_MAP_LIMIT - len))) { - addr = -EINVAL; - goto out; - } - down_write(¤t->mm->mmap_sem); addr = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); up_write(¤t->mm->mmap_sem); diff --git a/arch/ia64/sn/kernel/xpc_channel.c b/arch/ia64/sn/kernel/xpc_channel.c index 8255a9be4..7e8a4d1d9 100644 --- a/arch/ia64/sn/kernel/xpc_channel.c +++ b/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) ia64_tpa((u64) dst), - (u64) cnt, (BTE_NORMAL | BTE_WACQUIRE), NULL); + bte_ret = xp_bte_copy((u64) src, (u64) dst, (u64) cnt, + (BTE_NORMAL | BTE_WACQUIRE), NULL); if (bte_ret == BTE_SUCCESS) { return xpcSuccess; } diff --git a/arch/ia64/sn/kernel/xpc_main.c b/arch/ia64/sn/kernel/xpc_main.c index 1def91fc8..6b5d4c44f 100644 --- a/arch/ia64/sn/kernel/xpc_main.c +++ b/arch/ia64/sn/kernel/xpc_main.c @@ -1055,6 +1055,8 @@ xpc_do_exit(enum xpc_retval reason) if (xpc_sysctl) { unregister_sysctl_table(xpc_sysctl); } + + kfree(xpc_remote_copy_buffer_base); } @@ -1215,24 +1217,20 @@ xpc_init(void) partid_t partid; struct xpc_partition *part; pid_t pid; + size_t buf_size; if (!ia64_platform_is("sn2")) { return -ENODEV; } - /* - * 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)); + + 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; snprintf(xpc_part->bus_id, BUS_ID_SIZE, "part"); snprintf(xpc_chan->bus_id, BUS_ID_SIZE, "chan"); @@ -1296,6 +1294,8 @@ xpc_init(void) if (xpc_sysctl) { unregister_sysctl_table(xpc_sysctl); } + + kfree(xpc_remote_copy_buffer_base); return -EBUSY; } @@ -1314,6 +1314,8 @@ xpc_init(void) if (xpc_sysctl) { unregister_sysctl_table(xpc_sysctl); } + + kfree(xpc_remote_copy_buffer_base); return -EBUSY; } @@ -1365,6 +1367,8 @@ xpc_init(void) if (xpc_sysctl) { unregister_sysctl_table(xpc_sysctl); } + + kfree(xpc_remote_copy_buffer_base); return -EBUSY; } diff --git a/arch/ia64/sn/kernel/xpc_partition.c b/arch/ia64/sn/kernel/xpc_partition.c index 2a89cfce4..57c723f5c 100644 --- a/arch/ia64/sn/kernel/xpc_partition.c +++ b/arch/ia64/sn/kernel/xpc_partition.c @@ -71,19 +71,15 @@ 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 ____cacheline_aligned xpc_remote_copy_buffer[XPC_RP_HEADER_SIZE + - XP_NASID_MASK_BYTES]; +char *xpc_remote_copy_buffer; +void *xpc_remote_copy_buffer_base; /* * Guarantee that the kmalloc'd memory is cacheline aligned. */ -static void * +void * xpc_kmalloc_cacheline_aligned(size_t size, gfp_t flags, void **base) { /* see if kmalloc will give us cachline aligned memory by default */ @@ -148,7 +144,7 @@ xpc_get_rsvd_page_pa(int nasid) } } - bte_res = xp_bte_copy(rp_pa, ia64_tpa(buf), buf_len, + bte_res = xp_bte_copy(rp_pa, 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); @@ -447,7 +443,7 @@ xpc_check_remote_hb(void) /* pull the remote_hb cache line */ bres = xp_bte_copy(part->remote_vars_pa, - ia64_tpa((u64) remote_vars), + (u64) remote_vars, XPC_RP_VARS_SIZE, (BTE_NOTIFY | BTE_WACQUIRE), NULL); if (bres != BTE_SUCCESS) { @@ -498,8 +494,7 @@ 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, ia64_tpa((u64) remote_rp), + bres = xp_bte_copy(*remote_rp_pa, (u64) remote_rp, XPC_RP_HEADER_SIZE + xp_nasid_mask_bytes, (BTE_NOTIFY | BTE_WACQUIRE), NULL); if (bres != BTE_SUCCESS) { @@ -554,11 +549,8 @@ 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, ia64_tpa((u64) remote_vars), - XPC_RP_VARS_SIZE, + bres = xp_bte_copy(remote_vars_pa, (u64) remote_vars, XPC_RP_VARS_SIZE, (BTE_NOTIFY | BTE_WACQUIRE), NULL); if (bres != BTE_SUCCESS) { return xpc_map_bte_errors(bres); @@ -1239,7 +1231,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, ia64_tpa((u64) nasid_mask), + bte_res = xp_bte_copy(part_nasid_pa, (u64) nasid_mask, xp_nasid_mask_bytes, (BTE_NOTIFY | BTE_WACQUIRE), NULL); return xpc_map_bte_errors(bte_res); diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 747025987..f35dd7b70 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -620,6 +620,9 @@ config HOTPLUG_CPU Say N if you are unsure. +config ARCH_ENABLE_MEMORY_HOTPLUG + def_bool y + config KEXEC bool "kexec system call (EXPERIMENTAL)" depends on PPC_MULTIPLATFORM && EXPERIMENTAL diff --git a/arch/powerpc/kernel/cpu_setup_power4.S b/arch/powerpc/kernel/cpu_setup_power4.S index b61d86e7c..55f367edd 100644 --- a/arch/powerpc/kernel/cpu_setup_power4.S +++ b/arch/powerpc/kernel/cpu_setup_power4.S @@ -94,6 +94,8 @@ _GLOBAL(__setup_cpu_ppc970) mfspr r0,SPRN_HID0 li r11,5 /* clear DOZE and SLEEP */ rldimi r0,r11,52,8 /* set NAP and DPM */ + li r11,0 + rldimi r0,r11,32,31 /* clear EN_ATTN */ mtspr SPRN_HID0,r0 mfspr r0,SPRN_HID0 mfspr r0,SPRN_HID0 diff --git a/arch/powerpc/kernel/crash.c b/arch/powerpc/kernel/crash.c index 778f22fd8..dbcb85994 100644 --- a/arch/powerpc/kernel/crash.c +++ b/arch/powerpc/kernel/crash.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -174,6 +175,8 @@ static void crash_kexec_prepare_cpus(void) void default_machine_crash_shutdown(struct pt_regs *regs) { + unsigned int irq; + /* * This function is only called after the system * has paniced or is otherwise in a critical state. @@ -186,6 +189,16 @@ void default_machine_crash_shutdown(struct pt_regs *regs) */ local_irq_disable(); + for_each_irq(irq) { + struct irq_desc *desc = irq_descp(irq); + + if (desc->status & IRQ_INPROGRESS) + desc->handler->end(irq); + + if (!(desc->status & IRQ_DISABLED)) + desc->handler->disable(irq); + } + if (ppc_md.kexec_cpu_down) ppc_md.kexec_cpu_down(1, 0); diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c index 2d60ea30f..9ff7105bc 100644 --- a/arch/powerpc/platforms/pseries/xics.c +++ b/arch/powerpc/platforms/pseries/xics.c @@ -641,23 +641,28 @@ void xics_teardown_cpu(int secondary) ops->cppr_info(cpu, 0x00); iosync(); + /* + * Clear IPI + */ + ops->qirr_info(cpu, 0xff); + /* + * we need to EOI the IPI if we got here from kexec down IPI + * + * probably need to check all the other interrupts too + * should we be flagging idle loop instead? + * or creating some task to be scheduled? + */ + ops->xirr_info_set(cpu, XICS_IPI); + /* * Some machines need to have at least one cpu in the GIQ, * so leave the master cpu in the group. */ - if (secondary) { - /* - * we need to EOI the IPI if we got here from kexec down IPI - * - * probably need to check all the other interrupts too - * should we be flagging idle loop instead? - * or creating some task to be scheduled? - */ - ops->xirr_info_set(cpu, XICS_IPI); + if (secondary) rtas_set_indicator(GLOBAL_INTERRUPT_QUEUE, (1UL << interrupt_server_size) - 1 - default_distrib_server, 0); - } + } #ifdef CONFIG_HOTPLUG_CPU diff --git a/arch/sparc/kernel/sys_sparc.c b/arch/sparc/kernel/sys_sparc.c index 8fa541cc2..5a220d61b 100644 --- a/arch/sparc/kernel/sys_sparc.c +++ b/arch/sparc/kernel/sys_sparc.c @@ -220,6 +220,21 @@ out: return err; } +int sparc_mmap_check(unsigned long addr, unsigned long len, unsigned long flags) +{ + if (ARCH_SUN4C_SUN4 && + (len > 0x20000000 || + ((flags & MAP_FIXED) && + addr < 0xe0000000 && addr + len > 0x20000000))) + return -EINVAL; + + /* See asm-sparc/uaccess.h */ + if (len > TASK_SIZE - PAGE_SIZE || addr + len > TASK_SIZE - PAGE_SIZE) + return -EINVAL; + + return 0; +} + /* Linux version of mmap */ static unsigned long do_mmap2(unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags, unsigned long fd, @@ -234,25 +249,13 @@ static unsigned long do_mmap2(unsigned long addr, unsigned long len, goto out; } - retval = -EINVAL; len = PAGE_ALIGN(len); - if (ARCH_SUN4C_SUN4 && - (len > 0x20000000 || - ((flags & MAP_FIXED) && - addr < 0xe0000000 && addr + len > 0x20000000))) - goto out_putf; - - /* See asm-sparc/uaccess.h */ - if (len > TASK_SIZE - PAGE_SIZE || addr + len > TASK_SIZE - PAGE_SIZE) - goto out_putf; - flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); down_write(¤t->mm->mmap_sem); retval = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); up_write(¤t->mm->mmap_sem); -out_putf: if (file) fput(file); out: diff --git a/arch/sparc64/kernel/sys_sparc.c b/arch/sparc64/kernel/sys_sparc.c index 62d7497fb..ef419255c 100644 --- a/arch/sparc64/kernel/sys_sparc.c +++ b/arch/sparc64/kernel/sys_sparc.c @@ -550,6 +550,26 @@ asmlinkage long sparc64_personality(unsigned long personality) return ret; } +int sparc64_mmap_check(unsigned long addr, unsigned long len, + unsigned long flags) +{ + if (test_thread_flag(TIF_32BIT)) { + if (len >= STACK_TOP32) + return -EINVAL; + + if ((flags & MAP_FIXED) && addr > STACK_TOP32 - len) + return -EINVAL; + } else { + if (len >= VA_EXCLUDE_START) + return -EINVAL; + + if ((flags & MAP_FIXED) && invalid_64bit_range(addr, len)) + return -EINVAL; + } + + return 0; +} + /* Linux version of mmap */ asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags, unsigned long fd, @@ -565,27 +585,11 @@ asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len, } flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); len = PAGE_ALIGN(len); - retval = -EINVAL; - - if (test_thread_flag(TIF_32BIT)) { - if (len >= STACK_TOP32) - goto out_putf; - - if ((flags & MAP_FIXED) && addr > STACK_TOP32 - len) - goto out_putf; - } else { - if (len >= VA_EXCLUDE_START) - goto out_putf; - - if ((flags & MAP_FIXED) && invalid_64bit_range(addr, len)) - goto out_putf; - } down_write(¤t->mm->mmap_sem); retval = do_mmap(file, addr, len, prot, flags, off); up_write(¤t->mm->mmap_sem); -out_putf: if (file) fput(file); out: diff --git a/arch/sparc64/mm/generic.c b/arch/sparc64/mm/generic.c index 8cb06205d..af9d81db0 100644 --- a/arch/sparc64/mm/generic.c +++ b/arch/sparc64/mm/generic.c @@ -69,6 +69,8 @@ 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/arch/um/kernel/physmem.c b/arch/um/kernel/physmem.c index fc0f0b085..bd4627b4d 100644 --- a/arch/um/kernel/physmem.c +++ b/arch/um/kernel/physmem.c @@ -226,7 +226,7 @@ EXPORT_SYMBOL(physmem_forget_descriptor); EXPORT_SYMBOL(physmem_remove_mapping); EXPORT_SYMBOL(physmem_subst_mapping); -void arch_free_page(struct page *page, int order) +int arch_free_page(struct page *page, int order) { void *virt; int i; @@ -235,6 +235,8 @@ void arch_free_page(struct page *page, int order) virt = __va(page_to_phys(page + i)); physmem_remove_mapping(virt); } + + return 0; } int is_remapped(void *virt) diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig index b2cd1f245..0f4ed7159 100644 --- a/arch/x86_64/Kconfig +++ b/arch/x86_64/Kconfig @@ -123,6 +123,22 @@ config GENERIC_CPU endchoice +config X86_64_XEN + bool "Enable Xen compatible kernel" + select SWIOTLB + help + This option will compile a kernel compatible with Xen hypervisor + +config X86_NO_TSS + bool + depends on X86_64_XEN + default y + +config X86_NO_IDT + bool + depends on X86_64_XEN + default y + # # Define implied options from the CPU selection here # @@ -143,6 +159,7 @@ config X86_INTERNODE_CACHE_BYTES config X86_TSC bool + depends on !X86_64_XEN default y config X86_GOOD_APIC @@ -185,7 +202,7 @@ config X86_CPUID config X86_HT bool - depends on SMP && !MK8 + depends on SMP && !MK8 && !X86_64_XEN default y config MATH_EMULATION @@ -199,14 +216,22 @@ config EISA config X86_IO_APIC bool + depends !XEN_UNPRIVILEGED_GUEST default y +config X86_XEN_GENAPIC + bool + depends X86_64_XEN + default XEN_PRIVILEGED_GUEST || SMP + config X86_LOCAL_APIC bool + depends !XEN_UNPRIVILEGED_GUEST default y config MTRR bool "MTRR (Memory Type Range Register) support" + depends on !XEN_UNPRIVILEGED_GUEST ---help--- On Intel P6 family processors (Pentium Pro, Pentium II and later) the Memory Type Range Registers (MTRRs) may be used to control @@ -247,7 +272,7 @@ config SMP config SCHED_SMT bool "SMT (Hyperthreading) scheduler support" - depends on SMP + depends on SMP && !X86_64_XEN default n help SMT scheduler support improves the CPU scheduler's decision making @@ -257,7 +282,7 @@ config SCHED_SMT config SCHED_MC bool "Multi-core scheduler support" - depends on SMP + depends on SMP && !X86_64_XEN default y help Multi-core scheduler support improves the CPU scheduler's decision @@ -268,7 +293,7 @@ source "kernel/Kconfig.preempt" config NUMA bool "Non Uniform Memory Access (NUMA) Support" - depends on SMP + depends on SMP && !X86_64_XEN help Enable NUMA (Non Uniform Memory Access) support. The kernel will try to allocate memory used by a CPU on the local memory @@ -328,7 +353,7 @@ config ARCH_DISCONTIGMEM_DEFAULT config ARCH_SPARSEMEM_ENABLE def_bool y - depends on (NUMA || EXPERIMENTAL) + depends on (NUMA || EXPERIMENTAL) && !X86_64_XEN config ARCH_MEMORY_PROBE def_bool y @@ -352,6 +377,7 @@ config NR_CPUS int "Maximum number of CPUs (2-256)" range 2 255 depends on SMP + default "16" if X86_64_XEN default "8" help This allows you to specify the maximum number of CPUs which this @@ -369,9 +395,12 @@ config HOTPLUG_CPU can be controlled through /sys/devices/system/cpu/cpu#. Say N if you want to disable CPU hotplug. +config ARCH_ENABLE_MEMORY_HOTPLUG + def_bool y config HPET_TIMER bool + depends on !X86_64_XEN default y help Use the IA-PC HPET (High Precision Event Timer) to manage @@ -389,7 +418,7 @@ config GART_IOMMU bool "K8 GART IOMMU support" default y select SWIOTLB - depends on PCI + depends on PCI && !X86_64_XEN help Support for hardware IOMMU in AMD's Opteron/Athlon64 Processors and for the bounce buffering software IOMMU. @@ -409,6 +438,7 @@ config SWIOTLB config X86_MCE bool "Machine check support" if EMBEDDED + depends on !X86_64_XEN default y help Include a machine check error handler to report hardware errors. @@ -434,7 +464,7 @@ config X86_MCE_AMD config KEXEC bool "kexec system call (EXPERIMENTAL)" - depends on EXPERIMENTAL + depends on EXPERIMENTAL && !X86_64_XEN help kexec is a system call that implements the ability to shutdown your current kernel, and to start another kernel. It is like a reboot @@ -525,8 +555,11 @@ config GENERIC_PENDING_IRQ default y menu "Power management options" + depends on !XEN_UNPRIVILEGED_GUEST +if !X86_64_XEN source kernel/power/Kconfig +endif source "drivers/acpi/Kconfig" @@ -549,6 +582,21 @@ config PCI_MMCONFIG bool "Support mmconfig PCI config space access" depends on PCI && ACPI +config XEN_PCIDEV_FRONTEND + bool "Xen PCI Frontend" + depends on PCI && X86_64_XEN + default y + help + The PCI device frontend driver allows the kernel to import arbitrary + PCI devices from a PCI backend to support PCI driver domains. + +config XEN_PCIDEV_FE_DEBUG + bool "Xen PCI Frontend Debugging" + depends on XEN_PCIDEV_FRONTEND + default n + help + Enables some debug statements within the PCI Frontend. + source "drivers/pci/pcie/Kconfig" source "drivers/pci/Kconfig" @@ -621,4 +669,6 @@ source "security/Kconfig" source "crypto/Kconfig" +source "drivers/xen/Kconfig" + source "lib/Kconfig" diff --git a/arch/x86_64/Makefile b/arch/x86_64/Makefile index e573e2ab5..4b81d9f4c 100644 --- a/arch/x86_64/Makefile +++ b/arch/x86_64/Makefile @@ -31,6 +31,10 @@ cflags-$(CONFIG_MK8) += $(call cc-option,-march=k8) cflags-$(CONFIG_MPSC) += $(call cc-option,-march=nocona) cflags-$(CONFIG_GENERIC_CPU) += $(call cc-option,-mtune=generic) +cppflags-$(CONFIG_XEN) += \ + -D__XEN_INTERFACE_VERSION__=$(CONFIG_XEN_INTERFACE_VERSION) +CPPFLAGS += $(cppflags-y) + cflags-y += -m64 cflags-y += -mno-red-zone cflags-y += -mcmodel=kernel @@ -72,6 +76,21 @@ boot := arch/x86_64/boot PHONY += bzImage bzlilo install archmrproper \ fdimage fdimage144 fdimage288 isoimage archclean +ifdef CONFIG_XEN +CPPFLAGS := -Iinclude$(if $(KBUILD_SRC),2)/asm/mach-xen $(CPPFLAGS) +head-y := arch/x86_64/kernel/head-xen.o arch/x86_64/kernel/head64-xen.o arch/x86_64/kernel/init_task.o +LDFLAGS_vmlinux := -e _start +boot := arch/i386/boot-xen +.PHONY: vmlinuz +#Default target when executing "make" +all: vmlinuz + +vmlinuz: vmlinux + $(Q)$(MAKE) $(build)=$(boot) $@ + +install: + $(Q)$(MAKE) $(build)=$(boot) XENGUEST=$(XENGUEST) $@ +else #Default target when executing "make" all: bzImage @@ -92,6 +111,7 @@ fdimage fdimage144 fdimage288 isoimage: vmlinux install: $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(BOOTIMAGE) $@ +endif archclean: $(Q)$(MAKE) $(clean)=$(boot) diff --git a/arch/x86_64/ia32/Makefile b/arch/x86_64/ia32/Makefile index e9263b497..a84151e4c 100644 --- a/arch/x86_64/ia32/Makefile +++ b/arch/x86_64/ia32/Makefile @@ -23,9 +23,25 @@ quiet_cmd_syscall = SYSCALL $@ -Wl,-soname=linux-gate.so.1 -o $@ \ -Wl,-T,$(filter-out FORCE,$^) +$(obj)/vsyscall-int80.so \ $(obj)/vsyscall-sysenter.so $(obj)/vsyscall-syscall.so: \ $(obj)/vsyscall-%.so: $(src)/vsyscall.lds $(obj)/vsyscall-%.o FORCE $(call if_changed,syscall) -AFLAGS_vsyscall-sysenter.o = -m32 -Wa,-32 -AFLAGS_vsyscall-syscall.o = -m32 -Wa,-32 +AFLAGS_vsyscall-sysenter.o = -m32 -Wa,-32 -Iarch/i386/kernel +AFLAGS_vsyscall-syscall.o = -m32 -Wa,-32 -Iarch/i386/kernel + +ifdef CONFIG_XEN +AFLAGS_vsyscall-int80.o = -m32 -Wa,-32 -Iarch/i386/kernel +CFLAGS_syscall32-xen.o += -DUSE_INT80 +AFLAGS_syscall32_syscall-xen.o += -DUSE_INT80 + +$(obj)/syscall32_syscall-xen.o: \ + $(foreach F,int80 sysenter syscall,$(obj)/vsyscall-$F.so) + +targets := $(foreach F,int80 sysenter syscall,vsyscall-$F.o vsyscall-$F.so) + +include $(srctree)/scripts/Makefile.xen + +obj-y := $(call cherrypickxen, $(obj-y)) +endif diff --git a/arch/x86_64/ia32/vsyscall-sigreturn.S b/arch/x86_64/ia32/vsyscall-sigreturn.S index 1384367cd..6086ac6fe 100644 --- a/arch/x86_64/ia32/vsyscall-sigreturn.S +++ b/arch/x86_64/ia32/vsyscall-sigreturn.S @@ -139,5 +139,5 @@ __kernel_rt_sigreturn: .align 4 .LENDFDE3: -#include "../../i386/kernel/vsyscall-note.S" +#include diff --git a/arch/x86_64/kernel/Makefile b/arch/x86_64/kernel/Makefile index 059c88313..b0913f3ef 100644 --- a/arch/x86_64/kernel/Makefile +++ b/arch/x86_64/kernel/Makefile @@ -20,11 +20,13 @@ obj-$(CONFIG_MICROCODE) += microcode.o obj-$(CONFIG_X86_CPUID) += cpuid.o obj-$(CONFIG_SMP) += smp.o smpboot.o trampoline.o obj-$(CONFIG_X86_LOCAL_APIC) += apic.o nmi.o +obj-$(CONFIG_X86_XEN_GENAPIC) += genapic.o genapic_xen.o obj-$(CONFIG_X86_IO_APIC) += io_apic.o mpparse.o \ genapic.o genapic_cluster.o genapic_flat.o obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o crash.o obj-$(CONFIG_CRASH_DUMP) += crash_dump.o -obj-$(CONFIG_PM) += suspend.o +obj-$(CONFIG_SOFTWARE_SUSPEND) += suspend.o +obj-$(CONFIG_ACPI_SLEEP) += suspend.o obj-$(CONFIG_SOFTWARE_SUSPEND) += suspend_asm.o obj-$(CONFIG_CPU_FREQ) += cpufreq/ obj-$(CONFIG_EARLY_PRINTK) += early_printk.o @@ -49,3 +51,18 @@ intel_cacheinfo-y += ../../i386/kernel/cpu/intel_cacheinfo.o quirks-y += ../../i386/kernel/quirks.o i8237-y += ../../i386/kernel/i8237.o msr-$(subst m,y,$(CONFIG_X86_MSR)) += ../../i386/kernel/msr.o + +ifdef CONFIG_XEN +time-y += ../../i386/kernel/time-xen.o +pci-dma-y += ../../i386/kernel/pci-dma-xen.o +microcode-$(subst m,y,$(CONFIG_MICROCODE)) := ../../i386/kernel/microcode-xen.o +quirks-y := ../../i386/kernel/quirks-xen.o + +n-obj-xen := i8259.o reboot.o i8237.o smpboot.o trampoline.o + +include $(srctree)/scripts/Makefile.xen + +obj-y := $(call filterxen, $(obj-y), $(n-obj-xen)) +obj-y := $(call cherrypickxen, $(obj-y)) +extra-y := $(call cherrypickxen, $(extra-y)) +endif diff --git a/arch/x86_64/kernel/acpi/Makefile b/arch/x86_64/kernel/acpi/Makefile index 4fe97071f..aa84f6eb9 100644 --- a/arch/x86_64/kernel/acpi/Makefile +++ b/arch/x86_64/kernel/acpi/Makefile @@ -6,3 +6,4 @@ ifneq ($(CONFIG_ACPI_PROCESSOR),) obj-y += processor.o endif +boot-$(CONFIG_XEN) := ../../../i386/kernel/acpi/boot-xen.o diff --git a/arch/x86_64/kernel/asm-offsets.c b/arch/x86_64/kernel/asm-offsets.c index 38834bbba..06cf05867 100644 --- a/arch/x86_64/kernel/asm-offsets.c +++ b/arch/x86_64/kernel/asm-offsets.c @@ -66,7 +66,9 @@ int main(void) DEFINE(pbe_address, offsetof(struct pbe, address)); DEFINE(pbe_orig_address, offsetof(struct pbe, orig_address)); DEFINE(pbe_next, offsetof(struct pbe, next)); +#ifndef CONFIG_X86_NO_TSS BLANK(); DEFINE(TSS_ist, offsetof(struct tss_struct, ist)); +#endif return 0; } diff --git a/arch/x86_64/kernel/entry.S b/arch/x86_64/kernel/entry.S index 586b34c00..4c599eea1 100644 --- a/arch/x86_64/kernel/entry.S +++ b/arch/x86_64/kernel/entry.S @@ -596,7 +596,7 @@ retint_kernel: */ .macro apicinterrupt num,func INTR_FRAME - pushq $\num-256 + pushq $~(\num) CFI_ADJUST_CFA_OFFSET 8 interrupt \func jmp ret_from_intr diff --git a/arch/x86_64/kernel/init_task.c b/arch/x86_64/kernel/init_task.c index ce31d904d..9c141e1a6 100644 --- a/arch/x86_64/kernel/init_task.c +++ b/arch/x86_64/kernel/init_task.c @@ -37,6 +37,8 @@ union thread_union init_thread_union struct task_struct init_task = INIT_TASK(init_task); EXPORT_SYMBOL(init_task); + +#ifndef CONFIG_X86_NO_TSS /* * per-CPU TSS segments. Threads are completely 'soft' on Linux, * no more per-task TSS's. The TSS size is kept cacheline-aligned @@ -45,5 +47,6 @@ EXPORT_SYMBOL(init_task); * on exact cacheline boundaries, to eliminate cacheline ping-pong. */ DEFINE_PER_CPU(struct tss_struct, init_tss) ____cacheline_internodealigned_in_smp = INIT_TSS; +#endif #define ALIGN_TO_4K __attribute__((section(".data.init_task"))) diff --git a/arch/x86_64/kernel/irq.c b/arch/x86_64/kernel/irq.c index d8bd0b345..c87488532 100644 --- a/arch/x86_64/kernel/irq.c +++ b/arch/x86_64/kernel/irq.c @@ -91,8 +91,8 @@ skip: */ asmlinkage unsigned int do_IRQ(struct pt_regs *regs) { - /* high bits used in ret_from_ code */ - unsigned irq = regs->orig_rax & 0xff; + /* high bit used in ret_from_ code */ + unsigned irq = ~regs->orig_rax; exit_idle(); irq_enter(); diff --git a/arch/x86_64/kernel/pmtimer.c b/arch/x86_64/kernel/pmtimer.c index bf421ed26..07340aecf 100644 --- a/arch/x86_64/kernel/pmtimer.c +++ b/arch/x86_64/kernel/pmtimer.c @@ -60,7 +60,9 @@ int pmtimer_mark_offset(void) delta = cyc2us((tick - last_pmtmr_tick) & ACPI_PM_MASK); last_pmtmr_tick = tick; +#ifndef CONFIG_XEN monotonic_base += delta * NSEC_PER_USEC; +#endif delta += offset_delay; diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c index 655b9192e..e8d5f8441 100644 --- a/arch/x86_64/kernel/setup.c +++ b/arch/x86_64/kernel/setup.c @@ -1440,7 +1440,7 @@ struct seq_operations cpuinfo_op = { .show = show_cpuinfo, }; -#ifdef CONFIG_INPUT_PCSPKR +#if defined(CONFIG_INPUT_PCSPKR) || defined(CONFIG_INPUT_PCSPKR_MODULE) #include static __init int add_pcspkr(void) { diff --git a/arch/x86_64/kernel/setup64.c b/arch/x86_64/kernel/setup64.c index 8a691fa6d..189a7372e 100644 --- a/arch/x86_64/kernel/setup64.c +++ b/arch/x86_64/kernel/setup64.c @@ -46,7 +46,7 @@ Control non executable mappings for 64bit processes. on Enable(default) off Disable */ -int __init nonx_setup(char *str) +void __init nonx_setup(const char *str) { if (!strncmp(str, "on", 2)) { __supported_pte_mask |= _PAGE_NX; @@ -55,28 +55,7 @@ int __init nonx_setup(char *str) do_not_nx = 1; __supported_pte_mask &= ~_PAGE_NX; } - return 1; -} -__setup("noexec=", nonx_setup); /* parsed early actually */ - -int force_personality32 = 0; - -/* noexec32=on|off -Control non executable heap for 32bit processes. -To control the stack too use noexec=off - -on PROT_READ does not imply PROT_EXEC for 32bit processes -off PROT_READ implies PROT_EXEC (default) -*/ -static int __init nonx32_setup(char *str) -{ - if (!strcmp(str, "on")) - force_personality32 &= ~READ_IMPLIES_EXEC; - else if (!strcmp(str, "off")) - force_personality32 |= READ_IMPLIES_EXEC; - return 1; } -__setup("noexec32=", nonx32_setup); /* * Great future plan: diff --git a/arch/x86_64/kernel/smp.c b/arch/x86_64/kernel/smp.c index 4a6628b14..e13938d24 100644 --- a/arch/x86_64/kernel/smp.c +++ b/arch/x86_64/kernel/smp.c @@ -135,10 +135,10 @@ asmlinkage void smp_invalidate_interrupt(struct pt_regs *regs) cpu = smp_processor_id(); /* - * orig_rax contains the interrupt vector - 256. + * orig_rax contains the negated interrupt vector. * Use that to determine where the sender put the data. */ - sender = regs->orig_rax + 256 - INVALIDATE_TLB_VECTOR_START; + sender = ~regs->orig_rax - INVALIDATE_TLB_VECTOR_START; f = &per_cpu(flush_state, sender); if (!cpu_isset(cpu, f->flush_cpumask)) diff --git a/arch/x86_64/mm/Makefile b/arch/x86_64/mm/Makefile index d25ac86fe..7d6ceaef4 100644 --- a/arch/x86_64/mm/Makefile +++ b/arch/x86_64/mm/Makefile @@ -9,3 +9,13 @@ obj-$(CONFIG_K8_NUMA) += k8topology.o obj-$(CONFIG_ACPI_NUMA) += srat.o hugetlbpage-y = ../../i386/mm/hugetlbpage.o + +ifdef CONFIG_XEN +include $(srctree)/scripts/Makefile.xen + +ioremap-y += ../../i386/mm/ioremap-xen.o +hypervisor-y += ../../i386/mm/hypervisor.o +obj-y += hypervisor.o + +obj-y := $(call cherrypickxen, $(obj-y)) +endif diff --git a/arch/x86_64/oprofile/Makefile b/arch/x86_64/oprofile/Makefile index 6be32683e..589a7966e 100644 --- a/arch/x86_64/oprofile/Makefile +++ b/arch/x86_64/oprofile/Makefile @@ -11,9 +11,12 @@ DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \ oprofilefs.o oprofile_stats.o \ timer_int.o ) +ifdef CONFIG_XEN +OPROFILE-y := xenoprof.o +else OPROFILE-y := init.o backtrace.o OPROFILE-$(CONFIG_X86_LOCAL_APIC) += nmi_int.o op_model_athlon.o op_model_p4.o \ op_model_ppro.o OPROFILE-$(CONFIG_X86_IO_APIC) += nmi_timer_int.o - +endif oprofile-y = $(DRIVER_OBJS) $(addprefix ../../i386/oprofile/, $(OPROFILE-y)) diff --git a/arch/x86_64/pci/Makefile b/arch/x86_64/pci/Makefile index a3f6ad570..1ea6ea9b6 100644 --- a/arch/x86_64/pci/Makefile +++ b/arch/x86_64/pci/Makefile @@ -15,11 +15,23 @@ obj-$(CONFIG_PCI_MMCONFIG) += mmconfig.o direct.o obj-$(CONFIG_NUMA) += k8-bus.o +# pcifront should be after mmconfig.o and direct.o as it should only +# take over if direct access to the PCI bus is unavailable +obj-$(CONFIG_XEN_PCIDEV_FRONTEND) += pcifront.o + direct-y += ../../i386/pci/direct.o acpi-y += ../../i386/pci/acpi.o +pcifront-y += ../../i386/pci/pcifront.o legacy-y += ../../i386/pci/legacy.o irq-y += ../../i386/pci/irq.o common-y += ../../i386/pci/common.o fixup-y += ../../i386/pci/fixup.o i386-y += ../../i386/pci/i386.o init-y += ../../i386/pci/init.o + +ifdef CONFIG_XEN +irq-y := ../../i386/pci/irq-xen.o +include $(srctree)/scripts/Makefile.xen + +obj-y := $(call cherrypickxen, $(obj-y)) +endif diff --git a/arch/x86_64/pci/mmconfig.c b/arch/x86_64/pci/mmconfig.c index a2060e4d5..3c55c76c6 100644 --- a/arch/x86_64/pci/mmconfig.c +++ b/arch/x86_64/pci/mmconfig.c @@ -13,7 +13,10 @@ #include "pci.h" -#define MMCONFIG_APER_SIZE (256*1024*1024) +/* aperture is up to 256MB but BIOS may reserve less */ +#define MMCONFIG_APER_MIN (2 * 1024*1024) +#define MMCONFIG_APER_MAX (256 * 1024*1024) + /* Verify the first 16 busses. We assume that systems with more busses get MCFG right. */ #define MAX_CHECK_BUS 16 @@ -175,9 +178,10 @@ void __init pci_mmcfg_init(void) return; if (!e820_all_mapped(pci_mmcfg_config[0].base_address, - pci_mmcfg_config[0].base_address + MMCONFIG_APER_SIZE, + pci_mmcfg_config[0].base_address + MMCONFIG_APER_MIN, E820_RESERVED)) { - printk(KERN_ERR "PCI: BIOS Bug: MCFG area is not E820-reserved\n"); + 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; } @@ -190,7 +194,8 @@ void __init pci_mmcfg_init(void) } for (i = 0; i < pci_mmcfg_config_num; ++i) { pci_mmcfg_virt[i].cfg = &pci_mmcfg_config[i]; - pci_mmcfg_virt[i].virt = ioremap_nocache(pci_mmcfg_config[i].base_address, MMCONFIG_APER_SIZE); + pci_mmcfg_virt[i].virt = ioremap_nocache(pci_mmcfg_config[i].base_address, + MMCONFIG_APER_MAX); if (!pci_mmcfg_virt[i].virt) { printk("PCI: Cannot map mmconfig aperture for segment %d\n", pci_mmcfg_config[i].pci_segment_group_number); diff --git a/block/elevator.c b/block/elevator.c index a0afdd317..7be96bbe1 100644 --- a/block/elevator.c +++ b/block/elevator.c @@ -766,7 +766,8 @@ void elv_unregister(struct elevator_type *e) read_lock(&tasklist_lock); do_each_thread(g, p) { task_lock(p); - e->ops.trim(p->io_context); + if (p->io_context) + e->ops.trim(p->io_context); task_unlock(p); } while_each_thread(g, p); read_unlock(&tasklist_lock); diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c index 7eb36c53f..4293143c9 100644 --- a/block/ll_rw_blk.c +++ b/block/ll_rw_blk.c @@ -638,7 +638,7 @@ void blk_queue_bounce_limit(request_queue_t *q, u64 dma_addr) /* Assume anything <= 4GB can be handled by IOMMU. Actually some IOMMUs can handle everything, but I don't know of a way to test this here. */ - if (bounce_pfn < (0xffffffff>>PAGE_SHIFT)) + if (bounce_pfn < (min_t(u64,0xffffffff,BLK_BOUNCE_HIGH) >> PAGE_SHIFT)) dma = 1; q->bounce_pfn = max_low_pfn; #else diff --git a/configs/kernel-2.6.17-i586.config b/configs/kernel-2.6.17-i586.config index 1e12169f5..78c849cc2 100644 --- a/configs/kernel-2.6.17-i586.config +++ b/configs/kernel-2.6.17-i586.config @@ -1,7 +1,8 @@ +# i386 # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.17-prep -# Thu Jul 27 16:52:11 2006 +# Linux kernel version: 2.6.17.13 +# Wed Oct 18 17:15:50 2006 # CONFIG_X86_32=y CONFIG_SEMAPHORE_SLEEPERS=y @@ -93,6 +94,7 @@ CONFIG_DEFAULT_IOSCHED="cfq" # # CONFIG_SMP is not set CONFIG_X86_PC=y +# CONFIG_X86_XEN is not set # CONFIG_X86_ELAN is not set # CONFIG_X86_VOYAGER is not set # CONFIG_X86_NUMAQ is not set @@ -152,6 +154,7 @@ CONFIG_X86_MCE=y # CONFIG_MICROCODE is not set CONFIG_X86_MSR=m CONFIG_X86_CPUID=m +# CONFIG_SWIOTLB is not set # # Firmware Drivers @@ -160,10 +163,11 @@ CONFIG_EDD=m CONFIG_EFI_VARS=y # CONFIG_DELL_RBU is not set # CONFIG_DCDBAS is not set -CONFIG_NOHIGHMEM=y -# CONFIG_HIGHMEM4G is not set +# CONFIG_NOHIGHMEM is not set +CONFIG_HIGHMEM4G=y # CONFIG_HIGHMEM64G is not set CONFIG_PAGE_OFFSET=0xC0000000 +CONFIG_HIGHMEM=y CONFIG_ARCH_FLATMEM_ENABLE=y CONFIG_ARCH_SPARSEMEM_ENABLE=y CONFIG_ARCH_SELECT_MEMORY_MODEL=y @@ -175,6 +179,7 @@ CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y CONFIG_SPARSEMEM_STATIC=y CONFIG_SPLIT_PTLOCK_CPUS=4096 +CONFIG_HIGHPTE=y # CONFIG_MATH_EMULATION is not set CONFIG_MTRR=y CONFIG_EFI=y @@ -186,7 +191,9 @@ CONFIG_HZ_250=y # CONFIG_HZ_1000 is not set CONFIG_HZ=250 CONFIG_KEXEC=y +# CONFIG_CRASH_DUMP is not set CONFIG_PHYSICAL_START=0x400000 +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y # # Power management options (ACPI, APM) @@ -279,6 +286,7 @@ CONFIG_PCI=y # CONFIG_PCI_GOBIOS is not set # CONFIG_PCI_GOMMCONFIG is not set # CONFIG_PCI_GODIRECT is not set +# CONFIG_PCI_GOXEN_FE is not set CONFIG_PCI_GOANY=y CONFIG_PCI_BIOS=y CONFIG_PCI_DIRECT=y @@ -1224,7 +1232,10 @@ CONFIG_EL3=m CONFIG_VORTEX=m CONFIG_TYPHOON=m # CONFIG_LANCE is not set -# CONFIG_NET_VENDOR_SMC is not set +CONFIG_NET_VENDOR_SMC=y +# CONFIG_WD80x3 is not set +CONFIG_ULTRA=m +# CONFIG_SMC9194 is not set # CONFIG_NET_VENDOR_RACAL is not set # @@ -1710,7 +1721,7 @@ CONFIG_SERIO_SERPORT=y # CONFIG_SERIO_PARKBD is not set # CONFIG_SERIO_PCIPS2 is not set CONFIG_SERIO_LIBPS2=y -# CONFIG_SERIO_RAW is not set +CONFIG_SERIO_RAW=m CONFIG_GAMEPORT=m CONFIG_GAMEPORT_NS558=m CONFIG_GAMEPORT_L4=m @@ -2371,6 +2382,7 @@ CONFIG_SND_ENS1371=m CONFIG_SND_ES1938=m CONFIG_SND_ES1968=m CONFIG_SND_FM801=m +CONFIG_SND_FM801_TEA575X_BOOL=y CONFIG_SND_FM801_TEA575X=m CONFIG_SND_HDA_INTEL=m CONFIG_SND_HDSP=m @@ -2810,8 +2822,7 @@ CONFIG_SUNRPC=m CONFIG_SUNRPC_GSS=m CONFIG_RPCSEC_GSS_KRB5=m CONFIG_RPCSEC_GSS_SPKM3=m -CONFIG_SMB_FS=m -# CONFIG_SMB_NLS_DEFAULT is not set +# CONFIG_SMB_FS is not set CONFIG_CIFS=m # CONFIG_CIFS_STATS is not set CONFIG_CIFS_XATTR=y @@ -2917,6 +2928,7 @@ CONFIG_DEBUG_MUTEXES=y CONFIG_DEBUG_SPINLOCK=y CONFIG_DEBUG_SPINLOCK_SLEEP=y # CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_HIGHMEM=y CONFIG_DEBUG_BUGVERBOSE=y CONFIG_DEBUG_INFO=y CONFIG_DEBUG_FS=y diff --git a/configs/kernel-2.6.17-i686-smp.config b/configs/kernel-2.6.17-i686-smp.config index 1be197713..6bbc7950f 100644 --- a/configs/kernel-2.6.17-i686-smp.config +++ b/configs/kernel-2.6.17-i686-smp.config @@ -1,7 +1,8 @@ +# i386 # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.17-prep -# Thu Jul 27 16:52:13 2006 +# Linux kernel version: 2.6.17.13 +# Wed Oct 18 17:15:52 2006 # CONFIG_X86_32=y CONFIG_SEMAPHORE_SLEEPERS=y @@ -96,6 +97,7 @@ CONFIG_DEFAULT_IOSCHED="cfq" # CONFIG_SMP=y # CONFIG_X86_PC is not set +# CONFIG_X86_XEN is not set # CONFIG_X86_ELAN is not set # CONFIG_X86_VOYAGER is not set # CONFIG_X86_NUMAQ is not set @@ -163,6 +165,7 @@ CONFIG_I8K=m CONFIG_MICROCODE=m CONFIG_X86_MSR=m CONFIG_X86_CPUID=m +# CONFIG_SWIOTLB is not set # # Firmware Drivers @@ -202,6 +205,7 @@ CONFIG_KEXEC=y # CONFIG_CRASH_DUMP is not set CONFIG_PHYSICAL_START=0x400000 CONFIG_HOTPLUG_CPU=y +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y # # Power management options (ACPI, APM) @@ -302,6 +306,7 @@ CONFIG_PCI=y # CONFIG_PCI_GOBIOS is not set # CONFIG_PCI_GOMMCONFIG is not set # CONFIG_PCI_GODIRECT is not set +# CONFIG_PCI_GOXEN_FE is not set CONFIG_PCI_GOANY=y CONFIG_PCI_BIOS=y CONFIG_PCI_DIRECT=y @@ -1362,7 +1367,10 @@ CONFIG_EL3=m CONFIG_VORTEX=m CONFIG_TYPHOON=m # CONFIG_LANCE is not set -# CONFIG_NET_VENDOR_SMC is not set +CONFIG_NET_VENDOR_SMC=y +# CONFIG_WD80x3 is not set +CONFIG_ULTRA=m +# CONFIG_SMC9194 is not set # CONFIG_NET_VENDOR_RACAL is not set # @@ -1844,7 +1852,7 @@ CONFIG_SERIO_SERPORT=y # CONFIG_SERIO_PARKBD is not set # CONFIG_SERIO_PCIPS2 is not set CONFIG_SERIO_LIBPS2=y -# CONFIG_SERIO_RAW is not set +CONFIG_SERIO_RAW=m CONFIG_GAMEPORT=m CONFIG_GAMEPORT_NS558=m CONFIG_GAMEPORT_L4=m @@ -2570,6 +2578,7 @@ CONFIG_SND_ENS1371=m CONFIG_SND_ES1938=m CONFIG_SND_ES1968=m CONFIG_SND_FM801=m +CONFIG_SND_FM801_TEA575X_BOOL=y CONFIG_SND_FM801_TEA575X=m CONFIG_SND_HDA_INTEL=m CONFIG_SND_HDSP=m @@ -3026,8 +3035,7 @@ CONFIG_SUNRPC=m CONFIG_SUNRPC_GSS=m CONFIG_RPCSEC_GSS_KRB5=m CONFIG_RPCSEC_GSS_SPKM3=m -CONFIG_SMB_FS=m -# CONFIG_SMB_NLS_DEFAULT is not set +# CONFIG_SMB_FS is not set CONFIG_CIFS=m # CONFIG_CIFS_STATS is not set CONFIG_CIFS_XATTR=y diff --git a/configs/kernel-2.6.17-i686.config b/configs/kernel-2.6.17-i686.config index 97dd34931..111ab3a33 100644 --- a/configs/kernel-2.6.17-i686.config +++ b/configs/kernel-2.6.17-i686.config @@ -1,7 +1,8 @@ +# i386 # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.17-prep -# Thu Jul 27 16:52:12 2006 +# Linux kernel version: 2.6.17.13 +# Wed Oct 18 17:15:54 2006 # CONFIG_X86_32=y CONFIG_SEMAPHORE_SLEEPERS=y @@ -94,6 +95,7 @@ CONFIG_DEFAULT_IOSCHED="cfq" # # CONFIG_SMP is not set CONFIG_X86_PC=y +# CONFIG_X86_XEN is not set # CONFIG_X86_ELAN is not set # CONFIG_X86_VOYAGER is not set # CONFIG_X86_NUMAQ is not set @@ -158,6 +160,7 @@ CONFIG_I8K=m CONFIG_MICROCODE=m CONFIG_X86_MSR=m CONFIG_X86_CPUID=m +# CONFIG_SWIOTLB is not set # # Firmware Drivers @@ -196,6 +199,7 @@ CONFIG_HZ=250 CONFIG_KEXEC=y # CONFIG_CRASH_DUMP is not set CONFIG_PHYSICAL_START=0x400000 +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y # # Power management options (ACPI, APM) @@ -294,6 +298,7 @@ CONFIG_PCI=y # CONFIG_PCI_GOBIOS is not set # CONFIG_PCI_GOMMCONFIG is not set # CONFIG_PCI_GODIRECT is not set +# CONFIG_PCI_GOXEN_FE is not set CONFIG_PCI_GOANY=y CONFIG_PCI_BIOS=y CONFIG_PCI_DIRECT=y @@ -1355,7 +1360,10 @@ CONFIG_EL3=m CONFIG_VORTEX=m CONFIG_TYPHOON=m # CONFIG_LANCE is not set -# CONFIG_NET_VENDOR_SMC is not set +CONFIG_NET_VENDOR_SMC=y +# CONFIG_WD80x3 is not set +CONFIG_ULTRA=m +# CONFIG_SMC9194 is not set # CONFIG_NET_VENDOR_RACAL is not set # @@ -1841,7 +1849,7 @@ CONFIG_SERIO_SERPORT=y # CONFIG_SERIO_PARKBD is not set # CONFIG_SERIO_PCIPS2 is not set CONFIG_SERIO_LIBPS2=y -# CONFIG_SERIO_RAW is not set +CONFIG_SERIO_RAW=m CONFIG_GAMEPORT=m CONFIG_GAMEPORT_NS558=m CONFIG_GAMEPORT_L4=m @@ -2570,6 +2578,7 @@ CONFIG_SND_ENS1371=m CONFIG_SND_ES1938=m CONFIG_SND_ES1968=m CONFIG_SND_FM801=m +CONFIG_SND_FM801_TEA575X_BOOL=y CONFIG_SND_FM801_TEA575X=m CONFIG_SND_HDA_INTEL=m CONFIG_SND_HDSP=m @@ -3026,8 +3035,7 @@ CONFIG_SUNRPC=m CONFIG_SUNRPC_GSS=m CONFIG_RPCSEC_GSS_KRB5=m CONFIG_RPCSEC_GSS_SPKM3=m -CONFIG_SMB_FS=m -# CONFIG_SMB_NLS_DEFAULT is not set +# CONFIG_SMB_FS is not set CONFIG_CIFS=m # CONFIG_CIFS_STATS is not set CONFIG_CIFS_XATTR=y diff --git a/drivers/Makefile b/drivers/Makefile index 447d8e688..26b29563d 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -31,6 +31,7 @@ obj-y += base/ block/ misc/ mfd/ net/ media/ obj-$(CONFIG_NUBUS) += nubus/ obj-$(CONFIG_ATM) += atm/ obj-$(CONFIG_PPC_PMAC) += macintosh/ +obj-$(CONFIG_XEN) += xen/ obj-$(CONFIG_IDE) += ide/ obj-$(CONFIG_FC4) += fc4/ obj-$(CONFIG_SCSI) += scsi/ diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index c24652d31..f0c892613 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -46,7 +46,7 @@ if ACPI config ACPI_SLEEP bool "Sleep States" - depends on X86 && (!SMP || SUSPEND_SMP) + depends on X86 && (!SMP || SUSPEND_SMP) && !XEN depends on PM default y ---help--- @@ -300,6 +300,7 @@ config ACPI_SYSTEM config X86_PM_TIMER bool "Power Management Timer Support" if EMBEDDED depends on X86 + depends on !XEN default y help The Power Management Timer is available on all ACPI-capable, diff --git a/drivers/acpi/namespace/nsxfeval.c b/drivers/acpi/namespace/nsxfeval.c index a95f636dc..d7791fbc7 100644 --- a/drivers/acpi/namespace/nsxfeval.c +++ b/drivers/acpi/namespace/nsxfeval.c @@ -238,8 +238,9 @@ acpi_evaluate_object(acpi_handle handle, ACPI_ERROR((AE_INFO, "Both Handle and Pathname are NULL")); } else { - ACPI_ERROR((AE_INFO, - "Handle is NULL and Pathname is relative")); + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Null Handle with relative pathname [%s]", + pathname)); } status = AE_BAD_PARAMETER; diff --git a/drivers/block/aoe/aoenet.c b/drivers/block/aoe/aoenet.c index fdff774b8..c1434ed11 100644 --- a/drivers/block/aoe/aoenet.c +++ b/drivers/block/aoe/aoenet.c @@ -116,8 +116,7 @@ aoenet_rcv(struct sk_buff *skb, struct net_device *ifp, struct packet_type *pt, skb = skb_share_check(skb, GFP_ATOMIC); if (skb == NULL) return 0; - if (skb_is_nonlinear(skb)) - if (skb_linearize(skb, GFP_ATOMIC) < 0) + if (skb_linearize(skb)) goto exit; if (!is_aoe_netif(ifp)) goto exit; diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c index 3170eaa25..fdd37e407 100644 --- a/drivers/cdrom/cdrom.c +++ b/drivers/cdrom/cdrom.c @@ -1838,7 +1838,7 @@ static int dvd_read_bca(struct cdrom_device_info *cdi, dvd_struct *s) init_cdrom_command(&cgc, buf, sizeof(buf), CGC_DATA_READ); cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE; cgc.cmd[7] = s->type; - cgc.cmd[9] = cgc.buflen = 0xff; + cgc.cmd[9] = cgc.buflen & 0xff; if ((ret = cdo->generic_packet(cdi, &cgc))) return ret; diff --git a/drivers/char/mem.c b/drivers/char/mem.c index 6a7aa9314..418da028c 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c @@ -36,6 +36,22 @@ # include #endif +static inline int range_is_allowed(unsigned long from, unsigned long to) +{ + unsigned long cursor; + + cursor = from >> PAGE_SHIFT; + while ((cursor << PAGE_SHIFT) < to) { + if (!devmem_is_allowed(cursor)) { + printk ("Program %s tried to read /dev/mem between %lx->%lx.\n", + current->comm, from, to); + return 0; + } + cursor++; + } + return 1; +} + /* * Architectures vary in how they handle caching for addresses * outside of main memory. @@ -103,22 +119,7 @@ static inline int valid_mmap_phys_addr_range(unsigned long addr, size_t size) } #endif -static inline int range_is_allowed(unsigned long from, unsigned long to) -{ - unsigned long cursor; - - cursor = from >> PAGE_SHIFT; - while ((cursor << PAGE_SHIFT) < to) { - if (!devmem_is_allowed(cursor)) { - printk ("Program %s tried to read /dev/mem between %lx->%lx.\n", - current->comm, from, to); - return 0; - } - cursor++; - } - return 1; -} - +#ifndef ARCH_HAS_DEV_MEM /* * This funcion reads the *physical* memory. The f_pos points directly to the * memory location. @@ -245,6 +246,7 @@ static ssize_t write_mem(struct file * file, const char __user * buf, *ppos += written; return written; } +#endif #ifndef __HAVE_PHYS_MEM_ACCESS_PROT static pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, @@ -681,6 +683,7 @@ static int open_port(struct inode * inode, struct file * filp) #define open_kmem open_mem #define open_oldmem open_mem +#ifndef ARCH_HAS_DEV_MEM static struct file_operations mem_fops = { .llseek = memory_lseek, .read = read_mem, @@ -688,6 +691,9 @@ static struct file_operations mem_fops = { .mmap = mmap_mem, .open = open_mem, }; +#else +extern struct file_operations mem_fops; +#endif static struct file_operations kmem_fops = { .llseek = memory_lseek, diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c index 8ea70625f..2678034be 100644 --- a/drivers/char/tpm/tpm_tis.c +++ b/drivers/char/tpm/tpm_tis.c @@ -424,6 +424,7 @@ static irqreturn_t tis_int_handler(int irq, void *dev_id, struct pt_regs *regs) iowrite32(interrupt, chip->vendor.iobase + TPM_INT_STATUS(chip->vendor.locality)); + ioread32(chip->vendor.iobase + TPM_INT_STATUS(chip->vendor.locality)); return IRQ_HANDLED; } diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index 0b31cf25c..12c15826a 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c @@ -133,6 +133,8 @@ LIST_HEAD(tty_drivers); /* linked list of tty drivers */ vt.c for deeply disgusting hack reasons */ DEFINE_MUTEX(tty_mutex); +int console_use_vt = 1; + #ifdef CONFIG_UNIX98_PTYS extern struct tty_driver *ptm_driver; /* Unix98 pty masters; for /dev/ptmx */ extern int pty_limit; /* Config limit on Unix98 ptys */ @@ -1674,19 +1676,6 @@ release_mem_out: goto end_init; } -/* - * Get a copy of the termios structure for the driver/index - */ -void tty_get_termios(struct tty_driver *driver, int idx, struct termios *tio) -{ - lock_kernel(); - if (driver->termios[idx]) - *tio = *driver->termios[idx]; - else - *tio = driver->init_termios; - unlock_kernel(); -} - /* * Releases memory associated with a tty structure, and clears out the * driver table slots. @@ -2074,7 +2063,7 @@ retry_open: goto got_driver; } #ifdef CONFIG_VT - if (device == MKDEV(TTY_MAJOR,0)) { + if (console_use_vt && (device == MKDEV(TTY_MAJOR,0))) { extern struct tty_driver *console_driver; driver = console_driver; index = fg_console; @@ -2795,7 +2784,7 @@ static void flush_to_ldisc(void *private_) struct tty_struct *tty = (struct tty_struct *) private_; unsigned long flags; struct tty_ldisc *disc; - struct tty_buffer *tbuf; + struct tty_buffer *tbuf, *head; int count; char *char_buf; unsigned char *flag_buf; @@ -2812,7 +2801,9 @@ static void flush_to_ldisc(void *private_) goto out; } spin_lock_irqsave(&tty->buf.lock, flags); - while((tbuf = tty->buf.head) != NULL) { + head = tty->buf.head; + tty->buf.head = NULL; + while((tbuf = head) != NULL) { while ((count = tbuf->commit - tbuf->read) != 0) { char_buf = tbuf->char_buf_ptr + tbuf->read; flag_buf = tbuf->flag_buf_ptr + tbuf->read; @@ -2821,10 +2812,12 @@ static void flush_to_ldisc(void *private_) disc->receive_buf(tty, char_buf, flag_buf, count); spin_lock_irqsave(&tty->buf.lock, flags); } - if (tbuf->active) + if (tbuf->active) { + tty->buf.head = head; break; - tty->buf.head = tbuf->next; - if (tty->buf.head == NULL) + } + head = tbuf->next; + if (head == NULL) tty->buf.tail = NULL; tty_buffer_free(tty, tbuf); } @@ -3277,6 +3270,8 @@ static int __init tty_init(void) #endif #ifdef CONFIG_VT + if (!console_use_vt) + goto out_vt; cdev_init(&vc0_cdev, &console_fops); if (cdev_add(&vc0_cdev, MKDEV(TTY_MAJOR, 0), 1) || register_chrdev_region(MKDEV(TTY_MAJOR, 0), 1, "/dev/vc/0") < 0) @@ -3285,6 +3280,7 @@ static int __init tty_init(void) class_device_create(tty_class, NULL, MKDEV(TTY_MAJOR, 0), NULL, "tty0"); vty_init(); + out_vt: #endif return 0; } diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig index 1e371a510..f0dff5ac1 100644 --- a/drivers/firmware/Kconfig +++ b/drivers/firmware/Kconfig @@ -8,7 +8,7 @@ menu "Firmware Drivers" config EDD tristate "BIOS Enhanced Disk Drive calls determine boot disk (EXPERIMENTAL)" depends on EXPERIMENTAL - depends on !IA64 + depends on !IA64 && !XEN help Say Y or M here if you want to enable BIOS Enhanced Disk Drive Services real mode BIOS calls to determine which disk diff --git a/drivers/i2c/busses/scx200_acb.c b/drivers/i2c/busses/scx200_acb.c index 766cc969c..9b4f4ee4f 100644 --- a/drivers/i2c/busses/scx200_acb.c +++ b/drivers/i2c/busses/scx200_acb.c @@ -181,21 +181,21 @@ static void scx200_acb_machine(struct scx200_acb_iface *iface, u8 status) break; case state_read: - /* Set ACK if receiving the last byte */ - if (iface->len == 1) + /* Set ACK if _next_ byte will be the last one */ + if (iface->len == 2) outb(inb(ACBCTL1) | ACBCTL1_ACK, ACBCTL1); else outb(inb(ACBCTL1) & ~ACBCTL1_ACK, ACBCTL1); - *iface->ptr++ = inb(ACBSDA); - --iface->len; - - if (iface->len == 0) { + if (iface->len == 1) { iface->result = 0; iface->state = state_idle; outb(inb(ACBCTL1) | ACBCTL1_STOP, ACBCTL1); } + *iface->ptr++ = inb(ACBSDA); + --iface->len; + break; case state_write: @@ -304,8 +304,12 @@ static s32 scx200_acb_smbus_xfer(struct i2c_adapter *adapter, buffer = (u8 *)&cur_word; break; - case I2C_SMBUS_BLOCK_DATA: + case I2C_SMBUS_I2C_BLOCK_DATA: + if (rw == I2C_SMBUS_READ) + data->block[0] = I2C_SMBUS_BLOCK_MAX; /* For now */ len = data->block[0]; + if (len == 0 || len > I2C_SMBUS_BLOCK_MAX) + return -EINVAL; buffer = &data->block[1]; break; @@ -369,7 +373,7 @@ static u32 scx200_acb_func(struct i2c_adapter *adapter) { return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | - I2C_FUNC_SMBUS_BLOCK_DATA; + I2C_FUNC_SMBUS_I2C_BLOCK; } /* For now, we only handle combined mode (smbus) */ diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 45e2cdf54..2e79137dc 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -756,9 +756,9 @@ int i2c_probe(struct i2c_adapter *adapter, "parameter for adapter %d, " "addr 0x%02x\n", adap_id, address_data->ignore[j + 1]); + ignore = 1; + break; } - ignore = 1; - break; } if (ignore) continue; diff --git a/drivers/ide/ide-lib.c b/drivers/ide/ide-lib.c index 41d46dbe6..b09a6537c 100644 --- a/drivers/ide/ide-lib.c +++ b/drivers/ide/ide-lib.c @@ -410,10 +410,10 @@ void ide_toggle_bounce(ide_drive_t *drive, int on) { u64 addr = BLK_BOUNCE_HIGH; /* dma64_addr_t */ - if (!PCI_DMA_BUS_IS_PHYS) { - addr = BLK_BOUNCE_ANY; - } else if (on && drive->media == ide_disk) { - if (HWIF(drive)->pci_dev) + if (on && drive->media == ide_disk) { + if (!PCI_DMA_BUS_IS_PHYS) + addr = BLK_BOUNCE_ANY; + else if (HWIF(drive)->pci_dev) addr = HWIF(drive)->pci_dev->dma_mask; } diff --git a/drivers/ide/pci/via82cxxx.c b/drivers/ide/pci/via82cxxx.c index 3e677c4f8..9914a78a5 100644 --- a/drivers/ide/pci/via82cxxx.c +++ b/drivers/ide/pci/via82cxxx.c @@ -6,7 +6,7 @@ * * vt82c576, vt82c586, vt82c586a, vt82c586b, vt82c596a, vt82c596b, * vt82c686, vt82c686a, vt82c686b, vt8231, vt8233, vt8233c, vt8233a, - * vt8235, vt8237 + * vt8235, vt8237, vt8237a * * Copyright (c) 2000-2002 Vojtech Pavlik * @@ -82,6 +82,7 @@ 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/drivers/ieee1394/ohci1394.c b/drivers/ieee1394/ohci1394.c index 8f1292c36..d1788cdf0 100644 --- a/drivers/ieee1394/ohci1394.c +++ b/drivers/ieee1394/ohci1394.c @@ -3548,6 +3548,8 @@ 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; @@ -3559,8 +3561,6 @@ static int ohci1394_pci_suspend (struct pci_dev *pdev, pm_message_t state) } #endif - pci_save_state(pdev); - return 0; } diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c index 5413dc43b..e084dbf76 100644 --- a/drivers/ieee1394/sbp2.c +++ b/drivers/ieee1394/sbp2.c @@ -2541,6 +2541,9 @@ static int sbp2scsi_slave_configure(struct scsi_device *sdev) sdev->skip_ms_page_8 = 1; if (scsi_id->workarounds & SBP2_WORKAROUND_FIX_CAPACITY) sdev->fix_capacity = 1; + if (scsi_id->ne->guid_vendor_id == 0x0010b9 && /* Maxtor's OUI */ + (sdev->type == TYPE_DISK || sdev->type == TYPE_RBC)) + sdev->allow_restart = 1; return 0; } diff --git a/drivers/infiniband/hw/mthca/mthca_reset.c b/drivers/infiniband/hw/mthca/mthca_reset.c index df5e494a9..f4fddd532 100644 --- a/drivers/infiniband/hw/mthca/mthca_reset.c +++ b/drivers/infiniband/hw/mthca/mthca_reset.c @@ -49,6 +49,12 @@ int mthca_reset(struct mthca_dev *mdev) u32 *hca_header = NULL; u32 *bridge_header = NULL; struct pci_dev *bridge = NULL; + int bridge_pcix_cap = 0; + int hca_pcie_cap = 0; + int hca_pcix_cap = 0; + + u16 devctl; + u16 linkctl; #define MTHCA_RESET_OFFSET 0xf0010 #define MTHCA_RESET_VALUE swab32(1) @@ -110,6 +116,9 @@ int mthca_reset(struct mthca_dev *mdev) } } + hca_pcix_cap = pci_find_capability(mdev->pdev, PCI_CAP_ID_PCIX); + hca_pcie_cap = pci_find_capability(mdev->pdev, PCI_CAP_ID_EXP); + if (bridge) { bridge_header = kmalloc(256, GFP_KERNEL); if (!bridge_header) { @@ -129,6 +138,13 @@ int mthca_reset(struct mthca_dev *mdev) goto out; } } + bridge_pcix_cap = pci_find_capability(bridge, PCI_CAP_ID_PCIX); + if (!bridge_pcix_cap) { + err = -ENODEV; + mthca_err(mdev, "Couldn't locate HCA bridge " + "PCI-X capability, aborting.\n"); + goto out; + } } /* actually hit reset */ @@ -178,6 +194,20 @@ int mthca_reset(struct mthca_dev *mdev) good: /* Now restore the PCI headers */ if (bridge) { + if (pci_write_config_dword(bridge, bridge_pcix_cap + 0x8, + bridge_header[(bridge_pcix_cap + 0x8) / 4])) { + err = -ENODEV; + mthca_err(mdev, "Couldn't restore HCA bridge Upstream " + "split transaction control, aborting.\n"); + goto out; + } + if (pci_write_config_dword(bridge, bridge_pcix_cap + 0xc, + bridge_header[(bridge_pcix_cap + 0xc) / 4])) { + err = -ENODEV; + mthca_err(mdev, "Couldn't restore HCA bridge Downstream " + "split transaction control, aborting.\n"); + goto out; + } /* * Bridge control register is at 0x3e, so we'll * naturally restore it last in this loop. @@ -203,6 +233,35 @@ good: } } + if (hca_pcix_cap) { + if (pci_write_config_dword(mdev->pdev, hca_pcix_cap, + hca_header[hca_pcix_cap / 4])) { + err = -ENODEV; + mthca_err(mdev, "Couldn't restore HCA PCI-X " + "command register, aborting.\n"); + goto out; + } + } + + if (hca_pcie_cap) { + devctl = hca_header[(hca_pcie_cap + PCI_EXP_DEVCTL) / 4]; + if (pci_write_config_word(mdev->pdev, hca_pcie_cap + PCI_EXP_DEVCTL, + devctl)) { + err = -ENODEV; + mthca_err(mdev, "Couldn't restore HCA PCI Express " + "Device Control register, aborting.\n"); + goto out; + } + linkctl = hca_header[(hca_pcie_cap + PCI_EXP_LNKCTL) / 4]; + if (pci_write_config_word(mdev->pdev, hca_pcie_cap + PCI_EXP_LNKCTL, + linkctl)) { + err = -ENODEV; + mthca_err(mdev, "Couldn't restore HCA PCI Express " + "Link control register, aborting.\n"); + goto out; + } + } + for (i = 0; i < 16; ++i) { if (i * 4 == PCI_COMMAND) continue; diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c index 1dae4b238..1d917edcf 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c @@ -821,7 +821,8 @@ void ipoib_mcast_restart_task(void *dev_ptr) ipoib_mcast_stop_thread(dev, 0); - spin_lock_irqsave(&dev->xmit_lock, flags); + local_irq_save(flags); + netif_tx_lock(dev); spin_lock(&priv->lock); /* @@ -896,7 +897,8 @@ void ipoib_mcast_restart_task(void *dev_ptr) } spin_unlock(&priv->lock); - spin_unlock_irqrestore(&dev->xmit_lock, flags); + netif_tx_unlock(dev); + local_irq_restore(flags); /* We have to cancel outside of the spinlock */ list_for_each_entry_safe(mcast, tmcast, &remove_list, list) { diff --git a/drivers/md/dm-exception-store.c b/drivers/md/dm-exception-store.c index cc07bbebb..34a75939a 100644 --- a/drivers/md/dm-exception-store.c +++ b/drivers/md/dm-exception-store.c @@ -91,7 +91,6 @@ struct pstore { struct dm_snapshot *snap; /* up pointer to my snapshot */ int version; int valid; - uint32_t chunk_size; uint32_t exceptions_per_area; /* @@ -133,7 +132,7 @@ static int alloc_area(struct pstore *ps) int r = -ENOMEM; size_t len; - len = ps->chunk_size << SECTOR_SHIFT; + len = ps->snap->chunk_size << SECTOR_SHIFT; /* * Allocate the chunk_size block of memory that will hold @@ -160,8 +159,8 @@ static int chunk_io(struct pstore *ps, uint32_t chunk, int rw) unsigned long bits; where.bdev = ps->snap->cow->bdev; - where.sector = ps->chunk_size * chunk; - where.count = ps->chunk_size; + where.sector = ps->snap->chunk_size * chunk; + where.count = ps->snap->chunk_size; return dm_io_sync_vm(1, &where, rw, ps->area, &bits); } @@ -188,7 +187,7 @@ static int area_io(struct pstore *ps, uint32_t area, int rw) static int zero_area(struct pstore *ps, uint32_t area) { - memset(ps->area, 0, ps->chunk_size << SECTOR_SHIFT); + memset(ps->area, 0, ps->snap->chunk_size << SECTOR_SHIFT); return area_io(ps, area, WRITE); } @@ -196,6 +195,7 @@ static int read_header(struct pstore *ps, int *new_snapshot) { int r; struct disk_header *dh; + chunk_t chunk_size; r = chunk_io(ps, 0, READ); if (r) @@ -210,8 +210,29 @@ static int read_header(struct pstore *ps, int *new_snapshot) *new_snapshot = 0; ps->valid = le32_to_cpu(dh->valid); ps->version = le32_to_cpu(dh->version); - ps->chunk_size = le32_to_cpu(dh->chunk_size); - + chunk_size = le32_to_cpu(dh->chunk_size); + if (ps->snap->chunk_size != chunk_size) { + DMWARN("chunk size %llu in device metadata overrides " + "table chunk size of %llu.", + (unsigned long long)chunk_size, + (unsigned long long)ps->snap->chunk_size); + + /* We had a bogus chunk_size. Fix stuff up. */ + dm_io_put(sectors_to_pages(ps->snap->chunk_size)); + free_area(ps); + + ps->snap->chunk_size = chunk_size; + ps->snap->chunk_mask = chunk_size - 1; + ps->snap->chunk_shift = ffs(chunk_size) - 1; + + r = alloc_area(ps); + if (r) + return r; + + r = dm_io_get(sectors_to_pages(chunk_size)); + if (r) + return r; + } } else { DMWARN("Invalid/corrupt snapshot"); r = -ENXIO; @@ -224,13 +245,13 @@ static int write_header(struct pstore *ps) { struct disk_header *dh; - memset(ps->area, 0, ps->chunk_size << SECTOR_SHIFT); + memset(ps->area, 0, ps->snap->chunk_size << SECTOR_SHIFT); dh = (struct disk_header *) ps->area; dh->magic = cpu_to_le32(SNAP_MAGIC); dh->valid = cpu_to_le32(ps->valid); dh->version = cpu_to_le32(ps->version); - dh->chunk_size = cpu_to_le32(ps->chunk_size); + dh->chunk_size = cpu_to_le32(ps->snap->chunk_size); return chunk_io(ps, 0, WRITE); } @@ -365,7 +386,7 @@ static void persistent_destroy(struct exception_store *store) { struct pstore *ps = get_info(store); - dm_io_put(sectors_to_pages(ps->chunk_size)); + dm_io_put(sectors_to_pages(ps->snap->chunk_size)); vfree(ps->callbacks); free_area(ps); kfree(ps); @@ -383,6 +404,16 @@ static int persistent_read_metadata(struct exception_store *store) if (r) return r; + /* + * Now we know correct chunk_size, complete the initialisation. + */ + ps->exceptions_per_area = (ps->snap->chunk_size << SECTOR_SHIFT) / + sizeof(struct disk_exception); + ps->callbacks = dm_vcalloc(ps->exceptions_per_area, + sizeof(*ps->callbacks)); + if (!ps->callbacks) + return -ENOMEM; + /* * Do we need to setup a new snapshot ? */ @@ -533,9 +564,6 @@ int dm_create_persistent(struct exception_store *store, uint32_t chunk_size) ps->snap = store->snap; ps->valid = 1; ps->version = SNAPSHOT_DISK_VERSION; - ps->chunk_size = chunk_size; - ps->exceptions_per_area = (chunk_size << SECTOR_SHIFT) / - sizeof(struct disk_exception); ps->next_free = 2; /* skipping the header and first area */ ps->current_committed = 0; @@ -543,18 +571,9 @@ int dm_create_persistent(struct exception_store *store, uint32_t chunk_size) if (r) goto bad; - /* - * Allocate space for all the callbacks. - */ ps->callback_count = 0; atomic_set(&ps->pending_count, 0); - ps->callbacks = dm_vcalloc(ps->exceptions_per_area, - sizeof(*ps->callbacks)); - - if (!ps->callbacks) { - r = -ENOMEM; - goto bad; - } + ps->callbacks = NULL; store->destroy = persistent_destroy; store->read_metadata = persistent_read_metadata; diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c index 8edd64354..f7e743691 100644 --- a/drivers/md/dm-ioctl.c +++ b/drivers/md/dm-ioctl.c @@ -102,8 +102,10 @@ static struct hash_cell *__get_name_cell(const char *str) unsigned int h = hash_str(str); list_for_each_entry (hc, _name_buckets + h, name_list) - if (!strcmp(hc->name, str)) + if (!strcmp(hc->name, str)) { + dm_get(hc->md); return hc; + } return NULL; } @@ -114,8 +116,10 @@ static struct hash_cell *__get_uuid_cell(const char *str) unsigned int h = hash_str(str); list_for_each_entry (hc, _uuid_buckets + h, uuid_list) - if (!strcmp(hc->uuid, str)) + if (!strcmp(hc->uuid, str)) { + dm_get(hc->md); return hc; + } return NULL; } @@ -191,7 +195,7 @@ static int unregister_with_devfs(struct hash_cell *hc) */ static int dm_hash_insert(const char *name, const char *uuid, struct mapped_device *md) { - struct hash_cell *cell; + struct hash_cell *cell, *hc; /* * Allocate the new cells. @@ -204,14 +208,19 @@ static int dm_hash_insert(const char *name, const char *uuid, struct mapped_devi * Insert the cell into both hash tables. */ down_write(&_hash_lock); - if (__get_name_cell(name)) + hc = __get_name_cell(name); + if (hc) { + dm_put(hc->md); goto bad; + } list_add(&cell->name_list, _name_buckets + hash_str(name)); if (uuid) { - if (__get_uuid_cell(uuid)) { + hc = __get_uuid_cell(uuid); + if (hc) { list_del(&cell->name_list); + dm_put(hc->md); goto bad; } list_add(&cell->uuid_list, _uuid_buckets + hash_str(uuid)); @@ -289,6 +298,7 @@ static int dm_hash_rename(const char *old, const char *new) if (hc) { DMWARN("asked to rename to an already existing name %s -> %s", old, new); + dm_put(hc->md); up_write(&_hash_lock); kfree(new_name); return -EBUSY; @@ -328,6 +338,7 @@ static int dm_hash_rename(const char *old, const char *new) dm_table_put(table); } + dm_put(hc->md); up_write(&_hash_lock); kfree(old_name); return 0; @@ -611,10 +622,8 @@ static struct hash_cell *__find_device_hash_cell(struct dm_ioctl *param) return __get_name_cell(param->name); md = dm_get_md(huge_decode_dev(param->dev)); - if (md) { + if (md) mdptr = dm_get_mdptr(md); - dm_put(md); - } return mdptr; } @@ -628,7 +637,6 @@ static struct mapped_device *find_device(struct dm_ioctl *param) hc = __find_device_hash_cell(param); if (hc) { md = hc->md; - dm_get(md); /* * Sneakily write in both the name and the uuid @@ -653,6 +661,7 @@ static struct mapped_device *find_device(struct dm_ioctl *param) static int dev_remove(struct dm_ioctl *param, size_t param_size) { struct hash_cell *hc; + struct mapped_device *md; down_write(&_hash_lock); hc = __find_device_hash_cell(param); @@ -663,8 +672,11 @@ static int dev_remove(struct dm_ioctl *param, size_t param_size) return -ENXIO; } + md = hc->md; + __hash_remove(hc); up_write(&_hash_lock); + dm_put(md); param->data_size = 0; return 0; } @@ -790,7 +802,6 @@ static int do_resume(struct dm_ioctl *param) } md = hc->md; - dm_get(md); new_map = hc->new_map; hc->new_map = NULL; @@ -1078,6 +1089,7 @@ static int table_clear(struct dm_ioctl *param, size_t param_size) { int r; struct hash_cell *hc; + struct mapped_device *md; down_write(&_hash_lock); @@ -1096,7 +1108,9 @@ static int table_clear(struct dm_ioctl *param, size_t param_size) param->flags &= ~DM_INACTIVE_PRESENT_FLAG; r = __dev_status(hc->md, param); + md = hc->md; up_write(&_hash_lock); + dm_put(md); return r; } diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c index 1816f3067..5af5265cf 100644 --- a/drivers/md/dm-mpath.c +++ b/drivers/md/dm-mpath.c @@ -711,6 +711,8 @@ static int multipath_ctr(struct dm_target *ti, unsigned int argc, return -EINVAL; } + m->ti = ti; + r = parse_features(&as, m, ti); if (r) goto bad; @@ -752,7 +754,6 @@ static int multipath_ctr(struct dm_target *ti, unsigned int argc, } ti->private = m; - m->ti = ti; return 0; diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index d12cf3e5e..2cab46ed1 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c @@ -106,12 +106,42 @@ struct region { struct bio_list delayed_bios; }; + +/*----------------------------------------------------------------- + * Mirror set structures. + *---------------------------------------------------------------*/ +struct mirror { + atomic_t error_count; + struct dm_dev *dev; + sector_t offset; +}; + +struct mirror_set { + struct dm_target *ti; + struct list_head list; + struct region_hash rh; + struct kcopyd_client *kcopyd_client; + + spinlock_t lock; /* protects the next two lists */ + struct bio_list reads; + struct bio_list writes; + + /* recovery */ + region_t nr_regions; + int in_sync; + + struct mirror *default_mirror; /* Default mirror */ + + unsigned int nr_mirrors; + struct mirror mirror[0]; +}; + /* * Conversion fns */ static inline region_t bio_to_region(struct region_hash *rh, struct bio *bio) { - return bio->bi_sector >> rh->region_shift; + return (bio->bi_sector - rh->ms->ti->begin) >> rh->region_shift; } static inline sector_t region_to_sector(struct region_hash *rh, region_t region) @@ -223,7 +253,9 @@ 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_NOIO); + nreg = mempool_alloc(rh->region_pool, GFP_ATOMIC); + if (unlikely(!nreg)) + nreg = kmalloc(sizeof(struct region), GFP_NOIO); nreg->state = rh->log->type->in_sync(rh->log, region, 1) ? RH_CLEAN : RH_NOSYNC; nreg->rh = rh; @@ -541,35 +573,6 @@ static void rh_start_recovery(struct region_hash *rh) wake(); } -/*----------------------------------------------------------------- - * Mirror set structures. - *---------------------------------------------------------------*/ -struct mirror { - atomic_t error_count; - struct dm_dev *dev; - sector_t offset; -}; - -struct mirror_set { - struct dm_target *ti; - struct list_head list; - struct region_hash rh; - struct kcopyd_client *kcopyd_client; - - spinlock_t lock; /* protects the next two lists */ - struct bio_list reads; - struct bio_list writes; - - /* recovery */ - region_t nr_regions; - int in_sync; - - struct mirror *default_mirror; /* Default mirror */ - - unsigned int nr_mirrors; - struct mirror mirror[0]; -}; - /* * Every mirror should look like this one. */ @@ -1115,7 +1118,7 @@ static int mirror_map(struct dm_target *ti, struct bio *bio, struct mirror *m; struct mirror_set *ms = ti->private; - map_context->ll = bio->bi_sector >> ms->rh.region_shift; + map_context->ll = bio_to_region(&ms->rh, bio); if (rw == WRITE) { queue_bio(ms, bio, rw); diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index 08312b464..b84bc1aae 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c @@ -530,7 +530,7 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) } ti->private = s; - ti->split_io = chunk_size; + ti->split_io = s->chunk_size; return 0; @@ -1204,7 +1204,7 @@ static int origin_status(struct dm_target *ti, status_type_t type, char *result, static struct target_type origin_target = { .name = "snapshot-origin", - .version = {1, 1, 0}, + .version = {1, 4, 0}, .module = THIS_MODULE, .ctr = origin_ctr, .dtr = origin_dtr, @@ -1215,7 +1215,7 @@ static struct target_type origin_target = { static struct target_type snapshot_target = { .name = "snapshot", - .version = {1, 1, 0}, + .version = {1, 4, 0}, .module = THIS_MODULE, .ctr = snapshot_ctr, .dtr = snapshot_dtr, diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 4d710b7a1..dfd037858 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -26,6 +26,7 @@ static const char *_name = DM_NAME; static unsigned int major = 0; static unsigned int _major = 0; +static DEFINE_SPINLOCK(_minor_lock); /* * One of these is allocated per bio. */ @@ -54,12 +55,15 @@ union map_info *dm_get_mapinfo(struct bio *bio) return NULL; } +#define MINOR_ALLOCED ((void *)-1) + /* * Bits for the md->flags field. */ #define DMF_BLOCK_IO 0 #define DMF_SUSPENDED 1 #define DMF_FROZEN 2 +#define DMF_FREEING 3 struct mapped_device { struct rw_semaphore io_lock; @@ -218,9 +222,23 @@ static int dm_blk_open(struct inode *inode, struct file *file) { struct mapped_device *md; + spin_lock(&_minor_lock); + md = inode->i_bdev->bd_disk->private_data; + if (!md) + goto out; + + if (test_bit(DMF_FREEING, &md->flags)) { + md = NULL; + goto out; + } + dm_get(md); - return 0; + +out: + spin_unlock(&_minor_lock); + + return md ? 0 : -ENXIO; } static int dm_blk_close(struct inode *inode, struct file *file) @@ -744,14 +762,13 @@ static int dm_any_congested(void *congested_data, int bdi_bits) /*----------------------------------------------------------------- * An IDR is used to keep track of allocated minor numbers. *---------------------------------------------------------------*/ -static DEFINE_MUTEX(_minor_lock); static DEFINE_IDR(_minor_idr); static void free_minor(unsigned int minor) { - mutex_lock(&_minor_lock); + spin_lock(&_minor_lock); idr_remove(&_minor_idr, minor); - mutex_unlock(&_minor_lock); + spin_unlock(&_minor_lock); } /* @@ -764,23 +781,20 @@ static int specific_minor(struct mapped_device *md, unsigned int minor) if (minor >= (1 << MINORBITS)) return -EINVAL; - mutex_lock(&_minor_lock); + r = idr_pre_get(&_minor_idr, GFP_KERNEL); + if (!r) + return -ENOMEM; + + spin_lock(&_minor_lock); if (idr_find(&_minor_idr, minor)) { r = -EBUSY; goto out; } - r = idr_pre_get(&_minor_idr, GFP_KERNEL); - if (!r) { - r = -ENOMEM; - goto out; - } - - r = idr_get_new_above(&_minor_idr, md, minor, &m); - if (r) { + r = idr_get_new_above(&_minor_idr, MINOR_ALLOCED, minor, &m); + if (r) goto out; - } if (m != minor) { idr_remove(&_minor_idr, m); @@ -789,7 +803,7 @@ static int specific_minor(struct mapped_device *md, unsigned int minor) } out: - mutex_unlock(&_minor_lock); + spin_unlock(&_minor_lock); return r; } @@ -798,15 +812,13 @@ static int next_free_minor(struct mapped_device *md, unsigned int *minor) int r; unsigned int m; - mutex_lock(&_minor_lock); - r = idr_pre_get(&_minor_idr, GFP_KERNEL); - if (!r) { - r = -ENOMEM; - goto out; - } + if (!r) + return -ENOMEM; - r = idr_get_new(&_minor_idr, md, &m); + spin_lock(&_minor_lock); + + r = idr_get_new(&_minor_idr, MINOR_ALLOCED, &m); if (r) { goto out; } @@ -820,7 +832,7 @@ static int next_free_minor(struct mapped_device *md, unsigned int *minor) *minor = m; out: - mutex_unlock(&_minor_lock); + spin_unlock(&_minor_lock); return r; } @@ -833,12 +845,16 @@ static struct mapped_device *alloc_dev(unsigned int minor, int persistent) { int r; struct mapped_device *md = kmalloc(sizeof(*md), GFP_KERNEL); + void *old_md; if (!md) { DMWARN("unable to allocate device, out of memory."); return NULL; } + if (!try_module_get(THIS_MODULE)) + goto bad0; + /* get a minor number for the dev */ r = persistent ? specific_minor(md, minor) : next_free_minor(md, &minor); if (r < 0) @@ -875,6 +891,10 @@ static struct mapped_device *alloc_dev(unsigned int minor, int persistent) if (!md->disk) goto bad4; + atomic_set(&md->pending, 0); + init_waitqueue_head(&md->wait); + init_waitqueue_head(&md->eventq); + md->disk->major = _major; md->disk->first_minor = minor; md->disk->fops = &dm_blk_dops; @@ -884,9 +904,12 @@ static struct mapped_device *alloc_dev(unsigned int minor, int persistent) add_disk(md->disk); format_dev_t(md->name, MKDEV(_major, minor)); - atomic_set(&md->pending, 0); - init_waitqueue_head(&md->wait); - init_waitqueue_head(&md->eventq); + /* Populate the mapping, nobody knows we exist yet */ + spin_lock(&_minor_lock); + old_md = idr_replace(&_minor_idr, md, minor); + spin_unlock(&_minor_lock); + + BUG_ON(old_md != MINOR_ALLOCED); return md; @@ -898,6 +921,8 @@ static struct mapped_device *alloc_dev(unsigned int minor, int persistent) blk_cleanup_queue(md->queue); free_minor(minor); bad1: + module_put(THIS_MODULE); + bad0: kfree(md); return NULL; } @@ -914,8 +939,14 @@ static void free_dev(struct mapped_device *md) mempool_destroy(md->io_pool); del_gendisk(md->disk); free_minor(minor); + + spin_lock(&_minor_lock); + md->disk->private_data = NULL; + spin_unlock(&_minor_lock); + put_disk(md->disk); blk_cleanup_queue(md->queue); + module_put(THIS_MODULE); kfree(md); } @@ -1015,13 +1046,18 @@ static struct mapped_device *dm_find_md(dev_t dev) if (MAJOR(dev) != _major || minor >= (1 << MINORBITS)) return NULL; - mutex_lock(&_minor_lock); + spin_lock(&_minor_lock); md = idr_find(&_minor_idr, minor); - if (!md || (dm_disk(md)->first_minor != minor)) + if (md && (md == MINOR_ALLOCED || + (dm_disk(md)->first_minor != minor) || + test_bit(DMF_FREEING, &md->flags))) { md = NULL; + goto out; + } - mutex_unlock(&_minor_lock); +out: + spin_unlock(&_minor_lock); return md; } @@ -1055,8 +1091,13 @@ void dm_put(struct mapped_device *md) { struct dm_table *map; - if (atomic_dec_and_test(&md->holders)) { + BUG_ON(test_bit(DMF_FREEING, &md->flags)); + + if (atomic_dec_and_lock(&md->holders, &_minor_lock)) { map = dm_get_table(md); + idr_replace(&_minor_idr, MINOR_ALLOCED, dm_disk(md)->first_minor); + set_bit(DMF_FREEING, &md->flags); + spin_unlock(&_minor_lock); if (!dm_suspended(md)) { dm_table_presuspend_targets(map); dm_table_postsuspend_targets(map); diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 4070eff6f..5a5449400 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -1486,7 +1486,6 @@ 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, @@ -1509,6 +1508,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 { diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.c b/drivers/media/dvb/bt8xx/dvb-bt8xx.c index ccc7b2eb4..0bcaa358c 100644 --- a/drivers/media/dvb/bt8xx/dvb-bt8xx.c +++ b/drivers/media/dvb/bt8xx/dvb-bt8xx.c @@ -184,6 +184,11 @@ static struct mt352_config thomson_dtt7579_config = { .pll_set = thomson_dtt7579_pll_set, }; +static struct zl10353_config thomson_dtt7579_zl10353_config = { + .demod_address = 0x0f, + .pll_set = thomson_dtt7579_pll_set, +}; + static int cx24108_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) { u32 freq = params->frequency; @@ -617,6 +622,11 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type) switch(type) { case BTTV_BOARD_DVICO_DVBT_LITE: card->fe = mt352_attach(&thomson_dtt7579_config, card->i2c_adapter); + + if (card->fe == NULL) + card->fe = zl10353_attach(&thomson_dtt7579_zl10353_config, + card->i2c_adapter); + if (card->fe != NULL) { card->fe->ops->info.frequency_min = 174000000; card->fe->ops->info.frequency_max = 862000000; diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.h b/drivers/media/dvb/bt8xx/dvb-bt8xx.h index 00dd9fa54..e41066ae7 100644 --- a/drivers/media/dvb/bt8xx/dvb-bt8xx.h +++ b/drivers/media/dvb/bt8xx/dvb-bt8xx.h @@ -37,6 +37,7 @@ #include "cx24110.h" #include "or51211.h" #include "lgdt330x.h" +#include "zl10353.h" struct dvb_bt8xx_card { struct mutex lock; diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c index a05179016..cb69372fe 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -519,7 +519,9 @@ static int dvb_frontend_thread(void *data) fepriv->delay = 3*HZ; fepriv->status = 0; fepriv->wakeup = 0; - fepriv->reinitialise = 1; + fepriv->reinitialise = 0; + + dvb_frontend_init(fe); while (1) { up(&fepriv->sem); /* is locked when we enter the thread... */ @@ -996,17 +998,17 @@ static int dvb_frontend_open(struct inode *inode, struct file *file) return ret; if ((file->f_flags & O_ACCMODE) != O_RDONLY) { + /* normal tune mode when opened R/W */ + fepriv->tune_mode_flags &= ~FE_TUNE_MODE_ONESHOT; + fepriv->tone = -1; + fepriv->voltage = -1; + ret = dvb_frontend_start (fe); if (ret) dvb_generic_release (inode, file); /* empty event queue */ fepriv->events.eventr = fepriv->events.eventw = 0; - - /* normal tune mode when opened R/W */ - fepriv->tune_mode_flags &= ~FE_TUNE_MODE_ONESHOT; - fepriv->tone = -1; - fepriv->voltage = -1; } return ret; diff --git a/drivers/media/dvb/dvb-core/dvb_net.c b/drivers/media/dvb/dvb-core/dvb_net.c index 2f0f35811..9fd87521a 100644 --- a/drivers/media/dvb/dvb-core/dvb_net.c +++ b/drivers/media/dvb/dvb-core/dvb_net.c @@ -1052,7 +1052,7 @@ static void wq_set_multicast_list (void *data) dvb_net_feed_stop(dev); priv->rx_mode = RX_MODE_UNI; - spin_lock_bh(&dev->xmit_lock); + netif_tx_lock_bh(dev); if (dev->flags & IFF_PROMISC) { dprintk("%s: promiscuous mode\n", dev->name); @@ -1077,7 +1077,7 @@ static void wq_set_multicast_list (void *data) } } - spin_unlock_bh(&dev->xmit_lock); + netif_tx_unlock_bh(dev); dvb_net_feed_start(dev); } diff --git a/drivers/media/dvb/frontends/dvb-pll.c b/drivers/media/dvb/frontends/dvb-pll.c index 791706ec1..40930a358 100644 --- a/drivers/media/dvb/frontends/dvb-pll.c +++ b/drivers/media/dvb/frontends/dvb-pll.c @@ -194,11 +194,11 @@ struct dvb_pll_desc dvb_pll_tda665x = { { 253834000, 36249333, 166667, 0xca, 0x62 /* 011 0 0 0 10 */ }, { 383834000, 36249333, 166667, 0xca, 0xa2 /* 101 0 0 0 10 */ }, { 443834000, 36249333, 166667, 0xca, 0xc2 /* 110 0 0 0 10 */ }, - { 444000000, 36249333, 166667, 0xca, 0xc3 /* 110 0 0 0 11 */ }, - { 583834000, 36249333, 166667, 0xca, 0x63 /* 011 0 0 0 11 */ }, - { 793834000, 36249333, 166667, 0xca, 0xa3 /* 101 0 0 0 11 */ }, - { 444834000, 36249333, 166667, 0xca, 0xc3 /* 110 0 0 0 11 */ }, - { 861000000, 36249333, 166667, 0xca, 0xe3 /* 111 0 0 0 11 */ }, + { 444000000, 36249333, 166667, 0xca, 0xc4 /* 110 0 0 1 00 */ }, + { 583834000, 36249333, 166667, 0xca, 0x64 /* 011 0 0 1 00 */ }, + { 793834000, 36249333, 166667, 0xca, 0xa4 /* 101 0 0 1 00 */ }, + { 444834000, 36249333, 166667, 0xca, 0xc4 /* 110 0 0 1 00 */ }, + { 861000000, 36249333, 166667, 0xca, 0xe4 /* 111 0 0 1 00 */ }, } }; EXPORT_SYMBOL(dvb_pll_tda665x); diff --git a/drivers/media/dvb/ttpci/budget-av.c b/drivers/media/dvb/ttpci/budget-av.c index 8a7cd7d50..3f4aa083f 100644 --- a/drivers/media/dvb/ttpci/budget-av.c +++ b/drivers/media/dvb/ttpci/budget-av.c @@ -58,6 +58,7 @@ struct budget_av { struct tasklet_struct ciintf_irq_tasklet; int slot_status; struct dvb_ca_en50221 ca; + u8 reinitialise_demod:1; }; /* GPIO Connections: @@ -214,8 +215,9 @@ static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot) while (--timeout > 0 && ciintf_read_attribute_mem(ca, slot, 0) != 0x1d) msleep(100); - /* reinitialise the frontend */ - dvb_frontend_reinitialise(budget_av->budget.dvb_frontend); + /* reinitialise the frontend if necessary */ + if (budget_av->reinitialise_demod) + dvb_frontend_reinitialise(budget_av->budget.dvb_frontend); if (timeout <= 0) { @@ -1017,12 +1019,13 @@ static void frontend_init(struct budget_av *budget_av) struct saa7146_dev * saa = budget_av->budget.dev; struct dvb_frontend * fe = NULL; + /* Enable / PowerON Frontend */ + saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO); + switch (saa->pci->subsystem_device) { case SUBID_DVBS_KNC1_PLUS: case SUBID_DVBC_KNC1_PLUS: case SUBID_DVBT_KNC1_PLUS: - // Enable / PowerON Frontend - saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO); saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTHI); break; } @@ -1059,7 +1062,14 @@ static void frontend_init(struct budget_av *budget_av) break; case SUBID_DVBC_KNC1: + budget_av->reinitialise_demod = 1; + fe = tda10021_attach(&philips_cu1216_config, + &budget_av->budget.i2c_adap, + read_pwm(budget_av)); + break; + case SUBID_DVBC_KNC1_PLUS: + budget_av->reinitialise_demod = 1; fe = tda10021_attach(&philips_cu1216_config, &budget_av->budget.i2c_adap, read_pwm(budget_av)); @@ -1208,11 +1218,7 @@ static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extensio budget_av->budget.dvb_adapter.priv = budget_av; frontend_init(budget_av); - - if (!budget_av->has_saa7113) { - ciintf_init(budget_av); - } - + ciintf_init(budget_av); return 0; } diff --git a/drivers/media/dvb/ttpci/budget.c b/drivers/media/dvb/ttpci/budget.c index 689e97189..d6d37cf02 100644 --- a/drivers/media/dvb/ttpci/budget.c +++ b/drivers/media/dvb/ttpci/budget.c @@ -367,12 +367,6 @@ static void frontend_init(struct budget *budget) // try the ALPS BSRU6 now budget->dvb_frontend = stv0299_attach(&alps_bsru6_config, &budget->i2c_adap); - if (budget->dvb_frontend) { - budget->dvb_frontend->ops->diseqc_send_master_cmd = budget_diseqc_send_master_cmd; - budget->dvb_frontend->ops->diseqc_send_burst = budget_diseqc_send_burst; - budget->dvb_frontend->ops->set_tone = budget_set_tone; - break; - } break; case 0x1004: // Hauppauge/TT DVB-C budget (ves1820/ALPS TDBE2(sp5659)) diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index 6b4197018..67d729a84 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig @@ -380,10 +380,10 @@ config VIDEO_WM8739 source "drivers/media/video/cx25840/Kconfig" config VIDEO_SAA711X - tristate "Philips SAA7113/4/5 video decoders (OBSOLETED)" - depends on VIDEO_V4L1 && I2C && EXPERIMENTAL + tristate "Philips SAA7113/4/5 video decoders" + depends on VIDEO_DEV && I2C && EXPERIMENTAL ---help--- - Old support for the Philips SAA7113/4 video decoders. + Support for the Philips SAA7113/4/5 video decoders. To compile this driver as a module, choose M here: the module will be called saa7115. diff --git a/drivers/media/video/stradis.c b/drivers/media/video/stradis.c index 07476c711..af372dd25 100644 --- a/drivers/media/video/stradis.c +++ b/drivers/media/video/stradis.c @@ -2180,7 +2180,6 @@ static struct pci_device_id stradis_pci_tbl[] = { { 0 } }; -MODULE_DEVICE_TABLE(pci, stradis_pci_tbl); static struct pci_driver stradis_driver = { .name = "stradis", diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c index 066e22b01..365a07494 100644 --- a/drivers/net/8139cp.c +++ b/drivers/net/8139cp.c @@ -792,7 +792,7 @@ static int cp_start_xmit (struct sk_buff *skb, struct net_device *dev) entry = cp->tx_head; eor = (entry == (CP_TX_RING_SIZE - 1)) ? RingEnd : 0; if (dev->features & NETIF_F_TSO) - mss = skb_shinfo(skb)->tso_size; + mss = skb_shinfo(skb)->gso_size; if (skb_shinfo(skb)->nr_frags == 0) { struct cp_desc *txd = &cp->tx_ring[entry]; diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 54161aef3..a8f95e511 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -1638,7 +1638,7 @@ bnx2_tx_int(struct bnx2 *bp) skb = tx_buf->skb; #ifdef BCM_TSO /* partial BD completions possible with TSO packets */ - if (skb_shinfo(skb)->tso_size) { + if (skb_is_gso(skb)) { u16 last_idx, last_ring_idx; last_idx = sw_cons + @@ -2009,7 +2009,7 @@ bnx2_poll(struct net_device *dev, int *budget) return 1; } -/* Called with rtnl_lock from vlan functions and also dev->xmit_lock +/* Called with rtnl_lock from vlan functions and also netif_tx_lock * from set_multicast. */ static void @@ -4252,7 +4252,7 @@ bnx2_vlan_rx_kill_vid(struct net_device *dev, uint16_t vid) } #endif -/* Called with dev->xmit_lock. +/* Called with netif_tx_lock. * hard_start_xmit is pseudo-lockless - a lock is only required when * the tx queue is full. This way, we get the benefit of lockless * operations most of the time without the complexities to handle @@ -4290,7 +4290,7 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev) (TX_BD_FLAGS_VLAN_TAG | (vlan_tx_tag_get(skb) << 16)); } #ifdef BCM_TSO - if ((mss = skb_shinfo(skb)->tso_size) && + if ((mss = skb_shinfo(skb)->gso_size) && (skb->len > (bp->dev->mtu + ETH_HLEN))) { u32 tcp_opt_len, ip_tcp_len; diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 55d236726..8171cae06 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -1199,8 +1199,7 @@ int bond_sethwaddr(struct net_device *bond_dev, struct net_device *slave_dev) } #define BOND_INTERSECT_FEATURES \ - (NETIF_F_SG|NETIF_F_IP_CSUM|NETIF_F_NO_CSUM|NETIF_F_HW_CSUM|\ - NETIF_F_TSO|NETIF_F_UFO) + (NETIF_F_SG | NETIF_F_ALL_CSUM | NETIF_F_TSO | NETIF_F_UFO) /* * Compute the common dev->feature set available to all slaves. Some @@ -1218,9 +1217,7 @@ static int bond_compute_features(struct bonding *bond) features &= (slave->dev->features & BOND_INTERSECT_FEATURES); if ((features & NETIF_F_SG) && - !(features & (NETIF_F_IP_CSUM | - NETIF_F_NO_CSUM | - NETIF_F_HW_CSUM))) + !(features & NETIF_F_ALL_CSUM)) features &= ~NETIF_F_SG; /* @@ -4191,7 +4188,7 @@ static int bond_init(struct net_device *bond_dev, struct bond_params *params) */ bond_dev->features |= NETIF_F_VLAN_CHALLENGED; - /* don't acquire bond device's xmit_lock when + /* don't acquire bond device's netif_tx_lock when * transmitting */ bond_dev->features |= NETIF_F_LLTX; diff --git a/drivers/net/chelsio/sge.c b/drivers/net/chelsio/sge.c index 4391bf4bf..722be62f3 100644 --- a/drivers/net/chelsio/sge.c +++ b/drivers/net/chelsio/sge.c @@ -1418,7 +1418,7 @@ int t1_start_xmit(struct sk_buff *skb, struct net_device *dev) struct cpl_tx_pkt *cpl; #ifdef NETIF_F_TSO - if (skb_shinfo(skb)->tso_size) { + if (skb_is_gso(skb)) { int eth_type; struct cpl_tx_pkt_lso *hdr; @@ -1433,7 +1433,7 @@ int t1_start_xmit(struct sk_buff *skb, struct net_device *dev) hdr->ip_hdr_words = skb->nh.iph->ihl; hdr->tcp_hdr_words = skb->h.th->doff; hdr->eth_type_mss = htons(MK_ETH_TYPE_MSS(eth_type, - skb_shinfo(skb)->tso_size)); + skb_shinfo(skb)->gso_size)); hdr->len = htonl(skb->len - sizeof(*hdr)); cpl = (struct cpl_tx_pkt *)hdr; sge->stats.tx_lso_pkts++; diff --git a/drivers/net/e1000/e1000_hw.c b/drivers/net/e1000/e1000_hw.c index 523c2c9fc..c5e702349 100644 --- a/drivers/net/e1000/e1000_hw.c +++ b/drivers/net/e1000/e1000_hw.c @@ -353,6 +353,7 @@ e1000_set_mac_type(struct e1000_hw *hw) case E1000_DEV_ID_82572EI_COPPER: case E1000_DEV_ID_82572EI_FIBER: case E1000_DEV_ID_82572EI_SERDES: + case E1000_DEV_ID_82572EI: hw->mac_type = e1000_82572; break; case E1000_DEV_ID_82573E: diff --git a/drivers/net/e1000/e1000_hw.h b/drivers/net/e1000/e1000_hw.h index 150e45e30..c01e5d2e5 100644 --- a/drivers/net/e1000/e1000_hw.h +++ b/drivers/net/e1000/e1000_hw.h @@ -462,6 +462,7 @@ int32_t e1000_check_phy_reset_block(struct e1000_hw *hw); #define E1000_DEV_ID_82572EI_COPPER 0x107D #define E1000_DEV_ID_82572EI_FIBER 0x107E #define E1000_DEV_ID_82572EI_SERDES 0x107F +#define E1000_DEV_ID_82572EI 0x10B9 #define E1000_DEV_ID_82573E 0x108B #define E1000_DEV_ID_82573E_IAMT 0x108C #define E1000_DEV_ID_82573L 0x109A diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 97e71a4fe..43e647284 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -2413,7 +2413,7 @@ e1000_tso(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring, uint8_t ipcss, ipcso, tucss, tucso, hdr_len; int err; - if (skb_shinfo(skb)->tso_size) { + if (skb_is_gso(skb)) { if (skb_header_cloned(skb)) { err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC); if (err) @@ -2421,7 +2421,7 @@ e1000_tso(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring, } hdr_len = ((skb->h.raw - skb->data) + (skb->h.th->doff << 2)); - mss = skb_shinfo(skb)->tso_size; + mss = skb_shinfo(skb)->gso_size; if (skb->protocol == ntohs(ETH_P_IP)) { skb->nh.iph->tot_len = 0; skb->nh.iph->check = 0; @@ -2538,7 +2538,7 @@ e1000_tx_map(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring, * tso gets written back prematurely before the data is fully * DMA'd to the controller */ if (!skb->data_len && tx_ring->last_tx_tso && - !skb_shinfo(skb)->tso_size) { + !skb_is_gso(skb)) { tx_ring->last_tx_tso = 0; size -= 4; } @@ -2776,7 +2776,7 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev) } #ifdef NETIF_F_TSO - mss = skb_shinfo(skb)->tso_size; + mss = skb_shinfo(skb)->gso_size; /* The controller does a simple calculation to * make sure there is enough room in the FIFO before * initiating the DMA for each buffer. The calc is: @@ -2825,8 +2825,7 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev) #ifdef NETIF_F_TSO /* Controller Erratum workaround */ - if (!skb->data_len && tx_ring->last_tx_tso && - !skb_shinfo(skb)->tso_size) + if (!skb->data_len && tx_ring->last_tx_tso && !skb_is_gso(skb)) count++; #endif diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index feb5b223c..1a556957d 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c @@ -533,9 +533,9 @@ typedef union _ring_type { * critical parts: * - rx is (pseudo-) lockless: it relies on the single-threading provided * by the arch code for interrupts. - * - tx setup is lockless: it relies on dev->xmit_lock. Actual submission + * - tx setup is lockless: it relies on netif_tx_lock. Actual submission * needs dev->priv->lock :-( - * - set_multicast_list: preparation lockless, relies on dev->xmit_lock. + * - set_multicast_list: preparation lockless, relies on netif_tx_lock. */ /* in dev: base, irq */ @@ -1213,7 +1213,7 @@ static void drain_ring(struct net_device *dev) /* * nv_start_xmit: dev->hard_start_xmit function - * Called with dev->xmit_lock held. + * Called with netif_tx_lock held. */ static int nv_start_xmit(struct sk_buff *skb, struct net_device *dev) { @@ -1303,8 +1303,8 @@ static int nv_start_xmit(struct sk_buff *skb, struct net_device *dev) np->tx_skbuff[nr] = skb; #ifdef NETIF_F_TSO - if (skb_shinfo(skb)->tso_size) - tx_flags_extra = NV_TX2_TSO | (skb_shinfo(skb)->tso_size << NV_TX2_TSO_SHIFT); + if (skb_is_gso(skb)) + tx_flags_extra = NV_TX2_TSO | (skb_shinfo(skb)->gso_size << NV_TX2_TSO_SHIFT); else #endif tx_flags_extra = (skb->ip_summed == CHECKSUM_HW ? (NV_TX2_CHECKSUM_L3|NV_TX2_CHECKSUM_L4) : 0); @@ -1407,7 +1407,7 @@ static void nv_tx_done(struct net_device *dev) /* * nv_tx_timeout: dev->tx_timeout function - * Called with dev->xmit_lock held. + * Called with netif_tx_lock held. */ static void nv_tx_timeout(struct net_device *dev) { @@ -1736,8 +1736,8 @@ static int nv_change_mtu(struct net_device *dev, int new_mtu) * guessed, there is probably a simpler approach. * Changing the MTU is a rare event, it shouldn't matter. */ - nv_disable_irq(dev); - spin_lock_bh(&dev->xmit_lock); + disable_irq(dev->irq); + netif_tx_lock_bh(dev); spin_lock(&np->lock); /* stop engines */ nv_stop_rx(dev); @@ -1768,8 +1768,8 @@ static int nv_change_mtu(struct net_device *dev, int new_mtu) nv_start_rx(dev); nv_start_tx(dev); spin_unlock(&np->lock); - spin_unlock_bh(&dev->xmit_lock); - nv_enable_irq(dev); + netif_tx_unlock_bh(dev); + enable_irq(dev->irq); } return 0; } @@ -1803,7 +1803,7 @@ static int nv_set_mac_address(struct net_device *dev, void *addr) memcpy(dev->dev_addr, macaddr->sa_data, ETH_ALEN); if (netif_running(dev)) { - spin_lock_bh(&dev->xmit_lock); + netif_tx_lock_bh(dev); spin_lock_irq(&np->lock); /* stop rx engine */ @@ -1815,7 +1815,7 @@ static int nv_set_mac_address(struct net_device *dev, void *addr) /* restart rx engine */ nv_start_rx(dev); spin_unlock_irq(&np->lock); - spin_unlock_bh(&dev->xmit_lock); + netif_tx_unlock_bh(dev); } else { nv_copy_mac_to_hw(dev); } @@ -1824,7 +1824,7 @@ static int nv_set_mac_address(struct net_device *dev, void *addr) /* * nv_set_multicast: dev->set_multicast function - * Called with dev->xmit_lock held. + * Called with netif_tx_lock held. */ static void nv_set_multicast(struct net_device *dev) { diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c index 102c1f0b9..d12605f0a 100644 --- a/drivers/net/hamradio/6pack.c +++ b/drivers/net/hamradio/6pack.c @@ -308,9 +308,9 @@ static int sp_set_mac_address(struct net_device *dev, void *addr) { struct sockaddr_ax25 *sa = addr; - spin_lock_irq(&dev->xmit_lock); + netif_tx_lock_bh(dev); memcpy(dev->dev_addr, &sa->sax25_call, AX25_ADDR_LEN); - spin_unlock_irq(&dev->xmit_lock); + netif_tx_unlock_bh(dev); return 0; } @@ -767,9 +767,9 @@ static int sixpack_ioctl(struct tty_struct *tty, struct file *file, break; } - spin_lock_irq(&dev->xmit_lock); + netif_tx_lock_bh(dev); memcpy(dev->dev_addr, &addr, AX25_ADDR_LEN); - spin_unlock_irq(&dev->xmit_lock); + netif_tx_unlock_bh(dev); err = 0; break; diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c index d81a8e1ee..3ebbbe56b 100644 --- a/drivers/net/hamradio/mkiss.c +++ b/drivers/net/hamradio/mkiss.c @@ -357,9 +357,9 @@ static int ax_set_mac_address(struct net_device *dev, void *addr) { struct sockaddr_ax25 *sa = addr; - spin_lock_irq(&dev->xmit_lock); + netif_tx_lock_bh(dev); memcpy(dev->dev_addr, &sa->sax25_call, AX25_ADDR_LEN); - spin_unlock_irq(&dev->xmit_lock); + netif_tx_unlock_bh(dev); return 0; } @@ -886,9 +886,9 @@ static int mkiss_ioctl(struct tty_struct *tty, struct file *file, break; } - spin_lock_irq(&dev->xmit_lock); + netif_tx_lock_bh(dev); memcpy(dev->dev_addr, addr, AX25_ADDR_LEN); - spin_unlock_irq(&dev->xmit_lock); + netif_tx_unlock_bh(dev); err = 0; break; diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c index 31fb2d75d..2e222ef91 100644 --- a/drivers/net/ifb.c +++ b/drivers/net/ifb.c @@ -76,13 +76,13 @@ static void ri_tasklet(unsigned long dev) dp->st_task_enter++; if ((skb = skb_peek(&dp->tq)) == NULL) { dp->st_txq_refl_try++; - if (spin_trylock(&_dev->xmit_lock)) { + if (netif_tx_trylock(_dev)) { dp->st_rxq_enter++; while ((skb = skb_dequeue(&dp->rq)) != NULL) { skb_queue_tail(&dp->tq, skb); dp->st_rx2tx_tran++; } - spin_unlock(&_dev->xmit_lock); + netif_tx_unlock(_dev); } else { /* reschedule */ dp->st_rxq_notenter++; @@ -110,7 +110,7 @@ static void ri_tasklet(unsigned long dev) } } - if (spin_trylock(&_dev->xmit_lock)) { + if (netif_tx_trylock(_dev)) { dp->st_rxq_check++; if ((skb = skb_peek(&dp->rq)) == NULL) { dp->tasklet_pending = 0; @@ -118,10 +118,10 @@ static void ri_tasklet(unsigned long dev) netif_wake_queue(_dev); } else { dp->st_rxq_rsch++; - spin_unlock(&_dev->xmit_lock); + netif_tx_unlock(_dev); goto resched; } - spin_unlock(&_dev->xmit_lock); + netif_tx_unlock(_dev); } else { resched: dp->tasklet_pending = 1; diff --git a/drivers/net/irda/vlsi_ir.c b/drivers/net/irda/vlsi_ir.c index 97a49e0be..d70b9e8d6 100644 --- a/drivers/net/irda/vlsi_ir.c +++ b/drivers/net/irda/vlsi_ir.c @@ -959,7 +959,7 @@ static int vlsi_hard_start_xmit(struct sk_buff *skb, struct net_device *ndev) || (now.tv_sec==ready.tv_sec && now.tv_usec>=ready.tv_usec)) break; udelay(100); - /* must not sleep here - we are called under xmit_lock! */ + /* must not sleep here - called under netif_tx_lock! */ } } diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c index cfd67d812..83852450a 100644 --- a/drivers/net/ixgb/ixgb_main.c +++ b/drivers/net/ixgb/ixgb_main.c @@ -1168,7 +1168,7 @@ ixgb_tso(struct ixgb_adapter *adapter, struct sk_buff *skb) uint16_t ipcse, tucse, mss; int err; - if(likely(skb_shinfo(skb)->tso_size)) { + if (likely(skb_is_gso(skb))) { if (skb_header_cloned(skb)) { err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC); if (err) @@ -1176,7 +1176,7 @@ ixgb_tso(struct ixgb_adapter *adapter, struct sk_buff *skb) } hdr_len = ((skb->h.raw - skb->data) + (skb->h.th->doff << 2)); - mss = skb_shinfo(skb)->tso_size; + mss = skb_shinfo(skb)->gso_size; skb->nh.iph->tot_len = 0; skb->nh.iph->check = 0; skb->h.th->check = ~csum_tcpudp_magic(skb->nh.iph->saddr, diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c index b79d6e8d3..997cbce9a 100644 --- a/drivers/net/loopback.c +++ b/drivers/net/loopback.c @@ -74,7 +74,7 @@ static void emulate_large_send_offload(struct sk_buff *skb) struct iphdr *iph = skb->nh.iph; struct tcphdr *th = (struct tcphdr*)(skb->nh.raw + (iph->ihl * 4)); unsigned int doffset = (iph->ihl + th->doff) * 4; - unsigned int mtu = skb_shinfo(skb)->tso_size + doffset; + unsigned int mtu = skb_shinfo(skb)->gso_size + doffset; unsigned int offset = 0; u32 seq = ntohl(th->seq); u16 id = ntohs(iph->id); @@ -139,7 +139,7 @@ static int loopback_xmit(struct sk_buff *skb, struct net_device *dev) #endif #ifdef LOOPBACK_TSO - if (skb_shinfo(skb)->tso_size) { + if (skb_is_gso(skb)) { BUG_ON(skb->protocol != htons(ETH_P_IP)); BUG_ON(skb->nh.iph->protocol != IPPROTO_TCP); diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index 411f4d809..625ff61c9 100644 --- a/drivers/net/mv643xx_eth.c +++ b/drivers/net/mv643xx_eth.c @@ -1200,7 +1200,7 @@ static int mv643xx_eth_start_xmit(struct sk_buff *skb, struct net_device *dev) } if (has_tiny_unaligned_frags(skb)) { - if ((skb_linearize(skb, GFP_ATOMIC) != 0)) { + if (__skb_linearize(skb)) { stats->tx_dropped++; printk(KERN_DEBUG "%s: failed to linearize tiny " "unaligned fragment\n", dev->name); diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c index 90627756d..2e4ecedba 100644 --- a/drivers/net/natsemi.c +++ b/drivers/net/natsemi.c @@ -318,12 +318,12 @@ performance critical codepaths: The rx process only runs in the interrupt handler. Access from outside the interrupt handler is only permitted after disable_irq(). -The rx process usually runs under the dev->xmit_lock. If np->intr_tx_reap +The rx process usually runs under the netif_tx_lock. If np->intr_tx_reap is set, then access is permitted under spin_lock_irq(&np->lock). Thus configuration functions that want to access everything must call disable_irq(dev->irq); - spin_lock_bh(dev->xmit_lock); + netif_tx_lock_bh(dev); spin_lock_irq(&np->lock); IV. Notes diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 0ad331029..43641dd2c 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -2171,7 +2171,7 @@ static int rtl8169_xmit_frags(struct rtl8169_private *tp, struct sk_buff *skb, static inline u32 rtl8169_tso_csum(struct sk_buff *skb, struct net_device *dev) { if (dev->features & NETIF_F_TSO) { - u32 mss = skb_shinfo(skb)->tso_size; + u32 mss = skb_shinfo(skb)->gso_size; if (mss) return LargeSend | ((mss & MSSMask) << MSSShift); diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index 79208f434..0ad01f07e 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -3564,8 +3564,8 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) txdp->Control_1 = 0; txdp->Control_2 = 0; #ifdef NETIF_F_TSO - mss = skb_shinfo(skb)->tso_size; - if (mss) { + mss = skb_shinfo(skb)->gso_size; + if (skb_shinfo(skb)->gso_type == SKB_GSO_TCPV4) { txdp->Control_1 |= TXD_TCP_LSO_EN; txdp->Control_1 |= TXD_TCP_LSO_MSS(mss); } @@ -3585,10 +3585,10 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) } frg_len = skb->len - skb->data_len; - if (skb_shinfo(skb)->ufo_size) { + if (skb_shinfo(skb)->gso_type == SKB_GSO_UDPV4) { int ufo_size; - ufo_size = skb_shinfo(skb)->ufo_size; + ufo_size = skb_shinfo(skb)->gso_size; ufo_size &= ~7; txdp->Control_1 |= TXD_UFO_EN; txdp->Control_1 |= TXD_UFO_MSS(ufo_size); @@ -3614,7 +3614,7 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) txdp->Host_Control = (unsigned long) skb; txdp->Control_1 |= TXD_BUFFER0_SIZE(frg_len); - if (skb_shinfo(skb)->ufo_size) + if (skb_shinfo(skb)->gso_type == SKB_GSO_UDPV4) txdp->Control_1 |= TXD_UFO_EN; frg_cnt = skb_shinfo(skb)->nr_frags; @@ -3629,12 +3629,12 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) (sp->pdev, frag->page, frag->page_offset, frag->size, PCI_DMA_TODEVICE); txdp->Control_1 = TXD_BUFFER0_SIZE(frag->size); - if (skb_shinfo(skb)->ufo_size) + if (skb_shinfo(skb)->gso_type == SKB_GSO_UDPV4) txdp->Control_1 |= TXD_UFO_EN; } txdp->Control_1 |= TXD_GATHER_CODE_LAST; - if (skb_shinfo(skb)->ufo_size) + if (skb_shinfo(skb)->gso_type == SKB_GSO_UDPV4) frg_cnt++; /* as Txd0 was used for inband header */ tx_fifo = mac_control->tx_FIFO_start[queue]; @@ -3648,7 +3648,7 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) if (mss) val64 |= TX_FIFO_SPECIAL_FUNC; #endif - if (skb_shinfo(skb)->ufo_size) + if (skb_shinfo(skb)->gso_type == SKB_GSO_UDPV4) val64 |= TX_FIFO_SPECIAL_FUNC; writeq(val64, &tx_fifo->List_Control); diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index fba1e4d4d..4103e304f 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -51,7 +51,7 @@ #include "sky2.h" #define DRV_NAME "sky2" -#define DRV_VERSION "1.4" +#define DRV_VERSION "1.6.1" #define PFX DRV_NAME " " /* @@ -233,6 +233,8 @@ static void sky2_set_power_state(struct sky2_hw *hw, pci_power_t state) if (hw->ports > 1) reg1 |= PCI_Y2_PHY2_COMA; } + sky2_pci_write32(hw, PCI_DEV_REG1, reg1); + udelay(100); if (hw->chip_id == CHIP_ID_YUKON_EC_U) { sky2_write16(hw, B0_CTST, Y2_HW_WOL_ON); @@ -243,8 +245,6 @@ 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); - break; case PCI_D3hot: @@ -321,7 +321,7 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port) } ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL); - if (hw->copper) { + if (sky2_is_copper(hw)) { if (hw->chip_id == CHIP_ID_YUKON_FE) { /* enable automatic crossover */ ctrl |= PHY_M_PC_MDI_XMODE(PHY_M_PC_ENA_AUTO) >> 1; @@ -338,25 +338,37 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port) ctrl |= PHY_M_PC_DSC(2) | PHY_M_PC_DOWN_S_ENA; } } - gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl); } else { /* workaround for deviation #4.88 (CRC errors) */ /* disable Automatic Crossover */ ctrl &= ~PHY_M_PC_MDIX_MSK; - gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl); + } - if (hw->chip_id == CHIP_ID_YUKON_XL) { - /* Fiber: select 1000BASE-X only mode MAC Specific Ctrl Reg. */ - gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 2); - ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL); - ctrl &= ~PHY_M_MAC_MD_MSK; - ctrl |= PHY_M_MAC_MODE_SEL(PHY_M_MAC_MD_1000BX); - gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl); + gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl); + /* special setup for PHY 88E1112 Fiber */ + if (hw->chip_id == CHIP_ID_YUKON_XL && !sky2_is_copper(hw)) { + pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR); + + /* Fiber: select 1000BASE-X only mode MAC Specific Ctrl Reg. */ + gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 2); + ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL); + ctrl &= ~PHY_M_MAC_MD_MSK; + ctrl |= PHY_M_MAC_MODE_SEL(PHY_M_MAC_MD_1000BX); + gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl); + + if (hw->pmd_type == 'P') { /* select page 1 to access Fiber registers */ gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 1); + + /* for SFP-module set SIGDET polarity to low */ + ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL); + ctrl |= PHY_M_FIB_SIGD_POL; + gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl); } + + gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg); } ctrl = gm_phy_read(hw, port, PHY_MARV_CTRL); @@ -373,7 +385,7 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port) adv = PHY_AN_CSMA; if (sky2->autoneg == AUTONEG_ENABLE) { - if (hw->copper) { + if (sky2_is_copper(hw)) { if (sky2->advertising & ADVERTISED_1000baseT_Full) ct1000 |= PHY_M_1000C_AFD; if (sky2->advertising & ADVERTISED_1000baseT_Half) @@ -386,8 +398,12 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port) adv |= PHY_M_AN_10_FD; if (sky2->advertising & ADVERTISED_10baseT_Half) adv |= PHY_M_AN_10_HD; - } else /* special defines for FIBER (88E1011S only) */ - adv |= PHY_M_AN_1000X_AHD | PHY_M_AN_1000X_AFD; + } else { /* special defines for FIBER (88E1040S only) */ + if (sky2->advertising & ADVERTISED_1000baseT_Full) + adv |= PHY_M_AN_1000X_AFD; + if (sky2->advertising & ADVERTISED_1000baseT_Half) + adv |= PHY_M_AN_1000X_AHD; + } /* Set Flow-control capabilities */ if (sky2->tx_pause && sky2->rx_pause) @@ -949,14 +965,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 aligned. ALso alloc_skb() won't align properly if slab + * is not aligned. Also dev_alloc_skb() won't align properly if slab * debugging is enabled. */ static inline struct sk_buff *sky2_alloc_skb(unsigned int size, gfp_t gfp_mask) { struct sk_buff *skb; - skb = alloc_skb(size + RX_SKB_ALIGN, gfp_mask); + skb = __dev_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); @@ -1160,7 +1176,7 @@ static unsigned tx_le_req(const struct sk_buff *skb) count = sizeof(dma_addr_t) / sizeof(u32); count += skb_shinfo(skb)->nr_frags * count; - if (skb_shinfo(skb)->tso_size) + if (skb_is_gso(skb)) ++count; if (skb->ip_summed == CHECKSUM_HW) @@ -1232,7 +1248,7 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev) } /* Check for TCP Segmentation Offload */ - mss = skb_shinfo(skb)->tso_size; + mss = skb_shinfo(skb)->gso_size; if (mss != 0) { /* just drop the packet if non-linear expansion fails */ if (skb_header_cloned(skb) && @@ -1497,7 +1513,7 @@ static int sky2_down(struct net_device *dev) static u16 sky2_phy_speed(const struct sky2_hw *hw, u16 aux) { - if (!hw->copper) + if (!sky2_is_copper(hw)) return SPEED_1000; if (hw->chip_id == CHIP_ID_YUKON_FE) @@ -1855,7 +1871,7 @@ static struct sk_buff *sky2_receive(struct sky2_port *sky2, goto oversize; if (length < copybreak) { - skb = alloc_skb(length + 2, GFP_ATOMIC); + skb = dev_alloc_skb(length + 2); if (!skb) goto resubmit; @@ -2016,6 +2032,9 @@ 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: return work_done; } @@ -2187,9 +2206,6 @@ static int sky2_poll(struct net_device *dev0, int *budget) int work_done = 0; u32 status = sky2_read32(hw, B0_Y2_SP_EISR); - if (!~status) - goto out; - if (status & Y2_IS_HW_ERR) sky2_hw_intr(hw); @@ -2221,12 +2237,9 @@ static int sky2_poll(struct net_device *dev0, int *budget) *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; -out: + netif_rx_complete(dev0); sky2_read32(hw, B0_Y2_SP_LISR); @@ -2290,7 +2303,7 @@ static inline u32 sky2_clk2us(const struct sky2_hw *hw, u32 clk) static int __devinit sky2_reset(struct sky2_hw *hw) { u16 status; - u8 t8, pmd_type; + u8 t8; int i; sky2_write8(hw, B0_CTST, CS_RST_CLR); @@ -2336,9 +2349,7 @@ static int __devinit sky2_reset(struct sky2_hw *hw) sky2_pci_write32(hw, PEX_UNC_ERR_STAT, 0xffffffffUL); - pmd_type = sky2_read8(hw, B2_PMD_TYP); - hw->copper = !(pmd_type == 'L' || pmd_type == 'S'); - + hw->pmd_type = sky2_read8(hw, B2_PMD_TYP); hw->ports = 1; t8 = sky2_read8(hw, B2_Y2_HW_RES); if ((t8 & CFG_DUAL_MAC_MSK) == CFG_DUAL_MAC_MSK) { @@ -2435,21 +2446,22 @@ static int __devinit sky2_reset(struct sky2_hw *hw) static u32 sky2_supported_modes(const struct sky2_hw *hw) { - u32 modes; - if (hw->copper) { - modes = SUPPORTED_10baseT_Half - | SUPPORTED_10baseT_Full - | SUPPORTED_100baseT_Half - | SUPPORTED_100baseT_Full - | SUPPORTED_Autoneg | SUPPORTED_TP; + if (sky2_is_copper(hw)) { + u32 modes = SUPPORTED_10baseT_Half + | SUPPORTED_10baseT_Full + | SUPPORTED_100baseT_Half + | SUPPORTED_100baseT_Full + | SUPPORTED_Autoneg | SUPPORTED_TP; if (hw->chip_id != CHIP_ID_YUKON_FE) modes |= SUPPORTED_1000baseT_Half - | SUPPORTED_1000baseT_Full; + | SUPPORTED_1000baseT_Full; + return modes; } else - modes = SUPPORTED_1000baseT_Full | SUPPORTED_FIBRE - | SUPPORTED_Autoneg; - return modes; + return SUPPORTED_1000baseT_Half + | SUPPORTED_1000baseT_Full + | SUPPORTED_Autoneg + | SUPPORTED_FIBRE; } static int sky2_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) @@ -2460,7 +2472,7 @@ static int sky2_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) ecmd->transceiver = XCVR_INTERNAL; ecmd->supported = sky2_supported_modes(hw); ecmd->phy_address = PHY_ADDR_MARV; - if (hw->copper) { + if (sky2_is_copper(hw)) { ecmd->supported = SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | SUPPORTED_100baseT_Half @@ -2469,12 +2481,14 @@ static int sky2_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) | SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg | SUPPORTED_TP; ecmd->port = PORT_TP; - } else + ecmd->speed = sky2->speed; + } else { + ecmd->speed = SPEED_1000; ecmd->port = PORT_FIBRE; + } ecmd->advertising = sky2->advertising; ecmd->autoneg = sky2->autoneg; - ecmd->speed = sky2->speed; ecmd->duplex = sky2->duplex; return 0; } @@ -3187,6 +3201,8 @@ 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, SA_SHIRQ, DRV_NAME, hw); @@ -3196,10 +3212,8 @@ 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); - wmb(); + sky2_read8(hw, B0_CTST); wait_event_timeout(hw->msi_wait, hw->msi_detected, HZ/10); diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h index 8a0bc5525..9516c1f39 100644 --- a/drivers/net/sky2.h +++ b/drivers/net/sky2.h @@ -1317,6 +1317,14 @@ enum { PHY_M_FESC_SEL_CL_A = 1<<0, /* Select Class A driver (100B-TX) */ }; +/* for Yukon-2 Gigabit Ethernet PHY (88E1112 only) */ +/***** PHY_MARV_PHY_CTRL (page 1) 16 bit r/w Fiber Specific Ctrl *****/ +enum { + PHY_M_FIB_FORCE_LNK = 1<<10,/* Force Link Good */ + PHY_M_FIB_SIGD_POL = 1<<9, /* SIGDET Polarity */ + PHY_M_FIB_TX_DIS = 1<<3, /* Transmitter Disable */ +}; + /* for Yukon-2 Gigabit Ethernet PHY (88E1112 only) */ /***** PHY_MARV_PHY_CTRL (page 2) 16 bit r/w MAC Specific Ctrl *****/ enum { @@ -1566,7 +1574,7 @@ enum { GMR_FS_ANY_ERR = GMR_FS_RX_FF_OV | GMR_FS_CRC_ERR | GMR_FS_FRAGMENT | GMR_FS_LONG_ERR | - GMR_FS_MII_ERR | GMR_FS_BAD_FC | GMR_FS_GOOD_FC | + GMR_FS_MII_ERR | GMR_FS_BAD_FC | GMR_FS_UN_SIZE | GMR_FS_JABBER, }; @@ -1879,7 +1887,7 @@ struct sky2_hw { int pm_cap; u8 chip_id; u8 chip_rev; - u8 copper; + u8 pmd_type; u8 ports; struct sky2_status_le *st_le; @@ -1891,6 +1899,11 @@ struct sky2_hw { wait_queue_head_t msi_wait; }; +static inline int sky2_is_copper(const struct sky2_hw *hw) +{ + return !(hw->pmd_type == 'L' || hw->pmd_type == 'S' || hw->pmd_type == 'P'); +} + /* Register accessor for memory mapped device */ static inline u32 sky2_read32(const struct sky2_hw *hw, unsigned reg) { diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 862c226db..09a6b8e6d 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -69,8 +69,8 @@ #define DRV_MODULE_NAME "tg3" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "3.59" -#define DRV_MODULE_RELDATE "June 8, 2006" +#define DRV_MODULE_VERSION "3.59.1" +#define DRV_MODULE_RELDATE "August 25, 2006" #define TG3_DEF_MAC_MODE 0 #define TG3_DEF_RX_MODE 0 @@ -3743,7 +3743,7 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) #if TG3_TSO_SUPPORT != 0 mss = 0; if (skb->len > (tp->dev->mtu + ETH_HLEN) && - (mss = skb_shinfo(skb)->tso_size) != 0) { + (mss = skb_shinfo(skb)->gso_size) != 0) { int tcp_opt_len, ip_tcp_len; if (skb_header_cloned(skb) && @@ -3871,7 +3871,7 @@ static int tg3_start_xmit_dma_bug(struct sk_buff *skb, struct net_device *dev) #if TG3_TSO_SUPPORT != 0 mss = 0; if (skb->len > (tp->dev->mtu + ETH_HLEN) && - (mss = skb_shinfo(skb)->tso_size) != 0) { + (mss = skb_shinfo(skb)->gso_size) != 0) { int tcp_opt_len, ip_tcp_len; if (skb_header_cloned(skb) && @@ -11381,11 +11381,15 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, tp->tg3_flags2 |= TG3_FLG2_TSO_CAPABLE; } - /* TSO is on by default on chips that support hardware TSO. + /* TSO is on by default on chips that support HW_TSO_2. + * Some HW_TSO_1 capable chips have bugs that can lead to + * tx timeouts in some cases when TSO is enabled. * Firmware TSO on older chips gives lower performance, so it * is off by default, but can be enabled using ethtool. */ - if (tp->tg3_flags2 & TG3_FLG2_HW_TSO) + if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO_2) || + (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750 && + tp->pci_chip_rev_id >= CHIPREV_ID_5750_C2)) dev->features |= NETIF_F_TSO; #endif diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index ff0faab94..cd68f4688 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -125,6 +125,7 @@ #define CHIPREV_ID_5750_A0 0x4000 #define CHIPREV_ID_5750_A1 0x4001 #define CHIPREV_ID_5750_A3 0x4003 +#define CHIPREV_ID_5750_C2 0x4202 #define CHIPREV_ID_5752_A0_HW 0x5000 #define CHIPREV_ID_5752_A0 0x6000 #define CHIPREV_ID_5752_A1 0x6001 diff --git a/drivers/net/tulip/winbond-840.c b/drivers/net/tulip/winbond-840.c index 136a70c4d..56d86c7c0 100644 --- a/drivers/net/tulip/winbond-840.c +++ b/drivers/net/tulip/winbond-840.c @@ -1605,11 +1605,11 @@ static void __devexit w840_remove1 (struct pci_dev *pdev) * - get_stats: * spin_lock_irq(np->lock), doesn't touch hw if not present * - hard_start_xmit: - * netif_stop_queue + spin_unlock_wait(&dev->xmit_lock); + * synchronize_irq + netif_tx_disable; * - tx_timeout: - * netif_device_detach + spin_unlock_wait(&dev->xmit_lock); + * netif_device_detach + netif_tx_disable; * - set_multicast_list - * netif_device_detach + spin_unlock_wait(&dev->xmit_lock); + * netif_device_detach + netif_tx_disable; * - interrupt handler * doesn't touch hw if not present, synchronize_irq waits for * running instances of the interrupt handler. @@ -1635,11 +1635,10 @@ static int w840_suspend (struct pci_dev *pdev, pm_message_t state) netif_device_detach(dev); update_csr6(dev, 0); iowrite32(0, ioaddr + IntrEnable); - netif_stop_queue(dev); spin_unlock_irq(&np->lock); - spin_unlock_wait(&dev->xmit_lock); synchronize_irq(dev->irq); + netif_tx_disable(dev); np->stats.rx_missed_errors += ioread32(ioaddr + RxMissed) & 0xffff; diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c index d9258d420..389d19fb5 100644 --- a/drivers/net/typhoon.c +++ b/drivers/net/typhoon.c @@ -340,7 +340,7 @@ enum state_values { #endif #if defined(NETIF_F_TSO) -#define skb_tso_size(x) (skb_shinfo(x)->tso_size) +#define skb_tso_size(x) (skb_shinfo(x)->gso_size) #define TSO_NUM_DESCRIPTORS 2 #define TSO_OFFLOAD_ON TYPHOON_OFFLOAD_TCP_SEGMENT #else @@ -805,7 +805,7 @@ typhoon_start_tx(struct sk_buff *skb, struct net_device *dev) * If problems develop with TSO, check this first. */ numDesc = skb_shinfo(skb)->nr_frags + 1; - if(skb_tso_size(skb)) + if (skb_is_gso(skb)) numDesc++; /* When checking for free space in the ring, we need to also @@ -845,7 +845,7 @@ typhoon_start_tx(struct sk_buff *skb, struct net_device *dev) TYPHOON_TX_PF_VLAN_TAG_SHIFT); } - if(skb_tso_size(skb)) { + if (skb_is_gso(skb)) { first_txd->processFlags |= TYPHOON_TX_PF_TCP_SEGMENT; first_txd->numDesc++; diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c index ed1f837c8..09e05fe40 100644 --- a/drivers/net/via-velocity.c +++ b/drivers/net/via-velocity.c @@ -248,6 +248,7 @@ static void velocity_free_rd_ring(struct velocity_info *vptr); static void velocity_free_tx_buf(struct velocity_info *vptr, struct velocity_td_info *); static int velocity_soft_reset(struct velocity_info *vptr); static void mii_init(struct velocity_info *vptr, u32 mii_status); +static u32 velocity_get_link(struct net_device *dev); static u32 velocity_get_opt_media_mode(struct velocity_info *vptr); static void velocity_print_link_status(struct velocity_info *vptr); static void safe_disable_mii_autopoll(struct mac_regs __iomem * regs); @@ -798,6 +799,9 @@ static int __devinit velocity_found1(struct pci_dev *pdev, const struct pci_devi if (ret < 0) goto err_iounmap; + if (velocity_get_link(dev)) + netif_carrier_off(dev); + velocity_print_info(vptr); pci_set_drvdata(pdev, dev); @@ -1653,8 +1657,10 @@ static void velocity_error(struct velocity_info *vptr, int status) if (linked) { vptr->mii_status &= ~VELOCITY_LINK_FAIL; + netif_carrier_on(vptr->dev); } else { vptr->mii_status |= VELOCITY_LINK_FAIL; + netif_carrier_off(vptr->dev); } velocity_print_link_status(vptr); @@ -1899,6 +1905,13 @@ static int velocity_xmit(struct sk_buff *skb, struct net_device *dev) int pktlen = skb->len; +#ifdef VELOCITY_ZERO_COPY_SUPPORT + if (skb_shinfo(skb)->nr_frags > 6 && __skb_linearize(skb)) { + kfree_skb(skb); + return 0; + } +#endif + spin_lock_irqsave(&vptr->lock, flags); index = vptr->td_curr[qnum]; @@ -1914,8 +1927,6 @@ static int velocity_xmit(struct sk_buff *skb, struct net_device *dev) */ if (pktlen < ETH_ZLEN) { /* Cannot occur until ZC support */ - if(skb_linearize(skb, GFP_ATOMIC)) - return 0; pktlen = ETH_ZLEN; memcpy(tdinfo->buf, skb->data, skb->len); memset(tdinfo->buf + skb->len, 0, ETH_ZLEN - skb->len); @@ -1933,7 +1944,6 @@ static int velocity_xmit(struct sk_buff *skb, struct net_device *dev) int nfrags = skb_shinfo(skb)->nr_frags; tdinfo->skb = skb; if (nfrags > 6) { - skb_linearize(skb, GFP_ATOMIC); memcpy(tdinfo->buf, skb->data, skb->len); tdinfo->skb_dma[0] = tdinfo->buf_dma; td_ptr->tdesc0.pktsize = diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c index c2d0b09e0..a5fcfcde6 100644 --- a/drivers/net/wireless/orinoco.c +++ b/drivers/net/wireless/orinoco.c @@ -1833,7 +1833,9 @@ static int __orinoco_program_rids(struct net_device *dev) /* Set promiscuity / multicast*/ priv->promiscuous = 0; priv->mc_count = 0; - __orinoco_set_multicast_list(dev); /* FIXME: what about the xmit_lock */ + + /* FIXME: what about netif_tx_lock */ + __orinoco_set_multicast_list(dev); return 0; } diff --git a/drivers/net/wireless/spectrum_cs.c b/drivers/net/wireless/spectrum_cs.c index f7b77ce54..54fe4e4ea 100644 --- a/drivers/net/wireless/spectrum_cs.c +++ b/drivers/net/wireless/spectrum_cs.c @@ -245,7 +245,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/drivers/oprofile/buffer_sync.c b/drivers/oprofile/buffer_sync.c index b2e8e49c8..a647d3982 100644 --- a/drivers/oprofile/buffer_sync.c +++ b/drivers/oprofile/buffer_sync.c @@ -6,6 +6,10 @@ * * @author John Levon * + * Modified by Aravind Menon for Xen + * These modifications are: + * Copyright (C) 2005 Hewlett-Packard Co. + * * This is the core of the buffer management. Each * CPU buffer is processed and entered into the * global event buffer. Such processing is necessary @@ -275,15 +279,31 @@ static void add_cpu_switch(int i) last_cookie = INVALID_COOKIE; } -static void add_kernel_ctx_switch(unsigned int in_kernel) +static void add_cpu_mode_switch(unsigned int cpu_mode) { add_event_entry(ESCAPE_CODE); - if (in_kernel) - add_event_entry(KERNEL_ENTER_SWITCH_CODE); - else - add_event_entry(KERNEL_EXIT_SWITCH_CODE); + switch (cpu_mode) { + case CPU_MODE_USER: + add_event_entry(USER_ENTER_SWITCH_CODE); + break; + case CPU_MODE_KERNEL: + add_event_entry(KERNEL_ENTER_SWITCH_CODE); + break; + case CPU_MODE_XEN: + add_event_entry(XEN_ENTER_SWITCH_CODE); + break; + default: + break; + } } - + +static void add_domain_switch(unsigned long domain_id) +{ + add_event_entry(ESCAPE_CODE); + add_event_entry(DOMAIN_SWITCH_CODE); + add_event_entry(domain_id); +} + static void add_user_ctx_switch(struct task_struct const * task, unsigned long cookie) { @@ -348,9 +368,9 @@ static int add_us_sample(struct mm_struct * mm, struct op_sample * s) * for later lookup from userspace. */ static int -add_sample(struct mm_struct * mm, struct op_sample * s, int in_kernel) +add_sample(struct mm_struct * mm, struct op_sample * s, int cpu_mode) { - if (in_kernel) { + if (cpu_mode >= CPU_MODE_KERNEL) { add_sample_entry(s->eip, s->event); return 1; } else if (mm) { @@ -496,10 +516,11 @@ void sync_buffer(int cpu) struct mm_struct *mm = NULL; struct task_struct * new; unsigned long cookie = 0; - int in_kernel = 1; + int cpu_mode = 1; unsigned int i; sync_buffer_state state = sb_buffer_start; unsigned long available; + int domain_switch = 0; down(&buffer_sem); @@ -512,16 +533,18 @@ void sync_buffer(int cpu) for (i = 0; i < available; ++i) { struct op_sample * s = &cpu_buf->buffer[cpu_buf->tail_pos]; - if (is_code(s->eip)) { - if (s->event <= CPU_IS_KERNEL) { - /* kernel/userspace switch */ - in_kernel = s->event; + if (is_code(s->eip) && !domain_switch) { + if (s->event <= CPU_MODE_XEN) { + /* xen/kernel/userspace switch */ + cpu_mode = s->event; if (state == sb_buffer_start) state = sb_sample_start; - add_kernel_ctx_switch(s->event); + add_cpu_mode_switch(s->event); } else if (s->event == CPU_TRACE_BEGIN) { state = sb_bt_start; add_trace_begin(); + } else if (s->event == CPU_DOMAIN_SWITCH) { + domain_switch = 1; } else { struct mm_struct * oldmm = mm; @@ -535,11 +558,16 @@ void sync_buffer(int cpu) add_user_ctx_switch(new, cookie); } } else { - if (state >= sb_bt_start && - !add_sample(mm, s, in_kernel)) { - if (state == sb_bt_start) { - state = sb_bt_ignore; - atomic_inc(&oprofile_stats.bt_lost_no_mapping); + if (domain_switch) { + add_domain_switch(s->eip); + domain_switch = 0; + } else { + if (state >= sb_bt_start && + !add_sample(mm, s, cpu_mode)) { + if (state == sb_bt_start) { + state = sb_bt_ignore; + atomic_inc(&oprofile_stats.bt_lost_no_mapping); + } } } } diff --git a/drivers/oprofile/cpu_buffer.c b/drivers/oprofile/cpu_buffer.c index fc4bc9b94..a59878e14 100644 --- a/drivers/oprofile/cpu_buffer.c +++ b/drivers/oprofile/cpu_buffer.c @@ -6,6 +6,10 @@ * * @author John Levon * + * Modified by Aravind Menon for Xen + * These modifications are: + * Copyright (C) 2005 Hewlett-Packard Co. + * * Each CPU has a local buffer that stores PC value/event * pairs. We also log context switches when we notice them. * Eventually each CPU's buffer is processed into the global @@ -34,6 +38,8 @@ static void wq_sync_buffer(void *); #define DEFAULT_TIMER_EXPIRE (HZ / 10) static int work_enabled; +static int32_t current_domain = COORDINATOR_DOMAIN; + void free_cpu_buffers(void) { int i; @@ -57,7 +63,7 @@ int alloc_cpu_buffers(void) goto fail; b->last_task = NULL; - b->last_is_kernel = -1; + b->last_cpu_mode = -1; b->tracing = 0; b->buffer_size = buffer_size; b->tail_pos = 0; @@ -113,7 +119,7 @@ void cpu_buffer_reset(struct oprofile_cpu_buffer * cpu_buf) * collected will populate the buffer with proper * values to initialize the buffer */ - cpu_buf->last_is_kernel = -1; + cpu_buf->last_cpu_mode = -1; cpu_buf->last_task = NULL; } @@ -163,13 +169,13 @@ add_code(struct oprofile_cpu_buffer * buffer, unsigned long value) * because of the head/tail separation of the writer and reader * of the CPU buffer. * - * is_kernel is needed because on some architectures you cannot + * cpu_mode is needed because on some architectures you cannot * tell if you are in kernel or user space simply by looking at - * pc. We tag this in the buffer by generating kernel enter/exit - * events whenever is_kernel changes + * pc. We tag this in the buffer by generating kernel/user (and xen) + * enter events whenever cpu_mode changes */ static int log_sample(struct oprofile_cpu_buffer * cpu_buf, unsigned long pc, - int is_kernel, unsigned long event) + int cpu_mode, unsigned long event) { struct task_struct * task; @@ -180,18 +186,20 @@ static int log_sample(struct oprofile_cpu_buffer * cpu_buf, unsigned long pc, return 0; } - is_kernel = !!is_kernel; + WARN_ON(cpu_mode > CPU_MODE_XEN); task = current; /* notice a switch from user->kernel or vice versa */ - if (cpu_buf->last_is_kernel != is_kernel) { - cpu_buf->last_is_kernel = is_kernel; - add_code(cpu_buf, is_kernel); + if (cpu_buf->last_cpu_mode != cpu_mode) { + cpu_buf->last_cpu_mode = cpu_mode; + add_code(cpu_buf, cpu_mode); } - + /* notice a task switch */ - if (cpu_buf->last_task != task) { + /* if not processing other domain samples */ + if ((cpu_buf->last_task != task) && + (current_domain == COORDINATOR_DOMAIN)) { cpu_buf->last_task = task; add_code(cpu_buf, (unsigned long)task); } @@ -275,6 +283,25 @@ void oprofile_add_trace(unsigned long pc) add_sample(cpu_buf, pc, 0); } +int oprofile_add_domain_switch(int32_t domain_id) +{ + struct oprofile_cpu_buffer * cpu_buf = &cpu_buffer[smp_processor_id()]; + + /* should have space for switching into and out of domain + (2 slots each) plus one sample and one cpu mode switch */ + if (((nr_available_slots(cpu_buf) < 6) && + (domain_id != COORDINATOR_DOMAIN)) || + (nr_available_slots(cpu_buf) < 2)) + return 0; + + add_code(cpu_buf, CPU_DOMAIN_SWITCH); + add_sample(cpu_buf, domain_id, 0); + + current_domain = domain_id; + + return 1; +} + /* * This serves to avoid cpu buffer overflow, and makes sure * the task mortuary progresses diff --git a/drivers/oprofile/cpu_buffer.h b/drivers/oprofile/cpu_buffer.h index 09abb80e0..cd94735be 100644 --- a/drivers/oprofile/cpu_buffer.h +++ b/drivers/oprofile/cpu_buffer.h @@ -36,7 +36,7 @@ struct oprofile_cpu_buffer { volatile unsigned long tail_pos; unsigned long buffer_size; struct task_struct * last_task; - int last_is_kernel; + int last_cpu_mode; int tracing; struct op_sample * buffer; unsigned long sample_received; @@ -51,7 +51,10 @@ extern struct oprofile_cpu_buffer cpu_buffer[]; void cpu_buffer_reset(struct oprofile_cpu_buffer * cpu_buf); /* transient events for the CPU buffer -> event buffer */ -#define CPU_IS_KERNEL 1 -#define CPU_TRACE_BEGIN 2 +#define CPU_MODE_USER 0 +#define CPU_MODE_KERNEL 1 +#define CPU_MODE_XEN 2 +#define CPU_TRACE_BEGIN 3 +#define CPU_DOMAIN_SWITCH 4 #endif /* OPROFILE_CPU_BUFFER_H */ diff --git a/drivers/oprofile/event_buffer.h b/drivers/oprofile/event_buffer.h index 018023630..0c33ee71e 100644 --- a/drivers/oprofile/event_buffer.h +++ b/drivers/oprofile/event_buffer.h @@ -29,15 +29,20 @@ void wake_up_buffer_waiter(void); #define CPU_SWITCH_CODE 2 #define COOKIE_SWITCH_CODE 3 #define KERNEL_ENTER_SWITCH_CODE 4 -#define KERNEL_EXIT_SWITCH_CODE 5 +#define USER_ENTER_SWITCH_CODE 5 #define MODULE_LOADED_CODE 6 #define CTX_TGID_CODE 7 #define TRACE_BEGIN_CODE 8 #define TRACE_END_CODE 9 +#define XEN_ENTER_SWITCH_CODE 10 +#define DOMAIN_SWITCH_CODE 11 #define INVALID_COOKIE ~0UL #define NO_COOKIE 0UL +/* Constant used to refer to coordinator domain (Xen) */ +#define COORDINATOR_DOMAIN -1 + /* add data to the event buffer */ void add_event_entry(unsigned long data); diff --git a/drivers/oprofile/oprof.c b/drivers/oprofile/oprof.c index b3f1cd6a2..76bac8dfe 100644 --- a/drivers/oprofile/oprof.c +++ b/drivers/oprofile/oprof.c @@ -5,6 +5,10 @@ * @remark Read the file COPYING * * @author John Levon + * + * Modified by Aravind Menon for Xen + * These modifications are: + * Copyright (C) 2005 Hewlett-Packard Co. */ #include @@ -19,7 +23,7 @@ #include "cpu_buffer.h" #include "buffer_sync.h" #include "oprofile_stats.h" - + struct oprofile_operations oprofile_ops; unsigned long oprofile_started; @@ -33,6 +37,34 @@ static DECLARE_MUTEX(start_sem); */ static int timer = 0; +#ifdef CONFIG_XEN +int oprofile_set_active(int active_domains[], unsigned int adomains) +{ + int err; + + if (!oprofile_ops.set_active) + return -EINVAL; + + down(&start_sem); + err = oprofile_ops.set_active(active_domains, adomains); + up(&start_sem); + return err; +} + +int oprofile_set_passive(int passive_domains[], unsigned int pdomains) +{ + int err; + + if (!oprofile_ops.set_passive) + return -EINVAL; + + down(&start_sem); + err = oprofile_ops.set_passive(passive_domains, pdomains); + up(&start_sem); + return err; +} +#endif + int oprofile_setup(void) { int err; diff --git a/drivers/oprofile/oprof.h b/drivers/oprofile/oprof.h index 183236508..587db2b0a 100644 --- a/drivers/oprofile/oprof.h +++ b/drivers/oprofile/oprof.h @@ -35,5 +35,10 @@ void oprofile_create_files(struct super_block * sb, struct dentry * root); void oprofile_timer_init(struct oprofile_operations * ops); int oprofile_set_backtrace(unsigned long depth); - + +#ifdef CONFIG_XEN +int oprofile_set_active(int active_domains[], unsigned int adomains); +int oprofile_set_passive(int passive_domains[], unsigned int pdomains); +#endif + #endif /* OPROF_H */ diff --git a/drivers/oprofile/oprofile_files.c b/drivers/oprofile/oprofile_files.c index a72006c08..388846526 100644 --- a/drivers/oprofile/oprofile_files.c +++ b/drivers/oprofile/oprofile_files.c @@ -5,15 +5,21 @@ * @remark Read the file COPYING * * @author John Levon + * + * Modified by Aravind Menon for Xen + * These modifications are: + * Copyright (C) 2005 Hewlett-Packard Co. */ #include #include +#include +#include #include "event_buffer.h" #include "oprofile_stats.h" #include "oprof.h" - + unsigned long fs_buffer_size = 131072; unsigned long fs_cpu_buffer_size = 8192; unsigned long fs_buffer_watershed = 32768; /* FIXME: tune */ @@ -117,11 +123,206 @@ static ssize_t dump_write(struct file * file, char const __user * buf, size_t co static struct file_operations dump_fops = { .write = dump_write, }; - + +#define TMPBUFSIZE 512 + +#ifdef CONFIG_XEN +static unsigned int adomains = 0; +static int active_domains[MAX_OPROF_DOMAINS + 1]; +static DEFINE_MUTEX(adom_mutex); + +static ssize_t adomain_write(struct file * file, char const __user * buf, + size_t count, loff_t * offset) +{ + char *tmpbuf; + char *startp, *endp; + int i; + unsigned long val; + ssize_t retval = count; + + if (*offset) + return -EINVAL; + if (count > TMPBUFSIZE - 1) + return -EINVAL; + + if (!(tmpbuf = kmalloc(TMPBUFSIZE, GFP_KERNEL))) + return -ENOMEM; + + if (copy_from_user(tmpbuf, buf, count)) { + kfree(tmpbuf); + return -EFAULT; + } + tmpbuf[count] = 0; + + mutex_lock(&adom_mutex); + + startp = tmpbuf; + /* Parse one more than MAX_OPROF_DOMAINS, for easy error checking */ + for (i = 0; i <= MAX_OPROF_DOMAINS; i++) { + val = simple_strtoul(startp, &endp, 0); + if (endp == startp) + break; + while (ispunct(*endp) || isspace(*endp)) + endp++; + active_domains[i] = val; + if (active_domains[i] != val) + /* Overflow, force error below */ + i = MAX_OPROF_DOMAINS + 1; + startp = endp; + } + /* Force error on trailing junk */ + adomains = *startp ? MAX_OPROF_DOMAINS + 1 : i; + + kfree(tmpbuf); + + if (adomains > MAX_OPROF_DOMAINS + || oprofile_set_active(active_domains, adomains)) { + adomains = 0; + retval = -EINVAL; + } + + mutex_unlock(&adom_mutex); + return retval; +} + +static ssize_t adomain_read(struct file * file, char __user * buf, + size_t count, loff_t * offset) +{ + char * tmpbuf; + size_t len; + int i; + ssize_t retval; + + if (!(tmpbuf = kmalloc(TMPBUFSIZE, GFP_KERNEL))) + return -ENOMEM; + + mutex_lock(&adom_mutex); + + len = 0; + for (i = 0; i < adomains; i++) + len += snprintf(tmpbuf + len, + len < TMPBUFSIZE ? TMPBUFSIZE - len : 0, + "%u ", active_domains[i]); + WARN_ON(len > TMPBUFSIZE); + if (len != 0 && len <= TMPBUFSIZE) + tmpbuf[len-1] = '\n'; + + mutex_unlock(&adom_mutex); + + retval = simple_read_from_buffer(buf, count, offset, tmpbuf, len); + + kfree(tmpbuf); + return retval; +} + + +static struct file_operations active_domain_ops = { + .read = adomain_read, + .write = adomain_write, +}; + +static unsigned int pdomains = 0; +static int passive_domains[MAX_OPROF_DOMAINS]; +static DEFINE_MUTEX(pdom_mutex); + +static ssize_t pdomain_write(struct file * file, char const __user * buf, + size_t count, loff_t * offset) +{ + char *tmpbuf; + char *startp, *endp; + int i; + unsigned long val; + ssize_t retval = count; + + if (*offset) + return -EINVAL; + if (count > TMPBUFSIZE - 1) + return -EINVAL; + + if (!(tmpbuf = kmalloc(TMPBUFSIZE, GFP_KERNEL))) + return -ENOMEM; + + if (copy_from_user(tmpbuf, buf, count)) { + kfree(tmpbuf); + return -EFAULT; + } + tmpbuf[count] = 0; + + mutex_lock(&pdom_mutex); + + startp = tmpbuf; + /* Parse one more than MAX_OPROF_DOMAINS, for easy error checking */ + for (i = 0; i <= MAX_OPROF_DOMAINS; i++) { + val = simple_strtoul(startp, &endp, 0); + if (endp == startp) + break; + while (ispunct(*endp) || isspace(*endp)) + endp++; + passive_domains[i] = val; + if (passive_domains[i] != val) + /* Overflow, force error below */ + i = MAX_OPROF_DOMAINS + 1; + startp = endp; + } + /* Force error on trailing junk */ + pdomains = *startp ? MAX_OPROF_DOMAINS + 1 : i; + + kfree(tmpbuf); + + if (pdomains > MAX_OPROF_DOMAINS + || oprofile_set_passive(passive_domains, pdomains)) { + pdomains = 0; + retval = -EINVAL; + } + + mutex_unlock(&pdom_mutex); + return retval; +} + +static ssize_t pdomain_read(struct file * file, char __user * buf, + size_t count, loff_t * offset) +{ + char * tmpbuf; + size_t len; + int i; + ssize_t retval; + + if (!(tmpbuf = kmalloc(TMPBUFSIZE, GFP_KERNEL))) + return -ENOMEM; + + mutex_lock(&pdom_mutex); + + len = 0; + for (i = 0; i < pdomains; i++) + len += snprintf(tmpbuf + len, + len < TMPBUFSIZE ? TMPBUFSIZE - len : 0, + "%u ", passive_domains[i]); + WARN_ON(len > TMPBUFSIZE); + if (len != 0 && len <= TMPBUFSIZE) + tmpbuf[len-1] = '\n'; + + mutex_unlock(&pdom_mutex); + + retval = simple_read_from_buffer(buf, count, offset, tmpbuf, len); + + kfree(tmpbuf); + return retval; +} + +static struct file_operations passive_domain_ops = { + .read = pdomain_read, + .write = pdomain_write, +}; +#endif /* CONFIG_XEN */ + void oprofile_create_files(struct super_block * sb, struct dentry * root) { oprofilefs_create_file(sb, root, "enable", &enable_fops); oprofilefs_create_file_perm(sb, root, "dump", &dump_fops, 0666); +#ifdef CONFIG_XEN + oprofilefs_create_file(sb, root, "active_domains", &active_domain_ops); + oprofilefs_create_file(sb, root, "passive_domains", &passive_domain_ops); +#endif oprofilefs_create_file(sb, root, "buffer", &event_buffer_fops); oprofilefs_create_ulong(sb, root, "buffer_size", &fs_buffer_size); oprofilefs_create_ulong(sb, root, "buffer_watershed", &fs_buffer_watershed); diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index 4d762fc48..065ea43aa 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -5,6 +5,7 @@ config PCI_MSI bool "Message Signaled Interrupts (MSI and MSI-X)" depends on PCI depends on (X86_LOCAL_APIC && X86_IO_APIC) || IA64 + depends on !XEN help This allows device drivers to enable MSI (Message Signaled Interrupts). Message Signaled Interrupts enable a device to diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index d37847861..6e3786f4d 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -427,6 +427,7 @@ 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 ); /* @@ -1043,7 +1044,6 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_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) { diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c index 6ded52716..688421de9 100644 --- a/drivers/pnp/resource.c +++ b/drivers/pnp/resource.c @@ -396,7 +396,8 @@ int pnp_check_irq(struct pnp_dev * dev, int idx) /* check if the resource is already in use, skip if the * device is active because it itself may be in use */ if(!dev->active) { - if (request_irq(*irq, pnp_test_handler, SA_INTERRUPT, "pnp", NULL)) + if (request_irq(*irq, pnp_test_handler, + SA_INTERRUPT|SA_PROBEIRQ, "pnp", NULL)) return 0; free_irq(*irq, NULL); } diff --git a/drivers/s390/net/qeth_eddp.c b/drivers/s390/net/qeth_eddp.c index 0bab60a20..38aad8321 100644 --- a/drivers/s390/net/qeth_eddp.c +++ b/drivers/s390/net/qeth_eddp.c @@ -420,7 +420,7 @@ __qeth_eddp_fill_context_tcp(struct qeth_eddp_context *ctx, } tcph = eddp->skb->h.th; while (eddp->skb_offset < eddp->skb->len) { - data_len = min((int)skb_shinfo(eddp->skb)->tso_size, + data_len = min((int)skb_shinfo(eddp->skb)->gso_size, (int)(eddp->skb->len - eddp->skb_offset)); /* prepare qdio hdr */ if (eddp->qh.hdr.l2.id == QETH_HEADER_TYPE_LAYER2){ @@ -515,20 +515,20 @@ qeth_eddp_calc_num_pages(struct qeth_eddp_context *ctx, struct sk_buff *skb, QETH_DBF_TEXT(trace, 5, "eddpcanp"); /* can we put multiple skbs in one page? */ - skbs_per_page = PAGE_SIZE / (skb_shinfo(skb)->tso_size + hdr_len); + skbs_per_page = PAGE_SIZE / (skb_shinfo(skb)->gso_size + hdr_len); if (skbs_per_page > 1){ - ctx->num_pages = (skb_shinfo(skb)->tso_segs + 1) / + ctx->num_pages = (skb_shinfo(skb)->gso_segs + 1) / skbs_per_page + 1; ctx->elements_per_skb = 1; } else { /* no -> how many elements per skb? */ - ctx->elements_per_skb = (skb_shinfo(skb)->tso_size + hdr_len + + ctx->elements_per_skb = (skb_shinfo(skb)->gso_size + hdr_len + PAGE_SIZE) >> PAGE_SHIFT; ctx->num_pages = ctx->elements_per_skb * - (skb_shinfo(skb)->tso_segs + 1); + (skb_shinfo(skb)->gso_segs + 1); } ctx->num_elements = ctx->elements_per_skb * - (skb_shinfo(skb)->tso_segs + 1); + (skb_shinfo(skb)->gso_segs + 1); } static inline struct qeth_eddp_context * diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c index 9e671a48c..290866932 100644 --- a/drivers/s390/net/qeth_main.c +++ b/drivers/s390/net/qeth_main.c @@ -4417,7 +4417,6 @@ qeth_send_packet(struct qeth_card *card, struct sk_buff *skb) struct qeth_eddp_context *ctx = NULL; int tx_bytes = skb->len; unsigned short nr_frags = skb_shinfo(skb)->nr_frags; - unsigned short tso_size = skb_shinfo(skb)->tso_size; int rc; QETH_DBF_TEXT(trace, 6, "sendpkt"); @@ -4453,7 +4452,7 @@ qeth_send_packet(struct qeth_card *card, struct sk_buff *skb) queue = card->qdio.out_qs [qeth_get_priority_queue(card, skb, ipv, cast_type)]; - if (skb_shinfo(skb)->tso_size) + if (skb_is_gso(skb)) large_send = card->options.large_send; /*are we able to do TSO ? If so ,prepare and send it from here */ @@ -4500,9 +4499,8 @@ qeth_send_packet(struct qeth_card *card, struct sk_buff *skb) card->stats.tx_packets++; card->stats.tx_bytes += tx_bytes; #ifdef CONFIG_QETH_PERF_STATS - if (tso_size && - !(large_send == QETH_LARGE_SEND_NO)) { - card->perf_stats.large_send_bytes += tx_bytes; + if (skb_is_gso(skb) && !(large_send == QETH_LARGE_SEND_NO)) { + card->perf_stats.large_send_bytes += skb->len; card->perf_stats.large_send_cnt++; } if (nr_frags > 0){ diff --git a/drivers/s390/net/qeth_tso.h b/drivers/s390/net/qeth_tso.h index 24ef40ca9..593f29814 100644 --- a/drivers/s390/net/qeth_tso.h +++ b/drivers/s390/net/qeth_tso.h @@ -51,7 +51,7 @@ qeth_tso_fill_header(struct qeth_card *card, struct sk_buff *skb) hdr->ext.hdr_version = 1; hdr->ext.hdr_len = 28; /*insert non-fix values */ - hdr->ext.mss = skb_shinfo(skb)->tso_size; + hdr->ext.mss = skb_shinfo(skb)->gso_size; hdr->ext.dg_hdr_len = (__u16)(iph->ihl*4 + tcph->doff*4); hdr->ext.payload_len = (__u16)(skb->len - hdr->ext.dg_hdr_len - sizeof(struct qeth_hdr_tso)); diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile index a262e384c..81803a16f 100644 --- a/drivers/scsi/Makefile +++ b/drivers/scsi/Makefile @@ -33,7 +33,7 @@ obj-$(CONFIG_SCSI_FC_ATTRS) += scsi_transport_fc.o obj-$(CONFIG_SCSI_ISCSI_ATTRS) += scsi_transport_iscsi.o obj-$(CONFIG_SCSI_SAS_ATTRS) += scsi_transport_sas.o -obj-$(CONFIG_ISCSI_TCP) += libiscsi.o iscsi_tcp.o +obj-$(CONFIG_ISCSI_TCP) += iscsi_tcp.o obj-$(CONFIG_SCSI_AMIGA7XX) += amiga7xx.o 53c7xx.o obj-$(CONFIG_A3000_SCSI) += a3000.o wd33c93.o obj-$(CONFIG_A2091_SCSI) += a2091.o wd33c93.o diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index b4743a9ec..2068b6682 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c @@ -3,8 +3,7 @@ * * Copyright (C) 2004 Dmitry Yusupov * Copyright (C) 2004 Alex Aizman - * Copyright (C) 2005 - 2006 Mike Christie - * Copyright (C) 2006 Red Hat, Inc. All rights reserved. + * Copyright (C) 2005 Mike Christie * maintained by open-iscsi@googlegroups.com * * This program is free software; you can redistribute it and/or modify @@ -37,28 +36,37 @@ #include #include #include +#include +#include +#include +#include #include #include #include #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); +MODULE_VERSION("0:4.445"); /* #define DEBUG_TCP */ +/* #define DEBUG_SCSI */ #define DEBUG_ASSERT #ifdef DEBUG_TCP -#define debug_tcp(fmt...) printk(KERN_INFO "tcp: " fmt) +#define debug_tcp(fmt...) printk(KERN_DEBUG "tcp: " fmt) #else #define debug_tcp(fmt...) #endif +#ifdef DEBUG_SCSI +#define debug_scsi(fmt...) printk(KERN_DEBUG "scsi: " fmt) +#else +#define debug_scsi(fmt...) +#endif + #ifndef DEBUG_ASSERT #ifdef BUG_ON #undef BUG_ON @@ -66,9 +74,22 @@ MODULE_VERSION(ISCSI_TCP_VERSION); #define BUG_ON(expr) #endif +#define INVALID_SN_DELTA 0xffff + static unsigned int iscsi_max_lun = 512; module_param_named(max_lun, iscsi_max_lun, uint, S_IRUGO); +/* global data */ +static kmem_cache_t *taskcache; + +static inline void +iscsi_buf_init_virt(struct iscsi_buf *ibuf, char *vbuf, int size) +{ + sg_init_one(&ibuf->sg, (u8 *)vbuf, size); + ibuf->sent = 0; + ibuf->use_sendmsg = 0; +} + static inline void iscsi_buf_init_iov(struct iscsi_buf *ibuf, char *vbuf, int size) { @@ -109,39 +130,68 @@ static inline void iscsi_hdr_digest(struct iscsi_conn *conn, struct iscsi_buf *buf, u8* crc) { - struct iscsi_tcp_conn *tcp_conn = conn->dd_data; - - crypto_digest_digest(tcp_conn->tx_tfm, &buf->sg, 1, crc); + crypto_digest_digest(conn->tx_tfm, &buf->sg, 1, crc); buf->sg.length += sizeof(uint32_t); } +static void +iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err) +{ + struct iscsi_session *session = conn->session; + unsigned long flags; + + spin_lock_irqsave(&session->lock, flags); + if (session->conn_cnt == 1 || session->leadconn == conn) + session->state = ISCSI_STATE_FAILED; + spin_unlock_irqrestore(&session->lock, flags); + set_bit(SUSPEND_BIT, &conn->suspend_tx); + set_bit(SUSPEND_BIT, &conn->suspend_rx); + iscsi_conn_error(conn->cls_conn, err); +} + static inline int -iscsi_hdr_extract(struct iscsi_tcp_conn *tcp_conn) +iscsi_check_assign_cmdsn(struct iscsi_session *session, struct iscsi_nopin *hdr) { - struct sk_buff *skb = tcp_conn->in.skb; + uint32_t max_cmdsn = be32_to_cpu(hdr->max_cmdsn); + uint32_t exp_cmdsn = be32_to_cpu(hdr->exp_cmdsn); + + if (max_cmdsn < exp_cmdsn -1 && + max_cmdsn > exp_cmdsn - INVALID_SN_DELTA) + return ISCSI_ERR_MAX_CMDSN; + if (max_cmdsn > session->max_cmdsn || + max_cmdsn < session->max_cmdsn - INVALID_SN_DELTA) + session->max_cmdsn = max_cmdsn; + if (exp_cmdsn > session->exp_cmdsn || + exp_cmdsn < session->exp_cmdsn - INVALID_SN_DELTA) + session->exp_cmdsn = exp_cmdsn; + + return 0; +} - tcp_conn->in.zero_copy_hdr = 0; +static inline int +iscsi_hdr_extract(struct iscsi_conn *conn) +{ + struct sk_buff *skb = conn->in.skb; - if (tcp_conn->in.copy >= tcp_conn->hdr_size && - tcp_conn->in_progress == IN_PROGRESS_WAIT_HEADER) { + if (conn->in.copy >= conn->hdr_size && + conn->in_progress == IN_PROGRESS_WAIT_HEADER) { /* * Zero-copy PDU Header: using connection context * to store header pointer. */ if (skb_shinfo(skb)->frag_list == NULL && - !skb_shinfo(skb)->nr_frags) { - tcp_conn->in.hdr = (struct iscsi_hdr *) - ((char*)skb->data + tcp_conn->in.offset); - tcp_conn->in.zero_copy_hdr = 1; - } else { + !skb_shinfo(skb)->nr_frags) + conn->in.hdr = (struct iscsi_hdr *) + ((char*)skb->data + conn->in.offset); + else { /* ignoring return code since we checked * in.copy before */ - skb_copy_bits(skb, tcp_conn->in.offset, - &tcp_conn->hdr, tcp_conn->hdr_size); - tcp_conn->in.hdr = &tcp_conn->hdr; + skb_copy_bits(skb, conn->in.offset, + &conn->hdr, conn->hdr_size); + conn->in.hdr = &conn->hdr; } - tcp_conn->in.offset += tcp_conn->hdr_size; - tcp_conn->in.copy -= tcp_conn->hdr_size; + conn->in.offset += conn->hdr_size; + conn->in.copy -= conn->hdr_size; } else { int hdr_remains; int copylen; @@ -151,51 +201,118 @@ iscsi_hdr_extract(struct iscsi_tcp_conn *tcp_conn) * copying it... This'll happen quite rarely. */ - if (tcp_conn->in_progress == IN_PROGRESS_WAIT_HEADER) - tcp_conn->in.hdr_offset = 0; + if (conn->in_progress == IN_PROGRESS_WAIT_HEADER) + conn->in.hdr_offset = 0; - hdr_remains = tcp_conn->hdr_size - tcp_conn->in.hdr_offset; + hdr_remains = conn->hdr_size - conn->in.hdr_offset; BUG_ON(hdr_remains <= 0); - copylen = min(tcp_conn->in.copy, hdr_remains); - skb_copy_bits(skb, tcp_conn->in.offset, - (char*)&tcp_conn->hdr + tcp_conn->in.hdr_offset, - copylen); + copylen = min(conn->in.copy, hdr_remains); + skb_copy_bits(skb, conn->in.offset, + (char*)&conn->hdr + conn->in.hdr_offset, copylen); debug_tcp("PDU gather offset %d bytes %d in.offset %d " - "in.copy %d\n", tcp_conn->in.hdr_offset, copylen, - tcp_conn->in.offset, tcp_conn->in.copy); + "in.copy %d\n", conn->in.hdr_offset, copylen, + conn->in.offset, conn->in.copy); - tcp_conn->in.offset += copylen; - tcp_conn->in.copy -= copylen; + conn->in.offset += copylen; + conn->in.copy -= copylen; if (copylen < hdr_remains) { - tcp_conn->in_progress = IN_PROGRESS_HEADER_GATHER; - tcp_conn->in.hdr_offset += copylen; + conn->in_progress = IN_PROGRESS_HEADER_GATHER; + conn->in.hdr_offset += copylen; return -EAGAIN; } - tcp_conn->in.hdr = &tcp_conn->hdr; - tcp_conn->discontiguous_hdr_cnt++; - tcp_conn->in_progress = IN_PROGRESS_WAIT_HEADER; + conn->in.hdr = &conn->hdr; + conn->discontiguous_hdr_cnt++; + conn->in_progress = IN_PROGRESS_WAIT_HEADER; } return 0; } -/* - * must be called with session lock - */ -static void -__iscsi_ctask_cleanup(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) +static inline void +iscsi_ctask_cleanup(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) { - struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; - struct scsi_cmnd *sc; + struct scsi_cmnd *sc = ctask->sc; + struct iscsi_session *session = conn->session; - sc = ctask->sc; - if (unlikely(!sc)) + spin_lock(&session->lock); + if (unlikely(!sc)) { + spin_unlock(&session->lock); return; + } + if (sc->sc_data_direction == DMA_TO_DEVICE) { + struct iscsi_data_task *dtask, *n; + /* WRITE: cleanup Data-Out's if any */ + list_for_each_entry_safe(dtask, n, &ctask->dataqueue, item) { + list_del(&dtask->item); + mempool_free(dtask, ctask->datapool); + } + } + ctask->xmstate = XMSTATE_IDLE; + ctask->r2t = NULL; + ctask->sc = NULL; + __kfifo_put(session->cmdpool.queue, (void*)&ctask, sizeof(void*)); + spin_unlock(&session->lock); +} + +/** + * iscsi_cmd_rsp - SCSI Command Response processing + * @conn: iscsi connection + * @ctask: scsi command task + **/ +static int +iscsi_cmd_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) +{ + int rc; + struct iscsi_cmd_rsp *rhdr = (struct iscsi_cmd_rsp *)conn->in.hdr; + struct iscsi_session *session = conn->session; + struct scsi_cmnd *sc = ctask->sc; + + rc = iscsi_check_assign_cmdsn(session, (struct iscsi_nopin*)rhdr); + if (rc) { + sc->result = (DID_ERROR << 16); + goto out; + } + + conn->exp_statsn = be32_to_cpu(rhdr->statsn) + 1; + + sc->result = (DID_OK << 16) | rhdr->cmd_status; + + if (rhdr->response != ISCSI_STATUS_CMD_COMPLETED) { + sc->result = (DID_ERROR << 16); + goto out; + } + + if (rhdr->cmd_status == SAM_STAT_CHECK_CONDITION && conn->senselen) { + int sensecopy = min(conn->senselen, SCSI_SENSE_BUFFERSIZE); - tcp_ctask->xmstate = XMSTATE_IDLE; - tcp_ctask->r2t = NULL; + memcpy(sc->sense_buffer, conn->data + 2, sensecopy); + debug_scsi("copied %d bytes of sense\n", sensecopy); + } + + if (sc->sc_data_direction == DMA_TO_DEVICE) + goto out; + + if (rhdr->flags & ISCSI_FLAG_CMD_UNDERFLOW) { + int res_count = be32_to_cpu(rhdr->residual_count); + + if (res_count > 0 && res_count <= sc->request_bufflen) + sc->resid = res_count; + else + sc->result = (DID_BAD_TARGET << 16) | rhdr->cmd_status; + } else if (rhdr->flags & ISCSI_FLAG_CMD_BIDI_UNDERFLOW) + sc->result = (DID_BAD_TARGET << 16) | rhdr->cmd_status; + else if (rhdr->flags & ISCSI_FLAG_CMD_OVERFLOW) + sc->resid = be32_to_cpu(rhdr->residual_count); + +out: + debug_scsi("done [sc %lx res %d itt 0x%x]\n", + (long)sc, sc->result, ctask->itt); + conn->scsirsp_pdus_cnt++; + iscsi_ctask_cleanup(conn, ctask); + sc->scsi_done(sc); + return rc; } /** @@ -207,9 +324,7 @@ static int iscsi_data_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) { int rc; - struct iscsi_tcp_conn *tcp_conn = conn->dd_data; - struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; - struct iscsi_data_rsp *rhdr = (struct iscsi_data_rsp *)tcp_conn->in.hdr; + struct iscsi_data_rsp *rhdr = (struct iscsi_data_rsp *)conn->in.hdr; struct iscsi_session *session = conn->session; int datasn = be32_to_cpu(rhdr->datasn); @@ -219,9 +334,9 @@ iscsi_data_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) /* * setup Data-In byte counter (gets decremented..) */ - ctask->data_count = tcp_conn->in.datalen; + ctask->data_count = conn->in.datalen; - if (tcp_conn->in.datalen == 0) + if (conn->in.datalen == 0) return 0; if (ctask->datasn != datasn) @@ -229,8 +344,8 @@ iscsi_data_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) ctask->datasn++; - tcp_ctask->data_offset = be32_to_cpu(rhdr->offset); - if (tcp_ctask->data_offset + tcp_conn->in.datalen > ctask->total_length) + ctask->data_offset = be32_to_cpu(rhdr->offset); + if (ctask->data_offset + conn->in.datalen > ctask->total_length) return ISCSI_ERR_DATA_OFFSET; if (rhdr->flags & ISCSI_FLAG_DATA_STATUS) { @@ -275,17 +390,19 @@ iscsi_solicit_data_init(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask, struct iscsi_r2t_info *r2t) { struct iscsi_data *hdr; + struct iscsi_data_task *dtask; struct scsi_cmnd *sc = ctask->sc; - struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; - hdr = &r2t->dtask.hdr; + dtask = mempool_alloc(ctask->datapool, GFP_ATOMIC); + BUG_ON(!dtask); + hdr = &dtask->hdr; memset(hdr, 0, sizeof(struct iscsi_data)); hdr->ttt = r2t->ttt; hdr->datasn = cpu_to_be32(r2t->solicit_datasn); r2t->solicit_datasn++; hdr->opcode = ISCSI_OP_SCSI_DATA_OUT; - memcpy(hdr->lun, ctask->hdr->lun, sizeof(hdr->lun)); - hdr->itt = ctask->hdr->itt; + memcpy(hdr->lun, ctask->hdr.lun, sizeof(hdr->lun)); + hdr->itt = ctask->hdr.itt; hdr->exp_statsn = r2t->exp_statsn; hdr->offset = cpu_to_be32(r2t->data_offset); if (r2t->data_length > conn->max_xmit_dlength) { @@ -301,9 +418,11 @@ iscsi_solicit_data_init(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask, r2t->sent = 0; - iscsi_buf_init_iov(&r2t->headbuf, (char*)hdr, + iscsi_buf_init_virt(&r2t->headbuf, (char*)hdr, sizeof(struct iscsi_hdr)); + r2t->dtask = dtask; + if (sc->use_sg) { int i, sg_count = 0; struct scatterlist *sg = sc->request_buffer; @@ -332,9 +451,11 @@ iscsi_solicit_data_init(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask, } BUG_ON(r2t->sg == NULL); } else - iscsi_buf_init_iov(&tcp_ctask->sendbuf, + iscsi_buf_init_iov(&ctask->sendbuf, (char*)sc->request_buffer + r2t->data_offset, r2t->data_count); + + list_add(&dtask->item, &ctask->dataqueue); } /** @@ -347,16 +468,17 @@ iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) { struct iscsi_r2t_info *r2t; struct iscsi_session *session = conn->session; - struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; - struct iscsi_tcp_conn *tcp_conn = conn->dd_data; - struct iscsi_r2t_rsp *rhdr = (struct iscsi_r2t_rsp *)tcp_conn->in.hdr; + struct iscsi_r2t_rsp *rhdr = (struct iscsi_r2t_rsp *)conn->in.hdr; int r2tsn = be32_to_cpu(rhdr->r2tsn); int rc; - if (tcp_conn->in.datalen) + if (conn->in.ahslen) + return ISCSI_ERR_AHSLEN; + + if (conn->in.datalen) return ISCSI_ERR_DATALEN; - if (tcp_ctask->exp_r2tsn && tcp_ctask->exp_r2tsn != r2tsn) + if (ctask->exp_r2tsn && ctask->exp_r2tsn != r2tsn) return ISCSI_ERR_R2TSN; rc = iscsi_check_assign_cmdsn(session, (struct iscsi_nopin*)rhdr); @@ -374,7 +496,7 @@ 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*)); + rc = __kfifo_get(ctask->r2tpool.queue, (void*)&r2t, sizeof(void*)); BUG_ON(!rc); r2t->exp_statsn = rhdr->statsn; @@ -396,10 +518,10 @@ iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) iscsi_solicit_data_init(conn, ctask, r2t); - tcp_ctask->exp_r2tsn = r2tsn + 1; - tcp_ctask->xmstate |= XMSTATE_SOL_HDR; - __kfifo_put(tcp_ctask->r2tqueue, (void*)&r2t, sizeof(void*)); - __kfifo_put(conn->xmitqueue, (void*)&ctask, sizeof(void*)); + ctask->exp_r2tsn = r2tsn + 1; + ctask->xmstate |= XMSTATE_SOL_HDR; + __kfifo_put(ctask->r2tqueue, (void*)&r2t, sizeof(void*)); + __kfifo_put(conn->writequeue, (void*)&ctask, sizeof(void*)); scsi_queue_work(session->host, &conn->xmitwork); conn->r2t_pdus_cnt++; @@ -409,136 +531,258 @@ iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) } static int -iscsi_tcp_hdr_recv(struct iscsi_conn *conn) +iscsi_hdr_recv(struct iscsi_conn *conn) { - int rc = 0, opcode, ahslen; + int rc = 0; struct iscsi_hdr *hdr; + struct iscsi_cmd_task *ctask; struct iscsi_session *session = conn->session; - struct iscsi_tcp_conn *tcp_conn = conn->dd_data; - uint32_t cdgst, rdgst = 0, itt; + uint32_t cdgst, rdgst = 0; - hdr = tcp_conn->in.hdr; + hdr = conn->in.hdr; /* verify PDU length */ - tcp_conn->in.datalen = ntoh24(hdr->dlength); - if (tcp_conn->in.datalen > conn->max_recv_dlength) { + conn->in.datalen = ntoh24(hdr->dlength); + if (conn->in.datalen > conn->max_recv_dlength) { printk(KERN_ERR "iscsi_tcp: datalen %d > %d\n", - tcp_conn->in.datalen, conn->max_recv_dlength); + conn->in.datalen, conn->max_recv_dlength); return ISCSI_ERR_DATALEN; } - tcp_conn->data_copied = 0; + conn->data_copied = 0; /* read AHS */ - ahslen = hdr->hlength << 2; - tcp_conn->in.offset += ahslen; - tcp_conn->in.copy -= ahslen; - if (tcp_conn->in.copy < 0) { + conn->in.ahslen = hdr->hlength * 4; + conn->in.offset += conn->in.ahslen; + conn->in.copy -= conn->in.ahslen; + if (conn->in.copy < 0) { printk(KERN_ERR "iscsi_tcp: can't handle AHS with length " - "%d bytes\n", ahslen); + "%d bytes\n", conn->in.ahslen); return ISCSI_ERR_AHSLEN; } /* calculate read padding */ - tcp_conn->in.padding = tcp_conn->in.datalen & (ISCSI_PAD_LEN-1); - if (tcp_conn->in.padding) { - tcp_conn->in.padding = ISCSI_PAD_LEN - tcp_conn->in.padding; - debug_scsi("read padding %d bytes\n", tcp_conn->in.padding); + conn->in.padding = conn->in.datalen & (ISCSI_PAD_LEN-1); + if (conn->in.padding) { + conn->in.padding = ISCSI_PAD_LEN - conn->in.padding; + debug_scsi("read padding %d bytes\n", conn->in.padding); } if (conn->hdrdgst_en) { struct scatterlist sg; sg_init_one(&sg, (u8 *)hdr, - sizeof(struct iscsi_hdr) + ahslen); - crypto_digest_digest(tcp_conn->rx_tfm, &sg, 1, (u8 *)&cdgst); + sizeof(struct iscsi_hdr) + conn->in.ahslen); + crypto_digest_digest(conn->rx_tfm, &sg, 1, (u8 *)&cdgst); rdgst = *(uint32_t*)((char*)hdr + sizeof(struct iscsi_hdr) + - ahslen); + conn->in.ahslen); if (cdgst != rdgst) { - printk(KERN_ERR "iscsi_tcp: hdrdgst error " - "recv 0x%x calc 0x%x\n", rdgst, cdgst); + printk(KERN_ERR "iscsi_tcp: itt %x: hdrdgst error " + "recv 0x%x calc 0x%x\n", conn->in.itt, rdgst, + cdgst); return ISCSI_ERR_HDR_DGST; } } - opcode = hdr->opcode & ISCSI_OPCODE_MASK; + /* save opcode for later */ + conn->in.opcode = hdr->opcode & ISCSI_OPCODE_MASK; + /* verify itt (itt encoding: age+cid+itt) */ - rc = iscsi_verify_itt(conn, hdr, &itt); - if (rc == ISCSI_ERR_NO_SCSI_CMD) { - tcp_conn->in.datalen = 0; /* force drop */ - return 0; - } else if (rc) - return rc; + if (hdr->itt != cpu_to_be32(ISCSI_RESERVED_TAG)) { + if ((hdr->itt & AGE_MASK) != + (session->age << AGE_SHIFT)) { + printk(KERN_ERR "iscsi_tcp: received itt %x expected " + "session age (%x)\n", hdr->itt, + session->age & AGE_MASK); + return ISCSI_ERR_BAD_ITT; + } + + if ((hdr->itt & CID_MASK) != (conn->id << CID_SHIFT)) { + printk(KERN_ERR "iscsi_tcp: received itt %x, expected " + "CID (%x)\n", hdr->itt, conn->id); + return ISCSI_ERR_BAD_ITT; + } + conn->in.itt = hdr->itt & ITT_MASK; + } else + conn->in.itt = hdr->itt; debug_tcp("opcode 0x%x offset %d copy %d ahslen %d datalen %d\n", - opcode, tcp_conn->in.offset, tcp_conn->in.copy, - ahslen, tcp_conn->in.datalen); + hdr->opcode, conn->in.offset, conn->in.copy, + conn->in.ahslen, conn->in.datalen); - switch(opcode) { - case ISCSI_OP_SCSI_DATA_IN: - tcp_conn->in.ctask = session->cmds[itt]; - rc = iscsi_data_rsp(conn, tcp_conn->in.ctask); - /* fall through */ - case ISCSI_OP_SCSI_CMD_RSP: - tcp_conn->in.ctask = session->cmds[itt]; - if (tcp_conn->in.datalen) - goto copy_hdr; - - spin_lock(&session->lock); - __iscsi_ctask_cleanup(conn, tcp_conn->in.ctask); - rc = __iscsi_complete_pdu(conn, hdr, NULL, 0); - spin_unlock(&session->lock); - break; - case ISCSI_OP_R2T: - tcp_conn->in.ctask = session->cmds[itt]; - if (ahslen) - rc = ISCSI_ERR_AHSLEN; - else if (tcp_conn->in.ctask->sc->sc_data_direction == - DMA_TO_DEVICE) - rc = iscsi_r2t_rsp(conn, tcp_conn->in.ctask); - else - rc = ISCSI_ERR_PROTO; - 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: - if (tcp_conn->in.datalen) - goto copy_hdr; - /* fall through */ - case ISCSI_OP_SCSI_TMFUNC_RSP: - rc = iscsi_complete_pdu(conn, hdr, NULL, 0); - break; - default: - rc = ISCSI_ERR_BAD_OPCODE; - break; - } + if (conn->in.itt < session->cmds_max) { + ctask = (struct iscsi_cmd_task *)session->cmds[conn->in.itt]; - return rc; + if (!ctask->sc) { + printk(KERN_INFO "iscsi_tcp: dropping ctask with " + "itt 0x%x\n", ctask->itt); + conn->in.datalen = 0; /* force drop */ + return 0; + } -copy_hdr: - /* - * if we did zero copy for the header but we will need multiple - * 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 < - (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" - " %d\n", tcp_conn->in.copy, tcp_conn->in.datalen); - memcpy(&tcp_conn->hdr, tcp_conn->in.hdr, - sizeof(struct iscsi_hdr)); - tcp_conn->in.hdr = &tcp_conn->hdr; - tcp_conn->in.zero_copy_hdr = 0; - } - return 0; + if (ctask->sc->SCp.phase != session->age) { + printk(KERN_ERR "iscsi_tcp: ctask's session age %d, " + "expected %d\n", ctask->sc->SCp.phase, + session->age); + return ISCSI_ERR_SESSION_FAILED; + } + + conn->in.ctask = ctask; + + debug_scsi("rsp [op 0x%x cid %d sc %lx itt 0x%x len %d]\n", + hdr->opcode, conn->id, (long)ctask->sc, + ctask->itt, conn->in.datalen); + + switch(conn->in.opcode) { + case ISCSI_OP_SCSI_CMD_RSP: + BUG_ON((void*)ctask != ctask->sc->SCp.ptr); + if (!conn->in.datalen) + rc = iscsi_cmd_rsp(conn, ctask); + else + /* + * got sense or response data; copying PDU + * Header to the connection's header + * placeholder + */ + memcpy(&conn->hdr, hdr, + sizeof(struct iscsi_hdr)); + break; + case ISCSI_OP_SCSI_DATA_IN: + BUG_ON((void*)ctask != ctask->sc->SCp.ptr); + /* save flags for non-exceptional status */ + conn->in.flags = hdr->flags; + /* save cmd_status for sense data */ + conn->in.cmd_status = + ((struct iscsi_data_rsp*)hdr)->cmd_status; + rc = iscsi_data_rsp(conn, ctask); + break; + case ISCSI_OP_R2T: + BUG_ON((void*)ctask != ctask->sc->SCp.ptr); + if (ctask->sc->sc_data_direction == DMA_TO_DEVICE) + rc = iscsi_r2t_rsp(conn, ctask); + else + rc = ISCSI_ERR_PROTO; + break; + default: + rc = ISCSI_ERR_BAD_OPCODE; + break; + } + } else if (conn->in.itt >= ISCSI_MGMT_ITT_OFFSET && + conn->in.itt < ISCSI_MGMT_ITT_OFFSET + + session->mgmtpool_max) { + struct iscsi_mgmt_task *mtask = (struct iscsi_mgmt_task *) + session->mgmt_cmds[conn->in.itt - + ISCSI_MGMT_ITT_OFFSET]; + + debug_scsi("immrsp [op 0x%x cid %d itt 0x%x len %d]\n", + conn->in.opcode, conn->id, mtask->itt, + conn->in.datalen); + + switch(conn->in.opcode) { + case ISCSI_OP_LOGIN_RSP: + case ISCSI_OP_TEXT_RSP: + case ISCSI_OP_LOGOUT_RSP: + rc = iscsi_check_assign_cmdsn(session, + (struct iscsi_nopin*)hdr); + if (rc) + break; + + if (!conn->in.datalen) { + rc = iscsi_recv_pdu(conn->cls_conn, hdr, + NULL, 0); + if (conn->login_mtask != mtask) { + spin_lock(&session->lock); + __kfifo_put(session->mgmtpool.queue, + (void*)&mtask, sizeof(void*)); + spin_unlock(&session->lock); + } + } + break; + case ISCSI_OP_SCSI_TMFUNC_RSP: + rc = iscsi_check_assign_cmdsn(session, + (struct iscsi_nopin*)hdr); + if (rc) + break; + + if (conn->in.datalen || conn->in.ahslen) { + rc = ISCSI_ERR_PROTO; + break; + } + conn->tmfrsp_pdus_cnt++; + spin_lock(&session->lock); + if (conn->tmabort_state == TMABORT_INITIAL) { + __kfifo_put(session->mgmtpool.queue, + (void*)&mtask, sizeof(void*)); + conn->tmabort_state = + ((struct iscsi_tm_rsp *)hdr)-> + response == ISCSI_TMF_RSP_COMPLETE ? + TMABORT_SUCCESS:TMABORT_FAILED; + /* unblock eh_abort() */ + wake_up(&conn->ehwait); + } + spin_unlock(&session->lock); + break; + case ISCSI_OP_NOOP_IN: + if (hdr->ttt != ISCSI_RESERVED_TAG) { + rc = ISCSI_ERR_PROTO; + break; + } + rc = iscsi_check_assign_cmdsn(session, + (struct iscsi_nopin*)hdr); + if (rc) + break; + conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1; + + if (!conn->in.datalen) { + struct iscsi_mgmt_task *mtask; + + rc = iscsi_recv_pdu(conn->cls_conn, hdr, + NULL, 0); + mtask = (struct iscsi_mgmt_task *) + session->mgmt_cmds[conn->in.itt - + ISCSI_MGMT_ITT_OFFSET]; + if (conn->login_mtask != mtask) { + spin_lock(&session->lock); + __kfifo_put(session->mgmtpool.queue, + (void*)&mtask, sizeof(void*)); + spin_unlock(&session->lock); + } + } + break; + default: + rc = ISCSI_ERR_BAD_OPCODE; + break; + } + } else if (conn->in.itt == ISCSI_RESERVED_TAG) { + switch(conn->in.opcode) { + case ISCSI_OP_NOOP_IN: + if (!conn->in.datalen) { + rc = iscsi_check_assign_cmdsn(session, + (struct iscsi_nopin*)hdr); + 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()*/ + case ISCSI_OP_ASYNC_EVENT: + /* we need sth like iscsi_async_event_rsp() */ + rc = ISCSI_ERR_BAD_OPCODE; + break; + default: + rc = ISCSI_ERR_BAD_OPCODE; + break; + } + } else + rc = ISCSI_ERR_BAD_ITT; + + return rc; } /** * iscsi_ctask_copy - copy skb bits to the destanation cmd task - * @conn: iscsi tcp connection + * @conn: iscsi connection * @ctask: scsi command task * @buf: buffer to copy to * @buf_size: size of buffer @@ -560,113 +804,110 @@ copy_hdr: * buf_left left to copy from in progress buffer **/ static inline int -iscsi_ctask_copy(struct iscsi_tcp_conn *tcp_conn, struct iscsi_cmd_task *ctask, +iscsi_ctask_copy(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask, void *buf, int buf_size, int offset) { - struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; - int buf_left = buf_size - (tcp_conn->data_copied + offset); - int size = min(tcp_conn->in.copy, buf_left); + int buf_left = buf_size - (conn->data_copied + offset); + int size = min(conn->in.copy, buf_left); int rc; size = min(size, ctask->data_count); debug_tcp("ctask_copy %d bytes at offset %d copied %d\n", - size, tcp_conn->in.offset, tcp_conn->in.copied); + size, conn->in.offset, conn->in.copied); BUG_ON(size <= 0); - BUG_ON(tcp_ctask->sent + size > ctask->total_length); + BUG_ON(ctask->sent + size > ctask->total_length); - rc = skb_copy_bits(tcp_conn->in.skb, tcp_conn->in.offset, - (char*)buf + (offset + tcp_conn->data_copied), size); + rc = skb_copy_bits(conn->in.skb, conn->in.offset, + (char*)buf + (offset + conn->data_copied), size); /* must fit into skb->len */ BUG_ON(rc); - tcp_conn->in.offset += size; - tcp_conn->in.copy -= size; - tcp_conn->in.copied += size; - tcp_conn->data_copied += size; - tcp_ctask->sent += size; + conn->in.offset += size; + conn->in.copy -= size; + conn->in.copied += size; + conn->data_copied += size; + ctask->sent += size; ctask->data_count -= size; - BUG_ON(tcp_conn->in.copy < 0); + BUG_ON(conn->in.copy < 0); BUG_ON(ctask->data_count < 0); - if (buf_size != (tcp_conn->data_copied + offset)) { + if (buf_size != (conn->data_copied + offset)) { if (!ctask->data_count) { - BUG_ON(buf_size - tcp_conn->data_copied < 0); + BUG_ON(buf_size - conn->data_copied < 0); /* done with this PDU */ - return buf_size - tcp_conn->data_copied; + return buf_size - conn->data_copied; } return -EAGAIN; } /* done with this buffer or with both - PDU and buffer */ - tcp_conn->data_copied = 0; + conn->data_copied = 0; return 0; } /** * iscsi_tcp_copy - copy skb bits to the destanation buffer - * @conn: iscsi tcp connection + * @conn: iscsi connection + * @buf: buffer to copy to + * @buf_size: number of bytes to copy * * Notes: * The function calls skb_copy_bits() and updates per-connection * byte counters. **/ static inline int -iscsi_tcp_copy(struct iscsi_tcp_conn *tcp_conn) +iscsi_tcp_copy(struct iscsi_conn *conn, void *buf, int buf_size) { - 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); + int buf_left = buf_size - conn->data_copied; + int size = min(conn->in.copy, buf_left); int rc; debug_tcp("tcp_copy %d bytes at offset %d copied %d\n", - size, tcp_conn->in.offset, tcp_conn->data_copied); + size, conn->in.offset, conn->data_copied); BUG_ON(size <= 0); - rc = skb_copy_bits(tcp_conn->in.skb, tcp_conn->in.offset, - (char*)buf + tcp_conn->data_copied, size); + rc = skb_copy_bits(conn->in.skb, conn->in.offset, + (char*)buf + conn->data_copied, size); BUG_ON(rc); - tcp_conn->in.offset += size; - tcp_conn->in.copy -= size; - tcp_conn->in.copied += size; - tcp_conn->data_copied += size; + conn->in.offset += size; + conn->in.copy -= size; + conn->in.copied += size; + conn->data_copied += size; - if (buf_size != tcp_conn->data_copied) + if (buf_size != conn->data_copied) return -EAGAIN; return 0; } static inline void -partial_sg_digest_update(struct iscsi_tcp_conn *tcp_conn, - struct scatterlist *sg, int offset, int length) +partial_sg_digest_update(struct iscsi_conn *conn, struct scatterlist *sg, + int offset, int length) { struct scatterlist temp; memcpy(&temp, sg, sizeof(struct scatterlist)); temp.offset = offset; temp.length = length; - crypto_digest_update(tcp_conn->data_rx_tfm, &temp, 1); + crypto_digest_update(conn->data_rx_tfm, &temp, 1); } static void -iscsi_recv_digest_update(struct iscsi_tcp_conn *tcp_conn, char* buf, int len) +iscsi_recv_digest_update(struct iscsi_conn *conn, char* buf, int len) { struct scatterlist tmp; sg_init_one(&tmp, buf, len); - crypto_digest_update(tcp_conn->data_rx_tfm, &tmp, 1); + crypto_digest_update(conn->data_rx_tfm, &tmp, 1); } static int iscsi_scsi_data_in(struct iscsi_conn *conn) { - struct iscsi_tcp_conn *tcp_conn = conn->dd_data; - struct iscsi_cmd_task *ctask = tcp_conn->in.ctask; - struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; + struct iscsi_cmd_task *ctask = conn->in.ctask; struct scsi_cmnd *sc = ctask->sc; struct scatterlist *sg; int i, offset, rc = 0; @@ -678,33 +919,31 @@ static int iscsi_scsi_data_in(struct iscsi_conn *conn) */ if (!sc->use_sg) { i = ctask->data_count; - rc = iscsi_ctask_copy(tcp_conn, ctask, sc->request_buffer, - sc->request_bufflen, - tcp_ctask->data_offset); + rc = iscsi_ctask_copy(conn, ctask, sc->request_buffer, + sc->request_bufflen, ctask->data_offset); if (rc == -EAGAIN) return rc; if (conn->datadgst_en) - iscsi_recv_digest_update(tcp_conn, sc->request_buffer, - i); + iscsi_recv_digest_update(conn, sc->request_buffer, i); rc = 0; goto done; } - offset = tcp_ctask->data_offset; + offset = ctask->data_offset; sg = sc->request_buffer; - if (tcp_ctask->data_offset) - for (i = 0; i < tcp_ctask->sg_count; i++) + if (ctask->data_offset) + for (i = 0; i < ctask->sg_count; i++) offset -= sg[i].length; /* we've passed through partial sg*/ if (offset < 0) offset = 0; - for (i = tcp_ctask->sg_count; i < sc->use_sg; i++) { + for (i = ctask->sg_count; i < sc->use_sg; i++) { char *dest; dest = kmap_atomic(sg[i].page, KM_SOFTIRQ0); - rc = iscsi_ctask_copy(tcp_conn, ctask, dest + sg[i].offset, + rc = iscsi_ctask_copy(conn, ctask, dest + sg[i].offset, sg[i].length, offset); kunmap_atomic(dest, KM_SOFTIRQ0); if (rc == -EAGAIN) @@ -713,17 +952,15 @@ static int iscsi_scsi_data_in(struct iscsi_conn *conn) if (!rc) { if (conn->datadgst_en) { if (!offset) - crypto_digest_update( - tcp_conn->data_rx_tfm, - &sg[i], 1); + crypto_digest_update(conn->data_rx_tfm, + &sg[i], 1); else - partial_sg_digest_update(tcp_conn, - &sg[i], + partial_sg_digest_update(conn, &sg[i], sg[i].offset + offset, sg[i].length - offset); } offset = 0; - tcp_ctask->sg_count++; + ctask->sg_count++; } if (!ctask->data_count) { @@ -731,26 +968,25 @@ static int iscsi_scsi_data_in(struct iscsi_conn *conn) /* * data-in is complete, but buffer not... */ - partial_sg_digest_update(tcp_conn, &sg[i], + partial_sg_digest_update(conn, &sg[i], sg[i].offset, sg[i].length-rc); rc = 0; break; } - if (!tcp_conn->in.copy) + if (!conn->in.copy) return -EAGAIN; } BUG_ON(ctask->data_count); done: /* check for non-exceptional status */ - if (tcp_conn->in.hdr->flags & ISCSI_FLAG_DATA_STATUS) { + if (conn->in.flags & ISCSI_FLAG_DATA_STATUS) { debug_scsi("done [sc %lx res %d itt 0x%x]\n", (long)sc, sc->result, ctask->itt); - spin_lock(&conn->session->lock); - __iscsi_ctask_cleanup(conn, ctask); - __iscsi_complete_pdu(conn, tcp_conn->in.hdr, NULL, 0); - spin_unlock(&conn->session->lock); + conn->scsirsp_pdus_cnt++; + iscsi_ctask_cleanup(conn, ctask); + sc->scsi_done(sc); } return rc; @@ -759,38 +995,71 @@ done: static int iscsi_data_recv(struct iscsi_conn *conn) { - struct iscsi_tcp_conn *tcp_conn = conn->dd_data; - int rc = 0, opcode; + struct iscsi_session *session = conn->session; + int rc = 0; - opcode = tcp_conn->in.hdr->opcode & ISCSI_OPCODE_MASK; - switch (opcode) { + switch(conn->in.opcode) { case ISCSI_OP_SCSI_DATA_IN: rc = iscsi_scsi_data_in(conn); break; - case ISCSI_OP_SCSI_CMD_RSP: - spin_lock(&conn->session->lock); - __iscsi_ctask_cleanup(conn, tcp_conn->in.ctask); - spin_unlock(&conn->session->lock); + case ISCSI_OP_SCSI_CMD_RSP: { + /* + * SCSI Sense Data: + * copying the entire Data Segment. + */ + if (iscsi_tcp_copy(conn, conn->data, conn->in.datalen)) { + rc = -EAGAIN; + goto exit; + } + + /* + * check for sense + */ + conn->in.hdr = &conn->hdr; + conn->senselen = (conn->data[0] << 8) | conn->data[1]; + rc = iscsi_cmd_rsp(conn, conn->in.ctask); + if (!rc && conn->datadgst_en) + iscsi_recv_digest_update(conn, conn->data, + conn->in.datalen); + } + break; case ISCSI_OP_TEXT_RSP: case ISCSI_OP_LOGIN_RSP: - case ISCSI_OP_NOOP_IN: - case ISCSI_OP_ASYNC_EVENT: - case ISCSI_OP_REJECT: + case ISCSI_OP_NOOP_IN: { + struct iscsi_mgmt_task *mtask = NULL; + + if (conn->in.itt != ISCSI_RESERVED_TAG) + mtask = (struct iscsi_mgmt_task *) + session->mgmt_cmds[conn->in.itt - + ISCSI_MGMT_ITT_OFFSET]; + /* * Collect data segment to the connection's data * placeholder */ - if (iscsi_tcp_copy(tcp_conn)) { + if (iscsi_tcp_copy(conn, conn->data, conn->in.datalen)) { rc = -EAGAIN; goto exit; } - 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, tcp_conn->data, - tcp_conn->in.datalen); - break; + rc = iscsi_recv_pdu(conn->cls_conn, conn->in.hdr, + conn->data, conn->in.datalen); + + if (!rc && conn->datadgst_en && + conn->in.opcode != ISCSI_OP_LOGIN_RSP) + iscsi_recv_digest_update(conn, conn->data, + conn->in.datalen); + + if (mtask && conn->login_mtask != mtask) { + spin_lock(&session->lock); + __kfifo_put(session->mgmtpool.queue, (void*)&mtask, + sizeof(void*)); + spin_unlock(&session->lock); + } + } + break; + case ISCSI_OP_ASYNC_EVENT: + case ISCSI_OP_REJECT: default: BUG_ON(1); } @@ -811,7 +1080,6 @@ iscsi_tcp_data_recv(read_descriptor_t *rd_desc, struct sk_buff *skb, { int rc; struct iscsi_conn *conn = rd_desc->arg.data; - struct iscsi_tcp_conn *tcp_conn = conn->dd_data; int processed; char pad[ISCSI_PAD_LEN]; struct scatterlist sg; @@ -820,15 +1088,15 @@ iscsi_tcp_data_recv(read_descriptor_t *rd_desc, struct sk_buff *skb, * Save current SKB and its offset in the corresponding * connection context. */ - tcp_conn->in.copy = skb->len - offset; - tcp_conn->in.offset = offset; - tcp_conn->in.skb = skb; - tcp_conn->in.len = tcp_conn->in.copy; - BUG_ON(tcp_conn->in.copy <= 0); - debug_tcp("in %d bytes\n", tcp_conn->in.copy); + conn->in.copy = skb->len - offset; + conn->in.offset = offset; + conn->in.skb = skb; + conn->in.len = conn->in.copy; + BUG_ON(conn->in.copy <= 0); + debug_tcp("in %d bytes\n", conn->in.copy); more: - tcp_conn->in.copied = 0; + conn->in.copied = 0; rc = 0; if (unlikely(conn->suspend_rx)) { @@ -836,9 +1104,9 @@ more: return 0; } - if (tcp_conn->in_progress == IN_PROGRESS_WAIT_HEADER || - tcp_conn->in_progress == IN_PROGRESS_HEADER_GATHER) { - rc = iscsi_hdr_extract(tcp_conn); + if (conn->in_progress == IN_PROGRESS_WAIT_HEADER || + conn->in_progress == IN_PROGRESS_HEADER_GATHER) { + rc = iscsi_hdr_extract(conn); if (rc) { if (rc == -EAGAIN) goto nomore; @@ -851,91 +1119,90 @@ more: /* * Verify and process incoming PDU header. */ - rc = iscsi_tcp_hdr_recv(conn); - if (!rc && tcp_conn->in.datalen) { + rc = iscsi_hdr_recv(conn); + if (!rc && conn->in.datalen) { if (conn->datadgst_en) { - BUG_ON(!tcp_conn->data_rx_tfm); - crypto_digest_init(tcp_conn->data_rx_tfm); + BUG_ON(!conn->data_rx_tfm); + crypto_digest_init(conn->data_rx_tfm); } - tcp_conn->in_progress = IN_PROGRESS_DATA_RECV; + conn->in_progress = IN_PROGRESS_DATA_RECV; } else if (rc) { iscsi_conn_failure(conn, rc); return 0; } } - if (tcp_conn->in_progress == IN_PROGRESS_DDIGEST_RECV) { + if (conn->in_progress == IN_PROGRESS_DDIGEST_RECV) { uint32_t recv_digest; - debug_tcp("extra data_recv offset %d copy %d\n", - tcp_conn->in.offset, tcp_conn->in.copy); - skb_copy_bits(tcp_conn->in.skb, tcp_conn->in.offset, + conn->in.offset, conn->in.copy); + skb_copy_bits(conn->in.skb, conn->in.offset, &recv_digest, 4); - tcp_conn->in.offset += 4; - tcp_conn->in.copy -= 4; - if (recv_digest != tcp_conn->in.datadgst) { + conn->in.offset += 4; + conn->in.copy -= 4; + if (recv_digest != conn->in.datadgst) { debug_tcp("iscsi_tcp: data digest error!" "0x%x != 0x%x\n", recv_digest, - tcp_conn->in.datadgst); + conn->in.datadgst); iscsi_conn_failure(conn, ISCSI_ERR_DATA_DGST); return 0; } else { debug_tcp("iscsi_tcp: data digest match!" "0x%x == 0x%x\n", recv_digest, - tcp_conn->in.datadgst); - tcp_conn->in_progress = IN_PROGRESS_WAIT_HEADER; + conn->in.datadgst); + conn->in_progress = IN_PROGRESS_WAIT_HEADER; } } - if (tcp_conn->in_progress == IN_PROGRESS_DATA_RECV && - tcp_conn->in.copy) { + if (conn->in_progress == IN_PROGRESS_DATA_RECV && conn->in.copy) { debug_tcp("data_recv offset %d copy %d\n", - tcp_conn->in.offset, tcp_conn->in.copy); + conn->in.offset, conn->in.copy); rc = iscsi_data_recv(conn); if (rc) { - if (rc == -EAGAIN) + if (rc == -EAGAIN) { + rd_desc->count = conn->in.datalen - + conn->in.ctask->data_count; goto again; + } iscsi_conn_failure(conn, rc); return 0; } - tcp_conn->in.copy -= tcp_conn->in.padding; - tcp_conn->in.offset += tcp_conn->in.padding; + conn->in.copy -= conn->in.padding; + conn->in.offset += conn->in.padding; if (conn->datadgst_en) { - if (tcp_conn->in.padding) { - debug_tcp("padding -> %d\n", - tcp_conn->in.padding); - memset(pad, 0, tcp_conn->in.padding); - sg_init_one(&sg, pad, tcp_conn->in.padding); - crypto_digest_update(tcp_conn->data_rx_tfm, - &sg, 1); + if (conn->in.padding) { + debug_tcp("padding -> %d\n", conn->in.padding); + memset(pad, 0, conn->in.padding); + sg_init_one(&sg, pad, conn->in.padding); + crypto_digest_update(conn->data_rx_tfm, &sg, 1); } - crypto_digest_final(tcp_conn->data_rx_tfm, - (u8 *) & tcp_conn->in.datadgst); - debug_tcp("rx digest 0x%x\n", tcp_conn->in.datadgst); - tcp_conn->in_progress = IN_PROGRESS_DDIGEST_RECV; + crypto_digest_final(conn->data_rx_tfm, + (u8 *) & conn->in.datadgst); + debug_tcp("rx digest 0x%x\n", conn->in.datadgst); + conn->in_progress = IN_PROGRESS_DDIGEST_RECV; } else - tcp_conn->in_progress = IN_PROGRESS_WAIT_HEADER; + conn->in_progress = IN_PROGRESS_WAIT_HEADER; } debug_tcp("f, processed %d from out of %d padding %d\n", - tcp_conn->in.offset - offset, (int)len, tcp_conn->in.padding); - BUG_ON(tcp_conn->in.offset - offset > len); + conn->in.offset - offset, (int)len, conn->in.padding); + BUG_ON(conn->in.offset - offset > len); - if (tcp_conn->in.offset - offset != len) { + if (conn->in.offset - offset != len) { debug_tcp("continue to process %d bytes\n", - (int)len - (tcp_conn->in.offset - offset)); + (int)len - (conn->in.offset - offset)); goto more; } nomore: - processed = tcp_conn->in.offset - offset; + processed = conn->in.offset - offset; BUG_ON(processed == 0); return processed; again: - processed = tcp_conn->in.offset - offset; + processed = conn->in.offset - offset; debug_tcp("c, processed %d from out of %d rd_desc_cnt %d\n", processed, (int)len, (int)rd_desc->count); BUG_ON(processed == 0); @@ -953,14 +1220,9 @@ iscsi_tcp_data_ready(struct sock *sk, int flag) read_lock(&sk->sk_callback_lock); - /* - * Use rd_desc to pass 'conn' to iscsi_tcp_data_recv. - * We set count to 1 because we want the network layer to - * hand us all the skbs that are available. iscsi_tcp_data_recv - * handled pdus that cross buffers or pdus that still need data. - */ + /* use rd_desc to pass 'conn' to iscsi_tcp_data_recv */ rd_desc.arg.data = conn; - rd_desc.count = 1; + rd_desc.count = 0; tcp_read_sock(sk, &rd_desc, iscsi_tcp_data_recv); read_unlock(&sk->sk_callback_lock); @@ -969,7 +1231,6 @@ iscsi_tcp_data_ready(struct sock *sk, int flag) static void iscsi_tcp_state_change(struct sock *sk) { - struct iscsi_tcp_conn *tcp_conn; struct iscsi_conn *conn; struct iscsi_session *session; void (*old_state_change)(struct sock *); @@ -986,8 +1247,7 @@ iscsi_tcp_state_change(struct sock *sk) iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); } - tcp_conn = conn->dd_data; - old_state_change = tcp_conn->old_state_change; + old_state_change = conn->old_state_change; read_unlock(&sk->sk_callback_lock); @@ -1002,25 +1262,23 @@ static void iscsi_write_space(struct sock *sk) { struct iscsi_conn *conn = (struct iscsi_conn*)sk->sk_user_data; - struct iscsi_tcp_conn *tcp_conn = conn->dd_data; - - tcp_conn->old_write_space(sk); + conn->old_write_space(sk); debug_tcp("iscsi_write_space: cid %d\n", conn->id); + clear_bit(SUSPEND_BIT, &conn->suspend_tx); scsi_queue_work(conn->session->host, &conn->xmitwork); } static void iscsi_conn_set_callbacks(struct iscsi_conn *conn) { - struct iscsi_tcp_conn *tcp_conn = conn->dd_data; - struct sock *sk = tcp_conn->sock->sk; + struct sock *sk = conn->sock->sk; /* assign new callbacks */ write_lock_bh(&sk->sk_callback_lock); sk->sk_user_data = conn; - tcp_conn->old_data_ready = sk->sk_data_ready; - tcp_conn->old_state_change = sk->sk_state_change; - tcp_conn->old_write_space = sk->sk_write_space; + conn->old_data_ready = sk->sk_data_ready; + conn->old_state_change = sk->sk_state_change; + conn->old_write_space = sk->sk_write_space; sk->sk_data_ready = iscsi_tcp_data_ready; sk->sk_state_change = iscsi_tcp_state_change; sk->sk_write_space = iscsi_write_space; @@ -1030,15 +1288,14 @@ iscsi_conn_set_callbacks(struct iscsi_conn *conn) static void iscsi_conn_restore_callbacks(struct iscsi_conn *conn) { - struct iscsi_tcp_conn *tcp_conn = conn->dd_data; - struct sock *sk = tcp_conn->sock->sk; + struct sock *sk = conn->sock->sk; /* restore socket callbacks, see also: iscsi_conn_set_callbacks() */ write_lock_bh(&sk->sk_callback_lock); sk->sk_user_data = NULL; - sk->sk_data_ready = tcp_conn->old_data_ready; - sk->sk_state_change = tcp_conn->old_state_change; - sk->sk_write_space = tcp_conn->old_write_space; + sk->sk_data_ready = conn->old_data_ready; + sk->sk_state_change = conn->old_state_change; + sk->sk_write_space = conn->old_write_space; sk->sk_no_check = 0; write_unlock_bh(&sk->sk_callback_lock); } @@ -1053,9 +1310,8 @@ iscsi_conn_restore_callbacks(struct iscsi_conn *conn) static inline int iscsi_send(struct iscsi_conn *conn, struct iscsi_buf *buf, int size, int flags) { - struct iscsi_tcp_conn *tcp_conn = conn->dd_data; - struct socket *sk = tcp_conn->sock; - int offset = buf->sg.offset + buf->sent, res; + struct socket *sk = conn->sock; + int offset = buf->sg.offset + buf->sent; /* * if we got use_sg=0 or are sending something we kmallocd @@ -1066,22 +1322,9 @@ iscsi_send(struct iscsi_conn *conn, struct iscsi_buf *buf, int size, int flags) * slab case. */ if (buf->use_sendmsg) - res = sock_no_sendpage(sk, buf->sg.page, offset, size, flags); - else - res = tcp_conn->sendpage(sk, buf->sg.page, offset, size, flags); - - if (res >= 0) { - conn->txdata_octets += res; - buf->sent += res; - return res; - } - - tcp_conn->sendpage_failures_cnt++; - if (res == -EAGAIN) - res = -ENOBUFS; + return sock_no_sendpage(sk, buf->sg.page, offset, size, flags); else - iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); - return res; + return conn->sendpage(sk, buf->sg.page, offset, size, flags); } /** @@ -1107,10 +1350,16 @@ iscsi_sendhdr(struct iscsi_conn *conn, struct iscsi_buf *buf, int datalen) res = iscsi_send(conn, buf, size, flags); debug_tcp("sendhdr %d bytes, sent %d res %d\n", size, buf->sent, res); if (res >= 0) { + conn->txdata_octets += res; + buf->sent += res; if (size != res) return -EAGAIN; return 0; - } + } else if (res == -EAGAIN) { + conn->sendpage_failures_cnt++; + set_bit(SUSPEND_BIT, &conn->suspend_tx); + } else if (res == -EPIPE) + iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); return res; } @@ -1143,46 +1392,47 @@ iscsi_sendpage(struct iscsi_conn *conn, struct iscsi_buf *buf, debug_tcp("sendpage: %d bytes, sent %d left %d sent %d res %d\n", size, buf->sent, *count, *sent, res); if (res >= 0) { + conn->txdata_octets += res; + buf->sent += res; *count -= res; *sent += res; if (size != res) return -EAGAIN; return 0; - } + } else if (res == -EAGAIN) { + conn->sendpage_failures_cnt++; + set_bit(SUSPEND_BIT, &conn->suspend_tx); + } else if (res == -EPIPE) + iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); return res; } static inline void -iscsi_data_digest_init(struct iscsi_tcp_conn *tcp_conn, - struct iscsi_cmd_task *ctask) +iscsi_data_digest_init(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) { - struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; - - BUG_ON(!tcp_conn->data_tx_tfm); - crypto_digest_init(tcp_conn->data_tx_tfm); - tcp_ctask->digest_count = 4; + BUG_ON(!conn->data_tx_tfm); + crypto_digest_init(conn->data_tx_tfm); + ctask->digest_count = 4; } static int iscsi_digest_final_send(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask, struct iscsi_buf *buf, uint32_t *digest, int final) { - struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; - struct iscsi_tcp_conn *tcp_conn = conn->dd_data; int rc = 0; int sent = 0; if (final) - crypto_digest_final(tcp_conn->data_tx_tfm, (u8*)digest); + crypto_digest_final(conn->data_tx_tfm, (u8*)digest); - iscsi_buf_init_iov(buf, (char*)digest, 4); - rc = iscsi_sendpage(conn, buf, &tcp_ctask->digest_count, &sent); + iscsi_buf_init_virt(buf, (char*)digest, 4); + rc = iscsi_sendpage(conn, buf, &ctask->digest_count, &sent); if (rc) { - tcp_ctask->datadigest = *digest; - tcp_ctask->xmstate |= XMSTATE_DATA_DIGEST; + ctask->datadigest = *digest; + ctask->xmstate |= XMSTATE_DATA_DIGEST; } else - tcp_ctask->digest_count = 4; + ctask->digest_count = 4; return rc; } @@ -1203,19 +1453,21 @@ static void iscsi_solicit_data_cont(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask, struct iscsi_r2t_info *r2t, int left) { - struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; struct iscsi_data *hdr; + struct iscsi_data_task *dtask; struct scsi_cmnd *sc = ctask->sc; int new_offset; - hdr = &r2t->dtask.hdr; + dtask = mempool_alloc(ctask->datapool, GFP_ATOMIC); + BUG_ON(!dtask); + hdr = &dtask->hdr; memset(hdr, 0, sizeof(struct iscsi_data)); hdr->ttt = r2t->ttt; hdr->datasn = cpu_to_be32(r2t->solicit_datasn); r2t->solicit_datasn++; hdr->opcode = ISCSI_OP_SCSI_DATA_OUT; - memcpy(hdr->lun, ctask->hdr->lun, sizeof(hdr->lun)); - hdr->itt = ctask->hdr->itt; + memcpy(hdr->lun, ctask->hdr.lun, sizeof(hdr->lun)); + hdr->itt = ctask->hdr.itt; hdr->exp_statsn = r2t->exp_statsn; new_offset = r2t->data_offset + r2t->sent; hdr->offset = cpu_to_be32(new_offset); @@ -1229,98 +1481,181 @@ iscsi_solicit_data_cont(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask, } conn->dataout_pdus_cnt++; - iscsi_buf_init_iov(&r2t->headbuf, (char*)hdr, + iscsi_buf_init_virt(&r2t->headbuf, (char*)hdr, sizeof(struct iscsi_hdr)); + r2t->dtask = dtask; + if (sc->use_sg && !iscsi_buf_left(&r2t->sendbuf)) { - BUG_ON(tcp_ctask->bad_sg == r2t->sg); + BUG_ON(ctask->bad_sg == r2t->sg); iscsi_buf_init_sg(&r2t->sendbuf, r2t->sg); r2t->sg += 1; } else - iscsi_buf_init_iov(&tcp_ctask->sendbuf, + iscsi_buf_init_iov(&ctask->sendbuf, (char*)sc->request_buffer + new_offset, r2t->data_count); + + list_add(&dtask->item, &ctask->dataqueue); } static void iscsi_unsolicit_data_init(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) { - struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; + struct iscsi_data *hdr; struct iscsi_data_task *dtask; - dtask = tcp_ctask->dtask = &tcp_ctask->unsol_dtask; - iscsi_prep_unsolicit_data_pdu(ctask, &dtask->hdr, - tcp_ctask->r2t_data_count); - iscsi_buf_init_iov(&tcp_ctask->headbuf, (char*)&dtask->hdr, + dtask = mempool_alloc(ctask->datapool, GFP_ATOMIC); + BUG_ON(!dtask); + hdr = &dtask->hdr; + memset(hdr, 0, sizeof(struct iscsi_data)); + hdr->ttt = cpu_to_be32(ISCSI_RESERVED_TAG); + hdr->datasn = cpu_to_be32(ctask->unsol_datasn); + ctask->unsol_datasn++; + hdr->opcode = ISCSI_OP_SCSI_DATA_OUT; + memcpy(hdr->lun, ctask->hdr.lun, sizeof(hdr->lun)); + hdr->itt = ctask->hdr.itt; + hdr->exp_statsn = cpu_to_be32(conn->exp_statsn); + hdr->offset = cpu_to_be32(ctask->total_length - + ctask->r2t_data_count - + ctask->unsol_count); + if (ctask->unsol_count > conn->max_xmit_dlength) { + hton24(hdr->dlength, conn->max_xmit_dlength); + ctask->data_count = conn->max_xmit_dlength; + hdr->flags = 0; + } else { + hton24(hdr->dlength, ctask->unsol_count); + ctask->data_count = ctask->unsol_count; + hdr->flags = ISCSI_FLAG_CMD_FINAL; + } + + iscsi_buf_init_virt(&ctask->headbuf, (char*)hdr, sizeof(struct iscsi_hdr)); + + list_add(&dtask->item, &ctask->dataqueue); + + ctask->dtask = dtask; } /** - * iscsi_tcp_cmd_init - Initialize iSCSI SCSI_READ or SCSI_WRITE commands + * iscsi_cmd_init - Initialize iSCSI SCSI_READ or SCSI_WRITE commands * @conn: iscsi connection * @ctask: scsi command task * @sc: scsi command **/ static void -iscsi_tcp_cmd_init(struct iscsi_cmd_task *ctask) +iscsi_cmd_init(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask, + struct scsi_cmnd *sc) { - struct scsi_cmnd *sc = ctask->sc; - struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; + struct iscsi_session *session = conn->session; - BUG_ON(__kfifo_len(tcp_ctask->r2tqueue)); + BUG_ON(__kfifo_len(ctask->r2tqueue)); - tcp_ctask->sent = 0; - tcp_ctask->sg_count = 0; + ctask->sc = sc; + ctask->conn = conn; + ctask->hdr.opcode = ISCSI_OP_SCSI_CMD; + ctask->hdr.flags = ISCSI_ATTR_SIMPLE; + int_to_scsilun(sc->device->lun, (struct scsi_lun *)ctask->hdr.lun); + ctask->hdr.itt = ctask->itt | (conn->id << CID_SHIFT) | + (session->age << AGE_SHIFT); + ctask->hdr.data_length = cpu_to_be32(sc->request_bufflen); + ctask->hdr.cmdsn = cpu_to_be32(session->cmdsn); session->cmdsn++; + ctask->hdr.exp_statsn = cpu_to_be32(conn->exp_statsn); + memcpy(ctask->hdr.cdb, sc->cmnd, sc->cmd_len); + memset(&ctask->hdr.cdb[sc->cmd_len], 0, MAX_COMMAND_SIZE - sc->cmd_len); + + ctask->mtask = NULL; + ctask->sent = 0; + ctask->sg_count = 0; + + ctask->total_length = sc->request_bufflen; if (sc->sc_data_direction == DMA_TO_DEVICE) { - tcp_ctask->xmstate = XMSTATE_W_HDR; - tcp_ctask->exp_r2tsn = 0; + ctask->exp_r2tsn = 0; + ctask->hdr.flags |= ISCSI_FLAG_CMD_WRITE; BUG_ON(ctask->total_length == 0); - if (sc->use_sg) { struct scatterlist *sg = sc->request_buffer; - iscsi_buf_init_sg(&tcp_ctask->sendbuf, - &sg[tcp_ctask->sg_count++]); - tcp_ctask->sg = sg; - tcp_ctask->bad_sg = sg + sc->use_sg; - } else - iscsi_buf_init_iov(&tcp_ctask->sendbuf, - sc->request_buffer, - sc->request_bufflen); - - if (ctask->imm_count) - tcp_ctask->xmstate |= XMSTATE_IMM_DATA; + iscsi_buf_init_sg(&ctask->sendbuf, + &sg[ctask->sg_count++]); + ctask->sg = sg; + ctask->bad_sg = sg + sc->use_sg; + } else { + iscsi_buf_init_iov(&ctask->sendbuf, sc->request_buffer, + sc->request_bufflen); + } - tcp_ctask->pad_count = ctask->total_length & (ISCSI_PAD_LEN-1); - if (tcp_ctask->pad_count) { - tcp_ctask->pad_count = ISCSI_PAD_LEN - - tcp_ctask->pad_count; + /* + * Write counters: + * + * imm_count bytes to be sent right after + * SCSI PDU Header + * + * unsol_count bytes(as Data-Out) to be sent + * without R2T ack right after + * immediate data + * + * r2t_data_count bytes to be sent via R2T ack's + * + * pad_count bytes to be sent as zero-padding + */ + ctask->imm_count = 0; + ctask->unsol_count = 0; + ctask->unsol_datasn = 0; + ctask->xmstate = XMSTATE_W_HDR; + /* calculate write padding */ + ctask->pad_count = ctask->total_length & (ISCSI_PAD_LEN-1); + if (ctask->pad_count) { + ctask->pad_count = ISCSI_PAD_LEN - ctask->pad_count; debug_scsi("write padding %d bytes\n", - tcp_ctask->pad_count); - tcp_ctask->xmstate |= XMSTATE_W_PAD; + ctask->pad_count); + ctask->xmstate |= XMSTATE_W_PAD; } + if (session->imm_data_en) { + if (ctask->total_length >= session->first_burst) + ctask->imm_count = min(session->first_burst, + conn->max_xmit_dlength); + else + ctask->imm_count = min(ctask->total_length, + conn->max_xmit_dlength); + hton24(ctask->hdr.dlength, ctask->imm_count); + ctask->xmstate |= XMSTATE_IMM_DATA; + } else + zero_data(ctask->hdr.dlength); + + if (!session->initial_r2t_en) + ctask->unsol_count = min(session->first_burst, + ctask->total_length) - ctask->imm_count; + if (!ctask->unsol_count) + /* No unsolicit Data-Out's */ + ctask->hdr.flags |= ISCSI_FLAG_CMD_FINAL; + else + ctask->xmstate |= XMSTATE_UNS_HDR | XMSTATE_UNS_INIT; - if (ctask->unsol_count) - tcp_ctask->xmstate |= XMSTATE_UNS_HDR | - XMSTATE_UNS_INIT; - tcp_ctask->r2t_data_count = ctask->total_length - + ctask->r2t_data_count = ctask->total_length - ctask->imm_count - ctask->unsol_count; 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); - } else - tcp_ctask->xmstate = XMSTATE_R_HDR; + ctask->unsol_count, ctask->r2t_data_count); + } else { + ctask->hdr.flags |= ISCSI_FLAG_CMD_FINAL; + if (sc->sc_data_direction == DMA_FROM_DEVICE) + ctask->hdr.flags |= ISCSI_FLAG_CMD_READ; + ctask->datasn = 0; + ctask->xmstate = XMSTATE_R_HDR; + zero_data(ctask->hdr.dlength); + } - iscsi_buf_init_iov(&tcp_ctask->headbuf, (char*)ctask->hdr, + iscsi_buf_init_virt(&ctask->headbuf, (char*)&ctask->hdr, sizeof(struct iscsi_hdr)); + conn->scsicmd_pdus_cnt++; } /** - * iscsi_tcp_mtask_xmit - xmit management(immediate) task + * iscsi_mtask_xmit - xmit management(immediate) task * @conn: iscsi connection * @mtask: task management task * @@ -1334,167 +1669,132 @@ iscsi_tcp_cmd_init(struct iscsi_cmd_task *ctask) * IN_PROGRESS_IMM_DATA - PDU Data xmit in progress **/ static int -iscsi_tcp_mtask_xmit(struct iscsi_conn *conn, struct iscsi_mgmt_task *mtask) +iscsi_mtask_xmit(struct iscsi_conn *conn, struct iscsi_mgmt_task *mtask) { - struct iscsi_tcp_mgmt_task *tcp_mtask = mtask->dd_data; - int rc; debug_scsi("mtask deq [cid %d state %x itt 0x%x]\n", - conn->id, tcp_mtask->xmstate, mtask->itt); + conn->id, mtask->xmstate, mtask->itt); - if (tcp_mtask->xmstate & XMSTATE_IMM_HDR) { - tcp_mtask->xmstate &= ~XMSTATE_IMM_HDR; + if (mtask->xmstate & XMSTATE_IMM_HDR) { + mtask->xmstate &= ~XMSTATE_IMM_HDR; if (mtask->data_count) - tcp_mtask->xmstate |= XMSTATE_IMM_DATA; + mtask->xmstate |= XMSTATE_IMM_DATA; if (conn->c_stage != ISCSI_CONN_INITIAL_STAGE && - conn->stop_stage != STOP_CONN_RECOVER && + conn->stop_stage != STOP_CONN_RECOVER && conn->hdrdgst_en) - iscsi_hdr_digest(conn, &tcp_mtask->headbuf, - (u8*)tcp_mtask->hdrext); - rc = iscsi_sendhdr(conn, &tcp_mtask->headbuf, - mtask->data_count); - if (rc) { - tcp_mtask->xmstate |= XMSTATE_IMM_HDR; + iscsi_hdr_digest(conn, &mtask->headbuf, + (u8*)mtask->hdrext); + if (iscsi_sendhdr(conn, &mtask->headbuf, mtask->data_count)) { + mtask->xmstate |= XMSTATE_IMM_HDR; if (mtask->data_count) - tcp_mtask->xmstate &= ~XMSTATE_IMM_DATA; - return rc; + mtask->xmstate &= ~XMSTATE_IMM_DATA; + return -EAGAIN; } } - if (tcp_mtask->xmstate & XMSTATE_IMM_DATA) { + if (mtask->xmstate & XMSTATE_IMM_DATA) { BUG_ON(!mtask->data_count); - tcp_mtask->xmstate &= ~XMSTATE_IMM_DATA; + mtask->xmstate &= ~XMSTATE_IMM_DATA; /* FIXME: implement. * Virtual buffer could be spreaded across multiple pages... */ do { - int rc; - - rc = iscsi_sendpage(conn, &tcp_mtask->sendbuf, - &mtask->data_count, &tcp_mtask->sent); - if (rc) { - tcp_mtask->xmstate |= XMSTATE_IMM_DATA; - return rc; + if (iscsi_sendpage(conn, &mtask->sendbuf, + &mtask->data_count, &mtask->sent)) { + mtask->xmstate |= XMSTATE_IMM_DATA; + return -EAGAIN; } } while (mtask->data_count); } - BUG_ON(tcp_mtask->xmstate != XMSTATE_IDLE); - if (mtask->hdr->itt == cpu_to_be32(ISCSI_RESERVED_TAG)) { - struct iscsi_session *session = conn->session; - - spin_lock_bh(&session->lock); - list_del(&conn->mtask->running); - __kfifo_put(session->mgmtpool.queue, (void*)&conn->mtask, - sizeof(void*)); - spin_unlock_bh(&session->lock); - } + BUG_ON(mtask->xmstate != XMSTATE_IDLE); return 0; } static inline int -handle_xmstate_r_hdr(struct iscsi_conn *conn, - struct iscsi_tcp_cmd_task *tcp_ctask) +handle_xmstate_r_hdr(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) { - int rc; - - tcp_ctask->xmstate &= ~XMSTATE_R_HDR; + ctask->xmstate &= ~XMSTATE_R_HDR; if (conn->hdrdgst_en) - iscsi_hdr_digest(conn, &tcp_ctask->headbuf, - (u8*)tcp_ctask->hdrext); - rc = iscsi_sendhdr(conn, &tcp_ctask->headbuf, 0); - if (!rc) { - BUG_ON(tcp_ctask->xmstate != XMSTATE_IDLE); + iscsi_hdr_digest(conn, &ctask->headbuf, (u8*)ctask->hdrext); + if (!iscsi_sendhdr(conn, &ctask->headbuf, 0)) { + BUG_ON(ctask->xmstate != XMSTATE_IDLE); return 0; /* wait for Data-In */ } - tcp_ctask->xmstate |= XMSTATE_R_HDR; - return rc; + ctask->xmstate |= XMSTATE_R_HDR; + return -EAGAIN; } static inline int -handle_xmstate_w_hdr(struct iscsi_conn *conn, - struct iscsi_cmd_task *ctask) +handle_xmstate_w_hdr(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) { - struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; - int rc; - - tcp_ctask->xmstate &= ~XMSTATE_W_HDR; + ctask->xmstate &= ~XMSTATE_W_HDR; if (conn->hdrdgst_en) - iscsi_hdr_digest(conn, &tcp_ctask->headbuf, - (u8*)tcp_ctask->hdrext); - rc = iscsi_sendhdr(conn, &tcp_ctask->headbuf, ctask->imm_count); - if (rc) - tcp_ctask->xmstate |= XMSTATE_W_HDR; - return rc; + iscsi_hdr_digest(conn, &ctask->headbuf, (u8*)ctask->hdrext); + if (iscsi_sendhdr(conn, &ctask->headbuf, ctask->imm_count)) { + ctask->xmstate |= XMSTATE_W_HDR; + return -EAGAIN; + } + return 0; } static inline int handle_xmstate_data_digest(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) { - struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; - int rc; - - tcp_ctask->xmstate &= ~XMSTATE_DATA_DIGEST; - debug_tcp("resent data digest 0x%x\n", tcp_ctask->datadigest); - rc = iscsi_digest_final_send(conn, ctask, &tcp_ctask->immbuf, - &tcp_ctask->datadigest, 0); - if (rc) { - tcp_ctask->xmstate |= XMSTATE_DATA_DIGEST; + ctask->xmstate &= ~XMSTATE_DATA_DIGEST; + debug_tcp("resent data digest 0x%x\n", ctask->datadigest); + if (iscsi_digest_final_send(conn, ctask, &ctask->immbuf, + &ctask->datadigest, 0)) { + ctask->xmstate |= XMSTATE_DATA_DIGEST; debug_tcp("resent data digest 0x%x fail!\n", - tcp_ctask->datadigest); + ctask->datadigest); + return -EAGAIN; } - - return rc; + return 0; } static inline int handle_xmstate_imm_data(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; - int rc; - BUG_ON(!ctask->imm_count); - tcp_ctask->xmstate &= ~XMSTATE_IMM_DATA; + ctask->xmstate &= ~XMSTATE_IMM_DATA; if (conn->datadgst_en) { - iscsi_data_digest_init(tcp_conn, ctask); - tcp_ctask->immdigest = 0; + iscsi_data_digest_init(conn, ctask); + ctask->immdigest = 0; } for (;;) { - rc = iscsi_sendpage(conn, &tcp_ctask->sendbuf, - &ctask->imm_count, &tcp_ctask->sent); - if (rc) { - tcp_ctask->xmstate |= XMSTATE_IMM_DATA; + if (iscsi_sendpage(conn, &ctask->sendbuf, &ctask->imm_count, + &ctask->sent)) { + ctask->xmstate |= XMSTATE_IMM_DATA; if (conn->datadgst_en) { - crypto_digest_final(tcp_conn->data_tx_tfm, - (u8*)&tcp_ctask->immdigest); + crypto_digest_final(conn->data_tx_tfm, + (u8*)&ctask->immdigest); debug_tcp("tx imm sendpage fail 0x%x\n", - tcp_ctask->datadigest); + ctask->datadigest); } - return rc; + return -EAGAIN; } if (conn->datadgst_en) - crypto_digest_update(tcp_conn->data_tx_tfm, - &tcp_ctask->sendbuf.sg, 1); + crypto_digest_update(conn->data_tx_tfm, + &ctask->sendbuf.sg, 1); if (!ctask->imm_count) break; - iscsi_buf_init_sg(&tcp_ctask->sendbuf, - &tcp_ctask->sg[tcp_ctask->sg_count++]); + iscsi_buf_init_sg(&ctask->sendbuf, + &ctask->sg[ctask->sg_count++]); } - if (conn->datadgst_en && !(tcp_ctask->xmstate & XMSTATE_W_PAD)) { - rc = iscsi_digest_final_send(conn, ctask, &tcp_ctask->immbuf, - &tcp_ctask->immdigest, 1); - if (rc) { + if (conn->datadgst_en && !(ctask->xmstate & XMSTATE_W_PAD)) { + if (iscsi_digest_final_send(conn, ctask, &ctask->immbuf, + &ctask->immdigest, 1)) { debug_tcp("sending imm digest 0x%x fail!\n", - tcp_ctask->immdigest); - return rc; + ctask->immdigest); + return -EAGAIN; } - debug_tcp("sending imm digest 0x%x\n", tcp_ctask->immdigest); + debug_tcp("sending imm digest 0x%x\n", ctask->immdigest); } return 0; @@ -1503,81 +1803,74 @@ handle_xmstate_imm_data(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) static inline int handle_xmstate_uns_hdr(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) { - struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; struct iscsi_data_task *dtask; - int rc; - tcp_ctask->xmstate |= XMSTATE_UNS_DATA; - if (tcp_ctask->xmstate & XMSTATE_UNS_INIT) { + ctask->xmstate |= XMSTATE_UNS_DATA; + if (ctask->xmstate & XMSTATE_UNS_INIT) { iscsi_unsolicit_data_init(conn, ctask); - dtask = tcp_ctask->dtask; + BUG_ON(!ctask->dtask); + dtask = ctask->dtask; if (conn->hdrdgst_en) - iscsi_hdr_digest(conn, &tcp_ctask->headbuf, + iscsi_hdr_digest(conn, &ctask->headbuf, (u8*)dtask->hdrext); - tcp_ctask->xmstate &= ~XMSTATE_UNS_INIT; + ctask->xmstate &= ~XMSTATE_UNS_INIT; } - - rc = iscsi_sendhdr(conn, &tcp_ctask->headbuf, ctask->data_count); - if (rc) { - tcp_ctask->xmstate &= ~XMSTATE_UNS_DATA; - tcp_ctask->xmstate |= XMSTATE_UNS_HDR; - return rc; + if (iscsi_sendhdr(conn, &ctask->headbuf, ctask->data_count)) { + ctask->xmstate &= ~XMSTATE_UNS_DATA; + ctask->xmstate |= XMSTATE_UNS_HDR; + return -EAGAIN; } debug_scsi("uns dout [itt 0x%x dlen %d sent %d]\n", - ctask->itt, ctask->unsol_count, tcp_ctask->sent); + ctask->itt, ctask->unsol_count, ctask->sent); return 0; } static inline int handle_xmstate_uns_data(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) { - struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; - struct iscsi_data_task *dtask = tcp_ctask->dtask; - struct iscsi_tcp_conn *tcp_conn = conn->dd_data; - int rc; + struct iscsi_data_task *dtask = ctask->dtask; BUG_ON(!ctask->data_count); - tcp_ctask->xmstate &= ~XMSTATE_UNS_DATA; + ctask->xmstate &= ~XMSTATE_UNS_DATA; if (conn->datadgst_en) { - iscsi_data_digest_init(tcp_conn, ctask); + iscsi_data_digest_init(conn, ctask); dtask->digest = 0; } for (;;) { - int start = tcp_ctask->sent; + int start = ctask->sent; - rc = iscsi_sendpage(conn, &tcp_ctask->sendbuf, - &ctask->data_count, &tcp_ctask->sent); - if (rc) { - ctask->unsol_count -= tcp_ctask->sent - start; - tcp_ctask->xmstate |= XMSTATE_UNS_DATA; + if (iscsi_sendpage(conn, &ctask->sendbuf, &ctask->data_count, + &ctask->sent)) { + ctask->unsol_count -= ctask->sent - start; + ctask->xmstate |= XMSTATE_UNS_DATA; /* will continue with this ctask later.. */ if (conn->datadgst_en) { - crypto_digest_final(tcp_conn->data_tx_tfm, + crypto_digest_final(conn->data_tx_tfm, (u8 *)&dtask->digest); debug_tcp("tx uns data fail 0x%x\n", dtask->digest); } - return rc; + return -EAGAIN; } - BUG_ON(tcp_ctask->sent > ctask->total_length); - ctask->unsol_count -= tcp_ctask->sent - start; + BUG_ON(ctask->sent > ctask->total_length); + ctask->unsol_count -= ctask->sent - start; /* * XXX:we may run here with un-initial sendbuf. * so pass it */ - if (conn->datadgst_en && tcp_ctask->sent - start > 0) - crypto_digest_update(tcp_conn->data_tx_tfm, - &tcp_ctask->sendbuf.sg, 1); + if (conn->datadgst_en && ctask->sent - start > 0) + crypto_digest_update(conn->data_tx_tfm, + &ctask->sendbuf.sg, 1); if (!ctask->data_count) break; - iscsi_buf_init_sg(&tcp_ctask->sendbuf, - &tcp_ctask->sg[tcp_ctask->sg_count++]); + iscsi_buf_init_sg(&ctask->sendbuf, + &ctask->sg[ctask->sg_count++]); } BUG_ON(ctask->unsol_count < 0); @@ -1587,29 +1880,27 @@ handle_xmstate_uns_data(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) */ if (ctask->unsol_count) { if (conn->datadgst_en) { - rc = iscsi_digest_final_send(conn, ctask, + if (iscsi_digest_final_send(conn, ctask, &dtask->digestbuf, - &dtask->digest, 1); - if (rc) { + &dtask->digest, 1)) { debug_tcp("send uns digest 0x%x fail\n", dtask->digest); - return rc; + return -EAGAIN; } debug_tcp("sending uns digest 0x%x, more uns\n", dtask->digest); } - tcp_ctask->xmstate |= XMSTATE_UNS_INIT; + ctask->xmstate |= XMSTATE_UNS_INIT; return 1; } - if (conn->datadgst_en && !(tcp_ctask->xmstate & XMSTATE_W_PAD)) { - rc = iscsi_digest_final_send(conn, ctask, + if (conn->datadgst_en && !(ctask->xmstate & XMSTATE_W_PAD)) { + if (iscsi_digest_final_send(conn, ctask, &dtask->digestbuf, - &dtask->digest, 1); - if (rc) { + &dtask->digest, 1)) { debug_tcp("send last uns digest 0x%x fail\n", dtask->digest); - return rc; + return -EAGAIN; } debug_tcp("sending uns digest 0x%x\n",dtask->digest); } @@ -1621,17 +1912,15 @@ static inline int handle_xmstate_sol_data(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) { struct iscsi_session *session = conn->session; - struct iscsi_tcp_conn *tcp_conn = conn->dd_data; - struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; - struct iscsi_r2t_info *r2t = tcp_ctask->r2t; - struct iscsi_data_task *dtask = &r2t->dtask; - int left, rc; + struct iscsi_r2t_info *r2t = ctask->r2t; + struct iscsi_data_task *dtask = r2t->dtask; + int left; - tcp_ctask->xmstate &= ~XMSTATE_SOL_DATA; - tcp_ctask->dtask = dtask; + ctask->xmstate &= ~XMSTATE_SOL_DATA; + ctask->dtask = dtask; if (conn->datadgst_en) { - iscsi_data_digest_init(tcp_conn, ctask); + iscsi_data_digest_init(conn, ctask); dtask->digest = 0; } solicit_again: @@ -1641,27 +1930,25 @@ solicit_again: if (!r2t->data_count) goto data_out_done; - rc = iscsi_sendpage(conn, &r2t->sendbuf, &r2t->data_count, &r2t->sent); - if (rc) { - tcp_ctask->xmstate |= XMSTATE_SOL_DATA; + if (iscsi_sendpage(conn, &r2t->sendbuf, &r2t->data_count, &r2t->sent)) { + ctask->xmstate |= XMSTATE_SOL_DATA; /* will continue with this ctask later.. */ if (conn->datadgst_en) { - crypto_digest_final(tcp_conn->data_tx_tfm, + crypto_digest_final(conn->data_tx_tfm, (u8 *)&dtask->digest); debug_tcp("r2t data send fail 0x%x\n", dtask->digest); } - return rc; + return -EAGAIN; } BUG_ON(r2t->data_count < 0); if (conn->datadgst_en) - crypto_digest_update(tcp_conn->data_tx_tfm, &r2t->sendbuf.sg, - 1); + crypto_digest_update(conn->data_tx_tfm, &r2t->sendbuf.sg, 1); if (r2t->data_count) { BUG_ON(ctask->sc->use_sg == 0); if (!iscsi_buf_left(&r2t->sendbuf)) { - BUG_ON(tcp_ctask->bad_sg == r2t->sg); + BUG_ON(ctask->bad_sg == r2t->sg); iscsi_buf_init_sg(&r2t->sendbuf, r2t->sg); r2t->sg += 1; } @@ -1677,20 +1964,19 @@ data_out_done: left = r2t->data_length - r2t->sent; if (left) { if (conn->datadgst_en) { - rc = iscsi_digest_final_send(conn, ctask, + if (iscsi_digest_final_send(conn, ctask, &dtask->digestbuf, - &dtask->digest, 1); - if (rc) { + &dtask->digest, 1)) { debug_tcp("send r2t data digest 0x%x" "fail\n", dtask->digest); - return rc; + return -EAGAIN; } debug_tcp("r2t data send digest 0x%x\n", dtask->digest); } iscsi_solicit_data_cont(conn, ctask, r2t, left); - tcp_ctask->xmstate |= XMSTATE_SOL_DATA; - tcp_ctask->xmstate &= ~XMSTATE_SOL_HDR; + ctask->xmstate |= XMSTATE_SOL_DATA; + ctask->xmstate &= ~XMSTATE_SOL_HDR; return 1; } @@ -1698,27 +1984,26 @@ data_out_done: * Done with this R2T. Check if there are more * outstanding R2Ts ready to be processed. */ - BUG_ON(tcp_ctask->r2t_data_count - r2t->data_length < 0); + BUG_ON(ctask->r2t_data_count - r2t->data_length < 0); if (conn->datadgst_en) { - rc = iscsi_digest_final_send(conn, ctask, &dtask->digestbuf, - &dtask->digest, 1); - if (rc) { + if (iscsi_digest_final_send(conn, ctask, &dtask->digestbuf, + &dtask->digest, 1)) { debug_tcp("send last r2t data digest 0x%x" "fail\n", dtask->digest); - return rc; + return -EAGAIN; } debug_tcp("r2t done dout digest 0x%x\n", dtask->digest); } - tcp_ctask->r2t_data_count -= r2t->data_length; - tcp_ctask->r2t = NULL; + ctask->r2t_data_count -= r2t->data_length; + ctask->r2t = NULL; spin_lock_bh(&session->lock); - __kfifo_put(tcp_ctask->r2tpool.queue, (void*)&r2t, sizeof(void*)); + __kfifo_put(ctask->r2tpool.queue, (void*)&r2t, sizeof(void*)); spin_unlock_bh(&session->lock); - if (__kfifo_get(tcp_ctask->r2tqueue, (void*)&r2t, sizeof(void*))) { - tcp_ctask->r2t = r2t; - tcp_ctask->xmstate |= XMSTATE_SOL_DATA; - tcp_ctask->xmstate &= ~XMSTATE_SOL_HDR; + if (__kfifo_get(ctask->r2tqueue, (void*)&r2t, sizeof(void*))) { + ctask->r2t = r2t; + ctask->xmstate |= XMSTATE_SOL_DATA; + ctask->xmstate &= ~XMSTATE_SOL_HDR; return 1; } @@ -1728,44 +2013,36 @@ data_out_done: static inline int 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, rc; - - tcp_ctask->xmstate &= ~XMSTATE_W_PAD; - iscsi_buf_init_iov(&tcp_ctask->sendbuf, (char*)&tcp_ctask->pad, - tcp_ctask->pad_count); - rc = iscsi_sendpage(conn, &tcp_ctask->sendbuf, &tcp_ctask->pad_count, - &sent); - if (rc) { - tcp_ctask->xmstate |= XMSTATE_W_PAD; - return rc; + struct iscsi_data_task *dtask = ctask->dtask; + int sent; + + ctask->xmstate &= ~XMSTATE_W_PAD; + iscsi_buf_init_virt(&ctask->sendbuf, (char*)&ctask->pad, + ctask->pad_count); + if (iscsi_sendpage(conn, &ctask->sendbuf, &ctask->pad_count, &sent)) { + ctask->xmstate |= XMSTATE_W_PAD; + return -EAGAIN; } if (conn->datadgst_en) { - crypto_digest_update(tcp_conn->data_tx_tfm, - &tcp_ctask->sendbuf.sg, 1); + crypto_digest_update(conn->data_tx_tfm, &ctask->sendbuf.sg, 1); /* imm data? */ if (!dtask) { - rc = iscsi_digest_final_send(conn, ctask, - &tcp_ctask->immbuf, - &tcp_ctask->immdigest, 1); - if (rc) { + if (iscsi_digest_final_send(conn, ctask, &ctask->immbuf, + &ctask->immdigest, 1)) { debug_tcp("send padding digest 0x%x" - "fail!\n", tcp_ctask->immdigest); - return rc; + "fail!\n", ctask->immdigest); + return -EAGAIN; } debug_tcp("done with padding, digest 0x%x\n", - tcp_ctask->datadigest); + ctask->datadigest); } else { - rc = iscsi_digest_final_send(conn, ctask, + if (iscsi_digest_final_send(conn, ctask, &dtask->digestbuf, - &dtask->digest, 1); - if (rc) { + &dtask->digest, 1)) { debug_tcp("send padding digest 0x%x" "fail\n", dtask->digest); - return rc; + return -EAGAIN; } debug_tcp("done with padding, digest 0x%x\n", dtask->digest); @@ -1776,13 +2053,12 @@ handle_xmstate_w_pad(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) } static int -iscsi_tcp_ctask_xmit(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) +iscsi_ctask_xmit(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) { - struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; int rc = 0; debug_scsi("ctask deq [cid %d xmstate %x itt 0x%x]\n", - conn->id, tcp_ctask->xmstate, ctask->itt); + conn->id, ctask->xmstate, ctask->itt); /* * serialize with TMF AbortTask @@ -1790,38 +2066,40 @@ iscsi_tcp_ctask_xmit(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) if (ctask->mtask) return rc; - if (tcp_ctask->xmstate & XMSTATE_R_HDR) - return handle_xmstate_r_hdr(conn, tcp_ctask); + if (ctask->xmstate & XMSTATE_R_HDR) { + rc = handle_xmstate_r_hdr(conn, ctask); + return rc; + } - if (tcp_ctask->xmstate & XMSTATE_W_HDR) { + if (ctask->xmstate & XMSTATE_W_HDR) { rc = handle_xmstate_w_hdr(conn, ctask); if (rc) return rc; } /* XXX: for data digest xmit recover */ - if (tcp_ctask->xmstate & XMSTATE_DATA_DIGEST) { + if (ctask->xmstate & XMSTATE_DATA_DIGEST) { rc = handle_xmstate_data_digest(conn, ctask); if (rc) return rc; } - if (tcp_ctask->xmstate & XMSTATE_IMM_DATA) { + if (ctask->xmstate & XMSTATE_IMM_DATA) { rc = handle_xmstate_imm_data(conn, ctask); if (rc) return rc; } - if (tcp_ctask->xmstate & XMSTATE_UNS_HDR) { + if (ctask->xmstate & XMSTATE_UNS_HDR) { BUG_ON(!ctask->unsol_count); - tcp_ctask->xmstate &= ~XMSTATE_UNS_HDR; + ctask->xmstate &= ~XMSTATE_UNS_HDR; unsolicit_head_again: rc = handle_xmstate_uns_hdr(conn, ctask); if (rc) return rc; } - if (tcp_ctask->xmstate & XMSTATE_UNS_DATA) { + if (ctask->xmstate & XMSTATE_UNS_DATA) { rc = handle_xmstate_uns_data(conn, ctask); if (rc == 1) goto unsolicit_head_again; @@ -1830,24 +2108,23 @@ unsolicit_head_again: goto done; } - if (tcp_ctask->xmstate & XMSTATE_SOL_HDR) { + if (ctask->xmstate & XMSTATE_SOL_HDR) { struct iscsi_r2t_info *r2t; - tcp_ctask->xmstate &= ~XMSTATE_SOL_HDR; - tcp_ctask->xmstate |= XMSTATE_SOL_DATA; - if (!tcp_ctask->r2t) - __kfifo_get(tcp_ctask->r2tqueue, (void*)&tcp_ctask->r2t, + ctask->xmstate &= ~XMSTATE_SOL_HDR; + ctask->xmstate |= XMSTATE_SOL_DATA; + if (!ctask->r2t) + __kfifo_get(ctask->r2tqueue, (void*)&ctask->r2t, sizeof(void*)); solicit_head_again: - r2t = tcp_ctask->r2t; + r2t = ctask->r2t; if (conn->hdrdgst_en) iscsi_hdr_digest(conn, &r2t->headbuf, - (u8*)r2t->dtask.hdrext); - rc = iscsi_sendhdr(conn, &r2t->headbuf, r2t->data_count); - if (rc) { - tcp_ctask->xmstate &= ~XMSTATE_SOL_DATA; - tcp_ctask->xmstate |= XMSTATE_SOL_HDR; - return rc; + (u8*)r2t->dtask->hdrext); + if (iscsi_sendhdr(conn, &r2t->headbuf, r2t->data_count)) { + ctask->xmstate &= ~XMSTATE_SOL_DATA; + ctask->xmstate |= XMSTATE_SOL_HDR; + return -EAGAIN; } debug_scsi("sol dout [dsn %d itt 0x%x dlen %d sent %d]\n", @@ -1855,7 +2132,7 @@ solicit_head_again: r2t->sent); } - if (tcp_ctask->xmstate & XMSTATE_SOL_DATA) { + if (ctask->xmstate & XMSTATE_SOL_DATA) { rc = handle_xmstate_sol_data(conn, ctask); if (rc == 1) goto solicit_head_again; @@ -1868,199 +2145,1022 @@ done: * Last thing to check is whether we need to send write * padding. Note that we check for xmstate equality, not just the bit. */ - if (tcp_ctask->xmstate == XMSTATE_W_PAD) + if (ctask->xmstate == XMSTATE_W_PAD) rc = handle_xmstate_w_pad(conn, ctask); return rc; } +/** + * iscsi_data_xmit - xmit any command into the scheduled connection + * @conn: iscsi connection + * + * Notes: + * The function can return -EAGAIN in which case the caller must + * re-schedule it again later or recover. '0' return code means + * successful xmit. + **/ +static int +iscsi_data_xmit(struct iscsi_conn *conn) +{ + if (unlikely(conn->suspend_tx)) { + debug_tcp("conn %d Tx suspended!\n", conn->id); + return 0; + } + + /* + * Transmit in the following order: + * + * 1) un-finished xmit (ctask or mtask) + * 2) immediate control PDUs + * 3) write data + * 4) SCSI commands + * 5) non-immediate control PDUs + * + * No need to lock around __kfifo_get as long as + * there's one producer and one consumer. + */ + + BUG_ON(conn->ctask && conn->mtask); + + if (conn->ctask) { + if (iscsi_ctask_xmit(conn, conn->ctask)) + goto again; + /* done with this in-progress ctask */ + conn->ctask = NULL; + } + if (conn->mtask) { + if (iscsi_mtask_xmit(conn, conn->mtask)) + goto again; + /* done with this in-progress mtask */ + conn->mtask = NULL; + } + + /* process immediate first */ + if (unlikely(__kfifo_len(conn->immqueue))) { + struct iscsi_session *session = conn->session; + while (__kfifo_get(conn->immqueue, (void*)&conn->mtask, + sizeof(void*))) { + if (iscsi_mtask_xmit(conn, conn->mtask)) + goto again; + + if (conn->mtask->hdr.itt == + cpu_to_be32(ISCSI_RESERVED_TAG)) { + spin_lock_bh(&session->lock); + __kfifo_put(session->mgmtpool.queue, + (void*)&conn->mtask, sizeof(void*)); + spin_unlock_bh(&session->lock); + } + } + /* done with this mtask */ + conn->mtask = NULL; + } + + /* process write queue */ + while (__kfifo_get(conn->writequeue, (void*)&conn->ctask, + sizeof(void*))) { + if (iscsi_ctask_xmit(conn, conn->ctask)) + goto again; + } + + /* process command queue */ + while (__kfifo_get(conn->xmitqueue, (void*)&conn->ctask, + sizeof(void*))) { + if (iscsi_ctask_xmit(conn, conn->ctask)) + goto again; + } + /* done with this ctask */ + conn->ctask = NULL; + + /* process the rest control plane PDUs, if any */ + if (unlikely(__kfifo_len(conn->mgmtqueue))) { + struct iscsi_session *session = conn->session; + + while (__kfifo_get(conn->mgmtqueue, (void*)&conn->mtask, + sizeof(void*))) { + if (iscsi_mtask_xmit(conn, conn->mtask)) + goto again; + + if (conn->mtask->hdr.itt == + cpu_to_be32(ISCSI_RESERVED_TAG)) { + spin_lock_bh(&session->lock); + __kfifo_put(session->mgmtpool.queue, + (void*)&conn->mtask, + sizeof(void*)); + spin_unlock_bh(&session->lock); + } + } + /* done with this mtask */ + conn->mtask = NULL; + } + + return 0; + +again: + if (unlikely(conn->suspend_tx)) + return 0; + + return -EAGAIN; +} + +static void +iscsi_xmitworker(void *data) +{ + struct iscsi_conn *conn = data; + + /* + * serialize Xmit worker on a per-connection basis. + */ + mutex_lock(&conn->xmitmutex); + if (iscsi_data_xmit(conn)) + scsi_queue_work(conn->session->host, &conn->xmitwork); + mutex_unlock(&conn->xmitmutex); +} + +#define FAILURE_BAD_HOST 1 +#define FAILURE_SESSION_FAILED 2 +#define FAILURE_SESSION_FREED 3 +#define FAILURE_WINDOW_CLOSED 4 +#define FAILURE_SESSION_TERMINATE 5 + +static int +iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)) +{ + struct Scsi_Host *host; + int reason = 0; + struct iscsi_session *session; + struct iscsi_conn *conn = NULL; + struct iscsi_cmd_task *ctask = NULL; + + sc->scsi_done = done; + sc->result = 0; + + host = sc->device->host; + session = iscsi_hostdata(host->hostdata); + BUG_ON(host != session->host); + + spin_lock(&session->lock); + + if (session->state != ISCSI_STATE_LOGGED_IN) { + if (session->state == ISCSI_STATE_FAILED) { + reason = FAILURE_SESSION_FAILED; + goto reject; + } else if (session->state == ISCSI_STATE_TERMINATE) { + reason = FAILURE_SESSION_TERMINATE; + goto fault; + } + reason = FAILURE_SESSION_FREED; + goto fault; + } + + /* + * Check for iSCSI window and take care of CmdSN wrap-around + */ + if ((int)(session->max_cmdsn - session->cmdsn) < 0) { + reason = FAILURE_WINDOW_CLOSED; + goto reject; + } + + conn = session->leadconn; + + __kfifo_get(session->cmdpool.queue, (void*)&ctask, sizeof(void*)); + BUG_ON(ctask->sc); + + sc->SCp.phase = session->age; + sc->SCp.ptr = (char*)ctask; + iscsi_cmd_init(conn, ctask, sc); + + __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", + conn->id, (long)sc, ctask->itt, sc->request_bufflen, + session->cmdsn, session->max_cmdsn - session->exp_cmdsn + 1); + spin_unlock(&session->lock); + + scsi_queue_work(host, &conn->xmitwork); + return 0; + +reject: + spin_unlock(&session->lock); + debug_scsi("cmd 0x%x rejected (%d)\n", sc->cmnd[0], reason); + return SCSI_MLQUEUE_HOST_BUSY; + +fault: + spin_unlock(&session->lock); + printk(KERN_ERR "iscsi_tcp: cmd 0x%x is not queued (%d)\n", + sc->cmnd[0], reason); + sc->sense_buffer[0] = 0x70; + sc->sense_buffer[2] = NOT_READY; + sc->sense_buffer[7] = 0x6; + sc->sense_buffer[12] = 0x08; + sc->sense_buffer[13] = 0x00; + sc->result = (DID_NO_CONNECT << 16); + sc->resid = sc->request_bufflen; + sc->scsi_done(sc); + return 0; +} + +static int +iscsi_change_queue_depth(struct scsi_device *sdev, int depth) +{ + if (depth > ISCSI_MAX_CMD_PER_LUN) + depth = ISCSI_MAX_CMD_PER_LUN; + scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), depth); + return sdev->queue_depth; +} + +static int +iscsi_pool_init(struct iscsi_queue *q, int max, void ***items, int item_size) +{ + int i; + + *items = kmalloc(max * sizeof(void*), GFP_KERNEL); + if (*items == NULL) + return -ENOMEM; + + q->max = max; + q->pool = kmalloc(max * sizeof(void*), GFP_KERNEL); + if (q->pool == NULL) { + kfree(*items); + return -ENOMEM; + } + + q->queue = kfifo_init((void*)q->pool, max * sizeof(void*), + GFP_KERNEL, NULL); + if (q->queue == ERR_PTR(-ENOMEM)) { + kfree(q->pool); + kfree(*items); + return -ENOMEM; + } + + for (i = 0; i < max; i++) { + q->pool[i] = kmalloc(item_size, GFP_KERNEL); + if (q->pool[i] == NULL) { + int j; + + for (j = 0; j < i; j++) + kfree(q->pool[j]); + + kfifo_free(q->queue); + kfree(q->pool); + kfree(*items); + return -ENOMEM; + } + memset(q->pool[i], 0, item_size); + (*items)[i] = q->pool[i]; + __kfifo_put(q->queue, (void*)&q->pool[i], sizeof(void*)); + } + return 0; +} + +static void +iscsi_pool_free(struct iscsi_queue *q, void **items) +{ + int i; + + for (i = 0; i < q->max; i++) + kfree(items[i]); + kfree(q->pool); + kfree(items); +} + static struct iscsi_cls_conn * -iscsi_tcp_conn_create(struct iscsi_cls_session *cls_session, uint32_t conn_idx) +iscsi_conn_create(struct iscsi_cls_session *cls_session, uint32_t conn_idx) { + struct Scsi_Host *shost = iscsi_session_to_shost(cls_session); + struct iscsi_session *session = iscsi_hostdata(shost->hostdata); struct iscsi_conn *conn; struct iscsi_cls_conn *cls_conn; - struct iscsi_tcp_conn *tcp_conn; - cls_conn = iscsi_conn_setup(cls_session, conn_idx); + cls_conn = iscsi_create_conn(cls_session, conn_idx); if (!cls_conn) return NULL; conn = cls_conn->dd_data; - /* - * due to strange issues with iser these are not set - * in iscsi_conn_setup - */ - conn->max_recv_dlength = DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH; + memset(conn, 0, sizeof(*conn)); - tcp_conn = kzalloc(sizeof(*tcp_conn), GFP_KERNEL); - if (!tcp_conn) - goto tcp_conn_alloc_fail; + conn->cls_conn = cls_conn; + conn->c_stage = ISCSI_CONN_INITIAL_STAGE; + conn->in_progress = IN_PROGRESS_WAIT_HEADER; + conn->id = conn_idx; + conn->exp_statsn = 0; + conn->tmabort_state = TMABORT_INITIAL; - conn->dd_data = tcp_conn; - tcp_conn->iscsi_conn = conn; - 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; + conn->hdr_size = sizeof(struct iscsi_hdr); + conn->data_size = DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH; + conn->max_recv_dlength = DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH; + + /* 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 write response PDU commands queue */ + conn->writequeue = kfifo_alloc(session->cmds_max * sizeof(void*), + GFP_KERNEL, NULL); + if (conn->writequeue == ERR_PTR(-ENOMEM)) + goto writequeue_alloc_fail; + + /* initialize general immediate & non-immediate PDU commands queue */ + conn->immqueue = kfifo_alloc(session->mgmtpool_max * sizeof(void*), + GFP_KERNEL, NULL); + if (conn->immqueue == ERR_PTR(-ENOMEM)) + goto immqueue_alloc_fail; + + conn->mgmtqueue = kfifo_alloc(session->mgmtpool_max * sizeof(void*), + GFP_KERNEL, NULL); + if (conn->mgmtqueue == ERR_PTR(-ENOMEM)) + goto mgmtqueue_alloc_fail; + + INIT_WORK(&conn->xmitwork, iscsi_xmitworker, conn); + + /* allocate login_mtask used for the login/text sequences */ + spin_lock_bh(&session->lock); + if (!__kfifo_get(session->mgmtpool.queue, + (void*)&conn->login_mtask, + sizeof(void*))) { + spin_unlock_bh(&session->lock); + goto login_mtask_alloc_fail; + } + spin_unlock_bh(&session->lock); /* allocate initial PDU receive place holder */ - if (tcp_conn->data_size <= PAGE_SIZE) - tcp_conn->data = kmalloc(tcp_conn->data_size, GFP_KERNEL); + if (conn->data_size <= PAGE_SIZE) + conn->data = kmalloc(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) + conn->data = (void*)__get_free_pages(GFP_KERNEL, + get_order(conn->data_size)); + if (!conn->data) goto max_recv_dlenght_alloc_fail; + init_timer(&conn->tmabort_timer); + mutex_init(&conn->xmitmutex); + init_waitqueue_head(&conn->ehwait); + return cls_conn; max_recv_dlenght_alloc_fail: - kfree(tcp_conn); -tcp_conn_alloc_fail: - iscsi_conn_teardown(cls_conn); + spin_lock_bh(&session->lock); + __kfifo_put(session->mgmtpool.queue, (void*)&conn->login_mtask, + sizeof(void*)); + spin_unlock_bh(&session->lock); +login_mtask_alloc_fail: + kfifo_free(conn->mgmtqueue); +mgmtqueue_alloc_fail: + kfifo_free(conn->immqueue); +immqueue_alloc_fail: + kfifo_free(conn->writequeue); +writequeue_alloc_fail: + kfifo_free(conn->xmitqueue); +xmitqueue_alloc_fail: + iscsi_destroy_conn(cls_conn); return NULL; } static void -iscsi_tcp_conn_destroy(struct iscsi_cls_conn *cls_conn) +iscsi_conn_destroy(struct iscsi_cls_conn *cls_conn) { struct iscsi_conn *conn = cls_conn->dd_data; - struct iscsi_tcp_conn *tcp_conn = conn->dd_data; - int digest = 0; + struct iscsi_session *session = conn->session; + unsigned long flags; + + mutex_lock(&conn->xmitmutex); + set_bit(SUSPEND_BIT, &conn->suspend_tx); + if (conn->c_stage == ISCSI_CONN_INITIAL_STAGE && conn->sock) { + struct sock *sk = conn->sock->sk; + + /* + * conn_start() has never been called! + * need to cleanup the socket. + */ + write_lock_bh(&sk->sk_callback_lock); + set_bit(SUSPEND_BIT, &conn->suspend_rx); + write_unlock_bh(&sk->sk_callback_lock); + + sock_hold(conn->sock->sk); + iscsi_conn_restore_callbacks(conn); + sock_put(conn->sock->sk); + sock_release(conn->sock); + conn->sock = NULL; + } - if (conn->hdrdgst_en || conn->datadgst_en) - digest = 1; + spin_lock_bh(&session->lock); + conn->c_stage = ISCSI_CONN_CLEANUP_WAIT; + if (session->leadconn == conn) { + /* + * leading connection? then give up on recovery. + */ + session->state = ISCSI_STATE_TERMINATE; + wake_up(&conn->ehwait); + } + spin_unlock_bh(&session->lock); + + mutex_unlock(&conn->xmitmutex); - iscsi_conn_teardown(cls_conn); + /* + * Block until all in-progress commands for this connection + * time out or fail. + */ + for (;;) { + spin_lock_irqsave(session->host->host_lock, flags); + if (!session->host->host_busy) { /* OK for ERL == 0 */ + spin_unlock_irqrestore(session->host->host_lock, flags); + break; + } + spin_unlock_irqrestore(session->host->host_lock, flags); + msleep_interruptible(500); + printk("conn_destroy(): host_busy %d host_failed %d\n", + session->host->host_busy, session->host->host_failed); + /* + * force eh_abort() to unblock + */ + wake_up(&conn->ehwait); + } - /* now free tcp_conn */ - if (digest) { - if (tcp_conn->tx_tfm) - crypto_free_tfm(tcp_conn->tx_tfm); - if (tcp_conn->rx_tfm) - crypto_free_tfm(tcp_conn->rx_tfm); - if (tcp_conn->data_tx_tfm) - crypto_free_tfm(tcp_conn->data_tx_tfm); - if (tcp_conn->data_rx_tfm) - crypto_free_tfm(tcp_conn->data_rx_tfm); + /* now free crypto */ + if (conn->hdrdgst_en || conn->datadgst_en) { + if (conn->tx_tfm) + crypto_free_tfm(conn->tx_tfm); + if (conn->rx_tfm) + crypto_free_tfm(conn->rx_tfm); + if (conn->data_tx_tfm) + crypto_free_tfm(conn->data_tx_tfm); + if (conn->data_rx_tfm) + crypto_free_tfm(conn->data_rx_tfm); } /* free conn->data, size = MaxRecvDataSegmentLength */ - if (tcp_conn->data_size <= PAGE_SIZE) - kfree(tcp_conn->data); + if (conn->data_size <= PAGE_SIZE) + kfree(conn->data); else - free_pages((unsigned long)tcp_conn->data, - get_order(tcp_conn->data_size)); - kfree(tcp_conn); + free_pages((unsigned long)conn->data, + get_order(conn->data_size)); + + spin_lock_bh(&session->lock); + __kfifo_put(session->mgmtpool.queue, (void*)&conn->login_mtask, + sizeof(void*)); + list_del(&conn->item); + if (list_empty(&session->connections)) + session->leadconn = NULL; + if (session->leadconn && session->leadconn == conn) + session->leadconn = container_of(session->connections.next, + struct iscsi_conn, item); + + if (session->leadconn == NULL) + /* none connections exits.. reset sequencing */ + session->cmdsn = session->max_cmdsn = session->exp_cmdsn = 1; + spin_unlock_bh(&session->lock); + + kfifo_free(conn->xmitqueue); + kfifo_free(conn->writequeue); + kfifo_free(conn->immqueue); + kfifo_free(conn->mgmtqueue); + + iscsi_destroy_conn(cls_conn); } static int -iscsi_tcp_conn_bind(struct iscsi_cls_session *cls_session, - struct iscsi_cls_conn *cls_conn, uint64_t transport_eph, - int is_leading) +iscsi_conn_bind(struct iscsi_cls_session *cls_session, + struct iscsi_cls_conn *cls_conn, uint32_t transport_fd, + int is_leading) { - struct iscsi_conn *conn = cls_conn->dd_data; - struct iscsi_tcp_conn *tcp_conn = conn->dd_data; + struct Scsi_Host *shost = iscsi_session_to_shost(cls_session); + struct iscsi_session *session = iscsi_hostdata(shost->hostdata); + struct iscsi_conn *tmp = ERR_PTR(-EEXIST), *conn = cls_conn->dd_data; struct sock *sk; struct socket *sock; int err; /* lookup for existing socket */ - sock = sockfd_lookup((int)transport_eph, &err); + sock = sockfd_lookup(transport_fd, &err); if (!sock) { printk(KERN_ERR "iscsi_tcp: sockfd_lookup failed %d\n", err); return -EEXIST; } - err = iscsi_conn_bind(cls_session, cls_conn, is_leading); - if (err) - return err; + /* lookup for existing connection */ + spin_lock_bh(&session->lock); + list_for_each_entry(tmp, &session->connections, item) { + if (tmp == conn) { + if (conn->c_stage != ISCSI_CONN_STOPPED || + conn->stop_stage == STOP_CONN_TERM) { + printk(KERN_ERR "iscsi_tcp: can't bind " + "non-stopped connection (%d:%d)\n", + conn->c_stage, conn->stop_stage); + spin_unlock_bh(&session->lock); + return -EIO; + } + break; + } + } + if (tmp != conn) { + /* bind new iSCSI connection to session */ + conn->session = session; + + list_add(&conn->item, &session->connections); + } + spin_unlock_bh(&session->lock); - /* bind iSCSI connection and socket */ - tcp_conn->sock = sock; + if (conn->stop_stage != STOP_CONN_SUSPEND) { + /* bind iSCSI connection and socket */ + conn->sock = sock; - /* setup Socket parameters */ - sk = sock->sk; - sk->sk_reuse = 1; - sk->sk_sndtimeo = 15 * HZ; /* FIXME: make it configurable */ - sk->sk_allocation = GFP_ATOMIC; + /* setup Socket parameters */ + sk = sock->sk; + sk->sk_reuse = 1; + sk->sk_sndtimeo = 15 * HZ; /* FIXME: make it configurable */ + sk->sk_allocation = GFP_ATOMIC; - /* FIXME: disable Nagle's algorithm */ + /* FIXME: disable Nagle's algorithm */ + + /* + * Intercept TCP callbacks for sendfile like receive + * processing. + */ + iscsi_conn_set_callbacks(conn); + + conn->sendpage = conn->sock->ops->sendpage; + + /* + * set receive state machine into initial state + */ + conn->in_progress = IN_PROGRESS_WAIT_HEADER; + } + + if (is_leading) + session->leadconn = conn; /* - * Intercept TCP callbacks for sendfile like receive - * processing. - */ - conn->recv_lock = &sk->sk_callback_lock; - iscsi_conn_set_callbacks(conn); - tcp_conn->sendpage = tcp_conn->sock->ops->sendpage; - /* - * set receive state machine into initial state + * Unblock xmitworker(), Login Phase will pass through. */ - tcp_conn->in_progress = IN_PROGRESS_WAIT_HEADER; + clear_bit(SUSPEND_BIT, &conn->suspend_rx); + clear_bit(SUSPEND_BIT, &conn->suspend_tx); return 0; } -static void -iscsi_tcp_cleanup_ctask(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) +static int +iscsi_conn_start(struct iscsi_cls_conn *cls_conn) { - struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; - struct iscsi_r2t_info *r2t; + struct iscsi_conn *conn = cls_conn->dd_data; + struct iscsi_session *session = conn->session; + struct sock *sk; - /* 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*)); + /* FF phase warming up... */ - __iscsi_ctask_cleanup(conn, ctask); + if (session == NULL) { + printk(KERN_ERR "iscsi_tcp: can't start unbound connection\n"); + return -EPERM; + } + + sk = conn->sock->sk; + + write_lock_bh(&sk->sk_callback_lock); + spin_lock_bh(&session->lock); + conn->c_stage = ISCSI_CONN_STARTED; + session->state = ISCSI_STATE_LOGGED_IN; + + switch(conn->stop_stage) { + case STOP_CONN_RECOVER: + /* + * unblock eh_abort() if it is blocked. re-try all + * commands after successful recovery + */ + session->conn_cnt++; + conn->stop_stage = 0; + conn->tmabort_state = TMABORT_INITIAL; + session->age++; + wake_up(&conn->ehwait); + break; + case STOP_CONN_TERM: + session->conn_cnt++; + conn->stop_stage = 0; + break; + case STOP_CONN_SUSPEND: + conn->stop_stage = 0; + clear_bit(SUSPEND_BIT, &conn->suspend_rx); + clear_bit(SUSPEND_BIT, &conn->suspend_tx); + break; + default: + break; + } + spin_unlock_bh(&session->lock); + write_unlock_bh(&sk->sk_callback_lock); + + return 0; } static void -iscsi_tcp_suspend_conn_rx(struct iscsi_conn *conn) +iscsi_conn_stop(struct iscsi_cls_conn *cls_conn, int flag) { - struct iscsi_tcp_conn *tcp_conn = conn->dd_data; + struct iscsi_conn *conn = cls_conn->dd_data; + struct iscsi_session *session = conn->session; struct sock *sk; + unsigned long flags; - if (!tcp_conn->sock) - return; - - sk = tcp_conn->sock->sk; + BUG_ON(!conn->sock); + sk = conn->sock->sk; write_lock_bh(&sk->sk_callback_lock); - set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_rx); + set_bit(SUSPEND_BIT, &conn->suspend_rx); write_unlock_bh(&sk->sk_callback_lock); + + mutex_lock(&conn->xmitmutex); + + spin_lock_irqsave(session->host->host_lock, flags); + spin_lock(&session->lock); + conn->stop_stage = flag; + conn->c_stage = ISCSI_CONN_STOPPED; + set_bit(SUSPEND_BIT, &conn->suspend_tx); + + if (flag != STOP_CONN_SUSPEND) + session->conn_cnt--; + + if (session->conn_cnt == 0 || session->leadconn == conn) + session->state = ISCSI_STATE_FAILED; + + spin_unlock(&session->lock); + spin_unlock_irqrestore(session->host->host_lock, flags); + + if (flag == STOP_CONN_TERM || flag == STOP_CONN_RECOVER) { + struct iscsi_cmd_task *ctask; + struct iscsi_mgmt_task *mtask; + + /* + * Socket must go now. + */ + sock_hold(conn->sock->sk); + iscsi_conn_restore_callbacks(conn); + sock_put(conn->sock->sk); + + /* + * flush xmit queues. + */ + spin_lock_bh(&session->lock); + while (__kfifo_get(conn->writequeue, (void*)&ctask, + sizeof(void*)) || + __kfifo_get(conn->xmitqueue, (void*)&ctask, + sizeof(void*))) { + struct iscsi_r2t_info *r2t; + + /* + * flush ctask's r2t queues + */ + while (__kfifo_get(ctask->r2tqueue, (void*)&r2t, + sizeof(void*))) + __kfifo_put(ctask->r2tpool.queue, (void*)&r2t, + sizeof(void*)); + + spin_unlock_bh(&session->lock); + local_bh_disable(); + iscsi_ctask_cleanup(conn, ctask); + local_bh_enable(); + spin_lock_bh(&session->lock); + } + conn->ctask = NULL; + while (__kfifo_get(conn->immqueue, (void*)&mtask, + sizeof(void*)) || + __kfifo_get(conn->mgmtqueue, (void*)&mtask, + sizeof(void*))) { + __kfifo_put(session->mgmtpool.queue, + (void*)&mtask, sizeof(void*)); + } + conn->mtask = NULL; + spin_unlock_bh(&session->lock); + + /* + * release socket only after we stopped data_xmit() + * activity and flushed all outstandings + */ + sock_release(conn->sock); + conn->sock = NULL; + + /* + * for connection level recovery we should not calculate + * header digest. conn->hdr_size used for optimization + * in hdr_extract() and will be re-negotiated at + * set_param() time. + */ + if (flag == STOP_CONN_RECOVER) { + conn->hdr_size = sizeof(struct iscsi_hdr); + conn->hdrdgst_en = 0; + conn->datadgst_en = 0; + } + } + mutex_unlock(&conn->xmitmutex); } -static void -iscsi_tcp_terminate_conn(struct iscsi_conn *conn) +static int +iscsi_conn_send_generic(struct iscsi_conn *conn, struct iscsi_hdr *hdr, + char *data, uint32_t data_size) { - struct iscsi_tcp_conn *tcp_conn = conn->dd_data; + struct iscsi_session *session = conn->session; + struct iscsi_nopout *nop = (struct iscsi_nopout *)hdr; + struct iscsi_mgmt_task *mtask; - if (!tcp_conn->sock) - return; + spin_lock_bh(&session->lock); + if (session->state == ISCSI_STATE_TERMINATE) { + spin_unlock_bh(&session->lock); + return -EPERM; + } + if (hdr->opcode == (ISCSI_OP_LOGIN | ISCSI_OP_IMMEDIATE) || + hdr->opcode == (ISCSI_OP_TEXT | ISCSI_OP_IMMEDIATE)) + /* + * Login and Text are sent serially, in + * request-followed-by-response sequence. + * Same mtask can be used. Same ITT must be used. + * Note that login_mtask is preallocated at conn_create(). + */ + mtask = conn->login_mtask; + else { + BUG_ON(conn->c_stage == ISCSI_CONN_INITIAL_STAGE); + BUG_ON(conn->c_stage == ISCSI_CONN_STOPPED); + + if (!__kfifo_get(session->mgmtpool.queue, + (void*)&mtask, sizeof(void*))) { + spin_unlock_bh(&session->lock); + return -ENOSPC; + } + } + + /* + * pre-format CmdSN and ExpStatSN for outgoing PDU. + */ + if (hdr->itt != cpu_to_be32(ISCSI_RESERVED_TAG)) { + hdr->itt = mtask->itt | (conn->id << CID_SHIFT) | + (session->age << AGE_SHIFT); + nop->cmdsn = cpu_to_be32(session->cmdsn); + if (conn->c_stage == ISCSI_CONN_STARTED && + !(hdr->opcode & ISCSI_OP_IMMEDIATE)) + session->cmdsn++; + } else + /* do not advance CmdSN */ + nop->cmdsn = cpu_to_be32(session->cmdsn); + + nop->exp_statsn = cpu_to_be32(conn->exp_statsn); + + memcpy(&mtask->hdr, hdr, sizeof(struct iscsi_hdr)); + + iscsi_buf_init_virt(&mtask->headbuf, (char*)&mtask->hdr, + sizeof(struct iscsi_hdr)); + + spin_unlock_bh(&session->lock); + + if (data_size) { + memcpy(mtask->data, data, data_size); + mtask->data_count = data_size; + } else + mtask->data_count = 0; + + mtask->xmstate = XMSTATE_IMM_HDR; + + if (mtask->data_count) { + iscsi_buf_init_iov(&mtask->sendbuf, (char*)mtask->data, + mtask->data_count); + } + + debug_scsi("mgmtpdu [op 0x%x hdr->itt 0x%x datalen %d]\n", + hdr->opcode, hdr->itt, data_size); - sock_hold(tcp_conn->sock->sk); - iscsi_conn_restore_callbacks(conn); - sock_put(tcp_conn->sock->sk); + /* + * since send_pdu() could be called at least from two contexts, + * we need to serialize __kfifo_put, so we don't have to take + * additional lock on fast data-path + */ + if (hdr->opcode & ISCSI_OP_IMMEDIATE) + __kfifo_put(conn->immqueue, (void*)&mtask, sizeof(void*)); + else + __kfifo_put(conn->mgmtqueue, (void*)&mtask, sizeof(void*)); - sock_release(tcp_conn->sock); - tcp_conn->sock = NULL; - conn->recv_lock = NULL; + scsi_queue_work(session->host, &conn->xmitwork); + return 0; +} + +static int +iscsi_eh_host_reset(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; + + spin_lock_bh(&session->lock); + if (session->state == ISCSI_STATE_TERMINATE) { + debug_scsi("failing host reset: session terminated " + "[CID %d age %d]", conn->id, session->age); + spin_unlock_bh(&session->lock); + return FAILED; + } + spin_unlock_bh(&session->lock); + + debug_scsi("failing connection CID %d due to SCSI host reset " + "[itt 0x%x age %d]", conn->id, ctask->itt, + session->age); + iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); + + return SUCCESS; } -/* called with host lock */ static void -iscsi_tcp_mgmt_init(struct iscsi_conn *conn, struct iscsi_mgmt_task *mtask, - char *data, uint32_t data_size) +iscsi_tmabort_timedout(unsigned long data) { - struct iscsi_tcp_mgmt_task *tcp_mtask = mtask->dd_data; + struct iscsi_cmd_task *ctask = (struct iscsi_cmd_task *)data; + struct iscsi_conn *conn = ctask->conn; + struct iscsi_session *session = conn->session; - iscsi_buf_init_iov(&tcp_mtask->headbuf, (char*)mtask->hdr, - sizeof(struct iscsi_hdr)); - tcp_mtask->xmstate = XMSTATE_IMM_HDR; + spin_lock(&session->lock); + if (conn->tmabort_state == TMABORT_INITIAL) { + __kfifo_put(session->mgmtpool.queue, + (void*)&ctask->mtask, sizeof(void*)); + conn->tmabort_state = TMABORT_TIMEDOUT; + debug_scsi("tmabort timedout [sc %lx itt 0x%x]\n", + (long)ctask->sc, ctask->itt); + /* unblock eh_abort() */ + wake_up(&conn->ehwait); + } + spin_unlock(&session->lock); +} - if (mtask->data_count) - iscsi_buf_init_iov(&tcp_mtask->sendbuf, (char*)mtask->data, - mtask->data_count); +static int +iscsi_eh_abort(struct scsi_cmnd *sc) +{ + int rc; + struct iscsi_cmd_task *ctask = (struct iscsi_cmd_task *)sc->SCp.ptr; + struct iscsi_conn *conn = ctask->conn; + struct iscsi_session *session = conn->session; + + conn->eh_abort_cnt++; + debug_scsi("aborting [sc %lx itt 0x%x]\n", (long)sc, ctask->itt); + + /* + * two cases for ERL=0 here: + * + * 1) connection-level failure; + * 2) recovery due protocol error; + */ + mutex_lock(&conn->xmitmutex); + spin_lock_bh(&session->lock); + if (session->state != ISCSI_STATE_LOGGED_IN) { + if (session->state == ISCSI_STATE_TERMINATE) { + spin_unlock_bh(&session->lock); + mutex_unlock(&conn->xmitmutex); + goto failed; + } + spin_unlock_bh(&session->lock); + } else { + struct iscsi_tm *hdr = &conn->tmhdr; + + /* + * Still LOGGED_IN... + */ + + if (!ctask->sc || sc->SCp.phase != session->age) { + /* + * 1) ctask completed before time out. But session + * is still ok => Happy Retry. + * 2) session was re-open during time out of ctask. + */ + spin_unlock_bh(&session->lock); + mutex_unlock(&conn->xmitmutex); + goto success; + } + conn->tmabort_state = TMABORT_INITIAL; + spin_unlock_bh(&session->lock); + + /* + * ctask timed out but session is OK + * ERL=0 requires task mgmt abort to be issued on each + * failed command. requests must be serialized. + */ + memset(hdr, 0, sizeof(struct iscsi_tm)); + hdr->opcode = ISCSI_OP_SCSI_TMFUNC | ISCSI_OP_IMMEDIATE; + hdr->flags = ISCSI_TM_FUNC_ABORT_TASK; + hdr->flags |= ISCSI_FLAG_CMD_FINAL; + memcpy(hdr->lun, ctask->hdr.lun, sizeof(hdr->lun)); + hdr->rtt = ctask->hdr.itt; + hdr->refcmdsn = ctask->hdr.cmdsn; + + rc = iscsi_conn_send_generic(conn, (struct iscsi_hdr *)hdr, + NULL, 0); + if (rc) { + iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); + debug_scsi("abort sent failure [itt 0x%x]", ctask->itt); + } else { + struct iscsi_r2t_info *r2t; + + /* + * TMF abort vs. TMF response race logic + */ + spin_lock_bh(&session->lock); + ctask->mtask = (struct iscsi_mgmt_task *) + session->mgmt_cmds[(hdr->itt & ITT_MASK) - + ISCSI_MGMT_ITT_OFFSET]; + /* + * have to flush r2tqueue to avoid r2t leaks + */ + while (__kfifo_get(ctask->r2tqueue, (void*)&r2t, + sizeof(void*))) { + __kfifo_put(ctask->r2tpool.queue, (void*)&r2t, + sizeof(void*)); + } + if (conn->tmabort_state == TMABORT_INITIAL) { + conn->tmfcmd_pdus_cnt++; + conn->tmabort_timer.expires = 3*HZ + jiffies; + conn->tmabort_timer.function = + iscsi_tmabort_timedout; + conn->tmabort_timer.data = (unsigned long)ctask; + add_timer(&conn->tmabort_timer); + debug_scsi("abort sent [itt 0x%x]", ctask->itt); + } else { + if (!ctask->sc || + conn->tmabort_state == TMABORT_SUCCESS) { + conn->tmabort_state = TMABORT_INITIAL; + spin_unlock_bh(&session->lock); + mutex_unlock(&conn->xmitmutex); + goto success; + } + conn->tmabort_state = TMABORT_INITIAL; + iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); + } + spin_unlock_bh(&session->lock); + } + } + mutex_unlock(&conn->xmitmutex); + + + /* + * block eh thread until: + * + * 1) abort response; + * 2) abort timeout; + * 3) session re-opened; + * 4) session terminated; + */ + for (;;) { + int p_state = session->state; + + rc = wait_event_interruptible(conn->ehwait, + (p_state == ISCSI_STATE_LOGGED_IN ? + (session->state == ISCSI_STATE_TERMINATE || + conn->tmabort_state != TMABORT_INITIAL) : + (session->state == ISCSI_STATE_TERMINATE || + session->state == ISCSI_STATE_LOGGED_IN))); + if (rc) { + /* shutdown.. */ + session->state = ISCSI_STATE_TERMINATE; + goto failed; + } + + if (signal_pending(current)) + flush_signals(current); + + if (session->state == ISCSI_STATE_TERMINATE) + goto failed; + + spin_lock_bh(&session->lock); + if (sc->SCp.phase == session->age && + (conn->tmabort_state == TMABORT_TIMEDOUT || + conn->tmabort_state == TMABORT_FAILED)) { + conn->tmabort_state = TMABORT_INITIAL; + if (!ctask->sc) { + /* + * ctask completed before tmf abort response or + * time out. + * But session is still ok => Happy Retry. + */ + spin_unlock_bh(&session->lock); + break; + } + spin_unlock_bh(&session->lock); + iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); + continue; + } + spin_unlock_bh(&session->lock); + break; + } + +success: + debug_scsi("abort success [sc %lx itt 0x%x]\n", (long)sc, ctask->itt); + rc = SUCCESS; + goto exit; + +failed: + debug_scsi("abort failed [sc %lx itt 0x%x]\n", (long)sc, ctask->itt); + rc = FAILED; + +exit: + del_timer_sync(&conn->tmabort_timer); + + mutex_lock(&conn->xmitmutex); + if (conn->sock) { + struct sock *sk = conn->sock->sk; + + write_lock_bh(&sk->sk_callback_lock); + iscsi_ctask_cleanup(conn, ctask); + write_unlock_bh(&sk->sk_callback_lock); + } + mutex_unlock(&conn->xmitmutex); + return rc; } static int @@ -2074,7 +3174,6 @@ iscsi_r2tpool_alloc(struct iscsi_session *session) */ for (cmd_i = 0; cmd_i < session->cmds_max; cmd_i++) { struct iscsi_cmd_task *ctask = session->cmds[cmd_i]; - struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; /* * pre-allocated x4 as much r2ts to handle race when @@ -2083,32 +3182,42 @@ iscsi_r2tpool_alloc(struct iscsi_session *session) */ /* R2T pool */ - if (iscsi_pool_init(&tcp_ctask->r2tpool, session->max_r2t * 4, - (void***)&tcp_ctask->r2ts, - sizeof(struct iscsi_r2t_info))) { + if (iscsi_pool_init(&ctask->r2tpool, session->max_r2t * 4, + (void***)&ctask->r2ts, sizeof(struct iscsi_r2t_info))) { goto r2t_alloc_fail; } /* R2T xmit queue */ - tcp_ctask->r2tqueue = kfifo_alloc( + ctask->r2tqueue = kfifo_alloc( session->max_r2t * 4 * sizeof(void*), GFP_KERNEL, NULL); - if (tcp_ctask->r2tqueue == ERR_PTR(-ENOMEM)) { - iscsi_pool_free(&tcp_ctask->r2tpool, - (void**)tcp_ctask->r2ts); + if (ctask->r2tqueue == ERR_PTR(-ENOMEM)) { + iscsi_pool_free(&ctask->r2tpool, (void**)ctask->r2ts); goto r2t_alloc_fail; } + + /* + * number of + * Data-Out PDU's within R2T-sequence can be quite big; + * using mempool + */ + ctask->datapool = mempool_create_slab_pool(ISCSI_DTASK_DEFAULT_MAX, + taskcache); + if (ctask->datapool == NULL) { + kfifo_free(ctask->r2tqueue); + iscsi_pool_free(&ctask->r2tpool, (void**)ctask->r2ts); + goto r2t_alloc_fail; + } + INIT_LIST_HEAD(&ctask->dataqueue); } return 0; r2t_alloc_fail: for (i = 0; i < cmd_i; i++) { - struct iscsi_cmd_task *ctask = session->cmds[i]; - struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; - - kfifo_free(tcp_ctask->r2tqueue); - iscsi_pool_free(&tcp_ctask->r2tpool, - (void**)tcp_ctask->r2ts); + mempool_destroy(session->cmds[i]->datapool); + kfifo_free(session->cmds[i]->r2tqueue); + iscsi_pool_free(&session->cmds[i]->r2tpool, + (void**)session->cmds[i]->r2ts); } return -ENOMEM; } @@ -2119,13 +3228,127 @@ iscsi_r2tpool_free(struct iscsi_session *session) int i; for (i = 0; i < session->cmds_max; i++) { - struct iscsi_cmd_task *ctask = session->cmds[i]; - struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; + mempool_destroy(session->cmds[i]->datapool); + kfifo_free(session->cmds[i]->r2tqueue); + iscsi_pool_free(&session->cmds[i]->r2tpool, + (void**)session->cmds[i]->r2ts); + } +} + +static struct scsi_host_template iscsi_sht = { + .name = "iSCSI Initiator over TCP/IP, v." + ISCSI_VERSION_STR, + .queuecommand = iscsi_queuecommand, + .change_queue_depth = iscsi_change_queue_depth, + .can_queue = ISCSI_XMIT_CMDS_MAX - 1, + .sg_tablesize = ISCSI_SG_TABLESIZE, + .cmd_per_lun = ISCSI_DEF_CMD_PER_LUN, + .eh_abort_handler = iscsi_eh_abort, + .eh_host_reset_handler = iscsi_eh_host_reset, + .use_clustering = DISABLE_CLUSTERING, + .proc_name = "iscsi_tcp", + .this_id = -1, +}; + +static struct iscsi_transport iscsi_tcp_transport; + +static struct iscsi_cls_session * +iscsi_session_create(struct scsi_transport_template *scsit, + uint32_t initial_cmdsn, uint32_t *sid) +{ + struct Scsi_Host *shost; + struct iscsi_session *session; + int cmd_i; + + shost = iscsi_transport_create_session(scsit, &iscsi_tcp_transport); + if (!shost) + return NULL; + + session = iscsi_hostdata(shost->hostdata); + memset(session, 0, sizeof(struct iscsi_session)); + session->host = shost; + session->state = ISCSI_STATE_FREE; + session->mgmtpool_max = ISCSI_MGMT_CMDS_MAX; + session->cmds_max = ISCSI_XMIT_CMDS_MAX; + session->cmdsn = initial_cmdsn; + session->exp_cmdsn = initial_cmdsn + 1; + session->max_cmdsn = initial_cmdsn + 1; + session->max_r2t = 1; + *sid = shost->host_no; + + /* initialize SCSI PDU commands pool */ + if (iscsi_pool_init(&session->cmdpool, session->cmds_max, + (void***)&session->cmds, sizeof(struct iscsi_cmd_task))) + goto cmdpool_alloc_fail; + + /* pre-format cmds pool with ITT */ + for (cmd_i = 0; cmd_i < session->cmds_max; cmd_i++) + session->cmds[cmd_i]->itt = cmd_i; + + spin_lock_init(&session->lock); + INIT_LIST_HEAD(&session->connections); + + /* initialize immediate command pool */ + if (iscsi_pool_init(&session->mgmtpool, session->mgmtpool_max, + (void***)&session->mgmt_cmds, sizeof(struct iscsi_mgmt_task))) + goto mgmtpool_alloc_fail; + + + /* pre-format immediate cmds pool with ITT */ + for (cmd_i = 0; cmd_i < session->mgmtpool_max; cmd_i++) { + session->mgmt_cmds[cmd_i]->itt = ISCSI_MGMT_ITT_OFFSET + cmd_i; + session->mgmt_cmds[cmd_i]->data = kmalloc( + DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH, GFP_KERNEL); + if (!session->mgmt_cmds[cmd_i]->data) { + int j; + + for (j = 0; j < cmd_i; j++) + kfree(session->mgmt_cmds[j]->data); + goto immdata_alloc_fail; + } + } + + if (iscsi_r2tpool_alloc(session)) + goto r2tpool_alloc_fail; - kfifo_free(tcp_ctask->r2tqueue); - iscsi_pool_free(&tcp_ctask->r2tpool, - (void**)tcp_ctask->r2ts); + return hostdata_session(shost->hostdata); + +r2tpool_alloc_fail: + for (cmd_i = 0; cmd_i < session->mgmtpool_max; cmd_i++) + kfree(session->mgmt_cmds[cmd_i]->data); +immdata_alloc_fail: + iscsi_pool_free(&session->mgmtpool, (void**)session->mgmt_cmds); +mgmtpool_alloc_fail: + iscsi_pool_free(&session->cmdpool, (void**)session->cmds); +cmdpool_alloc_fail: + iscsi_transport_destroy_session(shost); + return NULL; +} + +static void +iscsi_session_destroy(struct iscsi_cls_session *cls_session) +{ + struct Scsi_Host *shost = iscsi_session_to_shost(cls_session); + struct iscsi_session *session = iscsi_hostdata(shost->hostdata); + int cmd_i; + struct iscsi_data_task *dtask, *n; + + for (cmd_i = 0; cmd_i < session->cmds_max; cmd_i++) { + struct iscsi_cmd_task *ctask = session->cmds[cmd_i]; + list_for_each_entry_safe(dtask, n, &ctask->dataqueue, item) { + list_del(&dtask->item); + mempool_free(dtask, ctask->datapool); + } } + + for (cmd_i = 0; cmd_i < session->mgmtpool_max; cmd_i++) + kfree(session->mgmt_cmds[cmd_i]->data); + + iscsi_r2tpool_free(session); + iscsi_pool_free(&session->mgmtpool, (void**)session->mgmt_cmds); + iscsi_pool_free(&session->cmdpool, (void**)session->cmds); + + iscsi_transport_destroy_session(shost); } static int @@ -2134,14 +3357,23 @@ iscsi_conn_set_param(struct iscsi_cls_conn *cls_conn, enum iscsi_param param, { struct iscsi_conn *conn = cls_conn->dd_data; struct iscsi_session *session = conn->session; - struct iscsi_tcp_conn *tcp_conn = conn->dd_data; + + spin_lock_bh(&session->lock); + if (conn->c_stage != ISCSI_CONN_INITIAL_STAGE && + conn->stop_stage != STOP_CONN_RECOVER) { + printk(KERN_ERR "iscsi_tcp: can not change parameter [%d]\n", + param); + spin_unlock_bh(&session->lock); + return 0; + } + spin_unlock_bh(&session->lock); switch(param) { case ISCSI_PARAM_MAX_RECV_DLENGTH: { - char *saveptr = tcp_conn->data; + char *saveptr = conn->data; gfp_t flags = GFP_KERNEL; - if (tcp_conn->data_size >= value) { + if (conn->data_size >= value) { conn->max_recv_dlength = value; break; } @@ -2152,21 +3384,21 @@ iscsi_conn_set_param(struct iscsi_cls_conn *cls_conn, enum iscsi_param param, spin_unlock_bh(&session->lock); if (value <= PAGE_SIZE) - tcp_conn->data = kmalloc(value, flags); + conn->data = kmalloc(value, flags); else - tcp_conn->data = (void*)__get_free_pages(flags, + conn->data = (void*)__get_free_pages(flags, get_order(value)); - if (tcp_conn->data == NULL) { - tcp_conn->data = saveptr; + if (conn->data == NULL) { + conn->data = saveptr; return -ENOMEM; } - if (tcp_conn->data_size <= PAGE_SIZE) + if (conn->data_size <= PAGE_SIZE) kfree(saveptr); else free_pages((unsigned long)saveptr, - get_order(tcp_conn->data_size)); + get_order(conn->data_size)); conn->max_recv_dlength = value; - tcp_conn->data_size = value; + conn->data_size = value; } break; case ISCSI_PARAM_MAX_XMIT_DLENGTH: @@ -2174,51 +3406,49 @@ iscsi_conn_set_param(struct iscsi_cls_conn *cls_conn, enum iscsi_param param, break; case ISCSI_PARAM_HDRDGST_EN: conn->hdrdgst_en = value; - tcp_conn->hdr_size = sizeof(struct iscsi_hdr); + conn->hdr_size = sizeof(struct iscsi_hdr); if (conn->hdrdgst_en) { - tcp_conn->hdr_size += sizeof(__u32); - if (!tcp_conn->tx_tfm) - tcp_conn->tx_tfm = crypto_alloc_tfm("crc32c", - 0); - if (!tcp_conn->tx_tfm) + conn->hdr_size += sizeof(__u32); + if (!conn->tx_tfm) + conn->tx_tfm = crypto_alloc_tfm("crc32c", 0); + if (!conn->tx_tfm) return -ENOMEM; - if (!tcp_conn->rx_tfm) - tcp_conn->rx_tfm = crypto_alloc_tfm("crc32c", - 0); - if (!tcp_conn->rx_tfm) { - crypto_free_tfm(tcp_conn->tx_tfm); + if (!conn->rx_tfm) + conn->rx_tfm = crypto_alloc_tfm("crc32c", 0); + if (!conn->rx_tfm) { + crypto_free_tfm(conn->tx_tfm); return -ENOMEM; } } else { - if (tcp_conn->tx_tfm) - crypto_free_tfm(tcp_conn->tx_tfm); - if (tcp_conn->rx_tfm) - crypto_free_tfm(tcp_conn->rx_tfm); + if (conn->tx_tfm) + crypto_free_tfm(conn->tx_tfm); + if (conn->rx_tfm) + crypto_free_tfm(conn->rx_tfm); } break; case ISCSI_PARAM_DATADGST_EN: conn->datadgst_en = value; if (conn->datadgst_en) { - if (!tcp_conn->data_tx_tfm) - tcp_conn->data_tx_tfm = + if (!conn->data_tx_tfm) + conn->data_tx_tfm = crypto_alloc_tfm("crc32c", 0); - if (!tcp_conn->data_tx_tfm) + if (!conn->data_tx_tfm) return -ENOMEM; - if (!tcp_conn->data_rx_tfm) - tcp_conn->data_rx_tfm = + if (!conn->data_rx_tfm) + conn->data_rx_tfm = crypto_alloc_tfm("crc32c", 0); - if (!tcp_conn->data_rx_tfm) { - crypto_free_tfm(tcp_conn->data_tx_tfm); + if (!conn->data_rx_tfm) { + crypto_free_tfm(conn->data_tx_tfm); return -ENOMEM; } } else { - if (tcp_conn->data_tx_tfm) - crypto_free_tfm(tcp_conn->data_tx_tfm); - if (tcp_conn->data_rx_tfm) - crypto_free_tfm(tcp_conn->data_rx_tfm); + if (conn->data_tx_tfm) + crypto_free_tfm(conn->data_tx_tfm); + if (conn->data_rx_tfm) + crypto_free_tfm(conn->data_rx_tfm); } - tcp_conn->sendpage = conn->datadgst_en ? - sock_no_sendpage : tcp_conn->sock->ops->sendpage; + conn->sendpage = conn->datadgst_en ? + sock_no_sendpage : conn->sock->ops->sendpage; break; case ISCSI_PARAM_INITIAL_R2T_EN: session->initial_r2t_en = value; @@ -2259,9 +3489,6 @@ iscsi_conn_set_param(struct iscsi_cls_conn *cls_conn, enum iscsi_param param, BUG_ON(value); session->ofmarker_en = value; break; - case ISCSI_PARAM_EXP_STATSN: - conn->exp_statsn = value; - break; default: break; } @@ -2308,7 +3535,7 @@ iscsi_session_get_param(struct iscsi_cls_session *cls_session, *value = session->ofmarker_en; break; default: - return -EINVAL; + return ISCSI_ERR_PARAM_NOT_FOUND; } return 0; @@ -2319,8 +3546,6 @@ iscsi_conn_get_param(struct iscsi_cls_conn *cls_conn, enum iscsi_param param, uint32_t *value) { struct iscsi_conn *conn = cls_conn->dd_data; - struct iscsi_tcp_conn *tcp_conn = conn->dd_data; - struct inet_sock *inet; switch(param) { case ISCSI_PARAM_MAX_RECV_DLENGTH: @@ -2335,70 +3560,17 @@ iscsi_conn_get_param(struct iscsi_cls_conn *cls_conn, case ISCSI_PARAM_DATADGST_EN: *value = conn->datadgst_en; break; - case ISCSI_PARAM_CONN_PORT: - mutex_lock(&conn->xmitmutex); - if (!tcp_conn->sock) { - mutex_unlock(&conn->xmitmutex); - return -EINVAL; - } - - inet = inet_sk(tcp_conn->sock->sk); - *value = be16_to_cpu(inet->dport); - mutex_unlock(&conn->xmitmutex); - case ISCSI_PARAM_EXP_STATSN: - *value = conn->exp_statsn; - break; default: - return -EINVAL; + return ISCSI_ERR_PARAM_NOT_FOUND; } return 0; } -static int -iscsi_conn_get_str_param(struct iscsi_cls_conn *cls_conn, - enum iscsi_param param, char *buf) -{ - struct iscsi_conn *conn = cls_conn->dd_data; - struct iscsi_tcp_conn *tcp_conn = conn->dd_data; - struct sock *sk; - struct inet_sock *inet; - struct ipv6_pinfo *np; - int len = 0; - - switch (param) { - case ISCSI_PARAM_CONN_ADDRESS: - mutex_lock(&conn->xmitmutex); - if (!tcp_conn->sock) { - mutex_unlock(&conn->xmitmutex); - return -EINVAL; - } - - sk = tcp_conn->sock->sk; - if (sk->sk_family == PF_INET) { - inet = inet_sk(sk); - len = sprintf(buf, "%u.%u.%u.%u\n", - NIPQUAD(inet->daddr)); - } else { - np = inet6_sk(sk); - len = sprintf(buf, - "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n", - NIP6(np->daddr)); - } - mutex_unlock(&conn->xmitmutex); - break; - default: - return -EINVAL; - } - - return len; -} - static void iscsi_conn_get_stats(struct iscsi_cls_conn *cls_conn, struct iscsi_stats *stats) { struct iscsi_conn *conn = cls_conn->dd_data; - struct iscsi_tcp_conn *tcp_conn = conn->dd_data; stats->txdata_octets = conn->txdata_octets; stats->rxdata_octets = conn->rxdata_octets; @@ -2411,141 +3583,68 @@ iscsi_conn_get_stats(struct iscsi_cls_conn *cls_conn, struct iscsi_stats *stats) stats->tmfrsp_pdus = conn->tmfrsp_pdus_cnt; stats->custom_length = 3; strcpy(stats->custom[0].desc, "tx_sendpage_failures"); - stats->custom[0].value = tcp_conn->sendpage_failures_cnt; + stats->custom[0].value = conn->sendpage_failures_cnt; strcpy(stats->custom[1].desc, "rx_discontiguous_hdr"); - stats->custom[1].value = tcp_conn->discontiguous_hdr_cnt; + stats->custom[1].value = conn->discontiguous_hdr_cnt; strcpy(stats->custom[2].desc, "eh_abort_cnt"); stats->custom[2].value = conn->eh_abort_cnt; } -static struct iscsi_cls_session * -iscsi_tcp_session_create(struct iscsi_transport *iscsit, - struct scsi_transport_template *scsit, - uint32_t initial_cmdsn, uint32_t *hostno) +static int +iscsi_conn_send_pdu(struct iscsi_cls_conn *cls_conn, struct iscsi_hdr *hdr, + char *data, uint32_t data_size) { - struct iscsi_cls_session *cls_session; - struct iscsi_session *session; - uint32_t hn; - int cmd_i; - - cls_session = iscsi_session_setup(iscsit, scsit, - sizeof(struct iscsi_tcp_cmd_task), - sizeof(struct iscsi_tcp_mgmt_task), - initial_cmdsn, &hn); - if (!cls_session) - return NULL; - *hostno = hn; - - session = class_to_transport_session(cls_session); - for (cmd_i = 0; cmd_i < session->cmds_max; cmd_i++) { - struct iscsi_cmd_task *ctask = session->cmds[cmd_i]; - struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; - - ctask->hdr = &tcp_ctask->hdr; - } - - for (cmd_i = 0; cmd_i < session->mgmtpool_max; cmd_i++) { - struct iscsi_mgmt_task *mtask = session->mgmt_cmds[cmd_i]; - struct iscsi_tcp_mgmt_task *tcp_mtask = mtask->dd_data; - - mtask->hdr = &tcp_mtask->hdr; - } - - if (iscsi_r2tpool_alloc(class_to_transport_session(cls_session))) - goto r2tpool_alloc_fail; - - return cls_session; + struct iscsi_conn *conn = cls_conn->dd_data; + int rc; -r2tpool_alloc_fail: - iscsi_session_teardown(cls_session); - return NULL; -} + mutex_lock(&conn->xmitmutex); + rc = iscsi_conn_send_generic(conn, hdr, data, data_size); + mutex_unlock(&conn->xmitmutex); -static void iscsi_tcp_session_destroy(struct iscsi_cls_session *cls_session) -{ - iscsi_r2tpool_free(class_to_transport_session(cls_session)); - iscsi_session_teardown(cls_session); + return rc; } -static struct scsi_host_template iscsi_sht = { - .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, - .sg_tablesize = ISCSI_SG_TABLESIZE, - .cmd_per_lun = ISCSI_DEF_CMD_PER_LUN, - .eh_abort_handler = iscsi_eh_abort, - .eh_host_reset_handler = iscsi_eh_host_reset, - .use_clustering = DISABLE_CLUSTERING, - .proc_name = "iscsi_tcp", - .this_id = -1, -}; - static struct iscsi_transport iscsi_tcp_transport = { .owner = THIS_MODULE, .name = "tcp", .caps = CAP_RECOVERY_L0 | CAP_MULTI_R2T | CAP_HDRDGST | CAP_DATADGST, - .param_mask = ISCSI_MAX_RECV_DLENGTH | - ISCSI_MAX_XMIT_DLENGTH | - ISCSI_HDRDGST_EN | - ISCSI_DATADGST_EN | - ISCSI_INITIAL_R2T_EN | - ISCSI_MAX_R2T | - ISCSI_IMM_DATA_EN | - ISCSI_FIRST_BURST | - ISCSI_MAX_BURST | - ISCSI_PDU_INORDER_EN | - ISCSI_DATASEQ_INORDER_EN | - ISCSI_ERL | - ISCSI_CONN_PORT | - ISCSI_CONN_ADDRESS | - ISCSI_EXP_STATSN, .host_template = &iscsi_sht, + .hostdata_size = sizeof(struct iscsi_session), .conndata_size = sizeof(struct iscsi_conn), .max_conn = 1, .max_cmd_len = ISCSI_TCP_MAX_CMD_LEN, - /* session management */ - .create_session = iscsi_tcp_session_create, - .destroy_session = iscsi_tcp_session_destroy, - /* connection management */ - .create_conn = iscsi_tcp_conn_create, - .bind_conn = iscsi_tcp_conn_bind, - .destroy_conn = iscsi_tcp_conn_destroy, + .create_session = iscsi_session_create, + .destroy_session = iscsi_session_destroy, + .create_conn = iscsi_conn_create, + .bind_conn = iscsi_conn_bind, + .destroy_conn = iscsi_conn_destroy, .set_param = iscsi_conn_set_param, .get_conn_param = iscsi_conn_get_param, - .get_conn_str_param = iscsi_conn_get_str_param, .get_session_param = iscsi_session_get_param, .start_conn = iscsi_conn_start, .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, - .init_cmd_task = iscsi_tcp_cmd_init, - .init_mgmt_task = iscsi_tcp_mgmt_init, - .xmit_cmd_task = iscsi_tcp_ctask_xmit, - .xmit_mgmt_task = iscsi_tcp_mtask_xmit, - .cleanup_cmd_task = iscsi_tcp_cleanup_ctask, - /* recovery */ - .session_recovery_timedout = iscsi_session_recovery_timedout, }; static int __init iscsi_tcp_init(void) { if (iscsi_max_lun < 1) { - printk(KERN_ERR "iscsi_tcp: Invalid max_lun value of %u\n", - iscsi_max_lun); + printk(KERN_ERR "Invalid max_lun value of %u\n", iscsi_max_lun); return -EINVAL; } iscsi_tcp_transport.max_lun = iscsi_max_lun; + taskcache = kmem_cache_create("iscsi_taskcache", + sizeof(struct iscsi_data_task), 0, + SLAB_HWCACHE_ALIGN, NULL, NULL); + if (!taskcache) + return -ENOMEM; + if (!iscsi_register_transport(&iscsi_tcp_transport)) - return -ENODEV; + kmem_cache_destroy(taskcache); return 0; } @@ -2554,6 +3653,7 @@ static void __exit iscsi_tcp_exit(void) { iscsi_unregister_transport(&iscsi_tcp_transport); + kmem_cache_destroy(taskcache); } module_init(iscsi_tcp_init); diff --git a/drivers/scsi/iscsi_tcp.h b/drivers/scsi/iscsi_tcp.h index 808302832..ba26741ac 100644 --- a/drivers/scsi/iscsi_tcp.h +++ b/drivers/scsi/iscsi_tcp.h @@ -2,8 +2,7 @@ * iSCSI Initiator TCP Transport * Copyright (C) 2004 Dmitry Yusupov * Copyright (C) 2004 Alex Aizman - * Copyright (C) 2005 - 2006 Mike Christie - * Copyright (C) 2006 Red Hat, Inc. All rights reserved. + * Copyright (C) 2005 Mike Christie * maintained by open-iscsi@googlegroups.com * * This program is free software; you can redistribute it and/or modify @@ -22,7 +21,20 @@ #ifndef ISCSI_TCP_H #define ISCSI_TCP_H -#include +/* Session's states */ +#define ISCSI_STATE_FREE 1 +#define ISCSI_STATE_LOGGED_IN 2 +#define ISCSI_STATE_FAILED 3 +#define ISCSI_STATE_TERMINATE 4 + +/* Connection's states */ +#define ISCSI_CONN_INITIAL_STAGE 0 +#define ISCSI_CONN_STARTED 1 +#define ISCSI_CONN_STOPPED 2 +#define ISCSI_CONN_CLEANUP_WAIT 3 + +/* Connection suspend "bit" */ +#define SUSPEND_BIT 1 /* Socket's Receive state machine */ #define IN_PROGRESS_WAIT_HEADER 0x0 @@ -30,6 +42,12 @@ #define IN_PROGRESS_DATA_RECV 0x2 #define IN_PROGRESS_DDIGEST_RECV 0x3 +/* Task Mgmt states */ +#define TMABORT_INITIAL 0x0 +#define TMABORT_SUCCESS 0x1 +#define TMABORT_FAILED 0x2 +#define TMABORT_TIMEDOUT 0x3 + /* xmit state machine */ #define XMSTATE_IDLE 0x0 #define XMSTATE_R_HDR 0x1 @@ -44,14 +62,34 @@ #define XMSTATE_W_PAD 0x200 #define XMSTATE_DATA_DIGEST 0x400 +#define ISCSI_CONN_MAX 1 #define ISCSI_CONN_RCVBUF_MIN 262144 #define ISCSI_CONN_SNDBUF_MIN 262144 #define ISCSI_PAD_LEN 4 #define ISCSI_R2T_MAX 16 +#define ISCSI_XMIT_CMDS_MAX 128 /* must be power of 2 */ +#define ISCSI_MGMT_CMDS_MAX 32 /* must be power of 2 */ +#define ISCSI_MGMT_ITT_OFFSET 0xa00 #define ISCSI_SG_TABLESIZE SG_ALL +#define ISCSI_DEF_CMD_PER_LUN 32 +#define ISCSI_MAX_CMD_PER_LUN 128 #define ISCSI_TCP_MAX_CMD_LEN 16 -struct socket; +#define ITT_MASK (0xfff) +#define CID_SHIFT 12 +#define CID_MASK (0xffff<removable && (cmd[0] != TEST_UNIT_READY)) { - printk(KERN_INFO "Device not ready. Make sure" - " there is a disc in the drive.\n"); + if (sdev->removable) break; - } case UNIT_ATTENTION: if (sdev->removable) { sdev->changed = 1; diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index 5569fdcfd..2730d507e 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c @@ -31,26 +31,31 @@ #include #include -#define ISCSI_SESSION_ATTRS 11 -#define ISCSI_CONN_ATTRS 11 -#define ISCSI_HOST_ATTRS 0 +#define ISCSI_SESSION_ATTRS 8 +#define ISCSI_CONN_ATTRS 6 struct iscsi_internal { - int daemon_pid; struct scsi_transport_template t; struct iscsi_transport *iscsi_transport; struct list_head list; - struct class_device cdev; + /* + * based on transport capabilities, at register time we set these + * bits to tell the transport class it wants attributes displayed + * in sysfs or that it can support different iSCSI Data-Path + * capabilities + */ + uint32_t param_mask; - struct class_device_attribute *host_attrs[ISCSI_HOST_ATTRS + 1]; + struct class_device cdev; + /* + * We do not have any private or other attrs. + */ struct transport_container conn_cont; struct class_device_attribute *conn_attrs[ISCSI_CONN_ATTRS + 1]; struct transport_container session_cont; struct class_device_attribute *session_attrs[ISCSI_SESSION_ATTRS + 1]; }; -static int iscsi_session_nr; /* sysfs session id for next new session */ - /* * list of registered transports and lock that must * be held while accessing list. The iscsi_transport_lock must @@ -115,24 +120,6 @@ static struct attribute_group iscsi_transport_group = { .attrs = iscsi_transport_attrs, }; -static int iscsi_setup_host(struct transport_container *tc, struct device *dev, - struct class_device *cdev) -{ - struct Scsi_Host *shost = dev_to_shost(dev); - struct iscsi_host *ihost = shost->shost_data; - - memset(ihost, 0, sizeof(*ihost)); - INIT_LIST_HEAD(&ihost->sessions); - mutex_init(&ihost->mutex); - return 0; -} - -static DECLARE_TRANSPORT_CLASS(iscsi_host_class, - "iscsi_host", - iscsi_setup_host, - NULL, - NULL); - static DECLARE_TRANSPORT_CLASS(iscsi_session_class, "iscsi_session", NULL, @@ -146,6 +133,7 @@ static DECLARE_TRANSPORT_CLASS(iscsi_connection_class, NULL); static struct sock *nls; +static int daemon_pid; static DEFINE_MUTEX(rx_queue_mutex); struct mempool_zone { @@ -177,23 +165,14 @@ static DEFINE_SPINLOCK(sesslock); static LIST_HEAD(connlist); static DEFINE_SPINLOCK(connlock); -static uint32_t iscsi_conn_get_sid(struct iscsi_cls_conn *conn) -{ - struct iscsi_cls_session *sess = iscsi_dev_to_session(conn->dev.parent); - return sess->sid; -} - -/* - * Returns the matching session to a given sid - */ -static struct iscsi_cls_session *iscsi_session_lookup(uint32_t sid) +static struct iscsi_cls_session *iscsi_session_lookup(uint64_t handle) { unsigned long flags; struct iscsi_cls_session *sess; spin_lock_irqsave(&sesslock, flags); list_for_each_entry(sess, &sesslist, sess_list) { - if (sess->sid == sid) { + if (sess == iscsi_ptr(handle)) { spin_unlock_irqrestore(&sesslock, flags); return sess; } @@ -202,17 +181,14 @@ static struct iscsi_cls_session *iscsi_session_lookup(uint32_t sid) return NULL; } -/* - * Returns the matching connection to a given sid / cid tuple - */ -static struct iscsi_cls_conn *iscsi_conn_lookup(uint32_t sid, uint32_t cid) +static struct iscsi_cls_conn *iscsi_conn_lookup(uint64_t handle) { unsigned long flags; struct iscsi_cls_conn *conn; spin_lock_irqsave(&connlock, flags); list_for_each_entry(conn, &connlist, conn_list) { - if ((conn->cid == cid) && (iscsi_conn_get_sid(conn) == sid)) { + if (conn == iscsi_ptr(handle)) { spin_unlock_irqrestore(&connlock, flags); return conn; } @@ -233,7 +209,6 @@ static void iscsi_session_release(struct device *dev) shost = iscsi_session_to_shost(session); scsi_host_put(shost); - kfree(session->targetname); kfree(session); module_put(transport->owner); } @@ -243,95 +218,30 @@ static int iscsi_is_session_dev(const struct device *dev) return dev->release == iscsi_session_release; } -static int iscsi_user_scan(struct Scsi_Host *shost, uint channel, - uint id, uint lun) -{ - struct iscsi_host *ihost = shost->shost_data; - struct iscsi_cls_session *session; - - mutex_lock(&ihost->mutex); - list_for_each_entry(session, &ihost->sessions, host_list) { - if ((channel == SCAN_WILD_CARD || - channel == session->channel) && - (id == SCAN_WILD_CARD || id == session->target_id)) - scsi_scan_target(&session->dev, session->channel, - session->target_id, lun, 1); - } - mutex_unlock(&ihost->mutex); - - return 0; -} - -static void session_recovery_timedout(void *data) -{ - struct iscsi_cls_session *session = data; - - dev_printk(KERN_INFO, &session->dev, "iscsi: session recovery timed " - "out after %d secs\n", session->recovery_tmo); - - if (session->transport->session_recovery_timedout) - session->transport->session_recovery_timedout(session); - - scsi_target_unblock(&session->dev); -} - -void iscsi_unblock_session(struct iscsi_cls_session *session) -{ - if (!cancel_delayed_work(&session->recovery_work)) - flush_scheduled_work(); - scsi_target_unblock(&session->dev); -} -EXPORT_SYMBOL_GPL(iscsi_unblock_session); - -void iscsi_block_session(struct iscsi_cls_session *session) -{ - scsi_target_block(&session->dev); - schedule_delayed_work(&session->recovery_work, - session->recovery_tmo * HZ); -} -EXPORT_SYMBOL_GPL(iscsi_block_session); - /** * iscsi_create_session - create iscsi class session * @shost: scsi host * @transport: iscsi transport * - * This can be called from a LLD or iscsi_transport. + * This can be called from a LLD or iscsi_transport **/ struct iscsi_cls_session * -iscsi_create_session(struct Scsi_Host *shost, - struct iscsi_transport *transport, int channel) +iscsi_create_session(struct Scsi_Host *shost, struct iscsi_transport *transport) { - struct iscsi_host *ihost; struct iscsi_cls_session *session; int err; if (!try_module_get(transport->owner)) return NULL; - session = kzalloc(sizeof(*session) + transport->sessiondata_size, - GFP_KERNEL); + session = kzalloc(sizeof(*session), GFP_KERNEL); if (!session) goto module_put; session->transport = transport; - session->recovery_tmo = 120; - INIT_WORK(&session->recovery_work, session_recovery_timedout, session); - INIT_LIST_HEAD(&session->host_list); - INIT_LIST_HEAD(&session->sess_list); - - if (transport->sessiondata_size) - session->dd_data = &session[1]; /* this is released in the dev's release function */ scsi_host_get(shost); - ihost = shost->shost_data; - - session->sid = iscsi_session_nr++; - session->channel = channel; - session->target_id = ihost->next_target_id++; - - snprintf(session->dev.bus_id, BUS_ID_SIZE, "session%u", - session->sid); + snprintf(session->dev.bus_id, BUS_ID_SIZE, "session%u", shost->host_no); session->dev.parent = &shost->shost_gendev; session->dev.release = iscsi_session_release; err = device_register(&session->dev); @@ -342,10 +252,6 @@ iscsi_create_session(struct Scsi_Host *shost, } transport_register_device(&session->dev); - mutex_lock(&ihost->mutex); - list_add(&session->host_list, &ihost->sessions); - mutex_unlock(&ihost->mutex); - return session; free_session: @@ -366,16 +272,6 @@ EXPORT_SYMBOL_GPL(iscsi_create_session); **/ int iscsi_destroy_session(struct iscsi_cls_session *session) { - struct Scsi_Host *shost = iscsi_session_to_shost(session); - struct iscsi_host *ihost = shost->shost_data; - - if (!cancel_delayed_work(&session->recovery_work)) - flush_scheduled_work(); - - mutex_lock(&ihost->mutex); - list_del(&session->host_list); - mutex_unlock(&ihost->mutex); - transport_unregister_device(&session->dev); device_unregister(&session->dev); return 0; @@ -388,7 +284,6 @@ static void iscsi_conn_release(struct device *dev) struct iscsi_cls_conn *conn = iscsi_dev_to_conn(dev); struct device *parent = conn->dev.parent; - kfree(conn->persistent_address); kfree(conn); put_device(parent); } @@ -406,16 +301,12 @@ static int iscsi_is_conn_dev(const struct device *dev) * This can be called from a LLD or iscsi_transport. The connection * is child of the session so cid must be unique for all connections * on the session. - * - * Since we do not support MCS, cid will normally be zero. In some cases - * for software iscsi we could be trying to preallocate a connection struct - * in which case there could be two connection structs and cid would be - * non-zero. **/ struct iscsi_cls_conn * iscsi_create_conn(struct iscsi_cls_session *session, uint32_t cid) { struct iscsi_transport *transport = session->transport; + struct Scsi_Host *shost = iscsi_session_to_shost(session); struct iscsi_cls_conn *conn; int err; @@ -428,14 +319,12 @@ iscsi_create_conn(struct iscsi_cls_session *session, uint32_t cid) INIT_LIST_HEAD(&conn->conn_list); conn->transport = transport; - conn->cid = cid; /* this is released in the dev's release function */ if (!get_device(&session->dev)) goto free_conn; - snprintf(conn->dev.bus_id, BUS_ID_SIZE, "connection%d:%u", - session->sid, cid); + shost->host_no, cid); conn->dev.parent = &session->dev; conn->dev.release = iscsi_conn_release; err = device_register(&conn->dev); @@ -471,6 +360,105 @@ int iscsi_destroy_conn(struct iscsi_cls_conn *conn) EXPORT_SYMBOL_GPL(iscsi_destroy_conn); +/* + * These functions are used only by software iscsi_transports + * which do not allocate and more their scsi_hosts since this + * is initiated from userspace. + */ + +/* + * iSCSI Session's hostdata organization: + * + * *------------------* <== hostdata_session(host->hostdata) + * | ptr to class sess| + * |------------------| <== iscsi_hostdata(host->hostdata) + * | transport's data | + * *------------------* + */ + +#define hostdata_privsize(_t) (sizeof(unsigned long) + _t->hostdata_size + \ + _t->hostdata_size % sizeof(unsigned long)) + +#define hostdata_session(_hostdata) (iscsi_ptr(*(unsigned long *)_hostdata)) + +/** + * iscsi_transport_create_session - create iscsi cls session and host + * scsit: scsi transport template + * transport: iscsi transport template + * + * This can be used by software iscsi_transports that allocate + * a session per scsi host. + **/ +struct Scsi_Host * +iscsi_transport_create_session(struct scsi_transport_template *scsit, + struct iscsi_transport *transport) +{ + struct iscsi_cls_session *session; + struct Scsi_Host *shost; + unsigned long flags; + + shost = scsi_host_alloc(transport->host_template, + hostdata_privsize(transport)); + if (!shost) { + printk(KERN_ERR "iscsi: can not allocate SCSI host for " + "session\n"); + return NULL; + } + + shost->max_id = 1; + shost->max_channel = 0; + shost->max_lun = transport->max_lun; + shost->max_cmd_len = transport->max_cmd_len; + shost->transportt = scsit; + shost->transportt->create_work_queue = 1; + + if (scsi_add_host(shost, NULL)) + goto free_host; + + session = iscsi_create_session(shost, transport); + if (!session) + goto remove_host; + + *(unsigned long*)shost->hostdata = (unsigned long)session; + spin_lock_irqsave(&sesslock, flags); + list_add(&session->sess_list, &sesslist); + spin_unlock_irqrestore(&sesslock, flags); + return shost; + +remove_host: + scsi_remove_host(shost); +free_host: + scsi_host_put(shost); + return NULL; +} + +EXPORT_SYMBOL_GPL(iscsi_transport_create_session); + +/** + * iscsi_transport_destroy_session - destroy session and scsi host + * shost: scsi host + * + * This can be used by software iscsi_transports that allocate + * a session per scsi host. + **/ +int iscsi_transport_destroy_session(struct Scsi_Host *shost) +{ + struct iscsi_cls_session *session; + unsigned long flags; + + scsi_remove_host(shost); + session = hostdata_session(shost->hostdata); + spin_lock_irqsave(&sesslock, flags); + list_del(&session->sess_list); + spin_unlock_irqrestore(&sesslock, flags); + iscsi_destroy_session(session); + /* ref from host alloc */ + scsi_host_put(shost); + return 0; +} + +EXPORT_SYMBOL_GPL(iscsi_transport_destroy_session); + /* * iscsi interface functions */ @@ -572,13 +560,13 @@ mempool_zone_get_skb(struct mempool_zone *zone) } static int -iscsi_unicast_skb(struct mempool_zone *zone, struct sk_buff *skb, int pid) +iscsi_unicast_skb(struct mempool_zone *zone, struct sk_buff *skb) { unsigned long flags; int rc; skb_get(skb); - rc = netlink_unicast(nls, skb, pid, MSG_DONTWAIT); + rc = netlink_unicast(nls, skb, daemon_pid, MSG_DONTWAIT); if (rc < 0) { mempool_free(skb, zone->pool); printk(KERN_ERR "iscsi: can not unicast skb (%d)\n", rc); @@ -586,7 +574,6 @@ iscsi_unicast_skb(struct mempool_zone *zone, struct sk_buff *skb, int pid) } spin_lock_irqsave(&zone->freelock, flags); - INIT_LIST_HEAD(skb_to_lh(skb)); list_add(skb_to_lh(skb), &zone->freequeue); spin_unlock_irqrestore(&zone->freelock, flags); @@ -600,14 +587,9 @@ int iscsi_recv_pdu(struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr, struct sk_buff *skb; struct iscsi_uevent *ev; char *pdu; - struct iscsi_internal *priv; int len = NLMSG_SPACE(sizeof(*ev) + sizeof(struct iscsi_hdr) + data_size); - priv = iscsi_if_transport_lookup(conn->transport); - if (!priv) - return -EINVAL; - mempool_zone_complete(conn->z_pdu); skb = mempool_zone_get_skb(conn->z_pdu); @@ -618,20 +600,19 @@ int iscsi_recv_pdu(struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr, return -ENOMEM; } - nlh = __nlmsg_put(skb, priv->daemon_pid, 0, 0, (len - sizeof(*nlh)), 0); + nlh = __nlmsg_put(skb, daemon_pid, 0, 0, (len - sizeof(*nlh)), 0); ev = NLMSG_DATA(nlh); memset(ev, 0, sizeof(*ev)); ev->transport_handle = iscsi_handle(conn->transport); ev->type = ISCSI_KEVENT_RECV_PDU; if (atomic_read(&conn->z_pdu->allocated) >= conn->z_pdu->hiwat) ev->iferror = -ENOMEM; - ev->r.recv_req.cid = conn->cid; - ev->r.recv_req.sid = iscsi_conn_get_sid(conn); + ev->r.recv_req.conn_handle = iscsi_handle(conn); pdu = (char*)ev + sizeof(*ev); memcpy(pdu, hdr, sizeof(struct iscsi_hdr)); memcpy(pdu + sizeof(struct iscsi_hdr), data, data_size); - return iscsi_unicast_skb(conn->z_pdu, skb, priv->daemon_pid); + return iscsi_unicast_skb(conn->z_pdu, skb); } EXPORT_SYMBOL_GPL(iscsi_recv_pdu); @@ -640,13 +621,8 @@ void iscsi_conn_error(struct iscsi_cls_conn *conn, enum iscsi_err error) struct nlmsghdr *nlh; struct sk_buff *skb; struct iscsi_uevent *ev; - struct iscsi_internal *priv; int len = NLMSG_SPACE(sizeof(*ev)); - priv = iscsi_if_transport_lookup(conn->transport); - if (!priv) - return; - mempool_zone_complete(conn->z_error); skb = mempool_zone_get_skb(conn->z_error); @@ -656,17 +632,16 @@ void iscsi_conn_error(struct iscsi_cls_conn *conn, enum iscsi_err error) return; } - nlh = __nlmsg_put(skb, priv->daemon_pid, 0, 0, (len - sizeof(*nlh)), 0); + nlh = __nlmsg_put(skb, daemon_pid, 0, 0, (len - sizeof(*nlh)), 0); ev = NLMSG_DATA(nlh); ev->transport_handle = iscsi_handle(conn->transport); ev->type = ISCSI_KEVENT_CONN_ERROR; if (atomic_read(&conn->z_error->allocated) >= conn->z_error->hiwat) ev->iferror = -ENOMEM; ev->r.connerror.error = error; - ev->r.connerror.cid = conn->cid; - ev->r.connerror.sid = iscsi_conn_get_sid(conn); + ev->r.connerror.conn_handle = iscsi_handle(conn); - iscsi_unicast_skb(conn->z_error, skb, priv->daemon_pid); + iscsi_unicast_skb(conn->z_error, skb); dev_printk(KERN_INFO, &conn->dev, "iscsi: detected conn error (%d)\n", error); @@ -696,7 +671,7 @@ iscsi_if_send_reply(int pid, int seq, int type, int done, int multi, nlh = __nlmsg_put(skb, pid, seq, t, (len - sizeof(*nlh)), 0); nlh->nlmsg_flags = flags; memcpy(NLMSG_DATA(nlh), payload, size); - return iscsi_unicast_skb(z_reply, skb, pid); + return iscsi_unicast_skb(z_reply, skb); } static int @@ -708,18 +683,13 @@ iscsi_if_get_stats(struct iscsi_transport *transport, struct nlmsghdr *nlh) struct iscsi_cls_conn *conn; struct nlmsghdr *nlhstat; struct iscsi_uevent *evstat; - struct iscsi_internal *priv; int len = NLMSG_SPACE(sizeof(*ev) + sizeof(struct iscsi_stats) + sizeof(struct iscsi_stats_custom) * ISCSI_STATS_CUSTOM_MAX); int err = 0; - priv = iscsi_if_transport_lookup(transport); - if (!priv) - return -EINVAL; - - conn = iscsi_conn_lookup(ev->u.get_stats.sid, ev->u.get_stats.cid); + conn = iscsi_conn_lookup(ev->u.get_stats.conn_handle); if (!conn) return -EEXIST; @@ -735,7 +705,7 @@ iscsi_if_get_stats(struct iscsi_transport *transport, struct nlmsghdr *nlh) return -ENOMEM; } - nlhstat = __nlmsg_put(skbstat, priv->daemon_pid, 0, 0, + nlhstat = __nlmsg_put(skbstat, daemon_pid, 0, 0, (len - sizeof(*nlhstat)), 0); evstat = NLMSG_DATA(nlhstat); memset(evstat, 0, sizeof(*evstat)); @@ -743,10 +713,8 @@ iscsi_if_get_stats(struct iscsi_transport *transport, struct nlmsghdr *nlh) evstat->type = nlh->nlmsg_type; if (atomic_read(&conn->z_pdu->allocated) >= conn->z_pdu->hiwat) evstat->iferror = -ENOMEM; - evstat->u.get_stats.cid = - ev->u.get_stats.cid; - evstat->u.get_stats.sid = - ev->u.get_stats.sid; + evstat->u.get_stats.conn_handle = + ev->u.get_stats.conn_handle; stats = (struct iscsi_stats *) ((char*)evstat + sizeof(*evstat)); memset(stats, 0, sizeof(*stats)); @@ -761,7 +729,7 @@ iscsi_if_get_stats(struct iscsi_transport *transport, struct nlmsghdr *nlh) skb_trim(skbstat, NLMSG_ALIGN(actual_size)); nlhstat->nlmsg_len = actual_size; - err = iscsi_unicast_skb(conn->z_pdu, skbstat, priv->daemon_pid); + err = iscsi_unicast_skb(conn->z_pdu, skbstat); } while (err < 0 && err != -ECONNREFUSED); return err; @@ -772,21 +740,16 @@ iscsi_if_create_session(struct iscsi_internal *priv, struct iscsi_uevent *ev) { struct iscsi_transport *transport = priv->iscsi_transport; struct iscsi_cls_session *session; - unsigned long flags; - uint32_t hostno; + uint32_t sid; - session = transport->create_session(transport, &priv->t, + session = transport->create_session(&priv->t, ev->u.c_session.initial_cmdsn, - &hostno); + &sid); if (!session) return -ENOMEM; - spin_lock_irqsave(&sesslock, flags); - list_add(&session->sess_list, &sesslist); - spin_unlock_irqrestore(&sesslock, flags); - - ev->r.c_session_ret.host_no = hostno; - ev->r.c_session_ret.sid = session->sid; + ev->r.c_session_ret.session_handle = iscsi_handle(session); + ev->r.c_session_ret.sid = sid; return 0; } @@ -797,20 +760,13 @@ iscsi_if_create_conn(struct iscsi_transport *transport, struct iscsi_uevent *ev) struct iscsi_cls_session *session; unsigned long flags; - session = iscsi_session_lookup(ev->u.c_conn.sid); - if (!session) { - printk(KERN_ERR "iscsi: invalid session %d\n", - ev->u.c_conn.sid); + session = iscsi_session_lookup(ev->u.c_conn.session_handle); + if (!session) return -EINVAL; - } conn = transport->create_conn(session, ev->u.c_conn.cid); - if (!conn) { - printk(KERN_ERR "iscsi: couldn't create a new " - "connection for session %d\n", - session->sid); + if (!conn) return -ENOMEM; - } conn->z_pdu = mempool_zone_init(Z_MAX_PDU, NLMSG_SPACE(sizeof(struct iscsi_uevent) + @@ -832,8 +788,7 @@ iscsi_if_create_conn(struct iscsi_transport *transport, struct iscsi_uevent *ev) goto free_pdu_pool; } - ev->r.c_conn_ret.sid = session->sid; - ev->r.c_conn_ret.cid = conn->cid; + ev->r.handle = iscsi_handle(conn); spin_lock_irqsave(&connlock, flags); list_add(&conn->conn_list, &connlist); @@ -857,7 +812,7 @@ iscsi_if_destroy_conn(struct iscsi_transport *transport, struct iscsi_uevent *ev struct iscsi_cls_conn *conn; struct mempool_zone *z_error, *z_pdu; - conn = iscsi_conn_lookup(ev->u.d_conn.sid, ev->u.d_conn.cid); + conn = iscsi_conn_lookup(ev->u.d_conn.conn_handle); if (!conn) return -EINVAL; spin_lock_irqsave(&connlock, flags); @@ -877,106 +832,6 @@ iscsi_if_destroy_conn(struct iscsi_transport *transport, struct iscsi_uevent *ev return 0; } -static void -iscsi_copy_param(struct iscsi_uevent *ev, uint32_t *value, char *data) -{ - if (ev->u.set_param.len != sizeof(uint32_t)) - BUG(); - memcpy(value, data, min_t(uint32_t, sizeof(uint32_t), - ev->u.set_param.len)); -} - -static int -iscsi_set_param(struct iscsi_transport *transport, struct iscsi_uevent *ev) -{ - char *data = (char*)ev + sizeof(*ev); - struct iscsi_cls_conn *conn; - struct iscsi_cls_session *session; - int err = 0; - uint32_t value = 0; - - session = iscsi_session_lookup(ev->u.set_param.sid); - conn = iscsi_conn_lookup(ev->u.set_param.sid, ev->u.set_param.cid); - if (!conn || !session) - return -EINVAL; - - switch (ev->u.set_param.param) { - case ISCSI_PARAM_SESS_RECOVERY_TMO: - iscsi_copy_param(ev, &value, data); - if (value != 0) - session->recovery_tmo = value; - break; - case ISCSI_PARAM_TARGET_NAME: - /* this should not change between logins */ - if (session->targetname) - return 0; - - session->targetname = kstrdup(data, GFP_KERNEL); - if (!session->targetname) - return -ENOMEM; - break; - case ISCSI_PARAM_TPGT: - iscsi_copy_param(ev, &value, data); - session->tpgt = value; - break; - case ISCSI_PARAM_PERSISTENT_PORT: - iscsi_copy_param(ev, &value, data); - conn->persistent_port = value; - break; - case ISCSI_PARAM_PERSISTENT_ADDRESS: - /* - * this is the address returned in discovery so it should - * not change between logins. - */ - if (conn->persistent_address) - return 0; - - conn->persistent_address = kstrdup(data, GFP_KERNEL); - if (!conn->persistent_address) - return -ENOMEM; - break; - default: - iscsi_copy_param(ev, &value, data); - err = transport->set_param(conn, ev->u.set_param.param, value); - } - - return err; -} - -static int -iscsi_if_transport_ep(struct iscsi_transport *transport, - struct iscsi_uevent *ev, int msg_type) -{ - struct sockaddr *dst_addr; - int rc = 0; - - switch (msg_type) { - case ISCSI_UEVENT_TRANSPORT_EP_CONNECT: - if (!transport->ep_connect) - return -EINVAL; - - dst_addr = (struct sockaddr *)((char*)ev + sizeof(*ev)); - rc = transport->ep_connect(dst_addr, - ev->u.ep_connect.non_blocking, - &ev->r.ep_connect_ret.handle); - break; - case ISCSI_UEVENT_TRANSPORT_EP_POLL: - if (!transport->ep_poll) - return -EINVAL; - - ev->r.retcode = transport->ep_poll(ev->u.ep_poll.ep_handle, - ev->u.ep_poll.timeout_ms); - break; - case ISCSI_UEVENT_TRANSPORT_EP_DISCONNECT: - if (!transport->ep_disconnect) - return -EINVAL; - - transport->ep_disconnect(ev->u.ep_disconnect.ep_handle); - break; - } - return rc; -} - static int iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) { @@ -986,7 +841,6 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) struct iscsi_internal *priv; struct iscsi_cls_session *session; struct iscsi_cls_conn *conn; - unsigned long flags; priv = iscsi_if_transport_lookup(iscsi_ptr(ev->transport_handle)); if (!priv) @@ -996,21 +850,15 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) if (!try_module_get(transport->owner)) return -EINVAL; - priv->daemon_pid = NETLINK_CREDS(skb)->pid; - switch (nlh->nlmsg_type) { case ISCSI_UEVENT_CREATE_SESSION: err = iscsi_if_create_session(priv, ev); break; case ISCSI_UEVENT_DESTROY_SESSION: - session = iscsi_session_lookup(ev->u.d_session.sid); - if (session) { - spin_lock_irqsave(&sesslock, flags); - list_del(&session->sess_list); - spin_unlock_irqrestore(&sesslock, flags); - + session = iscsi_session_lookup(ev->u.d_session.session_handle); + if (session) transport->destroy_session(session); - } else + else err = -EINVAL; break; case ISCSI_UEVENT_CREATE_CONN: @@ -1020,35 +868,41 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) err = iscsi_if_destroy_conn(transport, ev); break; case ISCSI_UEVENT_BIND_CONN: - session = iscsi_session_lookup(ev->u.b_conn.sid); - conn = iscsi_conn_lookup(ev->u.b_conn.sid, ev->u.b_conn.cid); + session = iscsi_session_lookup(ev->u.b_conn.session_handle); + conn = iscsi_conn_lookup(ev->u.b_conn.conn_handle); if (session && conn) ev->r.retcode = transport->bind_conn(session, conn, - ev->u.b_conn.transport_eph, + ev->u.b_conn.transport_fd, ev->u.b_conn.is_leading); else err = -EINVAL; break; case ISCSI_UEVENT_SET_PARAM: - err = iscsi_set_param(transport, ev); + conn = iscsi_conn_lookup(ev->u.set_param.conn_handle); + if (conn) + ev->r.retcode = transport->set_param(conn, + ev->u.set_param.param, ev->u.set_param.value); + else + err = -EINVAL; break; case ISCSI_UEVENT_START_CONN: - conn = iscsi_conn_lookup(ev->u.start_conn.sid, ev->u.start_conn.cid); + conn = iscsi_conn_lookup(ev->u.start_conn.conn_handle); if (conn) ev->r.retcode = transport->start_conn(conn); else err = -EINVAL; + break; case ISCSI_UEVENT_STOP_CONN: - conn = iscsi_conn_lookup(ev->u.stop_conn.sid, ev->u.stop_conn.cid); + conn = iscsi_conn_lookup(ev->u.stop_conn.conn_handle); if (conn) transport->stop_conn(conn, ev->u.stop_conn.flag); else err = -EINVAL; break; case ISCSI_UEVENT_SEND_PDU: - conn = iscsi_conn_lookup(ev->u.send_pdu.sid, ev->u.send_pdu.cid); + conn = iscsi_conn_lookup(ev->u.send_pdu.conn_handle); if (conn) ev->r.retcode = transport->send_pdu(conn, (struct iscsi_hdr*)((char*)ev + sizeof(*ev)), @@ -1060,11 +914,6 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) case ISCSI_UEVENT_GET_STATS: err = iscsi_if_get_stats(transport, nlh); break; - case ISCSI_UEVENT_TRANSPORT_EP_CONNECT: - case ISCSI_UEVENT_TRANSPORT_EP_POLL: - case ISCSI_UEVENT_TRANSPORT_EP_DISCONNECT: - err = iscsi_if_transport_ep(transport, ev, nlh->nlmsg_type); - break; default: err = -EINVAL; break; @@ -1074,11 +923,9 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) return err; } -/* - * Get message from skb (based on rtnetlink_rcv_skb). Each message is - * processed by iscsi_if_recv_msg. Malformed skbs with wrong lengths or - * invalid creds are discarded silently. - */ +/* Get message from skb (based on rtnetlink_rcv_skb). Each message is + * processed by iscsi_if_recv_msg. Malformed skbs with wrong length are + * or invalid creds discarded silently. */ static void iscsi_if_rx(struct sock *sk, int len) { @@ -1090,6 +937,7 @@ iscsi_if_rx(struct sock *sk, int len) skb_pull(skb, skb->len); goto free_skb; } + daemon_pid = NETLINK_CREDS(skb)->pid; while (skb->len >= NLMSG_SPACE(0)) { int err; @@ -1140,10 +988,6 @@ free_skb: #define iscsi_cdev_to_conn(_cdev) \ iscsi_dev_to_conn(_cdev->dev) -#define ISCSI_CLASS_ATTR(_prefix,_name,_mode,_show,_store) \ -struct class_device_attribute class_device_attr_##_prefix##_##_name = \ - __ATTR(_name,_mode,_show,_store) - /* * iSCSI connection attrs */ @@ -1161,8 +1005,7 @@ show_conn_int_param_##param(struct class_device *cdev, char *buf) \ #define iscsi_conn_int_attr(field, param, format) \ iscsi_conn_int_attr_show(param, format) \ -static ISCSI_CLASS_ATTR(conn, field, S_IRUGO, show_conn_int_param_##param, \ - NULL); +static CLASS_DEVICE_ATTR(field, S_IRUGO, show_conn_int_param_##param, NULL); iscsi_conn_int_attr(max_recv_dlength, ISCSI_PARAM_MAX_RECV_DLENGTH, "%u"); iscsi_conn_int_attr(max_xmit_dlength, ISCSI_PARAM_MAX_XMIT_DLENGTH, "%u"); @@ -1170,26 +1013,6 @@ iscsi_conn_int_attr(header_digest, ISCSI_PARAM_HDRDGST_EN, "%d"); iscsi_conn_int_attr(data_digest, ISCSI_PARAM_DATADGST_EN, "%d"); iscsi_conn_int_attr(ifmarker, ISCSI_PARAM_IFMARKER_EN, "%d"); iscsi_conn_int_attr(ofmarker, ISCSI_PARAM_OFMARKER_EN, "%d"); -iscsi_conn_int_attr(persistent_port, ISCSI_PARAM_PERSISTENT_PORT, "%d"); -iscsi_conn_int_attr(port, ISCSI_PARAM_CONN_PORT, "%d"); -iscsi_conn_int_attr(exp_statsn, ISCSI_PARAM_EXP_STATSN, "%u"); - -#define iscsi_conn_str_attr_show(param) \ -static ssize_t \ -show_conn_str_param_##param(struct class_device *cdev, char *buf) \ -{ \ - struct iscsi_cls_conn *conn = iscsi_cdev_to_conn(cdev); \ - struct iscsi_transport *t = conn->transport; \ - return t->get_conn_str_param(conn, param, buf); \ -} - -#define iscsi_conn_str_attr(field, param) \ - iscsi_conn_str_attr_show(param) \ -static ISCSI_CLASS_ATTR(conn, field, S_IRUGO, show_conn_str_param_##param, \ - NULL); - -iscsi_conn_str_attr(persistent_address, ISCSI_PARAM_PERSISTENT_ADDRESS); -iscsi_conn_str_attr(address, ISCSI_PARAM_CONN_ADDRESS); #define iscsi_cdev_to_session(_cdev) \ iscsi_dev_to_session(_cdev->dev) @@ -1211,8 +1034,7 @@ show_session_int_param_##param(struct class_device *cdev, char *buf) \ #define iscsi_session_int_attr(field, param, format) \ iscsi_session_int_attr_show(param, format) \ -static ISCSI_CLASS_ATTR(sess, field, S_IRUGO, show_session_int_param_##param, \ - NULL); +static CLASS_DEVICE_ATTR(field, S_IRUGO, show_session_int_param_##param, NULL); iscsi_session_int_attr(initial_r2t, ISCSI_PARAM_INITIAL_R2T_EN, "%d"); iscsi_session_int_attr(max_outstanding_r2t, ISCSI_PARAM_MAX_R2T, "%hu"); @@ -1222,89 +1044,18 @@ iscsi_session_int_attr(max_burst_len, ISCSI_PARAM_MAX_BURST, "%u"); iscsi_session_int_attr(data_pdu_in_order, ISCSI_PARAM_PDU_INORDER_EN, "%d"); iscsi_session_int_attr(data_seq_in_order, ISCSI_PARAM_DATASEQ_INORDER_EN, "%d"); iscsi_session_int_attr(erl, ISCSI_PARAM_ERL, "%d"); -iscsi_session_int_attr(tpgt, ISCSI_PARAM_TPGT, "%d"); - -#define iscsi_session_str_attr_show(param) \ -static ssize_t \ -show_session_str_param_##param(struct class_device *cdev, char *buf) \ -{ \ - struct iscsi_cls_session *session = iscsi_cdev_to_session(cdev); \ - struct iscsi_transport *t = session->transport; \ - return t->get_session_str_param(session, param, buf); \ -} - -#define iscsi_session_str_attr(field, param) \ - iscsi_session_str_attr_show(param) \ -static ISCSI_CLASS_ATTR(sess, field, S_IRUGO, show_session_str_param_##param, \ - NULL); - -iscsi_session_str_attr(targetname, ISCSI_PARAM_TARGET_NAME); - -/* - * Private session and conn attrs. userspace uses several iscsi values - * to identify each session between reboots. Some of these values may not - * be present in the iscsi_transport/LLD driver becuase userspace handles - * login (and failback for login redirect) so for these type of drivers - * the class manages the attrs and values for the iscsi_transport/LLD - */ -#define iscsi_priv_session_attr_show(field, format) \ -static ssize_t \ -show_priv_session_##field(struct class_device *cdev, char *buf) \ -{ \ - struct iscsi_cls_session *session = iscsi_cdev_to_session(cdev); \ - return sprintf(buf, format"\n", session->field); \ -} - -#define iscsi_priv_session_attr(field, format) \ - iscsi_priv_session_attr_show(field, format) \ -static ISCSI_CLASS_ATTR(priv_sess, field, S_IRUGO, show_priv_session_##field, \ - NULL) -iscsi_priv_session_attr(targetname, "%s"); -iscsi_priv_session_attr(tpgt, "%d"); -iscsi_priv_session_attr(recovery_tmo, "%d"); - -#define iscsi_priv_conn_attr_show(field, format) \ -static ssize_t \ -show_priv_conn_##field(struct class_device *cdev, char *buf) \ -{ \ - struct iscsi_cls_conn *conn = iscsi_cdev_to_conn(cdev); \ - return sprintf(buf, format"\n", conn->field); \ -} -#define iscsi_priv_conn_attr(field, format) \ - iscsi_priv_conn_attr_show(field, format) \ -static ISCSI_CLASS_ATTR(priv_conn, field, S_IRUGO, show_priv_conn_##field, \ - NULL) -iscsi_priv_conn_attr(persistent_address, "%s"); -iscsi_priv_conn_attr(persistent_port, "%d"); - -#define SETUP_PRIV_SESSION_RD_ATTR(field) \ -do { \ - priv->session_attrs[count] = &class_device_attr_priv_sess_##field; \ - count++; \ -} while (0) - -#define SETUP_SESSION_RD_ATTR(field, param_flag) \ -do { \ - if (tt->param_mask & param_flag) { \ - priv->session_attrs[count] = &class_device_attr_sess_##field; \ +#define SETUP_SESSION_RD_ATTR(field, param) \ + if (priv->param_mask & (1 << param)) { \ + priv->session_attrs[count] = &class_device_attr_##field;\ count++; \ - } \ -} while (0) - -#define SETUP_PRIV_CONN_RD_ATTR(field) \ -do { \ - priv->conn_attrs[count] = &class_device_attr_priv_conn_##field; \ - count++; \ -} while (0) - -#define SETUP_CONN_RD_ATTR(field, param_flag) \ -do { \ - if (tt->param_mask & param_flag) { \ - priv->conn_attrs[count] = &class_device_attr_conn_##field; \ + } + +#define SETUP_CONN_RD_ATTR(field, param) \ + if (priv->param_mask & (1 << param)) { \ + priv->conn_attrs[count] = &class_device_attr_##field; \ count++; \ - } \ -} while (0) + } static int iscsi_session_match(struct attribute_container *cont, struct device *dev) @@ -1353,24 +1104,6 @@ static int iscsi_conn_match(struct attribute_container *cont, return &priv->conn_cont.ac == cont; } -static int iscsi_host_match(struct attribute_container *cont, - struct device *dev) -{ - struct Scsi_Host *shost; - struct iscsi_internal *priv; - - if (!scsi_is_host_device(dev)) - return 0; - - shost = dev_to_shost(dev); - if (!shost->transportt || - shost->transportt->host_attrs.ac.class != &iscsi_host_class.class) - return 0; - - priv = to_iscsi_internal(shost->transportt); - return &priv->t.host_attrs.ac == cont; -} - struct scsi_transport_template * iscsi_register_transport(struct iscsi_transport *tt) { @@ -1389,7 +1122,6 @@ iscsi_register_transport(struct iscsi_transport *tt) return NULL; INIT_LIST_HEAD(&priv->list); priv->iscsi_transport = tt; - priv->t.user_scan = iscsi_user_scan; priv->cdev.class = &iscsi_transport_class; snprintf(priv->cdev.class_id, BUS_ID_SIZE, "%s", tt->name); @@ -1401,13 +1133,18 @@ iscsi_register_transport(struct iscsi_transport *tt) if (err) goto unregister_cdev; - /* host parameters */ - priv->t.host_attrs.ac.attrs = &priv->host_attrs[0]; - priv->t.host_attrs.ac.class = &iscsi_host_class.class; - priv->t.host_attrs.ac.match = iscsi_host_match; - priv->t.host_size = sizeof(struct iscsi_host); - priv->host_attrs[0] = NULL; - transport_container_register(&priv->t.host_attrs); + /* setup parameters mask */ + priv->param_mask = 0xFFFFFFFF; + if (!(tt->caps & CAP_MULTI_R2T)) + priv->param_mask &= ~(1 << ISCSI_PARAM_MAX_R2T); + if (!(tt->caps & CAP_HDRDGST)) + priv->param_mask &= ~(1 << ISCSI_PARAM_HDRDGST_EN); + if (!(tt->caps & CAP_DATADGST)) + priv->param_mask &= ~(1 << ISCSI_PARAM_DATADGST_EN); + if (!(tt->caps & CAP_MARKERS)) { + priv->param_mask &= ~(1 << ISCSI_PARAM_IFMARKER_EN); + priv->param_mask &= ~(1 << ISCSI_PARAM_OFMARKER_EN); + } /* connection parameters */ priv->conn_cont.ac.attrs = &priv->conn_attrs[0]; @@ -1415,25 +1152,12 @@ iscsi_register_transport(struct iscsi_transport *tt) priv->conn_cont.ac.match = iscsi_conn_match; transport_container_register(&priv->conn_cont); - SETUP_CONN_RD_ATTR(max_recv_dlength, ISCSI_MAX_RECV_DLENGTH); - SETUP_CONN_RD_ATTR(max_xmit_dlength, ISCSI_MAX_XMIT_DLENGTH); - SETUP_CONN_RD_ATTR(header_digest, ISCSI_HDRDGST_EN); - SETUP_CONN_RD_ATTR(data_digest, ISCSI_DATADGST_EN); - SETUP_CONN_RD_ATTR(ifmarker, ISCSI_IFMARKER_EN); - SETUP_CONN_RD_ATTR(ofmarker, ISCSI_OFMARKER_EN); - SETUP_CONN_RD_ATTR(address, ISCSI_CONN_ADDRESS); - SETUP_CONN_RD_ATTR(port, ISCSI_CONN_PORT); - SETUP_CONN_RD_ATTR(exp_statsn, ISCSI_EXP_STATSN); - - if (tt->param_mask & ISCSI_PERSISTENT_ADDRESS) - SETUP_CONN_RD_ATTR(persistent_address, ISCSI_PERSISTENT_ADDRESS); - else - SETUP_PRIV_CONN_RD_ATTR(persistent_address); - - if (tt->param_mask & ISCSI_PERSISTENT_PORT) - SETUP_CONN_RD_ATTR(persistent_port, ISCSI_PERSISTENT_PORT); - else - SETUP_PRIV_CONN_RD_ATTR(persistent_port); + SETUP_CONN_RD_ATTR(max_recv_dlength, ISCSI_PARAM_MAX_RECV_DLENGTH); + SETUP_CONN_RD_ATTR(max_xmit_dlength, ISCSI_PARAM_MAX_XMIT_DLENGTH); + SETUP_CONN_RD_ATTR(header_digest, ISCSI_PARAM_HDRDGST_EN); + SETUP_CONN_RD_ATTR(data_digest, ISCSI_PARAM_DATADGST_EN); + SETUP_CONN_RD_ATTR(ifmarker, ISCSI_PARAM_IFMARKER_EN); + SETUP_CONN_RD_ATTR(ofmarker, ISCSI_PARAM_OFMARKER_EN); BUG_ON(count > ISCSI_CONN_ATTRS); priv->conn_attrs[count] = NULL; @@ -1445,25 +1169,14 @@ iscsi_register_transport(struct iscsi_transport *tt) priv->session_cont.ac.match = iscsi_session_match; transport_container_register(&priv->session_cont); - SETUP_SESSION_RD_ATTR(initial_r2t, ISCSI_INITIAL_R2T_EN); - SETUP_SESSION_RD_ATTR(max_outstanding_r2t, ISCSI_MAX_R2T); - SETUP_SESSION_RD_ATTR(immediate_data, ISCSI_IMM_DATA_EN); - SETUP_SESSION_RD_ATTR(first_burst_len, ISCSI_FIRST_BURST); - SETUP_SESSION_RD_ATTR(max_burst_len, ISCSI_MAX_BURST); - SETUP_SESSION_RD_ATTR(data_pdu_in_order, ISCSI_PDU_INORDER_EN); - SETUP_SESSION_RD_ATTR(data_seq_in_order, ISCSI_DATASEQ_INORDER_EN); - SETUP_SESSION_RD_ATTR(erl, ISCSI_ERL); - SETUP_PRIV_SESSION_RD_ATTR(recovery_tmo); - - if (tt->param_mask & ISCSI_TARGET_NAME) - SETUP_SESSION_RD_ATTR(targetname, ISCSI_TARGET_NAME); - else - SETUP_PRIV_SESSION_RD_ATTR(targetname); - - if (tt->param_mask & ISCSI_TPGT) - SETUP_SESSION_RD_ATTR(tpgt, ISCSI_TPGT); - else - SETUP_PRIV_SESSION_RD_ATTR(tpgt); + SETUP_SESSION_RD_ATTR(initial_r2t, ISCSI_PARAM_INITIAL_R2T_EN); + SETUP_SESSION_RD_ATTR(max_outstanding_r2t, ISCSI_PARAM_MAX_R2T); + SETUP_SESSION_RD_ATTR(immediate_data, ISCSI_PARAM_IMM_DATA_EN); + SETUP_SESSION_RD_ATTR(first_burst_len, ISCSI_PARAM_FIRST_BURST); + SETUP_SESSION_RD_ATTR(max_burst_len, ISCSI_PARAM_MAX_BURST); + SETUP_SESSION_RD_ATTR(data_pdu_in_order, ISCSI_PARAM_PDU_INORDER_EN); + SETUP_SESSION_RD_ATTR(data_seq_in_order,ISCSI_PARAM_DATASEQ_INORDER_EN) + SETUP_SESSION_RD_ATTR(erl, ISCSI_PARAM_ERL); BUG_ON(count > ISCSI_SESSION_ATTRS); priv->session_attrs[count] = NULL; @@ -1501,7 +1214,6 @@ int iscsi_unregister_transport(struct iscsi_transport *tt) transport_container_unregister(&priv->conn_cont); transport_container_unregister(&priv->session_cont); - transport_container_unregister(&priv->t.host_attrs); sysfs_remove_group(&priv->cdev.kobj, &iscsi_transport_group); class_device_unregister(&priv->cdev); @@ -1545,13 +1257,9 @@ static __init int iscsi_transport_init(void) if (err) return err; - err = transport_class_register(&iscsi_host_class); - if (err) - goto unregister_transport_class; - err = transport_class_register(&iscsi_connection_class); if (err) - goto unregister_host_class; + goto unregister_transport_class; err = transport_class_register(&iscsi_session_class); if (err) @@ -1580,8 +1288,6 @@ unregister_session_class: transport_class_unregister(&iscsi_session_class); unregister_conn_class: transport_class_unregister(&iscsi_connection_class); -unregister_host_class: - transport_class_unregister(&iscsi_host_class); unregister_transport_class: class_unregister(&iscsi_transport_class); return err; @@ -1594,7 +1300,6 @@ static void __exit iscsi_transport_exit(void) netlink_unregister_notifier(&iscsi_nl_notifier); transport_class_unregister(&iscsi_connection_class); transport_class_unregister(&iscsi_session_class); - transport_class_unregister(&iscsi_host_class); class_unregister(&iscsi_transport_class); } diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index fbb53adee..968597781 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c @@ -7,6 +7,9 @@ * * Copyright (C) 2001 Russell King. * + * 2005/09/16: Enabled higher baud rates for 16C95x. + * (Mathias Adam ) + * * 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 @@ -1745,6 +1748,14 @@ static unsigned int serial8250_get_divisor(struct uart_port *port, unsigned int else if ((port->flags & UPF_MAGIC_MULTIPLIER) && baud == (port->uartclk/8)) quot = 0x8002; + /* + * For 16C950s UART_TCR is used in combination with divisor==1 + * to achieve baud rates up to baud_base*4. + */ + else if ((port->type == PORT_16C950) && + baud > (port->uartclk/16)) + quot = 1; + else quot = uart_get_divisor(port, baud); @@ -1758,7 +1769,7 @@ serial8250_set_termios(struct uart_port *port, struct termios *termios, struct uart_8250_port *up = (struct uart_8250_port *)port; unsigned char cval, fcr = 0; unsigned long flags; - unsigned int baud, quot; + unsigned int baud, quot, max_baud; switch (termios->c_cflag & CSIZE) { case CS5: @@ -1790,7 +1801,8 @@ serial8250_set_termios(struct uart_port *port, struct termios *termios, /* * Ask the core to calculate the divisor for us. */ - baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); + max_baud = (up->port.type == PORT_16C950 ? port->uartclk/4 : port->uartclk/16); + baud = uart_get_baud_rate(port, termios, old, 0, max_baud); quot = serial8250_get_divisor(port, baud); /* @@ -1826,6 +1838,19 @@ serial8250_set_termios(struct uart_port *port, struct termios *termios, */ spin_lock_irqsave(&up->port.lock, flags); + /* + * 16C950 supports additional prescaler ratios between 1:16 and 1:4 + * thus increasing max baud rate to uartclk/4. + */ + if (up->port.type == PORT_16C950) { + if (baud == port->uartclk/4) + serial_icr_write(up, UART_TCR, 0x4); + else if (baud == port->uartclk/8) + serial_icr_write(up, UART_TCR, 0x8); + else + serial_icr_write(up, UART_TCR, 0); + } + /* * Update the per-port timeout. */ @@ -2243,10 +2268,14 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count) touch_nmi_watchdog(); - if (oops_in_progress) { - locked = spin_trylock_irqsave(&up->port.lock, flags); + local_irq_save(flags); + if (up->port.sysrq) { + /* serial8250_handle_port() already took the lock */ + locked = 0; + } else if (oops_in_progress) { + locked = spin_trylock(&up->port.lock); } else - spin_lock_irqsave(&up->port.lock, flags); + spin_lock(&up->port.lock); /* * First save the IER then disable the interrupts @@ -2268,7 +2297,8 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count) serial_out(up, UART_IER, ier); if (locked) - spin_unlock_irqrestore(&up->port.lock, flags); + spin_unlock(&up->port.lock); + local_irq_restore(flags); } static int serial8250_console_setup(struct console *co, char *options) diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 7d22dc047..d2716173d 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -11,6 +11,7 @@ menu "Serial drivers" config SERIAL_8250 tristate "8250/16550 and compatible serial support" depends on (BROKEN || !SPARC) + depends on !XEN_DISABLE_SERIAL select SERIAL_CORE ---help--- This selects whether you want to include the driver for the standard @@ -803,6 +804,7 @@ config SERIAL_MPC52xx tristate "Freescale MPC52xx family PSC serial support" depends on PPC_MPC52xx select SERIAL_CORE + select FW_LOADER help This drivers support the MPC52xx PSC serial ports. If you would like to use them, you must answer Y or M to this option. Not that diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c index 7abe532d7..17839e753 100644 --- a/drivers/serial/serial_core.c +++ b/drivers/serial/serial_core.c @@ -1968,16 +1968,16 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *port) struct termios termios; /* - * Get the termios for this line + * First try to use the console cflag setting. */ - tty_get_termios(drv->tty_driver, port->line, &termios); + memset(&termios, 0, sizeof(struct termios)); + termios.c_cflag = port->cons->cflag; /* - * If the console cflag is still set, subsitute that - * for the termios cflag. + * If that's unset, use the tty termios setting. */ - if (port->cons->cflag) - termios.c_cflag = port->cons->cflag; + if (state->info && state->info->tty && termios.c_cflag == 0) + termios = *state->info->tty->termios; port->ops->set_termios(port, &termios, NULL); console_start(port->cons); diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c index a06d84c19..5f44354c4 100644 --- a/drivers/usb/host/uhci-q.c +++ b/drivers/usb/host/uhci-q.c @@ -264,7 +264,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.next, struct uhci_td, + td = list_entry(urbp->td_list.prev, struct uhci_td, list); toggle = uhci_toggle(td_token(td)) ^ 1; @@ -896,12 +896,14 @@ static int uhci_result_common(struct uhci_hcd *uhci, struct urb *urb) /* * This URB stopped short of its end. We have to * fix up the toggles of the following URBs on the - * queue and restart the queue. + * queue and restart the queue. But only if this + * TD isn't the last one in the URB. * * Do this only the first time we encounter the * short URB. */ - if (!urbp->short_transfer) { + if (!urbp->short_transfer && + &td->list != urbp->td_list.prev) { urbp->short_transfer = 1; urbp->qh->initial_toggle = uhci_toggle(td_token(td)) ^ 1; diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 986d76222..ad9ddecf1 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -553,6 +553,10 @@ struct ftdi_private { int force_baud; /* if non-zero, force the baud rate to this value */ int force_rtscts; /* if non-zero, force RTS-CTS to always be enabled */ + + spinlock_t tx_lock; /* spinlock for transmit state */ + unsigned long tx_outstanding_bytes; + unsigned long tx_outstanding_urbs; }; /* Used for TIOCMIWAIT */ @@ -626,6 +630,9 @@ static struct usb_serial_driver ftdi_sio_device = { #define HIGH 1 #define LOW 0 +/* number of outstanding urbs to prevent userspace DoS from happening */ +#define URB_UPPER_LIMIT 42 + /* * *************************************************************************** * Utlity functions @@ -1156,6 +1163,7 @@ static int ftdi_sio_attach (struct usb_serial *serial) } spin_lock_init(&priv->rx_lock); + spin_lock_init(&priv->tx_lock); init_waitqueue_head(&priv->delta_msr_wait); /* This will push the characters through immediately rather than queue a task to deliver them */ @@ -1372,6 +1380,7 @@ static int ftdi_write (struct usb_serial_port *port, int data_offset ; /* will be 1 for the SIO and 0 otherwise */ int status; int transfer_size; + unsigned long flags; dbg("%s port %d, %d bytes", __FUNCTION__, port->number, count); @@ -1379,6 +1388,13 @@ static int ftdi_write (struct usb_serial_port *port, dbg("write request of 0 bytes"); return 0; } + spin_lock_irqsave(&priv->tx_lock, flags); + if (priv->tx_outstanding_urbs > URB_UPPER_LIMIT) { + spin_unlock_irqrestore(&priv->tx_lock, flags); + dbg("%s - write limit hit\n", __FUNCTION__); + return 0; + } + spin_unlock_irqrestore(&priv->tx_lock, flags); data_offset = priv->write_offset; dbg("data_offset set to %d",data_offset); @@ -1445,6 +1461,11 @@ static int ftdi_write (struct usb_serial_port *port, err("%s - failed submitting write urb, error %d", __FUNCTION__, status); count = status; kfree (buffer); + } else { + spin_lock_irqsave(&priv->tx_lock, flags); + ++priv->tx_outstanding_urbs; + priv->tx_outstanding_bytes += count; + spin_unlock_irqrestore(&priv->tx_lock, flags); } /* we are done with this urb, so let the host driver @@ -1460,7 +1481,11 @@ static int ftdi_write (struct usb_serial_port *port, static void ftdi_write_bulk_callback (struct urb *urb, struct pt_regs *regs) { + unsigned long flags; struct usb_serial_port *port = (struct usb_serial_port *)urb->context; + struct ftdi_private *priv; + int data_offset; /* will be 1 for the SIO and 0 otherwise */ + unsigned long countback; /* free up the transfer buffer, as usb_free_urb() does not do this */ kfree (urb->transfer_buffer); @@ -1472,34 +1497,67 @@ static void ftdi_write_bulk_callback (struct urb *urb, struct pt_regs *regs) return; } + priv = usb_get_serial_port_data(port); + if (!priv) { + dbg("%s - bad port private data pointer - exiting", __FUNCTION__); + return; + } + /* account for transferred data */ + countback = urb->actual_length; + data_offset = priv->write_offset; + if (data_offset > 0) { + /* Subtract the control bytes */ + countback -= (data_offset * ((countback + (PKTSZ - 1)) / PKTSZ)); + } + spin_lock_irqsave(&priv->tx_lock, flags); + --priv->tx_outstanding_urbs; + priv->tx_outstanding_bytes -= countback; + spin_unlock_irqrestore(&priv->tx_lock, flags); + schedule_work(&port->work); } /* ftdi_write_bulk_callback */ static int ftdi_write_room( struct usb_serial_port *port ) { + struct ftdi_private *priv = usb_get_serial_port_data(port); + int room; + unsigned long flags; + dbg("%s - port %d", __FUNCTION__, port->number); - /* - * We really can take anything the user throws at us - * but let's pick a nice big number to tell the tty - * layer that we have lots of free space - */ - return 2048; + spin_lock_irqsave(&priv->tx_lock, flags); + if (priv->tx_outstanding_urbs < URB_UPPER_LIMIT) { + /* + * We really can take anything the user throws at us + * but let's pick a nice big number to tell the tty + * layer that we have lots of free space + */ + room = 2048; + } else { + room = 0; + } + spin_unlock_irqrestore(&priv->tx_lock, flags); + return room; } /* ftdi_write_room */ static int ftdi_chars_in_buffer (struct usb_serial_port *port) { /* ftdi_chars_in_buffer */ + struct ftdi_private *priv = usb_get_serial_port_data(port); + int buffered; + unsigned long flags; + dbg("%s - port %d", __FUNCTION__, port->number); - /* - * We can't really account for how much data we - * have sent out, but hasn't made it through to the - * device, so just tell the tty layer that everything - * is flushed. - */ - return 0; + spin_lock_irqsave(&priv->tx_lock, flags); + buffered = (int)priv->tx_outstanding_bytes; + spin_unlock_irqrestore(&priv->tx_lock, flags); + if (buffered < 0) { + err("%s outstanding tx bytes is negative!", __FUNCTION__); + buffered = 0; + } + return buffered; } /* ftdi_chars_in_buffer */ diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 2de6528aa..a1a83029c 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -113,6 +113,12 @@ UNUSUAL_DEV( 0x0411, 0x001c, 0x0113, 0x0113, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_FIX_INQUIRY ), +/* Reported by Orgad Shaneh */ +UNUSUAL_DEV( 0x0419, 0xaace, 0x0100, 0x0100, + "Samsung", "MP3 Player", + US_SC_DEVICE, US_PR_DEVICE, NULL, + US_FL_IGNORE_RESIDUE), + /* Reported by Christian Leber */ UNUSUAL_DEV( 0x0419, 0xaaf5, 0x0100, 0x0100, "TrekStor", @@ -133,12 +139,6 @@ UNUSUAL_DEV( 0x0420, 0x0001, 0x0100, 0x0100, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_IGNORE_RESIDUE ), -/* Reported by Pete Zaitcev , bz#176584 */ -UNUSUAL_DEV( 0x0420, 0x0001, 0x0100, 0x0100, - "GENERIC", "MP3 PLAYER", /* MyMusix PD-205 on the outside. */ - US_SC_DEVICE, US_PR_DEVICE, NULL, - US_FL_IGNORE_RESIDUE ), - /* Reported by Olaf Hering from novell bug #105878 */ UNUSUAL_DEV( 0x0424, 0x0fdc, 0x0210, 0x0210, "SMSC", diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index dd1086343..0142fe82f 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c @@ -593,6 +593,15 @@ static int get_transport(struct us_data *us) break; #endif +#ifdef CONFIG_USB_STORAGE_ALAUDA + case US_PR_ALAUDA: + us->transport_name = "Alauda Control/Bulk"; + us->transport = alauda_transport; + us->transport_reset = usb_stor_Bulk_reset; + us->max_lun = 1; + break; +#endif + default: return -EIO; } @@ -648,15 +657,6 @@ static int get_protocol(struct us_data *us) break; #endif -#ifdef CONFIG_USB_STORAGE_ALAUDA - case US_PR_ALAUDA: - us->transport_name = "Alauda Control/Bulk"; - us->transport = alauda_transport; - us->transport_reset = usb_stor_Bulk_reset; - us->max_lun = 1; - break; -#endif - default: return -EIO; } diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 4587087d7..2fd9ab7f4 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -513,7 +513,7 @@ config FB_HGA_ACCEL config VIDEO_SELECT bool - depends on (FB = y) && X86 + depends on (FB = y) && X86 && !XEN default y config FB_SGIVW diff --git a/drivers/video/console/softcursor.c b/drivers/video/console/softcursor.c index 0a2ed2fd3..2ade75291 100644 --- a/drivers/video/console/softcursor.c +++ b/drivers/video/console/softcursor.c @@ -27,7 +27,7 @@ int soft_cursor(struct fb_info *info, struct fb_cursor *cursor) struct fb_image *image; u8 *dst; static u8 *src=NULL; - static int allocsize=0; + static int allocsize = 0; if (info->state != FBINFO_STATE_RUNNING) return 0; @@ -41,8 +41,10 @@ int soft_cursor(struct fb_info *info, struct fb_cursor *cursor) allocsize = dsize + sizeof(struct fb_image); src = kmalloc(allocsize, GFP_ATOMIC); - if (!src) + if (!src) { + allocsize = 0; return -ENOMEM; + } } image = (struct fb_image *) (src + dsize); diff --git a/drivers/xen/Makefile b/drivers/xen/Makefile index 7bb479830..79eddeec1 100644 --- a/drivers/xen/Makefile +++ b/drivers/xen/Makefile @@ -1,13 +1,17 @@ - - +obj-y += core/ obj-y += console/ obj-y += evtchn/ -obj-y += balloon/ +obj-y += privcmd/ +obj-y += xenbus/ -obj-$(CONFIG_XEN_PRIVILEGED_GUEST) += privcmd/ +obj-$(CONFIG_XEN_UTIL) += util.o +obj-$(CONFIG_XEN_BALLOON) += balloon/ +obj-$(CONFIG_XEN_DEVMEM) += char/ obj-$(CONFIG_XEN_BLKDEV_BACKEND) += blkback/ +obj-$(CONFIG_XEN_BLKDEV_TAP) += blktap/ obj-$(CONFIG_XEN_NETDEV_BACKEND) += netback/ +obj-$(CONFIG_XEN_TPMDEV_BACKEND) += tpmback/ obj-$(CONFIG_XEN_BLKDEV_FRONTEND) += blkfront/ obj-$(CONFIG_XEN_NETDEV_FRONTEND) += netfront/ -obj-$(CONFIG_XEN_BLKDEV_TAP) += blktap/ - +obj-$(CONFIG_XEN_PCIDEV_BACKEND) += pciback/ +obj-$(CONFIG_XEN_PCIDEV_FRONTEND) += pcifront/ diff --git a/drivers/xen/balloon/balloon.c b/drivers/xen/balloon/balloon.c index 649f64c40..322675334 100644 --- a/drivers/xen/balloon/balloon.c +++ b/drivers/xen/balloon/balloon.c @@ -5,9 +5,13 @@ * * Copyright (c) 2003, B Dragovic * Copyright (c) 2003-2004, M Williamson, K Fraser + * Copyright (c) 2005 Dan M. Smith, IBM Corporation * - * This file may be distributed separately from the Linux kernel, or - * incorporated into other software packages, subject to the following license: + * 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; or, when distributed + * separately from the Linux kernel or incorporated into other + * software packages, subject to the following license: * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this source file (the "Software"), to deal in the Software without @@ -40,25 +44,43 @@ #include #include #include -#include -#include -#include -#include +#include +#include +#include +#include #include #include #include #include #include +#include + +#define PAGES2KB(_p) ((_p)<<(PAGE_SHIFT-10)) + +#ifdef CONFIG_PROC_FS static struct proc_dir_entry *balloon_pde; +#endif static DECLARE_MUTEX(balloon_mutex); -spinlock_t balloon_lock = SPIN_LOCK_UNLOCKED; + +/* + * Protects atomic reservation decrease/increase against concurrent increases. + * Also protects non-atomic updates of current_pages and driver_pages, and + * balloon lists. + */ +DEFINE_SPINLOCK(balloon_lock); /* We aim for 'current allocation' == 'target allocation'. */ static unsigned long current_pages; static unsigned long target_pages; +/* We increase/decrease in batches which fit in a page */ +static unsigned long frame_list[PAGE_SIZE / sizeof(unsigned long)]; + +/* VM /proc information for memory */ +extern unsigned long totalram_pages; + /* We may hit the hard limit in Xen. If we do then we remember it. */ static unsigned long hard_limit; @@ -77,79 +99,230 @@ static void balloon_process(void *unused); static DECLARE_WORK(balloon_worker, balloon_process, NULL); static struct timer_list balloon_timer; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) -/* Use the private and mapping fields of struct page as a list. */ -#define PAGE_TO_LIST(p) ( (struct list_head *)&p->private ) -#define LIST_TO_PAGE(l) ( list_entry( ((unsigned long *)l), \ - struct page, private ) ) -#define UNLIST_PAGE(p) do { list_del(PAGE_TO_LIST(p)); \ - p->mapping = NULL; \ - p->private = 0; } while(0) -#else -/* There's a dedicated list field in struct page we can use. */ -#define PAGE_TO_LIST(p) ( &p->list ) -#define LIST_TO_PAGE(l) ( list_entry(l, struct page, list) ) -#define UNLIST_PAGE(p) ( list_del(&p->list) ) -#define pte_offset_kernel pte_offset -#define pud_t pgd_t -#define pud_offset(d, va) d -#define pud_none(d) 0 -#define pud_bad(d) 0 -#define subsys_initcall(_fn) __initcall(_fn) -#define pfn_to_page(_pfn) (mem_map + (_pfn)) -#endif +/* When ballooning out (allocating memory to return to Xen) we don't really + want the kernel to try too hard since that can trigger the oom killer. */ +#define GFP_BALLOON \ + (GFP_HIGHUSER | __GFP_NOWARN | __GFP_NORETRY | __GFP_NOMEMALLOC) + +#define PAGE_TO_LIST(p) (&(p)->lru) +#define LIST_TO_PAGE(l) list_entry((l), struct page, lru) +#define UNLIST_PAGE(p) \ + do { \ + list_del(PAGE_TO_LIST(p)); \ + PAGE_TO_LIST(p)->next = NULL; \ + PAGE_TO_LIST(p)->prev = NULL; \ + } while(0) #define IPRINTK(fmt, args...) \ - printk(KERN_INFO "xen_mem: " fmt, ##args) + printk(KERN_INFO "xen_mem: " fmt, ##args) #define WPRINTK(fmt, args...) \ - printk(KERN_WARNING "xen_mem: " fmt, ##args) + printk(KERN_WARNING "xen_mem: " fmt, ##args) /* balloon_append: add the given page to the balloon. */ static void balloon_append(struct page *page) { - /* Low memory is re-populated first, so highmem pages go at list tail. */ - if ( PageHighMem(page) ) - { - list_add_tail(PAGE_TO_LIST(page), &ballooned_pages); - balloon_high++; - } - else - { - list_add(PAGE_TO_LIST(page), &ballooned_pages); - balloon_low++; - } + /* Lowmem is re-populated first, so highmem pages go at list tail. */ + if (PageHighMem(page)) { + list_add_tail(PAGE_TO_LIST(page), &ballooned_pages); + balloon_high++; + } else { + list_add(PAGE_TO_LIST(page), &ballooned_pages); + balloon_low++; + } } /* balloon_retrieve: rescue a page from the balloon, if it is not empty. */ static struct page *balloon_retrieve(void) { - struct page *page; + struct page *page; + + if (list_empty(&ballooned_pages)) + return NULL; + + page = LIST_TO_PAGE(ballooned_pages.next); + UNLIST_PAGE(page); - if ( list_empty(&ballooned_pages) ) - return NULL; + if (PageHighMem(page)) + balloon_high--; + else + balloon_low--; - page = LIST_TO_PAGE(ballooned_pages.next); - UNLIST_PAGE(page); + return page; +} - if ( PageHighMem(page) ) - balloon_high--; - else - balloon_low--; +static struct page *balloon_first_page(void) +{ + if (list_empty(&ballooned_pages)) + return NULL; + return LIST_TO_PAGE(ballooned_pages.next); +} - return page; +static struct page *balloon_next_page(struct page *page) +{ + struct list_head *next = PAGE_TO_LIST(page)->next; + if (next == &ballooned_pages) + return NULL; + return LIST_TO_PAGE(next); } static void balloon_alarm(unsigned long unused) { - schedule_work(&balloon_worker); + schedule_work(&balloon_worker); } static unsigned long current_target(void) { - unsigned long target = min(target_pages, hard_limit); - if ( target > (current_pages + balloon_low + balloon_high) ) - target = current_pages + balloon_low + balloon_high; - return target; + unsigned long target = min(target_pages, hard_limit); + if (target > (current_pages + balloon_low + balloon_high)) + target = current_pages + balloon_low + balloon_high; + return target; +} + +static int increase_reservation(unsigned long nr_pages) +{ + unsigned long pfn, i, flags; + struct page *page; + long rc; + struct xen_memory_reservation reservation = { + .address_bits = 0, + .extent_order = 0, + .domid = DOMID_SELF + }; + + if (nr_pages > ARRAY_SIZE(frame_list)) + nr_pages = ARRAY_SIZE(frame_list); + + balloon_lock(flags); + + page = balloon_first_page(); + for (i = 0; i < nr_pages; i++) { + BUG_ON(page == NULL); + frame_list[i] = page_to_pfn(page);; + page = balloon_next_page(page); + } + + set_xen_guest_handle(reservation.extent_start, frame_list); + reservation.nr_extents = nr_pages; + rc = HYPERVISOR_memory_op( + XENMEM_populate_physmap, &reservation); + if (rc < nr_pages) { + if (rc > 0) { + int ret; + + /* We hit the Xen hard limit: reprobe. */ + reservation.nr_extents = rc; + ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation, + &reservation); + BUG_ON(ret != rc); + } + if (rc >= 0) + hard_limit = current_pages + rc - driver_pages; + goto out; + } + + for (i = 0; i < nr_pages; i++) { + page = balloon_retrieve(); + BUG_ON(page == NULL); + + pfn = page_to_pfn(page); + BUG_ON(!xen_feature(XENFEAT_auto_translated_physmap) && + phys_to_machine_mapping_valid(pfn)); + + /* Update P->M and M->P tables. */ + set_phys_to_machine(pfn, frame_list[i]); + xen_machphys_update(frame_list[i], pfn); + + /* Link back into the page tables if not highmem. */ + if (pfn < max_low_pfn) { + int ret; + ret = HYPERVISOR_update_va_mapping( + (unsigned long)__va(pfn << PAGE_SHIFT), + pfn_pte_ma(frame_list[i], PAGE_KERNEL), + 0); + BUG_ON(ret); + } + + /* Relinquish the page back to the allocator. */ + ClearPageReserved(page); + init_page_count(page); + __free_page(page); + } + + current_pages += nr_pages; + totalram_pages = current_pages; + + out: + balloon_unlock(flags); + + return 0; +} + +static int decrease_reservation(unsigned long nr_pages) +{ + unsigned long pfn, i, flags; + struct page *page; + void *v; + int need_sleep = 0; + int ret; + struct xen_memory_reservation reservation = { + .address_bits = 0, + .extent_order = 0, + .domid = DOMID_SELF + }; + + if (nr_pages > ARRAY_SIZE(frame_list)) + nr_pages = ARRAY_SIZE(frame_list); + + for (i = 0; i < nr_pages; i++) { + if ((page = alloc_page(GFP_BALLOON)) == NULL) { + nr_pages = i; + need_sleep = 1; + break; + } + + pfn = page_to_pfn(page); + frame_list[i] = pfn_to_mfn(pfn); + + if (!PageHighMem(page)) { + v = phys_to_virt(pfn << PAGE_SHIFT); + scrub_pages(v, 1); + ret = HYPERVISOR_update_va_mapping( + (unsigned long)v, __pte_ma(0), 0); + BUG_ON(ret); + } +#ifdef CONFIG_XEN_SCRUB_PAGES + else { + v = kmap(page); + scrub_pages(v, 1); + kunmap(page); + } +#endif + } + + /* Ensure that ballooned highmem pages don't have kmaps. */ + kmap_flush_unused(); + flush_tlb_all(); + + balloon_lock(flags); + + /* No more mappings: invalidate P2M and add to balloon. */ + for (i = 0; i < nr_pages; i++) { + pfn = mfn_to_pfn(frame_list[i]); + set_phys_to_machine(pfn, INVALID_P2M_ENTRY); + balloon_append(pfn_to_page(pfn)); + } + + set_xen_guest_handle(reservation.extent_start, frame_list); + reservation.nr_extents = nr_pages; + ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation, &reservation); + BUG_ON(ret != nr_pages); + + current_pages -= nr_pages; + totalram_pages = current_pages; + + balloon_unlock(flags); + + return need_sleep; } /* @@ -160,279 +333,285 @@ static unsigned long current_target(void) */ static void balloon_process(void *unused) { - unsigned long *mfn_list, pfn, i, flags; - struct page *page; - long credit, debt, rc; - void *v; - - down(&balloon_mutex); - - retry: - mfn_list = NULL; - - if ( (credit = current_target() - current_pages) > 0 ) - { - mfn_list = (unsigned long *)vmalloc(credit * sizeof(*mfn_list)); - if ( mfn_list == NULL ) - goto out; - - balloon_lock(flags); - rc = HYPERVISOR_dom_mem_op( - MEMOP_increase_reservation, mfn_list, credit, 0); - balloon_unlock(flags); - if ( rc < credit ) - { - /* We hit the Xen hard limit: reprobe. */ - if ( HYPERVISOR_dom_mem_op( - MEMOP_decrease_reservation, mfn_list, rc, 0) != rc ) - BUG(); - hard_limit = current_pages + rc - driver_pages; - vfree(mfn_list); - goto retry; - } - - for ( i = 0; i < credit; i++ ) - { - if ( (page = balloon_retrieve()) == NULL ) - BUG(); - - pfn = page - mem_map; - if ( phys_to_machine_mapping[pfn] != INVALID_P2M_ENTRY ) - BUG(); - - /* Update P->M and M->P tables. */ - phys_to_machine_mapping[pfn] = mfn_list[i]; - xen_machphys_update(mfn_list[i], pfn); - - /* Link back into the page tables if it's not a highmem page. */ - if ( pfn < max_low_pfn ) - { - HYPERVISOR_update_va_mapping( - (unsigned long)__va(pfn << PAGE_SHIFT), - __pte_ma((mfn_list[i] << PAGE_SHIFT) | - pgprot_val(PAGE_KERNEL)), - 0); - } - - /* Finally, relinquish the memory back to the system allocator. */ - ClearPageReserved(page); - set_page_count(page, 1); - __free_page(page); - } - - current_pages += credit; - } - else if ( credit < 0 ) - { - debt = -credit; - - mfn_list = (unsigned long *)vmalloc(debt * sizeof(*mfn_list)); - if ( mfn_list == NULL ) - goto out; - - for ( i = 0; i < debt; i++ ) - { - if ( (page = alloc_page(GFP_HIGHUSER)) == NULL ) - { - debt = i; - break; - } - - pfn = page - mem_map; - mfn_list[i] = phys_to_machine_mapping[pfn]; - - if ( !PageHighMem(page) ) - { - v = phys_to_virt(pfn << PAGE_SHIFT); - scrub_pages(v, 1); - HYPERVISOR_update_va_mapping( - (unsigned long)v, __pte_ma(0), 0); - } -#ifdef CONFIG_XEN_SCRUB_PAGES - else - { - v = kmap(page); - scrub_pages(v, 1); - kunmap(page); - } -#endif - } + int need_sleep = 0; + long credit; - /* Ensure that ballooned highmem pages don't have cached mappings. */ - kmap_flush_unused(); - flush_tlb_all(); + down(&balloon_mutex); - /* No more mappings: invalidate pages in P2M and add to balloon. */ - for ( i = 0; i < debt; i++ ) - { - pfn = mfn_to_pfn(mfn_list[i]); - phys_to_machine_mapping[pfn] = INVALID_P2M_ENTRY; - balloon_append(pfn_to_page(pfn)); - } + do { + credit = current_target() - current_pages; + if (credit > 0) + need_sleep = (increase_reservation(credit) != 0); + if (credit < 0) + need_sleep = (decrease_reservation(-credit) != 0); - if ( HYPERVISOR_dom_mem_op( - MEMOP_decrease_reservation, mfn_list, debt, 0) != debt ) - BUG(); - - current_pages -= debt; - } - - out: - if ( mfn_list != NULL ) - vfree(mfn_list); +#ifndef CONFIG_PREEMPT + if (need_resched()) + schedule(); +#endif + } while ((credit != 0) && !need_sleep); - /* Schedule more work if there is some still to be done. */ - if ( current_target() != current_pages ) - mod_timer(&balloon_timer, jiffies + HZ); + /* Schedule more work if there is some still to be done. */ + if (current_target() != current_pages) + mod_timer(&balloon_timer, jiffies + HZ); - up(&balloon_mutex); + up(&balloon_mutex); } /* Resets the Xen limit, sets new target, and kicks off processing. */ static void set_new_target(unsigned long target) { - /* No need for lock. Not read-modify-write updates. */ - hard_limit = ~0UL; - target_pages = target; - schedule_work(&balloon_worker); + /* No need for lock. Not read-modify-write updates. */ + hard_limit = ~0UL; + target_pages = target; + schedule_work(&balloon_worker); } -static void balloon_ctrlif_rx(ctrl_msg_t *msg, unsigned long id) +static struct xenbus_watch target_watch = { - switch ( msg->subtype ) - { - case CMSG_MEM_REQUEST_SET: - { - mem_request_t *req = (mem_request_t *)&msg->msg[0]; - set_new_target(req->target); - req->status = 0; - } - break; - - default: - msg->length = 0; - break; - } - - ctrl_if_send_response(msg); + .node = "memory/target" +}; + +/* React to a change in the target key */ +static void watch_target(struct xenbus_watch *watch, + const char **vec, unsigned int len) +{ + unsigned long long new_target; + int err; + + err = xenbus_scanf(XBT_NIL, "memory", "target", "%llu", &new_target); + if (err != 1) { + /* This is ok (for domain0 at least) - so just return */ + return; + } + + /* The given memory/target value is in KiB, so it needs converting to + * pages. PAGE_SHIFT converts bytes to pages, hence PAGE_SHIFT - 10. + */ + set_new_target(new_target >> (PAGE_SHIFT - 10)); +} + +static int balloon_init_watcher(struct notifier_block *notifier, + unsigned long event, + void *data) +{ + int err; + + err = register_xenbus_watch(&target_watch); + if (err) + printk(KERN_ERR "Failed to set balloon watcher\n"); + + return NOTIFY_DONE; } +#ifdef CONFIG_PROC_FS static int balloon_write(struct file *file, const char __user *buffer, - unsigned long count, void *data) + unsigned long count, void *data) { - char memstring[64], *endchar; - unsigned long long target_bytes; + char memstring[64], *endchar; + unsigned long long target_bytes; - if ( !capable(CAP_SYS_ADMIN) ) - return -EPERM; + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; - if ( count <= 1 ) - return -EBADMSG; /* runt */ - if ( count > sizeof(memstring) ) - return -EFBIG; /* too long */ + if (count <= 1) + return -EBADMSG; /* runt */ + if (count > sizeof(memstring)) + return -EFBIG; /* too long */ - if ( copy_from_user(memstring, buffer, count) ) - return -EFAULT; - memstring[sizeof(memstring)-1] = '\0'; + if (copy_from_user(memstring, buffer, count)) + return -EFAULT; + memstring[sizeof(memstring)-1] = '\0'; - target_bytes = memparse(memstring, &endchar); - set_new_target(target_bytes >> PAGE_SHIFT); + target_bytes = memparse(memstring, &endchar); + set_new_target(target_bytes >> PAGE_SHIFT); - return count; + return count; } static int balloon_read(char *page, char **start, off_t off, - int count, int *eof, void *data) + int count, int *eof, void *data) { - int len; - -#define K(_p) ((_p)<<(PAGE_SHIFT-10)) - len = sprintf( - page, - "Current allocation: %8lu kB\n" - "Requested target: %8lu kB\n" - "Low-mem balloon: %8lu kB\n" - "High-mem balloon: %8lu kB\n" - "Xen hard limit: ", - K(current_pages), K(target_pages), K(balloon_low), K(balloon_high)); - - if ( hard_limit != ~0UL ) - len += sprintf( - page + len, - "%8lu kB (inc. %8lu kB driver headroom)\n", - K(hard_limit), K(driver_pages)); - else - len += sprintf( - page + len, - " ??? kB\n"); - - *eof = 1; - return len; + int len; + + len = sprintf( + page, + "Current allocation: %8lu kB\n" + "Requested target: %8lu kB\n" + "Low-mem balloon: %8lu kB\n" + "High-mem balloon: %8lu kB\n" + "Xen hard limit: ", + PAGES2KB(current_pages), PAGES2KB(target_pages), + PAGES2KB(balloon_low), PAGES2KB(balloon_high)); + + if (hard_limit != ~0UL) { + len += sprintf( + page + len, + "%8lu kB (inc. %8lu kB driver headroom)\n", + PAGES2KB(hard_limit), PAGES2KB(driver_pages)); + } else { + len += sprintf( + page + len, + " ??? kB\n"); + } + + *eof = 1; + return len; } +#endif + +static struct notifier_block xenstore_notifier; static int __init balloon_init(void) { - unsigned long pfn; - struct page *page; + unsigned long pfn; + struct page *page; + + if (!is_running_on_xen()) + return -ENODEV; + + IPRINTK("Initialising balloon driver.\n"); + + current_pages = min(xen_start_info->nr_pages, max_pfn); + totalram_pages = current_pages; + target_pages = current_pages; + balloon_low = 0; + balloon_high = 0; + driver_pages = 0UL; + hard_limit = ~0UL; - IPRINTK("Initialising balloon driver.\n"); + init_timer(&balloon_timer); + balloon_timer.data = 0; + balloon_timer.function = balloon_alarm; + +#ifdef CONFIG_PROC_FS + if ((balloon_pde = create_xen_proc_entry("balloon", 0644)) == NULL) { + WPRINTK("Unable to create /proc/xen/balloon.\n"); + return -1; + } + + balloon_pde->read_proc = balloon_read; + balloon_pde->write_proc = balloon_write; +#endif + + /* Initialise the balloon with excess memory space. */ + for (pfn = xen_start_info->nr_pages; pfn < max_pfn; pfn++) { + page = pfn_to_page(pfn); + if (!PageReserved(page)) + balloon_append(page); + } - current_pages = min(xen_start_info.nr_pages, max_pfn); - target_pages = current_pages; - balloon_low = 0; - balloon_high = 0; - driver_pages = 0UL; - hard_limit = ~0UL; + target_watch.callback = watch_target; + xenstore_notifier.notifier_call = balloon_init_watcher; - init_timer(&balloon_timer); - balloon_timer.data = 0; - balloon_timer.function = balloon_alarm; + register_xenstore_notifier(&xenstore_notifier); - if ( (balloon_pde = create_xen_proc_entry("balloon", 0644)) == NULL ) - { - WPRINTK("Unable to create /proc/xen/balloon.\n"); - return -1; - } - - balloon_pde->read_proc = balloon_read; - balloon_pde->write_proc = balloon_write; - - (void)ctrl_if_register_receiver(CMSG_MEM_REQUEST, balloon_ctrlif_rx, 0); - - /* Initialise the balloon with excess memory space. */ - for ( pfn = xen_start_info.nr_pages; pfn < max_pfn; pfn++ ) - { - page = &mem_map[pfn]; - if ( !PageReserved(page) ) - balloon_append(page); - } - - return 0; + return 0; } subsys_initcall(balloon_init); void balloon_update_driver_allowance(long delta) { - unsigned long flags; - balloon_lock(flags); - driver_pages += delta; /* non-atomic update */ - balloon_unlock(flags); + unsigned long flags; + + balloon_lock(flags); + driver_pages += delta; + balloon_unlock(flags); } -void balloon_put_pages(unsigned long *mfn_list, unsigned long nr_mfns) +static int dealloc_pte_fn( + pte_t *pte, struct page *pmd_page, unsigned long addr, void *data) { - unsigned long flags; + unsigned long mfn = pte_mfn(*pte); + int ret; + struct xen_memory_reservation reservation = { + .nr_extents = 1, + .extent_order = 0, + .domid = DOMID_SELF + }; + set_xen_guest_handle(reservation.extent_start, &mfn); + set_pte_at(&init_mm, addr, pte, __pte_ma(0)); + set_phys_to_machine(__pa(addr) >> PAGE_SHIFT, INVALID_P2M_ENTRY); + ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation, &reservation); + BUG_ON(ret != 1); + return 0; +} - balloon_lock(flags); - if ( HYPERVISOR_dom_mem_op(MEMOP_decrease_reservation, - mfn_list, nr_mfns, 0) != nr_mfns ) - BUG(); - current_pages -= nr_mfns; /* non-atomic update */ - balloon_unlock(flags); +struct page *balloon_alloc_empty_page_range(unsigned long nr_pages) +{ + unsigned long vstart, flags; + unsigned int order = get_order(nr_pages * PAGE_SIZE); + int ret; + unsigned long i; + struct page *page; + + vstart = __get_free_pages(GFP_KERNEL, order); + if (vstart == 0) + return NULL; + + scrub_pages(vstart, 1 << order); + + balloon_lock(flags); + if (xen_feature(XENFEAT_auto_translated_physmap)) { + unsigned long gmfn = __pa(vstart) >> PAGE_SHIFT; + struct xen_memory_reservation reservation = { + .nr_extents = 1, + .extent_order = order, + .domid = DOMID_SELF + }; + set_xen_guest_handle(reservation.extent_start, &gmfn); + ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation, + &reservation); + if (ret == -ENOSYS) + goto err; + BUG_ON(ret != 1); + } else { + ret = apply_to_page_range(&init_mm, vstart, PAGE_SIZE << order, + dealloc_pte_fn, NULL); + if (ret == -ENOSYS) + goto err; + BUG_ON(ret); + } + current_pages -= 1UL << order; + totalram_pages = current_pages; + balloon_unlock(flags); + + schedule_work(&balloon_worker); + + flush_tlb_all(); + + page = virt_to_page(vstart); + + for (i = 0; i < (1UL << order); i++) + init_page_count(page + i); + + return page; + + err: + free_pages(vstart, order); + balloon_unlock(flags); + return NULL; +} - schedule_work(&balloon_worker); +void balloon_dealloc_empty_page_range( + struct page *page, unsigned long nr_pages) +{ + unsigned long i, flags; + unsigned int order = get_order(nr_pages * PAGE_SIZE); + + balloon_lock(flags); + for (i = 0; i < (1UL << order); i++) { + BUG_ON(page_count(page + i) != 1); + balloon_append(page + i); + } + balloon_unlock(flags); + + schedule_work(&balloon_worker); } -EXPORT_SYMBOL(balloon_update_driver_allowance); -EXPORT_SYMBOL(balloon_put_pages); +EXPORT_SYMBOL_GPL(balloon_update_driver_allowance); +EXPORT_SYMBOL_GPL(balloon_alloc_empty_page_range); +EXPORT_SYMBOL_GPL(balloon_dealloc_empty_page_range); + +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/xen/blkback/Makefile b/drivers/xen/blkback/Makefile index a27fe65f4..8bab63da3 100644 --- a/drivers/xen/blkback/Makefile +++ b/drivers/xen/blkback/Makefile @@ -1,2 +1,3 @@ +obj-$(CONFIG_XEN_BLKDEV_BACKEND) := blkbk.o -obj-y := blkback.o control.o interface.o vbd.o +blkbk-y := blkback.o xenbus.o interface.o vbd.o diff --git a/drivers/xen/blkback/blkback.c b/drivers/xen/blkback/blkback.c index 2554f999d..c5b3eee0b 100644 --- a/drivers/xen/blkback/blkback.c +++ b/drivers/xen/blkback/blkback.c @@ -9,33 +9,60 @@ * * Copyright (c) 2003-2004, Keir Fraser & Steve Hand * Copyright (c) 2005, Christopher Clark + * + * 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; or, when distributed + * separately from the Linux kernel or incorporated into other + * software packages, subject to the following license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this source file (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, modify, + * merge, publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. */ +#include +#include +#include +#include +#include #include "common.h" -#include -#ifdef CONFIG_XEN_BLKDEV_GRANT -#include -#endif /* * These are rather arbitrary. They are fairly large because adjacent requests * pulled from a communication ring are quite likely to end up being part of * the same scatter/gather request at the disc. * - * ** TRY INCREASING 'MAX_PENDING_REQS' IF WRITE SPEEDS SEEM TOO LOW ** + * ** TRY INCREASING 'blkif_reqs' IF WRITE SPEEDS SEEM TOO LOW ** + * * This will increase the chances of being able to write whole tracks. * 64 should be enough to keep us competitive with Linux. */ -#define MAX_PENDING_REQS 64 -#define BATCH_PER_DOMAIN 16 +static int blkif_reqs = 64; +module_param_named(reqs, blkif_reqs, int, 0); +MODULE_PARM_DESC(reqs, "Number of blkback requests to allocate"); -static unsigned long mmap_vstart; -#define MMAP_PAGES \ - (MAX_PENDING_REQS * BLKIF_MAX_SEGMENTS_PER_REQUEST) -#define MMAP_VADDR(_req,_seg) \ - (mmap_vstart + \ - ((_req) * BLKIF_MAX_SEGMENTS_PER_REQUEST * PAGE_SIZE) + \ - ((_seg) * PAGE_SIZE)) +static int mmap_pages; + +/* Run-time switchable: /sys/module/blkback/parameters/ */ +static unsigned int log_stats = 0; +static unsigned int debug_lvl = 0; +module_param(log_stats, int, 0644); +module_param(debug_lvl, int, 0644); /* * Each outstanding request that we've passed to the lower device layers has a @@ -44,223 +71,173 @@ static unsigned long mmap_vstart; * response queued for it, with the saved 'id' passed back. */ typedef struct { - blkif_t *blkif; - unsigned long id; - int nr_pages; - atomic_t pendcnt; - unsigned short operation; - int status; + blkif_t *blkif; + unsigned long id; + int nr_pages; + atomic_t pendcnt; + unsigned short operation; + int status; + struct list_head free_list; } pending_req_t; -/* - * We can't allocate pending_req's in order, since they may complete out of - * order. We therefore maintain an allocation ring. This ring also indicates - * when enough work has been passed down -- at that point the allocation ring - * will be empty. - */ -static pending_req_t pending_reqs[MAX_PENDING_REQS]; -static unsigned char pending_ring[MAX_PENDING_REQS]; -static spinlock_t pend_prod_lock = SPIN_LOCK_UNLOCKED; -/* NB. We use a different index type to differentiate from shared blk rings. */ -typedef unsigned int PEND_RING_IDX; -#define MASK_PEND_IDX(_i) ((_i)&(MAX_PENDING_REQS-1)) -static PEND_RING_IDX pending_prod, pending_cons; -#define NR_PENDING_REQS (MAX_PENDING_REQS - pending_prod + pending_cons) - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) -static kmem_cache_t *buffer_head_cachep; -#else -static request_queue_t *plugged_queue; -static inline void flush_plugged_queue(void) -{ - request_queue_t *q = plugged_queue; - if ( q != NULL ) - { - if ( q->unplug_fn != NULL ) - q->unplug_fn(q); - blk_put_queue(q); - plugged_queue = NULL; - } -} -#endif +static pending_req_t *pending_reqs; +static struct list_head pending_free; +static DEFINE_SPINLOCK(pending_free_lock); +static DECLARE_WAIT_QUEUE_HEAD(pending_free_wq); -#ifdef CONFIG_XEN_BLKDEV_GRANT -/* When using grant tables to map a frame for device access then the - * handle returned must be used to unmap the frame. This is needed to - * drop the ref count on the frame. - */ -static u16 pending_grant_handles[MMAP_PAGES]; -#define pending_handle(_idx, _i) \ - (pending_grant_handles[((_idx) * BLKIF_MAX_SEGMENTS_PER_REQUEST) + (_i)]) -#define BLKBACK_INVALID_HANDLE (0xFFFF) -#endif +#define BLKBACK_INVALID_HANDLE (~0) -#ifdef CONFIG_XEN_BLKDEV_TAP_BE -/* - * If the tap driver is used, we may get pages belonging to either the tap - * or (more likely) the real frontend. The backend must specify which domain - * a given page belongs to in update_va_mapping though. For the moment, - * the tap rewrites the ID field of the request to contain the request index - * and the id of the real front end domain. - */ -#define BLKTAP_COOKIE 0xbeadfeed -static inline domid_t ID_TO_DOM(unsigned long id) { return (id >> 16); } -#endif +static unsigned long mmap_vstart; +static unsigned long *pending_vaddrs; +static grant_handle_t *pending_grant_handles; -static int do_block_io_op(blkif_t *blkif, int max_to_do); -static void dispatch_probe(blkif_t *blkif, blkif_request_t *req); -static void dispatch_rw_block_io(blkif_t *blkif, blkif_request_t *req); -static void make_response(blkif_t *blkif, unsigned long id, - unsigned short op, int st); +static inline int vaddr_pagenr(pending_req_t *req, int seg) +{ + return (req - pending_reqs) * BLKIF_MAX_SEGMENTS_PER_REQUEST + seg; +} -static void fast_flush_area(int idx, int nr_pages) +static inline unsigned long vaddr(pending_req_t *req, int seg) { -#ifdef CONFIG_XEN_BLKDEV_GRANT - gnttab_op_t aop[BLKIF_MAX_SEGMENTS_PER_REQUEST]; - unsigned int i, invcount = 0; - u16 handle; - - for ( i = 0; i < nr_pages; i++ ) - { - if ( BLKBACK_INVALID_HANDLE != ( handle = pending_handle(idx, i) ) ) - { - aop[i].u.unmap_grant_ref.host_virt_addr = MMAP_VADDR(idx, i); - aop[i].u.unmap_grant_ref.dev_bus_addr = 0; - aop[i].u.unmap_grant_ref.handle = handle; - pending_handle(idx, i) = BLKBACK_INVALID_HANDLE; - invcount++; - } - } - if ( unlikely(HYPERVISOR_grant_table_op( - GNTTABOP_unmap_grant_ref, aop, invcount))) - BUG(); -#else - - multicall_entry_t mcl[BLKIF_MAX_SEGMENTS_PER_REQUEST]; - int i; - - for ( i = 0; i < nr_pages; i++ ) - { - mcl[i].op = __HYPERVISOR_update_va_mapping; - mcl[i].args[0] = MMAP_VADDR(idx, i); - mcl[i].args[1] = 0; - mcl[i].args[2] = 0; - } - - mcl[nr_pages-1].args[2] = UVMF_TLB_FLUSH|UVMF_ALL; - if ( unlikely(HYPERVISOR_multicall(mcl, nr_pages) != 0) ) - BUG(); -#endif + return pending_vaddrs[vaddr_pagenr(req, seg)]; } +#define pending_handle(_req, _seg) \ + (pending_grant_handles[vaddr_pagenr(_req, _seg)]) + + +static int do_block_io_op(blkif_t *blkif); +static void dispatch_rw_block_io(blkif_t *blkif, + blkif_request_t *req, + pending_req_t *pending_req); +static void make_response(blkif_t *blkif, unsigned long id, + unsigned short op, int st); /****************************************************************** - * BLOCK-DEVICE SCHEDULER LIST MAINTENANCE + * misc small helpers */ +static pending_req_t* alloc_req(void) +{ + pending_req_t *req = NULL; + unsigned long flags; + + spin_lock_irqsave(&pending_free_lock, flags); + if (!list_empty(&pending_free)) { + req = list_entry(pending_free.next, pending_req_t, free_list); + list_del(&req->free_list); + } + spin_unlock_irqrestore(&pending_free_lock, flags); + return req; +} -static struct list_head blkio_schedule_list; -static spinlock_t blkio_schedule_list_lock; - -static int __on_blkdev_list(blkif_t *blkif) +static void free_req(pending_req_t *req) { - return blkif->blkdev_list.next != NULL; + unsigned long flags; + int was_empty; + + spin_lock_irqsave(&pending_free_lock, flags); + was_empty = list_empty(&pending_free); + list_add(&req->free_list, &pending_free); + spin_unlock_irqrestore(&pending_free_lock, flags); + if (was_empty) + wake_up(&pending_free_wq); } -static void remove_from_blkdev_list(blkif_t *blkif) +static void unplug_queue(blkif_t *blkif) { - unsigned long flags; - if ( !__on_blkdev_list(blkif) ) return; - spin_lock_irqsave(&blkio_schedule_list_lock, flags); - if ( __on_blkdev_list(blkif) ) - { - list_del(&blkif->blkdev_list); - blkif->blkdev_list.next = NULL; - blkif_put(blkif); - } - spin_unlock_irqrestore(&blkio_schedule_list_lock, flags); + if (blkif->plug == NULL) + return; + if (blkif->plug->unplug_fn) + blkif->plug->unplug_fn(blkif->plug); + blk_put_queue(blkif->plug); + blkif->plug = NULL; } -static void add_to_blkdev_list_tail(blkif_t *blkif) +static void plug_queue(blkif_t *blkif, struct bio *bio) { - unsigned long flags; - if ( __on_blkdev_list(blkif) ) return; - spin_lock_irqsave(&blkio_schedule_list_lock, flags); - if ( !__on_blkdev_list(blkif) && (blkif->status == CONNECTED) ) - { - list_add_tail(&blkif->blkdev_list, &blkio_schedule_list); - blkif_get(blkif); - } - spin_unlock_irqrestore(&blkio_schedule_list_lock, flags); + request_queue_t *q = bdev_get_queue(bio->bi_bdev); + + if (q == blkif->plug) + return; + unplug_queue(blkif); + blk_get_queue(q); + blkif->plug = q; } +static void fast_flush_area(pending_req_t *req) +{ + struct gnttab_unmap_grant_ref unmap[BLKIF_MAX_SEGMENTS_PER_REQUEST]; + unsigned int i, invcount = 0; + grant_handle_t handle; + int ret; + + for (i = 0; i < req->nr_pages; i++) { + handle = pending_handle(req, i); + if (handle == BLKBACK_INVALID_HANDLE) + continue; + gnttab_set_unmap_op(&unmap[i], vaddr(req, i), GNTMAP_host_map, + handle); + pending_handle(req, i) = BLKBACK_INVALID_HANDLE; + invcount++; + } + + ret = HYPERVISOR_grant_table_op( + GNTTABOP_unmap_grant_ref, unmap, invcount); + BUG_ON(ret); +} /****************************************************************** * SCHEDULER FUNCTIONS */ -static DECLARE_WAIT_QUEUE_HEAD(blkio_schedule_wait); +static void print_stats(blkif_t *blkif) +{ + printk(KERN_DEBUG "%s: oo %3d | rd %4d | wr %4d\n", + current->comm, blkif->st_oo_req, + blkif->st_rd_req, blkif->st_wr_req); + blkif->st_print = jiffies + msecs_to_jiffies(10 * 1000); + blkif->st_rd_req = 0; + blkif->st_wr_req = 0; + blkif->st_oo_req = 0; +} -static int blkio_schedule(void *arg) +int blkif_schedule(void *arg) { - DECLARE_WAITQUEUE(wq, current); + blkif_t *blkif = arg; - blkif_t *blkif; - struct list_head *ent; + blkif_get(blkif); - daemonize( -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) - "xenblkd" -#endif - ); - - for ( ; ; ) - { - /* Wait for work to do. */ - add_wait_queue(&blkio_schedule_wait, &wq); - set_current_state(TASK_INTERRUPTIBLE); - if ( (NR_PENDING_REQS == MAX_PENDING_REQS) || - list_empty(&blkio_schedule_list) ) - schedule(); - __set_current_state(TASK_RUNNING); - remove_wait_queue(&blkio_schedule_wait, &wq); - - /* Queue up a batch of requests. */ - while ( (NR_PENDING_REQS < MAX_PENDING_REQS) && - !list_empty(&blkio_schedule_list) ) - { - ent = blkio_schedule_list.next; - blkif = list_entry(ent, blkif_t, blkdev_list); - blkif_get(blkif); - remove_from_blkdev_list(blkif); - if ( do_block_io_op(blkif, BATCH_PER_DOMAIN) ) - add_to_blkdev_list_tail(blkif); - blkif_put(blkif); - } - - /* Push the batch through to disc. */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) - run_task_queue(&tq_disk); -#else - flush_plugged_queue(); -#endif - } -} + if (debug_lvl) + printk(KERN_DEBUG "%s: started\n", current->comm); -static void maybe_trigger_blkio_schedule(void) -{ - /* - * Needed so that two processes, who together make the following predicate - * true, don't both read stale values and evaluate the predicate - * incorrectly. Incredibly unlikely to stall the scheduler on x86, but... - */ - smp_mb(); - - if ( (NR_PENDING_REQS < (MAX_PENDING_REQS/2)) && - !list_empty(&blkio_schedule_list) ) - wake_up(&blkio_schedule_wait); -} + while (!kthread_should_stop()) { + wait_event_interruptible( + blkif->wq, + blkif->waiting_reqs || kthread_should_stop()); + wait_event_interruptible( + pending_free_wq, + !list_empty(&pending_free) || kthread_should_stop()); + + blkif->waiting_reqs = 0; + smp_mb(); /* clear flag *before* checking for work */ + + if (do_block_io_op(blkif)) + blkif->waiting_reqs = 1; + unplug_queue(blkif); + if (log_stats && time_after(jiffies, blkif->st_print)) + print_stats(blkif); + } + if (log_stats) + print_stats(blkif); + if (debug_lvl) + printk(KERN_DEBUG "%s: exiting\n", current->comm); + + blkif->xenblkd = NULL; + blkif_put(blkif); + + return 0; +} /****************************************************************** * COMPLETION CALLBACK -- Called as bh->b_end_io() @@ -268,56 +245,45 @@ static void maybe_trigger_blkio_schedule(void) static void __end_block_io_op(pending_req_t *pending_req, int uptodate) { - unsigned long flags; - - /* An error fails the entire request. */ - if ( !uptodate ) - { - DPRINTK("Buffer not up-to-date at end of operation\n"); - pending_req->status = BLKIF_RSP_ERROR; - } - - if ( atomic_dec_and_test(&pending_req->pendcnt) ) - { - int pending_idx = pending_req - pending_reqs; - fast_flush_area(pending_idx, pending_req->nr_pages); - make_response(pending_req->blkif, pending_req->id, - pending_req->operation, pending_req->status); - blkif_put(pending_req->blkif); - spin_lock_irqsave(&pend_prod_lock, flags); - pending_ring[MASK_PEND_IDX(pending_prod++)] = pending_idx; - spin_unlock_irqrestore(&pend_prod_lock, flags); - maybe_trigger_blkio_schedule(); - } + /* An error fails the entire request. */ + if (!uptodate) { + DPRINTK("Buffer not up-to-date at end of operation\n"); + pending_req->status = BLKIF_RSP_ERROR; + } + + if (atomic_dec_and_test(&pending_req->pendcnt)) { + fast_flush_area(pending_req); + make_response(pending_req->blkif, pending_req->id, + pending_req->operation, pending_req->status); + blkif_put(pending_req->blkif); + free_req(pending_req); + } } -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) -static void end_block_io_op(struct buffer_head *bh, int uptodate) -{ - __end_block_io_op(bh->b_private, uptodate); - kmem_cache_free(buffer_head_cachep, bh); -} -#else static int end_block_io_op(struct bio *bio, unsigned int done, int error) { - if ( done || error ) - __end_block_io_op(bio->bi_private, (done && !error)); - bio_put(bio); - return error; + if (bio->bi_size != 0) + return 1; + __end_block_io_op(bio->bi_private, !error); + bio_put(bio); + return error; } -#endif /****************************************************************************** * NOTIFICATION FROM GUEST OS. */ +static void blkif_notify_work(blkif_t *blkif) +{ + blkif->waiting_reqs = 1; + wake_up(&blkif->wq); +} + irqreturn_t blkif_be_int(int irq, void *dev_id, struct pt_regs *regs) { - blkif_t *blkif = dev_id; - add_to_blkdev_list_tail(blkif); - maybe_trigger_blkio_schedule(); - return IRQ_HANDLED; + blkif_notify_work(dev_id); + return IRQ_HANDLED; } @@ -326,347 +292,170 @@ irqreturn_t blkif_be_int(int irq, void *dev_id, struct pt_regs *regs) * DOWNWARD CALLS -- These interface with the block-device layer proper. */ -static int do_block_io_op(blkif_t *blkif, int max_to_do) +static int do_block_io_op(blkif_t *blkif) { - blkif_back_ring_t *blk_ring = &blkif->blk_ring; - blkif_request_t *req; - RING_IDX i, rp; - int more_to_do = 0; - - rp = blk_ring->sring->req_prod; - rmb(); /* Ensure we see queued requests up to 'rp'. */ - - for ( i = blk_ring->req_cons; - (i != rp) && !RING_REQUEST_CONS_OVERFLOW(blk_ring, i); - i++ ) - { - if ( (max_to_do-- == 0) || (NR_PENDING_REQS == MAX_PENDING_REQS) ) - { - more_to_do = 1; - break; - } - - req = RING_GET_REQUEST(blk_ring, i); - switch ( req->operation ) - { - case BLKIF_OP_READ: - case BLKIF_OP_WRITE: - dispatch_rw_block_io(blkif, req); - break; - - case BLKIF_OP_PROBE: - dispatch_probe(blkif, req); - break; - - default: - DPRINTK("error: unknown block io operation [%d]\n", - req->operation); - make_response(blkif, req->id, req->operation, BLKIF_RSP_ERROR); - break; - } - } - - blk_ring->req_cons = i; - return more_to_do; + blkif_back_ring_t *blk_ring = &blkif->blk_ring; + blkif_request_t *req; + pending_req_t *pending_req; + RING_IDX rc, rp; + int more_to_do = 0; + + rc = blk_ring->req_cons; + rp = blk_ring->sring->req_prod; + rmb(); /* Ensure we see queued requests up to 'rp'. */ + + while ((rc != rp) && !RING_REQUEST_CONS_OVERFLOW(blk_ring, rc)) { + + pending_req = alloc_req(); + if (NULL == pending_req) { + blkif->st_oo_req++; + more_to_do = 1; + break; + } + + req = RING_GET_REQUEST(blk_ring, rc); + blk_ring->req_cons = ++rc; /* before make_response() */ + + switch (req->operation) { + case BLKIF_OP_READ: + blkif->st_rd_req++; + dispatch_rw_block_io(blkif, req, pending_req); + break; + case BLKIF_OP_WRITE: + blkif->st_wr_req++; + dispatch_rw_block_io(blkif, req, pending_req); + break; + default: + DPRINTK("error: unknown block io operation [%d]\n", + req->operation); + make_response(blkif, req->id, req->operation, + BLKIF_RSP_ERROR); + free_req(pending_req); + break; + } + } + return more_to_do; } -static void dispatch_probe(blkif_t *blkif, blkif_request_t *req) +static void dispatch_rw_block_io(blkif_t *blkif, + blkif_request_t *req, + pending_req_t *pending_req) { - int rsp = BLKIF_RSP_ERROR; - int pending_idx = pending_ring[MASK_PEND_IDX(pending_cons)]; - - /* We expect one buffer only. */ - if ( unlikely(req->nr_segments != 1) ) - goto out; - - /* Make sure the buffer is page-sized. */ - if ( (blkif_first_sect(req->frame_and_sects[0]) != 0) || - (blkif_last_sect(req->frame_and_sects[0]) != 7) ) - goto out; - -#ifdef CONFIG_XEN_BLKDEV_GRANT - { - gnttab_op_t op; - - op.u.map_grant_ref.host_virt_addr = MMAP_VADDR(pending_idx, 0); - op.u.map_grant_ref.flags = GNTMAP_host_map; - op.u.map_grant_ref.ref = blkif_gref_from_fas(req->frame_and_sects[0]); - op.u.map_grant_ref.dom = blkif->domid; - - if ( unlikely(HYPERVISOR_grant_table_op( - GNTTABOP_map_grant_ref, &op, 1))) - BUG(); - - if ( op.u.map_grant_ref.handle < 0 ) - goto out; - - pending_handle(pending_idx, 0) = op.u.map_grant_ref.handle; - } -#else /* else CONFIG_XEN_BLKDEV_GRANT */ - -#ifdef CONFIG_XEN_BLKDEV_TAP_BE - /* Grab the real frontend out of the probe message. */ - if (req->frame_and_sects[1] == BLKTAP_COOKIE) - blkif->is_blktap = 1; -#endif - - -#ifdef CONFIG_XEN_BLKDEV_TAP_BE - if ( HYPERVISOR_update_va_mapping_otherdomain( - MMAP_VADDR(pending_idx, 0), - (pte_t) { (req->frame_and_sects[0] & PAGE_MASK) | __PAGE_KERNEL }, - 0, (blkif->is_blktap ? ID_TO_DOM(req->id) : blkif->domid) ) ) - - goto out; -#else - if ( HYPERVISOR_update_va_mapping_otherdomain( - MMAP_VADDR(pending_idx, 0), - (pte_t) { (req->frame_and_sects[0] & PAGE_MASK) | __PAGE_KERNEL }, - 0, blkif->domid) ) - - goto out; -#endif -#endif /* endif CONFIG_XEN_BLKDEV_GRANT */ - - rsp = vbd_probe(blkif, (vdisk_t *)MMAP_VADDR(pending_idx, 0), - PAGE_SIZE / sizeof(vdisk_t)); - - out: - fast_flush_area(pending_idx, 1); - make_response(blkif, req->id, req->operation, rsp); -} - -static void dispatch_rw_block_io(blkif_t *blkif, blkif_request_t *req) -{ - extern void ll_rw_block(int rw, int nr, struct buffer_head * bhs[]); - int operation = (req->operation == BLKIF_OP_WRITE) ? WRITE : READ; - unsigned long fas = 0; - int i, pending_idx = pending_ring[MASK_PEND_IDX(pending_cons)]; - pending_req_t *pending_req; -#ifdef CONFIG_XEN_BLKDEV_GRANT - gnttab_op_t aop[BLKIF_MAX_SEGMENTS_PER_REQUEST]; -#else - unsigned long remap_prot; - multicall_entry_t mcl[BLKIF_MAX_SEGMENTS_PER_REQUEST]; -#endif - struct phys_req preq; - struct { - unsigned long buf; unsigned int nsec; - } seg[BLKIF_MAX_SEGMENTS_PER_REQUEST]; - unsigned int nseg; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) - struct buffer_head *bh; -#else - struct bio *bio = NULL, *biolist[BLKIF_MAX_SEGMENTS_PER_REQUEST]; - int nbio = 0; - request_queue_t *q; -#endif - - /* Check that number of segments is sane. */ - nseg = req->nr_segments; - if ( unlikely(nseg == 0) || - unlikely(nseg > BLKIF_MAX_SEGMENTS_PER_REQUEST) ) - { - DPRINTK("Bad number of segments in request (%d)\n", nseg); - goto bad_descriptor; - } - - preq.dev = req->device; - preq.sector_number = req->sector_number; - preq.nr_sects = 0; - -#ifdef CONFIG_XEN_BLKDEV_GRANT - for ( i = 0; i < nseg; i++ ) - { - fas = req->frame_and_sects[i]; - seg[i].nsec = blkif_last_sect(fas) - blkif_first_sect(fas) + 1; - - if ( seg[i].nsec <= 0 ) - goto bad_descriptor; - preq.nr_sects += seg[i].nsec; - - aop[i].u.map_grant_ref.host_virt_addr = MMAP_VADDR(pending_idx, i); - - aop[i].u.map_grant_ref.dom = blkif->domid; - aop[i].u.map_grant_ref.ref = blkif_gref_from_fas(fas); - aop[i].u.map_grant_ref.flags = ( GNTMAP_host_map | - ( ( operation == READ ) ? - 0 : GNTMAP_readonly ) ); - } - - if ( unlikely(HYPERVISOR_grant_table_op( - GNTTABOP_map_grant_ref, aop, nseg))) - BUG(); - - for ( i = 0; i < nseg; i++ ) - { - if ( unlikely(aop[i].u.map_grant_ref.handle < 0) ) - { - DPRINTK("invalid buffer -- could not remap it\n"); - fast_flush_area(pending_idx, nseg); - goto bad_descriptor; - } - - phys_to_machine_mapping[__pa(MMAP_VADDR(pending_idx, i))>>PAGE_SHIFT] = - FOREIGN_FRAME(aop[i].u.map_grant_ref.dev_bus_addr); - - pending_handle(pending_idx, i) = aop[i].u.map_grant_ref.handle; - } -#endif - - for ( i = 0; i < nseg; i++ ) - { - fas = req->frame_and_sects[i]; -#ifdef CONFIG_XEN_BLKDEV_GRANT - seg[i].buf = (aop[i].u.map_grant_ref.dev_bus_addr << PAGE_SHIFT) | - (blkif_first_sect(fas) << 9); -#else - seg[i].buf = (fas & PAGE_MASK) | (blkif_first_sect(fas) << 9); - seg[i].nsec = blkif_last_sect(fas) - blkif_first_sect(fas) + 1; - if ( seg[i].nsec <= 0 ) - goto bad_descriptor; - preq.nr_sects += seg[i].nsec; -#endif - } - - if ( vbd_translate(&preq, blkif, operation) != 0 ) - { - DPRINTK("access denied: %s of [%llu,%llu] on dev=%04x\n", - operation == READ ? "read" : "write", preq.sector_number, - preq.sector_number + preq.nr_sects, preq.dev); - goto bad_descriptor; - } - -#ifndef CONFIG_XEN_BLKDEV_GRANT - if ( operation == READ ) - remap_prot = _PAGE_PRESENT|_PAGE_DIRTY|_PAGE_ACCESSED|_PAGE_RW; - else - remap_prot = _PAGE_PRESENT|_PAGE_DIRTY|_PAGE_ACCESSED; - - for ( i = 0; i < nseg; i++ ) - { - mcl[i].op = __HYPERVISOR_update_va_mapping_otherdomain; - mcl[i].args[0] = MMAP_VADDR(pending_idx, i); - mcl[i].args[1] = (seg[i].buf & PAGE_MASK) | remap_prot; - mcl[i].args[2] = 0; - mcl[i].args[3] = blkif->domid; -#ifdef CONFIG_XEN_BLKDEV_TAP_BE - if ( blkif->is_blktap ) - mcl[i].args[3] = ID_TO_DOM(req->id); -#endif - phys_to_machine_mapping[__pa(MMAP_VADDR(pending_idx, i))>>PAGE_SHIFT] = - FOREIGN_FRAME(seg[i].buf >> PAGE_SHIFT); - } - - BUG_ON(HYPERVISOR_multicall(mcl, nseg) != 0); - - for ( i = 0; i < nseg; i++ ) - { - if ( unlikely(mcl[i].args[5] != 0) ) - { - DPRINTK("invalid buffer -- could not remap it\n"); - fast_flush_area(pending_idx, nseg); - goto bad_descriptor; - } - } -#endif /* end ifndef CONFIG_XEN_BLKDEV_GRANT */ - - pending_req = &pending_reqs[pending_idx]; - pending_req->blkif = blkif; - pending_req->id = req->id; - pending_req->operation = operation; - pending_req->status = BLKIF_RSP_OKAY; - pending_req->nr_pages = nseg; - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) - - atomic_set(&pending_req->pendcnt, nseg); - pending_cons++; - blkif_get(blkif); - - for ( i = 0; i < nseg; i++ ) - { - bh = kmem_cache_alloc(buffer_head_cachep, GFP_KERNEL); - if ( unlikely(bh == NULL) ) - { - __end_block_io_op(pending_req, 0); - continue; - } - - memset(bh, 0, sizeof (struct buffer_head)); - - init_waitqueue_head(&bh->b_wait); - bh->b_size = seg[i].nsec << 9; - bh->b_dev = preq.dev; - bh->b_rdev = preq.dev; - bh->b_rsector = (unsigned long)preq.sector_number; - bh->b_data = (char *)MMAP_VADDR(pending_idx, i) + - (seg[i].buf & ~PAGE_MASK); - bh->b_page = virt_to_page(MMAP_VADDR(pending_idx, i)); - bh->b_end_io = end_block_io_op; - bh->b_private = pending_req; - - bh->b_state = (1 << BH_Mapped) | (1 << BH_Lock) | - (1 << BH_Req) | (1 << BH_Launder); - if ( operation == WRITE ) - bh->b_state |= (1 << BH_JBD) | (1 << BH_Req) | (1 << BH_Uptodate); - - atomic_set(&bh->b_count, 1); - - /* Dispatch a single request. We'll flush it to disc later. */ - generic_make_request(operation, bh); - - preq.sector_number += seg[i].nsec; - } - -#else - - for ( i = 0; i < nseg; i++ ) - { - while ( (bio == NULL) || - (bio_add_page(bio, - virt_to_page(MMAP_VADDR(pending_idx, i)), - seg[i].nsec << 9, - seg[i].buf & ~PAGE_MASK) == 0) ) - { - bio = biolist[nbio++] = bio_alloc(GFP_KERNEL, nseg-i); - if ( unlikely(bio == NULL) ) - { - for ( i = 0; i < (nbio-1); i++ ) - bio_put(biolist[i]); - fast_flush_area(pending_idx, nseg); - goto bad_descriptor; - } - - bio->bi_bdev = preq.bdev; - bio->bi_private = pending_req; - bio->bi_end_io = end_block_io_op; - bio->bi_sector = preq.sector_number; - } - - preq.sector_number += seg[i].nsec; - } - - if ( (q = bdev_get_queue(bio->bi_bdev)) != plugged_queue ) - { - flush_plugged_queue(); - blk_get_queue(q); - plugged_queue = q; - } - - atomic_set(&pending_req->pendcnt, nbio); - pending_cons++; - blkif_get(blkif); - - for ( i = 0; i < nbio; i++ ) - submit_bio(operation, biolist[i]); - -#endif - - return; - - bad_descriptor: - make_response(blkif, req->id, req->operation, BLKIF_RSP_ERROR); + extern void ll_rw_block(int rw, int nr, struct buffer_head * bhs[]); + int operation = (req->operation == BLKIF_OP_WRITE) ? WRITE : READ; + struct gnttab_map_grant_ref map[BLKIF_MAX_SEGMENTS_PER_REQUEST]; + struct phys_req preq; + struct { + unsigned long buf; unsigned int nsec; + } seg[BLKIF_MAX_SEGMENTS_PER_REQUEST]; + unsigned int nseg; + struct bio *bio = NULL, *biolist[BLKIF_MAX_SEGMENTS_PER_REQUEST]; + int ret, i, nbio = 0; + + /* Check that number of segments is sane. */ + nseg = req->nr_segments; + if (unlikely(nseg == 0) || + unlikely(nseg > BLKIF_MAX_SEGMENTS_PER_REQUEST)) { + DPRINTK("Bad number of segments in request (%d)\n", nseg); + goto fail_response; + } + + preq.dev = req->handle; + preq.sector_number = req->sector_number; + preq.nr_sects = 0; + + pending_req->blkif = blkif; + pending_req->id = req->id; + pending_req->operation = operation; + pending_req->status = BLKIF_RSP_OKAY; + pending_req->nr_pages = nseg; + + for (i = 0; i < nseg; i++) { + uint32_t flags; + + seg[i].nsec = req->seg[i].last_sect - + req->seg[i].first_sect + 1; + + if ((req->seg[i].last_sect >= (PAGE_SIZE >> 9)) || + (seg[i].nsec <= 0)) + goto fail_response; + preq.nr_sects += seg[i].nsec; + + flags = GNTMAP_host_map; + if ( operation == WRITE ) + flags |= GNTMAP_readonly; + gnttab_set_map_op(&map[i], vaddr(pending_req, i), flags, + req->seg[i].gref, blkif->domid); + } + + ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, map, nseg); + BUG_ON(ret); + + for (i = 0; i < nseg; i++) { + if (unlikely(map[i].status != 0)) { + DPRINTK("invalid buffer -- could not remap it\n"); + goto fail_flush; + } + + pending_handle(pending_req, i) = map[i].handle; + set_phys_to_machine(__pa(vaddr( + pending_req, i)) >> PAGE_SHIFT, + FOREIGN_FRAME(map[i].dev_bus_addr >> PAGE_SHIFT)); + seg[i].buf = map[i].dev_bus_addr | + (req->seg[i].first_sect << 9); + } + + if (vbd_translate(&preq, blkif, operation) != 0) { + DPRINTK("access denied: %s of [%llu,%llu] on dev=%04x\n", + operation == READ ? "read" : "write", + preq.sector_number, + preq.sector_number + preq.nr_sects, preq.dev); + goto fail_flush; + } + + for (i = 0; i < nseg; i++) { + if (((int)preq.sector_number|(int)seg[i].nsec) & + ((bdev_hardsect_size(preq.bdev) >> 9) - 1)) { + DPRINTK("Misaligned I/O request from domain %d", + blkif->domid); + goto fail_put_bio; + } + + while ((bio == NULL) || + (bio_add_page(bio, + virt_to_page(vaddr(pending_req, i)), + seg[i].nsec << 9, + seg[i].buf & ~PAGE_MASK) == 0)) { + bio = biolist[nbio++] = bio_alloc(GFP_KERNEL, nseg-i); + if (unlikely(bio == NULL)) + goto fail_put_bio; + + bio->bi_bdev = preq.bdev; + bio->bi_private = pending_req; + bio->bi_end_io = end_block_io_op; + bio->bi_sector = preq.sector_number; + } + + preq.sector_number += seg[i].nsec; + } + + plug_queue(blkif, bio); + atomic_set(&pending_req->pendcnt, nbio); + blkif_get(blkif); + + for (i = 0; i < nbio; i++) + submit_bio(operation, biolist[i]); + + return; + + fail_put_bio: + for (i = 0; i < (nbio-1); i++) + bio_put(biolist[i]); + fail_flush: + fast_flush_area(pending_req); + fail_response: + make_response(blkif, req->id, req->operation, BLKIF_RSP_ERROR); + free_req(pending_req); } @@ -677,75 +466,101 @@ static void dispatch_rw_block_io(blkif_t *blkif, blkif_request_t *req) static void make_response(blkif_t *blkif, unsigned long id, - unsigned short op, int st) + unsigned short op, int st) { - blkif_response_t *resp; - unsigned long flags; - blkif_back_ring_t *blk_ring = &blkif->blk_ring; - - /* Place on the response ring for the relevant domain. */ - spin_lock_irqsave(&blkif->blk_ring_lock, flags); - resp = RING_GET_RESPONSE(blk_ring, blk_ring->rsp_prod_pvt); - resp->id = id; - resp->operation = op; - resp->status = st; - wmb(); /* Ensure other side can see the response fields. */ - blk_ring->rsp_prod_pvt++; - RING_PUSH_RESPONSES(blk_ring); - spin_unlock_irqrestore(&blkif->blk_ring_lock, flags); - - /* Kick the relevant domain. */ - notify_via_evtchn(blkif->evtchn); -} - -void blkif_deschedule(blkif_t *blkif) -{ - remove_from_blkdev_list(blkif); + blkif_response_t *resp; + unsigned long flags; + blkif_back_ring_t *blk_ring = &blkif->blk_ring; + int more_to_do = 0; + int notify; + + spin_lock_irqsave(&blkif->blk_ring_lock, flags); + + /* Place on the response ring for the relevant domain. */ + resp = RING_GET_RESPONSE(blk_ring, blk_ring->rsp_prod_pvt); + resp->id = id; + resp->operation = op; + resp->status = st; + blk_ring->rsp_prod_pvt++; + RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(blk_ring, notify); + + if (blk_ring->rsp_prod_pvt == blk_ring->req_cons) { + /* + * Tail check for pending requests. Allows frontend to avoid + * notifications if requests are already in flight (lower + * overheads and promotes batching). + */ + RING_FINAL_CHECK_FOR_REQUESTS(blk_ring, more_to_do); + + } else if (RING_HAS_UNCONSUMED_REQUESTS(blk_ring)) { + more_to_do = 1; + + } + spin_unlock_irqrestore(&blkif->blk_ring_lock, flags); + + if (more_to_do) + blkif_notify_work(blkif); + if (notify) + notify_remote_via_irq(blkif->irq); } static int __init blkif_init(void) { - int i; - - if ( !(xen_start_info.flags & SIF_INITDOMAIN) && - !(xen_start_info.flags & SIF_BLK_BE_DOMAIN) ) - return 0; - - blkif_interface_init(); - - if ( (mmap_vstart = allocate_empty_lowmem_region(MMAP_PAGES)) == 0 ) - BUG(); - - pending_cons = 0; - pending_prod = MAX_PENDING_REQS; - memset(pending_reqs, 0, sizeof(pending_reqs)); - for ( i = 0; i < MAX_PENDING_REQS; i++ ) - pending_ring[i] = i; - - spin_lock_init(&blkio_schedule_list_lock); - INIT_LIST_HEAD(&blkio_schedule_list); - - if ( kernel_thread(blkio_schedule, 0, CLONE_FS | CLONE_FILES) < 0 ) - BUG(); - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) - buffer_head_cachep = kmem_cache_create( - "buffer_head_cache", sizeof(struct buffer_head), - 0, SLAB_HWCACHE_ALIGN, NULL, NULL); + struct page *page; + int i; + + if (!is_running_on_xen()) + return -ENODEV; + + mmap_pages = blkif_reqs * BLKIF_MAX_SEGMENTS_PER_REQUEST; + +#ifdef CONFIG_XEN_IA64_DOM0_NON_VP + extern unsigned long alloc_empty_foreign_map_page_range( + unsigned long pages); + mmap_vstart = (unsigned long) + alloc_empty_foreign_map_page_range(mmap_pages); +#else /* ! ia64 */ + page = balloon_alloc_empty_page_range(mmap_pages); + if (page == NULL) + return -ENOMEM; + mmap_vstart = (unsigned long)pfn_to_kaddr(page_to_pfn(page)); #endif - blkif_ctrlif_init(); + pending_reqs = kmalloc(sizeof(pending_reqs[0]) * + blkif_reqs, GFP_KERNEL); + pending_grant_handles = kmalloc(sizeof(pending_grant_handles[0]) * + mmap_pages, GFP_KERNEL); + pending_vaddrs = kmalloc(sizeof(pending_vaddrs[0]) * + mmap_pages, GFP_KERNEL); + if (!pending_reqs || !pending_grant_handles || !pending_vaddrs) { + kfree(pending_reqs); + kfree(pending_grant_handles); + kfree(pending_vaddrs); + printk("%s: out of memory\n", __FUNCTION__); + return -ENOMEM; + } + + blkif_interface_init(); + + printk("%s: reqs=%d, pages=%d, mmap_vstart=0x%lx\n", + __FUNCTION__, blkif_reqs, mmap_pages, mmap_vstart); + BUG_ON(mmap_vstart == 0); + for (i = 0; i < mmap_pages; i++) { + pending_vaddrs[i] = mmap_vstart + (i << PAGE_SHIFT); + pending_grant_handles[i] = BLKBACK_INVALID_HANDLE; + } + + memset(pending_reqs, 0, sizeof(pending_reqs)); + INIT_LIST_HEAD(&pending_free); + + for (i = 0; i < blkif_reqs; i++) + list_add_tail(&pending_reqs[i].free_list, &pending_free); -#ifdef CONFIG_XEN_BLKDEV_GRANT - memset( pending_grant_handles, BLKBACK_INVALID_HANDLE, MMAP_PAGES ); - printk(KERN_ALERT "Blkif backend is using grant tables.\n"); -#endif + blkif_xenbus_init(); -#ifdef CONFIG_XEN_BLKDEV_TAP_BE - printk(KERN_ALERT "NOTE: Blkif backend is running with tap support on!\n"); -#endif - - return 0; + return 0; } -__initcall(blkif_init); +module_init(blkif_init); + +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/xen/blkback/common.h b/drivers/xen/blkback/common.h index a698e01c6..d057f7924 100644 --- a/drivers/xen/blkback/common.h +++ b/drivers/xen/blkback/common.h @@ -1,3 +1,28 @@ +/* + * 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; or, when distributed + * separately from the Linux kernel or incorporated into other + * software packages, subject to the following license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this source file (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, modify, + * merge, publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ #ifndef __BLKIF__BACKEND__COMMON_H__ #define __BLKIF__BACKEND__COMMON_H__ @@ -5,100 +30,105 @@ #include #include #include -#include #include #include #include +#include +#include #include #include #include -#include -#include -#include -#include - -#if 0 -#define ASSERT(_p) \ - if ( !(_p) ) { printk("Assertion '%s' failed, line %d, file %s", #_p , \ - __LINE__, __FILE__); *(int*)0=0; } -#define DPRINTK(_f, _a...) printk(KERN_ALERT "(file=%s, line=%d) " _f, \ - __FILE__ , __LINE__ , ## _a ) -#else -#define ASSERT(_p) ((void)0) -#define DPRINTK(_f, _a...) ((void)0) -#endif - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) -typedef struct rb_root rb_root_t; -typedef struct rb_node rb_node_t; -#else -struct block_device; -#endif +#include +#include +#include +#include +#include +#include + +#define DPRINTK(_f, _a...) \ + pr_debug("(file=%s, line=%d) " _f, \ + __FILE__ , __LINE__ , ## _a ) + +struct vbd { + blkif_vdev_t handle; /* what the domain refers to this vbd as */ + unsigned char readonly; /* Non-zero -> read-only */ + unsigned char type; /* VDISK_xxx */ + u32 pdevice; /* phys device that this vbd maps to */ + struct block_device *bdev; +}; + +struct backend_info; typedef struct blkif_st { - /* Unique identifier for this interface. */ - domid_t domid; - unsigned int handle; - /* Physical parameters of the comms window. */ - unsigned long shmem_frame; - unsigned int evtchn; - int irq; - /* Comms information. */ - blkif_back_ring_t blk_ring; - /* VBDs attached to this interface. */ - rb_root_t vbd_rb; /* Mapping from 16-bit vdevices to VBDs.*/ - spinlock_t vbd_lock; /* Protects VBD mapping. */ - /* Private fields. */ - enum { DISCONNECTED, DISCONNECTING, CONNECTED } status; - /* - * DISCONNECT response is deferred until pending requests are ack'ed. - * We therefore need to store the id from the original request. - */ - u8 disconnect_rspid; -#ifdef CONFIG_XEN_BLKDEV_TAP_BE - /* Is this a blktap frontend */ - unsigned int is_blktap; -#endif - struct blkif_st *hash_next; - struct list_head blkdev_list; - spinlock_t blk_ring_lock; - atomic_t refcnt; - - struct work_struct work; + /* Unique identifier for this interface. */ + domid_t domid; + unsigned int handle; + /* Physical parameters of the comms window. */ + unsigned int evtchn; + unsigned int irq; + /* Comms information. */ + blkif_back_ring_t blk_ring; + struct vm_struct *blk_ring_area; + /* The VBD attached to this interface. */ + struct vbd vbd; + /* Back pointer to the backend_info. */ + struct backend_info *be; + /* Private fields. */ + spinlock_t blk_ring_lock; + atomic_t refcnt; + + wait_queue_head_t wq; + struct task_struct *xenblkd; + unsigned int waiting_reqs; + request_queue_t *plug; + + /* statistics */ + unsigned long st_print; + int st_rd_req; + int st_wr_req; + int st_oo_req; + + wait_queue_head_t waiting_to_free; + + grant_handle_t shmem_handle; + grant_ref_t shmem_ref; } blkif_t; -void blkif_create(blkif_be_create_t *create); -void blkif_destroy(blkif_be_destroy_t *destroy); -void blkif_connect(blkif_be_connect_t *connect); -int blkif_disconnect(blkif_be_disconnect_t *disconnect, u8 rsp_id); -void blkif_disconnect_complete(blkif_t *blkif); -blkif_t *blkif_find_by_handle(domid_t domid, unsigned int handle); +blkif_t *blkif_alloc(domid_t domid); +void blkif_disconnect(blkif_t *blkif); +void blkif_free(blkif_t *blkif); +int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn); + #define blkif_get(_b) (atomic_inc(&(_b)->refcnt)) -#define blkif_put(_b) \ - do { \ - if ( atomic_dec_and_test(&(_b)->refcnt) ) \ - blkif_disconnect_complete(_b); \ - } while (0) +#define blkif_put(_b) \ + do { \ + if (atomic_dec_and_test(&(_b)->refcnt)) \ + wake_up(&(_b)->waiting_to_free);\ + } while (0) + +/* Create a vbd. */ +int vbd_create(blkif_t *blkif, blkif_vdev_t vdevice, unsigned major, + unsigned minor, int readonly); +void vbd_free(struct vbd *vbd); -void vbd_create(blkif_be_vbd_create_t *create); -void vbd_destroy(blkif_be_vbd_destroy_t *delete); -int vbd_probe(blkif_t *blkif, vdisk_t *vbd_info, int max_vbds); -void destroy_all_vbds(blkif_t *blkif); +unsigned long vbd_size(struct vbd *vbd); +unsigned int vbd_info(struct vbd *vbd); +unsigned long vbd_secsize(struct vbd *vbd); struct phys_req { - unsigned short dev; - unsigned short nr_sects; - struct block_device *bdev; - blkif_sector_t sector_number; + unsigned short dev; + unsigned short nr_sects; + struct block_device *bdev; + blkif_sector_t sector_number; }; int vbd_translate(struct phys_req *req, blkif_t *blkif, int operation); void blkif_interface_init(void); -void blkif_ctrlif_init(void); -void blkif_deschedule(blkif_t *blkif); +void blkif_xenbus_init(void); irqreturn_t blkif_be_int(int irq, void *dev_id, struct pt_regs *regs); +int blkif_schedule(void *arg); #endif /* __BLKIF__BACKEND__COMMON_H__ */ diff --git a/drivers/xen/blkback/interface.c b/drivers/xen/blkback/interface.c index 46d55d1fd..53b4764c4 100644 --- a/drivers/xen/blkback/interface.c +++ b/drivers/xen/blkback/interface.c @@ -4,246 +4,168 @@ * Block-device interface management. * * Copyright (c) 2004, Keir Fraser + * + * 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; or, when distributed + * separately from the Linux kernel or incorporated into other + * software packages, subject to the following license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this source file (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, modify, + * merge, publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. */ #include "common.h" - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) -#define VMALLOC_VMADDR(x) ((unsigned long)(x)) -#endif - -#define BLKIF_HASHSZ 1024 -#define BLKIF_HASH(_d,_h) (((int)(_d)^(int)(_h))&(BLKIF_HASHSZ-1)) +#include +#include static kmem_cache_t *blkif_cachep; -static blkif_t *blkif_hash[BLKIF_HASHSZ]; -blkif_t *blkif_find_by_handle(domid_t domid, unsigned int handle) +blkif_t *blkif_alloc(domid_t domid) { - blkif_t *blkif = blkif_hash[BLKIF_HASH(domid, handle)]; - while ( (blkif != NULL) && - ((blkif->domid != domid) || (blkif->handle != handle)) ) - blkif = blkif->hash_next; - return blkif; -} + blkif_t *blkif; -static void __blkif_disconnect_complete(void *arg) -{ - blkif_t *blkif = (blkif_t *)arg; - ctrl_msg_t cmsg; - blkif_be_disconnect_t disc; - - /* - * These can't be done in blkif_disconnect() because at that point there - * may be outstanding requests at the disc whose asynchronous responses - * must still be notified to the remote driver. - */ - unbind_evtchn_from_irq(blkif->evtchn); - vfree(blkif->blk_ring.sring); - - /* Construct the deferred response message. */ - cmsg.type = CMSG_BLKIF_BE; - cmsg.subtype = CMSG_BLKIF_BE_DISCONNECT; - cmsg.id = blkif->disconnect_rspid; - cmsg.length = sizeof(blkif_be_disconnect_t); - disc.domid = blkif->domid; - disc.blkif_handle = blkif->handle; - disc.status = BLKIF_BE_STATUS_OKAY; - memcpy(cmsg.msg, &disc, sizeof(disc)); - - /* - * Make sure message is constructed /before/ status change, because - * after the status change the 'blkif' structure could be deallocated at - * any time. Also make sure we send the response /after/ status change, - * as otherwise a subsequent CONNECT request could spuriously fail if - * another CPU doesn't see the status change yet. - */ - mb(); - if ( blkif->status != DISCONNECTING ) - BUG(); - blkif->status = DISCONNECTED; - mb(); - - /* Send the successful response. */ - ctrl_if_send_response(&cmsg); + blkif = kmem_cache_alloc(blkif_cachep, GFP_KERNEL); + if (!blkif) + return ERR_PTR(-ENOMEM); + + memset(blkif, 0, sizeof(*blkif)); + blkif->domid = domid; + spin_lock_init(&blkif->blk_ring_lock); + atomic_set(&blkif->refcnt, 1); + init_waitqueue_head(&blkif->wq); + blkif->st_print = jiffies; + init_waitqueue_head(&blkif->waiting_to_free); + + return blkif; } -void blkif_disconnect_complete(blkif_t *blkif) +static int map_frontend_page(blkif_t *blkif, unsigned long shared_page) { - INIT_WORK(&blkif->work, __blkif_disconnect_complete, (void *)blkif); - schedule_work(&blkif->work); + struct gnttab_map_grant_ref op; + int ret; + + gnttab_set_map_op(&op, (unsigned long)blkif->blk_ring_area->addr, + GNTMAP_host_map, shared_page, blkif->domid); + + lock_vm_area(blkif->blk_ring_area); + ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1); + unlock_vm_area(blkif->blk_ring_area); + BUG_ON(ret); + + if (op.status) { + DPRINTK(" Grant table operation failure !\n"); + return op.status; + } + + blkif->shmem_ref = shared_page; + blkif->shmem_handle = op.handle; + + return 0; } -void blkif_create(blkif_be_create_t *create) +static void unmap_frontend_page(blkif_t *blkif) { - domid_t domid = create->domid; - unsigned int handle = create->blkif_handle; - blkif_t **pblkif, *blkif; - - if ( (blkif = kmem_cache_alloc(blkif_cachep, GFP_KERNEL)) == NULL ) - { - DPRINTK("Could not create blkif: out of memory\n"); - create->status = BLKIF_BE_STATUS_OUT_OF_MEMORY; - return; - } - - memset(blkif, 0, sizeof(*blkif)); - blkif->domid = domid; - blkif->handle = handle; - blkif->status = DISCONNECTED; - spin_lock_init(&blkif->vbd_lock); - spin_lock_init(&blkif->blk_ring_lock); - atomic_set(&blkif->refcnt, 0); - - pblkif = &blkif_hash[BLKIF_HASH(domid, handle)]; - while ( *pblkif != NULL ) - { - if ( ((*pblkif)->domid == domid) && ((*pblkif)->handle == handle) ) - { - DPRINTK("Could not create blkif: already exists\n"); - create->status = BLKIF_BE_STATUS_INTERFACE_EXISTS; - kmem_cache_free(blkif_cachep, blkif); - return; - } - pblkif = &(*pblkif)->hash_next; - } - - blkif->hash_next = *pblkif; - *pblkif = blkif; - - DPRINTK("Successfully created blkif\n"); - create->status = BLKIF_BE_STATUS_OKAY; + struct gnttab_unmap_grant_ref op; + int ret; + + gnttab_set_unmap_op(&op, (unsigned long)blkif->blk_ring_area->addr, + GNTMAP_host_map, blkif->shmem_handle); + + lock_vm_area(blkif->blk_ring_area); + ret = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1); + unlock_vm_area(blkif->blk_ring_area); + BUG_ON(ret); } -void blkif_destroy(blkif_be_destroy_t *destroy) +int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn) { - domid_t domid = destroy->domid; - unsigned int handle = destroy->blkif_handle; - blkif_t **pblkif, *blkif; - - pblkif = &blkif_hash[BLKIF_HASH(domid, handle)]; - while ( (blkif = *pblkif) != NULL ) - { - if ( (blkif->domid == domid) && (blkif->handle == handle) ) - { - if ( blkif->status != DISCONNECTED ) - goto still_connected; - goto destroy; - } - pblkif = &blkif->hash_next; - } - - destroy->status = BLKIF_BE_STATUS_INTERFACE_NOT_FOUND; - return; - - still_connected: - destroy->status = BLKIF_BE_STATUS_INTERFACE_CONNECTED; - return; - - destroy: - *pblkif = blkif->hash_next; - destroy_all_vbds(blkif); - kmem_cache_free(blkif_cachep, blkif); - destroy->status = BLKIF_BE_STATUS_OKAY; + blkif_sring_t *sring; + int err; + struct evtchn_bind_interdomain bind_interdomain; + + /* Already connected through? */ + if (blkif->irq) + return 0; + + if ( (blkif->blk_ring_area = alloc_vm_area(PAGE_SIZE)) == NULL ) + return -ENOMEM; + + err = map_frontend_page(blkif, shared_page); + if (err) { + free_vm_area(blkif->blk_ring_area); + return err; + } + + bind_interdomain.remote_dom = blkif->domid; + bind_interdomain.remote_port = evtchn; + + err = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain, + &bind_interdomain); + if (err) { + unmap_frontend_page(blkif); + free_vm_area(blkif->blk_ring_area); + return err; + } + + blkif->evtchn = bind_interdomain.local_port; + + sring = (blkif_sring_t *)blkif->blk_ring_area->addr; + BACK_RING_INIT(&blkif->blk_ring, sring, PAGE_SIZE); + + blkif->irq = bind_evtchn_to_irqhandler( + blkif->evtchn, blkif_be_int, 0, "blkif-backend", blkif); + + return 0; } -void blkif_connect(blkif_be_connect_t *connect) +void blkif_disconnect(blkif_t *blkif) { - domid_t domid = connect->domid; - unsigned int handle = connect->blkif_handle; - unsigned int evtchn = connect->evtchn; - unsigned long shmem_frame = connect->shmem_frame; - struct vm_struct *vma; - pgprot_t prot; - int error; - blkif_t *blkif; - blkif_sring_t *sring; - - blkif = blkif_find_by_handle(domid, handle); - if ( unlikely(blkif == NULL) ) - { - DPRINTK("blkif_connect attempted for non-existent blkif (%u,%u)\n", - connect->domid, connect->blkif_handle); - connect->status = BLKIF_BE_STATUS_INTERFACE_NOT_FOUND; - return; - } - - if ( (vma = get_vm_area(PAGE_SIZE, VM_IOREMAP)) == NULL ) - { - connect->status = BLKIF_BE_STATUS_OUT_OF_MEMORY; - return; - } - - prot = __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED); - error = direct_remap_area_pages(&init_mm, VMALLOC_VMADDR(vma->addr), - shmem_frame<status = BLKIF_BE_STATUS_OUT_OF_MEMORY; - else if ( error == -EFAULT ) - connect->status = BLKIF_BE_STATUS_MAPPING_ERROR; - else - connect->status = BLKIF_BE_STATUS_ERROR; - vfree(vma->addr); - return; - } - - if ( blkif->status != DISCONNECTED ) - { - connect->status = BLKIF_BE_STATUS_INTERFACE_CONNECTED; - vfree(vma->addr); - return; - } - sring = (blkif_sring_t *)vma->addr; - SHARED_RING_INIT(sring); - BACK_RING_INIT(&blkif->blk_ring, sring, PAGE_SIZE); - - blkif->evtchn = evtchn; - blkif->irq = bind_evtchn_to_irq(evtchn); - blkif->shmem_frame = shmem_frame; - blkif->status = CONNECTED; - blkif_get(blkif); - - request_irq(blkif->irq, blkif_be_int, 0, "blkif-backend", blkif); - - connect->status = BLKIF_BE_STATUS_OKAY; + if (blkif->xenblkd) { + kthread_stop(blkif->xenblkd); + blkif->xenblkd = NULL; + } + + atomic_dec(&blkif->refcnt); + wait_event(blkif->waiting_to_free, atomic_read(&blkif->refcnt) == 0); + atomic_inc(&blkif->refcnt); + + if (blkif->irq) { + unbind_from_irqhandler(blkif->irq, blkif); + blkif->irq = 0; + } + + if (blkif->blk_ring.sring) { + unmap_frontend_page(blkif); + free_vm_area(blkif->blk_ring_area); + blkif->blk_ring.sring = NULL; + } } -int blkif_disconnect(blkif_be_disconnect_t *disconnect, u8 rsp_id) +void blkif_free(blkif_t *blkif) { - domid_t domid = disconnect->domid; - unsigned int handle = disconnect->blkif_handle; - blkif_t *blkif; - - blkif = blkif_find_by_handle(domid, handle); - if ( unlikely(blkif == NULL) ) - { - DPRINTK("blkif_disconnect attempted for non-existent blkif" - " (%u,%u)\n", disconnect->domid, disconnect->blkif_handle); - disconnect->status = BLKIF_BE_STATUS_INTERFACE_NOT_FOUND; - return 1; /* Caller will send response error message. */ - } - - if ( blkif->status == CONNECTED ) - { - blkif->status = DISCONNECTING; - blkif->disconnect_rspid = rsp_id; - wmb(); /* Let other CPUs see the status change. */ - free_irq(blkif->irq, blkif); - blkif_deschedule(blkif); - blkif_put(blkif); - return 0; /* Caller should not send response message. */ - } - - disconnect->status = BLKIF_BE_STATUS_OKAY; - return 1; + if (!atomic_dec_and_test(&blkif->refcnt)) + BUG(); + kmem_cache_free(blkif_cachep, blkif); } void __init blkif_interface_init(void) { - blkif_cachep = kmem_cache_create("blkif_cache", sizeof(blkif_t), - 0, 0, NULL, NULL); - memset(blkif_hash, 0, sizeof(blkif_hash)); + blkif_cachep = kmem_cache_create("blkif_cache", sizeof(blkif_t), + 0, 0, NULL, NULL); } diff --git a/drivers/xen/blkback/vbd.c b/drivers/xen/blkback/vbd.c index f5ee589ee..a809b04cd 100644 --- a/drivers/xen/blkback/vbd.c +++ b/drivers/xen/blkback/vbd.c @@ -3,285 +3,117 @@ * * Routines for managing virtual block devices (VBDs). * - * NOTE: vbd_lock protects updates to the rb_tree against concurrent lookups - * in vbd_translate. All other lookups are implicitly protected because the - * only caller (the control message dispatch routine) serializes the calls. - * * Copyright (c) 2003-2005, Keir Fraser & Steve Hand + * + * 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; or, when distributed + * separately from the Linux kernel or incorporated into other + * software packages, subject to the following license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this source file (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, modify, + * merge, publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. */ #include "common.h" +#include -struct vbd { - blkif_vdev_t vdevice; /* what the domain refers to this vbd as */ - unsigned char readonly; /* Non-zero -> read-only */ - unsigned char type; /* VDISK_TYPE_xxx */ - blkif_pdev_t pdevice; /* phys device that this vbd maps to */ - struct block_device *bdev; - rb_node_t rb; /* for linking into R-B tree lookup struct */ -}; +#define vbd_sz(_v) ((_v)->bdev->bd_part ? \ + (_v)->bdev->bd_part->nr_sects : (_v)->bdev->bd_disk->capacity) -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) -static inline dev_t vbd_map_devnum(blkif_pdev_t cookie) -{ return MKDEV(cookie>>8, cookie&0xff); } -#define vbd_sz(_v) ((_v)->bdev->bd_part ? \ - (_v)->bdev->bd_part->nr_sects : (_v)->bdev->bd_disk->capacity) -#define bdev_put(_b) blkdev_put(_b) -#else -#define vbd_sz(_v) (blk_size[MAJOR((_v)->pdevice)][MINOR((_v)->pdevice)]*2) -#define bdev_put(_b) ((void)0) -#endif - -void vbd_create(blkif_be_vbd_create_t *create) +unsigned long vbd_size(struct vbd *vbd) { - struct vbd *vbd; - rb_node_t **rb_p, *rb_parent = NULL; - blkif_t *blkif; - blkif_vdev_t vdevice = create->vdevice; - - blkif = blkif_find_by_handle(create->domid, create->blkif_handle); - if ( unlikely(blkif == NULL) ) - { - DPRINTK("vbd_create attempted for non-existent blkif (%u,%u)\n", - create->domid, create->blkif_handle); - create->status = BLKIF_BE_STATUS_INTERFACE_NOT_FOUND; - return; - } - - rb_p = &blkif->vbd_rb.rb_node; - while ( *rb_p != NULL ) - { - rb_parent = *rb_p; - vbd = rb_entry(rb_parent, struct vbd, rb); - if ( vdevice < vbd->vdevice ) - { - rb_p = &rb_parent->rb_left; - } - else if ( vdevice > vbd->vdevice ) - { - rb_p = &rb_parent->rb_right; - } - else - { - DPRINTK("vbd_create attempted for already existing vbd\n"); - create->status = BLKIF_BE_STATUS_VBD_EXISTS; - return; - } - } - - if ( unlikely((vbd = kmalloc(sizeof(struct vbd), GFP_KERNEL)) == NULL) ) - { - DPRINTK("vbd_create: out of memory\n"); - create->status = BLKIF_BE_STATUS_OUT_OF_MEMORY; - return; - } - - vbd->vdevice = vdevice; - vbd->readonly = create->readonly; - vbd->type = VDISK_TYPE_DISK | VDISK_FLAG_VIRT; - - /* Mask to 16-bit for compatibility with old tools */ - vbd->pdevice = create->pdevice & 0xffff; - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) - vbd->bdev = open_by_devnum( - vbd_map_devnum(vbd->pdevice), - vbd->readonly ? FMODE_READ : FMODE_WRITE); - if ( IS_ERR(vbd->bdev) ) - { - DPRINTK("vbd_creat: device %08x doesn't exist.\n", vbd->pdevice); - create->status = BLKIF_BE_STATUS_PHYSDEV_NOT_FOUND; - return; - } - - if ( (vbd->bdev->bd_disk == NULL) ) - { - DPRINTK("vbd_creat: device %08x doesn't exist.\n", vbd->pdevice); - create->status = BLKIF_BE_STATUS_PHYSDEV_NOT_FOUND; - bdev_put(vbd->bdev); - return; - } -#else - if ( (blk_size[MAJOR(vbd->pdevice)] == NULL) || (vbd_sz(vbd) == 0) ) - { - DPRINTK("vbd_creat: device %08x doesn't exist.\n", vbd->pdevice); - create->status = BLKIF_BE_STATUS_PHYSDEV_NOT_FOUND; - return; - } -#endif - - spin_lock(&blkif->vbd_lock); - rb_link_node(&vbd->rb, rb_parent, rb_p); - rb_insert_color(&vbd->rb, &blkif->vbd_rb); - spin_unlock(&blkif->vbd_lock); - - DPRINTK("Successful creation of vdev=%04x (dom=%u)\n", - vdevice, create->domid); - create->status = BLKIF_BE_STATUS_OKAY; + return vbd_sz(vbd); } - -void vbd_destroy(blkif_be_vbd_destroy_t *destroy) +unsigned int vbd_info(struct vbd *vbd) { - blkif_t *blkif; - struct vbd *vbd; - rb_node_t *rb; - blkif_vdev_t vdevice = destroy->vdevice; - - blkif = blkif_find_by_handle(destroy->domid, destroy->blkif_handle); - if ( unlikely(blkif == NULL) ) - { - DPRINTK("vbd_destroy attempted for non-existent blkif (%u,%u)\n", - destroy->domid, destroy->blkif_handle); - destroy->status = BLKIF_BE_STATUS_INTERFACE_NOT_FOUND; - return; - } - - rb = blkif->vbd_rb.rb_node; - while ( rb != NULL ) - { - vbd = rb_entry(rb, struct vbd, rb); - if ( vdevice < vbd->vdevice ) - rb = rb->rb_left; - else if ( vdevice > vbd->vdevice ) - rb = rb->rb_right; - else - goto found; - } - - destroy->status = BLKIF_BE_STATUS_VBD_NOT_FOUND; - return; - - found: - spin_lock(&blkif->vbd_lock); - rb_erase(rb, &blkif->vbd_rb); - spin_unlock(&blkif->vbd_lock); - bdev_put(vbd->bdev); - kfree(vbd); + return vbd->type | (vbd->readonly?VDISK_READONLY:0); } - -void destroy_all_vbds(blkif_t *blkif) +unsigned long vbd_secsize(struct vbd *vbd) { - struct vbd *vbd; - rb_node_t *rb; - - spin_lock(&blkif->vbd_lock); - - while ( (rb = blkif->vbd_rb.rb_node) != NULL ) - { - vbd = rb_entry(rb, struct vbd, rb); - rb_erase(rb, &blkif->vbd_rb); - spin_unlock(&blkif->vbd_lock); - bdev_put(vbd->bdev); - kfree(vbd); - spin_lock(&blkif->vbd_lock); - } - - spin_unlock(&blkif->vbd_lock); + return bdev_hardsect_size(vbd->bdev); } - -static void vbd_probe_single( - blkif_t *blkif, vdisk_t *vbd_info, struct vbd *vbd) +int vbd_create(blkif_t *blkif, blkif_vdev_t handle, unsigned major, + unsigned minor, int readonly) { - vbd_info->device = vbd->vdevice; - vbd_info->info = vbd->type | (vbd->readonly ? VDISK_FLAG_RO : 0); - vbd_info->capacity = vbd_sz(vbd); + struct vbd *vbd; + struct block_device *bdev; + + vbd = &blkif->vbd; + vbd->handle = handle; + vbd->readonly = readonly; + vbd->type = 0; + + vbd->pdevice = MKDEV(major, minor); + + bdev = open_by_devnum(vbd->pdevice, + vbd->readonly ? FMODE_READ : FMODE_WRITE); + + if (IS_ERR(bdev)) { + DPRINTK("vbd_creat: device %08x could not be opened.\n", + vbd->pdevice); + return -ENOENT; + } + + vbd->bdev = bdev; + + if (vbd->bdev->bd_disk == NULL) { + DPRINTK("vbd_creat: device %08x doesn't exist.\n", + vbd->pdevice); + vbd_free(vbd); + return -ENOENT; + } + + if (vbd->bdev->bd_disk->flags & GENHD_FL_CD) + vbd->type |= VDISK_CDROM; + if (vbd->bdev->bd_disk->flags & GENHD_FL_REMOVABLE) + vbd->type |= VDISK_REMOVABLE; + + DPRINTK("Successful creation of handle=%04x (dom=%u)\n", + handle, blkif->domid); + return 0; } - -int vbd_probe(blkif_t *blkif, vdisk_t *vbd_info, int max_vbds) +void vbd_free(struct vbd *vbd) { - int rc = 0, nr_vbds = 0; - rb_node_t *rb; - - spin_lock(&blkif->vbd_lock); - - if ( (rb = blkif->vbd_rb.rb_node) == NULL ) - goto out; - - new_subtree: - /* STEP 1. Find least node (it'll be left-most). */ - while ( rb->rb_left != NULL ) - rb = rb->rb_left; - - for ( ; ; ) - { - /* STEP 2. Dealt with left subtree. Now process current node. */ - vbd_probe_single(blkif, &vbd_info[nr_vbds], - rb_entry(rb, struct vbd, rb)); - if ( ++nr_vbds == max_vbds ) - goto out; - - /* STEP 3. Process right subtree, if any. */ - if ( rb->rb_right != NULL ) - { - rb = rb->rb_right; - goto new_subtree; - } - - /* STEP 4. Done both subtrees. Head back through ancesstors. */ - for ( ; ; ) - { - /* We're done when we get back to the root node. */ - if ( rb->rb_parent == NULL ) - goto out; - /* If we are left of parent, then parent is next to process. */ - if ( rb->rb_parent->rb_left == rb ) - break; - /* If we are right of parent, then we climb to grandparent. */ - rb = rb->rb_parent; - } - - rb = rb->rb_parent; - } - - out: - spin_unlock(&blkif->vbd_lock); - return (rc == 0) ? nr_vbds : rc; + if (vbd->bdev) + blkdev_put(vbd->bdev); + vbd->bdev = NULL; } - int vbd_translate(struct phys_req *req, blkif_t *blkif, int operation) { - struct vbd *vbd; - rb_node_t *rb; - int rc = -EACCES; - - /* Take the vbd_lock because another thread could be updating the tree. */ - spin_lock(&blkif->vbd_lock); - - rb = blkif->vbd_rb.rb_node; - while ( rb != NULL ) - { - vbd = rb_entry(rb, struct vbd, rb); - if ( req->dev < vbd->vdevice ) - rb = rb->rb_left; - else if ( req->dev > vbd->vdevice ) - rb = rb->rb_right; - else - goto found; - } - - DPRINTK("vbd_translate; domain %u attempted to access " - "non-existent VBD.\n", blkif->domid); - rc = -ENODEV; - goto out; - - found: + struct vbd *vbd = &blkif->vbd; + int rc = -EACCES; - if ( (operation == WRITE) && vbd->readonly ) - goto out; + if ((operation == WRITE) && vbd->readonly) + goto out; - if ( unlikely((req->sector_number + req->nr_sects) > vbd_sz(vbd)) ) - goto out; + if (unlikely((req->sector_number + req->nr_sects) > vbd_sz(vbd))) + goto out; - req->dev = vbd->pdevice; - req->bdev = vbd->bdev; - rc = 0; + req->dev = vbd->pdevice; + req->bdev = vbd->bdev; + rc = 0; out: - spin_unlock(&blkif->vbd_lock); - return rc; + return rc; } diff --git a/drivers/xen/blkfront/Makefile b/drivers/xen/blkfront/Makefile index 5d1707dd7..182ef6531 100644 --- a/drivers/xen/blkfront/Makefile +++ b/drivers/xen/blkfront/Makefile @@ -1,3 +1,5 @@ -obj-y := blkfront.o vbd.o +obj-$(CONFIG_XEN_BLKDEV_FRONTEND) := xenblk.o + +xenblk-objs := blkfront.o vbd.o diff --git a/drivers/xen/blkfront/blkfront.c b/drivers/xen/blkfront/blkfront.c index 311b8398e..a911c766a 100644 --- a/drivers/xen/blkfront/blkfront.c +++ b/drivers/xen/blkfront/blkfront.c @@ -8,9 +8,13 @@ * Copyright (c) 2004, Christian Limpach * Copyright (c) 2004, Andrew Warfield * Copyright (c) 2005, Christopher Clark + * Copyright (c) 2005, XenSource Ltd * - * This file may be distributed separately from the Linux kernel, or - * incorporated into other software packages, subject to the following license: + * 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; or, when distributed + * separately from the Linux kernel or incorporated into other + * software packages, subject to the following license: * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this source file (the "Software"), to deal in the Software without @@ -31,1450 +35,807 @@ * IN THE SOFTWARE. */ -#if 1 -#define ASSERT(_p) \ - if ( !(_p) ) { printk("Assertion '%s' failed, line %d, file %s", #_p , \ - __LINE__, __FILE__); *(int*)0=0; } -#else -#define ASSERT(_p) -#endif - #include - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) #include "block.h" -#else -#include "common.h" -#include -#include -#endif - #include #include #include #include -#include -#include -#ifdef CONFIG_XEN_BLKDEV_GRANT -#include -#include -#endif - -typedef unsigned char byte; /* from linux/ide.h */ +#include +#include +#include +#include +#include -/* Control whether runtime update of vbds is enabled. */ -#define ENABLE_VBD_UPDATE 1 +#define BLKIF_STATE_DISCONNECTED 0 +#define BLKIF_STATE_CONNECTED 1 +#define BLKIF_STATE_SUSPENDED 2 -#if ENABLE_VBD_UPDATE -static void vbd_update(void); -#else -static void vbd_update(void){}; -#endif +#define MAXIMUM_OUTSTANDING_BLOCK_REQS \ + (BLKIF_MAX_SEGMENTS_PER_REQUEST * BLK_RING_SIZE) +#define GRANT_INVALID_REF 0 -#define BLKIF_STATE_CLOSED 0 -#define BLKIF_STATE_DISCONNECTED 1 -#define BLKIF_STATE_CONNECTED 2 +static void connect(struct blkfront_info *); +static void blkfront_closing(struct xenbus_device *); +static int blkfront_remove(struct xenbus_device *); +static int talk_to_backend(struct xenbus_device *, struct blkfront_info *); +static int setup_blkring(struct xenbus_device *, struct blkfront_info *); -#define WPRINTK(fmt, args...) printk(KERN_WARNING "xen_blk: " fmt, ##args) +static void kick_pending_request_queues(struct blkfront_info *); -static int blkif_handle = 0; -static unsigned int blkif_state = BLKIF_STATE_CLOSED; -static unsigned int blkif_evtchn = 0; -static unsigned int blkif_irq = 0; +static irqreturn_t blkif_int(int irq, void *dev_id, struct pt_regs *ptregs); +static void blkif_restart_queue(void *arg); +static void blkif_recover(struct blkfront_info *); +static void blkif_completion(struct blk_shadow *); +static void blkif_free(struct blkfront_info *, int); -static int blkif_control_rsp_valid; -static blkif_response_t blkif_control_rsp; -static blkif_front_ring_t blk_ring; +/** + * Entry point to this code when a new device is created. Allocate the basic + * structures and the ring buffer for communication with the backend, and + * inform the backend of the appropriate details for those. Switch to + * Initialised state. + */ +static int blkfront_probe(struct xenbus_device *dev, + const struct xenbus_device_id *id) +{ + int err, vdevice, i; + struct blkfront_info *info; + + /* FIXME: Use dynamic device id if this is not set. */ + err = xenbus_scanf(XBT_NIL, dev->nodename, + "virtual-device", "%i", &vdevice); + if (err != 1) { + xenbus_dev_fatal(dev, err, "reading virtual-device"); + return err; + } + + info = kzalloc(sizeof(*info), GFP_KERNEL); + if (!info) { + xenbus_dev_fatal(dev, -ENOMEM, "allocating info structure"); + return -ENOMEM; + } + + info->xbdev = dev; + info->vdevice = vdevice; + info->connected = BLKIF_STATE_DISCONNECTED; + INIT_WORK(&info->work, blkif_restart_queue, (void *)info); + + for (i = 0; i < BLK_RING_SIZE; i++) + info->shadow[i].req.id = i+1; + info->shadow[BLK_RING_SIZE-1].req.id = 0x0fffffff; + + /* Front end dir is a number, which is used as the id. */ + info->handle = simple_strtoul(strrchr(dev->nodename,'/')+1, NULL, 0); + dev->dev.driver_data = info; + + err = talk_to_backend(dev, info); + if (err) { + kfree(info); + dev->dev.driver_data = NULL; + return err; + } + + return 0; +} + + +/** + * We are reconnecting to the backend, due to a suspend/resume, or a backend + * driver restart. We tear down our blkif structure and recreate it, but + * leave the device-layer structures intact so that this is transparent to the + * rest of the kernel. + */ +static int blkfront_resume(struct xenbus_device *dev) +{ + struct blkfront_info *info = dev->dev.driver_data; + int err; + + DPRINTK("blkfront_resume: %s\n", dev->nodename); + + blkif_free(info, 1); + + err = talk_to_backend(dev, info); + if (!err) + blkif_recover(info); + + return err; +} + + +/* Common code used when first setting up, and when resuming. */ +static int talk_to_backend(struct xenbus_device *dev, + struct blkfront_info *info) +{ + const char *message = NULL; + struct xenbus_transaction xbt; + int err; + + /* Create shared ring, alloc event channel. */ + err = setup_blkring(dev, info); + if (err) + goto out; + +again: + err = xenbus_transaction_start(&xbt); + if (err) { + xenbus_dev_fatal(dev, err, "starting transaction"); + goto destroy_blkring; + } + + err = xenbus_printf(xbt, dev->nodename, + "ring-ref","%u", info->ring_ref); + if (err) { + message = "writing ring-ref"; + goto abort_transaction; + } + err = xenbus_printf(xbt, dev->nodename, + "event-channel", "%u", info->evtchn); + if (err) { + message = "writing event-channel"; + goto abort_transaction; + } + + err = xenbus_transaction_end(xbt, 0); + if (err) { + if (err == -EAGAIN) + goto again; + xenbus_dev_fatal(dev, err, "completing transaction"); + goto destroy_blkring; + } + + xenbus_switch_state(dev, XenbusStateInitialised); + + return 0; + + abort_transaction: + xenbus_transaction_end(xbt, 1); + if (message) + xenbus_dev_fatal(dev, err, "%s", message); + destroy_blkring: + blkif_free(info, 0); + out: + return err; +} -#define BLK_RING_SIZE __RING_SIZE((blkif_sring_t *)0, PAGE_SIZE) -#ifdef CONFIG_XEN_BLKDEV_GRANT -static domid_t rdomid = 0; -static grant_ref_t gref_head, gref_terminal; -#define MAXIMUM_OUTSTANDING_BLOCK_REQS \ - (BLKIF_MAX_SEGMENTS_PER_REQUEST * BLKIF_RING_SIZE) -#define GRANTREF_INVALID (1<<15) -#endif +static int setup_blkring(struct xenbus_device *dev, + struct blkfront_info *info) +{ + blkif_sring_t *sring; + int err; -static struct blk_shadow { - blkif_request_t req; - unsigned long request; - unsigned long frame[BLKIF_MAX_SEGMENTS_PER_REQUEST]; -} blk_shadow[BLK_RING_SIZE]; -unsigned long blk_shadow_free; + info->ring_ref = GRANT_INVALID_REF; -static int recovery = 0; /* Recovery in progress: protected by blkif_io_lock */ + sring = (blkif_sring_t *)__get_free_page(GFP_KERNEL); + if (!sring) { + xenbus_dev_fatal(dev, -ENOMEM, "allocating shared ring"); + return -ENOMEM; + } + SHARED_RING_INIT(sring); + FRONT_RING_INIT(&info->ring, sring, PAGE_SIZE); -static void kick_pending_request_queues(void); + err = xenbus_grant_ring(dev, virt_to_mfn(info->ring.sring)); + if (err < 0) { + free_page((unsigned long)sring); + info->ring.sring = NULL; + goto fail; + } + info->ring_ref = err; -int __init xlblk_init(void); + err = xenbus_alloc_evtchn(dev, &info->evtchn); + if (err) + goto fail; -static void blkif_completion(struct blk_shadow *s); + err = bind_evtchn_to_irqhandler( + info->evtchn, blkif_int, SA_SAMPLE_RANDOM, "blkif", info); + if (err <= 0) { + xenbus_dev_fatal(dev, err, + "bind_evtchn_to_irqhandler failed"); + goto fail; + } + info->irq = err; -static inline int GET_ID_FROM_FREELIST(void) -{ - unsigned long free = blk_shadow_free; - BUG_ON(free > BLK_RING_SIZE); - blk_shadow_free = blk_shadow[free].req.id; - blk_shadow[free].req.id = 0x0fffffee; /* debug */ - return free; + return 0; +fail: + blkif_free(info, 0); + return err; } -static inline void ADD_ID_TO_FREELIST(unsigned long id) + +/** + * Callback received when the backend's state changes. + */ +static void backend_changed(struct xenbus_device *dev, + enum xenbus_state backend_state) { - blk_shadow[id].req.id = blk_shadow_free; - blk_shadow[id].request = 0; - blk_shadow_free = id; -} + struct blkfront_info *info = dev->dev.driver_data; + struct block_device *bd; + DPRINTK("blkfront:backend_changed.\n"); -/************************ COMMON CODE (inlined) ************************/ + switch (backend_state) { + case XenbusStateUnknown: + case XenbusStateInitialising: + case XenbusStateInitWait: + case XenbusStateInitialised: + case XenbusStateClosed: + break; -/* Kernel-specific definitions used in the common code */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) -#define DISABLE_SCATTERGATHER() -#else -static int sg_operation = -1; -#define DISABLE_SCATTERGATHER() (sg_operation = -1) -#endif + case XenbusStateConnected: + connect(info); + break; -static inline void pickle_request(struct blk_shadow *s, blkif_request_t *r) -{ -#ifndef CONFIG_XEN_BLKDEV_GRANT - int i; -#endif + case XenbusStateClosing: + bd = bdget(info->dev); + if (bd == NULL) + xenbus_dev_fatal(dev, -ENODEV, "bdget failed"); - s->req = *r; - -#ifndef CONFIG_XEN_BLKDEV_GRANT - for ( i = 0; i < r->nr_segments; i++ ) - s->req.frame_and_sects[i] = machine_to_phys(r->frame_and_sects[i]); -#endif + mutex_lock(&bd->bd_mutex); + if (info->users > 0) + xenbus_dev_error(dev, -EBUSY, + "Device in use; refusing to close"); + else + blkfront_closing(dev); + mutex_unlock(&bd->bd_mutex); + bdput(bd); + break; + } } -static inline void unpickle_request(blkif_request_t *r, struct blk_shadow *s) -{ -#ifndef CONFIG_XEN_BLKDEV_GRANT - int i; -#endif - - *r = s->req; -#ifndef CONFIG_XEN_BLKDEV_GRANT - for ( i = 0; i < s->req.nr_segments; i++ ) - r->frame_and_sects[i] = phys_to_machine(s->req.frame_and_sects[i]); -#endif -} +/* ** Connection ** */ -static inline void flush_requests(void) +/* + * Invoked when the backend is finally 'ready' (and has told produced + * the details about the physical device - #sectors, size, etc). + */ +static void connect(struct blkfront_info *info) +{ + unsigned long sectors, sector_size; + unsigned int binfo; + int err; + + if ((info->connected == BLKIF_STATE_CONNECTED) || + (info->connected == BLKIF_STATE_SUSPENDED) ) + return; + + DPRINTK("blkfront.c:connect:%s.\n", info->xbdev->otherend); + + err = xenbus_gather(XBT_NIL, info->xbdev->otherend, + "sectors", "%lu", §ors, + "info", "%u", &binfo, + "sector-size", "%lu", §or_size, + NULL); + if (err) { + xenbus_dev_fatal(info->xbdev, err, + "reading backend fields at %s", + info->xbdev->otherend); + return; + } + + err = xlvbd_add(sectors, info->vdevice, binfo, sector_size, info); + if (err) { + xenbus_dev_fatal(info->xbdev, err, "xlvbd_add at %s", + info->xbdev->otherend); + return; + } + + (void)xenbus_switch_state(info->xbdev, XenbusStateConnected); + + /* Kick pending requests. */ + spin_lock_irq(&blkif_io_lock); + info->connected = BLKIF_STATE_CONNECTED; + kick_pending_request_queues(info); + spin_unlock_irq(&blkif_io_lock); + + add_disk(info->gd); +} + +/** + * Handle the change of state of the backend to Closing. We must delete our + * device-layer structures now, to ensure that writes are flushed through to + * the backend. Once is this done, we can switch to Closed in + * acknowledgement. + */ +static void blkfront_closing(struct xenbus_device *dev) { - DISABLE_SCATTERGATHER(); - RING_PUSH_REQUESTS(&blk_ring); - notify_via_evtchn(blkif_evtchn); -} + struct blkfront_info *info = dev->dev.driver_data; + unsigned long flags; + DPRINTK("blkfront_closing: %s removed\n", dev->nodename); -/************************** KERNEL VERSION 2.6 **************************/ + if (info->rq == NULL) + return; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + spin_lock_irqsave(&blkif_io_lock, flags); + /* No more blkif_request(). */ + blk_stop_queue(info->rq); + /* No more gnttab callback work. */ + gnttab_cancel_free_callback(&info->callback); + flush_scheduled_work(); + spin_unlock_irqrestore(&blkif_io_lock, flags); -module_init(xlblk_init); + xlvbd_del(info); -#if ENABLE_VBD_UPDATE -static void update_vbds_task(void *unused) -{ - xlvbd_update_vbds(); + xenbus_switch_state(dev, XenbusStateClosed); } -static void vbd_update(void) -{ - static DECLARE_WORK(update_tq, update_vbds_task, NULL); - schedule_work(&update_tq); -} -#endif /* ENABLE_VBD_UPDATE */ -static void kick_pending_request_queues(void) +static int blkfront_remove(struct xenbus_device *dev) { - if ( (xlbd_blk_queue != NULL) && - test_bit(QUEUE_FLAG_STOPPED, &xlbd_blk_queue->queue_flags) ) - { - blk_start_queue(xlbd_blk_queue); - /* XXXcl call to request_fn should not be needed but - * we get stuck without... needs investigating - */ - xlbd_blk_queue->request_fn(xlbd_blk_queue); - } -} + struct blkfront_info *info = dev->dev.driver_data; + DPRINTK("blkfront_remove: %s removed\n", dev->nodename); -int blkif_open(struct inode *inode, struct file *filep) -{ - struct gendisk *gd = inode->i_bdev->bd_disk; - struct xlbd_disk_info *di = (struct xlbd_disk_info *)gd->private_data; + blkif_free(info, 0); - /* Update of usage count is protected by per-device semaphore. */ - di->mi->usage++; - - return 0; -} + kfree(info); - -int blkif_release(struct inode *inode, struct file *filep) -{ - struct gendisk *gd = inode->i_bdev->bd_disk; - struct xlbd_disk_info *di = (struct xlbd_disk_info *)gd->private_data; - - /* - * When usage drops to zero it may allow more VBD updates to occur. - * Update of usage count is protected by a per-device semaphore. - */ - if ( --di->mi->usage == 0 ) - vbd_update(); - - return 0; + return 0; } -int blkif_ioctl(struct inode *inode, struct file *filep, - unsigned command, unsigned long argument) +static inline int GET_ID_FROM_FREELIST( + struct blkfront_info *info) { - int i; - - DPRINTK_IOCTL("command: 0x%x, argument: 0x%lx, dev: 0x%04x\n", - command, (long)argument, inode->i_rdev); - - switch ( command ) - { - case HDIO_GETGEO: - /* return ENOSYS to use defaults */ - return -ENOSYS; - - case CDROMMULTISESSION: - DPRINTK("FIXME: support multisession CDs later\n"); - for ( i = 0; i < sizeof(struct cdrom_multisession); i++ ) - if ( put_user(0, (byte *)(argument + i)) ) return -EFAULT; - return 0; - - default: - printk(KERN_ALERT "ioctl %08x not supported by Xen blkdev\n", - command); - return -ENOSYS; - } - - return 0; + unsigned long free = info->shadow_free; + BUG_ON(free > BLK_RING_SIZE); + info->shadow_free = info->shadow[free].req.id; + info->shadow[free].req.id = 0x0fffffee; /* debug */ + return free; } - -/* - * blkif_queue_request - * - * request block io - * - * id: for guest use only. - * operation: BLKIF_OP_{READ,WRITE,PROBE} - * buffer: buffer to read/write into. this should be a - * virtual address in the guest os. - */ -static int blkif_queue_request(struct request *req) +static inline void ADD_ID_TO_FREELIST( + struct blkfront_info *info, unsigned long id) { - struct xlbd_disk_info *di = - (struct xlbd_disk_info *)req->rq_disk->private_data; - unsigned long buffer_ma; - blkif_request_t *ring_req; - struct bio *bio; - struct bio_vec *bvec; - int idx; - unsigned long id; - unsigned int fsect, lsect; -#ifdef CONFIG_XEN_BLKDEV_GRANT - int ref; -#endif - - if ( unlikely(blkif_state != BLKIF_STATE_CONNECTED) ) - return 1; - - /* Fill out a communications ring structure. */ - ring_req = RING_GET_REQUEST(&blk_ring, blk_ring.req_prod_pvt); - id = GET_ID_FROM_FREELIST(); - blk_shadow[id].request = (unsigned long)req; - - ring_req->id = id; - ring_req->operation = rq_data_dir(req) ? BLKIF_OP_WRITE : - BLKIF_OP_READ; - ring_req->sector_number = (blkif_sector_t)req->sector; - ring_req->device = di->xd_device; - - ring_req->nr_segments = 0; - rq_for_each_bio(bio, req) - { - bio_for_each_segment(bvec, bio, idx) - { - if ( ring_req->nr_segments == BLKIF_MAX_SEGMENTS_PER_REQUEST ) - BUG(); - buffer_ma = page_to_phys(bvec->bv_page); - fsect = bvec->bv_offset >> 9; - lsect = fsect + (bvec->bv_len >> 9) - 1; -#ifdef CONFIG_XEN_BLKDEV_GRANT - /* install a grant reference. */ - ref = gnttab_claim_grant_reference(&gref_head, gref_terminal); - ASSERT( ref != -ENOSPC ); - - gnttab_grant_foreign_access_ref( - ref, - rdomid, - buffer_ma >> PAGE_SHIFT, - rq_data_dir(req) ); - - blk_shadow[id].frame[ring_req->nr_segments] = - buffer_ma >> PAGE_SHIFT; - - ring_req->frame_and_sects[ring_req->nr_segments++] = - (((u32) ref) << 16) | (fsect << 3) | lsect; - -#else - ring_req->frame_and_sects[ring_req->nr_segments++] = - buffer_ma | (fsect << 3) | lsect; -#endif - } - } - - blk_ring.req_prod_pvt++; - - /* Keep a private copy so we can reissue requests when recovering. */ - pickle_request(&blk_shadow[id], ring_req); - - return 0; + info->shadow[id].req.id = info->shadow_free; + info->shadow[id].request = 0; + info->shadow_free = id; } - -/* - * do_blkif_request - * read a block; request is in a request queue - */ -void do_blkif_request(request_queue_t *rq) +static inline void flush_requests(struct blkfront_info *info) { - struct request *req; - int queued; - - DPRINTK("Entered do_blkif_request\n"); - - queued = 0; - - while ( (req = elv_next_request(rq)) != NULL ) - { - if ( !blk_fs_request(req) ) - { - end_request(req, 0); - continue; - } - - if ( RING_FULL(&blk_ring) ) - { - blk_stop_queue(rq); - break; - } - - DPRINTK("do_blk_req %p: cmd %p, sec %lx, (%u/%li) buffer:%p [%s]\n", - req, req->cmd, req->sector, req->current_nr_sectors, - req->nr_sectors, req->buffer, - rq_data_dir(req) ? "write" : "read"); - - blkdev_dequeue_request(req); - if ( blkif_queue_request(req) ) - { - blk_stop_queue(rq); - break; - } - - queued++; - } - - if ( queued != 0 ) - flush_requests(); -} + int notify; + RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&info->ring, notify); -static irqreturn_t blkif_int(int irq, void *dev_id, struct pt_regs *ptregs) -{ - struct request *req; - blkif_response_t *bret; - RING_IDX i, rp; - unsigned long flags; - - spin_lock_irqsave(&blkif_io_lock, flags); - - if ( unlikely(blkif_state == BLKIF_STATE_CLOSED) || - unlikely(recovery) ) - { - spin_unlock_irqrestore(&blkif_io_lock, flags); - return IRQ_HANDLED; - } - - rp = blk_ring.sring->rsp_prod; - rmb(); /* Ensure we see queued responses up to 'rp'. */ - - for ( i = blk_ring.rsp_cons; i != rp; i++ ) - { - unsigned long id; - - bret = RING_GET_RESPONSE(&blk_ring, i); - id = bret->id; - req = (struct request *)blk_shadow[id].request; - - blkif_completion(&blk_shadow[id]); - - ADD_ID_TO_FREELIST(id); - - switch ( bret->operation ) - { - case BLKIF_OP_READ: - case BLKIF_OP_WRITE: - if ( unlikely(bret->status != BLKIF_RSP_OKAY) ) - DPRINTK("Bad return from blkdev data request: %x\n", - bret->status); - - if ( unlikely(end_that_request_first - (req, - (bret->status == BLKIF_RSP_OKAY), - req->hard_nr_sectors)) ) - BUG(); - end_that_request_last(req); - - break; - case BLKIF_OP_PROBE: - memcpy(&blkif_control_rsp, bret, sizeof(*bret)); - blkif_control_rsp_valid = 1; - break; - default: - BUG(); - } - } - - blk_ring.rsp_cons = i; - - kick_pending_request_queues(); - - spin_unlock_irqrestore(&blkif_io_lock, flags); - - return IRQ_HANDLED; + if (notify) + notify_remote_via_irq(info->irq); } -#else -/************************** KERNEL VERSION 2.4 **************************/ - -static kdev_t sg_dev; -static unsigned long sg_next_sect; - -/* - * Request queues with outstanding work, but ring is currently full. - * We need no special lock here, as we always access this with the - * blkif_io_lock held. We only need a small maximum list. - */ -#define MAX_PENDING 8 -static request_queue_t *pending_queues[MAX_PENDING]; -static int nr_pending; - - -#define blkif_io_lock io_request_lock - -/*============================================================================*/ -#if ENABLE_VBD_UPDATE - -/* - * blkif_update_int/update-vbds_task - handle VBD update events. - * Schedule a task for keventd to run, which will update the VBDs and perform - * the corresponding updates to our view of VBD state. - */ -static void update_vbds_task(void *unused) -{ - xlvbd_update_vbds(); +static void kick_pending_request_queues(struct blkfront_info *info) +{ + if (!RING_FULL(&info->ring)) { + /* Re-enable calldowns. */ + blk_start_queue(info->rq); + /* Kick things off immediately. */ + do_blkif_request(info->rq); + } } -static void vbd_update(void) +static void blkif_restart_queue(void *arg) { - static struct tq_struct update_tq; - update_tq.routine = update_vbds_task; - schedule_task(&update_tq); + struct blkfront_info *info = (struct blkfront_info *)arg; + spin_lock_irq(&blkif_io_lock); + if (info->connected == BLKIF_STATE_CONNECTED) + kick_pending_request_queues(info); + spin_unlock_irq(&blkif_io_lock); } -#endif /* ENABLE_VBD_UPDATE */ -/*============================================================================*/ - -static void kick_pending_request_queues(void) +static void blkif_restart_queue_callback(void *arg) { - /* We kick pending request queues if the ring is reasonably empty. */ - if ( (nr_pending != 0) && - (RING_PENDING_REQUESTS(&blk_ring) < (BLK_RING_SIZE >> 1)) ) - { - /* Attempt to drain the queue, but bail if the ring becomes full. */ - while ( (nr_pending != 0) && !RING_FULL(&blk_ring) ) - do_blkif_request(pending_queues[--nr_pending]); - } + struct blkfront_info *info = (struct blkfront_info *)arg; + schedule_work(&info->work); } int blkif_open(struct inode *inode, struct file *filep) { - short xldev = inode->i_rdev; - struct gendisk *gd = get_gendisk(xldev); - xl_disk_t *disk = xldev_to_xldisk(inode->i_rdev); - short minor = MINOR(xldev); - - if ( gd->part[minor].nr_sects == 0 ) - { - /* - * Device either doesn't exist, or has zero capacity; we use a few - * cheesy heuristics to return the relevant error code - */ - if ( (gd->sizes[minor >> gd->minor_shift] != 0) || - ((minor & (gd->max_p - 1)) != 0) ) - { - /* - * We have a real device, but no such partition, or we just have a - * partition number so guess this is the problem. - */ - return -ENXIO; /* no such device or address */ - } - else if ( gd->flags[minor >> gd->minor_shift] & GENHD_FL_REMOVABLE ) - { - /* This is a removable device => assume that media is missing. */ - return -ENOMEDIUM; /* media not present (this is a guess) */ - } - else - { - /* Just go for the general 'no such device' error. */ - return -ENODEV; /* no such device */ - } - } - - /* Update of usage count is protected by per-device semaphore. */ - disk->usage++; - - return 0; + struct blkfront_info *info = inode->i_bdev->bd_disk->private_data; + info->users++; + return 0; } int blkif_release(struct inode *inode, struct file *filep) { - xl_disk_t *disk = xldev_to_xldisk(inode->i_rdev); + struct blkfront_info *info = inode->i_bdev->bd_disk->private_data; + info->users--; + if (info->users == 0) { + /* Check whether we have been instructed to close. We will + have ignored this request initially, as the device was + still mounted. */ + struct xenbus_device * dev = info->xbdev; + enum xenbus_state state = xenbus_read_driver_state(dev->otherend); - /* - * When usage drops to zero it may allow more VBD updates to occur. - * Update of usage count is protected by a per-device semaphore. - */ - if ( --disk->usage == 0 ) { - vbd_update(); - } - - return 0; + if (state == XenbusStateClosing) + blkfront_closing(dev); + } + return 0; } int blkif_ioctl(struct inode *inode, struct file *filep, - unsigned command, unsigned long argument) + unsigned command, unsigned long argument) { - kdev_t dev = inode->i_rdev; - struct hd_geometry *geo = (struct hd_geometry *)argument; - struct gendisk *gd; - struct hd_struct *part; - int i; - unsigned short cylinders; - byte heads, sectors; - - /* NB. No need to check permissions. That is done for us. */ - - DPRINTK_IOCTL("command: 0x%x, argument: 0x%lx, dev: 0x%04x\n", - command, (long) argument, dev); - - gd = get_gendisk(dev); - part = &gd->part[MINOR(dev)]; - - switch ( command ) - { - case BLKGETSIZE: - DPRINTK_IOCTL(" BLKGETSIZE: %x %lx\n", BLKGETSIZE, part->nr_sects); - return put_user(part->nr_sects, (unsigned long *) argument); - - case BLKGETSIZE64: - DPRINTK_IOCTL(" BLKGETSIZE64: %x %llx\n", BLKGETSIZE64, - (u64)part->nr_sects * 512); - return put_user((u64)part->nr_sects * 512, (u64 *) argument); - - case BLKRRPART: /* re-read partition table */ - DPRINTK_IOCTL(" BLKRRPART: %x\n", BLKRRPART); - return blkif_revalidate(dev); - - case BLKSSZGET: - return hardsect_size[MAJOR(dev)][MINOR(dev)]; - - case BLKBSZGET: /* get block size */ - DPRINTK_IOCTL(" BLKBSZGET: %x\n", BLKBSZGET); - break; - - case BLKBSZSET: /* set block size */ - DPRINTK_IOCTL(" BLKBSZSET: %x\n", BLKBSZSET); - break; - - case BLKRASET: /* set read-ahead */ - DPRINTK_IOCTL(" BLKRASET: %x\n", BLKRASET); - break; - - case BLKRAGET: /* get read-ahead */ - DPRINTK_IOCTL(" BLKRAFET: %x\n", BLKRAGET); - break; - - case HDIO_GETGEO: - DPRINTK_IOCTL(" HDIO_GETGEO: %x\n", HDIO_GETGEO); - if (!argument) return -EINVAL; - - /* We don't have real geometry info, but let's at least return - values consistent with the size of the device */ - - heads = 0xff; - sectors = 0x3f; - cylinders = part->nr_sects / (heads * sectors); - - if (put_user(0x00, (unsigned long *) &geo->start)) return -EFAULT; - if (put_user(heads, (byte *)&geo->heads)) return -EFAULT; - if (put_user(sectors, (byte *)&geo->sectors)) return -EFAULT; - if (put_user(cylinders, (unsigned short *)&geo->cylinders)) return -EFAULT; - - return 0; - - case HDIO_GETGEO_BIG: - DPRINTK_IOCTL(" HDIO_GETGEO_BIG: %x\n", HDIO_GETGEO_BIG); - if (!argument) return -EINVAL; - - /* We don't have real geometry info, but let's at least return - values consistent with the size of the device */ - - heads = 0xff; - sectors = 0x3f; - cylinders = part->nr_sects / (heads * sectors); - - if (put_user(0x00, (unsigned long *) &geo->start)) return -EFAULT; - if (put_user(heads, (byte *)&geo->heads)) return -EFAULT; - if (put_user(sectors, (byte *)&geo->sectors)) return -EFAULT; - if (put_user(cylinders, (unsigned int *) &geo->cylinders)) return -EFAULT; - - return 0; - - case CDROMMULTISESSION: - DPRINTK("FIXME: support multisession CDs later\n"); - for ( i = 0; i < sizeof(struct cdrom_multisession); i++ ) - if ( put_user(0, (byte *)(argument + i)) ) return -EFAULT; - return 0; - - case SCSI_IOCTL_GET_BUS_NUMBER: - DPRINTK("FIXME: SCSI_IOCTL_GET_BUS_NUMBER ioctl in XL blkif"); - return -ENOSYS; - - default: - printk(KERN_ALERT "ioctl %08x not supported by XL blkif\n", command); - return -ENOSYS; - } - - return 0; -} + int i; + DPRINTK_IOCTL("command: 0x%x, argument: 0x%lx, dev: 0x%04x\n", + command, (long)argument, inode->i_rdev); + switch (command) { + case CDROMMULTISESSION: + DPRINTK("FIXME: support multisession CDs later\n"); + for (i = 0; i < sizeof(struct cdrom_multisession); i++) + if (put_user(0, (char __user *)(argument + i))) + return -EFAULT; + return 0; -/* check media change: should probably do something here in some cases :-) */ -int blkif_check(kdev_t dev) -{ - DPRINTK("blkif_check\n"); - return 0; + default: + /*printk(KERN_ALERT "ioctl %08x not supported by Xen blkdev\n", + command);*/ + return -EINVAL; /* same return as native Linux */ + } + + return 0; } -int blkif_revalidate(kdev_t dev) + +int blkif_getgeo(struct block_device *bd, struct hd_geometry *hg) { - struct block_device *bd; - struct gendisk *gd; - xl_disk_t *disk; - unsigned long capacity; - int i, rc = 0; - - if ( (bd = bdget(dev)) == NULL ) - return -EINVAL; - - /* - * Update of partition info, and check of usage count, is protected - * by the per-block-device semaphore. - */ - down(&bd->bd_sem); - - if ( ((gd = get_gendisk(dev)) == NULL) || - ((disk = xldev_to_xldisk(dev)) == NULL) || - ((capacity = gd->part[MINOR(dev)].nr_sects) == 0) ) - { - rc = -EINVAL; - goto out; - } - - if ( disk->usage > 1 ) - { - rc = -EBUSY; - goto out; - } - - /* Only reread partition table if VBDs aren't mapped to partitions. */ - if ( !(gd->flags[MINOR(dev) >> gd->minor_shift] & GENHD_FL_VIRT_PARTNS) ) - { - for ( i = gd->max_p - 1; i >= 0; i-- ) - { - invalidate_device(dev+i, 1); - gd->part[MINOR(dev+i)].start_sect = 0; - gd->part[MINOR(dev+i)].nr_sects = 0; - gd->sizes[MINOR(dev+i)] = 0; - } - - grok_partitions(gd, MINOR(dev)>>gd->minor_shift, gd->max_p, capacity); - } + /* We don't have real geometry info, but let's at least return + values consistent with the size of the device */ + sector_t nsect = get_capacity(bd->bd_disk); + sector_t cylinders = nsect; - out: - up(&bd->bd_sem); - bdput(bd); - return rc; + hg->heads = 0xff; + hg->sectors = 0x3f; + sector_div(cylinders, hg->heads * hg->sectors); + hg->cylinders = cylinders; + if ((sector_t)(hg->cylinders + 1) * hg->heads * hg->sectors < nsect) + hg->cylinders = 0xffff; + return 0; } /* * blkif_queue_request * - * request block io - * + * request block io + * * id: for guest use only. * operation: BLKIF_OP_{READ,WRITE,PROBE} * buffer: buffer to read/write into. this should be a * virtual address in the guest os. */ -static int blkif_queue_request(unsigned long id, - int operation, - char * buffer, - unsigned long sector_number, - unsigned short nr_sectors, - kdev_t device) +static int blkif_queue_request(struct request *req) { - unsigned long buffer_ma = virt_to_bus(buffer); - unsigned long xid; - struct gendisk *gd; - blkif_request_t *req; - struct buffer_head *bh; - unsigned int fsect, lsect; -#ifdef CONFIG_XEN_BLKDEV_GRANT - int ref; -#endif - - fsect = (buffer_ma & ~PAGE_MASK) >> 9; - lsect = fsect + nr_sectors - 1; - - /* Buffer must be sector-aligned. Extent mustn't cross a page boundary. */ - if ( unlikely((buffer_ma & ((1<<9)-1)) != 0) ) - BUG(); - if ( lsect > 7 ) - BUG(); - - buffer_ma &= PAGE_MASK; - - if ( unlikely(blkif_state != BLKIF_STATE_CONNECTED) ) - return 1; - - switch ( operation ) - { - - case BLKIF_OP_READ: - case BLKIF_OP_WRITE: - gd = get_gendisk(device); - - /* - * Update the sector_number we'll pass down as appropriate; note that - * we could sanity check that resulting sector will be in this - * partition, but this will happen in driver backend anyhow. - */ - sector_number += gd->part[MINOR(device)].start_sect; - - /* - * If this unit doesn't consist of virtual partitions then we clear - * the partn bits from the device number. - */ - if ( !(gd->flags[MINOR(device)>>gd->minor_shift] & - GENHD_FL_VIRT_PARTNS) ) - device &= ~(gd->max_p - 1); - - if ( (sg_operation == operation) && - (sg_dev == device) && - (sg_next_sect == sector_number) ) - { - req = RING_GET_REQUEST(&blk_ring, - blk_ring.req_prod_pvt - 1); - bh = (struct buffer_head *)id; - - bh->b_reqnext = (struct buffer_head *)blk_shadow[req->id].request; - blk_shadow[req->id].request = (unsigned long)id; - -#ifdef CONFIG_XEN_BLKDEV_GRANT - /* install a grant reference. */ - ref = gnttab_claim_grant_reference(&gref_head, gref_terminal); - ASSERT( ref != -ENOSPC ); - - gnttab_grant_foreign_access_ref( - ref, - rdomid, - buffer_ma >> PAGE_SHIFT, - ( operation == BLKIF_OP_WRITE ? 1 : 0 ) ); - - blk_shadow[id].frame[req->nr_segments] = - buffer_ma >> PAGE_SHIFT; - - req->frame_and_sects[req->nr_segments] = - (((u32) ref ) << 16) | (fsect << 3) | lsect; -#else - req->frame_and_sects[req->nr_segments] = - buffer_ma | (fsect << 3) | lsect; -#endif - if ( ++req->nr_segments < BLKIF_MAX_SEGMENTS_PER_REQUEST ) - sg_next_sect += nr_sectors; - else - DISABLE_SCATTERGATHER(); - - /* Update the copy of the request in the recovery ring. */ - pickle_request(&blk_shadow[req->id], req ); - - return 0; - } - else if ( RING_FULL(&blk_ring) ) - { - return 1; - } - else - { - sg_operation = operation; - sg_dev = device; - sg_next_sect = sector_number + nr_sectors; - } - break; - - default: - panic("unknown op %d\n", operation); - } - - /* Fill out a communications ring structure. */ - req = RING_GET_REQUEST(&blk_ring, blk_ring.req_prod_pvt); - - xid = GET_ID_FROM_FREELIST(); - blk_shadow[xid].request = (unsigned long)id; - - req->id = xid; - req->operation = operation; - req->sector_number = (blkif_sector_t)sector_number; - req->device = device; - req->nr_segments = 1; -#ifdef CONFIG_XEN_BLKDEV_GRANT - /* install a grant reference. */ - ref = gnttab_claim_grant_reference(&gref_head, gref_terminal); - ASSERT( ref != -ENOSPC ); - - gnttab_grant_foreign_access_ref( - ref, - rdomid, - buffer_ma >> PAGE_SHIFT, - ( operation == BLKIF_OP_WRITE ? 1 : 0 ) ); - - blk_shadow[xid].frame[0] = buffer_ma >> PAGE_SHIFT; - - req->frame_and_sects[0] = (((u32) ref)<<16) | (fsect<<3) | lsect; -#else - req->frame_and_sects[0] = buffer_ma | (fsect<<3) | lsect; -#endif - - /* Keep a private copy so we can reissue requests when recovering. */ - pickle_request(&blk_shadow[xid], req); - - blk_ring.req_prod_pvt++; - - return 0; + struct blkfront_info *info = req->rq_disk->private_data; + unsigned long buffer_mfn; + blkif_request_t *ring_req; + struct bio *bio; + struct bio_vec *bvec; + int idx; + unsigned long id; + unsigned int fsect, lsect; + int ref; + grant_ref_t gref_head; + + if (unlikely(info->connected != BLKIF_STATE_CONNECTED)) + return 1; + + if (gnttab_alloc_grant_references( + BLKIF_MAX_SEGMENTS_PER_REQUEST, &gref_head) < 0) { + gnttab_request_free_callback( + &info->callback, + blkif_restart_queue_callback, + info, + BLKIF_MAX_SEGMENTS_PER_REQUEST); + return 1; + } + + /* Fill out a communications ring structure. */ + ring_req = RING_GET_REQUEST(&info->ring, info->ring.req_prod_pvt); + id = GET_ID_FROM_FREELIST(info); + info->shadow[id].request = (unsigned long)req; + + ring_req->id = id; + ring_req->operation = rq_data_dir(req) ? + BLKIF_OP_WRITE : BLKIF_OP_READ; + ring_req->sector_number = (blkif_sector_t)req->sector; + ring_req->handle = info->handle; + + ring_req->nr_segments = 0; + rq_for_each_bio (bio, req) { + bio_for_each_segment (bvec, bio, idx) { + BUG_ON(ring_req->nr_segments + == BLKIF_MAX_SEGMENTS_PER_REQUEST); + buffer_mfn = page_to_phys(bvec->bv_page) >> PAGE_SHIFT; + fsect = bvec->bv_offset >> 9; + lsect = fsect + (bvec->bv_len >> 9) - 1; + /* install a grant reference. */ + ref = gnttab_claim_grant_reference(&gref_head); + BUG_ON(ref == -ENOSPC); + + gnttab_grant_foreign_access_ref( + ref, + info->xbdev->otherend_id, + buffer_mfn, + rq_data_dir(req) ); + + info->shadow[id].frame[ring_req->nr_segments] = + mfn_to_pfn(buffer_mfn); + + ring_req->seg[ring_req->nr_segments] = + (struct blkif_request_segment) { + .gref = ref, + .first_sect = fsect, + .last_sect = lsect }; + + ring_req->nr_segments++; + } + } + + info->ring.req_prod_pvt++; + + /* Keep a private copy so we can reissue requests when recovering. */ + info->shadow[id].req = *ring_req; + + gnttab_free_grant_references(gref_head); + + return 0; } - /* * do_blkif_request * read a block; request is in a request queue */ void do_blkif_request(request_queue_t *rq) { - struct request *req; - struct buffer_head *bh, *next_bh; - int rw, nsect, full, queued = 0; - - DPRINTK("Entered do_blkif_request\n"); - - while ( !rq->plugged && !list_empty(&rq->queue_head)) - { - if ( (req = blkdev_entry_next_request(&rq->queue_head)) == NULL ) - goto out; - - DPRINTK("do_blkif_request %p: cmd %i, sec %lx, (%li/%li) bh:%p\n", - req, req->cmd, req->sector, - req->current_nr_sectors, req->nr_sectors, req->bh); - - rw = req->cmd; - if ( rw == READA ) - rw = READ; - if ( unlikely((rw != READ) && (rw != WRITE)) ) - panic("XenoLinux Virtual Block Device: bad cmd: %d\n", rw); - - req->errors = 0; - - bh = req->bh; - while ( bh != NULL ) - { - next_bh = bh->b_reqnext; - bh->b_reqnext = NULL; - - full = blkif_queue_request( - (unsigned long)bh, - (rw == READ) ? BLKIF_OP_READ : BLKIF_OP_WRITE, - bh->b_data, bh->b_rsector, bh->b_size>>9, bh->b_rdev); - - if ( full ) - { - bh->b_reqnext = next_bh; - pending_queues[nr_pending++] = rq; - if ( unlikely(nr_pending >= MAX_PENDING) ) - BUG(); - goto out; - } - - queued++; - - /* Dequeue the buffer head from the request. */ - nsect = bh->b_size >> 9; - bh = req->bh = next_bh; - - if ( bh != NULL ) - { - /* There's another buffer head to do. Update the request. */ - req->hard_sector += nsect; - req->hard_nr_sectors -= nsect; - req->sector = req->hard_sector; - req->nr_sectors = req->hard_nr_sectors; - req->current_nr_sectors = bh->b_size >> 9; - req->buffer = bh->b_data; - } - else - { - /* That was the last buffer head. Finalise the request. */ - if ( unlikely(end_that_request_first(req, 1, "XenBlk")) ) - BUG(); - blkdev_dequeue_request(req); - end_that_request_last(req); - } - } - } + struct blkfront_info *info = NULL; + struct request *req; + int queued; - out: - if ( queued != 0 ) - flush_requests(); -} + DPRINTK("Entered do_blkif_request\n"); + queued = 0; -static void blkif_int(int irq, void *dev_id, struct pt_regs *ptregs) -{ - RING_IDX i, rp; - unsigned long flags; - struct buffer_head *bh, *next_bh; - - spin_lock_irqsave(&io_request_lock, flags); - - if ( unlikely(blkif_state == BLKIF_STATE_CLOSED || recovery) ) - { - spin_unlock_irqrestore(&io_request_lock, flags); - return; - } - - rp = blk_ring.sring->rsp_prod; - rmb(); /* Ensure we see queued responses up to 'rp'. */ - - for ( i = blk_ring.rsp_cons; i != rp; i++ ) - { - unsigned long id; - blkif_response_t *bret; - - bret = RING_GET_RESPONSE(&blk_ring, i); - id = bret->id; - bh = (struct buffer_head *)blk_shadow[id].request; - - blkif_completion(&blk_shadow[id]); - - ADD_ID_TO_FREELIST(id); - - switch ( bret->operation ) - { - case BLKIF_OP_READ: - case BLKIF_OP_WRITE: - if ( unlikely(bret->status != BLKIF_RSP_OKAY) ) - DPRINTK("Bad return from blkdev data request: %lx\n", - bret->status); - for ( ; bh != NULL; bh = next_bh ) - { - next_bh = bh->b_reqnext; - bh->b_reqnext = NULL; - bh->b_end_io(bh, bret->status == BLKIF_RSP_OKAY); - } - - break; - case BLKIF_OP_PROBE: - memcpy(&blkif_control_rsp, bret, sizeof(*bret)); - blkif_control_rsp_valid = 1; - break; - default: - BUG(); - } - - } - blk_ring.rsp_cons = i; - - kick_pending_request_queues(); - - spin_unlock_irqrestore(&io_request_lock, flags); -} + while ((req = elv_next_request(rq)) != NULL) { + info = req->rq_disk->private_data; + if (!blk_fs_request(req)) { + end_request(req, 0); + continue; + } -#endif + if (RING_FULL(&info->ring)) + goto wait; -/***************************** COMMON CODE *******************************/ + DPRINTK("do_blk_req %p: cmd %p, sec %lx, " + "(%u/%li) buffer:%p [%s]\n", + req, req->cmd, req->sector, req->current_nr_sectors, + req->nr_sectors, req->buffer, + rq_data_dir(req) ? "write" : "read"); -#ifdef CONFIG_XEN_BLKDEV_GRANT -void blkif_control_probe_send(blkif_request_t *req, blkif_response_t *rsp, - unsigned long address) -{ - int ref = gnttab_claim_grant_reference(&gref_head, gref_terminal); - ASSERT( ref != -ENOSPC ); - gnttab_grant_foreign_access_ref( ref, rdomid, address >> PAGE_SHIFT, 0 ); + blkdev_dequeue_request(req); + if (blkif_queue_request(req)) { + blk_requeue_request(rq, req); + wait: + /* Avoid pointless unplugs. */ + blk_stop_queue(rq); + break; + } - req->frame_and_sects[0] = (((u32) ref) << 16) | 7; + queued++; + } - blkif_control_send(req, rsp); + if (queued != 0) + flush_requests(info); } -#endif -void blkif_control_send(blkif_request_t *req, blkif_response_t *rsp) -{ - unsigned long flags, id; - blkif_request_t *req_d; - - retry: - while ( RING_FULL(&blk_ring) ) - { - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(1); - } - - spin_lock_irqsave(&blkif_io_lock, flags); - if ( RING_FULL(&blk_ring) ) - { - spin_unlock_irqrestore(&blkif_io_lock, flags); - goto retry; - } - - DISABLE_SCATTERGATHER(); - req_d = RING_GET_REQUEST(&blk_ring, blk_ring.req_prod_pvt); - *req_d = *req; - - id = GET_ID_FROM_FREELIST(); - req_d->id = id; - blk_shadow[id].request = (unsigned long)req; - - pickle_request(&blk_shadow[id], req); - - blk_ring.req_prod_pvt++; - flush_requests(); - - spin_unlock_irqrestore(&blkif_io_lock, flags); - - while ( !blkif_control_rsp_valid ) - { - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(1); - } - - memcpy(rsp, &blkif_control_rsp, sizeof(*rsp)); - blkif_control_rsp_valid = 0; -} - -/* Send a driver status notification to the domain controller. */ -static void send_driver_status(int ok) +static irqreturn_t blkif_int(int irq, void *dev_id, struct pt_regs *ptregs) { - ctrl_msg_t cmsg = { - .type = CMSG_BLKIF_FE, - .subtype = CMSG_BLKIF_FE_DRIVER_STATUS, - .length = sizeof(blkif_fe_driver_status_t), - }; - blkif_fe_driver_status_t *msg = (void*)cmsg.msg; - - msg->status = (ok ? BLKIF_DRIVER_STATUS_UP : BLKIF_DRIVER_STATUS_DOWN); - - ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE); -} + struct request *req; + blkif_response_t *bret; + RING_IDX i, rp; + unsigned long flags; + struct blkfront_info *info = (struct blkfront_info *)dev_id; + + spin_lock_irqsave(&blkif_io_lock, flags); + + if (unlikely(info->connected != BLKIF_STATE_CONNECTED)) { + spin_unlock_irqrestore(&blkif_io_lock, flags); + return IRQ_HANDLED; + } + + again: + rp = info->ring.sring->rsp_prod; + rmb(); /* Ensure we see queued responses up to 'rp'. */ + + for (i = info->ring.rsp_cons; i != rp; i++) { + unsigned long id; + int ret; + + bret = RING_GET_RESPONSE(&info->ring, i); + id = bret->id; + req = (struct request *)info->shadow[id].request; + + blkif_completion(&info->shadow[id]); + + ADD_ID_TO_FREELIST(info, id); + + switch (bret->operation) { + case BLKIF_OP_READ: + case BLKIF_OP_WRITE: + if (unlikely(bret->status != BLKIF_RSP_OKAY)) + DPRINTK("Bad return from blkdev data " + "request: %x\n", bret->status); + + ret = end_that_request_first( + req, (bret->status == BLKIF_RSP_OKAY), + req->hard_nr_sectors); + BUG_ON(ret); + end_that_request_last( + req, (bret->status == BLKIF_RSP_OKAY)); + break; + default: + BUG(); + } + } + + info->ring.rsp_cons = i; + + if (i != info->ring.req_prod_pvt) { + int more_to_do; + RING_FINAL_CHECK_FOR_RESPONSES(&info->ring, more_to_do); + if (more_to_do) + goto again; + } else + info->ring.sring->rsp_event = i + 1; + + kick_pending_request_queues(info); + + spin_unlock_irqrestore(&blkif_io_lock, flags); + + return IRQ_HANDLED; +} + +static void blkif_free(struct blkfront_info *info, int suspend) +{ + /* Prevent new requests being issued until we fix things up. */ + spin_lock_irq(&blkif_io_lock); + info->connected = suspend ? + BLKIF_STATE_SUSPENDED : BLKIF_STATE_DISCONNECTED; + /* No more blkif_request(). */ + if (info->rq) + blk_stop_queue(info->rq); + /* No more gnttab callback work. */ + gnttab_cancel_free_callback(&info->callback); + flush_scheduled_work(); + spin_unlock_irq(&blkif_io_lock); + + /* Free resources associated with old device channel. */ + if (info->ring_ref != GRANT_INVALID_REF) { + gnttab_end_foreign_access(info->ring_ref, 0, + (unsigned long)info->ring.sring); + info->ring_ref = GRANT_INVALID_REF; + info->ring.sring = NULL; + } + if (info->irq) + unbind_from_irqhandler(info->irq, info); + info->evtchn = info->irq = 0; -/* Tell the controller to bring up the interface. */ -static void blkif_send_interface_connect(void) -{ - ctrl_msg_t cmsg = { - .type = CMSG_BLKIF_FE, - .subtype = CMSG_BLKIF_FE_INTERFACE_CONNECT, - .length = sizeof(blkif_fe_interface_connect_t), - }; - blkif_fe_interface_connect_t *msg = (void*)cmsg.msg; - - msg->handle = 0; - msg->shmem_frame = (virt_to_machine(blk_ring.sring) >> PAGE_SHIFT); - - ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE); } -static void blkif_free(void) +static void blkif_completion(struct blk_shadow *s) { - /* Prevent new requests being issued until we fix things up. */ - spin_lock_irq(&blkif_io_lock); - recovery = 1; - blkif_state = BLKIF_STATE_DISCONNECTED; - spin_unlock_irq(&blkif_io_lock); - - /* Free resources associated with old device channel. */ - if ( blk_ring.sring != NULL ) - { - free_page((unsigned long)blk_ring.sring); - blk_ring.sring = NULL; - } - free_irq(blkif_irq, NULL); - blkif_irq = 0; - - unbind_evtchn_from_irq(blkif_evtchn); - blkif_evtchn = 0; + int i; + for (i = 0; i < s->req.nr_segments; i++) + gnttab_end_foreign_access(s->req.seg[i].gref, 0, 0UL); } -static void blkif_close(void) +static void blkif_recover(struct blkfront_info *info) { -} + int i; + blkif_request_t *req; + struct blk_shadow *copy; + int j; -/* Move from CLOSED to DISCONNECTED state. */ -static void blkif_disconnect(void) -{ - blkif_sring_t *sring; - - if ( blk_ring.sring != NULL ) - free_page((unsigned long)blk_ring.sring); - - sring = (blkif_sring_t *)__get_free_page(GFP_KERNEL); - SHARED_RING_INIT(sring); - FRONT_RING_INIT(&blk_ring, sring, PAGE_SIZE); - blkif_state = BLKIF_STATE_DISCONNECTED; - blkif_send_interface_connect(); -} + /* Stage 1: Make a safe copy of the shadow state. */ + copy = kmalloc(sizeof(info->shadow), GFP_KERNEL | __GFP_NOFAIL); + memcpy(copy, info->shadow, sizeof(info->shadow)); -static void blkif_reset(void) -{ - blkif_free(); - blkif_disconnect(); -} + /* Stage 2: Set up free list. */ + memset(&info->shadow, 0, sizeof(info->shadow)); + for (i = 0; i < BLK_RING_SIZE; i++) + info->shadow[i].req.id = i+1; + info->shadow_free = info->ring.req_prod_pvt; + info->shadow[BLK_RING_SIZE-1].req.id = 0x0fffffff; -static void blkif_recover(void) -{ - int i; - blkif_request_t *req; - struct blk_shadow *copy; -#ifdef CONFIG_XEN_BLKDEV_GRANT - int j; -#endif - - /* Stage 1: Make a safe copy of the shadow state. */ - copy = (struct blk_shadow *)kmalloc(sizeof(blk_shadow), GFP_KERNEL); - BUG_ON(copy == NULL); - memcpy(copy, blk_shadow, sizeof(blk_shadow)); - - /* Stage 2: Set up free list. */ - memset(&blk_shadow, 0, sizeof(blk_shadow)); - for ( i = 0; i < BLK_RING_SIZE; i++ ) - blk_shadow[i].req.id = i+1; - blk_shadow_free = blk_ring.req_prod_pvt; - blk_shadow[BLK_RING_SIZE-1].req.id = 0x0fffffff; - - /* Stage 3: Find pending requests and requeue them. */ - for ( i = 0; i < BLK_RING_SIZE; i++ ) - { - /* Not in use? */ - if ( copy[i].request == 0 ) - continue; - - /* Grab a request slot and unpickle shadow state into it. */ - req = RING_GET_REQUEST( - &blk_ring, blk_ring.req_prod_pvt); - unpickle_request(req, ©[i]); - - /* We get a new request id, and must reset the shadow state. */ - req->id = GET_ID_FROM_FREELIST(); - memcpy(&blk_shadow[req->id], ©[i], sizeof(copy[i])); - -#ifdef CONFIG_XEN_BLKDEV_GRANT - /* Rewrite any grant references invalidated by suspend/resume. */ - for ( j = 0; j < req->nr_segments; j++ ) - { - if ( req->frame_and_sects[j] & GRANTREF_INVALID ) - gnttab_grant_foreign_access_ref( - blkif_gref_from_fas(req->frame_and_sects[j]), - rdomid, - blk_shadow[req->id].frame[j], - rq_data_dir((struct request *) - blk_shadow[req->id].request)); - req->frame_and_sects[j] &= ~GRANTREF_INVALID; - } - blk_shadow[req->id].req = *req; -#endif - - blk_ring.req_prod_pvt++; - } - - kfree(copy); - - recovery = 0; - - /* blk_ring->req_prod will be set when we flush_requests().*/ - wmb(); - - /* Kicks things back into life. */ - flush_requests(); - - /* Now safe to left other people use the interface. */ - blkif_state = BLKIF_STATE_CONNECTED; -} + /* Stage 3: Find pending requests and requeue them. */ + for (i = 0; i < BLK_RING_SIZE; i++) { + /* Not in use? */ + if (copy[i].request == 0) + continue; -static void blkif_connect(blkif_fe_interface_status_t *status) -{ - int err = 0; - - blkif_evtchn = status->evtchn; - blkif_irq = bind_evtchn_to_irq(blkif_evtchn); -#ifdef CONFIG_XEN_BLKDEV_GRANT - rdomid = status->domid; -#endif - - err = request_irq(blkif_irq, blkif_int, SA_SAMPLE_RANDOM, "blkif", NULL); - if ( err ) - { - printk(KERN_ALERT "xen_blk: request_irq failed (err=%d)\n", err); - return; - } - - if ( recovery ) - { - blkif_recover(); - } - else - { - /* Transition to connected in case we need to do - * a partition probe on a whole disk. */ - blkif_state = BLKIF_STATE_CONNECTED; - - /* Probe for discs attached to the interface. */ - xlvbd_init(); - } - - /* Kick pending requests. */ - spin_lock_irq(&blkif_io_lock); - kick_pending_request_queues(); - spin_unlock_irq(&blkif_io_lock); -} + /* Grab a request slot and copy shadow state into it. */ + req = RING_GET_REQUEST( + &info->ring, info->ring.req_prod_pvt); + *req = copy[i].req; -static void unexpected(blkif_fe_interface_status_t *status) -{ - DPRINTK(" Unexpected blkif status %u in state %u\n", - status->status, blkif_state); -} + /* We get a new request id, and must reset the shadow state. */ + req->id = GET_ID_FROM_FREELIST(info); + memcpy(&info->shadow[req->id], ©[i], sizeof(copy[i])); -static void blkif_status(blkif_fe_interface_status_t *status) -{ - if ( status->handle != blkif_handle ) - { - WPRINTK(" Invalid blkif: handle=%u\n", status->handle); - unexpected(status); - return; - } - - switch ( status->status ) - { - case BLKIF_INTERFACE_STATUS_CLOSED: - switch ( blkif_state ) - { - case BLKIF_STATE_CLOSED: - unexpected(status); - break; - case BLKIF_STATE_DISCONNECTED: - case BLKIF_STATE_CONNECTED: - unexpected(status); - blkif_close(); - break; - } - break; - - case BLKIF_INTERFACE_STATUS_DISCONNECTED: - switch ( blkif_state ) - { - case BLKIF_STATE_CLOSED: - blkif_disconnect(); - break; - case BLKIF_STATE_DISCONNECTED: - case BLKIF_STATE_CONNECTED: - /* unexpected(status); */ /* occurs during suspend/resume */ - blkif_reset(); - break; - } - break; - - case BLKIF_INTERFACE_STATUS_CONNECTED: - switch ( blkif_state ) - { - case BLKIF_STATE_CLOSED: - unexpected(status); - blkif_disconnect(); - blkif_connect(status); - break; - case BLKIF_STATE_DISCONNECTED: - blkif_connect(status); - break; - case BLKIF_STATE_CONNECTED: - unexpected(status); - blkif_connect(status); - break; - } - break; - - case BLKIF_INTERFACE_STATUS_CHANGED: - switch ( blkif_state ) - { - case BLKIF_STATE_CLOSED: - case BLKIF_STATE_DISCONNECTED: - unexpected(status); - break; - case BLKIF_STATE_CONNECTED: - vbd_update(); - break; - } - break; - - default: - WPRINTK(" Invalid blkif status: %d\n", status->status); - break; - } -} + /* Rewrite any grant references invalidated by susp/resume. */ + for (j = 0; j < req->nr_segments; j++) + gnttab_grant_foreign_access_ref( + req->seg[j].gref, + info->xbdev->otherend_id, + pfn_to_mfn(info->shadow[req->id].frame[j]), + rq_data_dir( + (struct request *) + info->shadow[req->id].request)); + info->shadow[req->id].req = *req; + info->ring.req_prod_pvt++; + } -static void blkif_ctrlif_rx(ctrl_msg_t *msg, unsigned long id) -{ - switch ( msg->subtype ) - { - case CMSG_BLKIF_FE_INTERFACE_STATUS: - blkif_status((blkif_fe_interface_status_t *) - &msg->msg[0]); - break; - default: - msg->length = 0; - break; - } - - ctrl_if_send_response(msg); -} + kfree(copy); -int wait_for_blkif(void) -{ - int err = 0; - int i; - send_driver_status(1); - - /* - * We should read 'nr_interfaces' from response message and wait - * for notifications before proceeding. For now we assume that we - * will be notified of exactly one interface. - */ - for ( i=0; (blkif_state != BLKIF_STATE_CONNECTED) && (i < 10*HZ); i++ ) - { - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(1); - } - - if ( blkif_state != BLKIF_STATE_CONNECTED ) - { - printk(KERN_INFO "xen_blk: Timeout connecting to device!\n"); - err = -ENOSYS; - } - return err; -} + (void)xenbus_switch_state(info->xbdev, XenbusStateConnected); -int __init xlblk_init(void) -{ - int i; + spin_lock_irq(&blkif_io_lock); + + /* Now safe for us to use the shared ring */ + info->connected = BLKIF_STATE_CONNECTED; -#ifdef CONFIG_XEN_BLKDEV_GRANT - if ( 0 > gnttab_alloc_grant_references( MAXIMUM_OUTSTANDING_BLOCK_REQS, - &gref_head, &gref_terminal )) - return 1; - printk(KERN_ALERT "Blkif frontend is using grant tables.\n"); -#endif + /* Send off requeued requests */ + flush_requests(info); - if ( (xen_start_info.flags & SIF_INITDOMAIN) || - (xen_start_info.flags & SIF_BLK_BE_DOMAIN) ) - return 0; + /* Kick any other new requests queued since we resumed */ + kick_pending_request_queues(info); - printk(KERN_INFO "xen_blk: Initialising virtual block device driver\n"); + spin_unlock_irq(&blkif_io_lock); +} - blk_shadow_free = 0; - memset(blk_shadow, 0, sizeof(blk_shadow)); - for ( i = 0; i < BLK_RING_SIZE; i++ ) - blk_shadow[i].req.id = i+1; - blk_shadow[BLK_RING_SIZE-1].req.id = 0x0fffffff; - (void)ctrl_if_register_receiver(CMSG_BLKIF_FE, blkif_ctrlif_rx, - CALLBACK_IN_BLOCKING_CONTEXT); +/* ** Driver Registration ** */ - wait_for_blkif(); - return 0; -} +static struct xenbus_device_id blkfront_ids[] = { + { "vbd" }, + { "" } +}; -void blkdev_suspend(void) -{ -} -void blkdev_resume(void) +static struct xenbus_driver blkfront = { + .name = "vbd", + .owner = THIS_MODULE, + .ids = blkfront_ids, + .probe = blkfront_probe, + .remove = blkfront_remove, + .resume = blkfront_resume, + .otherend_changed = backend_changed, +}; + + +static int __init xlblk_init(void) { -#ifdef CONFIG_XEN_BLKDEV_GRANT - int i, j; - for ( i = 0; i < BLK_RING_SIZE; i++ ) - for ( j = 0; j < BLKIF_MAX_SEGMENTS_PER_REQUEST; j++ ) - blk_shadow[i].req.frame_and_sects[j] |= GRANTREF_INVALID; -#endif - send_driver_status(1); + if (!is_running_on_xen()) + return -ENODEV; + + return xenbus_register_frontend(&blkfront); } +module_init(xlblk_init); -static void blkif_completion(struct blk_shadow *s) + +static void xlblk_exit(void) { - int i; -#ifdef CONFIG_XEN_BLKDEV_GRANT - for ( i = 0; i < s->req.nr_segments; i++ ) - gnttab_release_grant_reference( - &gref_head, blkif_gref_from_fas(s->req.frame_and_sects[i])); -#else - /* This is a hack to get the dirty logging bits set */ - if ( s->req.operation == BLKIF_OP_READ ) - { - for ( i = 0; i < s->req.nr_segments; i++ ) - { - unsigned long pfn = s->req.frame_and_sects[i] >> PAGE_SHIFT; - unsigned long mfn = phys_to_machine_mapping[pfn]; - xen_machphys_update(mfn, pfn); - } - } -#endif + return xenbus_unregister_driver(&blkfront); } +module_exit(xlblk_exit); + +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/xen/blkfront/block.h b/drivers/xen/blkfront/block.h index ede57abfa..5ba3d1ebc 100644 --- a/drivers/xen/blkfront/block.h +++ b/drivers/xen/blkfront/block.h @@ -7,8 +7,11 @@ * Modifications by Mark A. Williamson are (c) Intel Research Cambridge * Copyright (c) 2004-2005, Christian Limpach * - * This file may be distributed separately from the Linux kernel, or - * incorporated into other software packages, subject to the following license: + * 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; or, when distributed + * separately from the Linux kernel or incorporated into other + * software packages, subject to the following license: * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this source file (the "Software"), to deal in the Software without @@ -33,6 +36,7 @@ #define __XEN_DRIVERS_BLOCK_H__ #include +#include #include #include #include @@ -44,74 +48,109 @@ #include #include #include -#include -#include -#include +#include +#include +#include +#include +#include +#include #include #include #include -#if 0 -#define DPRINTK(_f, _a...) printk ( KERN_ALERT _f , ## _a ) +#if 1 +#define IPRINTK(fmt, args...) \ + printk(KERN_INFO "xen_blk: " fmt, ##args) +#else +#define IPRINTK(fmt, args...) ((void)0) +#endif + +#if 1 +#define WPRINTK(fmt, args...) \ + printk(KERN_WARNING "xen_blk: " fmt, ##args) #else -#define DPRINTK(_f, _a...) ((void)0) +#define WPRINTK(fmt, args...) ((void)0) #endif +#define DPRINTK(_f, _a...) pr_debug(_f, ## _a) + #if 0 -#define DPRINTK_IOCTL(_f, _a...) printk ( KERN_ALERT _f , ## _a ) +#define DPRINTK_IOCTL(_f, _a...) printk(KERN_ALERT _f, ## _a) #else #define DPRINTK_IOCTL(_f, _a...) ((void)0) #endif -struct xlbd_type_info { - int partn_shift; - int partn_per_major; - int devs_per_major; - char *devname; - char *diskname; +struct xlbd_type_info +{ + int partn_shift; + int disks_per_major; + char *devname; + char *diskname; +}; + +struct xlbd_major_info +{ + int major; + int index; + int usage; + struct xlbd_type_info *type; }; +struct blk_shadow { + blkif_request_t req; + unsigned long request; + unsigned long frame[BLKIF_MAX_SEGMENTS_PER_REQUEST]; +}; + +#define BLK_RING_SIZE __RING_SIZE((blkif_sring_t *)0, PAGE_SIZE) + /* * We have one of these per vbd, whether ide, scsi or 'other'. They * hang in private_data off the gendisk structure. We may end up * putting all kinds of interesting stuff here :-) */ -struct xlbd_major_info { - int major; - int index; - int usage; - struct xlbd_type_info *type; -}; +struct blkfront_info +{ + struct xenbus_device *xbdev; + dev_t dev; + struct gendisk *gd; + int vdevice; + blkif_vdev_t handle; + int connected; + int ring_ref; + blkif_front_ring_t ring; + unsigned int evtchn, irq; + struct xlbd_major_info *mi; + request_queue_t *rq; + struct work_struct work; + struct gnttab_free_callback callback; + struct blk_shadow shadow[BLK_RING_SIZE]; + unsigned long shadow_free; -struct xlbd_disk_info { - int xd_device; - struct xlbd_major_info *mi; + /** + * The number of people holding this device open. We won't allow a + * hot-unplug unless this is 0. + */ + int users; }; -typedef struct xen_block { - int usage; -} xen_block_t; - -extern struct request_queue *xlbd_blk_queue; extern spinlock_t blkif_io_lock; extern int blkif_open(struct inode *inode, struct file *filep); extern int blkif_release(struct inode *inode, struct file *filep); extern int blkif_ioctl(struct inode *inode, struct file *filep, - unsigned command, unsigned long argument); + unsigned command, unsigned long argument); +extern int blkif_getgeo(struct block_device *, struct hd_geometry *); extern int blkif_check(dev_t dev); extern int blkif_revalidate(dev_t dev); -extern void blkif_control_send(blkif_request_t *req, blkif_response_t *rsp); -#ifdef CONFIG_XEN_BLKDEV_GRANT -extern void blkif_control_probe_send( - blkif_request_t *req, blkif_response_t *rsp, unsigned long address); -#endif -extern void do_blkif_request (request_queue_t *rq); - -extern void xlvbd_update_vbds(void); +extern void do_blkif_request (request_queue_t *rq); /* Virtual block-device subsystem. */ -extern int xlvbd_init(void); -extern void xlvbd_cleanup(void); +/* Note that xlvbd_add doesn't call add_disk for you: you're expected + to call add_disk on info->gd once the disk is properly connected + up. */ +int xlvbd_add(blkif_sector_t capacity, int device, + u16 vdisk_info, u16 sector_size, struct blkfront_info *info); +void xlvbd_del(struct blkfront_info *info); #endif /* __XEN_DRIVERS_BLOCK_H__ */ diff --git a/drivers/xen/blkfront/vbd.c b/drivers/xen/blkfront/vbd.c index b5f2b14b4..8aa453d3a 100644 --- a/drivers/xen/blkfront/vbd.c +++ b/drivers/xen/blkfront/vbd.c @@ -7,8 +7,11 @@ * Modifications by Mark A. Williamson are (c) Intel Research Cambridge * Copyright (c) 2004-2005, Christian Limpach * - * This file may be distributed separately from the Linux kernel, or - * incorporated into other software packages, subject to the following license: + * 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; or, when distributed + * separately from the Linux kernel or incorporated into other + * software packages, subject to the following license: * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this source file (the "Software"), to deal in the Software without @@ -33,6 +36,9 @@ #include #include +#define BLKIF_MAJOR(dev) ((dev)>>8) +#define BLKIF_MINOR(dev) ((dev) & 0xff) + /* * For convenience we distinguish between ide, scsi and 'other' (i.e., * potentially combinations of the two) in the naming scheme and in a few other @@ -43,465 +49,270 @@ #define NUM_SCSI_MAJORS 9 #define NUM_VBD_MAJORS 1 -struct lvdisk -{ - blkif_sector_t capacity; /* 0: Size in terms of 512-byte sectors. */ - blkif_vdev_t device; /* 8: Device number (opaque 16 bit value). */ - u16 info; - struct list_head list; -}; - static struct xlbd_type_info xlbd_ide_type = { - .partn_shift = 6, - .partn_per_major = 2, - .devname = "ide", - .diskname = "hd", + .partn_shift = 6, + .disks_per_major = 2, + .devname = "ide", + .diskname = "hd", }; static struct xlbd_type_info xlbd_scsi_type = { - .partn_shift = 4, - .partn_per_major = 16, - .devname = "sd", - .diskname = "sd", + .partn_shift = 4, + .disks_per_major = 16, + .devname = "sd", + .diskname = "sd", }; static struct xlbd_type_info xlbd_vbd_type = { - .partn_shift = 4, - .partn_per_major = 16, - .devname = "xvd", - .diskname = "xvd", + .partn_shift = 4, + .disks_per_major = 16, + .devname = "xvd", + .diskname = "xvd", }; static struct xlbd_major_info *major_info[NUM_IDE_MAJORS + NUM_SCSI_MAJORS + - NUM_VBD_MAJORS]; + NUM_VBD_MAJORS]; -#define XLBD_MAJOR_IDE_START 0 -#define XLBD_MAJOR_SCSI_START (NUM_IDE_MAJORS) -#define XLBD_MAJOR_VBD_START (NUM_IDE_MAJORS + NUM_SCSI_MAJORS) +#define XLBD_MAJOR_IDE_START 0 +#define XLBD_MAJOR_SCSI_START (NUM_IDE_MAJORS) +#define XLBD_MAJOR_VBD_START (NUM_IDE_MAJORS + NUM_SCSI_MAJORS) -#define XLBD_MAJOR_IDE_RANGE XLBD_MAJOR_IDE_START ... XLBD_MAJOR_SCSI_START - 1 -#define XLBD_MAJOR_SCSI_RANGE XLBD_MAJOR_SCSI_START ... XLBD_MAJOR_VBD_START - 1 -#define XLBD_MAJOR_VBD_RANGE XLBD_MAJOR_VBD_START ... XLBD_MAJOR_VBD_START + NUM_VBD_MAJORS - 1 +#define XLBD_MAJOR_IDE_RANGE XLBD_MAJOR_IDE_START ... XLBD_MAJOR_SCSI_START - 1 +#define XLBD_MAJOR_SCSI_RANGE XLBD_MAJOR_SCSI_START ... XLBD_MAJOR_VBD_START - 1 +#define XLBD_MAJOR_VBD_RANGE XLBD_MAJOR_VBD_START ... XLBD_MAJOR_VBD_START + NUM_VBD_MAJORS - 1 /* Information about our VBDs. */ #define MAX_VBDS 64 -struct list_head vbds_list; +static LIST_HEAD(vbds_list); -struct request_queue *xlbd_blk_queue = NULL; - -#define MAJOR_XEN(dev) ((dev)>>8) -#define MINOR_XEN(dev) ((dev) & 0xff) - -static struct block_device_operations xlvbd_block_fops = +static struct block_device_operations xlvbd_block_fops = { - .owner = THIS_MODULE, - .open = blkif_open, - .release = blkif_release, - .ioctl = blkif_ioctl, + .owner = THIS_MODULE, + .open = blkif_open, + .release = blkif_release, + .ioctl = blkif_ioctl, + .getgeo = blkif_getgeo }; -spinlock_t blkif_io_lock = SPIN_LOCK_UNLOCKED; +DEFINE_SPINLOCK(blkif_io_lock); -static struct lvdisk * xlvbd_device_alloc(void) +static struct xlbd_major_info * +xlbd_alloc_major_info(int major, int minor, int index) { - struct lvdisk *ret; - - ret = kmalloc(sizeof(struct lvdisk), GFP_KERNEL); - if ( ret ) { - memset(ret, '\0', sizeof(struct lvdisk)); - INIT_LIST_HEAD(&ret->list); - } - return ret; + struct xlbd_major_info *ptr; + + ptr = kzalloc(sizeof(struct xlbd_major_info), GFP_KERNEL); + if (ptr == NULL) + return NULL; + + ptr->major = major; + + switch (index) { + case XLBD_MAJOR_IDE_RANGE: + ptr->type = &xlbd_ide_type; + ptr->index = index - XLBD_MAJOR_IDE_START; + break; + case XLBD_MAJOR_SCSI_RANGE: + ptr->type = &xlbd_scsi_type; + ptr->index = index - XLBD_MAJOR_SCSI_START; + break; + case XLBD_MAJOR_VBD_RANGE: + ptr->type = &xlbd_vbd_type; + ptr->index = index - XLBD_MAJOR_VBD_START; + break; + } + + printk("Registering block device major %i\n", ptr->major); + if (register_blkdev(ptr->major, ptr->type->devname)) { + WPRINTK("can't get major %d with name %s\n", + ptr->major, ptr->type->devname); + kfree(ptr); + return NULL; + } + + devfs_mk_dir(ptr->type->devname); + major_info[index] = ptr; + return ptr; } -static void xlvbd_device_free(struct lvdisk *disk) +static struct xlbd_major_info * +xlbd_get_major_info(int vdevice) { - list_del(&disk->list); - kfree(disk); + struct xlbd_major_info *mi; + int major, minor, index; + + major = BLKIF_MAJOR(vdevice); + minor = BLKIF_MINOR(vdevice); + + switch (major) { + case IDE0_MAJOR: index = 0; break; + case IDE1_MAJOR: index = 1; break; + case IDE2_MAJOR: index = 2; break; + case IDE3_MAJOR: index = 3; break; + case IDE4_MAJOR: index = 4; break; + case IDE5_MAJOR: index = 5; break; + case IDE6_MAJOR: index = 6; break; + case IDE7_MAJOR: index = 7; break; + case IDE8_MAJOR: index = 8; break; + case IDE9_MAJOR: index = 9; break; + case SCSI_DISK0_MAJOR: index = 10; break; + case SCSI_DISK1_MAJOR ... SCSI_DISK7_MAJOR: + index = 11 + major - SCSI_DISK1_MAJOR; + break; + case SCSI_CDROM_MAJOR: index = 18; break; + default: index = 19; break; + } + + mi = ((major_info[index] != NULL) ? major_info[index] : + xlbd_alloc_major_info(major, minor, index)); + if (mi) + mi->usage++; + return mi; } -static vdisk_t * xlvbd_probe(int *ret) +static void +xlbd_put_major_info(struct xlbd_major_info *mi) { - blkif_response_t rsp; - blkif_request_t req; - vdisk_t *disk_info = NULL; - unsigned long buf; - int nr; - - buf = __get_free_page(GFP_KERNEL); - if ( !buf ) - goto out; - - memset(&req, 0, sizeof(req)); - req.operation = BLKIF_OP_PROBE; - req.nr_segments = 1; -#ifdef CONFIG_XEN_BLKDEV_GRANT - blkif_control_probe_send(&req, &rsp, - (unsigned long)(virt_to_machine(buf))); -#else - req.frame_and_sects[0] = virt_to_machine(buf) | 7; - - blkif_control_send(&req, &rsp); -#endif - if ( rsp.status <= 0 ) { - printk(KERN_ALERT "Could not probe disks (%d)\n", rsp.status); - goto out; - } - nr = rsp.status; - if ( nr > MAX_VBDS ) - nr = MAX_VBDS; - - disk_info = kmalloc(nr * sizeof(vdisk_t), GFP_KERNEL); - if ( disk_info ) - memcpy(disk_info, (void *) buf, nr * sizeof(vdisk_t)); - if ( ret ) - *ret = nr; -out: - free_page(buf); - return disk_info; + mi->usage--; + /* XXX: release major if 0 */ } -static struct xlbd_major_info *xlbd_alloc_major_info(int major, int minor, int index) +static int +xlvbd_init_blk_queue(struct gendisk *gd, u16 sector_size) { - struct xlbd_major_info *ptr; - - ptr = kmalloc(sizeof(struct xlbd_major_info), GFP_KERNEL); - if ( !ptr ) - return NULL; - - memset(ptr, 0, sizeof(struct xlbd_major_info)); - - ptr->major = major; - - switch (index) { - case XLBD_MAJOR_IDE_RANGE: - ptr->type = &xlbd_ide_type; - ptr->index = index - XLBD_MAJOR_IDE_START; - break; - case XLBD_MAJOR_SCSI_RANGE: - ptr->type = &xlbd_scsi_type; - ptr->index = index - XLBD_MAJOR_SCSI_START; - break; - case XLBD_MAJOR_VBD_RANGE: - ptr->type = &xlbd_vbd_type; - ptr->index = index - XLBD_MAJOR_VBD_START; - break; - } - - if ( register_blkdev(ptr->major, ptr->type->devname) ) { - printk(KERN_ALERT "XL VBD: can't get major %d with name %s\n", - ptr->major, ptr->type->devname); - kfree(ptr); - return NULL; - } - - devfs_mk_dir(ptr->type->devname); - major_info[index] = ptr; - return ptr; -} + request_queue_t *rq; -static struct xlbd_major_info *xlbd_get_major_info(int device) -{ - int major, minor, index; - - major = MAJOR_XEN(device); - minor = MINOR_XEN(device); - - switch (major) { - case IDE0_MAJOR: index = 0; break; - case IDE1_MAJOR: index = 1; break; - case IDE2_MAJOR: index = 2; break; - case IDE3_MAJOR: index = 3; break; - case IDE4_MAJOR: index = 4; break; - case IDE5_MAJOR: index = 5; break; - case IDE6_MAJOR: index = 6; break; - case IDE7_MAJOR: index = 7; break; - case IDE8_MAJOR: index = 8; break; - case IDE9_MAJOR: index = 9; break; - case SCSI_DISK0_MAJOR: index = 10; break; - case SCSI_DISK1_MAJOR ... SCSI_DISK7_MAJOR: - index = 11 + major - SCSI_DISK1_MAJOR; - break; - case SCSI_CDROM_MAJOR: index = 18; break; - default: index = 19; break; - } - - return major_info[index] - ? major_info[index] - : xlbd_alloc_major_info(major, minor, index); -} + rq = blk_init_queue(do_blkif_request, &blkif_io_lock); + if (rq == NULL) + return -1; -static int xlvbd_blk_queue_alloc(struct xlbd_type_info *type) -{ - xlbd_blk_queue = blk_init_queue(do_blkif_request, &blkif_io_lock); - if ( !xlbd_blk_queue ) - return -1; - - elevator_init(xlbd_blk_queue, "noop"); - - /* - * Turn off barking 'headactive' mode. We dequeue - * buffer heads as soon as we pass them to back-end - * driver. - */ - blk_queue_headactive(xlbd_blk_queue, 0); - - /* Hard sector size and max sectors impersonate the equiv. hardware. */ - blk_queue_hardsect_size(xlbd_blk_queue, 512); - blk_queue_max_sectors(xlbd_blk_queue, 512); - - /* Each segment in a request is up to an aligned page in size. */ - blk_queue_segment_boundary(xlbd_blk_queue, PAGE_SIZE - 1); - blk_queue_max_segment_size(xlbd_blk_queue, PAGE_SIZE); - - /* Ensure a merged request will fit in a single I/O ring slot. */ - blk_queue_max_phys_segments(xlbd_blk_queue, BLKIF_MAX_SEGMENTS_PER_REQUEST); - blk_queue_max_hw_segments(xlbd_blk_queue, BLKIF_MAX_SEGMENTS_PER_REQUEST); - - /* Make sure buffer addresses are sector-aligned. */ - blk_queue_dma_alignment(xlbd_blk_queue, 511); - return 0; -} + elevator_init(rq, "noop"); -struct gendisk *xlvbd_alloc_gendisk(struct xlbd_major_info *mi, int minor, - vdisk_t *disk) -{ - struct gendisk *gd; - struct xlbd_disk_info *di; - int nb_minors; - - di = kmalloc(sizeof(struct xlbd_disk_info), GFP_KERNEL); - if ( !di ) - goto out; - di->mi = mi; - di->xd_device = disk->device; - - nb_minors = ((minor & ((1 << mi->type->partn_shift) - 1)) == 0) - ? mi->type->partn_per_major - : 1; - - gd = alloc_disk(nb_minors); - if ( !gd ) - goto out; - - if ( nb_minors > 1 ) - sprintf(gd->disk_name, "%s%c", mi->type->diskname, - 'a' + mi->index * mi->type->partn_per_major + - (minor >> mi->type->partn_shift)); - else - sprintf(gd->disk_name, "%s%c%d", mi->type->diskname, - 'a' + mi->index * mi->type->partn_per_major + - (minor >> mi->type->partn_shift), - minor & ((1 << mi->type->partn_shift) - 1)); - - gd->major = mi->major; - gd->first_minor = minor; - gd->fops = &xlvbd_block_fops; - gd->private_data = di; - set_capacity(gd, disk->capacity); - - if ( !xlbd_blk_queue ) - if ( xlvbd_blk_queue_alloc(mi->type) ) - goto out_gendisk; - - gd->queue = xlbd_blk_queue; - add_disk(gd); - return gd; -out_gendisk: - printk(KERN_ALERT "error gendisk\n"); - del_gendisk(gd); -out: - printk(KERN_ALERT "error out\n"); - kfree(di); - return NULL; -} + /* Hard sector size and max sectors impersonate the equiv. hardware. */ + blk_queue_hardsect_size(rq, sector_size); + blk_queue_max_sectors(rq, 512); -static int xlvbd_device_add(struct list_head *list, vdisk_t *disk) -{ - struct lvdisk *new; - int minor; - dev_t device; - struct block_device *bd; - struct gendisk *gd; - struct xlbd_major_info *mi; - - mi = xlbd_get_major_info(disk->device); - if ( !mi ) - return -EPERM; - - new = xlvbd_device_alloc(); - if ( !new ) - return -1; - new->capacity = disk->capacity; - new->device = disk->device; - new->info = disk->info; - - minor = MINOR_XEN(disk->device); - device = MKDEV(mi->major, minor); - - bd = bdget(device); - if ( !bd ) - goto out; - - gd = xlvbd_alloc_gendisk(mi, minor, disk); - if ( !gd ) - goto out_bd; - - if ( VDISK_READONLY(disk->info) ) - set_disk_ro(gd, 1); - - switch (VDISK_TYPE(disk->info)) { - case VDISK_TYPE_CDROM: - gd->flags |= GENHD_FL_REMOVABLE | GENHD_FL_CD; - break; - case VDISK_TYPE_FLOPPY: - case VDISK_TYPE_TAPE: - gd->flags |= GENHD_FL_REMOVABLE; - break; - case VDISK_TYPE_DISK: - break; - default: - printk(KERN_ALERT "XenLinux: unknown device type %d\n", - VDISK_TYPE(disk->info)); - break; - } - - list_add(&new->list, list); -out_bd: - bdput(bd); -out: - return 0; -} + /* Each segment in a request is up to an aligned page in size. */ + blk_queue_segment_boundary(rq, PAGE_SIZE - 1); + blk_queue_max_segment_size(rq, PAGE_SIZE); -static int xlvbd_device_del(struct lvdisk *disk) -{ - dev_t device; - struct block_device *bd; - struct gendisk *gd; - struct xlbd_disk_info *di; - int ret = 0, unused; + /* Ensure a merged request will fit in a single I/O ring slot. */ + blk_queue_max_phys_segments(rq, BLKIF_MAX_SEGMENTS_PER_REQUEST); + blk_queue_max_hw_segments(rq, BLKIF_MAX_SEGMENTS_PER_REQUEST); - device = MKDEV(MAJOR_XEN(disk->device), MINOR_XEN(disk->device)); + /* Make sure buffer addresses are sector-aligned. */ + blk_queue_dma_alignment(rq, 511); - bd = bdget(device); - if ( !bd ) - return -1; + gd->queue = rq; - gd = get_gendisk(device, &unused); - di = gd->private_data; - - if ( di->mi->usage != 0 ) { - printk(KERN_ALERT "VBD removal failed: used [dev=%x]\n", device); - ret = -1; - goto out; - } - - del_gendisk(gd); - - xlvbd_device_free(disk); -out: - bdput(bd); - return ret; + return 0; } -static int xlvbd_device_update(struct lvdisk *ldisk, vdisk_t *disk) +static int +xlvbd_alloc_gendisk(int minor, blkif_sector_t capacity, int vdevice, + u16 vdisk_info, u16 sector_size, + struct blkfront_info *info) { - dev_t device; - struct block_device *bd; - struct gendisk *gd; - int unused; - - if ( ldisk->capacity == disk->capacity && ldisk->info == disk->info ) - return 0; + struct gendisk *gd; + struct xlbd_major_info *mi; + int nr_minors = 1; + int err = -ENODEV; + + BUG_ON(info->gd != NULL); + BUG_ON(info->mi != NULL); + BUG_ON(info->rq != NULL); + + mi = xlbd_get_major_info(vdevice); + if (mi == NULL) + goto out; + info->mi = mi; + + if ((minor & ((1 << mi->type->partn_shift) - 1)) == 0) + nr_minors = 1 << mi->type->partn_shift; + + gd = alloc_disk(nr_minors); + if (gd == NULL) + goto out; + + if (nr_minors > 1) + sprintf(gd->disk_name, "%s%c", mi->type->diskname, + 'a' + mi->index * mi->type->disks_per_major + + (minor >> mi->type->partn_shift)); + else + sprintf(gd->disk_name, "%s%c%d", mi->type->diskname, + 'a' + mi->index * mi->type->disks_per_major + + (minor >> mi->type->partn_shift), + minor & ((1 << mi->type->partn_shift) - 1)); + + gd->major = mi->major; + gd->first_minor = minor; + gd->fops = &xlvbd_block_fops; + gd->private_data = info; + gd->driverfs_dev = &(info->xbdev->dev); + set_capacity(gd, capacity); + + if (xlvbd_init_blk_queue(gd, sector_size)) { + del_gendisk(gd); + goto out; + } + + info->rq = gd->queue; + + if (vdisk_info & VDISK_READONLY) + set_disk_ro(gd, 1); + + if (vdisk_info & VDISK_REMOVABLE) + gd->flags |= GENHD_FL_REMOVABLE; + + if (vdisk_info & VDISK_CDROM) + gd->flags |= GENHD_FL_CD; + + info->gd = gd; + + return 0; + + out: + if (mi) + xlbd_put_major_info(mi); + info->mi = NULL; + return err; +} - device = MKDEV(MAJOR_XEN(ldisk->device), MINOR_XEN(ldisk->device)); +int +xlvbd_add(blkif_sector_t capacity, int vdevice, u16 vdisk_info, + u16 sector_size, struct blkfront_info *info) +{ + struct block_device *bd; + int err = 0; - bd = bdget(device); - if ( !bd ) - return -1; + info->dev = MKDEV(BLKIF_MAJOR(vdevice), BLKIF_MINOR(vdevice)); - gd = get_gendisk(device, &unused); - set_capacity(gd, disk->capacity); - ldisk->capacity = disk->capacity; + bd = bdget(info->dev); + if (bd == NULL) + return -ENODEV; - bdput(bd); + err = xlvbd_alloc_gendisk(BLKIF_MINOR(vdevice), capacity, vdevice, + vdisk_info, sector_size, info); - return 0; + bdput(bd); + return err; } -void xlvbd_refresh(void) +void +xlvbd_del(struct blkfront_info *info) { - vdisk_t *newdisks; - struct list_head *tmp, *tmp2; - struct lvdisk *disk; - int i, nr; - - newdisks = xlvbd_probe(&nr); - if ( !newdisks ) { - printk(KERN_ALERT "failed to probe\n"); - return; - } - - i = 0; - list_for_each_safe(tmp, tmp2, &vbds_list) { - disk = list_entry(tmp, struct lvdisk, list); - - for (i = 0; i < nr; i++) { - if ( !newdisks[i].device ) - continue; - if ( disk->device == newdisks[i].device ) { - xlvbd_device_update(disk, &newdisks[i]); - newdisks[i].device = 0; - break; - } - } - if ( i == nr ) { - xlvbd_device_del(disk); - newdisks[i].device = 0; - } - } - for (i = 0; i < nr; i++) - if ( newdisks[i].device ) - xlvbd_device_add(&vbds_list, &newdisks[i]); - kfree(newdisks); -} + if (info->mi == NULL) + return; -/* - * xlvbd_update_vbds - reprobes the VBD status and performs updates driver - * state. The VBDs need to be updated in this way when the domain is - * initialised and also each time we receive an XLBLK_UPDATE event. - */ -void xlvbd_update_vbds(void) -{ - xlvbd_refresh(); -} + BUG_ON(info->gd == NULL); + del_gendisk(info->gd); + put_disk(info->gd); + info->gd = NULL; -/* - * Set up all the linux device goop for the virtual block devices - * (vbd's) that we know about. Note that although from the backend - * driver's p.o.v. VBDs are addressed simply an opaque 16-bit device - * number, the domain creation tools conventionally allocate these - * numbers to correspond to those used by 'real' linux -- this is just - * for convenience as it means e.g. that the same /etc/fstab can be - * used when booting with or without Xen. - */ -int xlvbd_init(void) -{ - int i, nr; - vdisk_t *disks; - - INIT_LIST_HEAD(&vbds_list); - - memset(major_info, 0, sizeof(major_info)); - - disks = xlvbd_probe(&nr); - if ( !disks ) { - printk(KERN_ALERT "failed to probe\n"); - return -1; - } - - for (i = 0; i < nr; i++) - xlvbd_device_add(&vbds_list, &disks[i]); - kfree(disks); - return 0; + xlbd_put_major_info(info->mi); + info->mi = NULL; + + BUG_ON(info->rq == NULL); + blk_cleanup_queue(info->rq); + info->rq = NULL; } diff --git a/drivers/xen/blktap/Makefile b/drivers/xen/blktap/Makefile index 80b7ca062..409b07896 100644 --- a/drivers/xen/blktap/Makefile +++ b/drivers/xen/blktap/Makefile @@ -1,3 +1,3 @@ - -obj-y := blktap_userdev.o blktap_datapath.o blktap_controlmsg.o blktap.o +LINUXINCLUDE += -I../xen/include/public/io +obj-y := xenbus.o interface.o blktap.o diff --git a/drivers/xen/blktap/blktap.c b/drivers/xen/blktap/blktap.c index a9a00677b..8c5cf68d7 100644 --- a/drivers/xen/blktap/blktap.c +++ b/drivers/xen/blktap/blktap.c @@ -1,87 +1,1450 @@ /****************************************************************************** - * blktap.c + * drivers/xen/blktap/blktap.c * - * XenLinux virtual block-device tap. + * Back-end driver for user level virtual block devices. This portion of the + * driver exports a 'unified' block-device interface that can be accessed + * by any operating system that implements a compatible front end. Requests + * are remapped to a user-space memory region. + * + * Based on the blkback driver code. * - * Copyright (c) 2004, Andrew Warfield + * Copyright (c) 2004-2005, Andrew Warfield and Julian Chesterfield * - * Based on the original split block driver: - * Copyright (c) 2003-2004, Keir Fraser & Steve Hand - * Modifications by Mark A. Williamson are (c) Intel Research Cambridge - * Copyright (c) 2004, Christian Limpach + * 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; or, when distributed + * separately from the Linux kernel or incorporated into other + * software packages, subject to the following license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this source file (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, modify, + * merge, publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. * - * Note that unlike the split block driver code, this driver has been developed - * strictly for Linux 2.6 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include +#include +#include +#include +#include "common.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAX_TAP_DEV 100 /*the maximum number of tapdisk ring devices */ +#define MAX_DEV_NAME 100 /*the max tapdisk ring device name e.g. blktap0 */ + +/* + * The maximum number of requests that can be outstanding at any time + * is determined by + * + * [mmap_alloc * MAX_PENDING_REQS * BLKIF_MAX_SEGMENTS_PER_REQUEST] + * + * where mmap_alloc < MAX_DYNAMIC_MEM. + * + * TODO: + * mmap_alloc is initialised to 2 and should be adjustable on the fly via + * sysfs. */ +#define MAX_DYNAMIC_MEM 64 +#define MAX_PENDING_REQS 64 +#define MMAP_PAGES (MAX_PENDING_REQS * BLKIF_MAX_SEGMENTS_PER_REQUEST) +#define MMAP_VADDR(_start, _req,_seg) \ + (_start + \ + ((_req) * BLKIF_MAX_SEGMENTS_PER_REQUEST * PAGE_SIZE) + \ + ((_seg) * PAGE_SIZE)) +static int blkif_reqs = MAX_PENDING_REQS; +static int mmap_pages = MMAP_PAGES; + +#define RING_PAGES 1 /* BLKTAP - immediately before the mmap area, we + * have a bunch of pages reserved for shared + * memory rings. + */ + +/*Data struct associated with each of the tapdisk devices*/ +typedef struct tap_blkif { + struct vm_area_struct *vma; /*Shared memory area */ + unsigned long rings_vstart; /*Kernel memory mapping */ + unsigned long user_vstart; /*User memory mapping */ + unsigned long dev_inuse; /*One process opens device at a time. */ + unsigned long dev_pending; /*In process of being opened */ + unsigned long ring_ok; /*make this ring->state */ + blkif_front_ring_t ufe_ring; /*Rings up to user space. */ + wait_queue_head_t wait; /*for poll */ + unsigned long mode; /*current switching mode */ + int minor; /*Minor number for tapdisk device */ + pid_t pid; /*tapdisk process id */ + enum { RUNNING, CLEANSHUTDOWN } status; /*Detect a clean userspace + shutdown */ + unsigned long *idx_map; /*Record the user ring id to kern + [req id, idx] tuple */ + blkif_t *blkif; /*Associate blkif with tapdev */ +} tap_blkif_t; + +/*Private data struct associated with the inode*/ +typedef struct private_info { + int idx; +} private_info_t; + +/*Data struct handed back to userspace for tapdisk device to VBD mapping*/ +typedef struct domid_translate { + unsigned short domid; + unsigned short busid; +} domid_translate_t ; -#include "blktap.h" -int __init xlblktap_init(void) +domid_translate_t translate_domid[MAX_TAP_DEV]; +tap_blkif_t *tapfds[MAX_TAP_DEV]; + +static int __init set_blkif_reqs(char *str) { - ctrl_msg_t cmsg; - blkif_fe_driver_status_t fe_st; - blkif_be_driver_status_t be_st; + get_option(&str, &blkif_reqs); + return 1; +} +__setup("blkif_reqs=", set_blkif_reqs); + +/* Run-time switchable: /sys/module/blktap/parameters/ */ +static unsigned int log_stats = 0; +static unsigned int debug_lvl = 0; +module_param(log_stats, int, 0644); +module_param(debug_lvl, int, 0644); + +/* + * Each outstanding request that we've passed to the lower device layers has a + * 'pending_req' allocated to it. Each buffer_head that completes decrements + * the pendcnt towards zero. When it hits zero, the specified domain has a + * response queued for it, with the saved 'id' passed back. + */ +typedef struct { + blkif_t *blkif; + unsigned long id; + unsigned short mem_idx; + int nr_pages; + atomic_t pendcnt; + unsigned short operation; + int status; + struct list_head free_list; + int inuse; +} pending_req_t; + +static pending_req_t *pending_reqs[MAX_PENDING_REQS]; +static struct list_head pending_free; +static DEFINE_SPINLOCK(pending_free_lock); +static DECLARE_WAIT_QUEUE_HEAD (pending_free_wq); +static int alloc_pending_reqs; + +typedef unsigned int PEND_RING_IDX; + +static inline int MASK_PEND_IDX(int i) { + return (i & (MAX_PENDING_REQS-1)); +} + +static inline unsigned int RTN_PEND_IDX(pending_req_t *req, int idx) { + return (req - pending_reqs[idx]); +} + +#define NR_PENDING_REQS (MAX_PENDING_REQS - pending_prod + pending_cons) + +#define BLKBACK_INVALID_HANDLE (~0) + +typedef struct mmap_page { + unsigned long start; + struct page *mpage; +} mmap_page_t; + +static mmap_page_t mmap_start[MAX_DYNAMIC_MEM]; +static unsigned short mmap_alloc = 0; +static unsigned short mmap_lock = 0; +static unsigned short mmap_inuse = 0; +static unsigned long *pending_addrs[MAX_DYNAMIC_MEM]; + +/****************************************************************** + * GRANT HANDLES + */ + +/* When using grant tables to map a frame for device access then the + * handle returned must be used to unmap the frame. This is needed to + * drop the ref count on the frame. + */ +struct grant_handle_pair +{ + grant_handle_t kernel; + grant_handle_t user; +}; + +static struct grant_handle_pair + pending_grant_handles[MAX_DYNAMIC_MEM][MMAP_PAGES]; +#define pending_handle(_id, _idx, _i) \ + (pending_grant_handles[_id][((_idx) * BLKIF_MAX_SEGMENTS_PER_REQUEST) \ + + (_i)]) - printk(KERN_INFO "Initialising Xen block tap device\n"); - DPRINTK(" tap - Backend connection init:\n"); +static int blktap_read_ufe_ring(int idx); /*local prototypes*/ +#define BLKTAP_MINOR 0 /*/dev/xen/blktap resides at device number + major=254, minor numbers begin at 0 */ +#define BLKTAP_DEV_MAJOR 254 /* TODO: Make major number dynamic * + * and create devices in the kernel * + */ +#define BLKTAP_DEV_DIR "/dev/xen" - (void)ctrl_if_register_receiver(CMSG_BLKIF_FE, blkif_ctrlif_rx, - CALLBACK_IN_BLOCKING_CONTEXT); +/* blktap IOCTLs: */ +#define BLKTAP_IOCTL_KICK_FE 1 +#define BLKTAP_IOCTL_KICK_BE 2 /* currently unused */ +#define BLKTAP_IOCTL_SETMODE 3 +#define BLKTAP_IOCTL_SENDPID 4 +#define BLKTAP_IOCTL_NEWINTF 5 +#define BLKTAP_IOCTL_MINOR 6 +#define BLKTAP_IOCTL_MAJOR 7 +#define BLKTAP_QUERY_ALLOC_REQS 8 +#define BLKTAP_IOCTL_FREEINTF 9 +#define BLKTAP_IOCTL_PRINT_IDXS 100 - /* Send a driver-UP notification to the domain controller. */ - cmsg.type = CMSG_BLKIF_FE; - cmsg.subtype = CMSG_BLKIF_FE_DRIVER_STATUS; - cmsg.length = sizeof(blkif_fe_driver_status_t); - fe_st.status = BLKIF_DRIVER_STATUS_UP; - memcpy(cmsg.msg, &fe_st, sizeof(fe_st)); - ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE); +/* blktap switching modes: (Set with BLKTAP_IOCTL_SETMODE) */ +#define BLKTAP_MODE_PASSTHROUGH 0x00000000 /* default */ +#define BLKTAP_MODE_INTERCEPT_FE 0x00000001 +#define BLKTAP_MODE_INTERCEPT_BE 0x00000002 /* unimp. */ + +#define BLKTAP_MODE_INTERPOSE \ + (BLKTAP_MODE_INTERCEPT_FE | BLKTAP_MODE_INTERCEPT_BE) + + +static inline int BLKTAP_MODE_VALID(unsigned long arg) +{ + return ((arg == BLKTAP_MODE_PASSTHROUGH ) || + (arg == BLKTAP_MODE_INTERCEPT_FE) || + (arg == BLKTAP_MODE_INTERPOSE )); +} + +/* Requests passing through the tap to userspace are re-assigned an ID. + * We must record a mapping between the BE [IDX,ID] tuple and the userspace + * ring ID. + */ + +static inline unsigned long MAKE_ID(domid_t fe_dom, PEND_RING_IDX idx) +{ + return ((fe_dom << 16) | MASK_PEND_IDX(idx)); +} + +extern inline PEND_RING_IDX ID_TO_IDX(unsigned long id) +{ + return (PEND_RING_IDX)(id & 0x0000ffff); +} + +extern inline int ID_TO_MIDX(unsigned long id) +{ + return (int)(id >> 16); +} + +#define INVALID_REQ 0xdead0000 + +/*TODO: Convert to a free list*/ +static inline int GET_NEXT_REQ(unsigned long *idx_map) +{ + int i; + for (i = 0; i < MAX_PENDING_REQS; i++) + if (idx_map[i] == INVALID_REQ) return i; + + return INVALID_REQ; +} + + +#define BLKTAP_INVALID_HANDLE(_g) \ + (((_g->kernel) == 0xFFFF) && ((_g->user) == 0xFFFF)) + +#define BLKTAP_INVALIDATE_HANDLE(_g) do { \ + (_g)->kernel = 0xFFFF; (_g)->user = 0xFFFF; \ + } while(0) + + +/****************************************************************** + * BLKTAP VM OPS + */ + +static struct page *blktap_nopage(struct vm_area_struct *vma, + unsigned long address, + int *type) +{ + /* + * if the page has not been mapped in by the driver then return + * NOPAGE_SIGBUS to the domain. + */ + + return NOPAGE_SIGBUS; +} + +struct vm_operations_struct blktap_vm_ops = { + nopage: blktap_nopage, +}; + +/****************************************************************** + * BLKTAP FILE OPS + */ + +/*Function Declarations*/ +static int get_next_free_dev(void); +static int blktap_open(struct inode *inode, struct file *filp); +static int blktap_release(struct inode *inode, struct file *filp); +static int blktap_mmap(struct file *filp, struct vm_area_struct *vma); +static int blktap_ioctl(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +static unsigned int blktap_poll(struct file *file, poll_table *wait); - DPRINTK(" tap - Frontend connection init:\n"); +struct miscdevice *set_misc(int minor, char *name, int dev); + +static struct file_operations blktap_fops = { + .owner = THIS_MODULE, + .poll = blktap_poll, + .ioctl = blktap_ioctl, + .open = blktap_open, + .release = blktap_release, + .mmap = blktap_mmap, +}; + + +static int get_next_free_dev(void) +{ + tap_blkif_t *info; + int i = 0, ret = -1; + unsigned long flags; + + spin_lock_irqsave(&pending_free_lock, flags); + + while (i < MAX_TAP_DEV) { + info = tapfds[i]; + if ( (tapfds[i] != NULL) && (info->dev_inuse == 0) + && (info->dev_pending == 0) ) { + info->dev_pending = 1; + ret = i; + goto done; + } + i++; + } + +done: + spin_unlock_irqrestore(&pending_free_lock, flags); + return ret; +} + +int dom_to_devid(domid_t domid, int xenbus_id, blkif_t *blkif) +{ + int i; + + for (i = 0; i < MAX_TAP_DEV; i++) + if ( (translate_domid[i].domid == domid) + && (translate_domid[i].busid == xenbus_id) ) { + tapfds[i]->blkif = blkif; + tapfds[i]->status = RUNNING; + return i; + } + return -1; +} + +void signal_tapdisk(int idx) +{ + tap_blkif_t *info; + struct task_struct *ptask; + + info = tapfds[idx]; + if ( (idx > 0) && (idx < MAX_TAP_DEV) && (info->pid > 0) ) { + ptask = find_task_by_pid(info->pid); + if (ptask) { + info->status = CLEANSHUTDOWN; + } + } + info->blkif = NULL; + return; +} + +static int blktap_open(struct inode *inode, struct file *filp) +{ + blkif_sring_t *sring; + int idx = iminor(inode) - BLKTAP_MINOR; + tap_blkif_t *info; + private_info_t *prv; + int i; + + if (tapfds[idx] == NULL) { + WPRINTK("Unable to open device /dev/xen/blktap%d\n", + idx); + return -ENOMEM; + } + DPRINTK("Opening device /dev/xen/blktap%d\n",idx); + + info = tapfds[idx]; + + /*Only one process can access device at a time*/ + if (test_and_set_bit(0, &info->dev_inuse)) + return -EBUSY; + + info->dev_pending = 0; + + /* Allocate the fe ring. */ + sring = (blkif_sring_t *)get_zeroed_page(GFP_KERNEL); + if (sring == NULL) + goto fail_nomem; + + SetPageReserved(virt_to_page(sring)); + + SHARED_RING_INIT(sring); + FRONT_RING_INIT(&info->ufe_ring, sring, PAGE_SIZE); + + prv = kzalloc(sizeof(private_info_t),GFP_KERNEL); + prv->idx = idx; + filp->private_data = prv; + info->vma = NULL; + + info->idx_map = kmalloc(sizeof(unsigned long) * MAX_PENDING_REQS, + GFP_KERNEL); + + if (idx > 0) { + init_waitqueue_head(&info->wait); + for (i = 0; i < MAX_PENDING_REQS; i++) + info->idx_map[i] = INVALID_REQ; + } + + DPRINTK("Tap open: device /dev/xen/blktap%d\n",idx); + return 0; + + fail_nomem: + return -ENOMEM; +} + +static int blktap_release(struct inode *inode, struct file *filp) +{ + int idx = iminor(inode) - BLKTAP_MINOR; + tap_blkif_t *info; + + if (tapfds[idx] == NULL) { + WPRINTK("Trying to free device that doesn't exist " + "[/dev/xen/blktap%d]\n",idx); + return -1; + } + info = tapfds[idx]; + info->dev_inuse = 0; + DPRINTK("Freeing device [/dev/xen/blktap%d]\n",idx); + + /* Free the ring page. */ + ClearPageReserved(virt_to_page(info->ufe_ring.sring)); + free_page((unsigned long) info->ufe_ring.sring); + + /* Clear any active mappings and free foreign map table */ + if (info->vma) { + zap_page_range( + info->vma, info->vma->vm_start, + info->vma->vm_end - info->vma->vm_start, NULL); + info->vma = NULL; + } + + if (filp->private_data) kfree(filp->private_data); + + if ( (info->status != CLEANSHUTDOWN) && (info->blkif != NULL) ) { + kthread_stop(info->blkif->xenblkd); + info->blkif->xenblkd = NULL; + info->status = CLEANSHUTDOWN; + } + return 0; +} + + +/* Note on mmap: + * We need to map pages to user space in a way that will allow the block + * subsystem set up direct IO to them. This couldn't be done before, because + * there isn't really a sane way to translate a user virtual address down to a + * physical address when the page belongs to another domain. + * + * My first approach was to map the page in to kernel memory, add an entry + * for it in the physical frame list (using alloc_lomem_region as in blkback) + * and then attempt to map that page up to user space. This is disallowed + * by xen though, which realizes that we don't really own the machine frame + * underlying the physical page. + * + * The new approach is to provide explicit support for this in xen linux. + * The VMA now has a flag, VM_FOREIGN, to indicate that it contains pages + * mapped from other vms. vma->vm_private_data is set up as a mapping + * from pages to actual page structs. There is a new clause in get_user_pages + * that does the right thing for this sort of mapping. + */ +static int blktap_mmap(struct file *filp, struct vm_area_struct *vma) +{ + int size; + struct page **map; + int i; + private_info_t *prv; + tap_blkif_t *info; + + /*Retrieve the dev info*/ + prv = (private_info_t *)filp->private_data; + if (prv == NULL) { + WPRINTK("blktap: mmap, retrieving idx failed\n"); + return -ENOMEM; + } + info = tapfds[prv->idx]; + + vma->vm_flags |= VM_RESERVED; + vma->vm_ops = &blktap_vm_ops; + + size = vma->vm_end - vma->vm_start; + if (size != ((mmap_pages + RING_PAGES) << PAGE_SHIFT)) { + WPRINTK("you _must_ map exactly %d pages!\n", + mmap_pages + RING_PAGES); + return -EAGAIN; + } + + size >>= PAGE_SHIFT; + info->rings_vstart = vma->vm_start; + info->user_vstart = info->rings_vstart + (RING_PAGES << PAGE_SHIFT); - active_reqs_init(); - blkif_interface_init(); - blkdev_schedule_init(); + /* Map the ring pages to the start of the region and reserve it. */ + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + + if (remap_pfn_range(vma, vma->vm_start, + __pa(info->ufe_ring.sring) >> PAGE_SHIFT, + PAGE_SIZE, vma->vm_page_prot)) { + WPRINTK("Mapping user ring failed!\n"); + goto fail; + } + + /* Mark this VM as containing foreign pages, and set up mappings. */ + map = kzalloc(((vma->vm_end - vma->vm_start) >> PAGE_SHIFT) + * sizeof(struct page_struct*), + GFP_KERNEL); + if (map == NULL) { + WPRINTK("Couldn't alloc VM_FOREIGN map.\n"); + goto fail; + } + + for (i = 0; i < ((vma->vm_end - vma->vm_start) >> PAGE_SHIFT); i++) + map[i] = NULL; - (void)ctrl_if_register_receiver(CMSG_BLKIF_BE, blkif_ctrlif_rx, - CALLBACK_IN_BLOCKING_CONTEXT); + vma->vm_private_data = map; + vma->vm_flags |= VM_FOREIGN; + + info->vma = vma; + info->ring_ok = 1; + return 0; + fail: + /* Clear any active mappings. */ + zap_page_range(vma, vma->vm_start, + vma->vm_end - vma->vm_start, NULL); - /* Send a driver-UP notification to the domain controller. */ - cmsg.type = CMSG_BLKIF_BE; - cmsg.subtype = CMSG_BLKIF_BE_DRIVER_STATUS; - cmsg.length = sizeof(blkif_be_driver_status_t); - be_st.status = BLKIF_DRIVER_STATUS_UP; - memcpy(cmsg.msg, &be_st, sizeof(be_st)); - ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE); + return -ENOMEM; +} - DPRINTK(" tap - Userland channel init:\n"); - blktap_init(); +static int blktap_ioctl(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + int idx = iminor(inode) - BLKTAP_MINOR; + switch(cmd) { + case BLKTAP_IOCTL_KICK_FE: + { + /* There are fe messages to process. */ + return blktap_read_ufe_ring(idx); + } + case BLKTAP_IOCTL_SETMODE: + { + tap_blkif_t *info = tapfds[idx]; + + if ( (idx > 0) && (idx < MAX_TAP_DEV) + && (tapfds[idx] != NULL) ) + { + if (BLKTAP_MODE_VALID(arg)) { + info->mode = arg; + /* XXX: may need to flush rings here. */ + DPRINTK("blktap: set mode to %lx\n", + arg); + return 0; + } + } + return 0; + } + case BLKTAP_IOCTL_PRINT_IDXS: + { + tap_blkif_t *info = tapfds[idx]; + + if ( (idx > 0) && (idx < MAX_TAP_DEV) + && (tapfds[idx] != NULL) ) + { + printk("User Rings: \n-----------\n"); + printk("UF: rsp_cons: %2d, req_prod_prv: %2d " + "| req_prod: %2d, rsp_prod: %2d\n", + info->ufe_ring.rsp_cons, + info->ufe_ring.req_prod_pvt, + info->ufe_ring.sring->req_prod, + info->ufe_ring.sring->rsp_prod); + } + return 0; + } + case BLKTAP_IOCTL_SENDPID: + { + tap_blkif_t *info = tapfds[idx]; + + if ( (idx > 0) && (idx < MAX_TAP_DEV) + && (tapfds[idx] != NULL) ) + { + info->pid = (pid_t)arg; + DPRINTK("blktap: pid received %d\n", + info->pid); + } + return 0; + } + case BLKTAP_IOCTL_NEWINTF: + { + uint64_t val = (uint64_t)arg; + domid_translate_t *tr = (domid_translate_t *)&val; + int newdev; - DPRINTK("Blkif tap device initialized.\n"); + DPRINTK("NEWINTF Req for domid %d and bus id %d\n", + tr->domid, tr->busid); + newdev = get_next_free_dev(); + if (newdev < 1) { + WPRINTK("Error initialising /dev/xen/blktap - " + "No more devices\n"); + return -1; + } + translate_domid[newdev].domid = tr->domid; + translate_domid[newdev].busid = tr->busid; + return newdev; + } + case BLKTAP_IOCTL_FREEINTF: + { + unsigned long dev = arg; + tap_blkif_t *info = NULL; - return 0; + if ( (dev > 0) && (dev < MAX_TAP_DEV) ) info = tapfds[dev]; + + if ( (info != NULL) && (info->dev_pending) ) + info->dev_pending = 0; + return 0; + } + case BLKTAP_IOCTL_MINOR: + { + unsigned long dev = arg; + tap_blkif_t *info = NULL; + + if ( (dev > 0) && (dev < MAX_TAP_DEV) ) info = tapfds[dev]; + + if (info != NULL) return info->minor; + else return -1; + } + case BLKTAP_IOCTL_MAJOR: + return BLKTAP_DEV_MAJOR; + + case BLKTAP_QUERY_ALLOC_REQS: + { + WPRINTK("BLKTAP_QUERY_ALLOC_REQS ioctl: %d/%d\n", + alloc_pending_reqs, blkif_reqs); + return (alloc_pending_reqs/blkif_reqs) * 100; + } + } + return -ENOIOCTLCMD; } -#if 0 /* tap doesn't handle suspend/resume */ -void blkdev_suspend(void) +static unsigned int blktap_poll(struct file *file, poll_table *wait) { + private_info_t *prv; + tap_blkif_t *info; + + /*Retrieve the dev info*/ + prv = (private_info_t *)file->private_data; + if (prv == NULL) { + WPRINTK(" poll, retrieving idx failed\n"); + return 0; + } + + if (prv->idx == 0) return 0; + + info = tapfds[prv->idx]; + + poll_wait(file, &info->wait, wait); + if (info->ufe_ring.req_prod_pvt != info->ufe_ring.sring->req_prod) { + flush_tlb_all(); + RING_PUSH_REQUESTS(&info->ufe_ring); + return POLLIN | POLLRDNORM; + } + return 0; } -void blkdev_resume(void) +void blktap_kick_user(int idx) { - ctrl_msg_t cmsg; - blkif_fe_driver_status_t st; + tap_blkif_t *info; - /* Send a driver-UP notification to the domain controller. */ - cmsg.type = CMSG_BLKIF_FE; - cmsg.subtype = CMSG_BLKIF_FE_DRIVER_STATUS; - cmsg.length = sizeof(blkif_fe_driver_status_t); - st.status = BLKIF_DRIVER_STATUS_UP; - memcpy(cmsg.msg, &st, sizeof(st)); - ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE); + if (idx == 0) return; + + info = tapfds[idx]; + + if (info != NULL) wake_up_interruptible(&info->wait); + return; } + +static int do_block_io_op(blkif_t *blkif); +static void dispatch_rw_block_io(blkif_t *blkif, + blkif_request_t *req, + pending_req_t *pending_req); +static void make_response(blkif_t *blkif, unsigned long id, + unsigned short op, int st); + +/****************************************************************** + * misc small helpers + */ +static int req_increase(void) +{ + int i, j; + struct page *page; + unsigned long flags; + int ret; + + spin_lock_irqsave(&pending_free_lock, flags); + + ret = -EINVAL; + if (mmap_alloc >= MAX_PENDING_REQS || mmap_lock) + goto done; + +#ifdef __ia64__ + extern unsigned long alloc_empty_foreign_map_page_range( + unsigned long pages); + mmap_start[mmap_alloc].start = (unsigned long) + alloc_empty_foreign_map_page_range(mmap_pages); +#else /* ! ia64 */ + page = balloon_alloc_empty_page_range(mmap_pages); + ret = -ENOMEM; + if (page == NULL) { + printk("%s balloon_alloc_empty_page_range gave NULL\n", __FUNCTION__); + goto done; + } + + /* Pin all of the pages. */ + for (i=0; iinuse == 0) { + list_del(&req->free_list); + mmap_inuse--; + } + } + if (mmap_inuse == 0) mmap_req_del(mmap_alloc-1); + done: + spin_unlock_irqrestore(&pending_free_lock, flags); + return; +} + +static pending_req_t* alloc_req(void) +{ + pending_req_t *req = NULL; + unsigned long flags; + + spin_lock_irqsave(&pending_free_lock, flags); + + if (!list_empty(&pending_free)) { + req = list_entry(pending_free.next, pending_req_t, free_list); + list_del(&req->free_list); + } + + if (req) { + req->inuse = 1; + alloc_pending_reqs++; + } + spin_unlock_irqrestore(&pending_free_lock, flags); + + return req; +} + +static void free_req(pending_req_t *req) +{ + unsigned long flags; + int was_empty; + + spin_lock_irqsave(&pending_free_lock, flags); + + alloc_pending_reqs--; + req->inuse = 0; + if (mmap_lock && (req->mem_idx == mmap_alloc-1)) { + mmap_inuse--; + if (mmap_inuse == 0) mmap_req_del(mmap_alloc-1); + spin_unlock_irqrestore(&pending_free_lock, flags); + return; + } + was_empty = list_empty(&pending_free); + list_add(&req->free_list, &pending_free); + + spin_unlock_irqrestore(&pending_free_lock, flags); + + if (was_empty) + wake_up(&pending_free_wq); +} + +static void fast_flush_area(pending_req_t *req, int k_idx, int u_idx, int + tapidx) +{ + struct gnttab_unmap_grant_ref unmap[BLKIF_MAX_SEGMENTS_PER_REQUEST*2]; + unsigned int i, invcount = 0; + struct grant_handle_pair *khandle; + uint64_t ptep; + int ret, mmap_idx; + unsigned long kvaddr, uvaddr; + + tap_blkif_t *info = tapfds[tapidx]; + + if (info == NULL) { + WPRINTK("fast_flush: Couldn't get info!\n"); + return; + } + mmap_idx = req->mem_idx; + + for (i = 0; i < req->nr_pages; i++) { + kvaddr = MMAP_VADDR(mmap_start[mmap_idx].start, k_idx, i); + uvaddr = MMAP_VADDR(info->user_vstart, u_idx, i); + + khandle = &pending_handle(mmap_idx, k_idx, i); + if (BLKTAP_INVALID_HANDLE(khandle)) { + WPRINTK("BLKTAP_INVALID_HANDLE\n"); + continue; + } + gnttab_set_unmap_op(&unmap[invcount], + MMAP_VADDR(mmap_start[mmap_idx].start, k_idx, i), + GNTMAP_host_map, khandle->kernel); + invcount++; + + if (create_lookup_pte_addr( + info->vma->vm_mm, + MMAP_VADDR(info->user_vstart, u_idx, i), + &ptep) !=0) { + WPRINTK("Couldn't get a pte addr!\n"); + return; + } + + gnttab_set_unmap_op(&unmap[invcount], + ptep, GNTMAP_host_map, + khandle->user); + invcount++; + + BLKTAP_INVALIDATE_HANDLE(khandle); + } + ret = HYPERVISOR_grant_table_op( + GNTTABOP_unmap_grant_ref, unmap, invcount); + BUG_ON(ret); + + if (info->vma != NULL) + zap_page_range(info->vma, + MMAP_VADDR(info->user_vstart, u_idx, 0), + req->nr_pages << PAGE_SHIFT, NULL); +} + +/****************************************************************** + * SCHEDULER FUNCTIONS + */ + +static void print_stats(blkif_t *blkif) +{ + printk(KERN_DEBUG "%s: oo %3d | rd %4d | wr %4d\n", + current->comm, blkif->st_oo_req, + blkif->st_rd_req, blkif->st_wr_req); + blkif->st_print = jiffies + msecs_to_jiffies(10 * 1000); + blkif->st_rd_req = 0; + blkif->st_wr_req = 0; + blkif->st_oo_req = 0; +} + +int tap_blkif_schedule(void *arg) +{ + blkif_t *blkif = arg; + + blkif_get(blkif); + + if (debug_lvl) + printk(KERN_DEBUG "%s: started\n", current->comm); + + while (!kthread_should_stop()) { + wait_event_interruptible( + blkif->wq, + blkif->waiting_reqs || kthread_should_stop()); + wait_event_interruptible( + pending_free_wq, + !list_empty(&pending_free) || kthread_should_stop()); + + blkif->waiting_reqs = 0; + smp_mb(); /* clear flag *before* checking for work */ + + if (do_block_io_op(blkif)) + blkif->waiting_reqs = 1; + + if (log_stats && time_after(jiffies, blkif->st_print)) + print_stats(blkif); + } + + if (log_stats) + print_stats(blkif); + if (debug_lvl) + printk(KERN_DEBUG "%s: exiting\n", current->comm); + + blkif->xenblkd = NULL; + blkif_put(blkif); + + return 0; +} + +/****************************************************************** + * COMPLETION CALLBACK -- Called by user level ioctl() + */ + +static int blktap_read_ufe_ring(int idx) +{ + /* This is called to read responses from the UFE ring. */ + RING_IDX i, j, rp; + blkif_response_t *resp; + blkif_t *blkif=NULL; + int pending_idx, usr_idx, mmap_idx; + pending_req_t *pending_req; + tap_blkif_t *info; + + info = tapfds[idx]; + if (info == NULL) { + return 0; + } + + /* We currently only forward packets in INTERCEPT_FE mode. */ + if (!(info->mode & BLKTAP_MODE_INTERCEPT_FE)) + return 0; + + /* for each outstanding message on the UFEring */ + rp = info->ufe_ring.sring->rsp_prod; + rmb(); + + for (i = info->ufe_ring.rsp_cons; i != rp; i++) { + resp = RING_GET_RESPONSE(&info->ufe_ring, i); + ++info->ufe_ring.rsp_cons; + + /*retrieve [usr_idx] to [mmap_idx,pending_idx] mapping*/ + usr_idx = (int)resp->id; + pending_idx = MASK_PEND_IDX(ID_TO_IDX(info->idx_map[usr_idx])); + mmap_idx = ID_TO_MIDX(info->idx_map[usr_idx]); + + if ( (mmap_idx >= mmap_alloc) || + (ID_TO_IDX(info->idx_map[usr_idx]) >= MAX_PENDING_REQS) ) + WPRINTK("Incorrect req map" + "[%d], internal map [%d,%d (%d)]\n", + usr_idx, mmap_idx, + ID_TO_IDX(info->idx_map[usr_idx]), + MASK_PEND_IDX( + ID_TO_IDX(info->idx_map[usr_idx]))); + + pending_req = &pending_reqs[mmap_idx][pending_idx]; + blkif = pending_req->blkif; + + for (j = 0; j < pending_req->nr_pages; j++) { + + unsigned long kvaddr, uvaddr; + struct page **map = info->vma->vm_private_data; + struct page *pg; + int offset; + + uvaddr = MMAP_VADDR(info->user_vstart, usr_idx, j); + kvaddr = MMAP_VADDR(mmap_start[mmap_idx].start, + pending_idx, j); + + pg = pfn_to_page(__pa(kvaddr) >> PAGE_SHIFT); + ClearPageReserved(pg); + offset = (uvaddr - info->vma->vm_start) + >> PAGE_SHIFT; + map[offset] = NULL; + } + fast_flush_area(pending_req, pending_idx, usr_idx, idx); + make_response(blkif, pending_req->id, resp->operation, + resp->status); + info->idx_map[usr_idx] = INVALID_REQ; + blkif_put(pending_req->blkif); + free_req(pending_req); + } + + return 0; +} + + +/****************************************************************************** + * NOTIFICATION FROM GUEST OS. + */ + +static void blkif_notify_work(blkif_t *blkif) +{ + blkif->waiting_reqs = 1; + wake_up(&blkif->wq); +} + +irqreturn_t tap_blkif_be_int(int irq, void *dev_id, struct pt_regs *regs) +{ + blkif_notify_work(dev_id); + return IRQ_HANDLED; +} + + + +/****************************************************************** + * DOWNWARD CALLS -- These interface with the block-device layer proper. + */ +static int print_dbug = 1; +static int do_block_io_op(blkif_t *blkif) +{ + blkif_back_ring_t *blk_ring = &blkif->blk_ring; + blkif_request_t *req; + pending_req_t *pending_req; + RING_IDX rc, rp; + int more_to_do = 0; + tap_blkif_t *info; + + rc = blk_ring->req_cons; + rp = blk_ring->sring->req_prod; + rmb(); /* Ensure we see queued requests up to 'rp'. */ + + /*Check blkif has corresponding UE ring*/ + if (blkif->dev_num == -1) { + /*oops*/ + if (print_dbug) { + WPRINTK("Corresponding UE " + "ring does not exist!\n"); + print_dbug = 0; /*We only print this message once*/ + } + return 1; + } + + info = tapfds[blkif->dev_num]; + if (info == NULL || !info->dev_inuse) { + if (print_dbug) { + WPRINTK("Can't get UE info!\n"); + print_dbug = 0; + } + return 1; + } + + while (rc != rp) { + + if (RING_FULL(&info->ufe_ring)) { + WPRINTK("RING_FULL! More to do\n"); + more_to_do = 1; + break; + } + + if (RING_REQUEST_CONS_OVERFLOW(blk_ring, rc)) { + WPRINTK("RING_REQUEST_CONS_OVERFLOW!" + " More to do\n"); + more_to_do = 1; + break; + } + + pending_req = alloc_req(); + if (NULL == pending_req) { + blkif->st_oo_req++; + more_to_do = 1; + break; + } + + req = RING_GET_REQUEST(blk_ring, rc); + blk_ring->req_cons = ++rc; /* before make_response() */ + + switch (req->operation) { + case BLKIF_OP_READ: + blkif->st_rd_req++; + dispatch_rw_block_io(blkif, req, pending_req); + break; + + case BLKIF_OP_WRITE: + blkif->st_wr_req++; + dispatch_rw_block_io(blkif, req, pending_req); + break; + + default: + WPRINTK("unknown operation [%d]\n", + req->operation); + make_response(blkif, req->id, req->operation, + BLKIF_RSP_ERROR); + free_req(pending_req); + break; + } + } + + blktap_kick_user(blkif->dev_num); + + return more_to_do; +} + +static void dispatch_rw_block_io(blkif_t *blkif, + blkif_request_t *req, + pending_req_t *pending_req) +{ + extern void ll_rw_block(int rw, int nr, struct buffer_head * bhs[]); + int op, operation = (req->operation == BLKIF_OP_WRITE) ? WRITE : READ; + struct gnttab_map_grant_ref map[BLKIF_MAX_SEGMENTS_PER_REQUEST*2]; + unsigned int nseg; + int ret, i; + tap_blkif_t *info = tapfds[blkif->dev_num]; + uint64_t sector; + + blkif_request_t *target; + int pending_idx = RTN_PEND_IDX(pending_req,pending_req->mem_idx); + int usr_idx = GET_NEXT_REQ(info->idx_map); + uint16_t mmap_idx = pending_req->mem_idx; + + /*Check we have space on user ring - should never fail*/ + if(usr_idx == INVALID_REQ) goto fail_flush; + + /* Check that number of segments is sane. */ + nseg = req->nr_segments; + if ( unlikely(nseg == 0) || + unlikely(nseg > BLKIF_MAX_SEGMENTS_PER_REQUEST) ) { + WPRINTK("Bad number of segments in request (%d)\n", nseg); + goto fail_response; + } + + /* Make sure userspace is ready. */ + if (!info->ring_ok) { + WPRINTK("blktap: ring not ready for requests!\n"); + goto fail_response; + } + + if (RING_FULL(&info->ufe_ring)) { + WPRINTK("blktap: fe_ring is full, can't add " + "IO Request will be dropped. %d %d\n", + RING_SIZE(&info->ufe_ring), + RING_SIZE(&blkif->blk_ring)); + goto fail_response; + } + + pending_req->blkif = blkif; + pending_req->id = req->id; + pending_req->operation = operation; + pending_req->status = BLKIF_RSP_OKAY; + pending_req->nr_pages = nseg; + op = 0; + for (i = 0; i < nseg; i++) { + unsigned long uvaddr; + unsigned long kvaddr; + uint64_t ptep; + struct page *page; + uint32_t flags; + + uvaddr = MMAP_VADDR(info->user_vstart, usr_idx, i); + kvaddr = MMAP_VADDR(mmap_start[mmap_idx].start, + pending_idx, i); + page = virt_to_page(kvaddr); + + sector = req->sector_number + (8*i); + if( (blkif->sectors > 0) && (sector >= blkif->sectors) ) { + WPRINTK("BLKTAP: Sector request greater" + "than size\n"); + WPRINTK("BLKTAP: %s request sector" + "[%llu,%llu], Total [%llu]\n", + (req->operation == + BLKIF_OP_WRITE ? "WRITE" : "READ"), + (long long unsigned) sector, + (long long unsigned) sector>>9, + blkif->sectors); + } + + flags = GNTMAP_host_map; + if (operation == WRITE) + flags |= GNTMAP_readonly; + gnttab_set_map_op(&map[op], kvaddr, flags, + req->seg[i].gref, blkif->domid); + op++; + + /* Now map it to user. */ + ret = create_lookup_pte_addr(info->vma->vm_mm, + uvaddr, &ptep); + if (ret) { + WPRINTK("Couldn't get a pte addr!\n"); + fast_flush_area(pending_req, pending_idx, usr_idx, + blkif->dev_num); + goto fail_flush; + } + + flags = GNTMAP_host_map | GNTMAP_application_map + | GNTMAP_contains_pte; + if (operation == WRITE) + flags |= GNTMAP_readonly; + gnttab_set_map_op(&map[op], ptep, flags, + req->seg[i].gref, blkif->domid); + op++; + } + + ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, map, op); + BUG_ON(ret); + + for (i = 0; i < (nseg*2); i+=2) { + unsigned long uvaddr; + unsigned long kvaddr; + unsigned long offset; + struct page *pg; + + uvaddr = MMAP_VADDR(info->user_vstart, usr_idx, i/2); + kvaddr = MMAP_VADDR(mmap_start[mmap_idx].start, + pending_idx, i/2); + + if (unlikely(map[i].status != 0)) { + WPRINTK("invalid kernel buffer -- " + "could not remap it\n"); + goto fail_flush; + } + + if (unlikely(map[i+1].status != 0)) { + WPRINTK("invalid user buffer -- " + "could not remap it\n"); + goto fail_flush; + } + + pending_handle(mmap_idx, pending_idx, i/2).kernel + = map[i].handle; + pending_handle(mmap_idx, pending_idx, i/2).user + = map[i+1].handle; + set_phys_to_machine(__pa(kvaddr) >> PAGE_SHIFT, + FOREIGN_FRAME(map[i].dev_bus_addr >> PAGE_SHIFT)); + offset = (uvaddr - info->vma->vm_start) >> PAGE_SHIFT; + pg = pfn_to_page(__pa(kvaddr) >> PAGE_SHIFT); + ((struct page **)info->vma->vm_private_data)[offset] = + pg; + } + /* Mark mapped pages as reserved: */ + for (i = 0; i < req->nr_segments; i++) { + unsigned long kvaddr; + struct page *pg; + + kvaddr = MMAP_VADDR(mmap_start[mmap_idx].start, + pending_idx, i); + pg = pfn_to_page(__pa(kvaddr) >> PAGE_SHIFT); + SetPageReserved(pg); + } + + /*record [mmap_idx,pending_idx] to [usr_idx] mapping*/ + info->idx_map[usr_idx] = MAKE_ID(mmap_idx, pending_idx); + + blkif_get(blkif); + /* Finally, write the request message to the user ring. */ + target = RING_GET_REQUEST(&info->ufe_ring, + info->ufe_ring.req_prod_pvt); + memcpy(target, req, sizeof(*req)); + target->id = usr_idx; + info->ufe_ring.req_prod_pvt++; + return; + + fail_flush: + WPRINTK("Reached Fail_flush\n"); + fast_flush_area(pending_req, pending_idx, usr_idx, blkif->dev_num); + fail_response: + make_response(blkif, req->id, req->operation, BLKIF_RSP_ERROR); + free_req(pending_req); +} + + + +/****************************************************************** + * MISCELLANEOUS SETUP / TEARDOWN / DEBUGGING + */ + + +static void make_response(blkif_t *blkif, unsigned long id, + unsigned short op, int st) +{ + blkif_response_t *resp; + unsigned long flags; + blkif_back_ring_t *blk_ring = &blkif->blk_ring; + int more_to_do = 0; + int notify; + + spin_lock_irqsave(&blkif->blk_ring_lock, flags); + /* Place on the response ring for the relevant domain. */ + resp = RING_GET_RESPONSE(blk_ring, blk_ring->rsp_prod_pvt); + resp->id = id; + resp->operation = op; + resp->status = st; + blk_ring->rsp_prod_pvt++; + RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(blk_ring, notify); + + if (blk_ring->rsp_prod_pvt == blk_ring->req_cons) { + /* + * Tail check for pending requests. Allows frontend to avoid + * notifications if requests are already in flight (lower + * overheads and promotes batching). + */ + RING_FINAL_CHECK_FOR_REQUESTS(blk_ring, more_to_do); + } else if (RING_HAS_UNCONSUMED_REQUESTS(blk_ring)) { + more_to_do = 1; + + } + spin_unlock_irqrestore(&blkif->blk_ring_lock, flags); + if (more_to_do) + blkif_notify_work(blkif); + if (notify) + notify_remote_via_irq(blkif->irq); +} + +static int __init blkif_init(void) +{ + int i,ret,blktap_dir; + tap_blkif_t *info; + + if (!is_running_on_xen()) + return -ENODEV; + + INIT_LIST_HEAD(&pending_free); + for(i = 0; i < 2; i++) { + ret = req_increase(); + if (ret) + break; + } + if (i == 0) + return ret; + + tap_blkif_interface_init(); + + alloc_pending_reqs = 0; + + tap_blkif_xenbus_init(); + + /*Create the blktap devices, but do not map memory or waitqueue*/ + for(i = 0; i < MAX_TAP_DEV; i++) translate_domid[i].domid = 0xFFFF; + + ret = register_chrdev(BLKTAP_DEV_MAJOR,"blktap",&blktap_fops); + blktap_dir = devfs_mk_dir(NULL, "xen", 0, NULL); + + if ( (ret < 0)||(blktap_dir < 0) ) { + WPRINTK("Couldn't register /dev/xen/blktap\n"); + return -ENOMEM; + } + + for(i = 0; i < MAX_TAP_DEV; i++ ) { + info = tapfds[i] = kzalloc(sizeof(tap_blkif_t),GFP_KERNEL); + if(tapfds[i] == NULL) return -ENOMEM; + info->minor = i; + info->pid = 0; + info->blkif = NULL; + + ret = devfs_mk_cdev(MKDEV(BLKTAP_DEV_MAJOR, i), + S_IFCHR|S_IRUGO|S_IWUSR, "xen/blktap%d", i); + + if(ret != 0) return -ENOMEM; + info->dev_pending = info->dev_inuse = 0; + + DPRINTK("Created misc_dev [/dev/xen/blktap%d]\n",i); + } + + DPRINTK("Blktap device successfully created\n"); + + return 0; +} + +module_init(blkif_init); + +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/xen/console/Makefile b/drivers/xen/console/Makefile index e4ffdeffc..35de3e933 100644 --- a/drivers/xen/console/Makefile +++ b/drivers/xen/console/Makefile @@ -1,2 +1,2 @@ -obj-y := console.o +obj-y := console.o xencons_ring.o diff --git a/drivers/xen/console/console.c b/drivers/xen/console/console.c index 142ca2baa..ec7dd9e58 100644 --- a/drivers/xen/console/console.c +++ b/drivers/xen/console/console.c @@ -5,8 +5,11 @@ * * Copyright (c) 2002-2004, K A Fraser. * - * This file may be distributed separately from the Linux kernel, or - * incorporated into other software packages, subject to the following license: + * 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; or, when distributed + * separately from the Linux kernel or incorporated into other + * software packages, subject to the following license: * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this source file (the "Software"), to deal in the Software without @@ -45,13 +48,15 @@ #include #include #include +#include #include #include #include -#include -#include -#include -#include +#include +#include +#include +#include +#include /* * Modes: @@ -66,33 +71,39 @@ static enum { XC_OFF, XC_DEFAULT, XC_TTY, XC_SERIAL } xc_mode = XC_DEFAULT; static int xc_num = -1; +#ifdef CONFIG_MAGIC_SYSRQ +static unsigned long sysrq_requested; +extern int sysrq_enabled; +#endif + static int __init xencons_setup(char *str) { - char *q; - int n; - - if ( !strncmp(str, "ttyS", 4) ) - xc_mode = XC_SERIAL; - else if ( !strncmp(str, "tty", 3) ) - xc_mode = XC_TTY; - else if ( !strncmp(str, "off", 3) ) - xc_mode = XC_OFF; - - switch ( xc_mode ) - { - case XC_SERIAL: - n = simple_strtol( str+4, &q, 10 ); - if ( q > (str + 4) ) xc_num = n; - break; - case XC_TTY: - n = simple_strtol( str+3, &q, 10 ); - if ( q > (str + 3) ) xc_num = n; - break; - default: - break; - } - - return 1; + char *q; + int n; + + if (!strncmp(str, "ttyS", 4)) + xc_mode = XC_SERIAL; + else if (!strncmp(str, "tty", 3)) + xc_mode = XC_TTY; + else if (!strncmp(str, "off", 3)) + xc_mode = XC_OFF; + + switch (xc_mode) { + case XC_SERIAL: + n = simple_strtol(str+4, &q, 10); + if (q > (str + 4)) + xc_num = n; + break; + case XC_TTY: + n = simple_strtol(str+3, &q, 10); + if (q > (str + 3)) + xc_num = n; + break; + default: + break; + } + + return 1; } __setup("xencons=", xencons_setup); @@ -104,210 +115,158 @@ static unsigned int wc, wp; /* write_cons, write_prod */ static int __init xencons_bufsz_setup(char *str) { - unsigned int goal; - goal = simple_strtoul(str, NULL, 0); - while ( wbuf_size < goal ) - wbuf_size <<= 1; - return 1; + unsigned int goal; + goal = simple_strtoul(str, NULL, 0); + if (goal) { + goal = roundup_pow_of_two(goal); + if (wbuf_size < goal) + wbuf_size = goal; + } + return 1; } __setup("xencons_bufsz=", xencons_bufsz_setup); /* This lock protects accesses to the common transmit buffer. */ -static spinlock_t xencons_lock = SPIN_LOCK_UNLOCKED; +static DEFINE_SPINLOCK(xencons_lock); /* Common transmit-kick routine. */ static void __xencons_tx_flush(void); -/* This task is used to defer sending console data until there is space. */ -static void xencons_tx_flush_task_routine(void *data); - -static DECLARE_TQUEUE(xencons_tx_flush_task, - xencons_tx_flush_task_routine, - NULL); - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) static struct tty_driver *xencons_driver; -#else -static struct tty_driver xencons_driver; -#endif - /******************** Kernel console driver ********************************/ -static void kcons_write( - struct console *c, const char *s, unsigned int count) +static void kcons_write(struct console *c, const char *s, unsigned int count) { - int i; - unsigned long flags; - - spin_lock_irqsave(&xencons_lock, flags); - - for ( i = 0; i < count; i++ ) - { - if ( (wp - wc) >= (wbuf_size - 1) ) - break; - if ( (wbuf[WBUF_MASK(wp++)] = s[i]) == '\n' ) - wbuf[WBUF_MASK(wp++)] = '\r'; - } - - __xencons_tx_flush(); - - spin_unlock_irqrestore(&xencons_lock, flags); + int i = 0; + unsigned long flags; + + spin_lock_irqsave(&xencons_lock, flags); + + while (i < count) { + for (; i < count; i++) { + if ((wp - wc) >= (wbuf_size - 1)) + break; + if ((wbuf[WBUF_MASK(wp++)] = s[i]) == '\n') + wbuf[WBUF_MASK(wp++)] = '\r'; + } + + __xencons_tx_flush(); + } + + spin_unlock_irqrestore(&xencons_lock, flags); } -static void kcons_write_dom0( - struct console *c, const char *s, unsigned int count) +static void kcons_write_dom0(struct console *c, const char *s, unsigned int count) { - int rc; - - while ( (count > 0) && - ((rc = HYPERVISOR_console_io( - CONSOLEIO_write, count, (char *)s)) > 0) ) - { - count -= rc; - s += rc; - } + + while (count > 0) { + int rc; + rc = HYPERVISOR_console_io( CONSOLEIO_write, count, (char *)s); + if (rc <= 0) + break; + count -= rc; + s += rc; + } } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) static struct tty_driver *kcons_device(struct console *c, int *index) { - *index = c->index; - return xencons_driver; -} -#else -static kdev_t kcons_device(struct console *c) -{ - return MKDEV(TTY_MAJOR, (xc_mode == XC_SERIAL) ? 64 : 1); + *index = 0; + return xencons_driver; } -#endif static struct console kcons_info = { - device: kcons_device, - flags: CON_PRINTBUFFER, - index: -1 + .device = kcons_device, + .flags = CON_PRINTBUFFER | CON_ENABLED, + .index = -1, }; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) #define __RETCODE 0 static int __init xen_console_init(void) -#else -#define __RETCODE -void xen_console_init(void) -#endif { - if ( xen_start_info.flags & SIF_INITDOMAIN ) - { - if ( xc_mode == XC_DEFAULT ) - xc_mode = XC_SERIAL; - kcons_info.write = kcons_write_dom0; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) - if ( xc_mode == XC_SERIAL ) - kcons_info.flags |= CON_ENABLED; -#endif - } - else - { - if ( xc_mode == XC_DEFAULT ) - xc_mode = XC_TTY; - kcons_info.write = kcons_write; - } - - switch ( xc_mode ) - { - case XC_SERIAL: - strcpy(kcons_info.name, "ttyS"); - if ( xc_num == -1 ) xc_num = 0; - break; - - case XC_TTY: - strcpy(kcons_info.name, "tty"); - if ( xc_num == -1 ) xc_num = 1; - break; - - default: - return __RETCODE; - } - - wbuf = alloc_bootmem(wbuf_size); - - register_console(&kcons_info); - - return __RETCODE; + if (!is_running_on_xen()) + return __RETCODE; + + if (xen_start_info->flags & SIF_INITDOMAIN) { + if (xc_mode == XC_DEFAULT) + xc_mode = XC_SERIAL; + kcons_info.write = kcons_write_dom0; + } else { + if (xc_mode == XC_DEFAULT) + xc_mode = XC_TTY; + kcons_info.write = kcons_write; + } + + switch (xc_mode) { + case XC_SERIAL: + strcpy(kcons_info.name, "ttyS"); + if (xc_num == -1) + xc_num = 0; + break; + + case XC_TTY: + strcpy(kcons_info.name, "tty"); + if (xc_num == -1) + xc_num = 1; + break; + + default: + return __RETCODE; + } + + wbuf = alloc_bootmem(wbuf_size); + + register_console(&kcons_info); + + return __RETCODE; } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) console_initcall(xen_console_init); -#endif /*** Useful function for console debugging -- goes straight to Xen. ***/ asmlinkage int xprintk(const char *fmt, ...) { - va_list args; - int printk_len; - static char printk_buf[1024]; - - /* Emit the output into the temporary buffer */ - va_start(args, fmt); - printk_len = vsnprintf(printk_buf, sizeof(printk_buf), fmt, args); - va_end(args); - - /* Send the processed output directly to Xen. */ - kcons_write_dom0(NULL, printk_buf, printk_len); - - return 0; + va_list args; + int printk_len; + static char printk_buf[1024]; + + /* Emit the output into the temporary buffer */ + va_start(args, fmt); + printk_len = vsnprintf(printk_buf, sizeof(printk_buf), fmt, args); + va_end(args); + + /* Send the processed output directly to Xen. */ + kcons_write_dom0(NULL, printk_buf, printk_len); + + return 0; } /*** Forcibly flush console data before dying. ***/ void xencons_force_flush(void) { - ctrl_msg_t msg; - int sz; - - /* Emergency console is synchronous, so there's nothing to flush. */ - if ( xen_start_info.flags & SIF_INITDOMAIN ) - return; - - /* - * We use dangerous control-interface functions that require a quiescent - * system and no interrupts. Try to ensure this with a global cli(). - */ - local_irq_disable(); /* XXXsmp */ - - /* Spin until console data is flushed through to the domain controller. */ - while ( (wc != wp) && !ctrl_if_transmitter_empty() ) - { - /* Interrupts are disabled -- we must manually reap responses. */ - ctrl_if_discard_responses(); - - if ( (sz = wp - wc) == 0 ) - continue; - if ( sz > sizeof(msg.msg) ) - sz = sizeof(msg.msg); - if ( sz > (wbuf_size - WBUF_MASK(wc)) ) - sz = wbuf_size - WBUF_MASK(wc); - - msg.type = CMSG_CONSOLE; - msg.subtype = CMSG_CONSOLE_DATA; - msg.length = sz; - memcpy(msg.msg, &wbuf[WBUF_MASK(wc)], sz); - - if ( ctrl_if_send_message_noblock(&msg, NULL, 0) == 0 ) - wc += sz; - } + int sz; + + /* Emergency console is synchronous, so there's nothing to flush. */ + if (xen_start_info->flags & SIF_INITDOMAIN) + return; + + /* Spin until console data is flushed through to the daemon. */ + while (wc != wp) { + int sent = 0; + if ((sz = wp - wc) == 0) + continue; + sent = xencons_ring_send(&wbuf[WBUF_MASK(wc)], sz); + if (sent > 0) + wc += sent; + } } /******************** User-space console driver (/dev/console) ************/ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) #define DRV(_d) (_d) -#define TTY_INDEX(_tty) ((_tty)->index) -#else -static int xencons_refcount; -static struct tty_struct *xencons_table[MAX_NR_CONSOLES]; -#define DRV(_d) (&(_d)) -#define TTY_INDEX(_tty) (MINOR((_tty)->device) - xencons_driver.minor_start) -#endif +#define DUMMY_TTY(_tty) ((xc_mode != XC_SERIAL) && \ + ((_tty)->index != (xc_num - 1))) static struct termios *xencons_termios[MAX_NR_CONSOLES]; static struct termios *xencons_termios_locked[MAX_NR_CONSOLES]; @@ -315,497 +274,371 @@ static struct tty_struct *xencons_tty; static int xencons_priv_irq; static char x_char; -/* Non-privileged receive callback. */ -static void xencons_rx(ctrl_msg_t *msg, unsigned long id) +void xencons_rx(char *buf, unsigned len, struct pt_regs *regs) { - int i; - unsigned long flags; - - spin_lock_irqsave(&xencons_lock, flags); - if ( xencons_tty != NULL ) - { - for ( i = 0; i < msg->length; i++ ) - tty_insert_flip_char(xencons_tty, msg->msg[i], 0); - tty_flip_buffer_push(xencons_tty); - } - spin_unlock_irqrestore(&xencons_lock, flags); - - msg->length = 0; - ctrl_if_send_response(msg); + int i; + unsigned long flags; + + spin_lock_irqsave(&xencons_lock, flags); + if (xencons_tty == NULL) + goto out; + + for (i = 0; i < len; i++) { +#ifdef CONFIG_MAGIC_SYSRQ + if (sysrq_enabled) { + if (buf[i] == '\x0f') { /* ^O */ + sysrq_requested = jiffies; + continue; /* don't print the sysrq key */ + } else if (sysrq_requested) { + unsigned long sysrq_timeout = + sysrq_requested + HZ*2; + sysrq_requested = 0; + if (time_before(jiffies, sysrq_timeout)) { + spin_unlock_irqrestore( + &xencons_lock, flags); + handle_sysrq( + buf[i], regs, xencons_tty); + spin_lock_irqsave( + &xencons_lock, flags); + continue; + } + } + } +#endif + tty_insert_flip_char(xencons_tty, buf[i], 0); + } + tty_flip_buffer_push(xencons_tty); + + out: + spin_unlock_irqrestore(&xencons_lock, flags); } -/* Privileged and non-privileged transmit worker. */ static void __xencons_tx_flush(void) { - int sz, work_done = 0; - ctrl_msg_t msg; - - if ( xen_start_info.flags & SIF_INITDOMAIN ) - { - if ( x_char ) - { - kcons_write_dom0(NULL, &x_char, 1); - x_char = 0; - work_done = 1; - } - - while ( wc != wp ) - { - sz = wp - wc; - if ( sz > (wbuf_size - WBUF_MASK(wc)) ) - sz = wbuf_size - WBUF_MASK(wc); - kcons_write_dom0(NULL, &wbuf[WBUF_MASK(wc)], sz); - wc += sz; - work_done = 1; - } - } - else - { - while ( x_char ) - { - msg.type = CMSG_CONSOLE; - msg.subtype = CMSG_CONSOLE_DATA; - msg.length = 1; - msg.msg[0] = x_char; - - if ( ctrl_if_send_message_noblock(&msg, NULL, 0) == 0 ) - x_char = 0; - else if ( ctrl_if_enqueue_space_callback(&xencons_tx_flush_task) ) - break; - - work_done = 1; - } - - while ( wc != wp ) - { - sz = wp - wc; - if ( sz > sizeof(msg.msg) ) - sz = sizeof(msg.msg); - if ( sz > (wbuf_size - WBUF_MASK(wc)) ) - sz = wbuf_size - WBUF_MASK(wc); - - msg.type = CMSG_CONSOLE; - msg.subtype = CMSG_CONSOLE_DATA; - msg.length = sz; - memcpy(msg.msg, &wbuf[WBUF_MASK(wc)], sz); - - if ( ctrl_if_send_message_noblock(&msg, NULL, 0) == 0 ) - wc += sz; - else if ( ctrl_if_enqueue_space_callback(&xencons_tx_flush_task) ) - break; - - work_done = 1; - } - } - - if ( work_done && (xencons_tty != NULL) ) - { - wake_up_interruptible(&xencons_tty->write_wait); - if ( (xencons_tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && - (xencons_tty->ldisc.write_wakeup != NULL) ) - (xencons_tty->ldisc.write_wakeup)(xencons_tty); - } + int sent, sz, work_done = 0; + + if (x_char) { + if (xen_start_info->flags & SIF_INITDOMAIN) + kcons_write_dom0(NULL, &x_char, 1); + else + while (x_char) + if (xencons_ring_send(&x_char, 1) == 1) + break; + x_char = 0; + work_done = 1; + } + + while (wc != wp) { + sz = wp - wc; + if (sz > (wbuf_size - WBUF_MASK(wc))) + sz = wbuf_size - WBUF_MASK(wc); + if (xen_start_info->flags & SIF_INITDOMAIN) { + kcons_write_dom0(NULL, &wbuf[WBUF_MASK(wc)], sz); + wc += sz; + } else { + sent = xencons_ring_send(&wbuf[WBUF_MASK(wc)], sz); + if (sent == 0) + break; + wc += sent; + } + work_done = 1; + } + + if (work_done && (xencons_tty != NULL)) { + wake_up_interruptible(&xencons_tty->write_wait); + if ((xencons_tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && + (xencons_tty->ldisc.write_wakeup != NULL)) + (xencons_tty->ldisc.write_wakeup)(xencons_tty); + } } -/* Non-privileged transmit kicker. */ -static void xencons_tx_flush_task_routine(void *data) +void xencons_tx(void) { - unsigned long flags; - spin_lock_irqsave(&xencons_lock, flags); - __xencons_tx_flush(); - spin_unlock_irqrestore(&xencons_lock, flags); + unsigned long flags; + + spin_lock_irqsave(&xencons_lock, flags); + __xencons_tx_flush(); + spin_unlock_irqrestore(&xencons_lock, flags); } /* Privileged receive callback and transmit kicker. */ static irqreturn_t xencons_priv_interrupt(int irq, void *dev_id, - struct pt_regs *regs) + struct pt_regs *regs) { - static char rbuf[16]; - int i, l; - unsigned long flags; + static char rbuf[16]; + int l; - spin_lock_irqsave(&xencons_lock, flags); + while ((l = HYPERVISOR_console_io(CONSOLEIO_read, 16, rbuf)) > 0) + xencons_rx(rbuf, l, regs); - if ( xencons_tty != NULL ) - { - /* Receive work. */ - while ( (l = HYPERVISOR_console_io(CONSOLEIO_read, 16, rbuf)) > 0 ) - for ( i = 0; i < l; i++ ) - tty_insert_flip_char(xencons_tty, rbuf[i], 0); - if ( xencons_tty->flip.count != 0 ) - tty_flip_buffer_push(xencons_tty); - } + xencons_tx(); - /* Transmit work. */ - __xencons_tx_flush(); - - spin_unlock_irqrestore(&xencons_lock, flags); - - return IRQ_HANDLED; + return IRQ_HANDLED; } static int xencons_write_room(struct tty_struct *tty) { - return wbuf_size - (wp - wc); + return wbuf_size - (wp - wc); } static int xencons_chars_in_buffer(struct tty_struct *tty) { - return wp - wc; + return wp - wc; } static void xencons_send_xchar(struct tty_struct *tty, char ch) { - unsigned long flags; + unsigned long flags; - if ( TTY_INDEX(tty) != 0 ) - return; + if (DUMMY_TTY(tty)) + return; - spin_lock_irqsave(&xencons_lock, flags); - x_char = ch; - __xencons_tx_flush(); - spin_unlock_irqrestore(&xencons_lock, flags); + spin_lock_irqsave(&xencons_lock, flags); + x_char = ch; + __xencons_tx_flush(); + spin_unlock_irqrestore(&xencons_lock, flags); } static void xencons_throttle(struct tty_struct *tty) { - if ( TTY_INDEX(tty) != 0 ) - return; + if (DUMMY_TTY(tty)) + return; - if ( I_IXOFF(tty) ) - xencons_send_xchar(tty, STOP_CHAR(tty)); + if (I_IXOFF(tty)) + xencons_send_xchar(tty, STOP_CHAR(tty)); } static void xencons_unthrottle(struct tty_struct *tty) { - if ( TTY_INDEX(tty) != 0 ) - return; - - if ( I_IXOFF(tty) ) - { - if ( x_char != 0 ) - x_char = 0; - else - xencons_send_xchar(tty, START_CHAR(tty)); - } + if (DUMMY_TTY(tty)) + return; + + if (I_IXOFF(tty)) { + if (x_char != 0) + x_char = 0; + else + xencons_send_xchar(tty, START_CHAR(tty)); + } } static void xencons_flush_buffer(struct tty_struct *tty) { - unsigned long flags; + unsigned long flags; - if ( TTY_INDEX(tty) != 0 ) - return; + if (DUMMY_TTY(tty)) + return; - spin_lock_irqsave(&xencons_lock, flags); - wc = wp = 0; - spin_unlock_irqrestore(&xencons_lock, flags); + spin_lock_irqsave(&xencons_lock, flags); + wc = wp = 0; + spin_unlock_irqrestore(&xencons_lock, flags); } static inline int __xencons_put_char(int ch) { - char _ch = (char)ch; - if ( (wp - wc) == wbuf_size ) - return 0; - wbuf[WBUF_MASK(wp++)] = _ch; - return 1; + char _ch = (char)ch; + if ((wp - wc) == wbuf_size) + return 0; + wbuf[WBUF_MASK(wp++)] = _ch; + return 1; } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) static int xencons_write( - struct tty_struct *tty, - const unsigned char *buf, - int count) + struct tty_struct *tty, + const unsigned char *buf, + int count) { - int i; - unsigned long flags; + int i; + unsigned long flags; - if ( TTY_INDEX(tty) != 0 ) - return count; + if (DUMMY_TTY(tty)) + return count; - spin_lock_irqsave(&xencons_lock, flags); + spin_lock_irqsave(&xencons_lock, flags); - for ( i = 0; i < count; i++ ) - if ( !__xencons_put_char(buf[i]) ) - break; + for (i = 0; i < count; i++) + if (!__xencons_put_char(buf[i])) + break; - if ( i != 0 ) - __xencons_tx_flush(); + if (i != 0) + __xencons_tx_flush(); - spin_unlock_irqrestore(&xencons_lock, flags); + spin_unlock_irqrestore(&xencons_lock, flags); - return i; + return i; } -#else -static int xencons_write( - struct tty_struct *tty, - int from_user, - const u_char *buf, - int count) -{ - int i; - unsigned long flags; - - if ( from_user && verify_area(VERIFY_READ, buf, count) ) - return -EINVAL; - - if ( TTY_INDEX(tty) != 0 ) - return count; - - spin_lock_irqsave(&xencons_lock, flags); - - for ( i = 0; i < count; i++ ) - { - char ch; - if ( from_user ) - __get_user(ch, buf + i); - else - ch = buf[i]; - if ( !__xencons_put_char(ch) ) - break; - } - - if ( i != 0 ) - __xencons_tx_flush(); - - spin_unlock_irqrestore(&xencons_lock, flags); - - return i; -} -#endif static void xencons_put_char(struct tty_struct *tty, u_char ch) { - unsigned long flags; + unsigned long flags; - if ( TTY_INDEX(tty) != 0 ) - return; + if (DUMMY_TTY(tty)) + return; - spin_lock_irqsave(&xencons_lock, flags); - (void)__xencons_put_char(ch); - spin_unlock_irqrestore(&xencons_lock, flags); + spin_lock_irqsave(&xencons_lock, flags); + (void)__xencons_put_char(ch); + spin_unlock_irqrestore(&xencons_lock, flags); } static void xencons_flush_chars(struct tty_struct *tty) { - unsigned long flags; + unsigned long flags; - if ( TTY_INDEX(tty) != 0 ) - return; + if (DUMMY_TTY(tty)) + return; - spin_lock_irqsave(&xencons_lock, flags); - __xencons_tx_flush(); - spin_unlock_irqrestore(&xencons_lock, flags); + spin_lock_irqsave(&xencons_lock, flags); + __xencons_tx_flush(); + spin_unlock_irqrestore(&xencons_lock, flags); } static void xencons_wait_until_sent(struct tty_struct *tty, int timeout) { - unsigned long orig_jiffies = jiffies; - - if ( TTY_INDEX(tty) != 0 ) - return; - - while ( DRV(tty->driver)->chars_in_buffer(tty) ) - { - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(1); - if ( signal_pending(current) ) - break; - if ( (timeout != 0) && time_after(jiffies, orig_jiffies + timeout) ) - break; - } - - set_current_state(TASK_RUNNING); + unsigned long orig_jiffies = jiffies; + + if (DUMMY_TTY(tty)) + return; + + while (DRV(tty->driver)->chars_in_buffer(tty)) { + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(1); + if (signal_pending(current)) + break; + if (timeout && time_after(jiffies, orig_jiffies + timeout)) + break; + } + + set_current_state(TASK_RUNNING); } static int xencons_open(struct tty_struct *tty, struct file *filp) { - unsigned long flags; + unsigned long flags; - if ( TTY_INDEX(tty) != 0 ) - return 0; + if (DUMMY_TTY(tty)) + return 0; - spin_lock_irqsave(&xencons_lock, flags); - tty->driver_data = NULL; - if ( xencons_tty == NULL ) - xencons_tty = tty; - __xencons_tx_flush(); - spin_unlock_irqrestore(&xencons_lock, flags); + spin_lock_irqsave(&xencons_lock, flags); + tty->driver_data = NULL; + if (xencons_tty == NULL) + xencons_tty = tty; + __xencons_tx_flush(); + spin_unlock_irqrestore(&xencons_lock, flags); - return 0; + return 0; } static void xencons_close(struct tty_struct *tty, struct file *filp) { - unsigned long flags; - - if ( TTY_INDEX(tty) != 0 ) - return; - - if ( tty->count == 1 ) - { - tty->closing = 1; - tty_wait_until_sent(tty, 0); - if ( DRV(tty->driver)->flush_buffer != NULL ) - DRV(tty->driver)->flush_buffer(tty); - if ( tty->ldisc.flush_buffer != NULL ) - tty->ldisc.flush_buffer(tty); - tty->closing = 0; - spin_lock_irqsave(&xencons_lock, flags); - xencons_tty = NULL; - spin_unlock_irqrestore(&xencons_lock, flags); - } + unsigned long flags; + + if (DUMMY_TTY(tty)) + return; + + mutex_lock(&tty_mutex); + + if (tty->count != 1) { + mutex_unlock(&tty_mutex); + return; + } + + /* Prevent other threads from re-opening this tty. */ + set_bit(TTY_CLOSING, &tty->flags); + mutex_unlock(&tty_mutex); + + tty->closing = 1; + tty_wait_until_sent(tty, 0); + if (DRV(tty->driver)->flush_buffer != NULL) + DRV(tty->driver)->flush_buffer(tty); + if (tty->ldisc.flush_buffer != NULL) + tty->ldisc.flush_buffer(tty); + tty->closing = 0; + spin_lock_irqsave(&xencons_lock, flags); + xencons_tty = NULL; + spin_unlock_irqrestore(&xencons_lock, flags); } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) static struct tty_operations xencons_ops = { - .open = xencons_open, - .close = xencons_close, - .write = xencons_write, - .write_room = xencons_write_room, - .put_char = xencons_put_char, - .flush_chars = xencons_flush_chars, - .chars_in_buffer = xencons_chars_in_buffer, - .send_xchar = xencons_send_xchar, - .flush_buffer = xencons_flush_buffer, - .throttle = xencons_throttle, - .unthrottle = xencons_unthrottle, - .wait_until_sent = xencons_wait_until_sent, + .open = xencons_open, + .close = xencons_close, + .write = xencons_write, + .write_room = xencons_write_room, + .put_char = xencons_put_char, + .flush_chars = xencons_flush_chars, + .chars_in_buffer = xencons_chars_in_buffer, + .send_xchar = xencons_send_xchar, + .flush_buffer = xencons_flush_buffer, + .throttle = xencons_throttle, + .unthrottle = xencons_unthrottle, + .wait_until_sent = xencons_wait_until_sent, }; -#ifdef CONFIG_XEN_PRIVILEGED_GUEST -static const char *xennullcon_startup(void) -{ - return NULL; -} - -static int xennullcon_dummy(void) -{ - return 0; -} - -#define DUMMY (void *)xennullcon_dummy - -/* - * The console `switch' structure for the dummy console - * - * Most of the operations are dummies. - */ - -const struct consw xennull_con = { - .owner = THIS_MODULE, - .con_startup = xennullcon_startup, - .con_init = DUMMY, - .con_deinit = DUMMY, - .con_clear = DUMMY, - .con_putc = DUMMY, - .con_putcs = DUMMY, - .con_cursor = DUMMY, - .con_scroll = DUMMY, - .con_bmove = DUMMY, - .con_switch = DUMMY, - .con_blank = DUMMY, - .con_font_set = DUMMY, - .con_font_get = DUMMY, - .con_font_default = DUMMY, - .con_font_copy = DUMMY, - .con_set_palette = DUMMY, - .con_scrolldelta = DUMMY, -}; -#endif -#endif - static int __init xencons_init(void) { - int rc; - - if ( xc_mode == XC_OFF ) - return 0; - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) - xencons_driver = alloc_tty_driver((xc_mode == XC_SERIAL) ? - 1 : MAX_NR_CONSOLES); - if ( xencons_driver == NULL ) - return -ENOMEM; -#else - memset(&xencons_driver, 0, sizeof(struct tty_driver)); - xencons_driver.magic = TTY_DRIVER_MAGIC; - xencons_driver.refcount = &xencons_refcount; - xencons_driver.table = xencons_table; - xencons_driver.num = (xc_mode == XC_SERIAL) ? 1 : MAX_NR_CONSOLES; -#endif - - DRV(xencons_driver)->major = TTY_MAJOR; - DRV(xencons_driver)->type = TTY_DRIVER_TYPE_SERIAL; - DRV(xencons_driver)->subtype = SERIAL_TYPE_NORMAL; - DRV(xencons_driver)->init_termios = tty_std_termios; - DRV(xencons_driver)->flags = - TTY_DRIVER_REAL_RAW | TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_NO_DEVFS; - DRV(xencons_driver)->termios = xencons_termios; - DRV(xencons_driver)->termios_locked = xencons_termios_locked; - - if ( xc_mode == XC_SERIAL ) - { - DRV(xencons_driver)->name = "ttyS"; - DRV(xencons_driver)->minor_start = 64 + xc_num; - DRV(xencons_driver)->name_base = 0 + xc_num; - } - else - { - DRV(xencons_driver)->name = "tty"; - DRV(xencons_driver)->minor_start = xc_num; - DRV(xencons_driver)->name_base = xc_num; - } - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) - tty_set_operations(xencons_driver, &xencons_ops); -#else - xencons_driver.open = xencons_open; - xencons_driver.close = xencons_close; - xencons_driver.write = xencons_write; - xencons_driver.write_room = xencons_write_room; - xencons_driver.put_char = xencons_put_char; - xencons_driver.flush_chars = xencons_flush_chars; - xencons_driver.chars_in_buffer = xencons_chars_in_buffer; - xencons_driver.send_xchar = xencons_send_xchar; - xencons_driver.flush_buffer = xencons_flush_buffer; - xencons_driver.throttle = xencons_throttle; - xencons_driver.unthrottle = xencons_unthrottle; - xencons_driver.wait_until_sent = xencons_wait_until_sent; -#endif - - if ( (rc = tty_register_driver(DRV(xencons_driver))) != 0 ) - { - printk("WARNING: Failed to register Xen virtual " - "console driver as '%s%d'\n", - DRV(xencons_driver)->name, DRV(xencons_driver)->name_base); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) - put_tty_driver(xencons_driver); - xencons_driver = NULL; -#endif - return rc; - } - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) - tty_register_device(xencons_driver, 0, NULL); -#endif - - if ( xen_start_info.flags & SIF_INITDOMAIN ) - { - xencons_priv_irq = bind_virq_to_irq(VIRQ_CONSOLE); - (void)request_irq(xencons_priv_irq, - xencons_priv_interrupt, 0, "console", NULL); - } - else - { - (void)ctrl_if_register_receiver(CMSG_CONSOLE, xencons_rx, 0); - } - - printk("Xen virtual console successfully installed as %s%d\n", - DRV(xencons_driver)->name, - DRV(xencons_driver)->name_base ); - - return 0; + int rc; + + if (!is_running_on_xen()) + return -ENODEV; + + if (xc_mode == XC_OFF) + return 0; + + xencons_ring_init(); + + xencons_driver = alloc_tty_driver((xc_mode == XC_SERIAL) ? + 1 : MAX_NR_CONSOLES); + if (xencons_driver == NULL) + return -ENOMEM; + + DRV(xencons_driver)->name = "xencons"; + DRV(xencons_driver)->major = TTY_MAJOR; + DRV(xencons_driver)->type = TTY_DRIVER_TYPE_SERIAL; + DRV(xencons_driver)->subtype = SERIAL_TYPE_NORMAL; + DRV(xencons_driver)->init_termios = tty_std_termios; + DRV(xencons_driver)->flags = + TTY_DRIVER_REAL_RAW | + TTY_DRIVER_RESET_TERMIOS; + DRV(xencons_driver)->termios = xencons_termios; + DRV(xencons_driver)->termios_locked = xencons_termios_locked; + + if (xc_mode == XC_SERIAL) { + DRV(xencons_driver)->name = "ttyS"; + DRV(xencons_driver)->minor_start = 64 + xc_num; + DRV(xencons_driver)->name_base = 0 + xc_num; + } else { + DRV(xencons_driver)->name = "tty"; + DRV(xencons_driver)->minor_start = 1; + DRV(xencons_driver)->name_base = 1; + } + + tty_set_operations(xencons_driver, &xencons_ops); + + if ((rc = tty_register_driver(DRV(xencons_driver))) != 0) { + printk("WARNING: Failed to register Xen virtual " + "console driver as '%s%d'\n", + DRV(xencons_driver)->name, + DRV(xencons_driver)->name_base); + put_tty_driver(xencons_driver); + xencons_driver = NULL; + return rc; + } + + if (xen_start_info->flags & SIF_INITDOMAIN) { + xencons_priv_irq = bind_virq_to_irqhandler( + VIRQ_CONSOLE, + 0, + xencons_priv_interrupt, + 0, + "console", + NULL); + BUG_ON(xencons_priv_irq < 0); + } + + printk("Xen virtual console successfully installed as %s%d\n", + DRV(xencons_driver)->name, xc_num); + + return 0; } module_init(xencons_init); + +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/xen/evtchn/evtchn.c b/drivers/xen/evtchn/evtchn.c index f5da4283d..76bfab82e 100644 --- a/drivers/xen/evtchn/evtchn.c +++ b/drivers/xen/evtchn/evtchn.c @@ -1,13 +1,16 @@ /****************************************************************************** * evtchn.c * - * Xenolinux driver for receiving and demuxing event-channel signals. + * Driver for receiving and demuxing event-channel signals. * - * Copyright (c) 2004, K A Fraser + * Copyright (c) 2004-2005, K A Fraser * Multi-process extensions Copyright (c) 2004, Steven Smith * - * This file may be distributed separately from the Linux kernel, or - * incorporated into other software packages, subject to the following license: + * 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; or, when distributed + * separately from the Linux kernel or incorporated into other + * software packages, subject to the following license: * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this source file (the "Software"), to deal in the Software without @@ -44,31 +47,20 @@ #include #include #include -#define XEN_EVTCHN_MASK_OPS -#include - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) -#include -#define OLD_DEVFS -#else #include -#endif - -#ifdef OLD_DEVFS -/* NB. This must be shared amongst drivers if more things go in /dev/xen */ -static devfs_handle_t xen_dev_dir; -#endif +#include +#include struct per_user_data { - /* Notification ring, accessed via /dev/xen/evtchn. */ -# define EVTCHN_RING_SIZE 2048 /* 2048 16-bit entries */ -# define EVTCHN_RING_MASK(_i) ((_i)&(EVTCHN_RING_SIZE-1)) - u16 *ring; - unsigned int ring_cons, ring_prod, ring_overflow; - - /* Processes wait on this queue when ring is empty. */ - wait_queue_head_t evtchn_wait; - struct fasync_struct *evtchn_async_queue; + /* Notification ring, accessed via /dev/xen/evtchn. */ +#define EVTCHN_RING_SIZE (PAGE_SIZE / sizeof(evtchn_port_t)) +#define EVTCHN_RING_MASK(_i) ((_i)&(EVTCHN_RING_SIZE-1)) + evtchn_port_t *ring; + unsigned int ring_cons, ring_prod, ring_overflow; + + /* Processes wait on this queue when ring is empty. */ + wait_queue_head_t evtchn_wait; + struct fasync_struct *evtchn_async_queue; }; /* Who's bound to each port? */ @@ -77,354 +69,390 @@ static spinlock_t port_user_lock; void evtchn_device_upcall(int port) { - struct per_user_data *u; - - spin_lock(&port_user_lock); - - mask_evtchn(port); - clear_evtchn(port); - - if ( (u = port_user[port]) != NULL ) - { - if ( (u->ring_prod - u->ring_cons) < EVTCHN_RING_SIZE ) - { - u->ring[EVTCHN_RING_MASK(u->ring_prod)] = (u16)port; - if ( u->ring_cons == u->ring_prod++ ) - { - wake_up_interruptible(&u->evtchn_wait); - kill_fasync(&u->evtchn_async_queue, SIGIO, POLL_IN); - } - } - else - { - u->ring_overflow = 1; - } - } - - spin_unlock(&port_user_lock); + struct per_user_data *u; + + spin_lock(&port_user_lock); + + mask_evtchn(port); + clear_evtchn(port); + + if ((u = port_user[port]) != NULL) { + if ((u->ring_prod - u->ring_cons) < EVTCHN_RING_SIZE) { + u->ring[EVTCHN_RING_MASK(u->ring_prod)] = port; + if (u->ring_cons == u->ring_prod++) { + wake_up_interruptible(&u->evtchn_wait); + kill_fasync(&u->evtchn_async_queue, + SIGIO, POLL_IN); + } + } else { + u->ring_overflow = 1; + } + } + + spin_unlock(&port_user_lock); } -static ssize_t evtchn_read(struct file *file, char *buf, - size_t count, loff_t *ppos) +static ssize_t evtchn_read(struct file *file, char __user *buf, + size_t count, loff_t *ppos) { - int rc; - unsigned int c, p, bytes1 = 0, bytes2 = 0; - DECLARE_WAITQUEUE(wait, current); - struct per_user_data *u = file->private_data; - - add_wait_queue(&u->evtchn_wait, &wait); - - count &= ~1; /* even number of bytes */ - - if ( count == 0 ) - { - rc = 0; - goto out; - } - - if ( count > PAGE_SIZE ) - count = PAGE_SIZE; - - for ( ; ; ) - { - set_current_state(TASK_INTERRUPTIBLE); - - if ( (c = u->ring_cons) != (p = u->ring_prod) ) - break; - - if ( u->ring_overflow ) - { - rc = -EFBIG; - goto out; - } - - if ( file->f_flags & O_NONBLOCK ) - { - rc = -EAGAIN; - goto out; - } - - if ( signal_pending(current) ) - { - rc = -ERESTARTSYS; - goto out; - } - - schedule(); - } - - /* Byte lengths of two chunks. Chunk split (if any) is at ring wrap. */ - if ( ((c ^ p) & EVTCHN_RING_SIZE) != 0 ) - { - bytes1 = (EVTCHN_RING_SIZE - EVTCHN_RING_MASK(c)) * sizeof(u16); - bytes2 = EVTCHN_RING_MASK(p) * sizeof(u16); - } - else - { - bytes1 = (p - c) * sizeof(u16); - bytes2 = 0; - } - - /* Truncate chunks according to caller's maximum byte count. */ - if ( bytes1 > count ) - { - bytes1 = count; - bytes2 = 0; - } - else if ( (bytes1 + bytes2) > count ) - { - bytes2 = count - bytes1; - } - - if ( copy_to_user(buf, &u->ring[EVTCHN_RING_MASK(c)], bytes1) || - ((bytes2 != 0) && copy_to_user(&buf[bytes1], &u->ring[0], bytes2)) ) - { - rc = -EFAULT; - goto out; - } - - u->ring_cons += (bytes1 + bytes2) / sizeof(u16); - - rc = bytes1 + bytes2; - - out: - __set_current_state(TASK_RUNNING); - remove_wait_queue(&u->evtchn_wait, &wait); - return rc; + int rc; + unsigned int c, p, bytes1 = 0, bytes2 = 0; + struct per_user_data *u = file->private_data; + + /* Whole number of ports. */ + count &= ~(sizeof(evtchn_port_t)-1); + + if (count == 0) + return 0; + + if (count > PAGE_SIZE) + count = PAGE_SIZE; + + for (;;) { + if (u->ring_overflow) + return -EFBIG; + + if ((c = u->ring_cons) != (p = u->ring_prod)) + break; + + if (file->f_flags & O_NONBLOCK) + return -EAGAIN; + + rc = wait_event_interruptible( + u->evtchn_wait, u->ring_cons != u->ring_prod); + if (rc) + return rc; + } + + /* Byte lengths of two chunks. Chunk split (if any) is at ring wrap. */ + if (((c ^ p) & EVTCHN_RING_SIZE) != 0) { + bytes1 = (EVTCHN_RING_SIZE - EVTCHN_RING_MASK(c)) * + sizeof(evtchn_port_t); + bytes2 = EVTCHN_RING_MASK(p) * sizeof(evtchn_port_t); + } else { + bytes1 = (p - c) * sizeof(evtchn_port_t); + bytes2 = 0; + } + + /* Truncate chunks according to caller's maximum byte count. */ + if (bytes1 > count) { + bytes1 = count; + bytes2 = 0; + } else if ((bytes1 + bytes2) > count) { + bytes2 = count - bytes1; + } + + if (copy_to_user(buf, &u->ring[EVTCHN_RING_MASK(c)], bytes1) || + ((bytes2 != 0) && + copy_to_user(&buf[bytes1], &u->ring[0], bytes2))) + return -EFAULT; + + u->ring_cons += (bytes1 + bytes2) / sizeof(evtchn_port_t); + + return bytes1 + bytes2; } -static ssize_t evtchn_write(struct file *file, const char *buf, - size_t count, loff_t *ppos) +static ssize_t evtchn_write(struct file *file, const char __user *buf, + size_t count, loff_t *ppos) { - int rc, i; - u16 *kbuf = (u16 *)__get_free_page(GFP_KERNEL); - struct per_user_data *u = file->private_data; + int rc, i; + evtchn_port_t *kbuf = (evtchn_port_t *)__get_free_page(GFP_KERNEL); + struct per_user_data *u = file->private_data; - if ( kbuf == NULL ) - return -ENOMEM; + if (kbuf == NULL) + return -ENOMEM; - count &= ~1; /* even number of bytes */ + /* Whole number of ports. */ + count &= ~(sizeof(evtchn_port_t)-1); - if ( count == 0 ) - { - rc = 0; - goto out; - } + if (count == 0) { + rc = 0; + goto out; + } - if ( count > PAGE_SIZE ) - count = PAGE_SIZE; + if (count > PAGE_SIZE) + count = PAGE_SIZE; - if ( copy_from_user(kbuf, buf, count) != 0 ) - { - rc = -EFAULT; - goto out; - } + if (copy_from_user(kbuf, buf, count) != 0) { + rc = -EFAULT; + goto out; + } - spin_lock_irq(&port_user_lock); - for ( i = 0; i < (count/2); i++ ) - if ( (kbuf[i] < NR_EVENT_CHANNELS) && (port_user[kbuf[i]] == u) ) - unmask_evtchn(kbuf[i]); - spin_unlock_irq(&port_user_lock); + spin_lock_irq(&port_user_lock); + for (i = 0; i < (count/sizeof(evtchn_port_t)); i++) + if ((kbuf[i] < NR_EVENT_CHANNELS) && (port_user[kbuf[i]] == u)) + unmask_evtchn(kbuf[i]); + spin_unlock_irq(&port_user_lock); - rc = count; + rc = count; out: - free_page((unsigned long)kbuf); - return rc; + free_page((unsigned long)kbuf); + return rc; } -static int evtchn_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) +static void evtchn_bind_to_user(struct per_user_data *u, int port) { - int rc = 0; - struct per_user_data *u = file->private_data; + spin_lock_irq(&port_user_lock); + BUG_ON(port_user[port] != NULL); + port_user[port] = u; + unmask_evtchn(port); + spin_unlock_irq(&port_user_lock); +} - spin_lock_irq(&port_user_lock); +static int evtchn_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) +{ + int rc; + struct per_user_data *u = file->private_data; + void __user *uarg = (void __user *) arg; + + switch (cmd) { + case IOCTL_EVTCHN_BIND_VIRQ: { + struct ioctl_evtchn_bind_virq bind; + struct evtchn_bind_virq bind_virq; + + rc = -EFAULT; + if (copy_from_user(&bind, uarg, sizeof(bind))) + break; + + bind_virq.virq = bind.virq; + bind_virq.vcpu = 0; + rc = HYPERVISOR_event_channel_op(EVTCHNOP_bind_virq, + &bind_virq); + if (rc != 0) + break; + + rc = bind_virq.port; + evtchn_bind_to_user(u, rc); + break; + } + + case IOCTL_EVTCHN_BIND_INTERDOMAIN: { + struct ioctl_evtchn_bind_interdomain bind; + struct evtchn_bind_interdomain bind_interdomain; + + rc = -EFAULT; + if (copy_from_user(&bind, uarg, sizeof(bind))) + break; + + bind_interdomain.remote_dom = bind.remote_domain; + bind_interdomain.remote_port = bind.remote_port; + rc = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain, + &bind_interdomain); + if (rc != 0) + break; + + rc = bind_interdomain.local_port; + evtchn_bind_to_user(u, rc); + break; + } + + case IOCTL_EVTCHN_BIND_UNBOUND_PORT: { + struct ioctl_evtchn_bind_unbound_port bind; + struct evtchn_alloc_unbound alloc_unbound; + + rc = -EFAULT; + if (copy_from_user(&bind, uarg, sizeof(bind))) + break; + + alloc_unbound.dom = DOMID_SELF; + alloc_unbound.remote_dom = bind.remote_domain; + rc = HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound, + &alloc_unbound); + if (rc != 0) + break; + + rc = alloc_unbound.port; + evtchn_bind_to_user(u, rc); + break; + } + + case IOCTL_EVTCHN_UNBIND: { + struct ioctl_evtchn_unbind unbind; + struct evtchn_close close; + int ret; + + rc = -EFAULT; + if (copy_from_user(&unbind, uarg, sizeof(unbind))) + break; + + rc = -EINVAL; + if (unbind.port >= NR_EVENT_CHANNELS) + break; + + spin_lock_irq(&port_user_lock); - switch ( cmd ) - { - case EVTCHN_RESET: - /* Initialise the ring to empty. Clear errors. */ - u->ring_cons = u->ring_prod = u->ring_overflow = 0; - break; - - case EVTCHN_BIND: - if ( arg >= NR_EVENT_CHANNELS ) - { - rc = -EINVAL; - } - else if ( port_user[arg] != NULL ) - { - rc = -EISCONN; - } - else - { - port_user[arg] = u; - unmask_evtchn(arg); - } - break; - - case EVTCHN_UNBIND: - if ( arg >= NR_EVENT_CHANNELS ) - { - rc = -EINVAL; - } - else if ( port_user[arg] != u ) - { - rc = -ENOTCONN; - } - else - { - port_user[arg] = NULL; - mask_evtchn(arg); - } - break; - - default: - rc = -ENOSYS; - break; - } - - spin_unlock_irq(&port_user_lock); - - return rc; + rc = -ENOTCONN; + if (port_user[unbind.port] != u) { + spin_unlock_irq(&port_user_lock); + break; + } + + port_user[unbind.port] = NULL; + mask_evtchn(unbind.port); + + spin_unlock_irq(&port_user_lock); + + close.port = unbind.port; + ret = HYPERVISOR_event_channel_op(EVTCHNOP_close, &close); + BUG_ON(ret); + + rc = 0; + break; + } + + case IOCTL_EVTCHN_NOTIFY: { + struct ioctl_evtchn_notify notify; + + rc = -EFAULT; + if (copy_from_user(¬ify, uarg, sizeof(notify))) + break; + + if (notify.port >= NR_EVENT_CHANNELS) { + rc = -EINVAL; + } else if (port_user[notify.port] != u) { + rc = -ENOTCONN; + } else { + notify_remote_via_evtchn(notify.port); + rc = 0; + } + break; + } + + case IOCTL_EVTCHN_RESET: { + /* Initialise the ring to empty. Clear errors. */ + spin_lock_irq(&port_user_lock); + u->ring_cons = u->ring_prod = u->ring_overflow = 0; + spin_unlock_irq(&port_user_lock); + rc = 0; + break; + } + + default: + rc = -ENOSYS; + break; + } + + return rc; } static unsigned int evtchn_poll(struct file *file, poll_table *wait) { - unsigned int mask = POLLOUT | POLLWRNORM; - struct per_user_data *u = file->private_data; - - poll_wait(file, &u->evtchn_wait, wait); - if ( u->ring_cons != u->ring_prod ) - mask |= POLLIN | POLLRDNORM; - if ( u->ring_overflow ) - mask = POLLERR; - return mask; + unsigned int mask = POLLOUT | POLLWRNORM; + struct per_user_data *u = file->private_data; + + poll_wait(file, &u->evtchn_wait, wait); + if (u->ring_cons != u->ring_prod) + mask |= POLLIN | POLLRDNORM; + if (u->ring_overflow) + mask = POLLERR; + return mask; } static int evtchn_fasync(int fd, struct file *filp, int on) { - struct per_user_data *u = filp->private_data; - return fasync_helper(fd, filp, on, &u->evtchn_async_queue); + struct per_user_data *u = filp->private_data; + return fasync_helper(fd, filp, on, &u->evtchn_async_queue); } static int evtchn_open(struct inode *inode, struct file *filp) { - struct per_user_data *u; + struct per_user_data *u; - if ( (u = kmalloc(sizeof(*u), GFP_KERNEL)) == NULL ) - return -ENOMEM; + if ((u = kmalloc(sizeof(*u), GFP_KERNEL)) == NULL) + return -ENOMEM; - memset(u, 0, sizeof(*u)); - init_waitqueue_head(&u->evtchn_wait); + memset(u, 0, sizeof(*u)); + init_waitqueue_head(&u->evtchn_wait); - if ( (u->ring = (u16 *)__get_free_page(GFP_KERNEL)) == NULL ) - { - kfree(u); - return -ENOMEM; - } + u->ring = (evtchn_port_t *)__get_free_page(GFP_KERNEL); + if (u->ring == NULL) { + kfree(u); + return -ENOMEM; + } - filp->private_data = u; + filp->private_data = u; - return 0; + return 0; } static int evtchn_release(struct inode *inode, struct file *filp) { - int i; - struct per_user_data *u = filp->private_data; + int i; + struct per_user_data *u = filp->private_data; + struct evtchn_close close; + + spin_lock_irq(&port_user_lock); - spin_lock_irq(&port_user_lock); + free_page((unsigned long)u->ring); - free_page((unsigned long)u->ring); + for (i = 0; i < NR_EVENT_CHANNELS; i++) { + int ret; + if (port_user[i] != u) + continue; - for ( i = 0; i < NR_EVENT_CHANNELS; i++ ) - { - if ( port_user[i] == u ) - { - port_user[i] = NULL; - mask_evtchn(i); - } - } + port_user[i] = NULL; + mask_evtchn(i); - spin_unlock_irq(&port_user_lock); + close.port = i; + ret = HYPERVISOR_event_channel_op(EVTCHNOP_close, &close); + BUG_ON(ret); + } - return 0; + spin_unlock_irq(&port_user_lock); + + kfree(u); + + return 0; } static struct file_operations evtchn_fops = { - owner: THIS_MODULE, - read: evtchn_read, - write: evtchn_write, - ioctl: evtchn_ioctl, - poll: evtchn_poll, - fasync: evtchn_fasync, - open: evtchn_open, - release: evtchn_release + .owner = THIS_MODULE, + .read = evtchn_read, + .write = evtchn_write, + .ioctl = evtchn_ioctl, + .poll = evtchn_poll, + .fasync = evtchn_fasync, + .open = evtchn_open, + .release = evtchn_release, }; static struct miscdevice evtchn_miscdev = { - .minor = EVTCHN_MINOR, - .name = "evtchn", - .fops = &evtchn_fops, -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) - .devfs_name = "misc/evtchn", -#endif + .minor = EVTCHN_MINOR, + .name = "evtchn", + .fops = &evtchn_fops, + .devfs_name = "misc/evtchn", }; static int __init evtchn_init(void) { -#ifdef OLD_DEVFS - devfs_handle_t symlink_handle; - int pos; - char link_dest[64]; -#endif - int err; - - spin_lock_init(&port_user_lock); - memset(port_user, 0, sizeof(port_user)); - - /* (DEVFS) create '/dev/misc/evtchn'. */ - err = misc_register(&evtchn_miscdev); - if ( err != 0 ) - { - printk(KERN_ALERT "Could not register /dev/misc/evtchn\n"); - return err; - } - -#ifdef OLD_DEVFS - /* (DEVFS) create directory '/dev/xen'. */ - xen_dev_dir = devfs_mk_dir(NULL, "xen", NULL); - - /* (DEVFS) &link_dest[pos] == '../misc/evtchn'. */ - pos = devfs_generate_path(evtchn_miscdev.devfs_handle, - &link_dest[3], - sizeof(link_dest) - 3); - if ( pos >= 0 ) - strncpy(&link_dest[pos], "../", 3); - - /* (DEVFS) symlink '/dev/xen/evtchn' -> '../misc/evtchn'. */ - (void)devfs_mk_symlink(xen_dev_dir, - "evtchn", - DEVFS_FL_DEFAULT, - &link_dest[pos], - &symlink_handle, - NULL); - - /* (DEVFS) automatically destroy the symlink with its destination. */ - devfs_auto_unregister(evtchn_miscdev.devfs_handle, symlink_handle); -#endif - - printk("Event-channel device installed.\n"); - - return 0; + int err; + + if (!is_running_on_xen()) + return -ENODEV; + + spin_lock_init(&port_user_lock); + memset(port_user, 0, sizeof(port_user)); + + /* Create '/dev/misc/evtchn'. */ + err = misc_register(&evtchn_miscdev); + if (err != 0) { + printk(KERN_ALERT "Could not register /dev/misc/evtchn\n"); + return err; + } + + printk("Event-channel device installed.\n"); + + return 0; } static void evtchn_cleanup(void) { - misc_deregister(&evtchn_miscdev); + misc_deregister(&evtchn_miscdev); } module_init(evtchn_init); module_exit(evtchn_cleanup); + +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/xen/netback/Makefile b/drivers/xen/netback/Makefile index 327944214..d5d232837 100644 --- a/drivers/xen/netback/Makefile +++ b/drivers/xen/netback/Makefile @@ -1,2 +1,5 @@ +obj-$(CONFIG_XEN_NETDEV_BACKEND) := netbk.o +obj-$(CONFIG_XEN_NETDEV_LOOPBACK) += netloop.o -obj-y := netback.o control.o interface.o +netbk-y := netback.o xenbus.o interface.o +netloop-y := loopback.o diff --git a/drivers/xen/netback/common.h b/drivers/xen/netback/common.h index dfb750ee3..c5ec30071 100644 --- a/drivers/xen/netback/common.h +++ b/drivers/xen/netback/common.h @@ -1,5 +1,29 @@ /****************************************************************************** * arch/xen/drivers/netif/backend/common.h + * + * 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; or, when distributed + * separately from the Linux kernel or incorporated into other + * software packages, subject to the following license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this source file (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, modify, + * merge, publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. */ #ifndef __NETIF__BACKEND__COMMON_H__ @@ -14,84 +38,83 @@ #include #include #include -#include -#include +#include +#include +#include #include #include - -#if 0 -#define ASSERT(_p) \ - if ( !(_p) ) { printk("Assertion '%s' failed, line %d, file %s", #_p , \ - __LINE__, __FILE__); *(int*)0=0; } -#define DPRINTK(_f, _a...) printk(KERN_ALERT "(file=%s, line=%d) " _f, \ - __FILE__ , __LINE__ , ## _a ) -#else -#define ASSERT(_p) ((void)0) -#define DPRINTK(_f, _a...) ((void)0) -#endif +#include +#include +#include + +#define DPRINTK(_f, _a...) \ + pr_debug("(file=%s, line=%d) " _f, \ + __FILE__ , __LINE__ , ## _a ) +#define IPRINTK(fmt, args...) \ + printk(KERN_INFO "xen_net: " fmt, ##args) +#define WPRINTK(fmt, args...) \ + printk(KERN_WARNING "xen_net: " fmt, ##args) typedef struct netif_st { - /* Unique identifier for this interface. */ - domid_t domid; - unsigned int handle; - - u8 fe_dev_addr[6]; - - /* Physical parameters of the comms window. */ - unsigned long tx_shmem_frame; - unsigned long rx_shmem_frame; - unsigned int evtchn; - int irq; - - /* The shared rings and indexes. */ - netif_tx_interface_t *tx; - netif_rx_interface_t *rx; - - /* Private indexes into shared ring. */ - NETIF_RING_IDX rx_req_cons; - NETIF_RING_IDX rx_resp_prod; /* private version of shared variable */ - NETIF_RING_IDX tx_req_cons; - NETIF_RING_IDX tx_resp_prod; /* private version of shared variable */ - - /* Transmit shaping: allow 'credit_bytes' every 'credit_usec'. */ - unsigned long credit_bytes; - unsigned long credit_usec; - unsigned long remaining_credit; - struct timer_list credit_timeout; - - /* Miscellaneous private stuff. */ - enum { DISCONNECTED, DISCONNECTING, CONNECTED } status; - int active; - /* - * DISCONNECT response is deferred until pending requests are ack'ed. - * We therefore need to store the id from the original request. - */ - u8 disconnect_rspid; - struct netif_st *hash_next; - struct list_head list; /* scheduling list */ - atomic_t refcnt; - struct net_device *dev; - struct net_device_stats stats; - - struct work_struct work; + /* Unique identifier for this interface. */ + domid_t domid; + unsigned int handle; + + u8 fe_dev_addr[6]; + + /* Physical parameters of the comms window. */ + grant_handle_t tx_shmem_handle; + grant_ref_t tx_shmem_ref; + grant_handle_t rx_shmem_handle; + grant_ref_t rx_shmem_ref; + unsigned int evtchn; + unsigned int irq; + + /* The shared rings and indexes. */ + netif_tx_back_ring_t tx; + netif_rx_back_ring_t rx; + struct vm_struct *tx_comms_area; + struct vm_struct *rx_comms_area; + + /* Set of features that can be turned on in dev->features. */ + int features; + int can_queue; + + /* Allow netif_be_start_xmit() to peek ahead in the rx request ring. */ + RING_IDX rx_req_cons_peek; + + /* Transmit shaping: allow 'credit_bytes' every 'credit_usec'. */ + unsigned long credit_bytes; + unsigned long credit_usec; + unsigned long remaining_credit; + struct timer_list credit_timeout; + + /* Miscellaneous private stuff. */ + struct list_head list; /* scheduling list */ + atomic_t refcnt; + struct net_device *dev; + struct net_device_stats stats; + + wait_queue_head_t waiting_to_free; } netif_t; -void netif_create(netif_be_create_t *create); -void netif_destroy(netif_be_destroy_t *destroy); -void netif_creditlimit(netif_be_creditlimit_t *creditlimit); -void netif_connect(netif_be_connect_t *connect); -int netif_disconnect(netif_be_disconnect_t *disconnect, u8 rsp_id); -void netif_disconnect_complete(netif_t *netif); -netif_t *netif_find_by_handle(domid_t domid, unsigned int handle); +#define NET_TX_RING_SIZE __RING_SIZE((netif_tx_sring_t *)0, PAGE_SIZE) +#define NET_RX_RING_SIZE __RING_SIZE((netif_rx_sring_t *)0, PAGE_SIZE) + +void netif_disconnect(netif_t *netif); + +netif_t *netif_alloc(domid_t domid, unsigned int handle, u8 be_mac[ETH_ALEN]); +int netif_map(netif_t *netif, unsigned long tx_ring_ref, + unsigned long rx_ring_ref, unsigned int evtchn); + #define netif_get(_b) (atomic_inc(&(_b)->refcnt)) -#define netif_put(_b) \ - do { \ - if ( atomic_dec_and_test(&(_b)->refcnt) ) \ - netif_disconnect_complete(_b); \ - } while (0) +#define netif_put(_b) \ + do { \ + if ( atomic_dec_and_test(&(_b)->refcnt) ) \ + wake_up(&(_b)->waiting_to_free); \ + } while (0) -void netif_interface_init(void); -void netif_ctrlif_init(void); +void netif_xenbus_init(void); void netif_schedule_work(netif_t *netif); void netif_deschedule_work(netif_t *netif); @@ -100,4 +123,16 @@ int netif_be_start_xmit(struct sk_buff *skb, struct net_device *dev); struct net_device_stats *netif_be_get_stats(struct net_device *dev); irqreturn_t netif_be_int(int irq, void *dev_id, struct pt_regs *regs); +static inline int netbk_can_queue(struct net_device *dev) +{ + netif_t *netif = netdev_priv(dev); + return netif->can_queue; +} + +static inline int netbk_can_sg(struct net_device *dev) +{ + netif_t *netif = netdev_priv(dev); + return netif->features & NETIF_F_SG; +} + #endif /* __NETIF__BACKEND__COMMON_H__ */ diff --git a/drivers/xen/netback/interface.c b/drivers/xen/netback/interface.c index f509a1b8d..d60b23b0f 100644 --- a/drivers/xen/netback/interface.c +++ b/drivers/xen/netback/interface.c @@ -4,377 +4,336 @@ * Network-device interface management. * * Copyright (c) 2004-2005, Keir Fraser + * + * 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; or, when distributed + * separately from the Linux kernel or incorporated into other + * software packages, subject to the following license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this source file (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, modify, + * merge, publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. */ #include "common.h" +#include #include -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) -#define VMALLOC_VMADDR(x) ((unsigned long)(x)) -#endif - -#define NETIF_HASHSZ 1024 -#define NETIF_HASH(_d,_h) (((int)(_d)^(int)(_h))&(NETIF_HASHSZ-1)) - -static netif_t *netif_hash[NETIF_HASHSZ]; - -netif_t *netif_find_by_handle(domid_t domid, unsigned int handle) -{ - netif_t *netif = netif_hash[NETIF_HASH(domid, handle)]; - while ( (netif != NULL) && - ((netif->domid != domid) || (netif->handle != handle)) ) - netif = netif->hash_next; - return netif; -} - static void __netif_up(netif_t *netif) { - struct net_device *dev = netif->dev; - spin_lock_bh(&dev->xmit_lock); - netif->active = 1; - spin_unlock_bh(&dev->xmit_lock); - (void)request_irq(netif->irq, netif_be_int, 0, dev->name, netif); - netif_schedule_work(netif); + enable_irq(netif->irq); + netif_schedule_work(netif); } static void __netif_down(netif_t *netif) { - struct net_device *dev = netif->dev; - spin_lock_bh(&dev->xmit_lock); - netif->active = 0; - spin_unlock_bh(&dev->xmit_lock); - free_irq(netif->irq, netif); - netif_deschedule_work(netif); + disable_irq(netif->irq); + netif_deschedule_work(netif); } static int net_open(struct net_device *dev) { - netif_t *netif = netdev_priv(dev); - if ( netif->status == CONNECTED ) - __netif_up(netif); - netif_start_queue(dev); - return 0; + netif_t *netif = netdev_priv(dev); + if (netif_carrier_ok(dev)) + __netif_up(netif); + return 0; } static int net_close(struct net_device *dev) { - netif_t *netif = netdev_priv(dev); - netif_stop_queue(dev); - if ( netif->status == CONNECTED ) - __netif_down(netif); - return 0; + netif_t *netif = netdev_priv(dev); + if (netif_carrier_ok(dev)) + __netif_down(netif); + return 0; } -static void __netif_disconnect_complete(void *arg) +static int netbk_change_mtu(struct net_device *dev, int mtu) { - netif_t *netif = (netif_t *)arg; - ctrl_msg_t cmsg; - netif_be_disconnect_t disc; - - /* - * These can't be done in netif_disconnect() because at that point there - * may be outstanding requests in the network stack whose asynchronous - * responses must still be notified to the remote driver. - */ - unbind_evtchn_from_irq(netif->evtchn); - vfree(netif->tx); /* Frees netif->rx as well. */ - - /* Construct the deferred response message. */ - cmsg.type = CMSG_NETIF_BE; - cmsg.subtype = CMSG_NETIF_BE_DISCONNECT; - cmsg.id = netif->disconnect_rspid; - cmsg.length = sizeof(netif_be_disconnect_t); - disc.domid = netif->domid; - disc.netif_handle = netif->handle; - disc.status = NETIF_BE_STATUS_OKAY; - memcpy(cmsg.msg, &disc, sizeof(disc)); - - /* - * Make sure message is constructed /before/ status change, because - * after the status change the 'netif' structure could be deallocated at - * any time. Also make sure we send the response /after/ status change, - * as otherwise a subsequent CONNECT request could spuriously fail if - * another CPU doesn't see the status change yet. - */ - mb(); - if ( netif->status != DISCONNECTING ) - BUG(); - netif->status = DISCONNECTED; - mb(); - - /* Send the successful response. */ - ctrl_if_send_response(&cmsg); + int max = netbk_can_sg(dev) ? 65535 - ETH_HLEN : ETH_DATA_LEN; + + if (mtu > max) + return -EINVAL; + dev->mtu = mtu; + return 0; } -void netif_disconnect_complete(netif_t *netif) +static int netbk_set_sg(struct net_device *dev, u32 data) { - INIT_WORK(&netif->work, __netif_disconnect_complete, (void *)netif); - schedule_work(&netif->work); + if (data) { + netif_t *netif = netdev_priv(dev); + + if (!(netif->features & NETIF_F_SG)) + return -ENOSYS; + } + + return ethtool_op_set_sg(dev, data); } -void netif_create(netif_be_create_t *create) +static int netbk_set_tso(struct net_device *dev, u32 data) { - int err = 0; - domid_t domid = create->domid; - unsigned int handle = create->netif_handle; - struct net_device *dev; - netif_t **pnetif, *netif; - char name[IFNAMSIZ] = {}; - - snprintf(name, IFNAMSIZ - 1, "vif%u.%u", domid, handle); - dev = alloc_netdev(sizeof(netif_t), name, ether_setup); - if ( dev == NULL ) - { - DPRINTK("Could not create netif: out of memory\n"); - create->status = NETIF_BE_STATUS_OUT_OF_MEMORY; - return; - } - - netif = netdev_priv(dev); - memset(netif, 0, sizeof(*netif)); - netif->domid = domid; - netif->handle = handle; - netif->status = DISCONNECTED; - atomic_set(&netif->refcnt, 0); - netif->dev = dev; - - netif->credit_bytes = netif->remaining_credit = ~0UL; - netif->credit_usec = 0UL; - init_timer(&netif->credit_timeout); - - pnetif = &netif_hash[NETIF_HASH(domid, handle)]; - while ( *pnetif != NULL ) - { - if ( ((*pnetif)->domid == domid) && ((*pnetif)->handle == handle) ) - { - DPRINTK("Could not create netif: already exists\n"); - create->status = NETIF_BE_STATUS_INTERFACE_EXISTS; - free_netdev(dev); - return; - } - pnetif = &(*pnetif)->hash_next; - } - - dev->hard_start_xmit = netif_be_start_xmit; - dev->get_stats = netif_be_get_stats; - dev->open = net_open; - dev->stop = net_close; - - /* Disable queuing. */ - dev->tx_queue_len = 0; - - if ( (create->be_mac[0] == 0) && (create->be_mac[1] == 0) && - (create->be_mac[2] == 0) && (create->be_mac[3] == 0) && - (create->be_mac[4] == 0) && (create->be_mac[5] == 0) ) - { - /* - * Initialise a dummy MAC address. We choose the numerically largest - * non-broadcast address to prevent the address getting stolen by an - * Ethernet bridge for STP purposes. (FE:FF:FF:FF:FF:FF) - */ - memset(dev->dev_addr, 0xFF, ETH_ALEN); - dev->dev_addr[0] &= ~0x01; - } - else - { - memcpy(dev->dev_addr, create->be_mac, ETH_ALEN); - } - - memcpy(netif->fe_dev_addr, create->mac, ETH_ALEN); - - rtnl_lock(); - err = register_netdevice(dev); - rtnl_unlock(); - - if ( err != 0 ) - { - DPRINTK("Could not register new net device %s: err=%d\n", - dev->name, err); - create->status = NETIF_BE_STATUS_OUT_OF_MEMORY; - free_netdev(dev); - return; - } - - netif->hash_next = *pnetif; - *pnetif = netif; - - DPRINTK("Successfully created netif\n"); - create->status = NETIF_BE_STATUS_OKAY; + if (data) { + netif_t *netif = netdev_priv(dev); + + if (!(netif->features & NETIF_F_TSO)) + return -ENOSYS; + } + + return ethtool_op_set_tso(dev, data); } -void netif_destroy(netif_be_destroy_t *destroy) +static struct ethtool_ops network_ethtool_ops = { - domid_t domid = destroy->domid; - unsigned int handle = destroy->netif_handle; - netif_t **pnetif, *netif; - - pnetif = &netif_hash[NETIF_HASH(domid, handle)]; - while ( (netif = *pnetif) != NULL ) - { - if ( (netif->domid == domid) && (netif->handle == handle) ) - { - if ( netif->status != DISCONNECTED ) - goto still_connected; - goto destroy; - } - pnetif = &netif->hash_next; - } - - destroy->status = NETIF_BE_STATUS_INTERFACE_NOT_FOUND; - return; - - still_connected: - destroy->status = NETIF_BE_STATUS_INTERFACE_CONNECTED; - return; - - destroy: - *pnetif = netif->hash_next; - unregister_netdev(netif->dev); - free_netdev(netif->dev); - destroy->status = NETIF_BE_STATUS_OKAY; + .get_tx_csum = ethtool_op_get_tx_csum, + .set_tx_csum = ethtool_op_set_tx_csum, + .get_sg = ethtool_op_get_sg, + .set_sg = netbk_set_sg, + .get_tso = ethtool_op_get_tso, + .set_tso = netbk_set_tso, + .get_link = ethtool_op_get_link, +}; + +netif_t *netif_alloc(domid_t domid, unsigned int handle, u8 be_mac[ETH_ALEN]) +{ + int err = 0, i; + struct net_device *dev; + netif_t *netif; + char name[IFNAMSIZ] = {}; + + snprintf(name, IFNAMSIZ - 1, "vif%u.%u", domid, handle); + dev = alloc_netdev(sizeof(netif_t), name, ether_setup); + if (dev == NULL) { + DPRINTK("Could not create netif: out of memory\n"); + return ERR_PTR(-ENOMEM); + } + + netif_carrier_off(dev); + + netif = netdev_priv(dev); + memset(netif, 0, sizeof(*netif)); + netif->domid = domid; + netif->handle = handle; + atomic_set(&netif->refcnt, 1); + init_waitqueue_head(&netif->waiting_to_free); + netif->dev = dev; + + netif->credit_bytes = netif->remaining_credit = ~0UL; + netif->credit_usec = 0UL; + init_timer(&netif->credit_timeout); + + dev->hard_start_xmit = netif_be_start_xmit; + dev->get_stats = netif_be_get_stats; + dev->open = net_open; + dev->stop = net_close; + dev->change_mtu = netbk_change_mtu; + dev->features = NETIF_F_IP_CSUM; + + SET_ETHTOOL_OPS(dev, &network_ethtool_ops); + + /* + * Reduce default TX queuelen so that each guest interface only + * allows it to eat around 6.4MB of host memory. + */ + dev->tx_queue_len = 100; + + for (i = 0; i < ETH_ALEN; i++) + if (be_mac[i] != 0) + break; + if (i == ETH_ALEN) { + /* + * Initialise a dummy MAC address. We choose the numerically + * largest non-broadcast address to prevent the address getting + * stolen by an Ethernet bridge for STP purposes. + * (FE:FF:FF:FF:FF:FF) + */ + memset(dev->dev_addr, 0xFF, ETH_ALEN); + dev->dev_addr[0] &= ~0x01; + } else + memcpy(dev->dev_addr, be_mac, ETH_ALEN); + + rtnl_lock(); + err = register_netdevice(dev); + rtnl_unlock(); + if (err) { + DPRINTK("Could not register new net device %s: err=%d\n", + dev->name, err); + free_netdev(dev); + return ERR_PTR(err); + } + + DPRINTK("Successfully created netif\n"); + return netif; } -void netif_creditlimit(netif_be_creditlimit_t *creditlimit) +static int map_frontend_pages( + netif_t *netif, grant_ref_t tx_ring_ref, grant_ref_t rx_ring_ref) { - domid_t domid = creditlimit->domid; - unsigned int handle = creditlimit->netif_handle; - netif_t *netif; - - netif = netif_find_by_handle(domid, handle); - if ( unlikely(netif == NULL) ) - { - DPRINTK("netif_creditlimit attempted for non-existent netif" - " (%u,%u)\n", creditlimit->domid, creditlimit->netif_handle); - creditlimit->status = NETIF_BE_STATUS_INTERFACE_NOT_FOUND; - return; - } - - /* Set the credit limit (reset remaining credit to new limit). */ - netif->credit_bytes = netif->remaining_credit = creditlimit->credit_bytes; - netif->credit_usec = creditlimit->period_usec; - - if ( netif->status == CONNECTED ) - { - /* - * Schedule work so that any packets waiting under previous credit - * limit are dealt with (acts like a replenishment point). - */ - netif->credit_timeout.expires = jiffies; - netif_schedule_work(netif); - } + struct gnttab_map_grant_ref op; + int ret; + + gnttab_set_map_op(&op, (unsigned long)netif->tx_comms_area->addr, + GNTMAP_host_map, tx_ring_ref, netif->domid); - creditlimit->status = NETIF_BE_STATUS_OKAY; + lock_vm_area(netif->tx_comms_area); + ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1); + unlock_vm_area(netif->tx_comms_area); + BUG_ON(ret); + + if (op.status) { + DPRINTK(" Gnttab failure mapping tx_ring_ref!\n"); + return op.status; + } + + netif->tx_shmem_ref = tx_ring_ref; + netif->tx_shmem_handle = op.handle; + + gnttab_set_map_op(&op, (unsigned long)netif->rx_comms_area->addr, + GNTMAP_host_map, rx_ring_ref, netif->domid); + + lock_vm_area(netif->rx_comms_area); + ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1); + unlock_vm_area(netif->rx_comms_area); + BUG_ON(ret); + + if (op.status) { + DPRINTK(" Gnttab failure mapping rx_ring_ref!\n"); + return op.status; + } + + netif->rx_shmem_ref = rx_ring_ref; + netif->rx_shmem_handle = op.handle; + + return 0; } -void netif_connect(netif_be_connect_t *connect) +static void unmap_frontend_pages(netif_t *netif) { - domid_t domid = connect->domid; - unsigned int handle = connect->netif_handle; - unsigned int evtchn = connect->evtchn; - unsigned long tx_shmem_frame = connect->tx_shmem_frame; - unsigned long rx_shmem_frame = connect->rx_shmem_frame; - struct vm_struct *vma; - pgprot_t prot; - int error; - netif_t *netif; - - netif = netif_find_by_handle(domid, handle); - if ( unlikely(netif == NULL) ) - { - DPRINTK("netif_connect attempted for non-existent netif (%u,%u)\n", - connect->domid, connect->netif_handle); - connect->status = NETIF_BE_STATUS_INTERFACE_NOT_FOUND; - return; - } - - if ( netif->status != DISCONNECTED ) - { - connect->status = NETIF_BE_STATUS_INTERFACE_CONNECTED; - return; - } - - if ( (vma = get_vm_area(2*PAGE_SIZE, VM_IOREMAP)) == NULL ) - { - connect->status = NETIF_BE_STATUS_OUT_OF_MEMORY; - return; - } - - prot = __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED); - error = direct_remap_area_pages(&init_mm, - VMALLOC_VMADDR(vma->addr), - tx_shmem_frame<addr) + PAGE_SIZE, - rx_shmem_frame<status = NETIF_BE_STATUS_OUT_OF_MEMORY; - else if ( error == -EFAULT ) - connect->status = NETIF_BE_STATUS_MAPPING_ERROR; - else - connect->status = NETIF_BE_STATUS_ERROR; - vfree(vma->addr); - return; - } - - netif->evtchn = evtchn; - netif->irq = bind_evtchn_to_irq(evtchn); - netif->tx_shmem_frame = tx_shmem_frame; - netif->rx_shmem_frame = rx_shmem_frame; - netif->tx = - (netif_tx_interface_t *)vma->addr; - netif->rx = - (netif_rx_interface_t *)((char *)vma->addr + PAGE_SIZE); - netif->tx->resp_prod = netif->rx->resp_prod = 0; - netif_get(netif); - wmb(); /* Other CPUs see new state before interface is started. */ - - rtnl_lock(); - netif->status = CONNECTED; - wmb(); - if ( netif_running(netif->dev) ) - __netif_up(netif); - rtnl_unlock(); - - connect->status = NETIF_BE_STATUS_OKAY; + struct gnttab_unmap_grant_ref op; + int ret; + + gnttab_set_unmap_op(&op, (unsigned long)netif->tx_comms_area->addr, + GNTMAP_host_map, netif->tx_shmem_handle); + + lock_vm_area(netif->tx_comms_area); + ret = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1); + unlock_vm_area(netif->tx_comms_area); + BUG_ON(ret); + + gnttab_set_unmap_op(&op, (unsigned long)netif->rx_comms_area->addr, + GNTMAP_host_map, netif->rx_shmem_handle); + + lock_vm_area(netif->rx_comms_area); + ret = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1); + unlock_vm_area(netif->rx_comms_area); + BUG_ON(ret); +} + +int netif_map(netif_t *netif, unsigned long tx_ring_ref, + unsigned long rx_ring_ref, unsigned int evtchn) +{ + int err = -ENOMEM; + netif_tx_sring_t *txs; + netif_rx_sring_t *rxs; + struct evtchn_bind_interdomain bind_interdomain; + + /* Already connected through? */ + if (netif->irq) + return 0; + + netif->tx_comms_area = alloc_vm_area(PAGE_SIZE); + if (netif->tx_comms_area == NULL) + return -ENOMEM; + netif->rx_comms_area = alloc_vm_area(PAGE_SIZE); + if (netif->rx_comms_area == NULL) + goto err_rx; + + err = map_frontend_pages(netif, tx_ring_ref, rx_ring_ref); + if (err) + goto err_map; + + bind_interdomain.remote_dom = netif->domid; + bind_interdomain.remote_port = evtchn; + + err = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain, + &bind_interdomain); + if (err) + goto err_hypervisor; + + netif->evtchn = bind_interdomain.local_port; + + netif->irq = bind_evtchn_to_irqhandler( + netif->evtchn, netif_be_int, 0, netif->dev->name, netif); + disable_irq(netif->irq); + + txs = (netif_tx_sring_t *)netif->tx_comms_area->addr; + BACK_RING_INIT(&netif->tx, txs, PAGE_SIZE); + + rxs = (netif_rx_sring_t *) + ((char *)netif->rx_comms_area->addr); + BACK_RING_INIT(&netif->rx, rxs, PAGE_SIZE); + + netif->rx_req_cons_peek = 0; + + netif_get(netif); + + rtnl_lock(); + netif_carrier_on(netif->dev); + if (netif_running(netif->dev)) + __netif_up(netif); + rtnl_unlock(); + + return 0; +err_hypervisor: + unmap_frontend_pages(netif); +err_map: + free_vm_area(netif->rx_comms_area); +err_rx: + free_vm_area(netif->tx_comms_area); + return err; } -int netif_disconnect(netif_be_disconnect_t *disconnect, u8 rsp_id) +static void netif_free(netif_t *netif) { - domid_t domid = disconnect->domid; - unsigned int handle = disconnect->netif_handle; - netif_t *netif; - - netif = netif_find_by_handle(domid, handle); - if ( unlikely(netif == NULL) ) - { - DPRINTK("netif_disconnect attempted for non-existent netif" - " (%u,%u)\n", disconnect->domid, disconnect->netif_handle); - disconnect->status = NETIF_BE_STATUS_INTERFACE_NOT_FOUND; - return 1; /* Caller will send response error message. */ - } - - if ( netif->status == CONNECTED ) - { - rtnl_lock(); - netif->status = DISCONNECTING; - netif->disconnect_rspid = rsp_id; - wmb(); - if ( netif_running(netif->dev) ) - __netif_down(netif); - rtnl_unlock(); - netif_put(netif); - return 0; /* Caller should not send response message. */ - } - - disconnect->status = NETIF_BE_STATUS_OKAY; - return 1; + atomic_dec(&netif->refcnt); + wait_event(netif->waiting_to_free, atomic_read(&netif->refcnt) == 0); + + if (netif->irq) + unbind_from_irqhandler(netif->irq, netif); + + unregister_netdev(netif->dev); + + if (netif->tx.sring) { + unmap_frontend_pages(netif); + free_vm_area(netif->tx_comms_area); + free_vm_area(netif->rx_comms_area); + } + + free_netdev(netif->dev); } -void netif_interface_init(void) +void netif_disconnect(netif_t *netif) { - memset(netif_hash, 0, sizeof(netif_hash)); + if (netif_carrier_ok(netif->dev)) { + rtnl_lock(); + netif_carrier_off(netif->dev); + if (netif_running(netif->dev)) + __netif_down(netif); + rtnl_unlock(); + netif_put(netif); + } + netif_free(netif); } diff --git a/drivers/xen/netback/netback.c b/drivers/xen/netback/netback.c index d08c296a0..0316f3b05 100644 --- a/drivers/xen/netback/netback.c +++ b/drivers/xen/netback/netback.c @@ -8,26 +8,54 @@ * drivers/xen/netfront/netfront.c * * Copyright (c) 2002-2005, K A Fraser + * + * 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; or, when distributed + * separately from the Linux kernel or incorporated into other + * software packages, subject to the following license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this source file (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, modify, + * merge, publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. */ #include "common.h" -#include -#include +#include +#include -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) -#include -#endif +/*#define NETBE_DEBUG_INTERRUPT*/ + +struct netbk_rx_meta { + skb_frag_t frag; + int id; +}; static void netif_idx_release(u16 pending_idx); static void netif_page_release(struct page *page); static void make_tx_response(netif_t *netif, - u16 id, - s8 st); -static int make_rx_response(netif_t *netif, - u16 id, - s8 st, - memory_t addr, - u16 size); + netif_tx_request_t *txp, + s8 st); +static netif_rx_response_t *make_rx_response(netif_t *netif, + u16 id, + s8 st, + u16 offset, + u16 size, + u16 flags); static void net_tx_action(unsigned long unused); static DECLARE_TASKLET(net_tx_tasklet, net_tx_action, 0); @@ -37,24 +65,22 @@ static DECLARE_TASKLET(net_rx_tasklet, net_rx_action, 0); static struct timer_list net_timer; -static struct sk_buff_head rx_queue; -static multicall_entry_t rx_mcl[NETIF_RX_RING_SIZE*2+1]; -static mmu_update_t rx_mmu[NETIF_RX_RING_SIZE]; -static struct mmuext_op rx_mmuext[NETIF_RX_RING_SIZE]; -static unsigned char rx_notify[NR_EVENT_CHANNELS]; +#define MAX_PENDING_REQS 256 -/* Don't currently gate addition of an interface to the tx scheduling list. */ -#define tx_work_exists(_if) (1) +static struct sk_buff_head rx_queue; +static multicall_entry_t rx_mcl[NET_RX_RING_SIZE+1]; +static mmu_update_t rx_mmu[NET_RX_RING_SIZE]; +static gnttab_transfer_t grant_rx_op[NET_RX_RING_SIZE]; +static unsigned char rx_notify[NR_IRQS]; -#define MAX_PENDING_REQS 256 static unsigned long mmap_vstart; #define MMAP_VADDR(_req) (mmap_vstart + ((_req) * PAGE_SIZE)) #define PKT_PROT_LEN 64 static struct { - netif_tx_request_t req; - netif_t *netif; + netif_tx_request_t req; + netif_t *netif; } pending_tx_info[MAX_PENDING_REQS]; static u16 pending_ring[MAX_PENDING_REQS]; typedef unsigned int PEND_RING_IDX; @@ -67,7 +93,10 @@ static u16 dealloc_ring[MAX_PENDING_REQS]; static PEND_RING_IDX dealloc_prod, dealloc_cons; static struct sk_buff_head tx_queue; -static multicall_entry_t tx_mcl[MAX_PENDING_REQS]; + +static grant_handle_t grant_tx_handle[MAX_PENDING_REQS]; +static gnttab_unmap_grant_ref_t tx_unmap_ops[MAX_PENDING_REQS]; +static gnttab_map_grant_ref_t tx_map_ops[MAX_PENDING_REQS]; static struct list_head net_schedule_list; static spinlock_t net_schedule_list_lock; @@ -75,39 +104,36 @@ static spinlock_t net_schedule_list_lock; #define MAX_MFN_ALLOC 64 static unsigned long mfn_list[MAX_MFN_ALLOC]; static unsigned int alloc_index = 0; -static spinlock_t mfn_lock = SPIN_LOCK_UNLOCKED; -static unsigned long alloc_mfn(void) +static inline unsigned long alloc_mfn(void) { - unsigned long mfn = 0, flags; - spin_lock_irqsave(&mfn_lock, flags); - if ( unlikely(alloc_index == 0) ) - alloc_index = HYPERVISOR_dom_mem_op( - MEMOP_increase_reservation, mfn_list, MAX_MFN_ALLOC, 0); - if ( alloc_index != 0 ) - mfn = mfn_list[--alloc_index]; - spin_unlock_irqrestore(&mfn_lock, flags); - return mfn; + return mfn_list[--alloc_index]; } -static void free_mfn(unsigned long mfn) +static int check_mfn(int nr) { - unsigned long flags; - spin_lock_irqsave(&mfn_lock, flags); - if ( alloc_index != MAX_MFN_ALLOC ) - mfn_list[alloc_index++] = mfn; - else if ( HYPERVISOR_dom_mem_op(MEMOP_decrease_reservation, - &mfn, 1, 0) != 1 ) - BUG(); - spin_unlock_irqrestore(&mfn_lock, flags); + struct xen_memory_reservation reservation = { + .extent_order = 0, + .domid = DOMID_SELF + }; + + if (likely(alloc_index >= nr)) + return 0; + + set_xen_guest_handle(reservation.extent_start, mfn_list + alloc_index); + reservation.nr_extents = MAX_MFN_ALLOC - alloc_index; + alloc_index += HYPERVISOR_memory_op(XENMEM_increase_reservation, + &reservation); + + return alloc_index >= nr ? 0 : -ENOMEM; } static inline void maybe_schedule_tx_action(void) { - smp_mb(); - if ( (NR_PENDING_REQS < (MAX_PENDING_REQS/2)) && - !list_empty(&net_schedule_list) ) - tasklet_schedule(&net_tx_tasklet); + smp_mb(); + if ((NR_PENDING_REQS < (MAX_PENDING_REQS/2)) && + !list_empty(&net_schedule_list)) + tasklet_schedule(&net_tx_tasklet); } /* @@ -116,69 +142,166 @@ static inline void maybe_schedule_tx_action(void) */ static inline int is_xen_skb(struct sk_buff *skb) { - extern kmem_cache_t *skbuff_cachep; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) - kmem_cache_t *cp = (kmem_cache_t *)virt_to_page(skb->head)->lru.next; -#else - kmem_cache_t *cp = (kmem_cache_t *)virt_to_page(skb->head)->list.next; -#endif - return (cp == skbuff_cachep); + extern kmem_cache_t *skbuff_cachep; + kmem_cache_t *cp = (kmem_cache_t *)virt_to_page(skb->head)->lru.next; + return (cp == skbuff_cachep); +} + +static struct sk_buff *netbk_copy_skb(struct sk_buff *skb) +{ + struct skb_shared_info *ninfo; + struct sk_buff *nskb; + unsigned long offset; + int ret; + int len; + int headlen; + + nskb = alloc_skb(SKB_MAX_HEAD(0), GFP_ATOMIC); + if (unlikely(!nskb)) + goto err; + + skb_reserve(nskb, 16); + headlen = nskb->end - nskb->data; + if (headlen > skb_headlen(skb)) + headlen = skb_headlen(skb); + ret = skb_copy_bits(skb, 0, __skb_put(nskb, headlen), headlen); + BUG_ON(ret); + + ninfo = skb_shinfo(nskb); + ninfo->gso_size = skb_shinfo(skb)->gso_size; + ninfo->gso_type = skb_shinfo(skb)->gso_type; + + offset = headlen; + len = skb->len - headlen; + + nskb->len = skb->len; + nskb->data_len = len; + nskb->truesize += len; + + while (len) { + struct page *page; + int copy; + int zero; + + if (unlikely(ninfo->nr_frags >= MAX_SKB_FRAGS)) { + dump_stack(); + goto err_free; + } + + copy = len >= PAGE_SIZE ? PAGE_SIZE : len; + zero = len >= PAGE_SIZE ? 0 : __GFP_ZERO; + + page = alloc_page(GFP_ATOMIC | zero); + if (unlikely(!page)) + goto err_free; + + ret = skb_copy_bits(skb, offset, page_address(page), copy); + BUG_ON(ret); + + ninfo->frags[ninfo->nr_frags].page = page; + ninfo->frags[ninfo->nr_frags].page_offset = 0; + ninfo->frags[ninfo->nr_frags].size = copy; + ninfo->nr_frags++; + + offset += copy; + len -= copy; + } + + offset = nskb->data - skb->data; + + nskb->h.raw = skb->h.raw + offset; + nskb->nh.raw = skb->nh.raw + offset; + nskb->mac.raw = skb->mac.raw + offset; + + return nskb; + + err_free: + kfree_skb(nskb); + err: + return NULL; +} + +static inline int netbk_max_required_rx_slots(netif_t *netif) +{ + if (netif->features & (NETIF_F_SG|NETIF_F_TSO)) + return MAX_SKB_FRAGS + 2; /* header + extra_info + frags */ + return 1; /* all in one */ +} + +static inline int netbk_queue_full(netif_t *netif) +{ + RING_IDX peek = netif->rx_req_cons_peek; + RING_IDX needed = netbk_max_required_rx_slots(netif); + + return ((netif->rx.sring->req_prod - peek) < needed) || + ((netif->rx.rsp_prod_pvt + NET_RX_RING_SIZE - peek) < needed); } int netif_be_start_xmit(struct sk_buff *skb, struct net_device *dev) { - netif_t *netif = netdev_priv(dev); - - ASSERT(skb->dev == dev); - - /* Drop the packet if the target domain has no receive buffers. */ - if ( !netif->active || - (netif->rx_req_cons == netif->rx->req_prod) || - ((netif->rx_req_cons-netif->rx_resp_prod) == NETIF_RX_RING_SIZE) ) - goto drop; - - /* - * We do not copy the packet unless: - * 1. The data is shared; or - * 2. The data is not allocated from our special cache. - * NB. We also couldn't cope with fragmented packets, but we won't get - * any because we not advertise the NETIF_F_SG feature. - */ - if ( skb_shared(skb) || skb_cloned(skb) || !is_xen_skb(skb) ) - { - int hlen = skb->data - skb->head; - struct sk_buff *nskb = dev_alloc_skb(hlen + skb->len); - if ( unlikely(nskb == NULL) ) - goto drop; - skb_reserve(nskb, hlen); - __skb_put(nskb, skb->len); - (void)skb_copy_bits(skb, -hlen, nskb->data - hlen, skb->len + hlen); - nskb->dev = skb->dev; - dev_kfree_skb(skb); - skb = nskb; - } - - netif->rx_req_cons++; - netif_get(netif); - - skb_queue_tail(&rx_queue, skb); - tasklet_schedule(&net_rx_tasklet); - - return 0; + netif_t *netif = netdev_priv(dev); + + BUG_ON(skb->dev != dev); + + /* Drop the packet if the target domain has no receive buffers. */ + if (unlikely(!netif_running(dev) || !netif_carrier_ok(dev))) + goto drop; + + if (unlikely(netbk_queue_full(netif))) { + /* Not a BUG_ON() -- misbehaving netfront can trigger this. */ + if (netbk_can_queue(dev)) + DPRINTK("Queue full but not stopped!\n"); + goto drop; + } + + /* + * We do not copy the packet unless: + * 1. The data is shared; or + * 2. The data is not allocated from our special cache. + * 3. The data is fragmented. + */ + if (skb_cloned(skb) || skb_is_nonlinear(skb) || !is_xen_skb(skb)) { + struct sk_buff *nskb = netbk_copy_skb(skb); + if ( unlikely(nskb == NULL) ) + goto drop; + /* Copy only the header fields we use in this driver. */ + nskb->dev = skb->dev; + nskb->ip_summed = skb->ip_summed; + nskb->proto_data_valid = skb->proto_data_valid; + dev_kfree_skb(skb); + skb = nskb; + } + + netif->rx_req_cons_peek += skb_shinfo(skb)->nr_frags + 1 + + !!skb_shinfo(skb)->gso_size; + netif_get(netif); + + if (netbk_can_queue(dev) && netbk_queue_full(netif)) { + netif->rx.sring->req_event = netif->rx_req_cons_peek + + netbk_max_required_rx_slots(netif); + mb(); /* request notification /then/ check & stop the queue */ + if (netbk_queue_full(netif)) + netif_stop_queue(dev); + } + + skb_queue_tail(&rx_queue, skb); + tasklet_schedule(&net_rx_tasklet); + + return 0; drop: - netif->stats.tx_dropped++; - dev_kfree_skb(skb); - return 0; + netif->stats.tx_dropped++; + dev_kfree_skb(skb); + return 0; } #if 0 static void xen_network_done_notify(void) { - static struct net_device *eth0_dev = NULL; - if ( unlikely(eth0_dev == NULL) ) - eth0_dev = __dev_get_by_name("eth0"); - netif_rx_schedule(eth0_dev); + static struct net_device *eth0_dev = NULL; + if (unlikely(eth0_dev == NULL)) + eth0_dev = __dev_get_by_name("eth0"); + netif_rx_schedule(eth0_dev); } /* * Add following to poll() function in NAPI driver (Tigon3 is example): @@ -187,633 +310,1036 @@ static void xen_network_done_notify(void) */ int xen_network_done(void) { - return skb_queue_empty(&rx_queue); + return skb_queue_empty(&rx_queue); } #endif +static u16 netbk_gop_frag(netif_t *netif, struct page *page, int count, int i) +{ + multicall_entry_t *mcl = rx_mcl + count; + mmu_update_t *mmu = rx_mmu + count; + gnttab_transfer_t *gop = grant_rx_op + count; + netif_rx_request_t *req; + unsigned long old_mfn, new_mfn; + + old_mfn = virt_to_mfn(page_address(page)); + + if (!xen_feature(XENFEAT_auto_translated_physmap)) { + new_mfn = alloc_mfn(); + + /* + * Set the new P2M table entry before reassigning + * the old data page. Heed the comment in + * pgtable-2level.h:pte_page(). :-) + */ + set_phys_to_machine(page_to_pfn(page), new_mfn); + + MULTI_update_va_mapping(mcl, (unsigned long)page_address(page), + pfn_pte_ma(new_mfn, PAGE_KERNEL), 0); + + mmu->ptr = ((maddr_t)new_mfn << PAGE_SHIFT) | + MMU_MACHPHYS_UPDATE; + mmu->val = page_to_pfn(page); + } + + req = RING_GET_REQUEST(&netif->rx, netif->rx.req_cons + i); + gop->mfn = old_mfn; + gop->domid = netif->domid; + gop->ref = req->gref; + return req->id; +} + +static void netbk_gop_skb(struct sk_buff *skb, struct netbk_rx_meta *meta, + int count) +{ + netif_t *netif = netdev_priv(skb->dev); + int nr_frags = skb_shinfo(skb)->nr_frags; + int i; + int extra; + + meta[count].frag.page_offset = skb_shinfo(skb)->gso_type; + meta[count].frag.size = skb_shinfo(skb)->gso_size; + extra = !!meta[count].frag.size + 1; + + for (i = 0; i < nr_frags; i++) { + meta[++count].frag = skb_shinfo(skb)->frags[i]; + meta[count].id = netbk_gop_frag(netif, meta[count].frag.page, + count, i + extra); + } + + /* + * This must occur at the end to ensure that we don't trash + * skb_shinfo until we're done. + */ + meta[count - nr_frags].id = netbk_gop_frag(netif, + virt_to_page(skb->data), + count - nr_frags, 0); + netif->rx.req_cons += nr_frags + extra; +} + +static inline void netbk_free_pages(int nr_frags, struct netbk_rx_meta *meta) +{ + int i; + + for (i = 0; i < nr_frags; i++) + put_page(meta[i].frag.page); +} + +static int netbk_check_gop(int nr_frags, domid_t domid, int count) +{ + multicall_entry_t *mcl = rx_mcl + count; + gnttab_transfer_t *gop = grant_rx_op + count; + int status = NETIF_RSP_OKAY; + int i; + + for (i = 0; i <= nr_frags; i++) { + if (!xen_feature(XENFEAT_auto_translated_physmap)) { + /* The update_va_mapping() must not fail. */ + BUG_ON(mcl->result != 0); + mcl++; + } + + /* Check the reassignment error code. */ + if (gop->status != 0) { + DPRINTK("Bad status %d from grant transfer to DOM%u\n", + gop->status, domid); + /* + * Page no longer belongs to us unless GNTST_bad_page, + * but that should be a fatal error anyway. + */ + BUG_ON(gop->status == GNTST_bad_page); + status = NETIF_RSP_ERROR; + } + gop++; + } + + return status; +} + +static void netbk_add_frag_responses(netif_t *netif, int status, + struct netbk_rx_meta *meta, int nr_frags) +{ + int i; + + for (i = 0; i < nr_frags; i++) { + int id = meta[i].id; + int flags = (i == nr_frags - 1) ? 0 : NETRXF_more_data; + + make_rx_response(netif, id, status, meta[i].frag.page_offset, + meta[i].frag.size, flags); + } +} + static void net_rx_action(unsigned long unused) { - netif_t *netif; - s8 status; - u16 size, id, evtchn; - multicall_entry_t *mcl; - mmu_update_t *mmu; - struct mmuext_op *mmuext; - unsigned long vdata, mdata, new_mfn; - struct sk_buff_head rxq; - struct sk_buff *skb; - u16 notify_list[NETIF_RX_RING_SIZE]; - int notify_nr = 0; - - skb_queue_head_init(&rxq); - - mcl = rx_mcl; - mmu = rx_mmu; - mmuext = rx_mmuext; - while ( (skb = skb_dequeue(&rx_queue)) != NULL ) - { - netif = netdev_priv(skb->dev); - vdata = (unsigned long)skb->data; - mdata = virt_to_machine(vdata); - - /* Memory squeeze? Back off for an arbitrary while. */ - if ( (new_mfn = alloc_mfn()) == 0 ) - { - if ( net_ratelimit() ) - printk(KERN_WARNING "Memory squeeze in netback driver.\n"); - mod_timer(&net_timer, jiffies + HZ); - skb_queue_head(&rx_queue, skb); - break; - } - - /* - * Set the new P2M table entry before reassigning the old data page. - * Heed the comment in pgtable-2level.h:pte_page(). :-) - */ - phys_to_machine_mapping[__pa(skb->data) >> PAGE_SHIFT] = new_mfn; - - mcl->op = __HYPERVISOR_update_va_mapping; - mcl->args[0] = vdata; - mcl->args[1] = (new_mfn << PAGE_SHIFT) | __PAGE_KERNEL; - mcl->args[2] = 0; - mcl++; - - mcl->op = __HYPERVISOR_mmuext_op; - mcl->args[0] = (unsigned long)mmuext; - mcl->args[1] = 1; - mcl->args[2] = 0; - mcl->args[3] = netif->domid; - mcl++; - - mmuext->cmd = MMUEXT_REASSIGN_PAGE; - mmuext->mfn = mdata >> PAGE_SHIFT; - mmuext++; - - mmu->ptr = (new_mfn << PAGE_SHIFT) | MMU_MACHPHYS_UPDATE; - mmu->val = __pa(vdata) >> PAGE_SHIFT; - mmu++; - - __skb_queue_tail(&rxq, skb); - - /* Filled the batch queue? */ - if ( (mcl - rx_mcl) == ARRAY_SIZE(rx_mcl) ) - break; - } - - if ( mcl == rx_mcl ) - return; - - mcl->op = __HYPERVISOR_mmu_update; - mcl->args[0] = (unsigned long)rx_mmu; - mcl->args[1] = mmu - rx_mmu; - mcl->args[2] = 0; - mcl->args[3] = DOMID_SELF; - mcl++; - - mcl[-3].args[2] = UVMF_TLB_FLUSH|UVMF_ALL; - if ( unlikely(HYPERVISOR_multicall(rx_mcl, mcl - rx_mcl) != 0) ) - BUG(); - - mcl = rx_mcl; - mmuext = rx_mmuext; - while ( (skb = __skb_dequeue(&rxq)) != NULL ) - { - netif = netdev_priv(skb->dev); - size = skb->tail - skb->data; - - /* Rederive the machine addresses. */ - new_mfn = mcl[0].args[1] >> PAGE_SHIFT; - mdata = ((mmuext[0].mfn << PAGE_SHIFT) | - ((unsigned long)skb->data & ~PAGE_MASK)); - - atomic_set(&(skb_shinfo(skb)->dataref), 1); - skb_shinfo(skb)->nr_frags = 0; - skb_shinfo(skb)->frag_list = NULL; - - netif->stats.tx_bytes += size; - netif->stats.tx_packets++; - - /* The update_va_mapping() must not fail. */ - if ( unlikely(mcl[0].args[5] != 0) ) - BUG(); - - /* Check the reassignment error code. */ - status = NETIF_RSP_OKAY; - if ( unlikely(mcl[1].args[5] != 0) ) - { - DPRINTK("Failed MMU update transferring to DOM%u\n", netif->domid); - free_mfn(mdata >> PAGE_SHIFT); - status = NETIF_RSP_ERROR; - } - - evtchn = netif->evtchn; - id = netif->rx->ring[MASK_NETIF_RX_IDX(netif->rx_resp_prod)].req.id; - if ( make_rx_response(netif, id, status, mdata, size) && - (rx_notify[evtchn] == 0) ) - { - rx_notify[evtchn] = 1; - notify_list[notify_nr++] = evtchn; - } - - netif_put(netif); - dev_kfree_skb(skb); - - mcl += 2; - mmuext += 1; - } - - while ( notify_nr != 0 ) - { - evtchn = notify_list[--notify_nr]; - rx_notify[evtchn] = 0; - notify_via_evtchn(evtchn); - } - - /* More work to do? */ - if ( !skb_queue_empty(&rx_queue) && !timer_pending(&net_timer) ) - tasklet_schedule(&net_rx_tasklet); + netif_t *netif = NULL; + s8 status; + u16 id, irq, flags; + netif_rx_response_t *resp; + struct netif_extra_info *extra; + multicall_entry_t *mcl; + struct sk_buff_head rxq; + struct sk_buff *skb; + int notify_nr = 0; + int ret; + int nr_frags; + int count; + + /* + * Putting hundreds of bytes on the stack is considered rude. + * Static works because a tasklet can only be on one CPU at any time. + */ + static u16 notify_list[NET_RX_RING_SIZE]; + static struct netbk_rx_meta meta[NET_RX_RING_SIZE]; + + skb_queue_head_init(&rxq); + + count = 0; + + while ((skb = skb_dequeue(&rx_queue)) != NULL) { + nr_frags = skb_shinfo(skb)->nr_frags; + *(int *)skb->cb = nr_frags; + + if (!xen_feature(XENFEAT_auto_translated_physmap) && + check_mfn(nr_frags + 1)) { + /* Memory squeeze? Back off for an arbitrary while. */ + if ( net_ratelimit() ) + WPRINTK("Memory squeeze in netback " + "driver.\n"); + mod_timer(&net_timer, jiffies + HZ); + skb_queue_head(&rx_queue, skb); + break; + } + + netbk_gop_skb(skb, meta, count); + + count += nr_frags + 1; + + __skb_queue_tail(&rxq, skb); + + /* Filled the batch queue? */ + if (count + MAX_SKB_FRAGS >= NET_RX_RING_SIZE) + break; + } + + if (!count) + return; + + if (!xen_feature(XENFEAT_auto_translated_physmap)) { + mcl = rx_mcl + count; + + mcl[-1].args[MULTI_UVMFLAGS_INDEX] = UVMF_TLB_FLUSH|UVMF_ALL; + + mcl->op = __HYPERVISOR_mmu_update; + mcl->args[0] = (unsigned long)rx_mmu; + mcl->args[1] = count; + mcl->args[2] = 0; + mcl->args[3] = DOMID_SELF; + + ret = HYPERVISOR_multicall(rx_mcl, count + 1); + BUG_ON(ret != 0); + } + + ret = HYPERVISOR_grant_table_op(GNTTABOP_transfer, grant_rx_op, count); + BUG_ON(ret != 0); + + count = 0; + while ((skb = __skb_dequeue(&rxq)) != NULL) { + nr_frags = *(int *)skb->cb; + + atomic_set(&(skb_shinfo(skb)->dataref), 1); + skb_shinfo(skb)->nr_frags = 0; + skb_shinfo(skb)->frag_list = NULL; + + netif = netdev_priv(skb->dev); + netif->stats.tx_bytes += skb->len; + netif->stats.tx_packets++; + + netbk_free_pages(nr_frags, meta + count + 1); + status = netbk_check_gop(nr_frags, netif->domid, count); + + id = meta[count].id; + flags = nr_frags ? NETRXF_more_data : 0; + + if (skb->ip_summed == CHECKSUM_HW) /* local packet? */ + flags |= NETRXF_csum_blank | NETRXF_data_validated; + else if (skb->proto_data_valid) /* remote but checksummed? */ + flags |= NETRXF_data_validated; + + resp = make_rx_response(netif, id, status, + offset_in_page(skb->data), + skb_headlen(skb), flags); + + extra = NULL; + + if (meta[count].frag.size) { + struct netif_extra_info *gso = + (struct netif_extra_info *) + RING_GET_RESPONSE(&netif->rx, + netif->rx.rsp_prod_pvt++); + + if (extra) + extra->flags |= XEN_NETIF_EXTRA_FLAG_MORE; + else + resp->flags |= NETRXF_extra_info; + + gso->u.gso.size = meta[count].frag.size; + gso->u.gso.type = XEN_NETIF_GSO_TYPE_TCPV4; + gso->u.gso.pad = 0; + gso->u.gso.features = 0; + + gso->type = XEN_NETIF_EXTRA_TYPE_GSO; + gso->flags = 0; + extra = gso; + } + + netbk_add_frag_responses(netif, status, meta + count + 1, + nr_frags); + + RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&netif->rx, ret); + irq = netif->irq; + if (ret && !rx_notify[irq]) { + rx_notify[irq] = 1; + notify_list[notify_nr++] = irq; + } + + if (netif_queue_stopped(netif->dev) && + !netbk_queue_full(netif)) + netif_wake_queue(netif->dev); + + netif_put(netif); + dev_kfree_skb(skb); + count += nr_frags + 1; + } + + while (notify_nr != 0) { + irq = notify_list[--notify_nr]; + rx_notify[irq] = 0; + notify_remote_via_irq(irq); + } + + /* More work to do? */ + if (!skb_queue_empty(&rx_queue) && !timer_pending(&net_timer)) + tasklet_schedule(&net_rx_tasklet); #if 0 - else - xen_network_done_notify(); + else + xen_network_done_notify(); #endif } static void net_alarm(unsigned long unused) { - tasklet_schedule(&net_rx_tasklet); + tasklet_schedule(&net_rx_tasklet); } struct net_device_stats *netif_be_get_stats(struct net_device *dev) { - netif_t *netif = netdev_priv(dev); - return &netif->stats; + netif_t *netif = netdev_priv(dev); + return &netif->stats; } static int __on_net_schedule_list(netif_t *netif) { - return netif->list.next != NULL; + return netif->list.next != NULL; } static void remove_from_net_schedule_list(netif_t *netif) { - spin_lock_irq(&net_schedule_list_lock); - if ( likely(__on_net_schedule_list(netif)) ) - { - list_del(&netif->list); - netif->list.next = NULL; - netif_put(netif); - } - spin_unlock_irq(&net_schedule_list_lock); + spin_lock_irq(&net_schedule_list_lock); + if (likely(__on_net_schedule_list(netif))) { + list_del(&netif->list); + netif->list.next = NULL; + netif_put(netif); + } + spin_unlock_irq(&net_schedule_list_lock); } static void add_to_net_schedule_list_tail(netif_t *netif) { - if ( __on_net_schedule_list(netif) ) - return; - - spin_lock_irq(&net_schedule_list_lock); - if ( !__on_net_schedule_list(netif) && netif->active ) - { - list_add_tail(&netif->list, &net_schedule_list); - netif_get(netif); - } - spin_unlock_irq(&net_schedule_list_lock); + if (__on_net_schedule_list(netif)) + return; + + spin_lock_irq(&net_schedule_list_lock); + if (!__on_net_schedule_list(netif) && + likely(netif_running(netif->dev) && + netif_carrier_ok(netif->dev))) { + list_add_tail(&netif->list, &net_schedule_list); + netif_get(netif); + } + spin_unlock_irq(&net_schedule_list_lock); } +/* + * Note on CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER: + * If this driver is pipelining transmit requests then we can be very + * aggressive in avoiding new-packet notifications -- frontend only needs to + * send a notification if there are no outstanding unreceived responses. + * If we may be buffer transmit buffers for any reason then we must be rather + * more conservative and treat this as the final check for pending work. + */ void netif_schedule_work(netif_t *netif) { - if ( (netif->tx_req_cons != netif->tx->req_prod) && - ((netif->tx_req_cons-netif->tx_resp_prod) != NETIF_TX_RING_SIZE) ) - { - add_to_net_schedule_list_tail(netif); - maybe_schedule_tx_action(); - } + int more_to_do; + +#ifdef CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER + more_to_do = RING_HAS_UNCONSUMED_REQUESTS(&netif->tx); +#else + RING_FINAL_CHECK_FOR_REQUESTS(&netif->tx, more_to_do); +#endif + + if (more_to_do) { + add_to_net_schedule_list_tail(netif); + maybe_schedule_tx_action(); + } } void netif_deschedule_work(netif_t *netif) { - remove_from_net_schedule_list(netif); + remove_from_net_schedule_list(netif); } static void tx_credit_callback(unsigned long data) { - netif_t *netif = (netif_t *)data; - netif->remaining_credit = netif->credit_bytes; - netif_schedule_work(netif); + netif_t *netif = (netif_t *)data; + netif->remaining_credit = netif->credit_bytes; + netif_schedule_work(netif); } -static void net_tx_action(unsigned long unused) +inline static void net_tx_action_dealloc(void) { - struct list_head *ent; - struct sk_buff *skb; - netif_t *netif; - netif_tx_request_t txreq; - u16 pending_idx; - NETIF_RING_IDX i; - multicall_entry_t *mcl; - PEND_RING_IDX dc, dp; - unsigned int data_len; - - if ( (dc = dealloc_cons) == (dp = dealloc_prod) ) - goto skip_dealloc; - - mcl = tx_mcl; - while ( dc != dp ) - { - pending_idx = dealloc_ring[MASK_PEND_IDX(dc++)]; - mcl[0].op = __HYPERVISOR_update_va_mapping; - mcl[0].args[0] = MMAP_VADDR(pending_idx); - mcl[0].args[1] = 0; - mcl[0].args[2] = 0; - mcl++; - } - - mcl[-1].args[2] = UVMF_TLB_FLUSH|UVMF_ALL; - if ( unlikely(HYPERVISOR_multicall(tx_mcl, mcl - tx_mcl) != 0) ) - BUG(); - - mcl = tx_mcl; - while ( dealloc_cons != dp ) - { - /* The update_va_mapping() must not fail. */ - if ( unlikely(mcl[0].args[5] != 0) ) - BUG(); - - pending_idx = dealloc_ring[MASK_PEND_IDX(dealloc_cons++)]; - - netif = pending_tx_info[pending_idx].netif; - - make_tx_response(netif, pending_tx_info[pending_idx].req.id, - NETIF_RSP_OKAY); - - pending_ring[MASK_PEND_IDX(pending_prod++)] = pending_idx; - - /* - * Scheduling checks must happen after the above response is posted. - * This avoids a possible race with a guest OS on another CPU if that - * guest is testing against 'resp_prod' when deciding whether to notify - * us when it queues additional packets. - */ - mb(); - if ( (netif->tx_req_cons != netif->tx->req_prod) && - ((netif->tx_req_cons-netif->tx_resp_prod) != NETIF_TX_RING_SIZE) ) - add_to_net_schedule_list_tail(netif); - - netif_put(netif); - - mcl++; - } - - skip_dealloc: - mcl = tx_mcl; - while ( (NR_PENDING_REQS < MAX_PENDING_REQS) && - !list_empty(&net_schedule_list) ) - { - /* Get a netif from the list with work to do. */ - ent = net_schedule_list.next; - netif = list_entry(ent, netif_t, list); - netif_get(netif); - remove_from_net_schedule_list(netif); - - /* Work to do? */ - i = netif->tx_req_cons; - if ( (i == netif->tx->req_prod) || - ((i-netif->tx_resp_prod) == NETIF_TX_RING_SIZE) ) - { - netif_put(netif); - continue; - } - - rmb(); /* Ensure that we see the request before we copy it. */ - memcpy(&txreq, &netif->tx->ring[MASK_NETIF_TX_IDX(i)].req, - sizeof(txreq)); - - /* Credit-based scheduling. */ - if ( txreq.size > netif->remaining_credit ) - { - unsigned long now = jiffies; - unsigned long next_credit = - netif->credit_timeout.expires + - msecs_to_jiffies(netif->credit_usec / 1000); - - /* Timer could already be pending in some rare cases. */ - if ( timer_pending(&netif->credit_timeout) ) - break; - - /* Already passed the point at which we can replenish credit? */ - if ( time_after_eq(now, next_credit) ) - { - netif->credit_timeout.expires = now; - netif->remaining_credit = netif->credit_bytes; - } - - /* Still too big to send right now? Then set a timer callback. */ - if ( txreq.size > netif->remaining_credit ) - { - netif->remaining_credit = 0; - netif->credit_timeout.expires = next_credit; - netif->credit_timeout.data = (unsigned long)netif; - netif->credit_timeout.function = tx_credit_callback; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) - add_timer_on(&netif->credit_timeout, smp_processor_id()); -#else - add_timer(&netif->credit_timeout); -#endif - break; - } - } - netif->remaining_credit -= txreq.size; - - /* - * Why the barrier? It ensures that the frontend sees updated req_cons - * before we check for more work to schedule. - */ - netif->tx->req_cons = ++netif->tx_req_cons; - mb(); - - netif_schedule_work(netif); - - if ( unlikely(txreq.size < ETH_HLEN) || - unlikely(txreq.size > ETH_FRAME_LEN) ) - { - DPRINTK("Bad packet size: %d\n", txreq.size); - make_tx_response(netif, txreq.id, NETIF_RSP_ERROR); - netif_put(netif); - continue; - } - - /* No crossing a page boundary as the payload mustn't fragment. */ - if ( unlikely(((txreq.addr & ~PAGE_MASK) + txreq.size) >= PAGE_SIZE) ) - { - DPRINTK("txreq.addr: %lx, size: %u, end: %lu\n", - txreq.addr, txreq.size, - (txreq.addr &~PAGE_MASK) + txreq.size); - make_tx_response(netif, txreq.id, NETIF_RSP_ERROR); - netif_put(netif); - continue; - } - - pending_idx = pending_ring[MASK_PEND_IDX(pending_cons)]; - - data_len = (txreq.size > PKT_PROT_LEN) ? PKT_PROT_LEN : txreq.size; - - if ( unlikely((skb = alloc_skb(data_len+16, GFP_ATOMIC)) == NULL) ) - { - DPRINTK("Can't allocate a skb in start_xmit.\n"); - make_tx_response(netif, txreq.id, NETIF_RSP_ERROR); - netif_put(netif); - break; - } - - /* Packets passed to netif_rx() must have some headroom. */ - skb_reserve(skb, 16); - - mcl[0].op = __HYPERVISOR_update_va_mapping_otherdomain; - mcl[0].args[0] = MMAP_VADDR(pending_idx); - mcl[0].args[1] = (txreq.addr & PAGE_MASK) | __PAGE_KERNEL; - mcl[0].args[2] = 0; - mcl[0].args[3] = netif->domid; - mcl++; - - memcpy(&pending_tx_info[pending_idx].req, &txreq, sizeof(txreq)); - pending_tx_info[pending_idx].netif = netif; - *((u16 *)skb->data) = pending_idx; - - __skb_queue_tail(&tx_queue, skb); - - pending_cons++; - - /* Filled the batch queue? */ - if ( (mcl - tx_mcl) == ARRAY_SIZE(tx_mcl) ) - break; - } - - if ( mcl == tx_mcl ) - return; - - if ( unlikely(HYPERVISOR_multicall(tx_mcl, mcl - tx_mcl) != 0) ) - BUG(); - - mcl = tx_mcl; - while ( (skb = __skb_dequeue(&tx_queue)) != NULL ) - { - pending_idx = *((u16 *)skb->data); - netif = pending_tx_info[pending_idx].netif; - memcpy(&txreq, &pending_tx_info[pending_idx].req, sizeof(txreq)); - - /* Check the remap error code. */ - if ( unlikely(mcl[0].args[5] != 0) ) - { - DPRINTK("Bad page frame\n"); - make_tx_response(netif, txreq.id, NETIF_RSP_ERROR); - netif_put(netif); - kfree_skb(skb); - mcl++; - pending_ring[MASK_PEND_IDX(pending_prod++)] = pending_idx; - continue; - } - - phys_to_machine_mapping[__pa(MMAP_VADDR(pending_idx)) >> PAGE_SHIFT] = - FOREIGN_FRAME(txreq.addr >> PAGE_SHIFT); - - data_len = (txreq.size > PKT_PROT_LEN) ? PKT_PROT_LEN : txreq.size; - - __skb_put(skb, data_len); - memcpy(skb->data, - (void *)(MMAP_VADDR(pending_idx)|(txreq.addr&~PAGE_MASK)), - data_len); - - if ( data_len < txreq.size ) - { - /* Append the packet payload as a fragment. */ - skb_shinfo(skb)->frags[0].page = - virt_to_page(MMAP_VADDR(pending_idx)); - skb_shinfo(skb)->frags[0].size = txreq.size - data_len; - skb_shinfo(skb)->frags[0].page_offset = - (txreq.addr + data_len) & ~PAGE_MASK; - skb_shinfo(skb)->nr_frags = 1; - } - else - { - /* Schedule a response immediately. */ - netif_idx_release(pending_idx); - } - - skb->data_len = txreq.size - data_len; - skb->len += skb->data_len; - - skb->dev = netif->dev; - skb->protocol = eth_type_trans(skb, skb->dev); - - netif->stats.rx_bytes += txreq.size; - netif->stats.rx_packets++; - - netif_rx(skb); - netif->dev->last_rx = jiffies; - - mcl++; - } + gnttab_unmap_grant_ref_t *gop; + u16 pending_idx; + PEND_RING_IDX dc, dp; + netif_t *netif; + int ret; + + dc = dealloc_cons; + dp = dealloc_prod; + + /* Ensure we see all indexes enqueued by netif_idx_release(). */ + smp_rmb(); + + /* + * Free up any grants we have finished using + */ + gop = tx_unmap_ops; + while (dc != dp) { + pending_idx = dealloc_ring[MASK_PEND_IDX(dc++)]; + gnttab_set_unmap_op(gop, MMAP_VADDR(pending_idx), + GNTMAP_host_map, + grant_tx_handle[pending_idx]); + gop++; + } + ret = HYPERVISOR_grant_table_op( + GNTTABOP_unmap_grant_ref, tx_unmap_ops, gop - tx_unmap_ops); + BUG_ON(ret); + + while (dealloc_cons != dp) { + pending_idx = dealloc_ring[MASK_PEND_IDX(dealloc_cons++)]; + + netif = pending_tx_info[pending_idx].netif; + + make_tx_response(netif, &pending_tx_info[pending_idx].req, + NETIF_RSP_OKAY); + + pending_ring[MASK_PEND_IDX(pending_prod++)] = pending_idx; + + netif_put(netif); + } } -static void netif_idx_release(u16 pending_idx) +static void netbk_tx_err(netif_t *netif, netif_tx_request_t *txp, RING_IDX end) { - static spinlock_t _lock = SPIN_LOCK_UNLOCKED; - unsigned long flags; - - spin_lock_irqsave(&_lock, flags); - dealloc_ring[MASK_PEND_IDX(dealloc_prod++)] = pending_idx; - spin_unlock_irqrestore(&_lock, flags); - - tasklet_schedule(&net_tx_tasklet); + RING_IDX cons = netif->tx.req_cons; + + do { + make_tx_response(netif, txp, NETIF_RSP_ERROR); + if (cons >= end) + break; + txp = RING_GET_REQUEST(&netif->tx, cons++); + } while (1); + netif->tx.req_cons = cons; + netif_schedule_work(netif); + netif_put(netif); } -static void netif_page_release(struct page *page) +static int netbk_count_requests(netif_t *netif, netif_tx_request_t *txp, + int work_to_do) { - u16 pending_idx = page - virt_to_page(mmap_vstart); - - /* Ready for next use. */ - set_page_count(page, 1); - - netif_idx_release(pending_idx); + netif_tx_request_t *first = txp; + RING_IDX cons = netif->tx.req_cons; + int frags = 0; + + while (txp->flags & NETTXF_more_data) { + if (frags >= work_to_do) { + DPRINTK("Need more frags\n"); + return -frags; + } + + txp = RING_GET_REQUEST(&netif->tx, cons + frags); + if (txp->size > first->size) { + DPRINTK("Frags galore\n"); + return -frags; + } + + first->size -= txp->size; + frags++; + + if (unlikely((txp->offset + txp->size) > PAGE_SIZE)) { + DPRINTK("txp->offset: %x, size: %u\n", + txp->offset, txp->size); + return -frags; + } + } + + return frags; } -irqreturn_t netif_be_int(int irq, void *dev_id, struct pt_regs *regs) +static gnttab_map_grant_ref_t *netbk_get_requests(netif_t *netif, + struct sk_buff *skb, + gnttab_map_grant_ref_t *mop) { - netif_t *netif = dev_id; - if ( tx_work_exists(netif) ) - { - add_to_net_schedule_list_tail(netif); - maybe_schedule_tx_action(); - } - return IRQ_HANDLED; + struct skb_shared_info *shinfo = skb_shinfo(skb); + skb_frag_t *frags = shinfo->frags; + netif_tx_request_t *txp; + unsigned long pending_idx = *((u16 *)skb->data); + RING_IDX cons = netif->tx.req_cons; + int i, start; + + /* Skip first skb fragment if it is on same page as header fragment. */ + start = ((unsigned long)shinfo->frags[0].page == pending_idx); + + for (i = start; i < shinfo->nr_frags; i++) { + txp = RING_GET_REQUEST(&netif->tx, cons++); + pending_idx = pending_ring[MASK_PEND_IDX(pending_cons++)]; + + gnttab_set_map_op(mop++, MMAP_VADDR(pending_idx), + GNTMAP_host_map | GNTMAP_readonly, + txp->gref, netif->domid); + + memcpy(&pending_tx_info[pending_idx].req, txp, sizeof(*txp)); + netif_get(netif); + pending_tx_info[pending_idx].netif = netif; + frags[i].page = (void *)pending_idx; + } + + return mop; } -static void make_tx_response(netif_t *netif, - u16 id, - s8 st) +static int netbk_tx_check_mop(struct sk_buff *skb, + gnttab_map_grant_ref_t **mopp) { - NETIF_RING_IDX i = netif->tx_resp_prod; - netif_tx_response_t *resp; + gnttab_map_grant_ref_t *mop = *mopp; + int pending_idx = *((u16 *)skb->data); + netif_t *netif = pending_tx_info[pending_idx].netif; + netif_tx_request_t *txp; + struct skb_shared_info *shinfo = skb_shinfo(skb); + int nr_frags = shinfo->nr_frags; + int i, err, start; + + /* Check status of header. */ + err = mop->status; + if (unlikely(err)) { + txp = &pending_tx_info[pending_idx].req; + make_tx_response(netif, txp, NETIF_RSP_ERROR); + pending_ring[MASK_PEND_IDX(pending_prod++)] = pending_idx; + netif_put(netif); + } else { + set_phys_to_machine( + __pa(MMAP_VADDR(pending_idx)) >> PAGE_SHIFT, + FOREIGN_FRAME(mop->dev_bus_addr >> PAGE_SHIFT)); + grant_tx_handle[pending_idx] = mop->handle; + } + + /* Skip first skb fragment if it is on same page as header fragment. */ + start = ((unsigned long)shinfo->frags[0].page == pending_idx); + + for (i = start; i < nr_frags; i++) { + int j, newerr; + + pending_idx = (unsigned long)shinfo->frags[i].page; + + /* Check error status: if okay then remember grant handle. */ + newerr = (++mop)->status; + if (likely(!newerr)) { + set_phys_to_machine( + __pa(MMAP_VADDR(pending_idx))>>PAGE_SHIFT, + FOREIGN_FRAME(mop->dev_bus_addr>>PAGE_SHIFT)); + grant_tx_handle[pending_idx] = mop->handle; + /* Had a previous error? Invalidate this fragment. */ + if (unlikely(err)) + netif_idx_release(pending_idx); + continue; + } + + /* Error on this fragment: respond to client with an error. */ + txp = &pending_tx_info[pending_idx].req; + make_tx_response(netif, txp, NETIF_RSP_ERROR); + pending_ring[MASK_PEND_IDX(pending_prod++)] = pending_idx; + netif_put(netif); + + /* Not the first error? Preceding frags already invalidated. */ + if (err) + continue; + + /* First error: invalidate header and preceding fragments. */ + pending_idx = *((u16 *)skb->data); + netif_idx_release(pending_idx); + for (j = start; j < i; j++) { + pending_idx = (unsigned long)shinfo->frags[i].page; + netif_idx_release(pending_idx); + } + + /* Remember the error: invalidate all subsequent fragments. */ + err = newerr; + } + + *mopp = mop + 1; + return err; +} - resp = &netif->tx->ring[MASK_NETIF_TX_IDX(i)].resp; - resp->id = id; - resp->status = st; - wmb(); - netif->tx->resp_prod = netif->tx_resp_prod = ++i; +static void netbk_fill_frags(struct sk_buff *skb) +{ + struct skb_shared_info *shinfo = skb_shinfo(skb); + int nr_frags = shinfo->nr_frags; + int i; + + for (i = 0; i < nr_frags; i++) { + skb_frag_t *frag = shinfo->frags + i; + netif_tx_request_t *txp; + unsigned long pending_idx; + + pending_idx = (unsigned long)frag->page; + txp = &pending_tx_info[pending_idx].req; + frag->page = virt_to_page(MMAP_VADDR(pending_idx)); + frag->size = txp->size; + frag->page_offset = txp->offset; + + skb->len += txp->size; + skb->data_len += txp->size; + skb->truesize += txp->size; + } +} - mb(); /* Update producer before checking event threshold. */ - if ( i == netif->tx->event ) - notify_via_evtchn(netif->evtchn); +int netbk_get_extras(netif_t *netif, struct netif_extra_info *extras, + int work_to_do) +{ + struct netif_extra_info *extra; + RING_IDX cons = netif->tx.req_cons; + + do { + if (unlikely(work_to_do-- <= 0)) { + DPRINTK("Missing extra info\n"); + return -EBADR; + } + + extra = (struct netif_extra_info *) + RING_GET_REQUEST(&netif->tx, cons); + if (unlikely(!extra->type || + extra->type >= XEN_NETIF_EXTRA_TYPE_MAX)) { + netif->tx.req_cons = ++cons; + DPRINTK("Invalid extra type: %d\n", extra->type); + return -EINVAL; + } + + memcpy(&extras[extra->type - 1], extra, sizeof(*extra)); + netif->tx.req_cons = ++cons; + } while (extra->flags & XEN_NETIF_EXTRA_FLAG_MORE); + + return work_to_do; } -static int make_rx_response(netif_t *netif, - u16 id, - s8 st, - memory_t addr, - u16 size) +static int netbk_set_skb_gso(struct sk_buff *skb, struct netif_extra_info *gso) { - NETIF_RING_IDX i = netif->rx_resp_prod; - netif_rx_response_t *resp; + if (!gso->u.gso.size) { + DPRINTK("GSO size must not be zero.\n"); + return -EINVAL; + } + + /* Currently only TCPv4 S.O. is supported. */ + if (gso->u.gso.type != XEN_NETIF_GSO_TYPE_TCPV4) { + DPRINTK("Bad GSO type %d.\n", gso->u.gso.type); + return -EINVAL; + } + + skb_shinfo(skb)->gso_size = gso->u.gso.size; + skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4; - resp = &netif->rx->ring[MASK_NETIF_RX_IDX(i)].resp; - resp->addr = addr; - resp->id = id; - resp->status = (s16)size; - if ( st < 0 ) - resp->status = (s16)st; - wmb(); - netif->rx->resp_prod = netif->rx_resp_prod = ++i; + /* Header must be checked, and gso_segs computed. */ + skb_shinfo(skb)->gso_type |= SKB_GSO_DODGY; + skb_shinfo(skb)->gso_segs = 0; - mb(); /* Update producer before checking event threshold. */ - return (i == netif->rx->event); + return 0; } -static irqreturn_t netif_be_dbg(int irq, void *dev_id, struct pt_regs *regs) +/* Called after netfront has transmitted */ +static void net_tx_action(unsigned long unused) { - struct list_head *ent; - netif_t *netif; - int i = 0; - - printk(KERN_ALERT "netif_schedule_list:\n"); - spin_lock_irq(&net_schedule_list_lock); + struct list_head *ent; + struct sk_buff *skb; + netif_t *netif; + netif_tx_request_t txreq; + struct netif_extra_info extras[XEN_NETIF_EXTRA_TYPE_MAX - 1]; + u16 pending_idx; + RING_IDX i; + gnttab_map_grant_ref_t *mop; + unsigned int data_len; + int ret, work_to_do; + + if (dealloc_cons != dealloc_prod) + net_tx_action_dealloc(); + + mop = tx_map_ops; + while (((NR_PENDING_REQS + MAX_SKB_FRAGS) < MAX_PENDING_REQS) && + !list_empty(&net_schedule_list)) { + /* Get a netif from the list with work to do. */ + ent = net_schedule_list.next; + netif = list_entry(ent, netif_t, list); + netif_get(netif); + remove_from_net_schedule_list(netif); + + RING_FINAL_CHECK_FOR_REQUESTS(&netif->tx, work_to_do); + if (!work_to_do) { + netif_put(netif); + continue; + } + + i = netif->tx.req_cons; + rmb(); /* Ensure that we see the request before we copy it. */ + memcpy(&txreq, RING_GET_REQUEST(&netif->tx, i), sizeof(txreq)); + /* Credit-based scheduling. */ + if (txreq.size > netif->remaining_credit) { + unsigned long now = jiffies; + unsigned long next_credit = + netif->credit_timeout.expires + + msecs_to_jiffies(netif->credit_usec / 1000); + + /* Timer could already be pending in rare cases. */ + if (timer_pending(&netif->credit_timeout)) + break; + + /* Passed the point where we can replenish credit? */ + if (time_after_eq(now, next_credit)) { + netif->credit_timeout.expires = now; + netif->remaining_credit = netif->credit_bytes; + } + + /* Still too big to send right now? Set a callback. */ + if (txreq.size > netif->remaining_credit) { + netif->remaining_credit = 0; + netif->credit_timeout.data = + (unsigned long)netif; + netif->credit_timeout.function = + tx_credit_callback; + __mod_timer(&netif->credit_timeout, + next_credit); + break; + } + } + netif->remaining_credit -= txreq.size; + + work_to_do--; + netif->tx.req_cons = ++i; + + memset(extras, 0, sizeof(extras)); + if (txreq.flags & NETTXF_extra_info) { + work_to_do = netbk_get_extras(netif, extras, + work_to_do); + i = netif->tx.req_cons; + if (unlikely(work_to_do < 0)) { + netbk_tx_err(netif, &txreq, i); + continue; + } + } + + ret = netbk_count_requests(netif, &txreq, work_to_do); + if (unlikely(ret < 0)) { + netbk_tx_err(netif, &txreq, i - ret); + continue; + } + i += ret; + + if (unlikely(ret > MAX_SKB_FRAGS)) { + DPRINTK("Too many frags\n"); + netbk_tx_err(netif, &txreq, i); + continue; + } + + if (unlikely(txreq.size < ETH_HLEN)) { + DPRINTK("Bad packet size: %d\n", txreq.size); + netbk_tx_err(netif, &txreq, i); + continue; + } + + /* No crossing a page as the payload mustn't fragment. */ + if (unlikely((txreq.offset + txreq.size) > PAGE_SIZE)) { + DPRINTK("txreq.offset: %x, size: %u, end: %lu\n", + txreq.offset, txreq.size, + (txreq.offset &~PAGE_MASK) + txreq.size); + netbk_tx_err(netif, &txreq, i); + continue; + } + + pending_idx = pending_ring[MASK_PEND_IDX(pending_cons)]; + + data_len = (txreq.size > PKT_PROT_LEN && + ret < MAX_SKB_FRAGS) ? + PKT_PROT_LEN : txreq.size; + + skb = alloc_skb(data_len+16, GFP_ATOMIC); + if (unlikely(skb == NULL)) { + DPRINTK("Can't allocate a skb in start_xmit.\n"); + netbk_tx_err(netif, &txreq, i); + break; + } + + /* Packets passed to netif_rx() must have some headroom. */ + skb_reserve(skb, 16); + + if (extras[XEN_NETIF_EXTRA_TYPE_GSO - 1].type) { + struct netif_extra_info *gso; + gso = &extras[XEN_NETIF_EXTRA_TYPE_GSO - 1]; + + if (netbk_set_skb_gso(skb, gso)) { + kfree_skb(skb); + netbk_tx_err(netif, &txreq, i); + continue; + } + } + + gnttab_set_map_op(mop, MMAP_VADDR(pending_idx), + GNTMAP_host_map | GNTMAP_readonly, + txreq.gref, netif->domid); + mop++; + + memcpy(&pending_tx_info[pending_idx].req, + &txreq, sizeof(txreq)); + pending_tx_info[pending_idx].netif = netif; + *((u16 *)skb->data) = pending_idx; + + __skb_put(skb, data_len); + + skb_shinfo(skb)->nr_frags = ret; + if (data_len < txreq.size) { + skb_shinfo(skb)->nr_frags++; + skb_shinfo(skb)->frags[0].page = + (void *)(unsigned long)pending_idx; + } + + __skb_queue_tail(&tx_queue, skb); + + pending_cons++; + + mop = netbk_get_requests(netif, skb, mop); + + netif->tx.req_cons = i; + netif_schedule_work(netif); + + if ((mop - tx_map_ops) >= ARRAY_SIZE(tx_map_ops)) + break; + } + + if (mop == tx_map_ops) + return; + + ret = HYPERVISOR_grant_table_op( + GNTTABOP_map_grant_ref, tx_map_ops, mop - tx_map_ops); + BUG_ON(ret); + + mop = tx_map_ops; + while ((skb = __skb_dequeue(&tx_queue)) != NULL) { + netif_tx_request_t *txp; + + pending_idx = *((u16 *)skb->data); + netif = pending_tx_info[pending_idx].netif; + txp = &pending_tx_info[pending_idx].req; + + /* Check the remap error code. */ + if (unlikely(netbk_tx_check_mop(skb, &mop))) { + printk(KERN_ALERT "#### netback grant fails\n"); + skb_shinfo(skb)->nr_frags = 0; + kfree_skb(skb); + continue; + } + + data_len = skb->len; + memcpy(skb->data, + (void *)(MMAP_VADDR(pending_idx)|txp->offset), + data_len); + if (data_len < txp->size) { + /* Append the packet payload as a fragment. */ + txp->offset += data_len; + txp->size -= data_len; + } else { + /* Schedule a response immediately. */ + netif_idx_release(pending_idx); + } + + /* + * Old frontends do not assert data_validated but we + * can infer it from csum_blank so test both flags. + */ + if (txp->flags & (NETTXF_data_validated|NETTXF_csum_blank)) { + skb->ip_summed = CHECKSUM_UNNECESSARY; + skb->proto_data_valid = 1; + } else { + skb->ip_summed = CHECKSUM_NONE; + skb->proto_data_valid = 0; + } + skb->proto_csum_blank = !!(txp->flags & NETTXF_csum_blank); + + netbk_fill_frags(skb); + + skb->dev = netif->dev; + skb->protocol = eth_type_trans(skb, skb->dev); + + netif->stats.rx_bytes += skb->len; + netif->stats.rx_packets++; + + netif_rx(skb); + netif->dev->last_rx = jiffies; + } +} - list_for_each ( ent, &net_schedule_list ) - { - netif = list_entry(ent, netif_t, list); - printk(KERN_ALERT " %d: private(rx_req_cons=%08x rx_resp_prod=%08x\n", - i, netif->rx_req_cons, netif->rx_resp_prod); - printk(KERN_ALERT " tx_req_cons=%08x tx_resp_prod=%08x)\n", - netif->tx_req_cons, netif->tx_resp_prod); - printk(KERN_ALERT " shared(rx_req_prod=%08x rx_resp_prod=%08x\n", - netif->rx->req_prod, netif->rx->resp_prod); - printk(KERN_ALERT " rx_event=%08x tx_req_prod=%08x\n", - netif->rx->event, netif->tx->req_prod); - printk(KERN_ALERT " tx_resp_prod=%08x, tx_event=%08x)\n", - netif->tx->resp_prod, netif->tx->event); - i++; - } +static void netif_idx_release(u16 pending_idx) +{ + static DEFINE_SPINLOCK(_lock); + unsigned long flags; - spin_unlock_irq(&net_schedule_list_lock); - printk(KERN_ALERT " ** End of netif_schedule_list **\n"); + spin_lock_irqsave(&_lock, flags); + dealloc_ring[MASK_PEND_IDX(dealloc_prod)] = pending_idx; + /* Sync with net_tx_action_dealloc: insert idx /then/ incr producer. */ + smp_wmb(); + dealloc_prod++; + spin_unlock_irqrestore(&_lock, flags); - return IRQ_HANDLED; + tasklet_schedule(&net_tx_tasklet); } -static int __init netback_init(void) +static void netif_page_release(struct page *page) { - int i; - struct page *page; + u16 pending_idx = page - virt_to_page(mmap_vstart); - if ( !(xen_start_info.flags & SIF_NET_BE_DOMAIN) && - !(xen_start_info.flags & SIF_INITDOMAIN) ) - return 0; + /* Ready for next use. */ + init_page_count(page); - printk("Initialising Xen netif backend\n"); + netif_idx_release(pending_idx); +} - /* We can increase reservation by this much in net_rx_action(). */ - balloon_update_driver_allowance(NETIF_RX_RING_SIZE); +irqreturn_t netif_be_int(int irq, void *dev_id, struct pt_regs *regs) +{ + netif_t *netif = dev_id; - skb_queue_head_init(&rx_queue); - skb_queue_head_init(&tx_queue); + add_to_net_schedule_list_tail(netif); + maybe_schedule_tx_action(); - init_timer(&net_timer); - net_timer.data = 0; - net_timer.function = net_alarm; - - netif_interface_init(); + if (netif_queue_stopped(netif->dev) && !netbk_queue_full(netif)) + netif_wake_queue(netif->dev); - if ( (mmap_vstart = allocate_empty_lowmem_region(MAX_PENDING_REQS)) == 0 ) - BUG(); + return IRQ_HANDLED; +} - for ( i = 0; i < MAX_PENDING_REQS; i++ ) - { - page = virt_to_page(MMAP_VADDR(i)); - set_page_count(page, 1); - SetPageForeign(page, netif_page_release); - } +static void make_tx_response(netif_t *netif, + netif_tx_request_t *txp, + s8 st) +{ + RING_IDX i = netif->tx.rsp_prod_pvt; + netif_tx_response_t *resp; + int notify; + + resp = RING_GET_RESPONSE(&netif->tx, i); + resp->id = txp->id; + resp->status = st; + + if (txp->flags & NETTXF_extra_info) + RING_GET_RESPONSE(&netif->tx, ++i)->status = NETIF_RSP_NULL; + + netif->tx.rsp_prod_pvt = ++i; + RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&netif->tx, notify); + if (notify) + notify_remote_via_irq(netif->irq); + +#ifdef CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER + if (i == netif->tx.req_cons) { + int more_to_do; + RING_FINAL_CHECK_FOR_REQUESTS(&netif->tx, more_to_do); + if (more_to_do) + add_to_net_schedule_list_tail(netif); + } +#endif +} - pending_cons = 0; - pending_prod = MAX_PENDING_REQS; - for ( i = 0; i < MAX_PENDING_REQS; i++ ) - pending_ring[i] = i; +static netif_rx_response_t *make_rx_response(netif_t *netif, + u16 id, + s8 st, + u16 offset, + u16 size, + u16 flags) +{ + RING_IDX i = netif->rx.rsp_prod_pvt; + netif_rx_response_t *resp; - spin_lock_init(&net_schedule_list_lock); - INIT_LIST_HEAD(&net_schedule_list); + resp = RING_GET_RESPONSE(&netif->rx, i); + resp->offset = offset; + resp->flags = flags; + resp->id = id; + resp->status = (s16)size; + if (st < 0) + resp->status = (s16)st; - netif_ctrlif_init(); + netif->rx.rsp_prod_pvt = ++i; - (void)request_irq(bind_virq_to_irq(VIRQ_DEBUG), - netif_be_dbg, SA_SHIRQ, - "net-be-dbg", &netif_be_dbg); + return resp; +} - return 0; +#ifdef NETBE_DEBUG_INTERRUPT +static irqreturn_t netif_be_dbg(int irq, void *dev_id, struct pt_regs *regs) +{ + struct list_head *ent; + netif_t *netif; + int i = 0; + + printk(KERN_ALERT "netif_schedule_list:\n"); + spin_lock_irq(&net_schedule_list_lock); + + list_for_each (ent, &net_schedule_list) { + netif = list_entry(ent, netif_t, list); + printk(KERN_ALERT " %d: private(rx_req_cons=%08x " + "rx_resp_prod=%08x\n", + i, netif->rx.req_cons, netif->rx.rsp_prod_pvt); + printk(KERN_ALERT " tx_req_cons=%08x tx_resp_prod=%08x)\n", + netif->tx.req_cons, netif->tx.rsp_prod_pvt); + printk(KERN_ALERT " shared(rx_req_prod=%08x " + "rx_resp_prod=%08x\n", + netif->rx.sring->req_prod, netif->rx.sring->rsp_prod); + printk(KERN_ALERT " rx_event=%08x tx_req_prod=%08x\n", + netif->rx.sring->rsp_event, netif->tx.sring->req_prod); + printk(KERN_ALERT " tx_resp_prod=%08x, tx_event=%08x)\n", + netif->tx.sring->rsp_prod, netif->tx.sring->rsp_event); + i++; + } + + spin_unlock_irq(&net_schedule_list_lock); + printk(KERN_ALERT " ** End of netif_schedule_list **\n"); + + return IRQ_HANDLED; } +#endif -static void netback_cleanup(void) +static int __init netback_init(void) { - BUG(); + int i; + struct page *page; + + if (!is_running_on_xen()) + return -ENODEV; + + /* We can increase reservation by this much in net_rx_action(). */ + balloon_update_driver_allowance(NET_RX_RING_SIZE); + + skb_queue_head_init(&rx_queue); + skb_queue_head_init(&tx_queue); + + init_timer(&net_timer); + net_timer.data = 0; + net_timer.function = net_alarm; + + page = balloon_alloc_empty_page_range(MAX_PENDING_REQS); + if (page == NULL) + return -ENOMEM; + + mmap_vstart = (unsigned long)pfn_to_kaddr(page_to_pfn(page)); + + for (i = 0; i < MAX_PENDING_REQS; i++) { + page = virt_to_page(MMAP_VADDR(i)); + init_page_count(page); + SetPageForeign(page, netif_page_release); + } + + pending_cons = 0; + pending_prod = MAX_PENDING_REQS; + for (i = 0; i < MAX_PENDING_REQS; i++) + pending_ring[i] = i; + + spin_lock_init(&net_schedule_list_lock); + INIT_LIST_HEAD(&net_schedule_list); + + netif_xenbus_init(); + +#ifdef NETBE_DEBUG_INTERRUPT + (void)bind_virq_to_irqhandler( + VIRQ_DEBUG, + 0, + netif_be_dbg, + SA_SHIRQ, + "net-be-dbg", + &netif_be_dbg); +#endif + + return 0; } module_init(netback_init); -module_exit(netback_cleanup); + +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/xen/netfront/Makefile b/drivers/xen/netfront/Makefile index 7eb07a248..dc22829f5 100644 --- a/drivers/xen/netfront/Makefile +++ b/drivers/xen/netfront/Makefile @@ -1,2 +1,4 @@ -obj-y := netfront.o +obj-$(CONFIG_XEN_NETDEV_FRONTEND) := xennet.o + +xennet-objs := netfront.o diff --git a/drivers/xen/netfront/netfront.c b/drivers/xen/netfront/netfront.c index f72929502..ef6e134a7 100644 --- a/drivers/xen/netfront/netfront.c +++ b/drivers/xen/netfront/netfront.c @@ -1,21 +1,25 @@ /****************************************************************************** * Virtual network driver for conversing with remote driver backends. - * - * Copyright (c) 2002-2004, K A Fraser - * - * This file may be distributed separately from the Linux kernel, or - * incorporated into other software packages, subject to the following license: - * + * + * Copyright (c) 2002-2005, K A Fraser + * Copyright (c) 2005, XenSource Ltd + * + * 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; or, when distributed + * separately from the Linux kernel or incorporated into other + * software packages, subject to the following license: + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this source file (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, copy, modify, * merge, publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, subject to * the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -39,214 +43,422 @@ #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 -#ifndef __GFP_NOWARN -#define __GFP_NOWARN 0 -#endif -#define alloc_xen_skb(_l) __dev_alloc_skb((_l), GFP_ATOMIC|__GFP_NOWARN) +#define RX_COPY_THRESHOLD 256 -#define init_skb_shinfo(_skb) \ - do { \ - atomic_set(&(skb_shinfo(_skb)->dataref), 1); \ - skb_shinfo(_skb)->nr_frags = 0; \ - skb_shinfo(_skb)->frag_list = NULL; \ - } while (0) +#define GRANT_INVALID_REF 0 -/* Allow headroom on each rx pkt for Ethernet header, alignment padding, ... */ -#define RX_HEADROOM 200 +#define NET_TX_RING_SIZE __RING_SIZE((struct netif_tx_sring *)0, PAGE_SIZE) +#define NET_RX_RING_SIZE __RING_SIZE((struct netif_rx_sring *)0, PAGE_SIZE) -/* - * If the backend driver is pipelining transmit requests then we can be very - * aggressive in avoiding new-packet notifications -- only need to send a - * notification if there are no outstanding unreceived responses. - * If the backend may be buffering our transmit buffers for any reason then we - * are rather more conservative. - */ -#ifdef CONFIG_XEN_NETDEV_FRONTEND_PIPELINED_TRANSMITTER -#define TX_TEST_IDX resp_prod /* aggressive: any outstanding responses? */ -#else -#define TX_TEST_IDX req_cons /* conservative: not seen all our requests? */ -#endif +struct netfront_info { + struct list_head list; + struct net_device *netdev; -static void network_tx_buf_gc(struct net_device *dev); -static void network_alloc_rx_buffers(struct net_device *dev); + struct net_device_stats stats; -static unsigned long rx_pfn_array[NETIF_RX_RING_SIZE]; -static multicall_entry_t rx_mcl[NETIF_RX_RING_SIZE+1]; -static mmu_update_t rx_mmu[NETIF_RX_RING_SIZE]; + struct netif_tx_front_ring tx; + struct netif_rx_front_ring rx; -static struct list_head dev_list; + spinlock_t tx_lock; + spinlock_t rx_lock; -struct net_private -{ - struct list_head list; - struct net_device *dev; - - struct net_device_stats stats; - NETIF_RING_IDX rx_resp_cons, tx_resp_cons; - unsigned int tx_full; - - netif_tx_interface_t *tx; - netif_rx_interface_t *rx; - - spinlock_t tx_lock; - spinlock_t rx_lock; - - unsigned int handle; - unsigned int evtchn; - unsigned int irq; - - /* What is the status of our connection to the remote backend? */ -#define BEST_CLOSED 0 -#define BEST_DISCONNECTED 1 -#define BEST_CONNECTED 2 - unsigned int backend_state; - - /* Is this interface open or closed (down or up)? */ -#define UST_CLOSED 0 -#define UST_OPEN 1 - unsigned int user_state; - - /* Receive-ring batched refills. */ + unsigned int handle; + unsigned int evtchn, irq; + + /* Receive-ring batched refills. */ #define RX_MIN_TARGET 8 -#define RX_MAX_TARGET NETIF_RX_RING_SIZE - int rx_target; - struct sk_buff_head rx_batch; - - /* - * {tx,rx}_skbs store outstanding skbuffs. The first entry in each - * array is an index into a chain of free entries. - */ - struct sk_buff *tx_skbs[NETIF_TX_RING_SIZE+1]; - struct sk_buff *rx_skbs[NETIF_RX_RING_SIZE+1]; +#define RX_DFL_MIN_TARGET 64 +#define RX_MAX_TARGET min_t(int, NET_RX_RING_SIZE, 256) + unsigned rx_min_target, rx_max_target, rx_target; + struct sk_buff_head rx_batch; + + struct timer_list rx_refill_timer; + + /* + * {tx,rx}_skbs store outstanding skbuffs. The first entry in tx_skbs + * is an index into a chain of free entries. + */ + struct sk_buff *tx_skbs[NET_TX_RING_SIZE+1]; + struct sk_buff *rx_skbs[NET_RX_RING_SIZE]; + +#define TX_MAX_TARGET min_t(int, NET_RX_RING_SIZE, 256) + grant_ref_t gref_tx_head; + grant_ref_t grant_tx_ref[NET_TX_RING_SIZE + 1]; + grant_ref_t gref_rx_head; + grant_ref_t grant_rx_ref[NET_TX_RING_SIZE]; + + struct xenbus_device *xbdev; + int tx_ring_ref; + int rx_ring_ref; + u8 mac[ETH_ALEN]; + + unsigned long rx_pfn_array[NET_RX_RING_SIZE]; + struct multicall_entry rx_mcl[NET_RX_RING_SIZE+1]; + struct mmu_update rx_mmu[NET_RX_RING_SIZE]; }; -/* Access macros for acquiring freeing slots in {tx,rx}_skbs[]. */ -#define ADD_ID_TO_FREELIST(_list, _id) \ - (_list)[(_id)] = (_list)[0]; \ - (_list)[0] = (void *)(unsigned long)(_id); -#define GET_ID_FROM_FREELIST(_list) \ - ({ unsigned long _id = (unsigned long)(_list)[0]; \ - (_list)[0] = (_list)[_id]; \ - (unsigned short)_id; }) - -static char *status_name[] = { - [NETIF_INTERFACE_STATUS_CLOSED] = "closed", - [NETIF_INTERFACE_STATUS_DISCONNECTED] = "disconnected", - [NETIF_INTERFACE_STATUS_CONNECTED] = "connected", - [NETIF_INTERFACE_STATUS_CHANGED] = "changed", +struct netfront_rx_info { + struct netif_rx_response rx; + struct netif_extra_info extras[XEN_NETIF_EXTRA_TYPE_MAX - 1]; }; -static char *be_state_name[] = { - [BEST_CLOSED] = "closed", - [BEST_DISCONNECTED] = "disconnected", - [BEST_CONNECTED] = "connected", -}; +/* + * Access macros for acquiring freeing slots in tx_skbs[]. + */ -#if DEBUG -#define DPRINTK(fmt, args...) \ - printk(KERN_ALERT "xen_net (%s:%d) " fmt, __FUNCTION__, __LINE__, ##args) -#else -#define DPRINTK(fmt, args...) ((void)0) -#endif -#define IPRINTK(fmt, args...) \ - printk(KERN_INFO "xen_net: " fmt, ##args) -#define WPRINTK(fmt, args...) \ - printk(KERN_WARNING "xen_net: " fmt, ##args) +static inline void add_id_to_freelist(struct sk_buff **list, unsigned short id) +{ + list[id] = list[0]; + list[0] = (void *)(unsigned long)id; +} -static struct net_device *find_dev_by_handle(unsigned int handle) +static inline unsigned short get_id_from_freelist(struct sk_buff **list) { - struct list_head *ent; - struct net_private *np; - list_for_each (ent, &dev_list) { - np = list_entry(ent, struct net_private, list); - if (np->handle == handle) - return np->dev; - } - return NULL; + unsigned int id = (unsigned int)(unsigned long)list[0]; + list[0] = list[id]; + return id; } -/** Network interface info. */ -struct netif_ctrl { - /** Number of interfaces. */ - int interface_n; - /** Number of connected interfaces. */ - int connected_n; - /** Error code. */ - int err; - int up; -}; +static inline int xennet_rxidx(RING_IDX idx) +{ + return idx & (NET_RX_RING_SIZE - 1); +} + +static inline struct sk_buff *xennet_get_rx_skb(struct netfront_info *np, + RING_IDX ri) +{ + int i = xennet_rxidx(ri); + struct sk_buff *skb = np->rx_skbs[i]; + np->rx_skbs[i] = NULL; + return skb; +} + +static inline grant_ref_t xennet_get_rx_ref(struct netfront_info *np, + RING_IDX ri) +{ + int i = xennet_rxidx(ri); + grant_ref_t ref = np->grant_rx_ref[i]; + np->grant_rx_ref[i] = GRANT_INVALID_REF; + return ref; +} -static struct netif_ctrl netctrl; +#define DPRINTK(fmt, args...) \ + pr_debug("netfront (%s:%d) " fmt, \ + __FUNCTION__, __LINE__, ##args) +#define IPRINTK(fmt, args...) \ + printk(KERN_INFO "netfront: " fmt, ##args) +#define WPRINTK(fmt, args...) \ + printk(KERN_WARNING "netfront: " fmt, ##args) + +static int talk_to_backend(struct xenbus_device *, struct netfront_info *); +static int setup_device(struct xenbus_device *, struct netfront_info *); +static struct net_device *create_netdev(int, struct xenbus_device *); + +static void netfront_closing(struct xenbus_device *); + +static void end_access(int, void *); +static void netif_disconnect_backend(struct netfront_info *); +static void close_netdev(struct netfront_info *); +static void netif_free(struct netfront_info *); + +static void network_connect(struct net_device *); +static void network_tx_buf_gc(struct net_device *); +static void network_alloc_rx_buffers(struct net_device *); +static int send_fake_arp(struct net_device *); + +static irqreturn_t netif_int(int irq, void *dev_id, struct pt_regs *ptregs); + +#ifdef CONFIG_SYSFS +static int xennet_sysfs_addif(struct net_device *netdev); +static void xennet_sysfs_delif(struct net_device *netdev); +#else /* !CONFIG_SYSFS */ +#define xennet_sysfs_addif(dev) (0) +#define xennet_sysfs_delif(dev) do { } while(0) +#endif -static void netctrl_init(void) +static inline int xennet_can_sg(struct net_device *dev) { - memset(&netctrl, 0, sizeof(netctrl)); - netctrl.up = NETIF_DRIVER_STATUS_DOWN; + return dev->features & NETIF_F_SG; } -/** Get or set a network interface error. +/** + * Entry point to this code when a new device is created. Allocate the basic + * structures and the ring buffers for communication with the backend, and + * inform the backend of the appropriate details for those. Switch to + * Connected state. */ -static int netctrl_err(int err) +static int __devinit netfront_probe(struct xenbus_device *dev, + const struct xenbus_device_id *id) { - if ((err < 0) && !netctrl.err) - netctrl.err = err; - return netctrl.err; + int err; + struct net_device *netdev; + struct netfront_info *info; + unsigned int handle; + + err = xenbus_scanf(XBT_NIL, dev->nodename, "handle", "%u", &handle); + if (err != 1) { + xenbus_dev_fatal(dev, err, "reading handle"); + return err; + } + + netdev = create_netdev(handle, dev); + if (IS_ERR(netdev)) { + err = PTR_ERR(netdev); + xenbus_dev_fatal(dev, err, "creating netdev"); + return err; + } + + info = netdev_priv(netdev); + dev->dev.driver_data = info; + + err = talk_to_backend(dev, info); + if (err) { + xennet_sysfs_delif(info->netdev); + unregister_netdev(netdev); + free_netdev(netdev); + dev->dev.driver_data = NULL; + return err; + } + + return 0; } -/** Test if all network interfaces are connected. - * - * @return 1 if all connected, 0 if not, negative error code otherwise + +/** + * We are reconnecting to the backend, due to a suspend/resume, or a backend + * driver restart. We tear down our netif structure and recreate it, but + * leave the device-layer structures intact so that this is transparent to the + * rest of the kernel. */ -static int netctrl_connected(void) +static int netfront_resume(struct xenbus_device *dev) { - int ok; + struct netfront_info *info = dev->dev.driver_data; - if (netctrl.err) - ok = netctrl.err; - else if (netctrl.up == NETIF_DRIVER_STATUS_UP) - ok = (netctrl.connected_n == netctrl.interface_n); - else - ok = 0; + DPRINTK("%s\n", dev->nodename); - return ok; + netif_disconnect_backend(info); + return talk_to_backend(dev, info); } -/** Count the connected network interfaces. - * - * @return connected count +static int xen_net_read_mac(struct xenbus_device *dev, u8 mac[]) +{ + char *s, *e, *macstr; + int i; + + macstr = s = xenbus_read(XBT_NIL, dev->nodename, "mac", NULL); + if (IS_ERR(macstr)) + return PTR_ERR(macstr); + + for (i = 0; i < ETH_ALEN; i++) { + mac[i] = simple_strtoul(s, &e, 16); + if ((s == e) || (*e != ((i == ETH_ALEN-1) ? '\0' : ':'))) { + kfree(macstr); + return -ENOENT; + } + s = e+1; + } + + kfree(macstr); + return 0; +} + +/* Common code used when first setting up, and when resuming. */ +static int talk_to_backend(struct xenbus_device *dev, + struct netfront_info *info) +{ + const char *message; + struct xenbus_transaction xbt; + int err; + + err = xen_net_read_mac(dev, info->mac); + if (err) { + xenbus_dev_fatal(dev, err, "parsing %s/mac", dev->nodename); + goto out; + } + + /* Create shared ring, alloc event channel. */ + err = setup_device(dev, info); + if (err) + goto out; + +again: + err = xenbus_transaction_start(&xbt); + if (err) { + xenbus_dev_fatal(dev, err, "starting transaction"); + goto destroy_ring; + } + + err = xenbus_printf(xbt, dev->nodename, "tx-ring-ref","%u", + info->tx_ring_ref); + if (err) { + message = "writing tx ring-ref"; + goto abort_transaction; + } + err = xenbus_printf(xbt, dev->nodename, "rx-ring-ref","%u", + info->rx_ring_ref); + if (err) { + message = "writing rx ring-ref"; + goto abort_transaction; + } + err = xenbus_printf(xbt, dev->nodename, + "event-channel", "%u", info->evtchn); + if (err) { + message = "writing event-channel"; + goto abort_transaction; + } + + err = xenbus_printf(xbt, dev->nodename, "feature-rx-notify", "%d", 1); + if (err) { + message = "writing feature-rx-notify"; + goto abort_transaction; + } + + err = xenbus_printf(xbt, dev->nodename, "feature-sg", "%d", 1); + if (err) { + message = "writing feature-sg"; + goto abort_transaction; + } + + err = xenbus_printf(xbt, dev->nodename, "feature-gso-tcpv4", "%d", 1); + if (err) { + message = "writing feature-gso-tcpv4"; + goto abort_transaction; + } + + err = xenbus_transaction_end(xbt, 0); + if (err) { + if (err == -EAGAIN) + goto again; + xenbus_dev_fatal(dev, err, "completing transaction"); + goto destroy_ring; + } + + return 0; + + abort_transaction: + xenbus_transaction_end(xbt, 1); + xenbus_dev_fatal(dev, err, "%s", message); + destroy_ring: + netif_free(info); + out: + return err; +} + + +static int setup_device(struct xenbus_device *dev, struct netfront_info *info) +{ + struct netif_tx_sring *txs; + struct netif_rx_sring *rxs; + int err; + struct net_device *netdev = info->netdev; + + info->tx_ring_ref = GRANT_INVALID_REF; + info->rx_ring_ref = GRANT_INVALID_REF; + info->rx.sring = NULL; + info->tx.sring = NULL; + info->irq = 0; + + txs = (struct netif_tx_sring *)get_zeroed_page(GFP_KERNEL); + if (!txs) { + err = -ENOMEM; + xenbus_dev_fatal(dev, err, "allocating tx ring page"); + goto fail; + } + SHARED_RING_INIT(txs); + FRONT_RING_INIT(&info->tx, txs, PAGE_SIZE); + + err = xenbus_grant_ring(dev, virt_to_mfn(txs)); + if (err < 0) { + free_page((unsigned long)txs); + goto fail; + } + info->tx_ring_ref = err; + + rxs = (struct netif_rx_sring *)get_zeroed_page(GFP_KERNEL); + if (!rxs) { + err = -ENOMEM; + xenbus_dev_fatal(dev, err, "allocating rx ring page"); + goto fail; + } + SHARED_RING_INIT(rxs); + FRONT_RING_INIT(&info->rx, rxs, PAGE_SIZE); + + err = xenbus_grant_ring(dev, virt_to_mfn(rxs)); + if (err < 0) { + free_page((unsigned long)rxs); + goto fail; + } + info->rx_ring_ref = err; + + err = xenbus_alloc_evtchn(dev, &info->evtchn); + if (err) + goto fail; + + memcpy(netdev->dev_addr, info->mac, ETH_ALEN); + err = bind_evtchn_to_irqhandler(info->evtchn, netif_int, + SA_SAMPLE_RANDOM, netdev->name, netdev); + if (err < 0) + goto fail; + info->irq = err; + return 0; + + fail: + netif_free(info); + return err; +} + + +/** + * Callback received when the backend's state changes. */ -static int netctrl_connected_count(void) +static void backend_changed(struct xenbus_device *dev, + enum xenbus_state backend_state) { - - struct list_head *ent; - struct net_private *np; - unsigned int connected; - - connected = 0; - - list_for_each(ent, &dev_list) { - np = list_entry(ent, struct net_private, list); - if (np->backend_state == BEST_CONNECTED) - connected++; - } - - netctrl.connected_n = connected; - DPRINTK("> connected_n=%d interface_n=%d\n", - netctrl.connected_n, netctrl.interface_n); - return connected; + struct netfront_info *np = dev->dev.driver_data; + struct net_device *netdev = np->netdev; + + DPRINTK("\n"); + + switch (backend_state) { + case XenbusStateInitialising: + case XenbusStateInitialised: + case XenbusStateConnected: + case XenbusStateUnknown: + case XenbusStateClosed: + break; + + case XenbusStateInitWait: + network_connect(netdev); + xenbus_switch_state(dev, XenbusStateConnected); + (void)send_fake_arp(netdev); + break; + + case XenbusStateClosing: + netfront_closing(dev); + break; + } } + /** Send a packet on a net device to encourage switches to learn the * MAC. We send a fake ARP request. * @@ -255,1046 +467,1375 @@ static int netctrl_connected_count(void) */ static int send_fake_arp(struct net_device *dev) { - struct sk_buff *skb; - u32 src_ip, dst_ip; + struct sk_buff *skb; + u32 src_ip, dst_ip; - dst_ip = INADDR_BROADCAST; - src_ip = inet_select_addr(dev, dst_ip, RT_SCOPE_LINK); + dst_ip = INADDR_BROADCAST; + src_ip = inet_select_addr(dev, dst_ip, RT_SCOPE_LINK); - /* No IP? Then nothing to do. */ - if (src_ip == 0) - return 0; + /* No IP? Then nothing to do. */ + if (src_ip == 0) + return 0; - skb = arp_create(ARPOP_REPLY, ETH_P_ARP, - dst_ip, dev, src_ip, - /*dst_hw*/ NULL, /*src_hw*/ NULL, - /*target_hw*/ dev->dev_addr); - if (skb == NULL) - return -ENOMEM; + skb = arp_create(ARPOP_REPLY, ETH_P_ARP, + dst_ip, dev, src_ip, + /*dst_hw*/ NULL, /*src_hw*/ NULL, + /*target_hw*/ dev->dev_addr); + if (skb == NULL) + return -ENOMEM; - return dev_queue_xmit(skb); + return dev_queue_xmit(skb); } + static int network_open(struct net_device *dev) { - struct net_private *np = netdev_priv(dev); + struct netfront_info *np = netdev_priv(dev); + + memset(&np->stats, 0, sizeof(np->stats)); - memset(&np->stats, 0, sizeof(np->stats)); + network_alloc_rx_buffers(dev); + np->rx.sring->rsp_event = np->rx.rsp_cons + 1; - np->user_state = UST_OPEN; + if (RING_HAS_UNCONSUMED_RESPONSES(&np->rx)) + netif_rx_schedule(dev); - network_alloc_rx_buffers(dev); - np->rx->event = np->rx_resp_cons + 1; + netif_start_queue(dev); - netif_start_queue(dev); + return 0; +} - return 0; +static inline int netfront_tx_slot_available(struct netfront_info *np) +{ + return RING_FREE_REQUESTS(&np->tx) >= MAX_SKB_FRAGS + 2; +} + +static inline void network_maybe_wake_tx(struct net_device *dev) +{ + struct netfront_info *np = netdev_priv(dev); + + if (unlikely(netif_queue_stopped(dev)) && + netfront_tx_slot_available(np) && + likely(netif_running(dev))) + netif_wake_queue(dev); } static void network_tx_buf_gc(struct net_device *dev) { - NETIF_RING_IDX i, prod; - unsigned short id; - struct net_private *np = netdev_priv(dev); - struct sk_buff *skb; - - if (np->backend_state != BEST_CONNECTED) - return; - - do { - prod = np->tx->resp_prod; - rmb(); /* Ensure we see responses up to 'rp'. */ - - for (i = np->tx_resp_cons; i != prod; i++) { - id = np->tx->ring[MASK_NETIF_TX_IDX(i)].resp.id; - skb = np->tx_skbs[id]; - ADD_ID_TO_FREELIST(np->tx_skbs, id); - dev_kfree_skb_irq(skb); - } - - np->tx_resp_cons = prod; - - /* - * Set a new event, then check for race with update of tx_cons. Note - * that it is essential to schedule a callback, no matter how few - * buffers are pending. Even if there is space in the transmit ring, - * higher layers may be blocked because too much data is outstanding: - * in such cases notification from Xen is likely to be the only kick - * that we'll get. - */ - np->tx->event = - prod + ((np->tx->req_prod - prod) >> 1) + 1; - mb(); - } while (prod != np->tx->resp_prod); - - if (np->tx_full && ((np->tx->req_prod - prod) < NETIF_TX_RING_SIZE)) { - np->tx_full = 0; - if (np->user_state == UST_OPEN) - netif_wake_queue(dev); - } + RING_IDX cons, prod; + unsigned short id; + struct netfront_info *np = netdev_priv(dev); + struct sk_buff *skb; + + if (unlikely(!netif_carrier_ok(dev))) + return; + + do { + prod = np->tx.sring->rsp_prod; + rmb(); /* Ensure we see responses up to 'rp'. */ + + for (cons = np->tx.rsp_cons; cons != prod; cons++) { + struct netif_tx_response *txrsp; + + txrsp = RING_GET_RESPONSE(&np->tx, cons); + if (txrsp->status == NETIF_RSP_NULL) + continue; + + id = txrsp->id; + skb = np->tx_skbs[id]; + if (unlikely(gnttab_query_foreign_access( + np->grant_tx_ref[id]) != 0)) { + printk(KERN_ALERT "network_tx_buf_gc: warning " + "-- grant still in use by backend " + "domain.\n"); + BUG(); + } + gnttab_end_foreign_access_ref( + np->grant_tx_ref[id], GNTMAP_readonly); + gnttab_release_grant_reference( + &np->gref_tx_head, np->grant_tx_ref[id]); + np->grant_tx_ref[id] = GRANT_INVALID_REF; + add_id_to_freelist(np->tx_skbs, id); + dev_kfree_skb_irq(skb); + } + + np->tx.rsp_cons = prod; + + /* + * Set a new event, then check for race with update of tx_cons. + * Note that it is essential to schedule a callback, no matter + * how few buffers are pending. Even if there is space in the + * transmit ring, higher layers may be blocked because too much + * data is outstanding: in such cases notification from Xen is + * likely to be the only kick that we'll get. + */ + np->tx.sring->rsp_event = + prod + ((np->tx.sring->req_prod - prod) >> 1) + 1; + mb(); + } while ((cons == prod) && (prod != np->tx.sring->rsp_prod)); + + network_maybe_wake_tx(dev); +} + + +static void rx_refill_timeout(unsigned long data) +{ + struct net_device *dev = (struct net_device *)data; + netif_rx_schedule(dev); } static void network_alloc_rx_buffers(struct net_device *dev) { - unsigned short id; - struct net_private *np = netdev_priv(dev); - struct sk_buff *skb; - int i, batch_target; - NETIF_RING_IDX req_prod = np->rx->req_prod; - - if (unlikely(np->backend_state != BEST_CONNECTED)) - return; - - /* - * Allocate skbuffs greedily, even though we batch updates to the - * receive ring. This creates a less bursty demand on the memory allocator, - * so should reduce the chance of failed allocation requests both for - * ourself and for other kernel subsystems. - */ - batch_target = np->rx_target - (req_prod - np->rx_resp_cons); - for (i = skb_queue_len(&np->rx_batch); i < batch_target; i++) { - if (unlikely((skb = alloc_xen_skb(dev->mtu + RX_HEADROOM)) == NULL)) - break; - __skb_queue_tail(&np->rx_batch, skb); - } - - /* Is the batch large enough to be worthwhile? */ - if (i < (np->rx_target/2)) - return; - - for (i = 0; ; i++) { - if ((skb = __skb_dequeue(&np->rx_batch)) == NULL) - break; - - skb->dev = dev; - - id = GET_ID_FROM_FREELIST(np->rx_skbs); - - np->rx_skbs[id] = skb; - - np->rx->ring[MASK_NETIF_RX_IDX(req_prod + i)].req.id = id; - - rx_pfn_array[i] = virt_to_machine(skb->head) >> PAGE_SHIFT; - - /* Remove this page from pseudo phys map before passing back to Xen. */ - phys_to_machine_mapping[__pa(skb->head) >> PAGE_SHIFT] - = INVALID_P2M_ENTRY; - - rx_mcl[i].op = __HYPERVISOR_update_va_mapping; - rx_mcl[i].args[0] = (unsigned long)skb->head; - rx_mcl[i].args[1] = 0; - rx_mcl[i].args[2] = 0; - } - - /* After all PTEs have been zapped we blow away stale TLB entries. */ - rx_mcl[i-1].args[2] = UVMF_TLB_FLUSH|UVMF_ALL; - - /* Give away a batch of pages. */ - rx_mcl[i].op = __HYPERVISOR_dom_mem_op; - rx_mcl[i].args[0] = MEMOP_decrease_reservation; - rx_mcl[i].args[1] = (unsigned long)rx_pfn_array; - rx_mcl[i].args[2] = (unsigned long)i; - rx_mcl[i].args[3] = 0; - rx_mcl[i].args[4] = DOMID_SELF; - - /* Tell the ballon driver what is going on. */ - balloon_update_driver_allowance(i); - - /* Zap PTEs and give away pages in one big multicall. */ - (void)HYPERVISOR_multicall(rx_mcl, i+1); - - /* Check return status of HYPERVISOR_dom_mem_op(). */ - if (unlikely(rx_mcl[i].args[5] != i)) - panic("Unable to reduce memory reservation\n"); - - /* Above is a suitable barrier to ensure backend will see requests. */ - np->rx->req_prod = req_prod + i; - - /* Adjust our floating fill target if we risked running out of buffers. */ - if (((req_prod - np->rx->resp_prod) < (np->rx_target / 4)) && - ((np->rx_target *= 2) > RX_MAX_TARGET)) - np->rx_target = RX_MAX_TARGET; + unsigned short id; + struct netfront_info *np = netdev_priv(dev); + struct sk_buff *skb; + struct page *page; + int i, batch_target, notify; + RING_IDX req_prod = np->rx.req_prod_pvt; + struct xen_memory_reservation reservation; + grant_ref_t ref; + unsigned long pfn; + void *vaddr; + + if (unlikely(!netif_carrier_ok(dev))) + return; + + /* + * Allocate skbuffs greedily, even though we batch updates to the + * receive ring. This creates a less bursty demand on the memory + * allocator, so should reduce the chance of failed allocation requests + * both for ourself and for other kernel subsystems. + */ + batch_target = np->rx_target - (req_prod - np->rx.rsp_cons); + for (i = skb_queue_len(&np->rx_batch); i < batch_target; i++) { + /* + * Allocate an skb and a page. Do not use __dev_alloc_skb as + * that will allocate page-sized buffers which is not + * necessary here. + * 16 bytes added as necessary headroom for netif_receive_skb. + */ + skb = alloc_skb(RX_COPY_THRESHOLD + 16, + GFP_ATOMIC | __GFP_NOWARN); + if (unlikely(!skb)) + goto no_skb; + + page = alloc_page(GFP_ATOMIC | __GFP_NOWARN); + if (!page) { + kfree_skb(skb); +no_skb: + /* Any skbuffs queued for refill? Force them out. */ + if (i != 0) + goto refill; + /* Could not allocate any skbuffs. Try again later. */ + mod_timer(&np->rx_refill_timer, + jiffies + (HZ/10)); + break; + } + + skb_reserve(skb, 16); /* mimic dev_alloc_skb() */ + skb_shinfo(skb)->frags[0].page = page; + skb_shinfo(skb)->nr_frags = 1; + __skb_queue_tail(&np->rx_batch, skb); + } + + /* Is the batch large enough to be worthwhile? */ + if (i < (np->rx_target/2)) { + if (req_prod > np->rx.sring->req_prod) + goto push; + return; + } + + /* Adjust our fill target if we risked running out of buffers. */ + if (((req_prod - np->rx.sring->rsp_prod) < (np->rx_target / 4)) && + ((np->rx_target *= 2) > np->rx_max_target)) + np->rx_target = np->rx_max_target; + + refill: + for (i = 0; ; i++) { + if ((skb = __skb_dequeue(&np->rx_batch)) == NULL) + break; + + skb->dev = dev; + + id = xennet_rxidx(req_prod + i); + + BUG_ON(np->rx_skbs[id]); + np->rx_skbs[id] = skb; + + RING_GET_REQUEST(&np->rx, req_prod + i)->id = id; + ref = gnttab_claim_grant_reference(&np->gref_rx_head); + BUG_ON((signed short)ref < 0); + np->grant_rx_ref[id] = ref; + + pfn = page_to_pfn(skb_shinfo(skb)->frags[0].page); + vaddr = page_address(skb_shinfo(skb)->frags[0].page); + + gnttab_grant_foreign_transfer_ref(ref, + np->xbdev->otherend_id, pfn); + RING_GET_REQUEST(&np->rx, req_prod + i)->gref = ref; + np->rx_pfn_array[i] = pfn_to_mfn(pfn); + + if (!xen_feature(XENFEAT_auto_translated_physmap)) { + /* Remove this page before passing back to Xen. */ + set_phys_to_machine(pfn, INVALID_P2M_ENTRY); + MULTI_update_va_mapping(np->rx_mcl+i, + (unsigned long)vaddr, + __pte(0), 0); + } + } + + /* Tell the ballon driver what is going on. */ + balloon_update_driver_allowance(i); + + set_xen_guest_handle(reservation.extent_start, np->rx_pfn_array); + reservation.nr_extents = i; + reservation.extent_order = 0; + reservation.address_bits = 0; + reservation.domid = DOMID_SELF; + + if (!xen_feature(XENFEAT_auto_translated_physmap)) { + /* After all PTEs have been zapped, flush the TLB. */ + np->rx_mcl[i-1].args[MULTI_UVMFLAGS_INDEX] = + UVMF_TLB_FLUSH|UVMF_ALL; + + /* Give away a batch of pages. */ + np->rx_mcl[i].op = __HYPERVISOR_memory_op; + np->rx_mcl[i].args[0] = XENMEM_decrease_reservation; + np->rx_mcl[i].args[1] = (unsigned long)&reservation; + + /* Zap PTEs and give away pages in one big multicall. */ + (void)HYPERVISOR_multicall(np->rx_mcl, i+1); + + /* Check return status of HYPERVISOR_memory_op(). */ + if (unlikely(np->rx_mcl[i].result != i)) + panic("Unable to reduce memory reservation\n"); + } else + if (HYPERVISOR_memory_op(XENMEM_decrease_reservation, + &reservation) != i) + panic("Unable to reduce memory reservation\n"); + + /* Above is a suitable barrier to ensure backend will see requests. */ + np->rx.req_prod_pvt = req_prod + i; + push: + RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&np->rx, notify); + if (notify) + notify_remote_via_irq(np->irq); } +static void xennet_make_frags(struct sk_buff *skb, struct net_device *dev, + struct netif_tx_request *tx) +{ + struct netfront_info *np = netdev_priv(dev); + char *data = skb->data; + unsigned long mfn; + RING_IDX prod = np->tx.req_prod_pvt; + int frags = skb_shinfo(skb)->nr_frags; + unsigned int offset = offset_in_page(data); + unsigned int len = skb_headlen(skb); + unsigned int id; + grant_ref_t ref; + int i; + + while (len > PAGE_SIZE - offset) { + tx->size = PAGE_SIZE - offset; + tx->flags |= NETTXF_more_data; + len -= tx->size; + data += tx->size; + offset = 0; + + id = get_id_from_freelist(np->tx_skbs); + np->tx_skbs[id] = skb_get(skb); + tx = RING_GET_REQUEST(&np->tx, prod++); + tx->id = id; + ref = gnttab_claim_grant_reference(&np->gref_tx_head); + BUG_ON((signed short)ref < 0); + + mfn = virt_to_mfn(data); + gnttab_grant_foreign_access_ref(ref, np->xbdev->otherend_id, + mfn, GNTMAP_readonly); + + tx->gref = np->grant_tx_ref[id] = ref; + tx->offset = offset; + tx->size = len; + tx->flags = 0; + } + + for (i = 0; i < frags; i++) { + skb_frag_t *frag = skb_shinfo(skb)->frags + i; + + tx->flags |= NETTXF_more_data; + + id = get_id_from_freelist(np->tx_skbs); + np->tx_skbs[id] = skb_get(skb); + tx = RING_GET_REQUEST(&np->tx, prod++); + tx->id = id; + ref = gnttab_claim_grant_reference(&np->gref_tx_head); + BUG_ON((signed short)ref < 0); + + mfn = pfn_to_mfn(page_to_pfn(frag->page)); + gnttab_grant_foreign_access_ref(ref, np->xbdev->otherend_id, + mfn, GNTMAP_readonly); + + tx->gref = np->grant_tx_ref[id] = ref; + tx->offset = frag->page_offset; + tx->size = frag->size; + tx->flags = 0; + } + + np->tx.req_prod_pvt = prod; +} static int network_start_xmit(struct sk_buff *skb, struct net_device *dev) { - unsigned short id; - struct net_private *np = netdev_priv(dev); - netif_tx_request_t *tx; - NETIF_RING_IDX i; + unsigned short id; + struct netfront_info *np = netdev_priv(dev); + struct netif_tx_request *tx; + struct netif_extra_info *extra; + char *data = skb->data; + RING_IDX i; + grant_ref_t ref; + unsigned long mfn; + int notify; + int frags = skb_shinfo(skb)->nr_frags; + unsigned int offset = offset_in_page(data); + unsigned int len = skb_headlen(skb); + + frags += (offset + len + PAGE_SIZE - 1) / PAGE_SIZE; + if (unlikely(frags > MAX_SKB_FRAGS + 1)) { + printk(KERN_ALERT "xennet: skb rides the rocket: %d frags\n", + frags); + dump_stack(); + goto drop; + } + + spin_lock_irq(&np->tx_lock); + + if (unlikely(!netif_carrier_ok(dev) || + (frags > 1 && !xennet_can_sg(dev)) || + netif_needs_gso(dev, skb))) { + spin_unlock_irq(&np->tx_lock); + goto drop; + } + + i = np->tx.req_prod_pvt; + + id = get_id_from_freelist(np->tx_skbs); + np->tx_skbs[id] = skb; + + tx = RING_GET_REQUEST(&np->tx, i); + + tx->id = id; + ref = gnttab_claim_grant_reference(&np->gref_tx_head); + BUG_ON((signed short)ref < 0); + mfn = virt_to_mfn(data); + gnttab_grant_foreign_access_ref( + ref, np->xbdev->otherend_id, mfn, GNTMAP_readonly); + tx->gref = np->grant_tx_ref[id] = ref; + tx->offset = offset; + tx->size = len; + + tx->flags = 0; + extra = NULL; + + if (skb->ip_summed == CHECKSUM_HW) /* local packet? */ + tx->flags |= NETTXF_csum_blank | NETTXF_data_validated; + if (skb->proto_data_valid) /* remote but checksummed? */ + tx->flags |= NETTXF_data_validated; + + if (skb_shinfo(skb)->gso_size) { + struct netif_extra_info *gso = (struct netif_extra_info *) + RING_GET_REQUEST(&np->tx, ++i); + + if (extra) + extra->flags |= XEN_NETIF_EXTRA_FLAG_MORE; + else + tx->flags |= NETTXF_extra_info; + + gso->u.gso.size = skb_shinfo(skb)->gso_size; + gso->u.gso.type = XEN_NETIF_GSO_TYPE_TCPV4; + gso->u.gso.pad = 0; + gso->u.gso.features = 0; + + gso->type = XEN_NETIF_EXTRA_TYPE_GSO; + gso->flags = 0; + extra = gso; + } + + np->tx.req_prod_pvt = i + 1; + + xennet_make_frags(skb, dev, tx); + tx->size = skb->len; + + RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&np->tx, notify); + if (notify) + notify_remote_via_irq(np->irq); + + network_tx_buf_gc(dev); + + if (!netfront_tx_slot_available(np)) + netif_stop_queue(dev); + + spin_unlock_irq(&np->tx_lock); + + np->stats.tx_bytes += skb->len; + np->stats.tx_packets++; + + return 0; - if (unlikely(np->tx_full)) { - printk(KERN_ALERT "%s: full queue wasn't stopped!\n", dev->name); - netif_stop_queue(dev); - goto drop; - } + drop: + np->stats.tx_dropped++; + dev_kfree_skb(skb); + return 0; +} + +static irqreturn_t netif_int(int irq, void *dev_id, struct pt_regs *ptregs) +{ + struct net_device *dev = dev_id; + struct netfront_info *np = netdev_priv(dev); + unsigned long flags; - if (unlikely((((unsigned long)skb->data & ~PAGE_MASK) + skb->len) >= - PAGE_SIZE)) { - struct sk_buff *nskb; - if (unlikely((nskb = alloc_xen_skb(skb->len)) == NULL)) - goto drop; - skb_put(nskb, skb->len); - memcpy(nskb->data, skb->data, skb->len); - nskb->dev = skb->dev; - dev_kfree_skb(skb); - skb = nskb; - } - - spin_lock_irq(&np->tx_lock); + spin_lock_irqsave(&np->tx_lock, flags); + network_tx_buf_gc(dev); + spin_unlock_irqrestore(&np->tx_lock, flags); - if (np->backend_state != BEST_CONNECTED) { - spin_unlock_irq(&np->tx_lock); - goto drop; - } + if (RING_HAS_UNCONSUMED_RESPONSES(&np->rx) && + likely(netif_running(dev))) + netif_rx_schedule(dev); - i = np->tx->req_prod; + return IRQ_HANDLED; +} - id = GET_ID_FROM_FREELIST(np->tx_skbs); - np->tx_skbs[id] = skb; +static void xennet_move_rx_slot(struct netfront_info *np, struct sk_buff *skb, + grant_ref_t ref) +{ + int new = xennet_rxidx(np->rx.req_prod_pvt); + + BUG_ON(np->rx_skbs[new]); + np->rx_skbs[new] = skb; + np->grant_rx_ref[new] = ref; + RING_GET_REQUEST(&np->rx, np->rx.req_prod_pvt)->id = new; + RING_GET_REQUEST(&np->rx, np->rx.req_prod_pvt)->gref = ref; + np->rx.req_prod_pvt++; +} - tx = &np->tx->ring[MASK_NETIF_TX_IDX(i)].req; +int xennet_get_extras(struct netfront_info *np, + struct netif_extra_info *extras, RING_IDX rp) - tx->id = id; - tx->addr = virt_to_machine(skb->data); - tx->size = skb->len; +{ + struct netif_extra_info *extra; + RING_IDX cons = np->rx.rsp_cons; + int err = 0; + + do { + struct sk_buff *skb; + grant_ref_t ref; + + if (unlikely(cons + 1 == rp)) { + if (net_ratelimit()) + WPRINTK("Missing extra info\n"); + err = -EBADR; + break; + } + + extra = (struct netif_extra_info *) + RING_GET_RESPONSE(&np->rx, ++cons); + + if (unlikely(!extra->type || + extra->type >= XEN_NETIF_EXTRA_TYPE_MAX)) { + if (net_ratelimit()) + WPRINTK("Invalid extra type: %d\n", + extra->type); + err = -EINVAL; + } else + memcpy(&extras[extra->type - 1], extra, sizeof(*extra)); + + skb = xennet_get_rx_skb(np, cons); + ref = xennet_get_rx_ref(np, cons); + xennet_move_rx_slot(np, skb, ref); + } while (extra->flags & XEN_NETIF_EXTRA_FLAG_MORE); + + np->rx.rsp_cons = cons; + return err; +} - wmb(); /* Ensure that backend will see the request. */ - np->tx->req_prod = i + 1; +static int xennet_get_responses(struct netfront_info *np, + struct netfront_rx_info *rinfo, RING_IDX rp, + struct sk_buff_head *list, int count) +{ + struct mmu_update *mmu = np->rx_mmu + count; + struct multicall_entry *mcl = np->rx_mcl + count; + struct netif_rx_response *rx = &rinfo->rx; + struct netif_extra_info *extras = rinfo->extras; + RING_IDX cons = np->rx.rsp_cons; + struct sk_buff *skb = xennet_get_rx_skb(np, cons); + grant_ref_t ref = xennet_get_rx_ref(np, cons); + int max = MAX_SKB_FRAGS + (rx->status <= RX_COPY_THRESHOLD); + int frags = 1; + int err = 0; + + if (rx->flags & NETRXF_extra_info) { + err = xennet_get_extras(np, extras, rp); + cons = np->rx.rsp_cons; + } + + for (;;) { + unsigned long mfn; + + if (unlikely(rx->status < 0 || + rx->offset + rx->status > PAGE_SIZE)) { + if (net_ratelimit()) + WPRINTK("rx->offset: %x, size: %u\n", + rx->offset, rx->status); + err = -EINVAL; + } + + /* + * This definitely indicates a bug, either in this driver or in + * the backend driver. In future this should flag the bad + * situation to the system controller to reboot the backed. + */ + if (ref == GRANT_INVALID_REF) { + WPRINTK("Bad rx response id %d.\n", rx->id); + err = -EINVAL; + goto next; + } + + /* Memory pressure, insufficient buffer headroom, ... */ + if ((mfn = gnttab_end_foreign_transfer_ref(ref)) == 0) { + if (net_ratelimit()) + WPRINTK("Unfulfilled rx req (id=%d, st=%d).\n", + rx->id, rx->status); + xennet_move_rx_slot(np, skb, ref); + err = -ENOMEM; + goto next; + } + + gnttab_release_grant_reference(&np->gref_rx_head, ref); + + if (!xen_feature(XENFEAT_auto_translated_physmap)) { + /* Remap the page. */ + struct page *page = skb_shinfo(skb)->frags[0].page; + unsigned long pfn = page_to_pfn(page); + void *vaddr = page_address(page); + + MULTI_update_va_mapping(mcl, (unsigned long)vaddr, + pfn_pte_ma(mfn, PAGE_KERNEL), + 0); + mcl++; + mmu->ptr = ((maddr_t)mfn << PAGE_SHIFT) + | MMU_MACHPHYS_UPDATE; + mmu->val = pfn; + mmu++; + + set_phys_to_machine(pfn, mfn); + } + + __skb_queue_tail(list, skb); + +next: + if (!(rx->flags & NETRXF_more_data)) + break; + + if (cons + frags == rp) { + if (net_ratelimit()) + WPRINTK("Need more frags\n"); + err = -ENOENT; + break; + } + + rx = RING_GET_RESPONSE(&np->rx, cons + frags); + skb = xennet_get_rx_skb(np, cons + frags); + ref = xennet_get_rx_ref(np, cons + frags); + frags++; + } + + if (unlikely(frags > max)) { + if (net_ratelimit()) + WPRINTK("Too many frags\n"); + err = -E2BIG; + } + + return err; +} - network_tx_buf_gc(dev); +static RING_IDX xennet_fill_frags(struct netfront_info *np, + struct sk_buff *skb, + struct sk_buff_head *list) +{ + struct skb_shared_info *shinfo = skb_shinfo(skb); + int nr_frags = shinfo->nr_frags; + RING_IDX cons = np->rx.rsp_cons; + skb_frag_t *frag = shinfo->frags + nr_frags; + struct sk_buff *nskb; - if ((i - np->tx_resp_cons) == (NETIF_TX_RING_SIZE - 1)) { - np->tx_full = 1; - netif_stop_queue(dev); - } + while ((nskb = __skb_dequeue(list))) { + struct netif_rx_response *rx = + RING_GET_RESPONSE(&np->rx, ++cons); - spin_unlock_irq(&np->tx_lock); + frag->page = skb_shinfo(nskb)->frags[0].page; + frag->page_offset = rx->offset; + frag->size = rx->status; - np->stats.tx_bytes += skb->len; - np->stats.tx_packets++; + skb->data_len += rx->status; - /* Only notify Xen if we really have to. */ - mb(); - if (np->tx->TX_TEST_IDX == i) - notify_via_evtchn(np->evtchn); + skb_shinfo(nskb)->nr_frags = 0; + kfree_skb(nskb); - return 0; + frag++; + nr_frags++; + } - drop: - np->stats.tx_dropped++; - dev_kfree_skb(skb); - return 0; + shinfo->nr_frags = nr_frags; + return cons; } -static irqreturn_t netif_int(int irq, void *dev_id, struct pt_regs *ptregs) +static int xennet_set_skb_gso(struct sk_buff *skb, struct netif_extra_info *gso) { - struct net_device *dev = dev_id; - struct net_private *np = netdev_priv(dev); - unsigned long flags; + if (!gso->u.gso.size) { + if (net_ratelimit()) + WPRINTK("GSO size must not be zero.\n"); + return -EINVAL; + } + + /* Currently only TCPv4 S.O. is supported. */ + if (gso->u.gso.type != XEN_NETIF_GSO_TYPE_TCPV4) { + if (net_ratelimit()) + WPRINTK("Bad GSO type %d.\n", gso->u.gso.type); + return -EINVAL; + } + + skb_shinfo(skb)->gso_size = gso->u.gso.size; + skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4; + + /* Header must be checked, and gso_segs computed. */ + skb_shinfo(skb)->gso_type |= SKB_GSO_DODGY; + skb_shinfo(skb)->gso_segs = 0; + + return 0; +} - spin_lock_irqsave(&np->tx_lock, flags); - network_tx_buf_gc(dev); - spin_unlock_irqrestore(&np->tx_lock, flags); +static int netif_poll(struct net_device *dev, int *pbudget) +{ + struct netfront_info *np = netdev_priv(dev); + struct sk_buff *skb; + struct netfront_rx_info rinfo; + struct netif_rx_response *rx = &rinfo.rx; + struct netif_extra_info *extras = rinfo.extras; + RING_IDX i, rp; + struct multicall_entry *mcl; + int work_done, budget, more_to_do = 1; + struct sk_buff_head rxq; + struct sk_buff_head errq; + struct sk_buff_head tmpq; + unsigned long flags; + unsigned int len; + int pages_done; + int err; + + spin_lock(&np->rx_lock); + + if (unlikely(!netif_carrier_ok(dev))) { + spin_unlock(&np->rx_lock); + return 0; + } + + skb_queue_head_init(&rxq); + skb_queue_head_init(&errq); + skb_queue_head_init(&tmpq); + + if ((budget = *pbudget) > dev->quota) + budget = dev->quota; + rp = np->rx.sring->rsp_prod; + rmb(); /* Ensure we see queued responses up to 'rp'. */ + + for (i = np->rx.rsp_cons, work_done = 0, pages_done = 0; + (i != rp) && (work_done < budget); + np->rx.rsp_cons = ++i, work_done++) { + memcpy(rx, RING_GET_RESPONSE(&np->rx, i), sizeof(*rx)); + memset(extras, 0, sizeof(extras)); + + err = xennet_get_responses(np, &rinfo, rp, &tmpq, pages_done); + pages_done += skb_queue_len(&tmpq); + + if (unlikely(err)) { +err: + i = np->rx.rsp_cons + skb_queue_len(&tmpq) - 1; + work_done--; + while ((skb = __skb_dequeue(&tmpq))) + __skb_queue_tail(&errq, skb); + np->stats.rx_errors++; + continue; + } + + skb = __skb_dequeue(&tmpq); + + if (extras[XEN_NETIF_EXTRA_TYPE_GSO - 1].type) { + struct netif_extra_info *gso; + gso = &extras[XEN_NETIF_EXTRA_TYPE_GSO - 1]; + + if (unlikely(xennet_set_skb_gso(skb, gso))) { + __skb_queue_head(&tmpq, skb); + goto err; + } + } + + skb->nh.raw = (void *)skb_shinfo(skb)->frags[0].page; + skb->h.raw = skb->nh.raw + rx->offset; + + len = rx->status; + if (len > RX_COPY_THRESHOLD) + len = RX_COPY_THRESHOLD; + skb_put(skb, len); + + if (rx->status > len) { + skb_shinfo(skb)->frags[0].page_offset = + rx->offset + len; + skb_shinfo(skb)->frags[0].size = rx->status - len; + skb->data_len = rx->status - len; + } else { + skb_shinfo(skb)->frags[0].page = NULL; + skb_shinfo(skb)->nr_frags = 0; + } + + i = xennet_fill_frags(np, skb, &tmpq); + skb->truesize += skb->data_len; + skb->len += skb->data_len; + + /* + * Old backends do not assert data_validated but we + * can infer it from csum_blank so test both flags. + */ + if (rx->flags & (NETRXF_data_validated|NETRXF_csum_blank)) { + skb->ip_summed = CHECKSUM_UNNECESSARY; + skb->proto_data_valid = 1; + } else { + skb->ip_summed = CHECKSUM_NONE; + skb->proto_data_valid = 0; + } + skb->proto_csum_blank = !!(rx->flags & NETRXF_csum_blank); + + np->stats.rx_packets++; + np->stats.rx_bytes += skb->len; + + __skb_queue_tail(&rxq, skb); + } + + /* Some pages are no longer absent... */ + balloon_update_driver_allowance(-pages_done); + + /* Do all the remapping work, and M2P updates, in one big hypercall. */ + if (likely(pages_done)) { + mcl = np->rx_mcl + pages_done; + mcl->op = __HYPERVISOR_mmu_update; + mcl->args[0] = (unsigned long)np->rx_mmu; + mcl->args[1] = pages_done; + mcl->args[2] = 0; + mcl->args[3] = DOMID_SELF; + (void)HYPERVISOR_multicall(np->rx_mcl, pages_done + 1); + } + + while ((skb = __skb_dequeue(&errq))) + kfree_skb(skb); + + while ((skb = __skb_dequeue(&rxq)) != NULL) { + struct page *page = (struct page *)skb->nh.raw; + void *vaddr = page_address(page); + + memcpy(skb->data, vaddr + (skb->h.raw - skb->nh.raw), + skb_headlen(skb)); + + if (page != skb_shinfo(skb)->frags[0].page) + __free_page(page); + + /* Ethernet work: Delayed to here as it peeks the header. */ + skb->protocol = eth_type_trans(skb, dev); + + /* Pass it up. */ + netif_receive_skb(skb); + dev->last_rx = jiffies; + } + + /* If we get a callback with very few responses, reduce fill target. */ + /* NB. Note exponential increase, linear decrease. */ + if (((np->rx.req_prod_pvt - np->rx.sring->rsp_prod) > + ((3*np->rx_target) / 4)) && + (--np->rx_target < np->rx_min_target)) + np->rx_target = np->rx_min_target; + + network_alloc_rx_buffers(dev); + + *pbudget -= work_done; + dev->quota -= work_done; + + if (work_done < budget) { + local_irq_save(flags); + + RING_FINAL_CHECK_FOR_RESPONSES(&np->rx, more_to_do); + if (!more_to_do) + __netif_rx_complete(dev); + + local_irq_restore(flags); + } + + spin_unlock(&np->rx_lock); + + return more_to_do; +} - if ((np->rx_resp_cons != np->rx->resp_prod) && (np->user_state == UST_OPEN)) - netif_rx_schedule(dev); - return IRQ_HANDLED; +static int network_close(struct net_device *dev) +{ + struct netfront_info *np = netdev_priv(dev); + netif_stop_queue(np->netdev); + return 0; } -static int netif_poll(struct net_device *dev, int *pbudget) +static struct net_device_stats *network_get_stats(struct net_device *dev) { - struct net_private *np = netdev_priv(dev); - struct sk_buff *skb, *nskb; - netif_rx_response_t *rx; - NETIF_RING_IDX i, rp; - mmu_update_t *mmu = rx_mmu; - multicall_entry_t *mcl = rx_mcl; - int work_done, budget, more_to_do = 1; - struct sk_buff_head rxq; - unsigned long flags; - - spin_lock(&np->rx_lock); - - if (np->backend_state != BEST_CONNECTED) { - spin_unlock(&np->rx_lock); - return 0; - } - - skb_queue_head_init(&rxq); - - if ((budget = *pbudget) > dev->quota) - budget = dev->quota; - - rp = np->rx->resp_prod; - rmb(); /* Ensure we see queued responses up to 'rp'. */ - - for (i = np->rx_resp_cons, work_done = 0; - (i != rp) && (work_done < budget); - i++, work_done++) { - rx = &np->rx->ring[MASK_NETIF_RX_IDX(i)].resp; - - /* - * An error here is very odd. Usually indicates a backend bug, - * low-memory condition, or that we didn't have reservation headroom. - */ - if (unlikely(rx->status <= 0)) { - if (net_ratelimit()) - printk(KERN_WARNING "Bad rx buffer (memory squeeze?).\n"); - np->rx->ring[MASK_NETIF_RX_IDX(np->rx->req_prod)].req.id = rx->id; - wmb(); - np->rx->req_prod++; - work_done--; - continue; - } - - skb = np->rx_skbs[rx->id]; - ADD_ID_TO_FREELIST(np->rx_skbs, rx->id); - - /* NB. We handle skb overflow later. */ - skb->data = skb->head + (rx->addr & ~PAGE_MASK); - skb->len = rx->status; - skb->tail = skb->data + skb->len; - - np->stats.rx_packets++; - np->stats.rx_bytes += rx->status; - - /* Remap the page. */ - mmu->ptr = (rx->addr & PAGE_MASK) | MMU_MACHPHYS_UPDATE; - mmu->val = __pa(skb->head) >> PAGE_SHIFT; - mmu++; - mcl->op = __HYPERVISOR_update_va_mapping; - mcl->args[0] = (unsigned long)skb->head; - mcl->args[1] = (rx->addr & PAGE_MASK) | __PAGE_KERNEL; - mcl->args[2] = 0; - mcl++; - - phys_to_machine_mapping[__pa(skb->head) >> PAGE_SHIFT] = - rx->addr >> PAGE_SHIFT; - - __skb_queue_tail(&rxq, skb); - } - - /* Some pages are no longer absent... */ - balloon_update_driver_allowance(-work_done); - - /* Do all the remapping work, and M->P updates, in one big hypercall. */ - if (likely((mcl - rx_mcl) != 0)) { - mcl->op = __HYPERVISOR_mmu_update; - mcl->args[0] = (unsigned long)rx_mmu; - mcl->args[1] = mmu - rx_mmu; - mcl->args[2] = 0; - mcl->args[3] = DOMID_SELF; - mcl++; - (void)HYPERVISOR_multicall(rx_mcl, mcl - rx_mcl); - } - - while ((skb = __skb_dequeue(&rxq)) != NULL) { - /* - * Enough room in skbuff for the data we were passed? Also, Linux - * expects at least 16 bytes headroom in each receive buffer. - */ - if (unlikely(skb->tail > skb->end) || - unlikely((skb->data - skb->head) < 16)) { - nskb = NULL; - - /* Only copy the packet if it fits in the current MTU. */ - if (skb->len <= (dev->mtu + ETH_HLEN)) { - if ((skb->tail > skb->end) && net_ratelimit()) - printk(KERN_INFO "Received packet needs %d bytes more " - "headroom.\n", skb->tail - skb->end); - - if ((nskb = alloc_xen_skb(skb->len + 2)) != NULL) { - skb_reserve(nskb, 2); - skb_put(nskb, skb->len); - memcpy(nskb->data, skb->data, skb->len); - nskb->dev = skb->dev; - } - } - else if (net_ratelimit()) - printk(KERN_INFO "Received packet too big for MTU " - "(%d > %d)\n", skb->len - ETH_HLEN, dev->mtu); - - /* Reinitialise and then destroy the old skbuff. */ - skb->len = 0; - skb->tail = skb->data; - init_skb_shinfo(skb); - dev_kfree_skb(skb); - - /* Switch old for new, if we copied the buffer. */ - if ((skb = nskb) == NULL) - continue; - } - - /* Set the shared-info area, which is hidden behind the real data. */ - init_skb_shinfo(skb); - - /* Ethernet-specific work. Delayed to here as it peeks the header. */ - skb->protocol = eth_type_trans(skb, dev); - - /* Pass it up. */ - netif_receive_skb(skb); - dev->last_rx = jiffies; - } - - np->rx_resp_cons = i; - - /* If we get a callback with very few responses, reduce fill target. */ - /* NB. Note exponential increase, linear decrease. */ - if (((np->rx->req_prod - np->rx->resp_prod) > ((3*np->rx_target) / 4)) && - (--np->rx_target < RX_MIN_TARGET)) - np->rx_target = RX_MIN_TARGET; - - network_alloc_rx_buffers(dev); - - *pbudget -= work_done; - dev->quota -= work_done; - - if (work_done < budget) { - local_irq_save(flags); - - np->rx->event = i + 1; - - /* Deal with hypervisor racing our resetting of rx_event. */ - mb(); - if (np->rx->resp_prod == i) { - __netif_rx_complete(dev); - more_to_do = 0; - } - - local_irq_restore(flags); - } - - spin_unlock(&np->rx_lock); - - return more_to_do; + struct netfront_info *np = netdev_priv(dev); + return &np->stats; } +static int xennet_change_mtu(struct net_device *dev, int mtu) +{ + int max = xennet_can_sg(dev) ? 65535 - ETH_HLEN : ETH_DATA_LEN; -static int network_close(struct net_device *dev) + if (mtu > max) + return -EINVAL; + dev->mtu = mtu; + return 0; +} + +static int xennet_set_sg(struct net_device *dev, u32 data) { - struct net_private *np = netdev_priv(dev); - np->user_state = UST_CLOSED; - netif_stop_queue(np->dev); - return 0; + if (data) { + struct netfront_info *np = netdev_priv(dev); + int val; + + if (xenbus_scanf(XBT_NIL, np->xbdev->otherend, "feature-sg", + "%d", &val) < 0) + val = 0; + if (!val) + return -ENOSYS; + } else if (dev->mtu > ETH_DATA_LEN) + dev->mtu = ETH_DATA_LEN; + + return ethtool_op_set_sg(dev, data); } +static int xennet_set_tso(struct net_device *dev, u32 data) +{ + if (data) { + struct netfront_info *np = netdev_priv(dev); + int val; + + if (xenbus_scanf(XBT_NIL, np->xbdev->otherend, + "feature-gso-tcpv4", "%d", &val) < 0) + val = 0; + if (!val) + return -ENOSYS; + } + + return ethtool_op_set_tso(dev, data); +} -static struct net_device_stats *network_get_stats(struct net_device *dev) +static void xennet_set_features(struct net_device *dev) { - struct net_private *np = netdev_priv(dev); - return &np->stats; + /* Turn off all GSO bits except ROBUST. */ + dev->features &= (1 << NETIF_F_GSO_SHIFT) - 1; + dev->features |= NETIF_F_GSO_ROBUST; + xennet_set_sg(dev, 0); + + if (!xennet_set_sg(dev, 1)) + xennet_set_tso(dev, 1); } +static void network_connect(struct net_device *dev) +{ + struct netfront_info *np = netdev_priv(dev); + int i, requeue_idx; + struct sk_buff *skb; + grant_ref_t ref; + + xennet_set_features(dev); + + spin_lock_irq(&np->tx_lock); + spin_lock(&np->rx_lock); + + /* + * Recovery procedure: + * NB. Freelist index entries are always going to be less than + * PAGE_OFFSET, whereas pointers to skbs will always be equal or + * greater than PAGE_OFFSET: we use this property to distinguish + * them. + */ + + /* Step 1: Discard all pending TX packet fragments. */ + for (requeue_idx = 0, i = 1; i <= NET_TX_RING_SIZE; i++) { + if ((unsigned long)np->tx_skbs[i] < PAGE_OFFSET) + continue; + + skb = np->tx_skbs[i]; + gnttab_end_foreign_access_ref( + np->grant_tx_ref[i], GNTMAP_readonly); + gnttab_release_grant_reference( + &np->gref_tx_head, np->grant_tx_ref[i]); + np->grant_tx_ref[i] = GRANT_INVALID_REF; + add_id_to_freelist(np->tx_skbs, i); + dev_kfree_skb_irq(skb); + } + + /* Step 2: Rebuild the RX buffer freelist and the RX ring itself. */ + for (requeue_idx = 0, i = 0; i < NET_RX_RING_SIZE; i++) { + if (!np->rx_skbs[i]) + continue; + + skb = np->rx_skbs[requeue_idx] = xennet_get_rx_skb(np, i); + ref = np->grant_rx_ref[requeue_idx] = xennet_get_rx_ref(np, i); + + gnttab_grant_foreign_transfer_ref( + ref, np->xbdev->otherend_id, + page_to_pfn(skb_shinfo(skb)->frags->page)); + + RING_GET_REQUEST(&np->rx, requeue_idx)->gref = ref; + RING_GET_REQUEST(&np->rx, requeue_idx)->id = requeue_idx; + + requeue_idx++; + } + + np->rx.req_prod_pvt = requeue_idx; + + /* + * Step 3: All public and private state should now be sane. Get + * ready to start sending and receiving packets and give the driver + * domain a kick because we've probably just requeued some + * packets. + */ + netif_carrier_on(dev); + notify_remote_via_irq(np->irq); + network_tx_buf_gc(dev); + network_alloc_rx_buffers(dev); + + spin_unlock(&np->rx_lock); + spin_unlock_irq(&np->tx_lock); +} -static void network_connect(struct net_device *dev, - netif_fe_interface_status_t *status) +static void netif_uninit(struct net_device *dev) { - struct net_private *np; - int i, requeue_idx; - netif_tx_request_t *tx; - - np = netdev_priv(dev); - spin_lock_irq(&np->tx_lock); - spin_lock(&np->rx_lock); - - /* Recovery procedure: */ - - /* Step 1: Reinitialise variables. */ - np->rx_resp_cons = np->tx_resp_cons = np->tx_full = 0; - np->rx->event = np->tx->event = 1; - - /* Step 2: Rebuild the RX and TX ring contents. - * NB. We could just free the queued TX packets now but we hope - * that sending them out might do some good. We have to rebuild - * the RX ring because some of our pages are currently flipped out - * so we can't just free the RX skbs. - * NB2. Freelist index entries are always going to be less than - * __PAGE_OFFSET, whereas pointers to skbs will always be equal or - * greater than __PAGE_OFFSET: we use this property to distinguish - * them. - */ - - /* Rebuild the TX buffer freelist and the TX ring itself. - * NB. This reorders packets. We could keep more private state - * to avoid this but maybe it doesn't matter so much given the - * interface has been down. - */ - for (requeue_idx = 0, i = 1; i <= NETIF_TX_RING_SIZE; i++) { - if ((unsigned long)np->tx_skbs[i] >= __PAGE_OFFSET) { - struct sk_buff *skb = np->tx_skbs[i]; - - tx = &np->tx->ring[requeue_idx++].req; - - tx->id = i; - tx->addr = virt_to_machine(skb->data); - tx->size = skb->len; - - np->stats.tx_bytes += skb->len; - np->stats.tx_packets++; - } - } - wmb(); - np->tx->req_prod = requeue_idx; - - /* Rebuild the RX buffer freelist and the RX ring itself. */ - for (requeue_idx = 0, i = 1; i <= NETIF_RX_RING_SIZE; i++) - if ((unsigned long)np->rx_skbs[i] >= __PAGE_OFFSET) - np->rx->ring[requeue_idx++].req.id = i; - wmb(); - np->rx->req_prod = requeue_idx; - - /* Step 3: All public and private state should now be sane. Get - * ready to start sending and receiving packets and give the driver - * domain a kick because we've probably just requeued some - * packets. - */ - np->backend_state = BEST_CONNECTED; - wmb(); - notify_via_evtchn(status->evtchn); - network_tx_buf_gc(dev); - - if (np->user_state == UST_OPEN) - netif_start_queue(dev); - - spin_unlock(&np->rx_lock); - spin_unlock_irq(&np->tx_lock); + struct netfront_info *np = netdev_priv(dev); + gnttab_free_grant_references(np->gref_tx_head); + gnttab_free_grant_references(np->gref_rx_head); } -static void vif_show(struct net_private *np) +static struct ethtool_ops network_ethtool_ops = { -#if DEBUG - if (np) { - IPRINTK("\n", - np->handle, - be_state_name[np->backend_state], - np->user_state ? "open" : "closed", - np->evtchn, - np->irq, - np->tx, - np->rx); - } else { - IPRINTK("\n"); - } -#endif + .get_tx_csum = ethtool_op_get_tx_csum, + .set_tx_csum = ethtool_op_set_tx_csum, + .get_sg = ethtool_op_get_sg, + .set_sg = xennet_set_sg, + .get_tso = ethtool_op_get_tso, + .set_tso = xennet_set_tso, + .get_link = ethtool_op_get_link, +}; + +#ifdef CONFIG_SYSFS +static ssize_t show_rxbuf_min(struct class_device *cd, char *buf) +{ + struct net_device *netdev = container_of(cd, struct net_device, + class_dev); + struct netfront_info *info = netdev_priv(netdev); + + return sprintf(buf, "%u\n", info->rx_min_target); } -/* Send a connect message to xend to tell it to bring up the interface. */ -static void send_interface_connect(struct net_private *np) +static ssize_t store_rxbuf_min(struct class_device *cd, + const char *buf, size_t len) { - ctrl_msg_t cmsg = { - .type = CMSG_NETIF_FE, - .subtype = CMSG_NETIF_FE_INTERFACE_CONNECT, - .length = sizeof(netif_fe_interface_connect_t), - }; - netif_fe_interface_connect_t *msg = (void*)cmsg.msg; - - msg->handle = np->handle; - msg->tx_shmem_frame = (virt_to_machine(np->tx) >> PAGE_SHIFT); - msg->rx_shmem_frame = (virt_to_machine(np->rx) >> PAGE_SHIFT); - - ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE); + struct net_device *netdev = container_of(cd, struct net_device, + class_dev); + struct netfront_info *np = netdev_priv(netdev); + char *endp; + unsigned long target; + + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + + target = simple_strtoul(buf, &endp, 0); + if (endp == buf) + return -EBADMSG; + + if (target < RX_MIN_TARGET) + target = RX_MIN_TARGET; + if (target > RX_MAX_TARGET) + target = RX_MAX_TARGET; + + spin_lock(&np->rx_lock); + if (target > np->rx_max_target) + np->rx_max_target = target; + np->rx_min_target = target; + if (target > np->rx_target) + np->rx_target = target; + + network_alloc_rx_buffers(netdev); + + spin_unlock(&np->rx_lock); + return len; } -/* Send a driver status notification to the domain controller. */ -static int send_driver_status(int ok) +static ssize_t show_rxbuf_max(struct class_device *cd, char *buf) { - int err = 0; - ctrl_msg_t cmsg = { - .type = CMSG_NETIF_FE, - .subtype = CMSG_NETIF_FE_DRIVER_STATUS, - .length = sizeof(netif_fe_driver_status_t), - }; - netif_fe_driver_status_t *msg = (void*)cmsg.msg; - - msg->status = (ok ? NETIF_DRIVER_STATUS_UP : NETIF_DRIVER_STATUS_DOWN); - err = ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE); - return err; + struct net_device *netdev = container_of(cd, struct net_device, + class_dev); + struct netfront_info *info = netdev_priv(netdev); + + return sprintf(buf, "%u\n", info->rx_max_target); } -/* Stop network device and free tx/rx queues and irq. - */ -static void vif_release(struct net_private *np) +static ssize_t store_rxbuf_max(struct class_device *cd, + const char *buf, size_t len) { - /* Stop old i/f to prevent errors whilst we rebuild the state. */ - spin_lock_irq(&np->tx_lock); - spin_lock(&np->rx_lock); - netif_stop_queue(np->dev); - /* np->backend_state = BEST_DISCONNECTED; */ - spin_unlock(&np->rx_lock); - spin_unlock_irq(&np->tx_lock); - - /* Free resources. */ - if(np->tx != NULL){ - free_irq(np->irq, np->dev); - unbind_evtchn_from_irq(np->evtchn); - free_page((unsigned long)np->tx); - free_page((unsigned long)np->rx); - np->irq = 0; - np->evtchn = 0; - np->tx = NULL; - np->rx = NULL; - } + struct net_device *netdev = container_of(cd, struct net_device, + class_dev); + struct netfront_info *np = netdev_priv(netdev); + char *endp; + unsigned long target; + + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + + target = simple_strtoul(buf, &endp, 0); + if (endp == buf) + return -EBADMSG; + + if (target < RX_MIN_TARGET) + target = RX_MIN_TARGET; + if (target > RX_MAX_TARGET) + target = RX_MAX_TARGET; + + spin_lock(&np->rx_lock); + if (target < np->rx_min_target) + np->rx_min_target = target; + np->rx_max_target = target; + if (target < np->rx_target) + np->rx_target = target; + + network_alloc_rx_buffers(netdev); + + spin_unlock(&np->rx_lock); + return len; } -/* Release vif resources and close it down completely. - */ -static void vif_close(struct net_private *np) +static ssize_t show_rxbuf_cur(struct class_device *cd, char *buf) { - WPRINTK("Unexpected netif-CLOSED message in state %s\n", - be_state_name[np->backend_state]); - vif_release(np); - np->backend_state = BEST_CLOSED; - /* todo: take dev down and free. */ - vif_show(np); + struct net_device *netdev = container_of(cd, struct net_device, + class_dev); + struct netfront_info *info = netdev_priv(netdev); + + return sprintf(buf, "%u\n", info->rx_target); } -/* Move the vif into disconnected state. - * Allocates tx/rx pages. - * Sends connect message to xend. - */ -static void vif_disconnect(struct net_private *np) +static const struct class_device_attribute xennet_attrs[] = { + __ATTR(rxbuf_min, S_IRUGO|S_IWUSR, show_rxbuf_min, store_rxbuf_min), + __ATTR(rxbuf_max, S_IRUGO|S_IWUSR, show_rxbuf_max, store_rxbuf_max), + __ATTR(rxbuf_cur, S_IRUGO, show_rxbuf_cur, NULL), +}; + +static int xennet_sysfs_addif(struct net_device *netdev) { - if(np->tx) free_page((unsigned long)np->tx); - if(np->rx) free_page((unsigned long)np->rx); - // Before this np->tx and np->rx had better be null. - np->tx = (netif_tx_interface_t *)__get_free_page(GFP_KERNEL); - np->rx = (netif_rx_interface_t *)__get_free_page(GFP_KERNEL); - memset(np->tx, 0, PAGE_SIZE); - memset(np->rx, 0, PAGE_SIZE); - np->backend_state = BEST_DISCONNECTED; - send_interface_connect(np); - vif_show(np); + int i; + int error = 0; + + for (i = 0; i < ARRAY_SIZE(xennet_attrs); i++) { + error = class_device_create_file(&netdev->class_dev, + &xennet_attrs[i]); + if (error) + goto fail; + } + return 0; + + fail: + while (--i >= 0) + class_device_remove_file(&netdev->class_dev, + &xennet_attrs[i]); + return error; } -/* Begin interface recovery. - * - * NB. Whilst we're recovering, we turn the carrier state off. We - * take measures to ensure that this device isn't used for - * anything. We also stop the queue for this device. Various - * different approaches (e.g. continuing to buffer packets) have - * been tested but don't appear to improve the overall impact on - * TCP connections. - * - * TODO: (MAW) Change the Xend<->Guest protocol so that a recovery - * is initiated by a special "RESET" message - disconnect could - * just mean we're not allowed to use this interface any more. - */ -static void vif_reset(struct net_private *np) +static void xennet_sysfs_delif(struct net_device *netdev) { - IPRINTK("Attempting to reconnect network interface: handle=%u\n", - np->handle); - vif_release(np); - vif_disconnect(np); - vif_show(np); + int i; + + for (i = 0; i < ARRAY_SIZE(xennet_attrs); i++) { + class_device_remove_file(&netdev->class_dev, + &xennet_attrs[i]); + } } -/* Move the vif into connected state. - * Sets the mac and event channel from the message. - * Binds the irq to the event channel. +#endif /* CONFIG_SYSFS */ + + +/* + * Nothing to do here. Virtual interface is point-to-point and the + * physical interface is probably promiscuous anyway. */ -static void -vif_connect(struct net_private *np, netif_fe_interface_status_t *status) +static void network_set_multicast_list(struct net_device *dev) { - struct net_device *dev = np->dev; - memcpy(dev->dev_addr, status->mac, ETH_ALEN); - network_connect(dev, status); - np->evtchn = status->evtchn; - np->irq = bind_evtchn_to_irq(np->evtchn); - (void)request_irq(np->irq, netif_int, SA_SAMPLE_RANDOM, dev->name, dev); - netctrl_connected_count(); - (void)send_fake_arp(dev); - vif_show(np); } - /** Create a network device. * @param handle device handle * @param val return parameter for created device * @return 0 on success, error code otherwise */ -static int create_netdev(int handle, struct net_device **val) +static struct net_device * __devinit create_netdev(int handle, + struct xenbus_device *dev) { - int i, err = 0; - struct net_device *dev = NULL; - struct net_private *np = NULL; - - if ((dev = alloc_etherdev(sizeof(struct net_private))) == NULL) { - printk(KERN_WARNING "%s> alloc_etherdev failed.\n", __FUNCTION__); - err = -ENOMEM; - goto exit; - } - - np = netdev_priv(dev); - np->backend_state = BEST_CLOSED; - np->user_state = UST_CLOSED; - np->handle = handle; - - spin_lock_init(&np->tx_lock); - spin_lock_init(&np->rx_lock); - - skb_queue_head_init(&np->rx_batch); - np->rx_target = RX_MIN_TARGET; - - /* Initialise {tx,rx}_skbs to be a free chain containing every entry. */ - for (i = 0; i <= NETIF_TX_RING_SIZE; i++) - np->tx_skbs[i] = (void *)(i+1); - for (i = 0; i <= NETIF_RX_RING_SIZE; i++) - np->rx_skbs[i] = (void *)(i+1); - - dev->open = network_open; - dev->hard_start_xmit = network_start_xmit; - dev->stop = network_close; - dev->get_stats = network_get_stats; - dev->poll = netif_poll; - dev->weight = 64; - - if ((err = register_netdev(dev)) != 0) { - printk(KERN_WARNING "%s> register_netdev err=%d\n", __FUNCTION__, err); - goto exit; - } - np->dev = dev; - list_add(&np->list, &dev_list); - - exit: - if ((err != 0) && (dev != NULL )) - kfree(dev); - else if (val != NULL) - *val = dev; - return err; + int i, err = 0; + struct net_device *netdev = NULL; + struct netfront_info *np = NULL; + + netdev = alloc_etherdev(sizeof(struct netfront_info)); + if (!netdev) { + printk(KERN_WARNING "%s> alloc_etherdev failed.\n", + __FUNCTION__); + return ERR_PTR(-ENOMEM); + } + + np = netdev_priv(netdev); + np->handle = handle; + np->xbdev = dev; + + netif_carrier_off(netdev); + + spin_lock_init(&np->tx_lock); + spin_lock_init(&np->rx_lock); + + skb_queue_head_init(&np->rx_batch); + np->rx_target = RX_DFL_MIN_TARGET; + np->rx_min_target = RX_DFL_MIN_TARGET; + np->rx_max_target = RX_MAX_TARGET; + + init_timer(&np->rx_refill_timer); + np->rx_refill_timer.data = (unsigned long)netdev; + np->rx_refill_timer.function = rx_refill_timeout; + + /* Initialise {tx,rx}_skbs as a free chain containing every entry. */ + for (i = 0; i <= NET_TX_RING_SIZE; i++) { + np->tx_skbs[i] = (void *)((unsigned long) i+1); + np->grant_tx_ref[i] = GRANT_INVALID_REF; + } + + for (i = 0; i < NET_RX_RING_SIZE; i++) { + np->rx_skbs[i] = NULL; + np->grant_rx_ref[i] = GRANT_INVALID_REF; + } + + /* A grant for every tx ring slot */ + if (gnttab_alloc_grant_references(TX_MAX_TARGET, + &np->gref_tx_head) < 0) { + printk(KERN_ALERT "#### netfront can't alloc tx grant refs\n"); + err = -ENOMEM; + goto exit; + } + /* A grant for every rx ring slot */ + if (gnttab_alloc_grant_references(RX_MAX_TARGET, + &np->gref_rx_head) < 0) { + printk(KERN_ALERT "#### netfront can't alloc rx grant refs\n"); + err = -ENOMEM; + goto exit_free_tx; + } + + netdev->open = network_open; + netdev->hard_start_xmit = network_start_xmit; + netdev->stop = network_close; + netdev->get_stats = network_get_stats; + netdev->poll = netif_poll; + netdev->set_multicast_list = network_set_multicast_list; + netdev->uninit = netif_uninit; + netdev->change_mtu = xennet_change_mtu; + netdev->weight = 64; + netdev->features = NETIF_F_IP_CSUM; + + SET_ETHTOOL_OPS(netdev, &network_ethtool_ops); + SET_MODULE_OWNER(netdev); + SET_NETDEV_DEV(netdev, &dev->dev); + + err = register_netdev(netdev); + if (err) { + printk(KERN_WARNING "%s> register_netdev err=%d\n", + __FUNCTION__, err); + goto exit_free_rx; + } + + err = xennet_sysfs_addif(netdev); + if (err) { + /* This can be non-fatal: it only means no tuning parameters */ + printk(KERN_WARNING "%s> add sysfs failed err=%d\n", + __FUNCTION__, err); + } + + np->netdev = netdev; + + return netdev; + + + exit_free_rx: + gnttab_free_grant_references(np->gref_rx_head); + exit_free_tx: + gnttab_free_grant_references(np->gref_tx_head); + exit: + free_netdev(netdev); + return ERR_PTR(err); } -/* Get the target interface for a status message. - * Creates the interface when it makes sense. - * The returned interface may be null when there is no error. - * - * @param status status message - * @param np return parameter for interface state - * @return 0 on success, error code otherwise +/* + * We use this notifier to send out a fake ARP reply to reset switches and + * router ARP caches when an IP interface is brought up on a VIF. */ -static int -target_vif(netif_fe_interface_status_t *status, struct net_private **np) +static int +inetdev_notify(struct notifier_block *this, unsigned long event, void *ptr) { - int err = 0; - struct net_device *dev; - - DPRINTK("> handle=%d\n", status->handle); - if (status->handle < 0) { - err = -EINVAL; - goto exit; - } - - if ((dev = find_dev_by_handle(status->handle)) != NULL) - goto exit; - - if (status->status == NETIF_INTERFACE_STATUS_CLOSED) - goto exit; - if (status->status == NETIF_INTERFACE_STATUS_CHANGED) - goto exit; - - /* It's a new interface in a good state - create it. */ - DPRINTK("> create device...\n"); - if ((err = create_netdev(status->handle, &dev)) != 0) - goto exit; - - netctrl.interface_n++; - - exit: - if (np != NULL) - *np = ((dev && !err) ? netdev_priv(dev) : NULL); - DPRINTK("< err=%d\n", err); - return err; + struct in_ifaddr *ifa = (struct in_ifaddr *)ptr; + struct net_device *dev = ifa->ifa_dev->dev; + + /* UP event and is it one of our devices? */ + if (event == NETDEV_UP && dev->open == network_open) + (void)send_fake_arp(dev); + + return NOTIFY_DONE; } -/* Handle an interface status message. */ -static void netif_interface_status(netif_fe_interface_status_t *status) -{ - int err = 0; - struct net_private *np = NULL; - - DPRINTK("> status=%s handle=%d\n", - status_name[status->status], status->handle); - - if ((err = target_vif(status, &np)) != 0) { - WPRINTK("Invalid netif: handle=%u\n", status->handle); - return; - } - - if (np == NULL) { - DPRINTK("> no vif\n"); - return; - } - - switch (status->status) { - case NETIF_INTERFACE_STATUS_CLOSED: - switch (np->backend_state) { - case BEST_CLOSED: - case BEST_DISCONNECTED: - case BEST_CONNECTED: - vif_close(np); - break; - } - break; - - case NETIF_INTERFACE_STATUS_DISCONNECTED: - switch (np->backend_state) { - case BEST_CLOSED: - vif_disconnect(np); - break; - case BEST_DISCONNECTED: - case BEST_CONNECTED: - vif_reset(np); - break; - } - break; - - case NETIF_INTERFACE_STATUS_CONNECTED: - switch (np->backend_state) { - case BEST_CLOSED: - WPRINTK("Unexpected netif status %s in state %s\n", - status_name[status->status], - be_state_name[np->backend_state]); - vif_disconnect(np); - vif_connect(np, status); - break; - case BEST_DISCONNECTED: - vif_connect(np, status); - break; - } - break; - - case NETIF_INTERFACE_STATUS_CHANGED: - /* - * The domain controller is notifying us that a device has been - * added or removed. - */ - break; - default: - WPRINTK("Invalid netif status code %d\n", status->status); - break; - } +/* ** Close down ** */ - vif_show(np); -} -/* - * Initialize the network control interface. +/** + * Handle the change of state of the backend to Closing. We must delete our + * device-layer structures now, to ensure that writes are flushed through to + * the backend. Once is this done, we can switch to Closed in + * acknowledgement. */ -static void netif_driver_status(netif_fe_driver_status_t *status) +static void netfront_closing(struct xenbus_device *dev) { - netctrl.up = status->status; - netctrl_connected_count(); + struct netfront_info *info = dev->dev.driver_data; + + DPRINTK("netfront_closing: %s removed\n", dev->nodename); + + close_netdev(info); + + xenbus_switch_state(dev, XenbusStateClosed); } -/* Receive handler for control messages. */ -static void netif_ctrlif_rx(ctrl_msg_t *msg, unsigned long id) -{ - switch (msg->subtype) { - case CMSG_NETIF_FE_INTERFACE_STATUS: - netif_interface_status((netif_fe_interface_status_t *) &msg->msg[0]); - break; +static int __devexit netfront_remove(struct xenbus_device *dev) +{ + struct netfront_info *info = dev->dev.driver_data; - case CMSG_NETIF_FE_DRIVER_STATUS: - netif_driver_status((netif_fe_driver_status_t *) &msg->msg[0]); - break; + DPRINTK("%s\n", dev->nodename); - default: - msg->length = 0; - break; - } + netif_disconnect_backend(info); + free_netdev(info->netdev); - ctrl_if_send_response(msg); + return 0; } -#if 1 -/* Wait for all interfaces to be connected. - * - * This works OK, but we'd like to use the probing mode (see below). - */ -static int probe_interfaces(void) +static void close_netdev(struct netfront_info *info) { - int err = 0, conn = 0; - int wait_i, wait_n = 100; + del_timer_sync(&info->rx_refill_timer); - DPRINTK(">\n"); + xennet_sysfs_delif(info->netdev); + unregister_netdev(info->netdev); +} - for (wait_i = 0; wait_i < wait_n; wait_i++) { - DPRINTK("> wait_i=%d\n", wait_i); - conn = netctrl_connected(); - if(conn) break; - DPRINTK("> schedule_timeout...\n"); - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(10); - } - DPRINTK("> wait finished...\n"); - if (conn <= 0) { - err = netctrl_err(-ENETDOWN); - WPRINTK("Failed to connect all virtual interfaces: err=%d\n", err); - } +static void netif_disconnect_backend(struct netfront_info *info) +{ + /* Stop old i/f to prevent errors whilst we rebuild the state. */ + spin_lock_irq(&info->tx_lock); + spin_lock(&info->rx_lock); + netif_carrier_off(info->netdev); + spin_unlock(&info->rx_lock); + spin_unlock_irq(&info->tx_lock); + + if (info->irq) + unbind_from_irqhandler(info->irq, info->netdev); + info->evtchn = info->irq = 0; + + end_access(info->tx_ring_ref, info->tx.sring); + end_access(info->rx_ring_ref, info->rx.sring); + info->tx_ring_ref = GRANT_INVALID_REF; + info->rx_ring_ref = GRANT_INVALID_REF; + info->tx.sring = NULL; + info->rx.sring = NULL; +} - DPRINTK("< err=%d\n", err); - return err; -} -#else -/* Probe for interfaces until no more are found. - * - * This is the mode we'd like to use, but at the moment it panics the kernel. -*/ -static int probe_interfaces(void) +static void netif_free(struct netfront_info *info) { - int err = 0; - int wait_i, wait_n = 100; - ctrl_msg_t cmsg = { - .type = CMSG_NETIF_FE, - .subtype = CMSG_NETIF_FE_INTERFACE_STATUS, - .length = sizeof(netif_fe_interface_status_t), - }; - netif_fe_interface_status_t msg = {}; - ctrl_msg_t rmsg = {}; - netif_fe_interface_status_t *reply = (void*)rmsg.msg; - int state = TASK_UNINTERRUPTIBLE; - u32 query = -1; - - DPRINTK(">\n"); - - netctrl.interface_n = 0; - for (wait_i = 0; wait_i < wait_n; wait_i++) { - DPRINTK("> wait_i=%d query=%d\n", wait_i, query); - msg.handle = query; - memcpy(cmsg.msg, &msg, sizeof(msg)); - DPRINTK("> set_current_state...\n"); - set_current_state(state); - DPRINTK("> rmsg=%p msg=%p, reply=%p\n", &rmsg, rmsg.msg, reply); - DPRINTK("> sending...\n"); - err = ctrl_if_send_message_and_get_response(&cmsg, &rmsg, state); - DPRINTK("> err=%d\n", err); - if(err) goto exit; - DPRINTK("> rmsg=%p msg=%p, reply=%p\n", &rmsg, rmsg.msg, reply); - if((int)reply->handle < 0) { - // No more interfaces. - break; - } - query = -reply->handle - 2; - DPRINTK(">netif_interface_status ...\n"); - netif_interface_status(reply); - } - - exit: - if (err) { - err = netctrl_err(-ENETDOWN); - WPRINTK("Connecting virtual network interfaces failed: err=%d\n", err); - } - - DPRINTK("< err=%d\n", err); - return err; + close_netdev(info); + netif_disconnect_backend(info); + free_netdev(info->netdev); } -#endif -/* - * We use this notifier to send out a fake ARP reply to reset switches and - * router ARP caches when an IP interface is brought up on a VIF. - */ -static int -inetdev_notify(struct notifier_block *this, unsigned long event, void *ptr) +static void end_access(int ref, void *page) { - struct in_ifaddr *ifa = (struct in_ifaddr *)ptr; - struct net_device *dev = ifa->ifa_dev->dev; - struct list_head *ent; - struct net_private *np; - - if (event != NETDEV_UP) - goto out; - - list_for_each (ent, &dev_list) { - np = list_entry(ent, struct net_private, list); - if (np->dev == dev) - (void)send_fake_arp(dev); - } - - out: - return NOTIFY_DONE; + if (ref != GRANT_INVALID_REF) + gnttab_end_foreign_access(ref, 0, (unsigned long)page); } + +/* ** Driver registration ** */ + + +static struct xenbus_device_id netfront_ids[] = { + { "vif" }, + { "" } +}; + + +static struct xenbus_driver netfront = { + .name = "vif", + .owner = THIS_MODULE, + .ids = netfront_ids, + .probe = netfront_probe, + .remove = __devexit_p(netfront_remove), + .resume = netfront_resume, + .otherend_changed = backend_changed, +}; + + static struct notifier_block notifier_inetdev = { - .notifier_call = inetdev_notify, - .next = NULL, - .priority = 0 + .notifier_call = inetdev_notify, + .next = NULL, + .priority = 0 }; static int __init netif_init(void) { - int err = 0; - - if (xen_start_info.flags & SIF_INITDOMAIN) - return 0; - - IPRINTK("Initialising virtual ethernet driver.\n"); - INIT_LIST_HEAD(&dev_list); - (void)register_inetaddr_notifier(¬ifier_inetdev); - netctrl_init(); - (void)ctrl_if_register_receiver(CMSG_NETIF_FE, netif_ctrlif_rx, - CALLBACK_IN_BLOCKING_CONTEXT); - send_driver_status(1); - err = probe_interfaces(); - if (err) - ctrl_if_unregister_receiver(CMSG_NETIF_FE, netif_ctrlif_rx); - - DPRINTK("< err=%d\n", err); - return err; -} + if (!is_running_on_xen()) + return -ENODEV; -static void vif_suspend(struct net_private *np) -{ - /* Avoid having tx/rx stuff happen until we're ready. */ - free_irq(np->irq, np->dev); - unbind_evtchn_from_irq(np->evtchn); -} + if (xen_start_info->flags & SIF_INITDOMAIN) + return 0; -static void vif_resume(struct net_private *np) -{ - /* - * Connect regardless of whether IFF_UP flag set. - * Stop bad things from happening until we're back up. - */ - np->backend_state = BEST_DISCONNECTED; - memset(np->tx, 0, PAGE_SIZE); - memset(np->rx, 0, PAGE_SIZE); - - send_interface_connect(np); -} + IPRINTK("Initialising virtual ethernet driver.\n"); -void netif_suspend(void) -{ - struct list_head *ent; - struct net_private *np; - - list_for_each (ent, &dev_list) { - np = list_entry(ent, struct net_private, list); - vif_suspend(np); - } + (void)register_inetaddr_notifier(¬ifier_inetdev); + + return xenbus_register_frontend(&netfront); } +module_init(netif_init); + -void netif_resume(void) +static void __exit netif_exit(void) { - struct list_head *ent; - struct net_private *np; + unregister_inetaddr_notifier(¬ifier_inetdev); - list_for_each (ent, &dev_list) { - np = list_entry(ent, struct net_private, list); - vif_resume(np); - } + return xenbus_unregister_driver(&netfront); } +module_exit(netif_exit); - -module_init(netif_init); - +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/xen/privcmd/Makefile b/drivers/xen/privcmd/Makefile index e21869553..de090ba6b 100644 --- a/drivers/xen/privcmd/Makefile +++ b/drivers/xen/privcmd/Makefile @@ -1,2 +1,2 @@ -obj-y := privcmd.o +obj-$(CONFIG_XEN_PRIVCMD) := privcmd.o diff --git a/drivers/xen/privcmd/privcmd.c b/drivers/xen/privcmd/privcmd.c index 0b78cc7e8..3c9bb9f0d 100644 --- a/drivers/xen/privcmd/privcmd.c +++ b/drivers/xen/privcmd/privcmd.c @@ -19,214 +19,268 @@ #include #include #include +#include +#include #include #include #include #include -#include -#include -#include - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) -#define pud_t pgd_t -#define pud_offset(d, va) d -#endif +#include +#include +#include +#include +#include static struct proc_dir_entry *privcmd_intf; +static struct proc_dir_entry *capabilities_intf; + +#define NR_HYPERCALLS 64 +static DECLARE_BITMAP(hypercall_permission_map, NR_HYPERCALLS); static int privcmd_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long data) + unsigned int cmd, unsigned long data) { - int ret = -ENOSYS; + int ret = -ENOSYS; + void __user *udata = (void __user *) data; - switch ( cmd ) - { - case IOCTL_PRIVCMD_HYPERCALL: - { - privcmd_hypercall_t hypercall; + switch (cmd) { + case IOCTL_PRIVCMD_HYPERCALL: { + privcmd_hypercall_t hypercall; - if ( copy_from_user(&hypercall, (void *)data, sizeof(hypercall)) ) - return -EFAULT; + if (copy_from_user(&hypercall, udata, sizeof(hypercall))) + return -EFAULT; + + /* Check hypercall number for validity. */ + if (hypercall.op >= NR_HYPERCALLS) + return -EINVAL; + if (!test_bit(hypercall.op, hypercall_permission_map)) + return -EINVAL; #if defined(__i386__) - __asm__ __volatile__ ( - "pushl %%ebx; pushl %%ecx; pushl %%edx; pushl %%esi; pushl %%edi; " - "movl 4(%%eax),%%ebx ;" - "movl 8(%%eax),%%ecx ;" - "movl 12(%%eax),%%edx ;" - "movl 16(%%eax),%%esi ;" - "movl 20(%%eax),%%edi ;" - "movl (%%eax),%%eax ;" - TRAP_INSTR "; " - "popl %%edi; popl %%esi; popl %%edx; popl %%ecx; popl %%ebx" - : "=a" (ret) : "0" (&hypercall) : "memory" ); + __asm__ __volatile__ ( + "pushl %%ebx; pushl %%ecx; pushl %%edx; " + "pushl %%esi; pushl %%edi; " + "movl 8(%%eax),%%ebx ;" + "movl 16(%%eax),%%ecx ;" + "movl 24(%%eax),%%edx ;" + "movl 32(%%eax),%%esi ;" + "movl 40(%%eax),%%edi ;" + "movl (%%eax),%%eax ;" + "shll $5,%%eax ;" + "addl $hypercall_page,%%eax ;" + "call *%%eax ;" + "popl %%edi; popl %%esi; popl %%edx; " + "popl %%ecx; popl %%ebx" + : "=a" (ret) : "0" (&hypercall) : "memory" ); #elif defined (__x86_64__) - __asm__ __volatile__ ( - "movq %5,%%r10; movq %6,%%r8;" TRAP_INSTR - : "=a" (ret) - : "a" ((unsigned long)hypercall.op), - "D" ((unsigned long)hypercall.arg[0]), - "S" ((unsigned long)hypercall.arg[1]), - "d" ((unsigned long)hypercall.arg[2]), - "g" ((unsigned long)hypercall.arg[3]), - "g" ((unsigned long)hypercall.arg[4]) - : "r11","rcx","r8","r10","memory"); + { + long ign1, ign2, ign3; + __asm__ __volatile__ ( + "movq %8,%%r10; movq %9,%%r8;" + "shlq $5,%%rax ;" + "addq $hypercall_page,%%rax ;" + "call *%%rax" + : "=a" (ret), "=D" (ign1), + "=S" (ign2), "=d" (ign3) + : "0" ((unsigned long)hypercall.op), + "1" ((unsigned long)hypercall.arg[0]), + "2" ((unsigned long)hypercall.arg[1]), + "3" ((unsigned long)hypercall.arg[2]), + "g" ((unsigned long)hypercall.arg[3]), + "g" ((unsigned long)hypercall.arg[4]) + : "r8", "r10", "memory" ); + } +#elif defined (__ia64__) + __asm__ __volatile__ ( + ";; mov r14=%2; mov r15=%3; " + "mov r16=%4; mov r17=%5; mov r18=%6;" + "mov r2=%1; break 0x1000;; mov %0=r8 ;;" + : "=r" (ret) + : "r" (hypercall.op), + "r" (hypercall.arg[0]), + "r" (hypercall.arg[1]), + "r" (hypercall.arg[2]), + "r" (hypercall.arg[3]), + "r" (hypercall.arg[4]) + : "r14","r15","r16","r17","r18","r2","r8","memory"); #endif - } - break; - - case IOCTL_PRIVCMD_INITDOMAIN_EVTCHN: - { - extern int initdom_ctrlif_domcontroller_port; - ret = initdom_ctrlif_domcontroller_port; - } - break; - + } + break; + #if defined(CONFIG_XEN_PRIVILEGED_GUEST) - case IOCTL_PRIVCMD_MMAP: - { + case IOCTL_PRIVCMD_MMAP: { #define PRIVCMD_MMAP_SZ 32 - privcmd_mmap_t mmapcmd; - privcmd_mmap_entry_t msg[PRIVCMD_MMAP_SZ], *p; - int i, rc; - - if ( copy_from_user(&mmapcmd, (void *)data, sizeof(mmapcmd)) ) - return -EFAULT; + privcmd_mmap_t mmapcmd; + privcmd_mmap_entry_t msg[PRIVCMD_MMAP_SZ]; + privcmd_mmap_entry_t __user *p; + int i, rc; - p = mmapcmd.entry; + if (copy_from_user(&mmapcmd, udata, sizeof(mmapcmd))) + return -EFAULT; - for (i=0; iPRIVCMD_MMAP_SZ)? - PRIVCMD_MMAP_SZ:(mmapcmd.num-i); + p = mmapcmd.entry; + for (i = 0; i < mmapcmd.num; + i += PRIVCMD_MMAP_SZ, p += PRIVCMD_MMAP_SZ) { + int j, n = ((mmapcmd.num-i)>PRIVCMD_MMAP_SZ)? + PRIVCMD_MMAP_SZ:(mmapcmd.num-i); - if ( copy_from_user(&msg, p, n*sizeof(privcmd_mmap_entry_t)) ) - return -EFAULT; + if (copy_from_user(&msg, p, + n*sizeof(privcmd_mmap_entry_t))) + return -EFAULT; - for ( j = 0; j < n; j++ ) - { - struct vm_area_struct *vma = - find_vma( current->mm, msg[j].va ); - - if ( !vma ) - return -EINVAL; - - if ( msg[j].va > PAGE_OFFSET ) - return -EINVAL; - - if ( (msg[j].va + (msg[j].npages< vma->vm_end ) - return -EINVAL; - - if ( (rc = direct_remap_area_pages(vma->vm_mm, - msg[j].va&PAGE_MASK, - msg[j].mfn<vm_page_prot, - mmapcmd.dom)) < 0 ) - return rc; - } - } - ret = 0; - } - break; - - case IOCTL_PRIVCMD_MMAPBATCH: - { - mmu_update_t u; - privcmd_mmapbatch_t m; - struct vm_area_struct *vma = NULL; - unsigned long *p, addr; - unsigned long mfn; - int i; - - if ( copy_from_user(&m, (void *)data, sizeof(m)) ) - { ret = -EFAULT; goto batch_err; } - - vma = find_vma( current->mm, m.addr ); - - if ( !vma ) - { ret = -EINVAL; goto batch_err; } - - if ( m.addr > PAGE_OFFSET ) - { ret = -EFAULT; goto batch_err; } - - if ( (m.addr + (m.num< vma->vm_end ) - { ret = -EFAULT; goto batch_err; } - - p = m.arr; - addr = m.addr; - for ( i = 0; i < m.num; i++, addr += PAGE_SIZE, p++ ) - { - if ( get_user(mfn, p) ) - return -EFAULT; - - u.val = (mfn << PAGE_SHIFT) | pgprot_val(vma->vm_page_prot); - - __direct_remap_area_pages(vma->vm_mm, - addr, - PAGE_SIZE, - &u); - - if ( unlikely(HYPERVISOR_mmu_update(&u, 1, NULL, m.dom) < 0) ) - put_user(0xF0000000 | mfn, p); - } - - ret = 0; - break; - - batch_err: - printk("batch_err ret=%d vma=%p addr=%lx num=%d arr=%p %lx-%lx\n", - ret, vma, m.addr, m.num, m.arr, - vma ? vma->vm_start : 0, vma ? vma->vm_end : 0); - break; - } - break; + for (j = 0; j < n; j++) { + struct vm_area_struct *vma = + find_vma( current->mm, msg[j].va ); + + if (!vma) + return -EINVAL; + + if (msg[j].va > PAGE_OFFSET) + return -EINVAL; + + if ((msg[j].va + (msg[j].npages << PAGE_SHIFT)) + > vma->vm_end ) + return -EINVAL; + + if ((rc = direct_remap_pfn_range( + vma, + msg[j].va&PAGE_MASK, + msg[j].mfn, + msg[j].npages<vm_page_prot, + mmapcmd.dom)) < 0) + return rc; + } + } + ret = 0; + } + break; + + case IOCTL_PRIVCMD_MMAPBATCH: { + privcmd_mmapbatch_t m; + struct vm_area_struct *vma = NULL; + xen_pfn_t __user *p; + unsigned long addr, mfn; + int i; + + if (copy_from_user(&m, udata, sizeof(m))) { + ret = -EFAULT; + goto batch_err; + } + + if (m.dom == DOMID_SELF) { + ret = -EINVAL; + goto batch_err; + } + + vma = find_vma(current->mm, m.addr); + if (!vma) { + ret = -EINVAL; + goto batch_err; + } + + if (m.addr > PAGE_OFFSET) { + ret = -EFAULT; + goto batch_err; + } + + if ((m.addr + (m.num< vma->vm_end) { + ret = -EFAULT; + goto batch_err; + } + + p = m.arr; + addr = m.addr; + for (i = 0; i < m.num; i++, addr += PAGE_SIZE, p++) { + if (get_user(mfn, p)) + return -EFAULT; + + ret = direct_remap_pfn_range(vma, addr & PAGE_MASK, + mfn, PAGE_SIZE, + vma->vm_page_prot, m.dom); + if (ret < 0) + put_user(0xF0000000 | mfn, p); + } + + ret = 0; + break; + + batch_err: + printk("batch_err ret=%d vma=%p addr=%lx " + "num=%d arr=%p %lx-%lx\n", + ret, vma, (unsigned long)m.addr, m.num, m.arr, + vma ? vma->vm_start : 0, vma ? vma->vm_end : 0); + break; + } + break; #endif - case IOCTL_PRIVCMD_GET_MACH2PHYS_START_MFN: - { - unsigned long m2pv = (unsigned long)machine_to_phys_mapping; - pgd_t *pgd = pgd_offset_k(m2pv); - pud_t *pud = pud_offset(pgd, m2pv); - pmd_t *pmd = pmd_offset(pud, m2pv); - unsigned long m2p_start_mfn = (*(unsigned long *)pmd) >> PAGE_SHIFT; - ret = put_user(m2p_start_mfn, (unsigned long *)data) ? -EFAULT: 0; - } - break; - - default: - ret = -EINVAL; - break; - } - return ret; + default: + ret = -EINVAL; + break; + } + + return ret; } +#ifndef HAVE_ARCH_PRIVCMD_MMAP static int privcmd_mmap(struct file * file, struct vm_area_struct * vma) { - /* DONTCOPY is essential for Xen as copy_page_range is broken. */ - vma->vm_flags |= VM_RESERVED | VM_IO | VM_DONTCOPY; + /* DONTCOPY is essential for Xen as copy_page_range is broken. */ + vma->vm_flags |= VM_RESERVED | VM_IO | VM_DONTCOPY; - return 0; + return 0; } +#endif static struct file_operations privcmd_file_ops = { - ioctl : privcmd_ioctl, - mmap: privcmd_mmap + .ioctl = privcmd_ioctl, + .mmap = privcmd_mmap, }; - -static int __init privcmd_init(void) +static int capabilities_read(char *page, char **start, off_t off, + int count, int *eof, void *data) { - if ( !(xen_start_info.flags & SIF_PRIVILEGED) ) - return 0; + int len = 0; + *page = 0; - privcmd_intf = create_xen_proc_entry("privcmd", 0400); - if ( privcmd_intf != NULL ) - privcmd_intf->proc_fops = &privcmd_file_ops; + if (xen_start_info->flags & SIF_INITDOMAIN) + len = sprintf( page, "control_d\n" ); - return 0; + *eof = 1; + return len; +} + +static int __init privcmd_init(void) +{ + if (!is_running_on_xen()) + return -ENODEV; + + /* Set of hypercalls that privileged applications may execute. */ + set_bit(__HYPERVISOR_acm_op, hypercall_permission_map); + set_bit(__HYPERVISOR_dom0_op, hypercall_permission_map); + set_bit(__HYPERVISOR_event_channel_op, hypercall_permission_map); + set_bit(__HYPERVISOR_memory_op, hypercall_permission_map); + set_bit(__HYPERVISOR_mmu_update, hypercall_permission_map); + set_bit(__HYPERVISOR_mmuext_op, hypercall_permission_map); + set_bit(__HYPERVISOR_xen_version, hypercall_permission_map); + set_bit(__HYPERVISOR_sched_op, hypercall_permission_map); + set_bit(__HYPERVISOR_sched_op_compat, hypercall_permission_map); + set_bit(__HYPERVISOR_event_channel_op_compat, + hypercall_permission_map); + set_bit(__HYPERVISOR_hvm_op, hypercall_permission_map); + + privcmd_intf = create_xen_proc_entry("privcmd", 0400); + if (privcmd_intf != NULL) + privcmd_intf->proc_fops = &privcmd_file_ops; + + capabilities_intf = create_xen_proc_entry("capabilities", 0400 ); + if (capabilities_intf != NULL) + capabilities_intf->read_proc = capabilities_read; + + return 0; } __initcall(privcmd_init); diff --git a/fs/Kconfig b/fs/Kconfig index 0167990d8..1d0cf4054 100644 --- a/fs/Kconfig +++ b/fs/Kconfig @@ -842,6 +842,7 @@ config TMPFS config HUGETLBFS bool "HugeTLB file system support" depends X86 || IA64 || PPC64 || SPARC64 || SUPERH || BROKEN + depends !XEN help hugetlbfs is a filesystem backing for HugeTLB pages, based on ramfs. For architectures that support it, say Y here and read diff --git a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c index 68ebd10f3..aa50dc692 100644 --- a/fs/befs/linuxvfs.c +++ b/fs/befs/linuxvfs.c @@ -512,7 +512,11 @@ befs_utf2nls(struct super_block *sb, const char *in, wchar_t uni; int unilen, utflen; char *result; - int maxlen = in_len; /* The utf8->nls conversion can't make more chars */ + /* The utf8->nls conversion won't make the final nls string bigger + * than the utf one, but if the string is pure ascii they'll have the + * same width and an extra char is needed to save the additional \0 + */ + int maxlen = in_len + 1; befs_debug(sb, "---> utf2nls()"); @@ -588,7 +592,10 @@ befs_nls2utf(struct super_block *sb, const char *in, wchar_t uni; int unilen, utflen; char *result; - int maxlen = 3 * in_len; + /* There're nls characters that will translate to 3-chars-wide UTF-8 + * characters, a additional byte is needed to save the final \0 + * in special cases */ + int maxlen = (3 * in_len) + 1; befs_debug(sb, "---> nls2utf()\n"); diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 093645b22..479ee5fde 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -88,7 +88,7 @@ static struct linux_binfmt elf_format = { .min_coredump = ELF_EXEC_PAGESIZE }; -#define BAD_ADDR(x) ((unsigned long)(x) > PAGE_MASK) +#define BAD_ADDR(x) ((unsigned long)(x) >= PAGE_MASK) static int set_brk(unsigned long start, unsigned long end) { @@ -441,7 +441,7 @@ static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex, * <= p_memsize so it is only necessary to check p_memsz. */ k = load_addr + eppnt->p_vaddr; - if (k > TASK_SIZE || eppnt->p_filesz > eppnt->p_memsz || + if (BAD_ADDR(k) || eppnt->p_filesz > eppnt->p_memsz || eppnt->p_memsz > TASK_SIZE || TASK_SIZE - eppnt->p_memsz < k) { error = -ENOMEM; goto out_close; @@ -944,7 +944,7 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) * allowed task size. Note that p_filesz must always be * <= p_memsz so it is only necessary to check p_memsz. */ - if (k > TASK_SIZE || elf_ppnt->p_filesz > elf_ppnt->p_memsz || + if (BAD_ADDR(k) || elf_ppnt->p_filesz > elf_ppnt->p_memsz || elf_ppnt->p_memsz > TASK_SIZE || TASK_SIZE - elf_ppnt->p_memsz < k) { /* set_brk can never work. Avoid overflows. */ @@ -1005,10 +1005,9 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) } } if (BAD_ADDR(elf_entry)) { - printk(KERN_ERR "Unable to load interpreter %.128s\n", - elf_interpreter); force_sig(SIGSEGV, current); - retval = -ENOEXEC; /* Nobody gets to see this, but.. */ + retval = IS_ERR((void *)elf_entry) ? + (int)elf_entry : -EINVAL; goto out_free_dentry; } reloc_func_desc = interp_load_addr; @@ -1019,8 +1018,8 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) } else { elf_entry = loc->elf_ex.e_entry; if (BAD_ADDR(elf_entry)) { - send_sig(SIGSEGV, current, 0); - retval = -ENOEXEC; /* Nobody gets to see this, but.. */ + force_sig(SIGSEGV, current); + retval = -EINVAL; goto out_free_dentry; } } diff --git a/fs/buffer.c b/fs/buffer.c index 23f1f3a68..7f6d65925 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -473,13 +473,18 @@ out: pass does the actual I/O. */ void invalidate_bdev(struct block_device *bdev, int destroy_dirty_buffers) { + struct address_space *mapping = bdev->bd_inode->i_mapping; + + if (mapping->nrpages == 0) + return; + invalidate_bh_lrus(); /* * FIXME: what about destroy_dirty_buffers? * We really want to use invalidate_inode_pages2() for * that, but not until that's cleaned up. */ - invalidate_inode_pages(bdev->bd_inode->i_mapping); + invalidate_inode_pages(mapping); } /* diff --git a/fs/ext2/super.c b/fs/ext2/super.c index f05b2cff4..22993252e 100644 --- a/fs/ext2/super.c +++ b/fs/ext2/super.c @@ -252,6 +252,46 @@ static struct super_operations ext2_sops = { #endif }; +static struct dentry *ext2_get_dentry(struct super_block *sb, void *vobjp) +{ + __u32 *objp = vobjp; + unsigned long ino = objp[0]; + __u32 generation = objp[1]; + struct inode *inode; + struct dentry *result; + + if (ino != EXT2_ROOT_INO && ino < EXT2_FIRST_INO(sb)) + return ERR_PTR(-ESTALE); + if (ino > le32_to_cpu(EXT2_SB(sb)->s_es->s_inodes_count)) + return ERR_PTR(-ESTALE); + + /* iget isn't really right if the inode is currently unallocated!! + * ext2_read_inode currently does appropriate checks, but + * it might be "neater" to call ext2_get_inode first and check + * if the inode is valid..... + */ + inode = iget(sb, ino); + if (inode == NULL) + return ERR_PTR(-ENOMEM); + if (is_bad_inode(inode) + || (generation && inode->i_generation != generation) + ) { + /* we didn't find the right inode.. */ + iput(inode); + return ERR_PTR(-ESTALE); + } + /* now to find a dentry. + * If possible, get a well-connected one + */ + result = d_alloc_anon(inode); + if (!result) { + iput(inode); + return ERR_PTR(-ENOMEM); + } + return result; +} + + /* Yes, most of these are left as NULL!! * A NULL value implies the default, which works with ext2-like file * systems, but can be improved upon. @@ -259,6 +299,7 @@ static struct super_operations ext2_sops = { */ static struct export_operations ext2_export_ops = { .get_parent = ext2_get_parent, + .get_dentry = ext2_get_dentry, }; static unsigned long get_sb_block(void **data) diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c index bdd65f45d..4ce217b6d 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c @@ -1160,7 +1160,7 @@ retry: ret = PTR_ERR(handle); goto out; } - if (test_opt(inode->i_sb, NOBH)) + if (test_opt(inode->i_sb, NOBH) && ext3_should_writeback_data(inode)) ret = nobh_prepare_write(page, from, to, ext3_get_block); else ret = block_prepare_write(page, from, to, ext3_get_block); @@ -1246,7 +1246,7 @@ static int ext3_writeback_commit_write(struct file *file, struct page *page, if (new_i_size > EXT3_I(inode)->i_disksize) EXT3_I(inode)->i_disksize = new_i_size; - if (test_opt(inode->i_sb, NOBH)) + if (test_opt(inode->i_sb, NOBH) && ext3_should_writeback_data(inode)) ret = nobh_commit_write(file, page, from, to); else ret = generic_commit_write(file, page, from, to); @@ -1496,7 +1496,7 @@ static int ext3_writeback_writepage(struct page *page, goto out_fail; } - if (test_opt(inode->i_sb, NOBH)) + if (test_opt(inode->i_sb, NOBH) && ext3_should_writeback_data(inode)) ret = nobh_writepage(page, ext3_get_block, wbc); else ret = block_write_full_page(page, ext3_get_block, wbc); @@ -2403,14 +2403,15 @@ static unsigned long ext3_get_inode_block(struct super_block *sb, struct buffer_head *bh; struct ext3_group_desc * gdp; - - if ((ino != EXT3_ROOT_INO && ino != EXT3_JOURNAL_INO && - ino != EXT3_RESIZE_INO && ino < EXT3_FIRST_INO(sb)) || - ino > le32_to_cpu(EXT3_SB(sb)->s_es->s_inodes_count)) { - ext3_error(sb, "ext3_get_inode_block", - "bad inode number: %lu", ino); + if (!ext3_valid_inum(sb, ino)) { + /* + * This error is already checked for in namei.c unless we are + * looking at an NFS filehandle, in which case no error + * report is needed + */ return 0; } + block_group = (ino - 1) / EXT3_INODES_PER_GROUP(sb); if (block_group >= EXT3_SB(sb)->s_groups_count) { ext3_error(sb,"ext3_get_inode_block","group >= groups count"); diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c index 329eae367..045f58812 100644 --- a/fs/ext3/namei.c +++ b/fs/ext3/namei.c @@ -1001,7 +1001,12 @@ static struct dentry *ext3_lookup(struct inode * dir, struct dentry *dentry, str if (bh) { unsigned long ino = le32_to_cpu(de->inode); brelse (bh); - inode = iget(dir->i_sb, ino); + if (!ext3_valid_inum(dir->i_sb, ino)) { + ext3_error(dir->i_sb, "ext3_lookup", + "bad inode number: %lu", ino); + inode = NULL; + } else + inode = iget(dir->i_sb, ino); if (!inode) return ERR_PTR(-EACCES); @@ -1030,7 +1035,13 @@ struct dentry *ext3_get_parent(struct dentry *child) return ERR_PTR(-ENOENT); ino = le32_to_cpu(de->inode); brelse(bh); - inode = iget(child->d_inode->i_sb, ino); + + if (!ext3_valid_inum(child->d_inode->i_sb, ino)) { + ext3_error(child->d_inode->i_sb, "ext3_get_parent", + "bad inode number: %lu", ino); + inode = NULL; + } else + inode = iget(child->d_inode->i_sb, ino); if (!inode) return ERR_PTR(-EACCES); diff --git a/fs/ext3/super.c b/fs/ext3/super.c index 2a0cb4ca8..ed22106c9 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c @@ -620,8 +620,48 @@ static struct super_operations ext3_sops = { #endif }; +static struct dentry *ext3_get_dentry(struct super_block *sb, void *vobjp) +{ + __u32 *objp = vobjp; + unsigned long ino = objp[0]; + __u32 generation = objp[1]; + struct inode *inode; + struct dentry *result; + + if (ino != EXT3_ROOT_INO && ino < EXT3_FIRST_INO(sb)) + return ERR_PTR(-ESTALE); + if (ino > le32_to_cpu(EXT3_SB(sb)->s_es->s_inodes_count)) + return ERR_PTR(-ESTALE); + + /* iget isn't really right if the inode is currently unallocated!! + * ext3_read_inode currently does appropriate checks, but + * it might be "neater" to call ext3_get_inode first and check + * if the inode is valid..... + */ + inode = iget(sb, ino); + if (inode == NULL) + return ERR_PTR(-ENOMEM); + if (is_bad_inode(inode) + || (generation && inode->i_generation != generation) + ) { + /* we didn't find the right inode.. */ + iput(inode); + return ERR_PTR(-ESTALE); + } + /* now to find a dentry. + * If possible, get a well-connected one + */ + result = d_alloc_anon(inode); + if (!result) { + iput(inode); + return ERR_PTR(-ENOMEM); + } + return result; +} + static struct export_operations ext3_export_ops = { .get_parent = ext3_get_parent, + .get_dentry = ext3_get_dentry, }; enum { diff --git a/fs/file.c b/fs/file.c index 55f4e7022..4c2cacca4 100644 --- a/fs/file.c +++ b/fs/file.c @@ -277,11 +277,13 @@ static struct fdtable *alloc_fdtable(int nr) } while (nfds <= nr); new_fds = alloc_fd_array(nfds); if (!new_fds) - goto out; + goto out2; fdt->fd = new_fds; fdt->max_fds = nfds; fdt->free_files = NULL; return fdt; +out2: + nfds = fdt->max_fdset; out: if (new_openset) free_fdset(new_openset, nfds); diff --git a/fs/locks.c b/fs/locks.c index 7ec121cb3..718983409 100644 --- a/fs/locks.c +++ b/fs/locks.c @@ -1409,8 +1409,9 @@ static int __setlease(struct file *filp, long arg, struct file_lock **flp) if (!leases_enable) goto out; - error = lease_alloc(filp, arg, &fl); - if (error) + error = -ENOMEM; + fl = locks_alloc_lock(); + if (fl == NULL) goto out; locks_copy_lock(fl, lease); @@ -1418,6 +1419,7 @@ static int __setlease(struct file *filp, long arg, struct file_lock **flp) locks_insert_lock(before, fl); *flp = fl; + error = 0; out: return error; } diff --git a/fs/namei.c b/fs/namei.c index 181922326..178e70e79 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -1773,8 +1773,14 @@ do_link: if (error) goto exit_dput; error = __do_follow_link(&path, nd); - if (error) + if (error) { + /* Does someone understand code flow here? Or it is only + * me so stupid? Anathema to whoever designed this non-sense + * with "intent.open". + */ + release_open_intent(nd); return error; + } nd->flags &= ~LOOKUP_PARENT; if (nd->last_type == LAST_BIND) goto ok; diff --git a/fs/proc/base.c b/fs/proc/base.c index 8c880128d..f6e0c6274 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -631,6 +631,27 @@ static int proc_permission(struct inode *inode, int mask, struct nameidata *nd) return proc_check_root(inode); } +static int proc_setattr(struct dentry *dentry, struct iattr *attr) +{ + int error; + struct inode *inode = dentry->d_inode; + + if (attr->ia_valid & ATTR_MODE) + return -EPERM; + + error = inode_change_ok(inode, attr); + if (!error) { + error = security_inode_setattr(dentry, attr); + if (!error) + error = inode_setattr(inode, attr); + } + return error; +} + +static struct inode_operations proc_def_inode_operations = { + .setattr = proc_setattr, +}; + static int proc_task_permission(struct inode *inode, int mask, struct nameidata *nd) { struct dentry *root; @@ -1022,6 +1043,7 @@ static struct file_operations proc_oom_adjust_operations = { static struct inode_operations proc_mem_inode_operations = { .permission = proc_permission, + .setattr = proc_setattr, }; #ifdef CONFIG_AUDITSYSCALL @@ -1219,7 +1241,8 @@ out: static struct inode_operations proc_pid_link_inode_operations = { .readlink = proc_pid_readlink, - .follow_link = proc_pid_follow_link + .follow_link = proc_pid_follow_link, + .setattr = proc_setattr, }; #define NUMBUF 10 @@ -1400,6 +1423,7 @@ static struct inode *proc_pid_make_inode(struct super_block * sb, struct task_st ei->task = NULL; inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; inode->i_ino = fake_ino(task->pid, ino); + inode->i_op = &proc_def_inode_operations; if (!pid_alive(task)) goto out_unlock; @@ -1455,6 +1479,7 @@ static int pid_revalidate(struct dentry *dentry, struct nameidata *nd) inode->i_uid = 0; inode->i_gid = 0; } + inode->i_mode &= ~(S_ISUID | S_ISGID); security_task_to_inode(task, inode); return 1; } @@ -1483,6 +1508,7 @@ static int tid_fd_revalidate(struct dentry *dentry, struct nameidata *nd) inode->i_uid = 0; inode->i_gid = 0; } + inode->i_mode &= ~(S_ISUID | S_ISGID); security_task_to_inode(task, inode); return 1; } @@ -1628,11 +1654,13 @@ static struct file_operations proc_task_operations = { static struct inode_operations proc_fd_inode_operations = { .lookup = proc_lookupfd, .permission = proc_permission, + .setattr = proc_setattr, }; static struct inode_operations proc_task_inode_operations = { .lookup = proc_task_lookup, .permission = proc_task_permission, + .setattr = proc_setattr, }; #ifdef CONFIG_SECURITY @@ -1943,10 +1971,12 @@ static struct file_operations proc_tid_base_operations = { static struct inode_operations proc_tgid_base_inode_operations = { .lookup = proc_tgid_base_lookup, + .setattr = proc_setattr, }; static struct inode_operations proc_tid_base_inode_operations = { .lookup = proc_tid_base_lookup, + .setattr = proc_setattr, }; #ifdef CONFIG_SECURITY @@ -1988,10 +2018,12 @@ static struct dentry *proc_tid_attr_lookup(struct inode *dir, static struct inode_operations proc_tgid_attr_inode_operations = { .lookup = proc_tgid_attr_lookup, + .setattr = proc_setattr, }; static struct inode_operations proc_tid_attr_inode_operations = { .lookup = proc_tid_attr_lookup, + .setattr = proc_setattr, }; #endif @@ -2016,6 +2048,7 @@ static void *proc_self_follow_link(struct dentry *dentry, struct nameidata *nd) static struct inode_operations proc_self_inode_operations = { .readlink = proc_self_readlink, .follow_link = proc_self_follow_link, + .setattr = proc_setattr, }; /** diff --git a/fs/splice.c b/fs/splice.c index a285fd746..8fef6672b 100644 --- a/fs/splice.c +++ b/fs/splice.c @@ -1294,6 +1294,85 @@ asmlinkage long sys_splice(int fd_in, loff_t __user *off_in, return error; } +/* + * Make sure there's data to read. Wait for input if we can, otherwise + * return an appropriate error. + */ +static int link_ipipe_prep(struct pipe_inode_info *pipe, unsigned int flags) +{ + int ret; + + /* + * Check ->nrbufs without the inode lock first. This function + * is speculative anyways, so missing one is ok. + */ + if (pipe->nrbufs) + return 0; + + ret = 0; + mutex_lock(&pipe->inode->i_mutex); + + while (!pipe->nrbufs) { + if (signal_pending(current)) { + ret = -ERESTARTSYS; + break; + } + if (!pipe->writers) + break; + if (!pipe->waiting_writers) { + if (flags & SPLICE_F_NONBLOCK) { + ret = -EAGAIN; + break; + } + } + pipe_wait(pipe); + } + + mutex_unlock(&pipe->inode->i_mutex); + return ret; +} + +/* + * Make sure there's writeable room. Wait for room if we can, otherwise + * return an appropriate error. + */ +static int link_opipe_prep(struct pipe_inode_info *pipe, unsigned int flags) +{ + int ret; + + /* + * Check ->nrbufs without the inode lock first. This function + * is speculative anyways, so missing one is ok. + */ + if (pipe->nrbufs < PIPE_BUFFERS) + return 0; + + ret = 0; + mutex_lock(&pipe->inode->i_mutex); + + while (pipe->nrbufs >= PIPE_BUFFERS) { + if (!pipe->readers) { + send_sig(SIGPIPE, current, 0); + ret = -EPIPE; + break; + } + if (flags & SPLICE_F_NONBLOCK) { + ret = -EAGAIN; + break; + } + if (signal_pending(current)) { + ret = -ERESTARTSYS; + break; + } + pipe->waiting_writers++; + pipe_wait(pipe); + pipe->waiting_writers--; + } + + mutex_unlock(&pipe->inode->i_mutex); + return ret; +} + /* * Link contents of ipipe to opipe. */ @@ -1302,9 +1381,7 @@ static int link_pipe(struct pipe_inode_info *ipipe, size_t len, unsigned int flags) { struct pipe_buffer *ibuf, *obuf; - int ret, do_wakeup, i, ipipe_first; - - ret = do_wakeup = ipipe_first = 0; + int ret = 0, i = 0, nbuf; /* * Potential ABBA deadlock, work around it by ordering lock @@ -1312,7 +1389,6 @@ static int link_pipe(struct pipe_inode_info *ipipe, * could deadlock (one doing tee from A -> B, the other from B -> A). */ if (ipipe->inode < opipe->inode) { - ipipe_first = 1; mutex_lock(&ipipe->inode->i_mutex); mutex_lock(&opipe->inode->i_mutex); } else { @@ -1320,118 +1396,55 @@ static int link_pipe(struct pipe_inode_info *ipipe, mutex_lock(&ipipe->inode->i_mutex); } - for (i = 0;; i++) { + do { if (!opipe->readers) { send_sig(SIGPIPE, current, 0); if (!ret) ret = -EPIPE; break; } - if (ipipe->nrbufs - i) { - ibuf = ipipe->bufs + ((ipipe->curbuf + i) & (PIPE_BUFFERS - 1)); - /* - * If we have room, fill this buffer - */ - if (opipe->nrbufs < PIPE_BUFFERS) { - int nbuf = (opipe->curbuf + opipe->nrbufs) & (PIPE_BUFFERS - 1); - - /* - * Get a reference to this pipe buffer, - * so we can copy the contents over. - */ - ibuf->ops->get(ipipe, ibuf); - - obuf = opipe->bufs + nbuf; - *obuf = *ibuf; - - /* - * Don't inherit the gift flag, we need to - * prevent multiple steals of this page. - */ - obuf->flags &= ~PIPE_BUF_FLAG_GIFT; - - if (obuf->len > len) - obuf->len = len; - - opipe->nrbufs++; - do_wakeup = 1; - ret += obuf->len; - len -= obuf->len; - - if (!len) - break; - if (opipe->nrbufs < PIPE_BUFFERS) - continue; - } - - /* - * We have input available, but no output room. - * If we already copied data, return that. If we - * need to drop the opipe lock, it must be ordered - * last to avoid deadlocks. - */ - if ((flags & SPLICE_F_NONBLOCK) || !ipipe_first) { - if (!ret) - ret = -EAGAIN; - break; - } - if (signal_pending(current)) { - if (!ret) - ret = -ERESTARTSYS; - break; - } - if (do_wakeup) { - smp_mb(); - if (waitqueue_active(&opipe->wait)) - wake_up_interruptible(&opipe->wait); - kill_fasync(&opipe->fasync_readers, SIGIO, POLL_IN); - do_wakeup = 0; - } + /* + * If we have iterated all input buffers or ran out of + * output room, break. + */ + if (i >= ipipe->nrbufs || opipe->nrbufs >= PIPE_BUFFERS) + break; - opipe->waiting_writers++; - pipe_wait(opipe); - opipe->waiting_writers--; - continue; - } + ibuf = ipipe->bufs + ((ipipe->curbuf + i) & (PIPE_BUFFERS - 1)); + nbuf = (opipe->curbuf + opipe->nrbufs) & (PIPE_BUFFERS - 1); /* - * No input buffers, do the usual checks for available - * writers and blocking and wait if necessary + * Get a reference to this pipe buffer, + * so we can copy the contents over. */ - if (!ipipe->writers) - break; - if (!ipipe->waiting_writers) { - if (ret) - break; - } + ibuf->ops->get(ipipe, ibuf); + + obuf = opipe->bufs + nbuf; + *obuf = *ibuf; + /* - * pipe_wait() drops the ipipe mutex. To avoid deadlocks - * with another process, we can only safely do that if - * the ipipe lock is ordered last. + * Don't inherit the gift flag, we need to + * prevent multiple steals of this page. */ - if ((flags & SPLICE_F_NONBLOCK) || ipipe_first) { - if (!ret) - ret = -EAGAIN; - break; - } - if (signal_pending(current)) { - if (!ret) - ret = -ERESTARTSYS; - break; - } + obuf->flags &= ~PIPE_BUF_FLAG_GIFT; - if (waitqueue_active(&ipipe->wait)) - wake_up_interruptible_sync(&ipipe->wait); - kill_fasync(&ipipe->fasync_writers, SIGIO, POLL_OUT); + if (obuf->len > len) + obuf->len = len; - pipe_wait(ipipe); - } + opipe->nrbufs++; + ret += obuf->len; + len -= obuf->len; + i++; + } while (len); mutex_unlock(&ipipe->inode->i_mutex); mutex_unlock(&opipe->inode->i_mutex); - if (do_wakeup) { + /* + * If we put data in the output pipe, wakeup any potential readers. + */ + if (ret > 0) { smp_mb(); if (waitqueue_active(&opipe->wait)) wake_up_interruptible(&opipe->wait); @@ -1452,14 +1465,29 @@ static long do_tee(struct file *in, struct file *out, size_t len, { struct pipe_inode_info *ipipe = in->f_dentry->d_inode->i_pipe; struct pipe_inode_info *opipe = out->f_dentry->d_inode->i_pipe; + int ret = -EINVAL; /* - * Link ipipe to the two output pipes, consuming as we go along. + * Duplicate the contents of ipipe to opipe without actually + * copying the data. */ - if (ipipe && opipe) - return link_pipe(ipipe, opipe, len, flags); + if (ipipe && opipe && ipipe != opipe) { + /* + * Keep going, unless we encounter an error. The ipipe/opipe + * ordering doesn't really matter. + */ + ret = link_ipipe_prep(ipipe, flags); + if (!ret) { + ret = link_opipe_prep(opipe, flags); + if (!ret) { + ret = link_pipe(ipipe, opipe, len, flags); + if (!ret && (flags & SPLICE_F_NONBLOCK)) + ret = -EAGAIN; + } + } + } - return -EINVAL; + return ret; } asmlinkage long sys_tee(int fdin, int fdout, size_t len, unsigned int flags) diff --git a/fs/udf/super.c b/fs/udf/super.c index e45789fe3..73fc0d8ae 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c @@ -1653,7 +1653,7 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) iput(inode); goto error_out; } - sb->s_maxbytes = MAX_LFS_FILESIZE; + sb->s_maxbytes = 1<<30; return 0; error_out: diff --git a/fs/udf/truncate.c b/fs/udf/truncate.c index e1b0e8cfe..0abd66ce3 100644 --- a/fs/udf/truncate.c +++ b/fs/udf/truncate.c @@ -239,37 +239,51 @@ void udf_truncate_extents(struct inode * inode) { if (offset) { - 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); + /* + * 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); } - else if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30)) - { - kernel_lb_addr neloc = { 0, 0 }; + else { extoffset -= adsize; - 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)) + 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)) { + kernel_lb_addr neloc = { 0, 0 }; extoffset -= adsize; - elen = EXT_RECORDED_ALLOCATED | - ((elen + inode->i_sb->s_blocksize - 1) & + 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, eloc, elen, bh, 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); } - 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/fs/xfs/xfs_dir2_node.c b/fs/xfs/xfs_dir2_node.c index ac511ab9c..0655cc3cb 100644 --- a/fs/xfs/xfs_dir2_node.c +++ b/fs/xfs/xfs_dir2_node.c @@ -970,7 +970,7 @@ xfs_dir2_leafn_remove( /* * One less used entry in the free table. */ - free->hdr.nused = cpu_to_be32(-1); + be32_add(&free->hdr.nused, -1); xfs_dir2_free_log_header(tp, fbp); /* * If this was the last entry in the table, we can diff --git a/include/asm-generic/mman.h b/include/asm-generic/mman.h index 3b41d2bb7..010ced7cf 100644 --- a/include/asm-generic/mman.h +++ b/include/asm-generic/mman.h @@ -39,4 +39,10 @@ #define MAP_ANON MAP_ANONYMOUS #define MAP_FILE 0 +#ifdef __KERNEL__ +#ifndef arch_mmap_check +#define arch_mmap_check(addr, len, flags) (0) +#endif +#endif + #endif diff --git a/include/asm-i386/apic.h b/include/asm-i386/apic.h index 288233fd7..87476de38 100644 --- a/include/asm-i386/apic.h +++ b/include/asm-i386/apic.h @@ -132,10 +132,12 @@ extern unsigned int nmi_watchdog; extern int disable_timer_pin_1; +#ifndef CONFIG_XEN void smp_send_timer_broadcast_ipi(struct pt_regs *regs); void switch_APIC_timer_to_ipi(void *cpumask); void switch_ipi_to_APIC_timer(void *cpumask); #define ARCH_APICTIMER_STOPS_ON_C3 1 +#endif extern int timer_over_8254; diff --git a/include/asm-i386/desc.h b/include/asm-i386/desc.h index aa371537c..fdecfa0d1 100644 --- a/include/asm-i386/desc.h +++ b/include/asm-i386/desc.h @@ -170,7 +170,7 @@ static inline void set_user_cs(struct desc_struct *desc, unsigned long limit) } #define load_user_cs_desc(cpu, mm) \ - get_cpu_gdt_table(cpu)[GDT_ENTRY_DEFAULT_USER_CS] = (mm)->context.user_cs + get_cpu_gdt_table(cpu)[GDT_ENTRY_DEFAULT_USER_CS] = (mm)->context.user_cs extern void arch_add_exec_range(struct mm_struct *mm, unsigned long limit); extern void arch_remove_exec_range(struct mm_struct *mm, unsigned long limit); diff --git a/include/asm-i386/fixmap.h b/include/asm-i386/fixmap.h index cfb1c61d3..f11513aa9 100644 --- a/include/asm-i386/fixmap.h +++ b/include/asm-i386/fixmap.h @@ -20,7 +20,7 @@ * Leave one empty page between vmalloc'ed areas and * the start of the fixmap. */ -#define __FIXADDR_TOP 0xfffff000 +extern unsigned long __FIXADDR_TOP; #ifndef __ASSEMBLY__ #include @@ -95,6 +95,8 @@ enum fixed_addresses { extern void __set_fixmap (enum fixed_addresses idx, unsigned long phys, pgprot_t flags); +extern void set_fixaddr_top(unsigned long top); + #define set_fixmap(idx, phys) \ __set_fixmap(idx, phys, PAGE_KERNEL) /* diff --git a/include/asm-i386/mach-default/mach_traps.h b/include/asm-i386/mach-default/mach_traps.h index 625438b8a..4e34a91be 100644 --- a/include/asm-i386/mach-default/mach_traps.h +++ b/include/asm-i386/mach-default/mach_traps.h @@ -15,6 +15,18 @@ static inline void clear_mem_error(unsigned char reason) outb(reason, 0x61); } +static inline void clear_io_check_error(unsigned char reason) +{ + unsigned long i; + + reason = (reason & 0xf) | 8; + outb(reason, 0x61); + i = 2000; + while (--i) udelay(1000); + reason &= ~8; + outb(reason, 0x61); +} + static inline unsigned char get_nmi_reason(void) { return inb(0x61); diff --git a/include/asm-i386/page.h b/include/asm-i386/page.h index 104653b50..2b2683ea4 100644 --- a/include/asm-i386/page.h +++ b/include/asm-i386/page.h @@ -128,7 +128,7 @@ extern int devmem_is_allowed(unsigned long pagenr); #define PAGE_OFFSET ((unsigned long)__PAGE_OFFSET) #define VMALLOC_RESERVE ((unsigned long)__VMALLOC_RESERVE) -#define MAXMEM (-__PAGE_OFFSET-__VMALLOC_RESERVE) +#define MAXMEM (__FIXADDR_TOP-__PAGE_OFFSET-__VMALLOC_RESERVE) #define __pa(x) ((unsigned long)(x)-PAGE_OFFSET) #define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET)) #define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT) diff --git a/include/asm-i386/pgtable-2level-defs.h b/include/asm-i386/pgtable-2level-defs.h index 02518079f..bd6346f41 100644 --- a/include/asm-i386/pgtable-2level-defs.h +++ b/include/asm-i386/pgtable-2level-defs.h @@ -1,6 +1,8 @@ #ifndef _I386_PGTABLE_2LEVEL_DEFS_H #define _I386_PGTABLE_2LEVEL_DEFS_H +#define HAVE_SHARED_KERNEL_PMD 0 + /* * traditional i386 two-level paging structure: */ diff --git a/include/asm-i386/pgtable-3level-defs.h b/include/asm-i386/pgtable-3level-defs.h index eb3a1ea88..0c7599201 100644 --- a/include/asm-i386/pgtable-3level-defs.h +++ b/include/asm-i386/pgtable-3level-defs.h @@ -1,6 +1,8 @@ #ifndef _I386_PGTABLE_3LEVEL_DEFS_H #define _I386_PGTABLE_3LEVEL_DEFS_H +#define HAVE_SHARED_KERNEL_PMD 1 + /* * PGDIR_SHIFT determines what a top-level page table entry can map */ diff --git a/include/asm-i386/spinlock.h b/include/asm-i386/spinlock.h index d76b7693c..6d794a373 100644 --- a/include/asm-i386/spinlock.h +++ b/include/asm-i386/spinlock.h @@ -36,7 +36,7 @@ "\n1:\t" \ "lock ; decb %0\n\t" \ "jns 5f\n" \ - "2:\t" \ + "2:\t" \ "testl $0x200, %1\n\t" \ "jz 4f\n\t" \ "sti\n" \ diff --git a/include/asm-ia64/mman.h b/include/asm-ia64/mman.h index 6ba179f12..b242f9522 100644 --- a/include/asm-ia64/mman.h +++ b/include/asm-ia64/mman.h @@ -8,6 +8,14 @@ * David Mosberger-Tang , Hewlett-Packard Co */ +#ifdef __KERNEL__ +#ifndef __ASSEMBLY__ +#define arch_mmap_check ia64_map_check_rgn +int ia64_map_check_rgn(unsigned long addr, unsigned long len, + unsigned long flags); +#endif +#endif + #include #define MAP_GROWSDOWN 0x00100 /* stack-like segment */ diff --git a/include/asm-ia64/sn/xp.h b/include/asm-ia64/sn/xp.h index 9bd2f9bf3..6f807e019 100644 --- a/include/asm-ia64/sn/xp.h +++ b/include/asm-ia64/sn/xp.h @@ -60,23 +60,37 @@ * the bte_copy() once in the hope that the failure was due to a temporary * aberration (i.e., the link going down temporarily). * - * See bte_copy for definition of the input parameters. + * 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. * * Note: xp_bte_copy() should never be called while holding a spinlock. */ static inline bte_result_t -xp_bte_copy(u64 src, u64 dest, u64 len, u64 mode, void *notification) +xp_bte_copy(u64 src, u64 vdst, u64 len, u64 mode, void *notification) { bte_result_t ret; + u64 pdst = ia64_tpa(vdst); - ret = bte_copy(src, dest, len, mode, notification); + /* + * 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, pdst, len, mode, notification); if (ret != BTE_SUCCESS) { if (!in_interrupt()) { cond_resched(); } - ret = bte_copy(src, dest, len, mode, notification); + ret = bte_copy(src, pdst, len, mode, notification); } return ret; diff --git a/include/asm-ia64/sn/xpc.h b/include/asm-ia64/sn/xpc.h index aa3b8ace9..b454ad4e2 100644 --- a/include/asm-ia64/sn/xpc.h +++ b/include/asm-ia64/sn/xpc.h @@ -684,7 +684,9 @@ 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 char *xpc_remote_copy_buffer; +extern void *xpc_remote_copy_buffer_base; +extern void *xpc_kmalloc_cacheline_aligned(size_t, gfp_t, void **); 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/include/asm-s390/futex.h b/include/asm-s390/futex.h index 180277556..ffedf14f8 100644 --- a/include/asm-s390/futex.h +++ b/include/asm-s390/futex.h @@ -98,9 +98,10 @@ futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval) if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int))) return -EFAULT; - asm volatile(" cs %1,%4,0(%5)\n" + asm volatile(" sacf 256\n" + " cs %1,%4,0(%5)\n" "0: lr %0,%1\n" - "1:\n" + "1: sacf 0\n" #ifndef __s390x__ ".section __ex_table,\"a\"\n" " .align 4\n" diff --git a/include/asm-sparc/mman.h b/include/asm-sparc/mman.h index 88d1886ab..95ecab588 100644 --- a/include/asm-sparc/mman.h +++ b/include/asm-sparc/mman.h @@ -2,6 +2,12 @@ #ifndef __SPARC_MMAN_H__ #define __SPARC_MMAN_H__ +#ifdef __KERNEL__ +#define arch_mmap_check sparc_mmap_check +int sparc_mmap_check(unsigned long addr, unsigned long len, + unsigned long flags); +#endif + #include /* SunOS'ified... */ diff --git a/include/asm-sparc64/mman.h b/include/asm-sparc64/mman.h index 6fd878e61..b3002763c 100644 --- a/include/asm-sparc64/mman.h +++ b/include/asm-sparc64/mman.h @@ -2,6 +2,12 @@ #ifndef __SPARC64_MMAN_H__ #define __SPARC64_MMAN_H__ +#ifdef __KERNEL__ +#define arch_mmap_check sparc64_mmap_check +int sparc64_mmap_check(unsigned long addr, unsigned long len, + unsigned long flags); +#endif + #include /* SunOS'ified... */ diff --git a/include/asm-sparc64/sfp-machine.h b/include/asm-sparc64/sfp-machine.h index 5015bb8d6..89d42431e 100644 --- a/include/asm-sparc64/sfp-machine.h +++ b/include/asm-sparc64/sfp-machine.h @@ -34,7 +34,7 @@ #define _FP_MUL_MEAT_D(R,X,Y) \ _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm) #define _FP_MUL_MEAT_Q(R,X,Y) \ - _FP_MUL_MEAT_2_wide_3mul(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm) + _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm) #define _FP_DIV_MEAT_S(R,X,Y) _FP_DIV_MEAT_1_imm(S,R,X,Y,_FP_DIV_HELP_imm) #define _FP_DIV_MEAT_D(R,X,Y) _FP_DIV_MEAT_1_udiv_norm(D,R,X,Y) diff --git a/include/asm-um/page.h b/include/asm-um/page.h index 0f7229ce7..459311435 100644 --- a/include/asm-um/page.h +++ b/include/asm-um/page.h @@ -116,7 +116,7 @@ extern struct page *arch_validate(struct page *page, gfp_t mask, int order); #define HAVE_ARCH_VALIDATE #define devmem_is_allowed(x) 1 -extern void arch_free_page(struct page *page, int order); +extern int arch_free_page(struct page *page, int order); #define HAVE_ARCH_FREE_PAGE #include diff --git a/include/asm-x86_64/apic.h b/include/asm-x86_64/apic.h index bdbd89356..79db75f17 100644 --- a/include/asm-x86_64/apic.h +++ b/include/asm-x86_64/apic.h @@ -105,11 +105,13 @@ extern int disable_timer_pin_1; extern void setup_threshold_lvt(unsigned long lvt_off); +#ifndef CONFIG_XEN void smp_send_timer_broadcast_ipi(void); void switch_APIC_timer_to_ipi(void *cpumask); void switch_ipi_to_APIC_timer(void *cpumask); #define ARCH_APICTIMER_STOPS_ON_C3 1 +#endif #endif /* CONFIG_X86_LOCAL_APIC */ diff --git a/include/asm-x86_64/hw_irq.h b/include/asm-x86_64/hw_irq.h index 0df1715de..91f751ba0 100644 --- a/include/asm-x86_64/hw_irq.h +++ b/include/asm-x86_64/hw_irq.h @@ -127,7 +127,7 @@ asmlinkage void IRQ_NAME(nr); \ __asm__( \ "\n.p2align\n" \ "IRQ" #nr "_interrupt:\n\t" \ - "push $" #nr "-256 ; " \ + "push $~(" #nr ") ; " \ "jmp common_interrupt"); #if defined(CONFIG_X86_IO_APIC) diff --git a/include/asm-x86_64/ipi.h b/include/asm-x86_64/ipi.h index 2a5c162b7..be4bc7638 100644 --- a/include/asm-x86_64/ipi.h +++ b/include/asm-x86_64/ipi.h @@ -49,6 +49,7 @@ static inline int __prepare_ICR2 (unsigned int mask) return SET_APIC_DEST_FIELD(mask); } +#ifndef CONFIG_XEN_UNPRIVILEGED_GUEST static inline void __send_IPI_shortcut(unsigned int shortcut, int vector, unsigned int dest) { /* @@ -113,5 +114,6 @@ static inline void send_IPI_mask_sequence(cpumask_t mask, int vector) } local_irq_restore(flags); } +#endif /* CONFIG_XEN_UNPRIVILEGED_GUEST */ #endif /* __ASM_IPI_H */ diff --git a/include/asm-x86_64/pgtable.h b/include/asm-x86_64/pgtable.h index 31e83c3bd..195952b2c 100644 --- a/include/asm-x86_64/pgtable.h +++ b/include/asm-x86_64/pgtable.h @@ -21,7 +21,7 @@ extern unsigned long __supported_pte_mask; #define swapper_pg_dir init_level4_pgt -extern int nonx_setup(char *str); +extern void nonx_setup(const char *str); extern void paging_init(void); extern void clear_kernel_mapping(unsigned long addr, unsigned long size); diff --git a/include/linux/autoconf.h b/include/linux/autoconf.h index 546d52177..6b7b49be5 100644 --- a/include/linux/autoconf.h +++ b/include/linux/autoconf.h @@ -1,41 +1,62 @@ /* * Automatically generated C config: don't edit + * Linux kernel version: 2.6.17.13 + * Wed Oct 18 17:15:54 2006 */ #define AUTOCONF_INCLUDED +#define CONFIG_X86_32 1 +#define CONFIG_SEMAPHORE_SLEEPERS 1 #define CONFIG_X86 1 #define CONFIG_MMU 1 -#define CONFIG_UID16 1 #define CONFIG_GENERIC_ISA_DMA 1 +#define CONFIG_GENERIC_IOMAP 1 +#define CONFIG_GENERIC_HWEIGHT 1 +#define CONFIG_ARCH_MAY_HAVE_PC_FDC 1 +#define CONFIG_DMI 1 /* * Code maturity level options */ #define CONFIG_EXPERIMENTAL 1 -#define CONFIG_CLEAN_COMPILE 1 -#define CONFIG_STANDALONE 1 +#define CONFIG_BROKEN_ON_SMP 1 +#define CONFIG_INIT_ENV_ARG_LIMIT 32 /* * General setup */ +#define CONFIG_LOCALVERSION "" +#undef CONFIG_LOCALVERSION_AUTO #define CONFIG_SWAP 1 #define CONFIG_SYSVIPC 1 #define CONFIG_POSIX_MQUEUE 1 #define CONFIG_BSD_PROCESS_ACCT 1 +#undef CONFIG_BSD_PROCESS_ACCT_V3 #define CONFIG_SYSCTL 1 -#undef CONFIG_AUDIT -#define CONFIG_LOG_BUF_SHIFT 17 -#define CONFIG_HOTPLUG 1 +#define CONFIG_AUDIT 1 +#define CONFIG_AUDITSYSCALL 1 #undef CONFIG_IKCONFIG +#define CONFIG_RELAY 1 +#define CONFIG_INITRAMFS_SOURCE "" +#define CONFIG_UID16 1 +#define CONFIG_VM86 1 +#define CONFIG_CC_OPTIMIZE_FOR_SIZE 1 #undef CONFIG_EMBEDDED #define CONFIG_KALLSYMS 1 #undef CONFIG_KALLSYMS_ALL +#define CONFIG_KALLSYMS_EXTRA_PASS 1 +#define CONFIG_HOTPLUG 1 +#define CONFIG_PRINTK 1 +#define CONFIG_BUG 1 +#define CONFIG_ELF_CORE 1 +#define CONFIG_BASE_FULL 1 #define CONFIG_FUTEX 1 #define CONFIG_EPOLL 1 -#define CONFIG_IOSCHED_NOOP 1 -#define CONFIG_IOSCHED_AS 1 -#define CONFIG_IOSCHED_DEADLINE 1 -#define CONFIG_IOSCHED_CFQ 1 -#define CONFIG_CC_OPTIMIZE_FOR_SIZE 1 +#define CONFIG_SHMEM 1 +#define CONFIG_SLAB 1 +#undef CONFIG_TINY_SHMEM +#define CONFIG_BASE_SMALL 0 +#undef CONFIG_SLOB +#define CONFIG_OBSOLETE_INTERMODULE_MODULE 1 /* * Loadable module support @@ -43,24 +64,46 @@ #define CONFIG_MODULES 1 #define CONFIG_MODULE_UNLOAD 1 #undef CONFIG_MODULE_FORCE_UNLOAD -#define CONFIG_OBSOLETE_MODPARM 1 -#undef CONFIG_MODVERSIONS +#define CONFIG_MODVERSIONS 1 +#define CONFIG_MODULE_SRCVERSION_ALL 1 +#define CONFIG_MODULE_SIG 1 +#undef CONFIG_MODULE_SIG_FORCE #define CONFIG_KMOD 1 -#define CONFIG_STOP_MACHINE 1 + +/* + * Block layer + */ +#define CONFIG_LBD 1 +#define CONFIG_BLK_DEV_IO_TRACE 1 +#define CONFIG_LSF 1 + +/* + * IO Schedulers + */ +#define CONFIG_IOSCHED_NOOP 1 +#define CONFIG_IOSCHED_AS 1 +#define CONFIG_IOSCHED_DEADLINE 1 +#define CONFIG_IOSCHED_CFQ 1 +#undef CONFIG_DEFAULT_AS +#undef CONFIG_DEFAULT_DEADLINE +#define CONFIG_DEFAULT_CFQ 1 +#undef CONFIG_DEFAULT_NOOP +#define CONFIG_DEFAULT_IOSCHED "cfq" /* * Processor type and features */ -#undef CONFIG_X86_PC +#undef CONFIG_SMP +#define CONFIG_X86_PC 1 +#undef CONFIG_X86_XEN #undef CONFIG_X86_ELAN #undef CONFIG_X86_VOYAGER #undef CONFIG_X86_NUMAQ #undef CONFIG_X86_SUMMIT #undef CONFIG_X86_BIGSMP #undef CONFIG_X86_VISWS -#define CONFIG_X86_GENERICARCH 1 +#undef CONFIG_X86_GENERICARCH #undef CONFIG_X86_ES7000 -#define CONFIG_X86_CYCLONE_TIMER 1 #undef CONFIG_M386 #undef CONFIG_M486 #undef CONFIG_M586 @@ -75,9 +118,12 @@ #undef CONFIG_MK7 #undef CONFIG_MK8 #undef CONFIG_MCRUSOE +#undef CONFIG_MEFFICEON #undef CONFIG_MWINCHIPC6 #undef CONFIG_MWINCHIP2 #undef CONFIG_MWINCHIP3D +#undef CONFIG_MGEODEGX1 +#undef CONFIG_MGEODE_LX #undef CONFIG_MCYRIXIII #undef CONFIG_MVIAC3_2 #define CONFIG_X86_GENERIC 1 @@ -85,85 +131,111 @@ #define CONFIG_X86_XADD 1 #define CONFIG_X86_L1_CACHE_SHIFT 7 #define CONFIG_RWSEM_XCHGADD_ALGORITHM 1 +#define CONFIG_GENERIC_CALIBRATE_DELAY 1 #define CONFIG_X86_PPRO_FENCE 1 #define CONFIG_X86_WP_WORKS_OK 1 #define CONFIG_X86_INVLPG 1 #define CONFIG_X86_BSWAP 1 #define CONFIG_X86_POPAD_OK 1 +#define CONFIG_X86_CMPXCHG64 1 #define CONFIG_X86_GOOD_APIC 1 #define CONFIG_X86_INTEL_USERCOPY 1 #define CONFIG_X86_USE_PPRO_CHECKSUM 1 -#define CONFIG_X86_4G 1 -#define CONFIG_X86_SWITCH_PAGETABLES 1 -#define CONFIG_X86_4G_VM_LAYOUT 1 -#define CONFIG_X86_UACCESS_INDIRECT 1 -#define CONFIG_X86_HIGH_ENTRY 1 +#define CONFIG_X86_TSC 1 #define CONFIG_HPET_TIMER 1 #define CONFIG_HPET_EMULATE_RTC 1 -#define CONFIG_SMP 1 -#define CONFIG_NR_CPUS 32 -#define CONFIG_SCHED_SMT 1 +#undef CONFIG_PREEMPT_NONE +#define CONFIG_PREEMPT_VOLUNTARY 1 #undef CONFIG_PREEMPT +#define CONFIG_X86_UP_APIC 1 +#define CONFIG_X86_UP_IOAPIC 1 #define CONFIG_X86_LOCAL_APIC 1 #define CONFIG_X86_IO_APIC 1 -#define CONFIG_X86_TSC 1 #define CONFIG_X86_MCE 1 #undef CONFIG_X86_MCE_NONFATAL #define CONFIG_X86_MCE_P4THERMAL 1 #define CONFIG_TOSHIBA_MODULE 1 #define CONFIG_I8K_MODULE 1 +#undef CONFIG_X86_REBOOTFIXUPS #define CONFIG_MICROCODE_MODULE 1 #define CONFIG_X86_MSR_MODULE 1 #define CONFIG_X86_CPUID_MODULE 1 +#undef CONFIG_SWIOTLB /* * Firmware Drivers */ #define CONFIG_EDD_MODULE 1 +#define CONFIG_EFI_VARS 1 +#define CONFIG_DELL_RBU_MODULE 1 +#define CONFIG_DCDBAS_MODULE 1 #undef CONFIG_NOHIGHMEM -#undef CONFIG_HIGHMEM4G -#define CONFIG_HIGHMEM64G 1 +#define CONFIG_HIGHMEM4G 1 +#undef CONFIG_HIGHMEM64G +#define CONFIG_PAGE_OFFSET 0xC0000000 #define CONFIG_HIGHMEM 1 -#define CONFIG_X86_PAE 1 -#undef CONFIG_NUMA +#define CONFIG_ARCH_FLATMEM_ENABLE 1 +#define CONFIG_ARCH_SPARSEMEM_ENABLE 1 +#define CONFIG_ARCH_SELECT_MEMORY_MODEL 1 +#define CONFIG_SELECT_MEMORY_MODEL 1 +#define CONFIG_FLATMEM_MANUAL 1 +#undef CONFIG_DISCONTIGMEM_MANUAL +#undef CONFIG_SPARSEMEM_MANUAL +#define CONFIG_FLATMEM 1 +#define CONFIG_FLAT_NODE_MEM_MAP 1 +#define CONFIG_SPARSEMEM_STATIC 1 +#define CONFIG_SPLIT_PTLOCK_CPUS 4096 #define CONFIG_HIGHPTE 1 #undef CONFIG_MATH_EMULATION #define CONFIG_MTRR 1 -#undef CONFIG_EFI -#undef CONFIG_IRQBALANCE -#define CONFIG_HAVE_DEC_LOCK 1 +#define CONFIG_EFI 1 +#define CONFIG_BOOT_IOREMAP 1 #define CONFIG_REGPARM 1 +#undef CONFIG_SECCOMP +#undef CONFIG_HZ_100 +#define CONFIG_HZ_250 1 +#undef CONFIG_HZ_1000 +#define CONFIG_HZ 250 +#define CONFIG_KEXEC 1 +#undef CONFIG_CRASH_DUMP +#define CONFIG_PHYSICAL_START 0x400000 +#define CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG 1 /* * Power management options (ACPI, APM) */ #define CONFIG_PM 1 -#undef CONFIG_SOFTWARE_SUSPEND -#undef CONFIG_PM_DISK +#define CONFIG_PM_LEGACY 1 +#define CONFIG_PM_DEBUG 1 +#define CONFIG_SOFTWARE_SUSPEND 1 +#define CONFIG_PM_STD_PARTITION "" /* * ACPI (Advanced Configuration and Power Interface) Support */ #define CONFIG_ACPI 1 -#define CONFIG_ACPI_BOOT 1 -#define CONFIG_ACPI_INTERPRETER 1 #define CONFIG_ACPI_SLEEP 1 #define CONFIG_ACPI_SLEEP_PROC_FS 1 +#undef CONFIG_ACPI_SLEEP_PROC_SLEEP #define CONFIG_ACPI_AC_MODULE 1 #define CONFIG_ACPI_BATTERY_MODULE 1 #define CONFIG_ACPI_BUTTON_MODULE 1 +#define CONFIG_ACPI_VIDEO_MODULE 1 +#undef CONFIG_ACPI_HOTKEY #define CONFIG_ACPI_FAN 1 #define CONFIG_ACPI_PROCESSOR 1 #define CONFIG_ACPI_THERMAL 1 #define CONFIG_ACPI_ASUS_MODULE 1 +#define CONFIG_ACPI_IBM_MODULE 1 +#define CONFIG_ACPI_IBM_DOCK 1 #define CONFIG_ACPI_TOSHIBA_MODULE 1 +#define CONFIG_ACPI_BLACKLIST_YEAR 1999 #undef CONFIG_ACPI_DEBUG -#define CONFIG_ACPI_BUS 1 #define CONFIG_ACPI_EC 1 #define CONFIG_ACPI_POWER 1 -#define CONFIG_ACPI_PCI 1 #define CONFIG_ACPI_SYSTEM 1 #define CONFIG_X86_PM_TIMER 1 +#undef CONFIG_ACPI_CONTAINER /* * APM (Advanced Power Management) BIOS Support @@ -181,34 +253,43 @@ * CPU Frequency scaling */ #define CONFIG_CPU_FREQ 1 -#undef CONFIG_CPU_FREQ_PROC_INTF +#define CONFIG_CPU_FREQ_TABLE 1 +#define CONFIG_CPU_FREQ_DEBUG 1 +#define CONFIG_CPU_FREQ_STAT_MODULE 1 +#define CONFIG_CPU_FREQ_STAT_DETAILS 1 #undef CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE #define CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE 1 #define CONFIG_CPU_FREQ_GOV_PERFORMANCE 1 #define CONFIG_CPU_FREQ_GOV_POWERSAVE_MODULE 1 #define CONFIG_CPU_FREQ_GOV_USERSPACE 1 -#undef CONFIG_CPU_FREQ_24_API -#define CONFIG_CPU_FREQ_TABLE 1 +#define CONFIG_CPU_FREQ_GOV_ONDEMAND_MODULE 1 +#define CONFIG_CPU_FREQ_GOV_CONSERVATIVE_MODULE 1 /* * CPUFreq processor drivers */ #define CONFIG_X86_ACPI_CPUFREQ_MODULE 1 -#undef CONFIG_X86_ACPI_CPUFREQ_PROC_INTF -#define CONFIG_X86_POWERNOW_K6_MODULE 1 +#undef CONFIG_X86_POWERNOW_K6 #define CONFIG_X86_POWERNOW_K7 1 -#define CONFIG_X86_POWERNOW_K8_MODULE 1 +#define CONFIG_X86_POWERNOW_K7_ACPI 1 +#define CONFIG_X86_POWERNOW_K8 1 +#define CONFIG_X86_POWERNOW_K8_ACPI 1 #undef CONFIG_X86_GX_SUSPMOD #define CONFIG_X86_SPEEDSTEP_CENTRINO 1 -#define CONFIG_X86_SPEEDSTEP_CENTRINO_TABLE 1 #define CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI 1 +#define CONFIG_X86_SPEEDSTEP_CENTRINO_TABLE 1 #define CONFIG_X86_SPEEDSTEP_ICH 1 -#define CONFIG_X86_SPEEDSTEP_SMI_MODULE 1 +#define CONFIG_X86_SPEEDSTEP_SMI 1 #define CONFIG_X86_P4_CLOCKMOD_MODULE 1 +#undef CONFIG_X86_CPUFREQ_NFORCE2 +#define CONFIG_X86_LONGRUN 1 + +/* + * shared options + */ +#undef CONFIG_X86_ACPI_CPUFREQ_PROC_INTF #define CONFIG_X86_SPEEDSTEP_LIB 1 #undef CONFIG_X86_SPEEDSTEP_RELAXED_CAP_CHECK -#define CONFIG_X86_LONGRUN 1 -#undef CONFIG_X86_LONGHAUL /* * Bus options (PCI, PCMCIA, EISA, MCA, ISA) @@ -217,810 +298,1029 @@ #undef CONFIG_PCI_GOBIOS #undef CONFIG_PCI_GOMMCONFIG #undef CONFIG_PCI_GODIRECT +#undef CONFIG_PCI_GOXEN_FE #define CONFIG_PCI_GOANY 1 #define CONFIG_PCI_BIOS 1 #define CONFIG_PCI_DIRECT 1 #define CONFIG_PCI_MMCONFIG 1 -#define CONFIG_PCI_USE_VECTOR 1 -#define CONFIG_PCI_LEGACY_PROC 1 -#undef CONFIG_PCI_NAMES +#define CONFIG_PCIEPORTBUS 1 +#define CONFIG_HOTPLUG_PCI_PCIE_MODULE 1 +#undef CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE +#define CONFIG_PCI_MSI 1 +#undef CONFIG_PCI_DEBUG +#define CONFIG_ISA_DMA_API 1 #define CONFIG_ISA 1 #undef CONFIG_EISA #undef CONFIG_MCA #undef CONFIG_SCx200 /* - * PCMCIA/CardBus support + * PCCARD (PCMCIA/CardBus) support */ -#define CONFIG_PCMCIA_MODULE 1 +#define CONFIG_PCCARD 1 #undef CONFIG_PCMCIA_DEBUG -#define CONFIG_YENTA_MODULE 1 +#define CONFIG_PCMCIA 1 +#define CONFIG_PCMCIA_LOAD_CIS 1 +#define CONFIG_PCMCIA_IOCTL 1 #define CONFIG_CARDBUS 1 + +/* + * PC-card bridges + */ +#define CONFIG_YENTA 1 +#define CONFIG_YENTA_O2 1 +#define CONFIG_YENTA_RICOH 1 +#define CONFIG_YENTA_TI 1 +#define CONFIG_YENTA_ENE_TUNE 1 +#define CONFIG_YENTA_TOSHIBA 1 +#define CONFIG_PD6729_MODULE 1 #define CONFIG_I82092_MODULE 1 -#define CONFIG_I82365_MODULE 1 -#define CONFIG_TCIC_MODULE 1 +#undef CONFIG_I82365 +#undef CONFIG_TCIC #define CONFIG_PCMCIA_PROBE 1 +#define CONFIG_PCCARD_NONSTATIC 1 /* * PCI Hotplug Support */ #define CONFIG_HOTPLUG_PCI 1 -#undef CONFIG_HOTPLUG_PCI_FAKE +#define CONFIG_HOTPLUG_PCI_FAKE_MODULE 1 #define CONFIG_HOTPLUG_PCI_COMPAQ_MODULE 1 #undef CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM #define CONFIG_HOTPLUG_PCI_IBM_MODULE 1 -#undef CONFIG_HOTPLUG_PCI_ACPI +#define CONFIG_HOTPLUG_PCI_ACPI_MODULE 1 +#define CONFIG_HOTPLUG_PCI_ACPI_IBM_MODULE 1 #undef CONFIG_HOTPLUG_PCI_CPCI -#define CONFIG_HOTPLUG_PCI_PCIE_MODULE 1 -#define CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE 1 -#define CONFIG_HOTPLUG_PCI_SHPC_MODULE 1 -#define CONFIG_HOTPLUG_PCI_SHPC_POLL_EVENT_MODE 1 +#undef CONFIG_HOTPLUG_PCI_SHPC /* * Executable file formats */ #define CONFIG_BINFMT_ELF 1 #undef CONFIG_BINFMT_AOUT -#define CONFIG_BINFMT_MISC_MODULE 1 +#define CONFIG_BINFMT_MISC 1 /* - * Device Drivers + * Networking */ +#define CONFIG_NET 1 /* - * Generic Driver Options + * Networking options */ -#define CONFIG_FW_LOADER 1 -#undef CONFIG_DEBUG_DRIVER +#undef CONFIG_NETDEBUG +#define CONFIG_PACKET 1 +#define CONFIG_PACKET_MMAP 1 +#define CONFIG_UNIX 1 +#define CONFIG_XFRM 1 +#define CONFIG_XFRM_USER 1 +#define CONFIG_NET_KEY_MODULE 1 +#define CONFIG_INET 1 +#define CONFIG_IP_MULTICAST 1 +#define CONFIG_IP_ADVANCED_ROUTER 1 +#define CONFIG_ASK_IP_FIB_HASH 1 +#undef CONFIG_IP_FIB_TRIE +#define CONFIG_IP_FIB_HASH 1 +#define CONFIG_IP_MULTIPLE_TABLES 1 +#define CONFIG_IP_ROUTE_FWMARK 1 +#define CONFIG_IP_ROUTE_MULTIPATH 1 +#undef CONFIG_IP_ROUTE_MULTIPATH_CACHED +#define CONFIG_IP_ROUTE_VERBOSE 1 +#undef CONFIG_IP_PNP +#define CONFIG_NET_IPIP_MODULE 1 +#define CONFIG_NET_IPGRE_MODULE 1 +#define CONFIG_NET_IPGRE_BROADCAST 1 +#define CONFIG_IP_MROUTE 1 +#define CONFIG_IP_PIMSM_V1 1 +#define CONFIG_IP_PIMSM_V2 1 +#undef CONFIG_ARPD +#define CONFIG_SYN_COOKIES 1 +#define CONFIG_INET_AH_MODULE 1 +#define CONFIG_INET_ESP_MODULE 1 +#define CONFIG_INET_IPCOMP_MODULE 1 +#define CONFIG_INET_XFRM_TUNNEL_MODULE 1 +#define CONFIG_INET_TUNNEL_MODULE 1 +#define CONFIG_INET_DIAG_MODULE 1 +#define CONFIG_INET_TCP_DIAG_MODULE 1 +#undef CONFIG_TCP_CONG_ADVANCED +#define CONFIG_TCP_CONG_BIC 1 /* - * Memory Technology Devices (MTD) + * IP: Virtual Server Configuration */ -#define CONFIG_MTD_MODULE 1 -#undef CONFIG_MTD_DEBUG -#define CONFIG_MTD_PARTITIONS_MODULE 1 -#define CONFIG_MTD_CONCAT_MODULE 1 -#define CONFIG_MTD_REDBOOT_PARTS_MODULE 1 -#define CONFIG_MTD_CMDLINE_PARTS_MODULE 1 +#define CONFIG_IP_VS_MODULE 1 +#undef CONFIG_IP_VS_DEBUG +#define CONFIG_IP_VS_TAB_BITS 12 /* - * User Modules And Translation Layers + * IPVS transport protocol load balancing support */ -#define CONFIG_MTD_CHAR_MODULE 1 -#define CONFIG_MTD_BLOCK_MODULE 1 -#define CONFIG_MTD_BLOCK_RO_MODULE 1 -#define CONFIG_FTL_MODULE 1 -#define CONFIG_NFTL_MODULE 1 -#define CONFIG_NFTL_RW 1 -#define CONFIG_INFTL_MODULE 1 +#define CONFIG_IP_VS_PROTO_TCP 1 +#define CONFIG_IP_VS_PROTO_UDP 1 +#define CONFIG_IP_VS_PROTO_ESP 1 +#define CONFIG_IP_VS_PROTO_AH 1 /* - * RAM/ROM/Flash chip drivers + * IPVS scheduler */ -#define CONFIG_MTD_CFI_MODULE 1 -#define CONFIG_MTD_JEDECPROBE_MODULE 1 -#define CONFIG_MTD_GEN_PROBE_MODULE 1 -#undef CONFIG_MTD_CFI_ADV_OPTIONS -#define CONFIG_MTD_CFI_INTELEXT_MODULE 1 -#define CONFIG_MTD_CFI_AMDSTD_MODULE 1 -#define CONFIG_MTD_CFI_STAA_MODULE 1 -#define CONFIG_MTD_RAM_MODULE 1 -#define CONFIG_MTD_ROM_MODULE 1 -#define CONFIG_MTD_ABSENT_MODULE 1 -#undef CONFIG_MTD_OBSOLETE_CHIPS +#define CONFIG_IP_VS_RR_MODULE 1 +#define CONFIG_IP_VS_WRR_MODULE 1 +#define CONFIG_IP_VS_LC_MODULE 1 +#define CONFIG_IP_VS_WLC_MODULE 1 +#define CONFIG_IP_VS_LBLC_MODULE 1 +#define CONFIG_IP_VS_LBLCR_MODULE 1 +#define CONFIG_IP_VS_DH_MODULE 1 +#define CONFIG_IP_VS_SH_MODULE 1 +#define CONFIG_IP_VS_SED_MODULE 1 +#define CONFIG_IP_VS_NQ_MODULE 1 /* - * Mapping drivers for chip access + * IPVS application helper */ -#define CONFIG_MTD_COMPLEX_MAPPINGS 1 -#undef CONFIG_MTD_PHYSMAP -#undef CONFIG_MTD_PNC2000 -#define CONFIG_MTD_SC520CDP_MODULE 1 -#define CONFIG_MTD_NETSC520_MODULE 1 -#define CONFIG_MTD_SBC_GXX_MODULE 1 -#define CONFIG_MTD_ELAN_104NC_MODULE 1 -#define CONFIG_MTD_SCx200_DOCFLASH_MODULE 1 -#define CONFIG_MTD_AMD76XROM_MODULE 1 -#define CONFIG_MTD_ICH2ROM_MODULE 1 -#define CONFIG_MTD_SCB2_FLASH_MODULE 1 -#undef CONFIG_MTD_NETtel -#undef CONFIG_MTD_DILNETPC -#define CONFIG_MTD_L440GX_MODULE 1 -#define CONFIG_MTD_PCI_MODULE 1 +#define CONFIG_IP_VS_FTP_MODULE 1 +#define CONFIG_IPV6_MODULE 1 +#define CONFIG_IPV6_PRIVACY 1 +#define CONFIG_IPV6_ROUTER_PREF 1 +#define CONFIG_IPV6_ROUTE_INFO 1 +#define CONFIG_INET6_AH_MODULE 1 +#define CONFIG_INET6_ESP_MODULE 1 +#define CONFIG_INET6_IPCOMP_MODULE 1 +#define CONFIG_INET6_XFRM_TUNNEL_MODULE 1 +#define CONFIG_INET6_TUNNEL_MODULE 1 +#define CONFIG_IPV6_TUNNEL_MODULE 1 +#define CONFIG_NETFILTER 1 +#undef CONFIG_NETFILTER_DEBUG +#define CONFIG_BRIDGE_NETFILTER 1 /* - * Self-contained MTD device drivers + * Core Netfilter Configuration + */ +#define CONFIG_NETFILTER_NETLINK_MODULE 1 +#define CONFIG_NETFILTER_NETLINK_QUEUE_MODULE 1 +#define CONFIG_NETFILTER_NETLINK_LOG_MODULE 1 +#define CONFIG_NETFILTER_XTABLES_MODULE 1 +#define CONFIG_NETFILTER_XT_TARGET_CLASSIFY_MODULE 1 +#define CONFIG_NETFILTER_XT_TARGET_CONNMARK_MODULE 1 +#define CONFIG_NETFILTER_XT_TARGET_MARK_MODULE 1 +#define CONFIG_NETFILTER_XT_TARGET_NFQUEUE_MODULE 1 +#define CONFIG_NETFILTER_XT_TARGET_NOTRACK_MODULE 1 +#define CONFIG_NETFILTER_XT_MATCH_COMMENT_MODULE 1 +#define CONFIG_NETFILTER_XT_MATCH_CONNBYTES_MODULE 1 +#define CONFIG_NETFILTER_XT_MATCH_CONNMARK_MODULE 1 +#define CONFIG_NETFILTER_XT_MATCH_CONNTRACK_MODULE 1 +#define CONFIG_NETFILTER_XT_MATCH_DCCP_MODULE 1 +#define CONFIG_NETFILTER_XT_MATCH_ESP_MODULE 1 +#define CONFIG_NETFILTER_XT_MATCH_HELPER_MODULE 1 +#define CONFIG_NETFILTER_XT_MATCH_LENGTH_MODULE 1 +#define CONFIG_NETFILTER_XT_MATCH_LIMIT_MODULE 1 +#define CONFIG_NETFILTER_XT_MATCH_MAC_MODULE 1 +#define CONFIG_NETFILTER_XT_MATCH_MARK_MODULE 1 +#define CONFIG_NETFILTER_XT_MATCH_POLICY_MODULE 1 +#define CONFIG_NETFILTER_XT_MATCH_MULTIPORT_MODULE 1 +#define CONFIG_NETFILTER_XT_MATCH_PHYSDEV_MODULE 1 +#define CONFIG_NETFILTER_XT_MATCH_PKTTYPE_MODULE 1 +#define CONFIG_NETFILTER_XT_MATCH_REALM_MODULE 1 +#define CONFIG_NETFILTER_XT_MATCH_SCTP_MODULE 1 +#define CONFIG_NETFILTER_XT_MATCH_STATE_MODULE 1 +#define CONFIG_NETFILTER_XT_MATCH_STRING_MODULE 1 +#define CONFIG_NETFILTER_XT_MATCH_TCPMSS_MODULE 1 + +/* + * IP: Netfilter Configuration */ -#define CONFIG_MTD_PMC551_MODULE 1 -#undef CONFIG_MTD_PMC551_BUGFIX -#undef CONFIG_MTD_PMC551_DEBUG -#undef CONFIG_MTD_SLRAM -#define CONFIG_MTD_MTDRAM_MODULE 1 -#define CONFIG_MTDRAM_TOTAL_SIZE 4096 -#define CONFIG_MTDRAM_ERASE_SIZE 128 -#undef CONFIG_MTD_BLKMTD +#define CONFIG_IP_NF_CONNTRACK_MODULE 1 +#define CONFIG_IP_NF_CT_ACCT 1 +#define CONFIG_IP_NF_CONNTRACK_MARK 1 +#define CONFIG_IP_NF_CONNTRACK_EVENTS 1 +#define CONFIG_IP_NF_CONNTRACK_NETLINK_MODULE 1 +#define CONFIG_IP_NF_CT_PROTO_SCTP_MODULE 1 +#define CONFIG_IP_NF_FTP_MODULE 1 +#define CONFIG_IP_NF_IRC_MODULE 1 +#define CONFIG_IP_NF_NETBIOS_NS_MODULE 1 +#define CONFIG_IP_NF_TFTP_MODULE 1 +#define CONFIG_IP_NF_AMANDA_MODULE 1 +#define CONFIG_IP_NF_PPTP_MODULE 1 +#define CONFIG_IP_NF_H323_MODULE 1 +#define CONFIG_IP_NF_QUEUE_MODULE 1 +#define CONFIG_IP_NF_IPTABLES_MODULE 1 +#define CONFIG_IP_NF_MATCH_IPRANGE_MODULE 1 +#define CONFIG_IP_NF_MATCH_TOS_MODULE 1 +#define CONFIG_IP_NF_MATCH_RECENT_MODULE 1 +#define CONFIG_IP_NF_MATCH_ECN_MODULE 1 +#define CONFIG_IP_NF_MATCH_DSCP_MODULE 1 +#define CONFIG_IP_NF_MATCH_AH_MODULE 1 +#define CONFIG_IP_NF_MATCH_TTL_MODULE 1 +#define CONFIG_IP_NF_MATCH_OWNER_MODULE 1 +#define CONFIG_IP_NF_MATCH_ADDRTYPE_MODULE 1 +#define CONFIG_IP_NF_MATCH_HASHLIMIT_MODULE 1 +#define CONFIG_IP_NF_FILTER_MODULE 1 +#define CONFIG_IP_NF_TARGET_REJECT_MODULE 1 +#define CONFIG_IP_NF_TARGET_LOG_MODULE 1 +#define CONFIG_IP_NF_TARGET_ULOG_MODULE 1 +#define CONFIG_IP_NF_TARGET_TCPMSS_MODULE 1 +#define CONFIG_IP_NF_NAT_MODULE 1 +#define CONFIG_IP_NF_NAT_NEEDED 1 +#define CONFIG_IP_NF_TARGET_MASQUERADE_MODULE 1 +#define CONFIG_IP_NF_TARGET_REDIRECT_MODULE 1 +#define CONFIG_IP_NF_TARGET_NETMAP_MODULE 1 +#define CONFIG_IP_NF_TARGET_SAME_MODULE 1 +#define CONFIG_IP_NF_NAT_SNMP_BASIC_MODULE 1 +#define CONFIG_IP_NF_NAT_IRC_MODULE 1 +#define CONFIG_IP_NF_NAT_FTP_MODULE 1 +#define CONFIG_IP_NF_NAT_TFTP_MODULE 1 +#define CONFIG_IP_NF_NAT_AMANDA_MODULE 1 +#define CONFIG_IP_NF_NAT_PPTP_MODULE 1 +#define CONFIG_IP_NF_NAT_H323_MODULE 1 +#define CONFIG_IP_NF_MANGLE_MODULE 1 +#define CONFIG_IP_NF_TARGET_TOS_MODULE 1 +#define CONFIG_IP_NF_TARGET_ECN_MODULE 1 +#define CONFIG_IP_NF_TARGET_DSCP_MODULE 1 +#define CONFIG_IP_NF_TARGET_TTL_MODULE 1 +#define CONFIG_IP_NF_TARGET_CLUSTERIP_MODULE 1 +#define CONFIG_IP_NF_RAW_MODULE 1 +#define CONFIG_IP_NF_ARPTABLES_MODULE 1 +#define CONFIG_IP_NF_ARPFILTER_MODULE 1 +#define CONFIG_IP_NF_ARP_MANGLE_MODULE 1 /* - * Disk-On-Chip Device Drivers + * IPv6: Netfilter Configuration (EXPERIMENTAL) */ -#define CONFIG_MTD_DOC2000_MODULE 1 -#undef CONFIG_MTD_DOC2001 -#define CONFIG_MTD_DOC2001PLUS_MODULE 1 -#define CONFIG_MTD_DOCPROBE_MODULE 1 -#undef CONFIG_MTD_DOCPROBE_ADVANCED -#define CONFIG_MTD_DOCPROBE_ADDRESS 0x0 +#define CONFIG_IP6_NF_QUEUE_MODULE 1 +#define CONFIG_IP6_NF_IPTABLES_MODULE 1 +#define CONFIG_IP6_NF_MATCH_RT_MODULE 1 +#define CONFIG_IP6_NF_MATCH_OPTS_MODULE 1 +#define CONFIG_IP6_NF_MATCH_FRAG_MODULE 1 +#define CONFIG_IP6_NF_MATCH_HL_MODULE 1 +#define CONFIG_IP6_NF_MATCH_OWNER_MODULE 1 +#define CONFIG_IP6_NF_MATCH_IPV6HEADER_MODULE 1 +#define CONFIG_IP6_NF_MATCH_AH_MODULE 1 +#define CONFIG_IP6_NF_MATCH_EUI64_MODULE 1 +#define CONFIG_IP6_NF_FILTER_MODULE 1 +#define CONFIG_IP6_NF_TARGET_LOG_MODULE 1 +#define CONFIG_IP6_NF_TARGET_REJECT_MODULE 1 +#define CONFIG_IP6_NF_MANGLE_MODULE 1 +#define CONFIG_IP6_NF_TARGET_HL_MODULE 1 +#define CONFIG_IP6_NF_RAW_MODULE 1 /* - * NAND Flash Device Drivers + * DECnet: Netfilter Configuration */ -#define CONFIG_MTD_NAND_MODULE 1 -#undef CONFIG_MTD_NAND_VERIFY_WRITE -#define CONFIG_MTD_NAND_IDS_MODULE 1 +#undef CONFIG_DECNET_NF_GRABULATOR /* - * Parallel port support + * Bridge: Netfilter Configuration */ -#define CONFIG_PARPORT_MODULE 1 -#define CONFIG_PARPORT_PC_MODULE 1 -#define CONFIG_PARPORT_PC_CML1_MODULE 1 -#define CONFIG_PARPORT_SERIAL_MODULE 1 -#undef CONFIG_PARPORT_PC_FIFO -#undef CONFIG_PARPORT_PC_SUPERIO -#define CONFIG_PARPORT_PC_PCMCIA_MODULE 1 -#undef CONFIG_PARPORT_OTHER -#define CONFIG_PARPORT_1284 1 +#define CONFIG_BRIDGE_NF_EBTABLES_MODULE 1 +#define CONFIG_BRIDGE_EBT_BROUTE_MODULE 1 +#define CONFIG_BRIDGE_EBT_T_FILTER_MODULE 1 +#define CONFIG_BRIDGE_EBT_T_NAT_MODULE 1 +#define CONFIG_BRIDGE_EBT_802_3_MODULE 1 +#define CONFIG_BRIDGE_EBT_AMONG_MODULE 1 +#define CONFIG_BRIDGE_EBT_ARP_MODULE 1 +#define CONFIG_BRIDGE_EBT_IP_MODULE 1 +#define CONFIG_BRIDGE_EBT_LIMIT_MODULE 1 +#define CONFIG_BRIDGE_EBT_MARK_MODULE 1 +#define CONFIG_BRIDGE_EBT_PKTTYPE_MODULE 1 +#define CONFIG_BRIDGE_EBT_STP_MODULE 1 +#define CONFIG_BRIDGE_EBT_VLAN_MODULE 1 +#define CONFIG_BRIDGE_EBT_ARPREPLY_MODULE 1 +#define CONFIG_BRIDGE_EBT_DNAT_MODULE 1 +#define CONFIG_BRIDGE_EBT_MARK_T_MODULE 1 +#define CONFIG_BRIDGE_EBT_REDIRECT_MODULE 1 +#define CONFIG_BRIDGE_EBT_SNAT_MODULE 1 +#define CONFIG_BRIDGE_EBT_LOG_MODULE 1 +#define CONFIG_BRIDGE_EBT_ULOG_MODULE 1 /* - * Plug and Play support + * DCCP Configuration (EXPERIMENTAL) */ -#define CONFIG_PNP 1 -#undef CONFIG_PNP_DEBUG +#define CONFIG_IP_DCCP_MODULE 1 +#define CONFIG_INET_DCCP_DIAG_MODULE 1 +#define CONFIG_IP_DCCP_ACKVEC 1 /* - * Protocols + * DCCP CCIDs Configuration (EXPERIMENTAL) */ -#define CONFIG_ISAPNP 1 -#undef CONFIG_PNPBIOS +#define CONFIG_IP_DCCP_CCID2_MODULE 1 +#define CONFIG_IP_DCCP_CCID3_MODULE 1 +#define CONFIG_IP_DCCP_TFRC_LIB_MODULE 1 /* - * Block devices + * DCCP Kernel Hacking */ -#define CONFIG_BLK_DEV_FD_MODULE 1 -#undef CONFIG_BLK_DEV_XD -#undef CONFIG_PARIDE -#define CONFIG_BLK_CPQ_DA_MODULE 1 -#define CONFIG_BLK_CPQ_CISS_DA_MODULE 1 -#define CONFIG_CISS_SCSI_TAPE 1 -#define CONFIG_BLK_DEV_DAC960_MODULE 1 -#define CONFIG_BLK_DEV_UMEM_MODULE 1 -#define CONFIG_BLK_DEV_LOOP_MODULE 1 -#define CONFIG_BLK_DEV_CRYPTOLOOP_MODULE 1 -#define CONFIG_BLK_DEV_NBD_MODULE 1 -#define CONFIG_BLK_DEV_CARMEL_MODULE 1 -#define CONFIG_BLK_DEV_RAM 1 -#define CONFIG_BLK_DEV_RAM_SIZE 16384 -#define CONFIG_BLK_DEV_INITRD 1 -#define CONFIG_LBD 1 +#undef CONFIG_IP_DCCP_DEBUG /* - * ATA/ATAPI/MFM/RLL support + * SCTP Configuration (EXPERIMENTAL) */ -#define CONFIG_IDE 1 -#define CONFIG_BLK_DEV_IDE 1 +#define CONFIG_IP_SCTP_MODULE 1 +#undef CONFIG_SCTP_DBG_MSG +#undef CONFIG_SCTP_DBG_OBJCNT +#undef CONFIG_SCTP_HMAC_NONE +#undef CONFIG_SCTP_HMAC_SHA1 +#define CONFIG_SCTP_HMAC_MD5 1 /* - * Please see Documentation/ide.txt for help/info on IDE drives + * TIPC Configuration (EXPERIMENTAL) */ -#undef CONFIG_BLK_DEV_HD_IDE -#define CONFIG_BLK_DEV_IDEDISK 1 -#define CONFIG_IDEDISK_MULTI_MODE 1 -#undef CONFIG_IDEDISK_STROKE -#define CONFIG_BLK_DEV_IDECS_MODULE 1 -#define CONFIG_BLK_DEV_IDECD 1 -#define CONFIG_BLK_DEV_IDETAPE_MODULE 1 -#define CONFIG_BLK_DEV_IDEFLOPPY 1 -#undef CONFIG_BLK_DEV_IDESCSI -#undef CONFIG_IDE_TASK_IOCTL -#undef CONFIG_IDE_TASKFILE_IO +#define CONFIG_TIPC_MODULE 1 +#undef CONFIG_TIPC_ADVANCED +#undef CONFIG_TIPC_DEBUG +#define CONFIG_ATM_MODULE 1 +#define CONFIG_ATM_CLIP_MODULE 1 +#undef CONFIG_ATM_CLIP_NO_ICMP +#define CONFIG_ATM_LANE_MODULE 1 +#undef CONFIG_ATM_MPOA +#define CONFIG_ATM_BR2684_MODULE 1 +#undef CONFIG_ATM_BR2684_IPFILTER +#define CONFIG_BRIDGE_MODULE 1 +#define CONFIG_VLAN_8021Q_MODULE 1 +#define CONFIG_DECNET_MODULE 1 +#define CONFIG_DECNET_ROUTER 1 +#define CONFIG_DECNET_ROUTE_FWMARK 1 +#define CONFIG_LLC 1 +#undef CONFIG_LLC2 +#define CONFIG_IPX_MODULE 1 +#undef CONFIG_IPX_INTERN +#define CONFIG_ATALK_MODULE 1 +#define CONFIG_DEV_APPLETALK 1 +#undef CONFIG_LTPC +#undef CONFIG_COPS +#define CONFIG_IPDDP_MODULE 1 +#define CONFIG_IPDDP_ENCAP 1 +#define CONFIG_IPDDP_DECAP 1 +#undef CONFIG_X25 +#undef CONFIG_LAPB +#define CONFIG_NET_DIVERT 1 +#undef CONFIG_ECONET +#define CONFIG_WAN_ROUTER_MODULE 1 /* - * IDE chipset support/bugfixes + * QoS and/or fair queueing */ -#define CONFIG_IDE_GENERIC 1 -#undef CONFIG_BLK_DEV_CMD640 -#define CONFIG_BLK_DEV_IDEPNP 1 -#define CONFIG_BLK_DEV_IDEPCI 1 -#define CONFIG_IDEPCI_SHARE_IRQ 1 -#undef CONFIG_BLK_DEV_OFFBOARD -#define CONFIG_BLK_DEV_GENERIC 1 -#undef CONFIG_BLK_DEV_OPTI621 -#define CONFIG_BLK_DEV_RZ1000 1 -#define CONFIG_BLK_DEV_IDEDMA_PCI 1 -#undef CONFIG_BLK_DEV_IDEDMA_FORCED -#define CONFIG_IDEDMA_PCI_AUTO 1 -#undef CONFIG_IDEDMA_ONLYDISK -#define CONFIG_BLK_DEV_ADMA 1 -#define CONFIG_BLK_DEV_AEC62XX 1 -#define CONFIG_BLK_DEV_ALI15X3 1 -#undef CONFIG_WDC_ALI15X3 -#define CONFIG_BLK_DEV_AMD74XX 1 -#define CONFIG_BLK_DEV_ATIIXP 1 -#define CONFIG_BLK_DEV_CMD64X 1 -#define CONFIG_BLK_DEV_TRIFLEX 1 -#define CONFIG_BLK_DEV_CY82C693 1 -#define CONFIG_BLK_DEV_CS5520 1 -#define CONFIG_BLK_DEV_CS5530 1 -#define CONFIG_BLK_DEV_HPT34X 1 -#undef CONFIG_HPT34X_AUTODMA -#define CONFIG_BLK_DEV_HPT366 1 -#undef CONFIG_BLK_DEV_SC1200 -#define CONFIG_BLK_DEV_PIIX 1 -#undef CONFIG_BLK_DEV_NS87415 -#define CONFIG_BLK_DEV_PDC202XX_OLD 1 -#undef CONFIG_PDC202XX_BURST -#define CONFIG_BLK_DEV_PDC202XX_NEW 1 -#define CONFIG_PDC202XX_FORCE 1 -#define CONFIG_BLK_DEV_SVWKS 1 -#define CONFIG_BLK_DEV_SIIMAGE 1 -#define CONFIG_BLK_DEV_SIS5513 1 -#define CONFIG_BLK_DEV_SLC90E66 1 -#undef CONFIG_BLK_DEV_TRM290 -#define CONFIG_BLK_DEV_VIA82CXXX 1 -#undef CONFIG_IDE_ARM -#undef CONFIG_IDE_CHIPSETS -#define CONFIG_BLK_DEV_IDEDMA 1 -#undef CONFIG_IDEDMA_IVB -#define CONFIG_IDEDMA_AUTO 1 -#undef CONFIG_BLK_DEV_HD +#define CONFIG_NET_SCHED 1 +#undef CONFIG_NET_SCH_CLK_JIFFIES +#define CONFIG_NET_SCH_CLK_GETTIMEOFDAY 1 +#undef CONFIG_NET_SCH_CLK_CPU /* - * SCSI device support + * Queueing/Scheduling */ -#define CONFIG_SCSI_MODULE 1 -#define CONFIG_SCSI_PROC_FS 1 +#define CONFIG_NET_SCH_CBQ_MODULE 1 +#define CONFIG_NET_SCH_HTB_MODULE 1 +#define CONFIG_NET_SCH_HFSC_MODULE 1 +#define CONFIG_NET_SCH_ATM_MODULE 1 +#define CONFIG_NET_SCH_PRIO_MODULE 1 +#define CONFIG_NET_SCH_RED_MODULE 1 +#define CONFIG_NET_SCH_SFQ_MODULE 1 +#define CONFIG_NET_SCH_TEQL_MODULE 1 +#define CONFIG_NET_SCH_TBF_MODULE 1 +#define CONFIG_NET_SCH_GRED_MODULE 1 +#define CONFIG_NET_SCH_DSMARK_MODULE 1 +#define CONFIG_NET_SCH_NETEM_MODULE 1 +#define CONFIG_NET_SCH_INGRESS_MODULE 1 /* - * SCSI support type (disk, tape, CD-ROM) + * Classification */ -#define CONFIG_BLK_DEV_SD_MODULE 1 -#define CONFIG_CHR_DEV_ST_MODULE 1 -#define CONFIG_CHR_DEV_OSST_MODULE 1 -#define CONFIG_BLK_DEV_SR_MODULE 1 -#define CONFIG_BLK_DEV_SR_VENDOR 1 -#define CONFIG_CHR_DEV_SG_MODULE 1 +#define CONFIG_NET_CLS 1 +#define CONFIG_NET_CLS_BASIC_MODULE 1 +#define CONFIG_NET_CLS_TCINDEX_MODULE 1 +#define CONFIG_NET_CLS_ROUTE4_MODULE 1 +#define CONFIG_NET_CLS_ROUTE 1 +#define CONFIG_NET_CLS_FW_MODULE 1 +#define CONFIG_NET_CLS_U32_MODULE 1 +#define CONFIG_CLS_U32_PERF 1 +#define CONFIG_CLS_U32_MARK 1 +#define CONFIG_NET_CLS_RSVP_MODULE 1 +#define CONFIG_NET_CLS_RSVP6_MODULE 1 +#define CONFIG_NET_EMATCH 1 +#define CONFIG_NET_EMATCH_STACK 32 +#define CONFIG_NET_EMATCH_CMP_MODULE 1 +#define CONFIG_NET_EMATCH_NBYTE_MODULE 1 +#define CONFIG_NET_EMATCH_U32_MODULE 1 +#define CONFIG_NET_EMATCH_META_MODULE 1 +#define CONFIG_NET_EMATCH_TEXT_MODULE 1 +#undef CONFIG_NET_CLS_ACT +#define CONFIG_NET_CLS_POLICE 1 +#define CONFIG_NET_CLS_IND 1 +#define CONFIG_NET_ESTIMATOR 1 /* - * Some SCSI devices (e.g. CD jukebox) support multiple LUNs + * Network testing */ -#undef CONFIG_SCSI_MULTI_LUN -#define CONFIG_SCSI_CONSTANTS 1 -#define CONFIG_SCSI_LOGGING 1 +#define CONFIG_NET_PKTGEN_MODULE 1 +#undef CONFIG_HAMRADIO +#define CONFIG_IRDA_MODULE 1 /* - * SCSI Transport Attributes + * IrDA protocols */ -#define CONFIG_SCSI_SPI_ATTRS_MODULE 1 -#define CONFIG_SCSI_FC_ATTRS_MODULE 1 +#define CONFIG_IRLAN_MODULE 1 +#define CONFIG_IRNET_MODULE 1 +#define CONFIG_IRCOMM_MODULE 1 +#undef CONFIG_IRDA_ULTRA /* - * SCSI low-level drivers + * IrDA options */ -#define CONFIG_BLK_DEV_3W_XXXX_RAID_MODULE 1 -#undef CONFIG_SCSI_7000FASST -#define CONFIG_SCSI_ACARD_MODULE 1 -#define CONFIG_SCSI_AHA152X_MODULE 1 -#define CONFIG_SCSI_AHA1542_MODULE 1 -#define CONFIG_SCSI_AACRAID_MODULE 1 -#define CONFIG_SCSI_AIC7XXX_MODULE 1 -#define CONFIG_AIC7XXX_CMDS_PER_DEVICE 4 -#define CONFIG_AIC7XXX_RESET_DELAY_MS 15000 -#undef CONFIG_AIC7XXX_BUILD_FIRMWARE -#undef CONFIG_AIC7XXX_DEBUG_ENABLE -#define CONFIG_AIC7XXX_DEBUG_MASK 0 -#undef CONFIG_AIC7XXX_REG_PRETTY_PRINT -#define CONFIG_SCSI_AIC7XXX_OLD_MODULE 1 -#define CONFIG_SCSI_AIC79XX_MODULE 1 -#define CONFIG_AIC79XX_CMDS_PER_DEVICE 4 -#define CONFIG_AIC79XX_RESET_DELAY_MS 15000 -#undef CONFIG_AIC79XX_BUILD_FIRMWARE -#undef CONFIG_AIC79XX_ENABLE_RD_STRM -#undef CONFIG_AIC79XX_DEBUG_ENABLE -#define CONFIG_AIC79XX_DEBUG_MASK 0 -#undef CONFIG_AIC79XX_REG_PRETTY_PRINT -#undef CONFIG_SCSI_DPT_I2O -#define CONFIG_SCSI_ADVANSYS_MODULE 1 -#define CONFIG_SCSI_IN2000_MODULE 1 -#define CONFIG_SCSI_MEGARAID_MODULE 1 -#define CONFIG_SCSI_SATA 1 -#define CONFIG_SCSI_SATA_SVW_MODULE 1 -#define CONFIG_SCSI_ATA_PIIX_MODULE 1 -#define CONFIG_SCSI_SATA_PROMISE_MODULE 1 -#define CONFIG_SCSI_SATA_SX4_MODULE 1 -#define CONFIG_SCSI_SATA_SIL_MODULE 1 -#define CONFIG_SCSI_SATA_SIS_MODULE 1 -#define CONFIG_SCSI_SATA_VIA_MODULE 1 -#define CONFIG_SCSI_SATA_VITESSE_MODULE 1 -#define CONFIG_SCSI_BUSLOGIC_MODULE 1 -#undef CONFIG_SCSI_OMIT_FLASHPOINT -#undef CONFIG_SCSI_CPQFCTS -#undef CONFIG_SCSI_DMX3191D -#undef CONFIG_SCSI_DTC3280 -#undef CONFIG_SCSI_EATA -#undef CONFIG_SCSI_EATA_PIO -#define CONFIG_SCSI_FUTURE_DOMAIN_MODULE 1 -#define CONFIG_SCSI_GDTH_MODULE 1 -#undef CONFIG_SCSI_GENERIC_NCR5380 -#undef CONFIG_SCSI_GENERIC_NCR5380_MMIO -#define CONFIG_SCSI_IPS_MODULE 1 -#define CONFIG_SCSI_INIA100_MODULE 1 -#define CONFIG_SCSI_PPA_MODULE 1 -#define CONFIG_SCSI_IMM_MODULE 1 -#undef CONFIG_SCSI_IZIP_EPP16 -#undef CONFIG_SCSI_IZIP_SLOW_CTR -#undef CONFIG_SCSI_NCR53C406A -#define CONFIG_SCSI_SYM53C8XX_2_MODULE 1 -#define CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE 1 -#define CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS 16 -#define CONFIG_SCSI_SYM53C8XX_MAX_TAGS 64 -#undef CONFIG_SCSI_SYM53C8XX_IOMAPPED -#undef CONFIG_SCSI_IPR -#undef CONFIG_SCSI_PAS16 -#undef CONFIG_SCSI_PSI240I -#define CONFIG_SCSI_QLOGIC_FAS_MODULE 1 -#define CONFIG_SCSI_QLOGIC_ISP_MODULE 1 -#undef CONFIG_SCSI_QLOGIC_FC -#define CONFIG_SCSI_QLOGIC_1280_MODULE 1 -#define CONFIG_SCSI_QLA2XXX_MODULE 1 -#define CONFIG_SCSI_QLA21XX_MODULE 1 -#define CONFIG_SCSI_QLA22XX_MODULE 1 -#define CONFIG_SCSI_QLA2300_MODULE 1 -#define CONFIG_SCSI_QLA2322_MODULE 1 -#define CONFIG_SCSI_QLA6312_MODULE 1 -#define CONFIG_SCSI_QLA6322_MODULE 1 -#undef CONFIG_SCSI_SYM53C416 -#undef CONFIG_SCSI_DC395x -#define CONFIG_SCSI_DC390T_MODULE 1 -#undef CONFIG_SCSI_T128 -#undef CONFIG_SCSI_U14_34F -#undef CONFIG_SCSI_ULTRASTOR -#undef CONFIG_SCSI_NSP32 -#undef CONFIG_SCSI_DEBUG +#define CONFIG_IRDA_CACHE_LAST_LSAP 1 +#define CONFIG_IRDA_FAST_RR 1 +#undef CONFIG_IRDA_DEBUG /* - * PCMCIA SCSI adapter support + * Infrared-port device drivers */ -#define CONFIG_PCMCIA_AHA152X_MODULE 1 -#define CONFIG_PCMCIA_FDOMAIN_MODULE 1 -#define CONFIG_PCMCIA_NINJA_SCSI_MODULE 1 -#define CONFIG_PCMCIA_QLOGIC_MODULE 1 -#define CONFIG_PCMCIA_SYM53C500_MODULE 1 /* - * Old CD-ROM drivers (not SCSI, not IDE) + * SIR device drivers */ -#undef CONFIG_CD_NO_IDESCSI +#define CONFIG_IRTTY_SIR_MODULE 1 /* - * Multi-device support (RAID and LVM) + * Dongle support */ -#define CONFIG_MD 1 -#define CONFIG_BLK_DEV_MD 1 -#define CONFIG_MD_LINEAR_MODULE 1 -#define CONFIG_MD_RAID0_MODULE 1 -#define CONFIG_MD_RAID1_MODULE 1 -#define CONFIG_MD_RAID5_MODULE 1 -#define CONFIG_MD_RAID6_MODULE 1 -#define CONFIG_MD_MULTIPATH_MODULE 1 -#define CONFIG_BLK_DEV_DM_MODULE 1 -#define CONFIG_DM_CRYPT_MODULE 1 +#define CONFIG_DONGLE 1 +#define CONFIG_ESI_DONGLE_MODULE 1 +#define CONFIG_ACTISYS_DONGLE_MODULE 1 +#define CONFIG_TEKRAM_DONGLE_MODULE 1 +#define CONFIG_TOIM3232_DONGLE_MODULE 1 +#define CONFIG_LITELINK_DONGLE_MODULE 1 +#define CONFIG_MA600_DONGLE_MODULE 1 +#define CONFIG_GIRBIL_DONGLE_MODULE 1 +#define CONFIG_MCP2120_DONGLE_MODULE 1 +#define CONFIG_OLD_BELKIN_DONGLE_MODULE 1 +#define CONFIG_ACT200L_DONGLE_MODULE 1 /* - * Fusion MPT device support + * Old SIR device drivers */ -#define CONFIG_FUSION_MODULE 1 -#define CONFIG_FUSION_MAX_SGE 40 -#undef CONFIG_FUSION_ISENSE -#define CONFIG_FUSION_CTL_MODULE 1 -#define CONFIG_FUSION_LAN_MODULE 1 +#define CONFIG_IRPORT_SIR_MODULE 1 /* - * IEEE 1394 (FireWire) support + * Old Serial dongle support */ -#define CONFIG_IEEE1394_MODULE 1 +#undef CONFIG_DONGLE_OLD /* - * Subsystem Options + * FIR device drivers */ -#undef CONFIG_IEEE1394_VERBOSEDEBUG -#define CONFIG_IEEE1394_OUI_DB 1 -#undef CONFIG_IEEE1394_EXTRA_CONFIG_ROMS +#define CONFIG_USB_IRDA_MODULE 1 +#define CONFIG_SIGMATEL_FIR_MODULE 1 +#define CONFIG_NSC_FIR_MODULE 1 +#define CONFIG_WINBOND_FIR_MODULE 1 +#define CONFIG_TOSHIBA_FIR_MODULE 1 +#define CONFIG_SMC_IRCC_FIR_MODULE 1 +#define CONFIG_ALI_FIR_MODULE 1 +#define CONFIG_VLSI_FIR_MODULE 1 +#define CONFIG_VIA_FIR_MODULE 1 +#define CONFIG_BT_MODULE 1 +#define CONFIG_BT_L2CAP_MODULE 1 +#define CONFIG_BT_SCO_MODULE 1 +#define CONFIG_BT_RFCOMM_MODULE 1 +#define CONFIG_BT_RFCOMM_TTY 1 +#define CONFIG_BT_BNEP_MODULE 1 +#define CONFIG_BT_BNEP_MC_FILTER 1 +#define CONFIG_BT_BNEP_PROTO_FILTER 1 +#define CONFIG_BT_CMTP_MODULE 1 +#define CONFIG_BT_HIDP_MODULE 1 /* - * Device Drivers + * Bluetooth device drivers */ -#undef CONFIG_IEEE1394_PCILYNX -#define CONFIG_IEEE1394_OHCI1394_MODULE 1 +#define CONFIG_BT_HCIUSB_MODULE 1 +#define CONFIG_BT_HCIUSB_SCO 1 +#define CONFIG_BT_HCIUART_MODULE 1 +#define CONFIG_BT_HCIUART_H4 1 +#define CONFIG_BT_HCIUART_BCSP 1 +#define CONFIG_BT_HCIBCM203X_MODULE 1 +#define CONFIG_BT_HCIBPA10X_MODULE 1 +#define CONFIG_BT_HCIBFUSB_MODULE 1 +#define CONFIG_BT_HCIDTL1_MODULE 1 +#define CONFIG_BT_HCIBT3C_MODULE 1 +#define CONFIG_BT_HCIBLUECARD_MODULE 1 +#define CONFIG_BT_HCIBTUART_MODULE 1 +#define CONFIG_BT_HCIVHCI_MODULE 1 +#define CONFIG_IEEE80211_MODULE 1 +#undef CONFIG_IEEE80211_DEBUG +#define CONFIG_IEEE80211_CRYPT_WEP_MODULE 1 +#define CONFIG_IEEE80211_CRYPT_CCMP_MODULE 1 +#define CONFIG_IEEE80211_CRYPT_TKIP_MODULE 1 +#define CONFIG_IEEE80211_SOFTMAC_MODULE 1 +#define CONFIG_IEEE80211_SOFTMAC_DEBUG 1 +#define CONFIG_TUX_MODULE 1 /* - * Protocol Drivers + * TUX options */ -#define CONFIG_IEEE1394_VIDEO1394_MODULE 1 -#define CONFIG_IEEE1394_SBP2_MODULE 1 -#undef CONFIG_IEEE1394_SBP2_PHYS_DMA -#undef CONFIG_IEEE1394_ETH1394 -#define CONFIG_IEEE1394_DV1394_MODULE 1 -#define CONFIG_IEEE1394_RAWIO_MODULE 1 -#define CONFIG_IEEE1394_CMP_MODULE 1 -#define CONFIG_IEEE1394_AMDTP_MODULE 1 +#define CONFIG_TUX_EXTCGI 1 +#define CONFIG_TUX_EXTENDED_LOG 1 +#undef CONFIG_TUX_DEBUG +#define CONFIG_WIRELESS_EXT 1 /* - * I2O device support + * Device Drivers */ -#define CONFIG_I2O_MODULE 1 -#define CONFIG_I2O_CONFIG_MODULE 1 -#define CONFIG_I2O_BLOCK_MODULE 1 -#define CONFIG_I2O_SCSI_MODULE 1 -#define CONFIG_I2O_PROC_MODULE 1 /* - * Networking support + * Generic Driver Options */ -#define CONFIG_NET 1 +#define CONFIG_STANDALONE 1 +#define CONFIG_PREVENT_FIRMWARE_BUILD 1 +#define CONFIG_FW_LOADER 1 +#undef CONFIG_DEBUG_DRIVER /* - * Networking options + * Connector - unified userspace <-> kernelspace linker */ -#define CONFIG_PACKET 1 -#define CONFIG_PACKET_MMAP 1 -#define CONFIG_NETLINK_DEV 1 -#define CONFIG_UNIX 1 -#define CONFIG_NET_KEY_MODULE 1 -#define CONFIG_INET 1 -#define CONFIG_IP_MULTICAST 1 -#define CONFIG_IP_ADVANCED_ROUTER 1 -#define CONFIG_IP_MULTIPLE_TABLES 1 -#define CONFIG_IP_ROUTE_FWMARK 1 -#define CONFIG_IP_ROUTE_NAT 1 -#define CONFIG_IP_ROUTE_MULTIPATH 1 -#define CONFIG_IP_ROUTE_TOS 1 -#define CONFIG_IP_ROUTE_VERBOSE 1 -#undef CONFIG_IP_PNP -#define CONFIG_NET_IPIP_MODULE 1 -#define CONFIG_NET_IPGRE_MODULE 1 -#define CONFIG_NET_IPGRE_BROADCAST 1 -#define CONFIG_IP_MROUTE 1 -#define CONFIG_IP_PIMSM_V1 1 -#define CONFIG_IP_PIMSM_V2 1 -#undef CONFIG_ARPD -#define CONFIG_SYN_COOKIES 1 -#define CONFIG_INET_AH_MODULE 1 -#define CONFIG_INET_ESP_MODULE 1 -#define CONFIG_INET_IPCOMP_MODULE 1 +#define CONFIG_CONNECTOR_MODULE 1 /* - * IP: Virtual Server Configuration + * Memory Technology Devices (MTD) */ -#define CONFIG_IP_VS_MODULE 1 -#undef CONFIG_IP_VS_DEBUG -#define CONFIG_IP_VS_TAB_BITS 12 +#define CONFIG_MTD_MODULE 1 +#undef CONFIG_MTD_DEBUG +#define CONFIG_MTD_CONCAT_MODULE 1 +#define CONFIG_MTD_PARTITIONS 1 +#define CONFIG_MTD_REDBOOT_PARTS_MODULE 1 +#define CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK -1 +#undef CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED +#undef CONFIG_MTD_REDBOOT_PARTS_READONLY +#define CONFIG_MTD_CMDLINE_PARTS 1 /* - * IPVS transport protocol load balancing support + * User Modules And Translation Layers */ -#define CONFIG_IP_VS_PROTO_TCP 1 -#define CONFIG_IP_VS_PROTO_UDP 1 -#define CONFIG_IP_VS_PROTO_ESP 1 -#define CONFIG_IP_VS_PROTO_AH 1 +#define CONFIG_MTD_CHAR_MODULE 1 +#define CONFIG_MTD_BLOCK_MODULE 1 +#define CONFIG_MTD_BLOCK_RO_MODULE 1 +#define CONFIG_FTL_MODULE 1 +#define CONFIG_NFTL_MODULE 1 +#define CONFIG_NFTL_RW 1 +#define CONFIG_INFTL_MODULE 1 +#define CONFIG_RFD_FTL_MODULE 1 /* - * IPVS scheduler + * RAM/ROM/Flash chip drivers */ -#define CONFIG_IP_VS_RR_MODULE 1 -#define CONFIG_IP_VS_WRR_MODULE 1 -#define CONFIG_IP_VS_LC_MODULE 1 -#define CONFIG_IP_VS_WLC_MODULE 1 -#define CONFIG_IP_VS_LBLC_MODULE 1 -#define CONFIG_IP_VS_LBLCR_MODULE 1 -#define CONFIG_IP_VS_DH_MODULE 1 -#define CONFIG_IP_VS_SH_MODULE 1 -#define CONFIG_IP_VS_SED_MODULE 1 -#define CONFIG_IP_VS_NQ_MODULE 1 +#define CONFIG_MTD_CFI_MODULE 1 +#define CONFIG_MTD_JEDECPROBE_MODULE 1 +#define CONFIG_MTD_GEN_PROBE_MODULE 1 +#undef CONFIG_MTD_CFI_ADV_OPTIONS +#define CONFIG_MTD_MAP_BANK_WIDTH_1 1 +#define CONFIG_MTD_MAP_BANK_WIDTH_2 1 +#define CONFIG_MTD_MAP_BANK_WIDTH_4 1 +#undef CONFIG_MTD_MAP_BANK_WIDTH_8 +#undef CONFIG_MTD_MAP_BANK_WIDTH_16 +#undef CONFIG_MTD_MAP_BANK_WIDTH_32 +#define CONFIG_MTD_CFI_I1 1 +#define CONFIG_MTD_CFI_I2 1 +#undef CONFIG_MTD_CFI_I4 +#undef CONFIG_MTD_CFI_I8 +#define CONFIG_MTD_CFI_INTELEXT_MODULE 1 +#define CONFIG_MTD_CFI_AMDSTD_MODULE 1 +#define CONFIG_MTD_CFI_STAA_MODULE 1 +#define CONFIG_MTD_CFI_UTIL_MODULE 1 +#define CONFIG_MTD_RAM_MODULE 1 +#define CONFIG_MTD_ROM_MODULE 1 +#define CONFIG_MTD_ABSENT_MODULE 1 +#undef CONFIG_MTD_OBSOLETE_CHIPS /* - * IPVS application helper + * Mapping drivers for chip access */ -#define CONFIG_IP_VS_FTP_MODULE 1 -#define CONFIG_IPV6_MODULE 1 -#define CONFIG_IPV6_PRIVACY 1 -#define CONFIG_INET6_AH_MODULE 1 -#define CONFIG_INET6_ESP_MODULE 1 -#define CONFIG_INET6_IPCOMP_MODULE 1 -#define CONFIG_IPV6_TUNNEL_MODULE 1 -#define CONFIG_NETFILTER 1 -#undef CONFIG_NETFILTER_DEBUG -#define CONFIG_BRIDGE_NETFILTER 1 +#define CONFIG_MTD_COMPLEX_MAPPINGS 1 +#undef CONFIG_MTD_PHYSMAP +#undef CONFIG_MTD_PNC2000 +#define CONFIG_MTD_SC520CDP_MODULE 1 +#define CONFIG_MTD_NETSC520_MODULE 1 +#define CONFIG_MTD_TS5500_MODULE 1 +#undef CONFIG_MTD_SBC_GXX +#undef CONFIG_MTD_AMD76XROM +#undef CONFIG_MTD_ICHXROM +#define CONFIG_MTD_SCB2_FLASH_MODULE 1 +#undef CONFIG_MTD_NETtel +#undef CONFIG_MTD_DILNETPC +#undef CONFIG_MTD_L440GX +#define CONFIG_MTD_PCI_MODULE 1 +#undef CONFIG_MTD_PLATRAM /* - * IP: Netfilter Configuration + * Self-contained MTD device drivers */ -#define CONFIG_IP_NF_CONNTRACK_MODULE 1 -#define CONFIG_IP_NF_FTP_MODULE 1 -#define CONFIG_IP_NF_IRC_MODULE 1 -#define CONFIG_IP_NF_TFTP_MODULE 1 -#define CONFIG_IP_NF_AMANDA_MODULE 1 -#define CONFIG_IP_NF_QUEUE_MODULE 1 -#define CONFIG_IP_NF_IPTABLES_MODULE 1 -#define CONFIG_IP_NF_MATCH_LIMIT_MODULE 1 -#define CONFIG_IP_NF_MATCH_IPRANGE_MODULE 1 -#define CONFIG_IP_NF_MATCH_MAC_MODULE 1 -#define CONFIG_IP_NF_MATCH_PKTTYPE_MODULE 1 -#define CONFIG_IP_NF_MATCH_MARK_MODULE 1 -#define CONFIG_IP_NF_MATCH_MULTIPORT_MODULE 1 -#define CONFIG_IP_NF_MATCH_TOS_MODULE 1 -#define CONFIG_IP_NF_MATCH_RECENT_MODULE 1 -#define CONFIG_IP_NF_MATCH_ECN_MODULE 1 -#define CONFIG_IP_NF_MATCH_DSCP_MODULE 1 -#define CONFIG_IP_NF_MATCH_AH_ESP_MODULE 1 -#define CONFIG_IP_NF_MATCH_LENGTH_MODULE 1 -#define CONFIG_IP_NF_MATCH_TTL_MODULE 1 -#define CONFIG_IP_NF_MATCH_TCPMSS_MODULE 1 -#define CONFIG_IP_NF_MATCH_HELPER_MODULE 1 -#define CONFIG_IP_NF_MATCH_STATE_MODULE 1 -#define CONFIG_IP_NF_MATCH_CONNTRACK_MODULE 1 -#define CONFIG_IP_NF_MATCH_OWNER_MODULE 1 -#define CONFIG_IP_NF_MATCH_PHYSDEV_MODULE 1 -#define CONFIG_IP_NF_FILTER_MODULE 1 -#define CONFIG_IP_NF_TARGET_REJECT_MODULE 1 -#define CONFIG_IP_NF_NAT_MODULE 1 -#define CONFIG_IP_NF_NAT_NEEDED 1 -#define CONFIG_IP_NF_TARGET_MASQUERADE_MODULE 1 -#define CONFIG_IP_NF_TARGET_REDIRECT_MODULE 1 -#define CONFIG_IP_NF_TARGET_NETMAP_MODULE 1 -#define CONFIG_IP_NF_TARGET_SAME_MODULE 1 -#define CONFIG_IP_NF_NAT_LOCAL 1 -#define CONFIG_IP_NF_NAT_SNMP_BASIC_MODULE 1 -#define CONFIG_IP_NF_NAT_IRC_MODULE 1 -#define CONFIG_IP_NF_NAT_FTP_MODULE 1 -#define CONFIG_IP_NF_NAT_TFTP_MODULE 1 -#define CONFIG_IP_NF_NAT_AMANDA_MODULE 1 -#define CONFIG_IP_NF_MANGLE_MODULE 1 -#define CONFIG_IP_NF_TARGET_TOS_MODULE 1 -#define CONFIG_IP_NF_TARGET_ECN_MODULE 1 -#define CONFIG_IP_NF_TARGET_DSCP_MODULE 1 -#define CONFIG_IP_NF_TARGET_MARK_MODULE 1 -#define CONFIG_IP_NF_TARGET_CLASSIFY_MODULE 1 -#define CONFIG_IP_NF_TARGET_LOG_MODULE 1 -#define CONFIG_IP_NF_TARGET_ULOG_MODULE 1 -#define CONFIG_IP_NF_TARGET_TCPMSS_MODULE 1 -#define CONFIG_IP_NF_ARPTABLES_MODULE 1 -#define CONFIG_IP_NF_ARPFILTER_MODULE 1 -#define CONFIG_IP_NF_ARP_MANGLE_MODULE 1 -#undef CONFIG_IP_NF_COMPAT_IPCHAINS -#undef CONFIG_IP_NF_COMPAT_IPFWADM -#define CONFIG_IP_NF_TARGET_NOTRACK_MODULE 1 -#define CONFIG_IP_NF_RAW_MODULE 1 +#define CONFIG_MTD_PMC551_MODULE 1 +#undef CONFIG_MTD_PMC551_BUGFIX +#undef CONFIG_MTD_PMC551_DEBUG +#undef CONFIG_MTD_SLRAM +#undef CONFIG_MTD_PHRAM +#define CONFIG_MTD_MTDRAM_MODULE 1 +#define CONFIG_MTDRAM_TOTAL_SIZE 4096 +#define CONFIG_MTDRAM_ERASE_SIZE 128 +#define CONFIG_MTD_BLOCK2MTD_MODULE 1 /* - * IPv6: Netfilter Configuration + * Disk-On-Chip Device Drivers */ -#undef CONFIG_IP6_NF_QUEUE -#define CONFIG_IP6_NF_IPTABLES_MODULE 1 -#define CONFIG_IP6_NF_MATCH_LIMIT_MODULE 1 -#define CONFIG_IP6_NF_MATCH_MAC_MODULE 1 -#define CONFIG_IP6_NF_MATCH_RT_MODULE 1 -#define CONFIG_IP6_NF_MATCH_OPTS_MODULE 1 -#define CONFIG_IP6_NF_MATCH_FRAG_MODULE 1 -#define CONFIG_IP6_NF_MATCH_HL_MODULE 1 -#define CONFIG_IP6_NF_MATCH_MULTIPORT_MODULE 1 -#define CONFIG_IP6_NF_MATCH_OWNER_MODULE 1 -#define CONFIG_IP6_NF_MATCH_MARK_MODULE 1 -#define CONFIG_IP6_NF_MATCH_IPV6HEADER_MODULE 1 -#define CONFIG_IP6_NF_MATCH_AHESP_MODULE 1 -#define CONFIG_IP6_NF_MATCH_LENGTH_MODULE 1 -#define CONFIG_IP6_NF_MATCH_EUI64_MODULE 1 -#define CONFIG_IP6_NF_FILTER_MODULE 1 -#define CONFIG_IP6_NF_TARGET_LOG_MODULE 1 -#define CONFIG_IP6_NF_MANGLE_MODULE 1 -#define CONFIG_IP6_NF_TARGET_MARK_MODULE 1 -#define CONFIG_IP6_NF_RAW_MODULE 1 +#define CONFIG_MTD_DOC2000_MODULE 1 +#undef CONFIG_MTD_DOC2001 +#define CONFIG_MTD_DOC2001PLUS_MODULE 1 +#define CONFIG_MTD_DOCPROBE_MODULE 1 +#define CONFIG_MTD_DOCECC_MODULE 1 +#undef CONFIG_MTD_DOCPROBE_ADVANCED +#define CONFIG_MTD_DOCPROBE_ADDRESS 0x0 + +/* + * NAND Flash Device Drivers + */ +#define CONFIG_MTD_NAND_MODULE 1 +#undef CONFIG_MTD_NAND_VERIFY_WRITE +#define CONFIG_MTD_NAND_IDS_MODULE 1 +#undef CONFIG_MTD_NAND_DISKONCHIP +#define CONFIG_MTD_NAND_NANDSIM_MODULE 1 + +/* + * OneNAND Flash Device Drivers + */ +#undef CONFIG_MTD_ONENAND + +/* + * Parallel port support + */ +#define CONFIG_PARPORT_MODULE 1 +#define CONFIG_PARPORT_PC_MODULE 1 +#define CONFIG_PARPORT_SERIAL_MODULE 1 +#undef CONFIG_PARPORT_PC_FIFO +#undef CONFIG_PARPORT_PC_SUPERIO +#define CONFIG_PARPORT_PC_PCMCIA_MODULE 1 +#define CONFIG_PARPORT_NOT_PC 1 +#undef CONFIG_PARPORT_GSC +#define CONFIG_PARPORT_1284 1 + +/* + * Plug and Play support + */ +#define CONFIG_PNP 1 +#undef CONFIG_PNP_DEBUG + +/* + * Protocols + */ +#define CONFIG_ISAPNP 1 +#undef CONFIG_PNPBIOS +#define CONFIG_PNPACPI 1 + +/* + * Block devices + */ +#define CONFIG_BLK_DEV_FD_MODULE 1 +#undef CONFIG_BLK_DEV_XD +#define CONFIG_PARIDE_MODULE 1 +#define CONFIG_PARIDE_PARPORT_MODULE 1 + +/* + * Parallel IDE high-level drivers + */ +#define CONFIG_PARIDE_PD_MODULE 1 +#define CONFIG_PARIDE_PCD_MODULE 1 +#define CONFIG_PARIDE_PF_MODULE 1 +#define CONFIG_PARIDE_PT_MODULE 1 +#define CONFIG_PARIDE_PG_MODULE 1 + +/* + * Parallel IDE protocol modules + */ +#define CONFIG_PARIDE_ATEN_MODULE 1 +#define CONFIG_PARIDE_BPCK_MODULE 1 +#define CONFIG_PARIDE_BPCK6_MODULE 1 +#define CONFIG_PARIDE_COMM_MODULE 1 +#define CONFIG_PARIDE_DSTR_MODULE 1 +#define CONFIG_PARIDE_FIT2_MODULE 1 +#define CONFIG_PARIDE_FIT3_MODULE 1 +#define CONFIG_PARIDE_EPAT_MODULE 1 +#define CONFIG_PARIDE_EPATC8 1 +#define CONFIG_PARIDE_EPIA_MODULE 1 +#define CONFIG_PARIDE_FRIQ_MODULE 1 +#define CONFIG_PARIDE_FRPW_MODULE 1 +#define CONFIG_PARIDE_KBIC_MODULE 1 +#define CONFIG_PARIDE_KTTI_MODULE 1 +#define CONFIG_PARIDE_ON20_MODULE 1 +#define CONFIG_PARIDE_ON26_MODULE 1 +#define CONFIG_BLK_CPQ_DA_MODULE 1 +#define CONFIG_BLK_CPQ_CISS_DA_MODULE 1 +#define CONFIG_CISS_SCSI_TAPE 1 +#define CONFIG_BLK_DEV_DAC960_MODULE 1 +#define CONFIG_BLK_DEV_UMEM_MODULE 1 +#undef CONFIG_BLK_DEV_COW_COMMON +#define CONFIG_BLK_DEV_LOOP_MODULE 1 +#define CONFIG_BLK_DEV_CRYPTOLOOP_MODULE 1 +#define CONFIG_BLK_DEV_NBD_MODULE 1 +#define CONFIG_BLK_DEV_SX8_MODULE 1 +#define CONFIG_BLK_DEV_UB_MODULE 1 +#define CONFIG_BLK_DEV_RAM 1 +#define CONFIG_BLK_DEV_RAM_COUNT 16 +#define CONFIG_BLK_DEV_RAM_SIZE 16384 +#define CONFIG_BLK_DEV_INITRD 1 +#define CONFIG_CDROM_PKTCDVD_MODULE 1 +#define CONFIG_CDROM_PKTCDVD_BUFFERS 8 +#undef CONFIG_CDROM_PKTCDVD_WCACHE +#define CONFIG_ATA_OVER_ETH_MODULE 1 + +/* + * ATA/ATAPI/MFM/RLL support + */ +#define CONFIG_IDE 1 +#define CONFIG_BLK_DEV_IDE 1 + +/* + * Please see Documentation/ide.txt for help/info on IDE drives + */ +#undef CONFIG_BLK_DEV_IDE_SATA +#undef CONFIG_BLK_DEV_HD_IDE +#define CONFIG_BLK_DEV_IDEDISK 1 +#define CONFIG_IDEDISK_MULTI_MODE 1 +#define CONFIG_BLK_DEV_IDECS_MODULE 1 +#define CONFIG_BLK_DEV_IDECD 1 +#undef CONFIG_BLK_DEV_IDETAPE +#define CONFIG_BLK_DEV_IDEFLOPPY 1 +#define CONFIG_BLK_DEV_IDESCSI_MODULE 1 +#define CONFIG_IDE_TASK_IOCTL 1 + +/* + * IDE chipset support/bugfixes + */ +#define CONFIG_IDE_GENERIC 1 +#define CONFIG_BLK_DEV_CMD640 1 +#define CONFIG_BLK_DEV_CMD640_ENHANCED 1 +#define CONFIG_BLK_DEV_IDEPNP 1 +#define CONFIG_BLK_DEV_IDEPCI 1 +#define CONFIG_IDEPCI_SHARE_IRQ 1 +#undef CONFIG_BLK_DEV_OFFBOARD +#define CONFIG_BLK_DEV_GENERIC 1 +#undef CONFIG_BLK_DEV_OPTI621 +#define CONFIG_BLK_DEV_RZ1000 1 +#define CONFIG_BLK_DEV_IDEDMA_PCI 1 +#undef CONFIG_BLK_DEV_IDEDMA_FORCED +#define CONFIG_IDEDMA_PCI_AUTO 1 +#undef CONFIG_IDEDMA_ONLYDISK +#define CONFIG_BLK_DEV_AEC62XX 1 +#define CONFIG_BLK_DEV_ALI15X3 1 +#undef CONFIG_WDC_ALI15X3 +#define CONFIG_BLK_DEV_AMD74XX 1 +#define CONFIG_BLK_DEV_ATIIXP 1 +#define CONFIG_BLK_DEV_CMD64X 1 +#define CONFIG_BLK_DEV_TRIFLEX 1 +#define CONFIG_BLK_DEV_CY82C693 1 +#define CONFIG_BLK_DEV_CS5520 1 +#define CONFIG_BLK_DEV_CS5530 1 +#define CONFIG_BLK_DEV_CS5535 1 +#define CONFIG_BLK_DEV_HPT34X 1 +#undef CONFIG_HPT34X_AUTODMA +#define CONFIG_BLK_DEV_HPT366 1 +#undef CONFIG_BLK_DEV_SC1200 +#define CONFIG_BLK_DEV_PIIX 1 +#define CONFIG_BLK_DEV_IT821X 1 +#undef CONFIG_BLK_DEV_NS87415 +#define CONFIG_BLK_DEV_PDC202XX_OLD 1 +#undef CONFIG_PDC202XX_BURST +#define CONFIG_BLK_DEV_PDC202XX_NEW 1 +#define CONFIG_BLK_DEV_SVWKS 1 +#define CONFIG_BLK_DEV_SIIMAGE 1 +#define CONFIG_BLK_DEV_SIS5513 1 +#define CONFIG_BLK_DEV_SLC90E66 1 +#undef CONFIG_BLK_DEV_TRM290 +#define CONFIG_BLK_DEV_VIA82CXXX 1 +#undef CONFIG_IDE_ARM +#undef CONFIG_IDE_CHIPSETS +#define CONFIG_BLK_DEV_IDEDMA 1 +#undef CONFIG_IDEDMA_IVB +#define CONFIG_IDEDMA_AUTO 1 +#undef CONFIG_BLK_DEV_HD /* - * Bridge: Netfilter Configuration + * SCSI device support */ -#define CONFIG_BRIDGE_NF_EBTABLES_MODULE 1 -#define CONFIG_BRIDGE_EBT_BROUTE_MODULE 1 -#define CONFIG_BRIDGE_EBT_T_FILTER_MODULE 1 -#define CONFIG_BRIDGE_EBT_T_NAT_MODULE 1 -#define CONFIG_BRIDGE_EBT_802_3_MODULE 1 -#define CONFIG_BRIDGE_EBT_AMONG_MODULE 1 -#define CONFIG_BRIDGE_EBT_ARP_MODULE 1 -#define CONFIG_BRIDGE_EBT_IP_MODULE 1 -#define CONFIG_BRIDGE_EBT_LIMIT_MODULE 1 -#define CONFIG_BRIDGE_EBT_MARK_MODULE 1 -#define CONFIG_BRIDGE_EBT_PKTTYPE_MODULE 1 -#define CONFIG_BRIDGE_EBT_STP_MODULE 1 -#define CONFIG_BRIDGE_EBT_VLAN_MODULE 1 -#define CONFIG_BRIDGE_EBT_ARPREPLY_MODULE 1 -#define CONFIG_BRIDGE_EBT_DNAT_MODULE 1 -#define CONFIG_BRIDGE_EBT_MARK_T_MODULE 1 -#define CONFIG_BRIDGE_EBT_REDIRECT_MODULE 1 -#define CONFIG_BRIDGE_EBT_SNAT_MODULE 1 -#define CONFIG_BRIDGE_EBT_LOG_MODULE 1 -#define CONFIG_XFRM 1 -#define CONFIG_XFRM_USER 1 +#define CONFIG_RAID_ATTRS_MODULE 1 +#define CONFIG_SCSI_MODULE 1 +#define CONFIG_SCSI_PROC_FS 1 /* - * SCTP Configuration (EXPERIMENTAL) + * SCSI support type (disk, tape, CD-ROM) */ -#define CONFIG_IP_SCTP_MODULE 1 -#undef CONFIG_SCTP_DBG_MSG -#undef CONFIG_SCTP_DBG_OBJCNT -#undef CONFIG_SCTP_HMAC_NONE -#undef CONFIG_SCTP_HMAC_SHA1 -#define CONFIG_SCTP_HMAC_MD5 1 -#undef CONFIG_ATM -#define CONFIG_BRIDGE_MODULE 1 -#define CONFIG_VLAN_8021Q_MODULE 1 -#undef CONFIG_DECNET -#define CONFIG_LLC_MODULE 1 -#undef CONFIG_LLC2 -#define CONFIG_IPX_MODULE 1 -#undef CONFIG_IPX_INTERN -#define CONFIG_ATALK_MODULE 1 -#define CONFIG_DEV_APPLETALK 1 -#define CONFIG_LTPC_MODULE 1 -#define CONFIG_COPS_MODULE 1 -#define CONFIG_COPS_DAYNA 1 -#define CONFIG_COPS_TANGENT 1 -#define CONFIG_IPDDP_MODULE 1 -#define CONFIG_IPDDP_ENCAP 1 -#define CONFIG_IPDDP_DECAP 1 -#undef CONFIG_X25 -#undef CONFIG_LAPB -#define CONFIG_NET_DIVERT 1 -#undef CONFIG_ECONET -#define CONFIG_WAN_ROUTER_MODULE 1 -#undef CONFIG_NET_FASTROUTE -#undef CONFIG_NET_HW_FLOWCONTROL +#define CONFIG_BLK_DEV_SD_MODULE 1 +#define CONFIG_CHR_DEV_ST_MODULE 1 +#define CONFIG_CHR_DEV_OSST_MODULE 1 +#define CONFIG_BLK_DEV_SR_MODULE 1 +#define CONFIG_BLK_DEV_SR_VENDOR 1 +#define CONFIG_CHR_DEV_SG_MODULE 1 +#define CONFIG_CHR_DEV_SCH_MODULE 1 /* - * QoS and/or fair queueing + * Some SCSI devices (e.g. CD jukebox) support multiple LUNs */ -#define CONFIG_NET_SCHED 1 -#define CONFIG_NET_SCH_CBQ_MODULE 1 -#define CONFIG_NET_SCH_HTB_MODULE 1 -#define CONFIG_NET_SCH_HFSC_MODULE 1 -#define CONFIG_NET_SCH_CSZ_MODULE 1 -#define CONFIG_NET_SCH_PRIO_MODULE 1 -#define CONFIG_NET_SCH_RED_MODULE 1 -#define CONFIG_NET_SCH_SFQ_MODULE 1 -#define CONFIG_NET_SCH_TEQL_MODULE 1 -#define CONFIG_NET_SCH_TBF_MODULE 1 -#define CONFIG_NET_SCH_GRED_MODULE 1 -#define CONFIG_NET_SCH_DSMARK_MODULE 1 -#define CONFIG_NET_SCH_DELAY_MODULE 1 -#define CONFIG_NET_SCH_INGRESS_MODULE 1 -#define CONFIG_NET_QOS 1 -#define CONFIG_NET_ESTIMATOR 1 -#define CONFIG_NET_CLS 1 -#define CONFIG_NET_CLS_TCINDEX_MODULE 1 -#define CONFIG_NET_CLS_ROUTE4_MODULE 1 -#define CONFIG_NET_CLS_ROUTE 1 -#define CONFIG_NET_CLS_FW_MODULE 1 -#define CONFIG_NET_CLS_U32_MODULE 1 -#define CONFIG_NET_CLS_RSVP_MODULE 1 -#define CONFIG_NET_CLS_RSVP6_MODULE 1 -#define CONFIG_NET_CLS_POLICE 1 +#define CONFIG_SCSI_MULTI_LUN 1 +#define CONFIG_SCSI_CONSTANTS 1 +#define CONFIG_SCSI_LOGGING 1 /* - * Network testing + * SCSI Transport Attributes */ -#undef CONFIG_NET_PKTGEN -#define CONFIG_NETPOLL 1 -#undef CONFIG_NETPOLL_RX -#undef CONFIG_NETPOLL_TRAP -#define CONFIG_NET_POLL_CONTROLLER 1 -#undef CONFIG_HAMRADIO -#define CONFIG_IRDA_MODULE 1 +#define CONFIG_SCSI_SPI_ATTRS_MODULE 1 +#define CONFIG_SCSI_FC_ATTRS_MODULE 1 +#define CONFIG_SCSI_ISCSI_ATTRS_MODULE 1 +#define CONFIG_SCSI_SAS_ATTRS_MODULE 1 /* - * IrDA protocols + * SCSI low-level drivers */ -#define CONFIG_IRLAN_MODULE 1 -#define CONFIG_IRNET_MODULE 1 -#define CONFIG_IRCOMM_MODULE 1 -#undef CONFIG_IRDA_ULTRA +#define CONFIG_ISCSI_TCP_MODULE 1 +#define CONFIG_BLK_DEV_3W_XXXX_RAID_MODULE 1 +#define CONFIG_SCSI_3W_9XXX_MODULE 1 +#undef CONFIG_SCSI_7000FASST +#define CONFIG_SCSI_ACARD_MODULE 1 +#define CONFIG_SCSI_AHA152X_MODULE 1 +#define CONFIG_SCSI_AHA1542_MODULE 1 +#define CONFIG_SCSI_AACRAID_MODULE 1 +#define CONFIG_SCSI_AIC7XXX_MODULE 1 +#define CONFIG_AIC7XXX_CMDS_PER_DEVICE 4 +#define CONFIG_AIC7XXX_RESET_DELAY_MS 15000 +#undef CONFIG_AIC7XXX_DEBUG_ENABLE +#define CONFIG_AIC7XXX_DEBUG_MASK 0 +#undef CONFIG_AIC7XXX_REG_PRETTY_PRINT +#define CONFIG_SCSI_AIC7XXX_OLD_MODULE 1 +#define CONFIG_SCSI_AIC79XX_MODULE 1 +#define CONFIG_AIC79XX_CMDS_PER_DEVICE 4 +#define CONFIG_AIC79XX_RESET_DELAY_MS 15000 +#undef CONFIG_AIC79XX_ENABLE_RD_STRM +#undef CONFIG_AIC79XX_DEBUG_ENABLE +#define CONFIG_AIC79XX_DEBUG_MASK 0 +#undef CONFIG_AIC79XX_REG_PRETTY_PRINT +#undef CONFIG_SCSI_DPT_I2O +#define CONFIG_SCSI_ADVANSYS_MODULE 1 +#undef CONFIG_SCSI_IN2000 +#define CONFIG_MEGARAID_NEWGEN 1 +#define CONFIG_MEGARAID_MM_MODULE 1 +#define CONFIG_MEGARAID_MAILBOX_MODULE 1 +#define CONFIG_MEGARAID_LEGACY_MODULE 1 +#define CONFIG_MEGARAID_SAS_MODULE 1 +#define CONFIG_SCSI_SATA_MODULE 1 +#define CONFIG_SCSI_SATA_AHCI_MODULE 1 +#define CONFIG_SCSI_SATA_SVW_MODULE 1 +#define CONFIG_SCSI_ATA_PIIX_MODULE 1 +#define CONFIG_SCSI_SATA_MV_MODULE 1 +#define CONFIG_SCSI_SATA_NV_MODULE 1 +#define CONFIG_SCSI_PDC_ADMA_MODULE 1 +#define CONFIG_SCSI_SATA_QSTOR_MODULE 1 +#define CONFIG_SCSI_SATA_PROMISE_MODULE 1 +#define CONFIG_SCSI_SATA_SX4_MODULE 1 +#define CONFIG_SCSI_SATA_SIL_MODULE 1 +#define CONFIG_SCSI_SATA_SIL24_MODULE 1 +#define CONFIG_SCSI_SATA_SIS_MODULE 1 +#define CONFIG_SCSI_SATA_ULI_MODULE 1 +#define CONFIG_SCSI_SATA_VIA_MODULE 1 +#define CONFIG_SCSI_SATA_VITESSE_MODULE 1 +#define CONFIG_SCSI_SATA_INTEL_COMBINED 1 +#define CONFIG_SCSI_BUSLOGIC_MODULE 1 +#undef CONFIG_SCSI_OMIT_FLASHPOINT +#undef CONFIG_SCSI_DMX3191D +#undef CONFIG_SCSI_DTC3280 +#undef CONFIG_SCSI_EATA +#define CONFIG_SCSI_FUTURE_DOMAIN_MODULE 1 +#define CONFIG_SCSI_GDTH_MODULE 1 +#undef CONFIG_SCSI_GENERIC_NCR5380 +#undef CONFIG_SCSI_GENERIC_NCR5380_MMIO +#define CONFIG_SCSI_IPS_MODULE 1 +#define CONFIG_SCSI_INITIO_MODULE 1 +#define CONFIG_SCSI_INIA100_MODULE 1 +#define CONFIG_SCSI_PPA_MODULE 1 +#define CONFIG_SCSI_IMM_MODULE 1 +#undef CONFIG_SCSI_IZIP_EPP16 +#undef CONFIG_SCSI_IZIP_SLOW_CTR +#undef CONFIG_SCSI_NCR53C406A +#define CONFIG_SCSI_SYM53C8XX_2_MODULE 1 +#define CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE 1 +#define CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS 16 +#define CONFIG_SCSI_SYM53C8XX_MAX_TAGS 64 +#define CONFIG_SCSI_SYM53C8XX_MMIO 1 +#undef CONFIG_SCSI_IPR +#undef CONFIG_SCSI_PAS16 +#undef CONFIG_SCSI_PSI240I +#undef CONFIG_SCSI_QLOGIC_FAS +#define CONFIG_SCSI_QLOGIC_1280_MODULE 1 +#define CONFIG_SCSI_QLA_FC_MODULE 1 +#define CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE 1 +#define CONFIG_SCSI_QLA21XX_MODULE 1 +#define CONFIG_SCSI_QLA22XX_MODULE 1 +#define CONFIG_SCSI_QLA2300_MODULE 1 +#define CONFIG_SCSI_QLA2322_MODULE 1 +#define CONFIG_SCSI_QLA24XX_MODULE 1 +#define CONFIG_SCSI_LPFC_MODULE 1 +#undef CONFIG_SCSI_SYM53C416 +#define CONFIG_SCSI_DC395x_MODULE 1 +#define CONFIG_SCSI_DC390T_MODULE 1 +#undef CONFIG_SCSI_T128 +#undef CONFIG_SCSI_U14_34F +#undef CONFIG_SCSI_ULTRASTOR +#undef CONFIG_SCSI_NSP32 +#undef CONFIG_SCSI_DEBUG /* - * IrDA options + * PCMCIA SCSI adapter support */ -#define CONFIG_IRDA_CACHE_LAST_LSAP 1 -#define CONFIG_IRDA_FAST_RR 1 -#undef CONFIG_IRDA_DEBUG +#define CONFIG_PCMCIA_AHA152X_MODULE 1 +#define CONFIG_PCMCIA_FDOMAIN_MODULE 1 +#define CONFIG_PCMCIA_NINJA_SCSI_MODULE 1 +#define CONFIG_PCMCIA_QLOGIC_MODULE 1 +#define CONFIG_PCMCIA_SYM53C500_MODULE 1 /* - * Infrared-port device drivers + * Old CD-ROM drivers (not SCSI, not IDE) */ +#undef CONFIG_CD_NO_IDESCSI /* - * SIR device drivers + * Multi-device support (RAID and LVM) */ -#define CONFIG_IRTTY_SIR_MODULE 1 +#define CONFIG_MD 1 +#define CONFIG_BLK_DEV_MD 1 +#define CONFIG_MD_LINEAR_MODULE 1 +#define CONFIG_MD_RAID0_MODULE 1 +#define CONFIG_MD_RAID1_MODULE 1 +#define CONFIG_MD_RAID10_MODULE 1 +#define CONFIG_MD_RAID5_MODULE 1 +#define CONFIG_MD_RAID5_RESHAPE 1 +#define CONFIG_MD_RAID6_MODULE 1 +#define CONFIG_MD_MULTIPATH_MODULE 1 +#define CONFIG_MD_FAULTY_MODULE 1 +#define CONFIG_BLK_DEV_DM_MODULE 1 +#define CONFIG_DM_CRYPT_MODULE 1 +#define CONFIG_DM_SNAPSHOT_MODULE 1 +#define CONFIG_DM_MIRROR_MODULE 1 +#define CONFIG_DM_ZERO_MODULE 1 +#define CONFIG_DM_MULTIPATH_MODULE 1 +#define CONFIG_DM_MULTIPATH_EMC_MODULE 1 /* - * Dongle support + * Fusion MPT device support */ -#define CONFIG_DONGLE 1 -#define CONFIG_ESI_DONGLE_MODULE 1 -#define CONFIG_ACTISYS_DONGLE_MODULE 1 -#define CONFIG_TEKRAM_DONGLE_MODULE 1 -#define CONFIG_LITELINK_DONGLE_MODULE 1 -#define CONFIG_MA600_DONGLE_MODULE 1 -#define CONFIG_GIRBIL_DONGLE_MODULE 1 -#define CONFIG_MCP2120_DONGLE_MODULE 1 -#define CONFIG_OLD_BELKIN_DONGLE_MODULE 1 -#define CONFIG_ACT200L_DONGLE_MODULE 1 +#define CONFIG_FUSION 1 +#define CONFIG_FUSION_SPI_MODULE 1 +#define CONFIG_FUSION_FC_MODULE 1 +#define CONFIG_FUSION_SAS_MODULE 1 +#define CONFIG_FUSION_MAX_SGE 40 +#define CONFIG_FUSION_CTL_MODULE 1 +#define CONFIG_FUSION_LAN_MODULE 1 /* - * Old SIR device drivers + * IEEE 1394 (FireWire) support */ +#define CONFIG_IEEE1394_MODULE 1 /* - * Old Serial dongle support + * Subsystem Options */ +#undef CONFIG_IEEE1394_VERBOSEDEBUG +#define CONFIG_IEEE1394_OUI_DB 1 +#define CONFIG_IEEE1394_EXTRA_CONFIG_ROMS 1 +#define CONFIG_IEEE1394_CONFIG_ROM_IP1394 1 +#undef CONFIG_IEEE1394_EXPORT_FULL_API /* - * FIR device drivers + * Device Drivers */ -#define CONFIG_USB_IRDA_MODULE 1 -#define CONFIG_SIGMATEL_FIR_MODULE 1 -#define CONFIG_NSC_FIR_MODULE 1 -#undef CONFIG_WINBOND_FIR -#undef CONFIG_TOSHIBA_FIR -#undef CONFIG_SMC_IRCC_FIR -#undef CONFIG_ALI_FIR -#undef CONFIG_VLSI_FIR -#undef CONFIG_VIA_FIR -#define CONFIG_BT_MODULE 1 -#define CONFIG_BT_L2CAP_MODULE 1 -#define CONFIG_BT_SCO_MODULE 1 -#define CONFIG_BT_RFCOMM_MODULE 1 -#define CONFIG_BT_RFCOMM_TTY 1 -#define CONFIG_BT_BNEP_MODULE 1 -#define CONFIG_BT_BNEP_MC_FILTER 1 -#define CONFIG_BT_BNEP_PROTO_FILTER 1 -#define CONFIG_BT_CMTP_MODULE 1 +#define CONFIG_IEEE1394_PCILYNX_MODULE 1 +#define CONFIG_IEEE1394_OHCI1394_MODULE 1 /* - * Bluetooth device drivers + * Protocol Drivers */ -#define CONFIG_BT_HCIUSB_MODULE 1 -#define CONFIG_BT_HCIUSB_SCO 1 -#define CONFIG_BT_HCIUART_MODULE 1 -#define CONFIG_BT_HCIUART_H4 1 -#define CONFIG_BT_HCIUART_BCSP 1 -#define CONFIG_BT_HCIUART_BCSP_TXCRC 1 -#define CONFIG_BT_HCIBCM203X_MODULE 1 -#define CONFIG_BT_HCIBFUSB_MODULE 1 -#define CONFIG_BT_HCIDTL1_MODULE 1 -#define CONFIG_BT_HCIBT3C_MODULE 1 -#define CONFIG_BT_HCIBLUECARD_MODULE 1 -#define CONFIG_BT_HCIBTUART_MODULE 1 -#define CONFIG_BT_HCIVHCI_MODULE 1 -#define CONFIG_TUX_MODULE 1 +#define CONFIG_IEEE1394_VIDEO1394_MODULE 1 +#define CONFIG_IEEE1394_SBP2_MODULE 1 +#undef CONFIG_IEEE1394_SBP2_PHYS_DMA +#define CONFIG_IEEE1394_ETH1394_MODULE 1 +#define CONFIG_IEEE1394_DV1394_MODULE 1 +#define CONFIG_IEEE1394_RAWIO_MODULE 1 /* - * TUX options + * I2O device support + */ +#define CONFIG_I2O_MODULE 1 +#undef CONFIG_I2O_LCT_NOTIFY_ON_CHANGES +#define CONFIG_I2O_EXT_ADAPTEC 1 +#define CONFIG_I2O_CONFIG_MODULE 1 +#define CONFIG_I2O_CONFIG_OLD_IOCTL 1 +#define CONFIG_I2O_BUS_MODULE 1 +#define CONFIG_I2O_BLOCK_MODULE 1 +#define CONFIG_I2O_SCSI_MODULE 1 +#define CONFIG_I2O_PROC_MODULE 1 + +/* + * Network device support */ -#define CONFIG_TUX_EXTCGI 1 -#undef CONFIG_TUX_EXTENDED_LOG -#undef CONFIG_TUX_DEBUG #define CONFIG_NETDEVICES 1 #define CONFIG_DUMMY_MODULE 1 #define CONFIG_BONDING_MODULE 1 #define CONFIG_EQUALIZER_MODULE 1 #define CONFIG_TUN_MODULE 1 -#define CONFIG_ETHERTAP_MODULE 1 #define CONFIG_NET_SB1000_MODULE 1 /* @@ -1028,6 +1328,20 @@ */ #undef CONFIG_ARCNET +/* + * PHY device support + */ +#define CONFIG_PHYLIB_MODULE 1 + +/* + * MII PHY device drivers + */ +#define CONFIG_MARVELL_PHY_MODULE 1 +#define CONFIG_DAVICOM_PHY_MODULE 1 +#define CONFIG_QSEMI_PHY_MODULE 1 +#define CONFIG_LXT_PHY_MODULE 1 +#define CONFIG_CICADA_PHY_MODULE 1 + /* * Ethernet (10 or 100Mbit) */ @@ -1035,23 +1349,22 @@ #define CONFIG_MII_MODULE 1 #define CONFIG_HAPPYMEAL_MODULE 1 #define CONFIG_SUNGEM_MODULE 1 +#define CONFIG_CASSINI_MODULE 1 #define CONFIG_NET_VENDOR_3COM 1 -#define CONFIG_EL1_MODULE 1 -#define CONFIG_EL2_MODULE 1 -#define CONFIG_ELPLUS_MODULE 1 -#define CONFIG_EL16_MODULE 1 +#undef CONFIG_EL1 +#undef CONFIG_EL2 +#undef CONFIG_ELPLUS +#undef CONFIG_EL16 #define CONFIG_EL3_MODULE 1 -#define CONFIG_3C515_MODULE 1 +#undef CONFIG_3C515 #define CONFIG_VORTEX_MODULE 1 #define CONFIG_TYPHOON_MODULE 1 -#define CONFIG_LANCE_MODULE 1 +#undef CONFIG_LANCE #define CONFIG_NET_VENDOR_SMC 1 -#define CONFIG_WD80x3_MODULE 1 +#undef CONFIG_WD80x3 #define CONFIG_ULTRA_MODULE 1 -#define CONFIG_SMC9194_MODULE 1 -#define CONFIG_NET_VENDOR_RACAL 1 -#define CONFIG_NI52_MODULE 1 -#define CONFIG_NI65_MODULE 1 +#undef CONFIG_SMC9194 +#undef CONFIG_NET_VENDOR_RACAL /* * Tulip family network device support @@ -1065,34 +1378,44 @@ #define CONFIG_DE4X5_MODULE 1 #define CONFIG_WINBOND_840_MODULE 1 #define CONFIG_DM9102_MODULE 1 +#define CONFIG_ULI526X_MODULE 1 #define CONFIG_PCMCIA_XIRCOM_MODULE 1 +#undef CONFIG_PCMCIA_XIRTULIP #undef CONFIG_AT1700 -#define CONFIG_DEPCA_MODULE 1 +#undef CONFIG_DEPCA #define CONFIG_HP100_MODULE 1 -#undef CONFIG_NET_ISA +#define CONFIG_NET_ISA 1 +#undef CONFIG_E2100 +#define CONFIG_EWRK3_MODULE 1 +#undef CONFIG_EEXPRESS +#undef CONFIG_EEXPRESS_PRO +#undef CONFIG_HPLAN_PLUS +#undef CONFIG_HPLAN +#undef CONFIG_LP486E +#undef CONFIG_ETH16I #define CONFIG_NE2000_MODULE 1 +#undef CONFIG_ZNET +#undef CONFIG_SEEQ8005 #define CONFIG_NET_PCI 1 #define CONFIG_PCNET32_MODULE 1 #define CONFIG_AMD8111_ETH_MODULE 1 #define CONFIG_AMD8111E_NAPI 1 #define CONFIG_ADAPTEC_STARFIRE_MODULE 1 #define CONFIG_ADAPTEC_STARFIRE_NAPI 1 -#define CONFIG_AC3200_MODULE 1 -#define CONFIG_APRICOT_MODULE 1 +#undef CONFIG_AC3200 +#undef CONFIG_APRICOT #define CONFIG_B44_MODULE 1 #define CONFIG_FORCEDETH_MODULE 1 -#define CONFIG_CS89x0_MODULE 1 +#undef CONFIG_CS89x0 #define CONFIG_DGRS_MODULE 1 -#define CONFIG_EEPRO100_MODULE 1 -#undef CONFIG_EEPRO100_PIO +#undef CONFIG_EEPRO100 #define CONFIG_E100_MODULE 1 -#define CONFIG_E100_NAPI 1 #define CONFIG_FEALNX_MODULE 1 #define CONFIG_NATSEMI_MODULE 1 #define CONFIG_NE2K_PCI_MODULE 1 #define CONFIG_8139CP_MODULE 1 #define CONFIG_8139TOO_MODULE 1 -#define CONFIG_8139TOO_PIO 1 +#undef CONFIG_8139TOO_PIO #undef CONFIG_8139TOO_TUNE_TWISTER #define CONFIG_8139TOO_8129 1 #undef CONFIG_8139_OLD_RX_RESET @@ -1109,20 +1432,32 @@ #define CONFIG_DE620_MODULE 1 /* - * Gigabit Ethernet (1000/10000 Mbit) + * Ethernet (1000 Mbit) */ -#define CONFIG_NET_GIGE 1 #define CONFIG_ACENIC_MODULE 1 #undef CONFIG_ACENIC_OMIT_TIGON_I #define CONFIG_DL2K_MODULE 1 #define CONFIG_E1000_MODULE 1 #define CONFIG_E1000_NAPI 1 +#undef CONFIG_E1000_DISABLE_PACKET_SPLIT #define CONFIG_NS83820_MODULE 1 #define CONFIG_HAMACHI_MODULE 1 #define CONFIG_YELLOWFIN_MODULE 1 #define CONFIG_R8169_MODULE 1 -#define CONFIG_SK98LIN_MODULE 1 +#define CONFIG_R8169_NAPI 1 +#define CONFIG_R8169_VLAN 1 +#define CONFIG_SIS190_MODULE 1 +#define CONFIG_SKGE_MODULE 1 +#define CONFIG_SKY2_MODULE 1 +#undef CONFIG_SK98LIN +#define CONFIG_VIA_VELOCITY_MODULE 1 #define CONFIG_TIGON3_MODULE 1 +#define CONFIG_BNX2_MODULE 1 + +/* + * Ethernet (10000 Mbit) + */ +#define CONFIG_CHELSIO_T1_MODULE 1 #define CONFIG_IXGB_MODULE 1 #define CONFIG_IXGB_NAPI 1 #define CONFIG_S2IO_MODULE 1 @@ -1131,19 +1466,26 @@ /* * Token Ring devices */ -#undef CONFIG_TR +#define CONFIG_TR 1 +#undef CONFIG_IBMTR +#define CONFIG_IBMOL_MODULE 1 +#define CONFIG_IBMLS_MODULE 1 +#define CONFIG_3C359_MODULE 1 +#undef CONFIG_TMS380TR +#undef CONFIG_SMCTR /* * Wireless LAN (non-hamradio) */ #define CONFIG_NET_RADIO 1 +#define CONFIG_NET_WIRELESS_RTNETLINK 1 /* * Obsolete Wireless cards support (pre-802.11) */ #undef CONFIG_STRIP #undef CONFIG_ARLAN -#define CONFIG_WAVELAN_MODULE 1 +#undef CONFIG_WAVELAN #define CONFIG_PCMCIA_WAVELAN_MODULE 1 #define CONFIG_PCMCIA_NETWAVE_MODULE 1 @@ -1155,10 +1497,18 @@ /* * Wireless 802.11b ISA/PCI cards support */ +#define CONFIG_IPW2100_MODULE 1 +#define CONFIG_IPW2100_MONITOR 1 +#undef CONFIG_IPW2100_DEBUG +#define CONFIG_IPW2200_MODULE 1 +#define CONFIG_IPW2200_MONITOR 1 +#define CONFIG_IPW_QOS 1 +#undef CONFIG_IPW2200_DEBUG #define CONFIG_AIRO_MODULE 1 #define CONFIG_HERMES_MODULE 1 #define CONFIG_PLX_HERMES_MODULE 1 #define CONFIG_TMD_HERMES_MODULE 1 +#define CONFIG_NORTEL_HERMES_MODULE 1 #define CONFIG_PCI_HERMES_MODULE 1 #define CONFIG_ATMEL_MODULE 1 #define CONFIG_PCI_ATMEL_MODULE 1 @@ -1167,6 +1517,7 @@ * Wireless 802.11b Pcmcia/Cardbus cards support */ #define CONFIG_PCMCIA_HERMES_MODULE 1 +#define CONFIG_PCMCIA_SPECTRUM_MODULE 1 #define CONFIG_AIRO_CS_MODULE 1 #define CONFIG_PCMCIA_ATMEL_MODULE 1 #define CONFIG_PCMCIA_WL3501_MODULE 1 @@ -1175,6 +1526,19 @@ * Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support */ #define CONFIG_PRISM54_MODULE 1 +#define CONFIG_HOSTAP_MODULE 1 +#define CONFIG_HOSTAP_FIRMWARE 1 +#define CONFIG_HOSTAP_FIRMWARE_NVRAM 1 +#define CONFIG_HOSTAP_PLX_MODULE 1 +#define CONFIG_HOSTAP_PCI_MODULE 1 +#define CONFIG_HOSTAP_CS_MODULE 1 +#define CONFIG_BCM43XX_MODULE 1 +#define CONFIG_BCM43XX_DEBUG 1 +#define CONFIG_BCM43XX_DMA 1 +#define CONFIG_BCM43XX_PIO 1 +#define CONFIG_BCM43XX_DMA_AND_PIO_MODE 1 +#undef CONFIG_BCM43XX_DMA_MODE +#undef CONFIG_BCM43XX_PIO_MODE #define CONFIG_NET_WIRELESS 1 /* @@ -1189,11 +1553,40 @@ #define CONFIG_PCMCIA_SMC91C92_MODULE 1 #define CONFIG_PCMCIA_XIRC2PS_MODULE 1 #define CONFIG_PCMCIA_AXNET_MODULE 1 +#define CONFIG_PCMCIA_IBMTR_MODULE 1 /* * Wan interfaces */ #undef CONFIG_WAN + +/* + * ATM drivers + */ +#undef CONFIG_ATM_DUMMY +#define CONFIG_ATM_TCP_MODULE 1 +#define CONFIG_ATM_LANAI_MODULE 1 +#define CONFIG_ATM_ENI_MODULE 1 +#undef CONFIG_ATM_ENI_DEBUG +#undef CONFIG_ATM_ENI_TUNE_BURST +#define CONFIG_ATM_FIRESTREAM_MODULE 1 +#undef CONFIG_ATM_ZATM +#define CONFIG_ATM_NICSTAR_MODULE 1 +#undef CONFIG_ATM_NICSTAR_USE_SUNI +#undef CONFIG_ATM_NICSTAR_USE_IDT77105 +#define CONFIG_ATM_IDT77252_MODULE 1 +#undef CONFIG_ATM_IDT77252_DEBUG +#undef CONFIG_ATM_IDT77252_RCV_ALL +#define CONFIG_ATM_IDT77252_USE_SUNI 1 +#define CONFIG_ATM_AMBASSADOR_MODULE 1 +#undef CONFIG_ATM_AMBASSADOR_DEBUG +#define CONFIG_ATM_HORIZON_MODULE 1 +#undef CONFIG_ATM_HORIZON_DEBUG +#undef CONFIG_ATM_IA +#define CONFIG_ATM_FORE200E_MAYBE_MODULE 1 +#undef CONFIG_ATM_FORE200E_PCA +#define CONFIG_ATM_HE_MODULE 1 +#undef CONFIG_ATM_HE_USE_SUNI #define CONFIG_FDDI 1 #undef CONFIG_DEFXX #define CONFIG_SKFP_MODULE 1 @@ -1206,11 +1599,20 @@ #define CONFIG_PPP_SYNC_TTY_MODULE 1 #define CONFIG_PPP_DEFLATE_MODULE 1 #undef CONFIG_PPP_BSDCOMP +#define CONFIG_PPP_MPPE_MODULE 1 #define CONFIG_PPPOE_MODULE 1 -#undef CONFIG_SLIP +#define CONFIG_PPPOATM_MODULE 1 +#define CONFIG_SLIP_MODULE 1 +#define CONFIG_SLIP_COMPRESSED 1 +#define CONFIG_SLIP_SMART 1 +#undef CONFIG_SLIP_MODE_SLIP6 #define CONFIG_NET_FC 1 #undef CONFIG_SHAPER #define CONFIG_NETCONSOLE_MODULE 1 +#define CONFIG_NETPOLL 1 +#undef CONFIG_NETPOLL_RX +#define CONFIG_NETPOLL_TRAP 1 +#define CONFIG_NET_POLL_CONTROLLER 1 /* * ISDN subsystem @@ -1232,6 +1634,8 @@ /* * ISDN feature submodules */ +#define CONFIG_ISDN_DRV_LOOP_MODULE 1 +#define CONFIG_ISDN_DIVERSION_MODULE 1 /* * ISDN4Linux hardware drivers @@ -1257,27 +1661,27 @@ /* * HiSax supported cards */ -#define CONFIG_HISAX_16_0 1 +#undef CONFIG_HISAX_16_0 #define CONFIG_HISAX_16_3 1 #define CONFIG_HISAX_TELESPCI 1 #define CONFIG_HISAX_S0BOX 1 -#define CONFIG_HISAX_AVM_A1 1 +#undef CONFIG_HISAX_AVM_A1 #define CONFIG_HISAX_FRITZPCI 1 #define CONFIG_HISAX_AVM_A1_PCMCIA 1 #define CONFIG_HISAX_ELSA 1 -#define CONFIG_HISAX_IX1MICROR2 1 +#undef CONFIG_HISAX_IX1MICROR2 #define CONFIG_HISAX_DIEHLDIVA 1 -#define CONFIG_HISAX_ASUSCOM 1 -#define CONFIG_HISAX_TELEINT 1 -#define CONFIG_HISAX_HFCS 1 +#undef CONFIG_HISAX_ASUSCOM +#undef CONFIG_HISAX_TELEINT +#undef CONFIG_HISAX_HFCS #define CONFIG_HISAX_SEDLBAUER 1 -#define CONFIG_HISAX_SPORTSTER 1 -#define CONFIG_HISAX_MIC 1 +#undef CONFIG_HISAX_SPORTSTER +#undef CONFIG_HISAX_MIC #define CONFIG_HISAX_NETJET 1 #define CONFIG_HISAX_NETJET_U 1 #define CONFIG_HISAX_NICCY 1 -#define CONFIG_HISAX_ISURF 1 -#define CONFIG_HISAX_HSTSAPHIR 1 +#undef CONFIG_HISAX_ISURF +#undef CONFIG_HISAX_HSTSAPHIR #define CONFIG_HISAX_BKM_A4T 1 #define CONFIG_HISAX_SCT_QUADRO 1 #define CONFIG_HISAX_GAZEL 1 @@ -1299,18 +1703,29 @@ * HiSax sub driver modules */ #define CONFIG_HISAX_ST5481_MODULE 1 -#define CONFIG_HISAX_HFCUSB_MODULE 1 +#undef CONFIG_HISAX_HFCUSB +#define CONFIG_HISAX_HFC4S8S_MODULE 1 #define CONFIG_HISAX_FRITZ_PCIPNP_MODULE 1 #define CONFIG_HISAX_HDLC 1 /* * Active cards */ -#define CONFIG_ISDN_DRV_ICN_MODULE 1 -#define CONFIG_ISDN_DRV_PCBIT_MODULE 1 -#define CONFIG_ISDN_DRV_SC_MODULE 1 -#define CONFIG_ISDN_DRV_ACT2000_MODULE 1 -#define CONFIG_ISDN_DRV_TPAM_MODULE 1 +#undef CONFIG_ISDN_DRV_ICN +#undef CONFIG_ISDN_DRV_PCBIT +#undef CONFIG_ISDN_DRV_SC +#undef CONFIG_ISDN_DRV_ACT2000 +#define CONFIG_HYSDN_MODULE 1 +#define CONFIG_HYSDN_CAPI 1 + +/* + * Siemens Gigaset + */ +#define CONFIG_ISDN_DRV_GIGASET_MODULE 1 +#define CONFIG_GIGASET_BASE_MODULE 1 +#define CONFIG_GIGASET_M105_MODULE 1 +#undef CONFIG_GIGASET_DEBUG +#undef CONFIG_GIGASET_UNDOCREQ /* * CAPI subsystem @@ -1331,6 +1746,14 @@ * Active AVM cards */ #define CONFIG_CAPI_AVM 1 +#undef CONFIG_ISDN_DRV_AVMB1_B1ISA +#define CONFIG_ISDN_DRV_AVMB1_B1PCI_MODULE 1 +#define CONFIG_ISDN_DRV_AVMB1_B1PCIV4 1 +#undef CONFIG_ISDN_DRV_AVMB1_T1ISA +#define CONFIG_ISDN_DRV_AVMB1_B1PCMCIA_MODULE 1 +#define CONFIG_ISDN_DRV_AVMB1_AVM_CS_MODULE 1 +#define CONFIG_ISDN_DRV_AVMB1_T1PCI_MODULE 1 +#define CONFIG_ISDN_DRV_AVMB1_C4_MODULE 1 /* * Active Eicon DIVA Server cards @@ -1365,24 +1788,6 @@ #define CONFIG_INPUT_EVDEV 1 #undef CONFIG_INPUT_EVBUG -/* - * Input I/O drivers - */ -#define CONFIG_GAMEPORT_MODULE 1 -#define CONFIG_SOUND_GAMEPORT_MODULE 1 -#define CONFIG_GAMEPORT_NS558_MODULE 1 -#define CONFIG_GAMEPORT_L4_MODULE 1 -#define CONFIG_GAMEPORT_EMU10K1_MODULE 1 -#define CONFIG_GAMEPORT_VORTEX_MODULE 1 -#define CONFIG_GAMEPORT_FM801_MODULE 1 -#define CONFIG_GAMEPORT_CS461x_MODULE 1 -#define CONFIG_SERIO 1 -#define CONFIG_SERIO_I8042 1 -#define CONFIG_SERIO_SERPORT 1 -#undef CONFIG_SERIO_CT82C710 -#undef CONFIG_SERIO_PARKBD -#undef CONFIG_SERIO_PCIPS2 - /* * Input Device Drivers */ @@ -1395,10 +1800,9 @@ #define CONFIG_INPUT_MOUSE 1 #define CONFIG_MOUSE_PS2 1 #define CONFIG_MOUSE_SERIAL_MODULE 1 -#define CONFIG_MOUSE_INPORT_MODULE 1 -#define CONFIG_MOUSE_ATIXL 1 -#define CONFIG_MOUSE_LOGIBM_MODULE 1 -#define CONFIG_MOUSE_PC110PAD_MODULE 1 +#undef CONFIG_MOUSE_INPORT +#undef CONFIG_MOUSE_LOGIBM +#undef CONFIG_MOUSE_PC110PAD #define CONFIG_MOUSE_VSXXXAA_MODULE 1 #define CONFIG_INPUT_JOYSTICK 1 #define CONFIG_JOYSTICK_ANALOG_MODULE 1 @@ -1420,16 +1824,37 @@ #define CONFIG_JOYSTICK_SPACEORB_MODULE 1 #define CONFIG_JOYSTICK_SPACEBALL_MODULE 1 #define CONFIG_JOYSTICK_STINGER_MODULE 1 -#define CONFIG_JOYSTICK_TWIDDLER_MODULE 1 +#define CONFIG_JOYSTICK_TWIDJOY_MODULE 1 #define CONFIG_JOYSTICK_DB9_MODULE 1 #define CONFIG_JOYSTICK_GAMECON_MODULE 1 #define CONFIG_JOYSTICK_TURBOGRAFX_MODULE 1 -#undef CONFIG_INPUT_JOYDUMP +#define CONFIG_JOYSTICK_JOYDUMP_MODULE 1 #define CONFIG_INPUT_TOUCHSCREEN 1 #define CONFIG_TOUCHSCREEN_GUNZE_MODULE 1 +#define CONFIG_TOUCHSCREEN_ELO_MODULE 1 +#define CONFIG_TOUCHSCREEN_MTOUCH_MODULE 1 +#define CONFIG_TOUCHSCREEN_MK712_MODULE 1 #define CONFIG_INPUT_MISC 1 #define CONFIG_INPUT_PCSPKR_MODULE 1 -#undef CONFIG_INPUT_UINPUT +#define CONFIG_INPUT_WISTRON_BTNS_MODULE 1 +#define CONFIG_INPUT_UINPUT_MODULE 1 + +/* + * Hardware I/O ports + */ +#define CONFIG_SERIO 1 +#define CONFIG_SERIO_I8042 1 +#define CONFIG_SERIO_SERPORT 1 +#undef CONFIG_SERIO_CT82C710 +#undef CONFIG_SERIO_PARKBD +#undef CONFIG_SERIO_PCIPS2 +#define CONFIG_SERIO_LIBPS2 1 +#define CONFIG_SERIO_RAW_MODULE 1 +#define CONFIG_GAMEPORT_MODULE 1 +#define CONFIG_GAMEPORT_NS558_MODULE 1 +#define CONFIG_GAMEPORT_L4_MODULE 1 +#define CONFIG_GAMEPORT_EMU10K1_MODULE 1 +#define CONFIG_GAMEPORT_FM801_MODULE 1 /* * Character devices @@ -1438,33 +1863,50 @@ #define CONFIG_VT_CONSOLE 1 #define CONFIG_HW_CONSOLE 1 #define CONFIG_SERIAL_NONSTANDARD 1 +#undef CONFIG_COMPUTONE #define CONFIG_ROCKETPORT_MODULE 1 #undef CONFIG_CYCLADES +#undef CONFIG_DIGIEPCA +#undef CONFIG_ESPSERIAL +#undef CONFIG_MOXA_INTELLIO +#undef CONFIG_MOXA_SMARTIO +#undef CONFIG_ISI #define CONFIG_SYNCLINK_MODULE 1 #define CONFIG_SYNCLINKMP_MODULE 1 +#undef CONFIG_SYNCLINK_GT #define CONFIG_N_HDLC_MODULE 1 -#define CONFIG_STALDRV 1 +#undef CONFIG_RISCOM8 +#undef CONFIG_SPECIALIX +#undef CONFIG_SX +#undef CONFIG_RIO +#undef CONFIG_STALDRV /* * Serial drivers */ #define CONFIG_SERIAL_8250 1 #define CONFIG_SERIAL_8250_CONSOLE 1 +#define CONFIG_SERIAL_8250_PCI 1 +#define CONFIG_SERIAL_8250_PNP 1 #define CONFIG_SERIAL_8250_CS_MODULE 1 -#undef CONFIG_SERIAL_8250_ACPI -#define CONFIG_SERIAL_8250_NR_UARTS 4 +#define CONFIG_SERIAL_8250_NR_UARTS 32 +#define CONFIG_SERIAL_8250_RUNTIME_UARTS 4 #define CONFIG_SERIAL_8250_EXTENDED 1 -#undef CONFIG_SERIAL_8250_MANY_PORTS +#define CONFIG_SERIAL_8250_MANY_PORTS 1 #define CONFIG_SERIAL_8250_SHARE_IRQ 1 #define CONFIG_SERIAL_8250_DETECT_IRQ 1 -#define CONFIG_SERIAL_8250_MULTIPORT 1 #define CONFIG_SERIAL_8250_RSA 1 +#undef CONFIG_SERIAL_8250_FOURPORT +#undef CONFIG_SERIAL_8250_ACCENT +#undef CONFIG_SERIAL_8250_BOCA +#undef CONFIG_SERIAL_8250_HUB6 /* * Non-8250 serial port support */ #define CONFIG_SERIAL_CORE 1 #define CONFIG_SERIAL_CORE_CONSOLE 1 +#undef CONFIG_SERIAL_JSM #define CONFIG_UNIX98_PTYS 1 #undef CONFIG_LEGACY_PTYS #define CONFIG_CRASH_MODULE 1 @@ -1472,7 +1914,6 @@ #define CONFIG_LP_CONSOLE 1 #define CONFIG_PPDEV_MODULE 1 #define CONFIG_TIPAR_MODULE 1 -#undef CONFIG_QIC02_TAPE /* * IPMI @@ -1482,6 +1923,7 @@ #define CONFIG_IPMI_DEVICE_INTERFACE_MODULE 1 #define CONFIG_IPMI_SI_MODULE 1 #define CONFIG_IPMI_WATCHDOG_MODULE 1 +#define CONFIG_IPMI_POWEROFF_MODULE 1 /* * Watchdog Cards @@ -1493,30 +1935,33 @@ * Watchdog Device Drivers */ #define CONFIG_SOFT_WATCHDOG_MODULE 1 -#define CONFIG_ACQUIRE_WDT_MODULE 1 -#define CONFIG_ADVANTECH_WDT_MODULE 1 +#undef CONFIG_ACQUIRE_WDT +#undef CONFIG_ADVANTECH_WDT #define CONFIG_ALIM1535_WDT_MODULE 1 #define CONFIG_ALIM7101_WDT_MODULE 1 -#define CONFIG_SC520_WDT_MODULE 1 -#define CONFIG_EUROTECH_WDT_MODULE 1 -#define CONFIG_IB700_WDT_MODULE 1 -#define CONFIG_WAFER_WDT_MODULE 1 +#undef CONFIG_SC520_WDT +#undef CONFIG_EUROTECH_WDT +#undef CONFIG_IB700_WDT +#define CONFIG_IBMASR_MODULE 1 +#undef CONFIG_WAFER_WDT +#define CONFIG_I6300ESB_WDT_MODULE 1 #define CONFIG_I8XX_TCO_MODULE 1 -#define CONFIG_SC1200_WDT_MODULE 1 -#undef CONFIG_SCx200_WDT +#undef CONFIG_SC1200_WDT #undef CONFIG_60XX_WDT -#define CONFIG_CPU5_WDT_MODULE 1 +#undef CONFIG_SBC8360_WDT +#undef CONFIG_CPU5_WDT #define CONFIG_W83627HF_WDT_MODULE 1 #define CONFIG_W83877F_WDT_MODULE 1 +#define CONFIG_W83977F_WDT_MODULE 1 #define CONFIG_MACHZ_WDT_MODULE 1 +#undef CONFIG_SBC_EPX_C3_WATCHDOG /* * ISA-based Watchdog Cards */ -#define CONFIG_PCWATCHDOG_MODULE 1 +#undef CONFIG_PCWATCHDOG #undef CONFIG_MIXCOMWD -#define CONFIG_WDT_MODULE 1 -#undef CONFIG_WDT_501 +#undef CONFIG_WDT /* * PCI-based Watchdog Cards @@ -1530,7 +1975,7 @@ */ #define CONFIG_USBPCWATCHDOG_MODULE 1 #define CONFIG_HW_RANDOM_MODULE 1 -#define CONFIG_NVRAM_MODULE 1 +#define CONFIG_NVRAM 1 #define CONFIG_RTC 1 #define CONFIG_DTLK_MODULE 1 #define CONFIG_R3964_MODULE 1 @@ -1540,36 +1985,50 @@ /* * Ftape, the floppy tape device driver */ +#undef CONFIG_FTAPE #define CONFIG_AGP 1 #define CONFIG_AGP_ALI 1 #define CONFIG_AGP_ATI 1 #define CONFIG_AGP_AMD 1 #define CONFIG_AGP_AMD64 1 #define CONFIG_AGP_INTEL 1 -#define CONFIG_AGP_INTEL_MCH 1 #define CONFIG_AGP_NVIDIA 1 #define CONFIG_AGP_SIS 1 #define CONFIG_AGP_SWORKS 1 #define CONFIG_AGP_VIA 1 #define CONFIG_AGP_EFFICEON 1 -#define CONFIG_DRM 1 +#define CONFIG_DRM_MODULE 1 #define CONFIG_DRM_TDFX_MODULE 1 -#define CONFIG_DRM_GAMMA_MODULE 1 #define CONFIG_DRM_R128_MODULE 1 #define CONFIG_DRM_RADEON_MODULE 1 #define CONFIG_DRM_I810_MODULE 1 #define CONFIG_DRM_I830_MODULE 1 +#define CONFIG_DRM_I915_MODULE 1 #define CONFIG_DRM_MGA_MODULE 1 #define CONFIG_DRM_SIS_MODULE 1 +#define CONFIG_DRM_VIA_MODULE 1 +#define CONFIG_DRM_SAVAGE_MODULE 1 /* * PCMCIA character devices */ #define CONFIG_SYNCLINK_CS_MODULE 1 +#define CONFIG_CARDMAN_4000_MODULE 1 +#define CONFIG_CARDMAN_4040_MODULE 1 #define CONFIG_MWAVE_MODULE 1 +#define CONFIG_CS5535_GPIO_MODULE 1 #undef CONFIG_RAW_DRIVER +#define CONFIG_HPET 1 +#undef CONFIG_HPET_RTC_IRQ +#undef CONFIG_HPET_MMAP #define CONFIG_HANGCHECK_TIMER_MODULE 1 +/* + * TPM devices + */ +#undef CONFIG_TCG_TPM +#undef CONFIG_TELCLOCK + /* * I2C support */ @@ -1581,6 +2040,7 @@ */ #define CONFIG_I2C_ALGOBIT_MODULE 1 #define CONFIG_I2C_ALGOPCF_MODULE 1 +#define CONFIG_I2C_ALGOPCA_MODULE 1 /* * I2C Hardware Bus support @@ -1589,57 +2049,112 @@ #define CONFIG_I2C_ALI1563_MODULE 1 #define CONFIG_I2C_ALI15X3_MODULE 1 #define CONFIG_I2C_AMD756_MODULE 1 +#define CONFIG_I2C_AMD756_S4882_MODULE 1 #define CONFIG_I2C_AMD8111_MODULE 1 +#undef CONFIG_I2C_ELEKTOR #define CONFIG_I2C_I801_MODULE 1 #define CONFIG_I2C_I810_MODULE 1 +#define CONFIG_I2C_PIIX4_MODULE 1 #define CONFIG_I2C_ISA_MODULE 1 #define CONFIG_I2C_NFORCE2_MODULE 1 -#undef CONFIG_I2C_PARPORT -#undef CONFIG_I2C_PARPORT_LIGHT -#define CONFIG_I2C_PIIX4_MODULE 1 +#define CONFIG_I2C_PARPORT_MODULE 1 +#define CONFIG_I2C_PARPORT_LIGHT_MODULE 1 #define CONFIG_I2C_PROSAVAGE_MODULE 1 #define CONFIG_I2C_SAVAGE4_MODULE 1 #undef CONFIG_SCx200_ACB #define CONFIG_I2C_SIS5595_MODULE 1 #define CONFIG_I2C_SIS630_MODULE 1 #define CONFIG_I2C_SIS96X_MODULE 1 +#define CONFIG_I2C_STUB_MODULE 1 #define CONFIG_I2C_VIA_MODULE 1 #define CONFIG_I2C_VIAPRO_MODULE 1 #define CONFIG_I2C_VOODOO3_MODULE 1 +#define CONFIG_I2C_PCA_ISA_MODULE 1 + +/* + * Miscellaneous I2C Chip support + */ +#define CONFIG_SENSORS_DS1337_MODULE 1 +#define CONFIG_SENSORS_DS1374_MODULE 1 +#define CONFIG_SENSORS_EEPROM_MODULE 1 +#define CONFIG_SENSORS_PCF8574_MODULE 1 +#define CONFIG_SENSORS_PCA9539_MODULE 1 +#define CONFIG_SENSORS_PCF8591_MODULE 1 +#define CONFIG_SENSORS_MAX6875_MODULE 1 +#undef CONFIG_I2C_DEBUG_CORE +#undef CONFIG_I2C_DEBUG_ALGO +#undef CONFIG_I2C_DEBUG_BUS +#undef CONFIG_I2C_DEBUG_CHIP + +/* + * SPI support + */ +#undef CONFIG_SPI +#undef CONFIG_SPI_MASTER + +/* + * Dallas's 1-wire bus + */ +#define CONFIG_W1_MODULE 1 + +/* + * 1-wire Bus Masters + */ +#define CONFIG_W1_MASTER_MATROX_MODULE 1 +#define CONFIG_W1_MASTER_DS9490_MODULE 1 +#define CONFIG_W1_MASTER_DS9490_BRIDGE_MODULE 1 +#define CONFIG_W1_MASTER_DS2482_MODULE 1 + +/* + * 1-wire Slaves + */ +#define CONFIG_W1_SLAVE_THERM_MODULE 1 +#define CONFIG_W1_SLAVE_SMEM_MODULE 1 +#define CONFIG_W1_SLAVE_DS2433_MODULE 1 /* - * Hardware Sensors Chip support + * Hardware Monitoring support */ -#define CONFIG_I2C_SENSOR_MODULE 1 +#define CONFIG_HWMON_MODULE 1 +#define CONFIG_HWMON_VID_MODULE 1 #define CONFIG_SENSORS_ADM1021_MODULE 1 +#define CONFIG_SENSORS_ADM1025_MODULE 1 +#define CONFIG_SENSORS_ADM1026_MODULE 1 +#define CONFIG_SENSORS_ADM1031_MODULE 1 +#define CONFIG_SENSORS_ADM9240_MODULE 1 #define CONFIG_SENSORS_ASB100_MODULE 1 +#define CONFIG_SENSORS_ATXP1_MODULE 1 #define CONFIG_SENSORS_DS1621_MODULE 1 +#define CONFIG_SENSORS_F71805F_MODULE 1 #define CONFIG_SENSORS_FSCHER_MODULE 1 +#define CONFIG_SENSORS_FSCPOS_MODULE 1 #define CONFIG_SENSORS_GL518SM_MODULE 1 +#define CONFIG_SENSORS_GL520SM_MODULE 1 #define CONFIG_SENSORS_IT87_MODULE 1 +#define CONFIG_SENSORS_LM63_MODULE 1 #define CONFIG_SENSORS_LM75_MODULE 1 +#define CONFIG_SENSORS_LM77_MODULE 1 #define CONFIG_SENSORS_LM78_MODULE 1 #define CONFIG_SENSORS_LM80_MODULE 1 #define CONFIG_SENSORS_LM83_MODULE 1 #define CONFIG_SENSORS_LM85_MODULE 1 +#define CONFIG_SENSORS_LM87_MODULE 1 #define CONFIG_SENSORS_LM90_MODULE 1 +#define CONFIG_SENSORS_LM92_MODULE 1 #define CONFIG_SENSORS_MAX1619_MODULE 1 +#define CONFIG_SENSORS_PC87360_MODULE 1 +#define CONFIG_SENSORS_SIS5595_MODULE 1 +#define CONFIG_SENSORS_SMSC47M1_MODULE 1 +#define CONFIG_SENSORS_SMSC47B397_MODULE 1 #define CONFIG_SENSORS_VIA686A_MODULE 1 +#define CONFIG_SENSORS_VT8231_MODULE 1 #define CONFIG_SENSORS_W83781D_MODULE 1 +#define CONFIG_SENSORS_W83792D_MODULE 1 #define CONFIG_SENSORS_W83L785TS_MODULE 1 #define CONFIG_SENSORS_W83627HF_MODULE 1 - -/* - * Other I2C Chip support - */ -#define CONFIG_SENSORS_EEPROM_MODULE 1 -#define CONFIG_SENSORS_PCF8574_MODULE 1 -#define CONFIG_SENSORS_PCF8591_MODULE 1 -#define CONFIG_SENSORS_RTC8564_MODULE 1 -#undef CONFIG_I2C_DEBUG_CORE -#undef CONFIG_I2C_DEBUG_ALGO -#undef CONFIG_I2C_DEBUG_BUS -#undef CONFIG_I2C_DEBUG_CHIP +#define CONFIG_SENSORS_W83627EHF_MODULE 1 +#define CONFIG_SENSORS_HDAPS_MODULE 1 +#undef CONFIG_HWMON_DEBUG_CHIP /* * Misc devices @@ -1650,22 +2165,30 @@ * Multimedia devices */ #define CONFIG_VIDEO_DEV_MODULE 1 +#define CONFIG_VIDEO_V4L1 1 +#define CONFIG_VIDEO_V4L1_COMPAT 1 +#define CONFIG_VIDEO_V4L2_MODULE 1 /* - * Video For Linux + * Video Capture Adapters */ /* - * Video Adapters + * Video Capture Adapters */ +#undef CONFIG_VIDEO_ADV_DEBUG +#undef CONFIG_VIDEO_VIVI #define CONFIG_VIDEO_BT848_MODULE 1 -#define CONFIG_VIDEO_PMS_MODULE 1 +#define CONFIG_VIDEO_BT848_DVB 1 +#define CONFIG_VIDEO_SAA6588_MODULE 1 +#undef CONFIG_VIDEO_PMS #define CONFIG_VIDEO_BWQCAM_MODULE 1 #define CONFIG_VIDEO_CQCAM_MODULE 1 #define CONFIG_VIDEO_W9966_MODULE 1 #define CONFIG_VIDEO_CPIA_MODULE 1 #define CONFIG_VIDEO_CPIA_PP_MODULE 1 #define CONFIG_VIDEO_CPIA_USB_MODULE 1 +#define CONFIG_VIDEO_CPIA2_MODULE 1 #define CONFIG_VIDEO_SAA5246A_MODULE 1 #define CONFIG_VIDEO_SAA5249_MODULE 1 #define CONFIG_TUNER_3036_MODULE 1 @@ -1676,95 +2199,262 @@ #define CONFIG_VIDEO_ZORAN_DC30_MODULE 1 #define CONFIG_VIDEO_ZORAN_LML33_MODULE 1 #define CONFIG_VIDEO_ZORAN_LML33R10_MODULE 1 +#define CONFIG_VIDEO_MEYE_MODULE 1 #define CONFIG_VIDEO_SAA7134_MODULE 1 +#define CONFIG_VIDEO_SAA7134_ALSA_MODULE 1 +#define CONFIG_VIDEO_SAA7134_DVB_MODULE 1 +#define CONFIG_VIDEO_SAA7134_DVB_ALL_FRONTENDS 1 #define CONFIG_VIDEO_MXB_MODULE 1 #define CONFIG_VIDEO_DPC_MODULE 1 #define CONFIG_VIDEO_HEXIUM_ORION_MODULE 1 #define CONFIG_VIDEO_HEXIUM_GEMINI_MODULE 1 +#define CONFIG_VIDEO_CX88_VP3054_MODULE 1 #define CONFIG_VIDEO_CX88_MODULE 1 +#define CONFIG_VIDEO_CX88_ALSA_MODULE 1 +#define CONFIG_VIDEO_CX88_DVB_MODULE 1 +#define CONFIG_VIDEO_CX88_DVB_ALL_FRONTENDS 1 +#define CONFIG_VIDEO_OVCAMCHIP_MODULE 1 + +/* + * Encoders and Decoders + */ +#define CONFIG_VIDEO_MSP3400_MODULE 1 +#define CONFIG_VIDEO_CS53L32A_MODULE 1 +#define CONFIG_VIDEO_WM8775_MODULE 1 +#define CONFIG_VIDEO_WM8739_MODULE 1 +#define CONFIG_VIDEO_CX25840_MODULE 1 +#define CONFIG_VIDEO_SAA711X_MODULE 1 +#define CONFIG_VIDEO_SAA7127_MODULE 1 +#define CONFIG_VIDEO_UPD64031A_MODULE 1 +#define CONFIG_VIDEO_UPD64083_MODULE 1 + +/* + * V4L USB devices + */ +#define CONFIG_VIDEO_EM28XX_MODULE 1 +#define CONFIG_USB_DSBR_MODULE 1 +#define CONFIG_VIDEO_USBVIDEO_MODULE 1 +#define CONFIG_USB_VICAM_MODULE 1 +#define CONFIG_USB_IBMCAM_MODULE 1 +#define CONFIG_USB_KONICAWC_MODULE 1 +#define CONFIG_USB_ET61X251_MODULE 1 +#define CONFIG_USB_OV511_MODULE 1 +#define CONFIG_USB_SE401_MODULE 1 +#define CONFIG_USB_SN9C102_MODULE 1 +#define CONFIG_USB_STV680_MODULE 1 +#define CONFIG_USB_W9968CF_MODULE 1 +#define CONFIG_USB_ZC0301_MODULE 1 +#define CONFIG_USB_PWC_MODULE 1 /* * Radio Adapters */ -#define CONFIG_RADIO_CADET_MODULE 1 -#define CONFIG_RADIO_RTRACK_MODULE 1 -#define CONFIG_RADIO_RTRACK2_MODULE 1 -#define CONFIG_RADIO_AZTECH_MODULE 1 -#define CONFIG_RADIO_GEMTEK_MODULE 1 +#undef CONFIG_RADIO_CADET +#undef CONFIG_RADIO_RTRACK +#undef CONFIG_RADIO_RTRACK2 +#undef CONFIG_RADIO_AZTECH +#undef CONFIG_RADIO_GEMTEK #define CONFIG_RADIO_GEMTEK_PCI_MODULE 1 #define CONFIG_RADIO_MAXIRADIO_MODULE 1 #define CONFIG_RADIO_MAESTRO_MODULE 1 -#define CONFIG_RADIO_SF16FMI_MODULE 1 -#define CONFIG_RADIO_SF16FMR2_MODULE 1 -#define CONFIG_RADIO_TERRATEC_MODULE 1 -#define CONFIG_RADIO_TRUST_MODULE 1 -#define CONFIG_RADIO_TYPHOON_MODULE 1 -#define CONFIG_RADIO_TYPHOON_PROC_FS 1 -#define CONFIG_RADIO_ZOLTRIX_MODULE 1 +#undef CONFIG_RADIO_SF16FMI +#undef CONFIG_RADIO_SF16FMR2 +#undef CONFIG_RADIO_TERRATEC +#undef CONFIG_RADIO_TRUST +#undef CONFIG_RADIO_TYPHOON +#undef CONFIG_RADIO_ZOLTRIX /* * Digital Video Broadcasting Devices */ -#undef CONFIG_DVB +#define CONFIG_DVB 1 +#define CONFIG_DVB_CORE_MODULE 1 + +/* + * Supported SAA7146 based PCI Adapters + */ +#define CONFIG_DVB_AV7110_MODULE 1 +#define CONFIG_DVB_AV7110_OSD 1 +#define CONFIG_DVB_BUDGET_MODULE 1 +#define CONFIG_DVB_BUDGET_CI_MODULE 1 +#define CONFIG_DVB_BUDGET_AV_MODULE 1 +#define CONFIG_DVB_BUDGET_PATCH_MODULE 1 + +/* + * Supported USB Adapters + */ +#define CONFIG_DVB_USB_MODULE 1 +#undef CONFIG_DVB_USB_DEBUG +#define CONFIG_DVB_USB_A800_MODULE 1 +#define CONFIG_DVB_USB_DIBUSB_MB_MODULE 1 +#undef CONFIG_DVB_USB_DIBUSB_MB_FAULTY +#define CONFIG_DVB_USB_DIBUSB_MC_MODULE 1 +#define CONFIG_DVB_USB_UMT_010_MODULE 1 +#define CONFIG_DVB_USB_CXUSB_MODULE 1 +#define CONFIG_DVB_USB_DIGITV_MODULE 1 +#define CONFIG_DVB_USB_VP7045_MODULE 1 +#define CONFIG_DVB_USB_VP702X_MODULE 1 +#define CONFIG_DVB_USB_NOVA_T_USB2_MODULE 1 +#define CONFIG_DVB_USB_DTT200U_MODULE 1 +#define CONFIG_DVB_TTUSB_BUDGET_MODULE 1 +#define CONFIG_DVB_TTUSB_DEC_MODULE 1 +#define CONFIG_DVB_CINERGYT2_MODULE 1 +#define CONFIG_DVB_CINERGYT2_TUNING 1 +#define CONFIG_DVB_CINERGYT2_STREAM_URB_COUNT 32 +#define CONFIG_DVB_CINERGYT2_STREAM_BUF_SIZE 512 +#define CONFIG_DVB_CINERGYT2_QUERY_INTERVAL 250 +#define CONFIG_DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE 1 +#define CONFIG_DVB_CINERGYT2_RC_QUERY_INTERVAL 100 + +/* + * Supported FlexCopII (B2C2) Adapters + */ +#define CONFIG_DVB_B2C2_FLEXCOP_MODULE 1 +#define CONFIG_DVB_B2C2_FLEXCOP_PCI_MODULE 1 +#define CONFIG_DVB_B2C2_FLEXCOP_USB_MODULE 1 +#undef CONFIG_DVB_B2C2_FLEXCOP_DEBUG + +/* + * Supported BT878 Adapters + */ +#define CONFIG_DVB_BT8XX_MODULE 1 + +/* + * Supported Pluto2 Adapters + */ +#define CONFIG_DVB_PLUTO2_MODULE 1 + +/* + * Supported DVB Frontends + */ + +/* + * Customise DVB Frontends + */ + +/* + * DVB-S (satellite) frontends + */ +#define CONFIG_DVB_STV0299_MODULE 1 +#define CONFIG_DVB_CX24110_MODULE 1 +#define CONFIG_DVB_CX24123_MODULE 1 +#define CONFIG_DVB_TDA8083_MODULE 1 +#define CONFIG_DVB_MT312_MODULE 1 +#define CONFIG_DVB_VES1X93_MODULE 1 +#define CONFIG_DVB_S5H1420_MODULE 1 + +/* + * DVB-T (terrestrial) frontends + */ +#define CONFIG_DVB_SP8870_MODULE 1 +#define CONFIG_DVB_SP887X_MODULE 1 +#define CONFIG_DVB_CX22700_MODULE 1 +#define CONFIG_DVB_CX22702_MODULE 1 +#define CONFIG_DVB_L64781_MODULE 1 +#define CONFIG_DVB_TDA1004X_MODULE 1 +#define CONFIG_DVB_NXT6000_MODULE 1 +#define CONFIG_DVB_MT352_MODULE 1 +#define CONFIG_DVB_ZL10353_MODULE 1 +#define CONFIG_DVB_DIB3000MB_MODULE 1 +#define CONFIG_DVB_DIB3000MC_MODULE 1 + +/* + * DVB-C (cable) frontends + */ +#define CONFIG_DVB_VES1820_MODULE 1 +#define CONFIG_DVB_TDA10021_MODULE 1 +#define CONFIG_DVB_STV0297_MODULE 1 + +/* + * ATSC (North American/Korean Terresterial DTV) frontends + */ +#define CONFIG_DVB_NXT200X_MODULE 1 +#define CONFIG_DVB_OR51211_MODULE 1 +#define CONFIG_DVB_OR51132_MODULE 1 +#define CONFIG_DVB_BCM3510_MODULE 1 +#define CONFIG_DVB_LGDT330X_MODULE 1 #define CONFIG_VIDEO_SAA7146_MODULE 1 #define CONFIG_VIDEO_SAA7146_VV_MODULE 1 #define CONFIG_VIDEO_VIDEOBUF_MODULE 1 #define CONFIG_VIDEO_TUNER_MODULE 1 #define CONFIG_VIDEO_BUF_MODULE 1 +#define CONFIG_VIDEO_BUF_DVB_MODULE 1 #define CONFIG_VIDEO_BTCX_MODULE 1 #define CONFIG_VIDEO_IR_MODULE 1 +#define CONFIG_VIDEO_TVEEPROM_MODULE 1 +#define CONFIG_USB_DABUSB_MODULE 1 /* * Graphics support */ #define CONFIG_FB 1 +#define CONFIG_FB_CFB_FILLRECT 1 +#define CONFIG_FB_CFB_COPYAREA 1 +#define CONFIG_FB_CFB_IMAGEBLIT 1 +#undef CONFIG_FB_MACMODES +#undef CONFIG_FB_FIRMWARE_EDID +#define CONFIG_FB_MODE_HELPERS 1 +#define CONFIG_FB_TILEBLITTING 1 +#define CONFIG_FB_CIRRUS_MODULE 1 #undef CONFIG_FB_PM2 #undef CONFIG_FB_CYBER2000 +#undef CONFIG_FB_ARC #undef CONFIG_FB_ASILIANT #undef CONFIG_FB_IMSTT #define CONFIG_FB_VGA16_MODULE 1 #define CONFIG_FB_VESA 1 #define CONFIG_VIDEO_SELECT 1 -#define CONFIG_FB_HGA_MODULE 1 -#define CONFIG_FB_HGA_ACCEL 1 +#undef CONFIG_FB_HGA +#undef CONFIG_FB_S1D13XXX +#undef CONFIG_FB_NVIDIA #define CONFIG_FB_RIVA_MODULE 1 +#undef CONFIG_FB_RIVA_I2C +#undef CONFIG_FB_RIVA_DEBUG #define CONFIG_FB_I810_MODULE 1 #define CONFIG_FB_I810_GTF 1 +#define CONFIG_FB_I810_I2C 1 +#define CONFIG_FB_INTEL_MODULE 1 +#undef CONFIG_FB_INTEL_DEBUG #define CONFIG_FB_MATROX_MODULE 1 #define CONFIG_FB_MATROX_MILLENIUM 1 #define CONFIG_FB_MATROX_MYSTIQUE 1 -#define CONFIG_FB_MATROX_G450 1 -#define CONFIG_FB_MATROX_G100 1 +#define CONFIG_FB_MATROX_G 1 #define CONFIG_FB_MATROX_I2C_MODULE 1 #define CONFIG_FB_MATROX_MAVEN_MODULE 1 #define CONFIG_FB_MATROX_MULTIHEAD 1 -#undef CONFIG_FB_RADEON_OLD #define CONFIG_FB_RADEON_MODULE 1 #define CONFIG_FB_RADEON_I2C 1 #undef CONFIG_FB_RADEON_DEBUG #define CONFIG_FB_ATY128_MODULE 1 #define CONFIG_FB_ATY_MODULE 1 #define CONFIG_FB_ATY_CT 1 +#define CONFIG_FB_ATY_GENERIC_LCD 1 #define CONFIG_FB_ATY_GX 1 -#undef CONFIG_FB_ATY_XL_INIT +#define CONFIG_FB_SAVAGE_MODULE 1 +#define CONFIG_FB_SAVAGE_I2C 1 +#define CONFIG_FB_SAVAGE_ACCEL 1 #undef CONFIG_FB_SIS #define CONFIG_FB_NEOMAGIC_MODULE 1 #define CONFIG_FB_KYRO_MODULE 1 #define CONFIG_FB_3DFX_MODULE 1 #define CONFIG_FB_3DFX_ACCEL 1 #define CONFIG_FB_VOODOO1_MODULE 1 +#define CONFIG_FB_CYBLA_MODULE 1 #define CONFIG_FB_TRIDENT_MODULE 1 #define CONFIG_FB_TRIDENT_ACCEL 1 +#undef CONFIG_FB_GEODE #undef CONFIG_FB_VIRTUAL /* * Console display driver support */ #define CONFIG_VGA_CONSOLE 1 -#define CONFIG_MDA_CONSOLE_MODULE 1 +#define CONFIG_VGACON_SOFT_SCROLLBACK 1 +#define CONFIG_VGACON_SOFT_SCROLLBACK_SIZE 64 +#undef CONFIG_MDA_CONSOLE #define CONFIG_DUMMY_CONSOLE 1 #define CONFIG_FRAMEBUFFER_CONSOLE 1 -#define CONFIG_PCI_CONSOLE 1 +#define CONFIG_FRAMEBUFFER_CONSOLE_ROTATION 1 #undef CONFIG_FONTS #define CONFIG_FONT_8x8 1 #define CONFIG_FONT_8x16 1 @@ -1776,6 +2466,11 @@ #undef CONFIG_LOGO_LINUX_MONO #undef CONFIG_LOGO_LINUX_VGA16 #define CONFIG_LOGO_LINUX_CLUT224 1 +#define CONFIG_BACKLIGHT_LCD_SUPPORT 1 +#define CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE 1 +#define CONFIG_BACKLIGHT_DEVICE 1 +#define CONFIG_LCD_CLASS_DEVICE_MODULE 1 +#define CONFIG_LCD_DEVICE 1 /* * Sound @@ -1795,8 +2490,13 @@ #define CONFIG_SND_OSSEMUL 1 #define CONFIG_SND_MIXER_OSS_MODULE 1 #define CONFIG_SND_PCM_OSS_MODULE 1 +#define CONFIG_SND_PCM_OSS_PLUGINS 1 #define CONFIG_SND_SEQUENCER_OSS 1 #define CONFIG_SND_RTCTIMER_MODULE 1 +#define CONFIG_SND_SEQ_RTCTIMER_DEFAULT 1 +#define CONFIG_SND_DYNAMIC_MINORS 1 +#undef CONFIG_SND_SUPPORT_OLD_API +#define CONFIG_SND_VERBOSE_PROCFS 1 #undef CONFIG_SND_VERBOSE_PRINTK #undef CONFIG_SND_DEBUG @@ -1807,6 +2507,8 @@ #define CONFIG_SND_OPL3_LIB_MODULE 1 #define CONFIG_SND_OPL4_LIB_MODULE 1 #define CONFIG_SND_VX_LIB_MODULE 1 +#define CONFIG_SND_AC97_CODEC_MODULE 1 +#define CONFIG_SND_AC97_BUS_MODULE 1 #define CONFIG_SND_DUMMY_MODULE 1 #define CONFIG_SND_VIRMIDI_MODULE 1 #define CONFIG_SND_MTPAV_MODULE 1 @@ -1816,87 +2518,102 @@ /* * ISA devices */ -#define CONFIG_SND_AD1816A_MODULE 1 -#define CONFIG_SND_AD1848_MODULE 1 -#define CONFIG_SND_CS4231_MODULE 1 -#define CONFIG_SND_CS4232_MODULE 1 +#define CONFIG_SND_CS4231_LIB_MODULE 1 +#define CONFIG_SND_ADLIB_MODULE 1 +#undef CONFIG_SND_AD1816A +#undef CONFIG_SND_AD1848 +#undef CONFIG_SND_ALS100 +#undef CONFIG_SND_AZT2320 +#undef CONFIG_SND_CMI8330 +#undef CONFIG_SND_CS4231 +#undef CONFIG_SND_CS4232 #define CONFIG_SND_CS4236_MODULE 1 -#define CONFIG_SND_ES968_MODULE 1 -#define CONFIG_SND_ES1688_MODULE 1 +#undef CONFIG_SND_DT019X +#undef CONFIG_SND_ES968 +#undef CONFIG_SND_ES1688 #define CONFIG_SND_ES18XX_MODULE 1 -#define CONFIG_SND_GUSCLASSIC_MODULE 1 -#define CONFIG_SND_GUSEXTREME_MODULE 1 -#define CONFIG_SND_GUSMAX_MODULE 1 -#define CONFIG_SND_INTERWAVE_MODULE 1 -#define CONFIG_SND_INTERWAVE_STB_MODULE 1 -#define CONFIG_SND_OPTI92X_AD1848_MODULE 1 -#define CONFIG_SND_OPTI92X_CS4231_MODULE 1 -#define CONFIG_SND_OPTI93X_MODULE 1 -#define CONFIG_SND_SB8_MODULE 1 +#undef CONFIG_SND_GUSCLASSIC +#undef CONFIG_SND_GUSEXTREME +#undef CONFIG_SND_GUSMAX +#undef CONFIG_SND_INTERWAVE +#undef CONFIG_SND_INTERWAVE_STB +#define CONFIG_SND_OPL3SA2_MODULE 1 +#undef CONFIG_SND_OPTI92X_AD1848 +#undef CONFIG_SND_OPTI92X_CS4231 +#undef CONFIG_SND_OPTI93X +#define CONFIG_SND_MIRO_MODULE 1 +#undef CONFIG_SND_SB8 #define CONFIG_SND_SB16_MODULE 1 #define CONFIG_SND_SBAWE_MODULE 1 -#define CONFIG_SND_SB16_CSP 1 +#undef CONFIG_SND_SB16_CSP +#undef CONFIG_SND_SGALAXY +#undef CONFIG_SND_SSCAPE #undef CONFIG_SND_WAVEFRONT -#define CONFIG_SND_ALS100_MODULE 1 -#define CONFIG_SND_AZT2320_MODULE 1 -#define CONFIG_SND_CMI8330_MODULE 1 -#define CONFIG_SND_DT019X_MODULE 1 -#define CONFIG_SND_OPL3SA2_MODULE 1 -#define CONFIG_SND_SGALAXY_MODULE 1 -#define CONFIG_SND_SSCAPE_MODULE 1 /* * PCI devices */ -#define CONFIG_SND_AC97_CODEC_MODULE 1 +#define CONFIG_SND_AD1889_MODULE 1 +#define CONFIG_SND_ALS300_MODULE 1 +#define CONFIG_SND_ALS4000_MODULE 1 #define CONFIG_SND_ALI5451_MODULE 1 #define CONFIG_SND_ATIIXP_MODULE 1 +#define CONFIG_SND_ATIIXP_MODEM_MODULE 1 #define CONFIG_SND_AU8810_MODULE 1 #define CONFIG_SND_AU8820_MODULE 1 #define CONFIG_SND_AU8830_MODULE 1 #define CONFIG_SND_AZT3328_MODULE 1 #define CONFIG_SND_BT87X_MODULE 1 +#undef CONFIG_SND_BT87X_OVERCLOCK +#define CONFIG_SND_CA0106_MODULE 1 +#define CONFIG_SND_CMIPCI_MODULE 1 +#define CONFIG_SND_CS4281_MODULE 1 #define CONFIG_SND_CS46XX_MODULE 1 #define CONFIG_SND_CS46XX_NEW_DSP 1 -#define CONFIG_SND_CS4281_MODULE 1 +#define CONFIG_SND_CS5535AUDIO_MODULE 1 #define CONFIG_SND_EMU10K1_MODULE 1 -#define CONFIG_SND_KORG1212_MODULE 1 -#define CONFIG_SND_MIXART_MODULE 1 -#define CONFIG_SND_NM256_MODULE 1 -#define CONFIG_SND_RME32_MODULE 1 -#define CONFIG_SND_RME96_MODULE 1 -#define CONFIG_SND_RME9652_MODULE 1 -#define CONFIG_SND_HDSP_MODULE 1 -#define CONFIG_SND_TRIDENT_MODULE 1 -#define CONFIG_SND_YMFPCI_MODULE 1 -#define CONFIG_SND_ALS4000_MODULE 1 -#define CONFIG_SND_CMIPCI_MODULE 1 +#define CONFIG_SND_EMU10K1X_MODULE 1 #define CONFIG_SND_ENS1370_MODULE 1 #define CONFIG_SND_ENS1371_MODULE 1 #define CONFIG_SND_ES1938_MODULE 1 #define CONFIG_SND_ES1968_MODULE 1 -#define CONFIG_SND_MAESTRO3_MODULE 1 #define CONFIG_SND_FM801_MODULE 1 +#define CONFIG_SND_FM801_TEA575X_BOOL 1 #define CONFIG_SND_FM801_TEA575X_MODULE 1 +#define CONFIG_SND_HDA_INTEL_MODULE 1 +#define CONFIG_SND_HDSP_MODULE 1 +#define CONFIG_SND_HDSPM_MODULE 1 #define CONFIG_SND_ICE1712_MODULE 1 #define CONFIG_SND_ICE1724_MODULE 1 #define CONFIG_SND_INTEL8X0_MODULE 1 #define CONFIG_SND_INTEL8X0M_MODULE 1 +#define CONFIG_SND_KORG1212_MODULE 1 +#define CONFIG_SND_MAESTRO3_MODULE 1 +#define CONFIG_SND_MIXART_MODULE 1 +#define CONFIG_SND_NM256_MODULE 1 +#define CONFIG_SND_PCXHR_MODULE 1 +#define CONFIG_SND_RIPTIDE_MODULE 1 +#define CONFIG_SND_RME32_MODULE 1 +#define CONFIG_SND_RME96_MODULE 1 +#define CONFIG_SND_RME9652_MODULE 1 #define CONFIG_SND_SONICVIBES_MODULE 1 +#define CONFIG_SND_TRIDENT_MODULE 1 #define CONFIG_SND_VIA82XX_MODULE 1 +#define CONFIG_SND_VIA82XX_MODEM_MODULE 1 #define CONFIG_SND_VX222_MODULE 1 +#define CONFIG_SND_YMFPCI_MODULE 1 /* - * ALSA USB devices + * USB devices */ #define CONFIG_SND_USB_AUDIO_MODULE 1 +#define CONFIG_SND_USB_USX2Y_MODULE 1 /* * PCMCIA devices */ #undef CONFIG_SND_VXPOCKET -#undef CONFIG_SND_VXP440 -#define CONFIG_SND_PDAUDIOCF_MODULE 1 +#undef CONFIG_SND_PDAUDIOCF /* * Open Sound System @@ -1906,6 +2623,9 @@ /* * USB support */ +#define CONFIG_USB_ARCH_HAS_HCD 1 +#define CONFIG_USB_ARCH_HAS_OHCI 1 +#define CONFIG_USB_ARCH_HAS_EHCI 1 #define CONFIG_USB 1 #undef CONFIG_USB_DEBUG @@ -1915,6 +2635,8 @@ #define CONFIG_USB_DEVICEFS 1 #undef CONFIG_USB_BANDWIDTH #undef CONFIG_USB_DYNAMIC_MINORS +#undef CONFIG_USB_SUSPEND +#undef CONFIG_USB_OTG /* * USB Host Controller Drivers @@ -1922,36 +2644,46 @@ #define CONFIG_USB_EHCI_HCD_MODULE 1 #define CONFIG_USB_EHCI_SPLIT_ISO 1 #define CONFIG_USB_EHCI_ROOT_HUB_TT 1 +#define CONFIG_USB_ISP116X_HCD_MODULE 1 #define CONFIG_USB_OHCI_HCD_MODULE 1 +#undef CONFIG_USB_OHCI_BIG_ENDIAN +#define CONFIG_USB_OHCI_LITTLE_ENDIAN 1 #define CONFIG_USB_UHCI_HCD_MODULE 1 +#define CONFIG_USB_SL811_HCD_MODULE 1 +#define CONFIG_USB_SL811_CS_MODULE 1 /* * USB Device Class drivers */ -#define CONFIG_USB_AUDIO_MODULE 1 +#define CONFIG_USB_ACM_MODULE 1 +#define CONFIG_USB_PRINTER_MODULE 1 /* - * USB Bluetooth TTY can only be used with disabled Bluetooth subsystem + * NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' + */ + +/* + * may also be needed; see USB_STORAGE Help for more information */ -#define CONFIG_USB_MIDI_MODULE 1 -#define CONFIG_USB_ACM_MODULE 1 -#define CONFIG_USB_PRINTER_MODULE 1 #define CONFIG_USB_STORAGE_MODULE 1 #undef CONFIG_USB_STORAGE_DEBUG #define CONFIG_USB_STORAGE_DATAFAB 1 #define CONFIG_USB_STORAGE_FREECOM 1 #define CONFIG_USB_STORAGE_ISD200 1 #define CONFIG_USB_STORAGE_DPCM 1 -#define CONFIG_USB_STORAGE_HP8200e 1 +#define CONFIG_USB_STORAGE_USBAT 1 #define CONFIG_USB_STORAGE_SDDR09 1 #define CONFIG_USB_STORAGE_SDDR55 1 #define CONFIG_USB_STORAGE_JUMPSHOT 1 +#define CONFIG_USB_STORAGE_ALAUDA 1 +#define CONFIG_USB_LIBUSUAL 1 /* - * USB Human Interface Devices (HID) + * USB Input Devices */ #define CONFIG_USB_HID 1 #define CONFIG_USB_HIDINPUT 1 +#undef CONFIG_USB_HIDINPUT_POWERBOOK #define CONFIG_HID_FF 1 #define CONFIG_HID_PID 1 #define CONFIG_LOGITECH_FF 1 @@ -1959,64 +2691,50 @@ #define CONFIG_USB_HIDDEV 1 #define CONFIG_USB_AIPTEK_MODULE 1 #define CONFIG_USB_WACOM_MODULE 1 +#define CONFIG_USB_ACECAD_MODULE 1 #define CONFIG_USB_KBTAB_MODULE 1 #define CONFIG_USB_POWERMATE_MODULE 1 -#define CONFIG_USB_MTOUCH_MODULE 1 -#define CONFIG_USB_EGALAX_MODULE 1 +#define CONFIG_USB_TOUCHSCREEN_MODULE 1 +#define CONFIG_USB_TOUCHSCREEN_EGALAX 1 +#define CONFIG_USB_TOUCHSCREEN_PANJIT 1 +#define CONFIG_USB_TOUCHSCREEN_3M 1 +#define CONFIG_USB_TOUCHSCREEN_ITM 1 +#undef CONFIG_USB_YEALINK #define CONFIG_USB_XPAD_MODULE 1 #define CONFIG_USB_ATI_REMOTE_MODULE 1 +#define CONFIG_USB_ATI_REMOTE2_MODULE 1 +#define CONFIG_USB_KEYSPAN_REMOTE_MODULE 1 +#define CONFIG_USB_APPLETOUCH_MODULE 1 /* * USB Imaging devices */ #define CONFIG_USB_MDC800_MODULE 1 #define CONFIG_USB_MICROTEK_MODULE 1 -#define CONFIG_USB_HPUSBSCSI_MODULE 1 - -/* - * USB Multimedia devices - */ -#define CONFIG_USB_DABUSB_MODULE 1 -#define CONFIG_USB_VICAM_MODULE 1 -#define CONFIG_USB_DSBR_MODULE 1 -#define CONFIG_USB_IBMCAM_MODULE 1 -#define CONFIG_USB_KONICAWC_MODULE 1 -#define CONFIG_USB_OV511_MODULE 1 -#define CONFIG_USB_SE401_MODULE 1 -#define CONFIG_USB_STV680_MODULE 1 -#define CONFIG_USB_W9968CF_MODULE 1 /* - * USB Network adaptors + * USB Network Adapters */ #define CONFIG_USB_CATC_MODULE 1 #define CONFIG_USB_KAWETH_MODULE 1 #define CONFIG_USB_PEGASUS_MODULE 1 #define CONFIG_USB_RTL8150_MODULE 1 #define CONFIG_USB_USBNET_MODULE 1 - -/* - * USB Host-to-Host Cables - */ +#define CONFIG_USB_NET_AX8817X_MODULE 1 +#define CONFIG_USB_NET_CDCETHER_MODULE 1 +#define CONFIG_USB_NET_GL620A_MODULE 1 +#define CONFIG_USB_NET_NET1080_MODULE 1 +#define CONFIG_USB_NET_PLUSB_MODULE 1 +#define CONFIG_USB_NET_RNDIS_HOST_MODULE 1 +#define CONFIG_USB_NET_CDC_SUBSET_MODULE 1 #define CONFIG_USB_ALI_M5632 1 #define CONFIG_USB_AN2720 1 #define CONFIG_USB_BELKIN 1 -#define CONFIG_USB_GENESYS 1 -#define CONFIG_USB_NET1080 1 -#define CONFIG_USB_PL2301 1 - -/* - * Intelligent USB Devices/Gadgets - */ #define CONFIG_USB_ARMLINUX 1 #define CONFIG_USB_EPSON2888 1 -#define CONFIG_USB_ZAURUS 1 -#define CONFIG_USB_CDCETHER 1 - -/* - * USB Network Adapters - */ -#define CONFIG_USB_AX8817X 1 +#define CONFIG_USB_NET_ZAURUS_MODULE 1 +#define CONFIG_USB_ZD1201_MODULE 1 +#define CONFIG_USB_MON 1 /* * USB port drivers @@ -2028,15 +2746,24 @@ */ #define CONFIG_USB_SERIAL_MODULE 1 #define CONFIG_USB_SERIAL_GENERIC 1 +#define CONFIG_USB_SERIAL_AIRPRIME_MODULE 1 +#define CONFIG_USB_SERIAL_ANYDATA_MODULE 1 +#define CONFIG_USB_SERIAL_ARK3116_MODULE 1 #define CONFIG_USB_SERIAL_BELKIN_MODULE 1 +#define CONFIG_USB_SERIAL_WHITEHEAT_MODULE 1 #define CONFIG_USB_SERIAL_DIGI_ACCELEPORT_MODULE 1 +#define CONFIG_USB_SERIAL_CP2101_MODULE 1 +#define CONFIG_USB_SERIAL_CYPRESS_M8_MODULE 1 #define CONFIG_USB_SERIAL_EMPEG_MODULE 1 #define CONFIG_USB_SERIAL_FTDI_SIO_MODULE 1 +#define CONFIG_USB_SERIAL_FUNSOFT_MODULE 1 #define CONFIG_USB_SERIAL_VISOR_MODULE 1 #define CONFIG_USB_SERIAL_IPAQ_MODULE 1 #define CONFIG_USB_SERIAL_IR_MODULE 1 #define CONFIG_USB_SERIAL_EDGEPORT_MODULE 1 #define CONFIG_USB_SERIAL_EDGEPORT_TI_MODULE 1 +#define CONFIG_USB_SERIAL_GARMIN_MODULE 1 +#define CONFIG_USB_SERIAL_IPW_MODULE 1 #define CONFIG_USB_SERIAL_KEYSPAN_PDA_MODULE 1 #define CONFIG_USB_SERIAL_KEYSPAN_MODULE 1 #define CONFIG_USB_SERIAL_KEYSPAN_MPR 1 @@ -2054,11 +2781,15 @@ #define CONFIG_USB_SERIAL_KLSI_MODULE 1 #define CONFIG_USB_SERIAL_KOBIL_SCT_MODULE 1 #define CONFIG_USB_SERIAL_MCT_U232_MODULE 1 +#define CONFIG_USB_SERIAL_NAVMAN_MODULE 1 #define CONFIG_USB_SERIAL_PL2303_MODULE 1 +#define CONFIG_USB_SERIAL_HP4X_MODULE 1 #define CONFIG_USB_SERIAL_SAFE_MODULE 1 #define CONFIG_USB_SERIAL_SAFE_PADDED 1 +#define CONFIG_USB_SERIAL_TI_MODULE 1 #define CONFIG_USB_SERIAL_CYBERJACK_MODULE 1 #define CONFIG_USB_SERIAL_XIRCOM_MODULE 1 +#define CONFIG_USB_SERIAL_OPTION_MODULE 1 #define CONFIG_USB_SERIAL_OMNINET_MODULE 1 #define CONFIG_USB_EZUSB 1 @@ -2066,22 +2797,111 @@ * USB Miscellaneous drivers */ #define CONFIG_USB_EMI62_MODULE 1 -#undef CONFIG_USB_EMI26 -#define CONFIG_USB_TIGL_MODULE 1 +#define CONFIG_USB_EMI26_MODULE 1 #define CONFIG_USB_AUERSWALD_MODULE 1 #define CONFIG_USB_RIO500_MODULE 1 #define CONFIG_USB_LEGOTOWER_MODULE 1 #define CONFIG_USB_LCD_MODULE 1 #define CONFIG_USB_LED_MODULE 1 #undef CONFIG_USB_CYTHERM +#define CONFIG_USB_PHIDGETKIT_MODULE 1 #define CONFIG_USB_PHIDGETSERVO_MODULE 1 +#define CONFIG_USB_IDMOUSE_MODULE 1 +#define CONFIG_USB_SISUSBVGA_MODULE 1 +#define CONFIG_USB_SISUSBVGA_CON 1 +#define CONFIG_USB_LD_MODULE 1 #define CONFIG_USB_TEST_MODULE 1 +/* + * USB DSL modem support + */ +#define CONFIG_USB_ATM_MODULE 1 +#define CONFIG_USB_SPEEDTOUCH_MODULE 1 +#define CONFIG_USB_CXACRU_MODULE 1 +#define CONFIG_USB_UEAGLEATM_MODULE 1 +#define CONFIG_USB_XUSBATM_MODULE 1 + /* * USB Gadget Support */ #undef CONFIG_USB_GADGET +/* + * MMC/SD Card support + */ +#define CONFIG_MMC_MODULE 1 +#undef CONFIG_MMC_DEBUG +#define CONFIG_MMC_BLOCK_MODULE 1 +#define CONFIG_MMC_SDHCI_MODULE 1 +#define CONFIG_MMC_WBSD_MODULE 1 + +/* + * LED devices + */ +#undef CONFIG_NEW_LEDS + +/* + * LED drivers + */ + +/* + * LED Triggers + */ + +/* + * InfiniBand support + */ +#define CONFIG_INFINIBAND_MODULE 1 +#define CONFIG_INFINIBAND_USER_MAD_MODULE 1 +#define CONFIG_INFINIBAND_USER_ACCESS_MODULE 1 +#define CONFIG_INFINIBAND_MTHCA_MODULE 1 +#define CONFIG_INFINIBAND_MTHCA_DEBUG 1 +#define CONFIG_INFINIBAND_IPOIB_MODULE 1 +#define CONFIG_INFINIBAND_IPOIB_DEBUG 1 +#define CONFIG_INFINIBAND_IPOIB_DEBUG_DATA 1 +#define CONFIG_INFINIBAND_SRP_MODULE 1 + +/* + * EDAC - error detection and reporting (RAS) (EXPERIMENTAL) + */ +#define CONFIG_EDAC 1 + +/* + * Reporting subsystems + */ +#undef CONFIG_EDAC_DEBUG +#define CONFIG_EDAC_MM_EDAC_MODULE 1 +#define CONFIG_EDAC_AMD76X_MODULE 1 +#define CONFIG_EDAC_E7XXX_MODULE 1 +#define CONFIG_EDAC_E752X_MODULE 1 +#define CONFIG_EDAC_I82875P_MODULE 1 +#define CONFIG_EDAC_I82860_MODULE 1 +#define CONFIG_EDAC_R82600_MODULE 1 +#define CONFIG_EDAC_POLL 1 + +/* + * Real Time Clock + */ +#define CONFIG_RTC_LIB_MODULE 1 +#define CONFIG_RTC_CLASS_MODULE 1 + +/* + * RTC interfaces + */ +#define CONFIG_RTC_INTF_SYSFS_MODULE 1 +#define CONFIG_RTC_INTF_PROC_MODULE 1 +#define CONFIG_RTC_INTF_DEV_MODULE 1 + +/* + * RTC drivers + */ +#define CONFIG_RTC_DRV_X1205_MODULE 1 +#define CONFIG_RTC_DRV_DS1672_MODULE 1 +#define CONFIG_RTC_DRV_PCF8563_MODULE 1 +#define CONFIG_RTC_DRV_RS5C372_MODULE 1 +#undef CONFIG_RTC_DRV_M48T86 +#undef CONFIG_RTC_DRV_TEST + /* * File systems */ @@ -2089,6 +2909,8 @@ #define CONFIG_EXT2_FS_XATTR 1 #define CONFIG_EXT2_FS_POSIX_ACL 1 #define CONFIG_EXT2_FS_SECURITY 1 +#define CONFIG_EXT2_FS_XIP 1 +#define CONFIG_FS_XIP 1 #define CONFIG_EXT3_FS_MODULE 1 #define CONFIG_EXT3_FS_XATTR 1 #define CONFIG_EXT3_FS_POSIX_ACL 1 @@ -2104,22 +2926,28 @@ #define CONFIG_REISERFS_FS_SECURITY 1 #define CONFIG_JFS_FS_MODULE 1 #define CONFIG_JFS_POSIX_ACL 1 +#define CONFIG_JFS_SECURITY 1 #undef CONFIG_JFS_DEBUG #undef CONFIG_JFS_STATISTICS #define CONFIG_FS_POSIX_ACL 1 #define CONFIG_XFS_FS_MODULE 1 -#undef CONFIG_XFS_RT +#define CONFIG_XFS_EXPORT 1 #define CONFIG_XFS_QUOTA 1 #define CONFIG_XFS_SECURITY 1 #define CONFIG_XFS_POSIX_ACL 1 +#undef CONFIG_XFS_RT +#define CONFIG_OCFS2_FS_MODULE 1 #define CONFIG_MINIX_FS_MODULE 1 #define CONFIG_ROMFS_FS_MODULE 1 +#define CONFIG_INOTIFY 1 #define CONFIG_QUOTA 1 #undef CONFIG_QFMT_V1 #define CONFIG_QFMT_V2 1 #define CONFIG_QUOTACTL 1 +#define CONFIG_DNOTIFY 1 #define CONFIG_AUTOFS_FS_MODULE 1 #define CONFIG_AUTOFS4_FS_MODULE 1 +#define CONFIG_FUSE_FS_MODULE 1 /* * CD-ROM/DVD Filesystems @@ -2129,6 +2957,7 @@ #define CONFIG_ZISOFS 1 #define CONFIG_ZISOFS_FS 1 #define CONFIG_UDF_FS_MODULE 1 +#define CONFIG_UDF_NLS 1 /* * DOS/FAT/NT Filesystems @@ -2136,6 +2965,8 @@ #define CONFIG_FAT_FS_MODULE 1 #define CONFIG_MSDOS_FS_MODULE 1 #define CONFIG_VFAT_FS_MODULE 1 +#define CONFIG_FAT_DEFAULT_CODEPAGE 437 +#define CONFIG_FAT_DEFAULT_IOCHARSET "ascii" #undef CONFIG_NTFS_FS /* @@ -2144,13 +2975,11 @@ #define CONFIG_PROC_FS 1 #define CONFIG_PROC_KCORE 1 #define CONFIG_SYSFS 1 -#undef CONFIG_DEVFS_FS -#define CONFIG_DEVPTS_FS_XATTR 1 -#define CONFIG_DEVPTS_FS_SECURITY 1 #define CONFIG_TMPFS 1 #define CONFIG_HUGETLBFS 1 #define CONFIG_HUGETLB_PAGE 1 #define CONFIG_RAMFS 1 +#define CONFIG_CONFIGFS_FS_MODULE 1 /* * Miscellaneous filesystems @@ -2166,37 +2995,52 @@ #undef CONFIG_JFFS_FS #define CONFIG_JFFS2_FS_MODULE 1 #define CONFIG_JFFS2_FS_DEBUG 0 -#define CONFIG_JFFS2_FS_NAND 1 +#define CONFIG_JFFS2_FS_WRITEBUFFER 1 +#define CONFIG_JFFS2_SUMMARY 1 +#undef CONFIG_JFFS2_COMPRESSION_OPTIONS +#define CONFIG_JFFS2_ZLIB 1 +#define CONFIG_JFFS2_RTIME 1 +#undef CONFIG_JFFS2_RUBIN #define CONFIG_CRAMFS_MODULE 1 +#define CONFIG_SQUASHFS_MODULE 1 +#undef CONFIG_SQUASHFS_EMBEDDED +#define CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE 3 +#undef CONFIG_SQUASHFS_VMALLOC #define CONFIG_VXFS_FS_MODULE 1 #undef CONFIG_HPFS_FS #define CONFIG_QNX4FS_FS_MODULE 1 -#undef CONFIG_QNX4FS_RW #define CONFIG_SYSV_FS_MODULE 1 #define CONFIG_UFS_FS_MODULE 1 -#undef CONFIG_UFS_FS_WRITE /* * Network File Systems */ #define CONFIG_NFS_FS_MODULE 1 #define CONFIG_NFS_V3 1 +#define CONFIG_NFS_V3_ACL 1 #define CONFIG_NFS_V4 1 #define CONFIG_NFS_DIRECTIO 1 #define CONFIG_NFSD_MODULE 1 +#define CONFIG_NFSD_V2_ACL 1 #define CONFIG_NFSD_V3 1 +#define CONFIG_NFSD_V3_ACL 1 #define CONFIG_NFSD_V4 1 #define CONFIG_NFSD_TCP 1 #define CONFIG_LOCKD_MODULE 1 #define CONFIG_LOCKD_V4 1 #define CONFIG_EXPORTFS_MODULE 1 +#define CONFIG_NFS_ACL_SUPPORT_MODULE 1 +#define CONFIG_NFS_COMMON 1 #define CONFIG_SUNRPC_MODULE 1 #define CONFIG_SUNRPC_GSS_MODULE 1 #define CONFIG_RPCSEC_GSS_KRB5_MODULE 1 -#define CONFIG_SMB_FS_MODULE 1 -#undef CONFIG_SMB_NLS_DEFAULT +#define CONFIG_RPCSEC_GSS_SPKM3_MODULE 1 +#undef CONFIG_SMB_FS #define CONFIG_CIFS_MODULE 1 #undef CONFIG_CIFS_STATS +#define CONFIG_CIFS_XATTR 1 +#define CONFIG_CIFS_POSIX 1 +#undef CONFIG_CIFS_EXPERIMENTAL #define CONFIG_NCP_FS_MODULE 1 #define CONFIG_NCPFS_PACKET_SIGNING 1 #define CONFIG_NCPFS_IOCTL_LOCKING 1 @@ -2206,8 +3050,10 @@ #define CONFIG_NCPFS_SMALLDOS 1 #define CONFIG_NCPFS_NLS 1 #define CONFIG_NCPFS_EXTRAS 1 -#undef CONFIG_CODA_FS +#define CONFIG_CODA_FS_MODULE 1 +#undef CONFIG_CODA_FS_OLD_API #undef CONFIG_AFS_FS +#define CONFIG_9P_FS_MODULE 1 /* * Partition Types @@ -2215,7 +3061,7 @@ #define CONFIG_PARTITION_ADVANCED 1 #undef CONFIG_ACORN_PARTITION #define CONFIG_OSF_PARTITION 1 -#undef CONFIG_AMIGA_PARTITION +#define CONFIG_AMIGA_PARTITION 1 #undef CONFIG_ATARI_PARTITION #define CONFIG_MAC_PARTITION 1 #define CONFIG_MSDOS_PARTITION 1 @@ -2224,10 +3070,10 @@ #define CONFIG_SOLARIS_X86_PARTITION 1 #define CONFIG_UNIXWARE_DISKLABEL 1 #undef CONFIG_LDM_PARTITION -#undef CONFIG_NEC98_PARTITION #define CONFIG_SGI_PARTITION 1 #undef CONFIG_ULTRIX_PARTITION #define CONFIG_SUN_PARTITION 1 +#define CONFIG_KARMA_PARTITION 1 #define CONFIG_EFI_PARTITION 1 /* @@ -2235,7 +3081,7 @@ */ #define CONFIG_NLS 1 #define CONFIG_NLS_DEFAULT "utf8" -#define CONFIG_NLS_CODEPAGE_437_MODULE 1 +#define CONFIG_NLS_CODEPAGE_437 1 #define CONFIG_NLS_CODEPAGE_737_MODULE 1 #define CONFIG_NLS_CODEPAGE_775_MODULE 1 #define CONFIG_NLS_CODEPAGE_850_MODULE 1 @@ -2258,6 +3104,7 @@ #define CONFIG_NLS_ISO8859_8_MODULE 1 #define CONFIG_NLS_CODEPAGE_1250_MODULE 1 #define CONFIG_NLS_CODEPAGE_1251_MODULE 1 +#define CONFIG_NLS_ASCII 1 #define CONFIG_NLS_ISO8859_1_MODULE 1 #define CONFIG_NLS_ISO8859_2_MODULE 1 #define CONFIG_NLS_ISO8859_3_MODULE 1 @@ -2274,41 +3121,68 @@ #define CONFIG_NLS_UTF8_MODULE 1 /* - * Profiling support + * Instrumentation Support */ #define CONFIG_PROFILING 1 #define CONFIG_OPROFILE_MODULE 1 +#define CONFIG_KPROBES 1 /* * Kernel hacking */ +#undef CONFIG_PRINTK_TIME +#define CONFIG_MAGIC_SYSRQ 1 #define CONFIG_DEBUG_KERNEL 1 -#define CONFIG_EARLY_PRINTK 1 -#define CONFIG_DEBUG_STACKOVERFLOW 1 -#undef CONFIG_DEBUG_STACK_USAGE +#define CONFIG_LOG_BUF_SHIFT 17 +#define CONFIG_DETECT_SOFTLOCKUP 1 +#define CONFIG_SCHEDSTATS 1 #undef CONFIG_DEBUG_SLAB -#define CONFIG_MAGIC_SYSRQ 1 -#undef CONFIG_DEBUG_SPINLOCK -#undef CONFIG_DEBUG_PAGEALLOC -#undef CONFIG_DEBUG_HIGHMEM -#define CONFIG_DEBUG_INFO 1 +#define CONFIG_DEBUG_MUTEXES 1 +#define CONFIG_DEBUG_SPINLOCK 1 #define CONFIG_DEBUG_SPINLOCK_SLEEP 1 +#undef CONFIG_DEBUG_KOBJECT +#define CONFIG_DEBUG_HIGHMEM 1 +#define CONFIG_DEBUG_BUGVERBOSE 1 +#define CONFIG_DEBUG_INFO 1 +#define CONFIG_DEBUG_FS 1 +#define CONFIG_DEBUG_VM 1 #undef CONFIG_FRAME_POINTER +#define CONFIG_UNWIND_INFO 1 +#undef CONFIG_FORCED_INLINING +#define CONFIG_BOOT_DELAY 1 +#undef CONFIG_RCU_TORTURE_TEST +#define CONFIG_EARLY_PRINTK 1 +#define CONFIG_DEBUG_STACKOVERFLOW 1 +#define CONFIG_DEBUG_STACK_USAGE 1 +#define CONFIG_STACK_BACKTRACE_COLS 2 + +/* + * Page alloc debug is incompatible with Software Suspend on i386 + */ +#define CONFIG_DEBUG_RODATA 1 +#define CONFIG_4KSTACKS 1 #define CONFIG_X86_FIND_SMP_CONFIG 1 #define CONFIG_X86_MPPARSE 1 +#define CONFIG_DOUBLEFAULT 1 /* * Security options */ +#define CONFIG_KEYS 1 +#define CONFIG_KEYS_DEBUG_PROC_KEYS 1 #define CONFIG_SECURITY 1 #define CONFIG_SECURITY_NETWORK 1 +#define CONFIG_SECURITY_NETWORK_XFRM 1 #define CONFIG_SECURITY_CAPABILITIES 1 #undef CONFIG_SECURITY_ROOTPLUG +#undef CONFIG_SECURITY_SECLVL #define CONFIG_SECURITY_SELINUX 1 #define CONFIG_SECURITY_SELINUX_BOOTPARAM 1 +#define CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE 1 #define CONFIG_SECURITY_SELINUX_DISABLE 1 #define CONFIG_SECURITY_SELINUX_DEVELOP 1 -#undef CONFIG_SECURITY_SELINUX_MLS +#define CONFIG_SECURITY_SELINUX_AVC_STATS 1 +#define CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE 1 /* * Cryptographic options @@ -2318,32 +3192,51 @@ #define CONFIG_CRYPTO_NULL_MODULE 1 #define CONFIG_CRYPTO_MD4_MODULE 1 #define CONFIG_CRYPTO_MD5 1 -#define CONFIG_CRYPTO_SHA1_MODULE 1 +#define CONFIG_CRYPTO_SHA1 1 #define CONFIG_CRYPTO_SHA256_MODULE 1 #define CONFIG_CRYPTO_SHA512_MODULE 1 +#define CONFIG_CRYPTO_WP512_MODULE 1 +#define CONFIG_CRYPTO_TGR192_MODULE 1 #define CONFIG_CRYPTO_DES_MODULE 1 #define CONFIG_CRYPTO_BLOWFISH_MODULE 1 #define CONFIG_CRYPTO_TWOFISH_MODULE 1 #define CONFIG_CRYPTO_SERPENT_MODULE 1 #define CONFIG_CRYPTO_AES_MODULE 1 +#define CONFIG_CRYPTO_AES_586_MODULE 1 #define CONFIG_CRYPTO_CAST5_MODULE 1 #define CONFIG_CRYPTO_CAST6_MODULE 1 +#define CONFIG_CRYPTO_TEA_MODULE 1 #define CONFIG_CRYPTO_ARC4_MODULE 1 +#define CONFIG_CRYPTO_KHAZAD_MODULE 1 +#define CONFIG_CRYPTO_ANUBIS_MODULE 1 #define CONFIG_CRYPTO_DEFLATE_MODULE 1 #define CONFIG_CRYPTO_MICHAEL_MIC_MODULE 1 #define CONFIG_CRYPTO_CRC32C_MODULE 1 #undef CONFIG_CRYPTO_TEST +#define CONFIG_CRYPTO_SIGNATURE 1 +#define CONFIG_CRYPTO_SIGNATURE_DSA 1 +#define CONFIG_CRYPTO_MPILIB 1 + +/* + * Hardware crypto devices + */ +#define CONFIG_CRYPTO_DEV_PADLOCK_MODULE 1 +#define CONFIG_CRYPTO_DEV_PADLOCK_AES 1 /* * Library routines */ +#define CONFIG_CRC_CCITT_MODULE 1 +#define CONFIG_CRC16_MODULE 1 #define CONFIG_CRC32 1 #define CONFIG_LIBCRC32C_MODULE 1 #define CONFIG_ZLIB_INFLATE 1 #define CONFIG_ZLIB_DEFLATE_MODULE 1 -#define CONFIG_X86_SMP 1 -#define CONFIG_X86_HT 1 +#define CONFIG_TEXTSEARCH 1 +#define CONFIG_TEXTSEARCH_KMP_MODULE 1 +#define CONFIG_TEXTSEARCH_BM_MODULE 1 +#define CONFIG_TEXTSEARCH_FSM_MODULE 1 +#define CONFIG_GENERIC_HARDIRQS 1 +#define CONFIG_GENERIC_IRQ_PROBE 1 #define CONFIG_X86_BIOS_REBOOT 1 -#define CONFIG_X86_TRAMPOLINE 1 -#define CONFIG_X86_STD_RESOURCES 1 -#define CONFIG_PC 1 +#define CONFIG_KTIME_SCALAR 1 diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index 93535f093..9269df738 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h @@ -408,6 +408,8 @@ struct ethtool_ops { #define ETHTOOL_GPERMADDR 0x00000020 /* Get permanent hardware address */ #define ETHTOOL_GUFO 0x00000021 /* Get UFO enable (ethtool_value) */ #define ETHTOOL_SUFO 0x00000022 /* Set UFO enable (ethtool_value) */ +#define ETHTOOL_GGSO 0x00000023 /* Get GSO enable (ethtool_value) */ +#define ETHTOOL_SGSO 0x00000024 /* Set GSO enable (ethtool_value) */ /* compatibility with older code */ #define SPARC_ETH_GSET ETHTOOL_GSET diff --git a/include/linux/ext3_fs.h b/include/linux/ext3_fs.h index 014999512..a4c919c22 100644 --- a/include/linux/ext3_fs.h +++ b/include/linux/ext3_fs.h @@ -507,6 +507,15 @@ static inline struct ext3_inode_info *EXT3_I(struct inode *inode) { return container_of(inode, struct ext3_inode_info, vfs_inode); } + +static inline int ext3_valid_inum(struct super_block *sb, unsigned long ino) +{ + return ino == EXT3_ROOT_INO || + ino == EXT3_JOURNAL_INO || + ino == EXT3_RESIZE_INO || + (ino >= EXT3_FIRST_INO(sb) && + ino <= le32_to_cpu(EXT3_SB(sb)->s_es->s_inodes_count)); +} #else /* Assume that user mode programs are passing in an ext3fs superblock, not * a kernel struct super_block. This will allow us to call the feature-test diff --git a/include/linux/gfp.h b/include/linux/gfp.h index a308228b7..83ece62bc 100644 --- a/include/linux/gfp.h +++ b/include/linux/gfp.h @@ -100,7 +100,11 @@ static inline int gfp_zone(gfp_t gfp) */ #ifndef HAVE_ARCH_FREE_PAGE -static inline void arch_free_page(struct page *page, int order) { } +/* + * If arch_free_page returns non-zero then the generic free_page code can + * immediately bail: the arch-specific function has done all the work. + */ +static inline int arch_free_page(struct page *page, int order) { return 0; } #endif extern struct page * diff --git a/include/linux/highmem.h b/include/linux/highmem.h index 892c4ea1b..8f2bcfb85 100644 --- a/include/linux/highmem.h +++ b/include/linux/highmem.h @@ -25,10 +25,16 @@ static inline void flush_kernel_dcache_page(struct page *page) /* declarations for linux/mm/highmem.c */ unsigned int nr_free_highpages(void); +#ifdef CONFIG_XEN +void kmap_flush_unused(void); +#endif #else /* CONFIG_HIGHMEM */ static inline unsigned int nr_free_highpages(void) { return 0; } +#ifdef CONFIG_XEN +static inline void kmap_flush_unused(void) { } +#endif static inline void *kmap(struct page *page) { diff --git a/include/linux/idr.h b/include/linux/idr.h index d37c8d808..f559a719d 100644 --- a/include/linux/idr.h +++ b/include/linux/idr.h @@ -78,6 +78,7 @@ void *idr_find(struct idr *idp, int id); int idr_pre_get(struct idr *idp, gfp_t gfp_mask); int idr_get_new(struct idr *idp, void *ptr, int *id); int idr_get_new_above(struct idr *idp, void *ptr, int starting_id, int *id); +void *idr_replace(struct idr *idp, void *ptr, int id); void idr_remove(struct idr *idp, int id); void idr_destroy(struct idr *idp); void idr_init(struct idr *idp); diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h index 2c08fdc2b..d55ff51ff 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h @@ -58,6 +58,12 @@ extern void disable_irq(unsigned int irq); extern void enable_irq(unsigned int irq); #endif +#ifdef CONFIG_HAVE_IRQ_IGNORE_UNHANDLED +int irq_ignore_unhandled(unsigned int irq); +#else +#define irq_ignore_unhandled(irq) 0 +#endif + #ifndef __ARCH_SET_SOFTIRQ_PENDING #define set_softirq_pending(x) (local_softirq_pending() = (x)) #define or_softirq_pending(x) (local_softirq_pending() |= (x)) diff --git a/include/linux/mm.h b/include/linux/mm.h index e4183fa67..51eea5b38 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -166,6 +166,9 @@ extern unsigned int kobjsize(const void *objp); #define VM_NONLINEAR 0x00800000 /* Is non-linear (remap_file_pages) */ #define VM_MAPPED_COPY 0x01000000 /* T if mapped copy of data (nommu mmap) */ #define VM_INSERTPAGE 0x02000000 /* The vma has had "vm_insert_page()" done on it */ +#ifdef CONFIG_XEN +#define VM_FOREIGN 0x04000000 /* Has pages belonging to another VM */ +#endif #ifndef VM_STACK_DEFAULT_FLAGS /* arch can override this */ #define VM_STACK_DEFAULT_FLAGS VM_DATA_DEFAULT_FLAGS @@ -1026,6 +1029,13 @@ struct page *follow_page(struct vm_area_struct *, unsigned long address, #define FOLL_GET 0x04 /* do get_page on page */ #define FOLL_ANON 0x08 /* give ZERO_PAGE if no pgtable */ +#ifdef CONFIG_XEN +typedef int (*pte_fn_t)(pte_t *pte, struct page *pmd_page, unsigned long addr, + void *data); +extern int apply_to_page_range(struct mm_struct *mm, unsigned long address, + unsigned long size, pte_fn_t fn, void *data); +#endif + #ifdef CONFIG_PROC_FS void vm_stat_account(struct mm_struct *, unsigned long, struct file *, long); #else diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index f4169bbb6..c5b97cf59 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -232,6 +232,7 @@ enum netdev_state_t __LINK_STATE_RX_SCHED, __LINK_STATE_LINKWATCH_PENDING, __LINK_STATE_DORMANT, + __LINK_STATE_QDISC_RUNNING, }; @@ -307,9 +308,17 @@ struct net_device #define NETIF_F_HW_VLAN_RX 256 /* Receive VLAN hw acceleration */ #define NETIF_F_HW_VLAN_FILTER 512 /* Receive filtering on VLAN */ #define NETIF_F_VLAN_CHALLENGED 1024 /* Device cannot handle VLAN packets */ -#define NETIF_F_TSO 2048 /* Can offload TCP/IP segmentation */ +#define NETIF_F_GSO 2048 /* Enable software GSO. */ #define NETIF_F_LLTX 4096 /* LockLess TX */ -#define NETIF_F_UFO 8192 /* Can offload UDP Large Send*/ + + /* Segmentation offload features */ +#define NETIF_F_GSO_SHIFT 16 +#define NETIF_F_TSO (SKB_GSO_TCPV4 << NETIF_F_GSO_SHIFT) +#define NETIF_F_UFO (SKB_GSO_UDPV4 << NETIF_F_GSO_SHIFT) +#define NETIF_F_GSO_ROBUST (SKB_GSO_DODGY << NETIF_F_GSO_SHIFT) + +#define NETIF_F_GEN_CSUM (NETIF_F_NO_CSUM | NETIF_F_HW_CSUM) +#define NETIF_F_ALL_CSUM (NETIF_F_IP_CSUM | NETIF_F_GEN_CSUM) struct net_device *next_sched; @@ -398,6 +407,9 @@ struct net_device struct list_head qdisc_list; unsigned long tx_queue_len; /* Max frames per queue allowed */ + /* Partially transmitted GSO packet. */ + struct sk_buff *gso_skb; + /* ingress path synchronizer */ spinlock_t ingress_lock; struct Qdisc *qdisc_ingress; @@ -406,7 +418,7 @@ struct net_device * One part is mostly used on xmit path (device) */ /* hard_start_xmit synchronizer */ - spinlock_t xmit_lock ____cacheline_aligned_in_smp; + spinlock_t _xmit_lock ____cacheline_aligned_in_smp; /* cpu id of processor entered to hard_start_xmit or -1, if nobody entered there. */ @@ -532,6 +544,9 @@ struct packet_type { struct net_device *, struct packet_type *, struct net_device *); + struct sk_buff *(*gso_segment)(struct sk_buff *skb, + int features); + int (*gso_send_check)(struct sk_buff *skb); void *af_packet_priv; struct list_head list; }; @@ -679,7 +694,8 @@ extern int dev_change_name(struct net_device *, char *); extern int dev_set_mtu(struct net_device *, int); extern int dev_set_mac_address(struct net_device *, struct sockaddr *); -extern void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev); +extern int dev_hard_start_xmit(struct sk_buff *skb, + struct net_device *dev); extern void dev_init(void); @@ -889,11 +905,43 @@ static inline void __netif_rx_complete(struct net_device *dev) clear_bit(__LINK_STATE_RX_SCHED, &dev->state); } +static inline void netif_tx_lock(struct net_device *dev) +{ + spin_lock(&dev->_xmit_lock); + dev->xmit_lock_owner = smp_processor_id(); +} + +static inline void netif_tx_lock_bh(struct net_device *dev) +{ + spin_lock_bh(&dev->_xmit_lock); + dev->xmit_lock_owner = smp_processor_id(); +} + +static inline int netif_tx_trylock(struct net_device *dev) +{ + int ok = spin_trylock(&dev->_xmit_lock); + if (likely(ok)) + dev->xmit_lock_owner = smp_processor_id(); + return ok; +} + +static inline void netif_tx_unlock(struct net_device *dev) +{ + dev->xmit_lock_owner = -1; + spin_unlock(&dev->_xmit_lock); +} + +static inline void netif_tx_unlock_bh(struct net_device *dev) +{ + dev->xmit_lock_owner = -1; + spin_unlock_bh(&dev->_xmit_lock); +} + static inline void netif_tx_disable(struct net_device *dev) { - spin_lock_bh(&dev->xmit_lock); + netif_tx_lock_bh(dev); netif_stop_queue(dev); - spin_unlock_bh(&dev->xmit_lock); + netif_tx_unlock_bh(dev); } /* These functions live elsewhere (drivers/net/net_init.c, but related) */ @@ -921,6 +969,7 @@ extern int netdev_max_backlog; extern int weight_p; extern int netdev_set_master(struct net_device *dev, struct net_device *master); extern int skb_checksum_help(struct sk_buff *skb, int inward); +extern struct sk_buff *skb_gso_segment(struct sk_buff *skb, int features); #ifdef CONFIG_BUG extern void netdev_rx_csum_fault(struct net_device *dev); #else @@ -940,6 +989,19 @@ extern void dev_seq_stop(struct seq_file *seq, void *v); extern void linkwatch_run_queue(void); +static inline int skb_gso_ok(struct sk_buff *skb, int features) +{ + int feature = skb_shinfo(skb)->gso_type << NETIF_F_GSO_SHIFT; + return (features & feature) == feature; +} + +static inline int netif_needs_gso(struct net_device *dev, struct sk_buff *skb) +{ + return skb_is_gso(skb) && + (!skb_gso_ok(skb, dev->features) || + unlikely(skb->ip_summed != CHECKSUM_HW)); +} + #endif /* __KERNEL__ */ #endif /* _LINUX_DEV_H */ diff --git a/include/linux/netfilter_bridge.h b/include/linux/netfilter_bridge.h index a75b84bb9..178a97e1a 100644 --- a/include/linux/netfilter_bridge.h +++ b/include/linux/netfilter_bridge.h @@ -47,18 +47,26 @@ enum nf_br_hook_priorities { #define BRNF_BRIDGED 0x08 #define BRNF_NF_BRIDGE_PREROUTING 0x10 - /* Only used in br_forward.c */ -static inline -void nf_bridge_maybe_copy_header(struct sk_buff *skb) +static inline int 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 + } else { + err = skb_cow(skb, 16); + if (err) + return err; 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/include/linux/oprofile.h b/include/linux/oprofile.h index 0d514b252..6c33ee68d 100644 --- a/include/linux/oprofile.h +++ b/include/linux/oprofile.h @@ -16,6 +16,10 @@ #include #include #include + +#ifdef CONFIG_XEN +#include +#endif struct super_block; struct dentry; @@ -27,6 +31,11 @@ struct oprofile_operations { /* create any necessary configuration files in the oprofile fs. * Optional. */ int (*create_files)(struct super_block * sb, struct dentry * root); + /* setup active domains with Xen */ + int (*set_active)(int *active_domains, unsigned int adomains); + /* setup passive domains with Xen */ + int (*set_passive)(int *passive_domains, unsigned int pdomains); + /* Do any necessary interrupt setup. Optional. */ int (*setup)(void); /* Do any necessary interrupt shutdown. Optional. */ @@ -78,6 +87,8 @@ void oprofile_add_pc(unsigned long pc, int is_kernel, unsigned long event); /* add a backtrace entry, to be called from the ->backtrace callback */ void oprofile_add_trace(unsigned long eip); +/* add a domain switch entry */ +int oprofile_add_domain_switch(int32_t domain_id); /** * Create a file of the given name as a child of the given root, with diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 4550ab035..2bd4cbafc 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -1242,6 +1242,7 @@ #define PCI_DEVICE_ID_VIA_PX8X0_0 0x0259 #define PCI_DEVICE_ID_VIA_3269_0 0x0269 #define PCI_DEVICE_ID_VIA_K8T800PRO_0 0x0282 +#define PCI_DEVICE_ID_VIA_3296_0 0x0296 #define PCI_DEVICE_ID_VIA_8363_0 0x0305 #define PCI_DEVICE_ID_VIA_P4M800CE 0x0314 #define PCI_DEVICE_ID_VIA_8371_0 0x0391 @@ -1249,6 +1250,7 @@ #define PCI_DEVICE_ID_VIA_82C561 0x0561 #define PCI_DEVICE_ID_VIA_82C586_1 0x0571 #define PCI_DEVICE_ID_VIA_82C576 0x0576 +#define PCI_DEVICE_ID_VIA_SATA_EIDE 0x0581 #define PCI_DEVICE_ID_VIA_82C586_0 0x0586 #define PCI_DEVICE_ID_VIA_82C596 0x0596 #define PCI_DEVICE_ID_VIA_82C597_0 0x0597 @@ -1289,10 +1291,11 @@ #define PCI_DEVICE_ID_VIA_8783_0 0x3208 #define PCI_DEVICE_ID_VIA_8237 0x3227 #define PCI_DEVICE_ID_VIA_8251 0x3287 -#define PCI_DEVICE_ID_VIA_3296_0 0x0296 +#define PCI_DEVICE_ID_VIA_8237A 0x3337 #define PCI_DEVICE_ID_VIA_8231 0x8231 #define PCI_DEVICE_ID_VIA_8231_4 0x8235 #define PCI_DEVICE_ID_VIA_8365_1 0x8305 +#define PCI_DEVICE_ID_VIA_CX700 0x8324 #define PCI_DEVICE_ID_VIA_8371_1 0x8391 #define PCI_DEVICE_ID_VIA_82C598_1 0x8598 #define PCI_DEVICE_ID_VIA_838X_1 0xB188 diff --git a/include/linux/pfn.h b/include/linux/pfn.h index bb01f8b92..ba2a86677 100644 --- a/include/linux/pfn.h +++ b/include/linux/pfn.h @@ -4,6 +4,6 @@ #define PFN_ALIGN(x) (((unsigned long)(x) + (PAGE_SIZE - 1)) & PAGE_MASK) #define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT) #define PFN_DOWN(x) ((x) >> PAGE_SHIFT) -#define PFN_PHYS(x) ((x) << PAGE_SHIFT) +#define PFN_PHYS(x) ((unsigned long long)(x) << PAGE_SHIFT) #endif diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index c219f2f5f..e5f6a6824 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -134,9 +134,10 @@ struct skb_frag_struct { struct skb_shared_info { atomic_t dataref; unsigned short nr_frags; - unsigned short tso_size; - unsigned short tso_segs; - unsigned short ufo_size; + unsigned short gso_size; + /* Warning: this field is not always filled in (UFO)! */ + unsigned short gso_segs; + unsigned short gso_type; unsigned int ip6_frag_id; struct sk_buff *frag_list; skb_frag_t frags[MAX_SKB_FRAGS]; @@ -168,6 +169,14 @@ enum { SKB_FCLONE_CLONE, }; +enum { + SKB_GSO_TCPV4 = 1 << 0, + SKB_GSO_UDPV4 = 1 << 1, + + /* This indicates the skb is from an untrusted source. */ + SKB_GSO_DODGY = 1 << 2, +}; + /** * struct sk_buff - socket buffer * @next: Next buffer in list @@ -189,6 +198,8 @@ enum { * @local_df: allow local fragmentation * @cloned: Head may be cloned (check refcnt to be sure) * @nohdr: Payload reference only, must not modify header + * @proto_data_valid: Protocol data validated since arriving at localhost + * @proto_csum_blank: Protocol csum must be added before leaving localhost * @pkt_type: Packet class * @fclone: skbuff clone status * @ip_summed: Driver fed us an IP checksum @@ -265,7 +276,13 @@ struct sk_buff { nfctinfo:3; __u8 pkt_type:3, fclone:2, +#ifndef CONFIG_XEN ipvs_property:1; +#else + ipvs_property:1, + proto_data_valid:1, + proto_csum_blank:1; +#endif __be16 protocol; void (*destructor)(struct sk_buff *skb); @@ -322,7 +339,8 @@ static inline struct sk_buff *alloc_skb_fclone(unsigned int size, extern struct sk_buff *alloc_skb_from_cache(kmem_cache_t *cp, unsigned int size, - gfp_t priority); + gfp_t priority, + int fclone); extern void kfree_skbmem(struct sk_buff *skb); extern struct sk_buff *skb_clone(struct sk_buff *skb, gfp_t priority); @@ -967,15 +985,16 @@ static inline void skb_reserve(struct sk_buff *skb, int len) #define NET_SKB_PAD 16 #endif -extern int ___pskb_trim(struct sk_buff *skb, unsigned int len, int realloc); +extern int ___pskb_trim(struct sk_buff *skb, unsigned int len); static inline void __skb_trim(struct sk_buff *skb, unsigned int len) { - if (!skb->data_len) { - skb->len = len; - skb->tail = skb->data + len; - } else - ___pskb_trim(skb, len, 0); + if (unlikely(skb->data_len)) { + WARN_ON(1); + return; + } + skb->len = len; + skb->tail = skb->data + len; } /** @@ -985,6 +1004,7 @@ static inline void __skb_trim(struct sk_buff *skb, unsigned int len) * * Cut the length of a buffer down by removing data from the tail. If * the buffer is already under the length specified it is not modified. + * The skb must be linear. */ static inline void skb_trim(struct sk_buff *skb, unsigned int len) { @@ -995,12 +1015,10 @@ static inline void skb_trim(struct sk_buff *skb, unsigned int len) static inline int __pskb_trim(struct sk_buff *skb, unsigned int len) { - if (!skb->data_len) { - skb->len = len; - skb->tail = skb->data+len; - return 0; - } - return ___pskb_trim(skb, len, 1); + if (skb->data_len) + return ___pskb_trim(skb, len); + __skb_trim(skb, len); + return 0; } static inline int pskb_trim(struct sk_buff *skb, unsigned int len) @@ -1008,6 +1026,21 @@ static inline int pskb_trim(struct sk_buff *skb, unsigned int len) return (len < skb->len) ? __pskb_trim(skb, len) : 0; } +/** + * pskb_trim_unique - remove end from a paged unique (not cloned) buffer + * @skb: buffer to alter + * @len: new length + * + * This is identical to pskb_trim except that the caller knows that + * the skb is not cloned so we should never get an error due to out- + * of-memory. + */ +static inline void pskb_trim_unique(struct sk_buff *skb, unsigned int len) +{ + int err = pskb_trim(skb, len); + BUG_ON(err); +} + /** * skb_orphan - orphan a buffer * @skb: buffer to orphan @@ -1062,7 +1095,7 @@ static inline struct sk_buff *__dev_alloc_skb(unsigned int length, return skb; } #else -extern struct sk_buff *__dev_alloc_skb(unsigned int length, int gfp_mask); +extern struct sk_buff *__dev_alloc_skb(unsigned int length, gfp_t gfp_mask); #endif /** @@ -1161,18 +1194,34 @@ static inline int skb_can_coalesce(struct sk_buff *skb, int i, return 0; } +static inline int __skb_linearize(struct sk_buff *skb) +{ + return __pskb_pull_tail(skb, skb->data_len) ? 0 : -ENOMEM; +} + /** * skb_linearize - convert paged skb to linear one * @skb: buffer to linarize - * @gfp: allocation mode * * If there is no free memory -ENOMEM is returned, otherwise zero * is returned and the old skb data released. */ -extern int __skb_linearize(struct sk_buff *skb, gfp_t gfp); -static inline int skb_linearize(struct sk_buff *skb, gfp_t gfp) +static inline int skb_linearize(struct sk_buff *skb) +{ + return skb_is_nonlinear(skb) ? __skb_linearize(skb) : 0; +} + +/** + * skb_linearize_cow - make sure skb is linear and writable + * @skb: buffer to process + * + * If there is no free memory -ENOMEM is returned, otherwise zero + * is returned and the old skb data released. + */ +static inline int skb_linearize_cow(struct sk_buff *skb) { - return __skb_linearize(skb, gfp); + return skb_is_nonlinear(skb) || skb_cloned(skb) ? + __skb_linearize(skb) : 0; } /** @@ -1269,6 +1318,7 @@ extern void skb_split(struct sk_buff *skb, struct sk_buff *skb1, const u32 len); extern void skb_release_data(struct sk_buff *skb); +extern struct sk_buff *skb_segment(struct sk_buff *skb, int features); static inline void *skb_header_pointer(const struct sk_buff *skb, int offset, int len, void *buffer) @@ -1398,5 +1448,10 @@ static inline void nf_reset(struct sk_buff *skb) static inline void nf_reset(struct sk_buff *skb) {} #endif /* CONFIG_NETFILTER */ +static inline int skb_is_gso(const struct sk_buff *skb) +{ + return skb_shinfo(skb)->gso_size; +} + #endif /* __KERNEL__ */ #endif /* _LINUX_SKBUFF_H */ diff --git a/include/linux/tty.h b/include/linux/tty.h index 87931555b..f13f49afe 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -297,8 +297,6 @@ extern int tty_read_raw_data(struct tty_struct *tty, unsigned char *bufp, int buflen); extern void tty_write_message(struct tty_struct *tty, char *msg); -extern void tty_get_termios(struct tty_driver *drv, int idx, struct termios *tio); - extern int is_orphaned_pgrp(int pgrp); extern int is_ignored(int sig); extern int tty_signal(int sig, struct tty_struct *tty); diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h index b94d1ad92..75b5b9333 100644 --- a/include/net/pkt_sched.h +++ b/include/net/pkt_sched.h @@ -218,12 +218,13 @@ extern struct qdisc_rate_table *qdisc_get_rtab(struct tc_ratespec *r, struct rtattr *tab); extern void qdisc_put_rtab(struct qdisc_rate_table *tab); -extern int qdisc_restart(struct net_device *dev); +extern void __qdisc_run(struct net_device *dev); static inline void qdisc_run(struct net_device *dev) { - while (!netif_queue_stopped(dev) && qdisc_restart(dev) < 0) - /* NOTHING */; + if (!netif_queue_stopped(dev) && + !test_and_set_bit(__LINK_STATE_QDISC_RUNNING, &dev->state)) + __qdisc_run(dev); } extern int tc_classify(struct sk_buff *skb, struct tcf_proto *tp, diff --git a/include/net/protocol.h b/include/net/protocol.h index 6dc597061..d516c58ce 100644 --- a/include/net/protocol.h +++ b/include/net/protocol.h @@ -37,6 +37,9 @@ struct net_protocol { int (*handler)(struct sk_buff *skb); void (*err_handler)(struct sk_buff *skb, u32 info); + int (*gso_send_check)(struct sk_buff *skb); + struct sk_buff *(*gso_segment)(struct sk_buff *skb, + int features); int no_policy; }; diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h index aa6033ca7..225dcea94 100644 --- a/include/net/sctp/sctp.h +++ b/include/net/sctp/sctp.h @@ -405,19 +405,6 @@ 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/include/net/sctp/sm.h b/include/net/sctp/sm.h index 1eac3d0eb..de313de4f 100644 --- a/include/net/sctp/sm.h +++ b/include/net/sctp/sm.h @@ -221,8 +221,7 @@ 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 sctp_chunk *, - const struct msghdr *); + const struct msghdr *, size_t msg_len); struct sctp_chunk *sctp_make_abort_violation(const struct sctp_association *, const struct sctp_chunk *, const __u8 *, diff --git a/include/net/sock.h b/include/net/sock.h index f6e3f99c0..924d3481b 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -1042,9 +1042,13 @@ static inline void sk_setup_caps(struct sock *sk, struct dst_entry *dst) { __sk_dst_set(sk, dst); sk->sk_route_caps = dst->dev->features; + if (sk->sk_route_caps & NETIF_F_GSO) + sk->sk_route_caps |= NETIF_F_TSO; if (sk->sk_route_caps & NETIF_F_TSO) { if (sock_flag(sk, SOCK_NO_LARGESEND) || dst->header_len) sk->sk_route_caps &= ~NETIF_F_TSO; + else + sk->sk_route_caps |= NETIF_F_SG | NETIF_F_HW_CSUM; } } diff --git a/include/net/tcp.h b/include/net/tcp.h index c0f884027..8fa246247 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -568,13 +568,13 @@ struct tcp_skb_cb { */ static inline int tcp_skb_pcount(const struct sk_buff *skb) { - return skb_shinfo(skb)->tso_segs; + return skb_shinfo(skb)->gso_segs; } /* This is valid iff tcp_skb_pcount() > 1. */ static inline int tcp_skb_mss(const struct sk_buff *skb) { - return skb_shinfo(skb)->tso_size; + return skb_shinfo(skb)->gso_size; } static inline void tcp_dec_pcount_approx(__u32 *count, @@ -1079,6 +1079,9 @@ extern struct request_sock_ops tcp_request_sock_ops; extern int tcp_v4_destroy_sock(struct sock *sk); +extern int tcp_v4_gso_send_check(struct sk_buff *skb); +extern struct sk_buff *tcp_tso_segment(struct sk_buff *skb, int features); + #ifdef CONFIG_PROC_FS extern int tcp4_proc_init(void); extern void tcp4_proc_exit(void); diff --git a/include/scsi/iscsi_if.h b/include/scsi/iscsi_if.h index 0196291f6..e5618b909 100644 --- a/include/scsi/iscsi_if.h +++ b/include/scsi/iscsi_if.h @@ -43,10 +43,6 @@ enum iscsi_uevent_e { ISCSI_UEVENT_GET_STATS = UEVENT_BASE + 10, ISCSI_UEVENT_GET_PARAM = UEVENT_BASE + 11, - ISCSI_UEVENT_TRANSPORT_EP_CONNECT = UEVENT_BASE + 12, - ISCSI_UEVENT_TRANSPORT_EP_POLL = UEVENT_BASE + 13, - ISCSI_UEVENT_TRANSPORT_EP_DISCONNECT = UEVENT_BASE + 14, - /* up events */ ISCSI_KEVENT_RECV_PDU = KEVENT_BASE + 1, ISCSI_KEVENT_CONN_ERROR = KEVENT_BASE + 2, @@ -64,83 +60,61 @@ struct iscsi_uevent { uint32_t initial_cmdsn; } c_session; struct msg_destroy_session { + uint64_t session_handle; uint32_t sid; } d_session; struct msg_create_conn { - uint32_t sid; + uint64_t session_handle; uint32_t cid; + uint32_t sid; } c_conn; struct msg_bind_conn { - uint32_t sid; - uint32_t cid; - uint64_t transport_eph; + uint64_t session_handle; + uint64_t conn_handle; + uint32_t transport_fd; uint32_t is_leading; } b_conn; struct msg_destroy_conn { - uint32_t sid; + uint64_t conn_handle; uint32_t cid; } d_conn; struct msg_send_pdu { - uint32_t sid; - uint32_t cid; uint32_t hdr_size; uint32_t data_size; + uint64_t conn_handle; } send_pdu; struct msg_set_param { - uint32_t sid; - uint32_t cid; + uint64_t conn_handle; uint32_t param; /* enum iscsi_param */ - uint32_t len; + uint32_t value; } set_param; struct msg_start_conn { - uint32_t sid; - uint32_t cid; + uint64_t conn_handle; } start_conn; struct msg_stop_conn { - uint32_t sid; - uint32_t cid; uint64_t conn_handle; uint32_t flag; } stop_conn; struct msg_get_stats { - uint32_t sid; - uint32_t cid; + uint64_t conn_handle; } get_stats; - struct msg_transport_connect { - uint32_t non_blocking; - } ep_connect; - struct msg_transport_poll { - uint64_t ep_handle; - uint32_t timeout_ms; - } ep_poll; - struct msg_transport_disconnect { - uint64_t ep_handle; - } ep_disconnect; } u; union { /* messages k -> u */ + uint64_t handle; int retcode; struct msg_create_session_ret { + uint64_t session_handle; uint32_t sid; - uint32_t host_no; } c_session_ret; - struct msg_create_conn_ret { - uint32_t sid; - uint32_t cid; - } c_conn_ret; struct msg_recv_req { - uint32_t sid; - uint32_t cid; uint64_t recv_handle; + uint64_t conn_handle; } recv_req; struct msg_conn_error { - uint32_t sid; - uint32_t cid; + uint64_t conn_handle; uint32_t error; /* enum iscsi_err */ } connerror; - struct msg_transport_connect_ret { - uint64_t handle; - } ep_connect_ret; } r; } __attribute__ ((aligned (sizeof(uint64_t)))); @@ -165,66 +139,29 @@ enum iscsi_err { ISCSI_ERR_SESSION_FAILED = ISCSI_ERR_BASE + 13, ISCSI_ERR_HDR_DGST = ISCSI_ERR_BASE + 14, ISCSI_ERR_DATA_DGST = ISCSI_ERR_BASE + 15, - ISCSI_ERR_PARAM_NOT_FOUND = ISCSI_ERR_BASE + 16, - ISCSI_ERR_NO_SCSI_CMD = ISCSI_ERR_BASE + 17, + ISCSI_ERR_PARAM_NOT_FOUND = ISCSI_ERR_BASE + 16 }; /* * iSCSI Parameters (RFC3720) */ enum iscsi_param { - /* passed in using netlink set param */ - ISCSI_PARAM_MAX_RECV_DLENGTH, - ISCSI_PARAM_MAX_XMIT_DLENGTH, - ISCSI_PARAM_HDRDGST_EN, - ISCSI_PARAM_DATADGST_EN, - ISCSI_PARAM_INITIAL_R2T_EN, - ISCSI_PARAM_MAX_R2T, - ISCSI_PARAM_IMM_DATA_EN, - ISCSI_PARAM_FIRST_BURST, - ISCSI_PARAM_MAX_BURST, - ISCSI_PARAM_PDU_INORDER_EN, - ISCSI_PARAM_DATASEQ_INORDER_EN, - ISCSI_PARAM_ERL, - ISCSI_PARAM_IFMARKER_EN, - ISCSI_PARAM_OFMARKER_EN, - ISCSI_PARAM_EXP_STATSN, - ISCSI_PARAM_TARGET_NAME, - ISCSI_PARAM_TPGT, - ISCSI_PARAM_PERSISTENT_ADDRESS, - ISCSI_PARAM_PERSISTENT_PORT, - ISCSI_PARAM_SESS_RECOVERY_TMO, - - /* pased in through bind conn using transport_fd */ - ISCSI_PARAM_CONN_PORT, - ISCSI_PARAM_CONN_ADDRESS, - - /* must always be last */ - ISCSI_PARAM_MAX, + ISCSI_PARAM_MAX_RECV_DLENGTH = 0, + ISCSI_PARAM_MAX_XMIT_DLENGTH = 1, + ISCSI_PARAM_HDRDGST_EN = 2, + ISCSI_PARAM_DATADGST_EN = 3, + ISCSI_PARAM_INITIAL_R2T_EN = 4, + ISCSI_PARAM_MAX_R2T = 5, + ISCSI_PARAM_IMM_DATA_EN = 6, + ISCSI_PARAM_FIRST_BURST = 7, + ISCSI_PARAM_MAX_BURST = 8, + ISCSI_PARAM_PDU_INORDER_EN = 9, + ISCSI_PARAM_DATASEQ_INORDER_EN = 10, + ISCSI_PARAM_ERL = 11, + ISCSI_PARAM_IFMARKER_EN = 12, + ISCSI_PARAM_OFMARKER_EN = 13, }; - -#define ISCSI_MAX_RECV_DLENGTH (1 << ISCSI_PARAM_MAX_RECV_DLENGTH) -#define ISCSI_MAX_XMIT_DLENGTH (1 << ISCSI_PARAM_MAX_XMIT_DLENGTH) -#define ISCSI_HDRDGST_EN (1 << ISCSI_PARAM_HDRDGST_EN) -#define ISCSI_DATADGST_EN (1 << ISCSI_PARAM_DATADGST_EN) -#define ISCSI_INITIAL_R2T_EN (1 << ISCSI_PARAM_INITIAL_R2T_EN) -#define ISCSI_MAX_R2T (1 << ISCSI_PARAM_MAX_R2T) -#define ISCSI_IMM_DATA_EN (1 << ISCSI_PARAM_IMM_DATA_EN) -#define ISCSI_FIRST_BURST (1 << ISCSI_PARAM_FIRST_BURST) -#define ISCSI_MAX_BURST (1 << ISCSI_PARAM_MAX_BURST) -#define ISCSI_PDU_INORDER_EN (1 << ISCSI_PARAM_PDU_INORDER_EN) -#define ISCSI_DATASEQ_INORDER_EN (1 << ISCSI_PARAM_DATASEQ_INORDER_EN) -#define ISCSI_ERL (1 << ISCSI_PARAM_ERL) -#define ISCSI_IFMARKER_EN (1 << ISCSI_PARAM_IFMARKER_EN) -#define ISCSI_OFMARKER_EN (1 << ISCSI_PARAM_OFMARKER_EN) -#define ISCSI_EXP_STATSN (1 << ISCSI_PARAM_EXP_STATSN) -#define ISCSI_TARGET_NAME (1 << ISCSI_PARAM_TARGET_NAME) -#define ISCSI_TPGT (1 << ISCSI_PARAM_TPGT) -#define ISCSI_PERSISTENT_ADDRESS (1 << ISCSI_PARAM_PERSISTENT_ADDRESS) -#define ISCSI_PERSISTENT_PORT (1 << ISCSI_PARAM_PERSISTENT_PORT) -#define ISCSI_SESS_RECOVERY_TMO (1 << ISCSI_PARAM_SESS_RECOVERY_TMO) -#define ISCSI_CONN_PORT (1 << ISCSI_PARAM_CONN_PORT) -#define ISCSI_CONN_ADDRESS (1 << ISCSI_PARAM_CONN_ADDRESS) +#define ISCSI_PARAM_MAX 14 #define iscsi_ptr(_handle) ((void*)(unsigned long)_handle) #define iscsi_handle(_ptr) ((uint64_t)(unsigned long)_ptr) @@ -253,6 +190,7 @@ enum iscsi_param { * These flags describes reason of stop_conn() call */ #define STOP_CONN_TERM 0x1 +#define STOP_CONN_SUSPEND 0x2 #define STOP_CONN_RECOVER 0x3 #define ISCSI_STATS_CUSTOM_MAX 32 diff --git a/include/scsi/iscsi_proto.h b/include/scsi/iscsi_proto.h index 02f6e4b9e..4feda05fd 100644 --- a/include/scsi/iscsi_proto.h +++ b/include/scsi/iscsi_proto.h @@ -21,6 +21,8 @@ #ifndef ISCSI_PROTO_H #define ISCSI_PROTO_H +#define ISCSI_VERSION_STR "0.3" +#define ISCSI_DATE_STR "22-Apr-2005" #define ISCSI_DRAFT20_VERSION 0x00 /* default iSCSI listen port for incoming connections */ diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h index b684426a5..b41cf077e 100644 --- a/include/scsi/scsi_transport_iscsi.h +++ b/include/scsi/scsi_transport_iscsi.h @@ -2,7 +2,7 @@ * iSCSI transport class definitions * * Copyright (C) IBM Corporation, 2004 - * Copyright (C) Mike Christie, 2004 - 2006 + * Copyright (C) Mike Christie, 2004 - 2005 * Copyright (C) Dmitry Yusupov, 2004 - 2005 * Copyright (C) Alex Aizman, 2004 - 2005 * @@ -27,13 +27,9 @@ #include struct scsi_transport_template; -struct iscsi_transport; struct Scsi_Host; struct mempool_zone; struct iscsi_cls_conn; -struct iscsi_conn; -struct iscsi_cmd_task; -struct iscsi_mgmt_task; /** * struct iscsi_transport - iSCSI Transport template @@ -50,24 +46,6 @@ struct iscsi_mgmt_task; * @start_conn: set connection to be operational * @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. - * Called from iscsi_conn_send_generic with xmitmutex. - * @xmit_cmd_task: Requests LLD to transfer cmd task. Returns 0 or the - * the number of bytes transferred on success, and -Exyz - * value on error. - * @xmit_mgmt_task: Requests LLD to transfer mgmt task. Returns 0 or the - * the number of bytes transferred on success, and -Exyz - * value on error. - * @cleanup_cmd_task: requests LLD to fail cmd task. Called with xmitmutex - * and session->lock after the connection has been - * suspended and terminated during recovery. If called - * from abort task then connection is not suspended - * or terminated but sk_callback_lock is held * * Template API provided by iSCSI Transport */ @@ -75,58 +53,38 @@ struct iscsi_transport { struct module *owner; char *name; unsigned int caps; - /* LLD sets this to indicate what values it can export to sysfs */ - unsigned int param_mask; struct scsi_host_template *host_template; + /* LLD session/scsi_host data size */ + int hostdata_size; + /* LLD iscsi_host data size */ + int ihostdata_size; /* LLD connection data size */ int conndata_size; - /* LLD session data size */ - int sessiondata_size; int max_lun; unsigned int max_conn; unsigned int max_cmd_len; - struct iscsi_cls_session *(*create_session) (struct iscsi_transport *it, - struct scsi_transport_template *t, uint32_t sn, uint32_t *hn); + struct iscsi_cls_session *(*create_session) + (struct scsi_transport_template *t, uint32_t sn, uint32_t *sid); void (*destroy_session) (struct iscsi_cls_session *session); struct iscsi_cls_conn *(*create_conn) (struct iscsi_cls_session *sess, uint32_t cid); int (*bind_conn) (struct iscsi_cls_session *session, struct iscsi_cls_conn *cls_conn, - uint64_t transport_eph, int is_leading); + uint32_t transport_fd, int is_leading); int (*start_conn) (struct iscsi_cls_conn *conn); void (*stop_conn) (struct iscsi_cls_conn *conn, int flag); void (*destroy_conn) (struct iscsi_cls_conn *conn); int (*set_param) (struct iscsi_cls_conn *conn, enum iscsi_param param, uint32_t value); int (*get_conn_param) (struct iscsi_cls_conn *conn, - enum iscsi_param param, uint32_t *value); + enum iscsi_param param, + uint32_t *value); int (*get_session_param) (struct iscsi_cls_session *session, enum iscsi_param param, uint32_t *value); - int (*get_conn_str_param) (struct iscsi_cls_conn *conn, - enum iscsi_param param, char *buf); - int (*get_session_str_param) (struct iscsi_cls_session *session, - enum iscsi_param param, char *buf); int (*send_pdu) (struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr, 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, - char *data, uint32_t data_size); - int (*xmit_cmd_task) (struct iscsi_conn *conn, - struct iscsi_cmd_task *ctask); - void (*cleanup_cmd_task) (struct iscsi_conn *conn, - struct iscsi_cmd_task *ctask); - int (*xmit_mgmt_task) (struct iscsi_conn *conn, - struct iscsi_mgmt_task *mtask); - void (*session_recovery_timedout) (struct iscsi_cls_session *session); - int (*ep_connect) (struct sockaddr *dst_addr, int non_blocking, - uint64_t *ep_handle); - int (*ep_poll) (uint64_t ep_handle, int timeout_ms); - void (*ep_disconnect) (uint64_t ep_handle); }; /* @@ -142,26 +100,10 @@ extern void iscsi_conn_error(struct iscsi_cls_conn *conn, enum iscsi_err error); extern int iscsi_recv_pdu(struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr, char *data, uint32_t data_size); - -/* Connection's states */ -#define ISCSI_CONN_INITIAL_STAGE 0 -#define ISCSI_CONN_STARTED 1 -#define ISCSI_CONN_STOPPED 2 -#define ISCSI_CONN_CLEANUP_WAIT 3 - struct iscsi_cls_conn { struct list_head conn_list; /* item in connlist */ void *dd_data; /* LLD private data */ struct iscsi_transport *transport; - uint32_t cid; /* connection id */ - - /* portal/group values we got during discovery */ - char *persistent_address; - int persistent_port; - /* portal/group values we are currently using */ - char *address; - int port; - int active; /* must be accessed with the connlock */ struct device dev; /* sysfs transport/container device */ struct mempool_zone *z_error; @@ -172,32 +114,9 @@ struct iscsi_cls_conn { #define iscsi_dev_to_conn(_dev) \ container_of(_dev, struct iscsi_cls_conn, dev) -/* Session's states */ -#define ISCSI_STATE_FREE 1 -#define ISCSI_STATE_LOGGED_IN 2 -#define ISCSI_STATE_FAILED 3 -#define ISCSI_STATE_TERMINATE 4 -#define ISCSI_STATE_IN_RECOVERY 5 -#define ISCSI_STATE_RECOVERY_FAILED 6 - struct iscsi_cls_session { struct list_head sess_list; /* item in session_list */ - struct list_head host_list; struct iscsi_transport *transport; - - /* iSCSI values used as unique id by userspace. */ - char *targetname; - int tpgt; - - /* recovery fields */ - int recovery_tmo; - struct work_struct recovery_work; - - int target_id; - int channel; - - int sid; /* session id */ - void *dd_data; /* LLD private data */ struct device dev; /* sysfs transport/container device */ }; @@ -207,22 +126,22 @@ struct iscsi_cls_session { #define iscsi_session_to_shost(_session) \ dev_to_shost(_session->dev.parent) -struct iscsi_host { - int next_target_id; - struct list_head sessions; - struct mutex mutex; -}; - /* * session and connection functions that can be used by HW iSCSI LLDs */ extern struct iscsi_cls_session *iscsi_create_session(struct Scsi_Host *shost, - struct iscsi_transport *t, int channel); + struct iscsi_transport *t); extern int iscsi_destroy_session(struct iscsi_cls_session *session); extern struct iscsi_cls_conn *iscsi_create_conn(struct iscsi_cls_session *sess, uint32_t cid); extern int iscsi_destroy_conn(struct iscsi_cls_conn *conn); -extern void iscsi_unblock_session(struct iscsi_cls_session *session); -extern void iscsi_block_session(struct iscsi_cls_session *session); + +/* + * session functions used by software iscsi + */ +extern struct Scsi_Host * +iscsi_transport_create_session(struct scsi_transport_template *scsit, + struct iscsi_transport *transport); +extern int iscsi_transport_destroy_session(struct Scsi_Host *shost); #endif diff --git a/include/sound/initval.h b/include/sound/initval.h index d29e3d31d..d45170b9e 100644 --- a/include/sound/initval.h +++ b/include/sound/initval.h @@ -62,7 +62,8 @@ static int snd_legacy_find_free_irq(int *irq_table) { while (*irq_table != -1) { if (!request_irq(*irq_table, snd_legacy_empty_irq_handler, - SA_INTERRUPT, "ALSA Test IRQ", (void *) irq_table)) { + SA_INTERRUPT | SA_PROBEIRQ, "ALSA Test IRQ", + (void *) irq_table)) { free_irq(*irq_table, (void *) irq_table); return *irq_table; } diff --git a/kernel/Kconfig.preempt b/kernel/Kconfig.preempt index 0b46a5dff..17ab32232 100644 --- a/kernel/Kconfig.preempt +++ b/kernel/Kconfig.preempt @@ -35,6 +35,7 @@ config PREEMPT_VOLUNTARY config PREEMPT bool "Preemptible Kernel (Low-Latency Desktop)" + depends on !XEN help This option reduces the latency of the kernel by making all kernel code (that is not executing in a critical section) diff --git a/kernel/fork.c b/kernel/fork.c index fcaaa9978..471d19f71 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -280,6 +280,9 @@ static inline int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm) if (retval) goto out; } +#ifdef arch_dup_mmap + arch_dup_mmap(mm, oldmm); +#endif retval = 0; out: up_write(&mm->mmap_sem); diff --git a/kernel/futex.c b/kernel/futex.c index 9ddf5010a..c27bb560b 100644 --- a/kernel/futex.c +++ b/kernel/futex.c @@ -594,6 +594,7 @@ static int unqueue_me(struct futex_q *q) /* In the common case we don't take the spinlock, which is nice. */ retry: lock_ptr = q->lock_ptr; + barrier(); if (lock_ptr != 0) { spin_lock(lock_ptr); /* diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index 1279e3499..97d555999 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c @@ -204,14 +204,10 @@ int setup_irq(unsigned int irq, struct irqaction * new) p = &desc->action; if ((old = *p) != NULL) { /* Can't share interrupts unless both agree to */ - if (!(old->flags & new->flags & SA_SHIRQ)) - goto mismatch; - -#if defined(ARCH_HAS_IRQ_PER_CPU) && defined(SA_PERCPU_IRQ) - /* All handlers must agree on per-cpuness */ - if ((old->flags & IRQ_PER_CPU) != (new->flags & IRQ_PER_CPU)) - goto mismatch; -#endif + if (!(old->flags & new->flags & SA_SHIRQ)) { + spin_unlock_irqrestore(&desc->lock,flags); + return -EBUSY; + } /* add new interrupt at end of irq queue */ do { @@ -222,10 +218,7 @@ int setup_irq(unsigned int irq, struct irqaction * new) } *p = new; -#if defined(ARCH_HAS_IRQ_PER_CPU) && defined(SA_PERCPU_IRQ) - if (new->flags & SA_PERCPU_IRQ) - desc->status |= IRQ_PER_CPU; -#endif + if (!shared) { desc->depth = 0; desc->status &= ~(IRQ_DISABLED | IRQ_AUTODETECT | @@ -243,14 +236,6 @@ int setup_irq(unsigned int irq, struct irqaction * new) register_handler_proc(irq, new); return 0; - -mismatch: - spin_unlock_irqrestore(&desc->lock, flags); - if (!(new->flags & SA_PROBEIRQ)) { - printk(KERN_ERR "%s: irq handler mismatch\n", __FUNCTION__); - dump_stack(); - } - return -EBUSY; } /** @@ -273,7 +258,6 @@ void free_irq(unsigned int irq, void *dev_id) struct irqaction **p; unsigned long flags; - WARN_ON(in_interrupt()); if (irq >= NR_IRQS) return; diff --git a/kernel/irq/spurious.c b/kernel/irq/spurious.c index 7df9abd5e..f9353e960 100644 --- a/kernel/irq/spurious.c +++ b/kernel/irq/spurious.c @@ -137,7 +137,8 @@ void note_interrupt(unsigned int irq, irq_desc_t *desc, irqreturn_t action_ret, struct pt_regs *regs) { if (action_ret != IRQ_HANDLED) { - desc->irqs_unhandled++; + if (!irq_ignore_unhandled(irq)) + desc->irqs_unhandled++; if (action_ret != IRQ_NONE) report_bad_irq(irq, desc, action_ret); } diff --git a/kernel/sched.c b/kernel/sched.c index 60bff8bec..026ba1f6c 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -4189,17 +4189,22 @@ asmlinkage long sys_sched_yield(void) return 0; } -static inline void __cond_resched(void) +static inline int __resched_legal(int expected_preempt_count) +{ + if (unlikely(preempt_count() != expected_preempt_count)) + return 0; + if (unlikely(system_state != SYSTEM_RUNNING)) + return 0; + return 1; +} + +static void __cond_resched(void) { /* * The BKS might be reacquired before we have dropped * PREEMPT_ACTIVE, which could trigger a second * cond_resched() call. */ - if (unlikely(preempt_count())) - return; - if (unlikely(system_state != SYSTEM_RUNNING)) - return; do { add_preempt_count(PREEMPT_ACTIVE); schedule(); @@ -4209,13 +4214,12 @@ static inline void __cond_resched(void) int __sched cond_resched(void) { - if (need_resched()) { + if (need_resched() && __resched_legal(0)) { __cond_resched(); return 1; } return 0; } - EXPORT_SYMBOL(cond_resched); /* @@ -4236,7 +4240,7 @@ int cond_resched_lock(spinlock_t *lock) ret = 1; spin_lock(lock); } - if (need_resched()) { + if (need_resched() && __resched_legal(1)) { _raw_spin_unlock(lock); preempt_enable_no_resched(); __cond_resched(); @@ -4245,14 +4249,13 @@ int cond_resched_lock(spinlock_t *lock) } return ret; } - EXPORT_SYMBOL(cond_resched_lock); int __sched cond_resched_softirq(void) { BUG_ON(!in_softirq()); - if (need_resched()) { + if (need_resched() && __resched_legal(0)) { __local_bh_enable(); __cond_resched(); local_bh_disable(); @@ -4260,10 +4263,8 @@ int __sched cond_resched_softirq(void) } return 0; } - EXPORT_SYMBOL(cond_resched_softirq); - /** * yield - yield the current processor to other threads. * diff --git a/kernel/stop_machine.c b/kernel/stop_machine.c index dcfb5d731..51cacd111 100644 --- a/kernel/stop_machine.c +++ b/kernel/stop_machine.c @@ -111,7 +111,6 @@ 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/kernel/timer.c b/kernel/timer.c index 2f8cdbe00..20a4bca5e 100644 --- a/kernel/timer.c +++ b/kernel/timer.c @@ -543,6 +543,22 @@ found: } spin_unlock(&base->lock); + /* + * It can happen that other CPUs service timer IRQs and increment + * jiffies, but we have not yet got a local timer tick to process + * the timer wheels. In that case, the expiry time can be before + * jiffies, but since the high-resolution timer here is relative to + * jiffies, the default expression when high-resolution timers are + * not active, + * + * time_before(MAX_JIFFY_OFFSET + jiffies, expires) + * + * would falsely evaluate to true. If that is the case, just + * return jiffies so that we can immediately fire the local timer + */ + if (time_before(expires, jiffies)) + return jiffies; + /* * It can happen that other CPUs service timer IRQs and increment * jiffies, but we have not yet got a local timer tick to process @@ -971,46 +987,18 @@ asmlinkage long sys_getpid(void) } /* - * Accessing ->group_leader->real_parent is not SMP-safe, it could - * change from under us. However, rather than getting any lock - * we can use an optimistic algorithm: get the parent - * pid, and go back and check that the parent is still - * the same. If it has changed (which is extremely unlikely - * indeed), we just try again.. - * - * NOTE! This depends on the fact that even if we _do_ - * get an old value of "parent", we can happily dereference - * the pointer (it was and remains a dereferencable kernel pointer - * no matter what): we just can't necessarily trust the result - * until we know that the parent pointer is valid. - * - * NOTE2: ->group_leader never changes from under us. + * Accessing ->real_parent is not SMP-safe, it could + * change from under us. However, we can use a stale + * value of ->real_parent under rcu_read_lock(), see + * release_task()->call_rcu(delayed_put_task_struct). */ asmlinkage long sys_getppid(void) { int pid; - struct task_struct *me = current; - struct task_struct *parent; - parent = me->group_leader->real_parent; - for (;;) { - pid = parent->tgid; -#if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT) -{ - struct task_struct *old = parent; - - /* - * Make sure we read the pid before re-reading the - * parent pointer: - */ - smp_rmb(); - parent = me->group_leader->real_parent; - if (old != parent) - continue; -} -#endif - break; - } + rcu_read_lock(); + pid = rcu_dereference(current->real_parent)->tgid; + rcu_read_unlock(); return vx_map_pid(pid); } @@ -1025,7 +1013,7 @@ asmlinkage long do_getxpid(long *ppid) *ppid = sys_getppid(); return sys_getpid(); } - + #else /* _alpha_ */ asmlinkage long sys_getuid(void) diff --git a/lib/Makefile b/lib/Makefile index b830c9a15..033ff7c67 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -48,6 +48,9 @@ obj-$(CONFIG_TEXTSEARCH_BM) += ts_bm.o obj-$(CONFIG_TEXTSEARCH_FSM) += ts_fsm.o obj-$(CONFIG_SWIOTLB) += swiotlb.o +ifneq ($(CONFIG_XEN_IA64_DOM0_NON_VP),y) +swiotlb-$(CONFIG_XEN) := ../arch/i386/kernel/swiotlb.o +endif hostprogs-y := gen_crc32table clean-files := crc32table.h diff --git a/lib/idr.c b/lib/idr.c index de19030a9..4d0968195 100644 --- a/lib/idr.c +++ b/lib/idr.c @@ -29,6 +29,7 @@ #include #include #endif +#include #include #include @@ -398,6 +399,48 @@ void *idr_find(struct idr *idp, int id) } EXPORT_SYMBOL(idr_find); +/** + * idr_replace - replace pointer for given id + * @idp: idr handle + * @ptr: pointer you want associated with the id + * @id: lookup key + * + * Replace the pointer registered with an id and return the old value. + * A -ENOENT return indicates that @id was not found. + * A -EINVAL return indicates that @id was not within valid constraints. + * + * The caller must serialize vs idr_find(), idr_get_new(), and idr_remove(). + */ +void *idr_replace(struct idr *idp, void *ptr, int id) +{ + int n; + struct idr_layer *p, *old_p; + + n = idp->layers * IDR_BITS; + p = idp->top; + + id &= MAX_ID_MASK; + + if (id >= (1 << n)) + return ERR_PTR(-EINVAL); + + n -= IDR_BITS; + while ((n > 0) && p) { + p = p->ary[(id >> n) & IDR_MASK]; + n -= IDR_BITS; + } + + n = id & IDR_MASK; + if (unlikely(p == NULL || !test_bit(n, &p->bitmap))) + return ERR_PTR(-ENOENT); + + old_p = p->ary[n]; + p->ary[n] = ptr; + + return old_p; +} +EXPORT_SYMBOL(idr_replace); + static void idr_cache_ctor(void * idr_layer, kmem_cache_t *idr_layer_cache, unsigned long flags) { diff --git a/lib/spinlock_debug.c b/lib/spinlock_debug.c index 34022dd9a..8ebd8ea08 100644 --- a/lib/spinlock_debug.c +++ b/lib/spinlock_debug.c @@ -150,6 +150,7 @@ static void rwlock_bug(rwlock_t *lock, const char *msg) #define RWLOCK_BUG_ON(cond, lock, msg) if (unlikely(cond)) rwlock_bug(lock, msg) +#if 0 /* __write_lock_debug() can lock up - maybe this can too? */ static void __read_lock_debug(rwlock_t *lock) { int print_once = 1; @@ -171,12 +172,12 @@ static void __read_lock_debug(rwlock_t *lock) } } } +#endif void _raw_read_lock(rwlock_t *lock) { RWLOCK_BUG_ON(lock->magic != RWLOCK_MAGIC, lock, "bad magic"); - if (unlikely(!__raw_read_trylock(&lock->raw_lock))) - __read_lock_debug(lock); + __raw_read_lock(&lock->raw_lock); } int _raw_read_trylock(rwlock_t *lock) @@ -222,6 +223,7 @@ static inline void debug_write_unlock(rwlock_t *lock) lock->owner_cpu = -1; } +#if 0 /* This can cause lockups */ static void __write_lock_debug(rwlock_t *lock) { int print_once = 1; @@ -243,12 +245,12 @@ static void __write_lock_debug(rwlock_t *lock) } } } +#endif void _raw_write_lock(rwlock_t *lock) { debug_write_lock_before(lock); - if (unlikely(!__raw_write_trylock(&lock->raw_lock))) - __write_lock_debug(lock); + __raw_write_lock(&lock->raw_lock); debug_write_lock_after(lock); } diff --git a/lib/ts_bm.c b/lib/ts_bm.c index c4c1ac5fb..791726579 100644 --- a/lib/ts_bm.c +++ b/lib/ts_bm.c @@ -112,15 +112,14 @@ static int subpattern(u8 *pattern, int i, int j, int g) return ret; } -static void compute_prefix_tbl(struct ts_bm *bm, const u8 *pattern, - unsigned int len) +static void compute_prefix_tbl(struct ts_bm *bm) { int i, j, g; for (i = 0; i < ASIZE; i++) - bm->bad_shift[i] = len; - for (i = 0; i < len - 1; i++) - bm->bad_shift[pattern[i]] = len - 1 - 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; /* Compute the good shift array, used to match reocurrences * of a subpattern */ @@ -151,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/mm/Kconfig b/mm/Kconfig index 67b3f74ca..ab1007556 100644 --- a/mm/Kconfig +++ b/mm/Kconfig @@ -115,7 +115,7 @@ config SPARSEMEM_EXTREME # eventually, we can have this option just 'select SPARSEMEM' config MEMORY_HOTPLUG bool "Allow for memory hot-add" - depends on SPARSEMEM && HOTPLUG && !SOFTWARE_SUSPEND + depends on SPARSEMEM && HOTPLUG && !SOFTWARE_SUSPEND && ARCH_ENABLE_MEMORY_HOTPLUG comment "Memory hotplug is currently incompatible with Software Suspend" depends on SPARSEMEM && HOTPLUG && SOFTWARE_SUSPEND @@ -126,12 +126,16 @@ comment "Memory hotplug is currently incompatible with Software Suspend" # Default to 4 for wider testing, though 8 might be more appropriate. # ARM's adjust_pte (unused if VIPT) depends on mm-wide page_table_lock. # PA-RISC 7xxx's spinlock_t would enlarge struct page from 32 to 44 bytes. +# XEN on x86 architecture uses the mapping field on pagetable pages to store a +# pointer to the destructor. This conflicts with pte_lock_deinit(). # config SPLIT_PTLOCK_CPUS int default "4096" if ARM && !CPU_CACHE_VIPT default "4096" if PARISC && !PA20 - default "4096" + default "4096" if X86_XEN || X86_64_XEN + default "4096" if !64BIT + default "4" # # support for page migration diff --git a/mm/filemap.c b/mm/filemap.c index 4b0449581..96f354e18 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -518,18 +518,11 @@ EXPORT_SYMBOL(unlock_page); */ void end_page_writeback(struct page *page) { - struct zone *zone = page_zone(page); if (!TestClearPageReclaim(page) || rotate_reclaimable_page(page)) { if (!test_clear_page_writeback(page)) BUG(); } smp_mb__after_clear_bit(); - if (zone->all_unreclaimable) { - spin_lock(&zone->lock); - zone->all_unreclaimable = 0; - zone->pages_scanned = 0; - spin_unlock(&zone->lock); - } wake_up_page(page, PG_writeback); } EXPORT_SYMBOL(end_page_writeback); @@ -2022,14 +2015,21 @@ generic_file_buffered_write(struct kiocb *iocb, const struct iovec *iov, do { unsigned long index; unsigned long offset; - unsigned long maxlen; size_t copied; offset = (pos & (PAGE_CACHE_SIZE -1)); /* Within page */ index = pos >> PAGE_CACHE_SHIFT; bytes = PAGE_CACHE_SIZE - offset; - if (bytes > count) - bytes = count; + + /* Limit the size of the copy to the caller's write size */ + bytes = min(bytes, count); + + /* + * Limit the size of the copy to that of the current segment, + * because fault_in_pages_readable() doesn't know how to walk + * segments. + */ + bytes = min(bytes, cur_iov->iov_len - iov_base); /* * Bring in the user page that we will copy from _first_. @@ -2037,10 +2037,7 @@ generic_file_buffered_write(struct kiocb *iocb, const struct iovec *iov, * same page as we're writing to, without it being marked * up-to-date. */ - maxlen = cur_iov->iov_len - iov_base; - if (maxlen > bytes) - maxlen = bytes; - fault_in_pages_readable(buf, maxlen); + fault_in_pages_readable(buf, bytes); page = __grab_cache_page(mapping,index,&cached_page,&lru_pvec); if (!page) { @@ -2048,6 +2045,12 @@ generic_file_buffered_write(struct kiocb *iocb, const struct iovec *iov, break; } + if (unlikely(bytes == 0)) { + status = 0; + copied = 0; + goto zero_length_segment; + } + status = a_ops->prepare_write(file, page, offset, offset+bytes); if (unlikely(status)) { loff_t isize = i_size_read(inode); @@ -2077,7 +2080,8 @@ generic_file_buffered_write(struct kiocb *iocb, const struct iovec *iov, page_cache_release(page); continue; } - if (likely(copied > 0)) { +zero_length_segment: + if (likely(copied >= 0)) { if (!status) status = copied; diff --git a/mm/filemap.h b/mm/filemap.h index 13793ba0c..efd01426b 100644 --- a/mm/filemap.h +++ b/mm/filemap.h @@ -78,7 +78,7 @@ filemap_set_next_iovec(const struct iovec **iovp, size_t *basep, size_t bytes) const struct iovec *iov = *iovp; size_t base = *basep; - while (bytes) { + do { int copy = min(bytes, iov->iov_len - base); bytes -= copy; @@ -87,7 +87,7 @@ filemap_set_next_iovec(const struct iovec **iovp, size_t *basep, size_t bytes) iov++; base = 0; } - } + } while (bytes); *iovp = iov; *basep = base; } diff --git a/mm/highmem.c b/mm/highmem.c index 9b274fdf9..a02c6dec9 100644 --- a/mm/highmem.c +++ b/mm/highmem.c @@ -142,6 +142,17 @@ start: return vaddr; } +#ifdef CONFIG_XEN +void kmap_flush_unused(void) +{ + spin_lock(&kmap_lock); + flush_all_zero_pkmaps(); + spin_unlock(&kmap_lock); +} + +EXPORT_SYMBOL(kmap_flush_unused); +#endif + void fastcall *kmap_high(struct page *page) { unsigned long vaddr; diff --git a/mm/memory.c b/mm/memory.c index 1bd040470..9f75bb2ca 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -402,7 +402,8 @@ struct page *vm_normal_page(struct vm_area_struct *vma, unsigned long addr, pte_ * and that the resulting page looks ok. */ if (unlikely(!pfn_valid(pfn))) { - print_bad_pte(vma, pte, addr); + if (!(vma->vm_flags & VM_RESERVED)) + print_bad_pte(vma, pte, addr); return NULL; } @@ -1017,6 +1018,26 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, continue; } +#ifdef CONFIG_XEN + if (vma && (vma->vm_flags & VM_FOREIGN)) { + struct page **map = vma->vm_private_data; + int offset = (start - vma->vm_start) >> PAGE_SHIFT; + if (map[offset] != NULL) { + if (pages) { + struct page *page = map[offset]; + + pages[i] = page; + get_page(page); + } + if (vmas) + vmas[i] = vma; + i++; + start += PAGE_SIZE; + len--; + continue; + } + } +#endif if (!vma || (vma->vm_flags & (VM_IO | VM_PFNMAP)) || !(vm_flags & vma->vm_flags)) return i ? : -EFAULT; @@ -1356,6 +1377,102 @@ int remap_pfn_range(struct vm_area_struct *vma, unsigned long addr, } EXPORT_SYMBOL(remap_pfn_range); +#ifdef CONFIG_XEN +static inline int apply_to_pte_range(struct mm_struct *mm, pmd_t *pmd, + unsigned long addr, unsigned long end, + pte_fn_t fn, void *data) +{ + pte_t *pte; + int err; + struct page *pmd_page; + spinlock_t *ptl; + + pte = (mm == &init_mm) ? + pte_alloc_kernel(pmd, addr) : + pte_alloc_map_lock(mm, pmd, addr, &ptl); + if (!pte) + return -ENOMEM; + + BUG_ON(pmd_huge(*pmd)); + + pmd_page = pmd_page(*pmd); + + do { + err = fn(pte, pmd_page, addr, data); + if (err) + break; + } while (pte++, addr += PAGE_SIZE, addr != end); + + if (mm != &init_mm) + pte_unmap_unlock(pte-1, ptl); + return err; +} + +static inline int apply_to_pmd_range(struct mm_struct *mm, pud_t *pud, + unsigned long addr, unsigned long end, + pte_fn_t fn, void *data) +{ + pmd_t *pmd; + unsigned long next; + int err; + + pmd = pmd_alloc(mm, pud, addr); + if (!pmd) + return -ENOMEM; + do { + next = pmd_addr_end(addr, end); + err = apply_to_pte_range(mm, pmd, addr, next, fn, data); + if (err) + break; + } while (pmd++, addr = next, addr != end); + return err; +} + +static inline int apply_to_pud_range(struct mm_struct *mm, pgd_t *pgd, + unsigned long addr, unsigned long end, + pte_fn_t fn, void *data) +{ + pud_t *pud; + unsigned long next; + int err; + + pud = pud_alloc(mm, pgd, addr); + if (!pud) + return -ENOMEM; + do { + next = pud_addr_end(addr, end); + err = apply_to_pmd_range(mm, pud, addr, next, fn, data); + if (err) + break; + } while (pud++, addr = next, addr != end); + return err; +} + +/* + * Scan a region of virtual memory, filling in page tables as necessary + * and calling a provided function on each leaf page table. + */ +int apply_to_page_range(struct mm_struct *mm, unsigned long addr, + unsigned long size, pte_fn_t fn, void *data) +{ + pgd_t *pgd; + unsigned long next; + unsigned long end = addr + size; + int err; + + BUG_ON(addr >= end); + pgd = pgd_offset(mm, addr); + do { + next = pgd_addr_end(addr, end); + err = apply_to_pud_range(mm, pgd, addr, next, fn, data); + if (err) + break; + } while (pgd++, addr = next, addr != end); + return err; +} +EXPORT_SYMBOL_GPL(apply_to_page_range); +#endif + /* * handle_pte_fault chooses page fault handler according to an entry * which was read non-atomically. Before making any commitment, on diff --git a/mm/mmap.c b/mm/mmap.c index c34750cf9..f6940d1b3 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -920,6 +920,10 @@ unsigned long do_mmap_pgoff(struct file * file, unsigned long addr, if (!len) return -EINVAL; + error = arch_mmap_check(addr, len, flags); + if (error) + return error; + /* Careful about overflows.. */ len = PAGE_ALIGN(len); if (!len || len > TASK_SIZE) @@ -1940,6 +1944,7 @@ unsigned long do_brk(unsigned long addr, unsigned long len) unsigned long flags; struct rb_node ** rb_link, * rb_parent; pgoff_t pgoff = addr >> PAGE_SHIFT; + int error; len = PAGE_ALIGN(len); if (!len) @@ -1948,6 +1953,12 @@ unsigned long do_brk(unsigned long addr, unsigned long len) if ((addr + len) > TASK_SIZE || (addr + len) < addr) return -EINVAL; + flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags; + + error = arch_mmap_check(addr, len, flags); + if (error) + return error; + /* * mlock MCL_FUTURE? */ @@ -1991,8 +2002,6 @@ unsigned long do_brk(unsigned long addr, unsigned long len) !vx_vmpages_avail(mm, len >> PAGE_SHIFT)) return -ENOMEM; - flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags; - /* Can we just expand an old private anonymous mapping? */ if (vma_merge(mm, prev, addr, addr + len, flags, NULL, NULL, pgoff, NULL)) @@ -2033,6 +2042,10 @@ void exit_mmap(struct mm_struct *mm) unsigned long nr_accounted = 0; unsigned long end; +#ifdef arch_exit_mmap + arch_exit_mmap(mm); +#endif + lru_add_drain(); flush_cache_mm(mm); tlb = tlb_gather_mmu(mm, 1); diff --git a/mm/page_alloc.c b/mm/page_alloc.c index b747cbf8b..5581dd1a4 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -439,7 +439,8 @@ static void __free_pages_ok(struct page *page, unsigned int order) int i; int reserved = 0; - arch_free_page(page, order); + if (arch_free_page(page, order)) + return; if (!PageHighMem(page)) mutex_debug_check_no_locks_freed(page_address(page), PAGE_SIZE<mapping = NULL; @@ -751,11 +753,6 @@ static void fastcall free_hot_cold_page(struct page *page, int cold) if (pcp->count >= pcp->high) { free_pages_bulk(zone, pcp->batch, &pcp->list, 0); pcp->count -= pcp->batch; - } else if (zone->all_unreclaimable) { - spin_lock(&zone->lock); - zone->all_unreclaimable = 0; - zone->pages_scanned = 0; - spin_unlock(&zone->lock); } local_irq_restore(flags); put_cpu(); diff --git a/mm/pdflush.c b/mm/pdflush.c index c4b6d0afd..4842716d1 100644 --- a/mm/pdflush.c +++ b/mm/pdflush.c @@ -104,21 +104,20 @@ static int __pdflush(struct pdflush_work *my_work) list_move(&my_work->list, &pdflush_list); my_work->when_i_went_to_sleep = jiffies; spin_unlock_irq(&pdflush_lock); - schedule(); - if (try_to_freeze()) { - spin_lock_irq(&pdflush_lock); - continue; - } - + try_to_freeze(); spin_lock_irq(&pdflush_lock); if (!list_empty(&my_work->list)) { - printk("pdflush: bogus wakeup!\n"); + /* + * Someone woke us up, but without removing our control + * structure from the global list. swsusp will do this + * in try_to_freeze()->refrigerator(). Handle it. + */ my_work->fn = NULL; continue; } if (my_work->fn == NULL) { - printk("pdflush: NULL work function\n"); + printk("pdflush: bogus wakeup\n"); continue; } spin_unlock_irq(&pdflush_lock); diff --git a/mm/swapfile.c b/mm/swapfile.c index 234b2f173..a3bed3ff3 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c @@ -441,11 +441,12 @@ 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->swap_file->f_dentry->d_inode; + inode = swap_info[i].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/net/8021q/vlan.c b/net/8021q/vlan.c index 3948949a6..729abc439 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c @@ -67,10 +67,6 @@ static struct packet_type vlan_packet_type = { .func = vlan_skb_recv, /* VLAN receive method */ }; -/* Bits of netdev state that are propagated from real device to virtual */ -#define VLAN_LINK_STATE_MASK \ - ((1<<__LINK_STATE_PRESENT)|(1<<__LINK_STATE_NOCARRIER)|(1<<__LINK_STATE_DORMANT)) - /* End of global variables definitions. */ /* @@ -470,7 +466,9 @@ static struct net_device *register_vlan_device(const char *eth_IF_name, new_dev->flags = real_dev->flags; new_dev->flags &= ~IFF_UP; - new_dev->state = real_dev->state & ~(1<<__LINK_STATE_START); + new_dev->state = (real_dev->state & ((1<<__LINK_STATE_NOCARRIER) | + (1<<__LINK_STATE_DORMANT))) | + (1<<__LINK_STATE_PRESENT); /* need 4 bytes for extra VLAN header info, * hope the underlying device can handle it. diff --git a/net/atm/clip.c b/net/atm/clip.c index 72d852982..4f44e98f1 100644 --- a/net/atm/clip.c +++ b/net/atm/clip.c @@ -98,7 +98,7 @@ static void unlink_clip_vcc(struct clip_vcc *clip_vcc) printk(KERN_CRIT "!clip_vcc->entry (clip_vcc %p)\n", clip_vcc); return; } - spin_lock_bh(&entry->neigh->dev->xmit_lock); /* block clip_start_xmit() */ + netif_tx_lock_bh(entry->neigh->dev); /* block clip_start_xmit() */ entry->neigh->used = jiffies; for (walk = &entry->vccs; *walk; walk = &(*walk)->next) if (*walk == clip_vcc) { @@ -120,9 +120,9 @@ static void unlink_clip_vcc(struct clip_vcc *clip_vcc) goto out; } printk(KERN_CRIT "ATMARP: unlink_clip_vcc failed (entry %p, vcc " - "0x%p)\n", entry, clip_vcc); - out: - spin_unlock_bh(&entry->neigh->dev->xmit_lock); + "0x%p)\n",entry,clip_vcc); +out: + netif_tx_unlock_bh(entry->neigh->dev); } /* The neighbour entry n->lock is held. */ diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c index 0c88a2ac3..f8dbcee80 100644 --- a/net/bridge/br_device.c +++ b/net/bridge/br_device.c @@ -145,9 +145,9 @@ static int br_set_tx_csum(struct net_device *dev, u32 data) struct net_bridge *br = netdev_priv(dev); if (data) - br->feature_mask |= NETIF_F_IP_CSUM; + br->feature_mask |= NETIF_F_NO_CSUM; else - br->feature_mask &= ~NETIF_F_IP_CSUM; + br->feature_mask &= ~NETIF_F_ALL_CSUM; br_features_recompute(br); return 0; @@ -184,6 +184,6 @@ void br_dev_setup(struct net_device *dev) dev->set_mac_address = br_set_mac_address; dev->priv_flags = IFF_EBRIDGE; - dev->features = NETIF_F_SG | NETIF_F_FRAGLIST - | NETIF_F_HIGHDMA | NETIF_F_TSO | NETIF_F_IP_CSUM; + dev->features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA | + NETIF_F_TSO | NETIF_F_NO_CSUM | NETIF_F_GSO_ROBUST; } diff --git a/net/bridge/br_forward.c b/net/bridge/br_forward.c index 56f3aa47e..056df7ceb 100644 --- a/net/bridge/br_forward.c +++ b/net/bridge/br_forward.c @@ -38,16 +38,20 @@ static inline unsigned packet_length(const struct sk_buff *skb) int br_dev_queue_push_xmit(struct sk_buff *skb) { /* drop mtu oversized packets except tso */ - if (packet_length(skb) > skb->dev->mtu && !skb_shinfo(skb)->tso_size) + if (skb->len > skb->dev->mtu && !skb_is_gso(skb)) kfree_skb(skb); else { #ifdef CONFIG_BRIDGE_NETFILTER /* ip_refrag calls ip_fragment, doesn't copy the MAC header. */ - nf_bridge_maybe_copy_header(skb); + if (nf_bridge_maybe_copy_header(skb)) + kfree_skb(skb); + else #endif - skb_push(skb, ETH_HLEN); + { + skb_push(skb, ETH_HLEN); - dev_queue_xmit(skb); + dev_queue_xmit(skb); + } } return 0; diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index f5d47bf4f..f55ef682e 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c @@ -372,17 +372,28 @@ void br_features_recompute(struct net_bridge *br) struct net_bridge_port *p; unsigned long features, checksum; - features = br->feature_mask &~ NETIF_F_IP_CSUM; - checksum = br->feature_mask & NETIF_F_IP_CSUM; + checksum = br->feature_mask & NETIF_F_ALL_CSUM ? NETIF_F_NO_CSUM : 0; + features = br->feature_mask & ~NETIF_F_ALL_CSUM; list_for_each_entry(p, &br->port_list, list) { - if (!(p->dev->features - & (NETIF_F_IP_CSUM|NETIF_F_NO_CSUM|NETIF_F_HW_CSUM))) + unsigned long feature = p->dev->features; + + if (checksum & NETIF_F_NO_CSUM && !(feature & NETIF_F_NO_CSUM)) + checksum ^= NETIF_F_NO_CSUM | NETIF_F_HW_CSUM; + if (checksum & NETIF_F_HW_CSUM && !(feature & NETIF_F_HW_CSUM)) + checksum ^= NETIF_F_HW_CSUM | NETIF_F_IP_CSUM; + if (!(feature & NETIF_F_IP_CSUM)) checksum = 0; - features &= p->dev->features; + + if (feature & NETIF_F_GSO) + feature |= NETIF_F_TSO; + feature |= NETIF_F_GSO; + + features &= feature; } - br->dev->features = features | checksum | NETIF_F_LLTX; + br->dev->features = features | checksum | NETIF_F_LLTX | + NETIF_F_GSO_ROBUST; } /* called with RTNL */ diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c index 3da926444..a64272783 100644 --- a/net/bridge/br_netfilter.c +++ b/net/bridge/br_netfilter.c @@ -769,7 +769,7 @@ static int br_nf_dev_queue_xmit(struct sk_buff *skb) { if (skb->protocol == htons(ETH_P_IP) && skb->len > skb->dev->mtu && - !(skb_shinfo(skb)->ufo_size || skb_shinfo(skb)->tso_size)) + !skb_is_gso(skb)) return ip_fragment(skb, br_dev_queue_push_xmit); else return br_dev_queue_push_xmit(skb); @@ -877,8 +877,9 @@ static unsigned int ip_sabotage_out(unsigned int hook, struct sk_buff **pskb, struct sk_buff *skb = *pskb; if ((out->hard_start_xmit == br_dev_xmit && - okfn != br_nf_forward_finish && - okfn != br_nf_local_out_finish && okfn != br_nf_dev_queue_xmit) + okfn != br_nf_forward_finish && + okfn != br_nf_local_out_finish && + okfn != br_nf_dev_queue_xmit) #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) || ((out->priv_flags & IFF_802_1Q_VLAN) && VLAN_DEV_INFO(out)->real_dev->hard_start_xmit == br_dev_xmit) diff --git a/net/bridge/netfilter/ebt_ulog.c b/net/bridge/netfilter/ebt_ulog.c index ee5a51761..ae70123c6 100644 --- a/net/bridge/netfilter/ebt_ulog.c +++ b/net/bridge/netfilter/ebt_ulog.c @@ -75,6 +75,9 @@ static void ulog_send(unsigned int nlgroup) if (timer_pending(&ub->timer)) del_timer(&ub->timer); + if (!ub->skb) + return; + /* last nlmsg needs NLMSG_DONE */ if (ub->qlen > 1) ub->lastnlh->nlmsg_type = NLMSG_DONE; diff --git a/net/core/dev.c b/net/core/dev.c index eb965a773..d8bab16e9 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -115,8 +115,15 @@ #include #include #include +#include #include +#ifdef CONFIG_XEN +#include +#include +#include +#endif + /* * The list of packet types we will receive (as opposed to discard) * and the routines to invoke. @@ -1042,7 +1049,7 @@ static inline void net_timestamp(struct sk_buff *skb) * taps currently in use. */ -void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev) +static void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev) { struct packet_type *ptype; @@ -1180,6 +1187,45 @@ out: return ret; } +/** + * skb_gso_segment - Perform segmentation on skb. + * @skb: buffer to segment + * @features: features for the output path (see dev->features) + * + * This function segments the given skb and returns a list of segments. + * + * It may return NULL if the skb requires no segmentation. This is + * only possible when GSO is used for verifying header integrity. + */ +struct sk_buff *skb_gso_segment(struct sk_buff *skb, int features) +{ + struct sk_buff *segs = ERR_PTR(-EPROTONOSUPPORT); + struct packet_type *ptype; + int type = skb->protocol; + + BUG_ON(skb_shinfo(skb)->frag_list); + BUG_ON(skb->ip_summed != CHECKSUM_HW); + + skb->mac.raw = skb->data; + skb->mac_len = skb->nh.raw - skb->data; + __skb_pull(skb, skb->mac_len); + + rcu_read_lock(); + list_for_each_entry_rcu(ptype, &ptype_base[ntohs(type) & 15], list) { + if (ptype->type == type && !ptype->dev && ptype->gso_segment) { + segs = ptype->gso_segment(skb, features); + break; + } + } + rcu_read_unlock(); + + __skb_push(skb, skb->data - skb->mac.raw); + + return segs; +} + +EXPORT_SYMBOL(skb_gso_segment); + /* Take action when hardware reception checksum errors are detected. */ #ifdef CONFIG_BUG void netdev_rx_csum_fault(struct net_device *dev) @@ -1216,78 +1262,148 @@ static inline int illegal_highdma(struct net_device *dev, struct sk_buff *skb) #define illegal_highdma(dev, skb) (0) #endif -/* Keep head the same: replace data */ -int __skb_linearize(struct sk_buff *skb, gfp_t gfp_mask) -{ - unsigned int size; - u8 *data; - long offset; - struct skb_shared_info *ninfo; - int headerlen = skb->data - skb->head; - int expand = (skb->tail + skb->data_len) - skb->end; - - if (skb_shared(skb)) - BUG(); - - if (expand <= 0) - expand = 0; - - size = skb->end - skb->head + expand; - size = SKB_DATA_ALIGN(size); - data = kmalloc(size + sizeof(struct skb_shared_info), gfp_mask); - if (!data) - return -ENOMEM; - - /* Copy entire thing */ - if (skb_copy_bits(skb, -headerlen, data, headerlen + skb->len)) - BUG(); - - /* Set up shinfo */ - ninfo = (struct skb_shared_info*)(data + size); - atomic_set(&ninfo->dataref, 1); - ninfo->tso_size = skb_shinfo(skb)->tso_size; - ninfo->tso_segs = skb_shinfo(skb)->tso_segs; - ninfo->nr_frags = 0; - ninfo->frag_list = NULL; - - /* Offset between the two in bytes */ - offset = data - skb->head; - - /* Free old data. */ - skb_release_data(skb); - - skb->head = data; - skb->end = data + size; - - /* Set up new pointers */ - skb->h.raw += offset; - skb->nh.raw += offset; - skb->mac.raw += offset; - skb->tail += offset; - skb->data += offset; - - /* We are no longer a clone, even if we were. */ - skb->cloned = 0; - - skb->tail += skb->data_len; - skb->data_len = 0; +struct dev_gso_cb { + void (*destructor)(struct sk_buff *skb); +}; + +#define DEV_GSO_CB(skb) ((struct dev_gso_cb *)(skb)->cb) + +static void dev_gso_skb_destructor(struct sk_buff *skb) +{ + struct dev_gso_cb *cb; + + do { + struct sk_buff *nskb = skb->next; + + skb->next = nskb->next; + nskb->next = NULL; + kfree_skb(nskb); + } while (skb->next); + + cb = DEV_GSO_CB(skb); + if (cb->destructor) + cb->destructor(skb); +} + +/** + * dev_gso_segment - Perform emulated hardware segmentation on skb. + * @skb: buffer to segment + * + * This function segments the given skb and stores the list of segments + * in skb->next. + */ +static int dev_gso_segment(struct sk_buff *skb) +{ + struct net_device *dev = skb->dev; + struct sk_buff *segs; + int features = dev->features & ~(illegal_highdma(dev, skb) ? + NETIF_F_SG : 0); + + segs = skb_gso_segment(skb, features); + + /* Verifying header integrity only. */ + if (!segs) + return 0; + + if (unlikely(IS_ERR(segs))) + return PTR_ERR(segs); + + skb->next = segs; + DEV_GSO_CB(skb)->destructor = skb->destructor; + skb->destructor = dev_gso_skb_destructor; + + return 0; +} + +int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) +{ + if (likely(!skb->next)) { + if (netdev_nit) + dev_queue_xmit_nit(skb, dev); + + if (netif_needs_gso(dev, skb)) { + if (unlikely(dev_gso_segment(skb))) + goto out_kfree_skb; + if (skb->next) + goto gso; + } + + return dev->hard_start_xmit(skb, dev); + } + +gso: + do { + struct sk_buff *nskb = skb->next; + int rc; + + skb->next = nskb->next; + nskb->next = NULL; + rc = dev->hard_start_xmit(nskb, dev); + if (unlikely(rc)) { + nskb->next = skb->next; + skb->next = nskb; + return rc; + } + if (unlikely(netif_queue_stopped(dev) && skb->next)) + return NETDEV_TX_BUSY; + } while (skb->next); + + skb->destructor = DEV_GSO_CB(skb)->destructor; + +out_kfree_skb: + kfree_skb(skb); return 0; } #define HARD_TX_LOCK(dev, cpu) { \ if ((dev->features & NETIF_F_LLTX) == 0) { \ - spin_lock(&dev->xmit_lock); \ - dev->xmit_lock_owner = cpu; \ + netif_tx_lock(dev); \ } \ } #define HARD_TX_UNLOCK(dev) { \ if ((dev->features & NETIF_F_LLTX) == 0) { \ - dev->xmit_lock_owner = -1; \ - spin_unlock(&dev->xmit_lock); \ + netif_tx_unlock(dev); \ } \ } +#ifdef CONFIG_XEN +inline int skb_checksum_setup(struct sk_buff *skb) +{ + if (skb->proto_csum_blank) { + if (skb->protocol != htons(ETH_P_IP)) + goto out; + skb->h.raw = (unsigned char *)skb->nh.iph + 4*skb->nh.iph->ihl; + if (skb->h.raw >= skb->tail) + goto out; + switch (skb->nh.iph->protocol) { + case IPPROTO_TCP: + skb->csum = offsetof(struct tcphdr, check); + break; + case IPPROTO_UDP: + skb->csum = offsetof(struct udphdr, check); + break; + default: + if (net_ratelimit()) + printk(KERN_ERR "Attempting to checksum a non-" + "TCP/UDP packet, dropping a protocol" + " %d packet", skb->nh.iph->protocol); + goto out; + } + if ((skb->h.raw + skb->csum + 2) > skb->tail) + goto out; + skb->ip_summed = CHECKSUM_HW; + skb->proto_csum_blank = 0; + } + return 0; +out: + return -EPROTO; +} +#else +inline int skb_checksum_setup(struct sk_buff *skb) { return 0; } +#endif + + /** * dev_queue_xmit - transmit a buffer * @skb: buffer to transmit @@ -1320,9 +1436,19 @@ int dev_queue_xmit(struct sk_buff *skb) struct Qdisc *q; int rc = -ENOMEM; + /* If a checksum-deferred packet is forwarded to a device that needs a + * checksum, correct the pointers and force checksumming. + */ + if (skb_checksum_setup(skb)) + goto out_kfree_skb; + + /* GSO will handle the following emulations directly. */ + if (netif_needs_gso(dev, skb)) + goto gso; + if (skb_shinfo(skb)->frag_list && !(dev->features & NETIF_F_FRAGLIST) && - __skb_linearize(skb, GFP_ATOMIC)) + __skb_linearize(skb)) goto out_kfree_skb; /* Fragmented skb is linearized if device does not support SG, @@ -1331,25 +1457,26 @@ int dev_queue_xmit(struct sk_buff *skb) */ if (skb_shinfo(skb)->nr_frags && (!(dev->features & NETIF_F_SG) || illegal_highdma(dev, skb)) && - __skb_linearize(skb, GFP_ATOMIC)) + __skb_linearize(skb)) goto out_kfree_skb; /* If packet is not checksummed and device does not support * checksumming for this protocol, complete checksumming here. */ if (skb->ip_summed == CHECKSUM_HW && - (!(dev->features & (NETIF_F_HW_CSUM | NETIF_F_NO_CSUM)) && + (!(dev->features & NETIF_F_GEN_CSUM) && (!(dev->features & NETIF_F_IP_CSUM) || skb->protocol != htons(ETH_P_IP)))) if (skb_checksum_help(skb, 0)) goto out_kfree_skb; +gso: spin_lock_prefetch(&dev->queue_lock); /* Disable soft irqs for various locks below. Also * stops preemption for RCU. */ - local_bh_disable(); + rcu_read_lock_bh(); /* Updates of qdisc are serialized by queue_lock. * The struct Qdisc which is pointed to by qdisc is now a @@ -1383,8 +1510,8 @@ int dev_queue_xmit(struct sk_buff *skb) /* The device has no queue. Common case for software devices: loopback, all the sorts of tunnels... - Really, it is unlikely that xmit_lock protection is necessary here. - (f.e. loopback and IP tunnels are clean ignoring statistics + Really, it is unlikely that netif_tx_lock protection is necessary + here. (f.e. loopback and IP tunnels are clean ignoring statistics counters.) However, it is possible, that they rely on protection made by us here. @@ -1400,11 +1527,8 @@ int dev_queue_xmit(struct sk_buff *skb) HARD_TX_LOCK(dev, cpu); if (!netif_queue_stopped(dev)) { - if (netdev_nit) - dev_queue_xmit_nit(skb, dev); - rc = 0; - if (!dev->hard_start_xmit(skb, dev)) { + if (!dev_hard_start_xmit(skb, dev)) { HARD_TX_UNLOCK(dev); goto out; } @@ -1423,13 +1547,13 @@ int dev_queue_xmit(struct sk_buff *skb) } rc = -ENETDOWN; - local_bh_enable(); + rcu_read_unlock_bh(); out_kfree_skb: kfree_skb(skb); return rc; out: - local_bh_enable(); + rcu_read_unlock_bh(); return rc; } @@ -1707,6 +1831,19 @@ int netif_receive_skb(struct sk_buff *skb) } #endif +#ifdef CONFIG_XEN + switch (skb->ip_summed) { + case CHECKSUM_UNNECESSARY: + skb->proto_data_valid = 1; + break; + case CHECKSUM_HW: + /* XXX Implement me. */ + default: + skb->proto_data_valid = 0; + break; + } +#endif + list_for_each_entry_rcu(ptype, &ptype_all, list) { if (!ptype->dev || ptype->dev == skb->dev) { if (pt_prev) @@ -2793,7 +2930,7 @@ int register_netdevice(struct net_device *dev) BUG_ON(dev->reg_state != NETREG_UNINITIALIZED); spin_lock_init(&dev->queue_lock); - spin_lock_init(&dev->xmit_lock); + spin_lock_init(&dev->_xmit_lock); dev->xmit_lock_owner = -1; #ifdef CONFIG_NET_CLS_ACT spin_lock_init(&dev->ingress_lock); @@ -2837,9 +2974,7 @@ int register_netdevice(struct net_device *dev) /* Fix illegal SG+CSUM combinations. */ if ((dev->features & NETIF_F_SG) && - !(dev->features & (NETIF_F_IP_CSUM | - NETIF_F_NO_CSUM | - NETIF_F_HW_CSUM))) { + !(dev->features & NETIF_F_ALL_CSUM)) { printk("%s: Dropping NETIF_F_SG since no checksum feature.\n", dev->name); dev->features &= ~NETIF_F_SG; @@ -3379,7 +3514,6 @@ subsys_initcall(net_dev_init); EXPORT_SYMBOL(__dev_get_by_index); EXPORT_SYMBOL(__dev_get_by_name); EXPORT_SYMBOL(__dev_remove_pack); -EXPORT_SYMBOL(__skb_linearize); EXPORT_SYMBOL(dev_valid_name); EXPORT_SYMBOL(dev_add_pack); EXPORT_SYMBOL(dev_alloc_name); @@ -3411,6 +3545,7 @@ EXPORT_SYMBOL(unregister_netdevice_notifier); EXPORT_SYMBOL(net_enable_timestamp); EXPORT_SYMBOL(net_disable_timestamp); EXPORT_SYMBOL(dev_get_flags); +EXPORT_SYMBOL(skb_checksum_setup); #if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) EXPORT_SYMBOL(br_handle_frame_hook); diff --git a/net/core/dev_mcast.c b/net/core/dev_mcast.c index 05d608508..c57d887da 100644 --- a/net/core/dev_mcast.c +++ b/net/core/dev_mcast.c @@ -62,7 +62,7 @@ * Device mc lists are changed by bh at least if IPv6 is enabled, * so that it must be bh protected. * - * We block accesses to device mc filters with dev->xmit_lock. + * We block accesses to device mc filters with netif_tx_lock. */ /* @@ -93,9 +93,9 @@ static void __dev_mc_upload(struct net_device *dev) void dev_mc_upload(struct net_device *dev) { - spin_lock_bh(&dev->xmit_lock); + netif_tx_lock_bh(dev); __dev_mc_upload(dev); - spin_unlock_bh(&dev->xmit_lock); + netif_tx_unlock_bh(dev); } /* @@ -107,7 +107,7 @@ int dev_mc_delete(struct net_device *dev, void *addr, int alen, int glbl) int err = 0; struct dev_mc_list *dmi, **dmip; - spin_lock_bh(&dev->xmit_lock); + netif_tx_lock_bh(dev); for (dmip = &dev->mc_list; (dmi = *dmip) != NULL; dmip = &dmi->next) { /* @@ -139,13 +139,13 @@ int dev_mc_delete(struct net_device *dev, void *addr, int alen, int glbl) */ __dev_mc_upload(dev); - spin_unlock_bh(&dev->xmit_lock); + netif_tx_unlock_bh(dev); return 0; } } err = -ENOENT; done: - spin_unlock_bh(&dev->xmit_lock); + netif_tx_unlock_bh(dev); return err; } @@ -160,7 +160,7 @@ int dev_mc_add(struct net_device *dev, void *addr, int alen, int glbl) dmi1 = kmalloc(sizeof(*dmi), GFP_ATOMIC); - spin_lock_bh(&dev->xmit_lock); + netif_tx_lock_bh(dev); for (dmi = dev->mc_list; dmi != NULL; dmi = dmi->next) { if (memcmp(dmi->dmi_addr, addr, dmi->dmi_addrlen) == 0 && dmi->dmi_addrlen == alen) { @@ -176,7 +176,7 @@ int dev_mc_add(struct net_device *dev, void *addr, int alen, int glbl) } if ((dmi = dmi1) == NULL) { - spin_unlock_bh(&dev->xmit_lock); + netif_tx_unlock_bh(dev); return -ENOMEM; } memcpy(dmi->dmi_addr, addr, alen); @@ -189,11 +189,11 @@ int dev_mc_add(struct net_device *dev, void *addr, int alen, int glbl) __dev_mc_upload(dev); - spin_unlock_bh(&dev->xmit_lock); + netif_tx_unlock_bh(dev); return 0; done: - spin_unlock_bh(&dev->xmit_lock); + netif_tx_unlock_bh(dev); kfree(dmi1); return err; } @@ -204,7 +204,7 @@ done: void dev_mc_discard(struct net_device *dev) { - spin_lock_bh(&dev->xmit_lock); + netif_tx_lock_bh(dev); while (dev->mc_list != NULL) { struct dev_mc_list *tmp = dev->mc_list; @@ -215,7 +215,7 @@ void dev_mc_discard(struct net_device *dev) } dev->mc_count = 0; - spin_unlock_bh(&dev->xmit_lock); + netif_tx_unlock_bh(dev); } #ifdef CONFIG_PROC_FS @@ -250,7 +250,7 @@ static int dev_mc_seq_show(struct seq_file *seq, void *v) struct dev_mc_list *m; struct net_device *dev = v; - spin_lock_bh(&dev->xmit_lock); + netif_tx_lock_bh(dev); for (m = dev->mc_list; m; m = m->next) { int i; @@ -262,7 +262,7 @@ static int dev_mc_seq_show(struct seq_file *seq, void *v) seq_putc(seq, '\n'); } - spin_unlock_bh(&dev->xmit_lock); + netif_tx_unlock_bh(dev); return 0; } diff --git a/net/core/dst.c b/net/core/dst.c index 470c05bc4..1a5e49da0 100644 --- a/net/core/dst.c +++ b/net/core/dst.c @@ -95,12 +95,11 @@ static void dst_run_gc(unsigned long dummy) dst_gc_timer_inc = DST_GC_INC; dst_gc_timer_expires = DST_GC_MIN; } - dst_gc_timer.expires = jiffies + dst_gc_timer_expires; #if RT_CACHE_DEBUG >= 2 printk("dst_total: %d/%d %ld\n", atomic_read(&dst_total), delayed, dst_gc_timer_expires); #endif - add_timer(&dst_gc_timer); + mod_timer(&dst_gc_timer, jiffies + dst_gc_timer_expires); out: spin_unlock(&dst_lock); diff --git a/net/core/ethtool.c b/net/core/ethtool.c index c680b7e04..987cccaa0 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c @@ -30,7 +30,7 @@ u32 ethtool_op_get_link(struct net_device *dev) u32 ethtool_op_get_tx_csum(struct net_device *dev) { - return (dev->features & (NETIF_F_IP_CSUM | NETIF_F_HW_CSUM)) != 0; + return (dev->features & NETIF_F_ALL_CSUM) != 0; } int ethtool_op_set_tx_csum(struct net_device *dev, u32 data) @@ -437,7 +437,7 @@ static int ethtool_set_pauseparam(struct net_device *dev, void __user *useraddr) { struct ethtool_pauseparam pauseparam; - if (!dev->ethtool_ops->get_pauseparam) + if (!dev->ethtool_ops->set_pauseparam) return -EOPNOTSUPP; if (copy_from_user(&pauseparam, useraddr, sizeof(pauseparam))) @@ -551,9 +551,7 @@ static int ethtool_set_sg(struct net_device *dev, char __user *useraddr) return -EFAULT; if (edata.data && - !(dev->features & (NETIF_F_IP_CSUM | - NETIF_F_NO_CSUM | - NETIF_F_HW_CSUM))) + !(dev->features & NETIF_F_ALL_CSUM)) return -EINVAL; return __ethtool_set_sg(dev, edata.data); @@ -561,7 +559,7 @@ static int ethtool_set_sg(struct net_device *dev, char __user *useraddr) static int ethtool_get_tso(struct net_device *dev, char __user *useraddr) { - struct ethtool_value edata = { ETHTOOL_GTSO }; + struct ethtool_value edata = { ETHTOOL_GUFO }; if (!dev->ethtool_ops->get_tso) return -EOPNOTSUPP; @@ -616,6 +614,29 @@ static int ethtool_set_ufo(struct net_device *dev, char __user *useraddr) return dev->ethtool_ops->set_ufo(dev, edata.data); } +static int ethtool_get_gso(struct net_device *dev, char __user *useraddr) +{ + struct ethtool_value edata = { ETHTOOL_GGSO }; + + edata.data = dev->features & NETIF_F_GSO; + if (copy_to_user(useraddr, &edata, sizeof(edata))) + return -EFAULT; + return 0; +} + +static int ethtool_set_gso(struct net_device *dev, char __user *useraddr) +{ + struct ethtool_value edata; + + if (copy_from_user(&edata, useraddr, sizeof(edata))) + return -EFAULT; + if (edata.data) + dev->features |= NETIF_F_GSO; + else + dev->features &= ~NETIF_F_GSO; + return 0; +} + static int ethtool_self_test(struct net_device *dev, char __user *useraddr) { struct ethtool_test test; @@ -907,6 +928,12 @@ int dev_ethtool(struct ifreq *ifr) case ETHTOOL_SUFO: rc = ethtool_set_ufo(dev, useraddr); break; + case ETHTOOL_GGSO: + rc = ethtool_get_gso(dev, useraddr); + break; + case ETHTOOL_SGSO: + rc = ethtool_set_gso(dev, useraddr); + break; default: rc = -EOPNOTSUPP; } diff --git a/net/core/netpoll.c b/net/core/netpoll.c index e8e05cebd..9cb781830 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c @@ -273,24 +273,21 @@ static void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb) do { npinfo->tries--; - spin_lock(&np->dev->xmit_lock); - np->dev->xmit_lock_owner = smp_processor_id(); + netif_tx_lock(np->dev); /* * network drivers do not expect to be called if the queue is * stopped. */ if (netif_queue_stopped(np->dev)) { - np->dev->xmit_lock_owner = -1; - spin_unlock(&np->dev->xmit_lock); + netif_tx_unlock(np->dev); netpoll_poll(np); udelay(50); continue; } status = np->dev->hard_start_xmit(skb, np->dev); - np->dev->xmit_lock_owner = -1; - spin_unlock(&np->dev->xmit_lock); + netif_tx_unlock(np->dev); /* success */ if(!status) { diff --git a/net/core/pktgen.c b/net/core/pktgen.c index c23e9c06e..4e7437a56 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c @@ -2149,6 +2149,8 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev, skb->mac.raw = ((u8 *) iph) - 14 - pkt_dev->nr_labels*sizeof(u32); skb->dev = odev; skb->pkt_type = PACKET_HOST; + skb->nh.iph = iph; + skb->h.uh = udph; if (pkt_dev->nfrags <= 0) pgh = (struct pktgen_hdr *)skb_put(skb, datalen); @@ -2460,6 +2462,8 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev, skb->protocol = protocol; skb->dev = odev; skb->pkt_type = PACKET_HOST; + skb->nh.ipv6h = iph; + skb->h.uh = udph; if (pkt_dev->nfrags <= 0) pgh = (struct pktgen_hdr *)skb_put(skb, datalen); @@ -2896,8 +2900,8 @@ static __inline__ void pktgen_xmit(struct pktgen_dev *pkt_dev) pkt_dev->clone_count = 0; /* reset counter */ } } - - spin_lock_bh(&odev->xmit_lock); + + netif_tx_lock_bh(odev); if (!netif_queue_stopped(odev)) { atomic_inc(&(pkt_dev->skb->users)); @@ -2942,8 +2946,8 @@ static __inline__ void pktgen_xmit(struct pktgen_dev *pkt_dev) pkt_dev->next_tx_ns = 0; } - spin_unlock_bh(&odev->xmit_lock); - + netif_tx_unlock_bh(odev); + /* If pkt_dev->count is zero, then run forever */ if ((pkt_dev->count != 0) && (pkt_dev->sofar >= pkt_dev->count)) { if (atomic_read(&(pkt_dev->skb->users)) != 1) { diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index cfd2d1ef8..375dd9061 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -398,6 +398,9 @@ static int do_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) } if (ida[IFLA_ADDRESS - 1]) { + struct sockaddr *sa; + int len; + if (!dev->set_mac_address) { err = -EOPNOTSUPP; goto out; @@ -409,7 +412,17 @@ static int do_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) if (ida[IFLA_ADDRESS - 1]->rta_len != RTA_LENGTH(dev->addr_len)) goto out; - err = dev->set_mac_address(dev, RTA_DATA(ida[IFLA_ADDRESS - 1])); + len = sizeof(sa_family_t) + dev->addr_len; + sa = kmalloc(len, GFP_KERNEL); + if (!sa) { + err = -ENOMEM; + goto out; + } + sa->sa_family = dev->type; + memcpy(sa->sa_data, RTA_DATA(ida[IFLA_ADDRESS - 1]), + dev->addr_len); + err = dev->set_mac_address(dev, sa); + kfree(sa); if (err) goto out; send_addr_notify = 1; diff --git a/net/core/skbuff.c b/net/core/skbuff.c index fb3770f9c..bd64cb46f 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -140,6 +140,7 @@ EXPORT_SYMBOL(skb_truesize_bug); * Buffers may only be allocated from interrupts using a @gfp_mask of * %GFP_ATOMIC. */ +#ifndef CONFIG_HAVE_ARCH_ALLOC_SKB struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask, int fclone) { @@ -172,9 +173,9 @@ struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask, shinfo = skb_shinfo(skb); atomic_set(&shinfo->dataref, 1); shinfo->nr_frags = 0; - shinfo->tso_size = 0; - shinfo->tso_segs = 0; - shinfo->ufo_size = 0; + shinfo->gso_size = 0; + shinfo->gso_segs = 0; + shinfo->gso_type = 0; shinfo->ip6_frag_id = 0; shinfo->frag_list = NULL; @@ -194,6 +195,7 @@ nodata: skb = NULL; goto out; } +#endif /* !CONFIG_HAVE_ARCH_ALLOC_SKB */ /** * alloc_skb_from_cache - allocate a network buffer @@ -211,14 +213,18 @@ nodata: */ struct sk_buff *alloc_skb_from_cache(kmem_cache_t *cp, unsigned int size, - gfp_t gfp_mask) + gfp_t gfp_mask, + int fclone) { + kmem_cache_t *cache; + struct skb_shared_info *shinfo; struct sk_buff *skb; u8 *data; + cache = fclone ? skbuff_fclone_cache : skbuff_head_cache; + /* Get the HEAD */ - skb = kmem_cache_alloc(skbuff_head_cache, - gfp_mask & ~__GFP_DMA); + skb = kmem_cache_alloc(cache, gfp_mask & ~__GFP_DMA); if (!skb) goto out; @@ -235,26 +241,39 @@ struct sk_buff *alloc_skb_from_cache(kmem_cache_t *cp, skb->data = data; skb->tail = data; skb->end = data + size; + /* make sure we initialize shinfo sequentially */ + shinfo = skb_shinfo(skb); + atomic_set(&shinfo->dataref, 1); + shinfo->nr_frags = 0; + shinfo->gso_size = 0; + shinfo->gso_segs = 0; + shinfo->gso_type = 0; + shinfo->ip6_frag_id = 0; + shinfo->frag_list = NULL; - atomic_set(&(skb_shinfo(skb)->dataref), 1); - skb_shinfo(skb)->nr_frags = 0; - skb_shinfo(skb)->tso_size = 0; - skb_shinfo(skb)->tso_segs = 0; - skb_shinfo(skb)->frag_list = NULL; + if (fclone) { + struct sk_buff *child = skb + 1; + atomic_t *fclone_ref = (atomic_t *) (child + 1); + + skb->fclone = SKB_FCLONE_ORIG; + atomic_set(fclone_ref, 1); + + child->fclone = SKB_FCLONE_UNAVAILABLE; + } out: return skb; nodata: - kmem_cache_free(skbuff_head_cache, skb); + kmem_cache_free(cache, skb); skb = NULL; goto out; } -static void skb_drop_fraglist(struct sk_buff *skb) +static void skb_drop_list(struct sk_buff **listp) { - struct sk_buff *list = skb_shinfo(skb)->frag_list; + struct sk_buff *list = *listp; - skb_shinfo(skb)->frag_list = NULL; + *listp = NULL; do { struct sk_buff *this = list; @@ -263,6 +282,11 @@ static void skb_drop_fraglist(struct sk_buff *skb) } while (list); } +static inline void skb_drop_fraglist(struct sk_buff *skb) +{ + skb_drop_list(&skb_shinfo(skb)->frag_list); +} + static void skb_clone_fraglist(struct sk_buff *skb) { struct sk_buff *list; @@ -434,6 +458,10 @@ struct sk_buff *skb_clone(struct sk_buff *skb, gfp_t gfp_mask) C(local_df); n->cloned = 1; n->nohdr = 0; +#ifdef CONFIG_XEN + C(proto_data_valid); + C(proto_csum_blank); +#endif C(pkt_type); C(ip_summed); C(priority); @@ -527,8 +555,9 @@ static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old) new->tc_index = old->tc_index; #endif atomic_set(&new->users, 1); - skb_shinfo(new)->tso_size = skb_shinfo(old)->tso_size; - skb_shinfo(new)->tso_segs = skb_shinfo(old)->tso_segs; + skb_shinfo(new)->gso_size = skb_shinfo(old)->gso_size; + skb_shinfo(new)->gso_segs = skb_shinfo(old)->gso_segs; + skb_shinfo(new)->gso_type = skb_shinfo(old)->gso_type; } /** @@ -800,49 +829,86 @@ struct sk_buff *skb_pad(struct sk_buff *skb, int pad) return nskb; } -/* Trims skb to length len. It can change skb pointers, if "realloc" is 1. - * If realloc==0 and trimming is impossible without change of data, - * it is BUG(). +/* Trims skb to length len. It can change skb pointers. */ -int ___pskb_trim(struct sk_buff *skb, unsigned int len, int realloc) +int ___pskb_trim(struct sk_buff *skb, unsigned int len) { + struct sk_buff **fragp; + struct sk_buff *frag; int offset = skb_headlen(skb); int nfrags = skb_shinfo(skb)->nr_frags; int i; + int err; - for (i = 0; i < nfrags; i++) { + if (skb_cloned(skb) && + unlikely((err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC)))) + return err; + + i = 0; + if (offset >= len) + goto drop_pages; + + for (; i < nfrags; i++) { int end = offset + skb_shinfo(skb)->frags[i].size; - if (end > len) { - if (skb_cloned(skb)) { - BUG_ON(!realloc); - if (pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) - return -ENOMEM; - } - if (len <= offset) { - put_page(skb_shinfo(skb)->frags[i].page); - skb_shinfo(skb)->nr_frags--; - } else { - skb_shinfo(skb)->frags[i].size = len - offset; - } + + if (end < len) { + offset = end; + continue; } - offset = end; + + skb_shinfo(skb)->frags[i++].size = len - offset; + +drop_pages: + skb_shinfo(skb)->nr_frags = i; + + for (; i < nfrags; i++) + put_page(skb_shinfo(skb)->frags[i].page); + + if (skb_shinfo(skb)->frag_list) + skb_drop_fraglist(skb); + goto done; } - if (offset < len) { + for (fragp = &skb_shinfo(skb)->frag_list; (frag = *fragp); + fragp = &frag->next) { + int end = offset + frag->len; + + if (skb_shared(frag)) { + struct sk_buff *nfrag; + + nfrag = skb_clone(frag, GFP_ATOMIC); + if (unlikely(!nfrag)) + return -ENOMEM; + + nfrag->next = frag->next; + kfree_skb(frag); + frag = nfrag; + *fragp = frag; + } + + if (end < len) { + offset = end; + continue; + } + + if (end > len && + unlikely((err = pskb_trim(frag, len - offset)))) + return err; + + if (frag->next) + skb_drop_list(&frag->next); + break; + } + +done: + if (len > skb_headlen(skb)) { skb->data_len -= skb->len - len; skb->len = len; } else { - if (len <= skb_headlen(skb)) { - skb->len = len; - skb->data_len = 0; - skb->tail = skb->data + len; - if (skb_shinfo(skb)->frag_list && !skb_cloned(skb)) - skb_drop_fraglist(skb); - } else { - skb->data_len -= skb->len - len; - skb->len = len; - } + skb->len = len; + skb->data_len = 0; + skb->tail = skb->data + len; } return 0; @@ -1826,6 +1892,133 @@ unsigned char *skb_pull_rcsum(struct sk_buff *skb, unsigned int len) EXPORT_SYMBOL_GPL(skb_pull_rcsum); +/** + * skb_segment - Perform protocol segmentation on skb. + * @skb: buffer to segment + * @features: features for the output path (see dev->features) + * + * This function performs segmentation on the given skb. It returns + * the segment at the given position. It returns NULL if there are + * no more segments to generate, or when an error is encountered. + */ +struct sk_buff *skb_segment(struct sk_buff *skb, int features) +{ + struct sk_buff *segs = NULL; + struct sk_buff *tail = NULL; + unsigned int mss = skb_shinfo(skb)->gso_size; + unsigned int doffset = skb->data - skb->mac.raw; + unsigned int offset = doffset; + unsigned int headroom; + unsigned int len; + int sg = features & NETIF_F_SG; + int nfrags = skb_shinfo(skb)->nr_frags; + int err = -ENOMEM; + int i = 0; + int pos; + + __skb_push(skb, doffset); + headroom = skb_headroom(skb); + pos = skb_headlen(skb); + + do { + struct sk_buff *nskb; + skb_frag_t *frag; + int hsize, nsize; + int k; + int size; + + len = skb->len - offset; + if (len > mss) + len = mss; + + hsize = skb_headlen(skb) - offset; + if (hsize < 0) + hsize = 0; + nsize = hsize + doffset; + if (nsize > len + doffset || !sg) + nsize = len + doffset; + + nskb = alloc_skb(nsize + headroom, GFP_ATOMIC); + if (unlikely(!nskb)) + goto err; + + if (segs) + tail->next = nskb; + else + segs = nskb; + tail = nskb; + + nskb->dev = skb->dev; + nskb->priority = skb->priority; + nskb->protocol = skb->protocol; + nskb->dst = dst_clone(skb->dst); + memcpy(nskb->cb, skb->cb, sizeof(skb->cb)); + nskb->pkt_type = skb->pkt_type; + nskb->mac_len = skb->mac_len; + + skb_reserve(nskb, headroom); + nskb->mac.raw = nskb->data; + nskb->nh.raw = nskb->data + skb->mac_len; + nskb->h.raw = nskb->nh.raw + (skb->h.raw - skb->nh.raw); + memcpy(skb_put(nskb, doffset), skb->data, doffset); + + if (!sg) { + nskb->csum = skb_copy_and_csum_bits(skb, offset, + skb_put(nskb, len), + len, 0); + continue; + } + + frag = skb_shinfo(nskb)->frags; + k = 0; + + nskb->ip_summed = CHECKSUM_HW; + nskb->csum = skb->csum; + memcpy(skb_put(nskb, hsize), skb->data + offset, hsize); + + while (pos < offset + len) { + BUG_ON(i >= nfrags); + + *frag = skb_shinfo(skb)->frags[i]; + get_page(frag->page); + size = frag->size; + + if (pos < offset) { + frag->page_offset += offset - pos; + frag->size -= offset - pos; + } + + k++; + + if (pos + size <= offset + len) { + i++; + pos += size; + } else { + frag->size -= pos + size - (offset + len); + break; + } + + frag++; + } + + skb_shinfo(nskb)->nr_frags = k; + nskb->data_len = len - hsize; + nskb->len += nskb->data_len; + nskb->truesize += nskb->data_len; + } while ((offset += len) < skb->len); + + return segs; + +err: + while ((skb = segs)) { + segs = skb->next; + kfree(skb); + } + return ERR_PTR(err); +} + +EXPORT_SYMBOL_GPL(skb_segment); + void __init skb_init(void) { skbuff_head_cache = kmem_cache_create("skbuff_head_cache", diff --git a/net/decnet/dn_nsp_in.c b/net/decnet/dn_nsp_in.c index 547523b41..a2ba9db1c 100644 --- a/net/decnet/dn_nsp_in.c +++ b/net/decnet/dn_nsp_in.c @@ -801,8 +801,7 @@ got_it: * We linearize everything except data segments here. */ if (cb->nsp_flags & ~0x60) { - if (unlikely(skb_is_nonlinear(skb)) && - skb_linearize(skb, GFP_ATOMIC) != 0) + if (unlikely(skb_linearize(skb))) goto free_out; } diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c index e172cf98d..5abf7057a 100644 --- a/net/decnet/dn_route.c +++ b/net/decnet/dn_route.c @@ -629,8 +629,7 @@ int dn_route_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type padlen); if (flags & DN_RT_PKT_CNTL) { - if (unlikely(skb_is_nonlinear(skb)) && - skb_linearize(skb, GFP_ATOMIC) != 0) + if (unlikely(skb_linearize(skb))) goto dump_it; switch(flags & DN_RT_CNTL_MSK) { diff --git a/net/decnet/dn_rules.c b/net/decnet/dn_rules.c index 446faafe2..2440d0504 100644 --- a/net/decnet/dn_rules.c +++ b/net/decnet/dn_rules.c @@ -400,9 +400,10 @@ int dn_fib_dump_rules(struct sk_buff *skb, struct netlink_callback *cb) rcu_read_lock(); hlist_for_each_entry(r, node, &dn_fib_rules, r_hlist) { if (idx < s_idx) - continue; + goto next; if (dn_fib_fill_rule(skb, r, cb, NLM_F_MULTI) < 0) break; +next: idx++; } rcu_read_unlock(); diff --git a/net/ieee80211/Kconfig b/net/ieee80211/Kconfig index dbb08528d..f7e84e9d1 100644 --- a/net/ieee80211/Kconfig +++ b/net/ieee80211/Kconfig @@ -58,6 +58,7 @@ config IEEE80211_CRYPT_TKIP depends on IEEE80211 && NET_RADIO select CRYPTO select CRYPTO_MICHAEL_MIC + select CRC32 ---help--- Include software based cipher suites in support of IEEE 802.11i (aka TGi, WPA, WPA2, WPA-PSK, etc.) for use with TKIP enabled diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index ccf85aa4b..f4f4aa6e7 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -68,6 +68,7 @@ */ #include +#include #include #include #include @@ -1137,6 +1138,88 @@ int inet_sk_rebuild_header(struct sock *sk) EXPORT_SYMBOL(inet_sk_rebuild_header); +static int inet_gso_send_check(struct sk_buff *skb) +{ + struct iphdr *iph; + struct net_protocol *ops; + int proto; + int ihl; + int err = -EINVAL; + + if (unlikely(!pskb_may_pull(skb, sizeof(*iph)))) + goto out; + + iph = skb->nh.iph; + ihl = iph->ihl * 4; + if (ihl < sizeof(*iph)) + goto out; + + if (unlikely(!pskb_may_pull(skb, ihl))) + goto out; + + skb->h.raw = __skb_pull(skb, ihl); + iph = skb->nh.iph; + proto = iph->protocol & (MAX_INET_PROTOS - 1); + err = -EPROTONOSUPPORT; + + rcu_read_lock(); + ops = rcu_dereference(inet_protos[proto]); + if (likely(ops && ops->gso_send_check)) + err = ops->gso_send_check(skb); + rcu_read_unlock(); + +out: + return err; +} + +static struct sk_buff *inet_gso_segment(struct sk_buff *skb, int features) +{ + struct sk_buff *segs = ERR_PTR(-EINVAL); + struct iphdr *iph; + struct net_protocol *ops; + int proto; + int ihl; + int id; + + if (!pskb_may_pull(skb, sizeof(*iph))) + goto out; + + iph = skb->nh.iph; + ihl = iph->ihl * 4; + if (ihl < sizeof(*iph)) + goto out; + + if (!pskb_may_pull(skb, ihl)) + goto out; + + skb->h.raw = __skb_pull(skb, ihl); + iph = skb->nh.iph; + id = ntohs(iph->id); + proto = iph->protocol & (MAX_INET_PROTOS - 1); + segs = ERR_PTR(-EPROTONOSUPPORT); + + rcu_read_lock(); + ops = rcu_dereference(inet_protos[proto]); + if (ops && ops->gso_segment) + segs = ops->gso_segment(skb, features); + rcu_read_unlock(); + + if (!segs || unlikely(IS_ERR(segs))) + goto out; + + skb = segs; + do { + iph = skb->nh.iph; + iph->id = htons(id++); + iph->tot_len = htons(skb->len - skb->mac_len); + iph->check = 0; + iph->check = ip_fast_csum(skb->nh.raw, iph->ihl); + } while ((skb = skb->next)); + +out: + return segs; +} + #ifdef CONFIG_IP_MULTICAST static struct net_protocol igmp_protocol = { .handler = igmp_rcv, @@ -1146,6 +1229,8 @@ static struct net_protocol igmp_protocol = { static struct net_protocol tcp_protocol = { .handler = tcp_v4_rcv, .err_handler = tcp_v4_err, + .gso_send_check = tcp_v4_gso_send_check, + .gso_segment = tcp_tso_segment, .no_policy = 1, }; @@ -1191,6 +1276,8 @@ static int ipv4_proc_init(void); static struct packet_type ip_packet_type = { .type = __constant_htons(ETH_P_IP), .func = ip_rcv, + .gso_send_check = inet_gso_send_check, + .gso_segment = inet_gso_segment, }; static int __init inet_init(void) diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c index ec566f3e6..a66c96a25 100644 --- a/net/ipv4/fib_rules.c +++ b/net/ipv4/fib_rules.c @@ -458,13 +458,13 @@ int inet_dump_rules(struct sk_buff *skb, struct netlink_callback *cb) rcu_read_lock(); hlist_for_each_entry(r, node, &fib_rules, hlist) { - if (idx < s_idx) - continue; + goto next; if (inet_fill_rule(skb, r, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq, RTM_NEWRULE, NLM_F_MULTI) < 0) break; +next: idx++; } rcu_read_unlock(); diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c index 0f4145bab..1de08c186 100644 --- a/net/ipv4/fib_semantics.c +++ b/net/ipv4/fib_semantics.c @@ -160,7 +160,7 @@ void free_fib_info(struct fib_info *fi) void fib_release_info(struct fib_info *fi) { - write_lock(&fib_info_lock); + write_lock_bh(&fib_info_lock); if (fi && --fi->fib_treeref == 0) { hlist_del(&fi->fib_hash); if (fi->fib_prefsrc) @@ -173,7 +173,7 @@ void fib_release_info(struct fib_info *fi) fi->fib_dead = 1; fib_info_put(fi); } - write_unlock(&fib_info_lock); + write_unlock_bh(&fib_info_lock); } static __inline__ int nh_comp(const struct fib_info *fi, const struct fib_info *ofi) @@ -599,7 +599,7 @@ static void fib_hash_move(struct hlist_head *new_info_hash, unsigned int old_size = fib_hash_size; unsigned int i, bytes; - write_lock(&fib_info_lock); + write_lock_bh(&fib_info_lock); old_info_hash = fib_info_hash; old_laddrhash = fib_info_laddrhash; fib_hash_size = new_size; @@ -640,7 +640,7 @@ static void fib_hash_move(struct hlist_head *new_info_hash, } fib_info_laddrhash = new_laddrhash; - write_unlock(&fib_info_lock); + write_unlock_bh(&fib_info_lock); bytes = old_size * sizeof(struct hlist_head *); fib_hash_free(old_info_hash, bytes); @@ -822,7 +822,7 @@ link_it: fi->fib_treeref++; atomic_inc(&fi->fib_clntref); - write_lock(&fib_info_lock); + write_lock_bh(&fib_info_lock); hlist_add_head(&fi->fib_hash, &fib_info_hash[fib_info_hashfn(fi)]); if (fi->fib_prefsrc) { @@ -841,7 +841,7 @@ link_it: head = &fib_info_devhash[hash]; hlist_add_head(&nh->nh_hash, head); } endfor_nexthops(fi) - write_unlock(&fib_info_lock); + write_unlock_bh(&fib_info_lock); return fi; err_inval: diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index cff9c3a72..20b17047c 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -210,8 +210,7 @@ static inline int ip_finish_output(struct sk_buff *skb) return dst_output(skb); } #endif - if (skb->len > dst_mtu(skb->dst) && - !(skb_shinfo(skb)->ufo_size || skb_shinfo(skb)->tso_size)) + if (skb->len > dst_mtu(skb->dst) && !skb_is_gso(skb)) return ip_fragment(skb, ip_finish_output2); else return ip_finish_output2(skb); @@ -362,7 +361,7 @@ packet_routed: } ip_select_ident_more(iph, &rt->u.dst, sk, - (skb_shinfo(skb)->tso_segs ?: 1) - 1); + (skb_shinfo(skb)->gso_segs ?: 1) - 1); /* Add an IP checksum. */ ip_send_check(iph); @@ -743,7 +742,8 @@ static inline int ip_ufo_append_data(struct sock *sk, (length - transhdrlen)); if (!err) { /* specify the length of each IP datagram fragment*/ - skb_shinfo(skb)->ufo_size = (mtu - fragheaderlen); + skb_shinfo(skb)->gso_size = mtu - fragheaderlen; + skb_shinfo(skb)->gso_type = SKB_GSO_UDPV4; __skb_queue_tail(&sk->sk_write_queue, skb); return 0; @@ -839,7 +839,7 @@ int ip_append_data(struct sock *sk, */ if (transhdrlen && length + fragheaderlen <= mtu && - rt->u.dst.dev->features&(NETIF_F_IP_CSUM|NETIF_F_NO_CSUM|NETIF_F_HW_CSUM) && + rt->u.dst.dev->features & NETIF_F_ALL_CSUM && !exthdrlen) csummode = CHECKSUM_HW; @@ -946,7 +946,7 @@ alloc_new_skb: skb_prev->csum = csum_sub(skb_prev->csum, skb->csum); data += fraggap; - skb_trim(skb_prev, maxfraglen); + pskb_trim_unique(skb_prev, maxfraglen); } copy = datalen - transhdrlen - fraggap; @@ -1086,14 +1086,16 @@ ssize_t ip_append_page(struct sock *sk, struct page *page, inet->cork.length += size; if ((sk->sk_protocol == IPPROTO_UDP) && - (rt->u.dst.dev->features & NETIF_F_UFO)) - skb_shinfo(skb)->ufo_size = (mtu - fragheaderlen); + (rt->u.dst.dev->features & NETIF_F_UFO)) { + skb_shinfo(skb)->gso_size = mtu - fragheaderlen; + skb_shinfo(skb)->gso_type = SKB_GSO_UDPV4; + } while (size > 0) { int i; - if (skb_shinfo(skb)->ufo_size) + if (skb_is_gso(skb)) len = size; else { @@ -1139,7 +1141,7 @@ ssize_t ip_append_page(struct sock *sk, struct page *page, data, fraggap, 0); skb_prev->csum = csum_sub(skb_prev->csum, skb->csum); - skb_trim(skb_prev, maxfraglen); + pskb_trim_unique(skb_prev, maxfraglen); } /* diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c index 95278b22b..098d103ec 100644 --- a/net/ipv4/ipcomp.c +++ b/net/ipv4/ipcomp.c @@ -84,7 +84,7 @@ out: static int ipcomp_input(struct xfrm_state *x, struct sk_buff *skb) { u8 nexthdr; - int err = 0; + int err = -ENOMEM; struct iphdr *iph; union { struct iphdr iph; @@ -92,11 +92,8 @@ static int ipcomp_input(struct xfrm_state *x, struct sk_buff *skb) } tmp_iph; - if ((skb_is_nonlinear(skb) || skb_cloned(skb)) && - skb_linearize(skb, GFP_ATOMIC) != 0) { - err = -ENOMEM; + if (skb_linearize_cow(skb)) goto out; - } skb->ip_summed = CHECKSUM_NONE; @@ -171,10 +168,8 @@ static int ipcomp_output(struct xfrm_state *x, struct sk_buff *skb) goto out_ok; } - if ((skb_is_nonlinear(skb) || skb_cloned(skb)) && - skb_linearize(skb, GFP_ATOMIC) != 0) { + if (skb_linearize_cow(skb)) goto out_ok; - } err = ipcomp_compress(x, skb); iph = skb->nh.iph; diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index d0d191920..92adfebec 100644 --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c @@ -237,7 +237,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 = table->private; + struct xt_table_info *private; /* ARP header, plus 2 device addresses, plus 2 IP addresses. */ if (!pskb_may_pull((*pskb), (sizeof(struct arphdr) + @@ -249,6 +249,7 @@ 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/net/ipv4/netfilter/ip_conntrack_helper_h323.c b/net/ipv4/netfilter/ip_conntrack_helper_h323.c index 518f581d3..853a3d512 100644 --- a/net/ipv4/netfilter/ip_conntrack_helper_h323.c +++ b/net/ipv4/netfilter/ip_conntrack_helper_h323.c @@ -1092,7 +1092,7 @@ static struct ip_conntrack_expect *find_expect(struct ip_conntrack *ct, tuple.dst.protonum = IPPROTO_TCP; exp = __ip_conntrack_expect_find(&tuple); - if (exp->master == ct) + if (exp && exp->master == ct) return exp; return NULL; } diff --git a/net/ipv4/netfilter/ip_nat_proto_tcp.c b/net/ipv4/netfilter/ip_nat_proto_tcp.c index a3d14079e..35d1d90c9 100644 --- a/net/ipv4/netfilter/ip_nat_proto_tcp.c +++ b/net/ipv4/netfilter/ip_nat_proto_tcp.c @@ -129,7 +129,12 @@ tcp_manip_pkt(struct sk_buff **pskb, if (hdrsize < sizeof(*hdr)) return 1; - hdr->check = ip_nat_cheat_check(~oldip, newip, +#ifdef CONFIG_XEN + if ((*pskb)->proto_csum_blank) + hdr->check = ip_nat_cheat_check(oldip, ~newip, hdr->check); + else +#endif + hdr->check = ip_nat_cheat_check(~oldip, newip, ip_nat_cheat_check(oldport ^ 0xFFFF, newport, hdr->check)); diff --git a/net/ipv4/netfilter/ip_nat_proto_udp.c b/net/ipv4/netfilter/ip_nat_proto_udp.c index ec6053fdc..e8eaf6a37 100644 --- a/net/ipv4/netfilter/ip_nat_proto_udp.c +++ b/net/ipv4/netfilter/ip_nat_proto_udp.c @@ -113,11 +113,17 @@ udp_manip_pkt(struct sk_buff **pskb, newport = tuple->dst.u.udp.port; portptr = &hdr->dest; } - if (hdr->check) /* 0 is a special case meaning no checksum */ - hdr->check = ip_nat_cheat_check(~oldip, newip, + if (hdr->check) { /* 0 is a special case meaning no checksum */ +#ifdef CONFIG_XEN + if ((*pskb)->proto_csum_blank) + hdr->check = ip_nat_cheat_check(oldip, ~newip, hdr->check); + else +#endif + hdr->check = ip_nat_cheat_check(~oldip, newip, ip_nat_cheat_check(*portptr ^ 0xFFFF, newport, hdr->check)); + } *portptr = newport; return 1; } diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index cee3397ec..71871c4f9 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c @@ -231,7 +231,7 @@ ipt_do_table(struct sk_buff **pskb, const char *indev, *outdev; void *table_base; struct ipt_entry *e, *back; - struct xt_table_info *private = table->private; + struct xt_table_info *private; /* Initialization */ ip = (*pskb)->nh.iph; @@ -248,6 +248,7 @@ ipt_do_table(struct sk_buff **pskb, read_lock_bh(&table->lock); IP_NF_ASSERT(table->valid_hooks & (1 << hook)); + private = table->private; table_base = (void *)private->entries[smp_processor_id()]; e = get_entry(table_base, private->hook_entry[hook]); diff --git a/net/ipv4/netfilter/ipt_ULOG.c b/net/ipv4/netfilter/ipt_ULOG.c index c84cc0338..090f138e7 100644 --- a/net/ipv4/netfilter/ipt_ULOG.c +++ b/net/ipv4/netfilter/ipt_ULOG.c @@ -116,6 +116,11 @@ static void ulog_send(unsigned int nlgroupnum) del_timer(&ub->timer); } + if (!ub->skb) { + DEBUGP("ipt_ULOG: ulog_send: nothing to send\n"); + return; + } + /* last nlmsg needs NLMSG_DONE */ if (ub->qlen > 1) ub->lastnlh->nlmsg_type = NLMSG_DONE; diff --git a/net/ipv4/route.c b/net/ipv4/route.c index cc9423de7..5fe2fcf99 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -3144,7 +3144,7 @@ int __init ip_rt_init(void) rhash_entries, (num_physpages >= 128 * 1024) ? 15 : 17, - HASH_HIGHMEM, + 0, &rt_hash_log, &rt_hash_mask, 0); diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 6a228319f..e369c0b9d 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -258,6 +258,7 @@ #include #include #include +#include #include #include @@ -572,7 +573,7 @@ new_segment: skb->ip_summed = CHECKSUM_HW; tp->write_seq += copy; TCP_SKB_CB(skb)->end_seq += copy; - skb_shinfo(skb)->tso_segs = 0; + skb_shinfo(skb)->gso_segs = 0; if (!copied) TCP_SKB_CB(skb)->flags &= ~TCPCB_FLAG_PSH; @@ -623,14 +624,10 @@ ssize_t tcp_sendpage(struct socket *sock, struct page *page, int offset, ssize_t res; struct sock *sk = sock->sk; -#define TCP_ZC_CSUM_FLAGS (NETIF_F_IP_CSUM | NETIF_F_NO_CSUM | NETIF_F_HW_CSUM) - if (!(sk->sk_route_caps & NETIF_F_SG) || - !(sk->sk_route_caps & TCP_ZC_CSUM_FLAGS)) + !(sk->sk_route_caps & NETIF_F_ALL_CSUM)) return sock_no_sendpage(sock, page, offset, size, flags); -#undef TCP_ZC_CSUM_FLAGS - lock_sock(sk); TCP_CHECK_TIMER(sk); res = do_tcp_sendpages(sk, &page, offset, size, flags); @@ -727,9 +724,7 @@ new_segment: /* * Check whether we can use HW checksum. */ - if (sk->sk_route_caps & - (NETIF_F_IP_CSUM | NETIF_F_NO_CSUM | - NETIF_F_HW_CSUM)) + if (sk->sk_route_caps & NETIF_F_ALL_CSUM) skb->ip_summed = CHECKSUM_HW; skb_entail(sk, tp, skb); @@ -825,7 +820,7 @@ new_segment: tp->write_seq += copy; TCP_SKB_CB(skb)->end_seq += copy; - skb_shinfo(skb)->tso_segs = 0; + skb_shinfo(skb)->gso_segs = 0; from += copy; copied += copy; @@ -2072,6 +2067,77 @@ int compat_tcp_getsockopt(struct sock *sk, int level, int optname, EXPORT_SYMBOL(compat_tcp_getsockopt); #endif +struct sk_buff *tcp_tso_segment(struct sk_buff *skb, int features) +{ + struct sk_buff *segs = ERR_PTR(-EINVAL); + struct tcphdr *th; + unsigned thlen; + unsigned int seq; + unsigned int delta; + unsigned int oldlen; + unsigned int len; + + if (!pskb_may_pull(skb, sizeof(*th))) + goto out; + + th = skb->h.th; + thlen = th->doff * 4; + if (thlen < sizeof(*th)) + goto out; + + if (!pskb_may_pull(skb, thlen)) + goto out; + + oldlen = (u16)~skb->len; + __skb_pull(skb, thlen); + + if (skb_gso_ok(skb, features | NETIF_F_GSO_ROBUST)) { + /* Packet is from an untrusted source, reset gso_segs. */ + int mss = skb_shinfo(skb)->gso_size; + + skb_shinfo(skb)->gso_segs = (skb->len + mss - 1) / mss; + + segs = NULL; + goto out; + } + + segs = skb_segment(skb, features); + if (IS_ERR(segs)) + goto out; + + len = skb_shinfo(skb)->gso_size; + delta = htonl(oldlen + (thlen + len)); + + skb = segs; + th = skb->h.th; + seq = ntohl(th->seq); + + do { + th->fin = th->psh = 0; + + th->check = ~csum_fold(th->check + delta); + if (skb->ip_summed != CHECKSUM_HW) + th->check = csum_fold(csum_partial(skb->h.raw, thlen, + skb->csum)); + + seq += len; + skb = skb->next; + th = skb->h.th; + + th->seq = htonl(seq); + th->cwr = 0; + } while (skb->next); + + delta = htonl(oldlen + (skb->tail - skb->h.raw) + skb->data_len); + th->check = ~csum_fold(th->check + delta); + if (skb->ip_summed != CHECKSUM_HW) + th->check = csum_fold(csum_partial(skb->h.raw, thlen, + skb->csum)); + +out: + return segs; +} + extern void __skb_cb_too_small_for_tcp(int, int); extern struct tcp_congestion_ops tcp_reno; diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 662bd247b..0eadd3a27 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -1072,7 +1072,7 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_ else pkt_len = (end_seq - TCP_SKB_CB(skb)->seq); - if (tcp_fragment(sk, skb, pkt_len, skb_shinfo(skb)->tso_size)) + if (tcp_fragment(sk, skb, pkt_len, skb_shinfo(skb)->gso_size)) break; pcount = tcp_skb_pcount(skb); } diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 075216a98..0334bbe10 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -496,6 +496,24 @@ void tcp_v4_send_check(struct sock *sk, int len, struct sk_buff *skb) } } +int tcp_v4_gso_send_check(struct sk_buff *skb) +{ + struct iphdr *iph; + struct tcphdr *th; + + if (!pskb_may_pull(skb, sizeof(*th))) + return -EINVAL; + + iph = skb->nh.iph; + th = skb->h.th; + + th->check = 0; + th->check = ~tcp_v4_check(th, skb->len, iph->saddr, iph->daddr, 0); + skb->csum = offsetof(struct tcphdr, check); + skb->ip_summed = CHECKSUM_HW; + return 0; +} + /* * This routine will send an RST to the other tcp. * diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 1e848adbc..ba50b52f8 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -197,6 +197,7 @@ 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)++; @@ -511,15 +512,17 @@ static void tcp_set_skb_tso_segs(struct sock *sk, struct sk_buff *skb, unsigned /* Avoid the costly divide in the normal * non-TSO case. */ - skb_shinfo(skb)->tso_segs = 1; - skb_shinfo(skb)->tso_size = 0; + skb_shinfo(skb)->gso_segs = 1; + skb_shinfo(skb)->gso_size = 0; + skb_shinfo(skb)->gso_type = 0; } else { unsigned int factor; factor = skb->len + (mss_now - 1); factor /= mss_now; - skb_shinfo(skb)->tso_segs = factor; - skb_shinfo(skb)->tso_size = mss_now; + skb_shinfo(skb)->gso_segs = factor; + skb_shinfo(skb)->gso_size = mss_now; + skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4; } } @@ -912,7 +915,7 @@ static int tcp_init_tso_segs(struct sock *sk, struct sk_buff *skb, unsigned int if (!tso_segs || (tso_segs > 1 && - skb_shinfo(skb)->tso_size != mss_now)) { + tcp_skb_mss(skb) != mss_now)) { tcp_set_skb_tso_segs(sk, skb, mss_now); tso_segs = tcp_skb_pcount(skb); } @@ -1723,8 +1726,9 @@ int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb) tp->snd_una == (TCP_SKB_CB(skb)->end_seq - 1)) { if (!pskb_trim(skb, 0)) { TCP_SKB_CB(skb)->seq = TCP_SKB_CB(skb)->end_seq - 1; - skb_shinfo(skb)->tso_segs = 1; - skb_shinfo(skb)->tso_size = 0; + skb_shinfo(skb)->gso_segs = 1; + skb_shinfo(skb)->gso_size = 0; + skb_shinfo(skb)->gso_type = 0; skb->ip_summed = CHECKSUM_NONE; skb->csum = 0; } @@ -1929,8 +1933,9 @@ void tcp_send_fin(struct sock *sk) skb->csum = 0; TCP_SKB_CB(skb)->flags = (TCPCB_FLAG_ACK | TCPCB_FLAG_FIN); TCP_SKB_CB(skb)->sacked = 0; - skb_shinfo(skb)->tso_segs = 1; - skb_shinfo(skb)->tso_size = 0; + skb_shinfo(skb)->gso_segs = 1; + skb_shinfo(skb)->gso_size = 0; + skb_shinfo(skb)->gso_type = 0; /* FIN eats a sequence byte, write_seq advanced by tcp_queue_skb(). */ TCP_SKB_CB(skb)->seq = tp->write_seq; @@ -1962,8 +1967,9 @@ void tcp_send_active_reset(struct sock *sk, gfp_t priority) skb->csum = 0; TCP_SKB_CB(skb)->flags = (TCPCB_FLAG_ACK | TCPCB_FLAG_RST); TCP_SKB_CB(skb)->sacked = 0; - skb_shinfo(skb)->tso_segs = 1; - skb_shinfo(skb)->tso_size = 0; + skb_shinfo(skb)->gso_segs = 1; + skb_shinfo(skb)->gso_size = 0; + skb_shinfo(skb)->gso_type = 0; /* Send it off. */ TCP_SKB_CB(skb)->seq = tcp_acceptable_seq(sk, tp); @@ -2046,8 +2052,9 @@ struct sk_buff * tcp_make_synack(struct sock *sk, struct dst_entry *dst, TCP_SKB_CB(skb)->seq = tcp_rsk(req)->snt_isn; TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(skb)->seq + 1; TCP_SKB_CB(skb)->sacked = 0; - skb_shinfo(skb)->tso_segs = 1; - skb_shinfo(skb)->tso_size = 0; + skb_shinfo(skb)->gso_segs = 1; + skb_shinfo(skb)->gso_size = 0; + skb_shinfo(skb)->gso_type = 0; th->seq = htonl(TCP_SKB_CB(skb)->seq); th->ack_seq = htonl(tcp_rsk(req)->rcv_isn + 1); if (req->rcv_wnd == 0) { /* ignored for retransmitted syns */ @@ -2151,8 +2158,9 @@ int tcp_connect(struct sock *sk) TCP_SKB_CB(buff)->flags = TCPCB_FLAG_SYN; TCP_ECN_send_syn(sk, tp, buff); TCP_SKB_CB(buff)->sacked = 0; - skb_shinfo(buff)->tso_segs = 1; - skb_shinfo(buff)->tso_size = 0; + skb_shinfo(buff)->gso_segs = 1; + skb_shinfo(buff)->gso_size = 0; + skb_shinfo(buff)->gso_type = 0; buff->csum = 0; TCP_SKB_CB(buff)->seq = tp->write_seq++; TCP_SKB_CB(buff)->end_seq = tp->write_seq; @@ -2256,8 +2264,9 @@ void tcp_send_ack(struct sock *sk) buff->csum = 0; TCP_SKB_CB(buff)->flags = TCPCB_FLAG_ACK; TCP_SKB_CB(buff)->sacked = 0; - skb_shinfo(buff)->tso_segs = 1; - skb_shinfo(buff)->tso_size = 0; + skb_shinfo(buff)->gso_segs = 1; + skb_shinfo(buff)->gso_size = 0; + skb_shinfo(buff)->gso_type = 0; /* Send it off, this clears delayed acks for us. */ TCP_SKB_CB(buff)->seq = TCP_SKB_CB(buff)->end_seq = tcp_acceptable_seq(sk, tp); @@ -2292,8 +2301,9 @@ static int tcp_xmit_probe_skb(struct sock *sk, int urgent) skb->csum = 0; TCP_SKB_CB(skb)->flags = TCPCB_FLAG_ACK; TCP_SKB_CB(skb)->sacked = urgent; - skb_shinfo(skb)->tso_segs = 1; - skb_shinfo(skb)->tso_size = 0; + skb_shinfo(skb)->gso_segs = 1; + skb_shinfo(skb)->gso_size = 0; + skb_shinfo(skb)->gso_type = 0; /* Use a previous sequence. This should cause the other * end to send an ack. Don't queue or clone SKB, just diff --git a/net/ipv4/xfrm4_output.c b/net/ipv4/xfrm4_output.c index 4ef8efaf6..ecc4119df 100644 --- a/net/ipv4/xfrm4_output.c +++ b/net/ipv4/xfrm4_output.c @@ -9,6 +9,8 @@ */ #include +#include +#include #include #include #include @@ -17,6 +19,8 @@ #include #include +extern int skb_checksum_setup(struct sk_buff *skb); + /* Add encapsulation header. * * In transport mode, the IP header will be moved forward to make space @@ -103,6 +107,10 @@ static int xfrm4_output_one(struct sk_buff *skb) struct xfrm_state *x = dst->xfrm; int err; + err = skb_checksum_setup(skb); + if (err) + goto error_nolock; + if (skb->ip_summed == CHECKSUM_HW) { err = skb_checksum_help(skb, 0); if (err) @@ -152,16 +160,10 @@ error_nolock: goto out_exit; } -static int xfrm4_output_finish(struct sk_buff *skb) +static int xfrm4_output_finish2(struct sk_buff *skb) { int err; -#ifdef CONFIG_NETFILTER - if (!skb->dst->xfrm) { - IPCB(skb)->flags |= IPSKB_REROUTED; - return dst_output(skb); - } -#endif while (likely((err = xfrm4_output_one(skb)) == 0)) { nf_reset(skb); @@ -174,7 +176,7 @@ static int xfrm4_output_finish(struct sk_buff *skb) return dst_output(skb); err = nf_hook(PF_INET, NF_IP_POST_ROUTING, &skb, NULL, - skb->dst->dev, xfrm4_output_finish); + skb->dst->dev, xfrm4_output_finish2); if (unlikely(err != 1)) break; } @@ -182,6 +184,48 @@ static int xfrm4_output_finish(struct sk_buff *skb) return err; } +static int xfrm4_output_finish(struct sk_buff *skb) +{ + struct sk_buff *segs; + +#ifdef CONFIG_NETFILTER + if (!skb->dst->xfrm) { + IPCB(skb)->flags |= IPSKB_REROUTED; + return dst_output(skb); + } +#endif + + if (!skb_is_gso(skb)) + return xfrm4_output_finish2(skb); + + skb->protocol = htons(ETH_P_IP); + segs = skb_gso_segment(skb, 0); + kfree_skb(skb); + if (unlikely(IS_ERR(segs))) + return PTR_ERR(segs); + + do { + struct sk_buff *nskb = segs->next; + int err; + + segs->next = NULL; + err = xfrm4_output_finish2(segs); + + if (unlikely(err)) { + while ((segs = nskb)) { + nskb = segs->next; + segs->next = NULL; + kfree_skb(segs); + } + return err; + } + + segs = nskb; + } while (segs); + + return 0; +} + int xfrm4_output(struct sk_buff *skb) { return NF_HOOK_COND(PF_INET, NF_IP_POST_ROUTING, skb, NULL, skb->dst->dev, diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 1f5e0c63a..386ca5c41 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -2470,6 +2470,7 @@ static void addrconf_dad_start(struct inet6_ifaddr *ifp, u32 flags) spin_lock_bh(&ifp->lock); if (dev->flags&(IFF_NOARP|IFF_LOOPBACK) || + !(dev->flags&IFF_MULTICAST) || !(ifp->flags&IFA_F_TENTATIVE)) { ifp->flags &= ~IFA_F_TENTATIVE; spin_unlock_bh(&ifp->lock); @@ -2554,6 +2555,7 @@ static void addrconf_dad_completed(struct inet6_ifaddr *ifp) if (ifp->idev->cnf.forwarding == 0 && ifp->idev->cnf.rtr_solicits > 0 && (dev->flags&IFF_LOOPBACK) == 0 && + (dev->flags & IFF_MULTICAST) && (ipv6_addr_type(&ifp->addr) & IPV6_ADDR_LINKLOCAL)) { struct in6_addr all_routers; diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c index a18d42563..9ca783dcc 100644 --- a/net/ipv6/exthdrs.c +++ b/net/ipv6/exthdrs.c @@ -635,14 +635,17 @@ ipv6_renew_options(struct sock *sk, struct ipv6_txoptions *opt, struct ipv6_txoptions *opt2; int err; - 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 (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 (newopt && newoptlen) tot_len += CMSG_ALIGN(newoptlen); @@ -659,25 +662,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->hopopt, newopt, newoptlen, + err = ipv6_renew_option(opt ? opt->hopopt : NULL, newopt, newoptlen, newtype != IPV6_HOPOPTS, &opt2->hopopt, &p); if (err) goto out; - err = ipv6_renew_option(opt->dst0opt, newopt, newoptlen, + err = ipv6_renew_option(opt ? opt->dst0opt : NULL, newopt, newoptlen, newtype != IPV6_RTHDRDSTOPTS, &opt2->dst0opt, &p); if (err) goto out; - err = ipv6_renew_option(opt->srcrt, newopt, newoptlen, + err = ipv6_renew_option(opt ? opt->srcrt : NULL, 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->dst1opt, newopt, newoptlen, + err = ipv6_renew_option(opt ? opt->dst1opt : NULL, newopt, newoptlen, newtype != IPV6_DSTOPTS, &opt2->dst1opt, &p); if (err) diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index e46048974..1d5dfeb26 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -147,7 +147,7 @@ static int ip6_output2(struct sk_buff *skb) int ip6_output(struct sk_buff *skb) { - if ((skb->len > dst_mtu(skb->dst) && !skb_shinfo(skb)->ufo_size) || + if ((skb->len > dst_mtu(skb->dst) && !skb_is_gso(skb)) || dst_allfrag(skb->dst)) return ip6_fragment(skb, ip6_output2); else @@ -830,8 +830,9 @@ static inline int ip6_ufo_append_data(struct sock *sk, struct frag_hdr fhdr; /* specify the length of each IP datagram fragment*/ - skb_shinfo(skb)->ufo_size = (mtu - fragheaderlen) - - sizeof(struct frag_hdr); + skb_shinfo(skb)->gso_size = mtu - fragheaderlen - + sizeof(struct frag_hdr); + skb_shinfo(skb)->gso_type = SKB_GSO_UDPV4; ipv6_select_ident(skb, &fhdr); skb_shinfo(skb)->ip6_frag_id = fhdr.identification; __skb_queue_tail(&sk->sk_write_queue, skb); @@ -1047,7 +1048,7 @@ alloc_new_skb: skb_prev->csum = csum_sub(skb_prev->csum, skb->csum); data += fraggap; - skb_trim(skb_prev, maxfraglen); + pskb_trim_unique(skb_prev, maxfraglen); } copy = datalen - transhdrlen - fraggap; if (copy < 0) { diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c index 486364360..96cac9a94 100644 --- a/net/ipv6/ipcomp6.c +++ b/net/ipv6/ipcomp6.c @@ -65,7 +65,7 @@ static LIST_HEAD(ipcomp6_tfms_list); static int ipcomp6_input(struct xfrm_state *x, struct sk_buff *skb) { - int err = 0; + int err = -ENOMEM; u8 nexthdr = 0; int hdr_len = skb->h.raw - skb->nh.raw; unsigned char *tmp_hdr = NULL; @@ -76,11 +76,8 @@ static int ipcomp6_input(struct xfrm_state *x, struct sk_buff *skb) struct crypto_tfm *tfm; int cpu; - if ((skb_is_nonlinear(skb) || skb_cloned(skb)) && - skb_linearize(skb, GFP_ATOMIC) != 0) { - err = -ENOMEM; + if (skb_linearize_cow(skb)) goto out; - } skb->ip_summed = CHECKSUM_NONE; @@ -159,10 +156,8 @@ static int ipcomp6_output(struct xfrm_state *x, struct sk_buff *skb) goto out_ok; } - if ((skb_is_nonlinear(skb) || skb_cloned(skb)) && - skb_linearize(skb, GFP_ATOMIC) != 0) { + if (skb_linearize_cow(skb)) goto out_ok; - } /* compression */ plen = skb->len - hdr_len; diff --git a/net/ipv6/xfrm6_output.c b/net/ipv6/xfrm6_output.c index 80242172a..e9ea33892 100644 --- a/net/ipv6/xfrm6_output.c +++ b/net/ipv6/xfrm6_output.c @@ -151,7 +151,7 @@ error_nolock: goto out_exit; } -static int xfrm6_output_finish(struct sk_buff *skb) +static int xfrm6_output_finish2(struct sk_buff *skb) { int err; @@ -167,7 +167,7 @@ static int xfrm6_output_finish(struct sk_buff *skb) return dst_output(skb); err = nf_hook(PF_INET6, NF_IP6_POST_ROUTING, &skb, NULL, - skb->dst->dev, xfrm6_output_finish); + skb->dst->dev, xfrm6_output_finish2); if (unlikely(err != 1)) break; } @@ -175,6 +175,41 @@ static int xfrm6_output_finish(struct sk_buff *skb) return err; } +static int xfrm6_output_finish(struct sk_buff *skb) +{ + struct sk_buff *segs; + + if (!skb_is_gso(skb)) + return xfrm6_output_finish2(skb); + + skb->protocol = htons(ETH_P_IP); + segs = skb_gso_segment(skb, 0); + kfree_skb(skb); + if (unlikely(IS_ERR(segs))) + return PTR_ERR(segs); + + do { + struct sk_buff *nskb = segs->next; + int err; + + segs->next = NULL; + err = xfrm6_output_finish2(segs); + + if (unlikely(err)) { + while ((segs = nskb)) { + nskb = segs->next; + segs->next = NULL; + kfree_skb(segs); + } + return err; + } + + segs = nskb; + } while (segs); + + return 0; +} + int xfrm6_output(struct sk_buff *skb) { return NF_HOOK(PF_INET6, NF_IP6_POST_ROUTING, skb, NULL, skb->dst->dev, diff --git a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c index 811d99872..e6a50e826 100644 --- a/net/ipx/af_ipx.c +++ b/net/ipx/af_ipx.c @@ -1647,7 +1647,8 @@ static int ipx_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_ty ipx_pktsize = ntohs(ipx->ipx_pktsize); /* Too small or invalid header? */ - if (ipx_pktsize < sizeof(struct ipxhdr) || ipx_pktsize > skb->len) + if (ipx_pktsize < sizeof(struct ipxhdr) + || !pskb_may_pull(skb, ipx_pktsize)) goto drop; if (ipx->ipx_checksum != IPX_NO_CHECKSUM && diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c index 61cdda4e5..b59d3b2bd 100644 --- a/net/netfilter/nfnetlink_log.c +++ b/net/netfilter/nfnetlink_log.c @@ -366,6 +366,9 @@ __nfulnl_send(struct nfulnl_instance *inst) if (timer_pending(&inst->timer)) del_timer(&inst->timer); + if (!inst->skb) + return 0; + if (inst->qlen > 1) inst->lastnlh->nlmsg_type = NLMSG_DONE; diff --git a/net/sched/act_api.c b/net/sched/act_api.c index 2ffa11c6e..eb7dc2947 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c @@ -251,15 +251,17 @@ tcf_action_dump(struct sk_buff *skb, struct tc_action *act, int bind, int ref) RTA_PUT(skb, a->order, 0, NULL); err = tcf_action_dump_1(skb, a, bind, ref); if (err < 0) - goto rtattr_failure; + goto errout; r->rta_len = skb->tail - (u8*)r; } return 0; rtattr_failure: + err = -EINVAL; +errout: skb_trim(skb, b - skb->data); - return -err; + return err; } struct tc_action *tcf_action_init_1(struct rtattr *rta, struct rtattr *est, @@ -306,6 +308,7 @@ struct tc_action *tcf_action_init_1(struct rtattr *rta, struct rtattr *est, goto err_mod; } #endif + *err = -ENOENT; goto err_out; } @@ -777,7 +780,7 @@ replay: return ret; } -static char * +static struct rtattr * find_dump_kind(struct nlmsghdr *n) { struct rtattr *tb1, *tb2[TCA_ACT_MAX+1]; @@ -805,7 +808,7 @@ find_dump_kind(struct nlmsghdr *n) return NULL; kind = tb2[TCA_ACT_KIND-1]; - return (char *) RTA_DATA(kind); + return kind; } static int @@ -818,16 +821,15 @@ tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb) struct tc_action a; int ret = 0; struct tcamsg *t = (struct tcamsg *) NLMSG_DATA(cb->nlh); - char *kind = find_dump_kind(cb->nlh); + struct rtattr *kind = find_dump_kind(cb->nlh); if (kind == NULL) { printk("tc_dump_action: action bad kind\n"); return 0; } - a_o = tc_lookup_action_n(kind); + a_o = tc_lookup_action(kind); if (a_o == NULL) { - printk("failed to find %s\n", kind); return 0; } @@ -835,7 +837,7 @@ tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb) a.ops = a_o; if (a_o->walk == NULL) { - printk("tc_dump_action: %s !capable of dumping table\n", kind); + printk("tc_dump_action: %s !capable of dumping table\n", a_o->kind); goto rtattr_failure; } diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c index 138ea92ed..74d4a1dce 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c @@ -72,9 +72,9 @@ void qdisc_unlock_tree(struct net_device *dev) dev->queue_lock serializes queue accesses for this device AND dev->qdisc pointer itself. - dev->xmit_lock serializes accesses to device driver. + netif_tx_lock serializes accesses to device driver. - dev->queue_lock and dev->xmit_lock are mutually exclusive, + dev->queue_lock and netif_tx_lock are mutually exclusive, if one is grabbed, another must be free. */ @@ -90,14 +90,17 @@ void qdisc_unlock_tree(struct net_device *dev) NOTE: Called under dev->queue_lock with locally disabled BH. */ -int qdisc_restart(struct net_device *dev) +static inline int qdisc_restart(struct net_device *dev) { struct Qdisc *q = dev->qdisc; struct sk_buff *skb; /* Dequeue packet */ - if ((skb = q->dequeue(q)) != NULL) { + if (((skb = dev->gso_skb)) || ((skb = q->dequeue(q)))) { unsigned nolock = (dev->features & NETIF_F_LLTX); + + dev->gso_skb = NULL; + /* * When the driver has LLTX set it does its own locking * in start_xmit. No need to add additional overhead by @@ -108,7 +111,7 @@ int qdisc_restart(struct net_device *dev) * will be requeued. */ if (!nolock) { - if (!spin_trylock(&dev->xmit_lock)) { + if (!netif_tx_trylock(dev)) { collision: /* So, someone grabbed the driver. */ @@ -126,8 +129,6 @@ int qdisc_restart(struct net_device *dev) __get_cpu_var(netdev_rx_stat).cpu_collision++; goto requeue; } - /* Remember that the driver is grabbed by us. */ - dev->xmit_lock_owner = smp_processor_id(); } { @@ -136,14 +137,11 @@ int qdisc_restart(struct net_device *dev) if (!netif_queue_stopped(dev)) { int ret; - if (netdev_nit) - dev_queue_xmit_nit(skb, dev); - ret = dev->hard_start_xmit(skb, dev); + ret = dev_hard_start_xmit(skb, dev); if (ret == NETDEV_TX_OK) { if (!nolock) { - dev->xmit_lock_owner = -1; - spin_unlock(&dev->xmit_lock); + netif_tx_unlock(dev); } spin_lock(&dev->queue_lock); return -1; @@ -157,8 +155,7 @@ int qdisc_restart(struct net_device *dev) /* NETDEV_TX_BUSY - we need to requeue */ /* Release the driver */ if (!nolock) { - dev->xmit_lock_owner = -1; - spin_unlock(&dev->xmit_lock); + netif_tx_unlock(dev); } spin_lock(&dev->queue_lock); q = dev->qdisc; @@ -175,7 +172,10 @@ int qdisc_restart(struct net_device *dev) */ requeue: - q->ops->requeue(skb, q); + if (skb->next) + dev->gso_skb = skb; + else + q->ops->requeue(skb, q); netif_schedule(dev); return 1; } @@ -183,11 +183,23 @@ requeue: return q->q.qlen; } +void __qdisc_run(struct net_device *dev) +{ + if (unlikely(dev->qdisc == &noop_qdisc)) + goto out; + + while (qdisc_restart(dev) < 0 && !netif_queue_stopped(dev)) + /* NOTHING */; + +out: + clear_bit(__LINK_STATE_QDISC_RUNNING, &dev->state); +} + static void dev_watchdog(unsigned long arg) { struct net_device *dev = (struct net_device *)arg; - spin_lock(&dev->xmit_lock); + netif_tx_lock(dev); if (dev->qdisc != &noop_qdisc) { if (netif_device_present(dev) && netif_running(dev) && @@ -203,7 +215,7 @@ static void dev_watchdog(unsigned long arg) dev_hold(dev); } } - spin_unlock(&dev->xmit_lock); + netif_tx_unlock(dev); dev_put(dev); } @@ -227,17 +239,17 @@ void __netdev_watchdog_up(struct net_device *dev) static void dev_watchdog_up(struct net_device *dev) { - spin_lock_bh(&dev->xmit_lock); + netif_tx_lock_bh(dev); __netdev_watchdog_up(dev); - spin_unlock_bh(&dev->xmit_lock); + netif_tx_unlock_bh(dev); } static void dev_watchdog_down(struct net_device *dev) { - spin_lock_bh(&dev->xmit_lock); + netif_tx_lock_bh(dev); if (del_timer(&dev->watchdog_timer)) dev_put(dev); - spin_unlock_bh(&dev->xmit_lock); + netif_tx_unlock_bh(dev); } void netif_carrier_on(struct net_device *dev) @@ -579,10 +591,17 @@ void dev_deactivate(struct net_device *dev) dev_watchdog_down(dev); - while (test_bit(__LINK_STATE_SCHED, &dev->state)) + /* Wait for outstanding dev_queue_xmit calls. */ + synchronize_rcu(); + + /* Wait for outstanding qdisc_run calls. */ + while (test_bit(__LINK_STATE_QDISC_RUNNING, &dev->state)) yield(); - spin_unlock_wait(&dev->xmit_lock); + if (dev->gso_skb) { + kfree_skb(dev->gso_skb); + dev->gso_skb = NULL; + } } void dev_init_scheduler(struct net_device *dev) @@ -624,6 +643,5 @@ EXPORT_SYMBOL(qdisc_create_dflt); EXPORT_SYMBOL(qdisc_alloc); EXPORT_SYMBOL(qdisc_destroy); EXPORT_SYMBOL(qdisc_reset); -EXPORT_SYMBOL(qdisc_restart); EXPORT_SYMBOL(qdisc_lock_tree); EXPORT_SYMBOL(qdisc_unlock_tree); diff --git a/net/sched/sch_teql.c b/net/sched/sch_teql.c index 79b8ef34c..4c16ad57a 100644 --- a/net/sched/sch_teql.c +++ b/net/sched/sch_teql.c @@ -302,20 +302,17 @@ restart: switch (teql_resolve(skb, skb_res, slave)) { case 0: - if (spin_trylock(&slave->xmit_lock)) { - slave->xmit_lock_owner = smp_processor_id(); + if (netif_tx_trylock(slave)) { if (!netif_queue_stopped(slave) && slave->hard_start_xmit(skb, slave) == 0) { - slave->xmit_lock_owner = -1; - spin_unlock(&slave->xmit_lock); + netif_tx_unlock(slave); master->slaves = NEXT_SLAVE(q); netif_wake_queue(dev); master->stats.tx_packets++; master->stats.tx_bytes += len; return 0; } - slave->xmit_lock_owner = -1; - spin_unlock(&slave->xmit_lock); + netif_tx_unlock(slave); } if (netif_queue_stopped(dev)) busy = 1; diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c index 5e0de3c0e..b9b907023 100644 --- a/net/sctp/sm_make_chunk.c +++ b/net/sctp/sm_make_chunk.c @@ -806,38 +806,26 @@ no_mem: /* 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 sctp_chunk *chunk, - const struct msghdr *msg) + const struct msghdr *msg, + size_t paylen) { struct sctp_chunk *retval; - 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); - } + void *payload = NULL; + int err; - retval = sctp_make_abort(asoc, chunk, sizeof(sctp_errhdr_t) + paylen); + retval = sctp_make_abort(asoc, NULL, sizeof(sctp_errhdr_t) + paylen); if (!retval) goto err_chunk; if (paylen) { /* Put the msg_iov together into payload. */ - payload = kmalloc(paylen, GFP_ATOMIC); + payload = kmalloc(paylen, GFP_KERNEL); if (!payload) goto err_payload; - payoff = payload; - for (; iovlen > 0; --iovlen) { - if (copy_from_user(payoff, iov->iov_base,iov->iov_len)) - goto err_copy; - payoff += iov->iov_len; - iov++; - } + err = memcpy_fromiovec(payload, msg->msg_iov, paylen); + if (err < 0) + goto err_copy; } sctp_init_cause(retval, SCTP_ERROR_USER_ABORT, payload, paylen); diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index 9e58144f4..66e9c5b27 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c @@ -4026,18 +4026,12 @@ 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 msghdr *msg = arg; - struct sctp_chunk *abort; + struct sctp_chunk *abort = arg; sctp_disposition_t retval; retval = SCTP_DISPOSITION_CONSUME; - /* 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_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. @@ -4161,8 +4155,7 @@ sctp_disposition_t sctp_sf_cookie_wait_prm_abort( void *arg, sctp_cmd_seq_t *commands) { - struct msghdr *msg = arg; - struct sctp_chunk *abort; + struct sctp_chunk *abort = arg; sctp_disposition_t retval; /* Stop T1-init timer */ @@ -4170,12 +4163,7 @@ sctp_disposition_t sctp_sf_cookie_wait_prm_abort( SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT)); retval = SCTP_DISPOSITION_CONSUME; - /* 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_REPLY, SCTP_CHUNK(abort)); sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE, SCTP_STATE(SCTP_STATE_CLOSED)); diff --git a/net/sctp/socket.c b/net/sctp/socket.c index b811691c3..5b1c8375c 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -1246,9 +1246,13 @@ SCTP_STATIC void sctp_close(struct sock *sk, long timeout) } } - if (sock_flag(sk, SOCK_LINGER) && !sk->sk_lingertime) - sctp_primitive_ABORT(asoc, NULL); - else + 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 sctp_primitive_SHUTDOWN(asoc, NULL); } @@ -1477,8 +1481,16 @@ 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, msg); + sctp_primitive_ABORT(asoc, chunk); err = 0; goto out_unlock; } diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c index 7026b0866..00cb388ec 100644 --- a/net/sunrpc/cache.c +++ b/net/sunrpc/cache.c @@ -71,7 +71,12 @@ struct cache_head *sunrpc_cache_lookup(struct cache_detail *detail, new = detail->alloc(); if (!new) return NULL; + /* must fully initialise 'new', else + * we might get lose if we need to + * cache_put it soon. + */ cache_init(new); + detail->init(new, key); write_lock(&detail->hash_lock); @@ -85,7 +90,6 @@ struct cache_head *sunrpc_cache_lookup(struct cache_detail *detail, return tmp; } } - detail->init(new, key); new->next = *head; *head = new; detail->entries++; diff --git a/scripts/basic/.docproc.cmd b/scripts/basic/.docproc.cmd index e725e6b22..c9e1b962d 100644 --- a/scripts/basic/.docproc.cmd +++ b/scripts/basic/.docproc.cmd @@ -1,4 +1,4 @@ -cmd_scripts/basic/docproc := gcc -Wp,-MD,scripts/basic/.docproc.d -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -o scripts/basic/docproc scripts/basic/docproc.c +cmd_scripts/basic/docproc := gcc -Wp,-MD,scripts/basic/.docproc.d -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -o scripts/basic/docproc scripts/basic/docproc.c deps_scripts/basic/docproc := \ scripts/basic/docproc.c \ @@ -6,16 +6,17 @@ deps_scripts/basic/docproc := \ /usr/include/features.h \ /usr/include/sys/cdefs.h \ /usr/include/gnu/stubs.h \ - /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/stddef.h \ - /usr/include/bits/types.h \ /usr/include/bits/wordsize.h \ + /usr/include/gnu/stubs-32.h \ + /usr/lib/gcc/i386-redhat-linux/4.0.1/include/stddef.h \ + /usr/include/bits/types.h \ /usr/include/bits/typesizes.h \ /usr/include/libio.h \ /usr/include/_G_config.h \ /usr/include/wchar.h \ /usr/include/bits/wchar.h \ /usr/include/gconv.h \ - /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/stdarg.h \ + /usr/lib/gcc/i386-redhat-linux/4.0.1/include/stdarg.h \ /usr/include/bits/stdio_lim.h \ /usr/include/bits/sys_errlist.h \ /usr/include/bits/stdio.h \ @@ -30,7 +31,6 @@ deps_scripts/basic/docproc := \ /usr/include/bits/time.h \ /usr/include/sys/sysmacros.h \ /usr/include/bits/pthreadtypes.h \ - /usr/include/bits/sched.h \ /usr/include/alloca.h \ /usr/include/string.h \ /usr/include/bits/string.h \ @@ -40,8 +40,8 @@ deps_scripts/basic/docproc := \ /usr/include/bits/posix_opt.h \ /usr/include/bits/confname.h \ /usr/include/getopt.h \ - /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/limits.h \ - /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/syslimits.h \ + /usr/lib/gcc/i386-redhat-linux/4.0.1/include/limits.h \ + /usr/lib/gcc/i386-redhat-linux/4.0.1/include/syslimits.h \ /usr/include/limits.h \ /usr/include/bits/posix1_lim.h \ /usr/include/bits/local_lim.h \ @@ -54,9 +54,6 @@ deps_scripts/basic/docproc := \ /usr/include/bits/sigaction.h \ /usr/include/bits/sigcontext.h \ /usr/include/asm/sigcontext.h \ - /usr/include/linux/compiler.h \ - /usr/include/linux/compiler-gcc3.h \ - /usr/include/linux/compiler-gcc.h \ /usr/include/bits/sigstack.h \ /usr/include/bits/sigthread.h \ /usr/include/sys/resource.h \ diff --git a/scripts/basic/.fixdep.cmd b/scripts/basic/.fixdep.cmd index 1c463aa74..fc3d06a8d 100644 --- a/scripts/basic/.fixdep.cmd +++ b/scripts/basic/.fixdep.cmd @@ -1,4 +1,4 @@ -cmd_scripts/basic/fixdep := gcc -Wp,-MD,scripts/basic/.fixdep.d -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -o scripts/basic/fixdep scripts/basic/fixdep.c +cmd_scripts/basic/fixdep := gcc -Wp,-MD,scripts/basic/.fixdep.d -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -o scripts/basic/fixdep scripts/basic/fixdep.c deps_scripts/basic/fixdep := \ scripts/basic/fixdep.c \ @@ -6,13 +6,15 @@ deps_scripts/basic/fixdep := \ $(wildcard include/config/my/option.h) \ $(wildcard include/config/.h) \ $(wildcard include/config/foo.h) \ + $(wildcard include/config/boom.h) \ /usr/include/sys/types.h \ /usr/include/features.h \ /usr/include/sys/cdefs.h \ /usr/include/gnu/stubs.h \ - /usr/include/bits/types.h \ /usr/include/bits/wordsize.h \ - /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/stddef.h \ + /usr/include/gnu/stubs-32.h \ + /usr/include/bits/types.h \ + /usr/lib/gcc/i386-redhat-linux/4.0.1/include/stddef.h \ /usr/include/bits/typesizes.h \ /usr/include/time.h \ /usr/include/endian.h \ @@ -23,7 +25,6 @@ deps_scripts/basic/fixdep := \ /usr/include/bits/time.h \ /usr/include/sys/sysmacros.h \ /usr/include/bits/pthreadtypes.h \ - /usr/include/bits/sched.h \ /usr/include/sys/stat.h \ /usr/include/bits/stat.h \ /usr/include/sys/mman.h \ @@ -45,18 +46,19 @@ deps_scripts/basic/fixdep := \ /usr/include/wchar.h \ /usr/include/bits/wchar.h \ /usr/include/gconv.h \ - /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/stdarg.h \ + /usr/lib/gcc/i386-redhat-linux/4.0.1/include/stdarg.h \ /usr/include/bits/stdio_lim.h \ /usr/include/bits/sys_errlist.h \ /usr/include/bits/stdio.h \ - /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/limits.h \ - /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/syslimits.h \ + /usr/lib/gcc/i386-redhat-linux/4.0.1/include/limits.h \ + /usr/lib/gcc/i386-redhat-linux/4.0.1/include/syslimits.h \ /usr/include/limits.h \ /usr/include/bits/posix1_lim.h \ /usr/include/bits/local_lim.h \ /usr/include/linux/limits.h \ /usr/include/bits/posix2_lim.h \ /usr/include/ctype.h \ + /usr/include/arpa/inet.h \ /usr/include/netinet/in.h \ /usr/include/stdint.h \ /usr/include/sys/socket.h \ diff --git a/scripts/basic/.split-include.cmd b/scripts/basic/.split-include.cmd index e596a8729..b73a7c813 100644 --- a/scripts/basic/.split-include.cmd +++ b/scripts/basic/.split-include.cmd @@ -1,4 +1,4 @@ -cmd_scripts/basic/split-include := gcc -Wp,-MD,scripts/basic/.split-include.d -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -o scripts/basic/split-include scripts/basic/split-include.c +cmd_scripts/basic/split-include := gcc -Wp,-MD,scripts/basic/.split-include.d -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -o scripts/basic/split-include scripts/basic/split-include.c deps_scripts/basic/split-include := \ scripts/basic/split-include.c \ @@ -7,9 +7,10 @@ deps_scripts/basic/split-include := \ /usr/include/features.h \ /usr/include/sys/cdefs.h \ /usr/include/gnu/stubs.h \ - /usr/include/bits/types.h \ /usr/include/bits/wordsize.h \ - /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/stddef.h \ + /usr/include/gnu/stubs-32.h \ + /usr/include/bits/types.h \ + /usr/lib/gcc/i386-redhat-linux/4.0.1/include/stddef.h \ /usr/include/bits/typesizes.h \ /usr/include/time.h \ /usr/include/bits/stat.h \ @@ -22,14 +23,11 @@ deps_scripts/basic/split-include := \ /usr/include/bits/time.h \ /usr/include/sys/sysmacros.h \ /usr/include/bits/pthreadtypes.h \ - /usr/include/bits/sched.h \ /usr/include/ctype.h \ /usr/include/errno.h \ /usr/include/bits/errno.h \ /usr/include/linux/errno.h \ /usr/include/asm/errno.h \ - /usr/include/asm-generic/errno.h \ - /usr/include/asm-generic/errno-base.h \ /usr/include/fcntl.h \ /usr/include/bits/fcntl.h \ /usr/include/stdio.h \ @@ -38,7 +36,7 @@ deps_scripts/basic/split-include := \ /usr/include/wchar.h \ /usr/include/bits/wchar.h \ /usr/include/gconv.h \ - /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/stdarg.h \ + /usr/lib/gcc/i386-redhat-linux/4.0.1/include/stdarg.h \ /usr/include/bits/stdio_lim.h \ /usr/include/bits/sys_errlist.h \ /usr/include/bits/stdio.h \ diff --git a/scripts/basic/docproc b/scripts/basic/docproc index 51640ad93660a5e29ce19452befa76d58d827f84..939288420f5423503829a9e2f93da5b135ade1f3 100755 GIT binary patch literal 13404 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 literal 15691 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 OeD6)1ot}KH^8W%yQa%y@ diff --git a/scripts/basic/split-include b/scripts/basic/split-include index ecd686e99d025d2c3c9c70c36ec7ef64affb3e19..2e76d8ead012e1d95b22090c4280a2b062cc92b0 100755 GIT binary patch literal 7891 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 Cc9X3D literal 14592 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 dEZdO^=W;P_%BgRpir_={{bt)DqH{n diff --git a/scripts/kconfig/.conf.cmd b/scripts/kconfig/.conf.cmd index 4f007fa36..a09989cdf 100644 --- a/scripts/kconfig/.conf.cmd +++ b/scripts/kconfig/.conf.cmd @@ -1 +1 @@ -cmd_scripts/kconfig/conf := gcc -o scripts/kconfig/conf scripts/kconfig/conf.o -Wl,-rpath,\$$ORIGIN -Lscripts/kconfig -lkconfig +cmd_scripts/kconfig/conf := gcc -o scripts/kconfig/conf scripts/kconfig/conf.o scripts/kconfig/zconf.tab.o diff --git a/scripts/kconfig/.conf.o.cmd b/scripts/kconfig/.conf.o.cmd index 2c06e27ab..b04aab77b 100644 --- a/scripts/kconfig/.conf.o.cmd +++ b/scripts/kconfig/.conf.o.cmd @@ -3,13 +3,15 @@ cmd_scripts/kconfig/conf.o := gcc -Wp,-MD,scripts/kconfig/.conf.o.d -Wall -Wstri deps_scripts/kconfig/conf.o := \ scripts/kconfig/conf.c \ $(wildcard include/config/.h) \ + $(wildcard include/config/allconfig.h) \ /usr/include/ctype.h \ /usr/include/features.h \ /usr/include/sys/cdefs.h \ /usr/include/gnu/stubs.h \ - /usr/include/bits/types.h \ /usr/include/bits/wordsize.h \ - /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/stddef.h \ + /usr/include/gnu/stubs-32.h \ + /usr/include/bits/types.h \ + /usr/lib/gcc/i386-redhat-linux/4.0.1/include/stddef.h \ /usr/include/bits/typesizes.h \ /usr/include/endian.h \ /usr/include/bits/endian.h \ @@ -22,8 +24,17 @@ deps_scripts/kconfig/conf.o := \ /usr/include/bits/time.h \ /usr/include/sys/sysmacros.h \ /usr/include/bits/pthreadtypes.h \ - /usr/include/bits/sched.h \ /usr/include/alloca.h \ + /usr/include/stdio.h \ + /usr/include/libio.h \ + /usr/include/_G_config.h \ + /usr/include/wchar.h \ + /usr/include/bits/wchar.h \ + /usr/include/gconv.h \ + /usr/lib/gcc/i386-redhat-linux/4.0.1/include/stdarg.h \ + /usr/include/bits/stdio_lim.h \ + /usr/include/bits/sys_errlist.h \ + /usr/include/bits/stdio.h \ /usr/include/string.h \ /usr/include/bits/string.h \ /usr/include/bits/string2.h \ @@ -35,17 +46,10 @@ deps_scripts/kconfig/conf.o := \ /usr/include/bits/stat.h \ scripts/kconfig/lkc.h \ scripts/kconfig/expr.h \ - /usr/include/stdio.h \ - /usr/include/libio.h \ - /usr/include/_G_config.h \ - /usr/include/wchar.h \ - /usr/include/bits/wchar.h \ - /usr/include/gconv.h \ - /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/stdarg.h \ - /usr/include/bits/stdio_lim.h \ - /usr/include/bits/sys_errlist.h \ - /usr/include/bits/stdio.h \ - /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/stdbool.h \ + /usr/lib/gcc/i386-redhat-linux/4.0.1/include/stdbool.h \ + /usr/include/libintl.h \ + /usr/include/locale.h \ + /usr/include/bits/locale.h \ scripts/kconfig/lkc_proto.h \ scripts/kconfig/conf.o: $(deps_scripts/kconfig/conf.o) diff --git a/scripts/kconfig/.kxgettext.o.cmd b/scripts/kconfig/.kxgettext.o.cmd index 1ef4182d0..f05e92904 100644 --- a/scripts/kconfig/.kxgettext.o.cmd +++ b/scripts/kconfig/.kxgettext.o.cmd @@ -6,10 +6,11 @@ deps_scripts/kconfig/kxgettext.o := \ /usr/include/features.h \ /usr/include/sys/cdefs.h \ /usr/include/gnu/stubs.h \ - /usr/lib/gcc/i386-redhat-linux/3.4.2/include/stddef.h \ + /usr/include/bits/wordsize.h \ + /usr/include/gnu/stubs-32.h \ + /usr/lib/gcc/i386-redhat-linux/4.0.1/include/stddef.h \ /usr/include/sys/types.h \ /usr/include/bits/types.h \ - /usr/include/bits/wordsize.h \ /usr/include/bits/typesizes.h \ /usr/include/time.h \ /usr/include/endian.h \ @@ -20,7 +21,6 @@ deps_scripts/kconfig/kxgettext.o := \ /usr/include/bits/time.h \ /usr/include/sys/sysmacros.h \ /usr/include/bits/pthreadtypes.h \ - /usr/include/bits/sched.h \ /usr/include/alloca.h \ /usr/include/string.h \ /usr/include/bits/string.h \ @@ -33,11 +33,11 @@ deps_scripts/kconfig/kxgettext.o := \ /usr/include/wchar.h \ /usr/include/bits/wchar.h \ /usr/include/gconv.h \ - /usr/lib/gcc/i386-redhat-linux/3.4.2/include/stdarg.h \ + /usr/lib/gcc/i386-redhat-linux/4.0.1/include/stdarg.h \ /usr/include/bits/stdio_lim.h \ /usr/include/bits/sys_errlist.h \ /usr/include/bits/stdio.h \ - /usr/lib/gcc/i386-redhat-linux/3.4.2/include/stdbool.h \ + /usr/lib/gcc/i386-redhat-linux/4.0.1/include/stdbool.h \ /usr/include/libintl.h \ /usr/include/locale.h \ /usr/include/bits/locale.h \ diff --git a/scripts/kconfig/.mconf.o.cmd b/scripts/kconfig/.mconf.o.cmd index 6f874bf8c..bdd903011 100644 --- a/scripts/kconfig/.mconf.o.cmd +++ b/scripts/kconfig/.mconf.o.cmd @@ -2,12 +2,14 @@ cmd_scripts/kconfig/mconf.o := gcc -Wp,-MD,scripts/kconfig/.mconf.o.d -Wall -Wst deps_scripts/kconfig/mconf.o := \ scripts/kconfig/mconf.c \ - $(wildcard include/config/.h) \ $(wildcard include/config/mode.h) \ + $(wildcard include/config/.h) \ /usr/include/sys/ioctl.h \ /usr/include/features.h \ /usr/include/sys/cdefs.h \ /usr/include/gnu/stubs.h \ + /usr/include/bits/wordsize.h \ + /usr/include/gnu/stubs-32.h \ /usr/include/bits/ioctls.h \ /usr/include/asm/ioctls.h \ /usr/include/asm/ioctl.h \ @@ -17,8 +19,7 @@ deps_scripts/kconfig/mconf.o := \ /usr/include/signal.h \ /usr/include/bits/sigset.h \ /usr/include/bits/types.h \ - /usr/include/bits/wordsize.h \ - /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/stddef.h \ + /usr/lib/gcc/i386-redhat-linux/4.0.1/include/stddef.h \ /usr/include/bits/typesizes.h \ /usr/include/bits/signum.h \ /usr/include/time.h \ @@ -26,12 +27,8 @@ deps_scripts/kconfig/mconf.o := \ /usr/include/bits/sigaction.h \ /usr/include/bits/sigcontext.h \ /usr/include/asm/sigcontext.h \ - /usr/include/linux/compiler.h \ - /usr/include/linux/compiler-gcc3.h \ - /usr/include/linux/compiler-gcc.h \ /usr/include/bits/sigstack.h \ /usr/include/bits/pthreadtypes.h \ - /usr/include/bits/sched.h \ /usr/include/bits/sigthread.h \ /usr/include/sys/resource.h \ /usr/include/bits/resource.h \ @@ -45,22 +42,20 @@ deps_scripts/kconfig/mconf.o := \ /usr/include/bits/errno.h \ /usr/include/linux/errno.h \ /usr/include/asm/errno.h \ - /usr/include/asm-generic/errno.h \ - /usr/include/asm-generic/errno-base.h \ /usr/include/fcntl.h \ /usr/include/bits/fcntl.h \ /usr/include/sys/types.h \ /usr/include/sys/select.h \ /usr/include/bits/select.h \ /usr/include/sys/sysmacros.h \ - /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/limits.h \ - /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/syslimits.h \ + /usr/lib/gcc/i386-redhat-linux/4.0.1/include/limits.h \ + /usr/lib/gcc/i386-redhat-linux/4.0.1/include/syslimits.h \ /usr/include/limits.h \ /usr/include/bits/posix1_lim.h \ /usr/include/bits/local_lim.h \ /usr/include/linux/limits.h \ /usr/include/bits/posix2_lim.h \ - /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/stdarg.h \ + /usr/lib/gcc/i386-redhat-linux/4.0.1/include/stdarg.h \ /usr/include/stdlib.h \ /usr/include/alloca.h \ /usr/include/string.h \ @@ -72,6 +67,8 @@ deps_scripts/kconfig/mconf.o := \ /usr/include/bits/posix_opt.h \ /usr/include/bits/confname.h \ /usr/include/getopt.h \ + /usr/include/locale.h \ + /usr/include/bits/locale.h \ scripts/kconfig/lkc.h \ scripts/kconfig/expr.h \ /usr/include/stdio.h \ @@ -83,7 +80,8 @@ deps_scripts/kconfig/mconf.o := \ /usr/include/bits/stdio_lim.h \ /usr/include/bits/sys_errlist.h \ /usr/include/bits/stdio.h \ - /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/stdbool.h \ + /usr/lib/gcc/i386-redhat-linux/4.0.1/include/stdbool.h \ + /usr/include/libintl.h \ scripts/kconfig/lkc_proto.h \ scripts/kconfig/mconf.o: $(deps_scripts/kconfig/mconf.o) diff --git a/scripts/kconfig/.zconf.tab.o.cmd b/scripts/kconfig/.zconf.tab.o.cmd index 2a3661c06..b2e450deb 100644 --- a/scripts/kconfig/.zconf.tab.o.cmd +++ b/scripts/kconfig/.zconf.tab.o.cmd @@ -1,4 +1,4 @@ -cmd_scripts/kconfig/zconf.tab.o := gcc -Wp,-MD,scripts/kconfig/.zconf.tab.o.d -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -Iscripts/kconfig -fPIC -c -o scripts/kconfig/zconf.tab.o scripts/kconfig/zconf.tab.c +cmd_scripts/kconfig/zconf.tab.o := gcc -Wp,-MD,scripts/kconfig/.zconf.tab.o.d -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -Iscripts/kconfig -c -o scripts/kconfig/zconf.tab.o scripts/kconfig/zconf.tab.c deps_scripts/kconfig/zconf.tab.o := \ scripts/kconfig/zconf.tab.c \ @@ -6,13 +6,14 @@ deps_scripts/kconfig/zconf.tab.o := \ /usr/include/features.h \ /usr/include/sys/cdefs.h \ /usr/include/gnu/stubs.h \ - /usr/include/bits/types.h \ /usr/include/bits/wordsize.h \ - /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/stddef.h \ + /usr/include/gnu/stubs-32.h \ + /usr/include/bits/types.h \ + /usr/lib/gcc/i386-redhat-linux/4.0.1/include/stddef.h \ /usr/include/bits/typesizes.h \ /usr/include/endian.h \ /usr/include/bits/endian.h \ - /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/stdarg.h \ + /usr/lib/gcc/i386-redhat-linux/4.0.1/include/stdarg.h \ /usr/include/stdio.h \ /usr/include/libio.h \ /usr/include/_G_config.h \ @@ -31,24 +32,25 @@ deps_scripts/kconfig/zconf.tab.o := \ /usr/include/bits/time.h \ /usr/include/sys/sysmacros.h \ /usr/include/bits/pthreadtypes.h \ - /usr/include/bits/sched.h \ /usr/include/alloca.h \ /usr/include/string.h \ /usr/include/bits/string.h \ /usr/include/bits/string2.h \ - /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/stdbool.h \ + /usr/lib/gcc/i386-redhat-linux/4.0.1/include/stdbool.h \ scripts/kconfig/lkc.h \ scripts/kconfig/expr.h \ + /usr/include/libintl.h \ + /usr/include/locale.h \ + /usr/include/bits/locale.h \ scripts/kconfig/lkc_proto.h \ + scripts/kconfig/zconf.hash.c \ scripts/kconfig/lex.zconf.c \ /usr/include/errno.h \ /usr/include/bits/errno.h \ /usr/include/linux/errno.h \ /usr/include/asm/errno.h \ - /usr/include/asm-generic/errno.h \ - /usr/include/asm-generic/errno-base.h \ - /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/limits.h \ - /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/syslimits.h \ + /usr/lib/gcc/i386-redhat-linux/4.0.1/include/limits.h \ + /usr/lib/gcc/i386-redhat-linux/4.0.1/include/syslimits.h \ /usr/include/limits.h \ /usr/include/bits/posix1_lim.h \ /usr/include/bits/local_lim.h \ @@ -58,15 +60,24 @@ deps_scripts/kconfig/zconf.tab.o := \ /usr/include/bits/posix_opt.h \ /usr/include/bits/confname.h \ /usr/include/getopt.h \ + scripts/kconfig/lkc.h \ + scripts/kconfig/util.c \ + scripts/kconfig/lkc.h \ scripts/kconfig/confdata.c \ $(wildcard include/config/.h) \ + $(wildcard include/config/notimestamp.h) \ /usr/include/sys/stat.h \ /usr/include/bits/stat.h \ + scripts/kconfig/lkc.h \ scripts/kconfig/expr.c \ + scripts/kconfig/lkc.h \ scripts/kconfig/symbol.c \ + /usr/include/regex.h \ /usr/include/sys/utsname.h \ /usr/include/bits/utsname.h \ + scripts/kconfig/lkc.h \ scripts/kconfig/menu.c \ + scripts/kconfig/lkc.h \ scripts/kconfig/zconf.tab.o: $(deps_scripts/kconfig/zconf.tab.o) diff --git a/scripts/kconfig/conf b/scripts/kconfig/conf index 89b852e2f243ee2892596ec7ecd35607da6a7f80..3066bc9ebd412edb713c99b3509c7f8dc19b8000 100755 GIT binary patch literal 67464 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 z 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 N1Fz~#yU|Z>{vW^Sik<)f literal 20591 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 diff --git a/scripts/kconfig/conf.o b/scripts/kconfig/conf.o index c191a8a72cd7dc86b00872d436f45203e92698f7..fc7911451751f3d5917390039ba3ff2ed44769c2 100644 GIT binary patch literal 11136 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�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 UTLAbSfS=(`Aiz)sf((7Ye>iKSxBvhE diff --git a/scripts/kconfig/lex.zconf.c b/scripts/kconfig/lex.zconf.c index 22dda11f7..24e3c8cbb 100644 --- a/scripts/kconfig/lex.zconf.c +++ b/scripts/kconfig/lex.zconf.c @@ -1,5 +1,5 @@ -#line 3 "lex.zconf.c" +#line 3 "scripts/kconfig/lex.zconf.c" #define YY_INT_ALIGNED short int @@ -323,7 +323,7 @@ void zconffree (void * ); /* Begin user sect3 */ -#define zconfwrap(n) 1 +#define zconfwrap() 1 #define YY_SKIP_YYWRAP typedef unsigned char YY_CHAR; @@ -338,1567 +338,323 @@ int zconflineno = 1; extern char *zconftext; #define yytext_ptr zconftext -static yyconst flex_int16_t yy_nxt[][38] = +static yyconst flex_int16_t yy_nxt[][17] = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0 - }, - - { - 11, 12, 13, 14, 12, 12, 15, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12 - }, - - { - 11, 12, 13, 14, 12, 12, 15, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12 - }, - - { - 11, 16, 16, 17, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 18, 16, 16, 18, 18, 19, 20, - 21, 22, 18, 18, 23, 24, 18, 25, 18, 26, - 27, 18, 28, 29, 30, 18, 18, 16 - }, - - { - 11, 16, 16, 17, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 18, 16, 16, 18, 18, 19, 20, - 21, 22, 18, 18, 23, 24, 18, 25, 18, 26, - 27, 18, 28, 29, 30, 18, 18, 16 - - }, - - { - 11, 31, 32, 33, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31 - }, - - { - 11, 31, 32, 33, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31 - }, - - { - 11, 34, 34, 35, 34, 36, 34, 34, 36, 34, - 34, 34, 34, 34, 34, 37, 34, 34, 34, 34, - - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34 - }, - - { - 11, 34, 34, 35, 34, 36, 34, 34, 36, 34, - 34, 34, 34, 34, 34, 37, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34 - }, - - { - 11, 38, 38, 39, 40, 41, 42, 43, 41, 44, - 45, 46, 47, 47, 48, 49, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 50, 47, 47, 47, 51, - 47, 47, 47, 47, 47, 47, 47, 52 - - }, - - { - 11, 38, 38, 39, 40, 41, 42, 43, 41, 44, - 45, 46, 47, 47, 48, 49, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 50, 47, 47, 47, 51, - 47, 47, 47, 47, 47, 47, 47, 52 - }, - - { - -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, - -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, - -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, - -11, -11, -11, -11, -11, -11, -11, -11 - }, - - { - 11, -12, -12, -12, -12, -12, -12, -12, -12, -12, - -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, - - -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, - -12, -12, -12, -12, -12, -12, -12, -12 - }, - - { - 11, -13, 53, 54, -13, -13, 55, -13, -13, -13, - -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, - -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, - -13, -13, -13, -13, -13, -13, -13, -13 - }, - - { - 11, -14, -14, -14, -14, -14, -14, -14, -14, -14, - -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, - -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, - -14, -14, -14, -14, -14, -14, -14, -14 - - }, - - { - 11, 56, 56, 57, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56 - }, - - { - 11, -16, -16, -16, -16, -16, -16, -16, -16, -16, - -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, - -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, - -16, -16, -16, -16, -16, -16, -16, -16 - }, - - { - 11, -17, -17, -17, -17, -17, -17, -17, -17, -17, - -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, - - -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, - -17, -17, -17, -17, -17, -17, -17, -17 - }, - - { - 11, -18, -18, -18, -18, -18, -18, -18, -18, -18, - -18, -18, -18, 58, -18, -18, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -18 - }, - - { - 11, -19, -19, -19, -19, -19, -19, -19, -19, -19, - -19, -19, -19, 58, -19, -19, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 59, - 58, 58, 58, 58, 58, 58, 58, -19 - - }, - - { - 11, -20, -20, -20, -20, -20, -20, -20, -20, -20, - -20, -20, -20, 58, -20, -20, 58, 58, 58, 58, - 58, 58, 58, 58, 60, 58, 58, 58, 58, 61, - 58, 58, 58, 58, 58, 58, 58, -20 - }, - - { - 11, -21, -21, -21, -21, -21, -21, -21, -21, -21, - -21, -21, -21, 58, -21, -21, 58, 58, 58, 58, - 58, 62, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -21 - }, - - { - 11, -22, -22, -22, -22, -22, -22, -22, -22, -22, - -22, -22, -22, 58, -22, -22, 58, 58, 58, 58, - - 58, 58, 58, 58, 58, 58, 58, 58, 63, 58, - 58, 58, 58, 58, 58, 58, 58, -22 - }, - - { - 11, -23, -23, -23, -23, -23, -23, -23, -23, -23, - -23, -23, -23, 58, -23, -23, 58, 58, 58, 58, - 58, 64, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -23 - }, - - { - 11, -24, -24, -24, -24, -24, -24, -24, -24, -24, - -24, -24, -24, 58, -24, -24, 58, 58, 58, 58, - 58, 58, 65, 58, 58, 58, 58, 58, 66, 58, - 58, 58, 58, 58, 58, 58, 58, -24 - - }, - - { - 11, -25, -25, -25, -25, -25, -25, -25, -25, -25, - -25, -25, -25, 58, -25, -25, 58, 67, 58, 58, - 58, 68, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -25 - }, - - { - 11, -26, -26, -26, -26, -26, -26, -26, -26, -26, - -26, -26, -26, 58, -26, -26, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 69, 58, 58, 58, 58, 58, 58, -26 - }, - - { - 11, -27, -27, -27, -27, -27, -27, -27, -27, -27, - -27, -27, -27, 58, -27, -27, 58, 58, 58, 58, - - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 70, 58, 58, 58, 58, -27 - }, - - { - 11, -28, -28, -28, -28, -28, -28, -28, -28, -28, - -28, -28, -28, 58, -28, -28, 58, 71, 58, 58, - 58, 72, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -28 - }, - - { - 11, -29, -29, -29, -29, -29, -29, -29, -29, -29, - -29, -29, -29, 58, -29, -29, 58, 58, 58, 58, - 58, 73, 58, 58, 58, 58, 58, 58, 58, 74, - 58, 58, 58, 58, 75, 58, 58, -29 - - }, - - { - 11, -30, -30, -30, -30, -30, -30, -30, -30, -30, - -30, -30, -30, 58, -30, -30, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 76, 58, 58, 58, 58, -30 - }, - - { - 11, 77, 77, -31, 77, 77, 77, 77, 77, 77, - 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, - 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, - 77, 77, 77, 77, 77, 77, 77, 77 - }, - - { - 11, -32, 78, 79, -32, -32, -32, -32, -32, -32, - -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, - - -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, - -32, -32, -32, -32, -32, -32, -32, -32 - }, - - { - 11, 80, -33, -33, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80 - }, - - { - 11, 81, 81, 82, 81, -34, 81, 81, -34, 81, - 81, 81, 81, 81, 81, -34, 81, 81, 81, 81, - 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, - 81, 81, 81, 81, 81, 81, 81, 81 - - }, - - { - 11, -35, -35, -35, -35, -35, -35, -35, -35, -35, - -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, - -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, - -35, -35, -35, -35, -35, -35, -35, -35 - }, - - { - 11, -36, -36, -36, -36, -36, -36, -36, -36, -36, - -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, - -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, - -36, -36, -36, -36, -36, -36, -36, -36 - }, - - { - 11, 83, 83, 84, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, - - 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83 - }, - - { - 11, -38, -38, -38, -38, -38, -38, -38, -38, -38, - -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, - -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, - -38, -38, -38, -38, -38, -38, -38, -38 - }, - - { - 11, -39, -39, -39, -39, -39, -39, -39, -39, -39, - -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, - -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, - -39, -39, -39, -39, -39, -39, -39, -39 - - }, - - { - 11, -40, -40, -40, -40, -40, -40, -40, -40, -40, - -40, -40, -40, -40, 85, -40, -40, -40, -40, -40, - -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, - -40, -40, -40, -40, -40, -40, -40, -40 - }, - - { - 11, -41, -41, -41, -41, -41, -41, -41, -41, -41, - -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, - -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, - -41, -41, -41, -41, -41, -41, -41, -41 - }, - - { - 11, 86, 86, -42, 86, 86, 86, 86, 86, 86, - 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, - - 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, - 86, 86, 86, 86, 86, 86, 86, 86 - }, - - { - 11, -43, -43, -43, -43, -43, -43, 87, -43, -43, - -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, - -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, - -43, -43, -43, -43, -43, -43, -43, -43 - }, - - { - 11, -44, -44, -44, -44, -44, -44, -44, -44, -44, - -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, - -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, - -44, -44, -44, -44, -44, -44, -44, -44 - - }, - - { - 11, -45, -45, -45, -45, -45, -45, -45, -45, -45, - -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, - -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, - -45, -45, -45, -45, -45, -45, -45, -45 - }, - - { - 11, -46, -46, -46, -46, -46, -46, -46, -46, -46, - -46, 88, 89, 89, -46, -46, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, -46 - }, - - { - 11, -47, -47, -47, -47, -47, -47, -47, -47, -47, - -47, 89, 89, 89, -47, -47, 89, 89, 89, 89, - - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, -47 - }, - - { - 11, -48, -48, -48, -48, -48, -48, -48, -48, -48, - -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, - -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, - -48, -48, -48, -48, -48, -48, -48, -48 - }, - - { - 11, -49, -49, 90, -49, -49, -49, -49, -49, -49, - -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, - -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, - -49, -49, -49, -49, -49, -49, -49, -49 - - }, - - { - 11, -50, -50, -50, -50, -50, -50, -50, -50, -50, - -50, 89, 89, 89, -50, -50, 89, 89, 89, 89, - 89, 89, 91, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, -50 - }, - - { - 11, -51, -51, -51, -51, -51, -51, -51, -51, -51, - -51, 89, 89, 89, -51, -51, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 92, 89, - 89, 89, 89, 89, 89, 89, 89, -51 - }, - - { - 11, -52, -52, -52, -52, -52, -52, -52, -52, -52, - -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, - - -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, - -52, -52, -52, -52, -52, -52, -52, 93 - }, - - { - 11, -53, 53, 54, -53, -53, 55, -53, -53, -53, - -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, - -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, - -53, -53, -53, -53, -53, -53, -53, -53 - }, - - { - 11, -54, -54, -54, -54, -54, -54, -54, -54, -54, - -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, - -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, - -54, -54, -54, -54, -54, -54, -54, -54 - - }, - - { - 11, 56, 56, 57, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56 - }, - - { - 11, 56, 56, 57, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56 - }, - - { - 11, -57, -57, -57, -57, -57, -57, -57, -57, -57, - -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, - - -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, - -57, -57, -57, -57, -57, -57, -57, -57 - }, - - { - 11, -58, -58, -58, -58, -58, -58, -58, -58, -58, - -58, -58, -58, 58, -58, -58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -58 - }, - - { - 11, -59, -59, -59, -59, -59, -59, -59, -59, -59, - -59, -59, -59, 58, -59, -59, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 94, - 58, 58, 58, 58, 58, 58, 58, -59 - - }, - - { - 11, -60, -60, -60, -60, -60, -60, -60, -60, -60, - -60, -60, -60, 58, -60, -60, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 95, - 58, 58, 58, 58, 58, 58, 58, -60 - }, - - { - 11, -61, -61, -61, -61, -61, -61, -61, -61, -61, - -61, -61, -61, 58, -61, -61, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 96, 97, 58, - 58, 58, 58, 58, 58, 58, 58, -61 - }, - - { - 11, -62, -62, -62, -62, -62, -62, -62, -62, -62, - -62, -62, -62, 58, -62, -62, 58, 58, 58, 58, - - 58, 58, 98, 58, 58, 58, 58, 58, 58, 58, - 99, 58, 58, 58, 58, 58, 58, -62 - }, - - { - 11, -63, -63, -63, -63, -63, -63, -63, -63, -63, - -63, -63, -63, 58, -63, -63, 58, 100, 58, 58, - 101, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -63 - }, - - { - 11, -64, -64, -64, -64, -64, -64, -64, -64, -64, - -64, -64, -64, 58, -64, -64, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 102, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 103, -64 - - }, - - { - 11, -65, -65, -65, -65, -65, -65, -65, -65, -65, - -65, -65, -65, 58, -65, -65, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -65 - }, - - { - 11, -66, -66, -66, -66, -66, -66, -66, -66, -66, - -66, -66, -66, 58, -66, -66, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 104, 58, 58, -66 - }, - - { - 11, -67, -67, -67, -67, -67, -67, -67, -67, -67, - -67, -67, -67, 58, -67, -67, 58, 58, 58, 58, - - 58, 58, 58, 58, 58, 105, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -67 - }, - - { - 11, -68, -68, -68, -68, -68, -68, -68, -68, -68, - -68, -68, -68, 58, -68, -68, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 106, 58, - 58, 58, 58, 58, 58, 58, 58, -68 - }, - - { - 11, -69, -69, -69, -69, -69, -69, -69, -69, -69, - -69, -69, -69, 58, -69, -69, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 107, 58, 58, -69 - - }, - - { - 11, -70, -70, -70, -70, -70, -70, -70, -70, -70, - -70, -70, -70, 58, -70, -70, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 108, - 58, 58, 58, 58, 58, 58, 58, -70 - }, - - { - 11, -71, -71, -71, -71, -71, -71, -71, -71, -71, - -71, -71, -71, 58, -71, -71, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 109, 58, - 58, 58, 58, 58, 58, 58, 58, -71 - }, - - { - 11, -72, -72, -72, -72, -72, -72, -72, -72, -72, - -72, -72, -72, 58, -72, -72, 58, 58, 58, 58, - - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 110, 58, 58, 58, 58, 58, -72 - }, - - { - 11, -73, -73, -73, -73, -73, -73, -73, -73, -73, - -73, -73, -73, 58, -73, -73, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 111, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -73 - }, - - { - 11, -74, -74, -74, -74, -74, -74, -74, -74, -74, - -74, -74, -74, 58, -74, -74, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 112, 58, -74 - - }, - - { - 11, -75, -75, -75, -75, -75, -75, -75, -75, -75, - -75, -75, -75, 58, -75, -75, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 113, 58, 58, 58, 58, -75 - }, - - { - 11, -76, -76, -76, -76, -76, -76, -76, -76, -76, - -76, -76, -76, 58, -76, -76, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 114, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -76 - }, - - { - 11, 77, 77, -77, 77, 77, 77, 77, 77, 77, - 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, - - 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, - 77, 77, 77, 77, 77, 77, 77, 77 - }, - - { - 11, -78, 78, 79, -78, -78, -78, -78, -78, -78, - -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, - -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, - -78, -78, -78, -78, -78, -78, -78, -78 - }, - - { - 11, 80, -79, -79, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80 - - }, - - { - 11, -80, -80, -80, -80, -80, -80, -80, -80, -80, - -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, - -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, - -80, -80, -80, -80, -80, -80, -80, -80 - }, - - { - 11, 81, 81, 82, 81, -81, 81, 81, -81, 81, - 81, 81, 81, 81, 81, -81, 81, 81, 81, 81, - 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, - 81, 81, 81, 81, 81, 81, 81, 81 - }, - - { - 11, -82, -82, -82, -82, -82, -82, -82, -82, -82, - -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, - - -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, - -82, -82, -82, -82, -82, -82, -82, -82 - }, - - { - 11, -83, -83, 84, -83, -83, -83, -83, -83, -83, - -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, - -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, - -83, -83, -83, -83, -83, -83, -83, -83 - }, - - { - 11, -84, -84, -84, -84, -84, -84, -84, -84, -84, - -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, - -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, - -84, -84, -84, -84, -84, -84, -84, -84 - - }, - - { - 11, -85, -85, -85, -85, -85, -85, -85, -85, -85, - -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, - -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, - -85, -85, -85, -85, -85, -85, -85, -85 - }, - - { - 11, 86, 86, -86, 86, 86, 86, 86, 86, 86, - 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, - 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, - 86, 86, 86, 86, 86, 86, 86, 86 - }, - - { - 11, -87, -87, -87, -87, -87, -87, -87, -87, -87, - -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, - - -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, - -87, -87, -87, -87, -87, -87, -87, -87 - }, - - { - 11, -88, -88, -88, -88, -88, -88, -88, -88, -88, - -88, 115, 89, 89, -88, -88, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, -88 - }, - - { - 11, -89, -89, -89, -89, -89, -89, -89, -89, -89, - -89, 89, 89, 89, -89, -89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, -89 - - }, - - { - 11, -90, -90, -90, -90, -90, -90, -90, -90, -90, - -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, - -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, - -90, -90, -90, -90, -90, -90, -90, -90 - }, - - { - 11, -91, -91, -91, -91, -91, -91, -91, -91, -91, - -91, 89, 89, 89, -91, -91, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, -91 - }, - - { - 11, -92, -92, -92, -92, -92, -92, -92, -92, -92, - -92, 89, 89, 89, -92, -92, 89, 89, 89, 89, - - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, -92 - }, - - { - 11, -93, -93, -93, -93, -93, -93, -93, -93, -93, - -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, - -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, - -93, -93, -93, -93, -93, -93, -93, -93 - }, - - { - 11, -94, -94, -94, -94, -94, -94, -94, -94, -94, - -94, -94, -94, 58, -94, -94, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 116, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -94 - - }, - - { - 11, -95, -95, -95, -95, -95, -95, -95, -95, -95, - -95, -95, -95, 58, -95, -95, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 117, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -95 - }, - - { - 11, -96, -96, -96, -96, -96, -96, -96, -96, -96, - -96, -96, -96, 58, -96, -96, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 118, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -96 - }, - - { - 11, -97, -97, -97, -97, -97, -97, -97, -97, -97, - -97, -97, -97, 58, -97, -97, 58, 58, 58, 58, - - 58, 58, 119, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -97 - }, - - { - 11, -98, -98, -98, -98, -98, -98, -98, -98, -98, - -98, -98, -98, 58, -98, -98, 120, 121, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -98 - }, - - { - 11, -99, -99, -99, -99, -99, -99, -99, -99, -99, - -99, -99, -99, 58, -99, -99, 58, 58, 58, 58, - 58, 122, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -99 - - }, - - { - 11, -100, -100, -100, -100, -100, -100, -100, -100, -100, - -100, -100, -100, 58, -100, -100, 58, 58, 123, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -100 - }, - - { - 11, -101, -101, -101, -101, -101, -101, -101, -101, -101, - -101, -101, -101, 58, -101, -101, 58, 58, 58, 124, - 58, 58, 58, 58, 58, 125, 58, 126, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -101 - }, - - { - 11, -102, -102, -102, -102, -102, -102, -102, -102, -102, - -102, -102, -102, 58, -102, -102, 58, 58, 58, 58, - - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 127, 58, 58, 58, 58, 58, 58, -102 - }, - - { - 11, -103, -103, -103, -103, -103, -103, -103, -103, -103, - -103, -103, -103, 58, -103, -103, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -103 - }, - - { - 11, -104, -104, -104, -104, -104, -104, -104, -104, -104, - -104, -104, -104, 58, -104, -104, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -104 - - }, - - { - 11, -105, -105, -105, -105, -105, -105, -105, -105, -105, - -105, -105, -105, 58, -105, -105, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 128, 58, - 58, 58, 58, 58, 58, 58, 58, -105 - }, - - { - 11, -106, -106, -106, -106, -106, -106, -106, -106, -106, - -106, -106, -106, 58, -106, -106, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 129, 58, -106 - }, - - { - 11, -107, -107, -107, -107, -107, -107, -107, -107, -107, - -107, -107, -107, 58, -107, -107, 58, 58, 58, 58, - - 58, 58, 58, 58, 58, 130, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -107 - }, - - { - 11, -108, -108, -108, -108, -108, -108, -108, -108, -108, - -108, -108, -108, 58, -108, -108, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 131, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -108 - }, - - { - 11, -109, -109, -109, -109, -109, -109, -109, -109, -109, - -109, -109, -109, 58, -109, -109, 58, 58, 58, 58, - 58, 58, 58, 132, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -109 - - }, - - { - 11, -110, -110, -110, -110, -110, -110, -110, -110, -110, - -110, -110, -110, 58, -110, -110, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 133, 58, -110 - }, - - { - 11, -111, -111, -111, -111, -111, -111, -111, -111, -111, - -111, -111, -111, 58, -111, -111, 58, 58, 58, 58, - 58, 134, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -111 - }, - - { - 11, -112, -112, -112, -112, -112, -112, -112, -112, -112, - -112, -112, -112, 58, -112, -112, 58, 58, 58, 58, - - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 135, 58, 58, 58, 58, -112 - }, - - { - 11, -113, -113, -113, -113, -113, -113, -113, -113, -113, - -113, -113, -113, 58, -113, -113, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 136, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -113 - }, - - { - 11, -114, -114, -114, -114, -114, -114, -114, -114, -114, - -114, -114, -114, 58, -114, -114, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 137, 58, 58, 58, -114 - - }, - - { - 11, -115, -115, -115, -115, -115, -115, -115, -115, -115, - -115, 89, 89, 89, -115, -115, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, -115 - }, - - { - 11, -116, -116, -116, -116, -116, -116, -116, -116, -116, - -116, -116, -116, 58, -116, -116, 58, 58, 58, 58, - 58, 138, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -116 - }, - - { - 11, -117, -117, -117, -117, -117, -117, -117, -117, -117, - -117, -117, -117, 58, -117, -117, 58, 58, 58, 139, - - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -117 - }, - - { - 11, -118, -118, -118, -118, -118, -118, -118, -118, -118, - -118, -118, -118, 58, -118, -118, 58, 58, 58, 58, - 58, 140, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -118 - }, - - { - 11, -119, -119, -119, -119, -119, -119, -119, -119, -119, - -119, -119, -119, 58, -119, -119, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 141, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -119 - - }, - - { - 11, -120, -120, -120, -120, -120, -120, -120, -120, -120, - -120, -120, -120, 58, -120, -120, 58, 58, 142, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 143, 58, 58, -120 - }, - - { - 11, -121, -121, -121, -121, -121, -121, -121, -121, -121, - -121, -121, -121, 58, -121, -121, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 144, 58, -121 - }, - - { - 11, -122, -122, -122, -122, -122, -122, -122, -122, -122, - -122, -122, -122, 58, -122, -122, 58, 58, 58, 58, - - 58, 58, 58, 58, 58, 58, 58, 58, 145, 58, - 58, 58, 58, 58, 58, 58, 58, -122 - }, - - { - 11, -123, -123, -123, -123, -123, -123, -123, -123, -123, - -123, -123, -123, 58, -123, -123, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 146, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -123 - }, - - { - 11, -124, -124, -124, -124, -124, -124, -124, -124, -124, - -124, -124, -124, 58, -124, -124, 58, 58, 58, 58, - 58, 58, 58, 58, 147, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -124 - - }, - - { - 11, -125, -125, -125, -125, -125, -125, -125, -125, -125, - -125, -125, -125, 58, -125, -125, 58, 58, 58, 58, - 58, 58, 148, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -125 - }, - - { - 11, -126, -126, -126, -126, -126, -126, -126, -126, -126, - -126, -126, -126, 58, -126, -126, 58, 58, 58, 58, - 58, 149, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -126 - }, - - { - 11, -127, -127, -127, -127, -127, -127, -127, -127, -127, - -127, -127, -127, 58, -127, -127, 58, 58, 58, 58, - - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -127 - }, - - { - 11, -128, -128, -128, -128, -128, -128, -128, -128, -128, - -128, -128, -128, 58, -128, -128, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 150, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -128 - }, - - { - 11, -129, -129, -129, -129, -129, -129, -129, -129, -129, - -129, -129, -129, 58, -129, -129, 58, 58, 58, 151, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -129 - - }, - - { - 11, -130, -130, -130, -130, -130, -130, -130, -130, -130, - -130, -130, -130, 58, -130, -130, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 152, - 58, 58, 58, 58, 58, 58, 58, -130 - }, - - { - 11, -131, -131, -131, -131, -131, -131, -131, -131, -131, - -131, -131, -131, 58, -131, -131, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 153, 58, 58, 58, 58, 58, 58, -131 - }, - - { - 11, -132, -132, -132, -132, -132, -132, -132, -132, -132, - -132, -132, -132, 58, -132, -132, 58, 58, 58, 58, - - 58, 154, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -132 - }, - - { - 11, -133, -133, -133, -133, -133, -133, -133, -133, -133, - -133, -133, -133, 58, -133, -133, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 155, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -133 - }, - - { - 11, -134, -134, -134, -134, -134, -134, -134, -134, -134, - -134, -134, -134, 58, -134, -134, 58, 58, 58, 156, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -134 - - }, - - { - 11, -135, -135, -135, -135, -135, -135, -135, -135, -135, - -135, -135, -135, 58, -135, -135, 58, 58, 58, 157, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -135 - }, - - { - 11, -136, -136, -136, -136, -136, -136, -136, -136, -136, - -136, -136, -136, 58, -136, -136, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 158, 58, - 58, 58, 58, 58, 58, 58, 58, -136 - }, - - { - 11, -137, -137, -137, -137, -137, -137, -137, -137, -137, - -137, -137, -137, 58, -137, -137, 58, 58, 58, 58, - - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 159, 58, 58, -137 - }, - - { - 11, -138, -138, -138, -138, -138, -138, -138, -138, -138, - -138, -138, -138, 58, -138, -138, 58, 160, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -138 - }, - - { - 11, -139, -139, -139, -139, -139, -139, -139, -139, -139, - -139, -139, -139, 58, -139, -139, 58, 58, 58, 58, - 58, 161, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -139 - - }, - - { - 11, -140, -140, -140, -140, -140, -140, -140, -140, -140, - -140, -140, -140, 58, -140, -140, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 162, 58, - 58, 58, 58, 58, 58, 58, 58, -140 - }, - - { - 11, -141, -141, -141, -141, -141, -141, -141, -141, -141, - -141, -141, -141, 58, -141, -141, 58, 58, 58, 58, - 58, 58, 58, 163, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -141 - }, - - { - 11, -142, -142, -142, -142, -142, -142, -142, -142, -142, - -142, -142, -142, 58, -142, -142, 58, 58, 58, 58, - - 58, 58, 58, 58, 58, 58, 58, 58, 58, 164, - 58, 58, 58, 58, 58, 58, 58, -142 - }, - - { - 11, -143, -143, -143, -143, -143, -143, -143, -143, -143, - -143, -143, -143, 58, -143, -143, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 165, 58, 58, 58, 58, -143 - }, - - { - 11, -144, -144, -144, -144, -144, -144, -144, -144, -144, - -144, -144, -144, 58, -144, -144, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 166, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -144 - - }, - - { - 11, -145, -145, -145, -145, -145, -145, -145, -145, -145, - -145, -145, -145, 58, -145, -145, 58, 58, 58, 58, - 167, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -145 - }, - - { - 11, -146, -146, -146, -146, -146, -146, -146, -146, -146, - -146, -146, -146, 58, -146, -146, 58, 58, 58, 58, - 58, 168, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -146 - }, - - { - 11, -147, -147, -147, -147, -147, -147, -147, -147, -147, - -147, -147, -147, 58, -147, -147, 58, 58, 58, 58, - - 58, 58, 58, 58, 58, 58, 58, 58, 58, 169, - 58, 58, 58, 58, 58, 58, 58, -147 - }, - - { - 11, -148, -148, -148, -148, -148, -148, -148, -148, -148, - -148, -148, -148, 58, -148, -148, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -148 - }, - - { - 11, -149, -149, -149, -149, -149, -149, -149, -149, -149, - -149, -149, -149, 58, -149, -149, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 170, 58, - 58, 58, 58, 58, 58, 58, 58, -149 - - }, - - { - 11, -150, -150, -150, -150, -150, -150, -150, -150, -150, - -150, -150, -150, 58, -150, -150, 58, 58, 58, 58, - 58, 171, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -150 + 0, 0, 0, 0, 0, 0, 0 }, { - 11, -151, -151, -151, -151, -151, -151, -151, -151, -151, - -151, -151, -151, 58, -151, -151, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 172, - 58, 58, 58, 58, 58, 58, 58, -151 + 11, 12, 13, 14, 12, 12, 15, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12 }, { - 11, -152, -152, -152, -152, -152, -152, -152, -152, -152, - -152, -152, -152, 58, -152, -152, 58, 58, 58, 58, - - 58, 58, 58, 58, 58, 58, 58, 58, 173, 58, - 58, 58, 58, 58, 58, 58, 58, -152 + 11, 12, 13, 14, 12, 12, 15, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12 }, { - 11, -153, -153, -153, -153, -153, -153, -153, -153, -153, - -153, -153, -153, 58, -153, -153, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 174, 58, 58, -153 + 11, 16, 16, 17, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 18, 16, 16, 16 }, { - 11, -154, -154, -154, -154, -154, -154, -154, -154, -154, - -154, -154, -154, 58, -154, -154, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -154 + 11, 16, 16, 17, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 18, 16, 16, 16 }, { - 11, -155, -155, -155, -155, -155, -155, -155, -155, -155, - -155, -155, -155, 58, -155, -155, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 175, 58, 58, 58, 58, -155 + 11, 19, 20, 21, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19 }, { - 11, -156, -156, -156, -156, -156, -156, -156, -156, -156, - -156, -156, -156, 58, -156, -156, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 176, 58, 58, -156 + 11, 19, 20, 21, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19 }, { - 11, -157, -157, -157, -157, -157, -157, -157, -157, -157, - -157, -157, -157, 58, -157, -157, 58, 58, 58, 58, - - 58, 177, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -157 + 11, 22, 22, 23, 22, 24, 22, 22, 24, 22, + 22, 22, 22, 22, 22, 25, 22 }, { - 11, -158, -158, -158, -158, -158, -158, -158, -158, -158, - -158, -158, -158, 58, -158, -158, 58, 58, 58, 58, - 58, 58, 58, 178, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -158 + 11, 22, 22, 23, 22, 24, 22, 22, 24, 22, + 22, 22, 22, 22, 22, 25, 22 }, { - 11, -159, -159, -159, -159, -159, -159, -159, -159, -159, - -159, -159, -159, 58, -159, -159, 58, 179, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -159 + 11, 26, 26, 27, 28, 29, 30, 31, 29, 32, + 33, 34, 35, 35, 36, 37, 38 }, { - 11, -160, -160, -160, -160, -160, -160, -160, -160, -160, - -160, -160, -160, 58, -160, -160, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 180, 58, - 58, 58, 58, 58, 58, 58, 58, -160 + 11, 26, 26, 27, 28, 29, 30, 31, 29, 32, + 33, 34, 35, 35, 36, 37, 38 }, { - 11, -161, -161, -161, -161, -161, -161, -161, -161, -161, - -161, -161, -161, 58, -161, -161, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -161 + -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, + -11, -11, -11, -11, -11, -11, -11 }, { - 11, -162, -162, -162, -162, -162, -162, -162, -162, -162, - -162, -162, -162, 58, -162, -162, 58, 58, 58, 58, - - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 181, 58, 58, -162 + 11, -12, -12, -12, -12, -12, -12, -12, -12, -12, + -12, -12, -12, -12, -12, -12, -12 }, { - 11, -163, -163, -163, -163, -163, -163, -163, -163, -163, - -163, -163, -163, 58, -163, -163, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -163 + 11, -13, 39, 40, -13, -13, 41, -13, -13, -13, + -13, -13, -13, -13, -13, -13, -13 }, { - 11, -164, -164, -164, -164, -164, -164, -164, -164, -164, - -164, -164, -164, 58, -164, -164, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 182, - 58, 58, 58, 58, 58, 58, 58, -164 + 11, -14, -14, -14, -14, -14, -14, -14, -14, -14, + -14, -14, -14, -14, -14, -14, -14 }, { - 11, -165, -165, -165, -165, -165, -165, -165, -165, -165, - -165, -165, -165, 58, -165, -165, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 183, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -165 + 11, 42, 42, 43, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42 }, { - 11, -166, -166, -166, -166, -166, -166, -166, -166, -166, - -166, -166, -166, 58, -166, -166, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 184, 58, 58, -166 + 11, -16, -16, -16, -16, -16, -16, -16, -16, -16, + -16, -16, -16, -16, -16, -16, -16 }, { - 11, -167, -167, -167, -167, -167, -167, -167, -167, -167, - -167, -167, -167, 58, -167, -167, 58, 58, 58, 58, - - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 185, 58, 58, 58, -167 + 11, -17, -17, -17, -17, -17, -17, -17, -17, -17, + -17, -17, -17, -17, -17, -17, -17 }, { - 11, -168, -168, -168, -168, -168, -168, -168, -168, -168, - -168, -168, -168, 58, -168, -168, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -168 + 11, -18, -18, -18, -18, -18, -18, -18, -18, -18, + -18, -18, -18, 44, -18, -18, -18 }, { - 11, -169, -169, -169, -169, -169, -169, -169, -169, -169, - -169, -169, -169, 58, -169, -169, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 186, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -169 + 11, 45, 45, -19, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45 }, { - 11, -170, -170, -170, -170, -170, -170, -170, -170, -170, - -170, -170, -170, 58, -170, -170, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 187, 58, -170 + 11, -20, 46, 47, -20, -20, -20, -20, -20, -20, + -20, -20, -20, -20, -20, -20, -20 }, { - 11, -171, -171, -171, -171, -171, -171, -171, -171, -171, - -171, -171, -171, 58, -171, -171, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 188, 58, - 58, 58, 58, 58, 58, 58, 58, -171 + 11, 48, -21, -21, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48 }, { - 11, -172, -172, -172, -172, -172, -172, -172, -172, -172, - -172, -172, -172, 58, -172, -172, 58, 58, 58, 58, - - 58, 58, 58, 58, 58, 58, 58, 58, 189, 58, - 58, 58, 58, 58, 58, 58, 58, -172 + 11, 49, 49, 50, 49, -22, 49, 49, -22, 49, + 49, 49, 49, 49, 49, -22, 49 }, { - 11, -173, -173, -173, -173, -173, -173, -173, -173, -173, - -173, -173, -173, 58, -173, -173, 58, 190, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -173 + 11, -23, -23, -23, -23, -23, -23, -23, -23, -23, + -23, -23, -23, -23, -23, -23, -23 }, { - 11, -174, -174, -174, -174, -174, -174, -174, -174, -174, - -174, -174, -174, 58, -174, -174, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -174 + 11, -24, -24, -24, -24, -24, -24, -24, -24, -24, + -24, -24, -24, -24, -24, -24, -24 }, { - 11, -175, -175, -175, -175, -175, -175, -175, -175, -175, - -175, -175, -175, 58, -175, -175, 58, 58, 58, 58, - 58, 191, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -175 + 11, 51, 51, 52, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51 }, { - 11, -176, -176, -176, -176, -176, -176, -176, -176, -176, - -176, -176, -176, 58, -176, -176, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -176 + 11, -26, -26, -26, -26, -26, -26, -26, -26, -26, + -26, -26, -26, -26, -26, -26, -26 }, { - 11, -177, -177, -177, -177, -177, -177, -177, -177, -177, - -177, -177, -177, 58, -177, -177, 58, 58, 58, 58, - - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -177 + 11, -27, -27, -27, -27, -27, -27, -27, -27, -27, + -27, -27, -27, -27, -27, -27, -27 }, { - 11, -178, -178, -178, -178, -178, -178, -178, -178, -178, - -178, -178, -178, 58, -178, -178, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -178 + 11, -28, -28, -28, -28, -28, -28, -28, -28, -28, + -28, -28, -28, -28, 53, -28, -28 }, { - 11, -179, -179, -179, -179, -179, -179, -179, -179, -179, - -179, -179, -179, 58, -179, -179, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 192, 58, 58, -179 + 11, -29, -29, -29, -29, -29, -29, -29, -29, -29, + -29, -29, -29, -29, -29, -29, -29 }, { - 11, -180, -180, -180, -180, -180, -180, -180, -180, -180, - -180, -180, -180, 58, -180, -180, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -180 + 11, 54, 54, -30, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54 }, { - 11, -181, -181, -181, -181, -181, -181, -181, -181, -181, - -181, -181, -181, 58, -181, -181, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -181 + 11, -31, -31, -31, -31, -31, -31, 55, -31, -31, + -31, -31, -31, -31, -31, -31, -31 }, { - 11, -182, -182, -182, -182, -182, -182, -182, -182, -182, - -182, -182, -182, 58, -182, -182, 58, 58, 58, 58, - - 58, 58, 58, 58, 58, 58, 193, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -182 + 11, -32, -32, -32, -32, -32, -32, -32, -32, -32, + -32, -32, -32, -32, -32, -32, -32 }, { - 11, -183, -183, -183, -183, -183, -183, -183, -183, -183, - -183, -183, -183, 58, -183, -183, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 194, 58, 58, 58, -183 + 11, -33, -33, -33, -33, -33, -33, -33, -33, -33, + -33, -33, -33, -33, -33, -33, -33 }, { - 11, -184, -184, -184, -184, -184, -184, -184, -184, -184, - -184, -184, -184, 58, -184, -184, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -184 + 11, -34, -34, -34, -34, -34, -34, -34, -34, -34, + -34, 56, 57, 57, -34, -34, -34 }, { - 11, -185, -185, -185, -185, -185, -185, -185, -185, -185, - -185, -185, -185, 58, -185, -185, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -185 + 11, -35, -35, -35, -35, -35, -35, -35, -35, -35, + -35, 57, 57, 57, -35, -35, -35 }, { - 11, -186, -186, -186, -186, -186, -186, -186, -186, -186, - -186, -186, -186, 58, -186, -186, 58, 58, 58, 195, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -186 + 11, -36, -36, -36, -36, -36, -36, -36, -36, -36, + -36, -36, -36, -36, -36, -36, -36 }, { - 11, -187, -187, -187, -187, -187, -187, -187, -187, -187, - -187, -187, -187, 58, -187, -187, 58, 58, 58, 58, - - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -187 + 11, -37, -37, 58, -37, -37, -37, -37, -37, -37, + -37, -37, -37, -37, -37, -37, -37 }, { - 11, -188, -188, -188, -188, -188, -188, -188, -188, -188, - -188, -188, -188, 58, -188, -188, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 196, 58, -188 + 11, -38, -38, -38, -38, -38, -38, -38, -38, -38, + -38, -38, -38, -38, -38, -38, 59 }, { - 11, -189, -189, -189, -189, -189, -189, -189, -189, -189, - -189, -189, -189, 58, -189, -189, 58, 58, 58, 58, - 58, 58, 197, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -189 + 11, -39, 39, 40, -39, -39, 41, -39, -39, -39, + -39, -39, -39, -39, -39, -39, -39 }, { - 11, -190, -190, -190, -190, -190, -190, -190, -190, -190, - -190, -190, -190, 58, -190, -190, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 198, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -190 + 11, -40, -40, -40, -40, -40, -40, -40, -40, -40, + -40, -40, -40, -40, -40, -40, -40 }, { - 11, -191, -191, -191, -191, -191, -191, -191, -191, -191, - -191, -191, -191, 58, -191, -191, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 199, 58, 58, 58, -191 + 11, 42, 42, 43, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42 }, { - 11, -192, -192, -192, -192, -192, -192, -192, -192, -192, - -192, -192, -192, 58, -192, -192, 58, 58, 58, 58, - - 58, 200, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -192 + 11, 42, 42, 43, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42 }, { - 11, -193, -193, -193, -193, -193, -193, -193, -193, -193, - -193, -193, -193, 58, -193, -193, 58, 58, 58, 58, - 58, 201, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -193 + 11, -43, -43, -43, -43, -43, -43, -43, -43, -43, + -43, -43, -43, -43, -43, -43, -43 }, { - 11, -194, -194, -194, -194, -194, -194, -194, -194, -194, - -194, -194, -194, 58, -194, -194, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 202, 58, 58, -194 + 11, -44, -44, -44, -44, -44, -44, -44, -44, -44, + -44, -44, -44, 44, -44, -44, -44 }, { - 11, -195, -195, -195, -195, -195, -195, -195, -195, -195, - -195, -195, -195, 58, -195, -195, 58, 58, 58, 58, - 58, 203, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -195 + 11, 45, 45, -45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45 }, { - 11, -196, -196, -196, -196, -196, -196, -196, -196, -196, - -196, -196, -196, 58, -196, -196, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -196 + 11, -46, 46, 47, -46, -46, -46, -46, -46, -46, + -46, -46, -46, -46, -46, -46, -46 }, { - 11, -197, -197, -197, -197, -197, -197, -197, -197, -197, - -197, -197, -197, 58, -197, -197, 58, 58, 58, 58, - - 58, 58, 58, 58, 58, 204, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -197 + 11, 48, -47, -47, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48 }, { - 11, -198, -198, -198, -198, -198, -198, -198, -198, -198, - -198, -198, -198, 58, -198, -198, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -198 + 11, -48, -48, -48, -48, -48, -48, -48, -48, -48, + -48, -48, -48, -48, -48, -48, -48 }, { - 11, -199, -199, -199, -199, -199, -199, -199, -199, -199, - -199, -199, -199, 58, -199, -199, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -199 + 11, 49, 49, 50, 49, -49, 49, 49, -49, 49, + 49, 49, 49, 49, 49, -49, 49 }, { - 11, -200, -200, -200, -200, -200, -200, -200, -200, -200, - -200, -200, -200, 58, -200, -200, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -200 + 11, -50, -50, -50, -50, -50, -50, -50, -50, -50, + -50, -50, -50, -50, -50, -50, -50 }, { - 11, -201, -201, -201, -201, -201, -201, -201, -201, -201, - -201, -201, -201, 58, -201, -201, 58, 205, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -201 + 11, -51, -51, 52, -51, -51, -51, -51, -51, -51, + -51, -51, -51, -51, -51, -51, -51 }, { - 11, -202, -202, -202, -202, -202, -202, -202, -202, -202, - -202, -202, -202, 58, -202, -202, 58, 206, 58, 58, - - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -202 + 11, -52, -52, -52, -52, -52, -52, -52, -52, -52, + -52, -52, -52, -52, -52, -52, -52 }, { - 11, -203, -203, -203, -203, -203, -203, -203, -203, -203, - -203, -203, -203, 58, -203, -203, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -203 + 11, -53, -53, -53, -53, -53, -53, -53, -53, -53, + -53, -53, -53, -53, -53, -53, -53 }, { - 11, -204, -204, -204, -204, -204, -204, -204, -204, -204, - -204, -204, -204, 58, -204, -204, 58, 58, 58, 58, - 58, 58, 58, 207, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -204 + 11, 54, 54, -54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54 }, { - 11, -205, -205, -205, -205, -205, -205, -205, -205, -205, - -205, -205, -205, 58, -205, -205, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 208, 58, - 58, 58, 58, 58, 58, 58, 58, -205 + 11, -55, -55, -55, -55, -55, -55, -55, -55, -55, + -55, -55, -55, -55, -55, -55, -55 }, { - 11, -206, -206, -206, -206, -206, -206, -206, -206, -206, - -206, -206, -206, 58, -206, -206, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 209, 58, 58, -206 + 11, -56, -56, -56, -56, -56, -56, -56, -56, -56, + -56, 60, 57, 57, -56, -56, -56 }, { - 11, -207, -207, -207, -207, -207, -207, -207, -207, -207, - -207, -207, -207, 58, -207, -207, 58, 58, 58, 58, - - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -207 + 11, -57, -57, -57, -57, -57, -57, -57, -57, -57, + -57, 57, 57, 57, -57, -57, -57 }, { - 11, -208, -208, -208, -208, -208, -208, -208, -208, -208, - -208, -208, -208, 58, -208, -208, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -208 + 11, -58, -58, -58, -58, -58, -58, -58, -58, -58, + -58, -58, -58, -58, -58, -58, -58 }, { - 11, -209, -209, -209, -209, -209, -209, -209, -209, -209, - -209, -209, -209, 58, -209, -209, 58, 58, 58, 58, - 58, 210, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -209 + 11, -59, -59, -59, -59, -59, -59, -59, -59, -59, + -59, -59, -59, -59, -59, -59, -59 }, { - 11, -210, -210, -210, -210, -210, -210, -210, -210, -210, - -210, -210, -210, 58, -210, -210, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, -210 + 11, -60, -60, -60, -60, -60, -60, -60, -60, -60, + -60, 57, 57, 57, -60, -60, -60 }, } ; @@ -1918,8 +674,8 @@ static void yy_fatal_error (yyconst char msg[] ); *yy_cp = '\0'; \ (yy_c_buf_p) = yy_cp; -#define YY_NUM_RULES 64 -#define YY_END_OF_BUFFER 65 +#define YY_NUM_RULES 33 +#define YY_END_OF_BUFFER 34 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info @@ -1927,31 +683,14 @@ struct yy_trans_info flex_int32_t yy_verify; flex_int32_t yy_nxt; }; -static yyconst flex_int16_t yy_accept[211] = +static yyconst flex_int16_t yy_accept[61] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 65, 5, 4, 3, 2, 36, 37, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 63, 60, 62, 55, 59, 58, 57, 53, 48, 42, - 47, 51, 53, 40, 41, 50, 50, 43, 53, 50, - 50, 53, 4, 3, 2, 2, 1, 35, 35, 35, - 35, 35, 35, 35, 16, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 63, 60, 62, 61, - 55, 54, 57, 56, 44, 51, 38, 50, 50, 52, - 45, 46, 39, 35, 35, 35, 35, 35, 35, 35, - - 35, 35, 30, 29, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 49, 25, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 15, 35, 7, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 17, 35, 35, - 35, 35, 35, 34, 35, 35, 35, 35, 35, 35, - 10, 35, 13, 35, 35, 35, 35, 33, 35, 35, - 35, 35, 35, 22, 35, 32, 9, 31, 35, 26, - 12, 35, 35, 21, 18, 35, 8, 35, 35, 35, - 35, 35, 27, 35, 35, 6, 35, 20, 19, 23, - - 35, 35, 11, 35, 35, 35, 14, 28, 35, 24 + 34, 5, 4, 2, 3, 7, 8, 6, 32, 29, + 31, 24, 28, 27, 26, 22, 17, 13, 16, 20, + 22, 11, 12, 19, 19, 14, 22, 22, 4, 2, + 3, 3, 1, 6, 32, 29, 31, 30, 24, 23, + 26, 25, 15, 20, 9, 19, 19, 21, 10, 18 } ; static yyconst flex_int32_t yy_ec[256] = @@ -1965,11 +704,11 @@ static yyconst flex_int32_t yy_ec[256] = 14, 1, 1, 1, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 1, 15, 1, 1, 16, 1, 17, 18, 19, 20, + 1, 15, 1, 1, 13, 1, 13, 13, 13, 13, - 21, 22, 23, 24, 25, 13, 13, 26, 27, 28, - 29, 30, 31, 32, 33, 34, 35, 13, 13, 36, - 13, 13, 1, 37, 1, 1, 1, 1, 1, 1, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 1, 16, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -2014,8 +753,12 @@ char *zconftext; #define START_STRSIZE 16 -char *text; -static char *text_ptr; +static struct { + struct file *file; + int lineno; +} current_pos; + +static char *text; static int text_size, text_asize; struct buffer { @@ -2028,29 +771,28 @@ struct buffer *current_buf; static int last_ts, first_ts; static void zconf_endhelp(void); -static struct buffer *zconf_endfile(void); +static void zconf_endfile(void); void new_string(void) { text = malloc(START_STRSIZE); text_asize = START_STRSIZE; - text_ptr = text; text_size = 0; - *text_ptr = 0; + *text = 0; } void append_string(const char *str, int size) { int new_size = text_size + size + 1; if (new_size > text_asize) { + new_size += START_STRSIZE - 1; + new_size &= -START_STRSIZE; text = realloc(text, new_size); text_asize = new_size; - text_ptr = text + text_size; } - memcpy(text_ptr, str, size); - text_ptr += size; + memcpy(text + text_size, str, size); text_size += size; - *text_ptr = 0; + text[text_size] = 0; } void alloc_string(const char *str, int size) @@ -2066,11 +808,13 @@ void alloc_string(const char *str, int size) #define STRING 3 #define PARAM 4 +#ifndef YY_NO_UNISTD_H /* Special case for "unistd.h", since it is non-ANSI. We include it way * down here because we want the user's section 1 to have been scanned first. * The user has a chance to override it with an option. */ #include +#endif #ifndef YY_EXTRA_TYPE #define YY_EXTRA_TYPE void * @@ -2254,17 +998,17 @@ do_action: /* This label is used only to access EOF actions. */ { /* beginning of action switch */ case 1: /* rule 1 can match eol */ -YY_RULE_SETUP -current_file->lineno++; - YY_BREAK case 2: +/* rule 2 can match eol */ YY_RULE_SETUP - +{ + current_file->lineno++; + return T_EOL; +} YY_BREAK case 3: -/* rule 3 can match eol */ YY_RULE_SETUP -current_file->lineno++; return T_EOL; + YY_BREAK case 4: YY_RULE_SETUP @@ -2282,175 +1026,63 @@ YY_RULE_SETUP case 6: YY_RULE_SETUP -BEGIN(PARAM); return T_MAINMENU; - YY_BREAK -case 7: -YY_RULE_SETUP -BEGIN(PARAM); return T_MENU; - YY_BREAK -case 8: -YY_RULE_SETUP -BEGIN(PARAM); return T_ENDMENU; - YY_BREAK -case 9: -YY_RULE_SETUP -BEGIN(PARAM); return T_SOURCE; - YY_BREAK -case 10: -YY_RULE_SETUP -BEGIN(PARAM); return T_CHOICE; - YY_BREAK -case 11: -YY_RULE_SETUP -BEGIN(PARAM); return T_ENDCHOICE; - YY_BREAK -case 12: -YY_RULE_SETUP -BEGIN(PARAM); return T_COMMENT; - YY_BREAK -case 13: -YY_RULE_SETUP -BEGIN(PARAM); return T_CONFIG; - YY_BREAK -case 14: -YY_RULE_SETUP -BEGIN(PARAM); return T_MENUCONFIG; - YY_BREAK -case 15: -YY_RULE_SETUP -BEGIN(PARAM); return T_HELP; - YY_BREAK -case 16: -YY_RULE_SETUP -BEGIN(PARAM); return T_IF; - YY_BREAK -case 17: -YY_RULE_SETUP -BEGIN(PARAM); return T_ENDIF; - YY_BREAK -case 18: -YY_RULE_SETUP -BEGIN(PARAM); return T_DEPENDS; - YY_BREAK -case 19: -YY_RULE_SETUP -BEGIN(PARAM); return T_REQUIRES; - YY_BREAK -case 20: -YY_RULE_SETUP -BEGIN(PARAM); return T_OPTIONAL; - YY_BREAK -case 21: -YY_RULE_SETUP -BEGIN(PARAM); return T_DEFAULT; - YY_BREAK -case 22: -YY_RULE_SETUP -BEGIN(PARAM); return T_PROMPT; - YY_BREAK -case 23: -YY_RULE_SETUP -BEGIN(PARAM); return T_TRISTATE; - YY_BREAK -case 24: -YY_RULE_SETUP -BEGIN(PARAM); return T_DEF_TRISTATE; - YY_BREAK -case 25: -YY_RULE_SETUP -BEGIN(PARAM); return T_BOOLEAN; - YY_BREAK -case 26: -YY_RULE_SETUP -BEGIN(PARAM); return T_BOOLEAN; - YY_BREAK -case 27: -YY_RULE_SETUP -BEGIN(PARAM); return T_DEF_BOOLEAN; - YY_BREAK -case 28: -YY_RULE_SETUP -BEGIN(PARAM); return T_DEF_BOOLEAN; - YY_BREAK -case 29: -YY_RULE_SETUP -BEGIN(PARAM); return T_INT; - YY_BREAK -case 30: -YY_RULE_SETUP -BEGIN(PARAM); return T_HEX; - YY_BREAK -case 31: -YY_RULE_SETUP -BEGIN(PARAM); return T_STRING; - YY_BREAK -case 32: -YY_RULE_SETUP -BEGIN(PARAM); return T_SELECT; - YY_BREAK -case 33: -YY_RULE_SETUP -BEGIN(PARAM); return T_SELECT; - YY_BREAK -case 34: -YY_RULE_SETUP -BEGIN(PARAM); return T_RANGE; - YY_BREAK -case 35: -YY_RULE_SETUP { + struct kconf_id *id = kconf_id_lookup(zconftext, zconfleng); + BEGIN(PARAM); + current_pos.file = current_file; + current_pos.lineno = current_file->lineno; + if (id && id->flags & TF_COMMAND) { + zconflval.id = id; + return id->token; + } alloc_string(zconftext, zconfleng); zconflval.string = text; return T_WORD; } YY_BREAK -case 36: +case 7: YY_RULE_SETUP YY_BREAK -case 37: -/* rule 37 can match eol */ +case 8: +/* rule 8 can match eol */ YY_RULE_SETUP -current_file->lineno++; BEGIN(INITIAL); +{ + BEGIN(INITIAL); + current_file->lineno++; + return T_EOL; + } YY_BREAK -case 38: +case 9: YY_RULE_SETUP return T_AND; YY_BREAK -case 39: +case 10: YY_RULE_SETUP return T_OR; YY_BREAK -case 40: +case 11: YY_RULE_SETUP return T_OPEN_PAREN; YY_BREAK -case 41: +case 12: YY_RULE_SETUP return T_CLOSE_PAREN; YY_BREAK -case 42: +case 13: YY_RULE_SETUP return T_NOT; YY_BREAK -case 43: +case 14: YY_RULE_SETUP return T_EQUAL; YY_BREAK -case 44: +case 15: YY_RULE_SETUP return T_UNEQUAL; YY_BREAK -case 45: -YY_RULE_SETUP -return T_IF; - YY_BREAK -case 46: -YY_RULE_SETUP -return T_ON; - YY_BREAK -case 47: +case 16: YY_RULE_SETUP { str = zconftext[0]; @@ -2458,33 +1090,38 @@ YY_RULE_SETUP BEGIN(STRING); } YY_BREAK -case 48: -/* rule 48 can match eol */ +case 17: +/* rule 17 can match eol */ YY_RULE_SETUP BEGIN(INITIAL); current_file->lineno++; return T_EOL; YY_BREAK -case 49: +case 18: YY_RULE_SETUP /* ignore */ YY_BREAK -case 50: +case 19: YY_RULE_SETUP { + struct kconf_id *id = kconf_id_lookup(zconftext, zconfleng); + if (id && id->flags & TF_PARAM) { + zconflval.id = id; + return id->token; + } alloc_string(zconftext, zconfleng); zconflval.string = text; return T_WORD; } YY_BREAK -case 51: +case 20: YY_RULE_SETUP /* comment */ YY_BREAK -case 52: -/* rule 52 can match eol */ +case 21: +/* rule 21 can match eol */ YY_RULE_SETUP current_file->lineno++; YY_BREAK -case 53: +case 22: YY_RULE_SETUP YY_BREAK @@ -2494,8 +1131,8 @@ case YY_STATE_EOF(PARAM): } YY_BREAK -case 54: -/* rule 54 can match eol */ +case 23: +/* rule 23 can match eol */ *yy_cp = (yy_hold_char); /* undo effects of setting up zconftext */ (yy_c_buf_p) = yy_cp -= 1; YY_DO_BEFORE_ACTION; /* set up zconftext again */ @@ -2506,14 +1143,14 @@ YY_RULE_SETUP return T_WORD_QUOTE; } YY_BREAK -case 55: +case 24: YY_RULE_SETUP { append_string(zconftext, zconfleng); } YY_BREAK -case 56: -/* rule 56 can match eol */ +case 25: +/* rule 25 can match eol */ *yy_cp = (yy_hold_char); /* undo effects of setting up zconftext */ (yy_c_buf_p) = yy_cp -= 1; YY_DO_BEFORE_ACTION; /* set up zconftext again */ @@ -2524,13 +1161,13 @@ YY_RULE_SETUP return T_WORD_QUOTE; } YY_BREAK -case 57: +case 26: YY_RULE_SETUP { append_string(zconftext + 1, zconfleng - 1); } YY_BREAK -case 58: +case 27: YY_RULE_SETUP { if (str == zconftext[0]) { @@ -2541,8 +1178,8 @@ YY_RULE_SETUP append_string(zconftext, 1); } YY_BREAK -case 59: -/* rule 59 can match eol */ +case 28: +/* rule 28 can match eol */ YY_RULE_SETUP { printf("%s:%d:warning: multi-line strings not supported\n", zconf_curname(), zconf_lineno()); @@ -2557,7 +1194,7 @@ case YY_STATE_EOF(STRING): } YY_BREAK -case 60: +case 29: YY_RULE_SETUP { ts = 0; @@ -2582,8 +1219,8 @@ YY_RULE_SETUP } } YY_BREAK -case 61: -/* rule 61 can match eol */ +case 30: +/* rule 30 can match eol */ *yy_cp = (yy_hold_char); /* undo effects of setting up zconftext */ (yy_c_buf_p) = yy_cp -= 1; YY_DO_BEFORE_ACTION; /* set up zconftext again */ @@ -2594,15 +1231,15 @@ YY_RULE_SETUP return T_HELPTEXT; } YY_BREAK -case 62: -/* rule 62 can match eol */ +case 31: +/* rule 31 can match eol */ YY_RULE_SETUP { current_file->lineno++; append_string("\n", 1); } YY_BREAK -case 63: +case 32: YY_RULE_SETUP { append_string(zconftext, zconfleng); @@ -2620,15 +1257,15 @@ case YY_STATE_EOF(HELP): case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(COMMAND): { - if (current_buf) { + if (current_file) { zconf_endfile(); - return T_EOF; + return T_EOL; } fclose(zconfin); yyterminate(); } YY_BREAK -case 64: +case 33: YY_RULE_SETUP YY_FATAL_ERROR( "flex scanner jammed" ); YY_BREAK @@ -3332,16 +1969,16 @@ YY_BUFFER_STATE zconf_scan_buffer (char * base, yy_size_t size ) /** Setup the input buffer state to scan a string. The next call to zconflex() will * scan from a @e copy of @a str. - * @param str a NUL-terminated string to scan + * @param yy_str a NUL-terminated string to scan * * @return the newly allocated buffer state object. * @note If you want to scan bytes that may contain NUL values, then use * zconf_scan_bytes() instead. */ -YY_BUFFER_STATE zconf_scan_string (yyconst char * str ) +YY_BUFFER_STATE zconf_scan_string (yyconst char * yy_str ) { - return zconf_scan_bytes(str,strlen(str) ); + return zconf_scan_bytes(yy_str,strlen(yy_str) ); } /** Setup the input buffer state to scan the given bytes. The next call to zconflex() will @@ -3650,7 +2287,7 @@ void zconf_nextfile(const char *name) current_file = file; } -static struct buffer *zconf_endfile(void) +static void zconf_endfile(void) { struct buffer *parent; @@ -3666,23 +2303,15 @@ static struct buffer *zconf_endfile(void) } free(current_buf); current_buf = parent; - - return parent; } int zconf_lineno(void) { - if (current_buf) - return current_file->lineno - 1; - else - return 0; + return current_pos.lineno; } char *zconf_curname(void) { - if (current_buf) - return current_file->name; - else - return ""; + return current_pos.file ? current_pos.file->name : ""; } diff --git a/scripts/kconfig/mconf.o b/scripts/kconfig/mconf.o index 61fe000c02c6b0f4616655879d4e953705e48b32..6efca8d51391595fa067dba6ae17da4b657699ff 100644 GIT binary patch literal 29292 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 literal 20532 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 YQ@Bi_*k`>!gQC|dY*H9jxJBXr2CEg_(f|Me diff --git a/scripts/kconfig/zconf.tab.c b/scripts/kconfig/zconf.tab.c index c9bfdb451..ea7755da8 100644 --- a/scripts/kconfig/zconf.tab.c +++ b/scripts/kconfig/zconf.tab.c @@ -1,7 +1,7 @@ -/* A Bison parser, made by GNU Bison 1.875a. */ +/* A Bison parser, made by GNU Bison 2.0. */ /* Skeleton parser for Yacc-like parsing with Bison, - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, 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 @@ -45,8 +45,7 @@ /* Using locations. */ #define YYLSP_NEEDED 0 -/* If NAME_PREFIX is specified substitute the variables and functions - names. */ +/* Substitute the variable and function names. */ #define yyparse zconfparse #define yylex zconflex #define yyerror zconferror @@ -79,28 +78,21 @@ T_REQUIRES = 272, T_OPTIONAL = 273, T_PROMPT = 274, - T_DEFAULT = 275, - T_TRISTATE = 276, - T_DEF_TRISTATE = 277, - T_BOOLEAN = 278, - T_DEF_BOOLEAN = 279, - T_STRING = 280, - T_INT = 281, - T_HEX = 282, - T_WORD = 283, - T_WORD_QUOTE = 284, - T_UNEQUAL = 285, - T_EOF = 286, - T_EOL = 287, - T_CLOSE_PAREN = 288, - T_OPEN_PAREN = 289, - T_ON = 290, - T_SELECT = 291, - T_RANGE = 292, - T_OR = 293, - T_AND = 294, - T_EQUAL = 295, - T_NOT = 296 + T_TYPE = 275, + T_DEFAULT = 276, + T_SELECT = 277, + T_RANGE = 278, + T_ON = 279, + T_WORD = 280, + T_WORD_QUOTE = 281, + T_UNEQUAL = 282, + T_CLOSE_PAREN = 283, + T_OPEN_PAREN = 284, + T_EOL = 285, + T_OR = 286, + T_AND = 287, + T_EQUAL = 288, + T_NOT = 289 }; #endif #define T_MAINMENU 258 @@ -120,28 +112,21 @@ #define T_REQUIRES 272 #define T_OPTIONAL 273 #define T_PROMPT 274 -#define T_DEFAULT 275 -#define T_TRISTATE 276 -#define T_DEF_TRISTATE 277 -#define T_BOOLEAN 278 -#define T_DEF_BOOLEAN 279 -#define T_STRING 280 -#define T_INT 281 -#define T_HEX 282 -#define T_WORD 283 -#define T_WORD_QUOTE 284 -#define T_UNEQUAL 285 -#define T_EOF 286 -#define T_EOL 287 -#define T_CLOSE_PAREN 288 -#define T_OPEN_PAREN 289 -#define T_ON 290 -#define T_SELECT 291 -#define T_RANGE 292 -#define T_OR 293 -#define T_AND 294 -#define T_EQUAL 295 -#define T_NOT 296 +#define T_TYPE 275 +#define T_DEFAULT 276 +#define T_SELECT 277 +#define T_RANGE 278 +#define T_ON 279 +#define T_WORD 280 +#define T_WORD_QUOTE 281 +#define T_UNEQUAL 282 +#define T_CLOSE_PAREN 283 +#define T_OPEN_PAREN 284 +#define T_EOL 285 +#define T_OR 286 +#define T_AND 287 +#define T_EQUAL 288 +#define T_NOT 289 @@ -161,6 +146,11 @@ #include #include +#define LKC_DIRECT_LINK +#include "lkc.h" + +#include "zconf.hash.c" + #define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt) #define PRINTD 0x0001 @@ -170,12 +160,18 @@ int cdebug = PRINTD; extern int zconflex(void); static void zconfprint(const char *err, ...); +static void zconf_error(const char *err, ...); static void zconferror(const char *err); -static bool zconf_endtoken(int token, int starttoken, int endtoken); +static bool zconf_endtoken(struct kconf_id *id, int starttoken, int endtoken); struct symbol *symbol_hash[257]; +static struct menu *current_menu, *current_entry; + +#define YYDEBUG 0 +#if YYDEBUG #define YYERROR_VERBOSE +#endif /* Enabling traces. */ @@ -194,13 +190,14 @@ struct symbol *symbol_hash[257]; #if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) typedef union YYSTYPE { - int token; char *string; + struct file *file; struct symbol *symbol; struct expr *expr; struct menu *menu; + struct kconf_id *id; } YYSTYPE; -/* Line 191 of yacc.c. */ +/* Line 190 of yacc.c. */ # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 @@ -212,27 +209,26 @@ typedef union YYSTYPE { /* Copy the second part of user declarations. */ -#define LKC_DIRECT_LINK -#include "lkc.h" - - -/* Line 214 of yacc.c. */ +/* Line 213 of yacc.c. */ #if ! defined (yyoverflow) || YYERROR_VERBOSE +# ifndef YYFREE +# define YYFREE free +# endif +# ifndef YYMALLOC +# define YYMALLOC malloc +# endif + /* The parser invokes alloca or malloc; define the necessary symbols. */ -# if YYSTACK_USE_ALLOCA -# define YYSTACK_ALLOC alloca -# else -# ifndef YYSTACK_USE_ALLOCA -# if defined (alloca) || defined (_ALLOCA_H) -# define YYSTACK_ALLOC alloca +# ifdef YYSTACK_USE_ALLOCA +# if YYSTACK_USE_ALLOCA +# ifdef __GNUC__ +# define YYSTACK_ALLOC __builtin_alloca # else -# ifdef __GNUC__ -# define YYSTACK_ALLOC __builtin_alloca -# endif +# define YYSTACK_ALLOC alloca # endif # endif # endif @@ -245,20 +241,20 @@ typedef union YYSTYPE { # include /* INFRINGES ON USER NAME SPACE */ # define YYSIZE_T size_t # endif -# define YYSTACK_ALLOC malloc -# define YYSTACK_FREE free +# define YYSTACK_ALLOC YYMALLOC +# define YYSTACK_FREE YYFREE # endif #endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */ #if (! defined (yyoverflow) \ && (! defined (__cplusplus) \ - || (YYSTYPE_IS_TRIVIAL))) + || (defined (YYSTYPE_IS_TRIVIAL) && YYSTYPE_IS_TRIVIAL))) /* A type that is properly aligned for any stack member. */ union yyalloc { - short yyss; + short int yyss; YYSTYPE yyvs; }; @@ -268,13 +264,13 @@ union yyalloc /* The size of an array large to enough to hold all stacks, each with N elements. */ # define YYSTACK_BYTES(N) \ - ((N) * (sizeof (short) + sizeof (YYSTYPE)) \ + ((N) * (sizeof (short int) + sizeof (YYSTYPE)) \ + YYSTACK_GAP_MAXIMUM) /* Copy COUNT objects from FROM to TO. The source and destination do not overlap. */ # ifndef YYCOPY -# if 1 < __GNUC__ +# if defined (__GNUC__) && 1 < __GNUC__ # define YYCOPY(To, From, Count) \ __builtin_memcpy (To, From, (Count) * sizeof (*(From))) # else @@ -310,26 +306,26 @@ union yyalloc #if defined (__STDC__) || defined (__cplusplus) typedef signed char yysigned_char; #else - typedef short yysigned_char; + typedef short int yysigned_char; #endif /* YYFINAL -- State number of the termination state. */ -#define YYFINAL 2 +#define YYFINAL 3 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 201 +#define YYLAST 264 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 42 +#define YYNTOKENS 35 /* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 41 +#define YYNNTS 42 /* YYNRULES -- Number of rules. */ #define YYNRULES 104 /* YYNRULES -- Number of states. */ -#define YYNSTATES 182 +#define YYNSTATES 175 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 -#define YYMAXUTOK 296 +#define YYMAXUTOK 289 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) @@ -365,79 +361,78 @@ static const unsigned char yytranslate[] = 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, - 35, 36, 37, 38, 39, 40, 41 + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34 }; #if YYDEBUG /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in YYRHS. */ -static const unsigned short yyprhs[] = +static const unsigned short int yyprhs[] = { - 0, 0, 3, 4, 7, 9, 11, 13, 17, 19, - 21, 23, 26, 28, 30, 32, 34, 36, 38, 42, - 45, 49, 52, 53, 56, 59, 62, 65, 69, 74, - 78, 83, 87, 91, 95, 100, 105, 110, 116, 119, - 122, 124, 128, 131, 132, 135, 138, 141, 144, 149, - 153, 157, 160, 165, 166, 169, 173, 175, 179, 182, - 183, 186, 189, 192, 196, 199, 201, 205, 208, 209, - 212, 215, 218, 222, 226, 228, 232, 235, 238, 241, - 242, 245, 248, 253, 257, 261, 262, 265, 267, 269, - 272, 275, 278, 280, 282, 283, 286, 288, 292, 296, - 300, 303, 307, 311, 313 + 0, 0, 3, 5, 6, 9, 12, 15, 20, 23, + 28, 33, 37, 39, 41, 43, 45, 47, 49, 51, + 53, 55, 57, 59, 61, 63, 67, 70, 74, 77, + 81, 84, 85, 88, 91, 94, 97, 100, 104, 109, + 114, 119, 125, 128, 131, 133, 137, 138, 141, 144, + 147, 150, 153, 158, 162, 165, 170, 171, 174, 178, + 180, 184, 185, 188, 191, 194, 198, 201, 203, 207, + 208, 211, 214, 217, 221, 225, 228, 231, 234, 235, + 238, 241, 244, 249, 253, 257, 258, 261, 263, 265, + 268, 271, 274, 276, 279, 280, 283, 285, 289, 293, + 297, 300, 304, 308, 310 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ static const yysigned_char yyrhs[] = { - 43, 0, -1, -1, 43, 44, -1, 45, -1, 55, - -1, 66, -1, 3, 77, 79, -1, 5, -1, 15, - -1, 8, -1, 1, 79, -1, 61, -1, 71, -1, - 47, -1, 49, -1, 69, -1, 79, -1, 10, 28, - 32, -1, 46, 50, -1, 11, 28, 32, -1, 48, - 50, -1, -1, 50, 51, -1, 50, 75, -1, 50, - 73, -1, 50, 32, -1, 21, 76, 32, -1, 22, - 81, 80, 32, -1, 23, 76, 32, -1, 24, 81, - 80, 32, -1, 26, 76, 32, -1, 27, 76, 32, - -1, 25, 76, 32, -1, 19, 77, 80, 32, -1, - 20, 81, 80, 32, -1, 36, 28, 80, 32, -1, - 37, 82, 82, 80, 32, -1, 7, 32, -1, 52, - 56, -1, 78, -1, 53, 58, 54, -1, 53, 58, - -1, -1, 56, 57, -1, 56, 75, -1, 56, 73, - -1, 56, 32, -1, 19, 77, 80, 32, -1, 21, - 76, 32, -1, 23, 76, 32, -1, 18, 32, -1, - 20, 28, 80, 32, -1, -1, 58, 45, -1, 14, - 81, 32, -1, 78, -1, 59, 62, 60, -1, 59, - 62, -1, -1, 62, 45, -1, 62, 66, -1, 62, - 55, -1, 4, 77, 32, -1, 63, 74, -1, 78, - -1, 64, 67, 65, -1, 64, 67, -1, -1, 67, - 45, -1, 67, 66, -1, 67, 55, -1, 67, 1, - 32, -1, 6, 77, 32, -1, 68, -1, 9, 77, - 32, -1, 70, 74, -1, 12, 32, -1, 72, 13, - -1, -1, 74, 75, -1, 74, 32, -1, 16, 35, - 81, 32, -1, 16, 81, 32, -1, 17, 81, 32, - -1, -1, 77, 80, -1, 28, -1, 29, -1, 5, - 79, -1, 8, 79, -1, 15, 79, -1, 32, -1, - 31, -1, -1, 14, 81, -1, 82, -1, 82, 40, - 82, -1, 82, 30, 82, -1, 34, 81, 33, -1, - 41, 81, -1, 81, 38, 81, -1, 81, 39, 81, - -1, 28, -1, 29, -1 + 36, 0, -1, 37, -1, -1, 37, 39, -1, 37, + 50, -1, 37, 61, -1, 37, 3, 71, 73, -1, + 37, 72, -1, 37, 25, 1, 30, -1, 37, 38, + 1, 30, -1, 37, 1, 30, -1, 16, -1, 19, + -1, 20, -1, 22, -1, 18, -1, 23, -1, 21, + -1, 30, -1, 56, -1, 65, -1, 42, -1, 44, + -1, 63, -1, 25, 1, 30, -1, 1, 30, -1, + 10, 25, 30, -1, 41, 45, -1, 11, 25, 30, + -1, 43, 45, -1, -1, 45, 46, -1, 45, 69, + -1, 45, 67, -1, 45, 40, -1, 45, 30, -1, + 20, 70, 30, -1, 19, 71, 74, 30, -1, 21, + 75, 74, 30, -1, 22, 25, 74, 30, -1, 23, + 76, 76, 74, 30, -1, 7, 30, -1, 47, 51, + -1, 72, -1, 48, 53, 49, -1, -1, 51, 52, + -1, 51, 69, -1, 51, 67, -1, 51, 30, -1, + 51, 40, -1, 19, 71, 74, 30, -1, 20, 70, + 30, -1, 18, 30, -1, 21, 25, 74, 30, -1, + -1, 53, 39, -1, 14, 75, 73, -1, 72, -1, + 54, 57, 55, -1, -1, 57, 39, -1, 57, 61, + -1, 57, 50, -1, 4, 71, 30, -1, 58, 68, + -1, 72, -1, 59, 62, 60, -1, -1, 62, 39, + -1, 62, 61, -1, 62, 50, -1, 6, 71, 30, + -1, 9, 71, 30, -1, 64, 68, -1, 12, 30, + -1, 66, 13, -1, -1, 68, 69, -1, 68, 30, + -1, 68, 40, -1, 16, 24, 75, 30, -1, 16, + 75, 30, -1, 17, 75, 30, -1, -1, 71, 74, + -1, 25, -1, 26, -1, 5, 30, -1, 8, 30, + -1, 15, 30, -1, 30, -1, 73, 30, -1, -1, + 14, 75, -1, 76, -1, 76, 33, 76, -1, 76, + 27, 76, -1, 29, 75, 28, -1, 34, 75, -1, + 75, 31, 75, -1, 75, 32, 75, -1, 25, -1, + 26, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ -static const unsigned short yyrline[] = +static const unsigned short int yyrline[] = { - 0, 94, 94, 95, 98, 99, 100, 101, 102, 103, - 104, 105, 109, 110, 111, 112, 113, 114, 120, 128, - 134, 142, 152, 154, 155, 156, 157, 160, 166, 173, - 179, 186, 192, 198, 204, 210, 216, 222, 230, 239, - 245, 254, 255, 261, 263, 264, 265, 266, 269, 275, - 281, 287, 293, 299, 301, 306, 315, 324, 325, 331, - 333, 334, 335, 340, 347, 353, 362, 363, 369, 371, - 372, 373, 374, 377, 383, 390, 397, 404, 410, 417, - 418, 419, 422, 427, 432, 440, 442, 447, 448, 451, - 452, 453, 457, 457, 459, 460, 463, 464, 465, 466, - 467, 468, 469, 472, 473 + 0, 103, 103, 105, 107, 108, 109, 110, 111, 112, + 113, 117, 121, 121, 121, 121, 121, 121, 121, 125, + 126, 127, 128, 129, 130, 134, 135, 141, 149, 155, + 163, 173, 175, 176, 177, 178, 179, 182, 190, 196, + 206, 212, 220, 229, 234, 242, 245, 247, 248, 249, + 250, 251, 254, 260, 271, 277, 287, 289, 294, 302, + 310, 313, 315, 316, 317, 322, 329, 334, 342, 345, + 347, 348, 349, 352, 360, 367, 374, 380, 387, 389, + 390, 391, 394, 399, 404, 412, 414, 419, 420, 423, + 424, 425, 429, 430, 433, 434, 437, 438, 439, 440, + 441, 442, 443, 446, 447 }; #endif @@ -446,67 +441,65 @@ static const unsigned short yyrline[] = First, the terminals, then, starting at YYNTOKENS, nonterminals. */ static const char *const yytname[] = { - "$end", "error", "$undefined", "T_MAINMENU", "T_MENU", "T_ENDMENU", - "T_SOURCE", "T_CHOICE", "T_ENDCHOICE", "T_COMMENT", "T_CONFIG", - "T_MENUCONFIG", "T_HELP", "T_HELPTEXT", "T_IF", "T_ENDIF", "T_DEPENDS", - "T_REQUIRES", "T_OPTIONAL", "T_PROMPT", "T_DEFAULT", "T_TRISTATE", - "T_DEF_TRISTATE", "T_BOOLEAN", "T_DEF_BOOLEAN", "T_STRING", "T_INT", - "T_HEX", "T_WORD", "T_WORD_QUOTE", "T_UNEQUAL", "T_EOF", "T_EOL", - "T_CLOSE_PAREN", "T_OPEN_PAREN", "T_ON", "T_SELECT", "T_RANGE", "T_OR", - "T_AND", "T_EQUAL", "T_NOT", "$accept", "input", "block", - "common_block", "config_entry_start", "config_stmt", - "menuconfig_entry_start", "menuconfig_stmt", "config_option_list", - "config_option", "choice", "choice_entry", "choice_end", "choice_stmt", - "choice_option_list", "choice_option", "choice_block", "if", "if_end", - "if_stmt", "if_block", "menu", "menu_entry", "menu_end", "menu_stmt", - "menu_block", "source", "source_stmt", "comment", "comment_stmt", - "help_start", "help", "depends_list", "depends", "prompt_stmt_opt", - "prompt", "end", "nl_or_eof", "if_expr", "expr", "symbol", 0 + "$end", "error", "$undefined", "T_MAINMENU", "T_MENU", "T_ENDMENU", + "T_SOURCE", "T_CHOICE", "T_ENDCHOICE", "T_COMMENT", "T_CONFIG", + "T_MENUCONFIG", "T_HELP", "T_HELPTEXT", "T_IF", "T_ENDIF", "T_DEPENDS", + "T_REQUIRES", "T_OPTIONAL", "T_PROMPT", "T_TYPE", "T_DEFAULT", + "T_SELECT", "T_RANGE", "T_ON", "T_WORD", "T_WORD_QUOTE", "T_UNEQUAL", + "T_CLOSE_PAREN", "T_OPEN_PAREN", "T_EOL", "T_OR", "T_AND", "T_EQUAL", + "T_NOT", "$accept", "input", "stmt_list", "option_name", "common_stmt", + "option_error", "config_entry_start", "config_stmt", + "menuconfig_entry_start", "menuconfig_stmt", "config_option_list", + "config_option", "choice", "choice_entry", "choice_end", "choice_stmt", + "choice_option_list", "choice_option", "choice_block", "if_entry", + "if_end", "if_stmt", "if_block", "menu", "menu_entry", "menu_end", + "menu_stmt", "menu_block", "source_stmt", "comment", "comment_stmt", + "help_start", "help", "depends_list", "depends", "prompt_stmt_opt", + "prompt", "end", "nl", "if_expr", "expr", "symbol", 0 }; #endif # ifdef YYPRINT /* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to token YYLEX-NUM. */ -static const unsigned short yytoknum[] = +static const unsigned short int yytoknum[] = { 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, - 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, - 295, 296 + 285, 286, 287, 288, 289 }; # endif /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const unsigned char yyr1[] = { - 0, 42, 43, 43, 44, 44, 44, 44, 44, 44, - 44, 44, 45, 45, 45, 45, 45, 45, 46, 47, - 48, 49, 50, 50, 50, 50, 50, 51, 51, 51, - 51, 51, 51, 51, 51, 51, 51, 51, 52, 53, - 54, 55, 55, 56, 56, 56, 56, 56, 57, 57, - 57, 57, 57, 58, 58, 59, 60, 61, 61, 62, - 62, 62, 62, 63, 64, 65, 66, 66, 67, 67, - 67, 67, 67, 68, 69, 70, 71, 72, 73, 74, - 74, 74, 75, 75, 75, 76, 76, 77, 77, 78, - 78, 78, 79, 79, 80, 80, 81, 81, 81, 81, - 81, 81, 81, 82, 82 + 0, 35, 36, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 38, 38, 38, 38, 38, 38, 38, 39, + 39, 39, 39, 39, 39, 40, 40, 41, 42, 43, + 44, 45, 45, 45, 45, 45, 45, 46, 46, 46, + 46, 46, 47, 48, 49, 50, 51, 51, 51, 51, + 51, 51, 52, 52, 52, 52, 53, 53, 54, 55, + 56, 57, 57, 57, 57, 58, 59, 60, 61, 62, + 62, 62, 62, 63, 64, 65, 66, 67, 68, 68, + 68, 68, 69, 69, 69, 70, 70, 71, 71, 72, + 72, 72, 73, 73, 74, 74, 75, 75, 75, 75, + 75, 75, 75, 76, 76 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ static const unsigned char yyr2[] = { - 0, 2, 0, 2, 1, 1, 1, 3, 1, 1, - 1, 2, 1, 1, 1, 1, 1, 1, 3, 2, - 3, 2, 0, 2, 2, 2, 2, 3, 4, 3, - 4, 3, 3, 3, 4, 4, 4, 5, 2, 2, - 1, 3, 2, 0, 2, 2, 2, 2, 4, 3, - 3, 2, 4, 0, 2, 3, 1, 3, 2, 0, - 2, 2, 2, 3, 2, 1, 3, 2, 0, 2, - 2, 2, 3, 3, 1, 3, 2, 2, 2, 0, + 0, 2, 1, 0, 2, 2, 2, 4, 2, 4, + 4, 3, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 3, 2, 3, 2, 3, + 2, 0, 2, 2, 2, 2, 2, 3, 4, 4, + 4, 5, 2, 2, 1, 3, 0, 2, 2, 2, + 2, 2, 4, 3, 2, 4, 0, 2, 3, 1, + 3, 0, 2, 2, 2, 3, 2, 1, 3, 0, + 2, 2, 2, 3, 3, 2, 2, 2, 0, 2, 2, 2, 4, 3, 3, 0, 2, 1, 1, 2, - 2, 2, 1, 1, 0, 2, 1, 3, 3, 3, + 2, 2, 1, 2, 0, 2, 1, 3, 3, 3, 2, 3, 3, 1, 1 }; @@ -515,151 +508,160 @@ static const unsigned char yyr2[] = means the default is an error. */ static const unsigned char yydefact[] = { - 2, 0, 1, 0, 0, 0, 8, 0, 0, 10, - 0, 0, 0, 0, 9, 93, 92, 3, 4, 22, - 14, 22, 15, 43, 53, 5, 59, 12, 79, 68, - 6, 74, 16, 79, 13, 17, 11, 87, 88, 0, - 0, 0, 38, 0, 0, 0, 103, 104, 0, 0, - 0, 96, 19, 21, 39, 42, 58, 64, 0, 76, - 7, 63, 73, 75, 18, 20, 0, 100, 55, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, - 85, 0, 85, 85, 85, 26, 0, 0, 23, 0, - 25, 24, 0, 0, 0, 85, 85, 47, 44, 46, - 45, 0, 0, 0, 54, 41, 40, 60, 62, 57, - 61, 56, 81, 80, 0, 69, 71, 66, 70, 65, - 99, 101, 102, 98, 97, 77, 0, 0, 0, 94, - 94, 0, 94, 94, 0, 94, 0, 0, 0, 94, - 0, 78, 51, 94, 94, 0, 0, 89, 90, 91, - 72, 0, 83, 84, 0, 0, 0, 27, 86, 0, - 29, 0, 33, 31, 32, 0, 94, 0, 0, 49, - 50, 82, 95, 34, 35, 28, 30, 36, 0, 48, - 52, 37 + 3, 0, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 12, 16, 13, 14, + 18, 15, 17, 0, 19, 0, 4, 31, 22, 31, + 23, 46, 56, 5, 61, 20, 78, 69, 6, 24, + 78, 21, 8, 11, 87, 88, 0, 0, 89, 0, + 42, 90, 0, 0, 0, 103, 104, 0, 0, 0, + 96, 91, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 92, 7, 65, 73, 74, 27, 29, 0, + 100, 0, 0, 58, 0, 0, 9, 10, 0, 0, + 0, 0, 0, 85, 0, 0, 0, 0, 36, 35, + 32, 0, 34, 33, 0, 0, 85, 0, 50, 51, + 47, 49, 48, 57, 45, 44, 62, 64, 60, 63, + 59, 80, 81, 79, 70, 72, 68, 71, 67, 93, + 99, 101, 102, 98, 97, 26, 76, 0, 0, 0, + 94, 0, 94, 94, 94, 0, 0, 77, 54, 94, + 0, 94, 0, 83, 84, 0, 0, 37, 86, 0, + 0, 94, 25, 0, 53, 0, 82, 95, 38, 39, + 40, 0, 52, 55, 41 }; /* YYDEFGOTO[NTERM-NUM]. */ -static const short yydefgoto[] = +static const short int yydefgoto[] = { - -1, 1, 17, 18, 19, 20, 21, 22, 52, 88, - 23, 24, 105, 25, 54, 98, 55, 26, 109, 27, - 56, 28, 29, 117, 30, 58, 31, 32, 33, 34, - 89, 90, 57, 91, 131, 132, 106, 35, 155, 50, - 51 + -1, 1, 2, 25, 26, 99, 27, 28, 29, 30, + 64, 100, 31, 32, 114, 33, 66, 110, 67, 34, + 118, 35, 68, 36, 37, 126, 38, 70, 39, 40, + 41, 101, 102, 69, 103, 141, 142, 42, 73, 156, + 59, 60 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ -#define YYPACT_NINF -99 -static const short yypact[] = +#define YYPACT_NINF -78 +static const short int yypact[] = { - -99, 48, -99, 38, 46, 46, -99, 46, -29, -99, - 46, -17, -3, -11, -99, -99, -99, -99, -99, -99, - -99, -99, -99, -99, -99, -99, -99, -99, -99, -99, - -99, -99, -99, -99, -99, -99, -99, -99, -99, 38, - 12, 15, -99, 18, 51, 62, -99, -99, -11, -11, - 4, -24, 138, 138, 160, 121, 110, -4, 81, -4, - -99, -99, -99, -99, -99, -99, -19, -99, -99, -11, - -11, 70, 70, 73, 32, -11, 46, -11, 46, -11, - 46, -11, 46, 46, 46, -99, 36, 70, -99, 95, - -99, -99, 96, 46, 106, 46, 46, -99, -99, -99, - -99, 38, 38, 38, -99, -99, -99, -99, -99, -99, - -99, -99, -99, -99, 112, -99, -99, -99, -99, -99, - -99, 117, -99, -99, -99, -99, -11, 33, 65, 131, - 1, 119, 131, 1, 136, 1, 153, 154, 155, 131, - 70, -99, -99, 131, 131, 156, 157, -99, -99, -99, - -99, 101, -99, -99, -11, 158, 159, -99, -99, 161, - -99, 162, -99, -99, -99, 163, 131, 164, 165, -99, - -99, -99, 99, -99, -99, -99, -99, -99, 166, -99, - -99, -99 + -78, 2, 159, -78, -21, 0, 0, -12, 0, 1, + 4, 0, 27, 38, 60, 58, -78, -78, -78, -78, + -78, -78, -78, 100, -78, 104, -78, -78, -78, -78, + -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, + -78, -78, -78, -78, -78, -78, 86, 113, -78, 114, + -78, -78, 125, 127, 128, -78, -78, 60, 60, 210, + 65, -78, 141, 142, 39, 103, 182, 200, 6, 66, + 6, 131, -78, 146, -78, -78, -78, -78, -78, 196, + -78, 60, 60, 146, 40, 40, -78, -78, 155, 156, + -2, 60, 0, 0, 60, 105, 40, 194, -78, -78, + -78, 206, -78, -78, 183, 0, 0, 195, -78, -78, + -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, + -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, + -78, 197, -78, -78, -78, -78, -78, 60, 213, 216, + 212, 203, 212, 190, 212, 40, 208, -78, -78, 212, + 222, 212, 219, -78, -78, 60, 223, -78, -78, 224, + 225, 212, -78, 226, -78, 227, -78, 47, -78, -78, + -78, 228, -78, -78, -78 }; /* YYPGOTO[NTERM-NUM]. */ -static const short yypgoto[] = +static const short int yypgoto[] = { - -99, -99, -99, 111, -99, -99, -99, -99, 178, -99, - -99, -99, -99, 91, -99, -99, -99, -99, -99, -99, - -99, -99, -99, -99, 115, -99, -99, -99, -99, -99, - -99, 146, 168, 89, 27, 0, 126, -1, -98, -48, - -63 + -78, -78, -78, -78, 164, -36, -78, -78, -78, -78, + 230, -78, -78, -78, -78, 29, -78, -78, -78, -78, + -78, -78, -78, -78, -78, -78, 59, -78, -78, -78, + -78, -78, 198, 220, 24, 157, -5, 169, 202, 74, + -53, -77 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If positive, shift that token. If negative, reduce the rule which number is the opposite. If zero, do what YYDEFACT says. If YYTABLE_NINF, syntax error. */ -#define YYTABLE_NINF -68 -static const short yytable[] = +#define YYTABLE_NINF -76 +static const short int yytable[] = { - 66, 67, 36, 42, 39, 40, 71, 41, 123, 124, - 43, 44, 74, 75, 120, 154, 72, 46, 47, 69, - 70, 121, 122, 48, 140, 45, 127, 128, 112, 130, - 49, 133, 156, 135, 158, 159, 68, 161, 60, 69, - 70, 165, 69, 70, 61, 167, 168, 62, 2, 3, - 63, 4, 5, 6, 7, 8, 9, 10, 11, 12, - 46, 47, 13, 14, 139, 152, 48, 126, 178, 15, - 16, 69, 70, 49, 37, 38, 129, 166, 151, 15, - 16, -67, 114, 64, -67, 5, 101, 7, 8, 102, - 10, 11, 12, 143, 65, 13, 103, 153, 46, 47, - 147, 148, 149, 69, 70, 125, 172, 134, 141, 136, - 137, 138, 15, 16, 5, 101, 7, 8, 102, 10, - 11, 12, 145, 146, 13, 103, 101, 7, 142, 102, - 10, 11, 12, 171, 144, 13, 103, 69, 70, 69, - 70, 15, 16, 100, 150, 154, 113, 108, 113, 116, - 73, 157, 15, 16, 74, 75, 70, 76, 77, 78, - 79, 80, 81, 82, 83, 84, 104, 107, 160, 115, - 85, 110, 73, 118, 86, 87, 74, 75, 92, 93, - 94, 95, 111, 96, 119, 162, 163, 164, 169, 170, - 173, 174, 97, 175, 176, 177, 179, 180, 181, 53, - 99, 59 + 46, 47, 3, 49, 79, 80, 52, 133, 134, 43, + 6, 7, 8, 9, 10, 11, 12, 13, 48, 145, + 14, 15, 137, 55, 56, 44, 45, 57, 131, 132, + 109, 50, 58, 122, 51, 122, 24, 138, 139, -28, + 88, 143, -28, -28, -28, -28, -28, -28, -28, -28, + -28, 89, 53, -28, -28, 90, 91, -28, 92, 93, + 94, 95, 96, 54, 97, 55, 56, 88, 161, 98, + -66, -66, -66, -66, -66, -66, -66, -66, 81, 82, + -66, -66, 90, 91, 152, 55, 56, 140, 61, 57, + 112, 97, 84, 123, 58, 123, 121, 117, 85, 125, + 149, 62, 167, -30, 88, 63, -30, -30, -30, -30, + -30, -30, -30, -30, -30, 89, 72, -30, -30, 90, + 91, -30, 92, 93, 94, 95, 96, 119, 97, 127, + 144, -75, 88, 98, -75, -75, -75, -75, -75, -75, + -75, -75, -75, 74, 75, -75, -75, 90, 91, -75, + -75, -75, -75, -75, -75, 76, 97, 77, 78, -2, + 4, 121, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 86, 87, 14, 15, 16, 129, 17, 18, 19, + 20, 21, 22, 88, 23, 135, 136, -43, -43, 24, + -43, -43, -43, -43, 89, 146, -43, -43, 90, 91, + 104, 105, 106, 107, 155, 7, 8, 97, 10, 11, + 12, 13, 108, 148, 14, 15, 158, 159, 160, 147, + 151, 81, 82, 163, 130, 165, 155, 81, 82, 82, + 24, 113, 116, 157, 124, 171, 115, 120, 162, 128, + 72, 81, 82, 153, 81, 82, 154, 81, 82, 166, + 81, 82, 164, 168, 169, 170, 172, 173, 174, 65, + 71, 83, 0, 150, 111 }; -static const unsigned char yycheck[] = +static const short int yycheck[] = { - 48, 49, 3, 32, 4, 5, 30, 7, 71, 72, - 10, 28, 16, 17, 33, 14, 40, 28, 29, 38, - 39, 69, 70, 34, 87, 28, 74, 75, 32, 77, - 41, 79, 130, 81, 132, 133, 32, 135, 39, 38, - 39, 139, 38, 39, 32, 143, 144, 32, 0, 1, - 32, 3, 4, 5, 6, 7, 8, 9, 10, 11, - 28, 29, 14, 15, 28, 32, 34, 35, 166, 31, - 32, 38, 39, 41, 28, 29, 76, 140, 126, 31, - 32, 0, 1, 32, 3, 4, 5, 6, 7, 8, - 9, 10, 11, 93, 32, 14, 15, 32, 28, 29, - 101, 102, 103, 38, 39, 32, 154, 80, 13, 82, - 83, 84, 31, 32, 4, 5, 6, 7, 8, 9, - 10, 11, 95, 96, 14, 15, 5, 6, 32, 8, - 9, 10, 11, 32, 28, 14, 15, 38, 39, 38, - 39, 31, 32, 54, 32, 14, 57, 56, 59, 58, - 12, 32, 31, 32, 16, 17, 39, 19, 20, 21, - 22, 23, 24, 25, 26, 27, 55, 56, 32, 58, - 32, 56, 12, 58, 36, 37, 16, 17, 18, 19, - 20, 21, 56, 23, 58, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 21, - 54, 33 + 5, 6, 0, 8, 57, 58, 11, 84, 85, 30, + 4, 5, 6, 7, 8, 9, 10, 11, 30, 96, + 14, 15, 24, 25, 26, 25, 26, 29, 81, 82, + 66, 30, 34, 69, 30, 71, 30, 90, 91, 0, + 1, 94, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 25, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 25, 25, 25, 26, 1, 145, 30, + 4, 5, 6, 7, 8, 9, 10, 11, 31, 32, + 14, 15, 16, 17, 137, 25, 26, 92, 30, 29, + 66, 25, 27, 69, 34, 71, 30, 68, 33, 70, + 105, 1, 155, 0, 1, 1, 3, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 30, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 68, 25, 70, + 25, 0, 1, 30, 3, 4, 5, 6, 7, 8, + 9, 10, 11, 30, 30, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 30, 25, 30, 30, 0, + 1, 30, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 30, 30, 14, 15, 16, 30, 18, 19, 20, + 21, 22, 23, 1, 25, 30, 30, 5, 6, 30, + 8, 9, 10, 11, 12, 1, 14, 15, 16, 17, + 18, 19, 20, 21, 14, 5, 6, 25, 8, 9, + 10, 11, 30, 30, 14, 15, 142, 143, 144, 13, + 25, 31, 32, 149, 28, 151, 14, 31, 32, 32, + 30, 67, 68, 30, 70, 161, 67, 68, 30, 70, + 30, 31, 32, 30, 31, 32, 30, 31, 32, 30, + 31, 32, 30, 30, 30, 30, 30, 30, 30, 29, + 40, 59, -1, 106, 66 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const unsigned char yystos[] = { - 0, 43, 0, 1, 3, 4, 5, 6, 7, 8, - 9, 10, 11, 14, 15, 31, 32, 44, 45, 46, - 47, 48, 49, 52, 53, 55, 59, 61, 63, 64, - 66, 68, 69, 70, 71, 79, 79, 28, 29, 77, - 77, 77, 32, 77, 28, 28, 28, 29, 34, 41, - 81, 82, 50, 50, 56, 58, 62, 74, 67, 74, - 79, 32, 32, 32, 32, 32, 81, 81, 32, 38, - 39, 30, 40, 12, 16, 17, 19, 20, 21, 22, - 23, 24, 25, 26, 27, 32, 36, 37, 51, 72, - 73, 75, 18, 19, 20, 21, 23, 32, 57, 73, - 75, 5, 8, 15, 45, 54, 78, 45, 55, 60, - 66, 78, 32, 75, 1, 45, 55, 65, 66, 78, - 33, 81, 81, 82, 82, 32, 35, 81, 81, 77, - 81, 76, 77, 81, 76, 81, 76, 76, 76, 28, - 82, 13, 32, 77, 28, 76, 76, 79, 79, 79, - 32, 81, 32, 32, 14, 80, 80, 32, 80, 80, - 32, 80, 32, 32, 32, 80, 82, 80, 80, 32, - 32, 32, 81, 32, 32, 32, 32, 32, 80, 32, - 32, 32 + 0, 36, 37, 0, 1, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 14, 15, 16, 18, 19, 20, + 21, 22, 23, 25, 30, 38, 39, 41, 42, 43, + 44, 47, 48, 50, 54, 56, 58, 59, 61, 63, + 64, 65, 72, 30, 25, 26, 71, 71, 30, 71, + 30, 30, 71, 25, 25, 25, 26, 29, 34, 75, + 76, 30, 1, 1, 45, 45, 51, 53, 57, 68, + 62, 68, 30, 73, 30, 30, 30, 30, 30, 75, + 75, 31, 32, 73, 27, 33, 30, 30, 1, 12, + 16, 17, 19, 20, 21, 22, 23, 25, 30, 40, + 46, 66, 67, 69, 18, 19, 20, 21, 30, 40, + 52, 67, 69, 39, 49, 72, 39, 50, 55, 61, + 72, 30, 40, 69, 39, 50, 60, 61, 72, 30, + 28, 75, 75, 76, 76, 30, 30, 24, 75, 75, + 71, 70, 71, 75, 25, 76, 1, 13, 30, 71, + 70, 25, 75, 30, 30, 14, 74, 30, 74, 74, + 74, 76, 30, 74, 30, 74, 30, 75, 30, 30, + 30, 74, 30, 30, 30 }; #if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__) @@ -685,7 +687,7 @@ static const unsigned char yystos[] = #define YYACCEPT goto yyacceptlab #define YYABORT goto yyabortlab -#define YYERROR goto yyerrlab1 +#define YYERROR goto yyerrorlab /* Like YYERROR except do call yyerror. This remains here temporarily @@ -713,20 +715,53 @@ do \ } \ while (0) + #define YYTERROR 1 #define YYERRCODE 256 -/* YYLLOC_DEFAULT -- Compute the default location (before the actions - are run). */ +/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. + If N is 0, then set CURRENT to the empty location which ends + the previous symbol: RHS[0] (always defined). */ + +#define YYRHSLOC(Rhs, K) ((Rhs)[K]) #ifndef YYLLOC_DEFAULT -# define YYLLOC_DEFAULT(Current, Rhs, N) \ - Current.first_line = Rhs[1].first_line; \ - Current.first_column = Rhs[1].first_column; \ - Current.last_line = Rhs[N].last_line; \ - Current.last_column = Rhs[N].last_column; +# define YYLLOC_DEFAULT(Current, Rhs, N) \ + do \ + if (N) \ + { \ + (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ + (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ + (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ + (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ + } \ + else \ + { \ + (Current).first_line = (Current).last_line = \ + YYRHSLOC (Rhs, 0).last_line; \ + (Current).first_column = (Current).last_column = \ + YYRHSLOC (Rhs, 0).last_column; \ + } \ + while (0) #endif + +/* YY_LOCATION_PRINT -- Print the location on the stream. + This macro was not mandated originally: define only if we know + we won't break user code: when these are the locations we know. */ + +#ifndef YY_LOCATION_PRINT +# if YYLTYPE_IS_TRIVIAL +# define YY_LOCATION_PRINT(File, Loc) \ + fprintf (File, "%d.%d-%d.%d", \ + (Loc).first_line, (Loc).first_column, \ + (Loc).last_line, (Loc).last_column) +# else +# define YY_LOCATION_PRINT(File, Loc) ((void) 0) +# endif +#endif + + /* YYLEX -- calling `yylex' with the right arguments. */ #ifdef YYLEX_PARAM @@ -749,36 +784,30 @@ do { \ YYFPRINTF Args; \ } while (0) -# define YYDSYMPRINT(Args) \ -do { \ - if (yydebug) \ - yysymprint Args; \ -} while (0) - -# define YYDSYMPRINTF(Title, Token, Value, Location) \ +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ do { \ if (yydebug) \ { \ YYFPRINTF (stderr, "%s ", Title); \ yysymprint (stderr, \ - Token, Value); \ + Type, Value); \ YYFPRINTF (stderr, "\n"); \ } \ } while (0) /*------------------------------------------------------------------. | yy_stack_print -- Print the state stack from its BOTTOM up to its | -| TOP (cinluded). | +| TOP (included). | `------------------------------------------------------------------*/ #if defined (__STDC__) || defined (__cplusplus) static void -yy_stack_print (short *bottom, short *top) +yy_stack_print (short int *bottom, short int *top) #else static void yy_stack_print (bottom, top) - short *bottom; - short *top; + short int *bottom; + short int *top; #endif { YYFPRINTF (stderr, "Stack now"); @@ -808,9 +837,9 @@ yy_reduce_print (yyrule) #endif { int yyi; - unsigned int yylineno = yyrline[yyrule]; + unsigned int yylno = yyrline[yyrule]; YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ", - yyrule - 1, yylineno); + yyrule - 1, yylno); /* Print the symbols being reduced, and their result. */ for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++) YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]); @@ -828,8 +857,7 @@ do { \ int yydebug; #else /* !YYDEBUG */ # define YYDPRINTF(Args) -# define YYDSYMPRINT(Args) -# define YYDSYMPRINTF(Title, Token, Value, Location) +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) # define YY_STACK_PRINT(Bottom, Top) # define YY_REDUCE_PRINT(Rule) #endif /* !YYDEBUG */ @@ -847,10 +875,6 @@ int yydebug; SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH) evaluated with infinite-precision integer arithmetic. */ -#if YYMAXDEPTH == 0 -# undef YYMAXDEPTH -#endif - #ifndef YYMAXDEPTH # define YYMAXDEPTH 10000 #endif @@ -932,15 +956,15 @@ yysymprint (yyoutput, yytype, yyvaluep) (void) yyvaluep; if (yytype < YYNTOKENS) - { - YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); -# ifdef YYPRINT - YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); -# endif - } + YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); else YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); + +# ifdef YYPRINT + if (yytype < YYNTOKENS) + YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); +# endif switch (yytype) { default: @@ -956,10 +980,11 @@ yysymprint (yyoutput, yytype, yyvaluep) #if defined (__STDC__) || defined (__cplusplus) static void -yydestruct (int yytype, YYSTYPE *yyvaluep) +yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) #else static void -yydestruct (yytype, yyvaluep) +yydestruct (yymsg, yytype, yyvaluep) + const char *yymsg; int yytype; YYSTYPE *yyvaluep; #endif @@ -967,8 +992,42 @@ yydestruct (yytype, yyvaluep) /* Pacify ``unused variable'' warnings. */ (void) yyvaluep; + if (!yymsg) + yymsg = "Deleting"; + YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); + switch (yytype) { + case 48: /* choice_entry */ + + { + fprintf(stderr, "%s:%d: missing end statement for this entry\n", + (yyvaluep->menu)->file->name, (yyvaluep->menu)->lineno); + if (current_menu == (yyvaluep->menu)) + menu_end_menu(); +}; + + break; + case 54: /* if_entry */ + + { + fprintf(stderr, "%s:%d: missing end statement for this entry\n", + (yyvaluep->menu)->file->name, (yyvaluep->menu)->lineno); + if (current_menu == (yyvaluep->menu)) + menu_end_menu(); +}; + + break; + case 59: /* menu_entry */ + + { + fprintf(stderr, "%s:%d: missing end statement for this entry\n", + (yyvaluep->menu)->file->name, (yyvaluep->menu)->lineno); + if (current_menu == (yyvaluep->menu)) + menu_end_menu(); +}; + + break; default: break; @@ -994,10 +1053,10 @@ int yyparse (); -/* The lookahead symbol. */ +/* The look-ahead symbol. */ int yychar; -/* The semantic value of the lookahead symbol. */ +/* The semantic value of the look-ahead symbol. */ YYSTYPE yylval; /* Number of syntax errors so far. */ @@ -1033,7 +1092,7 @@ yyparse () int yyresult; /* Number of tokens to shift before error messages enabled. */ int yyerrstatus; - /* Lookahead token as an internal (translated) token number. */ + /* Look-ahead token as an internal (translated) token number. */ int yytoken = 0; /* Three stacks and their tools: @@ -1045,9 +1104,9 @@ yyparse () to reallocate them elsewhere. */ /* The state stack. */ - short yyssa[YYINITDEPTH]; - short *yyss = yyssa; - register short *yyssp; + short int yyssa[YYINITDEPTH]; + short int *yyss = yyssa; + register short int *yyssp; /* The semantic value stack. */ YYSTYPE yyvsa[YYINITDEPTH]; @@ -1084,6 +1143,9 @@ yyparse () yyssp = yyss; yyvsp = yyvs; + + yyvsp[0] = yylval; + goto yysetstate; /*------------------------------------------------------------. @@ -1109,7 +1171,7 @@ yyparse () these so that the &'s don't force the real ones into memory. */ YYSTYPE *yyvs1 = yyvs; - short *yyss1 = yyss; + short int *yyss1 = yyss; /* Each stack pointer address is followed by the size of the @@ -1137,7 +1199,7 @@ yyparse () yystacksize = YYMAXDEPTH; { - short *yyss1 = yyss; + short int *yyss1 = yyss; union yyalloc *yyptr = (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); if (! yyptr) @@ -1173,18 +1235,18 @@ yyparse () yybackup: /* Do appropriate processing given the current state. */ -/* Read a lookahead token if we need one and don't already have one. */ +/* Read a look-ahead token if we need one and don't already have one. */ /* yyresume: */ - /* First try to decide what to do without reference to lookahead token. */ + /* First try to decide what to do without reference to look-ahead token. */ yyn = yypact[yystate]; if (yyn == YYPACT_NINF) goto yydefault; - /* Not known => get a lookahead token if don't already have one. */ + /* Not known => get a look-ahead token if don't already have one. */ - /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ + /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */ if (yychar == YYEMPTY) { YYDPRINTF ((stderr, "Reading a token: ")); @@ -1199,7 +1261,7 @@ yybackup: else { yytoken = YYTRANSLATE (yychar); - YYDSYMPRINTF ("Next token is", yytoken, &yylval, &yylloc); + YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); } /* If the proper action on seeing token YYTOKEN is to reduce or to @@ -1219,8 +1281,8 @@ yybackup: if (yyn == YYFINAL) YYACCEPT; - /* Shift the lookahead token. */ - YYDPRINTF ((stderr, "Shifting token %s, ", yytname[yytoken])); + /* Shift the look-ahead token. */ + YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); /* Discard the token being shifted unless it is eof. */ if (yychar != YYEOF) @@ -1271,155 +1333,123 @@ yyreduce: { case 8: - { zconfprint("unexpected 'endmenu' statement"); ;} + { zconf_error("unexpected end statement"); ;} break; case 9: - { zconfprint("unexpected 'endif' statement"); ;} + { zconf_error("unknown statement \"%s\"", (yyvsp[-2].string)); ;} break; case 10: - { zconfprint("unexpected 'endchoice' statement"); ;} + { + zconf_error("unexpected option \"%s\"", kconf_id_strings + (yyvsp[-2].id)->name); +;} break; case 11: - { zconfprint("syntax error"); yyerrok; ;} + { zconf_error("invalid statement"); ;} break; - case 18: + case 25: - { - struct symbol *sym = sym_lookup(yyvsp[-1].string, 0); - sym->flags |= SYMBOL_OPTIONAL; - menu_add_entry(sym); - printd(DEBUG_PARSE, "%s:%d:config %s\n", zconf_curname(), zconf_lineno(), yyvsp[-1].string); -;} + { zconf_error("unknown option \"%s\"", (yyvsp[-2].string)); ;} break; - case 19: + case 26: - { - menu_end_entry(); - printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno()); -;} + { zconf_error("invalid option"); ;} break; - case 20: + case 27: { - struct symbol *sym = sym_lookup(yyvsp[-1].string, 0); + struct symbol *sym = sym_lookup((yyvsp[-1].string), 0); sym->flags |= SYMBOL_OPTIONAL; menu_add_entry(sym); - printd(DEBUG_PARSE, "%s:%d:menuconfig %s\n", zconf_curname(), zconf_lineno(), yyvsp[-1].string); + printd(DEBUG_PARSE, "%s:%d:config %s\n", zconf_curname(), zconf_lineno(), (yyvsp[-1].string)); ;} break; - case 21: + case 28: { - if (current_entry->prompt) - current_entry->prompt->type = P_MENU; - else - zconfprint("warning: menuconfig statement without prompt"); menu_end_entry(); printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno()); ;} break; - case 27: - - { - menu_set_type(S_TRISTATE); - printd(DEBUG_PARSE, "%s:%d:tristate\n", zconf_curname(), zconf_lineno()); -;} - break; - - case 28: - - { - menu_add_expr(P_DEFAULT, yyvsp[-2].expr, yyvsp[-1].expr); - menu_set_type(S_TRISTATE); - printd(DEBUG_PARSE, "%s:%d:def_boolean\n", zconf_curname(), zconf_lineno()); -;} - break; - case 29: { - menu_set_type(S_BOOLEAN); - printd(DEBUG_PARSE, "%s:%d:boolean\n", zconf_curname(), zconf_lineno()); + struct symbol *sym = sym_lookup((yyvsp[-1].string), 0); + sym->flags |= SYMBOL_OPTIONAL; + menu_add_entry(sym); + printd(DEBUG_PARSE, "%s:%d:menuconfig %s\n", zconf_curname(), zconf_lineno(), (yyvsp[-1].string)); ;} break; case 30: { - menu_add_expr(P_DEFAULT, yyvsp[-2].expr, yyvsp[-1].expr); - menu_set_type(S_BOOLEAN); - printd(DEBUG_PARSE, "%s:%d:def_boolean\n", zconf_curname(), zconf_lineno()); -;} - break; - - case 31: - - { - menu_set_type(S_INT); - printd(DEBUG_PARSE, "%s:%d:int\n", zconf_curname(), zconf_lineno()); -;} - break; - - case 32: - - { - menu_set_type(S_HEX); - printd(DEBUG_PARSE, "%s:%d:hex\n", zconf_curname(), zconf_lineno()); + if (current_entry->prompt) + current_entry->prompt->type = P_MENU; + else + zconfprint("warning: menuconfig statement without prompt"); + menu_end_entry(); + printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno()); ;} break; - case 33: + case 37: { - menu_set_type(S_STRING); - printd(DEBUG_PARSE, "%s:%d:string\n", zconf_curname(), zconf_lineno()); + menu_set_type((yyvsp[-2].id)->stype); + printd(DEBUG_PARSE, "%s:%d:type(%u)\n", + zconf_curname(), zconf_lineno(), + (yyvsp[-2].id)->stype); ;} break; - case 34: + case 38: { - menu_add_prompt(P_PROMPT, yyvsp[-2].string, yyvsp[-1].expr); + menu_add_prompt(P_PROMPT, (yyvsp[-2].string), (yyvsp[-1].expr)); printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno()); ;} break; - case 35: + case 39: { - menu_add_expr(P_DEFAULT, yyvsp[-2].expr, yyvsp[-1].expr); - printd(DEBUG_PARSE, "%s:%d:default\n", zconf_curname(), zconf_lineno()); + menu_add_expr(P_DEFAULT, (yyvsp[-2].expr), (yyvsp[-1].expr)); + if ((yyvsp[-3].id)->stype != S_UNKNOWN) + menu_set_type((yyvsp[-3].id)->stype); + printd(DEBUG_PARSE, "%s:%d:default(%u)\n", + zconf_curname(), zconf_lineno(), + (yyvsp[-3].id)->stype); ;} break; - case 36: + case 40: { - menu_add_symbol(P_SELECT, sym_lookup(yyvsp[-2].string, 0), yyvsp[-1].expr); + menu_add_symbol(P_SELECT, sym_lookup((yyvsp[-2].string), 0), (yyvsp[-1].expr)); printd(DEBUG_PARSE, "%s:%d:select\n", zconf_curname(), zconf_lineno()); ;} break; - case 37: + case 41: { - menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,yyvsp[-3].symbol, yyvsp[-2].symbol), yyvsp[-1].expr); + menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,(yyvsp[-3].symbol), (yyvsp[-2].symbol)), (yyvsp[-1].expr)); printd(DEBUG_PARSE, "%s:%d:range\n", zconf_curname(), zconf_lineno()); ;} break; - case 38: + case 42: { struct symbol *sym = sym_lookup(NULL, 0); @@ -1430,57 +1460,45 @@ yyreduce: ;} break; - case 39: + case 43: { - menu_end_entry(); - menu_add_menu(); + (yyval.menu) = menu_add_menu(); ;} break; - case 40: + case 44: { - if (zconf_endtoken(yyvsp[0].token, T_CHOICE, T_ENDCHOICE)) { + if (zconf_endtoken((yyvsp[0].id), T_CHOICE, T_ENDCHOICE)) { menu_end_menu(); printd(DEBUG_PARSE, "%s:%d:endchoice\n", zconf_curname(), zconf_lineno()); } ;} break; - case 42: - - { - printf("%s:%d: missing 'endchoice' for this 'choice' statement\n", current_menu->file->name, current_menu->lineno); - zconfnerrs++; -;} - break; - - case 48: + case 52: { - menu_add_prompt(P_PROMPT, yyvsp[-2].string, yyvsp[-1].expr); + menu_add_prompt(P_PROMPT, (yyvsp[-2].string), (yyvsp[-1].expr)); printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno()); ;} break; - case 49: + case 53: { - menu_set_type(S_TRISTATE); - printd(DEBUG_PARSE, "%s:%d:tristate\n", zconf_curname(), zconf_lineno()); + if ((yyvsp[-2].id)->stype == S_BOOLEAN || (yyvsp[-2].id)->stype == S_TRISTATE) { + menu_set_type((yyvsp[-2].id)->stype); + printd(DEBUG_PARSE, "%s:%d:type(%u)\n", + zconf_curname(), zconf_lineno(), + (yyvsp[-2].id)->stype); + } else + YYERROR; ;} break; - case 50: - - { - menu_set_type(S_BOOLEAN); - printd(DEBUG_PARSE, "%s:%d:boolean\n", zconf_curname(), zconf_lineno()); -;} - break; - - case 51: + case 54: { current_entry->sym->flags |= SYMBOL_OPTIONAL; @@ -1488,115 +1506,89 @@ yyreduce: ;} break; - case 52: + case 55: { - menu_add_symbol(P_DEFAULT, sym_lookup(yyvsp[-2].string, 0), yyvsp[-1].expr); - printd(DEBUG_PARSE, "%s:%d:default\n", zconf_curname(), zconf_lineno()); + if ((yyvsp[-3].id)->stype == S_UNKNOWN) { + menu_add_symbol(P_DEFAULT, sym_lookup((yyvsp[-2].string), 0), (yyvsp[-1].expr)); + printd(DEBUG_PARSE, "%s:%d:default\n", + zconf_curname(), zconf_lineno()); + } else + YYERROR; ;} break; - case 55: + case 58: { printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno()); menu_add_entry(NULL); - menu_add_dep(yyvsp[-1].expr); - menu_end_entry(); - menu_add_menu(); + menu_add_dep((yyvsp[-1].expr)); + (yyval.menu) = menu_add_menu(); ;} break; - case 56: + case 59: { - if (zconf_endtoken(yyvsp[0].token, T_IF, T_ENDIF)) { + if (zconf_endtoken((yyvsp[0].id), T_IF, T_ENDIF)) { menu_end_menu(); printd(DEBUG_PARSE, "%s:%d:endif\n", zconf_curname(), zconf_lineno()); } ;} break; - case 58: - - { - printf("%s:%d: missing 'endif' for this 'if' statement\n", current_menu->file->name, current_menu->lineno); - zconfnerrs++; -;} - break; - - case 63: + case 65: { menu_add_entry(NULL); - menu_add_prop(P_MENU, yyvsp[-1].string, NULL, NULL); + menu_add_prompt(P_MENU, (yyvsp[-1].string), NULL); printd(DEBUG_PARSE, "%s:%d:menu\n", zconf_curname(), zconf_lineno()); ;} break; - case 64: + case 66: { - menu_end_entry(); - menu_add_menu(); + (yyval.menu) = menu_add_menu(); ;} break; - case 65: + case 67: { - if (zconf_endtoken(yyvsp[0].token, T_MENU, T_ENDMENU)) { + if (zconf_endtoken((yyvsp[0].id), T_MENU, T_ENDMENU)) { menu_end_menu(); printd(DEBUG_PARSE, "%s:%d:endmenu\n", zconf_curname(), zconf_lineno()); } ;} break; - case 67: - - { - printf("%s:%d: missing 'endmenu' for this 'menu' statement\n", current_menu->file->name, current_menu->lineno); - zconfnerrs++; -;} - break; - - case 72: - - { zconfprint("invalid menu option"); yyerrok; ;} - break; - case 73: { - yyval.string = yyvsp[-1].string; - printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), yyvsp[-1].string); + printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), (yyvsp[-1].string)); + zconf_nextfile((yyvsp[-1].string)); ;} break; case 74: - { - zconf_nextfile(yyvsp[0].string); -;} - break; - - case 75: - { menu_add_entry(NULL); - menu_add_prop(P_COMMENT, yyvsp[-1].string, NULL, NULL); + menu_add_prompt(P_COMMENT, (yyvsp[-1].string), NULL); printd(DEBUG_PARSE, "%s:%d:comment\n", zconf_curname(), zconf_lineno()); ;} break; - case 76: + case 75: { menu_end_entry(); ;} break; - case 77: + case 76: { printd(DEBUG_PARSE, "%s:%d:help\n", zconf_curname(), zconf_lineno()); @@ -1604,17 +1596,17 @@ yyreduce: ;} break; - case 78: + case 77: { - current_entry->sym->help = yyvsp[0].string; + current_entry->sym->help = (yyvsp[0].string); ;} break; case 82: { - menu_add_dep(yyvsp[-1].expr); + menu_add_dep((yyvsp[-1].expr)); printd(DEBUG_PARSE, "%s:%d:depends on\n", zconf_curname(), zconf_lineno()); ;} break; @@ -1622,7 +1614,7 @@ yyreduce: case 83: { - menu_add_dep(yyvsp[-1].expr); + menu_add_dep((yyvsp[-1].expr)); printd(DEBUG_PARSE, "%s:%d:depends\n", zconf_curname(), zconf_lineno()); ;} break; @@ -1630,7 +1622,7 @@ yyreduce: case 84: { - menu_add_dep(yyvsp[-1].expr); + menu_add_dep((yyvsp[-1].expr)); printd(DEBUG_PARSE, "%s:%d:requires\n", zconf_curname(), zconf_lineno()); ;} break; @@ -1638,84 +1630,84 @@ yyreduce: case 86: { - menu_add_prop(P_PROMPT, yyvsp[-1].string, NULL, yyvsp[0].expr); + menu_add_prompt(P_PROMPT, (yyvsp[-1].string), (yyvsp[0].expr)); ;} break; case 89: - { yyval.token = T_ENDMENU; ;} + { (yyval.id) = (yyvsp[-1].id); ;} break; case 90: - { yyval.token = T_ENDCHOICE; ;} + { (yyval.id) = (yyvsp[-1].id); ;} break; case 91: - { yyval.token = T_ENDIF; ;} + { (yyval.id) = (yyvsp[-1].id); ;} break; case 94: - { yyval.expr = NULL; ;} + { (yyval.expr) = NULL; ;} break; case 95: - { yyval.expr = yyvsp[0].expr; ;} + { (yyval.expr) = (yyvsp[0].expr); ;} break; case 96: - { yyval.expr = expr_alloc_symbol(yyvsp[0].symbol); ;} + { (yyval.expr) = expr_alloc_symbol((yyvsp[0].symbol)); ;} break; case 97: - { yyval.expr = expr_alloc_comp(E_EQUAL, yyvsp[-2].symbol, yyvsp[0].symbol); ;} + { (yyval.expr) = expr_alloc_comp(E_EQUAL, (yyvsp[-2].symbol), (yyvsp[0].symbol)); ;} break; case 98: - { yyval.expr = expr_alloc_comp(E_UNEQUAL, yyvsp[-2].symbol, yyvsp[0].symbol); ;} + { (yyval.expr) = expr_alloc_comp(E_UNEQUAL, (yyvsp[-2].symbol), (yyvsp[0].symbol)); ;} break; case 99: - { yyval.expr = yyvsp[-1].expr; ;} + { (yyval.expr) = (yyvsp[-1].expr); ;} break; case 100: - { yyval.expr = expr_alloc_one(E_NOT, yyvsp[0].expr); ;} + { (yyval.expr) = expr_alloc_one(E_NOT, (yyvsp[0].expr)); ;} break; case 101: - { yyval.expr = expr_alloc_two(E_OR, yyvsp[-2].expr, yyvsp[0].expr); ;} + { (yyval.expr) = expr_alloc_two(E_OR, (yyvsp[-2].expr), (yyvsp[0].expr)); ;} break; case 102: - { yyval.expr = expr_alloc_two(E_AND, yyvsp[-2].expr, yyvsp[0].expr); ;} + { (yyval.expr) = expr_alloc_two(E_AND, (yyvsp[-2].expr), (yyvsp[0].expr)); ;} break; case 103: - { yyval.symbol = sym_lookup(yyvsp[0].string, 0); free(yyvsp[0].string); ;} + { (yyval.symbol) = sym_lookup((yyvsp[0].string), 0); free((yyvsp[0].string)); ;} break; case 104: - { yyval.symbol = sym_lookup(yyvsp[0].string, 1); free(yyvsp[0].string); ;} + { (yyval.symbol) = sym_lookup((yyvsp[0].string), 1); free((yyvsp[0].string)); ;} break; } -/* Line 999 of yacc.c. */ +/* Line 1037 of yacc.c. */ yyvsp -= yylen; @@ -1757,18 +1749,33 @@ yyerrlab: { YYSIZE_T yysize = 0; int yytype = YYTRANSLATE (yychar); + const char* yyprefix; char *yymsg; - int yyx, yycount; + int yyx; - yycount = 0; /* Start YYX at -YYN if negative to avoid negative indexes in YYCHECK. */ - for (yyx = yyn < 0 ? -yyn : 0; - yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++) + int yyxbegin = yyn < 0 ? -yyn : 0; + + /* Stay within bounds of both yycheck and yytname. */ + int yychecklim = YYLAST - yyn; + int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; + int yycount = 0; + + yyprefix = ", expecting "; + for (yyx = yyxbegin; yyx < yyxend; ++yyx) if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) - yysize += yystrlen (yytname[yyx]) + 15, yycount++; - yysize += yystrlen ("syntax error, unexpected ") + 1; - yysize += yystrlen (yytname[yytype]); + { + yysize += yystrlen (yyprefix) + yystrlen (yytname [yyx]); + yycount += 1; + if (yycount == 5) + { + yysize = 0; + break; + } + } + yysize += (sizeof ("syntax error, unexpected ") + + yystrlen (yytname[yytype])); yymsg = (char *) YYSTACK_ALLOC (yysize); if (yymsg != 0) { @@ -1777,16 +1784,13 @@ yyerrlab: if (yycount < 5) { - yycount = 0; - for (yyx = yyn < 0 ? -yyn : 0; - yyx < (int) (sizeof (yytname) / sizeof (char *)); - yyx++) + yyprefix = ", expecting "; + for (yyx = yyxbegin; yyx < yyxend; ++yyx) if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) { - const char *yyq = ! yycount ? ", expecting " : " or "; - yyp = yystpcpy (yyp, yyq); + yyp = yystpcpy (yyp, yyprefix); yyp = yystpcpy (yyp, yytname[yyx]); - yycount++; + yyprefix = " or "; } } yyerror (yymsg); @@ -1804,38 +1808,57 @@ yyerrlab: if (yyerrstatus == 3) { - /* If just tried and failed to reuse lookahead token after an + /* If just tried and failed to reuse look-ahead token after an error, discard it. */ - /* Return failure if at end of input. */ - if (yychar == YYEOF) + if (yychar <= YYEOF) { - /* Pop the error token. */ - YYPOPSTACK; - /* Pop the rest of the stack. */ - while (yyss < yyssp) - { - YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); - yydestruct (yystos[*yyssp], yyvsp); - YYPOPSTACK; - } - YYABORT; + /* If at end of input, pop the error token, + then the rest of the stack, then return failure. */ + if (yychar == YYEOF) + for (;;) + { + + YYPOPSTACK; + if (yyssp == yyss) + YYABORT; + yydestruct ("Error: popping", + yystos[*yyssp], yyvsp); + } } - - YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc); - yydestruct (yytoken, &yylval); - yychar = YYEMPTY; - + else + { + yydestruct ("Error: discarding", yytoken, &yylval); + yychar = YYEMPTY; + } } - /* Else will try to reuse lookahead token after shifting the error + /* Else will try to reuse look-ahead token after shifting the error token. */ goto yyerrlab1; -/*----------------------------------------------------. -| yyerrlab1 -- error raised explicitly by an action. | -`----------------------------------------------------*/ +/*---------------------------------------------------. +| yyerrorlab -- error raised explicitly by YYERROR. | +`---------------------------------------------------*/ +yyerrorlab: + +#ifdef __GNUC__ + /* Pacify GCC when the user code never invokes YYERROR and the label + yyerrorlab therefore never appears in user code. */ + if (0) + goto yyerrorlab; +#endif + +yyvsp -= yylen; + yyssp -= yylen; + yystate = *yyssp; + goto yyerrlab1; + + +/*-------------------------------------------------------------. +| yyerrlab1 -- common code for both syntax error and YYERROR. | +`-------------------------------------------------------------*/ yyerrlab1: yyerrstatus = 3; /* Each real token shifted decrements this. */ @@ -1857,22 +1880,22 @@ yyerrlab1: if (yyssp == yyss) YYABORT; - YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); - yydestruct (yystos[yystate], yyvsp); - yyvsp--; - yystate = *--yyssp; + yydestruct ("Error: popping", yystos[yystate], yyvsp); + YYPOPSTACK; + yystate = *yyssp; YY_STACK_PRINT (yyss, yyssp); } if (yyn == YYFINAL) YYACCEPT; - YYDPRINTF ((stderr, "Shifting error token, ")); - *++yyvsp = yylval; + /* Shift the error token. */ + YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); + yystate = yyn; goto yynewstate; @@ -1888,6 +1911,9 @@ yyacceptlab: | yyabortlab -- YYABORT comes here. | `-----------------------------------*/ yyabortlab: + yydestruct ("Error: discarding lookahead", + yytoken, &yylval); + yychar = YYEMPTY; yyresult = 1; goto yyreturn; @@ -1923,18 +1949,18 @@ void conf_parse(const char *name) sym_init(); menu_init(); modules_sym = sym_lookup("MODULES", 0); - rootmenu.prompt = menu_add_prop(P_MENU, "Linux Kernel Configuration", NULL, NULL); + rootmenu.prompt = menu_add_prompt(P_MENU, "Linux Kernel Configuration", NULL); - //zconfdebug = 1; +#if YYDEBUG + if (getenv("ZCONF_DEBUG")) + zconfdebug = 1; +#endif zconfparse(); if (zconfnerrs) exit(1); menu_finalize(&rootmenu); for_all_symbols(i, sym) { - if (!(sym->flags & SYMBOL_CHECKED) && sym_check_deps(sym)) - printf("\n"); - else - sym->flags |= SYMBOL_CHECK_DONE; + sym_check_deps(sym); } sym_change_count = 1; @@ -1949,20 +1975,25 @@ const char *zconf_tokenname(int token) case T_ENDCHOICE: return "endchoice"; case T_IF: return "if"; case T_ENDIF: return "endif"; + case T_DEPENDS: return "depends"; } return ""; } -static bool zconf_endtoken(int token, int starttoken, int endtoken) +static bool zconf_endtoken(struct kconf_id *id, int starttoken, int endtoken) { - if (token != endtoken) { - zconfprint("unexpected '%s' within %s block", zconf_tokenname(token), zconf_tokenname(starttoken)); + if (id->token != endtoken) { + zconf_error("unexpected '%s' within %s block", + kconf_id_strings + id->name, zconf_tokenname(starttoken)); zconfnerrs++; return false; } if (current_menu->file != current_file) { - zconfprint("'%s' in different file than '%s'", zconf_tokenname(token), zconf_tokenname(starttoken)); - zconfprint("location of the '%s'", zconf_tokenname(starttoken)); + zconf_error("'%s' in different file than '%s'", + kconf_id_strings + id->name, zconf_tokenname(starttoken)); + fprintf(stderr, "%s:%d: location of the '%s'\n", + current_menu->file->name, current_menu->lineno, + zconf_tokenname(starttoken)); zconfnerrs++; return false; } @@ -1973,7 +2004,19 @@ static void zconfprint(const char *err, ...) { va_list ap; - fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno() + 1); + fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno()); + va_start(ap, err); + vfprintf(stderr, err, ap); + va_end(ap); + fprintf(stderr, "\n"); +} + +static void zconf_error(const char *err, ...) +{ + va_list ap; + + zconfnerrs++; + fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno()); va_start(ap, err); vfprintf(stderr, err, ap); va_end(ap); @@ -1982,7 +2025,9 @@ static void zconfprint(const char *err, ...) static void zconferror(const char *err) { +#if YYDEBUG fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno() + 1, err); +#endif } void print_quoted_string(FILE *out, const char *str) @@ -2119,6 +2164,7 @@ void zconfdump(FILE *out) } #include "lex.zconf.c" +#include "util.c" #include "confdata.c" #include "expr.c" #include "symbol.c" diff --git a/scripts/kconfig/zconf.tab.o b/scripts/kconfig/zconf.tab.o index 3d1d070f08e892bfbf6ad208776f231e4c1108b7..e14d898256a534dcfd4c3cbe442a5a23e47da158 100644 GIT binary patch literal 66344 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 literal 95696 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

$wac<^DkC8N4X5wasQwZWVG@l)34()T+97~ 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 WLYx-js1P@W^;%eug>f#7>;DJ7H?;-; diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c index 7f393a024..0691aca51 100644 --- a/sound/core/oss/pcm_oss.c +++ b/sound/core/oss/pcm_oss.c @@ -1745,6 +1745,8 @@ static int snd_pcm_oss_open_file(struct file *file, for (idx = 0; idx < 2; idx++) { if (setup[idx].disable) continue; + if (! pcm->streams[idx].substream_count) + continue; /* no matching substream */ if (idx == SNDRV_PCM_STREAM_PLAYBACK) { if (! (f_mode & FMODE_WRITE)) continue; diff --git a/sound/core/timer.c b/sound/core/timer.c index cdeeb639b..4585600ba 100644 --- a/sound/core/timer.c +++ b/sound/core/timer.c @@ -628,8 +628,9 @@ static void snd_timer_tasklet(unsigned long arg) struct snd_timer_instance *ti; struct list_head *p; unsigned long resolution, ticks; + unsigned long flags; - spin_lock(&timer->lock); + spin_lock_irqsave(&timer->lock, flags); /* now process all callbacks */ while (!list_empty(&timer->sack_list_head)) { p = timer->sack_list_head.next; /* get first item */ @@ -649,7 +650,7 @@ static void snd_timer_tasklet(unsigned long arg) spin_lock(&timer->lock); ti->flags &= ~SNDRV_TIMER_IFLG_CALLBACK; } - spin_unlock(&timer->lock); + spin_unlock_irqrestore(&timer->lock, flags); } /* diff --git a/sound/isa/cs423x/Makefile b/sound/isa/cs423x/Makefile index d2afaea30..2fb4f7409 100644 --- a/sound/isa/cs423x/Makefile +++ b/sound/isa/cs423x/Makefile @@ -11,6 +11,7 @@ snd-cs4236-objs := cs4236.o # Toplevel Module Dependency obj-$(CONFIG_SND_AZT2320) += snd-cs4231-lib.o +obj-$(CONFIG_SND_MIRO) += snd-cs4231-lib.o obj-$(CONFIG_SND_OPL3SA2) += snd-cs4231-lib.o obj-$(CONFIG_SND_CS4231) += snd-cs4231.o snd-cs4231-lib.o obj-$(CONFIG_SND_CS4232) += snd-cs4232.o snd-cs4231-lib.o diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig index a2081803a..8f34986dd 100644 --- a/sound/pci/Kconfig +++ b/sound/pci/Kconfig @@ -318,17 +318,19 @@ config SND_FM801 To compile this driver as a module, choose M here: the module will be called snd-fm801. -config SND_FM801_TEA575X - tristate "ForteMedia FM801 + TEA5757 tuner" +config SND_FM801_TEA575X_BOOL + bool "ForteMedia FM801 + TEA5757 tuner" depends on SND_FM801 - select VIDEO_DEV help Say Y here to include support for soundcards based on the ForteMedia FM801 chip with a TEA5757 tuner connected to GPIO1-3 pins (Media - Forte SF256-PCS-02). + Forte SF256-PCS-02) into the snd-fm801 driver. - To compile this driver as a module, choose M here: the module - will be called snd-fm801-tea575x. +config SND_FM801_TEA575X + tristate + depends on SND_FM801_TEA575X_BOOL + default SND_FM801 + select VIDEO_DEV config SND_HDA_INTEL tristate "Intel HD Audio" diff --git a/sound/pci/au88x0/au88x0_mpu401.c b/sound/pci/au88x0/au88x0_mpu401.c index 873f486b0..118dcc71e 100644 --- a/sound/pci/au88x0/au88x0_mpu401.c +++ b/sound/pci/au88x0/au88x0_mpu401.c @@ -47,7 +47,7 @@ static int __devinit snd_vortex_midi(vortex_t * vortex) struct snd_rawmidi *rmidi; int temp, mode; struct snd_mpu401 *mpu; - int port; + unsigned long port; #ifdef VORTEX_MPU401_LEGACY /* EnableHardCodedMPU401Port() */ diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c index d72fc28c5..09a2885ca 100644 --- a/sound/pci/fm801.c +++ b/sound/pci/fm801.c @@ -35,7 +35,7 @@ #include -#if (defined(CONFIG_SND_FM801_TEA575X) || defined(CONFIG_SND_FM801_TEA575X_MODULE)) && (defined(CONFIG_VIDEO_DEV) || defined(CONFIG_VIDEO_DEV_MODULE)) +#ifdef CONFIG_SND_FM801_TEA575X_BOOL #include #define TEA575X_RADIO 1 #endif diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index e821d65af..9dd541df6 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -1393,10 +1393,10 @@ static int azx_free(struct azx *chip) msleep(1); } - if (chip->remap_addr) - iounmap(chip->remap_addr); if (chip->irq >= 0) free_irq(chip->irq, (void*)chip); + if (chip->remap_addr) + iounmap(chip->remap_addr); if (chip->bdl.area) snd_dma_free_pages(&chip->bdl); diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index 40f000ba1..d7343dc82 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c @@ -1488,6 +1488,9 @@ enum { /* reivision id to check workarounds */ #define AD1988A_REV2 0x100200 +#define is_rev2(codec) \ + ((codec)->vendor_id == 0x11d41988 && \ + (codec)->revision_id == AD1988A_REV2) /* * mixers @@ -1579,6 +1582,7 @@ static struct snd_kcontrol_new ad1988_6stack_mixers1[] = { HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x05, 2, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Side Playback Volume", 0x0a, 0x0, HDA_OUTPUT), + { } /* end */ }; static struct snd_kcontrol_new ad1988_6stack_mixers1_rev2[] = { @@ -1587,6 +1591,7 @@ static struct snd_kcontrol_new ad1988_6stack_mixers1_rev2[] = { HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0a, 2, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Side Playback Volume", 0x06, 0x0, HDA_OUTPUT), + { } /* end */ }; static struct snd_kcontrol_new ad1988_6stack_mixers2[] = { @@ -1625,6 +1630,7 @@ static struct snd_kcontrol_new ad1988_3stack_mixers1[] = { HDA_CODEC_VOLUME("Surround Playback Volume", 0x0a, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x05, 2, 0x0, HDA_OUTPUT), + { } /* end */ }; static struct snd_kcontrol_new ad1988_3stack_mixers1_rev2[] = { @@ -1632,6 +1638,7 @@ static struct snd_kcontrol_new ad1988_3stack_mixers1_rev2[] = { HDA_CODEC_VOLUME("Surround Playback Volume", 0x0a, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x06, 1, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x06, 2, 0x0, HDA_OUTPUT), + { } /* end */ }; static struct snd_kcontrol_new ad1988_3stack_mixers2[] = { @@ -2138,7 +2145,7 @@ static inline hda_nid_t ad1988_idx_to_dac(struct hda_codec *codec, int idx) /* A B C D E F G H */ 0x04, 0x05, 0x0a, 0x04, 0x06, 0x05, 0x0a, 0x06 }; - if (codec->revision_id == AD1988A_REV2) + if (is_rev2(codec)) return idx_to_dac_rev2[idx]; else return idx_to_dac[idx]; @@ -2507,7 +2514,7 @@ static int patch_ad1988(struct hda_codec *codec) mutex_init(&spec->amp_mutex); codec->spec = spec; - if (codec->revision_id == AD1988A_REV2) + if (is_rev2(codec)) snd_printk(KERN_INFO "patch_analog: AD1988A rev.2 is detected, enable workarounds\n"); board_config = snd_hda_check_board_config(codec, ad1988_cfg_tbl); @@ -2533,13 +2540,13 @@ static int patch_ad1988(struct hda_codec *codec) case AD1988_6STACK_DIG: spec->multiout.max_channels = 8; spec->multiout.num_dacs = 4; - if (codec->revision_id == AD1988A_REV2) + if (is_rev2(codec)) spec->multiout.dac_nids = ad1988_6stack_dac_nids_rev2; else spec->multiout.dac_nids = ad1988_6stack_dac_nids; spec->input_mux = &ad1988_6stack_capture_source; spec->num_mixers = 2; - if (codec->revision_id == AD1988A_REV2) + if (is_rev2(codec)) spec->mixers[0] = ad1988_6stack_mixers1_rev2; else spec->mixers[0] = ad1988_6stack_mixers1; @@ -2555,7 +2562,7 @@ static int patch_ad1988(struct hda_codec *codec) case AD1988_3STACK_DIG: spec->multiout.max_channels = 6; spec->multiout.num_dacs = 3; - if (codec->revision_id == AD1988A_REV2) + if (is_rev2(codec)) spec->multiout.dac_nids = ad1988_3stack_dac_nids_rev2; else spec->multiout.dac_nids = ad1988_3stack_dac_nids; @@ -2563,7 +2570,7 @@ static int patch_ad1988(struct hda_codec *codec) spec->channel_mode = ad1988_3stack_modes; spec->num_channel_mode = ARRAY_SIZE(ad1988_3stack_modes); spec->num_mixers = 2; - if (codec->revision_id == AD1988A_REV2) + if (is_rev2(codec)) spec->mixers[0] = ad1988_3stack_mixers1_rev2; else spec->mixers[0] = ad1988_3stack_mixers1; diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index f0e9a9c90..94cf292d9 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -3827,7 +3827,7 @@ static struct hda_board_config alc260_cfg_tbl[] = { { .modelname = "hp", .config = ALC260_HP }, { .pci_subvendor = 0x103c, .pci_subdevice = 0x3010, .config = ALC260_HP }, { .pci_subvendor = 0x103c, .pci_subdevice = 0x3011, .config = ALC260_HP }, - { .pci_subvendor = 0x103c, .pci_subdevice = 0x3012, .config = ALC260_HP }, + { .pci_subvendor = 0x103c, .pci_subdevice = 0x3012, .config = ALC260_HP_3013 }, { .pci_subvendor = 0x103c, .pci_subdevice = 0x3013, .config = ALC260_HP_3013 }, { .pci_subvendor = 0x103c, .pci_subdevice = 0x3014, .config = ALC260_HP }, { .pci_subvendor = 0x103c, .pci_subdevice = 0x3015, .config = ALC260_HP }, diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 8c440fb98..d8622951c 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -1262,13 +1262,13 @@ static int vaio_master_sw_put(struct snd_kcontrol *kcontrol, int change; change = snd_hda_codec_amp_update(codec, 0x02, 0, HDA_OUTPUT, 0, - 0x80, valp[0] & 0x80); + 0x80, (valp[0] ? 0 : 0x80)); change |= snd_hda_codec_amp_update(codec, 0x02, 1, HDA_OUTPUT, 0, - 0x80, valp[1] & 0x80); + 0x80, (valp[1] ? 0 : 0x80)); snd_hda_codec_amp_update(codec, 0x05, 0, HDA_OUTPUT, 0, - 0x80, valp[0] & 0x80); + 0x80, (valp[0] ? 0 : 0x80)); snd_hda_codec_amp_update(codec, 0x05, 1, HDA_OUTPUT, 0, - 0x80, valp[1] & 0x80); + 0x80, (valp[1] ? 0 : 0x80)); return change; } diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c index 61f82f0d5..10586e48a 100644 --- a/sound/pci/rme9652/hdsp.c +++ b/sound/pci/rme9652/hdsp.c @@ -389,7 +389,7 @@ MODULE_SUPPORTED_DEVICE("{{RME Hammerfall-DSP}," /* use hotplug firmeare loader? */ #if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE) -#ifndef HDSP_USE_HWDEP_LOADER +#if !defined(HDSP_USE_HWDEP_LOADER) && !defined(CONFIG_SND_HDSP) #define HDSP_FW_LOADER #endif #endif @@ -3169,9 +3169,10 @@ snd_hdsp_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer) char *clock_source; int x; - if (hdsp_check_for_iobox (hdsp)) + if (hdsp_check_for_iobox (hdsp)) { snd_iprintf(buffer, "No I/O box connected.\nPlease connect one and upload firmware.\n"); return; + } if (hdsp_check_for_firmware(hdsp, 0)) { if (hdsp->state & HDSP_FirmwareCached) { -- 2.51.1