Merge to Fedora kernel-2.6.17-1.2187_FC5 patched with stable patch-2.6.17.13-vs2...
authorMarc Fiuczynski <mef@cs.princeton.edu>
Thu, 19 Oct 2006 02:13:07 +0000 (02:13 +0000)
committerMarc Fiuczynski <mef@cs.princeton.edu>
Thu, 19 Oct 2006 02:13:07 +0000 (02:13 +0000)
337 files changed:
.config
.config.old
Documentation/networking/netdevices.txt
MAINTAINERS
arch/i386/Kconfig
arch/i386/Kconfig.cpu
arch/i386/Kconfig.debug
arch/i386/Makefile
arch/i386/kernel/Makefile
arch/i386/kernel/acpi/Makefile
arch/i386/kernel/asm-offsets.c
arch/i386/kernel/cpu/Makefile
arch/i386/kernel/cpu/cpufreq/powernow-k7.c
arch/i386/kernel/cpu/cpufreq/powernow-k8.c
arch/i386/kernel/cpu/mtrr/Makefile
arch/i386/kernel/entry.S
arch/i386/kernel/irq.c
arch/i386/kernel/reboot.c
arch/i386/kernel/sysenter.c
arch/i386/kernel/traps.c
arch/i386/kernel/vm86.c
arch/i386/mm/Makefile
arch/i386/mm/pageattr.c
arch/i386/mm/pgtable.c
arch/i386/oprofile/Makefile
arch/i386/pci/Makefile
arch/i386/pci/mmconfig.c
arch/i386/power/Makefile
arch/ia64/Kconfig
arch/ia64/kernel/sys_ia64.c
arch/ia64/sn/kernel/xpc_channel.c
arch/ia64/sn/kernel/xpc_main.c
arch/ia64/sn/kernel/xpc_partition.c
arch/powerpc/Kconfig
arch/powerpc/kernel/cpu_setup_power4.S
arch/powerpc/kernel/crash.c
arch/powerpc/platforms/pseries/xics.c
arch/sparc/kernel/sys_sparc.c
arch/sparc64/kernel/sys_sparc.c
arch/sparc64/mm/generic.c
arch/um/kernel/physmem.c
arch/x86_64/Kconfig
arch/x86_64/Makefile
arch/x86_64/ia32/Makefile
arch/x86_64/ia32/vsyscall-sigreturn.S
arch/x86_64/kernel/Makefile
arch/x86_64/kernel/acpi/Makefile
arch/x86_64/kernel/asm-offsets.c
arch/x86_64/kernel/entry.S
arch/x86_64/kernel/init_task.c
arch/x86_64/kernel/irq.c
arch/x86_64/kernel/pmtimer.c
arch/x86_64/kernel/setup.c
arch/x86_64/kernel/setup64.c
arch/x86_64/kernel/smp.c
arch/x86_64/mm/Makefile
arch/x86_64/oprofile/Makefile
arch/x86_64/pci/Makefile
arch/x86_64/pci/mmconfig.c
block/elevator.c
block/ll_rw_blk.c
configs/kernel-2.6.17-i586.config
configs/kernel-2.6.17-i686-smp.config
configs/kernel-2.6.17-i686.config
drivers/Makefile
drivers/acpi/Kconfig
drivers/acpi/namespace/nsxfeval.c
drivers/block/aoe/aoenet.c
drivers/cdrom/cdrom.c
drivers/char/mem.c
drivers/char/tpm/tpm_tis.c
drivers/char/tty_io.c
drivers/firmware/Kconfig
drivers/i2c/busses/scx200_acb.c
drivers/i2c/i2c-core.c
drivers/ide/ide-lib.c
drivers/ide/pci/via82cxxx.c
drivers/ieee1394/ohci1394.c
drivers/ieee1394/sbp2.c
drivers/infiniband/hw/mthca/mthca_reset.c
drivers/infiniband/ulp/ipoib/ipoib_multicast.c
drivers/md/dm-exception-store.c
drivers/md/dm-ioctl.c
drivers/md/dm-mpath.c
drivers/md/dm-raid1.c
drivers/md/dm-snap.c
drivers/md/dm.c
drivers/md/raid1.c
drivers/media/dvb/bt8xx/dvb-bt8xx.c
drivers/media/dvb/bt8xx/dvb-bt8xx.h
drivers/media/dvb/dvb-core/dvb_frontend.c
drivers/media/dvb/dvb-core/dvb_net.c
drivers/media/dvb/frontends/dvb-pll.c
drivers/media/dvb/ttpci/budget-av.c
drivers/media/dvb/ttpci/budget.c
drivers/media/video/Kconfig
drivers/media/video/stradis.c
drivers/net/8139cp.c
drivers/net/bnx2.c
drivers/net/bonding/bond_main.c
drivers/net/chelsio/sge.c
drivers/net/e1000/e1000_hw.c
drivers/net/e1000/e1000_hw.h
drivers/net/e1000/e1000_main.c
drivers/net/forcedeth.c
drivers/net/hamradio/6pack.c
drivers/net/hamradio/mkiss.c
drivers/net/ifb.c
drivers/net/irda/vlsi_ir.c
drivers/net/ixgb/ixgb_main.c
drivers/net/loopback.c
drivers/net/mv643xx_eth.c
drivers/net/natsemi.c
drivers/net/r8169.c
drivers/net/s2io.c
drivers/net/sky2.c
drivers/net/sky2.h
drivers/net/tg3.c
drivers/net/tg3.h
drivers/net/tulip/winbond-840.c
drivers/net/typhoon.c
drivers/net/via-velocity.c
drivers/net/wireless/orinoco.c
drivers/net/wireless/spectrum_cs.c
drivers/oprofile/buffer_sync.c
drivers/oprofile/cpu_buffer.c
drivers/oprofile/cpu_buffer.h
drivers/oprofile/event_buffer.h
drivers/oprofile/oprof.c
drivers/oprofile/oprof.h
drivers/oprofile/oprofile_files.c
drivers/pci/Kconfig
drivers/pci/quirks.c
drivers/pnp/resource.c
drivers/s390/net/qeth_eddp.c
drivers/s390/net/qeth_main.c
drivers/s390/net/qeth_tso.h
drivers/scsi/Makefile
drivers/scsi/iscsi_tcp.c
drivers/scsi/iscsi_tcp.h
drivers/scsi/scsi_ioctl.c
drivers/scsi/scsi_transport_iscsi.c
drivers/serial/8250.c
drivers/serial/Kconfig
drivers/serial/serial_core.c
drivers/usb/host/uhci-q.c
drivers/usb/serial/ftdi_sio.c
drivers/usb/storage/unusual_devs.h
drivers/usb/storage/usb.c
drivers/video/Kconfig
drivers/video/console/softcursor.c
drivers/xen/Makefile
drivers/xen/balloon/balloon.c
drivers/xen/blkback/Makefile
drivers/xen/blkback/blkback.c
drivers/xen/blkback/common.h
drivers/xen/blkback/interface.c
drivers/xen/blkback/vbd.c
drivers/xen/blkfront/Makefile
drivers/xen/blkfront/blkfront.c
drivers/xen/blkfront/block.h
drivers/xen/blkfront/vbd.c
drivers/xen/blktap/Makefile
drivers/xen/blktap/blktap.c
drivers/xen/console/Makefile
drivers/xen/console/console.c
drivers/xen/evtchn/evtchn.c
drivers/xen/netback/Makefile
drivers/xen/netback/common.h
drivers/xen/netback/interface.c
drivers/xen/netback/netback.c
drivers/xen/netfront/Makefile
drivers/xen/netfront/netfront.c
drivers/xen/privcmd/Makefile
drivers/xen/privcmd/privcmd.c
fs/Kconfig
fs/befs/linuxvfs.c
fs/binfmt_elf.c
fs/buffer.c
fs/ext2/super.c
fs/ext3/inode.c
fs/ext3/namei.c
fs/ext3/super.c
fs/file.c
fs/locks.c
fs/namei.c
fs/proc/base.c
fs/splice.c
fs/udf/super.c
fs/udf/truncate.c
fs/xfs/xfs_dir2_node.c
include/asm-generic/mman.h
include/asm-i386/apic.h
include/asm-i386/desc.h
include/asm-i386/fixmap.h
include/asm-i386/mach-default/mach_traps.h
include/asm-i386/page.h
include/asm-i386/pgtable-2level-defs.h
include/asm-i386/pgtable-3level-defs.h
include/asm-i386/spinlock.h
include/asm-ia64/mman.h
include/asm-ia64/sn/xp.h
include/asm-ia64/sn/xpc.h
include/asm-s390/futex.h
include/asm-sparc/mman.h
include/asm-sparc64/mman.h
include/asm-sparc64/sfp-machine.h
include/asm-um/page.h
include/asm-x86_64/apic.h
include/asm-x86_64/hw_irq.h
include/asm-x86_64/ipi.h
include/asm-x86_64/pgtable.h
include/linux/autoconf.h
include/linux/ethtool.h
include/linux/ext3_fs.h
include/linux/gfp.h
include/linux/highmem.h
include/linux/idr.h
include/linux/interrupt.h
include/linux/mm.h
include/linux/netdevice.h
include/linux/netfilter_bridge.h
include/linux/oprofile.h
include/linux/pci_ids.h
include/linux/pfn.h
include/linux/skbuff.h
include/linux/tty.h
include/net/pkt_sched.h
include/net/protocol.h
include/net/sctp/sctp.h
include/net/sctp/sm.h
include/net/sock.h
include/net/tcp.h
include/scsi/iscsi_if.h
include/scsi/iscsi_proto.h
include/scsi/scsi_transport_iscsi.h
include/sound/initval.h
kernel/Kconfig.preempt
kernel/fork.c
kernel/futex.c
kernel/irq/manage.c
kernel/irq/spurious.c
kernel/sched.c
kernel/stop_machine.c
kernel/timer.c
lib/Makefile
lib/idr.c
lib/spinlock_debug.c
lib/ts_bm.c
mm/Kconfig
mm/filemap.c
mm/filemap.h
mm/highmem.c
mm/memory.c
mm/mmap.c
mm/page_alloc.c
mm/pdflush.c
mm/swapfile.c
net/8021q/vlan.c
net/atm/clip.c
net/bridge/br_device.c
net/bridge/br_forward.c
net/bridge/br_if.c
net/bridge/br_netfilter.c
net/bridge/netfilter/ebt_ulog.c
net/core/dev.c
net/core/dev_mcast.c
net/core/dst.c
net/core/ethtool.c
net/core/netpoll.c
net/core/pktgen.c
net/core/rtnetlink.c
net/core/skbuff.c
net/decnet/dn_nsp_in.c
net/decnet/dn_route.c
net/decnet/dn_rules.c
net/ieee80211/Kconfig
net/ipv4/af_inet.c
net/ipv4/fib_rules.c
net/ipv4/fib_semantics.c
net/ipv4/ip_output.c
net/ipv4/ipcomp.c
net/ipv4/netfilter/arp_tables.c
net/ipv4/netfilter/ip_conntrack_helper_h323.c
net/ipv4/netfilter/ip_nat_proto_tcp.c
net/ipv4/netfilter/ip_nat_proto_udp.c
net/ipv4/netfilter/ip_tables.c
net/ipv4/netfilter/ipt_ULOG.c
net/ipv4/route.c
net/ipv4/tcp.c
net/ipv4/tcp_input.c
net/ipv4/tcp_ipv4.c
net/ipv4/tcp_output.c
net/ipv4/xfrm4_output.c
net/ipv6/addrconf.c
net/ipv6/exthdrs.c
net/ipv6/ip6_output.c
net/ipv6/ipcomp6.c
net/ipv6/xfrm6_output.c
net/ipx/af_ipx.c
net/netfilter/nfnetlink_log.c
net/sched/act_api.c
net/sched/sch_generic.c
net/sched/sch_teql.c
net/sctp/sm_make_chunk.c
net/sctp/sm_statefuns.c
net/sctp/socket.c
net/sunrpc/cache.c
scripts/basic/.docproc.cmd
scripts/basic/.fixdep.cmd
scripts/basic/.split-include.cmd
scripts/basic/docproc
scripts/basic/fixdep
scripts/basic/split-include
scripts/kconfig/.conf.cmd
scripts/kconfig/.conf.o.cmd
scripts/kconfig/.kxgettext.o.cmd
scripts/kconfig/.mconf.o.cmd
scripts/kconfig/.zconf.tab.o.cmd
scripts/kconfig/conf
scripts/kconfig/conf.o
scripts/kconfig/kxgettext.o
scripts/kconfig/lex.zconf.c
scripts/kconfig/mconf.o
scripts/kconfig/zconf.tab.c
scripts/kconfig/zconf.tab.o
sound/core/oss/pcm_oss.c
sound/core/timer.c
sound/isa/cs423x/Makefile
sound/pci/Kconfig
sound/pci/au88x0/au88x0_mpu401.c
sound/pci/fm801.c
sound/pci/hda/hda_intel.c
sound/pci/hda/patch_analog.c
sound/pci/hda/patch_realtek.c
sound/pci/hda/patch_sigmatel.c
sound/pci/rme9652/hdsp.c

diff --git a/.config b/.config
index de7e3e7..4094095 100644 (file)
--- a/.config
+++ b/.config
@@ -1,40 +1,61 @@
 #
 # Automatically generated make config: don't edit
 #
 # 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_X86=y
 CONFIG_MMU=y
-CONFIG_UID16=y
 CONFIG_GENERIC_ISA_DMA=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
 
 #
 # 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
 #
 
 #
 # 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_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_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_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_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_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
 
 #
 # 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_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_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
 #
 
 #
 # 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_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_ES7000 is not set
-CONFIG_X86_CYCLONE_TIMER=y
 # CONFIG_M386 is not set
 # CONFIG_M486 is not set
 # CONFIG_M586 is not set
 # 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_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_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
 # 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_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_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_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_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_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_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_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_MICROCODE=m
 CONFIG_X86_MSR=m
 CONFIG_X86_CPUID=m
+# CONFIG_SWIOTLB is not set
 
 #
 # Firmware Drivers
 #
 CONFIG_EDD=m
 
 #
 # Firmware Drivers
 #
 CONFIG_EDD=m
+CONFIG_EFI_VARS=y
+CONFIG_DELL_RBU=m
+CONFIG_DCDBAS=m
 # CONFIG_NOHIGHMEM is not set
 # 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_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_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_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
 
 #
 # 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
 
 #
 # 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=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_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_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_TOSHIBA=m
+CONFIG_ACPI_BLACKLIST_YEAR=1999
 # CONFIG_ACPI_DEBUG is not set
 # CONFIG_ACPI_DEBUG is not set
-CONFIG_ACPI_BUS=y
 CONFIG_ACPI_EC=y
 CONFIG_ACPI_POWER=y
 CONFIG_ACPI_EC=y
 CONFIG_ACPI_POWER=y
-CONFIG_ACPI_PCI=y
 CONFIG_ACPI_SYSTEM=y
 CONFIG_X86_PM_TIMER=y
 CONFIG_ACPI_SYSTEM=y
 CONFIG_X86_PM_TIMER=y
+# CONFIG_ACPI_CONTAINER is not set
 
 #
 # APM (Advanced Power Management) BIOS Support
 
 #
 # APM (Advanced Power Management) BIOS Support
@@ -180,34 +252,43 @@ CONFIG_APM_RTC_IS_GMT=y
 # CPU Frequency scaling
 #
 CONFIG_CPU_FREQ=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_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
 
 #
 # 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_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_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_ACPI=y
+CONFIG_X86_SPEEDSTEP_CENTRINO_TABLE=y
 CONFIG_X86_SPEEDSTEP_ICH=y
 CONFIG_X86_SPEEDSTEP_ICH=y
-CONFIG_X86_SPEEDSTEP_SMI=m
+CONFIG_X86_SPEEDSTEP_SMI=y
 CONFIG_X86_P4_CLOCKMOD=m
 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_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)
 
 #
 # 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_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_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
 
 #
 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_PCMCIA_DEBUG is not set
-CONFIG_YENTA=m
+CONFIG_PCMCIA=y
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
 CONFIG_CARDBUS=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_I82092=m
-CONFIG_I82365=m
-CONFIG_TCIC=m
+# CONFIG_I82365 is not set
+# CONFIG_TCIC is not set
 CONFIG_PCMCIA_PROBE=y
 CONFIG_PCMCIA_PROBE=y
+CONFIG_PCCARD_NONSTATIC=y
 
 #
 # PCI Hotplug Support
 #
 CONFIG_HOTPLUG_PCI=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_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_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
 
 #
 # 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_NETDEVICES=y
 CONFIG_DUMMY=m
 CONFIG_BONDING=m
 CONFIG_EQUALIZER=m
 CONFIG_TUN=m
-CONFIG_ETHERTAP=m
 CONFIG_NET_SB1000=m
 
 #
 CONFIG_NET_SB1000=m
 
 #
@@ -1027,6 +1327,20 @@ CONFIG_NET_SB1000=m
 #
 # CONFIG_ARCNET is not set
 
 #
 # 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)
 #
 #
 # Ethernet (10 or 100Mbit)
 #
@@ -1034,23 +1348,22 @@ CONFIG_NET_ETHERNET=y
 CONFIG_MII=m
 CONFIG_HAPPYMEAL=m
 CONFIG_SUNGEM=m
 CONFIG_MII=m
 CONFIG_HAPPYMEAL=m
 CONFIG_SUNGEM=m
+CONFIG_CASSINI=m
 CONFIG_NET_VENDOR_3COM=y
 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_EL3=m
-CONFIG_3C515=m
+# CONFIG_3C515 is not set
 CONFIG_VORTEX=m
 CONFIG_TYPHOON=m
 CONFIG_VORTEX=m
 CONFIG_TYPHOON=m
-CONFIG_LANCE=m
+# CONFIG_LANCE is not set
 CONFIG_NET_VENDOR_SMC=y
 CONFIG_NET_VENDOR_SMC=y
-CONFIG_WD80x3=m
+# CONFIG_WD80x3 is not set
 CONFIG_ULTRA=m
 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
 
 #
 # Tulip family network device support
@@ -1064,34 +1377,44 @@ CONFIG_TULIP_MMIO=y
 CONFIG_DE4X5=m
 CONFIG_WINBOND_840=m
 CONFIG_DM9102=m
 CONFIG_DE4X5=m
 CONFIG_WINBOND_840=m
 CONFIG_DM9102=m
+CONFIG_ULI526X=m
 CONFIG_PCMCIA_XIRCOM=m
 CONFIG_PCMCIA_XIRCOM=m
+# CONFIG_PCMCIA_XIRTULIP is not set
 # CONFIG_AT1700 is not set
 # CONFIG_AT1700 is not set
-CONFIG_DEPCA=m
+# CONFIG_DEPCA is not set
 CONFIG_HP100=m
 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_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_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_B44=m
 CONFIG_FORCEDETH=m
-CONFIG_CS89x0=m
+# CONFIG_CS89x0 is not set
 CONFIG_DGRS=m
 CONFIG_DGRS=m
-CONFIG_EEPRO100=m
-# CONFIG_EEPRO100_PIO is not set
+# CONFIG_EEPRO100 is not set
 CONFIG_E100=m
 CONFIG_E100=m
-CONFIG_E100_NAPI=y
 CONFIG_FEALNX=m
 CONFIG_NATSEMI=m
 CONFIG_NE2K_PCI=m
 CONFIG_8139CP=m
 CONFIG_8139TOO=m
 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
 # 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
 
 #
 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_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_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_TIGON3=m
+CONFIG_BNX2=m
+
+#
+# Ethernet (10000 Mbit)
+#
+CONFIG_CHELSIO_T1=m
 CONFIG_IXGB=m
 CONFIG_IXGB_NAPI=y
 CONFIG_S2IO=m
 CONFIG_IXGB=m
 CONFIG_IXGB_NAPI=y
 CONFIG_S2IO=m
@@ -1130,19 +1465,26 @@ CONFIG_S2IO_NAPI=y
 #
 # Token Ring devices
 #
 #
 # 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
 
 #
 # 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
 
 #
 # 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
 
 CONFIG_PCMCIA_WAVELAN=m
 CONFIG_PCMCIA_NETWAVE=m
 
@@ -1154,10 +1496,18 @@ CONFIG_PCMCIA_NETWAVE=m
 #
 # Wireless 802.11b ISA/PCI cards support
 #
 #
 # 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_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_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
 # 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_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
 # 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
 
 #
 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_SMC91C92=m
 CONFIG_PCMCIA_XIRC2PS=m
 CONFIG_PCMCIA_AXNET=m
+CONFIG_PCMCIA_IBMTR=m
 
 #
 # Wan interfaces
 #
 # CONFIG_WAN is not set
 
 #
 # 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
 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_SYNC_TTY=m
 CONFIG_PPP_DEFLATE=m
 # CONFIG_PPP_BSDCOMP is not set
+CONFIG_PPP_MPPE=m
 CONFIG_PPPOE=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_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
 
 #
 # ISDN subsystem
@@ -1231,6 +1633,8 @@ CONFIG_ISDN_TTY_FAX=y
 #
 # ISDN feature submodules
 #
 #
 # ISDN feature submodules
 #
+CONFIG_ISDN_DRV_LOOP=m
+CONFIG_ISDN_DIVERSION=m
 
 #
 # ISDN4Linux hardware drivers
 
 #
 # ISDN4Linux hardware drivers
@@ -1256,27 +1660,27 @@ CONFIG_HISAX_MAX_CARDS=8
 #
 # HiSax supported cards
 #
 #
 # 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_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_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_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_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_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
 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
 # 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_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
 
 #
 # CAPI subsystem
@@ -1330,6 +1745,14 @@ CONFIG_ISDN_CAPI_CAPIDRV=m
 # Active AVM cards
 #
 CONFIG_CAPI_AVM=y
 # 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
 
 #
 # Active Eicon DIVA Server cards
@@ -1364,24 +1787,6 @@ CONFIG_INPUT_JOYDEV=m
 CONFIG_INPUT_EVDEV=y
 # CONFIG_INPUT_EVBUG is not set
 
 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
 #
 #
 # Input Device Drivers
 #
@@ -1394,10 +1799,9 @@ CONFIG_KEYBOARD_ATKBD=y
 CONFIG_INPUT_MOUSE=y
 CONFIG_MOUSE_PS2=y
 CONFIG_MOUSE_SERIAL=m
 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
 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_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_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_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_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
 
 #
 # Character devices
@@ -1437,33 +1862,50 @@ CONFIG_VT=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
 CONFIG_SERIAL_NONSTANDARD=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_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=m
 CONFIG_SYNCLINKMP=m
+# CONFIG_SYNCLINK_GT is not set
 CONFIG_N_HDLC=m
 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
 
 #
 # 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_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_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_SHARE_IRQ=y
 CONFIG_SERIAL_8250_DETECT_IRQ=y
-CONFIG_SERIAL_8250_MULTIPORT=y
 CONFIG_SERIAL_8250_RSA=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
 
 #
 # 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
 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_LP_CONSOLE=y
 CONFIG_PPDEV=m
 CONFIG_TIPAR=m
-# CONFIG_QIC02_TAPE is not set
 
 #
 # IPMI
 
 #
 # IPMI
@@ -1481,6 +1922,7 @@ CONFIG_IPMI_HANDLER=m
 CONFIG_IPMI_DEVICE_INTERFACE=m
 CONFIG_IPMI_SI=m
 CONFIG_IPMI_WATCHDOG=m
 CONFIG_IPMI_DEVICE_INTERFACE=m
 CONFIG_IPMI_SI=m
 CONFIG_IPMI_WATCHDOG=m
+CONFIG_IPMI_POWEROFF=m
 
 #
 # Watchdog Cards
 
 #
 # Watchdog Cards
@@ -1492,30 +1934,33 @@ CONFIG_WATCHDOG=y
 # Watchdog Device Drivers
 #
 CONFIG_SOFT_WATCHDOG=m
 # 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_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_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_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_W83627HF_WDT=m
 CONFIG_W83877F_WDT=m
+CONFIG_W83977F_WDT=m
 CONFIG_MACHZ_WDT=m
 CONFIG_MACHZ_WDT=m
+# CONFIG_SBC_EPX_C3_WATCHDOG is not set
 
 #
 # ISA-based Watchdog Cards
 #
 
 #
 # ISA-based Watchdog Cards
 #
-CONFIG_PCWATCHDOG=m
+# CONFIG_PCWATCHDOG is not set
 # CONFIG_MIXCOMWD 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
 
 #
 # PCI-based Watchdog Cards
@@ -1529,7 +1974,7 @@ CONFIG_WDT_501_PCI=y
 #
 CONFIG_USBPCWATCHDOG=m
 CONFIG_HW_RANDOM=m
 #
 CONFIG_USBPCWATCHDOG=m
 CONFIG_HW_RANDOM=m
-CONFIG_NVRAM=m
+CONFIG_NVRAM=y
 CONFIG_RTC=y
 CONFIG_DTLK=m
 CONFIG_R3964=m
 CONFIG_RTC=y
 CONFIG_DTLK=m
 CONFIG_R3964=m
@@ -1539,36 +1984,50 @@ CONFIG_SONYPI=m
 #
 # Ftape, the floppy tape device driver
 #
 #
 # 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=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_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_TDFX=m
-CONFIG_DRM_GAMMA=m
 CONFIG_DRM_R128=m
 CONFIG_DRM_RADEON=m
 CONFIG_DRM_I810=m
 CONFIG_DRM_I830=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_MGA=m
 CONFIG_DRM_SIS=m
+CONFIG_DRM_VIA=m
+CONFIG_DRM_SAVAGE=m
 
 #
 # PCMCIA character devices
 #
 CONFIG_SYNCLINK_CS=m
 
 #
 # PCMCIA character devices
 #
 CONFIG_SYNCLINK_CS=m
+CONFIG_CARDMAN_4000=m
+CONFIG_CARDMAN_4040=m
 CONFIG_MWAVE=m
 CONFIG_MWAVE=m
+CONFIG_CS5535_GPIO=m
 # CONFIG_RAW_DRIVER is not set
 # 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
 
 CONFIG_HANGCHECK_TIMER=m
 
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+
 #
 # I2C support
 #
 #
 # I2C support
 #
@@ -1580,6 +2039,7 @@ CONFIG_I2C_CHARDEV=m
 #
 CONFIG_I2C_ALGOBIT=m
 CONFIG_I2C_ALGOPCF=m
 #
 CONFIG_I2C_ALGOBIT=m
 CONFIG_I2C_ALGOPCF=m
+CONFIG_I2C_ALGOPCA=m
 
 #
 # I2C Hardware Bus support
 
 #
 # 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_ALI1563=m
 CONFIG_I2C_ALI15X3=m
 CONFIG_I2C_AMD756=m
+CONFIG_I2C_AMD756_S4882=m
 CONFIG_I2C_AMD8111=m
 CONFIG_I2C_AMD8111=m
+# CONFIG_I2C_ELEKTOR is not set
 CONFIG_I2C_I801=m
 CONFIG_I2C_I810=m
 CONFIG_I2C_I801=m
 CONFIG_I2C_I810=m
+CONFIG_I2C_PIIX4=m
 CONFIG_I2C_ISA=m
 CONFIG_I2C_NFORCE2=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_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_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_ADM1021=m
+CONFIG_SENSORS_ADM1025=m
+CONFIG_SENSORS_ADM1026=m
+CONFIG_SENSORS_ADM1031=m
+CONFIG_SENSORS_ADM9240=m
 CONFIG_SENSORS_ASB100=m
 CONFIG_SENSORS_ASB100=m
+CONFIG_SENSORS_ATXP1=m
 CONFIG_SENSORS_DS1621=m
 CONFIG_SENSORS_DS1621=m
+CONFIG_SENSORS_F71805F=m
 CONFIG_SENSORS_FSCHER=m
 CONFIG_SENSORS_FSCHER=m
+CONFIG_SENSORS_FSCPOS=m
 CONFIG_SENSORS_GL518SM=m
 CONFIG_SENSORS_GL518SM=m
+CONFIG_SENSORS_GL520SM=m
 CONFIG_SENSORS_IT87=m
 CONFIG_SENSORS_IT87=m
+CONFIG_SENSORS_LM63=m
 CONFIG_SENSORS_LM75=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_LM78=m
 CONFIG_SENSORS_LM80=m
 CONFIG_SENSORS_LM83=m
 CONFIG_SENSORS_LM85=m
+CONFIG_SENSORS_LM87=m
 CONFIG_SENSORS_LM90=m
 CONFIG_SENSORS_LM90=m
+CONFIG_SENSORS_LM92=m
 CONFIG_SENSORS_MAX1619=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_VIA686A=m
+CONFIG_SENSORS_VT8231=m
 CONFIG_SENSORS_W83781D=m
 CONFIG_SENSORS_W83781D=m
+CONFIG_SENSORS_W83792D=m
 CONFIG_SENSORS_W83L785TS=m
 CONFIG_SENSORS_W83627HF=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
 
 #
 # Misc devices
@@ -1649,22 +2164,30 @@ CONFIG_IBM_ASM=m
 # Multimedia devices
 #
 CONFIG_VIDEO_DEV=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_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_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
 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_ZORAN_DC30=m
 CONFIG_VIDEO_ZORAN_LML33=m
 CONFIG_VIDEO_ZORAN_LML33R10=m
+CONFIG_VIDEO_MEYE=m
 CONFIG_VIDEO_SAA7134=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_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=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
 #
 
 #
 # 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_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
 #
 
 #
 # 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_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_BTCX=m
 CONFIG_VIDEO_IR=m
+CONFIG_VIDEO_TVEEPROM=m
+CONFIG_USB_DABUSB=m
 
 #
 # Graphics support
 #
 CONFIG_FB=y
 
 #
 # 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_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_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=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=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=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_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_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_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_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_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_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_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
 # 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_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
 
 #
 # 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_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_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
 
 # 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_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
 CONFIG_SND_DUMMY=m
 CONFIG_SND_VIRMIDI=m
 CONFIG_SND_MTPAV=m
@@ -1815,87 +2517,102 @@ CONFIG_SND_MPU401=m
 #
 # ISA devices
 #
 #
 # 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_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_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=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_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
 #
 
 #
 # 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_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_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_CS46XX=m
 CONFIG_SND_CS46XX_NEW_DSP=y
-CONFIG_SND_CS4281=m
+CONFIG_SND_CS5535AUDIO=m
 CONFIG_SND_EMU10K1=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_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=m
+CONFIG_SND_FM801_TEA575X_BOOL=y
 CONFIG_SND_FM801_TEA575X=m
 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_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_SONICVIBES=m
+CONFIG_SND_TRIDENT=m
 CONFIG_SND_VIA82XX=m
 CONFIG_SND_VIA82XX=m
+CONFIG_SND_VIA82XX_MODEM=m
 CONFIG_SND_VX222=m
 CONFIG_SND_VX222=m
+CONFIG_SND_YMFPCI=m
 
 #
 
 #
-# ALSA USB devices
+# USB devices
 #
 CONFIG_SND_USB_AUDIO=m
 #
 CONFIG_SND_USB_AUDIO=m
+CONFIG_SND_USB_USX2Y=m
 
 #
 # PCMCIA devices
 #
 # CONFIG_SND_VXPOCKET is not set
 
 #
 # 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
 
 #
 # Open Sound System
@@ -1905,6 +2622,9 @@ CONFIG_SND_PDAUDIOCF=m
 #
 # USB support
 #
 #
 # 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
 
 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_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
 
 #
 # 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_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_HCD=m
+# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 CONFIG_USB_UHCI_HCD=m
 CONFIG_USB_UHCI_HCD=m
+CONFIG_USB_SL811_HCD=m
+CONFIG_USB_SL811_CS=m
 
 #
 # USB Device Class drivers
 #
 
 #
 # 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=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_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_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
 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_HIDDEV=y
 CONFIG_USB_AIPTEK=m
 CONFIG_USB_WACOM=m
+CONFIG_USB_ACECAD=m
 CONFIG_USB_KBTAB=m
 CONFIG_USB_POWERMATE=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_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
 
 #
 # 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
 #
 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_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_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
 
 #
 # USB port drivers
@@ -2027,15 +2745,24 @@ CONFIG_USB_USS720=m
 #
 CONFIG_USB_SERIAL=m
 CONFIG_USB_SERIAL_GENERIC=y
 #
 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_BELKIN=m
+CONFIG_USB_SERIAL_WHITEHEAT=m
 CONFIG_USB_SERIAL_DIGI_ACCELEPORT=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_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_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
 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_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_PL2303=m
+CONFIG_USB_SERIAL_HP4X=m
 CONFIG_USB_SERIAL_SAFE=m
 CONFIG_USB_SERIAL_SAFE_PADDED=y
 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_CYBERJACK=m
 CONFIG_USB_SERIAL_XIRCOM=m
+CONFIG_USB_SERIAL_OPTION=m
 CONFIG_USB_SERIAL_OMNINET=m
 CONFIG_USB_EZUSB=y
 
 CONFIG_USB_SERIAL_OMNINET=m
 CONFIG_USB_EZUSB=y
 
@@ -2065,22 +2796,111 @@ CONFIG_USB_EZUSB=y
 # USB Miscellaneous drivers
 #
 CONFIG_USB_EMI62=m
 # 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_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_PHIDGETSERVO=m
+CONFIG_USB_IDMOUSE=m
+CONFIG_USB_SISUSBVGA=m
+CONFIG_USB_SISUSBVGA_CON=y
+CONFIG_USB_LD=m
 CONFIG_USB_TEST=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
 
 #
 # 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
 #
 #
 # 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_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
 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_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_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_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_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_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_AUTOFS_FS=m
 CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=m
 
 #
 # CD-ROM/DVD Filesystems
 
 #
 # CD-ROM/DVD Filesystems
@@ -2128,6 +2956,7 @@ CONFIG_JOLIET=y
 CONFIG_ZISOFS=y
 CONFIG_ZISOFS_FS=y
 CONFIG_UDF_FS=m
 CONFIG_ZISOFS=y
 CONFIG_ZISOFS_FS=y
 CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
 
 #
 # DOS/FAT/NT Filesystems
 
 #
 # 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_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
 
 #
 # 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_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_TMPFS=y
 CONFIG_HUGETLBFS=y
 CONFIG_HUGETLB_PAGE=y
 CONFIG_RAMFS=y
+CONFIG_CONFIGFS_FS=m
 
 #
 # Miscellaneous filesystems
 
 #
 # 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_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_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_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_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
 
 #
 # 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_NFS_V4=y
 CONFIG_NFS_DIRECTIO=y
 CONFIG_NFSD=m
+CONFIG_NFSD_V2_ACL=y
 CONFIG_NFSD_V3=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_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_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=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
 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_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_AFS_FS is not set
+CONFIG_9P_FS=m
 
 #
 # Partition Types
 
 #
 # 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_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
 # 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_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_SGI_PARTITION=y
 # CONFIG_ULTRIX_PARTITION is not set
 CONFIG_SUN_PARTITION=y
+CONFIG_KARMA_PARTITION=y
 CONFIG_EFI_PARTITION=y
 
 #
 CONFIG_EFI_PARTITION=y
 
 #
@@ -2234,7 +3080,7 @@ CONFIG_EFI_PARTITION=y
 #
 CONFIG_NLS=y
 CONFIG_NLS_DEFAULT="utf8"
 #
 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
 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_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
 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
 
 #
 CONFIG_NLS_UTF8=m
 
 #
-# Profiling support
+# Instrumentation Support
 #
 CONFIG_PROFILING=y
 CONFIG_OPROFILE=m
 #
 CONFIG_PROFILING=y
 CONFIG_OPROFILE=m
+CONFIG_KPROBES=y
 
 #
 # Kernel hacking
 #
 
 #
 # Kernel hacking
 #
+# CONFIG_PRINTK_TIME is not set
+CONFIG_MAGIC_SYSRQ=y
 CONFIG_DEBUG_KERNEL=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_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_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_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_X86_FIND_SMP_CONFIG=y
 CONFIG_X86_MPPARSE=y
+CONFIG_DOUBLEFAULT=y
 
 #
 # Security options
 #
 
 #
 # Security options
 #
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
 CONFIG_SECURITY=y
 CONFIG_SECURITY_NETWORK=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_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=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_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
 
 #
 # Cryptographic options
@@ -2317,32 +3191,51 @@ CONFIG_CRYPTO_HMAC=y
 CONFIG_CRYPTO_NULL=m
 CONFIG_CRYPTO_MD4=m
 CONFIG_CRYPTO_MD5=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_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_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_CAST5=m
 CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_TEA=m
 CONFIG_CRYPTO_ARC4=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_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
 #
 
 #
 # Library routines
 #
+CONFIG_CRC_CCITT=m
+CONFIG_CRC16=m
 CONFIG_CRC32=y
 CONFIG_LIBCRC32C=m
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=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_BIOS_REBOOT=y
-CONFIG_X86_TRAMPOLINE=y
-CONFIG_X86_STD_RESOURCES=y
-CONFIG_PC=y
+CONFIG_KTIME_SCALAR=y
index a1d48d7..8a7fee7 100644 (file)
@@ -1,44 +1,45 @@
+# i386
 #
 # Automatically generated make config: don't edit
 #
 CONFIG_MMU=y
 #
 # 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
 #
 # Code maturity level options
 #
 CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
 CONFIG_STANDALONE=y
 CONFIG_STANDALONE=y
-
+CONFIG_PREVENT_FIRMWARE_BUILD=y
 #
 # General setup
 #
 #
 # General setup
 #
+# CONFIG_LOCALVERSION_AUTO is not set
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_BSD_PROCESS_ACCT=y
 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_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_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_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
 
 #
 # 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_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
 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
 
 #
 # 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_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_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
 #
 
 #
 # 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_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
 
 #
 # Executable file formats
 #
 CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_AOUT is not set
-CONFIG_BINFMT_MISC=m
+CONFIG_BINFMT_MISC=y
 
 #
 # Device Drivers
 
 #
 # Device Drivers
@@ -158,26 +119,28 @@ CONFIG_BINFMT_MISC=m
 #
 CONFIG_FW_LOADER=y
 
 #
 CONFIG_FW_LOADER=y
 
+# CONFIG_SPI is not set
+
 #
 # Memory Technology Devices (MTD)
 #
 CONFIG_MTD=m
 # CONFIG_MTD_DEBUG 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_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
 #
 # 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_FTL=m
 CONFIG_NFTL=m
 CONFIG_NFTL_RW=y
 CONFIG_INFTL=m
+CONFIG_RFD_FTL=m
 
 #
 # RAM/ROM/Flash chip drivers
 
 #
 # 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_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_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_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_PCI=m
+CONFIG_MTD_TS5500=m
 
 #
 # Self-contained MTD device drivers
 
 #
 # 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=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
 
 #
 # 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_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_PARPORT_1284=y
 
 #
@@ -266,13 +242,37 @@ CONFIG_PNP=y
 #
 CONFIG_ISAPNP=y
 # CONFIG_PNPBIOS is not set
 #
 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
 
 #
 # 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
 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_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_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
 
 #
 # 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_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_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_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
 #
 
 #
 # 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
 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_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_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_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_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_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_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_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_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
 
 #
 # 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_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
 #
 
 #
 # 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_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
 
 #
 # 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_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_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_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_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_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_BUSLOGIC=m
+CONFIG_SCSI_INITIO=m
 # CONFIG_SCSI_OMIT_FLASHPOINT is not set
 # CONFIG_SCSI_OMIT_FLASHPOINT is not set
-# CONFIG_SCSI_CPQFCTS is not set
 # CONFIG_SCSI_DMX3191D 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_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_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_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_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_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_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_QLA21XX=m
 CONFIG_SCSI_QLA22XX=m
 CONFIG_SCSI_QLA2300=m
 CONFIG_SCSI_QLA2322=m
+CONFIG_SCSI_QLA24XX=m
 CONFIG_SCSI_QLA6312=m
 CONFIG_SCSI_QLA6312=m
-CONFIG_SCSI_QLA6322=m
 # CONFIG_SCSI_IPR is not set
 # CONFIG_SCSI_DPT_I2O is not set
 # CONFIG_SCSI_IPR is not set
 # CONFIG_SCSI_DPT_I2O is not set
+CONFIG_SCSI_LPFC=m
 
 #
 # PCMCIA SCSI adapter support
 
 #
 # PCMCIA SCSI adapter support
@@ -486,11 +490,6 @@ CONFIG_PCMCIA_QLOGIC=m
 CONFIG_PCMCIA_SYM53C500=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)
 #
 #
 # 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_RAID0=m
 CONFIG_MD_RAID1=m
 CONFIG_MD_RAID5=m
+CONFIG_MD_RAID5_RESHAPE=y
 CONFIG_MD_RAID6=m
 CONFIG_MD_RAID6=m
+CONFIG_MD_RAID10=m
 CONFIG_MD_MULTIPATH=m
 CONFIG_MD_MULTIPATH=m
+CONFIG_MD_FAULTY=m
 CONFIG_BLK_DEV_DM=m
 CONFIG_BLK_DEV_DM=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
 CONFIG_DM_CRYPT=m
 CONFIG_DM_CRYPT=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_MULTIPATH_EMC=m
 
 #
 # Fusion MPT device support
 #
 
 #
 # Fusion MPT device support
 #
-CONFIG_FUSION=m
+CONFIG_FUSION_SPI=m
+CONFIG_FUSION_FC=m
 CONFIG_FUSION_MAX_SGE=40
 CONFIG_FUSION_MAX_SGE=40
-# CONFIG_FUSION_ISENSE is not set
 CONFIG_FUSION_CTL=m
 CONFIG_FUSION_LAN=m
 CONFIG_FUSION_CTL=m
 CONFIG_FUSION_LAN=m
+CONFIG_FUSION_SAS=m
 
 #
 # IEEE 1394 (FireWire) support (EXPERIMENTAL)
 
 #
 # IEEE 1394 (FireWire) support (EXPERIMENTAL)
@@ -528,7 +536,7 @@ CONFIG_IEEE1394_OUI_DB=y
 #
 # Device Drivers
 #
 #
 # Device Drivers
 #
-# CONFIG_IEEE1394_PCILYNX is not set
+CONFIG_IEEE1394_PCILYNX=m
 CONFIG_IEEE1394_OHCI1394=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_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_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
 
 #
 # 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
 
 #
 # 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
 
 #
 # Networking options
 #
 CONFIG_PACKET=y
 CONFIG_PACKET_MMAP=y
-CONFIG_NETLINK_DEV=y
 CONFIG_UNIX=y
 CONFIG_NET_KEY=m
 CONFIG_INET=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_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_MULTIPATH=y
-CONFIG_IP_ROUTE_TOS=y
 CONFIG_IP_ROUTE_VERBOSE=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
 # 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_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
 
 #
 # IP: Virtual Server Configuration
@@ -614,16 +626,50 @@ CONFIG_IP_VS_SED=m
 CONFIG_IP_VS_NQ=m
 CONFIG_IP_VS_FTP=m
 
 CONFIG_IP_VS_NQ=m
 CONFIG_IP_VS_FTP=m
 
-
 CONFIG_IPV6=m
 CONFIG_IPV6_PRIVACY=y
 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_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_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
 
 # 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
 # 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_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_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_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_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_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_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_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_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
 #
 
 #
 # IPv6: Netfilter Configuration
 #
-# CONFIG_IP6_NF_QUEUE is not set
+CONFIG_IP6_NF_QUEUE=m
 CONFIG_IP6_NF_IPTABLES=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_FRAG=m
 CONFIG_IP6_NF_MATCH_HL=m
+CONFIG_IP6_NF_MATCH_IPV6HEADER=m
 CONFIG_IP6_NF_MATCH_MULTIPORT=m
 CONFIG_IP6_NF_MATCH_MULTIPORT=m
+CONFIG_IP6_NF_MATCH_OPTS=m
 CONFIG_IP6_NF_MATCH_OWNER=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_FILTER=m
-CONFIG_IP6_NF_TARGET_LOG=m
 CONFIG_IP6_NF_MANGLE=m
 CONFIG_IP6_NF_MANGLE=m
-CONFIG_IP6_NF_TARGET_MARK=m
 CONFIG_IP6_NF_RAW=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
 
 #
 # 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_REDIRECT=m
 CONFIG_BRIDGE_EBT_SNAT=m
 CONFIG_BRIDGE_EBT_LOG=m
+CONFIG_BRIDGE_EBT_ULOG=m
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=y
 
 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_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
 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_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_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_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
 
 #
 # 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_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
 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_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
 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_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_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
 #
 
 #
 # Network testing
 #
-# CONFIG_NET_PKTGEN is not set
+CONFIG_NET_PKTGEN=m
 CONFIG_NETDEVICES=y
 
 #
 CONFIG_NETDEVICES=y
 
 #
@@ -812,33 +872,64 @@ CONFIG_DUMMY=m
 CONFIG_BONDING=m
 CONFIG_EQUALIZER=m
 CONFIG_TUN=m
 CONFIG_BONDING=m
 CONFIG_EQUALIZER=m
 CONFIG_TUN=m
-CONFIG_ETHERTAP=m
 CONFIG_NET_SB1000=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
 #
 # 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_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_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
 
 #
 # 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_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
 # 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_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_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
 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_AMD8111E_NAPI=y
 CONFIG_ADAPTEC_STARFIRE=m
 CONFIG_ADAPTEC_STARFIRE_NAPI=y
-CONFIG_AC3200=m
-CONFIG_APRICOT=m
 CONFIG_B44=m
 CONFIG_B44=m
-CONFIG_CS89x0=m
+CONFIG_BNX2=m
 CONFIG_DGRS=m
 CONFIG_DGRS=m
-CONFIG_EEPRO100=m
-# CONFIG_EEPRO100_PIO is not set
+# CONFIG_EEPRO100 is not set
 CONFIG_E100=m
 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_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_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_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_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_NET_POCKET=y
 CONFIG_ATP=m
 CONFIG_DE600=m
 CONFIG_DE620=m
+CONFIG_CASSINI=m
+# CONFIG_FEC_8XX is not set
 
 #
 # Ethernet (1000 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_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_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_TIGON3=m
+CONFIG_SKY2=m
 
 #
 # Ethernet (10000 Mbit)
 
 #
 # Ethernet (10000 Mbit)
@@ -935,6 +1015,8 @@ CONFIG_IXGB=m
 CONFIG_IXGB_NAPI=y
 CONFIG_S2IO=m
 CONFIG_S2IO_NAPI=y
 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
 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_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)
 
 #
 # Wireless LAN (non-hamradio)
@@ -961,7 +1047,6 @@ CONFIG_NET_RADIO=y
 #
 # CONFIG_STRIP is not set
 # CONFIG_ARLAN is not set
 #
 # CONFIG_STRIP is not set
 # CONFIG_ARLAN is not set
-CONFIG_WAVELAN=m
 CONFIG_PCMCIA_WAVELAN=m
 CONFIG_PCMCIA_NETWAVE=m
 
 CONFIG_PCMCIA_WAVELAN=m
 CONFIG_PCMCIA_NETWAVE=m
 
@@ -973,31 +1058,62 @@ CONFIG_PCMCIA_NETWAVE=m
 #
 # Wireless 802.11b ISA/PCI cards support
 #
 #
 # 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_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_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
 
 #
 # 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_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
 #
 
 #
 # 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_NET_FC=y
-CONFIG_RCPCI=m
 # CONFIG_SHAPER is not set
 
 #
 # 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_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
 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_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
 
 #
 # 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_BNEP=m
 CONFIG_BT_BNEP_MC_FILTER=y
 CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=m
 
 #
 # Bluetooth device drivers
 
 #
 # 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=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
 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_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
 
 #
 # ISDN subsystem
@@ -1101,9 +1212,7 @@ CONFIG_USB_BLUETOOTH_TTY=m
 
 CONFIG_ISDN=m
 CONFIG_ISDN_I4L=m
 
 CONFIG_ISDN=m
 CONFIG_ISDN_I4L=m
-CONFIG_ISDN_DRV_AVMB1_B1ISA=m
 CONFIG_ISDN_DRV_AVMB1_B1PCI=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
 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_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_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_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_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_FRITZPCI=y
 CONFIG_HISAX_AVM_A1_PCMCIA=y
 CONFIG_HISAX_ELSA=y
-CONFIG_HISAX_IX1MICROR2=y
 CONFIG_HISAX_DIEHLDIVA=y
 CONFIG_HISAX_DIEHLDIVA=y
-CONFIG_HISAX_ASUSCOM=y
-CONFIG_HISAX_TELEINT=y
-CONFIG_HISAX_HFCS=y
 CONFIG_HISAX_SEDLBAUER=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_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
 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_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
 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_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
 
 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_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
 #
 #
 # Telephony Support
 #
@@ -1233,16 +1335,15 @@ CONFIG_INPUT_EVDEV=y
 # Input I/O drivers
 #
 CONFIG_GAMEPORT=m
 # 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_NS558=m
 CONFIG_GAMEPORT_L4=m
 CONFIG_GAMEPORT_EMU10K1=m
-CONFIG_GAMEPORT_VORTEX=m
 CONFIG_GAMEPORT_FM801=m
 CONFIG_GAMEPORT_FM801=m
-CONFIG_GAMEPORT_CS461x=m
 CONFIG_SERIO=y
 CONFIG_SERIO_I8042=y
 CONFIG_SERIO_SERPORT=y
 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
 # 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_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
 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_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_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_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_MISC=y
 CONFIG_INPUT_PCSPKR=m
-# CONFIG_INPUT_UINPUT is not set
+CONFIG_INPUT_UINPUT=m
+CONFIG_INPUT_WISTRON_BTNS=m
 
 #
 # Character devices
 
 #
 # Character devices
@@ -1305,10 +1406,16 @@ CONFIG_SERIAL_NONSTANDARD=y
 CONFIG_ROCKETPORT=m
 CONFIG_SYNCLINK=m
 CONFIG_SYNCLINKMP=m
 CONFIG_ROCKETPORT=m
 CONFIG_SYNCLINK=m
 CONFIG_SYNCLINKMP=m
+# CONFIG_SYNCLINK_GT is not set
 CONFIG_N_HDLC=m
 CONFIG_N_HDLC=m
-CONFIG_STALDRV=y
+# CONFIG_STALDRV is not set
 # CONFIG_FTAPE is not set
 CONFIG_IBM_ASM=m
 # 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
 
 #
 # 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_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_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_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_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
 # 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_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
 
 #
 # 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_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
 # 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
 #
 #
 # 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_ALI1535=m
+CONFIG_I2C_ALI1563=m
 CONFIG_I2C_ALI15X3=m
 CONFIG_I2C_AMD756=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_AMD8111=m
 CONFIG_I2C_I801=m
 CONFIG_I2C_I810=m
-CONFIG_I2C_ISA=m
-CONFIG_I2C_NFORCE2=m
 CONFIG_I2C_PIIX4=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_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_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
 #
 
 #
 # I2C Hardware Sensors Chip support
 #
-CONFIG_I2C_SENSOR=m
 CONFIG_SENSORS_ADM1021=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_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_IT87=m
+CONFIG_SENSORS_LM63=m
 CONFIG_SENSORS_LM75=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_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_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_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
 #
 
 #
 # Mice
 #
-CONFIG_BUSMOUSE=m
-# CONFIG_QIC02_TAPE is not set
-CONFIG_CRASH=m
 
 #
 # IPMI
 
 #
 # 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_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_WATCHDOG=m
 CONFIG_IPMI_SI=m
+CONFIG_IPMI_POWEROFF=m
 
 #
 # Watchdog Cards
 
 #
 # Watchdog Cards
@@ -1448,15 +1587,13 @@ CONFIG_IPMI_SI=m
 CONFIG_WATCHDOG=y
 # CONFIG_WATCHDOG_NOWAYOUT is not set
 CONFIG_SOFT_WATCHDOG=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_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
 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_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_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_PCIPCWATCHDOG=m
 CONFIG_USBPCWATCHDOG=m
-
+# CONFIG_SBC_EPX_C3_WATCHDOG is not set
 
 CONFIG_HW_RANDOM=m
 
 CONFIG_HW_RANDOM=m
-CONFIG_NVRAM=m
+CONFIG_NVRAM=y
 CONFIG_RTC=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
 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_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_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_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_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
 
 
 #
 # PCMCIA character devices
 #
 CONFIG_SYNCLINK_CS=m
 
-
+CONFIG_CARDMAN_4000=m
+CONFIG_CARDMAN_4040=m
 
 CONFIG_MWAVE=m
 # CONFIG_RAW_DRIVER is not set
 
 CONFIG_MWAVE=m
 # CONFIG_RAW_DRIVER is not set
@@ -1525,6 +1679,10 @@ CONFIG_HANGCHECK_TIMER=m
 # Multimedia devices
 #
 CONFIG_VIDEO_DEV=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
 
 #
 # Video For Linux
@@ -1533,59 +1691,65 @@ CONFIG_VIDEO_DEV=m
 #
 # Video Adapters
 #
 #
 # Video Adapters
 #
+CONFIG_VIDEO_AUDIO_DECODER=m
 CONFIG_VIDEO_BT848=m
 CONFIG_VIDEO_BT848=m
-CONFIG_VIDEO_PMS=m
+CONFIG_VIDEO_BT848_DVB=y
 CONFIG_VIDEO_BWQCAM=m
 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_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_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_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_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
 #
 
 #
 # 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_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
 #
 
 
 #
 # Digital Video Broadcasting Devices
 #
-# CONFIG_DVB is not set
+CONFIG_DVB=y
 CONFIG_DVB_CORE=m
 
 #
 CONFIG_DVB_CORE=m
 
 #
@@ -1593,19 +1757,13 @@ CONFIG_DVB_CORE=m
 #
 CONFIG_DVB_STV0299=m
 # CONFIG_DVB_SP887X is not set
 #
 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_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_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_TTUSB_DEC=m
 CONFIG_DVB_BT8XX=m
-# CONFIG_DVB_TDA1004X is not set
+CONFIG_DVB_TDA1004X=m
 CONFIG_DVB_NXT6000=m
 
 #
 CONFIG_DVB_NXT6000=m
 
 #
@@ -1627,7 +1785,43 @@ CONFIG_DVB_TTUSB_BUDGET=m
 #
 # Supported FlexCopII (B2C2) Adapters
 #
 #
 # 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
 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_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=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=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=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_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=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
 # 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_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_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
 
 #
 # 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_DUMMY_CONSOLE=y
 CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
 # CONFIG_FONTS is not set
 
 
 # CONFIG_FONTS is not set
 
 
@@ -1708,16 +1921,20 @@ CONFIG_SOUND=m
 # Advanced Linux Sound Architecture
 #
 CONFIG_SND=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=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_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_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
 
 #
 # Generic devices
@@ -1731,34 +1948,8 @@ CONFIG_SND_MPU401=m
 #
 # ISA devices
 #
 #
 # 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_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
 
 #
 # 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_CS46XX=m
 CONFIG_SND_CS46XX_NEW_DSP=y
 CONFIG_SND_CS4281=m
+CONFIG_SND_CS5535AUDIO=m
 CONFIG_SND_EMU10K1=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_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
 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_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_VX222=m
 CONFIG_SND_BT87X=m
+# CONFIG_SND_BT87X_OVERCLOCK is not set
 CONFIG_SND_ATIIXP=m
 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_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_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
 
 #
 # ALSA USB devices
 #
 CONFIG_SND_USB_AUDIO=m
+CONFIG_SND_USB_USX2Y=m
 
 #
 # PCMCIA devices
 #
 # CONFIG_SND_VXPOCKET is not set
 
 #
 # PCMCIA devices
 #
 # CONFIG_SND_VXPOCKET is not set
-# CONFIG_SND_VXP440 is not set
 
 #
 # Open Sound System
 
 #
 # 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_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
 
 #
 # 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_EHCI_ROOT_HUB_TT=y
 CONFIG_USB_OHCI_HCD=m
 CONFIG_USB_UHCI_HCD=m
+CONFIG_USB_SL811_CS=m
 
 #
 # USB Device Class drivers
 #
 
 #
 # 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
 
 #
 # 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_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=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_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)
 
 #
 # 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_LOGITECH_FF=y
 CONFIG_THRUSTMASTER_FF=y
 CONFIG_USB_HIDDEV=y
+CONFIG_USB_IDMOUSE=m
 
 #
 # USB HID Boot Protocol drivers
 
 #
 # 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_KBD is not set
 # CONFIG_USB_MOUSE is not set
 CONFIG_USB_AIPTEK=m
+
 CONFIG_USB_WACOM=m
 CONFIG_USB_WACOM=m
+
 CONFIG_USB_KBTAB=m
 CONFIG_USB_POWERMATE=m
 CONFIG_USB_XPAD=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_MDC800=m
 CONFIG_USB_MICROTEK=m
-CONFIG_USB_HPUSBSCSI=m
 
 #
 # USB Multimedia devices
 
 #
 # 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_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_IBMCAM=m
 CONFIG_USB_KONICAWC=m
 CONFIG_USB_OV511=m
-CONFIG_USB_PWC=m
 CONFIG_USB_SE401=m
 CONFIG_USB_STV680=m
 CONFIG_USB_SE401=m
 CONFIG_USB_STV680=m
+CONFIG_USB_SN9C102=m
 
 #
 # USB Network adaptors
 
 #
 # 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_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
 
 #
 # 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
 
 #
 # 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
 
 #
 # USB port drivers
@@ -1947,15 +2161,24 @@ CONFIG_USB_USS720=m
 #
 CONFIG_USB_SERIAL=m
 CONFIG_USB_SERIAL_GENERIC=y
 #
 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_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_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_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_IPAQ=m
+CONFIG_USB_SERIAL_IPW=m
 CONFIG_USB_SERIAL_IR=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
 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_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_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_WHITEHEAT=m
+CONFIG_USB_SERIAL_XIRCOM=m
+
 CONFIG_USB_EZUSB=y
 CONFIG_USB_EMI62=m
 CONFIG_USB_LED=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
 #
 #
 # 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_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_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_ZERO=m
 CONFIG_USB_ETH=m
-CONFIG_USB_GADGETFS=m
+# CONFIG_USB_GADGETFS is not set
 CONFIG_USB_W9968CF=m
 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_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_REMOTE=m
+CONFIG_USB_ATI_REMOTE2=m
 CONFIG_USB_ALI_M5632=y
 # CONFIG_USB_CYTHERM is not set
 CONFIG_USB_ALI_M5632=y
 # CONFIG_USB_CYTHERM is not set
-CONFIG_USB_EGALAX=m
 CONFIG_USB_PHIDGETSERVO=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
 
 #
 # 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_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
 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_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
 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_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
 
 #
 # CONFIG_NTFS_FS is not set
 
 #
@@ -2074,13 +2320,11 @@ CONFIG_VFAT_FS=m
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
 #
 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_TMPFS=y
 CONFIG_HUGETLBFS=y
 CONFIG_HUGETLB_PAGE=y
 CONFIG_RAMFS=y
+CONFIG_DEBUG_FS=y
 
 #
 # Miscellaneous filesystems
 
 #
 # 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_JFFS_FS is not set
 CONFIG_JFFS2_FS=m
 CONFIG_JFFS2_FS_DEBUG=0
-CONFIG_JFFS2_FS_NAND=y
 CONFIG_CRAMFS=m
 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
 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_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
 
 #
 # 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_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
 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_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_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
 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_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_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
 #
 # 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
 # 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_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_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=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
 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_KOI8_R=m
 CONFIG_NLS_KOI8_U=m
 CONFIG_NLS_UTF8=m
+CONFIG_NLS_ASCII=y
 
 #
 # Profiling support
 
 #
 # Profiling support
@@ -2212,46 +2470,54 @@ CONFIG_NLS_UTF8=m
 CONFIG_PROFILING=y
 CONFIG_OPROFILE=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
 #
 # Kernel hacking
 #
 CONFIG_DEBUG_KERNEL=y
-CONFIG_DEBUG_STACKOVERFLOW=y
-# CONFIG_DEBUG_SLAB is not set
 CONFIG_MAGIC_SYSRQ=y
 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_INFO=y
-CONFIG_DEBUG_SPINLOCK_SLEEP=y
 # CONFIG_FRAME_POINTER is not set
 CONFIG_CC_OPTIMIZE_FOR_SIZE=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_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
 
 #
 # 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_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
 
 #
 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_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
 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_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
 #
 
 #
 # Library routines
 #
+CONFIG_CRC16=m
 CONFIG_CRC32=m
 CONFIG_CRC32=m
+CONFIG_CRC_CCITT=m
+
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=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_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_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
 # 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_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_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
 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_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_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_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_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_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_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=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
 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_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_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_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_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_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_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_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_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=y
 CONFIG_HOTPLUG_PCI_COMPAQ=m
+# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set
 CONFIG_HOTPLUG_PCI_IBM=m
 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_HIGHMEM64G is not set
-# CONFIG_EWRK3 is not set
-CONFIG_NR_CPUS=32
-# CONFIG_X86_PC is not set
-CONFIG_X86_GENERICARCH=y
index 3c0a5ba..847cedb 100644 (file)
@@ -42,9 +42,9 @@ dev->get_stats:
        Context: nominally process, but don't sleep inside an rwlock
 
 dev->hard_start_xmit:
        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
        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 
        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:
          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:
        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:
        Context: BHs disabled
 
 dev->poll:
index c3c5842..6a1bb87 100644 (file)
@@ -2572,6 +2572,14 @@ M:       dbrownell@users.sourceforge.net
 L:     spi-devel-general@lists.sourceforge.net
 S:     Maintained
 
 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
 TPM DEVICE DRIVER
 P:     Kylene Hall
 M:     kjhall@us.ibm.com
index 03f53c2..d75fa40 100644 (file)
@@ -91,6 +91,15 @@ config X86_PC
        help
          Choose this option if your computer is a standard PC or compatible.
 
        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
 config X86_ELAN
        bool "AMD Elan"
        help
@@ -193,6 +202,7 @@ source "arch/i386/Kconfig.cpu"
 
 config HPET_TIMER
        bool "HPET Timer Support"
 
 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.
        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"
 
 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
        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"
 
 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
        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"
 
 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
        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
 
 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
        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
        default y
 
 config X86_VISWS_APIC
@@ -282,9 +292,14 @@ config X86_VISWS_APIC
        depends on X86_VISWS
        default y
 
        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"
 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).
        ---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"
 
 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
        ---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"
 
 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
        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.
 
          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
 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"
 
 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
        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"
 
 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
        ---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"
 
 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
        ---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)"
 
 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
        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"
 
 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.
        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)"
 
 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
        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
 
 
 endmenu
 
+config ARCH_ENABLE_MEMORY_HOTPLUG
+       def_bool y
+       depends on HIGHMEM
 
 menu "Power management options (ACPI, APM)"
 
 menu "Power management options (ACPI, APM)"
-       depends on !X86_VOYAGER
+       depends on !(X86_VOYAGER || XEN_UNPRIVILEGED_GUEST)
 
 
+if !X86_XEN
 source kernel/power/Kconfig
 source kernel/power/Kconfig
+endif
 
 source "drivers/acpi/Kconfig"
 
 menu "APM (Advanced Power Management) BIOS Support"
 
 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"
 
 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
        ---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"
 
 config PCI_GOBIOS
        bool "BIOS"
+       depends on !X86_XEN
 
 config PCI_GOMMCONFIG
        bool "MMConfig"
 
 config PCI_GOMMCONFIG
        bool "MMConfig"
@@ -970,6 +1000,13 @@ config PCI_GOMMCONFIG
 config PCI_GODIRECT
        bool "Direct"
 
 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"
 
 config PCI_GOANY
        bool "Any"
 
@@ -977,7 +1014,7 @@ endchoice
 
 config PCI_BIOS
        bool
 
 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
        default y
 
 config PCI_DIRECT
@@ -990,6 +1027,18 @@ config PCI_MMCONFIG
        depends on PCI && ACPI && (PCI_GOMMCONFIG || PCI_GOANY)
        default y
 
        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"
 source "drivers/pci/pcie/Kconfig"
 
 source "drivers/pci/Kconfig"
@@ -1000,7 +1049,7 @@ config ISA_DMA_API
 
 config ISA
        bool "ISA support"
 
 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
        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
 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
        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 "crypto/Kconfig"
 
+source "drivers/xen/Kconfig"
+
 source "lib/Kconfig"
 
 #
 source "lib/Kconfig"
 
 #
@@ -1116,7 +1167,7 @@ config X86_SMP
 
 config X86_HT
        bool
 
 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
        default y
 
 config X86_BIOS_REBOOT
@@ -1129,6 +1180,16 @@ config X86_TRAMPOLINE
        depends on X86_SMP || (X86_VOYAGER && SMP)
        default y
 
        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
 config KTIME_SCALAR
        bool
        default y
index eb13048..f90d8d0 100644 (file)
@@ -251,7 +251,7 @@ config X86_PPRO_FENCE
 
 config X86_F00F_BUG
        bool
 
 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
        default y
 
 config X86_WP_WORKS_OK
index c92191b..fb28fe7 100644 (file)
@@ -84,6 +84,7 @@ config X86_MPPARSE
 config DOUBLEFAULT
        default y
        bool "Enable doublefault exception handler" if EMBEDDED
 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
        help
           This option allows trapping of rare doublefault exceptions that
           would otherwise cause a system to silently reboot. Disabling this
index 94e0faf..53b7343 100644 (file)
@@ -48,6 +48,11 @@ CFLAGS                               += $(shell if [ $(call cc-version) -lt 0400 ] ; then echo $(call cc-op
 
 CFLAGS += $(cflags-y)
 
 
 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
 
 # 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
 
 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
 # 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
 
 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
 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
 
 install:
        $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) install
+endif
 
 archclean:
        $(Q)$(MAKE) $(clean)=arch/i386/boot
 
 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 += arch/$(ARCH)/boot/fdimage \
               arch/$(ARCH)/boot/image.iso \
               arch/$(ARCH)/boot/mtools.conf
+CLEAN_FILES += vmlinuz vmlinux-stripped
index 96fb8a0..ddaa19d 100644 (file)
@@ -42,6 +42,12 @@ EXTRA_AFLAGS   := -traditional
 
 obj-$(CONFIG_SCx200)           += scx200.o
 
 
 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
 # 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-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
        $(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 \
 
 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)
        $(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
index 7e9ac99..fa783e6 100644 (file)
@@ -6,3 +6,7 @@ ifneq ($(CONFIG_ACPI_PROCESSOR),)
 obj-y                          += cstate.o processor.o
 endif
 
 obj-y                          += cstate.o processor.o
 endif
 
+ifdef CONFIG_XEN
+include $(srctree)/scripts/Makefile.xen
+obj-y := $(call cherrypickxen, $(obj-y), $(src))
+endif
index ac3f4e5..c6b52aa 100644 (file)
@@ -13,6 +13,7 @@
 #include <asm/fixmap.h>
 #include <asm/processor.h>
 #include <asm/thread_info.h>
 #include <asm/fixmap.h>
 #include <asm/processor.h>
 #include <asm/thread_info.h>
+#include <asm/elf.h>
 
 #define DEFINE(sym, val) \
         asm volatile("\n->" #sym " %0 " #val : : "i" (val))
 
 #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);
 
        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 */
        /* 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));
                 sizeof(struct tss_struct));
+#else
+       /* sysenter stack points directly to esp0 */
+       DEFINE(SYSENTER_stack_esp0, 0);
+#endif
 
        DEFINE(PAGE_SIZE_asm, PAGE_SIZE);
 
        DEFINE(PAGE_SIZE_asm, PAGE_SIZE);
-       DEFINE(VSYSCALL_BASE, __fix_to_virt(FIX_VSYSCALL));
 }
 }
index 010aecf..753f1d7 100644 (file)
@@ -17,3 +17,8 @@ obj-$(CONFIG_X86_MCE) +=      mcheck/
 
 obj-$(CONFIG_MTRR)     +=      mtrr/
 obj-$(CONFIG_CPU_FREQ) +=      cpufreq/
 
 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
index da2db31..a748409 100644 (file)
@@ -581,7 +581,6 @@ static int __init powernow_cpu_init (struct cpufreq_policy *policy)
 
        rdmsrl (MSR_K7_FID_VID_STATUS, fidvidstatus.val);
 
 
        rdmsrl (MSR_K7_FID_VID_STATUS, fidvidstatus.val);
 
-       /* recalibrate cpu_khz */
        recalibrate_cpu_khz();
 
        fsb = (10 * cpu_khz) / fid_codes[fidvidstatus.bits.CFID];
        recalibrate_cpu_khz();
 
        fsb = (10 * cpu_khz) / fid_codes[fidvidstatus.bits.CFID];
index 71fffa1..2ea3c6c 100644 (file)
@@ -1008,7 +1008,7 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol)
                 * an UP version, and is deprecated by AMD.
                 */
 
                 * 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;
                        printk(KERN_ERR PFX "MP systems not supported by PSB BIOS structure\n");
                        kfree(data);
                        return -ENODEV;
index a25b701..06df4fe 100644 (file)
@@ -3,3 +3,10 @@ obj-y          += amd.o
 obj-y          += cyrix.o
 obj-y          += centaur.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
index 840d990..eed41e6 100644 (file)
@@ -177,7 +177,7 @@ need_resched:
 
        # sysenter call handler stub
 ENTRY(sysenter_entry)
 
        # 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)
 sysenter_past_esp:
        sti
        pushl $(__USER_DS)
@@ -414,7 +414,7 @@ vector=0
 ENTRY(irq_entries_start)
 .rept NR_IRQS
        ALIGN
 ENTRY(irq_entries_start)
 .rept NR_IRQS
        ALIGN
-1:     pushl $vector-256
+1:     pushl $~(vector)
        jmp common_interrupt
 .data
        .long 1b
        jmp common_interrupt
 .data
        .long 1b
@@ -431,7 +431,7 @@ common_interrupt:
 
 #define BUILD_INTERRUPT(name, nr)      \
 ENTRY(name)                            \
 
 #define BUILD_INTERRUPT(name, nr)      \
 ENTRY(name)                            \
-       pushl $nr-256;                  \
+       pushl $~(nr);                   \
        SAVE_ALL                        \
        movl %esp,%eax;                 \
        call smp_/**/name;              \
        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.
  *
  * 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.
  *
  * 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:                                         \
        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
        pushfl;                                 \
        pushl $__KERNEL_CS;                     \
        pushl $sysenter_past_esp
index f3a9c78..2904a66 100644 (file)
@@ -53,8 +53,8 @@ static union irq_ctx *softirq_ctx[NR_CPUS];
  */
 fastcall unsigned int do_IRQ(struct pt_regs *regs)
 {      
  */
 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;
 #ifdef CONFIG_4KSTACKS
        union irq_ctx *curctx, *irqctx;
        u32 *isp;
index 4163865..d207242 100644 (file)
@@ -120,14 +120,6 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq"),
                },
        },
                        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"),
-               },
-       },
        { }
 };
 
        { }
 };
 
index ec4959f..b97719a 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/gfp.h>
 #include <linux/string.h>
 #include <linux/elf.h>
 #include <linux/gfp.h>
 #include <linux/string.h>
 #include <linux/elf.h>
+#include <linux/mm.h>
 #include <linux/mman.h>
 
 #include <asm/a.out.h>
 #include <linux/mman.h>
 
 #include <asm/a.out.h>
 #include <asm/pgtable.h>
 #include <asm/unistd.h>
 
 #include <asm/pgtable.h>
 #include <asm/unistd.h>
 
+#ifdef CONFIG_XEN
+#include <xen/interface/callback.h>
+#endif
+
 extern asmlinkage void sysenter_entry(void);
 
 void enable_sep_cpu(void)
 {
 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);
 
        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();      
        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;
  */
 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)
 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);
 
 
        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,
                memcpy(page,
-                      &vsyscall_int80_start,
-                      &vsyscall_int80_end - &vsyscall_int80_start);
+                      &vsyscall_sysenter_start,
+                      &vsyscall_sysenter_end - &vsyscall_sysenter_start);
                return 0;
        }
 
        memcpy(page,
                return 0;
        }
 
        memcpy(page,
-              &vsyscall_sysenter_start,
-              &vsyscall_sysenter_end - &vsyscall_sysenter_start);
+              &vsyscall_int80_start,
+              &vsyscall_int80_end - &vsyscall_int80_start);
 
        return 0;
 }
 
        return 0;
 }
@@ -130,6 +148,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm,
        return err;
 }
 
        return err;
 }
 
+#ifndef CONFIG_XEN
 int in_gate_area_no_task(unsigned long addr)
 {
        return 0;
 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;
 }
 {
        return NULL;
 }
+#endif
index 0b9d741..5b65cb8 100644 (file)
@@ -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)
 {
 
 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 */
        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)
 }
 
 static void unknown_nmi_error(unsigned char reason, struct pt_regs * regs)
index 00e0118..c0adee5 100644 (file)
@@ -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)
 {
 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;
        struct tss_struct *tss;
+#endif
        struct pt_regs *ret;
        unsigned long tmp;
 
        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);
        }
 
                do_exit(SIGSEGV);
        }
 
+#ifndef CONFIG_X86_NO_TSS
        tss = &per_cpu(init_tss, get_cpu());
        tss = &per_cpu(init_tss, get_cpu());
+#endif
        current->thread.esp0 = current->thread.saved_esp0;
        current->thread.sysenter_cs = __KERNEL_CS;
        load_esp0(tss, &current->thread);
        current->thread.saved_esp0 = 0;
        current->thread.esp0 = current->thread.saved_esp0;
        current->thread.sysenter_cs = __KERNEL_CS;
        load_esp0(tss, &current->thread);
        current->thread.saved_esp0 = 0;
+#ifndef CONFIG_X86_NO_TSS
        put_cpu();
        put_cpu();
+#endif
 
        loadsegment(fs, current->thread.saved_fs);
        loadsegment(gs, current->thread.saved_gs);
 
        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)
 {
 
 static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk)
 {
+#ifndef CONFIG_X86_NO_TSS
        struct tss_struct *tss;
        struct tss_struct *tss;
+#endif
        long eax;
 /*
  * make sure the vm86() system call doesn't try to do anything silly
        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);
 
        savesegment(fs, tsk->thread.saved_fs);
        savesegment(gs, tsk->thread.saved_gs);
 
+#ifndef CONFIG_X86_NO_TSS
        tss = &per_cpu(init_tss, get_cpu());
        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);
        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();
        put_cpu();
+#endif
 
        tsk->thread.screen_bitmap = info->screen_bitmap;
        if (info->flags & VM86_SCREEN_BITMAP)
 
        tsk->thread.screen_bitmap = info->screen_bitmap;
        if (info->flags & VM86_SCREEN_BITMAP)
index 80908b5..2b33b20 100644 (file)
@@ -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
 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
index 92c3d9f..a00267a 100644 (file)
@@ -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 */
        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);
                return;
 
        spin_lock_irqsave(&pgd_lock, flags);
index 2889567..de8d187 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/slab.h>
 #include <linux/pagemap.h>
 #include <linux/spinlock.h>
 #include <linux/slab.h>
 #include <linux/pagemap.h>
 #include <linux/spinlock.h>
+#include <linux/module.h>
 
 #include <asm/system.h>
 #include <asm/pgtable.h>
 
 #include <asm/system.h>
 #include <asm/pgtable.h>
@@ -138,6 +139,10 @@ void set_pmd_pfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags)
        __flush_tlb_one(vaddr);
 }
 
        __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);
 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);
                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)
 }
 
 pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
index 30f3eb3..e596c39 100644 (file)
@@ -6,7 +6,11 @@ DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \
                oprofilefs.o oprofile_stats.o  \
                timer_int.o )
 
                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
 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
index 62ad75c..4447f39 100644 (file)
@@ -4,6 +4,10 @@ obj-$(CONFIG_PCI_BIOS)         += pcbios.o
 obj-$(CONFIG_PCI_MMCONFIG)     += mmconfig.o direct.o
 obj-$(CONFIG_PCI_DIRECT)       += direct.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
 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
 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
index 6b1ea0c..e545b09 100644 (file)
@@ -15,7 +15,9 @@
 #include <asm/e820.h>
 #include "pci.h"
 
 #include <asm/e820.h>
 #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
 
 /* 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,
                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)) {
                        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;
        }
                printk(KERN_ERR "PCI: Not using MMCONFIG.\n");
                return;
        }
index 8cfa4e8..e74fee6 100644 (file)
@@ -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
 obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o
index 67a9053..1e3ad1e 100644 (file)
@@ -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.
 
          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
 config SCHED_SMT
        bool "SMT scheduler support"
        depends on SMP
index c7b943f..3edefc8 100644 (file)
@@ -164,10 +164,25 @@ sys_pipe (void)
        return retval;
 }
 
        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)
 {
 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);
        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;
        }
 
                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(&current->mm->mmap_sem);
        addr = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
        up_write(&current->mm->mmap_sem);
        down_write(&current->mm->mmap_sem);
        addr = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
        up_write(&current->mm->mmap_sem);
index 8255a9b..7e8a4d1 100644 (file)
@@ -279,8 +279,8 @@ xpc_pull_remote_cachelines(struct xpc_partition *part, void *dst,
                return part->reason;
        }
 
                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;
        }
        if (bte_ret == BTE_SUCCESS) {
                return xpcSuccess;
        }
index 1def91f..6b5d4c4 100644 (file)
@@ -1055,6 +1055,8 @@ xpc_do_exit(enum xpc_retval reason)
        if (xpc_sysctl) {
                unregister_sysctl_table(xpc_sysctl);
        }
        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;
        partid_t partid;
        struct xpc_partition *part;
        pid_t pid;
+       size_t buf_size;
 
 
        if (!ia64_platform_is("sn2")) {
                return -ENODEV;
        }
 
 
 
        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");
 
        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);
                }
                if (xpc_sysctl) {
                        unregister_sysctl_table(xpc_sysctl);
                }
+
+               kfree(xpc_remote_copy_buffer_base);
                return -EBUSY;
        }
 
                return -EBUSY;
        }
 
@@ -1314,6 +1314,8 @@ xpc_init(void)
                if (xpc_sysctl) {
                        unregister_sysctl_table(xpc_sysctl);
                }
                if (xpc_sysctl) {
                        unregister_sysctl_table(xpc_sysctl);
                }
+
+               kfree(xpc_remote_copy_buffer_base);
                return -EBUSY;
        }
 
                return -EBUSY;
        }
 
@@ -1365,6 +1367,8 @@ xpc_init(void)
                if (xpc_sysctl) {
                        unregister_sysctl_table(xpc_sysctl);
                }
                if (xpc_sysctl) {
                        unregister_sysctl_table(xpc_sysctl);
                }
+
+               kfree(xpc_remote_copy_buffer_base);
                return -EBUSY;
        }
 
                return -EBUSY;
        }
 
index 2a89cfc..57c723f 100644 (file)
@@ -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).
  * 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.
  */
 
 
 /*
  * 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 */
 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);
                                        (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,
 
                /* 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) {
                                        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 */
 
 
        /* 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) {
                                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;
        }
 
                return xpcVarsNotSet;
        }
 
-
        /* pull over the cross partition variables */
        /* 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);
                                (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);
 
 
        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);
                        xp_nasid_mask_bytes, (BTE_NOTIFY | BTE_WACQUIRE), NULL);
 
        return xpc_map_bte_errors(bte_res);
index 7470259..f35dd7b 100644 (file)
@@ -620,6 +620,9 @@ config HOTPLUG_CPU
 
          Say N if you are unsure.
 
 
          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
 config KEXEC
        bool "kexec system call (EXPERIMENTAL)"
        depends on PPC_MULTIPLATFORM && EXPERIMENTAL
index b61d86e..55f367e 100644 (file)
@@ -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 */
        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
        mtspr   SPRN_HID0,r0
        mfspr   r0,SPRN_HID0
        mfspr   r0,SPRN_HID0
index 778f22f..dbcb859 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/elf.h>
 #include <linux/elfcore.h>
 #include <linux/init.h>
 #include <linux/elf.h>
 #include <linux/elfcore.h>
 #include <linux/init.h>
+#include <linux/irq.h>
 #include <linux/types.h>
 
 #include <asm/processor.h>
 #include <linux/types.h>
 
 #include <asm/processor.h>
@@ -174,6 +175,8 @@ static void crash_kexec_prepare_cpus(void)
 
 void default_machine_crash_shutdown(struct pt_regs *regs)
 {
 
 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.
        /*
         * 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();
 
         */
        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);
 
        if (ppc_md.kexec_cpu_down)
                ppc_md.kexec_cpu_down(1, 0);
 
index 2d60ea3..9ff7105 100644 (file)
@@ -641,23 +641,28 @@ void xics_teardown_cpu(int secondary)
        ops->cppr_info(cpu, 0x00);
        iosync();
 
        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.
         */
        /*
         * 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);
                rtas_set_indicator(GLOBAL_INTERRUPT_QUEUE,
                        (1UL << interrupt_server_size) - 1 -
                        default_distrib_server, 0);
-       }
+       
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
index 8fa541c..5a220d6 100644 (file)
@@ -220,6 +220,21 @@ out:
        return err;
 }
 
        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,
 /* 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;
        }
 
                        goto out;
        }
 
-       retval = -EINVAL;
        len = PAGE_ALIGN(len);
        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(&current->mm->mmap_sem);
        retval = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
        up_write(&current->mm->mmap_sem);
 
        flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
 
        down_write(&current->mm->mmap_sem);
        retval = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
        up_write(&current->mm->mmap_sem);
 
-out_putf:
        if (file)
                fput(file);
 out:
        if (file)
                fput(file);
 out:
index 62d7497..ef41925 100644 (file)
@@ -550,6 +550,26 @@ asmlinkage long sparc64_personality(unsigned long personality)
        return ret;
 }
 
        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,
 /* 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);
        }
        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(&current->mm->mmap_sem);
        retval = do_mmap(file, addr, len, prot, flags, off);
        up_write(&current->mm->mmap_sem);
 
 
        down_write(&current->mm->mmap_sem);
        retval = do_mmap(file, addr, len, prot, flags, off);
        up_write(&current->mm->mmap_sem);
 
-out_putf:
        if (file)
                fput(file);
 out:
        if (file)
                fput(file);
 out:
index 8cb0620..af9d81d 100644 (file)
@@ -69,6 +69,8 @@ static inline void io_remap_pte_range(struct mm_struct *mm, pte_t * pte,
                } else
                        offset += PAGE_SIZE;
 
                } 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);
                do {
                        BUG_ON(!pte_none(*pte));
                        set_pte_at(mm, address, pte, entry);
index fc0f0b0..bd4627b 100644 (file)
@@ -226,7 +226,7 @@ EXPORT_SYMBOL(physmem_forget_descriptor);
 EXPORT_SYMBOL(physmem_remove_mapping);
 EXPORT_SYMBOL(physmem_subst_mapping);
 
 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;
 {
        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);
        }
                virt = __va(page_to_phys(page + i));
                physmem_remove_mapping(virt);
        }
+
+       return 0;
 }
 
 int is_remapped(void *virt)
 }
 
 int is_remapped(void *virt)
index b2cd1f2..0f4ed71 100644 (file)
@@ -123,6 +123,22 @@ config GENERIC_CPU
 
 endchoice
 
 
 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
 #
 #
 # Define implied options from the CPU selection here
 #
@@ -143,6 +159,7 @@ config X86_INTERNODE_CACHE_BYTES
 
 config X86_TSC
        bool
 
 config X86_TSC
        bool
+       depends on !X86_64_XEN
        default y
 
 config X86_GOOD_APIC
        default y
 
 config X86_GOOD_APIC
@@ -185,7 +202,7 @@ config X86_CPUID
 
 config X86_HT
        bool
 
 config X86_HT
        bool
-       depends on SMP && !MK8
+       depends on SMP && !MK8 && !X86_64_XEN
        default y
 
 config MATH_EMULATION
        default y
 
 config MATH_EMULATION
@@ -199,14 +216,22 @@ config EISA
 
 config X86_IO_APIC
        bool
 
 config X86_IO_APIC
        bool
+       depends !XEN_UNPRIVILEGED_GUEST
        default y
 
        default y
 
+config X86_XEN_GENAPIC
+       bool
+       depends X86_64_XEN
+       default XEN_PRIVILEGED_GUEST || SMP
+
 config X86_LOCAL_APIC
        bool
 config X86_LOCAL_APIC
        bool
+       depends !XEN_UNPRIVILEGED_GUEST
        default y
 
 config MTRR
        bool "MTRR (Memory Type Range Register) support"
        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
        ---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"
 
 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
        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"
 
 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
        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"
 
 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 
        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
 
 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
 
 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
        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
        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.
 
                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
 
 config HPET_TIMER
        bool
+       depends on !X86_64_XEN
        default y
        help
          Use the IA-PC HPET (High Precision Event Timer) to manage
        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
        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.
        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
 
 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.
        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)"
 
 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
        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"
        default y
 
 menu "Power management options"
+       depends on !XEN_UNPRIVILEGED_GUEST
 
 
+if !X86_64_XEN
 source kernel/power/Kconfig
 source kernel/power/Kconfig
+endif
 
 source "drivers/acpi/Kconfig"
 
 
 source "drivers/acpi/Kconfig"
 
@@ -549,6 +582,21 @@ config PCI_MMCONFIG
        bool "Support mmconfig PCI config space access"
        depends on PCI && ACPI
 
        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"
 source "drivers/pci/pcie/Kconfig"
 
 source "drivers/pci/Kconfig"
@@ -621,4 +669,6 @@ source "security/Kconfig"
 
 source "crypto/Kconfig"
 
 
 source "crypto/Kconfig"
 
+source "drivers/xen/Kconfig"
+
 source "lib/Kconfig"
 source "lib/Kconfig"
index e573e2a..4b81d9f 100644 (file)
@@ -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)
 
 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
 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
 
 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
 
 #Default target when executing "make"
 all: bzImage
 
@@ -92,6 +111,7 @@ fdimage fdimage144 fdimage288 isoimage: vmlinux
 
 install:
        $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(BOOTIMAGE) $@ 
 
 install:
        $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(BOOTIMAGE) $@ 
+endif
 
 archclean:
        $(Q)$(MAKE) $(clean)=$(boot)
 
 archclean:
        $(Q)$(MAKE) $(clean)=$(boot)
index e9263b4..a84151e 100644 (file)
@@ -23,9 +23,25 @@ quiet_cmd_syscall = SYSCALL $@
                           -Wl,-soname=linux-gate.so.1 -o $@ \
                           -Wl,-T,$(filter-out FORCE,$^)
 
                           -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)
 
 $(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
index 1384367..6086ac6 100644 (file)
@@ -139,5 +139,5 @@ __kernel_rt_sigreturn:
        .align 4
 .LENDFDE3:
 
        .align 4
 .LENDFDE3:
 
-#include "../../i386/kernel/vsyscall-note.S"
+#include <vsyscall-note.S>
 
 
index 059c883..b0913f3 100644 (file)
@@ -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_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_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
 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
 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
index 4fe9707..aa84f6e 100644 (file)
@@ -6,3 +6,4 @@ ifneq ($(CONFIG_ACPI_PROCESSOR),)
 obj-y                  += processor.o
 endif
 
 obj-y                  += processor.o
 endif
 
+boot-$(CONFIG_XEN)             := ../../../i386/kernel/acpi/boot-xen.o
index 38834bb..06cf058 100644 (file)
@@ -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));
        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));
        BLANK();
        DEFINE(TSS_ist, offsetof(struct tss_struct, ist));
+#endif
        return 0;
 }
        return 0;
 }
index 586b34c..4c599ee 100644 (file)
@@ -596,7 +596,7 @@ retint_kernel:
  */            
        .macro apicinterrupt num,func
        INTR_FRAME
  */            
        .macro apicinterrupt num,func
        INTR_FRAME
-       pushq $\num-256
+       pushq $~(\num)
        CFI_ADJUST_CFA_OFFSET 8
        interrupt \func
        jmp ret_from_intr
        CFI_ADJUST_CFA_OFFSET 8
        interrupt \func
        jmp ret_from_intr
index ce31d90..9c141e1 100644 (file)
@@ -37,6 +37,8 @@ union thread_union init_thread_union
 struct task_struct init_task = INIT_TASK(init_task);
 
 EXPORT_SYMBOL(init_task);
 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
 /*
  * 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;
  * 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")))
 
 #define ALIGN_TO_4K __attribute__((section(".data.init_task")))
index d8bd0b3..c874885 100644 (file)
@@ -91,8 +91,8 @@ skip:
  */
 asmlinkage unsigned int do_IRQ(struct pt_regs *regs)
 {      
  */
 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();
 
        exit_idle();
        irq_enter();
index bf421ed..07340ae 100644 (file)
@@ -60,7 +60,9 @@ int pmtimer_mark_offset(void)
        delta = cyc2us((tick - last_pmtmr_tick) & ACPI_PM_MASK);
 
        last_pmtmr_tick = tick;
        delta = cyc2us((tick - last_pmtmr_tick) & ACPI_PM_MASK);
 
        last_pmtmr_tick = tick;
+#ifndef CONFIG_XEN
        monotonic_base += delta * NSEC_PER_USEC;
        monotonic_base += delta * NSEC_PER_USEC;
+#endif
 
        delta += offset_delay;
 
 
        delta += offset_delay;
 
index 655b919..e8d5f84 100644 (file)
@@ -1440,7 +1440,7 @@ struct seq_operations cpuinfo_op = {
        .show = show_cpuinfo,
 };
 
        .show = show_cpuinfo,
 };
 
-#ifdef CONFIG_INPUT_PCSPKR
+#if defined(CONFIG_INPUT_PCSPKR) || defined(CONFIG_INPUT_PCSPKR_MODULE)
 #include <linux/platform_device.h>
 static __init int add_pcspkr(void)
 {
 #include <linux/platform_device.h>
 static __init int add_pcspkr(void)
 {
index 8a691fa..189a737 100644 (file)
@@ -46,7 +46,7 @@ Control non executable mappings for 64bit processes.
 on     Enable(default)
 off    Disable
 */ 
 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; 
 {
        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;
         }
                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:
 
 /*
  * Great future plan:
index 4a6628b..e13938d 100644 (file)
@@ -135,10 +135,10 @@ asmlinkage void smp_invalidate_interrupt(struct pt_regs *regs)
 
        cpu = smp_processor_id();
        /*
 
        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.
         */
         * 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))
        f = &per_cpu(flush_state, sender);
 
        if (!cpu_isset(cpu, f->flush_cpumask))
index d25ac86..7d6ceae 100644 (file)
@@ -9,3 +9,13 @@ obj-$(CONFIG_K8_NUMA) += k8topology.o
 obj-$(CONFIG_ACPI_NUMA) += srat.o
 
 hugetlbpage-y = ../../i386/mm/hugetlbpage.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
index 6be3268..589a796 100644 (file)
@@ -11,9 +11,12 @@ DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \
        oprofilefs.o oprofile_stats.o \
        timer_int.o )
 
        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 
 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))
 oprofile-y = $(DRIVER_OBJS) $(addprefix ../../i386/oprofile/, $(OPROFILE-y))
index a3f6ad5..1ea6ea9 100644 (file)
@@ -15,11 +15,23 @@ obj-$(CONFIG_PCI_MMCONFIG) += mmconfig.o direct.o
 
 obj-$(CONFIG_NUMA)     += k8-bus.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
 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
 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
index a2060e4..3c55c76 100644 (file)
 
 #include "pci.h"
 
 
 #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
 /* 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,
                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)) {
                        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;
        }
                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];
        }
        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);
                if (!pci_mmcfg_virt[i].virt) {
                        printk("PCI: Cannot map mmconfig aperture for segment %d\n",
                               pci_mmcfg_config[i].pci_segment_group_number);
index a0afdd3..7be96bb 100644 (file)
@@ -766,7 +766,8 @@ void elv_unregister(struct elevator_type *e)
                read_lock(&tasklist_lock);
                do_each_thread(g, p) {
                        task_lock(p);
                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);
                        task_unlock(p);
                } while_each_thread(g, p);
                read_unlock(&tasklist_lock);
index 7eb36c5..4293143 100644 (file)
@@ -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. */
        /* 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
                dma = 1;
        q->bounce_pfn = max_low_pfn;
 #else
index 1e12169..78c849c 100644 (file)
@@ -1,7 +1,8 @@
+# i386
 #
 # Automatically generated make config: don't edit
 #
 # 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
 #
 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_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_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_MICROCODE is not set
 CONFIG_X86_MSR=m
 CONFIG_X86_CPUID=m
+# CONFIG_SWIOTLB is not set
 
 #
 # Firmware Drivers
 
 #
 # 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_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_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
 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_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
 # 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_HZ_1000 is not set
 CONFIG_HZ=250
 CONFIG_KEXEC=y
+# CONFIG_CRASH_DUMP is not set
 CONFIG_PHYSICAL_START=0x400000
 CONFIG_PHYSICAL_START=0x400000
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 
 #
 # Power management options (ACPI, APM)
 
 #
 # 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_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_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_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
 
 #
 # 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_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
 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_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
 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_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
 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_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_BUGVERBOSE=y
 CONFIG_DEBUG_INFO=y
 CONFIG_DEBUG_FS=y
index 1be1977..6bbc795 100644 (file)
@@ -1,7 +1,8 @@
+# i386
 #
 # Automatically generated make config: don't edit
 #
 # 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
 #
 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_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
 # 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_MICROCODE=m
 CONFIG_X86_MSR=m
 CONFIG_X86_CPUID=m
+# CONFIG_SWIOTLB is not set
 
 #
 # Firmware Drivers
 
 #
 # Firmware Drivers
@@ -202,6 +205,7 @@ CONFIG_KEXEC=y
 # CONFIG_CRASH_DUMP is not set
 CONFIG_PHYSICAL_START=0x400000
 CONFIG_HOTPLUG_CPU=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)
 
 #
 # 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_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_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_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
 
 #
 # 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_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
 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_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
 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_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
 CONFIG_CIFS=m
 # CONFIG_CIFS_STATS is not set
 CONFIG_CIFS_XATTR=y
index 97dd349..111ab3a 100644 (file)
@@ -1,7 +1,8 @@
+# i386
 #
 # Automatically generated make config: don't edit
 #
 # 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
 #
 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_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_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_MICROCODE=m
 CONFIG_X86_MSR=m
 CONFIG_X86_CPUID=m
+# CONFIG_SWIOTLB is not set
 
 #
 # Firmware Drivers
 
 #
 # Firmware Drivers
@@ -196,6 +199,7 @@ CONFIG_HZ=250
 CONFIG_KEXEC=y
 # CONFIG_CRASH_DUMP is not set
 CONFIG_PHYSICAL_START=0x400000
 CONFIG_KEXEC=y
 # CONFIG_CRASH_DUMP is not set
 CONFIG_PHYSICAL_START=0x400000
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 
 #
 # Power management options (ACPI, APM)
 
 #
 # 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_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_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_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
 
 #
 # 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_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
 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_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
 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_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
 CONFIG_CIFS=m
 # CONFIG_CIFS_STATS is not set
 CONFIG_CIFS_XATTR=y
index 447d8e6..26b2956 100644 (file)
@@ -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_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/
 obj-$(CONFIG_IDE)              += ide/
 obj-$(CONFIG_FC4)              += fc4/
 obj-$(CONFIG_SCSI)             += scsi/
index c24652d..f0c8926 100644 (file)
@@ -46,7 +46,7 @@ if ACPI
 
 config ACPI_SLEEP
        bool "Sleep States"
 
 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---
        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
 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,
        default y
        help
          The Power Management Timer is available on all ACPI-capable,
index a95f636..d7791fb 100644 (file)
@@ -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,
                                    "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;
                }
 
                status = AE_BAD_PARAMETER;
index fdff774..c1434ed 100644 (file)
@@ -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;
        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;
                goto exit;
        if (!is_aoe_netif(ifp))
                goto exit;
index 3170eaa..fdd37e4 100644 (file)
@@ -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;
        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;
 
        if ((ret = cdo->generic_packet(cdi, &cgc)))
                return ret;
index 6a7aa93..418da02 100644 (file)
 # include <linux/efi.h>
 #endif
 
 # include <linux/efi.h>
 #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.
 /*
  * 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
 
 }
 #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. 
 /*
  * 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;
 }
        *ppos += written;
        return written;
 }
+#endif
 
 #ifndef __HAVE_PHYS_MEM_ACCESS_PROT
 static pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
 
 #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
 
 #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,
 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,
 };
        .mmap           = mmap_mem,
        .open           = open_mem,
 };
+#else
+extern struct file_operations mem_fops;
+#endif
 
 static struct file_operations kmem_fops = {
        .llseek         = memory_lseek,
 
 static struct file_operations kmem_fops = {
        .llseek         = memory_lseek,
index 8ea7062..2678034 100644 (file)
@@ -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));
        iowrite32(interrupt,
                  chip->vendor.iobase +
                  TPM_INT_STATUS(chip->vendor.locality));
+       ioread32(chip->vendor.iobase + TPM_INT_STATUS(chip->vendor.locality));
        return IRQ_HANDLED;
 }
 
        return IRQ_HANDLED;
 }
 
index 0b31cf2..12c1582 100644 (file)
@@ -133,6 +133,8 @@ LIST_HEAD(tty_drivers);                     /* linked list of tty drivers */
    vt.c for deeply disgusting hack reasons */
 DEFINE_MUTEX(tty_mutex);
 
    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 */
 #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;
 }
 
        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.
 /*
  * 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
                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;
                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_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;
        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);
                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;
                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);
                }
                        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;
                        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);
        }
                        tty->buf.tail = NULL;
                tty_buffer_free(tty, tbuf);
        }
@@ -3277,6 +3270,8 @@ static int __init tty_init(void)
 #endif
 
 #ifdef CONFIG_VT
 #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)
        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();
        class_device_create(tty_class, NULL, MKDEV(TTY_MAJOR, 0), NULL, "tty0");
 
        vty_init();
+ out_vt:
 #endif
        return 0;
 }
 #endif
        return 0;
 }
index 1e371a5..f0dff5a 100644 (file)
@@ -8,7 +8,7 @@ menu "Firmware Drivers"
 config EDD
        tristate "BIOS Enhanced Disk Drive calls determine boot disk (EXPERIMENTAL)"
        depends on EXPERIMENTAL
 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
        help
          Say Y or M here if you want to enable BIOS Enhanced Disk Drive
          Services real mode BIOS calls to determine which disk
index 766cc96..9b4f4ee 100644 (file)
@@ -181,21 +181,21 @@ static void scx200_acb_machine(struct scx200_acb_iface *iface, u8 status)
                break;
 
        case state_read:
                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);
 
                        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->result = 0;
                        iface->state = state_idle;
                        outb(inb(ACBCTL1) | ACBCTL1_STOP, ACBCTL1);
                }
 
+               *iface->ptr++ = inb(ACBSDA);
+               --iface->len;
+
                break;
 
        case state_write:
                break;
 
        case state_write:
@@ -304,8 +304,12 @@ static s32 scx200_acb_smbus_xfer(struct i2c_adapter *adapter,
                buffer = (u8 *)&cur_word;
                break;
 
                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];
                len = data->block[0];
+               if (len == 0 || len > I2C_SMBUS_BLOCK_MAX)
+                       return -EINVAL;
                buffer = &data->block[1];
                break;
 
                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 |
 {
        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) */
 }
 
 /* For now, we only handle combined mode (smbus) */
index 45e2cdf..2e79137 100644 (file)
@@ -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]);
                                        "parameter for adapter %d, "
                                        "addr 0x%02x\n", adap_id,
                                        address_data->ignore[j + 1]);
+                               ignore = 1;
+                               break;
                        }
                        }
-                       ignore = 1;
-                       break;
                }
                if (ignore)
                        continue;
                }
                if (ignore)
                        continue;
index 41d46db..b09a653 100644 (file)
@@ -410,10 +410,10 @@ void ide_toggle_bounce(ide_drive_t *drive, int on)
 {
        u64 addr = BLK_BOUNCE_HIGH;     /* dma64_addr_t */
 
 {
        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;
        }
 
                        addr = HWIF(drive)->pci_dev->dma_mask;
        }
 
index 3e677c4..9914a78 100644 (file)
@@ -6,7 +6,7 @@
  *
  *   vt82c576, vt82c586, vt82c586a, vt82c586b, vt82c596a, vt82c596b,
  *   vt82c686, vt82c686a, vt82c686b, vt8231, vt8233, vt8233c, vt8233a,
  *
  *   vt82c576, vt82c586, vt82c586a, vt82c586b, vt82c596a, vt82c596b,
  *   vt82c686, vt82c686a, vt82c686b, vt8231, vt8233, vt8233c, vt8233a,
- *   vt8235, vt8237
+ *   vt8235, vt8237, vt8237a
  *
  * Copyright (c) 2000-2002 Vojtech Pavlik
  *
  *
  * 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 },
        { "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 },
        { "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 },
index 8f1292c..d1788cd 100644 (file)
@@ -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)
 {
 
 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;
 #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
 
        }
 #endif
 
-       pci_save_state(pdev);
-
        return 0;
 }
 
        return 0;
 }
 
index 5413dc4..e084dbf 100644 (file)
@@ -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;
                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;
 }
 
        return 0;
 }
 
index df5e494..f4fddd5 100644 (file)
@@ -49,6 +49,12 @@ int mthca_reset(struct mthca_dev *mdev)
        u32 *hca_header    = NULL;
        u32 *bridge_header = NULL;
        struct pci_dev *bridge = NULL;
        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)
 
 #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) {
        if (bridge) {
                bridge_header = kmalloc(256, GFP_KERNEL);
                if (!bridge_header) {
@@ -129,6 +138,13 @@ int mthca_reset(struct mthca_dev *mdev)
                                goto out;
                        }
                }
                                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 */
        }
 
        /* actually hit reset */
@@ -178,6 +194,20 @@ int mthca_reset(struct mthca_dev *mdev)
 good:
        /* Now restore the PCI headers */
        if (bridge) {
 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.
                /*
                 * 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;
        for (i = 0; i < 16; ++i) {
                if (i * 4 == PCI_COMMAND)
                        continue;
index 1dae4b2..1d917ed 100644 (file)
@@ -821,7 +821,8 @@ void ipoib_mcast_restart_task(void *dev_ptr)
 
        ipoib_mcast_stop_thread(dev, 0);
 
 
        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);
 
        /*
        spin_lock(&priv->lock);
 
        /*
@@ -896,7 +897,8 @@ void ipoib_mcast_restart_task(void *dev_ptr)
        }
 
        spin_unlock(&priv->lock);
        }
 
        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) {
 
        /* We have to cancel outside of the spinlock */
        list_for_each_entry_safe(mcast, tmcast, &remove_list, list) {
index cc07bbe..34a7593 100644 (file)
@@ -91,7 +91,6 @@ struct pstore {
        struct dm_snapshot *snap;       /* up pointer to my snapshot */
        int version;
        int valid;
        struct dm_snapshot *snap;       /* up pointer to my snapshot */
        int version;
        int valid;
-       uint32_t chunk_size;
        uint32_t exceptions_per_area;
 
        /*
        uint32_t exceptions_per_area;
 
        /*
@@ -133,7 +132,7 @@ static int alloc_area(struct pstore *ps)
        int r = -ENOMEM;
        size_t len;
 
        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
 
        /*
         * 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;
        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);
 }
 
        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)
 {
 
 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);
 }
 
        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;
 {
        int r;
        struct disk_header *dh;
+       chunk_t chunk_size;
 
        r = chunk_io(ps, 0, READ);
        if (r)
 
        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);
                *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;
        } else {
                DMWARN("Invalid/corrupt snapshot");
                r = -ENXIO;
@@ -224,13 +245,13 @@ static int write_header(struct pstore *ps)
 {
        struct disk_header *dh;
 
 {
        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 = (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);
 }
 
        return chunk_io(ps, 0, WRITE);
 }
@@ -365,7 +386,7 @@ static void persistent_destroy(struct exception_store *store)
 {
        struct pstore *ps = get_info(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);
        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;
 
        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 ?
         */
        /*
         * 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->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;
 
        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;
 
        if (r)
                goto bad;
 
-       /*
-        * Allocate space for all the callbacks.
-        */
        ps->callback_count = 0;
        atomic_set(&ps->pending_count, 0);
        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;
 
        store->destroy = persistent_destroy;
        store->read_metadata = persistent_read_metadata;
index 8edd643..f7e7436 100644 (file)
@@ -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)
        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 hc;
+               }
 
        return NULL;
 }
 
        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)
        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 hc;
+               }
 
        return NULL;
 }
 
        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)
 {
  */
 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.
 
        /*
         * 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);
         * 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;
                goto bad;
+       }
 
        list_add(&cell->name_list, _name_buckets + hash_str(name));
 
        if (uuid) {
 
        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);
                        list_del(&cell->name_list);
+                       dm_put(hc->md);
                        goto bad;
                }
                list_add(&cell->uuid_list, _uuid_buckets + hash_str(uuid));
                        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);
        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;
                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_table_put(table);
        }
 
+       dm_put(hc->md);
        up_write(&_hash_lock);
        kfree(old_name);
        return 0;
        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));
                return __get_name_cell(param->name);
 
        md = dm_get_md(huge_decode_dev(param->dev));
-       if (md) {
+       if (md)
                mdptr = dm_get_mdptr(md);
                mdptr = dm_get_mdptr(md);
-               dm_put(md);
-       }
 
        return mdptr;
 }
 
        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;
        hc = __find_device_hash_cell(param);
        if (hc) {
                md = hc->md;
-               dm_get(md);
 
                /*
                 * Sneakily write in both the name and the uuid
 
                /*
                 * 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;
 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);
 
        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;
        }
 
                return -ENXIO;
        }
 
+       md = hc->md;
+
        __hash_remove(hc);
        up_write(&_hash_lock);
        __hash_remove(hc);
        up_write(&_hash_lock);
+       dm_put(md);
        param->data_size = 0;
        return 0;
 }
        param->data_size = 0;
        return 0;
 }
@@ -790,7 +802,6 @@ static int do_resume(struct dm_ioctl *param)
        }
 
        md = hc->md;
        }
 
        md = hc->md;
-       dm_get(md);
 
        new_map = hc->new_map;
        hc->new_map = NULL;
 
        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;
 {
        int r;
        struct hash_cell *hc;
+       struct mapped_device *md;
 
        down_write(&_hash_lock);
 
 
        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);
        param->flags &= ~DM_INACTIVE_PRESENT_FLAG;
 
        r = __dev_status(hc->md, param);
+       md = hc->md;
        up_write(&_hash_lock);
        up_write(&_hash_lock);
+       dm_put(md);
        return r;
 }
 
        return r;
 }
 
index 1816f30..5af5265 100644 (file)
@@ -711,6 +711,8 @@ static int multipath_ctr(struct dm_target *ti, unsigned int argc,
                return -EINVAL;
        }
 
                return -EINVAL;
        }
 
+       m->ti = ti;
+
        r = parse_features(&as, m, ti);
        if (r)
                goto bad;
        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;
        }
 
        ti->private = m;
-       m->ti = ti;
 
        return 0;
 
 
        return 0;
 
index d12cf3e..2cab46e 100644 (file)
@@ -106,12 +106,42 @@ struct region {
        struct bio_list delayed_bios;
 };
 
        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)
 {
 /*
  * 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)
 }
 
 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);
        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;
        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();
 }
 
        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.
  */
 /*
  * 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;
 
        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);
 
        if (rw == WRITE) {
                queue_bio(ms, bio, rw);
index 08312b4..b84bc1a 100644 (file)
@@ -530,7 +530,7 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
        }
 
        ti->private = s;
        }
 
        ti->private = s;
-       ti->split_io = chunk_size;
+       ti->split_io = s->chunk_size;
 
        return 0;
 
 
        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",
 
 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,
        .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",
 
 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,
        .module  = THIS_MODULE,
        .ctr     = snapshot_ctr,
        .dtr     = snapshot_dtr,
index 4d710b7..dfd0378 100644 (file)
@@ -26,6 +26,7 @@ static const char *_name = DM_NAME;
 static unsigned int major = 0;
 static unsigned int _major = 0;
 
 static unsigned int major = 0;
 static unsigned int _major = 0;
 
+static DEFINE_SPINLOCK(_minor_lock);
 /*
  * One of these is allocated per bio.
  */
 /*
  * One of these is allocated per bio.
  */
@@ -54,12 +55,15 @@ union map_info *dm_get_mapinfo(struct bio *bio)
         return NULL;
 }
 
         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
 /*
  * 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;
 
 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;
 
 {
        struct mapped_device *md;
 
+       spin_lock(&_minor_lock);
+
        md = inode->i_bdev->bd_disk->private_data;
        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);
        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)
 }
 
 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.
  *---------------------------------------------------------------*/
 /*-----------------------------------------------------------------
  * 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)
 {
 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);
        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;
 
        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;
        }
 
 
        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;
                goto out;
-       }
 
        if (m != minor) {
                idr_remove(&_minor_idr, m);
 
        if (m != minor) {
                idr_remove(&_minor_idr, m);
@@ -789,7 +803,7 @@ static int specific_minor(struct mapped_device *md, unsigned int minor)
        }
 
 out:
        }
 
 out:
-       mutex_unlock(&_minor_lock);
+       spin_unlock(&_minor_lock);
        return r;
 }
 
        return r;
 }
 
@@ -798,15 +812,13 @@ static int next_free_minor(struct mapped_device *md, unsigned int *minor)
        int r;
        unsigned int m;
 
        int r;
        unsigned int m;
 
-       mutex_lock(&_minor_lock);
-
        r = idr_pre_get(&_minor_idr, GFP_KERNEL);
        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;
        }
        if (r) {
                goto out;
        }
@@ -820,7 +832,7 @@ static int next_free_minor(struct mapped_device *md, unsigned int *minor)
        *minor = m;
 
 out:
        *minor = m;
 
 out:
-       mutex_unlock(&_minor_lock);
+       spin_unlock(&_minor_lock);
        return r;
 }
 
        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);
 {
        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 (!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)
        /* 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;
 
        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;
        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));
 
        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;
 
 
        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:
        blk_cleanup_queue(md->queue);
        free_minor(minor);
  bad1:
+       module_put(THIS_MODULE);
+ bad0:
        kfree(md);
        return NULL;
 }
        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);
        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);
        put_disk(md->disk);
        blk_cleanup_queue(md->queue);
+       module_put(THIS_MODULE);
        kfree(md);
 }
 
        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;
 
        if (MAJOR(dev) != _major || minor >= (1 << MINORBITS))
                return NULL;
 
-       mutex_lock(&_minor_lock);
+       spin_lock(&_minor_lock);
 
        md = idr_find(&_minor_idr, minor);
 
        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;
                md = NULL;
+               goto out;
+       }
 
 
-       mutex_unlock(&_minor_lock);
+out:
+       spin_unlock(&_minor_lock);
 
        return md;
 }
 
        return md;
 }
@@ -1055,8 +1091,13 @@ void dm_put(struct mapped_device *md)
 {
        struct dm_table *map;
 
 {
        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);
                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);
                if (!dm_suspended(md)) {
                        dm_table_presuspend_targets(map);
                        dm_table_postsuspend_targets(map);
index 4070eff..5a54494 100644 (file)
@@ -1486,7 +1486,6 @@ static void raid1d(mddev_t *mddev)
                                                        d = conf->raid_disks;
                                                d--;
                                                rdev = conf->mirrors[d].rdev;
                                                        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,
                                                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);
                                                                         s<<9, conf->tmppage, READ) == 0)
                                                                /* Well, this device is dead */
                                                                md_error(mddev, rdev);
+                                                       else
+                                                               atomic_add(s, &rdev->corrected_errors);
+
                                                }
                                        }
                                } else {
                                                }
                                        }
                                } else {
index ccc7b2e..0bcaa35 100644 (file)
@@ -184,6 +184,11 @@ static struct mt352_config thomson_dtt7579_config = {
        .pll_set = thomson_dtt7579_pll_set,
 };
 
        .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;
 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);
        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;
                if (card->fe != NULL) {
                        card->fe->ops->info.frequency_min = 174000000;
                        card->fe->ops->info.frequency_max = 862000000;
index 00dd9fa..e41066a 100644 (file)
@@ -37,6 +37,7 @@
 #include "cx24110.h"
 #include "or51211.h"
 #include "lgdt330x.h"
 #include "cx24110.h"
 #include "or51211.h"
 #include "lgdt330x.h"
+#include "zl10353.h"
 
 struct dvb_bt8xx_card {
        struct mutex lock;
 
 struct dvb_bt8xx_card {
        struct mutex lock;
index a051790..cb69372 100644 (file)
@@ -519,7 +519,9 @@ static int dvb_frontend_thread(void *data)
        fepriv->delay = 3*HZ;
        fepriv->status = 0;
        fepriv->wakeup = 0;
        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... */
 
        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) {
                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;
                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;
        }
 
        return ret;
index 2f0f358..9fd8752 100644 (file)
@@ -1052,7 +1052,7 @@ static void wq_set_multicast_list (void *data)
 
        dvb_net_feed_stop(dev);
        priv->rx_mode = RX_MODE_UNI;
 
        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);
 
        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);
 }
 
        dvb_net_feed_start(dev);
 }
 
index 791706e..40930a3 100644 (file)
@@ -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 */ },
                {  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);
        }
 };
 EXPORT_SYMBOL(dvb_pll_tda665x);
index 8a7cd7d..3f4aa08 100644 (file)
@@ -58,6 +58,7 @@ struct budget_av {
        struct tasklet_struct ciintf_irq_tasklet;
        int slot_status;
        struct dvb_ca_en50221 ca;
        struct tasklet_struct ciintf_irq_tasklet;
        int slot_status;
        struct dvb_ca_en50221 ca;
+       u8 reinitialise_demod:1;
 };
 
 /* GPIO Connections:
 };
 
 /* 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);
 
        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)
        {
 
        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;
 
        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:
        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;
        }
                        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:
                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:
        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));
                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);
 
        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;
 }
 
        return 0;
 }
 
index 689e971..d6d37cf 100644 (file)
@@ -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);
 
                // 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))
                break;
 
        case 0x1004: // Hauppauge/TT DVB-C budget (ves1820/ALPS TDBE2(sp5659))
index 6b41970..67d729a 100644 (file)
@@ -380,10 +380,10 @@ config VIDEO_WM8739
 source "drivers/media/video/cx25840/Kconfig"
 
 config VIDEO_SAA711X
 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---
        ---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.
 
          To compile this driver as a module, choose M here: the
          module will be called saa7115.
index 07476c7..af372dd 100644 (file)
@@ -2180,7 +2180,6 @@ static struct pci_device_id stradis_pci_tbl[] = {
        { 0 }
 };
 
        { 0 }
 };
 
-MODULE_DEVICE_TABLE(pci, stradis_pci_tbl);
 
 static struct pci_driver stradis_driver = {
        .name = "stradis",
 
 static struct pci_driver stradis_driver = {
        .name = "stradis",
index 066e22b..365a074 100644 (file)
@@ -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)
        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];
 
        if (skb_shinfo(skb)->nr_frags == 0) {
                struct cp_desc *txd = &cp->tx_ring[entry];
index 54161ae..a8f95e5 100644 (file)
@@ -1638,7 +1638,7 @@ bnx2_tx_int(struct bnx2 *bp)
                skb = tx_buf->skb;
 #ifdef BCM_TSO 
                /* partial BD completions possible with TSO packets */
                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 +
                        u16 last_idx, last_ring_idx;
 
                        last_idx = sw_cons +
@@ -2009,7 +2009,7 @@ bnx2_poll(struct net_device *dev, int *budget)
        return 1;
 }
 
        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
  * from set_multicast.
  */
 static void
@@ -4252,7 +4252,7 @@ bnx2_vlan_rx_kill_vid(struct net_device *dev, uint16_t vid)
 }
 #endif
 
 }
 #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
  * 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 
                        (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;
 
                (skb->len > (bp->dev->mtu + ETH_HLEN))) {
                u32 tcp_opt_len, ip_tcp_len;
 
index 55d2367..8171cae 100644 (file)
@@ -1199,8 +1199,7 @@ int bond_sethwaddr(struct net_device *bond_dev, struct net_device *slave_dev)
 }
 
 #define BOND_INTERSECT_FEATURES \
 }
 
 #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
 
 /* 
  * 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 &= (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;
 
        /* 
                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;
 
         */
        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;
 
         * transmitting */
        bond_dev->features |= NETIF_F_LLTX;
 
index 4391bf4..722be62 100644 (file)
@@ -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
        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;
 
                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,
                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++;
                hdr->len = htonl(skb->len - sizeof(*hdr));
                cpl = (struct cpl_tx_pkt *)hdr;
                sge->stats.tx_lso_pkts++;
index 523c2c9..c5e7023 100644 (file)
@@ -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_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:
         hw->mac_type = e1000_82572;
         break;
     case E1000_DEV_ID_82573E:
index 150e45e..c01e5d2 100644 (file)
@@ -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_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
 #define E1000_DEV_ID_82573E              0x108B
 #define E1000_DEV_ID_82573E_IAMT         0x108C
 #define E1000_DEV_ID_82573L              0x109A
index 97e71a4..43e6472 100644 (file)
@@ -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;
 
        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)
                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));
                }
 
                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;
                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 &&
                 * 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;
                }
                        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
        }
 
 #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:
        /* 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 */
 
 #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
 
                count++;
 #endif
 
index feb5b22..1a55695 100644 (file)
@@ -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.
  * 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 :-(
  *     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 */
  */
 
 /* in dev: base, irq */
@@ -1213,7 +1213,7 @@ static void drain_ring(struct net_device *dev)
 
 /*
  * nv_start_xmit: dev->hard_start_xmit function
 
 /*
  * 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)
 {
  */
 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
        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);
        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
 
 /*
  * 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)
 {
  */
 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.
                 */
                 * 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);
                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);
                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;
 }
        }
        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)) {
        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 */
                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);
                /* 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);
        }
        } 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
 
 /*
  * 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)
 {
  */
 static void nv_set_multicast(struct net_device *dev)
 {
index 102c1f0..d12605f 100644 (file)
@@ -308,9 +308,9 @@ static int sp_set_mac_address(struct net_device *dev, void *addr)
 {
        struct sockaddr_ax25 *sa = 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);
        memcpy(dev->dev_addr, &sa->sax25_call, AX25_ADDR_LEN);
-       spin_unlock_irq(&dev->xmit_lock);
+       netif_tx_unlock_bh(dev);
 
        return 0;
 }
 
        return 0;
 }
@@ -767,9 +767,9 @@ static int sixpack_ioctl(struct tty_struct *tty, struct file *file,
                        break;
                }
 
                        break;
                }
 
-               spin_lock_irq(&dev->xmit_lock);
+               netif_tx_lock_bh(dev);
                memcpy(dev->dev_addr, &addr, AX25_ADDR_LEN);
                memcpy(dev->dev_addr, &addr, AX25_ADDR_LEN);
-               spin_unlock_irq(&dev->xmit_lock);
+               netif_tx_unlock_bh(dev);
 
                err = 0;
                break;
 
                err = 0;
                break;
index d81a8e1..3ebbbe5 100644 (file)
@@ -357,9 +357,9 @@ static int ax_set_mac_address(struct net_device *dev, void *addr)
 {
        struct sockaddr_ax25 *sa = 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);
        memcpy(dev->dev_addr, &sa->sax25_call, AX25_ADDR_LEN);
-       spin_unlock_irq(&dev->xmit_lock);
+       netif_tx_unlock_bh(dev);
 
        return 0;
 }
 
        return 0;
 }
@@ -886,9 +886,9 @@ static int mkiss_ioctl(struct tty_struct *tty, struct file *file,
                        break;
                }
 
                        break;
                }
 
-               spin_lock_irq(&dev->xmit_lock);
+               netif_tx_lock_bh(dev);
                memcpy(dev->dev_addr, addr, AX25_ADDR_LEN);
                memcpy(dev->dev_addr, addr, AX25_ADDR_LEN);
-               spin_unlock_irq(&dev->xmit_lock);
+               netif_tx_unlock_bh(dev);
 
                err = 0;
                break;
 
                err = 0;
                break;
index 31fb2d7..2e222ef 100644 (file)
@@ -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++;
        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++;
                        }
                        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++;
                } 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;
                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++;
                                netif_wake_queue(_dev);
                } else {
                        dp->st_rxq_rsch++;
-                       spin_unlock(&_dev->xmit_lock);
+                       netif_tx_unlock(_dev);
                        goto resched;
                }
                        goto resched;
                }
-               spin_unlock(&_dev->xmit_lock);
+               netif_tx_unlock(_dev);
        } else {
 resched:
                dp->tasklet_pending = 1;
        } else {
 resched:
                dp->tasklet_pending = 1;
index 97a49e0..d70b9e8 100644 (file)
@@ -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);
                            ||  (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! */
                }
        }
 
                }
        }
 
index cfd67d8..8385245 100644 (file)
@@ -1168,7 +1168,7 @@ ixgb_tso(struct ixgb_adapter *adapter, struct sk_buff *skb)
        uint16_t ipcse, tucse, mss;
        int err;
 
        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)
                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));
                }
 
                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,
                skb->nh.iph->tot_len = 0;
                skb->nh.iph->check = 0;
                skb->h.th->check = ~csum_tcpudp_magic(skb->nh.iph->saddr,
index b79d6e8..997cbce 100644 (file)
@@ -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;
        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);
        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
 #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);
 
                BUG_ON(skb->protocol != htons(ETH_P_IP));
                BUG_ON(skb->nh.iph->protocol != IPPROTO_TCP);
 
index 411f4d8..625ff61 100644 (file)
@@ -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 (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);
                        stats->tx_dropped++;
                        printk(KERN_DEBUG "%s: failed to linearize tiny "
                                        "unaligned fragment\n", dev->name);
index 9062775..2e4eced 100644 (file)
@@ -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 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);
 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
        spin_lock_irq(&np->lock);
 
 IV. Notes
index 0ad3310..43641dd 100644 (file)
@@ -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) {
 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);
 
                if (mss)
                        return LargeSend | ((mss & MSSMask) << MSSShift);
index 79208f4..0ad01f0 100644 (file)
@@ -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
        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);
        }
                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;
        }
 
        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;
 
                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);
                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);
 
        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;
                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);
                    (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;
 
                        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];
                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 (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);
 
                val64 |= TX_FIFO_SPECIAL_FUNC;
        writeq(val64, &tx_fifo->List_Control);
 
index fba1e4d..4103e30 100644 (file)
@@ -51,7 +51,7 @@
 #include "sky2.h"
 
 #define DRV_NAME               "sky2"
 #include "sky2.h"
 
 #define DRV_NAME               "sky2"
-#define DRV_VERSION            "1.4"
+#define DRV_VERSION            "1.6.1"
 #define PFX                    DRV_NAME " "
 
 /*
 #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;
                }
                        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);
 
                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_REG5, 0);
                }
 
-               sky2_pci_write32(hw, PCI_DEV_REG1, reg1);
-
                break;
 
        case PCI_D3hot:
                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);
        }
 
        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;
                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;
                        }
                }
                                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;
        } 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);
                        /* 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);
        }
 
        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) {
        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)
                        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;
                                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)
 
                /* 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
 /*
  * 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;
 
  * 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);
        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;
 
        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)
                ++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 */
        }
 
        /* 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) &&
        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)
 {
 
 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)
                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) {
                goto oversize;
 
        if (length < copybreak) {
-               skb = alloc_skb(length + 2, GFP_ATOMIC);
+               skb = dev_alloc_skb(length + 2);
                if (!skb)
                        goto resubmit;
 
                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;
 }
 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);
 
        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);
 
        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;
 
        *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;
        if (sky2_more_work(hw))
                return 1;
-out:
+
        netif_rx_complete(dev0);
 
        sky2_read32(hw, B0_Y2_SP_LISR);
        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;
 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);
        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);
 
 
                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) {
        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)
 {
 
 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
 
                if (hw->chip_id != CHIP_ID_YUKON_FE)
                        modes |= SUPPORTED_1000baseT_Half
-                           | SUPPORTED_1000baseT_Full;
+                               | SUPPORTED_1000baseT_Full;
+               return modes;
        } else
        } 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)
 }
 
 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;
        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
                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;
                    | 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->port = PORT_FIBRE;
+       }
 
        ecmd->advertising = sky2->advertising;
        ecmd->autoneg = sky2->autoneg;
 
        ecmd->advertising = sky2->advertising;
        ecmd->autoneg = sky2->autoneg;
-       ecmd->speed = sky2->speed;
        ecmd->duplex = sky2->duplex;
        return 0;
 }
        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;
 
        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);
        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;
        }
 
                return err;
        }
 
-       init_waitqueue_head (&hw->msi_wait);
-
        sky2_write8(hw, B0_CTST, CS_ST_SW_IRQ);
        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);
 
 
        wait_event_timeout(hw->msi_wait, hw->msi_detected, HZ/10);
 
index 8a0bc55..9516c1f 100644 (file)
@@ -1317,6 +1317,14 @@ enum {
        PHY_M_FESC_SEL_CL_A     = 1<<0, /* Select Class A driver (100B-TX) */
 };
 
        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 {
 /* 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_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,
 };
 
                          GMR_FS_UN_SIZE | GMR_FS_JABBER,
 };
 
@@ -1879,7 +1887,7 @@ struct sky2_hw {
        int                  pm_cap;
        u8                   chip_id;
        u8                   chip_rev;
        int                  pm_cap;
        u8                   chip_id;
        u8                   chip_rev;
-       u8                   copper;
+       u8                   pmd_type;
        u8                   ports;
 
        struct sky2_status_le *st_le;
        u8                   ports;
 
        struct sky2_status_le *st_le;
@@ -1891,6 +1899,11 @@ struct sky2_hw {
        wait_queue_head_t    msi_wait;
 };
 
        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)
 {
 /* Register accessor for memory mapped device */
 static inline u32 sky2_read32(const struct sky2_hw *hw, unsigned reg)
 {
index 862c226..09a6b8e 100644 (file)
@@ -69,8 +69,8 @@
 
 #define DRV_MODULE_NAME                "tg3"
 #define PFX DRV_MODULE_NAME    ": "
 
 #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
 
 #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) &&
 #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) &&
                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) &&
 #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) &&
                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;
        }
 
                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.
         */
         * 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
                dev->features |= NETIF_F_TSO;
 
 #endif
index ff0faab..cd68f46 100644 (file)
 #define  CHIPREV_ID_5750_A0             0x4000
 #define  CHIPREV_ID_5750_A1             0x4001
 #define  CHIPREV_ID_5750_A3             0x4003
 #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
 #define  CHIPREV_ID_5752_A0_HW          0x5000
 #define  CHIPREV_ID_5752_A0             0x6000
 #define  CHIPREV_ID_5752_A1             0x6001
index 136a70c..56d86c7 100644 (file)
@@ -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:
  * - 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:
  * - tx_timeout:
- *     netif_device_detach + spin_unlock_wait(&dev->xmit_lock);
+ *     netif_device_detach + netif_tx_disable;
  * - set_multicast_list
  * - 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.
  * - 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_device_detach(dev);
                update_csr6(dev, 0);
                iowrite32(0, ioaddr + IntrEnable);
-               netif_stop_queue(dev);
                spin_unlock_irq(&np->lock);
 
                spin_unlock_irq(&np->lock);
 
-               spin_unlock_wait(&dev->xmit_lock);
                synchronize_irq(dev->irq);
                synchronize_irq(dev->irq);
+               netif_tx_disable(dev);
        
                np->stats.rx_missed_errors += ioread32(ioaddr + RxMissed) & 0xffff;
 
        
                np->stats.rx_missed_errors += ioread32(ioaddr + RxMissed) & 0xffff;
 
index d9258d4..389d19f 100644 (file)
@@ -340,7 +340,7 @@ enum state_values {
 #endif
 
 #if defined(NETIF_F_TSO)
 #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
 #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 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
                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);
        }
 
                                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++;
 
                first_txd->processFlags |= TYPHOON_TX_PF_TCP_SEGMENT;
                first_txd->numDesc++;
 
index ed1f837..09e05fe 100644 (file)
@@ -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 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);
 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 (ret < 0)
                goto err_iounmap;
 
+       if (velocity_get_link(dev))
+               netif_carrier_off(dev);
+
        velocity_print_info(vptr);
        pci_set_drvdata(pdev, 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;
 
                if (linked) {
                        vptr->mii_status &= ~VELOCITY_LINK_FAIL;
+                       netif_carrier_on(vptr->dev);
                } else {
                        vptr->mii_status |= VELOCITY_LINK_FAIL;
                } else {
                        vptr->mii_status |= VELOCITY_LINK_FAIL;
+                       netif_carrier_off(vptr->dev);
                }
 
                velocity_print_link_status(vptr);
                }
 
                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;
 
 
        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];
        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 (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);
                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) {
                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 = 
                        memcpy(tdinfo->buf, skb->data, skb->len);
                        tdinfo->skb_dma[0] = tdinfo->buf_dma;
                        td_ptr->tdesc0.pktsize = 
index c2d0b09..a5fcfcd 100644 (file)
@@ -1833,7 +1833,9 @@ static int __orinoco_program_rids(struct net_device *dev)
        /* Set promiscuity / multicast*/
        priv->promiscuous = 0;
        priv->mc_count = 0;
        /* 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;
 }
 
        return 0;
 }
index f7b77ce..54fe4e4 100644 (file)
@@ -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 */
        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 */
                return -ENODEV;
 
        /* Save original COR value */
index b2e8e49..a647d39 100644 (file)
@@ -6,6 +6,10 @@
  *
  * @author John Levon <levon@movementarian.org>
  *
  *
  * @author John Levon <levon@movementarian.org>
  *
+ * 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
  * 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;
 }
 
        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);
 {
        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)
 {
 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
  * 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) {
                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;
        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;
        unsigned int i;
        sync_buffer_state state = sb_buffer_start;
        unsigned long available;
+       int domain_switch = 0;
 
        down(&buffer_sem);
  
 
        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];
  
        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;
                                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_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;
 
                        } else {
                                struct mm_struct * oldmm = mm;
 
@@ -535,11 +558,16 @@ void sync_buffer(int cpu)
                                add_user_ctx_switch(new, cookie);
                        }
                } else {
                                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);
+                                       }
                                }
                        }
                }
                                }
                        }
                }
index fc4bc9b..a59878e 100644 (file)
@@ -6,6 +6,10 @@
  *
  * @author John Levon <levon@movementarian.org>
  *
  *
  * @author John Levon <levon@movementarian.org>
  *
+ * 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
  * 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;
 
 #define DEFAULT_TIMER_EXPIRE (HZ / 10)
 static int work_enabled;
 
+static int32_t current_domain = COORDINATOR_DOMAIN;
+
 void free_cpu_buffers(void)
 {
        int i;
 void free_cpu_buffers(void)
 {
        int i;
@@ -57,7 +63,7 @@ int alloc_cpu_buffers(void)
                        goto fail;
  
                b->last_task = NULL;
                        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;
                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
         */
         * 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;
 }
 
        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.
  *
  * 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
  * 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,
  */
 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;
 
 {
        struct task_struct * task;
 
@@ -180,18 +186,20 @@ static int log_sample(struct oprofile_cpu_buffer * cpu_buf, unsigned long pc,
                return 0;
        }
 
                return 0;
        }
 
-       is_kernel = !!is_kernel;
+       WARN_ON(cpu_mode > CPU_MODE_XEN);
 
        task = current;
 
        /* notice a switch from user->kernel or vice versa */
 
        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 */
        /* 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);
        }
                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);
 }
 
        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
 /*
  * This serves to avoid cpu buffer overflow, and makes sure
  * the task mortuary progresses
index 09abb80..cd94735 100644 (file)
@@ -36,7 +36,7 @@ struct oprofile_cpu_buffer {
        volatile unsigned long tail_pos;
        unsigned long buffer_size;
        struct task_struct * last_task;
        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;
        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 */
 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 */
 
 #endif /* OPROFILE_CPU_BUFFER_H */
index 0180236..0c33ee7 100644 (file)
@@ -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 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 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
 
  
 #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);
  
 /* add data to the event buffer */
 void add_event_entry(unsigned long data);
  
index b3f1cd6..76bac8d 100644 (file)
@@ -5,6 +5,10 @@
  * @remark Read the file COPYING
  *
  * @author John Levon <levon@movementarian.org>
  * @remark Read the file COPYING
  *
  * @author John Levon <levon@movementarian.org>
+ *
+ * Modified by Aravind Menon for Xen
+ * These modifications are:
+ * Copyright (C) 2005 Hewlett-Packard Co.
  */
 
 #include <linux/kernel.h>
  */
 
 #include <linux/kernel.h>
@@ -19,7 +23,7 @@
 #include "cpu_buffer.h"
 #include "buffer_sync.h"
 #include "oprofile_stats.h"
 #include "cpu_buffer.h"
 #include "buffer_sync.h"
 #include "oprofile_stats.h"
+
 struct oprofile_operations oprofile_ops;
 
 unsigned long oprofile_started;
 struct oprofile_operations oprofile_ops;
 
 unsigned long oprofile_started;
@@ -33,6 +37,34 @@ static DECLARE_MUTEX(start_sem);
  */
 static int timer = 0;
 
  */
 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;
 int oprofile_setup(void)
 {
        int err;
index 1832365..587db2b 100644 (file)
@@ -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);
 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 */
 #endif /* OPROF_H */
index a72006c..3888465 100644 (file)
@@ -5,15 +5,21 @@
  * @remark Read the file COPYING
  *
  * @author John Levon <levon@movementarian.org>
  * @remark Read the file COPYING
  *
  * @author John Levon <levon@movementarian.org>
+ *
+ * Modified by Aravind Menon for Xen
+ * These modifications are:
+ * Copyright (C) 2005 Hewlett-Packard Co.      
  */
 
 #include <linux/fs.h>
 #include <linux/oprofile.h>
  */
 
 #include <linux/fs.h>
 #include <linux/oprofile.h>
+#include <asm/uaccess.h>
+#include <linux/ctype.h>
 
 #include "event_buffer.h"
 #include "oprofile_stats.h"
 #include "oprof.h"
 
 #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 */
 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,
 };
 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);
 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);
        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);
index 4d762fc..065ea43 100644 (file)
@@ -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
        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
        help
           This allows device drivers to enable MSI (Message Signaled
           Interrupts).  Message Signaled Interrupts enable a device to
index d378478..6e3786f 100644 (file)
@@ -427,6 +427,7 @@ static void __devinit quirk_ich6_lpc_acpi(struct pci_dev *dev)
        pci_read_config_dword(dev, 0x48, &region);
        quirk_io_region(dev, region, 64, PCI_BRIDGE_RESOURCES+1, "ICH6 GPIO");
 }
        pci_read_config_dword(dev, 0x48, &region);
        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 );
 
 /*
 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_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)
 {
 
 static void __init asus_hides_smbus_lpc_ich6(struct pci_dev *dev)
 {
index 6ded527..688421d 100644 (file)
@@ -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) {
        /* 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);
        }
                        return 0;
                free_irq(*irq, NULL);
        }
index 0bab60a..38aad83 100644 (file)
@@ -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) {
        }
        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){
                               (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? */
 
        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){
        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? */
                                 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 *
                                     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 *
        }
        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 *
 }
 
 static inline struct qeth_eddp_context *
index 9e671a4..2908669 100644 (file)
@@ -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;
        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");
        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)];
 
        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 */
                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
                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){
                        card->perf_stats.large_send_cnt++;
                }
                if (nr_frags > 0){
index 24ef40c..593f298 100644 (file)
@@ -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.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));
        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));
index a262e38..81803a1 100644 (file)
@@ -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_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
 obj-$(CONFIG_SCSI_AMIGA7XX)    += amiga7xx.o   53c7xx.o
 obj-$(CONFIG_A3000_SCSI)       += a3000.o      wd33c93.o
 obj-$(CONFIG_A2091_SCSI)       += a2091.o      wd33c93.o
index b4743a9..2068b66 100644 (file)
@@ -3,8 +3,7 @@
  *
  * Copyright (C) 2004 Dmitry Yusupov
  * Copyright (C) 2004 Alex Aizman
  *
  * 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
  * maintained by open-iscsi@googlegroups.com
  *
  * This program is free software; you can redistribute it and/or modify
 #include <linux/mutex.h>
 #include <net/tcp.h>
 #include <scsi/scsi_cmnd.h>
 #include <linux/mutex.h>
 #include <net/tcp.h>
 #include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_eh.h>
+#include <scsi/scsi_request.h>
+#include <scsi/scsi_tcq.h>
 #include <scsi/scsi_host.h>
 #include <scsi/scsi.h>
 #include <scsi/scsi_transport_iscsi.h>
 
 #include "iscsi_tcp.h"
 
 #include <scsi/scsi_host.h>
 #include <scsi/scsi.h>
 #include <scsi/scsi_transport_iscsi.h>
 
 #include "iscsi_tcp.h"
 
-#define ISCSI_TCP_VERSION "1.0-595"
-
 MODULE_AUTHOR("Dmitry Yusupov <dmitry_yus@yahoo.com>, "
              "Alex Aizman <itn780@yahoo.com>");
 MODULE_DESCRIPTION("iSCSI/TCP data-path");
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Dmitry Yusupov <dmitry_yus@yahoo.com>, "
              "Alex Aizman <itn780@yahoo.com>");
 MODULE_DESCRIPTION("iSCSI/TCP data-path");
 MODULE_LICENSE("GPL");
-MODULE_VERSION(ISCSI_TCP_VERSION);
+MODULE_VERSION("0:4.445");
 /* #define DEBUG_TCP */
 /* #define DEBUG_TCP */
+/* #define DEBUG_SCSI */
 #define DEBUG_ASSERT
 
 #ifdef DEBUG_TCP
 #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
 
 #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
 #ifndef DEBUG_ASSERT
 #ifdef BUG_ON
 #undef BUG_ON
@@ -66,9 +74,22 @@ MODULE_VERSION(ISCSI_TCP_VERSION);
 #define BUG_ON(expr)
 #endif
 
 #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);
 
 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)
 {
 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)
 {
 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);
 }
 
        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
 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 &&
                /*
                 * 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 */
                        /* 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;
        } 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.
                 */
 
                 * 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);
 
                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 "
 
                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)  {
                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;
                }
                        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;
 }
 
        }
 
        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;
                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;
 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);
 
        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..)
         */
        /*
         * 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)
                return 0;
 
        if (ctask->datasn != datasn)
@@ -229,8 +344,8 @@ iscsi_data_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
 
        ctask->datasn++;
 
 
        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) {
                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_r2t_info *r2t)
 {
        struct iscsi_data *hdr;
+       struct iscsi_data_task *dtask;
        struct scsi_cmnd *sc = ctask->sc;
        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;
        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) {
        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;
 
 
        r2t->sent = 0;
 
-       iscsi_buf_init_iov(&r2t->headbuf, (char*)hdr,
+       iscsi_buf_init_virt(&r2t->headbuf, (char*)hdr,
                           sizeof(struct iscsi_hdr));
 
                           sizeof(struct iscsi_hdr));
 
+       r2t->dtask = dtask;
+
        if (sc->use_sg) {
                int i, sg_count = 0;
                struct scatterlist *sg = sc->request_buffer;
        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
                }
                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);
                            (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_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;
 
        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;
 
                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);
                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;
        }
                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;
        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);
 
 
        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++;
 
        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
 }
 
 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_hdr *hdr;
+       struct iscsi_cmd_task *ctask;
        struct iscsi_session *session = conn->session;
        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 */
 
        /* 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",
                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;
        }
                return ISCSI_ERR_DATALEN;
        }
-       tcp_conn->data_copied = 0;
+       conn->data_copied = 0;
 
        /* read AHS */
 
        /* 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 "
                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 */
                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,
        }
 
        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) +
                rdgst = *(uint32_t*)((char*)hdr + sizeof(struct iscsi_hdr) +
-                                    ahslen);
+                                    conn->in.ahslen);
                if (cdgst != rdgst) {
                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;
                }
        }
 
                        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) */
        /* 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",
 
        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
 }
 
 /**
  * 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
  * @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
  *     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)
 {
                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",
        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(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);
 
        /* 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;
 
        ctask->data_count -= size;
 
-       BUG_ON(tcp_conn->in.copy < 0);
+       BUG_ON(conn->in.copy < 0);
        BUG_ON(ctask->data_count < 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) {
                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 */
                        /* 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 */
                }
                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
        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
  *
  * 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",
        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);
 
        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);
 
        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
                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;
 {
        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
 }
 
 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);
 {
        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)
 {
 }
 
 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;
        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;
         */
        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)
                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;
        }
 
                rc = 0;
                goto done;
        }
 
-       offset = tcp_ctask->data_offset;
+       offset = ctask->data_offset;
        sg = sc->request_buffer;
 
        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;
 
                        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);
                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)
                                      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)
                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
                                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;
                                                        sg[i].offset + offset,
                                                        sg[i].length - offset);
                        }
                        offset = 0;
-                       tcp_ctask->sg_count++;
+                       ctask->sg_count++;
                }
 
                if (!ctask->data_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...
                                 */
                                /*
                                 * 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;
                }
 
                                                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 */
                        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);
                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;
        }
 
        return rc;
@@ -759,38 +995,71 @@ done:
 static int
 iscsi_data_recv(struct iscsi_conn *conn)
 {
 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_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_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
                 */
                /*
                 * 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 = -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);
        }
        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;
 {
        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;
        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.
         */
         * 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:
 
 more:
-       tcp_conn->in.copied = 0;
+       conn->in.copied = 0;
        rc = 0;
 
        if (unlikely(conn->suspend_rx)) {
        rc = 0;
 
        if (unlikely(conn->suspend_rx)) {
@@ -836,9 +1104,9 @@ more:
                return 0;
        }
 
                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;
                if (rc) {
                       if (rc == -EAGAIN)
                                goto nomore;
@@ -851,91 +1119,90 @@ more:
                /*
                 * Verify and process incoming PDU header.
                 */
                /*
                 * 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) {
                        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;
                }
        }
 
                } 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;
                uint32_t recv_digest;
-
                debug_tcp("extra data_recv offset %d copy %d\n",
                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);
                                &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,
                        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,
                        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",
 
                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) {
 
                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;
                                goto again;
+                       }
                        iscsi_conn_failure(conn, rc);
                        return 0;
                }
                        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 (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
                } 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",
        }
 
        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",
                debug_tcp("continue to process %d bytes\n",
-                      (int)len - (tcp_conn->in.offset - offset));
+                      (int)len - (conn->in.offset - offset));
                goto more;
        }
 
 nomore:
                goto more;
        }
 
 nomore:
-       processed = tcp_conn->in.offset - offset;
+       processed = conn->in.offset - offset;
        BUG_ON(processed == 0);
        return processed;
 
 again:
        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);
        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);
 
 
        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.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);
        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)
 {
 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 *);
        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);
        }
 
                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);
 
 
        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;
 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);
        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)
 {
        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;
 
        /* 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;
        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)
 {
 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;
 
        /* 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);
 }
        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)
 {
 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
 
        /*
         * 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)
         * 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
        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) {
        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;
                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;
 }
 
        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) {
        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;
                *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
 
        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)
 {
 }
 
 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)
        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) {
        if (rc) {
-               tcp_ctask->datadigest = *digest;
-               tcp_ctask->xmstate |= XMSTATE_DATA_DIGEST;
+               ctask->datadigest = *digest;
+               ctask->xmstate |= XMSTATE_DATA_DIGEST;
        } else
        } else
-               tcp_ctask->digest_count = 4;
+               ctask->digest_count = 4;
        return rc;
 }
 
        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)
 {
 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 *hdr;
+       struct iscsi_data_task *dtask;
        struct scsi_cmnd *sc = ctask->sc;
        int new_offset;
 
        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;
        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);
        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++;
 
        }
        conn->dataout_pdus_cnt++;
 
-       iscsi_buf_init_iov(&r2t->headbuf, (char*)hdr,
+       iscsi_buf_init_virt(&r2t->headbuf, (char*)hdr,
                           sizeof(struct iscsi_hdr));
 
                           sizeof(struct iscsi_hdr));
 
+       r2t->dtask = dtask;
+
        if (sc->use_sg && !iscsi_buf_left(&r2t->sendbuf)) {
        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_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);
                            (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)
 {
 }
 
 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;
 
        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));
                           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
  * @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) {
 
        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);
                BUG_ON(ctask->total_length == 0);
-
                if (sc->use_sg) {
                        struct scatterlist *sg = sc->request_buffer;
 
                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",
                        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->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));
                            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
  *
  * @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
  *             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",
 
        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)
                if (mtask->data_count)
-                       tcp_mtask->xmstate |= XMSTATE_IMM_DATA;
+                       mtask->xmstate |= XMSTATE_IMM_DATA;
                if (conn->c_stage != ISCSI_CONN_INITIAL_STAGE &&
                if (conn->c_stage != ISCSI_CONN_INITIAL_STAGE &&
-                   conn->stop_stage != STOP_CONN_RECOVER &&
+                   conn->stop_stage != STOP_CONN_RECOVER &&
                    conn->hdrdgst_en)
                    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)
                        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);
                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 {
                /* 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);
        }
 
                        }
                } 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
        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)
        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 */
        }
                return 0; /* wait for Data-In */
        }
-       tcp_ctask->xmstate |= XMSTATE_R_HDR;
-       return rc;
+       ctask->xmstate |= XMSTATE_R_HDR;
+       return -EAGAIN;
 }
 
 static inline int
 }
 
 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)
        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)
 {
 }
 
 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",
                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)
 {
 }
 
 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);
        BUG_ON(!ctask->imm_count);
-       tcp_ctask->xmstate &= ~XMSTATE_IMM_DATA;
+       ctask->xmstate &= ~XMSTATE_IMM_DATA;
 
        if (conn->datadgst_en) {
 
        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 (;;) {
        }
 
        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) {
                        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",
                                debug_tcp("tx imm sendpage fail 0x%x\n",
-                                         tcp_ctask->datadigest);
+                                         ctask->datadigest);
                        }
                        }
-                       return rc;
+                       return -EAGAIN;
                }
                if (conn->datadgst_en)
                }
                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;
 
                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",
                        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;
        }
 
        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)
 {
 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;
        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);
                iscsi_unsolicit_data_init(conn, ctask);
-               dtask = tcp_ctask->dtask;
+               BUG_ON(!ctask->dtask);
+               dtask = ctask->dtask;
                if (conn->hdrdgst_en)
                if (conn->hdrdgst_en)
-                       iscsi_hdr_digest(conn, &tcp_ctask->headbuf,
+                       iscsi_hdr_digest(conn, &ctask->headbuf,
                                        (u8*)dtask->hdrext);
                                        (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",
        }
 
        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)
 {
        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);
 
        BUG_ON(!ctask->data_count);
-       tcp_ctask->xmstate &= ~XMSTATE_UNS_DATA;
+       ctask->xmstate &= ~XMSTATE_UNS_DATA;
 
        if (conn->datadgst_en) {
 
        if (conn->datadgst_en) {
-               iscsi_data_digest_init(tcp_conn, ctask);
+               iscsi_data_digest_init(conn, ctask);
                dtask->digest = 0;
        }
 
        for (;;) {
                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) {
                        /* 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);
                        }
                                                (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
                 */
 
                /*
                 * 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;
 
                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);
 
        }
        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) {
         */
        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->digestbuf,
-                                                   &dtask->digest, 1);
-                       if (rc) {
+                                                   &dtask->digest, 1)) {
                                debug_tcp("send uns digest 0x%x fail\n",
                                          dtask->digest);
                                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);
                }
                        }
                        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;
        }
 
                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->digestbuf,
-                                           &dtask->digest, 1);
-               if (rc) {
+                                           &dtask->digest, 1)) {
                        debug_tcp("send last uns digest 0x%x fail\n",
                                   dtask->digest);
                        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);
        }
                }
                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;
 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) {
 
        if (conn->datadgst_en) {
-               iscsi_data_digest_init(tcp_conn, ctask);
+               iscsi_data_digest_init(conn, ctask);
                dtask->digest = 0;
        }
 solicit_again:
                dtask->digest = 0;
        }
 solicit_again:
@@ -1641,27 +1930,25 @@ solicit_again:
        if (!r2t->data_count)
                goto data_out_done;
 
        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) {
                /* 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);
                }
                                          (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)
        }
 
        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)) {
 
        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;
                }
                        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) {
        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->digestbuf,
-                                                   &dtask->digest, 1);
-                       if (rc) {
+                                                   &dtask->digest, 1)) {
                                debug_tcp("send r2t data digest 0x%x"
                                          "fail\n", dtask->digest);
                                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);
                        }
                        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;
        }
 
                return 1;
        }
 
@@ -1698,27 +1984,26 @@ data_out_done:
         * Done with this R2T. Check if there are more
         * outstanding R2Ts ready to be processed.
         */
         * 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) {
        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);
                        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);
        }
 
                }
                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);
        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);
        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;
        }
 
                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)
 {
 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) {
        }
 
        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) {
                /* 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"
                                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",
                        }
                        debug_tcp("done with padding, digest 0x%x\n",
-                                 tcp_ctask->datadigest);
+                                 ctask->datadigest);
                } else {
                } else {
-                       rc = iscsi_digest_final_send(conn, ctask,
+                       if (iscsi_digest_final_send(conn, ctask,
                                                    &dtask->digestbuf,
                                                    &dtask->digestbuf,
-                                                   &dtask->digest, 1);
-                       if (rc) {
+                                                   &dtask->digest, 1)) {
                                debug_tcp("send padding digest 0x%x"
                                          "fail\n", dtask->digest);
                                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);
                        }
                        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
 }
 
 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",
        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
 
        /*
         * 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 (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 */
                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;
        }
 
                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;
        }
 
                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);
                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;
        }
 
 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;
                rc = handle_xmstate_uns_data(conn, ctask);
                if (rc == 1)
                        goto unsolicit_head_again;
@@ -1830,24 +2108,23 @@ unsolicit_head_again:
                goto done;
        }
 
                goto done;
        }
 
-       if (tcp_ctask->xmstate & XMSTATE_SOL_HDR) {
+       if (ctask->xmstate & XMSTATE_SOL_HDR) {
                struct iscsi_r2t_info *r2t;
 
                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:
                                    sizeof(void*));
 solicit_head_again:
-               r2t = tcp_ctask->r2t;
+               r2t = ctask->r2t;
                if (conn->hdrdgst_en)
                        iscsi_hdr_digest(conn, &r2t->headbuf,
                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",
                }
 
                debug_scsi("sol dout [dsn %d itt 0x%x dlen %d sent %d]\n",
@@ -1855,7 +2132,7 @@ solicit_head_again:
                        r2t->sent);
        }
 
                        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;
                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.
         */
         * 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;
 }
 
                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 *
 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_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;
        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 */
        /* 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 */
 
        /* 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
        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;
 
                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:
        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
        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_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 */
        }
 
        /* 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
        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
 }
 
 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 */
        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;
        }
 
        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;
 }
 
 
        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
 }
 
 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;
        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);
        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);
        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
 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
 }
 
 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];
         */
        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
 
                /*
                 * pre-allocated x4 as much r2ts to handle race when
@@ -2083,32 +3182,42 @@ iscsi_r2tpool_alloc(struct iscsi_session *session)
                 */
 
                /* R2T pool */
                 */
 
                /* 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 */
                        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);
                      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;
                }
                        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++) {
        }
 
        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;
 }
        }
        return -ENOMEM;
 }
@@ -2119,13 +3228,127 @@ iscsi_r2tpool_free(struct iscsi_session *session)
        int i;
 
        for (i = 0; i < session->cmds_max; i++) {
        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
 }
 
 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_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: {
 
        switch(param) {
        case ISCSI_PARAM_MAX_RECV_DLENGTH: {
-               char *saveptr = tcp_conn->data;
+               char *saveptr = conn->data;
                gfp_t flags = GFP_KERNEL;
 
                gfp_t flags = GFP_KERNEL;
 
-               if (tcp_conn->data_size >= value) {
+               if (conn->data_size >= value) {
                        conn->max_recv_dlength = value;
                        break;
                }
                        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)
                spin_unlock_bh(&session->lock);
 
                if (value <= PAGE_SIZE)
-                       tcp_conn->data = kmalloc(value, flags);
+                       conn->data = kmalloc(value, flags);
                else
                else
-                       tcp_conn->data = (void*)__get_free_pages(flags,
+                       conn->data = (void*)__get_free_pages(flags,
                                                             get_order(value));
                                                             get_order(value));
-               if (tcp_conn->data == NULL) {
-                       tcp_conn->data = saveptr;
+               if (conn->data == NULL) {
+                       conn->data = saveptr;
                        return -ENOMEM;
                }
                        return -ENOMEM;
                }
-               if (tcp_conn->data_size <= PAGE_SIZE)
+               if (conn->data_size <= PAGE_SIZE)
                        kfree(saveptr);
                else
                        free_pages((unsigned long)saveptr,
                        kfree(saveptr);
                else
                        free_pages((unsigned long)saveptr,
-                                  get_order(tcp_conn->data_size));
+                                  get_order(conn->data_size));
                conn->max_recv_dlength = value;
                conn->max_recv_dlength = value;
-               tcp_conn->data_size = value;
+               conn->data_size = value;
                }
                break;
        case ISCSI_PARAM_MAX_XMIT_DLENGTH:
                }
                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;
                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) {
                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;
                                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 {
                                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) {
                }
                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);
                                    crypto_alloc_tfm("crc32c", 0);
-                       if (!tcp_conn->data_tx_tfm)
+                       if (!conn->data_tx_tfm)
                                return -ENOMEM;
                                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);
                                    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 {
                                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;
                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;
                BUG_ON(value);
                session->ofmarker_en = value;
                break;
-       case ISCSI_PARAM_EXP_STATSN:
-               conn->exp_statsn = value;
-               break;
        default:
                break;
        }
        default:
                break;
        }
@@ -2308,7 +3535,7 @@ iscsi_session_get_param(struct iscsi_cls_session *cls_session,
                *value = session->ofmarker_en;
                break;
        default:
                *value = session->ofmarker_en;
                break;
        default:
-               return -EINVAL;
+               return ISCSI_ERR_PARAM_NOT_FOUND;
        }
 
        return 0;
        }
 
        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;
                     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:
 
        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_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:
        default:
-               return -EINVAL;
+               return ISCSI_ERR_PARAM_NOT_FOUND;
        }
 
        return 0;
 }
 
        }
 
        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;
 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;
 
        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->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");
        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;
 }
 
        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,
 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,
        .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,
        .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,
        .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,
        .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,
        .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) {
 };
 
 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;
 
                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))
        if (!iscsi_register_transport(&iscsi_tcp_transport))
-               return -ENODEV;
+               kmem_cache_destroy(taskcache);
 
        return 0;
 }
 
        return 0;
 }
@@ -2554,6 +3653,7 @@ static void __exit
 iscsi_tcp_exit(void)
 {
        iscsi_unregister_transport(&iscsi_tcp_transport);
 iscsi_tcp_exit(void)
 {
        iscsi_unregister_transport(&iscsi_tcp_transport);
+       kmem_cache_destroy(taskcache);
 }
 
 module_init(iscsi_tcp_init);
 }
 
 module_init(iscsi_tcp_init);
index 8083028..ba26741 100644 (file)
@@ -2,8 +2,7 @@
  * iSCSI Initiator TCP Transport
  * Copyright (C) 2004 Dmitry Yusupov
  * Copyright (C) 2004 Alex Aizman
  * 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
  * maintained by open-iscsi@googlegroups.com
  *
  * This program is free software; you can redistribute it and/or modify
 #ifndef ISCSI_TCP_H
 #define ISCSI_TCP_H
 
 #ifndef ISCSI_TCP_H
 #define ISCSI_TCP_H
 
-#include <scsi/libiscsi.h>
+/* 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
 
 /* Socket's Receive state machine */
 #define IN_PROGRESS_WAIT_HEADER                0x0
 #define IN_PROGRESS_DATA_RECV          0x2
 #define IN_PROGRESS_DDIGEST_RECV       0x3
 
 #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
 /* xmit state machine */
 #define        XMSTATE_IDLE                    0x0
 #define        XMSTATE_R_HDR                   0x1
 #define        XMSTATE_W_PAD                   0x200
 #define XMSTATE_DATA_DIGEST            0x400
 
 #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_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_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
 
 #define ISCSI_TCP_MAX_CMD_LEN          16
 
-struct socket;
+#define ITT_MASK                       (0xfff)
+#define CID_SHIFT                      12
+#define CID_MASK                       (0xffff<<CID_SHIFT)
+#define AGE_SHIFT                      28
+#define AGE_MASK                       (0xf<<AGE_SHIFT)
+
+struct iscsi_queue {
+       struct kfifo            *queue;         /* FIFO Queue */
+       void                    **pool;         /* Pool of elements */
+       int                     max;            /* Max number of elements */
+};
+
+struct iscsi_session;
+struct iscsi_cmd_task;
+struct iscsi_mgmt_task;
 
 /* Socket connection recieve helper */
 struct iscsi_tcp_recv {
 
 /* Socket connection recieve helper */
 struct iscsi_tcp_recv {
@@ -66,32 +104,48 @@ struct iscsi_tcp_recv {
        struct iscsi_cmd_task   *ctask;         /* current cmd in progress */
 
        /* copied and flipped values */
        struct iscsi_cmd_task   *ctask;         /* current cmd in progress */
 
        /* copied and flipped values */
+       int                     opcode;
+       int                     flags;
+       int                     cmd_status;
+       int                     ahslen;
        int                     datalen;
        int                     datalen;
+       uint32_t                itt;
        int                     datadgst;
        int                     datadgst;
-       char                    zero_copy_hdr;
 };
 
 };
 
-struct iscsi_tcp_conn {
-       struct iscsi_conn       *iscsi_conn;
-       struct socket           *sock;
+struct iscsi_cls_conn;
+
+struct iscsi_conn {
+       struct iscsi_cls_conn   *cls_conn;      /* ptr to class connection */
        struct iscsi_hdr        hdr;            /* header placeholder */
        char                    hdrext[4*sizeof(__u16) +
                                    sizeof(__u32)];
        int                     data_copied;
        char                    *data;          /* data placeholder */
        struct iscsi_hdr        hdr;            /* header placeholder */
        char                    hdrext[4*sizeof(__u16) +
                                    sizeof(__u32)];
        int                     data_copied;
        char                    *data;          /* data placeholder */
+       struct socket           *sock;          /* TCP socket */
        int                     data_size;      /* actual recv_dlength */
        int                     stop_stage;     /* conn_stop() flag: *
                                                 * stop to recover,  *
                                                 * stop to terminate */
        /* iSCSI connection-wide sequencing */
        int                     data_size;      /* actual recv_dlength */
        int                     stop_stage;     /* conn_stop() flag: *
                                                 * stop to recover,  *
                                                 * stop to terminate */
        /* iSCSI connection-wide sequencing */
+       uint32_t                exp_statsn;
        int                     hdr_size;       /* PDU header size */
        int                     hdr_size;       /* PDU header size */
+       unsigned long           suspend_rx;     /* suspend Rx */
 
        struct crypto_tfm       *rx_tfm;        /* CRC32C (Rx) */
        struct crypto_tfm       *data_rx_tfm;   /* CRC32C (Rx) for data */
 
        /* control data */
 
        struct crypto_tfm       *rx_tfm;        /* CRC32C (Rx) */
        struct crypto_tfm       *data_rx_tfm;   /* CRC32C (Rx) for data */
 
        /* control data */
+       int                     senselen;       /* scsi sense length */
+       int                     id;             /* CID */
        struct iscsi_tcp_recv   in;             /* TCP receive context */
        struct iscsi_tcp_recv   in;             /* TCP receive context */
+       struct iscsi_session    *session;       /* parent session */
+       struct list_head        item;           /* maintains list of conns */
        int                     in_progress;    /* connection state machine */
        int                     in_progress;    /* connection state machine */
+       int                     c_stage;        /* connection state */
+       struct iscsi_mgmt_task  *login_mtask;   /* mtask used for login/text */
+       struct iscsi_mgmt_task  *mtask;         /* xmit mtask in progress */
+       struct iscsi_cmd_task   *ctask;         /* xmit ctask in progress */
 
        /* old values for socket callbacks */
        void                    (*old_data_ready)(struct sock *, int);
 
        /* old values for socket callbacks */
        void                    (*old_data_ready)(struct sock *, int);
@@ -101,14 +155,93 @@ struct iscsi_tcp_conn {
        /* xmit */
        struct crypto_tfm       *tx_tfm;        /* CRC32C (Tx) */
        struct crypto_tfm       *data_tx_tfm;   /* CRC32C (Tx) for data */
        /* xmit */
        struct crypto_tfm       *tx_tfm;        /* CRC32C (Tx) */
        struct crypto_tfm       *data_tx_tfm;   /* CRC32C (Tx) for data */
+       struct kfifo            *writequeue;    /* write cmds for Data-Outs */
+       struct kfifo            *immqueue;      /* immediate xmit queue */
+       struct kfifo            *mgmtqueue;     /* mgmt (control) xmit queue */
+       struct kfifo            *xmitqueue;     /* data-path cmd queue */
+       struct work_struct      xmitwork;       /* per-conn. xmit workqueue */
+       struct mutex            xmitmutex;      /* serializes connection xmit,
+                                                * access to kfifos:      *
+                                                * xmitqueue, writequeue, *
+                                                * immqueue, mgmtqueue    */
+       unsigned long           suspend_tx;     /* suspend Tx */
+
+       /* abort */
+       wait_queue_head_t       ehwait;         /* used in eh_abort()     */
+       struct iscsi_tm         tmhdr;
+       struct timer_list       tmabort_timer;  /* abort timer */
+       int                     tmabort_state;  /* see TMABORT_INITIAL, etc.*/
+
+       /* negotiated params */
+       int                     max_recv_dlength;
+       int                     max_xmit_dlength;
+       int                     hdrdgst_en;
+       int                     datadgst_en;
 
 
-       /* MIB custom statistics */
+       /* MIB-statistics */
+       uint64_t                txdata_octets;
+       uint64_t                rxdata_octets;
+       uint32_t                scsicmd_pdus_cnt;
+       uint32_t                dataout_pdus_cnt;
+       uint32_t                scsirsp_pdus_cnt;
+       uint32_t                datain_pdus_cnt;
+       uint32_t                r2t_pdus_cnt;
+       uint32_t                tmfcmd_pdus_cnt;
+       int32_t                 tmfrsp_pdus_cnt;
+
+       /* custom statistics */
        uint32_t                sendpage_failures_cnt;
        uint32_t                discontiguous_hdr_cnt;
        uint32_t                sendpage_failures_cnt;
        uint32_t                discontiguous_hdr_cnt;
+       uint32_t                eh_abort_cnt;
 
        ssize_t (*sendpage)(struct socket *, struct page *, int, size_t, int);
 };
 
 
        ssize_t (*sendpage)(struct socket *, struct page *, int, size_t, int);
 };
 
+struct iscsi_session {
+       /* iSCSI session-wide sequencing */
+       uint32_t                cmdsn;
+       uint32_t                exp_cmdsn;
+       uint32_t                max_cmdsn;
+
+       /* configuration */
+       int                     initial_r2t_en;
+       int                     max_r2t;
+       int                     imm_data_en;
+       int                     first_burst;
+       int                     max_burst;
+       int                     time2wait;
+       int                     time2retain;
+       int                     pdu_inorder_en;
+       int                     dataseq_inorder_en;
+       int                     erl;
+       int                     ifmarker_en;
+       int                     ofmarker_en;
+
+       /* control data */
+       struct Scsi_Host        *host;
+       int                     id;
+       struct iscsi_conn       *leadconn;      /* leading connection */
+       spinlock_t              lock;           /* protects session state, *
+                                                * sequence numbers,       *
+                                                * session resources:      *
+                                                * - cmdpool,              *
+                                                * - mgmtpool,             *
+                                                * - r2tpool               */
+       int                     state;          /* session state           */
+       struct list_head        item;
+       void                    *auth_client;
+       int                     conn_cnt;
+       int                     age;            /* counts session re-opens */
+
+       struct list_head        connections;    /* list of connections */
+       int                     cmds_max;       /* size of cmds array */
+       struct iscsi_cmd_task   **cmds;         /* Original Cmds arr */
+       struct iscsi_queue      cmdpool;        /* PDU's pool */
+       int                     mgmtpool_max;   /* size of mgmt array */
+       struct iscsi_mgmt_task  **mgmt_cmds;    /* Original mgmt arr */
+       struct iscsi_queue      mgmtpool;       /* Mgmt PDU's pool */
+};
+
 struct iscsi_buf {
        struct scatterlist      sg;
        unsigned int            sent;
 struct iscsi_buf {
        struct scatterlist      sg;
        unsigned int            sent;
@@ -118,17 +251,22 @@ struct iscsi_buf {
 struct iscsi_data_task {
        struct iscsi_data       hdr;                    /* PDU */
        char                    hdrext[sizeof(__u32)];  /* Header-Digest */
 struct iscsi_data_task {
        struct iscsi_data       hdr;                    /* PDU */
        char                    hdrext[sizeof(__u32)];  /* Header-Digest */
+       struct list_head        item;                   /* data queue item */
        struct iscsi_buf        digestbuf;              /* digest buffer */
        uint32_t                digest;                 /* data digest */
 };
        struct iscsi_buf        digestbuf;              /* digest buffer */
        uint32_t                digest;                 /* data digest */
 };
+#define ISCSI_DTASK_DEFAULT_MAX        ISCSI_SG_TABLESIZE * PAGE_SIZE / 512
 
 
-struct iscsi_tcp_mgmt_task {
-       struct iscsi_hdr        hdr;
-       char                    hdrext[sizeof(__u32)]; /* Header-Digest */
+struct iscsi_mgmt_task {
+       struct iscsi_hdr        hdr;            /* mgmt. PDU */
+       char                    hdrext[sizeof(__u32)];  /* Header-Digest */
+       char                    *data;          /* mgmt payload */
        int                     xmstate;        /* mgmt xmit progress */
        int                     xmstate;        /* mgmt xmit progress */
+       int                     data_count;     /* counts data to be sent */
        struct iscsi_buf        headbuf;        /* header buffer */
        struct iscsi_buf        sendbuf;        /* in progress buffer */
        int                     sent;
        struct iscsi_buf        headbuf;        /* header buffer */
        struct iscsi_buf        sendbuf;        /* in progress buffer */
        int                     sent;
+       uint32_t                itt;            /* this ITT */
 };
 
 struct iscsi_r2t_info {
 };
 
 struct iscsi_r2t_info {
@@ -142,36 +280,48 @@ struct iscsi_r2t_info {
        int                     data_count;     /* DATA-Out payload progress */
        struct scatterlist      *sg;            /* per-R2T SG list */
        int                     solicit_datasn;
        int                     data_count;     /* DATA-Out payload progress */
        struct scatterlist      *sg;            /* per-R2T SG list */
        int                     solicit_datasn;
-       struct iscsi_data_task   dtask;        /* which data task */
+       struct iscsi_data_task   *dtask;        /* which data task */
 };
 
 };
 
-struct iscsi_tcp_cmd_task {
-       struct iscsi_cmd        hdr;
+struct iscsi_cmd_task {
+       struct iscsi_cmd        hdr;                    /* iSCSI PDU header */
        char                    hdrext[4*sizeof(__u16)+ /* AHS */
                                    sizeof(__u32)];     /* HeaderDigest */
        char                    pad[ISCSI_PAD_LEN];
        char                    hdrext[4*sizeof(__u16)+ /* AHS */
                                    sizeof(__u32)];     /* HeaderDigest */
        char                    pad[ISCSI_PAD_LEN];
-       int                     pad_count;              /* padded bytes */
+       int                     itt;                    /* this ITT */
+       int                     datasn;                 /* DataSN */
        struct iscsi_buf        headbuf;                /* header buf (xmit) */
        struct iscsi_buf        sendbuf;                /* in progress buffer*/
        struct iscsi_buf        headbuf;                /* header buf (xmit) */
        struct iscsi_buf        sendbuf;                /* in progress buffer*/
-       int                     xmstate;                /* xmit xtate machine */
        int                     sent;
        struct scatterlist      *sg;                    /* per-cmd SG list  */
        struct scatterlist      *bad_sg;                /* assert statement */
        int                     sg_count;               /* SG's to process  */
        int                     sent;
        struct scatterlist      *sg;                    /* per-cmd SG list  */
        struct scatterlist      *bad_sg;                /* assert statement */
        int                     sg_count;               /* SG's to process  */
+       uint32_t                unsol_datasn;
        uint32_t                exp_r2tsn;
        uint32_t                exp_r2tsn;
+       int                     xmstate;                /* xmit xtate machine */
+       int                     imm_count;              /* imm-data (bytes)   */
+       int                     unsol_count;            /* unsolicited (bytes)*/
        int                     r2t_data_count;         /* R2T Data-Out bytes */
        int                     r2t_data_count;         /* R2T Data-Out bytes */
+       int                     data_count;             /* remaining Data-Out */
+       int                     pad_count;              /* padded bytes */
+       struct scsi_cmnd        *sc;                    /* associated SCSI cmd*/
+       int                     total_length;
        int                     data_offset;
        int                     data_offset;
+       struct iscsi_conn       *conn;                  /* used connection    */
+       struct iscsi_mgmt_task  *mtask;                 /* tmf mtask in progr */
+
        struct iscsi_r2t_info   *r2t;                   /* in progress R2T    */
        struct iscsi_queue      r2tpool;
        struct kfifo            *r2tqueue;
        struct iscsi_r2t_info   **r2ts;
        struct iscsi_r2t_info   *r2t;                   /* in progress R2T    */
        struct iscsi_queue      r2tpool;
        struct kfifo            *r2tqueue;
        struct iscsi_r2t_info   **r2ts;
+       struct list_head        dataqueue;              /* Data-Out dataqueue */
+       mempool_t               *datapool;
        uint32_t                datadigest;             /* for recover digest */
        int                     digest_count;
        uint32_t                immdigest;              /* for imm data */
        struct iscsi_buf        immbuf;                 /* for imm data digest */
        uint32_t                datadigest;             /* for recover digest */
        int                     digest_count;
        uint32_t                immdigest;              /* for imm data */
        struct iscsi_buf        immbuf;                 /* for imm data digest */
-       struct iscsi_data_task  *dtask;         /* data task in progress*/
-       struct iscsi_data_task  unsol_dtask;    /* unsol data task */
-       int                     digest_offset;  /* for partial buff digest */
+       struct iscsi_data_task   *dtask;                /* data task in progress*/
+       int                     digest_offset;          /* for partial buff digest */
 };
 
 #endif /* ISCSI_H */
 };
 
 #endif /* ISCSI_H */
index a89aff6..46ababf 100644 (file)
@@ -110,11 +110,8 @@ static int ioctl_internal_command(struct scsi_device *sdev, char *cmd,
                                       sshdr.asc, sshdr.ascq);
                        break;
                case NOT_READY: /* This happens if there is no disc in drive */
                                       sshdr.asc, sshdr.ascq);
                        break;
                case NOT_READY: /* This happens if there is no disc in drive */
-                       if (sdev->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;
                                break;
-                       }
                case UNIT_ATTENTION:
                        if (sdev->removable) {
                                sdev->changed = 1;
                case UNIT_ATTENTION:
                        if (sdev->removable) {
                                sdev->changed = 1;
index 5569fdc..2730d50 100644 (file)
 #include <scsi/scsi_transport_iscsi.h>
 #include <scsi/iscsi_if.h>
 
 #include <scsi/scsi_transport_iscsi.h>
 #include <scsi/iscsi_if.h>
 
-#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 {
 
 struct iscsi_internal {
-       int daemon_pid;
        struct scsi_transport_template t;
        struct iscsi_transport *iscsi_transport;
        struct list_head list;
        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];
 };
 
        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
 /*
  * 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,
 };
 
        .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,
 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;
                               NULL);
 
 static struct sock *nls;
+static int daemon_pid;
 static DEFINE_MUTEX(rx_queue_mutex);
 
 struct mempool_zone {
 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 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) {
 {
        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;
                }
                        spin_unlock_irqrestore(&sesslock, flags);
                        return sess;
                }
@@ -202,17 +181,14 @@ static struct iscsi_cls_session *iscsi_session_lookup(uint32_t sid)
        return NULL;
 }
 
        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) {
 {
        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;
                }
                        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);
 
        shost = iscsi_session_to_shost(session);
        scsi_host_put(shost);
-       kfree(session->targetname);
        kfree(session);
        module_put(transport->owner);
 }
        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;
 }
 
        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
  *
 /**
  * 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 *
  **/
 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;
 
        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;
        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);
 
        /* 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);
        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);
 
        }
        transport_register_device(&session->dev);
 
-       mutex_lock(&ihost->mutex);
-       list_add(&session->host_list, &ihost->sessions);
-       mutex_unlock(&ihost->mutex);
-
        return session;
 
 free_session:
        return session;
 
 free_session:
@@ -366,16 +272,6 @@ EXPORT_SYMBOL_GPL(iscsi_create_session);
  **/
 int iscsi_destroy_session(struct iscsi_cls_session *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;
        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;
 
        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);
 }
        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.
  * 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 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;
 
        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;
 
        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;
 
        /* 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",
        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);
        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);
 
 
 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
  */
 /*
  * iscsi interface functions
  */
@@ -572,13 +560,13 @@ mempool_zone_get_skb(struct mempool_zone *zone)
 }
 
 static int
 }
 
 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);
 {
        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);
        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);
        }
 
        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);
 
        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 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);
 
        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);
        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;
        }
 
                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 = 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);
 
        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);
 
 }
 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 nlmsghdr *nlh;
        struct sk_buff  *skb;
        struct iscsi_uevent *ev;
-       struct iscsi_internal *priv;
        int len = NLMSG_SPACE(sizeof(*ev));
 
        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);
        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;
        }
 
                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 = 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);
 
        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);
        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
 }
 
 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_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;
 
        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;
 
        if (!conn)
                return -EEXIST;
 
@@ -735,7 +705,7 @@ iscsi_if_get_stats(struct iscsi_transport *transport, struct nlmsghdr *nlh)
                        return -ENOMEM;
                }
 
                        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));
                                      (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->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));
                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;
 
                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;
        } 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;
 {
        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,
                                            ev->u.c_session.initial_cmdsn,
-                                           &hostno);
+                                           &sid);
        if (!session)
                return -ENOMEM;
 
        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;
 }
 
        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;
 
        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;
                return -EINVAL;
-       }
 
        conn = transport->create_conn(session, ev->u.c_conn.cid);
 
        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;
                return -ENOMEM;
-       }
 
        conn->z_pdu = mempool_zone_init(Z_MAX_PDU,
                        NLMSG_SPACE(sizeof(struct iscsi_uevent) +
 
        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;
        }
 
                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);
 
        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;
 
        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);
        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;
 }
 
        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)
 {
 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;
        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)
 
        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;
 
        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:
        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);
                        transport->destroy_session(session);
-               else
+               else
                        err = -EINVAL;
                break;
        case ISCSI_UEVENT_CREATE_CONN:
                        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:
                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,
 
                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:
                                        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:
                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;
                if (conn)
                        ev->r.retcode = transport->start_conn(conn);
                else
                        err = -EINVAL;
+
                break;
        case ISCSI_UEVENT_STOP_CONN:
                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:
                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)),
                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_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;
        default:
                err = -EINVAL;
                break;
@@ -1074,11 +923,9 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
        return err;
 }
 
        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)
 {
 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;
                }
                        skb_pull(skb, skb->len);
                        goto free_skb;
                }
+               daemon_pid = NETLINK_CREDS(skb)->pid;
 
                while (skb->len >= NLMSG_SPACE(0)) {
                        int err;
 
                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_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
  */
 /*
  * 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)                         \
 
 #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");
 
 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(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)
 
 #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)                      \
 
 #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");
 
 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(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++;                                                \
                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++;                                                \
                count++;                                                \
-       }                                                               \
-} while (0)
+       }
 
 static int iscsi_session_match(struct attribute_container *cont,
                           struct device *dev)
 
 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;
 }
 
        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)
 {
 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;
                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);
 
        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;
 
        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];
 
        /* 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);
 
        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;
 
        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);
 
        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;
 
        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->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);
 
        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;
 
        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)
        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)
 
        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);
        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;
 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);
        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);
 }
 
        class_unregister(&iscsi_transport_class);
 }
 
index fbb53ad..9685977 100644 (file)
@@ -7,6 +7,9 @@
  *
  *  Copyright (C) 2001 Russell King.
  *
  *
  *  Copyright (C) 2001 Russell King.
  *
+ *  2005/09/16: Enabled higher baud rates for 16C95x.
+ *             (Mathias Adam <a2@adamis.de>)
+ *
  * 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
  * 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;
        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);
 
        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;
        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:
 
        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.
         */
        /*
         * 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);
 
        /*
        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);
 
         */
        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.
         */
        /*
         * Update the per-port timeout.
         */
@@ -2243,10 +2268,14 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count)
 
        touch_nmi_watchdog();
 
 
        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
        } else
-               spin_lock_irqsave(&up->port.lock, flags);
+               spin_lock(&up->port.lock);
 
        /*
         *      First save the IER then disable the interrupts
 
        /*
         *      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)
        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)
 }
 
 static int serial8250_console_setup(struct console *co, char *options)
index 7d22dc0..d271617 100644 (file)
@@ -11,6 +11,7 @@ menu "Serial drivers"
 config SERIAL_8250
        tristate "8250/16550 and compatible serial support"
        depends on (BROKEN || !SPARC)
 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
        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
        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
        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
index 7abe532..17839e7 100644 (file)
@@ -1968,16 +1968,16 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *port)
                struct termios termios;
 
                /*
                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);
 
                port->ops->set_termios(port, &termios, NULL);
                console_start(port->cons);
index a06d84c..5f44354 100644 (file)
@@ -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) {
                 * 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;
 
                                        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
                        /*
                         * 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.
                         */
                         *
                         * 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;
                                urbp->short_transfer = 1;
                                urbp->qh->initial_toggle =
                                                uhci_toggle(td_token(td)) ^ 1;
index 986d762..ad9ddec 100644 (file)
@@ -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 */
 
        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 */
 };
 
 /* Used for TIOCMIWAIT */
@@ -626,6 +630,9 @@ static struct usb_serial_driver ftdi_sio_device = {
 #define HIGH 1
 #define LOW 0
 
 #define HIGH 1
 #define LOW 0
 
+/* number of outstanding urbs to prevent userspace DoS from happening */
+#define URB_UPPER_LIMIT        42
+
 /*
  * ***************************************************************************
  * Utlity functions
 /*
  * ***************************************************************************
  * 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->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 */
         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;
        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);
 
 
        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;
        }
                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);
        
        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);
                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
        }
 
        /* 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)
 {
 
 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 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);
 
        /* 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;
        }
 
                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 )
 {
        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);
 
        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 */
 } /* 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);
 
        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 */
 
 
 } /* ftdi_chars_in_buffer */
 
 
index 2de6528..a1a8302 100644 (file)
@@ -113,6 +113,12 @@ UNUSUAL_DEV(  0x0411, 0x001c, 0x0113, 0x0113,
                US_SC_DEVICE, US_PR_DEVICE, NULL,
                US_FL_FIX_INQUIRY ),
 
                US_SC_DEVICE, US_PR_DEVICE, NULL,
                US_FL_FIX_INQUIRY ),
 
+/* Reported by Orgad Shaneh <orgads@gmail.com> */
+UNUSUAL_DEV(  0x0419, 0xaace, 0x0100, 0x0100,
+               "Samsung", "MP3 Player",
+               US_SC_DEVICE, US_PR_DEVICE, NULL,
+               US_FL_IGNORE_RESIDUE),
+
 /* Reported by Christian Leber <christian@leber.de> */
 UNUSUAL_DEV(  0x0419, 0xaaf5, 0x0100, 0x0100,
                "TrekStor",
 /* Reported by Christian Leber <christian@leber.de> */
 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 ),
 
                US_SC_DEVICE, US_PR_DEVICE, NULL,
                US_FL_IGNORE_RESIDUE ),
 
-/* Reported by Pete Zaitcev <zaitcev@redhat.com>, 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 <olh@suse.de> from novell bug #105878 */
 UNUSUAL_DEV(  0x0424, 0x0fdc, 0x0210, 0x0210,
                "SMSC",
 /* Reported by Olaf Hering <olh@suse.de> from novell bug #105878 */
 UNUSUAL_DEV(  0x0424, 0x0fdc, 0x0210, 0x0210,
                "SMSC",
index dd10863..0142fe8 100644 (file)
@@ -593,6 +593,15 @@ static int get_transport(struct us_data *us)
                break;
 #endif
 
                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;
        }
        default:
                return -EIO;
        }
@@ -648,15 +657,6 @@ static int get_protocol(struct us_data *us)
                break;
 #endif
 
                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;
        }
        default:
                return -EIO;
        }
index 4587087..2fd9ab7 100644 (file)
@@ -513,7 +513,7 @@ config FB_HGA_ACCEL
 
 config VIDEO_SELECT
        bool
 
 config VIDEO_SELECT
        bool
-       depends on (FB = y) && X86
+       depends on (FB = y) && X86 && !XEN
        default y
 
 config FB_SGIVW
        default y
 
 config FB_SGIVW
index 0a2ed2f..2ade752 100644 (file)
@@ -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;
        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;
 
        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);
                allocsize = dsize + sizeof(struct fb_image);
 
                src = kmalloc(allocsize, GFP_ATOMIC);
-               if (!src)
+               if (!src) {
+                       allocsize = 0;
                        return -ENOMEM;
                        return -ENOMEM;
+               }
        }
 
        image = (struct fb_image *) (src + dsize);
        }
 
        image = (struct fb_image *) (src + dsize);
index 7bb4798..79eddee 100644 (file)
@@ -1,13 +1,17 @@
-
-
+obj-y  += core/
 obj-y  += console/
 obj-y  += evtchn/
 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_BACKEND)       += blkback/
+obj-$(CONFIG_XEN_BLKDEV_TAP)           += blktap/
 obj-$(CONFIG_XEN_NETDEV_BACKEND)       += netback/
 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_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/
index 649f64c..3226753 100644 (file)
@@ -5,9 +5,13 @@
  *
  * Copyright (c) 2003, B Dragovic
  * Copyright (c) 2003-2004, M Williamson, K Fraser
  *
  * 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
  * 
  * 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
 #include <linux/bootmem.h>
 #include <linux/highmem.h>
 #include <linux/vmalloc.h>
 #include <linux/bootmem.h>
 #include <linux/highmem.h>
 #include <linux/vmalloc.h>
-#include <asm-xen/xen_proc.h>
-#include <asm-xen/hypervisor.h>
-#include <asm-xen/ctrl_if.h>
-#include <asm-xen/balloon.h>
+#include <xen/xen_proc.h>
+#include <asm/hypervisor.h>
+#include <xen/balloon.h>
+#include <xen/interface/memory.h>
 #include <asm/pgalloc.h>
 #include <asm/pgtable.h>
 #include <asm/uaccess.h>
 #include <asm/tlb.h>
 #include <linux/list.h>
 
 #include <asm/pgalloc.h>
 #include <asm/pgtable.h>
 #include <asm/uaccess.h>
 #include <asm/tlb.h>
 #include <linux/list.h>
 
+#include <xen/xenbus.h>
+
+#define PAGES2KB(_p) ((_p)<<(PAGE_SHIFT-10))
+
+#ifdef CONFIG_PROC_FS
 static struct proc_dir_entry *balloon_pde;
 static struct proc_dir_entry *balloon_pde;
+#endif
 
 static DECLARE_MUTEX(balloon_mutex);
 
 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 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;
 
 /* 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;
 
 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...) \
 
 #define IPRINTK(fmt, args...) \
-    printk(KERN_INFO "xen_mem: " fmt, ##args)
+       printk(KERN_INFO "xen_mem: " fmt, ##args)
 #define WPRINTK(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)
 {
 
 /* 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)
 {
 }
 
 /* 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)
 {
 }
 
 static void balloon_alarm(unsigned long unused)
 {
-    schedule_work(&balloon_worker);
+       schedule_work(&balloon_worker);
 }
 
 static unsigned long current_target(void)
 {
 }
 
 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)
 {
  */
 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)
 {
 }
 
 /* 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,
 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,
 }
 
 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)
 {
 
 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)
 {
 }
 
 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");
index a27fe65..8bab63d 100644 (file)
@@ -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
index 2554f99..c5b3eee 100644 (file)
@@ -9,33 +9,60 @@
  * 
  * Copyright (c) 2003-2004, Keir Fraser & Steve Hand
  * Copyright (c) 2005, Christopher Clark
  * 
  * 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 <linux/spinlock.h>
+#include <linux/kthread.h>
+#include <linux/list.h>
+#include <xen/balloon.h>
+#include <asm/hypervisor.h>
 #include "common.h"
 #include "common.h"
-#include <asm-xen/evtchn.h>
-#ifdef CONFIG_XEN_BLKDEV_GRANT
-#include <asm-xen/xen-public/grant_table.h>
-#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.
  * 
 
 /*
  * 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.
  */
  * 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 
 
 /*
  * 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 {
  * 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;
 
 } 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
  */
 
 
 /******************************************************************
  * 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()
 
 /******************************************************************
  * 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)
 {
 
 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)
 {
 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.
  */
 
 
 
 /******************************************************************************
  * 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)
 {
 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.
  */
 
  * 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, 
 
 
 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)
 {
 }
 
 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
 
 #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");
index a698e01..d057f79 100644 (file)
@@ -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__
 
 #ifndef __BLKIF__BACKEND__COMMON_H__
 #define __BLKIF__BACKEND__COMMON_H__
 #include <linux/config.h>
 #include <linux/version.h>
 #include <linux/module.h>
 #include <linux/config.h>
 #include <linux/version.h>
 #include <linux/module.h>
-#include <linux/rbtree.h>
 #include <linux/interrupt.h>
 #include <linux/slab.h>
 #include <linux/blkdev.h>
 #include <linux/interrupt.h>
 #include <linux/slab.h>
 #include <linux/blkdev.h>
+#include <linux/vmalloc.h>
+#include <linux/wait.h>
 #include <asm/io.h>
 #include <asm/setup.h>
 #include <asm/pgalloc.h>
 #include <asm/io.h>
 #include <asm/setup.h>
 #include <asm/pgalloc.h>
-#include <asm-xen/ctrl_if.h>
-#include <asm-xen/hypervisor.h>
-#include <asm-xen/xen-public/io/blkif.h>
-#include <asm-xen/xen-public/io/ring.h>
-
-#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 <xen/evtchn.h>
+#include <asm/hypervisor.h>
+#include <xen/interface/io/blkif.h>
+#include <xen/interface/io/ring.h>
+#include <xen/gnttab.h>
+#include <xen/driver_util.h>
+
+#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 {
 
 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;
 
 } 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_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 {
 
 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);
 };
 
 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);
 
 irqreturn_t blkif_be_int(int irq, void *dev_id, struct pt_regs *regs);
+int blkif_schedule(void *arg);
 
 #endif /* __BLKIF__BACKEND__COMMON_H__ */
 
 #endif /* __BLKIF__BACKEND__COMMON_H__ */
index 46d55d1..53b4764 100644 (file)
  * Block-device interface management.
  * 
  * Copyright (c) 2004, Keir Fraser
  * 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"
  */
 
 #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 <xen/evtchn.h>
+#include <linux/kthread.h>
 
 static kmem_cache_t *blkif_cachep;
 
 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<<PAGE_SHIFT, PAGE_SIZE,
-                                    prot, domid);
-    if ( error != 0 )
-    {
-        if ( error == -ENOMEM )
-            connect->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)
 {
 }
 
 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);
 }
 }
index f5ee589..a809b04 100644 (file)
  * 
  * Routines for managing virtual block devices (VBDs).
  * 
  * 
  * 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
  * 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 "common.h"
+#include <xen/xenbus.h>
 
 
-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)
 {
 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:
 
  out:
-    spin_unlock(&blkif->vbd_lock);
-    return rc;
+       return rc;
 }
 }
index 5d1707d..182ef65 100644 (file)
@@ -1,3 +1,5 @@
 
 
-obj-y  := blkfront.o vbd.o
+obj-$(CONFIG_XEN_BLKDEV_FRONTEND)      := xenblk.o
+
+xenblk-objs := blkfront.o vbd.o
 
 
index 311b839..a911c76 100644 (file)
@@ -8,9 +8,13 @@
  * Copyright (c) 2004, Christian Limpach
  * Copyright (c) 2004, Andrew Warfield
  * Copyright (c) 2005, Christopher Clark
  * 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
  * 
  * 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
  * IN THE SOFTWARE.
  */
 
  * 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 <linux/version.h>
 #include <linux/version.h>
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
 #include "block.h"
 #include "block.h"
-#else
-#include "common.h"
-#include <linux/blk.h>
-#include <linux/tqueue.h>
-#endif
-
 #include <linux/cdrom.h>
 #include <linux/sched.h>
 #include <linux/interrupt.h>
 #include <scsi/scsi.h>
 #include <linux/cdrom.h>
 #include <linux/sched.h>
 #include <linux/interrupt.h>
 #include <scsi/scsi.h>
-#include <asm-xen/ctrl_if.h>
-#include <asm-xen/evtchn.h>
-#ifdef CONFIG_XEN_BLKDEV_GRANT
-#include <asm-xen/xen-public/grant_table.h>
-#include <asm-xen/gnttab.h>
-#endif
-
-typedef unsigned char byte; /* from linux/ide.h */
+#include <xen/evtchn.h>
+#include <xen/xenbus.h>
+#include <xen/interface/grant_table.h>
+#include <xen/gnttab.h>
+#include <asm/hypervisor.h>
 
 
-/* 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", &sectors,
+                           "info", "%u", &binfo,
+                           "sector-size", "%lu", &sector_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)
 {
 }
 
 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)
 {
 }
 
 
 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,
 }
 
 
 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
  *
 }
 
 
 /*
  * 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.
  */
  * 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)
 {
 /*
  * 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, &copy[i]);
-
-        /* We get a new request id, and must reset the shadow state. */
-        req->id = GET_ID_FROM_FREELIST();
-        memcpy(&blk_shadow[req->id], &copy[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], &copy[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");
index ede57ab..5ba3d1e 100644 (file)
@@ -7,8 +7,11 @@
  * Modifications by Mark A. Williamson are (c) Intel Research Cambridge
  * Copyright (c) 2004-2005, Christian Limpach
  * 
  * 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
  * 
  * 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 <linux/config.h>
 #define __XEN_DRIVERS_BLOCK_H__
 
 #include <linux/config.h>
+#include <linux/version.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/blkdev.h>
 #include <linux/major.h>
 #include <linux/devfs_fs_kernel.h>
 #include <linux/blkdev.h>
 #include <linux/major.h>
 #include <linux/devfs_fs_kernel.h>
-#include <asm-xen/xen-public/xen.h>
-#include <asm-xen/xen-public/io/blkif.h>
-#include <asm-xen/xen-public/io/ring.h>
+#include <asm/hypervisor.h>
+#include <xen/xenbus.h>
+#include <xen/gnttab.h>
+#include <xen/interface/xen.h>
+#include <xen/interface/io/blkif.h>
+#include <xen/interface/io/ring.h>
 #include <asm/io.h>
 #include <asm/atomic.h>
 #include <asm/uaccess.h>
 
 #include <asm/io.h>
 #include <asm/atomic.h>
 #include <asm/uaccess.h>
 
-#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
 #else
-#define DPRINTK(_f, _a...) ((void)0)
+#define WPRINTK(fmt, args...) ((void)0)
 #endif
 
 #endif
 
+#define DPRINTK(_f, _a...) pr_debug(_f, ## _a)
+
 #if 0
 #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
 
 #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 :-)
  */
 /*
  * 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,
 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 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. */
 
 /* 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__ */
 
 #endif /* __XEN_DRIVERS_BLOCK_H__ */
index b5f2b14..8aa453d 100644 (file)
@@ -7,8 +7,11 @@
  * Modifications by Mark A. Williamson are (c) Intel Research Cambridge
  * Copyright (c) 2004-2005, Christian Limpach
  * 
  * 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
  * 
  * 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 <linux/blkdev.h>
 #include <linux/list.h>
 
 #include <linux/blkdev.h>
 #include <linux/list.h>
 
+#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
 /*
  * 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
 #define NUM_SCSI_MAJORS 9
 #define NUM_VBD_MAJORS 1
 
 #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 = {
 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 = {
 };
 
 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 = {
 };
 
 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 +
 };
 
 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
 
 /* 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;
 }
 }
index 80b7ca0..409b078 100644 (file)
@@ -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 
 
 
index a9a0067..8c5cf68 100644 (file)
 /******************************************************************************
 /******************************************************************************
- * 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 <linux/spinlock.h>
+#include <linux/kthread.h>
+#include <linux/list.h>
+#include <asm/hypervisor.h>
+#include "common.h"
+#include <xen/balloon.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/miscdevice.h>
+#include <linux/errno.h>
+#include <linux/major.h>
+#include <linux/gfp.h>
+#include <linux/poll.h>
+#include <asm/tlbflush.h>
+#include <linux/devfs_fs_kernel.h>
+
+#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; i<mmap_pages; i++)
+               get_page(&page[i]);
+
+       mmap_start[mmap_alloc].start = 
+               (unsigned long)pfn_to_kaddr(page_to_pfn(page));
+       mmap_start[mmap_alloc].mpage = page;
+
 #endif
 
 #endif
 
-__initcall(xlblktap_init);
+       pending_reqs[mmap_alloc]  = kzalloc(sizeof(pending_req_t) *
+                                       blkif_reqs, GFP_KERNEL);
+       pending_addrs[mmap_alloc] = kzalloc(sizeof(unsigned long) *
+                                       mmap_pages, GFP_KERNEL);
+
+       ret = -ENOMEM;
+       if (!pending_reqs[mmap_alloc] || !pending_addrs[mmap_alloc]) {
+               kfree(pending_reqs[mmap_alloc]);
+               kfree(pending_addrs[mmap_alloc]);
+               WPRINTK("%s: out of memory\n", __FUNCTION__); 
+               ret = -ENOMEM;
+               goto done;
+       }
+
+       ret = 0;
+
+       DPRINTK("%s: reqs=%d, pages=%d, mmap_vstart=0x%lx\n",
+               __FUNCTION__, blkif_reqs, mmap_pages, 
+              mmap_start[mmap_alloc].start);
+
+       BUG_ON(mmap_start[mmap_alloc].start == 0);
+
+       for (i = 0; i < mmap_pages; i++) 
+               pending_addrs[mmap_alloc][i] = 
+                       mmap_start[mmap_alloc].start + (i << PAGE_SHIFT);
+
+       for (i = 0; i < MAX_PENDING_REQS ; i++) {
+               list_add_tail(&pending_reqs[mmap_alloc][i].free_list, 
+                             &pending_free);
+               pending_reqs[mmap_alloc][i].mem_idx = mmap_alloc;
+               for (j = 0; j < BLKIF_MAX_SEGMENTS_PER_REQUEST; j++)
+                       BLKTAP_INVALIDATE_HANDLE(&pending_handle(mmap_alloc, 
+                                                                i, j));
+       }
+
+       mmap_alloc++;
+       DPRINTK("# MMAPs increased to %d\n",mmap_alloc);
+ done:
+       spin_unlock_irqrestore(&pending_free_lock, flags);
+       return ret;
+}
+
+static void mmap_req_del(int mmap)
+{
+       int i;
+       struct page *page;
+
+       /*Spinlock already acquired*/
+       kfree(pending_reqs[mmap]);
+       kfree(pending_addrs[mmap]);
+
+#ifdef __ia64__
+       /*Not sure what goes here yet!*/
+#else
+
+       /* Unpin all of the pages. */
+       page = mmap_start[mmap].mpage;
+       for (i=0; i<mmap_pages; i++)
+               put_page(&page[i]);
+
+       balloon_dealloc_empty_page_range(mmap_start[mmap].mpage, mmap_pages);
+#endif
+
+       mmap_lock = 0;
+       DPRINTK("# MMAPs decreased to %d\n",mmap_alloc);
+       mmap_alloc--;
+}
+
+/*N.B. Currently unused - will be accessed via sysfs*/
+static void req_decrease(void)
+{
+       pending_req_t *req;
+       int i;
+       unsigned long flags;
+
+       spin_lock_irqsave(&pending_free_lock, flags);
+
+       DPRINTK("Req decrease called.\n");
+       if (mmap_lock || mmap_alloc == 1) 
+               goto done;
+
+       mmap_lock = 1;
+       mmap_inuse = MAX_PENDING_REQS;
+       
+        /*Go through reqs and remove any that aren't in use*/
+       for (i = 0; i < MAX_PENDING_REQS ; i++) {
+               req = &pending_reqs[mmap_alloc-1][i];
+               if (req->inuse == 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");
index e4ffdef..35de3e9 100644 (file)
@@ -1,2 +1,2 @@
 
 
-obj-y  := console.o
+obj-y  := console.o xencons_ring.o
index 142ca2b..ec7dd9e 100644 (file)
@@ -5,8 +5,11 @@
  * 
  * Copyright (c) 2002-2004, K A Fraser.
  * 
  * 
  * 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
  * 
  * 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
 #include <linux/init.h>
 #include <linux/console.h>
 #include <linux/bootmem.h>
 #include <linux/init.h>
 #include <linux/console.h>
 #include <linux/bootmem.h>
+#include <linux/sysrq.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/uaccess.h>
-#include <asm-xen/xen-public/event_channel.h>
-#include <asm-xen/hypervisor.h>
-#include <asm-xen/evtchn.h>
-#include <asm-xen/ctrl_if.h>
+#include <xen/interface/xen.h>
+#include <xen/interface/event_channel.h>
+#include <asm/hypervisor.h>
+#include <xen/evtchn.h>
+#include <xen/xencons.h>
 
 /*
  * Modes:
 
 /*
  * Modes:
 static enum { XC_OFF, XC_DEFAULT, XC_TTY, XC_SERIAL } xc_mode = XC_DEFAULT;
 static int xc_num = -1;
 
 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)
 {
 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);
 
 }
 __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)
 {
 
 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. */
 }
 __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);
 
 
 /* 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;
 static struct tty_driver *xencons_driver;
-#else
-static struct tty_driver xencons_driver;
-#endif
-
 
 /******************** Kernel console driver ********************************/
 
 
 /******************** 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)
 {
 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 = {
 
 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)
 #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);
 console_initcall(xen_console_init);
-#endif
 
 /*** Useful function for console debugging -- goes straight to Xen. ***/
 asmlinkage int xprintk(const char *fmt, ...)
 {
 
 /*** 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)
 {
 }
 
 /*** 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) ************/
 
 }
 
 
 /******************** User-space console driver (/dev/console) ************/
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
 #define DRV(_d)         (_d)
 #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];
 
 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;
 
 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)
 {
 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,
 }
 
 /* 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)
 {
 }
 
 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)
 {
 }
 
 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)
 {
 }
 
 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)
 {
 }
 
 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)
 {
 }
 
 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)
 {
 }
 
 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)
 {
 }
 
 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(
 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)
 {
 
 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)
 {
 }
 
 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)
 {
 }
 
 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)
 {
 }
 
 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)
 {
 }
 
 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 = {
 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)
 {
 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_init(xencons_init);
+
+MODULE_LICENSE("Dual BSD/GPL");
index f5da428..76bfab8 100644 (file)
@@ -1,13 +1,16 @@
 /******************************************************************************
  * evtchn.c
  * 
 /******************************************************************************
  * 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
  * 
  * 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
  * 
  * 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
 #include <linux/poll.h>
 #include <linux/irq.h>
 #include <linux/init.h>
 #include <linux/poll.h>
 #include <linux/irq.h>
 #include <linux/init.h>
-#define XEN_EVTCHN_MASK_OPS
-#include <asm-xen/evtchn.h>
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
-#include <linux/devfs_fs_kernel.h>
-#define OLD_DEVFS
-#else
 #include <linux/gfp.h>
 #include <linux/gfp.h>
-#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 <xen/evtchn.h>
+#include <xen/public/evtchn.h>
 
 struct per_user_data {
 
 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? */
 };
 
 /* Who's bound to each port? */
@@ -77,354 +69,390 @@ static spinlock_t port_user_lock;
 
 void evtchn_device_upcall(int port)
 {
 
 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:
 
  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(&notify, 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)
 {
 }
 
 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)
 {
 }
 
 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)
 {
 }
 
 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)
 {
 }
 
 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 = {
 }
 
 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 = {
 };
 
 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)
 {
 };
 
 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)
 {
 }
 
 static void evtchn_cleanup(void)
 {
-    misc_deregister(&evtchn_miscdev);
+       misc_deregister(&evtchn_miscdev);
 }
 
 module_init(evtchn_init);
 module_exit(evtchn_cleanup);
 }
 
 module_init(evtchn_init);
 module_exit(evtchn_cleanup);
+
+MODULE_LICENSE("Dual BSD/GPL");
index 3279442..d5d2328 100644 (file)
@@ -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
index dfb750e..c5ec300 100644 (file)
@@ -1,5 +1,29 @@
 /******************************************************************************
  * arch/xen/drivers/netif/backend/common.h
 /******************************************************************************
  * 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__
  */
 
 #ifndef __NETIF__BACKEND__COMMON_H__
 #include <linux/in.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/in.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
-#include <asm-xen/ctrl_if.h>
-#include <asm-xen/xen-public/io/netif.h>
+#include <linux/wait.h>
+#include <xen/evtchn.h>
+#include <xen/interface/io/netif.h>
 #include <asm/io.h>
 #include <asm/pgalloc.h>
 #include <asm/io.h>
 #include <asm/pgalloc.h>
-
-#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 <xen/interface/grant_table.h>
+#include <xen/gnttab.h>
+#include <xen/driver_util.h>
+
+#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 {
 
 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;
 
 } 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_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);
 
 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);
 
 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__ */
 #endif /* __NETIF__BACKEND__COMMON_H__ */
index f509a1b..d60b23b 100644 (file)
  * Network-device interface management.
  * 
  * Copyright (c) 2004-2005, Keir Fraser
  * 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 "common.h"
+#include <linux/ethtool.h>
 #include <linux/rtnetlink.h>
 
 #include <linux/rtnetlink.h>
 
-#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)
 {
 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)
 {
 }
 
 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)
 {
 }
 
 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)
 {
 }
 
 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<<PAGE_SHIFT, PAGE_SIZE,
-                                     prot, domid);
-    error |= direct_remap_area_pages(&init_mm, 
-                                     VMALLOC_VMADDR(vma->addr) + PAGE_SIZE,
-                                     rx_shmem_frame<<PAGE_SHIFT, PAGE_SIZE,
-                                     prot, domid);
-    if ( error != 0 )
-    {
-        if ( error == -ENOMEM )
-            connect->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);
 }
 }
index d08c296..0316f3b 100644 (file)
@@ -8,26 +8,54 @@
  *  drivers/xen/netfront/netfront.c
  * 
  * Copyright (c) 2002-2005, K A Fraser
  *  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 "common.h"
-#include <asm-xen/balloon.h>
-#include <asm-xen/evtchn.h>
+#include <xen/balloon.h>
+#include <xen/interface/memory.h>
 
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
-#include <linux/delay.h>
-#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, 
 
 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);
 
 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 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 {
 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;
 } 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 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;
 
 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;
 #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)
 {
 }
 
 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)
 {
  */
 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)
 {
 }
 
 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:
 
  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)
 {
 }
 
 #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):
 }
 /* 
  * 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)
 {
  */
 int xen_network_done(void)
 {
-    return skb_queue_empty(&rx_queue);
+       return skb_queue_empty(&rx_queue);
 }
 #endif
 
 }
 #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)
 {
 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
 #if 0
-    else
-        xen_network_done_notify();
+       else
+               xen_network_done_notify();
 #endif
 }
 
 static void net_alarm(unsigned long unused)
 {
 #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)
 {
 }
 
 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)
 {
 }
 
 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)
 {
 }
 
 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)
 {
 }
 
 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)
 {
 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)
 {
 }
 
 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)
 {
 }
 
 
 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_init(netback_init);
-module_exit(netback_cleanup);
+
+MODULE_LICENSE("Dual BSD/GPL");
index 7eb07a2..dc22829 100644 (file)
@@ -1,2 +1,4 @@
 
 
-obj-y  := netfront.o
+obj-$(CONFIG_XEN_NETDEV_FRONTEND)      := xennet.o
+
+xennet-objs := netfront.o
index f729295..ef6e134 100644 (file)
@@ -1,21 +1,25 @@
 /******************************************************************************
  * Virtual network driver for conversing with remote driver backends.
 /******************************************************************************
  * 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:
  * 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 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
  * 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
 #include <linux/skbuff.h>
 #include <linux/init.h>
 #include <linux/bitops.h>
 #include <linux/skbuff.h>
 #include <linux/init.h>
 #include <linux/bitops.h>
+#include <linux/ethtool.h>
+#include <linux/in.h>
+#include <linux/if_ether.h>
+#include <linux/io.h>
 #include <net/sock.h>
 #include <net/pkt_sched.h>
 #include <net/arp.h>
 #include <net/route.h>
 #include <net/sock.h>
 #include <net/pkt_sched.h>
 #include <net/arp.h>
 #include <net/route.h>
-#include <asm/io.h>
-#include <asm-xen/evtchn.h>
-#include <asm-xen/ctrl_if.h>
-#include <asm-xen/xen-public/io/netif.h>
-#include <asm-xen/balloon.h>
+#include <asm/uaccess.h>
+#include <xen/evtchn.h>
+#include <xen/xenbus.h>
+#include <xen/interface/io/netif.h>
+#include <xen/interface/memory.h>
+#include <xen/balloon.h>
 #include <asm/page.h>
 #include <asm/page.h>
+#include <asm/uaccess.h>
+#include <xen/interface/grant_table.h>
+#include <xen/gnttab.h>
 
 
-#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_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.
  *
 /** 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)
 {
  */
 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)
 {
 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)
 {
 }
 
 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)
 {
 }
 
 
 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)
 {
 
 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("<vif handle=%u %s(%s) evtchn=%u irq=%u tx=%p rx=%p>\n",
-               np->handle,
-               be_state_name[np->backend_state],
-               np->user_state ? "open" : "closed",
-               np->evtchn,
-               np->irq,
-               np->tx,
-               np->rx);
-    } else {
-        IPRINTK("<vif NULL>\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
  */
 /** 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 = {
 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)
 {
 };
 
 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(&notifier_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(&notifier_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(&notifier_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");
index e218695..de090ba 100644 (file)
@@ -1,2 +1,2 @@
 
 
-obj-y  := privcmd.o
+obj-$(CONFIG_XEN_PRIVCMD)      := privcmd.o
index 0b78cc7..3c9bb9f 100644 (file)
 #include <linux/highmem.h>
 #include <linux/pagemap.h>
 #include <linux/seq_file.h>
 #include <linux/highmem.h>
 #include <linux/pagemap.h>
 #include <linux/seq_file.h>
+#include <linux/kthread.h>
+#include <asm/hypervisor.h>
 
 #include <asm/pgalloc.h>
 #include <asm/pgtable.h>
 #include <asm/uaccess.h>
 #include <asm/tlb.h>
 
 #include <asm/pgalloc.h>
 #include <asm/pgtable.h>
 #include <asm/uaccess.h>
 #include <asm/tlb.h>
-#include <asm-xen/linux-public/privcmd.h>
-#include <asm-xen/xen-public/dom0_ops.h>
-#include <asm-xen/xen_proc.h>
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
-#define pud_t pgd_t
-#define pud_offset(d, va) d
-#endif
+#include <asm/hypervisor.h>
+#include <xen/public/privcmd.h>
+#include <xen/interface/xen.h>
+#include <xen/interface/dom0_ops.h>
+#include <xen/xen_proc.h>
 
 static struct proc_dir_entry *privcmd_intf;
 
 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,
 
 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__)
 
 #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__)
 #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
 #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)
 #if defined(CONFIG_XEN_PRIVILEGED_GUEST)
-    case IOCTL_PRIVCMD_MMAP:
-    {
+       case IOCTL_PRIVCMD_MMAP: {
 #define PRIVCMD_MMAP_SZ 32
 #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; 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);
+               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<<PAGE_SHIFT)) > vma->vm_end )
-                    return -EINVAL;
-
-                if ( (rc = direct_remap_area_pages(vma->vm_mm, 
-                                                   msg[j].va&PAGE_MASK, 
-                                                   msg[j].mfn<<PAGE_SHIFT, 
-                                                   msg[j].npages<<PAGE_SHIFT, 
-                                                   vma->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<<PAGE_SHIFT)) > 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<<PAGE_SHIFT, 
+                                       vma->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<<PAGE_SHIFT)) > 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
 
 #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)
 {
 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 = {
 
 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);
 }
 
 __initcall(privcmd_init);
index 0167990..1d0cf40 100644 (file)
@@ -842,6 +842,7 @@ config TMPFS
 config HUGETLBFS
        bool "HugeTLB file system support"
        depends X86 || IA64 || PPC64 || SPARC64 || SUPERH || BROKEN
 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
        help
          hugetlbfs is a filesystem backing for HugeTLB pages, based on
          ramfs. For architectures that support it, say Y here and read
index 68ebd10..aa50dc6 100644 (file)
@@ -512,7 +512,11 @@ befs_utf2nls(struct super_block *sb, const char *in,
        wchar_t uni;
        int unilen, utflen;
        char *result;
        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()");
 
 
        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;
        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");
 
 
        befs_debug(sb, "---> nls2utf()\n");
 
index 093645b..479ee5f 100644 (file)
@@ -88,7 +88,7 @@ static struct linux_binfmt elf_format = {
                .min_coredump   = ELF_EXEC_PAGESIZE
 };
 
                .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)
 {
 
 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;
             * <= 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;
                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.
                 */
                 * 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.  */
                    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)) {
                        }
                }
                if (BAD_ADDR(elf_entry)) {
-                       printk(KERN_ERR "Unable to load interpreter %.128s\n",
-                               elf_interpreter);
                        force_sig(SIGSEGV, current);
                        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;
                        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)) {
        } 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;
                }
        }
                        goto out_free_dentry;
                }
        }
index 23f1f3a..7f6d659 100644 (file)
@@ -473,13 +473,18 @@ out:
    pass does the actual I/O. */
 void invalidate_bdev(struct block_device *bdev, int destroy_dirty_buffers)
 {
    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_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);
 }
 
 /*
 }
 
 /*
index f05b2cf..2299325 100644 (file)
@@ -252,6 +252,46 @@ static struct super_operations ext2_sops = {
 #endif
 };
 
 #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.
 /* 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,
  */
 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)
 };
 
 static unsigned long get_sb_block(void **data)
index bdd65f4..4ce217b 100644 (file)
@@ -1160,7 +1160,7 @@ retry:
                ret = PTR_ERR(handle);
                goto out;
        }
                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);
                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 (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);
                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;
        }
 
                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);
                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;
 
        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;
        }
                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");
        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");
index 329eae3..045f588 100644 (file)
@@ -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);
        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);
 
                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);
                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);
 
        if (!inode)
                return ERR_PTR(-EACCES);
index 2a0cb4c..ed22106 100644 (file)
@@ -620,8 +620,48 @@ static struct super_operations ext3_sops = {
 #endif
 };
 
 #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,
 static struct export_operations ext3_export_ops = {
        .get_parent = ext3_get_parent,
+       .get_dentry = ext3_get_dentry,
 };
 
 enum {
 };
 
 enum {
index 55f4e70..4c2cacc 100644 (file)
--- 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)
        } 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;
        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);
 out:
        if (new_openset)
                free_fdset(new_openset, nfds);
index 7ec121c..7189834 100644 (file)
@@ -1409,8 +1409,9 @@ static int __setlease(struct file *filp, long arg, struct file_lock **flp)
        if (!leases_enable)
                goto out;
 
        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);
                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;
        locks_insert_lock(before, fl);
 
        *flp = fl;
+       error = 0;
 out:
        return error;
 }
 out:
        return error;
 }
index 1819223..178e70e 100644 (file)
@@ -1773,8 +1773,14 @@ do_link:
        if (error)
                goto exit_dput;
        error = __do_follow_link(&path, nd);
        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;
                return error;
+       }
        nd->flags &= ~LOOKUP_PARENT;
        if (nd->last_type == LAST_BIND)
                goto ok;
        nd->flags &= ~LOOKUP_PARENT;
        if (nd->last_type == LAST_BIND)
                goto ok;
index 8c88012..f6e0c62 100644 (file)
@@ -631,6 +631,27 @@ static int proc_permission(struct inode *inode, int mask, struct nameidata *nd)
        return proc_check_root(inode);
 }
 
        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;
 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,
 
 static struct inode_operations proc_mem_inode_operations = {
        .permission     = proc_permission,
+       .setattr        = proc_setattr,
 };
 
 #ifdef CONFIG_AUDITSYSCALL
 };
 
 #ifdef CONFIG_AUDITSYSCALL
@@ -1219,7 +1241,8 @@ out:
 
 static struct inode_operations proc_pid_link_inode_operations = {
        .readlink       = proc_pid_readlink,
 
 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
 };
 
 #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);
        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;
 
        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_uid = 0;
                        inode->i_gid = 0;
                }
+               inode->i_mode &= ~(S_ISUID | S_ISGID);
                security_task_to_inode(task, inode);
                return 1;
        }
                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_uid = 0;
                                inode->i_gid = 0;
                        }
+                       inode->i_mode &= ~(S_ISUID | S_ISGID);
                        security_task_to_inode(task, inode);
                        return 1;
                }
                        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,
 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,
 };
 
 static struct inode_operations proc_task_inode_operations = {
        .lookup         = proc_task_lookup,
        .permission     = proc_task_permission,
+       .setattr        = proc_setattr,
 };
 
 #ifdef CONFIG_SECURITY
 };
 
 #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,
 
 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,
 };
 
 static struct inode_operations proc_tid_base_inode_operations = {
        .lookup         = proc_tid_base_lookup,
+       .setattr        = proc_setattr,
 };
 
 #ifdef CONFIG_SECURITY
 };
 
 #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,
 
 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,
 };
 
 static struct inode_operations proc_tid_attr_inode_operations = {
        .lookup         = proc_tid_attr_lookup,
+       .setattr        = proc_setattr,
 };
 #endif
 
 };
 #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,
 static struct inode_operations proc_self_inode_operations = {
        .readlink       = proc_self_readlink,
        .follow_link    = proc_self_follow_link,
+       .setattr        = proc_setattr,
 };
 
 /**
 };
 
 /**
index a285fd7..8fef667 100644 (file)
@@ -1294,6 +1294,85 @@ asmlinkage long sys_splice(int fd_in, loff_t __user *off_in,
        return error;
 }
 
        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.
  */
 /*
  * 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;
                     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
 
        /*
         * 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) {
         * 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 {
                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);
        }
 
                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 (!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);
 
 
        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);
                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;
 {
        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)
 }
 
 asmlinkage long sys_tee(int fdin, int fdout, size_t len, unsigned int flags)
index e45789f..73fc0d8 100644 (file)
@@ -1653,7 +1653,7 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
                iput(inode);
                goto error_out;
        }
                iput(inode);
                goto error_out;
        }
-       sb->s_maxbytes = MAX_LFS_FILESIZE;
+       sb->s_maxbytes = 1<<30;
        return 0;
 
 error_out:
        return 0;
 
 error_out:
index e1b0e8c..0abd66c 100644 (file)
@@ -239,37 +239,51 @@ void udf_truncate_extents(struct inode * inode)
        {
                if (offset)
                {
        {
                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;
                                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;
                                        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));
                                                ~(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);
                        }
                }
        }
                        }
                }
        }
index ac511ab..0655cc3 100644 (file)
@@ -970,7 +970,7 @@ xfs_dir2_leafn_remove(
                        /*
                         * One less used entry in the free table.
                         */
                        /*
                         * 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
                        xfs_dir2_free_log_header(tp, fbp);
                        /*
                         * If this was the last entry in the table, we can
index 3b41d2b..010ced7 100644 (file)
 #define MAP_ANON       MAP_ANONYMOUS
 #define MAP_FILE       0
 
 #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
 #endif
index 288233f..87476de 100644 (file)
@@ -132,10 +132,12 @@ extern unsigned int nmi_watchdog;
 
 extern int disable_timer_pin_1;
 
 
 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
 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;
 
 
 extern int timer_over_8254;
 
index aa37153..fdecfa0 100644 (file)
@@ -170,7 +170,7 @@ static inline void set_user_cs(struct desc_struct *desc, unsigned long limit)
 }
 
 #define load_user_cs_desc(cpu, mm) \
 }
 
 #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);
 
 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);
index cfb1c61..f11513a 100644 (file)
@@ -20,7 +20,7 @@
  * Leave one empty page between vmalloc'ed areas and
  * the start of the fixmap.
  */
  * 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 <linux/kernel.h>
 
 #ifndef __ASSEMBLY__
 #include <linux/kernel.h>
@@ -95,6 +95,8 @@ enum fixed_addresses {
 extern void __set_fixmap (enum fixed_addresses idx,
                                        unsigned long phys, pgprot_t flags);
 
 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)
 /*
 #define set_fixmap(idx, phys) \
                __set_fixmap(idx, phys, PAGE_KERNEL)
 /*
index 625438b..4e34a91 100644 (file)
@@ -15,6 +15,18 @@ static inline void clear_mem_error(unsigned char reason)
        outb(reason, 0x61);
 }
 
        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);
 static inline unsigned char get_nmi_reason(void)
 {
        return inb(0x61);
index 104653b..2b2683e 100644 (file)
@@ -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 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)
 #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)
index 0251807..bd6346f 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef _I386_PGTABLE_2LEVEL_DEFS_H
 #define _I386_PGTABLE_2LEVEL_DEFS_H
 
 #ifndef _I386_PGTABLE_2LEVEL_DEFS_H
 #define _I386_PGTABLE_2LEVEL_DEFS_H
 
+#define HAVE_SHARED_KERNEL_PMD 0
+
 /*
  * traditional i386 two-level paging structure:
  */
 /*
  * traditional i386 two-level paging structure:
  */
index eb3a1ea..0c75992 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef _I386_PGTABLE_3LEVEL_DEFS_H
 #define _I386_PGTABLE_3LEVEL_DEFS_H
 
 #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
  */
 /*
  * PGDIR_SHIFT determines what a top-level page table entry can map
  */
index d76b769..6d794a3 100644 (file)
@@ -36,7 +36,7 @@
        "\n1:\t" \
        "lock ; decb %0\n\t" \
        "jns 5f\n" \
        "\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" \
        "testl $0x200, %1\n\t" \
        "jz 4f\n\t" \
        "sti\n" \
index 6ba179f..b242f95 100644 (file)
@@ -8,6 +8,14 @@
  *     David Mosberger-Tang <davidm@hpl.hp.com>, Hewlett-Packard Co
  */
 
  *     David Mosberger-Tang <davidm@hpl.hp.com>, 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 <asm-generic/mman.h>
 
 #define MAP_GROWSDOWN  0x00100         /* stack-like segment */
 #include <asm-generic/mman.h>
 
 #define MAP_GROWSDOWN  0x00100         /* stack-like segment */
index 9bd2f9b..6f807e0 100644 (file)
  * the bte_copy() once in the hope that the failure was due to a temporary
  * aberration (i.e., the link going down temporarily).
  *
  * 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
  *
  * 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;
 {
        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();
                }
        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;
        }
 
        return ret;
index aa3b8ac..b454ad4 100644 (file)
@@ -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 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);
 extern struct xpc_rsvd_page *xpc_rsvd_page_init(void);
 extern void xpc_allow_IPI_ops(void);
 extern void xpc_restrict_IPI_ops(void);
index 1802775..ffedf14 100644 (file)
@@ -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;
 
        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"
                     "0: lr   %0,%1\n"
-                    "1:\n"
+                    "1: sacf 0\n"
 #ifndef __s390x__
                     ".section __ex_table,\"a\"\n"
                     "   .align 4\n"
 #ifndef __s390x__
                     ".section __ex_table,\"a\"\n"
                     "   .align 4\n"
index 88d1886..95ecab5 100644 (file)
@@ -2,6 +2,12 @@
 #ifndef __SPARC_MMAN_H__
 #define __SPARC_MMAN_H__
 
 #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 <asm-generic/mman.h>
 
 /* SunOS'ified... */
 #include <asm-generic/mman.h>
 
 /* SunOS'ified... */
index 6fd878e..b300276 100644 (file)
@@ -2,6 +2,12 @@
 #ifndef __SPARC64_MMAN_H__
 #define __SPARC64_MMAN_H__
 
 #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 <asm-generic/mman.h>
 
 /* SunOS'ified... */
 #include <asm-generic/mman.h>
 
 /* SunOS'ified... */
index 5015bb8..89d4243 100644 (file)
@@ -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)                                  \
 #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)
 
 #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)
index 0f7229c..4593114 100644 (file)
@@ -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
 
 #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 <asm-generic/memory_model.h>
 #define HAVE_ARCH_FREE_PAGE
 
 #include <asm-generic/memory_model.h>
index bdbd893..79db75f 100644 (file)
@@ -105,11 +105,13 @@ extern int disable_timer_pin_1;
 
 extern void setup_threshold_lvt(unsigned long lvt_off);
 
 
 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
 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 */
 
 
 #endif /* CONFIG_X86_LOCAL_APIC */
 
index 0df1715..91f751b 100644 (file)
@@ -127,7 +127,7 @@ asmlinkage void IRQ_NAME(nr); \
 __asm__( \
 "\n.p2align\n" \
 "IRQ" #nr "_interrupt:\n\t" \
 __asm__( \
 "\n.p2align\n" \
 "IRQ" #nr "_interrupt:\n\t" \
-       "push $" #nr "-256 ; " \
+       "push $~(" #nr ") ; " \
        "jmp common_interrupt");
 
 #if defined(CONFIG_X86_IO_APIC)
        "jmp common_interrupt");
 
 #if defined(CONFIG_X86_IO_APIC)
index 2a5c162..be4bc76 100644 (file)
@@ -49,6 +49,7 @@ static inline int __prepare_ICR2 (unsigned int mask)
        return SET_APIC_DEST_FIELD(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)
 {
        /*
 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);
 }
        }
        local_irq_restore(flags);
 }
+#endif /* CONFIG_XEN_UNPRIVILEGED_GUEST */
 
 #endif /* __ASM_IPI_H */
 
 #endif /* __ASM_IPI_H */
index 31e83c3..195952b 100644 (file)
@@ -21,7 +21,7 @@ extern unsigned long __supported_pte_mask;
 
 #define swapper_pg_dir init_level4_pgt
 
 
 #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);
 
 extern void paging_init(void);
 extern void clear_kernel_mapping(unsigned long addr, unsigned long size);
 
index 546d521..6b7b49b 100644 (file)
@@ -1,41 +1,62 @@
 /*
  * Automatically generated C config: don't edit
 /*
  * 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 AUTOCONF_INCLUDED
+#define CONFIG_X86_32 1
+#define CONFIG_SEMAPHORE_SLEEPERS 1
 #define CONFIG_X86 1
 #define CONFIG_MMU 1
 #define CONFIG_X86 1
 #define CONFIG_MMU 1
-#define CONFIG_UID16 1
 #define CONFIG_GENERIC_ISA_DMA 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
 
 /*
  * 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
  */
 
 /*
  * 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
 #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
 #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
 #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
 #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_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
 
 /*
  * Loadable module support
 #define CONFIG_MODULES 1
 #define CONFIG_MODULE_UNLOAD 1
 #undef CONFIG_MODULE_FORCE_UNLOAD
 #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_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
  */
 
 /*
  * 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
 #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
 #undef CONFIG_X86_ES7000
-#define CONFIG_X86_CYCLONE_TIMER 1
 #undef CONFIG_M386
 #undef CONFIG_M486
 #undef CONFIG_M586
 #undef CONFIG_M386
 #undef CONFIG_M486
 #undef CONFIG_M586
 #undef CONFIG_MK7
 #undef CONFIG_MK8
 #undef CONFIG_MCRUSOE
 #undef CONFIG_MK7
 #undef CONFIG_MK8
 #undef CONFIG_MCRUSOE
+#undef CONFIG_MEFFICEON
 #undef CONFIG_MWINCHIPC6
 #undef CONFIG_MWINCHIP2
 #undef CONFIG_MWINCHIP3D
 #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
 #undef CONFIG_MCYRIXIII
 #undef CONFIG_MVIAC3_2
 #define CONFIG_X86_GENERIC 1
 #define CONFIG_X86_XADD 1
 #define CONFIG_X86_L1_CACHE_SHIFT 7
 #define CONFIG_RWSEM_XCHGADD_ALGORITHM 1
 #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_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_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_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
 #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_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
 #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
 #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
 
 /*
  * 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_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_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
 #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
 #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
 
 /*
  * 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
 
 /*
  * 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
 #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_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_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_TOSHIBA_MODULE 1
+#define CONFIG_ACPI_BLACKLIST_YEAR 1999
 #undef CONFIG_ACPI_DEBUG
 #undef CONFIG_ACPI_DEBUG
-#define CONFIG_ACPI_BUS 1
 #define CONFIG_ACPI_EC 1
 #define CONFIG_ACPI_POWER 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
 #define CONFIG_ACPI_SYSTEM 1
 #define CONFIG_X86_PM_TIMER 1
+#undef CONFIG_ACPI_CONTAINER
 
 /*
  * APM (Advanced Power Management) BIOS Support
 
 /*
  * APM (Advanced Power Management) BIOS Support
  * CPU Frequency scaling
  */
 #define CONFIG_CPU_FREQ 1
  * 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_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
 
 /*
  * 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_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
 #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_ACPI 1
+#define CONFIG_X86_SPEEDSTEP_CENTRINO_TABLE 1
 #define CONFIG_X86_SPEEDSTEP_ICH 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
 #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_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)
 
 /*
  * Bus options (PCI, PCMCIA, EISA, MCA, ISA)
 #undef CONFIG_PCI_GOBIOS
 #undef CONFIG_PCI_GOMMCONFIG
 #undef CONFIG_PCI_GODIRECT
 #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_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
 
 /*
 #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
 #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
 #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_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_PCMCIA_PROBE 1
+#define CONFIG_PCCARD_NONSTATIC 1
 
 /*
  * PCI Hotplug Support
  */
 #define CONFIG_HOTPLUG_PCI 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
 #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
 #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
 
 /*
  * 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_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
 
 /*
 #define CONFIG_NET_SB1000_MODULE 1
 
 /*
  */
 #undef CONFIG_ARCNET
 
  */
 #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)
  */
 /*
  * Ethernet (10 or 100Mbit)
  */
 #define CONFIG_MII_MODULE 1
 #define CONFIG_HAPPYMEAL_MODULE 1
 #define CONFIG_SUNGEM_MODULE 1
 #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_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_EL3_MODULE 1
-#define CONFIG_3C515_MODULE 1
+#undef CONFIG_3C515
 #define CONFIG_VORTEX_MODULE 1
 #define CONFIG_TYPHOON_MODULE 1
 #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_NET_VENDOR_SMC 1
-#define CONFIG_WD80x3_MODULE 1
+#undef CONFIG_WD80x3
 #define CONFIG_ULTRA_MODULE 1
 #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
 
 /*
  * Tulip family network device support
 #define CONFIG_DE4X5_MODULE 1
 #define CONFIG_WINBOND_840_MODULE 1
 #define CONFIG_DM9102_MODULE 1
 #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
 #define CONFIG_PCMCIA_XIRCOM_MODULE 1
+#undef CONFIG_PCMCIA_XIRTULIP
 #undef CONFIG_AT1700
 #undef CONFIG_AT1700
-#define CONFIG_DEPCA_MODULE 1
+#undef CONFIG_DEPCA
 #define CONFIG_HP100_MODULE 1
 #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
 #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_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_B44_MODULE 1
 #define CONFIG_FORCEDETH_MODULE 1
-#define CONFIG_CS89x0_MODULE 1
+#undef CONFIG_CS89x0
 #define CONFIG_DGRS_MODULE 1
 #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_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_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
 #undef CONFIG_8139TOO_TUNE_TWISTER
 #define CONFIG_8139TOO_8129 1
 #undef CONFIG_8139_OLD_RX_RESET
 #define CONFIG_DE620_MODULE 1
 
 /*
 #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
 #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_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_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
 #define CONFIG_IXGB_MODULE 1
 #define CONFIG_IXGB_NAPI 1
 #define CONFIG_S2IO_MODULE 1
 /*
  * Token Ring devices
  */
 /*
  * 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
 
 /*
  * 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
 
 /*
  * 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
 
 #define CONFIG_PCMCIA_WAVELAN_MODULE 1
 #define CONFIG_PCMCIA_NETWAVE_MODULE 1
 
 /*
  * Wireless 802.11b ISA/PCI cards support
  */
 /*
  * 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_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
 #define CONFIG_PCI_HERMES_MODULE 1
 #define CONFIG_ATMEL_MODULE 1
 #define CONFIG_PCI_ATMEL_MODULE 1
  * Wireless 802.11b Pcmcia/Cardbus cards support
  */
 #define CONFIG_PCMCIA_HERMES_MODULE 1
  * 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
 #define CONFIG_AIRO_CS_MODULE 1
 #define CONFIG_PCMCIA_ATMEL_MODULE 1
 #define CONFIG_PCMCIA_WL3501_MODULE 1
  * Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
  */
 #define CONFIG_PRISM54_MODULE 1
  * 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
 
 /*
 #define CONFIG_NET_WIRELESS 1
 
 /*
 #define CONFIG_PCMCIA_SMC91C92_MODULE 1
 #define CONFIG_PCMCIA_XIRC2PS_MODULE 1
 #define CONFIG_PCMCIA_AXNET_MODULE 1
 #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
 
 /*
  * 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
 #define CONFIG_FDDI 1
 #undef CONFIG_DEFXX
 #define CONFIG_SKFP_MODULE 1
 #define CONFIG_PPP_SYNC_TTY_MODULE 1
 #define CONFIG_PPP_DEFLATE_MODULE 1
 #undef CONFIG_PPP_BSDCOMP
 #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
 #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_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
 
 /*
  * ISDN subsystem
 /*
  * ISDN feature submodules
  */
 /*
  * ISDN feature submodules
  */
+#define CONFIG_ISDN_DRV_LOOP_MODULE 1
+#define CONFIG_ISDN_DIVERSION_MODULE 1
 
 /*
  * ISDN4Linux hardware drivers
 
 /*
  * ISDN4Linux hardware drivers
 /*
  * HiSax supported cards
  */
 /*
  * 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_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_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_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_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_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
 #define CONFIG_HISAX_BKM_A4T 1
 #define CONFIG_HISAX_SCT_QUADRO 1
 #define CONFIG_HISAX_GAZEL 1
  * HiSax sub driver modules
  */
 #define CONFIG_HISAX_ST5481_MODULE 1
  * 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_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
 
 /*
  * CAPI subsystem
  * Active AVM cards
  */
 #define CONFIG_CAPI_AVM 1
  * 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
 
 /*
  * Active Eicon DIVA Server cards
 #define CONFIG_INPUT_EVDEV 1
 #undef CONFIG_INPUT_EVBUG
 
 #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
  */
 /*
  * Input Device Drivers
  */
 #define CONFIG_INPUT_MOUSE 1
 #define CONFIG_MOUSE_PS2 1
 #define CONFIG_MOUSE_SERIAL_MODULE 1
 #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
 #define CONFIG_MOUSE_VSXXXAA_MODULE 1
 #define CONFIG_INPUT_JOYSTICK 1
 #define CONFIG_JOYSTICK_ANALOG_MODULE 1
 #define CONFIG_JOYSTICK_SPACEORB_MODULE 1
 #define CONFIG_JOYSTICK_SPACEBALL_MODULE 1
 #define CONFIG_JOYSTICK_STINGER_MODULE 1
 #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
 #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_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
 #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
 
 /*
  * Character devices
 #define CONFIG_VT_CONSOLE 1
 #define CONFIG_HW_CONSOLE 1
 #define CONFIG_SERIAL_NONSTANDARD 1
 #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
 #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
 #define CONFIG_SYNCLINK_MODULE 1
 #define CONFIG_SYNCLINKMP_MODULE 1
+#undef CONFIG_SYNCLINK_GT
 #define CONFIG_N_HDLC_MODULE 1
 #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
 
 /*
  * 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
 #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
 #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_SHARE_IRQ 1
 #define CONFIG_SERIAL_8250_DETECT_IRQ 1
-#define CONFIG_SERIAL_8250_MULTIPORT 1
 #define CONFIG_SERIAL_8250_RSA 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
 
 /*
  * 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
 #define CONFIG_UNIX98_PTYS 1
 #undef CONFIG_LEGACY_PTYS
 #define CONFIG_CRASH_MODULE 1
 #define CONFIG_LP_CONSOLE 1
 #define CONFIG_PPDEV_MODULE 1
 #define CONFIG_TIPAR_MODULE 1
 #define CONFIG_LP_CONSOLE 1
 #define CONFIG_PPDEV_MODULE 1
 #define CONFIG_TIPAR_MODULE 1
-#undef CONFIG_QIC02_TAPE
 
 /*
  * IPMI
 
 /*
  * IPMI
 #define CONFIG_IPMI_DEVICE_INTERFACE_MODULE 1
 #define CONFIG_IPMI_SI_MODULE 1
 #define CONFIG_IPMI_WATCHDOG_MODULE 1
 #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
 
 /*
  * Watchdog Cards
  * Watchdog Device Drivers
  */
 #define CONFIG_SOFT_WATCHDOG_MODULE 1
  * 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_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_I8XX_TCO_MODULE 1
-#define CONFIG_SC1200_WDT_MODULE 1
-#undef CONFIG_SCx200_WDT
+#undef CONFIG_SC1200_WDT
 #undef CONFIG_60XX_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_W83627HF_WDT_MODULE 1
 #define CONFIG_W83877F_WDT_MODULE 1
+#define CONFIG_W83977F_WDT_MODULE 1
 #define CONFIG_MACHZ_WDT_MODULE 1
 #define CONFIG_MACHZ_WDT_MODULE 1
+#undef CONFIG_SBC_EPX_C3_WATCHDOG
 
 /*
  * ISA-based Watchdog Cards
  */
 
 /*
  * ISA-based Watchdog Cards
  */
-#define CONFIG_PCWATCHDOG_MODULE 1
+#undef CONFIG_PCWATCHDOG
 #undef CONFIG_MIXCOMWD
 #undef CONFIG_MIXCOMWD
-#define CONFIG_WDT_MODULE 1
-#undef CONFIG_WDT_501
+#undef CONFIG_WDT
 
 /*
  * PCI-based Watchdog Cards
 
 /*
  * PCI-based Watchdog Cards
  */
 #define CONFIG_USBPCWATCHDOG_MODULE 1
 #define CONFIG_HW_RANDOM_MODULE 1
  */
 #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
 #define CONFIG_RTC 1
 #define CONFIG_DTLK_MODULE 1
 #define CONFIG_R3964_MODULE 1
 /*
  * Ftape, the floppy tape device driver
  */
 /*
  * 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 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_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_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_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_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
 
 /*
  * 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_MWAVE_MODULE 1
+#define CONFIG_CS5535_GPIO_MODULE 1
 #undef CONFIG_RAW_DRIVER
 #undef CONFIG_RAW_DRIVER
+#define CONFIG_HPET 1
+#undef CONFIG_HPET_RTC_IRQ
+#undef CONFIG_HPET_MMAP
 #define CONFIG_HANGCHECK_TIMER_MODULE 1
 
 #define CONFIG_HANGCHECK_TIMER_MODULE 1
 
+/*
+ * TPM devices
+ */
+#undef CONFIG_TCG_TPM
+#undef CONFIG_TELCLOCK
+
 /*
  * I2C support
  */
 /*
  * I2C support
  */
  */
 #define CONFIG_I2C_ALGOBIT_MODULE 1
 #define CONFIG_I2C_ALGOPCF_MODULE 1
  */
 #define CONFIG_I2C_ALGOBIT_MODULE 1
 #define CONFIG_I2C_ALGOPCF_MODULE 1
+#define CONFIG_I2C_ALGOPCA_MODULE 1
 
 /*
  * I2C Hardware Bus support
 
 /*
  * I2C Hardware Bus support
 #define CONFIG_I2C_ALI1563_MODULE 1
 #define CONFIG_I2C_ALI15X3_MODULE 1
 #define CONFIG_I2C_AMD756_MODULE 1
 #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
 #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_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
 #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_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_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_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_ASB100_MODULE 1
+#define CONFIG_SENSORS_ATXP1_MODULE 1
 #define CONFIG_SENSORS_DS1621_MODULE 1
 #define CONFIG_SENSORS_DS1621_MODULE 1
+#define CONFIG_SENSORS_F71805F_MODULE 1
 #define CONFIG_SENSORS_FSCHER_MODULE 1
 #define CONFIG_SENSORS_FSCHER_MODULE 1
+#define CONFIG_SENSORS_FSCPOS_MODULE 1
 #define CONFIG_SENSORS_GL518SM_MODULE 1
 #define CONFIG_SENSORS_GL518SM_MODULE 1
+#define CONFIG_SENSORS_GL520SM_MODULE 1
 #define CONFIG_SENSORS_IT87_MODULE 1
 #define CONFIG_SENSORS_IT87_MODULE 1
+#define CONFIG_SENSORS_LM63_MODULE 1
 #define CONFIG_SENSORS_LM75_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_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_LM90_MODULE 1
+#define CONFIG_SENSORS_LM92_MODULE 1
 #define CONFIG_SENSORS_MAX1619_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_VIA686A_MODULE 1
+#define CONFIG_SENSORS_VT8231_MODULE 1
 #define CONFIG_SENSORS_W83781D_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
 #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
 
 /*
  * Misc devices
  * Multimedia devices
  */
 #define CONFIG_VIDEO_DEV_MODULE 1
  * 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_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_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
 #define CONFIG_VIDEO_SAA5246A_MODULE 1
 #define CONFIG_VIDEO_SAA5249_MODULE 1
 #define CONFIG_TUNER_3036_MODULE 1
 #define CONFIG_VIDEO_ZORAN_DC30_MODULE 1
 #define CONFIG_VIDEO_ZORAN_LML33_MODULE 1
 #define CONFIG_VIDEO_ZORAN_LML33R10_MODULE 1
 #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_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_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_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
  */
 
 /*
  * 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_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
  */
 
 /*
  * 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_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_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
 
 /*
  * 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_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
 #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
 #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_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_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
 #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_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
 #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
 #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
 #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
 #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_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
 #undef CONFIG_FONTS
 #define CONFIG_FONT_8x8 1
 #define CONFIG_FONT_8x16 1
 #undef CONFIG_LOGO_LINUX_MONO
 #undef CONFIG_LOGO_LINUX_VGA16
 #define CONFIG_LOGO_LINUX_CLUT224 1
 #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
 
 /*
  * Sound
 #define CONFIG_SND_OSSEMUL 1
 #define CONFIG_SND_MIXER_OSS_MODULE 1
 #define CONFIG_SND_PCM_OSS_MODULE 1
 #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_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
 
 #undef CONFIG_SND_VERBOSE_PRINTK
 #undef CONFIG_SND_DEBUG
 
 #define CONFIG_SND_OPL3_LIB_MODULE 1
 #define CONFIG_SND_OPL4_LIB_MODULE 1
 #define CONFIG_SND_VX_LIB_MODULE 1
 #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
 #define CONFIG_SND_DUMMY_MODULE 1
 #define CONFIG_SND_VIRMIDI_MODULE 1
 #define CONFIG_SND_MTPAV_MODULE 1
 /*
  * ISA devices
  */
 /*
  * 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_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_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_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
 #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
  */
 
 /*
  * 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_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
 #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_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_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_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_MODULE 1
+#define CONFIG_SND_FM801_TEA575X_BOOL 1
 #define CONFIG_SND_FM801_TEA575X_MODULE 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_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_SONICVIBES_MODULE 1
+#define CONFIG_SND_TRIDENT_MODULE 1
 #define CONFIG_SND_VIA82XX_MODULE 1
 #define CONFIG_SND_VIA82XX_MODULE 1
+#define CONFIG_SND_VIA82XX_MODEM_MODULE 1
 #define CONFIG_SND_VX222_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_AUDIO_MODULE 1
+#define CONFIG_SND_USB_USX2Y_MODULE 1
 
 /*
  * PCMCIA devices
  */
 #undef CONFIG_SND_VXPOCKET
 
 /*
  * PCMCIA devices
  */
 #undef CONFIG_SND_VXPOCKET
-#undef CONFIG_SND_VXP440
-#define CONFIG_SND_PDAUDIOCF_MODULE 1
+#undef CONFIG_SND_PDAUDIOCF
 
 /*
  * Open Sound System
 
 /*
  * Open Sound System
 /*
  * USB support
  */
 /*
  * 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
 
 #define CONFIG_USB 1
 #undef CONFIG_USB_DEBUG
 
 #define CONFIG_USB_DEVICEFS 1
 #undef CONFIG_USB_BANDWIDTH
 #undef CONFIG_USB_DYNAMIC_MINORS
 #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
 
 /*
  * USB Host Controller Drivers
 #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_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
 #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_UHCI_HCD_MODULE 1
+#define CONFIG_USB_SL811_HCD_MODULE 1
+#define CONFIG_USB_SL811_CS_MODULE 1
 
 /*
  * USB Device Class drivers
  */
 
 /*
  * 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_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_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
  */
 #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
 #define CONFIG_HID_FF 1
 #define CONFIG_HID_PID 1
 #define CONFIG_LOGITECH_FF 1
 #define CONFIG_USB_HIDDEV 1
 #define CONFIG_USB_AIPTEK_MODULE 1
 #define CONFIG_USB_WACOM_MODULE 1
 #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_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_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
 
 /*
  * 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
  */
 #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_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_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
 
 /*
  * USB port drivers
  */
 #define CONFIG_USB_SERIAL_MODULE 1
 #define CONFIG_USB_SERIAL_GENERIC 1
  */
 #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_BELKIN_MODULE 1
+#define CONFIG_USB_SERIAL_WHITEHEAT_MODULE 1
 #define CONFIG_USB_SERIAL_DIGI_ACCELEPORT_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_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_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
 #define CONFIG_USB_SERIAL_KEYSPAN_PDA_MODULE 1
 #define CONFIG_USB_SERIAL_KEYSPAN_MODULE 1
 #define CONFIG_USB_SERIAL_KEYSPAN_MPR 1
 #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_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_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_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_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
 
 #define CONFIG_USB_SERIAL_OMNINET_MODULE 1
 #define CONFIG_USB_EZUSB 1
 
  * USB Miscellaneous drivers
  */
 #define CONFIG_USB_EMI62_MODULE 1
  * 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_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_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
 
 #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
 
 /*
  * 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
  */
 /*
  * File systems
  */
 #define CONFIG_EXT2_FS_XATTR 1
 #define CONFIG_EXT2_FS_POSIX_ACL 1
 #define CONFIG_EXT2_FS_SECURITY 1
 #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
 #define CONFIG_EXT3_FS_MODULE 1
 #define CONFIG_EXT3_FS_XATTR 1
 #define CONFIG_EXT3_FS_POSIX_ACL 1
 #define CONFIG_REISERFS_FS_SECURITY 1
 #define CONFIG_JFS_FS_MODULE 1
 #define CONFIG_JFS_POSIX_ACL 1
 #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_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
 #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_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_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_AUTOFS_FS_MODULE 1
 #define CONFIG_AUTOFS4_FS_MODULE 1
+#define CONFIG_FUSE_FS_MODULE 1
 
 /*
  * CD-ROM/DVD Filesystems
 
 /*
  * CD-ROM/DVD Filesystems
 #define CONFIG_ZISOFS 1
 #define CONFIG_ZISOFS_FS 1
 #define CONFIG_UDF_FS_MODULE 1
 #define CONFIG_ZISOFS 1
 #define CONFIG_ZISOFS_FS 1
 #define CONFIG_UDF_FS_MODULE 1
+#define CONFIG_UDF_NLS 1
 
 /*
  * DOS/FAT/NT Filesystems
 
 /*
  * DOS/FAT/NT Filesystems
 #define CONFIG_FAT_FS_MODULE 1
 #define CONFIG_MSDOS_FS_MODULE 1
 #define CONFIG_VFAT_FS_MODULE 1
 #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
 
 /*
 #undef CONFIG_NTFS_FS
 
 /*
 #define CONFIG_PROC_FS 1
 #define CONFIG_PROC_KCORE 1
 #define CONFIG_SYSFS 1
 #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_TMPFS 1
 #define CONFIG_HUGETLBFS 1
 #define CONFIG_HUGETLB_PAGE 1
 #define CONFIG_RAMFS 1
+#define CONFIG_CONFIGFS_FS_MODULE 1
 
 /*
  * Miscellaneous filesystems
 
 /*
  * Miscellaneous filesystems
 #undef CONFIG_JFFS_FS
 #define CONFIG_JFFS2_FS_MODULE 1
 #define CONFIG_JFFS2_FS_DEBUG 0
 #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_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
 #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
 #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
 
 /*
  * 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_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 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_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_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_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
 #define CONFIG_NCP_FS_MODULE 1
 #define CONFIG_NCPFS_PACKET_SIGNING 1
 #define CONFIG_NCPFS_IOCTL_LOCKING 1
 #define CONFIG_NCPFS_SMALLDOS 1
 #define CONFIG_NCPFS_NLS 1
 #define CONFIG_NCPFS_EXTRAS 1
 #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
 #undef CONFIG_AFS_FS
+#define CONFIG_9P_FS_MODULE 1
 
 /*
  * Partition Types
 
 /*
  * Partition Types
 #define CONFIG_PARTITION_ADVANCED 1
 #undef CONFIG_ACORN_PARTITION
 #define CONFIG_OSF_PARTITION 1
 #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
 #undef CONFIG_ATARI_PARTITION
 #define CONFIG_MAC_PARTITION 1
 #define CONFIG_MSDOS_PARTITION 1
 #define CONFIG_SOLARIS_X86_PARTITION 1
 #define CONFIG_UNIXWARE_DISKLABEL 1
 #undef CONFIG_LDM_PARTITION
 #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_SGI_PARTITION 1
 #undef CONFIG_ULTRIX_PARTITION
 #define CONFIG_SUN_PARTITION 1
+#define CONFIG_KARMA_PARTITION 1
 #define CONFIG_EFI_PARTITION 1
 
 /*
 #define CONFIG_EFI_PARTITION 1
 
 /*
  */
 #define CONFIG_NLS 1
 #define CONFIG_NLS_DEFAULT "utf8"
  */
 #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
 #define CONFIG_NLS_CODEPAGE_737_MODULE 1
 #define CONFIG_NLS_CODEPAGE_775_MODULE 1
 #define CONFIG_NLS_CODEPAGE_850_MODULE 1
 #define CONFIG_NLS_ISO8859_8_MODULE 1
 #define CONFIG_NLS_CODEPAGE_1250_MODULE 1
 #define CONFIG_NLS_CODEPAGE_1251_MODULE 1
 #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
 #define CONFIG_NLS_ISO8859_1_MODULE 1
 #define CONFIG_NLS_ISO8859_2_MODULE 1
 #define CONFIG_NLS_ISO8859_3_MODULE 1
 #define CONFIG_NLS_UTF8_MODULE 1
 
 /*
 #define CONFIG_NLS_UTF8_MODULE 1
 
 /*
- * Profiling support
+ * Instrumentation Support
  */
 #define CONFIG_PROFILING 1
 #define CONFIG_OPROFILE_MODULE 1
  */
 #define CONFIG_PROFILING 1
 #define CONFIG_OPROFILE_MODULE 1
+#define CONFIG_KPROBES 1
 
 /*
  * Kernel hacking
  */
 
 /*
  * Kernel hacking
  */
+#undef CONFIG_PRINTK_TIME
+#define CONFIG_MAGIC_SYSRQ 1
 #define CONFIG_DEBUG_KERNEL 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
 #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
 #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
 #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_X86_FIND_SMP_CONFIG 1
 #define CONFIG_X86_MPPARSE 1
+#define CONFIG_DOUBLEFAULT 1
 
 /*
  * Security options
  */
 
 /*
  * 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 1
 #define CONFIG_SECURITY_NETWORK 1
+#define CONFIG_SECURITY_NETWORK_XFRM 1
 #define CONFIG_SECURITY_CAPABILITIES 1
 #undef CONFIG_SECURITY_ROOTPLUG
 #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 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
 #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
 
 /*
  * Cryptographic options
 #define CONFIG_CRYPTO_NULL_MODULE 1
 #define CONFIG_CRYPTO_MD4_MODULE 1
 #define CONFIG_CRYPTO_MD5 1
 #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_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_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_CAST5_MODULE 1
 #define CONFIG_CRYPTO_CAST6_MODULE 1
+#define CONFIG_CRYPTO_TEA_MODULE 1
 #define CONFIG_CRYPTO_ARC4_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_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
  */
 
 /*
  * 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_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_BIOS_REBOOT 1
-#define CONFIG_X86_TRAMPOLINE 1
-#define CONFIG_X86_STD_RESOURCES 1
-#define CONFIG_PC 1
+#define CONFIG_KTIME_SCALAR 1
index 93535f0..9269df7 100644 (file)
@@ -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_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
 
 /* compatibility with older code */
 #define SPARC_ETH_GSET         ETHTOOL_GSET
index 0149995..a4c919c 100644 (file)
@@ -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);
 }
 {
        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
 #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
index a308228..83ece62 100644 (file)
@@ -100,7 +100,11 @@ static inline int gfp_zone(gfp_t gfp)
  */
 
 #ifndef HAVE_ARCH_FREE_PAGE
  */
 
 #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 *
 #endif
 
 extern struct page *
index 892c4ea..8f2bcfb 100644 (file)
@@ -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);
 
 /* 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; }
 
 #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)
 {
 
 static inline void *kmap(struct page *page)
 {
index d37c8d8..f559a71 100644 (file)
@@ -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);
 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);
 void idr_remove(struct idr *idp, int id);
 void idr_destroy(struct idr *idp);
 void idr_init(struct idr *idp);
index 2c08fdc..d55ff51 100644 (file)
@@ -58,6 +58,12 @@ extern void disable_irq(unsigned int irq);
 extern void enable_irq(unsigned int irq);
 #endif
 
 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))
 #ifndef __ARCH_SET_SOFTIRQ_PENDING
 #define set_softirq_pending(x) (local_softirq_pending() = (x))
 #define or_softirq_pending(x)  (local_softirq_pending() |= (x))
index e4183fa..51eea5b 100644 (file)
@@ -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 */
 #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
 
 #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 */
 
 #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
 #ifdef CONFIG_PROC_FS
 void vm_stat_account(struct mm_struct *, unsigned long, struct file *, long);
 #else
index f4169bb..c5b97cf 100644 (file)
@@ -232,6 +232,7 @@ enum netdev_state_t
        __LINK_STATE_RX_SCHED,
        __LINK_STATE_LINKWATCH_PENDING,
        __LINK_STATE_DORMANT,
        __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_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_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;
 
 
        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 */
 
        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;
        /* 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 */
  * 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.
         */
        /* 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 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;
 };
        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 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);
 
 
 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);
 }
 
        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)
 {
 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);
        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) */
 }
 
 /* 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 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
 #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);
 
 
 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 */
 #endif /* __KERNEL__ */
 
 #endif /* _LINUX_DEV_H */
index a75b84b..178a97e 100644 (file)
@@ -47,18 +47,26 @@ enum nf_br_hook_priorities {
 #define BRNF_BRIDGED                   0x08
 #define BRNF_NF_BRIDGE_PREROUTING      0x10
 
 #define BRNF_BRIDGED                   0x08
 #define BRNF_NF_BRIDGE_PREROUTING      0x10
 
-
 /* Only used in br_forward.c */
 /* 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)) {
        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);
                        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);
                        memcpy(skb->data - 16, skb->nf_bridge->data, 16);
+               }
        }
        }
+       return 0;
 }
 
 /* This is called by the IP fragmenting code and it ensures there is
 }
 
 /* This is called by the IP fragmenting code and it ensures there is
index 0d514b2..6c33ee6 100644 (file)
 #include <linux/types.h>
 #include <linux/spinlock.h>
 #include <asm/atomic.h>
 #include <linux/types.h>
 #include <linux/spinlock.h>
 #include <asm/atomic.h>
+
+#ifdef CONFIG_XEN
+#include <xen/interface/xenoprof.h>
+#endif
  
 struct super_block;
 struct dentry;
  
 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);
        /* 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. */
        /* 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 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
 
 /**
  * Create a file of the given name as a child of the given root, with
index 4550ab0..2bd4cba 100644 (file)
 #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_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
 #define PCI_DEVICE_ID_VIA_8363_0       0x0305
 #define PCI_DEVICE_ID_VIA_P4M800CE     0x0314
 #define PCI_DEVICE_ID_VIA_8371_0       0x0391
 #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_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
 #define PCI_DEVICE_ID_VIA_82C586_0     0x0586
 #define PCI_DEVICE_ID_VIA_82C596       0x0596
 #define PCI_DEVICE_ID_VIA_82C597_0     0x0597
 #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_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_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
 #define PCI_DEVICE_ID_VIA_8371_1       0x8391
 #define PCI_DEVICE_ID_VIA_82C598_1     0x8598
 #define PCI_DEVICE_ID_VIA_838X_1       0xB188
index bb01f8b..ba2a866 100644 (file)
@@ -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_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
 
 #endif
index c219f2f..e5f6a68 100644 (file)
@@ -134,9 +134,10 @@ struct skb_frag_struct {
 struct skb_shared_info {
        atomic_t        dataref;
        unsigned short  nr_frags;
 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];
        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,
 };
 
        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
 /** 
  *     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
  *     @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
  *     @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,
                                nfctinfo:3;
        __u8                    pkt_type:3,
                                fclone:2,
+#ifndef CONFIG_XEN
                                ipvs_property:1;
                                ipvs_property:1;
+#else
+                               ipvs_property:1,
+                               proto_data_valid:1,
+                               proto_csum_blank:1;
+#endif
        __be16                  protocol;
 
        void                    (*destructor)(struct sk_buff *skb);
        __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,
 
 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);
 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
 
 #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)
 {
 
 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.
  *
  *     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)
 {
  */
 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)
 {
 
 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)
 }
 
 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;
 }
 
        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
 /**
  *     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
        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
 
 /**
 #endif
 
 /**
@@ -1161,18 +1194,34 @@ static inline int skb_can_coalesce(struct sk_buff *skb, int i,
        return 0;
 }
 
        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
 /**
  *     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.
  */
  *
  *     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);
                                 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)
 
 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 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 */
 #endif /* __KERNEL__ */
 #endif /* _LINUX_SKBUFF_H */
index 8793155..f13f49a 100644 (file)
@@ -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);
 
                             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);
 extern int is_orphaned_pgrp(int pgrp);
 extern int is_ignored(int sig);
 extern int tty_signal(int sig, struct tty_struct *tty);
index b94d1ad..75b5b93 100644 (file)
@@ -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);
 
                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)
 {
 
 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,
 }
 
 extern int tc_classify(struct sk_buff *skb, struct tcf_proto *tp,
index 6dc5970..d516c58 100644 (file)
@@ -37,6 +37,9 @@
 struct net_protocol {
        int                     (*handler)(struct sk_buff *skb);
        void                    (*err_handler)(struct sk_buff *skb, u32 info);
 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;
 };
 
        int                     no_policy;
 };
 
index aa6033c..225dcea 100644 (file)
@@ -405,19 +405,6 @@ static inline int sctp_list_single_entry(struct list_head *head)
        return ((head->next != head) && (head->next == head->prev));
 }
 
        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)
 {
 /* Generate a random jitter in the range of -50% ~ +50% of input RTO. */
 static inline __s32 sctp_jitter(__u32 rto)
 {
index 1eac3d0..de313de 100644 (file)
@@ -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 *,
                                      __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 *,
 struct sctp_chunk *sctp_make_abort_violation(const struct sctp_association *,
                                   const struct sctp_chunk *,
                                   const __u8 *,
index f6e3f99..924d348 100644 (file)
@@ -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;
 {
        __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;
        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;
        }
 }
 
        }
 }
 
index c0f8840..8fa2462 100644 (file)
@@ -568,13 +568,13 @@ struct tcp_skb_cb {
  */
 static inline int tcp_skb_pcount(const struct sk_buff *skb)
 {
  */
 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)
 {
 }
 
 /* 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,
 }
 
 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_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);
 #ifdef CONFIG_PROC_FS
 extern int  tcp4_proc_init(void);
 extern void tcp4_proc_exit(void);
index 0196291..e5618b9 100644 (file)
@@ -43,10 +43,6 @@ enum iscsi_uevent_e {
        ISCSI_UEVENT_GET_STATS          = UEVENT_BASE + 10,
        ISCSI_UEVENT_GET_PARAM          = UEVENT_BASE + 11,
 
        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,
        /* 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 {
                        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;
                } d_session;
                struct msg_create_conn {
-                       uint32_t        sid;
+                       uint64_t        session_handle;
                        uint32_t        cid;
                        uint32_t        cid;
+                       uint32_t        sid;
                } c_conn;
                struct msg_bind_conn {
                } 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        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        cid;
                } d_conn;
                struct msg_send_pdu {
-                       uint32_t        sid;
-                       uint32_t        cid;
                        uint32_t        hdr_size;
                        uint32_t        data_size;
                        uint32_t        hdr_size;
                        uint32_t        data_size;
+                       uint64_t        conn_handle;
                } send_pdu;
                struct msg_set_param {
                } send_pdu;
                struct msg_set_param {
-                       uint32_t        sid;
-                       uint32_t        cid;
+                       uint64_t        conn_handle;
                        uint32_t        param; /* enum iscsi_param */
                        uint32_t        param; /* enum iscsi_param */
-                       uint32_t        len;
+                       uint32_t        value;
                } set_param;
                struct msg_start_conn {
                } set_param;
                struct msg_start_conn {
-                       uint32_t        sid;
-                       uint32_t        cid;
+                       uint64_t        conn_handle;
                } start_conn;
                struct msg_stop_conn {
                } 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 {
                        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;
                } 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 */
        } u;
        union {
                /* messages k -> u */
+               uint64_t                handle;
                int                     retcode;
                struct msg_create_session_ret {
                int                     retcode;
                struct msg_create_session_ret {
+                       uint64_t        session_handle;
                        uint32_t        sid;
                        uint32_t        sid;
-                       uint32_t        host_no;
                } c_session_ret;
                } c_session_ret;
-               struct msg_create_conn_ret {
-                       uint32_t        sid;
-                       uint32_t        cid;
-               } c_conn_ret;
                struct msg_recv_req {
                struct msg_recv_req {
-                       uint32_t        sid;
-                       uint32_t        cid;
                        uint64_t        recv_handle;
                        uint64_t        recv_handle;
+                       uint64_t        conn_handle;
                } recv_req;
                struct msg_conn_error {
                } recv_req;
                struct msg_conn_error {
-                       uint32_t        sid;
-                       uint32_t        cid;
+                       uint64_t        conn_handle;
                        uint32_t        error; /* enum iscsi_err */
                } connerror;
                        uint32_t        error; /* enum iscsi_err */
                } connerror;
-               struct msg_transport_connect_ret {
-                       uint64_t        handle;
-               } ep_connect_ret;
        } r;
 } __attribute__ ((aligned (sizeof(uint64_t))));
 
        } 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_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 {
 };
 
 /*
  * 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)
 
 #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
  * 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
 #define STOP_CONN_RECOVER      0x3
 
 #define ISCSI_STATS_CUSTOM_MAX         32
index 02f6e4b..4feda05 100644 (file)
@@ -21,6 +21,8 @@
 #ifndef ISCSI_PROTO_H
 #define ISCSI_PROTO_H
 
 #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 */
 #define ISCSI_DRAFT20_VERSION  0x00
 
 /* default iSCSI listen port for incoming connections */
index b684426..b41cf07 100644 (file)
@@ -2,7 +2,7 @@
  * iSCSI transport class definitions
  *
  * Copyright (C) IBM Corporation, 2004
  * 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
  *
  * Copyright (C) Dmitry Yusupov, 2004 - 2005
  * Copyright (C) Alex Aizman, 2004 - 2005
  *
 #include <scsi/iscsi_if.h>
 
 struct scsi_transport_template;
 #include <scsi/iscsi_if.h>
 
 struct scsi_transport_template;
-struct iscsi_transport;
 struct Scsi_Host;
 struct mempool_zone;
 struct iscsi_cls_conn;
 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
 
 /**
  * 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.
  * @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
  */
  *
  * Template API provided by iSCSI Transport
  */
@@ -75,58 +53,38 @@ struct iscsi_transport {
        struct module *owner;
        char *name;
        unsigned int caps;
        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;
        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 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;
        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,
        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,
        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_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);
        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);
 
 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;
 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;
        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)
 
 #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 iscsi_cls_session {
        struct list_head sess_list;             /* item in session_list */
-       struct list_head host_list;
        struct iscsi_transport *transport;
        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 */
 };
 
        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)
 
 #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,
 /*
  * 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 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
 
 #endif
index d29e3d3..d45170b 100644 (file)
@@ -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,
 {
        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;
                }
                        free_irq(*irq_table, (void *) irq_table);
                        return *irq_table;
                }
index 0b46a5d..17ab322 100644 (file)
@@ -35,6 +35,7 @@ config PREEMPT_VOLUNTARY
 
 config PREEMPT
        bool "Preemptible Kernel (Low-Latency Desktop)"
 
 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)
        help
          This option reduces the latency of the kernel by making
          all kernel code (that is not executing in a critical section)
index fcaaa99..471d19f 100644 (file)
@@ -280,6 +280,9 @@ static inline int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
                if (retval)
                        goto out;
        }
                if (retval)
                        goto out;
        }
+#ifdef arch_dup_mmap
+       arch_dup_mmap(mm, oldmm);
+#endif
        retval = 0;
 out:
        up_write(&mm->mmap_sem);
        retval = 0;
 out:
        up_write(&mm->mmap_sem);
index 9ddf501..c27bb56 100644 (file)
@@ -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;
        /* 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);
                /*
        if (lock_ptr != 0) {
                spin_lock(lock_ptr);
                /*
index 1279e34..97d5559 100644 (file)
@@ -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 */
        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 {
 
                /* add new interrupt at end of irq queue */
                do {
@@ -222,10 +218,7 @@ int setup_irq(unsigned int irq, struct irqaction * new)
        }
 
        *p = 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 |
        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;
        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;
 
        struct irqaction **p;
        unsigned long flags;
 
-       WARN_ON(in_interrupt());
        if (irq >= NR_IRQS)
                return;
 
        if (irq >= NR_IRQS)
                return;
 
index 7df9abd..f9353e9 100644 (file)
@@ -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) {
                        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);
        }
                if (action_ret != IRQ_NONE)
                        report_bad_irq(irq, desc, action_ret);
        }
index 60bff8b..026ba1f 100644 (file)
@@ -4189,17 +4189,22 @@ asmlinkage long sys_sched_yield(void)
        return 0;
 }
 
        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.
         */
 {
        /*
         * 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();
        do {
                add_preempt_count(PREEMPT_ACTIVE);
                schedule();
@@ -4209,13 +4214,12 @@ static inline void __cond_resched(void)
 
 int __sched cond_resched(void)
 {
 
 int __sched cond_resched(void)
 {
-       if (need_resched()) {
+       if (need_resched() && __resched_legal(0)) {
                __cond_resched();
                return 1;
        }
        return 0;
 }
                __cond_resched();
                return 1;
        }
        return 0;
 }
-
 EXPORT_SYMBOL(cond_resched);
 
 /*
 EXPORT_SYMBOL(cond_resched);
 
 /*
@@ -4236,7 +4240,7 @@ int cond_resched_lock(spinlock_t *lock)
                ret = 1;
                spin_lock(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();
                _raw_spin_unlock(lock);
                preempt_enable_no_resched();
                __cond_resched();
@@ -4245,14 +4249,13 @@ int cond_resched_lock(spinlock_t *lock)
        }
        return ret;
 }
        }
        return ret;
 }
-
 EXPORT_SYMBOL(cond_resched_lock);
 
 int __sched cond_resched_softirq(void)
 {
        BUG_ON(!in_softirq());
 
 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();
                __local_bh_enable();
                __cond_resched();
                local_bh_disable();
@@ -4260,10 +4263,8 @@ int __sched cond_resched_softirq(void)
        }
        return 0;
 }
        }
        return 0;
 }
-
 EXPORT_SYMBOL(cond_resched_softirq);
 
 EXPORT_SYMBOL(cond_resched_softirq);
 
-
 /**
  * yield - yield the current processor to other threads.
  *
 /**
  * yield - yield the current processor to other threads.
  *
index dcfb5d7..51cacd1 100644 (file)
@@ -111,7 +111,6 @@ static int stop_machine(void)
        /* If some failed, kill them all. */
        if (ret < 0) {
                stopmachine_set_state(STOPMACHINE_EXIT);
        /* If some failed, kill them all. */
        if (ret < 0) {
                stopmachine_set_state(STOPMACHINE_EXIT);
-               up(&stopmachine_mutex);
                return ret;
        }
 
                return ret;
        }
 
index 2f8cdbe..20a4bca 100644 (file)
@@ -543,6 +543,22 @@ found:
        }
        spin_unlock(&base->lock);
 
        }
        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
        /*
         * 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;
  */
 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);
 }
 
        return vx_map_pid(pid);
 }
 
@@ -1025,7 +1013,7 @@ asmlinkage long do_getxpid(long *ppid)
        *ppid = sys_getppid();
        return sys_getpid();
 }
        *ppid = sys_getppid();
        return sys_getpid();
 }
-  
+
 #else /* _alpha_ */
 
 asmlinkage long sys_getuid(void)
 #else /* _alpha_ */
 
 asmlinkage long sys_getuid(void)
index b830c9a..033ff7c 100644 (file)
@@ -48,6 +48,9 @@ obj-$(CONFIG_TEXTSEARCH_BM) += ts_bm.o
 obj-$(CONFIG_TEXTSEARCH_FSM) += ts_fsm.o
 
 obj-$(CONFIG_SWIOTLB) += swiotlb.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
 
 hostprogs-y    := gen_crc32table
 clean-files    := crc32table.h
index de19030..4d09681 100644 (file)
--- a/lib/idr.c
+++ b/lib/idr.c
@@ -29,6 +29,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #endif
 #include <linux/init.h>
 #include <linux/module.h>
 #endif
+#include <linux/err.h>
 #include <linux/string.h>
 #include <linux/idr.h>
 
 #include <linux/string.h>
 #include <linux/idr.h>
 
@@ -398,6 +399,48 @@ void *idr_find(struct idr *idp, int id)
 }
 EXPORT_SYMBOL(idr_find);
 
 }
 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)
 {
 static void idr_cache_ctor(void * idr_layer, kmem_cache_t *idr_layer_cache,
                unsigned long flags)
 {
index 34022dd..8ebd8ea 100644 (file)
@@ -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)
 
 
 #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;
 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");
 
 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)
 }
 
 int _raw_read_trylock(rwlock_t *lock)
@@ -222,6 +223,7 @@ static inline void debug_write_unlock(rwlock_t *lock)
        lock->owner_cpu = -1;
 }
 
        lock->owner_cpu = -1;
 }
 
+#if 0          /* This can cause lockups */
 static void __write_lock_debug(rwlock_t *lock)
 {
        int print_once = 1;
 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);
 
 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);
 }
 
        debug_write_lock_after(lock);
 }
 
index c4c1ac5..7917265 100644 (file)
@@ -112,15 +112,14 @@ static int subpattern(u8 *pattern, int i, int j, int g)
        return ret;
 }
 
        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++)
 {
        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 */
 
        /* 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;
        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);
        memcpy(bm->pattern, pattern, len);
+       compute_prefix_tbl(bm);
 
        return conf;
 }
 
        return conf;
 }
index 67b3f74..ab10075 100644 (file)
@@ -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"
 # 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
 
 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.
 # 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
 #
 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
 
 #
 # support for page migration
index 4b04495..96f354e 100644 (file)
@@ -518,18 +518,11 @@ EXPORT_SYMBOL(unlock_page);
  */
 void end_page_writeback(struct page *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 (!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);
        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;
        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;
                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_.
 
                /*
                 * 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.
                 */
                 * 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) {
 
                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;
                }
 
                        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);
                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;
                }
                        page_cache_release(page);
                        continue;
                }
-               if (likely(copied > 0)) {
+zero_length_segment:
+               if (likely(copied >= 0)) {
                        if (!status)
                                status = copied;
 
                        if (!status)
                                status = copied;
 
index 13793ba..efd0142 100644 (file)
@@ -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;
 
        const struct iovec *iov = *iovp;
        size_t base = *basep;
 
-       while (bytes) {
+       do {
                int copy = min(bytes, iov->iov_len - base);
 
                bytes -= copy;
                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;
                }
                        iov++;
                        base = 0;
                }
-       }
+       } while (bytes);
        *iovp = iov;
        *basep = base;
 }
        *iovp = iov;
        *basep = base;
 }
index 9b274fd..a02c6de 100644 (file)
@@ -142,6 +142,17 @@ start:
        return vaddr;
 }
 
        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;
 void fastcall *kmap_high(struct page *page)
 {
        unsigned long vaddr;
index 1bd0404..9f75bb2 100644 (file)
@@ -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))) {
         * 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;
        }
 
                return NULL;
        }
 
@@ -1017,6 +1018,26 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
                        continue;
                }
 
                        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;
                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);
 
 }
 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
 /*
  * handle_pte_fault chooses page fault handler according to an entry
  * which was read non-atomically.  Before making any commitment, on
index c34750c..f6940d1 100644 (file)
--- 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;
 
        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)
        /* 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;
        unsigned long flags;
        struct rb_node ** rb_link, * rb_parent;
        pgoff_t pgoff = addr >> PAGE_SHIFT;
+       int error;
 
        len = PAGE_ALIGN(len);
        if (!len)
 
        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;
 
        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?
         */
        /*
         * 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;
 
                !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))
        /* 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;
 
        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);
        lru_add_drain();
        flush_cache_mm(mm);
        tlb = tlb_gather_mmu(mm, 1);
index b747cbf..5581dd1 100644 (file)
@@ -439,7 +439,8 @@ static void __free_pages_ok(struct page *page, unsigned int order)
        int i;
        int reserved = 0;
 
        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<<order);
        if (!PageHighMem(page))
                mutex_debug_check_no_locks_freed(page_address(page),
                                                 PAGE_SIZE<<order);
@@ -734,7 +735,8 @@ static void fastcall free_hot_cold_page(struct page *page, int cold)
        struct per_cpu_pages *pcp;
        unsigned long flags;
 
        struct per_cpu_pages *pcp;
        unsigned long flags;
 
-       arch_free_page(page, 0);
+       if (arch_free_page(page, 0))
+               return;
 
        if (PageAnon(page))
                page->mapping = NULL;
 
        if (PageAnon(page))
                page->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;
        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();
        }
        local_irq_restore(flags);
        put_cpu();
index c4b6d0a..4842716 100644 (file)
@@ -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);
                list_move(&my_work->list, &pdflush_list);
                my_work->when_i_went_to_sleep = jiffies;
                spin_unlock_irq(&pdflush_lock);
-
                schedule();
                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)) {
                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) {
                        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);
                        continue;
                }
                spin_unlock_irq(&pdflush_lock);
index 234b2f1..a3bed3f 100644 (file)
@@ -441,11 +441,12 @@ int swap_type_of(dev_t device)
 
                if (!(swap_info[i].flags & SWP_WRITEOK))
                        continue;
 
                if (!(swap_info[i].flags & SWP_WRITEOK))
                        continue;
+
                if (!device) {
                        spin_unlock(&swap_lock);
                        return i;
                }
                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);
                if (S_ISBLK(inode->i_mode) &&
                    device == MKDEV(imajor(inode), iminor(inode))) {
                        spin_unlock(&swap_lock);
index 3948949..729abc4 100644 (file)
@@ -67,10 +67,6 @@ static struct packet_type vlan_packet_type = {
        .func = vlan_skb_recv, /* VLAN receive method */
 };
 
        .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. */
 
 /*
 /* 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->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.
 
        /* need 4 bytes for extra VLAN header info,
         * hope the underlying device can handle it.
index 72d8529..4f44e98 100644 (file)
@@ -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;
        }
                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) {
        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 "
                        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. */
 }
 
 /* The neighbour entry n->lock is held. */
index 0c88a2a..f8dbcee 100644 (file)
@@ -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)
        struct net_bridge *br = netdev_priv(dev);
 
        if (data)
-               br->feature_mask |= NETIF_F_IP_CSUM;
+               br->feature_mask |= NETIF_F_NO_CSUM;
        else
        else
-               br->feature_mask &= ~NETIF_F_IP_CSUM;
+               br->feature_mask &= ~NETIF_F_ALL_CSUM;
 
        br_features_recompute(br);
        return 0;
 
        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->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;
 }
 }
index 56f3aa4..056df7c 100644 (file)
@@ -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 */
 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. */
                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
 #endif
-               skb_push(skb, ETH_HLEN);
+               {
+                       skb_push(skb, ETH_HLEN);
 
 
-               dev_queue_xmit(skb);
+                       dev_queue_xmit(skb);
+               }
        }
 
        return 0;
        }
 
        return 0;
index f5d47bf..f55ef68 100644 (file)
@@ -372,17 +372,28 @@ void br_features_recompute(struct net_bridge *br)
        struct net_bridge_port *p;
        unsigned long features, checksum;
 
        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) {
 
        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;
                        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 */
 }
 
 /* called with RTNL */
index 3da9264..a642727 100644 (file)
@@ -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 &&
 {
        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);
                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 &&
        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)
 #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)
index ee5a517..ae70123 100644 (file)
@@ -75,6 +75,9 @@ static void ulog_send(unsigned int nlgroup)
        if (timer_pending(&ub->timer))
                del_timer(&ub->timer);
 
        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;
        /* last nlmsg needs NLMSG_DONE */
        if (ub->qlen > 1)
                ub->lastnlh->nlmsg_type = NLMSG_DONE;
index eb965a7..d8bab16 100644 (file)
 #include <net/iw_handler.h>
 #include <asm/current.h>
 #include <linux/audit.h>
 #include <net/iw_handler.h>
 #include <asm/current.h>
 #include <linux/audit.h>
+#include <linux/err.h>
 #include <linux/vs_network.h>
 
 #include <linux/vs_network.h>
 
+#ifdef CONFIG_XEN
+#include <net/ip.h>
+#include <linux/tcp.h>
+#include <linux/udp.h>
+#endif
+
 /*
  *     The list of packet types we will receive (as opposed to discard)
  *     and the routines to invoke.
 /*
  *     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.
  */
 
  *     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;
 
 {
        struct packet_type *ptype;
 
@@ -1180,6 +1187,45 @@ out:
        return ret;
 }
 
        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)
 /* 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
 
 #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) {      \
        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) {      \
        }                                               \
 }
 
 #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
 /**
  *     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;
 
        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) &&
        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,
                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)) &&
         */
        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 &&
                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;
 
             (!(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. 
         */
        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 
 
        /* 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...
 
        /* 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.
           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)) {
                        HARD_TX_LOCK(dev, cpu);
 
                        if (!netif_queue_stopped(dev)) {
-                               if (netdev_nit)
-                                       dev_queue_xmit_nit(skb, dev);
-
                                rc = 0;
                                rc = 0;
-                               if (!dev->hard_start_xmit(skb, dev)) {
+                               if (!dev_hard_start_xmit(skb, dev)) {
                                        HARD_TX_UNLOCK(dev);
                                        goto out;
                                }
                                        HARD_TX_UNLOCK(dev);
                                        goto out;
                                }
@@ -1423,13 +1547,13 @@ int dev_queue_xmit(struct sk_buff *skb)
        }
 
        rc = -ENETDOWN;
        }
 
        rc = -ENETDOWN;
-       local_bh_enable();
+       rcu_read_unlock_bh();
 
 out_kfree_skb:
        kfree_skb(skb);
        return rc;
 out:
 
 out_kfree_skb:
        kfree_skb(skb);
        return rc;
 out:
-       local_bh_enable();
+       rcu_read_unlock_bh();
        return rc;
 }
 
        return rc;
 }
 
@@ -1707,6 +1831,19 @@ int netif_receive_skb(struct sk_buff *skb)
        }
 #endif
 
        }
 #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) 
        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);
        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);
        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) &&
 
        /* 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;
                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(__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);
 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(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);
 
 #if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
 EXPORT_SYMBOL(br_handle_frame_hook);
index 05d6085..c57d887 100644 (file)
@@ -62,7 +62,7 @@
  *     Device mc lists are changed by bh at least if IPv6 is enabled,
  *     so that it must be bh protected.
  *
  *     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)
 {
 
 void dev_mc_upload(struct net_device *dev)
 {
-       spin_lock_bh(&dev->xmit_lock);
+       netif_tx_lock_bh(dev);
        __dev_mc_upload(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;
 
        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) {
                /*
 
        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);
                        
                         */
                        __dev_mc_upload(dev);
                        
-                       spin_unlock_bh(&dev->xmit_lock);
+                       netif_tx_unlock_bh(dev);
                        return 0;
                }
        }
        err = -ENOENT;
 done:
                        return 0;
                }
        }
        err = -ENOENT;
 done:
-       spin_unlock_bh(&dev->xmit_lock);
+       netif_tx_unlock_bh(dev);
        return err;
 }
 
        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);
 
 
        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) {
        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) {
        }
 
        if ((dmi = dmi1) == NULL) {
-               spin_unlock_bh(&dev->xmit_lock);
+               netif_tx_unlock_bh(dev);
                return -ENOMEM;
        }
        memcpy(dmi->dmi_addr, addr, alen);
                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);
        
 
        __dev_mc_upload(dev);
        
-       spin_unlock_bh(&dev->xmit_lock);
+       netif_tx_unlock_bh(dev);
        return 0;
 
 done:
        return 0;
 
 done:
-       spin_unlock_bh(&dev->xmit_lock);
+       netif_tx_unlock_bh(dev);
        kfree(dmi1);
        return err;
 }
        kfree(dmi1);
        return err;
 }
@@ -204,7 +204,7 @@ done:
 
 void dev_mc_discard(struct net_device *dev)
 {
 
 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;
        
        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;
 
        }
        dev->mc_count = 0;
 
-       spin_unlock_bh(&dev->xmit_lock);
+       netif_tx_unlock_bh(dev);
 }
 
 #ifdef CONFIG_PROC_FS
 }
 
 #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;
 
        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;
 
        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');
        }
 
                seq_putc(seq, '\n');
        }
-       spin_unlock_bh(&dev->xmit_lock);
+       netif_tx_unlock_bh(dev);
        return 0;
 }
 
        return 0;
 }
 
index 470c05b..1a5e49d 100644 (file)
@@ -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_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
 #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);
 
 out:
        spin_unlock(&dst_lock);
index c680b7e..987ccca 100644 (file)
@@ -30,7 +30,7 @@ u32 ethtool_op_get_link(struct net_device *dev)
 
 u32 ethtool_op_get_tx_csum(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)
 }
 
 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;
 
 {
        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)))
                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 && 
                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);
                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)
 {
 
 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;
 
        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);
 }
 
        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;
 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_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;
        }
        default:
                rc =  -EOPNOTSUPP;
        }
index e8e05ce..9cb7818 100644 (file)
@@ -273,24 +273,21 @@ static void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb)
 
        do {
                npinfo->tries--;
 
        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)) {
 
                /*
                 * 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);
                        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) {
 
                /* success */
                if(!status) {
index c23e9c0..4e7437a 100644 (file)
@@ -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->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);
 
        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->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);
 
        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 */
                }
        }
                        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));
        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;
        }
 
                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) {
        /* 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) {
index cfd2d1e..375dd90 100644 (file)
@@ -398,6 +398,9 @@ static int do_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
        }
 
        if (ida[IFLA_ADDRESS - 1]) {
        }
 
        if (ida[IFLA_ADDRESS - 1]) {
+               struct sockaddr *sa;
+               int len;
+
                if (!dev->set_mac_address) {
                        err = -EOPNOTSUPP;
                        goto out;
                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;
 
                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;
                if (err)
                        goto out;
                send_addr_notify = 1;
index fb3770f..bd64cb4 100644 (file)
@@ -140,6 +140,7 @@ EXPORT_SYMBOL(skb_truesize_bug);
  *     Buffers may only be allocated from interrupts using a @gfp_mask of
  *     %GFP_ATOMIC.
  */
  *     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)
 {
 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 = 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;
 
        shinfo->ip6_frag_id = 0;
        shinfo->frag_list = NULL;
 
@@ -194,6 +195,7 @@ nodata:
        skb = NULL;
        goto out;
 }
        skb = NULL;
        goto out;
 }
+#endif /* !CONFIG_HAVE_ARCH_ALLOC_SKB */
 
 /**
  *     alloc_skb_from_cache    -       allocate a network buffer
 
 /**
  *     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,
  */
 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;
 
        struct sk_buff *skb;
        u8 *data;
 
+       cache = fclone ? skbuff_fclone_cache : skbuff_head_cache;
+
        /* Get the HEAD */
        /* 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;
 
        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;
        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:
 out:
        return skb;
 nodata:
-       kmem_cache_free(skbuff_head_cache, skb);
+       kmem_cache_free(cache, skb);
        skb = NULL;
        goto out;
 }
 
 
        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;
 
        do {
                struct sk_buff *this = list;
@@ -263,6 +282,11 @@ static void skb_drop_fraglist(struct sk_buff *skb)
        } while (list);
 }
 
        } 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;
 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;
        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);
        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);
        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;
 }      
  
        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 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;
                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 {
                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;
        }
 
        return 0;
@@ -1826,6 +1892,133 @@ unsigned char *skb_pull_rcsum(struct sk_buff *skb, unsigned int len)
 
 EXPORT_SYMBOL_GPL(skb_pull_rcsum);
 
 
 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",
 void __init skb_init(void)
 {
        skbuff_head_cache = kmem_cache_create("skbuff_head_cache",
index 547523b..a2ba9db 100644 (file)
@@ -801,8 +801,7 @@ got_it:
                 * We linearize everything except data segments here.
                 */
                if (cb->nsp_flags & ~0x60) {
                 * 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;
                }
 
                                goto free_out;
                }
 
index e172cf9..5abf705 100644 (file)
@@ -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) {
                        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) {
                        goto dump_it;
 
                 switch(flags & DN_RT_CNTL_MSK) {
index 446faaf..2440d05 100644 (file)
@@ -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)
        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;
                if (dn_fib_fill_rule(skb, r, cb, NLM_F_MULTI) < 0)
                        break;
+next:
                idx++;
        }
        rcu_read_unlock();
                idx++;
        }
        rcu_read_unlock();
index dbb0852..f7e84e9 100644 (file)
@@ -58,6 +58,7 @@ config IEEE80211_CRYPT_TKIP
        depends on IEEE80211 && NET_RADIO
        select CRYPTO
        select CRYPTO_MICHAEL_MIC
        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
        ---help---
        Include software based cipher suites in support of IEEE 802.11i
        (aka TGi, WPA, WPA2, WPA-PSK, etc.) for use with TKIP enabled
index ccf85aa..f4f4aa6 100644 (file)
@@ -68,6 +68,7 @@
  */
 
 #include <linux/config.h>
  */
 
 #include <linux/config.h>
+#include <linux/err.h>
 #include <linux/errno.h>
 #include <linux/types.h>
 #include <linux/socket.h>
 #include <linux/errno.h>
 #include <linux/types.h>
 #include <linux/socket.h>
@@ -1137,6 +1138,88 @@ int inet_sk_rebuild_header(struct sock *sk)
 
 EXPORT_SYMBOL(inet_sk_rebuild_header);
 
 
 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,
 #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,
 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,
 };
 
        .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,
 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)
 };
 
 static int __init inet_init(void)
index ec566f3..a66c96a 100644 (file)
@@ -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) {
 
        rcu_read_lock();
        hlist_for_each_entry(r, node, &fib_rules, hlist) {
-
                if (idx < s_idx)
                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;
                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();
                idx++;
        }
        rcu_read_unlock();
index 0f4145b..1de08c1 100644 (file)
@@ -160,7 +160,7 @@ void free_fib_info(struct fib_info *fi)
 
 void fib_release_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)
        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);
        }
                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)
 }
 
 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;
 
        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;
        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;
 
        }
        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);
 
        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);
 
        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) {
        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)
                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:
        return fi;
 
 err_inval:
index cff9c3a..20b1704 100644 (file)
@@ -210,8 +210,7 @@ static inline int ip_finish_output(struct sk_buff *skb)
                return dst_output(skb);
        }
 #endif
                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);
                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,
        }
 
        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);
 
        /* 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*/
                               (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;
                __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 &&
         */
        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;
 
            !exthdrlen)
                csummode = CHECKSUM_HW;
 
@@ -946,7 +946,7 @@ alloc_new_skb:
                                skb_prev->csum = csum_sub(skb_prev->csum,
                                                          skb->csum);
                                data += fraggap;
                                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;
                        }
 
                        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) &&
 
        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;
 
 
 
        while (size > 0) {
                int i;
 
-               if (skb_shinfo(skb)->ufo_size)
+               if (skb_is_gso(skb))
                        len = size;
                else {
 
                        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);
                                        data, fraggap, 0);
                                skb_prev->csum = csum_sub(skb_prev->csum,
                                                          skb->csum);
-                               skb_trim(skb_prev, maxfraglen);
+                               pskb_trim_unique(skb_prev, maxfraglen);
                        }
 
                        /*
                        }
 
                        /*
index 95278b2..098d103 100644 (file)
@@ -84,7 +84,7 @@ out:
 static int ipcomp_input(struct xfrm_state *x, struct sk_buff *skb)
 {
        u8 nexthdr;
 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;
        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;
 
 
        } 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;
                goto out;
-       }
 
        skb->ip_summed = CHECKSUM_NONE;
 
 
        skb->ip_summed = CHECKSUM_NONE;
 
@@ -171,10 +168,8 @@ static int ipcomp_output(struct xfrm_state *x, struct sk_buff *skb)
                goto out_ok;
        }
 
                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;
                goto out_ok;
-       }
        
        err = ipcomp_compress(x, skb);
        iph = skb->nh.iph;
        
        err = ipcomp_compress(x, skb);
        iph = skb->nh.iph;
index d0d1919..92adfeb 100644 (file)
@@ -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 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) +
 
        /* 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);
        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]);
        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]);
index 518f581..853a3d5 100644 (file)
@@ -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);
        tuple.dst.protonum = IPPROTO_TCP;
 
        exp = __ip_conntrack_expect_find(&tuple);
-       if (exp->master == ct)
+       if (exp && exp->master == ct)
                return exp;
        return NULL;
 }
                return exp;
        return NULL;
 }
index a3d1407..35d1d90 100644 (file)
@@ -129,7 +129,12 @@ tcp_manip_pkt(struct sk_buff **pskb,
        if (hdrsize < sizeof(*hdr))
                return 1;
 
        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));
                                        ip_nat_cheat_check(oldport ^ 0xFFFF,
                                                           newport,
                                                           hdr->check));
index ec6053f..e8eaf6a 100644 (file)
@@ -113,11 +113,17 @@ udp_manip_pkt(struct sk_buff **pskb,
                newport = tuple->dst.u.udp.port;
                portptr = &hdr->dest;
        }
                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));
                                        ip_nat_cheat_check(*portptr ^ 0xFFFF,
                                                           newport,
                                                           hdr->check));
+       }
        *portptr = newport;
        return 1;
 }
        *portptr = newport;
        return 1;
 }
index cee3397..71871c4 100644 (file)
@@ -231,7 +231,7 @@ ipt_do_table(struct sk_buff **pskb,
        const char *indev, *outdev;
        void *table_base;
        struct ipt_entry *e, *back;
        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;
 
        /* 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));
 
        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]);
 
        table_base = (void *)private->entries[smp_processor_id()];
        e = get_entry(table_base, private->hook_entry[hook]);
 
index c84cc03..090f138 100644 (file)
@@ -116,6 +116,11 @@ static void ulog_send(unsigned int nlgroupnum)
                del_timer(&ub->timer);
        }
 
                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;
        /* last nlmsg needs NLMSG_DONE */
        if (ub->qlen > 1)
                ub->lastnlh->nlmsg_type = NLMSG_DONE;
index cc9423d..5fe2fcf 100644 (file)
@@ -3144,7 +3144,7 @@ int __init ip_rt_init(void)
                                        rhash_entries,
                                        (num_physpages >= 128 * 1024) ?
                                        15 : 17,
                                        rhash_entries,
                                        (num_physpages >= 128 * 1024) ?
                                        15 : 17,
-                                       HASH_HIGHMEM,
+                                       0,
                                        &rt_hash_log,
                                        &rt_hash_mask,
                                        0);
                                        &rt_hash_log,
                                        &rt_hash_mask,
                                        0);
index 6a22831..e369c0b 100644 (file)
 #include <linux/random.h>
 #include <linux/bootmem.h>
 #include <linux/cache.h>
 #include <linux/random.h>
 #include <linux/bootmem.h>
 #include <linux/cache.h>
+#include <linux/err.h>
 #include <linux/in.h>
 
 #include <net/icmp.h>
 #include <linux/in.h>
 
 #include <net/icmp.h>
@@ -572,7 +573,7 @@ new_segment:
                skb->ip_summed = CHECKSUM_HW;
                tp->write_seq += copy;
                TCP_SKB_CB(skb)->end_seq += copy;
                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;
 
                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;
 
        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) ||
        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);
 
                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);
        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.
                                 */
                                /*
                                 * 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);
                                        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;
 
                        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;
 
                        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
 
 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;
 
 extern void __skb_cb_too_small_for_tcp(int, int);
 extern struct tcp_congestion_ops tcp_reno;
 
index 662bd24..0eadd3a 100644 (file)
@@ -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);
                                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);
                        }
                                        break;
                                pcount = tcp_skb_pcount(skb);
                        }
index 075216a..0334bbe 100644 (file)
@@ -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.
  *
 /*
  *     This routine will send an RST to the other tcp.
  *
index 1e848ad..ba50b52 100644 (file)
@@ -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);
                 * 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)++;
                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.
                 */
                /* 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;
        } 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 &&
 
        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);
        }
                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;
           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;
                }
                        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->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;
 
                /* 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->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);
 
        /* 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;
        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 */
        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;
        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;
        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;
                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);
 
                /* 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->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
 
        /* Use a previous sequence.  This should cause the other
         * end to send an ack.  Don't queue or clone SKB, just
index 4ef8efa..ecc4119 100644 (file)
@@ -9,6 +9,8 @@
  */
 
 #include <linux/compiler.h>
  */
 
 #include <linux/compiler.h>
+#include <linux/if_ether.h>
+#include <linux/kernel.h>
 #include <linux/skbuff.h>
 #include <linux/spinlock.h>
 #include <linux/netfilter_ipv4.h>
 #include <linux/skbuff.h>
 #include <linux/spinlock.h>
 #include <linux/netfilter_ipv4.h>
@@ -17,6 +19,8 @@
 #include <net/xfrm.h>
 #include <net/icmp.h>
 
 #include <net/xfrm.h>
 #include <net/icmp.h>
 
+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
 /* 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;
        
        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)
        if (skb->ip_summed == CHECKSUM_HW) {
                err = skb_checksum_help(skb, 0);
                if (err)
@@ -152,16 +160,10 @@ error_nolock:
        goto out_exit;
 }
 
        goto out_exit;
 }
 
-static int xfrm4_output_finish(struct sk_buff *skb)
+static int xfrm4_output_finish2(struct sk_buff *skb)
 {
        int err;
 
 {
        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);
 
        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,
                        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;
        }
                if (unlikely(err != 1))
                        break;
        }
@@ -182,6 +184,48 @@ static int xfrm4_output_finish(struct sk_buff *skb)
        return err;
 }
 
        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,
 int xfrm4_output(struct sk_buff *skb)
 {
        return NF_HOOK_COND(PF_INET, NF_IP_POST_ROUTING, skb, NULL, skb->dst->dev,
index 1f5e0c6..386ca5c 100644 (file)
@@ -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) ||
        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);
            !(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 &&
        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;
 
            (ipv6_addr_type(&ifp->addr) & IPV6_ADDR_LINKLOCAL)) {
                struct in6_addr all_routers;
 
index a18d425..9ca783d 100644 (file)
@@ -635,14 +635,17 @@ ipv6_renew_options(struct sock *sk, struct ipv6_txoptions *opt,
        struct ipv6_txoptions *opt2;
        int err;
 
        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);
 
        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);
 
        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;
 
                                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;
 
                                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,
                                newtype != IPV6_RTHDR,
-                               (struct ipv6_opt_hdr **)opt2->srcrt, &p);
+                               (struct ipv6_opt_hdr **)&opt2->srcrt, &p);
        if (err)
                goto out;
 
        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)
                                newtype != IPV6_DSTOPTS,
                                &opt2->dst1opt, &p);
        if (err)
index e460489..1d5dfeb 100644 (file)
@@ -147,7 +147,7 @@ static int ip6_output2(struct sk_buff *skb)
 
 int ip6_output(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
                                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*/
                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);
                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_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) {
                        }
                        copy = datalen - transhdrlen - fraggap;
                        if (copy < 0) {
index 4863643..96cac9a 100644 (file)
@@ -65,7 +65,7 @@ static LIST_HEAD(ipcomp6_tfms_list);
 
 static int ipcomp6_input(struct xfrm_state *x, struct sk_buff *skb)
 {
 
 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;
        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;
 
        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;
                goto out;
-       }
 
        skb->ip_summed = CHECKSUM_NONE;
 
 
        skb->ip_summed = CHECKSUM_NONE;
 
@@ -159,10 +156,8 @@ static int ipcomp6_output(struct xfrm_state *x, struct sk_buff *skb)
                goto out_ok;
        }
 
                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;
                goto out_ok;
-       }
 
        /* compression */
        plen = skb->len - hdr_len;
 
        /* compression */
        plen = skb->len - hdr_len;
index 8024217..e9ea338 100644 (file)
@@ -151,7 +151,7 @@ error_nolock:
        goto out_exit;
 }
 
        goto out_exit;
 }
 
-static int xfrm6_output_finish(struct sk_buff *skb)
+static int xfrm6_output_finish2(struct sk_buff *skb)
 {
        int err;
 
 {
        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,
                        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;
        }
                if (unlikely(err != 1))
                        break;
        }
@@ -175,6 +175,41 @@ static int xfrm6_output_finish(struct sk_buff *skb)
        return err;
 }
 
        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,
 int xfrm6_output(struct sk_buff *skb)
 {
        return NF_HOOK(PF_INET6, NF_IP6_POST_ROUTING, skb, NULL, skb->dst->dev,
index 811d998..e6a50e8 100644 (file)
@@ -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? */
        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 &&
                goto drop;
                         
        if (ipx->ipx_checksum != IPX_NO_CHECKSUM &&
index 61cdda4..b59d3b2 100644 (file)
@@ -366,6 +366,9 @@ __nfulnl_send(struct nfulnl_instance *inst)
        if (timer_pending(&inst->timer))
                del_timer(&inst->timer);
 
        if (timer_pending(&inst->timer))
                del_timer(&inst->timer);
 
+       if (!inst->skb)
+               return 0;
+
        if (inst->qlen > 1)
                inst->lastnlh->nlmsg_type = NLMSG_DONE;
 
        if (inst->qlen > 1)
                inst->lastnlh->nlmsg_type = NLMSG_DONE;
 
index 2ffa11c..eb7dc29 100644 (file)
@@ -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)
                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:
                r->rta_len = skb->tail - (u8*)r;
        }
 
        return 0;
 
 rtattr_failure:
+       err = -EINVAL;
+errout:
        skb_trim(skb, b - skb->data);
        skb_trim(skb, b - skb->data);
-       return -err;
+       return err;
 }
 
 struct tc_action *tcf_action_init_1(struct rtattr *rta, struct rtattr *est,
 }
 
 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
                        goto err_mod;
                }
 #endif
+               *err = -ENOENT;
                goto err_out;
        }
 
                goto err_out;
        }
 
@@ -777,7 +780,7 @@ replay:
        return ret;
 }
 
        return ret;
 }
 
-static char *
+static struct rtattr *
 find_dump_kind(struct nlmsghdr *n)
 {
        struct rtattr *tb1, *tb2[TCA_ACT_MAX+1];
 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 NULL;
        kind = tb2[TCA_ACT_KIND-1];
 
-       return (char *) RTA_DATA(kind);
+       return kind;
 }
 
 static int
 }
 
 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);
        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;
        }
 
 
        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) {
        if (a_o == NULL) {
-               printk("failed to find %s\n", kind);
                return 0;
        }
 
                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) {
        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;
        }
 
                goto rtattr_failure;
        }
 
index 138ea92..74d4a1d 100644 (file)
@@ -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->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.
  */
 
    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.
 */
 
    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 */
 {
        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);
                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
                /*
                 * 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) {
                 * will be requeued.
                 */
                if (!nolock) {
-                       if (!spin_trylock(&dev->xmit_lock)) {
+                       if (!netif_tx_trylock(dev)) {
                        collision:
                                /* So, someone grabbed the driver. */
                                
                        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;
                        }
                                __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 (!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) {
                                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;
                                        }
                                        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) { 
                        /* 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;
                        } 
                        spin_lock(&dev->queue_lock);
                        q = dev->qdisc;
@@ -175,7 +172,10 @@ int qdisc_restart(struct net_device *dev)
                 */
 
 requeue:
                 */
 
 requeue:
-               q->ops->requeue(skb, q);
+               if (skb->next)
+                       dev->gso_skb = skb;
+               else
+                       q->ops->requeue(skb, q);
                netif_schedule(dev);
                return 1;
        }
                netif_schedule(dev);
                return 1;
        }
@@ -183,11 +183,23 @@ requeue:
        return q->q.qlen;
 }
 
        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;
 
 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) &&
        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);
                }
        }
                                dev_hold(dev);
                }
        }
-       spin_unlock(&dev->xmit_lock);
+       netif_tx_unlock(dev);
 
        dev_put(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)
 {
 
 static void dev_watchdog_up(struct net_device *dev)
 {
-       spin_lock_bh(&dev->xmit_lock);
+       netif_tx_lock_bh(dev);
        __netdev_watchdog_up(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)
 {
 }
 
 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);
        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)
 }
 
 void netif_carrier_on(struct net_device *dev)
@@ -579,10 +591,17 @@ void dev_deactivate(struct net_device *dev)
 
        dev_watchdog_down(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();
 
                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)
 }
 
 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_alloc);
 EXPORT_SYMBOL(qdisc_destroy);
 EXPORT_SYMBOL(qdisc_reset);
-EXPORT_SYMBOL(qdisc_restart);
 EXPORT_SYMBOL(qdisc_lock_tree);
 EXPORT_SYMBOL(qdisc_unlock_tree);
 EXPORT_SYMBOL(qdisc_lock_tree);
 EXPORT_SYMBOL(qdisc_unlock_tree);
index 79b8ef3..4c16ad5 100644 (file)
@@ -302,20 +302,17 @@ restart:
 
                switch (teql_resolve(skb, skb_res, slave)) {
                case 0:
 
                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) {
                                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;
                                }
                                        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;
                        }
                        if (netif_queue_stopped(dev))
                                busy = 1;
index 5e0de3c..b9b9070 100644 (file)
@@ -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,
 
 /* 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;
 {
        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.  */
        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;
                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);
        }
 
        sctp_init_cause(retval, SCTP_ERROR_USER_ABORT, payload, paylen);
index 9e58144..66e9c5b 100644 (file)
@@ -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.
         */
         * 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;
 
        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.
 
        /* 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)
 {
        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 */
        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;
 
                        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));
 
        sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
                        SCTP_STATE(SCTP_STATE_CLOSED));
index b811691..5b1c837 100644 (file)
@@ -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);
        }
 
                        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) {
                        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_DEBUG_PRINTK("Aborting association: %p\n", asoc);
-                       sctp_primitive_ABORT(asoc, msg);
+                       sctp_primitive_ABORT(asoc, chunk);
                        err = 0;
                        goto out_unlock;
                }
                        err = 0;
                        goto out_unlock;
                }
index 7026b08..00cb388 100644 (file)
@@ -71,7 +71,12 @@ struct cache_head *sunrpc_cache_lookup(struct cache_detail *detail,
        new = detail->alloc();
        if (!new)
                return NULL;
        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);
        cache_init(new);
+       detail->init(new, key);
 
        write_lock(&detail->hash_lock);
 
 
        write_lock(&detail->hash_lock);
 
@@ -85,7 +90,6 @@ struct cache_head *sunrpc_cache_lookup(struct cache_detail *detail,
                        return tmp;
                }
        }
                        return tmp;
                }
        }
-       detail->init(new, key);
        new->next = *head;
        *head = new;
        detail->entries++;
        new->next = *head;
        *head = new;
        detail->entries++;
index e725e6b..c9e1b96 100644 (file)
@@ -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 \
 
 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/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/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/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 \
   /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/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/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/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 \
   /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/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 \
   /usr/include/bits/sigstack.h \
   /usr/include/bits/sigthread.h \
   /usr/include/sys/resource.h \
index 1c463aa..fc3d06a 100644 (file)
@@ -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 \
 
 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/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/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/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 \
   /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/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 \
   /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/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/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/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 \
   /usr/include/netinet/in.h \
   /usr/include/stdint.h \
   /usr/include/sys/socket.h \
index e596a87..b73a7c8 100644 (file)
@@ -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 \
 
 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/features.h \
   /usr/include/sys/cdefs.h \
   /usr/include/gnu/stubs.h \
-  /usr/include/bits/types.h \
   /usr/include/bits/wordsize.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 \
   /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/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/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 \
   /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/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/include/bits/stdio_lim.h \
   /usr/include/bits/sys_errlist.h \
   /usr/include/bits/stdio.h \
index 51640ad..9392884 100755 (executable)
Binary files a/scripts/basic/docproc and b/scripts/basic/docproc differ
index 800beed..942fd7c 100755 (executable)
Binary files a/scripts/basic/fixdep and b/scripts/basic/fixdep differ
index ecd686e..2e76d8e 100755 (executable)
Binary files a/scripts/basic/split-include and b/scripts/basic/split-include differ
index 4f007fa..a09989c 100644 (file)
@@ -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  
index 2c06e27..b04aab7 100644 (file)
@@ -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) \
 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/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/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/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/time.h \
   /usr/include/sys/sysmacros.h \
   /usr/include/bits/pthreadtypes.h \
-  /usr/include/bits/sched.h \
   /usr/include/alloca.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 \
   /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/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)
   scripts/kconfig/lkc_proto.h \
 
 scripts/kconfig/conf.o: $(deps_scripts/kconfig/conf.o)
index 1ef4182..f05e929 100644 (file)
@@ -6,10 +6,11 @@ deps_scripts/kconfig/kxgettext.o := \
   /usr/include/features.h \
   /usr/include/sys/cdefs.h \
   /usr/include/gnu/stubs.h \
   /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/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 \
   /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/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/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/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/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 \
   /usr/include/libintl.h \
   /usr/include/locale.h \
   /usr/include/bits/locale.h \
index 6f874bf..bdd9030 100644 (file)
@@ -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 \
 
 deps_scripts/kconfig/mconf.o := \
   scripts/kconfig/mconf.c \
-    $(wildcard include/config/.h) \
     $(wildcard include/config/mode.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/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 \
   /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/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 \
   /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/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/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 \
   /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/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/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/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 \
   /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/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 \
   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/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)
   scripts/kconfig/lkc_proto.h \
 
 scripts/kconfig/mconf.o: $(deps_scripts/kconfig/mconf.o)
index 2a3661c..b2e450d 100644 (file)
@@ -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 \
 
 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/features.h \
   /usr/include/sys/cdefs.h \
   /usr/include/gnu/stubs.h \
-  /usr/include/bits/types.h \
   /usr/include/bits/wordsize.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/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 \
   /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/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/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 \
   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/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 \
   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 \
   /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 \
   /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) \
   scripts/kconfig/confdata.c \
     $(wildcard include/config/.h) \
+    $(wildcard include/config/notimestamp.h) \
   /usr/include/sys/stat.h \
   /usr/include/bits/stat.h \
   /usr/include/sys/stat.h \
   /usr/include/bits/stat.h \
+  scripts/kconfig/lkc.h \
   scripts/kconfig/expr.c \
   scripts/kconfig/expr.c \
+  scripts/kconfig/lkc.h \
   scripts/kconfig/symbol.c \
   scripts/kconfig/symbol.c \
+  /usr/include/regex.h \
   /usr/include/sys/utsname.h \
   /usr/include/bits/utsname.h \
   /usr/include/sys/utsname.h \
   /usr/include/bits/utsname.h \
+  scripts/kconfig/lkc.h \
   scripts/kconfig/menu.c \
   scripts/kconfig/menu.c \
+  scripts/kconfig/lkc.h \
 
 scripts/kconfig/zconf.tab.o: $(deps_scripts/kconfig/zconf.tab.o)
 
 
 scripts/kconfig/zconf.tab.o: $(deps_scripts/kconfig/zconf.tab.o)
 
index 89b852e..3066bc9 100755 (executable)
Binary files a/scripts/kconfig/conf and b/scripts/kconfig/conf differ
index c191a8a..fc79114 100644 (file)
Binary files a/scripts/kconfig/conf.o and b/scripts/kconfig/conf.o differ
index e92d260..531fd72 100644 (file)
Binary files a/scripts/kconfig/kxgettext.o and b/scripts/kconfig/kxgettext.o differ
index 22dda11..24e3c8c 100644 (file)
@@ -1,5 +1,5 @@
 
 
-#line 3 "lex.zconf.c"
+#line 3 "scripts/kconfig/lex.zconf.c"
 
 #define  YY_INT_ALIGNED short int
 
 
 #define  YY_INT_ALIGNED short int
 
@@ -323,7 +323,7 @@ void zconffree (void *  );
 
 /* Begin user sect3 */
 
 
 /* Begin user sect3 */
 
-#define zconfwrap(n) 1
+#define zconfwrap() 1
 #define YY_SKIP_YYWRAP
 
 typedef unsigned char YY_CHAR;
 #define YY_SKIP_YYWRAP
 
 typedef unsigned char YY_CHAR;
@@ -338,1567 +338,323 @@ int zconflineno = 1;
 
 extern char *zconftext;
 #define yytext_ptr zconftext
 
 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,    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;
 
        *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
 /* 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;
        };
        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,
     {   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] =
     } ;
 
 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,
        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,
         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
 
 
 #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 {
 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 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;
 
 void new_string(void)
 {
        text = malloc(START_STRSIZE);
        text_asize = START_STRSIZE;
-       text_ptr = text;
        text_size = 0;
        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) {
 }
 
 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 = 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_size += size;
-       *text_ptr = 0;
+       text[text_size] = 0;
 }
 
 void alloc_string(const char *str, int size)
 }
 
 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
 
 #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 <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 <unistd.h>
+#endif
 
 #ifndef YY_EXTRA_TYPE
 #define YY_EXTRA_TYPE void *
 
 #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 */
        { /* beginning of action switch */
 case 1:
 /* rule 1 can match eol */
-YY_RULE_SETUP
-current_file->lineno++;
-       YY_BREAK
 case 2:
 case 2:
+/* rule 2 can match eol */
 YY_RULE_SETUP
 YY_RULE_SETUP
-
+{
+       current_file->lineno++;
+       return T_EOL;
+}
        YY_BREAK
 case 3:
        YY_BREAK
 case 3:
-/* rule 3 can match eol */
 YY_RULE_SETUP
 YY_RULE_SETUP
-current_file->lineno++; return T_EOL;
+
        YY_BREAK
 case 4:
 YY_RULE_SETUP
        YY_BREAK
 case 4:
 YY_RULE_SETUP
@@ -2282,175 +1026,63 @@ YY_RULE_SETUP
 
 case 6:
 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
                alloc_string(zconftext, zconfleng);
                zconflval.string = text;
                return T_WORD;
        }
        YY_BREAK
-case 36:
+case 7:
 YY_RULE_SETUP
 
        YY_BREAK
 YY_RULE_SETUP
 
        YY_BREAK
-case 37:
-/* rule 37 can match eol */
+case 8:
+/* rule 8 can match eol */
 YY_RULE_SETUP
 YY_RULE_SETUP
-current_file->lineno++; BEGIN(INITIAL);
+{
+               BEGIN(INITIAL);
+               current_file->lineno++;
+               return T_EOL;
+       }
        YY_BREAK
 
        YY_BREAK
 
-case 38:
+case 9:
 YY_RULE_SETUP
 return T_AND;
        YY_BREAK
 YY_RULE_SETUP
 return T_AND;
        YY_BREAK
-case 39:
+case 10:
 YY_RULE_SETUP
 return T_OR;
        YY_BREAK
 YY_RULE_SETUP
 return T_OR;
        YY_BREAK
-case 40:
+case 11:
 YY_RULE_SETUP
 return T_OPEN_PAREN;
        YY_BREAK
 YY_RULE_SETUP
 return T_OPEN_PAREN;
        YY_BREAK
-case 41:
+case 12:
 YY_RULE_SETUP
 return T_CLOSE_PAREN;
        YY_BREAK
 YY_RULE_SETUP
 return T_CLOSE_PAREN;
        YY_BREAK
-case 42:
+case 13:
 YY_RULE_SETUP
 return T_NOT;
        YY_BREAK
 YY_RULE_SETUP
 return T_NOT;
        YY_BREAK
-case 43:
+case 14:
 YY_RULE_SETUP
 return T_EQUAL;
        YY_BREAK
 YY_RULE_SETUP
 return T_EQUAL;
        YY_BREAK
-case 44:
+case 15:
 YY_RULE_SETUP
 return T_UNEQUAL;
        YY_BREAK
 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];
 YY_RULE_SETUP
 {
                str = zconftext[0];
@@ -2458,33 +1090,38 @@ YY_RULE_SETUP
                BEGIN(STRING);
        }
        YY_BREAK
                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
 YY_RULE_SETUP
 BEGIN(INITIAL); current_file->lineno++; return T_EOL;
        YY_BREAK
-case 49:
+case 18:
 YY_RULE_SETUP
 /* ignore */
        YY_BREAK
 YY_RULE_SETUP
 /* ignore */
        YY_BREAK
-case 50:
+case 19:
 YY_RULE_SETUP
 {
 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
                alloc_string(zconftext, zconfleng);
                zconflval.string = text;
                return T_WORD;
        }
        YY_BREAK
-case 51:
+case 20:
 YY_RULE_SETUP
 /* comment */
        YY_BREAK
 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
 YY_RULE_SETUP
 current_file->lineno++;
        YY_BREAK
-case 53:
+case 22:
 YY_RULE_SETUP
 
        YY_BREAK
 YY_RULE_SETUP
 
        YY_BREAK
@@ -2494,8 +1131,8 @@ case YY_STATE_EOF(PARAM):
        }
        YY_BREAK
 
        }
        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 */
 *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
                return T_WORD_QUOTE;
        }
        YY_BREAK
-case 55:
+case 24:
 YY_RULE_SETUP
 {
                append_string(zconftext, zconfleng);
        }
        YY_BREAK
 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 */
 *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
                return T_WORD_QUOTE;
        }
        YY_BREAK
-case 57:
+case 26:
 YY_RULE_SETUP
 {
                append_string(zconftext + 1, zconfleng - 1);
        }
        YY_BREAK
 YY_RULE_SETUP
 {
                append_string(zconftext + 1, zconfleng - 1);
        }
        YY_BREAK
-case 58:
+case 27:
 YY_RULE_SETUP
 {
                if (str == zconftext[0]) {
 YY_RULE_SETUP
 {
                if (str == zconftext[0]) {
@@ -2541,8 +1178,8 @@ YY_RULE_SETUP
                        append_string(zconftext, 1);
        }
        YY_BREAK
                        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());
 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
 
        }
        YY_BREAK
 
-case 60:
+case 29:
 YY_RULE_SETUP
 {
                ts = 0;
 YY_RULE_SETUP
 {
                ts = 0;
@@ -2582,8 +1219,8 @@ YY_RULE_SETUP
                }
        }
        YY_BREAK
                }
        }
        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 */
 *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
                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
 YY_RULE_SETUP
 {
                current_file->lineno++;
                append_string("\n", 1);
        }
        YY_BREAK
-case 63:
+case 32:
 YY_RULE_SETUP
 {
                append_string(zconftext, zconfleng);
 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):
 {
 case YY_STATE_EOF(INITIAL):
 case YY_STATE_EOF(COMMAND):
 {
-       if (current_buf) {
+       if (current_file) {
                zconf_endfile();
                zconf_endfile();
-               return T_EOF;
+               return T_EOL;
        }
        fclose(zconfin);
        yyterminate();
 }
        YY_BREAK
        }
        fclose(zconfin);
        yyterminate();
 }
        YY_BREAK
-case 64:
+case 33:
 YY_RULE_SETUP
 YY_FATAL_ERROR( "flex scanner jammed" );
        YY_BREAK
 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.
 
 /** 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.
  */
  * 
  * @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
 }
 
 /** 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;
 }
 
        current_file = file;
 }
 
-static struct buffer *zconf_endfile(void)
+static void zconf_endfile(void)
 {
        struct buffer *parent;
 
 {
        struct buffer *parent;
 
@@ -3666,23 +2303,15 @@ static struct buffer *zconf_endfile(void)
        }
        free(current_buf);
        current_buf = parent;
        }
        free(current_buf);
        current_buf = parent;
-
-       return parent;
 }
 
 int zconf_lineno(void)
 {
 }
 
 int zconf_lineno(void)
 {
-       if (current_buf)
-               return current_file->lineno - 1;
-       else
-               return 0;
+       return current_pos.lineno;
 }
 
 char *zconf_curname(void)
 {
 }
 
 char *zconf_curname(void)
 {
-       if (current_buf)
-               return current_file->name;
-       else
-               return "<none>";
+       return current_pos.file ? current_pos.file->name : "<none>";
 }
 
 }
 
index 61fe000..6efca8d 100644 (file)
Binary files a/scripts/kconfig/mconf.o and b/scripts/kconfig/mconf.o differ
index c9bfdb4..ea7755d 100644 (file)
@@ -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,
 
 /* 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
 
    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
 
 /* 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
 #define yyparse zconfparse
 #define yylex   zconflex
 #define yyerror zconferror
      T_REQUIRES = 272,
      T_OPTIONAL = 273,
      T_PROMPT = 274,
      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
    };
 #endif
 #define T_MAINMENU 258
 #define T_REQUIRES 272
 #define T_OPTIONAL 273
 #define T_PROMPT 274
 #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
 
 
 
 
 
 
 #include <string.h>
 #include <stdbool.h>
 
 #include <string.h>
 #include <stdbool.h>
 
+#define LKC_DIRECT_LINK
+#include "lkc.h"
+
+#include "zconf.hash.c"
+
 #define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt)
 
 #define PRINTD         0x0001
 #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, ...);
 
 extern int zconflex(void);
 static void zconfprint(const char *err, ...);
+static void zconf_error(const char *err, ...);
 static void zconferror(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];
 
 
 struct symbol *symbol_hash[257];
 
+static struct menu *current_menu, *current_entry;
+
+#define YYDEBUG 0
+#if YYDEBUG
 #define YYERROR_VERBOSE
 #define YYERROR_VERBOSE
+#endif
 
 
 /* Enabling traces.  */
 
 
 /* Enabling traces.  */
@@ -194,13 +190,14 @@ struct symbol *symbol_hash[257];
 #if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
 
 typedef union YYSTYPE {
 #if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
 
 typedef union YYSTYPE {
-       int token;
        char *string;
        char *string;
+       struct file *file;
        struct symbol *symbol;
        struct expr *expr;
        struct menu *menu;
        struct symbol *symbol;
        struct expr *expr;
        struct menu *menu;
+       struct kconf_id *id;
 } YYSTYPE;
 } YYSTYPE;
-/* Line 191 of yacc.c.  */
+/* Line 190 of yacc.c.  */
 
 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
 
 # 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.  */
 
 
 /* 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
 
 
 
 #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.  */
 
 /* 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
 #   else
-#    ifdef __GNUC__
-#     define YYSTACK_ALLOC __builtin_alloca
-#    endif
+#    define YYSTACK_ALLOC alloca
 #   endif
 #  endif
 # endif
 #   endif
 #  endif
 # endif
@@ -245,20 +241,20 @@ typedef union YYSTYPE {
 #   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
 #   define YYSIZE_T size_t
 #  endif
 #   include <stdlib.h> /* 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) \
 # 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
 {
 
 /* A type that is properly aligned for any stack member.  */
 union yyalloc
 {
-  short yyss;
+  short int yyss;
   YYSTYPE yyvs;
   };
 
   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) \
 /* 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
       + 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
 #   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
 #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. */
 #endif
 
 /* YYFINAL -- State number of the termination state. */
-#define YYFINAL  2
+#define YYFINAL  3
 /* YYLAST -- Last index in YYTABLE.  */
 /* YYLAST -- Last index in YYTABLE.  */
-#define YYLAST   201
+#define YYLAST   264
 
 /* YYNTOKENS -- Number of terminals. */
 
 /* YYNTOKENS -- Number of terminals. */
-#define YYNTOKENS  42
+#define YYNTOKENS  35
 /* YYNNTS -- Number of nonterminals. */
 /* YYNNTS -- Number of nonterminals. */
-#define YYNNTS  41
+#define YYNNTS  42
 /* YYNRULES -- Number of rules. */
 #define YYNRULES  104
 /* YYNRULES -- Number of states. */
 /* 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
 
 /* 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)
 
 #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,
        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.  */
 };
 
 #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[] =
 {
 };
 
 /* 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.  */
 };
 
 /* 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
 
 };
 #endif
 
@@ -446,67 +441,65 @@ static const unsigned short yyrline[] =
    First, the terminals, then, starting at YYNTOKENS, nonterminals. */
 static const char *const yytname[] =
 {
    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.  */
 };
 #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,
 {
        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[] =
 {
 };
 # 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[] =
 {
 };
 
 /* 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,     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
 };
 
        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[] =
 {
    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]. */
 };
 
 /* 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.  */
 };
 
 /* 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].  */
 };
 
 /* 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.  */
 };
 
 /* 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[] =
 {
 };
 
 /* 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__)
 };
 
 #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 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
 
 
 /* Like YYERROR except do call yyerror.  This remains here temporarily
@@ -713,20 +715,53 @@ do                                                                \
     }                                                          \
 while (0)
 
     }                                                          \
 while (0)
 
+
 #define YYTERROR       1
 #define YYERRCODE      256
 
 #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
 #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
 
 #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
 /* YYLEX -- calling `yylex' with the right arguments.  */
 
 #ifdef YYLEX_PARAM
@@ -749,36 +784,30 @@ do {                                              \
     YYFPRINTF Args;                            \
 } while (0)
 
     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,                                      \
 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 |
       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
 `------------------------------------------------------------------*/
 
 #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)
 #else
 static void
 yy_stack_print (bottom, top)
-    short *bottom;
-    short *top;
+    short int *bottom;
+    short int *top;
 #endif
 {
   YYFPRINTF (stderr, "Stack now");
 #endif
 {
   YYFPRINTF (stderr, "Stack now");
@@ -808,9 +837,9 @@ yy_reduce_print (yyrule)
 #endif
 {
   int yyi;
 #endif
 {
   int yyi;
-  unsigned int yylineno = yyrline[yyrule];
+  unsigned int yylno = yyrline[yyrule];
   YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ",
   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]]);
   /* 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)
 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 */
 # 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.  */
 
    SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH)
    evaluated with infinite-precision integer arithmetic.  */
 
-#if YYMAXDEPTH == 0
-# undef YYMAXDEPTH
-#endif
-
 #ifndef YYMAXDEPTH
 # define YYMAXDEPTH 10000
 #endif
 #ifndef YYMAXDEPTH
 # define YYMAXDEPTH 10000
 #endif
@@ -932,15 +956,15 @@ yysymprint (yyoutput, yytype, yyvaluep)
   (void) yyvaluep;
 
   if (yytype < YYNTOKENS)
   (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]);
 
   else
     YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
 
+
+# ifdef YYPRINT
+  if (yytype < YYNTOKENS)
+    YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+# endif
   switch (yytype)
     {
       default:
   switch (yytype)
     {
       default:
@@ -956,10 +980,11 @@ yysymprint (yyoutput, yytype, yyvaluep)
 
 #if defined (__STDC__) || defined (__cplusplus)
 static void
 
 #if defined (__STDC__) || defined (__cplusplus)
 static void
-yydestruct (int yytype, YYSTYPE *yyvaluep)
+yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep)
 #else
 static void
 #else
 static void
-yydestruct (yytype, yyvaluep)
+yydestruct (yymsg, yytype, yyvaluep)
+    const char *yymsg;
     int yytype;
     YYSTYPE *yyvaluep;
 #endif
     int yytype;
     YYSTYPE *yyvaluep;
 #endif
@@ -967,8 +992,42 @@ yydestruct (yytype, yyvaluep)
   /* Pacify ``unused variable'' warnings.  */
   (void) yyvaluep;
 
   /* Pacify ``unused variable'' warnings.  */
   (void) yyvaluep;
 
+  if (!yymsg)
+    yymsg = "Deleting";
+  YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
+
   switch (yytype)
     {
   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;
 
       default:
         break;
@@ -994,10 +1053,10 @@ int yyparse ();
 
 
 
 
 
 
-/* The lookahead symbol.  */
+/* The look-ahead symbol.  */
 int yychar;
 
 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.  */
 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;
   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:
   int yytoken = 0;
 
   /* Three stacks and their tools:
@@ -1045,9 +1104,9 @@ yyparse ()
      to reallocate them elsewhere.  */
 
   /* The state stack.  */
      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];
 
   /* The semantic value stack.  */
   YYSTYPE yyvsa[YYINITDEPTH];
@@ -1084,6 +1143,9 @@ yyparse ()
   yyssp = yyss;
   yyvsp = yyvs;
 
   yyssp = yyss;
   yyvsp = yyvs;
 
+
+  yyvsp[0] = yylval;
+
   goto yysetstate;
 
 /*------------------------------------------------------------.
   goto yysetstate;
 
 /*------------------------------------------------------------.
@@ -1109,7 +1171,7 @@ yyparse ()
           these so that the &'s don't force the real ones into
           memory.  */
        YYSTYPE *yyvs1 = yyvs;
           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
 
 
        /* Each stack pointer address is followed by the size of the
@@ -1137,7 +1199,7 @@ yyparse ()
        yystacksize = YYMAXDEPTH;
 
       {
        yystacksize = YYMAXDEPTH;
 
       {
-       short *yyss1 = yyss;
+       short int *yyss1 = yyss;
        union yyalloc *yyptr =
          (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
        if (! yyptr)
        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.  */
 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: */
 
 /* 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;
 
 
   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: "));
   if (yychar == YYEMPTY)
     {
       YYDPRINTF ((stderr, "Reading a token: "));
@@ -1199,7 +1261,7 @@ yybackup:
   else
     {
       yytoken = YYTRANSLATE (yychar);
   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
     }
 
   /* If the proper action on seeing token YYTOKEN is to reduce or to
@@ -1219,8 +1281,8 @@ yybackup:
   if (yyn == YYFINAL)
     YYACCEPT;
 
   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)
 
   /* Discard the token being shifted unless it is eof.  */
   if (yychar != YYEOF)
@@ -1271,155 +1333,123 @@ yyreduce:
     {
         case 8:
 
     {
         case 8:
 
-    { zconfprint("unexpected 'endmenu' statement"); ;}
+    { zconf_error("unexpected end statement"); ;}
     break;
 
   case 9:
 
     break;
 
   case 9:
 
-    { zconfprint("unexpected 'endif' statement"); ;}
+    { zconf_error("unknown statement \"%s\"", (yyvsp[-2].string)); ;}
     break;
 
   case 10:
 
     break;
 
   case 10:
 
-    { zconfprint("unexpected 'endchoice' statement"); ;}
+    {
+       zconf_error("unexpected option \"%s\"", kconf_id_strings + (yyvsp[-2].id)->name);
+;}
     break;
 
   case 11:
 
     break;
 
   case 11:
 
-    { zconfprint("syntax error"); yyerrok; ;}
+    { zconf_error("invalid statement"); ;}
     break;
 
     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;
 
     break;
 
-  case 19:
+  case 26:
 
 
-    {
-       menu_end_entry();
-       printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno());
-;}
+    { zconf_error("invalid option"); ;}
     break;
 
     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);
        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;
 
 ;}
     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;
 
        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:
 
     {
   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:
 
     {
 ;}
     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;
 
 ;}
     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;
 
 ;}
     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;
 
        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;
 
 ;}
     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;
 
        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;
 
        printd(DEBUG_PARSE, "%s:%d:range\n", zconf_curname(), zconf_lineno());
 ;}
     break;
 
-  case 38:
+  case 42:
 
     {
        struct symbol *sym = sym_lookup(NULL, 0);
 
     {
        struct symbol *sym = sym_lookup(NULL, 0);
@@ -1430,57 +1460,45 @@ yyreduce:
 ;}
     break;
 
 ;}
     break;
 
-  case 39:
+  case 43:
 
     {
 
     {
-       menu_end_entry();
-       menu_add_menu();
+       (yyval.menu) = menu_add_menu();
 ;}
     break;
 
 ;}
     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;
 
                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;
 
        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;
 
 ;}
     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;
 
     {
        current_entry->sym->flags |= SYMBOL_OPTIONAL;
@@ -1488,115 +1506,89 @@ yyreduce:
 ;}
     break;
 
 ;}
     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;
 
 ;}
     break;
 
-  case 55:
+  case 58:
 
     {
        printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno());
        menu_add_entry(NULL);
 
     {
        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;
 
 ;}
     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;
 
                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_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;
 
        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;
 
 ;}
     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;
 
                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:
 
     {
   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:
 
 ;}
     break;
 
   case 74:
 
-    {
-       zconf_nextfile(yyvsp[0].string);
-;}
-    break;
-
-  case 75:
-
     {
        menu_add_entry(NULL);
     {
        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;
 
        printd(DEBUG_PARSE, "%s:%d:comment\n", zconf_curname(), zconf_lineno());
 ;}
     break;
 
-  case 76:
+  case 75:
 
     {
        menu_end_entry();
 ;}
     break;
 
 
     {
        menu_end_entry();
 ;}
     break;
 
-  case 77:
+  case 76:
 
     {
        printd(DEBUG_PARSE, "%s:%d:help\n", zconf_curname(), zconf_lineno());
 
     {
        printd(DEBUG_PARSE, "%s:%d:help\n", zconf_curname(), zconf_lineno());
@@ -1604,17 +1596,17 @@ yyreduce:
 ;}
     break;
 
 ;}
     break;
 
-  case 78:
+  case 77:
 
     {
 
     {
-       current_entry->sym->help = yyvsp[0].string;
+       current_entry->sym->help = (yyvsp[0].string);
 ;}
     break;
 
   case 82:
 
     {
 ;}
     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;
        printd(DEBUG_PARSE, "%s:%d:depends on\n", zconf_curname(), zconf_lineno());
 ;}
     break;
@@ -1622,7 +1614,7 @@ yyreduce:
   case 83:
 
     {
   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;
        printd(DEBUG_PARSE, "%s:%d:depends\n", zconf_curname(), zconf_lineno());
 ;}
     break;
@@ -1630,7 +1622,7 @@ yyreduce:
   case 84:
 
     {
   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;
        printd(DEBUG_PARSE, "%s:%d:requires\n", zconf_curname(), zconf_lineno());
 ;}
     break;
@@ -1638,84 +1630,84 @@ yyreduce:
   case 86:
 
     {
   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:
 
 ;}
     break;
 
   case 89:
 
-    { yyval.token = T_ENDMENU; ;}
+    { (yyval.id) = (yyvsp[-1].id); ;}
     break;
 
   case 90:
 
     break;
 
   case 90:
 
-    { yyval.token = T_ENDCHOICE; ;}
+    { (yyval.id) = (yyvsp[-1].id); ;}
     break;
 
   case 91:
 
     break;
 
   case 91:
 
-    { yyval.token = T_ENDIF; ;}
+    { (yyval.id) = (yyvsp[-1].id); ;}
     break;
 
   case 94:
 
     break;
 
   case 94:
 
-    { yyval.expr = NULL; ;}
+    { (yyval.expr) = NULL; ;}
     break;
 
   case 95:
 
     break;
 
   case 95:
 
-    { yyval.expr = yyvsp[0].expr; ;}
+    { (yyval.expr) = (yyvsp[0].expr); ;}
     break;
 
   case 96:
 
     break;
 
   case 96:
 
-    { yyval.expr = expr_alloc_symbol(yyvsp[0].symbol); ;}
+    { (yyval.expr) = expr_alloc_symbol((yyvsp[0].symbol)); ;}
     break;
 
   case 97:
 
     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:
 
     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:
 
     break;
 
   case 99:
 
-    { yyval.expr = yyvsp[-1].expr; ;}
+    { (yyval.expr) = (yyvsp[-1].expr); ;}
     break;
 
   case 100:
 
     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:
 
     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:
 
     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:
 
     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:
 
     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;
 
 
     }
 
     break;
 
 
     }
 
-/* Line 999 of yacc.c.  */
+/* Line 1037 of yacc.c.  */
 
 \f
   yyvsp -= yylen;
 
 \f
   yyvsp -= yylen;
@@ -1757,18 +1749,33 @@ yyerrlab:
        {
          YYSIZE_T yysize = 0;
          int yytype = YYTRANSLATE (yychar);
        {
          YYSIZE_T yysize = 0;
          int yytype = YYTRANSLATE (yychar);
+         const char* yyprefix;
          char *yymsg;
          char *yymsg;
-         int yyx, yycount;
+         int yyx;
 
 
-         yycount = 0;
          /* Start YYX at -YYN if negative to avoid negative indexes in
             YYCHECK.  */
          /* 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)
            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)
            {
          yymsg = (char *) YYSTACK_ALLOC (yysize);
          if (yymsg != 0)
            {
@@ -1777,16 +1784,13 @@ yyerrlab:
 
              if (yycount < 5)
                {
 
              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)
                      {
                    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]);
                        yyp = yystpcpy (yyp, yytname[yyx]);
-                       yycount++;
+                       yyprefix = " or ";
                      }
                }
              yyerror (yymsg);
                      }
                }
              yyerror (yymsg);
@@ -1804,38 +1808,57 @@ yyerrlab:
 
   if (yyerrstatus == 3)
     {
 
   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.  */
 
         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;
 
 
      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.  */
 
 yyerrlab1:
   yyerrstatus = 3;     /* Each real token shifted decrements this.  */
 
@@ -1857,22 +1880,22 @@ yyerrlab1:
       if (yyssp == yyss)
        YYABORT;
 
       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;
 
       YY_STACK_PRINT (yyss, yyssp);
     }
 
   if (yyn == YYFINAL)
     YYACCEPT;
 
-  YYDPRINTF ((stderr, "Shifting error token, "));
-
   *++yyvsp = yylval;
 
 
   *++yyvsp = yylval;
 
 
+  /* Shift the error token. */
+  YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
+
   yystate = yyn;
   goto yynewstate;
 
   yystate = yyn;
   goto yynewstate;
 
@@ -1888,6 +1911,9 @@ yyacceptlab:
 | yyabortlab -- YYABORT comes here.  |
 `-----------------------------------*/
 yyabortlab:
 | yyabortlab -- YYABORT comes here.  |
 `-----------------------------------*/
 yyabortlab:
+  yydestruct ("Error: discarding lookahead",
+              yytoken, &yylval);
+  yychar = YYEMPTY;
   yyresult = 1;
   goto yyreturn;
 
   yyresult = 1;
   goto yyreturn;
 
@@ -1923,18 +1949,18 @@ void conf_parse(const char *name)
        sym_init();
        menu_init();
        modules_sym = sym_lookup("MODULES", 0);
        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) {
        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;
         }
 
        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_ENDCHOICE:       return "endchoice";
        case T_IF:              return "if";
        case T_ENDIF:           return "endif";
+       case T_DEPENDS:         return "depends";
        }
        return "<token>";
 }
 
        }
        return "<token>";
 }
 
-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) {
                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;
        }
                zconfnerrs++;
                return false;
        }
@@ -1973,7 +2004,19 @@ static void zconfprint(const char *err, ...)
 {
        va_list ap;
 
 {
        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);
        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)
 {
 
 static void zconferror(const char *err)
 {
+#if YYDEBUG
        fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno() + 1, err);
        fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno() + 1, err);
+#endif
 }
 
 void print_quoted_string(FILE *out, const char *str)
 }
 
 void print_quoted_string(FILE *out, const char *str)
@@ -2119,6 +2164,7 @@ void zconfdump(FILE *out)
 }
 
 #include "lex.zconf.c"
 }
 
 #include "lex.zconf.c"
+#include "util.c"
 #include "confdata.c"
 #include "expr.c"
 #include "symbol.c"
 #include "confdata.c"
 #include "expr.c"
 #include "symbol.c"
index 3d1d070..e14d898 100644 (file)
Binary files a/scripts/kconfig/zconf.tab.o and b/scripts/kconfig/zconf.tab.o differ
index 7f393a0..0691aca 100644 (file)
@@ -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;
        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;
                if (idx == SNDRV_PCM_STREAM_PLAYBACK) {
                        if (! (f_mode & FMODE_WRITE))
                                continue;
index cdeeb63..4585600 100644 (file)
@@ -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;
        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 */
        /* 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_lock(&timer->lock);
                ti->flags &= ~SNDRV_TIMER_IFLG_CALLBACK;
        }
-       spin_unlock(&timer->lock);
+       spin_unlock_irqrestore(&timer->lock, flags);
 }
 
 /*
 }
 
 /*
index d2afaea..2fb4f74 100644 (file)
@@ -11,6 +11,7 @@ snd-cs4236-objs := cs4236.o
 
 # Toplevel Module Dependency
 obj-$(CONFIG_SND_AZT2320) += snd-cs4231-lib.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
 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
index a208180..8f34986 100644 (file)
@@ -318,17 +318,19 @@ config SND_FM801
          To compile this driver as a module, choose M here: the module
          will be called 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
        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
        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"
 
 config SND_HDA_INTEL
        tristate "Intel HD Audio"
index 873f486..118dcc7 100644 (file)
@@ -47,7 +47,7 @@ static int __devinit snd_vortex_midi(vortex_t * vortex)
        struct snd_rawmidi *rmidi;
        int temp, mode;
        struct snd_mpu401 *mpu;
        struct snd_rawmidi *rmidi;
        int temp, mode;
        struct snd_mpu401 *mpu;
-       int port;
+       unsigned long port;
 
 #ifdef VORTEX_MPU401_LEGACY
        /* EnableHardCodedMPU401Port() */
 
 #ifdef VORTEX_MPU401_LEGACY
        /* EnableHardCodedMPU401Port() */
index d72fc28..09a2885 100644 (file)
@@ -35,7 +35,7 @@
 
 #include <asm/io.h>
 
 
 #include <asm/io.h>
 
-#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 <sound/tea575x-tuner.h>
 #define TEA575X_RADIO 1
 #endif
 #include <sound/tea575x-tuner.h>
 #define TEA575X_RADIO 1
 #endif
index e821d65..9dd541d 100644 (file)
@@ -1393,10 +1393,10 @@ static int azx_free(struct azx *chip)
                msleep(1);
        }
 
                msleep(1);
        }
 
-       if (chip->remap_addr)
-               iounmap(chip->remap_addr);
        if (chip->irq >= 0)
                free_irq(chip->irq, (void*)chip);
        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);
 
        if (chip->bdl.area)
                snd_dma_free_pages(&chip->bdl);
index 40f000b..d7343dc 100644 (file)
@@ -1488,6 +1488,9 @@ enum {
 /* reivision id to check workarounds */
 #define AD1988A_REV2           0x100200
 
 /* reivision id to check workarounds */
 #define AD1988A_REV2           0x100200
 
+#define is_rev2(codec) \
+       ((codec)->vendor_id == 0x11d41988 && \
+        (codec)->revision_id == AD1988A_REV2)
 
 /*
  * mixers
 
 /*
  * 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),
        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[] = {
 };
 
 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),
        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[] = {
 };
 
 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),
        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[] = {
 };
 
 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),
        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[] = {
 };
 
 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
        };
                /* 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];
                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;
 
        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);
                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;
        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;
                        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;
                        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;
        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;
                        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;
                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;
                        spec->mixers[0] = ad1988_3stack_mixers1_rev2;
                else
                        spec->mixers[0] = ad1988_3stack_mixers1;
index f0e9a9c..94cf292 100644 (file)
@@ -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 },
        { .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 },
        { .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 },
index 8c440fb..d862295 100644 (file)
@@ -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,
        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,
        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,
        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,
        snd_hda_codec_amp_update(codec, 0x05, 1, HDA_OUTPUT, 0,
-                                0x80, valp[1] & 0x80);
+                                0x80, (valp[1] ? 0 : 0x80));
        return change;
 }
 
        return change;
 }
 
index 61f82f0..10586e4 100644 (file)
@@ -389,7 +389,7 @@ MODULE_SUPPORTED_DEVICE("{{RME Hammerfall-DSP},"
 
 /* use hotplug firmeare loader? */
 #if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE)
 
 /* 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
 #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;
 
        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;
                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) {
 
        if (hdsp_check_for_firmware(hdsp, 0)) {
                if (hdsp->state & HDSP_FirmwareCached) {